diff --git a/CREDITS b/CREDITS
index 1a41bf4..72b4878 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2800,7 +2800,7 @@ D: Starter of Linux1394 effort
 S: ask per mail for current address
 
 N: Nicolas Pitre
-E: nico@cam.org
+E: nico@fluxnic.net
 D: StrongARM SA1100 support integrator & hacker
 D: Xscale PXA architecture
 D: unified SMC 91C9x/91C11x ethernet driver (smc91x)
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index d05737a..06b982a 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -82,6 +82,8 @@ block/
 	- info on the Block I/O (BIO) layer.
 blockdev/
 	- info on block devices & drivers
+btmrvl.txt
+	- info on Marvell Bluetooth driver usage.
 cachetlb.txt
 	- describes the cache/TLB flushing interfaces Linux uses.
 cdrom/
diff --git a/Documentation/ABI/testing/sysfs-bus-pci b/Documentation/ABI/testing/sysfs-bus-pci
index 6bf6805..25be325 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci
+++ b/Documentation/ABI/testing/sysfs-bus-pci
@@ -84,6 +84,16 @@ Description:
 		from this part of the device tree.
 		Depends on CONFIG_HOTPLUG.
 
+What:		/sys/bus/pci/devices/.../reset
+Date:		July 2009
+Contact:	Michael S. Tsirkin <mst@redhat.com>
+Description:
+		Some devices allow an individual function to be reset
+		without affecting other functions in the same device.
+		For devices that have this support, a file named reset
+		will be present in sysfs.  Writing 1 to this file
+		will perform reset.
+
 What:		/sys/bus/pci/devices/.../vpd
 Date:		February 2008
 Contact:	Ben Hutchings <bhutchings@solarflare.com>
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 9632444..ab8300f 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -14,7 +14,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
 	    genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
 	    mac80211.xml debugobjects.xml sh.xml regulator.xml \
 	    alsa-driver-api.xml writing-an-alsa-driver.xml \
-	    tracepoint.xml
+	    tracepoint.xml media.xml
 
 ###
 # The build process is as follows (targets):
@@ -32,7 +32,7 @@ PS_METHOD	= $(prefer-db2x)
 
 ###
 # The targets that may be used.
-PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs
+PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media
 
 BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
 xmldocs: $(BOOKS)
@@ -45,12 +45,16 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
 pdfdocs: $(PDF)
 
 HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
-htmldocs: $(HTML)
+htmldocs: media $(HTML)
 	$(call build_main_index)
 
 MAN := $(patsubst %.xml, %.9, $(BOOKS))
 mandocs: $(MAN)
 
+media:
+	mkdir -p $(srctree)/Documentation/DocBook/media/
+	cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/
+
 installmandocs: mandocs
 	mkdir -p /usr/local/man/man9/
 	install Documentation/DocBook/man/*.9.gz /usr/local/man/man9/
diff --git a/Documentation/DocBook/dvb/.gitignore b/Documentation/DocBook/dvb/.gitignore
new file mode 100644
index 0000000..d7ec32e
--- /dev/null
+++ b/Documentation/DocBook/dvb/.gitignore
@@ -0,0 +1 @@
+!*.xml
diff --git a/Documentation/DocBook/dvb/audio.xml b/Documentation/DocBook/dvb/audio.xml
new file mode 100644
index 0000000..eeb96b8
--- /dev/null
+++ b/Documentation/DocBook/dvb/audio.xml
@@ -0,0 +1,1473 @@
+<title>DVB Audio Device</title>
+<para>The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. It
+can be accessed through <emphasis role="tt">/dev/dvb/adapter0/audio0</emphasis>. Data types and and
+ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/video.h</emphasis> in your
+application.
+</para>
+<para>Please note that some DVB cards don&#8217;t have their own MPEG decoder, which results in
+the omission of the audio and video device.
+</para>
+
+<section id="audio_data_types">
+<title>Audio Data Types</title>
+<para>This section describes the structures, data types and defines used when talking to the
+audio device.
+</para>
+
+<section id="audio_stream_source_t">
+<title>audio_stream_source_t</title>
+<para>The audio stream source is set through the AUDIO_SELECT_SOURCE call and can take
+the following values, depending on whether we are replaying from an internal (demux) or
+external (user write) source.
+</para>
+<programlisting>
+ typedef enum {
+	 AUDIO_SOURCE_DEMUX,
+	 AUDIO_SOURCE_MEMORY
+ } audio_stream_source_t;
+</programlisting>
+<para>AUDIO_SOURCE_DEMUX selects the demultiplexer (fed either by the frontend or the
+DVR device) as the source of the video stream. If AUDIO_SOURCE_MEMORY
+is selected the stream comes from the application through the <emphasis role="tt">write()</emphasis> system
+call.
+</para>
+
+</section>
+<section id="audio_play_state_t">
+<title>audio_play_state_t</title>
+<para>The following values can be returned by the AUDIO_GET_STATUS call representing the
+state of audio playback.
+</para>
+<programlisting>
+ typedef enum {
+	 AUDIO_STOPPED,
+	 AUDIO_PLAYING,
+	 AUDIO_PAUSED
+ } audio_play_state_t;
+</programlisting>
+
+</section>
+<section id="audio_channel_select_t">
+<title>audio_channel_select_t</title>
+<para>The audio channel selected via AUDIO_CHANNEL_SELECT is determined by the
+following values.
+</para>
+<programlisting>
+ typedef enum {
+	 AUDIO_STEREO,
+	 AUDIO_MONO_LEFT,
+	 AUDIO_MONO_RIGHT,
+ } audio_channel_select_t;
+</programlisting>
+
+</section>
+<section id="struct_audio_status">
+<title>struct audio_status</title>
+<para>The AUDIO_GET_STATUS call returns the following structure informing about various
+states of the playback operation.
+</para>
+<programlisting>
+ typedef struct audio_status {
+	 boolean AV_sync_state;
+	 boolean mute_state;
+	 audio_play_state_t play_state;
+	 audio_stream_source_t stream_source;
+	 audio_channel_select_t channel_select;
+	 boolean bypass_mode;
+ } audio_status_t;
+</programlisting>
+
+</section>
+<section id="struct_audio_mixer">
+<title>struct audio_mixer</title>
+<para>The following structure is used by the AUDIO_SET_MIXER call to set the audio
+volume.
+</para>
+<programlisting>
+ typedef struct audio_mixer {
+	 unsigned int volume_left;
+	 unsigned int volume_right;
+ } audio_mixer_t;
+</programlisting>
+
+</section>
+<section id="audio_encodings">
+<title>audio encodings</title>
+<para>A call to AUDIO_GET_CAPABILITIES returns an unsigned integer with the following
+bits set according to the hardwares capabilities.
+</para>
+<programlisting>
+ #define AUDIO_CAP_DTS    1
+ #define AUDIO_CAP_LPCM   2
+ #define AUDIO_CAP_MP1    4
+ #define AUDIO_CAP_MP2    8
+ #define AUDIO_CAP_MP3   16
+ #define AUDIO_CAP_AAC   32
+ #define AUDIO_CAP_OGG   64
+ #define AUDIO_CAP_SDDS 128
+ #define AUDIO_CAP_AC3  256
+</programlisting>
+
+</section>
+<section id="struct_audio_karaoke">
+<title>struct audio_karaoke</title>
+<para>The ioctl AUDIO_SET_KARAOKE uses the following format:
+</para>
+<programlisting>
+ typedef
+ struct audio_karaoke{
+	 int vocal1;
+	 int vocal2;
+	 int melody;
+ } audio_karaoke_t;
+</programlisting>
+<para>If Vocal1 or Vocal2 are non-zero, they get mixed into left and right t at 70% each. If both,
+Vocal1 and Vocal2 are non-zero, Vocal1 gets mixed into the left channel and Vocal2 into the
+right channel at 100% each. Ff Melody is non-zero, the melody channel gets mixed into left
+and right.
+</para>
+
+</section>
+<section id="audio_attributes">
+<title>audio attributes</title>
+<para>The following attributes can be set by a call to AUDIO_SET_ATTRIBUTES:
+</para>
+<programlisting>
+ typedef uint16_t audio_attributes_t;
+ /&#x22C6;   bits: descr. &#x22C6;/
+ /&#x22C6;   15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, &#x22C6;/
+ /&#x22C6;   12    multichannel extension &#x22C6;/
+ /&#x22C6;   11-10 audio type (0=not spec, 1=language included) &#x22C6;/
+ /&#x22C6;    9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) &#x22C6;/
+ /&#x22C6;    7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit,  &#x22C6;/
+ /&#x22C6;    5- 4 Sample frequency fs (0=48kHz, 1=96kHz) &#x22C6;/
+ /&#x22C6;    2- 0 number of audio channels (n+1 channels) &#x22C6;/
+</programlisting>
+ </section></section>
+<section id="audio_function_calls">
+<title>Audio Function Calls</title>
+
+
+<section id="audio_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call opens a named audio device (e.g. /dev/dvb/adapter0/audio0)
+ for subsequent use. When an open() call has succeeded, the device will be ready
+ for use. The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call. This is a standard system call, documented in the Linux
+ manual page for fcntl. Only one user can open the Audio Device in O_RDWR
+ mode. All other attempts to open the device in this mode will fail, and an error
+ code will be returned. If the Audio Device is opened in O_RDONLY mode, the
+ only ioctl call that can be used is AUDIO_GET_STATUS. All other call will
+ return with an error code.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific audio device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="audio_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened audio device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="audio_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call can only be used if AUDIO_SOURCE_MEMORY is selected
+ in the ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in
+ PES format. If O_NONBLOCK is not specified the function will block until
+ buffer space is available. The amount of data to be transferred is implied by
+ count.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>size_t write(int fd, const void &#x22C6;buf, size_t count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer containing the PES data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode AUDIO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Attempted to write more data than the internal buffer can
+ hold.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_STOP</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to stop playing the current stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_STOP);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_STOP for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_PLAY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to start playing an audio stream from the
+ selected source.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_PLAY);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_PLAY for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_PAUSE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call suspends the audio stream being played. Decoding and playing
+ are paused. It is then possible to restart again decoding and playing process of
+ the audio stream using AUDIO_CONTINUE command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>If AUDIO_SOURCE_MEMORY is selected in the ioctl call
+ AUDIO_SELECT_SOURCE, the DVB-subsystem will not decode (consume)
+ any more data until the ioctl call AUDIO_CONTINUE or AUDIO_PLAY is
+ performed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_PAUSE);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_PAUSE for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SELECT_SOURCE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call informs the audio device which source shall be used
+ for the input data. The possible sources are demux or memory. If
+ AUDIO_SOURCE_MEMORY is selected, the data is fed to the Audio Device
+ through the write command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SELECT_SOURCE,
+ audio_stream_source_t source);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SELECT_SOURCE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_stream_source_t
+ source</para>
+</entry><entry
+ align="char">
+<para>Indicates the source that shall be used for the Audio
+ stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_MUTE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the audio device to mute the stream that is currently being
+ played.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_MUTE,
+ boolean state);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_MUTE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean state</para>
+</entry><entry
+ align="char">
+<para>Indicates if audio device shall mute or not.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE Audio Mute</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE Audio Un-mute</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_AV_SYNC</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to turn ON or OFF A/V synchronization.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_AV_SYNC,
+ boolean state);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_AV_SYNC for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean state</para>
+</entry><entry
+ align="char">
+<para>Tells the DVB subsystem if A/V synchronization shall be
+ ON or OFF.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE AV-sync ON</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE AV-sync OFF</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_BYPASS_MODE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to bypass the Audio decoder and forward
+ the stream without decoding. This mode shall be used if streams that can&#8217;t be
+ handled by the DVB system shall be decoded. Dolby DigitalTM streams are
+ automatically forwarded by the DVB subsystem if the hardware can handle it.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_SET_BYPASS_MODE, boolean mode);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_BYPASS_MODE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean mode</para>
+</entry><entry
+ align="char">
+<para>Enables or disables the decoding of the current Audio
+ stream in the DVB subsystem.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE Bypass is disabled</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE Bypass is enabled</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_CHANNEL_SELECT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to select the requested channel if possible.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_CHANNEL_SELECT, audio_channel_select_t);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_CHANNEL_SELECT for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_channel_select_t
+ ch</para>
+</entry><entry
+ align="char">
+<para>Select the output format of the audio (mono left/right,
+ stereo).</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter ch.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_GET_STATUS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to return the current state of the Audio
+ Device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_GET_STATUS,
+ struct audio_status &#x22C6;status);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_GET_STATUS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct audio_status
+ *status</para>
+</entry><entry
+ align="char">
+<para>Returns the current state of Audio Device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_GET_CAPABILITIES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to tell us about the decoding capabilities
+ of the audio hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ AUDIO_GET_CAPABILITIES, unsigned int &#x22C6;cap);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_GET_CAPABILITIES for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>unsigned int *cap</para>
+</entry><entry
+ align="char">
+<para>Returns a bit array of supported sound formats.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>cap points to an invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_CLEAR_BUFFER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Audio Device to clear all software and hardware buffers
+ of the audio decoder device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_CLEAR_BUFFER);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_CLEAR_BUFFER for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_ID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl selects which sub-stream is to be decoded if a program or system
+ stream is sent to the video device. If no audio stream type is set the id has to be
+ in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for AC3 and in [0xA0,0xA7]
+ for LPCM. More specifications may follow for other stream types. If the stream
+ type is set the id just specifies the substream id of the audio stream and only
+ the first 5 bits are recognized.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_ID, int
+ id);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int id</para>
+</entry><entry
+ align="char">
+<para>audio sub-stream id</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid sub-stream id.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_MIXER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl lets you adjust the mixer settings of the audio decoder.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = AUDIO_SET_MIXER,
+ audio_mixer_t &#x22C6;mix);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_mixer_t *mix</para>
+</entry><entry
+ align="char">
+<para>mixer settings.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>mix points to an invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_STREAMTYPE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl tells the driver which kind of audio stream to expect. This is useful
+ if the stream offers several audio sub-streams like LPCM and AC3.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_STREAMTYPE,
+ int type);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_STREAMTYPE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int type</para>
+</entry><entry
+ align="char">
+<para>stream type</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>type is not a valid or supported stream type.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_EXT_ID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl can be used to set the extension id for MPEG streams in DVD
+ playback. Only the first 3 bits are recognized.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_EXT_ID, int
+ id);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_EXT_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int id</para>
+</entry><entry
+ align="char">
+<para>audio sub_stream_id</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>id is not a valid id.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_ATTRIBUTES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is intended for DVD playback and allows you to set certain
+ information about the audio stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_ATTRIBUTES,
+ audio_attributes_t attr );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_ATTRIBUTES for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_attributes_t
+ attr</para>
+</entry><entry
+ align="char">
+<para>audio attributes according to section ??</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>attr is not a valid or supported attribute setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>AUDIO_SET_KARAOKE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl allows one to set the mixer settings for a karaoke DVD.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = AUDIO_SET_STREAMTYPE,
+ audio_karaoke_t &#x22C6;karaoke);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals AUDIO_SET_STREAMTYPE for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>audio_karaoke_t
+ *karaoke</para>
+</entry><entry
+ align="char">
+<para>karaoke settings according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>karaoke is not a valid or supported karaoke setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section>
+</section>
diff --git a/Documentation/DocBook/dvb/ca.xml b/Documentation/DocBook/dvb/ca.xml
new file mode 100644
index 0000000..b1f1d2f
--- /dev/null
+++ b/Documentation/DocBook/dvb/ca.xml
@@ -0,0 +1,221 @@
+<title>DVB CA Device</title>
+<para>The DVB CA device controls the conditional access hardware. It can be accessed through
+<emphasis role="tt">/dev/dvb/adapter0/ca0</emphasis>. Data types and and ioctl definitions can be accessed by
+including <emphasis role="tt">linux/dvb/ca.h</emphasis> in your application.
+</para>
+
+<section id="ca_data_types">
+<title>CA Data Types</title>
+
+
+<section id="ca_slot_info_t">
+<title>ca_slot_info_t</title>
+ <programlisting>
+ /&#x22C6; slot interface types and info &#x22C6;/
+
+ typedef struct ca_slot_info_s {
+	 int num;               /&#x22C6; slot number &#x22C6;/
+
+	 int type;           /&#x22C6; CA interface this slot supports &#x22C6;/
+ #define CA_CI            1  /&#x22C6; CI high level interface &#x22C6;/
+ #define CA_CI_LINK       2  /&#x22C6; CI link layer level interface &#x22C6;/
+ #define CA_CI_PHYS       4  /&#x22C6; CI physical layer level interface &#x22C6;/
+ #define CA_SC          128  /&#x22C6; simple smart card interface &#x22C6;/
+
+	 unsigned int flags;
+ #define CA_CI_MODULE_PRESENT 1 /&#x22C6; module (or card) inserted &#x22C6;/
+ #define CA_CI_MODULE_READY   2
+ } ca_slot_info_t;
+</programlisting>
+
+</section>
+<section id="ca_descr_info_t">
+<title>ca_descr_info_t</title>
+ <programlisting>
+ typedef struct ca_descr_info_s {
+	 unsigned int num;  /&#x22C6; number of available descramblers (keys) &#x22C6;/
+	 unsigned int type; /&#x22C6; type of supported scrambling system &#x22C6;/
+ #define CA_ECD           1
+ #define CA_NDS           2
+ #define CA_DSS           4
+ } ca_descr_info_t;
+</programlisting>
+
+</section>
+<section id="ca_cap_t">
+<title>ca_cap_t</title>
+ <programlisting>
+ typedef struct ca_cap_s {
+	 unsigned int slot_num;  /&#x22C6; total number of CA card and module slots &#x22C6;/
+	 unsigned int slot_type; /&#x22C6; OR of all supported types &#x22C6;/
+	 unsigned int descr_num; /&#x22C6; total number of descrambler slots (keys) &#x22C6;/
+	 unsigned int descr_type;/&#x22C6; OR of all supported types &#x22C6;/
+ } ca_cap_t;
+</programlisting>
+
+</section>
+<section id="ca_msg_t">
+<title>ca_msg_t</title>
+ <programlisting>
+ /&#x22C6; a message to/from a CI-CAM &#x22C6;/
+ typedef struct ca_msg_s {
+	 unsigned int index;
+	 unsigned int type;
+	 unsigned int length;
+	 unsigned char msg[256];
+ } ca_msg_t;
+</programlisting>
+
+</section>
+<section id="ca_descr_t">
+<title>ca_descr_t</title>
+ <programlisting>
+ typedef struct ca_descr_s {
+	 unsigned int index;
+	 unsigned int parity;
+	 unsigned char cw[8];
+ } ca_descr_t;
+</programlisting>
+ </section></section>
+<section id="ca_function_calls">
+<title>CA Function Calls</title>
+
+
+<section id="ca_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call opens a named ca device (e.g. /dev/ost/ca) for subsequent use.</para>
+<para>When an open() call has succeeded, the device will be ready for use.
+ The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call. This is a standard system call, documented in the Linux
+ manual page for fcntl. Only one user can open the CA Device in O_RDWR
+ mode. All other attempts to open the device in this mode will fail, and an error
+ code will be returned.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific video device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="ca_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened audio device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section>
+</section>
diff --git a/Documentation/DocBook/dvb/demux.xml b/Documentation/DocBook/dvb/demux.xml
new file mode 100644
index 0000000..1b8c4e9
--- /dev/null
+++ b/Documentation/DocBook/dvb/demux.xml
@@ -0,0 +1,973 @@
+<title>DVB Demux Device</title>
+
+<para>The DVB demux device controls the filters of the DVB hardware/software. It can be
+accessed through <emphasis role="tt">/dev/adapter0/demux0</emphasis>. Data types and and ioctl definitions can be
+accessed by including <emphasis role="tt">linux/dvb/dmx.h</emphasis> in your application.
+</para>
+<section id="dmx_types">
+<title>Demux Data Types</title>
+
+<section id="dmx_output_t">
+<title>dmx_output_t</title>
+ <programlisting>
+ typedef enum
+ {
+	 DMX_OUT_DECODER,
+	 DMX_OUT_TAP,
+	 DMX_OUT_TS_TAP
+ } dmx_output_t;
+</programlisting>
+<para><emphasis role="tt">DMX_OUT_TAP</emphasis> delivers the stream output to the demux device on which the ioctl is
+called.
+</para>
+<para><emphasis role="tt">DMX_OUT_TS_TAP</emphasis> routes output to the logical DVR device <emphasis role="tt">/dev/dvb/adapter0/dvr0</emphasis>,
+which delivers a TS multiplexed from all filters for which <emphasis role="tt">DMX_OUT_TS_TAP</emphasis> was
+specified.
+</para>
+</section>
+
+<section id="dmx_input_t">
+<title>dmx_input_t</title>
+ <programlisting>
+ typedef enum
+ {
+	 DMX_IN_FRONTEND,
+	 DMX_IN_DVR
+ } dmx_input_t;
+</programlisting>
+</section>
+
+<section id="dmx_pes_type_t">
+<title>dmx_pes_type_t</title>
+ <programlisting>
+ typedef enum
+ {
+	 DMX_PES_AUDIO,
+	 DMX_PES_VIDEO,
+	 DMX_PES_TELETEXT,
+	 DMX_PES_SUBTITLE,
+	 DMX_PES_PCR,
+	 DMX_PES_OTHER
+ } dmx_pes_type_t;
+</programlisting>
+</section>
+
+<section id="dmx_event_t">
+<title>dmx_event_t</title>
+ <programlisting>
+ typedef enum
+ {
+	 DMX_SCRAMBLING_EV,
+	 DMX_FRONTEND_EV
+ } dmx_event_t;
+</programlisting>
+</section>
+
+<section id="dmx_scrambling_status_t">
+<title>dmx_scrambling_status_t</title>
+ <programlisting>
+ typedef enum
+ {
+	 DMX_SCRAMBLING_OFF,
+	 DMX_SCRAMBLING_ON
+ } dmx_scrambling_status_t;
+</programlisting>
+</section>
+
+<section id="dmx_filter">
+<title>struct dmx_filter</title>
+ <programlisting>
+ typedef struct dmx_filter
+ {
+	 uint8_t         filter[DMX_FILTER_SIZE];
+	 uint8_t         mask[DMX_FILTER_SIZE];
+ } dmx_filter_t;
+</programlisting>
+</section>
+
+<section id="dmx_sct_filter_params">
+<title>struct dmx_sct_filter_params</title>
+ <programlisting>
+ struct dmx_sct_filter_params
+ {
+	 uint16_t            pid;
+	 dmx_filter_t        filter;
+	 uint32_t            timeout;
+	 uint32_t            flags;
+ #define DMX_CHECK_CRC       1
+ #define DMX_ONESHOT         2
+ #define DMX_IMMEDIATE_START 4
+ };
+</programlisting>
+</section>
+
+<section id="dmx_pes_filter_params">
+<title>struct dmx_pes_filter_params</title>
+ <programlisting>
+ struct dmx_pes_filter_params
+ {
+	 uint16_t            pid;
+	 dmx_input_t         input;
+	 dmx_output_t        output;
+	 dmx_pes_type_t      pes_type;
+	 uint32_t            flags;
+ };
+</programlisting>
+</section>
+
+<section id="dmx_event">
+<title>struct dmx_event</title>
+ <programlisting>
+ struct dmx_event
+ {
+	 dmx_event_t          event;
+	 time_t               timeStamp;
+	 union
+	 {
+		 dmx_scrambling_status_t scrambling;
+	 } u;
+ };
+</programlisting>
+</section>
+
+<section id="dmx_stc">
+<title>struct dmx_stc</title>
+ <programlisting>
+ struct dmx_stc {
+	 unsigned int num;       /&#x22C6; input : which STC? 0..N &#x22C6;/
+	 unsigned int base;      /&#x22C6; output: divisor for stc to get 90 kHz clock &#x22C6;/
+	 uint64_t stc;           /&#x22C6; output: stc in 'base'&#x22C6;90 kHz units &#x22C6;/
+ };
+</programlisting>
+ </section>
+
+</section>
+
+<section id="dmx_fcalls">
+<title>Demux Function Calls</title>
+
+<section id="dmx_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call, used with a device name of /dev/dvb/adapter0/demux0,
+ allocates a new filter and returns a handle which can be used for subsequent
+ control of that filter. This call has to be made for each filter to be used, i.e. every
+ returned file descriptor is a reference to a single filter. /dev/dvb/adapter0/dvr0
+ is a logical device to be used for retrieving Transport Streams for digital
+ video recording. When reading from this device a transport stream containing
+ the packets from all PES filters set in the corresponding demux device
+ (/dev/dvb/adapter0/demux0) having the output set to DMX_OUT_TS_TAP. A
+ recorded Transport Stream is replayed by writing to this device. </para>
+<para>The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of demux device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EMFILE</para>
+</entry><entry
+ align="char">
+<para>&#8220;Too many open files&#8221;, i.e. no more filters available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>The driver failed to allocate enough memory.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call deactivates and deallocates a filter that was previously
+ allocated via the open() call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_fread">
+<title>read()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call returns filtered data, which might be section or PES data. The
+ filtered data is transferred from the driver&#8217;s internal circular buffer to buf. The
+ maximum amount of data to be transferred is implied by count.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>When returning section data the driver always tries to return a complete single
+ section (even though buf would provide buffer space for more data). If the size
+ of the buffer is smaller than the section as much as possible will be returned,
+ and the remaining data will be provided in subsequent calls.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The size of the internal buffer is 2 * 4096 bytes (the size of two maximum
+ sized sections) by default. The size of this buffer may be changed by using the
+ DMX_SET_BUFFER_SIZE function. If the buffer is not large enough, or if
+ the read operations are not performed fast enough, this may result in a buffer
+ overflow error. In this case EOVERFLOW will be returned, and the circular
+ buffer will be emptied. This call is blocking if there is no data to return, i.e. the
+ process will be put to sleep waiting for data, unless the O_NONBLOCK flag
+ is specified.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Note that in order to be able to read, the filtering process has to be started
+ by defining either a section or a PES filter by means of the ioctl functions,
+ and then starting the filtering process via the DMX_START ioctl function
+ or by setting the DMX_IMMEDIATE_START flag. If the reading is done
+ from a logical DVR demux device, the data will constitute a Transport Stream
+ including the packets from all PES filters in the corresponding demux device
+ /dev/dvb/adapter0/demux0 having the output set to DMX_OUT_TS_TAP.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>size_t read(int fd, void &#x22C6;buf, size_t count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer to be used for returned filtered data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>No data to return and O_NONBLOCK was specified.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ECRC</para>
+</entry><entry
+ align="char">
+<para>Last section had a CRC error - no data returned. The
+ buffer is flushed.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EOVERFLOW</para>
+</entry><entry
+ align="char">
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>The filtered data was not read from the buffer in due
+ time, resulting in non-read data being lost. The buffer is
+ flushed.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ETIMEDOUT</para>
+</entry><entry
+ align="char">
+<para>The section was not loaded within the stated timeout
+ period. See ioctl DMX_SET_FILTER for how to set a
+ timeout.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>The driver failed to write to the callers buffer due to an
+ invalid *buf pointer.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call is only provided by the logical device /dev/dvb/adapter0/dvr0,
+ associated with the physical demux device that provides the actual DVR
+ functionality. It is used for replay of a digitally recorded Transport Stream.
+ Matching filters have to be defined in the corresponding physical demux
+ device, /dev/dvb/adapter0/demux0. The amount of data to be transferred is
+ implied by count.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>ssize_t write(int fd, const void &#x22C6;buf, size_t
+ count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer containing the Transport Stream.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>No data was written. This
+ might happen if O_NONBLOCK was specified and there
+ is no more buffer space available (if O_NONBLOCK is
+ not specified the function will block until buffer space is
+ available).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>This error code indicates that there are conflicting
+ requests. The corresponding demux device is setup to
+ receive data from the front- end. Make sure that these
+ filters are stopped and that the filters with input set to
+ DMX_IN_DVR are started.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_start">
+<title>DMX_START</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to start the actual filtering operation defined via the ioctl
+ calls DMX_SET_FILTER or DMX_SET_PES_FILTER.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_START);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_START for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument, i.e. no filtering parameters provided via
+ the DMX_SET_FILTER or DMX_SET_PES_FILTER
+ functions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>This error code indicates that there are conflicting
+ requests. There are active filters filtering data from
+ another input source. Make sure that these filters are
+ stopped before starting this filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_stop">
+<title>DMX_STOP</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to stop the actual filtering operation defined via the
+ ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via
+ the DMX_START command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_STOP);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_STOP for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_set_filter">
+<title>DMX_SET_FILTER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call sets up a filter according to the filter and mask parameters
+ provided. A timeout may be defined stating number of seconds to wait for a
+ section to be loaded. A value of 0 means that no timeout should be applied.
+ Finally there is a flag field where it is possible to state whether a section should
+ be CRC-checked, whether the filter should be a &#8221;one-shot&#8221; filter, i.e. if the
+ filtering operation should be stopped after the first section is received, and
+ whether the filtering operation should be started immediately (without waiting
+ for a DMX_START ioctl call). If a filter was previously set-up, this filter will
+ be canceled, and the receive buffer will be flushed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_SET_FILTER,
+ struct dmx_sct_filter_params &#x22C6;params);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_SET_FILTER for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dmx_sct_filter_params
+ *params</para>
+</entry><entry
+ align="char">
+<para>Pointer to structure containing filter parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_set_pes_filter">
+<title>DMX_SET_PES_FILTER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call sets up a PES filter according to the parameters provided. By a
+ PES filter is meant a filter that is based just on the packet identifier (PID), i.e.
+ no PES header or payload filtering capability is supported.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The transport stream destination for the filtered output may be set. Also the
+ PES type may be stated in order to be able to e.g. direct a video stream directly
+ to the video decoder. Finally there is a flag field where it is possible to state
+ whether the filtering operation should be started immediately (without waiting
+ for a DMX_START ioctl call). If a filter was previously set-up, this filter will
+ be cancelled, and the receive buffer will be flushed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_SET_PES_FILTER,
+ struct dmx_pes_filter_params &#x22C6;params);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_SET_PES_FILTER for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dmx_pes_filter_params
+ *params</para>
+</entry><entry
+ align="char">
+<para>Pointer to structure containing filter parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>This error code indicates that there are conflicting
+ requests. There are active filters filtering data from
+ another input source. Make sure that these filters are
+ stopped before starting this filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dms_set_buffer_size">
+<title>DMX_SET_BUFFER_SIZE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to set the size of the circular buffer used for filtered data.
+ The default size is two maximum sized sections, i.e. if this function is not called
+ a buffer size of 2 * 4096 bytes will be used.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request =
+ DMX_SET_BUFFER_SIZE, unsigned long size);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_SET_BUFFER_SIZE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>unsigned long size</para>
+</entry><entry
+ align="char">
+<para>Size of circular buffer.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>The driver was not able to allocate a buffer of the
+ requested size.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_get_event">
+<title>DMX_GET_EVENT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns an event if available. If an event is not available,
+ the behavior depends on whether the device is in blocking or non-blocking
+ mode. In the latter case, the call fails immediately with errno set to
+ EWOULDBLOCK. In the former case, the call blocks until an event becomes
+ available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The standard Linux poll() and/or select() system calls can be used with the
+ device file descriptor to watch for new events. For select(), the file descriptor
+ should be included in the exceptfds argument, and for poll(), POLLPRI should
+ be specified as the wake-up condition. Only the latest event for each filter is
+ saved.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_GET_EVENT,
+ struct dmx_event &#x22C6;ev);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_GET_EVENT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dmx_event *ev</para>
+</entry><entry
+ align="char">
+<para>Pointer to the location where the event is to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ev points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>There is no event pending, and the device is in
+ non-blocking mode.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="dmx_get_stc">
+<title>DMX_GET_STC</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the current value of the system time counter (which is driven
+ by a PES filter of type DMX_PES_PCR). Some hardware supports more than one
+ STC, so you must specify which one by setting the num field of stc before the ioctl
+ (range 0...n). The result is returned in form of a ratio with a 64 bit numerator
+ and a 32 bit denominator, so the real 90kHz STC value is stc-&#x003E;stc /
+ stc-&#x003E;base
+ .</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request = DMX_GET_STC, struct
+ dmx_stc &#x22C6;stc);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals DMX_GET_STC for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dmx_stc *stc</para>
+</entry><entry
+ align="char">
+<para>Pointer to the location where the stc is to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>stc points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid stc number.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
diff --git a/Documentation/DocBook/dvb/dvbapi.xml b/Documentation/DocBook/dvb/dvbapi.xml
new file mode 100644
index 0000000..4fc5b23
--- /dev/null
+++ b/Documentation/DocBook/dvb/dvbapi.xml
@@ -0,0 +1,87 @@
+<partinfo>
+<authorgroup>
+<author>
+<firstname>Ralph</firstname>
+<surname>Metzler</surname>
+<othername role="mi">J. K.</othername>
+<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
+</author>
+<author>
+<firstname>Marcus</firstname>
+<surname>Metzler</surname>
+<othername role="mi">O. C.</othername>
+<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
+</author>
+<author>
+<firstname>Mauro</firstname>
+<surname>Chehab</surname>
+<othername role="mi">Carvalho</othername>
+<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
+<contrib>Ported document to Docbook XML.</contrib>
+</author>
+</authorgroup>
+<copyright>
+	<year>2002</year>
+	<year>2003</year>
+	<year>2009</year>
+	<holder>Convergence GmbH</holder>
+</copyright>
+
+<revhistory>
+<!-- Put document revisions here, newest first. -->
+<revision>
+<revnumber>2.0.1</revnumber>
+<date>2009-09-16</date>
+<authorinitials>mcc</authorinitials>
+<revremark>
+Added ISDB-T test originally written by Patrick Boettcher
+</revremark>
+</revision>
+<revision>
+<revnumber>2.0.0</revnumber>
+<date>2009-09-06</date>
+<authorinitials>mcc</authorinitials>
+<revremark>Conversion from LaTex to DocBook XML. The
+	contents is the same as the original LaTex version.</revremark>
+</revision>
+<revision>
+<revnumber>1.0.0</revnumber>
+<date>2003-07-24</date>
+<authorinitials>rjkm</authorinitials>
+<revremark>Initial revision on LaTEX.</revremark>
+</revision>
+</revhistory>
+</partinfo>
+
+
+<title>LINUX DVB API</title>
+<subtitle>Version 3</subtitle>
+<!-- ADD THE CHAPTERS HERE -->
+  <chapter id="dvb_introdution">
+    &sub-intro;
+  </chapter>
+  <chapter id="dvb_frontend">
+    &sub-frontend;
+  </chapter>
+  <chapter id="dvb_demux">
+    &sub-demux;
+  </chapter>
+  <chapter id="dvb_video">
+    &sub-video;
+  </chapter>
+  <chapter id="dvb_audio">
+    &sub-audio;
+  </chapter>
+  <chapter id="dvb_ca">
+    &sub-ca;
+  </chapter>
+  <chapter id="dvb_net">
+    &sub-net;
+  </chapter>
+  <chapter id="dvb_kdapi">
+    &sub-kdapi;
+  </chapter>
+  <chapter id="dvb_examples">
+    &sub-examples;
+  </chapter>
+<!-- END OF CHAPTERS -->
diff --git a/Documentation/DocBook/dvb/dvbstb.pdf b/Documentation/DocBook/dvb/dvbstb.pdf
new file mode 100644
index 0000000..0fa75d9
Binary files /dev/null and b/Documentation/DocBook/dvb/dvbstb.pdf differ
diff --git a/Documentation/DocBook/dvb/dvbstb.png b/Documentation/DocBook/dvb/dvbstb.png
new file mode 100644
index 0000000..9b8f372
Binary files /dev/null and b/Documentation/DocBook/dvb/dvbstb.png differ
diff --git a/Documentation/DocBook/dvb/examples.xml b/Documentation/DocBook/dvb/examples.xml
new file mode 100644
index 0000000..f037e56
--- /dev/null
+++ b/Documentation/DocBook/dvb/examples.xml
@@ -0,0 +1,365 @@
+<title>Examples</title>
+<para>In this section we would like to present some examples for using the DVB API.
+</para>
+<para>Maintainer note: This section is out of date. Please refer to the sample programs packaged
+with the driver distribution from <ulink url="http://linuxtv.org/hg/dvb-apps" />.
+</para>
+
+<section id="tuning">
+<title>Tuning</title>
+<para>We will start with a generic tuning subroutine that uses the frontend and SEC, as well as
+the demux devices. The example is given for QPSK tuners, but can easily be adjusted for
+QAM.
+</para>
+<programlisting>
+ #include &#x003C;sys/ioctl.h&#x003E;
+ #include &#x003C;stdio.h&#x003E;
+ #include &#x003C;stdint.h&#x003E;
+ #include &#x003C;sys/types.h&#x003E;
+ #include &#x003C;sys/stat.h&#x003E;
+ #include &#x003C;fcntl.h&#x003E;
+ #include &#x003C;time.h&#x003E;
+ #include &#x003C;unistd.h&#x003E;
+
+ #include &#x003C;linux/dvb/dmx.h&#x003E;
+ #include &#x003C;linux/dvb/frontend.h&#x003E;
+ #include &#x003C;linux/dvb/sec.h&#x003E;
+ #include &#x003C;sys/poll.h&#x003E;
+
+ #define DMX "/dev/dvb/adapter0/demux1"
+ #define FRONT "/dev/dvb/adapter0/frontend1"
+ #define SEC "/dev/dvb/adapter0/sec1"
+
+ /&#x22C6; routine for checking if we have a signal and other status information&#x22C6;/
+ int FEReadStatus(int fd, fe_status_t &#x22C6;stat)
+ {
+	 int ans;
+
+	 if ( (ans = ioctl(fd,FE_READ_STATUS,stat) &#x003C; 0)){
+		 perror("FE READ STATUS: ");
+		 return -1;
+	 }
+
+	 if (&#x22C6;stat &amp; FE_HAS_POWER)
+		 printf("FE HAS POWER\n");
+
+	 if (&#x22C6;stat &amp; FE_HAS_SIGNAL)
+		 printf("FE HAS SIGNAL\n");
+
+	 if (&#x22C6;stat &amp; FE_SPECTRUM_INV)
+		 printf("SPEKTRUM INV\n");
+
+	 return 0;
+ }
+
+
+ /&#x22C6; tune qpsk &#x22C6;/
+ /&#x22C6; freq:             frequency of transponder                      &#x22C6;/
+ /&#x22C6; vpid, apid, tpid: PIDs of video, audio and teletext TS packets  &#x22C6;/
+ /&#x22C6; diseqc:           DiSEqC address of the used LNB                &#x22C6;/
+ /&#x22C6; pol:              Polarisation                                  &#x22C6;/
+ /&#x22C6; srate:            Symbol Rate                                   &#x22C6;/
+ /&#x22C6; fec.              FEC                                           &#x22C6;/
+ /&#x22C6; lnb_lof1:         local frequency of lower LNB band             &#x22C6;/
+ /&#x22C6; lnb_lof2:         local frequency of upper LNB band             &#x22C6;/
+ /&#x22C6; lnb_slof:         switch frequency of LNB                       &#x22C6;/
+
+ int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
+		 int diseqc, int pol, int srate, int fec, int lnb_lof1,
+		 int lnb_lof2, int lnb_slof)
+ {
+	 struct secCommand scmd;
+	 struct secCmdSequence scmds;
+	 struct dmx_pes_filter_params pesFilterParams;
+	 FrontendParameters frp;
+	 struct pollfd pfd[1];
+	 FrontendEvent event;
+	 int demux1, demux2, demux3, front;
+
+	 frequency = (uint32_t) freq;
+	 symbolrate = (uint32_t) srate;
+
+	 if((front = open(FRONT,O_RDWR)) &#x003C; 0){
+		 perror("FRONTEND DEVICE: ");
+		 return -1;
+	 }
+
+	 if((sec = open(SEC,O_RDWR)) &#x003C; 0){
+		 perror("SEC DEVICE: ");
+		 return -1;
+	 }
+
+	 if (demux1 &#x003C; 0){
+		 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
+		     &#x003C; 0){
+			 perror("DEMUX DEVICE: ");
+			 return -1;
+		 }
+	 }
+
+	 if (demux2 &#x003C; 0){
+		 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
+		     &#x003C; 0){
+			 perror("DEMUX DEVICE: ");
+			 return -1;
+		 }
+	 }
+
+	 if (demux3 &#x003C; 0){
+		 if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
+		     &#x003C; 0){
+			 perror("DEMUX DEVICE: ");
+			 return -1;
+		 }
+	 }
+
+	 if (freq &#x003C; lnb_slof) {
+		 frp.Frequency = (freq - lnb_lof1);
+		 scmds.continuousTone = SEC_TONE_OFF;
+	 } else {
+		 frp.Frequency = (freq - lnb_lof2);
+		 scmds.continuousTone = SEC_TONE_ON;
+	 }
+	 frp.Inversion = INVERSION_AUTO;
+	 if (pol) scmds.voltage = SEC_VOLTAGE_18;
+	 else scmds.voltage = SEC_VOLTAGE_13;
+
+	 scmd.type=0;
+	 scmd.u.diseqc.addr=0x10;
+	 scmd.u.diseqc.cmd=0x38;
+	 scmd.u.diseqc.numParams=1;
+	 scmd.u.diseqc.params[0] = 0xF0 | ((diseqc &#x22C6; 4) &amp; 0x0F) |
+		 (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
+		 (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
+
+	 scmds.miniCommand=SEC_MINI_NONE;
+	 scmds.numCommands=1;
+	 scmds.commands=&amp;scmd;
+	 if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
+		 perror("SEC SEND: ");
+		 return -1;
+	 }
+
+	 if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
+		 perror("SEC SEND: ");
+		 return -1;
+	 }
+
+	 frp.u.qpsk.SymbolRate = srate;
+	 frp.u.qpsk.FEC_inner = fec;
+
+	 if (ioctl(front, FE_SET_FRONTEND, &amp;frp) &#x003C; 0){
+		 perror("QPSK TUNE: ");
+		 return -1;
+	 }
+
+	 pfd[0].fd = front;
+	 pfd[0].events = POLLIN;
+
+	 if (poll(pfd,1,3000)){
+		 if (pfd[0].revents &amp; POLLIN){
+			 printf("Getting QPSK event\n");
+			 if ( ioctl(front, FE_GET_EVENT, &amp;event)
+
+			      == -EOVERFLOW){
+				 perror("qpsk get event");
+				 return -1;
+			 }
+			 printf("Received ");
+			 switch(event.type){
+			 case FE_UNEXPECTED_EV:
+				 printf("unexpected event\n");
+				 return -1;
+			 case FE_FAILURE_EV:
+				 printf("failure event\n");
+				 return -1;
+
+			 case FE_COMPLETION_EV:
+				 printf("completion event\n");
+			 }
+		 }
+	 }
+
+
+	 pesFilterParams.pid     = vpid;
+	 pesFilterParams.input   = DMX_IN_FRONTEND;
+	 pesFilterParams.output  = DMX_OUT_DECODER;
+	 pesFilterParams.pes_type = DMX_PES_VIDEO;
+	 pesFilterParams.flags   = DMX_IMMEDIATE_START;
+	 if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+		 perror("set_vpid");
+		 return -1;
+	 }
+
+	 pesFilterParams.pid     = apid;
+	 pesFilterParams.input   = DMX_IN_FRONTEND;
+	 pesFilterParams.output  = DMX_OUT_DECODER;
+	 pesFilterParams.pes_type = DMX_PES_AUDIO;
+	 pesFilterParams.flags   = DMX_IMMEDIATE_START;
+	 if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+		 perror("set_apid");
+		 return -1;
+	 }
+
+	 pesFilterParams.pid     = tpid;
+	 pesFilterParams.input   = DMX_IN_FRONTEND;
+	 pesFilterParams.output  = DMX_OUT_DECODER;
+	 pesFilterParams.pes_type = DMX_PES_TELETEXT;
+	 pesFilterParams.flags   = DMX_IMMEDIATE_START;
+	 if (ioctl(demux3, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+		 perror("set_tpid");
+		 return -1;
+	 }
+
+	 return has_signal(fds);
+ }
+
+</programlisting>
+<para>The program assumes that you are using a universal LNB and a standard DiSEqC
+switch with up to 4 addresses. Of course, you could build in some more checking if
+tuning was successful and maybe try to repeat the tuning process. Depending on the
+external hardware, i.e. LNB and DiSEqC switch, and weather conditions this may be
+necessary.
+</para>
+</section>
+
+<section id="the_dvr_device">
+<title>The DVR device</title>
+<para>The following program code shows how to use the DVR device for recording.
+</para>
+<programlisting>
+ #include &#x003C;sys/ioctl.h&#x003E;
+ #include &#x003C;stdio.h&#x003E;
+ #include &#x003C;stdint.h&#x003E;
+ #include &#x003C;sys/types.h&#x003E;
+ #include &#x003C;sys/stat.h&#x003E;
+ #include &#x003C;fcntl.h&#x003E;
+ #include &#x003C;time.h&#x003E;
+ #include &#x003C;unistd.h&#x003E;
+
+ #include &#x003C;linux/dvb/dmx.h&#x003E;
+ #include &#x003C;linux/dvb/video.h&#x003E;
+ #include &#x003C;sys/poll.h&#x003E;
+ #define DVR "/dev/dvb/adapter0/dvr1"
+ #define AUDIO "/dev/dvb/adapter0/audio1"
+ #define VIDEO "/dev/dvb/adapter0/video1"
+
+ #define BUFFY (188&#x22C6;20)
+ #define MAX_LENGTH (1024&#x22C6;1024&#x22C6;5) /&#x22C6; record 5MB &#x22C6;/
+
+
+ /&#x22C6; switch the demuxes to recording, assuming the transponder is tuned &#x22C6;/
+
+ /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
+ /&#x22C6; vpid, apid:     PIDs of video and audio channels           &#x22C6;/
+
+ int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
+ {
+	 struct dmx_pes_filter_params pesFilterParams;
+
+	 if (demux1 &#x003C; 0){
+		 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
+		     &#x003C; 0){
+			 perror("DEMUX DEVICE: ");
+			 return -1;
+		 }
+	 }
+
+	 if (demux2 &#x003C; 0){
+		 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
+		     &#x003C; 0){
+			 perror("DEMUX DEVICE: ");
+			 return -1;
+		 }
+	 }
+
+	 pesFilterParams.pid = vpid;
+	 pesFilterParams.input = DMX_IN_FRONTEND;
+	 pesFilterParams.output = DMX_OUT_TS_TAP;
+	 pesFilterParams.pes_type = DMX_PES_VIDEO;
+	 pesFilterParams.flags = DMX_IMMEDIATE_START;
+	 if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+		 perror("DEMUX DEVICE");
+		 return -1;
+	 }
+	 pesFilterParams.pid = apid;
+	 pesFilterParams.input = DMX_IN_FRONTEND;
+	 pesFilterParams.output = DMX_OUT_TS_TAP;
+	 pesFilterParams.pes_type = DMX_PES_AUDIO;
+	 pesFilterParams.flags = DMX_IMMEDIATE_START;
+	 if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
+		 perror("DEMUX DEVICE");
+		 return -1;
+	 }
+	 return 0;
+ }
+
+ /&#x22C6; start recording MAX_LENGTH , assuming the transponder is tuned &#x22C6;/
+
+ /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
+ /&#x22C6; vpid, apid:     PIDs of video and audio channels           &#x22C6;/
+ int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
+ {
+	 int i;
+	 int len;
+	 int written;
+	 uint8_t buf[BUFFY];
+	 uint64_t length;
+	 struct pollfd pfd[1];
+	 int dvr, dvr_out;
+
+	 /&#x22C6; open dvr device &#x22C6;/
+	 if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) &#x003C; 0){
+			 perror("DVR DEVICE");
+			 return -1;
+	 }
+
+	 /&#x22C6; switch video and audio demuxes to dvr &#x22C6;/
+	 printf ("Switching dvr on\n");
+	 i = switch_to_record(demux1, demux2, vpid, apid);
+	 printf("finished: ");
+
+	 printf("Recording %2.0f MB of test file in TS format\n",
+		MAX_LENGTH/(1024.0&#x22C6;1024.0));
+	 length = 0;
+
+	 /&#x22C6; open output file &#x22C6;/
+	 if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
+				  |O_TRUNC, S_IRUSR|S_IWUSR
+				  |S_IRGRP|S_IWGRP|S_IROTH|
+				  S_IWOTH)) &#x003C; 0){
+		 perror("Can't open file for dvr test");
+		 return -1;
+	 }
+
+	 pfd[0].fd = dvr;
+	 pfd[0].events = POLLIN;
+
+	 /&#x22C6; poll for dvr data and write to file &#x22C6;/
+	 while (length &#x003C; MAX_LENGTH ) {
+		 if (poll(pfd,1,1)){
+			 if (pfd[0].revents &amp; POLLIN){
+				 len = read(dvr, buf, BUFFY);
+				 if (len &#x003C; 0){
+					 perror("recording");
+					 return -1;
+				 }
+				 if (len &#x003E; 0){
+					 written = 0;
+					 while (written &#x003C; len)
+						 written +=
+							 write (dvr_out,
+								buf, len);
+					 length += len;
+					 printf("written %2.0f MB\r",
+						length/1024./1024.);
+				 }
+			 }
+		 }
+	 }
+	 return 0;
+ }
+
+</programlisting>
+
+</section>
diff --git a/Documentation/DocBook/dvb/frontend.xml b/Documentation/DocBook/dvb/frontend.xml
new file mode 100644
index 0000000..9d89a7b
--- /dev/null
+++ b/Documentation/DocBook/dvb/frontend.xml
@@ -0,0 +1,1766 @@
+<title>DVB Frontend API</title>
+
+<para>The DVB frontend device controls the tuner and DVB demodulator
+hardware. It can be accessed through <emphasis
+role="tt">/dev/dvb/adapter0/frontend0</emphasis>. Data types and and
+ioctl definitions can be accessed by including <emphasis
+role="tt">linux/dvb/frontend.h</emphasis> in your application.</para>
+
+<para>DVB frontends come in three varieties: DVB-S (satellite), DVB-C
+(cable) and DVB-T (terrestrial). Transmission via the internet (DVB-IP)
+is not yet handled by this API but a future extension is possible. For
+DVB-S the frontend device also supports satellite equipment control
+(SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC)
+specification is available from
+<ulink url="http://www.eutelsat.com/satellites/4_5_5.html">Eutelsat</ulink>.</para>
+
+<para>Note that the DVB API may also be used for MPEG decoder-only PCI
+cards, in which case there exists no frontend device.</para>
+
+<section id="frontend_types">
+<title>Frontend Data Types</title>
+
+<section id="frontend_type">
+<title>frontend type</title>
+
+<para>For historical reasons frontend types are named after the type of modulation used in
+transmission.</para>
+<programlisting>
+	typedef enum fe_type {
+	FE_QPSK,   /&#x22C6; DVB-S &#x22C6;/
+	FE_QAM,    /&#x22C6; DVB-C &#x22C6;/
+	FE_OFDM    /&#x22C6; DVB-T &#x22C6;/
+	} fe_type_t;
+</programlisting>
+
+</section>
+
+<section id="frontend_caps">
+<title>frontend capabilities</title>
+
+<para>Capabilities describe what a frontend can do. Some capabilities can only be supported for
+a specific frontend type.</para>
+<programlisting>
+	typedef enum fe_caps {
+	FE_IS_STUPID                  = 0,
+	FE_CAN_INVERSION_AUTO         = 0x1,
+	FE_CAN_FEC_1_2                = 0x2,
+	FE_CAN_FEC_2_3                = 0x4,
+	FE_CAN_FEC_3_4                = 0x8,
+	FE_CAN_FEC_4_5                = 0x10,
+	FE_CAN_FEC_5_6                = 0x20,
+	FE_CAN_FEC_6_7                = 0x40,
+	FE_CAN_FEC_7_8                = 0x80,
+	FE_CAN_FEC_8_9                = 0x100,
+	FE_CAN_FEC_AUTO               = 0x200,
+	FE_CAN_QPSK                   = 0x400,
+	FE_CAN_QAM_16                 = 0x800,
+	FE_CAN_QAM_32                 = 0x1000,
+	FE_CAN_QAM_64                 = 0x2000,
+	FE_CAN_QAM_128                = 0x4000,
+	FE_CAN_QAM_256                = 0x8000,
+	FE_CAN_QAM_AUTO               = 0x10000,
+	FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
+	FE_CAN_BANDWIDTH_AUTO         = 0x40000,
+	FE_CAN_GUARD_INTERVAL_AUTO    = 0x80000,
+	FE_CAN_HIERARCHY_AUTO         = 0x100000,
+	FE_CAN_MUTE_TS                = 0x80000000,
+	FE_CAN_CLEAN_SETUP            = 0x40000000
+	} fe_caps_t;
+</programlisting>
+</section>
+
+<section id="frontend_info">
+<title>frontend information</title>
+
+<para>Information about the frontend ca be queried with FE_GET_INFO.</para>
+
+<programlisting>
+	struct dvb_frontend_info {
+	char       name[128];
+	fe_type_t  type;
+	uint32_t   frequency_min;
+	uint32_t   frequency_max;
+	uint32_t   frequency_stepsize;
+	uint32_t   frequency_tolerance;
+	uint32_t   symbol_rate_min;
+	uint32_t   symbol_rate_max;
+	uint32_t   symbol_rate_tolerance;     /&#x22C6; ppm &#x22C6;/
+	uint32_t   notifier_delay;            /&#x22C6; ms &#x22C6;/
+	fe_caps_t  caps;
+	};
+</programlisting>
+</section>
+
+<section id="frontend_diseqc">
+<title>diseqc master command</title>
+
+<para>A message sent from the frontend to DiSEqC capable equipment.</para>
+<programlisting>
+	struct dvb_diseqc_master_cmd {
+	uint8_t msg [6]; /&#x22C6;  { framing, address, command, data[3] } &#x22C6;/
+	uint8_t msg_len; /&#x22C6;  valid values are 3...6  &#x22C6;/
+	};
+</programlisting>
+</section>
+<section role="subsection">
+<title>diseqc slave reply</title>
+
+<para>A reply to the frontend from DiSEqC 2.0 capable equipment.</para>
+<programlisting>
+	struct dvb_diseqc_slave_reply {
+	uint8_t msg [4]; /&#x22C6;  { framing, data [3] } &#x22C6;/
+	uint8_t msg_len; /&#x22C6;  valid values are 0...4, 0 means no msg  &#x22C6;/
+	int     timeout; /&#x22C6;  return from ioctl after timeout ms with &#x22C6;/
+	};                       /&#x22C6;  errorcode when no message was received  &#x22C6;/
+</programlisting>
+</section>
+
+<section id="frontend_diseqc_slave_reply">
+<title>diseqc slave reply</title>
+<para>The voltage is usually used with non-DiSEqC capable LNBs to switch the polarzation
+(horizontal/vertical). When using DiSEqC epuipment this voltage has to be switched
+consistently to the DiSEqC commands as described in the DiSEqC spec.</para>
+<programlisting>
+	typedef enum fe_sec_voltage {
+	SEC_VOLTAGE_13,
+	SEC_VOLTAGE_18
+	} fe_sec_voltage_t;
+</programlisting>
+</section>
+
+<section id="frontend_sec_tone">
+<title>SEC continuous tone</title>
+
+<para>The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to switch the
+high/low band of a dual-band LNB. When using DiSEqC epuipment this voltage has to
+be switched consistently to the DiSEqC commands as described in the DiSEqC
+spec.</para>
+<programlisting>
+	typedef enum fe_sec_tone_mode {
+	SEC_TONE_ON,
+	SEC_TONE_OFF
+	} fe_sec_tone_mode_t;
+</programlisting>
+</section>
+
+<section id="frontend_sec_burst">
+<title>SEC tone burst</title>
+
+<para>The 22KHz tone burst is usually used with non-DiSEqC capable switches to select
+between two connected LNBs/satellites. When using DiSEqC epuipment this voltage has to
+be switched consistently to the DiSEqC commands as described in the DiSEqC
+spec.</para>
+<programlisting>
+	typedef enum fe_sec_mini_cmd {
+	SEC_MINI_A,
+	SEC_MINI_B
+	} fe_sec_mini_cmd_t;
+</programlisting>
+
+<para></para>
+</section>
+
+<section id="frontend_status">
+<title>frontend status</title>
+<para>Several functions of the frontend device use the fe_status data type defined
+by</para>
+<programlisting>
+ typedef enum fe_status {
+	 FE_HAS_SIGNAL     = 0x01,   /&#x22C6;  found something above the noise level &#x22C6;/
+	 FE_HAS_CARRIER    = 0x02,   /&#x22C6;  found a DVB signal  &#x22C6;/
+	 FE_HAS_VITERBI    = 0x04,   /&#x22C6;  FEC is stable  &#x22C6;/
+	 FE_HAS_SYNC       = 0x08,   /&#x22C6;  found sync bytes  &#x22C6;/
+	 FE_HAS_LOCK       = 0x10,   /&#x22C6;  everything's working... &#x22C6;/
+	 FE_TIMEDOUT       = 0x20,   /&#x22C6;  no lock within the last ~2 seconds &#x22C6;/
+	 FE_REINIT         = 0x40    /&#x22C6;  frontend was reinitialized,  &#x22C6;/
+ } fe_status_t;                      /&#x22C6;  application is recommned to reset &#x22C6;/
+</programlisting>
+<para>to indicate the current state and/or state changes of the frontend hardware.
+</para>
+
+</section>
+
+<section id="frontend_params">
+<title>frontend parameters</title>
+<para>The kind of parameters passed to the frontend device for tuning depend on
+the kind of hardware you are using. All kinds of parameters are combined as an
+union in the FrontendParameters structure:</para>
+<programlisting>
+ struct dvb_frontend_parameters {
+	 uint32_t frequency;       /&#x22C6; (absolute) frequency in Hz for QAM/OFDM &#x22C6;/
+				   /&#x22C6; intermediate frequency in kHz for QPSK &#x22C6;/
+	 fe_spectral_inversion_t inversion;
+	 union {
+		 struct dvb_qpsk_parameters qpsk;
+		 struct dvb_qam_parameters  qam;
+		 struct dvb_ofdm_parameters ofdm;
+	 } u;
+ };
+</programlisting>
+<para>For satellite QPSK frontends you have to use the <constant>QPSKParameters</constant> member defined by</para>
+<programlisting>
+ struct dvb_qpsk_parameters {
+	 uint32_t        symbol_rate;  /&#x22C6; symbol rate in Symbols per second &#x22C6;/
+	 fe_code_rate_t  fec_inner;    /&#x22C6; forward error correction (see above) &#x22C6;/
+ };
+</programlisting>
+<para>for cable QAM frontend you use the <constant>QAMParameters</constant> structure</para>
+<programlisting>
+ struct dvb_qam_parameters {
+	 uint32_t         symbol_rate; /&#x22C6; symbol rate in Symbols per second &#x22C6;/
+	 fe_code_rate_t   fec_inner;   /&#x22C6; forward error correction (see above) &#x22C6;/
+	 fe_modulation_t  modulation;  /&#x22C6; modulation type (see above) &#x22C6;/
+ };
+</programlisting>
+<para>DVB-T frontends are supported by the <constant>OFDMParamters</constant> structure
+</para>
+<programlisting>
+ struct dvb_ofdm_parameters {
+	 fe_bandwidth_t      bandwidth;
+	 fe_code_rate_t      code_rate_HP;  /&#x22C6; high priority stream code rate &#x22C6;/
+	 fe_code_rate_t      code_rate_LP;  /&#x22C6; low priority stream code rate &#x22C6;/
+	 fe_modulation_t     constellation; /&#x22C6; modulation type (see above) &#x22C6;/
+	 fe_transmit_mode_t  transmission_mode;
+	 fe_guard_interval_t guard_interval;
+	 fe_hierarchy_t      hierarchy_information;
+ };
+</programlisting>
+<para>In the case of QPSK frontends the <constant>Frequency</constant> field specifies the intermediate
+frequency, i.e. the offset which is effectively added to the local oscillator frequency (LOF) of
+the LNB. The intermediate frequency has to be specified in units of kHz. For QAM and
+OFDM frontends the Frequency specifies the absolute frequency and is given in
+Hz.
+</para>
+<para>The Inversion field can take one of these values:
+</para>
+<programlisting>
+ typedef enum fe_spectral_inversion {
+	 INVERSION_OFF,
+	 INVERSION_ON,
+	 INVERSION_AUTO
+ } fe_spectral_inversion_t;
+</programlisting>
+<para>It indicates if spectral inversion should be presumed or not. In the automatic setting
+(<constant>INVERSION_AUTO</constant>) the hardware will try to figure out the correct setting by
+itself.
+</para>
+<para>The possible values for the <constant>FEC_inner</constant> field are
+</para>
+<programlisting>
+ typedef enum fe_code_rate {
+	 FEC_NONE = 0,
+	 FEC_1_2,
+	 FEC_2_3,
+	 FEC_3_4,
+	 FEC_4_5,
+	 FEC_5_6,
+	 FEC_6_7,
+	 FEC_7_8,
+	 FEC_8_9,
+	 FEC_AUTO
+ } fe_code_rate_t;
+</programlisting>
+<para>which correspond to error correction rates of 1/2, 2/3, etc., no error correction or auto
+detection.
+</para>
+<para>For cable and terrestrial frontends (QAM and OFDM) one also has to specify the quadrature
+modulation mode which can be one of the following:
+</para>
+<programlisting>
+ typedef enum fe_modulation {
+ QPSK,
+	 QAM_16,
+	 QAM_32,
+	 QAM_64,
+	 QAM_128,
+	 QAM_256,
+	 QAM_AUTO
+ } fe_modulation_t;
+</programlisting>
+<para>Finally, there are several more parameters for OFDM:
+</para>
+<programlisting>
+ typedef enum fe_transmit_mode {
+	 TRANSMISSION_MODE_2K,
+	 TRANSMISSION_MODE_8K,
+	 TRANSMISSION_MODE_AUTO
+ } fe_transmit_mode_t;
+</programlisting>
+ <programlisting>
+ typedef enum fe_bandwidth {
+	 BANDWIDTH_8_MHZ,
+	 BANDWIDTH_7_MHZ,
+	 BANDWIDTH_6_MHZ,
+	 BANDWIDTH_AUTO
+ } fe_bandwidth_t;
+</programlisting>
+ <programlisting>
+ typedef enum fe_guard_interval {
+	 GUARD_INTERVAL_1_32,
+	 GUARD_INTERVAL_1_16,
+	 GUARD_INTERVAL_1_8,
+	 GUARD_INTERVAL_1_4,
+	 GUARD_INTERVAL_AUTO
+ } fe_guard_interval_t;
+</programlisting>
+ <programlisting>
+ typedef enum fe_hierarchy {
+	 HIERARCHY_NONE,
+	 HIERARCHY_1,
+	 HIERARCHY_2,
+	 HIERARCHY_4,
+	 HIERARCHY_AUTO
+ } fe_hierarchy_t;
+</programlisting>
+
+</section>
+
+<section id="frontend_events">
+<title>frontend events</title>
+ <programlisting>
+ struct dvb_frontend_event {
+	 fe_status_t status;
+	 struct dvb_frontend_parameters parameters;
+ };
+</programlisting>
+ </section>
+</section>
+
+
+<section id="frontend_fcalls">
+<title>Frontend Function Calls</title>
+
+<section id="frontend_f_open">
+<title>open()</title>
+<para>DESCRIPTION</para>
+<informaltable><tgroup cols="1"><tbody><row>
+<entry align="char">
+<para>This system call opens a named frontend device (/dev/dvb/adapter0/frontend0)
+ for subsequent use. Usually the first thing to do after a successful open is to
+ find out the frontend type with FE_GET_INFO.</para>
+<para>The device can be opened in read-only mode, which only allows monitoring of
+ device status and statistics, or read/write mode, which allows any kind of use
+ (e.g. performing tuning operations.)
+</para>
+<para>In a system with multiple front-ends, it is usually the case that multiple devices
+ cannot be open in read/write mode simultaneously. As long as a front-end
+ device is opened in read/write mode, other open() calls in read/write mode will
+ either fail or block, depending on whether non-blocking or blocking mode was
+ specified. A front-end device opened in blocking mode can later be put into
+ non-blocking mode (and vice versa) using the F_SETFL command of the fcntl
+ system call. This is a standard system call, documented in the Linux manual
+ page for fcntl. When an open() call has succeeded, the device will be ready
+ for use in the specified mode. This implies that the corresponding hardware is
+ powered up, and that other front-ends may have been powered down to make
+ that possible.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific video device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_f_close">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened front-end device. After closing
+ a front-end device, its corresponding hardware might be powered down
+ automatically.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_status">
+<title>FE_READ_STATUS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns status information about the front-end. This call only
+ requires read-only access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_READ_STATUS,
+ fe_status_t &#x22C6;status);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_STATUS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct fe_status_t
+ *status</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the front-end status word is
+ to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_ber">
+<title>FE_READ_BER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the bit error rate for the signal currently
+ received/demodulated by the front-end. For this command, read-only access to
+ the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_READ_BER,
+ uint32_t &#x22C6;ber);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_BER for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>uint32_t *ber</para>
+</entry><entry
+ align="char">
+<para>The bit error rate is stored into *ber.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ber points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSIGNAL</para>
+</entry><entry
+ align="char">
+<para>There is no signal, thus no meaningful bit error rate. Also
+ returned if the front-end is not turned on.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_snr">
+<title>FE_READ_SNR</title>
+
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the signal-to-noise ratio for the signal currently received
+ by the front-end. For this command, read-only access to the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_READ_SNR, int16_t
+ &#x22C6;snr);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_SNR for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int16_t *snr</para>
+</entry><entry
+ align="char">
+<para>The signal-to-noise ratio is stored into *snr.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>snr points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSIGNAL</para>
+</entry><entry
+ align="char">
+<para>There is no signal, thus no meaningful signal strength
+ value. Also returned if front-end is not turned on.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_signal_strength">
+<title>FE_READ_SIGNAL_STRENGTH</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the signal strength value for the signal currently received
+ by the front-end. For this command, read-only access to the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request =
+ FE_READ_SIGNAL_STRENGTH, int16_t &#x22C6;strength);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_SIGNAL_STRENGTH for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int16_t *strength</para>
+</entry><entry
+ align="char">
+<para>The signal strength value is stored into *strength.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSIGNAL</para>
+</entry><entry
+ align="char">
+<para>There is no signal, thus no meaningful signal strength
+ value. Also returned if front-end is not turned on.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_read_ub">
+<title>FE_READ_UNCORRECTED_BLOCKS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns the number of uncorrected blocks detected by the device
+ driver during its lifetime. For meaningful measurements, the increment in block
+ count during a specific time interval should be calculated. For this command,
+ read-only access to the device is sufficient.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Note that the counter will wrap to zero after its maximum count has been
+ reached.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl( int fd, int request =
+ FE_READ_UNCORRECTED_BLOCKS, uint32_t &#x22C6;ublocks);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_READ_UNCORRECTED_BLOCKS for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>uint32_t *ublocks</para>
+</entry><entry
+ align="char">
+<para>The total number of uncorrected blocks seen by the driver
+ so far.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ublocks points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOSYS</para>
+</entry><entry
+ align="char">
+<para>Function not available for this device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_set_fe">
+<title>FE_SET_FRONTEND</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call starts a tuning operation using specified parameters. The result
+ of this call will be successful if the parameters were valid and the tuning could
+ be initiated. The result of the tuning operation in itself, however, will arrive
+ asynchronously as an event (see documentation for FE_GET_EVENT and
+ FrontendEvent.) If a new FE_SET_FRONTEND operation is initiated before
+ the previous one was completed, the previous operation will be aborted in favor
+ of the new one. This command requires read/write access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_SET_FRONTEND,
+ struct dvb_frontend_parameters &#x22C6;p);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_FRONTEND for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_parameters
+ *p</para>
+</entry><entry
+ align="char">
+<para>Points to parameters for tuning operation.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>p points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Maximum supported symbol rate reached.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_get_fe">
+<title>FE_GET_FRONTEND</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call queries the currently effective frontend parameters. For this
+ command, read-only access to the device is sufficient.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_GET_FRONTEND,
+ struct dvb_frontend_parameters &#x22C6;p);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_FRONTEND for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_parameters
+ *p</para>
+</entry><entry
+ align="char">
+<para>Points to parameters for tuning operation.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>p points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Maximum supported symbol rate reached.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+
+<section id="frontend_get_event">
+<title>FE_GET_EVENT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns a frontend event if available. If an event is not
+ available, the behavior depends on whether the device is in blocking or
+ non-blocking mode. In the latter case, the call fails immediately with errno
+ set to EWOULDBLOCK. In the former case, the call blocks until an event
+ becomes available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The standard Linux poll() and/or select() system calls can be used with the
+ device file descriptor to watch for new events. For select(), the file descriptor
+ should be included in the exceptfds argument, and for poll(), POLLPRI should
+ be specified as the wake-up condition. Since the event queue allocated is
+ rather small (room for 8 events), the queue must be serviced regularly to avoid
+ overflow. If an overflow happens, the oldest event is discarded from the queue,
+ and an error (EOVERFLOW) occurs the next time the queue is read. After
+ reporting the error condition in this fashion, subsequent FE_GET_EVENT
+ calls will return events from the queue as usual.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>For the sake of implementation simplicity, this command requires read/write
+ access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = QPSK_GET_EVENT,
+ struct dvb_frontend_event &#x22C6;ev);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_GET_EVENT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_event
+ *ev</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the event,</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>if any, is to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ev points to invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>There is no event pending, and the device is in
+ non-blocking mode.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EOVERFLOW</para>
+</entry><entry
+ align="char">
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>Overflow in event queue - one or more events were lost.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_get_info">
+<title>FE_GET_INFO</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns information about the front-end. This call only requires
+ read-only access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(int fd, int request = FE_GET_INFO, struct
+ dvb_frontend_info &#x22C6;info);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_GET_INFO for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_frontend_info
+ *info</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the front-end information is
+ to be stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>info points to invalid address.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_reset_overload">
+<title>FE_DISEQC_RESET_OVERLOAD</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>If the bus has been automatically powered off due to power overload, this ioctl
+ call restores the power to the bus. The call requires read/write access to the
+ device. This call has no effect if the device is manually powered off. Not all
+ DVB adapters support this ioctl.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_RESET_OVERLOAD);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_RESET_OVERLOAD for this
+ command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_send_master_cmd">
+<title>FE_DISEQC_SEND_MASTER_CMD</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to send a a DiSEqC command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_SEND_MASTER_CMD, struct
+ dvb_diseqc_master_cmd &#x22C6;cmd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_SEND_MASTER_CMD for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_diseqc_master_cmd
+ *cmd</para>
+</entry><entry
+ align="char">
+<para>Pointer to the command to be transmitted.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>Seq points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>The data structure referred to by seq is invalid in some
+ way.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_recv_slave_reply">
+<title>FE_DISEQC_RECV_SLAVE_REPLY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to receive reply to a DiSEqC 2.0 command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_RECV_SLAVE_REPLY, struct
+ dvb_diseqc_slave_reply &#x22C6;reply);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_RECV_SLAVE_REPLY for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ dvb_diseqc_slave_reply
+ *reply</para>
+</entry><entry
+ align="char">
+<para>Pointer to the command to be received.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>Seq points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>The data structure referred to by seq is invalid in some
+ way.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_diseqc_send_burst">
+<title>FE_DISEQC_SEND_BURST</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call is used to send a 22KHz tone burst.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_DISEQC_SEND_BURST, fe_sec_mini_cmd_t burst);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_DISEQC_SEND_BURST for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>fe_sec_mini_cmd_t
+ burst</para>
+</entry><entry
+ align="char">
+<para>burst A or B.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>Seq points to an invalid address.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>The data structure referred to by seq is invalid in some
+ way.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Permission denied (needs read/write access).</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_set_tone">
+<title>FE_SET_TONE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This call is used to set the generation of the continuous 22kHz tone. This call
+ requires read/write permissions.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_SET_TONE,
+ fe_sec_tone_mode_t tone);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_TONE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>fe_sec_tone_mode_t
+ tone</para>
+</entry><entry
+ align="char">
+<para>The requested tone generation mode (on/off).</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>File not opened with read permissions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+</row></tbody></tgroup></informaltable>
+</section>
+
+<section id="fe_set_voltage">
+<title>FE_SET_VOLTAGE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This call is used to set the bus voltage. This call requires read/write
+ permissions.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = FE_SET_VOLTAGE,
+ fe_sec_voltage_t voltage);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_VOLTAGE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>fe_sec_voltage_t
+ voltage</para>
+</entry><entry
+ align="char">
+<para>The requested bus voltage.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>File not opened with read permissions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="frontend_enable_high_lnb_volt">
+<title>FE_ENABLE_HIGH_LNB_VOLTAGE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>If high != 0 enables slightly higher voltages instead of 13/18V (to compensate
+ for long cables). This call requires read/write permissions. Not all DVB
+ adapters support this ioctl.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request =
+ FE_ENABLE_HIGH_LNB_VOLTAGE, int high);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals FE_SET_VOLTAGE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int high</para>
+</entry><entry
+ align="char">
+<para>The requested bus voltage.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>File not opened with read permissions.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error in the device driver.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+</section>
+&sub-isdbt;
diff --git a/Documentation/DocBook/dvb/intro.xml b/Documentation/DocBook/dvb/intro.xml
new file mode 100644
index 0000000..0dc83f6
--- /dev/null
+++ b/Documentation/DocBook/dvb/intro.xml
@@ -0,0 +1,191 @@
+<title>Introduction</title>
+
+<section id="requisites">
+<title>What you need to know</title>
+
+<para>The reader of this document is required to have some knowledge in
+the area of digital video broadcasting (DVB) and should be familiar with
+part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e
+you should know what a program/transport stream (PS/TS) is and what is
+meant by a packetized elementary stream (PES) or an I-frame.</para>
+
+<para>Various DVB standards documents are available from
+<ulink url="http://www.dvb.org" /> and/or
+<ulink url="http://www.etsi.org" />.</para>
+
+<para>It is also necessary to know how to access unix/linux devices and
+how to use ioctl calls. This also includes the knowledge of C or C++.
+</para>
+</section>
+
+<section id="history">
+<title>History</title>
+
+<para>The first API for DVB cards we used at Convergence in late 1999
+was an extension of the Video4Linux API which was primarily developed
+for frame grabber cards. As such it was not really well suited to be
+used for DVB cards and their new features like recording MPEG streams
+and filtering several section and PES data streams at the same time.
+</para>
+
+<para>In early 2000, we were approached by Nokia with a proposal for a
+new standard Linux DVB API. As a commitment to the development of
+terminals based on open standards, Nokia and Convergence made it
+available to all Linux developers and published it on
+<ulink url="http://www.linuxtv.org/" /> in September 2000.
+Convergence is the maintainer of the Linux DVB API. Together with the
+LinuxTV community (i.e. you, the reader of this document), the Linux DVB
+API will be constantly reviewed and improved. With the Linux driver for
+the Siemens/Hauppauge DVB PCI card Convergence provides a first
+implementation of the Linux DVB API.</para>
+</section>
+
+<section id="overview">
+<title>Overview</title>
+
+<figure id="stb_components">
+<title>Components of a DVB card/STB</title>
+<mediaobject>
+<imageobject>
+<imagedata fileref="dvbstb.pdf" format="PS" />
+</imageobject>
+<imageobject>
+<imagedata fileref="dvbstb.png" format="PNG" />
+</imageobject>
+</mediaobject>
+</figure>
+
+<para>A DVB PCI card or DVB set-top-box (STB) usually consists of the
+following main hardware components: </para>
+
+<itemizedlist>
+ <listitem>
+
+<para>Frontend consisting of tuner and DVB demodulator</para>
+
+<para>Here the raw signal reaches the DVB hardware from a satellite dish
+or antenna or directly from cable. The frontend down-converts and
+demodulates this signal into an MPEG transport stream (TS). In case of a
+satellite frontend, this includes a facility for satellite equipment
+control (SEC), which allows control of LNB polarization, multi feed
+switches or dish rotors.</para>
+
+</listitem>
+ <listitem>
+
+<para>Conditional Access (CA) hardware like CI adapters and smartcard slots
+</para>
+
+<para>The complete TS is passed through the CA hardware. Programs to
+which the user has access (controlled by the smart card) are decoded in
+real time and re-inserted into the TS.</para>
+
+</listitem>
+ <listitem>
+ <para>Demultiplexer which filters the incoming DVB stream</para>
+
+<para>The demultiplexer splits the TS into its components like audio and
+video streams. Besides usually several of such audio and video streams
+it also contains data streams with information about the programs
+offered in this or other streams of the same provider.</para>
+
+</listitem>
+<listitem>
+
+<para>MPEG2 audio and video decoder</para>
+
+<para>The main targets of the demultiplexer are the MPEG2 audio and
+video decoders. After decoding they pass on the uncompressed audio and
+video to the computer screen or (through a PAL/NTSC encoder) to a TV
+set.</para>
+
+
+</listitem>
+</itemizedlist>
+
+<para><xref linkend="stb_components" /> shows a crude schematic of the control and data flow
+between those components.</para>
+
+<para>On a DVB PCI card not all of these have to be present since some
+functionality can be provided by the main CPU of the PC (e.g. MPEG
+picture and sound decoding) or is not needed (e.g. for data-only uses
+like &#8220;internet over satellite&#8221;). Also not every card or STB
+provides conditional access hardware.</para>
+
+</section>
+
+<section id="dvb_devices">
+<title>Linux DVB Devices</title>
+
+<para>The Linux DVB API lets you control these hardware components
+through currently six Unix-style character devices for video, audio,
+frontend, demux, CA and IP-over-DVB networking. The video and audio
+devices control the MPEG2 decoder hardware, the frontend device the
+tuner and the DVB demodulator. The demux device gives you control over
+the PES and section filters of the hardware. If the hardware does not
+support filtering these filters can be implemented in software. Finally,
+the CA device controls all the conditional access capabilities of the
+hardware. It can depend on the individual security requirements of the
+platform, if and how many of the CA functions are made available to the
+application through this device.</para>
+
+<para>All devices can be found in the <emphasis role="tt">/dev</emphasis>
+tree under <emphasis role="tt">/dev/dvb</emphasis>. The individual devices
+are called:</para>
+
+<itemizedlist>
+<listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/audioM</emphasis>,</para>
+</listitem>
+<listitem>
+<para><emphasis role="tt">/dev/dvb/adapterN/videoM</emphasis>,</para>
+</listitem>
+<listitem>
+<para><emphasis role="tt">/dev/dvb/adapterN/frontendM</emphasis>,</para>
+</listitem>
+ <listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/netM</emphasis>,</para>
+</listitem>
+ <listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/demuxM</emphasis>,</para>
+</listitem>
+ <listitem>
+
+<para><emphasis role="tt">/dev/dvb/adapterN/caM</emphasis>,</para></listitem></itemizedlist>
+
+<para>where N enumerates the DVB PCI cards in a system starting
+from&#x00A0;0, and M enumerates the devices of each type within each
+adapter, starting from&#x00A0;0, too. We will omit the &#8220;<emphasis
+role="tt">/dev/dvb/adapterN/</emphasis>&#8221; in the further dicussion
+of these devices. The naming scheme for the devices is the same wheter
+devfs is used or not.</para>
+
+<para>More details about the data structures and function calls of all
+the devices are described in the following chapters.</para>
+
+</section>
+
+<section id="include_files">
+<title>API include files</title>
+
+<para>For each of the DVB devices a corresponding include file exists.
+The DVB API include files should be included in application sources with
+a partial path like:</para>
+
+
+<programlisting>
+	#include &#x003C;linux/dvb/frontend.h&#x003E;
+</programlisting>
+
+<para>To enable applications to support different API version, an
+additional include file <emphasis
+role="tt">linux/dvb/version.h</emphasis> exists, which defines the
+constant <emphasis role="tt">DVB_API_VERSION</emphasis>. This document
+describes <emphasis role="tt">DVB_API_VERSION&#x00A0;3</emphasis>.
+</para>
+
+</section>
+
diff --git a/Documentation/DocBook/dvb/isdbt.xml b/Documentation/DocBook/dvb/isdbt.xml
new file mode 100644
index 0000000..9285522
--- /dev/null
+++ b/Documentation/DocBook/dvb/isdbt.xml
@@ -0,0 +1,314 @@
+<section id="isdbt">
+	<title>ISDB-T frontend</title>
+	<para>This section describes shortly what are the possible parameters in the Linux
+		DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
+		demodulator:</para>
+
+	<para>This ISDB-T/ISDB-Tsb API extension should reflect all information
+		needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
+		that some very sophisticated devices won't need certain parameters to
+		tune.</para>
+
+	<para>The information given here should help application writers to know how
+		to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
+
+	<para>The details given here about ISDB-T and ISDB-Tsb are just enough to
+		basically show the dependencies between the needed parameter values,
+		but surely some information is left out. For more detailed information
+		see the following documents:</para>
+
+	<para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
+		Television Broadcasting" and</para>
+	<para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
+		Television Broadcasting".</para>
+
+	<para>In order to read this document one has to have some knowledge the
+		channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
+		the reader that an ISDB-T channel consists of 13 segments, that it can
+		have up to 3 layer sharing those segments, and things like that.</para>
+
+	<para>Parameters used by ISDB-T and ISDB-Tsb.</para>
+
+	<section id="isdbt-parms">
+		<title>Parameters that are common with DVB-T and ATSC</title>
+
+		<section id="isdbt-freq">
+			<title><constant>DTV_FREQUENCY</constant></title>
+
+			<para>Central frequency of the channel.</para>
+
+			<para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
+				valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
+				the channel which is 6MHz.</para>
+
+			<para>As in ISDB-Tsb the channel consists of only one or three segments the
+				frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
+				central frequency of the channel is expected.</para>
+		</section>
+
+		<section id="isdbt-bw">
+			<title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
+
+			<para>Possible values:</para>
+
+			<para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
+			<para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
+
+			<para>Note: Hardware specific values might be given here, but standard
+				applications should not bother to set a value to this field as
+				standard demods are ignoring it anyway.</para>
+
+			<para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
+				other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
+				DTV_ISDBT_SB_SEGMENT_COUNT).</para>
+		</section>
+
+		<section id="isdbt-delivery-sys">
+			<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
+
+			<para>Possible values: <constant>SYS_ISDBT</constant></para>
+		</section>
+
+		<section id="isdbt-tx-mode">
+			<title><constant>DTV_TRANSMISSION_MODE</constant></title>
+
+			<para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
+				'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
+
+			<para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
+				<constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
+
+			<para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
+				hardware will try to find the correct FFT-size (if capable) and will
+				use TMCC to fill in the missing parameters.</para>
+
+			<para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
+		</section>
+
+		<section id="isdbt-guard-interval">
+			<title><constant>DTV_GUARD_INTERVAL</constant></title>
+
+			<para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
+				<constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
+
+			<para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
+				try to find the correct guard interval (if capable) and will use TMCC to fill
+				in the missing parameters.</para>
+		</section>
+	</section>
+	<section id="isdbt-new-parms">
+		<title>ISDB-T only parameters</title>
+
+		<section id="isdbt-part-rec">
+			<title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
+
+			<para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
+				the channel is in partial reception mode or not.</para>
+
+			<para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
+				<constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
+
+			<para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
+				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
+				is consisting of one segment and layer or three segments and two layers.</para>
+
+			<para>Possible values: 0, 1, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sound-bcast">
+			<title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
+
+			<para>This field represents whether the other DTV_ISDBT_*-parameters are
+				referring to an ISDB-T and an ISDB-Tsb channel. (See also
+				<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
+
+			<para>Possible values: 0, 1, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sb-ch-id">
+			<title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para>(Note of the author: This might not be the correct description of the
+				<constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
+				background needed to program a device)</para>
+
+			<para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
+				set of connected ISDB-Tsb channels. In this set of channels every
+				channel can be received independently. The number of connected
+				ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
+				bandwidth available.</para>
+
+			<para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
+				broadcaster has several possibilities to put those channels in the
+				air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
+				segments from position 1-8 to 5-13 or anything in between.</para>
+
+			<para>The underlying layer of segments are subchannels: each segment is
+				consisting of several subchannels with a predefined IDs. A sub-channel
+				is used to help the demodulator to synchronize on the channel.</para>
+
+			<para>An ISDB-T channel is always centered over all sub-channels. As for
+				the example above, in ISDB-Tsb it is no longer as simple as that.</para>
+
+			<para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
+				sub-channel ID of the segment to be demodulated.</para>
+
+			<para>Possible values: 0 .. 41, -1 (AUTO)</para>
+		</section>
+
+		<section id="isdbt-sb-seg-idx">
+
+			<title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
+				demodulated for an ISDB-Tsb channel where several of them are
+				transmitted in the connected manner.</para>
+
+			<para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
+
+			<para>Note: This value cannot be determined by an automatic channel search.</para>
+		</section>
+
+		<section id="isdbt-sb-seg-cnt">
+			<title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
+
+			<para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
+
+			<para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
+				channels.</para>
+
+			<para>Possible values: 1 .. 13</para>
+
+			<para>Note: This value cannot be determined by an automatic channel search.</para>
+		</section>
+
+		<section id="isdb-hierq-layers">
+			<title>Hierarchical layers</title>
+
+			<para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
+				ISDB-T hierarchical layers can be decoded simultaneously. For that
+				reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
+
+			<para>ISDB-T has 3 hierarchical layers which each can use a part of the
+				available segments. The total number of segments over all layers has
+				to 13 in ISDB-T.</para>
+
+			<section id="isdbt-layer-ena">
+				<title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
+
+				<para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
+					layers in the decoding process. Setting all bits of
+					<constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
+					demodulated. This is the default.</para>
+
+				<para>If the channel is in the partial reception mode
+					(<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
+					independently of the other 12 segments. In that mode layer A has to
+					have a <constant>SEGMENT_COUNT</constant> of 1.</para>
+
+				<para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
+					according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
+					accordingly.</para>
+
+				<para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
+
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
+				<para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
+			</section>
+
+			<section id="isdbt-layer-fec">
+				<title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
+
+				<para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
+			</section>
+
+			<section id="isdbt-layer-mod">
+				<title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
+
+				<para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
+
+				<para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
+					and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
+			</section>
+
+			<section id="isdbt-layer-seg-cnt">
+				<title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
+
+				<para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
+
+				<para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
+					<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
+
+				<informaltable id="isdbt-layer_seg-cnt-table">
+					<tgroup cols="6">
+
+						<tbody>
+							<row>
+								<entry>PR</entry>
+								<entry>SB</entry>
+								<entry>Layer A width</entry>
+								<entry>Layer B width</entry>
+								<entry>Layer C width</entry>
+								<entry>total width</entry>
+							</row>
+
+							<row>
+								<entry>0</entry>
+								<entry>0</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>13</entry>
+							</row>
+
+							<row>
+								<entry>1</entry>
+								<entry>0</entry>
+								<entry>1</entry>
+								<entry>1 .. 13</entry>
+								<entry>1 .. 13</entry>
+								<entry>13</entry>
+							</row>
+
+							<row>
+								<entry>0</entry>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>0</entry>
+								<entry>0</entry>
+								<entry>1</entry>
+							</row>
+
+							<row>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>1</entry>
+								<entry>2</entry>
+								<entry>0</entry>
+								<entry>13</entry>
+							</row>
+						</tbody>
+
+					</tgroup>
+				</informaltable>
+
+			</section>
+
+			<section id="isdbt_layer_t_interl">
+				<title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
+
+				<para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
+
+				<para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
+					here are referring to what can be found in the TMCC-structure -
+					independent of the mode.</para>
+			</section>
+		</section>
+	</section>
+</section>
diff --git a/Documentation/DocBook/dvb/kdapi.xml b/Documentation/DocBook/dvb/kdapi.xml
new file mode 100644
index 0000000..6c67481
--- /dev/null
+++ b/Documentation/DocBook/dvb/kdapi.xml
@@ -0,0 +1,2309 @@
+<title>Kernel Demux API</title>
+<para>The kernel demux API defines a driver-internal interface for registering low-level,
+hardware specific driver to a hardware independent demux layer. It is only of interest for
+DVB device driver writers. The header file for this API is named <emphasis role="tt">demux.h</emphasis> and located in
+<emphasis role="tt">drivers/media/dvb/dvb-core</emphasis>.
+</para>
+<para>Maintainer note: This section must be reviewed. It is probably out of date.
+</para>
+
+<section id="kernel_demux_data_types">
+<title>Kernel Demux Data Types</title>
+
+
+<section id="dmx_success_t">
+<title>dmx_success_t</title>
+ <programlisting>
+ typedef enum {
+   DMX_OK = 0, /&#x22C6; Received Ok &#x22C6;/
+   DMX_LENGTH_ERROR, /&#x22C6; Incorrect length &#x22C6;/
+   DMX_OVERRUN_ERROR, /&#x22C6; Receiver ring buffer overrun &#x22C6;/
+   DMX_CRC_ERROR, /&#x22C6; Incorrect CRC &#x22C6;/
+   DMX_FRAME_ERROR, /&#x22C6; Frame alignment error &#x22C6;/
+   DMX_FIFO_ERROR, /&#x22C6; Receiver FIFO overrun &#x22C6;/
+   DMX_MISSED_ERROR /&#x22C6; Receiver missed packet &#x22C6;/
+ } dmx_success_t;
+</programlisting>
+
+</section>
+<section id="ts_filter_types">
+<title>TS filter types</title>
+ <programlisting>
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; TS packet reception &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ /&#x22C6; TS filter type for set_type() &#x22C6;/
+
+ #define TS_PACKET       1   /&#x22C6; send TS packets (188 bytes) to callback (default) &#x22C6;/
+ #define TS_PAYLOAD_ONLY 2   /&#x22C6; in case TS_PACKET is set, only send the TS
+				payload (&#x003C;=184 bytes per packet) to callback &#x22C6;/
+ #define TS_DECODER      4   /&#x22C6; send stream to built-in decoder (if present) &#x22C6;/
+</programlisting>
+
+</section>
+<section id="dmx_ts_pes_t">
+<title>dmx_ts_pes_t</title>
+<para>The structure
+</para>
+<programlisting>
+ typedef enum
+ {
+	 DMX_TS_PES_AUDIO,   /&#x22C6; also send packets to audio decoder (if it exists) &#x22C6;/
+	 DMX_TS_PES_VIDEO,   /&#x22C6; ... &#x22C6;/
+	 DMX_TS_PES_TELETEXT,
+	 DMX_TS_PES_SUBTITLE,
+	 DMX_TS_PES_PCR,
+	 DMX_TS_PES_OTHER,
+ } dmx_ts_pes_t;
+</programlisting>
+<para>describes the PES type for filters which write to a built-in decoder. The correspond (and
+should be kept identical) to the types in the demux device.
+</para>
+<programlisting>
+ struct dmx_ts_feed_s {
+	 int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
+	 struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+	 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+	 int (&#x22C6;set) (struct dmx_ts_feed_s&#x22C6; feed,
+		     __u16 pid,
+		     size_t callback_length,
+		     size_t circular_buffer_size,
+		     int descramble,
+		     struct timespec timeout);
+	 int (&#x22C6;start_filtering) (struct dmx_ts_feed_s&#x22C6; feed);
+	 int (&#x22C6;stop_filtering) (struct dmx_ts_feed_s&#x22C6; feed);
+	 int (&#x22C6;set_type) (struct dmx_ts_feed_s&#x22C6; feed,
+			  int type,
+			  dmx_ts_pes_t pes_type);
+ };
+
+ typedef struct dmx_ts_feed_s dmx_ts_feed_t;
+</programlisting>
+ <programlisting>
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; PES packet reception (not supported yet) &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ typedef struct dmx_pes_filter_s {
+	 struct dmx_pes_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+	 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ } dmx_pes_filter_t;
+</programlisting>
+ <programlisting>
+ typedef struct dmx_pes_feed_s {
+	 int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
+	 struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+	 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+	 int (&#x22C6;set) (struct dmx_pes_feed_s&#x22C6; feed,
+		     __u16 pid,
+		     size_t circular_buffer_size,
+		     int descramble,
+		     struct timespec timeout);
+	 int (&#x22C6;start_filtering) (struct dmx_pes_feed_s&#x22C6; feed);
+	 int (&#x22C6;stop_filtering) (struct dmx_pes_feed_s&#x22C6; feed);
+	 int (&#x22C6;allocate_filter) (struct dmx_pes_feed_s&#x22C6; feed,
+				 dmx_pes_filter_t&#x22C6;&#x22C6; filter);
+	 int (&#x22C6;release_filter) (struct dmx_pes_feed_s&#x22C6; feed,
+				dmx_pes_filter_t&#x22C6; filter);
+ } dmx_pes_feed_t;
+</programlisting>
+ <programlisting>
+ typedef struct {
+	 __u8 filter_value [DMX_MAX_FILTER_SIZE];
+	 __u8 filter_mask [DMX_MAX_FILTER_SIZE];
+	 struct dmx_section_feed_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+	 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+ } dmx_section_filter_t;
+</programlisting>
+ <programlisting>
+ struct dmx_section_feed_s {
+	 int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
+	 struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
+	 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
+	 int (&#x22C6;set) (struct dmx_section_feed_s&#x22C6; feed,
+		     __u16 pid,
+		     size_t circular_buffer_size,
+		     int descramble,
+		     int check_crc);
+	 int (&#x22C6;allocate_filter) (struct dmx_section_feed_s&#x22C6; feed,
+				 dmx_section_filter_t&#x22C6;&#x22C6; filter);
+	 int (&#x22C6;release_filter) (struct dmx_section_feed_s&#x22C6; feed,
+				dmx_section_filter_t&#x22C6; filter);
+	 int (&#x22C6;start_filtering) (struct dmx_section_feed_s&#x22C6; feed);
+	 int (&#x22C6;stop_filtering) (struct dmx_section_feed_s&#x22C6; feed);
+ };
+ typedef struct dmx_section_feed_s dmx_section_feed_t;
+
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; Callback functions &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ typedef int (&#x22C6;dmx_ts_cb) ( __u8 &#x22C6; buffer1,
+			    size_t buffer1_length,
+			    __u8 &#x22C6; buffer2,
+			    size_t buffer2_length,
+			    dmx_ts_feed_t&#x22C6; source,
+			    dmx_success_t success);
+
+ typedef int (&#x22C6;dmx_section_cb) ( __u8 &#x22C6; buffer1,
+				 size_t buffer1_len,
+				 __u8 &#x22C6; buffer2,
+				 size_t buffer2_len,
+				 dmx_section_filter_t &#x22C6; source,
+				 dmx_success_t success);
+
+ typedef int (&#x22C6;dmx_pes_cb) ( __u8 &#x22C6; buffer1,
+			     size_t buffer1_len,
+			     __u8 &#x22C6; buffer2,
+			     size_t buffer2_len,
+			     dmx_pes_filter_t&#x22C6; source,
+			     dmx_success_t success);
+
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; DVB Front-End &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ typedef enum {
+	 DMX_OTHER_FE = 0,
+	 DMX_SATELLITE_FE,
+	 DMX_CABLE_FE,
+	 DMX_TERRESTRIAL_FE,
+	 DMX_LVDS_FE,
+	 DMX_ASI_FE, /&#x22C6; DVB-ASI interface &#x22C6;/
+	 DMX_MEMORY_FE
+ } dmx_frontend_source_t;
+
+ typedef struct {
+	 /&#x22C6; The following char&#x22C6; fields point to NULL terminated strings &#x22C6;/
+	 char&#x22C6; id;                    /&#x22C6; Unique front-end identifier &#x22C6;/
+	 char&#x22C6; vendor;                /&#x22C6; Name of the front-end vendor &#x22C6;/
+	 char&#x22C6; model;                 /&#x22C6; Name of the front-end model &#x22C6;/
+	 struct list_head connectivity_list; /&#x22C6; List of front-ends that can
+						be connected to a particular
+						demux &#x22C6;/
+	 void&#x22C6; priv;     /&#x22C6; Pointer to private data of the API client &#x22C6;/
+	 dmx_frontend_source_t source;
+ } dmx_frontend_t;
+
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+ /&#x22C6; MPEG-2 TS Demux &#x22C6;/
+ /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
+
+ /&#x22C6;
+  &#x22C6; Flags OR'ed in the capabilites field of struct dmx_demux_s.
+  &#x22C6;/
+
+ #define DMX_TS_FILTERING                        1
+ #define DMX_PES_FILTERING                       2
+ #define DMX_SECTION_FILTERING                   4
+ #define DMX_MEMORY_BASED_FILTERING              8    /&#x22C6; write() available &#x22C6;/
+ #define DMX_CRC_CHECKING                        16
+ #define DMX_TS_DESCRAMBLING                     32
+ #define DMX_SECTION_PAYLOAD_DESCRAMBLING        64
+ #define DMX_MAC_ADDRESS_DESCRAMBLING            128
+</programlisting>
+
+</section>
+<section id="demux_demux_t">
+<title>demux_demux_t</title>
+ <programlisting>
+ /&#x22C6;
+  &#x22C6; DMX_FE_ENTRY(): Casts elements in the list of registered
+  &#x22C6; front-ends from the generic type struct list_head
+  &#x22C6; to the type &#x22C6; dmx_frontend_t
+  &#x22C6;.
+ &#x22C6;/
+
+ #define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list)
+
+ struct dmx_demux_s {
+	 /&#x22C6; The following char&#x22C6; fields point to NULL terminated strings &#x22C6;/
+	 char&#x22C6; id;                    /&#x22C6; Unique demux identifier &#x22C6;/
+	 char&#x22C6; vendor;                /&#x22C6; Name of the demux vendor &#x22C6;/
+	 char&#x22C6; model;                 /&#x22C6; Name of the demux model &#x22C6;/
+	 __u32 capabilities;          /&#x22C6; Bitfield of capability flags &#x22C6;/
+	 dmx_frontend_t&#x22C6; frontend;    /&#x22C6; Front-end connected to the demux &#x22C6;/
+	 struct list_head reg_list;   /&#x22C6; List of registered demuxes &#x22C6;/
+	 void&#x22C6; priv;                  /&#x22C6; Pointer to private data of the API client &#x22C6;/
+	 int users;                   /&#x22C6; Number of users &#x22C6;/
+	 int (&#x22C6;open) (struct dmx_demux_s&#x22C6; demux);
+	 int (&#x22C6;close) (struct dmx_demux_s&#x22C6; demux);
+	 int (&#x22C6;write) (struct dmx_demux_s&#x22C6; demux, const char&#x22C6; buf, size_t count);
+	 int (&#x22C6;allocate_ts_feed) (struct dmx_demux_s&#x22C6; demux,
+				  dmx_ts_feed_t&#x22C6;&#x22C6; feed,
+				  dmx_ts_cb callback);
+	 int (&#x22C6;release_ts_feed) (struct dmx_demux_s&#x22C6; demux,
+				 dmx_ts_feed_t&#x22C6; feed);
+	 int (&#x22C6;allocate_pes_feed) (struct dmx_demux_s&#x22C6; demux,
+				   dmx_pes_feed_t&#x22C6;&#x22C6; feed,
+				   dmx_pes_cb callback);
+	 int (&#x22C6;release_pes_feed) (struct dmx_demux_s&#x22C6; demux,
+				  dmx_pes_feed_t&#x22C6; feed);
+	 int (&#x22C6;allocate_section_feed) (struct dmx_demux_s&#x22C6; demux,
+				       dmx_section_feed_t&#x22C6;&#x22C6; feed,
+				       dmx_section_cb callback);
+	 int (&#x22C6;release_section_feed) (struct dmx_demux_s&#x22C6; demux,
+				      dmx_section_feed_t&#x22C6; feed);
+	 int (&#x22C6;descramble_mac_address) (struct dmx_demux_s&#x22C6; demux,
+					__u8&#x22C6; buffer1,
+					size_t buffer1_length,
+					__u8&#x22C6; buffer2,
+					size_t buffer2_length,
+					__u16 pid);
+	 int (&#x22C6;descramble_section_payload) (struct dmx_demux_s&#x22C6; demux,
+					    __u8&#x22C6; buffer1,
+					    size_t buffer1_length,
+					    __u8&#x22C6; buffer2, size_t buffer2_length,
+					    __u16 pid);
+	 int (&#x22C6;add_frontend) (struct dmx_demux_s&#x22C6; demux,
+			      dmx_frontend_t&#x22C6; frontend);
+	 int (&#x22C6;remove_frontend) (struct dmx_demux_s&#x22C6; demux,
+				 dmx_frontend_t&#x22C6; frontend);
+	 struct list_head&#x22C6; (&#x22C6;get_frontends) (struct dmx_demux_s&#x22C6; demux);
+	 int (&#x22C6;connect_frontend) (struct dmx_demux_s&#x22C6; demux,
+				  dmx_frontend_t&#x22C6; frontend);
+	 int (&#x22C6;disconnect_frontend) (struct dmx_demux_s&#x22C6; demux);
+
+
+	 /&#x22C6; added because js cannot keep track of these himself &#x22C6;/
+	 int (&#x22C6;get_pes_pids) (struct dmx_demux_s&#x22C6; demux, __u16 &#x22C6;pids);
+ };
+ typedef struct dmx_demux_s dmx_demux_t;
+</programlisting>
+
+</section>
+<section id="demux_directory">
+<title>Demux directory</title>
+ <programlisting>
+ /&#x22C6;
+  &#x22C6; DMX_DIR_ENTRY(): Casts elements in the list of registered
+  &#x22C6; demuxes from the generic type struct list_head&#x22C6; to the type dmx_demux_t
+  &#x22C6;.
+  &#x22C6;/
+
+ #define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list)
+
+ int dmx_register_demux (dmx_demux_t&#x22C6; demux);
+ int dmx_unregister_demux (dmx_demux_t&#x22C6; demux);
+ struct list_head&#x22C6; dmx_get_demuxes (void);
+</programlisting>
+ </section></section>
+<section id="demux_directory_api">
+<title>Demux Directory API</title>
+<para>The demux directory is a Linux kernel-wide facility for registering and accessing the
+MPEG-2 TS demuxes in the system. Run-time registering and unregistering of demux drivers
+is possible using this API.
+</para>
+<para>All demux drivers in the directory implement the abstract interface dmx_demux_t.
+</para>
+
+<section
+role="subsection"><title>dmx_register_demux()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function makes a demux driver interface available to the Linux kernel. It is
+ usually called by the init_module() function of the kernel module that contains
+ the demux driver. The caller of this function is responsible for allocating
+ dynamic or static memory for the demux structure and for initializing its fields
+ before calling this function. The memory allocated for the demux structure
+ must not be freed before calling dmx_unregister_demux(),</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_register_demux ( dmx_demux_t &#x22C6;demux )</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux structure.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EEXIST</para>
+</entry><entry
+ align="char">
+<para>A demux with the same value of the id field already stored
+ in the directory.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSPC</para>
+</entry><entry
+ align="char">
+<para>No space left in the directory.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>dmx_unregister_demux()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function is called to indicate that the given demux interface is no
+ longer available. The caller of this function is responsible for freeing the
+ memory of the demux structure, if it was dynamically allocated before calling
+ dmx_register_demux(). The cleanup_module() function of the kernel module
+ that contains the demux driver should call this function. Note that this function
+ fails if the demux is currently in use, i.e., release_demux() has not been called
+ for the interface.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_unregister_demux ( dmx_demux_t &#x22C6;demux )</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux structure which is to be
+ unregistered.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>The specified demux is not registered in the demux
+ directory.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>The specified demux is currently in use.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>dmx_get_demuxes()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Provides the caller with the list of registered demux interfaces, using the
+ standard list structure defined in the include file linux/list.h. The include file
+ demux.h defines the macro DMX_DIR_ENTRY() for converting an element of
+ the generic type struct list_head* to the type dmx_demux_t*. The caller must
+ not free the memory of any of the elements obtained via this function call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>struct list_head &#x22C6;dmx_get_demuxes ()</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>none</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>struct list_head *</para>
+</entry><entry
+ align="char">
+<para>A list of demux interfaces, or NULL in the case of an
+ empty list.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="demux_api">
+<title>Demux API</title>
+<para>The demux API should be implemented for each demux in the system. It is used to select
+the TS source of a demux and to manage the demux resources. When the demux
+client allocates a resource via the demux API, it receives a pointer to the API of that
+resource.
+</para>
+<para>Each demux receives its TS input from a DVB front-end or from memory, as set via the
+demux API. In a system with more than one front-end, the API can be used to select one of
+the DVB front-ends as a TS source for a demux, unless this is fixed in the HW platform. The
+demux API only controls front-ends regarding their connections with demuxes; the APIs
+used to set the other front-end parameters, such as tuning, are not defined in this
+document.
+</para>
+<para>The functions that implement the abstract interface demux should be defined static or
+module private and registered to the Demux Directory for external access. It is not necessary
+to implement every function in the demux_t struct, however (for example, a demux interface
+might support Section filtering, but not TS or PES filtering). The API client is expected to
+check the value of any function pointer before calling the function: the value of NULL means
+&#8220;function not available&#8221;.
+</para>
+<para>Whenever the functions of the demux API modify shared data, the possibilities of lost
+update and race condition problems should be addressed, e.g. by protecting parts of code with
+mutexes. This is especially important on multi-processor hosts.
+</para>
+<para>Note that functions called from a bottom half context must not sleep, at least in the 2.2.x
+kernels. Even a simple memory allocation can result in a kernel thread being put to sleep if
+swapping is needed. For example, the Linux kernel calls the functions of a network device
+interface from a bottom half context. Thus, if a demux API function is called from network
+device code, the function must not sleep.
+</para>
+
+
+<section id="kdapi_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function reserves the demux for use by the caller and, if necessary,
+ initializes the demux. When the demux is no longer needed, the function close()
+ should be called. It should be possible for multiple clients to access the demux
+ at the same time. Thus, the function implementation should increment the
+ demux usage count when open() is called and decrement it when close() is
+ called.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open ( demux_t&#x22C6; demux );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EUSERS</para>
+</entry><entry
+ align="char">
+<para>Maximum usage count reached.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="kdapi_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function reserves the demux for use by the caller and, if necessary,
+ initializes the demux. When the demux is no longer needed, the function close()
+ should be called. It should be possible for multiple clients to access the demux
+ at the same time. Thus, the function implementation should increment the
+ demux usage count when open() is called and decrement it when close() is
+ called.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(demux_t&#x22C6; demux);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENODEV</para>
+</entry><entry
+ align="char">
+<para>The demux was not in use.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="kdapi_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function provides the demux driver with a memory buffer containing TS
+ packets. Instead of receiving TS packets from the DVB front-end, the demux
+ driver software will read packets from memory. Any clients of this demux
+ with active TS, PES or Section filters will receive filtered data via the Demux
+ callback API (see 0). The function returns when all the data in the buffer has
+ been consumed by the demux. Demux hardware typically cannot read TS from
+ memory. If this is the case, memory-based filtering has to be implemented
+ entirely in software.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int write(demux_t&#x22C6; demux, const char&#x22C6; buf, size_t
+ count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>const char* buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS data in kernel-space memory.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t length</para>
+</entry><entry
+ align="char">
+<para>Length of the TS data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>The command is not implemented.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>allocate_ts_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Allocates a new TS feed, which is used to filter the TS packets carrying a
+ certain PID. The TS feed normally corresponds to a hardware PID filter on the
+ demux chip.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int allocate_ts_feed(dmx_demux_t&#x22C6; demux,
+ dmx_ts_feed_t&#x22C6;&#x22C6; feed, dmx_ts_cb callback);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_feed_t**
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_cb callback</para>
+</entry><entry
+ align="char">
+<para>Pointer to the callback function for passing received TS
+ packet</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>No more TS feeds available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>The command is not implemented.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>release_ts_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Releases the resources allocated with allocate_ts_feed(). Any filtering in
+ progress on the TS feed should be stopped before calling this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int release_ts_feed(dmx_demux_t&#x22C6; demux,
+ dmx_ts_feed_t&#x22C6; feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t* demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>allocate_section_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Allocates a new section feed, i.e. a demux resource for filtering and receiving
+ sections. On platforms with hardware support for section filtering, a section
+ feed is directly mapped to the demux HW. On other platforms, TS packets are
+ first PID filtered in hardware and a hardware section filter then emulated in
+ software. The caller obtains an API pointer of type dmx_section_feed_t as an
+ out parameter. Using this API the caller can set filtering parameters and start
+ receiving sections.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int allocate_section_feed(dmx_demux_t&#x22C6; demux,
+ dmx_section_feed_t &#x22C6;&#x22C6;feed, dmx_section_cb callback);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_feed_t
+ **feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_cb
+ callback</para>
+</entry><entry
+ align="char">
+<para>Pointer to the callback function for passing received
+ sections.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>No more section feeds available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>The command is not implemented.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>release_section_feed()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Releases the resources allocated with allocate_section_feed(), including
+ allocated filters. Any filtering in progress on the section feed should be stopped
+ before calling this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int release_section_feed(dmx_demux_t&#x22C6; demux,
+ dmx_section_feed_t &#x22C6;feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>demux_t *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_feed_t
+ *feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>descramble_mac_address()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function runs a descrambling algorithm on the destination MAC
+ address field of a DVB Datagram Section, replacing the original address
+ with its un-encrypted version. Otherwise, the description on the function
+ descramble_section_payload() applies also to this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int descramble_mac_address(dmx_demux_t&#x22C6; demux, __u8
+ &#x22C6;buffer1, size_t buffer1_length, __u8 &#x22C6;buffer2,
+ size_t buffer2_length, __u16 pid);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t
+ *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8 *buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the first byte of the section.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer1.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8* buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the section data, or NULL. The
+ pointer has a non-NULL value if the section wraps past
+ the end of a circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer2.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>The PID on which the section was received. Useful
+ for obtaining the descrambling key, e.g. from a DVB
+ Common Access facility.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>descramble_section_payload()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function runs a descrambling algorithm on the payload of a DVB
+ Datagram Section, replacing the original payload with its un-encrypted
+ version. The function will be called from the demux API implementation;
+ the API client need not call this function directly. Section-level scrambling
+ algorithms are currently standardized only for DVB-RCC (return channel
+ over 2-directional cable TV network) systems. For all other DVB networks,
+ encryption schemes are likely to be proprietary to each data broadcaster. Thus,
+ it is expected that this function pointer will have the value of NULL (i.e.,
+ function not available) in most demux API implementations. Nevertheless, it
+ should be possible to use the function pointer as a hook for dynamically adding
+ a &#8220;plug-in&#8221; descrambling facility to a demux driver.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>While this function is not needed with hardware-based section descrambling,
+ the descramble_section_payload function pointer can be used to override the
+ default hardware-based descrambling algorithm: if the function pointer has a
+ non-NULL value, the corresponding function should be used instead of any
+ descrambling hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int descramble_section_payload(dmx_demux_t&#x22C6; demux,
+ __u8 &#x22C6;buffer1, size_t buffer1_length, __u8 &#x22C6;buffer2,
+ size_t buffer2_length, __u16 pid);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t
+ *demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8 *buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the first byte of the section.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer1.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8 *buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the section data, or NULL. The
+ pointer has a non-NULL value if the section wraps past
+ the end of a circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the section data, including headers and CRC,
+ in buffer2.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>The PID on which the section was received. Useful
+ for obtaining the descrambling key, e.g. from a DVB
+ Common Access facility.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>add_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Registers a connectivity between a demux and a front-end, i.e., indicates that
+ the demux can be connected via a call to connect_frontend() to use the given
+ front-end as a TS source. The client of this function has to allocate dynamic or
+ static memory for the frontend structure and initialize its fields before calling
+ this function. This function is normally called during the driver initialization.
+ The caller must not free the memory of the frontend struct before successfully
+ calling remove_frontend().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int add_frontend(dmx_demux_t &#x22C6;demux, dmx_frontend_t
+ &#x22C6;frontend);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_frontend_t*
+ frontend</para>
+</entry><entry
+ align="char">
+<para>Pointer to the front-end instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EEXIST</para>
+</entry><entry
+ align="char">
+<para>A front-end with the same value of the id field already
+ registered.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINUSE</para>
+</entry><entry
+ align="char">
+<para>The demux is in use.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOMEM</para>
+</entry><entry
+ align="char">
+<para>No more front-ends can be added.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>remove_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Indicates that the given front-end, registered by a call to add_frontend(), can
+ no longer be connected as a TS source by this demux. The function should be
+ called when a front-end driver or a demux driver is removed from the system.
+ If the front-end is in use, the function fails with the return value of -EBUSY.
+ After successfully calling this function, the caller can free the memory of
+ the frontend struct if it was dynamically allocated before the add_frontend()
+ operation.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int remove_frontend(dmx_demux_t&#x22C6; demux,
+ dmx_frontend_t&#x22C6; frontend);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_frontend_t*
+ frontend</para>
+</entry><entry
+ align="char">
+<para>Pointer to the front-end instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>The front-end is in use, i.e. a call to connect_frontend()
+ has not been followed by a call to disconnect_frontend().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>get_frontends()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Provides the APIs of the front-ends that have been registered for this demux.
+ Any of the front-ends obtained with this call can be used as a parameter for
+ connect_frontend().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The include file demux.h contains the macro DMX_FE_ENTRY() for
+ converting an element of the generic type struct list_head* to the type
+ dmx_frontend_t*. The caller must not free the memory of any of the elements
+ obtained via this function call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>struct list_head&#x22C6; get_frontends(dmx_demux_t&#x22C6; demux);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*</para>
+</entry><entry
+ align="char">
+<para>A list of front-end interfaces, or NULL in the case of an
+ empty list.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>connect_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Connects the TS output of the front-end to the input of the demux. A demux
+ can only be connected to a front-end registered to the demux with the function
+ add_frontend().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>It may or may not be possible to connect multiple demuxes to the same
+ front-end, depending on the capabilities of the HW platform. When not used,
+ the front-end should be released by calling disconnect_frontend().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int connect_frontend(dmx_demux_t&#x22C6; demux,
+ dmx_frontend_t&#x22C6; frontend);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_frontend_t*
+ frontend</para>
+</entry><entry
+ align="char">
+<para>Pointer to the front-end instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EBUSY</para>
+</entry><entry
+ align="char">
+<para>The front-end is in use.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>disconnect_frontend()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Disconnects the demux and a front-end previously connected by a
+ connect_frontend() call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int disconnect_frontend(dmx_demux_t&#x22C6; demux);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_demux_t*
+ demux</para>
+</entry><entry
+ align="char">
+<para>Pointer to the demux API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="demux_callback_api">
+<title>Demux Callback API</title>
+<para>This kernel-space API comprises the callback functions that deliver filtered data to the
+demux client. Unlike the other APIs, these API functions are provided by the client and called
+from the demux code.
+</para>
+<para>The function pointers of this abstract interface are not packed into a structure as in the
+other demux APIs, because the callback functions are registered and used independent
+of each other. As an example, it is possible for the API client to provide several
+callback functions for receiving TS packets and no callbacks for PES packets or
+sections.
+</para>
+<para>The functions that implement the callback API need not be re-entrant: when a demux
+driver calls one of these functions, the driver is not allowed to call the function again before
+the original call returns. If a callback is triggered by a hardware interrupt, it is recommended
+to use the Linux &#8220;bottom half&#8221; mechanism or start a tasklet instead of making the callback
+function call directly from a hardware interrupt.
+</para>
+
+<section
+role="subsection"><title>dmx_ts_cb()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function, provided by the client of the demux API, is called from the
+ demux code. The function is only called when filtering on this TS feed has
+ been enabled using the start_filtering() function.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Any TS packets that match the filter settings are copied to a circular buffer. The
+ filtered TS packets are delivered to the client using this callback function. The
+ size of the circular buffer is controlled by the circular_buffer_size parameter
+ of the set() function in the TS Feed API. It is expected that the buffer1 and
+ buffer2 callback parameters point to addresses within the circular buffer, but
+ other implementations are also possible. Note that the called party should not
+ try to free the memory the buffer1 and buffer2 parameters point to.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>When this function is called, the buffer1 parameter typically points to the
+ start of the first undelivered TS packet within a circular buffer. The buffer2
+ buffer parameter is normally NULL, except when the received TS packets have
+ crossed the last address of the circular buffer and &#8221;wrapped&#8221; to the beginning
+ of the buffer. In the latter case the buffer1 parameter would contain an address
+ within the circular buffer, while the buffer2 parameter would contain the first
+ address of the circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The number of bytes delivered with this function (i.e. buffer1_length +
+ buffer2_length) is usually equal to the value of callback_length parameter
+ given in the set() function, with one exception: if a timeout occurs before
+ receiving callback_length bytes of TS data, any undelivered packets are
+ immediately delivered to the client by calling this function. The timeout
+ duration is controlled by the set() function in the TS Feed API.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>If a TS packet is received with errors that could not be fixed by the TS-level
+ forward error correction (FEC), the Transport_error_indicator flag of the TS
+ packet header should be set. The TS packet should not be discarded, as
+ the error can possibly be corrected by a higher layer protocol. If the called
+ party is slow in processing the callback, it is possible that the circular buffer
+ eventually fills up. If this happens, the demux driver should discard any TS
+ packets received while the buffer is full. The error should be indicated to the
+ client on the next callback by setting the success parameter to the value of
+ DMX_OVERRUN_ERROR.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The type of data returned to the callback can be selected by the new
+ function int (*set_type) (struct dmx_ts_feed_s* feed, int type, dmx_ts_pes_t
+ pes_type) which is part of the dmx_ts_feed_s struct (also cf. to the
+ include file ost/demux.h) The type parameter decides if the raw TS packet
+ (TS_PACKET) or just the payload (TS_PACKET&#8212;TS_PAYLOAD_ONLY)
+ should be returned. If additionally the TS_DECODER bit is set the stream
+ will also be sent to the hardware MPEG decoder. In this case, the second
+ flag decides as what kind of data the stream should be interpreted. The
+ possible choices are one of DMX_TS_PES_AUDIO, DMX_TS_PES_VIDEO,
+ DMX_TS_PES_TELETEXT, DMX_TS_PES_SUBTITLE,
+ DMX_TS_PES_PCR, or DMX_TS_PES_OTHER.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_ts_cb(__u8&#x22C6; buffer1, size_t buffer1_length,
+ __u8&#x22C6; buffer2, size_t buffer2_length, dmx_ts_feed_t&#x22C6;
+ source, dmx_success_t success);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>__u8* buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the start of the filtered TS packets.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the TS data in buffer1.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8* buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the filtered TS packets, or NULL.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the TS data in buffer2.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_ts_feed_t*
+ source</para>
+</entry><entry
+ align="char">
+<para>Indicates which TS feed is the source of the callback.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_success_t
+ success</para>
+</entry><entry
+ align="char">
+<para>Indicates if there was an error in TS reception.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>Continue filtering.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-1</para>
+</entry><entry
+ align="char">
+<para>Stop filtering - has the same effect as a call to
+ stop_filtering() on the TS Feed API.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>dmx_section_cb()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function, provided by the client of the demux API, is called from the
+ demux code. The function is only called when filtering of sections has been
+ enabled using the function start_filtering() of the section feed API. When the
+ demux driver has received a complete section that matches at least one section
+ filter, the client is notified via this callback function. Normally this function is
+ called for each received section; however, it is also possible to deliver multiple
+ sections with one callback, for example when the system load is high. If an
+ error occurs while receiving a section, this function should be called with
+ the corresponding error type set in the success field, whether or not there is
+ data to deliver. The Section Feed implementation should maintain a circular
+ buffer for received sections. However, this is not necessary if the Section Feed
+ API is implemented as a client of the TS Feed API, because the TS Feed
+ implementation then buffers the received data. The size of the circular buffer
+ can be configured using the set() function in the Section Feed API. If there
+ is no room in the circular buffer when a new section is received, the section
+ must be discarded. If this happens, the value of the success parameter should
+ be DMX_OVERRUN_ERROR on the next callback.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int dmx_section_cb(__u8&#x22C6; buffer1, size_t
+ buffer1_length, __u8&#x22C6; buffer2, size_t
+ buffer2_length, dmx_section_filter_t&#x22C6; source,
+ dmx_success_t success);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>__u8* buffer1</para>
+</entry><entry
+ align="char">
+<para>Pointer to the start of the filtered section, e.g. within the
+ circular buffer of the demux driver.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer1_length</para>
+</entry><entry
+ align="char">
+<para>Length of the filtered section data in buffer1, including
+ headers and CRC.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u8* buffer2</para>
+</entry><entry
+ align="char">
+<para>Pointer to the tail of the filtered section data, or NULL.
+ Useful to handle the wrapping of a circular buffer.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t buffer2_length</para>
+</entry><entry
+ align="char">
+<para>Length of the filtered section data in buffer2, including
+ headers and CRC.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_filter_t*
+ filter</para>
+</entry><entry
+ align="char">
+<para>Indicates the filter that triggered the callback.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_success_t
+ success</para>
+</entry><entry
+ align="char">
+<para>Indicates if there was an error in section reception.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>Continue filtering.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-1</para>
+</entry><entry
+ align="char">
+<para>Stop filtering - has the same effect as a call to
+ stop_filtering() on the Section Feed API.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="ts_feed_api">
+<title>TS Feed API</title>
+<para>A TS feed is typically mapped to a hardware PID filter on the demux chip.
+Using this API, the client can set the filtering properties to start/stop filtering TS
+packets on a particular TS feed. The API is defined as an abstract interface of the type
+dmx_ts_feed_t.
+</para>
+<para>The functions that implement the interface should be defined static or module private. The
+client can get the handle of a TS feed API by calling the function allocate_ts_feed() in the
+demux API.
+</para>
+
+<section
+role="subsection"><title>set()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function sets the parameters of a TS feed. Any filtering in progress on the
+ TS feed must be stopped before calling this function.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int set ( dmx_ts_feed_t&#x22C6; feed, __u16 pid, size_t
+ callback_length, size_t circular_buffer_size, int
+ descramble, struct timespec timeout);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>PID value to filter. Only the TS packets carrying the
+ specified PID will be passed to the API client.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t
+ callback_length</para>
+</entry><entry
+ align="char">
+<para>Number of bytes to deliver with each call to the
+ dmx_ts_cb() callback function. The value of this
+ parameter should be a multiple of 188.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t
+ circular_buffer_size</para>
+</entry><entry
+ align="char">
+<para>Size of the circular buffer for the filtered TS packets.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int descramble</para>
+</entry><entry
+ align="char">
+<para>If non-zero, descramble the filtered TS packets.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct timespec
+ timeout</para>
+</entry><entry
+ align="char">
+<para>Maximum time to wait before delivering received TS
+ packets to the client.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Not enough memory for the requested buffer size.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available for TS.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>start_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Starts filtering TS packets on this TS feed, according to its settings. The PID
+ value to filter can be set by the API client. All matching TS packets are
+ delivered asynchronously to the client, using the callback function registered
+ with allocate_ts_feed().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int start_filtering(dmx_ts_feed_t&#x22C6; feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>stop_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Stops filtering TS packets on this TS feed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int stop_filtering(dmx_ts_feed_t&#x22C6; feed);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_ts_feed_t* feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the TS feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
+<section id="section_feed_api">
+<title>Section Feed API</title>
+<para>A section feed is a resource consisting of a PID filter and a set of section filters. Using this
+API, the client can set the properties of a section feed and to start/stop filtering. The API is
+defined as an abstract interface of the type dmx_section_feed_t. The functions that implement
+the interface should be defined static or module private. The client can get the handle of
+a section feed API by calling the function allocate_section_feed() in the demux
+API.
+</para>
+<para>On demux platforms that provide section filtering in hardware, the Section Feed API
+implementation provides a software wrapper for the demux hardware. Other platforms may
+support only PID filtering in hardware, requiring that TS packets are converted to sections in
+software. In the latter case the Section Feed API implementation can be a client of the TS
+Feed API.
+</para>
+
+</section>
+<section id="kdapi_set">
+<title>set()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function sets the parameters of a section feed. Any filtering in progress on
+ the section feed must be stopped before calling this function. If descrambling
+ is enabled, the payload_scrambling_control and address_scrambling_control
+ fields of received DVB datagram sections should be observed. If either one is
+ non-zero, the section should be descrambled either in hardware or using the
+ functions descramble_mac_address() and descramble_section_payload() of the
+ demux API. Note that according to the MPEG-2 Systems specification, only
+ the payloads of private sections can be scrambled while the rest of the section
+ data must be sent in the clear.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int set(dmx_section_feed_t&#x22C6; feed, __u16 pid, size_t
+ circular_buffer_size, int descramble, int
+ check_crc);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>__u16 pid</para>
+</entry><entry
+ align="char">
+<para>PID value to filter; only the TS packets carrying the
+ specified PID will be accepted.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t
+ circular_buffer_size</para>
+</entry><entry
+ align="char">
+<para>Size of the circular buffer for filtered sections.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int descramble</para>
+</entry><entry
+ align="char">
+<para>If non-zero, descramble any sections that are scrambled.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int check_crc</para>
+</entry><entry
+ align="char">
+<para>If non-zero, check the CRC values of filtered sections.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Not enough memory for the requested buffer size.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSYS</para>
+</entry><entry
+ align="char">
+<para>No descrambling facility available for sections.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>allocate_filter()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function is used to allocate a section filter on the demux. It should only be
+ called when no filtering is in progress on this section feed. If a filter cannot be
+ allocated, the function fails with -ENOSPC. See in section ?? for the format of
+ the section filter.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>The bitfields filter_mask and filter_value should only be modified when no
+ filtering is in progress on this section feed. filter_mask controls which bits of
+ filter_value are compared with the section headers/payload. On a binary value
+ of 1 in filter_mask, the corresponding bits are compared. The filter only accepts
+ sections that are equal to filter_value in all the tested bit positions. Any changes
+ to the values of filter_mask and filter_value are guaranteed to take effect only
+ when the start_filtering() function is called next time. The parent pointer in
+ the struct is initialized by the API implementation to the value of the feed
+ parameter. The priv pointer is not used by the API implementation, and can
+ thus be freely utilized by the caller of this function. Any data pointed to by the
+ priv pointer is available to the recipient of the dmx_section_cb() function call.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>While the maximum section filter length (DMX_MAX_FILTER_SIZE) is
+ currently set at 16 bytes, hardware filters of that size are not available on all
+ platforms. Therefore, section filtering will often take place first in hardware,
+ followed by filtering in software for the header bytes that were not covered
+ by a hardware filter. The filter_mask field can be checked to determine how
+ many bytes of the section filter are actually used, and if the hardware filter will
+ suffice. Additionally, software-only section filters can optionally be allocated
+ to clients when all hardware section filters are in use. Note that on most demux
+ hardware it is not possible to filter on the section_length field of the section
+ header &#8211; thus this field is ignored, even though it is included in filter_value and
+ filter_mask fields.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int allocate_filter(dmx_section_feed_t&#x22C6; feed,
+ dmx_section_filter_t&#x22C6;&#x22C6; filter);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_filter_t**
+ filter</para>
+</entry><entry
+ align="char">
+<para>Pointer to the allocated filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENOSPC</para>
+</entry><entry
+ align="char">
+<para>No filters of given type and length available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameters.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>release_filter()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This function releases all the resources of a previously allocated section filter.
+ The function should not be called while filtering is in progress on this section
+ feed. After calling this function, the caller should not try to dereference the
+ filter pointer.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int release_filter ( dmx_section_feed_t&#x22C6; feed,
+ dmx_section_filter_t&#x22C6; filter);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>dmx_section_filter_t*
+ filter</para>
+</entry><entry
+ align="char">
+<para>I/O Pointer to the instance data of a section filter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-ENODEV</para>
+</entry><entry
+ align="char">
+<para>No such filter allocated.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>start_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Starts filtering sections on this section feed, according to its settings. Sections
+ are first filtered based on their PID and then matched with the section
+ filters allocated for this feed. If the section matches the PID filter and
+ at least one section filter, it is delivered to the API client. The section
+ is delivered asynchronously using the callback function registered with
+ allocate_section_feed().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int start_filtering ( dmx_section_feed_t&#x22C6; feed );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>stop_filtering()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>Stops filtering sections on this section feed. Note that any changes to the
+ filtering parameters (filter_value, filter_mask, etc.) should only be made when
+ filtering is stopped.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int stop_filtering ( dmx_section_feed_t&#x22C6; feed );</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>dmx_section_feed_t*
+ feed</para>
+</entry><entry
+ align="char">
+<para>Pointer to the section feed API and instance data.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>RETURNS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>0</para>
+</entry><entry
+ align="char">
+<para>The function was completed without errors.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>-EINVAL</para>
+</entry><entry
+ align="char">
+<para>Bad parameter.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
diff --git a/Documentation/DocBook/dvb/net.xml b/Documentation/DocBook/dvb/net.xml
new file mode 100644
index 0000000..94e388d
--- /dev/null
+++ b/Documentation/DocBook/dvb/net.xml
@@ -0,0 +1,12 @@
+<title>DVB Network API</title>
+<para>The DVB net device enables feeding of MPE (multi protocol encapsulation) packets
+received via DVB into the Linux network protocol stack, e.g. for internet via satellite
+applications. It can be accessed through <emphasis role="tt">/dev/dvb/adapter0/net0</emphasis>. Data types and
+and ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/net.h</emphasis> in your
+application.
+</para>
+<section id="dvb_net_types">
+<title>DVB Net Data Types</title>
+<para>To be written&#x2026;
+</para>
+</section>
diff --git a/Documentation/DocBook/dvb/video.xml b/Documentation/DocBook/dvb/video.xml
new file mode 100644
index 0000000..7bb287e
--- /dev/null
+++ b/Documentation/DocBook/dvb/video.xml
@@ -0,0 +1,1971 @@
+<title>DVB Video Device</title>
+<para>The DVB video device controls the MPEG2 video decoder of the DVB hardware. It
+can be accessed through <emphasis role="tt">/dev/dvb/adapter0/video0</emphasis>. Data types and and
+ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/video.h</emphasis> in your
+application.
+</para>
+<para>Note that the DVB video device only controls decoding of the MPEG video stream, not
+its presentation on the TV or computer screen. On PCs this is typically handled by an
+associated video4linux device, e.g. <emphasis role="tt">/dev/video</emphasis>, which allows scaling and defining output
+windows.
+</para>
+<para>Some DVB cards don&#8217;t have their own MPEG decoder, which results in the omission of
+the audio and video device as well as the video4linux device.
+</para>
+<para>The ioctls that deal with SPUs (sub picture units) and navigation packets are only
+supported on some MPEG decoders made for DVD playback.
+</para>
+<section id="video_types">
+<title>Video Data Types</title>
+
+<section id="video_format_t">
+<title>video_format_t</title>
+<para>The <emphasis role="tt">video_format_t</emphasis> data type defined by
+</para>
+<programlisting>
+ typedef enum {
+	 VIDEO_FORMAT_4_3,
+	 VIDEO_FORMAT_16_9
+ } video_format_t;
+</programlisting>
+<para>is used in the VIDEO_SET_FORMAT function (??) to tell the driver which aspect ratio
+the output hardware (e.g. TV) has. It is also used in the data structures video_status
+(??) returned by VIDEO_GET_STATUS (??) and video_event (??) returned by
+VIDEO_GET_EVENT (??) which report about the display format of the current video
+stream.
+</para>
+</section>
+
+<section id="video_display_format_t">
+<title>video_display_format_t</title>
+<para>In case the display format of the video stream and of the display hardware differ the
+application has to specify how to handle the cropping of the picture. This can be done using
+the VIDEO_SET_DISPLAY_FORMAT call (??) which accepts
+</para>
+<programlisting>
+ typedef enum {
+	 VIDEO_PAN_SCAN,
+	 VIDEO_LETTER_BOX,
+	 VIDEO_CENTER_CUT_OUT
+ } video_display_format_t;
+</programlisting>
+<para>as argument.
+</para>
+</section>
+
+<section id="video_stream_source">
+<title>video stream source</title>
+<para>The video stream source is set through the VIDEO_SELECT_SOURCE call and can take
+the following values, depending on whether we are replaying from an internal (demuxer) or
+external (user write) source.
+</para>
+<programlisting>
+ typedef enum {
+	 VIDEO_SOURCE_DEMUX,
+	 VIDEO_SOURCE_MEMORY
+ } video_stream_source_t;
+</programlisting>
+<para>VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the frontend or the
+DVR device) as the source of the video stream. If VIDEO_SOURCE_MEMORY
+is selected the stream comes from the application through the <emphasis role="tt">write()</emphasis> system
+call.
+</para>
+</section>
+
+<section id="video_play_state">
+<title>video play state</title>
+<para>The following values can be returned by the VIDEO_GET_STATUS call representing the
+state of video playback.
+</para>
+<programlisting>
+ typedef enum {
+	 VIDEO_STOPPED,
+	 VIDEO_PLAYING,
+	 VIDEO_FREEZED
+ } video_play_state_t;
+</programlisting>
+</section>
+
+<section id="video_event">
+<title>struct video_event</title>
+<para>The following is the structure of a video event as it is returned by the VIDEO_GET_EVENT
+call.
+</para>
+<programlisting>
+ struct video_event {
+	 int32_t type;
+	 time_t timestamp;
+	 union {
+		 video_format_t video_format;
+	 } u;
+ };
+</programlisting>
+</section>
+
+<section id="video_status">
+<title>struct video_status</title>
+<para>The VIDEO_GET_STATUS call returns the following structure informing about various
+states of the playback operation.
+</para>
+<programlisting>
+ struct video_status {
+	 boolean video_blank;
+	 video_play_state_t play_state;
+	 video_stream_source_t stream_source;
+	 video_format_t video_format;
+	 video_displayformat_t display_format;
+ };
+</programlisting>
+<para>If video_blank is set video will be blanked out if the channel is changed or if playback is
+stopped. Otherwise, the last picture will be displayed. play_state indicates if the video is
+currently frozen, stopped, or being played back. The stream_source corresponds to the seleted
+source for the video stream. It can come either from the demultiplexer or from memory.
+The video_format indicates the aspect ratio (one of 4:3 or 16:9) of the currently
+played video stream. Finally, display_format corresponds to the selected cropping
+mode in case the source video format is not the same as the format of the output
+device.
+</para>
+</section>
+
+<section id="video_still_picture">
+<title>struct video_still_picture</title>
+<para>An I-frame displayed via the VIDEO_STILLPICTURE call is passed on within the
+following structure.
+</para>
+<programlisting>
+ /&#x22C6; pointer to and size of a single iframe in memory &#x22C6;/
+ struct video_still_picture {
+	 char &#x22C6;iFrame;
+	 int32_t size;
+ };
+</programlisting>
+</section>
+
+<section id="video_caps">
+<title>video capabilities</title>
+<para>A call to VIDEO_GET_CAPABILITIES returns an unsigned integer with the following
+bits set according to the hardwares capabilities.
+</para>
+<programlisting>
+ /&#x22C6; bit definitions for capabilities: &#x22C6;/
+ /&#x22C6; can the hardware decode MPEG1 and/or MPEG2? &#x22C6;/
+ #define VIDEO_CAP_MPEG1   1
+ #define VIDEO_CAP_MPEG2   2
+ /&#x22C6; can you send a system and/or program stream to video device?
+    (you still have to open the video and the audio device but only
+     send the stream to the video device) &#x22C6;/
+ #define VIDEO_CAP_SYS     4
+ #define VIDEO_CAP_PROG    8
+ /&#x22C6; can the driver also handle SPU, NAVI and CSS encoded data?
+    (CSS API is not present yet) &#x22C6;/
+ #define VIDEO_CAP_SPU    16
+ #define VIDEO_CAP_NAVI   32
+ #define VIDEO_CAP_CSS    64
+</programlisting>
+</section>
+
+<section id="video_system">
+<title>video system</title>
+<para>A call to VIDEO_SET_SYSTEM sets the desired video system for TV output. The
+following system types can be set:
+</para>
+<programlisting>
+ typedef enum {
+	  VIDEO_SYSTEM_PAL,
+	  VIDEO_SYSTEM_NTSC,
+	  VIDEO_SYSTEM_PALN,
+	  VIDEO_SYSTEM_PALNc,
+	  VIDEO_SYSTEM_PALM,
+	  VIDEO_SYSTEM_NTSC60,
+	  VIDEO_SYSTEM_PAL60,
+	  VIDEO_SYSTEM_PALM60
+ } video_system_t;
+</programlisting>
+</section>
+
+<section id="video_highlight">
+<title>struct video_highlight</title>
+<para>Calling the ioctl VIDEO_SET_HIGHLIGHTS posts the SPU highlight information. The
+call expects the following format for that information:
+</para>
+<programlisting>
+ typedef
+ struct video_highlight {
+	 boolean active;      /&#x22C6;    1=show highlight, 0=hide highlight &#x22C6;/
+	 uint8_t contrast1;   /&#x22C6;    7- 4  Pattern pixel contrast &#x22C6;/
+			      /&#x22C6;    3- 0  Background pixel contrast &#x22C6;/
+	 uint8_t contrast2;   /&#x22C6;    7- 4  Emphasis pixel-2 contrast &#x22C6;/
+			      /&#x22C6;    3- 0  Emphasis pixel-1 contrast &#x22C6;/
+	 uint8_t color1;      /&#x22C6;    7- 4  Pattern pixel color &#x22C6;/
+			      /&#x22C6;    3- 0  Background pixel color &#x22C6;/
+	 uint8_t color2;      /&#x22C6;    7- 4  Emphasis pixel-2 color &#x22C6;/
+			      /&#x22C6;    3- 0  Emphasis pixel-1 color &#x22C6;/
+	 uint32_t ypos;       /&#x22C6;   23-22  auto action mode &#x22C6;/
+			      /&#x22C6;   21-12  start y &#x22C6;/
+			      /&#x22C6;    9- 0  end y &#x22C6;/
+	 uint32_t xpos;       /&#x22C6;   23-22  button color number &#x22C6;/
+			      /&#x22C6;   21-12  start x &#x22C6;/
+			      /&#x22C6;    9- 0  end x &#x22C6;/
+ } video_highlight_t;
+</programlisting>
+
+</section>
+<section id="video_spu">
+<title>video SPU</title>
+<para>Calling VIDEO_SET_SPU deactivates or activates SPU decoding, according to the
+following format:
+</para>
+<programlisting>
+ typedef
+ struct video_spu {
+	 boolean active;
+	 int stream_id;
+ } video_spu_t;
+</programlisting>
+
+</section>
+<section id="video_spu_palette">
+<title>video SPU palette</title>
+<para>The following structure is used to set the SPU palette by calling VIDEO_SPU_PALETTE:
+</para>
+<programlisting>
+ typedef
+ struct video_spu_palette{
+	 int length;
+	 uint8_t &#x22C6;palette;
+ } video_spu_palette_t;
+</programlisting>
+
+</section>
+<section id="video_navi_pack">
+<title>video NAVI pack</title>
+<para>In order to get the navigational data the following structure has to be passed to the ioctl
+VIDEO_GET_NAVI:
+</para>
+<programlisting>
+ typedef
+ struct video_navi_pack{
+	 int length;         /&#x22C6; 0 ... 1024 &#x22C6;/
+	 uint8_t data[1024];
+ } video_navi_pack_t;
+</programlisting>
+</section>
+
+
+<section id="video_attributes">
+<title>video attributes</title>
+<para>The following attributes can be set by a call to VIDEO_SET_ATTRIBUTES:
+</para>
+<programlisting>
+ typedef uint16_t video_attributes_t;
+ /&#x22C6;   bits: descr. &#x22C6;/
+ /&#x22C6;   15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) &#x22C6;/
+ /&#x22C6;   13-12 TV system (0=525/60, 1=625/50) &#x22C6;/
+ /&#x22C6;   11-10 Aspect ratio (0=4:3, 3=16:9) &#x22C6;/
+ /&#x22C6;    9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca &#x22C6;/
+ /&#x22C6;    7    line 21-1 data present in GOP (1=yes, 0=no) &#x22C6;/
+ /&#x22C6;    6    line 21-2 data present in GOP (1=yes, 0=no) &#x22C6;/
+ /&#x22C6;    5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 &#x22C6;/
+ /&#x22C6;    2    source letterboxed (1=yes, 0=no) &#x22C6;/
+ /&#x22C6;    0    film/camera mode (0=camera, 1=film (625/50 only)) &#x22C6;/
+</programlisting>
+</section></section>
+
+
+<section id="video_function_calls">
+<title>Video Function Calls</title>
+
+
+<section id="video_fopen">
+<title>open()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call opens a named video device (e.g. /dev/dvb/adapter0/video0)
+ for subsequent use.</para>
+<para>When an open() call has succeeded, the device will be ready for use.
+ The significance of blocking or non-blocking mode is described in the
+ documentation for functions where there is a difference. It does not affect the
+ semantics of the open() call itself. A device opened in blocking mode can later
+ be put into non-blocking mode (and vice versa) using the F_SETFL command
+ of the fcntl system call. This is a standard system call, documented in the Linux
+ manual page for fcntl. Only one user can open the Video Device in O_RDWR
+ mode. All other attempts to open the device in this mode will fail, and an
+ error-code will be returned. If the Video Device is opened in O_RDONLY
+ mode, the only ioctl call that can be used is VIDEO_GET_STATUS. All other
+ call will return an error code.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int open(const char &#x22C6;deviceName, int flags);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>const char
+ *deviceName</para>
+</entry><entry
+ align="char">
+<para>Name of specific video device.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int flags</para>
+</entry><entry
+ align="char">
+<para>A bit-wise OR of the following flags:</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDONLY read-only access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_RDWR read/write access</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>O_NONBLOCK open in non-blocking mode</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>(blocking mode is the default)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>ENODEV</para>
+</entry><entry
+ align="char">
+<para>Device driver not loaded/available.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBUSY</para>
+</entry><entry
+ align="char">
+<para>Device or resource busy.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid argument.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="video_fclose">
+<title>close()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call closes a previously opened video device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int close(int fd);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section>
+<section id="video_fwrite">
+<title>write()</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This system call can only be used if VIDEO_SOURCE_MEMORY is selected
+ in the ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in
+ PES format, unless the capability allows other formats. If O_NONBLOCK is
+ not specified the function will block until buffer space is available. The amount
+ of data to be transferred is implied by count.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>size_t write(int fd, const void &#x22C6;buf, size_t count);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>void *buf</para>
+</entry><entry
+ align="char">
+<para>Pointer to the buffer containing the PES data.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>size_t count</para>
+</entry><entry
+ align="char">
+<para>Size of buf.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>ENOMEM</para>
+</entry><entry
+ align="char">
+<para>Attempted to write more data than the internal buffer can
+ hold.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_STOP</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to stop playing the current stream.
+ Depending on the input parameter, the screen can be blanked out or displaying
+ the last decoded frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_STOP, boolean
+ mode);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_STOP for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>Boolean mode</para>
+</entry><entry
+ align="char">
+<para>Indicates how the screen shall be handled.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>TRUE: Blank screen when stop.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE: Show last decoded frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_PLAY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to start playing a video stream from the
+ selected source.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_PLAY);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_PLAY for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_FREEZE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call suspends the live video stream being played. Decoding
+ and playing are frozen. It is then possible to restart the decoding
+ and playing process of the video stream using the VIDEO_CONTINUE
+ command. If VIDEO_SOURCE_MEMORY is selected in the ioctl call
+ VIDEO_SELECT_SOURCE, the DVB subsystem will not decode any more
+ data until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_FREEZE);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_FREEZE for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_CONTINUE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call restarts decoding and playing processes of the video stream
+ which was played before a call to VIDEO_FREEZE was made.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_CONTINUE);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_CONTINUE for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SELECT_SOURCE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call informs the video device which source shall be used for the input
+ data. The possible sources are demux or memory. If memory is selected, the
+ data is fed to the video device through the write command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SELECT_SOURCE,
+ video_stream_source_t source);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SELECT_SOURCE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_stream_source_t
+ source</para>
+</entry><entry
+ align="char">
+<para>Indicates which source shall be used for the Video stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_BLANK</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to blank out the picture.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SET_BLANK, boolean
+ mode);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_BLANK for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>boolean mode</para>
+</entry><entry
+ align="char">
+<para>TRUE: Blank screen when stop.</para>
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>FALSE: Show last decoded frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal input parameter</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_STATUS</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to return the current status of the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_GET_STATUS, struct
+ video_status &#x22C6;status);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_STATUS for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct video_status
+ *status</para>
+</entry><entry
+ align="char">
+<para>Returns the current status of the Video Device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error, possibly in the communication with the
+ DVB subsystem.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>status points to invalid address</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_EVENT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns an event of type video_event if available. If an event is
+ not available, the behavior depends on whether the device is in blocking or
+ non-blocking mode. In the latter case, the call fails immediately with errno
+ set to EWOULDBLOCK. In the former case, the call blocks until an event
+ becomes available. The standard Linux poll() and/or select() system calls can
+ be used with the device file descriptor to watch for new events. For select(),
+ the file descriptor should be included in the exceptfds argument, and for
+ poll(), POLLPRI should be specified as the wake-up condition. Read-only
+ permissions are sufficient for this ioctl call.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_GET_EVENT, struct
+ video_event &#x22C6;ev);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_EVENT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct video_event
+ *ev</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the event, if any, is to be
+ stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>ev points to invalid address</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EWOULDBLOCK</para>
+</entry><entry
+ align="char">
+<para>There is no event pending, and the device is in
+ non-blocking mode.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EOVERFLOW</para>
+</entry><entry
+ align="char">
+</entry>
+ </row><row><entry
+ align="char">
+</entry><entry
+ align="char">
+<para>Overflow in event queue - one or more events were lost.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_DISPLAY_FORMAT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to select the video format to be applied
+ by the MPEG chip on the video.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request =
+ VIDEO_SET_DISPLAY_FORMAT, video_display_format_t
+ format);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_DISPLAY_FORMAT for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_display_format_t
+ format</para>
+</entry><entry
+ align="char">
+<para>Selects the video format to be used.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal parameter format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_STILLPICTURE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to display a still picture (I-frame). The
+ input data shall contain an I-frame. If the pointer is NULL, then the current
+ displayed still picture is blanked.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_STILLPICTURE,
+ struct video_still_picture &#x22C6;sp);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_STILLPICTURE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct
+ video_still_picture
+ *sp</para>
+</entry><entry
+ align="char">
+<para>Pointer to a location where an I-frame and size is stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>sp points to an invalid iframe.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_FAST_FORWARD</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the Video Device to skip decoding of N number of I-frames.
+ This call can only be used if VIDEO_SOURCE_MEMORY is selected.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_FAST_FORWARD, int
+ nFrames);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_FAST_FORWARD for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int nFrames</para>
+</entry><entry
+ align="char">
+<para>The number of frames to skip.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal parameter format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SLOWMOTION</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the video device to repeat decoding frames N number of
+ times. This call can only be used if VIDEO_SOURCE_MEMORY is selected.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SLOWMOTION, int
+ nFrames);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SLOWMOTION for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int nFrames</para>
+</entry><entry
+ align="char">
+<para>The number of times to repeat each frame.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EPERM</para>
+</entry><entry
+ align="char">
+<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Illegal parameter format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_CAPABILITIES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call asks the video device about its decoding capabilities. On success
+ it returns and integer which has bits set according to the defines in section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_GET_CAPABILITIES,
+ unsigned int &#x22C6;cap);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_CAPABILITIES for this
+ command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>unsigned int *cap</para>
+</entry><entry
+ align="char">
+<para>Pointer to a location where to store the capability
+ information.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>cap points to an invalid iframe.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_ID</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl selects which sub-stream is to be decoded if a program or system
+ stream is sent to the video device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = VIDEO_SET_ID, int
+ id);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_ID for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int id</para>
+</entry><entry
+ align="char">
+<para>video sub-stream id</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINTERNAL</para>
+</entry><entry
+ align="char">
+<para>Internal error.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>Invalid sub-stream id.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_CLEAR_BUFFER</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call clears all video buffers in the driver and in the decoder hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_CLEAR_BUFFER);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_CLEAR_BUFFER for this command.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_STREAMTYPE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl tells the driver which kind of stream to expect being written to it. If
+ this call is not used the default of video PES is used. Some drivers might not
+ support this call and always expect PES.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(fd, int request = VIDEO_SET_STREAMTYPE,
+ int type);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_STREAMTYPE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int type</para>
+</entry><entry
+ align="char">
+<para>stream type</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>type is not a valid or supported stream type.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_FORMAT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the screen format (aspect ratio) of the connected output device
+ (TV) so that the output of the decoder can be adjusted accordingly.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_FORMAT,
+ video_format_t format);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_FORMAT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_format_t
+ format</para>
+</entry><entry
+ align="char">
+<para>video format of TV as defined in section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>format is not a valid video format.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_SYSTEM</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the television output format. The format (see section ??) may
+ vary from the color format of the displayed MPEG stream. If the hardware is
+ not able to display the requested format the call will return an error.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_SYSTEM ,
+ video_system_t system);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_FORMAT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_system_t
+ system</para>
+</entry><entry
+ align="char">
+<para>video system of TV output.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>system is not a valid or supported video system.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_HIGHLIGHT</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the SPU highlight information for the menu access of a DVD.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_HIGHLIGHT
+ ,video_highlight_t &#x22C6;vhilite)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_HIGHLIGHT for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_highlight_t
+ *vhilite</para>
+</entry><entry
+ align="char">
+<para>SPU Highlight information according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid highlight setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_SPU</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl activates or deactivates SPU decoding in a DVD input stream. It can
+ only be used, if the driver is able to handle a DVD stream.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_SPU ,
+ video_spu_t &#x22C6;spu)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_SPU for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_spu_t *spu</para>
+</entry><entry
+ align="char">
+<para>SPU decoding (de)activation and subid setting according
+ to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid spu setting or driver cannot handle
+ SPU.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_SPU_PALETTE</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl sets the SPU color palette.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_SPU_PALETTE
+ ,video_spu_palette_t &#x22C6;palette )</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_SPU_PALETTE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_spu_palette_t
+ *palette</para>
+</entry><entry
+ align="char">
+<para>SPU palette according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid palette or driver doesn&#8217;t handle SPU.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_GET_NAVI</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl returns navigational information from the DVD stream. This is
+ especially needed if an encoded stream has to be decoded by the hardware.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_GET_NAVI ,
+ video_navi_pack_t &#x22C6;navipack)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_GET_NAVI for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_navi_pack_t
+ *navipack</para>
+</entry><entry
+ align="char">
+<para>PCI or DSI pack (private stream 2) according to section
+ ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EFAULT</para>
+</entry><entry
+ align="char">
+<para>driver is not able to return navigational information</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+
+</section><section
+role="subsection"><title>VIDEO_SET_ATTRIBUTES</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl is intended for DVD playback and allows you to set certain
+ information about the stream. Some hardware may not need this information,
+ but the call also tells the hardware to prepare for DVD playback.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para> int ioctl(fd, int request = VIDEO_SET_ATTRIBUTE
+ ,video_attributes_t vattr)</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int request</para>
+</entry><entry
+ align="char">
+<para>Equals VIDEO_SET_ATTRIBUTE for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>video_attributes_t
+ vattr</para>
+</entry><entry
+ align="char">
+<para>video attributes according to section ??.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry
+ align="char">
+<para>EBADF</para>
+</entry><entry
+ align="char">
+<para>fd is not a valid open file descriptor</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>EINVAL</para>
+</entry><entry
+ align="char">
+<para>input is not a valid attribute setting.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+ </section></section>
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
new file mode 100644
index 0000000..0eb43c1
--- /dev/null
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -0,0 +1,364 @@
+<!-- Generated file! Do not edit. -->
+
+<!-- Functions -->
+<!ENTITY func-close "<link linkend='func-close'><function>close()</function></link>">
+<!ENTITY func-ioctl "<link linkend='func-ioctl'><function>ioctl()</function></link>">
+<!ENTITY func-mmap "<link linkend='func-mmap'><function>mmap()</function></link>">
+<!ENTITY func-munmap "<link linkend='func-munmap'><function>munmap()</function></link>">
+<!ENTITY func-open "<link linkend='func-open'><function>open()</function></link>">
+<!ENTITY func-poll "<link linkend='func-poll'><function>poll()</function></link>">
+<!ENTITY func-read "<link linkend='func-read'><function>read()</function></link>">
+<!ENTITY func-select "<link linkend='func-select'><function>select()</function></link>">
+<!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>">
+
+<!-- Ioctls -->
+<!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>">
+<!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</constant></link>">
+<!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>">
+<!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>">
+<!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>">
+<!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>">
+<!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>">
+<!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">
+<!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>">
+<!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>">
+<!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>">
+<!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>">
+<!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>">
+<!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>">
+<!ENTITY VIDIOC-G-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_G_AUDIO</constant></link>">
+<!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>">
+<!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>">
+<!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>">
+<!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>">
+<!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>">
+<!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>">
+<!ENTITY VIDIOC-G-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_G_FMT</constant></link>">
+<!ENTITY VIDIOC-G-FREQUENCY "<link linkend='vidioc-g-frequency'><constant>VIDIOC_G_FREQUENCY</constant></link>">
+<!ENTITY VIDIOC-G-INPUT "<link linkend='vidioc-g-input'><constant>VIDIOC_G_INPUT</constant></link>">
+<!ENTITY VIDIOC-G-JPEGCOMP "<link linkend='vidioc-g-jpegcomp'><constant>VIDIOC_G_JPEGCOMP</constant></link>">
+<!ENTITY VIDIOC-G-MPEGCOMP "<link linkend=''><constant>VIDIOC_G_MPEGCOMP</constant></link>">
+<!ENTITY VIDIOC-G-MODULATOR "<link linkend='vidioc-g-modulator'><constant>VIDIOC_G_MODULATOR</constant></link>">
+<!ENTITY VIDIOC-G-OUTPUT "<link linkend='vidioc-g-output'><constant>VIDIOC_G_OUTPUT</constant></link>">
+<!ENTITY VIDIOC-G-PARM "<link linkend='vidioc-g-parm'><constant>VIDIOC_G_PARM</constant></link>">
+<!ENTITY VIDIOC-G-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_G_PRIORITY</constant></link>">
+<!ENTITY VIDIOC-G-SLICED-VBI-CAP "<link linkend='vidioc-g-sliced-vbi-cap'><constant>VIDIOC_G_SLICED_VBI_CAP</constant></link>">
+<!ENTITY VIDIOC-G-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_G_STD</constant></link>">
+<!ENTITY VIDIOC-G-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_G_TUNER</constant></link>">
+<!ENTITY VIDIOC-LOG-STATUS "<link linkend='vidioc-log-status'><constant>VIDIOC_LOG_STATUS</constant></link>">
+<!ENTITY VIDIOC-OVERLAY "<link linkend='vidioc-overlay'><constant>VIDIOC_OVERLAY</constant></link>">
+<!ENTITY VIDIOC-QBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_QBUF</constant></link>">
+<!ENTITY VIDIOC-QUERYBUF "<link linkend='vidioc-querybuf'><constant>VIDIOC_QUERYBUF</constant></link>">
+<!ENTITY VIDIOC-QUERYCAP "<link linkend='vidioc-querycap'><constant>VIDIOC_QUERYCAP</constant></link>">
+<!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>">
+<!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>">
+<!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>">
+<!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
+<!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
+<!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
+<!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>">
+<!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
+<!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
+<!ENTITY VIDIOC-S-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>">
+<!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>">
+<!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>">
+<!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>">
+<!ENTITY VIDIOC-S-FREQUENCY "<link linkend='vidioc-g-frequency'><constant>VIDIOC_S_FREQUENCY</constant></link>">
+<!ENTITY VIDIOC-S-HW-FREQ-SEEK "<link linkend='vidioc-s-hw-freq-seek'><constant>VIDIOC_S_HW_FREQ_SEEK</constant></link>">
+<!ENTITY VIDIOC-S-INPUT "<link linkend='vidioc-g-input'><constant>VIDIOC_S_INPUT</constant></link>">
+<!ENTITY VIDIOC-S-JPEGCOMP "<link linkend='vidioc-g-jpegcomp'><constant>VIDIOC_S_JPEGCOMP</constant></link>">
+<!ENTITY VIDIOC-S-MPEGCOMP "<link linkend=''><constant>VIDIOC_S_MPEGCOMP</constant></link>">
+<!ENTITY VIDIOC-S-MODULATOR "<link linkend='vidioc-g-modulator'><constant>VIDIOC_S_MODULATOR</constant></link>">
+<!ENTITY VIDIOC-S-OUTPUT "<link linkend='vidioc-g-output'><constant>VIDIOC_S_OUTPUT</constant></link>">
+<!ENTITY VIDIOC-S-PARM "<link linkend='vidioc-g-parm'><constant>VIDIOC_S_PARM</constant></link>">
+<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>">
+<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>">
+<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
+<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
+<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
+<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
+
+<!-- Types -->
+<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
+
+<!-- Enums -->
+<!ENTITY v4l2-buf-type "enum&nbsp;<link linkend='v4l2-buf-type'>v4l2_buf_type</link>">
+<!ENTITY v4l2-colorspace "enum&nbsp;<link linkend='v4l2-colorspace'>v4l2_colorspace</link>">
+<!ENTITY v4l2-ctrl-type "enum&nbsp;<link linkend='v4l2-ctrl-type'>v4l2_ctrl_type</link>">
+<!ENTITY v4l2-exposure-auto-type "enum&nbsp;<link linkend='v4l2-exposure-auto-type'>v4l2_exposure_auto_type</link>">
+<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>">
+<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>">
+<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>">
+<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>">
+<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>">
+<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>">
+<!ENTITY v4l2-mpeg-audio-emphasis "enum&nbsp;<link linkend='v4l2-mpeg-audio-emphasis'>v4l2_mpeg_audio_emphasis</link>">
+<!ENTITY v4l2-mpeg-audio-encoding "enum&nbsp;<link linkend='v4l2-mpeg-audio-encoding'>v4l2_mpeg_audio_encoding</link>">
+<!ENTITY v4l2-mpeg-audio-l1-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l1-bitrate'>v4l2_mpeg_audio_l1_bitrate</link>">
+<!ENTITY v4l2-mpeg-audio-l2-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l2-bitrate'>v4l2_mpeg_audio_l2_bitrate</link>">
+<!ENTITY v4l2-mpeg-audio-l3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l3-bitrate'>v4l2_mpeg_audio_l3_bitrate</link>">
+<!ENTITY v4l2-mpeg-audio-mode "enum&nbsp;<link linkend='v4l2-mpeg-audio-mode'>v4l2_mpeg_audio_mode</link>">
+<!ENTITY v4l2-mpeg-audio-mode-extension "enum&nbsp;<link linkend='v4l2-mpeg-audio-mode-extension'>v4l2_mpeg_audio_mode_extension</link>">
+<!ENTITY v4l2-mpeg-audio-sampling-freq "enum&nbsp;<link linkend='v4l2-mpeg-audio-sampling-freq'>v4l2_mpeg_audio_sampling_freq</link>">
+<!ENTITY chroma-spatial-filter-type "enum&nbsp;<link linkend='chroma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link>">
+<!ENTITY luma-spatial-filter-type "enum&nbsp;<link linkend='luma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link>">
+<!ENTITY v4l2-mpeg-cx2341x-video-median-filter-type "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-median-filter-type'>v4l2_mpeg_cx2341x_video_median_filter_type</link>">
+<!ENTITY v4l2-mpeg-cx2341x-video-spatial-filter-mode "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-spatial-filter-mode'>v4l2_mpeg_cx2341x_video_spatial_filter_mode</link>">
+<!ENTITY v4l2-mpeg-cx2341x-video-temporal-filter-mode "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-temporal-filter-mode'>v4l2_mpeg_cx2341x_video_temporal_filter_mode</link>">
+<!ENTITY v4l2-mpeg-stream-type "enum&nbsp;<link linkend='v4l2-mpeg-stream-type'>v4l2_mpeg_stream_type</link>">
+<!ENTITY v4l2-mpeg-stream-vbi-fmt "enum&nbsp;<link linkend='v4l2-mpeg-stream-vbi-fmt'>v4l2_mpeg_stream_vbi_fmt</link>">
+<!ENTITY v4l2-mpeg-video-aspect "enum&nbsp;<link linkend='v4l2-mpeg-video-aspect'>v4l2_mpeg_video_aspect</link>">
+<!ENTITY v4l2-mpeg-video-bitrate-mode "enum&nbsp;<link linkend='v4l2-mpeg-video-bitrate-mode'>v4l2_mpeg_video_bitrate_mode</link>">
+<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>">
+<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>">
+<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>">
+<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>">
+<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>">
+
+<!-- Structures -->
+<!ENTITY v4l2-audio "struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link>">
+<!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
+<!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
+<!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
+<!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
+<!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>">
+<!ENTITY v4l2-control "struct&nbsp;<link linkend='v4l2-control'>v4l2_control</link>">
+<!ENTITY v4l2-crop "struct&nbsp;<link linkend='v4l2-crop'>v4l2_crop</link>">
+<!ENTITY v4l2-cropcap "struct&nbsp;<link linkend='v4l2-cropcap'>v4l2_cropcap</link>">
+<!ENTITY v4l2-dbg-chip-ident "struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>">
+<!ENTITY v4l2-dbg-match "struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>">
+<!ENTITY v4l2-dbg-register "struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>">
+<!ENTITY v4l2-enc-idx "struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
+<!ENTITY v4l2-enc-idx-entry "struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
+<!ENTITY v4l2-encoder-cmd "struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
+<!ENTITY v4l2-ext-control "struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link>">
+<!ENTITY v4l2-ext-controls "struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>">
+<!ENTITY v4l2-fmtdesc "struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">
+<!ENTITY v4l2-format "struct&nbsp;<link linkend='v4l2-format'>v4l2_format</link>">
+<!ENTITY v4l2-fract "struct&nbsp;<link linkend='v4l2-fract'>v4l2_fract</link>">
+<!ENTITY v4l2-framebuffer "struct&nbsp;<link linkend='v4l2-framebuffer'>v4l2_framebuffer</link>">
+<!ENTITY v4l2-frequency "struct&nbsp;<link linkend='v4l2-frequency'>v4l2_frequency</link>">
+<!ENTITY v4l2-frmival-stepwise "struct&nbsp;<link linkend='v4l2-frmival-stepwise'>v4l2_frmival_stepwise</link>">
+<!ENTITY v4l2-frmivalenum "struct&nbsp;<link linkend='v4l2-frmivalenum'>v4l2_frmivalenum</link>">
+<!ENTITY v4l2-frmsize-discrete "struct&nbsp;<link linkend='v4l2-frmsize-discrete'>v4l2_frmsize_discrete</link>">
+<!ENTITY v4l2-frmsize-stepwise "struct&nbsp;<link linkend='v4l2-frmsize-stepwise'>v4l2_frmsize_stepwise</link>">
+<!ENTITY v4l2-frmsizeenum "struct&nbsp;<link linkend='v4l2-frmsizeenum'>v4l2_frmsizeenum</link>">
+<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>">
+<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>">
+<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>">
+<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>">
+<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>">
+<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>">
+<!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>">
+<!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>">
+<!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>">
+<!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>">
+<!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>">
+<!ENTITY v4l2-requestbuffers "struct&nbsp;<link linkend='v4l2-requestbuffers'>v4l2_requestbuffers</link>">
+<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>">
+<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>">
+<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
+<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
+<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>">
+<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>">
+<!ENTITY v4l2-tuner "struct&nbsp;<link linkend='v4l2-tuner'>v4l2_tuner</link>">
+<!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>">
+<!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>">
+
+<!-- Error Codes -->
+<!ENTITY EACCES "<errorcode>EACCES</errorcode> error code">
+<!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code">
+<!ENTITY EBADF "<errorcode>EBADF</errorcode> error code">
+<!ENTITY EBUSY "<errorcode>EBUSY</errorcode> error code">
+<!ENTITY EFAULT "<errorcode>EFAULT</errorcode> error code">
+<!ENTITY EIO "<errorcode>EIO</errorcode> error code">
+<!ENTITY EINTR "<errorcode>EINTR</errorcode> error code">
+<!ENTITY EINVAL "<errorcode>EINVAL</errorcode> error code">
+<!ENTITY ENFILE "<errorcode>ENFILE</errorcode> error code">
+<!ENTITY ENOMEM "<errorcode>ENOMEM</errorcode> error code">
+<!ENTITY ENOSPC "<errorcode>ENOSPC</errorcode> error code">
+<!ENTITY ENOTTY "<errorcode>ENOTTY</errorcode> error code">
+<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code">
+<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code">
+<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code">
+<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code">
+
+<!-- Subsections -->
+<!ENTITY sub-biblio SYSTEM "v4l/biblio.xml">
+<!ENTITY sub-common SYSTEM "v4l/common.xml">
+<!ENTITY sub-compat SYSTEM "v4l/compat.xml">
+<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
+<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
+<!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml">
+<!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml">
+<!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml">
+<!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">
+<!ENTITY sub-dev-overlay SYSTEM "v4l/dev-overlay.xml">
+<!ENTITY sub-dev-radio SYSTEM "v4l/dev-radio.xml">
+<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml">
+<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml">
+<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml">
+<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
+<!ENTITY sub-driver SYSTEM "v4l/driver.xml">
+<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
+<!ENTITY sub-remote_controllers SYSTEM "v4l/remote_controllers.xml">
+<!ENTITY sub-fdl-appendix SYSTEM "v4l/fdl-appendix.xml">
+<!ENTITY sub-close SYSTEM "v4l/func-close.xml">
+<!ENTITY sub-ioctl SYSTEM "v4l/func-ioctl.xml">
+<!ENTITY sub-mmap SYSTEM "v4l/func-mmap.xml">
+<!ENTITY sub-munmap SYSTEM "v4l/func-munmap.xml">
+<!ENTITY sub-open SYSTEM "v4l/func-open.xml">
+<!ENTITY sub-poll SYSTEM "v4l/func-poll.xml">
+<!ENTITY sub-read SYSTEM "v4l/func-read.xml">
+<!ENTITY sub-select SYSTEM "v4l/func-select.xml">
+<!ENTITY sub-write SYSTEM "v4l/func-write.xml">
+<!ENTITY sub-io SYSTEM "v4l/io.xml">
+<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
+<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
+<!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml">
+<!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
+<!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
+<!ENTITY sub-sbggr16 SYSTEM "v4l/pixfmt-sbggr16.xml">
+<!ENTITY sub-sbggr8 SYSTEM "v4l/pixfmt-sbggr8.xml">
+<!ENTITY sub-sgbrg8 SYSTEM "v4l/pixfmt-sgbrg8.xml">
+<!ENTITY sub-sgrbg8 SYSTEM "v4l/pixfmt-sgrbg8.xml">
+<!ENTITY sub-uyvy SYSTEM "v4l/pixfmt-uyvy.xml">
+<!ENTITY sub-vyuy SYSTEM "v4l/pixfmt-vyuy.xml">
+<!ENTITY sub-y16 SYSTEM "v4l/pixfmt-y16.xml">
+<!ENTITY sub-y41p SYSTEM "v4l/pixfmt-y41p.xml">
+<!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
+<!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
+<!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
+<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
+<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
+<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
+<!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
+<!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
+<!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
+<!ENTITY sub-encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml">
+<!ENTITY sub-enum-fmt SYSTEM "v4l/vidioc-enum-fmt.xml">
+<!ENTITY sub-enum-frameintervals SYSTEM "v4l/vidioc-enum-frameintervals.xml">
+<!ENTITY sub-enum-framesizes SYSTEM "v4l/vidioc-enum-framesizes.xml">
+<!ENTITY sub-enumaudio SYSTEM "v4l/vidioc-enumaudio.xml">
+<!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
+<!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml">
+<!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
+<!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml">
+<!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml">
+<!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
+<!ENTITY sub-dbg-g-chip-ident SYSTEM "v4l/vidioc-dbg-g-chip-ident.xml">
+<!ENTITY sub-g-crop SYSTEM "v4l/vidioc-g-crop.xml">
+<!ENTITY sub-g-ctrl SYSTEM "v4l/vidioc-g-ctrl.xml">
+<!ENTITY sub-g-enc-index SYSTEM "v4l/vidioc-g-enc-index.xml">
+<!ENTITY sub-g-ext-ctrls SYSTEM "v4l/vidioc-g-ext-ctrls.xml">
+<!ENTITY sub-g-fbuf SYSTEM "v4l/vidioc-g-fbuf.xml">
+<!ENTITY sub-g-fmt SYSTEM "v4l/vidioc-g-fmt.xml">
+<!ENTITY sub-g-frequency SYSTEM "v4l/vidioc-g-frequency.xml">
+<!ENTITY sub-g-input SYSTEM "v4l/vidioc-g-input.xml">
+<!ENTITY sub-g-jpegcomp SYSTEM "v4l/vidioc-g-jpegcomp.xml">
+<!ENTITY sub-g-modulator SYSTEM "v4l/vidioc-g-modulator.xml">
+<!ENTITY sub-g-output SYSTEM "v4l/vidioc-g-output.xml">
+<!ENTITY sub-g-parm SYSTEM "v4l/vidioc-g-parm.xml">
+<!ENTITY sub-g-priority SYSTEM "v4l/vidioc-g-priority.xml">
+<!ENTITY sub-g-sliced-vbi-cap SYSTEM "v4l/vidioc-g-sliced-vbi-cap.xml">
+<!ENTITY sub-g-std SYSTEM "v4l/vidioc-g-std.xml">
+<!ENTITY sub-g-tuner SYSTEM "v4l/vidioc-g-tuner.xml">
+<!ENTITY sub-log-status SYSTEM "v4l/vidioc-log-status.xml">
+<!ENTITY sub-overlay SYSTEM "v4l/vidioc-overlay.xml">
+<!ENTITY sub-qbuf SYSTEM "v4l/vidioc-qbuf.xml">
+<!ENTITY sub-querybuf SYSTEM "v4l/vidioc-querybuf.xml">
+<!ENTITY sub-querycap SYSTEM "v4l/vidioc-querycap.xml">
+<!ENTITY sub-queryctrl SYSTEM "v4l/vidioc-queryctrl.xml">
+<!ENTITY sub-querystd SYSTEM "v4l/vidioc-querystd.xml">
+<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
+<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
+<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml">
+<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
+<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
+<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
+<!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml">
+<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
+<!ENTITY sub-intro SYSTEM "dvb/intro.xml">
+<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
+<!ENTITY sub-isdbt SYSTEM "dvb/isdbt.xml">
+<!ENTITY sub-demux SYSTEM "dvb/demux.xml">
+<!ENTITY sub-video SYSTEM "dvb/video.xml">
+<!ENTITY sub-audio SYSTEM "dvb/audio.xml">
+<!ENTITY sub-ca SYSTEM "dvb/ca.xml">
+<!ENTITY sub-net SYSTEM "dvb/net.xml">
+<!ENTITY sub-kdapi SYSTEM "dvb/kdapi.xml">
+<!ENTITY sub-examples SYSTEM "dvb/examples.xml">
+<!ENTITY sub-dvbapi SYSTEM "dvb/dvbapi.xml">
+<!ENTITY sub-media SYSTEM "media.xml">
+<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
+<!ENTITY sub-media-indices SYSTEM "media-indices.tmpl">
+
+<!-- Function Reference -->
+<!ENTITY close SYSTEM "v4l/func-close.xml">
+<!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml">
+<!ENTITY mmap SYSTEM "v4l/func-mmap.xml">
+<!ENTITY munmap SYSTEM "v4l/func-munmap.xml">
+<!ENTITY open SYSTEM "v4l/func-open.xml">
+<!ENTITY poll SYSTEM "v4l/func-poll.xml">
+<!ENTITY read SYSTEM "v4l/func-read.xml">
+<!ENTITY select SYSTEM "v4l/func-select.xml">
+<!ENTITY write SYSTEM "v4l/func-write.xml">
+<!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml">
+<!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml">
+<!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml">
+<!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
+<!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
+<!ENTITY sbggr16 SYSTEM "v4l/pixfmt-sbggr16.xml">
+<!ENTITY sbggr8 SYSTEM "v4l/pixfmt-sbggr8.xml">
+<!ENTITY sgbrg8 SYSTEM "v4l/pixfmt-sgbrg8.xml">
+<!ENTITY sgrbg8 SYSTEM "v4l/pixfmt-sgrbg8.xml">
+<!ENTITY uyvy SYSTEM "v4l/pixfmt-uyvy.xml">
+<!ENTITY vyuy SYSTEM "v4l/pixfmt-vyuy.xml">
+<!ENTITY y16 SYSTEM "v4l/pixfmt-y16.xml">
+<!ENTITY y41p SYSTEM "v4l/pixfmt-y41p.xml">
+<!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
+<!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
+<!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
+<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
+<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
+<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
+<!ENTITY cropcap SYSTEM "v4l/vidioc-cropcap.xml">
+<!ENTITY dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
+<!ENTITY encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml">
+<!ENTITY enum-fmt SYSTEM "v4l/vidioc-enum-fmt.xml">
+<!ENTITY enum-frameintervals SYSTEM "v4l/vidioc-enum-frameintervals.xml">
+<!ENTITY enum-framesizes SYSTEM "v4l/vidioc-enum-framesizes.xml">
+<!ENTITY enumaudio SYSTEM "v4l/vidioc-enumaudio.xml">
+<!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
+<!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml">
+<!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
+<!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml">
+<!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml">
+<!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
+<!ENTITY dbg-g-chip-ident SYSTEM "v4l/vidioc-dbg-g-chip-ident.xml">
+<!ENTITY g-crop SYSTEM "v4l/vidioc-g-crop.xml">
+<!ENTITY g-ctrl SYSTEM "v4l/vidioc-g-ctrl.xml">
+<!ENTITY g-enc-index SYSTEM "v4l/vidioc-g-enc-index.xml">
+<!ENTITY g-ext-ctrls SYSTEM "v4l/vidioc-g-ext-ctrls.xml">
+<!ENTITY g-fbuf SYSTEM "v4l/vidioc-g-fbuf.xml">
+<!ENTITY g-fmt SYSTEM "v4l/vidioc-g-fmt.xml">
+<!ENTITY g-frequency SYSTEM "v4l/vidioc-g-frequency.xml">
+<!ENTITY g-input SYSTEM "v4l/vidioc-g-input.xml">
+<!ENTITY g-jpegcomp SYSTEM "v4l/vidioc-g-jpegcomp.xml">
+<!ENTITY g-modulator SYSTEM "v4l/vidioc-g-modulator.xml">
+<!ENTITY g-output SYSTEM "v4l/vidioc-g-output.xml">
+<!ENTITY g-parm SYSTEM "v4l/vidioc-g-parm.xml">
+<!ENTITY g-priority SYSTEM "v4l/vidioc-g-priority.xml">
+<!ENTITY g-sliced-vbi-cap SYSTEM "v4l/vidioc-g-sliced-vbi-cap.xml">
+<!ENTITY g-std SYSTEM "v4l/vidioc-g-std.xml">
+<!ENTITY g-tuner SYSTEM "v4l/vidioc-g-tuner.xml">
+<!ENTITY log-status SYSTEM "v4l/vidioc-log-status.xml">
+<!ENTITY overlay SYSTEM "v4l/vidioc-overlay.xml">
+<!ENTITY qbuf SYSTEM "v4l/vidioc-qbuf.xml">
+<!ENTITY querybuf SYSTEM "v4l/vidioc-querybuf.xml">
+<!ENTITY querycap SYSTEM "v4l/vidioc-querycap.xml">
+<!ENTITY queryctrl SYSTEM "v4l/vidioc-queryctrl.xml">
+<!ENTITY querystd SYSTEM "v4l/vidioc-querystd.xml">
+<!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
+<!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
+<!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml">
diff --git a/Documentation/DocBook/media-indices.tmpl b/Documentation/DocBook/media-indices.tmpl
new file mode 100644
index 0000000..9e30a23
--- /dev/null
+++ b/Documentation/DocBook/media-indices.tmpl
@@ -0,0 +1,85 @@
+<!-- Generated file! Do not edit. -->
+
+<index><title>List of Types</title>
+<indexentry><primaryie><link linkend='v4l2-std-id'>v4l2_std_id</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-buf-type'>v4l2_buf_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-colorspace'>v4l2_colorspace</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-ctrl-type'>v4l2_ctrl_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-exposure-auto-type'>v4l2_exposure_auto_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-emphasis'>v4l2_mpeg_audio_emphasis</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-encoding'>v4l2_mpeg_audio_encoding</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l1-bitrate'>v4l2_mpeg_audio_l1_bitrate</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l2-bitrate'>v4l2_mpeg_audio_l2_bitrate</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l3-bitrate'>v4l2_mpeg_audio_l3_bitrate</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-mode'>v4l2_mpeg_audio_mode</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-mode-extension'>v4l2_mpeg_audio_mode_extension</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-sampling-freq'>v4l2_mpeg_audio_sampling_freq</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='chroma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='luma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-median-filter-type'>v4l2_mpeg_cx2341x_video_median_filter_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-spatial-filter-mode'>v4l2_mpeg_cx2341x_video_spatial_filter_mode</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-temporal-filter-mode'>v4l2_mpeg_cx2341x_video_temporal_filter_mode</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-stream-type'>v4l2_mpeg_stream_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-stream-vbi-fmt'>v4l2_mpeg_stream_vbi_fmt</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-aspect'>v4l2_mpeg_video_aspect</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-bitrate-mode'>v4l2_mpeg_video_bitrate_mode</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link></primaryie></indexentry>
+<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-control'>v4l2_control</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-crop'>v4l2_crop</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-cropcap'>v4l2_cropcap</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-format'>v4l2_format</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-fract'>v4l2_fract</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-framebuffer'>v4l2_framebuffer</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frequency'>v4l2_frequency</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmival-stepwise'>v4l2_frmival_stepwise</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmivalenum'>v4l2_frmivalenum</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsize-discrete'>v4l2_frmsize_discrete</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsize-stepwise'>v4l2_frmsize_stepwise</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsizeenum'>v4l2_frmsizeenum</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-requestbuffers'>v4l2_requestbuffers</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-tuner'>v4l2_tuner</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link></primaryie></indexentry>
+<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link></primaryie></indexentry>
+</index>
diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl
new file mode 100644
index 0000000..eea564b
--- /dev/null
+++ b/Documentation/DocBook/media.tmpl
@@ -0,0 +1,112 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities;
+<!ENTITY media-indices SYSTEM "./media-indices.tmpl">
+
+<!ENTITY eg                     "e.&nbsp;g.">
+<!ENTITY ie                     "i.&nbsp;e.">
+<!ENTITY fd                     "File descriptor returned by <link linkend='func-open'><function>open()</function></link>.">
+<!ENTITY i2c                    "I<superscript>2</superscript>C">
+<!ENTITY return-value		"<title>Return Value</title><para>On success <returnvalue>0</returnvalue> is returned, on error <returnvalue>-1</returnvalue> and the <varname>errno</varname> variable is set appropriately:</para>">
+<!ENTITY manvol                 "<manvolnum>2</manvolnum>">
+
+<!-- Table templates: structs, structs w/union, defines. -->
+<!ENTITY cs-str                 "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
+<!ENTITY cs-ustr                "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='1*' /><colspec colname='c4' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c4' />">
+<!ENTITY cs-def                 "<colspec colname='c1' colwidth='3*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='4*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
+
+<!-- Video for Linux mailing list address. -->
+<!ENTITY v4l-ml                 "<ulink url='http://www.linuxtv.org/lists.php'>http://www.linuxtv.org/lists.php</ulink>">
+
+<!-- LinuxTV v4l-dvb repository. -->
+<!ENTITY v4l-dvb		"<ulink url='http://linuxtv.org/repo/'>http://linuxtv.org/repo/</ulink>">
+]>
+
+<book id="media_api">
+<bookinfo>
+<title>LINUX MEDIA INFRASTRUCTURE API</title>
+
+<copyright>
+	<year>2009</year>
+	<holder>LinuxTV Developers</holder>
+</copyright>
+
+<legalnotice>
+
+<para>Permission is granted to copy, distribute and/or modify
+this document under the terms of the GNU Free Documentation License,
+Version 1.1 or any later version published by the Free Software
+Foundation. A copy of the license is included in the chapter entitled
+"GNU Free Documentation License"</para>
+</legalnotice>
+
+</bookinfo>
+
+<toc></toc> <!-- autogenerated -->
+
+<preface>
+	<title>Introduction</title>
+
+	<para>This document covers the Linux Kernel to Userspace API's used by
+		video and radio straming devices, including video cameras,
+		analog and digital TV receiver cards, AM/FM receiver cards,
+		streaming capture devices.</para>
+	<para>It is divided into three parts.</para>
+	<para>The first part covers radio, capture,
+		cameras and analog TV devices.</para>
+	<para>The second part covers the
+		API used for digital TV and Internet reception via one of the
+		several digital tv standards. While it is called as DVB API,
+		in fact it covers several different video standards including
+		DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
+		to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
+	<para>The third part covers other API's used by all media infrastructure devices</para>
+	<para>For additional information and for the latest development code,
+		see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
+	<para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
+
+</preface>
+
+<part id="v4l2spec">
+&sub-v4l2;
+</part>
+<part id="dvbapi">
+&sub-dvbapi;
+</part>
+<part id="v4ldvb_common">
+<partinfo>
+<authorgroup>
+<author>
+<firstname>Mauro</firstname>
+<surname>Chehab</surname>
+<othername role="mi">Carvalho</othername>
+<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
+<contrib>Initial version.</contrib>
+</author>
+</authorgroup>
+<copyright>
+	<year>2009</year>
+	<holder>Mauro Carvalho Chehab</holder>
+</copyright>
+
+<revhistory>
+<!-- Put document revisions here, newest first. -->
+<revision>
+<revnumber>1.0.0</revnumber>
+<date>2009-09-06</date>
+<authorinitials>mcc</authorinitials>
+<revremark>Initial revision</revremark>
+</revision>
+</revhistory>
+</partinfo>
+
+<title>Other API's used by media infrastructure drivers</title>
+<chapter id="remote_controllers">
+&sub-remote_controllers;
+</chapter>
+</part>
+
+&sub-fdl-appendix;
+
+</book>
diff --git a/Documentation/DocBook/stylesheet.xsl b/Documentation/DocBook/stylesheet.xsl
index 974e17c..254c1d5 100644
--- a/Documentation/DocBook/stylesheet.xsl
+++ b/Documentation/DocBook/stylesheet.xsl
@@ -3,6 +3,7 @@
 <param name="chunk.quietly">1</param>
 <param name="funcsynopsis.style">ansi</param>
 <param name="funcsynopsis.tabular.threshold">80</param>
+<param name="callout.graphics">0</param>
 <!-- <param name="paper.type">A4</param> -->
 <param name="generate.section.toc.level">2</param>
 </stylesheet>
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index 8f6e3b2..4d4ce0e 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -25,6 +25,10 @@
 	<year>2006-2008</year>
 	<holder>Hans-JÃ¼rgen Koch.</holder>
 </copyright>
+<copyright>
+	<year>2009</year>
+	<holder>Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)</holder>
+</copyright>
 
 <legalnotice>
 <para>
@@ -42,6 +46,13 @@ GPL version 2.
 
 <revhistory>
 	<revision>
+	<revnumber>0.9</revnumber>
+	<date>2009-07-16</date>
+	<authorinitials>mst</authorinitials>
+	<revremark>Added generic pci driver
+		</revremark>
+	</revision>
+	<revision>
 	<revnumber>0.8</revnumber>
 	<date>2008-12-24</date>
 	<authorinitials>hjk</authorinitials>
@@ -809,6 +820,158 @@ framework to set up sysfs files for this region. Simply leave it alone.
 
 </chapter>
 
+<chapter id="uio_pci_generic" xreflabel="Using Generic driver for PCI cards">
+<?dbhtml filename="uio_pci_generic.html"?>
+<title>Generic PCI UIO driver</title>
+	<para>
+	The generic driver is a kernel module named uio_pci_generic.
+	It can work with any device compliant to PCI 2.3 (circa 2002) and
+	any compliant PCI Express device. Using this, you only need to
+        write the userspace driver, removing the need to write
+        a hardware-specific kernel module.
+	</para>
+
+<sect1 id="uio_pci_generic_binding">
+<title>Making the driver recognize the device</title>
+	<para>
+Since the driver does not declare any device ids, it will not get loaded
+automatically and will not automatically bind to any devices, you must load it
+and allocate id to the driver yourself. For example:
+	<programlisting>
+ modprobe uio_pci_generic
+ echo &quot;8086 10f5&quot; &gt; /sys/bus/pci/drivers/uio_pci_generic/new_id
+	</programlisting>
+	</para>
+	<para>
+If there already is a hardware specific kernel driver for your device, the
+generic driver still won't bind to it, in this case if you want to use the
+generic driver (why would you?) you'll have to manually unbind the hardware
+specific driver and bind the generic driver, like this:
+	<programlisting>
+    echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/e1000e/unbind
+    echo -n 0000:00:19.0 &gt; /sys/bus/pci/drivers/uio_pci_generic/bind
+	</programlisting>
+	</para>
+	<para>
+You can verify that the device has been bound to the driver
+by looking for it in sysfs, for example like the following:
+	<programlisting>
+    ls -l /sys/bus/pci/devices/0000:00:19.0/driver
+	</programlisting>
+Which if successful should print
+	<programlisting>
+  .../0000:00:19.0/driver -&gt; ../../../bus/pci/drivers/uio_pci_generic
+	</programlisting>
+Note that the generic driver will not bind to old PCI 2.2 devices.
+If binding the device failed, run the following command:
+	<programlisting>
+  dmesg
+	</programlisting>
+and look in the output for failure reasons
+	</para>
+</sect1>
+
+<sect1 id="uio_pci_generic_internals">
+<title>Things to know about uio_pci_generic</title>
+	<para>
+Interrupts are handled using the Interrupt Disable bit in the PCI command
+register and Interrupt Status bit in the PCI status register.  All devices
+compliant to PCI 2.3 (circa 2002) and all compliant PCI Express devices should
+support these bits.  uio_pci_generic detects this support, and won't bind to
+devices which do not support the Interrupt Disable Bit in the command register.
+	</para>
+	<para>
+On each interrupt, uio_pci_generic sets the Interrupt Disable bit.
+This prevents the device from generating further interrupts
+until the bit is cleared. The userspace driver should clear this
+bit before blocking and waiting for more interrupts.
+	</para>
+</sect1>
+<sect1 id="uio_pci_generic_userspace">
+<title>Writing userspace driver using uio_pci_generic</title>
+	<para>
+Userspace driver can use pci sysfs interface, or the
+libpci libray that wraps it, to talk to the device and to
+re-enable interrupts by writing to the command register.
+	</para>
+</sect1>
+<sect1 id="uio_pci_generic_example">
+<title>Example code using uio_pci_generic</title>
+	<para>
+Here is some sample userspace driver code using uio_pci_generic:
+<programlisting>
+#include &lt;stdlib.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;errno.h&gt;
+
+int main()
+{
+	int uiofd;
+	int configfd;
+	int err;
+	int i;
+	unsigned icount;
+	unsigned char command_high;
+
+	uiofd = open(&quot;/dev/uio0&quot;, O_RDONLY);
+	if (uiofd &lt; 0) {
+		perror(&quot;uio open:&quot;);
+		return errno;
+	}
+	configfd = open(&quot;/sys/class/uio/uio0/device/config&quot;, O_RDWR);
+	if (uiofd &lt; 0) {
+		perror(&quot;config open:&quot;);
+		return errno;
+	}
+
+	/* Read and cache command value */
+	err = pread(configfd, &amp;command_high, 1, 5);
+	if (err != 1) {
+		perror(&quot;command config read:&quot;);
+		return errno;
+	}
+	command_high &amp;= ~0x4;
+
+	for(i = 0;; ++i) {
+		/* Print out a message, for debugging. */
+		if (i == 0)
+			fprintf(stderr, &quot;Started uio test driver.\n&quot;);
+		else
+			fprintf(stderr, &quot;Interrupts: %d\n&quot;, icount);
+
+		/****************************************/
+		/* Here we got an interrupt from the
+		   device. Do something to it. */
+		/****************************************/
+
+		/* Re-enable interrupts. */
+		err = pwrite(configfd, &amp;command_high, 1, 5);
+		if (err != 1) {
+			perror(&quot;config write:&quot;);
+			break;
+		}
+
+		/* Wait for next interrupt. */
+		err = read(uiofd, &amp;icount, 4);
+		if (err != 4) {
+			perror(&quot;uio read:&quot;);
+			break;
+		}
+
+	}
+	return errno;
+}
+
+</programlisting>
+	</para>
+</sect1>
+
+</chapter>
+
 <appendix id="app1">
 <title>Further information</title>
 <itemizedlist>
diff --git a/Documentation/DocBook/v4l/.gitignore b/Documentation/DocBook/v4l/.gitignore
new file mode 100644
index 0000000..d7ec32e
--- /dev/null
+++ b/Documentation/DocBook/v4l/.gitignore
@@ -0,0 +1 @@
+!*.xml
diff --git a/Documentation/DocBook/v4l/biblio.xml b/Documentation/DocBook/v4l/biblio.xml
new file mode 100644
index 0000000..afc8a0d
--- /dev/null
+++ b/Documentation/DocBook/v4l/biblio.xml
@@ -0,0 +1,188 @@
+  <bibliography>
+    <title>References</title>
+
+    <biblioentry id="eia608">
+      <abbrev>EIA&nbsp;608-B</abbrev>
+      <authorgroup>
+	<corpauthor>Electronic Industries Alliance (<ulink
+url="http://www.eia.org">http://www.eia.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>EIA 608-B "Recommended Practice for Line 21 Data
+Service"</title>
+    </biblioentry>
+
+    <biblioentry id="en300294">
+      <abbrev>EN&nbsp;300&nbsp;294</abbrev>
+      <authorgroup>
+	<corpauthor>European Telecommunication Standards Institute
+(<ulink url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>EN 300 294 "625-line television Wide Screen Signalling
+(WSS)"</title>
+    </biblioentry>
+
+    <biblioentry id="ets300231">
+      <abbrev>ETS&nbsp;300&nbsp;231</abbrev>
+      <authorgroup>
+	<corpauthor>European Telecommunication Standards Institute
+(<ulink
+url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ETS 300 231 "Specification of the domestic video
+Programme Delivery Control system (PDC)"</title>
+    </biblioentry>
+
+    <biblioentry id="ets300706">
+      <abbrev>ETS&nbsp;300&nbsp;706</abbrev>
+      <authorgroup>
+	<corpauthor>European Telecommunication Standards Institute
+(<ulink url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ETS 300 706 "Enhanced Teletext specification"</title>
+    </biblioentry>
+
+    <biblioentry id="mpeg2part1">
+      <abbrev>ISO&nbsp;13818-1</abbrev>
+      <authorgroup>
+	<corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>), International
+Organisation for Standardisation (<ulink
+url="http://www.iso.ch">http://www.iso.ch</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information
+technology &mdash; Generic coding of moving pictures and associated
+audio information: Systems"</title>
+    </biblioentry>
+
+    <biblioentry id="mpeg2part2">
+      <abbrev>ISO&nbsp;13818-2</abbrev>
+      <authorgroup>
+	<corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>), International
+Organisation for Standardisation (<ulink
+url="http://www.iso.ch">http://www.iso.ch</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information
+technology &mdash; Generic coding of moving pictures and associated
+audio information: Video"</title>
+    </biblioentry>
+
+    <biblioentry id="itu470">
+      <abbrev>ITU&nbsp;BT.470</abbrev>
+      <authorgroup>
+	<corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ITU-R Recommendation BT.470-6 "Conventional Television
+Systems"</title>
+    </biblioentry>
+
+    <biblioentry id="itu601">
+      <abbrev>ITU&nbsp;BT.601</abbrev>
+      <authorgroup>
+	<corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ITU-R Recommendation BT.601-5 "Studio Encoding Parameters
+of Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect
+Ratios"</title>
+    </biblioentry>
+
+    <biblioentry id="itu653">
+      <abbrev>ITU&nbsp;BT.653</abbrev>
+      <authorgroup>
+	<corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ITU-R Recommendation BT.653-3 "Teletext systems"</title>
+    </biblioentry>
+
+    <biblioentry id="itu709">
+      <abbrev>ITU&nbsp;BT.709</abbrev>
+      <authorgroup>
+	<corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ITU-R Recommendation BT.709-5 "Parameter values for the
+HDTV standards for production and international programme
+exchange"</title>
+    </biblioentry>
+
+    <biblioentry id="itu1119">
+      <abbrev>ITU&nbsp;BT.1119</abbrev>
+      <authorgroup>
+	<corpauthor>International Telecommunication Union (<ulink
+url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
+      </authorgroup>
+      <title>ITU-R Recommendation BT.1119 "625-line
+television Wide Screen Signalling (WSS)"</title>
+    </biblioentry>
+
+    <biblioentry id="jfif">
+      <abbrev>JFIF</abbrev>
+      <authorgroup>
+	<corpauthor>Independent JPEG Group (<ulink
+url="http://www.ijg.org">http://www.ijg.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>JPEG File Interchange Format</title>
+      <subtitle>Version 1.02</subtitle>
+    </biblioentry>
+
+    <biblioentry id="smpte12m">
+      <abbrev>SMPTE&nbsp;12M</abbrev>
+      <authorgroup>
+	<corpauthor>Society of Motion Picture and Television Engineers
+(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>SMPTE 12M-1999 "Television, Audio and Film - Time and
+Control Code"</title>
+    </biblioentry>
+
+    <biblioentry id="smpte170m">
+      <abbrev>SMPTE&nbsp;170M</abbrev>
+      <authorgroup>
+	<corpauthor>Society of Motion Picture and Television Engineers
+(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>SMPTE 170M-1999 "Television - Composite Analog Video
+Signal - NTSC for Studio Applications"</title>
+    </biblioentry>
+
+    <biblioentry id="smpte240m">
+      <abbrev>SMPTE&nbsp;240M</abbrev>
+      <authorgroup>
+	<corpauthor>Society of Motion Picture and Television Engineers
+(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>SMPTE 240M-1999 "Television - Signal Parameters -
+1125-Line High-Definition Production"</title>
+    </biblioentry>
+
+    <biblioentry id="en50067">
+      <abbrev>EN&nbsp;50067</abbrev>
+      <authorgroup>
+	<corpauthor>European Committee for Electrotechnical Standardization
+(<ulink url="http://www.cenelec.eu">http://www.cenelec.eu</ulink>)</corpauthor>
+      </authorgroup>
+      <title>Specification of the radio data system (RDS) for VHF/FM sound broadcasting
+in the frequency range from 87,5 to 108,0 MHz</title>
+    </biblioentry>
+
+    <biblioentry id="nrsc4">
+      <abbrev>NRSC-4</abbrev>
+      <authorgroup>
+	<corpauthor>National Radio Systems Committee
+(<ulink url="http://www.nrscstandards.org">http://www.nrscstandards.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>NTSC-4: United States RBDS Standard</title>
+    </biblioentry>
+
+  </bibliography>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/capture.c.xml b/Documentation/DocBook/v4l/capture.c.xml
new file mode 100644
index 0000000..1c5c49a
--- /dev/null
+++ b/Documentation/DocBook/v4l/capture.c.xml
@@ -0,0 +1,659 @@
+<programlisting>
+/*
+ *  V4L2 video capture example
+ *
+ *  This program can be used and distributed without restrictions.
+ *
+ *      This program is provided with the V4L2 API
+ * see http://linuxtv.org/docs.php for more information
+ */
+
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;assert.h&gt;
+
+#include &lt;getopt.h&gt;             /* getopt_long() */
+
+#include &lt;fcntl.h&gt;              /* low-level i/o */
+#include &lt;unistd.h&gt;
+#include &lt;errno.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/time.h&gt;
+#include &lt;sys/mman.h&gt;
+#include &lt;sys/ioctl.h&gt;
+
+#include &lt;linux/videodev2.h&gt;
+
+#define CLEAR(x) memset(&amp;(x), 0, sizeof(x))
+
+enum io_method {
+        IO_METHOD_READ,
+        IO_METHOD_MMAP,
+        IO_METHOD_USERPTR,
+};
+
+struct buffer {
+        void   *start;
+        size_t  length;
+};
+
+static char            *dev_name;
+static enum io_method   io = IO_METHOD_MMAP;
+static int              fd = -1;
+struct buffer          *buffers;
+static unsigned int     n_buffers;
+static int              out_buf;
+static int              force_format;
+static int              frame_count = 70;
+
+static void errno_exit(const char *s)
+{
+        fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
+        exit(EXIT_FAILURE);
+}
+
+static int xioctl(int fh, int request, void *arg)
+{
+        int r;
+
+        do {
+                r = ioctl(fh, request, arg);
+        } while (-1 == r &amp;&amp; EINTR == errno);
+
+        return r;
+}
+
+static void process_image(const void *p, int size)
+{
+        if (out_buf)
+                fwrite(p, size, 1, stdout);
+
+        fflush(stderr);
+        fprintf(stderr, ".");
+        fflush(stdout);
+}
+
+static int read_frame(void)
+{
+        struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
+        unsigned int i;
+
+        switch (io) {
+        case IO_METHOD_READ:
+                if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
+                        switch (errno) {
+                        case EAGAIN:
+                                return 0;
+
+                        case EIO:
+                                /* Could ignore EIO, see spec. */
+
+                                /* fall through */
+
+                        default:
+                                errno_exit("read");
+                        }
+                }
+
+                process_image(buffers[0].start, buffers[0].length);
+                break;
+
+        case IO_METHOD_MMAP:
+                CLEAR(buf);
+
+                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                buf.memory = V4L2_MEMORY_MMAP;
+
+                if (-1 == xioctl(fd, VIDIOC_DQBUF, &amp;buf)) {
+                        switch (errno) {
+                        case EAGAIN:
+                                return 0;
+
+                        case EIO:
+                                /* Could ignore EIO, see spec. */
+
+                                /* fall through */
+
+                        default:
+                                errno_exit("VIDIOC_DQBUF");
+                        }
+                }
+
+                assert(buf.index &lt; n_buffers);
+
+                process_image(buffers[buf.index].start, buf.bytesused);
+
+                if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
+                        errno_exit("VIDIOC_QBUF");
+                break;
+
+        case IO_METHOD_USERPTR:
+                CLEAR(buf);
+
+                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                buf.memory = V4L2_MEMORY_USERPTR;
+
+                if (-1 == xioctl(fd, VIDIOC_DQBUF, &amp;buf)) {
+                        switch (errno) {
+                        case EAGAIN:
+                                return 0;
+
+                        case EIO:
+                                /* Could ignore EIO, see spec. */
+
+                                /* fall through */
+
+                        default:
+                                errno_exit("VIDIOC_DQBUF");
+                        }
+                }
+
+                for (i = 0; i &lt; n_buffers; ++i)
+                        if (buf.m.userptr == (unsigned long)buffers[i].start
+                            &amp;&amp; buf.length == buffers[i].length)
+                                break;
+
+                assert(i &lt; n_buffers);
+
+                process_image((void *)buf.m.userptr, buf.bytesused);
+
+                if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
+                        errno_exit("VIDIOC_QBUF");
+                break;
+        }
+
+        return 1;
+}
+
+static void mainloop(void)
+{
+        unsigned int count;
+
+        count = frame_count;
+
+        while (count-- &gt; 0) {
+                for (;;) {
+                        fd_set fds;
+                        struct timeval tv;
+                        int r;
+
+                        FD_ZERO(&amp;fds);
+                        FD_SET(fd, &amp;fds);
+
+                        /* Timeout. */
+                        tv.tv_sec = 2;
+                        tv.tv_usec = 0;
+
+                        r = select(fd + 1, &amp;fds, NULL, NULL, &amp;tv);
+
+                        if (-1 == r) {
+                                if (EINTR == errno)
+                                        continue;
+                                errno_exit("select");
+                        }
+
+                        if (0 == r) {
+                                fprintf(stderr, "select timeout\n");
+                                exit(EXIT_FAILURE);
+                        }
+
+                        if (read_frame())
+                                break;
+                        /* EAGAIN - continue select loop. */
+                }
+        }
+}
+
+static void stop_capturing(void)
+{
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
+
+        switch (io) {
+        case IO_METHOD_READ:
+                /* Nothing to do. */
+                break;
+
+        case IO_METHOD_MMAP:
+        case IO_METHOD_USERPTR:
+                type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &amp;type))
+                        errno_exit("VIDIOC_STREAMOFF");
+                break;
+        }
+}
+
+static void start_capturing(void)
+{
+        unsigned int i;
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
+
+        switch (io) {
+        case IO_METHOD_READ:
+                /* Nothing to do. */
+                break;
+
+        case IO_METHOD_MMAP:
+                for (i = 0; i &lt; n_buffers; ++i) {
+                        struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
+
+                        CLEAR(buf);
+                        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                        buf.memory = V4L2_MEMORY_MMAP;
+                        buf.index = i;
+
+                        if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
+                                errno_exit("VIDIOC_QBUF");
+                }
+                type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                if (-1 == xioctl(fd, VIDIOC_STREAMON, &amp;type))
+                        errno_exit("VIDIOC_STREAMON");
+                break;
+
+        case IO_METHOD_USERPTR:
+                for (i = 0; i &lt; n_buffers; ++i) {
+                        struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
+
+                        CLEAR(buf);
+                        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                        buf.memory = V4L2_MEMORY_USERPTR;
+                        buf.index = i;
+                        buf.m.userptr = (unsigned long)buffers[i].start;
+                        buf.length = buffers[i].length;
+
+                        if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
+                                errno_exit("VIDIOC_QBUF");
+                }
+                type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                if (-1 == xioctl(fd, VIDIOC_STREAMON, &amp;type))
+                        errno_exit("VIDIOC_STREAMON");
+                break;
+        }
+}
+
+static void uninit_device(void)
+{
+        unsigned int i;
+
+        switch (io) {
+        case IO_METHOD_READ:
+                free(buffers[0].start);
+                break;
+
+        case IO_METHOD_MMAP:
+                for (i = 0; i &lt; n_buffers; ++i)
+                        if (-1 == munmap(buffers[i].start, buffers[i].length))
+                                errno_exit("munmap");
+                break;
+
+        case IO_METHOD_USERPTR:
+                for (i = 0; i &lt; n_buffers; ++i)
+                        free(buffers[i].start);
+                break;
+        }
+
+        free(buffers);
+}
+
+static void init_read(unsigned int buffer_size)
+{
+        buffers = calloc(1, sizeof(*buffers));
+
+        if (!buffers) {
+                fprintf(stderr, "Out of memory\n");
+                exit(EXIT_FAILURE);
+        }
+
+        buffers[0].length = buffer_size;
+        buffers[0].start = malloc(buffer_size);
+
+        if (!buffers[0].start) {
+                fprintf(stderr, "Out of memory\n");
+                exit(EXIT_FAILURE);
+        }
+}
+
+static void init_mmap(void)
+{
+        struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> req;
+
+        CLEAR(req);
+
+        req.count = 4;
+        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        req.memory = V4L2_MEMORY_MMAP;
+
+        if (-1 == xioctl(fd, VIDIOC_REQBUFS, &amp;req)) {
+                if (EINVAL == errno) {
+                        fprintf(stderr, "%s does not support "
+                                 "memory mapping\n", dev_name);
+                        exit(EXIT_FAILURE);
+                } else {
+                        errno_exit("VIDIOC_REQBUFS");
+                }
+        }
+
+        if (req.count &lt; 2) {
+                fprintf(stderr, "Insufficient buffer memory on %s\n",
+                         dev_name);
+                exit(EXIT_FAILURE);
+        }
+
+        buffers = calloc(req.count, sizeof(*buffers));
+
+        if (!buffers) {
+                fprintf(stderr, "Out of memory\n");
+                exit(EXIT_FAILURE);
+        }
+
+        for (n_buffers = 0; n_buffers &lt; req.count; ++n_buffers) {
+                struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
+
+                CLEAR(buf);
+
+                buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                buf.memory      = V4L2_MEMORY_MMAP;
+                buf.index       = n_buffers;
+
+                if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &amp;buf))
+                        errno_exit("VIDIOC_QUERYBUF");
+
+                buffers[n_buffers].length = buf.length;
+                buffers[n_buffers].start =
+                        mmap(NULL /* start anywhere */,
+                              buf.length,
+                              PROT_READ | PROT_WRITE /* required */,
+                              MAP_SHARED /* recommended */,
+                              fd, buf.m.offset);
+
+                if (MAP_FAILED == buffers[n_buffers].start)
+                        errno_exit("mmap");
+        }
+}
+
+static void init_userp(unsigned int buffer_size)
+{
+        struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> req;
+
+        CLEAR(req);
+
+        req.count  = 4;
+        req.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        req.memory = V4L2_MEMORY_USERPTR;
+
+        if (-1 == xioctl(fd, VIDIOC_REQBUFS, &amp;req)) {
+                if (EINVAL == errno) {
+                        fprintf(stderr, "%s does not support "
+                                 "user pointer i/o\n", dev_name);
+                        exit(EXIT_FAILURE);
+                } else {
+                        errno_exit("VIDIOC_REQBUFS");
+                }
+        }
+
+        buffers = calloc(4, sizeof(*buffers));
+
+        if (!buffers) {
+                fprintf(stderr, "Out of memory\n");
+                exit(EXIT_FAILURE);
+        }
+
+        for (n_buffers = 0; n_buffers &lt; 4; ++n_buffers) {
+                buffers[n_buffers].length = buffer_size;
+                buffers[n_buffers].start = malloc(buffer_size);
+
+                if (!buffers[n_buffers].start) {
+                        fprintf(stderr, "Out of memory\n");
+                        exit(EXIT_FAILURE);
+                }
+        }
+}
+
+static void init_device(void)
+{
+        struct <link linkend="v4l2-capability">v4l2_capability</link> cap;
+        struct <link linkend="v4l2-cropcap">v4l2_cropcap</link> cropcap;
+        struct <link linkend="v4l2-crop">v4l2_crop</link> crop;
+        struct <link linkend="v4l2-format">v4l2_format</link> fmt;
+        unsigned int min;
+
+        if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &amp;cap)) {
+                if (EINVAL == errno) {
+                        fprintf(stderr, "%s is no V4L2 device\n",
+                                 dev_name);
+                        exit(EXIT_FAILURE);
+                } else {
+                        errno_exit("VIDIOC_QUERYCAP");
+                }
+        }
+
+        if (!(cap.capabilities &amp; V4L2_CAP_VIDEO_CAPTURE)) {
+                fprintf(stderr, "%s is no video capture device\n",
+                         dev_name);
+                exit(EXIT_FAILURE);
+        }
+
+        switch (io) {
+        case IO_METHOD_READ:
+                if (!(cap.capabilities &amp; V4L2_CAP_READWRITE)) {
+                        fprintf(stderr, "%s does not support read i/o\n",
+                                 dev_name);
+                        exit(EXIT_FAILURE);
+                }
+                break;
+
+        case IO_METHOD_MMAP:
+        case IO_METHOD_USERPTR:
+                if (!(cap.capabilities &amp; V4L2_CAP_STREAMING)) {
+                        fprintf(stderr, "%s does not support streaming i/o\n",
+                                 dev_name);
+                        exit(EXIT_FAILURE);
+                }
+                break;
+        }
+
+
+        /* Select video input, video standard and tune here. */
+
+
+        CLEAR(cropcap);
+
+        cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+        if (0 == xioctl(fd, VIDIOC_CROPCAP, &amp;cropcap)) {
+                crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                crop.c = cropcap.defrect; /* reset to default */
+
+                if (-1 == xioctl(fd, VIDIOC_S_CROP, &amp;crop)) {
+                        switch (errno) {
+                        case EINVAL:
+                                /* Cropping not supported. */
+                                break;
+                        default:
+                                /* Errors ignored. */
+                                break;
+                        }
+                }
+        } else {
+                /* Errors ignored. */
+        }
+
+
+        CLEAR(fmt);
+
+        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        if (force_format) {
+                fmt.fmt.pix.width       = 640;
+                fmt.fmt.pix.height      = 480;
+                fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+                fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
+
+                if (-1 == xioctl(fd, VIDIOC_S_FMT, &amp;fmt))
+                        errno_exit("VIDIOC_S_FMT");
+
+                /* Note VIDIOC_S_FMT may change width and height. */
+        } else {
+                /* Preserve original settings as set by v4l2-ctl for example */
+                if (-1 == xioctl(fd, VIDIOC_G_FMT, &amp;fmt))
+                        errno_exit("VIDIOC_G_FMT");
+        }
+
+        /* Buggy driver paranoia. */
+        min = fmt.fmt.pix.width * 2;
+        if (fmt.fmt.pix.bytesperline &lt; min)
+                fmt.fmt.pix.bytesperline = min;
+        min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
+        if (fmt.fmt.pix.sizeimage &lt; min)
+                fmt.fmt.pix.sizeimage = min;
+
+        switch (io) {
+        case IO_METHOD_READ:
+                init_read(fmt.fmt.pix.sizeimage);
+                break;
+
+        case IO_METHOD_MMAP:
+                init_mmap();
+                break;
+
+        case IO_METHOD_USERPTR:
+                init_userp(fmt.fmt.pix.sizeimage);
+                break;
+        }
+}
+
+static void close_device(void)
+{
+        if (-1 == close(fd))
+                errno_exit("close");
+
+        fd = -1;
+}
+
+static void open_device(void)
+{
+        struct stat st;
+
+        if (-1 == stat(dev_name, &amp;st)) {
+                fprintf(stderr, "Cannot identify '%s': %d, %s\n",
+                         dev_name, errno, strerror(errno));
+                exit(EXIT_FAILURE);
+        }
+
+        if (!S_ISCHR(st.st_mode)) {
+                fprintf(stderr, "%s is no device\n", dev_name);
+                exit(EXIT_FAILURE);
+        }
+
+        fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
+
+        if (-1 == fd) {
+                fprintf(stderr, "Cannot open '%s': %d, %s\n",
+                         dev_name, errno, strerror(errno));
+                exit(EXIT_FAILURE);
+        }
+}
+
+static void usage(FILE *fp, int argc, char **argv)
+{
+        fprintf(fp,
+                 "Usage: %s [options]\n\n"
+                 "Version 1.3\n"
+                 "Options:\n"
+                 "-d | --device name   Video device name [%s]\n"
+                 "-h | --help          Print this message\n"
+                 "-m | --mmap          Use memory mapped buffers [default]\n"
+                 "-r | --read          Use read() calls\n"
+                 "-u | --userp         Use application allocated buffers\n"
+                 "-o | --output        Outputs stream to stdout\n"
+                 "-f | --format        Force format to 640x480 YUYV\n"
+                 "-c | --count         Number of frames to grab [%i]\n"
+                 "",
+                 argv[0], dev_name, frame_count);
+}
+
+static const char short_options[] = "d:hmruofc:";
+
+static const struct option
+long_options[] = {
+        { "device", required_argument, NULL, 'd' },
+        { "help",   no_argument,       NULL, 'h' },
+        { "mmap",   no_argument,       NULL, 'm' },
+        { "read",   no_argument,       NULL, 'r' },
+        { "userp",  no_argument,       NULL, 'u' },
+        { "output", no_argument,       NULL, 'o' },
+        { "format", no_argument,       NULL, 'f' },
+        { "count",  required_argument, NULL, 'c' },
+        { 0, 0, 0, 0 }
+};
+
+int main(int argc, char **argv)
+{
+        dev_name = "/dev/video0";
+
+        for (;;) {
+                int idx;
+                int c;
+
+                c = getopt_long(argc, argv,
+                                short_options, long_options, &amp;idx);
+
+                if (-1 == c)
+                        break;
+
+                switch (c) {
+                case 0: /* getopt_long() flag */
+                        break;
+
+                case 'd':
+                        dev_name = optarg;
+                        break;
+
+                case 'h':
+                        usage(stdout, argc, argv);
+                        exit(EXIT_SUCCESS);
+
+                case 'm':
+                        io = IO_METHOD_MMAP;
+                        break;
+
+                case 'r':
+                        io = IO_METHOD_READ;
+                        break;
+
+                case 'u':
+                        io = IO_METHOD_USERPTR;
+                        break;
+
+                case 'o':
+                        out_buf++;
+                        break;
+
+                case 'f':
+                        force_format++;
+                        break;
+
+                case 'c':
+                        errno = 0;
+                        frame_count = strtol(optarg, NULL, 0);
+                        if (errno)
+                                errno_exit(optarg);
+                        break;
+
+                default:
+                        usage(stderr, argc, argv);
+                        exit(EXIT_FAILURE);
+                }
+        }
+
+        open_device();
+        init_device();
+        start_capturing();
+        mainloop();
+        stop_capturing();
+        uninit_device();
+        close_device();
+        fprintf(stderr, "\n");
+        return 0;
+}
+</programlisting>
diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml
new file mode 100644
index 0000000..b1a81d2
--- /dev/null
+++ b/Documentation/DocBook/v4l/common.xml
@@ -0,0 +1,1160 @@
+  <title>Common API Elements</title>
+
+  <para>Programming a V4L2 device consists of these
+steps:</para>
+
+  <itemizedlist>
+    <listitem>
+      <para>Opening the device</para>
+    </listitem>
+    <listitem>
+      <para>Changing device properties, selecting a video and audio
+input, video standard, picture brightness a.&nbsp;o.</para>
+    </listitem>
+    <listitem>
+      <para>Negotiating a data format</para>
+    </listitem>
+    <listitem>
+      <para>Negotiating an input/output method</para>
+    </listitem>
+    <listitem>
+      <para>The actual input/output loop</para>
+    </listitem>
+    <listitem>
+      <para>Closing the device</para>
+    </listitem>
+  </itemizedlist>
+
+  <para>In practice most steps are optional and can be executed out of
+order. It depends on the V4L2 device type, you can read about the
+details in <xref linkend="devices" />. In this chapter we will discuss
+the basic concepts applicable to all devices.</para>
+
+  <section id="open">
+    <title>Opening and Closing Devices</title>
+
+    <section>
+      <title>Device Naming</title>
+
+      <para>V4L2 drivers are implemented as kernel modules, loaded
+manually by the system administrator or automatically when a device is
+first opened. The driver modules plug into the "videodev" kernel
+module. It provides helper functions and a common application
+interface specified in this document.</para>
+
+      <para>Each driver thus loaded registers one or more device nodes
+with major number 81 and a minor number between 0 and 255. Assigning
+minor numbers to V4L2 devices is entirely up to the system administrator,
+this is primarily intended to solve conflicts between devices.<footnote>
+	  <para>Access permissions are associated with character
+device special files, hence we must ensure device numbers cannot
+change with the module load order. To this end minor numbers are no
+longer automatically assigned by the "videodev" module as in V4L but
+requested by the driver. The defaults will suffice for most people
+unless two drivers compete for the same minor numbers.</para>
+	</footnote> The module options to select minor numbers are named
+after the device special file with a "_nr" suffix. For example "video_nr"
+for <filename>/dev/video</filename> video capture devices. The number is
+an offset to the base minor number associated with the device type.
+<footnote>
+	  <para>In earlier versions of the V4L2 API the module options
+where named after the device special file with a "unit_" prefix, expressing
+the minor number itself, not an offset. Rationale for this change is unknown.
+Lastly the naming and semantics are just a convention among driver writers,
+the point to note is that minor numbers are not supposed to be hardcoded
+into drivers.</para>
+	</footnote> When the driver supports multiple devices of the same
+type more than one minor number can be assigned, separated by commas:
+<informalexample>
+	  <screen>
+&gt; insmod mydriver.o video_nr=0,1 radio_nr=0,1</screen>
+	</informalexample></para>
+
+      <para>In <filename>/etc/modules.conf</filename> this may be
+written as: <informalexample>
+	  <screen>
+alias char-major-81-0 mydriver
+alias char-major-81-1 mydriver
+alias char-major-81-64 mydriver              <co id="alias" />
+options mydriver video_nr=0,1 radio_nr=0,1   <co id="options" />
+	  </screen>
+	  <calloutlist>
+	    <callout arearefs="alias">
+	      <para>When an application attempts to open a device
+special file with major number 81 and minor number 0, 1, or 64, load
+"mydriver" (and the "videodev" module it depends upon).</para>
+	    </callout>
+	    <callout arearefs="options">
+	      <para>Register the first two video capture devices with
+minor number 0 and 1 (base number is 0), the first two radio device
+with minor number 64 and 65 (base 64).</para>
+	    </callout>
+	  </calloutlist>
+	</informalexample> When no minor number is given as module
+option the driver supplies a default. <xref linkend="devices" />
+recommends the base minor numbers to be used for the various device
+types. Obviously minor numbers must be unique. When the number is
+already in use the <emphasis>offending device</emphasis> will not be
+registered. <!-- Blessed by Linus Torvalds on
+linux-kernel@vger.kernel.org, 2002-11-20. --></para>
+
+      <para>By convention system administrators create various
+character device special files with these major and minor numbers in
+the <filename>/dev</filename> directory. The names recomended for the
+different V4L2 device types are listed in <xref linkend="devices" />.
+</para>
+
+      <para>The creation of character special files (with
+<application>mknod</application>) is a privileged operation and
+devices cannot be opened by major and minor number. That means
+applications cannot <emphasis>reliable</emphasis> scan for loaded or
+installed drivers. The user must enter a device name, or the
+application can try the conventional device names.</para>
+
+      <para>Under the device filesystem (devfs) the minor number
+options are ignored. V4L2 drivers (or by proxy the "videodev" module)
+automatically create the required device files in the
+<filename>/dev/v4l</filename> directory using the conventional device
+names above.</para>
+    </section>
+
+    <section id="related">
+      <title>Related Devices</title>
+
+      <para>Devices can support several related functions. For example
+video capturing, video overlay and VBI capturing are related because
+these functions share, amongst other, the same video input and tuner
+frequency. V4L and earlier versions of V4L2 used the same device name
+and minor number for video capturing and overlay, but different ones
+for VBI. Experience showed this approach has several problems<footnote>
+	  <para>Given a device file name one cannot reliable find
+related devices. For once names are arbitrary and in a system with
+multiple devices, where only some support VBI capturing, a
+<filename>/dev/video2</filename> is not necessarily related to
+<filename>/dev/vbi2</filename>. The V4L
+<constant>VIDIOCGUNIT</constant> ioctl would require a search for a
+device file with a particular major and minor number.</para>
+	</footnote>, and to make things worse the V4L videodev module
+used to prohibit multiple opens of a device.</para>
+
+      <para>As a remedy the present version of the V4L2 API relaxed the
+concept of device types with specific names and minor numbers. For
+compatibility with old applications drivers must still register different
+minor numbers to assign a default function to the device. But if related
+functions are supported by the driver they must be available under all
+registered minor numbers. The desired function can be selected after
+opening the device as described in <xref linkend="devices" />.</para>
+
+      <para>Imagine a driver supporting video capturing, video
+overlay, raw VBI capturing, and FM radio reception. It registers three
+devices with minor number 0, 64 and 224 (this numbering scheme is
+inherited from the V4L API). Regardless if
+<filename>/dev/video</filename> (81, 0) or
+<filename>/dev/vbi</filename> (81, 224) is opened the application can
+select any one of the video capturing, overlay or VBI capturing
+functions. Without programming (e.&nbsp;g. reading from the device
+with <application>dd</application> or <application>cat</application>)
+<filename>/dev/video</filename> captures video images, while
+<filename>/dev/vbi</filename> captures raw VBI data.
+<filename>/dev/radio</filename> (81, 64) is invariable a radio device,
+unrelated to the video functions. Being unrelated does not imply the
+devices can be used at the same time, however. The &func-open;
+function may very well return an &EBUSY;.</para>
+
+      <para>Besides video input or output the hardware may also
+support audio sampling or playback. If so, these functions are
+implemented as OSS or ALSA PCM devices and eventually OSS or ALSA
+audio mixer. The V4L2 API makes no provisions yet to find these
+related devices. If you have an idea please write to the linux-media
+mailing list: &v4l-ml;.</para>
+    </section>
+
+    <section>
+      <title>Multiple Opens</title>
+
+      <para>In general, V4L2 devices can be opened more than once.
+When this is supported by the driver, users can for example start a
+"panel" application to change controls like brightness or audio
+volume, while another application captures video and audio. In other words, panel
+applications are comparable to an OSS or ALSA audio mixer application.
+When a device supports multiple functions like capturing and overlay
+<emphasis>simultaneously</emphasis>, multiple opens allow concurrent
+use of the device by forked processes or specialized applications.</para>
+
+      <para>Multiple opens are optional, although drivers should
+permit at least concurrent accesses without data exchange, &ie; panel
+applications. This implies &func-open; can return an &EBUSY; when the
+device is already in use, as well as &func-ioctl; functions initiating
+data exchange (namely the &VIDIOC-S-FMT; ioctl), and the &func-read;
+and &func-write; functions.</para>
+
+      <para>Mere opening a V4L2 device does not grant exclusive
+access.<footnote>
+	  <para>Drivers could recognize the
+<constant>O_EXCL</constant> open flag. Presently this is not required,
+so applications cannot know if it really works.</para>
+	</footnote> Initiating data exchange however assigns the right
+to read or write the requested type of data, and to change related
+properties, to this file descriptor. Applications can request
+additional access privileges using the priority mechanism described in
+<xref linkend="app-pri" />.</para>
+    </section>
+
+    <section>
+      <title>Shared Data Streams</title>
+
+      <para>V4L2 drivers should not support multiple applications
+reading or writing the same data stream on a device by copying
+buffers, time multiplexing or similar means. This is better handled by
+a proxy application in user space. When the driver supports stream
+sharing anyway it must be implemented transparently. The V4L2 API does
+not specify how conflicts are solved. <!-- For example O_EXCL when the
+application does not want to be preempted, PROT_READ mmapped buffers
+which can be mapped twice, what happens when image formats do not
+match etc.--></para>
+    </section>
+
+    <section>
+      <title>Functions</title>
+
+    <para>To open and close V4L2 devices applications use the
+&func-open; and &func-close; function, respectively. Devices are
+programmed using the &func-ioctl; function as explained in the
+following sections.</para>
+    </section>
+  </section>
+
+  <section id="querycap">
+    <title>Querying Capabilities</title>
+
+    <para>Because V4L2 covers a wide variety of devices not all
+aspects of the API are equally applicable to all types of devices.
+Furthermore devices of the same type have different capabilities and
+this specification permits the omission of a few complicated and less
+important parts of the API.</para>
+
+    <para>The &VIDIOC-QUERYCAP; ioctl is available to check if the kernel
+device is compatible with this specification, and to query the <link
+linkend="devices">functions</link> and <link linkend="io">I/O
+methods</link> supported by the device. Other features can be queried
+by calling the respective ioctl, for example &VIDIOC-ENUMINPUT;
+to learn about the number, types and names of video connectors on the
+device. Although abstraction is a major objective of this API, the
+ioctl also allows driver specific applications to reliable identify
+the driver.</para>
+
+    <para>All V4L2 drivers must support
+<constant>VIDIOC_QUERYCAP</constant>. Applications should always call
+this ioctl after opening the device.</para>
+  </section>
+
+  <section id="app-pri">
+    <title>Application Priority</title>
+
+    <para>When multiple applications share a device it may be
+desirable to assign them different priorities. Contrary to the
+traditional "rm -rf /" school of thought a video recording application
+could for example block other applications from changing video
+controls or switching the current TV channel. Another objective is to
+permit low priority applications working in background, which can be
+preempted by user controlled applications and automatically regain
+control of the device at a later time.</para>
+
+    <para>Since these features cannot be implemented entirely in user
+space V4L2 defines the &VIDIOC-G-PRIORITY; and &VIDIOC-S-PRIORITY;
+ioctls to request and query the access priority associate with a file
+descriptor. Opening a device assigns a medium priority, compatible
+with earlier versions of V4L2 and drivers not supporting these ioctls.
+Applications requiring a different priority will usually call
+<constant>VIDIOC_S_PRIORITY</constant> after verifying the device with
+the &VIDIOC-QUERYCAP; ioctl.</para>
+
+    <para>Ioctls changing driver properties, such as &VIDIOC-S-INPUT;,
+return an &EBUSY; after another application obtained higher priority.
+An event mechanism to notify applications about asynchronous property
+changes has been proposed but not added yet.</para>
+  </section>
+
+  <section id="video">
+    <title>Video Inputs and Outputs</title>
+
+    <para>Video inputs and outputs are physical connectors of a
+device. These can be for example RF connectors (antenna/cable), CVBS
+a.k.a. Composite Video, S-Video or RGB connectors. Only video and VBI
+capture devices have inputs, output devices have outputs, at least one
+each. Radio devices have no video inputs or outputs.</para>
+
+    <para>To learn about the number and attributes of the
+available inputs and outputs applications can enumerate them with the
+&VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; ioctl, respectively. The
+&v4l2-input; returned by the <constant>VIDIOC_ENUMINPUT</constant>
+ioctl also contains signal status information applicable when the
+current video input is queried.</para>
+
+    <para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctl return the
+index of the current video input or output. To select a different
+input or output applications call the &VIDIOC-S-INPUT; and
+&VIDIOC-S-OUTPUT; ioctl. Drivers must implement all the input ioctls
+when the device has one or more inputs, all the output ioctls when the
+device has one or more outputs.</para>
+
+    <!--
+    <figure id=io-tree>
+      <title>Input and output enumeration is the root of most device properties.</title>
+      <mediaobject>
+	<imageobject>
+	  <imagedata fileref="links.pdf" format="ps" />
+	</imageobject>
+	<imageobject>
+	  <imagedata fileref="links.gif" format="gif" />
+	</imageobject>
+	<textobject>
+	  <phrase>Links between various device property structures.</phrase>
+	</textobject>
+      </mediaobject>
+    </figure>
+    -->
+
+    <example>
+      <title>Information about the current video input</title>
+
+      <programlisting>
+&v4l2-input; input;
+int index;
+
+if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;index)) {
+	perror ("VIDIOC_G_INPUT");
+	exit (EXIT_FAILURE);
+}
+
+memset (&amp;input, 0, sizeof (input));
+input.index = index;
+
+if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+	perror ("VIDIOC_ENUMINPUT");
+	exit (EXIT_FAILURE);
+}
+
+printf ("Current input: %s\n", input.name);
+      </programlisting>
+    </example>
+
+    <example>
+      <title>Switching to the first video input</title>
+
+      <programlisting>
+int index;
+
+index = 0;
+
+if (-1 == ioctl (fd, &VIDIOC-S-INPUT;, &amp;index)) {
+	perror ("VIDIOC_S_INPUT");
+	exit (EXIT_FAILURE);
+}
+      </programlisting>
+    </example>
+  </section>
+
+  <section id="audio">
+    <title>Audio Inputs and Outputs</title>
+
+    <para>Audio inputs and outputs are physical connectors of a
+device. Video capture devices have inputs, output devices have
+outputs, zero or more each. Radio devices have no audio inputs or
+outputs. They have exactly one tuner which in fact
+<emphasis>is</emphasis> an audio source, but this API associates
+tuners with video inputs or outputs only, and radio devices have
+none of these.<footnote>
+	<para>Actually &v4l2-audio; ought to have a
+<structfield>tuner</structfield> field like &v4l2-input;, not only
+making the API more consistent but also permitting radio devices with
+multiple tuners.</para>
+      </footnote> A connector on a TV card to loop back the received
+audio signal to a sound card is not considered an audio output.</para>
+
+    <para>Audio and video inputs and outputs are associated. Selecting
+a video source also selects an audio source. This is most evident when
+the video and audio source is a tuner. Further audio connectors can
+combine with more than one video input or output. Assumed two
+composite video inputs and two audio inputs exist, there may be up to
+four valid combinations. The relation of video and audio connectors
+is defined in the <structfield>audioset</structfield> field of the
+respective &v4l2-input; or &v4l2-output;, where each bit represents
+the index number, starting at zero, of one audio input or output.</para>
+
+    <para>To learn about the number and attributes of the
+available inputs and outputs applications can enumerate them with the
+&VIDIOC-ENUMAUDIO; and &VIDIOC-ENUMAUDOUT; ioctl, respectively. The
+&v4l2-audio; returned by the <constant>VIDIOC_ENUMAUDIO</constant> ioctl
+also contains signal status information applicable when the current
+audio input is queried.</para>
+
+    <para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctl report
+the current audio input and output, respectively. Note that, unlike
+&VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; these ioctls return a structure
+as <constant>VIDIOC_ENUMAUDIO</constant> and
+<constant>VIDIOC_ENUMAUDOUT</constant> do, not just an index.</para>
+
+    <para>To select an audio input and change its properties
+applications call the &VIDIOC-S-AUDIO; ioctl. To select an audio
+output (which presently has no changeable properties) applications
+call the &VIDIOC-S-AUDOUT; ioctl.</para>
+
+    <para>Drivers must implement all input ioctls when the device
+has one or more inputs, all output ioctls when the device has one
+or more outputs. When the device has any audio inputs or outputs the
+driver must set the <constant>V4L2_CAP_AUDIO</constant> flag in the
+&v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
+
+    <example>
+      <title>Information about the current audio input</title>
+
+      <programlisting>
+&v4l2-audio; audio;
+
+memset (&amp;audio, 0, sizeof (audio));
+
+if (-1 == ioctl (fd, &VIDIOC-G-AUDIO;, &amp;audio)) {
+	perror ("VIDIOC_G_AUDIO");
+	exit (EXIT_FAILURE);
+}
+
+printf ("Current input: %s\n", audio.name);
+      </programlisting>
+    </example>
+
+    <example>
+      <title>Switching to the first audio input</title>
+
+      <programlisting>
+&v4l2-audio; audio;
+
+memset (&amp;audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */
+
+audio.index = 0;
+
+if (-1 == ioctl (fd, &VIDIOC-S-AUDIO;, &amp;audio)) {
+	perror ("VIDIOC_S_AUDIO");
+	exit (EXIT_FAILURE);
+}
+      </programlisting>
+    </example>
+  </section>
+
+  <section id="tuner">
+    <title>Tuners and Modulators</title>
+
+    <section>
+      <title>Tuners</title>
+
+      <para>Video input devices can have one or more tuners
+demodulating a RF signal. Each tuner is associated with one or more
+video inputs, depending on the number of RF connectors on the tuner.
+The <structfield>type</structfield> field of the respective
+&v4l2-input; returned by the &VIDIOC-ENUMINPUT; ioctl is set to
+<constant>V4L2_INPUT_TYPE_TUNER</constant> and its
+<structfield>tuner</structfield> field contains the index number of
+the tuner.</para>
+
+      <para>Radio devices have exactly one tuner with index zero, no
+video inputs.</para>
+
+      <para>To query and change tuner properties applications use the
+&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctl, respectively. The
+&v4l2-tuner; returned by <constant>VIDIOC_G_TUNER</constant> also
+contains signal status information applicable when the tuner of the
+current video input, or a radio tuner is queried. Note that
+<constant>VIDIOC_S_TUNER</constant> does not switch the current tuner,
+when there is more than one at all. The tuner is solely determined by
+the current video input. Drivers must support both ioctls and set the
+<constant>V4L2_CAP_TUNER</constant> flag in the &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl when the device has one or
+more tuners.</para>
+    </section>
+
+    <section>
+      <title>Modulators</title>
+
+      <para>Video output devices can have one or more modulators, uh,
+modulating a video signal for radiation or connection to the antenna
+input of a TV set or video recorder. Each modulator is associated with
+one or more video outputs, depending on the number of RF connectors on
+the modulator. The <structfield>type</structfield> field of the
+respective &v4l2-output; returned by the &VIDIOC-ENUMOUTPUT; ioctl is
+set to <constant>V4L2_OUTPUT_TYPE_MODULATOR</constant> and its
+<structfield>modulator</structfield> field contains the index number
+of the modulator. This specification does not define radio output
+devices.</para>
+
+      <para>To query and change modulator properties applications use
+the &VIDIOC-G-MODULATOR; and &VIDIOC-S-MODULATOR; ioctl. Note that
+<constant>VIDIOC_S_MODULATOR</constant> does not switch the current
+modulator, when there is more than one at all. The modulator is solely
+determined by the current video output. Drivers must support both
+ioctls and set the <constant>V4L2_CAP_MODULATOR</constant> flag in
+the &v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl when the
+device has one or more modulators.</para>
+    </section>
+
+    <section>
+      <title>Radio Frequency</title>
+
+      <para>To get and set the tuner or modulator radio frequency
+applications use the &VIDIOC-G-FREQUENCY; and &VIDIOC-S-FREQUENCY;
+ioctl which both take a pointer to a &v4l2-frequency;. These ioctls
+are used for TV and radio devices alike. Drivers must support both
+ioctls when the tuner or modulator ioctls are supported, or
+when the device is a radio device.</para>
+    </section>
+  </section>
+
+  <section id="standard">
+    <title>Video Standards</title>
+
+    <para>Video devices typically support one or more different video
+standards or variations of standards. Each video input and output may
+support another set of standards. This set is reported by the
+<structfield>std</structfield> field of &v4l2-input; and
+&v4l2-output; returned by the &VIDIOC-ENUMINPUT; and
+&VIDIOC-ENUMOUTPUT; ioctl, respectively.</para>
+
+    <para>V4L2 defines one bit for each analog video standard
+currently in use worldwide, and sets aside bits for driver defined
+standards, &eg; hybrid standards to watch NTSC video tapes on PAL TVs
+and vice versa. Applications can use the predefined bits to select a
+particular standard, although presenting the user a menu of supported
+standards is preferred. To enumerate and query the attributes of the
+supported standards applications use the &VIDIOC-ENUMSTD; ioctl.</para>
+
+    <para>Many of the defined standards are actually just variations
+of a few major standards. The hardware may in fact not distinguish
+between them, or do so internal and switch automatically. Therefore
+enumerated standards also contain sets of one or more standard
+bits.</para>
+
+    <para>Assume a hypothetic tuner capable of demodulating B/PAL,
+G/PAL and I/PAL signals. The first enumerated standard is a set of B
+and G/PAL, switched automatically depending on the selected radio
+frequency in UHF or VHF band. Enumeration gives a "PAL-B/G" or "PAL-I"
+choice. Similar a Composite input may collapse standards, enumerating
+"PAL-B/G/H/I", "NTSC-M" and "SECAM-D/K".<footnote>
+	<para>Some users are already confused by technical terms PAL,
+NTSC and SECAM. There is no point asking them to distinguish between
+B, G, D, or K when the software or hardware can do that
+automatically.</para>
+    </footnote></para>
+
+    <para>To query and select the standard used by the current video
+input or output applications call the &VIDIOC-G-STD; and
+&VIDIOC-S-STD; ioctl, respectively. The <emphasis>received</emphasis>
+standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note parameter of all these ioctls is a pointer to a &v4l2-std-id; type (a standard set), <emphasis>not</emphasis> an index into the standard enumeration.<footnote>
+	<para>An alternative to the current scheme is to use pointers
+to indices as arguments of <constant>VIDIOC_G_STD</constant> and
+<constant>VIDIOC_S_STD</constant>, the &v4l2-input; and
+&v4l2-output; <structfield>std</structfield> field would be a set of
+indices like <structfield>audioset</structfield>.</para>
+	<para>Indices are consistent with the rest of the API
+and identify the standard unambiguously. In the present scheme of
+things an enumerated standard is looked up by &v4l2-std-id;. Now the
+standards supported by the inputs of a device can overlap. Just
+assume the tuner and composite input in the example above both
+exist on a device. An enumeration of "PAL-B/G", "PAL-H/I" suggests
+a choice which does not exist. We cannot merge or omit sets, because
+applications would be unable to find the standards reported by
+<constant>VIDIOC_G_STD</constant>. That leaves separate enumerations
+for each input. Also selecting a standard by &v4l2-std-id; can be
+ambiguous. Advantage of this method is that applications need not
+identify the standard indirectly, after enumerating.</para><para>So in
+summary, the lookup itself is unavoidable. The difference is only
+whether the lookup is necessary to find an enumerated standard or to
+switch to a standard by &v4l2-std-id;.</para>
+      </footnote> Drivers must implement all video standard ioctls
+when the device has one or more video inputs or outputs.</para>
+
+    <para>Special rules apply to USB cameras where the notion of video
+standards makes little sense. More generally any capture device,
+output devices accordingly, which is <itemizedlist>
+	<listitem>
+	  <para>incapable of capturing fields or frames at the nominal
+rate of the video standard, or</para>
+	</listitem>
+	<listitem>
+	  <para>where <link linkend="buffer">timestamps</link> refer
+to the instant the field or frame was received by the driver, not the
+capture time, or</para>
+	</listitem>
+	<listitem>
+	  <para>where <link linkend="buffer">sequence numbers</link>
+refer to the frames received by the driver, not the captured
+frames.</para>
+	</listitem>
+      </itemizedlist> Here the driver shall set the
+<structfield>std</structfield> field of &v4l2-input; and &v4l2-output;
+to zero, the <constant>VIDIOC_G_STD</constant>,
+<constant>VIDIOC_S_STD</constant>,
+<constant>VIDIOC_QUERYSTD</constant> and
+<constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
+&EINVAL;.<footnote>
+	<para>See <xref linkend="buffer" /> for a rationale. Probably
+even USB cameras follow some well known video standard. It might have
+been better to explicitly indicate elsewhere if a device cannot live
+up to normal expectations, instead of this exception.</para>
+	    </footnote></para>
+
+    <example>
+      <title>Information about the current video standard</title>
+
+      <programlisting>
+&v4l2-std-id; std_id;
+&v4l2-standard; standard;
+
+if (-1 == ioctl (fd, &VIDIOC-G-STD;, &amp;std_id)) {
+	/* Note when VIDIOC_ENUMSTD always returns EINVAL this
+	   is no video device or it falls under the USB exception,
+	   and VIDIOC_G_STD returning EINVAL is no error. */
+
+	perror ("VIDIOC_G_STD");
+	exit (EXIT_FAILURE);
+}
+
+memset (&amp;standard, 0, sizeof (standard));
+standard.index = 0;
+
+while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
+	if (standard.id &amp; std_id) {
+	       printf ("Current video standard: %s\n", standard.name);
+	       exit (EXIT_SUCCESS);
+	}
+
+	standard.index++;
+}
+
+/* EINVAL indicates the end of the enumeration, which cannot be
+   empty unless this device falls under the USB exception. */
+
+if (errno == EINVAL || standard.index == 0) {
+	perror ("VIDIOC_ENUMSTD");
+	exit (EXIT_FAILURE);
+}
+      </programlisting>
+    </example>
+
+    <example>
+      <title>Listing the video standards supported by the current
+input</title>
+
+      <programlisting>
+&v4l2-input; input;
+&v4l2-standard; standard;
+
+memset (&amp;input, 0, sizeof (input));
+
+if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
+	perror ("VIDIOC_G_INPUT");
+	exit (EXIT_FAILURE);
+}
+
+if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+	perror ("VIDIOC_ENUM_INPUT");
+	exit (EXIT_FAILURE);
+}
+
+printf ("Current input %s supports:\n", input.name);
+
+memset (&amp;standard, 0, sizeof (standard));
+standard.index = 0;
+
+while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
+	if (standard.id &amp; input.std)
+		printf ("%s\n", standard.name);
+
+	standard.index++;
+}
+
+/* EINVAL indicates the end of the enumeration, which cannot be
+   empty unless this device falls under the USB exception. */
+
+if (errno != EINVAL || standard.index == 0) {
+	perror ("VIDIOC_ENUMSTD");
+	exit (EXIT_FAILURE);
+}
+      </programlisting>
+    </example>
+
+    <example>
+      <title>Selecting a new video standard</title>
+
+      <programlisting>
+&v4l2-input; input;
+&v4l2-std-id; std_id;
+
+memset (&amp;input, 0, sizeof (input));
+
+if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
+	perror ("VIDIOC_G_INPUT");
+	exit (EXIT_FAILURE);
+}
+
+if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
+	perror ("VIDIOC_ENUM_INPUT");
+	exit (EXIT_FAILURE);
+}
+
+if (0 == (input.std &amp; V4L2_STD_PAL_BG)) {
+	fprintf (stderr, "Oops. B/G PAL is not supported.\n");
+	exit (EXIT_FAILURE);
+}
+
+/* Note this is also supposed to work when only B
+   <emphasis>or</emphasis> G/PAL is supported. */
+
+std_id = V4L2_STD_PAL_BG;
+
+if (-1 == ioctl (fd, &VIDIOC-S-STD;, &amp;std_id)) {
+	perror ("VIDIOC_S_STD");
+	exit (EXIT_FAILURE);
+}
+      </programlisting>
+    </example>
+  </section>
+
+  &sub-controls;
+
+  <section id="format">
+    <title>Data Formats</title>
+
+    <section>
+      <title>Data Format Negotiation</title>
+
+      <para>Different devices exchange different kinds of data with
+applications, for example video images, raw or sliced VBI data, RDS
+datagrams. Even within one kind many different formats are possible,
+in particular an abundance of image formats. Although drivers must
+provide a default and the selection persists across closing and
+reopening a device, applications should always negotiate a data format
+before engaging in data exchange. Negotiation means the application
+asks for a particular format and the driver selects and reports the
+best the hardware can do to satisfy the request. Of course
+applications can also just query the current selection.</para>
+
+      <para>A single mechanism exists to negotiate all data formats
+using the aggregate &v4l2-format; and the &VIDIOC-G-FMT; and
+&VIDIOC-S-FMT; ioctls. Additionally the &VIDIOC-TRY-FMT; ioctl can be
+used to examine what the hardware <emphasis>could</emphasis> do,
+without actually selecting a new data format. The data formats
+supported by the V4L2 API are covered in the respective device section
+in <xref linkend="devices" />. For a closer look at image formats see
+<xref linkend="pixfmt" />.</para>
+
+      <para>The <constant>VIDIOC_S_FMT</constant> ioctl is a major
+turning-point in the initialization sequence. Prior to this point
+multiple panel applications can access the same device concurrently to
+select the current input, change controls or modify other properties.
+The first <constant>VIDIOC_S_FMT</constant> assigns a logical stream
+(video data, VBI data etc.) exclusively to one file descriptor.</para>
+
+      <para>Exclusive means no other application, more precisely no
+other file descriptor, can grab this stream or change device
+properties inconsistent with the negotiated parameters. A video
+standard change for example, when the new standard uses a different
+number of scan lines, can invalidate the selected image format.
+Therefore only the file descriptor owning the stream can make
+invalidating changes. Accordingly multiple file descriptors which
+grabbed different logical streams prevent each other from interfering
+with their settings. When for example video overlay is about to start
+or already in progress, simultaneous video capturing may be restricted
+to the same cropping and image size.</para>
+
+      <para>When applications omit the
+<constant>VIDIOC_S_FMT</constant> ioctl its locking side effects are
+implied by the next step, the selection of an I/O method with the
+&VIDIOC-REQBUFS; ioctl or implicit with the first &func-read; or
+&func-write; call.</para>
+
+      <para>Generally only one logical stream can be assigned to a
+file descriptor, the exception being drivers permitting simultaneous
+video capturing and overlay using the same file descriptor for
+compatibility with V4L and earlier versions of V4L2. Switching the
+logical stream or returning into "panel mode" is possible by closing
+and reopening the device. Drivers <emphasis>may</emphasis> support a
+switch using <constant>VIDIOC_S_FMT</constant>.</para>
+
+      <para>All drivers exchanging data with
+applications must support the <constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl. Implementation of the
+<constant>VIDIOC_TRY_FMT</constant> is highly recommended but
+optional.</para>
+    </section>
+
+    <section>
+      <title>Image Format Enumeration</title>
+
+      <para>Apart of the generic format negotiation functions
+a special ioctl to enumerate all image formats supported by video
+capture, overlay or output devices is available.<footnote>
+	  <para>Enumerating formats an application has no a-priori
+knowledge of (otherwise it could explicitly ask for them and need not
+enumerate) seems useless, but there are applications serving as proxy
+between drivers and the actual video applications for which this is
+useful.</para>
+	</footnote></para>
+
+      <para>The &VIDIOC-ENUM-FMT; ioctl must be supported
+by all drivers exchanging image data with applications.</para>
+
+      <important>
+	<para>Drivers are not supposed to convert image formats in
+kernel space. They must enumerate only formats directly supported by
+the hardware. If necessary driver writers should publish an example
+conversion routine or library for integration into applications.</para>
+      </important>
+    </section>
+  </section>
+
+  <section id="crop">
+    <title>Image Cropping, Insertion and Scaling</title>
+
+    <para>Some video capture devices can sample a subsection of the
+picture and shrink or enlarge it to an image of arbitrary size. We
+call these abilities cropping and scaling. Some video output devices
+can scale an image up or down and insert it at an arbitrary scan line
+and horizontal offset into a video signal.</para>
+
+    <para>Applications can use the following API to select an area in
+the video signal, query the default area and the hardware limits.
+<emphasis>Despite their name, the &VIDIOC-CROPCAP;, &VIDIOC-G-CROP;
+and &VIDIOC-S-CROP; ioctls apply to input as well as output
+devices.</emphasis></para>
+
+    <para>Scaling requires a source and a target. On a video capture
+or overlay device the source is the video signal, and the cropping
+ioctls determine the area actually sampled. The target are images
+read by the application or overlaid onto the graphics screen. Their
+size (and position for an overlay) is negotiated with the
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls.</para>
+
+    <para>On a video output device the source are the images passed in
+by the application, and their size is again negotiated with the
+<constant>VIDIOC_G/S_FMT</constant> ioctls, or may be encoded in a
+compressed video stream. The target is the video signal, and the
+cropping ioctls determine the area where the images are
+inserted.</para>
+
+    <para>Source and target rectangles are defined even if the device
+does not support scaling or the <constant>VIDIOC_G/S_CROP</constant>
+ioctls. Their size (and position where applicable) will be fixed in
+this case. <emphasis>All capture and output device must support the
+<constant>VIDIOC_CROPCAP</constant> ioctl such that applications can
+determine if scaling takes place.</emphasis></para>
+
+    <section>
+      <title>Cropping Structures</title>
+
+      <figure id="crop-scale">
+	<title>Image Cropping, Insertion and Scaling</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="crop.pdf" format="PS" />
+	  </imageobject>
+	  <imageobject>
+	    <imagedata fileref="crop.gif" format="GIF" />
+	  </imageobject>
+	  <textobject>
+	    <phrase>The cropping, insertion and scaling process</phrase>
+	  </textobject>
+	</mediaobject>
+      </figure>
+
+      <para>For capture devices the coordinates of the top left
+corner, width and height of the area which can be sampled is given by
+the <structfield>bounds</structfield> substructure of the
+&v4l2-cropcap; returned by the <constant>VIDIOC_CROPCAP</constant>
+ioctl. To support a wide range of hardware this specification does not
+define an origin or units. However by convention drivers should
+horizontally count unscaled samples relative to 0H (the leading edge
+of the horizontal sync pulse, see <xref linkend="vbi-hsync" />).
+Vertically ITU-R line
+numbers of the first field (<xref linkend="vbi-525" />, <xref
+linkend="vbi-625" />), multiplied by two if the driver can capture both
+fields.</para>
+
+      <para>The top left corner, width and height of the source
+rectangle, that is the area actually sampled, is given by &v4l2-crop;
+using the same coordinate system as &v4l2-cropcap;. Applications can
+use the <constant>VIDIOC_G_CROP</constant> and
+<constant>VIDIOC_S_CROP</constant> ioctls to get and set this
+rectangle. It must lie completely within the capture boundaries and
+the driver may further adjust the requested size and/or position
+according to hardware limitations.</para>
+
+      <para>Each capture device has a default source rectangle, given
+by the <structfield>defrect</structfield> substructure of
+&v4l2-cropcap;. The center of this rectangle shall align with the
+center of the active picture area of the video signal, and cover what
+the driver writer considers the complete picture. Drivers shall reset
+the source rectangle to the default when the driver is first loaded,
+but not later.</para>
+
+      <para>For output devices these structures and ioctls are used
+accordingly, defining the <emphasis>target</emphasis> rectangle where
+the images will be inserted into the video signal.</para>
+
+    </section>
+
+    <section>
+      <title>Scaling Adjustments</title>
+
+      <para>Video hardware can have various cropping, insertion and
+scaling limitations. It may only scale up or down, support only
+discrete scaling factors, or have different scaling abilities in
+horizontal and vertical direction. Also it may not support scaling at
+all. At the same time the &v4l2-crop; rectangle may have to be
+aligned, and both the source and target rectangles may have arbitrary
+upper and lower size limits. In particular the maximum
+<structfield>width</structfield> and <structfield>height</structfield>
+in &v4l2-crop; may be smaller than the
+&v4l2-cropcap;.<structfield>bounds</structfield> area. Therefore, as
+usual, drivers are expected to adjust the requested parameters and
+return the actual values selected.</para>
+
+      <para>Applications can change the source or the target rectangle
+first, as they may prefer a particular image size or a certain area in
+the video signal. If the driver has to adjust both to satisfy hardware
+limitations, the last requested rectangle shall take priority, and the
+driver should preferably adjust the opposite one. The &VIDIOC-TRY-FMT;
+ioctl however shall not change the driver state and therefore only
+adjust the requested rectangle.</para>
+
+      <para>Suppose scaling on a video capture device is restricted to
+a factor 1:1 or 2:1 in either direction and the target image size must
+be a multiple of 16&nbsp;&times;&nbsp;16 pixels. The source cropping
+rectangle is set to defaults, which are also the upper limit in this
+example, of 640&nbsp;&times;&nbsp;400 pixels at offset 0,&nbsp;0. An
+application requests an image size of 300&nbsp;&times;&nbsp;225
+pixels, assuming video will be scaled down from the "full picture"
+accordingly. The driver sets the image size to the closest possible
+values 304&nbsp;&times;&nbsp;224, then chooses the cropping rectangle
+closest to the requested size, that is 608&nbsp;&times;&nbsp;224
+(224&nbsp;&times;&nbsp;2:1 would exceed the limit 400). The offset
+0,&nbsp;0 is still valid, thus unmodified. Given the default cropping
+rectangle reported by <constant>VIDIOC_CROPCAP</constant> the
+application can easily propose another offset to center the cropping
+rectangle.</para>
+
+      <para>Now the application may insist on covering an area using a
+picture aspect ratio closer to the original request, so it asks for a
+cropping rectangle of 608&nbsp;&times;&nbsp;456 pixels. The present
+scaling factors limit cropping to 640&nbsp;&times;&nbsp;384, so the
+driver returns the cropping size 608&nbsp;&times;&nbsp;384 and adjusts
+the image size to closest possible 304&nbsp;&times;&nbsp;192.</para>
+
+    </section>
+
+    <section>
+      <title>Examples</title>
+
+      <para>Source and target rectangles shall remain unchanged across
+closing and reopening a device, such that piping data into or out of a
+device will work without special preparations. More advanced
+applications should ensure the parameters are suitable before starting
+I/O.</para>
+
+      <example>
+	<title>Resetting the cropping parameters</title>
+
+	<para>(A video capture device is assumed; change
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> for other
+devices.)</para>
+
+	<programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-crop; crop;
+
+memset (&amp;cropcap, 0, sizeof (cropcap));
+cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &amp;cropcap)) {
+	perror ("VIDIOC_CROPCAP");
+	exit (EXIT_FAILURE);
+}
+
+memset (&amp;crop, 0, sizeof (crop));
+crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+crop.c = cropcap.defrect;
+
+/* Ignore if cropping is not supported (EINVAL). */
+
+if (-1 == ioctl (fd, &VIDIOC-S-CROP;, &amp;crop)
+    &amp;&amp; errno != EINVAL) {
+	perror ("VIDIOC_S_CROP");
+	exit (EXIT_FAILURE);
+}
+      </programlisting>
+      </example>
+
+      <example>
+	<title>Simple downscaling</title>
+
+	<para>(A video capture device is assumed.)</para>
+
+	<programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-format; format;
+
+reset_cropping_parameters ();
+
+/* Scale down to 1/4 size of full picture. */
+
+memset (&amp;format, 0, sizeof (format)); /* defaults */
+
+format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+format.fmt.pix.width = cropcap.defrect.width &gt;&gt; 1;
+format.fmt.pix.height = cropcap.defrect.height &gt;&gt; 1;
+format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+
+if (-1 == ioctl (fd, &VIDIOC-S-FMT;, &amp;format)) {
+	perror ("VIDIOC_S_FORMAT");
+	exit (EXIT_FAILURE);
+}
+
+/* We could check the actual image size now, the actual scaling factor
+   or if the driver can scale at all. */
+	</programlisting>
+      </example>
+
+      <example>
+	<title>Selecting an output area</title>
+
+	<programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-crop; crop;
+
+memset (&amp;cropcap, 0, sizeof (cropcap));
+cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &amp;cropcap)) {
+	perror ("VIDIOC_CROPCAP");
+	exit (EXIT_FAILURE);
+}
+
+memset (&amp;crop, 0, sizeof (crop));
+
+crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+crop.c = cropcap.defrect;
+
+/* Scale the width and height to 50 % of their original size
+   and center the output. */
+
+crop.c.width /= 2;
+crop.c.height /= 2;
+crop.c.left += crop.c.width / 2;
+crop.c.top += crop.c.height / 2;
+
+/* Ignore if cropping is not supported (EINVAL). */
+
+if (-1 == ioctl (fd, VIDIOC_S_CROP, &amp;crop)
+    &amp;&amp; errno != EINVAL) {
+	perror ("VIDIOC_S_CROP");
+	exit (EXIT_FAILURE);
+}
+</programlisting>
+      </example>
+
+      <example>
+	<title>Current scaling factor and pixel aspect</title>
+
+	<para>(A video capture device is assumed.)</para>
+
+	<programlisting>
+&v4l2-cropcap; cropcap;
+&v4l2-crop; crop;
+&v4l2-format; format;
+double hscale, vscale;
+double aspect;
+int dwidth, dheight;
+
+memset (&amp;cropcap, 0, sizeof (cropcap));
+cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &amp;cropcap)) {
+	perror ("VIDIOC_CROPCAP");
+	exit (EXIT_FAILURE);
+}
+
+memset (&amp;crop, 0, sizeof (crop));
+crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-G-CROP;, &amp;crop)) {
+	if (errno != EINVAL) {
+		perror ("VIDIOC_G_CROP");
+		exit (EXIT_FAILURE);
+	}
+
+	/* Cropping not supported. */
+	crop.c = cropcap.defrect;
+}
+
+memset (&amp;format, 0, sizeof (format));
+format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+if (-1 == ioctl (fd, &VIDIOC-G-FMT;, &amp;format)) {
+	perror ("VIDIOC_G_FMT");
+	exit (EXIT_FAILURE);
+}
+
+/* The scaling applied by the driver. */
+
+hscale = format.fmt.pix.width / (double) crop.c.width;
+vscale = format.fmt.pix.height / (double) crop.c.height;
+
+aspect = cropcap.pixelaspect.numerator /
+	 (double) cropcap.pixelaspect.denominator;
+aspect = aspect * hscale / vscale;
+
+/* Devices following ITU-R BT.601 do not capture
+   square pixels. For playback on a computer monitor
+   we should scale the images to this size. */
+
+dwidth = format.fmt.pix.width / aspect;
+dheight = format.fmt.pix.height;
+	</programlisting>
+      </example>
+    </section>
+  </section>
+
+  <section id="streaming-par">
+    <title>Streaming Parameters</title>
+
+    <para>Streaming parameters are intended to optimize the video
+capture process as well as I/O. Presently applications can request a
+high quality capture mode with the &VIDIOC-S-PARM; ioctl.</para>
+
+    <para>The current video standard determines a nominal number of
+frames per second. If less than this number of frames is to be
+captured or output, applications can request frame skipping or
+duplicating on the driver side. This is especially useful when using
+the &func-read; or &func-write;, which are not augmented by timestamps
+or sequence counters, and to avoid unneccessary data copying.</para>
+
+    <para>Finally these ioctls can be used to determine the number of
+buffers used internally by a driver in read/write mode. For
+implications see the section discussing the &func-read;
+function.</para>
+
+    <para>To get and set the streaming parameters applications call
+the &VIDIOC-G-PARM; and &VIDIOC-S-PARM; ioctl, respectively. They take
+a pointer to a &v4l2-streamparm;, which contains a union holding
+separate parameters for input and output devices.</para>
+
+    <para>These ioctls are optional, drivers need not implement
+them. If so, they return the &EINVAL;.</para>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/compat.xml b/Documentation/DocBook/v4l/compat.xml
new file mode 100644
index 0000000..4d1902a
--- /dev/null
+++ b/Documentation/DocBook/v4l/compat.xml
@@ -0,0 +1,2457 @@
+  <title>Changes</title>
+
+  <para>The following chapters document the evolution of the V4L2 API,
+errata or extensions. They are also intended to help application and
+driver writers to port or update their code.</para>
+
+  <section id="diff-v4l">
+    <title>Differences between V4L and V4L2</title>
+
+    <para>The Video For Linux API was first introduced in Linux 2.1 to
+unify and replace various TV and radio device related interfaces,
+developed independently by driver writers in prior years. Starting
+with Linux 2.5 the much improved V4L2 API replaces the V4L API,
+although existing drivers will continue to support V4L applications in
+the future, either directly or through the V4L2 compatibility layer in
+the <filename>videodev</filename> kernel module translating ioctls on
+the fly. For a transition period not all drivers will support the V4L2
+API.</para>
+
+    <section>
+      <title>Opening and Closing Devices</title>
+
+      <para>For compatibility reasons the character device file names
+recommended for V4L2 video capture, overlay, radio, teletext and raw
+vbi capture devices did not change from those used by V4L. They are
+listed in <xref linkend="devices" /> and below in <xref
+	  linkend="v4l-dev" />.</para>
+
+      <para>The V4L <filename>videodev</filename> module automatically
+assigns minor numbers to drivers in load order, depending on the
+registered device type. We recommend that V4L2 drivers by default
+register devices with the same numbers, but the system administrator
+can assign arbitrary minor numbers using driver module options. The
+major device number remains 81.</para>
+
+      <table id="v4l-dev">
+	<title>V4L Device Types, Names and Numbers</title>
+	<tgroup cols="3">
+	  <thead>
+	    <row>
+	      <entry>Device Type</entry>
+	      <entry>File Name</entry>
+	      <entry>Minor Numbers</entry>
+	    </row>
+	  </thead>
+	  <tbody valign="top">
+	    <row>
+	      <entry>Video capture and overlay</entry>
+	      <entry><para><filename>/dev/video</filename> and
+<filename>/dev/bttv0</filename><footnote> <para>According to
+Documentation/devices.txt these should be symbolic links to
+<filename>/dev/video0</filename>. Note the original bttv interface is
+not compatible with V4L or V4L2.</para> </footnote>,
+<filename>/dev/video0</filename> to
+<filename>/dev/video63</filename></para></entry>
+	      <entry>0-63</entry>
+	    </row>
+	    <row>
+	      <entry>Radio receiver</entry>
+	      <entry><para><filename>/dev/radio</filename><footnote>
+		    <para>According to
+<filename>Documentation/devices.txt</filename> a symbolic link to
+<filename>/dev/radio0</filename>.</para>
+		  </footnote>, <filename>/dev/radio0</filename> to
+<filename>/dev/radio63</filename></para></entry>
+	      <entry>64-127</entry>
+	    </row>
+	    <row>
+	      <entry>Teletext decoder</entry>
+	      <entry><para><filename>/dev/vtx</filename>,
+<filename>/dev/vtx0</filename> to
+<filename>/dev/vtx31</filename></para></entry>
+	      <entry>192-223</entry>
+	    </row>
+	    <row>
+	      <entry>Raw VBI capture</entry>
+	      <entry><para><filename>/dev/vbi</filename>,
+<filename>/dev/vbi0</filename> to
+<filename>/dev/vbi31</filename></para></entry>
+	      <entry>224-255</entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+
+      <para>V4L prohibits (or used to prohibit) multiple opens of a
+device file. V4L2 drivers <emphasis>may</emphasis> support multiple
+opens, see <xref linkend="open" /> for details and consequences.</para>
+
+      <para>V4L drivers respond to V4L2 ioctls with an &EINVAL;. The
+compatibility layer in the V4L2 <filename>videodev</filename> module
+can translate V4L ioctl requests to their V4L2 counterpart, however a
+V4L2 driver usually needs more preparation to become fully V4L
+compatible. This is covered in more detail in <xref
+	  linkend="driver" />.</para>
+    </section>
+
+    <section>
+      <title>Querying Capabilities</title>
+
+      <para>The V4L <constant>VIDIOCGCAP</constant> ioctl is
+equivalent to V4L2's &VIDIOC-QUERYCAP;.</para>
+
+      <para>The <structfield>name</structfield> field in struct
+<structname>video_capability</structname> became
+<structfield>card</structfield> in &v4l2-capability;,
+<structfield>type</structfield> was replaced by
+<structfield>capabilities</structfield>. Note V4L2 does not
+distinguish between device types like this, better think of basic
+video input, video output and radio devices supporting a set of
+related functions like video capturing, video overlay and VBI
+capturing. See <xref linkend="open" /> for an
+introduction.<informaltable>
+	  <tgroup cols="3">
+	    <thead>
+	      <row>
+		<entry>struct
+<structname>video_capability</structname>
+<structfield>type</structfield></entry>
+		<entry>&v4l2-capability;
+<structfield>capabilities</structfield> flags</entry>
+		<entry>Purpose</entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row>
+		<entry><constant>VID_TYPE_CAPTURE</constant></entry>
+		<entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
+		<entry>The <link linkend="capture">video
+capture</link> interface is supported.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_TUNER</constant></entry>
+		<entry><constant>V4L2_CAP_TUNER</constant></entry>
+		<entry>The device has a <link linkend="tuner">tuner or
+modulator</link>.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_TELETEXT</constant></entry>
+		<entry><constant>V4L2_CAP_VBI_CAPTURE</constant></entry>
+		<entry>The <link linkend="raw-vbi">raw VBI
+capture</link> interface is supported.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_OVERLAY</constant></entry>
+		<entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
+		<entry>The <link linkend="overlay">video
+overlay</link> interface is supported.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_CHROMAKEY</constant></entry>
+		<entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant> in
+field <structfield>capability</structfield> of
+&v4l2-framebuffer;</entry>
+		<entry>Whether chromakey overlay is supported. For
+more information on overlay see
+<xref linkend="overlay" />.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_CLIPPING</constant></entry>
+		<entry><constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant>
+and <constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant> in field
+<structfield>capability</structfield> of &v4l2-framebuffer;</entry>
+		<entry>Whether clipping the overlaid image is
+supported, see <xref linkend="overlay" />.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_FRAMERAM</constant></entry>
+		<entry><constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant>
+<emphasis>not set</emphasis> in field
+<structfield>capability</structfield> of &v4l2-framebuffer;</entry>
+		<entry>Whether overlay overwrites frame buffer memory,
+see <xref linkend="overlay" />.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_SCALES</constant></entry>
+		<entry><constant>-</constant></entry>
+		<entry>This flag indicates if the hardware can scale
+images. The V4L2 API implies the scale factor by setting the cropping
+dimensions and image size with the &VIDIOC-S-CROP; and &VIDIOC-S-FMT;
+ioctl, respectively. The driver returns the closest sizes possible.
+For more information on cropping and scaling see <xref
+		    linkend="crop" />.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_MONOCHROME</constant></entry>
+		<entry><constant>-</constant></entry>
+		<entry>Applications can enumerate the supported image
+formats with the &VIDIOC-ENUM-FMT; ioctl to determine if the device
+supports grey scale capturing only. For more information on image
+formats see <xref linkend="pixfmt" />.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_SUBCAPTURE</constant></entry>
+		<entry><constant>-</constant></entry>
+		<entry>Applications can call the &VIDIOC-G-CROP; ioctl
+to determine if the device supports capturing a subsection of the full
+picture ("cropping" in V4L2). If not, the ioctl returns the &EINVAL;.
+For more information on cropping and scaling see <xref
+		    linkend="crop" />.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_MPEG_DECODER</constant></entry>
+		<entry><constant>-</constant></entry>
+		<entry>Applications can enumerate the supported image
+formats with the &VIDIOC-ENUM-FMT; ioctl to determine if the device
+supports MPEG streams.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_MPEG_ENCODER</constant></entry>
+		<entry><constant>-</constant></entry>
+		<entry>See above.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_MJPEG_DECODER</constant></entry>
+		<entry><constant>-</constant></entry>
+		<entry>See above.</entry>
+	      </row>
+	      <row>
+		<entry><constant>VID_TYPE_MJPEG_ENCODER</constant></entry>
+		<entry><constant>-</constant></entry>
+		<entry>See above.</entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</informaltable></para>
+
+      <para>The <structfield>audios</structfield> field was replaced
+by <structfield>capabilities</structfield> flag
+<constant>V4L2_CAP_AUDIO</constant>, indicating
+<emphasis>if</emphasis> the device has any audio inputs or outputs. To
+determine their number applications can enumerate audio inputs with
+the &VIDIOC-G-AUDIO; ioctl. The audio ioctls are described in <xref
+	  linkend="audio" />.</para>
+
+      <para>The <structfield>maxwidth</structfield>,
+<structfield>maxheight</structfield>,
+<structfield>minwidth</structfield> and
+<structfield>minheight</structfield> fields were removed. Calling the
+&VIDIOC-S-FMT; or &VIDIOC-TRY-FMT; ioctl with the desired dimensions
+returns the closest size possible, taking into account the current
+video standard, cropping and scaling limitations.</para>
+    </section>
+
+    <section>
+      <title>Video Sources</title>
+
+      <para>V4L provides the <constant>VIDIOCGCHAN</constant> and
+<constant>VIDIOCSCHAN</constant> ioctl using struct
+<structname>video_channel</structname> to enumerate
+the video inputs of a V4L device. The equivalent V4L2 ioctls
+are &VIDIOC-ENUMINPUT;, &VIDIOC-G-INPUT; and &VIDIOC-S-INPUT;
+using &v4l2-input; as discussed in <xref linkend="video" />.</para>
+
+      <para>The <structfield>channel</structfield> field counting
+inputs was renamed to <structfield>index</structfield>, the video
+input types were renamed as follows: <informaltable>
+	  <tgroup cols="2">
+	    <thead>
+	      <row>
+		<entry>struct <structname>video_channel</structname>
+<structfield>type</structfield></entry>
+		<entry>&v4l2-input;
+<structfield>type</structfield></entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row>
+		<entry><constant>VIDEO_TYPE_TV</constant></entry>
+		<entry><constant>V4L2_INPUT_TYPE_TUNER</constant></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_TYPE_CAMERA</constant></entry>
+		<entry><constant>V4L2_INPUT_TYPE_CAMERA</constant></entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</informaltable></para>
+
+      <para>Unlike the <structfield>tuners</structfield> field
+expressing the number of tuners of this input, V4L2 assumes each video
+input is connected to at most one tuner. However a tuner can have more
+than one input, &ie; RF connectors, and a device can have multiple
+tuners. The index number of the tuner associated with the input, if
+any, is stored in field <structfield>tuner</structfield> of
+&v4l2-input;. Enumeration of tuners is discussed in <xref
+	  linkend="tuner" />.</para>
+
+      <para>The redundant <constant>VIDEO_VC_TUNER</constant> flag was
+dropped. Video inputs associated with a tuner are of type
+<constant>V4L2_INPUT_TYPE_TUNER</constant>. The
+<constant>VIDEO_VC_AUDIO</constant> flag was replaced by the
+<structfield>audioset</structfield> field. V4L2 considers devices with
+up to 32 audio inputs. Each set bit in the
+<structfield>audioset</structfield> field represents one audio input
+this video input combines with. For information about audio inputs and
+how to switch between them see <xref linkend="audio" />.</para>
+
+      <para>The <structfield>norm</structfield> field describing the
+supported video standards was replaced by
+<structfield>std</structfield>. The V4L specification mentions a flag
+<constant>VIDEO_VC_NORM</constant> indicating whether the standard can
+be changed. This flag was a later addition together with the
+<structfield>norm</structfield> field and has been removed in the
+meantime. V4L2 has a similar, albeit more comprehensive approach
+to video standards, see <xref linkend="standard" /> for more
+information.</para>
+    </section>
+
+    <section>
+      <title>Tuning</title>
+
+      <para>The V4L <constant>VIDIOCGTUNER</constant> and
+<constant>VIDIOCSTUNER</constant> ioctl and struct
+<structname>video_tuner</structname> can be used to enumerate the
+tuners of a V4L TV or radio device. The equivalent V4L2 ioctls are
+&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; using &v4l2-tuner;. Tuners are
+covered in <xref linkend="tuner" />.</para>
+
+      <para>The <structfield>tuner</structfield> field counting tuners
+was renamed to <structfield>index</structfield>. The fields
+<structfield>name</structfield>, <structfield>rangelow</structfield>
+and <structfield>rangehigh</structfield> remained unchanged.</para>
+
+      <para>The <constant>VIDEO_TUNER_PAL</constant>,
+<constant>VIDEO_TUNER_NTSC</constant> and
+<constant>VIDEO_TUNER_SECAM</constant> flags indicating the supported
+video standards were dropped. This information is now contained in the
+associated &v4l2-input;. No replacement exists for the
+<constant>VIDEO_TUNER_NORM</constant> flag indicating whether the
+video standard can be switched. The <structfield>mode</structfield>
+field to select a different video standard was replaced by a whole new
+set of ioctls and structures described in <xref linkend="standard" />.
+Due to its ubiquity it should be mentioned the BTTV driver supports
+several standards in addition to the regular
+<constant>VIDEO_MODE_PAL</constant> (0),
+<constant>VIDEO_MODE_NTSC</constant>,
+<constant>VIDEO_MODE_SECAM</constant> and
+<constant>VIDEO_MODE_AUTO</constant> (3). Namely N/PAL Argentina,
+M/PAL, N/PAL, and NTSC Japan with numbers 3-6 (sic).</para>
+
+      <para>The <constant>VIDEO_TUNER_STEREO_ON</constant> flag
+indicating stereo reception became
+<constant>V4L2_TUNER_SUB_STEREO</constant> in field
+<structfield>rxsubchans</structfield>. This field also permits the
+detection of monaural and bilingual audio, see the definition of
+&v4l2-tuner; for details. Presently no replacement exists for the
+<constant>VIDEO_TUNER_RDS_ON</constant> and
+<constant>VIDEO_TUNER_MBS_ON</constant> flags.</para>
+
+      <para> The <constant>VIDEO_TUNER_LOW</constant> flag was renamed
+to <constant>V4L2_TUNER_CAP_LOW</constant> in the &v4l2-tuner;
+<structfield>capability</structfield> field.</para>
+
+      <para>The <constant>VIDIOCGFREQ</constant> and
+<constant>VIDIOCSFREQ</constant> ioctl to change the tuner frequency
+where renamed to &VIDIOC-G-FREQUENCY; and  &VIDIOC-S-FREQUENCY;. They
+take a pointer to a &v4l2-frequency; instead of an unsigned long
+integer.</para>
+    </section>
+
+    <section id="v4l-image-properties">
+      <title>Image Properties</title>
+
+      <para>V4L2 has no equivalent of the
+<constant>VIDIOCGPICT</constant> and <constant>VIDIOCSPICT</constant>
+ioctl and struct <structname>video_picture</structname>. The following
+fields where replaced by V4L2 controls accessible with the
+&VIDIOC-QUERYCTRL;, &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls:<informaltable>
+	  <tgroup cols="2">
+	    <thead>
+	      <row>
+		<entry>struct <structname>video_picture</structname></entry>
+		<entry>V4L2 Control ID</entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row>
+		<entry><structfield>brightness</structfield></entry>
+		<entry><constant>V4L2_CID_BRIGHTNESS</constant></entry>
+	      </row>
+	      <row>
+		<entry><structfield>hue</structfield></entry>
+		<entry><constant>V4L2_CID_HUE</constant></entry>
+	      </row>
+	      <row>
+		<entry><structfield>colour</structfield></entry>
+		<entry><constant>V4L2_CID_SATURATION</constant></entry>
+	      </row>
+	      <row>
+		<entry><structfield>contrast</structfield></entry>
+		<entry><constant>V4L2_CID_CONTRAST</constant></entry>
+	      </row>
+	      <row>
+		<entry><structfield>whiteness</structfield></entry>
+		<entry><constant>V4L2_CID_WHITENESS</constant></entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</informaltable></para>
+
+      <para>The V4L picture controls are assumed to range from 0 to
+65535 with no particular reset value. The V4L2 API permits arbitrary
+limits and defaults which can be queried with the &VIDIOC-QUERYCTRL;
+ioctl. For general information about controls see <xref
+linkend="control" />.</para>
+
+      <para>The <structfield>depth</structfield> (average number of
+bits per pixel) of a video image is implied by the selected image
+format. V4L2 does not explicitely provide such information assuming
+applications recognizing the format are aware of the image depth and
+others need not know. The <structfield>palette</structfield> field
+moved into the &v4l2-pix-format;:<informaltable>
+	  <tgroup cols="2">
+	    <thead>
+	      <row>
+		<entry>struct <structname>video_picture</structname>
+<structfield>palette</structfield></entry>
+		<entry>&v4l2-pix-format;
+<structfield>pixfmt</structfield></entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row>
+		<entry><constant>VIDEO_PALETTE_GREY</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-GREY"><constant>V4L2_PIX_FMT_GREY</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_HI240</constant></entry>
+		<entry><para><link
+linkend="pixfmt-reserved"><constant>V4L2_PIX_FMT_HI240</constant></link><footnote>
+		      <para>This is a custom format used by the BTTV
+driver, not one of the V4L2 standard formats.</para>
+		    </footnote></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_RGB565</constant></entry>
+		<entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_RGB565</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_RGB555</constant></entry>
+		<entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_RGB555</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_RGB24</constant></entry>
+		<entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_BGR24</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_RGB32</constant></entry>
+		<entry><para><link
+linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_BGR32</constant></link><footnote>
+		      <para>Presumably all V4L RGB formats are
+little-endian, although some drivers might interpret them according to machine endianess. V4L2 defines little-endian, big-endian and red/blue
+swapped variants. For details see <xref linkend="pixfmt-rgb" />.</para>
+		    </footnote></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_YUV422</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><para><constant>VIDEO_PALETTE_YUYV</constant><footnote>
+		      <para><constant>VIDEO_PALETTE_YUV422</constant>
+and <constant>VIDEO_PALETTE_YUYV</constant> are the same formats. Some
+V4L drivers respond to one, some to the other.</para>
+		    </footnote></para></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_UYVY</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-UYVY"><constant>V4L2_PIX_FMT_UYVY</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_YUV420</constant></entry>
+		<entry>None</entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_YUV411</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-Y41P"><constant>V4L2_PIX_FMT_Y41P</constant></link><footnote>
+		      <para>Not to be confused with
+<constant>V4L2_PIX_FMT_YUV411P</constant>, which is a planar
+format.</para> </footnote></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_RAW</constant></entry>
+		<entry><para>None<footnote> <para>V4L explains this
+as: "RAW capture (BT848)"</para> </footnote></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_YUV422P</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-YUV422P"><constant>V4L2_PIX_FMT_YUV422P</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_YUV411P</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-YUV411P"><constant>V4L2_PIX_FMT_YUV411P</constant></link><footnote>
+		      <para>Not to be confused with
+<constant>V4L2_PIX_FMT_Y41P</constant>, which is a packed
+format.</para> </footnote></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_YUV420P</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link></para></entry>
+	      </row>
+	      <row>
+		<entry><constant>VIDEO_PALETTE_YUV410P</constant></entry>
+		<entry><para><link
+linkend="V4L2-PIX-FMT-YVU410"><constant>V4L2_PIX_FMT_YVU410</constant></link></para></entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</informaltable></para>
+
+      <para>V4L2 image formats are defined in <xref
+linkend="pixfmt" />. The image format can be selected with the
+&VIDIOC-S-FMT; ioctl.</para>
+    </section>
+
+    <section>
+      <title>Audio</title>
+
+      <para>The <constant>VIDIOCGAUDIO</constant> and
+<constant>VIDIOCSAUDIO</constant> ioctl and struct
+<structname>video_audio</structname> are used to enumerate the
+audio inputs of a V4L device. The equivalent V4L2 ioctls are
+&VIDIOC-G-AUDIO; and &VIDIOC-S-AUDIO; using &v4l2-audio; as
+discussed in <xref linkend="audio" />.</para>
+
+      <para>The <structfield>audio</structfield> "channel number"
+field counting audio inputs was renamed to
+<structfield>index</structfield>.</para>
+
+      <para>On <constant>VIDIOCSAUDIO</constant> the
+<structfield>mode</structfield> field selects <emphasis>one</emphasis>
+of the <constant>VIDEO_SOUND_MONO</constant>,
+<constant>VIDEO_SOUND_STEREO</constant>,
+<constant>VIDEO_SOUND_LANG1</constant> or
+<constant>VIDEO_SOUND_LANG2</constant> audio demodulation modes. When
+the current audio standard is BTSC
+<constant>VIDEO_SOUND_LANG2</constant> refers to SAP and
+<constant>VIDEO_SOUND_LANG1</constant> is meaningless. Also
+undocumented in the V4L specification, there is no way to query the
+selected mode. On <constant>VIDIOCGAUDIO</constant> the driver returns
+the <emphasis>actually received</emphasis> audio programmes in this
+field. In the V4L2 API this information is stored in the &v4l2-tuner;
+<structfield>rxsubchans</structfield> and
+<structfield>audmode</structfield> fields, respectively. See <xref
+linkend="tuner" /> for more information on tuners. Related to audio
+modes &v4l2-audio; also reports if this is a mono or stereo
+input, regardless if the source is a tuner.</para>
+
+      <para>The following fields where replaced by V4L2 controls
+accessible with the &VIDIOC-QUERYCTRL;, &VIDIOC-G-CTRL; and
+&VIDIOC-S-CTRL; ioctls:<informaltable>
+	  <tgroup cols="2">
+	    <thead>
+	      <row>
+		<entry>struct
+<structname>video_audio</structname></entry>
+		<entry>V4L2 Control ID</entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row>
+		<entry><structfield>volume</structfield></entry>
+		<entry><constant>V4L2_CID_AUDIO_VOLUME</constant></entry>
+	      </row>
+	      <row>
+		<entry><structfield>bass</structfield></entry>
+		<entry><constant>V4L2_CID_AUDIO_BASS</constant></entry>
+	      </row>
+	      <row>
+		<entry><structfield>treble</structfield></entry>
+		<entry><constant>V4L2_CID_AUDIO_TREBLE</constant></entry>
+	      </row>
+	      <row>
+		<entry><structfield>balance</structfield></entry>
+		<entry><constant>V4L2_CID_AUDIO_BALANCE</constant></entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</informaltable></para>
+
+      <para>To determine which of these controls are supported by a
+driver V4L provides the <structfield>flags</structfield>
+<constant>VIDEO_AUDIO_VOLUME</constant>,
+<constant>VIDEO_AUDIO_BASS</constant>,
+<constant>VIDEO_AUDIO_TREBLE</constant> and
+<constant>VIDEO_AUDIO_BALANCE</constant>. In the V4L2 API the
+&VIDIOC-QUERYCTRL; ioctl reports if the respective control is
+supported. Accordingly the <constant>VIDEO_AUDIO_MUTABLE</constant>
+and <constant>VIDEO_AUDIO_MUTE</constant> flags where replaced by the
+boolean <constant>V4L2_CID_AUDIO_MUTE</constant> control.</para>
+
+      <para>All V4L2 controls have a <structfield>step</structfield>
+attribute replacing the struct <structname>video_audio</structname>
+<structfield>step</structfield> field. The V4L audio controls are
+assumed to range from 0 to 65535 with no particular reset value. The
+V4L2 API permits arbitrary limits and defaults which can be queried
+with the &VIDIOC-QUERYCTRL; ioctl. For general information about
+controls see <xref linkend="control" />.</para>
+    </section>
+
+    <section>
+      <title>Frame Buffer Overlay</title>
+
+      <para>The V4L2 ioctls equivalent to
+<constant>VIDIOCGFBUF</constant> and <constant>VIDIOCSFBUF</constant>
+are &VIDIOC-G-FBUF; and &VIDIOC-S-FBUF;. The
+<structfield>base</structfield> field of struct
+<structname>video_buffer</structname> remained unchanged, except V4L2
+defines a flag to indicate non-destructive overlays instead of a
+<constant>NULL</constant> pointer. All other fields moved into the
+&v4l2-pix-format; <structfield>fmt</structfield> substructure of
+&v4l2-framebuffer;. The <structfield>depth</structfield> field was
+replaced by <structfield>pixelformat</structfield>. See <xref
+	  linkend="pixfmt-rgb" /> for a list of RGB formats and their
+respective color depths.</para>
+
+      <para>Instead of the special ioctls
+<constant>VIDIOCGWIN</constant> and <constant>VIDIOCSWIN</constant>
+V4L2 uses the general-purpose data format negotiation ioctls
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT;. They take a pointer to a
+&v4l2-format; as argument. Here the <structfield>win</structfield>
+member of the <structfield>fmt</structfield> union is used, a
+&v4l2-window;.</para>
+
+      <para>The <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> fields of struct
+<structname>video_window</structname> moved into &v4l2-rect;
+substructure <structfield>w</structfield> of struct
+<structname>v4l2_window</structname>. The
+<structfield>chromakey</structfield>,
+<structfield>clips</structfield>, and
+<structfield>clipcount</structfield> fields remained unchanged. Struct
+<structname>video_clip</structname> was renamed to &v4l2-clip;, also
+containing a struct <structname>v4l2_rect</structname>, but the
+semantics are still the same.</para>
+
+      <para>The <constant>VIDEO_WINDOW_INTERLACE</constant> flag was
+dropped. Instead applications must set the
+<structfield>field</structfield> field to
+<constant>V4L2_FIELD_ANY</constant> or
+<constant>V4L2_FIELD_INTERLACED</constant>. The
+<constant>VIDEO_WINDOW_CHROMAKEY</constant> flag moved into
+&v4l2-framebuffer;, under the new name
+<constant>V4L2_FBUF_FLAG_CHROMAKEY</constant>.</para>
+
+      <para>In V4L, storing a bitmap pointer in
+<structfield>clips</structfield> and setting
+<structfield>clipcount</structfield> to
+<constant>VIDEO_CLIP_BITMAP</constant> (-1) requests bitmap
+clipping, using a fixed size bitmap of 1024 &times; 625 bits. Struct
+<structname>v4l2_window</structname> has a separate
+<structfield>bitmap</structfield> pointer field for this purpose and
+the bitmap size is determined by <structfield>w.width</structfield> and
+<structfield>w.height</structfield>.</para>
+
+      <para>The <constant>VIDIOCCAPTURE</constant> ioctl to enable or
+disable overlay was renamed to &VIDIOC-OVERLAY;.</para>
+    </section>
+
+    <section>
+      <title>Cropping</title>
+
+      <para>To capture only a subsection of the full picture V4L
+defines the <constant>VIDIOCGCAPTURE</constant> and
+<constant>VIDIOCSCAPTURE</constant> ioctls using struct
+<structname>video_capture</structname>. The equivalent V4L2 ioctls are
+&VIDIOC-G-CROP; and &VIDIOC-S-CROP; using &v4l2-crop;, and the related
+&VIDIOC-CROPCAP; ioctl. This is a rather complex matter, see
+<xref linkend="crop" /> for details.</para>
+
+      <para>The <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> fields moved into &v4l2-rect;
+substructure <structfield>c</structfield> of struct
+<structname>v4l2_crop</structname>. The
+<structfield>decimation</structfield> field was dropped. In the V4L2
+API the scaling factor is implied by the size of the cropping
+rectangle and the size of the captured or overlaid image.</para>
+
+      <para>The <constant>VIDEO_CAPTURE_ODD</constant>
+and <constant>VIDEO_CAPTURE_EVEN</constant> flags to capture only the
+odd or even field, respectively, were replaced by
+<constant>V4L2_FIELD_TOP</constant> and
+<constant>V4L2_FIELD_BOTTOM</constant> in the field named
+<structfield>field</structfield> of &v4l2-pix-format; and
+&v4l2-window;. These structures are used to select a capture or
+overlay format with the &VIDIOC-S-FMT; ioctl.</para>
+    </section>
+
+    <section>
+      <title>Reading Images, Memory Mapping</title>
+
+      <section>
+	<title>Capturing using the read method</title>
+
+	<para>There is no essential difference between reading images
+from a V4L or V4L2 device using the &func-read; function, however V4L2
+drivers are not required to support this I/O method. Applications can
+determine if the function is available with the &VIDIOC-QUERYCAP;
+ioctl. All V4L2 devices exchanging data with applications must support
+the &func-select; and &func-poll; functions.</para>
+
+	<para>To select an image format and size, V4L provides the
+<constant>VIDIOCSPICT</constant> and <constant>VIDIOCSWIN</constant>
+ioctls. V4L2 uses the general-purpose data format negotiation ioctls
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT;. They take a pointer to a
+&v4l2-format; as argument, here the &v4l2-pix-format; named
+<structfield>pix</structfield> of its <structfield>fmt</structfield>
+union is used.</para>
+
+	<para>For more information about the V4L2 read interface see
+<xref linkend="rw" />.</para>
+      </section>
+      <section>
+	<title>Capturing using memory mapping</title>
+
+	<para>Applications can read from V4L devices by mapping
+buffers in device memory, or more often just buffers allocated in
+DMA-able system memory, into their address space. This avoids the data
+copying overhead of the read method. V4L2 supports memory mapping as
+well, with a few differences.</para>
+
+	<informaltable>
+	  <tgroup cols="2">
+	    <thead>
+	      <row>
+		<entry>V4L</entry>
+		<entry>V4L2</entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row>
+		<entry></entry>
+		<entry>The image format must be selected before
+buffers are allocated, with the &VIDIOC-S-FMT; ioctl. When no format
+is selected the driver may use the last, possibly by another
+application requested format.</entry>
+	      </row>
+	      <row>
+		<entry><para>Applications cannot change the number of
+buffers. The it is built into the driver, unless it has a module
+option to change the number when the driver module is
+loaded.</para></entry>
+		<entry><para>The &VIDIOC-REQBUFS; ioctl allocates the
+desired number of buffers, this is a required step in the initialization
+sequence.</para></entry>
+	      </row>
+	      <row>
+		<entry><para>Drivers map all buffers as one contiguous
+range of memory. The <constant>VIDIOCGMBUF</constant> ioctl is
+available to query the number of buffers, the offset of each buffer
+from the start of the virtual file, and the overall amount of memory
+used, which can be used as arguments for the &func-mmap;
+function.</para></entry>
+		<entry><para>Buffers are individually mapped. The
+offset and size of each buffer can be determined with the
+&VIDIOC-QUERYBUF; ioctl.</para></entry>
+	      </row>
+	      <row>
+		<entry><para>The <constant>VIDIOCMCAPTURE</constant>
+ioctl prepares a buffer for capturing. It also determines the image
+format for this buffer. The ioctl returns immediately, eventually with
+an &EAGAIN; if no video signal had been detected. When the driver
+supports more than one buffer applications can call the ioctl multiple
+times and thus have multiple outstanding capture
+requests.</para><para>The <constant>VIDIOCSYNC</constant> ioctl
+suspends execution until a particular buffer has been
+filled.</para></entry>
+		<entry><para>Drivers maintain an incoming and outgoing
+queue. &VIDIOC-QBUF; enqueues any empty buffer into the incoming
+queue. Filled buffers are dequeued from the outgoing queue with the
+&VIDIOC-DQBUF; ioctl. To wait until filled buffers become available this
+function, &func-select; or &func-poll; can be used. The
+&VIDIOC-STREAMON; ioctl must be called once after enqueuing one or
+more buffers to start capturing. Its counterpart
+&VIDIOC-STREAMOFF; stops capturing and dequeues all buffers from both
+queues. Applications can query the signal status, if known, with the
+&VIDIOC-ENUMINPUT; ioctl.</para></entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</informaltable>
+
+	<para>For a more in-depth discussion of memory mapping and
+examples, see <xref linkend="mmap" />.</para>
+      </section>
+    </section>
+
+    <section>
+      <title>Reading Raw VBI Data</title>
+
+      <para>Originally the V4L API did not specify a raw VBI capture
+interface, only the device file <filename>/dev/vbi</filename> was
+reserved for this purpose. The only driver supporting this interface
+was the BTTV driver, de-facto defining the V4L VBI interface. Reading
+from the device yields a raw VBI image with the following
+parameters:<informaltable>
+	    <tgroup cols="2">
+	      <thead>
+		<row>
+		  <entry>&v4l2-vbi-format;</entry>
+		  <entry>V4L, BTTV driver</entry>
+		</row>
+	      </thead>
+	      <tbody valign="top">
+		<row>
+		  <entry>sampling_rate</entry>
+		  <entry>28636363&nbsp;Hz NTSC (or any other 525-line
+standard); 35468950&nbsp;Hz PAL and SECAM (625-line standards)</entry>
+		</row>
+		<row>
+		  <entry>offset</entry>
+		  <entry>?</entry>
+		</row>
+		<row>
+		  <entry>samples_per_line</entry>
+		  <entry>2048</entry>
+		</row>
+		<row>
+		  <entry>sample_format</entry>
+		  <entry>V4L2_PIX_FMT_GREY. The last four bytes (a
+machine endianess integer) contain a frame counter.</entry>
+		</row>
+		<row>
+		  <entry>start[]</entry>
+		  <entry>10, 273 NTSC; 22, 335 PAL and SECAM</entry>
+		</row>
+		<row>
+		  <entry>count[]</entry>
+		  <entry><para>16, 16<footnote><para>Old driver
+versions used different values, eventually the custom
+<constant>BTTV_VBISIZE</constant> ioctl was added to query the
+correct values.</para></footnote></para></entry>
+		</row>
+		<row>
+		  <entry>flags</entry>
+		  <entry>0</entry>
+		</row>
+	      </tbody>
+	    </tgroup>
+	</informaltable></para>
+
+      <para>Undocumented in the V4L specification, in Linux 2.3 the
+<constant>VIDIOCGVBIFMT</constant> and
+<constant>VIDIOCSVBIFMT</constant> ioctls using struct
+<structname>vbi_format</structname> were added to determine the VBI
+image parameters. These ioctls are only partially compatible with the
+V4L2 VBI interface specified in <xref linkend="raw-vbi" />.</para>
+
+      <para>An <structfield>offset</structfield> field does not
+exist, <structfield>sample_format</structfield> is supposed to be
+<constant>VIDEO_PALETTE_RAW</constant>, equivalent to
+<constant>V4L2_PIX_FMT_GREY</constant>. The remaining fields are
+probably equivalent to &v4l2-vbi-format;.</para>
+
+      <para>Apparently only the Zoran (ZR 36120) driver implements
+these ioctls. The semantics differ from those specified for V4L2 in two
+ways. The parameters are reset on &func-open; and
+<constant>VIDIOCSVBIFMT</constant> always returns an &EINVAL; if the
+parameters are invalid.</para>
+    </section>
+
+    <section>
+      <title>Miscellaneous</title>
+
+      <para>V4L2 has no equivalent of the
+<constant>VIDIOCGUNIT</constant> ioctl. Applications can find the VBI
+device associated with a video capture device (or vice versa) by
+reopening the device and requesting VBI data. For details see
+<xref linkend="open" />.</para>
+
+      <para>No replacement exists for <constant>VIDIOCKEY</constant>,
+and the V4L functions for microcode programming. A new interface for
+MPEG compression and playback devices is documented in <xref
+	  linkend="extended-controls" />.</para>
+    </section>
+
+  </section>
+
+  <section id="hist-v4l2">
+    <title>Changes of the V4L2 API</title>
+
+    <para>Soon after the V4L API was added to the kernel it was
+criticised as too inflexible. In August 1998 Bill Dirks proposed a
+number of improvements and began to work on documentation, example
+drivers and applications. With the help of other volunteers this
+eventually became the V4L2 API, not just an extension but a
+replacement for the V4L API. However it took another four years and
+two stable kernel releases until the new API was finally accepted for
+inclusion into the kernel in its present form.</para>
+
+    <section>
+      <title>Early Versions</title>
+      <para>1998-08-20: First version.</para>
+
+      <para>1998-08-27: The &func-select; function was introduced.</para>
+
+      <para>1998-09-10: New video standard interface.</para>
+
+      <para>1998-09-18: The <constant>VIDIOC_NONCAP</constant> ioctl
+was replaced by the otherwise meaningless <constant>O_TRUNC</constant>
+&func-open; flag, and the aliases <constant>O_NONCAP</constant> and
+<constant>O_NOIO</constant> were defined. Applications can set this
+flag if they intend to access controls only, as opposed to capture
+applications which need exclusive access. The
+<constant>VIDEO_STD_XXX</constant> identifiers are now ordinals
+instead of flags, and the <function>video_std_construct()</function>
+helper function takes id and transmission arguments.</para>
+
+      <para>1998-09-28: Revamped video standard. Made video controls
+individually enumerable.</para>
+
+      <para>1998-10-02: The <structfield>id</structfield> field was
+removed from struct <structname>video_standard</structname> and the
+color subcarrier fields were renamed. The &VIDIOC-QUERYSTD; ioctl was
+renamed to &VIDIOC-ENUMSTD;, &VIDIOC-G-INPUT; to &VIDIOC-ENUMINPUT;. A
+first draft of the Codec API was released.</para>
+
+      <para>1998-11-08: Many minor changes. Most symbols have been
+renamed. Some material changes to &v4l2-capability;.</para>
+
+      <para>1998-11-12: The read/write directon of some ioctls was misdefined.</para>
+
+      <para>1998-11-14: <constant>V4L2_PIX_FMT_RGB24</constant>
+changed to <constant>V4L2_PIX_FMT_BGR24</constant>, and
+<constant>V4L2_PIX_FMT_RGB32</constant> changed to
+<constant>V4L2_PIX_FMT_BGR32</constant>. Audio controls are now
+accessible with the &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls under
+names starting with <constant>V4L2_CID_AUDIO</constant>. The
+<constant>V4L2_MAJOR</constant> define was removed from
+<filename>videodev.h</filename> since it was only used once in the
+<filename>videodev</filename> kernel module. The
+<constant>YUV422</constant> and <constant>YUV411</constant> planar
+image formats were added.</para>
+
+      <para>1998-11-28: A few ioctl symbols changed. Interfaces for codecs and
+video output devices were added.</para>
+
+      <para>1999-01-14: A raw VBI capture interface was added.</para>
+
+      <para>1999-01-19: The <constant>VIDIOC_NEXTBUF</constant> ioctl
+      was removed.</para>
+    </section>
+
+    <section>
+      <title>V4L2 Version 0.16 1999-01-31</title>
+      <para>1999-01-27: There is now one QBUF ioctl, VIDIOC_QWBUF and VIDIOC_QRBUF
+are gone. VIDIOC_QBUF takes a v4l2_buffer as a parameter. Added
+digital zoom (cropping) controls.</para>
+    </section>
+
+    <!-- Where's 0.17? mhs couldn't find that videodev.h, perhaps Bill
+	 forgot to bump the version number or never released it. -->
+
+    <section>
+      <title>V4L2 Version 0.18 1999-03-16</title>
+      <para>Added a v4l to V4L2 ioctl compatibility layer to
+videodev.c. Driver writers, this changes how you implement your ioctl
+handler. See the Driver Writer's Guide. Added some more control id
+codes.</para>
+    </section>
+
+    <section>
+      <title>V4L2 Version 0.19 1999-06-05</title>
+      <para>1999-03-18: Fill in the category and catname fields of
+v4l2_queryctrl objects before passing them to the driver. Required a
+minor change to the VIDIOC_QUERYCTRL handlers in the sample
+drivers.</para>
+      <para>1999-03-31: Better compatibility for v4l memory capture
+ioctls. Requires changes to drivers to fully support new compatibility
+features, see Driver Writer's Guide and v4l2cap.c. Added new control
+IDs: V4L2_CID_HFLIP, _VFLIP. Changed V4L2_PIX_FMT_YUV422P to _YUV422P,
+and _YUV411P to _YUV411P.</para>
+      <para>1999-04-04: Added a few more control IDs.</para>
+      <para>1999-04-07: Added the button control type.</para>
+      <para>1999-05-02: Fixed a typo in videodev.h, and added the
+V4L2_CTRL_FLAG_GRAYED (later V4L2_CTRL_FLAG_GRABBED) flag.</para>
+      <para>1999-05-20: Definition of VIDIOC_G_CTRL was wrong causing
+a malfunction of this ioctl.</para>
+      <para>1999-06-05: Changed the value of
+V4L2_CID_WHITENESS.</para>
+    </section>
+
+    <section>
+      <title>V4L2 Version 0.20 (1999-09-10)</title>
+
+      <para>Version 0.20 introduced a number of changes which were
+<emphasis>not backward compatible</emphasis> with 0.19 and earlier
+versions. Purpose of these changes was to simplify the API, while
+making it more extensible and following common Linux driver API
+conventions.</para>
+
+      <orderedlist>
+	<listitem>
+	  <para>Some typos in <constant>V4L2_FMT_FLAG</constant>
+symbols were fixed. &v4l2-clip; was changed for compatibility with
+v4l. (1999-08-30)</para>
+	</listitem>
+
+	<listitem>
+	  <para><constant>V4L2_TUNER_SUB_LANG1</constant> was added.
+(1999-09-05)</para>
+	</listitem>
+
+	<listitem>
+	  <para>All ioctl() commands that used an integer argument now
+take a pointer to an integer. Where it makes sense, ioctls will return
+the actual new value in the integer pointed to by the argument, a
+common convention in the V4L2 API. The affected ioctls are:
+VIDIOC_PREVIEW, VIDIOC_STREAMON, VIDIOC_STREAMOFF, VIDIOC_S_FREQ,
+VIDIOC_S_INPUT, VIDIOC_S_OUTPUT, VIDIOC_S_EFFECT. For example
+<programlisting>
+err = ioctl (fd, VIDIOC_XXX, V4L2_XXX);
+</programlisting> becomes <programlisting>
+int a = V4L2_XXX; err = ioctl(fd, VIDIOC_XXX, &amp;a);
+</programlisting>
+	  </para>
+	</listitem>
+
+	<listitem>
+	  <para>All the different get- and set-format commands were
+swept into one &VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctl taking a union
+and a type field selecting the union member as parameter. Purpose is to
+simplify the API by eliminating several ioctls and to allow new and
+driver private data streams without adding new ioctls.</para>
+
+	  <para>This change obsoletes the following ioctls:
+<constant>VIDIOC_S_INFMT</constant>,
+<constant>VIDIOC_G_INFMT</constant>,
+<constant>VIDIOC_S_OUTFMT</constant>,
+<constant>VIDIOC_G_OUTFMT</constant>,
+<constant>VIDIOC_S_VBIFMT</constant> and
+<constant>VIDIOC_G_VBIFMT</constant>. The image format structure
+<structname>v4l2_format</structname> was renamed to &v4l2-pix-format;,
+while &v4l2-format; is now the envelopping structure for all format
+negotiations.</para>
+	</listitem>
+
+	<listitem>
+	  <para>Similar to the changes above, the
+<constant>VIDIOC_G_PARM</constant> and
+<constant>VIDIOC_S_PARM</constant> ioctls were merged with
+<constant>VIDIOC_G_OUTPARM</constant> and
+<constant>VIDIOC_S_OUTPARM</constant>. A
+<structfield>type</structfield> field in the new &v4l2-streamparm;
+selects the respective union member.</para>
+
+	  <para>This change obsoletes the
+<constant>VIDIOC_G_OUTPARM</constant> and
+<constant>VIDIOC_S_OUTPARM</constant> ioctls.</para>
+	</listitem>
+
+	<listitem>
+	  <para>Control enumeration was simplified, and two new
+control flags were introduced and one dropped. The
+<structfield>catname</structfield> field was replaced by a
+<structfield>group</structfield> field.</para>
+
+	  <para>Drivers can now flag unsupported and temporarily
+unavailable controls with <constant>V4L2_CTRL_FLAG_DISABLED</constant>
+and <constant>V4L2_CTRL_FLAG_GRABBED</constant> respectively. The
+<structfield>group</structfield> name indicates a possibly narrower
+classification than the <structfield>category</structfield>. In other
+words, there may be multiple groups within a category. Controls within
+a group would typically be drawn within a group box. Controls in
+different categories might have a greater separation, or may even
+appear in separate windows.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &v4l2-buffer; <structfield>timestamp</structfield>
+was changed to a 64 bit integer, containing the sampling or output
+time of the frame in nanoseconds. Additionally timestamps will be in
+absolute system time, not starting from zero at the beginning of a
+stream. The data type name for timestamps is stamp_t, defined as a
+signed 64-bit integer. Output devices should not send a buffer out
+until the time in the timestamp field has arrived. I would like to
+follow SGI's lead, and adopt a multimedia timestamping system like
+their UST (Unadjusted System Time). See
+http://reality.sgi.com/cpirazzi_engr/lg/time/intro.html. [This link is
+no longer valid.] UST uses timestamps that are 64-bit signed integers
+(not struct timeval's) and given in nanosecond units. The UST clock
+starts at zero when the system is booted and runs continuously and
+uniformly. It takes a little over 292 years for UST to overflow. There
+is no way to set the UST clock. The regular Linux time-of-day clock
+can be changed periodically, which would cause errors if it were being
+used for timestamping a multimedia stream. A real UST style clock will
+require some support in the kernel that is not there yet. But in
+anticipation, I will change the timestamp field to a 64-bit integer,
+and I will change the v4l2_masterclock_gettime() function (used only
+by drivers) to return a 64-bit integer.</para>
+	</listitem>
+
+	<listitem>
+	  <para>A <structfield>sequence</structfield> field was added
+to &v4l2-buffer;. The <structfield>sequence</structfield> field counts
+captured frames, it is ignored by output devices. When a capture
+driver drops a frame, the sequence number of that frame is
+skipped.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 Version 0.20 incremental changes</title>
+      <!-- Version number didn't change anymore, reason unknown. -->
+
+      <para>1999-12-23: In &v4l2-vbi-format; the
+<structfield>reserved1</structfield> field became
+<structfield>offset</structfield>. Previously drivers were required to
+clear the <structfield>reserved1</structfield> field.</para>
+
+      <para>2000-01-13: The
+      <constant>V4L2_FMT_FLAG_NOT_INTERLACED</constant> flag was added.</para>
+
+      <para>2000-07-31: The <filename>linux/poll.h</filename> header
+is now included by <filename>videodev.h</filename> for compatibility
+with the original <filename>videodev.h</filename> file.</para>
+
+      <para>2000-11-20: <constant>V4L2_TYPE_VBI_OUTPUT</constant> and
+<constant>V4L2_PIX_FMT_Y41P</constant> were added.</para>
+
+      <para>2000-11-25: <constant>V4L2_TYPE_VBI_INPUT</constant> was
+added.</para>
+
+      <para>2000-12-04: A couple typos in symbol names were fixed.</para>
+
+      <para>2001-01-18: To avoid namespace conflicts the
+<constant>fourcc</constant> macro defined in the
+<filename>videodev.h</filename> header file was renamed to
+<constant>v4l2_fourcc</constant>.</para>
+
+      <para>2001-01-25: A possible driver-level compatibility problem
+between the <filename>videodev.h</filename> file in Linux 2.4.0 and
+the <filename>videodev.h</filename> file included in the
+<filename>videodevX</filename> patch was fixed. Users of an earlier
+version of <filename>videodevX</filename> on Linux 2.4.0 should
+recompile their V4L and V4L2 drivers.</para>
+
+      <para>2001-01-26: A possible kernel-level incompatibility
+between the <filename>videodev.h</filename> file in the
+<filename>videodevX</filename> patch and the
+<filename>videodev.h</filename> file in Linux 2.2.x with devfs patches
+applied was fixed.</para>
+
+      <para>2001-03-02: Certain V4L ioctls which pass data in both
+direction although they are defined with read-only parameter, did not
+work correctly through the backward compatibility layer.
+[Solution?]</para>
+
+      <para>2001-04-13: Big endian 16-bit RGB formats were added.</para>
+
+      <para>2001-09-17: New YUV formats and the &VIDIOC-G-FREQUENCY; and
+&VIDIOC-S-FREQUENCY; ioctls were added. (The old
+<constant>VIDIOC_G_FREQ</constant> and
+<constant>VIDIOC_S_FREQ</constant> ioctls did not take multiple tuners
+into account.)</para>
+
+      <para>2000-09-18: <constant>V4L2_BUF_TYPE_VBI</constant> was
+added. This may <emphasis>break compatibility</emphasis> as the
+&VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls may fail now if the struct
+<structname>v4l2_fmt</structname> <structfield>type</structfield>
+field does not contain <constant>V4L2_BUF_TYPE_VBI</constant>. In the
+documentation of the &v4l2-vbi-format;
+<structfield>offset</structfield> field the ambiguous phrase "rising
+edge" was changed to "leading edge".</para>
+    </section>
+
+    <section>
+      <title>V4L2 Version 0.20 2000-11-23</title>
+
+      <para>A number of changes were made to the raw VBI
+interface.</para>
+
+      <orderedlist>
+	<listitem>
+	  <para>Figures clarifying the line numbering scheme were
+added to the V4L2 API specification. The
+<structfield>start</structfield>[0] and
+<structfield>start</structfield>[1] fields no longer count line
+numbers beginning at zero. Rationale: a) The previous definition was
+unclear. b) The <structfield>start</structfield>[] values are ordinal
+numbers. c) There is no point in inventing a new line numbering
+scheme. We now use line number as defined by ITU-R, period.
+Compatibility: Add one to the start values. Applications depending on
+the previous semantics may not function correctly.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The restriction "count[0] &gt; 0 and count[1] &gt; 0"
+has been relaxed  to "(count[0] + count[1]) &gt; 0". Rationale:
+Drivers may allocate resources at scan line granularity and some data
+services are transmitted only on the first field. The comment that
+both <structfield>count</structfield> values will usually be equal is
+misleading and pointless and has been removed. This change
+<emphasis>breaks compatibility</emphasis> with earlier versions:
+Drivers may return EINVAL, applications may not function
+correctly.</para>
+	</listitem>
+
+	<listitem>
+	  <para>Drivers are again permitted to return negative
+(unknown) start values as proposed earlier. Why this feature was
+dropped is unclear. This change may <emphasis>break
+compatibility</emphasis> with applications depending on the start
+values being positive. The use of <constant>EBUSY</constant> and
+<constant>EINVAL</constant> error codes with the &VIDIOC-S-FMT; ioctl
+was clarified. The &EBUSY; was finally documented, and the
+<structfield>reserved2</structfield> field which was previously
+mentioned only in the <filename>videodev.h</filename> header
+file.</para>
+	</listitem>
+
+	<listitem>
+	  <para>New buffer types
+<constant>V4L2_TYPE_VBI_INPUT</constant> and
+<constant>V4L2_TYPE_VBI_OUTPUT</constant> were added. The former is an
+alias for the old <constant>V4L2_TYPE_VBI</constant>, the latter was
+missing in the <filename>videodev.h</filename> file.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 Version 0.20 2002-07-25</title>
+      <para>Added sliced VBI interface proposal.</para>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.5.46, 2002-10</title>
+
+      <para>Around October-November 2002, prior to an announced
+feature freeze of Linux 2.5, the API was revised, drawing from
+experience with V4L2 0.20. This unnamed version was finally merged
+into Linux 2.5.46.</para>
+
+      <orderedlist>
+	<listitem>
+	  <para>As specified in <xref linkend="related" />, drivers
+must make related device functions available under all minor device
+numbers.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &func-open; function requires access mode
+<constant>O_RDWR</constant> regardless of the device type. All V4L2
+drivers exchanging data with applications must support the
+<constant>O_NONBLOCK</constant> flag. The <constant>O_NOIO</constant>
+flag, a V4L2 symbol which aliased the meaningless
+<constant>O_TRUNC</constant> to indicate accesses without data
+exchange (panel applications) was dropped. Drivers must stay in "panel
+mode" until the application attempts to initiate a data exchange, see
+<xref linkend="open" />.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &v4l2-capability; changed dramatically. Note that
+also the size of the structure changed, which is encoded in the ioctl
+request code, thus older V4L2 devices will respond with an &EINVAL; to
+the new &VIDIOC-QUERYCAP; ioctl.</para>
+
+	  <para>There are new fields to identify the driver, a new RDS
+device function <constant>V4L2_CAP_RDS_CAPTURE</constant>, the
+<constant>V4L2_CAP_AUDIO</constant> flag indicates if the device has
+any audio connectors, another I/O capability
+<constant>V4L2_CAP_ASYNCIO</constant> can be flagged. In response to
+these changes the <structfield>type</structfield> field became a bit
+set and was merged into the <structfield>flags</structfield> field.
+<constant>V4L2_FLAG_TUNER</constant> was renamed to
+<constant>V4L2_CAP_TUNER</constant>,
+<constant>V4L2_CAP_VIDEO_OVERLAY</constant> replaced
+<constant>V4L2_FLAG_PREVIEW</constant> and
+<constant>V4L2_CAP_VBI_CAPTURE</constant> and
+<constant>V4L2_CAP_VBI_OUTPUT</constant> replaced
+<constant>V4L2_FLAG_DATA_SERVICE</constant>.
+<constant>V4L2_FLAG_READ</constant> and
+<constant>V4L2_FLAG_WRITE</constant> were merged into
+<constant>V4L2_CAP_READWRITE</constant>.</para>
+
+	  <para>The redundant fields
+<structfield>inputs</structfield>, <structfield>outputs</structfield>
+and <structfield>audios</structfield> were removed. These properties
+can be determined as described in <xref linkend="video" /> and <xref
+linkend="audio" />.</para>
+
+	  <para>The somewhat volatile and therefore barely useful
+fields <structfield>maxwidth</structfield>,
+<structfield>maxheight</structfield>,
+<structfield>minwidth</structfield>,
+<structfield>minheight</structfield>,
+<structfield>maxframerate</structfield> were removed. This information
+is available as described in <xref linkend="format" /> and
+<xref linkend="standard" />.</para>
+
+	  <para><constant>V4L2_FLAG_SELECT</constant> was removed. We
+believe the select() function is important enough to require support
+of it in all V4L2 drivers exchanging data with applications. The
+redundant <constant>V4L2_FLAG_MONOCHROME</constant> flag was removed,
+this information is available as described in <xref
+	      linkend="format" />.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-input; the
+<structfield>assoc_audio</structfield> field and the
+<structfield>capability</structfield> field and its only flag
+<constant>V4L2_INPUT_CAP_AUDIO</constant> was replaced by the new
+<structfield>audioset</structfield> field. Instead of linking one
+video input to one audio input this field reports all audio inputs
+this video input combines with.</para>
+
+	  <para>New fields are <structfield>tuner</structfield>
+(reversing the former link from tuners to video inputs),
+<structfield>std</structfield> and
+<structfield>status</structfield>.</para>
+
+	  <para>Accordingly &v4l2-output; lost its
+<structfield>capability</structfield> and
+<structfield>assoc_audio</structfield> fields.
+<structfield>audioset</structfield>,
+<structfield>modulator</structfield> and
+<structfield>std</structfield> where added instead.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &v4l2-audio; field
+<structfield>audio</structfield> was renamed to
+<structfield>index</structfield>, for consistency with other
+structures. A new capability flag
+<constant>V4L2_AUDCAP_STEREO</constant> was added to indicated if the
+audio input in question supports stereo sound.
+<constant>V4L2_AUDCAP_EFFECTS</constant> and the corresponding
+<constant>V4L2_AUDMODE</constant> flags where removed. This can be
+easily implemented using controls. (However the same applies to AVL
+which is still there.)</para>
+
+	  <para>Again for consistency the &v4l2-audioout; field
+<structfield>audio</structfield> was renamed to
+<structfield>index</structfield>.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &v4l2-tuner;
+<structfield>input</structfield> field was replaced by an
+<structfield>index</structfield> field, permitting devices with
+multiple tuners. The link between video inputs and tuners is now
+reversed, inputs point to their tuner. The
+<structfield>std</structfield> substructure became a
+simple set (more about this below) and moved into &v4l2-input;. A
+<structfield>type</structfield> field was added.</para>
+
+	  <para>Accordingly in &v4l2-modulator; the
+<structfield>output</structfield> was replaced by an
+<structfield>index</structfield> field.</para>
+
+	  <para>In &v4l2-frequency; the
+<structfield>port</structfield> field was replaced by a
+<structfield>tuner</structfield> field containing the respective tuner
+or modulator index number. A tuner <structfield>type</structfield>
+field was added and the <structfield>reserved</structfield> field
+became larger for future extensions (satellite tuners in
+particular).</para>
+	</listitem>
+
+	<listitem>
+	  <para>The idea of completely transparent video standards was
+dropped. Experience showed that applications must be able to work with
+video standards beyond presenting the user a menu. Instead of
+enumerating supported standards with an ioctl applications can now
+refer to standards by &v4l2-std-id; and symbols defined in the
+<filename>videodev2.h</filename> header file. For details see <xref
+	      linkend="standard" />. The &VIDIOC-G-STD; and
+&VIDIOC-S-STD; now take a pointer to this type as argument.
+&VIDIOC-QUERYSTD; was added to autodetect the received standard, if
+the hardware has this capability. In &v4l2-standard; an
+<structfield>index</structfield> field was added for &VIDIOC-ENUMSTD;.
+A &v4l2-std-id; field named <structfield>id</structfield> was added as
+machine readable identifier, also replacing the
+<structfield>transmission</structfield> field. The misleading
+<structfield>framerate</structfield> field was renamed
+to <structfield>frameperiod</structfield>. The now obsolete
+<structfield>colorstandard</structfield> information, originally
+needed to distguish between variations of standards, were
+removed.</para>
+
+	  <para>Struct <structname>v4l2_enumstd</structname> ceased to
+be. &VIDIOC-ENUMSTD; now takes a pointer to a &v4l2-standard;
+directly. The information which standards are supported by a
+particular video input or output moved into &v4l2-input; and
+&v4l2-output; fields named <structfield>std</structfield>,
+respectively.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &v4l2-queryctrl; fields
+<structfield>category</structfield> and
+<structfield>group</structfield> did not catch on and/or were not
+implemented as expected and therefore removed.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &VIDIOC-TRY-FMT; ioctl was added to negotiate data
+formats as with &VIDIOC-S-FMT;, but without the overhead of
+programming the hardware and regardless of I/O in progress.</para>
+
+	  <para>In &v4l2-format; the <structfield>fmt</structfield>
+union was extended to contain &v4l2-window;. All image format
+negotiations are now possible with <constant>VIDIOC_G_FMT</constant>,
+<constant>VIDIOC_S_FMT</constant> and
+<constant>VIDIOC_TRY_FMT</constant>; ioctl. The
+<constant>VIDIOC_G_WIN</constant> and
+<constant>VIDIOC_S_WIN</constant> ioctls to prepare for a video
+overlay were removed. The <structfield>type</structfield> field
+changed to type &v4l2-buf-type; and the buffer type names changed as
+follows.<informaltable>
+	      <tgroup cols="2">
+		<thead>
+		  <row>
+		    <entry>Old defines</entry>
+		    <entry>&v4l2-buf-type;</entry>
+		  </row>
+		</thead>
+		<tbody valign="top">
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_CAPTURE</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_CODECIN</constant></entry>
+		    <entry>Omitted for now</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_CODECOUT</constant></entry>
+		    <entry>Omitted for now</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_EFFECTSIN</constant></entry>
+		    <entry>Omitted for now</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_EFFECTSIN2</constant></entry>
+		    <entry>Omitted for now</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_EFFECTSOUT</constant></entry>
+		    <entry>Omitted for now</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_VIDEOOUT</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_BUF_TYPE_PRIVATE_BASE</constant></entry>
+		    <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
+		  </row>
+		</tbody>
+	      </tgroup>
+	    </informaltable></para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-fmtdesc; a &v4l2-buf-type; field named
+<structfield>type</structfield> was added as in &v4l2-format;. The
+<constant>VIDIOC_ENUM_FBUFFMT</constant> ioctl is no longer needed and
+was removed. These calls can be replaced by &VIDIOC-ENUM-FMT; with
+type <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-pix-format; the
+<structfield>depth</structfield> field was removed, assuming
+applications which recognize the format by its four-character-code
+already know the color depth, and others do not care about it. The
+same rationale lead to the removal of the
+<constant>V4L2_FMT_FLAG_COMPRESSED</constant> flag. The
+<constant>V4L2_FMT_FLAG_SWCONVECOMPRESSED</constant> flag was removed
+because drivers are not supposed to convert images in kernel space. A
+user library of conversion functions should be provided instead. The
+<constant>V4L2_FMT_FLAG_BYTESPERLINE</constant> flag was redundant.
+Applications can set the <structfield>bytesperline</structfield> field
+to zero to get a reasonable default. Since the remaining flags were
+replaced as well, the <structfield>flags</structfield> field itself
+was removed.</para>
+	  <para>The interlace flags were replaced by a &v4l2-field;
+value in a newly added <structfield>field</structfield>
+field.<informaltable>
+	      <tgroup cols="2">
+		<thead>
+		  <row>
+		    <entry>Old flag</entry>
+		    <entry>&v4l2-field;</entry>
+		  </row>
+		</thead>
+		<tbody valign="top">
+		  <row>
+		    <entry><constant>V4L2_FMT_FLAG_NOT_INTERLACED</constant></entry>
+		    <entry>?</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_FMT_FLAG_INTERLACED</constant>
+= <constant>V4L2_FMT_FLAG_COMBINED</constant></entry>
+		    <entry><constant>V4L2_FIELD_INTERLACED</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_FMT_FLAG_TOPFIELD</constant>
+= <constant>V4L2_FMT_FLAG_ODDFIELD</constant></entry>
+		    <entry><constant>V4L2_FIELD_TOP</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_FMT_FLAG_BOTFIELD</constant>
+= <constant>V4L2_FMT_FLAG_EVENFIELD</constant></entry>
+		    <entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_FIELD_SEQ_TB</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_FIELD_SEQ_BT</constant></entry>
+		  </row>
+		  <row>
+		    <entry><constant>-</constant></entry>
+		    <entry><constant>V4L2_FIELD_ALTERNATE</constant></entry>
+		  </row>
+		</tbody>
+	      </tgroup>
+	    </informaltable></para>
+
+	  <para>The color space flags were replaced by a
+&v4l2-colorspace; value in a newly added
+<structfield>colorspace</structfield> field, where one of
+<constant>V4L2_COLORSPACE_SMPTE170M</constant>,
+<constant>V4L2_COLORSPACE_BT878</constant>,
+<constant>V4L2_COLORSPACE_470_SYSTEM_M</constant> or
+<constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant> replaces
+<constant>V4L2_FMT_CS_601YUV</constant>.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-requestbuffers; the
+<structfield>type</structfield> field was properly defined as
+&v4l2-buf-type;. Buffer types changed as mentioned above. A new
+<structfield>memory</structfield> field of type &v4l2-memory; was
+added to distinguish between I/O methods using buffers allocated
+by the driver or the application. See <xref linkend="io" /> for
+details.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-buffer; the <structfield>type</structfield>
+field was properly defined as &v4l2-buf-type;. Buffer types changed as
+mentioned above. A <structfield>field</structfield> field of type
+&v4l2-field; was added to indicate if a buffer contains a top or
+bottom field. The old field flags were removed. Since no unadjusted
+system time clock was added to the kernel as planned, the
+<structfield>timestamp</structfield> field changed back from type
+stamp_t, an unsigned 64 bit integer expressing the sample time in
+nanoseconds, to struct <structname>timeval</structname>. With the
+addition of a second memory mapping method the
+<structfield>offset</structfield> field moved into union
+<structfield>m</structfield>, and a new
+<structfield>memory</structfield> field of type &v4l2-memory; was
+added to distinguish between I/O methods. See <xref linkend="io" />
+for details.</para>
+
+	  <para>The <constant>V4L2_BUF_REQ_CONTIG</constant>
+flag was used by the V4L compatibility layer, after changes to this
+code it was no longer needed. The
+<constant>V4L2_BUF_ATTR_DEVICEMEM</constant> flag would indicate if
+the buffer was indeed allocated in device memory rather than DMA-able
+system memory. It was barely useful and so was removed.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-framebuffer; the
+<structfield>base[3]</structfield> array anticipating double- and
+triple-buffering in off-screen video memory, however without defining
+a synchronization mechanism, was replaced by a single pointer. The
+<constant>V4L2_FBUF_CAP_SCALEUP</constant> and
+<constant>V4L2_FBUF_CAP_SCALEDOWN</constant> flags were removed.
+Applications can determine this capability more accurately using the
+new cropping and scaling interface. The
+<constant>V4L2_FBUF_CAP_CLIPPING</constant> flag was replaced by
+<constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant> and
+<constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant>.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-clip; the <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> field moved into a
+<structfield>c</structfield> substructure of type &v4l2-rect;. The
+<structfield>x</structfield> and <structfield>y</structfield> fields
+were renamed to <structfield>left</structfield> and
+<structfield>top</structfield>, &ie; offsets to a context dependent
+origin.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-window; the <structfield>x</structfield>,
+<structfield>y</structfield>, <structfield>width</structfield> and
+<structfield>height</structfield> field moved into a
+<structfield>w</structfield> substructure as above. A
+<structfield>field</structfield> field of type %v4l2-field; was added
+to distinguish between field and frame (interlaced) overlay.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The digital zoom interface, including struct
+<structname>v4l2_zoomcap</structname>, struct
+<structname>v4l2_zoom</structname>,
+<constant>V4L2_ZOOM_NONCAP</constant> and
+<constant>V4L2_ZOOM_WHILESTREAMING</constant> was replaced by a new
+cropping and scaling interface. The previously unused struct
+<structname>v4l2_cropcap</structname> and
+<structname>v4l2_crop</structname> where redefined for this purpose.
+See <xref linkend="crop" /> for details.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-vbi-format; the
+<structfield>SAMPLE_FORMAT</structfield> field now contains a
+four-character-code as used to identify video image formats and
+<constant>V4L2_PIX_FMT_GREY</constant> replaces the
+<constant>V4L2_VBI_SF_UBYTE</constant> define. The
+<structfield>reserved</structfield> field was extended.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In &v4l2-captureparm; the type of the
+<structfield>timeperframe</structfield> field changed from unsigned
+long to &v4l2-fract;. This allows the accurate expression of multiples
+of the NTSC-M frame rate 30000 / 1001. A new field
+<structfield>readbuffers</structfield> was added to control the driver
+behaviour in read I/O mode.</para>
+
+	  <para>Similar changes were made to &v4l2-outputparm;.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The struct <structname>v4l2_performance</structname>
+and <constant>VIDIOC_G_PERF</constant> ioctl were dropped. Except when
+using the <link linkend="rw">read/write I/O method</link>, which is
+limited anyway, this information is already available to
+applications.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The example transformation from RGB to YCbCr color
+space in the old V4L2 documentation was inaccurate, this has been
+corrected in <xref linkend="pixfmt" />.<!-- 0.5670G should be
+0.587, and 127/112 != 255/224 --></para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 2003-06-19</title>
+
+      <orderedlist>
+	<listitem>
+	  <para>A new capability flag
+<constant>V4L2_CAP_RADIO</constant> was added for radio devices. Prior
+to this change radio devices would identify solely by having exactly one
+tuner whose type field reads <constant>V4L2_TUNER_RADIO</constant>.</para>
+	</listitem>
+
+	<listitem>
+	  <para>An optional driver access priority mechanism was
+added, see <xref linkend="app-pri" /> for details.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The audio input and output interface was found to be
+incomplete.</para>
+	  <para>Previously the &VIDIOC-G-AUDIO;
+ioctl would enumerate the available audio inputs. An ioctl to
+determine the current audio input, if more than one combines with the
+current video input, did not exist. So
+<constant>VIDIOC_G_AUDIO</constant> was renamed to
+<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl will be removed in
+the future. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate
+audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio
+input.</para>
+	  <para>The same changes were made to &VIDIOC-G-AUDOUT; and
+&VIDIOC-ENUMAUDOUT;.</para>
+	  <para>Until further the "videodev" module will automatically
+translate between the old and new ioctls, but drivers and applications
+must be updated to successfully compile again.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with
+write-read parameter. It was changed to write-only, while the write-read
+version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old
+ioctl will be removed in the future. Until further the "videodev"
+kernel module will automatically translate to the new version, so drivers
+must be recompiled, but not applications.</para>
+	</listitem>
+
+	<listitem>
+	  <para><xref linkend="overlay" /> incorrectly stated that
+clipping rectangles define regions where the video can be seen.
+Correct is that clipping rectangles define regions where
+<emphasis>no</emphasis> video shall be displayed and so the graphics
+surface can be seen.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The &VIDIOC-S-PARM; and &VIDIOC-S-CTRL; ioctls were
+defined with write-only parameter, inconsistent with other ioctls
+modifying their argument. They were changed to write-read, while a
+<constant>_OLD</constant> suffix was added to the write-only versions.
+The old ioctls will be removed in the future. Drivers and
+applications assuming a constant parameter need an update.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 2003-11-05</title>
+      <orderedlist>
+	<listitem>
+	  <para>In <xref linkend="pixfmt-rgb" /> the following pixel
+formats were incorrectly transferred from Bill Dirks' V4L2
+specification. Descriptions below refer to bytes in memory, in
+ascending address order.<informaltable>
+	      <tgroup cols="3">
+		<thead>
+		  <row>
+		    <entry>Symbol</entry>
+		    <entry>In this document prior to revision
+0.5</entry>
+		    <entry>Corrected</entry>
+		  </row>
+		</thead>
+		<tbody valign="top">
+		  <row>
+		    <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
+		    <entry>B, G, R</entry>
+		    <entry>R, G, B</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
+		    <entry>R, G, B</entry>
+		    <entry>B, G, R</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
+		    <entry>B, G, R, X</entry>
+		    <entry>R, G, B, X</entry>
+		  </row>
+		  <row>
+		    <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
+		    <entry>R, G, B, X</entry>
+		    <entry>B, G, R, X</entry>
+		  </row>
+		</tbody>
+	      </tgroup>
+	    </informaltable> The
+<constant>V4L2_PIX_FMT_BGR24</constant> example was always
+correct.</para>
+	  <para>In <xref linkend="v4l-image-properties" /> the mapping
+of the V4L <constant>VIDEO_PALETTE_RGB24</constant> and
+<constant>VIDEO_PALETTE_RGB32</constant> formats to V4L2 pixel formats
+was accordingly corrected.</para>
+	</listitem>
+
+	<listitem>
+	  <para>Unrelated to the fixes above, drivers may still
+interpret some V4L2 RGB pixel formats differently. These issues have
+yet to be addressed, for details see <xref
+	      linkend="pixfmt-rgb" />.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.6, 2004-05-09</title>
+      <orderedlist>
+	<listitem>
+	  <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined
+with read-only parameter. It is now defined as write-read ioctl, while
+the read-only version was renamed to
+<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl will be removed
+in the future.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.8</title>
+      <orderedlist>
+	<listitem>
+	  <para>A new field <structfield>input</structfield> (former
+<structfield>reserved[0]</structfield>) was added to the &v4l2-buffer;
+structure. Purpose of this field is to alternate between video inputs
+(&eg; cameras) in step with the video capturing process. This function
+must be enabled with the new <constant>V4L2_BUF_FLAG_INPUT</constant>
+flag. The <structfield>flags</structfield> field is no longer
+read-only.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 spec erratum 2004-08-01</title>
+
+      <orderedlist>
+	<listitem>
+	  <para>The return value of the
+<xref linkend="func-open" /> function was incorrectly documented.</para>
+	</listitem>
+
+	<listitem>
+	  <para>Audio output ioctls end in -AUDOUT, not -AUDIOOUT.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In the Current Audio Input example the
+<constant>VIDIOC_G_AUDIO</constant> ioctl took the wrong
+argument.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The documentation of the &VIDIOC-QBUF; and
+&VIDIOC-DQBUF; ioctls did not mention the &v4l2-buffer;
+<structfield>memory</structfield> field. It was also missing from
+examples. Also on the <constant>VIDIOC_DQBUF</constant> page the &EIO;
+was not documented.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.14</title>
+      <orderedlist>
+	<listitem>
+	  <para>A new sliced VBI interface was added. It is documented
+in <xref linkend="sliced" /> and replaces the interface first
+proposed in V4L2 specification 0.8.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.15</title>
+      <orderedlist>
+	<listitem>
+	  <para>The &VIDIOC-LOG-STATUS; ioctl was added.</para>
+	</listitem>
+
+	<listitem>
+	  <para>New video standards
+<constant>V4L2_STD_NTSC_443</constant>,
+<constant>V4L2_STD_SECAM_LC</constant>,
+<constant>V4L2_STD_SECAM_DK</constant> (a set of SECAM D, K and K1),
+and <constant>V4L2_STD_ATSC</constant> (a set of
+<constant>V4L2_STD_ATSC_8_VSB</constant> and
+<constant>V4L2_STD_ATSC_16_VSB</constant>) were defined. Note the
+<constant>V4L2_STD_525_60</constant> set now includes
+<constant>V4L2_STD_NTSC_443</constant>. See also <xref
+	      linkend="v4l2-std-id" />.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The <constant>VIDIOC_G_COMP</constant> and
+<constant>VIDIOC_S_COMP</constant> ioctl were renamed to
+<constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> respectively. Their argument
+was replaced by a struct
+<structname>v4l2_mpeg_compression</structname> pointer. (The
+<constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> ioctls where removed in Linux
+2.6.25.)</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 spec erratum 2005-11-27</title>
+      <para>The capture example in <xref linkend="capture-example" />
+called the &VIDIOC-S-CROP; ioctl without checking if cropping is
+supported. In the video standard selection example in
+<xref linkend="standard" /> the &VIDIOC-S-STD; call used the wrong
+argument type.</para>
+    </section>
+
+    <section>
+      <title>V4L2 spec erratum 2006-01-10</title>
+      <orderedlist>
+	<listitem>
+	  <para>The <constant>V4L2_IN_ST_COLOR_KILL</constant> flag in
+&v4l2-input; not only indicates if the color killer is enabled, but
+also if it is active. (The color killer disables color decoding when
+it detects no color in the video signal to improve the image
+quality.)</para>
+	</listitem>
+
+	<listitem>
+	  <para>&VIDIOC-S-PARM; is a write-read ioctl, not write-only as
+stated on its reference page. The ioctl changed in 2003 as noted above.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 spec erratum 2006-02-03</title>
+      <orderedlist>
+	<listitem>
+	  <para>In &v4l2-captureparm; and &v4l2-outputparm; the
+<structfield>timeperframe</structfield> field gives the time in
+seconds, not microseconds.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 spec erratum 2006-02-04</title>
+      <orderedlist>
+	<listitem>
+	  <para>The <structfield>clips</structfield> field in
+&v4l2-window; must point to an array of &v4l2-clip;, not a linked
+list, because drivers ignore the struct
+<structname>v4l2_clip</structname>.<structfield>next</structfield>
+pointer.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.17</title>
+      <orderedlist>
+	<listitem>
+	  <para>New video standard macros were added:
+<constant>V4L2_STD_NTSC_M_KR</constant> (NTSC M South Korea), and the
+sets <constant>V4L2_STD_MN</constant>,
+<constant>V4L2_STD_B</constant>, <constant>V4L2_STD_GH</constant> and
+<constant>V4L2_STD_DK</constant>. The
+<constant>V4L2_STD_NTSC</constant> and
+<constant>V4L2_STD_SECAM</constant> sets now include
+<constant>V4L2_STD_NTSC_M_KR</constant> and
+<constant>V4L2_STD_SECAM_LC</constant> respectively.</para>
+	</listitem>
+
+	<listitem>
+	  <para>A new <constant>V4L2_TUNER_MODE_LANG1_LANG2</constant>
+was defined to record both languages of a bilingual program. The
+use of <constant>V4L2_TUNER_MODE_STEREO</constant> for this purpose
+is deprecated now. See the &VIDIOC-G-TUNER; section for
+details.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 spec erratum 2006-09-23 (Draft 0.15)</title>
+      <orderedlist>
+	<listitem>
+	  <para>In various places
+<constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> and
+<constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant> of the sliced VBI
+interface were not mentioned along with other buffer types.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In <xref linkend="vidioc-g-audio" /> it was clarified
+that the &v4l2-audio; <structfield>mode</structfield> field is a flags
+field.</para>
+	</listitem>
+
+	<listitem>
+	  <para><xref linkend="vidioc-querycap" /> did not mention the
+sliced VBI and radio capability flags.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In <xref linkend="vidioc-g-frequency" /> it was
+clarified that applications must initialize the tuner
+<structfield>type</structfield> field of &v4l2-frequency; before
+calling &VIDIOC-S-FREQUENCY;.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The <structfield>reserved</structfield> array
+in &v4l2-requestbuffers; has 2 elements, not 32.</para>
+	</listitem>
+
+	<listitem>
+	  <para>In <xref linkend="output" /> and <xref
+	      linkend="raw-vbi" /> the device file names
+<filename>/dev/vout</filename> which never caught on were replaced
+by <filename>/dev/video</filename>.</para>
+	</listitem>
+
+	<listitem>
+	  <para>With Linux 2.6.15 the possible range for VBI device minor
+numbers was extended from 224-239 to 224-255. Accordingly device file names
+<filename>/dev/vbi0</filename> to <filename>/dev/vbi31</filename> are
+possible now.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.18</title>
+      <orderedlist>
+	<listitem>
+	  <para>New ioctls &VIDIOC-G-EXT-CTRLS;, &VIDIOC-S-EXT-CTRLS;
+and &VIDIOC-TRY-EXT-CTRLS; were added, a flag to skip unsupported
+controls with &VIDIOC-QUERYCTRL;, new control types
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant> and
+<constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant> (<xref
+	      linkend="v4l2-ctrl-type" />), and new control flags
+<constant>V4L2_CTRL_FLAG_READ_ONLY</constant>,
+<constant>V4L2_CTRL_FLAG_UPDATE</constant>,
+<constant>V4L2_CTRL_FLAG_INACTIVE</constant> and
+<constant>V4L2_CTRL_FLAG_SLIDER</constant> (<xref
+	      linkend="control-flags" />). See <xref
+	      linkend="extended-controls" /> for details.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.19</title>
+      <orderedlist>
+	<listitem>
+	  <para>In &v4l2-sliced-vbi-cap; a buffer type field was added
+replacing a reserved field. Note on architectures where the size of
+enum types differs from int types the size of the structure changed.
+The &VIDIOC-G-SLICED-VBI-CAP; ioctl was redefined from being read-only
+to write-read. Applications must initialize the type field and clear
+the reserved fields now. These changes may <emphasis>break the
+compatibility</emphasis> with older drivers and applications.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The ioctls &VIDIOC-ENUM-FRAMESIZES; and
+&VIDIOC-ENUM-FRAMEINTERVALS; were added.</para>
+	</listitem>
+
+	<listitem>
+	  <para>A new pixel format <constant>V4L2_PIX_FMT_RGB444</constant> (<xref
+linkend="rgb-formats" />) was added.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 spec erratum 2006-10-12 (Draft 0.17)</title>
+      <orderedlist>
+	<listitem>
+	  <para><constant>V4L2_PIX_FMT_HM12</constant> (<xref
+linkend="reserved-formats" />) is a YUV 4:2:0, not 4:2:2 format.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.21</title>
+      <orderedlist>
+	<listitem>
+	  <para>The <filename>videodev2.h</filename> header file is
+now dual licensed under GNU General Public License version two or
+later, and under a 3-clause BSD-style license.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.22</title>
+      <orderedlist>
+	<listitem>
+	  <para>Two new field orders
+	  <constant>V4L2_FIELD_INTERLACED_TB</constant> and
+	  <constant>V4L2_FIELD_INTERLACED_BT</constant> were
+	  added. See <xref linkend="v4l2-field" /> for details.</para>
+	</listitem>
+
+	<listitem>
+	  <para>Three new clipping/blending methods with a global or
+straight or inverted local alpha value were added to the video overlay
+interface. See the description of the &VIDIOC-G-FBUF; and
+&VIDIOC-S-FBUF; ioctls for details.</para>
+	  <para>A new <structfield>global_alpha</structfield> field
+was added to <link
+linkend="v4l2-window"><structname>v4l2_window</structname></link>,
+extending the structure. This may <emphasis>break
+compatibility</emphasis> with applications using a struct
+<structname>v4l2_window</structname> directly. However the <link
+linkend="vidioc-g-fmt">VIDIOC_G/S/TRY_FMT</link> ioctls, which take a
+pointer to a <link linkend="v4l2-format">v4l2_format</link> parent
+structure with padding bytes at the end, are not affected.</para>
+	</listitem>
+
+	<listitem>
+	  <para>The format of the <structfield>chromakey</structfield>
+field in &v4l2-window; changed from "host order RGB32" to a pixel
+value in the same format as the framebuffer. This may <emphasis>break
+compatibility</emphasis> with existing applications. Drivers
+supporting the "host order RGB32" format are not known.</para>
+	</listitem>
+
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.24</title>
+      <orderedlist>
+	<listitem>
+	  <para>The pixel formats
+<constant>V4L2_PIX_FMT_PAL8</constant>,
+<constant>V4L2_PIX_FMT_YUV444</constant>,
+<constant>V4L2_PIX_FMT_YUV555</constant>,
+<constant>V4L2_PIX_FMT_YUV565</constant> and
+<constant>V4L2_PIX_FMT_YUV32</constant> were added.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.25</title>
+      <orderedlist>
+	<listitem>
+	  <para>The pixel formats <link linkend="V4L2-PIX-FMT-Y16">
+<constant>V4L2_PIX_FMT_Y16</constant></link> and <link
+linkend="V4L2-PIX-FMT-SBGGR16">
+<constant>V4L2_PIX_FMT_SBGGR16</constant></link> were added.</para>
+	</listitem>
+	<listitem>
+	  <para>New <link linkend="control">controls</link>
+<constant>V4L2_CID_POWER_LINE_FREQUENCY</constant>,
+<constant>V4L2_CID_HUE_AUTO</constant>,
+<constant>V4L2_CID_WHITE_BALANCE_TEMPERATURE</constant>,
+<constant>V4L2_CID_SHARPNESS</constant> and
+<constant>V4L2_CID_BACKLIGHT_COMPENSATION</constant> were added. The
+controls <constant>V4L2_CID_BLACK_LEVEL</constant>,
+<constant>V4L2_CID_WHITENESS</constant>,
+<constant>V4L2_CID_HCENTER</constant> and
+<constant>V4L2_CID_VCENTER</constant> were deprecated.
+</para>
+	</listitem>
+	<listitem>
+	  <para>A <link linkend="camera-controls">Camera controls
+class</link> was added, with the new controls
+<constant>V4L2_CID_EXPOSURE_AUTO</constant>,
+<constant>V4L2_CID_EXPOSURE_ABSOLUTE</constant>,
+<constant>V4L2_CID_EXPOSURE_AUTO_PRIORITY</constant>,
+<constant>V4L2_CID_PAN_RELATIVE</constant>,
+<constant>V4L2_CID_TILT_RELATIVE</constant>,
+<constant>V4L2_CID_PAN_RESET</constant>,
+<constant>V4L2_CID_TILT_RESET</constant>,
+<constant>V4L2_CID_PAN_ABSOLUTE</constant>,
+<constant>V4L2_CID_TILT_ABSOLUTE</constant>,
+<constant>V4L2_CID_FOCUS_ABSOLUTE</constant>,
+<constant>V4L2_CID_FOCUS_RELATIVE</constant> and
+<constant>V4L2_CID_FOCUS_AUTO</constant>.</para>
+	</listitem>
+	<listitem>
+	  <para>The <constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> ioctls, which were superseded
+by the <link linkend="extended-controls">extended controls</link>
+interface in Linux 2.6.18, where finally removed from the
+<filename>videodev2.h</filename> header file.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.26</title>
+      <orderedlist>
+	<listitem>
+	  <para>The pixel formats
+<constant>V4L2_PIX_FMT_Y16</constant> and
+<constant>V4L2_PIX_FMT_SBGGR16</constant> were added.</para>
+	</listitem>
+	<listitem>
+	  <para>Added user controls
+<constant>V4L2_CID_CHROMA_AGC</constant> and
+<constant>V4L2_CID_COLOR_KILLER</constant>.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.27</title>
+      <orderedlist>
+	<listitem>
+	  <para>The &VIDIOC-S-HW-FREQ-SEEK; ioctl and the
+<constant>V4L2_CAP_HW_FREQ_SEEK</constant> capability were added.</para>
+	</listitem>
+	<listitem>
+	  <para>The pixel formats
+<constant>V4L2_PIX_FMT_YVYU</constant>,
+<constant>V4L2_PIX_FMT_PCA501</constant>,
+<constant>V4L2_PIX_FMT_PCA505</constant>,
+<constant>V4L2_PIX_FMT_PCA508</constant>,
+<constant>V4L2_PIX_FMT_PCA561</constant>,
+<constant>V4L2_PIX_FMT_SGBRG8</constant>,
+<constant>V4L2_PIX_FMT_PAC207</constant> and
+<constant>V4L2_PIX_FMT_PJPG</constant> were added.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.28</title>
+      <orderedlist>
+	<listitem>
+	  <para>Added <constant>V4L2_MPEG_AUDIO_ENCODING_AAC</constant> and
+<constant>V4L2_MPEG_AUDIO_ENCODING_AC3</constant> MPEG audio encodings.</para>
+	</listitem>
+	<listitem>
+	  <para>Added <constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC</constant> MPEG
+video encoding.</para>
+	</listitem>
+	<listitem>
+	  <para>The pixel formats
+<constant>V4L2_PIX_FMT_SGRBG10</constant> and
+<constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant> were added.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+
+    <section>
+      <title>V4L2 in Linux 2.6.29</title>
+      <orderedlist>
+	<listitem>
+	  <para>The <constant>VIDIOC_G_CHIP_IDENT</constant> ioctl was renamed
+to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and &VIDIOC-DBG-G-CHIP-IDENT;
+was introduced in its place. The old struct <structname>v4l2_chip_ident</structname>
+was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structname>.</para>
+	</listitem>
+	<listitem>
+	  <para>The pixel formats
+<constant>V4L2_PIX_FMT_VYUY</constant>,
+<constant>V4L2_PIX_FMT_NV16</constant> and
+<constant>V4L2_PIX_FMT_NV61</constant> were added.</para>
+	</listitem>
+	<listitem>
+	  <para>Added camera controls
+<constant>V4L2_CID_ZOOM_ABSOLUTE</constant>,
+<constant>V4L2_CID_ZOOM_RELATIVE</constant>,
+<constant>V4L2_CID_ZOOM_CONTINUOUS</constant> and
+<constant>V4L2_CID_PRIVACY</constant>.</para>
+	</listitem>
+      </orderedlist>
+    </section>
+    <section>
+      <title>V4L2 in Linux 2.6.30</title>
+      <orderedlist>
+	<listitem>
+	  <para>New control flag <constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant> was added.</para>
+	</listitem>
+	<listitem>
+	  <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para>
+	</listitem>
+       </orderedlist>
+     </section>
+    <section>
+      <title>V4L2 in Linux 2.6.32</title>
+      <orderedlist>
+	<listitem>
+	  <para>In order to be easier to compare a V4L2 API and a kernel
+version, now V4L2 API is numbered using the Linux Kernel version numeration.</para>
+	</listitem>
+	<listitem>
+	  <para>Finalized the RDS capture API. See <xref linkend="rds" /> for
+more information.</para>
+	</listitem>
+	<listitem>
+	  <para>Added new capabilities for modulators and RDS encoders.</para>
+	</listitem>
+	<listitem>
+	  <para>Add description for libv4l API.</para>
+	</listitem>
+	<listitem>
+	  <para>Added support for string controls via new type <constant>V4L2_CTRL_TYPE_STRING</constant>.</para>
+	</listitem>
+	<listitem>
+	  <para>Added <constant>V4L2_CID_BAND_STOP_FILTER</constant> documentation.</para>
+	</listitem>
+	<listitem>
+	  <para>Added FM Modulator (FM TX) Extended Control Class: <constant>V4L2_CTRL_CLASS_FM_TX</constant> and their Control IDs.</para>
+	</listitem>
+	<listitem>
+	  <para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para>
+	</listitem>
+       </orderedlist>
+     </section>
+   </section>
+
+   <section id="other">
+     <title>Relation of V4L2 to other Linux multimedia APIs</title>
+
+    <section id="xvideo">
+      <title>X Video Extension</title>
+
+      <para>The X Video Extension (abbreviated XVideo or just Xv) is
+an extension of the X Window system, implemented for example by the
+XFree86 project. Its scope is similar to V4L2, an API to video capture
+and output devices for X clients. Xv allows applications to display
+live video in a window, send window contents to a TV output, and
+capture or output still images in XPixmaps<footnote>
+	  <para>This is not implemented in XFree86.</para>
+	</footnote>. With their implementation XFree86 makes the
+extension available across many operating systems and
+architectures.</para>
+
+      <para>Because the driver is embedded into the X server Xv has a
+number of advantages over the V4L2 <link linkend="overlay">video
+overlay interface</link>. The driver can easily determine the overlay
+target, &ie; visible graphics memory or off-screen buffers for a
+destructive overlay. It can program the RAMDAC for a non-destructive
+overlay, scaling or color-keying, or the clipping functions of the
+video capture hardware, always in sync with drawing operations or
+windows moving or changing their stacking order.</para>
+
+      <para>To combine the advantages of Xv and V4L a special Xv
+driver exists in XFree86 and XOrg, just programming any overlay capable
+Video4Linux device it finds. To enable it
+<filename>/etc/X11/XF86Config</filename> must contain these lines:</para>
+      <para><screen>
+Section "Module"
+    Load "v4l"
+EndSection</screen></para>
+
+      <para>As of XFree86 4.2 this driver still supports only V4L
+ioctls, however it should work just fine with all V4L2 devices through
+the V4L2 backward-compatibility layer. Since V4L2 permits multiple
+opens it is possible (if supported by the V4L2 driver) to capture
+video while an X client requested video overlay. Restrictions of
+simultaneous capturing and overlay are discussed in <xref
+	  linkend="overlay" /> apply.</para>
+
+      <para>Only marginally related to V4L2, XFree86 extended Xv to
+support hardware YUV to RGB conversion and scaling for faster video
+playback, and added an interface to MPEG-2 decoding hardware. This API
+is useful to display images captured with V4L2 devices.</para>
+    </section>
+
+    <section>
+      <title>Digital Video</title>
+
+      <para>V4L2 does not support digital terrestrial, cable or
+satellite broadcast. A separate project aiming at digital receivers
+exists. You can find its homepage at <ulink
+url="http://linuxtv.org">http://linuxtv.org</ulink>. The Linux DVB API
+has no connection to the V4L2 API except that drivers for hybrid
+hardware may support both.</para>
+    </section>
+
+    <section>
+      <title>Audio Interfaces</title>
+
+      <para>[to do - OSS/ALSA]</para>
+    </section>
+  </section>
+
+  <section id="experimental">
+    <title>Experimental API Elements</title>
+
+    <para>The following V4L2 API elements are currently experimental
+and may change in the future.</para>
+
+    <itemizedlist>
+      <listitem>
+	<para>Video Output Overlay (OSD) Interface, <xref
+	    linkend="osd" />.</para>
+      </listitem>
+	<listitem>
+	<para><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>,
+	&v4l2-buf-type;, <xref linkend="v4l2-buf-type" />.</para>
+      </listitem>
+      <listitem>
+	<para><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant>,
+&VIDIOC-QUERYCAP; ioctl, <xref linkend="device-capabilities" />.</para>
+      </listitem>
+      <listitem>
+	<para>&VIDIOC-ENUM-FRAMESIZES; and
+&VIDIOC-ENUM-FRAMEINTERVALS; ioctls.</para>
+      </listitem>
+      <listitem>
+	<para>&VIDIOC-G-ENC-INDEX; ioctl.</para>
+      </listitem>
+      <listitem>
+	<para>&VIDIOC-ENCODER-CMD; and &VIDIOC-TRY-ENCODER-CMD;
+ioctls.</para>
+      </listitem>
+      <listitem>
+	<para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER;
+ioctls.</para>
+      </listitem>
+      <listitem>
+	<para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
+      </listitem>
+    </itemizedlist>
+  </section>
+
+  <section id="obsolete">
+    <title>Obsolete API Elements</title>
+
+    <para>The following V4L2 API elements were superseded by new
+interfaces and should not be implemented in new drivers.</para>
+
+    <itemizedlist>
+      <listitem>
+	<para><constant>VIDIOC_G_MPEGCOMP</constant> and
+<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls,
+<xref linkend="extended-controls" />.</para>
+      </listitem>
+    </itemizedlist>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/controls.xml b/Documentation/DocBook/v4l/controls.xml
new file mode 100644
index 0000000..f492acc
--- /dev/null
+++ b/Documentation/DocBook/v4l/controls.xml
@@ -0,0 +1,2049 @@
+  <section id="control">
+    <title>User Controls</title>
+
+    <para>Devices typically have a number of user-settable controls
+such as brightness, saturation and so on, which would be presented to
+the user on a graphical user interface. But, different devices
+will have different controls available, and furthermore, the range of
+possible values, and the default value will vary from device to
+device. The control ioctls provide the information and a mechanism to
+create a nice user interface for these controls that will work
+correctly with any device.</para>
+
+    <para>All controls are accessed using an ID value. V4L2 defines
+several IDs for specific purposes. Drivers can also implement their
+own custom controls using <constant>V4L2_CID_PRIVATE_BASE</constant>
+and higher values. The pre-defined control IDs have the prefix
+<constant>V4L2_CID_</constant>, and are listed in <xref
+linkend="control-id" />. The ID is used when querying the attributes of
+a control, and when getting or setting the current value.</para>
+
+    <para>Generally applications should present controls to the user
+without assumptions about their purpose. Each control comes with a
+name string the user is supposed to understand. When the purpose is
+non-intuitive the driver writer should provide a user manual, a user
+interface plug-in or a driver specific panel application. Predefined
+IDs were introduced to change a few controls programmatically, for
+example to mute a device during a channel switch.</para>
+
+    <para>Drivers may enumerate different controls after switching
+the current video input or output, tuner or modulator, or audio input
+or output. Different in the sense of other bounds, another default and
+current value, step size or other menu items. A control with a certain
+<emphasis>custom</emphasis> ID can also change name and
+type.<footnote>
+	<para>It will be more convenient for applications if drivers
+make use of the <constant>V4L2_CTRL_FLAG_DISABLED</constant> flag, but
+that was never required.</para>
+      </footnote> Control values are stored globally, they do not
+change when switching except to stay within the reported bounds. They
+also do not change &eg; when the device is opened or closed, when the
+tuner radio frequency is changed or generally never without
+application request. Since V4L2 specifies no event mechanism, panel
+applications intended to cooperate with other panel applications (be
+they built into a larger application, as a TV viewer) may need to
+regularly poll control values to update their user
+interface.<footnote>
+	<para>Applications could call an ioctl to request events.
+After another process called &VIDIOC-S-CTRL; or another ioctl changing
+shared properties the &func-select; function would indicate
+readability until any ioctl (querying the properties) is
+called.</para>
+      </footnote></para>
+
+    <table pgwide="1" frame="none" id="control-id">
+      <title>Control IDs</title>
+      <tgroup cols="3">
+	&cs-def;
+	<thead>
+	  <row>
+	    <entry>ID</entry>
+	    <entry>Type</entry>
+	    <entry>Description</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CID_BASE</constant></entry>
+	    <entry></entry>
+	    <entry>First predefined ID, equal to
+<constant>V4L2_CID_BRIGHTNESS</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_USER_BASE</constant></entry>
+	    <entry></entry>
+	    <entry>Synonym of <constant>V4L2_CID_BASE</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_BRIGHTNESS</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Picture brightness, or more precisely, the black
+level.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_CONTRAST</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Picture contrast or luma gain.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_SATURATION</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Picture color saturation or chroma gain.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_HUE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Hue or color balance.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUDIO_VOLUME</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Overall audio volume. Note some drivers also
+provide an OSS or ALSA mixer interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUDIO_BALANCE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Audio stereo balance. Minimum corresponds to all
+the way left, maximum to right.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUDIO_BASS</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Audio bass adjustment.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUDIO_TREBLE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Audio treble adjustment.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUDIO_MUTE</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Mute audio, &ie; set the volume to zero, however
+without affecting <constant>V4L2_CID_AUDIO_VOLUME</constant>. Like
+ALSA drivers, V4L2 drivers must mute at load time to avoid excessive
+noise. Actually the entire device should be reset to a low power
+consumption state.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUDIO_LOUDNESS</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Loudness mode (bass boost).</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_BLACK_LEVEL</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Another name for brightness (not a synonym of
+<constant>V4L2_CID_BRIGHTNESS</constant>). This control is deprecated
+and should not be used in new drivers and applications.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUTO_WHITE_BALANCE</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Automatic white balance (cameras).</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_DO_WHITE_BALANCE</constant></entry>
+	    <entry>button</entry>
+	    <entry>This is an action control. When set (the value is
+ignored), the device will do a white balance and then hold the current
+setting. Contrast this with the boolean
+<constant>V4L2_CID_AUTO_WHITE_BALANCE</constant>, which, when
+activated, keeps adjusting the white balance.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_RED_BALANCE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Red chroma balance.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_BLUE_BALANCE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Blue chroma balance.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_GAMMA</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Gamma adjust.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_WHITENESS</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Whiteness for grey-scale devices. This is a synonym
+for <constant>V4L2_CID_GAMMA</constant>. This control is deprecated
+and should not be used in new drivers and applications.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_EXPOSURE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Exposure (cameras). [Unit?]</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_AUTOGAIN</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Automatic gain/exposure control.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_GAIN</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Gain control.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_HFLIP</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Mirror the picture horizontally.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_VFLIP</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Mirror the picture vertically.</entry>
+	  </row>
+	<row>
+	  <entry><constant>V4L2_CID_HCENTER_DEPRECATED</constant> (formerly <constant>V4L2_CID_HCENTER</constant>)</entry>
+	    <entry>integer</entry>
+	    <entry>Horizontal image centering. This control is
+deprecated. New drivers and applications should use the <link
+linkend="camera-controls">Camera class controls</link>
+<constant>V4L2_CID_PAN_ABSOLUTE</constant>,
+<constant>V4L2_CID_PAN_RELATIVE</constant> and
+<constant>V4L2_CID_PAN_RESET</constant> instead.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_VCENTER_DEPRECATED</constant>
+	    (formerly <constant>V4L2_CID_VCENTER</constant>)</entry>
+	    <entry>integer</entry>
+	    <entry>Vertical image centering. Centering is intended to
+<emphasis>physically</emphasis> adjust cameras. For image cropping see
+<xref linkend="crop" />, for clipping <xref linkend="overlay" />. This
+control is deprecated. New drivers and applications should use the
+<link linkend="camera-controls">Camera class controls</link>
+<constant>V4L2_CID_TILT_ABSOLUTE</constant>,
+<constant>V4L2_CID_TILT_RELATIVE</constant> and
+<constant>V4L2_CID_TILT_RESET</constant> instead.</entry>
+	  </row>
+	  <row id="v4l2-power-line-frequency">
+	    <entry><constant>V4L2_CID_POWER_LINE_FREQUENCY</constant></entry>
+	    <entry>enum</entry>
+	    <entry>Enables a power line frequency filter to avoid
+flicker. Possible values for <constant>enum v4l2_power_line_frequency</constant> are:
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_DISABLED</constant> (0),
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1) and
+<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2).</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_HUE_AUTO</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Enables automatic hue control by the device. The
+effect of setting <constant>V4L2_CID_HUE</constant> while automatic
+hue control is enabled is undefined, drivers should ignore such
+request.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_WHITE_BALANCE_TEMPERATURE</constant></entry>
+	    <entry>integer</entry>
+	    <entry>This control specifies the white balance settings
+as a color temperature in Kelvin. A driver should have a minimum of
+2800 (incandescent) to 6500 (daylight). For more information about
+color temperature see <ulink
+url="http://en.wikipedia.org/wiki/Color_temperature">Wikipedia</ulink>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_SHARPNESS</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Adjusts the sharpness filters in a camera. The
+minimum value disables the filters, higher values give a sharper
+picture.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_BACKLIGHT_COMPENSATION</constant></entry>
+	    <entry>integer</entry>
+	    <entry>Adjusts the backlight compensation in a camera. The
+minimum value disables backlight compensation.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_CHROMA_AGC</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Chroma automatic gain control.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_COLOR_KILLER</constant></entry>
+	    <entry>boolean</entry>
+	    <entry>Enable the color killer (&ie; force a black &amp; white image in case of a weak video signal).</entry>
+	  </row>
+	  <row id="v4l2-colorfx">
+	    <entry><constant>V4L2_CID_COLORFX</constant></entry>
+	    <entry>enum</entry>
+	    <entry>Selects a color effect. Possible values for
+<constant>enum v4l2_colorfx</constant> are:
+<constant>V4L2_COLORFX_NONE</constant> (0),
+<constant>V4L2_COLORFX_BW</constant> (1) and
+<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_LASTP1</constant></entry>
+	    <entry></entry>
+	    <entry>End of the predefined control IDs (currently
+<constant>V4L2_CID_COLORFX</constant> + 1).</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry>
+	    <entry></entry>
+	    <entry>ID of the first custom (driver specific) control.
+Applications depending on particular custom controls should check the
+driver name and version, see <xref linkend="querycap" />.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <para>Applications can enumerate the available controls with the
+&VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls, get and set a
+control value with the &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls.
+Drivers must implement <constant>VIDIOC_QUERYCTRL</constant>,
+<constant>VIDIOC_G_CTRL</constant> and
+<constant>VIDIOC_S_CTRL</constant> when the device has one or more
+controls, <constant>VIDIOC_QUERYMENU</constant> when it has one or
+more menu type controls.</para>
+
+    <example>
+      <title>Enumerating all controls</title>
+
+      <programlisting>
+&v4l2-queryctrl; queryctrl;
+&v4l2-querymenu; querymenu;
+
+static void
+enumerate_menu (void)
+{
+	printf ("  Menu items:\n");
+
+	memset (&amp;querymenu, 0, sizeof (querymenu));
+	querymenu.id = queryctrl.id;
+
+	for (querymenu.index = queryctrl.minimum;
+	     querymenu.index &lt;= queryctrl.maximum;
+	      querymenu.index++) {
+		if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &amp;querymenu)) {
+			printf ("  %s\n", querymenu.name);
+		} else {
+			perror ("VIDIOC_QUERYMENU");
+			exit (EXIT_FAILURE);
+		}
+	}
+}
+
+memset (&amp;queryctrl, 0, sizeof (queryctrl));
+
+for (queryctrl.id = V4L2_CID_BASE;
+     queryctrl.id &lt; V4L2_CID_LASTP1;
+     queryctrl.id++) {
+	if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
+		if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
+			continue;
+
+		printf ("Control %s\n", queryctrl.name);
+
+		if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+			enumerate_menu ();
+	} else {
+		if (errno == EINVAL)
+			continue;
+
+		perror ("VIDIOC_QUERYCTRL");
+		exit (EXIT_FAILURE);
+	}
+}
+
+for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
+     queryctrl.id++) {
+	if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
+		if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
+			continue;
+
+		printf ("Control %s\n", queryctrl.name);
+
+		if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
+			enumerate_menu ();
+	} else {
+		if (errno == EINVAL)
+			break;
+
+		perror ("VIDIOC_QUERYCTRL");
+		exit (EXIT_FAILURE);
+	}
+}
+</programlisting>
+    </example>
+
+    <example>
+      <title>Changing controls</title>
+
+      <programlisting>
+&v4l2-queryctrl; queryctrl;
+&v4l2-control; control;
+
+memset (&amp;queryctrl, 0, sizeof (queryctrl));
+queryctrl.id = V4L2_CID_BRIGHTNESS;
+
+if (-1 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
+	if (errno != EINVAL) {
+		perror ("VIDIOC_QUERYCTRL");
+		exit (EXIT_FAILURE);
+	} else {
+		printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+	}
+} else if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED) {
+	printf ("V4L2_CID_BRIGHTNESS is not supported\n");
+} else {
+	memset (&amp;control, 0, sizeof (control));
+	control.id = V4L2_CID_BRIGHTNESS;
+	control.value = queryctrl.default_value;
+
+	if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)) {
+		perror ("VIDIOC_S_CTRL");
+		exit (EXIT_FAILURE);
+	}
+}
+
+memset (&amp;control, 0, sizeof (control));
+control.id = V4L2_CID_CONTRAST;
+
+if (0 == ioctl (fd, &VIDIOC-G-CTRL;, &amp;control)) {
+	control.value += 1;
+
+	/* The driver may clamp the value or return ERANGE, ignored here */
+
+	if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)
+	    &amp;&amp; errno != ERANGE) {
+		perror ("VIDIOC_S_CTRL");
+		exit (EXIT_FAILURE);
+	}
+/* Ignore if V4L2_CID_CONTRAST is unsupported */
+} else if (errno != EINVAL) {
+	perror ("VIDIOC_G_CTRL");
+	exit (EXIT_FAILURE);
+}
+
+control.id = V4L2_CID_AUDIO_MUTE;
+control.value = TRUE; /* silence */
+
+/* Errors ignored */
+ioctl (fd, VIDIOC_S_CTRL, &amp;control);
+</programlisting>
+    </example>
+  </section>
+
+  <section id="extended-controls">
+    <title>Extended Controls</title>
+
+    <section>
+      <title>Introduction</title>
+
+      <para>The control mechanism as originally designed was meant
+to be used for user settings (brightness, saturation, etc). However,
+it turned out to be a very useful model for implementing more
+complicated driver APIs where each driver implements only a subset of
+a larger API.</para>
+
+      <para>The MPEG encoding API was the driving force behind
+designing and implementing this extended control mechanism: the MPEG
+standard is quite large and the currently supported hardware MPEG
+encoders each only implement a subset of this standard. Further more,
+many parameters relating to how the video is encoded into an MPEG
+stream are specific to the MPEG encoding chip since the MPEG standard
+only defines the format of the resulting MPEG stream, not how the
+video is actually encoded into that format.</para>
+
+      <para>Unfortunately, the original control API lacked some
+features needed for these new uses and so it was extended into the
+(not terribly originally named) extended control API.</para>
+
+      <para>Even though the MPEG encoding API was the first effort
+to use the Extended Control API, nowadays there are also other classes
+of Extended Controls, such as Camera Controls and FM Transmitter Controls.
+The Extended Controls API as well as all Extended Controls classes are
+described in the following text.</para>
+    </section>
+
+    <section>
+      <title>The Extended Control API</title>
+
+      <para>Three new ioctls are available: &VIDIOC-G-EXT-CTRLS;,
+&VIDIOC-S-EXT-CTRLS; and &VIDIOC-TRY-EXT-CTRLS;. These ioctls act on
+arrays of controls (as opposed to the &VIDIOC-G-CTRL; and
+&VIDIOC-S-CTRL; ioctls that act on a single control). This is needed
+since it is often required to atomically change several controls at
+once.</para>
+
+      <para>Each of the new ioctls expects a pointer to a
+&v4l2-ext-controls;. This structure contains a pointer to the control
+array, a count of the number of controls in that array and a control
+class. Control classes are used to group similar controls into a
+single class. For example, control class
+<constant>V4L2_CTRL_CLASS_USER</constant> contains all user controls
+(&ie; all controls that can also be set using the old
+<constant>VIDIOC_S_CTRL</constant> ioctl). Control class
+<constant>V4L2_CTRL_CLASS_MPEG</constant> contains all controls
+relating to MPEG encoding, etc.</para>
+
+      <para>All controls in the control array must belong to the
+specified control class. An error is returned if this is not the
+case.</para>
+
+      <para>It is also possible to use an empty control array (count
+== 0) to check whether the specified control class is
+supported.</para>
+
+      <para>The control array is a &v4l2-ext-control; array. The
+<structname>v4l2_ext_control</structname> structure is very similar to
+&v4l2-control;, except for the fact that it also allows for 64-bit
+values and pointers to be passed.</para>
+
+      <para>It is important to realize that due to the flexibility of
+controls it is necessary to check whether the control you want to set
+actually is supported in the driver and what the valid range of values
+is. So use the &VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls to
+check this. Also note that it is possible that some of the menu
+indices in a control of type <constant>V4L2_CTRL_TYPE_MENU</constant>
+may not be supported (<constant>VIDIOC_QUERYMENU</constant> will
+return an error). A good example is the list of supported MPEG audio
+bitrates. Some drivers only support one or two bitrates, others
+support a wider range.</para>
+    </section>
+
+    <section>
+      <title>Enumerating Extended Controls</title>
+
+      <para>The recommended way to enumerate over the extended
+controls is by using &VIDIOC-QUERYCTRL; in combination with the
+<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> flag:</para>
+
+      <informalexample>
+	<programlisting>
+&v4l2-queryctrl; qctrl;
+
+qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
+	/* ... */
+	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+}
+</programlisting>
+      </informalexample>
+
+      <para>The initial control ID is set to 0 ORed with the
+<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> flag. The
+<constant>VIDIOC_QUERYCTRL</constant> ioctl will return the first
+control with a higher ID than the specified one. When no such controls
+are found an error is returned.</para>
+
+      <para>If you want to get all controls within a specific control
+class, then you can set the initial
+<structfield>qctrl.id</structfield> value to the control class and add
+an extra check to break out of the loop when a control of another
+control class is found:</para>
+
+      <informalexample>
+	<programlisting>
+qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
+while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
+	if (V4L2_CTRL_ID2CLASS (qctrl.id) != V4L2_CTRL_CLASS_MPEG)
+		break;
+		/* ... */
+		qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+	}
+</programlisting>
+      </informalexample>
+
+      <para>The 32-bit <structfield>qctrl.id</structfield> value is
+subdivided into three bit ranges: the top 4 bits are reserved for
+flags (&eg; <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>) and are not
+actually part of the ID. The remaining 28 bits form the control ID, of
+which the most significant 12 bits define the control class and the
+least significant 16 bits identify the control within the control
+class. It is guaranteed that these last 16 bits are always non-zero
+for controls. The range of 0x1000 and up are reserved for
+driver-specific controls. The macro
+<constant>V4L2_CTRL_ID2CLASS(id)</constant> returns the control class
+ID based on a control ID.</para>
+
+      <para>If the driver does not support extended controls, then
+<constant>VIDIOC_QUERYCTRL</constant> will fail when used in
+combination with <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>. In
+that case the old method of enumerating control should be used (see
+1.8). But if it is supported, then it is guaranteed to enumerate over
+all controls, including driver-private controls.</para>
+    </section>
+
+    <section>
+      <title>Creating Control Panels</title>
+
+      <para>It is possible to create control panels for a graphical
+user interface where the user can select the various controls.
+Basically you will have to iterate over all controls using the method
+described above. Each control class starts with a control of type
+<constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant>.
+<constant>VIDIOC_QUERYCTRL</constant> will return the name of this
+control class which can be used as the title of a tab page within a
+control panel.</para>
+
+      <para>The flags field of &v4l2-queryctrl; also contains hints on
+the behavior of the control. See the &VIDIOC-QUERYCTRL; documentation
+for more details.</para>
+    </section>
+
+    <section id="mpeg-controls">
+      <title>MPEG Control Reference</title>
+
+      <para>Below all controls within the MPEG control class are
+described. First the generic controls, then controls specific for
+certain hardware.</para>
+
+      <section>
+	<title>Generic MPEG Controls</title>
+
+	<table pgwide="1" frame="none" id="mpeg-control-id">
+	  <title>MPEG Control IDs</title>
+	  <tgroup cols="4">
+	    <colspec colname="c1" colwidth="1*" />
+	    <colspec colname="c2" colwidth="6*" />
+	    <colspec colname="c3" colwidth="2*" />
+	    <colspec colname="c4" colwidth="6*" />
+	    <spanspec namest="c1" nameend="c2" spanname="id" />
+	    <spanspec namest="c2" nameend="c4" spanname="descr" />
+	    <thead>
+	      <row>
+		<entry spanname="id" align="left">ID</entry>
+		<entry align="left">Type</entry>
+	      </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CLASS</constant>&nbsp;</entry>
+		<entry>class</entry>
+	      </row><row><entry spanname="descr">The MPEG class
+descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
+description of this control class. This description can be used as the
+caption of a Tab page in a GUI, for example.</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-stream-type">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_TYPE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_stream_type</entry>
+	      </row><row><entry spanname="descr">The MPEG-1, -2 or -4
+output stream type. One cannot assume anything here. Each hardware
+MPEG encoder tends to support different subsets of the available MPEG
+stream types. The currently defined stream types are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_PS</constant>&nbsp;</entry>
+		      <entry>MPEG-2 program stream</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_TS</constant>&nbsp;</entry>
+		      <entry>MPEG-2 transport stream</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG1_SS</constant>&nbsp;</entry>
+		      <entry>MPEG-1 system stream</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_DVD</constant>&nbsp;</entry>
+		      <entry>MPEG-2 DVD-compatible stream</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG1_VCD</constant>&nbsp;</entry>
+		      <entry>MPEG-1 VCD-compatible stream</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD</constant>&nbsp;</entry>
+		      <entry>MPEG-2 SVCD-compatible stream</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_PMT</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Program Map Table
+Packet ID for the MPEG transport stream (default 16)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_AUDIO</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Audio Packet ID for
+the MPEG transport stream (default 256)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_VIDEO</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Video Packet ID for
+the MPEG transport stream (default 260)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_PCR</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Packet ID for the
+MPEG transport stream carrying PCR fields (default 259)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PES_ID_AUDIO</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Audio ID for MPEG
+PES</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PES_ID_VIDEO</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Video ID for MPEG
+PES</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-stream-vbi-fmt">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_VBI_FMT</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_stream_vbi_fmt</entry>
+	      </row><row><entry spanname="descr">Some cards can embed
+VBI data (&eg; Closed Caption, Teletext) into the MPEG stream. This
+control selects whether VBI data should be embedded, and if so, what
+embedding method should be used. The list of possible VBI formats
+depends on the driver. The currently defined VBI format types
+are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_VBI_FMT_NONE</constant>&nbsp;</entry>
+		      <entry>No VBI in the MPEG stream</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant>&nbsp;</entry>
+		      <entry>VBI in private packets, IVTV format (documented
+in the kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.vbi</filename>)</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-sampling-freq">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_sampling_freq</entry>
+	      </row><row><entry spanname="descr">MPEG Audio sampling
+frequency. Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100</constant>&nbsp;</entry>
+		      <entry>44.1 kHz</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000</constant>&nbsp;</entry>
+		      <entry>48 kHz</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000</constant>&nbsp;</entry>
+		      <entry>32 kHz</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-encoding">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_ENCODING</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_encoding</entry>
+	      </row><row><entry spanname="descr">MPEG Audio encoding.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_1</constant>&nbsp;</entry>
+		      <entry>MPEG-1/2 Layer I encoding</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_2</constant>&nbsp;</entry>
+		      <entry>MPEG-1/2 Layer II encoding</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_3</constant>&nbsp;</entry>
+		      <entry>MPEG-1/2 Layer III encoding</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_ENCODING_AAC</constant>&nbsp;</entry>
+		      <entry>MPEG-2/4 AAC (Advanced Audio Coding)</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_ENCODING_AC3</constant>&nbsp;</entry>
+		      <entry>AC-3 aka ATSC A/52 encoding</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-l1-bitrate">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L1_BITRATE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_l1_bitrate</entry>
+	      </row><row><entry spanname="descr">MPEG-1/2 Layer I bitrate.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_32K</constant>&nbsp;</entry>
+		      <entry>32 kbit/s</entry></row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_64K</constant>&nbsp;</entry>
+		      <entry>64 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_96K</constant>&nbsp;</entry>
+		      <entry>96 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_128K</constant>&nbsp;</entry>
+		      <entry>128 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_160K</constant>&nbsp;</entry>
+		      <entry>160 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_192K</constant>&nbsp;</entry>
+		      <entry>192 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_224K</constant>&nbsp;</entry>
+		      <entry>224 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_256K</constant>&nbsp;</entry>
+		      <entry>256 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_288K</constant>&nbsp;</entry>
+		      <entry>288 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_320K</constant>&nbsp;</entry>
+		      <entry>320 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_352K</constant>&nbsp;</entry>
+		      <entry>352 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_384K</constant>&nbsp;</entry>
+		      <entry>384 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_416K</constant>&nbsp;</entry>
+		      <entry>416 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_448K</constant>&nbsp;</entry>
+		      <entry>448 kbit/s</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-l2-bitrate">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L2_BITRATE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_l2_bitrate</entry>
+	      </row><row><entry spanname="descr">MPEG-1/2 Layer II bitrate.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_32K</constant>&nbsp;</entry>
+		      <entry>32 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_48K</constant>&nbsp;</entry>
+		      <entry>48 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_56K</constant>&nbsp;</entry>
+		      <entry>56 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_64K</constant>&nbsp;</entry>
+		      <entry>64 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_80K</constant>&nbsp;</entry>
+		      <entry>80 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_96K</constant>&nbsp;</entry>
+		      <entry>96 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_112K</constant>&nbsp;</entry>
+		      <entry>112 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_128K</constant>&nbsp;</entry>
+		      <entry>128 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_160K</constant>&nbsp;</entry>
+		      <entry>160 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_192K</constant>&nbsp;</entry>
+		      <entry>192 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_224K</constant>&nbsp;</entry>
+		      <entry>224 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_256K</constant>&nbsp;</entry>
+		      <entry>256 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_320K</constant>&nbsp;</entry>
+		      <entry>320 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_384K</constant>&nbsp;</entry>
+		      <entry>384 kbit/s</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-l3-bitrate">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L3_BITRATE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_l3_bitrate</entry>
+	      </row><row><entry spanname="descr">MPEG-1/2 Layer III bitrate.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_32K</constant>&nbsp;</entry>
+		      <entry>32 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_40K</constant>&nbsp;</entry>
+		      <entry>40 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_48K</constant>&nbsp;</entry>
+		      <entry>48 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_56K</constant>&nbsp;</entry>
+		      <entry>56 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_64K</constant>&nbsp;</entry>
+		      <entry>64 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_80K</constant>&nbsp;</entry>
+		      <entry>80 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_96K</constant>&nbsp;</entry>
+		      <entry>96 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_112K</constant>&nbsp;</entry>
+		      <entry>112 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_128K</constant>&nbsp;</entry>
+		      <entry>128 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_160K</constant>&nbsp;</entry>
+		      <entry>160 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_192K</constant>&nbsp;</entry>
+		      <entry>192 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_224K</constant>&nbsp;</entry>
+		      <entry>224 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_256K</constant>&nbsp;</entry>
+		      <entry>256 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_320K</constant>&nbsp;</entry>
+		      <entry>320 kbit/s</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_AAC_BITRATE</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">AAC bitrate in bits per second.</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-ac3-bitrate">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_AC3_BITRATE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_ac3_bitrate</entry>
+	      </row><row><entry spanname="descr">AC-3 bitrate.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_32K</constant>&nbsp;</entry>
+		      <entry>32 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_40K</constant>&nbsp;</entry>
+		      <entry>40 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_48K</constant>&nbsp;</entry>
+		      <entry>48 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_56K</constant>&nbsp;</entry>
+		      <entry>56 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_64K</constant>&nbsp;</entry>
+		      <entry>64 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_80K</constant>&nbsp;</entry>
+		      <entry>80 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_96K</constant>&nbsp;</entry>
+		      <entry>96 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_112K</constant>&nbsp;</entry>
+		      <entry>112 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_128K</constant>&nbsp;</entry>
+		      <entry>128 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_160K</constant>&nbsp;</entry>
+		      <entry>160 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_192K</constant>&nbsp;</entry>
+		      <entry>192 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_224K</constant>&nbsp;</entry>
+		      <entry>224 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_256K</constant>&nbsp;</entry>
+		      <entry>256 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_320K</constant>&nbsp;</entry>
+		      <entry>320 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_384K</constant>&nbsp;</entry>
+		      <entry>384 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_448K</constant>&nbsp;</entry>
+		      <entry>448 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_512K</constant>&nbsp;</entry>
+		      <entry>512 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_576K</constant>&nbsp;</entry>
+		      <entry>576 kbit/s</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_640K</constant>&nbsp;</entry>
+		      <entry>640 kbit/s</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-mode">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MODE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_mode</entry>
+	      </row><row><entry spanname="descr">MPEG Audio mode.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_STEREO</constant>&nbsp;</entry>
+		      <entry>Stereo</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_JOINT_STEREO</constant>&nbsp;</entry>
+		      <entry>Joint Stereo</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_DUAL</constant>&nbsp;</entry>
+		      <entry>Bilingual</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_MONO</constant>&nbsp;</entry>
+		      <entry>Mono</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-mode-extension">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MODE_EXTENSION</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_mode_extension</entry>
+	      </row><row><entry spanname="descr">Joint Stereo
+audio mode extension. In Layer I and II they indicate which subbands
+are in intensity stereo. All other subbands are coded in stereo. Layer
+III is not (yet) supported. Possible values
+are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4</constant>&nbsp;</entry>
+		      <entry>Subbands 4-31 in intensity stereo</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8</constant>&nbsp;</entry>
+		      <entry>Subbands 8-31 in intensity stereo</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12</constant>&nbsp;</entry>
+		      <entry>Subbands 12-31 in intensity stereo</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16</constant>&nbsp;</entry>
+		      <entry>Subbands 16-31 in intensity stereo</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-emphasis">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_EMPHASIS</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_emphasis</entry>
+	      </row><row><entry spanname="descr">Audio Emphasis.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_NONE</constant>&nbsp;</entry>
+		      <entry>None</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS</constant>&nbsp;</entry>
+		      <entry>50/15 microsecond emphasis</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17</constant>&nbsp;</entry>
+		      <entry>CCITT J.17</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-audio-crc">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_CRC</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_audio_crc</entry>
+	      </row><row><entry spanname="descr">CRC method. Possible
+values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_CRC_NONE</constant>&nbsp;</entry>
+		      <entry>None</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_AUDIO_CRC_CRC16</constant>&nbsp;</entry>
+		      <entry>16 bit parity check</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MUTE</constant>&nbsp;</entry>
+		<entry>boolean</entry>
+	      </row><row><entry spanname="descr">Mutes the audio when
+capturing. This is not done by muting audio hardware, which can still
+produce a slight hiss, but in the encoder itself, guaranteeing a fixed
+and reproducable audio bitstream. 0 = unmuted, 1 = muted.</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-video-encoding">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ENCODING</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_video_encoding</entry>
+	      </row><row><entry spanname="descr">MPEG Video encoding
+method. Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_1</constant>&nbsp;</entry>
+		      <entry>MPEG-1 Video encoding</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_2</constant>&nbsp;</entry>
+		      <entry>MPEG-2 Video encoding</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC</constant>&nbsp;</entry>
+		      <entry>MPEG-4 AVC (H.264) Video encoding</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-video-aspect">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ASPECT</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_video_aspect</entry>
+	      </row><row><entry spanname="descr">Video aspect.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_ASPECT_1x1</constant>&nbsp;</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_ASPECT_4x3</constant>&nbsp;</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_ASPECT_16x9</constant>&nbsp;</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_ASPECT_221x100</constant>&nbsp;</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_B_FRAMES</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Number of B-Frames
+(default 2)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_GOP_SIZE</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">GOP size (default
+12)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_GOP_CLOSURE</constant>&nbsp;</entry>
+		<entry>boolean</entry>
+	      </row><row><entry spanname="descr">GOP closure (default
+1)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_PULLDOWN</constant>&nbsp;</entry>
+		<entry>boolean</entry>
+	      </row><row><entry spanname="descr">Enable 3:2 pulldown
+(default 0)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-video-bitrate-mode">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE_MODE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_video_bitrate_mode</entry>
+	      </row><row><entry spanname="descr">Video bitrate mode.
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_BITRATE_MODE_VBR</constant>&nbsp;</entry>
+		      <entry>Variable bitrate</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_VIDEO_BITRATE_MODE_CBR</constant>&nbsp;</entry>
+		      <entry>Constant bitrate</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Video bitrate in bits
+per second.</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE_PEAK</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Peak video bitrate in
+bits per second. Must be larger or equal to the average video bitrate.
+It is ignored if the video bitrate mode is set to constant
+bitrate.</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">For every captured
+frame, skip this many subsequent frames (default 0).</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MUTE</constant>&nbsp;</entry>
+		<entry>boolean</entry>
+	      </row>
+	      <row><entry spanname="descr">"Mutes" the video to a
+fixed color when capturing. This is useful for testing, to produce a
+fixed video bitstream. 0 = unmuted, 1 = muted.</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MUTE_YUV</constant>&nbsp;</entry>
+		<entry>integer</entry>
+	      </row><row><entry spanname="descr">Sets the "mute" color
+of the video. The supplied 32-bit integer is interpreted as follows (bit
+0 = least significant bit):</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry>Bit 0:7</entry>
+		      <entry>V chrominance information</entry>
+		    </row>
+		    <row>
+		      <entry>Bit 8:15</entry>
+		      <entry>U chrominance information</entry>
+		    </row>
+		    <row>
+		      <entry>Bit 16:23</entry>
+		      <entry>Y luminance information</entry>
+		    </row>
+		    <row>
+		      <entry>Bit 24:31</entry>
+		      <entry>Must be zero.</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</table>
+      </section>
+
+      <section>
+	<title>CX2341x MPEG Controls</title>
+
+	<para>The following MPEG class controls deal with MPEG
+encoding settings that are specific to the Conexant CX23415 and
+CX23416 MPEG encoding chips.</para>
+
+	<table pgwide="1" frame="none" id="cx2341x-control-id">
+	  <title>CX2341x Control IDs</title>
+	  <tgroup cols="4">
+	    <colspec colname="c1" colwidth="1*" />
+	    <colspec colname="c2" colwidth="6*" />
+	    <colspec colname="c3" colwidth="2*" />
+	    <colspec colname="c4" colwidth="6*" />
+	    <spanspec namest="c1" nameend="c2" spanname="id" />
+	    <spanspec namest="c2" nameend="c4" spanname="descr" />
+	    <thead>
+	      <row>
+		<entry spanname="id" align="left">ID</entry>
+		<entry align="left">Type</entry>
+	      </row><row><entry spanname="descr" align="left">Description</entry>
+	      </row>
+	    </thead>
+	    <tbody valign="top">
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-cx2341x-video-spatial-filter-mode">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_cx2341x_video_spatial_filter_mode</entry>
+	      </row><row><entry spanname="descr">Sets the Spatial
+Filter mode (default <constant>MANUAL</constant>). Possible values
+are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL</constant>&nbsp;</entry>
+		      <entry>Choose the filter manually</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO</constant>&nbsp;</entry>
+		      <entry>Choose the filter automatically</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER</constant>&nbsp;</entry>
+		<entry>integer&nbsp;(0-15)</entry>
+	      </row><row><entry spanname="descr">The setting for the
+Spatial Filter. 0 = off, 15 = maximum. (Default is 0.)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="luma-spatial-filter-type">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</entry>
+	      </row><row><entry spanname="descr">Select the algorithm
+to use for the Luma Spatial Filter (default
+<constant>1D_HOR</constant>). Possible values:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF</constant>&nbsp;</entry>
+		      <entry>No filter</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR</constant>&nbsp;</entry>
+		      <entry>One-dimensional horizontal</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT</constant>&nbsp;</entry>
+		      <entry>One-dimensional vertical</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE</constant>&nbsp;</entry>
+		      <entry>Two-dimensional separable</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE</constant>&nbsp;</entry>
+		      <entry>Two-dimensional symmetrical
+non-separable</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="chroma-spatial-filter-type">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</entry>
+	      </row><row><entry spanname="descr">Select the algorithm
+for the Chroma Spatial Filter (default <constant>1D_HOR</constant>).
+Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF</constant>&nbsp;</entry>
+		      <entry>No filter</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR</constant>&nbsp;</entry>
+		      <entry>One-dimensional horizontal</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-cx2341x-video-temporal-filter-mode">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_cx2341x_video_temporal_filter_mode</entry>
+	      </row><row><entry spanname="descr">Sets the Temporal
+Filter mode (default <constant>MANUAL</constant>). Possible values
+are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL</constant>&nbsp;</entry>
+		      <entry>Choose the filter manually</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO</constant>&nbsp;</entry>
+		      <entry>Choose the filter automatically</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER</constant>&nbsp;</entry>
+		<entry>integer&nbsp;(0-31)</entry>
+	      </row><row><entry spanname="descr">The setting for the
+Temporal Filter. 0 = off, 31 = maximum. (Default is 8 for full-scale
+capturing and 0 for scaled capturing.)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row id="v4l2-mpeg-cx2341x-video-median-filter-type">
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE</constant>&nbsp;</entry>
+		<entry>enum&nbsp;v4l2_mpeg_cx2341x_video_median_filter_type</entry>
+	      </row><row><entry spanname="descr">Median Filter Type
+(default <constant>OFF</constant>). Possible values are:</entry>
+	      </row>
+	      <row>
+		<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF</constant>&nbsp;</entry>
+		      <entry>No filter</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR</constant>&nbsp;</entry>
+		      <entry>Horizontal filter</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT</constant>&nbsp;</entry>
+		      <entry>Vertical filter</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT</constant>&nbsp;</entry>
+		      <entry>Horizontal and vertical filter</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG</constant>&nbsp;</entry>
+		      <entry>Diagonal filter</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM</constant>&nbsp;</entry>
+		<entry>integer&nbsp;(0-255)</entry>
+	      </row><row><entry spanname="descr">Threshold above which
+the luminance median filter is enabled (default 0)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP</constant>&nbsp;</entry>
+		<entry>integer&nbsp;(0-255)</entry>
+	      </row><row><entry spanname="descr">Threshold below which
+the luminance median filter is enabled (default 255)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM</constant>&nbsp;</entry>
+		<entry>integer&nbsp;(0-255)</entry>
+	      </row><row><entry spanname="descr">Threshold above which
+the chroma median filter is enabled (default 0)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP</constant>&nbsp;</entry>
+		<entry>integer&nbsp;(0-255)</entry>
+	      </row><row><entry spanname="descr">Threshold below which
+the chroma median filter is enabled (default 255)</entry>
+	      </row>
+	      <row><entry></entry></row>
+	      <row>
+		<entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS</constant>&nbsp;</entry>
+		<entry>boolean</entry>
+	      </row>
+	      <row><entry spanname="descr">The CX2341X MPEG encoder
+can insert one empty MPEG-2 PES packet into the stream between every
+four video frames. The packet size is 2048 bytes, including the
+packet_start_code_prefix and stream_id fields. The stream_id is 0xBF
+(private stream 2). The payload consists of 0x00 bytes, to be filled
+in by the application. 0 = do not insert, 1 = insert packets.</entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</table>
+      </section>
+    </section>
+
+    <section id="camera-controls">
+      <title>Camera Control Reference</title>
+
+      <para>The Camera class includes controls for mechanical (or
+equivalent digital) features of a device such as controllable lenses
+or sensors.</para>
+
+    <table pgwide="1" frame="none" id="camera-control-id">
+      <title>Camera Control IDs</title>
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_CAMERA_CLASS</constant>&nbsp;</entry>
+	    <entry>class</entry>
+	  </row><row><entry spanname="descr">The Camera class
+descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
+description of this control class.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row id="v4l2-exposure-auto-type">
+	    <entry spanname="id"><constant>V4L2_CID_EXPOSURE_AUTO</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_exposure_auto_type</entry>
+	  </row><row><entry spanname="descr">Enables automatic
+adjustments of the exposure time and/or iris aperture. The effect of
+manual changes of the exposure time or iris aperture while these
+features are enabled is undefined, drivers should ignore such
+requests. Possible values are:</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_EXPOSURE_AUTO</constant>&nbsp;</entry>
+		      <entry>Automatic exposure time, automatic iris
+aperture.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_EXPOSURE_MANUAL</constant>&nbsp;</entry>
+		  <entry>Manual exposure time, manual iris.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_EXPOSURE_SHUTTER_PRIORITY</constant>&nbsp;</entry>
+		  <entry>Manual exposure time, auto iris.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_EXPOSURE_APERTURE_PRIORITY</constant>&nbsp;</entry>
+		  <entry>Auto exposure time, manual iris.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_EXPOSURE_ABSOLUTE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">Determines the exposure
+time of the camera sensor. The exposure time is limited by the frame
+interval. Drivers should interpret the values as 100 &micro;s units,
+where the value 1 stands for 1/10000th of a second, 10000 for 1 second
+and 100000 for 10 seconds.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_EXPOSURE_AUTO_PRIORITY</constant>&nbsp;</entry>
+	    <entry>boolean</entry>
+	  </row><row><entry spanname="descr">When
+<constant>V4L2_CID_EXPOSURE_AUTO</constant> is set to
+<constant>AUTO</constant> or <constant>APERTURE_PRIORITY</constant>,
+this control determines if the device may dynamically vary the frame
+rate. By default this feature is disabled (0) and the frame rate must
+remain constant.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control turns the
+camera horizontally by the specified amount. The unit is undefined. A
+positive value moves the camera to the right (clockwise when viewed
+from above), a negative value to the left. A value of zero does not
+cause motion. This is a write-only control.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TILT_RELATIVE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control turns the
+camera vertically by the specified amount. The unit is undefined. A
+positive value moves the camera up, a negative value down. A value of
+zero does not cause motion. This is a write-only control.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PAN_RESET</constant>&nbsp;</entry>
+	    <entry>button</entry>
+	  </row><row><entry spanname="descr">When this control is set,
+the camera moves horizontally to the default position.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TILT_RESET</constant>&nbsp;</entry>
+	    <entry>button</entry>
+	  </row><row><entry spanname="descr">When this control is set,
+the camera moves vertically to the default position.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PAN_ABSOLUTE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control
+turns the camera horizontally to the specified position. Positive
+values move the camera to the right (clockwise when viewed from above),
+negative values to the left. Drivers should interpret the values as arc
+seconds, with valid values between -180 * 3600 and +180 * 3600
+inclusive.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TILT_ABSOLUTE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control
+turns the camera vertically to the specified position. Positive values
+move the camera up, negative values down. Drivers should interpret the
+values as arc seconds, with valid values between -180 * 3600 and +180
+* 3600 inclusive.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_FOCUS_ABSOLUTE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control sets the
+focal point of the camera to the specified position. The unit is
+undefined. Positive values set the focus closer to the camera,
+negative values towards infinity.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_FOCUS_RELATIVE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">This control moves the
+focal point of the camera by the specified amount. The unit is
+undefined. Positive values move the focus closer to the camera,
+negative values towards infinity. This is a write-only control.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant>&nbsp;</entry>
+	    <entry>boolean</entry>
+	  </row><row><entry spanname="descr">Enables automatic focus
+adjustments. The effect of manual focus adjustments while this feature
+is enabled is undefined, drivers should ignore such requests.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">Specify the objective lens
+focal length as an absolute value. The zoom unit is driver-specific and its
+value should be a positive integer.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_ZOOM_RELATIVE</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">Specify the objective lens
+focal length relatively to the current value. Positive values move the zoom
+lens group towards the telephoto direction, negative values towards the
+wide-angle direction. The zoom unit is driver-specific. This is a write-only control.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_ZOOM_CONTINUOUS</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">Move the objective lens group
+at the specified speed until it reaches physical device limits or until an
+explicit request to stop the movement. A positive value moves the zoom lens
+group towards the telephoto direction. A value of zero stops the zoom lens
+group movement. A negative value moves the zoom lens group towards the
+wide-angle direction. The zoom speed unit is driver-specific.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PRIVACY</constant>&nbsp;</entry>
+	    <entry>boolean</entry>
+	  </row><row><entry spanname="descr">Prevent video from being acquired
+by the camera. When this control is set to <constant>TRUE</constant> (1), no
+image can be captured by the camera. Common means to enforce privacy are
+mechanical obturation of the sensor and firmware image processing, but the
+device is not restricted to these methods. Devices that implement the privacy
+control must support read access and may support write access.</entry>
+	  </row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_BAND_STOP_FILTER</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row><row><entry spanname="descr">Switch the band-stop filter of a
+camera sensor on or off, or specify its strength. Such band-stop filters can
+be used, for example, to filter out the fluorescent light component.</entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+    </table>
+  </section>
+
+    <section id="fm-tx-controls">
+      <title>FM Transmitter Control Reference</title>
+
+      <para>The FM Transmitter (FM_TX) class includes controls for common features of
+FM transmissions capable devices. Currently this class includes parameters for audio
+compression, pilot tone generation, audio deviation limiter, RDS transmission and
+tuning power features.</para>
+
+      <table pgwide="1" frame="none" id="fm-tx-control-id">
+      <title>FM_TX Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_FM_TX_CLASS</constant>&nbsp;</entry>
+	    <entry>class</entry>
+	  </row><row><entry spanname="descr">The FM_TX class
+descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
+description of this control class.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_RDS_TX_DEVIATION</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Configures RDS signal frequency deviation level in Hz.
+The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_RDS_TX_PI</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the RDS Programme Identification field
+for transmission.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_RDS_TX_PTY</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the RDS Programme Type field for transmission.
+This encodes up to 31 pre-defined programme types.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_RDS_TX_PS_NAME</constant>&nbsp;</entry>
+	    <entry>string</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the Programme Service name (PS_NAME) for transmission.
+It is intended for static display on a receiver. It is the primary aid to listeners in programme service
+identification and selection.  In Annex E of <xref linkend="en50067" />, the RDS specification,
+there is a full description of the correct character encoding for Programme Service name strings.
+Also from RDS specification, PS is usually a single eight character text. However, it is also possible
+to find receivers which can scroll strings sized as 8 x N characters. So, this control must be configured
+with steps of 8 characters. The result is it must always contain a string with size multiple of 8.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_RDS_TX_RADIO_TEXT</constant>&nbsp;</entry>
+	    <entry>string</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the Radio Text info for transmission. It is a textual description of
+what is being broadcasted. RDS Radio Text can be applied when broadcaster wishes to transmit longer PS names,
+programme-related information or any other text. In these cases, RadioText should be used in addition to
+<constant>V4L2_CID_RDS_TX_PS_NAME</constant>. The encoding for Radio Text strings is also fully described
+in Annex E of <xref linkend="en50067" />. The length of Radio Text strings depends on which RDS Block is being
+used to transmit it, either 32 (2A block) or 64 (2B block).  However, it is also possible
+to find receivers which can scroll strings sized as 32 x N or 64 x N characters. So, this control must be configured
+with steps of 32 or 64 characters. The result is it must always contain a string with size multiple of 32 or 64. </entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_ENABLED</constant>&nbsp;</entry>
+	    <entry>boolean</entry>
+	  </row>
+	  <row><entry spanname="descr">Enables or disables the audio deviation limiter feature.
+The limiter is useful when trying to maximize the audio volume, minimize receiver-generated
+distortion and prevent overmodulation.
+</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_RELEASE_TIME</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the audio deviation limiter feature release time.
+Unit is in useconds. Step and range are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_DEVIATION</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Configures audio frequency deviation level in Hz.
+The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_ENABLED</constant>&nbsp;</entry>
+	    <entry>boolean</entry>
+	  </row>
+	  <row><entry spanname="descr">Enables or disables the audio compression feature.
+This feature amplifies signals below the threshold by a fixed gain and compresses audio
+signals above the threshold by the ratio of Threshold/(Gain + Threshold).</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_GAIN</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the gain for audio compression feature. It is
+a dB value. The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_THRESHOLD</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the threshold level for audio compression freature.
+It is a dB value. The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the attack time for audio compression feature.
+It is a useconds value. The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the release time for audio compression feature.
+It is a useconds value. The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_ENABLED</constant>&nbsp;</entry>
+	    <entry>boolean</entry>
+	  </row>
+	  <row><entry spanname="descr">Enables or disables the pilot tone generation feature.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_DEVIATION</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Configures pilot tone frequency deviation level. Unit is
+in Hz. The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_FREQUENCY</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Configures pilot tone frequency value. Unit is
+in Hz. The range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TUNE_PREEMPHASIS</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row id="v4l2-preemphasis"><entry spanname="descr">Configures the pre-emphasis value for broadcasting.
+A pre-emphasis filter is applied to the broadcast to accentuate the high audio frequencies.
+Depending on the region, a time constant of either 50 or 75 useconds is used. The enum&nbsp;v4l2_preemphasis
+defines possible values for pre-emphasis. Here they are:</entry>
+	</row><row>
+	<entrytbl spanname="descr" cols="2">
+		  <tbody valign="top">
+		    <row>
+		      <entry><constant>V4L2_PREEMPHASIS_DISABLED</constant>&nbsp;</entry>
+		      <entry>No pre-emphasis is applied.</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_PREEMPHASIS_50_uS</constant>&nbsp;</entry>
+		      <entry>A pre-emphasis of 50 uS is used.</entry>
+		    </row>
+		    <row>
+		      <entry><constant>V4L2_PREEMPHASIS_75_uS</constant>&nbsp;</entry>
+		      <entry>A pre-emphasis of 75 uS is used.</entry>
+		    </row>
+		  </tbody>
+		</entrytbl>
+
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TUNE_POWER_LEVEL</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">Sets the output power level for signal transmission.
+Unit is in dBuV. Range and step are driver-specific.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_TUNE_ANTENNA_CAPACITOR</constant>&nbsp;</entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row><entry spanname="descr">This selects the value of antenna tuning capacitor
+manually or automatically if set to zero. Unit, range and step are driver-specific.</entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+<para>For more details about RDS specification, refer to
+<xref linkend="en50067" /> document, from CENELEC.</para>
+    </section>
+</section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "common.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/crop.gif b/Documentation/DocBook/v4l/crop.gif
new file mode 100644
index 0000000..3b9e7d8
Binary files /dev/null and b/Documentation/DocBook/v4l/crop.gif differ
diff --git a/Documentation/DocBook/v4l/crop.pdf b/Documentation/DocBook/v4l/crop.pdf
new file mode 100644
index 0000000..c9fb81c
Binary files /dev/null and b/Documentation/DocBook/v4l/crop.pdf differ
diff --git a/Documentation/DocBook/v4l/dev-capture.xml b/Documentation/DocBook/v4l/dev-capture.xml
new file mode 100644
index 0000000..32807e4
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-capture.xml
@@ -0,0 +1,115 @@
+  <title>Video Capture Interface</title>
+
+  <para>Video capture devices sample an analog video signal and store
+the digitized images in memory. Today nearly all devices can capture
+at full 25 or 30 frames/second. With this interface applications can
+control the capture process and move images from the driver into user
+space.</para>
+
+  <para>Conventionally V4L2 video capture devices are accessed through
+character device special files named <filename>/dev/video</filename>
+and <filename>/dev/video0</filename> to
+<filename>/dev/video63</filename> with major number 81 and minor
+numbers 0 to 63. <filename>/dev/video</filename> is typically a
+symbolic link to the preferred video device. Note the same device
+files are used for video output devices.</para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>Devices supporting the video capture interface set the
+<constant>V4L2_CAP_VIDEO_CAPTURE</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
+they may also support the <link linkend="overlay">video overlay</link>
+(<constant>V4L2_CAP_VIDEO_OVERLAY</constant>) and the <link
+linkend="raw-vbi">raw VBI capture</link>
+(<constant>V4L2_CAP_VBI_CAPTURE</constant>) interface. At least one of
+the read/write or streaming I/O methods must be supported. Tuners and
+audio inputs are optional.</para>
+  </section>
+
+  <section>
+    <title>Supplemental Functions</title>
+
+    <para>Video capture devices shall support <link
+linkend="audio">audio input</link>, <link
+linkend="tuner">tuner</link>, <link linkend="control">controls</link>,
+<link linkend="crop">cropping and scaling</link> and <link
+linkend="streaming-par">streaming parameter</link> ioctls as needed.
+The <link linkend="video">video input</link> and <link
+linkend="standard">video standard</link> ioctls must be supported by
+all video capture devices.</para>
+  </section>
+
+  <section>
+    <title>Image Format Negotiation</title>
+
+    <para>The result of a capture operation is determined by
+cropping and image format parameters. The former select an area of the
+video picture to capture, the latter how images are stored in memory,
+&ie; in RGB or YUV format, the number of bits per pixel or width and
+height. Together they also define how images are scaled in the
+process.</para>
+
+    <para>As usual these parameters are <emphasis>not</emphasis> reset
+at &func-open; time to permit Unix tool chains, programming a device
+and then reading from it as if it was a plain file. Well written V4L2
+applications ensure they really get what they want, including cropping
+and scaling.</para>
+
+    <para>Cropping initialization at minimum requires to reset the
+parameters to defaults. An example is given in <xref
+linkend="crop" />.</para>
+
+    <para>To query the current image format applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and call the
+&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
+the &v4l2-pix-format; <structfield>pix</structfield> member of the
+<structfield>fmt</structfield> union.</para>
+
+    <para>To request different parameters applications set the
+<structfield>type</structfield> field of a &v4l2-format; as above and
+initialize all fields of the &v4l2-pix-format;
+<structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union, or better just modify the
+results of <constant>VIDIOC_G_FMT</constant>, and call the
+&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers may
+adjust the parameters and finally return the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does.</para>
+
+    <para>Like <constant>VIDIOC_S_FMT</constant> the
+&VIDIOC-TRY-FMT; ioctl can be used to learn about hardware limitations
+without disabling I/O or possibly time consuming hardware
+preparations.</para>
+
+    <para>The contents of &v4l2-pix-format; are discussed in <xref
+linkend="pixfmt" />. See also the specification of the
+<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
+and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
+capture devices must implement both the
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl, even if
+<constant>VIDIOC_S_FMT</constant> ignores all requests and always
+returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
+<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
+  </section>
+
+  <section>
+    <title>Reading Images</title>
+
+    <para>A video capture device may support the <link
+linkend="rw">read() function</link> and/or streaming (<link
+linkend="mmap">memory mapping</link> or <link
+linkend="userp">user pointer</link>) I/O. See <xref
+linkend="io" /> for details.</para>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/dev-codec.xml b/Documentation/DocBook/v4l/dev-codec.xml
new file mode 100644
index 0000000..6e156dc
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-codec.xml
@@ -0,0 +1,26 @@
+  <title>Codec Interface</title>
+
+  <note>
+    <title>Suspended</title>
+
+    <para>This interface has been be suspended from the V4L2 API
+implemented in Linux 2.6 until we have more experience with codec
+device interfaces.</para>
+  </note>
+
+  <para>A V4L2 codec can compress, decompress, transform, or otherwise
+convert video data from one format into another format, in memory.
+Applications send data to be converted to the driver through a
+&func-write; call, and receive the converted data through a
+&func-read; call. For efficiency a driver may also support streaming
+I/O.</para>
+
+  <para>[to do]</para>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/dev-effect.xml b/Documentation/DocBook/v4l/dev-effect.xml
new file mode 100644
index 0000000..9c243be
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-effect.xml
@@ -0,0 +1,25 @@
+  <title>Effect Devices Interface</title>
+
+  <note>
+    <title>Suspended</title>
+
+    <para>This interface has been be suspended from the V4L2 API
+implemented in Linux 2.6 until we have more experience with effect
+device interfaces.</para>
+  </note>
+
+  <para>A V4L2 video effect device can do image effects, filtering, or
+combine two or more images or image streams. For example video
+transitions or wipes. Applications send data to be processed and
+receive the result data either with &func-read; and &func-write;
+functions, or through the streaming I/O mechanism.</para>
+
+  <para>[to do]</para>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/dev-osd.xml b/Documentation/DocBook/v4l/dev-osd.xml
new file mode 100644
index 0000000..c9a68a2
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-osd.xml
@@ -0,0 +1,164 @@
+  <title>Video Output Overlay Interface</title>
+  <subtitle>Also known as On-Screen Display (OSD)</subtitle>
+
+  <note>
+    <title>Experimental</title>
+
+    <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+  </note>
+
+  <para>Some video output devices can overlay a framebuffer image onto
+the outgoing video signal. Applications can set up such an overlay
+using this interface, which borrows structures and ioctls of the <link
+linkend="overlay">Video Overlay</link> interface.</para>
+
+  <para>The OSD function is accessible through the same character
+special file as the <link linkend="capture">Video Output</link> function.
+Note the default function of such a <filename>/dev/video</filename> device
+is video capturing or output. The OSD function is only available after
+calling the &VIDIOC-S-FMT; ioctl.</para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>Devices supporting the <wordasword>Video Output
+Overlay</wordasword> interface set the
+<constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl.</para>
+  </section>
+
+  <section>
+    <title>Framebuffer</title>
+
+    <para>Contrary to the <wordasword>Video Overlay</wordasword>
+interface the framebuffer is normally implemented on the TV card and
+not the graphics card. On Linux it is accessible as a framebuffer
+device (<filename>/dev/fbN</filename>). Given a V4L2 device,
+applications can find the corresponding framebuffer device by calling
+the &VIDIOC-G-FBUF; ioctl. It returns, amongst other information, the
+physical address of the framebuffer in the
+<structfield>base</structfield> field of &v4l2-framebuffer;. The
+framebuffer device ioctl <constant>FBIOGET_FSCREENINFO</constant>
+returns the same address in the <structfield>smem_start</structfield>
+field of struct <structname>fb_fix_screeninfo</structname>. The
+<constant>FBIOGET_FSCREENINFO</constant> ioctl and struct
+<structname>fb_fix_screeninfo</structname> are defined in the
+<filename>linux/fb.h</filename> header file.</para>
+
+    <para>The width and height of the framebuffer depends on the
+current video standard. A V4L2 driver may reject attempts to change
+the video standard (or any other ioctl which would imply a framebuffer
+size change) with an &EBUSY; until all applications closed the
+framebuffer device.</para>
+
+    <example>
+      <title>Finding a framebuffer device for OSD</title>
+
+      <programlisting>
+#include &lt;linux/fb.h&gt;
+
+&v4l2-framebuffer; fbuf;
+unsigned int i;
+int fb_fd;
+
+if (-1 == ioctl (fd, VIDIOC_G_FBUF, &amp;fbuf)) {
+	perror ("VIDIOC_G_FBUF");
+	exit (EXIT_FAILURE);
+}
+
+for (i = 0; i &gt; 30; ++i) {
+	char dev_name[16];
+	struct fb_fix_screeninfo si;
+
+	snprintf (dev_name, sizeof (dev_name), "/dev/fb%u", i);
+
+	fb_fd = open (dev_name, O_RDWR);
+	if (-1 == fb_fd) {
+		switch (errno) {
+		case ENOENT: /* no such file */
+		case ENXIO:  /* no driver */
+			continue;
+
+		default:
+			perror ("open");
+			exit (EXIT_FAILURE);
+		}
+	}
+
+	if (0 == ioctl (fb_fd, FBIOGET_FSCREENINFO, &amp;si)) {
+		if (si.smem_start == (unsigned long) fbuf.base)
+			break;
+	} else {
+		/* Apparently not a framebuffer device. */
+	}
+
+	close (fb_fd);
+	fb_fd = -1;
+}
+
+/* fb_fd is the file descriptor of the framebuffer device
+   for the video output overlay, or -1 if no device was found. */
+</programlisting>
+    </example>
+  </section>
+
+  <section>
+    <title>Overlay Window and Scaling</title>
+
+    <para>The overlay is controlled by source and target rectangles.
+The source rectangle selects a subsection of the framebuffer image to
+be overlaid, the target rectangle an area in the outgoing video signal
+where the image will appear. Drivers may or may not support scaling,
+and arbitrary sizes and positions of these rectangles. Further drivers
+may support any (or none) of the clipping/blending methods defined for
+the <link linkend="overlay">Video Overlay</link> interface.</para>
+
+    <para>A &v4l2-window; defines the size of the source rectangle,
+its position in the framebuffer and the clipping/blending method to be
+used for the overlay. To get the current parameters applications set
+the <structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant> and call the
+&VIDIOC-G-FMT; ioctl. The driver fills the
+<structname>v4l2_window</structname> substructure named
+<structfield>win</structfield>. It is not possible to retrieve a
+previously programmed clipping list or bitmap.</para>
+
+    <para>To program the source rectangle applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>, initialize
+the <structfield>win</structfield> substructure and call the
+&VIDIOC-S-FMT; ioctl. The driver adjusts the parameters against
+hardware limits and returns the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does. Like
+<constant>VIDIOC_S_FMT</constant>, the &VIDIOC-TRY-FMT; ioctl can be
+used to learn about driver capabilities without actually changing
+driver state. Unlike <constant>VIDIOC_S_FMT</constant> this also works
+after the overlay has been enabled.</para>
+
+    <para>A &v4l2-crop; defines the size and position of the target
+rectangle. The scaling factor of the overlay is implied by the width
+and height given in &v4l2-window; and &v4l2-crop;. The cropping API
+applies to <wordasword>Video Output</wordasword> and <wordasword>Video
+Output Overlay</wordasword> devices in the same way as to
+<wordasword>Video Capture</wordasword> and <wordasword>Video
+Overlay</wordasword> devices, merely reversing the direction of the
+data flow. For more information see <xref linkend="crop" />.</para>
+  </section>
+
+  <section>
+    <title>Enabling Overlay</title>
+
+    <para>There is no V4L2 ioctl to enable or disable the overlay,
+however the framebuffer interface of the driver may support the
+<constant>FBIOBLANK</constant> ioctl.</para>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/dev-output.xml b/Documentation/DocBook/v4l/dev-output.xml
new file mode 100644
index 0000000..63c3c20
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-output.xml
@@ -0,0 +1,111 @@
+  <title>Video Output Interface</title>
+
+  <para>Video output devices encode stills or image sequences as
+analog video signal. With this interface applications can
+control the encoding process and move images from user space to
+the driver.</para>
+
+  <para>Conventionally V4L2 video output devices are accessed through
+character device special files named <filename>/dev/video</filename>
+and <filename>/dev/video0</filename> to
+<filename>/dev/video63</filename> with major number 81 and minor
+numbers 0 to 63. <filename>/dev/video</filename> is typically a
+symbolic link to the preferred video device. Note the same device
+files are used for video capture devices.</para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>Devices supporting the video output interface set the
+<constant>V4L2_CAP_VIDEO_OUTPUT</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
+they may also support the <link linkend="raw-vbi">raw VBI
+output</link> (<constant>V4L2_CAP_VBI_OUTPUT</constant>) interface. At
+least one of the read/write or streaming I/O methods must be
+supported. Modulators and audio outputs are optional.</para>
+  </section>
+
+  <section>
+    <title>Supplemental Functions</title>
+
+    <para>Video output devices shall support <link
+linkend="audio">audio output</link>, <link
+linkend="tuner">modulator</link>, <link linkend="control">controls</link>,
+<link linkend="crop">cropping and scaling</link> and <link
+linkend="streaming-par">streaming parameter</link> ioctls as needed.
+The <link linkend="video">video output</link> and <link
+linkend="standard">video standard</link> ioctls must be supported by
+all video output devices.</para>
+  </section>
+
+  <section>
+    <title>Image Format Negotiation</title>
+
+    <para>The output is determined by cropping and image format
+parameters. The former select an area of the video picture where the
+image will appear, the latter how images are stored in memory, &ie; in
+RGB or YUV format, the number of bits per pixel or width and height.
+Together they also define how images are scaled in the process.</para>
+
+    <para>As usual these parameters are <emphasis>not</emphasis> reset
+at &func-open; time to permit Unix tool chains, programming a device
+and then writing to it as if it was a plain file. Well written V4L2
+applications ensure they really get what they want, including cropping
+and scaling.</para>
+
+    <para>Cropping initialization at minimum requires to reset the
+parameters to defaults. An example is given in <xref
+linkend="crop" />.</para>
+
+    <para>To query the current image format applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and call the
+&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
+the &v4l2-pix-format; <structfield>pix</structfield> member of the
+<structfield>fmt</structfield> union.</para>
+
+    <para>To request different parameters applications set the
+<structfield>type</structfield> field of a &v4l2-format; as above and
+initialize all fields of the &v4l2-pix-format;
+<structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union, or better just modify the
+results of <constant>VIDIOC_G_FMT</constant>, and call the
+&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers may
+adjust the parameters and finally return the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does.</para>
+
+    <para>Like <constant>VIDIOC_S_FMT</constant> the
+&VIDIOC-TRY-FMT; ioctl can be used to learn about hardware limitations
+without disabling I/O or possibly time consuming hardware
+preparations.</para>
+
+    <para>The contents of &v4l2-pix-format; are discussed in <xref
+linkend="pixfmt" />. See also the specification of the
+<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
+and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
+output devices must implement both the
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl, even if
+<constant>VIDIOC_S_FMT</constant> ignores all requests and always
+returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
+<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
+  </section>
+
+  <section>
+    <title>Writing Images</title>
+
+    <para>A video output device may support the <link
+linkend="rw">write() function</link> and/or streaming (<link
+linkend="mmap">memory mapping</link> or <link
+linkend="userp">user pointer</link>) I/O. See <xref
+linkend="io" /> for details.</para>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/dev-overlay.xml b/Documentation/DocBook/v4l/dev-overlay.xml
new file mode 100644
index 0000000..92513cf
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-overlay.xml
@@ -0,0 +1,379 @@
+  <title>Video Overlay Interface</title>
+  <subtitle>Also known as Framebuffer Overlay or Previewing</subtitle>
+
+  <para>Video overlay devices have the ability to genlock (TV-)video
+into the (VGA-)video signal of a graphics card, or to store captured
+images directly in video memory of a graphics card, typically with
+clipping. This can be considerable more efficient than capturing
+images and displaying them by other means. In the old days when only
+nuclear power plants needed cooling towers this used to be the only
+way to put live video into a window.</para>
+
+  <para>Video overlay devices are accessed through the same character
+special files as <link linkend="capture">video capture</link> devices.
+Note the default function of a <filename>/dev/video</filename> device
+is video capturing. The overlay function is only available after
+calling the &VIDIOC-S-FMT; ioctl.</para>
+
+    <para>The driver may support simultaneous overlay and capturing
+using the read/write and streaming I/O methods. If so, operation at
+the nominal frame rate of the video standard is not guaranteed. Frames
+may be directed away from overlay to capture, or one field may be used
+for overlay and the other for capture if the capture parameters permit
+this.</para>
+
+  <para>Applications should use different file descriptors for
+capturing and overlay. This must be supported by all drivers capable
+of simultaneous capturing and overlay. Optionally these drivers may
+also permit capturing and overlay with a single file descriptor for
+compatibility with V4L and earlier versions of V4L2.<footnote>
+	<para>A common application of two file descriptors is the
+XFree86 <link linkend="xvideo">Xv/V4L</link> interface driver and
+a V4L2 application. While the X server controls video overlay, the
+application can take advantage of memory mapping and DMA.</para>
+	<para>In the opinion of the designers of this API, no driver
+writer taking the efforts to support simultaneous capturing and
+overlay will restrict this ability by requiring a single file
+descriptor, as in V4L and earlier versions of V4L2. Making this
+optional means applications depending on two file descriptors need
+backup routines to be compatible with all drivers, which is
+considerable more work than using two fds in applications which do
+not. Also two fd's fit the general concept of one file descriptor for
+each logical stream. Hence as a complexity trade-off drivers
+<emphasis>must</emphasis> support two file descriptors and
+<emphasis>may</emphasis> support single fd operation.</para>
+      </footnote></para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>Devices supporting the video overlay interface set the
+<constant>V4L2_CAP_VIDEO_OVERLAY</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. The overlay I/O method specified
+below must be supported. Tuners and audio inputs are optional.</para>
+  </section>
+
+  <section>
+    <title>Supplemental Functions</title>
+
+    <para>Video overlay devices shall support <link
+linkend="audio">audio input</link>, <link
+linkend="tuner">tuner</link>, <link linkend="control">controls</link>,
+<link linkend="crop">cropping and scaling</link> and <link
+linkend="streaming-par">streaming parameter</link> ioctls as needed.
+The <link linkend="video">video input</link> and <link
+linkend="standard">video standard</link> ioctls must be supported by
+all video overlay devices.</para>
+  </section>
+
+  <section>
+    <title>Setup</title>
+
+    <para>Before overlay can commence applications must program the
+driver with frame buffer parameters, namely the address and size of
+the frame buffer and the image format, for example RGB 5:6:5. The
+&VIDIOC-G-FBUF; and &VIDIOC-S-FBUF; ioctls are available to get
+and set these parameters, respectively. The
+<constant>VIDIOC_S_FBUF</constant> ioctl is privileged because it
+allows to set up DMA into physical memory, bypassing the memory
+protection mechanisms of the kernel. Only the superuser can change the
+frame buffer address and size. Users are not supposed to run TV
+applications as root or with SUID bit set. A small helper application
+with suitable privileges should query the graphics system and program
+the V4L2 driver at the appropriate time.</para>
+
+    <para>Some devices add the video overlay to the output signal
+of the graphics card. In this case the frame buffer is not modified by
+the video device, and the frame buffer address and pixel format are
+not needed by the driver. The <constant>VIDIOC_S_FBUF</constant> ioctl
+is not privileged. An application can check for this type of device by
+calling the <constant>VIDIOC_G_FBUF</constant> ioctl.</para>
+
+    <para>A driver may support any (or none) of five clipping/blending
+methods:<orderedlist>
+	<listitem>
+	  <para>Chroma-keying displays the overlaid image only where
+pixels in the primary graphics surface assume a certain color.</para>
+	</listitem>
+	<listitem>
+	  <para>A bitmap can be specified where each bit corresponds
+to a pixel in the overlaid image. When the bit is set, the
+corresponding video pixel is displayed, otherwise a pixel of the
+graphics surface.</para>
+	</listitem>
+	<listitem>
+	  <para>A list of clipping rectangles can be specified. In
+these regions <emphasis>no</emphasis> video is displayed, so the
+graphics surface can be seen here.</para>
+	</listitem>
+	<listitem>
+	  <para>The framebuffer has an alpha channel that can be used
+to clip or blend the framebuffer with the video.</para>
+	</listitem>
+	<listitem>
+	  <para>A global alpha value can be specified to blend the
+framebuffer contents with video images.</para>
+	</listitem>
+      </orderedlist></para>
+
+    <para>When simultaneous capturing and overlay is supported and
+the hardware prohibits different image and frame buffer formats, the
+format requested first takes precedence. The attempt to capture
+(&VIDIOC-S-FMT;) or overlay (&VIDIOC-S-FBUF;) may fail with an
+&EBUSY; or return accordingly modified parameters..</para>
+  </section>
+
+  <section>
+    <title>Overlay Window</title>
+
+    <para>The overlaid image is determined by cropping and overlay
+window parameters. The former select an area of the video picture to
+capture, the latter how images are overlaid and clipped. Cropping
+initialization at minimum requires to reset the parameters to
+defaults. An example is given in <xref linkend="crop" />.</para>
+
+    <para>The overlay window is described by a &v4l2-window;. It
+defines the size of the image, its position over the graphics surface
+and the clipping to be applied. To get the current parameters
+applications set the <structfield>type</structfield> field of a
+&v4l2-format; to <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant> and
+call the &VIDIOC-G-FMT; ioctl. The driver fills the
+<structname>v4l2_window</structname> substructure named
+<structfield>win</structfield>. It is not possible to retrieve a
+previously programmed clipping list or bitmap.</para>
+
+    <para>To program the overlay window applications set the
+<structfield>type</structfield> field of a &v4l2-format; to
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, initialize the
+<structfield>win</structfield> substructure and call the
+&VIDIOC-S-FMT; ioctl. The driver adjusts the parameters against
+hardware limits and returns the actual parameters as
+<constant>VIDIOC_G_FMT</constant> does. Like
+<constant>VIDIOC_S_FMT</constant>, the &VIDIOC-TRY-FMT; ioctl can be
+used to learn about driver capabilities without actually changing
+driver state. Unlike <constant>VIDIOC_S_FMT</constant> this also works
+after the overlay has been enabled.</para>
+
+    <para>The scaling factor of the overlaid image is implied by the
+width and height given in &v4l2-window; and the size of the cropping
+rectangle. For more information see <xref linkend="crop" />.</para>
+
+    <para>When simultaneous capturing and overlay is supported and
+the hardware prohibits different image and window sizes, the size
+requested first takes precedence. The attempt to capture or overlay as
+well (&VIDIOC-S-FMT;) may fail with an &EBUSY; or return accordingly
+modified parameters.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-window">
+      <title>struct <structname>v4l2_window</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>&v4l2-rect;</entry>
+	    <entry><structfield>w</structfield></entry>
+	    <entry>Size and position of the window relative to the
+top, left corner of the frame buffer defined with &VIDIOC-S-FBUF;. The
+window can extend the frame buffer width and height, the
+<structfield>x</structfield> and <structfield>y</structfield>
+coordinates can be negative, and it can lie completely outside the
+frame buffer. The driver clips the window accordingly, or if that is
+not possible, modifies its size and/or position.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-field;</entry>
+	    <entry><structfield>field</structfield></entry>
+	    <entry>Applications set this field to determine which
+video field shall be overlaid, typically one of
+<constant>V4L2_FIELD_ANY</constant> (0),
+<constant>V4L2_FIELD_TOP</constant>,
+<constant>V4L2_FIELD_BOTTOM</constant> or
+<constant>V4L2_FIELD_INTERLACED</constant>. Drivers may have to choose
+a different field order and return the actual setting here.</entry>
+	    </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>chromakey</structfield></entry>
+	    <entry>When chroma-keying has been negotiated with
+&VIDIOC-S-FBUF; applications set this field to the desired pixel value
+for the chroma key. The format is the same as the pixel format of the
+framebuffer (&v4l2-framebuffer;
+<structfield>fmt.pixelformat</structfield> field), with bytes in host
+order. E.&nbsp;g. for <link
+linkend="V4L2-PIX-FMT-BGR32"><constant>V4L2_PIX_FMT_BGR24</constant></link>
+the value should be 0xRRGGBB on a little endian, 0xBBGGRR on a big
+endian host.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-clip; *</entry>
+	    <entry><structfield>clips</structfield></entry>
+	    <entry>When chroma-keying has <emphasis>not</emphasis>
+been negotiated and &VIDIOC-G-FBUF; indicated this capability,
+applications can set this field to point to an array of
+clipping rectangles.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Like the window coordinates
+<structfield>w</structfield>, clipping rectangles are defined relative
+to the top, left corner of the frame buffer. However clipping
+rectangles must not extend the frame buffer width and height, and they
+must not overlap. If possible applications should merge adjacent
+rectangles. Whether this must create x-y or y-x bands, or the order of
+rectangles, is not defined. When clip lists are not supported the
+driver ignores this field. Its contents after calling &VIDIOC-S-FMT;
+are undefined.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>clipcount</structfield></entry>
+	    <entry>When the application set the
+<structfield>clips</structfield> field, this field must contain the
+number of clipping rectangles in the list. When clip lists are not
+supported the driver ignores this field, its contents after calling
+<constant>VIDIOC_S_FMT</constant> are undefined. When clip lists are
+supported but no clipping is desired this field must be set to
+zero.</entry>
+	  </row>
+	  <row>
+	    <entry>void *</entry>
+	    <entry><structfield>bitmap</structfield></entry>
+	    <entry>When chroma-keying has
+<emphasis>not</emphasis> been negotiated and &VIDIOC-G-FBUF; indicated
+this capability, applications can set this field to point to a
+clipping bit mask.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan"><para>It must be of the same size
+as the window, <structfield>w.width</structfield> and
+<structfield>w.height</structfield>. Each bit corresponds to a pixel
+in the overlaid image, which is displayed only when the bit is
+<emphasis>set</emphasis>. Pixel coordinates translate to bits like:
+<programlisting>
+((__u8 *) <structfield>bitmap</structfield>)[<structfield>w.width</structfield> * y + x / 8] &amp; (1 &lt;&lt; (x &amp; 7))</programlisting></para><para>where <structfield>0</structfield> &le; x &lt;
+<structfield>w.width</structfield> and <structfield>0</structfield> &le;
+y &lt;<structfield>w.height</structfield>.<footnote>
+		  <para>Should we require
+	      <structfield>w.width</structfield> to be a multiple of
+	      eight?</para>
+		</footnote></para><para>When a clipping
+bit mask is not supported the driver ignores this field, its contents
+after calling &VIDIOC-S-FMT; are undefined. When a bit mask is supported
+but no clipping is desired this field must be set to
+<constant>NULL</constant>.</para><para>Applications need not create a
+clip list or bit mask. When they pass both, or despite negotiating
+chroma-keying, the results are undefined. Regardless of the chosen
+method, the clipping abilities of the hardware may be limited in
+quantity or quality. The results when these limits are exceeded are
+undefined.<footnote>
+		  <para>When the image is written into frame buffer
+memory it will be undesirable if the driver clips out less pixels
+than expected, because the application and graphics system are not
+aware these regions need to be refreshed. The driver should clip out
+more pixels or not write the image at all.</para>
+		</footnote></para></entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>global_alpha</structfield></entry>
+	    <entry>The global alpha value used to blend the
+framebuffer with video images, if global alpha blending has been
+negotiated (<constant>V4L2_FBUF_FLAG_GLOBAL_ALPHA</constant>, see
+&VIDIOC-S-FBUF;, <xref linkend="framebuffer-flags" />).</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Note this field was added in Linux 2.6.23, extending the structure. However
+the <link linkend="vidioc-g-fmt">VIDIOC_G/S/TRY_FMT</link> ioctls,
+which take a pointer to a <link
+linkend="v4l2-format">v4l2_format</link> parent structure with padding
+bytes at the end, are not affected.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-clip">
+      <title>struct <structname>v4l2_clip</structname><footnote>
+	  <para>The X Window system defines "regions" which are
+vectors of struct BoxRec { short x1, y1, x2, y2; } with width = x2 -
+x1 and height = y2 - y1, so one cannot pass X11 clip lists
+directly.</para>
+	</footnote></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>&v4l2-rect;</entry>
+	    <entry><structfield>c</structfield></entry>
+	    <entry>Coordinates of the clipping rectangle, relative to
+the top, left corner of the frame buffer. Only window pixels
+<emphasis>outside</emphasis> all clipping rectangles are
+displayed.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-clip; *</entry>
+	    <entry><structfield>next</structfield></entry>
+	    <entry>Pointer to the next clipping rectangle, NULL when
+this is the last rectangle. Drivers ignore this field, it cannot be
+used to pass a linked list of clipping rectangles.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- NB for easier reading this table is duplicated
+    in the vidioc-cropcap chapter.-->
+
+    <table pgwide="1" frame="none" id="v4l2-rect">
+      <title>struct <structname>v4l2_rect</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>left</structfield></entry>
+	    <entry>Horizontal offset of the top, left corner of the
+rectangle, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>top</structfield></entry>
+	    <entry>Vertical offset of the top, left corner of the
+rectangle, in pixels. Offsets increase to the right and down.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry>Width of the rectangle, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry>Height of the rectangle, in pixels. Width and
+height cannot be negative, the fields are signed for hysterical
+reasons. <!-- video4linux-list@redhat.com on 22 Oct 2002 subject
+"Re:[V4L][patches!] Re:v4l2/kernel-2.5" --></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <section>
+    <title>Enabling Overlay</title>
+
+    <para>To start or stop the frame buffer overlay applications call
+the &VIDIOC-OVERLAY; ioctl.</para>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/dev-radio.xml b/Documentation/DocBook/v4l/dev-radio.xml
new file mode 100644
index 0000000..73aa90b
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-radio.xml
@@ -0,0 +1,57 @@
+  <title>Radio Interface</title>
+
+  <para>This interface is intended for AM and FM (analog) radio
+receivers and transmitters.</para>
+
+  <para>Conventionally V4L2 radio devices are accessed through
+character device special files named <filename>/dev/radio</filename>
+and <filename>/dev/radio0</filename> to
+<filename>/dev/radio63</filename> with major number 81 and minor
+numbers 64 to 127.</para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>Devices supporting the radio interface set the
+<constant>V4L2_CAP_RADIO</constant> and
+<constant>V4L2_CAP_TUNER</constant> or
+<constant>V4L2_CAP_MODULATOR</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. Other combinations of
+capability flags are reserved for future extensions.</para>
+  </section>
+
+  <section>
+    <title>Supplemental Functions</title>
+
+    <para>Radio devices can support <link
+linkend="control">controls</link>, and must support the <link
+linkend="tuner">tuner or modulator</link> ioctls.</para>
+
+    <para>They do not support the video input or output, audio input
+or output, video standard, cropping and scaling, compression and
+streaming parameter, or overlay ioctls. All other ioctls and I/O
+methods are reserved for future extensions.</para>
+  </section>
+
+  <section>
+    <title>Programming</title>
+
+    <para>Radio devices may have a couple audio controls (as discussed
+in <xref linkend="control" />) such as a volume control, possibly custom
+controls. Further all radio devices have one tuner or modulator (these are
+discussed in <xref linkend="tuner" />) with index number zero to select
+the radio frequency and to determine if a monaural or FM stereo
+program is received/emitted. Drivers switch automatically between AM and FM
+depending on the selected frequency. The &VIDIOC-G-TUNER; or
+&VIDIOC-G-MODULATOR; ioctl
+reports the supported frequency range.</para>
+  </section>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/Documentation/DocBook/v4l/dev-raw-vbi.xml b/Documentation/DocBook/v4l/dev-raw-vbi.xml
new file mode 100644
index 0000000..c5a70bd
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-raw-vbi.xml
@@ -0,0 +1,347 @@
+  <title>Raw VBI Data Interface</title>
+
+  <para>VBI is an abbreviation of Vertical Blanking Interval, a gap
+in the sequence of lines of an analog video signal. During VBI
+no picture information is transmitted, allowing some time while the
+electron beam of a cathode ray tube TV returns to the top of the
+screen. Using an oscilloscope you will find here the vertical
+synchronization pulses and short data packages ASK
+modulated<footnote><para>ASK: Amplitude-Shift Keying. A high signal
+level represents a '1' bit, a low level a '0' bit.</para></footnote>
+onto the video signal. These are transmissions of services such as
+Teletext or Closed Caption.</para>
+
+  <para>Subject of this interface type is raw VBI data, as sampled off
+a video signal, or to be added to a signal for output.
+The data format is similar to uncompressed video images, a number of
+lines times a number of samples per line, we call this a VBI image.</para>
+
+  <para>Conventionally V4L2 VBI devices are accessed through character
+device special files named <filename>/dev/vbi</filename> and
+<filename>/dev/vbi0</filename> to <filename>/dev/vbi31</filename> with
+major number 81 and minor numbers 224 to 255.
+<filename>/dev/vbi</filename> is typically a symbolic link to the
+preferred VBI device. This convention applies to both input and output
+devices.</para>
+
+  <para>To address the problems of finding related video and VBI
+devices VBI capturing and output is also available as device function
+under <filename>/dev/video</filename>. To capture or output raw VBI
+data with these devices applications must call the &VIDIOC-S-FMT;
+ioctl. Accessed as <filename>/dev/vbi</filename>, raw VBI capturing
+or output is the default device function.</para>
+
+    <section>
+      <title>Querying Capabilities</title>
+
+      <para>Devices supporting the raw VBI capturing or output API set
+the <constant>V4L2_CAP_VBI_CAPTURE</constant> or
+<constant>V4L2_CAP_VBI_OUTPUT</constant> flags, respectively, in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. At least one of the
+read/write, streaming or asynchronous I/O methods must be
+supported. VBI devices may or may not have a tuner or modulator.</para>
+    </section>
+
+    <section>
+      <title>Supplemental Functions</title>
+
+      <para>VBI devices shall support <link linkend="video">video
+input or output</link>, <link linkend="tuner">tuner or
+modulator</link>, and <link linkend="control">controls</link> ioctls
+as needed. The <link linkend="standard">video standard</link> ioctls provide
+information vital to program a VBI device, therefore must be
+supported.</para>
+    </section>
+
+    <section>
+      <title>Raw VBI Format Negotiation</title>
+
+      <para>Raw VBI sampling abilities can vary, in particular the
+sampling frequency. To properly interpret the data V4L2 specifies an
+ioctl to query the sampling parameters. Moreover, to allow for some
+flexibility applications can also suggest different parameters.</para>
+
+      <para>As usual these parameters are <emphasis>not</emphasis>
+reset at &func-open; time to permit Unix tool chains, programming a
+device and then reading from it as if it was a plain file. Well
+written V4L2 applications should always ensure they really get what
+they want, requesting reasonable parameters and then checking if the
+actual parameters are suitable.</para>
+
+      <para>To query the current raw VBI capture parameters
+applications set the <structfield>type</structfield> field of a
+&v4l2-format; to <constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant> or
+<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>, and call the
+&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
+the &v4l2-vbi-format; <structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union.</para>
+
+      <para>To request different parameters applications set the
+<structfield>type</structfield> field of a &v4l2-format; as above and
+initialize all fields of the &v4l2-vbi-format;
+<structfield>vbi</structfield> member of the
+<structfield>fmt</structfield> union, or better just modify the
+results of <constant>VIDIOC_G_FMT</constant>, and call the
+&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers return
+an &EINVAL; only when the given parameters are ambiguous, otherwise
+they modify the parameters according to the hardware capabilites and
+return the actual parameters. When the driver allocates resources at
+this point, it may return an &EBUSY; to indicate the returned
+parameters are valid but the required resources are currently not
+available. That may happen for instance when the video and VBI areas
+to capture would overlap, or when the driver supports multiple opens
+and another process already requested VBI capturing or output. Anyway,
+applications must expect other resource allocation points which may
+return <errorcode>EBUSY</errorcode>, at the &VIDIOC-STREAMON; ioctl
+and the first read(), write() and select() call.</para>
+
+      <para>VBI devices must implement both the
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl, even if
+<constant>VIDIOC_S_FMT</constant> ignores all requests and always
+returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
+<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
+
+      <table pgwide="1" frame="none" id="v4l2-vbi-format">
+	<title>struct <structname>v4l2_vbi_format</structname></title>
+	<tgroup cols="3">
+	  &cs-str;
+	  <tbody valign="top">
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>sampling_rate</structfield></entry>
+	      <entry>Samples per second, i.&nbsp;e. unit 1 Hz.</entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>offset</structfield></entry>
+	      <entry><para>Horizontal offset of the VBI image,
+relative to the leading edge of the line synchronization pulse and
+counted in samples: The first sample in the VBI image will be located
+<structfield>offset</structfield> /
+<structfield>sampling_rate</structfield> seconds following the leading
+edge. See also <xref linkend="vbi-hsync" />.</para></entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>samples_per_line</structfield></entry>
+	      <entry></entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>sample_format</structfield></entry>
+	      <entry><para>Defines the sample format as in <xref
+linkend="pixfmt" />, a four-character-code.<footnote>
+		    <para>A few devices may be unable to
+sample VBI data at all but can extend the video capture window to the
+VBI region.</para>
+		  </footnote> Usually this is
+<constant>V4L2_PIX_FMT_GREY</constant>, i.&nbsp;e. each sample
+consists of 8 bits with lower values oriented towards the black level.
+Do not assume any other correlation of values with the signal level.
+For example, the MSB does not necessarily indicate if the signal is
+'high' or 'low' because 128 may not be the mean value of the
+signal. Drivers shall not convert the sample format by software.</para></entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>start</structfield>[2]</entry>
+	      <entry>This is the scanning system line number
+associated with the first line of the VBI image, of the first and the
+second field respectively. See <xref linkend="vbi-525" /> and
+<xref linkend="vbi-625" /> for valid values. VBI input drivers can
+return start values 0 if the hardware cannot reliable identify
+scanning lines, VBI acquisition may not require this
+information.</entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>count</structfield>[2]</entry>
+	      <entry>The number of lines in the first and second
+field image, respectively.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan"><para>Drivers should be as
+flexibility as possible. For example, it may be possible to extend or
+move the VBI capture window down to the picture area, implementing a
+'full field mode' to capture data service transmissions embedded in
+the picture.</para><para>An application can set the first or second
+<structfield>count</structfield> value to zero if no data is required
+from the respective field; <structfield>count</structfield>[1] if the
+scanning system is progressive, &ie; not interlaced. The
+corresponding start value shall be ignored by the application and
+driver. Anyway, drivers may not support single field capturing and
+return both count values non-zero.</para><para>Both
+<structfield>count</structfield> values set to zero, or line numbers
+outside the bounds depicted in <xref linkend="vbi-525" /> and <xref
+		    linkend="vbi-625" />, or a field image covering
+lines of two fields, are invalid and shall not be returned by the
+driver.</para><para>To initialize the <structfield>start</structfield>
+and <structfield>count</structfield> fields, applications must first
+determine the current video standard selection. The &v4l2-std-id; or
+the <structfield>framelines</structfield> field of &v4l2-standard; can
+be evaluated for this purpose.</para></entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>flags</structfield></entry>
+	      <entry>See <xref linkend="vbifmt-flags" /> below. Currently
+only drivers set flags, applications must set this field to
+zero.</entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>reserved</structfield>[2]</entry>
+	      <entry>This array is reserved for future extensions.
+Drivers and applications must set it to zero.</entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+
+      <table pgwide="1" frame="none" id="vbifmt-flags">
+	<title>Raw VBI Format Flags</title>
+	<tgroup cols="3">
+	  &cs-def;
+	  <tbody valign="top">
+	    <row>
+	      <entry><constant>V4L2_VBI_UNSYNC</constant></entry>
+	      <entry>0x0001</entry>
+	      <entry><para>This flag indicates hardware which does not
+properly distinguish between fields. Normally the VBI image stores the
+first field (lower scanning line numbers) first in memory. This may be
+a top or bottom field depending on the video standard. When this flag
+is set the first or second field may be stored first, however the
+fields are still in correct temporal order with the older field first
+in memory.<footnote>
+		  <para>Most VBI services transmit on both fields, but
+some have different semantics depending on the field number. These
+cannot be reliable decoded or encoded when
+<constant>V4L2_VBI_UNSYNC</constant> is set.</para>
+		</footnote></para></entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_VBI_INTERLACED</constant></entry>
+	      <entry>0x0002</entry>
+	      <entry>By default the two field images will be passed
+sequentially; all lines of the first field followed by all lines of
+the second field (compare <xref linkend="field-order" />
+<constant>V4L2_FIELD_SEQ_TB</constant> and
+<constant>V4L2_FIELD_SEQ_BT</constant>, whether the top or bottom
+field is first in memory depends on the video standard). When this
+flag is set, the two fields are interlaced (cf.
+<constant>V4L2_FIELD_INTERLACED</constant>). The first line of the
+first field followed by the first line of the second field, then the
+two second lines, and so on. Such a layout may be necessary when the
+hardware has been programmed to capture or output interlaced video
+images and is unable to separate the fields for VBI capturing at
+the same time. For simplicity setting this flag implies that both
+<structfield>count</structfield> values are equal and non-zero.</entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+
+      <figure id="vbi-hsync">
+	<title>Line synchronization</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="vbi_hsync.pdf" format="PS" />
+	  </imageobject>
+	  <imageobject>
+	    <imagedata fileref="vbi_hsync.gif" format="GIF" />
+	  </imageobject>
+	  <textobject>
+	    <phrase>Line synchronization diagram</phrase>
+	  </textobject>
+	</mediaobject>
+      </figure>
+
+      <figure id="vbi-525">
+	<title>ITU-R 525 line numbering (M/NTSC and M/PAL)</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="vbi_525.pdf" format="PS" />
+	  </imageobject>
+	  <imageobject>
+	    <imagedata fileref="vbi_525.gif" format="GIF" />
+	  </imageobject>
+	  <textobject>
+	    <phrase>NTSC field synchronization diagram</phrase>
+	  </textobject>
+	  <caption>
+	    <para>(1) For the purpose of this specification field 2
+starts in line 264 and not 263.5 because half line capturing is not
+supported.</para>
+	  </caption>
+	</mediaobject>
+      </figure>
+
+      <figure id="vbi-625">
+	<title>ITU-R 625 line numbering</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="vbi_625.pdf" format="PS" />
+	  </imageobject>
+	  <imageobject>
+	    <imagedata fileref="vbi_625.gif" format="GIF" />
+	  </imageobject>
+	  <textobject>
+	    <phrase>PAL/SECAM field synchronization diagram</phrase>
+	  </textobject>
+	  <caption>
+	    <para>(1) For the purpose of this specification field 2
+starts in line 314 and not 313.5 because half line capturing is not
+supported.</para>
+	  </caption>
+	</mediaobject>
+      </figure>
+
+      <para>Remember the VBI image format depends on the selected
+video standard, therefore the application must choose a new standard or
+query the current standard first. Attempts to read or write data ahead
+of format negotiation, or after switching the video standard which may
+invalidate the negotiated VBI parameters, should be refused by the
+driver. A format change during active I/O is not permitted.</para>
+    </section>
+
+    <section>
+      <title>Reading and writing VBI images</title>
+
+      <para>To assure synchronization with the field number and easier
+implementation, the smallest unit of data passed at a time is one
+frame, consisting of two fields of VBI images immediately following in
+memory.</para>
+
+      <para>The total size of a frame computes as follows:</para>
+
+      <programlisting>
+(<structfield>count</structfield>[0] + <structfield>count</structfield>[1]) *
+<structfield>samples_per_line</structfield> * sample size in bytes</programlisting>
+
+      <para>The sample size is most likely always one byte,
+applications must check the <structfield>sample_format</structfield>
+field though, to function properly with other drivers.</para>
+
+      <para>A VBI device may support <link
+      linkend="rw">read/write</link> and/or streaming (<link
+      linkend="mmap">memory mapping</link> or <link
+      linkend="userp">user pointer</link>) I/O. The latter bears the
+possibility of synchronizing video and
+VBI data by using buffer timestamps.</para>
+
+      <para>Remember the &VIDIOC-STREAMON; ioctl and the first read(),
+write() and select() call can be resource allocation points returning
+an &EBUSY; if the required hardware resources are temporarily
+unavailable, for example the device is already in use by another
+process.</para>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/dev-rds.xml b/Documentation/DocBook/v4l/dev-rds.xml
new file mode 100644
index 0000000..0869d70
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-rds.xml
@@ -0,0 +1,168 @@
+     <title>RDS Interface</title>
+
+      <para>The Radio Data System transmits supplementary
+information in binary format, for example the station name or travel
+information, on an inaudible audio subcarrier of a radio program. This
+interface is aimed at devices capable of receiving and decoding RDS
+information.</para>
+
+      <para>For more information see the core RDS standard <xref linkend="en50067" />
+and the RBDS standard <xref linkend="nrsc4" />.</para>
+
+      <para>Note that the RBDS standard as is used in the USA is almost identical
+to the RDS standard. Any RDS decoder can also handle RBDS. Only some of the fields
+have slightly different meanings. See the RBDS standard for more information.</para>
+
+      <para>The RBDS standard also specifies support for MMBS (Modified Mobile Search).
+This is a proprietary format which seems to be discontinued. The RDS interface does not
+support this format. Should support for MMBS (or the so-called 'E blocks' in general)
+be needed, then please contact the linux-media mailing list: &v4l-ml;.</para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>Devices supporting the RDS capturing API
+set the <constant>V4L2_CAP_RDS_CAPTURE</constant> flag in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl.
+Any tuner that supports RDS will set the
+<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
+field of &v4l2-tuner;.
+Whether an RDS signal is present can be detected by looking at
+the <structfield>rxsubchans</structfield> field of &v4l2-tuner;: the
+<constant>V4L2_TUNER_SUB_RDS</constant> will be set if RDS data was detected.</para>
+
+    <para>Devices supporting the RDS output API
+set the <constant>V4L2_CAP_RDS_OUTPUT</constant> flag in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl.
+Any modulator that supports RDS will set the
+<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
+field of &v4l2-modulator;.
+In order to enable the RDS transmission one must set the <constant>V4L2_TUNER_SUB_RDS</constant>
+bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;.</para>
+
+  </section>
+
+  <section>
+    <title>Reading RDS data</title>
+
+      <para>RDS data can be read from the radio device
+with the &func-read; function. The data is packed in groups of three bytes,
+as follows:</para>
+    <table frame="none" pgwide="1" id="v4l2-rds-data">
+      <title>struct
+<structname>v4l2_rds_data</structname></title>
+      <tgroup cols="3">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="1*" />
+	<colspec colname="c3" colwidth="5*" />
+	<tbody valign="top">
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>lsb</structfield></entry>
+	    <entry>Least Significant Byte of RDS Block</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>msb</structfield></entry>
+	    <entry>Most Significant Byte of RDS Block</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>block</structfield></entry>
+	    <entry>Block description</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+    <table frame="none" pgwide="1" id="v4l2-rds-block">
+      <title>Block description</title>
+      <tgroup cols="2">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="5*" />
+	<tbody valign="top">
+	  <row>
+	    <entry>Bits 0-2</entry>
+	    <entry>Block (aka offset) of the received data.</entry>
+	  </row>
+	  <row>
+	    <entry>Bits 3-5</entry>
+	    <entry>Deprecated. Currently identical to bits 0-2. Do not use these bits.</entry>
+	  </row>
+	  <row>
+	    <entry>Bit 6</entry>
+	    <entry>Corrected bit. Indicates that an error was corrected for this data block.</entry>
+	  </row>
+	  <row>
+	    <entry>Bit 7</entry>
+	    <entry>Error bit. Indicates that an uncorrectable error occurred during reception of this block.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="v4l2-rds-block-codes">
+      <title>Block defines</title>
+      <tgroup cols="3">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="1*" />
+	<colspec colname="c3" colwidth="5*" />
+	<tbody valign="top">
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_MSK</entry>
+	    <entry>7</entry>
+	    <entry>Mask for bits 0-2 to get the block ID.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_A</entry>
+	    <entry>0</entry>
+	    <entry>Block A.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_B</entry>
+	    <entry>1</entry>
+	    <entry>Block B.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_C</entry>
+	    <entry>2</entry>
+	    <entry>Block C.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_D</entry>
+	    <entry>3</entry>
+	    <entry>Block D.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_C_ALT</entry>
+	    <entry>4</entry>
+	    <entry>Block C'.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_INVALID</entry>
+	    <entry>7</entry>
+	    <entry>An invalid block.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_CORRECTED</entry>
+	    <entry>0x40</entry>
+	    <entry>A bit error was detected but corrected.</entry>
+	  </row>
+	  <row>
+	    <entry>V4L2_RDS_BLOCK_ERROR</entry>
+	    <entry>0x80</entry>
+	    <entry>An incorrectable error occurred.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </section>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/Documentation/DocBook/v4l/dev-sliced-vbi.xml b/Documentation/DocBook/v4l/dev-sliced-vbi.xml
new file mode 100644
index 0000000..69e789f
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-sliced-vbi.xml
@@ -0,0 +1,708 @@
+  <title>Sliced VBI Data Interface</title>
+
+  <para>VBI stands for Vertical Blanking Interval, a gap in the
+sequence of lines of an analog video signal. During VBI no picture
+information is transmitted, allowing some time while the electron beam
+of a cathode ray tube TV returns to the top of the screen.</para>
+
+  <para>Sliced VBI devices use hardware to demodulate data transmitted
+in the VBI. V4L2 drivers shall <emphasis>not</emphasis> do this by
+software, see also the <link linkend="raw-vbi">raw VBI
+interface</link>. The data is passed as short packets of fixed size,
+covering one scan line each. The number of packets per video frame is
+variable.</para>
+
+  <para>Sliced VBI capture and output devices are accessed through the
+same character special files as raw VBI devices. When a driver
+supports both interfaces, the default function of a
+<filename>/dev/vbi</filename> device is <emphasis>raw</emphasis> VBI
+capturing or output, and the sliced VBI function is only available
+after calling the &VIDIOC-S-FMT; ioctl as defined below. Likewise a
+<filename>/dev/video</filename> device may support the sliced VBI API,
+however the default function here is video capturing or output.
+Different file descriptors must be used to pass raw and sliced VBI
+data simultaneously, if this is supported by the driver.</para>
+
+  <section>
+    <title>Querying Capabilities</title>
+
+    <para>Devices supporting the sliced VBI capturing or output API
+set the <constant>V4L2_CAP_SLICED_VBI_CAPTURE</constant> or
+<constant>V4L2_CAP_SLICED_VBI_OUTPUT</constant> flag respectively, in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl. At least one of the
+read/write, streaming or asynchronous <link linkend="io">I/O
+methods</link> must be supported. Sliced VBI devices may have a tuner
+or modulator.</para>
+  </section>
+
+  <section>
+    <title>Supplemental Functions</title>
+
+    <para>Sliced VBI devices shall support <link linkend="video">video
+input or output</link> and <link linkend="tuner">tuner or
+modulator</link> ioctls if they have these capabilities, and they may
+support <link linkend="control">control</link> ioctls. The <link
+linkend="standard">video standard</link> ioctls provide information
+vital to program a sliced VBI device, therefore must be
+supported.</para>
+  </section>
+
+  <section id="sliced-vbi-format-negotitation">
+    <title>Sliced VBI Format Negotiation</title>
+
+    <para>To find out which data services are supported by the
+hardware applications can call the &VIDIOC-G-SLICED-VBI-CAP; ioctl.
+All drivers implementing the sliced VBI interface must support this
+ioctl. The results may differ from those of the &VIDIOC-S-FMT; ioctl
+when the number of VBI lines the hardware can capture or output per
+frame, or the number of services it can identify on a given line are
+limited. For example on PAL line 16 the hardware may be able to look
+for a VPS or Teletext signal, but not both at the same time.</para>
+
+    <para>To determine the currently selected services applications
+set the <structfield>type </structfield> field of &v4l2-format; to
+<constant> V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> or <constant>
+V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant>, and the &VIDIOC-G-FMT;
+ioctl fills the <structfield>fmt.sliced</structfield> member, a
+&v4l2-sliced-vbi-format;.</para>
+
+    <para>Applications can request different parameters by
+initializing or modifying the <structfield>fmt.sliced</structfield>
+member and calling the &VIDIOC-S-FMT; ioctl with a pointer to the
+<structname>v4l2_format</structname> structure.</para>
+
+    <para>The sliced VBI API is more complicated than the raw VBI API
+because the hardware must be told which VBI service to expect on each
+scan line. Not all services may be supported by the hardware on all
+lines (this is especially true for VBI output where Teletext is often
+unsupported and other services can only be inserted in one specific
+line). In many cases, however, it is sufficient to just set the
+<structfield>service_set</structfield> field to the required services
+and let the driver fill the <structfield>service_lines</structfield>
+array according to hardware capabilities. Only if more precise control
+is needed should the programmer set the
+<structfield>service_lines</structfield> array explicitly.</para>
+
+    <para>The &VIDIOC-S-FMT; ioctl modifies the parameters
+according to hardware capabilities. When the driver allocates
+resources at this point, it may return an &EBUSY; if the required
+resources are temporarily unavailable. Other resource allocation
+points which may return <errorcode>EBUSY</errorcode> can be the
+&VIDIOC-STREAMON; ioctl and the first &func-read;, &func-write; and
+&func-select; call.</para>
+
+    <table frame="none" pgwide="1" id="v4l2-sliced-vbi-format">
+      <title>struct
+<structname>v4l2_sliced_vbi_format</structname></title>
+      <tgroup cols="5">
+	<colspec colname="c1" colwidth="3*" />
+	<colspec colname="c2" colwidth="3*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="2*" />
+	<colspec colname="c5" colwidth="2*" />
+	<spanspec namest="c3" nameend="c5" spanname="hspan" />
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>service_set</structfield></entry>
+	    <entry spanname="hspan"><para>If
+<structfield>service_set</structfield> is non-zero when passed with
+&VIDIOC-S-FMT; or &VIDIOC-TRY-FMT;, the
+<structfield>service_lines</structfield> array will be filled by the
+driver according to the services specified in this field. For example,
+if <structfield>service_set</structfield> is initialized with
+<constant>V4L2_SLICED_TELETEXT_B | V4L2_SLICED_WSS_625</constant>, a
+driver for the cx25840 video decoder sets lines 7-22 of both
+fields<footnote><para>According to <link
+linkend="ets300706">ETS&nbsp;300&nbsp;706</link> lines 6-22 of the
+first field and lines 5-22 of the second field may carry Teletext
+data.</para></footnote> to <constant>V4L2_SLICED_TELETEXT_B</constant>
+and line 23 of the first field to
+<constant>V4L2_SLICED_WSS_625</constant>. If
+<structfield>service_set</structfield> is set to zero, then the values
+of <structfield>service_lines</structfield> will be used instead.
+</para><para>On return the driver sets this field to the union of all
+elements of the returned <structfield>service_lines</structfield>
+array. It may contain less services than requested, perhaps just one,
+if the hardware cannot handle more services simultaneously. It may be
+empty (zero) if none of the requested services are supported by the
+hardware.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u16</entry>
+	    <entry><structfield>service_lines</structfield>[2][24]</entry>
+	    <entry spanname="hspan"><para>Applications initialize this
+array with sets of data services the driver shall look for or insert
+on the respective scan line. Subject to hardware capabilities drivers
+return the requested set, a subset, which may be just a single
+service, or an empty set. When the hardware cannot handle multiple
+services on the same line the driver shall choose one. No assumptions
+can be made on which service the driver chooses.</para><para>Data
+services are defined in <xref linkend="vbi-services2" />. Array indices
+map to ITU-R line numbers (see also <xref linkend="vbi-525" /> and <xref
+		  linkend="vbi-625" />) as follows: <!-- No nested
+tables, sigh. --></para></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Element</entry>
+	    <entry>525 line systems</entry>
+	    <entry>625 line systems</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[0][1]</entry>
+	    <entry align="center">1</entry>
+	    <entry align="center">1</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[0][23]</entry>
+	    <entry align="center">23</entry>
+	    <entry align="center">23</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[1][1]</entry>
+	    <entry align="center">264</entry>
+	    <entry align="center">314</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[1][23]</entry>
+	    <entry align="center">286</entry>
+	    <entry align="center">336</entry>
+	  </row>
+	  <!-- End of line numbers table. -->
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry spanname="hspan">Drivers must set
+<structfield>service_lines</structfield>[0][0] and
+<structfield>service_lines</structfield>[1][0] to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>io_size</structfield></entry>
+	    <entry spanname="hspan">Maximum number of bytes passed by
+one &func-read; or &func-write; call, and the buffer size in bytes for
+the &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl. Drivers set this field to
+the size of &v4l2-sliced-vbi-data; times the number of non-zero
+elements in the returned <structfield>service_lines</structfield>
+array (that is the number of lines potentially carrying data).</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry spanname="hspan">This array is reserved for future
+extensions. Applications and drivers must set it to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- See also vidioc-g-sliced-vbi-cap.sgml -->
+    <table frame="none" pgwide="1" id="vbi-services2">
+      <title>Sliced VBI services</title>
+      <tgroup cols="5">
+	<colspec colname="c1" colwidth="2*" />
+	<colspec colname="c2" colwidth="1*" />
+	<colspec colname="c3" colwidth="1*" />
+	<colspec colname="c4" colwidth="2*" />
+	<colspec colname="c5" colwidth="2*" />
+	<spanspec namest="c3" nameend="c5" spanname="rlp" />
+	<thead>
+	  <row>
+	    <entry>Symbol</entry>
+	    <entry>Value</entry>
+	    <entry>Reference</entry>
+	    <entry>Lines, usually</entry>
+	    <entry>Payload</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_SLICED_TELETEXT_B</constant>
+(Teletext System B)</entry>
+	    <entry>0x0001</entry>
+	    <entry><xref linkend="ets300706" />, <xref linkend="itu653" /></entry>
+	    <entry>PAL/SECAM line 7-22, 320-335 (second field 7-22)</entry>
+	    <entry>Last 42 of the 45 byte Teletext packet, that is
+without clock run-in and framing code, lsb first transmitted.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_VPS</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry><xref linkend="ets300231" /></entry>
+	    <entry>PAL line 16</entry>
+	    <entry>Byte number 3 to 15 according to Figure 9 of
+ETS&nbsp;300&nbsp;231, lsb first transmitted.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_CAPTION_525</constant></entry>
+	    <entry>0x1000</entry>
+	    <entry><xref linkend="eia608" /></entry>
+	    <entry>NTSC line 21, 284 (second field 21)</entry>
+	    <entry>Two bytes in transmission order, including parity
+bit, lsb first transmitted.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_WSS_625</constant></entry>
+	    <entry>0x4000</entry>
+	    <entry><xref linkend="itu1119" />, <xref linkend="en300294" /></entry>
+	    <entry>PAL/SECAM line 23</entry>
+	    <entry><screen>
+Byte         0                 1
+      msb         lsb  msb           lsb
+ Bit  7 6 5 4 3 2 1 0  x x 13 12 11 10 9
+</screen></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_VBI_525</constant></entry>
+	    <entry>0x1000</entry>
+	    <entry spanname="rlp">Set of services applicable to 525
+line systems.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_VBI_625</constant></entry>
+	    <entry>0x4401</entry>
+	    <entry spanname="rlp">Set of services applicable to 625
+line systems.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <para>Drivers may return an &EINVAL; when applications attempt to
+read or write data without prior format negotiation, after switching
+the video standard (which may invalidate the negotiated VBI
+parameters) and after switching the video input (which may change the
+video standard as a side effect). The &VIDIOC-S-FMT; ioctl may return
+an &EBUSY; when applications attempt to change the format while i/o is
+in progress (between a &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; call,
+and after the first &func-read; or &func-write; call).</para>
+  </section>
+
+  <section>
+    <title>Reading and writing sliced VBI data</title>
+
+    <para>A single &func-read; or &func-write; call must pass all data
+belonging to one video frame. That is an array of
+<structname>v4l2_sliced_vbi_data</structname> structures with one or
+more elements and a total size not exceeding
+<structfield>io_size</structfield> bytes. Likewise in streaming I/O
+mode one buffer of <structfield>io_size</structfield> bytes must
+contain data of one video frame. The <structfield>id</structfield> of
+unused <structname>v4l2_sliced_vbi_data</structname> elements must be
+zero.</para>
+
+    <table frame="none" pgwide="1" id="v4l2-sliced-vbi-data">
+      <title>struct
+<structname>v4l2_sliced_vbi_data</structname></title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry>A flag from <xref linkend="vbi-services" />
+identifying the type of data in this packet. Only a single bit must be
+set. When the <structfield>id</structfield> of a captured packet is
+zero, the packet is empty and the contents of other fields are
+undefined. Applications shall ignore empty packets. When the
+<structfield>id</structfield> of a packet for output is zero the
+contents of the <structfield>data</structfield> field are undefined
+and the driver must no longer insert data on the requested
+<structfield>field</structfield> and
+<structfield>line</structfield>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>field</structfield></entry>
+	    <entry>The video field number this data has been captured
+from, or shall be inserted at. <constant>0</constant> for the first
+field, <constant>1</constant> for the second field.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>line</structfield></entry>
+	    <entry>The field (as opposed to frame) line number this
+data has been captured from, or shall be inserted at. See <xref
+	    linkend="vbi-525" /> and <xref linkend="vbi-625" /> for valid
+values. Sliced VBI capture devices can set the line number of all
+packets to <constant>0</constant> if the hardware cannot reliably
+identify scan lines. The field number must always be valid.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield></entry>
+	    <entry>This field is reserved for future extensions.
+Applications and drivers must set it to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>data</structfield>[48]</entry>
+	    <entry>The packet payload. See <xref
+	    linkend="vbi-services" /> for the contents and number of
+bytes passed for each data type. The contents of padding bytes at the
+end of this array are undefined, drivers and applications shall ignore
+them.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <para>Packets are always passed in ascending line number order,
+without duplicate line numbers. The &func-write; function and the
+&VIDIOC-QBUF; ioctl must return an &EINVAL; when applications violate
+this rule. They must also return an &EINVAL; when applications pass an
+incorrect field or line number, or a combination of
+<structfield>field</structfield>, <structfield>line</structfield> and
+<structfield>id</structfield> which has not been negotiated with the
+&VIDIOC-G-FMT; or &VIDIOC-S-FMT; ioctl. When the line numbers are
+unknown the driver must pass the packets in transmitted order. The
+driver can insert empty packets with <structfield>id</structfield> set
+to zero anywhere in the packet array.</para>
+
+    <para>To assure synchronization and to distinguish from frame
+dropping, when a captured frame does not carry any of the requested
+data services drivers must pass one or more empty packets. When an
+application fails to pass VBI data in time for output, the driver
+must output the last VPS and WSS packet again, and disable the output
+of Closed Caption and Teletext data, or output data which is ignored
+by Closed Caption and Teletext decoders.</para>
+
+    <para>A sliced VBI device may support <link
+linkend="rw">read/write</link> and/or streaming (<link
+linkend="mmap">memory mapping</link> and/or <link linkend="userp">user
+pointer</link>) I/O. The latter bears the possibility of synchronizing
+video and VBI data by using buffer timestamps.</para>
+
+  </section>
+
+  <section>
+    <title>Sliced VBI Data in MPEG Streams</title>
+
+    <para>If a device can produce an MPEG output stream, it may be
+capable of providing <link
+linkend="sliced-vbi-format-negotitation">negotiated sliced VBI
+services</link> as data embedded in the MPEG stream.  Users or
+applications control this sliced VBI data insertion with the <link
+linkend="v4l2-mpeg-stream-vbi-fmt">V4L2_CID_MPEG_STREAM_VBI_FMT</link>
+control.</para>
+
+    <para>If the driver does not provide the <link
+linkend="v4l2-mpeg-stream-vbi-fmt">V4L2_CID_MPEG_STREAM_VBI_FMT</link>
+control, or only allows that control to be set to <link
+linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
+V4L2_MPEG_STREAM_VBI_FMT_NONE</constant></link>, then the device
+cannot embed sliced VBI data in the MPEG stream.</para>
+
+    <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt">
+V4L2_CID_MPEG_STREAM_VBI_FMT</link> control does not implicitly set
+the device driver to capture nor cease capturing sliced VBI data.  The
+control only indicates to embed sliced VBI data in the MPEG stream, if
+an application has negotiated sliced VBI service be captured.</para>
+
+    <para>It may also be the case that a device can embed sliced VBI
+data in only certain types of MPEG streams: for example in an MPEG-2
+PS but not an MPEG-2 TS.  In this situation, if sliced VBI data
+insertion is requested, the sliced VBI data will be embedded in MPEG
+stream types when supported, and silently omitted from MPEG stream
+types where sliced VBI data insertion is not supported by the device.
+</para>
+
+    <para>The following subsections specify the format of the
+embedded sliced VBI data.</para>
+
+  <section>
+    <title>MPEG Stream Embedded, Sliced VBI Data Format: NONE</title>
+    <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
+V4L2_MPEG_STREAM_VBI_FMT_NONE</constant></link> embedded sliced VBI
+format shall be interpreted by drivers as a control to cease
+embedding sliced VBI data in MPEG streams.  Neither the device nor
+driver shall insert "empty" embedded sliced VBI data packets in the
+MPEG stream when this format is set.  No MPEG stream data structures
+are specified for this format.</para>
+  </section>
+
+  <section>
+    <title>MPEG Stream Embedded, Sliced VBI Data Format: IVTV</title>
+    <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
+V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant></link> embedded sliced VBI
+format, when supported, indicates to the driver to embed up to 36
+lines of sliced VBI data per frame in an MPEG-2 <emphasis>Private
+Stream 1 PES</emphasis> packet encapsulated in an MPEG-2 <emphasis>
+Program Pack</emphasis> in the MPEG stream.</para>
+
+    <para><emphasis>Historical context</emphasis>: This format
+specification originates from a custom, embedded, sliced VBI data
+format used by the <filename>ivtv</filename> driver.  This format
+has already been informally specified in the kernel sources in the
+file <filename>Documentation/video4linux/cx2341x/README.vbi</filename>
+.  The maximum size of the payload and other aspects of this format
+are driven by the CX23415 MPEG decoder's capabilities and limitations
+with respect to extracting, decoding, and displaying sliced VBI data
+embedded within an MPEG stream.</para>
+
+    <para>This format's use is <emphasis>not</emphasis> exclusive to
+the <filename>ivtv</filename> driver <emphasis>nor</emphasis>
+exclusive to CX2341x devices, as the sliced VBI data packet insertion
+into the MPEG stream is implemented in driver software.  At least the
+<filename>cx18</filename> driver provides sliced VBI data insertion
+into an MPEG-2 PS in this format as well.</para>
+
+    <para>The following definitions specify the payload of the
+MPEG-2 <emphasis>Private Stream 1 PES</emphasis> packets that contain
+sliced VBI data when <link linkend="v4l2-mpeg-stream-vbi-fmt">
+<constant>V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant></link> is set.
+(The MPEG-2 <emphasis>Private Stream 1 PES</emphasis> packet header
+and encapsulating MPEG-2 <emphasis>Program Pack</emphasis> header are
+not detailed here.  Please refer to the MPEG-2 specifications for
+details on those packet headers.)</para>
+
+    <para>The payload of the MPEG-2 <emphasis>Private Stream 1 PES
+</emphasis> packets that contain sliced VBI data is specified by
+&v4l2-mpeg-vbi-fmt-ivtv;.  The payload is variable
+length, depending on the actual number of lines of sliced VBI data
+present in a video frame.  The payload may be padded at the end with
+unspecified fill bytes to align the end of the payload to a 4-byte
+boundary.  The payload shall never exceed 1552 bytes (2 fields with
+18 lines/field with 43 bytes of data/line and a 4 byte magic number).
+</para>
+
+    <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-fmt-ivtv">
+      <title>struct <structname>v4l2_mpeg_vbi_fmt_ivtv</structname>
+      </title>
+      <tgroup cols="4">
+	&cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>magic</structfield>[4]</entry>
+	    <entry></entry>
+	    <entry>A "magic" constant from <xref
+	    linkend="v4l2-mpeg-vbi-fmt-ivtv-magic" /> that indicates
+this is a valid sliced VBI data payload and also indicates which
+member of the anonymous union, <structfield>itv0</structfield> or
+<structfield>ITV0</structfield>, to use for the payload data.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry>(anonymous)</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct <link linkend="v4l2-mpeg-vbi-itv0">
+	      <structname>v4l2_mpeg_vbi_itv0</structname></link>
+	    </entry>
+	    <entry><structfield>itv0</structfield></entry>
+	    <entry>The primary form of the sliced VBI data payload
+that contains anywhere from 1 to 35 lines of sliced VBI data.
+Line masks are provided in this form of the payload indicating
+which VBI lines are provided.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-1">
+	      <structname>v4l2_mpeg_vbi_ITV0</structname></link>
+	    </entry>
+	    <entry><structfield>ITV0</structfield></entry>
+	    <entry>An alternate form of the sliced VBI data payload
+used when 36 lines of sliced VBI data are present.  No line masks are
+provided in this form of the payload; all valid line mask bits are
+implcitly set.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-fmt-ivtv-magic">
+      <title>Magic Constants for &v4l2-mpeg-vbi-fmt-ivtv;
+	<structfield>magic</structfield> field</title>
+      <tgroup cols="3">
+	&cs-def;
+	<thead>
+	  <row>
+	    <entry align="left">Defined Symbol</entry>
+	    <entry align="left">Value</entry>
+	    <entry align="left">Description</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_MPEG_VBI_IVTV_MAGIC0</constant>
+	    </entry>
+	    <entry>"itv0"</entry>
+	    <entry>Indicates the <structfield>itv0</structfield>
+member of the union in &v4l2-mpeg-vbi-fmt-ivtv; is valid.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_MPEG_VBI_IVTV_MAGIC1</constant>
+	    </entry>
+	    <entry>"ITV0"</entry>
+	    <entry>Indicates the <structfield>ITV0</structfield>
+member of the union in &v4l2-mpeg-vbi-fmt-ivtv; is valid and
+that 36 lines of sliced VBI data are present.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0">
+      <title>struct <structname>v4l2_mpeg_vbi_itv0</structname>
+      </title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__le32</entry>
+	    <entry><structfield>linemask</structfield>[2]</entry>
+	    <entry><para>Bitmasks indicating the VBI service lines
+present.  These <structfield>linemask</structfield> values are stored
+in little endian byte order in the MPEG stream.  Some reference
+<structfield>linemask</structfield> bit positions with their
+corresponding VBI line number and video field are given below.
+b<subscript>0</subscript> indicates the least significant bit of a
+<structfield>linemask</structfield> value:<screen>
+<structfield>linemask</structfield>[0] b<subscript>0</subscript>:		line  6		first field
+<structfield>linemask</structfield>[0] b<subscript>17</subscript>:		line 23		first field
+<structfield>linemask</structfield>[0] b<subscript>18</subscript>:		line  6		second field
+<structfield>linemask</structfield>[0] b<subscript>31</subscript>:		line 19		second field
+<structfield>linemask</structfield>[1] b<subscript>0</subscript>:		line 20		second field
+<structfield>linemask</structfield>[1] b<subscript>3</subscript>:		line 23		second field
+<structfield>linemask</structfield>[1] b<subscript>4</subscript>-b<subscript>31</subscript>:	unused and set to 0</screen></para></entry>
+	  </row>
+	  <row>
+	    <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-line">
+	      <structname>v4l2_mpeg_vbi_itv0_line</structname></link>
+	    </entry>
+	    <entry><structfield>line</structfield>[35]</entry>
+	    <entry>This is a variable length array that holds from 1
+to 35 lines of sliced VBI data.  The sliced VBI data lines present
+correspond to the bits set in the <structfield>linemask</structfield>
+array, starting from b<subscript>0</subscript> of <structfield>
+linemask</structfield>[0] up through b<subscript>31</subscript> of
+<structfield>linemask</structfield>[0], and from b<subscript>0
+</subscript> of <structfield>linemask</structfield>[1] up through b
+<subscript>3</subscript> of <structfield>linemask</structfield>[1].
+<structfield>line</structfield>[0] corresponds to the first bit
+found set in the <structfield>linemask</structfield> array,
+<structfield>line</structfield>[1] corresponds to the second bit
+found set in the <structfield>linemask</structfield> array, etc.
+If no <structfield>linemask</structfield> array bits are set, then
+<structfield>line</structfield>[0] may contain one line of
+unspecified data that should be ignored by applications.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0-1">
+      <title>struct <structname>v4l2_mpeg_vbi_ITV0</structname>
+      </title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-line">
+	      <structname>v4l2_mpeg_vbi_itv0_line</structname></link>
+	    </entry>
+	    <entry><structfield>line</structfield>[36]</entry>
+	    <entry>A fixed length array of 36 lines of sliced VBI
+data.  <structfield>line</structfield>[0] through <structfield>line
+</structfield>[17] correspond to lines 6 through 23 of the
+first field.  <structfield>line</structfield>[18] through
+<structfield>line</structfield>[35] corresponds to lines 6
+through 23 of the second field.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0-line">
+      <title>struct <structname>v4l2_mpeg_vbi_itv0_line</structname>
+      </title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry>A line identifier value from
+<xref linkend="ITV0-Line-Identifier-Constants" /> that indicates
+the type of sliced VBI data stored on this line.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>data</structfield>[42]</entry>
+	    <entry>The sliced VBI data for the line.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="ITV0-Line-Identifier-Constants">
+      <title>Line Identifiers for struct <link
+      linkend="v4l2-mpeg-vbi-itv0-line"><structname>
+v4l2_mpeg_vbi_itv0_line</structname></link> <structfield>id
+</structfield> field</title>
+      <tgroup cols="3">
+	&cs-def;
+	<thead>
+	  <row>
+	    <entry align="left">Defined Symbol</entry>
+	    <entry align="left">Value</entry>
+	    <entry align="left">Description</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_MPEG_VBI_IVTV_TELETEXT_B</constant>
+	    </entry>
+	    <entry>1</entry>
+	    <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_MPEG_VBI_IVTV_CAPTION_525</constant>
+	    </entry>
+	    <entry>4</entry>
+	    <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_MPEG_VBI_IVTV_WSS_625</constant>
+	    </entry>
+	    <entry>5</entry>
+	    <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_MPEG_VBI_IVTV_VPS</constant>
+	    </entry>
+	    <entry>7</entry>
+	    <entry>Refer to <link linkend="vbi-services2">
+Sliced VBI services</link> for a description of the line payload.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </section>
+  </section>
+
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+ -->
diff --git a/Documentation/DocBook/v4l/dev-teletext.xml b/Documentation/DocBook/v4l/dev-teletext.xml
new file mode 100644
index 0000000..76184e8
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-teletext.xml
@@ -0,0 +1,40 @@
+  <title>Teletext Interface</title>
+
+  <para>This interface aims at devices receiving and demodulating
+Teletext data [<xref linkend="ets300706" />, <xref linkend="itu653" />], evaluating the
+Teletext packages and storing formatted pages in cache memory. Such
+devices are usually implemented as microcontrollers with serial
+interface (I<superscript>2</superscript>C) and can be found on older
+TV cards, dedicated Teletext decoding cards and home-brew devices
+connected to the PC parallel port.</para>
+
+  <para>The Teletext API was designed by Martin Buck. It is defined in
+the kernel header file <filename>linux/videotext.h</filename>, the
+specification is available from <ulink url="ftp://ftp.gwdg.de/pub/linux/misc/videotext/">
+ftp://ftp.gwdg.de/pub/linux/misc/videotext/</ulink>. (Videotext is the name of
+the German public television Teletext service.) Conventional character
+device file names are <filename>/dev/vtx</filename> and
+<filename>/dev/vttuner</filename>, with device number 83, 0 and 83, 16
+respectively. A similar interface exists for the Philips SAA5249
+Teletext decoder [specification?] with character device file names
+<filename>/dev/tlkN</filename>, device number 102, N.</para>
+
+  <para>Eventually the Teletext API was integrated into the V4L API
+with character device file names <filename>/dev/vtx0</filename> to
+<filename>/dev/vtx31</filename>, device major number 81, minor numbers
+192 to 223. For reference the V4L Teletext API specification is
+reproduced here in full: "Teletext interfaces talk the existing VTX
+API." Teletext devices with major number 83 and 102 will be removed in
+Linux 2.6.</para>
+
+  <para>There are no plans to replace the Teletext API or to integrate
+it into V4L2. Please write to the linux-media mailing list: &v4l-ml;
+when the need arises.</para>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/driver.xml b/Documentation/DocBook/v4l/driver.xml
new file mode 100644
index 0000000..1f7eea5
--- /dev/null
+++ b/Documentation/DocBook/v4l/driver.xml
@@ -0,0 +1,208 @@
+  <title>V4L2 Driver Programming</title>
+
+  <!-- This part defines the interface between the "videodev"
+    module and individual drivers. -->
+
+  <para>to do</para>
+<!--
+  <para>V4L2 is a two-layer driver system. The top layer is the "videodev"
+kernel module. When videodev initializes it registers as character device
+with major number 81, and it registers a set of file operations. All V4L2
+drivers are really clients of videodev, which calls V4L2 drivers through
+driver method functions. V4L2 drivers are also written as kernel modules.
+After probing the hardware they register one or more devices with
+videodev.</para>
+
+  <section id="driver-modules">
+    <title>Driver Modules</title>
+
+    <para>V4L2 driver modules must have an initialization function which is
+called after the module was loaded into kernel, an exit function whis is
+called before the module is removed.  When the driver is compiled into the
+kernel these functions called at system boot and shutdown time.</para>
+
+    <informalexample>
+      <programlisting>
+#include &lt;linux/module.h&gt;
+
+/* Export information about this module. For details and other useful
+   macros see <filename>linux/module.h</filename>. */
+MODULE_DESCRIPTION("my - driver for my hardware");
+MODULE_AUTHOR("Your name here");
+MODULE_LICENSE("GPL");
+
+static void
+my_module_exit (void)
+{
+	/* Free all resources allocated by my_module_init(). */
+}
+
+static int
+my_module_init (void)
+{
+	/* Bind the driver to the supported hardware, see
+	   <link linkend="driver-pci"> and
+	   <link linkend="driver-usb"> for examples. */
+
+	return 0; /* a negative value on error, 0 on success. */
+}
+
+/* Export module functions. */
+module_init (my_module_init);
+module_exit (my_module_exit);
+</programlisting>
+    </informalexample>
+
+    <para>Users can add parameters when kernel modules are inserted:</para>
+
+    <informalexample>
+      <programlisting>
+include &lt;linux/moduleparam.h&gt;
+
+static int my_option = 123;
+static int my_option_array[47];
+
+/* Export the symbol, an int, with access permissions 0664.
+   See <filename>linux/moduleparam.h</filename> for other types. */
+module_param (my_option, int, 0644);
+module_param_array (my_option_array, int, NULL, 0644);
+
+MODULE_PARM_DESC (my_option, "Does magic things, default 123");
+</programlisting>
+    </informalexample>
+
+    <para>One parameter should be supported by all V4L2 drivers, the minor
+number of the device it will register. Purpose is to predictably link V4L2
+drivers to device nodes if more than one video device is installed. Use the
+name of the device node followed by a "_nr" suffix, for example "video_nr"
+for <filename>/dev/video</filename>.</para>
+
+    <informalexample>
+      <programlisting>
+/* Minor number of the device, -1 to allocate the first unused. */
+static int video_nr = -1;
+
+module_param (video_nr, int, 0444);
+</programlisting>
+    </informalexample>
+  </section>
+
+  <section id="driver-pci">
+    <title>PCI Devices</title>
+
+    <para>PCI devices are initialized like this:</para>
+
+    <informalexample>
+      <programlisting>
+typedef struct {
+	/* State of one physical device. */
+} my_device;
+
+static int
+my_resume               (struct pci_dev *               pci_dev)
+{
+	/* Restore the suspended device to working state. */
+}
+
+static int
+my_suspend              (struct pci_dev *               pci_dev,
+			 pm_message_t                   state)
+{
+	/* This function is called before the system goes to sleep.
+	   Stop all DMAs and disable interrupts, then put the device
+	   into a low power state. For details see the kernel
+	   sources under <filename>Documentation/power</filename>. */
+
+	return 0; /* a negative value on error, 0 on success. */
+}
+
+static void __devexit
+my_remove               (struct pci_dev *               pci_dev)
+{
+	my_device *my = pci_get_drvdata (pci_dev);
+
+	/* Describe me. */
+}
+
+static int __devinit
+my_probe                (struct pci_dev *               pci_dev,
+			 const struct pci_device_id *   pci_id)
+{
+	my_device *my;
+
+	/* Describe me. */
+
+	/* You can allocate per-device data here and store a pointer
+	   to it in the pci_dev structure. */
+	my = ...;
+	pci_set_drvdata (pci_dev, my);
+
+	return 0; /* a negative value on error, 0 on success. */
+}
+
+/* A list of supported PCI devices. */
+static struct pci_device_id
+my_pci_device_ids [] = {
+	{ PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ 0 } /* end of list */
+};
+
+/* Load our module if supported PCI devices are installed. */
+MODULE_DEVICE_TABLE (pci, my_pci_device_ids);
+
+static struct pci_driver
+my_pci_driver = {
+	.name     = "my",
+	.id_table = my_pci_device_ids,
+
+	.probe    = my_probe,
+	.remove   = __devexit_p (my_remove),
+
+	/* Power management functions. */
+	.suspend  = my_suspend,
+	.resume   = my_resume,
+};
+
+static void
+my_module_exit          (void)
+{
+	pci_unregister_driver (&my_pci_driver);
+}
+
+static int
+my_module_init          (void)
+{
+	return pci_register_driver (&my_pci_driver);
+}
+</programlisting>
+    </informalexample>
+  </section>
+
+  <section id="driver-usb">
+    <title>USB Devices</title>
+    <para>to do</para>
+  </section>
+  <section id="driver-registering">
+    <title>Registering V4L2 Drivers</title>
+
+    <para>After a V4L2 driver probed the hardware it registers one or more
+devices with the videodev module.</para>
+  </section>
+  <section id="driver-file-ops">
+    <title>File Operations</title>
+    <para>to do</para>
+  </section>
+  <section id="driver-internal-api">
+    <title>Internal API</title>
+    <para>to do</para>
+  </section>
+-->
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/fdl-appendix.xml b/Documentation/DocBook/v4l/fdl-appendix.xml
new file mode 100644
index 0000000..b6ce50d
--- /dev/null
+++ b/Documentation/DocBook/v4l/fdl-appendix.xml
@@ -0,0 +1,671 @@
+<!--
+     The GNU Free Documentation License 1.1 in DocBook
+     Markup by Eric Baudais <baudais@okstate.edu>
+     Maintained by the GNOME Documentation Project
+     http://developer.gnome.org/projects/gdp
+     Version: 1.0.1
+     Last Modified: Nov 16, 2000
+-->
+
+<appendix id="fdl">
+  <appendixinfo>
+    <releaseinfo>
+      Version 1.1, March 2000
+    </releaseinfo>
+    <copyright>
+      <year>2000</year><holder>Free Software Foundation, Inc.</holder>
+    </copyright>
+    <legalnotice id="fdl-legalnotice">
+      <para>
+	<address>Free Software Foundation, Inc. <street>59 Temple Place,
+	Suite 330</street>, <city>Boston</city>, <state>MA</state>
+	<postcode>02111-1307</postcode>  <country>USA</country></address>
+	Everyone is permitted to copy and distribute verbatim copies of this
+	license document, but changing it is not allowed.
+      </para>
+    </legalnotice>
+  </appendixinfo>
+  <title>GNU Free Documentation License</title>
+
+  <sect1 id="fdl-preamble">
+    <title>0. PREAMBLE</title>
+    <para>
+      The purpose of this License is to make a manual, textbook, or
+      other written document <quote>free</quote> in the sense of
+      freedom: to assure everyone the effective freedom to copy and
+      redistribute it, with or without modifying it, either
+      commercially or noncommercially. Secondarily, this License
+      preserves for the author and publisher a way to get credit for
+      their work, while not being considered responsible for
+      modifications made by others.
+    </para>
+
+    <para>
+      This License is a kind of <quote>copyleft</quote>, which means
+      that derivative works of the document must themselves be free in
+      the same sense. It complements the GNU General Public License,
+      which is a copyleft license designed for free software.
+    </para>
+
+    <para>
+      We have designed this License in order to use it for manuals for
+      free software, because free software needs free documentation: a
+      free program should come with manuals providing the same
+      freedoms that the software does. But this License is not limited
+      to software manuals; it can be used for any textual work,
+      regardless of subject matter or whether it is published as a
+      printed book. We recommend this License principally for works
+      whose purpose is instruction or reference.
+    </para>
+  </sect1>
+  <sect1 id="fdl-section1">
+    <title>1. APPLICABILITY AND DEFINITIONS</title>
+    <para id="fdl-document">
+      This License applies to any manual or other work that contains a
+      notice placed by the copyright holder saying it can be
+      distributed under the terms of this License. The
+      <quote>Document</quote>, below, refers to any such manual or
+      work. Any member of the public is a licensee, and is addressed
+      as <quote>you</quote>.
+    </para>
+
+    <para id="fdl-modified">
+      A <quote>Modified Version</quote> of the Document means any work
+      containing the Document or a portion of it, either copied
+      verbatim, or with modifications and/or translated into another
+      language.
+    </para>
+
+    <para id="fdl-secondary">
+      A <quote>Secondary Section</quote> is a named appendix or a
+      front-matter section of the <link
+      linkend="fdl-document">Document</link> that deals exclusively
+      with the relationship of the publishers or authors of the
+      Document to the Document's overall subject (or to related
+      matters) and contains nothing that could fall directly within
+      that overall subject. (For example, if the Document is in part a
+      textbook of mathematics, a Secondary Section may not explain any
+      mathematics.)  The relationship could be a matter of historical
+      connection with the subject or with related matters, or of
+      legal, commercial, philosophical, ethical or political position
+      regarding them.
+    </para>
+
+    <para id="fdl-invariant">
+      The <quote>Invariant Sections</quote> are certain <link
+      linkend="fdl-secondary"> Secondary Sections</link> whose titles
+      are designated, as being those of Invariant Sections, in the
+      notice that says that the <link
+      linkend="fdl-document">Document</link> is released under this
+      License.
+    </para>
+
+    <para id="fdl-cover-texts">
+      The <quote>Cover Texts</quote> are certain short passages of
+      text that are listed, as Front-Cover Texts or Back-Cover Texts,
+      in the notice that says that the <link
+      linkend="fdl-document">Document</link> is released under this
+      License.
+    </para>
+
+    <para id="fdl-transparent">
+      A <quote>Transparent</quote> copy of the <link
+      linkend="fdl-document"> Document</link> means a machine-readable
+      copy, represented in a format whose specification is available
+      to the general public, whose contents can be viewed and edited
+      directly and straightforwardly with generic text editors or (for
+      images composed of pixels) generic paint programs or (for
+      drawings) some widely available drawing editor, and that is
+      suitable for input to text formatters or for automatic
+      translation to a variety of formats suitable for input to text
+      formatters. A copy made in an otherwise Transparent file format
+      whose markup has been designed to thwart or discourage
+      subsequent modification by readers is not Transparent.  A copy
+      that is not <quote>Transparent</quote> is called
+      <quote>Opaque</quote>.
+    </para>
+
+    <para>
+      Examples of suitable formats for Transparent copies include
+      plain ASCII without markup, Texinfo input format, LaTeX input
+      format, SGML or XML using a publicly available DTD, and
+      standard-conforming simple HTML designed for human
+      modification. Opaque formats include PostScript, PDF,
+      proprietary formats that can be read and edited only by
+      proprietary word processors, SGML or XML for which the DTD
+      and/or processing tools are not generally available, and the
+      machine-generated HTML produced by some word processors for
+      output purposes only.
+    </para>
+
+    <para id="fdl-title-page">
+      The <quote>Title Page</quote> means, for a printed book, the
+      title page itself, plus such following pages as are needed to
+      hold, legibly, the material this License requires to appear in
+      the title page. For works in formats which do not have any title
+      page as such, <quote>Title Page</quote> means the text near the
+      most prominent appearance of the work's title, preceding the
+      beginning of the body of the text.
+    </para>
+  </sect1>
+
+  <sect1 id="fdl-section2">
+    <title>2. VERBATIM COPYING</title>
+    <para>
+      You may copy and distribute the <link
+      linkend="fdl-document">Document</link> in any medium, either
+      commercially or noncommercially, provided that this License, the
+      copyright notices, and the license notice saying this License
+      applies to the Document are reproduced in all copies, and that
+      you add no other conditions whatsoever to those of this
+      License. You may not use technical measures to obstruct or
+      control the reading or further copying of the copies you make or
+      distribute. However, you may accept compensation in exchange for
+      copies. If you distribute a large enough number of copies you
+      must also follow the conditions in <link
+      linkend="fdl-section3">section 3</link>.
+    </para>
+
+    <para>
+      You may also lend copies, under the same conditions stated
+      above, and you may publicly display copies.
+    </para>
+    </sect1>
+
+  <sect1 id="fdl-section3">
+    <title>3. COPYING IN QUANTITY</title>
+    <para>
+      If you publish printed copies of the <link
+      linkend="fdl-document">Document</link> numbering more than 100,
+      and the Document's license notice requires <link
+      linkend="fdl-cover-texts">Cover Texts</link>, you must enclose
+      the copies in covers that carry, clearly and legibly, all these
+      Cover Texts: Front-Cover Texts on the front cover, and
+      Back-Cover Texts on the back cover. Both covers must also
+      clearly and legibly identify you as the publisher of these
+      copies. The front cover must present the full title with all
+      words of the title equally prominent and visible. You may add
+      other material on the covers in addition. Copying with changes
+      limited to the covers, as long as they preserve the title of the
+      <link linkend="fdl-document">Document</link> and satisfy these
+      conditions, can be treated as verbatim copying in other
+      respects.
+    </para>
+
+    <para>
+      If the required texts for either cover are too voluminous to fit
+      legibly, you should put the first ones listed (as many as fit
+      reasonably) on the actual cover, and continue the rest onto
+      adjacent pages.
+    </para>
+
+    <para>
+      If you publish or distribute <link
+      linkend="fdl-transparent">Opaque</link> copies of the <link
+      linkend="fdl-document">Document</link> numbering more than 100,
+      you must either include a machine-readable <link
+      linkend="fdl-transparent">Transparent</link> copy along with
+      each Opaque copy, or state in or with each Opaque copy a
+      publicly-accessible computer-network location containing a
+      complete Transparent copy of the Document, free of added
+      material, which the general network-using public has access to
+      download anonymously at no charge using public-standard network
+      protocols. If you use the latter option, you must take
+      reasonably prudent steps, when you begin distribution of Opaque
+      copies in quantity, to ensure that this Transparent copy will
+      remain thus accessible at the stated location until at least one
+      year after the last time you distribute an Opaque copy (directly
+      or through your agents or retailers) of that edition to the
+      public.
+    </para>
+
+    <para>
+      It is requested, but not required, that you contact the authors
+      of the <link linkend="fdl-document">Document</link> well before
+      redistributing any large number of copies, to give them a chance
+      to provide you with an updated version of the Document.
+    </para>
+    </sect1>
+
+  <sect1 id="fdl-section4">
+    <title>4. MODIFICATIONS</title>
+    <para>
+      You may copy and distribute a <link
+      linkend="fdl-modified">Modified Version</link> of the <link
+      linkend="fdl-document">Document</link> under the conditions of
+      sections <link linkend="fdl-section2">2</link> and <link
+      linkend="fdl-section3">3</link> above, provided that you release
+      the Modified Version under precisely this License, with the
+      Modified Version filling the role of the Document, thus
+      licensing distribution and modification of the Modified Version
+      to whoever possesses a copy of it. In addition, you must do
+      these things in the Modified Version:
+    </para>
+
+    <itemizedlist mark="opencircle">
+      <listitem>
+	<formalpara>
+	  <title>A</title>
+	  <para>
+	    Use in the <link linkend="fdl-title-page">Title
+	    Page</link> (and on the covers, if any) a title distinct
+	    from that of the <link
+	    linkend="fdl-document">Document</link>, and from those of
+	    previous versions (which should, if there were any, be
+	    listed in the History section of the Document). You may
+	    use the same title as a previous version if the original
+	    publisher of that version gives permission.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>B</title>
+	  <para>
+	    List on the <link linkend="fdl-title-page">Title
+	    Page</link>, as authors, one or more persons or entities
+	    responsible for authorship of the modifications in the
+	    <link linkend="fdl-modified">Modified Version</link>,
+	    together with at least five of the principal authors of
+	    the <link linkend="fdl-document">Document</link> (all of
+	    its principal authors, if it has less than five).
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>C</title>
+	  <para>
+	    State on the <link linkend="fdl-title-page">Title
+	    Page</link> the name of the publisher of the <link
+	    linkend="fdl-modified">Modified Version</link>, as the
+	    publisher.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>D</title>
+	  <para>
+	    Preserve all the copyright notices of the <link
+	    linkend="fdl-document">Document</link>.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>E</title>
+	  <para>
+	    Add an appropriate copyright notice for your modifications
+	    adjacent to the other copyright notices.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>F</title>
+	  <para>
+	    Include, immediately after the copyright notices, a
+	    license notice giving the public permission to use the
+	    <link linkend="fdl-modified">Modified Version</link> under
+	    the terms of this License, in the form shown in the
+	    Addendum below.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>G</title>
+	  <para>
+	    Preserve in that license notice the full lists of <link
+	    linkend="fdl-invariant"> Invariant Sections</link> and
+	    required <link linkend="fdl-cover-texts">Cover
+	    Texts</link> given in the <link
+	    linkend="fdl-document">Document's</link> license notice.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>H</title>
+	  <para>
+	    Include an unaltered copy of this License.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>I</title>
+	  <para>
+	    Preserve the section entitled <quote>History</quote>, and
+	    its title, and add to it an item stating at least the
+	    title, year, new authors, and publisher of the <link
+	    linkend="fdl-modified">Modified Version </link>as given on
+	    the <link linkend="fdl-title-page">Title Page</link>.  If
+	    there is no section entitled <quote>History</quote> in the
+	    <link linkend="fdl-document">Document</link>, create one
+	    stating the title, year, authors, and publisher of the
+	    Document as given on its Title Page, then add an item
+	    describing the Modified Version as stated in the previous
+	    sentence.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>J</title>
+	  <para>
+	    Preserve the network location, if any, given in the <link
+	    linkend="fdl-document">Document</link> for public access
+	    to a <link linkend="fdl-transparent">Transparent</link>
+	    copy of the Document, and likewise the network locations
+	    given in the Document for previous versions it was based
+	    on. These may be placed in the <quote>History</quote>
+	    section.  You may omit a network location for a work that
+	    was published at least four years before the Document
+	    itself, or if the original publisher of the version it
+	    refers to gives permission.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>K</title>
+	  <para>
+	    In any section entitled <quote>Acknowledgements</quote> or
+	    <quote>Dedications</quote>, preserve the section's title,
+	    and preserve in the section all the substance and tone of
+	    each of the contributor acknowledgements and/or
+	    dedications given therein.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>L</title>
+	  <para>
+	    Preserve all the <link linkend="fdl-invariant">Invariant
+	    Sections</link> of the <link
+	    linkend="fdl-document">Document</link>, unaltered in their
+	    text and in their titles.  Section numbers or the
+	    equivalent are not considered part of the section titles.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>M</title>
+	  <para>
+	    Delete any section entitled
+	    <quote>Endorsements</quote>. Such a section may not be
+	    included in the <link linkend="fdl-modified">Modified
+	    Version</link>.
+	  </para>
+	</formalpara>
+      </listitem>
+
+      <listitem>
+	<formalpara>
+	  <title>N</title>
+	  <para>
+	    Do not retitle any existing section as
+	    <quote>Endorsements</quote> or to conflict in title with
+	    any <link linkend="fdl-invariant">Invariant
+	    Section</link>.
+	  </para>
+	</formalpara>
+      </listitem>
+    </itemizedlist>
+
+    <para>
+      If the <link linkend="fdl-modified">Modified Version</link>
+      includes new front-matter sections or appendices that qualify as
+      <link linkend="fdl-secondary">Secondary Sections</link> and
+      contain no material copied from the Document, you may at your
+      option designate some or all of these sections as invariant. To
+      do this, add their titles to the list of <link
+      linkend="fdl-invariant">Invariant Sections</link> in the
+      Modified Version's license notice.  These titles must be
+      distinct from any other section titles.
+    </para>
+
+    <para>
+      You may add a section entitled <quote>Endorsements</quote>,
+      provided it contains nothing but endorsements of your <link
+      linkend="fdl-modified">Modified Version</link> by various
+      parties--for example, statements of peer review or that the text
+      has been approved by an organization as the authoritative
+      definition of a standard.
+    </para>
+
+    <para>
+      You may add a passage of up to five words as a <link
+      linkend="fdl-cover-texts">Front-Cover Text</link>, and a passage
+      of up to 25 words as a <link
+      linkend="fdl-cover-texts">Back-Cover Text</link>, to the end of
+      the list of <link linkend="fdl-cover-texts">Cover Texts</link>
+      in the <link linkend="fdl-modified">Modified Version</link>.
+      Only one passage of Front-Cover Text and one of Back-Cover Text
+      may be added by (or through arrangements made by) any one
+      entity. If the <link linkend="fdl-document">Document</link>
+      already includes a cover text for the same cover, previously
+      added by you or by arrangement made by the same entity you are
+      acting on behalf of, you may not add another; but you may
+      replace the old one, on explicit permission from the previous
+      publisher that added the old one.
+    </para>
+
+    <para>
+      The author(s) and publisher(s) of the <link
+      linkend="fdl-document">Document</link> do not by this License
+      give permission to use their names for publicity for or to
+      assert or imply endorsement of any <link
+      linkend="fdl-modified">Modified Version </link>.
+    </para>
+  </sect1>
+
+  <sect1 id="fdl-section5">
+    <title>5. COMBINING DOCUMENTS</title>
+    <para>
+      You may combine the <link linkend="fdl-document">Document</link>
+      with other documents released under this License, under the
+      terms defined in <link linkend="fdl-section4">section 4</link>
+      above for modified versions, provided that you include in the
+      combination all of the <link linkend="fdl-invariant">Invariant
+      Sections</link> of all of the original documents, unmodified,
+      and list them all as Invariant Sections of your combined work in
+      its license notice.
+    </para>
+
+    <para>
+      The combined work need only contain one copy of this License,
+      and multiple identical <link linkend="fdl-invariant">Invariant
+      Sections</link> may be replaced with a single copy. If there are
+      multiple Invariant Sections with the same name but different
+      contents, make the title of each such section unique by adding
+      at the end of it, in parentheses, the name of the original
+      author or publisher of that section if known, or else a unique
+      number. Make the same adjustment to the section titles in the
+      list of Invariant Sections in the license notice of the combined
+      work.
+    </para>
+
+    <para>
+      In the combination, you must combine any sections entitled
+      <quote>History</quote> in the various original documents,
+      forming one section entitled <quote>History</quote>; likewise
+      combine any sections entitled <quote>Acknowledgements</quote>,
+      and any sections entitled <quote>Dedications</quote>.  You must
+      delete all sections entitled <quote>Endorsements.</quote>
+    </para>
+    </sect1>
+
+  <sect1 id="fdl-section6">
+    <title>6. COLLECTIONS OF DOCUMENTS</title>
+    <para>
+      You may make a collection consisting of the <link
+      linkend="fdl-document">Document</link> and other documents
+      released under this License, and replace the individual copies
+      of this License in the various documents with a single copy that
+      is included in the collection, provided that you follow the
+      rules of this License for verbatim copying of each of the
+      documents in all other respects.
+    </para>
+
+    <para>
+      You may extract a single document from such a collection, and
+      dispbibute it individually under this License, provided you
+      insert a copy of this License into the extracted document, and
+      follow this License in all other respects regarding verbatim
+      copying of that document.
+    </para>
+    </sect1>
+
+  <sect1 id="fdl-section7">
+    <title>7. AGGREGATION WITH INDEPENDENT WORKS</title>
+    <para>
+      A compilation of the <link
+      linkend="fdl-document">Document</link> or its derivatives with
+      other separate and independent documents or works, in or on a
+      volume of a storage or distribution medium, does not as a whole
+      count as a <link linkend="fdl-modified">Modified Version</link>
+      of the Document, provided no compilation copyright is claimed
+      for the compilation.  Such a compilation is called an
+      <quote>aggregate</quote>, and this License does not apply to the
+      other self-contained works thus compiled with the Document , on
+      account of their being thus compiled, if they are not themselves
+      derivative works of the Document.  If the <link
+      linkend="fdl-cover-texts">Cover Text</link> requirement of <link
+      linkend="fdl-section3">section 3</link> is applicable to these
+      copies of the Document, then if the Document is less than one
+      quarter of the entire aggregate, the Document's Cover Texts may
+      be placed on covers that surround only the Document within the
+      aggregate. Otherwise they must appear on covers around the whole
+      aggregate.
+    </para>
+    </sect1>
+
+  <sect1 id="fdl-section8">
+    <title>8. TRANSLATION</title>
+    <para>
+      Translation is considered a kind of modification, so you may
+      distribute translations of the <link
+      linkend="fdl-document">Document</link> under the terms of <link
+      linkend="fdl-section4">section 4</link>. Replacing <link
+      linkend="fdl-invariant"> Invariant Sections</link> with
+      translations requires special permission from their copyright
+      holders, but you may include translations of some or all
+      Invariant Sections in addition to the original versions of these
+      Invariant Sections. You may include a translation of this
+      License provided that you also include the original English
+      version of this License. In case of a disagreement between the
+      translation and the original English version of this License,
+      the original English version will prevail.
+    </para>
+    </sect1>
+
+  <sect1 id="fdl-section9">
+    <title>9. TERMINATION</title>
+    <para>
+      You may not copy, modify, sublicense, or distribute the <link
+      linkend="fdl-document">Document</link> except as expressly
+      provided for under this License. Any other attempt to copy,
+      modify, sublicense or distribute the Document is void, and will
+      automatically terminate your rights under this License. However,
+      parties who have received copies, or rights, from you under this
+      License will not have their licenses terminated so long as such
+      parties remain in full compliance.
+    </para>
+    </sect1>
+
+  <sect1 id="fdl-section10">
+    <title>10. FUTURE REVISIONS OF THIS LICENSE</title>
+    <para>
+      The <ulink type="http"
+      url="http://www.gnu.org/fsf/fsf.html">Free Software
+      Foundation</ulink> may publish new, revised versions of the GNU
+      Free Documentation License from time to time. Such new versions
+      will be similar in spirit to the present version, but may differ
+      in detail to address new problems or concerns. See <ulink
+      type="http"
+      url="http://www.gnu.org/copyleft">http://www.gnu.org/copyleft/</ulink>.
+    </para>
+
+    <para>
+      Each version of the License is given a distinguishing version
+      number. If the <link linkend="fdl-document">Document</link>
+      specifies that a particular numbered version of this License
+      <quote>or any later version</quote> applies to it, you have the
+      option of following the terms and conditions either of that
+      specified version or of any later version that has been
+      published (not as a draft) by the Free Software Foundation. If
+      the Document does not specify a version number of this License,
+      you may choose any version ever published (not as a draft) by
+      the Free Software Foundation.
+    </para>
+  </sect1>
+
+  <sect1 id="fdl-using">
+    <title>Addendum</title>
+    <para>
+      To use this License in a document you have written, include a copy of
+      the License in the document and put the following copyright and
+      license notices just after the title page:
+    </para>
+
+    <blockquote>
+      <para>
+	Copyright &copy; YEAR YOUR NAME.
+      </para>
+      <para>
+	Permission is granted to copy, distribute and/or modify this
+	document under the terms of the GNU Free Documentation
+	License, Version 1.1 or any later version published by the
+	Free Software Foundation; with the <link
+	linkend="fdl-invariant">Invariant Sections</link> being LIST
+	THEIR TITLES, with the <link
+	linkend="fdl-cover-texts">Front-Cover Texts</link> being LIST,
+	and with the <link linkend="fdl-cover-texts">Back-Cover
+	Texts</link> being LIST.  A copy of the license is included in
+	the section entitled <quote>GNU Free Documentation
+	License</quote>.
+      </para>
+    </blockquote>
+
+    <para>
+      If you have no <link linkend="fdl-invariant">Invariant
+      Sections</link>, write <quote>with no Invariant Sections</quote>
+      instead of saying which ones are invariant.  If you have no
+      <link linkend="fdl-cover-texts">Front-Cover Texts</link>, write
+      <quote>no Front-Cover Texts</quote> instead of
+      <quote>Front-Cover Texts being LIST</quote>; likewise for <link
+      linkend="fdl-cover-texts">Back-Cover Texts</link>.
+    </para>
+
+    <para>
+      If your document contains nontrivial examples of program code,
+      we recommend releasing these examples in parallel under your
+      choice of free software license, such as the <ulink type="http"
+      url="http://www.gnu.org/copyleft/gpl.html"> GNU General Public
+      License</ulink>, to permit their use in free software.
+    </para>
+  </sect1>
+</appendix>
+
+
+
+
+
+
diff --git a/Documentation/DocBook/v4l/fieldseq_bt.gif b/Documentation/DocBook/v4l/fieldseq_bt.gif
new file mode 100644
index 0000000..60e8569
Binary files /dev/null and b/Documentation/DocBook/v4l/fieldseq_bt.gif differ
diff --git a/Documentation/DocBook/v4l/fieldseq_bt.pdf b/Documentation/DocBook/v4l/fieldseq_bt.pdf
new file mode 100644
index 0000000..26598b2
Binary files /dev/null and b/Documentation/DocBook/v4l/fieldseq_bt.pdf differ
diff --git a/Documentation/DocBook/v4l/fieldseq_tb.gif b/Documentation/DocBook/v4l/fieldseq_tb.gif
new file mode 100644
index 0000000..718492f
Binary files /dev/null and b/Documentation/DocBook/v4l/fieldseq_tb.gif differ
diff --git a/Documentation/DocBook/v4l/fieldseq_tb.pdf b/Documentation/DocBook/v4l/fieldseq_tb.pdf
new file mode 100644
index 0000000..4965b22
Binary files /dev/null and b/Documentation/DocBook/v4l/fieldseq_tb.pdf differ
diff --git a/Documentation/DocBook/v4l/func-close.xml b/Documentation/DocBook/v4l/func-close.xml
new file mode 100644
index 0000000..dfb41cb
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-close.xml
@@ -0,0 +1,70 @@
+<refentry id="func-close">
+  <refmeta>
+    <refentrytitle>V4L2 close()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-close</refname>
+    <refpurpose>Close a V4L2 device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>close</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Closes the device. Any I/O in progress is terminated and
+resources associated with the file descriptor are freed. However data
+format parameters, current input or output, control values or other
+properties remain unchanged.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>The function returns <returnvalue>0</returnvalue> on
+success, <returnvalue>-1</returnvalue> on failure and the
+<varname>errno</varname> is set appropriately. Possible error
+codes:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is not a valid open file
+descriptor.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-ioctl.xml b/Documentation/DocBook/v4l/func-ioctl.xml
new file mode 100644
index 0000000..00f9690
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-ioctl.xml
@@ -0,0 +1,146 @@
+<refentry id="func-ioctl">
+  <refmeta>
+    <refentrytitle>V4L2 ioctl()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-ioctl</refname>
+    <refpurpose>Program a V4L2 device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;sys/ioctl.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>void *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>V4L2 ioctl request code as defined in the <link
+linkend="videodev">videodev.h</link> header file, for example
+VIDIOC_QUERYCAP.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para>Pointer to a function parameter, usually a structure.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The <function>ioctl()</function> function is used to program
+V4L2 devices. The argument <parameter>fd</parameter> must be an open
+file descriptor. An ioctl <parameter>request</parameter> has encoded
+in it whether the argument is an input, output or read/write
+parameter, and the size of the argument <parameter>argp</parameter> in
+bytes. Macros and defines specifying V4L2 ioctl requests are located
+in the <link linkend="videodev">videodev.h</link> header file.
+Applications should use their own copy, not include the version in the
+kernel sources on the system they compile on. All V4L2 ioctl requests,
+their respective function and parameters are specified in <xref
+	linkend="user-func" />.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success the <function>ioctl()</function> function returns
+<returnvalue>0</returnvalue> and does not reset the
+<varname>errno</varname> variable. On failure
+<returnvalue>-1</returnvalue> is returned, when the ioctl takes an
+output or read/write parameter it remains unmodified, and the
+<varname>errno</varname> variable is set appropriately. See below for
+possible error codes. Generic errors like <errorcode>EBADF</errorcode>
+or <errorcode>EFAULT</errorcode> are not listed in the sections
+discussing individual ioctl requests.</para>
+    <para>Note ioctls may return undefined error codes. Since errors
+may have side effects such as a driver reset applications should
+abort on unexpected errors.</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is not a valid open file
+descriptor.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The property cannot be changed right now. Typically
+this error code is returned when I/O is in progress or the driver
+supports multiple opens and another process locked the property.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EFAULT</errorcode></term>
+	<listitem>
+	  <para><parameter>argp</parameter> references an inaccessible
+memory area.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOTTY</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is  not  associated  with  a
+character special device.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <parameter>request</parameter> or the data pointed
+to by <parameter>argp</parameter> is not valid. This is a very common
+error code, see the individual ioctl requests listed in <xref
+	      linkend="user-func" /> for actual causes.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>Not enough physical or virtual memory was available to
+complete the request.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ERANGE</errorcode></term>
+	<listitem>
+	  <para>The application attempted to set a control with the
+&VIDIOC-S-CTRL; ioctl to a value which is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-mmap.xml b/Documentation/DocBook/v4l/func-mmap.xml
new file mode 100644
index 0000000..2e2fc39
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-mmap.xml
@@ -0,0 +1,185 @@
+<refentry id="func-mmap">
+  <refmeta>
+    <refentrytitle>V4L2 mmap()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-mmap</refname>
+    <refpurpose>Map device memory into application address space</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+#include &lt;unistd.h&gt;
+#include &lt;sys/mman.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>void *<function>mmap</function></funcdef>
+	<paramdef>void *<parameter>start</parameter></paramdef>
+	<paramdef>size_t <parameter>length</parameter></paramdef>
+	<paramdef>int <parameter>prot</parameter></paramdef>
+	<paramdef>int <parameter>flags</parameter></paramdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>off_t <parameter>offset</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+    <variablelist>
+      <varlistentry>
+	<term><parameter>start</parameter></term>
+	<listitem>
+	  <para>Map the buffer to this address in the
+application's address space. When the <constant>MAP_FIXED</constant>
+flag is specified, <parameter>start</parameter> must be a multiple of the
+pagesize and mmap will fail when the specified address
+cannot be used. Use of this option is discouraged; applications should
+just specify a <constant>NULL</constant> pointer here.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>length</parameter></term>
+	<listitem>
+	  <para>Length of the memory area to map. This must be the
+same value as returned by the driver in the &v4l2-buffer;
+<structfield>length</structfield> field.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>prot</parameter></term>
+	<listitem>
+	  <para>The <parameter>prot</parameter> argument describes the
+desired memory protection. Regardless of the device type and the
+direction of data exchange it should be set to
+<constant>PROT_READ</constant> | <constant>PROT_WRITE</constant>,
+permitting read and write access to image buffers. Drivers should
+support at least this combination of flags. Note the Linux
+<filename>video-buf</filename> kernel module, which is used by the
+bttv, saa7134, saa7146, cx88 and vivi driver supports only
+<constant>PROT_READ</constant> | <constant>PROT_WRITE</constant>. When
+the driver does not support the desired protection the
+<function>mmap()</function> function fails.</para>
+	  <para>Note device memory accesses (&eg; the memory on a
+graphics card with video capturing hardware) may incur a performance
+penalty compared to main memory accesses, or reads may be
+significantly slower than writes or vice versa. Other I/O methods may
+be more efficient in this case.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>flags</parameter></term>
+	<listitem>
+	  <para>The <parameter>flags</parameter> parameter
+specifies the type of the mapped object, mapping options and whether
+modifications made to the mapped copy of the page are private to the
+process or are to be shared with other references.</para>
+	  <para><constant>MAP_FIXED</constant> requests that the
+driver selects no other address than the one specified. If the
+specified address cannot be used, <function>mmap()</function> will fail. If
+<constant>MAP_FIXED</constant> is specified,
+<parameter>start</parameter> must be a multiple of the pagesize. Use
+of this option is discouraged.</para>
+	  <para>One of the <constant>MAP_SHARED</constant> or
+<constant>MAP_PRIVATE</constant> flags must be set.
+<constant>MAP_SHARED</constant> allows applications to share the
+mapped memory with other (&eg; child-) processes. Note the Linux
+<filename>video-buf</filename> module which is used by the bttv,
+saa7134, saa7146, cx88 and vivi driver supports only
+<constant>MAP_SHARED</constant>. <constant>MAP_PRIVATE</constant>
+requests copy-on-write semantics. V4L2 applications should not set the
+<constant>MAP_PRIVATE</constant>, <constant>MAP_DENYWRITE</constant>,
+<constant>MAP_EXECUTABLE</constant> or <constant>MAP_ANON</constant>
+flag.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>offset</parameter></term>
+	<listitem>
+	  <para>Offset of the buffer in device memory. This must be the
+same value as returned by the driver in the &v4l2-buffer;
+<structfield>m</structfield> union <structfield>offset</structfield> field.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The <function>mmap()</function> function asks to map
+<parameter>length</parameter> bytes starting at
+<parameter>offset</parameter> in the memory of the device specified by
+<parameter>fd</parameter> into the application address space,
+preferably at address <parameter>start</parameter>. This latter
+address is a hint only, and is usually specified as 0.</para>
+
+    <para>Suitable length and offset parameters are queried with the
+&VIDIOC-QUERYBUF; ioctl. Buffers must be allocated with the
+&VIDIOC-REQBUFS; ioctl before they can be queried.</para>
+
+    <para>To unmap buffers the &func-munmap; function is used.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success <function>mmap()</function> returns a pointer to
+the mapped buffer. On error <constant>MAP_FAILED</constant> (-1) is
+returned, and the <varname>errno</varname> variable is set
+appropriately. Possible error codes are:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is not a valid file
+descriptor.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EACCES</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is
+not open for reading and writing.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <parameter>start</parameter> or
+<parameter>length</parameter> or <parameter>offset</parameter> are not
+suitable. (E.&nbsp;g. they are too large, or not aligned on a
+<constant>PAGESIZE</constant> boundary.)</para>
+	  <para>The <parameter>flags</parameter> or
+<parameter>prot</parameter> value is not supported.</para>
+	  <para>No buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>Not enough physical or virtual memory was available to
+complete the request.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-munmap.xml b/Documentation/DocBook/v4l/func-munmap.xml
new file mode 100644
index 0000000..502ed49
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-munmap.xml
@@ -0,0 +1,83 @@
+<refentry id="func-munmap">
+  <refmeta>
+    <refentrytitle>V4L2 munmap()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-munmap</refname>
+    <refpurpose>Unmap device memory</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+#include &lt;unistd.h&gt;
+#include &lt;sys/mman.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>munmap</function></funcdef>
+	<paramdef>void *<parameter>start</parameter></paramdef>
+	<paramdef>size_t <parameter>length</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+  <refsect1>
+    <title>Arguments</title>
+    <variablelist>
+      <varlistentry>
+	<term><parameter>start</parameter></term>
+	<listitem>
+	  <para>Address of the mapped buffer as returned by the
+&func-mmap; function.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>length</parameter></term>
+	<listitem>
+	  <para>Length of the mapped buffer. This must be the same
+value as given to <function>mmap()</function> and returned by the
+driver in the &v4l2-buffer; <structfield>length</structfield>
+field.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Unmaps a previously with the &func-mmap; function mapped
+buffer and frees it, if possible. <!-- ? This function (not freeing)
+has no impact on I/O in progress, specifically it does not imply
+&VIDIOC-STREAMOFF; to terminate I/O. Unmapped buffers can still be
+enqueued, dequeued or queried, they are just not accessible by the
+application.--></para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success <function>munmap()</function> returns 0, on
+failure -1 and the <varname>errno</varname> variable is set
+appropriately:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <parameter>start</parameter> or
+<parameter>length</parameter> is incorrect, or no buffers have been
+mapped yet.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-open.xml b/Documentation/DocBook/v4l/func-open.xml
new file mode 100644
index 0000000..7595d07
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-open.xml
@@ -0,0 +1,121 @@
+<refentry id="func-open">
+  <refmeta>
+    <refentrytitle>V4L2 open()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-open</refname>
+    <refpurpose>Open a V4L2 device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;fcntl.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>open</function></funcdef>
+	<paramdef>const char *<parameter>device_name</parameter></paramdef>
+	<paramdef>int <parameter>flags</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>device_name</parameter></term>
+	<listitem>
+	  <para>Device to be opened.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>flags</parameter></term>
+	<listitem>
+	  <para>Open flags. Access mode must be
+<constant>O_RDWR</constant>. This is just a technicality, input devices
+still support only reading and output devices only writing.</para>
+	  <para>When the <constant>O_NONBLOCK</constant> flag is
+given, the read() function and the &VIDIOC-DQBUF; ioctl will return
+the &EAGAIN; when no data is available or no buffer is in the driver
+outgoing queue, otherwise these functions block until data becomes
+available. All V4L2 drivers exchanging data with applications must
+support the <constant>O_NONBLOCK</constant> flag.</para>
+	  <para>Other flags have no effect.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+  <refsect1>
+    <title>Description</title>
+
+    <para>To open a V4L2 device applications call
+<function>open()</function> with the desired device name. This
+function has no side effects; all data format parameters, current
+input or output, control values or other properties remain unchanged.
+At the first <function>open()</function> call after loading the driver
+they will be reset to default values, drivers are never in an
+undefined state.</para>
+  </refsect1>
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success <function>open</function> returns the new file
+descriptor. On error -1 is returned, and the <varname>errno</varname>
+variable is set appropriately. Possible error codes are:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EACCES</errorcode></term>
+	<listitem>
+	  <para>The caller has no permission to access the
+device.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The driver does not support multiple opens and the
+device is already in use.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENXIO</errorcode></term>
+	<listitem>
+	  <para>No device corresponding to this device special file
+exists.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>Not enough kernel memory was available to complete the
+request.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EMFILE</errorcode></term>
+	<listitem>
+	  <para>The  process  already  has  the  maximum number of
+files open.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENFILE</errorcode></term>
+	<listitem>
+	  <para>The limit on the total number of files open on the
+system has been reached.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-poll.xml b/Documentation/DocBook/v4l/func-poll.xml
new file mode 100644
index 0000000..ec3c718
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-poll.xml
@@ -0,0 +1,127 @@
+<refentry id="func-poll">
+  <refmeta>
+    <refentrytitle>V4L2 poll()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-poll</refname>
+    <refpurpose>Wait for some event on a file descriptor</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;sys/poll.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>poll</function></funcdef>
+	<paramdef>struct pollfd *<parameter>ufds</parameter></paramdef>
+	<paramdef>unsigned int <parameter>nfds</parameter></paramdef>
+	<paramdef>int <parameter>timeout</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>With the <function>poll()</function> function applications
+can suspend execution until the driver has captured data or is ready
+to accept data for output.</para>
+
+    <para>When streaming I/O has been negotiated this function waits
+until a buffer has been filled or displayed and can be dequeued with
+the &VIDIOC-DQBUF; ioctl. When buffers are already in the outgoing
+queue of the driver the function returns immediately.</para>
+
+    <para>On success <function>poll()</function> returns the number of
+file descriptors that have been selected (that is, file descriptors
+for which the <structfield>revents</structfield> field of the
+respective <structname>pollfd</structname> structure is non-zero).
+Capture devices set the <constant>POLLIN</constant> and
+<constant>POLLRDNORM</constant> flags in the
+<structfield>revents</structfield> field, output devices the
+<constant>POLLOUT</constant> and <constant>POLLWRNORM</constant>
+flags. When the function timed out it returns a value of zero, on
+failure it returns <returnvalue>-1</returnvalue> and the
+<varname>errno</varname> variable is set appropriately. When the
+application did not call &VIDIOC-QBUF; or &VIDIOC-STREAMON; yet the
+<function>poll()</function> function succeeds, but sets the
+<constant>POLLERR</constant> flag in the
+<structfield>revents</structfield> field.</para>
+
+    <para>When use of the <function>read()</function> function has
+been negotiated and the driver does not capture yet, the
+<function>poll</function> function starts capturing. When that fails
+it returns a <constant>POLLERR</constant> as above. Otherwise it waits
+until data has been captured and can be read. When the driver captures
+continuously (as opposed to, for example, still images) the function
+may return immediately.</para>
+
+    <para>When use of the <function>write()</function> function has
+been negotiated the <function>poll</function> function just waits
+until the driver is ready for a non-blocking
+<function>write()</function> call.</para>
+
+    <para>All drivers implementing the <function>read()</function> or
+<function>write()</function> function or streaming I/O must also
+support the <function>poll()</function> function.</para>
+
+    <para>For more details see the
+<function>poll()</function> manual page.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, <function>poll()</function> returns the number
+structures which have non-zero <structfield>revents</structfield>
+fields, or zero if the call timed out. On error
+<returnvalue>-1</returnvalue> is returned, and the
+<varname>errno</varname> variable is set appropriately:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para>One or more of the <parameter>ufds</parameter> members
+specify an invalid file descriptor.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The driver does not support multiple read or write
+streams and the device is already in use.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EFAULT</errorcode></term>
+	<listitem>
+	  <para><parameter>ufds</parameter> references an inaccessible
+memory area.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINTR</errorcode></term>
+	<listitem>
+	  <para>The call was interrupted by a signal.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <parameter>nfds</parameter> argument is greater
+than <constant>OPEN_MAX</constant>.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-read.xml b/Documentation/DocBook/v4l/func-read.xml
new file mode 100644
index 0000000..a5089bf
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-read.xml
@@ -0,0 +1,189 @@
+<refentry id="func-read">
+  <refmeta>
+    <refentrytitle>V4L2 read()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-read</refname>
+    <refpurpose>Read from a V4L2 device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>ssize_t <function>read</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>void *<parameter>buf</parameter></paramdef>
+	<paramdef>size_t <parameter>count</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>buf</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>count</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>read()</function> attempts to read up to
+<parameter>count</parameter> bytes from file descriptor
+<parameter>fd</parameter> into the buffer starting at
+<parameter>buf</parameter>. The layout of the data in the buffer is
+discussed in the respective device interface section, see ##. If <parameter>count</parameter> is zero,
+<function>read()</function> returns zero and has no other results. If
+<parameter>count</parameter> is greater than
+<constant>SSIZE_MAX</constant>, the result is unspecified. Regardless
+of the <parameter>count</parameter> value each
+<function>read()</function> call will provide at most one frame (two
+fields) worth of data.</para>
+
+    <para>By default <function>read()</function> blocks until data
+becomes available. When the <constant>O_NONBLOCK</constant> flag was
+given to the &func-open; function it
+returns immediately with an &EAGAIN; when no data is available. The
+&func-select; or &func-poll; functions
+can always be used to suspend execution until data becomes available. All
+drivers supporting the <function>read()</function> function must also
+support <function>select()</function> and
+<function>poll()</function>.</para>
+
+    <para>Drivers can implement read functionality in different
+ways, using a single or multiple buffers and discarding the oldest or
+newest frames once the internal buffers are filled.</para>
+
+    <para><function>read()</function> never returns a "snapshot" of a
+buffer being filled. Using a single buffer the driver will stop
+capturing when the application starts reading the buffer until the
+read is finished. Thus only the period of the vertical blanking
+interval is available for reading, or the capture rate must fall below
+the nominal frame rate of the video standard.</para>
+
+<para>The behavior of
+<function>read()</function> when called during the active picture
+period or the vertical blanking separating the top and bottom field
+depends on the discarding policy. A driver discarding the oldest
+frames keeps capturing into an internal buffer, continuously
+overwriting the previously, not read frame, and returns the frame
+being received at the time of the <function>read()</function> call as
+soon as it is complete.</para>
+
+    <para>A driver discarding the newest frames stops capturing until
+the next <function>read()</function> call. The frame being received at
+<function>read()</function> time is discarded, returning the following
+frame instead. Again this implies a reduction of the capture rate to
+one half or less of the nominal frame rate. An example of this model
+is the video read mode of the bttv driver, initiating a DMA to user
+memory when <function>read()</function> is called and returning when
+the DMA finished.</para>
+
+    <para>In the multiple buffer model drivers maintain a ring of
+internal buffers, automatically advancing to the next free buffer.
+This allows continuous capturing when the application can empty the
+buffers fast enough. Again, the behavior when the driver runs out of
+free buffers depends on the discarding policy.</para>
+
+    <para>Applications can get and set the number of buffers used
+internally by the driver with the &VIDIOC-G-PARM; and &VIDIOC-S-PARM;
+ioctls. They are optional, however. The discarding policy is not
+reported and cannot be changed. For minimum requirements see <xref
+	linkend="devices" />.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, the number of bytes read is returned. It is not
+an error if this number is smaller than the number of bytes requested,
+or the amount of data required for one frame. This may happen for
+example because <function>read()</function> was interrupted by a
+signal. On error, -1 is returned, and the <varname>errno</varname>
+variable is set appropriately. In this case the next read will start
+at the beginning of a new frame. Possible error codes are:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EAGAIN</errorcode></term>
+	<listitem>
+	  <para>Non-blocking I/O has been selected using
+O_NONBLOCK and no data was immediately available for reading.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is not a valid file
+descriptor or is not open for reading, or the process already has the
+maximum number of files open.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The driver does not support multiple read streams and the
+device is already in use.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EFAULT</errorcode></term>
+	<listitem>
+	  <para><parameter>buf</parameter> references an inaccessible
+memory area.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINTR</errorcode></term>
+	<listitem>
+	  <para>The call was interrupted by a signal before any
+data was read.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EIO</errorcode></term>
+	<listitem>
+	  <para>I/O error. This indicates some hardware problem or a
+failure to communicate with a remote device (USB camera etc.).</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <function>read()</function> function is not
+supported by this driver, not on this device, or generally not on this
+type of device.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-select.xml b/Documentation/DocBook/v4l/func-select.xml
new file mode 100644
index 0000000..b671362
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-select.xml
@@ -0,0 +1,138 @@
+<refentry id="func-select">
+  <refmeta>
+    <refentrytitle>V4L2 select()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-select</refname>
+    <refpurpose>Synchronous I/O multiplexing</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+#include &lt;sys/time.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;unistd.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>int <function>select</function></funcdef>
+	<paramdef>int <parameter>nfds</parameter></paramdef>
+	<paramdef>fd_set *<parameter>readfds</parameter></paramdef>
+	<paramdef>fd_set *<parameter>writefds</parameter></paramdef>
+	<paramdef>fd_set *<parameter>exceptfds</parameter></paramdef>
+	<paramdef>struct timeval *<parameter>timeout</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>With the <function>select()</function> function applications
+can suspend execution until the driver has captured data or is ready
+to accept data for output.</para>
+
+    <para>When streaming I/O has been negotiated this function waits
+until a buffer has been filled or displayed and can be dequeued with
+the &VIDIOC-DQBUF; ioctl. When buffers are already in the outgoing
+queue of the driver the function returns immediately.</para>
+
+    <para>On success <function>select()</function> returns the total
+number of bits set in the <structname>fd_set</structname>s. When the
+function timed out it returns a value of zero. On failure it returns
+<returnvalue>-1</returnvalue> and the <varname>errno</varname>
+variable is set appropriately. When the application did not call
+&VIDIOC-QBUF; or &VIDIOC-STREAMON; yet the
+<function>select()</function> function succeeds, setting the bit of
+the file descriptor in <parameter>readfds</parameter> or
+<parameter>writefds</parameter>, but subsequent &VIDIOC-DQBUF; calls
+will fail.<footnote><para>The Linux kernel implements
+<function>select()</function> like the &func-poll; function, but
+<function>select()</function> cannot return a
+<constant>POLLERR</constant>.</para>
+      </footnote></para>
+
+    <para>When use of the <function>read()</function> function has
+been negotiated and the driver does not capture yet, the
+<function>select()</function> function starts capturing. When that
+fails, <function>select()</function> returns successful and a
+subsequent <function>read()</function> call, which also attempts to
+start capturing, will return an appropriate error code. When the
+driver captures continuously (as opposed to, for example, still
+images) and data is already available the
+<function>select()</function> function returns immediately.</para>
+
+    <para>When use of the <function>write()</function> function has
+been negotiated the <function>select()</function> function just waits
+until the driver is ready for a non-blocking
+<function>write()</function> call.</para>
+
+    <para>All drivers implementing the <function>read()</function> or
+<function>write()</function> function or streaming I/O must also
+support the <function>select()</function> function.</para>
+
+    <para>For more details see the <function>select()</function>
+manual page.</para>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, <function>select()</function> returns the number
+of descriptors contained in the three returned descriptor sets, which
+will be zero if the timeout expired. On error
+<returnvalue>-1</returnvalue> is returned, and the
+<varname>errno</varname> variable is set appropriately; the sets and
+<parameter>timeout</parameter> are undefined. Possible error codes
+are:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para>One or more of the file descriptor sets specified a
+file descriptor that is not open.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The driver does not support multiple read or write
+streams and the device is already in use.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EFAULT</errorcode></term>
+	<listitem>
+	  <para>The <parameter>readfds</parameter>,
+<parameter>writefds</parameter>, <parameter>exceptfds</parameter> or
+<parameter>timeout</parameter> pointer references an inaccessible memory
+area.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINTR</errorcode></term>
+	<listitem>
+	  <para>The call was interrupted by a signal.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <parameter>nfds</parameter> argument is less than
+zero or greater than <constant>FD_SETSIZE</constant>.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/func-write.xml b/Documentation/DocBook/v4l/func-write.xml
new file mode 100644
index 0000000..2c09c09
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-write.xml
@@ -0,0 +1,136 @@
+<refentry id="func-write">
+  <refmeta>
+    <refentrytitle>V4L2 write()</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>v4l2-write</refname>
+    <refpurpose>Write to a V4L2 device</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
+      <funcprototype>
+	<funcdef>ssize_t <function>write</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>void *<parameter>buf</parameter></paramdef>
+	<paramdef>size_t <parameter>count</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>buf</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>count</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para><function>write()</function> writes up to
+<parameter>count</parameter> bytes to the device referenced by the
+file descriptor <parameter>fd</parameter> from the buffer starting at
+<parameter>buf</parameter>. When the hardware outputs are not active
+yet, this function enables them. When <parameter>count</parameter> is
+zero, <function>write()</function> returns
+<returnvalue>0</returnvalue> without any other effect.</para>
+
+    <para>When the application does not provide more data in time, the
+previous video frame, raw VBI image, sliced VPS or WSS data is
+displayed again. Sliced Teletext or Closed Caption data is not
+repeated, the driver inserts a blank line instead.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Return Value</title>
+
+    <para>On success, the number of bytes written are returned. Zero
+indicates nothing was written. On error, <returnvalue>-1</returnvalue>
+is returned, and the <varname>errno</varname> variable is set
+appropriately. In this case the next write will start at the beginning
+of a new frame. Possible error codes are:</para>
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EAGAIN</errorcode></term>
+	<listitem>
+	  <para>Non-blocking I/O has been selected using the <link
+linkend="func-open"><constant>O_NONBLOCK</constant></link> flag and no
+buffer space was available to write the data immediately.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBADF</errorcode></term>
+	<listitem>
+	  <para><parameter>fd</parameter> is not a valid file
+descriptor or is not open for writing.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The driver does not support multiple write streams and the
+device is already in use.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EFAULT</errorcode></term>
+	<listitem>
+	  <para><parameter>buf</parameter> references an inaccessible
+memory area.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINTR</errorcode></term>
+	<listitem>
+	  <para>The call was interrupted by a signal before any
+data was written.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EIO</errorcode></term>
+	<listitem>
+	  <para>I/O error. This indicates some hardware problem.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <function>write()</function> function is not
+supported by this driver, not on this device, or generally not on this
+type of device.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/io.xml b/Documentation/DocBook/v4l/io.xml
new file mode 100644
index 0000000..f92f243
--- /dev/null
+++ b/Documentation/DocBook/v4l/io.xml
@@ -0,0 +1,1073 @@
+  <title>Input/Output</title>
+
+  <para>The V4L2 API defines several different methods to read from or
+write to a device. All drivers exchanging data with applications must
+support at least one of them.</para>
+
+  <para>The classic I/O method using the <function>read()</function>
+and <function>write()</function> function is automatically selected
+after opening a V4L2 device. When the driver does not support this
+method attempts to read or write will fail at any time.</para>
+
+  <para>Other methods must be negotiated. To select the streaming I/O
+method with memory mapped or user buffers applications call the
+&VIDIOC-REQBUFS; ioctl. The asynchronous I/O method is not defined
+yet.</para>
+
+  <para>Video overlay can be considered another I/O method, although
+the application does not directly receive the image data. It is
+selected by initiating video overlay with the &VIDIOC-S-FMT; ioctl.
+For more information see <xref linkend="overlay" />.</para>
+
+  <para>Generally exactly one I/O method, including overlay, is
+associated with each file descriptor. The only exceptions are
+applications not exchanging data with a driver ("panel applications",
+see <xref linkend="open" />) and drivers permitting simultaneous video capturing
+and overlay using the same file descriptor, for compatibility with V4L
+and earlier versions of V4L2.</para>
+
+  <para><constant>VIDIOC_S_FMT</constant> and
+<constant>VIDIOC_REQBUFS</constant> would permit this to some degree,
+but for simplicity drivers need not support switching the I/O method
+(after first switching away from read/write) other than by closing
+and reopening the device.</para>
+
+  <para>The following sections describe the various I/O methods in
+more detail.</para>
+
+  <section id="rw">
+    <title>Read/Write</title>
+
+    <para>Input and output devices support the
+<function>read()</function> and <function>write()</function> function,
+respectively, when the <constant>V4L2_CAP_READWRITE</constant> flag in
+the <structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl is set.</para>
+
+    <para>Drivers may need the CPU to copy the data, but they may also
+support DMA to or from user memory, so this I/O method is not
+necessarily less efficient than other methods merely exchanging buffer
+pointers. It is considered inferior though because no meta-information
+like frame counters or timestamps are passed. This information is
+necessary to recognize frame dropping and to synchronize with other
+data streams. However this is also the simplest I/O method, requiring
+little or no setup to exchange data. It permits command line stunts
+like this (the <application>vidctrl</application> tool is
+fictitious):</para>
+
+    <informalexample>
+      <screen>
+&gt; vidctrl /dev/video --input=0 --format=YUYV --size=352x288
+&gt; dd if=/dev/video of=myimage.422 bs=202752 count=1
+</screen>
+    </informalexample>
+
+    <para>To read from the device applications use the
+&func-read; function, to write the &func-write; function.
+Drivers must implement one I/O method if they
+exchange data with applications, but it need not be this.<footnote>
+	<para>It would be desirable if applications could depend on
+drivers supporting all I/O interfaces, but as much as the complex
+memory mapping I/O can be inadequate for some devices we have no
+reason to require this interface, which is most useful for simple
+applications capturing still images.</para>
+      </footnote> When reading or writing is supported, the driver
+must also support the &func-select; and &func-poll;
+function.<footnote>
+	<para>At the driver level <function>select()</function> and
+<function>poll()</function> are the same, and
+<function>select()</function> is too important to be optional.</para>
+      </footnote></para>
+  </section>
+
+  <section id="mmap">
+    <title>Streaming I/O (Memory Mapping)</title>
+
+    <para>Input and output devices support this I/O method when the
+<constant>V4L2_CAP_STREAMING</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl is set. There are two
+streaming methods, to determine if the memory mapping flavor is
+supported applications must call the &VIDIOC-REQBUFS; ioctl.</para>
+
+    <para>Streaming is an I/O method where only pointers to buffers
+are exchanged between application and driver, the data itself is not
+copied. Memory mapping is primarily intended to map buffers in device
+memory into the application's address space. Device memory can be for
+example the video memory on a graphics card with a video capture
+add-on. However, being the most efficient I/O method available for a
+long time, many other drivers support streaming as well, allocating
+buffers in DMA-able main memory.</para>
+
+    <para>A driver can support many sets of buffers. Each set is
+identified by a unique buffer type value. The sets are independent and
+each set can hold a different type of data. To access different sets
+at the same time different file descriptors must be used.<footnote>
+	<para>One could use one file descriptor and set the buffer
+type field accordingly when calling &VIDIOC-QBUF; etc., but it makes
+the <function>select()</function> function ambiguous. We also like the
+clean approach of one file descriptor per logical stream. Video
+overlay for example is also a logical stream, although the CPU is not
+needed for continuous operation.</para>
+      </footnote></para>
+
+    <para>To allocate device buffers applications call the
+&VIDIOC-REQBUFS; ioctl with the desired number of buffers and buffer
+type, for example <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>.
+This ioctl can also be used to change the number of buffers or to free
+the allocated memory, provided none of the buffers are still
+mapped.</para>
+
+    <para>Before applications can access the buffers they must map
+them into their address space with the &func-mmap; function. The
+location of the buffers in device memory can be determined with the
+&VIDIOC-QUERYBUF; ioctl. The <structfield>m.offset</structfield> and
+<structfield>length</structfield> returned in a &v4l2-buffer; are
+passed as sixth and second parameter to the
+<function>mmap()</function> function. The offset and length values
+must not be modified. Remember the buffers are allocated in physical
+memory, as opposed to virtual memory which can be swapped out to disk.
+Applications should free the buffers as soon as possible with the
+&func-munmap; function.</para>
+
+    <example>
+      <title>Mapping buffers</title>
+
+      <programlisting>
+&v4l2-requestbuffers; reqbuf;
+struct {
+	void *start;
+	size_t length;
+} *buffers;
+unsigned int i;
+
+memset (&amp;reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_MMAP;
+reqbuf.count = 20;
+
+if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf)) {
+	if (errno == EINVAL)
+		printf ("Video capturing or mmap-streaming is not supported\n");
+	else
+		perror ("VIDIOC_REQBUFS");
+
+	exit (EXIT_FAILURE);
+}
+
+/* We want at least five buffers. */
+
+if (reqbuf.count &lt; 5) {
+	/* You may need to free the buffers here. */
+	printf ("Not enough buffer memory\n");
+	exit (EXIT_FAILURE);
+}
+
+buffers = calloc (reqbuf.count, sizeof (*buffers));
+assert (buffers != NULL);
+
+for (i = 0; i &lt; reqbuf.count; i++) {
+	&v4l2-buffer; buffer;
+
+	memset (&amp;buffer, 0, sizeof (buffer));
+	buffer.type = reqbuf.type;
+	buffer.memory = V4L2_MEMORY_MMAP;
+	buffer.index = i;
+
+	if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &amp;buffer)) {
+		perror ("VIDIOC_QUERYBUF");
+		exit (EXIT_FAILURE);
+	}
+
+	buffers[i].length = buffer.length; /* remember for munmap() */
+
+	buffers[i].start = mmap (NULL, buffer.length,
+				 PROT_READ | PROT_WRITE, /* recommended */
+				 MAP_SHARED,             /* recommended */
+				 fd, buffer.m.offset);
+
+	if (MAP_FAILED == buffers[i].start) {
+		/* If you do not exit here you should unmap() and free()
+		   the buffers mapped so far. */
+		perror ("mmap");
+		exit (EXIT_FAILURE);
+	}
+}
+
+/* Cleanup. */
+
+for (i = 0; i &lt; reqbuf.count; i++)
+	munmap (buffers[i].start, buffers[i].length);
+      </programlisting>
+    </example>
+
+    <para>Conceptually streaming drivers maintain two buffer queues, an incoming
+and an outgoing queue. They separate the synchronous capture or output
+operation locked to a video clock from the application which is
+subject to random disk or network delays and preemption by
+other processes, thereby reducing the probability of data loss.
+The queues are organized as FIFOs, buffers will be
+output in the order enqueued in the incoming FIFO, and were
+captured in the order dequeued from the outgoing FIFO.</para>
+
+    <para>The driver may require a minimum number of buffers enqueued
+at all times to function, apart of this no limit exists on the number
+of buffers applications can enqueue in advance, or dequeue and
+process. They can also enqueue in a different order than buffers have
+been dequeued, and the driver can <emphasis>fill</emphasis> enqueued
+<emphasis>empty</emphasis> buffers in any order. <footnote>
+	<para>Random enqueue order permits applications processing
+images out of order (such as video codecs) to return buffers earlier,
+reducing the probability of data loss. Random fill order allows
+drivers to reuse buffers on a LIFO-basis, taking advantage of caches
+holding scatter-gather lists and the like.</para>
+      </footnote> The index number of a buffer (&v4l2-buffer;
+<structfield>index</structfield>) plays no role here, it only
+identifies the buffer.</para>
+
+    <para>Initially all mapped buffers are in dequeued state,
+inaccessible by the driver. For capturing applications it is customary
+to first enqueue all mapped buffers, then to start capturing and enter
+the read loop. Here the application waits until a filled buffer can be
+dequeued, and re-enqueues the buffer when the data is no longer
+needed. Output applications fill and enqueue buffers, when enough
+buffers are stacked up the output is started with
+<constant>VIDIOC_STREAMON</constant>. In the write loop, when
+the application runs out of free buffers, it must wait until an empty
+buffer can be dequeued and reused.</para>
+
+    <para>To enqueue and dequeue a buffer applications use the
+&VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl. The status of a buffer being
+mapped, enqueued, full or empty can be determined at any time using the
+&VIDIOC-QUERYBUF; ioctl. Two methods exist to suspend execution of the
+application until one or more buffers can be dequeued. By default
+<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the
+outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
+given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
+returns immediately with an &EAGAIN; when no buffer is available. The
+&func-select; or &func-poll; function are always available.</para>
+
+    <para>To start and stop capturing or output applications call the
+&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
+<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both
+queues as a side effect. Since there is no notion of doing anything
+"now" on a multitasking system, if an application needs to synchronize
+with another event it should examine the &v4l2-buffer;
+<structfield>timestamp</structfield> of captured buffers, or set the
+field before enqueuing buffers for output.</para>
+
+    <para>Drivers implementing memory mapping I/O must
+support the <constant>VIDIOC_REQBUFS</constant>,
+<constant>VIDIOC_QUERYBUF</constant>,
+<constant>VIDIOC_QBUF</constant>, <constant>VIDIOC_DQBUF</constant>,
+<constant>VIDIOC_STREAMON</constant> and
+<constant>VIDIOC_STREAMOFF</constant> ioctl, the
+<function>mmap()</function>, <function>munmap()</function>,
+<function>select()</function> and <function>poll()</function>
+function.<footnote>
+	<para>At the driver level <function>select()</function> and
+<function>poll()</function> are the same, and
+<function>select()</function> is too important to be optional. The
+rest should be evident.</para>
+      </footnote></para>
+
+    <para>[capture example]</para>
+
+  </section>
+
+  <section id="userp">
+    <title>Streaming I/O (User Pointers)</title>
+
+    <para>Input and output devices support this I/O method when the
+<constant>V4L2_CAP_STREAMING</constant> flag in the
+<structfield>capabilities</structfield> field of &v4l2-capability;
+returned by the &VIDIOC-QUERYCAP; ioctl is set. If the particular user
+pointer method (not only memory mapping) is supported must be
+determined by calling the &VIDIOC-REQBUFS; ioctl.</para>
+
+    <para>This I/O method combines advantages of the read/write and
+memory mapping methods. Buffers are allocated by the application
+itself, and can reside for example in virtual or shared memory. Only
+pointers to data are exchanged, these pointers and meta-information
+are passed in &v4l2-buffer;. The driver must be switched
+into user pointer I/O mode by calling the &VIDIOC-REQBUFS; with the
+desired buffer type. No buffers are allocated beforehands,
+consequently they are not indexed and cannot be queried like mapped
+buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para>
+
+    <example>
+      <title>Initiating streaming I/O with user pointers</title>
+
+      <programlisting>
+&v4l2-requestbuffers; reqbuf;
+
+memset (&amp;reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_USERPTR;
+
+if (ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf) == -1) {
+	if (errno == EINVAL)
+		printf ("Video capturing or user pointer streaming is not supported\n");
+	else
+		perror ("VIDIOC_REQBUFS");
+
+	exit (EXIT_FAILURE);
+}
+      </programlisting>
+    </example>
+
+    <para>Buffer addresses and sizes are passed on the fly with the
+&VIDIOC-QBUF; ioctl. Although buffers are commonly cycled,
+applications can pass different addresses and sizes at each
+<constant>VIDIOC_QBUF</constant> call. If required by the hardware the
+driver swaps memory pages within physical memory to create a
+continuous area of memory. This happens transparently to the
+application in the virtual memory subsystem of the kernel. When buffer
+pages have been swapped out to disk they are brought back and finally
+locked in physical memory for DMA.<footnote>
+	<para>We expect that frequently used buffers are typically not
+swapped out. Anyway, the process of swapping, locking or generating
+scatter-gather lists may be time consuming. The delay can be masked by
+the depth of the incoming buffer queue, and perhaps by maintaining
+caches assuming a buffer will be soon enqueued again. On the other
+hand, to optimize memory usage drivers can limit the number of buffers
+locked in advance and recycle the most recently used buffers first. Of
+course, the pages of empty buffers in the incoming queue need not be
+saved to disk. Output buffers must be saved on the incoming and
+outgoing queue because an application may share them with other
+processes.</para>
+      </footnote></para>
+
+    <para>Filled or displayed buffers are dequeued with the
+&VIDIOC-DQBUF; ioctl. The driver can unlock the memory pages at any
+time between the completion of the DMA and this ioctl. The memory is
+also unlocked when &VIDIOC-STREAMOFF; is called, &VIDIOC-REQBUFS;, or
+when the device is closed. Applications must take care not to free
+buffers without dequeuing. For once, the buffers remain locked until
+further, wasting physical memory. Second the driver will not be
+notified when the memory is returned to the application's free list
+and subsequently reused for other purposes, possibly completing the
+requested DMA and overwriting valuable data.</para>
+
+    <para>For capturing applications it is customary to enqueue a
+number of empty buffers, to start capturing and enter the read loop.
+Here the application waits until a filled buffer can be dequeued, and
+re-enqueues the buffer when the data is no longer needed. Output
+applications fill and enqueue buffers, when enough buffers are stacked
+up output is started. In the write loop, when the application
+runs out of free buffers it must wait until an empty buffer can be
+dequeued and reused. Two methods exist to suspend execution of the
+application until one or more buffers can be dequeued. By default
+<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the
+outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
+given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
+returns immediately with an &EAGAIN; when no buffer is available. The
+&func-select; or &func-poll; function are always available.</para>
+
+    <para>To start and stop capturing or output applications call the
+&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
+<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both
+queues and unlocks all buffers as a side effect. Since there is no
+notion of doing anything "now" on a multitasking system, if an
+application needs to synchronize with another event it should examine
+the &v4l2-buffer; <structfield>timestamp</structfield> of captured
+buffers, or set the field before enqueuing buffers for output.</para>
+
+    <para>Drivers implementing user pointer I/O must
+support the <constant>VIDIOC_REQBUFS</constant>,
+<constant>VIDIOC_QBUF</constant>, <constant>VIDIOC_DQBUF</constant>,
+<constant>VIDIOC_STREAMON</constant> and
+<constant>VIDIOC_STREAMOFF</constant> ioctl, the
+<function>select()</function> and <function>poll()</function> function.<footnote>
+	<para>At the driver level <function>select()</function> and
+<function>poll()</function> are the same, and
+<function>select()</function> is too important to be optional. The
+rest should be evident.</para>
+      </footnote></para>
+  </section>
+
+  <section id="async">
+    <title>Asynchronous I/O</title>
+
+    <para>This method is not defined yet.</para>
+  </section>
+
+  <section id="buffer">
+    <title>Buffers</title>
+
+    <para>A buffer contains data exchanged by application and
+driver using one of the Streaming I/O methods. Only pointers to
+buffers are exchanged, the data itself is not copied. These pointers,
+together with meta-information like timestamps or field parity, are
+stored in a struct <structname>v4l2_buffer</structname>, argument to
+the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.</para>
+
+      <para>Nominally timestamps refer to the first data byte transmitted.
+In practice however the wide range of hardware covered by the V4L2 API
+limits timestamp accuracy. Often an interrupt routine will
+sample the system clock shortly after the field or frame was stored
+completely in memory. So applications must expect a constant
+difference up to one field or frame period plus a small (few scan
+lines) random error. The delay and error can be much
+larger due to compression or transmission over an external bus when
+the frames are not properly stamped by the sender. This is frequently
+the case with USB cameras. Here timestamps refer to the instant the
+field or frame was received by the driver, not the capture time. These
+devices identify by not enumerating any video standards, see <xref
+linkend="standard" />.</para>
+
+      <para>Similar limitations apply to output timestamps. Typically
+the video hardware locks to a clock controlling the video timing, the
+horizontal and vertical synchronization pulses. At some point in the
+line sequence, possibly the vertical blanking, an interrupt routine
+samples the system clock, compares against the timestamp and programs
+the hardware to repeat the previous field or frame, or to display the
+buffer contents.</para>
+
+      <para>Apart of limitations of the video device and natural
+inaccuracies of all clocks, it should be noted system time itself is
+not perfectly stable. It can be affected by power saving cycles,
+warped to insert leap seconds, or even turned back or forth by the
+system administrator affecting long term measurements. <footnote>
+	  <para>Since no other Linux multimedia
+API supports unadjusted time it would be foolish to introduce here. We
+must use a universally supported clock to synchronize different media,
+hence time of day.</para>
+	</footnote></para>
+
+    <table frame="none" pgwide="1" id="v4l2-buffer">
+      <title>struct <structname>v4l2_buffer</structname></title>
+      <tgroup cols="4">
+	&cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry></entry>
+	    <entry>Number of the buffer, set by the application. This
+field is only used for <link linkend="mmap">memory mapping</link> I/O
+and can range from zero to the number of buffers allocated
+with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry></entry>
+	    <entry>Type of the buffer, same as &v4l2-format;
+<structfield>type</structfield> or &v4l2-requestbuffers;
+<structfield>type</structfield>, set by the application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>bytesused</structfield></entry>
+	    <entry></entry>
+	    <entry>The number of bytes occupied by the data in the
+buffer. It depends on the negotiated data format and may change with
+each buffer for compressed variable size data like JPEG images.
+Drivers must set this field when <structfield>type</structfield>
+refers to an input stream, applications when an output stream.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry></entry>
+	    <entry>Flags set by the application or driver, see <xref
+linkend="buffer-flags" />.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-field;</entry>
+	    <entry><structfield>field</structfield></entry>
+	    <entry></entry>
+	    <entry>Indicates the field order of the image in the
+buffer, see <xref linkend="v4l2-field" />. This field is not used when
+the buffer contains VBI data. Drivers must set it when
+<structfield>type</structfield> refers to an input stream,
+applications when an output stream.</entry>
+	  </row>
+	  <row>
+	    <entry>struct timeval</entry>
+	    <entry><structfield>timestamp</structfield></entry>
+	    <entry></entry>
+	    <entry><para>For input streams this is the
+system time (as returned by the <function>gettimeofday()</function>
+function) when the first data byte was captured. For output streams
+the data will not be displayed before this time, secondary to the
+nominal frame rate determined by the current video standard in
+enqueued order. Applications can for example zero this field to
+display frames as soon as possible. The driver stores the time at
+which the first data byte was actually sent out in the
+<structfield>timestamp</structfield> field. This permits
+applications to monitor the drift between the video and system
+clock.</para></entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-timecode;</entry>
+	    <entry><structfield>timecode</structfield></entry>
+	    <entry></entry>
+	    <entry>When <structfield>type</structfield> is
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and the
+<constant>V4L2_BUF_FLAG_TIMECODE</constant> flag is set in
+<structfield>flags</structfield>, this structure contains a frame
+timecode. In <link linkend="v4l2-field">V4L2_FIELD_ALTERNATE</link>
+mode the top and bottom field contain the same timecode.
+Timecodes are intended to help video editing and are typically recorded on
+video tapes, but also embedded in compressed formats like MPEG. This
+field is independent of the <structfield>timestamp</structfield> and
+<structfield>sequence</structfield> fields.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>sequence</structfield></entry>
+	    <entry></entry>
+	    <entry>Set by the driver, counting the frames in the
+sequence.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan"><para>In <link
+linkend="v4l2-field">V4L2_FIELD_ALTERNATE</link> mode the top and
+bottom field have the same sequence number. The count starts at zero
+and includes dropped or repeated frames. A dropped frame was received
+by an input device but could not be stored due to lack of free buffer
+space. A repeated frame was displayed again by an output device
+because the application did not pass new data in
+time.</para><para>Note this may count the frames received
+e.g. over USB, without taking into account the frames dropped by the
+remote hardware due to limited compression throughput or bus
+bandwidth. These devices identify by not enumerating any video
+standards, see <xref linkend="standard" />.</para></entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-memory;</entry>
+	    <entry><structfield>memory</structfield></entry>
+	    <entry></entry>
+	    <entry>This field must be set by applications and/or drivers
+in accordance with the selected I/O method.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry><structfield>m</structfield></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>offset</structfield></entry>
+	    <entry>When <structfield>memory</structfield> is
+<constant>V4L2_MEMORY_MMAP</constant> this is the offset of the buffer
+from the start of the device memory. The value is returned by the
+driver and apart of serving as parameter to the &func-mmap; function
+not useful for applications. See <xref linkend="mmap" /> for details.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>unsigned long</entry>
+	    <entry><structfield>userptr</structfield></entry>
+	    <entry>When <structfield>memory</structfield> is
+<constant>V4L2_MEMORY_USERPTR</constant> this is a pointer to the
+buffer (casted to unsigned long type) in virtual memory, set by the
+application. See <xref linkend="userp" /> for details.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>length</structfield></entry>
+	    <entry></entry>
+	    <entry>Size of the buffer (not the payload) in bytes.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>input</structfield></entry>
+	    <entry></entry>
+	    <entry>Some video capture drivers support rapid and
+synchronous video input changes, a function useful for example in
+video surveillance applications. For this purpose applications set the
+<constant>V4L2_BUF_FLAG_INPUT</constant> flag, and this field to the
+number of a video input as in &v4l2-input; field
+<structfield>index</structfield>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield></entry>
+	    <entry></entry>
+	    <entry>A place holder for future extensions and custom
+(driver defined) buffer types
+<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="v4l2-buf-type">
+      <title>enum v4l2_buf_type</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
+	    <entry>1</entry>
+	    <entry>Buffer of a video capture stream, see <xref
+		linkend="capture" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
+	    <entry>2</entry>
+	    <entry>Buffer of a video output stream, see <xref
+		linkend="output" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant></entry>
+	    <entry>3</entry>
+	    <entry>Buffer for video overlay, see <xref linkend="overlay" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant></entry>
+	    <entry>4</entry>
+	    <entry>Buffer of a raw VBI capture stream, see <xref
+		linkend="raw-vbi" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant></entry>
+	    <entry>5</entry>
+	    <entry>Buffer of a raw VBI output stream, see <xref
+		linkend="raw-vbi" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant></entry>
+	    <entry>6</entry>
+	    <entry>Buffer of a sliced VBI capture stream, see <xref
+		linkend="sliced" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant></entry>
+	    <entry>7</entry>
+	    <entry>Buffer of a sliced VBI output stream, see <xref
+		linkend="sliced" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant></entry>
+	    <entry>8</entry>
+	    <entry>Buffer for video output overlay (OSD), see <xref
+		linkend="osd" />. Status: <link
+linkend="experimental">Experimental</link>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
+	    <entry>0x80</entry>
+	  <entry>This and higher values are reserved for custom
+(driver defined) buffer types.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="buffer-flags">
+      <title>Buffer Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_MAPPED</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>The buffer resides in device memory and has been mapped
+into the application's address space, see <xref linkend="mmap" /> for details.
+Drivers set or clear this flag when the
+<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
+	  linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
+	  linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called. Set by the driver.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_QUEUED</constant></entry>
+	    <entry>0x0002</entry>
+	  <entry>Internally drivers maintain two buffer queues, an
+incoming and outgoing queue. When this flag is set, the buffer is
+currently on the incoming queue. It automatically moves to the
+outgoing queue after the buffer has been filled (capture devices) or
+displayed (output devices). Drivers set or clear this flag when the
+<constant>VIDIOC_QUERYBUF</constant> ioctl is called. After
+(successful) calling the <constant>VIDIOC_QBUF </constant>ioctl it is
+always set and after <constant>VIDIOC_DQBUF</constant> always
+cleared.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_DONE</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>When this flag is set, the buffer is currently on
+the outgoing queue, ready to be dequeued from the driver. Drivers set
+or clear this flag when the <constant>VIDIOC_QUERYBUF</constant> ioctl
+is called. After calling the <constant>VIDIOC_QBUF</constant> or
+<constant>VIDIOC_DQBUF</constant> it is always cleared. Of course a
+buffer cannot be on both queues at the same time, the
+<constant>V4L2_BUF_FLAG_QUEUED</constant> and
+<constant>V4L2_BUF_FLAG_DONE</constant> flag are mutually exclusive.
+They can be both cleared however, then the buffer is in "dequeued"
+state, in the application domain to say so.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
+	    <entry>0x0008</entry>
+	  <entry>Drivers set or clear this flag when calling the
+<constant>VIDIOC_DQBUF</constant> ioctl. It may be set by video
+capture devices when the buffer contains a compressed image which is a
+key frame (or field), &ie; can be decompressed on its own.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_PFRAME</constant></entry>
+	    <entry>0x0010</entry>
+	    <entry>Similar to <constant>V4L2_BUF_FLAG_KEYFRAME</constant>
+this flags predicted frames or fields which contain only differences to a
+previous key frame.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_BFRAME</constant></entry>
+	    <entry>0x0020</entry>
+	    <entry>Similar to <constant>V4L2_BUF_FLAG_PFRAME</constant>
+	this is a bidirectional predicted frame or field. [ooc tbd]</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_TIMECODE</constant></entry>
+	    <entry>0x0100</entry>
+	    <entry>The <structfield>timecode</structfield> field is valid.
+Drivers set or clear this flag when the <constant>VIDIOC_DQBUF</constant>
+ioctl is called.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_BUF_FLAG_INPUT</constant></entry>
+	    <entry>0x0200</entry>
+	    <entry>The <structfield>input</structfield> field is valid.
+Applications set or clear this flag before calling the
+<constant>VIDIOC_QBUF</constant> ioctl.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-memory">
+      <title>enum v4l2_memory</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_MEMORY_MMAP</constant></entry>
+	    <entry>1</entry>
+	    <entry>The buffer is used for <link linkend="mmap">memory
+mapping</link> I/O.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_MEMORY_USERPTR</constant></entry>
+	    <entry>2</entry>
+	    <entry>The buffer is used for <link linkend="userp">user
+pointer</link> I/O.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_MEMORY_OVERLAY</constant></entry>
+	    <entry>3</entry>
+	    <entry>[to do]</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <section>
+      <title>Timecodes</title>
+
+      <para>The <structname>v4l2_timecode</structname> structure is
+designed to hold a <xref linkend="smpte12m" /> or similar timecode.
+(struct <structname>timeval</structname> timestamps are stored in
+&v4l2-buffer; field <structfield>timestamp</structfield>.)</para>
+
+      <table frame="none" pgwide="1" id="v4l2-timecode">
+	<title>struct <structname>v4l2_timecode</structname></title>
+	<tgroup cols="3">
+	  &cs-str;
+	  <tbody valign="top">
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>type</structfield></entry>
+	      <entry>Frame rate the timecodes are based on, see <xref
+		  linkend="timecode-type" />.</entry>
+	    </row>
+	    <row>
+	      <entry>__u32</entry>
+	      <entry><structfield>flags</structfield></entry>
+	      <entry>Timecode flags, see <xref linkend="timecode-flags" />.</entry>
+	    </row>
+	    <row>
+	      <entry>__u8</entry>
+	      <entry><structfield>frames</structfield></entry>
+	      <entry>Frame count, 0 ... 23/24/29/49/59, depending on the
+	    type of timecode.</entry>
+	    </row>
+	    <row>
+	      <entry>__u8</entry>
+	      <entry><structfield>seconds</structfield></entry>
+	      <entry>Seconds count, 0 ... 59. This is a binary, not BCD number.</entry>
+	    </row>
+	    <row>
+	      <entry>__u8</entry>
+	      <entry><structfield>minutes</structfield></entry>
+	      <entry>Minutes count, 0 ... 59. This is a binary, not BCD number.</entry>
+	    </row>
+	    <row>
+	      <entry>__u8</entry>
+	      <entry><structfield>hours</structfield></entry>
+	      <entry>Hours count, 0 ... 29. This is a binary, not BCD number.</entry>
+	    </row>
+	    <row>
+	      <entry>__u8</entry>
+	      <entry><structfield>userbits</structfield>[4]</entry>
+	      <entry>The "user group" bits from the timecode.</entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+
+      <table frame="none" pgwide="1" id="timecode-type">
+	<title>Timecode Types</title>
+	<tgroup cols="3">
+	&cs-def;
+	  <tbody valign="top">
+	    <row>
+	      <entry><constant>V4L2_TC_TYPE_24FPS</constant></entry>
+	      <entry>1</entry>
+	      <entry>24 frames per second, i.&nbsp;e. film.</entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_TYPE_25FPS</constant></entry>
+	      <entry>2</entry>
+	      <entry>25 frames per second, &ie; PAL or SECAM video.</entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_TYPE_30FPS</constant></entry>
+	      <entry>3</entry>
+	      <entry>30 frames per second, &ie; NTSC video.</entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_TYPE_50FPS</constant></entry>
+	      <entry>4</entry>
+	      <entry></entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_TYPE_60FPS</constant></entry>
+	      <entry>5</entry>
+	      <entry></entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+
+      <table frame="none" pgwide="1" id="timecode-flags">
+	<title>Timecode Flags</title>
+	<tgroup cols="3">
+	&cs-def;
+	  <tbody valign="top">
+	    <row>
+	      <entry><constant>V4L2_TC_FLAG_DROPFRAME</constant></entry>
+	      <entry>0x0001</entry>
+	      <entry>Indicates "drop frame" semantics for counting frames
+in 29.97 fps material. When set, frame numbers 0 and 1 at the start of
+each minute, except minutes 0, 10, 20, 30, 40, 50 are omitted from the
+count.</entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_FLAG_COLORFRAME</constant></entry>
+	      <entry>0x0002</entry>
+	      <entry>The "color frame" flag.</entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_USERBITS_field</constant></entry>
+	      <entry>0x000C</entry>
+	      <entry>Field mask for the "binary group flags".</entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_USERBITS_USERDEFINED</constant></entry>
+	      <entry>0x0000</entry>
+	      <entry>Unspecified format.</entry>
+	    </row>
+	    <row>
+	      <entry><constant>V4L2_TC_USERBITS_8BITCHARS</constant></entry>
+	      <entry>0x0008</entry>
+	      <entry>8-bit ISO characters.</entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+    </section>
+  </section>
+
+  <section id="field-order">
+    <title>Field Order</title>
+
+    <para>We have to distinguish between progressive and interlaced
+video. Progressive video transmits all lines of a video image
+sequentially. Interlaced video divides an image into two fields,
+containing only the odd and even lines of the image, respectively.
+Alternating the so called odd and even field are transmitted, and due
+to a small delay between fields a cathode ray TV displays the lines
+interleaved, yielding the original frame. This curious technique was
+invented because at refresh rates similar to film the image would
+fade out too quickly. Transmitting fields reduces the flicker without
+the necessity of doubling the frame rate and with it the bandwidth
+required for each channel.</para>
+
+    <para>It is important to understand a video camera does not expose
+one frame at a time, merely transmitting the frames separated into
+fields. The fields are in fact captured at two different instances in
+time. An object on screen may well move between one field and the
+next. For applications analysing motion it is of paramount importance
+to recognize which field of a frame is older, the <emphasis>temporal
+order</emphasis>.</para>
+
+    <para>When the driver provides or accepts images field by field
+rather than interleaved, it is also important applications understand
+how the fields combine to frames. We distinguish between top and
+bottom fields, the <emphasis>spatial order</emphasis>: The first line
+of the top field is the first line of an interlaced frame, the first
+line of the bottom field is the second line of that frame.</para>
+
+    <para>However because fields were captured one after the other,
+arguing whether a frame commences with the top or bottom field is
+pointless. Any two successive top and bottom, or bottom and top fields
+yield a valid frame. Only when the source was progressive to begin
+with, &eg; when transferring film to video, two fields may come from
+the same frame, creating a natural order.</para>
+
+    <para>Counter to intuition the top field is not necessarily the
+older field. Whether the older field contains the top or bottom lines
+is a convention determined by the video standard. Hence the
+distinction between temporal and spatial order of fields. The diagrams
+below should make this clearer.</para>
+
+    <para>All video capture and output devices must report the current
+field order. Some drivers may permit the selection of a different
+order, to this end applications initialize the
+<structfield>field</structfield> field of &v4l2-pix-format; before
+calling the &VIDIOC-S-FMT; ioctl. If this is not desired it should
+have the value <constant>V4L2_FIELD_ANY</constant> (0).</para>
+
+    <table frame="none" pgwide="1" id="v4l2-field">
+      <title>enum v4l2_field</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_FIELD_ANY</constant></entry>
+	    <entry>0</entry>
+	    <entry>Applications request this field order when any
+one of the <constant>V4L2_FIELD_NONE</constant>,
+<constant>V4L2_FIELD_TOP</constant>,
+<constant>V4L2_FIELD_BOTTOM</constant>, or
+<constant>V4L2_FIELD_INTERLACED</constant> formats is acceptable.
+Drivers choose depending on hardware capabilities or e.&nbsp;g. the
+requested image size, and return the actual field order. &v4l2-buffer;
+<structfield>field</structfield> can never be
+<constant>V4L2_FIELD_ANY</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_NONE</constant></entry>
+	    <entry>1</entry>
+	    <entry>Images are in progressive format, not interlaced.
+The driver may also indicate this order when it cannot distinguish
+between <constant>V4L2_FIELD_TOP</constant> and
+<constant>V4L2_FIELD_BOTTOM</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_TOP</constant></entry>
+	    <entry>2</entry>
+	    <entry>Images consist of the top field only.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
+	    <entry>3</entry>
+	    <entry>Images consist of the bottom field only.
+Applications may wish to prevent a device from capturing interlaced
+images because they will have "comb" or "feathering" artefacts around
+moving objects.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_INTERLACED</constant></entry>
+	    <entry>4</entry>
+	    <entry>Images contain both fields, interleaved line by
+line. The temporal order of the fields (whether the top or bottom
+field is first transmitted) depends on the current video standard.
+M/NTSC transmits the bottom field first, all other standards the top
+field first.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_SEQ_TB</constant></entry>
+	    <entry>5</entry>
+	    <entry>Images contain both fields, the top field lines
+are stored first in memory, immediately followed by the bottom field
+lines. Fields are always stored in temporal order, the older one first
+in memory. Image sizes refer to the frame, not fields.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_SEQ_BT</constant></entry>
+	    <entry>6</entry>
+	    <entry>Images contain both fields, the bottom field
+lines are stored first in memory, immediately followed by the top
+field lines. Fields are always stored in temporal order, the older one
+first in memory. Image sizes refer to the frame, not fields.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_ALTERNATE</constant></entry>
+	    <entry>7</entry>
+	    <entry>The two fields of a frame are passed in separate
+buffers, in temporal order, &ie; the older one first. To indicate the field
+parity (whether the current field is a top or bottom field) the driver
+or application, depending on data direction, must set &v4l2-buffer;
+<structfield>field</structfield> to
+<constant>V4L2_FIELD_TOP</constant> or
+<constant>V4L2_FIELD_BOTTOM</constant>. Any two successive fields pair
+to build a frame. If fields are successive, without any dropped fields
+between them (fields can drop individually), can be determined from
+the &v4l2-buffer; <structfield>sequence</structfield> field. Image
+sizes refer to the frame, not fields. This format cannot be selected
+when using the read/write I/O method.<!-- Where it's indistinguishable
+from V4L2_FIELD_SEQ_*. --></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_INTERLACED_TB</constant></entry>
+	    <entry>8</entry>
+	    <entry>Images contain both fields, interleaved line by
+line, top field first. The top field is transmitted first.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FIELD_INTERLACED_BT</constant></entry>
+	    <entry>9</entry>
+	    <entry>Images contain both fields, interleaved line by
+line, top field first. The bottom field is transmitted first.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <figure id="fieldseq-tb">
+	<title>Field Order, Top Field First Transmitted</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="fieldseq_tb.pdf" format="PS" />
+	  </imageobject>
+	  <imageobject>
+	    <imagedata fileref="fieldseq_tb.gif" format="GIF" />
+	  </imageobject>
+	</mediaobject>
+    </figure>
+
+    <figure id="fieldseq-bt">
+	<title>Field Order, Bottom Field First Transmitted</title>
+	<mediaobject>
+	  <imageobject>
+	    <imagedata fileref="fieldseq_bt.pdf" format="PS" />
+	  </imageobject>
+	  <imageobject>
+	    <imagedata fileref="fieldseq_bt.gif" format="GIF" />
+	  </imageobject>
+	</mediaobject>
+    </figure>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/keytable.c.xml b/Documentation/DocBook/v4l/keytable.c.xml
new file mode 100644
index 0000000..d53254a
--- /dev/null
+++ b/Documentation/DocBook/v4l/keytable.c.xml
@@ -0,0 +1,172 @@
+<programlisting>
+/* keytable.c - This program allows checking/replacing keys at IR
+
+   Copyright (C) 2006-2009 Mauro Carvalho Chehab &lt;mchehab@infradead.org&gt;
+
+   This program is free software; 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.
+ */
+
+#include &lt;ctype.h&gt;
+#include &lt;errno.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;linux/input.h&gt;
+#include &lt;sys/ioctl.h&gt;
+
+#include "parse.h"
+
+void prtcode (int *codes)
+{
+        struct parse_key *p;
+
+        for (p=keynames;p-&gt;name!=NULL;p++) {
+                if (p-&gt;value == (unsigned)codes[1]) {
+                        printf("scancode 0x%04x = %s (0x%02x)\n", codes[0], p-&gt;name, codes[1]);
+                        return;
+                }
+        }
+
+        if (isprint (codes[1]))
+                printf("scancode %d = '%c' (0x%02x)\n", codes[0], codes[1], codes[1]);
+        else
+                printf("scancode %d = 0x%02x\n", codes[0], codes[1]);
+}
+
+int parse_code(char *string)
+{
+        struct parse_key *p;
+
+        for (p=keynames;p-&gt;name!=NULL;p++) {
+                if (!strcasecmp(p-&gt;name, string)) {
+                        return p-&gt;value;
+                }
+        }
+        return -1;
+}
+
+int main (int argc, char *argv[])
+{
+        int fd;
+        unsigned int i, j;
+        int codes[2];
+
+        if (argc&lt;2 || argc&gt;4) {
+                printf ("usage: %s &lt;device&gt; to get table; or\n"
+                        "       %s &lt;device&gt; &lt;scancode&gt; &lt;keycode&gt;\n"
+                        "       %s &lt;device&gt; &lt;keycode_file&gt;\n",*argv,*argv,*argv);
+                return -1;
+        }
+
+        if ((fd = open(argv[1], O_RDONLY)) &lt; 0) {
+                perror("Couldn't open input device");
+                return(-1);
+        }
+
+        if (argc==4) {
+                int value;
+
+                value=parse_code(argv[3]);
+
+                if (value==-1) {
+                        value = strtol(argv[3], NULL, 0);
+                        if (errno)
+                                perror("value");
+                }
+
+                codes [0] = (unsigned) strtol(argv[2], NULL, 0);
+                codes [1] = (unsigned) value;
+
+                if(ioctl(fd, EVIOCSKEYCODE, codes))
+                        perror ("EVIOCSKEYCODE");
+
+                if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
+                        prtcode(codes);
+                return 0;
+        }
+
+        if (argc==3) {
+                FILE *fin;
+                int value;
+                char *scancode, *keycode, s[2048];
+
+                fin=fopen(argv[2],"r");
+                if (fin==NULL) {
+                        perror ("opening keycode file");
+                        return -1;
+                }
+
+                /* Clears old table */
+                for (j = 0; j &lt; 256; j++) {
+                        for (i = 0; i &lt; 256; i++) {
+                                codes[0] = (j &lt;&lt; 8) | i;
+                                codes[1] = KEY_RESERVED;
+                                ioctl(fd, EVIOCSKEYCODE, codes);
+                        }
+                }
+
+                while (fgets(s,sizeof(s),fin)) {
+                        scancode=strtok(s,"\n\t =:");
+                        if (!scancode) {
+                                perror ("parsing input file scancode");
+                                return -1;
+                        }
+                        if (!strcasecmp(scancode, "scancode")) {
+                                scancode = strtok(NULL,"\n\t =:");
+                                if (!scancode) {
+                                        perror ("parsing input file scancode");
+                                        return -1;
+                                }
+                        }
+
+                        keycode=strtok(NULL,"\n\t =:(");
+                        if (!keycode) {
+                                perror ("parsing input file keycode");
+                                return -1;
+                        }
+
+                        // printf ("parsing %s=%s:", scancode, keycode);
+                        value=parse_code(keycode);
+                        // printf ("\tvalue=%d\n",value);
+
+                        if (value==-1) {
+                                value = strtol(keycode, NULL, 0);
+                                if (errno)
+                                        perror("value");
+                        }
+
+                        codes [0] = (unsigned) strtol(scancode, NULL, 0);
+                        codes [1] = (unsigned) value;
+
+                        // printf("\t%04x=%04x\n",codes[0], codes[1]);
+                        if(ioctl(fd, EVIOCSKEYCODE, codes)) {
+                                fprintf(stderr, "Setting scancode 0x%04x with 0x%04x via ",codes[0], codes[1]);
+                                perror ("EVIOCSKEYCODE");
+                        }
+
+                        if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
+                                prtcode(codes);
+                }
+                return 0;
+        }
+
+        /* Get scancode table */
+        for (j = 0; j &lt; 256; j++) {
+                for (i = 0; i &lt; 256; i++) {
+                        codes[0] = (j &lt;&lt; 8) | i;
+                        if (!ioctl(fd, EVIOCGKEYCODE, codes) &amp;&amp; codes[1] != KEY_RESERVED)
+                                prtcode(codes);
+                }
+        }
+        return 0;
+}
+
+</programlisting>
diff --git a/Documentation/DocBook/v4l/libv4l.xml b/Documentation/DocBook/v4l/libv4l.xml
new file mode 100644
index 0000000..c14fc3d
--- /dev/null
+++ b/Documentation/DocBook/v4l/libv4l.xml
@@ -0,0 +1,167 @@
+<title>Libv4l Userspace Library</title>
+<section id="libv4l-introduction">
+	<title>Introduction</title>
+
+	<para>libv4l is a collection of libraries which adds a thin abstraction
+layer on top of video4linux2 devices. The purpose of this (thin) layer
+is to make it easy for application writers to support a wide variety of
+devices without having to write separate code for different devices in the
+same class.</para>
+<para>An example of using libv4l is provided by
+<link linkend='v4l2grab-example'>v4l2grab</link>.
+</para>
+
+	<para>libv4l consists of 3 different libraries:</para>
+	<section>
+		<title>libv4lconvert</title>
+
+		<para>libv4lconvert is a library that converts several
+different pixelformats found in V4L2 drivers into a few common RGB and
+YUY formats.</para>
+		<para>It currently accepts the following V4L2 driver formats:
+<link linkend="V4L2-PIX-FMT-BGR24"><constant>V4L2_PIX_FMT_BGR24</constant></link>,
+<link linkend="V4L2-PIX-FMT-HM12"><constant>V4L2_PIX_FMT_HM12</constant></link>,
+<link linkend="V4L2-PIX-FMT-JPEG"><constant>V4L2_PIX_FMT_JPEG</constant></link>,
+<link linkend="V4L2-PIX-FMT-MJPEG"><constant>V4L2_PIX_FMT_MJPEG</constant></link>,
+<link linkend="V4L2-PIX-FMT-MR97310A"><constant>V4L2_PIX_FMT_MR97310A</constant></link>,
+<link linkend="V4L2-PIX-FMT-OV511"><constant>V4L2_PIX_FMT_OV511</constant></link>,
+<link linkend="V4L2-PIX-FMT-OV518"><constant>V4L2_PIX_FMT_OV518</constant></link>,
+<link linkend="V4L2-PIX-FMT-PAC207"><constant>V4L2_PIX_FMT_PAC207</constant></link>,
+<link linkend="V4L2-PIX-FMT-PJPG"><constant>V4L2_PIX_FMT_PJPG</constant></link>,
+<link linkend="V4L2-PIX-FMT-RGB24"><constant>V4L2_PIX_FMT_RGB24</constant></link>,
+<link linkend="V4L2-PIX-FMT-SBGGR8"><constant>V4L2_PIX_FMT_SBGGR8</constant></link>,
+<link linkend="V4L2-PIX-FMT-SGBRG8"><constant>V4L2_PIX_FMT_SGBRG8</constant></link>,
+<link linkend="V4L2-PIX-FMT-SGRBG8"><constant>V4L2_PIX_FMT_SGRBG8</constant></link>,
+<link linkend="V4L2-PIX-FMT-SN9C10X"><constant>V4L2_PIX_FMT_SN9C10X</constant></link>,
+<link linkend="V4L2-PIX-FMT-SN9C20X-I420"><constant>V4L2_PIX_FMT_SN9C20X_I420</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA501"><constant>V4L2_PIX_FMT_SPCA501</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA505"><constant>V4L2_PIX_FMT_SPCA505</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA508"><constant>V4L2_PIX_FMT_SPCA508</constant></link>,
+<link linkend="V4L2-PIX-FMT-SPCA561"><constant>V4L2_PIX_FMT_SPCA561</constant></link>,
+<link linkend="V4L2-PIX-FMT-SQ905C"><constant>V4L2_PIX_FMT_SQ905C</constant></link>,
+<constant>V4L2_PIX_FMT_SRGGB8</constant>,
+<link linkend="V4L2-PIX-FMT-UYVY"><constant>V4L2_PIX_FMT_UYVY</constant></link>,
+<link linkend="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></link>,
+<link linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link>,
+<link linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link>,
+and <link linkend="V4L2-PIX-FMT-YVYU"><constant>V4L2_PIX_FMT_YVYU</constant></link>.
+</para>
+		<para>Later on libv4lconvert was expanded to also be able to do
+various	video processing functions to improve webcam video quality.
+The video processing is split in to 2 parts: libv4lconvert/control and
+libv4lconvert/processing.</para>
+
+		<para>The control part is used to offer video controls which can
+be used	to control the video processing functions made available by
+	libv4lconvert/processing. These controls are stored application wide
+(until reboot) by using a persistent shared memory object.</para>
+
+		<para>libv4lconvert/processing offers the actual video
+processing functionality.</para>
+	</section>
+	<section>
+		<title>libv4l1</title>
+		<para>This library offers functions that can be used to quickly
+make v4l1 applications work with v4l2 devices. These functions work exactly
+like the normal open/close/etc, except that libv4l1 does full emulation of
+the v4l1 api on top of v4l2 drivers, in case of v4l1 drivers it
+will just pass calls through.</para>
+		<para>Since those functions are emulations of the old V4L1 API,
+it shouldn't be used for new applications.</para>
+	</section>
+	<section>
+		<title>libv4l2</title>
+		<para>This library should be used for all modern V4L2
+applications.</para>
+		<para>It provides handles to call V4L2 open/ioctl/close/poll
+methods. Instead of just providing the raw output of the device, it enhances
+the calls in the sense that it will use libv4lconvert to provide more video
+formats and to enhance the image quality.</para>
+		<para>In most cases, libv4l2 just passes the calls directly
+through to the v4l2 driver, intercepting the calls to
+<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>,
+<link linkend='vidioc-g-fmt'><constant>VIDIOC_G_FMT</constant></link>
+<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>
+<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>
+and <link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>
+in order to emulate the formats
+<link linkend="V4L2-PIX-FMT-BGR24"><constant>V4L2_PIX_FMT_BGR24</constant></link>,
+<link linkend="V4L2-PIX-FMT-RGB24"><constant>V4L2_PIX_FMT_RGB24</constant></link>,
+<link linkend="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></link>,
+and <link linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link>,
+if they aren't available in the driver.
+<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>
+keeps enumerating the hardware supported formats, plus the emulated formats
+offered by libv4l at the end.
+</para>
+		<section id="libv4l-ops">
+			<title>Libv4l device control functions</title>
+			<para>The common file operation methods are provided by
+libv4l.</para>
+			<para>Those functions operate just like glibc
+open/close/dup/ioctl/read/mmap/munmap:</para>
+<itemizedlist><listitem>
+			<para>int v4l2_open(const char *file, int oflag,
+...) -
+operates like the standard <link linkend='func-open'>open()</link> function.
+</para></listitem><listitem>
+			<para>int v4l2_close(int fd) -
+operates like the standard <link linkend='func-close'>close()</link> function.
+</para></listitem><listitem>
+			<para>int v4l2_dup(int fd) -
+operates like the standard dup() function, duplicating a file handler.
+</para></listitem><listitem>
+			<para>int v4l2_ioctl (int fd, unsigned long int request, ...) -
+operates like the standard <link linkend='func-ioctl'>ioctl()</link> function.
+</para></listitem><listitem>
+			<para>int v4l2_read (int fd, void* buffer, size_t n) -
+operates like the standard <link linkend='func-read'>read()</link> function.
+</para></listitem><listitem>
+			<para>void v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset); -
+operates like the standard <link linkend='func-mmap'>mmap()</link> function.
+</para></listitem><listitem>
+			<para>int v4l2_munmap(void *_start, size_t length); -
+operates like the standard <link linkend='func-munmap'>munmap()</link> function.
+</para></listitem>
+</itemizedlist>
+			<para>Those functions provide additional control:</para>
+<itemizedlist><listitem>
+			<para>int v4l2_fd_open(int fd, int v4l2_flags) -
+opens an already opened fd for further use through v4l2lib and possibly
+modify libv4l2's default behavior through the v4l2_flags argument.
+Currently, v4l2_flags can be <constant>V4L2_DISABLE_CONVERSION</constant>,
+to disable format conversion.
+</para></listitem><listitem>
+			<para>int v4l2_set_control(int fd, int cid, int value) -
+This function takes a value of 0 - 65535, and then scales that range to
+the actual range of the given v4l control id, and then if the cid exists
+and is not locked sets the cid to the scaled value.
+</para></listitem><listitem>
+			<para>int v4l2_get_control(int fd, int cid) -
+This function returns a value of 0 - 65535, scaled to from the actual range
+of the given v4l control id. when the cid does not exist, could not be
+accessed for some reason, or some error occured 0 is returned.
+</para></listitem>
+</itemizedlist>
+		</section>
+	</section>
+	<section>
+
+		<title>v4l1compat.so wrapper library</title>
+
+		<para>This library intercepts calls to
+open/close/ioctl/mmap/mmunmap operations and redirects them to the libv4l
+counterparts, by using LD_PRELOAD=/usr/lib/v4l1compat.so. It also
+emulates V4L1 calls via V4L2 API.</para>
+		<para>It allows usage of binary legacy applications that
+still don't use libv4l.</para>
+	</section>
+
+</section>
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/pixfmt-grey.xml b/Documentation/DocBook/v4l/pixfmt-grey.xml
new file mode 100644
index 0000000..3b72bc6
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-grey.xml
@@ -0,0 +1,70 @@
+    <refentry id="V4L2-PIX-FMT-GREY">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_GREY ('GREY')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_GREY</constant></refname>
+	<refpurpose>Grey-scale image</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This is a grey-scale image. It is really a degenerate
+Y'CbCr format which simply contains no Cb or Cr data.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_GREY</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-nv12.xml b/Documentation/DocBook/v4l/pixfmt-nv12.xml
new file mode 100644
index 0000000..873f670
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv12.xml
@@ -0,0 +1,151 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_NV12 ('NV12'), V4L2_PIX_FMT_NV21 ('NV21')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-NV12"><constant>V4L2_PIX_FMT_NV12</constant></refname>
+	<refname id="V4L2-PIX-FMT-NV21"><constant>V4L2_PIX_FMT_NV21</constant></refname>
+	<refpurpose>Formats with &frac12; horizontal and vertical
+chroma resolution, also known as YUV 4:2:0. One luminance and one
+chrominance plane with alternating chroma samples as opposed to
+<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>These are two-plane versions of the YUV 4:2:0 format.
+The three components are separated into two sub-images or planes. The
+Y plane is first. The Y plane has one byte per pixel. For
+<constant>V4L2_PIX_FMT_NV12</constant>, a combined CbCr plane
+immediately follows the Y plane in memory.  The CbCr plane is the same
+width, in bytes, as the Y plane (and of the image), but is half as
+tall in pixels. Each CbCr pair belongs to four pixels. For example,
+Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
+Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
+Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.
+<constant>V4L2_PIX_FMT_NV21</constant> is the same except the Cb and
+Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
+
+	<para>If the Y plane has pad bytes after each row, then the
+CbCr plane has as many pad bytes after its rows.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_NV12</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;20:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-nv16.xml b/Documentation/DocBook/v4l/pixfmt-nv16.xml
new file mode 100644
index 0000000..2609403
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv16.xml
@@ -0,0 +1,174 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_NV16 ('NV16'), V4L2_PIX_FMT_NV61 ('NV61')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-NV16"><constant>V4L2_PIX_FMT_NV16</constant></refname>
+	<refname id="V4L2-PIX-FMT-NV61"><constant>V4L2_PIX_FMT_NV61</constant></refname>
+	<refpurpose>Formats with &frac12; horizontal
+chroma resolution, also known as YUV 4:2:2. One luminance and one
+chrominance plane with alternating chroma samples as opposed to
+<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>These are two-plane versions of the YUV 4:2:2 format.
+The three components are separated into two sub-images or planes. The
+Y plane is first. The Y plane has one byte per pixel. For
+<constant>V4L2_PIX_FMT_NV16</constant>, a combined CbCr plane
+immediately follows the Y plane in memory.  The CbCr plane is the same
+width and height, in bytes, as the Y plane (and of the image).
+Each CbCr pair belongs to two pixels. For example,
+Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
+Y'<subscript>00</subscript>, Y'<subscript>01</subscript>.
+<constant>V4L2_PIX_FMT_NV61</constant> is the same except the Cb and
+Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
+
+	<para>If the Y plane has pad bytes after each row, then the
+CbCr plane has as many pad bytes after its rows.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_NV16</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;20:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		      <entry>Cb<subscript>21</subscript></entry>
+		      <entry>Cr<subscript>21</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;28:</entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		      <entry>Cb<subscript>31</subscript></entry>
+		      <entry>Cr<subscript>31</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml b/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml
new file mode 100644
index 0000000..d2dd697
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml
@@ -0,0 +1,862 @@
+<refentry id="packed-rgb">
+  <refmeta>
+    <refentrytitle>Packed RGB formats</refentrytitle>
+    &manvol;
+  </refmeta>
+  <refnamediv>
+    <refname>Packed RGB formats</refname>
+    <refpurpose>Packed RGB formats</refpurpose>
+  </refnamediv>
+  <refsect1>
+    <title>Description</title>
+
+    <para>These formats are designed to match the pixel formats of
+typical PC graphics frame buffers. They occupy 8, 16, 24 or 32 bits
+per pixel. These are all packed-pixel formats, meaning all the data
+for a pixel lie next to each other in memory.</para>
+
+    <para>When one of these formats is used, drivers shall report the
+colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
+
+    <table pgwide="1" frame="none" id="rgb-formats">
+      <title>Packed RGB Image Formats</title>
+      <tgroup cols="37" align="center">
+	<colspec colname="id" align="left" />
+	<colspec colname="fourcc" />
+	<colspec colname="bit" />
+
+	<colspec colnum="4" colname="b07" align="center" />
+	<colspec colnum="5" colname="b06" align="center" />
+	<colspec colnum="6" colname="b05" align="center" />
+	<colspec colnum="7" colname="b04" align="center" />
+	<colspec colnum="8" colname="b03" align="center" />
+	<colspec colnum="9" colname="b02" align="center" />
+	<colspec colnum="10" colname="b01" align="center" />
+	<colspec colnum="11" colname="b00" align="center" />
+
+	<colspec colnum="13" colname="b17" align="center" />
+	<colspec colnum="14" colname="b16" align="center" />
+	<colspec colnum="15" colname="b15" align="center" />
+	<colspec colnum="16" colname="b14" align="center" />
+	<colspec colnum="17" colname="b13" align="center" />
+	<colspec colnum="18" colname="b12" align="center" />
+	<colspec colnum="19" colname="b11" align="center" />
+	<colspec colnum="20" colname="b10" align="center" />
+
+	<colspec colnum="22" colname="b27" align="center" />
+	<colspec colnum="23" colname="b26" align="center" />
+	<colspec colnum="24" colname="b25" align="center" />
+	<colspec colnum="25" colname="b24" align="center" />
+	<colspec colnum="26" colname="b23" align="center" />
+	<colspec colnum="27" colname="b22" align="center" />
+	<colspec colnum="28" colname="b21" align="center" />
+	<colspec colnum="29" colname="b20" align="center" />
+
+	<colspec colnum="31" colname="b37" align="center" />
+	<colspec colnum="32" colname="b36" align="center" />
+	<colspec colnum="33" colname="b35" align="center" />
+	<colspec colnum="34" colname="b34" align="center" />
+	<colspec colnum="35" colname="b33" align="center" />
+	<colspec colnum="36" colname="b32" align="center" />
+	<colspec colnum="37" colname="b31" align="center" />
+	<colspec colnum="38" colname="b30" align="center" />
+
+	<spanspec namest="b07" nameend="b00" spanname="b0" />
+	<spanspec namest="b17" nameend="b10" spanname="b1" />
+	<spanspec namest="b27" nameend="b20" spanname="b2" />
+	<spanspec namest="b37" nameend="b30" spanname="b3" />
+	<thead>
+	  <row>
+	    <entry>Identifier</entry>
+	    <entry>Code</entry>
+	    <entry>&nbsp;</entry>
+	    <entry spanname="b0">Byte&nbsp;0 in memory</entry>
+	    <entry spanname="b1">Byte&nbsp;1</entry>
+	    <entry spanname="b2">Byte&nbsp;2</entry>
+	    <entry spanname="b3">Byte&nbsp;3</entry>
+	  </row>
+	  <row>
+	    <entry>&nbsp;</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>Bit</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row id="V4L2-PIX-FMT-RGB332">
+	    <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
+	    <entry>'RGB1'</entry>
+	    <entry></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-RGB444">
+	    <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
+	    <entry>'R444'</entry>
+	    <entry></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-RGB555">
+	    <entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
+	    <entry>'RGBO'</entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a</entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-RGB565">
+	    <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
+	    <entry>'RGBP'</entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-RGB555X">
+	    <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
+	    <entry>'RGBQ'</entry>
+	    <entry></entry>
+	    <entry>a</entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-RGB565X">
+	    <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
+	    <entry>'RGBR'</entry>
+	    <entry></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-BGR24">
+	    <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
+	    <entry>'BGR3'</entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-RGB24">
+	    <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
+	    <entry>'RGB3'</entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-BGR32">
+	    <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
+	    <entry>'BGR4'</entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a<subscript>7</subscript></entry>
+	    <entry>a<subscript>6</subscript></entry>
+	    <entry>a<subscript>5</subscript></entry>
+	    <entry>a<subscript>4</subscript></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-RGB32">
+	    <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
+	    <entry>'RGB4'</entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a<subscript>7</subscript></entry>
+	    <entry>a<subscript>6</subscript></entry>
+	    <entry>a<subscript>5</subscript></entry>
+	    <entry>a<subscript>4</subscript></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <para>Bit 7 is the most significant bit. The value of a = alpha
+bits is undefined when reading from the driver, ignored when writing
+to the driver, except when alpha blending has been negotiated for a
+<link linkend="overlay">Video Overlay</link> or <link
+linkend="osd">Video Output Overlay</link>.</para>
+
+    <example>
+      <title><constant>V4L2_PIX_FMT_BGR24</constant> 4 &times; 4 pixel
+image</title>
+
+      <formalpara>
+	<title>Byte Order.</title>
+	<para>Each cell is one byte.
+	      <informaltable frame="none">
+	    <tgroup cols="13" align="center">
+	      <colspec align="left" colwidth="2*" />
+	      <tbody valign="top">
+		<row>
+		  <entry>start&nbsp;+&nbsp;0:</entry>
+		  <entry>B<subscript>00</subscript></entry>
+		  <entry>G<subscript>00</subscript></entry>
+		  <entry>R<subscript>00</subscript></entry>
+		  <entry>B<subscript>01</subscript></entry>
+		  <entry>G<subscript>01</subscript></entry>
+		  <entry>R<subscript>01</subscript></entry>
+		  <entry>B<subscript>02</subscript></entry>
+		  <entry>G<subscript>02</subscript></entry>
+		  <entry>R<subscript>02</subscript></entry>
+		  <entry>B<subscript>03</subscript></entry>
+		  <entry>G<subscript>03</subscript></entry>
+		  <entry>R<subscript>03</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;12:</entry>
+		  <entry>B<subscript>10</subscript></entry>
+		  <entry>G<subscript>10</subscript></entry>
+		  <entry>R<subscript>10</subscript></entry>
+		  <entry>B<subscript>11</subscript></entry>
+		  <entry>G<subscript>11</subscript></entry>
+		  <entry>R<subscript>11</subscript></entry>
+		  <entry>B<subscript>12</subscript></entry>
+		  <entry>G<subscript>12</subscript></entry>
+		  <entry>R<subscript>12</subscript></entry>
+		  <entry>B<subscript>13</subscript></entry>
+		  <entry>G<subscript>13</subscript></entry>
+		  <entry>R<subscript>13</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;24:</entry>
+		  <entry>B<subscript>20</subscript></entry>
+		  <entry>G<subscript>20</subscript></entry>
+		  <entry>R<subscript>20</subscript></entry>
+		  <entry>B<subscript>21</subscript></entry>
+		  <entry>G<subscript>21</subscript></entry>
+		  <entry>R<subscript>21</subscript></entry>
+		  <entry>B<subscript>22</subscript></entry>
+		  <entry>G<subscript>22</subscript></entry>
+		  <entry>R<subscript>22</subscript></entry>
+		  <entry>B<subscript>23</subscript></entry>
+		  <entry>G<subscript>23</subscript></entry>
+		  <entry>R<subscript>23</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;36:</entry>
+		  <entry>B<subscript>30</subscript></entry>
+		  <entry>G<subscript>30</subscript></entry>
+		  <entry>R<subscript>30</subscript></entry>
+		  <entry>B<subscript>31</subscript></entry>
+		  <entry>G<subscript>31</subscript></entry>
+		  <entry>R<subscript>31</subscript></entry>
+		  <entry>B<subscript>32</subscript></entry>
+		  <entry>G<subscript>32</subscript></entry>
+		  <entry>R<subscript>32</subscript></entry>
+		  <entry>B<subscript>33</subscript></entry>
+		  <entry>G<subscript>33</subscript></entry>
+		  <entry>R<subscript>33</subscript></entry>
+		</row>
+	      </tbody>
+	    </tgroup>
+	      </informaltable>
+	    </para>
+      </formalpara>
+    </example>
+
+    <important>
+      <para>Drivers may interpret these formats differently.</para>
+    </important>
+
+    <para>Some RGB formats above are uncommon and were probably
+defined in error. Drivers may interpret them as in <xref
+	linkend="rgb-formats-corrected" />.</para>
+
+    <table pgwide="1" frame="none" id="rgb-formats-corrected">
+      <title>Packed RGB Image Formats (corrected)</title>
+      <tgroup cols="37" align="center">
+	<colspec colname="id" align="left" />
+	<colspec colname="fourcc" />
+	<colspec colname="bit" />
+
+	<colspec colnum="4" colname="b07" align="center" />
+	<colspec colnum="5" colname="b06" align="center" />
+	<colspec colnum="6" colname="b05" align="center" />
+	<colspec colnum="7" colname="b04" align="center" />
+	<colspec colnum="8" colname="b03" align="center" />
+	<colspec colnum="9" colname="b02" align="center" />
+	<colspec colnum="10" colname="b01" align="center" />
+	<colspec colnum="11" colname="b00" align="center" />
+
+	<colspec colnum="13" colname="b17" align="center" />
+	<colspec colnum="14" colname="b16" align="center" />
+	<colspec colnum="15" colname="b15" align="center" />
+	<colspec colnum="16" colname="b14" align="center" />
+	<colspec colnum="17" colname="b13" align="center" />
+	<colspec colnum="18" colname="b12" align="center" />
+	<colspec colnum="19" colname="b11" align="center" />
+	<colspec colnum="20" colname="b10" align="center" />
+
+	<colspec colnum="22" colname="b27" align="center" />
+	<colspec colnum="23" colname="b26" align="center" />
+	<colspec colnum="24" colname="b25" align="center" />
+	<colspec colnum="25" colname="b24" align="center" />
+	<colspec colnum="26" colname="b23" align="center" />
+	<colspec colnum="27" colname="b22" align="center" />
+	<colspec colnum="28" colname="b21" align="center" />
+	<colspec colnum="29" colname="b20" align="center" />
+
+	<colspec colnum="31" colname="b37" align="center" />
+	<colspec colnum="32" colname="b36" align="center" />
+	<colspec colnum="33" colname="b35" align="center" />
+	<colspec colnum="34" colname="b34" align="center" />
+	<colspec colnum="35" colname="b33" align="center" />
+	<colspec colnum="36" colname="b32" align="center" />
+	<colspec colnum="37" colname="b31" align="center" />
+	<colspec colnum="38" colname="b30" align="center" />
+
+	<spanspec namest="b07" nameend="b00" spanname="b0" />
+	<spanspec namest="b17" nameend="b10" spanname="b1" />
+	<spanspec namest="b27" nameend="b20" spanname="b2" />
+	<spanspec namest="b37" nameend="b30" spanname="b3" />
+	<thead>
+	  <row>
+	    <entry>Identifier</entry>
+	    <entry>Code</entry>
+	    <entry>&nbsp;</entry>
+	    <entry spanname="b0">Byte&nbsp;0 in memory</entry>
+	    <entry spanname="b1">Byte&nbsp;1</entry>
+	    <entry spanname="b2">Byte&nbsp;2</entry>
+	    <entry spanname="b3">Byte&nbsp;3</entry>
+	  </row>
+	  <row>
+	    <entry>&nbsp;</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>Bit</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row><!-- id="V4L2-PIX-FMT-RGB332" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
+	    <entry>'RGB1'</entry>
+	    <entry></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-RGB444" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
+	    <entry>'R444'</entry>
+	    <entry></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-RGB555" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
+	    <entry>'RGBO'</entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a</entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-RGB565" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
+	    <entry>'RGBP'</entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-RGB555X" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
+	    <entry>'RGBQ'</entry>
+	    <entry></entry>
+	    <entry>a</entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-RGB565X" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
+	    <entry>'RGBR'</entry>
+	    <entry></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-BGR24" -->
+	    <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
+	    <entry>'BGR3'</entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-RGB24" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
+	    <entry>'RGB3'</entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-BGR32" -->
+	    <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
+	    <entry>'BGR4'</entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a<subscript>7</subscript></entry>
+	    <entry>a<subscript>6</subscript></entry>
+	    <entry>a<subscript>5</subscript></entry>
+	    <entry>a<subscript>4</subscript></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	  </row>
+	  <row><!-- id="V4L2-PIX-FMT-RGB32" -->
+	    <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
+	    <entry>'RGB4'</entry>
+	    <entry></entry>
+	    <entry>a<subscript>7</subscript></entry>
+	    <entry>a<subscript>6</subscript></entry>
+	    <entry>a<subscript>5</subscript></entry>
+	    <entry>a<subscript>4</subscript></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>r<subscript>7</subscript></entry>
+	    <entry>r<subscript>6</subscript></entry>
+	    <entry>r<subscript>5</subscript></entry>
+	    <entry>r<subscript>4</subscript></entry>
+	    <entry>r<subscript>3</subscript></entry>
+	    <entry>r<subscript>2</subscript></entry>
+	    <entry>r<subscript>1</subscript></entry>
+	    <entry>r<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>g<subscript>7</subscript></entry>
+	    <entry>g<subscript>6</subscript></entry>
+	    <entry>g<subscript>5</subscript></entry>
+	    <entry>g<subscript>4</subscript></entry>
+	    <entry>g<subscript>3</subscript></entry>
+	    <entry>g<subscript>2</subscript></entry>
+	    <entry>g<subscript>1</subscript></entry>
+	    <entry>g<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>b<subscript>7</subscript></entry>
+	    <entry>b<subscript>6</subscript></entry>
+	    <entry>b<subscript>5</subscript></entry>
+	    <entry>b<subscript>4</subscript></entry>
+	    <entry>b<subscript>3</subscript></entry>
+	    <entry>b<subscript>2</subscript></entry>
+	    <entry>b<subscript>1</subscript></entry>
+	    <entry>b<subscript>0</subscript></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <para>A test utility to determine which RGB formats a driver
+actually supports is available from the LinuxTV v4l-dvb repository.
+See &v4l-dvb; for access instructions.</para>
+
+  </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml b/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml
new file mode 100644
index 0000000..3cab5d0
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml
@@ -0,0 +1,244 @@
+<refentry id="packed-yuv">
+  <refmeta>
+    <refentrytitle>Packed YUV formats</refentrytitle>
+    &manvol;
+  </refmeta>
+  <refnamediv>
+    <refname>Packed YUV formats</refname>
+    <refpurpose>Packed YUV formats</refpurpose>
+  </refnamediv>
+  <refsect1>
+    <title>Description</title>
+
+    <para>Similar to the packed RGB formats these formats store
+the Y, Cb and Cr component of each pixel in one 16 or 32 bit
+word.</para>
+
+    <table pgwide="1" frame="none">
+      <title>Packed YUV Image Formats</title>
+      <tgroup cols="37" align="center">
+	<colspec colname="id" align="left" />
+	<colspec colname="fourcc" />
+	<colspec colname="bit" />
+
+	<colspec colnum="4" colname="b07" align="center" />
+	<colspec colnum="5" colname="b06" align="center" />
+	<colspec colnum="6" colname="b05" align="center" />
+	<colspec colnum="7" colname="b04" align="center" />
+	<colspec colnum="8" colname="b03" align="center" />
+	<colspec colnum="9" colname="b02" align="center" />
+	<colspec colnum="10" colname="b01" align="center" />
+	<colspec colnum="11" colname="b00" align="center" />
+
+	<colspec colnum="13" colname="b17" align="center" />
+	<colspec colnum="14" colname="b16" align="center" />
+	<colspec colnum="15" colname="b15" align="center" />
+	<colspec colnum="16" colname="b14" align="center" />
+	<colspec colnum="17" colname="b13" align="center" />
+	<colspec colnum="18" colname="b12" align="center" />
+	<colspec colnum="19" colname="b11" align="center" />
+	<colspec colnum="20" colname="b10" align="center" />
+
+	<colspec colnum="22" colname="b27" align="center" />
+	<colspec colnum="23" colname="b26" align="center" />
+	<colspec colnum="24" colname="b25" align="center" />
+	<colspec colnum="25" colname="b24" align="center" />
+	<colspec colnum="26" colname="b23" align="center" />
+	<colspec colnum="27" colname="b22" align="center" />
+	<colspec colnum="28" colname="b21" align="center" />
+	<colspec colnum="29" colname="b20" align="center" />
+
+	<colspec colnum="31" colname="b37" align="center" />
+	<colspec colnum="32" colname="b36" align="center" />
+	<colspec colnum="33" colname="b35" align="center" />
+	<colspec colnum="34" colname="b34" align="center" />
+	<colspec colnum="35" colname="b33" align="center" />
+	<colspec colnum="36" colname="b32" align="center" />
+	<colspec colnum="37" colname="b31" align="center" />
+	<colspec colnum="38" colname="b30" align="center" />
+
+	<spanspec namest="b07" nameend="b00" spanname="b0" />
+	<spanspec namest="b17" nameend="b10" spanname="b1" />
+	<spanspec namest="b27" nameend="b20" spanname="b2" />
+	<spanspec namest="b37" nameend="b30" spanname="b3" />
+	<thead>
+	  <row>
+	    <entry>Identifier</entry>
+	    <entry>Code</entry>
+	    <entry>&nbsp;</entry>
+	    <entry spanname="b0">Byte&nbsp;0 in memory</entry>
+	    <entry spanname="b1">Byte&nbsp;1</entry>
+	    <entry spanname="b2">Byte&nbsp;2</entry>
+	    <entry spanname="b3">Byte&nbsp;3</entry>
+	  </row>
+	  <row>
+	    <entry>&nbsp;</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>Bit</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row id="V4L2-PIX-FMT-YUV444">
+	    <entry><constant>V4L2_PIX_FMT_YUV444</constant></entry>
+	    <entry>'Y444'</entry>
+	    <entry></entry>
+	    <entry>Cb<subscript>3</subscript></entry>
+	    <entry>Cb<subscript>2</subscript></entry>
+	    <entry>Cb<subscript>1</subscript></entry>
+	    <entry>Cb<subscript>0</subscript></entry>
+	    <entry>Cr<subscript>3</subscript></entry>
+	    <entry>Cr<subscript>2</subscript></entry>
+	    <entry>Cr<subscript>1</subscript></entry>
+	    <entry>Cr<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	    <entry>Y'<subscript>3</subscript></entry>
+	    <entry>Y'<subscript>2</subscript></entry>
+	    <entry>Y'<subscript>1</subscript></entry>
+	    <entry>Y'<subscript>0</subscript></entry>
+	  </row>
+
+	  <row id="V4L2-PIX-FMT-YUV555">
+	    <entry><constant>V4L2_PIX_FMT_YUV555</constant></entry>
+	    <entry>'YUVO'</entry>
+	    <entry></entry>
+	    <entry>Cb<subscript>2</subscript></entry>
+	    <entry>Cb<subscript>1</subscript></entry>
+	    <entry>Cb<subscript>0</subscript></entry>
+	    <entry>Cr<subscript>4</subscript></entry>
+	    <entry>Cr<subscript>3</subscript></entry>
+	    <entry>Cr<subscript>2</subscript></entry>
+	    <entry>Cr<subscript>1</subscript></entry>
+	    <entry>Cr<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>a</entry>
+	    <entry>Y'<subscript>4</subscript></entry>
+	    <entry>Y'<subscript>3</subscript></entry>
+	    <entry>Y'<subscript>2</subscript></entry>
+	    <entry>Y'<subscript>1</subscript></entry>
+	    <entry>Y'<subscript>0</subscript></entry>
+	    <entry>Cb<subscript>4</subscript></entry>
+	    <entry>Cb<subscript>3</subscript></entry>
+	  </row>
+
+	  <row id="V4L2-PIX-FMT-YUV565">
+	    <entry><constant>V4L2_PIX_FMT_YUV565</constant></entry>
+	    <entry>'YUVP'</entry>
+	    <entry></entry>
+	    <entry>Cb<subscript>2</subscript></entry>
+	    <entry>Cb<subscript>1</subscript></entry>
+	    <entry>Cb<subscript>0</subscript></entry>
+	    <entry>Cr<subscript>4</subscript></entry>
+	    <entry>Cr<subscript>3</subscript></entry>
+	    <entry>Cr<subscript>2</subscript></entry>
+	    <entry>Cr<subscript>1</subscript></entry>
+	    <entry>Cr<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>Y'<subscript>4</subscript></entry>
+	    <entry>Y'<subscript>3</subscript></entry>
+	    <entry>Y'<subscript>2</subscript></entry>
+	    <entry>Y'<subscript>1</subscript></entry>
+	    <entry>Y'<subscript>0</subscript></entry>
+	    <entry>Cb<subscript>5</subscript></entry>
+	    <entry>Cb<subscript>4</subscript></entry>
+	    <entry>Cb<subscript>3</subscript></entry>
+	  </row>
+
+	  <row id="V4L2-PIX-FMT-YUV32">
+	    <entry><constant>V4L2_PIX_FMT_YUV32</constant></entry>
+	    <entry>'YUV4'</entry>
+	    <entry></entry>
+	    <entry>a<subscript>7</subscript></entry>
+	    <entry>a<subscript>6</subscript></entry>
+	    <entry>a<subscript>5</subscript></entry>
+	    <entry>a<subscript>4</subscript></entry>
+	    <entry>a<subscript>3</subscript></entry>
+	    <entry>a<subscript>2</subscript></entry>
+	    <entry>a<subscript>1</subscript></entry>
+	    <entry>a<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>Y'<subscript>7</subscript></entry>
+	    <entry>Y'<subscript>6</subscript></entry>
+	    <entry>Y'<subscript>5</subscript></entry>
+	    <entry>Y'<subscript>4</subscript></entry>
+	    <entry>Y'<subscript>3</subscript></entry>
+	    <entry>Y'<subscript>2</subscript></entry>
+	    <entry>Y'<subscript>1</subscript></entry>
+	    <entry>Y'<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>Cb<subscript>7</subscript></entry>
+	    <entry>Cb<subscript>6</subscript></entry>
+	    <entry>Cb<subscript>5</subscript></entry>
+	    <entry>Cb<subscript>4</subscript></entry>
+	    <entry>Cb<subscript>3</subscript></entry>
+	    <entry>Cb<subscript>2</subscript></entry>
+	    <entry>Cb<subscript>1</subscript></entry>
+	    <entry>Cb<subscript>0</subscript></entry>
+	    <entry></entry>
+	    <entry>Cr<subscript>7</subscript></entry>
+	    <entry>Cr<subscript>6</subscript></entry>
+	    <entry>Cr<subscript>5</subscript></entry>
+	    <entry>Cr<subscript>4</subscript></entry>
+	    <entry>Cr<subscript>3</subscript></entry>
+	    <entry>Cr<subscript>2</subscript></entry>
+	    <entry>Cr<subscript>1</subscript></entry>
+	    <entry>Cr<subscript>0</subscript></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <para>Bit 7 is the most significant bit. The value of a = alpha
+bits is undefined when reading from the driver, ignored when writing
+to the driver, except when alpha blending has been negotiated for a
+<link linkend="overlay">Video Overlay</link> or <link
+linkend="osd">Video Output Overlay</link>.</para>
+
+  </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sbggr16.xml b/Documentation/DocBook/v4l/pixfmt-sbggr16.xml
new file mode 100644
index 0000000..519a9ef
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sbggr16.xml
@@ -0,0 +1,91 @@
+<refentry id="V4L2-PIX-FMT-SBGGR16">
+  <refmeta>
+    <refentrytitle>V4L2_PIX_FMT_SBGGR16 ('BYR2')</refentrytitle>
+    &manvol;
+  </refmeta>
+  <refnamediv>
+    <refname><constant>V4L2_PIX_FMT_SBGGR16</constant></refname>
+    <refpurpose>Bayer RGB format</refpurpose>
+  </refnamediv>
+  <refsect1>
+    <title>Description</title>
+
+    <para>This format is similar to <link
+linkend="V4L2-PIX-FMT-SBGGR8">
+<constant>V4L2_PIX_FMT_SBGGR8</constant></link>, except each pixel has
+a depth of 16 bits. The least significant byte is stored at lower
+memory addresses (little-endian). Note the actual sampling precision
+may be lower than 16 bits, for example 10 bits per pixel with values
+in range 0 to 1023.</para>
+
+    <example>
+      <title><constant>V4L2_PIX_FMT_SBGGR16</constant> 4 &times; 4
+pixel image</title>
+
+      <formalpara>
+	<title>Byte Order.</title>
+	<para>Each cell is one byte.
+	  <informaltable frame="none">
+	    <tgroup cols="5" align="center">
+	      <colspec align="left" colwidth="2*" />
+	      <tbody valign="top">
+		<row>
+		  <entry>start&nbsp;+&nbsp;0:</entry>
+		  <entry>B<subscript>00low</subscript></entry>
+		  <entry>B<subscript>00high</subscript></entry>
+		  <entry>G<subscript>01low</subscript></entry>
+		  <entry>G<subscript>01high</subscript></entry>
+		  <entry>B<subscript>02low</subscript></entry>
+		  <entry>B<subscript>02high</subscript></entry>
+		  <entry>G<subscript>03low</subscript></entry>
+		  <entry>G<subscript>03high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;8:</entry>
+		  <entry>G<subscript>10low</subscript></entry>
+		  <entry>G<subscript>10high</subscript></entry>
+		  <entry>R<subscript>11low</subscript></entry>
+		  <entry>R<subscript>11high</subscript></entry>
+		  <entry>G<subscript>12low</subscript></entry>
+		  <entry>G<subscript>12high</subscript></entry>
+		  <entry>R<subscript>13low</subscript></entry>
+		  <entry>R<subscript>13high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;16:</entry>
+		  <entry>B<subscript>20low</subscript></entry>
+		  <entry>B<subscript>20high</subscript></entry>
+		  <entry>G<subscript>21low</subscript></entry>
+		  <entry>G<subscript>21high</subscript></entry>
+		  <entry>B<subscript>22low</subscript></entry>
+		  <entry>B<subscript>22high</subscript></entry>
+		  <entry>G<subscript>23low</subscript></entry>
+		  <entry>G<subscript>23high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;24:</entry>
+		  <entry>G<subscript>30low</subscript></entry>
+		  <entry>G<subscript>30high</subscript></entry>
+		  <entry>R<subscript>31low</subscript></entry>
+		  <entry>R<subscript>31high</subscript></entry>
+		  <entry>G<subscript>32low</subscript></entry>
+		  <entry>G<subscript>32high</subscript></entry>
+		  <entry>R<subscript>33low</subscript></entry>
+		  <entry>R<subscript>33high</subscript></entry>
+		</row>
+	      </tbody>
+	    </tgroup>
+	  </informaltable>
+	</para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sbggr8.xml b/Documentation/DocBook/v4l/pixfmt-sbggr8.xml
new file mode 100644
index 0000000..5fe84ec
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sbggr8.xml
@@ -0,0 +1,75 @@
+    <refentry id="V4L2-PIX-FMT-SBGGR8">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_SBGGR8 ('BA81')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_SBGGR8</constant></refname>
+	<refpurpose>Bayer RGB format</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This is commonly the native format of digital cameras,
+reflecting the arrangement of sensors on the CCD device. Only one red,
+green or blue value is given for each pixel. Missing components must
+be interpolated from neighbouring pixels. From left to right the first
+row consists of a blue and green value, the second row of a green and
+red value. This scheme repeats to the right and down for every two
+columns and rows.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_SBGGR8</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+	      <informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>B<subscript>00</subscript></entry>
+		      <entry>G<subscript>01</subscript></entry>
+		      <entry>B<subscript>02</subscript></entry>
+		      <entry>G<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>G<subscript>10</subscript></entry>
+		      <entry>R<subscript>11</subscript></entry>
+		      <entry>G<subscript>12</subscript></entry>
+		      <entry>R<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>B<subscript>20</subscript></entry>
+		      <entry>G<subscript>21</subscript></entry>
+		      <entry>B<subscript>22</subscript></entry>
+		      <entry>G<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>G<subscript>30</subscript></entry>
+		      <entry>R<subscript>31</subscript></entry>
+		      <entry>G<subscript>32</subscript></entry>
+		      <entry>R<subscript>33</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+	      </informaltable>
+	    </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml b/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml
new file mode 100644
index 0000000..d67a472
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml
@@ -0,0 +1,75 @@
+    <refentry id="V4L2-PIX-FMT-SGBRG8">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_SGBRG8 ('GBRG')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_SGBRG8</constant></refname>
+	<refpurpose>Bayer RGB format</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This is commonly the native format of digital cameras,
+reflecting the arrangement of sensors on the CCD device. Only one red,
+green or blue value is given for each pixel. Missing components must
+be interpolated from neighbouring pixels. From left to right the first
+row consists of a green and blue value, the second row of a red and
+green value. This scheme repeats to the right and down for every two
+columns and rows.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_SGBRG8</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+	      <informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>G<subscript>00</subscript></entry>
+		      <entry>B<subscript>01</subscript></entry>
+		      <entry>G<subscript>02</subscript></entry>
+		      <entry>B<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>R<subscript>10</subscript></entry>
+		      <entry>G<subscript>11</subscript></entry>
+		      <entry>R<subscript>12</subscript></entry>
+		      <entry>G<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>G<subscript>20</subscript></entry>
+		      <entry>B<subscript>21</subscript></entry>
+		      <entry>G<subscript>22</subscript></entry>
+		      <entry>B<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>R<subscript>30</subscript></entry>
+		      <entry>G<subscript>31</subscript></entry>
+		      <entry>R<subscript>32</subscript></entry>
+		      <entry>G<subscript>33</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+	      </informaltable>
+	    </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml b/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml
new file mode 100644
index 0000000..0cdf13b
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml
@@ -0,0 +1,75 @@
+    <refentry id="V4L2-PIX-FMT-SGRBG8">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_SGRBG8 ('GRBG')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_SGRBG8</constant></refname>
+	<refpurpose>Bayer RGB format</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This is commonly the native format of digital cameras,
+reflecting the arrangement of sensors on the CCD device. Only one red,
+green or blue value is given for each pixel. Missing components must
+be interpolated from neighbouring pixels. From left to right the first
+row consists of a green and blue value, the second row of a red and
+green value. This scheme repeats to the right and down for every two
+columns and rows.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_SGRBG8</constant> 4 &times;
+4 pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+	      <informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>G<subscript>00</subscript></entry>
+		      <entry>R<subscript>01</subscript></entry>
+		      <entry>G<subscript>02</subscript></entry>
+		      <entry>R<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>R<subscript>10</subscript></entry>
+		      <entry>B<subscript>11</subscript></entry>
+		      <entry>R<subscript>12</subscript></entry>
+		      <entry>B<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>G<subscript>20</subscript></entry>
+		      <entry>R<subscript>21</subscript></entry>
+		      <entry>G<subscript>22</subscript></entry>
+		      <entry>R<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>R<subscript>30</subscript></entry>
+		      <entry>B<subscript>31</subscript></entry>
+		      <entry>R<subscript>32</subscript></entry>
+		      <entry>B<subscript>33</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+	      </informaltable>
+	    </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-uyvy.xml b/Documentation/DocBook/v4l/pixfmt-uyvy.xml
new file mode 100644
index 0000000..816c8d4
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-uyvy.xml
@@ -0,0 +1,128 @@
+    <refentry id="V4L2-PIX-FMT-UYVY">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_UYVY ('UYVY')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_UYVY</constant></refname>
+	<refpurpose>Variation of
+<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
+in memory</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y
+component.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_UYVY</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="9" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Cb<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Cr<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Cb<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Cr<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-vyuy.xml b/Documentation/DocBook/v4l/pixfmt-vyuy.xml
new file mode 100644
index 0000000..61f12a5
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-vyuy.xml
@@ -0,0 +1,128 @@
+    <refentry id="V4L2-PIX-FMT-VYUY">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_VYUY ('VYUY')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_VYUY</constant></refname>
+	<refpurpose>Variation of
+<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
+in memory</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y
+component.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_VYUY</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="9" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Cr<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Cb<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Cr<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Cb<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-y16.xml b/Documentation/DocBook/v4l/pixfmt-y16.xml
new file mode 100644
index 0000000..d584040
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-y16.xml
@@ -0,0 +1,89 @@
+<refentry id="V4L2-PIX-FMT-Y16">
+  <refmeta>
+    <refentrytitle>V4L2_PIX_FMT_Y16 ('Y16 ')</refentrytitle>
+    &manvol;
+  </refmeta>
+  <refnamediv>
+    <refname><constant>V4L2_PIX_FMT_Y16</constant></refname>
+    <refpurpose>Grey-scale image</refpurpose>
+  </refnamediv>
+  <refsect1>
+    <title>Description</title>
+
+    <para>This is a grey-scale image with a depth of 16 bits per
+pixel. The least significant byte is stored at lower memory addresses
+(little-endian). Note the actual sampling precision may be lower than
+16 bits, for example 10 bits per pixel with values in range 0 to
+1023.</para>
+
+    <example>
+      <title><constant>V4L2_PIX_FMT_Y16</constant> 4 &times; 4
+pixel image</title>
+
+      <formalpara>
+	<title>Byte Order.</title>
+	<para>Each cell is one byte.
+	  <informaltable frame="none">
+	    <tgroup cols="9" align="center">
+	      <colspec align="left" colwidth="2*" />
+	      <tbody valign="top">
+		<row>
+		  <entry>start&nbsp;+&nbsp;0:</entry>
+		  <entry>Y'<subscript>00low</subscript></entry>
+		  <entry>Y'<subscript>00high</subscript></entry>
+		  <entry>Y'<subscript>01low</subscript></entry>
+		  <entry>Y'<subscript>01high</subscript></entry>
+		  <entry>Y'<subscript>02low</subscript></entry>
+		  <entry>Y'<subscript>02high</subscript></entry>
+		  <entry>Y'<subscript>03low</subscript></entry>
+		  <entry>Y'<subscript>03high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;8:</entry>
+		  <entry>Y'<subscript>10low</subscript></entry>
+		  <entry>Y'<subscript>10high</subscript></entry>
+		  <entry>Y'<subscript>11low</subscript></entry>
+		  <entry>Y'<subscript>11high</subscript></entry>
+		  <entry>Y'<subscript>12low</subscript></entry>
+		  <entry>Y'<subscript>12high</subscript></entry>
+		  <entry>Y'<subscript>13low</subscript></entry>
+		  <entry>Y'<subscript>13high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;16:</entry>
+		  <entry>Y'<subscript>20low</subscript></entry>
+		  <entry>Y'<subscript>20high</subscript></entry>
+		  <entry>Y'<subscript>21low</subscript></entry>
+		  <entry>Y'<subscript>21high</subscript></entry>
+		  <entry>Y'<subscript>22low</subscript></entry>
+		  <entry>Y'<subscript>22high</subscript></entry>
+		  <entry>Y'<subscript>23low</subscript></entry>
+		  <entry>Y'<subscript>23high</subscript></entry>
+		</row>
+		<row>
+		  <entry>start&nbsp;+&nbsp;24:</entry>
+		  <entry>Y'<subscript>30low</subscript></entry>
+		  <entry>Y'<subscript>30high</subscript></entry>
+		  <entry>Y'<subscript>31low</subscript></entry>
+		  <entry>Y'<subscript>31high</subscript></entry>
+		  <entry>Y'<subscript>32low</subscript></entry>
+		  <entry>Y'<subscript>32high</subscript></entry>
+		  <entry>Y'<subscript>33low</subscript></entry>
+		  <entry>Y'<subscript>33high</subscript></entry>
+		</row>
+	      </tbody>
+	    </tgroup>
+	  </informaltable>
+	</para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-y41p.xml b/Documentation/DocBook/v4l/pixfmt-y41p.xml
new file mode 100644
index 0000000..73c8536
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-y41p.xml
@@ -0,0 +1,157 @@
+    <refentry id="V4L2-PIX-FMT-Y41P">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_Y41P ('Y41P')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_Y41P</constant></refname>
+	<refpurpose>Format with &frac14; horizontal chroma
+resolution, also known as YUV 4:1:1</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>In this format each 12 bytes is eight pixels. In the
+twelve bytes are two CbCr pairs and eight Y's. The first CbCr pair
+goes with the first four Y's, and the second CbCr pair goes with the
+other four Y's. The Cb and Cr components have one fourth the
+horizontal resolution of the Y component.</para>
+
+	<para>Do not confuse this format with <link
+linkend="V4L2-PIX-FMT-YUV411P"><constant>V4L2_PIX_FMT_YUV411P</constant></link>.
+Y41P is derived from "YUV 4:1:1 <emphasis>packed</emphasis>", while
+YUV411P stands for "YUV 4:1:1 <emphasis>planar</emphasis>".</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_Y41P</constant> 8 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="13" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		      <entry>Y'<subscript>04</subscript></entry>
+		      <entry>Y'<subscript>05</subscript></entry>
+		      <entry>Y'<subscript>06</subscript></entry>
+		      <entry>Y'<subscript>07</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		      <entry>Y'<subscript>14</subscript></entry>
+		      <entry>Y'<subscript>15</subscript></entry>
+		      <entry>Y'<subscript>16</subscript></entry>
+		      <entry>Y'<subscript>17</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Cb<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Cr<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		      <entry>Y'<subscript>24</subscript></entry>
+		      <entry>Y'<subscript>25</subscript></entry>
+		      <entry>Y'<subscript>26</subscript></entry>
+		      <entry>Y'<subscript>27</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;36:</entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Cb<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Cr<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		      <entry>Y'<subscript>34</subscript></entry>
+		      <entry>Y'<subscript>35</subscript></entry>
+		      <entry>Y'<subscript>36</subscript></entry>
+		      <entry>Y'<subscript>37</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+	      </informaltable></para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="15" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry><entry></entry>
+		      <entry>4</entry><entry></entry><entry>5</entry><entry></entry>
+		      <entry>6</entry><entry></entry><entry>7</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv410.xml b/Documentation/DocBook/v4l/pixfmt-yuv410.xml
new file mode 100644
index 0000000..8eb4a19
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv410.xml
@@ -0,0 +1,141 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_YVU410 ('YVU9'), V4L2_PIX_FMT_YUV410 ('YUV9')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-YVU410"><constant>V4L2_PIX_FMT_YVU410</constant></refname>
+	<refname id="V4L2-PIX-FMT-YUV410"><constant>V4L2_PIX_FMT_YUV410</constant></refname>
+	<refpurpose>Planar formats with &frac14; horizontal and
+vertical chroma resolution, also known as YUV 4:1:0</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>These are planar formats, as opposed to a packed format.
+The three components are separated into three sub-images or planes.
+The Y plane is first. The Y plane has one byte per pixel. For
+<constant>V4L2_PIX_FMT_YVU410</constant>, the Cr plane immediately
+follows the Y plane in memory. The Cr plane is &frac14; the width and
+&frac14; the height of the Y plane (and of the image). Each Cr belongs
+to 16 pixels, a four-by-four square of the image. Following the Cr
+plane is the Cb plane, just like the Cr plane.
+<constant>V4L2_PIX_FMT_YUV410</constant> is the same, except the Cb
+plane comes first, then the Cr plane.</para>
+
+	<para>If the Y plane has pad bytes after each row, then the Cr
+and Cb planes have &frac14; as many pad bytes after their rows. In
+other words, four Cx rows (including padding) are exactly as long as
+one Y row (including padding).</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_YVU410</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;17:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry></entry><entry></entry><entry>C</entry>
+		      <entry></entry><entry></entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv411p.xml b/Documentation/DocBook/v4l/pixfmt-yuv411p.xml
new file mode 100644
index 0000000..00e0960
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv411p.xml
@@ -0,0 +1,155 @@
+    <refentry id="V4L2-PIX-FMT-YUV411P">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_YUV411P ('411P')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_YUV411P</constant></refname>
+	<refpurpose>Format with &frac14; horizontal chroma resolution,
+also known as YUV 4:1:1. Planar layout as opposed to
+<constant>V4L2_PIX_FMT_Y41P</constant></refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This format is not commonly used. This is a planar
+format similar to the 4:2:2 planar format except with half as many
+chroma. The three components are separated into three sub-images or
+planes. The Y plane is first. The Y plane has one byte per pixel. The
+Cb plane immediately follows the Y plane in memory. The Cb plane is
+&frac14; the width of the Y plane (and of the image). Each Cb belongs
+to 4 pixels all on the same row. For example,
+Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>, Y'<subscript>02</subscript> and
+Y'<subscript>03</subscript>. Following the Cb plane is the Cr plane,
+just like the Cb plane.</para>
+
+	<para>If the Y plane has pad bytes after each row, then the Cr
+and Cb planes have &frac14; as many pad bytes after their rows. In
+other words, four C x rows (including padding) is exactly as long as
+one Y row (including padding).</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_YUV411P</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;17:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;18:</entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;19:</entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;20:</entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;21:</entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;22:</entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;23:</entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv420.xml b/Documentation/DocBook/v4l/pixfmt-yuv420.xml
new file mode 100644
index 0000000..42d7de5
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv420.xml
@@ -0,0 +1,157 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_YVU420 ('YV12'), V4L2_PIX_FMT_YUV420 ('YU12')</refentrytitle>
+	&manvol;
+     </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></refname>
+	<refname id="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></refname>
+	<refpurpose>Planar formats with &frac12; horizontal and
+vertical chroma resolution, also known as YUV 4:2:0</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>These are planar formats, as opposed to a packed format.
+The three components are separated into three sub- images or planes.
+The Y plane is first. The Y plane has one byte per pixel. For
+<constant>V4L2_PIX_FMT_YVU420</constant>, the Cr plane immediately
+follows the Y plane in memory. The Cr plane is half the width and half
+the height of the Y plane (and of the image). Each Cr belongs to four
+pixels, a two-by-two square of the image. For example,
+Cr<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
+Y'<subscript>11</subscript>. Following the Cr plane is the Cb plane,
+just like the Cr plane. <constant>V4L2_PIX_FMT_YUV420</constant> is
+the same except the Cb plane comes first, then the Cr plane.</para>
+
+	<para>If the Y plane has pad bytes after each row, then the Cr
+and Cb planes have half as many pad bytes after their rows. In other
+words, two Cx rows (including padding) is exactly as long as one Y row
+(including padding).</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_YVU420</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;18:</entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;20:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;22:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv422p.xml b/Documentation/DocBook/v4l/pixfmt-yuv422p.xml
new file mode 100644
index 0000000..4348bd9
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv422p.xml
@@ -0,0 +1,161 @@
+    <refentry id="V4L2-PIX-FMT-YUV422P">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_YUV422P ('422P')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_YUV422P</constant></refname>
+	<refpurpose>Format with &frac12; horizontal chroma resolution,
+also known as YUV 4:2:2. Planar layout as opposed to
+<constant>V4L2_PIX_FMT_YUYV</constant></refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>This format is not commonly used. This is a planar
+version of the YUYV format. The three components are separated into
+three sub-images or planes. The Y plane is first. The Y plane has one
+byte per pixel. The Cb plane immediately follows the Y plane in
+memory. The Cb plane is half the width of the Y plane (and of the
+image). Each Cb belongs to two pixels. For example,
+Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
+Y'<subscript>01</subscript>. Following the Cb plane is the Cr plane,
+just like the Cb plane.</para>
+
+	<para>If the Y plane has pad bytes after each row, then the Cr
+and Cb planes have half as many pad bytes after their rows. In other
+words, two Cx rows (including padding) is exactly as long as one Y row
+(including padding).</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_YUV422P</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;12:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;18:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;20:</entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		      <entry>Cb<subscript>21</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;22:</entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		      <entry>Cb<subscript>31</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;26:</entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;28:</entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		      <entry>Cr<subscript>21</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;30:</entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		      <entry>Cr<subscript>31</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuyv.xml b/Documentation/DocBook/v4l/pixfmt-yuyv.xml
new file mode 100644
index 0000000..bdb2ffa
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuyv.xml
@@ -0,0 +1,128 @@
+    <refentry id="V4L2-PIX-FMT-YUYV">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_YUYV ('YUYV')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_YUYV</constant></refname>
+	<refpurpose>Packed format with &frac12; horizontal chroma
+resolution, also known as YUV 4:2:2</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y component.
+<constant>V4L2_PIX_FMT_YUYV </constant> is known in the Windows
+environment as YUY2.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_YUYV</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="9" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Cb<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		      <entry>Cr<subscript>21</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Cb<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		      <entry>Cr<subscript>31</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yvyu.xml b/Documentation/DocBook/v4l/pixfmt-yvyu.xml
new file mode 100644
index 0000000..40d17ae
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yvyu.xml
@@ -0,0 +1,128 @@
+    <refentry id="V4L2-PIX-FMT-YVYU">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_YVYU ('YVYU')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_YVYU</constant></refname>
+	<refpurpose>Variation of
+<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
+in memory</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>In this format each four bytes is two pixels. Each four
+bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
+the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
+components have half the horizontal resolution of the Y
+component.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_YVYU</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="9" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Cr<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Cb<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Cr<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		      <entry>Cb<subscript>21</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Cr<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Cb<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Cr<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		      <entry>Cb<subscript>31</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry>C</entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
new file mode 100644
index 0000000..7d396a3
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -0,0 +1,801 @@
+  <title>Image Formats</title>
+
+  <para>The V4L2 API was primarily designed for devices exchanging
+image data with applications. The
+<structname>v4l2_pix_format</structname> structure defines the format
+and layout of an image in memory. Image formats are negotiated with
+the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video
+capturing and output, for overlay frame buffer formats see also
+&VIDIOC-G-FBUF;.)</para>
+
+  <table pgwide="1" frame="none" id="v4l2-pix-format">
+    <title>struct <structname>v4l2_pix_format</structname></title>
+    <tgroup cols="3">
+      &cs-str;
+      <tbody valign="top">
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>width</structfield></entry>
+	  <entry>Image width in pixels.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>height</structfield></entry>
+	  <entry>Image height in pixels.</entry>
+	</row>
+	<row>
+	  <entry spanname="hspan">Applications set these fields to
+request an image size, drivers return the closest possible values. In
+case of planar formats the <structfield>width</structfield> and
+<structfield>height</structfield> applies to the largest plane. To
+avoid ambiguities drivers must return values rounded up to a multiple
+of the scale factor of any smaller planes. For example when the image
+format is YUV 4:2:0, <structfield>width</structfield> and
+<structfield>height</structfield> must be multiples of two.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>pixelformat</structfield></entry>
+	  <entry>The pixel format or type of compression, set by the
+application. This is a little endian <link
+linkend="v4l2-fourcc">four character code</link>. V4L2 defines
+standard RGB formats in <xref linkend="rgb-formats" />, YUV formats in <xref
+linkend="yuv-formats" />, and reserved codes in <xref
+linkend="reserved-formats" /></entry>
+	</row>
+	<row>
+	  <entry>&v4l2-field;</entry>
+	  <entry><structfield>field</structfield></entry>
+	  <entry>Video images are typically interlaced. Applications
+can request to capture or output only the top or bottom field, or both
+fields interlaced or sequentially stored in one buffer or alternating
+in separate buffers. Drivers return the actual field order selected.
+For details see <xref linkend="field-order" />.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>bytesperline</structfield></entry>
+	  <entry>Distance in bytes between the leftmost pixels in two
+adjacent lines.</entry>
+	</row>
+	<row>
+	  <entry spanname="hspan"><para>Both applications and drivers
+can set this field to request padding bytes at the end of each line.
+Drivers however may ignore the value requested by the application,
+returning <structfield>width</structfield> times bytes per pixel or a
+larger value required by the hardware. That implies applications can
+just set this field to zero to get a reasonable
+default.</para><para>Video hardware may access padding bytes,
+therefore they must reside in accessible memory. Consider cases where
+padding bytes after the last line of an image cross a system page
+boundary. Input devices may write padding bytes, the value is
+undefined. Output devices ignore the contents of padding
+bytes.</para><para>When the image format is planar the
+<structfield>bytesperline</structfield> value applies to the largest
+plane and is divided by the same factor as the
+<structfield>width</structfield> field for any smaller planes. For
+example the Cb and Cr planes of a YUV 4:2:0 image have half as many
+padding bytes following each line as the Y plane. To avoid ambiguities
+drivers must return a <structfield>bytesperline</structfield> value
+rounded up to a multiple of the scale factor.</para></entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>sizeimage</structfield></entry>
+	  <entry>Size in bytes of the buffer to hold a complete image,
+set by the driver. Usually this is
+<structfield>bytesperline</structfield> times
+<structfield>height</structfield>. When the image consists of variable
+length compressed data this is the maximum number of bytes required to
+hold an image.</entry>
+	</row>
+	<row>
+	  <entry>&v4l2-colorspace;</entry>
+	  <entry><structfield>colorspace</structfield></entry>
+	  <entry>This information supplements the
+<structfield>pixelformat</structfield> and must be set by the driver,
+see <xref linkend="colorspaces" />.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>priv</structfield></entry>
+	  <entry>Reserved for custom (driver defined) additional
+information about formats. When not used drivers and applications must
+set this field to zero.</entry>
+	</row>
+      </tbody>
+    </tgroup>
+  </table>
+
+  <section>
+    <title>Standard Image Formats</title>
+
+    <para>In order to exchange images between drivers and
+applications, it is necessary to have standard image data formats
+which both sides will interpret the same way. V4L2 includes several
+such formats, and this section is intended to be an unambiguous
+specification of the standard image data formats in V4L2.</para>
+
+    <para>V4L2 drivers are not limited to these formats, however.
+Driver-specific formats are possible. In that case the application may
+depend on a codec to convert images to one of the standard formats
+when needed. But the data can still be stored and retrieved in the
+proprietary format. For example, a device may support a proprietary
+compressed format. Applications can still capture and save the data in
+the compressed format, saving much disk space, and later use a codec
+to convert the images to the X Windows screen format when the video is
+to be displayed.</para>
+
+    <para>Even so, ultimately, some standard formats are needed, so
+the V4L2 specification would not be complete without well-defined
+standard formats.</para>
+
+    <para>The V4L2 standard formats are mainly uncompressed formats. The
+pixels are always arranged in memory from left to right, and from top
+to bottom. The first byte of data in the image buffer is always for
+the leftmost pixel of the topmost row. Following that is the pixel
+immediately to its right, and so on until the end of the top row of
+pixels. Following the rightmost pixel of the row there may be zero or
+more bytes of padding to guarantee that each row of pixel data has a
+certain alignment. Following the pad bytes, if any, is data for the
+leftmost pixel of the second row from the top, and so on. The last row
+has just as many pad bytes after it as the other rows.</para>
+
+    <para>In V4L2 each format has an identifier which looks like
+<constant>PIX_FMT_XXX</constant>, defined in the <link
+linkend="videodev">videodev.h</link> header file. These identifiers
+represent <link linkend="v4l2-fourcc">four character codes</link>
+which are also listed below, however they are not the same as those
+used in the Windows world.</para>
+  </section>
+
+  <section id="colorspaces">
+    <title>Colorspaces</title>
+
+    <para>[intro]</para>
+
+    <!-- See proposal by Billy Biggs, video4linux-list@redhat.com
+on 11 Oct 2002, subject: "Re: [V4L] Re: v4l2 api", and
+http://vektor.theorem.ca/graphics/ycbcr/ and
+http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html -->
+
+    <para>
+      <variablelist>
+	<varlistentry>
+	  <term>Gamma Correction</term>
+	  <listitem>
+	    <para>[to do]</para>
+	    <para>E'<subscript>R</subscript> = f(R)</para>
+	    <para>E'<subscript>G</subscript> = f(G)</para>
+	    <para>E'<subscript>B</subscript> = f(B)</para>
+	  </listitem>
+	</varlistentry>
+	<varlistentry>
+	  <term>Construction of luminance and color-difference
+signals</term>
+	  <listitem>
+	    <para>[to do]</para>
+	    <para>E'<subscript>Y</subscript> =
+Coeff<subscript>R</subscript> E'<subscript>R</subscript>
++ Coeff<subscript>G</subscript> E'<subscript>G</subscript>
++ Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
+	    <para>(E'<subscript>R</subscript> - E'<subscript>Y</subscript>) = E'<subscript>R</subscript>
+- Coeff<subscript>R</subscript> E'<subscript>R</subscript>
+- Coeff<subscript>G</subscript> E'<subscript>G</subscript>
+- Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
+	    <para>(E'<subscript>B</subscript> - E'<subscript>Y</subscript>) = E'<subscript>B</subscript>
+- Coeff<subscript>R</subscript> E'<subscript>R</subscript>
+- Coeff<subscript>G</subscript> E'<subscript>G</subscript>
+- Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
+	  </listitem>
+	</varlistentry>
+	<varlistentry>
+	  <term>Re-normalized color-difference signals</term>
+	  <listitem>
+	    <para>The color-difference signals are scaled back to unity
+range [-0.5;+0.5]:</para>
+	    <para>K<subscript>B</subscript> = 0.5 / (1 - Coeff<subscript>B</subscript>)</para>
+	    <para>K<subscript>R</subscript> = 0.5 / (1 - Coeff<subscript>R</subscript>)</para>
+	    <para>P<subscript>B</subscript> =
+K<subscript>B</subscript> (E'<subscript>B</subscript> - E'<subscript>Y</subscript>) =
+  0.5 (Coeff<subscript>R</subscript> / Coeff<subscript>B</subscript>) E'<subscript>R</subscript>
++ 0.5 (Coeff<subscript>G</subscript> / Coeff<subscript>B</subscript>) E'<subscript>G</subscript>
++ 0.5 E'<subscript>B</subscript></para>
+	    <para>P<subscript>R</subscript> =
+K<subscript>R</subscript> (E'<subscript>R</subscript> - E'<subscript>Y</subscript>) =
+  0.5 E'<subscript>R</subscript>
++ 0.5 (Coeff<subscript>G</subscript> / Coeff<subscript>R</subscript>) E'<subscript>G</subscript>
++ 0.5 (Coeff<subscript>B</subscript> / Coeff<subscript>R</subscript>) E'<subscript>B</subscript></para>
+	  </listitem>
+	</varlistentry>
+	<varlistentry>
+	  <term>Quantization</term>
+	  <listitem>
+	    <para>[to do]</para>
+	    <para>Y' = (Lum. Levels - 1) &middot; E'<subscript>Y</subscript> + Lum. Offset</para>
+	    <para>C<subscript>B</subscript> = (Chrom. Levels - 1)
+&middot; P<subscript>B</subscript> + Chrom. Offset</para>
+	    <para>C<subscript>R</subscript> = (Chrom. Levels - 1)
+&middot; P<subscript>R</subscript> + Chrom. Offset</para>
+	    <para>Rounding to the nearest integer and clamping to the range
+[0;255] finally yields the digital color components Y'CbCr
+stored in YUV images.</para>
+	  </listitem>
+	</varlistentry>
+      </variablelist>
+    </para>
+
+    <example>
+      <title>ITU-R Rec. BT.601 color conversion</title>
+
+      <para>Forward Transformation</para>
+
+      <programlisting>
+int ER, EG, EB;         /* gamma corrected RGB input [0;255] */
+int Y1, Cb, Cr;         /* output [0;255] */
+
+double r, g, b;         /* temporaries */
+double y1, pb, pr;
+
+int
+clamp (double x)
+{
+	int r = x;      /* round to nearest */
+
+	if (r &lt; 0)         return 0;
+	else if (r &gt; 255)  return 255;
+	else               return r;
+}
+
+r = ER / 255.0;
+g = EG / 255.0;
+b = EB / 255.0;
+
+y1  =  0.299  * r + 0.587 * g + 0.114  * b;
+pb  = -0.169  * r - 0.331 * g + 0.5    * b;
+pr  =  0.5    * r - 0.419 * g - 0.081  * b;
+
+Y1 = clamp (219 * y1 + 16);
+Cb = clamp (224 * pb + 128);
+Cr = clamp (224 * pr + 128);
+
+/* or shorter */
+
+y1 = 0.299 * ER + 0.587 * EG + 0.114 * EB;
+
+Y1 = clamp ( (219 / 255.0)                    *       y1  + 16);
+Cb = clamp (((224 / 255.0) / (2 - 2 * 0.114)) * (EB - y1) + 128);
+Cr = clamp (((224 / 255.0) / (2 - 2 * 0.299)) * (ER - y1) + 128);
+      </programlisting>
+
+      <para>Inverse Transformation</para>
+
+      <programlisting>
+int Y1, Cb, Cr;         /* gamma pre-corrected input [0;255] */
+int ER, EG, EB;         /* output [0;255] */
+
+double r, g, b;         /* temporaries */
+double y1, pb, pr;
+
+int
+clamp (double x)
+{
+	int r = x;      /* round to nearest */
+
+	if (r &lt; 0)         return 0;
+	else if (r &gt; 255)  return 255;
+	else               return r;
+}
+
+y1 = (255 / 219.0) * (Y1 - 16);
+pb = (255 / 224.0) * (Cb - 128);
+pr = (255 / 224.0) * (Cr - 128);
+
+r = 1.0 * y1 + 0     * pb + 1.402 * pr;
+g = 1.0 * y1 - 0.344 * pb - 0.714 * pr;
+b = 1.0 * y1 + 1.772 * pb + 0     * pr;
+
+ER = clamp (r * 255); /* [ok? one should prob. limit y1,pb,pr] */
+EG = clamp (g * 255);
+EB = clamp (b * 255);
+      </programlisting>
+    </example>
+
+    <table pgwide="1" id="v4l2-colorspace" orient="land">
+      <title>enum v4l2_colorspace</title>
+      <tgroup cols="11" align="center">
+	<colspec align="left" />
+	<colspec align="center" />
+	<colspec align="left" />
+	<colspec colname="cr" />
+	<colspec colname="cg" />
+	<colspec colname="cb" />
+	<colspec colname="wp" />
+	<colspec colname="gc" />
+	<colspec colname="lum" />
+	<colspec colname="qy" />
+	<colspec colname="qc" />
+	<spanspec namest="cr" nameend="cb" spanname="chrom" />
+	<spanspec namest="qy" nameend="qc" spanname="quant" />
+	<spanspec namest="lum" nameend="qc" spanname="spam" />
+	<thead>
+	  <row>
+	    <entry morerows="1">Identifier</entry>
+	    <entry morerows="1">Value</entry>
+	    <entry morerows="1">Description</entry>
+	    <entry spanname="chrom">Chromaticities<footnote>
+		<para>The coordinates of the color primaries are
+given in the CIE system (1931)</para>
+	      </footnote></entry>
+	    <entry morerows="1">White Point</entry>
+	    <entry morerows="1">Gamma Correction</entry>
+	    <entry morerows="1">Luminance E'<subscript>Y</subscript></entry>
+	    <entry spanname="quant">Quantization</entry>
+	  </row>
+	  <row>
+	    <entry>Red</entry>
+	    <entry>Green</entry>
+	    <entry>Blue</entry>
+	    <entry>Y'</entry>
+	    <entry>Cb, Cr</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_SMPTE170M</constant></entry>
+	    <entry>1</entry>
+	    <entry>NTSC/PAL according to <xref linkend="smpte170m" />,
+<xref linkend="itu601" /></entry>
+	    <entry>x&nbsp;=&nbsp;0.630, y&nbsp;=&nbsp;0.340</entry>
+	    <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.595</entry>
+	    <entry>x&nbsp;=&nbsp;0.155, y&nbsp;=&nbsp;0.070</entry>
+	    <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+	    Illuminant D<subscript>65</subscript></entry>
+	    <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
+1.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
+	    <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+	    <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+	    <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_SMPTE240M</constant></entry>
+	    <entry>2</entry>
+	    <entry>1125-Line (US) HDTV, see <xref
+linkend="smpte240m" /></entry>
+	    <entry>x&nbsp;=&nbsp;0.630, y&nbsp;=&nbsp;0.340</entry>
+	    <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.595</entry>
+	    <entry>x&nbsp;=&nbsp;0.155, y&nbsp;=&nbsp;0.070</entry>
+	    <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+	    Illuminant D<subscript>65</subscript></entry>
+	    <entry>E' = 4&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.0228,
+1.1115&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.1115&nbsp;for&nbsp;0.0228&nbsp;&lt;&nbsp;I</entry>
+	    <entry>0.212&nbsp;E'<subscript>R</subscript>
++&nbsp;0.701&nbsp;E'<subscript>G</subscript>
++&nbsp;0.087&nbsp;E'<subscript>B</subscript></entry>
+	    <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+	    <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_REC709</constant></entry>
+	    <entry>3</entry>
+	    <entry>HDTV and modern devices, see <xref
+linkend="itu709" /></entry>
+	    <entry>x&nbsp;=&nbsp;0.640, y&nbsp;=&nbsp;0.330</entry>
+	    <entry>x&nbsp;=&nbsp;0.300, y&nbsp;=&nbsp;0.600</entry>
+	    <entry>x&nbsp;=&nbsp;0.150, y&nbsp;=&nbsp;0.060</entry>
+	    <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+	    Illuminant D<subscript>65</subscript></entry>
+	    <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
+1.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
+	    <entry>0.2125&nbsp;E'<subscript>R</subscript>
++&nbsp;0.7154&nbsp;E'<subscript>G</subscript>
++&nbsp;0.0721&nbsp;E'<subscript>B</subscript></entry>
+	    <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+	    <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_BT878</constant></entry>
+	    <entry>4</entry>
+	    <entry>Broken Bt878 extents<footnote>
+		<para>The ubiquitous Bt878 video capture chip
+quantizes E'<subscript>Y</subscript> to 238 levels, yielding a range
+of Y' = 16 &hellip; 253, unlike Rec. 601 Y' = 16 &hellip;
+235. This is not a typo in the Bt878 documentation, it has been
+implemented in silicon. The chroma extents are unclear.</para>
+	      </footnote>, <xref linkend="itu601" /></entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+	    <entry><emphasis>237</emphasis>&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+	    <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128 (probably)</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_470_SYSTEM_M</constant></entry>
+	    <entry>5</entry>
+	    <entry>M/NTSC<footnote>
+		<para>No identifier exists for M/PAL which uses
+the chromaticities of M/NTSC, the remaining parameters are equal to B and
+G/PAL.</para>
+	      </footnote> according to <xref linkend="itu470" />, <xref
+		linkend="itu601" /></entry>
+	    <entry>x&nbsp;=&nbsp;0.67, y&nbsp;=&nbsp;0.33</entry>
+	    <entry>x&nbsp;=&nbsp;0.21, y&nbsp;=&nbsp;0.71</entry>
+	    <entry>x&nbsp;=&nbsp;0.14, y&nbsp;=&nbsp;0.08</entry>
+	    <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.316, Illuminant C</entry>
+	    <entry>?</entry>
+	    <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+	    <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+	    <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant></entry>
+	    <entry>6</entry>
+	    <entry>625-line PAL and SECAM systems according to <xref
+linkend="itu470" />, <xref linkend="itu601" /></entry>
+	    <entry>x&nbsp;=&nbsp;0.64, y&nbsp;=&nbsp;0.33</entry>
+	    <entry>x&nbsp;=&nbsp;0.29, y&nbsp;=&nbsp;0.60</entry>
+	    <entry>x&nbsp;=&nbsp;0.15, y&nbsp;=&nbsp;0.06</entry>
+	    <entry>x&nbsp;=&nbsp;0.313, y&nbsp;=&nbsp;0.329,
+Illuminant D<subscript>65</subscript></entry>
+	    <entry>?</entry>
+	    <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+	    <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
+	    <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_JPEG</constant></entry>
+	    <entry>7</entry>
+	    <entry>JPEG Y'CbCr, see <xref linkend="jfif" />, <xref linkend="itu601" /></entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>?</entry>
+	    <entry>0.299&nbsp;E'<subscript>R</subscript>
++&nbsp;0.587&nbsp;E'<subscript>G</subscript>
++&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
+	    <entry>256&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16<footnote>
+		<para>Note JFIF quantizes
+Y'P<subscript>B</subscript>P<subscript>R</subscript> in range [0;+1] and
+[-0.5;+0.5] to <emphasis>257</emphasis> levels, however Y'CbCr signals
+are still clamped to [0;255].</para>
+	      </footnote></entry>
+	    <entry>256&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_COLORSPACE_SRGB</constant></entry>
+	    <entry>8</entry>
+	    <entry>[?]</entry>
+	    <entry>x&nbsp;=&nbsp;0.640, y&nbsp;=&nbsp;0.330</entry>
+	    <entry>x&nbsp;=&nbsp;0.300, y&nbsp;=&nbsp;0.600</entry>
+	    <entry>x&nbsp;=&nbsp;0.150, y&nbsp;=&nbsp;0.060</entry>
+	    <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
+	    Illuminant D<subscript>65</subscript></entry>
+	    <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
+1.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
+	    <entry spanname="spam">n/a</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <section id="pixfmt-indexed">
+    <title>Indexed Format</title>
+
+    <para>In this format each pixel is represented by an 8 bit index
+into a 256 entry ARGB palette. It is intended for <link
+linkend="osd">Video Output Overlays</link> only. There are no ioctls to
+access the palette, this must be done with ioctls of the Linux framebuffer API.</para>
+
+    <table pgwide="0" frame="none">
+      <title>Indexed Image Format</title>
+      <tgroup cols="37" align="center">
+	<colspec colname="id" align="left" />
+	<colspec colname="fourcc" />
+	<colspec colname="bit" />
+
+	<colspec colnum="4" colname="b07" align="center" />
+	<colspec colnum="5" colname="b06" align="center" />
+	<colspec colnum="6" colname="b05" align="center" />
+	<colspec colnum="7" colname="b04" align="center" />
+	<colspec colnum="8" colname="b03" align="center" />
+	<colspec colnum="9" colname="b02" align="center" />
+	<colspec colnum="10" colname="b01" align="center" />
+	<colspec colnum="11" colname="b00" align="center" />
+
+	<spanspec namest="b07" nameend="b00" spanname="b0" />
+	<spanspec namest="b17" nameend="b10" spanname="b1" />
+	<spanspec namest="b27" nameend="b20" spanname="b2" />
+	<spanspec namest="b37" nameend="b30" spanname="b3" />
+	<thead>
+	  <row>
+	    <entry>Identifier</entry>
+	    <entry>Code</entry>
+	    <entry>&nbsp;</entry>
+	    <entry spanname="b0">Byte&nbsp;0</entry>
+	  </row>
+	  <row>
+	    <entry>&nbsp;</entry>
+	    <entry>&nbsp;</entry>
+	    <entry>Bit</entry>
+	    <entry>7</entry>
+	    <entry>6</entry>
+	    <entry>5</entry>
+	    <entry>4</entry>
+	    <entry>3</entry>
+	    <entry>2</entry>
+	    <entry>1</entry>
+	    <entry>0</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row id="V4L2-PIX-FMT-PAL8">
+	    <entry><constant>V4L2_PIX_FMT_PAL8</constant></entry>
+	    <entry>'PAL8'</entry>
+	    <entry></entry>
+	    <entry>i<subscript>7</subscript></entry>
+	    <entry>i<subscript>6</subscript></entry>
+	    <entry>i<subscript>5</subscript></entry>
+	    <entry>i<subscript>4</subscript></entry>
+	    <entry>i<subscript>3</subscript></entry>
+	    <entry>i<subscript>2</subscript></entry>
+	    <entry>i<subscript>1</subscript></entry>
+	    <entry>i<subscript>0</subscript></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <section id="pixfmt-rgb">
+    <title>RGB Formats</title>
+
+    &sub-packed-rgb;
+    &sub-sbggr8;
+    &sub-sgbrg8;
+    &sub-sgrbg8;
+    &sub-sbggr16;
+  </section>
+
+  <section id="yuv-formats">
+    <title>YUV Formats</title>
+
+    <para>YUV is the format native to TV broadcast and composite video
+signals. It separates the brightness information (Y) from the color
+information (U and V or Cb and Cr). The color information consists of
+red and blue <emphasis>color difference</emphasis> signals, this way
+the green component can be reconstructed by subtracting from the
+brightness component. See <xref linkend="colorspaces" /> for conversion
+examples. YUV was chosen because early television would only transmit
+brightness information. To add color in a way compatible with existing
+receivers a new signal carrier was added to transmit the color
+difference signals. Secondary in the YUV format the U and V components
+usually have lower resolution than the Y component. This is an analog
+video compression technique taking advantage of a property of the
+human visual system, being more sensitive to brightness
+information.</para>
+
+    &sub-packed-yuv;
+    &sub-grey;
+    &sub-y16;
+    &sub-yuyv;
+    &sub-uyvy;
+    &sub-yvyu;
+    &sub-vyuy;
+    &sub-y41p;
+    &sub-yuv420;
+    &sub-yuv410;
+    &sub-yuv422p;
+    &sub-yuv411p;
+    &sub-nv12;
+    &sub-nv16;
+  </section>
+
+  <section>
+    <title>Compressed Formats</title>
+
+    <table pgwide="1" frame="none" id="compressed-formats">
+      <title>Compressed Image Formats</title>
+      <tgroup cols="3" align="left">
+	&cs-def;
+	<thead>
+	  <row>
+	    <entry>Identifier</entry>
+	    <entry>Code</entry>
+	    <entry>Details</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	 <row id="V4L2-PIX-FMT-JPEG">
+	    <entry><constant>V4L2_PIX_FMT_JPEG</constant></entry>
+	    <entry>'JPEG'</entry>
+	    <entry>TBD. See also &VIDIOC-G-JPEGCOMP;,
+	    &VIDIOC-S-JPEGCOMP;.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-MPEG">
+	    <entry><constant>V4L2_PIX_FMT_MPEG</constant></entry>
+	    <entry>'MPEG'</entry>
+	    <entry>MPEG stream. The actual format is determined by
+extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
+<xref linkend="mpeg-control-id" />.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <section id="pixfmt-reserved">
+    <title>Reserved Format Identifiers</title>
+
+    <para>These formats are not defined by this specification, they
+are just listed for reference and to avoid naming conflicts. If you
+want to register your own format, send an e-mail to the linux-media mailing
+list &v4l-ml; for inclusion in the <filename>videodev2.h</filename>
+file. If you want to share your format with other developers add a
+link to your documentation and send a copy to the linux-media mailing list
+for inclusion in this section. If you think your format should be listed
+in a standard format section please make a proposal on the linux-media mailing
+list.</para>
+
+    <table pgwide="1" frame="none" id="reserved-formats">
+      <title>Reserved Image Formats</title>
+      <tgroup cols="3" align="left">
+	&cs-def;
+	<thead>
+	  <row>
+	    <entry>Identifier</entry>
+	    <entry>Code</entry>
+	    <entry>Details</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row id="V4L2-PIX-FMT-DV">
+	    <entry><constant>V4L2_PIX_FMT_DV</constant></entry>
+	    <entry>'dvsd'</entry>
+	    <entry>unknown</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-ET61X251">
+	    <entry><constant>V4L2_PIX_FMT_ET61X251</constant></entry>
+	    <entry>'E625'</entry>
+	    <entry>Compressed format of the ET61X251 driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-HI240">
+	    <entry><constant>V4L2_PIX_FMT_HI240</constant></entry>
+	    <entry>'HI24'</entry>
+	    <entry><para>8 bit RGB format used by the BTTV driver.</para></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-HM12">
+	    <entry><constant>V4L2_PIX_FMT_HM12</constant></entry>
+	    <entry>'HM12'</entry>
+	    <entry><para>YUV 4:2:0 format used by the
+IVTV driver, <ulink url="http://www.ivtvdriver.org/">
+http://www.ivtvdriver.org/</ulink></para><para>The format is documented in the
+kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm12</filename>
+</para></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SPCA501">
+	    <entry><constant>V4L2_PIX_FMT_SPCA501</constant></entry>
+	    <entry>'S501'</entry>
+	    <entry>YUYV per line used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SPCA505">
+	    <entry><constant>V4L2_PIX_FMT_SPCA505</constant></entry>
+	    <entry>'S505'</entry>
+	    <entry>YYUV per line used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SPCA508">
+	    <entry><constant>V4L2_PIX_FMT_SPCA508</constant></entry>
+	    <entry>'S508'</entry>
+	    <entry>YUVY per line used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SPCA561">
+	    <entry><constant>V4L2_PIX_FMT_SPCA561</constant></entry>
+	    <entry>'S561'</entry>
+	    <entry>Compressed GBRG Bayer format used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SGRBG10">
+	    <entry><constant>V4L2_PIX_FMT_SGRBG10</constant></entry>
+	    <entry>'DA10'</entry>
+	    <entry>10 bit raw Bayer, expanded to 16 bits.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SGRBG10DPCM8">
+	    <entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry>
+	    <entry>'DB10'</entry>
+	    <entry>10 bit raw Bayer DPCM compressed to 8 bits.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-PAC207">
+	    <entry><constant>V4L2_PIX_FMT_PAC207</constant></entry>
+	    <entry>'P207'</entry>
+	    <entry>Compressed BGGR Bayer format used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-MR97310A">
+	    <entry><constant>V4L2_PIX_FMT_MR97310A</constant></entry>
+	    <entry>'M310'</entry>
+	    <entry>Compressed BGGR Bayer format used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-OV511">
+	    <entry><constant>V4L2_PIX_FMT_OV511</constant></entry>
+	    <entry>'O511'</entry>
+	    <entry>OV511 JPEG format used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-OV518">
+	    <entry><constant>V4L2_PIX_FMT_OV518</constant></entry>
+	    <entry>'O518'</entry>
+	    <entry>OV518 JPEG format used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-PJPG">
+	    <entry><constant>V4L2_PIX_FMT_PJPG</constant></entry>
+	    <entry>'PJPG'</entry>
+	    <entry>Pixart 73xx JPEG format used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SQ905C">
+	    <entry><constant>V4L2_PIX_FMT_SQ905C</constant></entry>
+	    <entry>'905C'</entry>
+	    <entry>Compressed RGGB bayer format used by the gspca driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-MJPEG">
+	    <entry><constant>V4L2_PIX_FMT_MJPEG</constant></entry>
+	    <entry>'MJPG'</entry>
+	    <entry>Compressed format used by the Zoran driver</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-PWC1">
+	    <entry><constant>V4L2_PIX_FMT_PWC1</constant></entry>
+	    <entry>'PWC1'</entry>
+	    <entry>Compressed format of the PWC driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-PWC2">
+	    <entry><constant>V4L2_PIX_FMT_PWC2</constant></entry>
+	    <entry>'PWC2'</entry>
+	    <entry>Compressed format of the PWC driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SN9C10X">
+	    <entry><constant>V4L2_PIX_FMT_SN9C10X</constant></entry>
+	    <entry>'S910'</entry>
+	    <entry>Compressed format of the SN9C102 driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-SN9C20X-I420">
+	    <entry><constant>V4L2_PIX_FMT_SN9C20X_I420</constant></entry>
+	    <entry>'S920'</entry>
+	    <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-WNVA">
+	    <entry><constant>V4L2_PIX_FMT_WNVA</constant></entry>
+	    <entry>'WNVA'</entry>
+	    <entry><para>Used by the Winnov Videum driver, <ulink
+url="http://www.thedirks.org/winnov/">
+http://www.thedirks.org/winnov/</ulink></para></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-TM6000">
+	    <entry><constant>V4L2_PIX_FMT_TM6000</constant></entry>
+	    <entry>'TM60'</entry>
+	    <entry><para>Used by Trident tm6000</para></entry>
+	  </row>
+	  <row id="V4L2-PIX-FMT-YYUV">
+	    <entry><constant>V4L2_PIX_FMT_YYUV</constant></entry>
+	    <entry>'YYUV'</entry>
+	    <entry>unknown</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff --git a/Documentation/DocBook/v4l/remote_controllers.xml b/Documentation/DocBook/v4l/remote_controllers.xml
new file mode 100644
index 0000000..73f5eab
--- /dev/null
+++ b/Documentation/DocBook/v4l/remote_controllers.xml
@@ -0,0 +1,175 @@
+<title>Remote Controllers</title>
+<section id="Remote_controllers_Intro">
+<title>Introduction</title>
+
+<para>Currently, most analog and digital devices have a Infrared input for remote controllers. Each
+manufacturer has their own type of control. It is not rare for the same manufacturer to ship different
+types of controls, depending on the device.</para>
+<para>Unfortunately, for several years, there was no effort to create uniform IR keycodes for
+different devices.  This caused the same IR keyname to be mapped completely differently on
+different IR devices. This resulted that the same IR keyname to be mapped completely different on
+different IR's. Due to that, V4L2 API now specifies a standard for mapping Media keys on IR.</para>
+<para>This standard should be used by both V4L/DVB drivers and userspace applications</para>
+<para>The modules register the remote as keyboard within the linux input layer. This means that the IR key strokes will look like normal keyboard key strokes (if CONFIG_INPUT_KEYBOARD is enabled). Using the event devices (CONFIG_INPUT_EVDEV) it is possible for applications to access the remote via /dev/input/event devices.</para>
+
+<table pgwide="1" frame="none" id="rc_standard_keymap">
+<title>IR default keymapping</title>
+<tgroup cols="3">
+&cs-str;
+<tbody valign="top">
+<row>
+<entry>Key code</entry>
+<entry>Meaning</entry>
+<entry>Key examples on IR</entry>
+</row>
+
+<row><entry><emphasis role="bold">Numeric keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_0</constant></entry><entry>Keyboard digit 0</entry><entry>0</entry></row>
+<row><entry><constant>KEY_1</constant></entry><entry>Keyboard digit 1</entry><entry>1</entry></row>
+<row><entry><constant>KEY_2</constant></entry><entry>Keyboard digit 2</entry><entry>2</entry></row>
+<row><entry><constant>KEY_3</constant></entry><entry>Keyboard digit 3</entry><entry>3</entry></row>
+<row><entry><constant>KEY_4</constant></entry><entry>Keyboard digit 4</entry><entry>4</entry></row>
+<row><entry><constant>KEY_5</constant></entry><entry>Keyboard digit 5</entry><entry>5</entry></row>
+<row><entry><constant>KEY_6</constant></entry><entry>Keyboard digit 6</entry><entry>6</entry></row>
+<row><entry><constant>KEY_7</constant></entry><entry>Keyboard digit 7</entry><entry>7</entry></row>
+<row><entry><constant>KEY_8</constant></entry><entry>Keyboard digit 8</entry><entry>8</entry></row>
+<row><entry><constant>KEY_9</constant></entry><entry>Keyboard digit 9</entry><entry>9</entry></row>
+
+<row><entry><emphasis role="bold">Movie play control</emphasis></entry></row>
+
+<row><entry><constant>KEY_FORWARD</constant></entry><entry>Instantly advance in time</entry><entry>&gt;&gt; / FORWARD</entry></row>
+<row><entry><constant>KEY_BACK</constant></entry><entry>Instantly go back in time</entry><entry>&lt;&lt;&lt; / BACK</entry></row>
+<row><entry><constant>KEY_FASTFORWARD</constant></entry><entry>Play movie faster</entry><entry>&gt;&gt;&gt; / FORWARD</entry></row>
+<row><entry><constant>KEY_REWIND</constant></entry><entry>Play movie back</entry><entry>REWIND / BACKWARD</entry></row>
+<row><entry><constant>KEY_NEXT</constant></entry><entry>Select next chapter / sub-chapter / interval</entry><entry>NEXT / SKIP</entry></row>
+<row><entry><constant>KEY_PREVIOUS</constant></entry><entry>Select previous chapter / sub-chapter / interval</entry><entry>&lt;&lt; /  PREV / PREVIOUS</entry></row>
+<row><entry><constant>KEY_AGAIN</constant></entry><entry>Repeat the video or a video interval</entry><entry>REPEAT / LOOP / RECALL</entry></row>
+<row><entry><constant>KEY_PAUSE</constant></entry><entry>Pause sroweam</entry><entry>PAUSE / FREEZE</entry></row>
+<row><entry><constant>KEY_PLAY</constant></entry><entry>Play movie at the normal timeshift</entry><entry>NORMAL TIMESHIFT / LIVE / &gt;</entry></row>
+<row><entry><constant>KEY_PLAYPAUSE</constant></entry><entry>Alternate between play and pause</entry><entry>PLAY / PAUSE</entry></row>
+<row><entry><constant>KEY_STOP</constant></entry><entry>Stop sroweam</entry><entry>STOP</entry></row>
+<row><entry><constant>KEY_RECORD</constant></entry><entry>Start/stop recording sroweam</entry><entry>CAPTURE / REC / RECORD/PAUSE</entry></row>
+<row><entry><constant>KEY_CAMERA</constant></entry><entry>Take a picture of the image</entry><entry>CAMERA ICON / CAPTURE / SNAPSHOT</entry></row>
+<row><entry><constant>KEY_SHUFFLE</constant></entry><entry>Enable shuffle mode</entry><entry>SHUFFLE</entry></row>
+<row><entry><constant>KEY_TIME</constant></entry><entry>Activate time shift mode</entry><entry>TIME SHIFT</entry></row>
+<row><entry><constant>KEY_TITLE</constant></entry><entry>Allow changing the chapter</entry><entry>CHAPTER</entry></row>
+<row><entry><constant>KEY_SUBTITLE</constant></entry><entry>Allow changing the subtitle</entry><entry>SUBTITLE</entry></row>
+
+<row><entry><emphasis role="bold">Image control</emphasis></entry></row>
+
+<row><entry><constant>KEY_BRIGHTNESSDOWN</constant></entry><entry>Decrease Brightness</entry><entry>BRIGHTNESS DECREASE</entry></row>
+<row><entry><constant>KEY_BRIGHTNESSUP</constant></entry><entry>Increase Brightness</entry><entry>BRIGHTNESS INCREASE</entry></row>
+
+<row><entry><constant>KEY_ANGLE</constant></entry><entry>Switch video camera angle (on videos with more than one angle stored)</entry><entry>ANGLE / SWAP</entry></row>
+<row><entry><constant>KEY_EPG</constant></entry><entry>Open the Elecrowonic Play Guide (EPG)</entry><entry>EPG / GUIDE</entry></row>
+<row><entry><constant>KEY_TEXT</constant></entry><entry>Activate/change closed caption mode</entry><entry>CLOSED CAPTION/TELETEXT / DVD TEXT / TELETEXT / TTX</entry></row>
+
+<row><entry><emphasis role="bold">Audio control</emphasis></entry></row>
+
+<row><entry><constant>KEY_AUDIO</constant></entry><entry>Change audio source</entry><entry>AUDIO SOURCE / AUDIO / MUSIC</entry></row>
+<row><entry><constant>KEY_MUTE</constant></entry><entry>Mute/unmute audio</entry><entry>MUTE / DEMUTE / UNMUTE</entry></row>
+<row><entry><constant>KEY_VOLUMEDOWN</constant></entry><entry>Decrease volume</entry><entry>VOLUME- / VOLUME DOWN</entry></row>
+<row><entry><constant>KEY_VOLUMEUP</constant></entry><entry>Increase volume</entry><entry>VOLUME+ / VOLUME UP</entry></row>
+<row><entry><constant>KEY_MODE</constant></entry><entry>Change sound mode</entry><entry>MONO/STEREO</entry></row>
+<row><entry><constant>KEY_LANGUAGE</constant></entry><entry>Select Language</entry><entry>1ST / 2ND LANGUAGE / DVD LANG / MTS/SAP / MTS SEL</entry></row>
+
+<row><entry><emphasis role="bold">Channel control</emphasis></entry></row>
+
+<row><entry><constant>KEY_CHANNEL</constant></entry><entry>Go to the next favorite channel</entry><entry>ALT / CHANNEL / CH SURFING / SURF / FAV</entry></row>
+<row><entry><constant>KEY_CHANNELDOWN</constant></entry><entry>Decrease channel sequencially</entry><entry>CHANNEL - / CHANNEL DOWN / DOWN</entry></row>
+<row><entry><constant>KEY_CHANNELUP</constant></entry><entry>Increase channel sequencially</entry><entry>CHANNEL + / CHANNEL UP / UP</entry></row>
+<row><entry><constant>KEY_DIGITS</constant></entry><entry>Use more than one digit for channel</entry><entry>PLUS / 100/ 1xx / xxx /  -/--  / Single Double Triple Digit</entry></row>
+<row><entry><constant>KEY_SEARCH</constant></entry><entry>Start channel autoscan</entry><entry>SCAN / AUTOSCAN</entry></row>
+
+<row><entry><emphasis role="bold">Colored keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_BLUE</constant></entry><entry>IR Blue key</entry><entry>BLUE</entry></row>
+<row><entry><constant>KEY_GREEN</constant></entry><entry>IR Green Key</entry><entry>GREEN</entry></row>
+<row><entry><constant>KEY_RED</constant></entry><entry>IR Red key</entry><entry>RED</entry></row>
+<row><entry><constant>KEY_YELLOW</constant></entry><entry>IR Yellow key</entry><entry> YELLOW</entry></row>
+
+<row><entry><emphasis role="bold">Media selection</emphasis></entry></row>
+
+<row><entry><constant>KEY_CD</constant></entry><entry>Change input source to Compact Disc</entry><entry>CD</entry></row>
+<row><entry><constant>KEY_DVD</constant></entry><entry>Change input to DVD</entry><entry>DVD / DVD MENU</entry></row>
+<row><entry><constant>KEY_EJECTCLOSECD</constant></entry><entry>Open/close the CD/DVD player</entry><entry>-&gt; ) / CLOSE / OPEN</entry></row>
+
+<row><entry><constant>KEY_MEDIA</constant></entry><entry>Turn on/off Media application</entry><entry>PC/TV /  TURN ON/OFF APP</entry></row>
+<row><entry><constant>KEY_PC</constant></entry><entry>Selects from TV to PC</entry><entry>PC</entry></row>
+<row><entry><constant>KEY_RADIO</constant></entry><entry>Put into AM/FM radio mode</entry><entry>RADIO / TV/FM / TV/RADIO / FM / FM/RADIO</entry></row>
+<row><entry><constant>KEY_TV</constant></entry><entry>Select tv mode</entry><entry>TV / LIVE TV</entry></row>
+<row><entry><constant>KEY_TV2</constant></entry><entry>Select Cable mode</entry><entry>AIR/CBL</entry></row>
+<row><entry><constant>KEY_VCR</constant></entry><entry>Select VCR mode</entry><entry>VCR MODE / DTR</entry></row>
+<row><entry><constant>KEY_VIDEO</constant></entry><entry>Alternate between input modes</entry><entry>SOURCE / SELECT / DISPLAY / SWITCH INPUTS / VIDEO</entry></row>
+
+<row><entry><emphasis role="bold">Power control</emphasis></entry></row>
+
+<row><entry><constant>KEY_POWER</constant></entry><entry>Turn on/off computer</entry><entry>SYSTEM POWER / COMPUTER POWER</entry></row>
+<row><entry><constant>KEY_POWER2</constant></entry><entry>Turn on/off application</entry><entry>TV ON/OFF / POWER</entry></row>
+<row><entry><constant>KEY_SLEEP</constant></entry><entry>Activate sleep timer</entry><entry>SLEEP / SLEEP TIMER</entry></row>
+<row><entry><constant>KEY_SUSPEND</constant></entry><entry>Put computer into suspend mode</entry><entry>STANDBY / SUSPEND</entry></row>
+
+<row><entry><emphasis role="bold">Window control</emphasis></entry></row>
+
+<row><entry><constant>KEY_CLEAR</constant></entry><entry>Stop sroweam and return to default input video/audio</entry><entry>CLEAR / RESET / BOSS KEY</entry></row>
+<row><entry><constant>KEY_CYCLEWINDOWS</constant></entry><entry>Minimize windows and move to the next one</entry><entry>ALT-TAB / MINIMIZE / DESKTOP</entry></row>
+<row><entry><constant>KEY_FAVORITES</constant></entry><entry>Open the favorites sroweam window</entry><entry>TV WALL / Favorites</entry></row>
+<row><entry><constant>KEY_MENU</constant></entry><entry>Call application menu</entry><entry>2ND CONTROLS (USA: MENU) / DVD/MENU / SHOW/HIDE CTRL</entry></row>
+<row><entry><constant>KEY_NEW</constant></entry><entry>Open/Close Picture in Picture</entry><entry>PIP</entry></row>
+<row><entry><constant>KEY_OK</constant></entry><entry>Send a confirmation code to application</entry><entry>OK / ENTER / RETURN</entry></row>
+<row><entry><constant>KEY_SCREEN</constant></entry><entry>Select screen aspect ratio</entry><entry>4:3 16:9 SELECT</entry></row>
+<row><entry><constant>KEY_ZOOM</constant></entry><entry>Put device into zoom/full screen mode</entry><entry>ZOOM / FULL SCREEN / ZOOM+ / HIDE PANNEL / SWITCH</entry></row>
+
+<row><entry><emphasis role="bold">Navigation keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_ESC</constant></entry><entry>Cancel current operation</entry><entry>CANCEL / BACK</entry></row>
+<row><entry><constant>KEY_HELP</constant></entry><entry>Open a Help window</entry><entry>HELP</entry></row>
+<row><entry><constant>KEY_HOMEPAGE</constant></entry><entry>Navigate to Homepage</entry><entry>HOME</entry></row>
+<row><entry><constant>KEY_INFO</constant></entry><entry>Open On Screen Display</entry><entry>DISPLAY INFORMATION / OSD</entry></row>
+<row><entry><constant>KEY_WWW</constant></entry><entry>Open the default browser</entry><entry>WEB</entry></row>
+<row><entry><constant>KEY_UP</constant></entry><entry>Up key</entry><entry>UP</entry></row>
+<row><entry><constant>KEY_DOWN</constant></entry><entry>Down key</entry><entry>DOWN</entry></row>
+<row><entry><constant>KEY_LEFT</constant></entry><entry>Left key</entry><entry>LEFT</entry></row>
+<row><entry><constant>KEY_RIGHT</constant></entry><entry>Right key</entry><entry>RIGHT</entry></row>
+
+<row><entry><emphasis role="bold">Miscelaneous keys</emphasis></entry></row>
+
+<row><entry><constant>KEY_DOT</constant></entry><entry>Return a dot</entry><entry>.</entry></row>
+<row><entry><constant>KEY_FN</constant></entry><entry>Select a function</entry><entry>FUNCTION</entry></row>
+
+</tbody>
+</tgroup>
+</table>
+
+<para>It should be noticed that, sometimes, there some fundamental missing keys at some cheaper IR's. Due to that, it is recommended to:</para>
+
+<table pgwide="1" frame="none" id="rc_keymap_notes">
+<title>Notes</title>
+<tgroup cols="1">
+&cs-str;
+<tbody valign="top">
+<row>
+<entry>On simpler IR's, without separate channel keys, you need to map UP as <constant>KEY_CHANNELUP</constant></entry>
+</row><row>
+<entry>On simpler IR's, without separate channel keys, you need to map DOWN as <constant>KEY_CHANNELDOWN</constant></entry>
+</row><row>
+<entry>On simpler IR's, without separate volume keys, you need to map LEFT as <constant>KEY_VOLUMEDOWN</constant></entry>
+</row><row>
+<entry>On simpler IR's, without separate volume keys, you need to map RIGHT as <constant>KEY_VOLUMEUP</constant></entry>
+</row>
+</tbody>
+</tgroup>
+</table>
+
+</section>
+
+<section id="Remote_controllers_table_change">
+<title>Changing default Remote Controller mappings</title>
+<para>The event interface provides two ioctls to be used against
+the /dev/input/event device, to allow changing the default
+keymapping.</para>
+
+<para>This program demonstrates how to replace the keymap tables.</para>
+&sub-keytable-c;
+</section>
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
new file mode 100644
index 0000000..937b415
--- /dev/null
+++ b/Documentation/DocBook/v4l/v4l2.xml
@@ -0,0 +1,479 @@
+ <partinfo>
+    <authorgroup>
+      <author>
+	<firstname>Michael</firstname>
+	<surname>Schimek</surname>
+	<othername role="mi">H</othername>
+	<affiliation>
+	  <address>
+	    <email>mschimek@gmx.at</email>
+	  </address>
+	</affiliation>
+      </author>
+
+      <author>
+	<firstname>Bill</firstname>
+	<surname>Dirks</surname>
+	<!-- Commented until Bill opts in to be spammed.
+	<affiliation>
+	  <address>
+	    <email>bill@thedirks.org</email>
+	  </address>
+	</affiliation> -->
+	<contrib>Original author of the V4L2 API and
+documentation.</contrib>
+      </author>
+
+      <author>
+	<firstname>Hans</firstname>
+	<surname>Verkuil</surname>
+	<contrib>Designed and documented the VIDIOC_LOG_STATUS ioctl,
+the extended control ioctls and major parts of the sliced VBI
+API.</contrib>
+	<affiliation>
+	  <address>
+	    <email>hverkuil@xs4all.nl</email>
+	  </address>
+	</affiliation>
+      </author>
+
+      <author>
+	<firstname>Martin</firstname>
+	<surname>Rubli</surname>
+	<!--
+	<affiliation>
+	  <address>
+	    <email>martin_rubli@logitech.com</email>
+	  </address>
+	</affiliation> -->
+	<contrib>Designed and documented the VIDIOC_ENUM_FRAMESIZES
+and VIDIOC_ENUM_FRAMEINTERVALS ioctls.</contrib>
+      </author>
+
+      <author>
+	<firstname>Andy</firstname>
+	<surname>Walls</surname>
+	<contrib>Documented the fielded V4L2_MPEG_STREAM_VBI_FMT_IVTV
+MPEG stream embedded, sliced VBI data format in this specification.
+</contrib>
+	<affiliation>
+	  <address>
+	    <email>awalls@radix.net</email>
+	  </address>
+	</affiliation>
+      </author>
+
+      <author>
+	<firstname>Mauro</firstname>
+	<surname>Carvalho Chehab</surname>
+	<contrib>Documented libv4l, designed and added v4l2grab example,
+Remote Controller chapter.</contrib>
+	<affiliation>
+	  <address>
+	    <email>mchehab@redhat.com</email>
+	  </address>
+	</affiliation>
+      </author>
+    </authorgroup>
+
+    <copyright>
+      <year>1999</year>
+      <year>2000</year>
+      <year>2001</year>
+      <year>2002</year>
+      <year>2003</year>
+      <year>2004</year>
+      <year>2005</year>
+      <year>2006</year>
+      <year>2007</year>
+      <year>2008</year>
+      <year>2009</year>
+      <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
+Rubli, Andy Walls, Mauro Carvalho Chehab</holder>
+    </copyright>
+    <legalnotice>
+    <para>Except when explicitly stated as GPL, programming examples within
+	    this part can be used and distributed without restrictions.</para>
+    </legalnotice>
+    <revhistory>
+      <!-- Put document revisions here, newest first. -->
+      <!-- API revisions (changes and additions of defines, enums,
+structs, ioctls) must be noted in more detail in the history chapter
+(compat.sgml), along with the possible impact on existing drivers and
+applications. -->
+
+      <revision>
+	<revnumber>2.6.32</revnumber>
+	<date>2009-08-31</date>
+	<authorinitials>mcc</authorinitials>
+	<revremark>Now, revisions will match the kernel version where
+the V4L2 API changes will be used by the Linux Kernel.
+Also added Remote Controller chapter.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.29</revnumber>
+	<date>2009-08-26</date>
+	<authorinitials>ev</authorinitials>
+	<revremark>Added documentation for string controls and for FM Transmitter controls.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.28</revnumber>
+	<date>2009-08-26</date>
+	<authorinitials>gl</authorinitials>
+	<revremark>Added V4L2_CID_BAND_STOP_FILTER documentation.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.27</revnumber>
+	<date>2009-08-15</date>
+	<authorinitials>mcc</authorinitials>
+	<revremark>Added libv4l and Remote Controller documentation;
+added v4l2grab and keytable application examples.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.26</revnumber>
+	<date>2009-07-23</date>
+	<authorinitials>hv</authorinitials>
+	<revremark>Finalized the RDS capture API. Added modulator and RDS encoder
+capabilities. Added support for string controls.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.25</revnumber>
+	<date>2009-01-18</date>
+	<authorinitials>hv</authorinitials>
+	<revremark>Added pixel formats VYUY, NV16 and NV61, and changed
+the debug ioctls VIDIOC_DBG_G/S_REGISTER and VIDIOC_DBG_G_CHIP_IDENT.
+Added camera controls V4L2_CID_ZOOM_ABSOLUTE, V4L2_CID_ZOOM_RELATIVE,
+V4L2_CID_ZOOM_CONTINUOUS and V4L2_CID_PRIVACY.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.24</revnumber>
+	<date>2008-03-04</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Added pixel formats Y16 and SBGGR16, new controls
+and a camera controls class. Removed VIDIOC_G/S_MPEGCOMP.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.23</revnumber>
+	<date>2007-08-30</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Fixed a typo in VIDIOC_DBG_G/S_REGISTER.
+Clarified the byte order of packed pixel formats.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.22</revnumber>
+	<date>2007-08-29</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Added the Video Output Overlay interface, new MPEG
+controls, V4L2_FIELD_INTERLACED_TB and V4L2_FIELD_INTERLACED_BT,
+VIDIOC_DBG_G/S_REGISTER, VIDIOC_(TRY_)ENCODER_CMD,
+VIDIOC_G_CHIP_IDENT, VIDIOC_G_ENC_INDEX, new pixel formats.
+Clarifications in the cropping chapter, about RGB pixel formats, the
+mmap(), poll(), select(), read() and write() functions. Typographical
+fixes.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.21</revnumber>
+	<date>2006-12-19</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Fixed a link in the VIDIOC_G_EXT_CTRLS section.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.20</revnumber>
+	<date>2006-11-24</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Clarified the purpose of the audioset field in
+struct v4l2_input and v4l2_output.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.19</revnumber>
+	<date>2006-10-19</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Documented V4L2_PIX_FMT_RGB444.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.18</revnumber>
+	<date>2006-10-18</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Added the description of extended controls by Hans
+Verkuil. Linked V4L2_PIX_FMT_MPEG to V4L2_CID_MPEG_STREAM_TYPE.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.17</revnumber>
+	<date>2006-10-12</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Corrected V4L2_PIX_FMT_HM12 description.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.16</revnumber>
+	<date>2006-10-08</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>VIDIOC_ENUM_FRAMESIZES and
+VIDIOC_ENUM_FRAMEINTERVALS are now part of the API.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.15</revnumber>
+	<date>2006-09-23</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Cleaned up the bibliography, added BT.653 and
+BT.1119. capture.c/start_capturing() for user pointer I/O did not
+initialize the buffer index. Documented the V4L MPEG and MJPEG
+VID_TYPEs and V4L2_PIX_FMT_SBGGR8. Updated the list of reserved pixel
+formats. See the history chapter for API changes.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.14</revnumber>
+	<date>2006-09-14</date>
+	<authorinitials>mr</authorinitials>
+	<revremark>Added VIDIOC_ENUM_FRAMESIZES and
+VIDIOC_ENUM_FRAMEINTERVALS proposal for frame format enumeration of
+digital devices.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.13</revnumber>
+	<date>2006-04-07</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Corrected the description of struct v4l2_window
+clips. New V4L2_STD_ and V4L2_TUNER_MODE_LANG1_LANG2
+defines.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.12</revnumber>
+	<date>2006-02-03</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Corrected the description of struct
+v4l2_captureparm and v4l2_outputparm.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.11</revnumber>
+	<date>2006-01-27</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Improved the description of struct
+v4l2_tuner.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.10</revnumber>
+	<date>2006-01-10</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>VIDIOC_G_INPUT and VIDIOC_S_PARM
+clarifications.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.9</revnumber>
+	<date>2005-11-27</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Improved the 525 line numbering diagram. Hans
+Verkuil and I rewrote the sliced VBI section. He also contributed a
+VIDIOC_LOG_STATUS page. Fixed VIDIOC_S_STD call in the video standard
+selection example. Various updates.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.8</revnumber>
+	<date>2004-10-04</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Somehow a piece of junk slipped into the capture
+example, removed.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.7</revnumber>
+	<date>2004-09-19</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Fixed video standard selection, control
+enumeration, downscaling and aspect example. Added read and user
+pointer i/o to video capture example.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.6</revnumber>
+	<date>2004-08-01</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>v4l2_buffer changes, added video capture example,
+various corrections.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.5</revnumber>
+	<date>2003-11-05</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Pixel format erratum.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.4</revnumber>
+	<date>2003-09-17</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Corrected source and Makefile to generate a PDF.
+SGML fixes. Added latest API changes. Closed gaps in the history
+chapter.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.3</revnumber>
+	<date>2003-02-05</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Another draft, more corrections.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.2</revnumber>
+	<date>2003-01-15</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>Second draft, with corrections pointed out by Gerd
+Knorr.</revremark>
+      </revision>
+
+      <revision>
+	<revnumber>0.1</revnumber>
+	<date>2002-12-01</date>
+	<authorinitials>mhs</authorinitials>
+	<revremark>First draft, based on documentation by Bill Dirks
+and discussions on the V4L mailing list.</revremark>
+      </revision>
+    </revhistory>
+</partinfo>
+
+<title>Video for Linux Two API Specification</title>
+ <subtitle>Revision 2.6.32</subtitle>
+
+  <chapter id="common">
+    &sub-common;
+  </chapter>
+
+  <chapter id="pixfmt">
+    &sub-pixfmt;
+  </chapter>
+
+  <chapter id="io">
+    &sub-io;
+  </chapter>
+
+  <chapter id="devices">
+    <title>Interfaces</title>
+
+    <section id="capture"> &sub-dev-capture; </section>
+    <section id="overlay"> &sub-dev-overlay; </section>
+    <section id="output"> &sub-dev-output; </section>
+    <section id="osd"> &sub-dev-osd; </section>
+    <section id="codec"> &sub-dev-codec; </section>
+    <section id="effect"> &sub-dev-effect; </section>
+    <section id="raw-vbi"> &sub-dev-raw-vbi; </section>
+    <section id="sliced"> &sub-dev-sliced-vbi; </section>
+    <section id="ttx"> &sub-dev-teletext; </section>
+    <section id="radio"> &sub-dev-radio; </section>
+    <section id="rds"> &sub-dev-rds; </section>
+  </chapter>
+
+  <chapter id="driver">
+	  &sub-driver;
+  </chapter>
+
+  <chapter id="libv4l">
+	  &sub-libv4l;
+  </chapter>
+
+  <chapter id="compat">
+	  &sub-compat;
+  </chapter>
+
+  <appendix id="user-func">
+  <title>Function Reference</title>
+
+    <!-- Keep this alphabetically sorted. -->
+
+    &sub-close;
+    &sub-ioctl;
+    <!-- All ioctls go here. -->
+    &sub-cropcap;
+    &sub-dbg-g-chip-ident;
+    &sub-dbg-g-register;
+    &sub-encoder-cmd;
+    &sub-enumaudio;
+    &sub-enumaudioout;
+    &sub-enum-fmt;
+    &sub-enum-framesizes;
+    &sub-enum-frameintervals;
+    &sub-enuminput;
+    &sub-enumoutput;
+    &sub-enumstd;
+    &sub-g-audio;
+    &sub-g-audioout;
+    &sub-g-crop;
+    &sub-g-ctrl;
+    &sub-g-enc-index;
+    &sub-g-ext-ctrls;
+    &sub-g-fbuf;
+    &sub-g-fmt;
+    &sub-g-frequency;
+    &sub-g-input;
+    &sub-g-jpegcomp;
+    &sub-g-modulator;
+    &sub-g-output;
+    &sub-g-parm;
+    &sub-g-priority;
+    &sub-g-sliced-vbi-cap;
+    &sub-g-std;
+    &sub-g-tuner;
+    &sub-log-status;
+    &sub-overlay;
+    &sub-qbuf;
+    &sub-querybuf;
+    &sub-querycap;
+    &sub-queryctrl;
+    &sub-querystd;
+    &sub-reqbufs;
+    &sub-s-hw-freq-seek;
+    &sub-streamon;
+    <!-- End of ioctls. -->
+    &sub-mmap;
+    &sub-munmap;
+    &sub-open;
+    &sub-poll;
+    &sub-read;
+    &sub-select;
+    &sub-write;
+  </appendix>
+
+  <appendix id="videodev">
+    <title>Video For Linux Two Header File</title>
+    &sub-videodev2-h;
+  </appendix>
+
+  <appendix id="capture-example">
+    <title>Video Capture Example</title>
+    &sub-capture-c;
+  </appendix>
+
+  <appendix id="v4l2grab-example">
+    <title>Video Grabber example using libv4l</title>
+    <para>This program demonstrates how to grab V4L2 images in ppm format by
+using libv4l handlers. The advantage is that this grabber can potentially work
+with any V4L2 driver.</para>
+    &sub-v4l2grab-c;
+  </appendix>
+
+  &sub-media-indices;
+
+  &sub-biblio;
+
diff --git a/Documentation/DocBook/v4l/v4l2grab.c.xml b/Documentation/DocBook/v4l/v4l2grab.c.xml
new file mode 100644
index 0000000..bed12e4
--- /dev/null
+++ b/Documentation/DocBook/v4l/v4l2grab.c.xml
@@ -0,0 +1,164 @@
+<programlisting>
+/* V4L2 video picture grabber
+   Copyright (C) 2009 Mauro Carvalho Chehab &lt;mchehab@infradead.org&gt;
+
+   This program is free software; 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.
+ */
+
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;errno.h&gt;
+#include &lt;sys/ioctl.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/time.h&gt;
+#include &lt;sys/mman.h&gt;
+#include &lt;linux/videodev2.h&gt;
+#include "../libv4l/include/libv4l2.h"
+
+#define CLEAR(x) memset(&amp;(x), 0, sizeof(x))
+
+struct buffer {
+        void   *start;
+        size_t length;
+};
+
+static void xioctl(int fh, int request, void *arg)
+{
+        int r;
+
+        do {
+                r = v4l2_ioctl(fh, request, arg);
+        } while (r == -1 &amp;&amp; ((errno == EINTR) || (errno == EAGAIN)));
+
+        if (r == -1) {
+                fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
+                exit(EXIT_FAILURE);
+        }
+}
+
+int main(int argc, char **argv)
+{
+        struct <link linkend="v4l2-format">v4l2_format</link>              fmt;
+        struct <link linkend="v4l2-buffer">v4l2_buffer</link>              buf;
+        struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link>      req;
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>              type;
+        fd_set                          fds;
+        struct timeval                  tv;
+        int                             r, fd = -1;
+        unsigned int                    i, n_buffers;
+        char                            *dev_name = "/dev/video0";
+        char                            out_name[256];
+        FILE                            *fout;
+        struct buffer                   *buffers;
+
+        fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
+        if (fd &lt; 0) {
+                perror("Cannot open device");
+                exit(EXIT_FAILURE);
+        }
+
+        CLEAR(fmt);
+        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        fmt.fmt.pix.width       = 640;
+        fmt.fmt.pix.height      = 480;
+        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
+        fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
+        xioctl(fd, VIDIOC_S_FMT, &amp;fmt);
+        if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
+                printf("Libv4l didn't accept RGB24 format. Can't proceed.\n");
+                exit(EXIT_FAILURE);
+        }
+        if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
+                printf("Warning: driver is sending image at %dx%d\n",
+                        fmt.fmt.pix.width, fmt.fmt.pix.height);
+
+        CLEAR(req);
+        req.count = 2;
+        req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        req.memory = V4L2_MEMORY_MMAP;
+        xioctl(fd, VIDIOC_REQBUFS, &amp;req);
+
+        buffers = calloc(req.count, sizeof(*buffers));
+        for (n_buffers = 0; n_buffers &lt; req.count; ++n_buffers) {
+                CLEAR(buf);
+
+                buf.type        = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                buf.memory      = V4L2_MEMORY_MMAP;
+                buf.index       = n_buffers;
+
+                xioctl(fd, VIDIOC_QUERYBUF, &amp;buf);
+
+                buffers[n_buffers].length = buf.length;
+                buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
+                              PROT_READ | PROT_WRITE, MAP_SHARED,
+                              fd, buf.m.offset);
+
+                if (MAP_FAILED == buffers[n_buffers].start) {
+                        perror("mmap");
+                        exit(EXIT_FAILURE);
+                }
+        }
+
+        for (i = 0; i &lt; n_buffers; ++i) {
+                CLEAR(buf);
+                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                buf.memory = V4L2_MEMORY_MMAP;
+                buf.index = i;
+                xioctl(fd, VIDIOC_QBUF, &amp;buf);
+        }
+        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+        xioctl(fd, VIDIOC_STREAMON, &amp;type);
+        for (i = 0; i &lt; 20; i++) {
+                do {
+                        FD_ZERO(&amp;fds);
+                        FD_SET(fd, &amp;fds);
+
+                        /* Timeout. */
+                        tv.tv_sec = 2;
+                        tv.tv_usec = 0;
+
+                        r = select(fd + 1, &amp;fds, NULL, NULL, &amp;tv);
+                } while ((r == -1 &amp;&amp; (errno = EINTR)));
+                if (r == -1) {
+                        perror("select");
+                        return errno;
+                }
+
+                CLEAR(buf);
+                buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                buf.memory = V4L2_MEMORY_MMAP;
+                xioctl(fd, VIDIOC_DQBUF, &amp;buf);
+
+                sprintf(out_name, "out%03d.ppm", i);
+                fout = fopen(out_name, "w");
+                if (!fout) {
+                        perror("Cannot open image");
+                        exit(EXIT_FAILURE);
+                }
+                fprintf(fout, "P6\n%d %d 255\n",
+                        fmt.fmt.pix.width, fmt.fmt.pix.height);
+                fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
+                fclose(fout);
+
+                xioctl(fd, VIDIOC_QBUF, &amp;buf);
+        }
+
+        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        xioctl(fd, VIDIOC_STREAMOFF, &amp;type);
+        for (i = 0; i &lt; n_buffers; ++i)
+                v4l2_munmap(buffers[i].start, buffers[i].length);
+        v4l2_close(fd);
+
+        return 0;
+}
+</programlisting>
diff --git a/Documentation/DocBook/v4l/vbi_525.gif b/Documentation/DocBook/v4l/vbi_525.gif
new file mode 100644
index 0000000..5580b69
Binary files /dev/null and b/Documentation/DocBook/v4l/vbi_525.gif differ
diff --git a/Documentation/DocBook/v4l/vbi_525.pdf b/Documentation/DocBook/v4l/vbi_525.pdf
new file mode 100644
index 0000000..9e72c25
Binary files /dev/null and b/Documentation/DocBook/v4l/vbi_525.pdf differ
diff --git a/Documentation/DocBook/v4l/vbi_625.gif b/Documentation/DocBook/v4l/vbi_625.gif
new file mode 100644
index 0000000..34e3251
Binary files /dev/null and b/Documentation/DocBook/v4l/vbi_625.gif differ
diff --git a/Documentation/DocBook/v4l/vbi_625.pdf b/Documentation/DocBook/v4l/vbi_625.pdf
new file mode 100644
index 0000000..765235e
Binary files /dev/null and b/Documentation/DocBook/v4l/vbi_625.pdf differ
diff --git a/Documentation/DocBook/v4l/vbi_hsync.gif b/Documentation/DocBook/v4l/vbi_hsync.gif
new file mode 100644
index 0000000..b02434d
Binary files /dev/null and b/Documentation/DocBook/v4l/vbi_hsync.gif differ
diff --git a/Documentation/DocBook/v4l/vbi_hsync.pdf b/Documentation/DocBook/v4l/vbi_hsync.pdf
new file mode 100644
index 0000000..200b668
Binary files /dev/null and b/Documentation/DocBook/v4l/vbi_hsync.pdf differ
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml
new file mode 100644
index 0000000..9700206
--- /dev/null
+++ b/Documentation/DocBook/v4l/videodev2.h.xml
@@ -0,0 +1,1640 @@
+<programlisting>
+/*
+ *  Video for Linux Two header file
+ *
+ *  Copyright (C) 1999-2007 the contributors
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  Alternatively you can redistribute this file under the terms of the
+ *  BSD license as stated below:
+ *
+ *  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. The names of its contributors may not be used to endorse or promote
+ *     products derived from this software without specific prior written
+ *     permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ *  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *      Header file for v4l or V4L2 drivers and applications
+ * with public API.
+ * All kernel-specific stuff were moved to media/v4l2-dev.h, so
+ * no #if __KERNEL tests are allowed here
+ *
+ *      See http://linuxtv.org for more info
+ *
+ *      Author: Bill Dirks &lt;bill@thedirks.org&gt;
+ *              Justin Schoeman
+ *              Hans Verkuil &lt;hverkuil@xs4all.nl&gt;
+ *              et al.
+ */
+#ifndef __LINUX_VIDEODEV2_H
+#define __LINUX_VIDEODEV2_H
+
+#ifdef __KERNEL__
+#include &lt;linux/time.h&gt;     /* need struct timeval */
+#else
+#include &lt;sys/time.h&gt;
+#endif
+#include &lt;linux/compiler.h&gt;
+#include &lt;linux/ioctl.h&gt;
+#include &lt;linux/types.h&gt;
+
+/*
+ * Common stuff for both V4L1 and V4L2
+ * Moved from videodev.h
+ */
+#define VIDEO_MAX_FRAME               32
+
+#ifndef __KERNEL__
+
+/* These defines are V4L1 specific and should not be used with the V4L2 API!
+   They will be removed from this header in the future. */
+
+#define VID_TYPE_CAPTURE        1       /* Can capture */
+#define VID_TYPE_TUNER          2       /* Can tune */
+#define VID_TYPE_TELETEXT       4       /* Does teletext */
+#define VID_TYPE_OVERLAY        8       /* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY      16      /* Overlay by chromakey */
+#define VID_TYPE_CLIPPING       32      /* Can clip */
+#define VID_TYPE_FRAMERAM       64      /* Uses the frame buffer memory */
+#define VID_TYPE_SCALES         128     /* Scalable */
+#define VID_TYPE_MONOCHROME     256     /* Monochrome only */
+#define VID_TYPE_SUBCAPTURE     512     /* Can capture subareas of the image */
+#define VID_TYPE_MPEG_DECODER   1024    /* Can decode MPEG streams */
+#define VID_TYPE_MPEG_ENCODER   2048    /* Can encode MPEG streams */
+#define VID_TYPE_MJPEG_DECODER  4096    /* Can decode MJPEG streams */
+#define VID_TYPE_MJPEG_ENCODER  8192    /* Can encode MJPEG streams */
+#endif
+
+/*
+ *      M I S C E L L A N E O U S
+ */
+
+/*  Four-character-code (FOURCC) */
+#define v4l2_fourcc(a, b, c, d)\
+        ((__u32)(a) | ((__u32)(b) &lt;&lt; 8) | ((__u32)(c) &lt;&lt; 16) | ((__u32)(d) &lt;&lt; 24))
+
+/*
+ *      E N U M S
+ */
+enum <link linkend="v4l2-field">v4l2_field</link> {
+        V4L2_FIELD_ANY           = 0, /* driver can choose from none,
+                                         top, bottom, interlaced
+                                         depending on whatever it thinks
+                                         is approximate ... */
+        V4L2_FIELD_NONE          = 1, /* this device has no fields ... */
+        V4L2_FIELD_TOP           = 2, /* top field only */
+        V4L2_FIELD_BOTTOM        = 3, /* bottom field only */
+        V4L2_FIELD_INTERLACED    = 4, /* both fields interlaced */
+        V4L2_FIELD_SEQ_TB        = 5, /* both fields sequential into one
+                                         buffer, top-bottom order */
+        V4L2_FIELD_SEQ_BT        = 6, /* same as above + bottom-top order */
+        V4L2_FIELD_ALTERNATE     = 7, /* both fields alternating into
+                                         separate buffers */
+        V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
+                                         first and the top field is
+                                         transmitted first */
+        V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
+                                         first and the bottom field is
+                                         transmitted first */
+};
+#define V4L2_FIELD_HAS_TOP(field)       \
+        ((field) == V4L2_FIELD_TOP      ||\
+         (field) == V4L2_FIELD_INTERLACED ||\
+         (field) == V4L2_FIELD_INTERLACED_TB ||\
+         (field) == V4L2_FIELD_INTERLACED_BT ||\
+         (field) == V4L2_FIELD_SEQ_TB   ||\
+         (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTTOM(field)    \
+        ((field) == V4L2_FIELD_BOTTOM   ||\
+         (field) == V4L2_FIELD_INTERLACED ||\
+         (field) == V4L2_FIELD_INTERLACED_TB ||\
+         (field) == V4L2_FIELD_INTERLACED_BT ||\
+         (field) == V4L2_FIELD_SEQ_TB   ||\
+         (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTH(field)      \
+        ((field) == V4L2_FIELD_INTERLACED ||\
+         (field) == V4L2_FIELD_INTERLACED_TB ||\
+         (field) == V4L2_FIELD_INTERLACED_BT ||\
+         (field) == V4L2_FIELD_SEQ_TB ||\
+         (field) == V4L2_FIELD_SEQ_BT)
+
+enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> {
+        V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,
+        V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
+        V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
+        V4L2_BUF_TYPE_VBI_CAPTURE          = 4,
+        V4L2_BUF_TYPE_VBI_OUTPUT           = 5,
+        V4L2_BUF_TYPE_SLICED_VBI_CAPTURE   = 6,
+        V4L2_BUF_TYPE_SLICED_VBI_OUTPUT    = 7,
+#if 1 /*KEEP*/
+        /* Experimental */
+        V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
+#endif
+        V4L2_BUF_TYPE_PRIVATE              = 0x80,
+};
+
+enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link> {
+        V4L2_CTRL_TYPE_INTEGER       = 1,
+        V4L2_CTRL_TYPE_BOOLEAN       = 2,
+        V4L2_CTRL_TYPE_MENU          = 3,
+        V4L2_CTRL_TYPE_BUTTON        = 4,
+        V4L2_CTRL_TYPE_INTEGER64     = 5,
+        V4L2_CTRL_TYPE_CTRL_CLASS    = 6,
+        V4L2_CTRL_TYPE_STRING        = 7,
+};
+
+enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> {
+        V4L2_TUNER_RADIO             = 1,
+        V4L2_TUNER_ANALOG_TV         = 2,
+        V4L2_TUNER_DIGITAL_TV        = 3,
+};
+
+enum <link linkend="v4l2-memory">v4l2_memory</link> {
+        V4L2_MEMORY_MMAP             = 1,
+        V4L2_MEMORY_USERPTR          = 2,
+        V4L2_MEMORY_OVERLAY          = 3,
+};
+
+/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
+enum <link linkend="v4l2-colorspace">v4l2_colorspace</link> {
+        /* ITU-R 601 -- broadcast NTSC/PAL */
+        V4L2_COLORSPACE_SMPTE170M     = 1,
+
+        /* 1125-Line (US) HDTV */
+        V4L2_COLORSPACE_SMPTE240M     = 2,
+
+        /* HD and modern captures. */
+        V4L2_COLORSPACE_REC709        = 3,
+
+        /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
+        V4L2_COLORSPACE_BT878         = 4,
+
+        /* These should be useful.  Assume 601 extents. */
+        V4L2_COLORSPACE_470_SYSTEM_M  = 5,
+        V4L2_COLORSPACE_470_SYSTEM_BG = 6,
+
+        /* I know there will be cameras that send this.  So, this is
+         * unspecified chromaticities and full 0-255 on each of the
+         * Y'CbCr components
+         */
+        V4L2_COLORSPACE_JPEG          = 7,
+
+        /* For RGB colourspaces, this is probably a good start. */
+        V4L2_COLORSPACE_SRGB          = 8,
+};
+
+enum <link linkend="v4l2-priority">v4l2_priority</link> {
+        V4L2_PRIORITY_UNSET       = 0,  /* not initialized */
+        V4L2_PRIORITY_BACKGROUND  = 1,
+        V4L2_PRIORITY_INTERACTIVE = 2,
+        V4L2_PRIORITY_RECORD      = 3,
+        V4L2_PRIORITY_DEFAULT     = V4L2_PRIORITY_INTERACTIVE,
+};
+
+struct <link linkend="v4l2-rect">v4l2_rect</link> {
+        __s32   left;
+        __s32   top;
+        __s32   width;
+        __s32   height;
+};
+
+struct <link linkend="v4l2-fract">v4l2_fract</link> {
+        __u32   numerator;
+        __u32   denominator;
+};
+
+/*
+ *      D R I V E R   C A P A B I L I T I E S
+ */
+struct <link linkend="v4l2-capability">v4l2_capability</link> {
+        __u8    driver[16];     /* i.e.ie; "bttv" */
+        __u8    card[32];       /* i.e.ie; "Hauppauge WinTV" */
+        __u8    bus_info[32];   /* "PCI:" + pci_name(pci_dev) */
+        __u32   version;        /* should use KERNEL_VERSION() */
+        __u32   capabilities;   /* Device capabilities */
+        __u32   reserved[4];
+};
+
+/* Values for 'capabilities' field */
+#define V4L2_CAP_VIDEO_CAPTURE          0x00000001  /* Is a video capture device */
+#define V4L2_CAP_VIDEO_OUTPUT           0x00000002  /* Is a video output device */
+#define V4L2_CAP_VIDEO_OVERLAY          0x00000004  /* Can do video overlay */
+#define V4L2_CAP_VBI_CAPTURE            0x00000010  /* Is a raw VBI capture device */
+#define V4L2_CAP_VBI_OUTPUT             0x00000020  /* Is a raw VBI output device */
+#define V4L2_CAP_SLICED_VBI_CAPTURE     0x00000040  /* Is a sliced VBI capture device */
+#define V4L2_CAP_SLICED_VBI_OUTPUT      0x00000080  /* Is a sliced VBI output device */
+#define V4L2_CAP_RDS_CAPTURE            0x00000100  /* RDS data capture */
+#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY   0x00000200  /* Can do video output overlay */
+#define V4L2_CAP_HW_FREQ_SEEK           0x00000400  /* Can do hardware frequency seek  */
+#define V4L2_CAP_RDS_OUTPUT             0x00000800  /* Is an RDS encoder */
+
+#define V4L2_CAP_TUNER                  0x00010000  /* has a tuner */
+#define V4L2_CAP_AUDIO                  0x00020000  /* has audio support */
+#define V4L2_CAP_RADIO                  0x00040000  /* is a radio device */
+#define V4L2_CAP_MODULATOR              0x00080000  /* has a modulator */
+
+#define V4L2_CAP_READWRITE              0x01000000  /* read/write systemcalls */
+#define V4L2_CAP_ASYNCIO                0x02000000  /* async I/O */
+#define V4L2_CAP_STREAMING              0x04000000  /* streaming I/O ioctls */
+
+/*
+ *      V I D E O   I M A G E   F O R M A T
+ */
+struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
+        __u32                   width;
+        __u32                   height;
+        __u32                   pixelformat;
+        enum <link linkend="v4l2-field">v4l2_field</link>         field;
+        __u32                   bytesperline;   /* for padding, zero if unused */
+        __u32                   sizeimage;
+        enum <link linkend="v4l2-colorspace">v4l2_colorspace</link>    colorspace;
+        __u32                   priv;           /* private data, depends on pixelformat */
+};
+
+/*      Pixel format         FOURCC                          depth  Description  */
+
+/* RGB formats */
+#define <link linkend="V4L2-PIX-FMT-RGB332">V4L2_PIX_FMT_RGB332</link>  v4l2_fourcc('R', 'G', 'B', '1') /*  8  RGB-3-3-2     */
+#define <link linkend="V4L2-PIX-FMT-RGB444">V4L2_PIX_FMT_RGB444</link>  v4l2_fourcc('R', '4', '4', '4') /* 16  xxxxrrrr ggggbbbb */
+#define <link linkend="V4L2-PIX-FMT-RGB555">V4L2_PIX_FMT_RGB555</link>  v4l2_fourcc('R', 'G', 'B', 'O') /* 16  RGB-5-5-5     */
+#define <link linkend="V4L2-PIX-FMT-RGB565">V4L2_PIX_FMT_RGB565</link>  v4l2_fourcc('R', 'G', 'B', 'P') /* 16  RGB-5-6-5     */
+#define <link linkend="V4L2-PIX-FMT-RGB555X">V4L2_PIX_FMT_RGB555X</link> v4l2_fourcc('R', 'G', 'B', 'Q') /* 16  RGB-5-5-5 BE  */
+#define <link linkend="V4L2-PIX-FMT-RGB565X">V4L2_PIX_FMT_RGB565X</link> v4l2_fourcc('R', 'G', 'B', 'R') /* 16  RGB-5-6-5 BE  */
+#define <link linkend="V4L2-PIX-FMT-BGR24">V4L2_PIX_FMT_BGR24</link>   v4l2_fourcc('B', 'G', 'R', '3') /* 24  BGR-8-8-8     */
+#define <link linkend="V4L2-PIX-FMT-RGB24">V4L2_PIX_FMT_RGB24</link>   v4l2_fourcc('R', 'G', 'B', '3') /* 24  RGB-8-8-8     */
+#define <link linkend="V4L2-PIX-FMT-BGR32">V4L2_PIX_FMT_BGR32</link>   v4l2_fourcc('B', 'G', 'R', '4') /* 32  BGR-8-8-8-8   */
+#define <link linkend="V4L2-PIX-FMT-RGB32">V4L2_PIX_FMT_RGB32</link>   v4l2_fourcc('R', 'G', 'B', '4') /* 32  RGB-8-8-8-8   */
+
+/* Grey formats */
+#define <link linkend="V4L2-PIX-FMT-GREY">V4L2_PIX_FMT_GREY</link>    v4l2_fourcc('G', 'R', 'E', 'Y') /*  8  Greyscale     */
+#define <link linkend="V4L2-PIX-FMT-Y16">V4L2_PIX_FMT_Y16</link>     v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale     */
+
+/* Palette formats */
+#define <link linkend="V4L2-PIX-FMT-PAL8">V4L2_PIX_FMT_PAL8</link>    v4l2_fourcc('P', 'A', 'L', '8') /*  8  8-bit palette */
+
+/* Luminance+Chrominance formats */
+#define <link linkend="V4L2-PIX-FMT-YVU410">V4L2_PIX_FMT_YVU410</link>  v4l2_fourcc('Y', 'V', 'U', '9') /*  9  YVU 4:1:0     */
+#define <link linkend="V4L2-PIX-FMT-YVU420">V4L2_PIX_FMT_YVU420</link>  v4l2_fourcc('Y', 'V', '1', '2') /* 12  YVU 4:2:0     */
+#define <link linkend="V4L2-PIX-FMT-YUYV">V4L2_PIX_FMT_YUYV</link>    v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2     */
+#define <link linkend="V4L2-PIX-FMT-YYUV">V4L2_PIX_FMT_YYUV</link>    v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16  YUV 4:2:2     */
+#define <link linkend="V4L2-PIX-FMT-YVYU">V4L2_PIX_FMT_YVYU</link>    v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
+#define <link linkend="V4L2-PIX-FMT-UYVY">V4L2_PIX_FMT_UYVY</link>    v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16  YUV 4:2:2     */
+#define <link linkend="V4L2-PIX-FMT-VYUY">V4L2_PIX_FMT_VYUY</link>    v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16  YUV 4:2:2     */
+#define <link linkend="V4L2-PIX-FMT-YUV422P">V4L2_PIX_FMT_YUV422P</link> v4l2_fourcc('4', '2', '2', 'P') /* 16  YVU422 planar */
+#define <link linkend="V4L2-PIX-FMT-YUV411P">V4L2_PIX_FMT_YUV411P</link> v4l2_fourcc('4', '1', '1', 'P') /* 16  YVU411 planar */
+#define <link linkend="V4L2-PIX-FMT-Y41P">V4L2_PIX_FMT_Y41P</link>    v4l2_fourcc('Y', '4', '1', 'P') /* 12  YUV 4:1:1     */
+#define <link linkend="V4L2-PIX-FMT-YUV444">V4L2_PIX_FMT_YUV444</link>  v4l2_fourcc('Y', '4', '4', '4') /* 16  xxxxyyyy uuuuvvvv */
+#define <link linkend="V4L2-PIX-FMT-YUV555">V4L2_PIX_FMT_YUV555</link>  v4l2_fourcc('Y', 'U', 'V', 'O') /* 16  YUV-5-5-5     */
+#define <link linkend="V4L2-PIX-FMT-YUV565">V4L2_PIX_FMT_YUV565</link>  v4l2_fourcc('Y', 'U', 'V', 'P') /* 16  YUV-5-6-5     */
+#define <link linkend="V4L2-PIX-FMT-YUV32">V4L2_PIX_FMT_YUV32</link>   v4l2_fourcc('Y', 'U', 'V', '4') /* 32  YUV-8-8-8-8   */
+#define <link linkend="V4L2-PIX-FMT-YUV410">V4L2_PIX_FMT_YUV410</link>  v4l2_fourcc('Y', 'U', 'V', '9') /*  9  YUV 4:1:0     */
+#define <link linkend="V4L2-PIX-FMT-YUV420">V4L2_PIX_FMT_YUV420</link>  v4l2_fourcc('Y', 'U', '1', '2') /* 12  YUV 4:2:0     */
+#define <link linkend="V4L2-PIX-FMT-HI240">V4L2_PIX_FMT_HI240</link>   v4l2_fourcc('H', 'I', '2', '4') /*  8  8-bit color   */
+#define <link linkend="V4L2-PIX-FMT-HM12">V4L2_PIX_FMT_HM12</link>    v4l2_fourcc('H', 'M', '1', '2') /*  8  YUV 4:2:0 16x16 macroblocks */
+
+/* two planes -- one Y, one Cr + Cb interleaved  */
+#define <link linkend="V4L2-PIX-FMT-NV12">V4L2_PIX_FMT_NV12</link>    v4l2_fourcc('N', 'V', '1', '2') /* 12  Y/CbCr 4:2:0  */
+#define <link linkend="V4L2-PIX-FMT-NV21">V4L2_PIX_FMT_NV21</link>    v4l2_fourcc('N', 'V', '2', '1') /* 12  Y/CrCb 4:2:0  */
+#define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link>    v4l2_fourcc('N', 'V', '1', '6') /* 16  Y/CbCr 4:2:2  */
+#define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link>    v4l2_fourcc('N', 'V', '6', '1') /* 16  Y/CrCb 4:2:2  */
+
+/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
+#define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link>  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
+#define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link>  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */
+#define <link linkend="V4L2-PIX-FMT-SGRBG8">V4L2_PIX_FMT_SGRBG8</link>  v4l2_fourcc('G', 'R', 'B', 'G') /*  8  GRGR.. BGBG.. */
+#define <link linkend="V4L2-PIX-FMT-SGRBG10">V4L2_PIX_FMT_SGRBG10</link> v4l2_fourcc('B', 'A', '1', '0') /* 10bit raw bayer */
+        /* 10bit raw bayer DPCM compressed to 8 bits */
+#define <link linkend="V4L2-PIX-FMT-SGRBG10DPCM8">V4L2_PIX_FMT_SGRBG10DPCM8</link> v4l2_fourcc('B', 'D', '1', '0')
+        /*
+         * 10bit raw bayer, expanded to 16 bits
+         * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
+         */
+#define <link linkend="V4L2-PIX-FMT-SBGGR16">V4L2_PIX_FMT_SBGGR16</link> v4l2_fourcc('B', 'Y', 'R', '2') /* 16  BGBG.. GRGR.. */
+
+/* compressed formats */
+#define <link linkend="V4L2-PIX-FMT-MJPEG">V4L2_PIX_FMT_MJPEG</link>    v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG   */
+#define <link linkend="V4L2-PIX-FMT-JPEG">V4L2_PIX_FMT_JPEG</link>     v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG     */
+#define <link linkend="V4L2-PIX-FMT-DV">V4L2_PIX_FMT_DV</link>       v4l2_fourcc('d', 'v', 's', 'd') /* 1394          */
+#define <link linkend="V4L2-PIX-FMT-MPEG">V4L2_PIX_FMT_MPEG</link>     v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4    */
+
+/*  Vendor-specific formats   */
+#define <link linkend="V4L2-PIX-FMT-WNVA">V4L2_PIX_FMT_WNVA</link>     v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
+#define <link linkend="V4L2-PIX-FMT-SN9C10X">V4L2_PIX_FMT_SN9C10X</link>  v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */
+#define <link linkend="V4L2-PIX-FMT-SN9C20X-I420">V4L2_PIX_FMT_SN9C20X_I420</link> v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */
+#define <link linkend="V4L2-PIX-FMT-PWC1">V4L2_PIX_FMT_PWC1</link>     v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */
+#define <link linkend="V4L2-PIX-FMT-PWC2">V4L2_PIX_FMT_PWC2</link>     v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */
+#define <link linkend="V4L2-PIX-FMT-ET61X251">V4L2_PIX_FMT_ET61X251</link> v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */
+#define <link linkend="V4L2-PIX-FMT-SPCA501">V4L2_PIX_FMT_SPCA501</link>  v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */
+#define <link linkend="V4L2-PIX-FMT-SPCA505">V4L2_PIX_FMT_SPCA505</link>  v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */
+#define <link linkend="V4L2-PIX-FMT-SPCA508">V4L2_PIX_FMT_SPCA508</link>  v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */
+#define <link linkend="V4L2-PIX-FMT-SPCA561">V4L2_PIX_FMT_SPCA561</link>  v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */
+#define <link linkend="V4L2-PIX-FMT-PAC207">V4L2_PIX_FMT_PAC207</link>   v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */
+#define <link linkend="V4L2-PIX-FMT-MR97310A">V4L2_PIX_FMT_MR97310A</link> v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
+#define <link linkend="V4L2-PIX-FMT-SQ905C">V4L2_PIX_FMT_SQ905C</link>   v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
+#define <link linkend="V4L2-PIX-FMT-PJPG">V4L2_PIX_FMT_PJPG</link>     v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
+#define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link>    v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
+#define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link>    v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
+#define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link>   v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
+
+/*
+ *      F O R M A T   E N U M E R A T I O N
+ */
+struct <link linkend="v4l2-fmtdesc">v4l2_fmtdesc</link> {
+        __u32               index;             /* Format number      */
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>  type;              /* buffer type        */
+        __u32               flags;
+        __u8                description[32];   /* Description string */
+        __u32               pixelformat;       /* Format fourcc      */
+        __u32               reserved[4];
+};
+
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+#define V4L2_FMT_FLAG_EMULATED   0x0002
+
+#if 1 /*KEEP*/
+        /* Experimental Frame Size and frame rate enumeration */
+/*
+ *      F R A M E   S I Z E   E N U M E R A T I O N
+ */
+enum <link linkend="v4l2-frmsizetypes">v4l2_frmsizetypes</link> {
+        V4L2_FRMSIZE_TYPE_DISCRETE      = 1,
+        V4L2_FRMSIZE_TYPE_CONTINUOUS    = 2,
+        V4L2_FRMSIZE_TYPE_STEPWISE      = 3,
+};
+
+struct <link linkend="v4l2-frmsize-discrete">v4l2_frmsize_discrete</link> {
+        __u32                   width;          /* Frame width [pixel] */
+        __u32                   height;         /* Frame height [pixel] */
+};
+
+struct <link linkend="v4l2-frmsize-stepwise">v4l2_frmsize_stepwise</link> {
+        __u32                   min_width;      /* Minimum frame width [pixel] */
+        __u32                   max_width;      /* Maximum frame width [pixel] */
+        __u32                   step_width;     /* Frame width step size [pixel] */
+        __u32                   min_height;     /* Minimum frame height [pixel] */
+        __u32                   max_height;     /* Maximum frame height [pixel] */
+        __u32                   step_height;    /* Frame height step size [pixel] */
+};
+
+struct <link linkend="v4l2-frmsizeenum">v4l2_frmsizeenum</link> {
+        __u32                   index;          /* Frame size number */
+        __u32                   pixel_format;   /* Pixel format */
+        __u32                   type;           /* Frame size type the device supports. */
+
+        union {                                 /* Frame size */
+                struct <link linkend="v4l2-frmsize-discrete">v4l2_frmsize_discrete</link>    discrete;
+                struct <link linkend="v4l2-frmsize-stepwise">v4l2_frmsize_stepwise</link>    stepwise;
+        };
+
+        __u32   reserved[2];                    /* Reserved space for future use */
+};
+
+/*
+ *      F R A M E   R A T E   E N U M E R A T I O N
+ */
+enum <link linkend="v4l2-frmivaltypes">v4l2_frmivaltypes</link> {
+        V4L2_FRMIVAL_TYPE_DISCRETE      = 1,
+        V4L2_FRMIVAL_TYPE_CONTINUOUS    = 2,
+        V4L2_FRMIVAL_TYPE_STEPWISE      = 3,
+};
+
+struct <link linkend="v4l2-frmival-stepwise">v4l2_frmival_stepwise</link> {
+        struct <link linkend="v4l2-fract">v4l2_fract</link>       min;            /* Minimum frame interval [s] */
+        struct <link linkend="v4l2-fract">v4l2_fract</link>       max;            /* Maximum frame interval [s] */
+        struct <link linkend="v4l2-fract">v4l2_fract</link>       step;           /* Frame interval step size [s] */
+};
+
+struct <link linkend="v4l2-frmivalenum">v4l2_frmivalenum</link> {
+        __u32                   index;          /* Frame format index */
+        __u32                   pixel_format;   /* Pixel format */
+        __u32                   width;          /* Frame width */
+        __u32                   height;         /* Frame height */
+        __u32                   type;           /* Frame interval type the device supports. */
+
+        union {                                 /* Frame interval */
+                struct <link linkend="v4l2-fract">v4l2_fract</link>               discrete;
+                struct <link linkend="v4l2-frmival-stepwise">v4l2_frmival_stepwise</link>    stepwise;
+        };
+
+        __u32   reserved[2];                    /* Reserved space for future use */
+};
+#endif
+
+/*
+ *      T I M E C O D E
+ */
+struct <link linkend="v4l2-timecode">v4l2_timecode</link> {
+        __u32   type;
+        __u32   flags;
+        __u8    frames;
+        __u8    seconds;
+        __u8    minutes;
+        __u8    hours;
+        __u8    userbits[4];
+};
+
+/*  Type  */
+#define V4L2_TC_TYPE_24FPS              1
+#define V4L2_TC_TYPE_25FPS              2
+#define V4L2_TC_TYPE_30FPS              3
+#define V4L2_TC_TYPE_50FPS              4
+#define V4L2_TC_TYPE_60FPS              5
+
+/*  Flags  */
+#define V4L2_TC_FLAG_DROPFRAME          0x0001 /* "drop-frame" mode */
+#define V4L2_TC_FLAG_COLORFRAME         0x0002
+#define V4L2_TC_USERBITS_field          0x000C
+#define V4L2_TC_USERBITS_USERDEFINED    0x0000
+#define V4L2_TC_USERBITS_8BITCHARS      0x0008
+/* The above is based on SMPTE timecodes */
+
+struct <link linkend="v4l2-jpegcompression">v4l2_jpegcompression</link> {
+        int quality;
+
+        int  APPn;              /* Number of APP segment to be written,
+                                 * must be 0..15 */
+        int  APP_len;           /* Length of data in JPEG APPn segment */
+        char APP_data[60];      /* Data in the JPEG APPn segment. */
+
+        int  COM_len;           /* Length of data in JPEG COM segment */
+        char COM_data[60];      /* Data in JPEG COM segment */
+
+        __u32 jpeg_markers;     /* Which markers should go into the JPEG
+                                 * output. Unless you exactly know what
+                                 * you do, leave them untouched.
+                                 * Inluding less markers will make the
+                                 * resulting code smaller, but there will
+                                 * be fewer aplications which can read it.
+                                 * The presence of the APP and COM marker
+                                 * is influenced by APP_len and COM_len
+                                 * ONLY, not by this property! */
+
+#define V4L2_JPEG_MARKER_DHT (1&lt;&lt;3)    /* Define Huffman Tables */
+#define V4L2_JPEG_MARKER_DQT (1&lt;&lt;4)    /* Define Quantization Tables */
+#define V4L2_JPEG_MARKER_DRI (1&lt;&lt;5)    /* Define Restart Interval */
+#define V4L2_JPEG_MARKER_COM (1&lt;&lt;6)    /* Comment segment */
+#define V4L2_JPEG_MARKER_APP (1&lt;&lt;7)    /* App segment, driver will
+                                        * allways use APP0 */
+};
+
+/*
+ *      M E M O R Y - M A P P I N G   B U F F E R S
+ */
+struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> {
+        __u32                   count;
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>      type;
+        enum <link linkend="v4l2-memory">v4l2_memory</link>        memory;
+        __u32                   reserved[2];
+};
+
+struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
+        __u32                   index;
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>      type;
+        __u32                   bytesused;
+        __u32                   flags;
+        enum <link linkend="v4l2-field">v4l2_field</link>         field;
+        struct timeval          timestamp;
+        struct <link linkend="v4l2-timecode">v4l2_timecode</link>    timecode;
+        __u32                   sequence;
+
+        /* memory location */
+        enum <link linkend="v4l2-memory">v4l2_memory</link>        memory;
+        union {
+                __u32           offset;
+                unsigned long   userptr;
+        } m;
+        __u32                   length;
+        __u32                   input;
+        __u32                   reserved;
+};
+
+/*  Flags for 'flags' field */
+#define V4L2_BUF_FLAG_MAPPED    0x0001  /* Buffer is mapped (flag) */
+#define V4L2_BUF_FLAG_QUEUED    0x0002  /* Buffer is queued for processing */
+#define V4L2_BUF_FLAG_DONE      0x0004  /* Buffer is ready */
+#define V4L2_BUF_FLAG_KEYFRAME  0x0008  /* Image is a keyframe (I-frame) */
+#define V4L2_BUF_FLAG_PFRAME    0x0010  /* Image is a P-frame */
+#define V4L2_BUF_FLAG_BFRAME    0x0020  /* Image is a B-frame */
+#define V4L2_BUF_FLAG_TIMECODE  0x0100  /* timecode field is valid */
+#define V4L2_BUF_FLAG_INPUT     0x0200  /* input field is valid */
+
+/*
+ *      O V E R L A Y   P R E V I E W
+ */
+struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link> {
+        __u32                   capability;
+        __u32                   flags;
+/* FIXME: in theory we should pass something like PCI device + memory
+ * region + offset instead of some physical address */
+        void                    *base;
+        struct <link linkend="v4l2-pix-format">v4l2_pix_format</link>  fmt;
+};
+/*  Flags for the 'capability' field. Read only */
+#define V4L2_FBUF_CAP_EXTERNOVERLAY     0x0001
+#define V4L2_FBUF_CAP_CHROMAKEY         0x0002
+#define V4L2_FBUF_CAP_LIST_CLIPPING     0x0004
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING   0x0008
+#define V4L2_FBUF_CAP_LOCAL_ALPHA       0x0010
+#define V4L2_FBUF_CAP_GLOBAL_ALPHA      0x0020
+#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA   0x0040
+/*  Flags for the 'flags' field. */
+#define V4L2_FBUF_FLAG_PRIMARY          0x0001
+#define V4L2_FBUF_FLAG_OVERLAY          0x0002
+#define V4L2_FBUF_FLAG_CHROMAKEY        0x0004
+#define V4L2_FBUF_FLAG_LOCAL_ALPHA      0x0008
+#define V4L2_FBUF_FLAG_GLOBAL_ALPHA     0x0010
+#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA  0x0020
+
+struct <link linkend="v4l2-clip">v4l2_clip</link> {
+        struct <link linkend="v4l2-rect">v4l2_rect</link>        c;
+        struct <link linkend="v4l2-clip">v4l2_clip</link>        __user *next;
+};
+
+struct <link linkend="v4l2-window">v4l2_window</link> {
+        struct <link linkend="v4l2-rect">v4l2_rect</link>        w;
+        enum <link linkend="v4l2-field">v4l2_field</link>         field;
+        __u32                   chromakey;
+        struct <link linkend="v4l2-clip">v4l2_clip</link>        __user *clips;
+        __u32                   clipcount;
+        void                    __user *bitmap;
+        __u8                    global_alpha;
+};
+
+/*
+ *      C A P T U R E   P A R A M E T E R S
+ */
+struct <link linkend="v4l2-captureparm">v4l2_captureparm</link> {
+        __u32              capability;    /*  Supported modes */
+        __u32              capturemode;   /*  Current mode */
+        struct <link linkend="v4l2-fract">v4l2_fract</link>  timeperframe;  /*  Time per frame in .1us units */
+        __u32              extendedmode;  /*  Driver-specific extensions */
+        __u32              readbuffers;   /*  # of buffers for read */
+        __u32              reserved[4];
+};
+
+/*  Flags for 'capability' and 'capturemode' fields */
+#define V4L2_MODE_HIGHQUALITY   0x0001  /*  High quality imaging mode */
+#define V4L2_CAP_TIMEPERFRAME   0x1000  /*  timeperframe field is supported */
+
+struct <link linkend="v4l2-outputparm">v4l2_outputparm</link> {
+        __u32              capability;   /*  Supported modes */
+        __u32              outputmode;   /*  Current mode */
+        struct <link linkend="v4l2-fract">v4l2_fract</link>  timeperframe; /*  Time per frame in seconds */
+        __u32              extendedmode; /*  Driver-specific extensions */
+        __u32              writebuffers; /*  # of buffers for write */
+        __u32              reserved[4];
+};
+
+/*
+ *      I N P U T   I M A G E   C R O P P I N G
+ */
+struct <link linkend="v4l2-cropcap">v4l2_cropcap</link> {
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>      type;
+        struct <link linkend="v4l2-rect">v4l2_rect</link>        bounds;
+        struct <link linkend="v4l2-rect">v4l2_rect</link>        defrect;
+        struct <link linkend="v4l2-fract">v4l2_fract</link>       pixelaspect;
+};
+
+struct <link linkend="v4l2-crop">v4l2_crop</link> {
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>      type;
+        struct <link linkend="v4l2-rect">v4l2_rect</link>        c;
+};
+
+/*
+ *      A N A L O G   V I D E O   S T A N D A R D
+ */
+
+typedef __u64 v4l2_std_id;
+
+/* one bit for each */
+#define V4L2_STD_PAL_B          ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1         ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G          ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H          ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I          ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D          ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1         ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K          ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M          ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N          ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc         ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60         ((v4l2_std_id)0x00000800)
+
+#define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
+#define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
+#define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)
+
+#define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G        ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H        ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K        ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1       ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L        ((v4l2_std_id)0x00400000)
+#define V4L2_STD_SECAM_LC       ((v4l2_std_id)0x00800000)
+
+/* ATSC/HDTV */
+#define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)
+
+/* FIXME:
+   Although std_id is 64 bits, there is an issue on PPC32 architecture that
+   makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding
+   this value to 32 bits.
+   As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide),
+   it should work fine. However, if needed to add more than two standards,
+   v4l2-common.c should be fixed.
+ */
+
+/* some merged standards */
+#define V4L2_STD_MN     (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
+#define V4L2_STD_B      (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
+#define V4L2_STD_GH     (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
+#define V4L2_STD_DK     (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
+
+/* some common needed stuff */
+#define V4L2_STD_PAL_BG         (V4L2_STD_PAL_B         |\
+                                 V4L2_STD_PAL_B1        |\
+                                 V4L2_STD_PAL_G)
+#define V4L2_STD_PAL_DK         (V4L2_STD_PAL_D         |\
+                                 V4L2_STD_PAL_D1        |\
+                                 V4L2_STD_PAL_K)
+#define V4L2_STD_PAL            (V4L2_STD_PAL_BG        |\
+                                 V4L2_STD_PAL_DK        |\
+                                 V4L2_STD_PAL_H         |\
+                                 V4L2_STD_PAL_I)
+#define V4L2_STD_NTSC           (V4L2_STD_NTSC_M        |\
+                                 V4L2_STD_NTSC_M_JP     |\
+                                 V4L2_STD_NTSC_M_KR)
+#define V4L2_STD_SECAM_DK       (V4L2_STD_SECAM_D       |\
+                                 V4L2_STD_SECAM_K       |\
+                                 V4L2_STD_SECAM_K1)
+#define V4L2_STD_SECAM          (V4L2_STD_SECAM_B       |\
+                                 V4L2_STD_SECAM_G       |\
+                                 V4L2_STD_SECAM_H       |\
+                                 V4L2_STD_SECAM_DK      |\
+                                 V4L2_STD_SECAM_L       |\
+                                 V4L2_STD_SECAM_LC)
+
+#define V4L2_STD_525_60         (V4L2_STD_PAL_M         |\
+                                 V4L2_STD_PAL_60        |\
+                                 V4L2_STD_NTSC          |\
+                                 V4L2_STD_NTSC_443)
+#define V4L2_STD_625_50         (V4L2_STD_PAL           |\
+                                 V4L2_STD_PAL_N         |\
+                                 V4L2_STD_PAL_Nc        |\
+                                 V4L2_STD_SECAM)
+#define V4L2_STD_ATSC           (V4L2_STD_ATSC_8_VSB    |\
+                                 V4L2_STD_ATSC_16_VSB)
+
+#define V4L2_STD_UNKNOWN        0
+#define V4L2_STD_ALL            (V4L2_STD_525_60        |\
+                                 V4L2_STD_625_50)
+
+struct <link linkend="v4l2-standard">v4l2_standard</link> {
+        __u32                index;
+        v4l2_std_id          id;
+        __u8                 name[24];
+        struct <link linkend="v4l2-fract">v4l2_fract</link>    frameperiod; /* Frames, not fields */
+        __u32                framelines;
+        __u32                reserved[4];
+};
+
+/*
+ *      V I D E O   I N P U T S
+ */
+struct <link linkend="v4l2-input">v4l2_input</link> {
+        __u32        index;             /*  Which input */
+        __u8         name[32];          /*  Label */
+        __u32        type;              /*  Type of input */
+        __u32        audioset;          /*  Associated audios (bitfield) */
+        __u32        tuner;             /*  Associated tuner */
+        v4l2_std_id  std;
+        __u32        status;
+        __u32        reserved[4];
+};
+
+/*  Values for the 'type' field */
+#define V4L2_INPUT_TYPE_TUNER           1
+#define V4L2_INPUT_TYPE_CAMERA          2
+
+/* field 'status' - general */
+#define V4L2_IN_ST_NO_POWER    0x00000001  /* Attached device is off */
+#define V4L2_IN_ST_NO_SIGNAL   0x00000002
+#define V4L2_IN_ST_NO_COLOR    0x00000004
+
+/* field 'status' - sensor orientation */
+/* If sensor is mounted upside down set both bits */
+#define V4L2_IN_ST_HFLIP       0x00000010 /* Frames are flipped horizontally */
+#define V4L2_IN_ST_VFLIP       0x00000020 /* Frames are flipped vertically */
+
+/* field 'status' - analog */
+#define V4L2_IN_ST_NO_H_LOCK   0x00000100  /* No horizontal sync lock */
+#define V4L2_IN_ST_COLOR_KILL  0x00000200  /* Color killer is active */
+
+/* field 'status' - digital */
+#define V4L2_IN_ST_NO_SYNC     0x00010000  /* No synchronization lock */
+#define V4L2_IN_ST_NO_EQU      0x00020000  /* No equalizer lock */
+#define V4L2_IN_ST_NO_CARRIER  0x00040000  /* Carrier recovery failed */
+
+/* field 'status' - VCR and set-top box */
+#define V4L2_IN_ST_MACROVISION 0x01000000  /* Macrovision detected */
+#define V4L2_IN_ST_NO_ACCESS   0x02000000  /* Conditional access denied */
+#define V4L2_IN_ST_VTR         0x04000000  /* VTR time constant */
+
+/*
+ *      V I D E O   O U T P U T S
+ */
+struct <link linkend="v4l2-output">v4l2_output</link> {
+        __u32        index;             /*  Which output */
+        __u8         name[32];          /*  Label */
+        __u32        type;              /*  Type of output */
+        __u32        audioset;          /*  Associated audios (bitfield) */
+        __u32        modulator;         /*  Associated modulator */
+        v4l2_std_id  std;
+        __u32        reserved[4];
+};
+/*  Values for the 'type' field */
+#define V4L2_OUTPUT_TYPE_MODULATOR              1
+#define V4L2_OUTPUT_TYPE_ANALOG                 2
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY       3
+
+/*
+ *      C O N T R O L S
+ */
+struct <link linkend="v4l2-control">v4l2_control</link> {
+        __u32                id;
+        __s32                value;
+};
+
+struct <link linkend="v4l2-ext-control">v4l2_ext_control</link> {
+        __u32 id;
+        __u32 size;
+        __u32 reserved2[1];
+        union {
+                __s32 value;
+                __s64 value64;
+                char *string;
+        };
+} __attribute__ ((packed));
+
+struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link> {
+        __u32 ctrl_class;
+        __u32 count;
+        __u32 error_idx;
+        __u32 reserved[2];
+        struct <link linkend="v4l2-ext-control">v4l2_ext_control</link> *controls;
+};
+
+/*  Values for ctrl_class field */
+#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
+#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
+#define V4L2_CTRL_CLASS_CAMERA 0x009a0000       /* Camera class controls */
+#define V4L2_CTRL_CLASS_FM_TX 0x009b0000        /* FM Modulator control class */
+
+#define V4L2_CTRL_ID_MASK         (0x0fffffff)
+#define V4L2_CTRL_ID2CLASS(id)    ((id) &amp; 0x0fff0000UL)
+#define V4L2_CTRL_DRIVER_PRIV(id) (((id) &amp; 0xffff) &gt;= 0x1000)
+
+/*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
+struct <link linkend="v4l2-queryctrl">v4l2_queryctrl</link> {
+        __u32                id;
+        enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link>  type;
+        __u8                 name[32];  /* Whatever */
+        __s32                minimum;   /* Note signedness */
+        __s32                maximum;
+        __s32                step;
+        __s32                default_value;
+        __u32                flags;
+        __u32                reserved[2];
+};
+
+/*  Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
+struct <link linkend="v4l2-querymenu">v4l2_querymenu</link> {
+        __u32           id;
+        __u32           index;
+        __u8            name[32];       /* Whatever */
+        __u32           reserved;
+};
+
+/*  Control flags  */
+#define V4L2_CTRL_FLAG_DISABLED         0x0001
+#define V4L2_CTRL_FLAG_GRABBED          0x0002
+#define V4L2_CTRL_FLAG_READ_ONLY        0x0004
+#define V4L2_CTRL_FLAG_UPDATE           0x0008
+#define V4L2_CTRL_FLAG_INACTIVE         0x0010
+#define V4L2_CTRL_FLAG_SLIDER           0x0020
+#define V4L2_CTRL_FLAG_WRITE_ONLY       0x0040
+
+/*  Query flag, to be ORed with the control ID */
+#define V4L2_CTRL_FLAG_NEXT_CTRL        0x80000000
+
+/*  User-class control IDs defined by V4L2 */
+#define V4L2_CID_BASE                   (V4L2_CTRL_CLASS_USER | 0x900)
+#define V4L2_CID_USER_BASE              V4L2_CID_BASE
+/*  IDs reserved for driver specific controls */
+#define V4L2_CID_PRIVATE_BASE           0x08000000
+
+#define V4L2_CID_USER_CLASS             (V4L2_CTRL_CLASS_USER | 1)
+#define V4L2_CID_BRIGHTNESS             (V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST               (V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION             (V4L2_CID_BASE+2)
+#define V4L2_CID_HUE                    (V4L2_CID_BASE+3)
+#define V4L2_CID_AUDIO_VOLUME           (V4L2_CID_BASE+5)
+#define V4L2_CID_AUDIO_BALANCE          (V4L2_CID_BASE+6)
+#define V4L2_CID_AUDIO_BASS             (V4L2_CID_BASE+7)
+#define V4L2_CID_AUDIO_TREBLE           (V4L2_CID_BASE+8)
+#define V4L2_CID_AUDIO_MUTE             (V4L2_CID_BASE+9)
+#define V4L2_CID_AUDIO_LOUDNESS         (V4L2_CID_BASE+10)
+#define V4L2_CID_BLACK_LEVEL            (V4L2_CID_BASE+11) /* Deprecated */
+#define V4L2_CID_AUTO_WHITE_BALANCE     (V4L2_CID_BASE+12)
+#define V4L2_CID_DO_WHITE_BALANCE       (V4L2_CID_BASE+13)
+#define V4L2_CID_RED_BALANCE            (V4L2_CID_BASE+14)
+#define V4L2_CID_BLUE_BALANCE           (V4L2_CID_BASE+15)
+#define V4L2_CID_GAMMA                  (V4L2_CID_BASE+16)
+#define V4L2_CID_WHITENESS              (V4L2_CID_GAMMA) /* Deprecated */
+#define V4L2_CID_EXPOSURE               (V4L2_CID_BASE+17)
+#define V4L2_CID_AUTOGAIN               (V4L2_CID_BASE+18)
+#define V4L2_CID_GAIN                   (V4L2_CID_BASE+19)
+#define V4L2_CID_HFLIP                  (V4L2_CID_BASE+20)
+#define V4L2_CID_VFLIP                  (V4L2_CID_BASE+21)
+
+/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */
+#define V4L2_CID_HCENTER                (V4L2_CID_BASE+22)
+#define V4L2_CID_VCENTER                (V4L2_CID_BASE+23)
+
+#define V4L2_CID_POWER_LINE_FREQUENCY   (V4L2_CID_BASE+24)
+enum <link linkend="v4l2-power-line-frequency">v4l2_power_line_frequency</link> {
+        V4L2_CID_POWER_LINE_FREQUENCY_DISABLED  = 0,
+        V4L2_CID_POWER_LINE_FREQUENCY_50HZ      = 1,
+        V4L2_CID_POWER_LINE_FREQUENCY_60HZ      = 2,
+};
+#define V4L2_CID_HUE_AUTO                       (V4L2_CID_BASE+25)
+#define V4L2_CID_WHITE_BALANCE_TEMPERATURE      (V4L2_CID_BASE+26)
+#define V4L2_CID_SHARPNESS                      (V4L2_CID_BASE+27)
+#define V4L2_CID_BACKLIGHT_COMPENSATION         (V4L2_CID_BASE+28)
+#define V4L2_CID_CHROMA_AGC                     (V4L2_CID_BASE+29)
+#define V4L2_CID_COLOR_KILLER                   (V4L2_CID_BASE+30)
+#define V4L2_CID_COLORFX                        (V4L2_CID_BASE+31)
+enum <link linkend="v4l2-colorfx">v4l2_colorfx</link> {
+        V4L2_COLORFX_NONE       = 0,
+        V4L2_COLORFX_BW         = 1,
+        V4L2_COLORFX_SEPIA      = 2,
+};
+#define V4L2_CID_AUTOBRIGHTNESS                 (V4L2_CID_BASE+32)
+#define V4L2_CID_BAND_STOP_FILTER               (V4L2_CID_BASE+33)
+
+/* last CID + 1 */
+#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+34)
+
+/*  MPEG-class control IDs defined by V4L2 */
+#define V4L2_CID_MPEG_BASE                      (V4L2_CTRL_CLASS_MPEG | 0x900)
+#define V4L2_CID_MPEG_CLASS                     (V4L2_CTRL_CLASS_MPEG | 1)
+
+/*  MPEG streams */
+#define V4L2_CID_MPEG_STREAM_TYPE               (V4L2_CID_MPEG_BASE+0)
+enum <link linkend="v4l2-mpeg-stream-type">v4l2_mpeg_stream_type</link> {
+        V4L2_MPEG_STREAM_TYPE_MPEG2_PS   = 0, /* MPEG-2 program stream */
+        V4L2_MPEG_STREAM_TYPE_MPEG2_TS   = 1, /* MPEG-2 transport stream */
+        V4L2_MPEG_STREAM_TYPE_MPEG1_SS   = 2, /* MPEG-1 system stream */
+        V4L2_MPEG_STREAM_TYPE_MPEG2_DVD  = 3, /* MPEG-2 DVD-compatible stream */
+        V4L2_MPEG_STREAM_TYPE_MPEG1_VCD  = 4, /* MPEG-1 VCD-compatible stream */
+        V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
+};
+#define V4L2_CID_MPEG_STREAM_PID_PMT            (V4L2_CID_MPEG_BASE+1)
+#define V4L2_CID_MPEG_STREAM_PID_AUDIO          (V4L2_CID_MPEG_BASE+2)
+#define V4L2_CID_MPEG_STREAM_PID_VIDEO          (V4L2_CID_MPEG_BASE+3)
+#define V4L2_CID_MPEG_STREAM_PID_PCR            (V4L2_CID_MPEG_BASE+4)
+#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO       (V4L2_CID_MPEG_BASE+5)
+#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO       (V4L2_CID_MPEG_BASE+6)
+#define V4L2_CID_MPEG_STREAM_VBI_FMT            (V4L2_CID_MPEG_BASE+7)
+enum <link linkend="v4l2-mpeg-stream-vbi-fmt">v4l2_mpeg_stream_vbi_fmt</link> {
+        V4L2_MPEG_STREAM_VBI_FMT_NONE = 0,  /* No VBI in the MPEG stream */
+        V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1,  /* VBI in private packets, IVTV format */
+};
+
+/*  MPEG audio */
+#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ       (V4L2_CID_MPEG_BASE+100)
+enum <link linkend="v4l2-mpeg-audio-sampling-freq">v4l2_mpeg_audio_sampling_freq</link> {
+        V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
+        V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
+        V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_ENCODING            (V4L2_CID_MPEG_BASE+101)
+enum <link linkend="v4l2-mpeg-audio-encoding">v4l2_mpeg_audio_encoding</link> {
+        V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
+        V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
+        V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
+        V4L2_MPEG_AUDIO_ENCODING_AAC     = 3,
+        V4L2_MPEG_AUDIO_ENCODING_AC3     = 4,
+};
+#define V4L2_CID_MPEG_AUDIO_L1_BITRATE          (V4L2_CID_MPEG_BASE+102)
+enum <link linkend="v4l2-mpeg-audio-l1-bitrate">v4l2_mpeg_audio_l1_bitrate</link> {
+        V4L2_MPEG_AUDIO_L1_BITRATE_32K  = 0,
+        V4L2_MPEG_AUDIO_L1_BITRATE_64K  = 1,
+        V4L2_MPEG_AUDIO_L1_BITRATE_96K  = 2,
+        V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3,
+        V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4,
+        V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5,
+        V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6,
+        V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7,
+        V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8,
+        V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9,
+        V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10,
+        V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11,
+        V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
+        V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L2_BITRATE          (V4L2_CID_MPEG_BASE+103)
+enum <link linkend="v4l2-mpeg-audio-l2-bitrate">v4l2_mpeg_audio_l2_bitrate</link> {
+        V4L2_MPEG_AUDIO_L2_BITRATE_32K  = 0,
+        V4L2_MPEG_AUDIO_L2_BITRATE_48K  = 1,
+        V4L2_MPEG_AUDIO_L2_BITRATE_56K  = 2,
+        V4L2_MPEG_AUDIO_L2_BITRATE_64K  = 3,
+        V4L2_MPEG_AUDIO_L2_BITRATE_80K  = 4,
+        V4L2_MPEG_AUDIO_L2_BITRATE_96K  = 5,
+        V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6,
+        V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7,
+        V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8,
+        V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9,
+        V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10,
+        V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11,
+        V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
+        V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L3_BITRATE          (V4L2_CID_MPEG_BASE+104)
+enum <link linkend="v4l2-mpeg-audio-l3-bitrate">v4l2_mpeg_audio_l3_bitrate</link> {
+        V4L2_MPEG_AUDIO_L3_BITRATE_32K  = 0,
+        V4L2_MPEG_AUDIO_L3_BITRATE_40K  = 1,
+        V4L2_MPEG_AUDIO_L3_BITRATE_48K  = 2,
+        V4L2_MPEG_AUDIO_L3_BITRATE_56K  = 3,
+        V4L2_MPEG_AUDIO_L3_BITRATE_64K  = 4,
+        V4L2_MPEG_AUDIO_L3_BITRATE_80K  = 5,
+        V4L2_MPEG_AUDIO_L3_BITRATE_96K  = 6,
+        V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7,
+        V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8,
+        V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9,
+        V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10,
+        V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11,
+        V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
+        V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE                (V4L2_CID_MPEG_BASE+105)
+enum <link linkend="v4l2-mpeg-audio-mode">v4l2_mpeg_audio_mode</link> {
+        V4L2_MPEG_AUDIO_MODE_STEREO       = 0,
+        V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
+        V4L2_MPEG_AUDIO_MODE_DUAL         = 2,
+        V4L2_MPEG_AUDIO_MODE_MONO         = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION      (V4L2_CID_MPEG_BASE+106)
+enum <link linkend="v4l2-mpeg-audio-mode-extension">v4l2_mpeg_audio_mode_extension</link> {
+        V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4  = 0,
+        V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8  = 1,
+        V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
+        V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_EMPHASIS            (V4L2_CID_MPEG_BASE+107)
+enum <link linkend="v4l2-mpeg-audio-emphasis">v4l2_mpeg_audio_emphasis</link> {
+        V4L2_MPEG_AUDIO_EMPHASIS_NONE         = 0,
+        V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
+        V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17    = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_CRC                 (V4L2_CID_MPEG_BASE+108)
+enum <link linkend="v4l2-mpeg-audio-crc">v4l2_mpeg_audio_crc</link> {
+        V4L2_MPEG_AUDIO_CRC_NONE  = 0,
+        V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
+};
+#define V4L2_CID_MPEG_AUDIO_MUTE                (V4L2_CID_MPEG_BASE+109)
+#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE         (V4L2_CID_MPEG_BASE+110)
+#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE         (V4L2_CID_MPEG_BASE+111)
+enum <link linkend="v4l2-mpeg-audio-ac3-bitrate">v4l2_mpeg_audio_ac3_bitrate</link> {
+        V4L2_MPEG_AUDIO_AC3_BITRATE_32K  = 0,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_40K  = 1,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_48K  = 2,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_56K  = 3,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_64K  = 4,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_80K  = 5,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_96K  = 6,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17,
+        V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
+};
+
+/*  MPEG video */
+#define V4L2_CID_MPEG_VIDEO_ENCODING            (V4L2_CID_MPEG_BASE+200)
+enum <link linkend="v4l2-mpeg-video-encoding">v4l2_mpeg_video_encoding</link> {
+        V4L2_MPEG_VIDEO_ENCODING_MPEG_1     = 0,
+        V4L2_MPEG_VIDEO_ENCODING_MPEG_2     = 1,
+        V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2,
+};
+#define V4L2_CID_MPEG_VIDEO_ASPECT              (V4L2_CID_MPEG_BASE+201)
+enum <link linkend="v4l2-mpeg-video-aspect">v4l2_mpeg_video_aspect</link> {
+        V4L2_MPEG_VIDEO_ASPECT_1x1     = 0,
+        V4L2_MPEG_VIDEO_ASPECT_4x3     = 1,
+        V4L2_MPEG_VIDEO_ASPECT_16x9    = 2,
+        V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
+};
+#define V4L2_CID_MPEG_VIDEO_B_FRAMES            (V4L2_CID_MPEG_BASE+202)
+#define V4L2_CID_MPEG_VIDEO_GOP_SIZE            (V4L2_CID_MPEG_BASE+203)
+#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE         (V4L2_CID_MPEG_BASE+204)
+#define V4L2_CID_MPEG_VIDEO_PULLDOWN            (V4L2_CID_MPEG_BASE+205)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE        (V4L2_CID_MPEG_BASE+206)
+enum <link linkend="v4l2-mpeg-video-bitrate-mode">v4l2_mpeg_video_bitrate_mode</link> {
+        V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
+        V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_BITRATE             (V4L2_CID_MPEG_BASE+207)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK        (V4L2_CID_MPEG_BASE+208)
+#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
+#define V4L2_CID_MPEG_VIDEO_MUTE                (V4L2_CID_MPEG_BASE+210)
+#define V4L2_CID_MPEG_VIDEO_MUTE_YUV            (V4L2_CID_MPEG_BASE+211)
+
+/*  MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
+#define V4L2_CID_MPEG_CX2341X_BASE                              (V4L2_CTRL_CLASS_MPEG | 0x1000)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE         (V4L2_CID_MPEG_CX2341X_BASE+0)
+enum <link linkend="v4l2-mpeg-cx2341x-video-spatial-filter-mode">v4l2_mpeg_cx2341x_video_spatial_filter_mode</link> {
+        V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
+        V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO   = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER              (V4L2_CID_MPEG_CX2341X_BASE+1)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE    (V4L2_CID_MPEG_CX2341X_BASE+2)
+enum <link linkend="luma-spatial-filter-type">v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link> {
+        V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF                  = 0,
+        V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR               = 1,
+        V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT              = 2,
+        V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE      = 3,
+        V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE  (V4L2_CID_MPEG_CX2341X_BASE+3)
+enum <link linkend="chroma-spatial-filter-type">v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link> {
+        V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF    = 0,
+        V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE        (V4L2_CID_MPEG_CX2341X_BASE+4)
+enum <link linkend="v4l2-mpeg-cx2341x-video-temporal-filter-mode">v4l2_mpeg_cx2341x_video_temporal_filter_mode</link> {
+        V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
+        V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO   = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER             (V4L2_CID_MPEG_CX2341X_BASE+5)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE          (V4L2_CID_MPEG_CX2341X_BASE+6)
+enum <link linkend="v4l2-mpeg-cx2341x-video-median-filter-type">v4l2_mpeg_cx2341x_video_median_filter_type</link> {
+        V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF      = 0,
+        V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR      = 1,
+        V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT     = 2,
+        V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
+        V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG     = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM   (V4L2_CID_MPEG_CX2341X_BASE+7)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP      (V4L2_CID_MPEG_CX2341X_BASE+8)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP    (V4L2_CID_MPEG_CX2341X_BASE+10)
+#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS         (V4L2_CID_MPEG_CX2341X_BASE+11)
+
+/*  Camera class control IDs */
+#define V4L2_CID_CAMERA_CLASS_BASE      (V4L2_CTRL_CLASS_CAMERA | 0x900)
+#define V4L2_CID_CAMERA_CLASS           (V4L2_CTRL_CLASS_CAMERA | 1)
+
+#define V4L2_CID_EXPOSURE_AUTO                  (V4L2_CID_CAMERA_CLASS_BASE+1)
+enum  <link linkend="v4l2-exposure-auto-type">v4l2_exposure_auto_type</link> {
+        V4L2_EXPOSURE_AUTO = 0,
+        V4L2_EXPOSURE_MANUAL = 1,
+        V4L2_EXPOSURE_SHUTTER_PRIORITY = 2,
+        V4L2_EXPOSURE_APERTURE_PRIORITY = 3
+};
+#define V4L2_CID_EXPOSURE_ABSOLUTE              (V4L2_CID_CAMERA_CLASS_BASE+2)
+#define V4L2_CID_EXPOSURE_AUTO_PRIORITY         (V4L2_CID_CAMERA_CLASS_BASE+3)
+
+#define V4L2_CID_PAN_RELATIVE                   (V4L2_CID_CAMERA_CLASS_BASE+4)
+#define V4L2_CID_TILT_RELATIVE                  (V4L2_CID_CAMERA_CLASS_BASE+5)
+#define V4L2_CID_PAN_RESET                      (V4L2_CID_CAMERA_CLASS_BASE+6)
+#define V4L2_CID_TILT_RESET                     (V4L2_CID_CAMERA_CLASS_BASE+7)
+
+#define V4L2_CID_PAN_ABSOLUTE                   (V4L2_CID_CAMERA_CLASS_BASE+8)
+#define V4L2_CID_TILT_ABSOLUTE                  (V4L2_CID_CAMERA_CLASS_BASE+9)
+
+#define V4L2_CID_FOCUS_ABSOLUTE                 (V4L2_CID_CAMERA_CLASS_BASE+10)
+#define V4L2_CID_FOCUS_RELATIVE                 (V4L2_CID_CAMERA_CLASS_BASE+11)
+#define V4L2_CID_FOCUS_AUTO                     (V4L2_CID_CAMERA_CLASS_BASE+12)
+
+#define V4L2_CID_ZOOM_ABSOLUTE                  (V4L2_CID_CAMERA_CLASS_BASE+13)
+#define V4L2_CID_ZOOM_RELATIVE                  (V4L2_CID_CAMERA_CLASS_BASE+14)
+#define V4L2_CID_ZOOM_CONTINUOUS                (V4L2_CID_CAMERA_CLASS_BASE+15)
+
+#define V4L2_CID_PRIVACY                        (V4L2_CID_CAMERA_CLASS_BASE+16)
+
+/* FM Modulator class control IDs */
+#define V4L2_CID_FM_TX_CLASS_BASE               (V4L2_CTRL_CLASS_FM_TX | 0x900)
+#define V4L2_CID_FM_TX_CLASS                    (V4L2_CTRL_CLASS_FM_TX | 1)
+
+#define V4L2_CID_RDS_TX_DEVIATION               (V4L2_CID_FM_TX_CLASS_BASE + 1)
+#define V4L2_CID_RDS_TX_PI                      (V4L2_CID_FM_TX_CLASS_BASE + 2)
+#define V4L2_CID_RDS_TX_PTY                     (V4L2_CID_FM_TX_CLASS_BASE + 3)
+#define V4L2_CID_RDS_TX_PS_NAME                 (V4L2_CID_FM_TX_CLASS_BASE + 5)
+#define V4L2_CID_RDS_TX_RADIO_TEXT              (V4L2_CID_FM_TX_CLASS_BASE + 6)
+
+#define V4L2_CID_AUDIO_LIMITER_ENABLED          (V4L2_CID_FM_TX_CLASS_BASE + 64)
+#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME     (V4L2_CID_FM_TX_CLASS_BASE + 65)
+#define V4L2_CID_AUDIO_LIMITER_DEVIATION        (V4L2_CID_FM_TX_CLASS_BASE + 66)
+
+#define V4L2_CID_AUDIO_COMPRESSION_ENABLED      (V4L2_CID_FM_TX_CLASS_BASE + 80)
+#define V4L2_CID_AUDIO_COMPRESSION_GAIN         (V4L2_CID_FM_TX_CLASS_BASE + 81)
+#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD    (V4L2_CID_FM_TX_CLASS_BASE + 82)
+#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME  (V4L2_CID_FM_TX_CLASS_BASE + 83)
+#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84)
+
+#define V4L2_CID_PILOT_TONE_ENABLED             (V4L2_CID_FM_TX_CLASS_BASE + 96)
+#define V4L2_CID_PILOT_TONE_DEVIATION           (V4L2_CID_FM_TX_CLASS_BASE + 97)
+#define V4L2_CID_PILOT_TONE_FREQUENCY           (V4L2_CID_FM_TX_CLASS_BASE + 98)
+
+#define V4L2_CID_TUNE_PREEMPHASIS               (V4L2_CID_FM_TX_CLASS_BASE + 112)
+enum <link linkend="v4l2-preemphasis">v4l2_preemphasis</link> {
+        V4L2_PREEMPHASIS_DISABLED       = 0,
+        V4L2_PREEMPHASIS_50_uS          = 1,
+        V4L2_PREEMPHASIS_75_uS          = 2,
+};
+#define V4L2_CID_TUNE_POWER_LEVEL               (V4L2_CID_FM_TX_CLASS_BASE + 113)
+#define V4L2_CID_TUNE_ANTENNA_CAPACITOR         (V4L2_CID_FM_TX_CLASS_BASE + 114)
+
+/*
+ *      T U N I N G
+ */
+struct <link linkend="v4l2-tuner">v4l2_tuner</link> {
+        __u32                   index;
+        __u8                    name[32];
+        enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link>    type;
+        __u32                   capability;
+        __u32                   rangelow;
+        __u32                   rangehigh;
+        __u32                   rxsubchans;
+        __u32                   audmode;
+        __s32                   signal;
+        __s32                   afc;
+        __u32                   reserved[4];
+};
+
+struct <link linkend="v4l2-modulator">v4l2_modulator</link> {
+        __u32                   index;
+        __u8                    name[32];
+        __u32                   capability;
+        __u32                   rangelow;
+        __u32                   rangehigh;
+        __u32                   txsubchans;
+        __u32                   reserved[4];
+};
+
+/*  Flags for the 'capability' field */
+#define V4L2_TUNER_CAP_LOW              0x0001
+#define V4L2_TUNER_CAP_NORM             0x0002
+#define V4L2_TUNER_CAP_STEREO           0x0010
+#define V4L2_TUNER_CAP_LANG2            0x0020
+#define V4L2_TUNER_CAP_SAP              0x0020
+#define V4L2_TUNER_CAP_LANG1            0x0040
+#define V4L2_TUNER_CAP_RDS              0x0080
+
+/*  Flags for the 'rxsubchans' field */
+#define V4L2_TUNER_SUB_MONO             0x0001
+#define V4L2_TUNER_SUB_STEREO           0x0002
+#define V4L2_TUNER_SUB_LANG2            0x0004
+#define V4L2_TUNER_SUB_SAP              0x0004
+#define V4L2_TUNER_SUB_LANG1            0x0008
+#define V4L2_TUNER_SUB_RDS              0x0010
+
+/*  Values for the 'audmode' field */
+#define V4L2_TUNER_MODE_MONO            0x0000
+#define V4L2_TUNER_MODE_STEREO          0x0001
+#define V4L2_TUNER_MODE_LANG2           0x0002
+#define V4L2_TUNER_MODE_SAP             0x0002
+#define V4L2_TUNER_MODE_LANG1           0x0003
+#define V4L2_TUNER_MODE_LANG1_LANG2     0x0004
+
+struct <link linkend="v4l2-frequency">v4l2_frequency</link> {
+        __u32                 tuner;
+        enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link>  type;
+        __u32                 frequency;
+        __u32                 reserved[8];
+};
+
+struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link> {
+        __u32                 tuner;
+        enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link>  type;
+        __u32                 seek_upward;
+        __u32                 wrap_around;
+        __u32                 reserved[8];
+};
+
+/*
+ *      R D S
+ */
+
+struct <link linkend="v4l2-rds-data">v4l2_rds_data</link> {
+        __u8    lsb;
+        __u8    msb;
+        __u8    block;
+} __attribute__ ((packed));
+
+#define V4L2_RDS_BLOCK_MSK       0x7
+#define V4L2_RDS_BLOCK_A         0
+#define V4L2_RDS_BLOCK_B         1
+#define V4L2_RDS_BLOCK_C         2
+#define V4L2_RDS_BLOCK_D         3
+#define V4L2_RDS_BLOCK_C_ALT     4
+#define V4L2_RDS_BLOCK_INVALID   7
+
+#define V4L2_RDS_BLOCK_CORRECTED 0x40
+#define V4L2_RDS_BLOCK_ERROR     0x80
+
+/*
+ *      A U D I O
+ */
+struct <link linkend="v4l2-audio">v4l2_audio</link> {
+        __u32   index;
+        __u8    name[32];
+        __u32   capability;
+        __u32   mode;
+        __u32   reserved[2];
+};
+
+/*  Flags for the 'capability' field */
+#define V4L2_AUDCAP_STEREO              0x00001
+#define V4L2_AUDCAP_AVL                 0x00002
+
+/*  Flags for the 'mode' field */
+#define V4L2_AUDMODE_AVL                0x00001
+
+struct <link linkend="v4l2-audioout">v4l2_audioout</link> {
+        __u32   index;
+        __u8    name[32];
+        __u32   capability;
+        __u32   mode;
+        __u32   reserved[2];
+};
+
+/*
+ *      M P E G   S E R V I C E S
+ *
+ *      NOTE: EXPERIMENTAL API
+ */
+#if 1 /*KEEP*/
+#define V4L2_ENC_IDX_FRAME_I    (0)
+#define V4L2_ENC_IDX_FRAME_P    (1)
+#define V4L2_ENC_IDX_FRAME_B    (2)
+#define V4L2_ENC_IDX_FRAME_MASK (0xf)
+
+struct <link linkend="v4l2-enc-idx-entry">v4l2_enc_idx_entry</link> {
+        __u64 offset;
+        __u64 pts;
+        __u32 length;
+        __u32 flags;
+        __u32 reserved[2];
+};
+
+#define V4L2_ENC_IDX_ENTRIES (64)
+struct <link linkend="v4l2-enc-idx">v4l2_enc_idx</link> {
+        __u32 entries;
+        __u32 entries_cap;
+        __u32 reserved[4];
+        struct <link linkend="v4l2-enc-idx-entry">v4l2_enc_idx_entry</link> entry[V4L2_ENC_IDX_ENTRIES];
+};
+
+
+#define V4L2_ENC_CMD_START      (0)
+#define V4L2_ENC_CMD_STOP       (1)
+#define V4L2_ENC_CMD_PAUSE      (2)
+#define V4L2_ENC_CMD_RESUME     (3)
+
+/* Flags for V4L2_ENC_CMD_STOP */
+#define V4L2_ENC_CMD_STOP_AT_GOP_END    (1 &lt;&lt; 0)
+
+struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link> {
+        __u32 cmd;
+        __u32 flags;
+        union {
+                struct {
+                        __u32 data[8];
+                } raw;
+        };
+};
+
+#endif
+
+
+/*
+ *      D A T A   S E R V I C E S   ( V B I )
+ *
+ *      Data services API by Michael Schimek
+ */
+
+/* Raw VBI */
+struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link> {
+        __u32   sampling_rate;          /* in 1 Hz */
+        __u32   offset;
+        __u32   samples_per_line;
+        __u32   sample_format;          /* V4L2_PIX_FMT_* */
+        __s32   start[2];
+        __u32   count[2];
+        __u32   flags;                  /* V4L2_VBI_* */
+        __u32   reserved[2];            /* must be zero */
+};
+
+/*  VBI flags  */
+#define V4L2_VBI_UNSYNC         (1 &lt;&lt; 0)
+#define V4L2_VBI_INTERLACED     (1 &lt;&lt; 1)
+
+/* Sliced VBI
+ *
+ *    This implements is a proposal V4L2 API to allow SLICED VBI
+ * required for some hardware encoders. It should change without
+ * notice in the definitive implementation.
+ */
+
+struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link> {
+        __u16   service_set;
+        /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+           service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+                                 (equals frame lines 313-336 for 625 line video
+                                  standards, 263-286 for 525 line standards) */
+        __u16   service_lines[2][24];
+        __u32   io_size;
+        __u32   reserved[2];            /* must be zero */
+};
+
+/* Teletext World System Teletext
+   (WST), defined on ITU-R BT.653-2 */
+#define V4L2_SLICED_TELETEXT_B          (0x0001)
+/* Video Program System, defined on ETS 300 231*/
+#define V4L2_SLICED_VPS                 (0x0400)
+/* Closed Caption, defined on EIA-608 */
+#define V4L2_SLICED_CAPTION_525         (0x1000)
+/* Wide Screen System, defined on ITU-R BT1119.1 */
+#define V4L2_SLICED_WSS_625             (0x4000)
+
+#define V4L2_SLICED_VBI_525             (V4L2_SLICED_CAPTION_525)
+#define V4L2_SLICED_VBI_625             (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+
+struct <link linkend="v4l2-sliced-vbi-cap">v4l2_sliced_vbi_cap</link> {
+        __u16   service_set;
+        /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
+           service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
+                                 (equals frame lines 313-336 for 625 line video
+                                  standards, 263-286 for 525 line standards) */
+        __u16   service_lines[2][24];
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
+        __u32   reserved[3];    /* must be 0 */
+};
+
+struct <link linkend="v4l2-sliced-vbi-data">v4l2_sliced_vbi_data</link> {
+        __u32   id;
+        __u32   field;          /* 0: first field, 1: second field */
+        __u32   line;           /* 1-23 */
+        __u32   reserved;       /* must be 0 */
+        __u8    data[48];
+};
+
+/*
+ * Sliced VBI data inserted into MPEG Streams
+ */
+
+/*
+ * V4L2_MPEG_STREAM_VBI_FMT_IVTV:
+ *
+ * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an
+ * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI
+ * data
+ *
+ * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header
+ * definitions are not included here.  See the MPEG-2 specifications for details
+ * on these headers.
+ */
+
+/* Line type IDs */
+#define V4L2_MPEG_VBI_IVTV_TELETEXT_B     (1)
+#define V4L2_MPEG_VBI_IVTV_CAPTION_525    (4)
+#define V4L2_MPEG_VBI_IVTV_WSS_625        (5)
+#define V4L2_MPEG_VBI_IVTV_VPS            (7)
+
+struct <link linkend="v4l2-mpeg-vbi-itv0-line">v4l2_mpeg_vbi_itv0_line</link> {
+        __u8 id;        /* One of V4L2_MPEG_VBI_IVTV_* above */
+        __u8 data[42];  /* Sliced VBI data for the line */
+} __attribute__ ((packed));
+
+struct <link linkend="v4l2-mpeg-vbi-itv0">v4l2_mpeg_vbi_itv0</link> {
+        __le32 linemask[2]; /* Bitmasks of VBI service lines present */
+        struct <link linkend="v4l2-mpeg-vbi-itv0-line">v4l2_mpeg_vbi_itv0_line</link> line[35];
+} __attribute__ ((packed));
+
+struct <link linkend="v4l2-mpeg-vbi-itv0-1">v4l2_mpeg_vbi_ITV0</link> {
+        struct <link linkend="v4l2-mpeg-vbi-itv0-line">v4l2_mpeg_vbi_itv0_line</link> line[36];
+} __attribute__ ((packed));
+
+#define V4L2_MPEG_VBI_IVTV_MAGIC0       "itv0"
+#define V4L2_MPEG_VBI_IVTV_MAGIC1       "ITV0"
+
+struct <link linkend="v4l2-mpeg-vbi-fmt-ivtv">v4l2_mpeg_vbi_fmt_ivtv</link> {
+        __u8 magic[4];
+        union {
+                struct <link linkend="v4l2-mpeg-vbi-itv0">v4l2_mpeg_vbi_itv0</link> itv0;
+                struct <link linkend="v4l2-mpeg-vbi-itv0-1">v4l2_mpeg_vbi_ITV0</link> ITV0;
+        };
+} __attribute__ ((packed));
+
+/*
+ *      A G G R E G A T E   S T R U C T U R E S
+ */
+
+/*      Stream data format
+ */
+struct <link linkend="v4l2-format">v4l2_format</link> {
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
+        union {
+                struct <link linkend="v4l2-pix-format">v4l2_pix_format</link>          pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
+                struct <link linkend="v4l2-window">v4l2_window</link>              win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
+                struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link>          vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
+                struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link>   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
+                __u8    raw_data[200];                   /* user-defined */
+        } fmt;
+};
+
+
+/*      Stream type-dependent parameters
+ */
+struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> {
+        enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
+        union {
+                struct <link linkend="v4l2-captureparm">v4l2_captureparm</link> capture;
+                struct <link linkend="v4l2-outputparm">v4l2_outputparm</link>  output;
+                __u8    raw_data[200];  /* user-defined */
+        } parm;
+};
+
+/*
+ *      A D V A N C E D   D E B U G G I N G
+ *
+ *      NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS!
+ *      FOR DEBUGGING, TESTING AND INTERNAL USE ONLY!
+ */
+
+/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
+
+#define V4L2_CHIP_MATCH_HOST       0  /* Match against chip ID on host (0 for the host) */
+#define V4L2_CHIP_MATCH_I2C_DRIVER 1  /* Match against I2C driver name */
+#define V4L2_CHIP_MATCH_I2C_ADDR   2  /* Match against I2C 7-bit address */
+#define V4L2_CHIP_MATCH_AC97       3  /* Match against anciliary AC97 chip */
+
+struct <link linkend="v4l2-dbg-match">v4l2_dbg_match</link> {
+        __u32 type; /* Match type */
+        union {     /* Match this chip, meaning determined by type */
+                __u32 addr;
+                char name[32];
+        };
+} __attribute__ ((packed));
+
+struct <link linkend="v4l2-dbg-register">v4l2_dbg_register</link> {
+        struct <link linkend="v4l2-dbg-match">v4l2_dbg_match</link> match;
+        __u32 size;     /* register size in bytes */
+        __u64 reg;
+        __u64 val;
+} __attribute__ ((packed));
+
+/* VIDIOC_DBG_G_CHIP_IDENT */
+struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
+        struct <link linkend="v4l2-dbg-match">v4l2_dbg_match</link> match;
+        __u32 ident;       /* chip identifier as specified in &lt;media/v4l2-chip-ident.h&gt; */
+        __u32 revision;    /* chip revision, chip specific */
+} __attribute__ ((packed));
+
+/*
+ *      I O C T L   C O D E S   F O R   V I D E O   D E V I C E S
+ *
+ */
+#define VIDIOC_QUERYCAP          _IOR('V',  0, struct <link linkend="v4l2-capability">v4l2_capability</link>)
+#define VIDIOC_RESERVED           _IO('V',  1)
+#define VIDIOC_ENUM_FMT         _IOWR('V',  2, struct <link linkend="v4l2-fmtdesc">v4l2_fmtdesc</link>)
+#define VIDIOC_G_FMT            _IOWR('V',  4, struct <link linkend="v4l2-format">v4l2_format</link>)
+#define VIDIOC_S_FMT            _IOWR('V',  5, struct <link linkend="v4l2-format">v4l2_format</link>)
+#define VIDIOC_REQBUFS          _IOWR('V',  8, struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link>)
+#define VIDIOC_QUERYBUF         _IOWR('V',  9, struct <link linkend="v4l2-buffer">v4l2_buffer</link>)
+#define VIDIOC_G_FBUF            _IOR('V', 10, struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link>)
+#define VIDIOC_S_FBUF            _IOW('V', 11, struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link>)
+#define VIDIOC_OVERLAY           _IOW('V', 14, int)
+#define VIDIOC_QBUF             _IOWR('V', 15, struct <link linkend="v4l2-buffer">v4l2_buffer</link>)
+#define VIDIOC_DQBUF            _IOWR('V', 17, struct <link linkend="v4l2-buffer">v4l2_buffer</link>)
+#define VIDIOC_STREAMON          _IOW('V', 18, int)
+#define VIDIOC_STREAMOFF         _IOW('V', 19, int)
+#define VIDIOC_G_PARM           _IOWR('V', 21, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
+#define VIDIOC_S_PARM           _IOWR('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
+#define VIDIOC_G_STD             _IOR('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD             _IOW('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD          _IOWR('V', 25, struct <link linkend="v4l2-standard">v4l2_standard</link>)
+#define VIDIOC_ENUMINPUT        _IOWR('V', 26, struct <link linkend="v4l2-input">v4l2_input</link>)
+#define VIDIOC_G_CTRL           _IOWR('V', 27, struct <link linkend="v4l2-control">v4l2_control</link>)
+#define VIDIOC_S_CTRL           _IOWR('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>)
+#define VIDIOC_G_TUNER          _IOWR('V', 29, struct <link linkend="v4l2-tuner">v4l2_tuner</link>)
+#define VIDIOC_S_TUNER           _IOW('V', 30, struct <link linkend="v4l2-tuner">v4l2_tuner</link>)
+#define VIDIOC_G_AUDIO           _IOR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>)
+#define VIDIOC_S_AUDIO           _IOW('V', 34, struct <link linkend="v4l2-audio">v4l2_audio</link>)
+#define VIDIOC_QUERYCTRL        _IOWR('V', 36, struct <link linkend="v4l2-queryctrl">v4l2_queryctrl</link>)
+#define VIDIOC_QUERYMENU        _IOWR('V', 37, struct <link linkend="v4l2-querymenu">v4l2_querymenu</link>)
+#define VIDIOC_G_INPUT           _IOR('V', 38, int)
+#define VIDIOC_S_INPUT          _IOWR('V', 39, int)
+#define VIDIOC_G_OUTPUT          _IOR('V', 46, int)
+#define VIDIOC_S_OUTPUT         _IOWR('V', 47, int)
+#define VIDIOC_ENUMOUTPUT       _IOWR('V', 48, struct <link linkend="v4l2-output">v4l2_output</link>)
+#define VIDIOC_G_AUDOUT          _IOR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
+#define VIDIOC_S_AUDOUT          _IOW('V', 50, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
+#define VIDIOC_G_MODULATOR      _IOWR('V', 54, struct <link linkend="v4l2-modulator">v4l2_modulator</link>)
+#define VIDIOC_S_MODULATOR       _IOW('V', 55, struct <link linkend="v4l2-modulator">v4l2_modulator</link>)
+#define VIDIOC_G_FREQUENCY      _IOWR('V', 56, struct <link linkend="v4l2-frequency">v4l2_frequency</link>)
+#define VIDIOC_S_FREQUENCY       _IOW('V', 57, struct <link linkend="v4l2-frequency">v4l2_frequency</link>)
+#define VIDIOC_CROPCAP          _IOWR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>)
+#define VIDIOC_G_CROP           _IOWR('V', 59, struct <link linkend="v4l2-crop">v4l2_crop</link>)
+#define VIDIOC_S_CROP            _IOW('V', 60, struct <link linkend="v4l2-crop">v4l2_crop</link>)
+#define VIDIOC_G_JPEGCOMP        _IOR('V', 61, struct <link linkend="v4l2-jpegcompression">v4l2_jpegcompression</link>)
+#define VIDIOC_S_JPEGCOMP        _IOW('V', 62, struct <link linkend="v4l2-jpegcompression">v4l2_jpegcompression</link>)
+#define VIDIOC_QUERYSTD          _IOR('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT          _IOWR('V', 64, struct <link linkend="v4l2-format">v4l2_format</link>)
+#define VIDIOC_ENUMAUDIO        _IOWR('V', 65, struct <link linkend="v4l2-audio">v4l2_audio</link>)
+#define VIDIOC_ENUMAUDOUT       _IOWR('V', 66, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
+#define VIDIOC_G_PRIORITY        _IOR('V', 67, enum <link linkend="v4l2-priority">v4l2_priority</link>)
+#define VIDIOC_S_PRIORITY        _IOW('V', 68, enum <link linkend="v4l2-priority">v4l2_priority</link>)
+#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct <link linkend="v4l2-sliced-vbi-cap">v4l2_sliced_vbi_cap</link>)
+#define VIDIOC_LOG_STATUS         _IO('V', 70)
+#define VIDIOC_G_EXT_CTRLS      _IOWR('V', 71, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
+#define VIDIOC_S_EXT_CTRLS      _IOWR('V', 72, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
+#define VIDIOC_TRY_EXT_CTRLS    _IOWR('V', 73, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
+#if 1 /*KEEP*/
+#define VIDIOC_ENUM_FRAMESIZES  _IOWR('V', 74, struct <link linkend="v4l2-frmsizeenum">v4l2_frmsizeenum</link>)
+#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct <link linkend="v4l2-frmivalenum">v4l2_frmivalenum</link>)
+#define VIDIOC_G_ENC_INDEX       _IOR('V', 76, struct <link linkend="v4l2-enc-idx">v4l2_enc_idx</link>)
+#define VIDIOC_ENCODER_CMD      _IOWR('V', 77, struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link>)
+#define VIDIOC_TRY_ENCODER_CMD  _IOWR('V', 78, struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link>)
+#endif
+
+#if 1 /*KEEP*/
+/* Experimental, meant for debugging, testing and internal use.
+   Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined.
+   You must be root to use these ioctls. Never use these in applications! */
+#define VIDIOC_DBG_S_REGISTER    _IOW('V', 79, struct <link linkend="v4l2-dbg-register">v4l2_dbg_register</link>)
+#define VIDIOC_DBG_G_REGISTER   _IOWR('V', 80, struct <link linkend="v4l2-dbg-register">v4l2_dbg_register</link>)
+
+/* Experimental, meant for debugging, testing and internal use.
+   Never use this ioctl in applications! */
+#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link>)
+#endif
+
+#define VIDIOC_S_HW_FREQ_SEEK    _IOW('V', 82, struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link>)
+/* Reminder: when adding new ioctls please add support for them to
+   drivers/media/video/v4l2-compat-ioctl32.c as well! */
+
+#ifdef __OLD_VIDIOC_
+/* for compatibility, will go away some day */
+#define VIDIOC_OVERLAY_OLD      _IOWR('V', 14, int)
+#define VIDIOC_S_PARM_OLD        _IOW('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
+#define VIDIOC_S_CTRL_OLD        _IOW('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>)
+#define VIDIOC_G_AUDIO_OLD      _IOWR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>)
+#define VIDIOC_G_AUDOUT_OLD     _IOWR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
+#define VIDIOC_CROPCAP_OLD       _IOR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>)
+#endif
+
+#define BASE_VIDIOC_PRIVATE     192             /* 192-255 are private */
+
+#endif /* __LINUX_VIDEODEV2_H */
+</programlisting>
diff --git a/Documentation/DocBook/v4l/vidioc-cropcap.xml b/Documentation/DocBook/v4l/vidioc-cropcap.xml
new file mode 100644
index 0000000..816e90e
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-cropcap.xml
@@ -0,0 +1,174 @@
+<refentry id="vidioc-cropcap">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_CROPCAP</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_CROPCAP</refname>
+    <refpurpose>Information about the video cropping and scaling abilities</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_cropcap
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_CROPCAP</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications use this function to query the cropping
+limits, the pixel aspect of images and to calculate scale factors.
+They set the <structfield>type</structfield> field of a v4l2_cropcap
+structure to the respective buffer (stream) type and call the
+<constant>VIDIOC_CROPCAP</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure. The results are
+constant except when switching the video standard. Remember this
+switch can occur implicit when switching the video input or
+output.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-cropcap">
+      <title>struct <structname>v4l2_cropcap</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of the data stream, set by the application.
+Only these types are valid here:
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
+defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
+and higher.</entry>
+	  </row>
+	  <row>
+	    <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
+	    <entry><structfield>bounds</structfield></entry>
+	    <entry>Defines the window within capturing or output is
+possible, this may exclude for example the horizontal and vertical
+blanking areas. The cropping rectangle cannot exceed these limits.
+Width and height are defined in pixels, the driver writer is free to
+choose origin and units of the coordinate system in the analog
+domain.</entry>
+	  </row>
+	  <row>
+	    <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
+	    <entry><structfield>defrect</structfield></entry>
+	    <entry>Default cropping rectangle, it shall cover the
+"whole picture". Assuming pixel aspect 1/1 this could be for example a
+640&nbsp;&times;&nbsp;480 rectangle for NTSC, a
+768&nbsp;&times;&nbsp;576 rectangle for PAL and SECAM centered over
+the active picture area. The same co-ordinate system as for
+	    <structfield>bounds</structfield> is used.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>pixelaspect</structfield></entry>
+	    <entry><para>This is the pixel aspect (y / x) when no
+scaling is applied, the ratio of the actual sampling
+frequency and the frequency required to get square
+pixels.</para><para>When cropping coordinates refer to square pixels,
+the driver sets <structfield>pixelaspect</structfield> to 1/1. Other
+common values are 54/59 for PAL and SECAM, 11/10 for NTSC sampled
+according to [<xref linkend="itu601" />].</para></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- NB this table is duplicated in the overlay chapter. -->
+
+    <table pgwide="1" frame="none" id="v4l2-rect-crop">
+      <title>struct <structname>v4l2_rect</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>left</structfield></entry>
+	    <entry>Horizontal offset of the top, left corner of the
+rectangle, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>top</structfield></entry>
+	    <entry>Vertical offset of the top, left corner of the
+rectangle, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry>Width of the rectangle, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry>Height of the rectangle, in pixels. Width
+and height cannot be negative, the fields are signed for
+hysterical reasons. <!-- video4linux-list@redhat.com
+on 22 Oct 2002 subject "Re:[V4L][patches!] Re:v4l2/kernel-2.5" -->
+</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-cropcap; <structfield>type</structfield> is
+invalid or the ioctl is not supported. This is not permitted for
+video capture, output and overlay devices, which must support
+<constant>VIDIOC_CROPCAP</constant>.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml b/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml
new file mode 100644
index 0000000..4a09e20
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml
@@ -0,0 +1,275 @@
+<refentry id="vidioc-dbg-g-chip-ident">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_DBG_G_CHIP_IDENT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_DBG_G_CHIP_IDENT</refname>
+    <refpurpose>Identify the chips on a TV card</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_dbg_chip_ident
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_DBG_G_CHIP_IDENT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+
+      <para>This is an <link
+linkend="experimental">experimental</link> interface and may change in
+the future.</para>
+    </note>
+
+    <para>For driver debugging purposes this ioctl allows test
+applications to query the driver about the chips present on the TV
+card. Regular applications must not use it. When you found a chip
+specific bug, please contact the linux-media mailing list (&v4l-ml;)
+so it can be fixed.</para>
+
+    <para>To query the driver applications must initialize the
+<structfield>match.type</structfield> and
+<structfield>match.addr</structfield> or <structfield>match.name</structfield>
+fields of a &v4l2-dbg-chip-ident;
+and call <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> with a pointer to
+this structure. On success the driver stores information about the
+selected chip in the <structfield>ident</structfield> and
+<structfield>revision</structfield> fields. On failure the structure
+remains unchanged.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_HOST</constant>,
+<structfield>match.addr</structfield> selects the nth non-&i2c; chip
+on the TV card. You can enumerate all chips by starting at zero and
+incrementing <structfield>match.addr</structfield> by one until
+<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.
+The number zero always selects the host chip, &eg; the chip connected
+to the PCI or USB bus.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
+<structfield>match.name</structfield> contains the I2C driver name.
+For instance
+<constant>"saa7127"</constant> will match any chip
+supported by the saa7127 driver, regardless of its &i2c; bus address.
+When multiple chips supported by the same driver are present, the
+ioctl will return <constant>V4L2_IDENT_AMBIGUOUS</constant> in the
+<structfield>ident</structfield> field.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
+<structfield>match.addr</structfield> selects a chip by its 7 bit
+&i2c; bus address.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_AC97</constant>,
+<structfield>match.addr</structfield> selects the nth AC97 chip
+on the TV card. You can enumerate all chips by starting at zero and
+incrementing <structfield>match.addr</structfield> by one until
+<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.</para>
+
+    <para>On success, the <structfield>ident</structfield> field will
+contain a chip ID from the Linux
+<filename>media/v4l2-chip-ident.h</filename> header file, and the
+<structfield>revision</structfield> field will contain a driver
+specific value, or zero if no particular revision is associated with
+this chip.</para>
+
+    <para>When the driver could not identify the selected chip,
+<structfield>ident</structfield> will contain
+<constant>V4L2_IDENT_UNKNOWN</constant>. When no chip matched
+the ioctl will succeed but the
+<structfield>ident</structfield> field will contain
+<constant>V4L2_IDENT_NONE</constant>. If multiple chips matched,
+<structfield>ident</structfield> will contain
+<constant>V4L2_IDENT_AMBIGUOUS</constant>. In all these cases the
+<structfield>revision</structfield> field remains unchanged.</para>
+
+    <para>This ioctl is optional, not all drivers may support it. It
+was introduced in Linux 2.6.21, but the API was changed to the
+one described here in 2.6.29.</para>
+
+    <para>We recommended the <application>v4l2-dbg</application>
+utility over calling this ioctl directly. It is available from the
+LinuxTV v4l-dvb repository; see <ulink
+url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
+access instructions.</para>
+
+    <!-- Note for convenience vidioc-dbg-g-register.sgml
+	 contains a duplicate of this table. -->
+    <table pgwide="1" frame="none" id="ident-v4l2-dbg-match">
+      <title>struct <structname>v4l2_dbg_match</structname></title>
+      <tgroup cols="4">
+	&cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>See <xref linkend="ident-chip-match-types" /> for a list of
+possible types.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry>(anonymous)</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>addr</structfield></entry>
+	    <entry>Match a chip by this number, interpreted according
+to the <structfield>type</structfield> field.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>char</entry>
+	    <entry><structfield>name[32]</structfield></entry>
+	    <entry>Match a chip by this name, interpreted according
+to the <structfield>type</structfield> field.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-dbg-chip-ident">
+      <title>struct <structname>v4l2_dbg_chip_ident</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>struct v4l2_dbg_match</entry>
+	    <entry><structfield>match</structfield></entry>
+	    <entry>How to match the chip, see <xref linkend="ident-v4l2-dbg-match" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>ident</structfield></entry>
+	    <entry>A chip identifier as defined in the Linux
+<filename>media/v4l2-chip-ident.h</filename> header file, or one of
+the values from <xref linkend="chip-ids" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>revision</structfield></entry>
+	    <entry>A chip revision, chip and driver specific.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- Note for convenience vidioc-dbg-g-register.sgml
+	 contains a duplicate of this table. -->
+    <table pgwide="1" frame="none" id="ident-chip-match-types">
+      <title>Chip Match Types</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
+	    <entry>0</entry>
+	    <entry>Match the nth chip on the card, zero for the
+	    host chip. Does not match &i2c; chips.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
+	    <entry>1</entry>
+	    <entry>Match an &i2c; chip by its driver name.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
+	    <entry>2</entry>
+	    <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
+	    <entry>3</entry>
+	    <entry>Match the nth anciliary AC97 chip.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- This is an anonymous enum in media/v4l2-chip-ident.h. -->
+    <table pgwide="1" frame="none" id="chip-ids">
+      <title>Chip Identifiers</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_IDENT_NONE</constant></entry>
+	    <entry>0</entry>
+	    <entry>No chip matched.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IDENT_AMBIGUOUS</constant></entry>
+	    <entry>1</entry>
+	    <entry>Multiple chips matched.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IDENT_UNKNOWN</constant></entry>
+	    <entry>2</entry>
+	    <entry>A chip is present at this address, but the driver
+could not identify it.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The driver does not support this ioctl, or the
+<structfield>match_type</structfield> is invalid.</para>
+	</listitem>
+      </varlistentry>
+     </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml b/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml
new file mode 100644
index 0000000..980c7f3
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml
@@ -0,0 +1,275 @@
+<refentry id="vidioc-dbg-g-register">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_DBG_G_REGISTER</refname>
+    <refname>VIDIOC_DBG_S_REGISTER</refname>
+    <refpurpose>Read or write hardware registers</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_dbg_register *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_dbg_register
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+
+      <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+    </note>
+
+    <para>For driver debugging purposes these ioctls allow test
+applications to access hardware registers directly. Regular
+applications must not use them.</para>
+
+    <para>Since writing or even reading registers can jeopardize the
+system security, its stability and damage the hardware, both ioctls
+require superuser privileges. Additionally the Linux kernel must be
+compiled with the <constant>CONFIG_VIDEO_ADV_DEBUG</constant> option
+to enable these ioctls.</para>
+
+    <para>To write a register applications must initialize all fields
+of a &v4l2-dbg-register; and call
+<constant>VIDIOC_DBG_S_REGISTER</constant> with a pointer to this
+structure. The <structfield>match.type</structfield> and
+<structfield>match.addr</structfield> or <structfield>match.name</structfield>
+fields select a chip on the TV
+card, the <structfield>reg</structfield> field specifies a register
+number and the <structfield>val</structfield> field the value to be
+written into the register.</para>
+
+    <para>To read a register applications must initialize the
+<structfield>match.type</structfield>,
+<structfield>match.chip</structfield> or <structfield>match.name</structfield> and
+<structfield>reg</structfield> fields, and call
+<constant>VIDIOC_DBG_G_REGISTER</constant> with a pointer to this
+structure. On success the driver stores the register value in the
+<structfield>val</structfield> field. On failure the structure remains
+unchanged.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_HOST</constant>,
+<structfield>match.addr</structfield> selects the nth non-&i2c; chip
+on the TV card.  The number zero always selects the host chip, &eg; the
+chip connected to the PCI or USB bus. You can find out which chips are
+present with the &VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
+<structfield>match.name</structfield> contains the I2C driver name.
+For instance
+<constant>"saa7127"</constant> will match any chip
+supported by the saa7127 driver, regardless of its &i2c; bus address.
+When multiple chips supported by the same driver are present, the
+effect of these ioctls is undefined. Again with the
+&VIDIOC-DBG-G-CHIP-IDENT; ioctl you can find out which &i2c; chips are
+present.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
+<structfield>match.addr</structfield> selects a chip by its 7 bit &i2c;
+bus address.</para>
+
+    <para>When <structfield>match.type</structfield> is
+<constant>V4L2_CHIP_MATCH_AC97</constant>,
+<structfield>match.addr</structfield> selects the nth AC97 chip
+on the TV card.</para>
+
+    <note>
+      <title>Success not guaranteed</title>
+
+      <para>Due to a flaw in the Linux &i2c; bus driver these ioctls may
+return successfully without actually reading or writing a register. To
+catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-IDENT;
+call confirming the presence of the selected &i2c; chip.</para>
+    </note>
+
+    <para>These ioctls are optional, not all drivers may support them.
+However when a driver supports these ioctls it must also support
+&VIDIOC-DBG-G-CHIP-IDENT;. Conversely it may support
+<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> but not these ioctls.</para>
+
+    <para><constant>VIDIOC_DBG_G_REGISTER</constant> and
+<constant>VIDIOC_DBG_S_REGISTER</constant> were introduced in Linux
+2.6.21, but their API was changed to the one described here in kernel 2.6.29.</para>
+
+    <para>We recommended the <application>v4l2-dbg</application>
+utility over calling these ioctls directly. It is available from the
+LinuxTV v4l-dvb repository; see <ulink
+url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
+access instructions.</para>
+
+    <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+	 contains a duplicate of this table. -->
+    <table pgwide="1" frame="none" id="v4l2-dbg-match">
+      <title>struct <structname>v4l2_dbg_match</structname></title>
+      <tgroup cols="4">
+	&cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>See <xref linkend="ident-chip-match-types" /> for a list of
+possible types.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry>(anonymous)</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>addr</structfield></entry>
+	    <entry>Match a chip by this number, interpreted according
+to the <structfield>type</structfield> field.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>char</entry>
+	    <entry><structfield>name[32]</structfield></entry>
+	    <entry>Match a chip by this name, interpreted according
+to the <structfield>type</structfield> field.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+
+    <table pgwide="1" frame="none" id="v4l2-dbg-register">
+      <title>struct <structname>v4l2_dbg_register</structname></title>
+      <tgroup cols="4">
+	<colspec colname="c1" />
+	<colspec colname="c2" />
+	<colspec colname="c4" />
+	<tbody valign="top">
+	  <row>
+	    <entry>struct v4l2_dbg_match</entry>
+	    <entry><structfield>match</structfield></entry>
+	    <entry>How to match the chip, see <xref linkend="v4l2-dbg-match" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u64</entry>
+	    <entry><structfield>reg</structfield></entry>
+	    <entry>A register number.</entry>
+	  </row>
+	  <row>
+	    <entry>__u64</entry>
+	    <entry><structfield>val</structfield></entry>
+	    <entry>The value read from, or to be written into the
+register.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
+	 contains a duplicate of this table. -->
+    <table pgwide="1" frame="none" id="chip-match-types">
+      <title>Chip Match Types</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
+	    <entry>0</entry>
+	    <entry>Match the nth chip on the card, zero for the
+	    host chip. Does not match &i2c; chips.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
+	    <entry>1</entry>
+	    <entry>Match an &i2c; chip by its driver name.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
+	    <entry>2</entry>
+	    <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
+	    <entry>3</entry>
+	    <entry>Match the nth anciliary AC97 chip.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The driver does not support this ioctl, or the kernel
+was not compiled with the <constant>CONFIG_VIDEO_ADV_DEBUG</constant>
+option, or the <structfield>match_type</structfield> is invalid, or the
+selected chip or register does not exist.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EPERM</errorcode></term>
+	<listitem>
+	  <para>Insufficient permissions. Root privileges are required
+to execute these ioctls.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml b/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml
new file mode 100644
index 0000000..b0dde94
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml
@@ -0,0 +1,204 @@
+<refentry id="vidioc-encoder-cmd">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENCODER_CMD</refname>
+    <refname>VIDIOC_TRY_ENCODER_CMD</refname>
+    <refpurpose>Execute an encoder command</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_encoder_cmd *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+
+      <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+    </note>
+
+    <para>These ioctls control an audio/video (usually MPEG-) encoder.
+<constant>VIDIOC_ENCODER_CMD</constant> sends a command to the
+encoder, <constant>VIDIOC_TRY_ENCODER_CMD</constant> can be used to
+try a command without actually executing it.</para>
+
+    <para>To send a command applications must initialize all fields of a
+    &v4l2-encoder-cmd; and call
+    <constant>VIDIOC_ENCODER_CMD</constant> or
+    <constant>VIDIOC_TRY_ENCODER_CMD</constant> with a pointer to this
+    structure.</para>
+
+    <para>The <structfield>cmd</structfield> field must contain the
+command code. The <structfield>flags</structfield> field is currently
+only used by the STOP command and contains one bit: If the
+<constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant> flag is set,
+encoding will continue until the end of the current <wordasword>Group
+Of Pictures</wordasword>, otherwise it will stop immediately.</para>
+
+    <para>A <function>read</function>() call sends a START command to
+the encoder if it has not been started yet. After a STOP command,
+<function>read</function>() calls will read the remaining data
+buffered by the driver. When the buffer is empty,
+<function>read</function>() will return zero and the next
+<function>read</function>() call will restart the encoder.</para>
+
+    <para>A <function>close</function>() call sends an immediate STOP
+to the encoder, and all buffered data is discarded.</para>
+
+    <para>These ioctls are optional, not all drivers may support
+them. They were introduced in Linux 2.6.21.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-encoder-cmd">
+      <title>struct <structname>v4l2_encoder_cmd</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>cmd</structfield></entry>
+	    <entry>The encoder command, see <xref linkend="encoder-cmds" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>Flags to go with the command, see <xref
+		linkend="encoder-flags" />. If no flags are defined for
+this command, drivers and applications must set this field to
+zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>data</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="encoder-cmds">
+      <title>Encoder Commands</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_ENC_CMD_START</constant></entry>
+	    <entry>0</entry>
+	    <entry>Start the encoder. When the encoder is already
+running or paused, this command does nothing. No flags are defined for
+this command.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_ENC_CMD_STOP</constant></entry>
+	    <entry>1</entry>
+	    <entry>Stop the encoder. When the
+<constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant> flag is set,
+encoding will continue until the end of the current <wordasword>Group
+Of Pictures</wordasword>, otherwise encoding will stop immediately.
+When the encoder is already stopped, this command does
+nothing.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_ENC_CMD_PAUSE</constant></entry>
+	    <entry>2</entry>
+	    <entry>Pause the encoder. When the encoder has not been
+started yet, the driver will return an &EPERM;. When the encoder is
+already paused, this command does nothing. No flags are defined for
+this command.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_ENC_CMD_RESUME</constant></entry>
+	    <entry>3</entry>
+	    <entry>Resume encoding after a PAUSE command. When the
+encoder has not been started yet, the driver will return an &EPERM;.
+When the encoder is already running, this command does nothing. No
+flags are defined for this command.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="encoder-flags">
+      <title>Encoder Command Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>Stop encoding at the end of the current <wordasword>Group Of
+Pictures</wordasword>, rather than immediately.</entry>
+	  </row>
+       </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The driver does not support this ioctl, or the
+<structfield>cmd</structfield> field is invalid.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EPERM</errorcode></term>
+	<listitem>
+	  <para>The application sent a PAUSE or RESUME command when
+the encoder was not running.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
new file mode 100644
index 0000000..960d446
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
@@ -0,0 +1,164 @@
+<refentry id="vidioc-enum-fmt">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUM_FMT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUM_FMT</refname>
+    <refpurpose>Enumerate image formats</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_fmtdesc
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUM_FMT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To enumerate image formats applications initialize the
+<structfield>type</structfield> and <structfield>index</structfield>
+field of &v4l2-fmtdesc; and call the
+<constant>VIDIOC_ENUM_FMT</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL;. All formats are enumerable by beginning at index zero and
+incrementing by one until <errorcode>EINVAL</errorcode> is
+returned.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-fmtdesc">
+      <title>struct <structname>v4l2_fmtdesc</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Number of the format in the enumeration, set by
+the application. This is in no way related to the <structfield>
+pixelformat</structfield> field.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of the data stream, set by the application.
+Only these types are valid here:
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
+defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
+and higher.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>See <xref linkend="fmtdesc-flags" /></entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>description</structfield>[32]</entry>
+	    <entry>Description of the format, a NUL-terminated ASCII
+string. This information is intended for the user, for example: "YUV
+4:2:2".</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pixelformat</structfield></entry>
+	    <entry>The image format identifier. This is a
+four character code as computed by the v4l2_fourcc()
+macro:</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan"><para><programlisting id="v4l2-fourcc">
+#define v4l2_fourcc(a,b,c,d) (((__u32)(a)&lt;&lt;0)|((__u32)(b)&lt;&lt;8)|((__u32)(c)&lt;&lt;16)|((__u32)(d)&lt;&lt;24))
+</programlisting></para><para>Several image formats are already
+defined by this specification in <xref linkend="pixfmt" />. Note these
+codes are not the same as those used in the Windows world.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="fmtdesc-flags">
+      <title>Image Format Description Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_FMT_FLAG_COMPRESSED</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>This is a compressed format.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FMT_FLAG_EMULATED</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>This format is not native to the device but emulated
+through software (usually libv4l2), where possible try to use a native format
+instead for better performance.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-fmtdesc; <structfield>type</structfield>
+is not supported or the <structfield>index</structfield> is out of
+bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml b/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml
new file mode 100644
index 0000000..3c216e1
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml
@@ -0,0 +1,270 @@
+<refentry id="vidioc-enum-frameintervals">
+
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUM_FRAMEINTERVALS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUM_FRAMEINTERVALS</refname>
+    <refpurpose>Enumerate frame intervals</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_frmivalenum *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUM_FRAMEINTERVALS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para>Pointer to a &v4l2-frmivalenum; structure that
+contains a pixel format and size and receives a frame interval.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl allows applications to enumerate all frame
+intervals that the device supports for the given pixel format and
+frame size.</para>
+    <para>The supported pixel formats and frame sizes can be obtained
+by using the &VIDIOC-ENUM-FMT; and &VIDIOC-ENUM-FRAMESIZES;
+functions.</para>
+    <para>The return value and the content of the
+<structfield>v4l2_frmivalenum.type</structfield> field depend on the
+type of frame intervals the device supports. Here are the semantics of
+the function for the different cases:</para>
+    <itemizedlist>
+      <listitem>
+	<para><emphasis role="bold">Discrete:</emphasis> The function
+returns success if the given index value (zero-based) is valid. The
+application should increase the index by one for each call until
+<constant>EINVAL</constant> is returned. The `v4l2_frmivalenum.type`
+field is set to `V4L2_FRMIVAL_TYPE_DISCRETE` by the driver. Of the
+union only the `discrete` member is valid.</para>
+      </listitem>
+      <listitem>
+	<para><emphasis role="bold">Step-wise:</emphasis> The function
+returns success if the given index value is zero and
+<constant>EINVAL</constant> for any other index value. The
+<structfield>v4l2_frmivalenum.type</structfield> field is set to
+<constant>V4L2_FRMIVAL_TYPE_STEPWISE</constant> by the driver. Of the
+union only the <structfield>stepwise</structfield> member is
+valid.</para>
+      </listitem>
+      <listitem>
+	<para><emphasis role="bold">Continuous:</emphasis> This is a
+special case of the step-wise type above. The function returns success
+if the given index value is zero and <constant>EINVAL</constant> for
+any other index value. The
+<structfield>v4l2_frmivalenum.type</structfield> field is set to
+<constant>V4L2_FRMIVAL_TYPE_CONTINUOUS</constant> by the driver. Of
+the union only the <structfield>stepwise</structfield> member is valid
+and the <structfield>step</structfield> value is set to 1.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>When the application calls the function with index zero, it
+must check the <structfield>type</structfield> field to determine the
+type of frame interval enumeration the device supports. Only for the
+<constant>V4L2_FRMIVAL_TYPE_DISCRETE</constant> type does it make
+sense to increase the index value to receive more frame
+intervals.</para>
+    <para>Note that the order in which the frame intervals are
+returned has no special meaning. In particular does it not say
+anything about potential default frame intervals.</para>
+    <para>Applications can assume that the enumeration data does not
+change without any interaction from the application itself. This means
+that the enumeration data is consistent if the application does not
+perform any other ioctl calls while it runs the frame interval
+enumeration.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Notes</title>
+
+    <itemizedlist>
+      <listitem>
+	<para><emphasis role="bold">Frame intervals and frame
+rates:</emphasis> The V4L2 API uses frame intervals instead of frame
+rates. Given the frame interval the frame rate can be computed as
+follows:<screen>frame_rate = 1 / frame_interval</screen></para>
+      </listitem>
+    </itemizedlist>
+
+  </refsect1>
+
+  <refsect1>
+    <title>Structs</title>
+
+    <para>In the structs below, <emphasis>IN</emphasis> denotes a
+value that has to be filled in by the application,
+<emphasis>OUT</emphasis> denotes values that the driver fills in. The
+application should zero out all members except for the
+<emphasis>IN</emphasis> fields.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-frmival-stepwise">
+      <title>struct <structname>v4l2_frmival_stepwise</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>min</structfield></entry>
+	    <entry>Minimum frame interval [s].</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>max</structfield></entry>
+	    <entry>Maximum frame interval [s].</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>step</structfield></entry>
+	    <entry>Frame interval step size [s].</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-frmivalenum">
+      <title>struct <structname>v4l2_frmivalenum</structname></title>
+      <tgroup cols="4">
+	<colspec colname="c1" />
+	<colspec colname="c2" />
+	<colspec colname="c3" />
+	<colspec colname="c4" />
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry></entry>
+	    <entry>IN: Index of the given frame interval in the
+enumeration.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pixel_format</structfield></entry>
+	    <entry></entry>
+	    <entry>IN: Pixel format for which the frame intervals are
+enumerated.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry></entry>
+	    <entry>IN: Frame width for which the frame intervals are
+enumerated.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry></entry>
+	    <entry>IN: Frame height for which the frame intervals are
+enumerated.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry></entry>
+	    <entry>OUT: Frame interval type the device supports.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>OUT: Frame interval with the given index.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>discrete</structfield></entry>
+	    <entry>Frame interval [s].</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-frmival-stepwise;</entry>
+	    <entry><structfield>stepwise</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved[2]</structfield></entry>
+	    <entry></entry>
+	    <entry>Reserved space for future use.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    <title>Enums</title>
+
+    <table pgwide="1" frame="none" id="v4l2-frmivaltypes">
+      <title>enum <structname>v4l2_frmivaltypes</structname></title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_FRMIVAL_TYPE_DISCRETE</constant></entry>
+	    <entry>1</entry>
+	    <entry>Discrete frame interval.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FRMIVAL_TYPE_CONTINUOUS</constant></entry>
+	    <entry>2</entry>
+	    <entry>Continuous frame interval.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FRMIVAL_TYPE_STEPWISE</constant></entry>
+	    <entry>3</entry>
+	    <entry>Step-wise defined frame interval.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <para>See the description section above for a list of return
+values that <varname>errno</varname> can have.</para>
+  </refsect1>
+
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml b/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml
new file mode 100644
index 0000000..6afa454
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml
@@ -0,0 +1,282 @@
+<refentry id="vidioc-enum-framesizes">
+
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUM_FRAMESIZES</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUM_FRAMESIZES</refname>
+    <refpurpose>Enumerate frame sizes</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_frmsizeenum *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUM_FRAMESIZES</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para>Pointer to a &v4l2-frmsizeenum; that contains an index
+and pixel format and receives a frame width and height.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+
+      <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+    </note>
+
+    <para>This ioctl allows applications to enumerate all frame sizes
+(&ie; width and height in pixels) that the device supports for the
+given pixel format.</para>
+    <para>The supported pixel formats can be obtained by using the
+&VIDIOC-ENUM-FMT; function.</para>
+    <para>The return value and the content of the
+<structfield>v4l2_frmsizeenum.type</structfield> field depend on the
+type of frame sizes the device supports. Here are the semantics of the
+function for the different cases:</para>
+
+    <itemizedlist>
+      <listitem>
+	<para><emphasis role="bold">Discrete:</emphasis> The function
+returns success if the given index value (zero-based) is valid. The
+application should increase the index by one for each call until
+<constant>EINVAL</constant> is returned. The
+<structfield>v4l2_frmsizeenum.type</structfield> field is set to
+<constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant> by the driver. Of the
+union only the <structfield>discrete</structfield> member is
+valid.</para>
+      </listitem>
+      <listitem>
+	<para><emphasis role="bold">Step-wise:</emphasis> The function
+returns success if the given index value is zero and
+<constant>EINVAL</constant> for any other index value. The
+<structfield>v4l2_frmsizeenum.type</structfield> field is set to
+<constant>V4L2_FRMSIZE_TYPE_STEPWISE</constant> by the driver. Of the
+union only the <structfield>stepwise</structfield> member is
+valid.</para>
+      </listitem>
+      <listitem>
+	<para><emphasis role="bold">Continuous:</emphasis> This is a
+special case of the step-wise type above. The function returns success
+if the given index value is zero and <constant>EINVAL</constant> for
+any other index value. The
+<structfield>v4l2_frmsizeenum.type</structfield> field is set to
+<constant>V4L2_FRMSIZE_TYPE_CONTINUOUS</constant> by the driver. Of
+the union only the <structfield>stepwise</structfield> member is valid
+and the <structfield>step_width</structfield> and
+<structfield>step_height</structfield> values are set to 1.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>When the application calls the function with index zero, it
+must check the <structfield>type</structfield> field to determine the
+type of frame size enumeration the device supports. Only for the
+<constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant> type does it make
+sense to increase the index value to receive more frame sizes.</para>
+    <para>Note that the order in which the frame sizes are returned
+has no special meaning. In particular does it not say anything about
+potential default format sizes.</para>
+    <para>Applications can assume that the enumeration data does not
+change without any interaction from the application itself. This means
+that the enumeration data is consistent if the application does not
+perform any other ioctl calls while it runs the frame size
+enumeration.</para>
+  </refsect1>
+
+  <refsect1>
+    <title>Structs</title>
+
+    <para>In the structs below, <emphasis>IN</emphasis> denotes a
+value that has to be filled in by the application,
+<emphasis>OUT</emphasis> denotes values that the driver fills in. The
+application should zero out all members except for the
+<emphasis>IN</emphasis> fields.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-frmsize-discrete">
+      <title>struct <structname>v4l2_frmsize_discrete</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry>Width of the frame [pixel].</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry>Height of the frame [pixel].</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-frmsize-stepwise">
+      <title>struct <structname>v4l2_frmsize_stepwise</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>min_width</structfield></entry>
+	    <entry>Minimum frame width [pixel].</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>max_width</structfield></entry>
+	    <entry>Maximum frame width [pixel].</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>step_width</structfield></entry>
+	    <entry>Frame width step size [pixel].</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>min_height</structfield></entry>
+	    <entry>Minimum frame height [pixel].</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>max_height</structfield></entry>
+	    <entry>Maximum frame height [pixel].</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>step_height</structfield></entry>
+	    <entry>Frame height step size [pixel].</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-frmsizeenum">
+      <title>struct <structname>v4l2_frmsizeenum</structname></title>
+      <tgroup cols="4">
+	<colspec colname="c1" />
+	<colspec colname="c2" />
+	<colspec colname="c3" />
+	<colspec colname="c4" />
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry></entry>
+	    <entry>IN: Index of the given frame size in the enumeration.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pixel_format</structfield></entry>
+	    <entry></entry>
+	    <entry>IN: Pixel format for which the frame sizes are enumerated.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry></entry>
+	    <entry>OUT: Frame size type the device supports.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>OUT: Frame size with the given index.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-frmsize-discrete;</entry>
+	    <entry><structfield>discrete</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-frmsize-stepwise;</entry>
+	    <entry><structfield>stepwise</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved[2]</structfield></entry>
+	    <entry></entry>
+	    <entry>Reserved space for future use.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    <title>Enums</title>
+
+    <table pgwide="1" frame="none" id="v4l2-frmsizetypes">
+      <title>enum <structname>v4l2_frmsizetypes</structname></title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant></entry>
+	    <entry>1</entry>
+	    <entry>Discrete frame size.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FRMSIZE_TYPE_CONTINUOUS</constant></entry>
+	    <entry>2</entry>
+	    <entry>Continuous frame size.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FRMSIZE_TYPE_STEPWISE</constant></entry>
+	    <entry>3</entry>
+	    <entry>Step-wise defined frame size.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <para>See the description section above for a list of return
+values that <varname>errno</varname> can have.</para>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumaudio.xml b/Documentation/DocBook/v4l/vidioc-enumaudio.xml
new file mode 100644
index 0000000..9ae8f2d
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumaudio.xml
@@ -0,0 +1,86 @@
+<refentry id="vidioc-enumaudio">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUMAUDIO</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUMAUDIO</refname>
+    <refpurpose>Enumerate audio inputs</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_audio *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUMAUDIO</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of an audio input applications
+initialize the <structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-audio;
+and call the <constant>VIDIOC_ENUMAUDIO</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all audio
+inputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+    <para>See <xref linkend="vidioc-g-audio" /> for a description of
+&v4l2-audio;.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The number of the audio input is out of bounds, or
+there are no audio inputs at all and this ioctl is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumaudioout.xml b/Documentation/DocBook/v4l/vidioc-enumaudioout.xml
new file mode 100644
index 0000000..d3d7c0a
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumaudioout.xml
@@ -0,0 +1,89 @@
+<refentry id="vidioc-enumaudioout">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUMAUDOUT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUMAUDOUT</refname>
+    <refpurpose>Enumerate audio outputs</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_audioout *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUMAUDOUT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of an audio output applications
+initialize the <structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-audioout; and
+call the <constant>VIDIOC_G_AUDOUT</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all audio
+outputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+    <para>Note connectors on a TV card to loop back the received audio
+signal to a sound card are not audio outputs in this sense.</para>
+
+    <para>See <xref linkend="vidioc-g-audioout" /> for a description of
+&v4l2-audioout;.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The number of the audio output is out of bounds, or
+there are no audio outputs at all and this ioctl is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enuminput.xml b/Documentation/DocBook/v4l/vidioc-enuminput.xml
new file mode 100644
index 0000000..414856b
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enuminput.xml
@@ -0,0 +1,287 @@
+<refentry id="vidioc-enuminput">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUMINPUT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUMINPUT</refname>
+    <refpurpose>Enumerate video inputs</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_input
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUMINPUT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a video input applications
+initialize the <structfield>index</structfield> field of &v4l2-input;
+and call the <constant>VIDIOC_ENUMINPUT</constant> ioctl with a
+pointer to this structure. Drivers fill the rest of the structure or
+return an &EINVAL; when the index is out of bounds. To enumerate all
+inputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+    <table frame="none" pgwide="1" id="v4l2-input">
+      <title>struct <structname>v4l2_input</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Identifies the input, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry>Name of the video input, a NUL-terminated ASCII
+string, for example: "Vin (Composite 2)". This information is intended
+for the user, preferably the connector label on the device itself.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of the input, see <xref
+		linkend="input-type" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>audioset</structfield></entry>
+	    <entry><para>Drivers can enumerate up to 32 video and
+audio inputs. This field shows which audio inputs were selectable as
+audio source if this was the currently selected video input. It is a
+bit mask. The LSB corresponds to audio input 0, the MSB to input 31.
+Any number of bits can be set, or none.</para><para>When the driver
+does not enumerate audio inputs no bits must be set. Applications
+shall not interpret this as lack of audio support. Some drivers
+automatically select audio sources and do not enumerate them since
+there is no choice anyway.</para><para>For details on audio inputs and
+how to select the current input see <xref
+		  linkend="audio" />.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>tuner</structfield></entry>
+	    <entry>Capture devices can have zero or more tuners (RF
+demodulators). When the <structfield>type</structfield> is set to
+<constant>V4L2_INPUT_TYPE_TUNER</constant> this is an RF connector and
+this field identifies the tuner. It corresponds to
+&v4l2-tuner; field <structfield>index</structfield>. For details on
+tuners see <xref linkend="tuner" />.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-std-id;</entry>
+	    <entry><structfield>std</structfield></entry>
+	    <entry>Every video input supports one or more different
+video standards. This field is a set of all supported standards. For
+details on video standards and how to switch see <xref
+linkend="standard" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>status</structfield></entry>
+	    <entry>This field provides status information about the
+input. See <xref linkend="input-status" /> for flags.
+With the exception of the sensor orientation bits <structfield>status</structfield> is only valid when this is the
+current input.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="input-type">
+      <title>Input Types</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_INPUT_TYPE_TUNER</constant></entry>
+	    <entry>1</entry>
+	    <entry>This input uses a tuner (RF demodulator).</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_INPUT_TYPE_CAMERA</constant></entry>
+	    <entry>2</entry>
+	    <entry>Analog baseband input, for example CVBS /
+Composite Video, S-Video, RGB.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- Status flags based on proposal by Mark McClelland,
+video4linux-list@redhat.com on 18 Oct 2002, subject "Re: [V4L] Re:
+v4l2 api". "Why are some of them inverted? So that the driver doesn't
+have to lie about the status in cases where it can't tell one way or
+the other. Plus, a status of zero would generally mean that everything
+is OK." -->
+
+    <table frame="none" pgwide="1" id="input-status">
+      <title>Input Status Flags</title>
+      <tgroup cols="3">
+	<colspec colname="c1" />
+	<colspec colname="c2" align="center" />
+	<colspec colname="c3" />
+	<spanspec namest="c1" nameend="c3" spanname="hspan"
+	  align="left" />
+	<tbody valign="top">
+	  <row>
+	    <entry spanname="hspan">General</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_POWER</constant></entry>
+	    <entry>0x00000001</entry>
+	    <entry>Attached device is off.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_SIGNAL</constant></entry>
+	    <entry>0x00000002</entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_COLOR</constant></entry>
+	    <entry>0x00000004</entry>
+	    <entry>The hardware supports color decoding, but does not
+detect color modulation in the signal.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan">Sensor Orientation</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_HFLIP</constant></entry>
+	    <entry>0x00000010</entry>
+	    <entry>The input is connected to a device that produces a signal
+that is flipped horizontally and does not correct this before passing the
+signal to userspace.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_VFLIP</constant></entry>
+	    <entry>0x00000020</entry>
+	    <entry>The input is connected to a device that produces a signal
+that is flipped vertically and does not correct this before passing the
+signal to userspace. Note that a 180 degree rotation is the same as HFLIP | VFLIP</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan">Analog Video</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_H_LOCK</constant></entry>
+	    <entry>0x00000100</entry>
+	    <entry>No horizontal sync lock.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_COLOR_KILL</constant></entry>
+	    <entry>0x00000200</entry>
+	    <entry>A color killer circuit automatically disables color
+decoding when it detects no color modulation. When this flag is set
+the color killer is enabled <emphasis>and</emphasis> has shut off
+color decoding.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan">Digital Video</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_SYNC</constant></entry>
+	    <entry>0x00010000</entry>
+	    <entry>No synchronization lock.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_EQU</constant></entry>
+	    <entry>0x00020000</entry>
+	    <entry>No equalizer lock.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_CARRIER</constant></entry>
+	    <entry>0x00040000</entry>
+	    <entry>Carrier recovery failed.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan">VCR and Set-Top Box</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_MACROVISION</constant></entry>
+	    <entry>0x01000000</entry>
+	    <entry>Macrovision is an analog copy prevention system
+mangling the video signal to confuse video recorders. When this
+flag is set Macrovision has been detected.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_NO_ACCESS</constant></entry>
+	    <entry>0x02000000</entry>
+	    <entry>Conditional access denied.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_IN_ST_VTR</constant></entry>
+	    <entry>0x04000000</entry>
+	    <entry>VTR time constant. [?]</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-input; <structfield>index</structfield> is
+out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumoutput.xml b/Documentation/DocBook/v4l/vidioc-enumoutput.xml
new file mode 100644
index 0000000..e8d16dc
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumoutput.xml
@@ -0,0 +1,172 @@
+<refentry id="vidioc-enumoutput">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUMOUTPUT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUMOUTPUT</refname>
+    <refpurpose>Enumerate video outputs</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_output *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUMOUTPUT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a video outputs applications
+initialize the <structfield>index</structfield> field of &v4l2-output;
+and call the <constant>VIDIOC_ENUMOUTPUT</constant> ioctl with a
+pointer to this structure. Drivers fill the rest of the structure or
+return an &EINVAL; when the index is out of bounds. To enumerate all
+outputs applications shall begin at index zero, incrementing by one
+until the driver returns <errorcode>EINVAL</errorcode>.</para>
+
+    <table frame="none" pgwide="1" id="v4l2-output">
+      <title>struct <structname>v4l2_output</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Identifies the output, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry>Name of the video output, a NUL-terminated ASCII
+string, for example: "Vout". This information is intended for the
+user, preferably the connector label on the device itself.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of the output, see <xref
+		linkend="output-type" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>audioset</structfield></entry>
+	    <entry><para>Drivers can enumerate up to 32 video and
+audio outputs. This field shows which audio outputs were
+selectable as the current output if this was the currently selected
+video output. It is a bit mask. The LSB corresponds to audio output 0,
+the MSB to output 31. Any number of bits can be set, or
+none.</para><para>When the driver does not enumerate audio outputs no
+bits must be set. Applications shall not interpret this as lack of
+audio support. Drivers may automatically select audio outputs without
+enumerating them.</para><para>For details on audio outputs and how to
+select the current output see <xref linkend="audio" />.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>modulator</structfield></entry>
+	    <entry>Output devices can have zero or more RF modulators.
+When the <structfield>type</structfield> is
+<constant>V4L2_OUTPUT_TYPE_MODULATOR</constant> this is an RF
+connector and this field identifies the modulator. It corresponds to
+&v4l2-modulator; field <structfield>index</structfield>. For details
+on modulators see <xref linkend="tuner" />.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-std-id;</entry>
+	    <entry><structfield>std</structfield></entry>
+	    <entry>Every video output supports one or more different
+video standards. This field is a set of all supported standards. For
+details on video standards and how to switch see <xref
+		linkend="standard" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table frame="none" pgwide="1" id="output-type">
+      <title>Output Type</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_OUTPUT_TYPE_MODULATOR</constant></entry>
+	    <entry>1</entry>
+	    <entry>This output is an analog TV modulator.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_OUTPUT_TYPE_ANALOG</constant></entry>
+	    <entry>2</entry>
+	    <entry>Analog baseband output, for example Composite /
+CVBS, S-Video, RGB.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY</constant></entry>
+	    <entry>3</entry>
+	    <entry>[?]</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-output; <structfield>index</structfield>
+is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumstd.xml b/Documentation/DocBook/v4l/vidioc-enumstd.xml
new file mode 100644
index 0000000..95803fe
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumstd.xml
@@ -0,0 +1,391 @@
+<refentry id="vidioc-enumstd">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_ENUMSTD</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_ENUMSTD</refname>
+    <refpurpose>Enumerate supported video standards</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_standard *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_ENUMSTD</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a video standard,
+especially a custom (driver defined) one, applications initialize the
+<structfield>index</structfield> field of &v4l2-standard; and call the
+<constant>VIDIOC_ENUMSTD</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all standards
+applications shall begin  at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a
+different set of standards after switching the video input or
+output.<footnote>
+	<para>The supported standards may overlap and we need an
+unambiguous set to find the current standard returned by
+<constant>VIDIOC_G_STD</constant>.</para>
+      </footnote></para>
+
+    <table pgwide="1" frame="none" id="v4l2-standard">
+      <title>struct <structname>v4l2_standard</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Number of the video standard, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-std-id;</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry>The bits in this field identify the standard as
+one of the common standards listed in <xref linkend="v4l2-std-id" />,
+or if bits 32 to 63 are set as custom standards. Multiple bits can be
+set if the hardware does not distinguish between these standards,
+however separate indices do not indicate the opposite. The
+<structfield>id</structfield> must be unique. No other enumerated
+<structname>v4l2_standard</structname> structure, for this input or
+output anyway, can contain the same set of bits.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[24]</entry>
+	    <entry>Name of the standard, a NUL-terminated ASCII
+string, for example: "PAL-B/G", "NTSC Japan". This information is
+intended for the user.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>frameperiod</structfield></entry>
+	    <entry>The frame period (not field period) is numerator
+/ denominator. For example M/NTSC has a frame period of 1001 /
+30000 seconds.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>framelines</structfield></entry>
+	    <entry>Total lines per frame including blanking,
+e.&nbsp;g. 625 for B/PAL.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-fract">
+      <title>struct <structname>v4l2_fract</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>numerator</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>denominator</structfield></entry>
+	    <entry></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-std-id">
+      <title>typedef <structname>v4l2_std_id</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u64</entry>
+	    <entry><structfield>v4l2_std_id</structfield></entry>
+	    <entry>This type is a set, each bit representing another
+video standard as listed below and in <xref
+linkend="video-standards" />. The 32 most significant bits are reserved
+for custom (driver defined) video standards.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <para><programlisting>
+#define V4L2_STD_PAL_B          ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1         ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G          ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H          ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I          ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D          ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1         ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K          ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M          ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N          ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc         ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60         ((v4l2_std_id)0x00000800)
+</programlisting></para><para><constant>V4L2_STD_PAL_60</constant> is
+a hybrid standard with 525 lines, 60 Hz refresh rate, and PAL color
+modulation with a 4.43 MHz color subcarrier. Some PAL video recorders
+can play back NTSC tapes in this mode for display on a 50/60 Hz agnostic
+PAL TV.</para><para><programlisting>
+#define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)
+#define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)
+#define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
+</programlisting></para><para><constant>V4L2_STD_NTSC_443</constant>
+is a hybrid standard with 525 lines, 60 Hz refresh rate, and NTSC
+color modulation with a 4.43 MHz color
+subcarrier.</para><para><programlisting>
+#define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)
+
+#define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G        ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H        ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K        ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1       ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L        ((v4l2_std_id)0x00400000)
+#define V4L2_STD_SECAM_LC       ((v4l2_std_id)0x00800000)
+
+/* ATSC/HDTV */
+#define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)
+</programlisting></para><para><!-- ATSC proposal by Mark McClelland,
+video4linux-list@redhat.com on 17 Oct 2002
+--><constant>V4L2_STD_ATSC_8_VSB</constant> and
+<constant>V4L2_STD_ATSC_16_VSB</constant> are U.S. terrestrial digital
+TV standards. Presently the V4L2 API does not support digital TV. See
+also the Linux DVB API at <ulink
+url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
+<para><programlisting>
+#define V4L2_STD_PAL_BG         (V4L2_STD_PAL_B         |\
+				 V4L2_STD_PAL_B1        |\
+				 V4L2_STD_PAL_G)
+#define V4L2_STD_B              (V4L2_STD_PAL_B         |\
+				 V4L2_STD_PAL_B1        |\
+				 V4L2_STD_SECAM_B)
+#define V4L2_STD_GH             (V4L2_STD_PAL_G         |\
+				 V4L2_STD_PAL_H         |\
+				 V4L2_STD_SECAM_G       |\
+				 V4L2_STD_SECAM_H)
+#define V4L2_STD_PAL_DK         (V4L2_STD_PAL_D         |\
+				 V4L2_STD_PAL_D1        |\
+				 V4L2_STD_PAL_K)
+#define V4L2_STD_PAL            (V4L2_STD_PAL_BG        |\
+				 V4L2_STD_PAL_DK        |\
+				 V4L2_STD_PAL_H         |\
+				 V4L2_STD_PAL_I)
+#define V4L2_STD_NTSC           (V4L2_STD_NTSC_M        |\
+				 V4L2_STD_NTSC_M_JP     |\
+				 V4L2_STD_NTSC_M_KR)
+#define V4L2_STD_MN             (V4L2_STD_PAL_M         |\
+				 V4L2_STD_PAL_N         |\
+				 V4L2_STD_PAL_Nc        |\
+				 V4L2_STD_NTSC)
+#define V4L2_STD_SECAM_DK       (V4L2_STD_SECAM_D       |\
+				 V4L2_STD_SECAM_K       |\
+				 V4L2_STD_SECAM_K1)
+#define V4L2_STD_DK             (V4L2_STD_PAL_DK        |\
+				 V4L2_STD_SECAM_DK)
+
+#define V4L2_STD_SECAM          (V4L2_STD_SECAM_B       |\
+				 V4L2_STD_SECAM_G       |\
+				 V4L2_STD_SECAM_H       |\
+				 V4L2_STD_SECAM_DK      |\
+				 V4L2_STD_SECAM_L       |\
+				 V4L2_STD_SECAM_LC)
+
+#define V4L2_STD_525_60         (V4L2_STD_PAL_M         |\
+				 V4L2_STD_PAL_60        |\
+				 V4L2_STD_NTSC          |\
+				 V4L2_STD_NTSC_443)
+#define V4L2_STD_625_50         (V4L2_STD_PAL           |\
+				 V4L2_STD_PAL_N         |\
+				 V4L2_STD_PAL_Nc        |\
+				 V4L2_STD_SECAM)
+
+#define V4L2_STD_UNKNOWN        0
+#define V4L2_STD_ALL            (V4L2_STD_525_60        |\
+				 V4L2_STD_625_50)
+</programlisting></para>
+
+    <table pgwide="1" id="video-standards" orient="land">
+      <title>Video Standards (based on [<xref linkend="itu470" />])</title>
+      <tgroup cols="12" colsep="1" rowsep="1" align="center">
+	<colspec colname="c1" align="left" />
+	<colspec colname="c2" />
+	<colspec colname="c3" />
+	<colspec colname="c4" />
+	<colspec colname="c5" />
+	<colspec colnum="7" colname="c7" />
+	<colspec colnum="9" colname="c9" />
+	<colspec colnum="12" colname="c12" />
+	<spanspec namest="c2" nameend="c3" spanname="m" align="center" />
+	<spanspec namest="c4" nameend="c12" spanname="x" align="center" />
+	<spanspec namest="c5" nameend="c7" spanname="b" align="center" />
+	<spanspec namest="c9" nameend="c12" spanname="s" align="center" />
+	<thead>
+	  <row>
+	    <entry>Characteristics</entry>
+	    <entry><para>M/NTSC<footnote><para>Japan uses a standard
+similar to M/NTSC
+(V4L2_STD_NTSC_M_JP).</para></footnote></para></entry>
+	    <entry>M/PAL</entry>
+	    <entry><para>N/PAL<footnote><para> The values in
+brackets apply to the combination N/PAL a.k.a.
+N<subscript>C</subscript> used in Argentina
+(V4L2_STD_PAL_Nc).</para></footnote></para></entry>
+	    <entry align="center">B, B1, G/PAL</entry>
+	    <entry align="center">D, D1, K/PAL</entry>
+	    <entry align="center">H/PAL</entry>
+	    <entry align="center">I/PAL</entry>
+	    <entry align="center">B, G/SECAM</entry>
+	    <entry align="center">D, K/SECAM</entry>
+	    <entry align="center">K1/SECAM</entry>
+	    <entry align="center">L/SECAM</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry>Frame lines</entry>
+	    <entry spanname="m">525</entry>
+	    <entry spanname="x">625</entry>
+	  </row>
+	  <row>
+	    <entry>Frame period (s)</entry>
+	    <entry spanname="m">1001/30000</entry>
+	    <entry spanname="x">1/25</entry>
+	  </row>
+	  <row>
+	    <entry>Chrominance sub-carrier frequency (Hz)</entry>
+	    <entry>3579545 &plusmn;&nbsp;10</entry>
+	    <entry>3579611.49 &plusmn;&nbsp;10</entry>
+	    <entry>4433618.75 &plusmn;&nbsp;5 (3582056.25
+&plusmn;&nbsp;5)</entry>
+	    <entry spanname="b">4433618.75 &plusmn;&nbsp;5</entry>
+	    <entry>4433618.75 &plusmn;&nbsp;1</entry>
+	    <entry spanname="s">f<subscript>OR</subscript>&nbsp;=
+4406250 &plusmn;&nbsp;2000, f<subscript>OB</subscript>&nbsp;= 4250000
+&plusmn;&nbsp;2000</entry>
+	  </row>
+	  <row>
+	    <entry>Nominal radio-frequency channel bandwidth
+(MHz)</entry>
+	    <entry>6</entry>
+	    <entry>6</entry>
+	    <entry>6</entry>
+	    <entry>B: 7; B1, G: 8</entry>
+	    <entry>8</entry>
+	    <entry>8</entry>
+	    <entry>8</entry>
+	    <entry>8</entry>
+	    <entry>8</entry>
+	    <entry>8</entry>
+	    <entry>8</entry>
+	  </row>
+	  <row>
+	    <entry>Sound carrier relative to vision carrier
+(MHz)</entry>
+	    <entry>+&nbsp;4.5</entry>
+	    <entry>+&nbsp;4.5</entry>
+	    <entry>+&nbsp;4.5</entry>
+	    <entry><para>+&nbsp;5.5 &plusmn;&nbsp;0.001
+<footnote><para>In the Federal Republic of Germany, Austria, Italy,
+the Netherlands, Slovakia and Switzerland a system of two sound
+carriers is used, the frequency of the second carrier being
+242.1875&nbsp;kHz above the frequency of the first sound carrier. For
+stereophonic sound transmissions a similar system is used in
+Australia.</para></footnote> <footnote><para>New Zealand uses a sound
+carrier displaced 5.4996 &plusmn;&nbsp;0.0005 MHz from the vision
+carrier.</para></footnote> <footnote><para>In Denmark, Finland, New
+Zealand, Sweden and Spain a system of two sound carriers is used. In
+Iceland, Norway and Poland the same system is being introduced. The
+second carrier is 5.85&nbsp;MHz above the vision carrier and is DQPSK
+modulated with 728&nbsp;kbit/s sound and data multiplex. (NICAM
+system)</para></footnote> <footnote><para>In the United Kingdom, a
+system of two sound carriers is used. The second sound carrier is
+6.552&nbsp;MHz above the vision carrier and is DQPSK modulated with a
+728&nbsp;kbit/s sound and data multiplex able to carry two sound
+channels. (NICAM system)</para></footnote></para></entry>
+	    <entry>+&nbsp;6.5 &plusmn;&nbsp;0.001</entry>
+	    <entry>+&nbsp;5.5</entry>
+	    <entry>+&nbsp;5.9996 &plusmn;&nbsp;0.0005</entry>
+	    <entry>+&nbsp;5.5 &plusmn;&nbsp;0.001</entry>
+	    <entry>+&nbsp;6.5 &plusmn;&nbsp;0.001</entry>
+	    <entry>+&nbsp;6.5</entry>
+	    <entry><para>+&nbsp;6.5 <footnote><para>In France, a
+digital carrier 5.85 MHz away from the vision carrier may be used in
+addition to the main sound carrier. It is modulated in differentially
+encoded QPSK with a 728 kbit/s sound and data multiplexer capable of
+carrying two sound channels. (NICAM
+system)</para></footnote></para></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-standard; <structfield>index</structfield>
+is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-audio.xml b/Documentation/DocBook/v4l/vidioc-g-audio.xml
new file mode 100644
index 0000000..65361a8
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-audio.xml
@@ -0,0 +1,188 @@
+<refentry id="vidioc-g-audio">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_AUDIO, VIDIOC_S_AUDIO</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_AUDIO</refname>
+    <refname>VIDIOC_S_AUDIO</refname>
+    <refpurpose>Query or select the current audio input and its
+attributes</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_audio *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_audio *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_AUDIO, VIDIOC_S_AUDIO</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the current audio input applications zero out the
+<structfield>reserved</structfield> array of a &v4l2-audio;
+and call the <constant>VIDIOC_G_AUDIO</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the device has no audio inputs, or none which combine
+with the current video input.</para>
+
+    <para>Audio inputs have one writable property, the audio mode. To
+select the current audio input <emphasis>and</emphasis> change the
+audio mode, applications initialize the
+<structfield>index</structfield> and <structfield>mode</structfield>
+fields, and the
+<structfield>reserved</structfield> array of a
+<structname>v4l2_audio</structname> structure and call the
+<constant>VIDIOC_S_AUDIO</constant> ioctl. Drivers may switch to a
+different audio mode if the request cannot be satisfied. However, this
+is a write-only ioctl, it does not return the actual new audio
+mode.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-audio">
+      <title>struct <structname>v4l2_audio</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Identifies the audio input, set by the
+driver or application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry>Name of the audio input, a NUL-terminated ASCII
+string, for example: "Line In". This information is intended for the
+user, preferably the connector label on the device itself.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capability</structfield></entry>
+	    <entry>Audio capability flags, see <xref
+		linkend="audio-capability" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>mode</structfield></entry>
+	    <entry>Audio mode flags set by drivers and applications (on
+	    <constant>VIDIOC_S_AUDIO</constant> ioctl), see <xref linkend="audio-mode" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="audio-capability">
+      <title>Audio Capability Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_AUDCAP_STEREO</constant></entry>
+	    <entry>0x00001</entry>
+	    <entry>This is a stereo input. The flag is intended to
+automatically disable stereo recording etc. when the signal is always
+monaural. The API provides no means to detect if stereo is
+<emphasis>received</emphasis>, unless the audio input belongs to a
+tuner.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_AUDCAP_AVL</constant></entry>
+	    <entry>0x00002</entry>
+	    <entry>Automatic Volume Level mode is supported.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="audio-mode">
+      <title>Audio Mode Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_AUDMODE_AVL</constant></entry>
+	    <entry>0x00001</entry>
+	    <entry>AVL mode is on.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>No audio inputs combine with the current video input,
+or the number of the selected audio input is out of bounds or it does
+not combine, or there are no audio inputs at all and the ioctl is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>I/O is in progress, the input cannot be
+switched.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-audioout.xml b/Documentation/DocBook/v4l/vidioc-g-audioout.xml
new file mode 100644
index 0000000..3632730
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-audioout.xml
@@ -0,0 +1,154 @@
+<refentry id="vidioc-g-audioout">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_AUDOUT</refname>
+    <refname>VIDIOC_S_AUDOUT</refname>
+    <refpurpose>Query or select the current audio output</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_audioout *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_audioout *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the current audio output applications zero out the
+<structfield>reserved</structfield> array of a &v4l2-audioout; and
+call the <constant>VIDIOC_G_AUDOUT</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the device has no audio inputs, or none which combine
+with the current video output.</para>
+
+    <para>Audio outputs have no writable properties. Nevertheless, to
+select the current audio output applications can initialize the
+<structfield>index</structfield> field and
+<structfield>reserved</structfield> array (which in the future may
+contain writable properties) of a
+<structname>v4l2_audioout</structname> structure and call the
+<constant>VIDIOC_S_AUDOUT</constant> ioctl. Drivers switch to the
+requested output or return the &EINVAL; when the index is out of
+bounds. This is a write-only ioctl, it does not return the current
+audio output attributes as <constant>VIDIOC_G_AUDOUT</constant>
+does.</para>
+
+    <para>Note connectors on a TV card to loop back the received audio
+signal to a sound card are not audio outputs in this sense.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-audioout">
+      <title>struct <structname>v4l2_audioout</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Identifies the audio output, set by the
+driver or application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry>Name of the audio output, a NUL-terminated ASCII
+string, for example: "Line Out". This information is intended for the
+user, preferably the connector label on the device itself.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capability</structfield></entry>
+	    <entry>Audio capability flags, none defined yet. Drivers
+must set this field to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>mode</structfield></entry>
+	    <entry>Audio mode, none defined yet. Drivers and
+applications (on <constant>VIDIOC_S_AUDOUT</constant>) must set this
+field to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>No audio outputs combine with the current video
+output, or the number of the selected audio output is out of bounds or
+it does not combine, or there are no audio outputs at all and the
+ioctl is not supported.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>I/O is in progress, the output cannot be
+switched.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-crop.xml b/Documentation/DocBook/v4l/vidioc-g-crop.xml
new file mode 100644
index 0000000..d235b1d
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-crop.xml
@@ -0,0 +1,143 @@
+<refentry id="vidioc-g-crop">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_CROP, VIDIOC_S_CROP</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_CROP</refname>
+    <refname>VIDIOC_S_CROP</refname>
+    <refpurpose>Get or set the current cropping rectangle</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_crop *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_crop *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_CROP, VIDIOC_S_CROP</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the cropping rectangle size and position
+applications set the <structfield>type</structfield> field of a
+<structname>v4l2_crop</structname> structure to the respective buffer
+(stream) type and call the <constant>VIDIOC_G_CROP</constant> ioctl
+with a pointer to this structure. The driver fills the rest of the
+structure or returns the &EINVAL; if cropping is not supported.</para>
+
+    <para>To change the cropping rectangle applications initialize the
+<structfield>type</structfield> and &v4l2-rect; substructure named
+<structfield>c</structfield> of a v4l2_crop structure and call the
+<constant>VIDIOC_S_CROP</constant> ioctl with a pointer to this
+structure.</para>
+
+    <para>The driver first adjusts the requested dimensions against
+hardware limits, &ie; the bounds given by the capture/output window,
+and it rounds to the closest possible values of horizontal and
+vertical offset, width and height. In particular the driver must round
+the vertical offset of the cropping rectangle to frame lines modulo
+two, such that the field order cannot be confused.</para>
+
+    <para>Second the driver adjusts the image size (the opposite
+rectangle of the scaling process, source or target depending on the
+data direction) to the closest size possible while maintaining the
+current horizontal and vertical scaling factor.</para>
+
+    <para>Finally the driver programs the hardware with the actual
+cropping and image parameters. <constant>VIDIOC_S_CROP</constant> is a
+write-only ioctl, it does not return the actual parameters. To query
+them applications must call <constant>VIDIOC_G_CROP</constant> and
+&VIDIOC-G-FMT;. When the parameters are unsuitable the application may
+modify the cropping or image parameters and repeat the cycle until
+satisfactory parameters have been negotiated.</para>
+
+    <para>When cropping is not supported then no parameters are
+changed and <constant>VIDIOC_S_CROP</constant> returns the
+&EINVAL;.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-crop">
+      <title>struct <structname>v4l2_crop</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of the data stream, set by the application.
+Only these types are valid here: <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
+<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
+defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
+and higher.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-rect;</entry>
+	    <entry><structfield>c</structfield></entry>
+	    <entry>Cropping rectangle. The same co-ordinate system as
+for &v4l2-cropcap; <structfield>bounds</structfield> is used.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>Cropping is not supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-ctrl.xml b/Documentation/DocBook/v4l/vidioc-g-ctrl.xml
new file mode 100644
index 0000000..8b5e6ff
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-ctrl.xml
@@ -0,0 +1,130 @@
+<refentry id="vidioc-g-ctrl">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_CTRL, VIDIOC_S_CTRL</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_CTRL</refname>
+    <refname>VIDIOC_S_CTRL</refname>
+    <refpurpose>Get or set the value of a control</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_control
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_CTRL, VIDIOC_S_CTRL</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To get the current value of a control applications
+initialize the <structfield>id</structfield> field of a struct
+<structname>v4l2_control</structname> and call the
+<constant>VIDIOC_G_CTRL</constant> ioctl with a pointer to this
+structure. To change the value of a control applications initialize
+the <structfield>id</structfield> and <structfield>value</structfield>
+fields of a struct <structname>v4l2_control</structname> and call the
+<constant>VIDIOC_S_CTRL</constant> ioctl.</para>
+
+    <para>When the <structfield>id</structfield> is invalid drivers
+return an &EINVAL;. When the <structfield>value</structfield> is out
+of bounds drivers can choose to take the closest valid value or return
+an &ERANGE;, whatever seems more appropriate. However,
+<constant>VIDIOC_S_CTRL</constant> is a write-only ioctl, it does not
+return the actual new value.</para>
+
+    <para>These ioctls work only with user controls. For other
+control classes the &VIDIOC-G-EXT-CTRLS;, &VIDIOC-S-EXT-CTRLS; or
+&VIDIOC-TRY-EXT-CTRLS; must be used.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-control">
+      <title>struct <structname>v4l2_control</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry>Identifies the control, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>value</structfield></entry>
+	    <entry>New value or current value.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-control; <structfield>id</structfield> is
+invalid.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ERANGE</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-control; <structfield>value</structfield>
+is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The control is temporarily not changeable, possibly
+because another applications took over control of the device function
+this control belongs to.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-enc-index.xml b/Documentation/DocBook/v4l/vidioc-g-enc-index.xml
new file mode 100644
index 0000000..9f242e4
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-enc-index.xml
@@ -0,0 +1,213 @@
+<refentry id="vidioc-g-enc-index">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_ENC_INDEX</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_ENC_INDEX</refname>
+    <refpurpose>Get meta data about a compressed video stream</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_enc_idx *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_ENC_INDEX</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+
+      <para>This is an <link linkend="experimental">experimental</link>
+interface and may change in the future.</para>
+    </note>
+
+    <para>The <constant>VIDIOC_G_ENC_INDEX</constant> ioctl provides
+meta data about a compressed video stream the same or another
+application currently reads from the driver, which is useful for
+random access into the stream without decoding it.</para>
+
+    <para>To read the data applications must call
+<constant>VIDIOC_G_ENC_INDEX</constant> with a pointer to a
+&v4l2-enc-idx;. On success the driver fills the
+<structfield>entry</structfield> array, stores the number of elements
+written in the <structfield>entries</structfield> field, and
+initializes the <structfield>entries_cap</structfield> field.</para>
+
+    <para>Each element of the <structfield>entry</structfield> array
+contains meta data about one picture. A
+<constant>VIDIOC_G_ENC_INDEX</constant> call reads up to
+<constant>V4L2_ENC_IDX_ENTRIES</constant> entries from a driver
+buffer, which can hold up to <structfield>entries_cap</structfield>
+entries. This number can be lower or higher than
+<constant>V4L2_ENC_IDX_ENTRIES</constant>, but not zero. When the
+application fails to read the meta data in time the oldest entries
+will be lost. When the buffer is empty or no capturing/encoding is in
+progress, <structfield>entries</structfield> will be zero.</para>
+
+    <para>Currently this ioctl is only defined for MPEG-2 program
+streams and video elementary streams.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-enc-idx">
+      <title>struct <structname>v4l2_enc_idx</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>entries</structfield></entry>
+	    <entry>The number of entries the driver stored in the
+<structfield>entry</structfield> array.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>entries_cap</structfield></entry>
+	    <entry>The number of entries the driver can
+buffer. Must be greater than zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry spanname="hspan">Reserved for future extensions.
+Drivers must set the array to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-enc-idx-entry;</entry>
+	    <entry><structfield>entry</structfield>[<constant>V4L2_ENC_IDX_ENTRIES</constant>]</entry>
+	    <entry>Meta data about a compressed video stream. Each
+element of the array corresponds to one picture, sorted in ascending
+order by their <structfield>offset</structfield>.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-enc-idx-entry">
+      <title>struct <structname>v4l2_enc_idx_entry</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u64</entry>
+	    <entry><structfield>offset</structfield></entry>
+	    <entry>The offset in bytes from the beginning of the
+compressed video stream to the beginning of this picture, that is a
+<wordasword>PES packet header</wordasword> as defined in <xref
+	    linkend="mpeg2part1" /> or a <wordasword>picture
+header</wordasword> as defined in <xref linkend="mpeg2part2" />. When
+the encoder is stopped, the driver resets the offset to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u64</entry>
+	    <entry><structfield>pts</structfield></entry>
+	    <entry>The 33 bit <wordasword>Presentation Time
+Stamp</wordasword> of this picture as defined in <xref
+		linkend="mpeg2part1" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>length</structfield></entry>
+	    <entry>The length of this picture in bytes.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>Flags containing the coding type of this picture, see <xref
+		linkend="enc-idx-flags" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry>Reserved for future extensions.
+Drivers must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="enc-idx-flags">
+      <title>Index Entry Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_ENC_IDX_FRAME_I</constant></entry>
+	    <entry>0x00</entry>
+	    <entry>This is an Intra-coded picture.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_ENC_IDX_FRAME_P</constant></entry>
+	    <entry>0x01</entry>
+	    <entry>This is a Predictive-coded picture.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_ENC_IDX_FRAME_B</constant></entry>
+	    <entry>0x02</entry>
+	    <entry>This is a Bidirectionally predictive-coded
+picture.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_ENC_IDX_FRAME_MASK</constant></entry>
+	    <entry>0x0F</entry>
+	    <entry><wordasword>AND</wordasword> the flags field with
+this mask to obtain the picture coding type.</entry>
+	  </row>
+       </tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The driver does not support this ioctl.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml b/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml
new file mode 100644
index 0000000..3aa7f8f
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml
@@ -0,0 +1,307 @@
+<refentry id="vidioc-g-ext-ctrls">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS,
+VIDIOC_TRY_EXT_CTRLS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_EXT_CTRLS</refname>
+    <refname>VIDIOC_S_EXT_CTRLS</refname>
+    <refname>VIDIOC_TRY_EXT_CTRLS</refname>
+    <refpurpose>Get or set the value of several controls, try control
+values</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_ext_controls
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS,
+VIDIOC_TRY_EXT_CTRLS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>These ioctls allow the caller to get or set multiple
+controls atomically. Control IDs are grouped into control classes (see
+<xref linkend="ctrl-class" />) and all controls in the control array
+must belong to the same control class.</para>
+
+    <para>Applications must always fill in the
+<structfield>count</structfield>,
+<structfield>ctrl_class</structfield>,
+<structfield>controls</structfield> and
+<structfield>reserved</structfield> fields of &v4l2-ext-controls;, and
+initialize the &v4l2-ext-control; array pointed to by the
+<structfield>controls</structfield> fields.</para>
+
+    <para>To get the current value of a set of controls applications
+initialize the <structfield>id</structfield>,
+<structfield>size</structfield> and <structfield>reserved2</structfield> fields
+of each &v4l2-ext-control; and call the
+<constant>VIDIOC_G_EXT_CTRLS</constant> ioctl. String controls controls
+must also set the <structfield>string</structfield> field.</para>
+
+    <para>If the <structfield>size</structfield> is too small to
+receive the control result (only relevant for pointer-type controls
+like strings), then the driver will set <structfield>size</structfield>
+to a valid value and return an &ENOSPC;. You should re-allocate the
+string memory to this new size and try again. It is possible that the
+same issue occurs again if the string has grown in the meantime. It is
+recommended to call &VIDIOC-QUERYCTRL; first and use
+<structfield>maximum</structfield>+1 as the new <structfield>size</structfield>
+value. It is guaranteed that that is sufficient memory.
+</para>
+
+    <para>To change the value of a set of controls applications
+initialize the <structfield>id</structfield>, <structfield>size</structfield>,
+<structfield>reserved2</structfield> and
+<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
+call the <constant>VIDIOC_S_EXT_CTRLS</constant> ioctl. The controls
+will only be set if <emphasis>all</emphasis> control values are
+valid.</para>
+
+    <para>To check if a set of controls have correct values applications
+initialize the <structfield>id</structfield>, <structfield>size</structfield>,
+<structfield>reserved2</structfield> and
+<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
+call the <constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctl. It is up to
+the driver whether wrong values are automatically adjusted to a valid
+value or if an error is returned.</para>
+
+    <para>When the <structfield>id</structfield> or
+<structfield>ctrl_class</structfield> is invalid drivers return an
+&EINVAL;. When the value is out of bounds drivers can choose to take
+the closest valid value or return an &ERANGE;, whatever seems more
+appropriate. In the first case the new value is set in
+&v4l2-ext-control;.</para>
+
+    <para>The driver will only set/get these controls if all control
+values are correct. This prevents the situation where only some of the
+controls were set/get. Only low-level errors (&eg; a failed i2c
+command) can still cause this situation.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-ext-control">
+      <title>struct <structname>v4l2_ext_control</structname></title>
+      <tgroup cols="4">
+	&cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry></entry>
+	    <entry>Identifies the control, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>size</structfield></entry>
+	    <entry></entry>
+	    <entry>The total size in bytes of the payload of this
+control. This is normally 0, but for pointer controls this should be
+set to the size of the memory containing the payload, or that will
+receive the payload. If <constant>VIDIOC_G_EXT_CTRLS</constant> finds
+that this value is less than is required to store
+the payload result, then it is set to a value large enough to store the
+payload result and ENOSPC is returned. Note that for string controls
+this <structfield>size</structfield> field should not be confused with the length of the string.
+This field refers to the size of the memory that contains the string.
+The actual <emphasis>length</emphasis> of the string may well be much smaller.
+</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved2</structfield>[1]</entry>
+	    <entry></entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry>(anonymous)</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__s32</entry>
+	    <entry><structfield>value</structfield></entry>
+	    <entry>New value or current value.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__s64</entry>
+	    <entry><structfield>value64</structfield></entry>
+	    <entry>New value or current value.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>char *</entry>
+	    <entry><structfield>string</structfield></entry>
+	    <entry>A pointer to a string.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-ext-controls">
+      <title>struct <structname>v4l2_ext_controls</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>ctrl_class</structfield></entry>
+	    <entry>The control class to which all controls belong, see
+<xref linkend="ctrl-class" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>count</structfield></entry>
+	    <entry>The number of controls in the controls array. May
+also be zero.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>error_idx</structfield></entry>
+	    <entry>Set by the driver in case of an error. It is the
+index of the control causing the error or equal to 'count' when the
+error is not associated with a particular control. Undefined when the
+ioctl returns 0 (success).</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-ext-control; *</entry>
+	    <entry><structfield>controls</structfield></entry>
+	    <entry>Pointer to an array of
+<structfield>count</structfield> v4l2_ext_control structures. Ignored
+if <structfield>count</structfield> equals zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="ctrl-class">
+      <title>Control classes</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_USER</constant></entry>
+	    <entry>0x980000</entry>
+	    <entry>The class containing user controls. These controls
+are described in <xref linkend="control" />. All controls that can be set
+using the &VIDIOC-S-CTRL; and &VIDIOC-G-CTRL; ioctl belong to this
+class.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_MPEG</constant></entry>
+	    <entry>0x990000</entry>
+	    <entry>The class containing MPEG compression controls.
+These controls are described in <xref
+		linkend="mpeg-controls" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_CAMERA</constant></entry>
+	    <entry>0x9a0000</entry>
+	    <entry>The class containing camera controls.
+These controls are described in <xref
+		linkend="camera-controls" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_FM_TX</constant></entry>
+	    <entry>0x9b0000</entry>
+	    <entry>The class containing FM Transmitter (FM TX) controls.
+These controls are described in <xref
+		linkend="fm-tx-controls" />.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-ext-control; <structfield>id</structfield>
+is invalid or the &v4l2-ext-controls;
+<structfield>ctrl_class</structfield> is invalid. This error code is
+also returned by the <constant>VIDIOC_S_EXT_CTRLS</constant> and
+<constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctls if two or more
+control values are in conflict.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ERANGE</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-ext-control; <structfield>value</structfield>
+is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The control is temporarily not changeable, possibly
+because another applications took over control of the device function
+this control belongs to.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOSPC</errorcode></term>
+	<listitem>
+	  <para>The space reserved for the control's payload is insufficient.
+The field <structfield>size</structfield> is set to a value that is enough
+to store the payload and this error code is returned.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
new file mode 100644
index 0000000..f701706
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
@@ -0,0 +1,456 @@
+<refentry id="vidioc-g-fbuf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_FBUF, VIDIOC_S_FBUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_FBUF</refname>
+    <refname>VIDIOC_S_FBUF</refname>
+    <refpurpose>Get or set frame buffer overlay parameters</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_framebuffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_framebuffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_FBUF, VIDIOC_S_FBUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications can use the <constant>VIDIOC_G_FBUF</constant> and
+<constant>VIDIOC_S_FBUF</constant> ioctl to get and set the
+framebuffer parameters for a <link linkend="overlay">Video
+Overlay</link> or <link linkend="osd">Video Output Overlay</link>
+(OSD). The type of overlay is implied by the device type (capture or
+output device) and can be determined with the &VIDIOC-QUERYCAP; ioctl.
+One <filename>/dev/videoN</filename> device must not support both
+kinds of overlay.</para>
+
+    <para>The V4L2 API distinguishes destructive and non-destructive
+overlays. A destructive overlay copies captured video images into the
+video memory of a graphics card. A non-destructive overlay blends
+video images into a VGA signal or graphics into a video signal.
+<wordasword>Video Output Overlays</wordasword> are always
+non-destructive.</para>
+
+    <para>To get the current parameters applications call the
+<constant>VIDIOC_G_FBUF</constant> ioctl with a pointer to a
+<structname>v4l2_framebuffer</structname> structure. The driver fills
+all fields of the structure or returns an &EINVAL; when overlays are
+not supported.</para>
+
+    <para>To set the parameters for a <wordasword>Video Output
+Overlay</wordasword>, applications must initialize the
+<structfield>flags</structfield> field of a struct
+<structname>v4l2_framebuffer</structname>. Since the framebuffer is
+implemented on the TV card all other parameters are determined by the
+driver. When an application calls <constant>VIDIOC_S_FBUF</constant>
+with a pointer to this structure, the driver prepares for the overlay
+and returns the framebuffer parameters as
+<constant>VIDIOC_G_FBUF</constant> does, or it returns an error
+code.</para>
+
+    <para>To set the parameters for a <wordasword>non-destructive
+Video Overlay</wordasword>, applications must initialize the
+<structfield>flags</structfield> field, the
+<structfield>fmt</structfield> substructure, and call
+<constant>VIDIOC_S_FBUF</constant>. Again the driver prepares for the
+overlay and returns the framebuffer parameters as
+<constant>VIDIOC_G_FBUF</constant> does, or it returns an error
+code.</para>
+
+    <para>For a <wordasword>destructive Video Overlay</wordasword>
+applications must additionally provide a
+<structfield>base</structfield> address. Setting up a DMA to a
+random memory location can jeopardize the system security, its
+stability or even damage the hardware, therefore only the superuser
+can set the parameters for a destructive video overlay.</para>
+
+    <!-- NB v4l2_pix_format is also specified in pixfmt.sgml.-->
+
+    <table pgwide="1" frame="none" id="v4l2-framebuffer">
+      <title>struct <structname>v4l2_framebuffer</structname></title>
+      <tgroup cols="4">
+	&cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capability</structfield></entry>
+	    <entry></entry>
+	    <entry>Overlay capability flags set by the driver, see
+<xref linkend="framebuffer-cap" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry></entry>
+	    <entry>Overlay control flags set by application and
+driver, see <xref linkend="framebuffer-flags" /></entry>
+	  </row>
+	  <row>
+	    <entry>void *</entry>
+	    <entry><structfield>base</structfield></entry>
+	    <entry></entry>
+	    <entry>Physical base address of the framebuffer,
+that is the address of the pixel in the top left corner of the
+framebuffer.<footnote><para>A physical base address may not suit all
+platforms. GK notes in theory we should pass something like PCI device
++ memory region + offset instead. If you encounter problems please
+discuss on the linux-media mailing list: &v4l-ml;.</para></footnote></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>This field is irrelevant to
+<wordasword>non-destructive Video Overlays</wordasword>. For
+<wordasword>destructive Video Overlays</wordasword> applications must
+provide a base address. The driver may accept only base addresses
+which are a multiple of two, four or eight bytes. For
+<wordasword>Video Output Overlays</wordasword> the driver must return
+a valid base address, so applications can find the corresponding Linux
+framebuffer device (see <xref linkend="osd" />).</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-pix-format;</entry>
+	    <entry><structfield>fmt</structfield></entry>
+	    <entry></entry>
+	    <entry>Layout of the frame buffer. The
+<structname>v4l2_pix_format</structname> structure is defined in <xref
+linkend="pixfmt" />, for clarification the fields and acceptable values
+	    are listed below:</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>width</structfield></entry>
+	    <entry>Width of the frame buffer in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>height</structfield></entry>
+	    <entry>Height of the frame buffer in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>pixelformat</structfield></entry>
+	    <entry>The pixel format of the
+framebuffer.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>For <wordasword>non-destructive Video
+Overlays</wordasword> this field only defines a format for the
+&v4l2-window; <structfield>chromakey</structfield> field.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>For <wordasword>destructive Video
+Overlays</wordasword> applications must initialize this field. For
+<wordasword>Video Output Overlays</wordasword> the driver must return
+a valid format.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Usually this is an RGB format (for example
+<link linkend="V4L2-PIX-FMT-RGB565"><constant>V4L2_PIX_FMT_RGB565</constant></link>)
+but YUV formats (only packed YUV formats when chroma keying is used,
+not including <constant>V4L2_PIX_FMT_YUYV</constant> and
+<constant>V4L2_PIX_FMT_UYVY</constant>) and the
+<constant>V4L2_PIX_FMT_PAL8</constant> format are also permitted. The
+behavior of the driver when an application requests a compressed
+format is undefined. See <xref linkend="pixfmt" /> for information on
+pixel formats.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-field;</entry>
+	    <entry><structfield>field</structfield></entry>
+	    <entry>Drivers and applications shall ignore this field.
+If applicable, the field order is selected with the &VIDIOC-S-FMT;
+ioctl, using the <structfield>field</structfield> field of
+&v4l2-window;.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>bytesperline</structfield></entry>
+	    <entry>Distance in bytes between the leftmost pixels in
+two adjacent lines.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan"><para>This field is irrelevant to
+<wordasword>non-destructive Video
+Overlays</wordasword>.</para><para>For <wordasword>destructive Video
+Overlays</wordasword> both applications and drivers can set this field
+to request padding bytes at the end of each line. Drivers however may
+ignore the requested value, returning <structfield>width</structfield>
+times bytes-per-pixel or a larger value required by the hardware. That
+implies applications can just set this field to zero to get a
+reasonable default.</para><para>For <wordasword>Video Output
+Overlays</wordasword> the driver must return a valid
+value.</para><para>Video hardware may access padding bytes, therefore
+they must reside in accessible memory. Consider for example the case
+where padding bytes after the last line of an image cross a system
+page boundary. Capture devices may write padding bytes, the value is
+undefined. Output devices ignore the contents of padding
+bytes.</para><para>When the image format is planar the
+<structfield>bytesperline</structfield> value applies to the largest
+plane and is divided by the same factor as the
+<structfield>width</structfield> field for any smaller planes. For
+example the Cb and Cr planes of a YUV 4:2:0 image have half as many
+padding bytes following each line as the Y plane. To avoid ambiguities
+drivers must return a <structfield>bytesperline</structfield> value
+rounded up to a multiple of the scale factor.</para></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>sizeimage</structfield></entry>
+	    <entry><para>This field is irrelevant to
+<wordasword>non-destructive Video Overlays</wordasword>. For
+<wordasword>destructive Video Overlays</wordasword> applications must
+initialize this field. For <wordasword>Video Output
+Overlays</wordasword> the driver must return a valid
+format.</para><para>Together with <structfield>base</structfield> it
+defines the framebuffer memory accessible by the
+driver.</para></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-colorspace;</entry>
+	    <entry><structfield>colorspace</structfield></entry>
+	    <entry>This information supplements the
+<structfield>pixelformat</structfield> and must be set by the driver,
+see <xref linkend="colorspaces" />.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u32</entry>
+	    <entry><structfield>priv</structfield></entry>
+	    <entry>Reserved for additional information about custom
+(driver defined) formats. When not used drivers and applications must
+set this field to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="framebuffer-cap">
+      <title>Frame Buffer Capability Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>The device is capable of non-destructive overlays.
+When the driver clears this flag, only destructive overlays are
+supported. There are no drivers yet which support both destructive and
+non-destructive overlays.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>The device supports clipping by chroma-keying the
+images. That is, image pixels replace pixels in the VGA or video
+signal only where the latter assume a certain color. Chroma-keying
+makes no sense for destructive overlays.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>The device supports clipping using a list of clip
+rectangles.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant></entry>
+	    <entry>0x0008</entry>
+	    <entry>The device supports clipping using a bit mask.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_LOCAL_ALPHA</constant></entry>
+	    <entry>0x0010</entry>
+	    <entry>The device supports clipping/blending using the
+alpha channel of the framebuffer or VGA signal. Alpha blending makes
+no sense for destructive overlays.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_GLOBAL_ALPHA</constant></entry>
+	    <entry>0x0020</entry>
+	    <entry>The device supports alpha blending using a global
+alpha value. Alpha blending makes no sense for destructive overlays.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_CAP_LOCAL_INV_ALPHA</constant></entry>
+	    <entry>0x0040</entry>
+	    <entry>The device supports clipping/blending using the
+inverted alpha channel of the framebuffer or VGA signal. Alpha
+blending makes no sense for destructive overlays.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="framebuffer-flags">
+      <title>Frame Buffer Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_PRIMARY</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>The framebuffer is the primary graphics surface.
+In other words, the overlay is destructive. [?]</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>The frame buffer is an overlay surface the same
+size as the capture. [?]</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan">The purpose of
+<constant>V4L2_FBUF_FLAG_PRIMARY</constant> and
+<constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear.
+Most drivers seem to ignore these flags. For compatibility with the
+<wordasword>bttv</wordasword> driver applications should set the
+<constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_CHROMAKEY</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>Use chroma-keying. The chroma-key color is
+determined by the <structfield>chromakey</structfield> field of
+&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+		linkend="overlay" />
+and
+	    <xref linkend="osd" />.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan">There are no flags to enable
+clipping using a list of clip rectangles or a bitmap. These methods
+are negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+		linkend="overlay" /> and <xref linkend="osd" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_LOCAL_ALPHA</constant></entry>
+	    <entry>0x0008</entry>
+	    <entry>Use the alpha channel of the framebuffer to clip or
+blend framebuffer pixels with video images. The blend
+function is: output = framebuffer pixel * alpha + video pixel * (1 -
+alpha). The actual alpha depth depends on the framebuffer pixel
+format.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_GLOBAL_ALPHA</constant></entry>
+	    <entry>0x0010</entry>
+	    <entry>Use a global alpha value to blend the framebuffer
+with video images. The blend function is: output = (framebuffer pixel
+* alpha + video pixel * (255 - alpha)) / 255. The alpha value is
+determined by the <structfield>global_alpha</structfield> field of
+&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
+		linkend="overlay" />
+and <xref linkend="osd" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_FBUF_FLAG_LOCAL_INV_ALPHA</constant></entry>
+	    <entry>0x0020</entry>
+	    <entry>Like
+<constant>V4L2_FBUF_FLAG_LOCAL_ALPHA</constant>, use the alpha channel
+of the framebuffer to clip or blend framebuffer pixels with video
+images, but with an inverted alpha value. The blend function is:
+output = framebuffer pixel * (1 - alpha) + video pixel * alpha. The
+actual alpha depth depends on the framebuffer pixel format.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EPERM</errorcode></term>
+	<listitem>
+	  <para><constant>VIDIOC_S_FBUF</constant> can only be called
+by a privileged user to negotiate the parameters for a destructive
+overlay.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The framebuffer parameters cannot be changed at this
+time because overlay is already enabled, or capturing is enabled
+and the hardware cannot capture and overlay simultaneously.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The ioctl is not supported or the
+<constant>VIDIOC_S_FBUF</constant> parameters are unsuitable.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-fmt.xml b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
new file mode 100644
index 0000000..7c7d1b7
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
@@ -0,0 +1,201 @@
+<refentry id="vidioc-g-fmt">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_FMT, VIDIOC_S_FMT,
+VIDIOC_TRY_FMT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_FMT</refname>
+    <refname>VIDIOC_S_FMT</refname>
+    <refname>VIDIOC_TRY_FMT</refname>
+    <refpurpose>Get or set the data format, try a format</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_format
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>These ioctls are used to negotiate the format of data
+(typically image format) exchanged between driver and
+application.</para>
+
+    <para>To query the current parameters applications set the
+<structfield>type</structfield> field of a struct
+<structname>v4l2_format</structname> to the respective buffer (stream)
+type. For example video capture devices use
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>. When the application
+calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to
+this structure the driver fills the respective member of the
+<structfield>fmt</structfield> union. In case of video capture devices
+that is the &v4l2-pix-format; <structfield>pix</structfield> member.
+When the requested buffer type is not supported drivers return an
+&EINVAL;.</para>
+
+    <para>To change the current format parameters applications
+initialize the <structfield>type</structfield> field and all
+fields of the respective <structfield>fmt</structfield>
+union member. For details see the documentation of the various devices
+types in <xref linkend="devices" />. Good practice is to query the
+current parameters first, and to
+modify only those parameters not suitable for the application. When
+the application calls the <constant>VIDIOC_S_FMT</constant> ioctl
+with a pointer to a <structname>v4l2_format</structname> structure
+the driver checks
+and adjusts the parameters against hardware abilities. Drivers
+should not return an error code unless the input is ambiguous, this is
+a mechanism to fathom device capabilities and to approach parameters
+acceptable for both the application and driver. On success the driver
+may program the hardware, allocate resources and generally prepare for
+data exchange.
+Finally the <constant>VIDIOC_S_FMT</constant> ioctl returns the
+current format parameters as <constant>VIDIOC_G_FMT</constant> does.
+Very simple, inflexible devices may even ignore all input and always
+return the default parameters. However all V4L2 devices exchanging
+data with the application must implement the
+<constant>VIDIOC_G_FMT</constant> and
+<constant>VIDIOC_S_FMT</constant> ioctl. When the requested buffer
+type is not supported drivers return an &EINVAL; on a
+<constant>VIDIOC_S_FMT</constant> attempt. When I/O is already in
+progress or the resource is not available for other reasons drivers
+return the &EBUSY;.</para>
+
+    <para>The <constant>VIDIOC_TRY_FMT</constant> ioctl is equivalent
+to <constant>VIDIOC_S_FMT</constant> with one exception: it does not
+change driver state. It can also be called at any time, never
+returning <errorcode>EBUSY</errorcode>. This function is provided to
+negotiate parameters, to learn about hardware limitations, without
+disabling I/O or possibly time consuming hardware preparations.
+Although strongly recommended drivers are not required to implement
+this ioctl.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-format">
+      <title>struct <structname>v4l2_format</structname></title>
+      <tgroup cols="4">
+	<colspec colname="c1" />
+	<colspec colname="c2" />
+	<colspec colname="c3" />
+	<colspec colname="c4" />
+	<tbody valign="top">
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry></entry>
+	    <entry>Type of the data stream, see <xref
+		linkend="v4l2-buf-type" />.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry><structfield>fmt</structfield></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-pix-format;</entry>
+	    <entry><structfield>pix</structfield></entry>
+	    <entry>Definition of an image format, see <xref
+		linkend="pixfmt" />, used by video capture and output
+devices.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-window;</entry>
+	    <entry><structfield>win</structfield></entry>
+	    <entry>Definition of an overlaid image, see <xref
+	    linkend="overlay" />, used by video overlay devices.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-vbi-format;</entry>
+	    <entry><structfield>vbi</structfield></entry>
+	    <entry>Raw VBI capture or output parameters. This is
+discussed in more detail in <xref linkend="raw-vbi" />. Used by raw VBI
+capture and output devices.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-sliced-vbi-format;</entry>
+	    <entry><structfield>sliced</structfield></entry>
+	    <entry>Sliced VBI capture or output parameters. See
+<xref linkend="sliced" /> for details. Used by sliced VBI
+capture and output devices.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u8</entry>
+	    <entry><structfield>raw_data</structfield>[200]</entry>
+	    <entry>Place holder for future extensions and custom
+(driver defined) formats with <structfield>type</structfield>
+<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The data format cannot be changed at this
+time, for example because I/O is already in progress.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-format; <structfield>type</structfield>
+field is invalid, the requested buffer type not supported, or
+<constant>VIDIOC_TRY_FMT</constant> was called and is not
+supported with this buffer type.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-frequency.xml b/Documentation/DocBook/v4l/vidioc-g-frequency.xml
new file mode 100644
index 0000000..062d720
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-frequency.xml
@@ -0,0 +1,145 @@
+<refentry id="vidioc-g-frequency">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_FREQUENCY</refname>
+    <refname>VIDIOC_S_FREQUENCY</refname>
+    <refpurpose>Get or set tuner or modulator radio
+frequency</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_frequency
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_frequency
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To get the current tuner or modulator radio frequency
+applications set the <structfield>tuner</structfield> field of a
+&v4l2-frequency; to the respective tuner or modulator number (only
+input devices have tuners, only output devices have modulators), zero
+out the <structfield>reserved</structfield> array and
+call the <constant>VIDIOC_G_FREQUENCY</constant> ioctl with a pointer
+to this structure. The driver stores the current frequency in the
+<structfield>frequency</structfield> field.</para>
+
+    <para>To change the current tuner or modulator radio frequency
+applications initialize the <structfield>tuner</structfield>,
+<structfield>type</structfield> and
+<structfield>frequency</structfield> fields, and the
+<structfield>reserved</structfield> array of a &v4l2-frequency; and
+call the <constant>VIDIOC_S_FREQUENCY</constant> ioctl with a pointer
+to this structure. When the requested frequency is not possible the
+driver assumes the closest possible value. However
+<constant>VIDIOC_S_FREQUENCY</constant> is a write-only ioctl, it does
+not return the actual new frequency.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-frequency">
+      <title>struct <structname>v4l2_frequency</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>tuner</structfield></entry>
+	    <entry>The tuner or modulator index number. This is the
+same value as in the &v4l2-input; <structfield>tuner</structfield>
+field and the &v4l2-tuner; <structfield>index</structfield> field, or
+the &v4l2-output; <structfield>modulator</structfield> field and the
+&v4l2-modulator; <structfield>index</structfield> field.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-tuner-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>The tuner type. This is the same value as in the
+&v4l2-tuner; <structfield>type</structfield> field. The field is not
+applicable to modulators, &ie; ignored by drivers.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>frequency</structfield></entry>
+	    <entry>Tuning frequency in units of 62.5 kHz, or if the
+&v4l2-tuner; or &v4l2-modulator; <structfield>capabilities</structfield> flag
+<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+	    applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <structfield>tuner</structfield> index is out of
+bounds or the value in the <structfield>type</structfield> field is
+wrong.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-input.xml b/Documentation/DocBook/v4l/vidioc-g-input.xml
new file mode 100644
index 0000000..ed076e9
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-input.xml
@@ -0,0 +1,100 @@
+<refentry id="vidioc-g-input">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_INPUT, VIDIOC_S_INPUT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_INPUT</refname>
+    <refname>VIDIOC_S_INPUT</refname>
+    <refpurpose>Query or select the current video input</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>int *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_INPUT, VIDIOC_S_INPUT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the current video input applications call the
+<constant>VIDIOC_G_INPUT</constant> ioctl with a pointer to an integer
+where the driver stores the number of the input, as in the
+&v4l2-input; <structfield>index</structfield> field. This ioctl will
+fail only when there are no video inputs, returning
+<errorcode>EINVAL</errorcode>.</para>
+
+    <para>To select a video input applications store the number of the
+desired input in an integer and call the
+<constant>VIDIOC_S_INPUT</constant> ioctl with a pointer to this
+integer. Side effects are possible. For example inputs may support
+different video standards, so the driver may implicitly switch the
+current standard. It is good practice to select an input before
+querying or negotiating any other parameters.</para>
+
+    <para>Information about video inputs is available using the
+&VIDIOC-ENUMINPUT; ioctl.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The number of the video input is out of bounds, or
+there are no video inputs at all and this ioctl is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>I/O is in progress, the input cannot be
+switched.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml b/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml
new file mode 100644
index 0000000..77394b2
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml
@@ -0,0 +1,180 @@
+<refentry id="vidioc-g-jpegcomp">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_JPEGCOMP, VIDIOC_S_JPEGCOMP</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_JPEGCOMP</refname>
+    <refname>VIDIOC_S_JPEGCOMP</refname>
+    <refpurpose></refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>v4l2_jpegcompression *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const v4l2_jpegcompression *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_JPEGCOMP, VIDIOC_S_JPEGCOMP</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>[to do]</para>
+
+    <para>Ronald Bultje elaborates:</para>
+
+    <!-- See video4linux-list@redhat.com on 16 Oct 2002, subject
+"Re: [V4L] Re: v4l2 api / Zoran v4l2_jpegcompression" -->
+
+    <para>APP is some application-specific information. The
+application can set it itself, and it'll be stored in the JPEG-encoded
+fields (eg; interlacing information for in an AVI or so). COM is the
+same, but it's comments, like 'encoded by me' or so.</para>
+
+    <para>jpeg_markers describes whether the huffman tables,
+quantization tables and the restart interval information (all
+JPEG-specific stuff) should be stored in the JPEG-encoded fields.
+These define how the JPEG field is encoded. If you omit them,
+applications assume you've used standard encoding. You usually do want
+to add them.</para>
+
+    <!-- NB VIDIOC_S_JPEGCOMP is w/o. -->
+
+    <table pgwide="1" frame="none" id="v4l2-jpegcompression">
+      <title>struct <structname>v4l2_jpegcompression</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>int</entry>
+	    <entry><structfield>quality</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>int</entry>
+	    <entry><structfield>APPn</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>int</entry>
+	    <entry><structfield>APP_len</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>char</entry>
+	    <entry><structfield>APP_data</structfield>[60]</entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>int</entry>
+	    <entry><structfield>COM_len</structfield></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>char</entry>
+	    <entry><structfield>COM_data</structfield>[60]</entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>jpeg_markers</structfield></entry>
+	    <entry>See <xref linkend="jpeg-markers" />.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="jpeg-markers">
+      <title>JPEG Markers Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_JPEG_MARKER_DHT</constant></entry>
+	    <entry>(1&lt;&lt;3)</entry>
+	    <entry>Define Huffman Tables</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_JPEG_MARKER_DQT</constant></entry>
+	    <entry>(1&lt;&lt;4)</entry>
+	    <entry>Define Quantization Tables</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_JPEG_MARKER_DRI</constant></entry>
+	    <entry>(1&lt;&lt;5)</entry>
+	    <entry>Define Restart Interval</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_JPEG_MARKER_COM</constant></entry>
+	    <entry>(1&lt;&lt;6)</entry>
+	    <entry>Comment segment</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_JPEG_MARKER_APP</constant></entry>
+	    <entry>(1&lt;&lt;7)</entry>
+	    <entry>App segment, driver will always use APP0</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>This ioctl is not supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-modulator.xml b/Documentation/DocBook/v4l/vidioc-g-modulator.xml
new file mode 100644
index 0000000..15ce660
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-modulator.xml
@@ -0,0 +1,246 @@
+<refentry id="vidioc-g-modulator">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_MODULATOR, VIDIOC_S_MODULATOR</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_MODULATOR</refname>
+    <refname>VIDIOC_S_MODULATOR</refname>
+    <refpurpose>Get or set modulator attributes</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_modulator
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_modulator
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_MODULATOR, VIDIOC_S_MODULATOR</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a modulator applications initialize
+the <structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-modulator; and
+call the <constant>VIDIOC_G_MODULATOR</constant> ioctl with a pointer
+to this structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all modulators
+applications shall begin at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>.</para>
+
+    <para>Modulators have two writable properties, an audio
+modulation set and the radio frequency. To change the modulated audio
+subprograms, applications initialize the <structfield>index
+</structfield> and <structfield>txsubchans</structfield> fields and the
+<structfield>reserved</structfield> array and call the
+<constant>VIDIOC_S_MODULATOR</constant> ioctl. Drivers may choose a
+different audio modulation if the request cannot be satisfied. However
+this is a write-only ioctl, it does not return the actual audio
+modulation selected.</para>
+
+    <para>To change the radio frequency the &VIDIOC-S-FREQUENCY; ioctl
+is available.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-modulator">
+      <title>struct <structname>v4l2_modulator</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Identifies the modulator, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry>Name of the modulator, a NUL-terminated ASCII
+string. This information is intended for the user.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capability</structfield></entry>
+	    <entry>Modulator capability flags. No flags are defined
+for this field, the tuner flags in &v4l2-tuner;
+are used accordingly. The audio flags indicate the ability
+to encode audio subprograms. They will <emphasis>not</emphasis>
+change for example with the current video standard.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>rangelow</structfield></entry>
+	    <entry>The lowest tunable frequency in units of 62.5
+KHz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>rangehigh</structfield></entry>
+	    <entry>The highest tunable frequency in units of 62.5
+KHz, or if the <structfield>capability</structfield> flag
+<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>txsubchans</structfield></entry>
+	    <entry>With this field applications can determine how
+audio sub-carriers shall be modulated. It contains a set of flags as
+defined in <xref linkend="modulator-txsubchans" />. Note the tuner
+<structfield>rxsubchans</structfield> flags are reused, but the
+semantics are different. Video output devices are assumed to have an
+analog or PCM audio input with 1-3 channels. The
+<structfield>txsubchans</structfield> flags select one or more
+channels for modulation, together with some audio subprogram
+indicator, for example a stereo pilot tone.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="modulator-txsubchans">
+      <title>Modulator Audio Transmission Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>Modulate channel 1 as mono audio, when the input
+has more channels, a down-mix of channel 1 and 2. This flag does not
+combine with <constant>V4L2_TUNER_SUB_STEREO</constant> or
+<constant>V4L2_TUNER_SUB_LANG1</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_STEREO</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>Modulate channel 1 and 2 as left and right
+channel of a stereo audio signal. When the input has only one channel
+or two channels and <constant>V4L2_TUNER_SUB_SAP</constant> is also
+set, channel 1 is encoded as left and right channel. This flag does
+not combine with <constant>V4L2_TUNER_SUB_MONO</constant> or
+<constant>V4L2_TUNER_SUB_LANG1</constant>. When the driver does not
+support stereo audio it shall fall back to mono.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_LANG1</constant></entry>
+	    <entry>0x0008</entry>
+	    <entry>Modulate channel 1 and 2 as primary and secondary
+language of a bilingual audio signal. When the input has only one
+channel it is used for both languages. It is not possible to encode
+the primary or secondary language only. This flag does not combine
+with <constant>V4L2_TUNER_SUB_MONO</constant>,
+<constant>V4L2_TUNER_SUB_STEREO</constant> or
+<constant>V4L2_TUNER_SUB_SAP</constant>. If the hardware does not
+support the respective audio matrix, or the current video standard
+does not permit bilingual audio the
+<constant>VIDIOC_S_MODULATOR</constant> ioctl shall return an &EINVAL;
+and the driver shall fall back to mono or stereo mode.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_LANG2</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>Same effect as
+<constant>V4L2_TUNER_SUB_SAP</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_SAP</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>When combined with <constant>V4L2_TUNER_SUB_MONO
+</constant> the first channel is encoded as mono audio, the last
+channel as Second Audio Program. When the input has only one channel
+it is used for both audio tracks. When the input has three channels
+the mono track is a down-mix of channel 1 and 2. When combined with
+<constant>V4L2_TUNER_SUB_STEREO</constant> channel 1 and 2 are
+encoded as left and right stereo audio, channel 3 as Second Audio
+Program. When the input has only two channels, the first is encoded as
+left and right channel and the second as SAP. When the input has only
+one channel it is used for all audio tracks. It is not possible to
+encode a Second Audio Program only. This flag must combine with
+<constant>V4L2_TUNER_SUB_MONO</constant> or
+<constant>V4L2_TUNER_SUB_STEREO</constant>. If the hardware does not
+support the respective audio matrix, or the current video standard
+does not permit SAP the <constant>VIDIOC_S_MODULATOR</constant> ioctl
+shall return an &EINVAL; and driver shall fall back to mono or stereo
+mode.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_RDS</constant></entry>
+	    <entry>0x0010</entry>
+	    <entry>Enable the RDS encoder for a radio FM transmitter.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-modulator;
+<structfield>index</structfield> is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-output.xml b/Documentation/DocBook/v4l/vidioc-g-output.xml
new file mode 100644
index 0000000..3ea8c0e
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-output.xml
@@ -0,0 +1,100 @@
+<refentry id="vidioc-g-output">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_OUTPUT</refname>
+    <refname>VIDIOC_S_OUTPUT</refname>
+    <refpurpose>Query or select the current video output</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>int *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the current video output applications call the
+<constant>VIDIOC_G_OUTPUT</constant> ioctl with a pointer to an integer
+where the driver stores the number of the output, as in the
+&v4l2-output; <structfield>index</structfield> field. This ioctl
+will fail only when there are no video outputs, returning the
+&EINVAL;.</para>
+
+    <para>To select a video output applications store the number of the
+desired output in an integer and call the
+<constant>VIDIOC_S_OUTPUT</constant> ioctl with a pointer to this integer.
+Side effects are possible. For example outputs may support different
+video standards, so the driver may implicitly switch the current
+standard. It is good practice to select an output before querying or
+negotiating any other parameters.</para>
+
+    <para>Information about video outputs is available using the
+&VIDIOC-ENUMOUTPUT; ioctl.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The number of the video output is out of bounds, or
+there are no video outputs at all and this ioctl is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>I/O is in progress, the output cannot be
+switched.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-parm.xml b/Documentation/DocBook/v4l/vidioc-g-parm.xml
new file mode 100644
index 0000000..78332d3
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-parm.xml
@@ -0,0 +1,332 @@
+<refentry id="vidioc-g-parm">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_PARM, VIDIOC_S_PARM</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_PARM</refname>
+    <refname>VIDIOC_S_PARM</refname>
+    <refpurpose>Get or set streaming parameters</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>v4l2_streamparm *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_PARM, VIDIOC_S_PARM</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The current video standard determines a nominal number of
+frames per second. If less than this number of frames is to be
+captured or output, applications can request frame skipping or
+duplicating on the driver side. This is especially useful when using
+the <function>read()</function> or <function>write()</function>, which
+are not augmented by timestamps or sequence counters, and to avoid
+unneccessary data copying.</para>
+
+    <para>Further these ioctls can be used to determine the number of
+buffers used internally by a driver in read/write mode. For
+implications see the section discussing the &func-read;
+function.</para>
+
+    <para>To get and set the streaming parameters applications call
+the <constant>VIDIOC_G_PARM</constant> and
+<constant>VIDIOC_S_PARM</constant> ioctl, respectively. They take a
+pointer to a struct <structname>v4l2_streamparm</structname> which
+contains a union holding separate parameters for input and output
+devices.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-streamparm">
+      <title>struct <structname>v4l2_streamparm</structname></title>
+      <tgroup cols="4">
+	&cs-ustr;
+	<tbody valign="top">
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry></entry>
+	    <entry>The buffer (stream) type, same as &v4l2-format;
+<structfield>type</structfield>, set by the application.</entry>
+	  </row>
+	  <row>
+	    <entry>union</entry>
+	    <entry><structfield>parm</structfield></entry>
+	    <entry></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-captureparm;</entry>
+	    <entry><structfield>capture</structfield></entry>
+	    <entry>Parameters for capture devices, used when
+<structfield>type</structfield> is
+<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>&v4l2-outputparm;</entry>
+	    <entry><structfield>output</structfield></entry>
+	    <entry>Parameters for output devices, used when
+<structfield>type</structfield> is
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__u8</entry>
+	    <entry><structfield>raw_data</structfield>[200]</entry>
+	    <entry>A place holder for future extensions and custom
+(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
+higher.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-captureparm">
+      <title>struct <structname>v4l2_captureparm</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capability</structfield></entry>
+	    <entry>See <xref linkend="parm-caps" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capturemode</structfield></entry>
+	    <entry>Set by drivers and applications, see <xref linkend="parm-flags" />.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>timeperframe</structfield></entry>
+	    <entry><para>This is is the desired period between
+successive frames captured by the driver, in seconds. The
+field is intended to skip frames on the driver side, saving I/O
+bandwidth.</para><para>Applications store here the desired frame
+period, drivers return the actual frame period, which must be greater
+or equal to the nominal frame period determined by the current video
+standard (&v4l2-standard; <structfield>frameperiod</structfield>
+field). Changing the video standard (also implicitly by switching the
+video input) may reset this parameter to the nominal frame period. To
+reset manually applications can just set this field to
+zero.</para><para>Drivers support this function only when they set the
+<constant>V4L2_CAP_TIMEPERFRAME</constant> flag in the
+<structfield>capability</structfield> field.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>extendedmode</structfield></entry>
+	    <entry>Custom (driver specific) streaming parameters. When
+unused, applications and drivers must set this field to zero.
+Applications using this field should check the driver name and
+version, see <xref linkend="querycap" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>readbuffers</structfield></entry>
+	    <entry>Applications set this field to the desired number
+of buffers used internally by the driver in &func-read; mode. Drivers
+return the actual number of buffers. When an application requests zero
+buffers, drivers should just return the current setting rather than
+the minimum or an error code. For details see <xref
+		linkend="rw" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-outputparm">
+      <title>struct <structname>v4l2_outputparm</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capability</structfield></entry>
+	    <entry>See <xref linkend="parm-caps" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>outputmode</structfield></entry>
+	    <entry>Set by drivers and applications, see <xref
+	    linkend="parm-flags" />.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-fract;</entry>
+	    <entry><structfield>timeperframe</structfield></entry>
+	    <entry>This is is the desired period between
+successive frames output by the driver, in seconds.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan"><para>The field is intended to
+repeat frames on the driver side in &func-write; mode (in streaming
+mode timestamps can be used to throttle the output), saving I/O
+bandwidth.</para><para>Applications store here the desired frame
+period, drivers return the actual frame period, which must be greater
+or equal to the nominal frame period determined by the current video
+standard (&v4l2-standard; <structfield>frameperiod</structfield>
+field). Changing the video standard (also implicitly by switching the
+video output) may reset this parameter to the nominal frame period. To
+reset manually applications can just set this field to
+zero.</para><para>Drivers support this function only when they set the
+<constant>V4L2_CAP_TIMEPERFRAME</constant> flag in the
+<structfield>capability</structfield> field.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>extendedmode</structfield></entry>
+	    <entry>Custom (driver specific) streaming parameters. When
+unused, applications and drivers must set this field to zero.
+Applications using this field should check the driver name and
+version, see <xref linkend="querycap" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>writebuffers</structfield></entry>
+	    <entry>Applications set this field to the desired number
+of buffers used internally by the driver in
+<function>write()</function> mode. Drivers return the actual number of
+buffers. When an application requests zero buffers, drivers should
+just return the current setting rather than the minimum or an error
+code. For details see <xref linkend="rw" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="parm-caps">
+      <title>Streaming Parameters Capabilites</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CAP_TIMEPERFRAME</constant></entry>
+	    <entry>0x1000</entry>
+	    <entry>The frame skipping/repeating controlled by the
+<structfield>timeperframe</structfield> field is supported.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="parm-flags">
+      <title>Capture Parameters Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_MODE_HIGHQUALITY</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry><para>High quality imaging mode. High quality mode
+is intended for still imaging applications. The idea is to get the
+best possible image quality that the hardware can deliver. It is not
+defined how the driver writer may achieve that; it will depend on the
+hardware and the ingenuity of the driver writer. High quality mode is
+a different mode from the the regular motion video capture modes. In
+high quality mode:<itemizedlist>
+		  <listitem>
+		    <para>The driver may be able to capture higher
+resolutions than for motion capture.</para>
+		  </listitem>
+		  <listitem>
+		    <para>The driver may support fewer pixel formats
+than motion capture (eg; true color).</para>
+		  </listitem>
+		  <listitem>
+		    <para>The driver may capture and arithmetically
+combine multiple successive fields or frames to remove color edge
+artifacts and reduce the noise in the video data.
+</para>
+		  </listitem>
+		  <listitem>
+		    <para>The driver may capture images in slices like
+a scanner in order to handle larger format images than would otherwise
+be possible. </para>
+		  </listitem>
+		  <listitem>
+		    <para>An image capture operation may be
+significantly slower than motion capture. </para>
+		  </listitem>
+		  <listitem>
+		    <para>Moving objects in the image might have
+excessive motion blur. </para>
+		  </listitem>
+		  <listitem>
+		    <para>Capture might only work through the
+<function>read()</function> call.</para>
+		  </listitem>
+		</itemizedlist></para></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>This ioctl is not supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-priority.xml b/Documentation/DocBook/v4l/vidioc-g-priority.xml
new file mode 100644
index 0000000..5fb0019
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-priority.xml
@@ -0,0 +1,144 @@
+<refentry id="vidioc-g-priority">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_PRIORITY</refname>
+    <refname>VIDIOC_S_PRIORITY</refname>
+    <refpurpose>Query or request the access priority associated with a
+file descriptor</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>enum v4l2_priority *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const enum v4l2_priority *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para>Pointer to an enum v4l2_priority type.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the current access priority
+applications call the <constant>VIDIOC_G_PRIORITY</constant> ioctl
+with a pointer to an enum v4l2_priority variable where the driver stores
+the current priority.</para>
+
+    <para>To request an access priority applications store the
+desired priority in an enum v4l2_priority variable and call
+<constant>VIDIOC_S_PRIORITY</constant> ioctl with a pointer to this
+variable.</para>
+
+    <table frame="none" pgwide="1" id="v4l2-priority">
+      <title>enum v4l2_priority</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_PRIORITY_UNSET</constant></entry>
+	    <entry>0</entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_PRIORITY_BACKGROUND</constant></entry>
+	    <entry>1</entry>
+	    <entry>Lowest priority, usually applications running in
+background, for example monitoring VBI transmissions. A proxy
+application running in user space will be necessary if multiple
+applications want to read from a device at this priority.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_PRIORITY_INTERACTIVE</constant></entry>
+	    <entry>2</entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_PRIORITY_DEFAULT</constant></entry>
+	    <entry>2</entry>
+	    <entry>Medium priority, usually applications started and
+interactively controlled by the user. For example TV viewers, Teletext
+browsers, or just "panel" applications to change the channel or video
+controls. This is the default priority unless an application requests
+another.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_PRIORITY_RECORD</constant></entry>
+	    <entry>3</entry>
+	    <entry>Highest priority. Only one file descriptor can have
+this priority, it blocks any other fd from changing device properties.
+Usually applications which must not be interrupted, like video
+recording.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The requested priority value is invalid, or the
+driver does not support access priorities.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>Another application already requested higher
+priority.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml b/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml
new file mode 100644
index 0000000..10e721b
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml
@@ -0,0 +1,264 @@
+<refentry id="vidioc-g-sliced-vbi-cap">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_SLICED_VBI_CAP</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_SLICED_VBI_CAP</refname>
+    <refpurpose>Query sliced VBI capabilities</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_sliced_vbi_cap *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_SLICED_VBI_CAP</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To find out which data services are supported by a sliced
+VBI capture or output device, applications initialize the
+<structfield>type</structfield> field of a &v4l2-sliced-vbi-cap;,
+clear the <structfield>reserved</structfield> array and
+call the <constant>VIDIOC_G_SLICED_VBI_CAP</constant> ioctl. The
+driver fills in the remaining fields or returns an &EINVAL; if the
+sliced VBI API is unsupported or <structfield>type</structfield>
+is invalid.</para>
+
+    <para>Note the <structfield>type</structfield> field was added,
+and the ioctl changed from read-only to write-read, in Linux 2.6.19.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-sliced-vbi-cap">
+      <title>struct <structname>v4l2_sliced_vbi_cap</structname></title>
+      <tgroup cols="5">
+	<colspec colname="c1" colwidth="3*" />
+	<colspec colname="c2" colwidth="3*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="2*" />
+	<colspec colname="c5" colwidth="2*" />
+	<spanspec spanname="hspan" namest="c3" nameend="c5" />
+	<tbody valign="top">
+	  <row>
+	    <entry>__u16</entry>
+	    <entry><structfield>service_set</structfield></entry>
+	    <entry spanname="hspan">A set of all data services
+supported by the driver. Equal to the union of all elements of the
+<structfield>service_lines </structfield> array.</entry>
+	  </row>
+	  <row>
+	    <entry>__u16</entry>
+	    <entry><structfield>service_lines</structfield>[2][24]</entry>
+	    <entry spanname="hspan">Each element of this array
+contains a set of data services the hardware can look for or insert
+into a particular scan line. Data services are defined in <xref
+		linkend="vbi-services" />. Array indices map to ITU-R
+line numbers (see also <xref
+		linkend="vbi-525" /> and <xref
+linkend="vbi-625" />) as follows:</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry>Element</entry>
+	    <entry>525 line systems</entry>
+	    <entry>625 line systems</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[0][1]</entry>
+	    <entry align="center">1</entry>
+	    <entry align="center">1</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[0][23]</entry>
+	    <entry align="center">23</entry>
+	    <entry align="center">23</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[1][1]</entry>
+	    <entry align="center">264</entry>
+	    <entry align="center">314</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><structfield>service_lines</structfield>[1][23]</entry>
+	    <entry align="center">286</entry>
+	    <entry align="center">336</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry spanname="hspan">The number of VBI lines the
+hardware can capture or output per frame, or the number of services it
+can identify on a given line may be limited. For example on PAL line
+16 the hardware may be able to look for a VPS or Teletext signal, but
+not both at the same time. Applications can learn about these limits
+using the &VIDIOC-S-FMT; ioctl as described in <xref
+		linkend="sliced" />.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry spanname="hspan">Drivers must set
+<structfield>service_lines</structfield>[0][0] and
+<structfield>service_lines</structfield>[1][0] to zero.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of the data stream, see <xref
+		  linkend="v4l2-buf-type" />. Should be
+<constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> or
+<constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[3]</entry>
+	    <entry spanname="hspan">This array is reserved for future
+extensions. Applications and drivers must set it to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <!-- See also dev-sliced-vbi.sgml -->
+    <table pgwide="1" frame="none" id="vbi-services">
+      <title>Sliced VBI services</title>
+      <tgroup cols="5">
+	<colspec colname="c1" colwidth="2*" />
+	<colspec colname="c2" colwidth="1*" />
+	<colspec colname="c3" colwidth="1*" />
+	<colspec colname="c4" colwidth="2*" />
+	<colspec colname="c5" colwidth="2*" />
+	<spanspec spanname='rlp' namest='c3' nameend='c5' />
+	<thead>
+	  <row>
+	    <entry>Symbol</entry>
+	    <entry>Value</entry>
+	    <entry>Reference</entry>
+	    <entry>Lines, usually</entry>
+	    <entry>Payload</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_SLICED_TELETEXT_B</constant> (Teletext
+System B)</entry>
+	    <entry>0x0001</entry>
+	    <entry><xref linkend="ets300706" />, <xref linkend="itu653" /></entry>
+	    <entry>PAL/SECAM line 7-22, 320-335 (second field 7-22)</entry>
+	    <entry>Last 42 of the 45 byte Teletext packet, that is
+without clock run-in and framing code, lsb first transmitted.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_VPS</constant></entry>
+	    <entry>0x0400</entry>
+	    <entry><xref linkend="ets300231" /></entry>
+	    <entry>PAL line 16</entry>
+	    <entry>Byte number 3 to 15 according to Figure 9 of
+ETS&nbsp;300&nbsp;231, lsb first transmitted.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_CAPTION_525</constant></entry>
+	    <entry>0x1000</entry>
+	    <entry><xref linkend="eia608" /></entry>
+	    <entry>NTSC line 21, 284 (second field 21)</entry>
+	    <entry>Two bytes in transmission order, including parity
+bit, lsb first transmitted.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_WSS_625</constant></entry>
+	    <entry>0x4000</entry>
+	    <entry><xref linkend="en300294" />, <xref linkend="itu1119" /></entry>
+	    <entry>PAL/SECAM line 23</entry>
+	    <entry><screen>
+Byte        0                 1
+     msb         lsb  msb           lsb
+Bit  7 6 5 4 3 2 1 0  x x 13 12 11 10 9
+</screen></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_VBI_525</constant></entry>
+	    <entry>0x1000</entry>
+	    <entry spanname="rlp">Set of services applicable to 525
+line systems.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SLICED_VBI_625</constant></entry>
+	    <entry>0x4401</entry>
+	    <entry spanname="rlp">Set of services applicable to 625
+line systems.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The device does not support sliced VBI capturing or
+output, or the value in the <structfield>type</structfield> field is
+wrong.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-std.xml b/Documentation/DocBook/v4l/vidioc-g-std.xml
new file mode 100644
index 0000000..b6f5d26
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-std.xml
@@ -0,0 +1,99 @@
+<refentry id="vidioc-g-std">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_STD, VIDIOC_S_STD</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_STD</refname>
+    <refname>VIDIOC_S_STD</refname>
+    <refpurpose>Query or select the video standard of the current input</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>v4l2_std_id
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const v4l2_std_id
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_STD, VIDIOC_S_STD</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query and select the current video standard applications
+use the <constant>VIDIOC_G_STD</constant> and <constant>VIDIOC_S_STD</constant> ioctls which take a pointer to a
+&v4l2-std-id; type as argument. <constant>VIDIOC_G_STD</constant> can
+return a single flag or a set of flags as in &v4l2-standard; field
+<structfield>id</structfield>. The flags must be unambiguous such
+that they appear in only one enumerated <structname>v4l2_standard</structname> structure.</para>
+
+    <para><constant>VIDIOC_S_STD</constant> accepts one or more
+flags, being a write-only ioctl it does not return the actual new standard as
+<constant>VIDIOC_G_STD</constant> does. When no flags are given or
+the current input does not support the requested standard the driver
+returns an &EINVAL;. When the standard set is ambiguous drivers may
+return <errorcode>EINVAL</errorcode> or choose any of the requested
+standards.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>This ioctl is not supported, or the
+<constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/v4l/vidioc-g-tuner.xml
new file mode 100644
index 0000000..bd98c73
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-tuner.xml
@@ -0,0 +1,535 @@
+<refentry id="vidioc-g-tuner">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_G_TUNER, VIDIOC_S_TUNER</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_G_TUNER</refname>
+    <refname>VIDIOC_S_TUNER</refname>
+    <refpurpose>Get or set tuner attributes</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_tuner
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const struct v4l2_tuner
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_G_TUNER, VIDIOC_S_TUNER</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a tuner applications initialize the
+<structfield>index</structfield> field and zero out the
+<structfield>reserved</structfield> array of a &v4l2-tuner; and call the
+<constant>VIDIOC_G_TUNER</constant> ioctl with a pointer to this
+structure. Drivers fill the rest of the structure or return an
+&EINVAL; when the index is out of bounds. To enumerate all tuners
+applications shall begin at index zero, incrementing by one until the
+driver returns <errorcode>EINVAL</errorcode>.</para>
+
+    <para>Tuners have two writable properties, the audio mode and
+the radio frequency. To change the audio mode, applications initialize
+the <structfield>index</structfield>,
+<structfield>audmode</structfield> and
+<structfield>reserved</structfield> fields and call the
+<constant>VIDIOC_S_TUNER</constant> ioctl. This will
+<emphasis>not</emphasis> change the current tuner, which is determined
+by the current video input. Drivers may choose a different audio mode
+if the requested mode is invalid or unsupported. Since this is a
+<!-- FIXME -->write-only ioctl, it does not return the actually
+selected audio mode.</para>
+
+    <para>To change the radio frequency the &VIDIOC-S-FREQUENCY; ioctl
+is available.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-tuner">
+      <title>struct <structname>v4l2_tuner</structname></title>
+      <tgroup cols="3">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="1*" />
+	<colspec colname="c3" colwidth="1*" />
+	<colspec colname="c4" colwidth="1*" />
+	<spanspec spanname="hspan" namest="c3" nameend="c4" />
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry spanname="hspan">Identifies the tuner, set by the
+application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry spanname="hspan"><para>Name of the tuner, a
+NUL-terminated ASCII string. This information is intended for the
+user.<!-- FIXME Video inputs already have a name, the purpose of this
+field is not quite clear.--></para></entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-tuner-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry spanname="hspan">Type of the tuner, see <xref
+		linkend="v4l2-tuner-type" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capability</structfield></entry>
+	    <entry spanname="hspan"><para>Tuner capability flags, see
+<xref linkend="tuner-capability" />. Audio flags indicate the ability
+to decode audio subprograms. They will <emphasis>not</emphasis>
+change, for example with the current video standard.</para><para>When
+the structure refers to a radio tuner only the
+<constant>V4L2_TUNER_CAP_LOW</constant>,
+<constant>V4L2_TUNER_CAP_STEREO</constant> and
+<constant>V4L2_TUNER_CAP_RDS</constant> flags can be set.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>rangelow</structfield></entry>
+	    <entry spanname="hspan">The lowest tunable frequency in
+units of 62.5 kHz, or if the <structfield>capability</structfield>
+flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>rangehigh</structfield></entry>
+	    <entry spanname="hspan">The highest tunable frequency in
+units of 62.5 kHz, or if the <structfield>capability</structfield>
+flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
+Hz.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>rxsubchans</structfield></entry>
+	    <entry spanname="hspan"><para>Some tuners or audio
+decoders can determine the received audio subprograms by analyzing
+audio carriers, pilot tones or other indicators. To pass this
+information drivers set flags defined in <xref
+		  linkend="tuner-rxsubchans" /> in this field. For
+example:</para></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
+	    <entry>receiving mono audio</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><constant>STEREO | SAP</constant></entry>
+	    <entry>receiving stereo audio and a secondary audio
+program</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><constant>MONO | STEREO</constant></entry>
+	    <entry>receiving mono or stereo audio, the hardware cannot
+distinguish</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><constant>LANG1 | LANG2</constant></entry>
+	    <entry>receiving bilingual audio</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry><constant>MONO | STEREO | LANG1 | LANG2</constant></entry>
+	    <entry>receiving mono, stereo or bilingual
+audio</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry spanname="hspan"><para>When the
+<constant>V4L2_TUNER_CAP_STEREO</constant>,
+<constant>_LANG1</constant>, <constant>_LANG2</constant> or
+<constant>_SAP</constant> flag is cleared in the
+<structfield>capability</structfield> field, the corresponding
+<constant>V4L2_TUNER_SUB_</constant> flag must not be set
+here.</para><para>This field is valid only if this is the tuner of the
+current video input, or when the structure refers to a radio
+tuner.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>audmode</structfield></entry>
+	    <entry spanname="hspan"><para>The selected audio mode, see
+<xref linkend="tuner-audmode" /> for valid values. The audio mode does
+not affect audio subprogram detection, and like a <link
+linkend="control">control</link> it does not automatically change
+unless the requested mode is invalid or unsupported. See <xref
+		  linkend="tuner-matrix" /> for possible results when
+the selected and received audio programs do not
+match.</para><para>Currently this is the only field of struct
+<structname>v4l2_tuner</structname> applications can
+change.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>signal</structfield></entry>
+	    <entry spanname="hspan">The signal strength if known, ranging
+from 0 to 65535. Higher values indicate a better signal.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>afc</structfield></entry>
+	    <entry spanname="hspan">Automatic frequency control: When the
+<structfield>afc</structfield> value is negative, the frequency is too
+low, when positive too high.<!-- FIXME need example what to do when it never
+settles at zero, &ie; range is what? --></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry spanname="hspan">Reserved for future extensions. Drivers and
+applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-tuner-type">
+      <title>enum v4l2_tuner_type</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_TUNER_RADIO</constant></entry>
+	    <entry>1</entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_ANALOG_TV</constant></entry>
+	    <entry>2</entry>
+	    <entry></entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="tuner-capability">
+      <title>Tuner and Modulator Capability Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_TUNER_CAP_LOW</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>When set, tuning frequencies are expressed in units of
+62.5&nbsp;Hz, otherwise in units of 62.5&nbsp;kHz.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_CAP_NORM</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>This is a multi-standard tuner; the video standard
+can or must be switched. (B/G PAL tuners for example are typically not
+      considered multi-standard because the video standard is automatically
+      determined from the frequency band.) The set of supported video
+      standards is available from the &v4l2-input; pointing to this tuner,
+      see the description of ioctl &VIDIOC-ENUMINPUT; for details. Only
+      <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
+	  </row>
+	  <row>
+	<entry><constant>V4L2_TUNER_CAP_STEREO</constant></entry>
+	<entry>0x0010</entry>
+	<entry>Stereo audio reception is supported.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_CAP_LANG1</constant></entry>
+	    <entry>0x0040</entry>
+	    <entry>Reception of the primary language of a bilingual
+audio program is supported. Bilingual audio is a feature of
+two-channel systems, transmitting the primary language monaural on the
+main audio carrier and a secondary language monaural on a second
+carrier. Only
+      <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_CAP_LANG2</constant></entry>
+	    <entry>0x0020</entry>
+	    <entry>Reception of the secondary language of a bilingual
+audio program is supported. Only
+      <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_CAP_SAP</constant></entry>
+	    <entry>0x0020</entry>
+	    <entry><para>Reception of a secondary audio program is
+supported. This is a feature of the BTSC system which accompanies the
+NTSC video standard. Two audio carriers are available for mono or
+stereo transmissions of a primary language, and an independent third
+carrier for a monaural secondary language. Only
+      <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</para><para>Note the
+<constant>V4L2_TUNER_CAP_LANG2</constant> and
+<constant>V4L2_TUNER_CAP_SAP</constant> flags are synonyms.
+<constant>V4L2_TUNER_CAP_SAP</constant> applies when the tuner
+supports the <constant>V4L2_STD_NTSC_M</constant> video
+standard.</para><!-- FIXME what if PAL+NTSC and Bi but not SAP? --></entry>
+	  </row>
+	  <row>
+	<entry><constant>V4L2_TUNER_CAP_RDS</constant></entry>
+	<entry>0x0080</entry>
+	<entry>RDS capture is supported. This capability is only valid for
+radio tuners.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="tuner-rxsubchans">
+      <title>Tuner Audio Reception Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>The tuner receives a mono audio signal.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_STEREO</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>The tuner receives a stereo audio signal.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_LANG1</constant></entry>
+	    <entry>0x0008</entry>
+	    <entry>The tuner receives the primary language of a
+bilingual audio signal. Drivers must clear this flag when the current
+video standard is <constant>V4L2_STD_NTSC_M</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_LANG2</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>The tuner receives the secondary language of a
+bilingual audio signal (or a second audio program).</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_SAP</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>The tuner receives a Second Audio Program. Note the
+<constant>V4L2_TUNER_SUB_LANG2</constant> and
+<constant>V4L2_TUNER_SUB_SAP</constant> flags are synonyms. The
+<constant>V4L2_TUNER_SUB_SAP</constant> flag applies when the
+current video standard is <constant>V4L2_STD_NTSC_M</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_SUB_RDS</constant></entry>
+	    <entry>0x0010</entry>
+	    <entry>The tuner receives an RDS channel.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="tuner-audmode">
+      <title>Tuner Audio Modes</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_TUNER_MODE_MONO</constant></entry>
+	    <entry>0</entry>
+	    <entry>Play mono audio. When the tuner receives a stereo
+signal this a down-mix of the left and right channel. When the tuner
+receives a bilingual or SAP signal this mode selects the primary
+language.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_MODE_STEREO</constant></entry>
+	    <entry>1</entry>
+	    <entry><para>Play stereo audio. When the tuner receives
+bilingual audio it may play different languages on the left and right
+channel or the primary language is played on both channels.</para><para>Playing
+different languages in this mode is
+deprecated. New drivers should do this only in
+<constant>MODE_LANG1_LANG2</constant>.</para><para>When the tuner
+receives no stereo signal or does not support stereo reception the
+driver shall fall back to <constant>MODE_MONO</constant>.</para></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_MODE_LANG1</constant></entry>
+	    <entry>3</entry>
+	    <entry>Play the primary language, mono or stereo. Only
+<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
+mode.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_MODE_LANG2</constant></entry>
+	    <entry>2</entry>
+	    <entry>Play the secondary language, mono. When the tuner
+receives no bilingual audio or SAP, or their reception is not
+supported the driver shall fall back to mono or stereo mode. Only
+<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
+mode.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_MODE_SAP</constant></entry>
+	    <entry>2</entry>
+	    <entry>Play the Second Audio Program. When the tuner
+receives no bilingual audio or SAP, or their reception is not
+supported the driver shall fall back to mono or stereo mode. Only
+<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this mode.
+Note the <constant>V4L2_TUNER_MODE_LANG2</constant> and
+<constant>V4L2_TUNER_MODE_SAP</constant> are synonyms.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_TUNER_MODE_LANG1_LANG2</constant></entry>
+	    <entry>4</entry>
+	    <entry>Play the primary language on the left channel, the
+secondary language on the right channel. When the tuner receives no
+bilingual audio or SAP, it shall fall back to
+<constant>MODE_LANG1</constant> or <constant>MODE_MONO</constant>.
+Only <constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
+mode.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="all" id="tuner-matrix">
+      <title>Tuner Audio Matrix</title>
+      <tgroup cols="6" align="center">
+	<colspec align="left" />
+	<colspec colname="c2" colwidth="1*" />
+	<colspec colwidth="1*" />
+	<colspec colwidth="1*" />
+	<colspec colnum="6" colname="c6" colwidth="1*" />
+	<spanspec namest="c2" nameend="c6" spanname="hspan" align="center" />
+	<thead>
+	  <row>
+	    <entry></entry>
+	    <entry spanname="hspan">Selected
+<constant>V4L2_TUNER_MODE_</constant></entry>
+	  </row>
+	  <row>
+	    <entry>Received <constant>V4L2_TUNER_SUB_</constant></entry>
+	    <entry><constant>MONO</constant></entry>
+	    <entry><constant>STEREO</constant></entry>
+	    <entry><constant>LANG1</constant></entry>
+	    <entry><constant>LANG2 = SAP</constant></entry>
+	    <entry><constant>LANG1_LANG2</constant><footnote><para>This
+mode has been added in Linux 2.6.17 and may not be supported by older
+drivers.</para></footnote></entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>MONO</constant></entry>
+	    <entry>Mono</entry>
+	    <entry>Mono/Mono</entry>
+	    <entry>Mono</entry>
+	    <entry>Mono</entry>
+	    <entry>Mono/Mono</entry>
+	  </row>
+	  <row>
+	    <entry><constant>MONO | SAP</constant></entry>
+	    <entry>Mono</entry>
+	    <entry>Mono/Mono</entry>
+	    <entry>Mono</entry>
+	    <entry>SAP</entry>
+	    <entry>Mono/SAP (preferred) or Mono/Mono</entry>
+	  </row>
+	  <row>
+	    <entry><constant>STEREO</constant></entry>
+	    <entry>L+R</entry>
+	    <entry>L/R</entry>
+	    <entry>Stereo L/R (preferred) or Mono L+R</entry>
+	    <entry>Stereo L/R (preferred) or Mono L+R</entry>
+	    <entry>L/R (preferred) or L+R/L+R</entry>
+	  </row>
+	  <row>
+	    <entry><constant>STEREO | SAP</constant></entry>
+	    <entry>L+R</entry>
+	    <entry>L/R</entry>
+	    <entry>Stereo L/R (preferred) or Mono L+R</entry>
+	    <entry>SAP</entry>
+	    <entry>L+R/SAP (preferred) or L/R or L+R/L+R</entry>
+	  </row>
+	  <row>
+	    <entry><constant>LANG1 | LANG2</constant></entry>
+	    <entry>Language&nbsp;1</entry>
+	    <entry>Lang1/Lang2 (deprecated<footnote><para>Playback of
+both languages in <constant>MODE_STEREO</constant> is deprecated. In
+the future drivers should produce only the primary language in this
+mode. Applications should request
+<constant>MODE_LANG1_LANG2</constant> to record both languages or a
+stereo signal.</para></footnote>) or
+Lang1/Lang1</entry>
+	    <entry>Language&nbsp;1</entry>
+	    <entry>Language&nbsp;2</entry>
+	    <entry>Lang1/Lang2 (preferred) or Lang1/Lang1</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-tuner; <structfield>index</structfield> is
+out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-log-status.xml b/Documentation/DocBook/v4l/vidioc-log-status.xml
new file mode 100644
index 0000000..2634b7c
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-log-status.xml
@@ -0,0 +1,58 @@
+<refentry id="vidioc-log-status">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_LOG_STATUS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_LOG_STATUS</refname>
+    <refpurpose>Log driver status information</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>As the video/audio devices become more complicated it
+becomes harder to debug problems. When this ioctl is called the driver
+will output the current device status to the kernel log. This is
+particular useful when dealing with problems like no sound, no video
+and incorrectly tuned channels. Also many modern devices autodetect
+video and audio standards and this ioctl will report what the device
+thinks what the standard is. Mismatches may give an indication where
+the problem is.</para>
+
+    <para>This ioctl is optional and not all drivers support it. It
+was introduced in Linux 2.6.15.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The driver does not support this ioctl.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-overlay.xml b/Documentation/DocBook/v4l/vidioc-overlay.xml
new file mode 100644
index 0000000..1036c58
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-overlay.xml
@@ -0,0 +1,83 @@
+<refentry id="vidioc-overlay">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_OVERLAY</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_OVERLAY</refname>
+    <refpurpose>Start or stop video overlay</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const int *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_OVERLAY</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is part of the <link linkend="overlay">video
+    overlay</link> I/O method. Applications call
+    <constant>VIDIOC_OVERLAY</constant> to start or stop the
+    overlay. It takes a pointer to an integer which must be set to
+    zero by the application to stop overlay, to one to start.</para>
+
+    <para>Drivers do not support &VIDIOC-STREAMON; or
+&VIDIOC-STREAMOFF; with <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>Video overlay is not supported, or the
+parameters have not been set up. See <xref
+linkend="overlay" /> for the necessary steps.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-qbuf.xml b/Documentation/DocBook/v4l/vidioc-qbuf.xml
new file mode 100644
index 0000000..1870817
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-qbuf.xml
@@ -0,0 +1,168 @@
+<refentry id="vidioc-qbuf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_QBUF, VIDIOC_DQBUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_QBUF</refname>
+    <refname>VIDIOC_DQBUF</refname>
+    <refpurpose>Exchange a buffer with the driver</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_QBUF, VIDIOC_DQBUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Applications call the <constant>VIDIOC_QBUF</constant> ioctl
+to enqueue an empty (capturing) or filled (output) buffer in the
+driver's incoming queue. The semantics depend on the selected I/O
+method.</para>
+
+    <para>To enqueue a <link linkend="mmap">memory mapped</link>
+buffer applications set the <structfield>type</structfield> field of a
+&v4l2-buffer; to the same buffer type as previously &v4l2-format;
+<structfield>type</structfield> and &v4l2-requestbuffers;
+<structfield>type</structfield>, the <structfield>memory</structfield>
+field to <constant>V4L2_MEMORY_MMAP</constant> and the
+<structfield>index</structfield> field. Valid index numbers range from
+zero to the number of buffers allocated with &VIDIOC-REQBUFS;
+(&v4l2-requestbuffers; <structfield>count</structfield>) minus one. The
+contents of the struct <structname>v4l2_buffer</structname> returned
+by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is
+intended for output (<structfield>type</structfield> is
+<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or
+<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also
+initialize the <structfield>bytesused</structfield>,
+<structfield>field</structfield> and
+<structfield>timestamp</structfield> fields. See <xref
+	linkend="buffer" /> for details. When
+<constant>VIDIOC_QBUF</constant> is called with a pointer to this
+structure the driver sets the
+<constant>V4L2_BUF_FLAG_MAPPED</constant> and
+<constant>V4L2_BUF_FLAG_QUEUED</constant> flags and clears the
+<constant>V4L2_BUF_FLAG_DONE</constant> flag in the
+<structfield>flags</structfield> field, or it returns an
+&EINVAL;.</para>
+
+    <para>To enqueue a <link linkend="userp">user pointer</link>
+buffer applications set the <structfield>type</structfield> field of a
+&v4l2-buffer; to the same buffer type as previously &v4l2-format;
+<structfield>type</structfield> and &v4l2-requestbuffers;
+<structfield>type</structfield>, the <structfield>memory</structfield>
+field to <constant>V4L2_MEMORY_USERPTR</constant> and the
+<structfield>m.userptr</structfield> field to the address of the
+buffer and <structfield>length</structfield> to its size. When the
+buffer is intended for output additional fields must be set as above.
+When <constant>VIDIOC_QBUF</constant> is called with a pointer to this
+structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant>
+flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and
+<constant>V4L2_BUF_FLAG_DONE</constant> flags in the
+<structfield>flags</structfield> field, or it returns an error code.
+This ioctl locks the memory pages of the buffer in physical memory,
+they cannot be swapped out to disk. Buffers remain locked until
+dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl are
+called, or until the device is closed.</para>
+
+    <para>Applications call the <constant>VIDIOC_DQBUF</constant>
+ioctl to dequeue a filled (capturing) or displayed (output) buffer
+from the driver's outgoing queue. They just set the
+<structfield>type</structfield> and <structfield>memory</structfield>
+fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
+is called with a pointer to this structure the driver fills the
+remaining fields or returns an error code.</para>
+
+    <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
+buffer is in the outgoing queue. When the
+<constant>O_NONBLOCK</constant> flag was given to the &func-open;
+function, <constant>VIDIOC_DQBUF</constant> returns immediately
+with an &EAGAIN; when no buffer is available.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EAGAIN</errorcode></term>
+	<listitem>
+	  <para>Non-blocking I/O has been selected using
+<constant>O_NONBLOCK</constant> and no buffer was in the outgoing
+queue.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds,
+or no buffers have been allocated yet, or the
+<structfield>userptr</structfield> or
+<structfield>length</structfield> are invalid.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>ENOMEM</errorcode></term>
+	<listitem>
+	  <para>Not enough physical or virtual memory was available to
+enqueue a user pointer buffer.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EIO</errorcode></term>
+	<listitem>
+	  <para><constant>VIDIOC_DQBUF</constant> failed due to an
+internal error. Can also indicate temporary problems like signal
+loss. Note the driver might dequeue an (empty) buffer despite
+returning an error, or even stop capturing.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-querybuf.xml b/Documentation/DocBook/v4l/vidioc-querybuf.xml
new file mode 100644
index 0000000..d834993
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-querybuf.xml
@@ -0,0 +1,103 @@
+<refentry id="vidioc-querybuf">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_QUERYBUF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_QUERYBUF</refname>
+    <refpurpose>Query the status of a buffer</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_QUERYBUF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is part of the <link linkend="mmap">memory
+mapping</link> I/O method. It can be used to query the status of a
+buffer at any time after buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.</para>
+
+    <para>Applications set the <structfield>type</structfield> field
+    of a &v4l2-buffer; to the same buffer type as previously
+&v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers;
+<structfield>type</structfield>, and the <structfield>index</structfield>
+    field. Valid index numbers range from zero
+to the number of buffers allocated with &VIDIOC-REQBUFS;
+    (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
+After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to
+    this structure drivers return an error code or fill the rest of
+the structure.</para>
+
+    <para>In the <structfield>flags</structfield> field the
+<constant>V4L2_BUF_FLAG_MAPPED</constant>,
+<constant>V4L2_BUF_FLAG_QUEUED</constant> and
+<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
+<structfield>memory</structfield> field will be set to
+<constant>V4L2_MEMORY_MMAP</constant>, the <structfield>m.offset</structfield>
+contains the offset of the buffer from the start of the device memory,
+the <structfield>length</structfield> field its size. The driver may
+or may not set the remaining fields and flags, they are meaningless in
+this context.</para>
+
+    <para>The <structname>v4l2_buffer</structname> structure is
+    specified in <xref linkend="buffer" />.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer <structfield>type</structfield> is not
+supported, or the <structfield>index</structfield> is out of bounds.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-querycap.xml b/Documentation/DocBook/v4l/vidioc-querycap.xml
new file mode 100644
index 0000000..6ab7e25
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-querycap.xml
@@ -0,0 +1,284 @@
+<refentry id="vidioc-querycap">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_QUERYCAP</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_QUERYCAP</refname>
+    <refpurpose>Query device capabilities</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_capability *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_QUERYCAP</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>All V4L2 devices support the
+<constant>VIDIOC_QUERYCAP</constant> ioctl. It is used to identify
+kernel devices compatible with this specification and to obtain
+information about driver and hardware capabilities. The ioctl takes a
+pointer to a &v4l2-capability; which is filled by the driver. When the
+driver is not compatible with this specification the ioctl returns an
+&EINVAL;.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-capability">
+      <title>struct <structname>v4l2_capability</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>driver</structfield>[16]</entry>
+	    <entry><para>Name of the driver, a unique NUL-terminated
+ASCII string. For example: "bttv". Driver specific applications can
+use this information to verify the driver identity. It is also useful
+to work around known bugs, or to identify drivers in error reports.
+The driver version is stored in the <structfield>version</structfield>
+field.</para><para>Storing strings in fixed sized arrays is bad
+practice but unavoidable here. Drivers and applications should take
+precautions to never read or write beyond the end of the array and to
+make sure the strings are properly NUL-terminated.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>card</structfield>[32]</entry>
+	    <entry>Name of the device, a NUL-terminated ASCII string.
+For example: "Yoyodyne TV/FM". One driver may support different brands
+or models of video hardware. This information is intended for users,
+for example in a menu of available devices. Since multiple TV cards of
+the same brand may be installed which are supported by the same
+driver, this name should be combined with the character device file
+name (&eg; <filename>/dev/video2</filename>) or the
+<structfield>bus_info</structfield> string to avoid
+ambiguities.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>bus_info</structfield>[32]</entry>
+	    <entry>Location of the device in the system, a
+NUL-terminated ASCII string. For example: "PCI Slot 4". This
+information is intended for users, to distinguish multiple
+identical devices. If no such information is available the field may
+simply count the devices controlled by the driver, or contain the
+empty string (<structfield>bus_info</structfield>[0] = 0).<!-- XXX pci_dev->slot_name example --></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>version</structfield></entry>
+	    <entry><para>Version number of the driver. Together with
+the <structfield>driver</structfield> field this identifies a
+particular driver. The version number is formatted using the
+<constant>KERNEL_VERSION()</constant> macro:</para></entry>
+	  </row>
+	  <row>
+	    <entry spanname="hspan"><para>
+<programlisting>
+#define KERNEL_VERSION(a,b,c) (((a) &lt;&lt; 16) + ((b) &lt;&lt; 8) + (c))
+
+__u32 version = KERNEL_VERSION(0, 8, 1);
+
+printf ("Version: %u.%u.%u\n",
+	(version &gt;&gt; 16) &amp; 0xFF,
+	(version &gt;&gt; 8) &amp; 0xFF,
+	 version &amp; 0xFF);
+</programlisting></para></entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>capabilities</structfield></entry>
+	    <entry>Device capabilities, see <xref
+		linkend="device-capabilities" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[4]</entry>
+	    <entry>Reserved for future extensions. Drivers must set
+this array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="device-capabilities">
+      <title>Device Capabilities Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
+	    <entry>0x00000001</entry>
+	    <entry>The device supports the <link
+linkend="capture">Video Capture</link> interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry>
+	    <entry>0x00000002</entry>
+	    <entry>The device supports the <link
+linkend="output">Video Output</link> interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
+	    <entry>0x00000004</entry>
+	    <entry>The device supports the <link
+linkend="overlay">Video Overlay</link> interface. A video overlay device
+typically stores captured images directly in the video memory of a
+graphics card, with hardware clipping and scaling.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_VBI_CAPTURE</constant></entry>
+	    <entry>0x00000010</entry>
+	    <entry>The device supports the <link linkend="raw-vbi">Raw
+VBI Capture</link> interface, providing Teletext and Closed Caption
+data.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_VBI_OUTPUT</constant></entry>
+	    <entry>0x00000020</entry>
+	    <entry>The device supports the <link linkend="raw-vbi">Raw VBI Output</link> interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_SLICED_VBI_CAPTURE</constant></entry>
+	    <entry>0x00000040</entry>
+	    <entry>The device supports the <link linkend="sliced">Sliced VBI Capture</link> interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_SLICED_VBI_OUTPUT</constant></entry>
+	    <entry>0x00000080</entry>
+	    <entry>The device supports the <link linkend="sliced">Sliced VBI Output</link> interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_RDS_CAPTURE</constant></entry>
+	    <entry>0x00000100</entry>
+	    <entry>The device supports the <link linkend="rds">RDS</link> interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant></entry>
+	    <entry>0x00000200</entry>
+	    <entry>The device supports the <link linkend="osd">Video
+Output Overlay</link> (OSD) interface. Unlike the <wordasword>Video
+Overlay</wordasword> interface, this is a secondary function of video
+output devices and overlays an image onto an outgoing video signal.
+When the driver sets this flag, it must clear the
+<constant>V4L2_CAP_VIDEO_OVERLAY</constant> flag and vice
+versa.<footnote><para>The &v4l2-framebuffer; lacks an
+&v4l2-buf-type; field, therefore the type of overlay is implied by the
+driver capabilities.</para></footnote></entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_HW_FREQ_SEEK</constant></entry>
+	    <entry>0x00000400</entry>
+	    <entry>The device supports the &VIDIOC-S-HW-FREQ-SEEK; ioctl for
+hardware frequency seeking.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_TUNER</constant></entry>
+	    <entry>0x00010000</entry>
+	    <entry>The device has some sort of tuner to
+receive RF-modulated video signals. For more information about
+tuner programming see
+<xref linkend="tuner" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_AUDIO</constant></entry>
+	    <entry>0x00020000</entry>
+	    <entry>The device has audio inputs or outputs. It may or
+may not support audio recording or playback, in PCM or compressed
+formats. PCM audio support must be implemented as ALSA or OSS
+interface. For more information on audio inputs and outputs see <xref
+		linkend="audio" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_RADIO</constant></entry>
+	    <entry>0x00040000</entry>
+	    <entry>This is a radio receiver.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_MODULATOR</constant></entry>
+	    <entry>0x00080000</entry>
+	    <entry>The device has some sort of modulator to
+emit RF-modulated video/audio signals. For more information about
+modulator programming see
+<xref linkend="tuner" />.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_READWRITE</constant></entry>
+	    <entry>0x01000000</entry>
+	    <entry>The device supports the <link
+linkend="rw">read()</link> and/or <link linkend="rw">write()</link>
+I/O methods.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_ASYNCIO</constant></entry>
+	    <entry>0x02000000</entry>
+	    <entry>The device supports the <link
+linkend="async">asynchronous</link> I/O methods.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CAP_STREAMING</constant></entry>
+	    <entry>0x04000000</entry>
+	    <entry>The device supports the <link
+linkend="mmap">streaming</link> I/O method.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The device is not compatible with this
+specification.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
+
diff --git a/Documentation/DocBook/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/v4l/vidioc-queryctrl.xml
new file mode 100644
index 0000000..4876ff1
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-queryctrl.xml
@@ -0,0 +1,428 @@
+<refentry id="vidioc-queryctrl">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_QUERYCTRL</refname>
+    <refname>VIDIOC_QUERYMENU</refname>
+    <refpurpose>Enumerate controls and menu control items</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_queryctrl *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_querymenu *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>To query the attributes of a control applications set the
+<structfield>id</structfield> field of a &v4l2-queryctrl; and call the
+<constant>VIDIOC_QUERYCTRL</constant> ioctl with a pointer to this
+structure. The driver fills the rest of the structure or returns an
+&EINVAL; when the <structfield>id</structfield> is invalid.</para>
+
+    <para>It is possible to enumerate controls by calling
+<constant>VIDIOC_QUERYCTRL</constant> with successive
+<structfield>id</structfield> values starting from
+<constant>V4L2_CID_BASE</constant> up to and exclusive
+<constant>V4L2_CID_BASE_LASTP1</constant>. Drivers may return
+<errorcode>EINVAL</errorcode> if a control in this range is not
+supported. Further applications can enumerate private controls, which
+are not defined in this specification, by starting at
+<constant>V4L2_CID_PRIVATE_BASE</constant> and incrementing
+<structfield>id</structfield> until the driver returns
+<errorcode>EINVAL</errorcode>.</para>
+
+    <para>In both cases, when the driver sets the
+<constant>V4L2_CTRL_FLAG_DISABLED</constant> flag in the
+<structfield>flags</structfield> field this control is permanently
+disabled and should be ignored by the application.<footnote>
+	<para><constant>V4L2_CTRL_FLAG_DISABLED</constant> was
+intended for two purposes: Drivers can skip predefined controls not
+supported by the hardware (although returning EINVAL would do as
+well), or disable predefined and private controls after hardware
+detection without the trouble of reordering control arrays and indices
+(EINVAL cannot be used to skip private controls because it would
+prematurely end the enumeration).</para></footnote></para>
+
+    <para>When the application ORs <structfield>id</structfield> with
+<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver returns the
+next supported control, or <errorcode>EINVAL</errorcode> if there is
+none. Drivers which do not support this flag yet always return
+<errorcode>EINVAL</errorcode>.</para>
+
+    <para>Additional information is required for menu controls: the
+names of the menu items. To query them applications set the
+<structfield>id</structfield> and <structfield>index</structfield>
+fields of &v4l2-querymenu; and call the
+<constant>VIDIOC_QUERYMENU</constant> ioctl with a pointer to this
+structure. The driver fills the rest of the structure or returns an
+&EINVAL; when the <structfield>id</structfield> or
+<structfield>index</structfield> is invalid. Menu items are enumerated
+by calling <constant>VIDIOC_QUERYMENU</constant> with successive
+<structfield>index</structfield> values from &v4l2-queryctrl;
+<structfield>minimum</structfield> (0) to
+<structfield>maximum</structfield>, inclusive.</para>
+
+    <para>See also the examples in <xref linkend="control" />.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-queryctrl">
+      <title>struct <structname>v4l2_queryctrl</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry>Identifies the control, set by the application. See
+<xref linkend="control-id" /> for predefined IDs. When the ID is ORed
+with V4L2_CTRL_FLAG_NEXT_CTRL the driver clears the flag and returns
+the first control with a higher ID. Drivers which do not support this
+flag yet always return an &EINVAL;.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-ctrl-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of control, see <xref
+		linkend="v4l2-ctrl-type" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry>Name of the control, a NUL-terminated ASCII
+string. This information is intended for the user.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>minimum</structfield></entry>
+	    <entry>Minimum value, inclusive. This field gives a lower
+bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
+lowest valid index (always 0) for <constant>V4L2_CTRL_TYPE_MENU</constant> controls.
+For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the minimum value
+gives the minimum length of the string. This length <emphasis>does not include the terminating
+zero</emphasis>. It may not be valid for any other type of control, including
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
+signed value.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>maximum</structfield></entry>
+	    <entry>Maximum value, inclusive. This field gives an upper
+bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
+highest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant>
+controls.
+For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the maximum value
+gives the maximum length of the string. This length <emphasis>does not include the terminating
+zero</emphasis>. It may not be valid for any other type of control, including
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
+signed value.</entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>step</structfield></entry>
+	    <entry><para>This field gives a step size for
+<constant>V4L2_CTRL_TYPE_INTEGER</constant> controls. For
+<constant>V4L2_CTRL_TYPE_STRING</constant> controls this field refers to
+the string length that has to be a multiple of this step size.
+It may not be valid for any other type of control, including
+<constant>V4L2_CTRL_TYPE_INTEGER64</constant>
+controls.</para><para>Generally drivers should not scale hardware
+control values. It may be necessary for example when the
+<structfield>name</structfield> or <structfield>id</structfield> imply
+a particular unit and the hardware actually accepts only multiples of
+said unit. If so, drivers must take care values are properly rounded
+when scaling, such that errors will not accumulate on repeated
+read-write cycles.</para><para>This field gives the smallest change of
+an integer control actually affecting hardware. Often the information
+is needed when the user can change controls by keyboard or GUI
+buttons, rather than a slider. When for example a hardware register
+accepts values 0-511 and the driver reports 0-65535, step should be
+128.</para><para>Note that although signed, the step value is supposed to
+be always positive.</para></entry>
+	  </row>
+	  <row>
+	    <entry>__s32</entry>
+	    <entry><structfield>default_value</structfield></entry>
+	    <entry>The default value of a
+<constant>V4L2_CTRL_TYPE_INTEGER</constant>,
+<constant>_BOOLEAN</constant> or <constant>_MENU</constant> control.
+Not valid for other types of controls. Drivers reset controls only
+when the driver is loaded, not later, in particular not when the
+func-open; is called.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>Control flags, see <xref
+		linkend="control-flags" />.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-querymenu">
+      <title>struct <structname>v4l2_querymenu</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>id</structfield></entry>
+	    <entry>Identifies the control, set by the application
+from the respective &v4l2-queryctrl;
+<structfield>id</structfield>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>index</structfield></entry>
+	    <entry>Index of the menu item, starting at zero, set by
+	    the application.</entry>
+	  </row>
+	  <row>
+	    <entry>__u8</entry>
+	    <entry><structfield>name</structfield>[32]</entry>
+	    <entry>Name of the menu item, a NUL-terminated ASCII
+string. This information is intended for the user.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield></entry>
+	    <entry>Reserved for future extensions. Drivers must set
+the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-ctrl-type">
+      <title>enum v4l2_ctrl_type</title>
+      <tgroup cols="5" align="left">
+	<colspec colwidth="30*" />
+	<colspec colwidth="5*" align="center" />
+	<colspec colwidth="5*" align="center" />
+	<colspec colwidth="5*" align="center" />
+	<colspec colwidth="55*" />
+	<thead>
+	  <row>
+	    <entry>Type</entry>
+	    <entry><structfield>minimum</structfield></entry>
+	    <entry><structfield>step</structfield></entry>
+	    <entry><structfield>maximum</structfield></entry>
+	    <entry>Description</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_INTEGER</constant></entry>
+	    <entry>any</entry>
+	    <entry>any</entry>
+	    <entry>any</entry>
+	    <entry>An integer-valued control ranging from minimum to
+maximum inclusive. The step value indicates the increment between
+values which are actually different on the hardware.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_BOOLEAN</constant></entry>
+	    <entry>0</entry>
+	    <entry>1</entry>
+	    <entry>1</entry>
+	    <entry>A boolean-valued control. Zero corresponds to
+"disabled", and one means "enabled".</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_MENU</constant></entry>
+	    <entry>0</entry>
+	    <entry>1</entry>
+	    <entry>N-1</entry>
+	    <entry>The control has a menu of N choices. The names of
+the menu items can be enumerated with the
+<constant>VIDIOC_QUERYMENU</constant> ioctl.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_BUTTON</constant></entry>
+	    <entry>0</entry>
+	    <entry>0</entry>
+	    <entry>0</entry>
+	    <entry>A control which performs an action when set.
+Drivers must ignore the value passed with
+<constant>VIDIOC_S_CTRL</constant> and return an &EINVAL; on a
+<constant>VIDIOC_G_CTRL</constant> attempt.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_INTEGER64</constant></entry>
+	    <entry>n/a</entry>
+	    <entry>n/a</entry>
+	    <entry>n/a</entry>
+	    <entry>A 64-bit integer valued control. Minimum, maximum
+and step size cannot be queried.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_STRING</constant></entry>
+	    <entry>&ge; 0</entry>
+	    <entry>&ge; 1</entry>
+	    <entry>&ge; 0</entry>
+	    <entry>The minimum and maximum string lengths. The step size
+means that the string must be (minimum + N * step) characters long for
+N &ge; 0. These lengths do not include the terminating zero, so in order to
+pass a string of length 8 to &VIDIOC-S-EXT-CTRLS; you need to set the
+<structfield>size</structfield> field of &v4l2-ext-control; to 9. For &VIDIOC-G-EXT-CTRLS; you can
+set the <structfield>size</structfield> field to <structfield>maximum</structfield> + 1.
+Which character encoding is used will depend on the string control itself and
+should be part of the control documentation.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant></entry>
+	    <entry>n/a</entry>
+	    <entry>n/a</entry>
+	    <entry>n/a</entry>
+	    <entry>This is not a control. When
+<constant>VIDIOC_QUERYCTRL</constant> is called with a control ID
+equal to a control class code (see <xref linkend="ctrl-class" />), the
+ioctl returns the name of the control class and this control type.
+Older drivers which do not support this feature return an
+&EINVAL;.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="control-flags">
+      <title>Control Flags</title>
+      <tgroup cols="3">
+	&cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_DISABLED</constant></entry>
+	    <entry>0x0001</entry>
+	    <entry>This control is permanently disabled and should be
+ignored by the application. Any attempt to change the control will
+result in an &EINVAL;.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_GRABBED</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>This control is temporarily unchangeable, for
+example because another application took over control of the
+respective resource. Such controls may be displayed specially in a
+user interface. Attempts to change the control may result in an
+&EBUSY;.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_READ_ONLY</constant></entry>
+	    <entry>0x0004</entry>
+	    <entry>This control is permanently readable only. Any
+attempt to change the control will result in an &EINVAL;.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_UPDATE</constant></entry>
+	    <entry>0x0008</entry>
+	    <entry>A hint that changing this control may affect the
+value of other controls within the same control class. Applications
+should update their user interface accordingly.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_INACTIVE</constant></entry>
+	    <entry>0x0010</entry>
+	    <entry>This control is not applicable to the current
+configuration and should be displayed accordingly in a user interface.
+For example the flag may be set on a MPEG audio level 2 bitrate
+control when MPEG audio encoding level 1 was selected with another
+control.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_SLIDER</constant></entry>
+	    <entry>0x0020</entry>
+	    <entry>A hint that this control is best represented as a
+slider-like element in a user interface.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant></entry>
+	    <entry>0x0040</entry>
+	    <entry>This control is permanently writable only. Any
+attempt to read the control will result in an &EACCES; error code. This
+flag is typically present for relative controls or action controls where
+writing a value will cause the device to carry out a given action
+(&eg; motor control) but no meaningful value can be returned.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-queryctrl; <structfield>id</structfield>
+is invalid. The &v4l2-querymenu; <structfield>id</structfield> or
+<structfield>index</structfield> is invalid.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EACCES</errorcode></term>
+	<listitem>
+	  <para>An attempt was made to read a write-only control.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-querystd.xml b/Documentation/DocBook/v4l/vidioc-querystd.xml
new file mode 100644
index 0000000..b5a7ff9
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-querystd.xml
@@ -0,0 +1,83 @@
+<refentry id="vidioc-querystd">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_QUERYSTD</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_QUERYSTD</refname>
+    <refpurpose>Sense the video standard received by the current
+input</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>v4l2_std_id *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+	<varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_QUERYSTD</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The hardware may be able to detect the current video
+standard automatically. To do so, applications call <constant>
+VIDIOC_QUERYSTD</constant> with a pointer to a &v4l2-std-id; type. The
+driver stores here a set of candidates, this can be a single flag or a
+set of supported standards if for example the hardware can only
+distinguish between 50 and 60 Hz systems. When detection is not
+possible or fails, the set must contain all standards supported by the
+current video input or output.</para>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>This ioctl is not supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-reqbufs.xml b/Documentation/DocBook/v4l/vidioc-reqbufs.xml
new file mode 100644
index 0000000..bab3808
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-reqbufs.xml
@@ -0,0 +1,160 @@
+<refentry id="vidioc-reqbufs">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_REQBUFS</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_REQBUFS</refname>
+    <refpurpose>Initiate Memory Mapping or User Pointer I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_requestbuffers *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_REQBUFS</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>This ioctl is used to initiate <link linkend="mmap">memory
+mapped</link> or <link linkend="userp">user pointer</link>
+I/O. Memory mapped buffers are located in device memory and must be
+allocated with this ioctl before they can be mapped into the
+application's address space. User buffers are allocated by
+applications themselves, and this ioctl is merely used to switch the
+driver into user pointer I/O mode.</para>
+
+    <para>To allocate device buffers applications initialize three
+fields of a <structname>v4l2_requestbuffers</structname> structure.
+They set the <structfield>type</structfield> field to the respective
+stream or buffer type, the <structfield>count</structfield> field to
+the desired number of buffers, and <structfield>memory</structfield>
+must be set to <constant>V4L2_MEMORY_MMAP</constant>. When the ioctl
+is called with a pointer to this structure the driver attempts to
+allocate the requested number of buffers and stores the actual number
+allocated in the <structfield>count</structfield> field. It can be
+smaller than the number requested, even zero, when the driver runs out
+of free memory. A larger number is possible when the driver requires
+more buffers to function correctly.<footnote>
+	<para>For example video output requires at least two buffers,
+one displayed and one filled by the application.</para>
+	</footnote> When memory mapping I/O is not supported the ioctl
+returns an &EINVAL;.</para>
+
+    <para>Applications can call <constant>VIDIOC_REQBUFS</constant>
+again to change the number of buffers, however this cannot succeed
+when any buffers are still mapped. A <structfield>count</structfield>
+value of zero frees all buffers, after aborting or finishing any DMA
+in progress, an implicit &VIDIOC-STREAMOFF;. <!-- mhs: I see no
+reason why munmap()ping one or even all buffers must imply
+streamoff.--></para>
+
+    <para>To negotiate user pointer I/O, applications initialize only
+the <structfield>type</structfield> field and set
+<structfield>memory</structfield> to
+<constant>V4L2_MEMORY_USERPTR</constant>. When the ioctl is called
+with a pointer to this structure the driver prepares for user pointer
+I/O, when this I/O method is not supported the ioctl returns an
+&EINVAL;.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-requestbuffers">
+      <title>struct <structname>v4l2_requestbuffers</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>count</structfield></entry>
+	    <entry>The number of buffers requested or granted. This
+field is only used when <structfield>memory</structfield> is set to
+<constant>V4L2_MEMORY_MMAP</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-buf-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>Type of the stream or buffers, this is the same
+as the &v4l2-format; <structfield>type</structfield> field. See <xref
+		linkend="v4l2-buf-type" /> for valid values.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-memory;</entry>
+	    <entry><structfield>memory</structfield></entry>
+	    <entry>Applications set this field to
+<constant>V4L2_MEMORY_MMAP</constant> or
+<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[2]</entry>
+	    <entry>A place holder for future extensions and custom
+(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
+higher.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The driver supports multiple opens and I/O is already
+in progress, or reallocation of buffers was attempted although one or
+more are still mapped.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The buffer type (<structfield>type</structfield> field) or the
+requested I/O method (<structfield>memory</structfield>) is not
+supported.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml
new file mode 100644
index 0000000..14b3ec7
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml
@@ -0,0 +1,129 @@
+<refentry id="vidioc-s-hw-freq-seek">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_S_HW_FREQ_SEEK</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_S_HW_FREQ_SEEK</refname>
+    <refpurpose>Perform a hardware frequency seek</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_hw_freq_seek
+*<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_S_HW_FREQ_SEEK</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>Start a hardware frequency seek from the current frequency.
+To do this applications initialize the <structfield>tuner</structfield>,
+<structfield>type</structfield>, <structfield>seek_upward</structfield> and
+<structfield>wrap_around</structfield> fields, and zero out the
+<structfield>reserved</structfield> array of a &v4l2-hw-freq-seek; and
+call the <constant>VIDIOC_S_HW_FREQ_SEEK</constant> ioctl with a pointer
+to this structure.</para>
+
+    <para>This ioctl is supported if the <constant>V4L2_CAP_HW_FREQ_SEEK</constant> capability is set.</para>
+
+    <table pgwide="1" frame="none" id="v4l2-hw-freq-seek">
+      <title>struct <structname>v4l2_hw_freq_seek</structname></title>
+      <tgroup cols="3">
+	&cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>tuner</structfield></entry>
+	    <entry>The tuner index number. This is the
+same value as in the &v4l2-input; <structfield>tuner</structfield>
+field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-tuner-type;</entry>
+	    <entry><structfield>type</structfield></entry>
+	    <entry>The tuner type. This is the same value as in the
+&v4l2-tuner; <structfield>type</structfield> field.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>seek_upward</structfield></entry>
+	    <entry>If non-zero, seek upward from the current frequency, else seek downward.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>wrap_around</structfield></entry>
+	    <entry>If non-zero, wrap around when at the end of the frequency range, else stop seeking.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Drivers and
+	    applications must set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The <structfield>tuner</structfield> index is out of
+bounds or the value in the <structfield>type</structfield> field is
+wrong.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EAGAIN</errorcode></term>
+	<listitem>
+	  <para>The ioctl timed-out. Try again.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/DocBook/v4l/vidioc-streamon.xml b/Documentation/DocBook/v4l/vidioc-streamon.xml
new file mode 100644
index 0000000..e42bff1
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-streamon.xml
@@ -0,0 +1,106 @@
+<refentry id="vidioc-streamon">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_STREAMON</refname>
+    <refname>VIDIOC_STREAMOFF</refname>
+    <refpurpose>Start or stop streaming I/O</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>const int *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_STREAMON, VIDIOC_STREAMOFF</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <refsect1>
+    <title>Description</title>
+
+    <para>The <constant>VIDIOC_STREAMON</constant> and
+<constant>VIDIOC_STREAMOFF</constant> ioctl start and stop the capture
+or output process during streaming (<link linkend="mmap">memory
+mapping</link> or <link linkend="userp">user pointer</link>) I/O.</para>
+
+    <para>Specifically the capture hardware is disabled and no input
+buffers are filled (if there are any empty buffers in the incoming
+queue) until <constant>VIDIOC_STREAMON</constant> has been called.
+Accordingly the output hardware is disabled, no video signal is
+produced until <constant>VIDIOC_STREAMON</constant> has been called.
+The ioctl will succeed only when at least one output buffer is in the
+incoming queue.</para>
+
+    <para>The <constant>VIDIOC_STREAMOFF</constant> ioctl, apart of
+aborting or finishing any DMA in progress, unlocks any user pointer
+buffers locked in physical memory, and it removes all buffers from the
+incoming and outgoing queues. That means all images captured but not
+dequeued yet will be lost, likewise all images enqueued for output but
+not transmitted yet. I/O returns to the same state as after calling
+&VIDIOC-REQBUFS; and can be restarted accordingly.</para>
+
+    <para>Both ioctls take a pointer to an integer, the desired buffer or
+stream type. This is the same as &v4l2-requestbuffers;
+<structfield>type</structfield>.</para>
+
+    <para>Note applications can be preempted for unknown periods right
+before or after the <constant>VIDIOC_STREAMON</constant> or
+<constant>VIDIOC_STREAMOFF</constant> calls, there is no notion of
+starting or stopping "now". Buffer timestamps can be used to
+synchronize with other events.</para>
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>Streaming I/O is not supported, the buffer
+<structfield>type</structfield> is not supported, or no buffers have
+been allocated (memory mapping) or enqueued (output) yet.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
+
+<!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "v4l2.sgml"
+indent-tabs-mode: nil
+End:
+-->
diff --git a/Documentation/PCI/pci-error-recovery.txt b/Documentation/PCI/pci-error-recovery.txt
index 6650af4..e83f2ea 100644
--- a/Documentation/PCI/pci-error-recovery.txt
+++ b/Documentation/PCI/pci-error-recovery.txt
@@ -4,15 +4,17 @@
                         February 2, 2006
 
                  Current document maintainer:
-             Linas Vepstas <linas@austin.ibm.com>
+             Linas Vepstas <linasvepstas@gmail.com>
+          updated by Richard Lary <rlary@us.ibm.com>
+       and Mike Mason <mmlnx@us.ibm.com> on 27-Jul-2009
 
 
 Many PCI bus controllers are able to detect a variety of hardware
 PCI errors on the bus, such as parity errors on the data and address
 busses, as well as SERR and PERR errors.  Some of the more advanced
 chipsets are able to deal with these errors; these include PCI-E chipsets,
-and the PCI-host bridges found on IBM Power4 and Power5-based pSeries
-boxes. A typical action taken is to disconnect the affected device,
+and the PCI-host bridges found on IBM Power4, Power5 and Power6-based
+pSeries boxes. A typical action taken is to disconnect the affected device,
 halting all I/O to it.  The goal of a disconnection is to avoid system
 corruption; for example, to halt system memory corruption due to DMA's
 to "wild" addresses. Typically, a reconnection mechanism is also
@@ -37,10 +39,11 @@ is forced by the need to handle multi-function devices, that is,
 devices that have multiple device drivers associated with them.
 In the first stage, each driver is allowed to indicate what type
 of reset it desires, the choices being a simple re-enabling of I/O
-or requesting a hard reset (a full electrical #RST of the PCI card).
-If any driver requests a full reset, that is what will be done.
+or requesting a slot reset.
 
-After a full reset and/or a re-enabling of I/O, all drivers are
+If any driver requests a slot reset, that is what will be done.
+
+After a reset and/or a re-enabling of I/O, all drivers are
 again notified, so that they may then perform any device setup/config
 that may be required.  After these have all completed, a final
 "resume normal operations" event is sent out.
@@ -101,7 +104,7 @@ if it implements any, it must implement error_detected(). If a callback
 is not implemented, the corresponding feature is considered unsupported.
 For example, if mmio_enabled() and resume() aren't there, then it
 is assumed that the driver is not doing any direct recovery and requires
-a reset. If link_reset() is not implemented, the card is assumed as
+a slot reset. If link_reset() is not implemented, the card is assumed to
 not care about link resets. Typically a driver will want to know about
 a slot_reset().
 
@@ -111,7 +114,7 @@ sequence described below.
 
 STEP 0: Error Event
 -------------------
-PCI bus error is detect by the PCI hardware.  On powerpc, the slot
+A PCI bus error is detected by the PCI hardware.  On powerpc, the slot
 is isolated, in that all I/O is blocked: all reads return 0xffffffff,
 all writes are ignored.
 
@@ -139,7 +142,7 @@ The driver must return one of the following result codes:
 		  a chance to extract some diagnostic information (see
 		  mmio_enable, below).
 		- PCI_ERS_RESULT_NEED_RESET:
-		  Driver returns this if it can't recover without a hard
+		  Driver returns this if it can't recover without a
 		  slot reset.
 		- PCI_ERS_RESULT_DISCONNECT:
 		  Driver returns this if it doesn't want to recover at all.
@@ -169,11 +172,11 @@ is STEP 6 (Permanent Failure).
 
 >>> The current powerpc implementation doesn't much care if the device
 >>> attempts I/O at this point, or not.  I/O's will fail, returning
->>> a value of 0xff on read, and writes will be dropped. If the device
->>> driver attempts more than 10K I/O's to a frozen adapter, it will
->>> assume that the device driver has gone into an infinite loop, and
->>> it will panic the kernel. There doesn't seem to be any other
->>> way of stopping a device driver that insists on spinning on I/O.
+>>> a value of 0xff on read, and writes will be dropped. If more than
+>>> EEH_MAX_FAILS I/O's are attempted to a frozen adapter, EEH
+>>> assumes that the device driver has gone into an infinite loop
+>>> and prints an error to syslog.  A reboot is then required to 
+>>> get the device working again.
 
 STEP 2: MMIO Enabled
 -------------------
@@ -182,15 +185,14 @@ DMA), and then calls the mmio_enabled() callback on all affected
 device drivers.
 
 This is the "early recovery" call. IOs are allowed again, but DMA is
-not (hrm... to be discussed, I prefer not), with some restrictions. This
-is NOT a callback for the driver to start operations again, only to
-peek/poke at the device, extract diagnostic information, if any, and
-eventually do things like trigger a device local reset or some such,
-but not restart operations. This is callback is made if all drivers on
-a segment agree that they can try to recover and if no automatic link reset
-was performed by the HW. If the platform can't just re-enable IOs without
-a slot reset or a link reset, it wont call this callback, and instead
-will have gone directly to STEP 3 (Link Reset) or STEP 4 (Slot Reset)
+not, with some restrictions. This is NOT a callback for the driver to
+start operations again, only to peek/poke at the device, extract diagnostic
+information, if any, and eventually do things like trigger a device local
+reset or some such, but not restart operations. This callback is made if
+all drivers on a segment agree that they can try to recover and if no automatic
+link reset was performed by the HW. If the platform can't just re-enable IOs
+without a slot reset or a link reset, it will not call this callback, and
+instead will have gone directly to STEP 3 (Link Reset) or STEP 4 (Slot Reset)
 
 >>> The following is proposed; no platform implements this yet:
 >>> Proposal: All I/O's should be done _synchronously_ from within
@@ -228,9 +230,6 @@ proceeds to either STEP3 (Link Reset) or to STEP 5 (Resume Operations).
 If any driver returned PCI_ERS_RESULT_NEED_RESET, then the platform
 proceeds to STEP 4 (Slot Reset)
 
->>> The current powerpc implementation does not implement this callback.
-
-
 STEP 3: Link Reset
 ------------------
 The platform resets the link, and then calls the link_reset() callback
@@ -253,16 +252,33 @@ The platform then proceeds to either STEP 4 (Slot Reset) or STEP 5
 
 >>> The current powerpc implementation does not implement this callback.
 
-
 STEP 4: Slot Reset
 ------------------
-The platform performs a soft or hard reset of the device, and then
-calls the slot_reset() callback.
 
-A soft reset consists of asserting the adapter #RST line and then
+In response to a return value of PCI_ERS_RESULT_NEED_RESET, the
+the platform will peform a slot reset on the requesting PCI device(s). 
+The actual steps taken by a platform to perform a slot reset
+will be platform-dependent. Upon completion of slot reset, the
+platform will call the device slot_reset() callback.
+
+Powerpc platforms implement two levels of slot reset:
+soft reset(default) and fundamental(optional) reset.
+
+Powerpc soft reset consists of asserting the adapter #RST line and then
 restoring the PCI BAR's and PCI configuration header to a state
 that is equivalent to what it would be after a fresh system
 power-on followed by power-on BIOS/system firmware initialization.
+Soft reset is also known as hot-reset.
+
+Powerpc fundamental reset is supported by PCI Express cards only
+and results in device's state machines, hardware logic, port states and
+configuration registers to initialize to their default conditions.
+
+For most PCI devices, a soft reset will be sufficient for recovery.
+Optional fundamental reset is provided to support a limited number
+of PCI Express PCI devices  for which a soft reset is not sufficient
+for recovery.
+
 If the platform supports PCI hotplug, then the reset might be
 performed by toggling the slot electrical power off/on.
 
@@ -274,10 +290,12 @@ may result in hung devices, kernel panics, or silent data corruption.
 
 This call gives drivers the chance to re-initialize the hardware
 (re-download firmware, etc.).  At this point, the driver may assume
-that he card is in a fresh state and is fully functional. In
-particular, interrupt generation should work normally.
+that the card is in a fresh state and is fully functional. The slot
+is unfrozen and the driver has full access to PCI config space,
+memory mapped I/O space and DMA. Interrupts (Legacy, MSI, or MSI-X)
+will also be available.
 
-Drivers should not yet restart normal I/O processing operations
+Drivers should not restart normal I/O processing operations
 at this point.  If all device drivers report success on this
 callback, the platform will call resume() to complete the sequence,
 and let the driver restart normal I/O processing.
@@ -302,11 +320,21 @@ driver performs device init only from PCI function 0:
 		- PCI_ERS_RESULT_DISCONNECT
 		Same as above.
 
+Drivers for PCI Express cards that require a fundamental reset must
+set the needs_freset bit in the pci_dev structure in their probe function.  
+For example, the QLogic qla2xxx driver sets the needs_freset bit for certain
+PCI card types:
+
++	/* Set EEH reset type to fundamental if required by hba  */
++	if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha))
++		pdev->needs_freset = 1;
++
+
 Platform proceeds either to STEP 5 (Resume Operations) or STEP 6 (Permanent
 Failure).
 
->>> The current powerpc implementation does not currently try a
->>> power-cycle reset if the driver returned PCI_ERS_RESULT_DISCONNECT.
+>>> The current powerpc implementation does not try a power-cycle
+>>> reset if the driver returned PCI_ERS_RESULT_DISCONNECT.
 >>> However, it probably should.
 
 
@@ -348,7 +376,7 @@ software errors.
 
 Conclusion; General Remarks
 ---------------------------
-The way those callbacks are called is platform policy. A platform with
+The way the callbacks are called is platform policy. A platform with
 no slot reset capability may want to just "ignore" drivers that can't
 recover (disconnect them) and try to let other cards on the same segment
 recover. Keep in mind that in most real life cases, though, there will
@@ -361,8 +389,8 @@ That is, the recovery API only requires that:
 
  - There is no guarantee that interrupt delivery can proceed from any
 device on the segment starting from the error detection and until the
-resume callback is sent, at which point interrupts are expected to be
-fully operational.
+slot_reset callback is called, at which point interrupts are expected
+to be fully operational.
 
  - There is no guarantee that interrupt delivery is stopped, that is,
 a driver that gets an interrupt after detecting an error, or that detects
@@ -381,16 +409,23 @@ anyway :)
 >>> Implementation details for the powerpc platform are discussed in
 >>> the file Documentation/powerpc/eeh-pci-error-recovery.txt
 
->>> As of this writing, there are six device drivers with patches
->>> implementing error recovery. Not all of these patches are in
+>>> As of this writing, there is a growing list of device drivers with
+>>> patches implementing error recovery. Not all of these patches are in
 >>> mainline yet. These may be used as "examples":
 >>>
->>> drivers/scsi/ipr.c
->>> drivers/scsi/sym53cxx_2
+>>> drivers/scsi/ipr
+>>> drivers/scsi/sym53c8xx_2
+>>> drivers/scsi/qla2xxx
+>>> drivers/scsi/lpfc
+>>> drivers/next/bnx2.c
 >>> drivers/next/e100.c
 >>> drivers/net/e1000
+>>> drivers/net/e1000e
 >>> drivers/net/ixgb
+>>> drivers/net/ixgbe
+>>> drivers/net/cxgb3
 >>> drivers/net/s2io.c
+>>> drivers/net/qlge
 
 The End
 -------
diff --git a/Documentation/arm/OMAP/omap_pm b/Documentation/arm/OMAP/omap_pm
new file mode 100644
index 0000000..5389440
--- /dev/null
+++ b/Documentation/arm/OMAP/omap_pm
@@ -0,0 +1,129 @@
+
+The OMAP PM interface
+=====================
+
+This document describes the temporary OMAP PM interface.  Driver
+authors use these functions to communicate minimum latency or
+throughput constraints to the kernel power management code.
+Over time, the intention is to merge features from the OMAP PM
+interface into the Linux PM QoS code.
+
+Drivers need to express PM parameters which:
+
+- support the range of power management parameters present in the TI SRF;
+
+- separate the drivers from the underlying PM parameter
+  implementation, whether it is the TI SRF or Linux PM QoS or Linux
+  latency framework or something else;
+
+- specify PM parameters in terms of fundamental units, such as
+  latency and throughput, rather than units which are specific to OMAP
+  or to particular OMAP variants;
+
+- allow drivers which are shared with other architectures (e.g.,
+  DaVinci) to add these constraints in a way which won't affect non-OMAP
+  systems,
+
+- can be implemented immediately with minimal disruption of other
+  architectures.
+
+
+This document proposes the OMAP PM interface, including the following
+five power management functions for driver code:
+
+1. Set the maximum MPU wakeup latency:
+   (*pdata->set_max_mpu_wakeup_lat)(struct device *dev, unsigned long t)
+
+2. Set the maximum device wakeup latency:
+   (*pdata->set_max_dev_wakeup_lat)(struct device *dev, unsigned long t)
+
+3. Set the maximum system DMA transfer start latency (CORE pwrdm):
+   (*pdata->set_max_sdma_lat)(struct device *dev, long t)
+
+4. Set the minimum bus throughput needed by a device:
+   (*pdata->set_min_bus_tput)(struct device *dev, u8 agent_id, unsigned long r)
+
+5. Return the number of times the device has lost context
+   (*pdata->get_dev_context_loss_count)(struct device *dev)
+
+
+Further documentation for all OMAP PM interface functions can be
+found in arch/arm/plat-omap/include/mach/omap-pm.h.
+
+
+The OMAP PM layer is intended to be temporary
+---------------------------------------------
+
+The intention is that eventually the Linux PM QoS layer should support
+the range of power management features present in OMAP3.  As this
+happens, existing drivers using the OMAP PM interface can be modified
+to use the Linux PM QoS code; and the OMAP PM interface can disappear.
+
+
+Driver usage of the OMAP PM functions
+-------------------------------------
+
+As the 'pdata' in the above examples indicates, these functions are
+exposed to drivers through function pointers in driver .platform_data
+structures.  The function pointers are initialized by the board-*.c
+files to point to the corresponding OMAP PM functions:
+.set_max_dev_wakeup_lat will point to
+omap_pm_set_max_dev_wakeup_lat(), etc.  Other architectures which do
+not support these functions should leave these function pointers set
+to NULL.  Drivers should use the following idiom:
+
+        if (pdata->set_max_dev_wakeup_lat)
+            (*pdata->set_max_dev_wakeup_lat)(dev, t);
+
+The most common usage of these functions will probably be to specify
+the maximum time from when an interrupt occurs, to when the device
+becomes accessible.  To accomplish this, driver writers should use the
+set_max_mpu_wakeup_lat() function to to constrain the MPU wakeup
+latency, and the set_max_dev_wakeup_lat() function to constrain the
+device wakeup latency (from clk_enable() to accessibility).  For
+example,
+
+        /* Limit MPU wakeup latency */
+        if (pdata->set_max_mpu_wakeup_lat)
+            (*pdata->set_max_mpu_wakeup_lat)(dev, tc);
+
+        /* Limit device powerdomain wakeup latency */
+        if (pdata->set_max_dev_wakeup_lat)
+            (*pdata->set_max_dev_wakeup_lat)(dev, td);
+
+        /* total wakeup latency in this example: (tc + td) */
+
+The PM parameters can be overwritten by calling the function again
+with the new value.  The settings can be removed by calling the
+function with a t argument of -1 (except in the case of
+set_max_bus_tput(), which should be called with an r argument of 0).
+
+The fifth function above, omap_pm_get_dev_context_loss_count(),
+is intended as an optimization to allow drivers to determine whether the
+device has lost its internal context.  If context has been lost, the
+driver must restore its internal context before proceeding.
+
+
+Other specialized interface functions
+-------------------------------------
+
+The five functions listed above are intended to be usable by any
+device driver.  DSPBridge and CPUFreq have a few special requirements.
+DSPBridge expresses target DSP performance levels in terms of OPP IDs.
+CPUFreq expresses target MPU performance levels in terms of MPU
+frequency.  The OMAP PM interface contains functions for these
+specialized cases to convert that input information (OPPs/MPU
+frequency) into the form that the underlying power management
+implementation needs:
+
+6. (*pdata->dsp_get_opp_table)(void)
+
+7. (*pdata->dsp_set_min_opp)(u8 opp_id)
+
+8. (*pdata->dsp_get_opp)(void)
+
+9. (*pdata->cpu_get_freq_table)(void)
+
+10. (*pdata->cpu_set_freq)(unsigned long f)
+
+11. (*pdata->cpu_get_freq)(void)
diff --git a/Documentation/arm/SA1100/ADSBitsy b/Documentation/arm/SA1100/ADSBitsy
index ab47c38..7197a9e 100644
--- a/Documentation/arm/SA1100/ADSBitsy
+++ b/Documentation/arm/SA1100/ADSBitsy
@@ -40,4 +40,4 @@ Notes:
   mode, the timing is off so the image is corrupted.  This will be
   fixed soon.
 
-Any contribution can be sent to nico@cam.org and will be greatly welcome!
+Any contribution can be sent to nico@fluxnic.net and will be greatly welcome!
diff --git a/Documentation/arm/SA1100/Assabet b/Documentation/arm/SA1100/Assabet
index 78bc1c1..91f7ce7 100644
--- a/Documentation/arm/SA1100/Assabet
+++ b/Documentation/arm/SA1100/Assabet
@@ -240,7 +240,7 @@ Then, rebooting the Assabet is just a matter of waiting for the login prompt.
 
 
 Nicolas Pitre
-nico@cam.org
+nico@fluxnic.net
 June 12, 2001
 
 
diff --git a/Documentation/arm/SA1100/Brutus b/Documentation/arm/SA1100/Brutus
index 2254c8f..b1cfd40 100644
--- a/Documentation/arm/SA1100/Brutus
+++ b/Documentation/arm/SA1100/Brutus
@@ -60,7 +60,7 @@ little modifications.
 
 Any contribution is welcome.
 
-Please send patches to nico@cam.org
+Please send patches to nico@fluxnic.net
 
 Have Fun !
 
diff --git a/Documentation/arm/SA1100/GraphicsClient b/Documentation/arm/SA1100/GraphicsClient
index 8fa7e80..6c9c4f5 100644
--- a/Documentation/arm/SA1100/GraphicsClient
+++ b/Documentation/arm/SA1100/GraphicsClient
@@ -4,7 +4,7 @@ For more details, contact Applied Data Systems or see
 http://www.applieddata.net/products.html
 
 The original Linux support for this product has been provided by 
-Nicolas Pitre <nico@cam.org>. Continued development work by
+Nicolas Pitre <nico@fluxnic.net>. Continued development work by
 Woojung Huh <whuh@applieddata.net>
 
 It's currently possible to mount a root filesystem via NFS providing a
@@ -94,5 +94,5 @@ Notes:
   mode, the timing is off so the image is corrupted.  This will be
   fixed soon.
 
-Any contribution can be sent to nico@cam.org and will be greatly welcome!
+Any contribution can be sent to nico@fluxnic.net and will be greatly welcome!
 
diff --git a/Documentation/arm/SA1100/GraphicsMaster b/Documentation/arm/SA1100/GraphicsMaster
index dd28745..ee7c659 100644
--- a/Documentation/arm/SA1100/GraphicsMaster
+++ b/Documentation/arm/SA1100/GraphicsMaster
@@ -4,7 +4,7 @@ For more details, contact Applied Data Systems or see
 http://www.applieddata.net/products.html
 
 The original Linux support for this product has been provided by
-Nicolas Pitre <nico@cam.org>. Continued development work by
+Nicolas Pitre <nico@fluxnic.net>. Continued development work by
 Woojung Huh <whuh@applieddata.net>
 
 Use 'make graphicsmaster_config' before any 'make config'.
@@ -50,4 +50,4 @@ Notes:
   mode, the timing is off so the image is corrupted.  This will be
   fixed soon.
 
-Any contribution can be sent to nico@cam.org and will be greatly welcome!
+Any contribution can be sent to nico@fluxnic.net and will be greatly welcome!
diff --git a/Documentation/arm/SA1100/Victor b/Documentation/arm/SA1100/Victor
index 01e81fc..f938a29 100644
--- a/Documentation/arm/SA1100/Victor
+++ b/Documentation/arm/SA1100/Victor
@@ -9,7 +9,7 @@ Of course Victor is using Linux as its main operating system.
 The Victor implementation for Linux is maintained by Nicolas Pitre:
 
 	nico@visuaide.com
-	nico@cam.org
+	nico@fluxnic.net
 
 For any comments, please feel free to contact me through the above
 addresses.
diff --git a/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt b/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt
new file mode 100644
index 0000000..76b3a11
--- /dev/null
+++ b/Documentation/arm/Samsung-S3C24XX/CPUfreq.txt
@@ -0,0 +1,75 @@
+		S3C24XX CPUfreq support
+		=======================
+
+Introduction
+------------
+
+ The S3C24XX series support a number of power saving systems, such as
+ the ability to change the core, memory and peripheral operating
+ frequencies. The core control is exported via the CPUFreq driver
+ which has a number of different manual or automatic controls over the
+ rate the core is running at.
+
+ There are two forms of the driver depending on the specific CPU and
+ how the clocks are arranged. The first implementation used as single
+ PLL to feed the ARM, memory and peripherals via a series of dividers
+ and muxes and this is the implementation that is documented here. A
+ newer version where there is a seperate PLL and clock divider for the
+ ARM core is available as a seperate driver.
+
+
+Layout
+------
+
+ The code core manages the CPU specific drivers, any data that they
+ need to register and the interface to the generic drivers/cpufreq
+ system. Each CPU registers a driver to control the PLL, clock dividers
+ and anything else associated with it. Any board that wants to use this
+ framework needs to supply at least basic details of what is required.
+
+ The core registers with drivers/cpufreq at init time if all the data
+ necessary has been supplied.
+
+
+CPU support
+-----------
+
+ The support for each CPU depends on the facilities provided by the
+ SoC and the driver as each device has different PLL and clock chains
+ associated with it.
+
+
+Slow Mode
+---------
+
+ The SLOW mode where the PLL is turned off altogether and the
+ system is fed by the external crystal input is currently not
+ supported.
+
+
+sysfs
+-----
+
+ The core code exports extra information via sysfs in the directory
+ devices/system/cpu/cpu0/arch-freq.
+
+
+Board Support
+-------------
+
+ Each board that wants to use the cpufreq code must register some basic
+ information with the core driver to provide information about what the
+ board requires and any restrictions being placed on it.
+
+ The board needs to supply information about whether it needs the IO bank
+ timings changing, any maximum frequency limits and information about the
+ SDRAM refresh rate.
+
+
+
+
+Document Author
+---------------
+
+Ben Dooks, Copyright 2009 Simtec Electronics
+Licensed under GPLv2
diff --git a/Documentation/btmrvl.txt b/Documentation/btmrvl.txt
new file mode 100644
index 0000000..34916a4
--- /dev/null
+++ b/Documentation/btmrvl.txt
@@ -0,0 +1,119 @@
+=======================================================================
+		README for btmrvl driver
+=======================================================================
+
+
+All commands are used via debugfs interface.
+
+=====================
+Set/get driver configurations:
+
+Path:	/debug/btmrvl/config/
+
+gpiogap=[n]
+hscfgcmd
+	These commands are used to configure the host sleep parameters.
+	bit 8:0  -- Gap
+	bit 16:8 -- GPIO
+
+	where GPIO is the pin number of GPIO used to wake up the host.
+	It could be any valid GPIO pin# (e.g. 0-7) or 0xff (SDIO interface
+	wakeup will be used instead).
+
+	where Gap is the gap in milli seconds between wakeup signal and
+	wakeup event, or 0xff for special host sleep setting.
+
+	Usage:
+		# Use SDIO interface to wake up the host and set GAP to 0x80:
+		echo 0xff80 > /debug/btmrvl/config/gpiogap
+		echo 1 > /debug/btmrvl/config/hscfgcmd
+
+		# Use GPIO pin #3 to wake up the host and set GAP to 0xff:
+		echo 0x03ff >  /debug/btmrvl/config/gpiogap
+		echo 1 > /debug/btmrvl/config/hscfgcmd
+
+psmode=[n]
+pscmd
+	These commands are used to enable/disable auto sleep mode
+
+	where the option is:
+			1 	-- Enable auto sleep mode
+			0 	-- Disable auto sleep mode
+
+	Usage:
+		# Enable auto sleep mode
+		echo 1 > /debug/btmrvl/config/psmode
+		echo 1 > /debug/btmrvl/config/pscmd
+
+		# Disable auto sleep mode
+		echo 0 > /debug/btmrvl/config/psmode
+		echo 1 > /debug/btmrvl/config/pscmd
+
+
+hsmode=[n]
+hscmd
+	These commands are used to enable host sleep or wake up firmware
+
+	where the option is:
+			1	-- Enable host sleep
+			0	-- Wake up firmware
+
+	Usage:
+		# Enable host sleep
+		echo 1 > /debug/btmrvl/config/hsmode
+		echo 1 > /debug/btmrvl/config/hscmd
+
+		# Wake up firmware
+		echo 0 > /debug/btmrvl/config/hsmode
+		echo 1 > /debug/btmrvl/config/hscmd
+
+
+======================
+Get driver status:
+
+Path:	/debug/btmrvl/status/
+
+Usage:
+	cat /debug/btmrvl/status/<args>
+
+where the args are:
+
+curpsmode
+	This command displays current auto sleep status.
+
+psstate
+	This command display the power save state.
+
+hsstate
+	This command display the host sleep state.
+
+txdnldrdy
+	This command displays the value of Tx download ready flag.
+
+
+=====================
+
+Use hcitool to issue raw hci command, refer to hcitool manual
+
+	Usage: Hcitool cmd <ogf> <ocf> [Parameters]
+
+	Interface Control Command
+	hcitool cmd 0x3f 0x5b 0xf5 0x01 0x00    --Enable All interface
+	hcitool cmd 0x3f 0x5b 0xf5 0x01 0x01    --Enable Wlan interface
+	hcitool cmd 0x3f 0x5b 0xf5 0x01 0x02    --Enable BT interface
+	hcitool cmd 0x3f 0x5b 0xf5 0x00 0x00    --Disable All interface
+	hcitool cmd 0x3f 0x5b 0xf5 0x00 0x01    --Disable Wlan interface
+	hcitool cmd 0x3f 0x5b 0xf5 0x00 0x02    --Disable BT interface
+
+=======================================================================
+
+
+SD8688 firmware:
+
+/lib/firmware/sd8688_helper.bin
+/lib/firmware/sd8688.bin
+
+
+The images can be downloaded from:
+
+git.infradead.org/users/dwmw2/linux-firmware.git/libertas/
diff --git a/Documentation/connector/Makefile b/Documentation/connector/Makefile
index 8df1a72..d98e4df 100644
--- a/Documentation/connector/Makefile
+++ b/Documentation/connector/Makefile
@@ -9,3 +9,8 @@ hostprogs-y := ucon
 always := $(hostprogs-y)
 
 HOSTCFLAGS_ucon.o += -I$(objtree)/usr/include
+
+all: modules
+
+modules clean:
+	$(MAKE) -C ../.. SUBDIRS=$(PWD) $@
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
index 6a5be5d..1711adc 100644
--- a/Documentation/connector/cn_test.c
+++ b/Documentation/connector/cn_test.c
@@ -19,6 +19,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define pr_fmt(fmt) "cn_test: " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -27,18 +29,17 @@
 
 #include <linux/connector.h>
 
-static struct cb_id cn_test_id = { 0x123, 0x456 };
+static struct cb_id cn_test_id = { CN_NETLINK_USERS + 3, 0x456 };
 static char cn_test_name[] = "cn_test";
 static struct sock *nls;
 static struct timer_list cn_test_timer;
 
-void cn_test_callback(void *data)
+static void cn_test_callback(struct cn_msg *msg)
 {
-	struct cn_msg *msg = (struct cn_msg *)data;
-
-	printk("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
-	       __func__, jiffies, msg->id.idx, msg->id.val,
-	       msg->seq, msg->ack, msg->len, (char *)msg->data);
+	pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
+	        __func__, jiffies, msg->id.idx, msg->id.val,
+	        msg->seq, msg->ack, msg->len,
+	        msg->len ? (char *)msg->data : "");
 }
 
 /*
@@ -63,9 +64,7 @@ static int cn_test_want_notify(void)
 
 	skb = alloc_skb(size, GFP_ATOMIC);
 	if (!skb) {
-		printk(KERN_ERR "Failed to allocate new skb with size=%u.\n",
-		       size);
-
+		pr_err("failed to allocate new skb with size=%u\n", size);
 		return -ENOMEM;
 	}
 
@@ -114,12 +113,12 @@ static int cn_test_want_notify(void)
 	//netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC);
 	netlink_unicast(nls, skb, 0, 0);
 
-	printk(KERN_INFO "Request was sent. Group=0x%x.\n", ctl->group);
+	pr_info("request was sent: group=0x%x\n", ctl->group);
 
 	return 0;
 
 nlmsg_failure:
-	printk(KERN_ERR "Failed to send %u.%u\n", msg->seq, msg->ack);
+	pr_err("failed to send %u.%u\n", msg->seq, msg->ack);
 	kfree_skb(skb);
 	return -EINVAL;
 }
@@ -131,6 +130,8 @@ static void cn_test_timer_func(unsigned long __data)
 	struct cn_msg *m;
 	char data[32];
 
+	pr_debug("%s: timer fired with data %lu\n", __func__, __data);
+
 	m = kzalloc(sizeof(*m) + sizeof(data), GFP_ATOMIC);
 	if (m) {
 
@@ -150,7 +151,7 @@ static void cn_test_timer_func(unsigned long __data)
 
 	cn_test_timer_counter++;
 
-	mod_timer(&cn_test_timer, jiffies + HZ);
+	mod_timer(&cn_test_timer, jiffies + msecs_to_jiffies(1000));
 }
 
 static int cn_test_init(void)
@@ -168,8 +169,10 @@ static int cn_test_init(void)
 	}
 
 	setup_timer(&cn_test_timer, cn_test_timer_func, 0);
-	cn_test_timer.expires = jiffies + HZ;
-	add_timer(&cn_test_timer);
+	mod_timer(&cn_test_timer, jiffies + msecs_to_jiffies(1000));
+
+	pr_info("initialized with id={%u.%u}\n",
+		cn_test_id.idx, cn_test_id.val);
 
 	return 0;
 
diff --git a/Documentation/connector/connector.txt b/Documentation/connector/connector.txt
index ad6e0ba..81e6bf6 100644
--- a/Documentation/connector/connector.txt
+++ b/Documentation/connector/connector.txt
@@ -5,10 +5,10 @@ Kernel Connector.
 Kernel connector - new netlink based userspace <-> kernel space easy
 to use communication module.
 
-Connector driver adds possibility to connect various agents using
-netlink based network.  One must register callback and
-identifier. When driver receives special netlink message with
-appropriate identifier, appropriate callback will be called.
+The Connector driver makes it easy to connect various agents using a
+netlink based network.  One must register a callback and an identifier.
+When the driver receives a special netlink message with the appropriate
+identifier, the appropriate callback will be called.
 
 From the userspace point of view it's quite straightforward:
 
@@ -17,10 +17,10 @@ From the userspace point of view it's quite straightforward:
 	send();
 	recv();
 
-But if kernelspace want to use full power of such connections, driver
-writer must create special sockets, must know about struct sk_buff
-handling...  Connector allows any kernelspace agents to use netlink
-based networking for inter-process communication in a significantly
+But if kernelspace wants to use the full power of such connections, the
+driver writer must create special sockets, must know about struct sk_buff
+handling, etc...  The Connector driver allows any kernelspace agents to use
+netlink based networking for inter-process communication in a significantly
 easier way:
 
 int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
@@ -32,15 +32,15 @@ struct cb_id
 	__u32			val;
 };
 
-idx and val are unique identifiers which must be registered in
-connector.h for in-kernel usage.  void (*callback) (void *) - is a
-callback function which will be called when message with above idx.val
-will be received by connector core.  Argument for that function must
+idx and val are unique identifiers which must be registered in the
+connector.h header for in-kernel usage.  void (*callback) (void *) is a
+callback function which will be called when a message with above idx.val
+is received by the connector core.  The argument for that function must
 be dereferenced to struct cn_msg *.
 
 struct cn_msg
 {
-	struct cb_id 		id;
+	struct cb_id		id;
 
 	__u32			seq;
 	__u32			ack;
@@ -55,92 +55,95 @@ Connector interfaces.
 
 int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *));
 
-Registers new callback with connector core.
+ Registers new callback with connector core.
 
-struct cb_id *id 		- unique connector's user identifier.
-			  	  It must be registered in connector.h for legal in-kernel users.
-char *name 			- connector's callback symbolic name.
-void (*callback) (void *)	- connector's callback.
+ struct cb_id *id		- unique connector's user identifier.
+				  It must be registered in connector.h for legal in-kernel users.
+ char *name			- connector's callback symbolic name.
+ void (*callback) (void *)	- connector's callback.
 				  Argument must be dereferenced to struct cn_msg *.
 
+
 void cn_del_callback(struct cb_id *id);
 
-Unregisters new callback with connector core.
+ Unregisters new callback with connector core.
+
+ struct cb_id *id		- unique connector's user identifier.
 
-struct cb_id *id 		- unique connector's user identifier.
 
 int cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask);
 
-Sends message to the specified groups.  It can be safely called from
-softirq context, but may silently fail under strong memory pressure.
-If there are no listeners for given group -ESRCH can be returned.
+ Sends message to the specified groups.  It can be safely called from
+ softirq context, but may silently fail under strong memory pressure.
+ If there are no listeners for given group -ESRCH can be returned.
 
-struct cn_msg *			- message header(with attached data).
-u32 __group			- destination group.
+ struct cn_msg *		- message header(with attached data).
+ u32 __group			- destination group.
 				  If __group is zero, then appropriate group will
 				  be searched through all registered connector users,
 				  and message will be delivered to the group which was
 				  created for user with the same ID as in msg.
 				  If __group is not zero, then message will be delivered
 				  to the specified group.
-int gfp_mask			- GFP mask.
+ int gfp_mask			- GFP mask.
 
-Note: When registering new callback user, connector core assigns
-netlink group to the user which is equal to it's id.idx.
+ Note: When registering new callback user, connector core assigns
+ netlink group to the user which is equal to it's id.idx.
 
 /*****************************************/
 Protocol description.
 /*****************************************/
 
-Current offers transport layer with fixed header.  Recommended
-protocol which uses such header is following:
+The current framework offers a transport layer with fixed headers.  The
+recommended protocol which uses such a header is as following:
 
 msg->seq and msg->ack are used to determine message genealogy.  When
-someone sends message it puts there locally unique sequence and random
-acknowledge numbers.  Sequence number may be copied into
+someone sends a message, they use a locally unique sequence and random
+acknowledge number.  The sequence number may be copied into
 nlmsghdr->nlmsg_seq too.
 
-Sequence number is incremented with each message to be sent.
+The sequence number is incremented with each message sent.
 
-If we expect reply to our message, then sequence number in received
-message MUST be the same as in original message, and acknowledge
-number MUST be the same + 1.
+If you expect a reply to the message, then the sequence number in the
+received message MUST be the same as in the original message, and the
+acknowledge number MUST be the same + 1.
 
-If we receive message and it's sequence number is not equal to one we
-are expecting, then it is new message.  If we receive message and it's
-sequence number is the same as one we are expecting, but it's
-acknowledge is not equal acknowledge number in original message + 1,
-then it is new message.
+If we receive a message and its sequence number is not equal to one we
+are expecting, then it is a new message.  If we receive a message and
+its sequence number is the same as one we are expecting, but its
+acknowledge is not equal to the acknowledge number in the original
+message + 1, then it is a new message.
 
-Obviously, protocol header contains above id.
+Obviously, the protocol header contains the above id.
 
-connector allows event notification in the following form: kernel
+The connector allows event notification in the following form: kernel
 driver or userspace process can ask connector to notify it when
-selected id's will be turned on or off(registered or unregistered it's
-callback). It is done by sending special command to connector
-driver(it also registers itself with id={-1, -1}).
+selected ids will be turned on or off (registered or unregistered its
+callback).  It is done by sending a special command to the connector
+driver (it also registers itself with id={-1, -1}).
 
-As example of usage Documentation/connector now contains cn_test.c -
-testing module which uses connector to request notification and to
-send messages.
+As example of this usage can be found in the cn_test.c module which
+uses the connector to request notification and to send messages.
 
 /*****************************************/
 Reliability.
 /*****************************************/
 
-Netlink itself is not reliable protocol, that means that messages can
+Netlink itself is not a reliable protocol.  That means that messages can
 be lost due to memory pressure or process' receiving queue overflowed,
-so caller is warned must be prepared. That is why struct cn_msg [main
-connector's message header] contains u32 seq and u32 ack fields.
+so caller is warned that it must be prepared.  That is why the struct
+cn_msg [main connector's message header] contains u32 seq and u32 ack
+fields.
 
 /*****************************************/
 Userspace usage.
 /*****************************************/
+
 2.6.14 has a new netlink socket implementation, which by default does not
-allow to send data to netlink groups other than 1.
-So, if to use netlink socket (for example using connector) 
-with different group number userspace application must subscribe to 
-that group. It can be achieved by following pseudocode:
+allow people to send data to netlink groups other than 1.
+So, if you wish to use a netlink socket (for example using connector)
+with a different group number, the userspace application must subscribe to
+that group first.  It can be achieved by the following pseudocode:
 
 s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
 
@@ -160,8 +163,8 @@ if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
 }
 
 Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
-option. To drop multicast subscription one should call above socket option
-with NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
+option.  To drop a multicast subscription, one should call the above socket
+option with the NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
 
 2.6.14 netlink code only allows to select a group which is less or equal to
 the maximum group number, which is used at netlink_kernel_create() time.
diff --git a/Documentation/connector/ucon.c b/Documentation/connector/ucon.c
index c5092ad..4848db8 100644
--- a/Documentation/connector/ucon.c
+++ b/Documentation/connector/ucon.c
@@ -30,18 +30,24 @@
 
 #include <arpa/inet.h>
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
 #include <time.h>
+#include <getopt.h>
 
 #include <linux/connector.h>
 
 #define DEBUG
 #define NETLINK_CONNECTOR 	11
 
+/* Hopefully your userspace connector.h matches this kernel */
+#define CN_TEST_IDX		CN_NETLINK_USERS + 3
+#define CN_TEST_VAL		0x456
+
 #ifdef DEBUG
 #define ulog(f, a...) fprintf(stdout, f, ##a)
 #else
@@ -83,6 +89,25 @@ static int netlink_send(int s, struct cn_msg *msg)
 	return err;
 }
 
+static void usage(void)
+{
+	printf(
+		"Usage: ucon [options] [output file]\n"
+		"\n"
+		"\t-h\tthis help screen\n"
+		"\t-s\tsend buffers to the test module\n"
+		"\n"
+		"The default behavior of ucon is to subscribe to the test module\n"
+		"and wait for state messages.  Any ones received are dumped to the\n"
+		"specified output file (or stdout).  The test module is assumed to\n"
+		"have an id of {%u.%u}\n"
+		"\n"
+		"If you get no output, then verify the cn_test module id matches\n"
+		"the expected id above.\n"
+		, CN_TEST_IDX, CN_TEST_VAL
+	);
+}
+
 int main(int argc, char *argv[])
 {
 	int s;
@@ -94,17 +119,34 @@ int main(int argc, char *argv[])
 	FILE *out;
 	time_t tm;
 	struct pollfd pfd;
+	bool send_msgs = false;
 
-	if (argc < 2)
-		out = stdout;
-	else {
-		out = fopen(argv[1], "a+");
+	while ((s = getopt(argc, argv, "hs")) != -1) {
+		switch (s) {
+		case 's':
+			send_msgs = true;
+			break;
+
+		case 'h':
+			usage();
+			return 0;
+
+		default:
+			/* getopt() outputs an error for us */
+			usage();
+			return 1;
+		}
+	}
+
+	if (argc != optind) {
+		out = fopen(argv[optind], "a+");
 		if (!out) {
 			ulog("Unable to open %s for writing: %s\n",
 				argv[1], strerror(errno));
 			out = stdout;
 		}
-	}
+	} else
+		out = stdout;
 
 	memset(buf, 0, sizeof(buf));
 
@@ -115,9 +157,11 @@ int main(int argc, char *argv[])
 	}
 
 	l_local.nl_family = AF_NETLINK;
-	l_local.nl_groups = 0x123; /* bitmask of requested groups */
+	l_local.nl_groups = -1; /* bitmask of requested groups */
 	l_local.nl_pid = 0;
 
+	ulog("subscribing to %u.%u\n", CN_TEST_IDX, CN_TEST_VAL);
+
 	if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
 		perror("bind");
 		close(s);
@@ -130,15 +174,15 @@ int main(int argc, char *argv[])
 		setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
 	}
 #endif
-	if (0) {
+	if (send_msgs) {
 		int i, j;
 
 		memset(buf, 0, sizeof(buf));
 
 		data = (struct cn_msg *)buf;
 
-		data->id.idx = 0x123;
-		data->id.val = 0x456;
+		data->id.idx = CN_TEST_IDX;
+		data->id.val = CN_TEST_VAL;
 		data->seq = seq++;
 		data->ack = 0;
 		data->len = 0;
diff --git a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt
index 5d5f5fa..2a5b850 100644
--- a/Documentation/cpu-freq/user-guide.txt
+++ b/Documentation/cpu-freq/user-guide.txt
@@ -176,7 +176,9 @@ scaling_governor,		and by "echoing" the name of another
 				work on some specific architectures or
 				processors.
 
-cpuinfo_cur_freq :		Current speed of the CPU, in KHz.
+cpuinfo_cur_freq :		Current frequency of the CPU as obtained from
+				the hardware, in KHz. This is the frequency
+				the CPU actually runs at.
 
 scaling_available_frequencies : List of available frequencies, in KHz.
 
@@ -196,7 +198,10 @@ related_cpus :			List of CPUs that need some sort of frequency
 
 scaling_driver :		Hardware driver for cpufreq.
 
-scaling_cur_freq :		Current frequency of the CPU, in KHz.
+scaling_cur_freq :		Current frequency of the CPU as determined by
+				the governor and cpufreq core, in KHz. This is
+				the frequency the kernel thinks the CPU runs
+				at.
 
 If you have selected the "userspace" governor which allows you to
 set the CPU operating frequency to a specific value, you can read out
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 88519da..e1efc40 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -152,7 +152,6 @@ piggy.gz
 piggyback
 pnmtologo
 ppc_defs.h*
-promcon_tbl.c
 pss_boot.h
 qconf
 raid6altivec*.c
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 3d1b0ab..14b7b5a 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -25,7 +25,8 @@ use IO::Handle;
 		"tda10046lifeview", "av7110", "dec2000t", "dec2540t",
 		"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
 		"or51211", "or51132_qam", "or51132_vsb", "bluebird",
-		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718" );
+		"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
+		"af9015");
 
 # Check args
 syntax() if (scalar(@ARGV) != 1);
@@ -514,6 +515,40 @@ sub bluebird {
 	$outfile;
 }
 
+sub af9015 {
+	my $sourcefile = "download.ashx?file=57";
+	my $url = "http://www.ite.com.tw/EN/Services/$sourcefile";
+	my $hash = "ff5b096ed47c080870eacdab2de33ad6";
+	my $outfile = "dvb-usb-af9015.fw";
+	my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+	my $fwoffset = 0x22708;
+	my $fwlength = 18225;
+	my ($chunklength, $buf, $rcount);
+
+	checkstandard();
+
+	wgetfile($sourcefile, $url);
+	unzip($sourcefile, $tmpdir);
+	verify("$tmpdir/Driver/Files/AF15BDA.sys", $hash);
+
+	open INFILE, '<', "$tmpdir/Driver/Files/AF15BDA.sys";
+	open OUTFILE, '>', $outfile;
+
+	sysseek(INFILE, $fwoffset, SEEK_SET);
+	while($fwlength > 0) {
+		$chunklength = 55;
+		$chunklength = $fwlength if ($chunklength > $fwlength);
+		$rcount = sysread(INFILE, $buf, $chunklength);
+		die "Ran out of data\n" if ($rcount != $chunklength);
+		syswrite(OUTFILE, $buf);
+		sysread(INFILE, $buf, 8);
+		$fwlength -= $rcount + 8;
+	}
+
+	close OUTFILE;
+	close INFILE;
+}
+
 # ---------------------------------------------------------------
 # Utilities
 
diff --git a/Documentation/dvb/technisat.txt b/Documentation/dvb/technisat.txt
index 3f435ff..f0cc4f2 100644
--- a/Documentation/dvb/technisat.txt
+++ b/Documentation/dvb/technisat.txt
@@ -4,9 +4,12 @@ How to set up the Technisat/B2C2 Flexcop devices
 1) Find out what device you have
 ================================
 
+Important Notice: The driver does NOT support Technisat USB 2 devices!
+
 First start your linux box with a shipped kernel:
 lspci -vvv for a PCI device (lsusb -vvv for an USB device) will show you for example:
-02:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card (rev 02)
+02:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip /
+ Technisat SkyStar2 DVB card (rev 02)
 
 dmesg | grep frontend may show you for example:
 DVB: registering frontend 0 (Conexant CX24123/CX24109)...
@@ -14,62 +17,62 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)...
 2) Kernel compilation:
 ======================
 
-If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one:
-"Multimedia devices" => "Customise analog and hybrid tuner modules to build"
-In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only).
+If the Flexcop / Technisat is the only DVB / TV / Radio device in your box
+ get rid of unnecessary modules and check this one:
+"Multimedia support" => "Customise analog and hybrid tuner modules to build"
+In this directory uncheck every driver which is activated there
+ (except "Simple tuner support" for ATSC 3rd generation only -> see case 9 please).
 
 Then please activate:
 2a) Main module part:
+"Multimedia support" => "DVB/ATSC adapters"
+ => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
 
-a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
-b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card
-OR
-c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter
-d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers"
-Notice: d.) is helpful for troubleshooting
+a.) => "Technisat/B2C2 Air/Sky/Cable2PC PCI" (PCI card) or
+b.) => "Technisat/B2C2 Air/Sky/Cable2PC USB" (USB 1.1 adapter)
+ and for troubleshooting purposes:
+c.) => "Enable debug for the B2C2 FlexCop drivers"
 
-2b) Frontend module part:
+2b) Frontend / Tuner / Demodulator module part:
+"Multimedia support" => "DVB/ATSC adapters"
+ => "Customise the frontend modules to build" "Customise DVB frontends" =>
 
 1.) SkyStar DVB-S Revision 2.3:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based"
+a.) => "Zarlink VP310/MT312/ZL10313 based"
+b.) => "Generic I2C PLL based tuners"
 
 2.) SkyStar DVB-S Revision 2.6:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based"
+a.) => "ST STV0299 based"
+b.) => "Generic I2C PLL based tuners"
 
 3.) SkyStar DVB-S Revision 2.7:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based"
-c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
-d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
+a.) => "Samsung S5H1420 based"
+b.) => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
+c.) => "ISL6421 SEC controller"
 
 4.) SkyStar DVB-S Revision 2.8:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
-c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based"
-d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
+a.) => "Conexant CX24123 based"
+b.) => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
+c.) => "ISL6421 SEC controller"
 
 5.) AirStar DVB-T card:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based"
+a.) => "Zarlink MT352 based"
+b.) => "Generic I2C PLL based tuners"
 
 6.) CableStar DVB-C card:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based"
+a.) => "ST STV0297 based"
+b.) => "Generic I2C PLL based tuners"
 
 7.) AirStar ATSC card 1st generation:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510"
+a.) => "Broadcom BCM3510"
 
 8.) AirStar ATSC card 2nd generation:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based"
-c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners"
+a.) => "NxtWave Communications NXT2002/NXT2004 based"
+b.) => "Generic I2C PLL based tuners"
 
 9.) AirStar ATSC card 3rd generation:
-a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build"
-b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based"
-c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support"
+a.) => "LG Electronics LGDT3302/LGDT3303 based"
+b.) "Multimedia support" => "Customise analog and hybrid tuner modules to build"
+ => "Simple tuner support"
 
-Author: Uwe Bugla <uwe.bugla@gmx.de> February 2009
+Author: Uwe Bugla <uwe.bugla@gmx.de> August 2009
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index bb3a53c..fa75220 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,6 +6,35 @@ be removed from this file.
 
 ---------------------------
 
+What:	PRISM54
+When:	2.6.34
+
+Why:	prism54 FullMAC PCI / Cardbus devices used to be supported only by the
+	prism54 wireless driver. After Intersil stopped selling these
+	devices in preference for the newer more flexible SoftMAC devices
+	a SoftMAC device driver was required and prism54 did not support
+	them. The p54pci driver now exists and has been present in the kernel for
+	a while. This driver supports both SoftMAC devices and FullMAC devices.
+	The main difference between these devices was the amount of memory which
+	could be used for the firmware. The SoftMAC devices support a smaller
+	amount of memory. Because of this the SoftMAC firmware fits into FullMAC
+	devices's memory. p54pci supports not only PCI / Cardbus but also USB
+	and SPI. Since p54pci supports all devices prism54 supports
+	you will have a conflict. I'm not quite sure how distributions are
+	handling this conflict right now. prism54 was kept around due to
+	claims users may experience issues when using the SoftMAC driver.
+	Time has passed users have not reported issues. If you use prism54
+	and for whatever reason you cannot use p54pci please let us know!
+	E-mail us at: linux-wireless@vger.kernel.org
+
+	For more information see the p54 wiki page:
+
+	http://wireless.kernel.org/en/users/Drivers/p54
+
+Who:	Luis R. Rodriguez <lrodriguez@atheros.com>
+
+---------------------------
+
 What:	IRQF_SAMPLE_RANDOM
 Check:	IRQF_SAMPLE_RANDOM
 When:	July 2009
@@ -217,31 +246,6 @@ Who:	Thomas Gleixner <tglx@linutronix.de>
 ---------------------------
 
 What (Why):
-	- include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
-	  (superseded by xt_TOS/xt_tos target & match)
-
-	- "forwarding" header files like ipt_mac.h in
-	  include/linux/netfilter_ipv4/ and include/linux/netfilter_ipv6/
-
-	- xt_CONNMARK match revision 0
-	  (superseded by xt_CONNMARK match revision 1)
-
-	- xt_MARK target revisions 0 and 1
-	  (superseded by xt_MARK match revision 2)
-
-	- xt_connmark match revision 0
-	  (superseded by xt_connmark match revision 1)
-
-	- xt_conntrack match revision 0
-	  (superseded by xt_conntrack match revision 1)
-
-	- xt_iprange match revision 0,
-	  include/linux/netfilter_ipv4/ipt_iprange.h
-	  (superseded by xt_iprange match revision 1)
-
-	- xt_mark match revision 0
-	  (superseded by xt_mark match revision 1)
-
 	- xt_recent: the old ipt_recent proc dir
 	  (superseded by /proc/net/xt_recent)
 
@@ -424,16 +428,6 @@ Who:	Johannes Berg <johannes@sipsolutions.net>
 
 ----------------------------
 
-What:	CONFIG_X86_OLD_MCE
-When:	2.6.32
-Why:	Remove the old legacy 32bit machine check code. This has been
-	superseded by the newer machine check code from the 64bit port,
-	but the old version has been kept around for easier testing. Note this
-	doesn't impact the old P5 and WinChip machine check handlers.
-Who:	Andi Kleen <andi@firstfloor.org>
-
-----------------------------
-
 What:	lock_policy_rwsem_* and unlock_policy_rwsem_* will not be
 	exported interface anymore.
 When:	2.6.33
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 7be02ac..18b5ec8 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -134,15 +134,9 @@ ro                   	Mount filesystem read only. Note that ext4 will
                      	mount options "ro,noload" can be used to prevent
 		     	writes to the filesystem.
 
-journal_checksum	Enable checksumming of the journal transactions.
-			This will allow the recovery code in e2fsck and the
-			kernel to detect corruption in the kernel.  It is a
-			compatible change and will be ignored by older kernels.
-
 journal_async_commit	Commit block can be written to disk without waiting
 			for descriptor blocks. If enabled older kernels cannot
-			mount the device. This will enable 'journal_checksum'
-			internally.
+			mount the device.
 
 journal=update		Update the ext4 file system's journal to the current
 			format.
@@ -263,10 +257,18 @@ resuid=n		The user ID which may use the reserved blocks.
 
 sb=n			Use alternate superblock at this location.
 
-quota
-noquota
-grpquota
-usrquota
+quota			These options are ignored by the filesystem. They
+noquota			are used only by quota tools to recognize volumes
+grpquota		where quota should be turned on. See documentation
+usrquota		in the quota-tools package for more details
+			(http://sourceforge.net/projects/linuxquota).
+
+jqfmt=<quota type>	These options tell filesystem details about quota
+usrjquota=<file>	so that quota information can be properly updated
+grpjquota=<file>	during journal replay. They replace the above
+			quota options. See documentation in the quota-tools
+			package for more details
+			(http://sourceforge.net/projects/linuxquota).
 
 bh		(*)	ext4 associates buffer heads to data pages to
 nobh			(a) cache disk block mapping information
diff --git a/Documentation/filesystems/gfs2-uevents.txt b/Documentation/filesystems/gfs2-uevents.txt
new file mode 100644
index 0000000..fd966dc
--- /dev/null
+++ b/Documentation/filesystems/gfs2-uevents.txt
@@ -0,0 +1,100 @@
+                              uevents and GFS2
+                             ==================
+
+During the lifetime of a GFS2 mount, a number of uevents are generated.
+This document explains what the events are and what they are used
+for (by gfs_controld in gfs2-utils).
+
+A list of GFS2 uevents
+-----------------------
+
+1. ADD
+
+The ADD event occurs at mount time. It will always be the first
+uevent generated by the newly created filesystem. If the mount
+is successful, an ONLINE uevent will follow.  If it is not successful
+then a REMOVE uevent will follow.
+
+The ADD uevent has two environment variables: SPECTATOR=[0|1]
+and RDONLY=[0|1] that specify the spectator status (a read-only mount
+with no journal assigned), and read-only (with journal assigned) status
+of the filesystem respectively.
+
+2. ONLINE
+
+The ONLINE uevent is generated after a successful mount or remount. It
+has the same environment variables as the ADD uevent. The ONLINE
+uevent, along with the two environment variables for spectator and
+RDONLY are a relatively recent addition (2.6.32-rc+) and will not
+be generated by older kernels.
+
+3. CHANGE
+
+The CHANGE uevent is used in two places. One is when reporting the
+successful mount of the filesystem by the first node (FIRSTMOUNT=Done).
+This is used as a signal by gfs_controld that it is then ok for other
+nodes in the cluster to mount the filesystem.
+
+The other CHANGE uevent is used to inform of the completion
+of journal recovery for one of the filesystems journals. It has
+two environment variables, JID= which specifies the journal id which
+has just been recovered, and RECOVERY=[Done|Failed] to indicate the
+success (or otherwise) of the operation. These uevents are generated
+for every journal recovered, whether it is during the initial mount
+process or as the result of gfs_controld requesting a specific journal
+recovery via the /sys/fs/gfs2/<fsname>/lock_module/recovery file.
+
+Because the CHANGE uevent was used (in early versions of gfs_controld)
+without checking the environment variables to discover the state, we
+cannot add any more functions to it without running the risk of
+someone using an older version of the user tools and breaking their
+cluster. For this reason the ONLINE uevent was used when adding a new
+uevent for a successful mount or remount.
+
+4. OFFLINE
+
+The OFFLINE uevent is only generated due to filesystem errors and is used
+as part of the "withdraw" mechanism. Currently this doesn't give any
+information about what the error is, which is something that needs to
+be fixed.
+
+5. REMOVE
+
+The REMOVE uevent is generated at the end of an unsuccessful mount
+or at the end of a umount of the filesystem. All REMOVE uevents will
+have been preceeded by at least an ADD uevent for the same fileystem,
+and unlike the other uevents is generated automatically by the kernel's
+kobject subsystem.
+
+
+Information common to all GFS2 uevents (uevent environment variables)
+----------------------------------------------------------------------
+
+1. LOCKTABLE=
+
+The LOCKTABLE is a string, as supplied on the mount command
+line (locktable=) or via fstab. It is used as a filesystem label
+as well as providing the information for a lock_dlm mount to be
+able to join the cluster.
+
+2. LOCKPROTO=
+
+The LOCKPROTO is a string, and its value depends on what is set
+on the mount command line, or via fstab. It will be either
+lock_nolock or lock_dlm. In the future other lock managers
+may be supported.
+
+3. JOURNALID=
+
+If a journal is in use by the filesystem (journals are not
+assigned for spectator mounts) then this will give the
+numeric journal id in all GFS2 uevents.
+
+4. UUID=
+
+With recent versions of gfs2-utils, mkfs.gfs2 writes a UUID
+into the filesystem superblock. If it exists, this will
+be included in every uevent relating to the filesystem.
+
+
+
diff --git a/Documentation/filesystems/seq_file.txt b/Documentation/filesystems/seq_file.txt
index b843743..0d15ebc 100644
--- a/Documentation/filesystems/seq_file.txt
+++ b/Documentation/filesystems/seq_file.txt
@@ -46,7 +46,7 @@ better to do. The file is seekable, in that one can do something like the
 following:
 
     dd if=/proc/sequence of=out1 count=1
-    dd if=/proc/sequence skip=1 out=out2 count=1
+    dd if=/proc/sequence skip=1 of=out2 count=1
 
 Then concatenate the output files out1 and out2 and get the right
 result. Yes, it is a thoroughly useless module, but the point is to show
diff --git a/Documentation/flexible-arrays.txt b/Documentation/flexible-arrays.txt
new file mode 100644
index 0000000..84eb268
--- /dev/null
+++ b/Documentation/flexible-arrays.txt
@@ -0,0 +1,99 @@
+Using flexible arrays in the kernel
+Last updated for 2.6.31
+Jonathan Corbet <corbet@lwn.net>
+
+Large contiguous memory allocations can be unreliable in the Linux kernel.
+Kernel programmers will sometimes respond to this problem by allocating
+pages with vmalloc().  This solution not ideal, though.  On 32-bit systems,
+memory from vmalloc() must be mapped into a relatively small address space;
+it's easy to run out.  On SMP systems, the page table changes required by
+vmalloc() allocations can require expensive cross-processor interrupts on
+all CPUs.  And, on all systems, use of space in the vmalloc() range
+increases pressure on the translation lookaside buffer (TLB), reducing the
+performance of the system.
+
+In many cases, the need for memory from vmalloc() can be eliminated by
+piecing together an array from smaller parts; the flexible array library
+exists to make this task easier.
+
+A flexible array holds an arbitrary (within limits) number of fixed-sized
+objects, accessed via an integer index.  Sparse arrays are handled
+reasonably well.  Only single-page allocations are made, so memory
+allocation failures should be relatively rare.  The down sides are that the
+arrays cannot be indexed directly, individual object size cannot exceed the
+system page size, and putting data into a flexible array requires a copy
+operation.  It's also worth noting that flexible arrays do no internal
+locking at all; if concurrent access to an array is possible, then the
+caller must arrange for appropriate mutual exclusion.
+
+The creation of a flexible array is done with:
+
+    #include <linux/flex_array.h>
+
+    struct flex_array *flex_array_alloc(int element_size,
+					unsigned int total,
+					gfp_t flags);
+
+The individual object size is provided by element_size, while total is the
+maximum number of objects which can be stored in the array.  The flags
+argument is passed directly to the internal memory allocation calls.  With
+the current code, using flags to ask for high memory is likely to lead to
+notably unpleasant side effects.
+
+Storing data into a flexible array is accomplished with a call to:
+
+    int flex_array_put(struct flex_array *array, unsigned int element_nr,
+    		       void *src, gfp_t flags);
+
+This call will copy the data from src into the array, in the position
+indicated by element_nr (which must be less than the maximum specified when
+the array was created).  If any memory allocations must be performed, flags
+will be used.  The return value is zero on success, a negative error code
+otherwise.
+
+There might possibly be a need to store data into a flexible array while
+running in some sort of atomic context; in this situation, sleeping in the
+memory allocator would be a bad thing.  That can be avoided by using
+GFP_ATOMIC for the flags value, but, often, there is a better way.  The
+trick is to ensure that any needed memory allocations are done before
+entering atomic context, using:
+
+    int flex_array_prealloc(struct flex_array *array, unsigned int start,
+			    unsigned int end, gfp_t flags);
+
+This function will ensure that memory for the elements indexed in the range
+defined by start and end has been allocated.  Thereafter, a
+flex_array_put() call on an element in that range is guaranteed not to
+block.
+
+Getting data back out of the array is done with:
+
+    void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
+
+The return value is a pointer to the data element, or NULL if that
+particular element has never been allocated.
+
+Note that it is possible to get back a valid pointer for an element which
+has never been stored in the array.  Memory for array elements is allocated
+one page at a time; a single allocation could provide memory for several
+adjacent elements.  The flexible array code does not know if a specific
+element has been written; it only knows if the associated memory is
+present.  So a flex_array_get() call on an element which was never stored
+in the array has the potential to return a pointer to random data.  If the
+caller does not have a separate way to know which elements were actually
+stored, it might be wise, at least, to add GFP_ZERO to the flags argument
+to ensure that all elements are zeroed.
+
+There is no way to remove a single element from the array.  It is possible,
+though, to remove all elements with a call to:
+
+    void flex_array_free_parts(struct flex_array *array);
+
+This call frees all elements, but leaves the array itself in place.
+Freeing the entire array is done with:
+
+    void flex_array_free(struct flex_array *array);
+
+As of this writing, there are no users of flexible arrays in the mainline
+kernel.  The functions described here are also not exported to modules;
+that will probably be fixed when somebody comes up with a need for it.
diff --git a/Documentation/hwmon/pcf8591 b/Documentation/hwmon/pcf8591
index 5628fcf..e76a789 100644
--- a/Documentation/hwmon/pcf8591
+++ b/Documentation/hwmon/pcf8591
@@ -2,11 +2,11 @@ Kernel driver pcf8591
 =====================
 
 Supported chips:
-  * Philips PCF8591
+  * Philips/NXP PCF8591
     Prefix: 'pcf8591'
     Addresses scanned: I2C 0x48 - 0x4f
-    Datasheet: Publicly available at the Philips Semiconductor website
-               http://www.semiconductors.philips.com/pip/PCF8591P.html
+    Datasheet: Publicly available at the NXP website
+               http://www.nxp.com/pip/PCF8591_6.html
 
 Authors:
         Aurelien Jarno <aurelien@aurel32.net>
@@ -16,9 +16,10 @@ Authors:
 
 Description
 -----------
+
 The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
-analog output) for the I2C bus produced by Philips Semiconductors. It
-is designed to provide a byte I2C interface to up to 4 separate devices.
+analog output) for the I2C bus produced by Philips Semiconductors (now NXP).
+It is designed to provide a byte I2C interface to up to 4 separate devices.
 
 The PCF8591 has 4 analog inputs programmable as single-ended or
 differential inputs :
@@ -58,8 +59,8 @@ Accessing PCF8591 via /sys interface
 -------------------------------------
 
 ! Be careful !
-The PCF8591 is plainly impossible to detect ! Stupid chip.
-So every chip with address in the interval [48..4f] is
+The PCF8591 is plainly impossible to detect! Stupid chip.
+So every chip with address in the interval [0x48..0x4f] is
 detected as PCF8591. If you have other chips in this address
 range, the workaround is to load this module after the one
 for your others chips.
@@ -67,19 +68,20 @@ for your others chips.
 On detection (i.e. insmod, modprobe et al.), directories are being
 created for each detected PCF8591:
 
-/sys/bus/devices/<0>-<1>/
+/sys/bus/i2c/devices/<0>-<1>/
 where <0> is the bus the chip was detected on (e. g. i2c-0)
 and <1> the chip address ([48..4f])
 
 Inside these directories, there are such files:
-in0, in1, in2, in3, out0_enable, out0_output, name
+in0_input, in1_input, in2_input, in3_input, out0_enable, out0_output, name
 
 Name contains chip name.
 
-The in0, in1, in2 and in3 files are RO. Reading gives the value of the
-corresponding channel. Depending on the current analog inputs configuration,
-files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
-ended inputs and -128 to +127 for differential inputs (8-bit ADC).
+The in0_input, in1_input, in2_input and in3_input files are RO. Reading gives
+the value of the corresponding channel. Depending on the current analog inputs
+configuration, files in2_input and in3_input may not exist. Values range
+from 0 to 255 for single ended inputs and -128 to +127 for differential inputs
+(8-bit ADC).
 
 The out0_enable file is RW. Reading gives "1" for analog output enabled and
 "0" for analog output disabled. Writing accepts "0" and "1" accordingly.
diff --git a/Documentation/hwmon/tmp421 b/Documentation/hwmon/tmp421
new file mode 100644
index 0000000..0cf07f8
--- /dev/null
+++ b/Documentation/hwmon/tmp421
@@ -0,0 +1,36 @@
+Kernel driver tmp421
+====================
+
+Supported chips:
+  * Texas Instruments TMP421
+    Prefix: 'tmp421'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+  * Texas Instruments TMP422
+    Prefix: 'tmp422'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+  * Texas Instruments TMP423
+    Prefix: 'tmp423'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+
+Authors:
+	Andre Prendel <andre.prendel@gmx.de>
+
+Description
+-----------
+
+This driver implements support for Texas Instruments TMP421, TMP422
+and TMP423 temperature sensor chips. These chips implement one local
+and up to one (TMP421), up to two (TMP422) or up to three (TMP423)
+remote sensors. Temperature is measured in degrees Celsius. The chips
+are wired over I2C/SMBus and specified over a temperature range of -40
+to +125 degrees Celsius. Resolution for both the local and remote
+channels is 0.0625 degree C.
+
+The chips support only temperature measurement. The driver exports
+the temperature values via the following sysfs files:
+
+temp[1-4]_input
+temp[2-4]_fault
diff --git a/Documentation/hwmon/wm831x b/Documentation/hwmon/wm831x
new file mode 100644
index 0000000..24f47d8
--- /dev/null
+++ b/Documentation/hwmon/wm831x
@@ -0,0 +1,37 @@
+Kernel driver wm831x-hwmon
+==========================
+
+Supported chips:
+  * Wolfson Microelectronics WM831x PMICs
+    Prefix: 'wm831x'
+    Datasheet:
+	http://www.wolfsonmicro.com/products/WM8310
+	http://www.wolfsonmicro.com/products/WM8311
+	http://www.wolfsonmicro.com/products/WM8312
+
+Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
+
+Description
+-----------
+
+The WM831x series of PMICs include an AUXADC which can be used to
+monitor a range of system operating parameters, including the voltages
+of the major supplies within the system.  Currently the driver provides
+reporting of all the input values but does not provide any alarms.
+
+Voltage Monitoring
+------------------
+
+Voltages are sampled by a 12 bit ADC.  Voltages in milivolts are 1.465
+times the ADC value.
+
+Temperature Monitoring
+----------------------
+
+Temperatures are sampled by a 12 bit ADC.  Chip and battery temperatures
+are available.  The chip temperature is calculated as:
+
+	Degrees celsius = (512.18 - data) / 1.0983
+
+while the battery temperature calculation will depend on the NTC
+thermistor component.
diff --git a/Documentation/hwmon/wm8350 b/Documentation/hwmon/wm8350
new file mode 100644
index 0000000..98f923b
--- /dev/null
+++ b/Documentation/hwmon/wm8350
@@ -0,0 +1,26 @@
+Kernel driver wm8350-hwmon
+==========================
+
+Supported chips:
+  * Wolfson Microelectronics WM835x PMICs
+    Prefix: 'wm8350'
+    Datasheet:
+	http://www.wolfsonmicro.com/products/WM8350
+	http://www.wolfsonmicro.com/products/WM8351
+	http://www.wolfsonmicro.com/products/WM8352
+
+Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
+
+Description
+-----------
+
+The WM835x series of PMICs include an AUXADC which can be used to
+monitor a range of system operating parameters, including the voltages
+of the major supplies within the system.  Currently the driver provides
+simple access to these major supplies.
+
+Voltage Monitoring
+------------------
+
+Voltages are sampled by a 12 bit ADC.  For the internal supplies the ADC
+is referenced to the system VRTC.
diff --git a/Documentation/input/sentelic.txt b/Documentation/input/sentelic.txt
new file mode 100644
index 0000000..f7160a2
--- /dev/null
+++ b/Documentation/input/sentelic.txt
@@ -0,0 +1,475 @@
+Copyright (C) 2002-2008 Sentelic Corporation.
+Last update: Oct-31-2008
+
+==============================================================================
+* Finger Sensing Pad Intellimouse Mode(scrolling wheel, 4th and 5th buttons)
+==============================================================================
+A) MSID 4: Scrolling wheel mode plus Forward page(4th button) and Backward
+   page (5th button)
+@1. Set sample rate to 200;
+@2. Set sample rate to 200;
+@3. Set sample rate to 80;
+@4. Issuing the "Get device ID" command (0xF2) and waits for the response;
+@5. FSP will respond 0x04.
+
+Packet 1
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |Y|X|y|x|1|M|R|L|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 | | |B|F|W|W|W|W|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7 => Y overflow
+        Bit6 => X overflow
+        Bit5 => Y sign bit
+        Bit4 => X sign bit
+        Bit3 => 1
+        Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: X Movement(9-bit 2's complement integers)
+Byte 3: Y Movement(9-bit 2's complement integers)
+Byte 4: Bit3~Bit0 => the scrolling wheel's movement since the last data report.
+                     valid values, -8 ~ +7
+        Bit4 => 1 = 4th mouse button is pressed, Forward one page.
+                0 = 4th mouse button is not pressed.
+        Bit5 => 1 = 5th mouse button is pressed, Backward one page.
+                0 = 5th mouse button is not pressed.
+
+B) MSID 6: Horizontal and Vertical scrolling.
+@ Set bit 1 in register 0x40 to 1
+
+# FSP replaces scrolling wheel's movement as 4 bits to show horizontal and
+  vertical scrolling.
+
+Packet 1
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |Y|X|y|x|1|M|R|L|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 | | |B|F|l|r|u|d|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7 => Y overflow
+        Bit6 => X overflow
+        Bit5 => Y sign bit
+        Bit4 => X sign bit
+        Bit3 => 1
+        Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: X Movement(9-bit 2's complement integers)
+Byte 3: Y Movement(9-bit 2's complement integers)
+Byte 4: Bit0 => the Vertical scrolling movement downward.
+	Bit1 => the Vertical scrolling movement upward.
+	Bit2 => the Vertical scrolling movement rightward.
+	Bit3 => the Vertical scrolling movement leftward.
+        Bit4 => 1 = 4th mouse button is pressed, Forward one page.
+                0 = 4th mouse button is not pressed.
+        Bit5 => 1 = 5th mouse button is pressed, Backward one page.
+                0 = 5th mouse button is not pressed.
+
+C) MSID 7:
+# FSP uses 2 packets(8 Bytes) data to represent Absolute Position
+  so we have PACKET NUMBER to identify packets.
+  If PACKET NUMBER is 0, the packet is Packet 1.
+  If PACKET NUMBER is 1, the packet is Packet 2.
+  Please count this number in program.
+
+# MSID6 special packet will be enable at the same time when enable MSID 7.
+
+==============================================================================
+* Absolute position for STL3886-G0.
+==============================================================================
+@ Set bit 2 or 3 in register 0x40 to 1
+@ Set bit 6 in register 0x40 to 1
+
+Packet 1 (ABSOLUTE POSITION)
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |0|1|V|1|1|M|R|L|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 |r|l|d|u|X|X|Y|Y|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordination packet
+                  => 10, Notify packet
+        Bit5 => valid bit
+        Bit4 => 1
+        Bit3 => 1
+        Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: X coordinate (xpos[9:2])
+Byte 3: Y coordinate (ypos[9:2])
+Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
+        Bit3~Bit2 => X coordinate (ypos[1:0])
+        Bit4 => scroll up
+        Bit5 => scroll down
+        Bit6 => scroll left
+        Bit7 => scroll right
+
+Notify Packet for G0
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |1|0|0|1|1|M|R|L|  2  |C|C|C|C|C|C|C|C|  3 |M|M|M|M|M|M|M|M|  4 |0|0|0|0|0|0|0|0|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordination packet
+                  => 10, Notify packet
+        Bit5 => 0
+        Bit4 => 1
+        Bit3 => 1
+        Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: Message Type => 0x5A (Enable/Disable status packet)
+        Mode Type => 0xA5 (Normal/Icon mode status)
+Byte 3: Message Type => 0x00 (Disabled)
+                     => 0x01 (Enabled)
+        Mode Type    => 0x00 (Normal)
+                     => 0x01 (Icon)
+Byte 4: Bit7~Bit0 => Don't Care
+
+==============================================================================
+* Absolute position for STL3888-A0.
+==============================================================================
+Packet 1 (ABSOLUTE POSITION)
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |0|1|V|A|1|L|0|1|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 |x|x|y|y|X|X|Y|Y|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordination packet
+                  => 10, Notify packet
+        Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
+                When both fingers are up, the last two reports have zero valid
+                bit.
+        Bit4 => arc
+        Bit3 => 1
+        Bit2 => Left Button, 1 is pressed, 0 is released.
+        Bit1 => 0
+        Bit0 => 1
+Byte 2: X coordinate (xpos[9:2])
+Byte 3: Y coordinate (ypos[9:2])
+Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
+        Bit3~Bit2 => X coordinate (ypos[1:0])
+        Bit5~Bit4 => y1_g
+        Bit7~Bit6 => x1_g
+
+Packet 2 (ABSOLUTE POSITION)
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |0|1|V|A|1|R|1|0|  2  |X|X|X|X|X|X|X|X|  3 |Y|Y|Y|Y|Y|Y|Y|Y|  4 |x|x|y|y|X|X|Y|Y|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordinates packet
+                  => 10, Notify packet
+        Bit5 => Valid bit, 0 means that the coordinate is invalid or finger up.
+                When both fingers are up, the last two reports have zero valid
+                bit.
+        Bit4 => arc
+        Bit3 => 1
+        Bit2 => Right Button, 1 is pressed, 0 is released.
+        Bit1 => 1
+        Bit0 => 0
+Byte 2: X coordinate (xpos[9:2])
+Byte 3: Y coordinate (ypos[9:2])
+Byte 4: Bit1~Bit0 => Y coordinate (xpos[1:0])
+        Bit3~Bit2 => X coordinate (ypos[1:0])
+        Bit5~Bit4 => y2_g
+        Bit7~Bit6 => x2_g
+
+Notify Packet for STL3888-A0
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |1|0|1|P|1|M|R|L|  2  |C|C|C|C|C|C|C|C|  3 |0|0|F|F|0|0|0|i|  4 |r|l|d|u|0|0|0|0|
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+Byte 1: Bit7~Bit6 => 00, Normal data packet
+                  => 01, Absolute coordination packet
+                  => 10, Notify packet
+        Bit5 => 1
+        Bit4 => when in absolute coordinates mode (valid when EN_PKT_GO is 1):
+                0: left button is generated by the on-pad command
+                1: left button is generated by the external button
+        Bit3 => 1
+        Bit2 => Middle Button, 1 is pressed, 0 is not pressed.
+        Bit1 => Right Button, 1 is pressed, 0 is not pressed.
+        Bit0 => Left Button, 1 is pressed, 0 is not pressed.
+Byte 2: Message Type => 0xB7 (Multi Finger, Multi Coordinate mode)
+Byte 3: Bit7~Bit6 => Don't care
+        Bit5~Bit4 => Number of fingers
+        Bit3~Bit1 => Reserved
+        Bit0 => 1: enter gesture mode; 0: leaving gesture mode
+Byte 4: Bit7 => scroll right button
+        Bit6 => scroll left button
+        Bit5 => scroll down button
+        Bit4 => scroll up button
+            * Note that if gesture and additional button (Bit4~Bit7)
+	      happen at the same time, the button information will not
+	      be sent.
+        Bit3~Bit0 => Reserved
+
+Sample sequence of Multi-finger, Multi-coordinate mode:
+
+	notify packet (valid bit == 1), abs pkt 1, abs pkt 2, abs pkt 1,
+	abs pkt 2, ..., notify packet(valid bit == 0)
+
+==============================================================================
+* FSP Enable/Disable packet
+==============================================================================
+   Bit 7 6 5 4 3 2 1 0       7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0      7 6 5 4 3 2 1 0
+BYTE  |---------------|BYTE |---------------|BYTE|---------------|BYTE|---------------|
+  1   |Y|X|0|0|1|M|R|L|  2  |0|1|0|1|1|0|1|E|  3 | | | | | | | | |  4 | | | | | | | | |
+      |---------------|     |---------------|    |---------------|    |---------------|
+
+FSP will send out enable/disable packet when FSP receive PS/2 enable/disable
+command. Host will receive the packet which Middle, Right, Left button will
+be set. The packet only use byte 0 and byte 1 as a pattern of original packet.
+Ignore the other bytes of the packet.
+
+Byte 1: Bit7 => 0, Y overflow
+        Bit6 => 0, X overflow
+	Bit5 => 0, Y sign bit
+        Bit4 => 0, X sign bit
+	Bit3 => 1
+	Bit2 => 1, Middle Button
+        Bit1 => 1, Right Button
+        Bit0 => 1, Left Button
+Byte 2: Bit7~1 => (0101101b)
+        Bit0 => 1 = Enable
+		0 = Disable
+Byte 3: Don't care
+Byte 4: Don't care (MOUSE ID 3, 4)
+Byte 5~8: Don't care (Absolute packet)
+
+==============================================================================
+* PS/2 Command Set
+==============================================================================
+
+FSP supports basic PS/2 commanding set and modes, refer to following URL for
+details about PS/2 commands:
+
+http://www.computer-engineering.org/index.php?title=PS/2_Mouse_Interface
+
+==============================================================================
+* Programming Sequence for Determining Packet Parsing Flow
+==============================================================================
+1. Identify FSP by reading device ID(0x00) and version(0x01) register
+
+2. Determine number of buttons by reading status2 (0x0b) register
+
+	buttons = reg[0x0b] & 0x30
+
+	if buttons == 0x30 or buttons == 0x20:
+		# two/four buttons
+		Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
+		section A for packet parsing detail(ignore byte 4, bit ~ 7)
+	elif buttons == 0x10:
+		# 6 buttons
+		Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
+		section B for packet parsing detail
+	elif buttons == 0x00:
+		# 6 buttons
+		Refer to 'Finger Sensing Pad PS/2 Mouse Intellimouse'
+		section A for packet parsing detail
+
+==============================================================================
+* Programming Sequence for Register Reading/Writing
+==============================================================================
+
+Register inversion requirement:
+
+  Following values needed to be inverted(the '~' operator in C) before being
+sent to FSP:
+
+	0xe9, 0xee, 0xf2 and 0xff.
+
+Register swapping requirement:
+
+  Following values needed to have their higher 4 bits and lower 4 bits being
+swapped before being sent to FSP:
+
+	10, 20, 40, 60, 80, 100 and 200.
+
+Register reading sequence:
+
+	1. send 0xf3 PS/2 command to FSP;
+
+	2. send 0x66 PS/2 command to FSP;
+
+	3. send 0x88 PS/2 command to FSP;
+
+	4. send 0xf3 PS/2 command to FSP;
+
+	5. if the register address being to read is not required to be
+	inverted(refer to the 'Register inversion requirement' section),
+	goto step 6
+
+	5a. send 0x68 PS/2 command to FSP;
+
+	5b. send the inverted register address to FSP and goto step 8;
+
+	6. if the register address being to read is not required to be
+	swapped(refer to the 'Register swapping requirement' section),
+	goto step 7
+
+	6a. send 0xcc PS/2 command to FSP;
+
+	6b. send the swapped register address to FSP and goto step 8;
+
+	7. send 0x66 PS/2 command to FSP;
+
+	7a. send the original register address to FSP and goto step 8;
+
+	8. send 0xe9(status request) PS/2 command to FSP;
+
+	9. the response read from FSP should be the requested register value.
+
+Register writing sequence:
+
+	1. send 0xf3 PS/2 command to FSP;
+
+	2. if the register address being to write is not required to be
+	inverted(refer to the 'Register inversion requirement' section),
+	goto step 3
+
+	2a. send 0x74 PS/2 command to FSP;
+
+	2b. send the inverted register address to FSP and goto step 5;
+
+	3. if the register address being to write is not required to be
+	swapped(refer to the 'Register swapping requirement' section),
+	goto step 4
+
+	3a. send 0x77 PS/2 command to FSP;
+
+	3b. send the swapped register address to FSP and goto step 5;
+
+	4. send 0x55 PS/2 command to FSP;
+
+	4a. send the register address to FSP and goto step 5;
+
+	5. send 0xf3 PS/2 command to FSP;
+
+	6. if the register value being to write is not required to be
+	inverted(refer to the 'Register inversion requirement' section),
+	goto step 7
+
+	6a. send 0x47 PS/2 command to FSP;
+
+	6b. send the inverted register value to FSP and goto step 9;
+
+	7. if the register value being to write is not required to be
+	swapped(refer to the 'Register swapping requirement' section),
+	goto step 8
+
+	7a. send 0x44 PS/2 command to FSP;
+
+	7b. send the swapped register value to FSP and goto step 9;
+
+	8. send 0x33 PS/2 command to FSP;
+
+	8a. send the register value to FSP;
+
+	9. the register writing sequence is completed.
+
+==============================================================================
+* Register Listing
+==============================================================================
+
+offset	width		default	r/w	name
+0x00	bit7~bit0	0x01	RO	device ID
+
+0x01	bit7~bit0	0xc0	RW	version ID
+
+0x02	bit7~bit0	0x01	RO	vendor ID
+
+0x03	bit7~bit0	0x01	RO	product ID
+
+0x04	bit3~bit0	0x01	RW	revision ID
+
+0x0b				RO	test mode status 1
+	bit3		1	RO	0: rotate 180 degree, 1: no rotation
+
+	bit5~bit4		RO	number of buttons
+			11 => 2, lbtn/rbtn
+			10 => 4, lbtn/rbtn/scru/scrd
+			01 => 6, lbtn/rbtn/scru/scrd/scrl/scrr
+			00 => 6, lbtn/rbtn/scru/scrd/fbtn/bbtn
+
+0x0f				RW	register file page control
+	bit0		0	RW	1 to enable page 1 register files
+
+0x10				RW	system control 1
+	bit0		1	RW	Reserved, must be 1
+	bit1		0	RW	Reserved, must be 0
+	bit4		1	RW	Reserved, must be 0
+	bit5		0	RW	register clock gating enable
+					0: read only, 1: read/write enable
+	(Note that following registers does not require clock gating being
+	enabled prior to write: 05 06 07 08 09 0c 0f 10 11 12 16 17 18 23 2e
+	40 41 42 43.)
+
+0x31				RW	on-pad command detection
+	bit7		0	RW	on-pad command left button down tag
+					enable
+					0: disable, 1: enable
+
+0x34				RW	on-pad command control 5
+	bit4~bit0	0x05	RW	XLO in 0s/4/1, so 03h = 0010.1b = 2.5
+	(Note that position unit is in 0.5 scanline)
+
+	bit7		0	RW	on-pad tap zone enable
+					0: disable, 1: enable
+
+0x35				RW	on-pad command control 6
+	bit4~bit0	0x1d	RW	XHI in 0s/4/1, so 19h = 1100.1b = 12.5
+	(Note that position unit is in 0.5 scanline)
+
+0x36				RW	on-pad command control 7
+	bit4~bit0	0x04	RW	YLO in 0s/4/1, so 03h = 0010.1b = 2.5
+	(Note that position unit is in 0.5 scanline)
+
+0x37				RW	on-pad command control 8
+	bit4~bit0	0x13	RW	YHI in 0s/4/1, so 11h = 1000.1b = 8.5
+	(Note that position unit is in 0.5 scanline)
+
+0x40				RW	system control 5
+	bit1		0	RW	FSP Intellimouse mode enable
+					0: disable, 1: enable
+
+	bit2		0	RW	movement + abs. coordinate mode enable
+					0: disable, 1: enable
+	(Note that this function has the functionality of bit 1 even when
+	bit 1 is not set. However, the format is different from that of bit 1.
+	In addition, when bit 1 and bit 2 are set at the same time, bit 2 will
+	override bit 1.)
+
+	bit3		0	RW	abs. coordinate only mode enable
+					0: disable, 1: enable
+	(Note that this function has the functionality of bit 1 even when
+	bit 1 is not set. However, the format is different from that of bit 1.
+	In addition, when bit 1, bit 2 and bit 3 are set at the same time,
+	bit 3 will override bit 1 and 2.)
+
+	bit5		0	RW	auto switch enable
+					0: disable, 1: enable
+
+	bit6		0	RW	G0 abs. + notify packet format enable
+					0: disable, 1: enable
+	(Note that the absolute/relative coordinate output still depends on
+	bit 2 and 3.  That is, if any of those bit is 1, host will receive
+	absolute coordinates; otherwise, host only receives packets with
+	relative coordinate.)
+
+0x43				RW	on-pad control
+	bit0		0	RW	on-pad control enable
+					0: disable, 1: enable
+	(Note that if this bit is cleared, bit 3/5 will be ineffective)
+
+	bit3		0	RW	on-pad fix vertical scrolling enable
+					0: disable, 1: enable
+
+	bit5		0	RW	on-pad fix horizontal scrolling enable
+					0: disable, 1: enable
diff --git a/Documentation/intel_txt.txt b/Documentation/intel_txt.txt
new file mode 100644
index 0000000..f40a1f0
--- /dev/null
+++ b/Documentation/intel_txt.txt
@@ -0,0 +1,210 @@
+Intel(R) TXT Overview:
+=====================
+
+Intel's technology for safer computing, Intel(R) Trusted Execution
+Technology (Intel(R) TXT), defines platform-level enhancements that
+provide the building blocks for creating trusted platforms.
+
+Intel TXT was formerly known by the code name LaGrande Technology (LT).
+
+Intel TXT in Brief:
+o  Provides dynamic root of trust for measurement (DRTM)
+o  Data protection in case of improper shutdown
+o  Measurement and verification of launched environment
+
+Intel TXT is part of the vPro(TM) brand and is also available some
+non-vPro systems.  It is currently available on desktop systems
+based on the Q35, X38, Q45, and Q43 Express chipsets (e.g. Dell
+Optiplex 755, HP dc7800, etc.) and mobile systems based on the GM45,
+PM45, and GS45 Express chipsets.
+
+For more information, see http://www.intel.com/technology/security/.
+This site also has a link to the Intel TXT MLE Developers Manual,
+which has been updated for the new released platforms.
+
+Intel TXT has been presented at various events over the past few
+years, some of which are:
+      LinuxTAG 2008:
+          http://www.linuxtag.org/2008/en/conf/events/vp-donnerstag/
+          details.html?talkid=110
+      TRUST2008:
+          http://www.trust2008.eu/downloads/Keynote-Speakers/
+          3_David-Grawrock_The-Front-Door-of-Trusted-Computing.pdf
+      IDF 2008, Shanghai:
+          http://inteldeveloperforum.com.edgesuite.net/shanghai_2008/
+          aep/PROS003/index.html
+      IDFs 2006, 2007 (I'm not sure if/where they are online)
+
+Trusted Boot Project Overview:
+=============================
+
+Trusted Boot (tboot) is an open source, pre- kernel/VMM module that
+uses Intel TXT to perform a measured and verified launch of an OS
+kernel/VMM.
+
+It is hosted on SourceForge at http://sourceforge.net/projects/tboot.
+The mercurial source repo is available at http://www.bughost.org/
+repos.hg/tboot.hg.
+
+Tboot currently supports launching Xen (open source VMM/hypervisor
+w/ TXT support since v3.2), and now Linux kernels.
+
+
+Value Proposition for Linux or "Why should you care?"
+=====================================================
+
+While there are many products and technologies that attempt to
+measure or protect the integrity of a running kernel, they all
+assume the kernel is "good" to begin with.  The Integrity
+Measurement Architecture (IMA) and Linux Integrity Module interface
+are examples of such solutions.
+
+To get trust in the initial kernel without using Intel TXT, a
+static root of trust must be used.  This bases trust in BIOS
+starting at system reset and requires measurement of all code
+executed between system reset through the completion of the kernel
+boot as well as data objects used by that code.  In the case of a
+Linux kernel, this means all of BIOS, any option ROMs, the
+bootloader and the boot config.  In practice, this is a lot of
+code/data, much of which is subject to change from boot to boot
+(e.g. changing NICs may change option ROMs).  Without reference
+hashes, these measurement changes are difficult to assess or
+confirm as benign.  This process also does not provide DMA
+protection, memory configuration/alias checks and locks, crash
+protection, or policy support.
+
+By using the hardware-based root of trust that Intel TXT provides,
+many of these issues can be mitigated.  Specifically: many
+pre-launch components can be removed from the trust chain, DMA
+protection is provided to all launched components, a large number
+of platform configuration checks are performed and values locked,
+protection is provided for any data in the event of an improper
+shutdown, and there is support for policy-based execution/verification.
+This provides a more stable measurement and a higher assurance of
+system configuration and initial state than would be otherwise
+possible.  Since the tboot project is open source, source code for
+almost all parts of the trust chain is available (excepting SMM and
+Intel-provided firmware).
+
+How Does it Work?
+=================
+
+o  Tboot is an executable that is launched by the bootloader as
+   the "kernel" (the binary the bootloader executes).
+o  It performs all of the work necessary to determine if the
+   platform supports Intel TXT and, if so, executes the GETSEC[SENTER]
+   processor instruction that initiates the dynamic root of trust.
+   -  If tboot determines that the system does not support Intel TXT
+      or is not configured correctly (e.g. the SINIT AC Module was
+      incorrect), it will directly launch the kernel with no changes
+      to any state.
+   -  Tboot will output various information about its progress to the
+      terminal, serial port, and/or an in-memory log; the output
+      locations can be configured with a command line switch.
+o  The GETSEC[SENTER] instruction will return control to tboot and
+   tboot then verifies certain aspects of the environment (e.g. TPM NV
+   lock, e820 table does not have invalid entries, etc.).
+o  It will wake the APs from the special sleep state the GETSEC[SENTER]
+   instruction had put them in and place them into a wait-for-SIPI
+   state.
+   -  Because the processors will not respond to an INIT or SIPI when
+      in the TXT environment, it is necessary to create a small VT-x
+      guest for the APs.  When they run in this guest, they will
+      simply wait for the INIT-SIPI-SIPI sequence, which will cause
+      VMEXITs, and then disable VT and jump to the SIPI vector.  This
+      approach seemed like a better choice than having to insert
+      special code into the kernel's MP wakeup sequence.
+o  Tboot then applies an (optional) user-defined launch policy to
+   verify the kernel and initrd.
+   -  This policy is rooted in TPM NV and is described in the tboot
+      project.  The tboot project also contains code for tools to
+      create and provision the policy.
+   -  Policies are completely under user control and if not present
+      then any kernel will be launched.
+   -  Policy action is flexible and can include halting on failures
+      or simply logging them and continuing.
+o  Tboot adjusts the e820 table provided by the bootloader to reserve
+   its own location in memory as well as to reserve certain other
+   TXT-related regions.
+o  As part of it's launch, tboot DMA protects all of RAM (using the
+   VT-d PMRs).  Thus, the kernel must be booted with 'intel_iommu=on'
+   in order to remove this blanket protection and use VT-d's
+   page-level protection.
+o  Tboot will populate a shared page with some data about itself and
+   pass this to the Linux kernel as it transfers control.
+   -  The location of the shared page is passed via the boot_params
+      struct as a physical address.
+o  The kernel will look for the tboot shared page address and, if it
+   exists, map it.
+o  As one of the checks/protections provided by TXT, it makes a copy
+   of the VT-d DMARs in a DMA-protected region of memory and verifies
+   them for correctness.  The VT-d code will detect if the kernel was
+   launched with tboot and use this copy instead of the one in the
+   ACPI table.
+o  At this point, tboot and TXT are out of the picture until a
+   shutdown (S<n>)
+o  In order to put a system into any of the sleep states after a TXT
+   launch, TXT must first be exited.  This is to prevent attacks that
+   attempt to crash the system to gain control on reboot and steal
+   data left in memory.
+   -  The kernel will perform all of its sleep preparation and
+      populate the shared page with the ACPI data needed to put the
+      platform in the desired sleep state.
+   -  Then the kernel jumps into tboot via the vector specified in the
+      shared page.
+   -  Tboot will clean up the environment and disable TXT, then use the
+      kernel-provided ACPI information to actually place the platform
+      into the desired sleep state.
+   -  In the case of S3, tboot will also register itself as the resume
+      vector.  This is necessary because it must re-establish the
+      measured environment upon resume.  Once the TXT environment
+      has been restored, it will restore the TPM PCRs and then
+      transfer control back to the kernel's S3 resume vector.
+      In order to preserve system integrity across S3, the kernel
+      provides tboot with a set of memory ranges (kernel
+      code/data/bss, S3 resume code, and AP trampoline) that tboot
+      will calculate a MAC (message authentication code) over and then
+      seal with the TPM.  On resume and once the measured environment
+      has been re-established, tboot will re-calculate the MAC and
+      verify it against the sealed value.  Tboot's policy determines
+      what happens if the verification fails.
+
+That's pretty much it for TXT support.
+
+
+Configuring the System:
+======================
+
+This code works with 32bit, 32bit PAE, and 64bit (x86_64) kernels.
+
+In BIOS, the user must enable:  TPM, TXT, VT-x, VT-d.  Not all BIOSes
+allow these to be individually enabled/disabled and the screens in
+which to find them are BIOS-specific.
+
+grub.conf needs to be modified as follows:
+        title Linux 2.6.29-tip w/ tboot
+          root (hd0,0)
+                kernel /tboot.gz logging=serial,vga,memory
+                module /vmlinuz-2.6.29-tip intel_iommu=on ro
+                       root=LABEL=/ rhgb console=ttyS0,115200 3
+                module /initrd-2.6.29-tip.img
+                module /Q35_SINIT_17.BIN
+
+The kernel option for enabling Intel TXT support is found under the
+Security top-level menu and is called "Enable Intel(R) Trusted
+Execution Technology (TXT)".  It is marked as EXPERIMENTAL and
+depends on the generic x86 support (to allow maximum flexibility in
+kernel build options), since the tboot code will detect whether the
+platform actually supports Intel TXT and thus whether any of the
+kernel code is executed.
+
+The Q35_SINIT_17.BIN file is what Intel TXT refers to as an
+Authenticated Code Module.  It is specific to the chipset in the
+system and can also be found on the Trusted Boot site.  It is an
+(unencrypted) module signed by Intel that is used as part of the
+DRTM process to verify and configure the system.  It is signed
+because it operates at a higher privilege level in the system than
+any other macrocode and its correct operation is critical to the
+establishment of the DRTM.  The process for determining the correct
+SINIT ACM for a system is documented in the SINIT-guide.txt file
+that is on the tboot SourceForge site under the SINIT ACM downloads.
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index dbea4f9..aafca0a 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -121,6 +121,7 @@ Code	Seq#	Include File		Comments
 'c'	00-7F	linux/comstats.h	conflict!
 'c'	00-7F	linux/coda.h		conflict!
 'c'	80-9F	arch/s390/include/asm/chsc.h
+'c'	A0-AF   arch/x86/include/asm/msr.h
 'd'	00-FF	linux/char/drm/drm/h	conflict!
 'd'	F0-FF	linux/digi1.h
 'e'	all	linux/digi1.h		conflict!
@@ -192,7 +193,7 @@ Code	Seq#	Include File		Comments
 0xAD	00	Netfilter device	in development:
 					<mailto:rusty@rustcorp.com.au>	
 0xAE	all	linux/kvm.h		Kernel-based Virtual Machine
-					<mailto:kvm-devel@lists.sourceforge.net>
+					<mailto:kvm@vger.kernel.org>
 0xB0	all	RATIO devices		in development:
 					<mailto:vgo@ratio.de>
 0xB1	00-1F	PPPoX			<mailto:mostrows@styx.uwaterloo.ca>
diff --git a/Documentation/kernel-doc-nano-HOWTO.txt b/Documentation/kernel-doc-nano-HOWTO.txt
index 4d04572..348b9e5 100644
--- a/Documentation/kernel-doc-nano-HOWTO.txt
+++ b/Documentation/kernel-doc-nano-HOWTO.txt
@@ -66,7 +66,9 @@ Example kernel-doc function comment:
  * The longer description can have multiple paragraphs.
  */
 
-The first line, with the short description, must be on a single line.
+The short description following the subject can span multiple lines
+and ends with an @argument description, an empty line or the end of
+the comment block.
 
 The @argument descriptions must begin on the very next line following
 this opening short function description line, with no intervening
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 5d4427d..0f17d16 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -57,6 +57,7 @@ parameter is applicable:
 	ISAPNP	ISA PnP code is enabled.
 	ISDN	Appropriate ISDN support is enabled.
 	JOY	Appropriate joystick support is enabled.
+	KVM	Kernel Virtual Machine support is enabled.
 	LIBATA  Libata driver is enabled
 	LP	Printer support is enabled.
 	LOOP	Loopback device support is enabled.
@@ -1098,6 +1099,44 @@ and is between 256 and 4096 characters. It is defined in the file
 	kstack=N	[X86] Print N words from the kernel stack
 			in oops dumps.
 
+	kvm.ignore_msrs=[KVM] Ignore guest accesses to unhandled MSRs.
+			Default is 0 (don't ignore, but inject #GP)
+
+	kvm.oos_shadow=	[KVM] Disable out-of-sync shadow paging.
+			Default is 1 (enabled)
+
+	kvm-amd.nested=	[KVM,AMD] Allow nested virtualization in KVM/SVM.
+			Default is 0 (off)
+
+	kvm-amd.npt=	[KVM,AMD] Disable nested paging (virtualized MMU)
+			for all guests.
+			Default is 1 (enabled) if in 64bit or 32bit-PAE mode
+
+	kvm-intel.bypass_guest_pf=
+			[KVM,Intel] Disables bypassing of guest page faults
+			on Intel chips. Default is 1 (enabled)
+
+	kvm-intel.ept=	[KVM,Intel] Disable extended page tables
+			(virtualized MMU) support on capable Intel chips.
+			Default is 1 (enabled)
+
+	kvm-intel.emulate_invalid_guest_state=
+			[KVM,Intel] Enable emulation of invalid guest states
+			Default is 0 (disabled)
+
+	kvm-intel.flexpriority=
+			[KVM,Intel] Disable FlexPriority feature (TPR shadow).
+			Default is 1 (enabled)
+
+	kvm-intel.unrestricted_guest=
+			[KVM,Intel] Disable unrestricted guest feature
+			(virtualized real and unpaged mode) on capable
+			Intel chips. Default is 1 (enabled)
+
+	kvm-intel.vpid=	[KVM,Intel] Disable Virtual Processor Identification
+			feature (tagged TLBs) on capable Intel chips.
+			Default is 1 (enabled)
+
 	l2cr=		[PPC]
 
 	l3cr=		[PPC]
@@ -1247,6 +1286,10 @@ and is between 256 and 4096 characters. It is defined in the file
 			(machvec) in a generic kernel.
 			Example: machvec=hpzx1_swiotlb
 
+	machtype=	[Loongson] Share the same kernel image file between different
+			 yeeloong laptop.
+			Example: machtype=lemote-yeeloong-2f-7inch
+
 	max_addr=nn[KMG]	[KNL,BOOT,ia64] All physical memory greater
 			than or equal to this physical address is ignored.
 
@@ -1522,7 +1565,7 @@ and is between 256 and 4096 characters. It is defined in the file
 			of returning the full 64-bit number.
 			The default is to return 64-bit inode numbers.
 
-	nmi_debug=	[KNL,AVR32] Specify one or more actions to take
+	nmi_debug=	[KNL,AVR32,SH] Specify one or more actions to take
 			when a NMI is triggered.
 			Format: [state][,regs][,debounce][,die]
 
@@ -1543,6 +1586,11 @@ and is between 256 and 4096 characters. It is defined in the file
 			symbolic names: lapic and ioapic
 			Example: nmi_watchdog=2 or nmi_watchdog=panic,lapic
 
+	netpoll.carrier_timeout=
+			[NET] Specifies amount of time (in seconds) that
+			netpoll should wait for a carrier. By default netpoll
+			waits 4 seconds.
+
 	no387		[BUGS=X86-32] Tells the kernel to use the 387 maths
 			emulation library even if a 387 maths coprocessor
 			is present.
@@ -1927,11 +1975,12 @@ and is between 256 and 4096 characters. It is defined in the file
 			Format: { 0 | 1 }
 			See arch/parisc/kernel/pdc_chassis.c
 
-	percpu_alloc=	[X86] Select which percpu first chunk allocator to use.
-			Allowed values are one of "lpage", "embed" and "4k".
-			See comments in arch/x86/kernel/setup_percpu.c for
-			details on each allocator.  This parameter is primarily
-			for debugging and performance comparison.
+	percpu_alloc=	Select which percpu first chunk allocator to use.
+			Currently supported values are "embed" and "page".
+			Archs may support subset or none of the	selections.
+			See comments in mm/percpu.c for details on each
+			allocator.  This parameter is primarily	for debugging
+			and performance comparison.
 
 	pf.		[PARIDE]
 			See Documentation/blockdev/paride.txt.
diff --git a/Documentation/kref.txt b/Documentation/kref.txt
index 130b6e8..ae203f9 100644
--- a/Documentation/kref.txt
+++ b/Documentation/kref.txt
@@ -84,7 +84,6 @@ int my_data_handler(void)
 	task = kthread_run(more_data_handling, data, "more_data_handling");
 	if (task == ERR_PTR(-ENOMEM)) {
 		rv = -ENOMEM;
-	        kref_put(&data->refcount, data_release);
 		goto out;
 	}
 
diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
new file mode 100644
index 0000000..5a4bc8c
--- /dev/null
+++ b/Documentation/kvm/api.txt
@@ -0,0 +1,759 @@
+The Definitive KVM (Kernel-based Virtual Machine) API Documentation
+===================================================================
+
+1. General description
+
+The kvm API is a set of ioctls that are issued to control various aspects
+of a virtual machine.  The ioctls belong to three classes
+
+ - System ioctls: These query and set global attributes which affect the
+   whole kvm subsystem.  In addition a system ioctl is used to create
+   virtual machines
+
+ - VM ioctls: These query and set attributes that affect an entire virtual
+   machine, for example memory layout.  In addition a VM ioctl is used to
+   create virtual cpus (vcpus).
+
+   Only run VM ioctls from the same process (address space) that was used
+   to create the VM.
+
+ - vcpu ioctls: These query and set attributes that control the operation
+   of a single virtual cpu.
+
+   Only run vcpu ioctls from the same thread that was used to create the
+   vcpu.
+
+2. File descritpors
+
+The kvm API is centered around file descriptors.  An initial
+open("/dev/kvm") obtains a handle to the kvm subsystem; this handle
+can be used to issue system ioctls.  A KVM_CREATE_VM ioctl on this
+handle will create a VM file descripror which can be used to issue VM
+ioctls.  A KVM_CREATE_VCPU ioctl on a VM fd will create a virtual cpu
+and return a file descriptor pointing to it.  Finally, ioctls on a vcpu
+fd can be used to control the vcpu, including the important task of
+actually running guest code.
+
+In general file descriptors can be migrated among processes by means
+of fork() and the SCM_RIGHTS facility of unix domain socket.  These
+kinds of tricks are explicitly not supported by kvm.  While they will
+not cause harm to the host, their actual behavior is not guaranteed by
+the API.  The only supported use is one virtual machine per process,
+and one vcpu per thread.
+
+3. Extensions
+
+As of Linux 2.6.22, the KVM ABI has been stabilized: no backward
+incompatible change are allowed.  However, there is an extension
+facility that allows backward-compatible extensions to the API to be
+queried and used.
+
+The extension mechanism is not based on on the Linux version number.
+Instead, kvm defines extension identifiers and a facility to query
+whether a particular extension identifier is available.  If it is, a
+set of ioctls is available for application use.
+
+4. API description
+
+This section describes ioctls that can be used to control kvm guests.
+For each ioctl, the following information is provided along with a
+description:
+
+  Capability: which KVM extension provides this ioctl.  Can be 'basic',
+      which means that is will be provided by any kernel that supports
+      API version 12 (see section 4.1), or a KVM_CAP_xyz constant, which
+      means availability needs to be checked with KVM_CHECK_EXTENSION
+      (see section 4.4).
+
+  Architectures: which instruction set architectures provide this ioctl.
+      x86 includes both i386 and x86_64.
+
+  Type: system, vm, or vcpu.
+
+  Parameters: what parameters are accepted by the ioctl.
+
+  Returns: the return value.  General error numbers (EBADF, ENOMEM, EINVAL)
+      are not detailed, but errors with specific meanings are.
+
+4.1 KVM_GET_API_VERSION
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: none
+Returns: the constant KVM_API_VERSION (=12)
+
+This identifies the API version as the stable kvm API. It is not
+expected that this number will change.  However, Linux 2.6.20 and
+2.6.21 report earlier versions; these are not documented and not
+supported.  Applications should refuse to run if KVM_GET_API_VERSION
+returns a value other than 12.  If this check passes, all ioctls
+described as 'basic' will be available.
+
+4.2 KVM_CREATE_VM
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: none
+Returns: a VM fd that can be used to control the new virtual machine.
+
+The new VM has no virtual cpus and no memory.  An mmap() of a VM fd
+will access the virtual machine's physical address space; offset zero
+corresponds to guest physical address zero.  Use of mmap() on a VM fd
+is discouraged if userspace memory allocation (KVM_CAP_USER_MEMORY) is
+available.
+
+4.3 KVM_GET_MSR_INDEX_LIST
+
+Capability: basic
+Architectures: x86
+Type: system
+Parameters: struct kvm_msr_list (in/out)
+Returns: 0 on success; -1 on error
+Errors:
+  E2BIG:     the msr index list is to be to fit in the array specified by
+             the user.
+
+struct kvm_msr_list {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 indices[0];
+};
+
+This ioctl returns the guest msrs that are supported.  The list varies
+by kvm version and host processor, but does not change otherwise.  The
+user fills in the size of the indices array in nmsrs, and in return
+kvm adjusts nmsrs to reflect the actual number of msrs and fills in
+the indices array with their numbers.
+
+4.4 KVM_CHECK_EXTENSION
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: extension identifier (KVM_CAP_*)
+Returns: 0 if unsupported; 1 (or some other positive integer) if supported
+
+The API allows the application to query about extensions to the core
+kvm API.  Userspace passes an extension identifier (an integer) and
+receives an integer that describes the extension availability.
+Generally 0 means no and 1 means yes, but some extensions may report
+additional information in the integer return value.
+
+4.5 KVM_GET_VCPU_MMAP_SIZE
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: none
+Returns: size of vcpu mmap area, in bytes
+
+The KVM_RUN ioctl (cf.) communicates with userspace via a shared
+memory region.  This ioctl returns the size of that region.  See the
+KVM_RUN documentation for details.
+
+4.6 KVM_SET_MEMORY_REGION
+
+Capability: basic
+Architectures: all
+Type: vm ioctl
+Parameters: struct kvm_memory_region (in)
+Returns: 0 on success, -1 on error
+
+struct kvm_memory_region {
+	__u32 slot;
+	__u32 flags;
+	__u64 guest_phys_addr;
+	__u64 memory_size; /* bytes */
+};
+
+/* for kvm_memory_region::flags */
+#define KVM_MEM_LOG_DIRTY_PAGES  1UL
+
+This ioctl allows the user to create or modify a guest physical memory
+slot.  When changing an existing slot, it may be moved in the guest
+physical memory space, or its flags may be modified.  It may not be
+resized.  Slots may not overlap.
+
+The flags field supports just one flag, KVM_MEM_LOG_DIRTY_PAGES, which
+instructs kvm to keep track of writes to memory within the slot.  See
+the KVM_GET_DIRTY_LOG ioctl.
+
+It is recommended to use the KVM_SET_USER_MEMORY_REGION ioctl instead
+of this API, if available.  This newer API allows placing guest memory
+at specified locations in the host address space, yielding better
+control and easy access.
+
+4.6 KVM_CREATE_VCPU
+
+Capability: basic
+Architectures: all
+Type: vm ioctl
+Parameters: vcpu id (apic id on x86)
+Returns: vcpu fd on success, -1 on error
+
+This API adds a vcpu to a virtual machine.  The vcpu id is a small integer
+in the range [0, max_vcpus).
+
+4.7 KVM_GET_DIRTY_LOG (vm ioctl)
+
+Capability: basic
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_dirty_log (in/out)
+Returns: 0 on success, -1 on error
+
+/* for KVM_GET_DIRTY_LOG */
+struct kvm_dirty_log {
+	__u32 slot;
+	__u32 padding;
+	union {
+		void __user *dirty_bitmap; /* one bit per page */
+		__u64 padding;
+	};
+};
+
+Given a memory slot, return a bitmap containing any pages dirtied
+since the last call to this ioctl.  Bit 0 is the first page in the
+memory slot.  Ensure the entire structure is cleared to avoid padding
+issues.
+
+4.8 KVM_SET_MEMORY_ALIAS
+
+Capability: basic
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_memory_alias (in)
+Returns: 0 (success), -1 (error)
+
+struct kvm_memory_alias {
+	__u32 slot;  /* this has a different namespace than memory slots */
+	__u32 flags;
+	__u64 guest_phys_addr;
+	__u64 memory_size;
+	__u64 target_phys_addr;
+};
+
+Defines a guest physical address space region as an alias to another
+region.  Useful for aliased address, for example the VGA low memory
+window. Should not be used with userspace memory.
+
+4.9 KVM_RUN
+
+Capability: basic
+Architectures: all
+Type: vcpu ioctl
+Parameters: none
+Returns: 0 on success, -1 on error
+Errors:
+  EINTR:     an unmasked signal is pending
+
+This ioctl is used to run a guest virtual cpu.  While there are no
+explicit parameters, there is an implicit parameter block that can be
+obtained by mmap()ing the vcpu fd at offset 0, with the size given by
+KVM_GET_VCPU_MMAP_SIZE.  The parameter block is formatted as a 'struct
+kvm_run' (see below).
+
+4.10 KVM_GET_REGS
+
+Capability: basic
+Architectures: all
+Type: vcpu ioctl
+Parameters: struct kvm_regs (out)
+Returns: 0 on success, -1 on error
+
+Reads the general purpose registers from the vcpu.
+
+/* x86 */
+struct kvm_regs {
+	/* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
+	__u64 rax, rbx, rcx, rdx;
+	__u64 rsi, rdi, rsp, rbp;
+	__u64 r8,  r9,  r10, r11;
+	__u64 r12, r13, r14, r15;
+	__u64 rip, rflags;
+};
+
+4.11 KVM_SET_REGS
+
+Capability: basic
+Architectures: all
+Type: vcpu ioctl
+Parameters: struct kvm_regs (in)
+Returns: 0 on success, -1 on error
+
+Writes the general purpose registers into the vcpu.
+
+See KVM_GET_REGS for the data structure.
+
+4.12 KVM_GET_SREGS
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_sregs (out)
+Returns: 0 on success, -1 on error
+
+Reads special registers from the vcpu.
+
+/* x86 */
+struct kvm_sregs {
+	struct kvm_segment cs, ds, es, fs, gs, ss;
+	struct kvm_segment tr, ldt;
+	struct kvm_dtable gdt, idt;
+	__u64 cr0, cr2, cr3, cr4, cr8;
+	__u64 efer;
+	__u64 apic_base;
+	__u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
+};
+
+interrupt_bitmap is a bitmap of pending external interrupts.  At most
+one bit may be set.  This interrupt has been acknowledged by the APIC
+but not yet injected into the cpu core.
+
+4.13 KVM_SET_SREGS
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_sregs (in)
+Returns: 0 on success, -1 on error
+
+Writes special registers into the vcpu.  See KVM_GET_SREGS for the
+data structures.
+
+4.14 KVM_TRANSLATE
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_translation (in/out)
+Returns: 0 on success, -1 on error
+
+Translates a virtual address according to the vcpu's current address
+translation mode.
+
+struct kvm_translation {
+	/* in */
+	__u64 linear_address;
+
+	/* out */
+	__u64 physical_address;
+	__u8  valid;
+	__u8  writeable;
+	__u8  usermode;
+	__u8  pad[5];
+};
+
+4.15 KVM_INTERRUPT
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_interrupt (in)
+Returns: 0 on success, -1 on error
+
+Queues a hardware interrupt vector to be injected.  This is only
+useful if in-kernel local APIC is not used.
+
+/* for KVM_INTERRUPT */
+struct kvm_interrupt {
+	/* in */
+	__u32 irq;
+};
+
+Note 'irq' is an interrupt vector, not an interrupt pin or line.
+
+4.16 KVM_DEBUG_GUEST
+
+Capability: basic
+Architectures: none
+Type: vcpu ioctl
+Parameters: none)
+Returns: -1 on error
+
+Support for this has been removed.  Use KVM_SET_GUEST_DEBUG instead.
+
+4.17 KVM_GET_MSRS
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_msrs (in/out)
+Returns: 0 on success, -1 on error
+
+Reads model-specific registers from the vcpu.  Supported msr indices can
+be obtained using KVM_GET_MSR_INDEX_LIST.
+
+struct kvm_msrs {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 pad;
+
+	struct kvm_msr_entry entries[0];
+};
+
+struct kvm_msr_entry {
+	__u32 index;
+	__u32 reserved;
+	__u64 data;
+};
+
+Application code should set the 'nmsrs' member (which indicates the
+size of the entries array) and the 'index' member of each array entry.
+kvm will fill in the 'data' member.
+
+4.18 KVM_SET_MSRS
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_msrs (in)
+Returns: 0 on success, -1 on error
+
+Writes model-specific registers to the vcpu.  See KVM_GET_MSRS for the
+data structures.
+
+Application code should set the 'nmsrs' member (which indicates the
+size of the entries array), and the 'index' and 'data' members of each
+array entry.
+
+4.19 KVM_SET_CPUID
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_cpuid (in)
+Returns: 0 on success, -1 on error
+
+Defines the vcpu responses to the cpuid instruction.  Applications
+should use the KVM_SET_CPUID2 ioctl if available.
+
+
+struct kvm_cpuid_entry {
+	__u32 function;
+	__u32 eax;
+	__u32 ebx;
+	__u32 ecx;
+	__u32 edx;
+	__u32 padding;
+};
+
+/* for KVM_SET_CPUID */
+struct kvm_cpuid {
+	__u32 nent;
+	__u32 padding;
+	struct kvm_cpuid_entry entries[0];
+};
+
+4.20 KVM_SET_SIGNAL_MASK
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_signal_mask (in)
+Returns: 0 on success, -1 on error
+
+Defines which signals are blocked during execution of KVM_RUN.  This
+signal mask temporarily overrides the threads signal mask.  Any
+unblocked signal received (except SIGKILL and SIGSTOP, which retain
+their traditional behaviour) will cause KVM_RUN to return with -EINTR.
+
+Note the signal will only be delivered if not blocked by the original
+signal mask.
+
+/* for KVM_SET_SIGNAL_MASK */
+struct kvm_signal_mask {
+	__u32 len;
+	__u8  sigset[0];
+};
+
+4.21 KVM_GET_FPU
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_fpu (out)
+Returns: 0 on success, -1 on error
+
+Reads the floating point state from the vcpu.
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+	__u8  fpr[8][16];
+	__u16 fcw;
+	__u16 fsw;
+	__u8  ftwx;  /* in fxsave format */
+	__u8  pad1;
+	__u16 last_opcode;
+	__u64 last_ip;
+	__u64 last_dp;
+	__u8  xmm[16][16];
+	__u32 mxcsr;
+	__u32 pad2;
+};
+
+4.22 KVM_SET_FPU
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_fpu (in)
+Returns: 0 on success, -1 on error
+
+Writes the floating point state to the vcpu.
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+	__u8  fpr[8][16];
+	__u16 fcw;
+	__u16 fsw;
+	__u8  ftwx;  /* in fxsave format */
+	__u8  pad1;
+	__u16 last_opcode;
+	__u64 last_ip;
+	__u64 last_dp;
+	__u8  xmm[16][16];
+	__u32 mxcsr;
+	__u32 pad2;
+};
+
+4.23 KVM_CREATE_IRQCHIP
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: none
+Returns: 0 on success, -1 on error
+
+Creates an interrupt controller model in the kernel.  On x86, creates a virtual
+ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a
+local APIC.  IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23
+only go to the IOAPIC.  On ia64, a IOSAPIC is created.
+
+4.24 KVM_IRQ_LINE
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: struct kvm_irq_level
+Returns: 0 on success, -1 on error
+
+Sets the level of a GSI input to the interrupt controller model in the kernel.
+Requires that an interrupt controller model has been previously created with
+KVM_CREATE_IRQCHIP.  Note that edge-triggered interrupts require the level
+to be set to 1 and then back to 0.
+
+struct kvm_irq_level {
+	union {
+		__u32 irq;     /* GSI */
+		__s32 status;  /* not used for KVM_IRQ_LEVEL */
+	};
+	__u32 level;           /* 0 or 1 */
+};
+
+4.25 KVM_GET_IRQCHIP
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: struct kvm_irqchip (in/out)
+Returns: 0 on success, -1 on error
+
+Reads the state of a kernel interrupt controller created with
+KVM_CREATE_IRQCHIP into a buffer provided by the caller.
+
+struct kvm_irqchip {
+	__u32 chip_id;  /* 0 = PIC1, 1 = PIC2, 2 = IOAPIC */
+	__u32 pad;
+        union {
+		char dummy[512];  /* reserving space */
+		struct kvm_pic_state pic;
+		struct kvm_ioapic_state ioapic;
+	} chip;
+};
+
+4.26 KVM_SET_IRQCHIP
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: struct kvm_irqchip (in)
+Returns: 0 on success, -1 on error
+
+Sets the state of a kernel interrupt controller created with
+KVM_CREATE_IRQCHIP from a buffer provided by the caller.
+
+struct kvm_irqchip {
+	__u32 chip_id;  /* 0 = PIC1, 1 = PIC2, 2 = IOAPIC */
+	__u32 pad;
+        union {
+		char dummy[512];  /* reserving space */
+		struct kvm_pic_state pic;
+		struct kvm_ioapic_state ioapic;
+	} chip;
+};
+
+5. The kvm_run structure
+
+Application code obtains a pointer to the kvm_run structure by
+mmap()ing a vcpu fd.  From that point, application code can control
+execution by changing fields in kvm_run prior to calling the KVM_RUN
+ioctl, and obtain information about the reason KVM_RUN returned by
+looking up structure members.
+
+struct kvm_run {
+	/* in */
+	__u8 request_interrupt_window;
+
+Request that KVM_RUN return when it becomes possible to inject external
+interrupts into the guest.  Useful in conjunction with KVM_INTERRUPT.
+
+	__u8 padding1[7];
+
+	/* out */
+	__u32 exit_reason;
+
+When KVM_RUN has returned successfully (return value 0), this informs
+application code why KVM_RUN has returned.  Allowable values for this
+field are detailed below.
+
+	__u8 ready_for_interrupt_injection;
+
+If request_interrupt_window has been specified, this field indicates
+an interrupt can be injected now with KVM_INTERRUPT.
+
+	__u8 if_flag;
+
+The value of the current interrupt flag.  Only valid if in-kernel
+local APIC is not used.
+
+	__u8 padding2[2];
+
+	/* in (pre_kvm_run), out (post_kvm_run) */
+	__u64 cr8;
+
+The value of the cr8 register.  Only valid if in-kernel local APIC is
+not used.  Both input and output.
+
+	__u64 apic_base;
+
+The value of the APIC BASE msr.  Only valid if in-kernel local
+APIC is not used.  Both input and output.
+
+	union {
+		/* KVM_EXIT_UNKNOWN */
+		struct {
+			__u64 hardware_exit_reason;
+		} hw;
+
+If exit_reason is KVM_EXIT_UNKNOWN, the vcpu has exited due to unknown
+reasons.  Further architecture-specific information is available in
+hardware_exit_reason.
+
+		/* KVM_EXIT_FAIL_ENTRY */
+		struct {
+			__u64 hardware_entry_failure_reason;
+		} fail_entry;
+
+If exit_reason is KVM_EXIT_FAIL_ENTRY, the vcpu could not be run due
+to unknown reasons.  Further architecture-specific information is
+available in hardware_entry_failure_reason.
+
+		/* KVM_EXIT_EXCEPTION */
+		struct {
+			__u32 exception;
+			__u32 error_code;
+		} ex;
+
+Unused.
+
+		/* KVM_EXIT_IO */
+		struct {
+#define KVM_EXIT_IO_IN  0
+#define KVM_EXIT_IO_OUT 1
+			__u8 direction;
+			__u8 size; /* bytes */
+			__u16 port;
+			__u32 count;
+			__u64 data_offset; /* relative to kvm_run start */
+		} io;
+
+If exit_reason is KVM_EXIT_IO_IN or KVM_EXIT_IO_OUT, then the vcpu has
+executed a port I/O instruction which could not be satisfied by kvm.
+data_offset describes where the data is located (KVM_EXIT_IO_OUT) or
+where kvm expects application code to place the data for the next
+KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a patcked array.
+
+		struct {
+			struct kvm_debug_exit_arch arch;
+		} debug;
+
+Unused.
+
+		/* KVM_EXIT_MMIO */
+		struct {
+			__u64 phys_addr;
+			__u8  data[8];
+			__u32 len;
+			__u8  is_write;
+		} mmio;
+
+If exit_reason is KVM_EXIT_MMIO or KVM_EXIT_IO_OUT, then the vcpu has
+executed a memory-mapped I/O instruction which could not be satisfied
+by kvm.  The 'data' member contains the written data if 'is_write' is
+true, and should be filled by application code otherwise.
+
+		/* KVM_EXIT_HYPERCALL */
+		struct {
+			__u64 nr;
+			__u64 args[6];
+			__u64 ret;
+			__u32 longmode;
+			__u32 pad;
+		} hypercall;
+
+Unused.
+
+		/* KVM_EXIT_TPR_ACCESS */
+		struct {
+			__u64 rip;
+			__u32 is_write;
+			__u32 pad;
+		} tpr_access;
+
+To be documented (KVM_TPR_ACCESS_REPORTING).
+
+		/* KVM_EXIT_S390_SIEIC */
+		struct {
+			__u8 icptcode;
+			__u64 mask; /* psw upper half */
+			__u64 addr; /* psw lower half */
+			__u16 ipa;
+			__u32 ipb;
+		} s390_sieic;
+
+s390 specific.
+
+		/* KVM_EXIT_S390_RESET */
+#define KVM_S390_RESET_POR       1
+#define KVM_S390_RESET_CLEAR     2
+#define KVM_S390_RESET_SUBSYSTEM 4
+#define KVM_S390_RESET_CPU_INIT  8
+#define KVM_S390_RESET_IPL       16
+		__u64 s390_reset_flags;
+
+s390 specific.
+
+		/* KVM_EXIT_DCR */
+		struct {
+			__u32 dcrn;
+			__u32 data;
+			__u8  is_write;
+		} dcr;
+
+powerpc specific.
+
+		/* Fix the size of the union. */
+		char padding[256];
+	};
+};
diff --git a/Documentation/markers.txt b/Documentation/markers.txt
deleted file mode 100644
index d2b3d0e..0000000
--- a/Documentation/markers.txt
+++ /dev/null
@@ -1,104 +0,0 @@
- 	             Using the Linux Kernel Markers
-
-			    Mathieu Desnoyers
-
-
-This document introduces Linux Kernel Markers and their use. It provides
-examples of how to insert markers in the kernel and connect probe functions to
-them and provides some examples of probe functions.
-
-
-* Purpose of markers
-
-A marker placed in code provides a hook to call a function (probe) that you can
-provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
-(no probe is attached). When a marker is "off" it has no effect, except for
-adding a tiny time penalty (checking a condition for a branch) and space
-penalty (adding a few bytes for the function call at the end of the
-instrumented function and adds a data structure in a separate section).  When a
-marker is "on", the function you provide is called each time the marker is
-executed, in the execution context of the caller. When the function provided
-ends its execution, it returns to the caller (continuing from the marker site).
-
-You can put markers at important locations in the code. Markers are
-lightweight hooks that can pass an arbitrary number of parameters,
-described in a printk-like format string, to the attached probe function.
-
-They can be used for tracing and performance accounting.
-
-
-* Usage
-
-In order to use the macro trace_mark, you should include linux/marker.h.
-
-#include <linux/marker.h>
-
-And,
-
-trace_mark(subsystem_event, "myint %d mystring %s", someint, somestring);
-Where :
-- subsystem_event is an identifier unique to your event
-    - subsystem is the name of your subsystem.
-    - event is the name of the event to mark.
-- "myint %d mystring %s" is the formatted string for the serializer. "myint" and
-  "mystring" are repectively the field names associated with the first and
-  second parameter.
-- someint is an integer.
-- somestring is a char pointer.
-
-Connecting a function (probe) to a marker is done by providing a probe (function
-to call) for the specific marker through marker_probe_register() and can be
-activated by calling marker_arm(). Marker deactivation can be done by calling
-marker_disarm() as many times as marker_arm() has been called. Removing a probe
-is done through marker_probe_unregister(); it will disarm the probe.
-
-marker_synchronize_unregister() must be called between probe unregistration and
-the first occurrence of
-- the end of module exit function,
-  to make sure there is no caller left using the probe;
-- the free of any resource used by the probes,
-  to make sure the probes wont be accessing invalid data.
-This, and the fact that preemption is disabled around the probe call, make sure
-that probe removal and module unload are safe. See the "Probe example" section
-below for a sample probe module.
-
-The marker mechanism supports inserting multiple instances of the same marker.
-Markers can be put in inline functions, inlined static functions, and
-unrolled loops as well as regular functions.
-
-The naming scheme "subsystem_event" is suggested here as a convention intended
-to limit collisions. Marker names are global to the kernel: they are considered
-as being the same whether they are in the core kernel image or in modules.
-Conflicting format strings for markers with the same name will cause the markers
-to be detected to have a different format string not to be armed and will output
-a printk warning which identifies the inconsistency:
-
-"Format mismatch for probe probe_name (format), marker (format)"
-
-Another way to use markers is to simply define the marker without generating any
-function call to actually call into the marker. This is useful in combination
-with tracepoint probes in a scheme like this :
-
-void probe_tracepoint_name(unsigned int arg1, struct task_struct *tsk);
-
-DEFINE_MARKER_TP(marker_eventname, tracepoint_name, probe_tracepoint_name,
-	"arg1 %u pid %d");
-
-notrace void probe_tracepoint_name(unsigned int arg1, struct task_struct *tsk)
-{
-	struct marker *marker = &GET_MARKER(kernel_irq_entry);
-	/* write data to trace buffers ... */
-}
-
-* Probe / marker example
-
-See the example provided in samples/markers/src
-
-Compile them with your kernel.
-
-Run, as root :
-modprobe marker-example (insmod order is not important)
-modprobe probe-example
-cat /proc/marker-example (returns an expected error)
-rmmod marker-example probe-example
-dmesg
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index 1634c6d..50189bf 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -60,6 +60,8 @@ framerelay.txt
 	- info on using Frame Relay/Data Link Connection Identifier (DLCI).
 generic_netlink.txt
 	- info on Generic Netlink
+ieee802154.txt
+	- Linux IEEE 802.15.4 implementation, API and drivers
 ip-sysctl.txt
 	- /proc/sys/net/ipv4/* variables
 ip_dynaddr.txt
diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt
index a0280ad..23c995e 100644
--- a/Documentation/networking/ieee802154.txt
+++ b/Documentation/networking/ieee802154.txt
@@ -22,7 +22,7 @@ int sd = socket(PF_IEEE802154, SOCK_DGRAM, 0);
 .....
 
 The address family, socket addresses etc. are defined in the
-include/net/ieee802154/af_ieee802154.h header or in the special header
+include/net/af_ieee802154.h header or in the special header
 in our userspace package (see either linux-zigbee sourceforge download page
 or git tree at git://linux-zigbee.git.sourceforge.net/gitroot/linux-zigbee).
 
@@ -33,7 +33,7 @@ MLME - MAC Level Management
 ============================
 
 Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands.
-See the include/net/ieee802154/nl802154.h header. Our userspace tools package
+See the include/net/nl802154.h header. Our userspace tools package
 (see above) provides CLI configuration utility for radio interfaces and simple
 coordinator for IEEE 802.15.4 networks as an example users of MLME protocol.
 
@@ -54,10 +54,14 @@ Those types of devices require different approach to be hooked into Linux kernel
 HardMAC
 =======
 
-See the header include/net/ieee802154/netdevice.h. You have to implement Linux
+See the header include/net/ieee802154_netdev.h. You have to implement Linux
 net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family
-code via plain sk_buffs. The control block of sk_buffs will contain additional
-info as described in the struct ieee802154_mac_cb.
+code via plain sk_buffs. On skb reception skb->cb must contain additional
+info as described in the struct ieee802154_mac_cb. During packet transmission
+the skb->cb is used to provide additional data to device's header_ops->create
+function. Be aware, that this data can be overriden later (when socket code
+submits skb to qdisc), so if you need something from that cb later, you should
+store info in the skb->data on your own.
 
 To hook the MLME interface you have to populate the ml_priv field of your
 net_device with a pointer to struct ieee802154_mlme_ops instance. All fields are
@@ -69,8 +73,8 @@ We provide an example of simple HardMAC driver at drivers/ieee802154/fakehard.c
 SoftMAC
 =======
 
-We are going to provide intermediate layer impelementing IEEE 802.15.4 MAC
+We are going to provide intermediate layer implementing IEEE 802.15.4 MAC
 in software. This is currently WIP.
 
-See header include/net/ieee802154/mac802154.h and several drivers in
-drivers/ieee802154/
+See header include/net/mac802154.h and several drivers in drivers/ieee802154/.
+
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 8be7623..fbe427a 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -311,9 +311,12 @@ tcp_no_metrics_save - BOOLEAN
 	connections.
 
 tcp_orphan_retries - INTEGER
-	How may times to retry before killing TCP connection, closed
-	by our side. Default value 7 corresponds to ~50sec-16min
-	depending on RTO. If you machine is loaded WEB server,
+	This value influences the timeout of a locally closed TCP connection,
+	when RTO retransmissions remain unacknowledged.
+	See tcp_retries2 for more details.
+
+	The default value is 7.
+	If your machine is a loaded WEB server,
 	you should think about lowering this value, such sockets
 	may consume significant resources. Cf. tcp_max_orphans.
 
@@ -327,16 +330,28 @@ tcp_retrans_collapse - BOOLEAN
 	certain TCP stacks.
 
 tcp_retries1 - INTEGER
-	How many times to retry before deciding that something is wrong
-	and it is necessary to report this suspicion to network layer.
-	Minimal RFC value is 3, it is default, which corresponds
-	to ~3sec-8min depending on RTO.
+	This value influences the time, after which TCP decides, that
+	something is wrong due to unacknowledged RTO retransmissions,
+	and reports this suspicion to the network layer.
+	See tcp_retries2 for more details.
+
+	RFC 1122 recommends at least 3 retransmissions, which is the
+	default.
 
 tcp_retries2 - INTEGER
-	How may times to retry before killing alive TCP connection.
-	RFC1122 says that the limit should be longer than 100 sec.
-	It is too small number.	Default value 15 corresponds to ~13-30min
-	depending on RTO.
+	This value influences the timeout of an alive TCP connection,
+	when RTO retransmissions remain unacknowledged.
+	Given a value of N, a hypothetical TCP connection following
+	exponential backoff with an initial RTO of TCP_RTO_MIN would
+	retransmit N times before killing the connection at the (N+1)th RTO.
+
+	The default value of 15 yields a hypothetical timeout of 924.6
+	seconds and is a lower bound for the effective timeout.
+	TCP will effectively time out at the first RTO which exceeds the
+	hypothetical timeout.
+
+	RFC 1122 recommends at least 100 seconds for the timeout,
+	which corresponds to a value of at least 8.
 
 tcp_rfc1337 - BOOLEAN
 	If set, the TCP stack behaves conforming to RFC1337. If unset,
@@ -1282,6 +1297,16 @@ sctp_rmem - vector of 3 INTEGERs: min, default, max
 sctp_wmem  - vector of 3 INTEGERs: min, default, max
 	See tcp_wmem for a description.
 
+addr_scope_policy - INTEGER
+	Control IPv4 address scoping - draft-stewart-tsvwg-sctp-ipv4-00
+
+	0   - Disable IPv4 address scoping
+	1   - Enable IPv4 address scoping
+	2   - Follow draft but allow IPv4 private addresses
+	3   - Follow draft but allow IPv4 link local addresses
+
+	Default: 1
+
 
 /proc/sys/net/core/*
 dev_weight - INTEGER
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
new file mode 100644
index 0000000..f49a33b
--- /dev/null
+++ b/Documentation/power/runtime_pm.txt
@@ -0,0 +1,378 @@
+Run-time Power Management Framework for I/O Devices
+
+(C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+
+1. Introduction
+
+Support for run-time power management (run-time PM) of I/O devices is provided
+at the power management core (PM core) level by means of:
+
+* The power management workqueue pm_wq in which bus types and device drivers can
+  put their PM-related work items.  It is strongly recommended that pm_wq be
+  used for queuing all work items related to run-time PM, because this allows
+  them to be synchronized with system-wide power transitions (suspend to RAM,
+  hibernation and resume from system sleep states).  pm_wq is declared in
+  include/linux/pm_runtime.h and defined in kernel/power/main.c.
+
+* A number of run-time PM fields in the 'power' member of 'struct device' (which
+  is of the type 'struct dev_pm_info', defined in include/linux/pm.h) that can
+  be used for synchronizing run-time PM operations with one another.
+
+* Three device run-time PM callbacks in 'struct dev_pm_ops' (defined in
+  include/linux/pm.h).
+
+* A set of helper functions defined in drivers/base/power/runtime.c that can be
+  used for carrying out run-time PM operations in such a way that the
+  synchronization between them is taken care of by the PM core.  Bus types and
+  device drivers are encouraged to use these functions.
+
+The run-time PM callbacks present in 'struct dev_pm_ops', the device run-time PM
+fields of 'struct dev_pm_info' and the core helper functions provided for
+run-time PM are described below.
+
+2. Device Run-time PM Callbacks
+
+There are three device run-time PM callbacks defined in 'struct dev_pm_ops':
+
+struct dev_pm_ops {
+	...
+	int (*runtime_suspend)(struct device *dev);
+	int (*runtime_resume)(struct device *dev);
+	void (*runtime_idle)(struct device *dev);
+	...
+};
+
+The ->runtime_suspend() callback is executed by the PM core for the bus type of
+the device being suspended.  The bus type's callback is then _entirely_
+_responsible_ for handling the device as appropriate, which may, but need not
+include executing the device driver's own ->runtime_suspend() callback (from the
+PM core's point of view it is not necessary to implement a ->runtime_suspend()
+callback in a device driver as long as the bus type's ->runtime_suspend() knows
+what to do to handle the device).
+
+  * Once the bus type's ->runtime_suspend() callback has completed successfully
+    for given device, the PM core regards the device as suspended, which need
+    not mean that the device has been put into a low power state.  It is
+    supposed to mean, however, that the device will not process data and will
+    not communicate with the CPU(s) and RAM until its bus type's
+    ->runtime_resume() callback is executed for it.  The run-time PM status of
+    a device after successful execution of its bus type's ->runtime_suspend()
+    callback is 'suspended'.
+
+  * If the bus type's ->runtime_suspend() callback returns -EBUSY or -EAGAIN,
+    the device's run-time PM status is supposed to be 'active', which means that
+    the device _must_ be fully operational afterwards.
+
+  * If the bus type's ->runtime_suspend() callback returns an error code
+    different from -EBUSY or -EAGAIN, the PM core regards this as a fatal
+    error and will refuse to run the helper functions described in Section 4
+    for the device, until the status of it is directly set either to 'active'
+    or to 'suspended' (the PM core provides special helper functions for this
+    purpose).
+
+In particular, if the driver requires remote wakeup capability for proper
+functioning and device_may_wakeup() returns 'false' for the device, then
+->runtime_suspend() should return -EBUSY.  On the other hand, if
+device_may_wakeup() returns 'true' for the device and the device is put
+into a low power state during the execution of its bus type's
+->runtime_suspend(), it is expected that remote wake-up (i.e. hardware mechanism
+allowing the device to request a change of its power state, such as PCI PME)
+will be enabled for the device.  Generally, remote wake-up should be enabled
+for all input devices put into a low power state at run time.
+
+The ->runtime_resume() callback is executed by the PM core for the bus type of
+the device being woken up.  The bus type's callback is then _entirely_
+_responsible_ for handling the device as appropriate, which may, but need not
+include executing the device driver's own ->runtime_resume() callback (from the
+PM core's point of view it is not necessary to implement a ->runtime_resume()
+callback in a device driver as long as the bus type's ->runtime_resume() knows
+what to do to handle the device).
+
+  * Once the bus type's ->runtime_resume() callback has completed successfully,
+    the PM core regards the device as fully operational, which means that the
+    device _must_ be able to complete I/O operations as needed.  The run-time
+    PM status of the device is then 'active'.
+
+  * If the bus type's ->runtime_resume() callback returns an error code, the PM
+    core regards this as a fatal error and will refuse to run the helper
+    functions described in Section 4 for the device, until its status is
+    directly set either to 'active' or to 'suspended' (the PM core provides
+    special helper functions for this purpose).
+
+The ->runtime_idle() callback is executed by the PM core for the bus type of
+given device whenever the device appears to be idle, which is indicated to the
+PM core by two counters, the device's usage counter and the counter of 'active'
+children of the device.
+
+  * If any of these counters is decreased using a helper function provided by
+    the PM core and it turns out to be equal to zero, the other counter is
+    checked.  If that counter also is equal to zero, the PM core executes the
+    device bus type's ->runtime_idle() callback (with the device as an
+    argument).
+
+The action performed by a bus type's ->runtime_idle() callback is totally
+dependent on the bus type in question, but the expected and recommended action
+is to check if the device can be suspended (i.e. if all of the conditions
+necessary for suspending the device are satisfied) and to queue up a suspend
+request for the device in that case.
+
+The helper functions provided by the PM core, described in Section 4, guarantee
+that the following constraints are met with respect to the bus type's run-time
+PM callbacks:
+
+(1) The callbacks are mutually exclusive (e.g. it is forbidden to execute
+    ->runtime_suspend() in parallel with ->runtime_resume() or with another
+    instance of ->runtime_suspend() for the same device) with the exception that
+    ->runtime_suspend() or ->runtime_resume() can be executed in parallel with
+    ->runtime_idle() (although ->runtime_idle() will not be started while any
+    of the other callbacks is being executed for the same device).
+
+(2) ->runtime_idle() and ->runtime_suspend() can only be executed for 'active'
+    devices (i.e. the PM core will only execute ->runtime_idle() or
+    ->runtime_suspend() for the devices the run-time PM status of which is
+    'active').
+
+(3) ->runtime_idle() and ->runtime_suspend() can only be executed for a device
+    the usage counter of which is equal to zero _and_ either the counter of
+    'active' children of which is equal to zero, or the 'power.ignore_children'
+    flag of which is set.
+
+(4) ->runtime_resume() can only be executed for 'suspended' devices  (i.e. the
+    PM core will only execute ->runtime_resume() for the devices the run-time
+    PM status of which is 'suspended').
+
+Additionally, the helper functions provided by the PM core obey the following
+rules:
+
+  * If ->runtime_suspend() is about to be executed or there's a pending request
+    to execute it, ->runtime_idle() will not be executed for the same device.
+
+  * A request to execute or to schedule the execution of ->runtime_suspend()
+    will cancel any pending requests to execute ->runtime_idle() for the same
+    device.
+
+  * If ->runtime_resume() is about to be executed or there's a pending request
+    to execute it, the other callbacks will not be executed for the same device.
+
+  * A request to execute ->runtime_resume() will cancel any pending or
+    scheduled requests to execute the other callbacks for the same device.
+
+3. Run-time PM Device Fields
+
+The following device run-time PM fields are present in 'struct dev_pm_info', as
+defined in include/linux/pm.h:
+
+  struct timer_list suspend_timer;
+    - timer used for scheduling (delayed) suspend request
+
+  unsigned long timer_expires;
+    - timer expiration time, in jiffies (if this is different from zero, the
+      timer is running and will expire at that time, otherwise the timer is not
+      running)
+
+  struct work_struct work;
+    - work structure used for queuing up requests (i.e. work items in pm_wq)
+
+  wait_queue_head_t wait_queue;
+    - wait queue used if any of the helper functions needs to wait for another
+      one to complete
+
+  spinlock_t lock;
+    - lock used for synchronisation
+
+  atomic_t usage_count;
+    - the usage counter of the device
+
+  atomic_t child_count;
+    - the count of 'active' children of the device
+
+  unsigned int ignore_children;
+    - if set, the value of child_count is ignored (but still updated)
+
+  unsigned int disable_depth;
+    - used for disabling the helper funcions (they work normally if this is
+      equal to zero); the initial value of it is 1 (i.e. run-time PM is
+      initially disabled for all devices)
+
+  unsigned int runtime_error;
+    - if set, there was a fatal error (one of the callbacks returned error code
+      as described in Section 2), so the helper funtions will not work until
+      this flag is cleared; this is the error code returned by the failing
+      callback
+
+  unsigned int idle_notification;
+    - if set, ->runtime_idle() is being executed
+
+  unsigned int request_pending;
+    - if set, there's a pending request (i.e. a work item queued up into pm_wq)
+
+  enum rpm_request request;
+    - type of request that's pending (valid if request_pending is set)
+
+  unsigned int deferred_resume;
+    - set if ->runtime_resume() is about to be run while ->runtime_suspend() is
+      being executed for that device and it is not practical to wait for the
+      suspend to complete; means "start a resume as soon as you've suspended"
+
+  enum rpm_status runtime_status;
+    - the run-time PM status of the device; this field's initial value is
+      RPM_SUSPENDED, which means that each device is initially regarded by the
+      PM core as 'suspended', regardless of its real hardware status
+
+All of the above fields are members of the 'power' member of 'struct device'.
+
+4. Run-time PM Device Helper Functions
+
+The following run-time PM helper functions are defined in
+drivers/base/power/runtime.c and include/linux/pm_runtime.h:
+
+  void pm_runtime_init(struct device *dev);
+    - initialize the device run-time PM fields in 'struct dev_pm_info'
+
+  void pm_runtime_remove(struct device *dev);
+    - make sure that the run-time PM of the device will be disabled after
+      removing the device from device hierarchy
+
+  int pm_runtime_idle(struct device *dev);
+    - execute ->runtime_idle() for the device's bus type; returns 0 on success
+      or error code on failure, where -EINPROGRESS means that ->runtime_idle()
+      is already being executed
+
+  int pm_runtime_suspend(struct device *dev);
+    - execute ->runtime_suspend() for the device's bus type; returns 0 on
+      success, 1 if the device's run-time PM status was already 'suspended', or
+      error code on failure, where -EAGAIN or -EBUSY means it is safe to attempt
+      to suspend the device again in future
+
+  int pm_runtime_resume(struct device *dev);
+    - execute ->runtime_resume() for the device's bus type; returns 0 on
+      success, 1 if the device's run-time PM status was already 'active' or
+      error code on failure, where -EAGAIN means it may be safe to attempt to
+      resume the device again in future, but 'power.runtime_error' should be
+      checked additionally
+
+  int pm_request_idle(struct device *dev);
+    - submit a request to execute ->runtime_idle() for the device's bus type
+      (the request is represented by a work item in pm_wq); returns 0 on success
+      or error code if the request has not been queued up
+
+  int pm_schedule_suspend(struct device *dev, unsigned int delay);
+    - schedule the execution of ->runtime_suspend() for the device's bus type
+      in future, where 'delay' is the time to wait before queuing up a suspend
+      work item in pm_wq, in milliseconds (if 'delay' is zero, the work item is
+      queued up immediately); returns 0 on success, 1 if the device's PM
+      run-time status was already 'suspended', or error code if the request
+      hasn't been scheduled (or queued up if 'delay' is 0); if the execution of
+      ->runtime_suspend() is already scheduled and not yet expired, the new
+      value of 'delay' will be used as the time to wait
+
+  int pm_request_resume(struct device *dev);
+    - submit a request to execute ->runtime_resume() for the device's bus type
+      (the request is represented by a work item in pm_wq); returns 0 on
+      success, 1 if the device's run-time PM status was already 'active', or
+      error code if the request hasn't been queued up
+
+  void pm_runtime_get_noresume(struct device *dev);
+    - increment the device's usage counter
+
+  int pm_runtime_get(struct device *dev);
+    - increment the device's usage counter, run pm_request_resume(dev) and
+      return its result
+
+  int pm_runtime_get_sync(struct device *dev);
+    - increment the device's usage counter, run pm_runtime_resume(dev) and
+      return its result
+
+  void pm_runtime_put_noidle(struct device *dev);
+    - decrement the device's usage counter
+
+  int pm_runtime_put(struct device *dev);
+    - decrement the device's usage counter, run pm_request_idle(dev) and return
+      its result
+
+  int pm_runtime_put_sync(struct device *dev);
+    - decrement the device's usage counter, run pm_runtime_idle(dev) and return
+      its result
+
+  void pm_runtime_enable(struct device *dev);
+    - enable the run-time PM helper functions to run the device bus type's
+      run-time PM callbacks described in Section 2
+
+  int pm_runtime_disable(struct device *dev);
+    - prevent the run-time PM helper functions from running the device bus
+      type's run-time PM callbacks, make sure that all of the pending run-time
+      PM operations on the device are either completed or canceled; returns
+      1 if there was a resume request pending and it was necessary to execute
+      ->runtime_resume() for the device's bus type to satisfy that request,
+      otherwise 0 is returned
+
+  void pm_suspend_ignore_children(struct device *dev, bool enable);
+    - set/unset the power.ignore_children flag of the device
+
+  int pm_runtime_set_active(struct device *dev);
+    - clear the device's 'power.runtime_error' flag, set the device's run-time
+      PM status to 'active' and update its parent's counter of 'active'
+      children as appropriate (it is only valid to use this function if
+      'power.runtime_error' is set or 'power.disable_depth' is greater than
+      zero); it will fail and return error code if the device has a parent
+      which is not active and the 'power.ignore_children' flag of which is unset
+
+  void pm_runtime_set_suspended(struct device *dev);
+    - clear the device's 'power.runtime_error' flag, set the device's run-time
+      PM status to 'suspended' and update its parent's counter of 'active'
+      children as appropriate (it is only valid to use this function if
+      'power.runtime_error' is set or 'power.disable_depth' is greater than
+      zero)
+
+It is safe to execute the following helper functions from interrupt context:
+
+pm_request_idle()
+pm_schedule_suspend()
+pm_request_resume()
+pm_runtime_get_noresume()
+pm_runtime_get()
+pm_runtime_put_noidle()
+pm_runtime_put()
+pm_suspend_ignore_children()
+pm_runtime_set_active()
+pm_runtime_set_suspended()
+pm_runtime_enable()
+
+5. Run-time PM Initialization, Device Probing and Removal
+
+Initially, the run-time PM is disabled for all devices, which means that the
+majority of the run-time PM helper funtions described in Section 4 will return
+-EAGAIN until pm_runtime_enable() is called for the device.
+
+In addition to that, the initial run-time PM status of all devices is
+'suspended', but it need not reflect the actual physical state of the device.
+Thus, if the device is initially active (i.e. it is able to process I/O), its
+run-time PM status must be changed to 'active', with the help of
+pm_runtime_set_active(), before pm_runtime_enable() is called for the device.
+
+However, if the device has a parent and the parent's run-time PM is enabled,
+calling pm_runtime_set_active() for the device will affect the parent, unless
+the parent's 'power.ignore_children' flag is set.  Namely, in that case the
+parent won't be able to suspend at run time, using the PM core's helper
+functions, as long as the child's status is 'active', even if the child's
+run-time PM is still disabled (i.e. pm_runtime_enable() hasn't been called for
+the child yet or pm_runtime_disable() has been called for it).  For this reason,
+once pm_runtime_set_active() has been called for the device, pm_runtime_enable()
+should be called for it too as soon as reasonably possible or its run-time PM
+status should be changed back to 'suspended' with the help of
+pm_runtime_set_suspended().
+
+If the default initial run-time PM status of the device (i.e. 'suspended')
+reflects the actual state of the device, its bus type's or its driver's
+->probe() callback will likely need to wake it up using one of the PM core's
+helper functions described in Section 4.  In that case, pm_runtime_resume()
+should be used.  Of course, for this purpose the device's run-time PM has to be
+enabled earlier by calling pm_runtime_enable().
+
+If the device bus type's or driver's ->probe() or ->remove() callback runs
+pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts,
+they will fail returning -EAGAIN, because the device's usage counter is
+incremented by the core before executing ->probe() and ->remove().  Still, it
+may be desirable to suspend the device as soon as ->probe() or ->remove() has
+finished, so the PM core uses pm_runtime_idle_sync() to invoke the device bus
+type's ->runtime_idle() callback at that time.
diff --git a/Documentation/trace/events.txt b/Documentation/trace/events.txt
index 2bcc8d4..78c45a8 100644
--- a/Documentation/trace/events.txt
+++ b/Documentation/trace/events.txt
@@ -1,7 +1,7 @@
 			     Event Tracing
 
 		Documentation written by Theodore Ts'o
-			Updated by Li Zefan
+		Updated by Li Zefan and Tom Zanussi
 
 1. Introduction
 ===============
@@ -22,12 +22,12 @@ tracing information should be printed.
 ---------------------------------
 
 The events which are available for tracing can be found in the file
-/debug/tracing/available_events.
+/sys/kernel/debug/tracing/available_events.
 
 To enable a particular event, such as 'sched_wakeup', simply echo it
-to /debug/tracing/set_event. For example:
+to /sys/kernel/debug/tracing/set_event. For example:
 
-	# echo sched_wakeup >> /debug/tracing/set_event
+	# echo sched_wakeup >> /sys/kernel/debug/tracing/set_event
 
 [ Note: '>>' is necessary, otherwise it will firstly disable
   all the events. ]
@@ -35,15 +35,15 @@ to /debug/tracing/set_event. For example:
 To disable an event, echo the event name to the set_event file prefixed
 with an exclamation point:
 
-	# echo '!sched_wakeup' >> /debug/tracing/set_event
+	# echo '!sched_wakeup' >> /sys/kernel/debug/tracing/set_event
 
 To disable all events, echo an empty line to the set_event file:
 
-	# echo > /debug/tracing/set_event
+	# echo > /sys/kernel/debug/tracing/set_event
 
 To enable all events, echo '*:*' or '*:' to the set_event file:
 
-	# echo *:* > /debug/tracing/set_event
+	# echo *:* > /sys/kernel/debug/tracing/set_event
 
 The events are organized into subsystems, such as ext4, irq, sched,
 etc., and a full event name looks like this: <subsystem>:<event>.  The
@@ -52,29 +52,29 @@ file.  All of the events in a subsystem can be specified via the syntax
 "<subsystem>:*"; for example, to enable all irq events, you can use the
 command:
 
-	# echo 'irq:*' > /debug/tracing/set_event
+	# echo 'irq:*' > /sys/kernel/debug/tracing/set_event
 
 2.2 Via the 'enable' toggle
 ---------------------------
 
-The events available are also listed in /debug/tracing/events/ hierarchy
+The events available are also listed in /sys/kernel/debug/tracing/events/ hierarchy
 of directories.
 
 To enable event 'sched_wakeup':
 
-	# echo 1 > /debug/tracing/events/sched/sched_wakeup/enable
+	# echo 1 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
 
 To disable it:
 
-	# echo 0 > /debug/tracing/events/sched/sched_wakeup/enable
+	# echo 0 > /sys/kernel/debug/tracing/events/sched/sched_wakeup/enable
 
 To enable all events in sched subsystem:
 
-	# echo 1 > /debug/tracing/events/sched/enable
+	# echo 1 > /sys/kernel/debug/tracing/events/sched/enable
 
 To eanble all events:
 
-	# echo 1 > /debug/tracing/events/enable
+	# echo 1 > /sys/kernel/debug/tracing/events/enable
 
 When reading one of these enable files, there are four results:
 
@@ -97,3 +97,185 @@ The format of this boot option is the same as described in section 2.1.
 
 See The example provided in samples/trace_events
 
+4. Event formats
+================
+
+Each trace event has a 'format' file associated with it that contains
+a description of each field in a logged event.  This information can
+be used to parse the binary trace stream, and is also the place to
+find the field names that can be used in event filters (see section 5).
+
+It also displays the format string that will be used to print the
+event in text mode, along with the event name and ID used for
+profiling.
+
+Every event has a set of 'common' fields associated with it; these are
+the fields prefixed with 'common_'.  The other fields vary between
+events and correspond to the fields defined in the TRACE_EVENT
+definition for that event.
+
+Each field in the format has the form:
+
+     field:field-type field-name; offset:N; size:N;
+
+where offset is the offset of the field in the trace record and size
+is the size of the data item, in bytes.
+
+For example, here's the information displayed for the 'sched_wakeup'
+event:
+
+# cat /debug/tracing/events/sched/sched_wakeup/format
+
+name: sched_wakeup
+ID: 60
+format:
+	field:unsigned short common_type;	offset:0;	size:2;
+	field:unsigned char common_flags;	offset:2;	size:1;
+	field:unsigned char common_preempt_count;	offset:3;	size:1;
+	field:int common_pid;	offset:4;	size:4;
+	field:int common_tgid;	offset:8;	size:4;
+
+	field:char comm[TASK_COMM_LEN];	offset:12;	size:16;
+	field:pid_t pid;	offset:28;	size:4;
+	field:int prio;	offset:32;	size:4;
+	field:int success;	offset:36;	size:4;
+	field:int cpu;	offset:40;	size:4;
+
+print fmt: "task %s:%d [%d] success=%d [%03d]", REC->comm, REC->pid,
+	   REC->prio, REC->success, REC->cpu
+
+This event contains 10 fields, the first 5 common and the remaining 5
+event-specific.  All the fields for this event are numeric, except for
+'comm' which is a string, a distinction important for event filtering.
+
+5. Event filtering
+==================
+
+Trace events can be filtered in the kernel by associating boolean
+'filter expressions' with them.  As soon as an event is logged into
+the trace buffer, its fields are checked against the filter expression
+associated with that event type.  An event with field values that
+'match' the filter will appear in the trace output, and an event whose
+values don't match will be discarded.  An event with no filter
+associated with it matches everything, and is the default when no
+filter has been set for an event.
+
+5.1 Expression syntax
+---------------------
+
+A filter expression consists of one or more 'predicates' that can be
+combined using the logical operators '&&' and '||'.  A predicate is
+simply a clause that compares the value of a field contained within a
+logged event with a constant value and returns either 0 or 1 depending
+on whether the field value matched (1) or didn't match (0):
+
+	  field-name relational-operator value
+
+Parentheses can be used to provide arbitrary logical groupings and
+double-quotes can be used to prevent the shell from interpreting
+operators as shell metacharacters.
+
+The field-names available for use in filters can be found in the
+'format' files for trace events (see section 4).
+
+The relational-operators depend on the type of the field being tested:
+
+The operators available for numeric fields are:
+
+==, !=, <, <=, >, >=
+
+And for string fields they are:
+
+==, !=
+
+Currently, only exact string matches are supported.
+
+Currently, the maximum number of predicates in a filter is 16.
+
+5.2 Setting filters
+-------------------
+
+A filter for an individual event is set by writing a filter expression
+to the 'filter' file for the given event.
+
+For example:
+
+# cd /debug/tracing/events/sched/sched_wakeup
+# echo "common_preempt_count > 4" > filter
+
+A slightly more involved example:
+
+# cd /debug/tracing/events/sched/sched_signal_send
+# echo "((sig >= 10 && sig < 15) || sig == 17) && comm != bash" > filter
+
+If there is an error in the expression, you'll get an 'Invalid
+argument' error when setting it, and the erroneous string along with
+an error message can be seen by looking at the filter e.g.:
+
+# cd /debug/tracing/events/sched/sched_signal_send
+# echo "((sig >= 10 && sig < 15) || dsig == 17) && comm != bash" > filter
+-bash: echo: write error: Invalid argument
+# cat filter
+((sig >= 10 && sig < 15) || dsig == 17) && comm != bash
+^
+parse_error: Field not found
+
+Currently the caret ('^') for an error always appears at the beginning of
+the filter string; the error message should still be useful though
+even without more accurate position info.
+
+5.3 Clearing filters
+--------------------
+
+To clear the filter for an event, write a '0' to the event's filter
+file.
+
+To clear the filters for all events in a subsystem, write a '0' to the
+subsystem's filter file.
+
+5.3 Subsystem filters
+---------------------
+
+For convenience, filters for every event in a subsystem can be set or
+cleared as a group by writing a filter expression into the filter file
+at the root of the subsytem.  Note however, that if a filter for any
+event within the subsystem lacks a field specified in the subsystem
+filter, or if the filter can't be applied for any other reason, the
+filter for that event will retain its previous setting.  This can
+result in an unintended mixture of filters which could lead to
+confusing (to the user who might think different filters are in
+effect) trace output.  Only filters that reference just the common
+fields can be guaranteed to propagate successfully to all events.
+
+Here are a few subsystem filter examples that also illustrate the
+above points:
+
+Clear the filters on all events in the sched subsytem:
+
+# cd /sys/kernel/debug/tracing/events/sched
+# echo 0 > filter
+# cat sched_switch/filter
+none
+# cat sched_wakeup/filter
+none
+
+Set a filter using only common fields for all events in the sched
+subsytem (all events end up with the same filter):
+
+# cd /sys/kernel/debug/tracing/events/sched
+# echo common_pid == 0 > filter
+# cat sched_switch/filter
+common_pid == 0
+# cat sched_wakeup/filter
+common_pid == 0
+
+Attempt to set a filter using a non-common field for all events in the
+sched subsytem (all events but those that have a prev_pid field retain
+their old filters):
+
+# cd /sys/kernel/debug/tracing/events/sched
+# echo prev_pid == 0 > filter
+# cat sched_switch/filter
+prev_pid == 0
+# cat sched_wakeup/filter
+common_pid == 0
diff --git a/Documentation/trace/ftrace-design.txt b/Documentation/trace/ftrace-design.txt
new file mode 100644
index 0000000..7003e10
--- /dev/null
+++ b/Documentation/trace/ftrace-design.txt
@@ -0,0 +1,233 @@
+		function tracer guts
+		====================
+
+Introduction
+------------
+
+Here we will cover the architecture pieces that the common function tracing
+code relies on for proper functioning.  Things are broken down into increasing
+complexity so that you can start simple and at least get basic functionality.
+
+Note that this focuses on architecture implementation details only.  If you
+want more explanation of a feature in terms of common code, review the common
+ftrace.txt file.
+
+
+Prerequisites
+-------------
+
+Ftrace relies on these features being implemented:
+ STACKTRACE_SUPPORT - implement save_stack_trace()
+ TRACE_IRQFLAGS_SUPPORT - implement include/asm/irqflags.h
+
+
+HAVE_FUNCTION_TRACER
+--------------------
+
+You will need to implement the mcount and the ftrace_stub functions.
+
+The exact mcount symbol name will depend on your toolchain.  Some call it
+"mcount", "_mcount", or even "__mcount".  You can probably figure it out by
+running something like:
+	$ echo 'main(){}' | gcc -x c -S -o - - -pg | grep mcount
+	        call    mcount
+We'll make the assumption below that the symbol is "mcount" just to keep things
+nice and simple in the examples.
+
+Keep in mind that the ABI that is in effect inside of the mcount function is
+*highly* architecture/toolchain specific.  We cannot help you in this regard,
+sorry.  Dig up some old documentation and/or find someone more familiar than
+you to bang ideas off of.  Typically, register usage (argument/scratch/etc...)
+is a major issue at this point, especially in relation to the location of the
+mcount call (before/after function prologue).  You might also want to look at
+how glibc has implemented the mcount function for your architecture.  It might
+be (semi-)relevant.
+
+The mcount function should check the function pointer ftrace_trace_function
+to see if it is set to ftrace_stub.  If it is, there is nothing for you to do,
+so return immediately.  If it isn't, then call that function in the same way
+the mcount function normally calls __mcount_internal -- the first argument is
+the "frompc" while the second argument is the "selfpc" (adjusted to remove the
+size of the mcount call that is embedded in the function).
+
+For example, if the function foo() calls bar(), when the bar() function calls
+mcount(), the arguments mcount() will pass to the tracer are:
+	"frompc" - the address bar() will use to return to foo()
+	"selfpc" - the address bar() (with _mcount() size adjustment)
+
+Also keep in mind that this mcount function will be called *a lot*, so
+optimizing for the default case of no tracer will help the smooth running of
+your system when tracing is disabled.  So the start of the mcount function is
+typically the bare min with checking things before returning.  That also means
+the code flow should usually kept linear (i.e. no branching in the nop case).
+This is of course an optimization and not a hard requirement.
+
+Here is some pseudo code that should help (these functions should actually be
+implemented in assembly):
+
+void ftrace_stub(void)
+{
+	return;
+}
+
+void mcount(void)
+{
+	/* save any bare state needed in order to do initial checking */
+
+	extern void (*ftrace_trace_function)(unsigned long, unsigned long);
+	if (ftrace_trace_function != ftrace_stub)
+		goto do_trace;
+
+	/* restore any bare state */
+
+	return;
+
+do_trace:
+
+	/* save all state needed by the ABI (see paragraph above) */
+
+	unsigned long frompc = ...;
+	unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
+	ftrace_trace_function(frompc, selfpc);
+
+	/* restore all state needed by the ABI */
+}
+
+Don't forget to export mcount for modules !
+extern void mcount(void);
+EXPORT_SYMBOL(mcount);
+
+
+HAVE_FUNCTION_TRACE_MCOUNT_TEST
+-------------------------------
+
+This is an optional optimization for the normal case when tracing is turned off
+in the system.  If you do not enable this Kconfig option, the common ftrace
+code will take care of doing the checking for you.
+
+To support this feature, you only need to check the function_trace_stop
+variable in the mcount function.  If it is non-zero, there is no tracing to be
+done at all, so you can return.
+
+This additional pseudo code would simply be:
+void mcount(void)
+{
+	/* save any bare state needed in order to do initial checking */
+
++	if (function_trace_stop)
++		return;
+
+	extern void (*ftrace_trace_function)(unsigned long, unsigned long);
+	if (ftrace_trace_function != ftrace_stub)
+...
+
+
+HAVE_FUNCTION_GRAPH_TRACER
+--------------------------
+
+Deep breath ... time to do some real work.  Here you will need to update the
+mcount function to check ftrace graph function pointers, as well as implement
+some functions to save (hijack) and restore the return address.
+
+The mcount function should check the function pointers ftrace_graph_return
+(compare to ftrace_stub) and ftrace_graph_entry (compare to
+ftrace_graph_entry_stub).  If either of those are not set to the relevant stub
+function, call the arch-specific function ftrace_graph_caller which in turn
+calls the arch-specific function prepare_ftrace_return.  Neither of these
+function names are strictly required, but you should use them anyways to stay
+consistent across the architecture ports -- easier to compare & contrast
+things.
+
+The arguments to prepare_ftrace_return are slightly different than what are
+passed to ftrace_trace_function.  The second argument "selfpc" is the same,
+but the first argument should be a pointer to the "frompc".  Typically this is
+located on the stack.  This allows the function to hijack the return address
+temporarily to have it point to the arch-specific function return_to_handler.
+That function will simply call the common ftrace_return_to_handler function and
+that will return the original return address with which, you can return to the
+original call site.
+
+Here is the updated mcount pseudo code:
+void mcount(void)
+{
+...
+	if (ftrace_trace_function != ftrace_stub)
+		goto do_trace;
+
++#ifdef CONFIG_FUNCTION_GRAPH_TRACER
++	extern void (*ftrace_graph_return)(...);
++	extern void (*ftrace_graph_entry)(...);
++	if (ftrace_graph_return != ftrace_stub ||
++	    ftrace_graph_entry != ftrace_graph_entry_stub)
++		ftrace_graph_caller();
++#endif
+
+	/* restore any bare state */
+...
+
+Here is the pseudo code for the new ftrace_graph_caller assembly function:
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void ftrace_graph_caller(void)
+{
+	/* save all state needed by the ABI */
+
+	unsigned long *frompc = &...;
+	unsigned long selfpc = <return address> - MCOUNT_INSN_SIZE;
+	prepare_ftrace_return(frompc, selfpc);
+
+	/* restore all state needed by the ABI */
+}
+#endif
+
+For information on how to implement prepare_ftrace_return(), simply look at
+the x86 version.  The only architecture-specific piece in it is the setup of
+the fault recovery table (the asm(...) code).  The rest should be the same
+across architectures.
+
+Here is the pseudo code for the new return_to_handler assembly function.  Note
+that the ABI that applies here is different from what applies to the mcount
+code.  Since you are returning from a function (after the epilogue), you might
+be able to skimp on things saved/restored (usually just registers used to pass
+return values).
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void return_to_handler(void)
+{
+	/* save all state needed by the ABI (see paragraph above) */
+
+	void (*original_return_point)(void) = ftrace_return_to_handler();
+
+	/* restore all state needed by the ABI */
+
+	/* this is usually either a return or a jump */
+	original_return_point();
+}
+#endif
+
+
+HAVE_FTRACE_NMI_ENTER
+---------------------
+
+If you can't trace NMI functions, then skip this option.
+
+<details to be filled>
+
+
+HAVE_FTRACE_SYSCALLS
+---------------------
+
+<details to be filled>
+
+
+HAVE_FTRACE_MCOUNT_RECORD
+-------------------------
+
+See scripts/recordmcount.pl for more info.
+
+<details to be filled>
+
+
+HAVE_DYNAMIC_FTRACE
+---------------------
+
+<details to be filled>
diff --git a/Documentation/trace/ftrace.txt b/Documentation/trace/ftrace.txt
index 355d0f1..1b6292b 100644
--- a/Documentation/trace/ftrace.txt
+++ b/Documentation/trace/ftrace.txt
@@ -26,6 +26,12 @@ disabled, and more (ftrace allows for tracer plugins, which
 means that the list of tracers can always grow).
 
 
+Implementation Details
+----------------------
+
+See ftrace-design.txt for details for arch porters and such.
+
+
 The File System
 ---------------
 
diff --git a/Documentation/trace/power.txt b/Documentation/trace/power.txt
deleted file mode 100644
index cd805e1..0000000
--- a/Documentation/trace/power.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-The power tracer collects detailed information about C-state and P-state
-transitions, instead of just looking at the high-level "average"
-information.
-
-There is a helper script found in scrips/tracing/power.pl in the kernel
-sources which can be used to parse this information and create a
-Scalable Vector Graphics (SVG) picture from the trace data.
-
-To use this tracer:
-
-	echo 0 > /sys/kernel/debug/tracing/tracing_enabled
-	echo power > /sys/kernel/debug/tracing/current_tracer
-	echo 1 > /sys/kernel/debug/tracing/tracing_enabled
-	sleep 1
-	echo 0 > /sys/kernel/debug/tracing/tracing_enabled
-	cat /sys/kernel/debug/tracing/trace | \
-		perl scripts/tracing/power.pl > out.sv
diff --git a/Documentation/vgaarbiter.txt b/Documentation/vgaarbiter.txt
new file mode 100644
index 0000000..987f9b0
--- /dev/null
+++ b/Documentation/vgaarbiter.txt
@@ -0,0 +1,194 @@
+
+VGA Arbiter
+===========
+
+Graphic devices are accessed through ranges in I/O or memory space. While most
+modern devices allow relocation of such ranges, some "Legacy" VGA devices
+implemented on PCI will typically have the same "hard-decoded" addresses as
+they did on ISA. For more details see "PCI Bus Binding to IEEE Std 1275-1994
+Standard for Boot (Initialization Configuration) Firmware Revision 2.1"
+Section 7, Legacy Devices.
+
+The Resource Access Control (RAC) module inside the X server [0] existed for
+the legacy VGA arbitration task (besides other bus management tasks) when more
+than one legacy device co-exists on the same machine. But the problem happens
+when these devices are trying to be accessed by different userspace clients
+(e.g. two server in parallel). Their address assignments conflict. Moreover,
+ideally, being an userspace application, it is not the role of the the X
+server to control bus resources. Therefore an arbitration scheme outside of
+the X server is needed to control the sharing of these resources. This
+document introduces the operation of the VGA arbiter implemented for Linux
+kernel.
+
+----------------------------------------------------------------------------
+
+I.  Details and Theory of Operation
+        I.1 vgaarb
+        I.2 libpciaccess
+        I.3 xf86VGAArbiter (X server implementation)
+II. Credits
+III.References
+
+
+I. Details and Theory of Operation
+==================================
+
+I.1 vgaarb
+----------
+
+The vgaarb is a module of the Linux Kernel. When it is initially loaded, it
+scans all PCI devices and adds the VGA ones inside the arbitration. The
+arbiter then enables/disables the decoding on different devices of the VGA
+legacy instructions. Device which do not want/need to use the arbiter may
+explicitly tell it by calling vga_set_legacy_decoding().
+
+The kernel exports a char device interface (/dev/vga_arbiter) to the clients,
+which has the following semantics:
+
+ open       : open user instance of the arbiter. By default, it's attached to
+              the default VGA device of the system.
+
+ close      : close user instance. Release locks made by the user
+
+ read       : return a string indicating the status of the target like:
+
+              "<card_ID>,decodes=<io_state>,owns=<io_state>,locks=<io_state> (ic,mc)"
+
+              An IO state string is of the form {io,mem,io+mem,none}, mc and
+              ic are respectively mem and io lock counts (for debugging/
+              diagnostic only). "decodes" indicate what the card currently
+              decodes, "owns" indicates what is currently enabled on it, and
+              "locks" indicates what is locked by this card. If the card is
+              unplugged, we get "invalid" then for card_ID and an -ENODEV
+              error is returned for any command until a new card is targeted.
+
+
+ write       : write a command to the arbiter. List of commands:
+
+  target <card_ID>   : switch target to card <card_ID> (see below)
+  lock <io_state>    : acquires locks on target ("none" is an invalid io_state)
+  trylock <io_state> : non-blocking acquire locks on target (returns EBUSY if
+                       unsuccessful)
+  unlock <io_state>  : release locks on target
+  unlock all         : release all locks on target held by this user (not
+                       implemented yet)
+  decodes <io_state> : set the legacy decoding attributes for the card
+
+  poll               : event if something changes on any card (not just the
+                       target)
+
+  card_ID is of the form "PCI:domain:bus:dev.fn". It can be set to "default"
+  to go back to the system default card (TODO: not implemented yet). Currently,
+  only PCI is supported as a prefix, but the userland API may support other bus
+  types in the future, even if the current kernel implementation doesn't.
+
+Note about locks:
+
+The driver keeps track of which user has which locks on which card. It
+supports stacking, like the kernel one. This complexifies the implementation
+a bit, but makes the arbiter more tolerant to user space problems and able
+to properly cleanup in all cases when a process dies.
+Currently, a max of 16 cards can have locks simultaneously issued from
+user space for a given user (file descriptor instance) of the arbiter.
+
+In the case of devices hot-{un,}plugged, there is a hook - pci_notify() - to
+notify them being added/removed in the system and automatically added/removed
+in the arbiter.
+
+There's also a in-kernel API of the arbiter in the case of DRM, vgacon and
+others which may use the arbiter.
+
+
+I.2 libpciaccess
+----------------
+
+To use the vga arbiter char device it was implemented an API inside the
+libpciaccess library. One fieldd was added to struct pci_device (each device
+on the system):
+
+    /* the type of resource decoded by the device */
+    int vgaarb_rsrc;
+
+Besides it, in pci_system were added:
+
+    int vgaarb_fd;
+    int vga_count;
+    struct pci_device *vga_target;
+    struct pci_device *vga_default_dev;
+
+
+The vga_count is usually need to keep informed how many cards are being
+arbitrated, so for instance if there's only one then it can totally escape the
+scheme.
+
+
+These functions below acquire VGA resources for the given card and mark those
+resources as locked. If the resources requested are "normal" (and not legacy)
+resources, the arbiter will first check whether the card is doing legacy
+decoding for that type of resource. If yes, the lock is "converted" into a
+legacy resource lock. The arbiter will first look for all VGA cards that
+might conflict and disable their IOs and/or Memory access, including VGA
+forwarding on P2P bridges if necessary, so that the requested resources can
+be used. Then, the card is marked as locking these resources and the IO and/or
+Memory access is enabled on the card (including VGA forwarding on parent
+P2P bridges if any). In the case of vga_arb_lock(), the function will block
+if some conflicting card is already locking one of the required resources (or
+any resource on a different bus segment, since P2P bridges don't differentiate
+VGA memory and IO afaik). If the card already owns the resources, the function
+succeeds.  vga_arb_trylock() will return (-EBUSY) instead of blocking. Nested
+calls are supported (a per-resource counter is maintained).
+
+
+Set the target device of this client.
+    int  pci_device_vgaarb_set_target   (struct pci_device *dev);
+
+
+For instance, in x86 if two devices on the same bus want to lock different
+resources, both will succeed (lock). If devices are in different buses and
+trying to lock different resources, only the first who tried succeeds.
+    int  pci_device_vgaarb_lock         (void);
+    int  pci_device_vgaarb_trylock      (void);
+
+Unlock resources of device.
+    int  pci_device_vgaarb_unlock       (void);
+
+Indicates to the arbiter if the card decodes legacy VGA IOs, legacy VGA
+Memory, both, or none. All cards default to both, the card driver (fbdev for
+example) should tell the arbiter if it has disabled legacy decoding, so the
+card can be left out of the arbitration process (and can be safe to take
+interrupts at any time.
+    int  pci_device_vgaarb_decodes      (int new_vgaarb_rsrc);
+
+Connects to the arbiter device, allocates the struct
+    int  pci_device_vgaarb_init         (void);
+
+Close the connection
+    void pci_device_vgaarb_fini         (void);
+
+
+I.3 xf86VGAArbiter (X server implementation)
+--------------------------------------------
+
+(TODO)
+
+X server basically wraps all the functions that touch VGA registers somehow.
+
+
+II. Credits
+===========
+
+Benjamin Herrenschmidt (IBM?) started this work when he discussed such design
+with the Xorg community in 2005 [1, 2]. In the end of 2007, Paulo Zanoni and
+Tiago Vignatti (both of C3SL/Federal University of Paraná) proceeded his work
+enhancing the kernel code to adapt as a kernel module and also did the
+implementation of the user space side [3]. Now (2009) Tiago Vignatti and Dave
+Airlie finally put this work in shape and queued to Jesse Barnes' PCI tree.
+
+
+III. References
+==============
+
+[0] http://cgit.freedesktop.org/xorg/xserver/commit/?id=4b42448a2388d40f257774fbffdccaea87bd0347
+[1] http://lists.freedesktop.org/archives/xorg/2005-March/006663.html
+[2] http://lists.freedesktop.org/archives/xorg/2005-March/006745.html
+[3] http://lists.freedesktop.org/archives/xorg/2007-October/029507.html
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 450b8f8..5f33d84 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -21,3 +21,6 @@
  20 -> Hauppauge WinTV-HVR1255                             [0070:2251]
  21 -> Hauppauge WinTV-HVR1210                             [0070:2291,0070:2295]
  22 -> Mygica X8506 DMB-TH                                 [14f1:8651]
+ 23 -> Magic-Pro ProHDTV Extreme 2                         [14f1:8657]
+ 24 -> Hauppauge WinTV-HVR1850                             [0070:8541]
+ 25 -> Compro VideoMate E800                               [1858:e800]
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88
index 0736518..3385f8b 100644
--- a/Documentation/video4linux/CARDLIST.cx88
+++ b/Documentation/video4linux/CARDLIST.cx88
@@ -80,3 +80,4 @@
  79 -> Terratec Cinergy HT PCI MKII                        [153b:1177]
  80 -> Hauppauge WinTV-IR Only                             [0070:9290]
  81 -> Leadtek WinFast DTV1800 Hybrid                      [107d:6654]
+ 82 -> WinFast DTV2000 H rev. J                            [107d:6f2b]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index e352d75..b8afef4 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,5 +1,5 @@
   0 -> Unknown EM2800 video grabber             (em2800)        [eb1a:2800]
-  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
+  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
   2 -> Terratec Cinergy 250 USB                 (em2820/em2840) [0ccd:0036]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
@@ -7,7 +7,7 @@
   6 -> Terratec Cinergy 200 USB                 (em2800)
   7 -> Leadtek Winfast USB II                   (em2800)        [0413:6023]
   8 -> Kworld USB2800                           (em2800)
-  9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker (em2820/em2840) [1b80:e302,2304:0207,2304:021a]
+  9 -> Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker  (em2820/em2840) [1b80:e302,1b80:e304,2304:0207,2304:021a]
  10 -> Hauppauge WinTV HVR 900                  (em2880)        [2040:6500]
  11 -> Terratec Hybrid XS                       (em2880)        [0ccd:0042]
  12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
@@ -33,7 +33,7 @@
  34 -> Terratec Cinergy A Hybrid XS             (em2860)        [0ccd:004f]
  35 -> Typhoon DVD Maker                        (em2860)
  36 -> NetGMBH Cam                              (em2860)
- 37 -> Gadmei UTV330                            (em2860)
+ 37 -> Gadmei UTV330                            (em2860)        [eb1a:50a6]
  38 -> Yakumo MovieMixer                        (em2861)
  39 -> KWorld PVRTV 300U                        (em2861)        [eb1a:e300]
  40 -> Plextor ConvertX PX-TV100U               (em2861)        [093b:a005]
@@ -67,3 +67,5 @@
  69 -> KWorld ATSC 315U HDTV TV Box             (em2882)        [eb1a:a313]
  70 -> Evga inDtube                             (em2882)
  71 -> Silvercrest Webcam 1.3mpix               (em2820/em2840)
+ 72 -> Gadmei UTV330+                           (em2861)
+ 73 -> Reddo DVB-C USB TV Box                   (em2870)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index c913e56..2620d60 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -167,3 +167,8 @@
 166 -> Beholder BeholdTV 607 RDS                [5ace:6073]
 167 -> Beholder BeholdTV 609 RDS                [5ace:6092]
 168 -> Beholder BeholdTV 609 RDS                [5ace:6093]
+169 -> Compro VideoMate S350/S300               [185b:c900]
+170 -> AverMedia AverTV Studio 505              [1461:a115]
+171 -> Beholder BeholdTV X7                     [5ace:7595]
+172 -> RoverMedia TV Link Pro FM                [19d1:0138]
+173 -> Zolid Hybrid TV Tuner PCI                [1131:2004]
diff --git a/Documentation/video4linux/CARDLIST.saa7164 b/Documentation/video4linux/CARDLIST.saa7164
new file mode 100644
index 0000000..152bd7b
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.saa7164
@@ -0,0 +1,9 @@
+  0 -> Unknown
+  1 -> Generic Rev2
+  2 -> Generic Rev3
+  3 -> Hauppauge WinTV-HVR2250                             [0070:8880,0070:8810]
+  4 -> Hauppauge WinTV-HVR2200                             [0070:8980]
+  5 -> Hauppauge WinTV-HVR2200                             [0070:8900]
+  6 -> Hauppauge WinTV-HVR2200                             [0070:8901]
+  7 -> Hauppauge WinTV-HVR2250                             [0070:8891,0070:8851]
+  8 -> Hauppauge WinTV-HVR2250                             [0070:88A1]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index be67844..e0d298f 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -78,3 +78,6 @@ tuner=77 - TCL tuner MF02GIP-5N-E
 tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner
 tuner=79 - Philips PAL/SECAM multi (FM1216 MK5)
 tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
+tuner=81 - Partsnic (Daewoo) PTI-5NF05
+tuner=82 - Philips CU1216L
+tuner=83 - NXP TDA18271
diff --git a/Documentation/video4linux/CQcam.txt b/Documentation/video4linux/CQcam.txt
index 04986ef..d230878 100644
--- a/Documentation/video4linux/CQcam.txt
+++ b/Documentation/video4linux/CQcam.txt
@@ -18,8 +18,8 @@ Table of Contents
 
 1.0 Introduction
 
-  The file ../drivers/char/c-qcam.c is a device driver for the
-Logitech (nee Connectix) parallel port interface color CCD camera.
+  The file ../../drivers/media/video/c-qcam.c is a device driver for
+the Logitech (nee Connectix) parallel port interface color CCD camera.
 This is a fairly inexpensive device for capturing images.  Logitech
 does not currently provide information for developers, but many people
 have engineered several solutions for non-Microsoft use of the Color
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 573f95b..3f61825 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -140,6 +140,7 @@ spca500		04fc:7333	PalmPixDC85
 sunplus		04fc:ffff	Pure DigitalDakota
 spca501		0506:00df	3Com HomeConnect Lite
 sunplus		052b:1513	Megapix V4
+sunplus		052b:1803	MegaImage VI
 tv8532		0545:808b	Veo Stingray
 tv8532		0545:8333	Veo Stingray
 sunplus		0546:3155	Polaroid PDC3070
@@ -172,6 +173,8 @@ ov519		05a9:8519	OmniVision
 ov519		05a9:a518	D-Link DSB-C310 Webcam
 sunplus		05da:1018	Digital Dream Enigma 1.3
 stk014		05e1:0893	Syntek DV4000
+gl860		05e3:0503	Genesys Logic PC Camera
+gl860		05e3:f191	Genesys Logic PC Camera
 spca561		060b:a001	Maxell Compact Pc PM3
 zc3xx		0698:2003	CTX M730V built in
 spca500		06bd:0404	Agfa CL20
@@ -182,6 +185,7 @@ ov534		06f8:3002	Hercules Blog Webcam
 ov534		06f8:3003	Hercules Dualpix HD Weblog
 sonixj		06f8:3004	Hercules Classic Silver
 sonixj		06f8:3008	Hercules Deluxe Optical Glass
+pac7311		06f8:3009	Hercules Classic Link
 spca508		0733:0110	ViewQuest VQ110
 spca508		0130:0130	Clone Digital Webcam 11043
 spca501		0733:0401	Intel Create and Share
@@ -235,8 +239,10 @@ pac7311		093a:2621	PAC731x
 pac7311		093a:2622	Genius Eye 312
 pac7311		093a:2624	PAC7302
 pac7311		093a:2626	Labtec 2200
+pac7311		093a:2629	Genious iSlim 300
 pac7311		093a:262a	Webcam 300k
 pac7311		093a:262c	Philips SPC 230 NC
+jeilinj		0979:0280	Sakar 57379
 zc3xx		0ac8:0302	Z-star Vimicro zc0302
 vc032x		0ac8:0321	Vimicro generic vc0321
 vc032x		0ac8:0323	Vimicro Vc0323
@@ -247,6 +253,7 @@ zc3xx		0ac8:305b	Z-star Vimicro zc0305b
 zc3xx		0ac8:307b	Ldlc VC302+Ov7620
 vc032x		0ac8:c001	Sony embedded vimicro
 vc032x		0ac8:c002	Sony embedded vimicro
+vc032x		0ac8:c301	Samsung Q1 Ultra Premium
 spca508		0af9:0010	Hama USB Sightcam 100
 spca508		0af9:0011	Hama USB Sightcam 100
 sonixb		0c45:6001	Genius VideoCAM NB
@@ -284,6 +291,7 @@ sonixj		0c45:613a	Microdia Sonix PC Camera
 sonixj		0c45:613b	Surfer SN-206
 sonixj		0c45:613c	Sonix Pccam168
 sonixj		0c45:6143	Sonix Pccam168
+sonixj		0c45:6148	Digitus DA-70811/ZSMC USB PC Camera ZS211/Microdia
 sn9c20x		0c45:6240	PC Camera (SN9C201 + MT9M001)
 sn9c20x		0c45:6242	PC Camera (SN9C201 + MT9M111)
 sn9c20x		0c45:6248	PC Camera (SN9C201 + OV9655)
diff --git a/Documentation/video4linux/si4713.txt b/Documentation/video4linux/si4713.txt
new file mode 100644
index 0000000..25abdb7
--- /dev/null
+++ b/Documentation/video4linux/si4713.txt
@@ -0,0 +1,176 @@
+Driver for I2C radios for the Silicon Labs Si4713 FM Radio Transmitters
+
+Copyright (c) 2009 Nokia Corporation
+Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
+
+
+Information about the Device
+============================
+This chip is a Silicon Labs product. It is a I2C device, currently on 0x63 address.
+Basically, it has transmission and signal noise level measurement features.
+
+The Si4713 integrates transmit functions for FM broadcast stereo transmission.
+The chip also allows integrated receive power scanning to identify low signal
+power FM channels.
+
+The chip is programmed using commands and responses. There are also several
+properties which can change the behavior of this chip.
+
+Users must comply with local regulations on radio frequency (RF) transmission.
+
+Device driver description
+=========================
+There are two modules to handle this device. One is a I2C device driver
+and the other is a platform driver.
+
+The I2C device driver exports a v4l2-subdev interface to the kernel.
+All properties can also be accessed by v4l2 extended controls interface, by
+using the v4l2-subdev calls (g_ext_ctrls, s_ext_ctrls).
+
+The platform device driver exports a v4l2 radio device interface to user land.
+So, it uses the I2C device driver as a sub device in order to send the user
+commands to the actual device. Basically it is a wrapper to the I2C device driver.
+
+Applications can use v4l2 radio API to specify frequency of operation, mute state,
+etc. But mostly of its properties will be present in the extended controls.
+
+When the v4l2 mute property is set to 1 (true), the driver will turn the chip off.
+
+Properties description
+======================
+
+The properties can be accessed using v4l2 extended controls.
+Here is an output from v4l2-ctl util:
+/ # v4l2-ctl -d /dev/radio0 --all -L
+Driver Info:
+	Driver name   : radio-si4713
+	Card type     : Silicon Labs Si4713 Modulator
+	Bus info      :
+	Driver version: 0
+	Capabilities  : 0x00080800
+		RDS Output
+		Modulator
+Audio output: 0 (FM Modulator Audio Out)
+Frequency: 1408000 (88.000000 MHz)
+Video Standard = 0x00000000
+Modulator:
+	Name                 : FM Modulator
+	Capabilities         : 62.5 Hz stereo rds
+	Frequency range      : 76.0 MHz - 108.0 MHz
+	Subchannel modulation: stereo+rds
+
+User Controls
+
+			   mute (bool) : default=1 value=0
+
+FM Radio Modulator Controls
+
+	   rds_signal_deviation (int)  : min=0 max=90000 step=10 default=200 value=200 flags=slider
+		 rds_program_id (int)  : min=0 max=65535 step=1 default=0 value=0
+	       rds_program_type (int)  : min=0 max=31 step=1 default=0 value=0
+		    rds_ps_name (str)  : min=0 max=96 step=8 value='si4713  '
+		 rds_radio_text (str)  : min=0 max=384 step=32 value=''
+  audio_limiter_feature_enabled (bool) : default=1 value=1
+     audio_limiter_release_time (int)  : min=250 max=102390 step=50 default=5010 value=5010 flags=slider
+	audio_limiter_deviation (int)  : min=0 max=90000 step=10 default=66250 value=66250 flags=slider
+audio_compression_feature_enabl (bool) : default=1 value=1
+	 audio_compression_gain (int)  : min=0 max=20 step=1 default=15 value=15 flags=slider
+    audio_compression_threshold (int)  : min=-40 max=0 step=1 default=-40 value=-40 flags=slider
+  audio_compression_attack_time (int)  : min=0 max=5000 step=500 default=0 value=0 flags=slider
+ audio_compression_release_time (int)  : min=100000 max=1000000 step=100000 default=1000000 value=1000000 flags=slider
+     pilot_tone_feature_enabled (bool) : default=1 value=1
+	   pilot_tone_deviation (int)  : min=0 max=90000 step=10 default=6750 value=6750 flags=slider
+	   pilot_tone_frequency (int)  : min=0 max=19000 step=1 default=19000 value=19000 flags=slider
+	  pre_emphasis_settings (menu) : min=0 max=2 default=1 value=1
+	       tune_power_level (int)  : min=0 max=120 step=1 default=88 value=88 flags=slider
+	 tune_antenna_capacitor (int)  : min=0 max=191 step=1 default=0 value=110 flags=slider
+/ #
+
+Here is a summary of them:
+
+* Pilot is an audible tone sent by the device.
+
+pilot_frequency - Configures the frequency of the stereo pilot tone.
+pilot_deviation - Configures pilot tone frequency deviation level.
+pilot_enabled - Enables or disables the pilot tone feature.
+
+* The si4713 device is capable of applying audio compression to the transmitted signal.
+
+acomp_enabled - Enables or disables the audio dynamic range control feature.
+acomp_gain - Sets the gain for audio dynamic range control.
+acomp_threshold - Sets the threshold level for audio dynamic range control.
+acomp_attack_time - Sets the attack time for audio dynamic range control.
+acomp_release_time - Sets the release time for audio dynamic range control.
+
+* Limiter setups audio deviation limiter feature. Once a over deviation occurs,
+it is possible to adjust the front-end gain of the audio input and always
+prevent over deviation.
+
+limiter_enabled - Enables or disables the limiter feature.
+limiter_deviation - Configures audio frequency deviation level.
+limiter_release_time - Sets the limiter release time.
+
+* Tuning power
+
+power_level - Sets the output power level for signal transmission.
+antenna_capacitor - This selects the value of antenna tuning capacitor manually
+or automatically if set to zero.
+
+* RDS related
+
+rds_ps_name - Sets the RDS ps name field for transmission.
+rds_radio_text - Sets the RDS radio text for transmission.
+rds_pi - Sets the RDS PI field for transmission.
+rds_pty - Sets the RDS PTY field for transmission.
+
+* Region related
+
+preemphasis - sets the preemphasis to be applied for transmission.
+
+RNL
+===
+
+This device also has an interface to measure received noise level. To do that, you should
+ioctl the device node. Here is an code of example:
+
+int main (int argc, char *argv[])
+{
+	struct si4713_rnl rnl;
+	int fd = open("/dev/radio0", O_RDWR);
+	int rval;
+
+	if (argc < 2)
+		return -EINVAL;
+
+	if (fd < 0)
+		return fd;
+
+	sscanf(argv[1], "%d", &rnl.frequency);
+
+	rval = ioctl(fd, SI4713_IOC_MEASURE_RNL, &rnl);
+	if (rval < 0)
+		return rval;
+
+	printf("received noise level: %d\n", rnl.rnl);
+
+	close(fd);
+}
+
+The struct si4713_rnl and SI4713_IOC_MEASURE_RNL are defined under
+include/media/si4713.h.
+
+Stereo/Mono and RDS subchannels
+===============================
+
+The device can also be configured using the available sub channels for
+transmission. To do that use S/G_MODULATOR ioctl and configure txsubchans properly.
+Refer to v4l2-spec for proper use of this ioctl.
+
+Testing
+=======
+Testing is usually done with v4l2-ctl utility for managing FM tuner cards.
+The tool can be found in v4l-dvb repository under v4l2-apps/util directory.
+
+Example for setting rds ps name:
+# v4l2-ctl -d /dev/radio0 --set-ctrl=rds_ps_name="Dummy"
+
diff --git a/Documentation/video4linux/soc-camera.txt b/Documentation/video4linux/soc-camera.txt
index 178ef3c..3f87c7d 100644
--- a/Documentation/video4linux/soc-camera.txt
+++ b/Documentation/video4linux/soc-camera.txt
@@ -116,5 +116,45 @@ functionality.
 struct soc_camera_device also links to an array of struct soc_camera_data_format,
 listing pixel formats, supported by the camera.
 
+VIDIOC_S_CROP and VIDIOC_S_FMT behaviour
+----------------------------------------
+
+Above user ioctls modify image geometry as follows:
+
+VIDIOC_S_CROP: sets location and sizes of the sensor window. Unit is one sensor
+pixel. Changing sensor window sizes preserves any scaling factors, therefore
+user window sizes change as well.
+
+VIDIOC_S_FMT: sets user window. Should preserve previously set sensor window as
+much as possible by modifying scaling factors. If the sensor window cannot be
+preserved precisely, it may be changed too.
+
+In soc-camera there are two locations, where scaling and cropping can taks
+place: in the camera driver and in the host driver. User ioctls are first passed
+to the host driver, which then generally passes them down to the camera driver.
+It is more efficient to perform scaling and cropping in the camera driver to
+save camera bus bandwidth and maximise the framerate. However, if the camera
+driver failed to set the required parameters with sufficient precision, the host
+driver may decide to also use its own scaling and cropping to fulfill the user's
+request.
+
+Camera drivers are interfaced to the soc-camera core and to host drivers over
+the v4l2-subdev API, which is completely functional, it doesn't pass any data.
+Therefore all camera drivers shall reply to .g_fmt() requests with their current
+output geometry. This is necessary to correctly configure the camera bus.
+.s_fmt() and .try_fmt() have to be implemented too. Sensor window and scaling
+factors have to be maintained by camera drivers internally. According to the
+V4L2 API all capture drivers must support the VIDIOC_CROPCAP ioctl, hence we
+rely on camera drivers implementing .cropcap(). If the camera driver does not
+support cropping, it may choose to not implement .s_crop(), but to enable
+cropping support by the camera host driver at least the .g_crop method must be
+implemented.
+
+User window geometry is kept in .user_width and .user_height fields in struct
+soc_camera_device and used by the soc-camera core and host drivers. The core
+updates these fields upon successful completion of a .s_fmt() call, but if these
+fields change elsewhere, e.g., during .s_crop() processing, the host driver is
+responsible for updating them.
+
 --
 Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index ba4706a..b806eda 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -370,19 +370,20 @@ from the remove() callback ensures that this is always done correctly.
 The bridge driver also has some helper functions it can use:
 
 struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
-	       "module_foo", "chipid", 0x36);
+	       "module_foo", "chipid", 0x36, NULL);
 
 This loads the given module (can be NULL if no module needs to be loaded) and
 calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
 If all goes well, then it registers the subdev with the v4l2_device.
 
-You can also use v4l2_i2c_new_probed_subdev() which is very similar to
-v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses
-that it should probe. Internally it calls i2c_new_probed_device().
+You can also use the last argument of v4l2_i2c_new_subdev() to pass an array
+of possible I2C addresses that it should probe. These probe addresses are
+only used if the previous argument is 0. A non-zero argument means that you
+know the exact i2c address so in that case no probing will take place.
 
 Both functions return NULL if something went wrong.
 
-Note that the chipid you pass to v4l2_i2c_new_(probed_)subdev() is usually
+Note that the chipid you pass to v4l2_i2c_new_subdev() is usually
 the same as the module name. It allows you to specify a chip variant, e.g.
 "saa7114" or "saa7115". In general though the i2c driver autodetects this.
 The use of chipid is something that needs to be looked at more closely at a
@@ -410,11 +411,6 @@ the irq and platform_data arguments after the subdev was setup. The older
 v4l2_i2c_new_(probed_)subdev functions will call s_config as well, but with
 irq set to 0 and platform_data set to NULL.
 
-Note that in the next kernel release the functions v4l2_i2c_new_subdev,
-v4l2_i2c_new_probed_subdev and v4l2_i2c_new_probed_subdev_addr will all be
-replaced by a single v4l2_i2c_new_subdev that is identical to
-v4l2_i2c_new_subdev_cfg but without the irq and platform_data arguments.
-
 struct video_device
 -------------------
 
@@ -490,31 +486,35 @@ VFL_TYPE_RADIO: radioX for radio tuners
 VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use)
 
 The last argument gives you a certain amount of control over the device
-kernel number used (i.e. the X in videoX). Normally you will pass -1 to
-let the v4l2 framework pick the first free number. But if a driver creates
-many devices, then it can be useful to have different video devices in
-separate ranges. For example, video capture devices start at 0, video
-output devices start at 16.
-
-So you can use the last argument to specify a minimum kernel number and
-the v4l2 framework will try to pick the first free number that is equal
+device node number used (i.e. the X in videoX). Normally you will pass -1
+to let the v4l2 framework pick the first free number. But sometimes users
+want to select a specific node number. It is common that drivers allow
+the user to select a specific device node number through a driver module
+option. That number is then passed to this function and video_register_device
+will attempt to select that device node number. If that number was already
+in use, then the next free device node number will be selected and it
+will send a warning to the kernel log.
+
+Another use-case is if a driver creates many devices. In that case it can
+be useful to place different video devices in separate ranges. For example,
+video capture devices start at 0, video output devices start at 16.
+So you can use the last argument to specify a minimum device node number
+and the v4l2 framework will try to pick the first free number that is equal
 or higher to what you passed. If that fails, then it will just pick the
 first free number.
 
+Since in this case you do not care about a warning about not being able
+to select the specified device node number, you can call the function
+video_register_device_no_warn() instead.
+
 Whenever a device node is created some attributes are also created for you.
 If you look in /sys/class/video4linux you see the devices. Go into e.g.
 video0 and you will see 'name' and 'index' attributes. The 'name' attribute
-is the 'name' field of the video_device struct. The 'index' attribute is
-a device node index that can be assigned by the driver, or that is calculated
-for you.
-
-If you call video_register_device(), then the index is just increased by
-1 for each device node you register. The first video device node you register
-always starts off with 0.
+is the 'name' field of the video_device struct.
 
-Alternatively you can call video_register_device_index() which is identical
-to video_register_device(), but with an extra index argument. Here you can
-pass a specific index value (between 0 and 31) that should be used.
+The 'index' attribute is the index of the device node: for each call to
+video_register_device() the index is just increased by 1. The first video
+device node you register always starts with index 0.
 
 Users can setup udev rules that utilize the index attribute to make fancy
 device names (e.g. 'mpegX' for MPEG video capture device nodes).
@@ -523,9 +523,8 @@ After the device was successfully registered, then you can use these fields:
 
 - vfl_type: the device type passed to video_register_device.
 - minor: the assigned device minor number.
-- num: the device kernel number (i.e. the X in videoX).
-- index: the device index number (calculated or set explicitly using
-  video_register_device_index).
+- num: the device node number (i.e. the X in videoX).
+- index: the device index number.
 
 If the registration failed, then you need to call video_device_release()
 to free the allocated video_device struct, or free your own struct if the
diff --git a/Documentation/vm/slub.txt b/Documentation/vm/slub.txt
index bb1f5c6..510917f 100644
--- a/Documentation/vm/slub.txt
+++ b/Documentation/vm/slub.txt
@@ -41,6 +41,8 @@ Possible debug options are
 	P		Poisoning (object and padding)
 	U		User tracking (free and alloc)
 	T		Trace (please only use on single slabs)
+	O		Switch debugging off for caches that would have
+			caused higher minimum slab orders
 	-		Switch all debugging off (useful if the kernel is
 			configured with CONFIG_SLUB_DEBUG_ON)
 
@@ -59,6 +61,14 @@ to the dentry cache with
 
 	slub_debug=F,dentry
 
+Debugging options may require the minimum possible slab order to increase as
+a result of storing the metadata (for example, caches with PAGE_SIZE object
+sizes).  This has a higher liklihood of resulting in slab allocation errors
+in low memory situations or if there's high fragmentation of memory.  To
+switch off debugging for such caches by default, use
+
+	slub_debug=O
+
 In case you forgot to enable debugging on the kernel command line: It is
 possible to enable debugging manually when the kernel is up. Look at the
 contents of:
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index 8da3a79..30b43e1 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -599,6 +599,7 @@ Protocol:	2.07+
   0x00000000	The default x86/PC environment
   0x00000001	lguest
   0x00000002	Xen
+  0x00000003	Moorestown MID
 
 Field name:	hardware_subarch_data
 Type:		write (subarch-dependent)
diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
index 4f91385..feb37e1 100644
--- a/Documentation/x86/zero-page.txt
+++ b/Documentation/x86/zero-page.txt
@@ -12,6 +12,7 @@ Offset	Proto	Name		Meaning
 000/040	ALL	screen_info	Text mode or frame buffer information
 				(struct screen_info)
 040/014	ALL	apm_bios_info	APM BIOS information (struct apm_bios_info)
+058/008	ALL	tboot_addr      Physical address of tboot shared page
 060/010	ALL	ist_info	Intel SpeedStep (IST) BIOS support information
 				(struct ist_info)
 080/010	ALL	hd0_info	hd0 disk parameter, OBSOLETE!!
diff --git a/MAINTAINERS b/MAINTAINERS
index 989ff11..751a307 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -534,10 +534,30 @@ L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 W:	http://maxim.org.za/at91_26.html
 S:	Maintained
 
+ARM/BCMRING ARM ARCHITECTURE
+M:	Leo Chen <leochen@broadcom.com>
+M:	Scott Branden <sbranden@broadcom.com>
+L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S:	Maintained
+F:	arch/arm/mach-bcmring
+
+ARM/BCMRING MTD NAND DRIVER
+M:	Leo Chen <leochen@broadcom.com>
+M:	Scott Branden <sbranden@broadcom.com>
+L:	linux-mtd@lists.infradead.org
+S:	Maintained
+F:	drivers/mtd/nand/bcm_umi_nand.c
+F:	drivers/mtd/nand/bcm_umi_bch.c
+F:	drivers/mtd/nand/bcm_umi_hamming.c
+F:	drivers/mtd/nand/nand_bcm_umi.h
+
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
-M:	Lennert Buytenhek <kernel@wantstofly.org>
+M:	Hartley Sweeten <hsweeten@visionengravers.com>
+M:	Ryan Mallon <ryan@bluewatersys.com>
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:	Maintained
+F:	arch/arm/mach-ep93xx/
+F:	arch/arm/mach-ep93xx/include/mach/
 
 ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT
 M:	Lennert Buytenhek <kernel@wantstofly.org>
@@ -685,6 +705,18 @@ ARM/MAGICIAN MACHINE SUPPORT
 M:	Philipp Zabel <philipp.zabel@gmail.com>
 S:	Maintained
 
+ARM/Marvell Loki/Kirkwood/MV78xx0/Orion SOC support
+M:	Lennert Buytenhek <buytenh@marvell.com>
+M:	Nicolas Pitre <nico@marvell.com>
+L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+T:	git git://git.marvell.com/orion
+S:	Maintained
+F:	arch/arm/mach-loki/
+F:	arch/arm/mach-kirkwood/
+F:	arch/arm/mach-mv78xx0/
+F:	arch/arm/mach-orion5x/
+F:	arch/arm/plat-orion/
+
 ARM/MIOA701 MACHINE SUPPORT
 M:	Robert Jarzmik <robert.jarzmik@free.fr>
 L:	linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
@@ -876,6 +908,7 @@ M:	"Luis R. Rodriguez" <lrodriguez@atheros.com>
 M:	Bob Copeland <me@bobcopeland.com>
 L:	linux-wireless@vger.kernel.org
 L:	ath5k-devel@lists.ath5k.org
+W:	http://wireless.kernel.org/en/users/Drivers/ath5k
 S:	Maintained
 F:	drivers/net/wireless/ath/ath5k/
 
@@ -887,6 +920,7 @@ M:	Vasanthakumar Thiagarajan <vasanth@atheros.com>
 M:	Senthil Balasubramanian <senthilkumar@atheros.com>
 L:	linux-wireless@vger.kernel.org
 L:	ath9k-devel@lists.ath9k.org
+W:	http://wireless.kernel.org/en/users/Drivers/ath9k
 S:	Supported
 F:	drivers/net/wireless/ath/ath9k/
 
@@ -897,6 +931,12 @@ W:	http://wireless.kernel.org/en/users/Drivers/ar9170
 S:	Maintained
 F:	drivers/net/wireless/ath/ar9170/
 
+ATK0110 HWMON DRIVER
+M:	Luca Tettamanti <kronos.it@gmail.com>
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+F:	drivers/hwmon/asus_atk0110.c
+
 ATI_REMOTE2 DRIVER
 M:	Ville Syrjala <syrjala@sci.fi>
 S:	Maintained
@@ -1933,7 +1973,6 @@ F:	fs/ext2/
 F:	include/linux/ext2*
 
 EXT3 FILE SYSTEM
-M:	Stephen Tweedie <sct@redhat.com>
 M:	Andrew Morton <akpm@linux-foundation.org>
 M:	Andreas Dilger <adilger@sun.com>
 L:	linux-ext4@vger.kernel.org
@@ -2118,13 +2157,16 @@ F:	Documentation/filesystems/caching/
 F:	fs/fscache/
 F:	include/linux/fscache*.h
 
-FTRACE
+TRACING
 M:	Steven Rostedt <rostedt@goodmis.org>
+M:	Frederic Weisbecker <fweisbec@gmail.com>
+M:	Ingo Molnar <mingo@redhat.com>
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip.git tracing/core
 S:	Maintained
 F:	Documentation/trace/ftrace.txt
 F:	arch/*/*/*/ftrace.h
 F:	arch/*/kernel/ftrace.c
-F:	include/*/ftrace.h
+F:	include/*/ftrace.h include/trace/ include/linux/trace*.h
 F:	kernel/trace/
 
 FUJITSU FR-V (FRV) PORT
@@ -2184,6 +2226,13 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git
 S:	Maintained
 F:	include/asm-generic
 
+GENERIC UIO DRIVER FOR PCI DEVICES
+M:	Michael S. Tsirkin <mst@redhat.com>
+L:	kvm@vger.kernel.org
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+F:	drivers/uio/uio_pci_generic.c
+
 GFS2 FILE SYSTEM
 M:	Steven Whitehouse <swhiteho@redhat.com>
 L:	cluster-devel@redhat.com
@@ -2660,25 +2709,21 @@ F:	drivers/net/ixgbe/
 
 INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
 M:	Zhu Yi <yi.zhu@intel.com>
-M:	James Ketrenos <jketreno@linux.intel.com>
 M:	Reinette Chatre <reinette.chatre@intel.com>
+M:	Intel Linux Wireless <ilw@linux.intel.com>
 L:	linux-wireless@vger.kernel.org
-L:	ipw2100-devel@lists.sourceforge.net
-W:	http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
 W:	http://ipw2100.sourceforge.net
-S:	Supported
+S:	Odd Fixes
 F:	Documentation/networking/README.ipw2100
 F:	drivers/net/wireless/ipw2x00/ipw2100.*
 
 INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
 M:	Zhu Yi <yi.zhu@intel.com>
-M:	James Ketrenos <jketreno@linux.intel.com>
 M:	Reinette Chatre <reinette.chatre@intel.com>
+M:	Intel Linux Wireless <ilw@linux.intel.com>
 L:	linux-wireless@vger.kernel.org
-L:	ipw2100-devel@lists.sourceforge.net
-W:	http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
 W:	http://ipw2200.sourceforge.net
-S:	Supported
+S:	Odd Fixes
 F:	Documentation/networking/README.ipw2200
 F:	drivers/net/wireless/ipw2x00/ipw2200.*
 
@@ -2695,8 +2740,8 @@ F:	include/linux/wimax/i2400m.h
 INTEL WIRELESS WIFI LINK (iwlwifi)
 M:	Zhu Yi <yi.zhu@intel.com>
 M:	Reinette Chatre <reinette.chatre@intel.com>
+M:	Intel Linux Wireless <ilw@linux.intel.com>
 L:	linux-wireless@vger.kernel.org
-L:	ipw3945-devel@lists.sourceforge.net
 W:	http://intellinuxwireless.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
 S:	Supported
@@ -2855,8 +2900,8 @@ F:	fs/jffs2/
 F:	include/linux/jffs2.h
 
 JOURNALLING LAYER FOR BLOCK DEVICES (JBD)
-M:	Stephen Tweedie <sct@redhat.com>
 M:	Andrew Morton <akpm@linux-foundation.org>
+M:	Jan Kara <jack@suse.cz>
 L:	linux-ext4@vger.kernel.org
 S:	Maintained
 F:	fs/jbd*/
@@ -2928,6 +2973,7 @@ F:	include/linux/sunrpc/
 
 KERNEL VIRTUAL MACHINE (KVM)
 M:	Avi Kivity <avi@redhat.com>
+M:	Marcelo Tosatti <mtosatti@redhat.com>
 L:	kvm@vger.kernel.org
 W:	http://kvm.qumranet.com
 S:	Supported
@@ -3279,8 +3325,14 @@ S:	Supported
 F:	drivers/net/mv643xx_eth.*
 F:	include/linux/mv643xx.h
 
+MARVELL MWL8K WIRELESS DRIVER
+M:	Lennert Buytenhek <buytenh@marvell.com>
+L:	linux-wireless@vger.kernel.org
+S:	Supported
+F:	drivers/net/wireless/mwl8k.c
+
 MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
-M:	Nicolas Pitre <nico@cam.org>
+M:	Nicolas Pitre <nico@fluxnic.net>
 S:	Maintained
 
 MARVELL YUKON / SYSKONNECT DRIVER
@@ -3591,9 +3643,12 @@ M:	"John W. Linville" <linville@tuxdriver.com>
 L:	linux-wireless@vger.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
 S:	Maintained
+F:	net/mac80211/
+F:	net/rfkill/
 F:	net/wireless/
 F:	include/net/ieee80211*
 F:	include/linux/wireless.h
+F:	drivers/net/wireless/
 
 NETWORKING DRIVERS
 L:	netdev@vger.kernel.org
@@ -3945,7 +4000,7 @@ S:	Maintained
 F:	include/linux/delayacct.h
 F:	kernel/delayacct.c
 
-PERFORMANCE COUNTER SUBSYSTEM
+PERFORMANCE EVENTS SUBSYSTEM
 M:	Peter Zijlstra <a.p.zijlstra@chello.nl>
 M:	Paul Mackerras <paulus@samba.org>
 M:	Ingo Molnar <mingo@elte.hu>
@@ -3969,6 +4024,14 @@ S:	Maintained
 F:	drivers/block/pktcdvd.c
 F:	include/linux/pktcdvd.h
 
+PMC SIERRA MaxRAID DRIVER
+P:	Anil Ravindranath
+M:	anil_ravindranath@pmc-sierra.com
+L:	linux-scsi@vger.kernel.org
+W:	http://www.pmc-sierra.com/
+S:	Supported
+F:	drivers/scsi/pmcraid.*
+
 POSIX CLOCKS and TIMERS
 M:	Thomas Gleixner <tglx@linutronix.de>
 S:	Supported
@@ -4299,7 +4362,7 @@ L:	linux-wireless@vger.kernel.org
 W:	http://linuxwireless.org/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 S:	Maintained
-F:	drivers/net/wireless/rtl818*
+F:	drivers/net/wireless/rtl818x/rtl8180*
 
 RTL8187 WIRELESS DRIVER
 M:	Herton Ronaldo Krzesinski <herton@mandriva.com.br>
@@ -4391,6 +4454,14 @@ S:	Maintained
 F:	kernel/sched*
 F:	include/linux/sched.h
 
+SCORE ARCHITECTURE
+P:	Chen Liqin
+M:	liqin.chen@sunplusct.com
+P:	Lennox Wu
+M:	lennox.wu@sunplusct.com
+W:	http://www.sunplusct.com
+S:	Supported
+
 SCSI CDROM DRIVER
 M:	Jens Axboe <axboe@kernel.dk>
 L:	linux-scsi@vger.kernel.org
@@ -4407,7 +4478,7 @@ F:	drivers/scsi/sg.c
 F:	include/scsi/sg.h
 
 SCSI SUBSYSTEM
-M:	"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
+M:	"James E.J. Bottomley" <James.Bottomley@suse.de>
 L:	linux-scsi@vger.kernel.org
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git
@@ -4526,9 +4597,10 @@ S:	Supported
 F:	drivers/net/benet/
 
 SFC NETWORK DRIVER
-P:	Steve Hodgson
-P:	Ben Hutchings
-M:	Robert Stonehouse <linux-net-drivers@solarflare.com>
+M:	Solarflare linux maintainers <linux-net-drivers@solarflare.com>
+M:	Steve Hodgson <shodgson@solarflare.com>
+M:	Ben Hutchings <bhutchings@solarflare.com>
+L:	netdev@vger.kernel.org
 S:	Supported
 F:	drivers/net/sfc/
 
@@ -4589,6 +4661,12 @@ F:	arch/arm/mach-s3c2410/
 F:	drivers/*/*s3c2410*
 F:	drivers/*/*/*s3c2410*
 
+TI DAVINCI MACHINE SUPPORT
+P:	Kevin Hilman
+M:	davinci-linux-open-source@linux.davincidsp.com
+S:	Supported
+F:	arch/arm/mach-davinci
+
 SIS 190 ETHERNET DRIVER
 M:	Francois Romieu <romieu@fr.zoreil.com>
 L:	netdev@vger.kernel.org
@@ -4640,7 +4718,7 @@ F:	include/linux/sl?b*.h
 F:	mm/sl?b.c
 
 SMC91x ETHERNET DRIVER
-M:	Nicolas Pitre <nico@cam.org>
+M:	Nicolas Pitre <nico@fluxnic.net>
 S:	Maintained
 F:	drivers/net/smc91x.*
 
@@ -5578,6 +5656,24 @@ M:	Miloslav Trmac <mitr@volny.cz>
 S:	Maintained
 F:	drivers/input/misc/wistron_btns.c
 
+WL1251 WIRELESS DRIVER
+P:	Kalle Valo
+M:	kalle.valo@nokia.com
+L:	linux-wireless@vger.kernel.org
+W:	http://wireless.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+S:	Maintained
+F:	drivers/net/wireless/wl12xx/*
+X:	drivers/net/wireless/wl12xx/wl1271*
+
+WL1271 WIRELESS DRIVER
+M:	Luciano Coelho <luciano.coelho@nokia.com>
+L:	linux-wireless@vger.kernel.org
+W:	http://wireless.kernel.org
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+S:	Maintained
+F:	drivers/net/wireless/wl12xx/wl1271*
+
 WL3501 WIRELESS PCMCIA CARD DRIVER
 M:	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
 L:	linux-wireless@vger.kernel.org
@@ -5595,6 +5691,26 @@ S:	Supported
 F:	drivers/input/touchscreen/*wm97*
 F:	include/linux/wm97xx.h
 
+WOLFSON MICROELECTRONICS PMIC DRIVERS
+P:	Mark Brown
+M:	broonie@opensource.wolfsonmicro.com
+L:	linux-kernel@vger.kernel.org
+T:	git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
+W:	http://opensource.wolfsonmicro.com/node/8
+S:	Supported
+F:	drivers/leds/leds-wm83*.c
+F:	drivers/mfd/wm8*.c
+F:	drivers/power/wm83*.c
+F:	drivers/rtc/rtc-wm83*.c
+F:	drivers/regulator/wm8*.c
+F:	drivers/video/backlight/wm83*_bl.c
+F:	drivers/watchdog/wm83*_wdt.c
+F:	include/linux/mfd/wm831x/
+F:	include/linux/mfd/wm8350/
+F:	include/linux/mfd/wm8400/
+F:	sound/soc/codecs/wm8350.c
+F:	sound/soc/codecs/wm8400.c
+
 X.25 NETWORK LAYER
 M:	Henner Eisen <eis@baty.hanse.de>
 L:	linux-x25@vger.kernel.org
@@ -5627,7 +5743,7 @@ F:	include/xen/
 
 XFS FILESYSTEM
 P:	Silicon Graphics Inc
-M:	Felix Blyakher <felixb@sgi.com>
+M:	Alex Elder <aelder@sgi.com>
 M:	xfs-masters@oss.sgi.com
 L:	xfs@oss.sgi.com
 W:	http://oss.sgi.com/projects/xfs
diff --git a/Makefile b/Makefile
index 60de4ef..433493a 100644
--- a/Makefile
+++ b/Makefile
@@ -325,7 +325,7 @@ CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
 MODFLAGS	= -DMODULE
 CFLAGS_MODULE   = $(MODFLAGS)
 AFLAGS_MODULE   = $(MODFLAGS)
-LDFLAGS_MODULE  =
+LDFLAGS_MODULE  = -T $(srctree)/scripts/module-common.lds
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
 CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage
diff --git a/arch/Kconfig b/arch/Kconfig
index beea3cc..7f418bb 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -9,6 +9,7 @@ config OPROFILE
 	depends on TRACING_SUPPORT
 	select TRACING
 	select RING_BUFFER
+	select RING_BUFFER_ALLOW_SWAP
 	help
 	  OProfile is a profiling system capable of profiling the
 	  whole system, include the kernel, kernel modules, libraries,
diff --git a/arch/alpha/include/asm/agp.h b/arch/alpha/include/asm/agp.h
index 26c1791..a94d48b 100644
--- a/arch/alpha/include/asm/agp.h
+++ b/arch/alpha/include/asm/agp.h
@@ -9,10 +9,6 @@
 #define unmap_page_from_agp(page) 
 #define flush_agp_cache() mb()
 
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
 #define alloc_gatt_pages(order)		\
 	((char *)__get_free_pages(GFP_KERNEL, (order)))
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index d22ace9..dd8dcab 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -52,7 +52,6 @@ struct pci_controller {
    bus numbers.  */
 
 #define pcibios_assign_all_busses()	1
-#define pcibios_scan_all_fns(a, b)	0
 
 #define PCIBIOS_MIN_IO		alpha_mv.min_io_address
 #define PCIBIOS_MIN_MEM		alpha_mv.min_mem_address
diff --git a/arch/alpha/include/asm/percpu.h b/arch/alpha/include/asm/percpu.h
index b663f1f..2c12378 100644
--- a/arch/alpha/include/asm/percpu.h
+++ b/arch/alpha/include/asm/percpu.h
@@ -1,102 +1,18 @@
 #ifndef __ALPHA_PERCPU_H
 #define __ALPHA_PERCPU_H
 
-#include <linux/compiler.h>
-#include <linux/threads.h>
-#include <linux/percpu-defs.h>
-
-/*
- * Determine the real variable name from the name visible in the
- * kernel sources.
- */
-#define per_cpu_var(var) per_cpu__##var
-
-#ifdef CONFIG_SMP
-
-/*
- * per_cpu_offset() is the offset that has to be added to a
- * percpu variable to get to the instance for a certain processor.
- */
-extern unsigned long __per_cpu_offset[NR_CPUS];
-
-#define per_cpu_offset(x) (__per_cpu_offset[x])
-
-#define __my_cpu_offset per_cpu_offset(raw_smp_processor_id())
-#ifdef CONFIG_DEBUG_PREEMPT
-#define my_cpu_offset per_cpu_offset(smp_processor_id())
-#else
-#define my_cpu_offset __my_cpu_offset
-#endif
-
-#ifndef MODULE
-#define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset))
-#define PER_CPU_DEF_ATTRIBUTES
-#else
 /*
- * To calculate addresses of locally defined variables, GCC uses 32-bit
- * displacement from the GP. Which doesn't work for per cpu variables in
- * modules, as an offset to the kernel per cpu area is way above 4G.
+ * To calculate addresses of locally defined variables, GCC uses
+ * 32-bit displacement from the GP. Which doesn't work for per cpu
+ * variables in modules, as an offset to the kernel per cpu area is
+ * way above 4G.
  *
- * This forces allocation of a GOT entry for per cpu variable using
- * ldq instruction with a 'literal' relocation.
- */
-#define SHIFT_PERCPU_PTR(var, offset) ({		\
-	extern int simple_identifier_##var(void);	\
-	unsigned long __ptr, tmp_gp;			\
-	asm (  "br	%1, 1f		  	      \n\
-	1:	ldgp	%1, 0(%1)	    	      \n\
-		ldq %0, per_cpu__" #var"(%1)\t!literal"		\
-		: "=&r"(__ptr), "=&r"(tmp_gp));		\
-	(typeof(&per_cpu_var(var)))(__ptr + (offset)); })
-
-#define PER_CPU_DEF_ATTRIBUTES	__used
-
-#endif /* MODULE */
-
-/*
- * A percpu variable may point to a discarded regions. The following are
- * established ways to produce a usable pointer from the percpu variable
- * offset.
+ * Always use weak definitions for percpu variables in modules.
  */
-#define per_cpu(var, cpu) \
-	(*SHIFT_PERCPU_PTR(var, per_cpu_offset(cpu)))
-#define __get_cpu_var(var) \
-	(*SHIFT_PERCPU_PTR(var, my_cpu_offset))
-#define __raw_get_cpu_var(var) \
-	(*SHIFT_PERCPU_PTR(var, __my_cpu_offset))
-
-#else /* ! SMP */
-
-#define per_cpu(var, cpu)		(*((void)(cpu), &per_cpu_var(var)))
-#define __get_cpu_var(var)		per_cpu_var(var)
-#define __raw_get_cpu_var(var)		per_cpu_var(var)
-
-#define PER_CPU_DEF_ATTRIBUTES
-
-#endif /* SMP */
-
-#ifdef CONFIG_SMP
-#define PER_CPU_BASE_SECTION ".data.percpu"
-#else
-#define PER_CPU_BASE_SECTION ".data"
-#endif
-
-#ifdef CONFIG_SMP
-
-#ifdef MODULE
-#define PER_CPU_SHARED_ALIGNED_SECTION ""
-#else
-#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
-#endif
-#define PER_CPU_FIRST_SECTION ".first"
-
-#else
-
-#define PER_CPU_SHARED_ALIGNED_SECTION ""
-#define PER_CPU_FIRST_SECTION ""
-
+#if defined(MODULE) && defined(CONFIG_SMP)
+#define ARCH_NEEDS_WEAK_PER_CPU
 #endif
 
-#define PER_CPU_ATTRIBUTES
+#include <asm-generic/percpu.h>
 
 #endif /* __ALPHA_PERCPU_H */
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h
index 3641ec1..26773e3 100644
--- a/arch/alpha/include/asm/socket.h
+++ b/arch/alpha/include/asm/socket.h
@@ -32,6 +32,8 @@
 #define	SO_RCVTIMEO	0x1012
 #define	SO_SNDTIMEO	0x1013
 #define SO_ACCEPTCONN	0x1014
+#define SO_PROTOCOL	0x1028
+#define SO_DOMAIN	0x1029
 
 /* linux-specific, might as well be the same as on i386 */
 #define SO_NO_CHECK	11
diff --git a/arch/alpha/include/asm/tlbflush.h b/arch/alpha/include/asm/tlbflush.h
index 9d87aaa..e89e0c2 100644
--- a/arch/alpha/include/asm/tlbflush.h
+++ b/arch/alpha/include/asm/tlbflush.h
@@ -2,6 +2,7 @@
 #define _ALPHA_TLBFLUSH_H
 
 #include <linux/mm.h>
+#include <linux/sched.h>
 #include <asm/compiler.h>
 #include <asm/pgalloc.h>
 
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index b9d6568..6dc03c3 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -134,13 +134,6 @@ SECTIONS
 	__bss_stop = .;
 	_end = .;
 
-	/* Sections to be discarded */
-	/DISCARD/ : {
-		EXIT_TEXT
-		EXIT_DATA
-		*(.exitcall.exit)
-	}
-
 	.mdebug 0 : {
 		*(.mdebug)
 	}
@@ -150,4 +143,6 @@ SECTIONS
 
 	STABS_DEBUG
 	DWARF_DEBUG
+
+	DISCARDS
 }
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aef63c8..d778a69 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -46,10 +46,6 @@ config GENERIC_CLOCKEVENTS_BROADCAST
 	depends on GENERIC_CLOCKEVENTS
 	default y if SMP && !LOCAL_TIMERS
 
-config MMU
-	bool
-	default y
-
 config NO_IOPORT
 	bool
 
@@ -126,6 +122,13 @@ config ARCH_HAS_ILOG2_U32
 config ARCH_HAS_ILOG2_U64
 	bool
 
+config ARCH_HAS_CPUFREQ
+	bool
+	help
+	  Internal node to signify that the ARCH has CPUFREQ support
+	  and that the relevant menu configurations are displayed for
+	  it.
+
 config GENERIC_HWEIGHT
 	bool
 	default y
@@ -188,6 +191,13 @@ source "kernel/Kconfig.freezer"
 
 menu "System Type"
 
+config MMU
+	bool "MMU-based Paged Memory Management Support"
+	default y
+	help
+	  Select if you want MMU-based virtualised addressing space
+	  support by paged memory management. If unsure, say 'Y'.
+
 choice
 	prompt "ARM system type"
 	default ARCH_VERSATILE
@@ -203,6 +213,7 @@ config ARCH_AAEC2000
 config ARCH_INTEGRATOR
 	bool "ARM Ltd. Integrator family"
 	select ARM_AMBA
+	select ARCH_HAS_CPUFREQ
 	select HAVE_CLK
 	select COMMON_CLKDEV
 	select ICST525
@@ -217,6 +228,7 @@ config ARCH_REALVIEW
 	select ICST307
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
 	  This enables support for ARM Ltd RealView boards.
 
@@ -229,6 +241,7 @@ config ARCH_VERSATILE
 	select ICST307
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
 	  This enables support for ARM Ltd Versatile board.
 
@@ -327,6 +340,20 @@ config ARCH_H720X
 	help
 	  This enables support for systems based on the Hynix HMS720x
 
+config ARCH_NOMADIK
+	bool "STMicroelectronics Nomadik"
+	select ARM_AMBA
+	select ARM_VIC
+	select CPU_ARM926T
+	select HAVE_CLK
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  Support for the Nomadik platform by ST-Ericsson
+
 config ARCH_IOP13XX
 	bool "IOP13xx-based"
 	depends on MMU
@@ -493,10 +520,18 @@ config ARCH_W90X900
 	select CPU_ARM926T
 	select ARCH_REQUIRE_GPIOLIB
 	select GENERIC_GPIO
+	select HAVE_CLK
 	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
 	help
-		Support for Nuvoton (Winbond logic dept.) ARM9 processor,You
-		can login www.mcuos.com or www.nuvoton.com to know more.
+	  Support for Nuvoton (Winbond logic dept.) ARM9 processor,
+	  At present, the w90x900 has been renamed nuc900, regarding
+	  the ARM series product line, you can login the following
+	  link address to know more.
+
+	  <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
+		ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
 
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
@@ -509,6 +544,7 @@ config ARCH_PXA
 	bool "PXA2xx/PXA3xx-based"
 	depends on MMU
 	select ARCH_MTD_XIP
+	select ARCH_HAS_CPUFREQ
 	select GENERIC_GPIO
 	select HAVE_CLK
 	select COMMON_CLKDEV
@@ -551,6 +587,7 @@ config ARCH_SA1100
 	select ISA
 	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_MTD_XIP
+	select ARCH_HAS_CPUFREQ
 	select GENERIC_GPIO
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
@@ -563,6 +600,7 @@ config ARCH_SA1100
 config ARCH_S3C2410
 	bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
 	select GENERIC_GPIO
+	select ARCH_HAS_CPUFREQ
 	select HAVE_CLK
 	help
 	  Samsung S3C2410X CPU based systems, such as the Simtec Electronics
@@ -573,9 +611,18 @@ config ARCH_S3C64XX
 	bool "Samsung S3C64XX"
 	select GENERIC_GPIO
 	select HAVE_CLK
+	select ARCH_HAS_CPUFREQ
 	help
 	  Samsung S3C64XX series based systems
 
+config ARCH_S5PC1XX
+	bool "Samsung S5PC1XX"
+	select GENERIC_GPIO
+	select HAVE_CLK
+	select CPU_V7
+	help
+	  Samsung S5PC1XX series based systems
+
 config ARCH_SHARK
 	bool "Shark"
 	select CPU_SA110
@@ -632,11 +679,24 @@ config ARCH_OMAP
 	select GENERIC_GPIO
 	select HAVE_CLK
 	select ARCH_REQUIRE_GPIOLIB
+	select ARCH_HAS_CPUFREQ
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	help
 	  Support for TI's OMAP platform (OMAP1 and OMAP2).
 
+config ARCH_BCMRING
+	bool "Broadcom BCMRING"
+	depends on MMU
+	select CPU_V6
+	select ARM_AMBA
+	select COMMON_CLKDEV
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+	select ARCH_WANT_OPTIONAL_GPIOLIB
+	help
+	  Support for Broadcom's BCMRing platform.
+
 endchoice
 
 source "arch/arm/mach-clps711x/Kconfig"
@@ -685,6 +745,7 @@ source "arch/arm/mach-kirkwood/Kconfig"
 source "arch/arm/plat-s3c24xx/Kconfig"
 source "arch/arm/plat-s3c64xx/Kconfig"
 source "arch/arm/plat-s3c/Kconfig"
+source "arch/arm/plat-s5pc1xx/Kconfig"
 
 if ARCH_S3C2410
 source "arch/arm/mach-s3c2400/Kconfig"
@@ -702,6 +763,10 @@ endif
 
 source "arch/arm/plat-stmp3xxx/Kconfig"
 
+if ARCH_S5PC1XX
+source "arch/arm/mach-s5pc100/Kconfig"
+endif
+
 source "arch/arm/mach-lh7a40x/Kconfig"
 
 source "arch/arm/mach-h720x/Kconfig"
@@ -716,6 +781,8 @@ source "arch/arm/mach-at91/Kconfig"
 
 source "arch/arm/plat-mxc/Kconfig"
 
+source "arch/arm/mach-nomadik/Kconfig"
+
 source "arch/arm/mach-netx/Kconfig"
 
 source "arch/arm/mach-ns9xxx/Kconfig"
@@ -730,6 +797,8 @@ source "arch/arm/mach-u300/Kconfig"
 
 source "arch/arm/mach-w90x900/Kconfig"
 
+source "arch/arm/mach-bcmring/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
@@ -962,18 +1031,7 @@ config LOCAL_TIMERS
 	  accounting to be spread across the timer interval, preventing a
 	  "thundering herd" at every timer tick.
 
-config PREEMPT
-	bool "Preemptible Kernel (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	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.
-	  This allows applications to run more reliably even when the system is
-	  under load.
-
-	  Say Y here if you are building a kernel for a desktop, embedded
-	  or real-time system.  Say N if you are unsure.
+source kernel/Kconfig.preempt
 
 config HZ
 	int
@@ -983,6 +1041,21 @@ config HZ
 	default AT91_TIMER_HZ if ARCH_AT91
 	default 100
 
+config THUMB2_KERNEL
+	bool "Compile the kernel in Thumb-2 mode"
+	depends on CPU_V7 && EXPERIMENTAL
+	select AEABI
+	select ARM_ASM_UNIFIED
+	help
+	  By enabling this option, the kernel will be compiled in
+	  Thumb-2 mode. A compiler/assembler that understand the unified
+	  ARM-Thumb syntax is needed.
+
+	  If unsure, say N.
+
+config ARM_ASM_UNIFIED
+	bool
+
 config AEABI
 	bool "Use the ARM EABI to compile the kernel"
 	help
@@ -1054,6 +1127,11 @@ config HIGHMEM
 
 	  If unsure, say n.
 
+config HIGHPTE
+	bool "Allocate 2nd-level pagetables from highmem"
+	depends on HIGHMEM
+	depends on !OUTER_CACHE
+
 source "mm/Kconfig"
 
 config LEDS
@@ -1241,7 +1319,7 @@ endmenu
 
 menu "CPU Power Management"
 
-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_PXA || ARCH_S3C64XX)
+if ARCH_HAS_CPUFREQ
 
 source "drivers/cpufreq/Kconfig"
 
@@ -1276,6 +1354,52 @@ config CPU_FREQ_S3C64XX
 	bool "CPUfreq support for Samsung S3C64XX CPUs"
 	depends on CPU_FREQ && CPU_S3C6410
 
+config CPU_FREQ_S3C
+	bool
+	help
+	  Internal configuration node for common cpufreq on Samsung SoC
+
+config CPU_FREQ_S3C24XX
+	bool "CPUfreq driver for Samsung S3C24XX series CPUs"
+	depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
+	select CPU_FREQ_S3C
+	help
+	  This enables the CPUfreq driver for the Samsung S3C24XX family
+	  of CPUs.
+
+	  For details, take a look at <file:Documentation/cpu-freq>.
+
+	  If in doubt, say N.
+
+config CPU_FREQ_S3C24XX_PLL
+	bool "Support CPUfreq changing of PLL frequency"
+	depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
+	help
+	  Compile in support for changing the PLL frequency from the
+	  S3C24XX series CPUfreq driver. The PLL takes time to settle
+	  after a frequency change, so by default it is not enabled.
+
+	  This also means that the PLL tables for the selected CPU(s) will
+	  be built which may increase the size of the kernel image.
+
+config CPU_FREQ_S3C24XX_DEBUG
+	bool "Debug CPUfreq Samsung driver core"
+	depends on CPU_FREQ_S3C24XX
+	help
+	  Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
+
+config CPU_FREQ_S3C24XX_IODEBUG
+	bool "Debug CPUfreq Samsung driver IO timing"
+	depends on CPU_FREQ_S3C24XX
+	help
+	  Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
+
+config CPU_FREQ_S3C24XX_DEBUGFS
+	bool "Export debugfs for CPUFreq"
+	depends on CPU_FREQ_S3C24XX && DEBUG_FS
+	help
+	  Export status information via debugfs.
+
 endif
 
 source "drivers/cpuidle/Kconfig"
@@ -1377,107 +1501,7 @@ endmenu
 
 source "net/Kconfig"
 
-menu "Device Drivers"
-
-source "drivers/base/Kconfig"
-
-source "drivers/connector/Kconfig"
-
-if ALIGNMENT_TRAP || !CPU_CP15_MMU
-source "drivers/mtd/Kconfig"
-endif
-
-source "drivers/parport/Kconfig"
-
-source "drivers/pnp/Kconfig"
-
-source "drivers/block/Kconfig"
-
-# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
-
-source "drivers/misc/Kconfig"
-
-source "drivers/ide/Kconfig"
-
-source "drivers/scsi/Kconfig"
-
-source "drivers/ata/Kconfig"
-
-source "drivers/md/Kconfig"
-
-source "drivers/message/fusion/Kconfig"
-
-source "drivers/ieee1394/Kconfig"
-
-source "drivers/message/i2o/Kconfig"
-
-source "drivers/net/Kconfig"
-
-source "drivers/isdn/Kconfig"
-
-# input before char - char/joystick depends on it. As does USB.
-
-source "drivers/input/Kconfig"
-
-source "drivers/char/Kconfig"
-
-source "drivers/i2c/Kconfig"
-
-source "drivers/spi/Kconfig"
-
-source "drivers/gpio/Kconfig"
-
-source "drivers/w1/Kconfig"
-
-source "drivers/power/Kconfig"
-
-source "drivers/hwmon/Kconfig"
-
-source "drivers/thermal/Kconfig"
-
-source "drivers/watchdog/Kconfig"
-
-source "drivers/ssb/Kconfig"
-
-#source "drivers/l3/Kconfig"
-
-source "drivers/mfd/Kconfig"
-
-source "drivers/media/Kconfig"
-
-source "drivers/video/Kconfig"
-
-source "sound/Kconfig"
-
-source "drivers/hid/Kconfig"
-
-source "drivers/usb/Kconfig"
-
-source "drivers/uwb/Kconfig"
-
-source "drivers/mmc/Kconfig"
-
-source "drivers/memstick/Kconfig"
-
-source "drivers/accessibility/Kconfig"
-
-source "drivers/leds/Kconfig"
-
-source "drivers/rtc/Kconfig"
-
-source "drivers/dma/Kconfig"
-
-source "drivers/dca/Kconfig"
-
-source "drivers/auxdisplay/Kconfig"
-
-source "drivers/regulator/Kconfig"
-
-source "drivers/uio/Kconfig"
-
-source "drivers/staging/Kconfig"
-
-endmenu
+source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index a89e473..1a6f70e 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -8,6 +8,7 @@ source "lib/Kconfig.debug"
 # n, but then RMK will have to kill you ;).
 config FRAME_POINTER
 	bool
+	depends on !THUMB2_KERNEL
 	default y if !ARM_UNWIND
 	help
 	  If you say N here, the resulting kernel will be slightly smaller and
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c877d6d..7350557 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -93,9 +93,16 @@ ifeq ($(CONFIG_ARM_UNWIND),y)
 CFLAGS_ABI	+=-funwind-tables
 endif
 
+ifeq ($(CONFIG_THUMB2_KERNEL),y)
+AFLAGS_AUTOIT	:=$(call as-option,-Wa$(comma)-mimplicit-it=thumb,-Wa$(comma)-mauto-it)
+AFLAGS_NOWARN	:=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
+CFLAGS_THUMB2	:=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
+AFLAGS_THUMB2	:=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
+endif
+
 # Need -Uarm for gcc < 3.x
-KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
-KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float
+KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
 
 CHECKFLAGS	+= -D__arm__
 
@@ -112,6 +119,7 @@ endif
 # by CONFIG_* macro name.
 machine-$(CONFIG_ARCH_AAEC2000)		:= aaec2000
 machine-$(CONFIG_ARCH_AT91)		:= at91
+machine-$(CONFIG_ARCH_BCMRING)		:= bcmring
 machine-$(CONFIG_ARCH_CLPS711X)		:= clps711x
 machine-$(CONFIG_ARCH_DAVINCI)		:= davinci
 machine-$(CONFIG_ARCH_EBSA110)		:= ebsa110
@@ -135,8 +143,10 @@ machine-$(CONFIG_ARCH_MSM)		:= msm
 machine-$(CONFIG_ARCH_MV78XX0)		:= mv78xx0
 machine-$(CONFIG_ARCH_MX1)		:= mx1
 machine-$(CONFIG_ARCH_MX2)		:= mx2
+machine-$(CONFIG_ARCH_MX25)		:= mx25
 machine-$(CONFIG_ARCH_MX3)		:= mx3
 machine-$(CONFIG_ARCH_NETX)		:= netx
+machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
 machine-$(CONFIG_ARCH_OMAP1)		:= omap1
 machine-$(CONFIG_ARCH_OMAP2)		:= omap2
@@ -150,6 +160,7 @@ machine-$(CONFIG_ARCH_RPC)		:= rpc
 machine-$(CONFIG_ARCH_S3C2410)		:= s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
 machine-$(CONFIG_ARCH_S3C24A0)		:= s3c24a0
 machine-$(CONFIG_ARCH_S3C64XX)		:= s3c6400 s3c6410
+machine-$(CONFIG_ARCH_S5PC1XX)		:= s5pc100
 machine-$(CONFIG_ARCH_SA1100)		:= sa1100
 machine-$(CONFIG_ARCH_SHARK)		:= shark
 machine-$(CONFIG_ARCH_STMP378X)		:= stmp378x
@@ -158,6 +169,7 @@ machine-$(CONFIG_ARCH_U300)		:= u300
 machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 machine-$(CONFIG_ARCH_W90X900)		:= w90x900
 machine-$(CONFIG_FOOTBRIDGE)		:= footbridge
+machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
 
 # Platform directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
@@ -168,6 +180,7 @@ plat-$(CONFIG_PLAT_ORION)	:= orion
 plat-$(CONFIG_PLAT_PXA)		:= pxa
 plat-$(CONFIG_PLAT_S3C24XX)	:= s3c24xx s3c
 plat-$(CONFIG_PLAT_S3C64XX)	:= s3c64xx s3c
+plat-$(CONFIG_PLAT_S5PC1XX)	:= s5pc1xx s3c
 plat-$(CONFIG_ARCH_STMP3XXX)	:= stmp3xxx
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index da226ab..4a590f4 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -61,7 +61,7 @@ endif
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
-		   -C none -a $(LOADADDR) -e $(LOADADDR) \
+		   -C none -a $(LOADADDR) -e $(STARTADDR) \
 		   -n 'Linux-$(KERNELRELEASE)' -d $< $@
 
 ifeq ($(CONFIG_ZBOOT_ROM),y)
@@ -70,6 +70,13 @@ else
 $(obj)/uImage: LOADADDR=$(ZRELADDR)
 endif
 
+ifeq ($(CONFIG_THUMB2_KERNEL),y)
+# Set bit 0 to 1 so that "mov pc, rx" switches to Thumb-2 mode
+$(obj)/uImage: STARTADDR=$(shell echo $(LOADADDR) | sed -e "s/.$$/1/")
+else
+$(obj)/uImage: STARTADDR=$(LOADADDR)
+endif
+
 $(obj)/uImage:	$(obj)/zImage FORCE
 	$(call if_changed,uimage)
 	@echo '  Image $@ is ready'
diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S
index 4c8c0e4..6179d94 100644
--- a/arch/arm/boot/compressed/head-sa1100.S
+++ b/arch/arm/boot/compressed/head-sa1100.S
@@ -1,7 +1,7 @@
 /* 
  * linux/arch/arm/boot/compressed/head-sa1100.S
  * 
- * Copyright (C) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 1999 Nicolas Pitre <nico@fluxnic.net>
  * 
  * SA1100 specific tweaks.  This is merged into head.S by the linker.
  *
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 4515728..fa6fbf4 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -140,7 +140,8 @@ start:
 		tst	r2, #3			@ not user?
 		bne	not_angel
 		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
-		swi	0x123456		@ angel_SWI_ARM
+ ARM(		swi	0x123456	)	@ angel_SWI_ARM
+ THUMB(		svc	0xab		)	@ angel_SWI_THUMB
 not_angel:
 		mrs	r2, cpsr		@ turn off interrupts to
 		orr	r2, r2, #0xc0		@ prevent angel from running
@@ -161,7 +162,9 @@ not_angel:
 
 		.text
 		adr	r0, LC0
-		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip, sp}
+ ARM(		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip, sp}	)
+ THUMB(		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip}	)
+ THUMB(		ldr	sp, [r0, #28]				)
 		subs	r0, r0, r1		@ calculate the delta offset
 
 						@ if delta is zero, we are
@@ -263,22 +266,25 @@ not_relocated:	mov	r0, #0
  * r6     = processor ID
  * r7     = architecture ID
  * r8     = atags pointer
- * r9-r14 = corrupted
+ * r9-r12,r14 = corrupted
  */
 		add	r1, r5, r0		@ end of decompressed kernel
 		adr	r2, reloc_start
 		ldr	r3, LC1
 		add	r3, r2, r3
-1:		ldmia	r2!, {r9 - r14}		@ copy relocation code
-		stmia	r1!, {r9 - r14}
-		ldmia	r2!, {r9 - r14}
-		stmia	r1!, {r9 - r14}
+1:		ldmia	r2!, {r9 - r12, r14}	@ copy relocation code
+		stmia	r1!, {r9 - r12, r14}
+		ldmia	r2!, {r9 - r12, r14}
+		stmia	r1!, {r9 - r12, r14}
 		cmp	r2, r3
 		blo	1b
-		add	sp, r1, #128		@ relocate the stack
+		mov	sp, r1
+		add	sp, sp, #128		@ relocate the stack
 
 		bl	cache_clean_flush
-		add	pc, r5, r0		@ call relocation code
+ ARM(		add	pc, r5, r0		) @ call relocation code
+ THUMB(		add	r12, r5, r0		)
+ THUMB(		mov	pc, r12			) @ call relocation code
 
 /*
  * We're not in danger of overwriting ourselves.  Do this the simple way.
@@ -291,6 +297,7 @@ wont_overwrite:	mov	r0, r4
 		bl	decompress_kernel
 		b	call_kernel
 
+		.align	2
 		.type	LC0, #object
 LC0:		.word	LC0			@ r1
 		.word	__bss_start		@ r2
@@ -431,6 +438,7 @@ ENDPROC(__setup_mmu)
 
 __armv4_mmu_cache_on:
 		mov	r12, lr
+#ifdef CONFIG_MMU
 		bl	__setup_mmu
 		mov	r0, #0
 		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
@@ -444,10 +452,12 @@ __armv4_mmu_cache_on:
 		bl	__common_mmu_cache_on
 		mov	r0, #0
 		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
+#endif
 		mov	pc, r12
 
 __armv7_mmu_cache_on:
 		mov	r12, lr
+#ifdef CONFIG_MMU
 		mrc	p15, 0, r11, c0, c1, 4	@ read ID_MMFR0
 		tst	r11, #0xf		@ VMSA
 		blne	__setup_mmu
@@ -455,9 +465,11 @@ __armv7_mmu_cache_on:
 		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
 		tst	r11, #0xf		@ VMSA
 		mcrne	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
+#endif
 		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
 		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
 		orr	r0, r0, #0x003c		@ write buffer
+#ifdef CONFIG_MMU
 #ifdef CONFIG_CPU_ENDIAN_BE8
 		orr	r0, r0, #1 << 25	@ big-endian page tables
 #endif
@@ -465,6 +477,7 @@ __armv7_mmu_cache_on:
 		movne	r1, #-1
 		mcrne	p15, 0, r3, c2, c0, 0	@ load page table pointer
 		mcrne	p15, 0, r1, c3, c0, 0	@ load domain access control
+#endif
 		mcr	p15, 0, r0, c1, c0, 0	@ load control register
 		mrc	p15, 0, r0, c1, c0, 0	@ and read it back
 		mov	r0, #0
@@ -498,6 +511,7 @@ __arm6_mmu_cache_on:
 		mov	pc, r12
 
 __common_mmu_cache_on:
+#ifndef CONFIG_THUMB2_KERNEL
 #ifndef DEBUG
 		orr	r0, r0, #0x000d		@ Write buffer, mmu
 #endif
@@ -509,6 +523,7 @@ __common_mmu_cache_on:
 1:		mcr	p15, 0, r0, c1, c0, 0	@ load control register
 		mrc	p15, 0, r0, c1, c0, 0	@ and read it back to
 		sub	pc, lr, r0, lsr #32	@ properly flush pipeline
+#endif
 
 /*
  * All code following this line is relocatable.  It is relocated by
@@ -522,7 +537,7 @@ __common_mmu_cache_on:
  * r6     = processor ID
  * r7     = architecture ID
  * r8     = atags pointer
- * r9-r14 = corrupted
+ * r9-r12,r14 = corrupted
  */
 		.align	5
 reloc_start:	add	r9, r5, r0
@@ -531,13 +546,14 @@ reloc_start:	add	r9, r5, r0
 		mov	r1, r4
 1:
 		.rept	4
-		ldmia	r5!, {r0, r2, r3, r10 - r14}	@ relocate kernel
-		stmia	r1!, {r0, r2, r3, r10 - r14}
+		ldmia	r5!, {r0, r2, r3, r10 - r12, r14}	@ relocate kernel
+		stmia	r1!, {r0, r2, r3, r10 - r12, r14}
 		.endr
 
 		cmp	r5, r9
 		blo	1b
-		add	sp, r1, #128		@ relocate the stack
+		mov	sp, r1
+		add	sp, sp, #128		@ relocate the stack
 		debug_reloc_end
 
 call_kernel:	bl	cache_clean_flush
@@ -571,7 +587,9 @@ call_cache_fn:	adr	r12, proc_types
 		ldr	r2, [r12, #4]		@ get mask
 		eor	r1, r1, r6		@ (real ^ match)
 		tst	r1, r2			@       & mask
-		addeq	pc, r12, r3		@ call cache function
+ ARM(		addeq	pc, r12, r3		) @ call cache function
+ THUMB(		addeq	r12, r3			)
+ THUMB(		moveq	pc, r12			) @ call cache function
 		add	r12, r12, #4*5
 		b	1b
 
@@ -589,13 +607,15 @@ call_cache_fn:	adr	r12, proc_types
  * methods.  Writeback caches _must_ have the flush method
  * defined.
  */
+		.align	2
 		.type	proc_types,#object
 proc_types:
 		.word	0x41560600		@ ARM6/610
 		.word	0xffffffe0
-		b	__arm6_mmu_cache_off	@ works, but slow
-		b	__arm6_mmu_cache_off
+		W(b)	__arm6_mmu_cache_off	@ works, but slow
+		W(b)	__arm6_mmu_cache_off
 		mov	pc, lr
+ THUMB(		nop				)
 @		b	__arm6_mmu_cache_on		@ untested
 @		b	__arm6_mmu_cache_off
 @		b	__armv3_mmu_cache_flush
@@ -603,76 +623,84 @@ proc_types:
 		.word	0x00000000		@ old ARM ID
 		.word	0x0000f000
 		mov	pc, lr
+ THUMB(		nop				)
 		mov	pc, lr
+ THUMB(		nop				)
 		mov	pc, lr
+ THUMB(		nop				)
 
 		.word	0x41007000		@ ARM7/710
 		.word	0xfff8fe00
-		b	__arm7_mmu_cache_off
-		b	__arm7_mmu_cache_off
+		W(b)	__arm7_mmu_cache_off
+		W(b)	__arm7_mmu_cache_off
 		mov	pc, lr
+ THUMB(		nop				)
 
 		.word	0x41807200		@ ARM720T (writethrough)
 		.word	0xffffff00
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
 		mov	pc, lr
+ THUMB(		nop				)
 
 		.word	0x41007400		@ ARM74x
 		.word	0xff00ff00
-		b	__armv3_mpu_cache_on
-		b	__armv3_mpu_cache_off
-		b	__armv3_mpu_cache_flush
+		W(b)	__armv3_mpu_cache_on
+		W(b)	__armv3_mpu_cache_off
+		W(b)	__armv3_mpu_cache_flush
 		
 		.word	0x41009400		@ ARM94x
 		.word	0xff00ff00
-		b	__armv4_mpu_cache_on
-		b	__armv4_mpu_cache_off
-		b	__armv4_mpu_cache_flush
+		W(b)	__armv4_mpu_cache_on
+		W(b)	__armv4_mpu_cache_off
+		W(b)	__armv4_mpu_cache_flush
 
 		.word	0x00007000		@ ARM7 IDs
 		.word	0x0000f000
 		mov	pc, lr
+ THUMB(		nop				)
 		mov	pc, lr
+ THUMB(		nop				)
 		mov	pc, lr
+ THUMB(		nop				)
 
 		@ Everything from here on will be the new ID system.
 
 		.word	0x4401a100		@ sa110 / sa1100
 		.word	0xffffffe0
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_flush
 
 		.word	0x6901b110		@ sa1110
 		.word	0xfffffff0
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_flush
 
 		.word	0x56056930
 		.word	0xff0ffff0		@ PXA935
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_flush
 
 		.word	0x56158000		@ PXA168
 		.word	0xfffff000
-		b __armv4_mmu_cache_on
-		b __armv4_mmu_cache_off
-		b __armv5tej_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv5tej_mmu_cache_flush
 
 		.word	0x56056930
 		.word	0xff0ffff0		@ PXA935
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_flush
 
 		.word	0x56050000		@ Feroceon
 		.word	0xff0f0000
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv5tej_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv5tej_mmu_cache_flush
 
 #ifdef CONFIG_CPU_FEROCEON_OLD_ID
 		/* this conflicts with the standard ARMv5TE entry */
@@ -685,47 +713,50 @@ proc_types:
 
 		.word	0x66015261		@ FA526
 		.word	0xff01fff1
-		b	__fa526_cache_on
-		b	__armv4_mmu_cache_off
-		b	__fa526_cache_flush
+		W(b)	__fa526_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__fa526_cache_flush
 
 		@ These match on the architecture ID
 
 		.word	0x00020000		@ ARMv4T
 		.word	0x000f0000
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_flush
 
 		.word	0x00050000		@ ARMv5TE
 		.word	0x000f0000
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv4_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_flush
 
 		.word	0x00060000		@ ARMv5TEJ
 		.word	0x000f0000
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv5tej_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv4_mmu_cache_flush
 
 		.word	0x0007b000		@ ARMv6
 		.word	0x000ff000
-		b	__armv4_mmu_cache_on
-		b	__armv4_mmu_cache_off
-		b	__armv6_mmu_cache_flush
+		W(b)	__armv4_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv6_mmu_cache_flush
 
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
-		b	__armv7_mmu_cache_on
-		b	__armv7_mmu_cache_off
-		b	__armv7_mmu_cache_flush
+		W(b)	__armv7_mmu_cache_on
+		W(b)	__armv7_mmu_cache_off
+		W(b)	__armv7_mmu_cache_flush
 
 		.word	0			@ unrecognised type
 		.word	0
 		mov	pc, lr
+ THUMB(		nop				)
 		mov	pc, lr
+ THUMB(		nop				)
 		mov	pc, lr
+ THUMB(		nop				)
 
 		.size	proc_types, . - proc_types
 
@@ -760,22 +791,30 @@ __armv3_mpu_cache_off:
 		mov	pc, lr
 
 __armv4_mmu_cache_off:
+#ifdef CONFIG_MMU
 		mrc	p15, 0, r0, c1, c0
 		bic	r0, r0, #0x000d
 		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
 		mov	r0, #0
 		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
 		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
+#endif
 		mov	pc, lr
 
 __armv7_mmu_cache_off:
 		mrc	p15, 0, r0, c1, c0
+#ifdef CONFIG_MMU
 		bic	r0, r0, #0x000d
+#else
+		bic	r0, r0, #0x000c
+#endif
 		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
 		mov	r12, lr
 		bl	__armv7_mmu_cache_flush
 		mov	r0, #0
+#ifdef CONFIG_MMU
 		mcr	p15, 0, r0, c8, c7, 0	@ invalidate whole TLB
+#endif
 		mcr	p15, 0, r0, c7, c5, 6	@ invalidate BTC
 		mcr	p15, 0, r0, c7, c10, 4	@ DSB
 		mcr	p15, 0, r0, c7, c5, 4	@ ISB
@@ -852,7 +891,7 @@ __armv7_mmu_cache_flush:
 		b	iflush
 hierarchical:
 		mcr	p15, 0, r10, c7, c10, 5	@ DMB
-		stmfd	sp!, {r0-r5, r7, r9, r11}
+		stmfd	sp!, {r0-r7, r9-r11}
 		mrc	p15, 1, r0, c0, c0, 1	@ read clidr
 		ands	r3, r0, #0x7000000	@ extract loc from clidr
 		mov	r3, r3, lsr #23		@ left align loc bit field
@@ -877,8 +916,12 @@ loop1:
 loop2:
 		mov	r9, r4			@ create working copy of max way size
 loop3:
-		orr	r11, r10, r9, lsl r5	@ factor way and cache number into r11
-		orr	r11, r11, r7, lsl r2	@ factor index number into r11
+ ARM(		orr	r11, r10, r9, lsl r5	) @ factor way and cache number into r11
+ ARM(		orr	r11, r11, r7, lsl r2	) @ factor index number into r11
+ THUMB(		lsl	r6, r9, r5		)
+ THUMB(		orr	r11, r10, r6		) @ factor way and cache number into r11
+ THUMB(		lsl	r6, r7, r2		)
+ THUMB(		orr	r11, r11, r6		) @ factor index number into r11
 		mcr	p15, 0, r11, c7, c14, 2	@ clean & invalidate by set/way
 		subs	r9, r9, #1		@ decrement the way
 		bge	loop3
@@ -889,7 +932,7 @@ skip:
 		cmp	r3, r10
 		bgt	loop1
 finished:
-		ldmfd	sp!, {r0-r5, r7, r9, r11}
+		ldmfd	sp!, {r0-r7, r9-r11}
 		mov	r10, #0			@ swith back to cache level 0
 		mcr	p15, 2, r10, c0, c0, 0	@ select current cache level in cssr
 iflush:
@@ -923,9 +966,13 @@ __armv4_mmu_cache_flush:
 		mov	r11, #8
 		mov	r11, r11, lsl r3	@ cache line size in bytes
 no_cache_id:
-		bic	r1, pc, #63		@ align to longest cache line
+		mov	r1, pc
+		bic	r1, r1, #63		@ align to longest cache line
 		add	r2, r1, r2
-1:		ldr	r3, [r1], r11		@ s/w flush D cache
+1:
+ ARM(		ldr	r3, [r1], r11		) @ s/w flush D cache
+ THUMB(		ldr     r3, [r1]		) @ s/w flush D cache
+ THUMB(		add     r1, r1, r11		)
 		teq	r1, r2
 		bne	1b
 
@@ -945,6 +992,7 @@ __armv3_mpu_cache_flush:
  * memory, which again must be relocatable.
  */
 #ifdef DEBUG
+		.align	2
 		.type	phexbuf,#object
 phexbuf:	.space	12
 		.size	phexbuf, . - phexbuf
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 6ed8983..920ced0 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -22,10 +22,20 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/sysdev.h>
+#include <linux/amba/bus.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware/vic.h>
 
+static void vic_ack_irq(unsigned int irq)
+{
+	void __iomem *base = get_irq_chip_data(irq);
+	irq &= 31;
+	writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+	/* moreover, clear the soft-triggered, in case it was the reason */
+	writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
+}
+
 static void vic_mask_irq(unsigned int irq)
 {
 	void __iomem *base = get_irq_chip_data(irq);
@@ -253,12 +263,16 @@ static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg
 
 static struct irq_chip vic_chip = {
 	.name	= "VIC",
-	.ack	= vic_mask_irq,
+	.ack	= vic_ack_irq,
 	.mask	= vic_mask_irq,
 	.unmask	= vic_unmask_irq,
 	.set_wake = vic_set_wake,
 };
 
+/* The PL190 cell from ARM has been modified by ST, so handle both here */
+static void vik_init_st(void __iomem *base, unsigned int irq_start,
+			 u32 vic_sources);
+
 /**
  * vic_init - initialise a vectored interrupt controller
  * @base: iomem base address
@@ -270,6 +284,28 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
 		     u32 vic_sources, u32 resume_sources)
 {
 	unsigned int i;
+	u32 cellid = 0;
+	enum amba_vendor vendor;
+
+	/* Identify which VIC cell this one is, by reading the ID */
+	for (i = 0; i < 4; i++) {
+		u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
+		cellid |= (readl(addr) & 0xff) << (8 * i);
+	}
+	vendor = (cellid >> 12) & 0xff;
+	printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n",
+	       base, cellid, vendor);
+
+	switch(vendor) {
+	case AMBA_VENDOR_ST:
+		vik_init_st(base, irq_start, vic_sources);
+		return;
+	default:
+		printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
+		/* fall through */
+	case AMBA_VENDOR_ARM:
+		break;
+	}
 
 	/* Disable all interrupts initially. */
 
@@ -306,3 +342,60 @@ void __init vic_init(void __iomem *base, unsigned int irq_start,
 
 	vic_pm_register(base, irq_start, resume_sources);
 }
+
+/*
+ * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
+ * The original cell has 32 interrupts, while the modified one has 64,
+ * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
+ * the probe function is called twice, with base set to offset 000
+ *  and 020 within the page. We call this "second block".
+ */
+static void __init vik_init_st(void __iomem *base, unsigned int irq_start,
+				u32 vic_sources)
+{
+	unsigned int i;
+	int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
+
+	/* Disable all interrupts initially. */
+
+	writel(0, base + VIC_INT_SELECT);
+	writel(0, base + VIC_INT_ENABLE);
+	writel(~0, base + VIC_INT_ENABLE_CLEAR);
+	writel(0, base + VIC_IRQ_STATUS);
+	writel(0, base + VIC_ITCR);
+	writel(~0, base + VIC_INT_SOFT_CLEAR);
+
+	/*
+	 * Make sure we clear all existing interrupts. The vector registers
+	 * in this cell are after the second block of general registers,
+	 * so we can address them using standard offsets, but only from
+	 * the second base address, which is 0x20 in the page
+	 */
+	if (vic_2nd_block) {
+		writel(0, base + VIC_PL190_VECT_ADDR);
+		for (i = 0; i < 19; i++) {
+			unsigned int value;
+
+			value = readl(base + VIC_PL190_VECT_ADDR);
+			writel(value, base + VIC_PL190_VECT_ADDR);
+		}
+		/* ST has 16 vectors as well, but we don't enable them by now */
+		for (i = 0; i < 16; i++) {
+			void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+			writel(0, reg);
+		}
+
+		writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+	}
+
+	for (i = 0; i < 32; i++) {
+		if (vic_sources & (1 << i)) {
+			unsigned int irq = irq_start + i;
+
+			set_irq_chip(irq, &vic_chip);
+			set_irq_chip_data(irq, base);
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		}
+	}
+}
diff --git a/arch/arm/configs/bcmring_defconfig b/arch/arm/configs/bcmring_defconfig
new file mode 100644
index 0000000..bcc0bac
--- /dev/null
+++ b/arch/arm/configs/bcmring_defconfig
@@ -0,0 +1,725 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc3
+# Fri Jul 17 12:07:28 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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 is not set
+# CONFIG_SWAP is not set
+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=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_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 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+CONFIG_SHMEM=y
+# CONFIG_AIO is not set
+
+#
+# Performance Counters
+#
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# 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 is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_ARCH_BCMRING=y
+# CONFIG_ARCH_FPGA11107 is not set
+CONFIG_ARCH_BCM11107=y
+
+#
+# BCMRING Options
+#
+CONFIG_BCM_ZRELADDR=0x8000
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+CONFIG_UACCESS_WITH_MEMCPY=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0e000000
+CONFIG_ZBOOT_ROM_BSS=0x0ea00000
+CONFIG_ZBOOT_ROM=y
+CONFIG_CMDLINE=""
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_UNIX is not set
+# CONFIG_NET_KEY is not set
+# CONFIG_INET is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER 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_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 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_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_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=y
+# CONFIG_MTD_AFS_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 is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+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 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# 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 is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_BCM_UMI=y
+CONFIG_MTD_NAND_BCM_UMI_HWCS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# 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
+# 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 is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH 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
+
+#
+# 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 is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# 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 is not set
+# 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_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=64
+# 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 is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB 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 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_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR 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=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_FILE_LOCKING is not set
+# CONFIG_FSNOTIFY 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
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_PROC_PAGE_MONITOR is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+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 is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+# CONFIG_JFFS2_FS_SECURITY 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 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
+# 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_NILFS2_FS 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
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_BUILD_DOCSRC is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER 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
+# CONFIG_BINARY_PRINTF 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/cpu9260_defconfig b/arch/arm/configs/cpu9260_defconfig
new file mode 100644
index 0000000..601e7f3
--- /dev/null
+++ b/arch/arm/configs/cpu9260_defconfig
@@ -0,0 +1,1338 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc3
+# Tue Jul 14 14:57:55 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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 is not set
+# CONFIG_SWAP is not set
+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=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 is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# 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 is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# 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=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+CONFIG_ARCH_AT91SAM9260=y
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91SAM9G20 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9260 Variants
+#
+# CONFIG_ARCH_AT91SAM9260_SAM9XE is not set
+
+#
+# AT91SAM9260 / AT91SAM9XE Board Type
+#
+# CONFIG_MACH_AT91SAM9260EK is not set
+# CONFIG_MACH_CAM60 is not set
+# CONFIG_MACH_SAM9_L9260 is not set
+# CONFIG_MACH_AFEB9260 is not set
+# CONFIG_MACH_USB_A9260 is not set
+# CONFIG_MACH_QIL_A9260 is not set
+CONFIG_MACH_CPU9260=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+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=y
+# CONFIG_IP_PNP_DHCP is not set
+# 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_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=y
+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_PHONET is not set
+# CONFIG_IEEE802154 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_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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# 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_AFS_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 is not set
+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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# 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_ARM_INTEGRATOR is not set
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_HW=y
+# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# 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
+# 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=y
+# CONFIG_BLK_DEV_UB 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_MG_DISK 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=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
+CONFIG_SCSI_MULTI_LUN=y
+# 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_SCSI_OSD_INITIATOR 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=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_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 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
+# 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_KS8842 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
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN 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=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# 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=y
+CONFIG_LEGACY_PTY_COUNT=32
+# 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_DESIGNWARE is not set
+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
+# CONFIG_I2C_TINY_USB 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 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_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=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91SAM9X_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG 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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB 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_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# 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
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# 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_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# 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_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# 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_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+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_AT91=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+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=y
+# 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 is not set
+# 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
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_AT91SAM9 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# 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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# 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_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 is not set
+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 is not set
+CONFIG_JFFS2_SUMMARY=y
+# 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=y
+# 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_NILFS2_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_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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+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 is not set
+# 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=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER 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
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/cpu9g20_defconfig b/arch/arm/configs/cpu9g20_defconfig
new file mode 100644
index 0000000..b5b9cbb
--- /dev/null
+++ b/arch/arm/configs/cpu9g20_defconfig
@@ -0,0 +1,1328 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc3
+# Tue Jul 14 15:03:43 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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 is not set
+# CONFIG_SWAP is not set
+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=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 is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# 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 is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# 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=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Atmel AT91 System-on-Chip
+#
+# CONFIG_ARCH_AT91RM9200 is not set
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+CONFIG_ARCH_AT91SAM9G20=y
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91SAM9G20 Board Type
+#
+# CONFIG_MACH_AT91SAM9G20EK is not set
+CONFIG_MACH_CPU9G20=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+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=y
+# CONFIG_IP_PNP_DHCP is not set
+# 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_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=y
+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_PHONET is not set
+# CONFIG_IEEE802154 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_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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# 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_AFS_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 is not set
+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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# 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_ARM_INTEGRATOR is not set
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# 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
+# 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=y
+# CONFIG_BLK_DEV_UB 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_MG_DISK 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=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
+CONFIG_SCSI_MULTI_LUN=y
+# 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_SCSI_OSD_INITIATOR 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=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_MACB=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 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
+# 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_KS8842 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
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN 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=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# 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=y
+CONFIG_LEGACY_PTY_COUNT=32
+# 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_DESIGNWARE is not set
+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
+# CONFIG_I2C_TINY_USB 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 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_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=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91SAM9X_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG 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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB 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_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# 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
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# 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_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# 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_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# 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_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+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_AT91=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+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=y
+# 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 is not set
+# 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
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_AT91SAM9 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# 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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# 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_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 is not set
+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 is not set
+CONFIG_JFFS2_SUMMARY=y
+# 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=y
+# 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_NILFS2_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_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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+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 is not set
+# 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=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER 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
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/cpuat91_defconfig b/arch/arm/configs/cpuat91_defconfig
new file mode 100644
index 0000000..4901827
--- /dev/null
+++ b/arch/arm/configs/cpuat91_defconfig
@@ -0,0 +1,1316 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc3
+# Tue Jul 14 14:45:01 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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 is not set
+# CONFIG_SWAP is not set
+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=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 is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# 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 is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# 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=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+CONFIG_ARCH_AT91=y
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Atmel AT91 System-on-Chip
+#
+CONFIG_ARCH_AT91RM9200=y
+# CONFIG_ARCH_AT91SAM9260 is not set
+# CONFIG_ARCH_AT91SAM9261 is not set
+# CONFIG_ARCH_AT91SAM9263 is not set
+# CONFIG_ARCH_AT91SAM9RL is not set
+# CONFIG_ARCH_AT91SAM9G20 is not set
+# CONFIG_ARCH_AT91CAP9 is not set
+# CONFIG_ARCH_AT91X40 is not set
+CONFIG_AT91_PMC_UNIT=y
+
+#
+# AT91RM9200 Board Type
+#
+# CONFIG_MACH_ONEARM is not set
+# CONFIG_ARCH_AT91RM9200DK is not set
+# CONFIG_MACH_AT91RM9200EK is not set
+# CONFIG_MACH_CSB337 is not set
+# CONFIG_MACH_CSB637 is not set
+# CONFIG_MACH_CARMEVA is not set
+# CONFIG_MACH_ATEB9200 is not set
+# CONFIG_MACH_KB9200 is not set
+# CONFIG_MACH_PICOTUX2XX is not set
+# CONFIG_MACH_KAFA is not set
+# CONFIG_MACH_ECBAT91 is not set
+# CONFIG_MACH_YL9200 is not set
+CONFIG_MACH_CPUAT91=y
+
+#
+# AT91 Board Options
+#
+
+#
+# AT91 Feature Selections
+#
+# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
+CONFIG_AT91_TIMER_HZ=100
+CONFIG_AT91_EARLY_DBGU=y
+# CONFIG_AT91_EARLY_USART0 is not set
+# CONFIG_AT91_EARLY_USART1 is not set
+# CONFIG_AT91_EARLY_USART2 is not set
+# CONFIG_AT91_EARLY_USART3 is not set
+# CONFIG_AT91_EARLY_USART4 is not set
+# CONFIG_AT91_EARLY_USART5 is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM920T=y
+CONFIG_CPU_32v4T=y
+CONFIG_CPU_ABRT_EV4T=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V4WT=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+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=y
+# CONFIG_IP_PNP_DHCP is not set
+# 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_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=y
+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_PHONET is not set
+# CONFIG_IEEE802154 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_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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# 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_AFS_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 is not set
+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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# 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_ARM_INTEGRATOR is not set
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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
+
+#
+# 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=y
+# CONFIG_BLK_DEV_UB 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_MG_DISK 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=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
+CONFIG_SCSI_MULTI_LUN=y
+# 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_SCSI_OSD_INITIATOR 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=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 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
+# 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_KS8842 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
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=y
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=y
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN 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=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# 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=y
+CONFIG_LEGACY_PTY_COUNT=32
+# 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_DESIGNWARE is not set
+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
+# CONFIG_I2C_TINY_USB 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 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_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=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT91RM9200_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG 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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB 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_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# 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
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# 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_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+CONFIG_USB_GADGET_AT91=y
+CONFIG_USB_AT91=y
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# 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_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# 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_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+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_AT91=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+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=y
+# 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
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_AT91RM9200 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# 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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# 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_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 is not set
+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 is not set
+CONFIG_JFFS2_SUMMARY=y
+# 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=y
+# 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_NILFS2_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_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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+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 is not set
+# 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=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_DEBUG_USER 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
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/da830_omapl137_defconfig b/arch/arm/configs/da830_omapl137_defconfig
new file mode 100644
index 0000000..7c8e38f
--- /dev/null
+++ b/arch/arm/configs/da830_omapl137_defconfig
@@ -0,0 +1,1254 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc2-davinci1
+# Wed May 13 15:33:29 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_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_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+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_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# 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=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_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA 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 is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=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_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD 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=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+CONFIG_ARCH_DAVINCI=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+CONFIG_CP_INTC=y
+
+#
+# TI DaVinci Implementations
+#
+
+#
+# DaVinci Core Type
+#
+# CONFIG_ARCH_DAVINCI_DM644x is not set
+# CONFIG_ARCH_DAVINCI_DM646x is not set
+# CONFIG_ARCH_DAVINCI_DM355 is not set
+CONFIG_ARCH_DAVINCI_DA830=y
+
+#
+# DaVinci Board Type
+#
+CONFIG_MACH_DAVINCI_DA830_EVM=y
+CONFIG_DAVINCI_MUX=y
+# CONFIG_DAVINCI_MUX_DEBUG is not set
+# CONFIG_DAVINCI_MUX_WARNINGS is not set
+CONFIG_DAVINCI_RESET_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+CONFIG_CPU_DCACHE_WRITETHROUGH=y
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_LEDS=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# 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=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_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=m
+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=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES 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_PHONET 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_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=y
+# CONFIG_FW_LOADER is not set
+# 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=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# 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=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+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=m
+# 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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE 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
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# 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=y
+# 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=y
+# 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_TI_DAVINCI_EMAC=y
+# CONFIG_DM9000 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
+# 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
+
+#
+# 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=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN 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=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_XTKBD=m
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# 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 is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+# 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=y
+CONFIG_LEGACY_PTY_COUNT=256
+# 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
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_DAVINCI=y
+# CONFIG_I2C_GPIO is not set
+# 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_SENSORS_PCA9539 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 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:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+CONFIG_GPIO_PCF857X=m
+
+#
+# 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=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DAVINCI_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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB 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
+
+#
+# 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SOC=m
+CONFIG_SND_DAVINCI_SOC=m
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# 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 is not set
+# 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
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# 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
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# 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_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 is not set
+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_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+# 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_NILFS2_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=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+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 is not set
+# 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=m
+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=m
+# 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=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# 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_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL 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_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
+# CONFIG_CRYPTO_AUTHENC is not set
+# 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 is not set
+# 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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 is not set
+# 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 is not set
+# 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 is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
+# 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_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/da850_omapl138_defconfig b/arch/arm/configs/da850_omapl138_defconfig
new file mode 100644
index 0000000..842a70b
--- /dev/null
+++ b/arch/arm/configs/da850_omapl138_defconfig
@@ -0,0 +1,1229 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-davinci1
+# Mon Jun 29 07:54:15 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_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_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+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_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# 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=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_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA 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 is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=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_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD 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=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+CONFIG_ARCH_DAVINCI=y
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
+CONFIG_CP_INTC=y
+
+#
+# TI DaVinci Implementations
+#
+
+#
+# DaVinci Core Type
+#
+# CONFIG_ARCH_DAVINCI_DM644x is not set
+# CONFIG_ARCH_DAVINCI_DM355 is not set
+# CONFIG_ARCH_DAVINCI_DM646x is not set
+# CONFIG_ARCH_DAVINCI_DA830 is not set
+CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_ARCH_DAVINCI_DA8XX=y
+# CONFIG_ARCH_DAVINCI_DM365 is not set
+
+#
+# DaVinci Board Type
+#
+CONFIG_MACH_DAVINCI_DA850_EVM=y
+CONFIG_DAVINCI_MUX=y
+# CONFIG_DAVINCI_MUX_DEBUG is not set
+# CONFIG_DAVINCI_MUX_WARNINGS is not set
+CONFIG_DAVINCI_RESET_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_LEDS=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# 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=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_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=m
+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=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES 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_PHONET 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_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=y
+# CONFIG_FW_LOADER is not set
+# 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=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# 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=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+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=m
+# 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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE 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
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# 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=y
+# 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=y
+# 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_TI_DAVINCI_EMAC is not set
+# CONFIG_DM9000 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
+# 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
+
+#
+# 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=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN 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=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_XTKBD=m
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# 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 is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+# 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=y
+CONFIG_LEGACY_PTY_COUNT=256
+# 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
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_DAVINCI=y
+# CONFIG_I2C_GPIO is not set
+# 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_SENSORS_PCA9539 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 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:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+CONFIG_GPIO_PCF857X=m
+
+#
+# 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=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_DAVINCI_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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB 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
+
+#
+# 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SOC=m
+CONFIG_SND_DAVINCI_SOC=m
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# 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
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# 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_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 is not set
+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_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+# 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_NILFS2_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=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+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 is not set
+# 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=m
+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=m
+# 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=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# 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_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL 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_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
+# CONFIG_CRYPTO_AUTHENC is not set
+# 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 is not set
+# 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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 is not set
+# 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 is not set
+# 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 is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
+# 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_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index ac18662..ddffe39 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc7
-# Tue May 26 07:24:28 2009
+# Linux kernel version: 2.6.31-rc3-davinci1
+# Fri Jul 17 08:26:52 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,14 +17,13 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# 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_ZONE_DMA=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -62,8 +60,7 @@ CONFIG_FAIR_GROUP_SCHED=y
 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_SYSFS_DEPRECATED_V2 is not set
 # CONFIG_RELAY is not set
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
@@ -80,7 +77,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -93,8 +89,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Performance Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
@@ -106,6 +107,11 @@ CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
@@ -118,7 +124,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -145,13 +151,14 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -160,26 +167,27 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
 # CONFIG_ARCH_S3C64XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 CONFIG_ARCH_DAVINCI=y
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_W90X900 is not set
 CONFIG_AINTC=y
+CONFIG_ARCH_DAVINCI_DMx=y
 
 #
 # TI DaVinci Implementations
@@ -191,6 +199,9 @@ CONFIG_AINTC=y
 CONFIG_ARCH_DAVINCI_DM644x=y
 CONFIG_ARCH_DAVINCI_DM355=y
 CONFIG_ARCH_DAVINCI_DM646x=y
+# CONFIG_ARCH_DAVINCI_DA830 is not set
+# CONFIG_ARCH_DAVINCI_DA850 is not set
+CONFIG_ARCH_DAVINCI_DM365=y
 
 #
 # DaVinci Board Type
@@ -200,6 +211,7 @@ CONFIG_MACH_SFFSDR=y
 CONFIG_MACH_DAVINCI_DM355_EVM=y
 CONFIG_MACH_DM355_LEOPARD=y
 CONFIG_MACH_DAVINCI_DM6467_EVM=y
+CONFIG_MACH_DAVINCI_DM365_EVM=y
 CONFIG_DAVINCI_MUX=y
 CONFIG_DAVINCI_MUX_DEBUG=y
 CONFIG_DAVINCI_MUX_WARNINGS=y
@@ -227,7 +239,6 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_DCACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_WRITETHROUGH is not set
 # CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
 CONFIG_COMMON_CLKDEV=y
 
 #
@@ -252,7 +263,6 @@ CONFIG_PREEMPT=y
 CONFIG_HZ=100
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
-# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_HIGHMEM is not set
@@ -268,12 +278,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_LEDS=y
 # CONFIG_LEDS_CPU is not set
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
@@ -415,6 +426,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -553,6 +565,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -564,6 +577,7 @@ CONFIG_MISC_DEVICES=y
 #
 CONFIG_EEPROM_AT24=y
 # CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
 # CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=m
@@ -609,10 +623,6 @@ CONFIG_BLK_DEV_SD=m
 # 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
@@ -637,7 +647,6 @@ CONFIG_SCSI_LOWLEVEL=y
 # 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
@@ -684,6 +693,7 @@ CONFIG_DM9000_DEBUGLEVEL=4
 # 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_KS8842 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -748,18 +758,21 @@ CONFIG_INPUT_EVBUG=m
 #
 CONFIG_INPUT_KEYBOARD=y
 CONFIG_KEYBOARD_ATKBD=m
-# CONFIG_KEYBOARD_SUNKBD is not set
 # CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_XTKBD=m
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_XTKBD=m
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 # CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
 # CONFIG_TOUCHSCREEN_FUJITSU is not set
 # CONFIG_TOUCHSCREEN_GUNZE is not set
 # CONFIG_TOUCHSCREEN_ELO is not set
@@ -773,6 +786,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
 # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 # CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -832,6 +846,7 @@ CONFIG_I2C_HELPER_AUTO=y
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
 CONFIG_I2C_DAVINCI=y
+# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_GPIO is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
@@ -854,7 +869,6 @@ CONFIG_I2C_DAVINCI=y
 #
 # CONFIG_DS1682 is not set
 # CONFIG_SENSORS_PCA9539 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
@@ -935,6 +949,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
@@ -986,52 +1001,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_V4L2_COMMON=y
-CONFIG_VIDEO_ALLOW_V4L1=y
-CONFIG_VIDEO_V4L1_COMPAT=y
-# CONFIG_DVB_CORE is not set
-CONFIG_VIDEO_MEDIA=y
-
-#
-# Multimedia drivers
-#
-# CONFIG_MEDIA_ATTACH is not set
-CONFIG_MEDIA_TUNER=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-CONFIG_MEDIA_TUNER_SIMPLE=y
-CONFIG_MEDIA_TUNER_TDA8290=y
-CONFIG_MEDIA_TUNER_TDA9887=y
-CONFIG_MEDIA_TUNER_TEA5761=y
-CONFIG_MEDIA_TUNER_TEA5767=y
-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
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_CPIA2 is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_SOC_CAMERA is not set
-# CONFIG_V4L_USB_DRIVERS is not set
-# CONFIG_RADIO_ADAPTERS is not set
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -1102,6 +1073,11 @@ CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
 CONFIG_SND_DRIVERS=y
 # CONFIG_SND_DUMMY is not set
 # CONFIG_SND_MTPAV is not set
@@ -1112,9 +1088,16 @@ CONFIG_SND_USB=y
 # CONFIG_SND_USB_AUDIO is not set
 # CONFIG_SND_USB_CAIAQ is not set
 CONFIG_SND_SOC=m
-# CONFIG_SND_DAVINCI_SOC is not set
+CONFIG_SND_DAVINCI_SOC=m
+CONFIG_SND_DAVINCI_SOC_I2S=m
+CONFIG_SND_DAVINCI_SOC_MCASP=m
+CONFIG_SND_DAVINCI_SOC_EVM=m
+CONFIG_SND_DM6467_SOC_EVM=m
+# CONFIG_SND_DAVINCI_SOC_SFFSDR is not set
 CONFIG_SND_SOC_I2C_AND_SPI=m
 # CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_SPDIF=m
+CONFIG_SND_SOC_TLV320AIC3X=m
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -1143,7 +1126,7 @@ CONFIG_HID_BELKIN=m
 CONFIG_HID_CHERRY=m
 CONFIG_HID_CHICONY=m
 CONFIG_HID_CYPRESS=m
-# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_DRAGONRISE is not set
 CONFIG_HID_EZKEY=m
 # CONFIG_HID_KYE is not set
 CONFIG_HID_GYRATION=m
@@ -1160,10 +1143,11 @@ CONFIG_HID_PETALYNX=m
 CONFIG_HID_SAMSUNG=m
 CONFIG_HID_SONY=m
 CONFIG_HID_SUNPLUS=m
-# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
 # CONFIG_HID_TOPSEED is not set
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
@@ -1266,6 +1250,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_IDMOUSE is not set
 # CONFIG_USB_FTDI_ELAN is not set
 # CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
@@ -1285,17 +1270,20 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_OMAP is not set
 # CONFIG_USB_GADGET_PXA25X is not set
 # CONFIG_USB_GADGET_PXA27X is not set
-# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
 # CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
 # CONFIG_USB_GADGET_M66592 is not set
 # 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_LANGWELL is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
 CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
 CONFIG_USB_ETH=m
 CONFIG_USB_ETH_RNDIS=y
 CONFIG_USB_GADGETFS=m
@@ -1311,7 +1299,7 @@ CONFIG_USB_CDC_COMPOSITE=m
 #
 CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_NOP_USB_XCEIV=m
 CONFIG_MMC=m
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -1328,7 +1316,6 @@ CONFIG_MMC_BLOCK=m
 # MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_DAVINCI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_NEW_LEDS=y
@@ -1340,7 +1327,7 @@ CONFIG_LEDS_CLASS=m
 # CONFIG_LEDS_PCA9532 is not set
 CONFIG_LEDS_GPIO=m
 CONFIG_LEDS_GPIO_PLATFORM=y
-# CONFIG_LEDS_LP5521 is not set
+# CONFIG_LEDS_LP3944 is not set
 # CONFIG_LEDS_PCA955X is not set
 # CONFIG_LEDS_BD2802 is not set
 
@@ -1386,6 +1373,7 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_S35390A is not set
 # CONFIG_RTC_DRV_FM3130 is not set
 # CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
 
 #
 # SPI RTC drivers
@@ -1433,14 +1421,16 @@ CONFIG_FS_MBCACHE=y
 # 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=m
 # CONFIG_XFS_QUOTA is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -1623,6 +1613,7 @@ CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 CONFIG_DEBUG_PREEMPT=y
 CONFIG_DEBUG_RT_MUTEXES=y
 CONFIG_DEBUG_PI_LIST=y
@@ -1654,18 +1645,16 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_PAGE_POISONING is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_PREEMPT_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
index f3074e4..df9bfbe 100644
--- a/arch/arm/configs/jornada720_defconfig
+++ b/arch/arm/configs/jornada720_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc6
-# Tue Sep 16 18:56:58 2008
+# Linux kernel version: 2.6.31-rc6
+# Fri Aug 21 15:41:39 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
@@ -18,16 +17,14 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_HARDIRQS_SW_RESEND=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# 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_ARCH_SUPPORTS_AOUT=y
 CONFIG_ZONE_DMA=y
 CONFIG_ARCH_MTD_XIP=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -44,10 +41,19 @@ CONFIG_SYSVIPC_SYSCTL=y
 # 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
@@ -56,9 +62,11 @@ CONFIG_NAMESPACES=y
 # CONFIG_IPC_NS is not set
 # 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 is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
@@ -69,17 +77,22 @@ 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_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -87,30 +100,25 @@ CONFIG_SLUB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
 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
 # CONFIG_MODULE_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_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -126,7 +134,7 @@ CONFIG_IOSCHED_CFQ=y
 CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type
@@ -136,14 +144,15 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
 # CONFIG_ARCH_IOP33X is not set
@@ -152,23 +161,25 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
 # CONFIG_ARCH_LOKI is not set
 # CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
 # CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
 # CONFIG_ARCH_RPC is not set
 CONFIG_ARCH_SA1100=y
 # CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
 # CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM7X00A is not set
-CONFIG_DMABOUNCE=y
 
 #
 # SA11x0 Implementations
@@ -189,14 +200,6 @@ CONFIG_SA1100_JORNADA720_SSP=y
 CONFIG_SA1100_SSP=y
 
 #
-# Boot options
-#
-
-#
-# Power management
-#
-
-#
 # Processor Type
 #
 CONFIG_CPU_32=y
@@ -215,8 +218,8 @@ CONFIG_CPU_CP15_MMU=y
 #
 # CONFIG_CPU_ICACHE_DISABLE is not set
 # CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_OUTER_CACHE is not set
 CONFIG_SA1111=y
+CONFIG_DMABOUNCE=y
 CONFIG_FORCE_MAX_ZONEORDER=9
 
 #
@@ -246,30 +249,36 @@ CONFIG_TICK_ONESHOT=y
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=100
 # CONFIG_AEABI is not set
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_NODES_SHIFT=2
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM_MANUAL=y
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_NEED_MULTIPLE_NODES=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
 
 #
 # Boot options
@@ -281,9 +290,10 @@ CONFIG_CMDLINE=""
 # CONFIG_KEXEC is not set
 
 #
-# CPU Frequency scaling
+# CPU Power Management
 #
 # CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -294,12 +304,14 @@ CONFIG_CMDLINE=""
 #
 CONFIG_FPE_NWFPE=y
 # CONFIG_FPE_NWFPE_XP is not set
-CONFIG_FPE_FASTFPE=y
+# CONFIG_FPE_FASTFPE is not set
 
 #
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
 CONFIG_BINFMT_AOUT=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_ARTHUR is not set
@@ -353,7 +365,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
@@ -367,10 +378,12 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_NETFILTER_NETLINK_LOG is not set
 # CONFIG_NF_CONNTRACK is not set
 # CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+# CONFIG_NF_DEFRAG_IPV4 is not set
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
 # CONFIG_IP_NF_ARPTABLES is not set
@@ -379,6 +392,7 @@ CONFIG_NETFILTER_ADVANCED=y
 # 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
@@ -388,7 +402,10 @@ CONFIG_NETFILTER_ADVANCED=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
@@ -431,14 +448,17 @@ CONFIG_IRCOMM=m
 CONFIG_SA1100_FIR=m
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC 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
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -464,29 +484,34 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_PNP is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK 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
-CONFIG_BLK_DEV_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -513,8 +538,34 @@ CONFIG_DUMMY=y
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
 # CONFIG_ARCNET is not set
-# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=m
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_AX88796 is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DNET is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA 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_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_KS8842 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -523,17 +574,27 @@ CONFIG_MII=m
 # Wireless LAN
 #
 # CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_WLAN_80211=y
+# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_ATMEL is not set
+# CONFIG_AIRO_CS is not set
+# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_HERMES is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
 CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -565,20 +626,23 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
 #
 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_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+CONFIG_KEYBOARD_HP7XX=y
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_KEYBOARD_HP7XX=y
-# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD 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_AD7879 is not set
 # 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
@@ -587,8 +651,8 @@ CONFIG_TOUCHSCREEN_HP7XX=y
 # CONFIG_TOUCHSCREEN_PENMOUNT is not set
 # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 # CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_UCB1400 is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -624,11 +688,12 @@ CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=32
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
@@ -650,6 +715,10 @@ CONFIG_GPIOLIB=y
 # CONFIG_GPIO_SYSFS is not set
 
 #
+# Memory mapped GPIO expanders:
+#
+
+#
 # I2C GPIO expanders:
 #
 
@@ -663,12 +732,14 @@ CONFIG_GPIOLIB=y
 # 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_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -676,6 +747,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
 # CONFIG_MFD_TMIO is not set
@@ -687,22 +759,7 @@ CONFIG_SSB_POSSIBLE=y
 # Multimedia Capabilities Port drivers
 #
 # CONFIG_MCP_SA11X0 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
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -712,6 +769,7 @@ CONFIG_SSB_POSSIBLE=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
@@ -733,7 +791,17 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_SA1100 is not set
 CONFIG_FB_S1D13XXX=y
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT 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_LCD_HP700=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_HP700=y
 
 #
 # Display device support
@@ -757,6 +825,8 @@ CONFIG_FONT_8x16=y
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -781,12 +851,15 @@ CONFIG_RTC_INTF_DEV=y
 # Platform RTC drivers
 #
 # CONFIG_RTC_DRV_CMOS is not set
+# 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
 
 #
@@ -794,15 +867,10 @@ CONFIG_RTC_INTF_DEV=y
 #
 CONFIG_RTC_DRV_SA1100=y
 # CONFIG_DMADEVICES is not set
-
-#
-# Voltage and Current regulators
-#
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REGULATOR_BQ24022 is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
 
 #
 # File systems
@@ -811,12 +879,16 @@ 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_EXT4DEV_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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -826,6 +898,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -846,14 +923,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 # CONFIG_TMPFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 # 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
@@ -862,6 +937,7 @@ CONFIG_SYSFS=y
 # 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
@@ -870,6 +946,7 @@ CONFIG_SYSFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 # CONFIG_NETWORK_FILESYSTEMS is not set
 
 #
@@ -935,12 +1012,16 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -958,19 +1039,20 @@ CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
 CONFIG_FRAME_POINTER=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -985,13 +1067,16 @@ CONFIG_DEBUG_LL=y
 #
 # 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_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
@@ -1062,15 +1147,21 @@ CONFIG_CRYPTO=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1078,7 +1169,7 @@ CONFIG_CRC_CCITT=m
 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/arm/configs/n8x0_defconfig b/arch/arm/configs/n8x0_defconfig
new file mode 100644
index 0000000..8da75de
--- /dev/null
+++ b/arch/arm/configs/n8x0_defconfig
@@ -0,0 +1,1104 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc5
+# Thu Aug  6 22:17:23 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=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=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT 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 is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF 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
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+CONFIG_ARCH_OMAP2=y
+# CONFIG_ARCH_OMAP3 is not set
+# CONFIG_ARCH_OMAP4 is not set
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+CONFIG_OMAP_RESET_CLOCKS=y
+# CONFIG_OMAP_MUX is not set
+# CONFIG_OMAP_MCBSP is not set
+CONFIG_OMAP_MBOX_FWK=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_MACH_OMAP_GENERIC is not set
+
+#
+# OMAP Core Type
+#
+CONFIG_ARCH_OMAP24XX=y
+CONFIG_ARCH_OMAP2420=y
+# CONFIG_ARCH_OMAP2430 is not set
+
+#
+# OMAP Board Type
+#
+CONFIG_MACH_OMAP2_TUSB6010=y
+# CONFIG_MACH_OMAP_H4 is not set
+# CONFIG_MACH_OMAP_APOLLON is not set
+# CONFIG_MACH_OMAP_2430SDP is not set
+CONFIG_MACH_NOKIA_N8X0=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x10C08000
+CONFIG_ZBOOT_ROM_BSS=0x10200000
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_CMDLINE="root=1f03 rootfstype=jffs2 console=ttyS0,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET 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=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_PHONET is not set
+# CONFIG_IEEE802154 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_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
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# 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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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=y
+# 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_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_HAVE_MTD_OTP=y
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# 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 is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS 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 is not set
+
+#
+# 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=y
+# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
+# CONFIG_MTD_ONENAND_GENERIC is not set
+CONFIG_MTD_ONENAND_OMAP2=y
+CONFIG_MTD_ONENAND_OTP=y
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_SIM is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR 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 is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB 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_MG_DISK 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
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 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 is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 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_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 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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# 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 is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_TUSB6010=y
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_GADGET_MUSB_HDRC=y
+# CONFIG_MUSB_PIO_ONLY is not set
+# CONFIG_USB_INVENTRA_DMA is not set
+# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_USB_TUSB_OMAP_DMA=y
+CONFIG_USB_MUSB_DEBUG=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# 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_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=y
+# CONFIG_USB_ETH_RNDIS is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# 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_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+CONFIG_NOP_USB_XCEIV=y
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR 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_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_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 is not set
+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 is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO 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
+# 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_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD 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 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# 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 is not set
+# 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 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+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=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# 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_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL 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
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+# 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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
new file mode 100644
index 0000000..9bb45b9
--- /dev/null
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -0,0 +1,1316 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30
+# Tue Jun 23 22:57:16 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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 is not set
+# CONFIG_SWAP is not set
+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=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
+# 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_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_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+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_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+CONFIG_ARCH_NOMADIK=y
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Nomadik boards
+#
+CONFIG_MACH_NOMADIK_8815NHK=y
+CONFIG_NOMADIK_8815=y
+CONFIG_I2C_BITBANG_8815NHK=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+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=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+# CONFIG_IP_PIMSM_V1 is not set
+# CONFIG_IP_PIMSM_V2 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=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_PHONET is not set
+# CONFIG_IEEE802154 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=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# 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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_TESTS=m
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_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 is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_NOMADIK=y
+CONFIG_MTD_ONENAND=y
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+CONFIG_MTD_ONENAND_GENERIC=y
+# CONFIG_MTD_ONENAND_OTP is not set
+# CONFIG_MTD_ONENAND_2X_PROGRAM is not set
+# CONFIG_MTD_ONENAND_SIM is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR 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=y
+# 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_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE 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_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=y
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+CONFIG_SMC91X=y
+# CONFIG_DM9000 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
+# 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_KS8842 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+CONFIG_NETCONSOLE=m
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN 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=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_PL061 is not set
+
+#
+# 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_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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB 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_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=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_APPLE is not set
+# CONFIG_HID_WACOM is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB 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
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# 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 is not set
+# 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
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# 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_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 is not set
+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 is not set
+# 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 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
+# 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_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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 is not set
+# 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=y
+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=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# 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 is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_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_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# 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_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL 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_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+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
+
+#
+# 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=m
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# 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=m
+# 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 is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# 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_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig
index 4c6fb7e..51c0fa8 100644
--- a/arch/arm/configs/omap3_beagle_defconfig
+++ b/arch/arm/configs/omap3_beagle_defconfig
@@ -128,6 +128,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type
@@ -236,6 +237,7 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
 # CONFIG_OUTER_CACHE is not set
+CONFIG_COMMON_CLKDEV=y
 
 #
 # Bus support
@@ -317,7 +319,12 @@ CONFIG_BINFMT_MISC=y
 #
 # Power management options
 #
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -713,6 +720,7 @@ CONFIG_GPIOLIB=y
 # CONFIG_GPIO_MAX732X is not set
 # CONFIG_GPIO_PCA953X is not set
 # CONFIG_GPIO_PCF857X is not set
+CONFIG_GPIO_TWL4030=y
 
 #
 # PCI GPIO expanders:
@@ -741,6 +749,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+CONFIG_TWL4030_CORE=y
 # CONFIG_UCB1400_CORE is not set
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
@@ -787,7 +796,7 @@ CONFIG_DUMMY_CONSOLE=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
@@ -798,7 +807,8 @@ CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_DEVICE_CLASS=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 CONFIG_USB_MON=y
@@ -806,6 +816,8 @@ CONFIG_USB_MON=y
 #
 # USB Host Controller Drivers
 #
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
 # CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
@@ -818,10 +830,10 @@ CONFIG_USB_MUSB_SOC=y
 #
 # OMAP 343x high speed USB support
 #
-CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_HOST is not set
 # CONFIG_USB_MUSB_PERIPHERAL is not set
-# CONFIG_USB_MUSB_OTG is not set
-# CONFIG_USB_GADGET_MUSB_HDRC is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
 CONFIG_USB_MUSB_HDRC_HCD=y
 # CONFIG_MUSB_PIO_ONLY is not set
 CONFIG_USB_INVENTRA_DMA=y
@@ -887,8 +899,8 @@ CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_FSL_USB2 is not set
 # CONFIG_USB_GADGET_NET2280 is not set
 # CONFIG_USB_GADGET_PXA25X is not set
-CONFIG_USB_GADGET_M66592=y
-CONFIG_USB_M66592=y
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_M66592 is not set
 # CONFIG_USB_GADGET_PXA27X is not set
 # CONFIG_USB_GADGET_GOKU is not set
 # CONFIG_USB_GADGET_LH7A40X is not set
@@ -906,6 +918,15 @@ CONFIG_USB_ETH_RNDIS=y
 # 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_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -923,6 +944,7 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 #
 # CONFIG_MMC_SDHCI is not set
 # CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
 # CONFIG_MEMSTICK is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
@@ -981,10 +1003,11 @@ CONFIG_RTC_INTF_DEV=y
 #
 # Voltage and Current regulators
 #
-# CONFIG_REGULATOR is not set
+CONFIG_REGULATOR=y
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
 # CONFIG_REGULATOR_BQ24022 is not set
+CONFIG_REGULATOR_TWL4030=y
 # CONFIG_UIO is not set
 
 #
diff --git a/arch/arm/configs/omap_3430sdp_defconfig b/arch/arm/configs/omap_3430sdp_defconfig
index 8fb918d..9a510ea 100644
--- a/arch/arm/configs/omap_3430sdp_defconfig
+++ b/arch/arm/configs/omap_3430sdp_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc8
-# Fri Mar 13 14:17:01 2009
+# Linux kernel version: 2.6.30-omap1
+# Tue Jun 23 10:36:45 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -197,9 +197,9 @@ CONFIG_OMAP_MCBSP=y
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
 CONFIG_OMAP_DM_TIMER=y
-# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+CONFIG_OMAP_LL_DEBUG_UART1=y
 # CONFIG_OMAP_LL_DEBUG_UART2 is not set
-CONFIG_OMAP_LL_DEBUG_UART3=y
+# CONFIG_OMAP_LL_DEBUG_UART3 is not set
 CONFIG_OMAP_SERIAL_WAKE=y
 CONFIG_ARCH_OMAP34XX=y
 CONFIG_ARCH_OMAP3430=y
@@ -207,10 +207,10 @@ CONFIG_ARCH_OMAP3430=y
 #
 # OMAP Board Type
 #
-CONFIG_MACH_OMAP3_BEAGLE=y
-CONFIG_MACH_OMAP_LDP=y
-CONFIG_MACH_OVERO=y
-CONFIG_MACH_OMAP3_PANDORA=y
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_OMAP_LDP is not set
+# CONFIG_MACH_OVERO is not set
+# CONFIG_MACH_OMAP3_PANDORA is not set
 CONFIG_MACH_OMAP_3430SDP=y
 
 #
@@ -950,7 +950,7 @@ CONFIG_SPI_OMAP24XX=y
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
-CONFIG_DEBUG_GPIO=y
+# CONFIG_DEBUG_GPIO is not set
 CONFIG_GPIO_SYSFS=y
 
 #
@@ -1370,7 +1370,7 @@ CONFIG_SND_OMAP_SOC=y
 CONFIG_SND_OMAP_SOC_MCBSP=y
 # CONFIG_SND_OMAP_SOC_OVERO is not set
 CONFIG_SND_OMAP_SOC_SDP3430=y
-CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
+# CONFIG_SND_OMAP_SOC_OMAP3_PANDORA is not set
 CONFIG_SND_SOC_I2C_AND_SPI=y
 # CONFIG_SND_SOC_ALL_CODECS is not set
 CONFIG_SND_SOC_TWL4030=y
diff --git a/arch/arm/configs/omap_zoom2_defconfig b/arch/arm/configs/omap_zoom2_defconfig
index 213fe9c..f1739fa 100644
--- a/arch/arm/configs/omap_zoom2_defconfig
+++ b/arch/arm/configs/omap_zoom2_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc5
-# Fri Oct 10 11:49:41 2008
+# Linux kernel version: 2.6.30-omap1
+# Fri Jun 12 17:25:46 2009
 #
 CONFIG_ARM=y
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -22,8 +22,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
-CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -39,44 +37,61 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
 # 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
 # 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_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 is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS 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_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
@@ -84,19 +99,13 @@ CONFIG_SLAB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
-# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
 CONFIG_HAVE_CLK=y
-CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_SLOW_WORK is not set
 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
@@ -104,11 +113,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-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
 
@@ -124,7 +130,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # System Type
@@ -134,10 +140,10 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_VERSATILE is not set
 # CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_NETX is not set
 # CONFIG_ARCH_H720X is not set
@@ -158,14 +164,17 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_ARCH_ORION5X is not set
 # CONFIG_ARCH_PNX4008 is not set
 # CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
 # CONFIG_ARCH_SHARK is not set
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_DAVINCI is not set
 CONFIG_ARCH_OMAP=y
-# CONFIG_ARCH_MSM7X00A is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_W90X900 is not set
 
 #
 # TI OMAP Implementations
@@ -174,6 +183,7 @@ CONFIG_ARCH_OMAP_OTG=y
 # CONFIG_ARCH_OMAP1 is not set
 # CONFIG_ARCH_OMAP2 is not set
 CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
 
 #
 # OMAP Feature Selections
@@ -185,6 +195,7 @@ CONFIG_OMAP_MUX=y
 CONFIG_OMAP_MUX_DEBUG=y
 CONFIG_OMAP_MUX_WARNINGS=y
 CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MBOX_FWK is not set
 # CONFIG_OMAP_MPU_TIMER is not set
 CONFIG_OMAP_32K_TIMER=y
 CONFIG_OMAP_32K_TIMER_HZ=128
@@ -192,25 +203,20 @@ CONFIG_OMAP_DM_TIMER=y
 # CONFIG_OMAP_LL_DEBUG_UART1 is not set
 # CONFIG_OMAP_LL_DEBUG_UART2 is not set
 CONFIG_OMAP_LL_DEBUG_UART3=y
-CONFIG_OMAP_SERIAL_WAKE=y
 CONFIG_ARCH_OMAP34XX=y
 CONFIG_ARCH_OMAP3430=y
 
 #
 # OMAP Board Type
 #
-# CONFIG_MACH_OMAP3_BEAGLE is not set
+# CONFIG_MACH_NOKIA_RX51 is not set
 # CONFIG_MACH_OMAP_LDP is not set
-CONFIG_MACH_OMAP_ZOOM2=y
+# CONFIG_MACH_OMAP_3430SDP is not set
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_OMAP3_BEAGLE is not set
 # CONFIG_MACH_OVERO is not set
-
-#
-# Boot options
-#
-
-#
-# Power management
-#
+# CONFIG_MACH_OMAP3_PANDORA is not set
+CONFIG_MACH_OMAP_ZOOM2=y
 
 #
 # Processor Type
@@ -239,6 +245,10 @@ CONFIG_ARM_THUMB=y
 # CONFIG_CPU_BPREDICT_DISABLE is not set
 CONFIG_HAS_TLS_REG=y
 # CONFIG_OUTER_CACHE is not set
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
 
 #
 # Bus support
@@ -254,26 +264,32 @@ CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
 # CONFIG_PREEMPT is not set
 CONFIG_HZ=128
 CONFIG_AEABI=y
 CONFIG_OABI_COMPAT=y
-CONFIG_ARCH_FLATMEM_HAS_HOLES=y
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 # CONFIG_LEDS is not set
 CONFIG_ALIGNMENT_TRAP=y
 
@@ -287,9 +303,10 @@ CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.16
 # CONFIG_KEXEC is not set
 
 #
-# CPU Frequency scaling
+# CPU Power Management
 #
 # CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
 
 #
 # Floating point emulation
@@ -309,13 +326,23 @@ CONFIG_VFPv3=y
 # Userspace binary formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_MISC=y
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_VERBOSE=y
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_NET=y
 
@@ -378,7 +405,9 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
@@ -389,8 +418,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
 
@@ -416,14 +445,28 @@ 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_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
 CONFIG_MISC_DEVICES=y
-# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_OMAP_STI 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
 
@@ -461,14 +504,20 @@ CONFIG_SCSI_WAIT_SCAN=m
 #
 # 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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE 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
@@ -501,8 +550,10 @@ CONFIG_MII=y
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 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
@@ -519,7 +570,10 @@ CONFIG_NETDEV_10000=y
 #
 # 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
@@ -561,17 +615,25 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_TABLET is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
 # 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_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_TSC2005 is not set
+# CONFIG_TOUCHSCREEN_TSC210X is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
 # CONFIG_INPUT_MISC is not set
 
 #
@@ -607,13 +669,15 @@ CONFIG_SERIAL_8250_RSA=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 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=y
-# CONFIG_NVRAM is not set
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 # CONFIG_R3964 is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -639,6 +703,7 @@ CONFIG_I2C_OMAP=y
 #
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
 
 #
 # Other I2C/SMBus bus drivers
@@ -650,14 +715,11 @@ CONFIG_I2C_OMAP=y
 # 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_ISP1301_OMAP is not set
-# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_MADC is not set
+# CONFIG_TWL4030_POWEROFF is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -672,12 +734,12 @@ CONFIG_SPI_MASTER=y
 # SPI Master Controller Drivers
 #
 # CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
 CONFIG_SPI_OMAP24XX=y
 
 #
 # SPI Protocol Masters
 #
-# CONFIG_EEPROM_AT25 is not set
 # CONFIG_SPI_SPIDEV is not set
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
@@ -686,11 +748,16 @@ CONFIG_GPIOLIB=y
 # CONFIG_GPIO_SYSFS is not set
 
 #
+# 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
+CONFIG_GPIO_TWL4030=y
 
 #
 # PCI GPIO expanders:
@@ -702,26 +769,34 @@ CONFIG_GPIOLIB=y
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
 CONFIG_W1=y
+CONFIG_W1_CON=y
 
 #
 # 1-wire Bus Masters
 #
+# CONFIG_W1_MASTER_DS2490 is not set
 # CONFIG_W1_MASTER_DS2482 is not set
 # CONFIG_W1_MASTER_DS1WM is not set
 # CONFIG_W1_MASTER_GPIO is not set
+# CONFIG_HDQ_MASTER_OMAP is not set
 
 #
 # 1-wire Slaves
 #
 # CONFIG_W1_SLAVE_THERM is not set
 # CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2431 is not set
 # CONFIG_W1_SLAVE_DS2433 is not set
 # CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_W1_SLAVE_BQ27000 is not set
 CONFIG_POWER_SUPPLY=y
 # CONFIG_POWER_SUPPLY_DEBUG is not set
 # CONFIG_PDA_POWER is not set
 # CONFIG_BATTERY_DS2760 is not set
+# CONFIG_BATTERY_BQ27x00 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=y
 
@@ -729,11 +804,17 @@ CONFIG_WATCHDOG_NOWAYOUT=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_OMAP_WATCHDOG is not set
 
 #
-# Sonics Silicon Backplane
+# USB-based Watchdog Cards
 #
+# CONFIG_USBPCWATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
 # CONFIG_SSB is not set
 
 #
@@ -741,12 +822,19 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
 # CONFIG_HTC_EGPIO is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+CONFIG_TWL4030_CORE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_T7L66XB is not set
 # CONFIG_MFD_TC6387XB is not set
 # CONFIG_MFD_TC6393XB 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
 
 #
 # Multimedia devices
@@ -756,12 +844,14 @@ CONFIG_SSB_POSSIBLE=y
 # 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=y
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -782,10 +872,12 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
 CONFIG_SND=y
 # CONFIG_SND_SEQUENCER is not set
 # CONFIG_SND_MIXER_OSS is not set
 # CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
 CONFIG_SND_VERBOSE_PROCFS=y
@@ -798,19 +890,197 @@ CONFIG_SND_DRIVERS=y
 # CONFIG_SND_MPU401 is not set
 CONFIG_SND_ARM=y
 CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
 # CONFIG_SND_SOC is not set
 # CONFIG_SOUND_PRIME is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
-# CONFIG_USB_SUPPORT is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_GREENASIA_FF is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# 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 is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+CONFIG_USB_MUSB_OTG=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+CONFIG_USB_MUSB_DEBUG=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# 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 is not set
+# 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
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=y
+# CONFIG_USB_ZERO_HNPTEST is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# 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_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_ISP1301_OMAP is not set
+CONFIG_TWL4030_USB=y
+# CONFIG_NOP_USB_XCEIV is not set
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
 #
-# MMC/SD Card Drivers
+# MMC/SD/SDIO Card Drivers
 #
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
@@ -818,11 +1088,13 @@ CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_MMC_TEST is not set
 
 #
-# MMC/SD Host Controller Drivers
+# MMC/SD/SDIO Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_OMAP is not set
+CONFIG_MMC_OMAP_HS=y
 # CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_NEW_LEDS is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -852,43 +1124,55 @@ CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_TWL4030 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_CMOS is not set
+# 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_DMADEVICES is not set
-
-#
-# Voltage and Current regulators
-#
-# CONFIG_REGULATOR is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
 # CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 # CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
 # CONFIG_REGULATOR_BQ24022 is not set
+CONFIG_REGULATOR_TWL4030=y
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# CBUS support
+#
+# CONFIG_CBUS is not set
 
 #
 # File systems
@@ -897,18 +1181,24 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
+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
 CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
 CONFIG_PRINT_QUOTA_WARNING=y
+CONFIG_QUOTA_TREE=y
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=y
 CONFIG_QUOTACTL=y
@@ -917,6 +1207,11 @@ CONFIG_QUOTACTL=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -937,15 +1232,13 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 #
 CONFIG_PROC_FS=y
 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 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
@@ -954,6 +1247,7 @@ CONFIG_TMPFS=y
 # 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
@@ -962,6 +1256,7 @@ CONFIG_TMPFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -975,7 +1270,6 @@ CONFIG_NFS_ACL_SUPPORT=y
 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
@@ -1045,6 +1339,7 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
 
 #
 # Kernel hacking
@@ -1062,6 +1357,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1084,21 +1382,36 @@ CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_NOTIFIERS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1110,17 +1423,28 @@ CONFIG_DEBUG_LL=y
 #
 # 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_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+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
@@ -1152,7 +1476,7 @@ CONFIG_CRYPTO_PCBC=m
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
@@ -1189,15 +1513,21 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
@@ -1205,7 +1535,9 @@ CONFIG_CRC_T10DIF=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 CONFIG_LIBCRC32C=y
-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/arm/configs/rx51_defconfig b/arch/arm/configs/rx51_defconfig
index f238df6..e7e3133 100644
--- a/arch/arm/configs/rx51_defconfig
+++ b/arch/arm/configs/rx51_defconfig
@@ -1006,6 +1006,7 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_OMAP_WATCHDOG=m
+CONFIG_TWL4030_WATCHDOG=m
 
 #
 # USB-based Watchdog Cards
diff --git a/arch/arm/configs/s5pc100_defconfig b/arch/arm/configs/s5pc100_defconfig
new file mode 100644
index 0000000..b0d7d3d
--- /dev/null
+++ b/arch/arm/configs/s5pc100_defconfig
@@ -0,0 +1,892 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30
+# Wed Jul  1 15:53:07 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_MMU=y
+CONFIG_NO_IOPORT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_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_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+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=17
+# 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=y
+# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+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
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+CONFIG_ARCH_S5PC1XX=y
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_PLAT_S3C=y
+
+#
+# Boot options
+#
+# CONFIG_S3C_BOOT_ERROR_RESET is not set
+CONFIG_S3C_BOOT_UART_FORCE_FIFO=y
+
+#
+# Power management
+#
+CONFIG_S3C_LOWLEVEL_UART_PORT=0
+CONFIG_S3C_GPIO_SPACE=0
+CONFIG_S3C_GPIO_TRACK=y
+CONFIG_S3C_GPIO_PULL_UPDOWN=y
+CONFIG_PLAT_S5PC1XX=y
+CONFIG_CPU_S5PC100_INIT=y
+CONFIG_CPU_S5PC100_CLOCK=y
+CONFIG_S5PC100_SETUP_I2C0=y
+CONFIG_CPU_S5PC100=y
+CONFIG_MACH_SMDKC100=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_VIC=y
+CONFIG_ARM_VIC_NR=2
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM 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_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=cramfs init=/linuxrc console=ttySAC2,115200 mem=128M"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR 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=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# 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=y
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 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
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_UARTS=3
+# CONFIG_SERIAL_SAMSUNG_DEBUG is not set
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 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:
+#
+# 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_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# 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_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# 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_SHT15 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP 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_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO 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_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB 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_AB3100_CORE is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+# CONFIG_MMC_SDHCI_PLTFM is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO 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=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+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_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=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS 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=y
+# 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 is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# 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_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+CONFIG_DEBUG_S3C_PORT=y
+CONFIG_DEBUG_S3C_UART=0
+
+#
+# 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
+# CONFIG_BINARY_PRINTF 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_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 15f8a09..00f46d9 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -74,23 +74,56 @@
  * Enable and disable interrupts
  */
 #if __LINUX_ARM_ARCH__ >= 6
-	.macro	disable_irq
+	.macro	disable_irq_notrace
 	cpsid	i
 	.endm
 
-	.macro	enable_irq
+	.macro	enable_irq_notrace
 	cpsie	i
 	.endm
 #else
-	.macro	disable_irq
+	.macro	disable_irq_notrace
 	msr	cpsr_c, #PSR_I_BIT | SVC_MODE
 	.endm
 
-	.macro	enable_irq
+	.macro	enable_irq_notrace
 	msr	cpsr_c, #SVC_MODE
 	.endm
 #endif
 
+	.macro asm_trace_hardirqs_off
+#if defined(CONFIG_TRACE_IRQFLAGS)
+	stmdb   sp!, {r0-r3, ip, lr}
+	bl	trace_hardirqs_off
+	ldmia	sp!, {r0-r3, ip, lr}
+#endif
+	.endm
+
+	.macro asm_trace_hardirqs_on_cond, cond
+#if defined(CONFIG_TRACE_IRQFLAGS)
+	/*
+	 * actually the registers should be pushed and pop'd conditionally, but
+	 * after bl the flags are certainly clobbered
+	 */
+	stmdb   sp!, {r0-r3, ip, lr}
+	bl\cond	trace_hardirqs_on
+	ldmia	sp!, {r0-r3, ip, lr}
+#endif
+	.endm
+
+	.macro asm_trace_hardirqs_on
+	asm_trace_hardirqs_on_cond al
+	.endm
+
+	.macro disable_irq
+	disable_irq_notrace
+	asm_trace_hardirqs_off
+	.endm
+
+	.macro enable_irq
+	asm_trace_hardirqs_on
+	enable_irq_notrace
+	.endm
 /*
  * Save the current IRQ state and disable IRQs.  Note that this macro
  * assumes FIQs are enabled, and that the processor is in SVC mode.
@@ -104,10 +137,16 @@
  * Restore interrupt state previously stored in a register.  We don't
  * guarantee that this will preserve the flags.
  */
-	.macro	restore_irqs, oldcpsr
+	.macro	restore_irqs_notrace, oldcpsr
 	msr	cpsr_c, \oldcpsr
 	.endm
 
+	.macro restore_irqs, oldcpsr
+	tst	\oldcpsr, #PSR_I_BIT
+	asm_trace_hardirqs_on_cond eq
+	restore_irqs_notrace \oldcpsr
+	.endm
+
 #define USER(x...)				\
 9999:	x;					\
 	.section __ex_table,"a";		\
@@ -127,3 +166,87 @@
 #endif
 #endif
 	.endm
+
+#ifdef CONFIG_THUMB2_KERNEL
+	.macro	setmode, mode, reg
+	mov	\reg, #\mode
+	msr	cpsr_c, \reg
+	.endm
+#else
+	.macro	setmode, mode, reg
+	msr	cpsr_c, #\mode
+	.endm
+#endif
+
+/*
+ * STRT/LDRT access macros with ARM and Thumb-2 variants
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+
+	.macro	usraccoff, instr, reg, ptr, inc, off, cond, abort
+9999:
+	.if	\inc == 1
+	\instr\cond\()bt \reg, [\ptr, #\off]
+	.elseif	\inc == 4
+	\instr\cond\()t \reg, [\ptr, #\off]
+	.else
+	.error	"Unsupported inc macro argument"
+	.endif
+
+	.section __ex_table,"a"
+	.align	3
+	.long	9999b, \abort
+	.previous
+	.endm
+
+	.macro	usracc, instr, reg, ptr, inc, cond, rept, abort
+	@ explicit IT instruction needed because of the label
+	@ introduced by the USER macro
+	.ifnc	\cond,al
+	.if	\rept == 1
+	itt	\cond
+	.elseif	\rept == 2
+	ittt	\cond
+	.else
+	.error	"Unsupported rept macro argument"
+	.endif
+	.endif
+
+	@ Slightly optimised to avoid incrementing the pointer twice
+	usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
+	.if	\rept == 2
+	usraccoff \instr, \reg, \ptr, \inc, 4, \cond, \abort
+	.endif
+
+	add\cond \ptr, #\rept * \inc
+	.endm
+
+#else	/* !CONFIG_THUMB2_KERNEL */
+
+	.macro	usracc, instr, reg, ptr, inc, cond, rept, abort
+	.rept	\rept
+9999:
+	.if	\inc == 1
+	\instr\cond\()bt \reg, [\ptr], #\inc
+	.elseif	\inc == 4
+	\instr\cond\()t \reg, [\ptr], #\inc
+	.else
+	.error	"Unsupported inc macro argument"
+	.endif
+
+	.section __ex_table,"a"
+	.align	3
+	.long	9999b, \abort
+	.previous
+	.endr
+	.endm
+
+#endif	/* CONFIG_THUMB2_KERNEL */
+
+	.macro	strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
+	usracc	str, \reg, \ptr, \inc, \cond, \rept, \abort
+	.endm
+
+	.macro	ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
+	usracc	ldr, \reg, \ptr, \inc, \cond, \rept, \abort
+	.endm
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index c61642b..9f390ce 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -12,4 +12,7 @@ struct dev_archdata {
 #endif
 };
 
+struct pdev_archdata {
+};
+
 #endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index c207504..c3b911e 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -55,6 +55,9 @@ typedef struct user_fp elf_fpregset_t;
 #define R_ARM_MOVW_ABS_NC	43
 #define R_ARM_MOVT_ABS		44
 
+#define R_ARM_THM_CALL		10
+#define R_ARM_THM_JUMP24	30
+
 /*
  * These are used to set parameters in the core dumps.
  */
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index 39c8bc1..103f7ee 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -7,8 +7,43 @@
 
 #ifndef __ASSEMBLY__
 extern void mcount(void);
+extern void __gnu_mcount_nc(void);
 #endif
 
 #endif
 
+#ifndef __ASSEMBLY__
+
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+/*
+ * return_address uses walk_stackframe to do it's work.  If both
+ * CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind
+ * information.  For this to work in the function tracer many functions would
+ * have to be marked with __notrace.  So for now just depend on
+ * !CONFIG_ARM_UNWIND.
+ */
+
+void *return_address(unsigned int);
+
+#else
+
+extern inline void *return_address(unsigned int level)
+{
+	return NULL;
+}
+
+#endif
+
+#define HAVE_ARCH_CALLER_ADDR
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* ifndef __ASSEMBLY__ */
+
 #endif /* _ASM_ARM_FTRACE */
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
index 9ee743b..bfcc159 100644
--- a/arch/arm/include/asm/futex.h
+++ b/arch/arm/include/asm/futex.h
@@ -99,6 +99,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
 	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
 	"1:	ldrt	%0, [%3]\n"
 	"	teq	%0, %1\n"
+	"	it	eq	@ explicit IT needed for the 2b label\n"
 	"2:	streqt	%2, [%3]\n"
 	"3:\n"
 	"	.section __ex_table,\"a\"\n"
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index 4da332b..b490ecc 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -10,6 +10,8 @@ struct mmc_platform_data {
 	unsigned int ocr_mask;			/* available voltages */
 	u32 (*translate_vdd)(struct device *, unsigned int);
 	unsigned int (*status)(struct device *);
+	int	gpio_wp;
+	int	gpio_cd;
 };
 
 #endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 85763db..cefedf0 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -44,7 +44,13 @@
  * The module space lives between the addresses given by TASK_SIZE
  * and PAGE_OFFSET - it must be within 32MB of the kernel text.
  */
+#ifndef CONFIG_THUMB2_KERNEL
 #define MODULES_VADDR		(PAGE_OFFSET - 16*1024*1024)
+#else
+/* smaller range for Thumb-2 symbols relocation (2^24)*/
+#define MODULES_VADDR		(PAGE_OFFSET - 8*1024*1024)
+#endif
+
 #if TASK_SIZE > MODULES_VADDR
 #error Top of user space clashes with start of module space
 #endif
@@ -212,7 +218,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
  *
  *  page_to_pfn(page)	convert a struct page * to a PFN number
  *  pfn_to_page(pfn)	convert a _valid_ PFN number to struct page *
- *  pfn_valid(pfn)	indicates whether a PFN number is valid
  *
  *  virt_to_page(k)	convert a _valid_ virtual address to struct page *
  *  virt_addr_valid(k)	indicates whether a virtual address is valid
@@ -221,10 +226,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
 
 #define ARCH_PFN_OFFSET		PHYS_PFN_OFFSET
 
-#ifndef CONFIG_SPARSEMEM
-#define pfn_valid(pfn)		((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
-#endif
-
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
 #define virt_addr_valid(kaddr)	((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
 
@@ -241,18 +242,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
 #define arch_pfn_to_nid(pfn)	PFN_TO_NID(pfn)
 #define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT)
 
-#define pfn_valid(pfn)						\
-	({							\
-		unsigned int nid = PFN_TO_NID(pfn);		\
-		int valid = nid < MAX_NUMNODES;			\
-		if (valid) {					\
-			pg_data_t *node = NODE_DATA(nid);	\
-			valid = (pfn - node->node_start_pfn) <	\
-				node->node_spanned_pages;	\
-		}						\
-		valid;						\
-	})
-
 #define virt_to_page(kaddr)					\
 	(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
 
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 263fed0..bcdb929 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -62,8 +62,10 @@ static inline void check_context(struct mm_struct *mm)
 
 static inline void check_context(struct mm_struct *mm)
 {
+#ifdef CONFIG_MMU
 	if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq))
 		__check_kvm_seq(mm);
+#endif
 }
 
 #define init_new_context(tsk,mm)	0
diff --git a/arch/arm/include/asm/page-nommu.h b/arch/arm/include/asm/page-nommu.h
index 3574c0d..d1b162a 100644
--- a/arch/arm/include/asm/page-nommu.h
+++ b/arch/arm/include/asm/page-nommu.h
@@ -43,7 +43,4 @@ typedef unsigned long pgprot_t;
 #define __pmd(x)        (x)
 #define __pgprot(x)     (x)
 
-extern unsigned long memory_start;
-extern unsigned long memory_end;
-
 #endif
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 9c746af..3a32af4 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -194,6 +194,10 @@ typedef unsigned long pgprot_t;
 
 typedef struct page *pgtable_t;
 
+#ifndef CONFIG_SPARSEMEM
+extern int pfn_valid(unsigned long);
+#endif
+
 #include <asm/memory.h>
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 0abf386..226cddd 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -6,8 +6,6 @@
 
 #include <mach/hardware.h> /* for PCIBIOS_MIN_* */
 
-#define pcibios_scan_all_fns(a, b)	0
-
 #ifdef CONFIG_PCI_HOST_ITE8152
 /* ITE bridge requires setting latency timer to avoid early bus access
    termination by PIC bus mater devices
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 3dcd64b..b12cc98 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -36,6 +36,8 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
 #define pgd_alloc(mm)			get_pgd_slow(mm)
 #define pgd_free(mm, pgd)		free_pgd_slow(mm, pgd)
 
+#define PGALLOC_GFP	(GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+
 /*
  * Allocate one PTE table.
  *
@@ -57,7 +59,7 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
 {
 	pte_t *pte;
 
-	pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
+	pte = (pte_t *)__get_free_page(PGALLOC_GFP);
 	if (pte) {
 		clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
 		pte += PTRS_PER_PTE;
@@ -71,10 +73,16 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
 	struct page *pte;
 
-	pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
+#ifdef CONFIG_HIGHPTE
+	pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
+#else
+	pte = alloc_pages(PGALLOC_GFP, 0);
+#endif
 	if (pte) {
-		void *page = page_address(pte);
-		clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
+		if (!PageHighMem(pte)) {
+			void *page = page_address(pte);
+			clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
+		}
 		pgtable_page_ctor(pte);
 	}
 
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index c433c6c..201ccaa 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -162,10 +162,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
  * entries are stored 1024 bytes below.
  */
 #define L_PTE_PRESENT		(1 << 0)
-#define L_PTE_FILE		(1 << 1)	/* only when !PRESENT */
 #define L_PTE_YOUNG		(1 << 1)
-#define L_PTE_BUFFERABLE	(1 << 2)	/* obsolete, matches PTE */
-#define L_PTE_CACHEABLE		(1 << 3)	/* obsolete, matches PTE */
+#define L_PTE_FILE		(1 << 2)	/* only when !PRESENT */
 #define L_PTE_DIRTY		(1 << 6)
 #define L_PTE_WRITE		(1 << 7)
 #define L_PTE_USER		(1 << 8)
@@ -264,10 +262,19 @@ extern struct page *empty_zero_page;
 #define pte_clear(mm,addr,ptep)	set_pte_ext(ptep, __pte(0), 0)
 #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
 #define pte_offset_kernel(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
-#define pte_offset_map(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
-#define pte_offset_map_nested(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
-#define pte_unmap(pte)		do { } while (0)
-#define pte_unmap_nested(pte)	do { } while (0)
+
+#define pte_offset_map(dir,addr)	(__pte_map(dir, KM_PTE0) + __pte_index(addr))
+#define pte_offset_map_nested(dir,addr)	(__pte_map(dir, KM_PTE1) + __pte_index(addr))
+#define pte_unmap(pte)			__pte_unmap(pte, KM_PTE0)
+#define pte_unmap_nested(pte)		__pte_unmap(pte, KM_PTE1)
+
+#ifndef CONFIG_HIGHPTE
+#define __pte_map(dir,km)	pmd_page_vaddr(*(dir))
+#define __pte_unmap(pte,km)	do { } while (0)
+#else
+#define __pte_map(dir,km)	((pte_t *)kmap_atomic(pmd_page(*(dir)), km) + PTRS_PER_PTE)
+#define __pte_unmap(pte,km)	kunmap_atomic((pte - PTRS_PER_PTE), km)
+#endif
 
 #define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
 
@@ -381,13 +388,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  *
  *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *   <--------------- offset --------------------> <--- type --> 0 0
+ *   <--------------- offset --------------------> <- type --> 0 0 0
  *
- * This gives us up to 127 swap files and 32GB per swap file.  Note that
+ * This gives us up to 63 swap files and 32GB per swap file.  Note that
  * the offset field is always non-zero.
  */
-#define __SWP_TYPE_SHIFT	2
-#define __SWP_TYPE_BITS		7
+#define __SWP_TYPE_SHIFT	3
+#define __SWP_TYPE_BITS		6
 #define __SWP_TYPE_MASK		((1 << __SWP_TYPE_BITS) - 1)
 #define __SWP_OFFSET_SHIFT	(__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
 
@@ -411,13 +418,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  *
  *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- *   <------------------------ offset -------------------------> 1 0
+ *   <----------------------- offset ------------------------> 1 0 0
  */
 #define pte_file(pte)		(pte_val(pte) & L_PTE_FILE)
-#define pte_to_pgoff(x)		(pte_val(x) >> 2)
-#define pgoff_to_pte(x)		__pte(((x) << 2) | L_PTE_FILE)
+#define pte_to_pgoff(x)		(pte_val(x) >> 3)
+#define pgoff_to_pte(x)		__pte(((x) << 3) | L_PTE_FILE)
 
-#define PTE_FILE_MAX_BITS	30
+#define PTE_FILE_MAX_BITS	29
 
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 /* FIXME: this is not correct */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 67b833c..bbecccd 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -82,6 +82,14 @@
 #define PSR_ENDSTATE	0
 #endif
 
+/* 
+ * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
+ * process is located in memory.
+ */
+#define PT_TEXT_ADDR		0x10000
+#define PT_DATA_ADDR		0x10004
+#define PT_TEXT_END_ADDR	0x10008
+
 #ifndef __ASSEMBLY__
 
 /*
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
index 537de4e..92ac61d 100644
--- a/arch/arm/include/asm/socket.h
+++ b/arch/arm/include/asm/socket.h
@@ -57,4 +57,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index d3a39b1..2dfb7d7 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -142,6 +142,7 @@ extern void vfp_sync_state(struct thread_info *thread);
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18
 #define TIF_FREEZE		19
+#define TIF_RESTORE_SIGMASK	20
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
@@ -150,6 +151,7 @@ extern void vfp_sync_state(struct thread_info *thread);
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
 #define _TIF_FREEZE		(1 << TIF_FREEZE)
+#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 
 /*
  * Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 0da9bc9..1d6bd40 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -17,6 +17,7 @@
 #include <asm/memory.h>
 #include <asm/domain.h>
 #include <asm/system.h>
+#include <asm/unified.h>
 
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
@@ -365,8 +366,10 @@ do {									\
 
 #define __put_user_asm_dword(x,__pu_addr,err)			\
 	__asm__ __volatile__(					\
-	"1:	strt	" __reg_oper1 ", [%1], #4\n"		\
-	"2:	strt	" __reg_oper0 ", [%1]\n"		\
+ ARM(	"1:	strt	" __reg_oper1 ", [%1], #4\n"	)	\
+ ARM(	"2:	strt	" __reg_oper0 ", [%1]\n"	)	\
+ THUMB(	"1:	strt	" __reg_oper1 ", [%1]\n"	)	\
+ THUMB(	"2:	strt	" __reg_oper0 ", [%1, #4]\n"	)	\
 	"3:\n"							\
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h
new file mode 100644
index 0000000..073e85b
--- /dev/null
+++ b/arch/arm/include/asm/unified.h
@@ -0,0 +1,126 @@
+/*
+ * include/asm-arm/unified.h - Unified Assembler Syntax helper macros
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_UNIFIED_H
+#define __ASM_UNIFIED_H
+
+#if defined(__ASSEMBLY__) && defined(CONFIG_ARM_ASM_UNIFIED)
+	.syntax unified
+#endif
+
+#ifdef CONFIG_THUMB2_KERNEL
+
+#if __GNUC__ < 4
+#error Thumb-2 kernel requires gcc >= 4
+#endif
+
+/* The CPSR bit describing the instruction set (Thumb) */
+#define PSR_ISETSTATE	PSR_T_BIT
+
+#define ARM(x...)
+#define THUMB(x...)	x
+#define W(instr)	instr.w
+#define BSYM(sym)	sym + 1
+
+#else	/* !CONFIG_THUMB2_KERNEL */
+
+/* The CPSR bit describing the instruction set (ARM) */
+#define PSR_ISETSTATE	0
+
+#define ARM(x...)	x
+#define THUMB(x...)
+#define W(instr)	instr
+#define BSYM(sym)	sym
+
+#endif	/* CONFIG_THUMB2_KERNEL */
+
+#ifndef CONFIG_ARM_ASM_UNIFIED
+
+/*
+ * If the unified assembly syntax isn't used (in ARM mode), these
+ * macros expand to an empty string
+ */
+#ifdef __ASSEMBLY__
+	.macro	it, cond
+	.endm
+	.macro	itt, cond
+	.endm
+	.macro	ite, cond
+	.endm
+	.macro	ittt, cond
+	.endm
+	.macro	itte, cond
+	.endm
+	.macro	itet, cond
+	.endm
+	.macro	itee, cond
+	.endm
+	.macro	itttt, cond
+	.endm
+	.macro	ittte, cond
+	.endm
+	.macro	ittet, cond
+	.endm
+	.macro	ittee, cond
+	.endm
+	.macro	itett, cond
+	.endm
+	.macro	itete, cond
+	.endm
+	.macro	iteet, cond
+	.endm
+	.macro	iteee, cond
+	.endm
+#else	/* !__ASSEMBLY__ */
+__asm__(
+"	.macro	it, cond\n"
+"	.endm\n"
+"	.macro	itt, cond\n"
+"	.endm\n"
+"	.macro	ite, cond\n"
+"	.endm\n"
+"	.macro	ittt, cond\n"
+"	.endm\n"
+"	.macro	itte, cond\n"
+"	.endm\n"
+"	.macro	itet, cond\n"
+"	.endm\n"
+"	.macro	itee, cond\n"
+"	.endm\n"
+"	.macro	itttt, cond\n"
+"	.endm\n"
+"	.macro	ittte, cond\n"
+"	.endm\n"
+"	.macro	ittet, cond\n"
+"	.endm\n"
+"	.macro	ittee, cond\n"
+"	.endm\n"
+"	.macro	itett, cond\n"
+"	.endm\n"
+"	.macro	itete, cond\n"
+"	.endm\n"
+"	.macro	iteet, cond\n"
+"	.endm\n"
+"	.macro	iteee, cond\n"
+"	.endm\n");
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* CONFIG_ARM_ASM_UNIFIED */
+
+#endif	/* !__ASM_UNIFIED_H */
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 0e97b8c..89f7ead 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -360,8 +360,8 @@
 #define __NR_readlinkat			(__NR_SYSCALL_BASE+332)
 #define __NR_fchmodat			(__NR_SYSCALL_BASE+333)
 #define __NR_faccessat			(__NR_SYSCALL_BASE+334)
-					/* 335 for pselect6 */
-					/* 336 for ppoll */
+#define __NR_pselect6			(__NR_SYSCALL_BASE+335)
+#define __NR_ppoll			(__NR_SYSCALL_BASE+336)
 #define __NR_unshare			(__NR_SYSCALL_BASE+337)
 #define __NR_set_robust_list		(__NR_SYSCALL_BASE+338)
 #define __NR_get_robust_list		(__NR_SYSCALL_BASE+339)
@@ -372,7 +372,7 @@
 #define __NR_vmsplice			(__NR_SYSCALL_BASE+343)
 #define __NR_move_pages			(__NR_SYSCALL_BASE+344)
 #define __NR_getcpu			(__NR_SYSCALL_BASE+345)
-					/* 346 for epoll_pwait */
+#define __NR_epoll_pwait		(__NR_SYSCALL_BASE+346)
 #define __NR_kexec_load			(__NR_SYSCALL_BASE+347)
 #define __NR_utimensat			(__NR_SYSCALL_BASE+348)
 #define __NR_signalfd			(__NR_SYSCALL_BASE+349)
@@ -390,7 +390,7 @@
 #define __NR_preadv			(__NR_SYSCALL_BASE+361)
 #define __NR_pwritev			(__NR_SYSCALL_BASE+362)
 #define __NR_rt_tgsigqueueinfo		(__NR_SYSCALL_BASE+363)
-#define __NR_perf_counter_open		(__NR_SYSCALL_BASE+364)
+#define __NR_perf_event_open		(__NR_SYSCALL_BASE+364)
 
 /*
  * The following SWIs are ARM private.
@@ -432,6 +432,7 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
 
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 #define __ARCH_WANT_SYS_TIME
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ff89d0b..3213c93 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -8,10 +8,12 @@ ifdef CONFIG_DYNAMIC_FTRACE
 CFLAGS_REMOVE_ftrace.o = -pg
 endif
 
+CFLAGS_REMOVE_return_address.o = -pg
+
 # Object file lists.
 
 obj-y		:= compat.o elf.o entry-armv.o entry-common.o irq.o \
-		   process.o ptrace.o setup.o signal.o \
+		   process.o ptrace.o return_address.o setup.o signal.o \
 		   sys_arm.o stacktrace.o time.o traps.o
 
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 531e186..0e62770 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -186,4 +186,5 @@ EXPORT_SYMBOL(_find_next_bit_be);
 
 #ifdef CONFIG_FUNCTION_TRACER
 EXPORT_SYMBOL(mcount);
+EXPORT_SYMBOL(__gnu_mcount_nc);
 #endif
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index f776e72..fafce1b 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -81,7 +81,7 @@
 		CALL(sys_ni_syscall)		/* was sys_ssetmask */
 /* 70 */	CALL(sys_setreuid16)
 		CALL(sys_setregid16)
-		CALL(sys_sigsuspend_wrapper)
+		CALL(sys_sigsuspend)
 		CALL(sys_sigpending)
 		CALL(sys_sethostname)
 /* 75 */	CALL(sys_setrlimit)
@@ -188,7 +188,7 @@
 		CALL(sys_rt_sigpending)
 		CALL(sys_rt_sigtimedwait)
 		CALL(sys_rt_sigqueueinfo)
-		CALL(sys_rt_sigsuspend_wrapper)
+		CALL(sys_rt_sigsuspend)
 /* 180 */	CALL(ABI(sys_pread64, sys_oabi_pread64))
 		CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
 		CALL(sys_chown16)
@@ -344,8 +344,8 @@
 		CALL(sys_readlinkat)
 		CALL(sys_fchmodat)
 		CALL(sys_faccessat)
-/* 335 */	CALL(sys_ni_syscall)		/* eventually pselect6 */
-		CALL(sys_ni_syscall)		/* eventually ppoll */
+/* 335 */	CALL(sys_pselect6)
+		CALL(sys_ppoll)
 		CALL(sys_unshare)
 		CALL(sys_set_robust_list)
 		CALL(sys_get_robust_list)
@@ -355,7 +355,7 @@
 		CALL(sys_vmsplice)
 		CALL(sys_move_pages)
 /* 345 */	CALL(sys_getcpu)
-		CALL(sys_ni_syscall)		/* eventually epoll_pwait */
+		CALL(sys_epoll_pwait)
 		CALL(sys_kexec_load)
 		CALL(sys_utimensat)
 		CALL(sys_signalfd)
@@ -373,7 +373,7 @@
 		CALL(sys_preadv)
 		CALL(sys_pwritev)
 		CALL(sys_rt_tgsigqueueinfo)
-		CALL(sys_perf_counter_open)
+		CALL(sys_perf_event_open)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
index 99995c2..769abe1 100644
--- a/arch/arm/kernel/crunch.c
+++ b/arch/arm/kernel/crunch.c
@@ -31,7 +31,7 @@ void crunch_task_release(struct thread_info *thread)
 
 static int crunch_enabled(u32 devcfg)
 {
-	return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE);
+	return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
 }
 
 static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
@@ -56,11 +56,16 @@ static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
 		break;
 
 	case THREAD_NOTIFY_SWITCH:
-		devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
+		devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
 		if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
-			devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
+			/*
+			 * We don't use ep93xx_syscon_swlocked_write() here
+			 * because we are on the context switch path and
+			 * preemption is already disabled.
+			 */
+			devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
 			__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-			__raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG);
+			__raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
 		}
 		break;
 	}
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index fc8af43..3d727a8 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -34,7 +34,7 @@
 	@
 	@ routine called with r0 = irq number, r1 = struct pt_regs *
 	@
-	adrne	lr, 1b
+	adrne	lr, BSYM(1b)
 	bne	asm_do_IRQ
 
 #ifdef CONFIG_SMP
@@ -46,13 +46,13 @@
 	 */
 	test_for_ipi r0, r6, r5, lr
 	movne	r0, sp
-	adrne	lr, 1b
+	adrne	lr, BSYM(1b)
 	bne	do_IPI
 
 #ifdef CONFIG_LOCAL_TIMERS
 	test_for_ltirq r0, r6, r5, lr
 	movne	r0, sp
-	adrne	lr, 1b
+	adrne	lr, BSYM(1b)
 	bne	do_local_timer
 #endif
 #endif
@@ -70,7 +70,10 @@
  */
 	.macro	inv_entry, reason
 	sub	sp, sp, #S_FRAME_SIZE
-	stmib	sp, {r1 - lr}
+ ARM(	stmib	sp, {r1 - lr}		)
+ THUMB(	stmia	sp, {r0 - r12}		)
+ THUMB(	str	sp, [sp, #S_SP]		)
+ THUMB(	str	lr, [sp, #S_LR]		)
 	mov	r1, #\reason
 	.endm
 
@@ -126,17 +129,24 @@ ENDPROC(__und_invalid)
 	.macro	svc_entry, stack_hole=0
  UNWIND(.fnstart		)
  UNWIND(.save {r0 - pc}		)
-	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole)
+	sub	sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+#ifdef CONFIG_THUMB2_KERNEL
+ SPFIX(	str	r0, [sp]	)	@ temporarily saved
+ SPFIX(	mov	r0, sp		)
+ SPFIX(	tst	r0, #4		)	@ test original stack alignment
+ SPFIX(	ldr	r0, [sp]	)	@ restored
+#else
  SPFIX(	tst	sp, #4		)
- SPFIX(	bicne	sp, sp, #4	)
-	stmib	sp, {r1 - r12}
+#endif
+ SPFIX(	subeq	sp, sp, #4	)
+	stmia	sp, {r1 - r12}
 
 	ldmia	r0, {r1 - r3}
-	add	r5, sp, #S_SP		@ here for interlock avoidance
+	add	r5, sp, #S_SP - 4	@ here for interlock avoidance
 	mov	r4, #-1			@  ""  ""      ""       ""
-	add	r0, sp, #(S_FRAME_SIZE + \stack_hole)
- SPFIX(	addne	r0, r0, #4	)
-	str	r1, [sp]		@ save the "real" r0 copied
+	add	r0, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+ SPFIX(	addeq	r0, r0, #4	)
+	str	r1, [sp, #-4]!		@ save the "real" r0 copied
 					@ from the exception stack
 
 	mov	r1, lr
@@ -151,6 +161,8 @@ ENDPROC(__und_invalid)
 	@  r4 - orig_r0 (see pt_regs definition in ptrace.h)
 	@
 	stmia	r5, {r0 - r4}
+
+	asm_trace_hardirqs_off
 	.endm
 
 	.align	5
@@ -196,9 +208,8 @@ __dabt_svc:
 	@
 	@ restore SPSR and restart the instruction
 	@
-	ldr	r0, [sp, #S_PSR]
-	msr	spsr_cxsf, r0
-	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+	ldr	r2, [sp, #S_PSR]
+	svc_exit r2				@ return from exception
  UNWIND(.fnend		)
 ENDPROC(__dabt_svc)
 
@@ -206,9 +217,6 @@ ENDPROC(__dabt_svc)
 __irq_svc:
 	svc_entry
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-	bl	trace_hardirqs_off
-#endif
 #ifdef CONFIG_PREEMPT
 	get_thread_info tsk
 	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
@@ -225,13 +233,12 @@ __irq_svc:
 	tst	r0, #_TIF_NEED_RESCHED
 	blne	svc_preempt
 #endif
-	ldr	r0, [sp, #S_PSR]		@ irqs are already disabled
-	msr	spsr_cxsf, r0
+	ldr	r4, [sp, #S_PSR]		@ irqs are already disabled
 #ifdef CONFIG_TRACE_IRQFLAGS
-	tst	r0, #PSR_I_BIT
+	tst	r4, #PSR_I_BIT
 	bleq	trace_hardirqs_on
 #endif
-	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+	svc_exit r4				@ return from exception
  UNWIND(.fnend		)
 ENDPROC(__irq_svc)
 
@@ -266,7 +273,7 @@ __und_svc:
 	@  r0 - instruction
 	@
 	ldr	r0, [r2, #-4]
-	adr	r9, 1f
+	adr	r9, BSYM(1f)
 	bl	call_fpe
 
 	mov	r0, sp				@ struct pt_regs *regs
@@ -280,9 +287,8 @@ __und_svc:
 	@
 	@ restore SPSR and restart the instruction
 	@
-	ldr	lr, [sp, #S_PSR]		@ Get SVC cpsr
-	msr	spsr_cxsf, lr
-	ldmia	sp, {r0 - pc}^			@ Restore SVC registers
+	ldr	r2, [sp, #S_PSR]		@ Get SVC cpsr
+	svc_exit r2				@ return from exception
  UNWIND(.fnend		)
 ENDPROC(__und_svc)
 
@@ -323,9 +329,8 @@ __pabt_svc:
 	@
 	@ restore SPSR and restart the instruction
 	@
-	ldr	r0, [sp, #S_PSR]
-	msr	spsr_cxsf, r0
-	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+	ldr	r2, [sp, #S_PSR]
+	svc_exit r2				@ return from exception
  UNWIND(.fnend		)
 ENDPROC(__pabt_svc)
 
@@ -353,7 +358,8 @@ ENDPROC(__pabt_svc)
  UNWIND(.fnstart	)
  UNWIND(.cantunwind	)	@ don't unwind the user space
 	sub	sp, sp, #S_FRAME_SIZE
-	stmib	sp, {r1 - r12}
+ ARM(	stmib	sp, {r1 - r12}	)
+ THUMB(	stmia	sp, {r0 - r12}	)
 
 	ldmia	r0, {r1 - r3}
 	add	r0, sp, #S_PC		@ here for interlock avoidance
@@ -372,7 +378,8 @@ ENDPROC(__pabt_svc)
 	@ Also, separately save sp_usr and lr_usr
 	@
 	stmia	r0, {r2 - r4}
-	stmdb	r0, {sp, lr}^
+ ARM(	stmdb	r0, {sp, lr}^			)
+ THUMB(	store_user_sp_lr r0, r1, S_SP - S_PC	)
 
 	@
 	@ Enable the alignment trap while in kernel mode
@@ -383,6 +390,8 @@ ENDPROC(__pabt_svc)
 	@ Clear FP to mark the first stack frame
 	@
 	zero_fp
+
+	asm_trace_hardirqs_off
 	.endm
 
 	.macro	kuser_cmpxchg_check
@@ -427,7 +436,7 @@ __dabt_usr:
 	@
 	enable_irq
 	mov	r2, sp
-	adr	lr, ret_from_exception
+	adr	lr, BSYM(ret_from_exception)
 	b	do_DataAbort
  UNWIND(.fnend		)
 ENDPROC(__dabt_usr)
@@ -437,9 +446,6 @@ __irq_usr:
 	usr_entry
 	kuser_cmpxchg_check
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-	bl	trace_hardirqs_off
-#endif
 	get_thread_info tsk
 #ifdef CONFIG_PREEMPT
 	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
@@ -452,7 +458,9 @@ __irq_usr:
 	ldr	r0, [tsk, #TI_PREEMPT]
 	str	r8, [tsk, #TI_PREEMPT]
 	teq	r0, r7
-	strne	r0, [r0, -r0]
+ ARM(	strne	r0, [r0, -r0]	)
+ THUMB(	movne	r0, #0		)
+ THUMB(	strne	r0, [r0]	)
 #endif
 #ifdef CONFIG_TRACE_IRQFLAGS
 	bl	trace_hardirqs_on
@@ -476,9 +484,10 @@ __und_usr:
 	@
 	@  r0 - instruction
 	@
-	adr	r9, ret_from_exception
-	adr	lr, __und_usr_unknown
+	adr	r9, BSYM(ret_from_exception)
+	adr	lr, BSYM(__und_usr_unknown)
 	tst	r3, #PSR_T_BIT			@ Thumb mode?
+	itet	eq				@ explicit IT needed for the 1f label
 	subeq	r4, r2, #4			@ ARM instr at LR - 4
 	subne	r4, r2, #2			@ Thumb instr at LR - 2
 1:	ldreqt	r0, [r4]
@@ -488,7 +497,10 @@ __und_usr:
 	beq	call_fpe
 	@ Thumb instruction
 #if __LINUX_ARM_ARCH__ >= 7
-2:	ldrht	r5, [r4], #2
+2:
+ ARM(	ldrht	r5, [r4], #2	)
+ THUMB(	ldrht	r5, [r4]	)
+ THUMB(	add	r4, r4, #2	)
 	and	r0, r5, #0xf800			@ mask bits 111x x... .... ....
 	cmp	r0, #0xe800			@ 32bit instruction if xx != 0
 	blo	__und_usr_unknown
@@ -577,9 +589,11 @@ call_fpe:
 	moveq	pc, lr
 	get_thread_info r10			@ get current thread
 	and	r8, r0, #0x00000f00		@ mask out CP number
+ THUMB(	lsr	r8, r8, #8		)
 	mov	r7, #1
 	add	r6, r10, #TI_USED_CP
-	strb	r7, [r6, r8, lsr #8]		@ set appropriate used_cp[]
+ ARM(	strb	r7, [r6, r8, lsr #8]	)	@ set appropriate used_cp[]
+ THUMB(	strb	r7, [r6, r8]		)	@ set appropriate used_cp[]
 #ifdef CONFIG_IWMMXT
 	@ Test if we need to give access to iWMMXt coprocessors
 	ldr	r5, [r10, #TI_FLAGS]
@@ -587,36 +601,38 @@ call_fpe:
 	movcss	r7, r5, lsr #(TIF_USING_IWMMXT + 1)
 	bcs	iwmmxt_task_enable
 #endif
-	add	pc, pc, r8, lsr #6
-	mov	r0, r0
-
-	mov	pc, lr				@ CP#0
-	b	do_fpe				@ CP#1 (FPE)
-	b	do_fpe				@ CP#2 (FPE)
-	mov	pc, lr				@ CP#3
+ ARM(	add	pc, pc, r8, lsr #6	)
+ THUMB(	lsl	r8, r8, #2		)
+ THUMB(	add	pc, r8			)
+	nop
+
+	W(mov)	pc, lr				@ CP#0
+	W(b)	do_fpe				@ CP#1 (FPE)
+	W(b)	do_fpe				@ CP#2 (FPE)
+	W(mov)	pc, lr				@ CP#3
 #ifdef CONFIG_CRUNCH
 	b	crunch_task_enable		@ CP#4 (MaverickCrunch)
 	b	crunch_task_enable		@ CP#5 (MaverickCrunch)
 	b	crunch_task_enable		@ CP#6 (MaverickCrunch)
 #else
-	mov	pc, lr				@ CP#4
-	mov	pc, lr				@ CP#5
-	mov	pc, lr				@ CP#6
+	W(mov)	pc, lr				@ CP#4
+	W(mov)	pc, lr				@ CP#5
+	W(mov)	pc, lr				@ CP#6
 #endif
-	mov	pc, lr				@ CP#7
-	mov	pc, lr				@ CP#8
-	mov	pc, lr				@ CP#9
+	W(mov)	pc, lr				@ CP#7
+	W(mov)	pc, lr				@ CP#8
+	W(mov)	pc, lr				@ CP#9
 #ifdef CONFIG_VFP
-	b	do_vfp				@ CP#10 (VFP)
-	b	do_vfp				@ CP#11 (VFP)
+	W(b)	do_vfp				@ CP#10 (VFP)
+	W(b)	do_vfp				@ CP#11 (VFP)
 #else
-	mov	pc, lr				@ CP#10 (VFP)
-	mov	pc, lr				@ CP#11 (VFP)
+	W(mov)	pc, lr				@ CP#10 (VFP)
+	W(mov)	pc, lr				@ CP#11 (VFP)
 #endif
-	mov	pc, lr				@ CP#12
-	mov	pc, lr				@ CP#13
-	mov	pc, lr				@ CP#14 (Debug)
-	mov	pc, lr				@ CP#15 (Control)
+	W(mov)	pc, lr				@ CP#12
+	W(mov)	pc, lr				@ CP#13
+	W(mov)	pc, lr				@ CP#14 (Debug)
+	W(mov)	pc, lr				@ CP#15 (Control)
 
 #ifdef CONFIG_NEON
 	.align	6
@@ -667,7 +683,7 @@ no_fp:	mov	pc, lr
 __und_usr_unknown:
 	enable_irq
 	mov	r0, sp
-	adr	lr, ret_from_exception
+	adr	lr, BSYM(ret_from_exception)
 	b	do_undefinstr
 ENDPROC(__und_usr_unknown)
 
@@ -711,7 +727,10 @@ ENTRY(__switch_to)
  UNWIND(.cantunwind	)
 	add	ip, r1, #TI_CPU_SAVE
 	ldr	r3, [r2, #TI_TP_VALUE]
-	stmia	ip!, {r4 - sl, fp, sp, lr}	@ Store most regs on stack
+ ARM(	stmia	ip!, {r4 - sl, fp, sp, lr} )	@ Store most regs on stack
+ THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
+ THUMB(	str	sp, [ip], #4		   )
+ THUMB(	str	lr, [ip], #4		   )
 #ifdef CONFIG_MMU
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
@@ -736,8 +755,12 @@ ENTRY(__switch_to)
 	ldr	r0, =thread_notify_head
 	mov	r1, #THREAD_NOTIFY_SWITCH
 	bl	atomic_notifier_call_chain
+ THUMB(	mov	ip, r4			   )
 	mov	r0, r5
-	ldmia	r4, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
+ ARM(	ldmia	r4, {r4 - sl, fp, sp, pc}  )	@ Load all regs saved previously
+ THUMB(	ldmia	ip!, {r4 - sl, fp}	   )	@ Load all regs saved previously
+ THUMB(	ldr	sp, [ip], #4		   )
+ THUMB(	ldr	pc, [ip]		   )
  UNWIND(.fnend		)
 ENDPROC(__switch_to)
 
@@ -772,6 +795,7 @@ ENDPROC(__switch_to)
  * if your compiled code is not going to use the new instructions for other
  * purpose.
  */
+ THUMB(	.arm	)
 
 	.macro	usr_ret, reg
 #ifdef CONFIG_ARM_THUMB
@@ -1020,6 +1044,7 @@ __kuser_helper_version:				@ 0xffff0ffc
 	.globl	__kuser_helper_end
 __kuser_helper_end:
 
+ THUMB(	.thumb	)
 
 /*
  * Vector stubs.
@@ -1054,17 +1079,23 @@ vector_\name:
 	@ Prepare for SVC32 mode.  IRQs remain disabled.
 	@
 	mrs	r0, cpsr
-	eor	r0, r0, #(\mode ^ SVC_MODE)
+	eor	r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
 	msr	spsr_cxsf, r0
 
 	@
 	@ the branch table must immediately follow this code
 	@
 	and	lr, lr, #0x0f
+ THUMB(	adr	r0, 1f			)
+ THUMB(	ldr	lr, [r0, lr, lsl #2]	)
 	mov	r0, sp
-	ldr	lr, [pc, lr, lsl #2]
+ ARM(	ldr	lr, [pc, lr, lsl #2]	)
 	movs	pc, lr			@ branch to handler in SVC mode
 ENDPROC(vector_\name)
+
+	.align	2
+	@ handler addresses follow this label
+1:
 	.endm
 
 	.globl	__stubs_start
@@ -1202,14 +1233,16 @@ __stubs_end:
 
 	.globl	__vectors_start
 __vectors_start:
-	swi	SYS_ERROR0
-	b	vector_und + stubs_offset
-	ldr	pc, .LCvswi + stubs_offset
-	b	vector_pabt + stubs_offset
-	b	vector_dabt + stubs_offset
-	b	vector_addrexcptn + stubs_offset
-	b	vector_irq + stubs_offset
-	b	vector_fiq + stubs_offset
+ ARM(	swi	SYS_ERROR0	)
+ THUMB(	svc	#0		)
+ THUMB(	nop			)
+	W(b)	vector_und + stubs_offset
+	W(ldr)	pc, .LCvswi + stubs_offset
+	W(b)	vector_pabt + stubs_offset
+	W(b)	vector_dabt + stubs_offset
+	W(b)	vector_addrexcptn + stubs_offset
+	W(b)	vector_irq + stubs_offset
+	W(b)	vector_fiq + stubs_offset
 
 	.globl	__vectors_end
 __vectors_end:
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 7813ab7..807cfeb 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -33,14 +33,7 @@ ret_fast_syscall:
 	/* perform architecture specific actions before user return */
 	arch_ret_to_user r1, lr
 
-	@ fast_restore_user_regs
-	ldr	r1, [sp, #S_OFF + S_PSR]	@ get calling cpsr
-	ldr	lr, [sp, #S_OFF + S_PC]!	@ get pc
-	msr	spsr_cxsf, r1			@ save in spsr_svc
-	ldmdb	sp, {r1 - lr}^			@ get calling r1 - lr
-	mov	r0, r0
-	add	sp, sp, #S_FRAME_SIZE - S_PC
-	movs	pc, lr				@ return & move spsr_svc into cpsr
+	restore_user_regs fast = 1, offset = S_OFF
  UNWIND(.fnend		)
 
 /*
@@ -73,14 +66,7 @@ no_work_pending:
 	/* perform architecture specific actions before user return */
 	arch_ret_to_user r1, lr
 
-	@ slow_restore_user_regs
-	ldr	r1, [sp, #S_PSR]		@ get calling cpsr
-	ldr	lr, [sp, #S_PC]!		@ get pc
-	msr	spsr_cxsf, r1			@ save in spsr_svc
-	ldmdb	sp, {r0 - lr}^			@ get calling r0 - lr
-	mov	r0, r0
-	add	sp, sp, #S_FRAME_SIZE - S_PC
-	movs	pc, lr				@ return & move spsr_svc into cpsr
+	restore_user_regs fast = 0, offset = 0
 ENDPROC(ret_to_user)
 
 /*
@@ -132,6 +118,25 @@ ftrace_call:
 
 #else
 
+ENTRY(__gnu_mcount_nc)
+	stmdb sp!, {r0-r3, lr}
+	ldr r0, =ftrace_trace_function
+	ldr r2, [r0]
+	adr r0, ftrace_stub
+	cmp r0, r2
+	bne gnu_trace
+	ldmia sp!, {r0-r3, ip, lr}
+	bx ip
+
+gnu_trace:
+	ldr r1, [sp, #20]			@ lr of instrumented routine
+	mov r0, lr
+	sub r0, r0, #MCOUNT_INSN_SIZE
+	mov lr, pc
+	mov pc, r2
+	ldmia sp!, {r0-r3, ip, lr}
+	bx ip
+
 ENTRY(mcount)
 	stmdb sp!, {r0-r3, lr}
 	ldr r0, =ftrace_trace_function
@@ -182,8 +187,10 @@ ftrace_stub:
 ENTRY(vector_swi)
 	sub	sp, sp, #S_FRAME_SIZE
 	stmia	sp, {r0 - r12}			@ Calling r0 - r12
-	add	r8, sp, #S_PC
-	stmdb	r8, {sp, lr}^			@ Calling sp, lr
+ ARM(	add	r8, sp, #S_PC		)
+ ARM(	stmdb	r8, {sp, lr}^		)	@ Calling sp, lr
+ THUMB(	mov	r8, sp			)
+ THUMB(	store_user_sp_lr r8, r10, S_SP	)	@ calling sp, lr
 	mrs	r8, spsr			@ called from non-FIQ mode, so ok.
 	str	lr, [sp, #S_PC]			@ Save calling PC
 	str	r8, [sp, #S_PSR]		@ Save CPSR
@@ -272,7 +279,7 @@ ENTRY(vector_swi)
 	bne	__sys_trace
 
 	cmp	scno, #NR_syscalls		@ check upper syscall limit
-	adr	lr, ret_fast_syscall		@ return address
+	adr	lr, BSYM(ret_fast_syscall)	@ return address
 	ldrcc	pc, [tbl, scno, lsl #2]		@ call sys_* routine
 
 	add	r1, sp, #S_OFF
@@ -293,7 +300,7 @@ __sys_trace:
 	mov	r0, #0				@ trace entry [IP = 0]
 	bl	syscall_trace
 
-	adr	lr, __sys_trace_return		@ return address
+	adr	lr, BSYM(__sys_trace_return)	@ return address
 	mov	scno, r0			@ syscall number (possibly new)
 	add	r1, sp, #S_R0 + S_OFF		@ pointer to regs
 	cmp	scno, #NR_syscalls		@ check upper syscall limit
@@ -373,16 +380,6 @@ sys_clone_wrapper:
 		b	sys_clone
 ENDPROC(sys_clone_wrapper)
 
-sys_sigsuspend_wrapper:
-		add	r3, sp, #S_OFF
-		b	sys_sigsuspend
-ENDPROC(sys_sigsuspend_wrapper)
-
-sys_rt_sigsuspend_wrapper:
-		add	r2, sp, #S_OFF
-		b	sys_rt_sigsuspend
-ENDPROC(sys_rt_sigsuspend_wrapper)
-
 sys_sigreturn_wrapper:
 		add	r0, sp, #S_OFF
 		b	sys_sigreturn
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 87ab4e1..a4eaf4f 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -36,11 +36,6 @@
 #endif
 	.endm
 
-	.macro	get_thread_info, rd
-	mov	\rd, sp, lsr #13
-	mov	\rd, \rd, lsl #13
-	.endm
-
 	.macro	alignment_trap, rtemp
 #ifdef CONFIG_ALIGNMENT_TRAP
 	ldr	\rtemp, .LCcralign
@@ -49,6 +44,93 @@
 #endif
 	.endm
 
+	@
+	@ Store/load the USER SP and LR registers by switching to the SYS
+	@ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not
+	@ available. Should only be called from SVC mode
+	@
+	.macro	store_user_sp_lr, rd, rtemp, offset = 0
+	mrs	\rtemp, cpsr
+	eor	\rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+	msr	cpsr_c, \rtemp			@ switch to the SYS mode
+
+	str	sp, [\rd, #\offset]		@ save sp_usr
+	str	lr, [\rd, #\offset + 4]		@ save lr_usr
+
+	eor	\rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+	msr	cpsr_c, \rtemp			@ switch back to the SVC mode
+	.endm
+
+	.macro	load_user_sp_lr, rd, rtemp, offset = 0
+	mrs	\rtemp, cpsr
+	eor	\rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+	msr	cpsr_c, \rtemp			@ switch to the SYS mode
+
+	ldr	sp, [\rd, #\offset]		@ load sp_usr
+	ldr	lr, [\rd, #\offset + 4]		@ load lr_usr
+
+	eor	\rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+	msr	cpsr_c, \rtemp			@ switch back to the SVC mode
+	.endm
+
+#ifndef CONFIG_THUMB2_KERNEL
+	.macro	svc_exit, rpsr
+	msr	spsr_cxsf, \rpsr
+	ldmia	sp, {r0 - pc}^			@ load r0 - pc, cpsr
+	.endm
+
+	.macro	restore_user_regs, fast = 0, offset = 0
+	ldr	r1, [sp, #\offset + S_PSR]	@ get calling cpsr
+	ldr	lr, [sp, #\offset + S_PC]!	@ get pc
+	msr	spsr_cxsf, r1			@ save in spsr_svc
+	.if	\fast
+	ldmdb	sp, {r1 - lr}^			@ get calling r1 - lr
+	.else
+	ldmdb	sp, {r0 - lr}^			@ get calling r0 - lr
+	.endif
+	add	sp, sp, #S_FRAME_SIZE - S_PC
+	movs	pc, lr				@ return & move spsr_svc into cpsr
+	.endm
+
+	.macro	get_thread_info, rd
+	mov	\rd, sp, lsr #13
+	mov	\rd, \rd, lsl #13
+	.endm
+#else	/* CONFIG_THUMB2_KERNEL */
+	.macro	svc_exit, rpsr
+	ldr	r0, [sp, #S_SP]			@ top of the stack
+	ldr	r1, [sp, #S_PC]			@ return address
+	tst	r0, #4				@ orig stack 8-byte aligned?
+	stmdb	r0, {r1, \rpsr}			@ rfe context
+	ldmia	sp, {r0 - r12}
+	ldr	lr, [sp, #S_LR]
+	addeq	sp, sp, #S_FRAME_SIZE - 8	@ aligned
+	addne	sp, sp, #S_FRAME_SIZE - 4	@ not aligned
+	rfeia	sp!
+	.endm
+
+	.macro	restore_user_regs, fast = 0, offset = 0
+	mov	r2, sp
+	load_user_sp_lr r2, r3, \offset + S_SP	@ calling sp, lr
+	ldr	r1, [sp, #\offset + S_PSR]	@ get calling cpsr
+	ldr	lr, [sp, #\offset + S_PC]	@ get pc
+	add	sp, sp, #\offset + S_SP
+	msr	spsr_cxsf, r1			@ save in spsr_svc
+	.if	\fast
+	ldmdb	sp, {r1 - r12}			@ get calling r1 - r12
+	.else
+	ldmdb	sp, {r0 - r12}			@ get calling r0 - r12
+	.endif
+	add	sp, sp, #S_FRAME_SIZE - S_SP
+	movs	pc, lr				@ return & move spsr_svc into cpsr
+	.endm
+
+	.macro	get_thread_info, rd
+	mov	\rd, sp
+	lsr	\rd, \rd, #13
+	mov	\rd, \rd, lsl #13
+	.endm
+#endif	/* !CONFIG_THUMB2_KERNEL */
 
 /*
  * These are the registers used in the syscall handler, and allow us to
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 991952c..93ad576 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -14,6 +14,7 @@
 #define ATAG_CORE 0x54410001
 #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
 
+	.align	2
 	.type	__switch_data, %object
 __switch_data:
 	.long	__mmap_switched
@@ -51,7 +52,9 @@ __mmap_switched:
 	strcc	fp, [r6],#4
 	bcc	1b
 
-	ldmia	r3, {r4, r5, r6, r7, sp}
+ ARM(	ldmia	r3, {r4, r5, r6, r7, sp})
+ THUMB(	ldmia	r3, {r4, r5, r6, r7}	)
+ THUMB(	ldr	sp, [r3, #16]		)
 	str	r9, [r4]			@ Save processor ID
 	str	r1, [r5]			@ Save machine type
 	str	r2, [r6]			@ Save atags pointer
@@ -155,7 +158,8 @@ ENDPROC(__error)
  */
 __lookup_processor_type:
 	adr	r3, 3f
-	ldmda	r3, {r5 - r7}
+	ldmia	r3, {r5 - r7}
+	add	r3, r3, #8
 	sub	r3, r3, r7			@ get offset between virt&phys
 	add	r5, r5, r3			@ convert virt addresses to
 	add	r6, r6, r3			@ physical address space
@@ -185,9 +189,10 @@ ENDPROC(lookup_processor_type)
  * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for
  * more information about the __proc_info and __arch_info structures.
  */
-	.long	__proc_info_begin
+	.align	2
+3:	.long	__proc_info_begin
 	.long	__proc_info_end
-3:	.long	.
+4:	.long	.
 	.long	__arch_info_begin
 	.long	__arch_info_end
 
@@ -203,7 +208,7 @@ ENDPROC(lookup_processor_type)
  *  r5 = mach_info pointer in physical address space
  */
 __lookup_machine_type:
-	adr	r3, 3b
+	adr	r3, 4b
 	ldmia	r3, {r4, r5, r6}
 	sub	r3, r3, r4			@ get offset between virt&phys
 	add	r5, r5, r3			@ convert virt addresses to
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index cc87e17..e5dfc28 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -34,7 +34,7 @@
  */
 	.section ".text.head", "ax"
 ENTRY(stext)
-	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
+	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
 						@ and irqs disabled
 #ifndef CONFIG_CPU_CP15
 	ldr	r9, =CONFIG_PROCESSOR_ID
@@ -50,8 +50,10 @@ ENTRY(stext)
 
 	ldr	r13, __switch_data		@ address to jump to after
 						@ the initialization is done
-	adr	lr, __after_proc_init		@ return (PIC) address
-	add	pc, r10, #PROCINFO_INITFUNC
+	adr	lr, BSYM(__after_proc_init)	@ return (PIC) address
+ ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
+ THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
+ THUMB(	mov	pc, r12				)
 ENDPROC(stext)
 
 /*
@@ -59,7 +61,10 @@ ENDPROC(stext)
  */
 __after_proc_init:
 #ifdef CONFIG_CPU_CP15
-	mrc	p15, 0, r0, c1, c0, 0		@ read control reg
+	/*
+	 * CP15 system control register value returned in r0 from
+	 * the CPU init function.
+	 */
 #ifdef CONFIG_ALIGNMENT_TRAP
 	orr	r0, r0, #CR_A
 #else
@@ -82,7 +87,8 @@ __after_proc_init:
 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
 #endif /* CONFIG_CPU_CP15 */
 
-	mov	pc, r13				@ clear the BSS and jump
+	mov	r3, r13
+	mov	pc, r3				@ clear the BSS and jump
 						@ to start_kernel
 ENDPROC(__after_proc_init)
 	.ltorg
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 21e17dc..38ccbe1 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -76,7 +76,7 @@
  */
 	.section ".text.head", "ax"
 ENTRY(stext)
-	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
+	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
 						@ and irqs disabled
 	mrc	p15, 0, r9, c0, c0		@ get processor id
 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
@@ -97,8 +97,10 @@ ENTRY(stext)
 	 */
 	ldr	r13, __switch_data		@ address to jump to after
 						@ mmu has been enabled
-	adr	lr, __enable_mmu		@ return (PIC) address
-	add	pc, r10, #PROCINFO_INITFUNC
+	adr	lr, BSYM(__enable_mmu)		@ return (PIC) address
+ ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
+ THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
+ THUMB(	mov	pc, r12				)
 ENDPROC(stext)
 
 #if defined(CONFIG_SMP)
@@ -110,7 +112,7 @@ ENTRY(secondary_startup)
 	 * the processor type - there is no need to check the machine type
 	 * as it has already been validated by the primary processor.
 	 */
-	msr	cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
+	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
 	mrc	p15, 0, r9, c0, c0		@ get processor id
 	bl	__lookup_processor_type
 	movs	r10, r5				@ invalid processor?
@@ -121,12 +123,15 @@ ENTRY(secondary_startup)
 	 * Use the page tables supplied from  __cpu_up.
 	 */
 	adr	r4, __secondary_data
-	ldmia	r4, {r5, r7, r13}		@ address to jump to after
+	ldmia	r4, {r5, r7, r12}		@ address to jump to after
 	sub	r4, r4, r5			@ mmu has been enabled
 	ldr	r4, [r7, r4]			@ get secondary_data.pgdir
-	adr	lr, __enable_mmu		@ return address
-	add	pc, r10, #PROCINFO_INITFUNC	@ initialise processor
-						@ (return control reg)
+	adr	lr, BSYM(__enable_mmu)		@ return address
+	mov	r13, r12			@ __secondary_switched address
+ ARM(	add	pc, r10, #PROCINFO_INITFUNC	) @ initialise processor
+						  @ (return control reg)
+ THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
+ THUMB(	mov	pc, r12				)
 ENDPROC(secondary_startup)
 
 	/*
@@ -193,8 +198,8 @@ __turn_mmu_on:
 	mcr	p15, 0, r0, c1, c0, 0		@ write control reg
 	mrc	p15, 0, r3, c0, c0, 0		@ read id reg
 	mov	r3, r3
-	mov	r3, r3
-	mov	pc, r13
+	mov	r3, r13
+	mov	pc, r3
 ENDPROC(__turn_mmu_on)
 
 
@@ -235,7 +240,8 @@ __create_page_tables:
 	 * will be removed by paging_init().  We use our current program
 	 * counter to determine corresponding section base address.
 	 */
-	mov	r6, pc, lsr #20			@ start of kernel section
+	mov	r6, pc
+	mov	r6, r6, lsr #20			@ start of kernel section
 	orr	r3, r7, r6, lsl #20		@ flags + kernel base
 	str	r3, [r4, r6, lsl #2]		@ identity mapping
 
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b7c3490..c9a8619 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -86,7 +86,7 @@ int show_interrupts(struct seq_file *p, void *v)
 unlock:
 		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	} else if (i == NR_IRQS) {
-#ifdef CONFIG_ARCH_ACORN
+#ifdef CONFIG_FIQ
 		show_fiq_list(p, v);
 #endif
 #ifdef CONFIG_SMP
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index bac03c8..f28c5e9 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -102,6 +102,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 		unsigned long loc;
 		Elf32_Sym *sym;
 		s32 offset;
+		u32 upper, lower, sign, j1, j2;
 
 		offset = ELF32_R_SYM(rel->r_info);
 		if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
@@ -184,6 +185,58 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 					(offset & 0x0fff);
 			break;
 
+		case R_ARM_THM_CALL:
+		case R_ARM_THM_JUMP24:
+			upper = *(u16 *)loc;
+			lower = *(u16 *)(loc + 2);
+
+			/*
+			 * 25 bit signed address range (Thumb-2 BL and B.W
+			 * instructions):
+			 *   S:I1:I2:imm10:imm11:0
+			 * where:
+			 *   S     = upper[10]   = offset[24]
+			 *   I1    = ~(J1 ^ S)   = offset[23]
+			 *   I2    = ~(J2 ^ S)   = offset[22]
+			 *   imm10 = upper[9:0]  = offset[21:12]
+			 *   imm11 = lower[10:0] = offset[11:1]
+			 *   J1    = lower[13]
+			 *   J2    = lower[11]
+			 */
+			sign = (upper >> 10) & 1;
+			j1 = (lower >> 13) & 1;
+			j2 = (lower >> 11) & 1;
+			offset = (sign << 24) | ((~(j1 ^ sign) & 1) << 23) |
+				((~(j2 ^ sign) & 1) << 22) |
+				((upper & 0x03ff) << 12) |
+				((lower & 0x07ff) << 1);
+			if (offset & 0x01000000)
+				offset -= 0x02000000;
+			offset += sym->st_value - loc;
+
+			/* only Thumb addresses allowed (no interworking) */
+			if (!(offset & 1) ||
+			    offset <= (s32)0xff000000 ||
+			    offset >= (s32)0x01000000) {
+				printk(KERN_ERR
+				       "%s: relocation out of range, section "
+				       "%d reloc %d sym '%s'\n", module->name,
+				       relindex, i, strtab + sym->st_name);
+				return -ENOEXEC;
+			}
+
+			sign = (offset >> 24) & 1;
+			j1 = sign ^ (~(offset >> 23) & 1);
+			j2 = sign ^ (~(offset >> 22) & 1);
+			*(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) |
+					    ((offset >> 12) & 0x03ff));
+			*(u16 *)(loc + 2) = (u16)((lower & 0xd000) |
+						  (j1 << 13) | (j2 << 11) |
+						  ((offset >> 1) & 0x07ff));
+			upper = *(u16 *)loc;
+			lower = *(u16 *)(loc + 2);
+			break;
+
 		default:
 			printk(KERN_ERR "%s: unknown relocation: %u\n",
 			       module->name, ELF32_R_TYPE(rel->r_info));
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 39196df..790fbee 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -388,7 +388,7 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 	regs.ARM_r2 = (unsigned long)fn;
 	regs.ARM_r3 = (unsigned long)kernel_thread_exit;
 	regs.ARM_pc = (unsigned long)kernel_thread_helper;
-	regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE;
+	regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
 
 	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 }
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 89882a1..a2ea385 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -521,7 +521,13 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
 		return -EIO;
 
 	tmp = 0;
-	if (off < sizeof(struct pt_regs))
+	if (off == PT_TEXT_ADDR)
+		tmp = tsk->mm->start_code;
+	else if (off == PT_DATA_ADDR)
+		tmp = tsk->mm->start_data;
+	else if (off == PT_TEXT_END_ADDR)
+		tmp = tsk->mm->end_code;
+	else if (off < sizeof(struct pt_regs))
 		tmp = get_user_reg(tsk, off >> 2);
 
 	return put_user(tmp, ret);
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
new file mode 100644
index 0000000..df246da
--- /dev/null
+++ b/arch/arm/kernel/return_address.c
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/kernel/return_address.c
+ *
+ * Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ * for Pengutronix
+ *
+ * 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>
+
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+#include <linux/sched.h>
+
+#include <asm/stacktrace.h>
+
+struct return_address_data {
+	unsigned int level;
+	void *addr;
+};
+
+static int save_return_addr(struct stackframe *frame, void *d)
+{
+	struct return_address_data *data = d;
+
+	if (!data->level) {
+		data->addr = (void *)frame->lr;
+
+		return 1;
+	} else {
+		--data->level;
+		return 0;
+	}
+}
+
+void *return_address(unsigned int level)
+{
+	struct return_address_data data;
+	struct stackframe frame;
+	register unsigned long current_sp asm ("sp");
+
+	data.level = level + 1;
+
+	frame.fp = (unsigned long)__builtin_frame_address(0);
+	frame.sp = current_sp;
+	frame.lr = (unsigned long)__builtin_return_address(0);
+	frame.pc = (unsigned long)return_address;
+
+	walk_stackframe(&frame, save_return_addr, &data);
+
+	if (!data.level)
+		return data.addr;
+	else
+		return NULL;
+}
+
+#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
+
+#if defined(CONFIG_ARM_UNWIND)
+#warning "TODO: return_address should use unwind tables"
+#endif
+
+void *return_address(unsigned int level)
+{
+	return NULL;
+}
+
+#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
+
+EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index bc5e412..d4d4f77 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 
+#include <asm/unified.h>
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/elf.h>
@@ -327,25 +328,38 @@ void cpu_init(void)
 	}
 
 	/*
+	 * Define the placement constraint for the inline asm directive below.
+	 * In Thumb-2, msr with an immediate value is not allowed.
+	 */
+#ifdef CONFIG_THUMB2_KERNEL
+#define PLC	"r"
+#else
+#define PLC	"I"
+#endif
+
+	/*
 	 * setup stacks for re-entrant exception handlers
 	 */
 	__asm__ (
 	"msr	cpsr_c, %1\n\t"
-	"add	sp, %0, %2\n\t"
+	"add	r14, %0, %2\n\t"
+	"mov	sp, r14\n\t"
 	"msr	cpsr_c, %3\n\t"
-	"add	sp, %0, %4\n\t"
+	"add	r14, %0, %4\n\t"
+	"mov	sp, r14\n\t"
 	"msr	cpsr_c, %5\n\t"
-	"add	sp, %0, %6\n\t"
+	"add	r14, %0, %6\n\t"
+	"mov	sp, r14\n\t"
 	"msr	cpsr_c, %7"
 	    :
 	    : "r" (stk),
-	      "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
+	      PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
 	      "I" (offsetof(struct stack, irq[0])),
-	      "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
+	      PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
 	      "I" (offsetof(struct stack, abt[0])),
-	      "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
+	      PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
 	      "I" (offsetof(struct stack, und[0])),
-	      "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+	      PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
 	    : "r14");
 }
 
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index b76fe06..1423a34 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -48,57 +48,22 @@ const unsigned long sigreturn_codes[7] = {
 	MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
 };
 
-static int do_signal(sigset_t *oldset, struct pt_regs * regs, int syscall);
-
 /*
  * atomically swap in the new signal mask, and wait for a signal.
  */
-asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
 {
-	sigset_t saveset;
-
 	mask &= _BLOCKABLE;
 	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
+	current->saved_sigmask = current->blocked;
 	siginitset(&current->blocked, mask);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
-	regs->ARM_r0 = -EINTR;
-
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs, 0))
-			return regs->ARM_r0;
-	}
-}
-
-asmlinkage int
-sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
-{
-	sigset_t saveset, newset;
-
-	/* XXX: Don't preclude handling different sized sigset_t's. */
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&newset, unewset, sizeof(newset)))
-		return -EFAULT;
-	sigdelsetmask(&newset, ~_BLOCKABLE);
-
-	spin_lock_irq(&current->sighand->siglock);
-	saveset = current->blocked;
-	current->blocked = newset;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-	regs->ARM_r0 = -EINTR;
 
-	while (1) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		if (do_signal(&saveset, regs, 0))
-			return regs->ARM_r0;
-	}
+	current->state = TASK_INTERRUPTIBLE;
+	schedule();
+	set_restore_sigmask();
+	return -ERESTARTNOHAND;
 }
 
 asmlinkage int 
@@ -546,7 +511,7 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
 /*
  * OK, we're invoking a handler
  */	
-static void
+static int
 handle_signal(unsigned long sig, struct k_sigaction *ka,
 	      siginfo_t *info, sigset_t *oldset,
 	      struct pt_regs * regs, int syscall)
@@ -597,7 +562,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
 
 	if (ret != 0) {
 		force_sigsegv(sig, tsk);
-		return;
+		return ret;
 	}
 
 	/*
@@ -611,6 +576,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
 	recalc_sigpending();
 	spin_unlock_irq(&tsk->sighand->siglock);
 
+	return 0;
 }
 
 /*
@@ -622,7 +588,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
  * the kernel can handle, and then we build all the user-level signal handling
  * stack-frames in one go after that.
  */
-static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
+static void do_signal(struct pt_regs *regs, int syscall)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
@@ -635,7 +601,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
 	 * if so.
 	 */
 	if (!user_mode(regs))
-		return 0;
+		return;
 
 	if (try_to_freeze())
 		goto no_signal;
@@ -644,9 +610,24 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
 
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
-		handle_signal(signr, &ka, &info, oldset, regs, syscall);
+		sigset_t *oldset;
+
+		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+			oldset = &current->saved_sigmask;
+		else
+			oldset = &current->blocked;
+		if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) {
+			/*
+			 * A signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag.
+			 */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
 		single_step_set(current);
-		return 1;
+		return;
 	}
 
  no_signal:
@@ -698,16 +679,23 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
 		    regs->ARM_r0 == -ERESTARTNOINTR) {
 			setup_syscall_restart(regs);
 		}
+
+		/* If there's no signal to deliver, we just put the saved sigmask
+		 * back.
+		 */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+		}
 	}
 	single_step_set(current);
-	return 0;
 }
 
 asmlinkage void
 do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 {
 	if (thread_flags & _TIF_SIGPENDING)
-		do_signal(&current->blocked, regs, syscall);
+		do_signal(regs, syscall);
 
 	if (thread_flags & _TIF_NOTIFY_RESUME) {
 		clear_thread_flag(TIF_NOTIFY_RESUME);
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 9f444e5..20b7411 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -21,7 +21,7 @@
  * Note that with framepointer enabled, even the leaf functions have the same
  * prologue and epilogue, therefore we can ignore the LR value in this case.
  */
-int unwind_frame(struct stackframe *frame)
+int notrace unwind_frame(struct stackframe *frame)
 {
 	unsigned long high, low;
 	unsigned long fp = frame->fp;
@@ -43,7 +43,7 @@ int unwind_frame(struct stackframe *frame)
 }
 #endif
 
-void walk_stackframe(struct stackframe *frame,
+void notrace walk_stackframe(struct stackframe *frame,
 		     int (*fn)(struct stackframe *, void *), void *data)
 {
 	while (1) {
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index dd56e11..39baf11 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -62,7 +62,11 @@ struct unwind_ctrl_block {
 };
 
 enum regs {
+#ifdef CONFIG_THUMB2_KERNEL
+	FP = 7,
+#else
 	FP = 11,
+#endif
 	SP = 13,
 	LR = 14,
 	PC = 15
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 6937102..5cc4812 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -83,6 +83,7 @@ SECTIONS
 		EXIT_TEXT
 		EXIT_DATA
 		*(.exitcall.exit)
+		*(.discard)
 		*(.ARM.exidx.exit.text)
 		*(.ARM.extab.exit.text)
 #ifndef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
index 1154d92..638deb1 100644
--- a/arch/arm/lib/ashldi3.S
+++ b/arch/arm/lib/ashldi3.S
@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsl)
 	rsb	ip, r2, #32
 	movmi	ah, ah, lsl r2
 	movpl	ah, al, lsl r3
-	orrmi	ah, ah, al, lsr ip
+ ARM(	orrmi	ah, ah, al, lsr ip	)
+ THUMB(	lsrmi	r3, al, ip		)
+ THUMB(	orrmi	ah, ah, r3		)
 	mov	al, al, lsl r2
 	mov	pc, lr
 
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
index 9f8b355..015e8aa 100644
--- a/arch/arm/lib/ashrdi3.S
+++ b/arch/arm/lib/ashrdi3.S
@@ -43,7 +43,9 @@ ENTRY(__aeabi_lasr)
 	rsb	ip, r2, #32
 	movmi	al, al, lsr r2
 	movpl	al, ah, asr r3
-	orrmi	al, al, ah, lsl ip
+ ARM(	orrmi	al, al, ah, lsl ip	)
+ THUMB(	lslmi	r3, ah, ip		)
+ THUMB(	orrmi	al, al, r3		)
 	mov	ah, ah, asr r2
 	mov	pc, lr
 
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index b0951d0..aaf7220 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -38,7 +38,9 @@ ENDPROC(c_backtrace)
 		beq	no_frame		@ we have no stack frames
 
 		tst	r1, #0x10		@ 26 or 32-bit mode?
-		moveq	mask, #0xfc000003	@ mask for 26-bit
+ ARM(		moveq	mask, #0xfc000003	)
+ THUMB(		moveq	mask, #0xfc000000	)
+ THUMB(		orreq	mask, #0x03		)
 		movne	mask, #0		@ mask for 32-bit
 
 1:		stmfd	sp!, {pc}		@ calculate offset of PC stored
@@ -126,7 +128,9 @@ ENDPROC(c_backtrace)
 		mov	reg, #10
 		mov	r7, #0
 1:		mov	r3, #1
-		tst	instr, r3, lsl reg
+ ARM(		tst	instr, r3, lsl reg	)
+ THUMB(		lsl	r3, reg			)
+ THUMB(		tst	instr, r3		)
 		beq	2f
 		add	r7, r7, #1
 		teq	r7, #6
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index c7f2627..d422529 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -60,8 +60,8 @@
 	tst	r2, r0, lsl r3
 	\instr	r2, r2, r0, lsl r3
 	\store	r2, [r1]
-	restore_irqs ip
 	moveq	r0, #0
+	restore_irqs ip
 	mov	pc, lr
 	.endm
 #endif
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
index 844f567..1279abd 100644
--- a/arch/arm/lib/clear_user.S
+++ b/arch/arm/lib/clear_user.S
@@ -27,21 +27,20 @@ WEAK(__clear_user)
 		ands	ip, r0, #3
 		beq	1f
 		cmp	ip, #2
-USER(		strbt	r2, [r0], #1)
-USER(		strlebt	r2, [r0], #1)
-USER(		strltbt	r2, [r0], #1)
+		strusr	r2, r0, 1
+		strusr	r2, r0, 1, le
+		strusr	r2, r0, 1, lt
 		rsb	ip, ip, #4
 		sub	r1, r1, ip		@  7  6  5  4  3  2  1
 1:		subs	r1, r1, #8		@ -1 -2 -3 -4 -5 -6 -7
-USER(		strplt	r2, [r0], #4)
-USER(		strplt	r2, [r0], #4)
+		strusr	r2, r0, 4, pl, rept=2
 		bpl	1b
 		adds	r1, r1, #4		@  3  2  1  0 -1 -2 -3
-USER(		strplt	r2, [r0], #4)
+		strusr	r2, r0, 4, pl
 2:		tst	r1, #2			@ 1x 1x 0x 0x 1x 1x 0x
-USER(		strnebt	r2, [r0], #1)
-USER(		strnebt	r2, [r0], #1)
+		strusr	r2, r0, 1, ne, rept=2
 		tst	r1, #1			@ x1 x0 x1 x0 x1 x0 x1
+		it	ne			@ explicit IT needed for the label
 USER(		strnebt	r2, [r0])
 		mov	r0, #0
 		ldmfd	sp!, {r1, pc}
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 56799a1..e4fe124 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -33,11 +33,15 @@
  *	Number of bytes NOT copied.
  */
 
+#ifndef CONFIG_THUMB2_KERNEL
+#define LDR1W_SHIFT	0
+#else
+#define LDR1W_SHIFT	1
+#endif
+#define STR1W_SHIFT	0
+
 	.macro ldr1w ptr reg abort
-100:	ldrt \reg, [\ptr], #4
-	.section __ex_table, "a"
-	.long 100b, \abort
-	.previous
+	ldrusr	\reg, \ptr, 4, abort=\abort
 	.endm
 
 	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
@@ -53,14 +57,11 @@
 	.endm
 
 	.macro ldr1b ptr reg cond=al abort
-100:	ldr\cond\()bt \reg, [\ptr], #1
-	.section __ex_table, "a"
-	.long 100b, \abort
-	.previous
+	ldrusr	\reg, \ptr, 1, \cond, abort=\abort
 	.endm
 
 	.macro str1w ptr reg abort
-	str \reg, [\ptr], #4
+	W(str) \reg, [\ptr], #4
 	.endm
 
 	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 139cce6..805e3f8 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -57,6 +57,13 @@
  *
  *	Restore registers with the values previously saved with the
  *	'preserv' macro. Called upon code termination.
+ *
+ * LDR1W_SHIFT
+ * STR1W_SHIFT
+ *
+ *	Correction to be applied to the "ip" register when branching into
+ *	the ldr1w or str1w instructions (some of these macros may expand to
+ *	than one 32bit instruction in Thumb-2)
  */
 
 
@@ -99,9 +106,15 @@
 
 5:		ands	ip, r2, #28
 		rsb	ip, ip, #32
+#if LDR1W_SHIFT > 0
+		lsl	ip, ip, #LDR1W_SHIFT
+#endif
 		addne	pc, pc, ip		@ C is always clear here
 		b	7f
-6:		nop
+6:
+		.rept	(1 << LDR1W_SHIFT)
+		W(nop)
+		.endr
 		ldr1w	r1, r3, abort=20f
 		ldr1w	r1, r4, abort=20f
 		ldr1w	r1, r5, abort=20f
@@ -110,9 +123,16 @@
 		ldr1w	r1, r8, abort=20f
 		ldr1w	r1, lr, abort=20f
 
+#if LDR1W_SHIFT < STR1W_SHIFT
+		lsl	ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+		lsr	ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
 		add	pc, pc, ip
 		nop
-		nop
+		.rept	(1 << STR1W_SHIFT)
+		W(nop)
+		.endr
 		str1w	r0, r3, abort=20f
 		str1w	r0, r4, abort=20f
 		str1w	r0, r5, abort=20f
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 878820f..1a71e15 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -33,8 +33,15 @@
  *	Number of bytes NOT copied.
  */
 
+#define LDR1W_SHIFT	0
+#ifndef CONFIG_THUMB2_KERNEL
+#define STR1W_SHIFT	0
+#else
+#define STR1W_SHIFT	1
+#endif
+
 	.macro ldr1w ptr reg abort
-	ldr \reg, [\ptr], #4
+	W(ldr) \reg, [\ptr], #4
 	.endm
 
 	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
@@ -50,10 +57,7 @@
 	.endm
 
 	.macro str1w ptr reg abort
-100:	strt \reg, [\ptr], #4
-	.section __ex_table, "a"
-	.long 100b, \abort
-	.previous
+	strusr	\reg, \ptr, 4, abort=\abort
 	.endm
 
 	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
@@ -68,10 +72,7 @@
 	.endm
 
 	.macro str1b ptr reg cond=al abort
-100:	str\cond\()bt \reg, [\ptr], #1
-	.section __ex_table, "a"
-	.long 100b, \abort
-	.previous
+	strusr	\reg, \ptr, 1, \cond, abort=\abort
 	.endm
 
 	.macro enter reg1 reg2
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index 14677fb..fd0e9dc 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -26,50 +26,28 @@
 		.endm
 
 		.macro	load1b,	reg1
-9999:		ldrbt	\reg1, [r0], $1
-		.section __ex_table, "a"
-		.align	3
-		.long	9999b, 6001f
-		.previous
+		ldrusr	\reg1, r0, 1
 		.endm
 
 		.macro	load2b, reg1, reg2
-9999:		ldrbt	\reg1, [r0], $1
-9998:		ldrbt	\reg2, [r0], $1
-		.section __ex_table, "a"
-		.long	9999b, 6001f
-		.long	9998b, 6001f
-		.previous
+		ldrusr	\reg1, r0, 1
+		ldrusr	\reg2, r0, 1
 		.endm
 
 		.macro	load1l, reg1
-9999:		ldrt	\reg1, [r0], $4
-		.section __ex_table, "a"
-		.align	3
-		.long	9999b, 6001f
-		.previous
+		ldrusr	\reg1, r0, 4
 		.endm
 
 		.macro	load2l, reg1, reg2
-9999:		ldrt	\reg1, [r0], $4
-9998:		ldrt	\reg2, [r0], $4
-		.section __ex_table, "a"
-		.long	9999b, 6001f
-		.long	9998b, 6001f
-		.previous
+		ldrusr	\reg1, r0, 4
+		ldrusr	\reg2, r0, 4
 		.endm
 
 		.macro	load4l, reg1, reg2, reg3, reg4
-9999:		ldrt	\reg1, [r0], $4
-9998:		ldrt	\reg2, [r0], $4
-9997:		ldrt	\reg3, [r0], $4
-9996:		ldrt	\reg4, [r0], $4
-		.section __ex_table, "a"
-		.long	9999b, 6001f
-		.long	9998b, 6001f
-		.long	9997b, 6001f
-		.long	9996b, 6001f
-		.previous
+		ldrusr	\reg1, r0, 4
+		ldrusr	\reg2, r0, 4
+		ldrusr	\reg3, r0, 4
+		ldrusr	\reg4, r0, 4
 		.endm
 
 /*
@@ -92,14 +70,14 @@
  */
 		.section .fixup,"ax"
 		.align	4
-6001:		mov	r4, #-EFAULT
+9001:		mov	r4, #-EFAULT
 		ldr	r5, [fp, #4]		@ *err_ptr
 		str	r4, [r5]
 		ldmia	sp, {r1, r2}		@ retrieve dst, len
 		add	r2, r2, r1
 		mov	r0, #0			@ zero the buffer
-6002:		teq	r2, r1
+9002:		teq	r2, r1
 		strneb	r0, [r1], #1
-		bne	6002b
+		bne	9002b
 		load_regs
 		.previous
diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S
index 1425e78..faa7748 100644
--- a/arch/arm/lib/div64.S
+++ b/arch/arm/lib/div64.S
@@ -177,7 +177,9 @@ ENTRY(__do_div64)
 	mov	yh, xh, lsr ip
 	mov	yl, xl, lsr ip
 	rsb	ip, ip, #32
-	orr	yl, yl, xh, lsl ip
+ ARM(	orr	yl, yl, xh, lsl ip	)
+ THUMB(	lsl	xh, xh, ip		)
+ THUMB(	orr	yl, yl, xh		)
 	mov	xh, xl, lsl ip
 	mov	xh, xh, lsr ip
 	mov	pc, lr
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 8c4defc..1e4cbd4 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -25,7 +25,10 @@ ENTRY(_find_first_zero_bit_le)
 		teq	r1, #0	
 		beq	3f
 		mov	r2, #0
-1:		ldrb	r3, [r0, r2, lsr #3]
+1:
+ ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ THUMB(		lsr	r3, r2, #3		)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		eors	r3, r3, #0xff		@ invert bits
 		bne	.L_found		@ any now set - found zero bit
 		add	r2, r2, #8		@ next bit pointer
@@ -44,7 +47,9 @@ ENTRY(_find_next_zero_bit_le)
 		beq	3b
 		ands	ip, r2, #7
 		beq	1b			@ If new byte, goto old routine
-		ldrb	r3, [r0, r2, lsr #3]
+ ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ THUMB(		lsr	r3, r2, #3		)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		eor	r3, r3, #0xff		@ now looking for a 1 bit
 		movs	r3, r3, lsr ip		@ shift off unused bits
 		bne	.L_found
@@ -61,7 +66,10 @@ ENTRY(_find_first_bit_le)
 		teq	r1, #0	
 		beq	3f
 		mov	r2, #0
-1:		ldrb	r3, [r0, r2, lsr #3]
+1:
+ ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ THUMB(		lsr	r3, r2, #3		)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		movs	r3, r3
 		bne	.L_found		@ any now set - found zero bit
 		add	r2, r2, #8		@ next bit pointer
@@ -80,7 +88,9 @@ ENTRY(_find_next_bit_le)
 		beq	3b
 		ands	ip, r2, #7
 		beq	1b			@ If new byte, goto old routine
-		ldrb	r3, [r0, r2, lsr #3]
+ ARM(		ldrb	r3, [r0, r2, lsr #3]	)
+ THUMB(		lsr	r3, r2, #3		)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		movs	r3, r3, lsr ip		@ shift off unused bits
 		bne	.L_found
 		orr	r2, r2, #7		@ if zero, then no bits here
@@ -95,7 +105,9 @@ ENTRY(_find_first_zero_bit_be)
 		beq	3f
 		mov	r2, #0
 1:		eor	r3, r2, #0x18		@ big endian byte ordering
-		ldrb	r3, [r0, r3, lsr #3]
+ ARM(		ldrb	r3, [r0, r3, lsr #3]	)
+ THUMB(		lsr	r3, #3			)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		eors	r3, r3, #0xff		@ invert bits
 		bne	.L_found		@ any now set - found zero bit
 		add	r2, r2, #8		@ next bit pointer
@@ -111,7 +123,9 @@ ENTRY(_find_next_zero_bit_be)
 		ands	ip, r2, #7
 		beq	1b			@ If new byte, goto old routine
 		eor	r3, r2, #0x18		@ big endian byte ordering
-		ldrb	r3, [r0, r3, lsr #3]
+ ARM(		ldrb	r3, [r0, r3, lsr #3]	)
+ THUMB(		lsr	r3, #3			)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		eor	r3, r3, #0xff		@ now looking for a 1 bit
 		movs	r3, r3, lsr ip		@ shift off unused bits
 		bne	.L_found
@@ -125,7 +139,9 @@ ENTRY(_find_first_bit_be)
 		beq	3f
 		mov	r2, #0
 1:		eor	r3, r2, #0x18		@ big endian byte ordering
-		ldrb	r3, [r0, r3, lsr #3]
+ ARM(		ldrb	r3, [r0, r3, lsr #3]	)
+ THUMB(		lsr	r3, #3			)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		movs	r3, r3
 		bne	.L_found		@ any now set - found zero bit
 		add	r2, r2, #8		@ next bit pointer
@@ -141,7 +157,9 @@ ENTRY(_find_next_bit_be)
 		ands	ip, r2, #7
 		beq	1b			@ If new byte, goto old routine
 		eor	r3, r2, #0x18		@ big endian byte ordering
-		ldrb	r3, [r0, r3, lsr #3]
+ ARM(		ldrb	r3, [r0, r3, lsr #3]	)
+ THUMB(		lsr	r3, #3			)
+ THUMB(		ldrb	r3, [r0, r3]		)
 		movs	r3, r3, lsr ip		@ shift off unused bits
 		bne	.L_found
 		orr	r2, r2, #7		@ if zero, then no bits here
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index 6763088..a1814d9 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -36,8 +36,13 @@ ENTRY(__get_user_1)
 ENDPROC(__get_user_1)
 
 ENTRY(__get_user_2)
+#ifdef CONFIG_THUMB2_KERNEL
+2:	ldrbt	r2, [r0]
+3:	ldrbt	r3, [r0, #1]
+#else
 2:	ldrbt	r2, [r0], #1
 3:	ldrbt	r3, [r0]
+#endif
 #ifndef __ARMEB__
 	orr	r2, r2, r3, lsl #8
 #else
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
index d658561..ff4f71b 100644
--- a/arch/arm/lib/io-writesw-armv4.S
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -75,7 +75,10 @@ ENTRY(__raw_writesw)
 #endif
 
 .Loutsw_noalign:
-		ldr	r3, [r1, -r3]!
+ ARM(		ldr	r3, [r1, -r3]!	)
+ THUMB(		rsb	r3, r3, #0	)
+ THUMB(		ldr	r3, [r1, r3]	)
+ THUMB(		sub	r1, r3		)
 		subcs	r2, r2, #1
 		bcs	2f
 		subs	r2, r2, #2
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
index 67964bc..6dc0648 100644
--- a/arch/arm/lib/lib1funcs.S
+++ b/arch/arm/lib/lib1funcs.S
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
  *
- * Author: Nicolas Pitre <nico@cam.org>
+ * Author: Nicolas Pitre <nico@fluxnic.net>
  *   - contributed to gcc-3.4 on Sep 30, 2003
  *   - adapted for the Linux kernel on Oct 2, 2003
  */
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
index 99ea338..f83d449 100644
--- a/arch/arm/lib/lshrdi3.S
+++ b/arch/arm/lib/lshrdi3.S
@@ -43,7 +43,9 @@ ENTRY(__aeabi_llsr)
 	rsb	ip, r2, #32
 	movmi	al, al, lsr r2
 	movpl	al, ah, lsr r3
-	orrmi	al, al, ah, lsl ip
+ ARM(	orrmi	al, al, ah, lsl ip	)
+ THUMB(	lslmi	r3, ah, ip		)
+ THUMB(	orrmi	al, al, r3		)
 	mov	ah, ah, lsr r2
 	mov	pc, lr
 
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index e0d0026..a9b9e22 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -13,8 +13,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
+#define LDR1W_SHIFT	0
+#define STR1W_SHIFT	0
+
 	.macro ldr1w ptr reg abort
-	ldr \reg, [\ptr], #4
+	W(ldr) \reg, [\ptr], #4
 	.endm
 
 	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
@@ -30,7 +33,7 @@
 	.endm
 
 	.macro str1w ptr reg abort
-	str \reg, [\ptr], #4
+	W(str) \reg, [\ptr], #4
 	.endm
 
 	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 1254918..5025c86 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -75,24 +75,24 @@ ENTRY(memmove)
 		addne	pc, pc, ip		@ C is always clear here
 		b	7f
 6:		nop
-		ldr	r3, [r1, #-4]!
-		ldr	r4, [r1, #-4]!
-		ldr	r5, [r1, #-4]!
-		ldr	r6, [r1, #-4]!
-		ldr	r7, [r1, #-4]!
-		ldr	r8, [r1, #-4]!
-		ldr	lr, [r1, #-4]!
+		W(ldr)	r3, [r1, #-4]!
+		W(ldr)	r4, [r1, #-4]!
+		W(ldr)	r5, [r1, #-4]!
+		W(ldr)	r6, [r1, #-4]!
+		W(ldr)	r7, [r1, #-4]!
+		W(ldr)	r8, [r1, #-4]!
+		W(ldr)	lr, [r1, #-4]!
 
 		add	pc, pc, ip
 		nop
 		nop
-		str	r3, [r0, #-4]!
-		str	r4, [r0, #-4]!
-		str	r5, [r0, #-4]!
-		str	r6, [r0, #-4]!
-		str	r7, [r0, #-4]!
-		str	r8, [r0, #-4]!
-		str	lr, [r0, #-4]!
+		W(str)	r3, [r0, #-4]!
+		W(str)	r4, [r0, #-4]!
+		W(str)	r5, [r0, #-4]!
+		W(str)	r6, [r0, #-4]!
+		W(str)	r7, [r0, #-4]!
+		W(str)	r8, [r0, #-4]!
+		W(str)	lr, [r0, #-4]!
 
 	CALGN(	bcs	2b			)
 
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
index 864f3c1..02fedbf 100644
--- a/arch/arm/lib/putuser.S
+++ b/arch/arm/lib/putuser.S
@@ -37,6 +37,15 @@ ENDPROC(__put_user_1)
 
 ENTRY(__put_user_2)
 	mov	ip, r2, lsr #8
+#ifdef CONFIG_THUMB2_KERNEL
+#ifndef __ARMEB__
+2:	strbt	r2, [r0]
+3:	strbt	ip, [r0, #1]
+#else
+2:	strbt	ip, [r0]
+3:	strbt	r2, [r0, #1]
+#endif
+#else	/* !CONFIG_THUMB2_KERNEL */
 #ifndef __ARMEB__
 2:	strbt	r2, [r0], #1
 3:	strbt	ip, [r0]
@@ -44,6 +53,7 @@ ENTRY(__put_user_2)
 2:	strbt	ip, [r0], #1
 3:	strbt	r2, [r0]
 #endif
+#endif	/* CONFIG_THUMB2_KERNEL */
 	mov	r0, #0
 	mov	pc, lr
 ENDPROC(__put_user_2)
@@ -55,8 +65,13 @@ ENTRY(__put_user_4)
 ENDPROC(__put_user_4)
 
 ENTRY(__put_user_8)
+#ifdef CONFIG_THUMB2_KERNEL
+5:	strt	r2, [r0]
+6:	strt	r3, [r0, #4]
+#else
 5:	strt	r2, [r0], #4
 6:	strt	r3, [r0]
+#endif
 	mov	r0, #0
 	mov	pc, lr
 ENDPROC(__put_user_8)
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
index a16fb20..eb0edb8 100644
--- a/arch/arm/lib/sha1.S
+++ b/arch/arm/lib/sha1.S
@@ -3,7 +3,7 @@
  *
  *  SHA transform optimized for ARM
  *
- *  Copyright:	(C) 2005 by Nicolas Pitre <nico@cam.org>
+ *  Copyright:	(C) 2005 by Nicolas Pitre <nico@fluxnic.net>
  *  Created:	September 17, 2005
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -187,6 +187,7 @@ ENTRY(sha_transform)
 
 ENDPROC(sha_transform)
 
+	.align	2
 .L_sha_K:
 	.word	0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
 
@@ -195,6 +196,7 @@ ENDPROC(sha_transform)
  * void sha_init(__u32 *buf)
  */
 
+	.align	2
 .L_sha_initial_digest:
 	.word	0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
 
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S
index 330373c..1c9814f 100644
--- a/arch/arm/lib/strncpy_from_user.S
+++ b/arch/arm/lib/strncpy_from_user.S
@@ -23,7 +23,7 @@
 ENTRY(__strncpy_from_user)
 	mov	ip, r1
 1:	subs	r2, r2, #1
-USER(	ldrplbt	r3, [r1], #1)
+	ldrusr	r3, r1, 1, pl
 	bmi	2f
 	strb	r3, [r0], #1
 	teq	r3, #0
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S
index 90bb9d0..7855b29 100644
--- a/arch/arm/lib/strnlen_user.S
+++ b/arch/arm/lib/strnlen_user.S
@@ -23,7 +23,7 @@
 ENTRY(__strnlen_user)
 	mov	r2, r0
 1:
-USER(	ldrbt	r3, [r0], #1)
+	ldrusr	r3, r0, 1
 	teq	r3, #0
 	beq	2f
 	subs	r1, r1, #1
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 323b47f..a24d824 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -23,6 +23,12 @@ config ARCH_AT91SAM9261
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 
+config ARCH_AT91SAM9G10
+	bool "AT91SAM9G10"
+	select CPU_ARM926T
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+
 config ARCH_AT91SAM9263
 	bool "AT91SAM9263"
 	select CPU_ARM926T
@@ -41,6 +47,12 @@ config ARCH_AT91SAM9G20
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 
+config ARCH_AT91SAM9G45
+	bool "AT91SAM9G45"
+	select CPU_ARM926T
+	select GENERIC_TIME
+	select GENERIC_CLOCKEVENTS
+
 config ARCH_AT91CAP9
 	bool "AT91CAP9"
 	select CPU_ARM926T
@@ -144,6 +156,13 @@ config MACH_YL9200
 	help
 	  Select this if you are using the ucDragon YL-9200 board.
 
+config MACH_CPUAT91
+	bool "Eukrea CPUAT91"
+	depends on ARCH_AT91RM9200
+	help
+	  Select this if you are using the Eukrea Electromatique's
+	  CPUAT91 board <http://www.eukrea.com/>.
+
 endif
 
 # ----------------------------------------------------------
@@ -205,6 +224,13 @@ config MACH_QIL_A9260
 	  Select this if you are using a Calao Systems QIL-A9260 Board.
 	  <http://www.calao-systems.com>
 
+config MACH_CPU9260
+	bool "Eukrea CPU9260 board"
+	depends on ARCH_AT91SAM9260
+	help
+	  Select this if you are using a Eukrea Electromatique's
+	  CPU9260 Board <http://www.eukrea.com/>
+
 endif
 
 # ----------------------------------------------------------
@@ -224,6 +250,21 @@ endif
 
 # ----------------------------------------------------------
 
+if ARCH_AT91SAM9G10
+
+comment "AT91SAM9G10 Board Type"
+
+config MACH_AT91SAM9G10EK
+	bool "Atmel AT91SAM9G10-EK Evaluation Kit"
+	depends on ARCH_AT91SAM9G10
+	help
+	  Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
+	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
+
+endif
+
+# ----------------------------------------------------------
+
 if ARCH_AT91SAM9263
 
 comment "AT91SAM9263 Board Type"
@@ -276,6 +317,29 @@ config MACH_AT91SAM9G20EK
 	help
 	  Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
 
+config MACH_CPU9G20
+	bool "Eukrea CPU9G20 board"
+	depends on ARCH_AT91SAM9G20
+	help
+	  Select this if you are using a Eukrea Electromatique's
+	  CPU9G20 Board <http://www.eukrea.com/>
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9G45
+
+comment "AT91SAM9G45 Board Type"
+
+config MACH_AT91SAM9G45EKES
+	bool "Atmel AT91SAM9G45-EKES Evaluation Kit"
+	depends on ARCH_AT91SAM9G45
+	help
+	  Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
+	  "ES" at the end of the name means that this board is an
+	  Engineering Sample.
+
 endif
 
 # ----------------------------------------------------------
@@ -315,13 +379,13 @@ comment "AT91 Board Options"
 
 config MTD_AT91_DATAFLASH_CARD
 	bool "Enable DataFlash Card support"
-	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926)
+	depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_ECBAT91 || MACH_SAM9_L9260 || MACH_AT91CAP9ADK || MACH_NEOCORE926)
 	help
 	  Enable support for the DataFlash card.
 
 config MTD_NAND_ATMEL_BUSWIDTH_16
 	bool "Enable 16-bit data bus interface to NAND flash"
-	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK)
+	depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
 	help
 	  On AT91SAM926x boards both types of NAND flash can be present
 	  (8 and 16 bit data bus width).
@@ -383,7 +447,7 @@ config AT91_EARLY_USART2
 
 config AT91_EARLY_USART3
 	bool "USART3"
-	depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
+	depends on (ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9260 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45)
 
 config AT91_EARLY_USART4
 	bool "USART4"
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index c69ff23..a6ed015 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -13,9 +13,11 @@ obj-$(CONFIG_AT91_PMC_UNIT)	+= clock.o
 obj-$(CONFIG_ARCH_AT91RM9200)	+= at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
 obj-$(CONFIG_ARCH_AT91SAM9260)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9261)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G10)	+= at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9263)	+= at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)	+= at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
+ obj-$(CONFIG_ARCH_AT91SAM9G45)	+= at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)	+= at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)	+= at91x40.o at91x40_time.o
 
@@ -32,6 +34,7 @@ obj-$(CONFIG_MACH_KAFA)		+= board-kafa.o
 obj-$(CONFIG_MACH_PICOTUX2XX)	+= board-picotux200.o
 obj-$(CONFIG_MACH_ECBAT91)	+= board-ecbat91.o
 obj-$(CONFIG_MACH_YL9200)	+= board-yl-9200.o
+obj-$(CONFIG_MACH_CPUAT91)	+= board-cpuat91.o
 
 # AT91SAM9260 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
@@ -40,9 +43,11 @@ obj-$(CONFIG_MACH_SAM9_L9260)	+= board-sam9-l9260.o
 obj-$(CONFIG_MACH_USB_A9260)	+= board-usb-a9260.o
 obj-$(CONFIG_MACH_QIL_A9260)	+= board-qil-a9260.o
 obj-$(CONFIG_MACH_AFEB9260)	+= board-afeb-9260v1.o
+obj-$(CONFIG_MACH_CPU9260)	+= board-cpu9krea.o
 
 # AT91SAM9261 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
+obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o
 
 # AT91SAM9263 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
@@ -54,6 +59,10 @@ obj-$(CONFIG_MACH_AT91SAM9RLEK)	+= board-sam9rlek.o
 
 # AT91SAM9G20 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
+obj-$(CONFIG_MACH_CPU9G20)	+= board-cpu9krea.o
+
+# AT91SAM9G45 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
 
 # AT91CAP9 board-specific support
 obj-$(CONFIG_MACH_AT91CAP9ADK)	+= board-cap9adk.o
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index 071a250..3462b81 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -7,6 +7,10 @@ ifeq ($(CONFIG_ARCH_AT91CAP9),y)
    zreladdr-y	:= 0x70008000
 params_phys-y	:= 0x70000100
 initrd_phys-y	:= 0x70410000
+else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
+   zreladdr-y	:= 0x70008000
+params_phys-y	:= 0x70000100
+initrd_phys-y	:= 0x70410000
 else
    zreladdr-y	:= 0x20008000
 params_phys-y	:= 0x20000100
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index d74c9ac..ee4ea0e 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -1113,6 +1113,122 @@ void __init at91_set_serial_console(unsigned portnr) {}
 void __init at91_add_device_serial(void) {}
 #endif
 
+/* --------------------------------------------------------------------
+ *  CF/IDE
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \
+	defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
+	defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
+
+static struct at91_cf_data cf0_data;
+
+static struct resource cf0_resources[] = {
+	[0] = {
+		.start	= AT91_CHIPSELECT_4,
+		.end	= AT91_CHIPSELECT_4 + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device cf0_device = {
+	.id		= 0,
+	.dev		= {
+				.platform_data	= &cf0_data,
+	},
+	.resource	= cf0_resources,
+	.num_resources	= ARRAY_SIZE(cf0_resources),
+};
+
+static struct at91_cf_data cf1_data;
+
+static struct resource cf1_resources[] = {
+	[0] = {
+		.start	= AT91_CHIPSELECT_5,
+		.end	= AT91_CHIPSELECT_5 + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device cf1_device = {
+	.id		= 1,
+	.dev		= {
+				.platform_data	= &cf1_data,
+	},
+	.resource	= cf1_resources,
+	.num_resources	= ARRAY_SIZE(cf1_resources),
+};
+
+void __init at91_add_device_cf(struct at91_cf_data *data)
+{
+	struct platform_device *pdev;
+	unsigned long csa;
+
+	if (!data)
+		return;
+
+	csa = at91_sys_read(AT91_MATRIX_EBICSA);
+
+	switch (data->chipselect) {
+	case 4:
+		at91_set_multi_drive(AT91_PIN_PC8, 0);
+		at91_set_A_periph(AT91_PIN_PC8, 0);
+		csa |= AT91_MATRIX_CS4A_SMC_CF1;
+		cf0_data = *data;
+		pdev = &cf0_device;
+		break;
+	case 5:
+		at91_set_multi_drive(AT91_PIN_PC9, 0);
+		at91_set_A_periph(AT91_PIN_PC9, 0);
+		csa |= AT91_MATRIX_CS5A_SMC_CF2;
+		cf1_data = *data;
+		pdev = &cf1_device;
+		break;
+	default:
+		printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
+		       data->chipselect);
+		return;
+	}
+
+	at91_sys_write(AT91_MATRIX_EBICSA, csa);
+
+	if (data->rst_pin) {
+		at91_set_multi_drive(data->rst_pin, 0);
+		at91_set_gpio_output(data->rst_pin, 1);
+	}
+
+	if (data->irq_pin) {
+		at91_set_gpio_input(data->irq_pin, 0);
+		at91_set_deglitch(data->irq_pin, 1);
+	}
+
+	if (data->det_pin) {
+		at91_set_gpio_input(data->det_pin, 0);
+		at91_set_deglitch(data->det_pin, 1);
+	}
+
+	at91_set_B_periph(AT91_PIN_PC6, 0);     /* CFCE1 */
+	at91_set_B_periph(AT91_PIN_PC7, 0);     /* CFCE2 */
+	at91_set_A_periph(AT91_PIN_PC10, 0);    /* CFRNW */
+	at91_set_A_periph(AT91_PIN_PC15, 1);    /* NWAIT */
+
+	if (data->flags & AT91_CF_TRUE_IDE)
+#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
+		pdev->name = "pata_at91";
+#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
+		pdev->name = "at91_ide";
+#else
+#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91"
+#endif
+	else
+		pdev->name = "at91_cf";
+
+	platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_cf(struct at91_cf_data * data) {}
+#endif
 
 /* -------------------------------------------------------------------- */
 /*
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 3acd7d7..4ecf379 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -16,6 +16,7 @@
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <mach/cpu.h>
 #include <mach/at91sam9261.h>
 #include <mach/at91_pmc.h>
 #include <mach/at91_rstc.h>
@@ -30,7 +31,11 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
 		.length		= SZ_16K,
 		.type		= MT_DEVICE,
-	}, {
+	},
+};
+
+static struct map_desc at91sam9261_sram_desc[] __initdata = {
+	{
 		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,
 		.pfn		= __phys_to_pfn(AT91SAM9261_SRAM_BASE),
 		.length		= AT91SAM9261_SRAM_SIZE,
@@ -38,6 +43,15 @@ static struct map_desc at91sam9261_io_desc[] __initdata = {
 	},
 };
 
+static struct map_desc at91sam9g10_sram_desc[] __initdata = {
+	{
+		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE,
+		.pfn		= __phys_to_pfn(AT91SAM9G10_SRAM_BASE),
+		.length		= AT91SAM9G10_SRAM_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
 /* --------------------------------------------------------------------
  *  Clocks
  * -------------------------------------------------------------------- */
@@ -263,6 +277,12 @@ void __init at91sam9261_initialize(unsigned long main_clock)
 	/* Map peripherals */
 	iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
 
+	if (cpu_is_at91sam9g10())
+		iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));
+	else
+		iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
+
+
 	at91_arch_reset = at91sam9261_reset;
 	pm_power_off = at91sam9261_poweroff;
 	at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index b7f2332..55719a9 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -707,9 +707,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
  *  AC97
  * -------------------------------------------------------------------- */
 
-#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
+#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
 static u64 ac97_dmamask = DMA_BIT_MASK(32);
-static struct atmel_ac97_data ac97_data;
+static struct ac97c_platform_data ac97_data;
 
 static struct resource ac97_resources[] = {
 	[0] = {
@@ -725,8 +725,8 @@ static struct resource ac97_resources[] = {
 };
 
 static struct platform_device at91sam9263_ac97_device = {
-	.name		= "ac97c",
-	.id		= 1,
+	.name		= "atmel_ac97c",
+	.id		= 0,
 	.dev		= {
 				.dma_mask		= &ac97_dmamask,
 				.coherent_dma_mask	= DMA_BIT_MASK(32),
@@ -736,7 +736,7 @@ static struct platform_device at91sam9263_ac97_device = {
 	.num_resources	= ARRAY_SIZE(ac97_resources),
 };
 
-void __init at91_add_device_ac97(struct atmel_ac97_data *data)
+void __init at91_add_device_ac97(struct ac97c_platform_data *data)
 {
 	if (!data)
 		return;
@@ -750,11 +750,11 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data)
 	if (data->reset_pin)
 		at91_set_gpio_output(data->reset_pin, 0);
 
-	ac97_data = *ek_data;
+	ac97_data = *data;
 	platform_device_register(&at91sam9263_ac97_device);
 }
 #else
-void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
+void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
 #endif
 
 
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
new file mode 100644
index 0000000..85166b7
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -0,0 +1,360 @@
+/*
+ *  Chip-specific setup code for the AT91SAM9G45 family
+ *
+ *  Copyright (C) 2009 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at91sam9g45.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91sam9g45_io_desc[] __initdata = {
+	{
+		.virtual	= AT91_VA_BASE_SYS,
+		.pfn		= __phys_to_pfn(AT91_BASE_SYS),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE,
+		.pfn		= __phys_to_pfn(AT91SAM9G45_SRAM_BASE),
+		.length		= AT91SAM9G45_SRAM_SIZE,
+		.type		= MT_DEVICE,
+	}
+};
+
+/* --------------------------------------------------------------------
+ *  Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+	.name		= "pioA_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_PIOA,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+	.name		= "pioB_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_PIOB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+	.name		= "pioC_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_PIOC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioDE_clk = {
+	.name		= "pioDE_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_PIODE,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+	.name		= "usart0_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_US0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+	.name		= "usart1_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_US1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+	.name		= "usart2_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_US2,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart3_clk = {
+	.name		= "usart3_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_US3,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+	.name		= "mci0_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_MCI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi0_clk = {
+	.name		= "twi0_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_TWI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi1_clk = {
+	.name		= "twi1_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_TWI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+	.name		= "spi0_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_SPI0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+	.name		= "spi1_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_SPI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+	.name		= "ssc0_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_SSC0,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+	.name		= "ssc1_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_SSC1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb_clk = {
+	.name		= "tcb_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_TCB,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwm_clk = {
+	.name		= "pwm_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_PWMC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk tsc_clk = {
+	.name		= "tsc_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_TSC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma_clk = {
+	.name		= "dma_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_DMA,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk uhphs_clk = {
+	.name		= "uhphs_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_UHPHS,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+	.name		= "lcdc_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_LCDC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+	.name		= "ac97_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_AC97C,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+	.name		= "macb_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_EMAC,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk isi_clk = {
+	.name		= "isi_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_ISI,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk udphs_clk = {
+	.name		= "udphs_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_UDPHS,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+	.name		= "mci1_clk",
+	.pmc_mask	= 1 << AT91SAM9G45_ID_MCI1,
+	.type		= CLK_TYPE_PERIPHERAL,
+};
+
+/* One additional fake clock for ohci */
+static struct clk ohci_clk = {
+	.name		= "ohci_clk",
+	.pmc_mask	= 0,
+	.type		= CLK_TYPE_PERIPHERAL,
+	.parent		= &uhphs_clk,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+	&pioA_clk,
+	&pioB_clk,
+	&pioC_clk,
+	&pioDE_clk,
+	&usart0_clk,
+	&usart1_clk,
+	&usart2_clk,
+	&usart3_clk,
+	&mmc0_clk,
+	&twi0_clk,
+	&twi1_clk,
+	&spi0_clk,
+	&spi1_clk,
+	&ssc0_clk,
+	&ssc1_clk,
+	&tcb_clk,
+	&pwm_clk,
+	&tsc_clk,
+	&dma_clk,
+	&uhphs_clk,
+	&lcdc_clk,
+	&ac97_clk,
+	&macb_clk,
+	&isi_clk,
+	&udphs_clk,
+	&mmc1_clk,
+	// irq0
+	&ohci_clk,
+};
+
+/*
+ * The two programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+	.name		= "pck0",
+	.pmc_mask	= AT91_PMC_PCK0,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 0,
+};
+static struct clk pck1 = {
+	.name		= "pck1",
+	.pmc_mask	= AT91_PMC_PCK1,
+	.type		= CLK_TYPE_PROGRAMMABLE,
+	.id		= 1,
+};
+
+static void __init at91sam9g45_register_clocks(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+		clk_register(periph_clocks[i]);
+
+	clk_register(&pck0);
+	clk_register(&pck1);
+}
+
+/* --------------------------------------------------------------------
+ *  GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91sam9g45_gpio[] = {
+	{
+		.id		= AT91SAM9G45_ID_PIOA,
+		.offset		= AT91_PIOA,
+		.clock		= &pioA_clk,
+	}, {
+		.id		= AT91SAM9G45_ID_PIOB,
+		.offset		= AT91_PIOB,
+		.clock		= &pioB_clk,
+	}, {
+		.id		= AT91SAM9G45_ID_PIOC,
+		.offset		= AT91_PIOC,
+		.clock		= &pioC_clk,
+	}, {
+		.id		= AT91SAM9G45_ID_PIODE,
+		.offset		= AT91_PIOD,
+		.clock		= &pioDE_clk,
+	}, {
+		.id		= AT91SAM9G45_ID_PIODE,
+		.offset		= AT91_PIOE,
+		.clock		= &pioDE_clk,
+	}
+};
+
+static void at91sam9g45_reset(void)
+{
+	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+static void at91sam9g45_poweroff(void)
+{
+	at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
+/* --------------------------------------------------------------------
+ *  AT91SAM9G45 processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91sam9g45_initialize(unsigned long main_clock)
+{
+	/* Map peripherals */
+	iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
+
+	at91_arch_reset = at91sam9g45_reset;
+	pm_power_off = at91sam9g45_poweroff;
+	at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
+
+	/* Init clock subsystem */
+	at91_clock_init(main_clock);
+
+	/* Register the processor-specific clocks */
+	at91sam9g45_register_clocks();
+
+	/* Register GPIO subsystem */
+	at91_gpio_init(at91sam9g45_gpio, 5);
+}
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
+	7,	/* Advanced Interrupt Controller (FIQ) */
+	7,	/* System Peripherals */
+	1,	/* Parallel IO Controller A */
+	1,	/* Parallel IO Controller B */
+	1,	/* Parallel IO Controller C */
+	1,	/* Parallel IO Controller D and E */
+	0,
+	5,	/* USART 0 */
+	5,	/* USART 1 */
+	5,	/* USART 2 */
+	5,	/* USART 3 */
+	0,	/* Multimedia Card Interface 0 */
+	6,	/* Two-Wire Interface 0 */
+	6,	/* Two-Wire Interface 1 */
+	5,	/* Serial Peripheral Interface 0 */
+	5,	/* Serial Peripheral Interface 1 */
+	4,	/* Serial Synchronous Controller 0 */
+	4,	/* Serial Synchronous Controller 1 */
+	0,	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
+	0,	/* Pulse Width Modulation Controller */
+	0,	/* Touch Screen Controller */
+	0,	/* DMA Controller */
+	2,	/* USB Host High Speed port */
+	3,	/* LDC Controller */
+	5,	/* AC97 Controller */
+	3,	/* Ethernet */
+	0,	/* Image Sensor Interface */
+	2,	/* USB Device High speed port */
+	0,
+	0,	/* Multimedia Card Interface 1 */
+	0,
+	0,	/* Advanced Interrupt Controller (IRQ0) */
+};
+
+void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+	if (!priority)
+		priority = at91sam9g45_default_irq_priority;
+
+	/* Initialize the AIC interrupt controller */
+	at91_aic_init(priority);
+
+	/* Enable GPIO interrupts */
+	at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
new file mode 100644
index 0000000..d746e86
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -0,0 +1,1230 @@
+/*
+ *  On-Chip devices setup code for the AT91SAM9G45 family
+ *
+ *  Copyright (C) 2009 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9g45.h>
+#include <mach/at91sam9g45_matrix.h>
+#include <mach/at91sam9_smc.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ *  USB Host (OHCI)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_ohci_data;
+
+static struct resource usbh_ohci_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_OHCI_BASE,
+		.end	= AT91SAM9G45_OHCI_BASE + SZ_1M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_UHPHS,
+		.end	= AT91SAM9G45_ID_UHPHS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_usbh_ohci_device = {
+	.name		= "at91_ohci",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &ohci_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &usbh_ohci_data,
+	},
+	.resource	= usbh_ohci_resources,
+	.num_resources	= ARRAY_SIZE(usbh_ohci_resources),
+};
+
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
+{
+	int i;
+
+	if (!data)
+		return;
+
+	/* Enable VBus control for UHP ports */
+	for (i = 0; i < data->ports; i++) {
+		if (data->vbus_pin[i])
+			at91_set_gpio_output(data->vbus_pin[i], 0);
+	}
+
+	usbh_ohci_data = *data;
+	platform_device_register(&at91_usbh_ohci_device);
+}
+#else
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+static struct resource usba_udc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_UDPHS_FIFO,
+		.end	= AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_BASE_UDPHS,
+		.end	= AT91SAM9G45_BASE_UDPHS + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= AT91SAM9G45_ID_UDPHS,
+		.end	= AT91SAM9G45_ID_UDPHS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc)			\
+	[idx] = {						\
+		.name		= nam,				\
+		.index		= idx,				\
+		.fifo_size	= maxpkt,			\
+		.nr_banks	= maxbk,			\
+		.can_dma	= dma,				\
+		.can_isoc	= isoc,				\
+	}
+
+static struct usba_ep_data usba_udc_ep[] __initdata = {
+	EP("ep0", 0, 64, 1, 0, 0),
+	EP("ep1", 1, 1024, 2, 1, 1),
+	EP("ep2", 2, 1024, 2, 1, 1),
+	EP("ep3", 3, 1024, 3, 1, 0),
+	EP("ep4", 4, 1024, 3, 1, 0),
+	EP("ep5", 5, 1024, 3, 1, 1),
+	EP("ep6", 6, 1024, 3, 1, 1),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+	struct usba_platform_data pdata;
+	struct usba_ep_data ep[7];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+	.name		= "atmel_usba_udc",
+	.id		= -1,
+	.dev		= {
+				.platform_data	= &usba_udc_data.pdata,
+	},
+	.resource	= usba_udc_resources,
+	.num_resources	= ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+	usba_udc_data.pdata.vbus_pin = -EINVAL;
+	usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+
+	if (data && data->vbus_pin > 0) {
+		at91_set_gpio_input(data->vbus_pin, 0);
+		at91_set_deglitch(data->vbus_pin, 1);
+		usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+	}
+
+	/* Pullup pin is handled internally by USB device peripheral */
+
+	/* Clocks */
+	at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
+	at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
+
+	platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_EMAC,
+		.end	= AT91SAM9G45_BASE_EMAC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_EMAC,
+		.end	= AT91SAM9G45_ID_EMAC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_eth_device = {
+	.name		= "macb",
+	.id		= -1,
+	.dev		= {
+				.dma_mask		= &eth_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &eth_data,
+	},
+	.resource	= eth_resources,
+	.num_resources	= ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+	if (!data)
+		return;
+
+	if (data->phy_irq_pin) {
+		at91_set_gpio_input(data->phy_irq_pin, 0);
+		at91_set_deglitch(data->phy_irq_pin, 1);
+	}
+
+	/* Pins used for MII and RMII */
+	at91_set_A_periph(AT91_PIN_PA17, 0);	/* ETXCK_EREFCK */
+	at91_set_A_periph(AT91_PIN_PA15, 0);	/* ERXDV */
+	at91_set_A_periph(AT91_PIN_PA12, 0);	/* ERX0 */
+	at91_set_A_periph(AT91_PIN_PA13, 0);	/* ERX1 */
+	at91_set_A_periph(AT91_PIN_PA16, 0);	/* ERXER */
+	at91_set_A_periph(AT91_PIN_PA14, 0);	/* ETXEN */
+	at91_set_A_periph(AT91_PIN_PA10, 0);	/* ETX0 */
+	at91_set_A_periph(AT91_PIN_PA11, 0);	/* ETX1 */
+	at91_set_A_periph(AT91_PIN_PA19, 0);	/* EMDIO */
+	at91_set_A_periph(AT91_PIN_PA18, 0);	/* EMDC */
+
+	if (!data->is_rmii) {
+		at91_set_B_periph(AT91_PIN_PA29, 0);	/* ECRS */
+		at91_set_B_periph(AT91_PIN_PA30, 0);	/* ECOL */
+		at91_set_B_periph(AT91_PIN_PA8,  0);	/* ERX2 */
+		at91_set_B_periph(AT91_PIN_PA9,  0);	/* ERX3 */
+		at91_set_B_periph(AT91_PIN_PA28, 0);	/* ERXCK */
+		at91_set_B_periph(AT91_PIN_PA6,  0);	/* ETX2 */
+		at91_set_B_periph(AT91_PIN_PA7,  0);	/* ETX3 */
+		at91_set_B_periph(AT91_PIN_PA27, 0);	/* ETXER */
+	}
+
+	eth_data = *data;
+	platform_device_register(&at91sam9g45_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE	AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+	[0] = {
+		.start	= NAND_BASE,
+		.end	= NAND_BASE + SZ_256M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91_BASE_SYS + AT91_ECC,
+		.end	= AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91sam9g45_nand_device = {
+	.name		= "atmel_nand",
+	.id		= -1,
+	.dev		= {
+				.platform_data	= &nand_data,
+	},
+	.resource	= nand_resources,
+	.num_resources	= ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+	unsigned long csa;
+
+	if (!data)
+		return;
+
+	csa = at91_sys_read(AT91_MATRIX_EBICSA);
+	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
+
+	/* enable pin */
+	if (data->enable_pin)
+		at91_set_gpio_output(data->enable_pin, 1);
+
+	/* ready/busy pin */
+	if (data->rdy_pin)
+		at91_set_gpio_input(data->rdy_pin, 1);
+
+	/* card detect pin */
+	if (data->det_pin)
+		at91_set_gpio_input(data->det_pin, 1);
+
+	nand_data = *data;
+	platform_device_register(&at91sam9g45_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+static struct i2c_gpio_platform_data pdata_i2c0 = {
+	.sda_pin		= AT91_PIN_PA20,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PA21,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9g45_twi0_device = {
+	.name			= "i2c-gpio",
+	.id			= 0,
+	.dev.platform_data	= &pdata_i2c0,
+};
+
+static struct i2c_gpio_platform_data pdata_i2c1 = {
+	.sda_pin		= AT91_PIN_PB10,
+	.sda_is_open_drain	= 1,
+	.scl_pin		= AT91_PIN_PB11,
+	.scl_is_open_drain	= 1,
+	.udelay			= 2,		/* ~100 kHz */
+};
+
+static struct platform_device at91sam9g45_twi1_device = {
+	.name			= "i2c-gpio",
+	.id			= 1,
+	.dev.platform_data	= &pdata_i2c1,
+};
+
+void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
+{
+	i2c_register_board_info(i2c_id, devices, nr_devices);
+
+	if (i2c_id == 0) {
+		at91_set_GPIO_periph(AT91_PIN_PA20, 1);		/* TWD (SDA) */
+		at91_set_multi_drive(AT91_PIN_PA20, 1);
+
+		at91_set_GPIO_periph(AT91_PIN_PA21, 1);		/* TWCK (SCL) */
+		at91_set_multi_drive(AT91_PIN_PA21, 1);
+
+		platform_device_register(&at91sam9g45_twi0_device);
+	} else {
+		at91_set_GPIO_periph(AT91_PIN_PB10, 1);		/* TWD (SDA) */
+		at91_set_multi_drive(AT91_PIN_PB10, 1);
+
+		at91_set_GPIO_periph(AT91_PIN_PB11, 1);		/* TWCK (SCL) */
+		at91_set_multi_drive(AT91_PIN_PB11, 1);
+
+		platform_device_register(&at91sam9g45_twi1_device);
+	}
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+static struct resource twi0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_TWI0,
+		.end	= AT91SAM9G45_BASE_TWI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_TWI0,
+		.end	= AT91SAM9G45_ID_TWI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_twi0_device = {
+	.name		= "at91_i2c",
+	.id		= 0,
+	.resource	= twi0_resources,
+	.num_resources	= ARRAY_SIZE(twi0_resources),
+};
+
+static struct resource twi1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_TWI1,
+		.end	= AT91SAM9G45_BASE_TWI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_TWI1,
+		.end	= AT91SAM9G45_ID_TWI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_twi1_device = {
+	.name		= "at91_i2c",
+	.id		= 1,
+	.resource	= twi1_resources,
+	.num_resources	= ARRAY_SIZE(twi1_resources),
+};
+
+void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
+{
+	i2c_register_board_info(i2c_id, devices, nr_devices);
+
+	/* pins used for TWI interface */
+	if (i2c_id == 0) {
+		at91_set_A_periph(AT91_PIN_PA20, 0);		/* TWD */
+		at91_set_multi_drive(AT91_PIN_PA20, 1);
+
+		at91_set_A_periph(AT91_PIN_PA21, 0);		/* TWCK */
+		at91_set_multi_drive(AT91_PIN_PA21, 1);
+
+		platform_device_register(&at91sam9g45_twi0_device);
+	} else {
+		at91_set_A_periph(AT91_PIN_PB10, 0);		/* TWD */
+		at91_set_multi_drive(AT91_PIN_PB10, 1);
+
+		at91_set_A_periph(AT91_PIN_PB11, 0);		/* TWCK */
+		at91_set_multi_drive(AT91_PIN_PB11, 1);
+
+		platform_device_register(&at91sam9g45_twi1_device);
+	}
+}
+#else
+void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_SPI0,
+		.end	= AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_SPI0,
+		.end	= AT91SAM9G45_ID_SPI0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_spi0_device = {
+	.name		= "atmel_spi",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi0_resources,
+	.num_resources	= ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
+
+static struct resource spi1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_SPI1,
+		.end	= AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_SPI1,
+		.end	= AT91SAM9G45_ID_SPI1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_spi1_device = {
+	.name		= "atmel_spi",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &spi_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= spi1_resources,
+	.num_resources	= ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+	int i;
+	unsigned long cs_pin;
+	short enable_spi0 = 0;
+	short enable_spi1 = 0;
+
+	/* Choose SPI chip-selects */
+	for (i = 0; i < nr_devices; i++) {
+		if (devices[i].controller_data)
+			cs_pin = (unsigned long) devices[i].controller_data;
+		else if (devices[i].bus_num == 0)
+			cs_pin = spi0_standard_cs[devices[i].chip_select];
+		else
+			cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+		if (devices[i].bus_num == 0)
+			enable_spi0 = 1;
+		else
+			enable_spi1 = 1;
+
+		/* enable chip-select pin */
+		at91_set_gpio_output(cs_pin, 1);
+
+		/* pass chip-select pin to driver */
+		devices[i].controller_data = (void *) cs_pin;
+	}
+
+	spi_register_board_info(devices, nr_devices);
+
+	/* Configure SPI bus(es) */
+	if (enable_spi0) {
+		at91_set_A_periph(AT91_PIN_PB0, 0);	/* SPI0_MISO */
+		at91_set_A_periph(AT91_PIN_PB1, 0);	/* SPI0_MOSI */
+		at91_set_A_periph(AT91_PIN_PB2, 0);	/* SPI0_SPCK */
+
+		at91_clock_associate("spi0_clk", &at91sam9g45_spi0_device.dev, "spi_clk");
+		platform_device_register(&at91sam9g45_spi0_device);
+	}
+	if (enable_spi1) {
+		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_MISO */
+		at91_set_A_periph(AT91_PIN_PB15, 0);	/* SPI1_MOSI */
+		at91_set_A_periph(AT91_PIN_PB16, 0);	/* SPI1_SPCK */
+
+		at91_clock_associate("spi1_clk", &at91sam9g45_spi1_device.dev, "spi_clk");
+		platform_device_register(&at91sam9g45_spi1_device);
+	}
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_LCDC_BASE,
+		.end	= AT91SAM9G45_LCDC_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_LCDC,
+		.end	= AT91SAM9G45_ID_LCDC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91_lcdc_device = {
+	.name		= "atmel_lcdfb",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &lcdc_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &lcdc_data,
+	},
+	.resource	= lcdc_resources,
+	.num_resources	= ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+	if (!data)
+		return;
+
+	at91_set_A_periph(AT91_PIN_PE0, 0);	/* LCDDPWR */
+
+	at91_set_A_periph(AT91_PIN_PE2, 0);	/* LCDCC */
+	at91_set_A_periph(AT91_PIN_PE3, 0);	/* LCDVSYNC */
+	at91_set_A_periph(AT91_PIN_PE4, 0);	/* LCDHSYNC */
+	at91_set_A_periph(AT91_PIN_PE5, 0);	/* LCDDOTCK */
+	at91_set_A_periph(AT91_PIN_PE6, 0);	/* LCDDEN */
+	at91_set_A_periph(AT91_PIN_PE7, 0);	/* LCDD0 */
+	at91_set_A_periph(AT91_PIN_PE8, 0);	/* LCDD1 */
+	at91_set_A_periph(AT91_PIN_PE9, 0);	/* LCDD2 */
+	at91_set_A_periph(AT91_PIN_PE10, 0);	/* LCDD3 */
+	at91_set_A_periph(AT91_PIN_PE11, 0);	/* LCDD4 */
+	at91_set_A_periph(AT91_PIN_PE12, 0);	/* LCDD5 */
+	at91_set_A_periph(AT91_PIN_PE13, 0);	/* LCDD6 */
+	at91_set_A_periph(AT91_PIN_PE14, 0);	/* LCDD7 */
+	at91_set_A_periph(AT91_PIN_PE15, 0);	/* LCDD8 */
+	at91_set_A_periph(AT91_PIN_PE16, 0);	/* LCDD9 */
+	at91_set_A_periph(AT91_PIN_PE17, 0);	/* LCDD10 */
+	at91_set_A_periph(AT91_PIN_PE18, 0);	/* LCDD11 */
+	at91_set_A_periph(AT91_PIN_PE19, 0);	/* LCDD12 */
+	at91_set_A_periph(AT91_PIN_PE20, 0);	/* LCDD13 */
+	at91_set_A_periph(AT91_PIN_PE21, 0);	/* LCDD14 */
+	at91_set_A_periph(AT91_PIN_PE22, 0);	/* LCDD15 */
+	at91_set_A_periph(AT91_PIN_PE23, 0);	/* LCDD16 */
+	at91_set_A_periph(AT91_PIN_PE24, 0);	/* LCDD17 */
+	at91_set_A_periph(AT91_PIN_PE25, 0);	/* LCDD18 */
+	at91_set_A_periph(AT91_PIN_PE26, 0);	/* LCDD19 */
+	at91_set_A_periph(AT91_PIN_PE27, 0);	/* LCDD20 */
+	at91_set_A_periph(AT91_PIN_PE28, 0);	/* LCDD21 */
+	at91_set_A_periph(AT91_PIN_PE29, 0);	/* LCDD22 */
+	at91_set_A_periph(AT91_PIN_PE30, 0);	/* LCDD23 */
+
+	lcdc_data = *data;
+	platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+static struct resource tcb0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_TCB0,
+		.end	= AT91SAM9G45_BASE_TCB0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_TCB,
+		.end	= AT91SAM9G45_ID_TCB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_tcb0_device = {
+	.name		= "atmel_tcb",
+	.id		= 0,
+	.resource	= tcb0_resources,
+	.num_resources	= ARRAY_SIZE(tcb0_resources),
+};
+
+/* TCB1 begins with TC3 */
+static struct resource tcb1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_TCB1,
+		.end	= AT91SAM9G45_BASE_TCB1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_TCB,
+		.end	= AT91SAM9G45_ID_TCB,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_tcb1_device = {
+	.name		= "atmel_tcb",
+	.id		= 1,
+	.resource	= tcb1_resources,
+	.num_resources	= ARRAY_SIZE(tcb1_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+	/* this chip has one clock and irq for all six TC channels */
+	at91_clock_associate("tcb_clk", &at91sam9g45_tcb0_device.dev, "t0_clk");
+	platform_device_register(&at91sam9g45_tcb0_device);
+	at91_clock_associate("tcb_clk", &at91sam9g45_tcb1_device.dev, "t0_clk");
+	platform_device_register(&at91sam9g45_tcb1_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTC
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
+static struct platform_device at91sam9g45_rtc_device = {
+	.name		= "at91_rtc",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_rtc(void)
+{
+	platform_device_register(&at91sam9g45_rtc_device);
+}
+#else
+static void __init at91_add_device_rtc(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+	{
+		.start	= AT91_BASE_SYS + AT91_RTT,
+		.end	= AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device at91sam9g45_rtt_device = {
+	.name		= "at91_rtt",
+	.id		= 0,
+	.resource	= rtt_resources,
+	.num_resources	= ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+	platform_device_register(&at91sam9g45_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ *  Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9_WATCHDOG) || defined(CONFIG_AT91SAM9_WATCHDOG_MODULE)
+static struct platform_device at91sam9g45_wdt_device = {
+	.name		= "at91_wdt",
+	.id		= -1,
+	.num_resources	= 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+	platform_device_register(&at91sam9g45_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_PWMC,
+		.end	= AT91SAM9G45_BASE_PWMC + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_PWMC,
+		.end	= AT91SAM9G45_ID_PWMC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_pwm0_device = {
+	.name	= "atmel_pwm",
+	.id	= -1,
+	.dev	= {
+		.platform_data		= &pwm_mask,
+	},
+	.resource	= pwm_resources,
+	.num_resources	= ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+	if (mask & (1 << AT91_PWM0))
+		at91_set_B_periph(AT91_PIN_PD24, 1);	/* enable PWM0 */
+
+	if (mask & (1 << AT91_PWM1))
+		at91_set_B_periph(AT91_PIN_PD31, 1);	/* enable PWM1 */
+
+	if (mask & (1 << AT91_PWM2))
+		at91_set_B_periph(AT91_PIN_PD26, 1);	/* enable PWM2 */
+
+	if (mask & (1 << AT91_PWM3))
+		at91_set_B_periph(AT91_PIN_PD0, 1);	/* enable PWM3 */
+
+	pwm_mask = mask;
+
+	platform_device_register(&at91sam9g45_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_SSC0,
+		.end	= AT91SAM9G45_BASE_SSC0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_SSC0,
+		.end	= AT91SAM9G45_ID_SSC0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_ssc0_device = {
+	.name	= "ssc",
+	.id	= 0,
+	.dev	= {
+		.dma_mask		= &ssc0_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc0_resources,
+	.num_resources	= ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PD1, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PD0, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PD2, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PD3, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PD4, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PD5, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_SSC1,
+		.end	= AT91SAM9G45_BASE_SSC1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_SSC1,
+		.end	= AT91SAM9G45_ID_SSC1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device at91sam9g45_ssc1_device = {
+	.name	= "ssc",
+	.id	= 1,
+	.dev	= {
+		.dma_mask		= &ssc1_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= ssc1_resources,
+	.num_resources	= ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+	if (pins & ATMEL_SSC_TF)
+		at91_set_A_periph(AT91_PIN_PD14, 1);
+	if (pins & ATMEL_SSC_TK)
+		at91_set_A_periph(AT91_PIN_PD12, 1);
+	if (pins & ATMEL_SSC_TD)
+		at91_set_A_periph(AT91_PIN_PD10, 1);
+	if (pins & ATMEL_SSC_RD)
+		at91_set_A_periph(AT91_PIN_PD11, 1);
+	if (pins & ATMEL_SSC_RK)
+		at91_set_A_periph(AT91_PIN_PD13, 1);
+	if (pins & ATMEL_SSC_RF)
+		at91_set_A_periph(AT91_PIN_PD15, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver.  For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	/*
+	 * NOTE: caller is responsible for passing information matching
+	 * "pins" to whatever will be using each particular controller.
+	 */
+	switch (id) {
+	case AT91SAM9G45_ID_SSC0:
+		pdev = &at91sam9g45_ssc0_device;
+		configure_ssc0_pins(pins);
+		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
+		break;
+	case AT91SAM9G45_ID_SSC1:
+		pdev = &at91sam9g45_ssc1_device;
+		configure_ssc1_pins(pins);
+		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
+		break;
+	default:
+		return;
+	}
+
+	platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ *  UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+	[0] = {
+		.start	= AT91_VA_BASE_SYS + AT91_DBGU,
+		.end	= AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91_ID_SYS,
+		.end	= AT91_ID_SYS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data dbgu_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,
+	.regs		= (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_dbgu_device = {
+	.name		= "atmel_usart",
+	.id		= 0,
+	.dev		= {
+				.dma_mask		= &dbgu_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &dbgu_data,
+	},
+	.resource	= dbgu_resources,
+	.num_resources	= ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+	at91_set_A_periph(AT91_PIN_PB12, 0);		/* DRXD */
+	at91_set_A_periph(AT91_PIN_PB13, 1);		/* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_US0,
+		.end	= AT91SAM9G45_BASE_US0 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_US0,
+		.end	= AT91SAM9G45_ID_US0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart0_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart0_device = {
+	.name		= "atmel_usart",
+	.id		= 1,
+	.dev		= {
+				.dma_mask		= &uart0_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart0_data,
+	},
+	.resource	= uart0_resources,
+	.num_resources	= ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PB19, 1);		/* TXD0 */
+	at91_set_A_periph(AT91_PIN_PB18, 0);		/* RXD0 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PB17, 0);	/* RTS0 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PB15, 0);	/* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_US1,
+		.end	= AT91SAM9G45_BASE_US1 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_US1,
+		.end	= AT91SAM9G45_ID_US1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart1_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart1_device = {
+	.name		= "atmel_usart",
+	.id		= 2,
+	.dev		= {
+				.dma_mask		= &uart1_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart1_data,
+	},
+	.resource	= uart1_resources,
+	.num_resources	= ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PB4, 1);		/* TXD1 */
+	at91_set_A_periph(AT91_PIN_PB5, 0);		/* RXD1 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_A_periph(AT91_PIN_PD16, 0);	/* RTS1 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_A_periph(AT91_PIN_PD17, 0);	/* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_US2,
+		.end	= AT91SAM9G45_BASE_US2 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_US2,
+		.end	= AT91SAM9G45_ID_US2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart2_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart2_device = {
+	.name		= "atmel_usart",
+	.id		= 3,
+	.dev		= {
+				.dma_mask		= &uart2_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart2_data,
+	},
+	.resource	= uart2_resources,
+	.num_resources	= ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PB6, 1);		/* TXD2 */
+	at91_set_A_periph(AT91_PIN_PB7, 0);		/* RXD2 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PC9, 0);	/* RTS2 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PC11, 0);	/* CTS2 */
+}
+
+static struct resource uart3_resources[] = {
+	[0] = {
+		.start	= AT91SAM9G45_BASE_US3,
+		.end	= AT91SAM9G45_BASE_US3 + SZ_16K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9G45_ID_US3,
+		.end	= AT91SAM9G45_ID_US3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct atmel_uart_data uart3_data = {
+	.use_dma_tx	= 1,
+	.use_dma_rx	= 1,
+};
+
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart3_device = {
+	.name		= "atmel_usart",
+	.id		= 4,
+	.dev		= {
+				.dma_mask		= &uart3_dmamask,
+				.coherent_dma_mask	= DMA_BIT_MASK(32),
+				.platform_data		= &uart3_data,
+	},
+	.resource	= uart3_resources,
+	.num_resources	= ARRAY_SIZE(uart3_resources),
+};
+
+static inline void configure_usart3_pins(unsigned pins)
+{
+	at91_set_A_periph(AT91_PIN_PB8, 1);		/* TXD3 */
+	at91_set_A_periph(AT91_PIN_PB9, 0);		/* RXD3 */
+
+	if (pins & ATMEL_UART_RTS)
+		at91_set_B_periph(AT91_PIN_PA23, 0);	/* RTS3 */
+	if (pins & ATMEL_UART_CTS)
+		at91_set_B_periph(AT91_PIN_PA24, 0);	/* CTS3 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART];	/* the UARTs to use */
+struct platform_device *atmel_default_console_device;	/* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+	struct platform_device *pdev;
+
+	switch (id) {
+		case 0:		/* DBGU */
+			pdev = &at91sam9g45_dbgu_device;
+			configure_dbgu_pins();
+			at91_clock_associate("mck", &pdev->dev, "usart");
+			break;
+		case AT91SAM9G45_ID_US0:
+			pdev = &at91sam9g45_uart0_device;
+			configure_usart0_pins(pins);
+			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9G45_ID_US1:
+			pdev = &at91sam9g45_uart1_device;
+			configure_usart1_pins(pins);
+			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9G45_ID_US2:
+			pdev = &at91sam9g45_uart2_device;
+			configure_usart2_pins(pins);
+			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
+			break;
+		case AT91SAM9G45_ID_US3:
+			pdev = &at91sam9g45_uart3_device;
+			configure_usart3_pins(pins);
+			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
+			break;
+		default:
+			return;
+	}
+	pdev->id = portnr;		/* update to mapped ID */
+
+	if (portnr < ATMEL_MAX_UART)
+		at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+	if (portnr < ATMEL_MAX_UART)
+		atmel_default_console_device = at91_uarts[portnr];
+}
+
+void __init at91_add_device_serial(void)
+{
+	int i;
+
+	for (i = 0; i < ATMEL_MAX_UART; i++) {
+		if (at91_uarts[i])
+			platform_device_register(at91_uarts[i]);
+	}
+
+	if (!atmel_default_console_device)
+		printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+	at91_add_device_rtc();
+	at91_add_device_rtt();
+	at91_add_device_watchdog();
+	at91_add_device_tc();
+	return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
index 970fd6b..61e52b6 100644
--- a/arch/arm/mach-at91/board-afeb-9260v1.c
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -174,6 +174,16 @@ static struct i2c_board_info __initdata afeb9260_i2c_devices[] = {
 	},
 };
 
+/*
+ * IDE (CF True IDE mode)
+ */
+static struct at91_cf_data afeb9260_cf_data = {
+	.chipselect = 4,
+	.irq_pin    = AT91_PIN_PA6,
+	.rst_pin    = AT91_PIN_PA7,
+	.flags      = AT91_CF_TRUE_IDE,
+};
+
 static void __init afeb9260_board_init(void)
 {
 	/* Serial */
@@ -202,6 +212,8 @@ static void __init afeb9260_board_init(void)
 			ARRAY_SIZE(afeb9260_i2c_devices));
 	/* Audio */
 	at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
+	/* IDE */
+	at91_add_device_cf(&afeb9260_cf_data);
 }
 
 MACHINE_START(AFEB9260, "Custom afeb9260 board")
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
new file mode 100644
index 0000000..4bc2e9f
--- /dev/null
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -0,0 +1,385 @@
+/*
+ * linux/arch/arm/mach-at91/board-cpu9krea.c
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2006 Atmel
+ *  Copyright (C) 2009 Eric Benard - eric@eukrea.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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91sam9260_matrix.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+static void __init cpu9krea_map_io(void)
+{
+	/* Initialize processor: 18.432 MHz crystal */
+	at91sam9260_initialize(18432000);
+
+	/* DGBU on ttyS0. (Rx & Tx only) */
+	at91_register_uart(0, 0, 0);
+
+	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+	at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
+		ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
+		ATMEL_UART_DCD | ATMEL_UART_RI);
+
+	/* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+	at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS |
+		ATMEL_UART_RTS);
+
+	/* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */
+	at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS |
+		ATMEL_UART_RTS);
+
+	/* USART3 on ttyS4. (Rx, Tx) */
+	at91_register_uart(AT91SAM9260_ID_US3, 4, 0);
+
+	/* USART4 on ttyS5. (Rx, Tx) */
+	at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+
+	/* USART5 on ttyS6. (Rx, Tx) */
+	at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init cpu9krea_init_irq(void)
+{
+	at91sam9260_init_interrupts(NULL);
+}
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata cpu9krea_usbh_data = {
+	.ports		= 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata cpu9krea_udc_data = {
+	.vbus_pin	= AT91_PIN_PC8,
+	.pullup_pin	= 0,		/* pull-up driven by UDC */
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata cpu9krea_macb_data = {
+	.is_rmii	= 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct atmel_nand_data __initdata cpu9krea_nand_data = {
+	.ale		= 21,
+	.cle		= 22,
+	.rdy_pin	= AT91_PIN_PC13,
+	.enable_pin	= AT91_PIN_PC14,
+	.bus_width_16	= 0,
+};
+
+#ifdef CONFIG_MACH_CPU9260
+static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 1,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 1,
+
+	.ncs_read_pulse		= 3,
+	.nrd_pulse		= 3,
+	.ncs_write_pulse	= 3,
+	.nwe_pulse		= 3,
+
+	.read_cycle		= 5,
+	.write_cycle		= 5,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+		| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+	.tdf_cycles		= 2,
+};
+#else
+static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 2,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 2,
+
+	.ncs_read_pulse		= 4,
+	.nrd_pulse		= 4,
+	.ncs_write_pulse	= 4,
+	.nwe_pulse		= 4,
+
+	.read_cycle		= 7,
+	.write_cycle		= 7,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+		| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+	.tdf_cycles		= 3,
+};
+#endif
+
+static void __init cpu9krea_add_device_nand(void)
+{
+	sam9_smc_configure(3, &cpu9krea_nand_smc_config);
+	at91_add_device_nand(&cpu9krea_nand_data);
+}
+
+/*
+ * NOR flash
+ */
+static struct physmap_flash_data cpuat9260_nor_data = {
+	.width		= 2,
+};
+
+#define NOR_BASE	AT91_CHIPSELECT_0
+#define NOR_SIZE	SZ_64M
+
+static struct resource nor_flash_resources[] = {
+	{
+		.start	= NOR_BASE,
+		.end	= NOR_BASE + NOR_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device cpu9krea_nor_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &cpuat9260_nor_data,
+	},
+	.resource	= nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(nor_flash_resources),
+};
+
+#ifdef CONFIG_MACH_CPU9260
+static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 1,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 1,
+
+	.ncs_read_pulse		= 10,
+	.nrd_pulse		= 10,
+	.ncs_write_pulse	= 6,
+	.nwe_pulse		= 6,
+
+	.read_cycle		= 12,
+	.write_cycle		= 8,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+			| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
+			| AT91_SMC_DBW_16,
+	.tdf_cycles		= 2,
+};
+#else
+static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 1,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 1,
+
+	.ncs_read_pulse		= 13,
+	.nrd_pulse		= 13,
+	.ncs_write_pulse	= 8,
+	.nwe_pulse		= 8,
+
+	.read_cycle		= 15,
+	.write_cycle		= 10,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+			| AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
+			| AT91_SMC_DBW_16,
+	.tdf_cycles		= 2,
+};
+#endif
+
+static __init void cpu9krea_add_device_nor(void)
+{
+	unsigned long csa;
+
+	csa = at91_sys_read(AT91_MATRIX_EBICSA);
+	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V);
+
+	/* configure chip-select 0 (NOR) */
+	sam9_smc_configure(0, &cpu9krea_nor_smc_config);
+
+	platform_device_register(&cpu9krea_nor_flash);
+}
+
+/*
+ * LEDs
+ */
+static struct gpio_led cpu9krea_leds[] = {
+	{	/* LED1 */
+		.name			= "LED1",
+		.gpio			= AT91_PIN_PC11,
+		.active_low		= 1,
+		.default_trigger	= "timer",
+	},
+	{	/* LED2 */
+		.name			= "LED2",
+		.gpio			= AT91_PIN_PC12,
+		.active_low		= 1,
+		.default_trigger	= "heartbeat",
+	},
+	{	/* LED3 */
+		.name			= "LED3",
+		.gpio			= AT91_PIN_PC7,
+		.active_low		= 1,
+		.default_trigger	= "none",
+	},
+	{	/* LED4 */
+		.name			= "LED4",
+		.gpio			= AT91_PIN_PC9,
+		.active_low		= 1,
+		.default_trigger	= "none",
+	}
+};
+
+static struct i2c_board_info __initdata cpu9krea_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("rtc-ds1307", 0x68),
+		.type	= "ds1339",
+	},
+};
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button cpu9krea_buttons[] = {
+	{
+		.gpio		= AT91_PIN_PC3,
+		.code		= BTN_0,
+		.desc		= "BP1",
+		.active_low	= 1,
+		.wakeup		= 1,
+	},
+	{
+		.gpio		= AT91_PIN_PB20,
+		.code		= BTN_1,
+		.desc		= "BP2",
+		.active_low	= 1,
+		.wakeup		= 1,
+	}
+};
+
+static struct gpio_keys_platform_data cpu9krea_button_data = {
+	.buttons	= cpu9krea_buttons,
+	.nbuttons	= ARRAY_SIZE(cpu9krea_buttons),
+};
+
+static struct platform_device cpu9krea_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &cpu9krea_button_data,
+	}
+};
+
+static void __init cpu9krea_add_device_buttons(void)
+{
+	at91_set_gpio_input(AT91_PIN_PC3, 1);	/* BP1 */
+	at91_set_deglitch(AT91_PIN_PC3, 1);
+	at91_set_gpio_input(AT91_PIN_PB20, 1);	/* BP2 */
+	at91_set_deglitch(AT91_PIN_PB20, 1);
+
+	platform_device_register(&cpu9krea_button_device);
+}
+#else
+static void __init cpu9krea_add_device_buttons(void)
+{
+}
+#endif
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata cpu9krea_mmc_data = {
+	.slot_b		= 0,
+	.wire4		= 1,
+	.det_pin	= AT91_PIN_PA29,
+};
+
+static void __init cpu9krea_board_init(void)
+{
+	/* NOR */
+	cpu9krea_add_device_nor();
+	/* Serial */
+	at91_add_device_serial();
+	/* USB Host */
+	at91_add_device_usbh(&cpu9krea_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&cpu9krea_udc_data);
+	/* NAND */
+	cpu9krea_add_device_nand();
+	/* Ethernet */
+	at91_add_device_eth(&cpu9krea_macb_data);
+	/* MMC */
+	at91_add_device_mmc(0, &cpu9krea_mmc_data);
+	/* I2C */
+	at91_add_device_i2c(cpu9krea_i2c_devices,
+		ARRAY_SIZE(cpu9krea_i2c_devices));
+	/* LEDs */
+	at91_gpio_leds(cpu9krea_leds, ARRAY_SIZE(cpu9krea_leds));
+	/* Push Buttons */
+	cpu9krea_add_device_buttons();
+}
+
+#ifdef CONFIG_MACH_CPU9260
+MACHINE_START(CPUAT9260, "Eukrea CPU9260")
+#else
+MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
+#endif
+	/* Maintainer: Eric Benard - EUKREA Electromatique */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91sam926x_timer,
+	.map_io		= cpu9krea_map_io,
+	.init_irq	= cpu9krea_init_irq,
+	.init_machine	= cpu9krea_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c
new file mode 100644
index 0000000..a28d996
--- /dev/null
+++ b/arch/arm/mach-at91/board-cpuat91.c
@@ -0,0 +1,185 @@
+/*
+ * linux/arch/arm/mach-at91/board-cpuat91.c
+ *
+ *  Copyright (C) 2009 Eric Benard - eric@eukrea.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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+static struct gpio_led cpuat91_leds[] = {
+	{
+		.name			= "led1",
+		.default_trigger	= "heartbeat",
+		.active_low		= 1,
+		.gpio			= AT91_PIN_PC0,
+	},
+};
+
+static void __init cpuat91_map_io(void)
+{
+	/* Initialize processor: 18.432 MHz crystal */
+	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+
+	/* DBGU on ttyS0. (Rx & Tx only) */
+	at91_register_uart(0, 0, 0);
+
+	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */
+	at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS |
+		ATMEL_UART_RTS);
+
+	/* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+	at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS |
+		ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
+		ATMEL_UART_DCD | ATMEL_UART_RI);
+
+	/* USART2 on ttyS3 (Rx, Tx) */
+	at91_register_uart(AT91RM9200_ID_US2, 3, 0);
+
+	/* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */
+	at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS |
+		ATMEL_UART_RTS);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init cpuat91_init_irq(void)
+{
+	at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata cpuat91_eth_data = {
+	.is_rmii	= 1,
+};
+
+static struct at91_usbh_data __initdata cpuat91_usbh_data = {
+	.ports		= 1,
+};
+
+static struct at91_udc_data __initdata cpuat91_udc_data = {
+	.vbus_pin	= AT91_PIN_PC15,
+	.pullup_pin	= AT91_PIN_PC14,
+};
+
+static struct at91_mmc_data __initdata cpuat91_mmc_data = {
+	.det_pin	= AT91_PIN_PC2,
+	.wire4		= 1,
+};
+
+static struct physmap_flash_data cpuat91_flash_data = {
+	.width		= 2,
+};
+
+static struct resource cpuat91_flash_resource = {
+	.start		= AT91_CHIPSELECT_0,
+	.end		= AT91_CHIPSELECT_0 + SZ_16M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device cpuat91_norflash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev	= {
+		.platform_data	= &cpuat91_flash_data,
+	},
+	.resource	= &cpuat91_flash_resource,
+	.num_resources	= 1,
+};
+
+#ifdef CONFIG_MTD_PLATRAM
+struct platdata_mtd_ram at91_sram_pdata = {
+	.mapname	= "SRAM",
+	.bankwidth	= 2,
+};
+
+static struct resource at91_sram_resource[] = {
+	[0] = {
+		.start = AT91RM9200_SRAM_BASE,
+		.end   = AT91RM9200_SRAM_BASE + AT91RM9200_SRAM_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device at91_sram = {
+	.name		= "mtd-ram",
+	.id		= 0,
+	.resource	= at91_sram_resource,
+	.num_resources	= ARRAY_SIZE(at91_sram_resource),
+	.dev	= {
+		.platform_data = &at91_sram_pdata,
+	},
+};
+#endif /* MTD_PLATRAM */
+
+static struct platform_device *platform_devices[] __initdata = {
+	&cpuat91_norflash,
+#ifdef CONFIG_MTD_PLATRAM
+	&at91_sram,
+#endif /* CONFIG_MTD_PLATRAM */
+};
+
+static void __init cpuat91_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* LEDs. */
+	at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds));
+	/* Ethernet */
+	at91_add_device_eth(&cpuat91_eth_data);
+	/* USB Host */
+	at91_add_device_usbh(&cpuat91_usbh_data);
+	/* USB Device */
+	at91_add_device_udc(&cpuat91_udc_data);
+	/* MMC */
+	at91_add_device_mmc(0, &cpuat91_mmc_data);
+	/* I2C */
+	at91_add_device_i2c(NULL, 0);
+	/* Platform devices */
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+MACHINE_START(CPUAT91, "Eukrea")
+	/* Maintainer: Eric Benard - EUKREA Electromatique */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91rm9200_timer,
+	.map_io		= cpuat91_map_io,
+	.init_irq	= cpuat91_init_irq,
+	.init_machine	= cpuat91_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index d5266da..f9b1999 100644
--- a/arch/arm/mach-at91/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -287,7 +287,11 @@ static void __init ek_add_device_ts(void) {}
  */
 static struct at73c213_board_info at73c213_data = {
 	.ssc_id		= 1,
+#if defined(CONFIG_MACH_AT91SAM9261EK)
 	.shortname	= "AT91SAM9261-EK external DAC",
+#else
+	.shortname	= "AT91SAM9G10-EK external DAC",
+#endif
 };
 
 #if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
@@ -414,6 +418,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
 	.default_monspecs		= &at91fb_default_stn_monspecs,
 	.atmel_lcdfb_power_control	= at91_lcdc_stn_power_control,
 	.guard_time			= 1,
+#if defined(CONFIG_MACH_AT91SAM9G10EK)
+	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
+#endif
 };
 
 #else
@@ -467,6 +474,9 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
 	.default_monspecs		= &at91fb_default_tft_monspecs,
 	.atmel_lcdfb_power_control	= at91_lcdc_tft_power_control,
 	.guard_time			= 1,
+#if defined(CONFIG_MACH_AT91SAM9G10EK)
+	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
+#endif
 };
 #endif
 
@@ -600,7 +610,11 @@ static void __init ek_board_init(void)
 	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
 }
 
+#if defined(CONFIG_MACH_AT91SAM9261EK)
 MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
+#else
+MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
+#endif
 	/* Maintainer: Atmel */
 	.phys_io	= AT91_BASE_SYS,
 	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
index 57d5252..1bf7bd4 100644
--- a/arch/arm/mach-at91/board-sam9263ek.c
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -364,9 +364,9 @@ static void __init ek_add_device_buttons(void) {}
 
 /*
  * AC97
+ * reset_pin is not connected: NRST
  */
-static struct atmel_ac97_data ek_ac97_data = {
-	.reset_pin	= AT91_PIN_PA13,
+static struct ac97c_platform_data ek_ac97_data = {
 };
 
 
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index a55398e..ca470d5 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -273,6 +273,7 @@ static void __init ek_add_device_buttons(void) {}
 static struct i2c_board_info __initdata ek_i2c_devices[] = {
 	{
 		I2C_BOARD_INFO("24c512", 0x50),
+		I2C_BOARD_INFO("wm8731", 0x1b),
 	},
 };
 
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
new file mode 100644
index 0000000..b8558ea
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -0,0 +1,389 @@
+/*
+ *  Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
+ *
+ *  Covers: * AT91SAM9G45-EKES  board
+ *          * AT91SAM9M10G45-EK board
+ *
+ *  Copyright (C) 2009 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/fb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_map_io(void)
+{
+	/* Initialize processor: 12.000 MHz crystal */
+	at91sam9g45_initialize(12000000);
+
+	/* DGBU on ttyS0. (Rx & Tx only) */
+	at91_register_uart(0, 0, 0);
+
+	/* USART0 not connected on the -EK board */
+	/* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+	at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+	/* set serial console to ttyS0 (ie, DBGU) */
+	at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+	at91sam9g45_init_interrupts(NULL);
+}
+
+
+/*
+ * USB HS Host port (common to OHCI & EHCI)
+ */
+static struct at91_usbh_data __initdata ek_usbh_hs_data = {
+	.ports		= 2,
+	.vbus_pin	= {AT91_PIN_PD1, AT91_PIN_PD3},
+};
+
+
+/*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata ek_usba_udc_data = {
+	.vbus_pin	= AT91_PIN_PB19,
+};
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+	{	/* DataFlash chip */
+		.modalias	= "mtd_dataflash",
+		.chip_select	= 0,
+		.max_speed_hz	= 15 * 1000 * 1000,
+		.bus_num	= 0,
+	},
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+	.phy_irq_pin	= AT91_PIN_PD5,
+	.is_rmii	= 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+	{
+		.name	= "Partition 1",
+		.offset	= 0,
+		.size	= SZ_64M,
+	},
+	{
+		.name	= "Partition 2",
+		.offset	= MTDPART_OFS_NXTBLK,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(ek_nand_partition);
+	return ek_nand_partition;
+}
+
+/* det_pin is not connected */
+static struct atmel_nand_data __initdata ek_nand_data = {
+	.ale		= 21,
+	.cle		= 22,
+	.rdy_pin	= AT91_PIN_PC8,
+	.enable_pin	= AT91_PIN_PC14,
+	.partition_info	= nand_partitions,
+#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
+	.bus_width_16	= 1,
+#else
+	.bus_width_16	= 0,
+#endif
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 2,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 2,
+
+	.ncs_read_pulse		= 4,
+	.nrd_pulse		= 4,
+	.ncs_write_pulse	= 4,
+	.nwe_pulse		= 4,
+
+	.read_cycle		= 7,
+	.write_cycle		= 7,
+
+	.mode			= AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+	.tdf_cycles		= 3,
+};
+
+static void __init ek_add_device_nand(void)
+{
+	/* setup bus-width (8 or 16) */
+	if (ek_nand_data.bus_width_16)
+		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+	else
+		ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+	/* configure chip-select 3 (NAND) */
+	sam9_smc_configure(3, &ek_nand_smc_config);
+
+	at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+	{
+		.name           = "LG",
+		.refresh	= 60,
+		.xres		= 480,		.yres		= 272,
+		.pixclock	= KHZ2PICOS(9000),
+
+		.left_margin	= 1,		.right_margin	= 1,
+		.upper_margin	= 40,		.lower_margin	= 1,
+		.hsync_len	= 45,		.vsync_len	= 1,
+
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+	.manufacturer	= "LG",
+	.monitor        = "LB043WQ1",
+
+	.modedb		= at91_tft_vga_modes,
+	.modedb_len	= ARRAY_SIZE(at91_tft_vga_modes),
+	.hfmin		= 15000,
+	.hfmax		= 17640,
+	.vfmin		= 57,
+	.vfmax		= 67,
+};
+
+#define AT91SAM9G45_DEFAULT_LCDCON2 	(ATMEL_LCDC_MEMOR_LITTLE \
+					| ATMEL_LCDC_DISTYPE_TFT \
+					| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+	.lcdcon_is_backlight		= true,
+	.default_bpp			= 32,
+	.default_dmacon			= ATMEL_LCDC_DMAEN,
+	.default_lcdcon2		= AT91SAM9G45_DEFAULT_LCDCON2,
+	.default_monspecs		= &at91fb_default_monspecs,
+	.guard_time			= 9,
+	.lcd_wiring_mode		= ATMEL_LCDC_WIRING_RGB,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+#endif
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+	{	/* BP1, "leftclic" */
+		.code		= BTN_LEFT,
+		.gpio		= AT91_PIN_PB6,
+		.active_low	= 1,
+		.desc		= "left_click",
+		.wakeup		= 1,
+	},
+	{	/* BP2, "rightclic" */
+		.code		= BTN_RIGHT,
+		.gpio		= AT91_PIN_PB7,
+		.active_low	= 1,
+		.desc		= "right_click",
+		.wakeup		= 1,
+	},
+		/* BP3, "joystick" */
+	{
+		.code		= KEY_LEFT,
+		.gpio		= AT91_PIN_PB14,
+		.active_low	= 1,
+		.desc		= "Joystick Left",
+	},
+	{
+		.code		= KEY_RIGHT,
+		.gpio		= AT91_PIN_PB15,
+		.active_low	= 1,
+		.desc		= "Joystick Right",
+	},
+	{
+		.code		= KEY_UP,
+		.gpio		= AT91_PIN_PB16,
+		.active_low	= 1,
+		.desc		= "Joystick Up",
+	},
+	{
+		.code		= KEY_DOWN,
+		.gpio		= AT91_PIN_PB17,
+		.active_low	= 1,
+		.desc		= "Joystick Down",
+	},
+	{
+		.code		= KEY_ENTER,
+		.gpio		= AT91_PIN_PB18,
+		.active_low	= 1,
+		.desc		= "Joystick Press",
+	},
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+	.buttons	= ek_buttons,
+	.nbuttons	= ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &ek_button_data,
+	}
+};
+
+static void __init ek_add_device_buttons(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) {
+		at91_set_GPIO_periph(ek_buttons[i].gpio, 1);
+		at91_set_deglitch(ek_buttons[i].gpio, 1);
+	}
+
+	platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
+/*
+ * LEDs ... these could all be PWM-driven, for variable brightness
+ */
+static struct gpio_led ek_leds[] = {
+	{	/* "top" led, red, powerled */
+		.name			= "d8",
+		.gpio			= AT91_PIN_PD30,
+		.default_trigger	= "heartbeat",
+	},
+	{	/* "left" led, green, userled2, pwm3 */
+		.name			= "d6",
+		.gpio			= AT91_PIN_PD0,
+		.active_low		= 1,
+		.default_trigger	= "nand-disk",
+	},
+#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE))
+	{	/* "right" led, green, userled1, pwm1 */
+		.name			= "d7",
+		.gpio			= AT91_PIN_PD31,
+		.active_low		= 1,
+		.default_trigger	= "mmc0",
+	},
+#endif
+};
+
+
+/*
+ * PWM Leds
+ */
+static struct gpio_led ek_pwm_led[] = {
+#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)
+	{	/* "right" led, green, userled1, pwm1 */
+		.name			= "d7",
+		.gpio			= 1,	/* is PWM channel number */
+		.active_low		= 1,
+		.default_trigger	= "none",
+	},
+#endif
+};
+
+
+
+static void __init ek_board_init(void)
+{
+	/* Serial */
+	at91_add_device_serial();
+	/* USB HS Host */
+	at91_add_device_usbh_ohci(&ek_usbh_hs_data);
+	/* USB HS Device */
+	at91_add_device_usba(&ek_usba_udc_data);
+	/* SPI */
+	at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+	/* Ethernet */
+	at91_add_device_eth(&ek_macb_data);
+	/* NAND */
+	ek_add_device_nand();
+	/* I2C */
+	at91_add_device_i2c(0, NULL, 0);
+	/* LCD Controller */
+	at91_add_device_lcdc(&ek_lcdc_data);
+	/* Push Buttons */
+	ek_add_device_buttons();
+	/* LEDs */
+	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+	at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+}
+
+MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
+	/* Maintainer: Atmel */
+	.phys_io	= AT91_BASE_SYS,
+	.io_pg_offst	= (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+	.boot_params	= AT91_SDRAM_BASE + 0x100,
+	.timer		= &at91sam926x_timer,
+	.map_io		= ek_map_io,
+	.init_irq	= ek_init_irq,
+	.init_machine	= ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
index f6b5672..9d07679 100644
--- a/arch/arm/mach-at91/board-sam9rlek.c
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -15,6 +15,8 @@
 #include <linux/spi/spi.h>
 #include <linux/fb.h>
 #include <linux/clk.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
 
 #include <video/atmel_lcdc.h>
 
@@ -208,6 +210,79 @@ static struct atmel_lcdfb_info __initdata ek_lcdc_data;
 #endif
 
 
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+	{	/* "bottom" led, green, userled1 to be defined */
+		.name			= "ds1",
+		.gpio			= AT91_PIN_PD15,
+		.active_low		= 1,
+		.default_trigger	= "none",
+	},
+	{	/* "bottom" led, green, userled2 to be defined */
+		.name			= "ds2",
+		.gpio			= AT91_PIN_PD16,
+		.active_low		= 1,
+		.default_trigger	= "none",
+	},
+	{	/* "power" led, yellow */
+		.name			= "ds3",
+		.gpio			= AT91_PIN_PD14,
+		.default_trigger	= "heartbeat",
+	}
+};
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+	{
+		.gpio		= AT91_PIN_PB0,
+		.code		= BTN_2,
+		.desc		= "Right Click",
+		.active_low	= 1,
+		.wakeup		= 1,
+	},
+	{
+		.gpio		= AT91_PIN_PB1,
+		.code		= BTN_1,
+		.desc		= "Left Click",
+		.active_low	= 1,
+		.wakeup		= 1,
+	}
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+	.buttons	= ek_buttons,
+	.nbuttons	= ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.num_resources	= 0,
+	.dev		= {
+		.platform_data	= &ek_button_data,
+	}
+};
+
+static void __init ek_add_device_buttons(void)
+{
+	at91_set_gpio_input(AT91_PIN_PB1, 1);	/* btn1 */
+	at91_set_deglitch(AT91_PIN_PB1, 1);
+	at91_set_gpio_input(AT91_PIN_PB0, 1);	/* btn2 */
+	at91_set_deglitch(AT91_PIN_PB0, 1);
+
+	platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
 static void __init ek_board_init(void)
 {
 	/* Serial */
@@ -226,6 +301,10 @@ static void __init ek_board_init(void)
 	at91_add_device_lcdc(&ek_lcdc_data);
 	/* Touch Screen Controller */
 	at91_add_device_tsadcc();
+	/* LEDs */
+	at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+	/* Push Buttons */
+	ek_add_device_buttons();
 }
 
 MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index bac578f..c042dcf 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -47,20 +47,25 @@
  * Chips have some kind of clocks : group them by functionality
  */
 #define cpu_has_utmi()		(  cpu_is_at91cap9() \
-				|| cpu_is_at91sam9rl())
+				|| cpu_is_at91sam9rl() \
+				|| cpu_is_at91sam9g45())
 
-#define cpu_has_800M_plla()	(cpu_is_at91sam9g20())
+#define cpu_has_800M_plla()	(  cpu_is_at91sam9g20() \
+				|| cpu_is_at91sam9g45())
 
-#define cpu_has_pllb()		(!cpu_is_at91sam9rl())
+#define cpu_has_300M_plla()	(cpu_is_at91sam9g10())
 
-#define cpu_has_upll()		(0)
+#define cpu_has_pllb()		(!(cpu_is_at91sam9rl() \
+				|| cpu_is_at91sam9g45()))
+
+#define cpu_has_upll()		(cpu_is_at91sam9g45())
 
 /* USB host HS & FS */
 #define cpu_has_uhp()		(!cpu_is_at91sam9rl())
 
 /* USB device FS only */
-#define cpu_has_udpfs()		(!cpu_is_at91sam9rl())
-
+#define cpu_has_udpfs()		(!(cpu_is_at91sam9rl() \
+				|| cpu_is_at91sam9g45()))
 
 static LIST_HEAD(clocks);
 static DEFINE_SPINLOCK(clk_lock);
@@ -133,6 +138,13 @@ static void pmc_uckr_mode(struct clk *clk, int is_on)
 {
 	unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
 
+	if (cpu_is_at91sam9g45()) {
+		if (is_on)
+			uckr |= AT91_PMC_BIASEN;
+		else
+			uckr &= ~AT91_PMC_BIASEN;
+	}
+
 	if (is_on) {
 		is_on = AT91_PMC_LOCKU;
 		at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
@@ -310,6 +322,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 	unsigned long	flags;
 	unsigned	prescale;
 	unsigned long	actual;
+	unsigned long	prev = ULONG_MAX;
 
 	if (!clk_is_programmable(clk))
 		return -EINVAL;
@@ -317,8 +330,16 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 
 	actual = clk->parent->rate_hz;
 	for (prescale = 0; prescale < 7; prescale++) {
-		if (actual && actual <= rate)
+		if (actual > rate)
+			prev = actual;
+
+		if (actual && actual <= rate) {
+			if ((prev - rate) < (rate - actual)) {
+				actual = prev;
+				prescale--;
+			}
 			break;
+		}
 		actual >>= 1;
 	}
 
@@ -373,6 +394,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 		return -EBUSY;
 	if (!clk_is_primary(parent) || !clk_is_programmable(clk))
 		return -EINVAL;
+
+	if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB)
+		return -EINVAL;
+
 	spin_lock_irqsave(&clk_lock, flags);
 
 	clk->rate_hz = parent->rate_hz;
@@ -601,7 +626,9 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
 		uhpck.pmc_mask = AT91RM9200_PMC_UHP;
 		udpck.pmc_mask = AT91RM9200_PMC_UDP;
 		at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
-	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() || cpu_is_at91sam9g20()) {
+	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
+		   cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
+		   cpu_is_at91sam9g10()) {
 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
 	} else if (cpu_is_at91cap9()) {
@@ -637,6 +664,7 @@ int __init at91_clock_init(unsigned long main_clock)
 {
 	unsigned tmp, freq, mckr;
 	int i;
+	int pll_overclock = false;
 
 	/*
 	 * When the bootloader initialized the main oscillator correctly,
@@ -654,12 +682,25 @@ int __init at91_clock_init(unsigned long main_clock)
 
 	/* report if PLLA is more than mildly overclocked */
 	plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
-	if ((!cpu_has_800M_plla() && plla.rate_hz > 209000000)
-	   || (cpu_has_800M_plla() && plla.rate_hz > 800000000))
+	if (cpu_has_300M_plla()) {
+		if (plla.rate_hz > 300000000)
+			pll_overclock = true;
+	} else if (cpu_has_800M_plla()) {
+		if (plla.rate_hz > 800000000)
+			pll_overclock = true;
+	} else {
+		if (plla.rate_hz > 209000000)
+			pll_overclock = true;
+	}
+	if (pll_overclock)
 		pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
 
+	if (cpu_is_at91sam9g45()) {
+		mckr = at91_sys_read(AT91_PMC_MCKR);
+		plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12));	/* plla divisor by 2 */
+	}
 
-	if (cpu_has_upll() && !cpu_has_pllb()) {
+	if (!cpu_has_pllb() && cpu_has_upll()) {
 		/* setup UTMI clock as the fourth primary clock
 		 * (instead of pllb) */
 		utmi_clk.type |= CLK_TYPE_PRIMARY;
@@ -701,6 +742,9 @@ int __init at91_clock_init(unsigned long main_clock)
 			freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq;	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 		if (mckr & AT91_PMC_PDIV)
 			freq /= 2;		/* processor clock division */
+	} else if (cpu_is_at91sam9g45()) {
+		mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
+			freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));	/* mdiv */
 	} else {
 		mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8));      /* mdiv */
 	}
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index b5daf7f..88e413b 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -14,6 +14,7 @@ extern void __init at91sam9260_initialize(unsigned long main_clock);
 extern void __init at91sam9261_initialize(unsigned long main_clock);
 extern void __init at91sam9263_initialize(unsigned long main_clock);
 extern void __init at91sam9rl_initialize(unsigned long main_clock);
+extern void __init at91sam9g45_initialize(unsigned long main_clock);
 extern void __init at91x40_initialize(unsigned long main_clock);
 extern void __init at91cap9_initialize(unsigned long main_clock);
 
@@ -23,6 +24,7 @@ extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
 extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
 extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
 extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
+extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
 extern void __init at91x40_init_interrupts(unsigned int priority[]);
 extern void __init at91cap9_init_interrupts(unsigned int priority[]);
 extern void __init at91_aic_init(unsigned int priority[]);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index f2236f0..ae4772e 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -44,13 +44,11 @@ static int at91_gpiolib_direction_output(struct gpio_chip *chip,
 					 unsigned offset, int val);
 static int at91_gpiolib_direction_input(struct gpio_chip *chip,
 					unsigned offset);
-static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset);
 
 #define AT91_GPIO_CHIP(name, base_gpio, nr_gpio)			\
 	{								\
 		.chip = {						\
 			.label		  = name,			\
-			.request	  = at91_gpiolib_request,	\
 			.direction_input  = at91_gpiolib_direction_input, \
 			.direction_output = at91_gpiolib_direction_output, \
 			.get		  = at91_gpiolib_get,		\
@@ -588,19 +586,6 @@ static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
 	__raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
 }
 
-static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset)
-{
-	unsigned pin = chip->base + offset;
-	void __iomem *pio = pin_to_controller(pin);
-	unsigned mask = pin_to_mask(pin);
-
-	/* Cannot request GPIOs that are in alternate function mode */
-	if (!(__raw_readl(pio + PIO_PSR) & mask))
-		return -EPERM;
-
-	return 0;
-}
-
 static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
 	int i;
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
index 3a348ca..87de8be 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9261.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -95,6 +95,9 @@
 #define AT91SAM9261_SRAM_BASE	0x00300000	/* Internal SRAM base address */
 #define AT91SAM9261_SRAM_SIZE	0x00028000	/* Internal SRAM size (160Kb) */
 
+#define AT91SAM9G10_SRAM_BASE	AT91SAM9261_SRAM_BASE	/* Internal SRAM base address */
+#define AT91SAM9G10_SRAM_SIZE	0x00004000	/* Internal SRAM size (16Kb) */
+
 #define AT91SAM9261_ROM_BASE	0x00400000	/* Internal ROM base address */
 #define AT91SAM9261_ROM_SIZE	SZ_32K		/* Internal ROM size (32Kb) */
 
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h
new file mode 100644
index 0000000..a526869
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h
@@ -0,0 +1,155 @@
+/*
+ * Chip-specific header file for the AT91SAM9G45 family
+ *
+ *  Copyright (C) 2008-2009 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91SAM9G45 preliminary datasheet.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 AT91SAM9G45_H
+#define AT91SAM9G45_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS		1	/* System Controller Interrupt */
+#define AT91SAM9G45_ID_PIOA	2	/* Parallel I/O Controller A */
+#define AT91SAM9G45_ID_PIOB	3	/* Parallel I/O Controller B */
+#define AT91SAM9G45_ID_PIOC	4	/* Parallel I/O Controller C */
+#define AT91SAM9G45_ID_PIODE	5	/* Parallel I/O Controller D and E */
+#define AT91SAM9G45_ID_TRNG	6	/* True Random Number Generator */
+#define AT91SAM9G45_ID_US0	7	/* USART 0 */
+#define AT91SAM9G45_ID_US1	8	/* USART 1 */
+#define AT91SAM9G45_ID_US2	9	/* USART 2 */
+#define AT91SAM9G45_ID_US3	10	/* USART 3 */
+#define AT91SAM9G45_ID_MCI0	11	/* High Speed Multimedia Card Interface 0 */
+#define AT91SAM9G45_ID_TWI0	12	/* Two-Wire Interface 0 */
+#define AT91SAM9G45_ID_TWI1	13	/* Two-Wire Interface 1 */
+#define AT91SAM9G45_ID_SPI0	14	/* Serial Peripheral Interface 0 */
+#define AT91SAM9G45_ID_SPI1	15	/* Serial Peripheral Interface 1 */
+#define AT91SAM9G45_ID_SSC0	16	/* Synchronous Serial Controller 0 */
+#define AT91SAM9G45_ID_SSC1	17	/* Synchronous Serial Controller 1 */
+#define AT91SAM9G45_ID_TCB	18	/* Timer Counter 0, 1, 2, 3, 4 and 5 */
+#define AT91SAM9G45_ID_PWMC	19	/* Pulse Width Modulation Controller */
+#define AT91SAM9G45_ID_TSC	20	/* Touch Screen ADC Controller */
+#define AT91SAM9G45_ID_DMA	21	/* DMA Controller */
+#define AT91SAM9G45_ID_UHPHS	22	/* USB Host High Speed */
+#define AT91SAM9G45_ID_LCDC	23	/* LCD Controller */
+#define AT91SAM9G45_ID_AC97C	24	/* AC97 Controller */
+#define AT91SAM9G45_ID_EMAC	25	/* Ethernet MAC */
+#define AT91SAM9G45_ID_ISI	26	/* Image Sensor Interface */
+#define AT91SAM9G45_ID_UDPHS	27	/* USB Device High Speed */
+#define AT91SAM9G45_ID_AESTDESSHA 28	/* AES + T-DES + SHA */
+#define AT91SAM9G45_ID_MCI1	29	/* High Speed Multimedia Card Interface 1 */
+#define AT91SAM9G45_ID_VDEC	30	/* Video Decoder */
+#define AT91SAM9G45_ID_IRQ0	31	/* Advanced Interrupt Controller */
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9G45_BASE_UDPHS		0xfff78000
+#define AT91SAM9G45_BASE_TCB0		0xfff7c000
+#define AT91SAM9G45_BASE_TC0		0xfff7c000
+#define AT91SAM9G45_BASE_TC1		0xfff7c040
+#define AT91SAM9G45_BASE_TC2		0xfff7c080
+#define AT91SAM9G45_BASE_MCI0		0xfff80000
+#define AT91SAM9G45_BASE_TWI0		0xfff84000
+#define AT91SAM9G45_BASE_TWI1		0xfff88000
+#define AT91SAM9G45_BASE_US0		0xfff8c000
+#define AT91SAM9G45_BASE_US1		0xfff90000
+#define AT91SAM9G45_BASE_US2		0xfff94000
+#define AT91SAM9G45_BASE_US3		0xfff98000
+#define AT91SAM9G45_BASE_SSC0		0xfff9c000
+#define AT91SAM9G45_BASE_SSC1		0xfffa0000
+#define AT91SAM9G45_BASE_SPI0		0xfffa4000
+#define AT91SAM9G45_BASE_SPI1		0xfffa8000
+#define AT91SAM9G45_BASE_AC97C		0xfffac000
+#define AT91SAM9G45_BASE_TSC		0xfffb0000
+#define AT91SAM9G45_BASE_ISI		0xfffb4000
+#define AT91SAM9G45_BASE_PWMC		0xfffb8000
+#define AT91SAM9G45_BASE_EMAC		0xfffbc000
+#define AT91SAM9G45_BASE_AES		0xfffc0000
+#define AT91SAM9G45_BASE_TDES		0xfffc4000
+#define AT91SAM9G45_BASE_SHA		0xfffc8000
+#define AT91SAM9G45_BASE_TRNG		0xfffcc000
+#define AT91SAM9G45_BASE_MCI1		0xfffd0000
+#define AT91SAM9G45_BASE_TCB1		0xfffd4000
+#define AT91SAM9G45_BASE_TC3		0xfffd4000
+#define AT91SAM9G45_BASE_TC4		0xfffd4040
+#define AT91SAM9G45_BASE_TC5		0xfffd4080
+#define AT91_BASE_SYS			0xffffe200
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC	(0xffffe200 - AT91_BASE_SYS)
+#define AT91_DDRSDRC1	(0xffffe400 - AT91_BASE_SYS)
+#define AT91_DDRSDRC0	(0xffffe600 - AT91_BASE_SYS)
+#define AT91_SMC	(0xffffe800 - AT91_BASE_SYS)
+#define AT91_MATRIX	(0xffffea00 - AT91_BASE_SYS)
+#define AT91_DMA	(0xffffec00 - AT91_BASE_SYS)
+#define AT91_DBGU	(0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
+#define AT91_PIOA	(0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOB	(0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOC	(0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOD	(0xfffff800 - AT91_BASE_SYS)
+#define AT91_PIOE	(0xfffffa00 - AT91_BASE_SYS)
+#define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT	(0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT	(0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
+#define AT91_GPBR	(0xfffffd60 - AT91_BASE_SYS)
+#define AT91_RTC	(0xfffffdb0 - AT91_BASE_SYS)
+
+#define AT91_USART0	AT91SAM9G45_BASE_US0
+#define AT91_USART1	AT91SAM9G45_BASE_US1
+#define AT91_USART2	AT91SAM9G45_BASE_US2
+#define AT91_USART3	AT91SAM9G45_BASE_US3
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9G45_SRAM_BASE	0x00300000	/* Internal SRAM base address */
+#define AT91SAM9G45_SRAM_SIZE	SZ_64K		/* Internal SRAM size (64Kb) */
+
+#define AT91SAM9G45_ROM_BASE	0x00400000	/* Internal ROM base address */
+#define AT91SAM9G45_ROM_SIZE	SZ_64K		/* Internal ROM size (64Kb) */
+
+#define AT91SAM9G45_LCDC_BASE	0x00500000	/* LCD Controller */
+#define AT91SAM9G45_UDPHS_FIFO	0x00600000	/* USB Device HS controller */
+#define AT91SAM9G45_OHCI_BASE	0x00700000	/* USB Host controller (OHCI) */
+#define AT91SAM9G45_EHCI_BASE	0x00800000	/* USB Host controller (EHCI) */
+#define AT91SAM9G45_VDEC_BASE	0x00900000	/* Video Decoder Controller */
+
+#define CONFIG_DRAM_BASE	AT91_CHIPSELECT_6
+
+#define CONSISTENT_DMA_SIZE	SZ_4M
+
+/*
+ * DMA peripheral identifiers
+ * for hardware handshaking interface
+ */
+#define AT_DMA_ID_MCI0		 0
+#define AT_DMA_ID_SPI0_TX	 1
+#define AT_DMA_ID_SPI0_RX	 2
+#define AT_DMA_ID_SPI1_TX	 3
+#define AT_DMA_ID_SPI1_RX	 4
+#define AT_DMA_ID_SSC0_TX	 5
+#define AT_DMA_ID_SSC0_RX	 6
+#define AT_DMA_ID_SSC1_TX	 7
+#define AT_DMA_ID_SSC1_RX	 8
+#define AT_DMA_ID_AC97_TX	 9
+#define AT_DMA_ID_AC97_RX	10
+#define AT_DMA_ID_MCI1		13
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
new file mode 100644
index 0000000..c972d60
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
@@ -0,0 +1,153 @@
+/*
+ * Matrix-centric header file for the AT91SAM9G45 family
+ *
+ *  Copyright (C) 2008-2009 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91SAM9G45 preliminary datasheet.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the 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 AT91SAM9G45_MATRIX_H
+#define AT91SAM9G45_MATRIX_H
+
+#define AT91_MATRIX_MCFG0	(AT91_MATRIX + 0x00)	/* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1	(AT91_MATRIX + 0x04)	/* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2	(AT91_MATRIX + 0x08)	/* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3	(AT91_MATRIX + 0x0C)	/* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4	(AT91_MATRIX + 0x10)	/* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5	(AT91_MATRIX + 0x14)	/* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6	(AT91_MATRIX + 0x18)	/* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7	(AT91_MATRIX + 0x1C)	/* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8	(AT91_MATRIX + 0x20)	/* Master Configuration Register 8 */
+#define AT91_MATRIX_MCFG9	(AT91_MATRIX + 0x24)	/* Master Configuration Register 9 */
+#define AT91_MATRIX_MCFG10	(AT91_MATRIX + 0x28)	/* Master Configuration Register 10 */
+#define AT91_MATRIX_MCFG11	(AT91_MATRIX + 0x2C)	/* Master Configuration Register 11 */
+#define		AT91_MATRIX_ULBT	(7 << 0)	/* Undefined Length Burst Type */
+#define			AT91_MATRIX_ULBT_INFINITE	(0 << 0)
+#define			AT91_MATRIX_ULBT_SINGLE		(1 << 0)
+#define			AT91_MATRIX_ULBT_FOUR		(2 << 0)
+#define			AT91_MATRIX_ULBT_EIGHT		(3 << 0)
+#define			AT91_MATRIX_ULBT_SIXTEEN	(4 << 0)
+#define			AT91_MATRIX_ULBT_THIRTYTWO	(5 << 0)
+#define			AT91_MATRIX_ULBT_SIXTYFOUR	(6 << 0)
+#define			AT91_MATRIX_ULBT_128		(7 << 0)
+
+#define AT91_MATRIX_SCFG0	(AT91_MATRIX + 0x40)	/* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1	(AT91_MATRIX + 0x44)	/* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2	(AT91_MATRIX + 0x48)	/* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3	(AT91_MATRIX + 0x4C)	/* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4	(AT91_MATRIX + 0x50)	/* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5	(AT91_MATRIX + 0x54)	/* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6	(AT91_MATRIX + 0x58)	/* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7	(AT91_MATRIX + 0x5C)	/* Slave Configuration Register 7 */
+#define		AT91_MATRIX_SLOT_CYCLE		(0x1ff << 0)	/* Maximum Number of Allowed Cycles for a Burst */
+#define		AT91_MATRIX_DEFMSTR_TYPE	(3    << 16)	/* Default Master Type */
+#define			AT91_MATRIX_DEFMSTR_TYPE_NONE	(0 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_LAST	(1 << 16)
+#define			AT91_MATRIX_DEFMSTR_TYPE_FIXED	(2 << 16)
+#define		AT91_MATRIX_FIXED_DEFMSTR	(0xf  << 18)	/* Fixed Index of Default Master */
+
+#define AT91_MATRIX_PRAS0	(AT91_MATRIX + 0x80)	/* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0	(AT91_MATRIX + 0x84)	/* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1	(AT91_MATRIX + 0x88)	/* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1	(AT91_MATRIX + 0x8C)	/* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2	(AT91_MATRIX + 0x90)	/* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2	(AT91_MATRIX + 0x94)	/* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3	(AT91_MATRIX + 0x98)	/* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3	(AT91_MATRIX + 0x9C)	/* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4	(AT91_MATRIX + 0xA0)	/* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4	(AT91_MATRIX + 0xA4)	/* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5	(AT91_MATRIX + 0xA8)	/* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5	(AT91_MATRIX + 0xAC)	/* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6	(AT91_MATRIX + 0xB0)	/* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6	(AT91_MATRIX + 0xB4)	/* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7	(AT91_MATRIX + 0xB8)	/* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7	(AT91_MATRIX + 0xBC)	/* Priority Register B for Slave 7 */
+#define		AT91_MATRIX_M0PR		(3 << 0)	/* Master 0 Priority */
+#define		AT91_MATRIX_M1PR		(3 << 4)	/* Master 1 Priority */
+#define		AT91_MATRIX_M2PR		(3 << 8)	/* Master 2 Priority */
+#define		AT91_MATRIX_M3PR		(3 << 12)	/* Master 3 Priority */
+#define		AT91_MATRIX_M4PR		(3 << 16)	/* Master 4 Priority */
+#define		AT91_MATRIX_M5PR		(3 << 20)	/* Master 5 Priority */
+#define		AT91_MATRIX_M6PR		(3 << 24)	/* Master 6 Priority */
+#define		AT91_MATRIX_M7PR		(3 << 28)	/* Master 7 Priority */
+#define		AT91_MATRIX_M8PR		(3 << 0)	/* Master 8 Priority (in Register B) */
+#define		AT91_MATRIX_M9PR		(3 << 4)	/* Master 9 Priority (in Register B) */
+#define		AT91_MATRIX_M10PR		(3 << 8)	/* Master 10 Priority (in Register B) */
+#define		AT91_MATRIX_M11PR		(3 << 12)	/* Master 11 Priority (in Register B) */
+
+#define AT91_MATRIX_MRCR	(AT91_MATRIX + 0x100)	/* Master Remap Control Register */
+#define		AT91_MATRIX_RCB0		(1 << 0)	/* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define		AT91_MATRIX_RCB1		(1 << 1)	/* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define		AT91_MATRIX_RCB2		(1 << 2)
+#define		AT91_MATRIX_RCB3		(1 << 3)
+#define		AT91_MATRIX_RCB4		(1 << 4)
+#define		AT91_MATRIX_RCB5		(1 << 5)
+#define		AT91_MATRIX_RCB6		(1 << 6)
+#define		AT91_MATRIX_RCB7		(1 << 7)
+#define		AT91_MATRIX_RCB8		(1 << 8)
+#define		AT91_MATRIX_RCB9		(1 << 9)
+#define		AT91_MATRIX_RCB10		(1 << 10)
+#define		AT91_MATRIX_RCB11		(1 << 11)
+
+#define AT91_MATRIX_TCMR	(AT91_MATRIX + 0x110)	/* TCM Configuration Register */
+#define		AT91_MATRIX_ITCM_SIZE		(0xf << 0)	/* Size of ITCM enabled memory block */
+#define			AT91_MATRIX_ITCM_0		(0 << 0)
+#define			AT91_MATRIX_ITCM_32		(6 << 0)
+#define		AT91_MATRIX_DTCM_SIZE		(0xf << 4)	/* Size of DTCM enabled memory block */
+#define			AT91_MATRIX_DTCM_0		(0 << 4)
+#define			AT91_MATRIX_DTCM_32		(6 << 4)
+#define			AT91_MATRIX_DTCM_64		(7 << 4)
+#define		AT91_MATRIX_TCM_NWS		(0x1 << 11)	/* Wait state TCM register */
+#define			AT91_MATRIX_TCM_NO_WS		(0x0 << 11)
+#define			AT91_MATRIX_TCM_ONE_WS		(0x1 << 11)
+
+#define AT91_MATRIX_VIDEO	(AT91_MATRIX + 0x118)	/* Video Mode Configuration Register */
+#define		AT91C_VDEC_SEL			(0x1 <<  0) /* Video Mode Selection */
+#define			AT91C_VDEC_SEL_OFF		(0 << 0)
+#define			AT91C_VDEC_SEL_ON		(1 << 0)
+
+#define AT91_MATRIX_EBICSA	(AT91_MATRIX + 0x128)	/* EBI Chip Select Assignment Register */
+#define		AT91_MATRIX_EBI_CS1A		(1 << 1)	/* Chip Select 1 Assignment */
+#define			AT91_MATRIX_EBI_CS1A_SMC		(0 << 1)
+#define			AT91_MATRIX_EBI_CS1A_SDRAMC		(1 << 1)
+#define		AT91_MATRIX_EBI_CS3A		(1 << 3)	/* Chip Select 3 Assignment */
+#define			AT91_MATRIX_EBI_CS3A_SMC		(0 << 3)
+#define			AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA	(1 << 3)
+#define		AT91_MATRIX_EBI_CS4A		(1 << 4)	/* Chip Select 4 Assignment */
+#define			AT91_MATRIX_EBI_CS4A_SMC		(0 << 4)
+#define			AT91_MATRIX_EBI_CS4A_SMC_CF0		(1 << 4)
+#define		AT91_MATRIX_EBI_CS5A		(1 << 5)	/* Chip Select 5 Assignment */
+#define			AT91_MATRIX_EBI_CS5A_SMC		(0 << 5)
+#define			AT91_MATRIX_EBI_CS5A_SMC_CF1		(1 << 5)
+#define		AT91_MATRIX_EBI_DBPUC		(1 << 8)	/* Data Bus Pull-up Configuration */
+#define			AT91_MATRIX_EBI_DBPU_ON			(0 << 8)
+#define			AT91_MATRIX_EBI_DBPU_OFF		(1 << 8)
+#define		AT91_MATRIX_EBI_VDDIOMSEL	(1 << 16)	/* Memory voltage selection */
+#define			AT91_MATRIX_EBI_VDDIOMSEL_1_8V		(0 << 16)
+#define			AT91_MATRIX_EBI_VDDIOMSEL_3_3V		(1 << 16)
+#define		AT91_MATRIX_EBI_EBI_IOSR	(1 << 17)	/* EBI I/O slew rate selection */
+#define			AT91_MATRIX_EBI_EBI_IOSR_REDUCED	(0 << 17)
+#define			AT91_MATRIX_EBI_EBI_IOSR_NORMAL		(1 << 17)
+#define		AT91_MATRIX_EBI_DDR_IOSR	(1 << 18)	/* DDR2 dedicated port I/O slew rate selection */
+#define			AT91_MATRIX_EBI_DDR_IOSR_REDUCED	(0 << 18)
+#define			AT91_MATRIX_EBI_DDR_IOSR_NORMAL		(1 << 18)
+
+#define AT91_MATRIX_WPMR	(AT91_MATRIX + 0x1E4)	/* Write Protect Mode Register */
+#define		AT91_MATRIX_WPMR_WPEN		(1 << 0)	/* Write Protect ENable */
+#define			AT91_MATRIX_WPMR_WP_WPDIS		(0 << 0)
+#define			AT91_MATRIX_WPMR_WP_WPEN		(1 << 0)
+#define		AT91_MATRIX_WPMR_WPKEY		(0xFFFFFF << 8)	/* Write Protect KEY */
+
+#define AT91_MATRIX_WPSR	(AT91_MATRIX + 0x1E8)	/* Write Protect Status Register */
+#define		AT91_MATRIX_WPSR_WPVS		(1 << 0)	/* Write Protect Violation Status */
+#define			AT91_MATRIX_WPSR_NO_WPV		(0 << 0)
+#define			AT91_MATRIX_WPSR_WPV		(1 << 0)
+#define		AT91_MATRIX_WPSR_WPVSRC		(0xFFFF << 8)	/* Write Protect Violation Source */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index e6afff8..13f27a4 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -37,6 +37,7 @@
 #include <linux/leds.h>
 #include <linux/spi/spi.h>
 #include <linux/usb/atmel_usba_udc.h>
+#include <sound/atmel-ac97c.h>
 
  /* USB Device */
 struct at91_udc_data {
@@ -80,7 +81,8 @@ struct at91_eth_data {
 };
 extern void __init at91_add_device_eth(struct at91_eth_data *data);
 
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9)
+#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
+	|| defined(CONFIG_ARCH_AT91SAM9G45)
 #define eth_platform_data	at91_eth_data
 #endif
 
@@ -90,6 +92,7 @@ struct at91_usbh_data {
 	u8		vbus_pin[2];	/* port power-control pin */
 };
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
+extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
 
  /* NAND / SmartMedia */
 struct atmel_nand_data {
@@ -105,7 +108,11 @@ struct atmel_nand_data {
 extern void __init at91_add_device_nand(struct atmel_nand_data *data);
 
  /* I2C*/
+#if defined(CONFIG_ARCH_AT91SAM9G45)
+extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices);
+#else
 extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices);
+#endif
 
  /* SPI */
 extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
@@ -168,10 +175,7 @@ struct atmel_lcdfb_info;
 extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
 
  /* AC97 */
-struct atmel_ac97_data {
-	u8		reset_pin;	/* reset */
-};
-extern void __init at91_add_device_ac97(struct atmel_ac97_data *data);
+extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
 
  /* ISI */
 extern void __init at91_add_device_isi(void);
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index c554c3e..34a9502 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -21,8 +21,10 @@
 #define ARCH_ID_AT91SAM9260	0x019803a0
 #define ARCH_ID_AT91SAM9261	0x019703a0
 #define ARCH_ID_AT91SAM9263	0x019607a0
+#define ARCH_ID_AT91SAM9G10	0x819903a0
 #define ARCH_ID_AT91SAM9G20	0x019905a0
 #define ARCH_ID_AT91SAM9RL64	0x019b03a0
+#define ARCH_ID_AT91SAM9G45	0x819b05a0
 #define ARCH_ID_AT91CAP9	0x039A03A0
 
 #define ARCH_ID_AT91SAM9XE128	0x329973a0
@@ -39,6 +41,15 @@ static inline unsigned long at91_cpu_identify(void)
 	return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
 }
 
+#define ARCH_EXID_AT91SAM9M11	0x00000001
+#define ARCH_EXID_AT91SAM9M10	0x00000002
+#define ARCH_EXID_AT91SAM9G45	0x00000004
+
+static inline unsigned long at91_exid_identify(void)
+{
+	return at91_sys_read(AT91_DBGU_EXID);
+}
+
 
 #define ARCH_FAMILY_AT91X92	0x09200000
 #define ARCH_FAMILY_AT91SAM9	0x01900000
@@ -87,6 +98,12 @@ static inline unsigned long at91cap9_rev_identify(void)
 #define cpu_is_at91sam9261()	(0)
 #endif
 
+#ifdef CONFIG_ARCH_AT91SAM9G10
+#define cpu_is_at91sam9g10()	(at91_cpu_identify() == ARCH_ID_AT91SAM9G10)
+#else
+#define cpu_is_at91sam9g10()	(0)
+#endif
+
 #ifdef CONFIG_ARCH_AT91SAM9263
 #define cpu_is_at91sam9263()	(at91_cpu_identify() == ARCH_ID_AT91SAM9263)
 #else
@@ -99,6 +116,12 @@ static inline unsigned long at91cap9_rev_identify(void)
 #define cpu_is_at91sam9rl()	(0)
 #endif
 
+#ifdef CONFIG_ARCH_AT91SAM9G45
+#define cpu_is_at91sam9g45()	(at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
+#else
+#define cpu_is_at91sam9g45()	(0)
+#endif
+
 #ifdef CONFIG_ARCH_AT91CAP9
 #define cpu_is_at91cap9()	(at91_cpu_identify() == ARCH_ID_AT91CAP9)
 #define cpu_is_at91cap9_revB()	(at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index da0b681..a0df8b0 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -20,12 +20,14 @@
 #include <mach/at91rm9200.h>
 #elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
 #include <mach/at91sam9260.h>
-#elif defined(CONFIG_ARCH_AT91SAM9261)
+#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)
 #include <mach/at91sam9261.h>
 #elif defined(CONFIG_ARCH_AT91SAM9263)
 #include <mach/at91sam9263.h>
 #elif defined(CONFIG_ARCH_AT91SAM9RL)
 #include <mach/at91sam9rl.h>
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9g45.h>
 #elif defined(CONFIG_ARCH_AT91CAP9)
 #include <mach/at91cap9.h>
 #elif defined(CONFIG_ARCH_AT91X40)
diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h
index d84c994..31ac2d9 100644
--- a/arch/arm/mach-at91/include/mach/timex.h
+++ b/arch/arm/mach-at91/include/mach/timex.h
@@ -42,6 +42,11 @@
 #define AT91SAM9_MASTER_CLOCK	99300000
 #define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
 
+#elif defined(CONFIG_ARCH_AT91SAM9G10)
+
+#define AT91SAM9_MASTER_CLOCK	133000000
+#define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
+
 #elif defined(CONFIG_ARCH_AT91SAM9263)
 
 #if defined(CONFIG_MACH_USB_A9263)
@@ -62,6 +67,11 @@
 #define AT91SAM9_MASTER_CLOCK	132096000
 #define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
 
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+
+#define AT91SAM9_MASTER_CLOCK	133333333
+#define CLOCK_TICK_RATE		(AT91SAM9_MASTER_CLOCK/16)
+
 #elif defined(CONFIG_ARCH_AT91CAP9)
 
 #define AT91CAP9_MASTER_CLOCK	100000000
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index e26c4fe..4028724 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -201,7 +201,8 @@ static int at91_pm_verify_clocks(void)
 			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()) {
+	} else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
+			|| cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
 		if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
 			pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
 			return 0;
diff --git a/arch/arm/mach-bcmring/Kconfig b/arch/arm/mach-bcmring/Kconfig
new file mode 100644
index 0000000..457b438
--- /dev/null
+++ b/arch/arm/mach-bcmring/Kconfig
@@ -0,0 +1,21 @@
+choice
+	prompt "Processor selection in BCMRING family of devices"
+	depends on ARCH_BCMRING
+	default ARCH_BCM11107
+
+config ARCH_FPGA11107
+	bool "FPGA11107"
+
+config ARCH_BCM11107
+	bool "BCM11107"
+endchoice
+
+menu "BCMRING Options"
+	depends on ARCH_BCMRING
+
+config BCM_ZRELADDR
+	hex "Compressed ZREL ADDR"
+
+endmenu
+
+# source "drivers/char/bcmring/Kconfig"
diff --git a/arch/arm/mach-bcmring/Makefile b/arch/arm/mach-bcmring/Makefile
new file mode 100644
index 0000000..f8d9fce
--- /dev/null
+++ b/arch/arm/mach-bcmring/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := arch.o mm.o irq.o clock.o core.o timer.o dma.o
+obj-y += csp/
diff --git a/arch/arm/mach-bcmring/Makefile.boot b/arch/arm/mach-bcmring/Makefile.boot
new file mode 100644
index 0000000..fb53b28
--- /dev/null
+++ b/arch/arm/mach-bcmring/Makefile.boot
@@ -0,0 +1,6 @@
+# Address where decompressor will be written and eventually executed.
+#
+# default to SDRAM
+zreladdr-y      := $(CONFIG_BCM_ZRELADDR)
+params_phys-y   := 0x00000800
+
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c
new file mode 100644
index 0000000..0da693b
--- /dev/null
+++ b/arch/arm/mach-bcmring/arch.c
@@ -0,0 +1,157 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/time.h>
+
+#include <asm/mach/arch.h>
+#include <mach/dma.h>
+#include <mach/hardware.h>
+#include <mach/csp/mm_io.h>
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include <cfg_global.h>
+
+#include "core.h"
+
+HW_DECLARE_SPINLOCK(arch)
+HW_DECLARE_SPINLOCK(gpio)
+#if defined(CONFIG_DEBUG_SPINLOCK)
+    EXPORT_SYMBOL(bcmring_gpio_reg_lock);
+#endif
+
+/* FIXME: temporary solution */
+#define BCM_SYSCTL_REBOOT_WARM               1
+#define CTL_BCM_REBOOT                 112
+
+/* sysctl */
+int bcmring_arch_warm_reboot;	/* do a warm reboot on hard reset */
+
+static struct ctl_table_header *bcmring_sysctl_header;
+
+static struct ctl_table bcmring_sysctl_warm_reboot[] = {
+	{
+	 .ctl_name = BCM_SYSCTL_REBOOT_WARM,
+	 .procname = "warm",
+	 .data = &bcmring_arch_warm_reboot,
+	 .maxlen = sizeof(int),
+	 .mode = 0644,
+	 .proc_handler = &proc_dointvec},
+	{}
+};
+
+static struct ctl_table bcmring_sysctl_reboot[] = {
+	{
+	 .ctl_name = CTL_BCM_REBOOT,
+	 .procname = "reboot",
+	 .mode = 0555,
+	 .child = bcmring_sysctl_warm_reboot},
+	{}
+};
+
+static struct platform_device nand_device = {
+	.name = "bcm-nand",
+	.id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&nand_device,
+};
+
+/****************************************************************************
+*
+*   Called from the customize_machine function in arch/arm/kernel/setup.c
+*
+*   The customize_machine function is tagged as an arch_initcall
+*   (see include/linux/init.h for the order that the various init sections
+*   are called in.
+*
+*****************************************************************************/
+static void __init bcmring_init_machine(void)
+{
+
+	bcmring_sysctl_header = register_sysctl_table(bcmring_sysctl_reboot);
+
+	/* Enable spread spectrum */
+	chipcHw_enableSpreadSpectrum();
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	bcmring_amba_init();
+
+	dma_init();
+}
+
+/****************************************************************************
+*
+*   Called from setup_arch (in arch/arm/kernel/setup.c) to fixup any tags
+*   passed in by the boot loader.
+*
+*****************************************************************************/
+
+static void __init bcmring_fixup(struct machine_desc *desc,
+     struct tag *t, char **cmdline, struct meminfo *mi) {
+#ifdef CONFIG_BLK_DEV_INITRD
+	printk(KERN_NOTICE "bcmring_fixup\n");
+	t->hdr.tag = ATAG_CORE;
+	t->hdr.size = tag_size(tag_core);
+	t->u.core.flags = 0;
+	t->u.core.pagesize = PAGE_SIZE;
+	t->u.core.rootdev = 31 << 8 | 0;
+	t = tag_next(t);
+
+	t->hdr.tag = ATAG_MEM;
+	t->hdr.size = tag_size(tag_mem32);
+	t->u.mem.start = CFG_GLOBAL_RAM_BASE;
+	t->u.mem.size = CFG_GLOBAL_RAM_SIZE;
+
+	t = tag_next(t);
+
+	t->hdr.tag = ATAG_NONE;
+	t->hdr.size = 0;
+#endif
+}
+
+/****************************************************************************
+*
+*   Machine Description
+*
+*****************************************************************************/
+
+MACHINE_START(BCMRING, "BCMRING")
+	/* Maintainer: Broadcom Corporation */
+	.phys_io = MM_IO_START,
+	.io_pg_offst = (MM_IO_BASE >> 18) & 0xfffc,
+	.fixup = bcmring_fixup,
+	.map_io = bcmring_map_io,
+	.init_irq = bcmring_init_irq,
+	.timer = &bcmring_timer,
+	.init_machine = bcmring_init_machine
+MACHINE_END
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c
new file mode 100644
index 0000000..14bafc3
--- /dev/null
+++ b/arch/arm/mach-bcmring/clock.c
@@ -0,0 +1,224 @@
+/*****************************************************************************
+* Copyright 2001 - 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <mach/csp/hw_cfg.h>
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_reg.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include <asm/clkdev.h>
+
+#include "clock.h"
+
+#define clk_is_primary(x)       ((x)->type & CLK_TYPE_PRIMARY)
+#define clk_is_pll1(x)          ((x)->type & CLK_TYPE_PLL1)
+#define clk_is_pll2(x)          ((x)->type & CLK_TYPE_PLL2)
+#define clk_is_programmable(x)  ((x)->type & CLK_TYPE_PROGRAMMABLE)
+#define clk_is_bypassable(x)    ((x)->type & CLK_TYPE_BYPASSABLE)
+
+#define clk_is_using_xtal(x)    ((x)->mode & CLK_MODE_XTAL)
+
+static DEFINE_SPINLOCK(clk_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+	if (!clk)
+		return;
+
+	/* enable parent clock first */
+	if (clk->parent)
+		__clk_enable(clk->parent);
+
+	if (clk->use_cnt++ == 0) {
+		if (clk_is_pll1(clk)) {	/* PLL1 */
+			chipcHw_pll1Enable(clk->rate_hz, 0);
+		} else if (clk_is_pll2(clk)) {	/* PLL2 */
+			chipcHw_pll2Enable(clk->rate_hz);
+		} else if (clk_is_using_xtal(clk)) {	/* source is crystal */
+			if (!clk_is_primary(clk))
+				chipcHw_bypassClockEnable(clk->csp_id);
+		} else {	/* source is PLL */
+			chipcHw_setClockEnable(clk->csp_id);
+		}
+	}
+}
+
+int clk_enable(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (!clk)
+		return -EINVAL;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	__clk_enable(clk);
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+static void __clk_disable(struct clk *clk)
+{
+	if (!clk)
+		return;
+
+	BUG_ON(clk->use_cnt == 0);
+
+	if (--clk->use_cnt == 0) {
+		if (clk_is_pll1(clk)) {	/* PLL1 */
+			chipcHw_pll1Disable();
+		} else if (clk_is_pll2(clk)) {	/* PLL2 */
+			chipcHw_pll2Disable();
+		} else if (clk_is_using_xtal(clk)) {	/* source is crystal */
+			if (!clk_is_primary(clk))
+				chipcHw_bypassClockDisable(clk->csp_id);
+		} else {	/* source is PLL */
+			chipcHw_setClockDisable(clk->csp_id);
+		}
+	}
+
+	if (clk->parent)
+		__clk_disable(clk->parent);
+}
+
+void clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+
+	if (!clk)
+		return;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	__clk_disable(clk);
+	spin_unlock_irqrestore(&clk_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (!clk)
+		return 0;
+
+	return clk->rate_hz;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long flags;
+	unsigned long actual;
+	unsigned long rate_hz;
+
+	if (!clk)
+		return -EINVAL;
+
+	if (!clk_is_programmable(clk))
+		return -EINVAL;
+
+	if (clk->use_cnt)
+		return -EBUSY;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	actual = clk->parent->rate_hz;
+	rate_hz = min(actual, rate);
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return rate_hz;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long flags;
+	unsigned long actual;
+	unsigned long rate_hz;
+
+	if (!clk)
+		return -EINVAL;
+
+	if (!clk_is_programmable(clk))
+		return -EINVAL;
+
+	if (clk->use_cnt)
+		return -EBUSY;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	actual = clk->parent->rate_hz;
+	rate_hz = min(actual, rate);
+	rate_hz = chipcHw_setClockFrequency(clk->csp_id, rate_hz);
+	clk->rate_hz = rate_hz;
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+	if (!clk)
+		return NULL;
+
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned long flags;
+	struct clk *old_parent;
+
+	if (!clk || !parent)
+		return -EINVAL;
+
+	if (!clk_is_primary(parent) || !clk_is_bypassable(clk))
+		return -EINVAL;
+
+	/* if more than one user, parent is not allowed */
+	if (clk->use_cnt > 1)
+		return -EBUSY;
+
+	if (clk->parent == parent)
+		return 0;
+
+	spin_lock_irqsave(&clk_lock, flags);
+	old_parent = clk->parent;
+	clk->parent = parent;
+	if (clk_is_using_xtal(parent))
+		clk->mode |= CLK_MODE_XTAL;
+	else
+		clk->mode &= (~CLK_MODE_XTAL);
+
+	/* if clock is active */
+	if (clk->use_cnt != 0) {
+		clk->use_cnt--;
+		/* enable clock with the new parent */
+		__clk_enable(clk);
+		/* disable the old parent */
+		__clk_disable(old_parent);
+	}
+	spin_unlock_irqrestore(&clk_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
diff --git a/arch/arm/mach-bcmring/clock.h b/arch/arm/mach-bcmring/clock.h
new file mode 100644
index 0000000..5e0b981
--- /dev/null
+++ b/arch/arm/mach-bcmring/clock.h
@@ -0,0 +1,33 @@
+/*****************************************************************************
+* Copyright 2001 - 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+#include <mach/csp/chipcHw_def.h>
+
+#define CLK_TYPE_PRIMARY         1	/* primary clock must NOT have a parent */
+#define CLK_TYPE_PLL1            2	/* PPL1 */
+#define CLK_TYPE_PLL2            4	/* PPL2 */
+#define CLK_TYPE_PROGRAMMABLE    8	/* programmable clock rate */
+#define CLK_TYPE_BYPASSABLE      16	/* parent can be changed */
+
+#define CLK_MODE_XTAL            1	/* clock source is from crystal */
+
+struct clk {
+	const char *name;	/* clock name */
+	unsigned int type;	/* clock type */
+	unsigned int mode;	/* current mode */
+	volatile int use_bypass;	/* indicate if it's in bypass mode */
+	chipcHw_CLOCK_e csp_id;	/* clock ID for CSP CHIPC */
+	unsigned long rate_hz;	/* clock rate in Hz */
+	unsigned int use_cnt;	/* usage count */
+	struct clk *parent;	/* parent clock */
+};
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
new file mode 100644
index 0000000..492c649
--- /dev/null
+++ b/arch/arm/mach-bcmring/core.c
@@ -0,0 +1,367 @@
+/*
+ *  derived from linux/arch/arm/mach-versatile/core.c
+ *  linux/arch/arm/mach-bcmring/core.c
+ *
+ *  Copyright (C) 1999 - 2003 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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
+ */
+/* Portions copyright Broadcom 2008 */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+
+#include <linux/amba/bus.h>
+#include <mach/csp/mm_addr.h>
+#include <mach/hardware.h>
+#include <asm/clkdev.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/mach/mmc.h>
+
+#include <cfg_global.h>
+
+#include "clock.h"
+
+#include <csp/secHw.h>
+#include <mach/csp/secHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+#include <mach/csp/tmrHw_reg.h>
+
+#define AMBA_DEVICE(name, initname, base, plat, size)       \
+static struct amba_device name##_device = {     \
+   .dev = {                                     \
+      .coherent_dma_mask = ~0,                  \
+      .init_name = initname,                    \
+      .platform_data = plat                     \
+   },                                           \
+   .res = {                                     \
+      .start = MM_ADDR_IO_##base,               \
+		.end = MM_ADDR_IO_##base + (size) - 1,    \
+      .flags = IORESOURCE_MEM                   \
+   },                                           \
+   .dma_mask = ~0,                              \
+   .irq = {                                     \
+      IRQ_##base                                \
+   }                                            \
+}
+
+
+AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K);
+AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K);
+
+static struct clk pll1_clk = {
+	.name = "PLL1",
+	.type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL1,
+	.rate_hz = 2000000000,
+	.use_cnt = 7,
+};
+
+static struct clk uart_clk = {
+	.name = "UART",
+	.type = CLK_TYPE_PROGRAMMABLE,
+	.csp_id = chipcHw_CLOCK_UART,
+	.rate_hz = HW_CFG_UART_CLK_HZ,
+	.parent = &pll1_clk,
+};
+
+static struct clk_lookup lookups[] = {
+	{			/* UART0 */
+	 .dev_id = "uarta",
+	 .clk = &uart_clk,
+	 }, {			/* UART1 */
+	     .dev_id = "uartb",
+	     .clk = &uart_clk,
+	     }
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	&uartA_device,
+	&uartB_device,
+};
+
+void __init bcmring_amba_init(void)
+{
+	int i;
+	u32 bus_clock;
+
+/* Linux is run initially in non-secure mode. Secure peripherals */
+/* generate FIQ, and must be handled in secure mode. Until we have */
+/* a linux security monitor implementation, keep everything in */
+/* non-secure mode. */
+	chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_SPU);
+	secHw_setUnsecure(secHw_BLK_MASK_CHIP_CONTROL |
+			  secHw_BLK_MASK_KEY_SCAN |
+			  secHw_BLK_MASK_TOUCH_SCREEN |
+			  secHw_BLK_MASK_UART0 |
+			  secHw_BLK_MASK_UART1 |
+			  secHw_BLK_MASK_WATCHDOG |
+			  secHw_BLK_MASK_SPUM |
+			  secHw_BLK_MASK_DDR2 |
+			  secHw_BLK_MASK_SPU |
+			  secHw_BLK_MASK_PKA |
+			  secHw_BLK_MASK_RNG |
+			  secHw_BLK_MASK_RTC |
+			  secHw_BLK_MASK_OTP |
+			  secHw_BLK_MASK_BOOT |
+			  secHw_BLK_MASK_MPU |
+			  secHw_BLK_MASK_TZCTRL | secHw_BLK_MASK_INTR);
+
+	/* Only the devices attached to the AMBA bus are enabled just before the bus is */
+	/* scanned and the drivers are loaded. The clocks need to be on for the AMBA bus */
+	/* driver to access these blocks. The bus is probed, and the drivers are loaded. */
+	/* FIXME Need to remove enable of PIF once CLCD clock enable used properly in FPGA. */
+	bus_clock = chipcHw_REG_BUS_CLOCK_GE
+	    | chipcHw_REG_BUS_CLOCK_SDIO0 | chipcHw_REG_BUS_CLOCK_SDIO1;
+
+	chipcHw_busInterfaceClockEnable(bus_clock);
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+		struct amba_device *d = amba_devs[i];
+		amba_device_register(d, &iomem_resource);
+	}
+}
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE		 MM_IO_BASE_TMR
+#define TIMER1_VA_BASE		(MM_IO_BASE_TMR + 0x20)
+#define TIMER2_VA_BASE		(MM_IO_BASE_TMR + 0x40)
+#define TIMER3_VA_BASE          (MM_IO_BASE_TMR + 0x60)
+
+/* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically  150-166 MHz */
+#if defined(CONFIG_ARCH_FPGA11107)
+/* fpga cpu/bus are currently 30 times slower so scale frequency as well to */
+/* slow down Linux's sense of time */
+#define TIMER0_FREQUENCY_MHZ  (tmrHw_LOW_FREQUENCY_MHZ * 30)
+#define TIMER1_FREQUENCY_MHZ  (tmrHw_LOW_FREQUENCY_MHZ * 30)
+#define TIMER3_FREQUENCY_MHZ  (tmrHw_HIGH_FREQUENCY_MHZ * 30)
+#define TIMER3_FREQUENCY_KHZ   (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
+#else
+#define TIMER0_FREQUENCY_MHZ  tmrHw_LOW_FREQUENCY_MHZ
+#define TIMER1_FREQUENCY_MHZ  tmrHw_LOW_FREQUENCY_MHZ
+#define TIMER3_FREQUENCY_MHZ  tmrHw_HIGH_FREQUENCY_MHZ
+#define TIMER3_FREQUENCY_KHZ  (tmrHw_HIGH_FREQUENCY_HZ / 1000)
+#endif
+
+#define TICKS_PER_uSEC     TIMER0_FREQUENCY_MHZ
+
+/*
+ *  These are useconds NOT ticks.
+ *
+ */
+#define mSEC_1                          1000
+#define mSEC_5                          (mSEC_1 * 5)
+#define mSEC_10                         (mSEC_1 * 10)
+#define mSEC_25                         (mSEC_1 * 25)
+#define SEC_1                           (mSEC_1 * 1000)
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
+#if TIMER_INTERVAL >= 0x100000
+#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV256)
+#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
+#elif TIMER_INTERVAL >= 0x10000
+#define TIMER_RELOAD	(TIMER_INTERVAL >> 4)	/* Divide by 16 */
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV16)
+#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
+#else
+#define TIMER_RELOAD	(TIMER_INTERVAL)
+#define TIMER_DIVISOR	(TIMER_CTRL_DIV1)
+#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
+#endif
+
+static void timer_set_mode(enum clock_event_mode mode,
+			   struct clock_event_device *clk)
+{
+	unsigned long ctrl;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
+
+		ctrl = TIMER_CTRL_PERIODIC;
+		ctrl |=
+		    TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE |
+		    TIMER_CTRL_ENABLE;
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* period set, and timer enabled in 'next_event' hook */
+		ctrl = TIMER_CTRL_ONESHOT;
+		ctrl |= TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE;
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	default:
+		ctrl = 0;
+	}
+
+	writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
+}
+
+static int timer_set_next_event(unsigned long evt,
+				struct clock_event_device *unused)
+{
+	unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
+
+	writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
+	writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
+
+	return 0;
+}
+
+static struct clock_event_device timer0_clockevent = {
+	.name = "timer0",
+	.shift = 32,
+	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode = timer_set_mode,
+	.set_next_event = timer_set_next_event,
+};
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t bcmring_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &timer0_clockevent;
+
+	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction bcmring_timer_irq = {
+	.name = "bcmring Timer Tick",
+	.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler = bcmring_timer_interrupt,
+};
+
+static cycle_t bcmring_get_cycles_timer1(void)
+{
+	return ~readl(TIMER1_VA_BASE + TIMER_VALUE);
+}
+
+static cycle_t bcmring_get_cycles_timer3(void)
+{
+	return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
+}
+
+static struct clocksource clocksource_bcmring_timer1 = {
+	.name = "timer1",
+	.rating = 200,
+	.read = bcmring_get_cycles_timer1,
+	.mask = CLOCKSOURCE_MASK(32),
+	.shift = 20,
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static struct clocksource clocksource_bcmring_timer3 = {
+	.name = "timer3",
+	.rating = 100,
+	.read = bcmring_get_cycles_timer3,
+	.mask = CLOCKSOURCE_MASK(32),
+	.shift = 20,
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init bcmring_clocksource_init(void)
+{
+	/* setup timer1 as free-running clocksource */
+	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+	writel(0xffffffff, TIMER1_VA_BASE + TIMER_LOAD);
+	writel(0xffffffff, TIMER1_VA_BASE + TIMER_VALUE);
+	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
+	       TIMER1_VA_BASE + TIMER_CTRL);
+
+	clocksource_bcmring_timer1.mult =
+	    clocksource_khz2mult(TIMER1_FREQUENCY_MHZ * 1000,
+				 clocksource_bcmring_timer1.shift);
+	clocksource_register(&clocksource_bcmring_timer1);
+
+	/* setup timer3 as free-running clocksource */
+	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+	writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
+	writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
+	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
+	       TIMER3_VA_BASE + TIMER_CTRL);
+
+	clocksource_bcmring_timer3.mult =
+	    clocksource_khz2mult(TIMER3_FREQUENCY_KHZ,
+				 clocksource_bcmring_timer3.shift);
+	clocksource_register(&clocksource_bcmring_timer3);
+
+	return 0;
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init bcmring_init_timer(void)
+{
+	printk(KERN_INFO "bcmring_init_timer\n");
+	/*
+	 * Initialise to a known state (all timers off)
+	 */
+	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+
+	/*
+	 * Make irqs happen for the system timer
+	 */
+	setup_irq(IRQ_TIMER0, &bcmring_timer_irq);
+
+	bcmring_clocksource_init();
+
+	timer0_clockevent.mult =
+	    div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
+	timer0_clockevent.max_delta_ns =
+	    clockevent_delta2ns(0xffffffff, &timer0_clockevent);
+	timer0_clockevent.min_delta_ns =
+	    clockevent_delta2ns(0xf, &timer0_clockevent);
+
+	timer0_clockevent.cpumask = cpumask_of(0);
+	clockevents_register_device(&timer0_clockevent);
+}
+
+struct sys_timer bcmring_timer = {
+	.init = bcmring_init_timer,
+};
diff --git a/arch/arm/mach-bcmring/core.h b/arch/arm/mach-bcmring/core.h
new file mode 100644
index 0000000..b197ba4
--- /dev/null
+++ b/arch/arm/mach-bcmring/core.h
@@ -0,0 +1,30 @@
+/*
+ *  linux/arch/arm/mach-versatile/core.h
+ *
+ *  Copyright (C) 2004 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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
+ */
+/* Portions copyright Broadcom 2008 */
+#ifndef __ASM_ARCH_BCMRING_H
+#define __ASM_ARCH_BCMRING_H
+
+void __init bcmring_amba_init(void);
+void __init bcmring_map_io(void);
+void __init bcmring_init_irq(void);
+
+extern struct sys_timer bcmring_timer;
+#endif
diff --git a/arch/arm/mach-bcmring/csp/Makefile b/arch/arm/mach-bcmring/csp/Makefile
new file mode 100644
index 0000000..648c037
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/Makefile
@@ -0,0 +1,3 @@
+obj-y += dmac/
+obj-y += tmr/
+obj-y += chipc/
diff --git a/arch/arm/mach-bcmring/csp/chipc/Makefile b/arch/arm/mach-bcmring/csp/chipc/Makefile
new file mode 100644
index 0000000..6739527
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/Makefile
@@ -0,0 +1 @@
+obj-y += chipcHw.o chipcHw_str.o chipcHw_reset.o chipcHw_init.o
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c
new file mode 100644
index 0000000..b3a61d8
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c
@@ -0,0 +1,776 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    chipcHw.c
+*
+*  @brief   Low level Various CHIP clock controlling routines
+*
+*  @note
+*
+*   These routines provide basic clock controlling functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/stdint.h>
+#include <csp/module.h>
+
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include <csp/reg.h>
+#include <csp/delay.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+
+/* VPM alignment algorithm uses this */
+#define MAX_PHASE_ADJUST_COUNT         0xFFFF	/* Max number of times allowed to adjust the phase */
+#define MAX_PHASE_ALIGN_ATTEMPTS       10	/* Max number of attempt to align the phase */
+
+/* Local definition of clock type */
+#define PLL_CLOCK                      1	/* PLL Clock */
+#define NON_PLL_CLOCK                  2	/* Divider clock */
+
+static int chipcHw_divide(int num, int denom)
+    __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Set clock fequency for miscellaneous configurable clocks
+*
+*  This function sets clock frequency
+*
+*  @return  Configured clock frequency in hertz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock	/*  [ IN ] Configurable clock */
+    ) {
+	volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
+	volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
+	volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
+	uint32_t vcoFreqPll1Hz = 0;	/* Effective VCO frequency for PLL1 in Hz */
+	uint32_t vcoFreqPll2Hz = 0;	/* Effective VCO frequency for PLL2 in Hz */
+	uint32_t dependentClockType = 0;
+	uint32_t vcoHz = 0;
+
+	/* Get VCO frequencies */
+	if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
+		uint64_t adjustFreq = 0;
+
+		vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+		    chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+		    ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+		     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+		/* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
+		adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
+			(uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
+			chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
+		vcoFreqPll1Hz += (uint32_t) adjustFreq;
+	} else {
+		vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+		    chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+		    ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+		     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+	}
+	vcoFreqPll2Hz =
+	    chipcHw_XTAL_FREQ_Hz *
+		 chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+	    ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+	     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+	switch (clock) {
+	case chipcHw_CLOCK_DDR:
+		pPLLReg = &pChipcHw->DDRClock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ARM:
+		pPLLReg = &pChipcHw->ARMClock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ESW:
+		pPLLReg = &pChipcHw->ESWClock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_VPM:
+		pPLLReg = &pChipcHw->VPMClock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ESW125:
+		pPLLReg = &pChipcHw->ESW125Clock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_UART:
+		pPLLReg = &pChipcHw->UARTClock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_SDIO0:
+		pPLLReg = &pChipcHw->SDIO0Clock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_SDIO1:
+		pPLLReg = &pChipcHw->SDIO1Clock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_SPI:
+		pPLLReg = &pChipcHw->SPIClock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ETM:
+		pPLLReg = &pChipcHw->ETMClock;
+		vcoHz = vcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_USB:
+		pPLLReg = &pChipcHw->USBClock;
+		vcoHz = vcoFreqPll2Hz;
+		break;
+	case chipcHw_CLOCK_LCD:
+		pPLLReg = &pChipcHw->LCDClock;
+		vcoHz = vcoFreqPll2Hz;
+		break;
+	case chipcHw_CLOCK_APM:
+		pPLLReg = &pChipcHw->APMClock;
+		vcoHz = vcoFreqPll2Hz;
+		break;
+	case chipcHw_CLOCK_BUS:
+		pClockCtrl = &pChipcHw->ACLKClock;
+		pDependentClock = &pChipcHw->ARMClock;
+		vcoHz = vcoFreqPll1Hz;
+		dependentClockType = PLL_CLOCK;
+		break;
+	case chipcHw_CLOCK_OTP:
+		pClockCtrl = &pChipcHw->OTPClock;
+		break;
+	case chipcHw_CLOCK_I2C:
+		pClockCtrl = &pChipcHw->I2CClock;
+		break;
+	case chipcHw_CLOCK_I2S0:
+		pClockCtrl = &pChipcHw->I2S0Clock;
+		break;
+	case chipcHw_CLOCK_RTBUS:
+		pClockCtrl = &pChipcHw->RTBUSClock;
+		pDependentClock = &pChipcHw->ACLKClock;
+		dependentClockType = NON_PLL_CLOCK;
+		break;
+	case chipcHw_CLOCK_APM100:
+		pClockCtrl = &pChipcHw->APM100Clock;
+		pDependentClock = &pChipcHw->APMClock;
+		vcoHz = vcoFreqPll2Hz;
+		dependentClockType = PLL_CLOCK;
+		break;
+	case chipcHw_CLOCK_TSC:
+		pClockCtrl = &pChipcHw->TSCClock;
+		break;
+	case chipcHw_CLOCK_LED:
+		pClockCtrl = &pChipcHw->LEDClock;
+		break;
+	case chipcHw_CLOCK_I2S1:
+		pClockCtrl = &pChipcHw->I2S1Clock;
+		break;
+	}
+
+	if (pPLLReg) {
+		/* Obtain PLL clock frequency */
+		if (*pPLLReg & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
+			/* Return crystal clock frequency when bypassed */
+			return chipcHw_XTAL_FREQ_Hz;
+		} else if (clock == chipcHw_CLOCK_DDR) {
+			/* DDR frequency is configured in PLLDivider register */
+			return chipcHw_divide (vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
+		} else {
+			/* From chip revision number B0, LCD clock is internally divided by 2 */
+			if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
+				vcoHz >>= 1;
+			}
+			/* Obtain PLL clock frequency using VCO dividers */
+			return chipcHw_divide(vcoHz, ((*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
+		}
+	} else if (pClockCtrl) {
+		/* Obtain divider clock frequency */
+		uint32_t div;
+		uint32_t freq = 0;
+
+		if (*pClockCtrl & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
+			/* Return crystal clock frequency when bypassed */
+			return chipcHw_XTAL_FREQ_Hz;
+		} else if (pDependentClock) {
+			/* Identify the dependent clock frequency */
+			switch (dependentClockType) {
+			case PLL_CLOCK:
+				if (*pDependentClock & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
+					/* Use crystal clock frequency when dependent PLL clock is bypassed */
+					freq = chipcHw_XTAL_FREQ_Hz;
+				} else {
+					/* Obtain PLL clock frequency using VCO dividers */
+					div = *pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK;
+					freq = div ? chipcHw_divide(vcoHz, div) : 0;
+				}
+				break;
+			case NON_PLL_CLOCK:
+				if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
+					freq = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
+				} else {
+					if (*pDependentClock & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
+						/* Use crystal clock frequency when dependent divider clock is bypassed */
+						freq = chipcHw_XTAL_FREQ_Hz;
+					} else {
+						/* Obtain divider clock frequency using XTAL dividers */
+						div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
+						freq = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, (div ? div : 256));
+					}
+				}
+				break;
+			}
+		} else {
+			/* Dependent on crystal clock */
+			freq = chipcHw_XTAL_FREQ_Hz;
+		}
+
+		div = *pClockCtrl & chipcHw_REG_DIV_CLOCK_DIV_MASK;
+		return chipcHw_divide(freq, (div ? div : 256));
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set clock fequency for miscellaneous configurable clocks
+*
+*  This function sets clock frequency
+*
+*  @return  Configured clock frequency in Hz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock,	/*  [ IN ] Configurable clock */
+				       uint32_t freq	/*  [ IN ] Clock frequency in Hz */
+    ) {
+	volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
+	volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
+	volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
+	uint32_t vcoFreqPll1Hz = 0;	/* Effective VCO frequency for PLL1 in Hz */
+	uint32_t desVcoFreqPll1Hz = 0;	/* Desired VCO frequency for PLL1 in Hz */
+	uint32_t vcoFreqPll2Hz = 0;	/* Effective VCO frequency for PLL2 in Hz */
+	uint32_t dependentClockType = 0;
+	uint32_t vcoHz = 0;
+	uint32_t desVcoHz = 0;
+
+	/* Get VCO frequencies */
+	if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
+		uint64_t adjustFreq = 0;
+
+		vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+		    chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+		    ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+		     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+		/* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
+		adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
+			(uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
+			chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
+		vcoFreqPll1Hz += (uint32_t) adjustFreq;
+
+		/* Desired VCO frequency */
+		desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+		    chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+		    (((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+		      chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) + 1);
+	} else {
+		vcoFreqPll1Hz = desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+		    chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+		    ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+		     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+	}
+	vcoFreqPll2Hz = chipcHw_XTAL_FREQ_Hz * chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+	    ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+	     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+	switch (clock) {
+	case chipcHw_CLOCK_DDR:
+		/* Configure the DDR_ctrl:BUS ratio settings */
+		{
+			REG_LOCAL_IRQ_SAVE;
+			/* Dvide DDR_phy by two to obtain DDR_ctrl clock */
+			pChipcHw->DDRClock = (pChipcHw->DDRClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((((freq / 2) / chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
+				<< chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
+			REG_LOCAL_IRQ_RESTORE;
+		}
+		pPLLReg = &pChipcHw->DDRClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ARM:
+		pPLLReg = &pChipcHw->ARMClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ESW:
+		pPLLReg = &pChipcHw->ESWClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_VPM:
+		/* Configure the VPM:BUS ratio settings */
+		{
+			REG_LOCAL_IRQ_SAVE;
+			pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((chipcHw_divide (freq, chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
+				<< chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
+			REG_LOCAL_IRQ_RESTORE;
+		}
+		pPLLReg = &pChipcHw->VPMClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ESW125:
+		pPLLReg = &pChipcHw->ESW125Clock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_UART:
+		pPLLReg = &pChipcHw->UARTClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_SDIO0:
+		pPLLReg = &pChipcHw->SDIO0Clock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_SDIO1:
+		pPLLReg = &pChipcHw->SDIO1Clock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_SPI:
+		pPLLReg = &pChipcHw->SPIClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_ETM:
+		pPLLReg = &pChipcHw->ETMClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		break;
+	case chipcHw_CLOCK_USB:
+		pPLLReg = &pChipcHw->USBClock;
+		vcoHz = vcoFreqPll2Hz;
+		desVcoHz = vcoFreqPll2Hz;
+		break;
+	case chipcHw_CLOCK_LCD:
+		pPLLReg = &pChipcHw->LCDClock;
+		vcoHz = vcoFreqPll2Hz;
+		desVcoHz = vcoFreqPll2Hz;
+		break;
+	case chipcHw_CLOCK_APM:
+		pPLLReg = &pChipcHw->APMClock;
+		vcoHz = vcoFreqPll2Hz;
+		desVcoHz = vcoFreqPll2Hz;
+		break;
+	case chipcHw_CLOCK_BUS:
+		pClockCtrl = &pChipcHw->ACLKClock;
+		pDependentClock = &pChipcHw->ARMClock;
+		vcoHz = vcoFreqPll1Hz;
+		desVcoHz = desVcoFreqPll1Hz;
+		dependentClockType = PLL_CLOCK;
+		break;
+	case chipcHw_CLOCK_OTP:
+		pClockCtrl = &pChipcHw->OTPClock;
+		break;
+	case chipcHw_CLOCK_I2C:
+		pClockCtrl = &pChipcHw->I2CClock;
+		break;
+	case chipcHw_CLOCK_I2S0:
+		pClockCtrl = &pChipcHw->I2S0Clock;
+		break;
+	case chipcHw_CLOCK_RTBUS:
+		pClockCtrl = &pChipcHw->RTBUSClock;
+		pDependentClock = &pChipcHw->ACLKClock;
+		dependentClockType = NON_PLL_CLOCK;
+		break;
+	case chipcHw_CLOCK_APM100:
+		pClockCtrl = &pChipcHw->APM100Clock;
+		pDependentClock = &pChipcHw->APMClock;
+		vcoHz = vcoFreqPll2Hz;
+		desVcoHz = vcoFreqPll2Hz;
+		dependentClockType = PLL_CLOCK;
+		break;
+	case chipcHw_CLOCK_TSC:
+		pClockCtrl = &pChipcHw->TSCClock;
+		break;
+	case chipcHw_CLOCK_LED:
+		pClockCtrl = &pChipcHw->LEDClock;
+		break;
+	case chipcHw_CLOCK_I2S1:
+		pClockCtrl = &pChipcHw->I2S1Clock;
+		break;
+	}
+
+	if (pPLLReg) {
+		/* Select XTAL as bypass source */
+		reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_SOURCE_GPIO);
+		reg32_modify_or(pPLLReg, chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+		/* For DDR settings use only the PLL divider clock */
+		if (pPLLReg == &pChipcHw->DDRClock) {
+			/* Set M1DIV for PLL1, which controls the DDR clock */
+			reg32_write(&pChipcHw->PLLDivider, (pChipcHw->PLLDivider & 0x00FFFFFF) | ((chipcHw_REG_PLL_DIVIDER_MDIV (desVcoHz, freq)) << 24));
+			/* Calculate expected frequency */
+			freq = chipcHw_divide(vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
+		} else {
+			/* From chip revision number B0, LCD clock is internally divided by 2 */
+			if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
+				desVcoHz >>= 1;
+				vcoHz >>= 1;
+			}
+			/* Set MDIV to change the frequency */
+			reg32_modify_and(pPLLReg, ~(chipcHw_REG_PLL_CLOCK_MDIV_MASK));
+			reg32_modify_or(pPLLReg, chipcHw_REG_PLL_DIVIDER_MDIV(desVcoHz, freq));
+			/* Calculate expected frequency */
+			freq = chipcHw_divide(vcoHz, ((*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
+		}
+		/* Wait for for atleast 200ns as per the protocol to change frequency */
+		udelay(1);
+		/* Do not bypass */
+		reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+		/* Return the configured frequency */
+		return freq;
+	} else if (pClockCtrl) {
+		uint32_t divider = 0;
+
+		/* Divider clock should not be bypassed  */
+		reg32_modify_and(pClockCtrl,
+				 ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
+
+		/* Identify the clock source */
+		if (pDependentClock) {
+			switch (dependentClockType) {
+			case PLL_CLOCK:
+				divider = chipcHw_divide(chipcHw_divide (desVcoHz, (*pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK)), freq);
+				break;
+			case NON_PLL_CLOCK:
+				{
+					uint32_t sourceClock = 0;
+
+					if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
+						sourceClock = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
+					} else {
+						uint32_t div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
+						sourceClock = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, ((div) ? div : 256));
+					}
+					divider = chipcHw_divide(sourceClock, freq);
+				}
+				break;
+			}
+		} else {
+			divider = chipcHw_divide(chipcHw_XTAL_FREQ_Hz, freq);
+		}
+
+		if (divider) {
+			REG_LOCAL_IRQ_SAVE;
+			/* Set the divider to obtain the required frequency */
+			*pClockCtrl = (*pClockCtrl & (~chipcHw_REG_DIV_CLOCK_DIV_MASK)) | (((divider > 256) ? chipcHw_REG_DIV_CLOCK_DIV_256 : divider) & chipcHw_REG_DIV_CLOCK_DIV_MASK);
+			REG_LOCAL_IRQ_RESTORE;
+			return freq;
+		}
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(chipcHw_setClockFrequency);
+
+/****************************************************************************/
+/**
+*  @brief   Set VPM clock in sync with BUS clock for Chip Rev #A0
+*
+*  This function does the phase adjustment between VPM and BUS clock
+*
+*  @return >= 0 : On success (# of adjustment required)
+*            -1 : On failure
+*
+*/
+/****************************************************************************/
+static int vpmPhaseAlignA0(void)
+{
+	uint32_t phaseControl;
+	uint32_t phaseValue;
+	uint32_t prevPhaseComp;
+	int iter = 0;
+	int adjustCount = 0;
+	int count = 0;
+
+	for (iter = 0; (iter < MAX_PHASE_ALIGN_ATTEMPTS) && (adjustCount < MAX_PHASE_ADJUST_COUNT); iter++) {
+		phaseControl = (pChipcHw->VPMClock & chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT;
+		phaseValue = 0;
+		prevPhaseComp = 0;
+
+		/* Step 1: Look for falling PH_COMP transition */
+
+		/* Read the contents of VPM Clock resgister */
+		phaseValue = pChipcHw->VPMClock;
+		do {
+			/* Store previous value of phase comparator */
+			prevPhaseComp = phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP;
+			/* Change the value of PH_CTRL. */
+			reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+			/* Wait atleast 20 ns */
+			udelay(1);
+			/* Toggle the LOAD_CH after phase control is written. */
+			pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+			/* Read the contents of  VPM Clock resgister. */
+			phaseValue = pChipcHw->VPMClock;
+
+			if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
+				phaseControl = (0x3F & (phaseControl - 1));
+			} else {
+				/* Increment to the Phase count value for next write, if Phase is not stable. */
+				phaseControl = (0x3F & (phaseControl + 1));
+			}
+			/* Count number of adjustment made */
+			adjustCount++;
+		} while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) ||	/* Look for a transition */
+			  ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) &&	/* Look for a falling edge */
+			 (adjustCount < MAX_PHASE_ADJUST_COUNT)	/* Do not exceed the limit while trying */
+		    );
+
+		if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+			/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+			return -1;
+		}
+
+		/* Step 2: Keep moving forward to make sure falling PH_COMP transition was valid */
+
+		for (count = 0; (count < 5) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
+			phaseControl = (0x3F & (phaseControl + 1));
+			reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+			/* Wait atleast 20 ns */
+			udelay(1);
+			/* Toggle the LOAD_CH after phase control is written. */
+			pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+			phaseValue = pChipcHw->VPMClock;
+			/* Count number of adjustment made */
+			adjustCount++;
+		}
+
+		if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+			/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+			return -1;
+		}
+
+		if (count != 5) {
+			/* Detected false transition */
+			continue;
+		}
+
+		/* Step 3: Keep moving backward to make sure falling PH_COMP transition was stable */
+
+		for (count = 0; (count < 3) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
+			phaseControl = (0x3F & (phaseControl - 1));
+			reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+			/* Wait atleast 20 ns */
+			udelay(1);
+			/* Toggle the LOAD_CH after phase control is written. */
+			pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+			phaseValue = pChipcHw->VPMClock;
+			/* Count number of adjustment made */
+			adjustCount++;
+		}
+
+		if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+			/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+			return -1;
+		}
+
+		if (count != 3) {
+			/* Detected noisy transition */
+			continue;
+		}
+
+		/* Step 4: Keep moving backward before the original transition took place. */
+
+		for (count = 0; (count < 5); count++) {
+			phaseControl = (0x3F & (phaseControl - 1));
+			reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+			/* Wait atleast 20 ns */
+			udelay(1);
+			/* Toggle the LOAD_CH after phase control is written. */
+			pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+			phaseValue = pChipcHw->VPMClock;
+			/* Count number of adjustment made */
+			adjustCount++;
+		}
+
+		if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+			/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+			return -1;
+		}
+
+		if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0) {
+			/* Detected false transition */
+			continue;
+		}
+
+		/* Step 5: Re discover the valid transition */
+
+		do {
+			/* Store previous value of phase comparator */
+			prevPhaseComp = phaseValue;
+			/* Change the value of PH_CTRL. */
+			reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+			/* Wait atleast 20 ns */
+			udelay(1);
+			/* Toggle the LOAD_CH after phase control is written. */
+			pChipcHw->VPMClock ^=
+			    chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+			/* Read the contents of  VPM Clock resgister. */
+			phaseValue = pChipcHw->VPMClock;
+
+			if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
+				phaseControl = (0x3F & (phaseControl - 1));
+			} else {
+				/* Increment to the Phase count value for next write, if Phase is not stable. */
+				phaseControl = (0x3F & (phaseControl + 1));
+			}
+
+			/* Count number of adjustment made */
+			adjustCount++;
+		} while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && (adjustCount < MAX_PHASE_ADJUST_COUNT));
+
+		if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+			/* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries  */
+			return -1;
+		} else {
+			/* Valid phase must have detected */
+			break;
+		}
+	}
+
+	/* For VPM Phase should be perfectly aligned. */
+	phaseControl = (((pChipcHw->VPMClock >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT) - 1) & 0x3F);
+	{
+		REG_LOCAL_IRQ_SAVE;
+
+		pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT);
+		/* Load new phase value */
+		pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+
+		REG_LOCAL_IRQ_RESTORE;
+	}
+	/* Return the status */
+	return (int)adjustCount;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set VPM clock in sync with BUS clock
+*
+*  This function does the phase adjustment between VPM and BUS clock
+*
+*  @return >= 0 : On success (# of adjustment required)
+*            -1 : On failure
+*
+*/
+/****************************************************************************/
+int chipcHw_vpmPhaseAlign(void)
+{
+
+	if (chipcHw_getChipRevisionNumber() == chipcHw_REV_NUMBER_A0) {
+		return vpmPhaseAlignA0();
+	} else {
+		uint32_t phaseControl = chipcHw_getVpmPhaseControl();
+		uint32_t phaseValue = 0;
+		int adjustCount = 0;
+
+		/* Disable VPM access */
+		pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
+		/* Disable HW VPM phase alignment  */
+		chipcHw_vpmHwPhaseAlignDisable();
+		/* Enable SW VPM phase alignment  */
+		chipcHw_vpmSwPhaseAlignEnable();
+		/* Adjust VPM phase */
+		while (adjustCount < MAX_PHASE_ADJUST_COUNT) {
+			phaseValue = chipcHw_getVpmHwPhaseAlignStatus();
+
+			/* Adjust phase control value */
+			if (phaseValue > 0xF) {
+				/* Increment phase control value */
+				phaseControl++;
+			} else if (phaseValue < 0xF) {
+				/* Decrement phase control value */
+				phaseControl--;
+			} else {
+				/* Enable VPM access */
+				pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
+				/* Return adjust count */
+				return adjustCount;
+			}
+			/* Change the value of PH_CTRL. */
+			reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+			/* Wait atleast 20 ns */
+			udelay(1);
+			/* Toggle the LOAD_CH after phase control is written. */
+			pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+			/* Count adjustment */
+			adjustCount++;
+		}
+	}
+
+	/* Disable VPM access */
+	pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
+	return -1;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Local Divide function
+*
+*  This function does the divide
+*
+*  @return divide value
+*
+*/
+/****************************************************************************/
+static int chipcHw_divide(int num, int denom)
+{
+	int r;
+	int t = 1;
+
+	/* Shift denom and t up to the largest value to optimize algorithm */
+	/* t contains the units of each divide */
+	while ((denom & 0x40000000) == 0) {	/* fails if denom=0 */
+		denom = denom << 1;
+		t = t << 1;
+	}
+
+	/* Intialize the result */
+	r = 0;
+
+	do {
+		/* Determine if there exists a positive remainder */
+		if ((num - denom) >= 0) {
+			/* Accumlate t to the result and calculate a new remainder */
+			num = num - denom;
+			r = r + t;
+		}
+		/* Continue to shift denom and shift t down to 0 */
+		denom = denom >> 1;
+		t = t >> 1;
+	} while (t != 0);
+
+	return r;
+}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c
new file mode 100644
index 0000000..367df75
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c
@@ -0,0 +1,293 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    chipcHw_init.c
+*
+*  @brief   Low level CHIPC PLL configuration functions
+*
+*  @note
+*
+*   These routines provide basic PLL controlling functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/stdint.h>
+#include <csp/module.h>
+
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include <csp/reg.h>
+#include <csp/delay.h>
+/* ---- Private Constants and Types --------------------------------------- */
+
+/*
+    Calculation for NDIV_i to obtain VCO frequency
+    -----------------------------------------------
+
+	Freq_vco = Freq_ref * (P2 / P1) * (PLL_NDIV_i + PLL_NDIV_f)
+	for Freq_vco = VCO_FREQ_MHz
+		Freq_ref = chipcHw_XTAL_FREQ_Hz
+		PLL_P1 = PLL_P2 = 1
+		and
+		PLL_NDIV_f = 0
+
+	We get:
+		PLL_NDIV_i = Freq_vco / Freq_ref = VCO_FREQ_MHz / chipcHw_XTAL_FREQ_Hz
+
+    Calculation for PLL MDIV to obtain frequency Freq_x for channel x
+    -----------------------------------------------------------------
+		Freq_x = chipcHw_XTAL_FREQ_Hz * PLL_NDIV_i / PLL_MDIV_x = VCO_FREQ_MHz / PLL_MDIV_x
+
+		PLL_MDIV_x = VCO_FREQ_MHz / Freq_x
+*/
+
+/* ---- Private Variables ------------------------------------------------- */
+/****************************************************************************/
+/**
+*  @brief  Initializes the PLL2
+*
+*  This function initializes the PLL2
+*
+*/
+/****************************************************************************/
+void chipcHw_pll2Enable(uint32_t vcoFreqHz)
+{
+	uint32_t pllPreDivider2 = 0;
+
+	{
+		REG_LOCAL_IRQ_SAVE;
+		pChipcHw->PLLConfig2 =
+		    chipcHw_REG_PLL_CONFIG_D_RESET |
+		    chipcHw_REG_PLL_CONFIG_A_RESET;
+
+		pllPreDivider2 = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
+		    chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
+		    (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
+		     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
+		    (chipcHw_REG_PLL_PREDIVIDER_P1 <<
+		     chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
+		    (chipcHw_REG_PLL_PREDIVIDER_P2 <<
+		     chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
+
+		/* Enable CHIPC registers to control the PLL */
+		pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
+
+		/* Set pre divider to get desired VCO frequency */
+		pChipcHw->PLLPreDivider2 = pllPreDivider2;
+		/* Set NDIV Frac */
+		pChipcHw->PLLDivider2 = chipcHw_REG_PLL_DIVIDER_NDIV_f;
+
+		/* This has to be removed once the default values are fixed for PLL2. */
+		pChipcHw->PLLControl12 = 0x38000700;
+		pChipcHw->PLLControl22 = 0x00000015;
+
+		/* Reset PLL2 */
+		if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
+			pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
+			    chipcHw_REG_PLL_CONFIG_A_RESET |
+			    chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
+			    chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+		} else {
+			pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
+			    chipcHw_REG_PLL_CONFIG_A_RESET |
+			    chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
+			    chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+		}
+		REG_LOCAL_IRQ_RESTORE;
+	}
+
+	/* Insert certain amount of delay before deasserting ARESET. */
+	udelay(1);
+
+	{
+		REG_LOCAL_IRQ_SAVE;
+		/* Remove analog reset and Power on the PLL */
+		pChipcHw->PLLConfig2 &=
+		    ~(chipcHw_REG_PLL_CONFIG_A_RESET |
+		      chipcHw_REG_PLL_CONFIG_POWER_DOWN);
+
+		REG_LOCAL_IRQ_RESTORE;
+
+	}
+
+	/* Wait until PLL is locked */
+	while (!(pChipcHw->PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
+		;
+
+	{
+		REG_LOCAL_IRQ_SAVE;
+		/* Remove digital reset */
+		pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
+
+		REG_LOCAL_IRQ_RESTORE;
+	}
+}
+
+EXPORT_SYMBOL(chipcHw_pll2Enable);
+
+/****************************************************************************/
+/**
+*  @brief  Initializes the PLL1
+*
+*  This function initializes the PLL1
+*
+*/
+/****************************************************************************/
+void chipcHw_pll1Enable(uint32_t vcoFreqHz, chipcHw_SPREAD_SPECTRUM_e ssSupport)
+{
+	uint32_t pllPreDivider = 0;
+
+	{
+		REG_LOCAL_IRQ_SAVE;
+
+		pChipcHw->PLLConfig =
+		    chipcHw_REG_PLL_CONFIG_D_RESET |
+		    chipcHw_REG_PLL_CONFIG_A_RESET;
+		/* Setting VCO frequency */
+		if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
+			pllPreDivider =
+			    chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 |
+			    ((chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) -
+			      1) << chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
+			    (chipcHw_REG_PLL_PREDIVIDER_P1 <<
+			     chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
+			    (chipcHw_REG_PLL_PREDIVIDER_P2 <<
+			     chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
+		} else {
+			pllPreDivider = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
+			    chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
+			    (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
+			     chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
+			    (chipcHw_REG_PLL_PREDIVIDER_P1 <<
+			     chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
+			    (chipcHw_REG_PLL_PREDIVIDER_P2 <<
+			     chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
+		}
+
+		/* Enable CHIPC registers to control the PLL */
+		pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
+
+		/* Set pre divider to get desired VCO frequency */
+		pChipcHw->PLLPreDivider = pllPreDivider;
+		/* Set NDIV Frac */
+		if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
+			pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
+			    chipcHw_REG_PLL_DIVIDER_NDIV_f_SS;
+		} else {
+			pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
+			    chipcHw_REG_PLL_DIVIDER_NDIV_f;
+		}
+
+		/* Reset PLL1 */
+		if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
+			pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
+			    chipcHw_REG_PLL_CONFIG_A_RESET |
+			    chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
+			    chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+		} else {
+			pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
+			    chipcHw_REG_PLL_CONFIG_A_RESET |
+			    chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
+			    chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+		}
+
+		REG_LOCAL_IRQ_RESTORE;
+
+		/* Insert certain amount of delay before deasserting ARESET. */
+		udelay(1);
+
+		{
+			REG_LOCAL_IRQ_SAVE;
+			/* Remove analog reset and Power on the PLL */
+			pChipcHw->PLLConfig &=
+			    ~(chipcHw_REG_PLL_CONFIG_A_RESET |
+			      chipcHw_REG_PLL_CONFIG_POWER_DOWN);
+			REG_LOCAL_IRQ_RESTORE;
+		}
+
+		/* Wait until PLL is locked */
+		while (!(pChipcHw->PLLStatus & chipcHw_REG_PLL_STATUS_LOCKED)
+		       || !(pChipcHw->
+			    PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
+			;
+
+		/* Remove digital reset */
+		{
+			REG_LOCAL_IRQ_SAVE;
+			pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
+			REG_LOCAL_IRQ_RESTORE;
+		}
+	}
+}
+
+EXPORT_SYMBOL(chipcHw_pll1Enable);
+
+/****************************************************************************/
+/**
+*  @brief  Initializes the chipc module
+*
+*  This function initializes the PLLs and core system clocks
+*
+*/
+/****************************************************************************/
+
+void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam	/*  [ IN ] Misc chip initialization parameter */
+    ) {
+#if !(defined(__KERNEL__) && !defined(STANDALONE))
+	delay_init();
+#endif
+
+	/* Do not program PLL, when warm reset */
+	if (!(chipcHw_getStickyBits() & chipcHw_REG_STICKY_CHIP_WARM_RESET)) {
+		chipcHw_pll1Enable(initParam->pllVcoFreqHz,
+				   initParam->ssSupport);
+		chipcHw_pll2Enable(initParam->pll2VcoFreqHz);
+	} else {
+		/* Clear sticky bits */
+		chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_WARM_RESET);
+	}
+	/* Clear sticky bits */
+	chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_SOFT_RESET);
+
+	/* Before configuring the ARM clock, atleast we need to make sure BUS clock maintains the proper ratio with ARM clock */
+	pChipcHw->ACLKClock =
+	    (pChipcHw->
+	     ACLKClock & ~chipcHw_REG_ACLKClock_CLK_DIV_MASK) | (initParam->
+								 armBusRatio &
+								 chipcHw_REG_ACLKClock_CLK_DIV_MASK);
+
+	/* Set various core component frequencies. The order in which this is done is important for some. */
+	/* The RTBUS (DDR PHY) is derived from the BUS, and the BUS from the ARM, and VPM needs to know BUS */
+	/* frequency to find its ratio with the BUS.  Hence we must set the ARM first, followed by the BUS,  */
+	/* then VPM and RTBUS. */
+
+	chipcHw_setClockFrequency(chipcHw_CLOCK_ARM,
+				  initParam->busClockFreqHz *
+				  initParam->armBusRatio);
+	chipcHw_setClockFrequency(chipcHw_CLOCK_BUS, initParam->busClockFreqHz);
+	chipcHw_setClockFrequency(chipcHw_CLOCK_VPM,
+				  initParam->busClockFreqHz *
+				  initParam->vpmBusRatio);
+	chipcHw_setClockFrequency(chipcHw_CLOCK_DDR,
+				  initParam->busClockFreqHz *
+				  initParam->ddrBusRatio);
+	chipcHw_setClockFrequency(chipcHw_CLOCK_RTBUS,
+				  initParam->busClockFreqHz / 2);
+}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
new file mode 100644
index 0000000..2671d88
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
@@ -0,0 +1,124 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/stdint.h>
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+#include <csp/intcHw.h>
+#include <csp/cache.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+/* ---- Private Variables ------------------------------------------------- */
+void chipcHw_reset_run_from_aram(void);
+
+typedef void (*RUNFUNC) (void);
+
+/****************************************************************************/
+/**
+*  @brief   warmReset
+*
+*  @note warmReset configures the clocks which are not reset back to the state
+*   required to execute on reset.  To do so we need to copy the code into internal
+*   memory to change the ARM clock while we are not executing from DDR.
+*/
+/****************************************************************************/
+void chipcHw_reset(uint32_t mask)
+{
+	int i = 0;
+	RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM;
+
+	/* Disable all interrupts */
+	intcHw_irq_disable(INTCHW_INTC0, 0xffffffff);
+	intcHw_irq_disable(INTCHW_INTC1, 0xffffffff);
+	intcHw_irq_disable(INTCHW_SINTC, 0xffffffff);
+
+	{
+		REG_LOCAL_IRQ_SAVE;
+		if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) {
+			chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
+		}
+		/* Bypass the PLL clocks before reboot */
+		pChipcHw->UARTClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
+		pChipcHw->SPIClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
+
+		/* Copy the chipcHw_warmReset_run_from_aram function into ARAM */
+		do {
+			((uint32_t *) MM_IO_BASE_ARAM)[i] =
+			    ((uint32_t *) &chipcHw_reset_run_from_aram)[i];
+			i++;
+		} while (((uint32_t *) MM_IO_BASE_ARAM)[i - 1] != 0xe1a0f00f);	/* 0xe1a0f00f == asm ("mov r15, r15"); */
+
+		CSP_CACHE_FLUSH_ALL;
+
+		/* run the function from ARAM */
+		runFunc();
+
+		/* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */
+		REG_LOCAL_IRQ_RESTORE;
+	}
+}
+
+/* This function must run from internal memory */
+void chipcHw_reset_run_from_aram(void)
+{
+/* Make sure, pipeline is filled with instructions coming from ARAM */
+__asm (" nop                                                            \n\t"
+		" nop                                                            \n\t"
+#if defined(__KERNEL__) && !defined(STANDALONE)
+		" MRC      p15,#0x0,r0,c1,c0,#0                                  \n\t"
+		" BIC      r0,r0,#0xd                                            \n\t"
+		" MCR      p15,#0x0,r0,c1,c0,#0                                  \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+#endif
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+/* Bypass the ARM clock and switch to XTAL clock */
+		" MOV      r2,#0x80000000                                        \n\t"
+		" LDR      r3,[r2,#8]                                            \n\t"
+		" ORR      r3,r3,#0x20000                                        \n\t"
+		" STR      r3,[r2,#8]                                            \n\t"
+
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+		" nop                                                            \n\t"
+/* Issue reset */
+		" MOV      r3,#0x2                                               \n\t"
+		" STR      r3,[r2,#0x80]                                         \n\t"
+/* End here */
+		" MOV      pc,pc                                                 \n\t");
+/* 0xe1a0f00f ==  asm ("mov r15, r15"); */
+}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c
new file mode 100644
index 0000000..54ad964
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c
@@ -0,0 +1,64 @@
+/*****************************************************************************
+* Copyright 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+/****************************************************************************/
+/**
+*  @file    chipcHw_str.c
+*
+*  @brief   Contains strings which are useful to linux and csp
+*
+*  @note
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <mach/csp/chipcHw_inline.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+
+static const char *gMuxStr[] = {
+	"GPIO",			/* 0 */
+	"KeyPad",		/* 1 */
+	"I2C-Host",		/* 2 */
+	"SPI",			/* 3 */
+	"Uart",			/* 4 */
+	"LED-Mtx-P",		/* 5 */
+	"LED-Mtx-S",		/* 6 */
+	"SDIO-0",		/* 7 */
+	"SDIO-1",		/* 8 */
+	"PCM",			/* 9 */
+	"I2S",			/* 10 */
+	"ETM",			/* 11 */
+	"Debug",		/* 12 */
+	"Misc",			/* 13 */
+	"0xE",			/* 14 */
+	"0xF",			/* 15 */
+};
+
+/****************************************************************************/
+/**
+*  @brief   Retrieves a string representation of the mux setting for a pin.
+*
+*  @return  Pointer to a character string.
+*/
+/****************************************************************************/
+
+const char *chipcHw_getGpioPinFunctionStr(int pin)
+{
+	if ((pin < 0) || (pin >= chipcHw_GPIO_COUNT)) {
+		return "";
+	}
+
+	return gMuxStr[chipcHw_getGpioPinFunction(pin)];
+}
diff --git a/arch/arm/mach-bcmring/csp/dmac/Makefile b/arch/arm/mach-bcmring/csp/dmac/Makefile
new file mode 100644
index 0000000..fb1104f
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/Makefile
@@ -0,0 +1 @@
+obj-y += dmacHw.o dmacHw_extra.o
\ No newline at end of file
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c
new file mode 100644
index 0000000..7b9bac2
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c
@@ -0,0 +1,917 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    dmacHw.c
+*
+*  @brief   Low level DMA controller driver routines
+*
+*  @note
+*
+*   These routines provide basic DMA functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/stdint.h>
+#include <csp/string.h>
+#include <stddef.h>
+
+#include <csp/dmacHw.h>
+#include <mach/csp/dmacHw_reg.h>
+#include <mach/csp/dmacHw_priv.h>
+#include <mach/csp/chipcHw_inline.h>
+
+/* ---- External Function Prototypes ------------------------------------- */
+
+/* Allocate DMA control blocks */
+dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT];
+
+uint32_t dmaChannelCount_0 = dmacHw_MAX_CHANNEL_COUNT / 2;
+uint32_t dmaChannelCount_1 = dmacHw_MAX_CHANNEL_COUNT / 2;
+
+/****************************************************************************/
+/**
+*  @brief   Get maximum FIFO for a DMA channel
+*
+*  @return  Maximum allowable FIFO size
+*
+*
+*/
+/****************************************************************************/
+static uint32_t GetFifoSize(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle */
+    ) {
+	uint32_t val = 0;
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+	dmacHw_MISC_t *pMiscReg =
+	    (dmacHw_MISC_t *) dmacHw_REG_MISC_BASE(pCblk->module);
+
+	switch (pCblk->channel) {
+	case 0:
+		val = (pMiscReg->CompParm2.lo & 0x70000000) >> 28;
+		break;
+	case 1:
+		val = (pMiscReg->CompParm3.hi & 0x70000000) >> 28;
+		break;
+	case 2:
+		val = (pMiscReg->CompParm3.lo & 0x70000000) >> 28;
+		break;
+	case 3:
+		val = (pMiscReg->CompParm4.hi & 0x70000000) >> 28;
+		break;
+	case 4:
+		val = (pMiscReg->CompParm4.lo & 0x70000000) >> 28;
+		break;
+	case 5:
+		val = (pMiscReg->CompParm5.hi & 0x70000000) >> 28;
+		break;
+	case 6:
+		val = (pMiscReg->CompParm5.lo & 0x70000000) >> 28;
+		break;
+	case 7:
+		val = (pMiscReg->CompParm6.hi & 0x70000000) >> 28;
+		break;
+	}
+
+	if (val <= 0x4) {
+		return 8 << val;
+	} else {
+		dmacHw_ASSERT(0);
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Program channel register to initiate transfer
+*
+*  @return  void
+*
+*
+*  @note
+*     - Descriptor buffer MUST ALWAYS be flushed before calling this function
+*     - This function should also be called from ISR to program the channel with
+*       pending descriptors
+*/
+/****************************************************************************/
+void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
+			     dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+			     void *pDescriptor	/*   [ IN ] Descriptor buffer */
+    ) {
+	dmacHw_DESC_RING_t *pRing;
+	dmacHw_DESC_t *pProg;
+	dmacHw_CBLK_t *pCblk;
+
+	pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+	pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+	if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
+		/* Not safe yet to program the channel */
+		return;
+	}
+
+	if (pCblk->varDataStarted) {
+		if (pCblk->descUpdated) {
+			pCblk->descUpdated = 0;
+			pProg =
+			    (dmacHw_DESC_t *) ((uint32_t)
+					       dmacHw_REG_LLP(pCblk->module,
+							      pCblk->channel) +
+					       pRing->virt2PhyOffset);
+
+			/* Load descriptor if not loaded */
+			if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
+				dmacHw_SET_SAR(pCblk->module, pCblk->channel,
+					       pProg->sar);
+				dmacHw_SET_DAR(pCblk->module, pCblk->channel,
+					       pProg->dar);
+				dmacHw_REG_CTL_LO(pCblk->module,
+						  pCblk->channel) =
+				    pProg->ctl.lo;
+				dmacHw_REG_CTL_HI(pCblk->module,
+						  pCblk->channel) =
+				    pProg->ctl.hi;
+			} else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
+				/* Return as end descriptor is processed */
+				return;
+			} else {
+				dmacHw_ASSERT(0);
+			}
+		} else {
+			return;
+		}
+	} else {
+		if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
+			/* Do not make a single chain, rather process one descriptor at a time */
+			pProg = pRing->pHead;
+			/* Point to the next descriptor for next iteration */
+			dmacHw_NEXT_DESC(pRing, pHead);
+		} else {
+			/* Return if no more pending descriptor */
+			if (pRing->pEnd == NULL) {
+				return;
+			}
+
+			pProg = pRing->pProg;
+			if (pConfig->transferMode ==
+			    dmacHw_TRANSFER_MODE_CONTINUOUS) {
+				/* Make sure a complete ring can be formed */
+				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
+					      llp == pRing->pProg);
+				/* Make sure pProg pointing to the pHead */
+				dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
+					      pRing->pHead);
+				/* Make a complete ring */
+				do {
+					pRing->pProg->ctl.lo |=
+					    (dmacHw_REG_CTL_LLP_DST_EN |
+					     dmacHw_REG_CTL_LLP_SRC_EN);
+					pRing->pProg =
+					    (dmacHw_DESC_t *) pRing->pProg->llp;
+				} while (pRing->pProg != pRing->pHead);
+			} else {
+				/* Make a single long chain */
+				while (pRing->pProg != pRing->pEnd) {
+					pRing->pProg->ctl.lo |=
+					    (dmacHw_REG_CTL_LLP_DST_EN |
+					     dmacHw_REG_CTL_LLP_SRC_EN);
+					pRing->pProg =
+					    (dmacHw_DESC_t *) pRing->pProg->llp;
+				}
+			}
+		}
+
+		/* Program the channel registers */
+		dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
+		dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
+		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
+			       (uint32_t) pProg - pRing->virt2PhyOffset);
+		dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
+		    pProg->ctl.lo;
+		dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
+		    pProg->ctl.hi;
+		if (pRing->pEnd) {
+			/* Remember the descriptor to use next */
+			pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
+		}
+		/* Indicate no more pending descriptor  */
+		pRing->pEnd = (dmacHw_DESC_t *) NULL;
+	}
+	/* Start DMA operation */
+	dmacHw_DMA_START(pCblk->module, pCblk->channel);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Initializes DMA
+*
+*  This function initializes DMA CSP driver
+*
+*  @note
+*     Must be called before using any DMA channel
+*/
+/****************************************************************************/
+void dmacHw_initDma(void)
+{
+
+	uint32_t i = 0;
+
+	dmaChannelCount_0 = dmacHw_GET_NUM_CHANNEL(0);
+	dmaChannelCount_1 = dmacHw_GET_NUM_CHANNEL(1);
+
+	/* Enable access to the DMA block */
+	chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC0);
+	chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC1);
+
+	if ((dmaChannelCount_0 + dmaChannelCount_1) > dmacHw_MAX_CHANNEL_COUNT) {
+		dmacHw_ASSERT(0);
+	}
+
+	memset((void *)dmacHw_gCblk, 0,
+	       sizeof(dmacHw_CBLK_t) * (dmaChannelCount_0 + dmaChannelCount_1));
+	for (i = 0; i < dmaChannelCount_0; i++) {
+		dmacHw_gCblk[i].module = 0;
+		dmacHw_gCblk[i].channel = i;
+	}
+	for (i = 0; i < dmaChannelCount_1; i++) {
+		dmacHw_gCblk[i + dmaChannelCount_0].module = 1;
+		dmacHw_gCblk[i + dmaChannelCount_0].channel = i;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Exit function for  DMA
+*
+*  This function isolates DMA from the system
+*
+*/
+/****************************************************************************/
+void dmacHw_exitDma(void)
+{
+	/* Disable access to the DMA block */
+	chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC0);
+	chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC1);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Gets a handle to a DMA channel
+*
+*  This function returns a handle, representing a control block of a particular DMA channel
+*
+*  @return  -1       - On Failure
+*            handle  - On Success, representing a channel control block
+*
+*  @note
+*     None  Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId	/* [ IN ] DMA Channel Id */
+    ) {
+	int idx;
+
+	switch ((channelId >> 8)) {
+	case 0:
+		dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_0);
+		idx = (channelId & 0xff);
+		break;
+	case 1:
+		dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_1);
+		idx = dmaChannelCount_0 + (channelId & 0xff);
+		break;
+	default:
+		dmacHw_ASSERT(0);
+		return (dmacHw_HANDLE_t) -1;
+	}
+
+	return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[idx]);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Initializes a DMA channel for use
+*
+*  This function initializes and resets a DMA channel for use
+*
+*  @return  -1     - On Failure
+*            0     - On Success
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+int dmacHw_initChannel(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+	int module = pCblk->module;
+	int channel = pCblk->channel;
+
+	/* Reinitialize the control block */
+	memset((void *)pCblk, 0, sizeof(dmacHw_CBLK_t));
+	pCblk->module = module;
+	pCblk->channel = channel;
+
+	/* Enable DMA controller */
+	dmacHw_DMA_ENABLE(pCblk->module);
+	/* Reset DMA channel */
+	dmacHw_RESET_CONTROL_LO(pCblk->module, pCblk->channel);
+	dmacHw_RESET_CONTROL_HI(pCblk->module, pCblk->channel);
+	dmacHw_RESET_CONFIG_LO(pCblk->module, pCblk->channel);
+	dmacHw_RESET_CONFIG_HI(pCblk->module, pCblk->channel);
+
+	/* Clear all raw interrupt status */
+	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
+	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
+	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
+
+	/* Mask event specific interrupts */
+	dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+	dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
+	dmacHw_STRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+	dmacHw_DTRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+	dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
+
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief  Finds amount of memory required to form a descriptor ring
+*
+*
+*  @return   Number of bytes required to form a descriptor ring
+*
+*
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorLen(uint32_t descCnt	/* [ IN ] Number of descriptor in the ring */
+    ) {
+	/* Need extra 4 byte to ensure 32 bit alignment  */
+	return (descCnt * sizeof(dmacHw_DESC_t)) + sizeof(dmacHw_DESC_RING_t) +
+		sizeof(uint32_t);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Initializes descriptor ring
+*
+*  This function will initializes the descriptor ring of a DMA channel
+*
+*
+*  @return   -1 - On failure
+*             0 - On success
+*  @note
+*     - "len" parameter should be obtained from "dmacHw_descriptorLen"
+*     - Descriptor buffer MUST be 32 bit aligned and uncached as it is
+*       accessed by ARM and DMA
+*/
+/****************************************************************************/
+int dmacHw_initDescriptor(void *pDescriptorVirt,	/*  [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */
+			  uint32_t descriptorPhyAddr,	/*  [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */
+			  uint32_t len,	/*  [ IN ] Size of the pBuf */
+			  uint32_t num	/*  [ IN ] Number of descriptor in the ring */
+    ) {
+	uint32_t i;
+	dmacHw_DESC_RING_t *pRing;
+	dmacHw_DESC_t *pDesc;
+
+	/* Check the alignment of the descriptor */
+	if ((uint32_t) pDescriptorVirt & 0x00000003) {
+		dmacHw_ASSERT(0);
+		return -1;
+	}
+
+	/* Check if enough space has been allocated for descriptor ring */
+	if (len < dmacHw_descriptorLen(num)) {
+		return -1;
+	}
+
+	pRing = dmacHw_GET_DESC_RING(pDescriptorVirt);
+	pRing->pHead =
+	    (dmacHw_DESC_t *) ((uint32_t) pRing + sizeof(dmacHw_DESC_RING_t));
+	pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead;
+	pRing->pProg = dmacHw_DESC_INIT;
+	/* Initialize link item chain, starting from the head */
+	pDesc = pRing->pHead;
+	/* Find the offset between virtual to physical address */
+	pRing->virt2PhyOffset = (uint32_t) pDescriptorVirt - descriptorPhyAddr;
+
+	/* Form the descriptor ring */
+	for (i = 0; i < num - 1; i++) {
+		/* Clear link list item */
+		memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
+		/* Point to the next item in the physical address */
+		pDesc->llpPhy = (uint32_t) (pDesc + 1) - pRing->virt2PhyOffset;
+		/* Point to the next item in the virtual address */
+		pDesc->llp = (uint32_t) (pDesc + 1);
+		/* Mark descriptor is ready to use */
+		pDesc->ctl.hi = dmacHw_DESC_FREE;
+		/* Look into next link list item */
+		pDesc++;
+	}
+
+	/* Clear last link list item */
+	memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
+	/* Last item pointing to the first item in the
+	   physical address to complete the ring */
+	pDesc->llpPhy = (uint32_t) pRing->pHead - pRing->virt2PhyOffset;
+	/* Last item pointing to the first item in the
+	   virtual address to complete the ring
+	 */
+	pDesc->llp = (uint32_t) pRing->pHead;
+	/* Mark descriptor is ready to use */
+	pDesc->ctl.hi = dmacHw_DESC_FREE;
+	/* Set the number of descriptors in the ring */
+	pRing->num = num;
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Configure DMA channel
+*
+*  @return  0  : On success
+*           -1 : On failure
+*/
+/****************************************************************************/
+int dmacHw_configChannel(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
+			 dmacHw_CONFIG_t *pConfig	/*   [ IN ] Configuration settings */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+	uint32_t cfgHigh = 0;
+	int srcTrSize;
+	int dstTrSize;
+
+	pCblk->varDataStarted = 0;
+	pCblk->userData = NULL;
+
+	/* Configure
+	   - Burst transaction when enough data in available in FIFO
+	   - AHB Access protection 1
+	   - Source and destination peripheral ports
+	 */
+	cfgHigh =
+	    dmacHw_REG_CFG_HI_FIFO_ENOUGH | dmacHw_REG_CFG_HI_AHB_HPROT_1 |
+	    dmacHw_SRC_PERI_INTF(pConfig->
+				 srcPeripheralPort) |
+	    dmacHw_DST_PERI_INTF(pConfig->dstPeripheralPort);
+	/* Set priority */
+	dmacHw_SET_CHANNEL_PRIORITY(pCblk->module, pCblk->channel,
+				    pConfig->channelPriority);
+
+	if (pConfig->dstStatusRegisterAddress != 0) {
+		/* Destination status update enable */
+		cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_DST_STAT;
+		/* Configure status registers */
+		dmacHw_SET_DSTATAR(pCblk->module, pCblk->channel,
+				   pConfig->dstStatusRegisterAddress);
+	}
+
+	if (pConfig->srcStatusRegisterAddress != 0) {
+		/* Source status update enable */
+		cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_SRC_STAT;
+		/* Source status update enable */
+		dmacHw_SET_SSTATAR(pCblk->module, pCblk->channel,
+				   pConfig->srcStatusRegisterAddress);
+	}
+	/* Configure the config high register */
+	dmacHw_GET_CONFIG_HI(pCblk->module, pCblk->channel) = cfgHigh;
+
+	/* Clear all raw interrupt status */
+	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
+	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
+	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
+
+	/* Configure block interrupt */
+	if (pConfig->blockTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
+		dmacHw_BLOCK_INT_ENABLE(pCblk->module, pCblk->channel);
+	} else {
+		dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
+	}
+	/* Configure complete transfer interrupt */
+	if (pConfig->completeTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
+		dmacHw_TRAN_INT_ENABLE(pCblk->module, pCblk->channel);
+	} else {
+		dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+	}
+	/* Configure error interrupt */
+	if (pConfig->errorInterrupt == dmacHw_INTERRUPT_ENABLE) {
+		dmacHw_ERROR_INT_ENABLE(pCblk->module, pCblk->channel);
+	} else {
+		dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
+	}
+	/* Configure gather register */
+	if (pConfig->srcGatherWidth) {
+		srcTrSize =
+		    dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+		if (!
+		    ((pConfig->srcGatherWidth % srcTrSize)
+		     && (pConfig->srcGatherJump % srcTrSize))) {
+			dmacHw_REG_SGR_LO(pCblk->module, pCblk->channel) =
+			    ((pConfig->srcGatherWidth /
+			      srcTrSize) << 20) | (pConfig->srcGatherJump /
+						   srcTrSize);
+		} else {
+			return -1;
+		}
+	}
+	/* Configure scatter register */
+	if (pConfig->dstScatterWidth) {
+		dstTrSize =
+		    dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
+		if (!
+		    ((pConfig->dstScatterWidth % dstTrSize)
+		     && (pConfig->dstScatterJump % dstTrSize))) {
+			dmacHw_REG_DSR_LO(pCblk->module, pCblk->channel) =
+			    ((pConfig->dstScatterWidth /
+			      dstTrSize) << 20) | (pConfig->dstScatterJump /
+						   dstTrSize);
+		} else {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Indicates whether DMA transfer is in progress or completed
+*
+*  @return   DMA transfer status
+*          dmacHw_TRANSFER_STATUS_BUSY:         DMA Transfer ongoing
+*          dmacHw_TRANSFER_STATUS_DONE:         DMA Transfer completed
+*          dmacHw_TRANSFER_STATUS_ERROR:        DMA Transfer error
+*
+*/
+/****************************************************************************/
+dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+	if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
+		return dmacHw_TRANSFER_STATUS_BUSY;
+	} else if (dmacHw_REG_INT_RAW_ERROR(pCblk->module) &
+		   (0x00000001 << pCblk->channel)) {
+		return dmacHw_TRANSFER_STATUS_ERROR;
+	}
+
+	return dmacHw_TRANSFER_STATUS_DONE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set descriptors for known data length
+*
+*  When DMA has to work as a flow controller, this function prepares the
+*  descriptor chain to transfer data
+*
+*  from:
+*          - Memory to memory
+*          - Peripheral to memory
+*          - Memory to Peripheral
+*          - Peripheral to Peripheral
+*
+*  @return   -1 - On failure
+*             0 - On success
+*
+*/
+/****************************************************************************/
+int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+			     void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+			     void *pSrcAddr,	/*   [ IN ] Source (Peripheral/Memory) address */
+			     void *pDstAddr,	/*   [ IN ] Destination (Peripheral/Memory) address */
+			     size_t dataLen	/*   [ IN ] Data length in bytes */
+    ) {
+	dmacHw_TRANSACTION_WIDTH_e dstTrWidth;
+	dmacHw_TRANSACTION_WIDTH_e srcTrWidth;
+	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+	dmacHw_DESC_t *pStart;
+	dmacHw_DESC_t *pProg;
+	int srcTs = 0;
+	int blkTs = 0;
+	int oddSize = 0;
+	int descCount = 0;
+	int count = 0;
+	int dstTrSize = 0;
+	int srcTrSize = 0;
+	uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE;
+
+	dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
+	srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+
+	/* Skip Tx if buffer is NULL  or length is unknown */
+	if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) {
+		/* Do not initiate transfer */
+		return -1;
+	}
+
+	/* Ensure scatter and gather are transaction aligned */
+	if ((pConfig->srcGatherWidth % srcTrSize)
+	    || (pConfig->dstScatterWidth % dstTrSize)) {
+		return -2;
+	}
+
+	/*
+	   Background 1: DMAC can not perform DMA if source and destination addresses are
+	   not properly aligned with the channel's transaction width. So, for successful
+	   DMA transfer, transaction width must be set according to the alignment of the
+	   source and destination address.
+	 */
+
+	/* Adjust destination transaction width if destination address is not aligned properly */
+	dstTrWidth = pConfig->dstMaxTransactionWidth;
+	while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) {
+		dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth);
+		dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth);
+	}
+
+	/* Adjust source transaction width if source address is not aligned properly */
+	srcTrWidth = pConfig->srcMaxTransactionWidth;
+	while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) {
+		srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth);
+		srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth);
+	}
+
+	/* Find the maximum transaction per descriptor */
+	if (pConfig->maxDataPerBlock
+	    && ((pConfig->maxDataPerBlock / srcTrSize) <
+		dmacHw_MAX_BLOCKSIZE)) {
+		maxBlockSize = pConfig->maxDataPerBlock / srcTrSize;
+	}
+
+	/* Find number of source transactions needed to complete the DMA transfer */
+	srcTs = dataLen / srcTrSize;
+	/* Find the odd number of bytes that need to be transferred as single byte transaction width */
+	if (srcTs && (dstTrSize > srcTrSize)) {
+		oddSize = dataLen % dstTrSize;
+		/* Adjust source transaction count due to "oddSize" */
+		srcTs = srcTs - (oddSize / srcTrSize);
+	} else {
+		oddSize = dataLen % srcTrSize;
+	}
+	/* Adjust "descCount" due to "oddSize" */
+	if (oddSize) {
+		descCount++;
+	}
+	/* Find the number of descriptor needed for total "srcTs" */
+	if (srcTs) {
+		descCount += ((srcTs - 1) / maxBlockSize) + 1;
+	}
+
+	/* Check the availability of "descCount" discriptors in the ring */
+	pProg = pRing->pHead;
+	for (count = 0; (descCount <= pRing->num) && (count < descCount);
+	     count++) {
+		if ((pProg->ctl.hi & dmacHw_DESC_FREE) == 0) {
+			/* Sufficient descriptors are not available */
+			return -3;
+		}
+		pProg = (dmacHw_DESC_t *) pProg->llp;
+	}
+
+	/* Remember the link list item to program the channel registers */
+	pStart = pProg = pRing->pHead;
+	/* Make a link list with "descCount(=count)" number of descriptors */
+	while (count) {
+		/* Reset channel control information */
+		pProg->ctl.lo = 0;
+		/* Enable source gather if configured */
+		if (pConfig->srcGatherWidth) {
+			pProg->ctl.lo |= dmacHw_REG_CTL_SG_ENABLE;
+		}
+		/* Enable destination scatter if configured */
+		if (pConfig->dstScatterWidth) {
+			pProg->ctl.lo |= dmacHw_REG_CTL_DS_ENABLE;
+		}
+		/* Set source and destination address */
+		pProg->sar = (uint32_t) pSrcAddr;
+		pProg->dar = (uint32_t) pDstAddr;
+		/* Use "devCtl" to mark that user memory need to be freed later if needed */
+		if (pProg == pRing->pHead) {
+			pProg->devCtl = dmacHw_FREE_USER_MEMORY;
+		} else {
+			pProg->devCtl = 0;
+		}
+
+		blkTs = srcTs;
+
+		/* Special treatmeant for last descriptor */
+		if (count == 1) {
+			/* Mark the last descriptor */
+			pProg->ctl.lo &=
+			    ~(dmacHw_REG_CTL_LLP_DST_EN |
+			      dmacHw_REG_CTL_LLP_SRC_EN);
+			/* Treatment for odd data bytes */
+			if (oddSize) {
+				/* Adjust for single byte transaction width */
+				switch (pConfig->transferType) {
+				case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+					dstTrWidth =
+					    dmacHw_DST_TRANSACTION_WIDTH_8;
+					blkTs =
+					    (oddSize / srcTrSize) +
+					    ((oddSize % srcTrSize) ? 1 : 0);
+					break;
+				case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+					srcTrWidth =
+					    dmacHw_SRC_TRANSACTION_WIDTH_8;
+					blkTs = oddSize;
+					break;
+				case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
+					srcTrWidth =
+					    dmacHw_SRC_TRANSACTION_WIDTH_8;
+					dstTrWidth =
+					    dmacHw_DST_TRANSACTION_WIDTH_8;
+					blkTs = oddSize;
+					break;
+				case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
+					/* Do not adjust the transaction width  */
+					break;
+				}
+			} else {
+				srcTs -= blkTs;
+			}
+		} else {
+			if (srcTs / maxBlockSize) {
+				blkTs = maxBlockSize;
+			}
+			/* Remaining source transactions for next iteration */
+			srcTs -= blkTs;
+		}
+		/* Must have a valid source transactions */
+		dmacHw_ASSERT(blkTs > 0);
+		/* Set control information */
+		if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) {
+			pProg->ctl.lo |= pConfig->transferType |
+			    pConfig->srcUpdate |
+			    pConfig->dstUpdate |
+			    srcTrWidth |
+			    dstTrWidth |
+			    pConfig->srcMaxBurstWidth |
+			    pConfig->dstMaxBurstWidth |
+			    pConfig->srcMasterInterface |
+			    pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
+		} else {
+			uint32_t transferType = 0;
+			switch (pConfig->transferType) {
+			case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+				transferType = dmacHw_REG_CTL_TTFC_PM_PERI;
+				break;
+			case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+				transferType = dmacHw_REG_CTL_TTFC_MP_PERI;
+				break;
+			default:
+				dmacHw_ASSERT(0);
+			}
+			pProg->ctl.lo |= transferType |
+			    pConfig->srcUpdate |
+			    pConfig->dstUpdate |
+			    srcTrWidth |
+			    dstTrWidth |
+			    pConfig->srcMaxBurstWidth |
+			    pConfig->dstMaxBurstWidth |
+			    pConfig->srcMasterInterface |
+			    pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
+		}
+
+		/* Set block transaction size */
+		pProg->ctl.hi = blkTs & dmacHw_REG_CTL_BLOCK_TS_MASK;
+		/* Look for next descriptor */
+		if (count > 1) {
+			/* Point to the next descriptor */
+			pProg = (dmacHw_DESC_t *) pProg->llp;
+
+			/* Update source and destination address for next iteration */
+			switch (pConfig->transferType) {
+			case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+				if (pConfig->dstScatterWidth) {
+					pDstAddr =
+					    (char *)pDstAddr +
+					    blkTs * srcTrSize +
+					    (((blkTs * srcTrSize) /
+					      pConfig->dstScatterWidth) *
+					     pConfig->dstScatterJump);
+				} else {
+					pDstAddr =
+					    (char *)pDstAddr +
+					    blkTs * srcTrSize;
+				}
+				break;
+			case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+				if (pConfig->srcGatherWidth) {
+					pSrcAddr =
+					    (char *)pDstAddr +
+					    blkTs * srcTrSize +
+					    (((blkTs * srcTrSize) /
+					      pConfig->srcGatherWidth) *
+					     pConfig->srcGatherJump);
+				} else {
+					pSrcAddr =
+					    (char *)pSrcAddr +
+					    blkTs * srcTrSize;
+				}
+				break;
+			case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
+				if (pConfig->dstScatterWidth) {
+					pDstAddr =
+					    (char *)pDstAddr +
+					    blkTs * srcTrSize +
+					    (((blkTs * srcTrSize) /
+					      pConfig->dstScatterWidth) *
+					     pConfig->dstScatterJump);
+				} else {
+					pDstAddr =
+					    (char *)pDstAddr +
+					    blkTs * srcTrSize;
+				}
+
+				if (pConfig->srcGatherWidth) {
+					pSrcAddr =
+					    (char *)pDstAddr +
+					    blkTs * srcTrSize +
+					    (((blkTs * srcTrSize) /
+					      pConfig->srcGatherWidth) *
+					     pConfig->srcGatherJump);
+				} else {
+					pSrcAddr =
+					    (char *)pSrcAddr +
+					    blkTs * srcTrSize;
+				}
+				break;
+			case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
+				/* Do not adjust the address */
+				break;
+			default:
+				dmacHw_ASSERT(0);
+			}
+		} else {
+			/* At the end of transfer "srcTs" must be zero */
+			dmacHw_ASSERT(srcTs == 0);
+		}
+		count--;
+	}
+
+	/* Remember the descriptor to initialize the registers */
+	if (pRing->pProg == dmacHw_DESC_INIT) {
+		pRing->pProg = pStart;
+	}
+	/* Indicate that the descriptor is updated */
+	pRing->pEnd = pProg;
+	/* Head pointing to the next descriptor */
+	pRing->pHead = (dmacHw_DESC_t *) pProg->llp;
+	/* Update Tail pointer if destination is a peripheral,
+	   because no one is going to read from the pTail
+	 */
+	if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
+		pRing->pTail = pRing->pHead;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Provides DMA controller attributes
+*
+*
+*  @return  DMA controller attributes
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle,	/*  [ IN ]  DMA Channel handle */
+					  dmacHw_CONTROLLER_ATTRIB_e attr	/*  [ IN ]  DMA Controler attribute of type  dmacHw_CONTROLLER_ATTRIB_e */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+	switch (attr) {
+	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM:
+		return dmacHw_GET_NUM_CHANNEL(pCblk->module);
+	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE:
+		return (1 <<
+			 (dmacHw_GET_MAX_BLOCK_SIZE
+			  (pCblk->module, pCblk->module) + 2)) - 8;
+	case dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM:
+		return dmacHw_GET_NUM_INTERFACE(pCblk->module);
+	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH:
+		return 32 << dmacHw_GET_CHANNEL_DATA_WIDTH(pCblk->module,
+							   pCblk->channel);
+	case dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE:
+		return GetFifoSize(handle);
+	}
+	dmacHw_ASSERT(0);
+	return 0;
+}
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c
new file mode 100644
index 0000000..ff7b436
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c
@@ -0,0 +1,1017 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    dmacHw_extra.c
+*
+*  @brief   Extra Low level DMA controller driver routines
+*
+*  @note
+*
+*   These routines provide basic DMA functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/stdint.h>
+#include <stddef.h>
+
+#include <csp/dmacHw.h>
+#include <mach/csp/dmacHw_reg.h>
+#include <mach/csp/dmacHw_priv.h>
+
+extern dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT];	/* Declared in dmacHw.c */
+
+/* ---- External Function Prototypes ------------------------------------- */
+
+/* ---- Internal Use Function Prototypes --------------------------------- */
+/****************************************************************************/
+/**
+*  @brief   Overwrites data length in the descriptor
+*
+*  This function overwrites data length in the descriptor
+*
+*
+*  @return   void
+*
+*  @note
+*          This is only used for PCM channel
+*/
+/****************************************************************************/
+void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+			  void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+			  size_t dataLen	/*   [ IN ] Data length in bytes */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Helper function to display DMA registers
+*
+*  @return  void
+*
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+static void DisplayRegisterContents(int module,	/*   [ IN ] DMA Controller unit  (0-1) */
+				    int channel,	/*   [ IN ] DMA Channel          (0-7) / -1(all) */
+				    int (*fpPrint) (const char *, ...)	/*   [ IN ] Callback to the print function */
+    ) {
+	int chan;
+
+	(*fpPrint) ("Displaying register content \n\n");
+	(*fpPrint) ("Module %d: Interrupt raw transfer              0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_RAW_TRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt raw block                 0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_RAW_BLOCK(module)));
+	(*fpPrint) ("Module %d: Interrupt raw src transfer          0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_RAW_STRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt raw dst transfer          0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_RAW_DTRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt raw error                 0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_RAW_ERROR(module)));
+	(*fpPrint) ("--------------------------------------------------\n");
+	(*fpPrint) ("Module %d: Interrupt stat transfer             0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_STAT_TRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt stat block                0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_STAT_BLOCK(module)));
+	(*fpPrint) ("Module %d: Interrupt stat src transfer         0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_STAT_STRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt stat dst transfer         0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_STAT_DTRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt stat error                0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_STAT_ERROR(module)));
+	(*fpPrint) ("--------------------------------------------------\n");
+	(*fpPrint) ("Module %d: Interrupt mask transfer             0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_MASK_TRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt mask block                0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_MASK_BLOCK(module)));
+	(*fpPrint) ("Module %d: Interrupt mask src transfer         0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_MASK_STRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt mask dst transfer         0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_MASK_DTRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt mask error                0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_MASK_ERROR(module)));
+	(*fpPrint) ("--------------------------------------------------\n");
+	(*fpPrint) ("Module %d: Interrupt clear transfer            0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_TRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt clear block               0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_BLOCK(module)));
+	(*fpPrint) ("Module %d: Interrupt clear src transfer        0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_STRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt clear dst transfer        0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_DTRAN(module)));
+	(*fpPrint) ("Module %d: Interrupt clear error               0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_INT_CLEAR_ERROR(module)));
+	(*fpPrint) ("--------------------------------------------------\n");
+	(*fpPrint) ("Module %d: SW source req                       0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_SW_HS_SRC_REQ(module)));
+	(*fpPrint) ("Module %d: SW dest req                         0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_SW_HS_DST_REQ(module)));
+	(*fpPrint) ("Module %d: SW source signal                    0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_SW_HS_SRC_SGL_REQ(module)));
+	(*fpPrint) ("Module %d: SW dest signal                      0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_SW_HS_DST_SGL_REQ(module)));
+	(*fpPrint) ("Module %d: SW source last                      0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_SW_HS_SRC_LST_REQ(module)));
+	(*fpPrint) ("Module %d: SW dest last                        0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_SW_HS_DST_LST_REQ(module)));
+	(*fpPrint) ("--------------------------------------------------\n");
+	(*fpPrint) ("Module %d: misc config                         0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_MISC_CFG(module)));
+	(*fpPrint) ("Module %d: misc channel enable                 0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_MISC_CH_ENABLE(module)));
+	(*fpPrint) ("Module %d: misc ID                             0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_MISC_ID(module)));
+	(*fpPrint) ("Module %d: misc test                           0x%X\n",
+		    module, (uint32_t) (dmacHw_REG_MISC_TEST(module)));
+
+	if (channel == -1) {
+		for (chan = 0; chan < 8; chan++) {
+			(*fpPrint)
+			    ("--------------------------------------------------\n");
+			(*fpPrint)
+			    ("Module %d: Channel %d Source                   0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_SAR(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Destination              0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_DAR(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d LLP                      0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_LLP(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Control (LO)             0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Control (HI)             0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Source Stats             0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Dest Stats               0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Source Stats Addr        0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Dest Stats Addr          0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Config (LO)              0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
+			(*fpPrint)
+			    ("Module %d: Channel %d Config (HI)              0x%X\n",
+			     module, chan,
+			     (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
+		}
+	} else {
+		chan = channel;
+		(*fpPrint)
+		    ("--------------------------------------------------\n");
+		(*fpPrint)
+		    ("Module %d: Channel %d Source                   0x%X\n",
+		     module, chan, (uint32_t) (dmacHw_REG_SAR(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Destination              0x%X\n",
+		     module, chan, (uint32_t) (dmacHw_REG_DAR(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d LLP                      0x%X\n",
+		     module, chan, (uint32_t) (dmacHw_REG_LLP(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Control (LO)             0x%X\n",
+		     module, chan,
+		     (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Control (HI)             0x%X\n",
+		     module, chan,
+		     (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Source Stats             0x%X\n",
+		     module, chan, (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Dest Stats               0x%X\n",
+		     module, chan, (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Source Stats Addr        0x%X\n",
+		     module, chan,
+		     (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Dest Stats Addr          0x%X\n",
+		     module, chan,
+		     (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Config (LO)              0x%X\n",
+		     module, chan,
+		     (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
+		(*fpPrint)
+		    ("Module %d: Channel %d Config (HI)              0x%X\n",
+		     module, chan,
+		     (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Helper function to display descriptor ring
+*
+*  @return  void
+*
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+static void DisplayDescRing(void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+			    int (*fpPrint) (const char *, ...)	/*   [ IN ] Callback to the print function */
+    ) {
+	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+	dmacHw_DESC_t *pStart;
+
+	if (pRing->pHead == NULL) {
+		return;
+	}
+
+	pStart = pRing->pHead;
+
+	while ((dmacHw_DESC_t *) pStart->llp != pRing->pHead) {
+		if (pStart == pRing->pHead) {
+			(*fpPrint) ("Head\n");
+		}
+		if (pStart == pRing->pTail) {
+			(*fpPrint) ("Tail\n");
+		}
+		if (pStart == pRing->pProg) {
+			(*fpPrint) ("Prog\n");
+		}
+		if (pStart == pRing->pEnd) {
+			(*fpPrint) ("End\n");
+		}
+		if (pStart == pRing->pFree) {
+			(*fpPrint) ("Free\n");
+		}
+		(*fpPrint) ("0x%X:\n", (uint32_t) pStart);
+		(*fpPrint) ("sar    0x%0X\n", pStart->sar);
+		(*fpPrint) ("dar    0x%0X\n", pStart->dar);
+		(*fpPrint) ("llp    0x%0X\n", pStart->llp);
+		(*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo);
+		(*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi);
+		(*fpPrint) ("sstat  0x%0X\n", pStart->sstat);
+		(*fpPrint) ("dstat  0x%0X\n", pStart->dstat);
+		(*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl);
+
+		pStart = (dmacHw_DESC_t *) pStart->llp;
+	}
+	if (pStart == pRing->pHead) {
+		(*fpPrint) ("Head\n");
+	}
+	if (pStart == pRing->pTail) {
+		(*fpPrint) ("Tail\n");
+	}
+	if (pStart == pRing->pProg) {
+		(*fpPrint) ("Prog\n");
+	}
+	if (pStart == pRing->pEnd) {
+		(*fpPrint) ("End\n");
+	}
+	if (pStart == pRing->pFree) {
+		(*fpPrint) ("Free\n");
+	}
+	(*fpPrint) ("0x%X:\n", (uint32_t) pStart);
+	(*fpPrint) ("sar    0x%0X\n", pStart->sar);
+	(*fpPrint) ("dar    0x%0X\n", pStart->dar);
+	(*fpPrint) ("llp    0x%0X\n", pStart->llp);
+	(*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo);
+	(*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi);
+	(*fpPrint) ("sstat  0x%0X\n", pStart->sstat);
+	(*fpPrint) ("dstat  0x%0X\n", pStart->dstat);
+	(*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Check if DMA channel is the flow controller
+*
+*  @return  1 : If DMA is a flow controler
+*           0 : Peripheral is the flow controller
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+static inline int DmaIsFlowController(void *pDescriptor	/*   [ IN ] Descriptor buffer */
+    ) {
+	uint32_t ttfc =
+	    (dmacHw_GET_DESC_RING(pDescriptor))->pTail->ctl.
+	    lo & dmacHw_REG_CTL_TTFC_MASK;
+
+	switch (ttfc) {
+	case dmacHw_REG_CTL_TTFC_MM_DMAC:
+	case dmacHw_REG_CTL_TTFC_MP_DMAC:
+	case dmacHw_REG_CTL_TTFC_PM_DMAC:
+	case dmacHw_REG_CTL_TTFC_PP_DMAC:
+		return 1;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Overwrites data length in the descriptor
+*
+*  This function overwrites data length in the descriptor
+*
+*
+*  @return   void
+*
+*  @note
+*          This is only used for PCM channel
+*/
+/****************************************************************************/
+void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+			  void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+			  size_t dataLen	/*   [ IN ] Data length in bytes */
+    ) {
+	dmacHw_DESC_t *pProg;
+	dmacHw_DESC_t *pHead;
+	int srcTs = 0;
+	int srcTrSize = 0;
+
+	pHead = (dmacHw_GET_DESC_RING(pDescriptor))->pHead;
+	pProg = pHead;
+
+	srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+	srcTs = dataLen / srcTrSize;
+	do {
+		pProg->ctl.hi = srcTs & dmacHw_REG_CTL_BLOCK_TS_MASK;
+		pProg = (dmacHw_DESC_t *) pProg->llp;
+	} while (pProg != pHead);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Clears the interrupt
+*
+*  This function clears the DMA channel specific interrupt
+*
+*
+*  @return   void
+*
+*  @note
+*     Must be called under the context of ISR
+*/
+/****************************************************************************/
+void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle	/* [ IN ] DMA Channel handle */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+	dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
+	dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
+	dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Returns the cause of channel specific DMA interrupt
+*
+*  This function returns the cause of interrupt
+*
+*  @return  Interrupt status, each bit representing a specific type of interrupt
+*
+*  @note
+*     Should be called under the context of ISR
+*/
+/****************************************************************************/
+dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle	/* [ IN ] DMA Channel handle */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+	dmacHw_INTERRUPT_STATUS_e status = dmacHw_INTERRUPT_STATUS_NONE;
+
+	if (dmacHw_REG_INT_STAT_TRAN(pCblk->module) &
+	    ((0x00000001 << pCblk->channel))) {
+		status |= dmacHw_INTERRUPT_STATUS_TRANS;
+	}
+	if (dmacHw_REG_INT_STAT_BLOCK(pCblk->module) &
+	    ((0x00000001 << pCblk->channel))) {
+		status |= dmacHw_INTERRUPT_STATUS_BLOCK;
+	}
+	if (dmacHw_REG_INT_STAT_ERROR(pCblk->module) &
+	    ((0x00000001 << pCblk->channel))) {
+		status |= dmacHw_INTERRUPT_STATUS_ERROR;
+	}
+
+	return status;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Indentifies a DMA channel causing interrupt
+*
+*  This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e
+*
+*  @return  NULL   : No channel causing DMA interrupt
+*           ! NULL : Handle to a channel causing DMA interrupt
+*  @note
+*     dmacHw_clearInterrupt() must be called with a valid handle after calling this function
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getInterruptSource(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < dmaChannelCount_0 + dmaChannelCount_1; i++) {
+		if ((dmacHw_REG_INT_STAT_TRAN(dmacHw_gCblk[i].module) &
+		     ((0x00000001 << dmacHw_gCblk[i].channel)))
+		    || (dmacHw_REG_INT_STAT_BLOCK(dmacHw_gCblk[i].module) &
+			((0x00000001 << dmacHw_gCblk[i].channel)))
+		    || (dmacHw_REG_INT_STAT_ERROR(dmacHw_gCblk[i].module) &
+			((0x00000001 << dmacHw_gCblk[i].channel)))
+		    ) {
+			return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[i]);
+		}
+	}
+	return dmacHw_CBLK_TO_HANDLE(NULL);
+}
+
+/****************************************************************************/
+/**
+*  @brief  Estimates number of descriptor needed to perform certain DMA transfer
+*
+*
+*  @return  On failure : -1
+*           On success : Number of descriptor count
+*
+*
+*/
+/****************************************************************************/
+int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+				    void *pSrcAddr,	/*   [ IN ] Source (Peripheral/Memory) address */
+				    void *pDstAddr,	/*   [ IN ] Destination (Peripheral/Memory) address */
+				    size_t dataLen	/*   [ IN ] Data length in bytes */
+    ) {
+	int srcTs = 0;
+	int oddSize = 0;
+	int descCount = 0;
+	int dstTrSize = 0;
+	int srcTrSize = 0;
+	uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE;
+	dmacHw_TRANSACTION_WIDTH_e dstTrWidth;
+	dmacHw_TRANSACTION_WIDTH_e srcTrWidth;
+
+	dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
+	srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+
+	/* Skip Tx if buffer is NULL  or length is unknown */
+	if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) {
+		/* Do not initiate transfer */
+		return -1;
+	}
+
+	/* Ensure scatter and gather are transaction aligned */
+	if (pConfig->srcGatherWidth % srcTrSize
+	    || pConfig->dstScatterWidth % dstTrSize) {
+		return -1;
+	}
+
+	/*
+	   Background 1: DMAC can not perform DMA if source and destination addresses are
+	   not properly aligned with the channel's transaction width. So, for successful
+	   DMA transfer, transaction width must be set according to the alignment of the
+	   source and destination address.
+	 */
+
+	/* Adjust destination transaction width if destination address is not aligned properly */
+	dstTrWidth = pConfig->dstMaxTransactionWidth;
+	while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) {
+		dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth);
+		dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth);
+	}
+
+	/* Adjust source transaction width if source address is not aligned properly */
+	srcTrWidth = pConfig->srcMaxTransactionWidth;
+	while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) {
+		srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth);
+		srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth);
+	}
+
+	/* Find the maximum transaction per descriptor */
+	if (pConfig->maxDataPerBlock
+	    && ((pConfig->maxDataPerBlock / srcTrSize) <
+		dmacHw_MAX_BLOCKSIZE)) {
+		maxBlockSize = pConfig->maxDataPerBlock / srcTrSize;
+	}
+
+	/* Find number of source transactions needed to complete the DMA transfer */
+	srcTs = dataLen / srcTrSize;
+	/* Find the odd number of bytes that need to be transferred as single byte transaction width */
+	if (srcTs && (dstTrSize > srcTrSize)) {
+		oddSize = dataLen % dstTrSize;
+		/* Adjust source transaction count due to "oddSize" */
+		srcTs = srcTs - (oddSize / srcTrSize);
+	} else {
+		oddSize = dataLen % srcTrSize;
+	}
+	/* Adjust "descCount" due to "oddSize" */
+	if (oddSize) {
+		descCount++;
+	}
+
+	/* Find the number of descriptor needed for total "srcTs" */
+	if (srcTs) {
+		descCount += ((srcTs - 1) / maxBlockSize) + 1;
+	}
+
+	return descCount;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Check the existance of pending descriptor
+*
+*  This function confirmes if there is any pending descriptor in the chain
+*  to program the channel
+*
+*  @return  1 : Channel need to be programmed with pending descriptor
+*           0 : No more pending descriptor to programe the channel
+*
+*  @note
+*     - This function should be called from ISR in case there are pending
+*       descriptor to program the channel.
+*
+*     Example:
+*
+*     dmac_isr ()
+*     {
+*         ...
+*         if (dmacHw_descriptorPending (handle))
+*         {
+*            dmacHw_initiateTransfer (handle);
+*         }
+*     }
+*
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
+				  void *pDescriptor	/*   [ IN ] Descriptor buffer */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+	/* Make sure channel is not busy */
+	if (!CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
+		/* Check if pEnd is not processed */
+		if (pRing->pEnd) {
+			/* Something left for processing */
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Program channel register to stop transfer
+*
+*  Ensures the channel is not doing any transfer after calling this function
+*
+*  @return  void
+*
+*/
+/****************************************************************************/
+void dmacHw_stopTransfer(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle */
+    ) {
+	dmacHw_CBLK_t *pCblk;
+
+	pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+	/* Stop the channel */
+	dmacHw_DMA_STOP(pCblk->module, pCblk->channel);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Deallocates source or destination memory, allocated
+*
+*  This function can be called to deallocate data memory that was DMAed successfully
+*
+*  @return  On failure : -1
+*           On success : Number of buffer freed
+*
+*  @note
+*     This function will be called ONLY, when source OR destination address is pointing
+*     to dynamic memory
+*/
+/****************************************************************************/
+int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+		   void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+		   void (*fpFree) (void *)	/*   [ IN ] Function pointer to free data memory */
+    ) {
+	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+	uint32_t count = 0;
+
+	if (fpFree == NULL) {
+		return -1;
+	}
+
+	while ((pRing->pFree != pRing->pTail)
+	       && (pRing->pFree->ctl.lo & dmacHw_DESC_FREE)) {
+		if (pRing->pFree->devCtl == dmacHw_FREE_USER_MEMORY) {
+			/* Identify, which memory to free */
+			if (dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
+				(*fpFree) ((void *)pRing->pFree->dar);
+			} else {
+				/* Destination was a peripheral */
+				(*fpFree) ((void *)pRing->pFree->sar);
+			}
+			/* Unmark user memory to indicate it is freed */
+			pRing->pFree->devCtl = ~dmacHw_FREE_USER_MEMORY;
+		}
+		dmacHw_NEXT_DESC(pRing, pFree);
+
+		count++;
+	}
+
+	return count;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Prepares descriptor ring, when source peripheral working as a flow controller
+*
+*  This function will update the discriptor ring by allocating buffers, when source peripheral
+*  has to work as a flow controller to transfer data from:
+*           - Peripheral to memory.
+*
+*  @return  On failure : -1
+*           On success : Number of descriptor updated
+*
+*
+*  @note
+*     Channel must be configured for peripheral to memory transfer
+*
+*/
+/****************************************************************************/
+int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
+				     dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+				     void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+				     uint32_t srcAddr,	/*   [ IN ] Source peripheral address */
+				     void *(*fpAlloc) (int len),	/*   [ IN ] Function pointer  that provides destination memory */
+				     int len,	/*   [ IN ] Number of bytes "fpAlloc" will allocate for destination */
+				     int num	/*   [ IN ] Number of descriptor to set */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+	dmacHw_DESC_t *pProg = NULL;
+	dmacHw_DESC_t *pLast = NULL;
+	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+	uint32_t dstAddr;
+	uint32_t controlParam;
+	int i;
+
+	dmacHw_ASSERT(pConfig->transferType ==
+		      dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM);
+
+	if (num > pRing->num) {
+		return -1;
+	}
+
+	pLast = pRing->pEnd;	/* Last descriptor updated */
+	pProg = pRing->pHead;	/* First descriptor in the new list */
+
+	controlParam = pConfig->srcUpdate |
+	    pConfig->dstUpdate |
+	    pConfig->srcMaxTransactionWidth |
+	    pConfig->dstMaxTransactionWidth |
+	    pConfig->srcMasterInterface |
+	    pConfig->dstMasterInterface |
+	    pConfig->srcMaxBurstWidth |
+	    pConfig->dstMaxBurstWidth |
+	    dmacHw_REG_CTL_TTFC_PM_PERI |
+	    dmacHw_REG_CTL_LLP_DST_EN |
+	    dmacHw_REG_CTL_LLP_SRC_EN | dmacHw_REG_CTL_INT_EN;
+
+	for (i = 0; i < num; i++) {
+		/* Allocate Rx buffer only for idle descriptor */
+		if (((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) ||
+		    ((dmacHw_DESC_t *) pRing->pHead->llp == pRing->pTail)
+		    ) {
+			/* Rx descriptor is not idle */
+			break;
+		}
+		/* Set source address */
+		pRing->pHead->sar = srcAddr;
+		if (fpAlloc) {
+			/* Allocate memory for buffer in descriptor */
+			dstAddr = (uint32_t) (*fpAlloc) (len);
+			/* Check the destination address */
+			if (dstAddr == 0) {
+				if (i == 0) {
+					/* Not a single descriptor is available */
+					return -1;
+				}
+				break;
+			}
+			/* Set destination address */
+			pRing->pHead->dar = dstAddr;
+		}
+		/* Set control information */
+		pRing->pHead->ctl.lo = controlParam;
+		/* Use "devCtl" to mark the memory that need to be freed later */
+		pRing->pHead->devCtl = dmacHw_FREE_USER_MEMORY;
+		/* Descriptor is now owned by the channel */
+		pRing->pHead->ctl.hi = 0;
+		/* Remember the descriptor last updated */
+		pRing->pEnd = pRing->pHead;
+		/* Update next descriptor */
+		dmacHw_NEXT_DESC(pRing, pHead);
+	}
+
+	/* Mark the end of the list */
+	pRing->pEnd->ctl.lo &=
+	    ~(dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN);
+	/* Connect the list */
+	if (pLast != pProg) {
+		pLast->ctl.lo |=
+		    dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN;
+	}
+	/* Mark the descriptors are updated */
+	pCblk->descUpdated = 1;
+	if (!pCblk->varDataStarted) {
+		/* LLP must be pointing to the first descriptor */
+		dmacHw_SET_LLP(pCblk->module, pCblk->channel,
+			       (uint32_t) pProg - pRing->virt2PhyOffset);
+		/* Channel, handling variable data started */
+		pCblk->varDataStarted = 1;
+	}
+
+	return i;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Read data DMAed to memory
+*
+*  This function will read data that has been DMAed to memory while transfering from:
+*          - Memory to memory
+*          - Peripheral to memory
+*
+*  @param    handle     -
+*  @param    ppBbuf     -
+*  @param    pLen       -
+*
+*  @return  0 - No more data is available to read
+*           1 - More data might be available to read
+*
+*/
+/****************************************************************************/
+int dmacHw_readTransferredData(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle */
+			       dmacHw_CONFIG_t *pConfig,	/*   [ IN ]  Configuration settings */
+			       void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+			       void **ppBbuf,	/*   [ OUT ] Data received */
+			       size_t *pLlen	/*   [ OUT ] Length of the data received */
+    ) {
+	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+	(void)handle;
+
+	if (pConfig->transferMode != dmacHw_TRANSFER_MODE_CONTINUOUS) {
+		if (((pRing->pTail->ctl.hi & dmacHw_DESC_FREE) == 0) ||
+		    (pRing->pTail == pRing->pHead)
+		    ) {
+			/* No receive data available */
+			*ppBbuf = (char *)NULL;
+			*pLlen = 0;
+
+			return 0;
+		}
+	}
+
+	/* Return read buffer and length */
+	*ppBbuf = (char *)pRing->pTail->dar;
+
+	/* Extract length of the received data */
+	if (DmaIsFlowController(pDescriptor)) {
+		uint32_t srcTrSize = 0;
+
+		switch (pRing->pTail->ctl.lo & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) {
+		case dmacHw_REG_CTL_SRC_TR_WIDTH_8:
+			srcTrSize = 1;
+			break;
+		case dmacHw_REG_CTL_SRC_TR_WIDTH_16:
+			srcTrSize = 2;
+			break;
+		case dmacHw_REG_CTL_SRC_TR_WIDTH_32:
+			srcTrSize = 4;
+			break;
+		case dmacHw_REG_CTL_SRC_TR_WIDTH_64:
+			srcTrSize = 8;
+			break;
+		default:
+			dmacHw_ASSERT(0);
+		}
+		/* Calculate length from the block size */
+		*pLlen =
+		    (pRing->pTail->ctl.hi & dmacHw_REG_CTL_BLOCK_TS_MASK) *
+		    srcTrSize;
+	} else {
+		/* Extract length from the source peripheral */
+		*pLlen = pRing->pTail->sstat;
+	}
+
+	/* Advance tail to next descriptor */
+	dmacHw_NEXT_DESC(pRing, pTail);
+
+	return 1;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set descriptor carrying control information
+*
+*  This function will be used to send specific control information to the device
+*  using the DMA channel
+*
+*
+*  @return  -1 - On failure
+*            0 - On success
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+				void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+				uint32_t ctlAddress,	/*   [ IN ] Address of the device control register */
+				uint32_t control	/*   [ IN ] Device control information */
+    ) {
+	dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+	if (ctlAddress == 0) {
+		return -1;
+	}
+
+	/* Check the availability of descriptors in the ring */
+	if ((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) {
+		return -1;
+	}
+	/* Set control information */
+	pRing->pHead->devCtl = control;
+	/* Set source and destination address */
+	pRing->pHead->sar = (uint32_t) &pRing->pHead->devCtl;
+	pRing->pHead->dar = ctlAddress;
+	/* Set control parameters */
+	if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) {
+		pRing->pHead->ctl.lo = pConfig->transferType |
+		    dmacHw_SRC_ADDRESS_UPDATE_MODE_INC |
+		    dmacHw_DST_ADDRESS_UPDATE_MODE_INC |
+		    dmacHw_SRC_TRANSACTION_WIDTH_32 |
+		    pConfig->dstMaxTransactionWidth |
+		    dmacHw_SRC_BURST_WIDTH_0 |
+		    dmacHw_DST_BURST_WIDTH_0 |
+		    pConfig->srcMasterInterface |
+		    pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
+	} else {
+		uint32_t transferType = 0;
+		switch (pConfig->transferType) {
+		case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+			transferType = dmacHw_REG_CTL_TTFC_PM_PERI;
+			break;
+		case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+			transferType = dmacHw_REG_CTL_TTFC_MP_PERI;
+			break;
+		default:
+			dmacHw_ASSERT(0);
+		}
+		pRing->pHead->ctl.lo = transferType |
+		    dmacHw_SRC_ADDRESS_UPDATE_MODE_INC |
+		    dmacHw_DST_ADDRESS_UPDATE_MODE_INC |
+		    dmacHw_SRC_TRANSACTION_WIDTH_32 |
+		    pConfig->dstMaxTransactionWidth |
+		    dmacHw_SRC_BURST_WIDTH_0 |
+		    dmacHw_DST_BURST_WIDTH_0 |
+		    pConfig->srcMasterInterface |
+		    pConfig->dstMasterInterface |
+		    pConfig->flowControler | dmacHw_REG_CTL_INT_EN;
+	}
+
+	/* Set block transaction size to one 32 bit transaction */
+	pRing->pHead->ctl.hi = dmacHw_REG_CTL_BLOCK_TS_MASK & 1;
+
+	/* Remember the descriptor to initialize the registers */
+	if (pRing->pProg == dmacHw_DESC_INIT) {
+		pRing->pProg = pRing->pHead;
+	}
+	pRing->pEnd = pRing->pHead;
+
+	/* Advance the descriptor */
+	dmacHw_NEXT_DESC(pRing, pHead);
+
+	/* Update Tail pointer if destination is a peripheral */
+	if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
+		pRing->pTail = pRing->pHead;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Sets channel specific user data
+*
+*  This function associates user data to a specif DMA channel
+*
+*/
+/****************************************************************************/
+void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle */
+			       void *userData	/*  [ IN ] User data */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+	pCblk->userData = userData;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Gets channel specific user data
+*
+*  This function returns user data specific to a DMA channel
+*
+*  @return   user data
+*/
+/****************************************************************************/
+void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle	/*  [ IN ] DMA Channel handle */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+	return pCblk->userData;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Resets descriptor control information
+*
+*  @return  void
+*/
+/****************************************************************************/
+void dmacHw_resetDescriptorControl(void *pDescriptor	/*   [ IN ] Descriptor buffer  */
+    ) {
+	int i;
+	dmacHw_DESC_RING_t *pRing;
+	dmacHw_DESC_t *pDesc;
+
+	pRing = dmacHw_GET_DESC_RING(pDescriptor);
+	pDesc = pRing->pHead;
+
+	for (i = 0; i < pRing->num; i++) {
+		/* Mark descriptor is ready to use */
+		pDesc->ctl.hi = dmacHw_DESC_FREE;
+		/* Look into next link list item */
+		pDesc++;
+	}
+	pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead;
+	pRing->pProg = dmacHw_DESC_INIT;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Displays channel specific registers and other control parameters
+*
+*  @return  void
+*
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle */
+			   void *pDescriptor,	/*   [ IN ] Descriptor buffer */
+			   int (*fpPrint) (const char *, ...)	/*  [ IN ] Print callback function */
+    ) {
+	dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+	DisplayRegisterContents(pCblk->module, pCblk->channel, fpPrint);
+	DisplayDescRing(pDescriptor, fpPrint);
+}
diff --git a/arch/arm/mach-bcmring/csp/tmr/Makefile b/arch/arm/mach-bcmring/csp/tmr/Makefile
new file mode 100644
index 0000000..244a61a
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/tmr/Makefile
@@ -0,0 +1 @@
+obj-y += tmrHw.o
diff --git a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c
new file mode 100644
index 0000000..5c1c9a0
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c
@@ -0,0 +1,576 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    tmrHw.c
+*
+*  @brief   Low level Timer driver routines
+*
+*  @note
+*
+*   These routines provide basic timer functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/stdint.h>
+
+#include <csp/tmrHw.h>
+#include <mach/csp/tmrHw_reg.h>
+
+#define tmrHw_ASSERT(a)                     if (!(a)) *(char *)0 = 0
+#define tmrHw_MILLISEC_PER_SEC              (1000)
+
+#define tmrHw_LOW_1_RESOLUTION_COUNT        (tmrHw_LOW_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
+#define tmrHw_LOW_1_MAX_MILLISEC            (0xFFFFFFFF / tmrHw_LOW_1_RESOLUTION_COUNT)
+#define tmrHw_LOW_16_RESOLUTION_COUNT       (tmrHw_LOW_1_RESOLUTION_COUNT / 16)
+#define tmrHw_LOW_16_MAX_MILLISEC           (0xFFFFFFFF / tmrHw_LOW_16_RESOLUTION_COUNT)
+#define tmrHw_LOW_256_RESOLUTION_COUNT      (tmrHw_LOW_1_RESOLUTION_COUNT / 256)
+#define tmrHw_LOW_256_MAX_MILLISEC          (0xFFFFFFFF / tmrHw_LOW_256_RESOLUTION_COUNT)
+
+#define tmrHw_HIGH_1_RESOLUTION_COUNT       (tmrHw_HIGH_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
+#define tmrHw_HIGH_1_MAX_MILLISEC           (0xFFFFFFFF / tmrHw_HIGH_1_RESOLUTION_COUNT)
+#define tmrHw_HIGH_16_RESOLUTION_COUNT      (tmrHw_HIGH_1_RESOLUTION_COUNT / 16)
+#define tmrHw_HIGH_16_MAX_MILLISEC          (0xFFFFFFFF / tmrHw_HIGH_16_RESOLUTION_COUNT)
+#define tmrHw_HIGH_256_RESOLUTION_COUNT     (tmrHw_HIGH_1_RESOLUTION_COUNT / 256)
+#define tmrHw_HIGH_256_MAX_MILLISEC         (0xFFFFFFFF / tmrHw_HIGH_256_RESOLUTION_COUNT)
+
+static void ResetTimer(tmrHw_ID_t timerId)
+    __attribute__ ((section(".aramtext")));
+static int tmrHw_divide(int num, int denom)
+    __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Get timer capability
+*
+*  This function returns various capabilities/attributes of a timer
+*
+*  @return  Capability
+*
+*/
+/****************************************************************************/
+uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+				  tmrHw_CAPABILITY_e capability	/*  [ IN ] Timer capability */
+) {
+	switch (capability) {
+	case tmrHw_CAPABILITY_CLOCK:
+		return (timerId <=
+			1) ? tmrHw_LOW_RESOLUTION_CLOCK :
+		    tmrHw_HIGH_RESOLUTION_CLOCK;
+	case tmrHw_CAPABILITY_RESOLUTION:
+		return 32;
+	default:
+		return 0;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Resets a timer
+*
+*  This function initializes  timer
+*
+*  @return  void
+*
+*/
+/****************************************************************************/
+static void ResetTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer Id */
+) {
+	/* Reset timer */
+	pTmrHw[timerId].LoadValue = 0;
+	pTmrHw[timerId].CurrentValue = 0xFFFFFFFF;
+	pTmrHw[timerId].Control = 0;
+	pTmrHw[timerId].BackgroundLoad = 0;
+	/* Always configure as a 32 bit timer */
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_32BIT;
+	/* Clear interrupt only if raw status interrupt is set */
+	if (pTmrHw[timerId].RawInterruptStatus) {
+		pTmrHw[timerId].InterruptClear = 0xFFFFFFFF;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Sets counter value for an interval in ms
+*
+*  @return   On success: Effective counter value set
+*            On failure: 0
+*
+*/
+/****************************************************************************/
+static tmrHw_INTERVAL_t SetTimerPeriod(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+				       tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in milli-second */
+) {
+	uint32_t scale = 0;
+	uint32_t count = 0;
+
+	if (timerId == 0 || timerId == 1) {
+		if (msec <= tmrHw_LOW_1_MAX_MILLISEC) {
+			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+			scale = tmrHw_LOW_1_RESOLUTION_COUNT;
+		} else if (msec <= tmrHw_LOW_16_MAX_MILLISEC) {
+			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
+			scale = tmrHw_LOW_16_RESOLUTION_COUNT;
+		} else if (msec <= tmrHw_LOW_256_MAX_MILLISEC) {
+			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
+			scale = tmrHw_LOW_256_RESOLUTION_COUNT;
+		} else {
+			return 0;
+		}
+
+		count = msec * scale;
+		/* Set counter value */
+		pTmrHw[timerId].LoadValue = count;
+		pTmrHw[timerId].BackgroundLoad = count;
+
+	} else if (timerId == 2 || timerId == 3) {
+		if (msec <= tmrHw_HIGH_1_MAX_MILLISEC) {
+			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+			scale = tmrHw_HIGH_1_RESOLUTION_COUNT;
+		} else if (msec <= tmrHw_HIGH_16_MAX_MILLISEC) {
+			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
+			scale = tmrHw_HIGH_16_RESOLUTION_COUNT;
+		} else if (msec <= tmrHw_HIGH_256_MAX_MILLISEC) {
+			pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
+			scale = tmrHw_HIGH_256_RESOLUTION_COUNT;
+		} else {
+			return 0;
+		}
+
+		count = msec * scale;
+		/* Set counter value */
+		pTmrHw[timerId].LoadValue = count;
+		pTmrHw[timerId].BackgroundLoad = count;
+	}
+	return count / scale;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Configures a periodic timer in terms of timer interrupt rate
+*
+*  This function initializes a periodic timer to generate specific number of
+*  timer interrupt per second
+*
+*  @return   On success: Effective timer frequency
+*            On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+					tmrHw_RATE_t rate	/*  [ IN ] Number of timer interrupt per second */
+) {
+	uint32_t resolution = 0;
+	uint32_t count = 0;
+	ResetTimer(timerId);
+
+	/* Set timer mode periodic */
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
+	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
+	/* Set timer in highest resolution */
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+
+	if (rate && (timerId == 0 || timerId == 1)) {
+		if (rate > tmrHw_LOW_RESOLUTION_CLOCK) {
+			return 0;
+		}
+		resolution = tmrHw_LOW_RESOLUTION_CLOCK;
+	} else if (rate && (timerId == 2 || timerId == 3)) {
+		if (rate > tmrHw_HIGH_RESOLUTION_CLOCK) {
+			return 0;
+		} else {
+			resolution = tmrHw_HIGH_RESOLUTION_CLOCK;
+		}
+	} else {
+		return 0;
+	}
+	/* Find the counter value */
+	count = resolution / rate;
+	/* Set counter value */
+	pTmrHw[timerId].LoadValue = count;
+	pTmrHw[timerId].BackgroundLoad = count;
+
+	return resolution / count;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Configures a periodic timer to generate timer interrupt after
+*           certain time interval
+*
+*  This function initializes a periodic timer to generate timer interrupt
+*  after every time interval in millisecond
+*
+*  @return   On success: Effective interval set in milli-second
+*            On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+						tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in milli-second */
+) {
+	ResetTimer(timerId);
+
+	/* Set timer mode periodic */
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
+	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
+
+	return SetTimerPeriod(timerId, msec);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Configures a periodic timer to generate timer interrupt just once
+*           after certain time interval
+*
+*  This function initializes a periodic timer to generate a single ticks after
+*  certain time interval in millisecond
+*
+*  @return   On success: Effective interval set in milli-second
+*            On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+					       tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in milli-second */
+) {
+	ResetTimer(timerId);
+
+	/* Set timer mode oneshot */
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_ONESHOT;
+
+	return SetTimerPeriod(timerId, msec);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Configures a timer to run as a free running timer
+*
+*  This function initializes a timer to run as a free running timer
+*
+*  @return   Timer resolution (count / sec)
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+				       uint32_t divider	/*  [ IN ] Dividing the clock frequency */
+) {
+	uint32_t scale = 0;
+
+	ResetTimer(timerId);
+	/* Set timer as free running mode */
+	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_PERIODIC;
+	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
+
+	if (divider >= 64) {
+		pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
+		scale = 256;
+	} else if (divider >= 8) {
+		pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
+		scale = 16;
+	} else {
+		pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+		scale = 1;
+	}
+
+	if (timerId == 0 || timerId == 1) {
+		return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, scale);
+	} else if (timerId == 2 || timerId == 3) {
+		return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, scale);
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Starts a timer
+*
+*  This function starts a preconfigured timer
+*
+*  @return  -1     - On Failure
+*            0     - On Success
+*
+*/
+/****************************************************************************/
+int tmrHw_startTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_TIMER_ENABLE;
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Stops a timer
+*
+*  This function stops a running timer
+*
+*  @return  -1     - On Failure
+*            0     - On Success
+*
+*/
+/****************************************************************************/
+int tmrHw_stopTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_TIMER_ENABLE;
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Gets current timer count
+*
+*  This function returns the current timer value
+*
+*  @return  Current downcounting timer value
+*
+*/
+/****************************************************************************/
+uint32_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	/* return 32 bit timer value */
+	switch (pTmrHw[timerId].Control & tmrHw_CONTROL_MODE_MASK) {
+	case tmrHw_CONTROL_FREE_RUNNING:
+		if (pTmrHw[timerId].CurrentValue) {
+			return tmrHw_MAX_COUNT - pTmrHw[timerId].CurrentValue;
+		}
+		break;
+	case tmrHw_CONTROL_PERIODIC:
+	case tmrHw_CONTROL_ONESHOT:
+		return pTmrHw[timerId].BackgroundLoad -
+		    pTmrHw[timerId].CurrentValue;
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Gets timer count rate
+*
+*  This function returns the number of counts per second
+*
+*  @return  Count rate
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	uint32_t divider = 0;
+
+	switch (pTmrHw[timerId].Control & tmrHw_CONTROL_PRESCALE_MASK) {
+	case tmrHw_CONTROL_PRESCALE_1:
+		divider = 1;
+		break;
+	case tmrHw_CONTROL_PRESCALE_16:
+		divider = 16;
+		break;
+	case tmrHw_CONTROL_PRESCALE_256:
+		divider = 256;
+		break;
+	default:
+		tmrHw_ASSERT(0);
+	}
+
+	if (timerId == 0 || timerId == 1) {
+		return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, divider);
+	} else {
+		return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, divider);
+	}
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enables timer interrupt
+*
+*  This function enables the timer interrupt
+*
+*  @return   N/A
+*
+*/
+/****************************************************************************/
+void tmrHw_enableInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	pTmrHw[timerId].Control |= tmrHw_CONTROL_INTERRUPT_ENABLE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disables timer interrupt
+*
+*  This function disable the timer interrupt
+*
+*  @return   N/A
+*
+*/
+/****************************************************************************/
+void tmrHw_disableInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	pTmrHw[timerId].Control &= ~tmrHw_CONTROL_INTERRUPT_ENABLE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Clears the interrupt
+*
+*  This function clears the timer interrupt
+*
+*  @return   N/A
+*
+*  @note
+*     Must be called under the context of ISR
+*/
+/****************************************************************************/
+void tmrHw_clearInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	pTmrHw[timerId].InterruptClear = 0x1;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Gets the interrupt status
+*
+*  This function returns timer interrupt status
+*
+*  @return   Interrupt status
+*/
+/****************************************************************************/
+tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) {
+	if (pTmrHw[timerId].InterruptStatus) {
+		return tmrHw_INTERRUPT_STATUS_SET;
+	} else {
+		return tmrHw_INTERRUPT_STATUS_UNSET;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Indentifies a timer causing interrupt
+*
+*  This functions returns a timer causing interrupt
+*
+*  @return  0xFFFFFFFF   : No timer causing an interrupt
+*           ! 0xFFFFFFFF : timer causing an interrupt
+*  @note
+*     tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function
+*/
+/****************************************************************************/
+tmrHw_ID_t tmrHw_getInterruptSource(void	/*  void */
+) {
+	int i;
+
+	for (i = 0; i < tmrHw_TIMER_NUM_COUNT; i++) {
+		if (pTmrHw[i].InterruptStatus) {
+			return i;
+		}
+	}
+
+	return 0xFFFFFFFF;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Displays specific timer registers
+*
+*
+*  @return  void
+*
+*/
+/****************************************************************************/
+void tmrHw_printDebugInfo(tmrHw_ID_t timerId,	/*  [ IN ] Timer id */
+			  int (*fpPrint) (const char *, ...)	/*  [ IN ] Print callback function */
+) {
+	(*fpPrint) ("Displaying register contents \n\n");
+	(*fpPrint) ("Timer %d: Load value              0x%X\n", timerId,
+		    pTmrHw[timerId].LoadValue);
+	(*fpPrint) ("Timer %d: Background load value   0x%X\n", timerId,
+		    pTmrHw[timerId].BackgroundLoad);
+	(*fpPrint) ("Timer %d: Control                 0x%X\n", timerId,
+		    pTmrHw[timerId].Control);
+	(*fpPrint) ("Timer %d: Interrupt clear         0x%X\n", timerId,
+		    pTmrHw[timerId].InterruptClear);
+	(*fpPrint) ("Timer %d: Interrupt raw interrupt 0x%X\n", timerId,
+		    pTmrHw[timerId].RawInterruptStatus);
+	(*fpPrint) ("Timer %d: Interrupt status        0x%X\n", timerId,
+		    pTmrHw[timerId].InterruptStatus);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Use a timer to perform a busy wait delay for a number of usecs.
+*
+*  @return   N/A
+*/
+/****************************************************************************/
+void tmrHw_udelay(tmrHw_ID_t timerId,	/*  [ IN ] Timer id */
+		  unsigned long usecs /*  [ IN ] usec to delay */
+) {
+	tmrHw_RATE_t usec_tick_rate;
+	tmrHw_COUNT_t start_time;
+	tmrHw_COUNT_t delta_time;
+
+	start_time = tmrHw_GetCurrentCount(timerId);
+	usec_tick_rate = tmrHw_divide(tmrHw_getCountRate(timerId), 1000000);
+	delta_time = usecs * usec_tick_rate;
+
+	/* Busy wait */
+	while (delta_time > (tmrHw_GetCurrentCount(timerId) - start_time))
+		;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Local Divide function
+*
+*  This function does the divide
+*
+*  @return divide value
+*
+*/
+/****************************************************************************/
+static int tmrHw_divide(int num, int denom)
+{
+	int r;
+	int t = 1;
+
+	/* Shift denom and t up to the largest value to optimize algorithm */
+	/* t contains the units of each divide */
+	while ((denom & 0x40000000) == 0) {	/* fails if denom=0 */
+		denom = denom << 1;
+		t = t << 1;
+	}
+
+	/* Intialize the result */
+	r = 0;
+
+	do {
+		/* Determine if there exists a positive remainder */
+		if ((num - denom) >= 0) {
+			/* Accumlate t to the result and calculate a new remainder */
+			num = num - denom;
+			r = r + t;
+		}
+		/* Continue to shift denom and shift t down to 0 */
+		denom = denom >> 1;
+		t = t >> 1;
+	} while (t != 0);
+	return r;
+}
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c
new file mode 100644
index 0000000..7b20fcc
--- /dev/null
+++ b/arch/arm/mach-bcmring/dma.c
@@ -0,0 +1,2321 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*   @file   dma.c
+*
+*   @brief  Implements the DMA interface.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/proc_fs.h>
+
+#include <mach/timer.h>
+
+#include <linux/mm.h>
+#include <linux/pfn.h>
+#include <asm/atomic.h>
+#include <mach/dma.h>
+
+/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
+/* especially since dc4 doesn't use kmalloc'd memory. */
+
+#define ALLOW_MAP_OF_KMALLOC_MEMORY 0
+
+/* ---- Public Variables ------------------------------------------------- */
+
+/* ---- Private Constants and Types -------------------------------------- */
+
+#define MAKE_HANDLE(controllerIdx, channelIdx)    (((controllerIdx) << 4) | (channelIdx))
+
+#define CONTROLLER_FROM_HANDLE(handle)    (((handle) >> 4) & 0x0f)
+#define CHANNEL_FROM_HANDLE(handle)       ((handle) & 0x0f)
+
+#define DMA_MAP_DEBUG   0
+
+#if DMA_MAP_DEBUG
+#   define  DMA_MAP_PRINT(fmt, args...)   printk("%s: " fmt, __func__,  ## args)
+#else
+#   define  DMA_MAP_PRINT(fmt, args...)
+#endif
+
+/* ---- Private Variables ------------------------------------------------ */
+
+static DMA_Global_t gDMA;
+static struct proc_dir_entry *gDmaDir;
+
+static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0);
+static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0);
+static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0);
+static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0);
+
+#include "dma_device.c"
+
+/* ---- Private Function Prototypes -------------------------------------- */
+
+/* ---- Functions  ------------------------------------------------------- */
+
+/****************************************************************************/
+/**
+*   Displays information for /proc/dma/mem-type
+*/
+/****************************************************************************/
+
+static int dma_proc_read_mem_type(char *buf, char **start, off_t offset,
+				  int count, int *eof, void *data)
+{
+	int len = 0;
+
+	len += sprintf(buf + len, "dma_map_mem statistics\n");
+	len +=
+	    sprintf(buf + len, "coherent: %d\n",
+		    atomic_read(&gDmaStatMemTypeCoherent));
+	len +=
+	    sprintf(buf + len, "kmalloc:  %d\n",
+		    atomic_read(&gDmaStatMemTypeKmalloc));
+	len +=
+	    sprintf(buf + len, "vmalloc:  %d\n",
+		    atomic_read(&gDmaStatMemTypeVmalloc));
+	len +=
+	    sprintf(buf + len, "user:     %d\n",
+		    atomic_read(&gDmaStatMemTypeUser));
+
+	return len;
+}
+
+/****************************************************************************/
+/**
+*   Displays information for /proc/dma/channels
+*/
+/****************************************************************************/
+
+static int dma_proc_read_channels(char *buf, char **start, off_t offset,
+				  int count, int *eof, void *data)
+{
+	int controllerIdx;
+	int channelIdx;
+	int limit = count - 200;
+	int len = 0;
+	DMA_Channel_t *channel;
+
+	if (down_interruptible(&gDMA.lock) < 0) {
+		return -ERESTARTSYS;
+	}
+
+	for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
+	     controllerIdx++) {
+		for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
+		     channelIdx++) {
+			if (len >= limit) {
+				break;
+			}
+
+			channel =
+			    &gDMA.controller[controllerIdx].channel[channelIdx];
+
+			len +=
+			    sprintf(buf + len, "%d:%d ", controllerIdx,
+				    channelIdx);
+
+			if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
+			    0) {
+				len +=
+				    sprintf(buf + len, "Dedicated for %s ",
+					    DMA_gDeviceAttribute[channel->
+								 devType].name);
+			} else {
+				len += sprintf(buf + len, "Shared ");
+			}
+
+			if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) != 0) {
+				len += sprintf(buf + len, "No ISR ");
+			}
+
+			if ((channel->flags & DMA_CHANNEL_FLAG_LARGE_FIFO) != 0) {
+				len += sprintf(buf + len, "Fifo: 128 ");
+			} else {
+				len += sprintf(buf + len, "Fifo: 64  ");
+			}
+
+			if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
+				len +=
+				    sprintf(buf + len, "InUse by %s",
+					    DMA_gDeviceAttribute[channel->
+								 devType].name);
+#if (DMA_DEBUG_TRACK_RESERVATION)
+				len +=
+				    sprintf(buf + len, " (%s:%d)",
+					    channel->fileName,
+					    channel->lineNum);
+#endif
+			} else {
+				len += sprintf(buf + len, "Avail ");
+			}
+
+			if (channel->lastDevType != DMA_DEVICE_NONE) {
+				len +=
+				    sprintf(buf + len, "Last use: %s ",
+					    DMA_gDeviceAttribute[channel->
+								 lastDevType].
+					    name);
+			}
+
+			len += sprintf(buf + len, "\n");
+		}
+	}
+	up(&gDMA.lock);
+	*eof = 1;
+
+	return len;
+}
+
+/****************************************************************************/
+/**
+*   Displays information for /proc/dma/devices
+*/
+/****************************************************************************/
+
+static int dma_proc_read_devices(char *buf, char **start, off_t offset,
+				 int count, int *eof, void *data)
+{
+	int limit = count - 200;
+	int len = 0;
+	int devIdx;
+
+	if (down_interruptible(&gDMA.lock) < 0) {
+		return -ERESTARTSYS;
+	}
+
+	for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
+		DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
+
+		if (devAttr->name == NULL) {
+			continue;
+		}
+
+		if (len >= limit) {
+			break;
+		}
+
+		len += sprintf(buf + len, "%-12s ", devAttr->name);
+
+		if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
+			len +=
+			    sprintf(buf + len, "Dedicated %d:%d ",
+				    devAttr->dedicatedController,
+				    devAttr->dedicatedChannel);
+		} else {
+			len += sprintf(buf + len, "Shared DMA:");
+			if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA0) != 0) {
+				len += sprintf(buf + len, "0");
+			}
+			if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA1) != 0) {
+				len += sprintf(buf + len, "1");
+			}
+			len += sprintf(buf + len, " ");
+		}
+		if ((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0) {
+			len += sprintf(buf + len, "NoISR ");
+		}
+		if ((devAttr->flags & DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO) != 0) {
+			len += sprintf(buf + len, "Allow-128 ");
+		}
+
+		len +=
+		    sprintf(buf + len,
+			    "Xfer #: %Lu Ticks: %Lu Bytes: %Lu DescLen: %u\n",
+			    devAttr->numTransfers, devAttr->transferTicks,
+			    devAttr->transferBytes,
+			    devAttr->ring.bytesAllocated);
+
+	}
+
+	up(&gDMA.lock);
+	*eof = 1;
+
+	return len;
+}
+
+/****************************************************************************/
+/**
+*   Determines if a DMA_Device_t is "valid".
+*
+*   @return
+*       TRUE        - dma device is valid
+*       FALSE       - dma device isn't valid
+*/
+/****************************************************************************/
+
+static inline int IsDeviceValid(DMA_Device_t device)
+{
+	return (device >= 0) && (device < DMA_NUM_DEVICE_ENTRIES);
+}
+
+/****************************************************************************/
+/**
+*   Translates a DMA handle into a pointer to a channel.
+*
+*   @return
+*       non-NULL    - pointer to DMA_Channel_t
+*       NULL        - DMA Handle was invalid
+*/
+/****************************************************************************/
+
+static inline DMA_Channel_t *HandleToChannel(DMA_Handle_t handle)
+{
+	int controllerIdx;
+	int channelIdx;
+
+	controllerIdx = CONTROLLER_FROM_HANDLE(handle);
+	channelIdx = CHANNEL_FROM_HANDLE(handle);
+
+	if ((controllerIdx > DMA_NUM_CONTROLLERS)
+	    || (channelIdx > DMA_NUM_CHANNELS)) {
+		return NULL;
+	}
+	return &gDMA.controller[controllerIdx].channel[channelIdx];
+}
+
+/****************************************************************************/
+/**
+*   Interrupt handler which is called to process DMA interrupts.
+*/
+/****************************************************************************/
+
+static irqreturn_t dma_interrupt_handler(int irq, void *dev_id)
+{
+	DMA_Channel_t *channel;
+	DMA_DeviceAttribute_t *devAttr;
+	int irqStatus;
+
+	channel = (DMA_Channel_t *) dev_id;
+
+	/* Figure out why we were called, and knock down the interrupt */
+
+	irqStatus = dmacHw_getInterruptStatus(channel->dmacHwHandle);
+	dmacHw_clearInterrupt(channel->dmacHwHandle);
+
+	if ((channel->devType < 0)
+	    || (channel->devType > DMA_NUM_DEVICE_ENTRIES)) {
+		printk(KERN_ERR "dma_interrupt_handler: Invalid devType: %d\n",
+		       channel->devType);
+		return IRQ_NONE;
+	}
+	devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+	/* Update stats */
+
+	if ((irqStatus & dmacHw_INTERRUPT_STATUS_TRANS) != 0) {
+		devAttr->transferTicks +=
+		    (timer_get_tick_count() - devAttr->transferStartTime);
+	}
+
+	if ((irqStatus & dmacHw_INTERRUPT_STATUS_ERROR) != 0) {
+		printk(KERN_ERR
+		       "dma_interrupt_handler: devType :%d DMA error (%s)\n",
+		       channel->devType, devAttr->name);
+	} else {
+		devAttr->numTransfers++;
+		devAttr->transferBytes += devAttr->numBytes;
+	}
+
+	/* Call any installed handler */
+
+	if (devAttr->devHandler != NULL) {
+		devAttr->devHandler(channel->devType, irqStatus,
+				    devAttr->userData);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/****************************************************************************/
+/**
+*   Allocates memory to hold a descriptor ring. The descriptor ring then
+*   needs to be populated by making one or more calls to
+*   dna_add_descriptors.
+*
+*   The returned descriptor ring will be automatically initialized.
+*
+*   @return
+*       0           Descriptor ring was allocated successfully
+*       -EINVAL     Invalid parameters passed in
+*       -ENOMEM     Unable to allocate memory for the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring,	/* Descriptor ring to populate */
+			      int numDescriptors	/* Number of descriptors that need to be allocated. */
+    ) {
+	size_t bytesToAlloc = dmacHw_descriptorLen(numDescriptors);
+
+	if ((ring == NULL) || (numDescriptors <= 0)) {
+		return -EINVAL;
+	}
+
+	ring->physAddr = 0;
+	ring->descriptorsAllocated = 0;
+	ring->bytesAllocated = 0;
+
+	ring->virtAddr = dma_alloc_writecombine(NULL,
+						     bytesToAlloc,
+						     &ring->physAddr,
+						     GFP_KERNEL);
+	if (ring->virtAddr == NULL) {
+		return -ENOMEM;
+	}
+
+	ring->bytesAllocated = bytesToAlloc;
+	ring->descriptorsAllocated = numDescriptors;
+
+	return dma_init_descriptor_ring(ring, numDescriptors);
+}
+
+EXPORT_SYMBOL(dma_alloc_descriptor_ring);
+
+/****************************************************************************/
+/**
+*   Releases the memory which was previously allocated for a descriptor ring.
+*/
+/****************************************************************************/
+
+void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring	/* Descriptor to release */
+    ) {
+	if (ring->virtAddr != NULL) {
+		dma_free_writecombine(NULL,
+				      ring->bytesAllocated,
+				      ring->virtAddr, ring->physAddr);
+	}
+
+	ring->bytesAllocated = 0;
+	ring->descriptorsAllocated = 0;
+	ring->virtAddr = NULL;
+	ring->physAddr = 0;
+}
+
+EXPORT_SYMBOL(dma_free_descriptor_ring);
+
+/****************************************************************************/
+/**
+*   Initializes a descriptor ring, so that descriptors can be added to it.
+*   Once a descriptor ring has been allocated, it may be reinitialized for
+*   use with additional/different regions of memory.
+*
+*   Note that if 7 descriptors are allocated, it's perfectly acceptable to
+*   initialize the ring with a smaller number of descriptors. The amount
+*   of memory allocated for the descriptor ring will not be reduced, and
+*   the descriptor ring may be reinitialized later
+*
+*   @return
+*       0           Descriptor ring was initialized successfully
+*       -ENOMEM     The descriptor which was passed in has insufficient space
+*                   to hold the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring,	/* Descriptor ring to initialize */
+			     int numDescriptors	/* Number of descriptors to initialize. */
+    ) {
+	if (ring->virtAddr == NULL) {
+		return -EINVAL;
+	}
+	if (dmacHw_initDescriptor(ring->virtAddr,
+				  ring->physAddr,
+				  ring->bytesAllocated, numDescriptors) < 0) {
+		printk(KERN_ERR
+		       "dma_init_descriptor_ring: dmacHw_initDescriptor failed\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_init_descriptor_ring);
+
+/****************************************************************************/
+/**
+*   Determines the number of descriptors which would be required for a
+*   transfer of the indicated memory region.
+*
+*   This function also needs to know which DMA device this transfer will
+*   be destined for, so that the appropriate DMA configuration can be retrieved.
+*   DMA parameters such as transfer width, and whether this is a memory-to-memory
+*   or memory-to-peripheral, etc can all affect the actual number of descriptors
+*   required.
+*
+*   @return
+*       > 0     Returns the number of descriptors required for the indicated transfer
+*       -ENODEV - Device handed in is invalid.
+*       -EINVAL Invalid parameters
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_calculate_descriptor_count(DMA_Device_t device,	/* DMA Device that this will be associated with */
+				   dma_addr_t srcData,	/* Place to get data to write to device */
+				   dma_addr_t dstData,	/* Pointer to device data address */
+				   size_t numBytes	/* Number of bytes to transfer to the device */
+    ) {
+	int numDescriptors;
+	DMA_DeviceAttribute_t *devAttr;
+
+	if (!IsDeviceValid(device)) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[device];
+
+	numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
+							      (void *)srcData,
+							      (void *)dstData,
+							      numBytes);
+	if (numDescriptors < 0) {
+		printk(KERN_ERR
+		       "dma_calculate_descriptor_count: dmacHw_calculateDescriptorCount failed\n");
+		return -EINVAL;
+	}
+
+	return numDescriptors;
+}
+
+EXPORT_SYMBOL(dma_calculate_descriptor_count);
+
+/****************************************************************************/
+/**
+*   Adds a region of memory to the descriptor ring. Note that it may take
+*   multiple descriptors for each region of memory. It is the callers
+*   responsibility to allocate a sufficiently large descriptor ring.
+*
+*   @return
+*       0       Descriptors were added successfully
+*       -ENODEV Device handed in is invalid.
+*       -EINVAL Invalid parameters
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_add_descriptors(DMA_DescriptorRing_t *ring,	/* Descriptor ring to add descriptors to */
+			DMA_Device_t device,	/* DMA Device that descriptors are for */
+			dma_addr_t srcData,	/* Place to get data (memory or device) */
+			dma_addr_t dstData,	/* Place to put data (memory or device) */
+			size_t numBytes	/* Number of bytes to transfer to the device */
+    ) {
+	int rc;
+	DMA_DeviceAttribute_t *devAttr;
+
+	if (!IsDeviceValid(device)) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[device];
+
+	rc = dmacHw_setDataDescriptor(&devAttr->config,
+				      ring->virtAddr,
+				      (void *)srcData,
+				      (void *)dstData, numBytes);
+	if (rc < 0) {
+		printk(KERN_ERR
+		       "dma_add_descriptors: dmacHw_setDataDescriptor failed with code: %d\n",
+		       rc);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_add_descriptors);
+
+/****************************************************************************/
+/**
+*   Sets the descriptor ring associated with a device.
+*
+*   Once set, the descriptor ring will be associated with the device, even
+*   across channel request/free calls. Passing in a NULL descriptor ring
+*   will release any descriptor ring currently associated with the device.
+*
+*   Note: If you call dma_transfer, or one of the other dma_alloc_ functions
+*         the descriptor ring may be released and reallocated.
+*
+*   Note: This function will release the descriptor memory for any current
+*         descriptor ring associated with this device.
+*
+*   @return
+*       0       Descriptors were added successfully
+*       -ENODEV Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_set_device_descriptor_ring(DMA_Device_t device,	/* Device to update the descriptor ring for. */
+				   DMA_DescriptorRing_t *ring	/* Descriptor ring to add descriptors to */
+    ) {
+	DMA_DeviceAttribute_t *devAttr;
+
+	if (!IsDeviceValid(device)) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[device];
+
+	/* Free the previously allocated descriptor ring */
+
+	dma_free_descriptor_ring(&devAttr->ring);
+
+	if (ring != NULL) {
+		/* Copy in the new one */
+
+		devAttr->ring = *ring;
+	}
+
+	/* Set things up so that if dma_transfer is called then this descriptor */
+	/* ring will get freed. */
+
+	devAttr->prevSrcData = 0;
+	devAttr->prevDstData = 0;
+	devAttr->prevNumBytes = 0;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_set_device_descriptor_ring);
+
+/****************************************************************************/
+/**
+*   Retrieves the descriptor ring associated with a device.
+*
+*   @return
+*       0       Descriptors were added successfully
+*       -ENODEV Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_get_device_descriptor_ring(DMA_Device_t device,	/* Device to retrieve the descriptor ring for. */
+				   DMA_DescriptorRing_t *ring	/* Place to store retrieved ring */
+    ) {
+	DMA_DeviceAttribute_t *devAttr;
+
+	memset(ring, 0, sizeof(*ring));
+
+	if (!IsDeviceValid(device)) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[device];
+
+	*ring = devAttr->ring;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_get_device_descriptor_ring);
+
+/****************************************************************************/
+/**
+*   Configures a DMA channel.
+*
+*   @return
+*       >= 0    - Initialization was successfull.
+*
+*       -EBUSY  - Device is currently being used.
+*       -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+static int ConfigChannel(DMA_Handle_t handle)
+{
+	DMA_Channel_t *channel;
+	DMA_DeviceAttribute_t *devAttr;
+	int controllerIdx;
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[channel->devType];
+	controllerIdx = CONTROLLER_FROM_HANDLE(handle);
+
+	if ((devAttr->flags & DMA_DEVICE_FLAG_PORT_PER_DMAC) != 0) {
+		if (devAttr->config.transferType ==
+		    dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL) {
+			devAttr->config.dstPeripheralPort =
+			    devAttr->dmacPort[controllerIdx];
+		} else if (devAttr->config.transferType ==
+			   dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) {
+			devAttr->config.srcPeripheralPort =
+			    devAttr->dmacPort[controllerIdx];
+		}
+	}
+
+	if (dmacHw_configChannel(channel->dmacHwHandle, &devAttr->config) != 0) {
+		printk(KERN_ERR "ConfigChannel: dmacHw_configChannel failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*   Intializes all of the data structures associated with the DMA.
+*   @return
+*       >= 0    - Initialization was successfull.
+*
+*       -EBUSY  - Device is currently being used.
+*       -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_init(void)
+{
+	int rc = 0;
+	int controllerIdx;
+	int channelIdx;
+	DMA_Device_t devIdx;
+	DMA_Channel_t *channel;
+	DMA_Handle_t dedicatedHandle;
+
+	memset(&gDMA, 0, sizeof(gDMA));
+
+	init_MUTEX_LOCKED(&gDMA.lock);
+	init_waitqueue_head(&gDMA.freeChannelQ);
+
+	/* Initialize the Hardware */
+
+	dmacHw_initDma();
+
+	/* Start off by marking all of the DMA channels as shared. */
+
+	for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
+	     controllerIdx++) {
+		for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
+		     channelIdx++) {
+			channel =
+			    &gDMA.controller[controllerIdx].channel[channelIdx];
+
+			channel->flags = 0;
+			channel->devType = DMA_DEVICE_NONE;
+			channel->lastDevType = DMA_DEVICE_NONE;
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+			channel->fileName = "";
+			channel->lineNum = 0;
+#endif
+
+			channel->dmacHwHandle =
+			    dmacHw_getChannelHandle(dmacHw_MAKE_CHANNEL_ID
+						    (controllerIdx,
+						     channelIdx));
+			dmacHw_initChannel(channel->dmacHwHandle);
+		}
+	}
+
+	/* Record any special attributes that channels may have */
+
+	gDMA.controller[0].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+	gDMA.controller[0].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+	gDMA.controller[1].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+	gDMA.controller[1].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+
+	/* Now walk through and record the dedicated channels. */
+
+	for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
+		DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
+
+		if (((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0)
+		    && ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0)) {
+			printk(KERN_ERR
+			       "DMA Device: %s Can only request NO_ISR for dedicated devices\n",
+			       devAttr->name);
+			rc = -EINVAL;
+			goto out;
+		}
+
+		if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
+			/* This is a dedicated device. Mark the channel as being reserved. */
+
+			if (devAttr->dedicatedController >= DMA_NUM_CONTROLLERS) {
+				printk(KERN_ERR
+				       "DMA Device: %s DMA Controller %d is out of range\n",
+				       devAttr->name,
+				       devAttr->dedicatedController);
+				rc = -EINVAL;
+				goto out;
+			}
+
+			if (devAttr->dedicatedChannel >= DMA_NUM_CHANNELS) {
+				printk(KERN_ERR
+				       "DMA Device: %s DMA Channel %d is out of range\n",
+				       devAttr->name,
+				       devAttr->dedicatedChannel);
+				rc = -EINVAL;
+				goto out;
+			}
+
+			dedicatedHandle =
+			    MAKE_HANDLE(devAttr->dedicatedController,
+					devAttr->dedicatedChannel);
+			channel = HandleToChannel(dedicatedHandle);
+
+			if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
+			    0) {
+				printk
+				    ("DMA Device: %s attempting to use same DMA Controller:Channel (%d:%d) as %s\n",
+				     devAttr->name,
+				     devAttr->dedicatedController,
+				     devAttr->dedicatedChannel,
+				     DMA_gDeviceAttribute[channel->devType].
+				     name);
+				rc = -EBUSY;
+				goto out;
+			}
+
+			channel->flags |= DMA_CHANNEL_FLAG_IS_DEDICATED;
+			channel->devType = devIdx;
+
+			if (devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) {
+				channel->flags |= DMA_CHANNEL_FLAG_NO_ISR;
+			}
+
+			/* For dedicated channels, we can go ahead and configure the DMA channel now */
+			/* as well. */
+
+			ConfigChannel(dedicatedHandle);
+		}
+	}
+
+	/* Go through and register the interrupt handlers */
+
+	for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
+	     controllerIdx++) {
+		for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
+		     channelIdx++) {
+			channel =
+			    &gDMA.controller[controllerIdx].channel[channelIdx];
+
+			if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) == 0) {
+				snprintf(channel->name, sizeof(channel->name),
+					 "dma %d:%d %s", controllerIdx,
+					 channelIdx,
+					 channel->devType ==
+					 DMA_DEVICE_NONE ? "" :
+					 DMA_gDeviceAttribute[channel->devType].
+					 name);
+
+				rc =
+				     request_irq(IRQ_DMA0C0 +
+						 (controllerIdx *
+						  DMA_NUM_CHANNELS) +
+						 channelIdx,
+						 dma_interrupt_handler,
+						 IRQF_DISABLED, channel->name,
+						 channel);
+				if (rc != 0) {
+					printk(KERN_ERR
+					       "request_irq for IRQ_DMA%dC%d failed\n",
+					       controllerIdx, channelIdx);
+				}
+			}
+		}
+	}
+
+	/* Create /proc/dma/channels and /proc/dma/devices */
+
+	gDmaDir = create_proc_entry("dma", S_IFDIR | S_IRUGO | S_IXUGO, NULL);
+
+	if (gDmaDir == NULL) {
+		printk(KERN_ERR "Unable to create /proc/dma\n");
+	} else {
+		create_proc_read_entry("channels", 0, gDmaDir,
+				       dma_proc_read_channels, NULL);
+		create_proc_read_entry("devices", 0, gDmaDir,
+				       dma_proc_read_devices, NULL);
+		create_proc_read_entry("mem-type", 0, gDmaDir,
+				       dma_proc_read_mem_type, NULL);
+	}
+
+out:
+
+	up(&gDMA.lock);
+
+	return rc;
+}
+
+/****************************************************************************/
+/**
+*   Reserves a channel for use with @a dev. If the device is setup to use
+*   a shared channel, then this function will block until a free channel
+*   becomes available.
+*
+*   @return
+*       >= 0    - A valid DMA Handle.
+*       -EBUSY  - Device is currently being used.
+*       -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+DMA_Handle_t dma_request_channel_dbg
+    (DMA_Device_t dev, const char *fileName, int lineNum)
+#else
+DMA_Handle_t dma_request_channel(DMA_Device_t dev)
+#endif
+{
+	DMA_Handle_t handle;
+	DMA_DeviceAttribute_t *devAttr;
+	DMA_Channel_t *channel;
+	int controllerIdx;
+	int controllerIdx2;
+	int channelIdx;
+
+	if (down_interruptible(&gDMA.lock) < 0) {
+		return -ERESTARTSYS;
+	}
+
+	if ((dev < 0) || (dev >= DMA_NUM_DEVICE_ENTRIES)) {
+		handle = -ENODEV;
+		goto out;
+	}
+	devAttr = &DMA_gDeviceAttribute[dev];
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+	{
+		char *s;
+
+		s = strrchr(fileName, '/');
+		if (s != NULL) {
+			fileName = s + 1;
+		}
+	}
+#endif
+	if ((devAttr->flags & DMA_DEVICE_FLAG_IN_USE) != 0) {
+		/* This device has already been requested and not been freed */
+
+		printk(KERN_ERR "%s: device %s is already requested\n",
+		       __func__, devAttr->name);
+		handle = -EBUSY;
+		goto out;
+	}
+
+	if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
+		/* This device has a dedicated channel. */
+
+		channel =
+		    &gDMA.controller[devAttr->dedicatedController].
+		    channel[devAttr->dedicatedChannel];
+		if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
+			handle = -EBUSY;
+			goto out;
+		}
+
+		channel->flags |= DMA_CHANNEL_FLAG_IN_USE;
+		devAttr->flags |= DMA_DEVICE_FLAG_IN_USE;
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+		channel->fileName = fileName;
+		channel->lineNum = lineNum;
+#endif
+		handle =
+		    MAKE_HANDLE(devAttr->dedicatedController,
+				devAttr->dedicatedChannel);
+		goto out;
+	}
+
+	/* This device needs to use one of the shared channels. */
+
+	handle = DMA_INVALID_HANDLE;
+	while (handle == DMA_INVALID_HANDLE) {
+		/* Scan through the shared channels and see if one is available */
+
+		for (controllerIdx2 = 0; controllerIdx2 < DMA_NUM_CONTROLLERS;
+		     controllerIdx2++) {
+			/* Check to see if we should try on controller 1 first. */
+
+			controllerIdx = controllerIdx2;
+			if ((devAttr->
+			     flags & DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST) != 0) {
+				controllerIdx = 1 - controllerIdx;
+			}
+
+			/* See if the device is available on the controller being tested */
+
+			if ((devAttr->
+			     flags & (DMA_DEVICE_FLAG_ON_DMA0 << controllerIdx))
+			    != 0) {
+				for (channelIdx = 0;
+				     channelIdx < DMA_NUM_CHANNELS;
+				     channelIdx++) {
+					channel =
+					    &gDMA.controller[controllerIdx].
+					    channel[channelIdx];
+
+					if (((channel->
+					      flags &
+					      DMA_CHANNEL_FLAG_IS_DEDICATED) ==
+					     0)
+					    &&
+					    ((channel->
+					      flags & DMA_CHANNEL_FLAG_IN_USE)
+					     == 0)) {
+						if (((channel->
+						      flags &
+						      DMA_CHANNEL_FLAG_LARGE_FIFO)
+						     != 0)
+						    &&
+						    ((devAttr->
+						      flags &
+						      DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO)
+						     == 0)) {
+							/* This channel is a large fifo - don't tie it up */
+							/* with devices that we don't want using it. */
+
+							continue;
+						}
+
+						channel->flags |=
+						    DMA_CHANNEL_FLAG_IN_USE;
+						channel->devType = dev;
+						devAttr->flags |=
+						    DMA_DEVICE_FLAG_IN_USE;
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+						channel->fileName = fileName;
+						channel->lineNum = lineNum;
+#endif
+						handle =
+						    MAKE_HANDLE(controllerIdx,
+								channelIdx);
+
+						/* Now that we've reserved the channel - we can go ahead and configure it */
+
+						if (ConfigChannel(handle) != 0) {
+							handle = -EIO;
+							printk(KERN_ERR
+							       "dma_request_channel: ConfigChannel failed\n");
+						}
+						goto out;
+					}
+				}
+			}
+		}
+
+		/* No channels are currently available. Let's wait for one to free up. */
+
+		{
+			DEFINE_WAIT(wait);
+
+			prepare_to_wait(&gDMA.freeChannelQ, &wait,
+					TASK_INTERRUPTIBLE);
+			up(&gDMA.lock);
+			schedule();
+			finish_wait(&gDMA.freeChannelQ, &wait);
+
+			if (signal_pending(current)) {
+				/* We don't currently hold gDMA.lock, so we return directly */
+
+				return -ERESTARTSYS;
+			}
+		}
+
+		if (down_interruptible(&gDMA.lock)) {
+			return -ERESTARTSYS;
+		}
+	}
+
+out:
+	up(&gDMA.lock);
+
+	return handle;
+}
+
+/* Create both _dbg and non _dbg functions for modules. */
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+#undef dma_request_channel
+DMA_Handle_t dma_request_channel(DMA_Device_t dev)
+{
+	return dma_request_channel_dbg(dev, __FILE__, __LINE__);
+}
+
+EXPORT_SYMBOL(dma_request_channel_dbg);
+#endif
+EXPORT_SYMBOL(dma_request_channel);
+
+/****************************************************************************/
+/**
+*   Frees a previously allocated DMA Handle.
+*/
+/****************************************************************************/
+
+int dma_free_channel(DMA_Handle_t handle	/* DMA handle. */
+    ) {
+	int rc = 0;
+	DMA_Channel_t *channel;
+	DMA_DeviceAttribute_t *devAttr;
+
+	if (down_interruptible(&gDMA.lock) < 0) {
+		return -ERESTARTSYS;
+	}
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		rc = -EINVAL;
+		goto out;
+	}
+
+	devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+	if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) == 0) {
+		channel->lastDevType = channel->devType;
+		channel->devType = DMA_DEVICE_NONE;
+	}
+	channel->flags &= ~DMA_CHANNEL_FLAG_IN_USE;
+	devAttr->flags &= ~DMA_DEVICE_FLAG_IN_USE;
+
+out:
+	up(&gDMA.lock);
+
+	wake_up_interruptible(&gDMA.freeChannelQ);
+
+	return rc;
+}
+
+EXPORT_SYMBOL(dma_free_channel);
+
+/****************************************************************************/
+/**
+*   Determines if a given device has been configured as using a shared
+*   channel.
+*
+*   @return
+*       0           Device uses a dedicated channel
+*       > zero      Device uses a shared channel
+*       < zero      Error code
+*/
+/****************************************************************************/
+
+int dma_device_is_channel_shared(DMA_Device_t device	/* Device to check. */
+    ) {
+	DMA_DeviceAttribute_t *devAttr;
+
+	if (!IsDeviceValid(device)) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[device];
+
+	return ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0);
+}
+
+EXPORT_SYMBOL(dma_device_is_channel_shared);
+
+/****************************************************************************/
+/**
+*   Allocates buffers for the descriptors. This is normally done automatically
+*   but needs to be done explicitly when initiating a dma from interrupt
+*   context.
+*
+*   @return
+*       0       Descriptors were allocated successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptors(DMA_Handle_t handle,	/* DMA Handle */
+			  dmacHw_TRANSFER_TYPE_e transferType,	/* Type of transfer being performed */
+			  dma_addr_t srcData,	/* Place to get data to write to device */
+			  dma_addr_t dstData,	/* Pointer to device data address */
+			  size_t numBytes	/* Number of bytes to transfer to the device */
+    ) {
+	DMA_Channel_t *channel;
+	DMA_DeviceAttribute_t *devAttr;
+	int numDescriptors;
+	size_t ringBytesRequired;
+	int rc = 0;
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		return -ENODEV;
+	}
+
+	devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+	if (devAttr->config.transferType != transferType) {
+		return -EINVAL;
+	}
+
+	/* Figure out how many descriptors we need. */
+
+	/* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
+	/*        srcData, dstData, numBytes); */
+
+	numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
+							      (void *)srcData,
+							      (void *)dstData,
+							      numBytes);
+	if (numDescriptors < 0) {
+		printk(KERN_ERR "%s: dmacHw_calculateDescriptorCount failed\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	/* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
+	/* a new one. */
+
+	ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
+
+	/* printk("ringBytesRequired: %d\n", ringBytesRequired); */
+
+	if (ringBytesRequired > devAttr->ring.bytesAllocated) {
+		/* Make sure that this code path is never taken from interrupt context. */
+		/* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
+		/* allocation needs to have already been done. */
+
+		might_sleep();
+
+		/* Free the old descriptor ring and allocate a new one. */
+
+		dma_free_descriptor_ring(&devAttr->ring);
+
+		/* And allocate a new one. */
+
+		rc =
+		     dma_alloc_descriptor_ring(&devAttr->ring,
+					       numDescriptors);
+		if (rc < 0) {
+			printk(KERN_ERR
+			       "%s: dma_alloc_descriptor_ring(%d) failed\n",
+			       __func__, numDescriptors);
+			return rc;
+		}
+		/* Setup the descriptor for this transfer */
+
+		if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
+					  devAttr->ring.physAddr,
+					  devAttr->ring.bytesAllocated,
+					  numDescriptors) < 0) {
+			printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n",
+			       __func__);
+			return -EINVAL;
+		}
+	} else {
+		/* We've already got enough ring buffer allocated. All we need to do is reset */
+		/* any control information, just in case the previous DMA was stopped. */
+
+		dmacHw_resetDescriptorControl(devAttr->ring.virtAddr);
+	}
+
+	/* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
+	/* as last time, then we don't need to call setDataDescriptor again. */
+
+	if (dmacHw_setDataDescriptor(&devAttr->config,
+				     devAttr->ring.virtAddr,
+				     (void *)srcData,
+				     (void *)dstData, numBytes) < 0) {
+		printk(KERN_ERR "%s: dmacHw_setDataDescriptor failed\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	/* Remember the critical information for this transfer so that we can eliminate */
+	/* another call to dma_alloc_descriptors if the caller reuses the same buffers */
+
+	devAttr->prevSrcData = srcData;
+	devAttr->prevDstData = dstData;
+	devAttr->prevNumBytes = numBytes;
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_alloc_descriptors);
+
+/****************************************************************************/
+/**
+*   Allocates and sets up descriptors for a double buffered circular buffer.
+*
+*   This is primarily intended to be used for things like the ingress samples
+*   from a microphone.
+*
+*   @return
+*       > 0     Number of descriptors actually allocated.
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_double_dst_descriptors(DMA_Handle_t handle,	/* DMA Handle */
+				     dma_addr_t srcData,	/* Physical address of source data */
+				     dma_addr_t dstData1,	/* Physical address of first destination buffer */
+				     dma_addr_t dstData2,	/* Physical address of second destination buffer */
+				     size_t numBytes	/* Number of bytes in each destination buffer */
+    ) {
+	DMA_Channel_t *channel;
+	DMA_DeviceAttribute_t *devAttr;
+	int numDst1Descriptors;
+	int numDst2Descriptors;
+	int numDescriptors;
+	size_t ringBytesRequired;
+	int rc = 0;
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		return -ENODEV;
+	}
+
+	devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+	/* Figure out how many descriptors we need. */
+
+	/* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
+	/*        srcData, dstData, numBytes); */
+
+	numDst1Descriptors =
+	     dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
+					     (void *)dstData1, numBytes);
+	if (numDst1Descriptors < 0) {
+		return -EINVAL;
+	}
+	numDst2Descriptors =
+	     dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
+					     (void *)dstData2, numBytes);
+	if (numDst2Descriptors < 0) {
+		return -EINVAL;
+	}
+	numDescriptors = numDst1Descriptors + numDst2Descriptors;
+	/* printk("numDescriptors: %d\n", numDescriptors); */
+
+	/* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
+	/* a new one. */
+
+	ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
+
+	/* printk("ringBytesRequired: %d\n", ringBytesRequired); */
+
+	if (ringBytesRequired > devAttr->ring.bytesAllocated) {
+		/* Make sure that this code path is never taken from interrupt context. */
+		/* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
+		/* allocation needs to have already been done. */
+
+		might_sleep();
+
+		/* Free the old descriptor ring and allocate a new one. */
+
+		dma_free_descriptor_ring(&devAttr->ring);
+
+		/* And allocate a new one. */
+
+		rc =
+		     dma_alloc_descriptor_ring(&devAttr->ring,
+					       numDescriptors);
+		if (rc < 0) {
+			printk(KERN_ERR
+			       "%s: dma_alloc_descriptor_ring(%d) failed\n",
+			       __func__, ringBytesRequired);
+			return rc;
+		}
+	}
+
+	/* Setup the descriptor for this transfer. Since this function is used with */
+	/* CONTINUOUS DMA operations, we need to reinitialize every time, otherwise */
+	/* setDataDescriptor will keep trying to append onto the end. */
+
+	if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
+				  devAttr->ring.physAddr,
+				  devAttr->ring.bytesAllocated,
+				  numDescriptors) < 0) {
+		printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n", __func__);
+		return -EINVAL;
+	}
+
+	/* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
+	/* as last time, then we don't need to call setDataDescriptor again. */
+
+	if (dmacHw_setDataDescriptor(&devAttr->config,
+				     devAttr->ring.virtAddr,
+				     (void *)srcData,
+				     (void *)dstData1, numBytes) < 0) {
+		printk(KERN_ERR "%s: dmacHw_setDataDescriptor 1 failed\n",
+		       __func__);
+		return -EINVAL;
+	}
+	if (dmacHw_setDataDescriptor(&devAttr->config,
+				     devAttr->ring.virtAddr,
+				     (void *)srcData,
+				     (void *)dstData2, numBytes) < 0) {
+		printk(KERN_ERR "%s: dmacHw_setDataDescriptor 2 failed\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	/* You should use dma_start_transfer rather than dma_transfer_xxx so we don't */
+	/* try to make the 'prev' variables right. */
+
+	devAttr->prevSrcData = 0;
+	devAttr->prevDstData = 0;
+	devAttr->prevNumBytes = 0;
+
+	return numDescriptors;
+}
+
+EXPORT_SYMBOL(dma_alloc_double_dst_descriptors);
+
+/****************************************************************************/
+/**
+*   Initiates a transfer when the descriptors have already been setup.
+*
+*   This is a special case, and normally, the dma_transfer_xxx functions should
+*   be used.
+*
+*   @return
+*       0       Transfer was started successfully
+*       -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_start_transfer(DMA_Handle_t handle)
+{
+	DMA_Channel_t *channel;
+	DMA_DeviceAttribute_t *devAttr;
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+	dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
+				devAttr->ring.virtAddr);
+
+	/* Since we got this far, everything went successfully */
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_start_transfer);
+
+/****************************************************************************/
+/**
+*   Stops a previously started DMA transfer.
+*
+*   @return
+*       0       Transfer was stopped successfully
+*       -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_stop_transfer(DMA_Handle_t handle)
+{
+	DMA_Channel_t *channel;
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		return -ENODEV;
+	}
+
+	dmacHw_stopTransfer(channel->dmacHwHandle);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_stop_transfer);
+
+/****************************************************************************/
+/**
+*   Waits for a DMA to complete by polling. This function is only intended
+*   to be used for testing. Interrupts should be used for most DMA operations.
+*/
+/****************************************************************************/
+
+int dma_wait_transfer_done(DMA_Handle_t handle)
+{
+	DMA_Channel_t *channel;
+	dmacHw_TRANSFER_STATUS_e status;
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		return -ENODEV;
+	}
+
+	while ((status =
+		dmacHw_transferCompleted(channel->dmacHwHandle)) ==
+	       dmacHw_TRANSFER_STATUS_BUSY) {
+		;
+	}
+
+	if (status == dmacHw_TRANSFER_STATUS_ERROR) {
+		printk(KERN_ERR "%s: DMA transfer failed\n", __func__);
+		return -EIO;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_wait_transfer_done);
+
+/****************************************************************************/
+/**
+*   Initiates a DMA, allocating the descriptors as required.
+*
+*   @return
+*       0       Transfer was started successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
+*/
+/****************************************************************************/
+
+int dma_transfer(DMA_Handle_t handle,	/* DMA Handle */
+		 dmacHw_TRANSFER_TYPE_e transferType,	/* Type of transfer being performed */
+		 dma_addr_t srcData,	/* Place to get data to write to device */
+		 dma_addr_t dstData,	/* Pointer to device data address */
+		 size_t numBytes	/* Number of bytes to transfer to the device */
+    ) {
+	DMA_Channel_t *channel;
+	DMA_DeviceAttribute_t *devAttr;
+	int rc = 0;
+
+	channel = HandleToChannel(handle);
+	if (channel == NULL) {
+		return -ENODEV;
+	}
+
+	devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+	if (devAttr->config.transferType != transferType) {
+		return -EINVAL;
+	}
+
+	/* We keep track of the information about the previous request for this */
+	/* device, and if the attributes match, then we can use the descriptors we setup */
+	/* the last time, and not have to reinitialize everything. */
+
+	{
+		rc =
+		     dma_alloc_descriptors(handle, transferType, srcData,
+					   dstData, numBytes);
+		if (rc != 0) {
+			return rc;
+		}
+	}
+
+	/* And kick off the transfer */
+
+	devAttr->numBytes = numBytes;
+	devAttr->transferStartTime = timer_get_tick_count();
+
+	dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
+				devAttr->ring.virtAddr);
+
+	/* Since we got this far, everything went successfully */
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_transfer);
+
+/****************************************************************************/
+/**
+*   Set the callback function which will be called when a transfer completes.
+*   If a NULL callback function is set, then no callback will occur.
+*
+*   @note   @a devHandler will be called from IRQ context.
+*
+*   @return
+*       0       - Success
+*       -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_set_device_handler(DMA_Device_t dev,	/* Device to set the callback for. */
+			   DMA_DeviceHandler_t devHandler,	/* Function to call when the DMA completes */
+			   void *userData	/* Pointer which will be passed to devHandler. */
+    ) {
+	DMA_DeviceAttribute_t *devAttr;
+	unsigned long flags;
+
+	if (!IsDeviceValid(dev)) {
+		return -ENODEV;
+	}
+	devAttr = &DMA_gDeviceAttribute[dev];
+
+	local_irq_save(flags);
+
+	devAttr->userData = userData;
+	devAttr->devHandler = devHandler;
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_set_device_handler);
+
+/****************************************************************************/
+/**
+*   Initializes a memory mapping structure
+*/
+/****************************************************************************/
+
+int dma_init_mem_map(DMA_MemMap_t *memMap)
+{
+	memset(memMap, 0, sizeof(*memMap));
+
+	init_MUTEX(&memMap->lock);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_init_mem_map);
+
+/****************************************************************************/
+/**
+*   Releases any memory currently being held by a memory mapping structure.
+*/
+/****************************************************************************/
+
+int dma_term_mem_map(DMA_MemMap_t *memMap)
+{
+	down(&memMap->lock);	/* Just being paranoid */
+
+	/* Free up any allocated memory */
+
+	up(&memMap->lock);
+	memset(memMap, 0, sizeof(*memMap));
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_term_mem_map);
+
+/****************************************************************************/
+/**
+*   Looks at a memory address and categorizes it.
+*
+*   @return One of the values from the DMA_MemType_t enumeration.
+*/
+/****************************************************************************/
+
+DMA_MemType_t dma_mem_type(void *addr)
+{
+	unsigned long addrVal = (unsigned long)addr;
+
+	if (addrVal >= VMALLOC_END) {
+		/* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */
+
+		/* dma_alloc_xxx pages are physically and virtually contiguous */
+
+		return DMA_MEM_TYPE_DMA;
+	}
+
+	/* Technically, we could add one more classification. Addresses between VMALLOC_END */
+	/* and the beginning of the DMA virtual address could be considered to be I/O space. */
+	/* Right now, nobody cares about this particular classification, so we ignore it. */
+
+	if (is_vmalloc_addr(addr)) {
+		/* Address comes from the vmalloc'd region. Pages are virtually */
+		/* contiguous but NOT physically contiguous */
+
+		return DMA_MEM_TYPE_VMALLOC;
+	}
+
+	if (addrVal >= PAGE_OFFSET) {
+		/* PAGE_OFFSET is typically 0xC0000000 */
+
+		/* kmalloc'd pages are physically contiguous */
+
+		return DMA_MEM_TYPE_KMALLOC;
+	}
+
+	return DMA_MEM_TYPE_USER;
+}
+
+EXPORT_SYMBOL(dma_mem_type);
+
+/****************************************************************************/
+/**
+*   Looks at a memory address and determines if we support DMA'ing to/from
+*   that type of memory.
+*
+*   @return boolean -
+*               return value != 0 means dma supported
+*               return value == 0 means dma not supported
+*/
+/****************************************************************************/
+
+int dma_mem_supports_dma(void *addr)
+{
+	DMA_MemType_t memType = dma_mem_type(addr);
+
+	return (memType == DMA_MEM_TYPE_DMA)
+#if ALLOW_MAP_OF_KMALLOC_MEMORY
+	    || (memType == DMA_MEM_TYPE_KMALLOC)
+#endif
+	    || (memType == DMA_MEM_TYPE_USER);
+}
+
+EXPORT_SYMBOL(dma_mem_supports_dma);
+
+/****************************************************************************/
+/**
+*   Maps in a memory region such that it can be used for performing a DMA.
+*
+*   @return
+*/
+/****************************************************************************/
+
+int dma_map_start(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+		  enum dma_data_direction dir	/* Direction that the mapping will be going */
+    ) {
+	int rc;
+
+	down(&memMap->lock);
+
+	DMA_MAP_PRINT("memMap: %p\n", memMap);
+
+	if (memMap->inUse) {
+		printk(KERN_ERR "%s: memory map %p is already being used\n",
+		       __func__, memMap);
+		rc = -EBUSY;
+		goto out;
+	}
+
+	memMap->inUse = 1;
+	memMap->dir = dir;
+	memMap->numRegionsUsed = 0;
+
+	rc = 0;
+
+out:
+
+	DMA_MAP_PRINT("returning %d", rc);
+
+	up(&memMap->lock);
+
+	return rc;
+}
+
+EXPORT_SYMBOL(dma_map_start);
+
+/****************************************************************************/
+/**
+*   Adds a segment of memory to a memory map. Each segment is both
+*   physically and virtually contiguous.
+*
+*   @return     0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+static int dma_map_add_segment(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+			       DMA_Region_t *region,	/* Region that the segment belongs to */
+			       void *virtAddr,	/* Virtual address of the segment being added */
+			       dma_addr_t physAddr,	/* Physical address of the segment being added */
+			       size_t numBytes	/* Number of bytes of the segment being added */
+    ) {
+	DMA_Segment_t *segment;
+
+	DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr,
+		      physAddr, numBytes);
+
+	/* Sanity check */
+
+	if (((unsigned long)virtAddr < (unsigned long)region->virtAddr)
+	    || (((unsigned long)virtAddr + numBytes)) >
+	    ((unsigned long)region->virtAddr + region->numBytes)) {
+		printk(KERN_ERR
+		       "%s: virtAddr %p is outside region @ %p len: %d\n",
+		       __func__, virtAddr, region->virtAddr, region->numBytes);
+		return -EINVAL;
+	}
+
+	if (region->numSegmentsUsed > 0) {
+		/* Check to see if this segment is physically contiguous with the previous one */
+
+		segment = &region->segment[region->numSegmentsUsed - 1];
+
+		if ((segment->physAddr + segment->numBytes) == physAddr) {
+			/* It is - just add on to the end */
+
+			DMA_MAP_PRINT("appending %d bytes to last segment\n",
+				      numBytes);
+
+			segment->numBytes += numBytes;
+
+			return 0;
+		}
+	}
+
+	/* Reallocate to hold more segments, if required. */
+
+	if (region->numSegmentsUsed >= region->numSegmentsAllocated) {
+		DMA_Segment_t *newSegment;
+		size_t oldSize =
+		    region->numSegmentsAllocated * sizeof(*newSegment);
+		int newAlloc = region->numSegmentsAllocated + 4;
+		size_t newSize = newAlloc * sizeof(*newSegment);
+
+		newSegment = kmalloc(newSize, GFP_KERNEL);
+		if (newSegment == NULL) {
+			return -ENOMEM;
+		}
+		memcpy(newSegment, region->segment, oldSize);
+		memset(&((uint8_t *) newSegment)[oldSize], 0,
+		       newSize - oldSize);
+		kfree(region->segment);
+
+		region->numSegmentsAllocated = newAlloc;
+		region->segment = newSegment;
+	}
+
+	segment = &region->segment[region->numSegmentsUsed];
+	region->numSegmentsUsed++;
+
+	segment->virtAddr = virtAddr;
+	segment->physAddr = physAddr;
+	segment->numBytes = numBytes;
+
+	DMA_MAP_PRINT("returning success\n");
+
+	return 0;
+}
+
+/****************************************************************************/
+/**
+*   Adds a region of memory to a memory map. Each region is virtually
+*   contiguous, but not necessarily physically contiguous.
+*
+*   @return     0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_add_region(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+		       void *mem,	/* Virtual address that we want to get a map of */
+		       size_t numBytes	/* Number of bytes being mapped */
+    ) {
+	unsigned long addr = (unsigned long)mem;
+	unsigned int offset;
+	int rc = 0;
+	DMA_Region_t *region;
+	dma_addr_t physAddr;
+
+	down(&memMap->lock);
+
+	DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes);
+
+	if (!memMap->inUse) {
+		printk(KERN_ERR "%s: Make sure you call dma_map_start first\n",
+		       __func__);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Reallocate to hold more regions. */
+
+	if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) {
+		DMA_Region_t *newRegion;
+		size_t oldSize =
+		    memMap->numRegionsAllocated * sizeof(*newRegion);
+		int newAlloc = memMap->numRegionsAllocated + 4;
+		size_t newSize = newAlloc * sizeof(*newRegion);
+
+		newRegion = kmalloc(newSize, GFP_KERNEL);
+		if (newRegion == NULL) {
+			rc = -ENOMEM;
+			goto out;
+		}
+		memcpy(newRegion, memMap->region, oldSize);
+		memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize);
+
+		kfree(memMap->region);
+
+		memMap->numRegionsAllocated = newAlloc;
+		memMap->region = newRegion;
+	}
+
+	region = &memMap->region[memMap->numRegionsUsed];
+	memMap->numRegionsUsed++;
+
+	offset = addr & ~PAGE_MASK;
+
+	region->memType = dma_mem_type(mem);
+	region->virtAddr = mem;
+	region->numBytes = numBytes;
+	region->numSegmentsUsed = 0;
+	region->numLockedPages = 0;
+	region->lockedPages = NULL;
+
+	switch (region->memType) {
+	case DMA_MEM_TYPE_VMALLOC:
+		{
+			atomic_inc(&gDmaStatMemTypeVmalloc);
+
+			/* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */
+
+			/* vmalloc'd pages are not physically contiguous */
+
+			rc = -EINVAL;
+			break;
+		}
+
+	case DMA_MEM_TYPE_KMALLOC:
+		{
+			atomic_inc(&gDmaStatMemTypeKmalloc);
+
+			/* kmalloc'd pages are physically contiguous, so they'll have exactly */
+			/* one segment */
+
+#if ALLOW_MAP_OF_KMALLOC_MEMORY
+			physAddr =
+			    dma_map_single(NULL, mem, numBytes, memMap->dir);
+			rc = dma_map_add_segment(memMap, region, mem, physAddr,
+						 numBytes);
+#else
+			rc = -EINVAL;
+#endif
+			break;
+		}
+
+	case DMA_MEM_TYPE_DMA:
+		{
+			/* dma_alloc_xxx pages are physically contiguous */
+
+			atomic_inc(&gDmaStatMemTypeCoherent);
+
+			physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset;
+
+			dma_sync_single_for_cpu(NULL, physAddr, numBytes,
+						memMap->dir);
+			rc = dma_map_add_segment(memMap, region, mem, physAddr,
+						 numBytes);
+			break;
+		}
+
+	case DMA_MEM_TYPE_USER:
+		{
+			size_t firstPageOffset;
+			size_t firstPageSize;
+			struct page **pages;
+			struct task_struct *userTask;
+
+			atomic_inc(&gDmaStatMemTypeUser);
+
+#if 1
+			/* If the pages are user pages, then the dma_mem_map_set_user_task function */
+			/* must have been previously called. */
+
+			if (memMap->userTask == NULL) {
+				printk(KERN_ERR
+				       "%s: must call dma_mem_map_set_user_task when using user-mode memory\n",
+				       __func__);
+				return -EINVAL;
+			}
+
+			/* User pages need to be locked. */
+
+			firstPageOffset =
+			    (unsigned long)region->virtAddr & (PAGE_SIZE - 1);
+			firstPageSize = PAGE_SIZE - firstPageOffset;
+
+			region->numLockedPages = (firstPageOffset
+						  + region->numBytes +
+						  PAGE_SIZE - 1) / PAGE_SIZE;
+			pages =
+			    kmalloc(region->numLockedPages *
+				    sizeof(struct page *), GFP_KERNEL);
+
+			if (pages == NULL) {
+				region->numLockedPages = 0;
+				return -ENOMEM;
+			}
+
+			userTask = memMap->userTask;
+
+			down_read(&userTask->mm->mmap_sem);
+			rc = get_user_pages(userTask,	/* task */
+					    userTask->mm,	/* mm */
+					    (unsigned long)region->virtAddr,	/* start */
+					    region->numLockedPages,	/* len */
+					    memMap->dir == DMA_FROM_DEVICE,	/* write */
+					    0,	/* force */
+					    pages,	/* pages (array of pointers to page) */
+					    NULL);	/* vmas */
+			up_read(&userTask->mm->mmap_sem);
+
+			if (rc != region->numLockedPages) {
+				kfree(pages);
+				region->numLockedPages = 0;
+
+				if (rc >= 0) {
+					rc = -EINVAL;
+				}
+			} else {
+				uint8_t *virtAddr = region->virtAddr;
+				size_t bytesRemaining;
+				int pageIdx;
+
+				rc = 0;	/* Since get_user_pages returns +ve number */
+
+				region->lockedPages = pages;
+
+				/* We've locked the user pages. Now we need to walk them and figure */
+				/* out the physical addresses. */
+
+				/* The first page may be partial */
+
+				dma_map_add_segment(memMap,
+						    region,
+						    virtAddr,
+						    PFN_PHYS(page_to_pfn
+							     (pages[0])) +
+						    firstPageOffset,
+						    firstPageSize);
+
+				virtAddr += firstPageSize;
+				bytesRemaining =
+				    region->numBytes - firstPageSize;
+
+				for (pageIdx = 1;
+				     pageIdx < region->numLockedPages;
+				     pageIdx++) {
+					size_t bytesThisPage =
+					    (bytesRemaining >
+					     PAGE_SIZE ? PAGE_SIZE :
+					     bytesRemaining);
+
+					DMA_MAP_PRINT
+					    ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n",
+					     pageIdx, pages[pageIdx],
+					     page_to_pfn(pages[pageIdx]),
+					     PFN_PHYS(page_to_pfn
+						      (pages[pageIdx])));
+
+					dma_map_add_segment(memMap,
+							    region,
+							    virtAddr,
+							    PFN_PHYS(page_to_pfn
+								     (pages
+								      [pageIdx])),
+							    bytesThisPage);
+
+					virtAddr += bytesThisPage;
+					bytesRemaining -= bytesThisPage;
+				}
+			}
+#else
+			printk(KERN_ERR
+			       "%s: User mode pages are not yet supported\n",
+			       __func__);
+
+			/* user pages are not physically contiguous */
+
+			rc = -EINVAL;
+#endif
+			break;
+		}
+
+	default:
+		{
+			printk(KERN_ERR "%s: Unsupported memory type: %d\n",
+			       __func__, region->memType);
+
+			rc = -EINVAL;
+			break;
+		}
+	}
+
+	if (rc != 0) {
+		memMap->numRegionsUsed--;
+	}
+
+out:
+
+	DMA_MAP_PRINT("returning %d\n", rc);
+
+	up(&memMap->lock);
+
+	return rc;
+}
+
+EXPORT_SYMBOL(dma_map_add_segment);
+
+/****************************************************************************/
+/**
+*   Maps in a memory region such that it can be used for performing a DMA.
+*
+*   @return     0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_mem(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+		void *mem,	/* Virtual address that we want to get a map of */
+		size_t numBytes,	/* Number of bytes being mapped */
+		enum dma_data_direction dir	/* Direction that the mapping will be going */
+    ) {
+	int rc;
+
+	rc = dma_map_start(memMap, dir);
+	if (rc == 0) {
+		rc = dma_map_add_region(memMap, mem, numBytes);
+		if (rc < 0) {
+			/* Since the add fails, this function will fail, and the caller won't */
+			/* call unmap, so we need to do it here. */
+
+			dma_unmap(memMap, 0);
+		}
+	}
+
+	return rc;
+}
+
+EXPORT_SYMBOL(dma_map_mem);
+
+/****************************************************************************/
+/**
+*   Setup a descriptor ring for a given memory map.
+*
+*   It is assumed that the descriptor ring has already been initialized, and
+*   this routine will only reallocate a new descriptor ring if the existing
+*   one is too small.
+*
+*   @return     0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_create_descriptor_ring(DMA_Device_t dev,	/* DMA device (where the ring is stored) */
+				   DMA_MemMap_t *memMap,	/* Memory map that will be used */
+				   dma_addr_t devPhysAddr	/* Physical address of device */
+    ) {
+	int rc;
+	int numDescriptors;
+	DMA_DeviceAttribute_t *devAttr;
+	DMA_Region_t *region;
+	DMA_Segment_t *segment;
+	dma_addr_t srcPhysAddr;
+	dma_addr_t dstPhysAddr;
+	int regionIdx;
+	int segmentIdx;
+
+	devAttr = &DMA_gDeviceAttribute[dev];
+
+	down(&memMap->lock);
+
+	/* Figure out how many descriptors we need */
+
+	numDescriptors = 0;
+	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
+		region = &memMap->region[regionIdx];
+
+		for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
+		     segmentIdx++) {
+			segment = &region->segment[segmentIdx];
+
+			if (memMap->dir == DMA_TO_DEVICE) {
+				srcPhysAddr = segment->physAddr;
+				dstPhysAddr = devPhysAddr;
+			} else {
+				srcPhysAddr = devPhysAddr;
+				dstPhysAddr = segment->physAddr;
+			}
+
+			rc =
+			     dma_calculate_descriptor_count(dev, srcPhysAddr,
+							    dstPhysAddr,
+							    segment->
+							    numBytes);
+			if (rc < 0) {
+				printk(KERN_ERR
+				       "%s: dma_calculate_descriptor_count failed: %d\n",
+				       __func__, rc);
+				goto out;
+			}
+			numDescriptors += rc;
+		}
+	}
+
+	/* Adjust the size of the ring, if it isn't big enough */
+
+	if (numDescriptors > devAttr->ring.descriptorsAllocated) {
+		dma_free_descriptor_ring(&devAttr->ring);
+		rc =
+		     dma_alloc_descriptor_ring(&devAttr->ring,
+					       numDescriptors);
+		if (rc < 0) {
+			printk(KERN_ERR
+			       "%s: dma_alloc_descriptor_ring failed: %d\n",
+			       __func__, rc);
+			goto out;
+		}
+	} else {
+		rc =
+		     dma_init_descriptor_ring(&devAttr->ring,
+					      numDescriptors);
+		if (rc < 0) {
+			printk(KERN_ERR
+			       "%s: dma_init_descriptor_ring failed: %d\n",
+			       __func__, rc);
+			goto out;
+		}
+	}
+
+	/* Populate the descriptors */
+
+	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
+		region = &memMap->region[regionIdx];
+
+		for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
+		     segmentIdx++) {
+			segment = &region->segment[segmentIdx];
+
+			if (memMap->dir == DMA_TO_DEVICE) {
+				srcPhysAddr = segment->physAddr;
+				dstPhysAddr = devPhysAddr;
+			} else {
+				srcPhysAddr = devPhysAddr;
+				dstPhysAddr = segment->physAddr;
+			}
+
+			rc =
+			     dma_add_descriptors(&devAttr->ring, dev,
+						 srcPhysAddr, dstPhysAddr,
+						 segment->numBytes);
+			if (rc < 0) {
+				printk(KERN_ERR
+				       "%s: dma_add_descriptors failed: %d\n",
+				       __func__, rc);
+				goto out;
+			}
+		}
+	}
+
+	rc = 0;
+
+out:
+
+	up(&memMap->lock);
+	return rc;
+}
+
+EXPORT_SYMBOL(dma_map_create_descriptor_ring);
+
+/****************************************************************************/
+/**
+*   Maps in a memory region such that it can be used for performing a DMA.
+*
+*   @return
+*/
+/****************************************************************************/
+
+int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+	      int dirtied	/* non-zero if any of the pages were modified */
+    ) {
+	int regionIdx;
+	int segmentIdx;
+	DMA_Region_t *region;
+	DMA_Segment_t *segment;
+
+	for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
+		region = &memMap->region[regionIdx];
+
+		for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
+		     segmentIdx++) {
+			segment = &region->segment[segmentIdx];
+
+			switch (region->memType) {
+			case DMA_MEM_TYPE_VMALLOC:
+				{
+					printk(KERN_ERR
+					       "%s: vmalloc'd pages are not yet supported\n",
+					       __func__);
+					return -EINVAL;
+				}
+
+			case DMA_MEM_TYPE_KMALLOC:
+				{
+#if ALLOW_MAP_OF_KMALLOC_MEMORY
+					dma_unmap_single(NULL,
+							 segment->physAddr,
+							 segment->numBytes,
+							 memMap->dir);
+#endif
+					break;
+				}
+
+			case DMA_MEM_TYPE_DMA:
+				{
+					dma_sync_single_for_cpu(NULL,
+								segment->
+								physAddr,
+								segment->
+								numBytes,
+								memMap->dir);
+					break;
+				}
+
+			case DMA_MEM_TYPE_USER:
+				{
+					/* Nothing to do here. */
+
+					break;
+				}
+
+			default:
+				{
+					printk(KERN_ERR
+					       "%s: Unsupported memory type: %d\n",
+					       __func__, region->memType);
+					return -EINVAL;
+				}
+			}
+
+			segment->virtAddr = NULL;
+			segment->physAddr = 0;
+			segment->numBytes = 0;
+		}
+
+		if (region->numLockedPages > 0) {
+			int pageIdx;
+
+			/* Some user pages were locked. We need to go and unlock them now. */
+
+			for (pageIdx = 0; pageIdx < region->numLockedPages;
+			     pageIdx++) {
+				struct page *page =
+				    region->lockedPages[pageIdx];
+
+				if (memMap->dir == DMA_FROM_DEVICE) {
+					SetPageDirty(page);
+				}
+				page_cache_release(page);
+			}
+			kfree(region->lockedPages);
+			region->numLockedPages = 0;
+			region->lockedPages = NULL;
+		}
+
+		region->memType = DMA_MEM_TYPE_NONE;
+		region->virtAddr = NULL;
+		region->numBytes = 0;
+		region->numSegmentsUsed = 0;
+	}
+	memMap->userTask = NULL;
+	memMap->numRegionsUsed = 0;
+	memMap->inUse = 0;
+
+	up(&memMap->lock);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dma_unmap);
diff --git a/arch/arm/mach-bcmring/dma_device.c b/arch/arm/mach-bcmring/dma_device.c
new file mode 100644
index 0000000..ca0ad73
--- /dev/null
+++ b/arch/arm/mach-bcmring/dma_device.c
@@ -0,0 +1,593 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*   @file   dma_device.c
+*
+*   @brief  private array of DMA_DeviceAttribute_t
+*/
+/****************************************************************************/
+
+DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES] = {
+	[DMA_DEVICE_MEM_TO_MEM] =	/* MEM 2 MEM */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "mem-to-mem",
+	 .config = {
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+
+		    },
+	 },
+	[DMA_DEVICE_VPM_MEM_TO_MEM] =	/* VPM */
+	{
+	 .flags = DMA_DEVICE_FLAG_IS_DEDICATED | DMA_DEVICE_FLAG_NO_ISR,
+	 .name = "vpm",
+	 .dedicatedController = 0,
+	 .dedicatedChannel = 0,
+	 /* reserve DMA0:0 for VPM */
+	 },
+	[DMA_DEVICE_NAND_MEM_TO_MEM] =	/* NAND */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "nand",
+	 .config = {
+		    .srcPeripheralPort = 0,
+		    .dstPeripheralPort = 0,
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_6,
+		    },
+	 },
+	[DMA_DEVICE_PIF_MEM_TO_DEV] =	/* PIF TX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1
+	 | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO
+	 | DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST | DMA_DEVICE_FLAG_PORT_PER_DMAC,
+	 .name = "pif_tx",
+	 .dmacPort = {14, 5},
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    /* dstPeripheralPort          = 5 or 14 */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+		    .maxDataPerBlock = 16256,
+		    },
+	 },
+	[DMA_DEVICE_PIF_DEV_TO_MEM] =	/* PIF RX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1
+	 | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO
+	 /* DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST */
+	 | DMA_DEVICE_FLAG_PORT_PER_DMAC,
+	 .name = "pif_rx",
+	 .dmacPort = {14, 5},
+	 .config = {
+		    /* srcPeripheralPort          = 5 or 14 */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+		    .maxDataPerBlock = 16256,
+		    },
+	 },
+	[DMA_DEVICE_I2S0_DEV_TO_MEM] =	/* I2S RX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "i2s0_rx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: I2S0 */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+		    },
+	 },
+	[DMA_DEVICE_I2S0_MEM_TO_DEV] =	/* I2S TX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "i2s0_tx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 1,	/* DST: I2S0 */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    },
+	 },
+	[DMA_DEVICE_I2S1_DEV_TO_MEM] =	/* I2S1 RX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "i2s1_rx",
+	 .config = {
+		    .srcPeripheralPort = 2,	/* SRC: I2S1 */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+		    },
+	 },
+	[DMA_DEVICE_I2S1_MEM_TO_DEV] =	/* I2S1 TX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "i2s1_tx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 3,	/* DST: I2S1 */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    },
+	 },
+	[DMA_DEVICE_ESW_MEM_TO_DEV] =	/* ESW TX */
+	{
+	 .name = "esw_tx",
+	 .flags = DMA_DEVICE_FLAG_IS_DEDICATED,
+	 .dedicatedController = 1,
+	 .dedicatedChannel = 3,
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 1,	/* DST: ESW (MTP) */
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    /* DMAx_AHB_SSTATARy */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    /* DMAx_AHB_DSTATARy */
+		    .dstStatusRegisterAddress = 0x30490010,
+		    /* DMAx_AHB_CFGy */
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    /* DMAx_AHB_CTLy */
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    },
+	 },
+	[DMA_DEVICE_ESW_DEV_TO_MEM] =	/* ESW RX */
+	{
+	 .name = "esw_rx",
+	 .flags = DMA_DEVICE_FLAG_IS_DEDICATED,
+	 .dedicatedController = 1,
+	 .dedicatedChannel = 2,
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: ESW (PTM) */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    /* DMAx_AHB_SSTATARy */
+		    .srcStatusRegisterAddress = 0x30480010,
+		    /* DMAx_AHB_DSTATARy */
+		    .dstStatusRegisterAddress = 0x00000000,
+		    /* DMAx_AHB_CFGy */
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    /* DMAx_AHB_CTLy */
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    },
+	 },
+	[DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM] =	/* APM Codec A Ingress */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "apm_a_rx",
+	 .config = {
+		    .srcPeripheralPort = 2,	/* SRC: Codec A Ingress FIFO */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+		    },
+	 },
+	[DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV] =	/* APM Codec A Egress */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "apm_a_tx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 3,	/* DST: Codec A Egress FIFO */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    },
+	 },
+	[DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM] =	/* APM Codec B Ingress */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "apm_b_rx",
+	 .config = {
+		    .srcPeripheralPort = 4,	/* SRC: Codec B Ingress FIFO */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+		    },
+	 },
+	[DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV] =	/* APM Codec B Egress */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "apm_b_tx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 5,	/* DST: Codec B Egress FIFO */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    },
+	 },
+	[DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM] =	/* APM Codec C Ingress */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "apm_c_rx",
+	 .config = {
+		    .srcPeripheralPort = 4,	/* SRC: Codec C Ingress FIFO */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+		    },
+	 },
+	[DMA_DEVICE_APM_PCM0_DEV_TO_MEM] =	/* PCM0 RX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "pcm0_rx",
+	 .config = {
+		    .srcPeripheralPort = 12,	/* SRC: PCM0 */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+		    },
+	 },
+	[DMA_DEVICE_APM_PCM0_MEM_TO_DEV] =	/* PCM0 TX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0,
+	 .name = "pcm0_tx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 13,	/* DST: PCM0 */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    },
+	 },
+	[DMA_DEVICE_APM_PCM1_DEV_TO_MEM] =	/* PCM1 RX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "pcm1_rx",
+	 .config = {
+		    .srcPeripheralPort = 14,	/* SRC: PCM1 */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+		    },
+	 },
+	[DMA_DEVICE_APM_PCM1_MEM_TO_DEV] =	/* PCM1 TX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "pcm1_tx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 15,	/* DST: PCM1 */
+		    .srcStatusRegisterAddress = 0,
+		    .dstStatusRegisterAddress = 0,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    },
+	 },
+	[DMA_DEVICE_SPUM_DEV_TO_MEM] =	/* SPUM RX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "spum_rx",
+	 .config = {
+		    .srcPeripheralPort = 6,	/* SRC: Codec A Ingress FIFO */
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    /* Busrt size **MUST** be 16 for SPUM to work */
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    /* on the RX side, SPU needs to be the flow controller */
+		    .flowControler = dmacHw_FLOW_CONTROL_PERIPHERAL,
+		    },
+	 },
+	[DMA_DEVICE_SPUM_MEM_TO_DEV] =	/* SPUM TX */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "spum_tx",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .dstPeripheralPort = 7,	/* DST: SPUM */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+		    .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+		    /* Busrt size **MUST** be 16 for SPUM to work */
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16,
+		    .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+		    },
+	 },
+	[DMA_DEVICE_MEM_TO_VRAM] =	/* MEM 2 VRAM */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "mem-to-vram",
+	 .config = {
+		    .srcPeripheralPort = 0,	/* SRC: memory */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+		    },
+	 },
+	[DMA_DEVICE_VRAM_TO_MEM] =	/* VRAM 2 MEM */
+	{
+	 .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+	 .name = "vram-to-mem",
+	 .config = {
+		    .dstPeripheralPort = 0,	/* DST: memory */
+		    .srcStatusRegisterAddress = 0x00000000,
+		    .dstStatusRegisterAddress = 0x00000000,
+		    .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+		    .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+		    .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+		    .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+		    .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+		    .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+		    .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+		    .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+		    .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+		    .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+		    .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+		    },
+	 },
+};
+EXPORT_SYMBOL(DMA_gDeviceAttribute);	/* primarily for dma-test.c */
diff --git a/arch/arm/mach-bcmring/include/cfg_global.h b/arch/arm/mach-bcmring/include/cfg_global.h
new file mode 100644
index 0000000..f01da87
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/cfg_global.h
@@ -0,0 +1,13 @@
+#ifndef _CFG_GLOBAL_H_
+#define _CFG_GLOBAL_H_
+
+#include <cfg_global_defines.h>
+
+#define CFG_GLOBAL_CHIP                         BCM11107
+#define CFG_GLOBAL_CHIP_FAMILY                  CFG_GLOBAL_CHIP_FAMILY_BCMRING
+#define CFG_GLOBAL_CHIP_REV                     0xB0
+#define CFG_GLOBAL_RAM_SIZE                     0x10000000
+#define CFG_GLOBAL_RAM_BASE                     0x00000000
+#define CFG_GLOBAL_RAM_RESERVED_SIZE            0x000000
+
+#endif /* _CFG_GLOBAL_H_ */
diff --git a/arch/arm/mach-bcmring/include/cfg_global_defines.h b/arch/arm/mach-bcmring/include/cfg_global_defines.h
new file mode 100644
index 0000000..b5beb0b
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/cfg_global_defines.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+* Copyright 2006 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CFG_GLOBAL_DEFINES_H
+#define CFG_GLOBAL_DEFINES_H
+
+/* CHIP */
+#define BCM1103 1
+
+#define BCM1191 4
+#define BCM2153 5
+#define BCM2820 6
+
+#define BCM2826 8
+#define FPGA11107 9
+#define BCM11107   10
+#define BCM11109   11
+#define BCM11170   12
+#define BCM11110   13
+#define BCM11211   14
+
+/* CFG_GLOBAL_CHIP_FAMILY types */
+#define CFG_GLOBAL_CHIP_FAMILY_NONE        0
+#define CFG_GLOBAL_CHIP_FAMILY_BCM116X     2
+#define CFG_GLOBAL_CHIP_FAMILY_BCMRING     4
+#define CFG_GLOBAL_CHIP_FAMILY_BCM1103     8
+
+#define IMAGE_HEADER_SIZE_CHECKSUM    4
+#endif
diff --git a/arch/arm/mach-bcmring/include/csp/cache.h b/arch/arm/mach-bcmring/include/csp/cache.h
new file mode 100644
index 0000000..caa20e5
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/cache.h
@@ -0,0 +1,35 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CSP_CACHE_H
+#define CSP_CACHE_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/stdint.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#if defined(__KERNEL__) && !defined(STANDALONE)
+#include <asm/cacheflush.h>
+
+#define CSP_CACHE_FLUSH_ALL      flush_cache_all()
+
+#else
+
+#define CSP_CACHE_FLUSH_ALL
+
+#endif
+
+#endif /* CSP_CACHE_H */
diff --git a/arch/arm/mach-bcmring/include/csp/delay.h b/arch/arm/mach-bcmring/include/csp/delay.h
new file mode 100644
index 0000000..8b3d803
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/delay.h
@@ -0,0 +1,36 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+#ifndef CSP_DELAY_H
+#define CSP_DELAY_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+/* Some CSP routines require use of the following delay routines. Use the OS */
+/* version if available, otherwise use a CSP specific definition. */
+/* void udelay(unsigned long usecs); */
+/* void mdelay(unsigned long msecs); */
+
+#if defined(__KERNEL__) && !defined(STANDALONE)
+   #include <linux/delay.h>
+#else
+   #include <mach/csp/delay.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /*  CSP_DELAY_H */
diff --git a/arch/arm/mach-bcmring/include/csp/dmacHw.h b/arch/arm/mach-bcmring/include/csp/dmacHw.h
new file mode 100644
index 0000000..5d51013
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/dmacHw.h
@@ -0,0 +1,596 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    dmacHw.h
+*
+*  @brief   API definitions for low level DMA controller driver
+*
+*/
+/****************************************************************************/
+#ifndef _DMACHW_H
+#define _DMACHW_H
+
+#include <stddef.h>
+
+#include <csp/stdint.h>
+#include <mach/csp/dmacHw_reg.h>
+
+/* Define DMA Channel ID using DMA controller number (m) and channel number (c).
+
+   System specific channel ID should be defined as follows
+
+   For example:
+
+   #include <dmacHw.h>
+   ...
+   #define systemHw_LCD_CHANNEL_ID                dmacHw_MAKE_CHANNEL_ID(0,5)
+   #define systemHw_SWITCH_RX_CHANNEL_ID          dmacHw_MAKE_CHANNEL_ID(0,0)
+   #define systemHw_SWITCH_TX_CHANNEL_ID          dmacHw_MAKE_CHANNEL_ID(0,1)
+   #define systemHw_APM_RX_CHANNEL_ID             dmacHw_MAKE_CHANNEL_ID(0,3)
+   #define systemHw_APM_TX_CHANNEL_ID             dmacHw_MAKE_CHANNEL_ID(0,4)
+   ...
+   #define systemHw_SHARED1_CHANNEL_ID            dmacHw_MAKE_CHANNEL_ID(1,4)
+   #define systemHw_SHARED2_CHANNEL_ID            dmacHw_MAKE_CHANNEL_ID(1,5)
+   #define systemHw_SHARED3_CHANNEL_ID            dmacHw_MAKE_CHANNEL_ID(0,6)
+   ...
+*/
+#define dmacHw_MAKE_CHANNEL_ID(m, c)         (m << 8 | c)
+
+typedef enum {
+	dmacHw_CHANNEL_PRIORITY_0 = dmacHw_REG_CFG_LO_CH_PRIORITY_0,	/* Channel priority 0. Lowest priority DMA channel */
+	dmacHw_CHANNEL_PRIORITY_1 = dmacHw_REG_CFG_LO_CH_PRIORITY_1,	/* Channel priority 1 */
+	dmacHw_CHANNEL_PRIORITY_2 = dmacHw_REG_CFG_LO_CH_PRIORITY_2,	/* Channel priority 2 */
+	dmacHw_CHANNEL_PRIORITY_3 = dmacHw_REG_CFG_LO_CH_PRIORITY_3,	/* Channel priority 3 */
+	dmacHw_CHANNEL_PRIORITY_4 = dmacHw_REG_CFG_LO_CH_PRIORITY_4,	/* Channel priority 4 */
+	dmacHw_CHANNEL_PRIORITY_5 = dmacHw_REG_CFG_LO_CH_PRIORITY_5,	/* Channel priority 5 */
+	dmacHw_CHANNEL_PRIORITY_6 = dmacHw_REG_CFG_LO_CH_PRIORITY_6,	/* Channel priority 6 */
+	dmacHw_CHANNEL_PRIORITY_7 = dmacHw_REG_CFG_LO_CH_PRIORITY_7	/* Channel priority 7. Highest priority DMA channel */
+} dmacHw_CHANNEL_PRIORITY_e;
+
+/* Source destination master interface */
+typedef enum {
+	dmacHw_SRC_MASTER_INTERFACE_1 = dmacHw_REG_CTL_SMS_1,	/* Source DMA master interface 1 */
+	dmacHw_SRC_MASTER_INTERFACE_2 = dmacHw_REG_CTL_SMS_2,	/* Source DMA master interface 2 */
+	dmacHw_DST_MASTER_INTERFACE_1 = dmacHw_REG_CTL_DMS_1,	/* Destination DMA master interface 1 */
+	dmacHw_DST_MASTER_INTERFACE_2 = dmacHw_REG_CTL_DMS_2	/* Destination DMA master interface 2 */
+} dmacHw_MASTER_INTERFACE_e;
+
+typedef enum {
+	dmacHw_SRC_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_SRC_TR_WIDTH_8,	/* Source 8 bit  (1 byte) per transaction */
+	dmacHw_SRC_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_SRC_TR_WIDTH_16,	/* Source 16 bit (2 byte) per transaction */
+	dmacHw_SRC_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_SRC_TR_WIDTH_32,	/* Source 32 bit (4 byte) per transaction */
+	dmacHw_SRC_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_SRC_TR_WIDTH_64,	/* Source 64 bit (8 byte) per transaction */
+	dmacHw_DST_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_DST_TR_WIDTH_8,	/* Destination 8 bit  (1 byte) per transaction */
+	dmacHw_DST_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_DST_TR_WIDTH_16,	/* Destination 16 bit (2 byte) per transaction */
+	dmacHw_DST_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_DST_TR_WIDTH_32,	/* Destination 32 bit (4 byte) per transaction */
+	dmacHw_DST_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_DST_TR_WIDTH_64	/* Destination 64 bit (8 byte) per transaction */
+} dmacHw_TRANSACTION_WIDTH_e;
+
+typedef enum {
+	dmacHw_SRC_BURST_WIDTH_0 = dmacHw_REG_CTL_SRC_MSIZE_0,	/* Source No burst */
+	dmacHw_SRC_BURST_WIDTH_4 = dmacHw_REG_CTL_SRC_MSIZE_4,	/* Source 4  X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+	dmacHw_SRC_BURST_WIDTH_8 = dmacHw_REG_CTL_SRC_MSIZE_8,	/* Source 8  X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+	dmacHw_SRC_BURST_WIDTH_16 = dmacHw_REG_CTL_SRC_MSIZE_16,	/* Source 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+	dmacHw_DST_BURST_WIDTH_0 = dmacHw_REG_CTL_DST_MSIZE_0,	/* Destination No burst */
+	dmacHw_DST_BURST_WIDTH_4 = dmacHw_REG_CTL_DST_MSIZE_4,	/* Destination 4  X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+	dmacHw_DST_BURST_WIDTH_8 = dmacHw_REG_CTL_DST_MSIZE_8,	/* Destination 8  X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+	dmacHw_DST_BURST_WIDTH_16 = dmacHw_REG_CTL_DST_MSIZE_16	/* Destination 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+} dmacHw_BURST_WIDTH_e;
+
+typedef enum {
+	dmacHw_TRANSFER_TYPE_MEM_TO_MEM = dmacHw_REG_CTL_TTFC_MM_DMAC,	/* Memory to memory transfer */
+	dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM = dmacHw_REG_CTL_TTFC_PM_DMAC,	/* Peripheral to memory transfer */
+	dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_MP_DMAC,	/* Memory to peripheral transfer */
+	dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_PP_DMAC	/* Peripheral to peripheral transfer */
+} dmacHw_TRANSFER_TYPE_e;
+
+typedef enum {
+	dmacHw_TRANSFER_MODE_PERREQUEST,	/* Block transfer per DMA request */
+	dmacHw_TRANSFER_MODE_CONTINUOUS,	/* Continuous transfer of streaming data */
+	dmacHw_TRANSFER_MODE_PERIODIC	/* Periodic transfer of streaming data */
+} dmacHw_TRANSFER_MODE_e;
+
+typedef enum {
+	dmacHw_SRC_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_SINC_INC,	/* Increment source address after every transaction */
+	dmacHw_SRC_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_SINC_DEC,	/* Decrement source address after every transaction */
+	dmacHw_DST_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_DINC_INC,	/* Increment destination address after every transaction */
+	dmacHw_DST_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_DINC_DEC,	/* Decrement destination address after every transaction */
+	dmacHw_SRC_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_SINC_NC,	/* No change in source address after every transaction */
+	dmacHw_DST_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_DINC_NC	/* No change in destination address after every transaction */
+} dmacHw_ADDRESS_UPDATE_MODE_e;
+
+typedef enum {
+	dmacHw_FLOW_CONTROL_DMA,	/* DMA working as flow controller (default) */
+	dmacHw_FLOW_CONTROL_PERIPHERAL	/* Peripheral working as flow controller */
+} dmacHw_FLOW_CONTROL_e;
+
+typedef enum {
+	dmacHw_TRANSFER_STATUS_BUSY,	/* DMA Transfer ongoing */
+	dmacHw_TRANSFER_STATUS_DONE,	/* DMA Transfer completed */
+	dmacHw_TRANSFER_STATUS_ERROR	/* DMA Transfer error */
+} dmacHw_TRANSFER_STATUS_e;
+
+typedef enum {
+	dmacHw_INTERRUPT_DISABLE,	/* Interrupt disable  */
+	dmacHw_INTERRUPT_ENABLE	/* Interrupt enable */
+} dmacHw_INTERRUPT_e;
+
+typedef enum {
+	dmacHw_INTERRUPT_STATUS_NONE = 0x0,	/* No DMA interrupt */
+	dmacHw_INTERRUPT_STATUS_TRANS = 0x1,	/* End of DMA transfer interrupt */
+	dmacHw_INTERRUPT_STATUS_BLOCK = 0x2,	/* End of block transfer interrupt */
+	dmacHw_INTERRUPT_STATUS_ERROR = 0x4	/* Error interrupt */
+} dmacHw_INTERRUPT_STATUS_e;
+
+typedef enum {
+	dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM,	/* Number of DMA channel */
+	dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE,	/* Maximum channel burst size */
+	dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM,	/* Number of DMA master interface */
+	dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH,	/* Channel Data bus width */
+	dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE	/* Channel FIFO size */
+} dmacHw_CONTROLLER_ATTRIB_e;
+
+typedef unsigned long dmacHw_HANDLE_t;	/* DMA channel handle */
+typedef uint32_t dmacHw_ID_t;	/* DMA channel Id.  Must be created using
+				   "dmacHw_MAKE_CHANNEL_ID" macro
+				 */
+/* DMA channel configuration parameters */
+typedef struct {
+	uint32_t srcPeripheralPort;	/* Source peripheral port */
+	uint32_t dstPeripheralPort;	/* Destination peripheral port */
+	uint32_t srcStatusRegisterAddress;	/* Source status register address */
+	uint32_t dstStatusRegisterAddress;	/* Destination status register address of type  */
+
+	uint32_t srcGatherWidth;	/* Number of bytes gathered before successive gather opearation */
+	uint32_t srcGatherJump;	/* Number of bytes jumpped before successive gather opearation */
+	uint32_t dstScatterWidth;	/* Number of bytes sacattered before successive scatter opearation */
+	uint32_t dstScatterJump;	/* Number of bytes jumpped  before successive scatter opearation */
+	uint32_t maxDataPerBlock;	/* Maximum number of bytes to be transferred per block/descrptor.
+					   0 = Maximum possible.
+					 */
+
+	dmacHw_ADDRESS_UPDATE_MODE_e srcUpdate;	/* Source address update mode */
+	dmacHw_ADDRESS_UPDATE_MODE_e dstUpdate;	/* Destination address update mode */
+	dmacHw_TRANSFER_TYPE_e transferType;	/* DMA transfer type  */
+	dmacHw_TRANSFER_MODE_e transferMode;	/* DMA transfer mode */
+	dmacHw_MASTER_INTERFACE_e srcMasterInterface;	/* DMA source interface  */
+	dmacHw_MASTER_INTERFACE_e dstMasterInterface;	/* DMA destination interface */
+	dmacHw_TRANSACTION_WIDTH_e srcMaxTransactionWidth;	/* Source transaction width   */
+	dmacHw_TRANSACTION_WIDTH_e dstMaxTransactionWidth;	/* Destination transaction width */
+	dmacHw_BURST_WIDTH_e srcMaxBurstWidth;	/* Source burst width */
+	dmacHw_BURST_WIDTH_e dstMaxBurstWidth;	/* Destination burst width */
+	dmacHw_INTERRUPT_e blockTransferInterrupt;	/* Block trsnafer interrupt */
+	dmacHw_INTERRUPT_e completeTransferInterrupt;	/* Complete DMA trsnafer interrupt */
+	dmacHw_INTERRUPT_e errorInterrupt;	/* Error interrupt */
+	dmacHw_CHANNEL_PRIORITY_e channelPriority;	/* Channel priority */
+	dmacHw_FLOW_CONTROL_e flowControler;	/* Data flow controller */
+} dmacHw_CONFIG_t;
+
+/****************************************************************************/
+/**
+*  @brief   Initializes DMA
+*
+*  This function initializes DMA CSP driver
+*
+*  @note
+*     Must be called before using any DMA channel
+*/
+/****************************************************************************/
+void dmacHw_initDma(void);
+
+/****************************************************************************/
+/**
+*  @brief   Exit function for  DMA
+*
+*  This function isolates DMA from the system
+*
+*/
+/****************************************************************************/
+void dmacHw_exitDma(void);
+
+/****************************************************************************/
+/**
+*  @brief   Gets a handle to a DMA channel
+*
+*  This function returns a handle, representing a control block of a particular DMA channel
+*
+*  @return  -1       - On Failure
+*            handle  - On Success, representing a channel control block
+*
+*  @note
+*     None  Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId	/* [ IN ] DMA Channel Id */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Initializes a DMA channel for use
+*
+*  This function initializes and resets a DMA channel for use
+*
+*  @return  -1     - On Failure
+*            0     - On Success
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+int dmacHw_initChannel(dmacHw_HANDLE_t handle	/*  [ IN ] DMA Channel handle  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief  Estimates number of descriptor needed to perform certain DMA transfer
+*
+*
+*  @return  On failure : -1
+*           On success : Number of descriptor count
+*
+*
+*/
+/****************************************************************************/
+int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+				    void *pSrcAddr,	/*   [ IN ] Source (Peripheral/Memory) address */
+				    void *pDstAddr,	/*   [ IN ] Destination (Peripheral/Memory) address */
+				    size_t dataLen	/*   [ IN ] Data length in bytes */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Initializes descriptor ring
+*
+*  This function will initializes the descriptor ring of a DMA channel
+*
+*
+*  @return   -1 - On failure
+*             0 - On success
+*  @note
+*     - "len" parameter should be obtained from "dmacHw_descriptorLen"
+*     - Descriptor buffer MUST be 32 bit aligned and uncached as it
+*       is accessed by ARM and DMA
+*/
+/****************************************************************************/
+int dmacHw_initDescriptor(void *pDescriptorVirt,	/*  [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */
+			  uint32_t descriptorPhyAddr,	/*  [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */
+			  uint32_t len,	/*  [ IN ] Size of the pBuf */
+			  uint32_t num	/*  [ IN ] Number of descriptor in the ring */
+    );
+
+/****************************************************************************/
+/**
+*  @brief  Finds amount of memory required to form a descriptor ring
+*
+*
+*  @return   Number of bytes required to form a descriptor ring
+*
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorLen(uint32_t descCnt	/*  [ IN ] Number of descriptor in the ring */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Configure DMA channel
+*
+*  @return  0  : On success
+*           -1 : On failure
+*/
+/****************************************************************************/
+int dmacHw_configChannel(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle  */
+			 dmacHw_CONFIG_t *pConfig	/*   [ IN ] Configuration settings */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Set descriptors for known data length
+*
+*  When DMA has to work as a flow controller, this function prepares the
+*  descriptor chain to transfer data
+*
+*  from:
+*          - Memory to memory
+*          - Peripheral to memory
+*          - Memory to Peripheral
+*          - Peripheral to Peripheral
+*
+*  @return   -1 - On failure
+*             0 - On success
+*
+*/
+/****************************************************************************/
+int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig,	/*  [ IN ] Configuration settings */
+			     void *pDescriptor,	/*  [ IN ] Descriptor buffer  */
+			     void *pSrcAddr,	/*  [ IN ] Source (Peripheral/Memory) address */
+			     void *pDstAddr,	/*  [ IN ] Destination (Peripheral/Memory) address */
+			     size_t dataLen	/*  [ IN ] Length in bytes   */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Indicates whether DMA transfer is in progress or completed
+*
+*  @return   DMA transfer status
+*          dmacHw_TRANSFER_STATUS_BUSY:         DMA Transfer ongoing
+*          dmacHw_TRANSFER_STATUS_DONE:         DMA Transfer completed
+*          dmacHw_TRANSFER_STATUS_ERROR:        DMA Transfer error
+*
+*/
+/****************************************************************************/
+dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Set descriptor carrying control information
+*
+*  This function will be used to send specific control information to the device
+*  using the DMA channel
+*
+*
+*  @return  -1 - On failure
+*            0 - On success
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig,	/*  [ IN ] Configuration settings */
+				void *pDescriptor,	/*  [ IN ] Descriptor buffer  */
+				uint32_t ctlAddress,	/*  [ IN ] Address of the device control register  */
+				uint32_t control	/*  [ IN ] Device control information */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Read data DMA transferred to memory
+*
+*  This function will read data that has been DMAed to memory while transfering from:
+*          - Memory to memory
+*          - Peripheral to memory
+*
+*  @return  0 - No more data is available to read
+*           1 - More data might be available to read
+*
+*/
+/****************************************************************************/
+int dmacHw_readTransferredData(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle    */
+			       dmacHw_CONFIG_t *pConfig,	/*  [ IN ]  Configuration settings */
+			       void *pDescriptor,	/*  [ IN ] Descriptor buffer  */
+			       void **ppBbuf,	/*  [ OUT ] Data received */
+			       size_t *pLlen	/*  [ OUT ] Length of the data received */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Prepares descriptor ring, when source peripheral working as a flow controller
+*
+*  This function will form the descriptor ring by allocating buffers, when source peripheral
+*  has to work as a flow controller to transfer data from:
+*           - Peripheral to memory.
+*
+*  @return  -1 - On failure
+*            0 - On success
+*
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle   */
+				     dmacHw_CONFIG_t *pConfig,	/*  [ IN ] Configuration settings */
+				     void *pDescriptor,	/*  [ IN ] Descriptor buffer  */
+				     uint32_t srcAddr,	/*  [ IN ] Source peripheral address */
+				     void *(*fpAlloc) (int len),	/*  [ IN ] Function pointer  that provides destination memory */
+				     int len,	/*  [ IN ] Number of bytes "fpAlloc" will allocate for destination */
+				     int num	/*  [ IN ] Number of descriptor to set */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Program channel register to initiate transfer
+*
+*  @return  void
+*
+*
+*  @note
+*     - Descriptor buffer MUST ALWAYS be flushed before calling this function
+*     - This function should also be called from ISR to program the channel with
+*       pending descriptors
+*/
+/****************************************************************************/
+void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
+			     dmacHw_CONFIG_t *pConfig,	/*   [ IN ] Configuration settings */
+			     void *pDescriptor	/*   [ IN ] Descriptor buffer  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Resets descriptor control information
+*
+*  @return  void
+*/
+/****************************************************************************/
+void dmacHw_resetDescriptorControl(void *pDescriptor	/*   [ IN ] Descriptor buffer  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Program channel register to stop transfer
+*
+*  Ensures the channel is not doing any transfer after calling this function
+*
+*  @return  void
+*
+*/
+/****************************************************************************/
+void dmacHw_stopTransfer(dmacHw_HANDLE_t handle	/*   [ IN ] DMA Channel handle */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Check the existance of pending descriptor
+*
+*  This function confirmes if there is any pending descriptor in the chain
+*  to program the channel
+*
+*  @return  1 : Channel need to be programmed with pending descriptor
+*           0 : No more pending descriptor to programe the channel
+*
+*  @note
+*     - This function should be called from ISR in case there are pending
+*       descriptor to program the channel.
+*
+*     Example:
+*
+*     dmac_isr ()
+*     {
+*         ...
+*         if (dmacHw_descriptorPending (handle))
+*         {
+*            dmacHw_initiateTransfer (handle);
+*         }
+*     }
+*
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle,	/*   [ IN ] DMA Channel handle */
+				  void *pDescriptor	/*   [ IN ] Descriptor buffer */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Deallocates source or destination memory, allocated
+*
+*  This function can be called to deallocate data memory that was DMAed successfully
+*
+*  @return  -1  - On failure
+*            0  - On success
+*
+*  @note
+*     This function will be called ONLY, when source OR destination address is pointing
+*     to dynamic memory
+*/
+/****************************************************************************/
+int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig,	/*  [ IN ] Configuration settings */
+		   void *pDescriptor,	/*  [ IN ] Descriptor buffer  */
+		   void (*fpFree) (void *)	/*  [ IN ] Function pointer to free data memory */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Clears the interrupt
+*
+*  This function clears the DMA channel specific interrupt
+*
+*  @return   N/A
+*
+*  @note
+*     Must be called under the context of ISR
+*/
+/****************************************************************************/
+void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle	/*  [ IN ] DMA Channel handle  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Returns the cause of channel specific DMA interrupt
+*
+*  This function returns the cause of interrupt
+*
+*  @return  Interrupt status, each bit representing a specific type of interrupt
+*           of type dmacHw_INTERRUPT_STATUS_e
+*  @note
+*           This function should be called under the context of ISR
+*/
+/****************************************************************************/
+dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle	/*  [ IN ] DMA Channel handle  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Indentifies a DMA channel causing interrupt
+*
+*  This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e
+*
+*  @return  NULL   : No channel causing DMA interrupt
+*           ! NULL : Handle to a channel causing DMA interrupt
+*  @note
+*     dmacHw_clearInterrupt() must be called with a valid handle after calling this function
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getInterruptSource(void);
+
+/****************************************************************************/
+/**
+*  @brief   Sets channel specific user data
+*
+*  This function associates user data to a specif DMA channel
+*
+*/
+/****************************************************************************/
+void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle  */
+			       void *userData	/*  [ IN ] User data  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Gets channel specific user data
+*
+*  This function returns user data specific to a DMA channel
+*
+*  @return   user data
+*/
+/****************************************************************************/
+void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle	/*  [ IN ] DMA Channel handle  */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Displays channel specific registers and other control parameters
+*
+*
+*  @return  void
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle,	/*  [ IN ] DMA Channel handle  */
+			   void *pDescriptor,	/*  [ IN ] Descriptor buffer  */
+			   int (*fpPrint) (const char *, ...)	/*  [ IN ] Print callback function */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Provides DMA controller attributes
+*
+*
+*  @return  DMA controller attributes
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle,	/*  [ IN ]  DMA Channel handle  */
+					  dmacHw_CONTROLLER_ATTRIB_e attr	/*  [ IN ]  DMA Controler attribute of type  dmacHw_CONTROLLER_ATTRIB_e */
+    );
+
+#endif /* _DMACHW_H */
diff --git a/arch/arm/mach-bcmring/include/csp/errno.h b/arch/arm/mach-bcmring/include/csp/errno.h
new file mode 100644
index 0000000..51357dd
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/errno.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CSP_ERRNO_H
+#define CSP_ERRNO_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#if   defined(__KERNEL__)
+#include <linux/errno.h>
+#elif defined(CSP_SIMULATION)
+#include <asm-generic/errno.h>
+#else
+#include <errno.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* CSP_ERRNO_H */
diff --git a/arch/arm/mach-bcmring/include/csp/intcHw.h b/arch/arm/mach-bcmring/include/csp/intcHw.h
new file mode 100644
index 0000000..1c639c8
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/intcHw.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+/****************************************************************************/
+/**
+*  @file    intcHw.h
+*
+*  @brief   generic interrupt controller API
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+
+#ifndef _INTCHW_H
+#define _INTCHW_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/csp/intcHw_reg.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+static inline void intcHw_irq_disable(void *basep, uint32_t mask);
+static inline void intcHw_irq_enable(void *basep, uint32_t mask);
+
+#endif /* _INTCHW_H */
+
diff --git a/arch/arm/mach-bcmring/include/csp/module.h b/arch/arm/mach-bcmring/include/csp/module.h
new file mode 100644
index 0000000..c30d2a5
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/module.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+#ifndef CSP_MODULE_H
+#define CSP_MODULE_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#ifdef __KERNEL__
+    #include <linux/module.h>
+#else
+    #define EXPORT_SYMBOL(symbol)
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+
+#endif /* CSP_MODULE_H */
diff --git a/arch/arm/mach-bcmring/include/csp/reg.h b/arch/arm/mach-bcmring/include/csp/reg.h
new file mode 100644
index 0000000..e5f60bf
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/reg.h
@@ -0,0 +1,114 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    reg.h
+*
+*  @brief   Generic register defintions used in CSP
+*/
+/****************************************************************************/
+
+#ifndef CSP_REG_H
+#define CSP_REG_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/stdint.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#define __REG32(x)      (*((volatile uint32_t *)(x)))
+#define __REG16(x)      (*((volatile uint16_t *)(x)))
+#define __REG8(x)       (*((volatile uint8_t *) (x)))
+
+/* Macros used to define a sequence of reserved registers. The start / end */
+/* are byte offsets in the particular register definition, with the "end" */
+/* being the offset of the next un-reserved register. E.g. if offsets */
+/* 0x10 through to 0x1f are reserved, then this reserved area could be */
+/* specified as follows. */
+/*  typedef struct */
+/*  { */
+/*      uint32_t reg1;           offset 0x00 */
+/*      uint32_t reg2;           offset 0x04 */
+/*      uint32_t reg3;           offset 0x08 */
+/*      uint32_t reg4;           offset 0x0c */
+/*      REG32_RSVD(0x10, 0x20); */
+/*      uint32_t reg5;           offset 0x20 */
+/*      ... */
+/*  } EXAMPLE_REG_t; */
+#define REG8_RSVD(start, end)   uint8_t rsvd_##start[(end - start) / sizeof(uint8_t)]
+#define REG16_RSVD(start, end)  uint16_t rsvd_##start[(end - start) / sizeof(uint16_t)]
+#define REG32_RSVD(start, end)  uint32_t rsvd_##start[(end - start) / sizeof(uint32_t)]
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+/* Note: When protecting multiple statements, the REG_LOCAL_IRQ_SAVE and */
+/* REG_LOCAL_IRQ_RESTORE must be enclosed in { } to allow the  */
+/* flags variable to be declared locally. */
+/* e.g. */
+/*    statement1; */
+/*    { */
+/*       REG_LOCAL_IRQ_SAVE; */
+/*       <multiple statements here> */
+/*       REG_LOCAL_IRQ_RESTORE; */
+/*    } */
+/*    statement2; */
+/*  */
+
+#if defined(__KERNEL__) && !defined(STANDALONE)
+#include <mach/hardware.h>
+#include <linux/interrupt.h>
+
+#define REG_LOCAL_IRQ_SAVE      HW_DECLARE_SPINLOCK(reg32) \
+	unsigned long flags; HW_IRQ_SAVE(reg32, flags)
+
+#define REG_LOCAL_IRQ_RESTORE   HW_IRQ_RESTORE(reg32, flags)
+
+#else
+
+#define REG_LOCAL_IRQ_SAVE
+#define REG_LOCAL_IRQ_RESTORE
+
+#endif
+
+static inline void reg32_modify_and(volatile uint32_t *reg, uint32_t value)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*reg &= value;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void reg32_modify_or(volatile uint32_t *reg, uint32_t value)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*reg |= value;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void reg32_modify_mask(volatile uint32_t *reg, uint32_t mask,
+				     uint32_t value)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*reg = (*reg & mask) | value;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void reg32_write(volatile uint32_t *reg, uint32_t value)
+{
+	*reg = value;
+}
+
+#endif /* CSP_REG_H */
diff --git a/arch/arm/mach-bcmring/include/csp/secHw.h b/arch/arm/mach-bcmring/include/csp/secHw.h
new file mode 100644
index 0000000..b9d7e07
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/secHw.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    secHw.h
+*
+*  @brief   Definitions for accessing low level security features
+*
+*/
+/****************************************************************************/
+#ifndef SECHW_H
+#define SECHW_H
+
+typedef void (*secHw_FUNC_t) (void);
+
+typedef enum {
+	secHw_MODE_SECURE = 0x0,	/* Switches processor into secure mode */
+	secHw_MODE_NONSECURE = 0x1	/* Switches processor into non-secure mode */
+} secHw_MODE;
+
+/****************************************************************************/
+/**
+*  @brief   Requesting to execute the function in secure mode
+*
+*  This function requests the given function to run in secure mode
+*
+*/
+/****************************************************************************/
+void secHw_RunSecure(secHw_FUNC_t	/* Function to run in secure mode */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Sets the  mode
+*
+*  his function sets the processor mode (secure/non-secure)
+*
+*/
+/****************************************************************************/
+void secHw_SetMode(secHw_MODE	/* Processor mode */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Get the current mode
+*
+*  This function retieves the processor mode (secure/non-secure)
+*
+*/
+/****************************************************************************/
+void secHw_GetMode(secHw_MODE *);
+
+#endif /* SECHW_H */
diff --git a/arch/arm/mach-bcmring/include/csp/stdint.h b/arch/arm/mach-bcmring/include/csp/stdint.h
new file mode 100644
index 0000000..3a8718b
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/stdint.h
@@ -0,0 +1,30 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CSP_STDINT_H
+#define CSP_STDINT_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* CSP_STDINT_H */
diff --git a/arch/arm/mach-bcmring/include/csp/string.h b/arch/arm/mach-bcmring/include/csp/string.h
new file mode 100644
index 0000000..ad9e400
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/string.h
@@ -0,0 +1,34 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+
+#ifndef CSP_STRING_H
+#define CSP_STRING_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#ifdef __KERNEL__
+   #include <linux/string.h>
+#else
+   #include <string.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+
+#endif /* CSP_STRING_H */
+
diff --git a/arch/arm/mach-bcmring/include/csp/tmrHw.h b/arch/arm/mach-bcmring/include/csp/tmrHw.h
new file mode 100644
index 0000000..f1236d0
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/tmrHw.h
@@ -0,0 +1,263 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    tmrHw.h
+*
+*  @brief   API definitions for low level Timer driver
+*
+*/
+/****************************************************************************/
+#ifndef _TMRHW_H
+#define _TMRHW_H
+
+#include <csp/stdint.h>
+
+typedef uint32_t tmrHw_ID_t;	/* Timer ID */
+typedef uint32_t tmrHw_COUNT_t;	/* Timer count */
+typedef uint32_t tmrHw_INTERVAL_t;	/* Timer interval */
+typedef uint32_t tmrHw_RATE_t;	/* Timer event (count/interrupt) rate */
+
+typedef enum {
+	tmrHw_INTERRUPT_STATUS_SET,	/* Interrupted  */
+	tmrHw_INTERRUPT_STATUS_UNSET	/* No Interrupt */
+} tmrHw_INTERRUPT_STATUS_e;
+
+typedef enum {
+	tmrHw_CAPABILITY_CLOCK,	/* Clock speed in HHz */
+	tmrHw_CAPABILITY_RESOLUTION	/* Timer resolution in bits */
+} tmrHw_CAPABILITY_e;
+
+/****************************************************************************/
+/**
+*  @brief   Get timer capability
+*
+*  This function returns various capabilities/attributes of a timer
+*
+*  @return  Numeric capability
+*
+*/
+/****************************************************************************/
+uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+				  tmrHw_CAPABILITY_e capability	/*  [ IN ] Timer capability */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Configures a periodic timer in terms of timer interrupt rate
+*
+*  This function initializes a periodic timer to generate specific number of
+*  timer interrupt per second
+*
+*  @return   On success: Effective timer frequency
+*            On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+					tmrHw_RATE_t rate	/*  [ IN ] Number of timer interrupt per second */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Configures a periodic timer to generate timer interrupt after
+*           certain time interval
+*
+*  This function initializes a periodic timer to generate timer interrupt
+*  after every time interval in milisecond
+*
+*  @return   On success: Effective interval set in mili-second
+*            On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+						tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in mili-second */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Configures a periodic timer to generate timer interrupt just once
+*           after certain time interval
+*
+*  This function initializes a periodic timer to generate a single ticks after
+*  certain time interval in milisecond
+*
+*  @return   On success: Effective interval set in mili-second
+*            On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+					       tmrHw_INTERVAL_t msec	/*  [ IN ] Interval in mili-second */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Configures a timer to run as a free running timer
+*
+*  This function initializes a timer to run as a free running timer
+*
+*  @return   Timer resolution (count / sec)
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId,	/*  [ IN ] Timer Id */
+				       uint32_t divider	/*  [ IN ] Dividing the clock frequency */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Starts a timer
+*
+*  This function starts a preconfigured timer
+*
+*  @return  -1     - On Failure
+*            0     - On Success
+*/
+/****************************************************************************/
+int tmrHw_startTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Stops a timer
+*
+*  This function stops a running timer
+*
+*  @return  -1     - On Failure
+*            0     - On Success
+*/
+/****************************************************************************/
+int tmrHw_stopTimer(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Gets current timer count
+*
+*  This function returns the current timer value
+*
+*  @return  Current downcounting timer value
+*
+*/
+/****************************************************************************/
+tmrHw_COUNT_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Gets timer count rate
+*
+*  This function returns the number of counts per second
+*
+*  @return  Count rate
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Enables timer interrupt
+*
+*  This function enables the timer interrupt
+*
+*  @return   N/A
+*
+*/
+/****************************************************************************/
+void tmrHw_enableInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Disables timer interrupt
+*
+*  This function disable the timer interrupt
+*
+*  @return   N/A
+*/
+/****************************************************************************/
+void tmrHw_disableInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Clears the interrupt
+*
+*  This function clears the timer interrupt
+*
+*  @return   N/A
+*
+*  @note
+*     Must be called under the context of ISR
+*/
+/****************************************************************************/
+void tmrHw_clearInterrupt(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Gets the interrupt status
+*
+*  This function returns timer interrupt status
+*
+*  @return   Interrupt status
+*/
+/****************************************************************************/
+tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId	/*  [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Indentifies a timer causing interrupt
+*
+*  This functions returns a timer causing interrupt
+*
+*  @return  0xFFFFFFFF   : No timer causing an interrupt
+*           ! 0xFFFFFFFF : timer causing an interrupt
+*  @note
+*     tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function
+*/
+/****************************************************************************/
+tmrHw_ID_t tmrHw_getInterruptSource(void);
+
+/****************************************************************************/
+/**
+*  @brief   Displays specific timer registers
+*
+*
+*  @return  void
+*
+*/
+/****************************************************************************/
+void tmrHw_printDebugInfo(tmrHw_ID_t timerId,	/*  [ IN ] Timer id */
+			  int (*fpPrint) (const char *, ...)	/*  [ IN ] Print callback function */
+);
+
+/****************************************************************************/
+/**
+*  @brief   Use a timer to perform a busy wait delay for a number of usecs.
+*
+*  @return   N/A
+*/
+/****************************************************************************/
+void tmrHw_udelay(tmrHw_ID_t timerId,	/*  [ IN ] Timer id */
+		  unsigned long usecs	/*  [ IN ] usec to delay */
+) __attribute__ ((section(".aramtext")));
+
+#endif /* _TMRHW_H */
diff --git a/arch/arm/mach-bcmring/include/mach/clkdev.h b/arch/arm/mach-bcmring/include/mach/clkdev.h
new file mode 100644
index 0000000..04b37a8
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap.h b/arch/arm/mach-bcmring/include/mach/csp/cap.h
new file mode 100644
index 0000000..30fa2d5
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/cap.h
@@ -0,0 +1,63 @@
+/*****************************************************************************
+* Copyright 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CAP_H
+#define CAP_H
+
+/* ---- Include Files ---------------------------------------------------- */
+/* ---- Public Constants and Types --------------------------------------- */
+typedef enum {
+	CAP_NOT_PRESENT = 0,
+	CAP_PRESENT
+} CAP_RC_T;
+
+typedef enum {
+	CAP_VPM,
+	CAP_ETH_PHY,
+	CAP_ETH_GMII,
+	CAP_ETH_SGMII,
+	CAP_USB,
+	CAP_TSC,
+	CAP_EHSS,
+	CAP_SDIO,
+	CAP_UARTB,
+	CAP_KEYPAD,
+	CAP_CLCD,
+	CAP_GE,
+	CAP_LEDM,
+	CAP_BBL,
+	CAP_VDEC,
+	CAP_PIF,
+	CAP_APM,
+	CAP_SPU,
+	CAP_PKA,
+	CAP_RNG,
+} CAP_CAPABILITY_T;
+
+typedef enum {
+	CAP_LCD_WVGA = 0,
+	CAP_LCD_VGA = 0x1,
+	CAP_LCD_WQVGA = 0x2,
+	CAP_LCD_QVGA = 0x3
+} CAP_LCD_RES_T;
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index);
+static inline uint32_t cap_getMaxArmSpeedHz(void);
+static inline uint32_t cap_getMaxVpmSpeedHz(void);
+static inline CAP_LCD_RES_T cap_getMaxLcdRes(void);
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h
new file mode 100644
index 0000000..933ce68
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h
@@ -0,0 +1,409 @@
+/*****************************************************************************
+* Copyright 2009 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CAP_INLINE_H
+#define CAP_INLINE_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/csp/cap.h>
+#include <cfg_global.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+#define CAP_CONFIG0_VPM_DIS          0x00000001
+#define CAP_CONFIG0_ETH_PHY0_DIS     0x00000002
+#define CAP_CONFIG0_ETH_PHY1_DIS     0x00000004
+#define CAP_CONFIG0_ETH_GMII0_DIS    0x00000008
+#define CAP_CONFIG0_ETH_GMII1_DIS    0x00000010
+#define CAP_CONFIG0_ETH_SGMII0_DIS   0x00000020
+#define CAP_CONFIG0_ETH_SGMII1_DIS   0x00000040
+#define CAP_CONFIG0_USB0_DIS         0x00000080
+#define CAP_CONFIG0_USB1_DIS         0x00000100
+#define CAP_CONFIG0_TSC_DIS          0x00000200
+#define CAP_CONFIG0_EHSS0_DIS        0x00000400
+#define CAP_CONFIG0_EHSS1_DIS        0x00000800
+#define CAP_CONFIG0_SDIO0_DIS        0x00001000
+#define CAP_CONFIG0_SDIO1_DIS        0x00002000
+#define CAP_CONFIG0_UARTB_DIS        0x00004000
+#define CAP_CONFIG0_KEYPAD_DIS       0x00008000
+#define CAP_CONFIG0_CLCD_DIS         0x00010000
+#define CAP_CONFIG0_GE_DIS           0x00020000
+#define CAP_CONFIG0_LEDM_DIS         0x00040000
+#define CAP_CONFIG0_BBL_DIS          0x00080000
+#define CAP_CONFIG0_VDEC_DIS         0x00100000
+#define CAP_CONFIG0_PIF_DIS          0x00200000
+#define CAP_CONFIG0_RESERVED1_DIS    0x00400000
+#define CAP_CONFIG0_RESERVED2_DIS    0x00800000
+
+#define CAP_CONFIG1_APMA_DIS         0x00000001
+#define CAP_CONFIG1_APMB_DIS         0x00000002
+#define CAP_CONFIG1_APMC_DIS         0x00000004
+#define CAP_CONFIG1_CLCD_RES_MASK    0x00000600
+#define CAP_CONFIG1_CLCD_RES_SHIFT   9
+#define CAP_CONFIG1_CLCD_RES_WVGA    (CAP_LCD_WVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+#define CAP_CONFIG1_CLCD_RES_VGA     (CAP_LCD_VGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+#define CAP_CONFIG1_CLCD_RES_WQVGA   (CAP_LCD_WQVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+#define CAP_CONFIG1_CLCD_RES_QVGA    (CAP_LCD_QVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+
+#define CAP_CONFIG2_SPU_DIS          0x00000010
+#define CAP_CONFIG2_PKA_DIS          0x00000020
+#define CAP_CONFIG2_RNG_DIS          0x00000080
+
+#if   (CFG_GLOBAL_CHIP == BCM11107)
+#define capConfig0 0
+#define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA
+#define capConfig2 0
+#define CAP_APM_MAX_NUM_CHANS 3
+#elif (CFG_GLOBAL_CHIP == FPGA11107)
+#define capConfig0 0
+#define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA
+#define capConfig2 0
+#define CAP_APM_MAX_NUM_CHANS 3
+#elif (CFG_GLOBAL_CHIP == BCM11109)
+#define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
+#define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA)
+#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
+#define CAP_APM_MAX_NUM_CHANS 2
+#elif (CFG_GLOBAL_CHIP == BCM11170)
+#define capConfig0 (CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_USB0_DIS | CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_CLCD_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
+#define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA)
+#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
+#define CAP_APM_MAX_NUM_CHANS 2
+#elif (CFG_GLOBAL_CHIP == BCM11110)
+#define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
+#define capConfig1 CAP_CONFIG1_APMC_DIS
+#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
+#define CAP_APM_MAX_NUM_CHANS 2
+#elif (CFG_GLOBAL_CHIP == BCM11211)
+#define capConfig0 (CAP_CONFIG0_ETH_PHY0_DIS | CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_ETH_SGMII0_DIS | CAP_CONFIG0_ETH_SGMII1_DIS | CAP_CONFIG0_CLCD_DIS)
+#define capConfig1 CAP_CONFIG1_APMC_DIS
+#define capConfig2 0
+#define CAP_APM_MAX_NUM_CHANS 2
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+
+#if   ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107))
+#define CAP_HW_CFG_ARM_CLK_HZ 500000000
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+#define CAP_HW_CFG_ARM_CLK_HZ 300000000
+#elif (CFG_GLOBAL_CHIP == BCM11211)
+#define CAP_HW_CFG_ARM_CLK_HZ 666666666
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+
+#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107))
+#define CAP_HW_CFG_VPM_CLK_HZ 333333333
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+#define CAP_HW_CFG_VPM_CLK_HZ 200000000
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+/****************************************************************************
+*  cap_isPresent -
+*
+*  PURPOSE:
+*     Determines if the chip has a certain capability present
+*
+*  PARAMETERS:
+*     capability - type of capability to determine if present
+*
+*  RETURNS:
+*     CAP_PRESENT or CAP_NOT_PRESENT
+****************************************************************************/
+static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index)
+{
+	CAP_RC_T returnVal = CAP_NOT_PRESENT;
+
+	switch (capability) {
+	case CAP_VPM:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_VPM_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_ETH_PHY:
+		{
+			if ((index == 0)
+			    && (!(capConfig0 & CAP_CONFIG0_ETH_PHY0_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 1)
+			    && (!(capConfig0 & CAP_CONFIG0_ETH_PHY1_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_ETH_GMII:
+		{
+			if ((index == 0)
+			    && (!(capConfig0 & CAP_CONFIG0_ETH_GMII0_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 1)
+			    && (!(capConfig0 & CAP_CONFIG0_ETH_GMII1_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_ETH_SGMII:
+		{
+			if ((index == 0)
+			    && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII0_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 1)
+			    && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII1_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_USB:
+		{
+			if ((index == 0)
+			    && (!(capConfig0 & CAP_CONFIG0_USB0_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 1)
+			    && (!(capConfig0 & CAP_CONFIG0_USB1_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_TSC:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_TSC_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_EHSS:
+		{
+			if ((index == 0)
+			    && (!(capConfig0 & CAP_CONFIG0_EHSS0_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 1)
+			    && (!(capConfig0 & CAP_CONFIG0_EHSS1_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_SDIO:
+		{
+			if ((index == 0)
+			    && (!(capConfig0 & CAP_CONFIG0_SDIO0_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 1)
+			    && (!(capConfig0 & CAP_CONFIG0_SDIO1_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_UARTB:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_UARTB_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_KEYPAD:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_KEYPAD_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_CLCD:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_CLCD_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_GE:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_GE_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_LEDM:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_LEDM_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_BBL:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_BBL_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_VDEC:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_VDEC_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_PIF:
+		{
+			if (!(capConfig0 & CAP_CONFIG0_PIF_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_APM:
+		{
+			if ((index == 0)
+			    && (!(capConfig1 & CAP_CONFIG1_APMA_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 1)
+			    && (!(capConfig1 & CAP_CONFIG1_APMB_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+			if ((index == 2)
+			    && (!(capConfig1 & CAP_CONFIG1_APMC_DIS))) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_SPU:
+		{
+			if (!(capConfig2 & CAP_CONFIG2_SPU_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_PKA:
+		{
+			if (!(capConfig2 & CAP_CONFIG2_PKA_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	case CAP_RNG:
+		{
+			if (!(capConfig2 & CAP_CONFIG2_RNG_DIS)) {
+				returnVal = CAP_PRESENT;
+			}
+		}
+		break;
+
+	default:
+		{
+		}
+		break;
+	}
+	return returnVal;
+}
+
+/****************************************************************************
+*  cap_getMaxArmSpeedHz -
+*
+*  PURPOSE:
+*     Determines the maximum speed of the ARM CPU
+*
+*  PARAMETERS:
+*     none
+*
+*  RETURNS:
+*     clock speed in Hz that the ARM processor is able to run at
+****************************************************************************/
+static inline uint32_t cap_getMaxArmSpeedHz(void)
+{
+#if   ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107))
+	return 500000000;
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+	return 300000000;
+#elif (CFG_GLOBAL_CHIP == BCM11211)
+	return 666666666;
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+}
+
+/****************************************************************************
+*  cap_getMaxVpmSpeedHz -
+*
+*  PURPOSE:
+*     Determines the maximum speed of the VPM
+*
+*  PARAMETERS:
+*     none
+*
+*  RETURNS:
+*     clock speed in Hz that the VPM is able to run at
+****************************************************************************/
+static inline uint32_t cap_getMaxVpmSpeedHz(void)
+{
+#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107))
+	return 333333333;
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+	return 200000000;
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+}
+
+/****************************************************************************
+*  cap_getMaxLcdRes -
+*
+*  PURPOSE:
+*     Determines the maximum LCD resolution capabilities
+*
+*  PARAMETERS:
+*     none
+*
+*  RETURNS:
+*   CAP_LCD_WVGA, CAP_LCD_VGA, CAP_LCD_WQVGA or CAP_LCD_QVGA
+*
+****************************************************************************/
+static inline CAP_LCD_RES_T cap_getMaxLcdRes(void)
+{
+	return (CAP_LCD_RES_T)
+		((capConfig1 & CAP_CONFIG1_CLCD_RES_MASK) >>
+		 CAP_CONFIG1_CLCD_RES_SHIFT);
+}
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h
new file mode 100644
index 0000000..70eaea8
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h
@@ -0,0 +1,1123 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CHIPC_DEF_H
+#define CHIPC_DEF_H
+
+/* ---- Include Files ----------------------------------------------------- */
+
+#include <csp/stdint.h>
+#include <csp/errno.h>
+#include <csp/reg.h>
+#include <mach/csp/chipcHw_reg.h>
+
+/* ---- Public Constants and Types ---------------------------------------- */
+
+/* Set 1 to configure DDR/VPM phase alignment by HW */
+#define chipcHw_DDR_HW_PHASE_ALIGN    0
+#define chipcHw_VPM_HW_PHASE_ALIGN    0
+
+typedef uint32_t chipcHw_freq;
+
+/* Configurable miscellaneous clocks */
+typedef enum {
+	chipcHw_CLOCK_DDR,	/* DDR PHY Clock */
+	chipcHw_CLOCK_ARM,	/* ARM Clock */
+	chipcHw_CLOCK_ESW,	/* Ethernet Switch Clock */
+	chipcHw_CLOCK_VPM,	/* VPM Clock */
+	chipcHw_CLOCK_ESW125,	/* Ethernet MII Clock */
+	chipcHw_CLOCK_UART,	/* UART Clock */
+	chipcHw_CLOCK_SDIO0,	/* SDIO 0 Clock */
+	chipcHw_CLOCK_SDIO1,	/* SDIO 1 Clock */
+	chipcHw_CLOCK_SPI,	/* SPI Clock */
+	chipcHw_CLOCK_ETM,	/* ARM ETM Clock */
+
+	chipcHw_CLOCK_BUS,	/* BUS Clock */
+	chipcHw_CLOCK_OTP,	/* OTP Clock */
+	chipcHw_CLOCK_I2C,	/* I2C Host Clock */
+	chipcHw_CLOCK_I2S0,	/* I2S 0 Host Clock */
+	chipcHw_CLOCK_RTBUS,	/* DDR PHY Configuration Clock */
+	chipcHw_CLOCK_APM100,	/* APM100 Clock */
+	chipcHw_CLOCK_TSC,	/* Touch screen Clock */
+	chipcHw_CLOCK_LED,	/* LED Clock */
+
+	chipcHw_CLOCK_USB,	/* USB Clock */
+	chipcHw_CLOCK_LCD,	/* LCD CLock */
+	chipcHw_CLOCK_APM,	/* APM Clock */
+
+	chipcHw_CLOCK_I2S1,	/* I2S 1 Host Clock */
+} chipcHw_CLOCK_e;
+
+/* System booting strap options */
+typedef enum {
+	chipcHw_BOOT_DEVICE_UART = chipcHw_STRAPS_BOOT_DEVICE_UART,
+	chipcHw_BOOT_DEVICE_SERIAL_FLASH =
+	    chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH,
+	chipcHw_BOOT_DEVICE_NOR_FLASH_16 =
+	    chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16,
+	chipcHw_BOOT_DEVICE_NAND_FLASH_8 =
+	    chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8,
+	chipcHw_BOOT_DEVICE_NAND_FLASH_16 =
+	    chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16
+} chipcHw_BOOT_DEVICE_e;
+
+/* System booting modes */
+typedef enum {
+	chipcHw_BOOT_MODE_NORMAL = chipcHw_STRAPS_BOOT_MODE_NORMAL,
+	chipcHw_BOOT_MODE_DBG_SW = chipcHw_STRAPS_BOOT_MODE_DBG_SW,
+	chipcHw_BOOT_MODE_DBG_BOOT = chipcHw_STRAPS_BOOT_MODE_DBG_BOOT,
+	chipcHw_BOOT_MODE_NORMAL_QUIET = chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET
+} chipcHw_BOOT_MODE_e;
+
+/* NAND Flash page size strap options */
+typedef enum {
+	chipcHw_NAND_PAGESIZE_512 = chipcHw_STRAPS_NAND_PAGESIZE_512,
+	chipcHw_NAND_PAGESIZE_2048 = chipcHw_STRAPS_NAND_PAGESIZE_2048,
+	chipcHw_NAND_PAGESIZE_4096 = chipcHw_STRAPS_NAND_PAGESIZE_4096,
+	chipcHw_NAND_PAGESIZE_EXT = chipcHw_STRAPS_NAND_PAGESIZE_EXT
+} chipcHw_NAND_PAGESIZE_e;
+
+/* GPIO Pin function */
+typedef enum {
+	chipcHw_GPIO_FUNCTION_KEYPAD = chipcHw_REG_GPIO_MUX_KEYPAD,
+	chipcHw_GPIO_FUNCTION_I2CH = chipcHw_REG_GPIO_MUX_I2CH,
+	chipcHw_GPIO_FUNCTION_SPI = chipcHw_REG_GPIO_MUX_SPI,
+	chipcHw_GPIO_FUNCTION_UART = chipcHw_REG_GPIO_MUX_UART,
+	chipcHw_GPIO_FUNCTION_LEDMTXP = chipcHw_REG_GPIO_MUX_LEDMTXP,
+	chipcHw_GPIO_FUNCTION_LEDMTXS = chipcHw_REG_GPIO_MUX_LEDMTXS,
+	chipcHw_GPIO_FUNCTION_SDIO0 = chipcHw_REG_GPIO_MUX_SDIO0,
+	chipcHw_GPIO_FUNCTION_SDIO1 = chipcHw_REG_GPIO_MUX_SDIO1,
+	chipcHw_GPIO_FUNCTION_PCM = chipcHw_REG_GPIO_MUX_PCM,
+	chipcHw_GPIO_FUNCTION_I2S = chipcHw_REG_GPIO_MUX_I2S,
+	chipcHw_GPIO_FUNCTION_ETM = chipcHw_REG_GPIO_MUX_ETM,
+	chipcHw_GPIO_FUNCTION_DEBUG = chipcHw_REG_GPIO_MUX_DEBUG,
+	chipcHw_GPIO_FUNCTION_MISC = chipcHw_REG_GPIO_MUX_MISC,
+	chipcHw_GPIO_FUNCTION_GPIO = chipcHw_REG_GPIO_MUX_GPIO
+} chipcHw_GPIO_FUNCTION_e;
+
+/* PIN Output slew rate */
+typedef enum {
+	chipcHw_PIN_SLEW_RATE_HIGH = chipcHw_REG_SLEW_RATE_HIGH,
+	chipcHw_PIN_SLEW_RATE_NORMAL = chipcHw_REG_SLEW_RATE_NORMAL
+} chipcHw_PIN_SLEW_RATE_e;
+
+/* PIN Current drive strength */
+typedef enum {
+	chipcHw_PIN_CURRENT_STRENGTH_2mA = chipcHw_REG_CURRENT_STRENGTH_2mA,
+	chipcHw_PIN_CURRENT_STRENGTH_4mA = chipcHw_REG_CURRENT_STRENGTH_4mA,
+	chipcHw_PIN_CURRENT_STRENGTH_6mA = chipcHw_REG_CURRENT_STRENGTH_6mA,
+	chipcHw_PIN_CURRENT_STRENGTH_8mA = chipcHw_REG_CURRENT_STRENGTH_8mA,
+	chipcHw_PIN_CURRENT_STRENGTH_10mA = chipcHw_REG_CURRENT_STRENGTH_10mA,
+	chipcHw_PIN_CURRENT_STRENGTH_12mA = chipcHw_REG_CURRENT_STRENGTH_12mA
+} chipcHw_PIN_CURRENT_STRENGTH_e;
+
+/* PIN Pull up register settings */
+typedef enum {
+	chipcHw_PIN_PULL_NONE = chipcHw_REG_PULL_NONE,
+	chipcHw_PIN_PULL_UP = chipcHw_REG_PULL_UP,
+	chipcHw_PIN_PULL_DOWN = chipcHw_REG_PULL_DOWN
+} chipcHw_PIN_PULL_e;
+
+/* PIN input type settings */
+typedef enum {
+	chipcHw_PIN_INPUTTYPE_CMOS = chipcHw_REG_INPUTTYPE_CMOS,
+	chipcHw_PIN_INPUTTYPE_ST = chipcHw_REG_INPUTTYPE_ST
+} chipcHw_PIN_INPUTTYPE_e;
+
+/* Allow/Disalow the support of spread spectrum  */
+typedef enum {
+	chipcHw_SPREAD_SPECTRUM_DISALLOW,	/* Spread spectrum support is not allowed */
+	chipcHw_SPREAD_SPECTRUM_ALLOW	/* Spread spectrum support is allowed */
+} chipcHw_SPREAD_SPECTRUM_e;
+
+typedef struct {
+	chipcHw_SPREAD_SPECTRUM_e ssSupport;	/* Allow/Disalow to support spread spectrum.
+						   If supported, call chipcHw_enableSpreadSpectrum ()
+						   to activate the spread spectrum with desired spread. */
+	uint32_t pllVcoFreqHz;	/* PLL VCO frequency in Hz */
+	uint32_t pll2VcoFreqHz;	/* PLL2 VCO frequency in Hz */
+	uint32_t busClockFreqHz;	/* Bus clock frequency in Hz */
+	uint32_t armBusRatio;	/* ARM clock : Bus clock */
+	uint32_t vpmBusRatio;	/* VPM clock : Bus clock */
+	uint32_t ddrBusRatio;	/* DDR clock : Bus clock */
+} chipcHw_INIT_PARAM_t;
+
+/* CHIP revision number */
+typedef enum {
+	chipcHw_REV_NUMBER_A0 = chipcHw_REG_REV_A0,
+	chipcHw_REV_NUMBER_B0 = chipcHw_REG_REV_B0
+} chipcHw_REV_NUMBER_e;
+
+typedef enum {
+	chipcHw_VPM_HW_PHASE_INTR_DISABLE = chipcHw_REG_VPM_INTR_DISABLE,
+	chipcHw_VPM_HW_PHASE_INTR_FAST = chipcHw_REG_VPM_INTR_FAST,
+	chipcHw_VPM_HW_PHASE_INTR_MEDIUM = chipcHw_REG_VPM_INTR_MEDIUM,
+	chipcHw_VPM_HW_PHASE_INTR_SLOW = chipcHw_REG_VPM_INTR_SLOW
+} chipcHw_VPM_HW_PHASE_INTR_e;
+
+typedef enum {
+	chipcHw_DDR_HW_PHASE_MARGIN_STRICT,	/*  Strict margin for DDR phase align condition */
+	chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM,	/*  Medium margin for DDR phase align condition */
+	chipcHw_DDR_HW_PHASE_MARGIN_WIDE	/*  Wider margin for DDR phase align condition */
+} chipcHw_DDR_HW_PHASE_MARGIN_e;
+
+typedef enum {
+	chipcHw_VPM_HW_PHASE_MARGIN_STRICT,	/*  Strict margin for VPM phase align condition */
+	chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM,	/*  Medium margin for VPM phase align condition */
+	chipcHw_VPM_HW_PHASE_MARGIN_WIDE	/*  Wider margin for VPM phase align condition */
+} chipcHw_VPM_HW_PHASE_MARGIN_e;
+
+#define chipcHw_XTAL_FREQ_Hz                    25000000	/* Reference clock frequency in Hz */
+
+/* Programable pin defines */
+#define chipcHw_PIN_GPIO(n)                     ((((n) >= 0) && ((n) < (chipcHw_GPIO_COUNT))) ? (n) : 0xFFFFFFFF)
+									     /* GPIO pin 0 - 60 */
+#define chipcHw_PIN_UARTTXD                     (chipcHw_GPIO_COUNT + 0)	/* UART Transmit */
+#define chipcHw_PIN_NVI_A                       (chipcHw_GPIO_COUNT + 1)	/* NVI Interface */
+#define chipcHw_PIN_NVI_D                       (chipcHw_GPIO_COUNT + 2)	/* NVI Interface */
+#define chipcHw_PIN_NVI_OEB                     (chipcHw_GPIO_COUNT + 3)	/* NVI Interface */
+#define chipcHw_PIN_NVI_WEB                     (chipcHw_GPIO_COUNT + 4)	/* NVI Interface */
+#define chipcHw_PIN_NVI_CS                      (chipcHw_GPIO_COUNT + 5)	/* NVI Interface */
+#define chipcHw_PIN_NVI_NAND_CSB                (chipcHw_GPIO_COUNT + 6)	/* NVI Interface */
+#define chipcHw_PIN_NVI_FLASHWP                 (chipcHw_GPIO_COUNT + 7)	/* NVI Interface */
+#define chipcHw_PIN_NVI_NAND_RDYB               (chipcHw_GPIO_COUNT + 8)	/* NVI Interface */
+#define chipcHw_PIN_CL_DATA_0_17                (chipcHw_GPIO_COUNT + 9)	/* LCD Data 0 - 17 */
+#define chipcHw_PIN_CL_DATA_18_20               (chipcHw_GPIO_COUNT + 10)	/* LCD Data 18 - 20 */
+#define chipcHw_PIN_CL_DATA_21_23               (chipcHw_GPIO_COUNT + 11)	/* LCD Data 21 - 23 */
+#define chipcHw_PIN_CL_POWER                    (chipcHw_GPIO_COUNT + 12)	/* LCD Power */
+#define chipcHw_PIN_CL_ACK                      (chipcHw_GPIO_COUNT + 13)	/* LCD Ack */
+#define chipcHw_PIN_CL_FP                       (chipcHw_GPIO_COUNT + 14)	/* LCD FP */
+#define chipcHw_PIN_CL_LP                       (chipcHw_GPIO_COUNT + 15)	/* LCD LP */
+#define chipcHw_PIN_UARTRXD                     (chipcHw_GPIO_COUNT + 16)	/* UART Receive */
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+/****************************************************************************/
+/**
+*  @brief  Initializes the clock module
+*
+*/
+/****************************************************************************/
+void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam	/*  [ IN ] Misc chip initialization parameter */
+    ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief  Enables the PLL1
+*
+*  This function enables the PLL1
+*
+*/
+/****************************************************************************/
+void chipcHw_pll1Enable(uint32_t vcoFreqHz,	/*  [ IN ] VCO frequency in Hz */
+			chipcHw_SPREAD_SPECTRUM_e ssSupport	/*  [ IN ] SS status */
+    ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief  Enables the PLL2
+*
+*  This function enables the PLL2
+*
+*/
+/****************************************************************************/
+void chipcHw_pll2Enable(uint32_t vcoFreqHz	/*  [ IN ] VCO frequency in Hz */
+    ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief  Disable the PLL1
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll1Disable(void);
+
+/****************************************************************************/
+/**
+*  @brief  Disable the PLL2
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll2Disable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Set clock fequency for miscellaneous configurable clocks
+*
+*  This function sets clock frequency
+*
+*  @return  Configured clock frequency in KHz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock	/*  [ IN ] Configurable clock */
+    ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Set clock fequency for miscellaneous configurable clocks
+*
+*  This function sets clock frequency
+*
+*  @return  Configured clock frequency in Hz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock,	/*  [ IN ] Configurable clock */
+				       uint32_t freq	/*  [ IN ] Clock frequency in Hz */
+    ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+*  @brief   Set VPM clock in sync with BUS clock
+*
+*  This function does the phase adjustment between VPM and BUS clock
+*
+*  @return >= 0 : On success ( # of adjustment required )
+*            -1 : On failure
+*/
+/****************************************************************************/
+int chipcHw_vpmPhaseAlign(void);
+
+/****************************************************************************/
+/**
+*  @brief   Enables core a clock of a certain device
+*
+*  This function enables a core clock
+*
+*  @return  void
+*
+*  @note    Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock	/*  [ IN ] Configurable clock */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Disabled a core clock of a certain device
+*
+*  This function disables a core clock
+*
+*  @return  void
+*
+*  @note    Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock	/*  [ IN ] Configurable clock */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Enables bypass clock of a certain device
+*
+*  This function enables bypass clock
+*
+*  @note    Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock	/*  [ IN ] Configurable clock */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Disabled bypass clock of a certain device
+*
+*  This function disables bypass clock
+*
+*  @note    Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock	/*  [ IN ] Configurable clock */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Get Numeric Chip ID
+*
+*  This function returns Chip ID that includes the revison number
+*
+*  @return  Complete numeric Chip ID
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipId(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get Chip Product ID
+*
+*  This function returns Chip Product ID
+*
+*  @return  Chip Product ID
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipProductId(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get revision number
+*
+*  This function returns revision number of the chip
+*
+*  @return  Revision number
+*/
+/****************************************************************************/
+static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void);
+
+/****************************************************************************/
+/**
+*  @brief   Enables bus interface clock
+*
+*  Enables  bus interface clock of various device
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_BUS_CLOCK_XXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockEnable(uint32_t mask	/*  [ IN ] Bit map of type  chipcHw_REG_BUS_CLOCK_XXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Disables bus interface clock
+*
+*  Disables  bus interface clock of various device
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_BUS_CLOCK_XXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockDisable(uint32_t mask	/*  [ IN ] Bit map of type  chipcHw_REG_BUS_CLOCK_XXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Enables various audio channels
+*
+*  Enables audio channel
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelEnable(uint32_t mask	/*  [ IN ] Bit map of type  chipcHw_REG_AUDIO_CHANNEL_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Disables various audio channels
+*
+*  Disables audio channel
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelDisable(uint32_t mask	/*  [ IN ] Bit map of type  chipcHw_REG_AUDIO_CHANNEL_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief    Soft resets devices
+*
+*  Soft resets various devices
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_SOFT_RESET_XXXXXX defines
+*/
+/****************************************************************************/
+static inline void chipcHw_softReset(uint64_t mask	/*  [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
+    );
+
+static inline void chipcHw_softResetDisable(uint64_t mask	/*  [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
+    );
+
+static inline void chipcHw_softResetEnable(uint64_t mask	/*  [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief    Configures misc CHIP functionality
+*
+*  Configures CHIP functionality
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_MISC_CTRL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_miscControl(uint32_t mask	/*  [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
+    );
+
+static inline void chipcHw_miscControlDisable(uint32_t mask	/*  [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
+    );
+
+static inline void chipcHw_miscControlEnable(uint32_t mask	/*  [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief    Set OTP options
+*
+*  Set OTP options
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_OTP_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setOTPOption(uint64_t mask	/*  [ IN ] Bit map of type chipcHw_REG_OTP_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief    Get sticky bits
+*
+*  @return   Sticky bit options of type chipcHw_REG_STICKY_XXXXXX
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getStickyBits(void);
+
+/****************************************************************************/
+/**
+*  @brief    Set sticky bits
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setStickyBits(uint32_t mask	/*  [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief    Clear sticky bits
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_clearStickyBits(uint32_t mask	/*  [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief    Get software override strap options
+*
+*  Retrieves software override strap options
+*
+*  @return   Software override strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getSoftStraps(void);
+
+/****************************************************************************/
+/**
+*  @brief    Set software override strap options
+*
+*  set software override strap options
+*
+*  @return   nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setSoftStraps(uint32_t strapOptions);
+
+/****************************************************************************/
+/**
+*  @brief    Get pin strap options
+*
+*  Retrieves pin strap options
+*
+*  @return   Pin strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getPinStraps(void);
+
+/****************************************************************************/
+/**
+*  @brief    Get valid pin strap options
+*
+*  Retrieves valid pin strap options
+*
+*  @return   valid Pin strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getValidStraps(void);
+
+/****************************************************************************/
+/**
+*  @brief    Initialize valid pin strap options
+*
+*  Retrieves valid pin strap options by copying HW strap options to soft register
+*  (if chipcHw_STRAPS_SOFT_OVERRIDE not set)
+*
+*  @return   nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_initValidStraps(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get status (enabled/disabled) of bus interface clock
+*
+*  This function returns the status of devices' bus interface clock
+*
+*  @return  Bus interface clock
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getBusInterfaceClockStatus(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get boot device
+*
+*  This function returns the device type used in booting the system
+*
+*  @return  Boot device of type chipcHw_BOOT_DEVICE_e
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get boot mode
+*
+*  This function returns the way the system was booted
+*
+*  @return  Boot mode of type chipcHw_BOOT_MODE_e
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get NAND flash page size
+*
+*  This function returns the NAND device page size
+*
+*  @return  Boot NAND device page size
+*
+*/
+/****************************************************************************/
+static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get NAND flash address cycle configuration
+*
+*  This function returns the NAND flash address cycle configuration
+*
+*  @return  0 = Do not extra address cycle, 1 = Add extra cycle
+*
+*/
+/****************************************************************************/
+static inline int chipcHw_getNandExtraCycle(void);
+
+/****************************************************************************/
+/**
+*  @brief   Activates PIF interface
+*
+*  This function activates PIF interface by taking control of LCD pins
+*
+*  @note
+*       When activated, LCD pins will be defined as follows for PIF operation
+*
+*       CLD[17:0]  = pif_data[17:0]
+*       CLD[23:18] = pif_address[5:0]
+*       CLPOWER    = pif_wr_str
+*       CLCP       = pif_rd_str
+*       CLAC       = pif_hat1
+*       CLFP       = pif_hrdy1
+*       CLLP       = pif_hat2
+*       GPIO[42]   = pif_hrdy2
+*
+*       In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_activatePifInterface(void);
+
+/****************************************************************************/
+/**
+*  @brief   Activates LCD interface
+*
+*  This function activates LCD interface
+*
+*  @note
+*       When activated, LCD pins will be defined as follows
+*
+*       CLD[17:0]  = LCD data
+*       CLD[23:18] = LCD data
+*       CLPOWER    = LCD power
+*       CLCP       =
+*       CLAC       = LCD ack
+*       CLFP       =
+*       CLLP       =
+*/
+/****************************************************************************/
+static inline void chipcHw_activateLcdInterface(void);
+
+/****************************************************************************/
+/**
+*  @brief   Deactivates PIF/LCD interface
+*
+*  This function deactivates PIF/LCD interface
+*
+*  @note
+*       When deactivated LCD pins will be in rti-stated
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_deactivatePifLcdInterface(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get to know the configuration of GPIO pin
+*
+*/
+/****************************************************************************/
+static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin	/* GPIO Pin number */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Configure GPIO pin function
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setGpioPinFunction(int pin,	/* GPIO Pin number */
+					      chipcHw_GPIO_FUNCTION_e func	/* Configuration function */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin slew rate
+*
+*  This function sets the slew of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinSlewRate(uint32_t pin,	/* Pin of type chipcHw_PIN_XXXXX */
+					  chipcHw_PIN_SLEW_RATE_e slewRate	/* Pin slew rate */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin output drive current
+*
+*  This function sets output drive current of individual pin
+*
+*  Note: Avoid the use of the word 'current' since linux headers define this
+*        to be the current task.
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinOutputCurrent(uint32_t pin,	/* Pin of type chipcHw_PIN_XXXXX */
+					       chipcHw_PIN_CURRENT_STRENGTH_e curr	/* Pin current rating */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin pullup register
+*
+*  This function sets pullup register of individual  pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinPullup(uint32_t pin,	/* Pin of type chipcHw_PIN_XXXXX */
+					chipcHw_PIN_PULL_e pullup	/* Pullup register settings */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin input type
+*
+*  This function sets input type of individual Pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinInputType(uint32_t pin,	/* Pin of type chipcHw_PIN_XXXXX */
+					   chipcHw_PIN_INPUTTYPE_e inputType	/* Pin input type */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Retrieves a string representation of the mux setting for a pin.
+*
+*  @return  Pointer to a character string.
+*/
+/****************************************************************************/
+
+const char *chipcHw_getGpioPinFunctionStr(int pin);
+
+/****************************************************************************/
+/**  @brief issue warmReset
+ */
+/****************************************************************************/
+void chipcHw_reset(uint32_t mask);
+
+/****************************************************************************/
+/**  @brief clock reconfigure
+ */
+/****************************************************************************/
+void chipcHw_clockReconfig(uint32_t busHz, uint32_t armRatio, uint32_t vpmRatio,
+			   uint32_t ddrRatio);
+
+/****************************************************************************/
+/**
+*  @brief   Enable Spread Spectrum
+*
+*  @note chipcHw_Init() must be called earlier
+*/
+/****************************************************************************/
+static inline void chipcHw_enableSpreadSpectrum(void);
+
+/****************************************************************************/
+/**
+*  @brief   Disable Spread Spectrum
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_disableSpreadSpectrum(void);
+
+/****************************************************************************/
+/**  @brief Checks if software strap is enabled
+ *
+ *   @return 1 : When enable
+ *           0 : When disable
+ */
+/****************************************************************************/
+static inline int chipcHw_isSoftwareStrapsEnable(void);
+
+/****************************************************************************/
+/**  @brief Enable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsEnable(void);
+
+/****************************************************************************/
+/**  @brief Disable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsDisable(void);
+
+/****************************************************************************/
+/**  @brief PLL test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestEnable(void);
+
+/****************************************************************************/
+/**  @brief PLL2 test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestEnable(void);
+
+/****************************************************************************/
+/**  @brief PLL test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestDisable(void);
+
+/****************************************************************************/
+/**  @brief PLL2 test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestDisable(void);
+
+/****************************************************************************/
+/**  @brief Get PLL test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPllTestEnable(void);
+
+/****************************************************************************/
+/**  @brief Get PLL2 test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPll2TestEnable(void);
+
+/****************************************************************************/
+/**  @brief PLL test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestSelect(uint32_t val);
+
+/****************************************************************************/
+/**  @brief PLL2 test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestSelect(uint32_t val);
+
+/****************************************************************************/
+/**  @brief Get PLL test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPllTestSelected(void);
+
+/****************************************************************************/
+/**  @brief Get PLL2 test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPll2TestSelected(void);
+
+/****************************************************************************/
+/**
+*  @brief   Enables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptEnable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Disables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptDisable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Set VPM SW phase alignment interrupt mode
+*
+*  This function sets VPM phase alignment interrupt
+*
+*/
+/****************************************************************************/
+static inline void
+chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode);
+
+/****************************************************************************/
+/**
+*  @brief   Enable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Disable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Enable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Disable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Enable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Disable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Enable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Disable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Set DDR phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin	/* Margin alinging DDR  phase */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Set VPM phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin	/* Margin alinging VPM  phase */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   Checks DDR phase aligned status done by HW
+*
+*  @return  1: When aligned
+*           0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isDdrHwPhaseAligned(void);
+
+/****************************************************************************/
+/**
+*  @brief   Checks VPM phase aligned status done by HW
+*
+*  @return  1: When aligned
+*           0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isVpmHwPhaseAligned(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get DDR phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get VPM phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get DDR phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrPhaseControl(void);
+
+/****************************************************************************/
+/**
+*  @brief   Get VPM phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmPhaseControl(void);
+
+/****************************************************************************/
+/**
+*  @brief   DDR phase alignment timeout count
+*
+*  @note    If HW fails to perform the phase alignment, it will trigger
+*           a DDR phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle	/* Timeout in bus cycle */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   VPM phase alignment timeout count
+*
+*  @note    If HW fails to perform the phase alignment, it will trigger
+*           a VPM phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle	/* Timeout in bus cycle */
+    );
+
+/****************************************************************************/
+/**
+*  @brief   DDR phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void);
+
+/****************************************************************************/
+/**
+*  @brief   VPM phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void);
+
+/****************************************************************************/
+/**
+*  @brief   DDR phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void);
+
+/****************************************************************************/
+/**
+*  @brief   VPM phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void);
+
+/****************************************************************************/
+/**
+*  @brief   Clear DDR phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void);
+
+/****************************************************************************/
+/**
+*  @brief   Clear VPM phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void);
+
+/* ---- Private Constants and Types -------------------------------------- */
+
+#endif /* CHIPC_DEF_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h
new file mode 100644
index 0000000..c78833a
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h
@@ -0,0 +1,1673 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CHIPC_INLINE_H
+#define CHIPC_INLINE_H
+
+/* ---- Include Files ----------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/reg.h>
+#include <mach/csp/chipcHw_reg.h>
+#include <mach/csp/chipcHw_def.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+typedef enum {
+	chipcHw_OPTYPE_BYPASS,	/* Bypass operation */
+	chipcHw_OPTYPE_OUTPUT	/* Output operation */
+} chipcHw_OPTYPE_e;
+
+/* ---- Public Constants and Types ---------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------- */
+/* ---- Public Function Prototypes ---------------------------------------- */
+/* ---- Private Function Prototypes --------------------------------------- */
+static inline void chipcHw_setClock(chipcHw_CLOCK_e clock,
+				    chipcHw_OPTYPE_e type, int mode);
+
+/****************************************************************************/
+/**
+*  @brief   Get Numeric Chip ID
+*
+*  This function returns Chip ID that includes the revison number
+*
+*  @return  Complete numeric Chip ID
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipId(void)
+{
+	return pChipcHw->ChipId;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enable Spread Spectrum
+*
+*  @note chipcHw_Init() must be called earlier
+*/
+/****************************************************************************/
+static inline void chipcHw_enableSpreadSpectrum(void)
+{
+	if ((pChipcHw->
+	     PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) !=
+	    chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
+		ddrcReg_PHY_ADDR_CTL_REGP->ssCfg =
+		    (0xFFFF << ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT) |
+		    (ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK <<
+		     ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT);
+		ddrcReg_PHY_ADDR_CTL_REGP->ssCtl |=
+		    ddrcReg_PHY_ADDR_SS_CTRL_ENABLE;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disable Spread Spectrum
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_disableSpreadSpectrum(void)
+{
+	ddrcReg_PHY_ADDR_CTL_REGP->ssCtl &= ~ddrcReg_PHY_ADDR_SS_CTRL_ENABLE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get Chip Product ID
+*
+*  This function returns Chip Product ID
+*
+*  @return  Chip Product ID
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipProductId(void)
+{
+	return (pChipcHw->
+		 ChipId & chipcHw_REG_CHIPID_BASE_MASK) >>
+		chipcHw_REG_CHIPID_BASE_SHIFT;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get revision number
+*
+*  This function returns revision number of the chip
+*
+*  @return  Revision number
+*/
+/****************************************************************************/
+static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void)
+{
+	return pChipcHw->ChipId & chipcHw_REG_CHIPID_REV_MASK;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enables bus interface clock
+*
+*  Enables  bus interface clock of various device
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_BUS_CLOCK_XXXX for mask
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockEnable(uint32_t mask)
+{
+	reg32_modify_or(&pChipcHw->BusIntfClock, mask);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disables bus interface clock
+*
+*  Disables  bus interface clock of various device
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_BUS_CLOCK_XXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockDisable(uint32_t mask)
+{
+	reg32_modify_and(&pChipcHw->BusIntfClock, ~mask);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get status (enabled/disabled) of bus interface clock
+*
+*  This function returns the status of devices' bus interface clock
+*
+*  @return  Bus interface clock
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getBusInterfaceClockStatus(void)
+{
+	return pChipcHw->BusIntfClock;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enables various audio channels
+*
+*  Enables audio channel
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelEnable(uint32_t mask)
+{
+	reg32_modify_or(&pChipcHw->AudioEnable, mask);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disables various audio channels
+*
+*  Disables audio channel
+*
+*  @return  void
+*
+*  @note    use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelDisable(uint32_t mask)
+{
+	reg32_modify_and(&pChipcHw->AudioEnable, ~mask);
+}
+
+/****************************************************************************/
+/**
+*  @brief    Soft resets devices
+*
+*  Soft resets various devices
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_SOFT_RESET_XXXXXX defines
+*/
+/****************************************************************************/
+static inline void chipcHw_softReset(uint64_t mask)
+{
+	chipcHw_softResetEnable(mask);
+	chipcHw_softResetDisable(mask);
+}
+
+static inline void chipcHw_softResetDisable(uint64_t mask)
+{
+	uint32_t ctrl1 = (uint32_t) mask;
+	uint32_t ctrl2 = (uint32_t) (mask >> 32);
+
+	/* Deassert module soft reset */
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->SoftReset1 ^= ctrl1;
+	pChipcHw->SoftReset2 ^= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK));
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void chipcHw_softResetEnable(uint64_t mask)
+{
+	uint32_t ctrl1 = (uint32_t) mask;
+	uint32_t ctrl2 = (uint32_t) (mask >> 32);
+	uint32_t unhold = 0;
+
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->SoftReset1 |= ctrl1;
+	/* Mask out unhold request bits */
+	pChipcHw->SoftReset2 |= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK));
+
+	/* Process unhold requests */
+	if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD) {
+		unhold = chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD;
+	}
+
+	if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_UNHOLD) {
+		unhold |= chipcHw_REG_SOFT_RESET_VPM_HOLD;
+	}
+
+	if (ctrl2 & chipcHw_REG_SOFT_RESET_ARM_UNHOLD) {
+		unhold |= chipcHw_REG_SOFT_RESET_ARM_HOLD;
+	}
+
+	if (unhold) {
+		/* Make sure unhold request is effective */
+		pChipcHw->SoftReset1 &= ~unhold;
+	}
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief    Configures misc CHIP functionality
+*
+*  Configures CHIP functionality
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_MISC_CTRL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_miscControl(uint32_t mask)
+{
+	reg32_write(&pChipcHw->MiscCtrl, mask);
+}
+
+static inline void chipcHw_miscControlDisable(uint32_t mask)
+{
+	reg32_modify_and(&pChipcHw->MiscCtrl, ~mask);
+}
+
+static inline void chipcHw_miscControlEnable(uint32_t mask)
+{
+	reg32_modify_or(&pChipcHw->MiscCtrl, mask);
+}
+
+/****************************************************************************/
+/**
+*  @brief    Set OTP options
+*
+*  Set OTP options
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_OTP_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setOTPOption(uint64_t mask)
+{
+	uint32_t ctrl1 = (uint32_t) mask;
+	uint32_t ctrl2 = (uint32_t) (mask >> 32);
+
+	reg32_modify_or(&pChipcHw->SoftOTP1, ctrl1);
+	reg32_modify_or(&pChipcHw->SoftOTP2, ctrl2);
+}
+
+/****************************************************************************/
+/**
+*  @brief    Get sticky bits
+*
+*  @return   Sticky bit options of type chipcHw_REG_STICKY_XXXXXX
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getStickyBits(void)
+{
+	return pChipcHw->Sticky;
+}
+
+/****************************************************************************/
+/**
+*  @brief    Set sticky bits
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setStickyBits(uint32_t mask)
+{
+	uint32_t bits = 0;
+
+	REG_LOCAL_IRQ_SAVE;
+	if (mask & chipcHw_REG_STICKY_POR_BROM) {
+		bits |= chipcHw_REG_STICKY_POR_BROM;
+	} else {
+		uint32_t sticky;
+		sticky = pChipcHw->Sticky;
+
+		if ((mask & chipcHw_REG_STICKY_BOOT_DONE)
+		    && (sticky & chipcHw_REG_STICKY_BOOT_DONE) == 0) {
+			bits |= chipcHw_REG_STICKY_BOOT_DONE;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_1)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_1) == 0) {
+			bits |= chipcHw_REG_STICKY_GENERAL_1;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_2)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_2) == 0) {
+			bits |= chipcHw_REG_STICKY_GENERAL_2;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_3)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_3) == 0) {
+			bits |= chipcHw_REG_STICKY_GENERAL_3;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_4)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_4) == 0) {
+			bits |= chipcHw_REG_STICKY_GENERAL_4;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_5)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_5) == 0) {
+			bits |= chipcHw_REG_STICKY_GENERAL_5;
+		}
+	}
+	pChipcHw->Sticky = bits;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief    Clear sticky bits
+*
+*  @return   void
+*
+*  @note     use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_clearStickyBits(uint32_t mask)
+{
+	uint32_t bits = 0;
+
+	REG_LOCAL_IRQ_SAVE;
+	if (mask &
+	    (chipcHw_REG_STICKY_BOOT_DONE | chipcHw_REG_STICKY_GENERAL_1 |
+	     chipcHw_REG_STICKY_GENERAL_2 | chipcHw_REG_STICKY_GENERAL_3 |
+	     chipcHw_REG_STICKY_GENERAL_4 | chipcHw_REG_STICKY_GENERAL_5)) {
+		uint32_t sticky = pChipcHw->Sticky;
+
+		if ((mask & chipcHw_REG_STICKY_BOOT_DONE)
+		    && (sticky & chipcHw_REG_STICKY_BOOT_DONE)) {
+			bits = chipcHw_REG_STICKY_BOOT_DONE;
+			mask &= ~chipcHw_REG_STICKY_BOOT_DONE;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_1)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_1)) {
+			bits |= chipcHw_REG_STICKY_GENERAL_1;
+			mask &= ~chipcHw_REG_STICKY_GENERAL_1;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_2)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_2)) {
+			bits |= chipcHw_REG_STICKY_GENERAL_2;
+			mask &= ~chipcHw_REG_STICKY_GENERAL_2;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_3)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_3)) {
+			bits |= chipcHw_REG_STICKY_GENERAL_3;
+			mask &= ~chipcHw_REG_STICKY_GENERAL_3;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_4)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_4)) {
+			bits |= chipcHw_REG_STICKY_GENERAL_4;
+			mask &= ~chipcHw_REG_STICKY_GENERAL_4;
+		}
+		if ((mask & chipcHw_REG_STICKY_GENERAL_5)
+		    && (sticky & chipcHw_REG_STICKY_GENERAL_5)) {
+			bits |= chipcHw_REG_STICKY_GENERAL_5;
+			mask &= ~chipcHw_REG_STICKY_GENERAL_5;
+		}
+	}
+	pChipcHw->Sticky = bits | mask;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief    Get software strap value
+*
+*  Retrieves software strap value
+*
+*  @return   Software strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getSoftStraps(void)
+{
+	return pChipcHw->SoftStraps;
+}
+
+/****************************************************************************/
+/**
+*  @brief    Set software override strap options
+*
+*  set software override strap options
+*
+*  @return   nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setSoftStraps(uint32_t strapOptions)
+{
+	reg32_write(&pChipcHw->SoftStraps, strapOptions);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get Pin Strap Options
+*
+*  This function returns the raw boot strap options
+*
+*  @return  strap options
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getPinStraps(void)
+{
+	return pChipcHw->PinStraps;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get Valid Strap Options
+*
+*  This function returns the valid raw boot strap options
+*
+*  @return  strap options
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getValidStraps(void)
+{
+	uint32_t softStraps;
+
+	/*
+	 ** Always return the SoftStraps - bootROM calls chipcHw_initValidStraps
+	 ** which copies HW straps to soft straps if there is no override
+	 */
+	softStraps = chipcHw_getSoftStraps();
+
+	return softStraps;
+}
+
+/****************************************************************************/
+/**
+*  @brief    Initialize valid pin strap options
+*
+*  Retrieves valid pin strap options by copying HW strap options to soft register
+*  (if chipcHw_STRAPS_SOFT_OVERRIDE not set)
+*
+*  @return   nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_initValidStraps(void)
+{
+	uint32_t softStraps;
+
+	REG_LOCAL_IRQ_SAVE;
+	softStraps = chipcHw_getSoftStraps();
+
+	if ((softStraps & chipcHw_STRAPS_SOFT_OVERRIDE) == 0) {
+		/* Copy HW straps to software straps */
+		chipcHw_setSoftStraps(chipcHw_getPinStraps());
+	}
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get boot device
+*
+*  This function returns the device type used in booting the system
+*
+*  @return  Boot device of type chipcHw_BOOT_DEVICE
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void)
+{
+	return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_DEVICE_MASK;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get boot mode
+*
+*  This function returns the way the system was booted
+*
+*  @return  Boot mode of type chipcHw_BOOT_MODE
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void)
+{
+	return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_MODE_MASK;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get NAND flash page size
+*
+*  This function returns the NAND device page size
+*
+*  @return  Boot NAND device page size
+*
+*/
+/****************************************************************************/
+static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void)
+{
+	return chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_PAGESIZE_MASK;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get NAND flash address cycle configuration
+*
+*  This function returns the NAND flash address cycle configuration
+*
+*  @return  0 = Do not extra address cycle, 1 = Add extra cycle
+*
+*/
+/****************************************************************************/
+static inline int chipcHw_getNandExtraCycle(void)
+{
+	if (chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_EXTRA_CYCLE) {
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Activates PIF interface
+*
+*  This function activates PIF interface by taking control of LCD pins
+*
+*  @note
+*       When activated, LCD pins will be defined as follows for PIF operation
+*
+*       CLD[17:0]  = pif_data[17:0]
+*       CLD[23:18] = pif_address[5:0]
+*       CLPOWER    = pif_wr_str
+*       CLCP       = pif_rd_str
+*       CLAC       = pif_hat1
+*       CLFP       = pif_hrdy1
+*       CLLP       = pif_hat2
+*       GPIO[42]   = pif_hrdy2
+*
+*       In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_activatePifInterface(void)
+{
+	reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_PIF_PIN_ENABLE);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Activates LCD interface
+*
+*  This function activates LCD interface
+*
+*  @note
+*       When activated, LCD pins will be defined as follows
+*
+*       CLD[17:0]  = LCD data
+*       CLD[23:18] = LCD data
+*       CLPOWER    = LCD power
+*       CLCP       =
+*       CLAC       = LCD ack
+*       CLFP       =
+*       CLLP       =
+*/
+/****************************************************************************/
+static inline void chipcHw_activateLcdInterface(void)
+{
+	reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_LCD_PIN_ENABLE);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Deactivates PIF/LCD interface
+*
+*  This function deactivates PIF/LCD interface
+*
+*  @note
+*       When deactivated LCD pins will be in rti-stated
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_deactivatePifLcdInterface(void)
+{
+	reg32_write(&pChipcHw->LcdPifMode, 0);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Select GE2
+*
+*  This function select GE2 as the graphic engine
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_selectGE2(void)
+{
+	reg32_modify_and(&pChipcHw->MiscCtrl, ~chipcHw_REG_MISC_CTRL_GE_SEL);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Select GE3
+*
+*  This function select GE3 as the graphic engine
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_selectGE3(void)
+{
+	reg32_modify_or(&pChipcHw->MiscCtrl, chipcHw_REG_MISC_CTRL_GE_SEL);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get to know the configuration of GPIO pin
+*
+*/
+/****************************************************************************/
+static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin)
+{
+	return (*((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) &
+		(chipcHw_REG_GPIO_MUX_MASK <<
+		 chipcHw_REG_GPIO_MUX_POSITION(pin))) >>
+	    chipcHw_REG_GPIO_MUX_POSITION(pin);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Configure GPIO pin function
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setGpioPinFunction(int pin,
+					      chipcHw_GPIO_FUNCTION_e func)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) &=
+	    ~(chipcHw_REG_GPIO_MUX_MASK << chipcHw_REG_GPIO_MUX_POSITION(pin));
+	*((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) |=
+	    func << chipcHw_REG_GPIO_MUX_POSITION(pin);
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin slew rate
+*
+*  This function sets the slew of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinSlewRate(uint32_t pin,
+					  chipcHw_PIN_SLEW_RATE_e slewRate)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) &=
+	    ~(chipcHw_REG_SLEW_RATE_MASK <<
+	      chipcHw_REG_SLEW_RATE_POSITION(pin));
+	*((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) |=
+	    (uint32_t) slewRate << chipcHw_REG_SLEW_RATE_POSITION(pin);
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin output drive current
+*
+*  This function sets output drive current of individual pin
+*
+*  Note: Avoid the use of the word 'current' since linux headers define this
+*        to be the current task.
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinOutputCurrent(uint32_t pin,
+					       chipcHw_PIN_CURRENT_STRENGTH_e
+					       curr)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*((uint32_t *) chipcHw_REG_CURRENT(pin)) &=
+	    ~(chipcHw_REG_CURRENT_MASK << chipcHw_REG_CURRENT_POSITION(pin));
+	*((uint32_t *) chipcHw_REG_CURRENT(pin)) |=
+	    (uint32_t) curr << chipcHw_REG_CURRENT_POSITION(pin);
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin pullup register
+*
+*  This function sets pullup register of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinPullup(uint32_t pin, chipcHw_PIN_PULL_e pullup)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*((uint32_t *) chipcHw_REG_PULLUP(pin)) &=
+	    ~(chipcHw_REG_PULLUP_MASK << chipcHw_REG_PULLUP_POSITION(pin));
+	*((uint32_t *) chipcHw_REG_PULLUP(pin)) |=
+	    (uint32_t) pullup << chipcHw_REG_PULLUP_POSITION(pin);
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set Pin input type
+*
+*  This function sets input type of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinInputType(uint32_t pin,
+					   chipcHw_PIN_INPUTTYPE_e inputType)
+{
+	REG_LOCAL_IRQ_SAVE;
+	*((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) &=
+	    ~(chipcHw_REG_INPUTTYPE_MASK <<
+	      chipcHw_REG_INPUTTYPE_POSITION(pin));
+	*((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) |=
+	    (uint32_t) inputType << chipcHw_REG_INPUTTYPE_POSITION(pin);
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Power up the USB PHY
+*
+*  This function powers up the USB PHY
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_powerUpUsbPhy(void)
+{
+	reg32_modify_and(&pChipcHw->MiscCtrl,
+			 chipcHw_REG_MISC_CTRL_USB_POWERON);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Power down the USB PHY
+*
+*  This function powers down the USB PHY
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_powerDownUsbPhy(void)
+{
+	reg32_modify_or(&pChipcHw->MiscCtrl,
+			chipcHw_REG_MISC_CTRL_USB_POWEROFF);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set the 2nd USB as host
+*
+*  This function sets the 2nd USB as host
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setUsbHost(void)
+{
+	reg32_modify_or(&pChipcHw->MiscCtrl,
+			chipcHw_REG_MISC_CTRL_USB_MODE_HOST);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set the 2nd USB as device
+*
+*  This function sets the 2nd USB as device
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setUsbDevice(void)
+{
+	reg32_modify_and(&pChipcHw->MiscCtrl,
+			 chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Lower layer funtion to enable/disable a clock of a certain device
+*
+*  This function enables/disables a core clock
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setClock(chipcHw_CLOCK_e clock,
+				    chipcHw_OPTYPE_e type, int mode)
+{
+	volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
+	volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
+
+	switch (clock) {
+	case chipcHw_CLOCK_DDR:
+		pPLLReg = &pChipcHw->DDRClock;
+		break;
+	case chipcHw_CLOCK_ARM:
+		pPLLReg = &pChipcHw->ARMClock;
+		break;
+	case chipcHw_CLOCK_ESW:
+		pPLLReg = &pChipcHw->ESWClock;
+		break;
+	case chipcHw_CLOCK_VPM:
+		pPLLReg = &pChipcHw->VPMClock;
+		break;
+	case chipcHw_CLOCK_ESW125:
+		pPLLReg = &pChipcHw->ESW125Clock;
+		break;
+	case chipcHw_CLOCK_UART:
+		pPLLReg = &pChipcHw->UARTClock;
+		break;
+	case chipcHw_CLOCK_SDIO0:
+		pPLLReg = &pChipcHw->SDIO0Clock;
+		break;
+	case chipcHw_CLOCK_SDIO1:
+		pPLLReg = &pChipcHw->SDIO1Clock;
+		break;
+	case chipcHw_CLOCK_SPI:
+		pPLLReg = &pChipcHw->SPIClock;
+		break;
+	case chipcHw_CLOCK_ETM:
+		pPLLReg = &pChipcHw->ETMClock;
+		break;
+	case chipcHw_CLOCK_USB:
+		pPLLReg = &pChipcHw->USBClock;
+		if (type == chipcHw_OPTYPE_OUTPUT) {
+			if (mode) {
+				reg32_modify_and(pPLLReg,
+						 ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+			} else {
+				reg32_modify_or(pPLLReg,
+						chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+			}
+		}
+		break;
+	case chipcHw_CLOCK_LCD:
+		pPLLReg = &pChipcHw->LCDClock;
+		if (type == chipcHw_OPTYPE_OUTPUT) {
+			if (mode) {
+				reg32_modify_and(pPLLReg,
+						 ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+			} else {
+				reg32_modify_or(pPLLReg,
+						chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+			}
+		}
+		break;
+	case chipcHw_CLOCK_APM:
+		pPLLReg = &pChipcHw->APMClock;
+		if (type == chipcHw_OPTYPE_OUTPUT) {
+			if (mode) {
+				reg32_modify_and(pPLLReg,
+						 ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+			} else {
+				reg32_modify_or(pPLLReg,
+						chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+			}
+		}
+		break;
+	case chipcHw_CLOCK_BUS:
+		pClockCtrl = &pChipcHw->ACLKClock;
+		break;
+	case chipcHw_CLOCK_OTP:
+		pClockCtrl = &pChipcHw->OTPClock;
+		break;
+	case chipcHw_CLOCK_I2C:
+		pClockCtrl = &pChipcHw->I2CClock;
+		break;
+	case chipcHw_CLOCK_I2S0:
+		pClockCtrl = &pChipcHw->I2S0Clock;
+		break;
+	case chipcHw_CLOCK_RTBUS:
+		pClockCtrl = &pChipcHw->RTBUSClock;
+		break;
+	case chipcHw_CLOCK_APM100:
+		pClockCtrl = &pChipcHw->APM100Clock;
+		break;
+	case chipcHw_CLOCK_TSC:
+		pClockCtrl = &pChipcHw->TSCClock;
+		break;
+	case chipcHw_CLOCK_LED:
+		pClockCtrl = &pChipcHw->LEDClock;
+		break;
+	case chipcHw_CLOCK_I2S1:
+		pClockCtrl = &pChipcHw->I2S1Clock;
+		break;
+	}
+
+	if (pPLLReg) {
+		switch (type) {
+		case chipcHw_OPTYPE_OUTPUT:
+			/* PLL clock output enable/disable */
+			if (mode) {
+				if (clock == chipcHw_CLOCK_DDR) {
+					/* DDR clock enable is inverted */
+					reg32_modify_and(pPLLReg,
+							 ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+				} else {
+					reg32_modify_or(pPLLReg,
+							chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+				}
+			} else {
+				if (clock == chipcHw_CLOCK_DDR) {
+					/* DDR clock disable is inverted */
+					reg32_modify_or(pPLLReg,
+							chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+				} else {
+					reg32_modify_and(pPLLReg,
+							 ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+				}
+			}
+			break;
+		case chipcHw_OPTYPE_BYPASS:
+			/* PLL clock bypass enable/disable */
+			if (mode) {
+				reg32_modify_or(pPLLReg,
+						chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+			} else {
+				reg32_modify_and(pPLLReg,
+						 ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+			}
+			break;
+		}
+	} else if (pClockCtrl) {
+		switch (type) {
+		case chipcHw_OPTYPE_OUTPUT:
+			if (mode) {
+				reg32_modify_or(pClockCtrl,
+						chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE);
+			} else {
+				reg32_modify_and(pClockCtrl,
+						 ~chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE);
+			}
+			break;
+		case chipcHw_OPTYPE_BYPASS:
+			if (mode) {
+				reg32_modify_or(pClockCtrl,
+						chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
+			} else {
+				reg32_modify_and(pClockCtrl,
+						 ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
+			}
+			break;
+		}
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disables a core clock of a certain device
+*
+*  This function disables a core clock
+*
+*  @note    no change in power consumption
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock)
+{
+
+	/* Disable output of the clock */
+	chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 0);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enable a core clock of a certain device
+*
+*  This function enables a core clock
+*
+*  @note    no change in power consumption
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock)
+{
+
+	/* Enable output of the clock */
+	chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 1);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enables bypass clock of a certain device
+*
+*  This function enables bypass clock
+*
+*  @note    Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock)
+{
+	/* Enable bypass clock */
+	chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 1);
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disabled bypass clock of a certain device
+*
+*  This function disables bypass clock
+*
+*  @note    Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock)
+{
+	/* Disable bypass clock */
+	chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 0);
+
+}
+
+/****************************************************************************/
+/**  @brief Checks if software strap is enabled
+ *
+ *   @return 1 : When enable
+ *           0 : When disable
+ */
+/****************************************************************************/
+static inline int chipcHw_isSoftwareStrapsEnable(void)
+{
+	return pChipcHw->SoftStraps & 0x00000001;
+}
+
+/****************************************************************************/
+/**  @brief Enable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsEnable(void)
+{
+	reg32_modify_or(&pChipcHw->SoftStraps, 0x00000001);
+}
+
+/****************************************************************************/
+/**  @brief Disable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsDisable(void)
+{
+	reg32_modify_and(&pChipcHw->SoftStraps, (~0x00000001));
+}
+
+/****************************************************************************/
+/**  @brief PLL test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestEnable(void)
+{
+	reg32_modify_or(&pChipcHw->PLLConfig,
+			chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/**  @brief PLL2 test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestEnable(void)
+{
+	reg32_modify_or(&pChipcHw->PLLConfig2,
+			chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/**  @brief PLL test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestDisable(void)
+{
+	reg32_modify_and(&pChipcHw->PLLConfig,
+			 ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/**  @brief PLL2 test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestDisable(void)
+{
+	reg32_modify_and(&pChipcHw->PLLConfig2,
+			 ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/**  @brief Get PLL test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPllTestEnable(void)
+{
+	return pChipcHw->PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_ENABLE;
+}
+
+/****************************************************************************/
+/**  @brief Get PLL2 test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPll2TestEnable(void)
+{
+	return pChipcHw->PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_ENABLE;
+}
+
+/****************************************************************************/
+/**  @brief PLL test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestSelect(uint32_t val)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK;
+	pChipcHw->PLLConfig |=
+	    (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**  @brief PLL2 test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestSelect(uint32_t val)
+{
+
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK;
+	pChipcHw->PLLConfig2 |=
+	    (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**  @brief Get PLL test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPllTestSelected(void)
+{
+	return (uint8_t) ((pChipcHw->
+			   PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK)
+			  >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT);
+}
+
+/****************************************************************************/
+/**  @brief Get PLL2 test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPll2TestSelected(void)
+{
+	return (uint8_t) ((pChipcHw->
+			   PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK)
+			  >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT);
+}
+
+/****************************************************************************/
+/**
+*  @brief  Disable the PLL1
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll1Disable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->PLLConfig |= chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief  Disable the PLL2
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll2Disable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->PLLConfig2 |= chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptEnable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->Spare1 |= chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptDisable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set VPM SW phase alignment interrupt mode
+*
+*  This function sets VPM phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void
+chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode)
+{
+	REG_LOCAL_IRQ_SAVE;
+	if (mode == chipcHw_VPM_HW_PHASE_INTR_DISABLE) {
+		pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE;
+	} else {
+		pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE;
+	}
+	pChipcHw->VPMPhaseCtrl2 =
+	    (pChipcHw->
+	     VPMPhaseCtrl2 & ~(chipcHw_REG_VPM_INTR_SELECT_MASK <<
+			       chipcHw_REG_VPM_INTR_SELECT_SHIFT)) | mode;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignEnable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignDisable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignEnable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignDisable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignEnable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignDisable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Enable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignEnable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Disable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignDisable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set DDR phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void
+chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin)
+{
+	uint32_t ge = 0;
+	uint32_t le = 0;
+
+	switch (margin) {
+	case chipcHw_DDR_HW_PHASE_MARGIN_STRICT:
+		ge = 0x0F;
+		le = 0x0F;
+		break;
+	case chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM:
+		ge = 0x03;
+		le = 0x3F;
+		break;
+	case chipcHw_DDR_HW_PHASE_MARGIN_WIDE:
+		ge = 0x01;
+		le = 0x7F;
+		break;
+	}
+
+	{
+		REG_LOCAL_IRQ_SAVE;
+
+		pChipcHw->DDRPhaseCtrl1 &=
+		    ~((chipcHw_REG_DDR_PHASE_VALUE_GE_MASK <<
+		       chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT)
+		      || (chipcHw_REG_DDR_PHASE_VALUE_LE_MASK <<
+			  chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT));
+
+		pChipcHw->DDRPhaseCtrl1 |=
+		    ((ge << chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT)
+		     || (le << chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT));
+
+		REG_LOCAL_IRQ_RESTORE;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Set VPM phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void
+chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin)
+{
+	uint32_t ge = 0;
+	uint32_t le = 0;
+
+	switch (margin) {
+	case chipcHw_VPM_HW_PHASE_MARGIN_STRICT:
+		ge = 0x0F;
+		le = 0x0F;
+		break;
+	case chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM:
+		ge = 0x03;
+		le = 0x3F;
+		break;
+	case chipcHw_VPM_HW_PHASE_MARGIN_WIDE:
+		ge = 0x01;
+		le = 0x7F;
+		break;
+	}
+
+	{
+		REG_LOCAL_IRQ_SAVE;
+
+		pChipcHw->VPMPhaseCtrl1 &=
+		    ~((chipcHw_REG_VPM_PHASE_VALUE_GE_MASK <<
+		       chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT)
+		      || (chipcHw_REG_VPM_PHASE_VALUE_LE_MASK <<
+			  chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT));
+
+		pChipcHw->VPMPhaseCtrl1 |=
+		    ((ge << chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT)
+		     || (le << chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT));
+
+		REG_LOCAL_IRQ_RESTORE;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief   Checks DDR phase aligned status done by HW
+*
+*  @return  1: When aligned
+*           0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isDdrHwPhaseAligned(void)
+{
+	return (pChipcHw->
+		PhaseAlignStatus & chipcHw_REG_DDR_PHASE_ALIGNED) ? 1 : 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Checks VPM phase aligned status done by HW
+*
+*  @return  1: When aligned
+*           0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isVpmHwPhaseAligned(void)
+{
+	return (pChipcHw->
+		PhaseAlignStatus & chipcHw_REG_VPM_PHASE_ALIGNED) ? 1 : 0;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get DDR phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void)
+{
+	return (pChipcHw->
+		PhaseAlignStatus & chipcHw_REG_DDR_PHASE_STATUS_MASK) >>
+	    chipcHw_REG_DDR_PHASE_STATUS_SHIFT;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get VPM phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void)
+{
+	return (pChipcHw->
+		PhaseAlignStatus & chipcHw_REG_VPM_PHASE_STATUS_MASK) >>
+	    chipcHw_REG_VPM_PHASE_STATUS_SHIFT;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get DDR phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrPhaseControl(void)
+{
+	return (pChipcHw->
+		PhaseAlignStatus & chipcHw_REG_DDR_PHASE_CTRL_MASK) >>
+	    chipcHw_REG_DDR_PHASE_CTRL_SHIFT;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get VPM phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmPhaseControl(void)
+{
+	return (pChipcHw->
+		PhaseAlignStatus & chipcHw_REG_VPM_PHASE_CTRL_MASK) >>
+	    chipcHw_REG_VPM_PHASE_CTRL_SHIFT;
+}
+
+/****************************************************************************/
+/**
+*  @brief   DDR phase alignment timeout count
+*
+*  @note    If HW fails to perform the phase alignment, it will trigger
+*           a DDR phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->DDRPhaseCtrl2 &=
+	    ~(chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK <<
+	      chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT);
+	pChipcHw->DDRPhaseCtrl2 |=
+	    (busCycle & chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK) <<
+	    chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   VPM phase alignment timeout count
+*
+*  @note    If HW fails to perform the phase alignment, it will trigger
+*           a VPM phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->VPMPhaseCtrl2 &=
+	    ~(chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK <<
+	      chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT);
+	pChipcHw->VPMPhaseCtrl2 |=
+	    (busCycle & chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK) <<
+	    chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Clear DDR phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	/* Clear timeout interrupt service bit */
+	pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_INTR_SERVICED;
+	pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_INTR_SERVICED;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Clear VPM phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	/* Clear timeout interrupt service bit */
+	pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_INTR_SERVICED;
+	pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_INTR_SERVICED;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   DDR phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	chipcHw_ddrHwPhaseAlignTimeoutInterruptClear();	/* Recommended */
+	/* Enable timeout interrupt */
+	pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   VPM phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	chipcHw_vpmHwPhaseAlignTimeoutInterruptClear();	/* Recommended */
+	/* Enable timeout interrupt */
+	pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   DDR phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+*  @brief   VPM phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void)
+{
+	REG_LOCAL_IRQ_SAVE;
+	pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE;
+	REG_LOCAL_IRQ_RESTORE;
+}
+
+#endif /* CHIPC_INLINE_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h
new file mode 100644
index 0000000..b162448
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h
@@ -0,0 +1,530 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    chipcHw_reg.h
+*
+*  @brief   Definitions for low level chip control registers
+*
+*/
+/****************************************************************************/
+#ifndef CHIPCHW_REG_H
+#define CHIPCHW_REG_H
+
+#include <mach/csp/mm_io.h>
+#include <csp/reg.h>
+#include <mach/csp/ddrcReg.h>
+
+#define chipcHw_BASE_ADDRESS    MM_IO_BASE_CHIPC
+
+typedef struct {
+	uint32_t ChipId;	/* Chip ID */
+	uint32_t DDRClock;	/* PLL1 Channel 1 for DDR clock */
+	uint32_t ARMClock;	/* PLL1 Channel 2 for ARM clock */
+	uint32_t ESWClock;	/* PLL1 Channel 3 for ESW system clock */
+	uint32_t VPMClock;	/* PLL1 Channel 4 for VPM clock */
+	uint32_t ESW125Clock;	/* PLL1 Channel 5 for ESW 125MHz clock */
+	uint32_t UARTClock;	/* PLL1 Channel 6 for UART clock */
+	uint32_t SDIO0Clock;	/* PLL1 Channel 7 for SDIO 0 clock */
+	uint32_t SDIO1Clock;	/* PLL1 Channel 8 for SDIO 1 clock */
+	uint32_t SPIClock;	/* PLL1 Channel 9 for SPI master Clock  */
+	uint32_t ETMClock;	/* PLL1 Channel 10 for ARM ETM Clock  */
+
+	uint32_t ACLKClock;	/* ACLK Clock (Divider) */
+	uint32_t OTPClock;	/* OTP Clock  (Divider) */
+	uint32_t I2CClock;	/* I2C Clock (CK_13m) (Divider) */
+	uint32_t I2S0Clock;	/* I2S0 Clock (Divider) */
+	uint32_t RTBUSClock;	/* RTBUS (DDR PHY Config.) Clock (Divider) */
+	uint32_t pad1;
+	uint32_t APM100Clock;	/* APM 100MHz CLK Clock (Divider) */
+	uint32_t TSCClock;	/* TSC Clock (Divider) */
+	uint32_t LEDClock;	/* LED Clock (Divider) */
+
+	uint32_t USBClock;	/* PLL2 Channel 1 for USB clock */
+	uint32_t LCDClock;	/* PLL2 Channel 2 for LCD clock */
+	uint32_t APMClock;	/* PLL2 Channel 3 for APM 200 MHz clock */
+
+	uint32_t BusIntfClock;	/* Bus interface clock */
+
+	uint32_t PLLStatus;	/* PLL status register (PLL1) */
+	uint32_t PLLConfig;	/* PLL configuration register  (PLL1) */
+	uint32_t PLLPreDivider;	/* PLL pre-divider control register (PLL1) */
+	uint32_t PLLDivider;	/* PLL divider control register (PLL1) */
+	uint32_t PLLControl1;	/* PLL analog control register #1 (PLL1) */
+	uint32_t PLLControl2;	/* PLL analog control register #2 (PLL1) */
+
+	uint32_t I2S1Clock;	/* I2S1 Clock  */
+	uint32_t AudioEnable;	/* Enable/ disable audio channel */
+	uint32_t SoftReset1;	/* Reset blocks */
+	uint32_t SoftReset2;	/* Reset blocks */
+	uint32_t Spare1;	/* Phase align interrupts */
+	uint32_t Sticky;	/* Sticky bits */
+	uint32_t MiscCtrl;	/* Misc. control */
+	uint32_t pad3[3];
+
+	uint32_t PLLStatus2;	/* PLL status register (PLL2) */
+	uint32_t PLLConfig2;	/* PLL configuration register  (PLL2) */
+	uint32_t PLLPreDivider2;	/* PLL pre-divider control register (PLL2) */
+	uint32_t PLLDivider2;	/* PLL divider control register (PLL2) */
+	uint32_t PLLControl12;	/* PLL analog control register #1 (PLL2) */
+	uint32_t PLLControl22;	/* PLL analog control register #2 (PLL2) */
+
+	uint32_t DDRPhaseCtrl1;	/* DDR Clock Phase Alignment control1 */
+	uint32_t VPMPhaseCtrl1;	/* VPM Clock Phase Alignment control1 */
+	uint32_t PhaseAlignStatus;	/* DDR/VPM Clock Phase Alignment Status */
+	uint32_t PhaseCtrlStatus;	/* DDR/VPM Clock HW DDR/VPM ph_ctrl and load_ch Status */
+	uint32_t DDRPhaseCtrl2;	/* DDR Clock Phase Alignment control2 */
+	uint32_t VPMPhaseCtrl2;	/* VPM Clock Phase Alignment control2 */
+	uint32_t pad4[9];
+
+	uint32_t SoftOTP1;	/* Software OTP control */
+	uint32_t SoftOTP2;	/* Software OTP control */
+	uint32_t SoftStraps;	/* Software strap */
+	uint32_t PinStraps;	/* Pin Straps */
+	uint32_t DiffOscCtrl;	/* Diff oscillator control */
+	uint32_t DiagsCtrl;	/* Diagnostic control */
+	uint32_t DiagsOutputCtrl;	/* Diagnostic output enable */
+	uint32_t DiagsReadBackCtrl;	/* Diagnostic read back control */
+
+	uint32_t LcdPifMode;	/* LCD/PIF Pin Sharing MUX Mode */
+
+	uint32_t GpioMux_0_7;	/* Pin Sharing MUX0 Control */
+	uint32_t GpioMux_8_15;	/* Pin Sharing MUX1 Control */
+	uint32_t GpioMux_16_23;	/* Pin Sharing MUX2 Control */
+	uint32_t GpioMux_24_31;	/* Pin Sharing MUX3 Control */
+	uint32_t GpioMux_32_39;	/* Pin Sharing MUX4 Control */
+	uint32_t GpioMux_40_47;	/* Pin Sharing MUX5 Control */
+	uint32_t GpioMux_48_55;	/* Pin Sharing MUX6 Control */
+	uint32_t GpioMux_56_63;	/* Pin Sharing MUX7 Control */
+
+	uint32_t GpioSR_0_7;	/* Slew rate for GPIO 0 - 7 */
+	uint32_t GpioSR_8_15;	/* Slew rate for GPIO 8 - 15 */
+	uint32_t GpioSR_16_23;	/* Slew rate for GPIO 16 - 23 */
+	uint32_t GpioSR_24_31;	/* Slew rate for GPIO 24 - 31 */
+	uint32_t GpioSR_32_39;	/* Slew rate for GPIO 32 - 39 */
+	uint32_t GpioSR_40_47;	/* Slew rate for GPIO 40 - 47 */
+	uint32_t GpioSR_48_55;	/* Slew rate for GPIO 48 - 55 */
+	uint32_t GpioSR_56_63;	/* Slew rate for GPIO 56 - 63 */
+	uint32_t MiscSR_0_7;	/* Slew rate for MISC 0 - 7 */
+	uint32_t MiscSR_8_15;	/* Slew rate for MISC 8 - 15 */
+
+	uint32_t GpioPull_0_15;	/* Pull up registers for GPIO 0 - 15 */
+	uint32_t GpioPull_16_31;	/* Pull up registers for GPIO 16 - 31 */
+	uint32_t GpioPull_32_47;	/* Pull up registers for GPIO 32 - 47 */
+	uint32_t GpioPull_48_63;	/* Pull up registers for GPIO 48 - 63 */
+	uint32_t MiscPull_0_15;	/* Pull up registers for MISC 0 - 15 */
+
+	uint32_t GpioInput_0_31;	/* Input type for GPIO 0 - 31 */
+	uint32_t GpioInput_32_63;	/* Input type for GPIO 32 - 63 */
+	uint32_t MiscInput_0_15;	/* Input type for MISC 0 - 16 */
+} chipcHw_REG_t;
+
+#define pChipcHw  ((volatile chipcHw_REG_t *) chipcHw_BASE_ADDRESS)
+#define pChipcPhysical  ((volatile chipcHw_REG_t *) MM_ADDR_IO_CHIPC)
+
+#define chipcHw_REG_CHIPID_BASE_MASK                    0xFFFFF000
+#define chipcHw_REG_CHIPID_BASE_SHIFT                   12
+#define chipcHw_REG_CHIPID_REV_MASK                     0x00000FFF
+#define chipcHw_REG_REV_A0                              0xA00
+#define chipcHw_REG_REV_B0                              0x0B0
+
+#define chipcHw_REG_PLL_STATUS_CONTROL_ENABLE           0x80000000	/* Allow controlling PLL registers */
+#define chipcHw_REG_PLL_STATUS_LOCKED                   0x00000001	/* PLL is settled */
+#define chipcHw_REG_PLL_CONFIG_D_RESET                  0x00000008	/* Digital reset */
+#define chipcHw_REG_PLL_CONFIG_A_RESET                  0x00000004	/* Analog reset */
+#define chipcHw_REG_PLL_CONFIG_BYPASS_ENABLE            0x00000020	/* Bypass enable */
+#define chipcHw_REG_PLL_CONFIG_OUTPUT_ENABLE            0x00000010	/* Output enable */
+#define chipcHw_REG_PLL_CONFIG_POWER_DOWN               0x00000001	/* Power down */
+#define chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ           1600000000	/* 1.6GHz VCO split frequency */
+#define chipcHw_REG_PLL_CONFIG_VCO_800_1600             0x00000000	/* VCO range 800-1600 MHz */
+#define chipcHw_REG_PLL_CONFIG_VCO_1601_3200            0x00000080	/* VCO range 1601-3200 MHz */
+#define chipcHw_REG_PLL_CONFIG_TEST_ENABLE              0x00010000	/* PLL test output enable */
+#define chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK         0x003E0000	/* Mask to set test values */
+#define chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT        17
+
+#define chipcHw_REG_PLL_CLOCK_PHASE_COMP                0x00800000	/* Phase comparator output */
+#define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK         0x00300000	/* Clock to bus ratio mask */
+#define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT        20	/* Number of bits to be shifted */
+#define chipcHw_REG_PLL_CLOCK_POWER_DOWN                0x00080000	/* PLL channel power down */
+#define chipcHw_REG_PLL_CLOCK_SOURCE_GPIO               0x00040000	/* Use GPIO as source */
+#define chipcHw_REG_PLL_CLOCK_BYPASS_SELECT             0x00020000	/* Select bypass clock */
+#define chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE             0x00010000	/* Clock gated ON */
+#define chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE       0x00008000	/* Clock phase update enable */
+#define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT       8	/* Number of bits to be shifted */
+#define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK        0x00003F00	/* Phase control mask */
+#define chipcHw_REG_PLL_CLOCK_MDIV_MASK                 0x000000FF	/* Clock post divider mask
+
+									   00000000 = divide-by-256
+									   00000001 = divide-by-1
+									   00000010 = divide-by-2
+									   00000011 = divide-by-3
+									   00000100 = divide-by-4
+									   00000101 = divide-by-5
+									   00000110 = divide-by-6
+									   .
+									   .
+									   11111011 = divide-by-251
+									   11111100 = divide-by-252
+									   11111101 = divide-by-253
+									   11111110 = divide-by-254
+									 */
+
+#define chipcHw_REG_DIV_CLOCK_SOURCE_OTHER              0x00040000	/* NON-PLL clock source select */
+#define chipcHw_REG_DIV_CLOCK_BYPASS_SELECT             0x00020000	/* NON-PLL clock bypass enable */
+#define chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE             0x00010000	/* NON-PLL clock output enable */
+#define chipcHw_REG_DIV_CLOCK_DIV_MASK                  0x000000FF	/* NON-PLL clock post-divide mask */
+#define chipcHw_REG_DIV_CLOCK_DIV_256                   0x00000000	/* NON-PLL clock post-divide by 256 */
+
+#define chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT             0
+#define chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT             4
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT           8
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK            0x0001FF00
+#define chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN           0x02000000
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK       0x00700000	/* Divider mask */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER    0x00000000	/* Integer-N Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_UNIT  0x00100000	/* MASH Sigma-Delta Modulator Unit Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_UNIT   0x00200000	/* MFB Sigma-Delta Modulator Unit Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8   0x00300000	/* MASH Sigma-Delta Modulator 1/8 Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_1_8    0x00400000	/* MFB Sigma-Delta Modulator 1/8 Mode */
+
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vco)          ((vco) / chipcHw_XTAL_FREQ_Hz)
+#define chipcHw_REG_PLL_PREDIVIDER_P1                   1
+#define chipcHw_REG_PLL_PREDIVIDER_P2                   1
+
+#define chipcHw_REG_PLL_DIVIDER_M1DIV                   0x03000000
+#define chipcHw_REG_PLL_DIVIDER_FRAC                    0x00FFFFFF	/* Fractional divider */
+
+#define chipcHw_REG_PLL_DIVIDER_NDIV_f_SS               (0x00FFFFFF)	/* To attain spread with max frequency */
+
+#define chipcHw_REG_PLL_DIVIDER_NDIV_f                  0	/* ndiv_frac = chipcHw_REG_PLL_DIVIDER_NDIV_f /
+								   chipcHw_REG_PLL_DIVIDER_FRAC
+								   = 0, when SS is disable
+								 */
+
+#define chipcHw_REG_PLL_DIVIDER_MDIV(vco, Hz)           ((chipcHw_divide((vco), (Hz)) > 255) ? 0 : chipcHw_divide((vco), (Hz)))
+
+#define chipcHw_REG_ACLKClock_CLK_DIV_MASK              0x3
+
+/* System booting strap options */
+#define chipcHw_STRAPS_SOFT_OVERRIDE                    0x00000001	/* Software Strap Override */
+
+#define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8         0x00000000	/* 8 bit NAND FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16         0x00000002	/* 16 bit NOR FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH         0x00000004	/* Serial FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16        0x00000006	/* 16 bit NAND FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_UART                 0x00000008	/* UART Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_MASK                 0x0000000E	/* Mask */
+
+/* System boot option */
+#define chipcHw_STRAPS_BOOT_OPTION_BROM                 0x00000000	/* Boot from Boot ROM */
+#define chipcHw_STRAPS_BOOT_OPTION_ARAM                 0x00000020	/* Boot from ARAM */
+#define chipcHw_STRAPS_BOOT_OPTION_NOR                  0x00000030	/* Boot from NOR flash */
+
+/* NAND Flash page size strap options */
+#define chipcHw_STRAPS_NAND_PAGESIZE_512                0x00000000	/* NAND FLASH page size of 512 bytes */
+#define chipcHw_STRAPS_NAND_PAGESIZE_2048               0x00000040	/* NAND FLASH page size of 2048 bytes */
+#define chipcHw_STRAPS_NAND_PAGESIZE_4096               0x00000080	/* NAND FLASH page size of 4096 bytes */
+#define chipcHw_STRAPS_NAND_PAGESIZE_EXT                0x000000C0	/* NAND FLASH page of extened size */
+#define chipcHw_STRAPS_NAND_PAGESIZE_MASK               0x000000C0	/* Mask */
+
+#define chipcHw_STRAPS_NAND_EXTRA_CYCLE                 0x00000400	/* NAND FLASH address cycle configuration */
+#define chipcHw_STRAPS_REBOOT_TO_UART                   0x00000800	/* Reboot to UART on error */
+
+/* Secure boot mode strap options */
+#define chipcHw_STRAPS_BOOT_MODE_NORMAL                 0x00000000	/* Normal Boot */
+#define chipcHw_STRAPS_BOOT_MODE_DBG_SW                 0x00000100	/* Software debugging Boot */
+#define chipcHw_STRAPS_BOOT_MODE_DBG_BOOT               0x00000200	/* Boot rom debugging Boot */
+#define chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET           0x00000300	/* Normal Boot (Quiet BootRom) */
+#define chipcHw_STRAPS_BOOT_MODE_MASK                   0x00000300	/* Mask */
+
+/* Slave Mode straps */
+#define chipcHw_STRAPS_I2CS                             0x02000000	/* I2C Slave  */
+#define chipcHw_STRAPS_SPIS                             0x01000000	/* SPI Slave  */
+
+/* Strap pin options */
+#define chipcHw_REG_SW_STRAPS                           ((pChipcHw->PinStraps & 0x0000FC00) >> 10)
+
+/* PIF/LCD pin sharing defines */
+#define chipcHw_REG_LCD_PIN_ENABLE                      0x00000001	/* LCD Controller is used and the pins have LCD functions */
+#define chipcHw_REG_PIF_PIN_ENABLE                      0x00000002	/* LCD pins are used to perform PIF functions  */
+
+#define chipcHw_GPIO_COUNT                              61	/* Number of GPIO pin accessible thorugh CHIPC */
+
+/* NOTE: Any changes to these constants will require a corresponding change to chipcHw_str.c */
+#define chipcHw_REG_GPIO_MUX_KEYPAD                     0x00000001	/* GPIO mux for Keypad */
+#define chipcHw_REG_GPIO_MUX_I2CH                       0x00000002	/* GPIO mux for I2CH */
+#define chipcHw_REG_GPIO_MUX_SPI                        0x00000003	/* GPIO mux for SPI */
+#define chipcHw_REG_GPIO_MUX_UART                       0x00000004	/* GPIO mux for UART */
+#define chipcHw_REG_GPIO_MUX_LEDMTXP                    0x00000005	/* GPIO mux for LEDMTXP */
+#define chipcHw_REG_GPIO_MUX_LEDMTXS                    0x00000006	/* GPIO mux for LEDMTXS */
+#define chipcHw_REG_GPIO_MUX_SDIO0                      0x00000007	/* GPIO mux for SDIO0 */
+#define chipcHw_REG_GPIO_MUX_SDIO1                      0x00000008	/* GPIO mux for SDIO1 */
+#define chipcHw_REG_GPIO_MUX_PCM                        0x00000009	/* GPIO mux for PCM */
+#define chipcHw_REG_GPIO_MUX_I2S                        0x0000000A	/* GPIO mux for I2S */
+#define chipcHw_REG_GPIO_MUX_ETM                        0x0000000B	/* GPIO mux for ETM */
+#define chipcHw_REG_GPIO_MUX_DEBUG                      0x0000000C	/* GPIO mux for DEBUG */
+#define chipcHw_REG_GPIO_MUX_MISC                       0x0000000D	/* GPIO mux for MISC */
+#define chipcHw_REG_GPIO_MUX_GPIO                       0x00000000	/* GPIO mux for GPIO */
+#define chipcHw_REG_GPIO_MUX(pin)                       (&pChipcHw->GpioMux_0_7 + ((pin) >> 3))
+#define chipcHw_REG_GPIO_MUX_POSITION(pin)              (((pin) & 0x00000007) << 2)
+#define chipcHw_REG_GPIO_MUX_MASK                       0x0000000F	/* Mask */
+
+#define chipcHw_REG_SLEW_RATE_HIGH                      0x00000000	/* High speed slew rate */
+#define chipcHw_REG_SLEW_RATE_NORMAL                    0x00000008	/* Normal slew rate */
+							/* Pins beyond 42 are defined by skipping 8 bits within the register */
+#define chipcHw_REG_SLEW_RATE(pin)                      (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3)))
+#define chipcHw_REG_SLEW_RATE_POSITION(pin)             (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2))
+#define chipcHw_REG_SLEW_RATE_MASK                      0x00000008	/* Mask */
+
+#define chipcHw_REG_CURRENT_STRENGTH_2mA                0x00000001	/* Current driving strength 2 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_4mA                0x00000002	/* Current driving strength 4 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_6mA                0x00000004	/* Current driving strength 6 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_8mA                0x00000005	/* Current driving strength 8 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_10mA               0x00000006	/* Current driving strength 10 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_12mA               0x00000007	/* Current driving strength 12 milli ampere */
+#define chipcHw_REG_CURRENT_MASK                        0x00000007	/* Mask */
+							/* Pins beyond 42 are defined by skipping 8 bits */
+#define chipcHw_REG_CURRENT(pin)                        (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3)))
+#define chipcHw_REG_CURRENT_POSITION(pin)               (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2))
+
+#define chipcHw_REG_PULL_NONE                           0x00000000	/* No pull up register */
+#define chipcHw_REG_PULL_UP                             0x00000001	/* Pull up register enable */
+#define chipcHw_REG_PULL_DOWN                           0x00000002	/* Pull down register enable */
+#define chipcHw_REG_PULLUP_MASK                         0x00000003	/* Mask */
+							/* Pins beyond 42 are defined by skipping 4 bits */
+#define chipcHw_REG_PULLUP(pin)                         (((pin) > 42) ? (&pChipcHw->GpioPull_0_15 + (((pin) + 2) >> 4)) : (&pChipcHw->GpioPull_0_15 + ((pin) >> 4)))
+#define chipcHw_REG_PULLUP_POSITION(pin)                (((pin) > 42) ? ((((pin) + 2) & 0x0000000F) << 1) : (((pin) & 0x0000000F) << 1))
+
+#define chipcHw_REG_INPUTTYPE_CMOS                      0x00000000	/* Normal CMOS logic */
+#define chipcHw_REG_INPUTTYPE_ST                        0x00000001	/* High speed Schmitt Trigger */
+#define chipcHw_REG_INPUTTYPE_MASK                      0x00000001	/* Mask */
+							/* Pins beyond 42 are defined by skipping 2 bits */
+#define chipcHw_REG_INPUTTYPE(pin)                      (((pin) > 42) ? (&pChipcHw->GpioInput_0_31 + (((pin) + 2) >> 5)) : (&pChipcHw->GpioInput_0_31 + ((pin) >> 5)))
+#define chipcHw_REG_INPUTTYPE_POSITION(pin)             (((pin) > 42) ? ((((pin) + 2) & 0x0000001F)) : (((pin) & 0x0000001F)))
+
+/* Device connected to the bus clock */
+#define chipcHw_REG_BUS_CLOCK_ARM                       0x00000001	/* Bus interface clock for ARM */
+#define chipcHw_REG_BUS_CLOCK_VDEC                      0x00000002	/* Bus interface clock for VDEC */
+#define chipcHw_REG_BUS_CLOCK_ARAM                      0x00000004	/* Bus interface clock for ARAM */
+#define chipcHw_REG_BUS_CLOCK_HPM                       0x00000008	/* Bus interface clock for HPM */
+#define chipcHw_REG_BUS_CLOCK_DDRC                      0x00000010	/* Bus interface clock for DDRC */
+#define chipcHw_REG_BUS_CLOCK_DMAC0                     0x00000020	/* Bus interface clock for DMAC0 */
+#define chipcHw_REG_BUS_CLOCK_DMAC1                     0x00000040	/* Bus interface clock for DMAC1 */
+#define chipcHw_REG_BUS_CLOCK_NVI                       0x00000080	/* Bus interface clock for NVI */
+#define chipcHw_REG_BUS_CLOCK_ESW                       0x00000100	/* Bus interface clock for ESW */
+#define chipcHw_REG_BUS_CLOCK_GE                        0x00000200	/* Bus interface clock for GE */
+#define chipcHw_REG_BUS_CLOCK_I2CH                      0x00000400	/* Bus interface clock for I2CH */
+#define chipcHw_REG_BUS_CLOCK_I2S0                      0x00000800	/* Bus interface clock for I2S0 */
+#define chipcHw_REG_BUS_CLOCK_I2S1                      0x00001000	/* Bus interface clock for I2S1 */
+#define chipcHw_REG_BUS_CLOCK_VRAM                      0x00002000	/* Bus interface clock for VRAM */
+#define chipcHw_REG_BUS_CLOCK_CLCD                      0x00004000	/* Bus interface clock for CLCD */
+#define chipcHw_REG_BUS_CLOCK_LDK                       0x00008000	/* Bus interface clock for LDK */
+#define chipcHw_REG_BUS_CLOCK_LED                       0x00010000	/* Bus interface clock for LED */
+#define chipcHw_REG_BUS_CLOCK_OTP                       0x00020000	/* Bus interface clock for OTP */
+#define chipcHw_REG_BUS_CLOCK_PIF                       0x00040000	/* Bus interface clock for PIF */
+#define chipcHw_REG_BUS_CLOCK_SPU                       0x00080000	/* Bus interface clock for SPU */
+#define chipcHw_REG_BUS_CLOCK_SDIO0                     0x00100000	/* Bus interface clock for SDIO0 */
+#define chipcHw_REG_BUS_CLOCK_SDIO1                     0x00200000	/* Bus interface clock for SDIO1 */
+#define chipcHw_REG_BUS_CLOCK_SPIH                      0x00400000	/* Bus interface clock for SPIH */
+#define chipcHw_REG_BUS_CLOCK_SPIS                      0x00800000	/* Bus interface clock for SPIS */
+#define chipcHw_REG_BUS_CLOCK_UART0                     0x01000000	/* Bus interface clock for UART0 */
+#define chipcHw_REG_BUS_CLOCK_UART1                     0x02000000	/* Bus interface clock for UART1 */
+#define chipcHw_REG_BUS_CLOCK_BBL                       0x04000000	/* Bus interface clock for BBL */
+#define chipcHw_REG_BUS_CLOCK_I2CS                      0x08000000	/* Bus interface clock for I2CS */
+#define chipcHw_REG_BUS_CLOCK_USBH                      0x10000000	/* Bus interface clock for USB Host */
+#define chipcHw_REG_BUS_CLOCK_USBD                      0x20000000	/* Bus interface clock for USB Device */
+#define chipcHw_REG_BUS_CLOCK_BROM                      0x40000000	/* Bus interface clock for Boot ROM */
+#define chipcHw_REG_BUS_CLOCK_TSC                       0x80000000	/* Bus interface clock for Touch screen */
+
+/* Software resets defines */
+#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD          0x0000000080000000ULL	/* Reset Global VPM and hold */
+#define chipcHw_REG_SOFT_RESET_VPM_HOLD                 0x0000000040000000ULL	/* Reset VPM and hold */
+#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL               0x0000000020000000ULL	/* Reset Global VPM */
+#define chipcHw_REG_SOFT_RESET_VPM                      0x0000000010000000ULL	/* Reset VPM */
+#define chipcHw_REG_SOFT_RESET_KEYPAD                   0x0000000008000000ULL	/* Reset Key pad */
+#define chipcHw_REG_SOFT_RESET_LED                      0x0000000004000000ULL	/* Reset LED */
+#define chipcHw_REG_SOFT_RESET_SPU                      0x0000000002000000ULL	/* Reset SPU */
+#define chipcHw_REG_SOFT_RESET_RNG                      0x0000000001000000ULL	/* Reset RNG */
+#define chipcHw_REG_SOFT_RESET_PKA                      0x0000000000800000ULL	/* Reset PKA */
+#define chipcHw_REG_SOFT_RESET_LCD                      0x0000000000400000ULL	/* Reset LCD */
+#define chipcHw_REG_SOFT_RESET_PIF                      0x0000000000200000ULL	/* Reset PIF */
+#define chipcHw_REG_SOFT_RESET_I2CS                     0x0000000000100000ULL	/* Reset I2C Slave */
+#define chipcHw_REG_SOFT_RESET_I2CH                     0x0000000000080000ULL	/* Reset I2C Host */
+#define chipcHw_REG_SOFT_RESET_SDIO1                    0x0000000000040000ULL	/* Reset SDIO 1 */
+#define chipcHw_REG_SOFT_RESET_SDIO0                    0x0000000000020000ULL	/* Reset SDIO 0 */
+#define chipcHw_REG_SOFT_RESET_BBL                      0x0000000000010000ULL	/* Reset BBL */
+#define chipcHw_REG_SOFT_RESET_I2S1                     0x0000000000008000ULL	/* Reset I2S1 */
+#define chipcHw_REG_SOFT_RESET_I2S0                     0x0000000000004000ULL	/* Reset I2S0 */
+#define chipcHw_REG_SOFT_RESET_SPIS                     0x0000000000002000ULL	/* Reset SPI Slave */
+#define chipcHw_REG_SOFT_RESET_SPIH                     0x0000000000001000ULL	/* Reset SPI Host */
+#define chipcHw_REG_SOFT_RESET_GPIO1                    0x0000000000000800ULL	/* Reset GPIO block 1 */
+#define chipcHw_REG_SOFT_RESET_GPIO0                    0x0000000000000400ULL	/* Reset GPIO block 0 */
+#define chipcHw_REG_SOFT_RESET_UART1                    0x0000000000000200ULL	/* Reset UART 1 */
+#define chipcHw_REG_SOFT_RESET_UART0                    0x0000000000000100ULL	/* Reset UART 0 */
+#define chipcHw_REG_SOFT_RESET_NVI                      0x0000000000000080ULL	/* Reset NVI */
+#define chipcHw_REG_SOFT_RESET_WDOG                     0x0000000000000040ULL	/* Reset Watch dog */
+#define chipcHw_REG_SOFT_RESET_TMR                      0x0000000000000020ULL	/* Reset Timer */
+#define chipcHw_REG_SOFT_RESET_ETM                      0x0000000000000010ULL	/* Reset ETM */
+#define chipcHw_REG_SOFT_RESET_ARM_HOLD                 0x0000000000000008ULL	/* Reset ARM and HOLD */
+#define chipcHw_REG_SOFT_RESET_ARM                      0x0000000000000004ULL	/* Reset ARM */
+#define chipcHw_REG_SOFT_RESET_CHIP_WARM                0x0000000000000002ULL	/* Chip warm reset */
+#define chipcHw_REG_SOFT_RESET_CHIP_SOFT                0x0000000000000001ULL	/* Chip soft reset */
+#define chipcHw_REG_SOFT_RESET_VDEC                     0x0000100000000000ULL	/* Video decoder */
+#define chipcHw_REG_SOFT_RESET_GE                       0x0000080000000000ULL	/* Graphics engine */
+#define chipcHw_REG_SOFT_RESET_OTP                      0x0000040000000000ULL	/* Reset OTP */
+#define chipcHw_REG_SOFT_RESET_USB2                     0x0000020000000000ULL	/* Reset USB2 */
+#define chipcHw_REG_SOFT_RESET_USB1                     0x0000010000000000ULL	/* Reset USB 1 */
+#define chipcHw_REG_SOFT_RESET_USB                      0x0000008000000000ULL	/* Reset USB 1 and USB2 soft reset */
+#define chipcHw_REG_SOFT_RESET_ESW                      0x0000004000000000ULL	/* Reset Ethernet switch */
+#define chipcHw_REG_SOFT_RESET_ESWCLK                   0x0000002000000000ULL	/* Reset Ethernet switch clock */
+#define chipcHw_REG_SOFT_RESET_DDRPHY                   0x0000001000000000ULL	/* Reset DDR Physical */
+#define chipcHw_REG_SOFT_RESET_DDR                      0x0000000800000000ULL	/* Reset DDR Controller */
+#define chipcHw_REG_SOFT_RESET_TSC                      0x0000000400000000ULL	/* Reset Touch screen */
+#define chipcHw_REG_SOFT_RESET_PCM                      0x0000000200000000ULL	/* Reset PCM device */
+#define chipcHw_REG_SOFT_RESET_APM                      0x0000200100000000ULL	/* Reset APM device */
+
+#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD        0x8000000000000000ULL	/* Unhold Global VPM */
+#define chipcHw_REG_SOFT_RESET_VPM_UNHOLD               0x4000000000000000ULL	/* Unhold VPM */
+#define chipcHw_REG_SOFT_RESET_ARM_UNHOLD               0x2000000000000000ULL	/* Unhold ARM reset  */
+#define chipcHw_REG_SOFT_RESET_UNHOLD_MASK              0xF000000000000000ULL	/* Mask to handle unhold request */
+
+/* Audio channel control defines */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_ALL            0x00000001	/* Enable all audio channel */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_A              0x00000002	/* Enable channel A */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_B              0x00000004	/* Enable channel B */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_C              0x00000008	/* Enable channel C */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_NTP_CLOCK      0x00000010	/* Enable NTP clock */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM0_CLOCK     0x00000020	/* Enable PCM0 clock */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM1_CLOCK     0x00000040	/* Enable PCM1 clock */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_APM_CLOCK      0x00000080	/* Enable APM clock */
+
+/* Misc. chip control defines */
+#define chipcHw_REG_MISC_CTRL_GE_SEL                    0x00040000	/* Select GE2/GE3 */
+#define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_ONCHIP         0x00000000	/* Use on chip clock for I2S1 */
+#define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_GPIO           0x00020000	/* Use external clock via GPIO pin 26 for I2S1 */
+#define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_ONCHIP         0x00000000	/* Use on chip clock for I2S0 */
+#define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_GPIO           0x00010000	/* Use external clock via GPIO pin 45 for I2S0 */
+#define chipcHw_REG_MISC_CTRL_ARM_CP15_DISABLE          0x00008000	/* Disable ARM CP15 bit */
+#define chipcHw_REG_MISC_CTRL_RTC_DISABLE               0x00000008	/* Disable RTC registers */
+#define chipcHw_REG_MISC_CTRL_BBRAM_DISABLE             0x00000004	/* Disable Battery Backed RAM */
+#define chipcHw_REG_MISC_CTRL_USB_MODE_HOST             0x00000002	/* Set USB as host */
+#define chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE           0xFFFFFFFD	/* Set USB as device */
+#define chipcHw_REG_MISC_CTRL_USB_POWERON               0xFFFFFFFE	/* Power up USB */
+#define chipcHw_REG_MISC_CTRL_USB_POWEROFF              0x00000001	/* Power down USB */
+
+/* OTP configuration defines */
+#define chipcHw_REG_OTP_SECURITY_OFF                    0x0000020000000000ULL	/* Security support is OFF */
+#define chipcHw_REG_OTP_SPU_SLOW                        0x0000010000000000ULL	/* Limited SPU throughput */
+#define chipcHw_REG_OTP_LCD_SPEED                       0x0000000600000000ULL	/* Set VPM speed one */
+#define chipcHw_REG_OTP_VPM_SPEED_1                     0x0000000100000000ULL	/* Set VPM speed one */
+#define chipcHw_REG_OTP_VPM_SPEED_0                     0x0000000080000000ULL	/* Set VPM speed zero */
+#define chipcHw_REG_OTP_AXI_SPEED                       0x0000000060000000ULL	/* Set maximum AXI bus speed */
+#define chipcHw_REG_OTP_APM_DISABLE                     0x000000001F000000ULL	/* Disable APM */
+#define chipcHw_REG_OTP_PIF_DISABLE                     0x0000000000200000ULL	/* Disable PIF */
+#define chipcHw_REG_OTP_VDEC_DISABLE                    0x0000000000100000ULL	/* Disable Video decoder */
+#define chipcHw_REG_OTP_BBL_DISABLE                     0x0000000000080000ULL	/* Disable RTC and BBRAM */
+#define chipcHw_REG_OTP_LED_DISABLE                     0x0000000000040000ULL	/* Disable LED */
+#define chipcHw_REG_OTP_GE_DISABLE                      0x0000000000020000ULL	/* Disable Graphics Engine */
+#define chipcHw_REG_OTP_LCD_DISABLE                     0x0000000000010000ULL	/* Disable LCD */
+#define chipcHw_REG_OTP_KEYPAD_DISABLE                  0x0000000000008000ULL	/* Disable keypad */
+#define chipcHw_REG_OTP_UART_DISABLE                    0x0000000000004000ULL	/* Disable UART */
+#define chipcHw_REG_OTP_SDIOH_DISABLE                   0x0000000000003000ULL	/* Disable SDIO host */
+#define chipcHw_REG_OTP_HSS_DISABLE                     0x0000000000000C00ULL	/* Disable HSS */
+#define chipcHw_REG_OTP_TSC_DISABLE                     0x0000000000000200ULL	/* Disable touch screen */
+#define chipcHw_REG_OTP_USB_DISABLE                     0x0000000000000180ULL	/* Disable USB */
+#define chipcHw_REG_OTP_SGMII_DISABLE                   0x0000000000000060ULL	/* Disable SGMII */
+#define chipcHw_REG_OTP_ETH_DISABLE                     0x0000000000000018ULL	/* Disable gigabit ethernet */
+#define chipcHw_REG_OTP_ETH_PHY_DISABLE                 0x0000000000000006ULL	/* Disable ethernet PHY */
+#define chipcHw_REG_OTP_VPM_DISABLE                     0x0000000000000001ULL	/* Disable VPM */
+
+/* Sticky bit defines */
+#define chipcHw_REG_STICKY_BOOT_DONE                    0x00000001	/* Boot done */
+#define chipcHw_REG_STICKY_SOFT_RESET                   0x00000002	/* ARM soft reset */
+#define chipcHw_REG_STICKY_GENERAL_1                    0x00000004	/* General purpose bit 1 */
+#define chipcHw_REG_STICKY_GENERAL_2                    0x00000008	/* General purpose bit 2 */
+#define chipcHw_REG_STICKY_GENERAL_3                    0x00000010	/* General purpose bit 3 */
+#define chipcHw_REG_STICKY_GENERAL_4                    0x00000020	/* General purpose bit 4 */
+#define chipcHw_REG_STICKY_GENERAL_5                    0x00000040	/* General purpose bit 5 */
+#define chipcHw_REG_STICKY_POR_BROM                     0x00000080	/* Special sticky bit for security - set in BROM to avoid other modes being entered */
+#define chipcHw_REG_STICKY_ARM_RESET                    0x00000100	/* ARM reset */
+#define chipcHw_REG_STICKY_CHIP_SOFT_RESET              0x00000200	/* Chip soft reset */
+#define chipcHw_REG_STICKY_CHIP_WARM_RESET              0x00000400	/* Chip warm reset */
+#define chipcHw_REG_STICKY_WDOG_RESET                   0x00000800	/* Watchdog reset */
+#define chipcHw_REG_STICKY_OTP_RESET                    0x00001000	/* OTP reset */
+
+							/* HW phase alignment defines *//* Spare1 register definitions */
+#define chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE        0x80000000	/* Enable DDR phase align panic interrupt */
+#define chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE        0x40000000	/* Enable VPM phase align panic interrupt */
+#define chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE        0x00000002	/* Enable access to VPM using system BUS */
+#define chipcHw_REG_SPARE1_DDR_BUS_ACCESS_ENABLE        0x00000001	/* Enable access to DDR using system BUS */
+							/* DDRPhaseCtrl1 register definitions */
+#define chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE            0x80000000	/* Enable DDR SW phase alignment */
+#define chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE            0x40000000	/* Enable DDR HW phase alignment */
+#define chipcHw_REG_DDR_PHASE_VALUE_GE_MASK             0x0000007F	/* DDR lower threshold for phase alignment */
+#define chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT            23
+#define chipcHw_REG_DDR_PHASE_VALUE_LE_MASK             0x0000007F	/* DDR upper threshold for phase alignment */
+#define chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT            16
+#define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_MASK     0x0000FFFF	/* BUS Cycle to wait to run next DDR phase alignment */
+#define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_SHIFT    0
+							/* VPMPhaseCtrl1 register definitions */
+#define chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE            0x80000000	/* Enable VPM SW phase alignment */
+#define chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE            0x40000000	/* Enable VPM HW phase alignment */
+#define chipcHw_REG_VPM_PHASE_VALUE_GE_MASK             0x0000007F	/* VPM lower threshold for phase alignment */
+#define chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT            23
+#define chipcHw_REG_VPM_PHASE_VALUE_LE_MASK             0x0000007F	/* VPM upper threshold for phase alignment */
+#define chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT            16
+#define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_MASK     0x0000FFFF	/* BUS Cycle to wait to complete the VPM phase alignment */
+#define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_SHIFT    0
+							/* PhaseAlignStatus register definitions */
+#define chipcHw_REG_DDR_TIMEOUT_INTR_STATUS             0x80000000	/* DDR time out interrupt status */
+#define chipcHw_REG_DDR_PHASE_STATUS_MASK               0x0000007F	/* DDR phase status value */
+#define chipcHw_REG_DDR_PHASE_STATUS_SHIFT              24
+#define chipcHw_REG_DDR_PHASE_ALIGNED                   0x00800000	/* DDR Phase aligned status */
+#define chipcHw_REG_DDR_LOAD                            0x00400000	/* Load DDR phase status */
+#define chipcHw_REG_DDR_PHASE_CTRL_MASK                 0x0000003F	/* DDR phase control value */
+#define chipcHw_REG_DDR_PHASE_CTRL_SHIFT                16
+#define chipcHw_REG_VPM_TIMEOUT_INTR_STATUS             0x80000000	/* VPM time out interrupt status */
+#define chipcHw_REG_VPM_PHASE_STATUS_MASK               0x0000007F	/* VPM phase status value */
+#define chipcHw_REG_VPM_PHASE_STATUS_SHIFT              8
+#define chipcHw_REG_VPM_PHASE_ALIGNED                   0x00000080	/* VPM Phase aligned status */
+#define chipcHw_REG_VPM_LOAD                            0x00000040	/* Load VPM phase status */
+#define chipcHw_REG_VPM_PHASE_CTRL_MASK                 0x0000003F	/* VPM phase control value */
+#define chipcHw_REG_VPM_PHASE_CTRL_SHIFT                0
+							/* DDRPhaseCtrl2 register definitions */
+#define chipcHw_REG_DDR_INTR_SERVICED                   0x02000000	/* Acknowledge that interrupt was serviced */
+#define chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE             0x01000000	/* Enable time out interrupt */
+#define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_MASK      0x0000000F	/* Wait before toggling load_ch */
+#define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_SHIFT     20
+#define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_MASK      0x0000000F	/* Total wait to settle ph_ctrl and load_ch */
+#define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_SHIFT     16
+#define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK        0x0000FFFF	/* Time out value for DDR HW phase alignment */
+#define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT       0
+							/* VPMPhaseCtrl2 register definitions */
+#define chipcHw_REG_VPM_INTR_SELECT_MASK                0x00000003	/* Interrupt select */
+#define chipcHw_REG_VPM_INTR_SELECT_SHIFT               26
+#define chipcHw_REG_VPM_INTR_DISABLE                    0x00000000
+#define chipcHw_REG_VPM_INTR_FAST                       (0x1 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
+#define chipcHw_REG_VPM_INTR_MEDIUM                     (0x2 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
+#define chipcHw_REG_VPM_INTR_SLOW                       (0x3 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
+#define chipcHw_REG_VPM_INTR_SERVICED                   0x02000000	/* Acknowledge that interrupt was serviced */
+#define chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE             0x01000000	/* Enable time out interrupt */
+#define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_MASK      0x0000000F	/* Wait before toggling load_ch */
+#define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_SHIFT     20
+#define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_MASK      0x0000000F	/* Total wait cycle to settle ph_ctrl and load_ch */
+#define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_SHIFT     16
+#define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK        0x0000FFFF	/* Time out value for VPM HW phase alignment */
+#define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT       0
+
+#endif /* CHIPCHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h
new file mode 100644
index 0000000..f1b68e2
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h
@@ -0,0 +1,872 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    ddrcReg.h
+*
+*  @brief   Register definitions for BCMRING DDR2 Controller and PHY
+*
+*/
+/****************************************************************************/
+
+#ifndef DDRC_REG_H
+#define DDRC_REG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/reg.h>
+#include <csp/stdint.h>
+
+#include <mach/csp/mm_io.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+/*********************************************************************/
+/* DDR2 Controller (ARM PL341) register definitions */
+/*********************************************************************/
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 DDR2 configuration registers, offset 0x000 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+	typedef struct {
+		uint32_t memcStatus;
+		uint32_t memcCmd;
+		uint32_t directCmd;
+		uint32_t memoryCfg;
+		uint32_t refreshPrd;
+		uint32_t casLatency;
+		uint32_t writeLatency;
+		uint32_t tMrd;
+		uint32_t tRas;
+		uint32_t tRc;
+		uint32_t tRcd;
+		uint32_t tRfc;
+		uint32_t tRp;
+		uint32_t tRrd;
+		uint32_t tWr;
+		uint32_t tWtr;
+		uint32_t tXp;
+		uint32_t tXsr;
+		uint32_t tEsr;
+		uint32_t memoryCfg2;
+		uint32_t memoryCfg3;
+		uint32_t tFaw;
+	} ddrcReg_CTLR_MEMC_REG_t;
+
+#define ddrcReg_CTLR_MEMC_REG_OFFSET                    0x0000
+#define ddrcReg_CTLR_MEMC_REGP                          ((volatile ddrcReg_CTLR_MEMC_REG_t *)  (MM_IO_BASE_DDRC + ddrcReg_CTLR_MEMC_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMC_STATUS_BANKS_MASK             (0x3 << 12)
+#define ddrcReg_CTLR_MEMC_STATUS_BANKS_4                (0x0 << 12)
+#define ddrcReg_CTLR_MEMC_STATUS_BANKS_8                (0x3 << 12)
+
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_MASK          (0x3 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_0             (0x0 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_1             (0x1 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_2             (0x2 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_4             (0x3 << 10)
+
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_MASK             (0x3 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_1                (0x0 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_2                (0x1 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_3                (0x2 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_4                (0x3 << 7)
+
+#define ddrcReg_CTLR_MEMC_STATUS_TYPE_MASK              (0x7 << 4)
+#define ddrcReg_CTLR_MEMC_STATUS_TYPE_DDR2              (0x5 << 4)
+
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_MASK             (0x3 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_16               (0x0 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_32               (0x1 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_64               (0x2 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_128              (0x3 << 2)
+
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_MASK             (0x3 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_CONFIG           (0x0 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_READY            (0x1 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_PAUSED           (0x2 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_LOWPWR           (0x3 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMC_CMD_MASK                      (0x7 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_GO                        (0x0 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_SLEEP                     (0x1 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_WAKEUP                    (0x2 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_PAUSE                     (0x3 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_CONFIGURE                 (0x4 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_ACTIVE_PAUSE              (0x7 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT              20
+#define ddrcReg_CTLR_DIRECT_CMD_CHIP_MASK               (0x3 << ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT)
+
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_PRECHARGEALL       (0x0 << 18)
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_AUTOREFRESH        (0x1 << 18)
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_MODEREG            (0x2 << 18)
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_NOP                (0x3 << 18)
+
+#define ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT              16
+#define ddrcReg_CTLR_DIRECT_CMD_BANK_MASK               (0x3 << ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT)
+
+#define ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT              0
+#define ddrcReg_CTLR_DIRECT_CMD_ADDR_MASK               (0x1ffff << ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_MASK           (0x3 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_1              (0x0 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_2              (0x1 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_3              (0x2 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_4              (0x3 << 21)
+
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_MASK           (0x7 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_3_0            (0x0 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_4_1            (0x1 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_5_2            (0x2 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_6_3            (0x3 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_7_4            (0x4 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_8_5            (0x5 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_9_6            (0x6 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_10_7           (0x7 << 18)
+
+#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_MASK          (0x7 << 15)
+#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_4             (0x2 << 15)
+#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_8             (0x3 << 15)	/* @note Not supported in PL341 */
+
+#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_ENABLE          (0x1 << 13)
+
+#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT    7
+#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_MASK     (0x3f << ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT)
+
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_MASK       (0x7 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_11         (0x0 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_12         (0x1 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_13         (0x2 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_14         (0x3 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_15         (0x4 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_16         (0x5 << 3)
+
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_MASK       (0x7 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_9          (0x1 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_10         (0x2 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_11         (0x3 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_REFRESH_PRD_SHIFT                  0
+#define ddrcReg_CTLR_REFRESH_PRD_MASK                   (0x7fff << ddrcReg_CTLR_REFRESH_PRD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_CAS_LATENCY_SHIFT                  1
+#define ddrcReg_CTLR_CAS_LATENCY_MASK                   (0x7 << ddrcReg_CTLR_CAS_LATENCY_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_WRITE_LATENCY_SHIFT                0
+#define ddrcReg_CTLR_WRITE_LATENCY_MASK                 (0x7 << ddrcReg_CTLR_WRITE_LATENCY_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_MRD_SHIFT                        0
+#define ddrcReg_CTLR_T_MRD_MASK                         (0x7f << ddrcReg_CTLR_T_MRD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RAS_SHIFT                        0
+#define ddrcReg_CTLR_T_RAS_MASK                         (0x1f << ddrcReg_CTLR_T_RAS_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RC_SHIFT                         0
+#define ddrcReg_CTLR_T_RC_MASK                          (0x1f << ddrcReg_CTLR_T_RC_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT         8
+#define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_MASK          (0x7 << ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_RCD_SHIFT                        0
+#define ddrcReg_CTLR_T_RCD_MASK                         (0x7 << ddrcReg_CTLR_T_RCD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT         8
+#define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_MASK          (0x7f << ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_RFC_SHIFT                        0
+#define ddrcReg_CTLR_T_RFC_MASK                         (0x7f << ddrcReg_CTLR_T_RFC_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT          8
+#define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_MASK           (0x7 << ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_RP_SHIFT                         0
+#define ddrcReg_CTLR_T_RP_MASK                          (0xf << ddrcReg_CTLR_T_RP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RRD_SHIFT                        0
+#define ddrcReg_CTLR_T_RRD_MASK                         (0xf << ddrcReg_CTLR_T_RRD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_WR_SHIFT                         0
+#define ddrcReg_CTLR_T_WR_MASK                          (0x7 << ddrcReg_CTLR_T_WR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_WTR_SHIFT                        0
+#define ddrcReg_CTLR_T_WTR_MASK                         (0x7 << ddrcReg_CTLR_T_WTR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_XP_SHIFT                         0
+#define ddrcReg_CTLR_T_XP_MASK                          (0xff << ddrcReg_CTLR_T_XP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_XSR_SHIFT                        0
+#define ddrcReg_CTLR_T_XSR_MASK                         (0xff << ddrcReg_CTLR_T_XSR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_ESR_SHIFT                        0
+#define ddrcReg_CTLR_T_ESR_MASK                         (0xff << ddrcReg_CTLR_T_ESR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_MASK             (0x3 << 6)
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_16BITS           (0 << 6)
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_32BITS           (1 << 6)
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_64BITS           (2 << 6)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_MASK     (0x3 << 4)
+#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_2        (0 << 4)
+#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_3        (3 << 4)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_LOW     (0 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_HIGH    (1 << 3)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_LOW     (0 << 2)
+#define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_HIGH    (1 << 2)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_MASK               (0x3 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_ASYNC              (0 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_LE_M        (1 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_GT_M        (3 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT       0
+#define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_MASK        (0x7 << ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT         8
+#define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_MASK          (0x1f << ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_FAW_PERIOD_SHIFT                 0
+#define ddrcReg_CTLR_T_FAW_PERIOD_MASK                  (0x1f << ddrcReg_CTLR_T_FAW_PERIOD_SHIFT)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 AXI ID QOS configuration registers, offset 0x100 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_CTLR_QOS_CNT                            16
+#define ddrcReg_CTLR_QOS_MAX                            (ddrcReg_CTLR_QOS_CNT - 1)
+
+	typedef struct {
+		uint32_t cfg[ddrcReg_CTLR_QOS_CNT];
+	} ddrcReg_CTLR_QOS_REG_t;
+
+#define ddrcReg_CTLR_QOS_REG_OFFSET                     0x100
+#define ddrcReg_CTLR_QOS_REGP                           ((volatile ddrcReg_CTLR_QOS_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_QOS_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_QOS_CFG_MAX_SHIFT                  2
+#define ddrcReg_CTLR_QOS_CFG_MAX_MASK                   (0xff << ddrcReg_CTLR_QOS_CFG_MAX_SHIFT)
+
+#define ddrcReg_CTLR_QOS_CFG_MIN_SHIFT                  1
+#define ddrcReg_CTLR_QOS_CFG_MIN_MASK                   (1 << ddrcReg_CTLR_QOS_CFG_MIN_SHIFT)
+
+#define ddrcReg_CTLR_QOS_CFG_ENABLE                     (1 << 0)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 Memory chip configuration registers, offset 0x200 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_CTLR_CHIP_CNT                           4
+#define ddrcReg_CTLR_CHIP_MAX                           (ddrcReg_CTLR_CHIP_CNT - 1)
+
+	typedef struct {
+		uint32_t cfg[ddrcReg_CTLR_CHIP_CNT];
+	} ddrcReg_CTLR_CHIP_REG_t;
+
+#define ddrcReg_CTLR_CHIP_REG_OFFSET                    0x200
+#define ddrcReg_CTLR_CHIP_REGP                          ((volatile ddrcReg_CTLR_CHIP_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_CHIP_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_MASK              (1 << 16)
+#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_ROW_BANK_COL      (0 << 16)
+#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_BANK_ROW_COL      (1 << 16)
+
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT      8
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_MASK       (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT)
+
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT       0
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_MASK        (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 User configuration registers, offset 0x300 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_CTLR_USER_OUTPUT_CNT                    2
+
+	typedef struct {
+		uint32_t input;
+		uint32_t output[ddrcReg_CTLR_USER_OUTPUT_CNT];
+		uint32_t feature;
+	} ddrcReg_CTLR_USER_REG_t;
+
+#define ddrcReg_CTLR_USER_REG_OFFSET                    0x300
+#define ddrcReg_CTLR_USER_REGP                          ((volatile ddrcReg_CTLR_USER_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_USER_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT            0
+#define ddrcReg_CTLR_USER_INPUT_STATUS_MASK             (0xff << ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT              0
+#define ddrcReg_CTLR_USER_OUTPUT_CFG_MASK               (0xff << ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT)
+
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT      1
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_MASK       (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_BP134      (0 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301      (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_REGISTERED ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_FEATURE_WRITE_BLOCK_DISABLE        (1 << 2)
+#define ddrcReg_CTLR_FEATURE_EARLY_BURST_RSP_DISABLE    (1 << 0)
+
+/*********************************************************************/
+/* Broadcom DDR23 PHY register definitions */
+/*********************************************************************/
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* Broadcom DDR23 PHY Address and Control register definitions */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+	typedef struct {
+		uint32_t revision;
+		uint32_t pmCtl;
+		 REG32_RSVD(0x0008, 0x0010);
+		uint32_t pllStatus;
+		uint32_t pllCfg;
+		uint32_t pllPreDiv;
+		uint32_t pllDiv;
+		uint32_t pllCtl1;
+		uint32_t pllCtl2;
+		uint32_t ssCtl;
+		uint32_t ssCfg;
+		uint32_t vdlStatic;
+		uint32_t vdlDynamic;
+		uint32_t padIdle;
+		uint32_t pvtComp;
+		uint32_t padDrive;
+		uint32_t clkRgltrCtl;
+	} ddrcReg_PHY_ADDR_CTL_REG_t;
+
+#define ddrcReg_PHY_ADDR_CTL_REG_OFFSET                 0x0400
+#define ddrcReg_PHY_ADDR_CTL_REGP                       ((volatile ddrcReg_PHY_ADDR_CTL_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_ADDR_CTL_REG_OFFSET))
+
+/* @todo These SS definitions are duplicates of ones below */
+
+#define ddrcReg_PHY_ADDR_SS_CTRL_ENABLE                 0x00000001
+#define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_MASK     0xFFFF0000
+#define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT    16
+#define ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK      10	/* Higher the value, lower the SS modulation frequency */
+#define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_MASK     0x0000FFFF
+#define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT    0
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT       8
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_MASK        (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT       0
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_MASK        (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_CLK_PM_CTL_DDR_CLK_DISABLE (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_STATUS_LOCKED          (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_DIV2_CLK_RESET     (1 << 31)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT     17
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_MASK      (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_ENABLE        (1 << 16)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT     12
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_MASK      (0xf << ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_VCO_RNG            (1 << 7)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CH1_PWRDWN         (1 << 6)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BYPASS_ENABLE      (1 << 5)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CLKOUT_ENABLE      (1 << 4)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_D_RESET            (1 << 3)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_A_RESET            (1 << 2)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_PWRDWN             (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_DITHER_MFB     (1 << 26)
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_PWRDWN         (1 << 25)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT     20
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_MASK      (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT      8
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_MASK       (0x1ff << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT       4
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_MASK        (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT       0
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_MASK        (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT           24
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_MASK            (0xff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT         0
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_MASK          (0xffffff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT       30
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_MASK        (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT     27
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_MASK      (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT     24
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_MASK      (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT      22
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_MASK       (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LF_ORDER          (0x1 << 21)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT          19
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_MASK           (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT          17
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_MASK           (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT          15
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_MASK           (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT          13
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_MASK           (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT          10
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_MASK           (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT        5
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_MASK         (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT     0
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_MASK      (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT)
+
+/* ----------------------------------------------------- */
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT    4
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_MASK     (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT    2
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_MASK     (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_LOWCUR_ENABLE     (0x1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_BIASIN_ENABLE     (0x1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_EN_ENABLE           (0x1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT  16
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_MASK   (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT      0
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_MASK       (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FORCE           (1 << 20)
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_ENABLE          (1 << 16)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT      12
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_MASK       (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT      8
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_MASK       (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT      0
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_MASK       (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_ENABLE         (1 << 16)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT     12
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_MASK      (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT     8
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_MASK      (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT     0
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_MASK      (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_ENABLE            (1u << 31)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_RXENB_DISABLE     (1 << 8)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_IDDQ_DISABLE  (1 << 6)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_REB_DISABLE   (1 << 5)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_OEB_DISABLE   (1 << 4)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_IDDQ_DISABLE  (1 << 2)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_REB_DISABLE   (1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_OEB_DISABLE   (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_DONE           (1 << 30)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_DONE           (1 << 29)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_DONE       (1 << 28)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_AUTO_ENABLE    (1 << 27)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_ENABLE     (1 << 26)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_OVR_ENABLE   (1 << 25)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_OVR_ENABLE     (1 << 24)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT          20
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_MASK           (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT          16
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_MASK           (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT     12
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_MASK      (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT     8
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_MASK      (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT       4
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_MASK        (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT       0
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_MASK        (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_RT60B            (1 << 4)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SEL_SSTL18       (1 << 3)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELTXDRV_CI      (1 << 2)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELRXDRV         (1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SLEW             (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_HALF     (1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_OFF      (1 << 0)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* Broadcom DDR23 PHY Byte Lane register definitions */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_CNT                       2
+#define ddrcReg_PHY_BYTE_LANE_MAX                       (ddrcReg_CTLR_BYTE_LANE_CNT - 1)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT               8
+
+	typedef struct {
+		uint32_t revision;
+		uint32_t vdlCalibrate;
+		uint32_t vdlStatus;
+		 REG32_RSVD(0x000c, 0x0010);
+		uint32_t vdlOverride[ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT];
+		uint32_t readCtl;
+		uint32_t readStatus;
+		uint32_t readClear;
+		uint32_t padIdleCtl;
+		uint32_t padDriveCtl;
+		uint32_t padClkCtl;
+		uint32_t writeCtl;
+		uint32_t clkRegCtl;
+	} ddrcReg_PHY_BYTE_LANE_REG_t;
+
+/* There are 2 instances of the byte Lane registers, one for each byte lane. */
+#define ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET              0x0500
+#define ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET              0x0600
+
+#define ddrcReg_PHY_BYTE_LANE_1_REGP                    ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET))
+#define ddrcReg_PHY_BYTE_LANE_2_REGP                    ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT      8
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_MASK       (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT      0
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_MASK       (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_2CYCLE      (1 << 4)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_1CYCLE      (0 << 4)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_TEST            (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ALWAYS          (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ONCE            (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_FAST            (1 << 0)
+
+/* ----------------------------------------------------- */
+
+/* The byte lane VDL status calibTotal[9:0] is comprised of [9:4] step value, [3:2] fine fall */
+/* and [1:0] fine rise. Note that calibTotal[9:0] is located at bit 4 in the VDL status */
+/* register. The fine rise and fall are no longer used, so add some definitions for just */
+/* the step setting to simplify things. */
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT     8
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_MASK      (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT    4
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_MASK     (0x3ff << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_LOCK           (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_IDLE           (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_ENABLE            (1 << 16)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT        12
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_MASK         (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT        8
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_MASK         (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT        0
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_MASK         (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_P     0
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_N     1
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_EN        2
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_WRITE_DQ_DQM   3
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_P    4
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_N    5
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_EN       6
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_WRITE_DQ_DQM  7
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT      8
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_MASK       (0x3 << ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ENABLE    (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ADJUST    (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ENABLE    (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ADJUST    (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT   0
+#define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_MASK    (0xf << ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_READ_CLEAR_STATUS         (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_ENABLE                   (1u << 31)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_RXENB_DISABLE         (1 << 19)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_IDDQ_DISABLE          (1 << 18)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_REB_DISABLE           (1 << 17)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_OEB_DISABLE           (1 << 16)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_RXENB_DISABLE         (1 << 15)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_IDDQ_DISABLE          (1 << 14)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_REB_DISABLE           (1 << 13)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_OEB_DISABLE           (1 << 12)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_RXENB_DISABLE   (1 << 11)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_IDDQ_DISABLE    (1 << 10)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_REB_DISABLE     (1 << 9)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_OEB_DISABLE     (1 << 8)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_RXENB_DISABLE        (1 << 7)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_IDDQ_DISABLE         (1 << 6)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_REB_DISABLE          (1 << 5)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_OEB_DISABLE          (1 << 4)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_RXENB_DISABLE        (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_IDDQ_DISABLE         (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_REB_DISABLE          (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_OEB_DISABLE          (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B_DDR_READ_ENB      (1 << 5)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B                   (1 << 4)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SEL_SSTL18              (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELTXDRV_CI             (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELRXDRV                (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SLEW                    (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_PAD_CLK_CTL_DISABLE                   (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_WRITE_CTL_PREAMBLE_DDR3               (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_HALF                  (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_OFF                   (1 << 0)
+
+/*********************************************************************/
+/* ARM PL341 DDRC to Broadcom DDR23 PHY glue register definitions */
+/*********************************************************************/
+
+	typedef struct {
+		uint32_t cfg;
+		uint32_t actMonCnt;
+		uint32_t ctl;
+		uint32_t lbistCtl;
+		uint32_t lbistSeed;
+		uint32_t lbistStatus;
+		uint32_t tieOff;
+		uint32_t actMonClear;
+		uint32_t status;
+		uint32_t user;
+	} ddrcReg_CTLR_PHY_GLUE_REG_t;
+
+#define ddrcReg_CTLR_PHY_GLUE_OFFSET                            0x0700
+#define ddrcReg_CTLR_PHY_GLUE_REGP                              ((volatile ddrcReg_CTLR_PHY_GLUE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_PHY_GLUE_OFFSET))
+
+/* ----------------------------------------------------- */
+
+/* DDR2 / AXI block phase alignment interrupt control */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT                     18
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_MASK                      (0x3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_OFF                       (0 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_TIGHT                  (1 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_MEDIUM                 (2 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_LOOSE                  (3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT              17
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_MASK               (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_DIFFERENTIAL       (0 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_CMOS               (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT            16
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_MASK             (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_DEEP             (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW          (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_HW_FIXED_ALIGNMENT_DISABLED   ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT             15
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_MASK              (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_BP134             (0 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301             (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_REGISTERED        ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301
+
+/* Software control of PHY VDL updates from control register settings. Bit 13 enables the use of Bit 14. */
+/* If software control is not enabled, then updates occur when a refresh command is issued by the hardware */
+/* controller. If 2 chips selects are being used, then software control must be enabled. */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_LOAD    (1 << 14)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_ENABLE  (1 << 13)
+
+/* Use these to bypass a pipeline stage. By default the ADDR is off but the BYTE LANE in / out are on. */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_ADDR_CTL_IN_BYPASS_PIPELINE_STAGE (1 << 12)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_IN_BYPASS_PIPELINE_STAGE (1 << 11)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_OUT_BYPASS_PIPELINE_STAGE (1 << 10)
+
+/* Chip select count */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT                  9
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_MASK                   (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_1                      (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_2                      (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT                     8
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_ASYNC                     (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SYNC                      (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT                7
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_LOW                  (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_HIGH                 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT                6
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_LOW                  (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_HIGH                 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT             0
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_MASK              (0x7 << ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT)
+
+/* ----------------------------------------------------- */
+#define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT                0
+#define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_MASK                 (0x7f << ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT)
+
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#ifdef __cplusplus
+}				/* end extern "C" */
+#endif
+#endif				/* DDRC_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
new file mode 100644
index 0000000..375066a
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
@@ -0,0 +1,145 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    dmacHw_priv.h
+*
+*  @brief   Private Definitions for low level DMA driver
+*
+*/
+/****************************************************************************/
+
+#ifndef _DMACHW_PRIV_H
+#define _DMACHW_PRIV_H
+
+#include <csp/stdint.h>
+
+/* Data type for DMA Link List Item */
+typedef struct {
+	uint32_t sar;		/* Source Adress Register.
+				   Address must be aligned to CTLx.SRC_TR_WIDTH.             */
+	uint32_t dar;		/* Destination Address Register.
+				   Address must be aligned to CTLx.DST_TR_WIDTH.             */
+	uint32_t llpPhy;	/* LLP contains the physical address of the next descriptor for block chaining using linked lists.
+				   Address MUST be aligned to a 32-bit boundary.             */
+	dmacHw_REG64_t ctl;	/* Control Register. 64 bits */
+	uint32_t sstat;		/* Source Status Register */
+	uint32_t dstat;		/* Destination Status Register */
+	uint32_t devCtl;	/* Device specific control information */
+	uint32_t llp;		/* LLP contains the virtual address of the next descriptor for block chaining using linked lists. */
+} dmacHw_DESC_t;
+
+/*
+ *  Descriptor ring pointers
+ */
+typedef struct {
+	int num;		/* Number of link items */
+	dmacHw_DESC_t *pHead;	/* Head of descriptor ring (for writing) */
+	dmacHw_DESC_t *pTail;	/* Tail of descriptor ring (for reading) */
+	dmacHw_DESC_t *pProg;	/* Descriptor to program the channel (for programming the channel register) */
+	dmacHw_DESC_t *pEnd;	/* End of current descriptor chain */
+	dmacHw_DESC_t *pFree;	/* Descriptor to free memory (freeing dynamic memory) */
+	uint32_t virt2PhyOffset;	/* Virtual to physical address offset for the descriptor ring */
+} dmacHw_DESC_RING_t;
+
+/*
+ *  DMA channel control block
+ */
+typedef struct {
+	uint32_t module;	/* DMA controller module (0-1) */
+	uint32_t channel;	/* DMA channel (0-7) */
+	volatile uint32_t varDataStarted;	/* Flag indicating variable data channel is enabled */
+	volatile uint32_t descUpdated;	/* Flag to indicate descriptor update is complete */
+	void *userData;		/* Channel specifc user data */
+} dmacHw_CBLK_t;
+
+#define dmacHw_ASSERT(a)                  if (!(a)) while (1)
+#define dmacHw_MAX_CHANNEL_COUNT          16
+#define dmacHw_FREE_USER_MEMORY           0xFFFFFFFF
+#define dmacHw_DESC_FREE                  dmacHw_REG_CTL_DONE
+#define dmacHw_DESC_INIT                  ((dmacHw_DESC_t *) 0xFFFFFFFF)
+#define dmacHw_MAX_BLOCKSIZE              4064
+#define dmacHw_GET_DESC_RING(addr)        (dmacHw_DESC_RING_t *)(addr)
+#define dmacHw_ADDRESS_MASK(byte)         ((byte) - 1)
+#define dmacHw_NEXT_DESC(rp, dp)           ((rp)->dp = (dmacHw_DESC_t *)(rp)->dp->llp)
+#define dmacHw_HANDLE_TO_CBLK(handle)     ((dmacHw_CBLK_t *) (handle))
+#define dmacHw_CBLK_TO_HANDLE(cblkp)      ((dmacHw_HANDLE_t) (cblkp))
+#define dmacHw_DST_IS_MEMORY(tt)          (((tt) ==  dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) || ((tt) == dmacHw_TRANSFER_TYPE_MEM_TO_MEM)) ? 1 : 0
+
+/****************************************************************************/
+/**
+*  @brief   Get next available transaction width
+*
+*
+*  @return  On sucess  : Next avail able transaction width
+*           On failure : dmacHw_TRANSACTION_WIDTH_8
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+static inline dmacHw_TRANSACTION_WIDTH_e dmacHw_GetNextTrWidth(dmacHw_TRANSACTION_WIDTH_e tw	/*   [ IN ] Current transaction width */
+    ) {
+	if (tw & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) {
+		return ((tw >> dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT) -
+			 1) << dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT;
+	} else if (tw & dmacHw_REG_CTL_DST_TR_WIDTH_MASK) {
+		return ((tw >> dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT) -
+			 1) << dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT;
+	}
+
+	/* Default return  */
+	return dmacHw_SRC_TRANSACTION_WIDTH_8;
+}
+
+/****************************************************************************/
+/**
+*  @brief   Get number of bytes per transaction
+*
+*  @return  Number of bytes per transaction
+*
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+static inline int dmacHw_GetTrWidthInBytes(dmacHw_TRANSACTION_WIDTH_e tw	/*   [ IN ]  Transaction width */
+    ) {
+	int width = 1;
+	switch (tw) {
+	case dmacHw_SRC_TRANSACTION_WIDTH_8:
+		width = 1;
+		break;
+	case dmacHw_SRC_TRANSACTION_WIDTH_16:
+	case dmacHw_DST_TRANSACTION_WIDTH_16:
+		width = 2;
+		break;
+	case dmacHw_SRC_TRANSACTION_WIDTH_32:
+	case dmacHw_DST_TRANSACTION_WIDTH_32:
+		width = 4;
+		break;
+	case dmacHw_SRC_TRANSACTION_WIDTH_64:
+	case dmacHw_DST_TRANSACTION_WIDTH_64:
+		width = 8;
+		break;
+	default:
+		dmacHw_ASSERT(0);
+	}
+
+	/* Default transaction width */
+	return width;
+}
+
+#endif /* _DMACHW_PRIV_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h
new file mode 100644
index 0000000..891cea8
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h
@@ -0,0 +1,406 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    dmacHw_reg.h
+*
+*  @brief   Definitions for low level DMA registers
+*
+*/
+/****************************************************************************/
+
+#ifndef _DMACHW_REG_H
+#define _DMACHW_REG_H
+
+#include <csp/stdint.h>
+#include <mach/csp/mm_io.h>
+
+/* Data type for 64 bit little endian register */
+typedef struct {
+	volatile uint32_t lo;	/* Lower 32 bit in little endian mode */
+	volatile uint32_t hi;	/* Upper 32 bit in little endian mode */
+} dmacHw_REG64_t;
+
+/* Data type representing DMA channel registers */
+typedef struct {
+	dmacHw_REG64_t ChannelSar;	/*  Source Adress Register. 64 bits (upper 32 bits are reserved)
+					   Address must be aligned to CTLx.SRC_TR_WIDTH.
+					 */
+	dmacHw_REG64_t ChannelDar;	/*  Destination Address Register.64 bits (upper 32 bits are reserved)
+					   Address must be aligned to CTLx.DST_TR_WIDTH.
+					 */
+	dmacHw_REG64_t ChannelLlp;	/*  Link List Pointer.64 bits (upper 32 bits are reserved)
+					   LLP contains the pointer to the next LLI for block chaining using linked lists.
+					   If LLPis set to 0x0, then transfers using linked lists are not enabled.
+					   Address MUST be aligned to a 32-bit boundary.
+					 */
+	dmacHw_REG64_t ChannelCtl;	/* Control Register. 64 bits */
+	dmacHw_REG64_t ChannelSstat;	/* Source Status Register */
+	dmacHw_REG64_t ChannelDstat;	/* Destination Status Register */
+	dmacHw_REG64_t ChannelSstatAddr;	/* Source Status Address Register */
+	dmacHw_REG64_t ChannelDstatAddr;	/* Destination Status Address Register */
+	dmacHw_REG64_t ChannelConfig;	/* Channel Configuration Register */
+	dmacHw_REG64_t SrcGather;	/* Source gather register */
+	dmacHw_REG64_t DstScatter;	/* Destination scatter register */
+} dmacHw_CH_REG_t;
+
+/* Data type for RAW interrupt status registers */
+typedef struct {
+	dmacHw_REG64_t RawTfr;	/* Raw Status for IntTfr Interrupt */
+	dmacHw_REG64_t RawBlock;	/* Raw Status for IntBlock Interrupt */
+	dmacHw_REG64_t RawSrcTran;	/* Raw Status for IntSrcTran Interrupt */
+	dmacHw_REG64_t RawDstTran;	/* Raw Status for IntDstTran Interrupt */
+	dmacHw_REG64_t RawErr;	/* Raw Status for IntErr Interrupt */
+} dmacHw_INT_RAW_t;
+
+/* Data type for interrupt status registers */
+typedef struct {
+	dmacHw_REG64_t StatusTfr;	/* Status for IntTfr Interrupt */
+	dmacHw_REG64_t StatusBlock;	/* Status for IntBlock Interrupt */
+	dmacHw_REG64_t StatusSrcTran;	/* Status for IntSrcTran Interrupt */
+	dmacHw_REG64_t StatusDstTran;	/* Status for IntDstTran Interrupt */
+	dmacHw_REG64_t StatusErr;	/* Status for IntErr Interrupt */
+} dmacHw_INT_STATUS_t;
+
+/* Data type for interrupt mask registers*/
+typedef struct {
+	dmacHw_REG64_t MaskTfr;	/* Mask for IntTfr Interrupt */
+	dmacHw_REG64_t MaskBlock;	/* Mask for IntBlock Interrupt */
+	dmacHw_REG64_t MaskSrcTran;	/* Mask for IntSrcTran Interrupt */
+	dmacHw_REG64_t MaskDstTran;	/* Mask for IntDstTran Interrupt */
+	dmacHw_REG64_t MaskErr;	/* Mask for IntErr Interrupt */
+} dmacHw_INT_MASK_t;
+
+/* Data type for interrupt clear registers */
+typedef struct {
+	dmacHw_REG64_t ClearTfr;	/* Clear for IntTfr Interrupt */
+	dmacHw_REG64_t ClearBlock;	/* Clear for IntBlock Interrupt */
+	dmacHw_REG64_t ClearSrcTran;	/* Clear for IntSrcTran Interrupt */
+	dmacHw_REG64_t ClearDstTran;	/* Clear for IntDstTran Interrupt */
+	dmacHw_REG64_t ClearErr;	/* Clear for IntErr Interrupt */
+	dmacHw_REG64_t StatusInt;	/* Status for each interrupt type */
+} dmacHw_INT_CLEAR_t;
+
+/* Data type for software handshaking registers */
+typedef struct {
+	dmacHw_REG64_t ReqSrcReg;	/* Source Software Transaction Request Register */
+	dmacHw_REG64_t ReqDstReg;	/* Destination Software Transaction Request Register */
+	dmacHw_REG64_t SglReqSrcReg;	/* Single Source Transaction Request Register */
+	dmacHw_REG64_t SglReqDstReg;	/* Single Destination Transaction Request Register */
+	dmacHw_REG64_t LstSrcReg;	/* Last Source Transaction Request Register */
+	dmacHw_REG64_t LstDstReg;	/* Last Destination Transaction Request Register */
+} dmacHw_SW_HANDSHAKE_t;
+
+/* Data type for misc. registers */
+typedef struct {
+	dmacHw_REG64_t DmaCfgReg;	/* DMA Configuration Register */
+	dmacHw_REG64_t ChEnReg;	/* DMA Channel Enable Register */
+	dmacHw_REG64_t DmaIdReg;	/* DMA ID Register */
+	dmacHw_REG64_t DmaTestReg;	/* DMA Test Register */
+	dmacHw_REG64_t Reserved0;	/* Reserved */
+	dmacHw_REG64_t Reserved1;	/* Reserved */
+	dmacHw_REG64_t CompParm6;	/* Component Parameter 6 */
+	dmacHw_REG64_t CompParm5;	/* Component Parameter 5 */
+	dmacHw_REG64_t CompParm4;	/* Component Parameter 4 */
+	dmacHw_REG64_t CompParm3;	/* Component Parameter 3 */
+	dmacHw_REG64_t CompParm2;	/* Component Parameter 2 */
+	dmacHw_REG64_t CompParm1;	/* Component Parameter 1 */
+	dmacHw_REG64_t CompId;	/* Compoent ID */
+} dmacHw_MISC_t;
+
+/* Base registers */
+#define dmacHw_0_MODULE_BASE_ADDR        (char *) MM_IO_BASE_DMA0	/* DMAC 0 module's base address */
+#define dmacHw_1_MODULE_BASE_ADDR        (char *) MM_IO_BASE_DMA1	/* DMAC 1 module's base address */
+
+extern uint32_t dmaChannelCount_0;
+extern uint32_t dmaChannelCount_1;
+
+/* Define channel specific registers */
+#define dmacHw_CHAN_BASE(module, chan)          ((dmacHw_CH_REG_t *) ((char *)((module) ? dmacHw_1_MODULE_BASE_ADDR : dmacHw_0_MODULE_BASE_ADDR) + ((chan) * sizeof(dmacHw_CH_REG_t))))
+
+/* Raw interrupt status registers */
+#define dmacHw_REG_INT_RAW_BASE(module)         ((char *)dmacHw_CHAN_BASE((module), ((module) ? dmaChannelCount_1 : dmaChannelCount_0)))
+#define dmacHw_REG_INT_RAW_TRAN(module)         (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawTfr.lo)
+#define dmacHw_REG_INT_RAW_BLOCK(module)        (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawBlock.lo)
+#define dmacHw_REG_INT_RAW_STRAN(module)        (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawSrcTran.lo)
+#define dmacHw_REG_INT_RAW_DTRAN(module)        (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawDstTran.lo)
+#define dmacHw_REG_INT_RAW_ERROR(module)        (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawErr.lo)
+
+/* Interrupt status registers */
+#define dmacHw_REG_INT_STAT_BASE(module)        ((char *)(dmacHw_REG_INT_RAW_BASE((module)) + sizeof(dmacHw_INT_RAW_t)))
+#define dmacHw_REG_INT_STAT_TRAN(module)        (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusTfr.lo)
+#define dmacHw_REG_INT_STAT_BLOCK(module)       (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusBlock.lo)
+#define dmacHw_REG_INT_STAT_STRAN(module)       (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusSrcTran.lo)
+#define dmacHw_REG_INT_STAT_DTRAN(module)       (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusDstTran.lo)
+#define dmacHw_REG_INT_STAT_ERROR(module)       (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusErr.lo)
+
+/* Interrupt status registers */
+#define dmacHw_REG_INT_MASK_BASE(module)        ((char *)(dmacHw_REG_INT_STAT_BASE((module)) + sizeof(dmacHw_INT_STATUS_t)))
+#define dmacHw_REG_INT_MASK_TRAN(module)        (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskTfr.lo)
+#define dmacHw_REG_INT_MASK_BLOCK(module)       (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskBlock.lo)
+#define dmacHw_REG_INT_MASK_STRAN(module)       (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskSrcTran.lo)
+#define dmacHw_REG_INT_MASK_DTRAN(module)       (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskDstTran.lo)
+#define dmacHw_REG_INT_MASK_ERROR(module)       (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskErr.lo)
+
+/* Interrupt clear registers */
+#define dmacHw_REG_INT_CLEAR_BASE(module)       ((char *)(dmacHw_REG_INT_MASK_BASE((module)) + sizeof(dmacHw_INT_MASK_t)))
+#define dmacHw_REG_INT_CLEAR_TRAN(module)       (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearTfr.lo)
+#define dmacHw_REG_INT_CLEAR_BLOCK(module)      (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearBlock.lo)
+#define dmacHw_REG_INT_CLEAR_STRAN(module)      (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearSrcTran.lo)
+#define dmacHw_REG_INT_CLEAR_DTRAN(module)      (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearDstTran.lo)
+#define dmacHw_REG_INT_CLEAR_ERROR(module)      (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearErr.lo)
+#define dmacHw_REG_INT_STATUS(module)           (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->StatusInt.lo)
+
+/* Software handshaking registers */
+#define dmacHw_REG_SW_HS_BASE(module)           ((char *)(dmacHw_REG_INT_CLEAR_BASE((module)) + sizeof(dmacHw_INT_CLEAR_t)))
+#define dmacHw_REG_SW_HS_SRC_REQ(module)        (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqSrcReg.lo)
+#define dmacHw_REG_SW_HS_DST_REQ(module)        (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqDstReg.lo)
+#define dmacHw_REG_SW_HS_SRC_SGL_REQ(module)    (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqSrcReg.lo)
+#define dmacHw_REG_SW_HS_DST_SGL_REQ(module)    (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqDstReg.lo)
+#define dmacHw_REG_SW_HS_SRC_LST_REQ(module)    (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstSrcReg.lo)
+#define dmacHw_REG_SW_HS_DST_LST_REQ(module)    (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstDstReg.lo)
+
+/* Miscellaneous registers */
+#define dmacHw_REG_MISC_BASE(module)            ((char *)(dmacHw_REG_SW_HS_BASE((module)) + sizeof(dmacHw_SW_HANDSHAKE_t)))
+#define dmacHw_REG_MISC_CFG(module)             (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaCfgReg.lo)
+#define dmacHw_REG_MISC_CH_ENABLE(module)       (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->ChEnReg.lo)
+#define dmacHw_REG_MISC_ID(module)              (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaIdReg.lo)
+#define dmacHw_REG_MISC_TEST(module)            (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaTestReg.lo)
+#define dmacHw_REG_MISC_COMP_PARAM1_LO(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.lo)
+#define dmacHw_REG_MISC_COMP_PARAM1_HI(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.hi)
+#define dmacHw_REG_MISC_COMP_PARAM2_LO(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.lo)
+#define dmacHw_REG_MISC_COMP_PARAM2_HI(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.hi)
+#define dmacHw_REG_MISC_COMP_PARAM3_LO(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.lo)
+#define dmacHw_REG_MISC_COMP_PARAM3_HI(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.hi)
+#define dmacHw_REG_MISC_COMP_PARAM4_LO(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.lo)
+#define dmacHw_REG_MISC_COMP_PARAM4_HI(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.hi)
+#define dmacHw_REG_MISC_COMP_PARAM5_LO(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.lo)
+#define dmacHw_REG_MISC_COMP_PARAM5_HI(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.hi)
+#define dmacHw_REG_MISC_COMP_PARAM6_LO(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.lo)
+#define dmacHw_REG_MISC_COMP_PARAM6_HI(module)  (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.hi)
+
+/* Channel control registers */
+#define dmacHw_REG_SAR(module, chan)            (dmacHw_CHAN_BASE((module), (chan))->ChannelSar.lo)
+#define dmacHw_REG_DAR(module, chan)            (dmacHw_CHAN_BASE((module), (chan))->ChannelDar.lo)
+#define dmacHw_REG_LLP(module, chan)            (dmacHw_CHAN_BASE((module), (chan))->ChannelLlp.lo)
+
+#define dmacHw_REG_CTL_LO(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.lo)
+#define dmacHw_REG_CTL_HI(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.hi)
+
+#define dmacHw_REG_SSTAT(module, chan)          (dmacHw_CHAN_BASE((module), (chan))->ChannelSstat.lo)
+#define dmacHw_REG_DSTAT(module, chan)          (dmacHw_CHAN_BASE((module), (chan))->ChannelDstat.lo)
+#define dmacHw_REG_SSTATAR(module, chan)        (dmacHw_CHAN_BASE((module), (chan))->ChannelSstatAddr.lo)
+#define dmacHw_REG_DSTATAR(module, chan)        (dmacHw_CHAN_BASE((module), (chan))->ChannelDstatAddr.lo)
+
+#define dmacHw_REG_CFG_LO(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.lo)
+#define dmacHw_REG_CFG_HI(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.hi)
+
+#define dmacHw_REG_SGR_LO(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->SrcGather.lo)
+#define dmacHw_REG_SGR_HI(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->SrcGather.hi)
+
+#define dmacHw_REG_DSR_LO(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->DstScatter.lo)
+#define dmacHw_REG_DSR_HI(module, chan)         (dmacHw_CHAN_BASE((module), (chan))->DstScatter.hi)
+
+#define INT_STATUS_MASK(channel)                (0x00000001 << (channel))
+#define CHANNEL_BUSY(mod, channel)              (dmacHw_REG_MISC_CH_ENABLE((mod)) & (0x00000001 << (channel)))
+
+/* Bit mask for REG_DMACx_CTL_LO */
+
+#define dmacHw_REG_CTL_INT_EN                       0x00000001	/* Channel interrupt enable */
+
+#define dmacHw_REG_CTL_DST_TR_WIDTH_MASK            0x0000000E	/* Destination transaction width mask */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT           1
+#define dmacHw_REG_CTL_DST_TR_WIDTH_8               0x00000000	/* Destination transaction width 8 bit */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_16              0x00000002	/* Destination transaction width 16 bit */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_32              0x00000004	/* Destination transaction width 32 bit */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_64              0x00000006	/* Destination transaction width 64 bit */
+
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_MASK            0x00000070	/* Source transaction width mask */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT           4
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_8               0x00000000	/* Source transaction width 8 bit */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_16              0x00000010	/* Source transaction width 16 bit */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_32              0x00000020	/* Source transaction width 32 bit */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_64              0x00000030	/* Source transaction width 64 bit */
+
+#define dmacHw_REG_CTL_DS_ENABLE                    0x00040000	/* Destination scatter enable */
+#define dmacHw_REG_CTL_SG_ENABLE                    0x00020000	/* Source gather enable */
+
+#define dmacHw_REG_CTL_DINC_MASK                    0x00000180	/* Destination address inc/dec mask */
+#define dmacHw_REG_CTL_DINC_INC                     0x00000000	/* Destination address increment */
+#define dmacHw_REG_CTL_DINC_DEC                     0x00000080	/* Destination address decrement */
+#define dmacHw_REG_CTL_DINC_NC                      0x00000100	/* Destination address no change */
+
+#define dmacHw_REG_CTL_SINC_MASK                    0x00000600	/* Source address inc/dec mask */
+#define dmacHw_REG_CTL_SINC_INC                     0x00000000	/* Source address increment */
+#define dmacHw_REG_CTL_SINC_DEC                     0x00000200	/* Source address decrement */
+#define dmacHw_REG_CTL_SINC_NC                      0x00000400	/* Source address no change */
+
+#define dmacHw_REG_CTL_DST_MSIZE_MASK               0x00003800	/* Destination burst transaction length */
+#define dmacHw_REG_CTL_DST_MSIZE_0                  0x00000000	/* No Destination burst */
+#define dmacHw_REG_CTL_DST_MSIZE_4                  0x00000800	/* Destination burst transaction length 4 */
+#define dmacHw_REG_CTL_DST_MSIZE_8                  0x00001000	/* Destination burst transaction length 8 */
+#define dmacHw_REG_CTL_DST_MSIZE_16                 0x00001800	/* Destination burst transaction length 16 */
+
+#define dmacHw_REG_CTL_SRC_MSIZE_MASK               0x0001C000	/* Source burst transaction length */
+#define dmacHw_REG_CTL_SRC_MSIZE_0                  0x00000000	/* No Source burst */
+#define dmacHw_REG_CTL_SRC_MSIZE_4                  0x00004000	/* Source burst transaction length 4 */
+#define dmacHw_REG_CTL_SRC_MSIZE_8                  0x00008000	/* Source burst transaction length 8 */
+#define dmacHw_REG_CTL_SRC_MSIZE_16                 0x0000C000	/* Source burst transaction length 16 */
+
+#define dmacHw_REG_CTL_TTFC_MASK                    0x00700000	/* Transfer type and flow controller */
+#define dmacHw_REG_CTL_TTFC_MM_DMAC                 0x00000000	/* Memory to Memory with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_MP_DMAC                 0x00100000	/* Memory to Peripheral with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_PM_DMAC                 0x00200000	/* Peripheral to Memory with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_PP_DMAC                 0x00300000	/* Peripheral to Peripheral with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_PM_PERI                 0x00400000	/* Peripheral to Memory with Peripheral as flow controller */
+#define dmacHw_REG_CTL_TTFC_PP_SPERI                0x00500000	/* Peripheral to Peripheral with Source Peripheral as flow controller */
+#define dmacHw_REG_CTL_TTFC_MP_PERI                 0x00600000	/* Memory to Peripheral with Peripheral as flow controller */
+#define dmacHw_REG_CTL_TTFC_PP_DPERI                0x00700000	/* Peripheral to Peripheral with Destination Peripheral as flow controller */
+
+#define dmacHw_REG_CTL_DMS_MASK                     0x01800000	/* Destination AHB master interface */
+#define dmacHw_REG_CTL_DMS_1                        0x00000000	/* Destination AHB master interface 1 */
+#define dmacHw_REG_CTL_DMS_2                        0x00800000	/* Destination AHB master interface 2 */
+
+#define dmacHw_REG_CTL_SMS_MASK                     0x06000000	/* Source AHB master interface */
+#define dmacHw_REG_CTL_SMS_1                        0x00000000	/* Source AHB master interface 1 */
+#define dmacHw_REG_CTL_SMS_2                        0x02000000	/* Source AHB master interface 2 */
+
+#define dmacHw_REG_CTL_LLP_DST_EN                   0x08000000	/* Block chaining enable for destination side */
+#define dmacHw_REG_CTL_LLP_SRC_EN                   0x10000000	/* Block chaining enable for source side */
+
+/* Bit mask for REG_DMACx_CTL_HI */
+#define dmacHw_REG_CTL_BLOCK_TS_MASK                0x00000FFF	/* Block transfer size */
+#define dmacHw_REG_CTL_DONE                         0x00001000	/* Block trasnfer done */
+
+/* Bit mask for REG_DMACx_CFG_LO */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_SHIFT                  5	/* Channel priority shift */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_MASK          0x000000E0	/* Channel priority mask */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_0             0x00000000	/* Channel priority 0 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_1             0x00000020	/* Channel priority 1 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_2             0x00000040	/* Channel priority 2 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_3             0x00000060	/* Channel priority 3 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_4             0x00000080	/* Channel priority 4 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_5             0x000000A0	/* Channel priority 5 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_6             0x000000C0	/* Channel priority 6 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_7             0x000000E0	/* Channel priority 7 */
+
+#define dmacHw_REG_CFG_LO_CH_SUSPEND                0x00000100	/* Channel suspend */
+#define dmacHw_REG_CFG_LO_CH_FIFO_EMPTY             0x00000200	/* Channel FIFO empty */
+#define dmacHw_REG_CFG_LO_DST_CH_SW_HS              0x00000400	/* Destination channel SW handshaking */
+#define dmacHw_REG_CFG_LO_SRC_CH_SW_HS              0x00000800	/* Source channel SW handshaking */
+
+#define dmacHw_REG_CFG_LO_CH_LOCK_MASK              0x00003000	/* Channel locking mask */
+#define dmacHw_REG_CFG_LO_CH_LOCK_DMA               0x00000000	/* Channel lock over the entire DMA transfer operation */
+#define dmacHw_REG_CFG_LO_CH_LOCK_BLOCK             0x00001000	/* Channel lock over the block transfer operation */
+#define dmacHw_REG_CFG_LO_CH_LOCK_TRANS             0x00002000	/* Channel lock over the transaction */
+#define dmacHw_REG_CFG_LO_CH_LOCK_ENABLE            0x00010000	/* Channel lock enable */
+
+#define dmacHw_REG_CFG_LO_BUS_LOCK_MASK             0x0000C000	/* Bus locking mask */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_DMA              0x00000000	/* Bus lock over the entire DMA transfer operation */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_BLOCK            0x00004000	/* Bus lock over the block transfer operation */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_TRANS            0x00008000	/* Bus lock over the transaction */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_ENABLE           0x00020000	/* Bus lock enable */
+
+#define dmacHw_REG_CFG_LO_DST_HS_POLARITY_LOW       0x00040000	/* Destination channel handshaking signal polarity low */
+#define dmacHw_REG_CFG_LO_SRC_HS_POLARITY_LOW       0x00080000	/* Source channel handshaking signal polarity low */
+
+#define dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK   0x3FF00000	/* Maximum AMBA burst length */
+
+#define dmacHw_REG_CFG_LO_AUTO_RELOAD_SRC           0x40000000	/* Source address auto reload */
+#define dmacHw_REG_CFG_LO_AUTO_RELOAD_DST           0x80000000	/* Destination address auto reload */
+
+/* Bit mask for REG_DMACx_CFG_HI */
+#define dmacHw_REG_CFG_HI_FC_DST_READY              0x00000001	/* Source transaction request is serviced when destination is ready */
+#define dmacHw_REG_CFG_HI_FIFO_ENOUGH               0x00000002	/* Initiate burst transaction when enough data in available in FIFO */
+
+#define dmacHw_REG_CFG_HI_AHB_HPROT_MASK            0x0000001C	/* AHB protection mask */
+#define dmacHw_REG_CFG_HI_AHB_HPROT_1               0x00000004	/* AHB protection 1 */
+#define dmacHw_REG_CFG_HI_AHB_HPROT_2               0x00000008	/* AHB protection 2 */
+#define dmacHw_REG_CFG_HI_AHB_HPROT_3               0x00000010	/* AHB protection 3 */
+
+#define dmacHw_REG_CFG_HI_UPDATE_DST_STAT           0x00000020	/* Destination status update enable */
+#define dmacHw_REG_CFG_HI_UPDATE_SRC_STAT           0x00000040	/* Source status update enable */
+
+#define dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK        0x00000780	/* Source peripheral hardware interface mask */
+#define dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK        0x00007800	/* Destination peripheral hardware interface mask */
+
+/* DMA Configuration Parameters */
+#define dmacHw_REG_COMP_PARAM_NUM_CHANNELS          0x00000700	/* Number of channels */
+#define dmacHw_REG_COMP_PARAM_NUM_INTERFACE         0x00001800	/* Number of master interface */
+#define dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE          0x0000000f	/* Maximum brust size */
+#define dmacHw_REG_COMP_PARAM_DATA_WIDTH            0x00006000	/* Data transfer width */
+
+/* Define GET/SET macros to program the registers */
+#define dmacHw_SET_SAR(module, channel, addr)          (dmacHw_REG_SAR((module), (channel)) = (uint32_t) (addr))
+#define dmacHw_SET_DAR(module, channel, addr)          (dmacHw_REG_DAR((module), (channel)) = (uint32_t) (addr))
+#define dmacHw_SET_LLP(module, channel, ptr)           (dmacHw_REG_LLP((module), (channel)) = (uint32_t) (ptr))
+
+#define dmacHw_GET_SSTAT(module, channel)              (dmacHw_REG_SSTAT((module), (channel)))
+#define dmacHw_GET_DSTAT(module, channel)              (dmacHw_REG_DSTAT((module), (channel)))
+
+#define dmacHw_SET_SSTATAR(module, channel, addr)      (dmacHw_REG_SSTATAR((module), (channel)) = (uint32_t) (addr))
+#define dmacHw_SET_DSTATAR(module, channel, addr)      (dmacHw_REG_DSTATAR((module), (channel)) = (uint32_t) (addr))
+
+#define dmacHw_SET_CONTROL_LO(module, channel, ctl)    (dmacHw_REG_CTL_LO((module), (channel)) |= (ctl))
+#define dmacHw_RESET_CONTROL_LO(module, channel)       (dmacHw_REG_CTL_LO((module), (channel)) = 0)
+#define dmacHw_GET_CONTROL_LO(module, channel)         (dmacHw_REG_CTL_LO((module), (channel)))
+
+#define dmacHw_SET_CONTROL_HI(module, channel, ctl)    (dmacHw_REG_CTL_HI((module), (channel)) |= (ctl))
+#define dmacHw_RESET_CONTROL_HI(module, channel)       (dmacHw_REG_CTL_HI((module), (channel)) = 0)
+#define dmacHw_GET_CONTROL_HI(module, channel)         (dmacHw_REG_CTL_HI((module), (channel)))
+
+#define dmacHw_GET_BLOCK_SIZE(module, channel)         (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_BLOCK_TS_MASK)
+#define dmacHw_DMA_COMPLETE(module, channel)           (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_DONE)
+
+#define dmacHw_SET_CONFIG_LO(module, channel, cfg)     (dmacHw_REG_CFG_LO((module), (channel)) |= (cfg))
+#define dmacHw_RESET_CONFIG_LO(module, channel)        (dmacHw_REG_CFG_LO((module), (channel)) = 0)
+#define dmacHw_GET_CONFIG_LO(module, channel)          (dmacHw_REG_CFG_LO((module), (channel)))
+#define dmacHw_SET_AMBA_BUSRT_LEN(module, channel, len)    (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK)) | (((len) << 20) & dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK))
+#define dmacHw_SET_CHANNEL_PRIORITY(module, channel, prio) (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_CH_PRIORITY_MASK)) | (prio))
+#define dmacHw_SET_AHB_HPROT(module, channel, protect)  (dmacHw_REG_CFG_HI(module, channel) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_AHB_HPROT_MASK)) | (protect))
+
+#define dmacHw_SET_CONFIG_HI(module, channel, cfg)      (dmacHw_REG_CFG_HI((module), (channel)) |= (cfg))
+#define dmacHw_RESET_CONFIG_HI(module, channel)         (dmacHw_REG_CFG_HI((module), (channel)) = 0)
+#define dmacHw_GET_CONFIG_HI(module, channel)           (dmacHw_REG_CFG_HI((module), (channel)))
+#define dmacHw_SET_SRC_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)) | (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK))
+#define dmacHw_SRC_PERI_INTF(intf)                      (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)
+#define dmacHw_SET_DST_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)) | (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK))
+#define dmacHw_DST_PERI_INTF(intf)                      (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)
+
+#define dmacHw_DMA_START(module, channel)              (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+#define dmacHw_DMA_STOP(module, channel)               (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_DMA_ENABLE(module)                      (dmacHw_REG_MISC_CFG((module)) = 1)
+#define dmacHw_DMA_DISABLE(module)                     (dmacHw_REG_MISC_CFG((module)) = 0)
+
+#define dmacHw_TRAN_INT_ENABLE(module, channel)        (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+#define dmacHw_BLOCK_INT_ENABLE(module, channel)       (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+#define dmacHw_ERROR_INT_ENABLE(module, channel)       (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+
+#define dmacHw_TRAN_INT_DISABLE(module, channel)       (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_BLOCK_INT_DISABLE(module, channel)      (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_ERROR_INT_DISABLE(module, channel)      (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_STRAN_INT_DISABLE(module, channel)      (dmacHw_REG_INT_MASK_STRAN((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_DTRAN_INT_DISABLE(module, channel)      (dmacHw_REG_INT_MASK_DTRAN((module)) = (0x00000001 << ((channel) + 8)))
+
+#define dmacHw_TRAN_INT_CLEAR(module, channel)         (dmacHw_REG_INT_CLEAR_TRAN((module)) = (0x00000001 << (channel)))
+#define dmacHw_BLOCK_INT_CLEAR(module, channel)        (dmacHw_REG_INT_CLEAR_BLOCK((module)) = (0x00000001 << (channel)))
+#define dmacHw_ERROR_INT_CLEAR(module, channel)        (dmacHw_REG_INT_CLEAR_ERROR((module)) = (0x00000001 << (channel)))
+
+#define dmacHw_GET_NUM_CHANNEL(module)                 (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_CHANNELS) >> 8) + 1)
+#define dmacHw_GET_NUM_INTERFACE(module)               (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_INTERFACE) >> 11) + 1)
+#define dmacHw_GET_MAX_BLOCK_SIZE(module, channel)     ((dmacHw_REG_MISC_COMP_PARAM1_LO((module)) >> (4 * (channel))) & dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE)
+#define dmacHw_GET_CHANNEL_DATA_WIDTH(module, channel) ((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_DATA_WIDTH) >> 13)
+
+#endif /* _DMACHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h
new file mode 100644
index 0000000..cfa91be
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h
@@ -0,0 +1,73 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+#ifndef CSP_HW_CFG_H
+#define CSP_HW_CFG_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <cfg_global.h>
+#include <mach/csp/cap_inline.h>
+
+#if defined(__KERNEL__)
+#include <mach/memory_settings.h>
+#else
+#include <hw_cfg.h>
+#endif
+
+/* Some items that can be defined externally, but will be set to default values */
+/* if they are not defined. */
+/*      HW_CFG_PLL_SPREAD_SPECTRUM_DISABLE   Default undefined and SS is enabled. */
+/*      HW_CFG_SDRAM_CAS_LATENCY        5    Default 5, Values [3..6] */
+/*      HW_CFG_SDRAM_CHIP_SELECT_CNT    1    Default 1, Vaules [1..2] */
+/*      HW_CFG_SDRAM_SPEED_GRADE        667  Default 667, Values [400,533,667,800] */
+/*      HW_CFG_SDRAM_WIDTH_BITS         16   Default 16, Vaules [8,16] */
+/*      HW_CFG_SDRAM_ADDR_BRC                Default undefined and Row-Bank-Col (RBC) addressing used. Define to use Bank-Row-Col (BRC). */
+/*      HW_CFG_SDRAM_CLK_ASYNC               Default undefined and DDR clock is synchronous with AXI BUS clock. Define for ASYNC mode. */
+
+#if defined(CFG_GLOBAL_CHIP)
+  #if (CFG_GLOBAL_CHIP == FPGA11107)
+     #define HW_CFG_BUS_CLK_HZ            5000000
+     #define HW_CFG_DDR_CTLR_CLK_HZ      10000000
+     #define HW_CFG_DDR_PHY_OMIT
+     #define HW_CFG_UART_CLK_HZ           7500000
+  #else
+     #define HW_CFG_PLL_VCO_HZ           2000000000
+     #define HW_CFG_PLL2_VCO_HZ          1800000000
+     #define HW_CFG_ARM_CLK_HZ            CAP_HW_CFG_ARM_CLK_HZ
+     #define HW_CFG_BUS_CLK_HZ            166666666
+     #define HW_CFG_DDR_CTLR_CLK_HZ       333333333
+     #define HW_CFG_DDR_PHY_CLK_HZ        (2 * HW_CFG_DDR_CTLR_CLK_HZ)
+     #define HW_CFG_UART_CLK_HZ           142857142
+     #define HW_CFG_VPM_CLK_HZ            CAP_HW_CFG_VPM_CLK_HZ
+  #endif
+#else
+   #define HW_CFG_PLL_VCO_HZ           1800000000
+   #define HW_CFG_PLL2_VCO_HZ          1800000000
+   #define HW_CFG_ARM_CLK_HZ            450000000
+   #define HW_CFG_BUS_CLK_HZ            150000000
+   #define HW_CFG_DDR_CTLR_CLK_HZ       300000000
+   #define HW_CFG_DDR_PHY_CLK_HZ        (2 * HW_CFG_DDR_CTLR_CLK_HZ)
+   #define HW_CFG_UART_CLK_HZ           150000000
+   #define HW_CFG_VPM_CLK_HZ            300000000
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+
+#endif /* CSP_HW_CFG_H */
+
diff --git a/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h
new file mode 100644
index 0000000..e01fc46
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h
@@ -0,0 +1,246 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    intcHw_reg.h
+*
+*  @brief   platform specific interrupt controller bit assignments
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+
+#ifndef _INTCHW_REG_H
+#define _INTCHW_REG_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/stdint.h>
+#include <csp/reg.h>
+#include <mach/csp/mm_io.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#define INTCHW_NUM_IRQ_PER_INTC   32	/* Maximum number of interrupt controllers */
+#define INTCHW_NUM_INTC           3
+
+/* Defines for interrupt controllers. This simplifies and cleans up the function calls. */
+#define INTCHW_INTC0    ((void *)MM_IO_BASE_INTC0)
+#define INTCHW_INTC1    ((void *)MM_IO_BASE_INTC1)
+#define INTCHW_SINTC    ((void *)MM_IO_BASE_SINTC)
+
+/* INTC0 - interrupt controller 0 */
+#define INTCHW_INTC0_PIF_BITNUM           31	/* Peripheral interface interrupt */
+#define INTCHW_INTC0_CLCD_BITNUM          30	/* LCD Controller interrupt */
+#define INTCHW_INTC0_GE_BITNUM            29	/* Graphic engine interrupt */
+#define INTCHW_INTC0_APM_BITNUM           28	/* Audio process module interrupt */
+#define INTCHW_INTC0_ESW_BITNUM           27	/* Ethernet switch interrupt */
+#define INTCHW_INTC0_SPIH_BITNUM          26	/* SPI host interrupt */
+#define INTCHW_INTC0_TIMER3_BITNUM        25	/* Timer3 interrupt */
+#define INTCHW_INTC0_TIMER2_BITNUM        24	/* Timer2 interrupt */
+#define INTCHW_INTC0_TIMER1_BITNUM        23	/* Timer1 interrupt */
+#define INTCHW_INTC0_TIMER0_BITNUM        22	/* Timer0 interrupt */
+#define INTCHW_INTC0_SDIOH1_BITNUM        21	/* SDIO1 host interrupt */
+#define INTCHW_INTC0_SDIOH0_BITNUM        20	/* SDIO0 host interrupt */
+#define INTCHW_INTC0_USBD_BITNUM          19	/* USB device interrupt */
+#define INTCHW_INTC0_USBH1_BITNUM         18	/* USB1 host interrupt */
+#define INTCHW_INTC0_USBHD2_BITNUM        17	/* USB host2/device2 interrupt */
+#define INTCHW_INTC0_VPM_BITNUM           16	/* Voice process module interrupt */
+#define INTCHW_INTC0_DMA1C7_BITNUM        15	/* DMA1 channel 7 interrupt */
+#define INTCHW_INTC0_DMA1C6_BITNUM        14	/* DMA1 channel 6 interrupt */
+#define INTCHW_INTC0_DMA1C5_BITNUM        13	/* DMA1 channel 5 interrupt */
+#define INTCHW_INTC0_DMA1C4_BITNUM        12	/* DMA1 channel 4 interrupt */
+#define INTCHW_INTC0_DMA1C3_BITNUM        11	/* DMA1 channel 3 interrupt */
+#define INTCHW_INTC0_DMA1C2_BITNUM        10	/* DMA1 channel 2 interrupt */
+#define INTCHW_INTC0_DMA1C1_BITNUM         9	/* DMA1 channel 1 interrupt */
+#define INTCHW_INTC0_DMA1C0_BITNUM         8	/* DMA1 channel 0 interrupt */
+#define INTCHW_INTC0_DMA0C7_BITNUM         7	/* DMA0 channel 7 interrupt */
+#define INTCHW_INTC0_DMA0C6_BITNUM         6	/* DMA0 channel 6 interrupt */
+#define INTCHW_INTC0_DMA0C5_BITNUM         5	/* DMA0 channel 5 interrupt */
+#define INTCHW_INTC0_DMA0C4_BITNUM         4	/* DMA0 channel 4 interrupt */
+#define INTCHW_INTC0_DMA0C3_BITNUM         3	/* DMA0 channel 3 interrupt */
+#define INTCHW_INTC0_DMA0C2_BITNUM         2	/* DMA0 channel 2 interrupt */
+#define INTCHW_INTC0_DMA0C1_BITNUM         1	/* DMA0 channel 1 interrupt */
+#define INTCHW_INTC0_DMA0C0_BITNUM         0	/* DMA0 channel 0 interrupt */
+
+#define INTCHW_INTC0_PIF                  (1<<INTCHW_INTC0_PIF_BITNUM)
+#define INTCHW_INTC0_CLCD                 (1<<INTCHW_INTC0_CLCD_BITNUM)
+#define INTCHW_INTC0_GE                   (1<<INTCHW_INTC0_GE_BITNUM)
+#define INTCHW_INTC0_APM                  (1<<INTCHW_INTC0_APM_BITNUM)
+#define INTCHW_INTC0_ESW                  (1<<INTCHW_INTC0_ESW_BITNUM)
+#define INTCHW_INTC0_SPIH                 (1<<INTCHW_INTC0_SPIH_BITNUM)
+#define INTCHW_INTC0_TIMER3               (1<<INTCHW_INTC0_TIMER3_BITNUM)
+#define INTCHW_INTC0_TIMER2               (1<<INTCHW_INTC0_TIMER2_BITNUM)
+#define INTCHW_INTC0_TIMER1               (1<<INTCHW_INTC0_TIMER1_BITNUM)
+#define INTCHW_INTC0_TIMER0               (1<<INTCHW_INTC0_TIMER0_BITNUM)
+#define INTCHW_INTC0_SDIOH1               (1<<INTCHW_INTC0_SDIOH1_BITNUM)
+#define INTCHW_INTC0_SDIOH0               (1<<INTCHW_INTC0_SDIOH0_BITNUM)
+#define INTCHW_INTC0_USBD                 (1<<INTCHW_INTC0_USBD_BITNUM)
+#define INTCHW_INTC0_USBH1                (1<<INTCHW_INTC0_USBH1_BITNUM)
+#define INTCHW_INTC0_USBHD2               (1<<INTCHW_INTC0_USBHD2_BITNUM)
+#define INTCHW_INTC0_VPM                  (1<<INTCHW_INTC0_VPM_BITNUM)
+#define INTCHW_INTC0_DMA1C7               (1<<INTCHW_INTC0_DMA1C7_BITNUM)
+#define INTCHW_INTC0_DMA1C6               (1<<INTCHW_INTC0_DMA1C6_BITNUM)
+#define INTCHW_INTC0_DMA1C5               (1<<INTCHW_INTC0_DMA1C5_BITNUM)
+#define INTCHW_INTC0_DMA1C4               (1<<INTCHW_INTC0_DMA1C4_BITNUM)
+#define INTCHW_INTC0_DMA1C3               (1<<INTCHW_INTC0_DMA1C3_BITNUM)
+#define INTCHW_INTC0_DMA1C2               (1<<INTCHW_INTC0_DMA1C2_BITNUM)
+#define INTCHW_INTC0_DMA1C1               (1<<INTCHW_INTC0_DMA1C1_BITNUM)
+#define INTCHW_INTC0_DMA1C0               (1<<INTCHW_INTC0_DMA1C0_BITNUM)
+#define INTCHW_INTC0_DMA0C7               (1<<INTCHW_INTC0_DMA0C7_BITNUM)
+#define INTCHW_INTC0_DMA0C6               (1<<INTCHW_INTC0_DMA0C6_BITNUM)
+#define INTCHW_INTC0_DMA0C5               (1<<INTCHW_INTC0_DMA0C5_BITNUM)
+#define INTCHW_INTC0_DMA0C4               (1<<INTCHW_INTC0_DMA0C4_BITNUM)
+#define INTCHW_INTC0_DMA0C3               (1<<INTCHW_INTC0_DMA0C3_BITNUM)
+#define INTCHW_INTC0_DMA0C2               (1<<INTCHW_INTC0_DMA0C2_BITNUM)
+#define INTCHW_INTC0_DMA0C1               (1<<INTCHW_INTC0_DMA0C1_BITNUM)
+#define INTCHW_INTC0_DMA0C0               (1<<INTCHW_INTC0_DMA0C0_BITNUM)
+
+/* INTC1 - interrupt controller 1 */
+#define INTCHW_INTC1_DDRVPMP_BITNUM       27	/* DDR and VPM PLL clock phase relationship interupt (Not for A0) */
+#define INTCHW_INTC1_DDRVPMT_BITNUM       26	/* DDR and VPM HW phase align timeout interrupt (Not for A0) */
+#define INTCHW_INTC1_DDRP_BITNUM          26	/* DDR and PLL clock phase relationship interupt (For A0 only)) */
+#define INTCHW_INTC1_RTC2_BITNUM          25	/* Real time clock tamper interrupt */
+#define INTCHW_INTC1_VDEC_BITNUM          24	/* Hantro Video Decoder interrupt */
+/* Bits 13-23 are non-secure versions of the corresponding secure bits in SINTC bits 0-10. */
+#define INTCHW_INTC1_SPUM_BITNUM          23	/* Secure process module interrupt */
+#define INTCHW_INTC1_RTC1_BITNUM          22	/* Real time clock one-shot interrupt */
+#define INTCHW_INTC1_RTC0_BITNUM          21	/* Real time clock periodic interrupt */
+#define INTCHW_INTC1_RNG_BITNUM           20	/* Random number generator interrupt */
+#define INTCHW_INTC1_FMPU_BITNUM          19	/* Flash memory parition unit interrupt */
+#define INTCHW_INTC1_VMPU_BITNUM          18	/* VRAM memory partition interrupt */
+#define INTCHW_INTC1_DMPU_BITNUM          17	/* DDR2 memory partition interrupt */
+#define INTCHW_INTC1_KEYC_BITNUM          16	/* Key pad controller interrupt */
+#define INTCHW_INTC1_TSC_BITNUM           15	/* Touch screen controller interrupt */
+#define INTCHW_INTC1_UART0_BITNUM         14	/* UART 0 */
+#define INTCHW_INTC1_WDOG_BITNUM          13	/* Watchdog timer interrupt */
+
+#define INTCHW_INTC1_UART1_BITNUM         12	/* UART 1 */
+#define INTCHW_INTC1_PMUIRQ_BITNUM        11	/* ARM performance monitor interrupt */
+#define INTCHW_INTC1_COMMRX_BITNUM        10	/* ARM DDC receive interrupt */
+#define INTCHW_INTC1_COMMTX_BITNUM         9	/* ARM DDC transmit interrupt */
+#define INTCHW_INTC1_FLASHC_BITNUM         8	/* Flash controller interrupt */
+#define INTCHW_INTC1_GPHY_BITNUM           7	/* Gigabit Phy interrupt */
+#define INTCHW_INTC1_SPIS_BITNUM           6	/* SPI slave interrupt */
+#define INTCHW_INTC1_I2CS_BITNUM           5	/* I2C slave interrupt */
+#define INTCHW_INTC1_I2CH_BITNUM           4	/* I2C host interrupt */
+#define INTCHW_INTC1_I2S1_BITNUM           3	/* I2S1 interrupt */
+#define INTCHW_INTC1_I2S0_BITNUM           2	/* I2S0 interrupt */
+#define INTCHW_INTC1_GPIO1_BITNUM          1	/* GPIO bit 64//32 combined interrupt */
+#define INTCHW_INTC1_GPIO0_BITNUM          0	/* GPIO bit 31//0 combined interrupt */
+
+#define INTCHW_INTC1_DDRVPMT              (1<<INTCHW_INTC1_DDRVPMT_BITNUM)
+#define INTCHW_INTC1_DDRVPMP              (1<<INTCHW_INTC1_DDRVPMP_BITNUM)
+#define INTCHW_INTC1_DDRP                 (1<<INTCHW_INTC1_DDRP_BITNUM)
+#define INTCHW_INTC1_VDEC                 (1<<INTCHW_INTC1_VDEC_BITNUM)
+#define INTCHW_INTC1_SPUM                 (1<<INTCHW_INTC1_SPUM_BITNUM)
+#define INTCHW_INTC1_RTC2                 (1<<INTCHW_INTC1_RTC2_BITNUM)
+#define INTCHW_INTC1_RTC1                 (1<<INTCHW_INTC1_RTC1_BITNUM)
+#define INTCHW_INTC1_RTC0                 (1<<INTCHW_INTC1_RTC0_BITNUM)
+#define INTCHW_INTC1_RNG                  (1<<INTCHW_INTC1_RNG_BITNUM)
+#define INTCHW_INTC1_FMPU                 (1<<INTCHW_INTC1_FMPU_BITNUM)
+#define INTCHW_INTC1_IMPU                 (1<<INTCHW_INTC1_IMPU_BITNUM)
+#define INTCHW_INTC1_DMPU                 (1<<INTCHW_INTC1_DMPU_BITNUM)
+#define INTCHW_INTC1_KEYC                 (1<<INTCHW_INTC1_KEYC_BITNUM)
+#define INTCHW_INTC1_TSC                  (1<<INTCHW_INTC1_TSC_BITNUM)
+#define INTCHW_INTC1_UART0                (1<<INTCHW_INTC1_UART0_BITNUM)
+#define INTCHW_INTC1_WDOG                 (1<<INTCHW_INTC1_WDOG_BITNUM)
+#define INTCHW_INTC1_UART1                (1<<INTCHW_INTC1_UART1_BITNUM)
+#define INTCHW_INTC1_PMUIRQ               (1<<INTCHW_INTC1_PMUIRQ_BITNUM)
+#define INTCHW_INTC1_COMMRX               (1<<INTCHW_INTC1_COMMRX_BITNUM)
+#define INTCHW_INTC1_COMMTX               (1<<INTCHW_INTC1_COMMTX_BITNUM)
+#define INTCHW_INTC1_FLASHC               (1<<INTCHW_INTC1_FLASHC_BITNUM)
+#define INTCHW_INTC1_GPHY                 (1<<INTCHW_INTC1_GPHY_BITNUM)
+#define INTCHW_INTC1_SPIS                 (1<<INTCHW_INTC1_SPIS_BITNUM)
+#define INTCHW_INTC1_I2CS                 (1<<INTCHW_INTC1_I2CS_BITNUM)
+#define INTCHW_INTC1_I2CH                 (1<<INTCHW_INTC1_I2CH_BITNUM)
+#define INTCHW_INTC1_I2S1                 (1<<INTCHW_INTC1_I2S1_BITNUM)
+#define INTCHW_INTC1_I2S0                 (1<<INTCHW_INTC1_I2S0_BITNUM)
+#define INTCHW_INTC1_GPIO1                (1<<INTCHW_INTC1_GPIO1_BITNUM)
+#define INTCHW_INTC1_GPIO0                (1<<INTCHW_INTC1_GPIO0_BITNUM)
+
+/* SINTC secure int controller */
+#define INTCHW_SINTC_RTC2_BITNUM          15	/* Real time clock tamper interrupt */
+#define INTCHW_SINTC_TIMER3_BITNUM        14	/* Secure timer3 interrupt */
+#define INTCHW_SINTC_TIMER2_BITNUM        13	/* Secure timer2 interrupt */
+#define INTCHW_SINTC_TIMER1_BITNUM        12	/* Secure timer1 interrupt */
+#define INTCHW_SINTC_TIMER0_BITNUM        11	/* Secure timer0 interrupt */
+#define INTCHW_SINTC_SPUM_BITNUM          10	/* Secure process module interrupt */
+#define INTCHW_SINTC_RTC1_BITNUM           9	/* Real time clock one-shot interrupt */
+#define INTCHW_SINTC_RTC0_BITNUM           8	/* Real time clock periodic interrupt */
+#define INTCHW_SINTC_RNG_BITNUM            7	/* Random number generator interrupt */
+#define INTCHW_SINTC_FMPU_BITNUM           6	/* Flash memory parition unit interrupt */
+#define INTCHW_SINTC_VMPU_BITNUM           5	/* VRAM memory partition interrupt */
+#define INTCHW_SINTC_DMPU_BITNUM           4	/* DDR2 memory partition interrupt */
+#define INTCHW_SINTC_KEYC_BITNUM           3	/* Key pad controller interrupt */
+#define INTCHW_SINTC_TSC_BITNUM            2	/* Touch screen controller interrupt */
+#define INTCHW_SINTC_UART0_BITNUM          1	/* UART0 interrupt */
+#define INTCHW_SINTC_WDOG_BITNUM           0	/* Watchdog timer interrupt */
+
+#define INTCHW_SINTC_TIMER3               (1<<INTCHW_SINTC_TIMER3_BITNUM)
+#define INTCHW_SINTC_TIMER2               (1<<INTCHW_SINTC_TIMER2_BITNUM)
+#define INTCHW_SINTC_TIMER1               (1<<INTCHW_SINTC_TIMER1_BITNUM)
+#define INTCHW_SINTC_TIMER0               (1<<INTCHW_SINTC_TIMER0_BITNUM)
+#define INTCHW_SINTC_SPUM                 (1<<INTCHW_SINTC_SPUM_BITNUM)
+#define INTCHW_SINTC_RTC2                 (1<<INTCHW_SINTC_RTC2_BITNUM)
+#define INTCHW_SINTC_RTC1                 (1<<INTCHW_SINTC_RTC1_BITNUM)
+#define INTCHW_SINTC_RTC0                 (1<<INTCHW_SINTC_RTC0_BITNUM)
+#define INTCHW_SINTC_RNG                  (1<<INTCHW_SINTC_RNG_BITNUM)
+#define INTCHW_SINTC_FMPU                 (1<<INTCHW_SINTC_FMPU_BITNUM)
+#define INTCHW_SINTC_IMPU                 (1<<INTCHW_SINTC_IMPU_BITNUM)
+#define INTCHW_SINTC_DMPU                 (1<<INTCHW_SINTC_DMPU_BITNUM)
+#define INTCHW_SINTC_KEYC                 (1<<INTCHW_SINTC_KEYC_BITNUM)
+#define INTCHW_SINTC_TSC                  (1<<INTCHW_SINTC_TSC_BITNUM)
+#define INTCHW_SINTC_UART0                (1<<INTCHW_SINTC_UART0_BITNUM)
+#define INTCHW_SINTC_WDOG                 (1<<INTCHW_SINTC_WDOG_BITNUM)
+
+/* PL192 Vectored Interrupt Controller (VIC) layout */
+#define INTCHW_IRQSTATUS      0x00	/* IRQ status register */
+#define INTCHW_FIQSTATUS      0x04	/* FIQ status register */
+#define INTCHW_RAWINTR        0x08	/* Raw Interrupt Status register */
+#define INTCHW_INTSELECT      0x0c	/* Interrupt Select Register */
+#define INTCHW_INTENABLE      0x10	/* Interrupt Enable Register */
+#define INTCHW_INTENCLEAR     0x14	/* Interrupt Enable Clear Register */
+#define INTCHW_SOFTINT        0x18	/* Soft Interrupt Register */
+#define INTCHW_SOFTINTCLEAR   0x1c	/* Soft Interrupt Clear Register */
+#define INTCHW_PROTECTION     0x20	/* Protection Enable Register */
+#define INTCHW_SWPRIOMASK     0x24	/* Software Priority Mask Register */
+#define INTCHW_PRIODAISY      0x28	/* Priority Daisy Chain Register */
+#define INTCHW_VECTADDR0      0x100	/* Vector Address Registers */
+#define INTCHW_VECTPRIO0      0x200	/* Vector Priority Registers 0-31 */
+#define INTCHW_ADDRESS        0xf00	/* Vector Address Register 0-31 */
+#define INTCHW_PID            0xfe0	/* Peripheral ID Register 0-3 */
+#define INTCHW_PCELLID        0xff0	/* PrimeCell ID Register 0-3 */
+
+/* Example Usage: intcHw_irq_enable(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */
+/*                intcHw_irq_clear(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */
+/*                uint32_t bits = intcHw_irq_status(INTCHW_INTC0); */
+/*                uint32_t bits = intcHw_irq_raw_status(INTCHW_INTC0); */
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+/* Clear one or more IRQ interrupts. */
+static inline void intcHw_irq_disable(void *basep, uint32_t mask)
+{
+	__REG32(basep + INTCHW_INTENCLEAR) = mask;
+}
+
+/* Enables one or more IRQ interrupts. */
+static inline void intcHw_irq_enable(void *basep, uint32_t mask)
+{
+	__REG32(basep + INTCHW_INTENABLE) = mask;
+}
+
+#endif /* _INTCHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
new file mode 100644
index 0000000..86bb58d
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
@@ -0,0 +1,101 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    mm_addr.h
+*
+*  @brief   Memory Map address defintions
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+
+#ifndef _MM_ADDR_H
+#define _MM_ADDR_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#if !defined(CSP_SIMULATION)
+#include <cfg_global.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+/*  Memory Map address definitions */
+
+#define MM_ADDR_DDR                0x00000000
+
+#define MM_ADDR_IO_VPM_EXTMEM_RSVD 0x0F000000	/* 16 MB - Reserved external memory for VPM use */
+
+#define MM_ADDR_IO_FLASHC          0x20000000
+#define MM_ADDR_IO_BROM            0x30000000
+#define MM_ADDR_IO_ARAM            0x30100000	/* 64 KB - extra cycle latency - WS switch */
+#define MM_ADDR_IO_DMA0            0x30200000
+#define MM_ADDR_IO_DMA1            0x30300000
+#define MM_ADDR_IO_ESW             0x30400000
+#define MM_ADDR_IO_CLCD            0x30500000
+#define MM_ADDR_IO_PIF             0x30580000
+#define MM_ADDR_IO_APM             0x30600000
+#define MM_ADDR_IO_SPUM            0x30700000
+#define MM_ADDR_IO_VPM_PROG        0x30800000
+#define MM_ADDR_IO_VPM_DATA        0x30A00000
+#define MM_ADDR_IO_VRAM            0x40000000	/* 64 KB  - security block in front of it */
+#define MM_ADDR_IO_CHIPC           0x80000000
+#define MM_ADDR_IO_UMI             0x80001000
+#define MM_ADDR_IO_NAND            0x80001800
+#define MM_ADDR_IO_LEDM            0x80002000
+#define MM_ADDR_IO_PWM             0x80002040
+#define MM_ADDR_IO_VINTC           0x80003000
+#define MM_ADDR_IO_GPIO0           0x80004000
+#define MM_ADDR_IO_GPIO1           0x80004800
+#define MM_ADDR_IO_I2CS            0x80005000
+#define MM_ADDR_IO_SPIS            0x80006000
+#define MM_ADDR_IO_HPM             0x80007400
+#define MM_ADDR_IO_HPM_REMAP       0x80007800
+#define MM_ADDR_IO_TZPC            0x80008000
+#define MM_ADDR_IO_MPU             0x80009000
+#define MM_ADDR_IO_SPUMP           0x8000a000
+#define MM_ADDR_IO_PKA             0x8000b000
+#define MM_ADDR_IO_RNG             0x8000c000
+#define MM_ADDR_IO_KEYC            0x8000d000
+#define MM_ADDR_IO_BBL             0x8000e000
+#define MM_ADDR_IO_OTP             0x8000f000
+#define MM_ADDR_IO_I2S0            0x80010000
+#define MM_ADDR_IO_I2S1            0x80011000
+#define MM_ADDR_IO_UARTA           0x80012000
+#define MM_ADDR_IO_UARTB           0x80013000
+#define MM_ADDR_IO_I2CH            0x80014020
+#define MM_ADDR_IO_SPIH            0x80015000
+#define MM_ADDR_IO_TSC             0x80016000
+#define MM_ADDR_IO_TMR             0x80017000
+#define MM_ADDR_IO_WATCHDOG        0x80017800
+#define MM_ADDR_IO_ETM             0x80018000
+#define MM_ADDR_IO_DDRC            0x80019000
+#define MM_ADDR_IO_SINTC           0x80100000
+#define MM_ADDR_IO_INTC0           0x80200000
+#define MM_ADDR_IO_INTC1           0x80201000
+#define MM_ADDR_IO_GE              0x80300000
+#define MM_ADDR_IO_USB_CTLR0       0x80400000
+#define MM_ADDR_IO_USB_CTLR1       0x80410000
+#define MM_ADDR_IO_USB_PHY         0x80420000
+#define MM_ADDR_IO_SDIOH0          0x80500000
+#define MM_ADDR_IO_SDIOH1          0x80600000
+#define MM_ADDR_IO_VDEC            0x80700000
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* _MM_ADDR_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_io.h b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h
new file mode 100644
index 0000000..de92ec6
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h
@@ -0,0 +1,147 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    mm_io.h
+*
+*  @brief   Memory Map I/O definitions
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+
+#ifndef _MM_IO_H
+#define _MM_IO_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/csp/mm_addr.h>
+
+#if !defined(CSP_SIMULATION)
+#include <cfg_global.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#if defined(CONFIG_MMU)
+
+/* This macro is referenced in <mach/io.h>
+ * Phys to Virtual 0xNyxxxxxx => 0xFNxxxxxx
+ * This macro is referenced in <asm/arch/io.h>
+ *
+ * Assume VPM address is the last x MB of memory.  For VPM, map to
+ * 0xf0000000 and up.
+ */
+
+#ifndef MM_IO_PHYS_TO_VIRT
+#ifdef __ASSEMBLY__
+#define MM_IO_PHYS_TO_VIRT(phys)       (0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF))
+#else
+#define MM_IO_PHYS_TO_VIRT(phys)       (((phys) == MM_ADDR_IO_VPM_EXTMEM_RSVD) ? 0xF0000000 : \
+			(0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF)))
+#endif
+#endif
+
+/* Virtual to Physical 0xFNxxxxxx => 0xN0xxxxxx */
+
+#ifndef MM_IO_VIRT_TO_PHYS
+#ifdef __ASSEMBLY__
+#define MM_IO_VIRT_TO_PHYS(virt)       ((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF))
+#else
+#define MM_IO_VIRT_TO_PHYS(virt)       (((virt) == 0xF0000000) ? MM_ADDR_IO_VPM_EXTMEM_RSVD : \
+			((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF)))
+#endif
+#endif
+
+#else
+
+#ifndef MM_IO_PHYS_TO_VIRT
+#define MM_IO_PHYS_TO_VIRT(phys)       (phys)
+#endif
+
+#ifndef MM_IO_VIRT_TO_PHYS
+#define MM_IO_VIRT_TO_PHYS(virt)       (virt)
+#endif
+
+#endif
+
+/* Registers in 0xExxxxxxx that should be moved to 0xFxxxxxxx */
+#define MM_IO_BASE_FLASHC              MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_FLASHC)
+#define MM_IO_BASE_NAND                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_NAND)
+#define MM_IO_BASE_UMI                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UMI)
+
+#define MM_IO_START MM_ADDR_IO_FLASHC	/* Physical beginning of IO mapped memory */
+#define MM_IO_BASE  MM_IO_BASE_FLASHC	/* Virtual beginning of IO mapped memory */
+
+#define MM_IO_BASE_BROM                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BROM)
+#define MM_IO_BASE_ARAM                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ARAM)
+#define MM_IO_BASE_DMA0                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA0)
+#define MM_IO_BASE_DMA1                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA1)
+#define MM_IO_BASE_ESW                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ESW)
+#define MM_IO_BASE_CLCD                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CLCD)
+#define MM_IO_BASE_PIF                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PIF)
+#define MM_IO_BASE_APM                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_APM)
+#define MM_IO_BASE_SPUM                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUM)
+#define MM_IO_BASE_VPM_PROG            MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_PROG)
+#define MM_IO_BASE_VPM_DATA            MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_DATA)
+
+#define MM_IO_BASE_VRAM                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VRAM)
+
+#define MM_IO_BASE_CHIPC               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CHIPC)
+#define MM_IO_BASE_DDRC                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DDRC)
+#define MM_IO_BASE_LEDM                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_LEDM)
+#define MM_IO_BASE_PWM                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PWM)
+#define MM_IO_BASE_VINTC               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VINTC)
+#define MM_IO_BASE_GPIO0               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO0)
+#define MM_IO_BASE_GPIO1               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO1)
+#define MM_IO_BASE_TMR                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TMR)
+#define MM_IO_BASE_WATCHDOG            MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_WATCHDOG)
+#define MM_IO_BASE_ETM                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ETM)
+#define MM_IO_BASE_HPM                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM)
+#define MM_IO_BASE_HPM_REMAP           MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM_REMAP)
+#define MM_IO_BASE_TZPC                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TZPC)
+#define MM_IO_BASE_MPU                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_MPU)
+#define MM_IO_BASE_SPUMP               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUMP)
+#define MM_IO_BASE_PKA                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PKA)
+#define MM_IO_BASE_RNG                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_RNG)
+#define MM_IO_BASE_KEYC                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_KEYC)
+#define MM_IO_BASE_BBL                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BBL)
+#define MM_IO_BASE_OTP                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_OTP)
+#define MM_IO_BASE_I2S0                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S0)
+#define MM_IO_BASE_I2S1                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S1)
+#define MM_IO_BASE_UARTA               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTA)
+#define MM_IO_BASE_UARTB               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTB)
+#define MM_IO_BASE_I2CH                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CH)
+#define MM_IO_BASE_SPIH                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIH)
+#define MM_IO_BASE_TSC                 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TSC)
+#define MM_IO_BASE_I2CS                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CS)
+#define MM_IO_BASE_SPIS                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIS)
+#define MM_IO_BASE_SINTC               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SINTC)
+#define MM_IO_BASE_INTC0               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC0)
+#define MM_IO_BASE_INTC1               MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC1)
+#define MM_IO_BASE_GE                  MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GE)
+#define MM_IO_BASE_USB_CTLR0           MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR0)
+#define MM_IO_BASE_USB_CTLR1           MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR1)
+#define MM_IO_BASE_USB_PHY             MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_PHY)
+#define MM_IO_BASE_SDIOH0              MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH0)
+#define MM_IO_BASE_SDIOH1              MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH1)
+#define MM_IO_BASE_VDEC                MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VDEC)
+
+#define MM_IO_BASE_VPM_EXTMEM_RSVD     MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_EXTMEM_RSVD)
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* _MM_IO_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h
new file mode 100644
index 0000000..d15f5f3
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h
@@ -0,0 +1,100 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    secHw_def.h
+*
+*  @brief   Definitions for configuring/testing secure blocks
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+
+#ifndef SECHW_DEF_H
+#define SECHW_DEF_H
+
+#include <mach/csp/mm_io.h>
+
+/* Bit mask for various secure device */
+#define secHw_BLK_MASK_CHIP_CONTROL     0x00000001
+#define secHw_BLK_MASK_KEY_SCAN         0x00000002
+#define secHw_BLK_MASK_TOUCH_SCREEN     0x00000004
+#define secHw_BLK_MASK_UART0            0x00000008
+#define secHw_BLK_MASK_UART1            0x00000010
+#define secHw_BLK_MASK_WATCHDOG         0x00000020
+#define secHw_BLK_MASK_SPUM             0x00000040
+#define secHw_BLK_MASK_DDR2             0x00000080
+#define secHw_BLK_MASK_EXT_MEM          0x00000100
+#define secHw_BLK_MASK_ESW              0x00000200
+#define secHw_BLK_MASK_SPU              0x00010000
+#define secHw_BLK_MASK_PKA              0x00020000
+#define secHw_BLK_MASK_RNG              0x00040000
+#define secHw_BLK_MASK_RTC              0x00080000
+#define secHw_BLK_MASK_OTP              0x00100000
+#define secHw_BLK_MASK_BOOT             0x00200000
+#define secHw_BLK_MASK_MPU              0x00400000
+#define secHw_BLK_MASK_TZCTRL           0x00800000
+#define secHw_BLK_MASK_INTR             0x01000000
+
+/* Trustzone register set */
+typedef struct {
+	volatile uint32_t status;	/* read only - reflects status of writes of 2 write registers */
+	volatile uint32_t setUnsecure;	/* write only. reads back as 0 */
+	volatile uint32_t setSecure;	/* write only. reads back as 0 */
+} secHw_TZREG_t;
+
+/* There are 2 register sets. The first is for the lower 16 bits, the 2nd */
+/* is for the higher 16 bits. */
+
+typedef enum {
+	secHw_IDX_LS = 0,
+	secHw_IDX_MS = 1,
+	secHw_IDX_NUM
+} secHw_IDX_e;
+
+typedef struct {
+	volatile secHw_TZREG_t reg[secHw_IDX_NUM];
+} secHw_REGS_t;
+
+/****************************************************************************/
+/**
+*  @brief  Configures a device as a secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setSecure(uint32_t mask	/*  mask of type secHw_BLK_MASK_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief  Configures a device as a non-secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setUnsecure(uint32_t mask	/*  mask of type secHw_BLK_MASK_XXXXXX */
+    );
+
+/****************************************************************************/
+/**
+*  @brief  Get the trustzone status for all components. 1 = non-secure, 0 = secure
+*
+*/
+/****************************************************************************/
+static inline uint32_t secHw_getStatus(void);
+
+#include <mach/csp/secHw_inline.h>
+
+#endif /* SECHW_DEF_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h
new file mode 100644
index 0000000..9cd6a03
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    secHw_inline.h
+*
+*  @brief   Definitions for configuring/testing secure blocks
+*
+*  @note
+*     None
+*/
+/****************************************************************************/
+
+#ifndef SECHW_INLINE_H
+#define SECHW_INLINE_H
+
+/****************************************************************************/
+/**
+*  @brief  Configures a device as a secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setSecure(uint32_t mask	/*  mask of type secHw_BLK_MASK_XXXXXX */
+    ) {
+	secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
+
+	if (mask & 0x0000FFFF) {
+		regp->reg[secHw_IDX_LS].setSecure = mask & 0x0000FFFF;
+	}
+
+	if (mask & 0xFFFF0000) {
+		regp->reg[secHw_IDX_MS].setSecure = mask >> 16;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief  Configures a device as a non-secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setUnsecure(uint32_t mask	/*  mask of type secHw_BLK_MASK_XXXXXX */
+    ) {
+	secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
+
+	if (mask & 0x0000FFFF) {
+		regp->reg[secHw_IDX_LS].setUnsecure = mask & 0x0000FFFF;
+	}
+	if (mask & 0xFFFF0000) {
+		regp->reg[secHw_IDX_MS].setUnsecure = mask >> 16;
+	}
+}
+
+/****************************************************************************/
+/**
+*  @brief  Get the trustzone status for all components. 1 = non-secure, 0 = secure
+*
+*/
+/****************************************************************************/
+static inline uint32_t secHw_getStatus(void)
+{
+	secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
+
+	return (regp->reg[1].status << 16) + regp->reg[0].status;
+}
+
+#endif /* SECHW_INLINE_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h
new file mode 100644
index 0000000..3080ac7
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h
@@ -0,0 +1,82 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*  @file    tmrHw_reg.h
+*
+*  @brief   Definitions for low level Timer registers
+*
+*/
+/****************************************************************************/
+#ifndef _TMRHW_REG_H
+#define _TMRHW_REG_H
+
+#include <mach/csp/mm_io.h>
+#include <mach/csp/hw_cfg.h>
+/* Base address */
+#define tmrHw_MODULE_BASE_ADDR          MM_IO_BASE_TMR
+
+/*
+This platform has four different timers running at different clock speed
+
+Timer one   (Timer ID 0) runs at  25 MHz
+Timer two   (Timer ID 1) runs at  25 MHz
+Timer three (Timer ID 2) runs at 150 MHz
+Timer four  (Timer ID 3) runs at 150 MHz
+*/
+#define tmrHw_LOW_FREQUENCY_MHZ         25	/* Always 25MHz from XTAL */
+#define tmrHw_LOW_FREQUENCY_HZ          25000000
+
+#if defined(CFG_GLOBAL_CHIP) && (CFG_GLOBAL_CHIP == FPGA11107)
+#define tmrHw_HIGH_FREQUENCY_MHZ        150	/* Always 150MHz for FPGA */
+#define tmrHw_HIGH_FREQUENCY_HZ         150000000
+#else
+#define tmrHw_HIGH_FREQUENCY_HZ         HW_CFG_BUS_CLK_HZ
+#define tmrHw_HIGH_FREQUENCY_MHZ        (HW_CFG_BUS_CLK_HZ / 1000000)
+#endif
+
+#define tmrHw_LOW_RESOLUTION_CLOCK      tmrHw_LOW_FREQUENCY_HZ
+#define tmrHw_HIGH_RESOLUTION_CLOCK     tmrHw_HIGH_FREQUENCY_HZ
+#define tmrHw_MAX_COUNT                 (0xFFFFFFFF)	/* maximum number of count a timer can count */
+#define tmrHw_TIMER_NUM_COUNT           (4)	/* Number of timer module supported */
+
+typedef struct {
+	uint32_t LoadValue;	/* Load value for timer */
+	uint32_t CurrentValue;	/* Current value for timer */
+	uint32_t Control;	/* Control register */
+	uint32_t InterruptClear;	/* Interrupt clear register */
+	uint32_t RawInterruptStatus;	/* Raw interrupt status */
+	uint32_t InterruptStatus;	/* Masked interrupt status */
+	uint32_t BackgroundLoad;	/* Background load value */
+	uint32_t padding;	/* Padding register */
+} tmrHw_REG_t;
+
+/* Control bot masks */
+#define tmrHw_CONTROL_TIMER_ENABLE            0x00000080
+#define tmrHw_CONTROL_PERIODIC                0x00000040
+#define tmrHw_CONTROL_INTERRUPT_ENABLE        0x00000020
+#define tmrHw_CONTROL_PRESCALE_MASK           0x0000000C
+#define tmrHw_CONTROL_PRESCALE_1              0x00000000
+#define tmrHw_CONTROL_PRESCALE_16             0x00000004
+#define tmrHw_CONTROL_PRESCALE_256            0x00000008
+#define tmrHw_CONTROL_32BIT                   0x00000002
+#define tmrHw_CONTROL_ONESHOT                 0x00000001
+#define tmrHw_CONTROL_FREE_RUNNING            0x00000000
+
+#define tmrHw_CONTROL_MODE_MASK               (tmrHw_CONTROL_PERIODIC | tmrHw_CONTROL_ONESHOT)
+
+#define pTmrHw ((volatile tmrHw_REG_t *)tmrHw_MODULE_BASE_ADDR)
+
+#endif /* _TMRHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h
new file mode 100644
index 0000000..847980c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/dma.h
@@ -0,0 +1,826 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*   @file   dma.h
+*
+*   @brief  API definitions for the linux DMA interface.
+*/
+/****************************************************************************/
+
+#if !defined(ASM_ARM_ARCH_BCMRING_DMA_H)
+#define ASM_ARM_ARCH_BCMRING_DMA_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/semaphore.h>
+#include <csp/dmacHw.h>
+#include <mach/timer.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+/* If DMA_DEBUG_TRACK_RESERVATION is set to a non-zero value, then the filename */
+/* and line number of the reservation request will be recorded in the channel table */
+
+#define DMA_DEBUG_TRACK_RESERVATION   1
+
+#define DMA_NUM_CONTROLLERS     2
+#define DMA_NUM_CHANNELS        8	/* per controller */
+
+typedef enum {
+	DMA_DEVICE_MEM_TO_MEM,	/* For memory to memory transfers */
+	DMA_DEVICE_I2S0_DEV_TO_MEM,
+	DMA_DEVICE_I2S0_MEM_TO_DEV,
+	DMA_DEVICE_I2S1_DEV_TO_MEM,
+	DMA_DEVICE_I2S1_MEM_TO_DEV,
+	DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM,
+	DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV,
+	DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM,
+	DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV,
+	DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM,	/* Additional mic input for beam-forming */
+	DMA_DEVICE_APM_PCM0_DEV_TO_MEM,
+	DMA_DEVICE_APM_PCM0_MEM_TO_DEV,
+	DMA_DEVICE_APM_PCM1_DEV_TO_MEM,
+	DMA_DEVICE_APM_PCM1_MEM_TO_DEV,
+	DMA_DEVICE_SPUM_DEV_TO_MEM,
+	DMA_DEVICE_SPUM_MEM_TO_DEV,
+	DMA_DEVICE_SPIH_DEV_TO_MEM,
+	DMA_DEVICE_SPIH_MEM_TO_DEV,
+	DMA_DEVICE_UART_A_DEV_TO_MEM,
+	DMA_DEVICE_UART_A_MEM_TO_DEV,
+	DMA_DEVICE_UART_B_DEV_TO_MEM,
+	DMA_DEVICE_UART_B_MEM_TO_DEV,
+	DMA_DEVICE_PIF_MEM_TO_DEV,
+	DMA_DEVICE_PIF_DEV_TO_MEM,
+	DMA_DEVICE_ESW_DEV_TO_MEM,
+	DMA_DEVICE_ESW_MEM_TO_DEV,
+	DMA_DEVICE_VPM_MEM_TO_MEM,
+	DMA_DEVICE_CLCD_MEM_TO_MEM,
+	DMA_DEVICE_NAND_MEM_TO_MEM,
+	DMA_DEVICE_MEM_TO_VRAM,
+	DMA_DEVICE_VRAM_TO_MEM,
+
+	/* Add new entries before this line. */
+
+	DMA_NUM_DEVICE_ENTRIES,
+	DMA_DEVICE_NONE = 0xff,	/* Special value to indicate that no device is currently assigned. */
+
+} DMA_Device_t;
+
+/****************************************************************************
+*
+*   The DMA_Handle_t is the primary object used by callers of the API.
+*
+*****************************************************************************/
+
+#define DMA_INVALID_HANDLE  ((DMA_Handle_t) -1)
+
+typedef int DMA_Handle_t;
+
+/****************************************************************************
+*
+*   The DMA_DescriptorRing_t contains a ring of descriptors which is used
+*   to point to regions of memory.
+*
+*****************************************************************************/
+
+typedef struct {
+	void *virtAddr;		/* Virtual Address of the descriptor ring */
+	dma_addr_t physAddr;	/* Physical address of the descriptor ring */
+	int descriptorsAllocated;	/* Number of descriptors allocated in the descriptor ring */
+	size_t bytesAllocated;	/* Number of bytes allocated in the descriptor ring */
+
+} DMA_DescriptorRing_t;
+
+/****************************************************************************
+*
+*   The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup
+*   DMA chains from a variety of memory sources.
+*
+*****************************************************************************/
+
+#define DMA_MEM_MAP_MIN_SIZE    4096	/* Pages less than this size are better */
+					/* off not being DMA'd. */
+
+typedef enum {
+	DMA_MEM_TYPE_NONE,	/* Not a valid setting */
+	DMA_MEM_TYPE_VMALLOC,	/* Memory came from vmalloc call */
+	DMA_MEM_TYPE_KMALLOC,	/* Memory came from kmalloc call */
+	DMA_MEM_TYPE_DMA,	/* Memory came from dma_alloc_xxx call */
+	DMA_MEM_TYPE_USER,	/* Memory came from user space. */
+
+} DMA_MemType_t;
+
+/* A segment represents a physically and virtually contiguous chunk of memory. */
+/* i.e. each segment can be DMA'd */
+/* A user of the DMA code will add memory regions. Each region may need to be */
+/* represented by one or more segments. */
+
+typedef struct {
+	void *virtAddr;		/* Virtual address used for this segment */
+	dma_addr_t physAddr;	/* Physical address this segment maps to */
+	size_t numBytes;	/* Size of the segment, in bytes */
+
+} DMA_Segment_t;
+
+/* A region represents a virtually contiguous chunk of memory, which may be */
+/* made up of multiple segments. */
+
+typedef struct {
+	DMA_MemType_t memType;
+	void *virtAddr;
+	size_t numBytes;
+
+	/* Each region (virtually contiguous) consists of one or more segments. Each */
+	/* segment is virtually and physically contiguous. */
+
+	int numSegmentsUsed;
+	int numSegmentsAllocated;
+	DMA_Segment_t *segment;
+
+	/* When a region corresponds to user memory, we need to lock all of the pages */
+	/* down before we can figure out the physical addresses. The lockedPage array contains */
+	/* the pages that were locked, and which subsequently need to be unlocked once the */
+	/* memory is unmapped. */
+
+	unsigned numLockedPages;
+	struct page **lockedPages;
+
+} DMA_Region_t;
+
+typedef struct {
+	int inUse;		/* Is this mapping currently being used? */
+	struct semaphore lock;	/* Acquired when using this structure */
+	enum dma_data_direction dir;	/* Direction this transfer is intended for */
+
+	/* In the event that we're mapping user memory, we need to know which task */
+	/* the memory is for, so that we can obtain the correct mm locks. */
+
+	struct task_struct *userTask;
+
+	int numRegionsUsed;
+	int numRegionsAllocated;
+	DMA_Region_t *region;
+
+} DMA_MemMap_t;
+
+/****************************************************************************
+*
+*   The DMA_DeviceAttribute_t contains information which describes a
+*   particular DMA device (or peripheral).
+*
+*   It is anticipated that the arrary of DMA_DeviceAttribute_t's will be
+*   statically initialized.
+*
+*****************************************************************************/
+
+/* The device handler is called whenever a DMA operation completes. The reaon */
+/* for it to be called will be a bitmask with one or more of the following bits */
+/* set. */
+
+#define DMA_HANDLER_REASON_BLOCK_COMPLETE       dmacHw_INTERRUPT_STATUS_BLOCK
+#define DMA_HANDLER_REASON_TRANSFER_COMPLETE    dmacHw_INTERRUPT_STATUS_TRANS
+#define DMA_HANDLER_REASON_ERROR                dmacHw_INTERRUPT_STATUS_ERROR
+
+typedef void (*DMA_DeviceHandler_t) (DMA_Device_t dev, int reason,
+				     void *userData);
+
+#define DMA_DEVICE_FLAG_ON_DMA0             0x00000001
+#define DMA_DEVICE_FLAG_ON_DMA1             0x00000002
+#define DMA_DEVICE_FLAG_PORT_PER_DMAC       0x00000004	/* If set, it means that the port used on DMAC0 is different from the port used on DMAC1 */
+#define DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST    0x00000008	/* If set, allocate from DMA1 before allocating from DMA0 */
+#define DMA_DEVICE_FLAG_IS_DEDICATED        0x00000100
+#define DMA_DEVICE_FLAG_NO_ISR              0x00000200
+#define DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO    0x00000400
+#define DMA_DEVICE_FLAG_IN_USE              0x00000800	/* If set, device is in use on a channel */
+
+/* Note: Some DMA devices can be used from multiple DMA Controllers. The bitmask is used to */
+/*       determine which DMA controllers a given device can be used from, and the interface */
+/*       array determeines the actual interface number to use for a given controller. */
+
+typedef struct {
+	uint32_t flags;		/* Bitmask of DMA_DEVICE_FLAG_xxx constants */
+	uint8_t dedicatedController;	/* Controller number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */
+	uint8_t dedicatedChannel;	/* Channel number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */
+	const char *name;	/* Will show up in the /proc entry */
+
+	uint32_t dmacPort[DMA_NUM_CONTROLLERS];	/* Specifies the port number when DMA_DEVICE_FLAG_PORT_PER_DMAC flag is set */
+
+	dmacHw_CONFIG_t config;	/* Configuration to use when DMA'ing using this device */
+
+	void *userData;		/* Passed to the devHandler */
+	DMA_DeviceHandler_t devHandler;	/* Called when DMA operations finish. */
+
+	timer_tick_count_t transferStartTime;	/* Time the current transfer was started */
+
+	/* The following statistical information will be collected and presented in a proc entry. */
+	/* Note: With a contiuous bandwidth of 1 Gb/sec, it would take 584 years to overflow */
+	/*       a 64 bit counter. */
+
+	uint64_t numTransfers;	/* Number of DMA transfers performed */
+	uint64_t transferTicks;	/* Total time spent doing DMA transfers (measured in timer_tick_count_t's) */
+	uint64_t transferBytes;	/* Total bytes transferred */
+	uint32_t timesBlocked;	/* Number of times a channel was unavailable */
+	uint32_t numBytes;	/* Last transfer size */
+
+	/* It's not possible to free memory which is allocated for the descriptors from within */
+	/* the ISR. So make the presumption that a given device will tend to use the */
+	/* same sized buffers over and over again, and we keep them around. */
+
+	DMA_DescriptorRing_t ring;	/* Ring of descriptors allocated for this device */
+
+	/* We stash away some of the information from the previous transfer. If back-to-back */
+	/* transfers are performed from the same buffer, then we don't have to keep re-initializing */
+	/* the descriptor buffers. */
+
+	uint32_t prevNumBytes;
+	dma_addr_t prevSrcData;
+	dma_addr_t prevDstData;
+
+} DMA_DeviceAttribute_t;
+
+/****************************************************************************
+*
+*   DMA_Channel_t, DMA_Controller_t, and DMA_State_t are really internal
+*   data structures and don't belong in this header file, but are included
+*   merely for discussion.
+*
+*   By the time this is implemented, these structures will be moved out into
+*   the appropriate C source file instead.
+*
+*****************************************************************************/
+
+/****************************************************************************
+*
+*   The DMA_Channel_t contains state information about each DMA channel. Some
+*   of the channels are dedicated. Non-dedicated channels are shared
+*   amongst the other devices.
+*
+*****************************************************************************/
+
+#define DMA_CHANNEL_FLAG_IN_USE         0x00000001
+#define DMA_CHANNEL_FLAG_IS_DEDICATED   0x00000002
+#define DMA_CHANNEL_FLAG_NO_ISR         0x00000004
+#define DMA_CHANNEL_FLAG_LARGE_FIFO     0x00000008
+
+typedef struct {
+	uint32_t flags;		/* bitmask of DMA_CHANNEL_FLAG_xxx constants */
+	DMA_Device_t devType;	/* Device this channel is currently reserved for */
+	DMA_Device_t lastDevType;	/* Device type that used this previously */
+	char name[20];		/* Name passed onto request_irq */
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+	const char *fileName;	/* Place where channel reservation took place */
+	int lineNum;		/* Place where channel reservation took place */
+#endif
+	dmacHw_HANDLE_t dmacHwHandle;	/* low level channel handle. */
+
+} DMA_Channel_t;
+
+/****************************************************************************
+*
+*   The DMA_Controller_t contains state information about each DMA controller.
+*
+*   The freeChannelQ is stored in the controller data structure rather than
+*   the channel data structure since several of the devices are accessible
+*   from multiple controllers, and there is no way to know which controller
+*   will become available first.
+*
+*****************************************************************************/
+
+typedef struct {
+	DMA_Channel_t channel[DMA_NUM_CHANNELS];
+
+} DMA_Controller_t;
+
+/****************************************************************************
+*
+*   The DMA_Global_t contains all of the global state information used by
+*   the DMA code.
+*
+*   Callers which need to allocate a shared channel will be queued up
+*   on the freeChannelQ until a channel becomes available.
+*
+*****************************************************************************/
+
+typedef struct {
+	struct semaphore lock;	/* acquired when manipulating table entries */
+	wait_queue_head_t freeChannelQ;
+
+	DMA_Controller_t controller[DMA_NUM_CONTROLLERS];
+
+} DMA_Global_t;
+
+/* ---- Variable Externs ------------------------------------------------- */
+
+extern DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES];
+
+/* ---- Function Prototypes ---------------------------------------------- */
+
+#if defined(__KERNEL__)
+
+/****************************************************************************/
+/**
+*   Initializes the DMA module.
+*
+*   @return
+*       0       - Success
+*       < 0     - Error
+*/
+/****************************************************************************/
+
+int dma_init(void);
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+DMA_Handle_t dma_request_channel_dbg(DMA_Device_t dev, const char *fileName,
+				     int lineNum);
+#define dma_request_channel(dev)  dma_request_channel_dbg(dev, __FILE__, __LINE__)
+#else
+
+/****************************************************************************/
+/**
+*   Reserves a channel for use with @a dev. If the device is setup to use
+*   a shared channel, then this function will block until a free channel
+*   becomes available.
+*
+*   @return
+*       >= 0    - A valid DMA Handle.
+*       -EBUSY  - Device is currently being used.
+*       -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+DMA_Handle_t dma_request_channel(DMA_Device_t dev	/* Device to use with the allocated channel. */
+    );
+#endif
+
+/****************************************************************************/
+/**
+*   Frees a previously allocated DMA Handle.
+*
+*   @return
+*        0      - DMA Handle was released successfully.
+*       -EINVAL - Invalid DMA handle
+*/
+/****************************************************************************/
+
+int dma_free_channel(DMA_Handle_t channel	/* DMA handle. */
+    );
+
+/****************************************************************************/
+/**
+*   Determines if a given device has been configured as using a shared
+*   channel.
+*
+*   @return boolean
+*       0           Device uses a dedicated channel
+*       non-zero    Device uses a shared channel
+*/
+/****************************************************************************/
+
+int dma_device_is_channel_shared(DMA_Device_t dev	/* Device to check. */
+    );
+
+/****************************************************************************/
+/**
+*   Allocates memory to hold a descriptor ring. The descriptor ring then
+*   needs to be populated by making one or more calls to
+*   dna_add_descriptors.
+*
+*   The returned descriptor ring will be automatically initialized.
+*
+*   @return
+*       0           Descriptor ring was allocated successfully
+*       -ENOMEM     Unable to allocate memory for the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring,	/* Descriptor ring to populate */
+			      int numDescriptors	/* Number of descriptors that need to be allocated. */
+    );
+
+/****************************************************************************/
+/**
+*   Releases the memory which was previously allocated for a descriptor ring.
+*/
+/****************************************************************************/
+
+void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring	/* Descriptor to release */
+    );
+
+/****************************************************************************/
+/**
+*   Initializes a descriptor ring, so that descriptors can be added to it.
+*   Once a descriptor ring has been allocated, it may be reinitialized for
+*   use with additional/different regions of memory.
+*
+*   Note that if 7 descriptors are allocated, it's perfectly acceptable to
+*   initialize the ring with a smaller number of descriptors. The amount
+*   of memory allocated for the descriptor ring will not be reduced, and
+*   the descriptor ring may be reinitialized later
+*
+*   @return
+*       0           Descriptor ring was initialized successfully
+*       -ENOMEM     The descriptor which was passed in has insufficient space
+*                   to hold the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring,	/* Descriptor ring to initialize */
+			     int numDescriptors	/* Number of descriptors to initialize. */
+    );
+
+/****************************************************************************/
+/**
+*   Determines the number of descriptors which would be required for a
+*   transfer of the indicated memory region.
+*
+*   This function also needs to know which DMA device this transfer will
+*   be destined for, so that the appropriate DMA configuration can be retrieved.
+*   DMA parameters such as transfer width, and whether this is a memory-to-memory
+*   or memory-to-peripheral, etc can all affect the actual number of descriptors
+*   required.
+*
+*   @return
+*       > 0     Returns the number of descriptors required for the indicated transfer
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_calculate_descriptor_count(DMA_Device_t device,	/* DMA Device that this will be associated with */
+				   dma_addr_t srcData,	/* Place to get data to write to device */
+				   dma_addr_t dstData,	/* Pointer to device data address */
+				   size_t numBytes	/* Number of bytes to transfer to the device */
+    );
+
+/****************************************************************************/
+/**
+*   Adds a region of memory to the descriptor ring. Note that it may take
+*   multiple descriptors for each region of memory. It is the callers
+*   responsibility to allocate a sufficiently large descriptor ring.
+*
+*   @return
+*       0       Descriptors were added successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_add_descriptors(DMA_DescriptorRing_t *ring,	/* Descriptor ring to add descriptors to */
+			DMA_Device_t device,	/* DMA Device that descriptors are for */
+			dma_addr_t srcData,	/* Place to get data (memory or device) */
+			dma_addr_t dstData,	/* Place to put data (memory or device) */
+			size_t numBytes	/* Number of bytes to transfer to the device */
+    );
+
+/****************************************************************************/
+/**
+*   Sets the descriptor ring associated with a device.
+*
+*   Once set, the descriptor ring will be associated with the device, even
+*   across channel request/free calls. Passing in a NULL descriptor ring
+*   will release any descriptor ring currently associated with the device.
+*
+*   Note: If you call dma_transfer, or one of the other dma_alloc_ functions
+*         the descriptor ring may be released and reallocated.
+*
+*   Note: This function will release the descriptor memory for any current
+*         descriptor ring associated with this device.
+*/
+/****************************************************************************/
+
+int dma_set_device_descriptor_ring(DMA_Device_t device,	/* Device to update the descriptor ring for. */
+				   DMA_DescriptorRing_t *ring	/* Descriptor ring to add descriptors to */
+    );
+
+/****************************************************************************/
+/**
+*   Retrieves the descriptor ring associated with a device.
+*/
+/****************************************************************************/
+
+int dma_get_device_descriptor_ring(DMA_Device_t device,	/* Device to retrieve the descriptor ring for. */
+				   DMA_DescriptorRing_t *ring	/* Place to store retrieved ring */
+    );
+
+/****************************************************************************/
+/**
+*   Allocates buffers for the descriptors. This is normally done automatically
+*   but needs to be done explicitly when initiating a dma from interrupt
+*   context.
+*
+*   @return
+*       0       Descriptors were allocated successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptors(DMA_Handle_t handle,	/* DMA Handle */
+			  dmacHw_TRANSFER_TYPE_e transferType,	/* Type of transfer being performed */
+			  dma_addr_t srcData,	/* Place to get data to write to device */
+			  dma_addr_t dstData,	/* Pointer to device data address */
+			  size_t numBytes	/* Number of bytes to transfer to the device */
+    );
+
+/****************************************************************************/
+/**
+*   Allocates and sets up descriptors for a double buffered circular buffer.
+*
+*   This is primarily intended to be used for things like the ingress samples
+*   from a microphone.
+*
+*   @return
+*       > 0     Number of descriptors actually allocated.
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*       -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_double_dst_descriptors(DMA_Handle_t handle,	/* DMA Handle */
+				     dma_addr_t srcData,	/* Physical address of source data */
+				     dma_addr_t dstData1,	/* Physical address of first destination buffer */
+				     dma_addr_t dstData2,	/* Physical address of second destination buffer */
+				     size_t numBytes	/* Number of bytes in each destination buffer */
+    );
+
+/****************************************************************************/
+/**
+*   Initializes a DMA_MemMap_t data structure
+*/
+/****************************************************************************/
+
+int dma_init_mem_map(DMA_MemMap_t *memMap	/* Stores state information about the map */
+    );
+
+/****************************************************************************/
+/**
+*   Releases any memory currently being held by a memory mapping structure.
+*/
+/****************************************************************************/
+
+int dma_term_mem_map(DMA_MemMap_t *memMap	/* Stores state information about the map */
+    );
+
+/****************************************************************************/
+/**
+*   Looks at a memory address and categorizes it.
+*
+*   @return One of the values from the DMA_MemType_t enumeration.
+*/
+/****************************************************************************/
+
+DMA_MemType_t dma_mem_type(void *addr);
+
+/****************************************************************************/
+/**
+*   Sets the process (aka userTask) associated with a mem map. This is
+*   required if user-mode segments will be added to the mapping.
+*/
+/****************************************************************************/
+
+static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,
+					     struct task_struct *task)
+{
+	memMap->userTask = task;
+}
+
+/****************************************************************************/
+/**
+*   Looks at a memory address and determines if we support DMA'ing to/from
+*   that type of memory.
+*
+*   @return boolean -
+*               return value != 0 means dma supported
+*               return value == 0 means dma not supported
+*/
+/****************************************************************************/
+
+int dma_mem_supports_dma(void *addr);
+
+/****************************************************************************/
+/**
+*   Initializes a memory map for use. Since this function acquires a
+*   sempaphore within the memory map, it is VERY important that dma_unmap
+*   be called when you're finished using the map.
+*/
+/****************************************************************************/
+
+int dma_map_start(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+		  enum dma_data_direction dir	/* Direction that the mapping will be going */
+    );
+
+/****************************************************************************/
+/**
+*   Adds a segment of memory to a memory map.
+*
+*   @return     0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_add_region(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+		       void *mem,	/* Virtual address that we want to get a map of */
+		       size_t numBytes	/* Number of bytes being mapped */
+    );
+
+/****************************************************************************/
+/**
+*   Creates a descriptor ring from a memory mapping.
+*
+*   @return 0 on sucess, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_create_descriptor_ring(DMA_Device_t dev,	/* DMA device (where the ring is stored) */
+				   DMA_MemMap_t *memMap,	/* Memory map that will be used */
+				   dma_addr_t devPhysAddr	/* Physical address of device */
+    );
+
+/****************************************************************************/
+/**
+*   Maps in a memory region such that it can be used for performing a DMA.
+*
+*   @return
+*/
+/****************************************************************************/
+
+int dma_map_mem(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+		void *addr,	/* Virtual address that we want to get a map of */
+		size_t count,	/* Number of bytes being mapped */
+		enum dma_data_direction dir	/* Direction that the mapping will be going */
+    );
+
+/****************************************************************************/
+/**
+*   Maps in a memory region such that it can be used for performing a DMA.
+*
+*   @return
+*/
+/****************************************************************************/
+
+int dma_unmap(DMA_MemMap_t *memMap,	/* Stores state information about the map */
+	      int dirtied	/* non-zero if any of the pages were modified */
+    );
+
+/****************************************************************************/
+/**
+*   Initiates a transfer when the descriptors have already been setup.
+*
+*   This is a special case, and normally, the dma_transfer_xxx functions should
+*   be used.
+*
+*   @return
+*       0       Transfer was started successfully
+*       -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_start_transfer(DMA_Handle_t handle);
+
+/****************************************************************************/
+/**
+*   Stops a previously started DMA transfer.
+*
+*   @return
+*       0       Transfer was stopped successfully
+*       -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_stop_transfer(DMA_Handle_t handle);
+
+/****************************************************************************/
+/**
+*   Waits for a DMA to complete by polling. This function is only intended
+*   to be used for testing. Interrupts should be used for most DMA operations.
+*/
+/****************************************************************************/
+
+int dma_wait_transfer_done(DMA_Handle_t handle);
+
+/****************************************************************************/
+/**
+*   Initiates a DMA transfer
+*
+*   @return
+*       0       Transfer was started successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*/
+/****************************************************************************/
+
+int dma_transfer(DMA_Handle_t handle,	/* DMA Handle */
+		 dmacHw_TRANSFER_TYPE_e transferType,	/* Type of transfer being performed */
+		 dma_addr_t srcData,	/* Place to get data to write to device */
+		 dma_addr_t dstData,	/* Pointer to device data address */
+		 size_t numBytes	/* Number of bytes to transfer to the device */
+    );
+
+/****************************************************************************/
+/**
+*   Initiates a transfer from memory to a device.
+*
+*   @return
+*       0       Transfer was started successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
+*/
+/****************************************************************************/
+
+static inline int dma_transfer_to_device(DMA_Handle_t handle,	/* DMA Handle */
+					 dma_addr_t srcData,	/* Place to get data to write to device (physical address) */
+					 dma_addr_t dstData,	/* Pointer to device data address (physical address) */
+					 size_t numBytes	/* Number of bytes to transfer to the device */
+    ) {
+	return dma_transfer(handle,
+			    dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+			    srcData, dstData, numBytes);
+}
+
+/****************************************************************************/
+/**
+*   Initiates a transfer from a device to memory.
+*
+*   @return
+*       0       Transfer was started successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*/
+/****************************************************************************/
+
+static inline int dma_transfer_from_device(DMA_Handle_t handle,	/* DMA Handle */
+					   dma_addr_t srcData,	/* Pointer to the device data address (physical address) */
+					   dma_addr_t dstData,	/* Place to store data retrieved from the device (physical address) */
+					   size_t numBytes	/* Number of bytes to retrieve from the device */
+    ) {
+	return dma_transfer(handle,
+			    dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+			    srcData, dstData, numBytes);
+}
+
+/****************************************************************************/
+/**
+*   Initiates a memory to memory transfer.
+*
+*   @return
+*       0       Transfer was started successfully
+*       -EINVAL Invalid device type for this kind of transfer
+*               (i.e. the device wasn't DMA_DEVICE_MEM_TO_MEM)
+*/
+/****************************************************************************/
+
+static inline int dma_transfer_mem_to_mem(DMA_Handle_t handle,	/* DMA Handle */
+					  dma_addr_t srcData,	/* Place to transfer data from (physical address) */
+					  dma_addr_t dstData,	/* Place to transfer data to (physical address) */
+					  size_t numBytes	/* Number of bytes to transfer */
+    ) {
+	return dma_transfer(handle,
+			    dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+			    srcData, dstData, numBytes);
+}
+
+/****************************************************************************/
+/**
+*   Set the callback function which will be called when a transfer completes.
+*   If a NULL callback function is set, then no callback will occur.
+*
+*   @note   @a devHandler will be called from IRQ context.
+*
+*   @return
+*       0       - Success
+*       -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_set_device_handler(DMA_Device_t dev,	/* Device to set the callback for. */
+			   DMA_DeviceHandler_t devHandler,	/* Function to call when the DMA completes */
+			   void *userData	/* Pointer which will be passed to devHandler. */
+    );
+
+#endif
+
+#endif /* ASM_ARM_ARCH_BCMRING_DMA_H */
diff --git a/arch/arm/mach-bcmring/include/mach/entry-macro.S b/arch/arm/mach-bcmring/include/mach/entry-macro.S
new file mode 100644
index 0000000..7d393ca
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/entry-macro.S
@@ -0,0 +1,86 @@
+/*****************************************************************************
+* Copyright 2006 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+ *
+ * Low-level IRQ helper macros for BCMRing-based platforms
+ *
+ */
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/csp/mm_io.h>
+
+		.macro	disable_fiq
+		.endm
+
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\base, =(MM_IO_BASE_INTC0)
+		ldr	\irqstat, [\base, #0]		@ get status
+                ldr     \irqnr, [\base, #0x10]          @ mask with enable register
+                ands    \irqstat, \irqstat, \irqnr
+		mov	\irqnr, #IRQ_INTC0_START
+		cmp	\irqstat, #0
+		bne	1001f
+
+		ldr	\base, =(MM_IO_BASE_INTC1)
+		ldr	\irqstat, [\base, #0]		@ get status
+                ldr     \irqnr, [\base, #0x10]          @ mask with enable register
+                ands    \irqstat, \irqstat, \irqnr
+		mov	\irqnr, #IRQ_INTC1_START
+		cmp	\irqstat, #0
+		bne	1001f
+
+		ldr	\base, =(MM_IO_BASE_SINTC)
+		ldr	\irqstat, [\base, #0]		@ get status
+                ldr     \irqnr, [\base, #0x10]          @ mask with enable register
+                ands    \irqstat, \irqstat, \irqnr
+		mov	\irqnr, #0xffffffff             @ code meaning no interrupt bits set
+		cmp	\irqstat, #0
+		beq	1002f
+
+		mov	\irqnr, #IRQ_SINTC_START        @ something is set, so fixup return value
+
+1001:
+		movs	\tmp, \irqstat, lsl #16
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #16
+
+		movs	\tmp, \irqstat, lsl #8
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #8
+
+		movs	\tmp, \irqstat, lsl #4
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #4
+
+		movs	\tmp, \irqstat, lsl #2
+		movne	\irqstat, \tmp
+		addeq	\irqnr, \irqnr, #2
+
+		movs	\tmp, \irqstat, lsl #1
+		addeq	\irqnr, \irqnr, #1
+		orrs	\base, \base, #1
+
+1002:           @ irqnr will be set to 0xffffffff if no irq bits are set
+		.endm
+
+		.macro  get_irqnr_preamble, base, tmp
+		.endm
+
+		.macro  arch_ret_to_user, tmp1, tmp2
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h
new file mode 100644
index 0000000..447eb34
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/hardware.h
@@ -0,0 +1,60 @@
+/*
+ *
+ *  This file contains the hardware definitions of the BCMRing.
+ *
+ *  Copyright (C) 1999 ARM Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/memory.h>
+#include <cfg_global.h>
+#include <mach/csp/mm_io.h>
+
+/* Hardware addresses of major areas.
+ *  *_START is the physical address
+ *  *_SIZE  is the size of the region
+ *  *_BASE  is the virtual address
+ */
+#define RAM_START               PHYS_OFFSET
+
+#define RAM_SIZE                (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED)
+#define RAM_BASE                PAGE_OFFSET
+
+#define pcibios_assign_all_busses()	1
+
+/* Macros to make managing spinlocks a bit more controlled in terms of naming. */
+/* See reg_gpio.h, reg_irq.h, arch.c, gpio.c for example usage. */
+#if defined(__KERNEL__)
+#define HW_DECLARE_SPINLOCK(name)  DEFINE_SPINLOCK(bcmring_##name##_reg_lock);
+#define HW_EXTERN_SPINLOCK(name)   extern spinlock_t bcmring_##name##_reg_lock;
+#define HW_IRQ_SAVE(name, val)     spin_lock_irqsave(&bcmring_##name##_reg_lock, (val))
+#define HW_IRQ_RESTORE(name, val)  spin_unlock_irqrestore(&bcmring_##name##_reg_lock, (val))
+#else
+#define HW_DECLARE_SPINLOCK(name)
+#define HW_EXTERN_SPINLOCK(name)
+#define HW_IRQ_SAVE(name, val)     {(void)(name); (void)(val); }
+#define HW_IRQ_RESTORE(name, val)  {(void)(name); (void)(val); }
+#endif
+
+#ifndef HW_IO_PHYS_TO_VIRT
+#define HW_IO_PHYS_TO_VIRT MM_IO_PHYS_TO_VIRT
+#endif
+#define HW_IO_VIRT_TO_PHYS MM_IO_VIRT_TO_PHYS
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/io.h b/arch/arm/mach-bcmring/include/mach/io.h
new file mode 100644
index 0000000..4db0eff
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/io.h
@@ -0,0 +1,56 @@
+/*
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a)         ((void __iomem *)HW_IO_PHYS_TO_VIRT(a))
+
+/* Do not enable mem_pci for a big endian arm architecture or unexpected byteswaps will */
+/* happen in readw/writew etc. */
+
+#define readb(c)        __raw_readb(c)
+#define readw(c)        __raw_readw(c)
+#define readl(c)        __raw_readl(c)
+#define readb_relaxed(addr) readb(addr)
+#define readw_relaxed(addr) readw(addr)
+#define readl_relaxed(addr) readl(addr)
+
+#define readsb(p, d, l)   __raw_readsb(p, d, l)
+#define readsw(p, d, l)   __raw_readsw(p, d, l)
+#define readsl(p, d, l)   __raw_readsl(p, d, l)
+
+#define writeb(v, c)     __raw_writeb(v, c)
+#define writew(v, c)     __raw_writew(v, c)
+#define writel(v, c)     __raw_writel(v, c)
+
+#define writesb(p, d, l)  __raw_writesb(p, d, l)
+#define writesw(p, d, l)  __raw_writesw(p, d, l)
+#define writesl(p, d, l)  __raw_writesl(p, d, l)
+
+#define memset_io(c, v, l)    _memset_io((c), (v), (l))
+#define memcpy_fromio(a, c, l)    _memcpy_fromio((a), (c), (l))
+#define memcpy_toio(c, a, l)  _memcpy_toio((c), (a), (l))
+
+#define eth_io_copy_and_sum(s, c, l, b) eth_copy_and_sum((s), (c), (l), (b))
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/irqs.h b/arch/arm/mach-bcmring/include/mach/irqs.h
new file mode 100644
index 0000000..b279b82
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/irqs.h
@@ -0,0 +1,132 @@
+/*
+ *  Copyright (C) 2007 Broadcom
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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
+ */
+
+#if !defined(ARCH_BCMRING_IRQS_H)
+#define ARCH_BCMRING_IRQS_H
+
+/* INTC0 - interrupt controller 0 */
+#define IRQ_INTC0_START     0
+#define IRQ_DMA0C0          0	/* DMA0 channel 0 interrupt */
+#define IRQ_DMA0C1          1	/* DMA0 channel 1 interrupt */
+#define IRQ_DMA0C2          2	/* DMA0 channel 2 interrupt */
+#define IRQ_DMA0C3          3	/* DMA0 channel 3 interrupt */
+#define IRQ_DMA0C4          4	/* DMA0 channel 4 interrupt */
+#define IRQ_DMA0C5          5	/* DMA0 channel 5 interrupt */
+#define IRQ_DMA0C6          6	/* DMA0 channel 6 interrupt */
+#define IRQ_DMA0C7          7	/* DMA0 channel 7 interrupt */
+#define IRQ_DMA1C0          8	/* DMA1 channel 0 interrupt */
+#define IRQ_DMA1C1          9	/* DMA1 channel 1 interrupt */
+#define IRQ_DMA1C2         10	/* DMA1 channel 2 interrupt */
+#define IRQ_DMA1C3         11	/* DMA1 channel 3 interrupt */
+#define IRQ_DMA1C4         12	/* DMA1 channel 4 interrupt */
+#define IRQ_DMA1C5         13	/* DMA1 channel 5 interrupt */
+#define IRQ_DMA1C6         14	/* DMA1 channel 6 interrupt */
+#define IRQ_DMA1C7         15	/* DMA1 channel 7 interrupt */
+#define IRQ_VPM            16	/* Voice process module interrupt */
+#define IRQ_USBHD2         17	/* USB host2/device2 interrupt */
+#define IRQ_USBH1          18	/* USB1 host interrupt */
+#define IRQ_USBD           19	/* USB device interrupt */
+#define IRQ_SDIOH0         20	/* SDIO0 host interrupt */
+#define IRQ_SDIOH1         21	/* SDIO1 host interrupt */
+#define IRQ_TIMER0         22	/* Timer0 interrupt */
+#define IRQ_TIMER1         23	/* Timer1 interrupt */
+#define IRQ_TIMER2         24	/* Timer2 interrupt */
+#define IRQ_TIMER3         25	/* Timer3 interrupt */
+#define IRQ_SPIH           26	/* SPI host interrupt */
+#define IRQ_ESW            27	/* Ethernet switch interrupt */
+#define IRQ_APM            28	/* Audio process module interrupt */
+#define IRQ_GE             29	/* Graphic engine interrupt */
+#define IRQ_CLCD           30	/* LCD Controller interrupt */
+#define IRQ_PIF            31	/* Peripheral interface interrupt */
+#define IRQ_INTC0_END      31
+
+/* INTC1 - interrupt controller 1 */
+#define IRQ_INTC1_START    32
+#define IRQ_GPIO0          32	/*  0 GPIO bit 31//0 combined interrupt */
+#define IRQ_GPIO1          33	/*  1 GPIO bit 64//32 combined interrupt */
+#define IRQ_I2S0           34	/*  2 I2S0 interrupt */
+#define IRQ_I2S1           35	/*  3 I2S1 interrupt */
+#define IRQ_I2CH           36	/*  4 I2C host interrupt */
+#define IRQ_I2CS           37	/*  5 I2C slave interrupt */
+#define IRQ_SPIS           38	/*  6 SPI slave interrupt */
+#define IRQ_GPHY           39	/*  7 Gigabit Phy interrupt */
+#define IRQ_FLASHC         40	/*  8 Flash controller interrupt */
+#define IRQ_COMMTX         41	/*  9 ARM DDC transmit interrupt */
+#define IRQ_COMMRX         42	/* 10 ARM DDC receive interrupt */
+#define IRQ_PMUIRQ         43	/* 11 ARM performance monitor interrupt */
+#define IRQ_UARTB          44	/* 12 UARTB */
+#define IRQ_WATCHDOG       45	/* 13 Watchdog timer interrupt */
+#define IRQ_UARTA          46	/* 14 UARTA */
+#define IRQ_TSC            47	/* 15 Touch screen controller interrupt */
+#define IRQ_KEYC           48	/* 16 Key pad controller interrupt */
+#define IRQ_DMPU           49	/* 17 DDR2 memory partition interrupt */
+#define IRQ_VMPU           50	/* 18 VRAM memory partition interrupt */
+#define IRQ_FMPU           51	/* 19 Flash memory parition unit interrupt */
+#define IRQ_RNG            52	/* 20 Random number generator interrupt */
+#define IRQ_RTC0           53	/* 21 Real time clock periodic interrupt */
+#define IRQ_RTC1           54	/* 22 Real time clock one-shot interrupt */
+#define IRQ_SPUM           55	/* 23 Secure process module interrupt */
+#define IRQ_VDEC           56	/* 24 Hantro video decoder interrupt */
+#define IRQ_RTC2           57	/* 25 Real time clock tamper interrupt */
+#define IRQ_DDRP           58	/* 26 DDR Panic interrupt */
+#define IRQ_INTC1_END      58
+
+/* SINTC secure int controller */
+#define IRQ_SINTC_START    59
+#define IRQ_SEC_WATCHDOG   59	/*  0 Watchdog timer interrupt */
+#define IRQ_SEC_UARTA      60	/*  1 UARTA interrupt */
+#define IRQ_SEC_TSC        61	/*  2 Touch screen controller interrupt */
+#define IRQ_SEC_KEYC       62	/*  3 Key pad controller interrupt */
+#define IRQ_SEC_DMPU       63	/*  4 DDR2 memory partition interrupt */
+#define IRQ_SEC_VMPU       64	/*  5 VRAM memory partition interrupt */
+#define IRQ_SEC_FMPU       65	/*  6 Flash memory parition unit interrupt */
+#define IRQ_SEC_RNG        66	/*  7 Random number generator interrupt */
+#define IRQ_SEC_RTC0       67	/*  8 Real time clock periodic interrupt */
+#define IRQ_SEC_RTC1       68	/*  9 Real time clock one-shot interrupt */
+#define IRQ_SEC_SPUM       69	/* 10 Secure process module interrupt */
+#define IRQ_SEC_TIMER0     70	/* 11 Secure timer0 interrupt */
+#define IRQ_SEC_TIMER1     71	/* 12 Secure timer1 interrupt */
+#define IRQ_SEC_TIMER2     72	/* 13 Secure timer2 interrupt */
+#define IRQ_SEC_TIMER3     73	/* 14 Secure timer3 interrupt */
+#define IRQ_SEC_RTC2       74	/* 15 Real time clock tamper interrupt */
+
+#define IRQ_SINTC_END      74
+
+/* Note: there are 3 INTC registers of 32 bits each. So internal IRQs could go from 0-95 */
+/*       Since IRQs are typically viewed in decimal, we start the gpio based IRQs off at 100 */
+/*       to make the mapping easy for humans to decipher. */
+
+#define IRQ_GPIO_0                  100
+
+#define NUM_INTERNAL_IRQS          (IRQ_SINTC_END+1)
+
+/* I couldn't get the gpioHw_reg.h file to be included cleanly, so I hardcoded it */
+/* define NUM_GPIO_IRQS               GPIOHW_TOTAL_NUM_PINS */
+#define NUM_GPIO_IRQS               62
+
+#define NR_IRQS                     (IRQ_GPIO_0 + NUM_GPIO_IRQS)
+
+#define IRQ_UNKNOWN                 -1
+
+/* Tune these bits to preclude noisy or unsupported interrupt sources as required. */
+#define IRQ_INTC0_VALID_MASK        0xffffffff
+#define IRQ_INTC1_VALID_MASK        0x07ffffff
+#define IRQ_SINTC_VALID_MASK        0x0000ffff
+
+#endif /* ARCH_BCMRING_IRQS_H */
diff --git a/arch/arm/mach-bcmring/include/mach/memory.h b/arch/arm/mach-bcmring/include/mach/memory.h
new file mode 100644
index 0000000..114f942
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/memory.h
@@ -0,0 +1,33 @@
+/*****************************************************************************
+* Copyright 2005 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <cfg_global.h>
+
+/*
+ * Physical vs virtual RAM address space conversion.  These are
+ * private definitions which should NOT be used outside memory.h
+ * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
+ */
+
+#define PHYS_OFFSET CFG_GLOBAL_RAM_BASE
+
+/*
+ * Maximum DMA memory allowed is 14M
+ */
+#define CONSISTENT_DMA_SIZE (SZ_16M - SZ_2M)
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/memory_settings.h b/arch/arm/mach-bcmring/include/mach/memory_settings.h
new file mode 100644
index 0000000..ce5cd16
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/memory_settings.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef MEMORY_SETTINGS_H
+#define MEMORY_SETTINGS_H
+
+/* ---- Include Files ---------------------------------------- */
+/* ---- Constants and Types ---------------------------------- */
+
+/* Memory devices */
+/* NAND Flash timing for 166 MHz setting */
+#define HW_CFG_NAND_tBTA  (5 << 16)	/* Bus turnaround cycle (n)        0-7  (30 ns) */
+#define HW_CFG_NAND_tWP   (4 << 11)	/* Write pulse width cycle (n+1)   0-31 (25 ns) */
+#define HW_CFG_NAND_tWR   (1 << 9)	/* Write recovery cycle (n+1)      0-3  (10 ns) */
+#define HW_CFG_NAND_tAS   (0 << 7)	/* Write address setup cycle (n+1) 0-3  ( 0 ns) */
+#define HW_CFG_NAND_tOE   (3 << 5)	/* Output enable delay cycle (n)   0-3  (15 ns) */
+#define HW_CFG_NAND_tRC   (7 << 0)	/* Read access cycle (n+2)         0-31 (50 ns) */
+
+#define HW_CFG_NAND_TCR (HW_CFG_NAND_tBTA \
+	| HW_CFG_NAND_tWP  \
+	| HW_CFG_NAND_tWR  \
+	| HW_CFG_NAND_tAS  \
+	| HW_CFG_NAND_tOE  \
+	| HW_CFG_NAND_tRC)
+
+/* NOR Flash timing for 166 MHz setting */
+#define HW_CFG_NOR_TPRC_TWLC (0 << 19)	/* Page read access cycle / Burst write latency (n+2 / n+1) (max 25ns) */
+#define HW_CFG_NOR_TBTA      (0 << 16)	/* Bus turnaround cycle (n)                                 (DNA)      */
+#define HW_CFG_NOR_TWP       (6 << 11)	/* Write pulse width cycle (n+1)                            (35ns)     */
+#define HW_CFG_NOR_TWR       (0 << 9)	/* Write recovery cycle (n+1)                               (0ns)      */
+#define HW_CFG_NOR_TAS       (0 << 7)	/* Write address setup cycle (n+1)                          (0ns)      */
+#define HW_CFG_NOR_TOE       (0 << 5)	/* Output enable delay cycle (n)                            (max 25ns) */
+#define HW_CFG_NOR_TRC_TLC   (0x10 << 0)	/* Read access cycle / Burst read latency (n+2 / n+1)       (100ns)    */
+
+#define HW_CFG_FLASH0_TCR (HW_CFG_NOR_TPRC_TWLC \
+	| HW_CFG_NOR_TBTA      \
+	| HW_CFG_NOR_TWP       \
+	| HW_CFG_NOR_TWR       \
+	| HW_CFG_NOR_TAS       \
+	| HW_CFG_NOR_TOE       \
+	| HW_CFG_NOR_TRC_TLC)
+
+#define HW_CFG_FLASH1_TCR    HW_CFG_FLASH0_TCR
+#define HW_CFG_FLASH2_TCR    HW_CFG_FLASH0_TCR
+
+/* SDRAM Settings */
+/* #define HW_CFG_SDRAM_CAS_LATENCY        5    Default 5, Values [3..6] */
+/* #define HW_CFG_SDRAM_CHIP_SELECT_CNT    1    Default 1, Vaules [1..2] */
+/* #define HW_CFG_SDRAM_SPEED_GRADE        667  Default 667, Values [400,533,667,800] */
+/* #define HW_CFG_SDRAM_WIDTH_BITS         16   Default 16, Vaules [8,16] */
+#define HW_CFG_SDRAM_SIZE_BYTES         0x10000000	/* Total memory, not per device size */
+
+/* ---- Variable Externs ------------------------------------- */
+/* ---- Function Prototypes ---------------------------------- */
+
+#endif /* MEMORY_SETTINGS_H */
diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h
new file mode 100644
index 0000000..cdbf93c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/system.h
@@ -0,0 +1,54 @@
+/*
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/csp/chipcHw_inline.h>
+
+extern int bcmring_arch_warm_reboot;
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, char *cmd)
+{
+	printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot);
+
+	if (mode == 'h') {
+		/* Reboot configured in proc entry */
+		if (bcmring_arch_warm_reboot) {
+			printk("warm reset\n");
+			/* Issue Warm reset (do not reset ethernet switch, keep alive) */
+			chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_WARM);
+		} else {
+			/* Force reset of everything */
+			printk("force reset\n");
+			chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
+		}
+	} else {
+		/* Force reset of everything */
+		printk("force reset\n");
+		chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
+	}
+}
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/timer.h b/arch/arm/mach-bcmring/include/mach/timer.h
new file mode 100644
index 0000000..5a94bbb
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/timer.h
@@ -0,0 +1,77 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+*
+*****************************************************************************
+*
+*  timer.h
+*
+*  PURPOSE:
+*
+*
+*
+*  NOTES:
+*
+*****************************************************************************/
+
+#if !defined(BCM_LINUX_TIMER_H)
+#define BCM_LINUX_TIMER_H
+
+#if defined(__KERNEL__)
+
+/* ---- Include Files ---------------------------------------------------- */
+/* ---- Constants and Types ---------------------------------------------- */
+
+typedef unsigned int timer_tick_count_t;
+typedef unsigned int timer_tick_rate_t;
+typedef unsigned int timer_msec_t;
+
+/* ---- Variable Externs ------------------------------------------------- */
+/* ---- Function Prototypes ---------------------------------------------- */
+
+/****************************************************************************
+*
+*  timer_get_tick_count
+*
+*
+***************************************************************************/
+timer_tick_count_t timer_get_tick_count(void);
+
+/****************************************************************************
+*
+*  timer_get_tick_rate
+*
+*
+***************************************************************************/
+timer_tick_rate_t timer_get_tick_rate(void);
+
+/****************************************************************************
+*
+*  timer_get_msec
+*
+*
+***************************************************************************/
+timer_msec_t timer_get_msec(void);
+
+/****************************************************************************
+*
+*  timer_ticks_to_msec
+*
+*
+***************************************************************************/
+timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks);
+
+#endif /* __KERNEL__ */
+#endif /* BCM_LINUX_TIMER_H */
diff --git a/arch/arm/mach-bcmring/include/mach/timex.h b/arch/arm/mach-bcmring/include/mach/timex.h
new file mode 100644
index 0000000..40d033e
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/timex.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  Integrator architecture timex specifications
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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
+ */
+
+/*
+ * Specifies the number of ticks per second
+ */
+#define CLOCK_TICK_RATE		100000 /* REG_SMT_TICKS_PER_SEC */
diff --git a/arch/arm/mach-bcmring/include/mach/uncompress.h b/arch/arm/mach-bcmring/include/mach/uncompress.h
new file mode 100644
index 0000000..9c9821b
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/uncompress.h
@@ -0,0 +1,43 @@
+/*****************************************************************************
+* Copyright 2005 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+#include <mach/csp/mm_addr.h>
+
+#define BCMRING_UART_0_DR (*(volatile unsigned int *)MM_ADDR_IO_UARTA)
+#define BCMRING_UART_0_FR (*(volatile unsigned int *)(MM_ADDR_IO_UARTA + 0x18))
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+	/* Send out UARTA */
+	while (BCMRING_UART_0_FR & (1 << 5))
+		;
+
+	BCMRING_UART_0_DR = c;
+}
+
+
+static inline void flush(void)
+{
+	/* Wait for the tx fifo to be empty */
+	while ((BCMRING_UART_0_FR & (1 << 7)) == 0)
+		;
+
+	/* Wait for the final character to be sent on the txd line */
+	while (BCMRING_UART_0_FR & (1 << 3))
+		;
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h
new file mode 100644
index 0000000..35e2ead
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  Copyright (C) 2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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
+ */
+
+/*
+ * Move VMALLOC_END to 0xf0000000 so that the vm space can range from
+ * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
+ * larger physical memory designs better.
+ */
+#define VMALLOC_END       (PAGE_OFFSET + 0x30000000)
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c
new file mode 100644
index 0000000..dc1c493
--- /dev/null
+++ b/arch/arm/mach-bcmring/irq.c
@@ -0,0 +1,127 @@
+/*
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/version.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <mach/csp/intcHw_reg.h>
+#include <mach/csp/mm_io.h>
+
+static void bcmring_mask_irq0(unsigned int irq)
+{
+	writel(1 << (irq - IRQ_INTC0_START),
+	       MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR);
+}
+
+static void bcmring_unmask_irq0(unsigned int irq)
+{
+	writel(1 << (irq - IRQ_INTC0_START),
+	       MM_IO_BASE_INTC0 + INTCHW_INTENABLE);
+}
+
+static void bcmring_mask_irq1(unsigned int irq)
+{
+	writel(1 << (irq - IRQ_INTC1_START),
+	       MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR);
+}
+
+static void bcmring_unmask_irq1(unsigned int irq)
+{
+	writel(1 << (irq - IRQ_INTC1_START),
+	       MM_IO_BASE_INTC1 + INTCHW_INTENABLE);
+}
+
+static void bcmring_mask_irq2(unsigned int irq)
+{
+	writel(1 << (irq - IRQ_SINTC_START),
+	       MM_IO_BASE_SINTC + INTCHW_INTENCLEAR);
+}
+
+static void bcmring_unmask_irq2(unsigned int irq)
+{
+	writel(1 << (irq - IRQ_SINTC_START),
+	       MM_IO_BASE_SINTC + INTCHW_INTENABLE);
+}
+
+static struct irq_chip bcmring_irq0_chip = {
+	.typename = "ARM-INTC0",
+	.ack = bcmring_mask_irq0,
+	.mask = bcmring_mask_irq0,	/* mask a specific interrupt, blocking its delivery. */
+	.unmask = bcmring_unmask_irq0,	/* unmaks an interrupt */
+};
+
+static struct irq_chip bcmring_irq1_chip = {
+	.typename = "ARM-INTC1",
+	.ack = bcmring_mask_irq1,
+	.mask = bcmring_mask_irq1,
+	.unmask = bcmring_unmask_irq1,
+};
+
+static struct irq_chip bcmring_irq2_chip = {
+	.typename = "ARM-SINTC",
+	.ack = bcmring_mask_irq2,
+	.mask = bcmring_mask_irq2,
+	.unmask = bcmring_unmask_irq2,
+};
+
+static void vic_init(void __iomem *base, struct irq_chip *chip,
+		     unsigned int irq_start, unsigned int vic_sources)
+{
+	unsigned int i;
+	for (i = 0; i < 32; i++) {
+		unsigned int irq = irq_start + i;
+		set_irq_chip(irq, chip);
+		set_irq_chip_data(irq, base);
+
+		if (vic_sources & (1 << i)) {
+			set_irq_handler(irq, handle_level_irq);
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+		}
+	}
+	writel(0, base + INTCHW_INTSELECT);
+	writel(0, base + INTCHW_INTENABLE);
+	writel(~0, base + INTCHW_INTENCLEAR);
+	writel(0, base + INTCHW_IRQSTATUS);
+	writel(~0, base + INTCHW_SOFTINTCLEAR);
+}
+
+void __init bcmring_init_irq(void)
+{
+	vic_init((void __iomem *)MM_IO_BASE_INTC0, &bcmring_irq0_chip,
+		 IRQ_INTC0_START, IRQ_INTC0_VALID_MASK);
+	vic_init((void __iomem *)MM_IO_BASE_INTC1, &bcmring_irq1_chip,
+		 IRQ_INTC1_START, IRQ_INTC1_VALID_MASK);
+	vic_init((void __iomem *)MM_IO_BASE_SINTC, &bcmring_irq2_chip,
+		 IRQ_SINTC_START, IRQ_SINTC_VALID_MASK);
+
+	/* special cases */
+	if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) {
+		set_irq_handler(IRQ_GPIO0, handle_simple_irq);
+	}
+	if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) {
+		set_irq_handler(IRQ_GPIO1, handle_simple_irq);
+	}
+}
diff --git a/arch/arm/mach-bcmring/mm.c b/arch/arm/mach-bcmring/mm.c
new file mode 100644
index 0000000..0f1c37e
--- /dev/null
+++ b/arch/arm/mach-bcmring/mm.c
@@ -0,0 +1,56 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/csp/mm_io.h>
+
+#define IO_DESC(va, sz) { .virtual = va, \
+	.pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \
+	.length = sz, \
+	.type = MT_DEVICE }
+
+#define MEM_DESC(va, sz) { .virtual = va, \
+	.pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \
+	.length = sz, \
+	.type = MT_MEMORY }
+
+static struct map_desc bcmring_io_desc[] __initdata = {
+	IO_DESC(MM_IO_BASE_NAND, SZ_64K),	/* phys:0x28000000-0x28000FFF  virt:0xE8000000-0xE8000FFF  size:0x00010000 */
+	IO_DESC(MM_IO_BASE_UMI, SZ_64K),	/* phys:0x2C000000-0x2C000FFF  virt:0xEC000000-0xEC000FFF  size:0x00010000 */
+
+	IO_DESC(MM_IO_BASE_BROM, SZ_64K),	/* phys:0x30000000-0x3000FFFF  virt:0xF3000000-0xF300FFFF  size:0x00010000 */
+	MEM_DESC(MM_IO_BASE_ARAM, SZ_1M),	/* phys:0x31000000-0x31FFFFFF  virt:0xF3100000-0xF31FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_DMA0, SZ_1M),	/* phys:0x32000000-0x32FFFFFF  virt:0xF3200000-0xF32FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_DMA1, SZ_1M),	/* phys:0x33000000-0x33FFFFFF  virt:0xF3300000-0xF33FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_ESW, SZ_1M),	/* phys:0x34000000-0x34FFFFFF  virt:0xF3400000-0xF34FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_CLCD, SZ_1M),	/* phys:0x35000000-0x35FFFFFF  virt:0xF3500000-0xF35FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_APM, SZ_1M),	/* phys:0x36000000-0x36FFFFFF  virt:0xF3600000-0xF36FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_SPUM, SZ_1M),	/* phys:0x37000000-0x37FFFFFF  virt:0xF3700000-0xF37FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_VPM_PROG, SZ_1M),	/* phys:0x38000000-0x38FFFFFF  virt:0xF3800000-0xF38FFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_VPM_DATA, SZ_1M),	/* phys:0x3A000000-0x3AFFFFFF  virt:0xF3A00000-0xF3AFFFFF  size:0x01000000 */
+
+	IO_DESC(MM_IO_BASE_VRAM, SZ_64K),	/* phys:0x40000000-0x4000FFFF  virt:0xF4000000-0xF400FFFF  size:0x00010000 */
+	IO_DESC(MM_IO_BASE_CHIPC, SZ_16M),	/* phys:0x80000000-0x80FFFFFF  virt:0xF8000000-0xF8FFFFFF  size:0x01000000 */
+	IO_DESC(MM_IO_BASE_VPM_EXTMEM_RSVD,
+		SZ_16M),	/* phys:0x0F000000-0x0FFFFFFF  virt:0xF0000000-0xF0FFFFFF  size:0x01000000 */
+};
+
+void __init bcmring_map_io(void)
+{
+
+	iotable_init(bcmring_io_desc, ARRAY_SIZE(bcmring_io_desc));
+}
diff --git a/arch/arm/mach-bcmring/timer.c b/arch/arm/mach-bcmring/timer.c
new file mode 100644
index 0000000..2d415d2
--- /dev/null
+++ b/arch/arm/mach-bcmring/timer.c
@@ -0,0 +1,62 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <csp/tmrHw.h>
+
+#include <mach/timer.h>
+/* The core.c file initializes timers 1 and 3 as a linux clocksource. */
+/* The real time clock should probably be the real linux clocksource. */
+/* In the meantime, this file should agree with core.c as to the */
+/* profiling timer. If the clocksource is moved to rtc later, then */
+/* we can init the profiling timer here instead. */
+
+/* Timer 1 provides 25MHz resolution syncrhonized to scheduling and APM timing */
+/* Timer 3 provides bus freqeuncy sychronized to ACLK, but spread spectrum will */
+/* affect synchronization with scheduling and APM timing. */
+
+#define PROF_TIMER 1
+
+timer_tick_rate_t timer_get_tick_rate(void)
+{
+	return tmrHw_getCountRate(PROF_TIMER);
+}
+
+timer_tick_count_t timer_get_tick_count(void)
+{
+	return tmrHw_GetCurrentCount(PROF_TIMER);	/* change downcounter to upcounter */
+}
+
+timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks)
+{
+	static int tickRateMsec;
+
+	if (tickRateMsec == 0) {
+		tickRateMsec = timer_get_tick_rate() / 1000;
+	}
+
+	return ticks / tickRateMsec;
+}
+
+timer_msec_t timer_get_msec(void)
+{
+	return timer_ticks_to_msec(timer_get_tick_count());
+}
+
+EXPORT_SYMBOL(timer_get_tick_count);
+EXPORT_SYMBOL(timer_ticks_to_msec);
+EXPORT_SYMBOL(timer_get_tick_rate);
+EXPORT_SYMBOL(timer_get_msec);
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index be747f5..40866c6 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -6,6 +6,9 @@ config AINTC
 config CP_INTC
 	bool
 
+config ARCH_DAVINCI_DMx
+	bool
+
 menu "TI DaVinci Implementations"
 
 comment "DaVinci Core Type"
@@ -13,20 +16,41 @@ comment "DaVinci Core Type"
 config ARCH_DAVINCI_DM644x
 	bool "DaVinci 644x based system"
 	select AINTC
+	select ARCH_DAVINCI_DMx
 
 config ARCH_DAVINCI_DM355
         bool "DaVinci 355 based system"
 	select AINTC
+	select ARCH_DAVINCI_DMx
 
 config ARCH_DAVINCI_DM646x
         bool "DaVinci 646x based system"
 	select AINTC
+	select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_DA830
+        bool "DA830/OMAP-L137 based system"
+	select CP_INTC
+	select ARCH_DAVINCI_DA8XX
+
+config ARCH_DAVINCI_DA850
+	bool "DA850/OMAP-L138 based system"
+	select CP_INTC
+	select ARCH_DAVINCI_DA8XX
+
+config ARCH_DAVINCI_DA8XX
+	bool
+
+config ARCH_DAVINCI_DM365
+	bool "DaVinci 365 based system"
+	select AINTC
+	select ARCH_DAVINCI_DMx
 
 comment "DaVinci Board Type"
 
 config MACH_DAVINCI_EVM
 	bool "TI DM644x EVM"
-	default y
+	default ARCH_DAVINCI_DM644x
 	depends on ARCH_DAVINCI_DM644x
 	help
 	  Configure this option to specify the whether the board used
@@ -41,6 +65,7 @@ config MACH_SFFSDR
 
 config MACH_DAVINCI_DM355_EVM
 	bool "TI DM355 EVM"
+	default ARCH_DAVINCI_DM355
 	depends on ARCH_DAVINCI_DM355
 	help
 	  Configure this option to specify the whether the board used
@@ -55,11 +80,33 @@ config MACH_DM355_LEOPARD
 
 config MACH_DAVINCI_DM6467_EVM
 	bool "TI DM6467 EVM"
+	default ARCH_DAVINCI_DM646x
 	depends on ARCH_DAVINCI_DM646x
 	help
 	  Configure this option to specify the whether the board used
 	  for development is a DM6467 EVM
 
+config MACH_DAVINCI_DM365_EVM
+	bool "TI DM365 EVM"
+	default ARCH_DAVINCI_DM365
+	depends on ARCH_DAVINCI_DM365
+	help
+	  Configure this option to specify whether the board used
+	  for development is a DM365 EVM
+
+config MACH_DAVINCI_DA830_EVM
+	bool "TI DA830/OMAP-L137 Reference Platform"
+	default ARCH_DAVINCI_DA830
+	depends on ARCH_DAVINCI_DA830
+	help
+	  Say Y here to select the TI DA830/OMAP-L137 Evaluation Module.
+
+config MACH_DAVINCI_DA850_EVM
+	bool "TI DA850/OMAP-L138 Reference Platform"
+	default ARCH_DAVINCI_DA850
+	depends on ARCH_DAVINCI_DA850
+	help
+	  Say Y here to select the TI DA850/OMAP-L138 Evaluation Module.
 
 config DAVINCI_MUX
 	bool "DAVINCI multiplexing support"
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 059ab78..2e11e84 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -5,14 +5,17 @@
 
 # Common objects
 obj-y 			:= time.o clock.o serial.o io.o psc.o \
-			   gpio.o devices.o dma.o usb.o common.o sram.o
+			   gpio.o dma.o usb.o common.o sram.o
 
 obj-$(CONFIG_DAVINCI_MUX)		+= mux.o
 
 # Chip specific
-obj-$(CONFIG_ARCH_DAVINCI_DM644x)       += dm644x.o
-obj-$(CONFIG_ARCH_DAVINCI_DM355)        += dm355.o
-obj-$(CONFIG_ARCH_DAVINCI_DM646x)       += dm646x.o
+obj-$(CONFIG_ARCH_DAVINCI_DM644x)       += dm644x.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355)        += dm355.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x)       += dm646x.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM365)	+= dm365.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DA830)        += da830.o devices-da8xx.o
+obj-$(CONFIG_ARCH_DAVINCI_DA850)        += da850.o devices-da8xx.o
 
 obj-$(CONFIG_AINTC)			+= irq.o
 obj-$(CONFIG_CP_INTC)			+= cp_intc.o
@@ -23,3 +26,6 @@ obj-$(CONFIG_MACH_SFFSDR)		+= board-sffsdr.o
 obj-$(CONFIG_MACH_DAVINCI_DM355_EVM)	+= board-dm355-evm.o
 obj-$(CONFIG_MACH_DM355_LEOPARD)	+= board-dm355-leopard.o
 obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM)	+= board-dm646x-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DM365_EVM)	+= board-dm365-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DA830_EVM)	+= board-da830-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DA850_EVM)	+= board-da850-evm.o
diff --git a/arch/arm/mach-davinci/Makefile.boot b/arch/arm/mach-davinci/Makefile.boot
index e1dd366..db97ef2 100644
--- a/arch/arm/mach-davinci/Makefile.boot
+++ b/arch/arm/mach-davinci/Makefile.boot
@@ -1,3 +1,13 @@
+ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y)
+ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
+$(error Cannot enable DaVinci and DA8XX platforms concurrently)
+else
+   zreladdr-y	:= 0xc0008000
+params_phys-y	:= 0xc0000100
+initrd_phys-y	:= 0xc0800000
+endif
+else
    zreladdr-y	:= 0x80008000
 params_phys-y	:= 0x80000100
 initrd_phys-y	:= 0x80800000
+endif
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
new file mode 100644
index 0000000..bfbb639
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -0,0 +1,157 @@
+/*
+ * TI DA830/OMAP L137 EVM board
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ * Derived from: arch/arm/mach-davinci/board-dm644x-evm.c
+ *
+ * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/asp.h>
+
+#define DA830_EVM_PHY_MASK		0x0
+#define DA830_EVM_MDIO_FREQUENCY	2200000	/* PHY bus frequency */
+
+static struct at24_platform_data da830_evm_i2c_eeprom_info = {
+	.byte_len	= SZ_256K / 8,
+	.page_size	= 64,
+	.flags		= AT24_FLAG_ADDR16,
+	.setup		= davinci_get_mac_addr,
+	.context	= (void *)0x7f00,
+};
+
+static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("24c256", 0x50),
+		.platform_data	= &da830_evm_i2c_eeprom_info,
+	},
+	{
+		I2C_BOARD_INFO("tlv320aic3x", 0x18),
+	}
+};
+
+static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
+	.bus_freq	= 100,	/* kHz */
+	.bus_delay	= 0,	/* usec */
+};
+
+static struct davinci_uart_config da830_evm_uart_config __initdata = {
+	.enabled_uarts = 0x7,
+};
+
+static u8 da830_iis_serializer_direction[] = {
+	RX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
+	INACTIVE_MODE,	TX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
+	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
+};
+
+static struct snd_platform_data da830_evm_snd_data = {
+	.tx_dma_offset  = 0x2000,
+	.rx_dma_offset  = 0x2000,
+	.op_mode        = DAVINCI_MCASP_IIS_MODE,
+	.num_serializer = ARRAY_SIZE(da830_iis_serializer_direction),
+	.tdm_slots      = 2,
+	.serial_dir     = da830_iis_serializer_direction,
+	.eventq_no      = EVENTQ_0,
+	.version	= MCASP_VERSION_2,
+	.txnumevt	= 1,
+	.rxnumevt	= 1,
+};
+
+static __init void da830_evm_init(void)
+{
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	int ret;
+
+	ret = da8xx_register_edma();
+	if (ret)
+		pr_warning("da830_evm_init: edma registration failed: %d\n",
+				ret);
+
+	ret = da8xx_pinmux_setup(da830_i2c0_pins);
+	if (ret)
+		pr_warning("da830_evm_init: i2c0 mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_register_i2c(0, &da830_evm_i2c_0_pdata);
+	if (ret)
+		pr_warning("da830_evm_init: i2c0 registration failed: %d\n",
+				ret);
+
+	soc_info->emac_pdata->phy_mask = DA830_EVM_PHY_MASK;
+	soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY;
+	soc_info->emac_pdata->rmii_en = 1;
+
+	ret = da8xx_pinmux_setup(da830_cpgmac_pins);
+	if (ret)
+		pr_warning("da830_evm_init: cpgmac mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_register_emac();
+	if (ret)
+		pr_warning("da830_evm_init: emac registration failed: %d\n",
+				ret);
+
+	ret = da8xx_register_watchdog();
+	if (ret)
+		pr_warning("da830_evm_init: watchdog registration failed: %d\n",
+				ret);
+
+	davinci_serial_init(&da830_evm_uart_config);
+	i2c_register_board_info(1, da830_evm_i2c_devices,
+			ARRAY_SIZE(da830_evm_i2c_devices));
+
+	ret = da8xx_pinmux_setup(da830_mcasp1_pins);
+	if (ret)
+		pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n",
+				ret);
+
+	da8xx_init_mcasp(1, &da830_evm_snd_data);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init da830_evm_console_init(void)
+{
+	return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(da830_evm_console_init);
+#endif
+
+static __init void da830_evm_irq_init(void)
+{
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+	cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA830_N_CP_INTC_IRQ,
+			soc_info->intc_irq_prios);
+}
+
+static void __init da830_evm_map_io(void)
+{
+	da830_init();
+}
+
+MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP L137 EVM")
+	.phys_io	= IO_PHYS,
+	.io_pg_offst	= (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+	.boot_params	= (DA8XX_DDR_BASE + 0x100),
+	.map_io		= da830_evm_map_io,
+	.init_irq	= da830_evm_irq_init,
+	.timer		= &davinci_timer,
+	.init_machine	= da830_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
new file mode 100644
index 0000000..c759d72
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -0,0 +1,415 @@
+/*
+ * TI DA850/OMAP-L138 EVM board
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Derived from: arch/arm/mach-davinci/board-da830-evm.c
+ * Original Copyrights follow:
+ *
+ * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/nand.h>
+
+#define DA850_EVM_PHY_MASK		0x1
+#define DA850_EVM_MDIO_FREQUENCY	2200000 /* PHY bus frequency */
+
+#define DA850_LCD_BL_PIN		GPIO_TO_PIN(2, 15)
+#define DA850_LCD_PWR_PIN		GPIO_TO_PIN(8, 10)
+
+#define DA850_MMCSD_CD_PIN		GPIO_TO_PIN(4, 0)
+#define DA850_MMCSD_WP_PIN		GPIO_TO_PIN(4, 1)
+
+static struct mtd_partition da850_evm_norflash_partition[] = {
+	{
+		.name           = "NOR filesystem",
+		.offset         = 0,
+		.size           = MTDPART_SIZ_FULL,
+		.mask_flags     = 0,
+	},
+};
+
+static struct physmap_flash_data da850_evm_norflash_data = {
+	.width		= 2,
+	.parts		= da850_evm_norflash_partition,
+	.nr_parts	= ARRAY_SIZE(da850_evm_norflash_partition),
+};
+
+static struct resource da850_evm_norflash_resource[] = {
+	{
+		.start	= DA8XX_AEMIF_CS2_BASE,
+		.end	= DA8XX_AEMIF_CS2_BASE + SZ_32M - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device da850_evm_norflash_device = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data  = &da850_evm_norflash_data,
+	},
+	.num_resources	= 1,
+	.resource	= da850_evm_norflash_resource,
+};
+
+/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
+ * (128K blocks). It may be used instead of the (default) SPI flash
+ * to boot, using TI's tools to install the secondary boot loader
+ * (UBL) and U-Boot.
+ */
+struct mtd_partition da850_evm_nandflash_partition[] = {
+	{
+		.name		= "u-boot env",
+		.offset		= 0,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	 },
+	{
+		.name		= "UBL",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	{
+		.name		= "u-boot",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 4 * SZ_128K,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+	{
+		.name		= "kernel",
+		.offset		= 0x200000,
+		.size		= SZ_2M,
+		.mask_flags	= 0,
+	},
+	{
+		.name		= "filesystem",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	},
+};
+
+static struct davinci_nand_pdata da850_evm_nandflash_data = {
+	.parts		= da850_evm_nandflash_partition,
+	.nr_parts	= ARRAY_SIZE(da850_evm_nandflash_partition),
+	.ecc_mode	= NAND_ECC_HW,
+	.options	= NAND_USE_FLASH_BBT,
+};
+
+static struct resource da850_evm_nandflash_resource[] = {
+	{
+		.start	= DA8XX_AEMIF_CS3_BASE,
+		.end	= DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= DA8XX_AEMIF_CTL_BASE,
+		.end	= DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device da850_evm_nandflash_device = {
+	.name		= "davinci_nand",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &da850_evm_nandflash_data,
+	},
+	.num_resources	= ARRAY_SIZE(da850_evm_nandflash_resource),
+	.resource	= da850_evm_nandflash_resource,
+};
+
+static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("tlv320aic3x", 0x18),
+	}
+};
+
+static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
+	.bus_freq	= 100,	/* kHz */
+	.bus_delay	= 0,	/* usec */
+};
+
+static struct davinci_uart_config da850_evm_uart_config __initdata = {
+	.enabled_uarts = 0x7,
+};
+
+static struct platform_device *da850_evm_devices[] __initdata = {
+	&da850_evm_nandflash_device,
+	&da850_evm_norflash_device,
+};
+
+/* davinci da850 evm audio machine driver */
+static u8 da850_iis_serializer_direction[] = {
+	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
+	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
+	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	TX_MODE,
+	RX_MODE,	INACTIVE_MODE,	INACTIVE_MODE,	INACTIVE_MODE,
+};
+
+static struct snd_platform_data da850_evm_snd_data = {
+	.tx_dma_offset	= 0x2000,
+	.rx_dma_offset	= 0x2000,
+	.op_mode	= DAVINCI_MCASP_IIS_MODE,
+	.num_serializer	= ARRAY_SIZE(da850_iis_serializer_direction),
+	.tdm_slots	= 2,
+	.serial_dir	= da850_iis_serializer_direction,
+	.eventq_no	= EVENTQ_1,
+	.version	= MCASP_VERSION_2,
+	.txnumevt	= 1,
+	.rxnumevt	= 1,
+};
+
+static int da850_evm_mmc_get_ro(int index)
+{
+	return gpio_get_value(DA850_MMCSD_WP_PIN);
+}
+
+static int da850_evm_mmc_get_cd(int index)
+{
+	return !gpio_get_value(DA850_MMCSD_CD_PIN);
+}
+
+static struct davinci_mmc_config da850_mmc_config = {
+	.get_ro		= da850_evm_mmc_get_ro,
+	.get_cd		= da850_evm_mmc_get_cd,
+	.wires		= 4,
+	.version	= MMC_CTLR_VERSION_2,
+};
+
+static int da850_lcd_hw_init(void)
+{
+	int status;
+
+	status = gpio_request(DA850_LCD_BL_PIN, "lcd bl\n");
+	if (status < 0)
+		return status;
+
+	status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr\n");
+	if (status < 0) {
+		gpio_free(DA850_LCD_BL_PIN);
+		return status;
+	}
+
+	gpio_direction_output(DA850_LCD_BL_PIN, 0);
+	gpio_direction_output(DA850_LCD_PWR_PIN, 0);
+
+	/* disable lcd backlight */
+	gpio_set_value(DA850_LCD_BL_PIN, 0);
+
+	/* disable lcd power */
+	gpio_set_value(DA850_LCD_PWR_PIN, 0);
+
+	/* enable lcd power */
+	gpio_set_value(DA850_LCD_PWR_PIN, 1);
+
+	/* enable lcd backlight */
+	gpio_set_value(DA850_LCD_BL_PIN, 1);
+
+	return 0;
+}
+
+#define DA8XX_AEMIF_CE2CFG_OFFSET	0x10
+#define DA8XX_AEMIF_ASIZE_16BIT		0x1
+
+static void __init da850_evm_init_nor(void)
+{
+	void __iomem *aemif_addr;
+
+	aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
+
+	/* Configure data bus width of CS2 to 16 bit */
+	writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
+		DA8XX_AEMIF_ASIZE_16BIT,
+		aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
+
+	iounmap(aemif_addr);
+}
+
+#if defined(CONFIG_MTD_PHYSMAP) || \
+    defined(CONFIG_MTD_PHYSMAP_MODULE)
+#define HAS_NOR 1
+#else
+#define HAS_NOR 0
+#endif
+
+#if defined(CONFIG_MMC_DAVINCI) || \
+    defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC 1
+#else
+#define HAS_MMC 0
+#endif
+
+static __init void da850_evm_init(void)
+{
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	int ret;
+
+	ret = da8xx_pinmux_setup(da850_nand_pins);
+	if (ret)
+		pr_warning("da850_evm_init: nand mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_pinmux_setup(da850_nor_pins);
+	if (ret)
+		pr_warning("da850_evm_init: nor mux setup failed: %d\n",
+				ret);
+
+	da850_evm_init_nor();
+
+	platform_add_devices(da850_evm_devices,
+				ARRAY_SIZE(da850_evm_devices));
+
+	ret = da8xx_register_edma();
+	if (ret)
+		pr_warning("da850_evm_init: edma registration failed: %d\n",
+				ret);
+
+	ret = da8xx_pinmux_setup(da850_i2c0_pins);
+	if (ret)
+		pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_register_i2c(0, &da850_evm_i2c_0_pdata);
+	if (ret)
+		pr_warning("da850_evm_init: i2c0 registration failed: %d\n",
+				ret);
+
+	soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK;
+	soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY;
+	soc_info->emac_pdata->rmii_en = 0;
+
+	ret = da8xx_pinmux_setup(da850_cpgmac_pins);
+	if (ret)
+		pr_warning("da850_evm_init: cpgmac mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_register_emac();
+	if (ret)
+		pr_warning("da850_evm_init: emac registration failed: %d\n",
+				ret);
+
+	ret = da8xx_register_watchdog();
+	if (ret)
+		pr_warning("da830_evm_init: watchdog registration failed: %d\n",
+				ret);
+
+	if (HAS_MMC) {
+		if (HAS_NOR)
+			pr_warning("WARNING: both NOR Flash and MMC/SD are "
+				"enabled, but they share AEMIF pins.\n"
+				"\tDisable one of them.\n");
+
+		ret = da8xx_pinmux_setup(da850_mmcsd0_pins);
+		if (ret)
+			pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
+					" %d\n", ret);
+
+		ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n");
+		if (ret)
+			pr_warning("da850_evm_init: can not open GPIO %d\n",
+					DA850_MMCSD_CD_PIN);
+		gpio_direction_input(DA850_MMCSD_CD_PIN);
+
+		ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n");
+		if (ret)
+			pr_warning("da850_evm_init: can not open GPIO %d\n",
+					DA850_MMCSD_WP_PIN);
+		gpio_direction_input(DA850_MMCSD_WP_PIN);
+
+		ret = da8xx_register_mmcsd0(&da850_mmc_config);
+		if (ret)
+			pr_warning("da850_evm_init: mmcsd0 registration failed:"
+					" %d\n", ret);
+	}
+
+	davinci_serial_init(&da850_evm_uart_config);
+
+	i2c_register_board_info(1, da850_evm_i2c_devices,
+			ARRAY_SIZE(da850_evm_i2c_devices));
+
+	/*
+	 * shut down uart 0 and 1; they are not used on the board and
+	 * accessing them causes endless "too much work in irq53" messages
+	 * with arago fs
+	 */
+	__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30);
+	__raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30);
+
+	ret = da8xx_pinmux_setup(da850_mcasp_pins);
+	if (ret)
+		pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
+				ret);
+
+	da8xx_init_mcasp(0, &da850_evm_snd_data);
+
+	ret = da8xx_pinmux_setup(da850_lcdcntl_pins);
+	if (ret)
+		pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
+				ret);
+
+	ret = da850_lcd_hw_init();
+	if (ret)
+		pr_warning("da850_evm_init: lcd initialization failed: %d\n",
+				ret);
+
+	ret = da8xx_register_lcdc();
+	if (ret)
+		pr_warning("da850_evm_init: lcdc registration failed: %d\n",
+				ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init da850_evm_console_init(void)
+{
+	return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(da850_evm_console_init);
+#endif
+
+static __init void da850_evm_irq_init(void)
+{
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+	cp_intc_init((void __iomem *)DA8XX_CP_INTC_VIRT, DA850_N_CP_INTC_IRQ,
+			soc_info->intc_irq_prios);
+}
+
+static void __init da850_evm_map_io(void)
+{
+	da850_init();
+}
+
+MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138 EVM")
+	.phys_io	= IO_PHYS,
+	.io_pg_offst	= (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+	.boot_params	= (DA8XX_DDR_BASE + 0x100),
+	.map_io		= da850_evm_map_io,
+	.init_irq	= da850_evm_irq_init,
+	.timer		= &davinci_timer,
+	.init_machine	= da850_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
index d6ab64c..77e8067 100644
--- a/arch/arm/mach-davinci/board-dm355-evm.c
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -20,6 +20,8 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
+#include <linux/videodev2.h>
+#include <media/tvp514x.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/eeprom.h>
 
@@ -117,6 +119,8 @@ static struct davinci_i2c_platform_data i2c_pdata = {
 	.bus_delay	= 0	/* usec */,
 };
 
+static struct snd_platform_data dm355_evm_snd_data;
+
 static int dm355evm_mmc_gpios = -EINVAL;
 
 static void dm355evm_mmcsd_gpios(unsigned gpio)
@@ -134,11 +138,11 @@ static void dm355evm_mmcsd_gpios(unsigned gpio)
 }
 
 static struct i2c_board_info dm355evm_i2c_info[] = {
-	{ I2C_BOARD_INFO("dm355evm_msp", 0x25),
+	{	I2C_BOARD_INFO("dm355evm_msp", 0x25),
 		.platform_data = dm355evm_mmcsd_gpios,
-		/* plus irq */ },
-	/* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */
-	/* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */
+	},
+	/* { plus irq  }, */
+	{ I2C_BOARD_INFO("tlv320aic33", 0x1b), },
 };
 
 static void __init evm_init_i2c(void)
@@ -177,6 +181,72 @@ static struct platform_device dm355evm_dm9000 = {
 	.num_resources	= ARRAY_SIZE(dm355evm_dm9000_rsrc),
 };
 
+static struct tvp514x_platform_data tvp5146_pdata = {
+	.clk_polarity = 0,
+	.hs_polarity = 1,
+	.vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL	(V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+	{
+		.index = 0,
+		.name = "Composite",
+		.type = V4L2_INPUT_TYPE_CAMERA,
+		.std = TVP514X_STD_ALL,
+	},
+	{
+		.index = 1,
+		.name = "S-Video",
+		.type = V4L2_INPUT_TYPE_CAMERA,
+		.std = TVP514X_STD_ALL,
+	},
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+	{
+		.input = INPUT_CVBS_VI2B,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+	},
+	{
+		.input = INPUT_SVIDEO_VI2C_VI1C,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+	},
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+	{
+		.name = "tvp5146",
+		.grp_id = 0,
+		.num_inputs = ARRAY_SIZE(tvp5146_inputs),
+		.inputs = tvp5146_inputs,
+		.routes = tvp5146_routes,
+		.can_route = 1,
+		.ccdc_if_params = {
+			.if_type = VPFE_BT656,
+			.hdpol = VPFE_PINPOL_POSITIVE,
+			.vdpol = VPFE_PINPOL_POSITIVE,
+		},
+		.board_info = {
+			I2C_BOARD_INFO("tvp5146", 0x5d),
+			.platform_data = &tvp5146_pdata,
+		},
+	}
+};
+
+static struct vpfe_config vpfe_cfg = {
+	.num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+	.sub_devs = vpfe_sub_devs,
+	.card_name = "DM355 EVM",
+	.ccdc = "DM355 CCDC",
+};
+
 static struct platform_device *davinci_evm_devices[] __initdata = {
 	&dm355evm_dm9000,
 	&davinci_nand_device,
@@ -188,6 +258,8 @@ static struct davinci_uart_config uart_config __initdata = {
 
 static void __init dm355_evm_map_io(void)
 {
+	/* setup input configuration for VPFE input devices */
+	dm355_set_vpfe_config(&vpfe_cfg);
 	dm355_init();
 }
 
@@ -279,6 +351,9 @@ static __init void dm355_evm_init(void)
 
 	dm355_init_spi0(BIT(0), dm355_evm_spi_info,
 			ARRAY_SIZE(dm355_evm_spi_info));
+
+	/* DM335 EVM uses ASP1; line-out is a stereo mini-jack */
+	dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN, &dm355_evm_snd_data);
 }
 
 static __init void dm355_evm_irq_init(void)
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
new file mode 100644
index 0000000..a1d5e7d
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -0,0 +1,492 @@
+/*
+ * TI DaVinci DM365 EVM board support
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ *
+ * This program is free software; 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/i2c/at24.h>
+#include <linux/leds.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/mux.h>
+#include <mach/hardware.h>
+#include <mach/dm365.h>
+#include <mach/psc.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/mmc.h>
+#include <mach/nand.h>
+
+
+static inline int have_imager(void)
+{
+	/* REVISIT when it's supported, trigger via Kconfig */
+	return 0;
+}
+
+static inline int have_tvp7002(void)
+{
+	/* REVISIT when it's supported, trigger via Kconfig */
+	return 0;
+}
+
+
+#define DM365_ASYNC_EMIF_CONTROL_BASE	0x01d10000
+#define DM365_ASYNC_EMIF_DATA_CE0_BASE	0x02000000
+#define DM365_ASYNC_EMIF_DATA_CE1_BASE	0x04000000
+
+#define DM365_EVM_PHY_MASK		(0x2)
+#define DM365_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
+
+/*
+ * A MAX-II CPLD is used for various board control functions.
+ */
+#define CPLD_OFFSET(a13a8,a2a1)		(((a13a8) << 10) + ((a2a1) << 3))
+
+#define CPLD_VERSION	CPLD_OFFSET(0,0)	/* r/o */
+#define CPLD_TEST	CPLD_OFFSET(0,1)
+#define CPLD_LEDS	CPLD_OFFSET(0,2)
+#define CPLD_MUX	CPLD_OFFSET(0,3)
+#define CPLD_SWITCH	CPLD_OFFSET(1,0)	/* r/o */
+#define CPLD_POWER	CPLD_OFFSET(1,1)
+#define CPLD_VIDEO	CPLD_OFFSET(1,2)
+#define CPLD_CARDSTAT	CPLD_OFFSET(1,3)	/* r/o */
+
+#define CPLD_DILC_OUT	CPLD_OFFSET(2,0)
+#define CPLD_DILC_IN	CPLD_OFFSET(2,1)	/* r/o */
+
+#define CPLD_IMG_DIR0	CPLD_OFFSET(2,2)
+#define CPLD_IMG_MUX0	CPLD_OFFSET(2,3)
+#define CPLD_IMG_MUX1	CPLD_OFFSET(3,0)
+#define CPLD_IMG_DIR1	CPLD_OFFSET(3,1)
+#define CPLD_IMG_MUX2	CPLD_OFFSET(3,2)
+#define CPLD_IMG_MUX3	CPLD_OFFSET(3,3)
+#define CPLD_IMG_DIR2	CPLD_OFFSET(4,0)
+#define CPLD_IMG_MUX4	CPLD_OFFSET(4,1)
+#define CPLD_IMG_MUX5	CPLD_OFFSET(4,2)
+
+#define CPLD_RESETS	CPLD_OFFSET(4,3)
+
+#define CPLD_CCD_DIR1	CPLD_OFFSET(0x3e,0)
+#define CPLD_CCD_IO1	CPLD_OFFSET(0x3e,1)
+#define CPLD_CCD_DIR2	CPLD_OFFSET(0x3e,2)
+#define CPLD_CCD_IO2	CPLD_OFFSET(0x3e,3)
+#define CPLD_CCD_DIR3	CPLD_OFFSET(0x3f,0)
+#define CPLD_CCD_IO3	CPLD_OFFSET(0x3f,1)
+
+static void __iomem *cpld;
+
+
+/* NOTE:  this is geared for the standard config, with a socketed
+ * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors.  If you
+ * swap chips with a different block size, partitioning will
+ * need to be changed. This NAND chip MT29F16G08FAA is the default
+ * NAND shipped with the Spectrum Digital DM365 EVM
+ */
+#define NAND_BLOCK_SIZE		SZ_128K
+
+static struct mtd_partition davinci_nand_partitions[] = {
+	{
+		/* UBL (a few copies) plus U-Boot */
+		.name		= "bootloader",
+		.offset		= 0,
+		.size		= 28 * NAND_BLOCK_SIZE,
+		.mask_flags	= MTD_WRITEABLE, /* force read-only */
+	}, {
+		/* U-Boot environment */
+		.name		= "params",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= 2 * NAND_BLOCK_SIZE,
+		.mask_flags	= 0,
+	}, {
+		.name		= "kernel",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_4M,
+		.mask_flags	= 0,
+	}, {
+		.name		= "filesystem1",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= SZ_512M,
+		.mask_flags	= 0,
+	}, {
+		.name		= "filesystem2",
+		.offset		= MTDPART_OFS_APPEND,
+		.size		= MTDPART_SIZ_FULL,
+		.mask_flags	= 0,
+	}
+	/* two blocks with bad block table (and mirror) at the end */
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+	.mask_chipsel		= BIT(14),
+	.parts			= davinci_nand_partitions,
+	.nr_parts		= ARRAY_SIZE(davinci_nand_partitions),
+	.ecc_mode		= NAND_ECC_HW,
+	.options		= NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_nand_resources[] = {
+	{
+		.start		= DM365_ASYNC_EMIF_DATA_CE0_BASE,
+		.end		= DM365_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+		.flags		= IORESOURCE_MEM,
+	}, {
+		.start		= DM365_ASYNC_EMIF_CONTROL_BASE,
+		.end		= DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device davinci_nand_device = {
+	.name			= "davinci_nand",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(davinci_nand_resources),
+	.resource		= davinci_nand_resources,
+	.dev			= {
+		.platform_data	= &davinci_nand_data,
+	},
+};
+
+static struct at24_platform_data eeprom_info = {
+	.byte_len       = (256*1024) / 8,
+	.page_size      = 64,
+	.flags          = AT24_FLAG_ADDR16,
+	.setup          = davinci_get_mac_addr,
+	.context	= (void *)0x7f00,
+};
+
+static struct i2c_board_info i2c_info[] = {
+	{
+		I2C_BOARD_INFO("24c256", 0x50),
+		.platform_data	= &eeprom_info,
+	},
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+	.bus_freq	= 400	/* kHz */,
+	.bus_delay	= 0	/* usec */,
+};
+
+static int cpld_mmc_get_cd(int module)
+{
+	if (!cpld)
+		return -ENXIO;
+
+	/* low == card present */
+	return !(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 4 : 0));
+}
+
+static int cpld_mmc_get_ro(int module)
+{
+	if (!cpld)
+		return -ENXIO;
+
+	/* high == card's write protect switch active */
+	return !!(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 5 : 1));
+}
+
+static struct davinci_mmc_config dm365evm_mmc_config = {
+	.get_cd		= cpld_mmc_get_cd,
+	.get_ro		= cpld_mmc_get_ro,
+	.wires		= 4,
+	.max_freq	= 50000000,
+	.caps		= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+	.version	= MMC_CTLR_VERSION_2,
+};
+
+static void dm365evm_emac_configure(void)
+{
+	/*
+	 * EMAC pins are multiplexed with GPIO and UART
+	 * Further details are available at the DM365 ARM
+	 * Subsystem Users Guide(sprufg5.pdf) pages 125 - 127
+	 */
+	davinci_cfg_reg(DM365_EMAC_TX_EN);
+	davinci_cfg_reg(DM365_EMAC_TX_CLK);
+	davinci_cfg_reg(DM365_EMAC_COL);
+	davinci_cfg_reg(DM365_EMAC_TXD3);
+	davinci_cfg_reg(DM365_EMAC_TXD2);
+	davinci_cfg_reg(DM365_EMAC_TXD1);
+	davinci_cfg_reg(DM365_EMAC_TXD0);
+	davinci_cfg_reg(DM365_EMAC_RXD3);
+	davinci_cfg_reg(DM365_EMAC_RXD2);
+	davinci_cfg_reg(DM365_EMAC_RXD1);
+	davinci_cfg_reg(DM365_EMAC_RXD0);
+	davinci_cfg_reg(DM365_EMAC_RX_CLK);
+	davinci_cfg_reg(DM365_EMAC_RX_DV);
+	davinci_cfg_reg(DM365_EMAC_RX_ER);
+	davinci_cfg_reg(DM365_EMAC_CRS);
+	davinci_cfg_reg(DM365_EMAC_MDIO);
+	davinci_cfg_reg(DM365_EMAC_MDCLK);
+
+	/*
+	 * EMAC interrupts are multiplexed with GPIO interrupts
+	 * Details are available at the DM365 ARM
+	 * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134
+	 */
+	davinci_cfg_reg(DM365_INT_EMAC_RXTHRESH);
+	davinci_cfg_reg(DM365_INT_EMAC_RXPULSE);
+	davinci_cfg_reg(DM365_INT_EMAC_TXPULSE);
+	davinci_cfg_reg(DM365_INT_EMAC_MISCPULSE);
+}
+
+static void dm365evm_mmc_configure(void)
+{
+	/*
+	 * MMC/SD pins are multiplexed with GPIO and EMIF
+	 * Further details are available at the DM365 ARM
+	 * Subsystem Users Guide(sprufg5.pdf) pages 118, 128 - 131
+	 */
+	davinci_cfg_reg(DM365_SD1_CLK);
+	davinci_cfg_reg(DM365_SD1_CMD);
+	davinci_cfg_reg(DM365_SD1_DATA3);
+	davinci_cfg_reg(DM365_SD1_DATA2);
+	davinci_cfg_reg(DM365_SD1_DATA1);
+	davinci_cfg_reg(DM365_SD1_DATA0);
+}
+
+static void __init evm_init_i2c(void)
+{
+	davinci_init_i2c(&i2c_pdata);
+	i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *dm365_evm_nand_devices[] __initdata = {
+	&davinci_nand_device,
+};
+
+static inline int have_leds(void)
+{
+#ifdef CONFIG_LEDS_CLASS
+	return 1;
+#else
+	return 0;
+#endif
+}
+
+struct cpld_led {
+	struct led_classdev	cdev;
+	u8			mask;
+};
+
+static const struct {
+	const char *name;
+	const char *trigger;
+} cpld_leds[] = {
+	{ "dm365evm::ds2", },
+	{ "dm365evm::ds3", },
+	{ "dm365evm::ds4", },
+	{ "dm365evm::ds5", },
+	{ "dm365evm::ds6", "nand-disk", },
+	{ "dm365evm::ds7", "mmc1", },
+	{ "dm365evm::ds8", "mmc0", },
+	{ "dm365evm::ds9", "heartbeat", },
+};
+
+static void cpld_led_set(struct led_classdev *cdev, enum led_brightness b)
+{
+	struct cpld_led *led = container_of(cdev, struct cpld_led, cdev);
+	u8 reg = __raw_readb(cpld + CPLD_LEDS);
+
+	if (b != LED_OFF)
+		reg &= ~led->mask;
+	else
+		reg |= led->mask;
+	__raw_writeb(reg, cpld + CPLD_LEDS);
+}
+
+static enum led_brightness cpld_led_get(struct led_classdev *cdev)
+{
+	struct cpld_led *led = container_of(cdev, struct cpld_led, cdev);
+	u8 reg = __raw_readb(cpld + CPLD_LEDS);
+
+	return (reg & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init cpld_leds_init(void)
+{
+	int	i;
+
+	if (!have_leds() ||  !cpld)
+		return 0;
+
+	/* setup LEDs */
+	__raw_writeb(0xff, cpld + CPLD_LEDS);
+	for (i = 0; i < ARRAY_SIZE(cpld_leds); i++) {
+		struct cpld_led *led;
+
+		led = kzalloc(sizeof(*led), GFP_KERNEL);
+		if (!led)
+			break;
+
+		led->cdev.name = cpld_leds[i].name;
+		led->cdev.brightness_set = cpld_led_set;
+		led->cdev.brightness_get = cpld_led_get;
+		led->cdev.default_trigger = cpld_leds[i].trigger;
+		led->mask = BIT(i);
+
+		if (led_classdev_register(NULL, &led->cdev) < 0) {
+			kfree(led);
+			break;
+		}
+	}
+
+	return 0;
+}
+/* run after subsys_initcall() for LEDs */
+fs_initcall(cpld_leds_init);
+
+
+static void __init evm_init_cpld(void)
+{
+	u8 mux, resets;
+	const char *label;
+	struct clk *aemif_clk;
+
+	/* Make sure we can configure the CPLD through CS1.  Then
+	 * leave it on for later access to MMC and LED registers.
+	 */
+	aemif_clk = clk_get(NULL, "aemif");
+	if (IS_ERR(aemif_clk))
+		return;
+	clk_enable(aemif_clk);
+
+	if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE,
+			"cpld") == NULL)
+		goto fail;
+	cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE);
+	if (!cpld) {
+		release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE,
+				SECTION_SIZE);
+fail:
+		pr_err("ERROR: can't map CPLD\n");
+		clk_disable(aemif_clk);
+		return;
+	}
+
+	/* External muxing for some signals */
+	mux = 0;
+
+	/* Read SW5 to set up NAND + keypad _or_ OneNAND (sync read).
+	 * NOTE:  SW4 bus width setting must match!
+	 */
+	if ((__raw_readb(cpld + CPLD_SWITCH) & BIT(5)) == 0) {
+		/* external keypad mux */
+		mux |= BIT(7);
+
+		platform_add_devices(dm365_evm_nand_devices,
+				ARRAY_SIZE(dm365_evm_nand_devices));
+	} else {
+		/* no OneNAND support yet */
+	}
+
+	/* Leave external chips in reset when unused. */
+	resets = BIT(3) | BIT(2) | BIT(1) | BIT(0);
+
+	/* Static video input config with SN74CBT16214 1-of-3 mux:
+	 *  - port b1 == tvp7002 (mux lowbits == 1 or 6)
+	 *  - port b2 == imager (mux lowbits == 2 or 7)
+	 *  - port b3 == tvp5146 (mux lowbits == 5)
+	 *
+	 * Runtime switching could work too, with limitations.
+	 */
+	if (have_imager()) {
+		label = "HD imager";
+		mux |= 1;
+
+		/* externally mux MMC1/ENET/AIC33 to imager */
+		mux |= BIT(6) | BIT(5) | BIT(3);
+	} else {
+		struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+		/* we can use MMC1 ... */
+		dm365evm_mmc_configure();
+		davinci_setup_mmc(1, &dm365evm_mmc_config);
+
+		/* ... and ENET ... */
+		dm365evm_emac_configure();
+		soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK;
+		soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY;
+		resets &= ~BIT(3);
+
+		/* ... and AIC33 */
+		resets &= ~BIT(1);
+
+		if (have_tvp7002()) {
+			mux |= 2;
+			resets &= ~BIT(2);
+			label = "tvp7002 HD";
+		} else {
+			/* default to tvp5146 */
+			mux |= 5;
+			resets &= ~BIT(0);
+			label = "tvp5146 SD";
+		}
+	}
+	__raw_writeb(mux, cpld + CPLD_MUX);
+	__raw_writeb(resets, cpld + CPLD_RESETS);
+	pr_info("EVM: %s video input\n", label);
+
+	/* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */
+}
+
+static struct davinci_uart_config uart_config __initdata = {
+	.enabled_uarts = (1 << 0),
+};
+
+static void __init dm365_evm_map_io(void)
+{
+	dm365_init();
+}
+
+static __init void dm365_evm_init(void)
+{
+	evm_init_i2c();
+	davinci_serial_init(&uart_config);
+
+	dm365evm_emac_configure();
+	dm365evm_mmc_configure();
+
+	davinci_setup_mmc(0, &dm365evm_mmc_config);
+
+	/* maybe setup mmc1/etc ... _after_ mmc0 */
+	evm_init_cpld();
+}
+
+static __init void dm365_evm_irq_init(void)
+{
+	davinci_irq_init();
+}
+
+MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
+	.phys_io	= IO_PHYS,
+	.io_pg_offst	= (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
+	.boot_params	= (0x80000100),
+	.map_io		= dm365_evm_map_io,
+	.init_irq	= dm365_evm_irq_init,
+	.timer		= &davinci_timer,
+	.init_machine	= dm365_evm_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
index 56c8cd0..1213a00 100644
--- a/arch/arm/mach-davinci/board-dm644x-evm.c
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -28,6 +28,9 @@
 #include <linux/io.h>
 #include <linux/phy.h>
 #include <linux/clk.h>
+#include <linux/videodev2.h>
+
+#include <media/tvp514x.h>
 
 #include <asm/setup.h>
 #include <asm/mach-types.h>
@@ -194,6 +197,72 @@ static struct platform_device davinci_fb_device = {
 	.num_resources = 0,
 };
 
+static struct tvp514x_platform_data tvp5146_pdata = {
+	.clk_polarity = 0,
+	.hs_polarity = 1,
+	.vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL	(V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+	{
+		.index = 0,
+		.name = "Composite",
+		.type = V4L2_INPUT_TYPE_CAMERA,
+		.std = TVP514X_STD_ALL,
+	},
+	{
+		.index = 1,
+		.name = "S-Video",
+		.type = V4L2_INPUT_TYPE_CAMERA,
+		.std = TVP514X_STD_ALL,
+	},
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+	{
+		.input = INPUT_CVBS_VI2B,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+	},
+	{
+		.input = INPUT_SVIDEO_VI2C_VI1C,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+	},
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+	{
+		.name = "tvp5146",
+		.grp_id = 0,
+		.num_inputs = ARRAY_SIZE(tvp5146_inputs),
+		.inputs = tvp5146_inputs,
+		.routes = tvp5146_routes,
+		.can_route = 1,
+		.ccdc_if_params = {
+			.if_type = VPFE_BT656,
+			.hdpol = VPFE_PINPOL_POSITIVE,
+			.vdpol = VPFE_PINPOL_POSITIVE,
+		},
+		.board_info = {
+			I2C_BOARD_INFO("tvp5146", 0x5d),
+			.platform_data = &tvp5146_pdata,
+		},
+	},
+};
+
+static struct vpfe_config vpfe_cfg = {
+	.num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+	.sub_devs = vpfe_sub_devs,
+	.card_name = "DM6446 EVM",
+	.ccdc = "DM6446 CCDC",
+};
+
 static struct platform_device rtc_dev = {
 	.name           = "rtc_davinci_evm",
 	.id             = -1,
@@ -225,6 +294,8 @@ static struct platform_device ide_dev = {
 	},
 };
 
+static struct snd_platform_data dm644x_evm_snd_data;
+
 /*----------------------------------------------------------------------*/
 
 /*
@@ -557,10 +628,9 @@ static struct i2c_board_info __initdata i2c_info[] =  {
 		I2C_BOARD_INFO("24c256", 0x50),
 		.platform_data	= &eeprom_info,
 	},
-	/* ALSO:
-	 * - tvl320aic33 audio codec (0x1b)
-	 * - tvp5146 video decoder (0x5d)
-	 */
+	{
+		I2C_BOARD_INFO("tlv320aic33", 0x1b),
+	},
 };
 
 /* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
@@ -590,6 +660,8 @@ static struct davinci_uart_config uart_config __initdata = {
 static void __init
 davinci_evm_map_io(void)
 {
+	/* setup input configuration for VPFE input devices */
+	dm644x_set_vpfe_config(&vpfe_cfg);
 	dm644x_init();
 }
 
@@ -666,6 +738,7 @@ static __init void davinci_evm_init(void)
 	davinci_setup_mmc(0, &dm6446evm_mmc_config);
 
 	davinci_serial_init(&uart_config);
+	dm644x_init_asp(&dm644x_evm_snd_data);
 
 	soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK;
 	soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY;
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index 8657e72..24e0e13 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -34,6 +34,8 @@
 #include <linux/i2c/pcf857x.h>
 #include <linux/etherdevice.h>
 
+#include <media/tvp514x.h>
+
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -48,13 +50,89 @@
 #include <mach/mmc.h>
 #include <mach/emac.h>
 
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+    defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+/* CPLD Register 0 bits to control ATA */
+#define DM646X_EVM_ATA_RST		BIT(0)
+#define DM646X_EVM_ATA_PWD		BIT(1)
+
 #define DM646X_EVM_PHY_MASK		(0x2)
 #define DM646X_EVM_MDIO_FREQUENCY	(2200000) /* PHY bus frequency */
 
+#define VIDCLKCTL_OFFSET	(DAVINCI_SYSTEM_MODULE_BASE + 0x38)
+#define VSCLKDIS_OFFSET		(DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
+#define VCH2CLK_MASK		(BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8))
+#define VCH2CLK_SYSCLK8		(BIT(9))
+#define VCH2CLK_AUXCLK		(BIT(9) | BIT(8))
+#define VCH3CLK_MASK		(BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12))
+#define VCH3CLK_SYSCLK8		(BIT(13))
+#define VCH3CLK_AUXCLK		(BIT(14) | BIT(13))
+
+#define VIDCH2CLK		(BIT(10))
+#define VIDCH3CLK		(BIT(11))
+#define VIDCH1CLK		(BIT(4))
+#define TVP7002_INPUT		(BIT(4))
+#define TVP5147_INPUT		(~BIT(4))
+#define VPIF_INPUT_ONE_CHANNEL	(BIT(5))
+#define VPIF_INPUT_TWO_CHANNEL	(~BIT(5))
+#define TVP5147_CH0		"tvp514x-0"
+#define TVP5147_CH1		"tvp514x-1"
+
+static void __iomem *vpif_vidclkctl_reg;
+static void __iomem *vpif_vsclkdis_reg;
+/* spin lock for updating above registers */
+static spinlock_t vpif_reg_lock;
+
 static struct davinci_uart_config uart_config __initdata = {
 	.enabled_uarts = (1 << 0),
 };
 
+/* CPLD Register 0 Client: used for I/O Control */
+static int cpld_reg0_probe(struct i2c_client *client,
+			   const struct i2c_device_id *id)
+{
+	if (HAS_ATA) {
+		u8 data;
+		struct i2c_msg msg[2] = {
+			{
+				.addr = client->addr,
+				.flags = I2C_M_RD,
+				.len = 1,
+				.buf = &data,
+			},
+			{
+				.addr = client->addr,
+				.flags = 0,
+				.len = 1,
+				.buf = &data,
+			},
+		};
+
+		/* Clear ATA_RSTn and ATA_PWD bits to enable ATA operation. */
+		i2c_transfer(client->adapter, msg, 1);
+		data &= ~(DM646X_EVM_ATA_RST | DM646X_EVM_ATA_PWD);
+		i2c_transfer(client->adapter, msg + 1, 1);
+	}
+
+	return 0;
+}
+
+static const struct i2c_device_id cpld_reg_ids[] = {
+	{ "cpld_reg0", 0, },
+	{ },
+};
+
+static struct i2c_driver dm6467evm_cpld_driver = {
+	.driver.name	= "cpld_reg0",
+	.id_table	= cpld_reg_ids,
+	.probe		= cpld_reg0_probe,
+};
+
 /* LEDS */
 
 static struct gpio_led evm_leds[] = {
@@ -206,6 +284,69 @@ static struct at24_platform_data eeprom_info = {
 	.context	= (void *)0x7f00,
 };
 
+static u8 dm646x_iis_serializer_direction[] = {
+       TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static u8 dm646x_dit_serializer_direction[] = {
+       TX_MODE,
+};
+
+static struct snd_platform_data dm646x_evm_snd_data[] = {
+	{
+		.tx_dma_offset  = 0x400,
+		.rx_dma_offset  = 0x400,
+		.op_mode        = DAVINCI_MCASP_IIS_MODE,
+		.num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction),
+		.tdm_slots      = 2,
+		.serial_dir     = dm646x_iis_serializer_direction,
+		.eventq_no      = EVENTQ_0,
+	},
+	{
+		.tx_dma_offset  = 0x400,
+		.rx_dma_offset  = 0,
+		.op_mode        = DAVINCI_MCASP_DIT_MODE,
+		.num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction),
+		.tdm_slots      = 32,
+		.serial_dir     = dm646x_dit_serializer_direction,
+		.eventq_no      = EVENTQ_0,
+	},
+};
+
+static struct i2c_client *cpld_client;
+
+static int cpld_video_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	cpld_client = client;
+	return 0;
+}
+
+static int __devexit cpld_video_remove(struct i2c_client *client)
+{
+	cpld_client = NULL;
+	return 0;
+}
+
+static const struct i2c_device_id cpld_video_id[] = {
+	{ "cpld_video", 0 },
+	{ }
+};
+
+static struct i2c_driver cpld_video_driver = {
+	.driver = {
+		.name	= "cpld_video",
+	},
+	.probe		= cpld_video_probe,
+	.remove		= cpld_video_remove,
+	.id_table	= cpld_video_id,
+};
+
+static void evm_init_cpld(void)
+{
+	i2c_add_driver(&cpld_video_driver);
+}
+
 static struct i2c_board_info __initdata i2c_info[] =  {
 	{
 		I2C_BOARD_INFO("24c256", 0x50),
@@ -215,6 +356,15 @@ static struct i2c_board_info __initdata i2c_info[] =  {
 		I2C_BOARD_INFO("pcf8574a", 0x38),
 		.platform_data	= &pcf_data,
 	},
+	{
+		I2C_BOARD_INFO("cpld_reg0", 0x3a),
+	},
+	{
+		I2C_BOARD_INFO("tlv320aic33", 0x18),
+	},
+	{
+		I2C_BOARD_INFO("cpld_video", 0x3b),
+	},
 };
 
 static struct davinci_i2c_platform_data i2c_pdata = {
@@ -222,10 +372,265 @@ static struct davinci_i2c_platform_data i2c_pdata = {
 	.bus_delay      = 0 /* usec */,
 };
 
+static int set_vpif_clock(int mux_mode, int hd)
+{
+	unsigned long flags;
+	unsigned int value;
+	int val = 0;
+	int err = 0;
+
+	if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg || !cpld_client)
+		return -ENXIO;
+
+	/* disable the clock */
+	spin_lock_irqsave(&vpif_reg_lock, flags);
+	value = __raw_readl(vpif_vsclkdis_reg);
+	value |= (VIDCH3CLK | VIDCH2CLK);
+	__raw_writel(value, vpif_vsclkdis_reg);
+	spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+	val = i2c_smbus_read_byte(cpld_client);
+	if (val < 0)
+		return val;
+
+	if (mux_mode == 1)
+		val &= ~0x40;
+	else
+		val |= 0x40;
+
+	err = i2c_smbus_write_byte(cpld_client, val);
+	if (err)
+		return err;
+
+	value = __raw_readl(vpif_vidclkctl_reg);
+	value &= ~(VCH2CLK_MASK);
+	value &= ~(VCH3CLK_MASK);
+
+	if (hd >= 1)
+		value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8);
+	else
+		value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK);
+
+	__raw_writel(value, vpif_vidclkctl_reg);
+
+	spin_lock_irqsave(&vpif_reg_lock, flags);
+	value = __raw_readl(vpif_vsclkdis_reg);
+	/* enable the clock */
+	value &= ~(VIDCH3CLK | VIDCH2CLK);
+	__raw_writel(value, vpif_vsclkdis_reg);
+	spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+	return 0;
+}
+
+static struct vpif_subdev_info dm646x_vpif_subdev[] = {
+	{
+		.name	= "adv7343",
+		.board_info = {
+			I2C_BOARD_INFO("adv7343", 0x2a),
+		},
+	},
+	{
+		.name	= "ths7303",
+		.board_info = {
+			I2C_BOARD_INFO("ths7303", 0x2c),
+		},
+	},
+};
+
+static const char *output[] = {
+	"Composite",
+	"Component",
+	"S-Video",
+};
+
+static struct vpif_display_config dm646x_vpif_display_config = {
+	.set_clock	= set_vpif_clock,
+	.subdevinfo	= dm646x_vpif_subdev,
+	.subdev_count	= ARRAY_SIZE(dm646x_vpif_subdev),
+	.output		= output,
+	.output_count	= ARRAY_SIZE(output),
+	.card_name	= "DM646x EVM",
+};
+
+/**
+ * setup_vpif_input_path()
+ * @channel: channel id (0 - CH0, 1 - CH1)
+ * @sub_dev_name: ptr sub device name
+ *
+ * This will set vpif input to capture data from tvp514x or
+ * tvp7002.
+ */
+static int setup_vpif_input_path(int channel, const char *sub_dev_name)
+{
+	int err = 0;
+	int val;
+
+	/* for channel 1, we don't do anything */
+	if (channel != 0)
+		return 0;
+
+	if (!cpld_client)
+		return -ENXIO;
+
+	val = i2c_smbus_read_byte(cpld_client);
+	if (val < 0)
+		return val;
+
+	if (!strcmp(sub_dev_name, TVP5147_CH0) ||
+	    !strcmp(sub_dev_name, TVP5147_CH1))
+		val &= TVP5147_INPUT;
+	else
+		val |= TVP7002_INPUT;
+
+	err = i2c_smbus_write_byte(cpld_client, val);
+	if (err)
+		return err;
+	return 0;
+}
+
+/**
+ * setup_vpif_input_channel_mode()
+ * @mux_mode:  mux mode. 0 - 1 channel or (1) - 2 channel
+ *
+ * This will setup input mode to one channel (TVP7002) or 2 channel (TVP5147)
+ */
+static int setup_vpif_input_channel_mode(int mux_mode)
+{
+	unsigned long flags;
+	int err = 0;
+	int val;
+	u32 value;
+
+	if (!vpif_vsclkdis_reg || !cpld_client)
+		return -ENXIO;
+
+	val = i2c_smbus_read_byte(cpld_client);
+	if (val < 0)
+		return val;
+
+	spin_lock_irqsave(&vpif_reg_lock, flags);
+	value = __raw_readl(vpif_vsclkdis_reg);
+	if (mux_mode) {
+		val &= VPIF_INPUT_TWO_CHANNEL;
+		value |= VIDCH1CLK;
+	} else {
+		val |= VPIF_INPUT_ONE_CHANNEL;
+		value &= ~VIDCH1CLK;
+	}
+	__raw_writel(value, vpif_vsclkdis_reg);
+	spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+	err = i2c_smbus_write_byte(cpld_client, val);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+	.clk_polarity = 0,
+	.hs_polarity = 1,
+	.vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+static struct vpif_subdev_info vpif_capture_sdev_info[] = {
+	{
+		.name	= TVP5147_CH0,
+		.board_info = {
+			I2C_BOARD_INFO("tvp5146", 0x5d),
+			.platform_data = &tvp5146_pdata,
+		},
+		.input = INPUT_CVBS_VI2B,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+		.can_route = 1,
+		.vpif_if = {
+			.if_type = VPIF_IF_BT656,
+			.hd_pol = 1,
+			.vd_pol = 1,
+			.fid_pol = 0,
+		},
+	},
+	{
+		.name	= TVP5147_CH1,
+		.board_info = {
+			I2C_BOARD_INFO("tvp5146", 0x5c),
+			.platform_data = &tvp5146_pdata,
+		},
+		.input = INPUT_SVIDEO_VI2C_VI1C,
+		.output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+		.can_route = 1,
+		.vpif_if = {
+			.if_type = VPIF_IF_BT656,
+			.hd_pol = 1,
+			.vd_pol = 1,
+			.fid_pol = 0,
+		},
+	},
+};
+
+static const struct vpif_input dm6467_ch0_inputs[] = {
+	{
+		.input = {
+			.index = 0,
+			.name = "Composite",
+			.type = V4L2_INPUT_TYPE_CAMERA,
+			.std = TVP514X_STD_ALL,
+		},
+		.subdev_name = TVP5147_CH0,
+	},
+};
+
+static const struct vpif_input dm6467_ch1_inputs[] = {
+       {
+		.input = {
+			.index = 0,
+			.name = "S-Video",
+			.type = V4L2_INPUT_TYPE_CAMERA,
+			.std = TVP514X_STD_ALL,
+		},
+		.subdev_name = TVP5147_CH1,
+	},
+};
+
+static struct vpif_capture_config dm646x_vpif_capture_cfg = {
+	.setup_input_path = setup_vpif_input_path,
+	.setup_input_channel_mode = setup_vpif_input_channel_mode,
+	.subdev_info = vpif_capture_sdev_info,
+	.subdev_count = ARRAY_SIZE(vpif_capture_sdev_info),
+	.chan_config[0] = {
+		.inputs = dm6467_ch0_inputs,
+		.input_count = ARRAY_SIZE(dm6467_ch0_inputs),
+	},
+	.chan_config[1] = {
+		.inputs = dm6467_ch1_inputs,
+		.input_count = ARRAY_SIZE(dm6467_ch1_inputs),
+	},
+};
+
+static void __init evm_init_video(void)
+{
+	vpif_vidclkctl_reg = ioremap(VIDCLKCTL_OFFSET, 4);
+	vpif_vsclkdis_reg = ioremap(VSCLKDIS_OFFSET, 4);
+	if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg) {
+		pr_err("Can't map VPIF VIDCLKCTL or VSCLKDIS registers\n");
+		return;
+	}
+	spin_lock_init(&vpif_reg_lock);
+
+	dm646x_setup_vpif(&dm646x_vpif_display_config,
+			  &dm646x_vpif_capture_cfg);
+}
+
 static void __init evm_init_i2c(void)
 {
 	davinci_init_i2c(&i2c_pdata);
+	i2c_add_driver(&dm6467evm_cpld_driver);
 	i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+	evm_init_cpld();
+	evm_init_video();
 }
 
 static void __init davinci_map_io(void)
@@ -239,6 +644,11 @@ static __init void evm_init(void)
 
 	evm_init_i2c();
 	davinci_serial_init(&uart_config);
+	dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
+	dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
+
+	if (HAS_ATA)
+		dm646x_init_ide();
 
 	soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK;
 	soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY;
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
index 39bf321..83d54d5 100644
--- a/arch/arm/mach-davinci/clock.c
+++ b/arch/arm/mach-davinci/clock.c
@@ -227,7 +227,10 @@ static void __init clk_pll_init(struct clk *clk)
 	if (ctrl & PLLCTL_PLLEN) {
 		bypass = 0;
 		mult = __raw_readl(pll->base + PLLM);
-		mult = (mult & PLLM_PLLM_MASK) + 1;
+		if (cpu_is_davinci_dm365())
+			mult = 2 * (mult & PLLM_PLLM_MASK);
+		else
+			mult = (mult & PLLM_PLLM_MASK) + 1;
 	} else
 		bypass = 1;
 
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
new file mode 100644
index 0000000..19b2748
--- /dev/null
+++ b/arch/arm/mach-davinci/da830.c
@@ -0,0 +1,1205 @@
+/*
+ * TI DA830/OMAP L137 chip specific setup
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/clock.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/asp.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* Offsets of the 8 compare registers on the da830 */
+#define DA830_CMP12_0		0x60
+#define DA830_CMP12_1		0x64
+#define DA830_CMP12_2		0x68
+#define DA830_CMP12_3		0x6c
+#define DA830_CMP12_4		0x70
+#define DA830_CMP12_5		0x74
+#define DA830_CMP12_6		0x78
+#define DA830_CMP12_7		0x7c
+
+#define DA830_REF_FREQ		24000000
+
+static struct pll_data pll0_data = {
+	.num		= 1,
+	.phys_base	= DA8XX_PLL0_BASE,
+	.flags		= PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct clk ref_clk = {
+	.name		= "ref_clk",
+	.rate		= DA830_REF_FREQ,
+};
+
+static struct clk pll0_clk = {
+	.name		= "pll0",
+	.parent		= &ref_clk,
+	.pll_data	= &pll0_data,
+	.flags		= CLK_PLL,
+};
+
+static struct clk pll0_aux_clk = {
+	.name		= "pll0_aux_clk",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll0_sysclk2 = {
+	.name		= "pll0_sysclk2",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV2,
+};
+
+static struct clk pll0_sysclk3 = {
+	.name		= "pll0_sysclk3",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV3,
+};
+
+static struct clk pll0_sysclk4 = {
+	.name		= "pll0_sysclk4",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV4,
+};
+
+static struct clk pll0_sysclk5 = {
+	.name		= "pll0_sysclk5",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV5,
+};
+
+static struct clk pll0_sysclk6 = {
+	.name		= "pll0_sysclk6",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV6,
+};
+
+static struct clk pll0_sysclk7 = {
+	.name		= "pll0_sysclk7",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV7,
+};
+
+static struct clk i2c0_clk = {
+	.name		= "i2c0",
+	.parent		= &pll0_aux_clk,
+};
+
+static struct clk timerp64_0_clk = {
+	.name		= "timer0",
+	.parent		= &pll0_aux_clk,
+};
+
+static struct clk timerp64_1_clk = {
+	.name		= "timer1",
+	.parent		= &pll0_aux_clk,
+};
+
+static struct clk arm_rom_clk = {
+	.name		= "arm_rom",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_ARM_RAM_ROM,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk scr0_ss_clk = {
+	.name		= "scr0_ss",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_SCR0_SS,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk scr1_ss_clk = {
+	.name		= "scr1_ss",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_SCR1_SS,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk scr2_ss_clk = {
+	.name		= "scr2_ss",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_SCR2_SS,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk dmax_clk = {
+	.name		= "dmax",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_DMAX,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk tpcc_clk = {
+	.name		= "tpcc",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_TPCC,
+	.flags		= ALWAYS_ENABLED | CLK_PSC,
+};
+
+static struct clk tptc0_clk = {
+	.name		= "tptc0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_TPTC0,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk tptc1_clk = {
+	.name		= "tptc1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_TPTC1,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk mmcsd_clk = {
+	.name		= "mmcsd",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_MMC_SD,
+};
+
+static struct clk uart0_clk = {
+	.name		= "uart0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_UART0,
+};
+
+static struct clk uart1_clk = {
+	.name		= "uart1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_UART1,
+	.psc_ctlr	= 1,
+};
+
+static struct clk uart2_clk = {
+	.name		= "uart2",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_UART2,
+	.psc_ctlr	= 1,
+};
+
+static struct clk spi0_clk = {
+	.name		= "spi0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_SPI0,
+};
+
+static struct clk spi1_clk = {
+	.name		= "spi1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_SPI1,
+	.psc_ctlr	= 1,
+};
+
+static struct clk ecap0_clk = {
+	.name		= "ecap0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_ECAP,
+	.psc_ctlr	= 1,
+};
+
+static struct clk ecap1_clk = {
+	.name		= "ecap1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_ECAP,
+	.psc_ctlr	= 1,
+};
+
+static struct clk ecap2_clk = {
+	.name		= "ecap2",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_ECAP,
+	.psc_ctlr	= 1,
+};
+
+static struct clk pwm0_clk = {
+	.name		= "pwm0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_PWM,
+	.psc_ctlr	= 1,
+};
+
+static struct clk pwm1_clk = {
+	.name		= "pwm1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_PWM,
+	.psc_ctlr	= 1,
+};
+
+static struct clk pwm2_clk = {
+	.name		= "pwm2",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_PWM,
+	.psc_ctlr	= 1,
+};
+
+static struct clk eqep0_clk = {
+	.name		= "eqep0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA830_LPSC1_EQEP,
+	.psc_ctlr	= 1,
+};
+
+static struct clk eqep1_clk = {
+	.name		= "eqep1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA830_LPSC1_EQEP,
+	.psc_ctlr	= 1,
+};
+
+static struct clk lcdc_clk = {
+	.name		= "lcdc",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_LCDC,
+	.psc_ctlr	= 1,
+};
+
+static struct clk mcasp0_clk = {
+	.name		= "mcasp0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_McASP0,
+	.psc_ctlr	= 1,
+};
+
+static struct clk mcasp1_clk = {
+	.name		= "mcasp1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA830_LPSC1_McASP1,
+	.psc_ctlr	= 1,
+};
+
+static struct clk mcasp2_clk = {
+	.name		= "mcasp2",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA830_LPSC1_McASP2,
+	.psc_ctlr	= 1,
+};
+
+static struct clk usb20_clk = {
+	.name		= "usb20",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_USB20,
+	.psc_ctlr	= 1,
+};
+
+static struct clk aemif_clk = {
+	.name		= "aemif",
+	.parent		= &pll0_sysclk3,
+	.lpsc		= DA8XX_LPSC0_EMIF25,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk aintc_clk = {
+	.name		= "aintc",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC0_AINTC,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk secu_mgr_clk = {
+	.name		= "secu_mgr",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC0_SECU_MGR,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk emac_clk = {
+	.name		= "emac",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC1_CPGMAC,
+	.psc_ctlr	= 1,
+};
+
+static struct clk gpio_clk = {
+	.name		= "gpio",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC1_GPIO,
+	.psc_ctlr	= 1,
+};
+
+static struct clk i2c1_clk = {
+	.name		= "i2c1",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC1_I2C,
+	.psc_ctlr	= 1,
+};
+
+static struct clk usb11_clk = {
+	.name		= "usb11",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC1_USB11,
+	.psc_ctlr	= 1,
+};
+
+static struct clk emif3_clk = {
+	.name		= "emif3",
+	.parent		= &pll0_sysclk5,
+	.lpsc		= DA8XX_LPSC1_EMIF3C,
+	.flags		= ALWAYS_ENABLED,
+	.psc_ctlr	= 1,
+};
+
+static struct clk arm_clk = {
+	.name		= "arm",
+	.parent		= &pll0_sysclk6,
+	.lpsc		= DA8XX_LPSC0_ARM,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk rmii_clk = {
+	.name		= "rmii",
+	.parent		= &pll0_sysclk7,
+};
+
+static struct davinci_clk da830_clks[] = {
+	CLK(NULL,		"ref",		&ref_clk),
+	CLK(NULL,		"pll0",		&pll0_clk),
+	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
+	CLK(NULL,		"pll0_sysclk2",	&pll0_sysclk2),
+	CLK(NULL,		"pll0_sysclk3",	&pll0_sysclk3),
+	CLK(NULL,		"pll0_sysclk4",	&pll0_sysclk4),
+	CLK(NULL,		"pll0_sysclk5",	&pll0_sysclk5),
+	CLK(NULL,		"pll0_sysclk6",	&pll0_sysclk6),
+	CLK(NULL,		"pll0_sysclk7",	&pll0_sysclk7),
+	CLK("i2c_davinci.1",	NULL,		&i2c0_clk),
+	CLK(NULL,		"timer0",	&timerp64_0_clk),
+	CLK("watchdog",		NULL,		&timerp64_1_clk),
+	CLK(NULL,		"arm_rom",	&arm_rom_clk),
+	CLK(NULL,		"scr0_ss",	&scr0_ss_clk),
+	CLK(NULL,		"scr1_ss",	&scr1_ss_clk),
+	CLK(NULL,		"scr2_ss",	&scr2_ss_clk),
+	CLK(NULL,		"dmax",		&dmax_clk),
+	CLK(NULL,		"tpcc",		&tpcc_clk),
+	CLK(NULL,		"tptc0",	&tptc0_clk),
+	CLK(NULL,		"tptc1",	&tptc1_clk),
+	CLK("davinci_mmc.0",	NULL,		&mmcsd_clk),
+	CLK(NULL,		"uart0",	&uart0_clk),
+	CLK(NULL,		"uart1",	&uart1_clk),
+	CLK(NULL,		"uart2",	&uart2_clk),
+	CLK("dm_spi.0",		NULL,		&spi0_clk),
+	CLK("dm_spi.1",		NULL,		&spi1_clk),
+	CLK(NULL,		"ecap0",	&ecap0_clk),
+	CLK(NULL,		"ecap1",	&ecap1_clk),
+	CLK(NULL,		"ecap2",	&ecap2_clk),
+	CLK(NULL,		"pwm0",		&pwm0_clk),
+	CLK(NULL,		"pwm1",		&pwm1_clk),
+	CLK(NULL,		"pwm2",		&pwm2_clk),
+	CLK("eqep.0",		NULL,		&eqep0_clk),
+	CLK("eqep.1",		NULL,		&eqep1_clk),
+	CLK("da830_lcdc",	NULL,		&lcdc_clk),
+	CLK("davinci-mcasp.0",	NULL,		&mcasp0_clk),
+	CLK("davinci-mcasp.1",	NULL,		&mcasp1_clk),
+	CLK("davinci-mcasp.2",	NULL,		&mcasp2_clk),
+	CLK("musb_hdrc",	NULL,		&usb20_clk),
+	CLK(NULL,		"aemif",	&aemif_clk),
+	CLK(NULL,		"aintc",	&aintc_clk),
+	CLK(NULL,		"secu_mgr",	&secu_mgr_clk),
+	CLK("davinci_emac.1",	NULL,		&emac_clk),
+	CLK(NULL,		"gpio",		&gpio_clk),
+	CLK("i2c_davinci.2",	NULL,		&i2c1_clk),
+	CLK(NULL,		"usb11",	&usb11_clk),
+	CLK(NULL,		"emif3",	&emif3_clk),
+	CLK(NULL,		"arm",		&arm_clk),
+	CLK(NULL,		"rmii",		&rmii_clk),
+	CLK(NULL,		NULL,		NULL),
+};
+
+/*
+ * Device specific mux setup
+ *
+ *	     soc      description	mux    mode    mode   mux	dbg
+ *					reg   offset   mask   mode
+ */
+static const struct mux_config da830_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+	MUX_CFG(DA830, GPIO7_14,	0,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, RTCK,		0,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_15,	0,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMU_0,		0,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, EMB_SDCKE,	0,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_CLK_GLUE,	0,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_CLK,		0,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, NEMB_CS_0,	0,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMB_CAS,	0,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMB_RAS,	0,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMB_WE,		0,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_BA_1,	1,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_BA_0,	1,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_0,		1,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_1,		1,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_2,		1,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_3,		1,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_4,		1,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_5,		1,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, GPIO7_0,		1,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_1,		1,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_2,		1,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_3,		1,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_4,		1,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_5,		1,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_6,		1,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_7,		1,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMB_A_6,		2,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_7,		2,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_8,		2,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_9,		2,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_10,	2,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_11,	2,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_A_12,	2,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_31,	2,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, GPIO7_8,		2,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_9,		2,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_10,	2,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_11,	2,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_12,	2,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO7_13,	2,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_13,	2,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, EMB_D_30,	3,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_29,	3,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_28,	3,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_27,	3,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_26,	3,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_25,	3,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_24,	3,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_23,	3,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_22,	4,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_21,	4,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_20,	4,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_19,	4,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_18,	4,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_17,	4,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_16,	4,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMB_WE_DQM_3,	4,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMB_WE_DQM_2,	5,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_0,		5,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_1,		5,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_2,		5,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_3,		5,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_4,		5,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_5,		5,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_6,		5,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, GPIO6_0,		5,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_1,		5,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_2,		5,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_3,		5,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_4,		5,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_5,		5,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_6,		5,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMB_D_7,		6,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_8,		6,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_9,		6,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_10,	6,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_11,	6,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_12,	6,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_13,	6,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMB_D_14,	6,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, GPIO6_7,		6,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_8,		6,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_9,		6,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_10,	6,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_11,	6,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_12,	6,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_13,	6,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO6_14,	6,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMB_D_15,	7,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMB_WE_DQM_1,	7,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMB_WE_DQM_0,	7,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, SPI0_SOMI_0,	7,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, SPI0_SIMO_0,	7,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, SPI0_CLK,	7,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, NSPI0_ENA,	7,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, NSPI0_SCS_0,	7,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, EQEP0I,		7,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, EQEP0S,		7,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, EQEP1I,		7,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, NUART0_CTS,	7,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, NUART0_RTS,	7,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, EQEP0A,		7,	24,	0xf,	4,	false)
+	MUX_CFG(DA830, EQEP0B,		7,	28,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO6_15,	7,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_14,	7,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_15,	7,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_0,		7,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_1,		7,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_2,		7,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_3,		7,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_4,		7,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, SPI1_SOMI_0,	8,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, SPI1_SIMO_0,	8,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, SPI1_CLK,	8,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, UART0_RXD,	8,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, UART0_TXD,	8,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_10,		8,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_11,		8,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, NSPI1_ENA,	8,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, I2C1_SCL,	8,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, I2C1_SDA,	8,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, EQEP1S,		8,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, I2C0_SDA,	8,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, I2C0_SCL,	8,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, UART2_RXD,	8,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, TM64P0_IN12,	8,	12,	0xf,	4,	false)
+	MUX_CFG(DA830, TM64P0_OUT12,	8,	16,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO5_5,		8,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_6,		8,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_7,		8,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_8,		8,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_9,		8,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_10,	8,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_11,	8,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO5_12,	8,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, NSPI1_SCS_0,	9,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, USB0_DRVVBUS,	9,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, AHCLKX0,		9,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, ACLKX0,		9,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, AFSX0,		9,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, AHCLKR0,		9,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, ACLKR0,		9,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, AFSR0,		9,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, UART2_TXD,	9,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, AHCLKX2,		9,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, ECAP0_APWM0,	9,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, RMII_MHZ_50_CLK,	9,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, ECAP1_APWM1,	9,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, USB_REFCLKIN,	9,	8,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO5_13,	9,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_15,	9,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_11,	9,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_12,	9,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_13,	9,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_14,	9,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_15,	9,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_12,	9,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, AMUTE0,		10,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_0,		10,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_1,		10,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_2,		10,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_3,		10,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_4,		10,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_5,		10,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_6,		10,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, RMII_TXD_0,	10,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, RMII_TXD_1,	10,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, RMII_TXEN,	10,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, RMII_CRS_DV,	10,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, RMII_RXD_0,	10,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, RMII_RXD_1,	10,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, RMII_RXER,	10,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, AFSR2,		10,	4,	0xf,	4,	false)
+	MUX_CFG(DA830, ACLKX2,		10,	8,	0xf,	4,	false)
+	MUX_CFG(DA830, AXR2_3,		10,	12,	0xf,	4,	false)
+	MUX_CFG(DA830, AXR2_2,		10,	16,	0xf,	4,	false)
+	MUX_CFG(DA830, AXR2_1,		10,	20,	0xf,	4,	false)
+	MUX_CFG(DA830, AFSX2,		10,	24,	0xf,	4,	false)
+	MUX_CFG(DA830, ACLKR2,		10,	28,	0xf,	4,	false)
+	MUX_CFG(DA830, NRESETOUT,	10,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_0,		10,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_1,		10,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_2,		10,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_3,		10,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_4,		10,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_5,		10,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_6,		10,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, AXR0_7,		11,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_8,		11,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, UART1_RXD,	11,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, UART1_TXD,	11,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR0_11,		11,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, AHCLKX1,		11,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, ACLKX1,		11,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, AFSX1,		11,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, MDIO_CLK,	11,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, MDIO_D,		11,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, AXR0_9,		11,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, AXR0_10,		11,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, EPWM0B,		11,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, EPWM0A,		11,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, EPWMSYNCI,	11,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, AXR2_0,		11,	16,	0xf,	4,	false)
+	MUX_CFG(DA830, EPWMSYNC0,	11,	28,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO3_7,		11,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_8,		11,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_9,		11,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_10,	11,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_11,	11,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_14,	11,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO3_15,	11,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_10,	11,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, AHCLKR1,		12,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, ACLKR1,		12,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, AFSR1,		12,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, AMUTE1,		12,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_0,		12,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_1,		12,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_2,		12,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_3,		12,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, ECAP2_APWM2,	12,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, EHRPWMGLUETZ,	12,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, EQEP1A,		12,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, GPIO4_11,	12,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_12,	12,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_13,	12,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_14,	12,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_0,		12,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_1,		12,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_2,		12,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_3,		12,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, AXR1_4,		13,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_5,		13,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_6,		13,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_7,		13,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_8,		13,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, AXR1_9,		13,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_0,		13,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_1,		13,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, EQEP1B,		13,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, EPWM2B,		13,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, EPWM2A,		13,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, EPWM1B,		13,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, EPWM1A,		13,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_DAT_0,	13,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_DAT_1,	13,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_0,	13,	24,	0xf,	4,	false)
+	MUX_CFG(DA830, UHPI_HD_1,	13,	28,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO4_4,		13,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_5,		13,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_6,		13,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_7,		13,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_8,		13,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO4_9,		13,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_0,		13,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_1,		13,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMA_D_2,		14,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_3,		14,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_4,		14,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_5,		14,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_6,		14,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_7,		14,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_8,		14,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_9,		14,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, MMCSD_DAT_2,	14,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_DAT_3,	14,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_DAT_4,	14,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_DAT_5,	14,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_DAT_6,	14,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_DAT_7,	14,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_8,	14,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_9,	14,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_2,	14,	0,	0xf,	4,	false)
+	MUX_CFG(DA830, UHPI_HD_3,	14,	4,	0xf,	4,	false)
+	MUX_CFG(DA830, UHPI_HD_4,	14,	8,	0xf,	4,	false)
+	MUX_CFG(DA830, UHPI_HD_5,	14,	12,	0xf,	4,	false)
+	MUX_CFG(DA830, UHPI_HD_6,	14,	16,	0xf,	4,	false)
+	MUX_CFG(DA830, UHPI_HD_7,	14,	20,	0xf,	4,	false)
+	MUX_CFG(DA830, LCD_D_8,		14,	24,	0xf,	4,	false)
+	MUX_CFG(DA830, LCD_D_9,		14,	28,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO0_2,		14,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_3,		14,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_4,		14,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_5,		14,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_6,		14,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_7,		14,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_8,		14,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_9,		14,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMA_D_10,	15,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_11,	15,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_12,	15,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_13,	15,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_14,	15,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_D_15,	15,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_0,		15,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_1,		15,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, UHPI_HD_10,	15,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_11,	15,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_12,	15,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_13,	15,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_14,	15,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HD_15,	15,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_7,		15,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, MMCSD_CLK,	15,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_10,	15,	0,	0xf,	4,	false)
+	MUX_CFG(DA830, LCD_D_11,	15,	4,	0xf,	4,	false)
+	MUX_CFG(DA830, LCD_D_12,	15,	8,	0xf,	4,	false)
+	MUX_CFG(DA830, LCD_D_13,	15,	12,	0xf,	4,	false)
+	MUX_CFG(DA830, LCD_D_14,	15,	16,	0xf,	4,	false)
+	MUX_CFG(DA830, LCD_D_15,	15,	20,	0xf,	4,	false)
+	MUX_CFG(DA830, UHPI_HCNTL0,	15,	28,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO0_10,	15,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_11,	15,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_12,	15,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_13,	15,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_14,	15,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO0_15,	15,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_0,		15,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_1,		15,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMA_A_2,		16,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_3,		16,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_4,		16,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_5,		16,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_6,		16,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_7,		16,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_8,		16,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_9,		16,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, MMCSD_CMD,	16,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_6,		16,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_3,		16,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_2,		16,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_1,		16,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_0,		16,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_PCLK,	16,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_HSYNC,	16,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HCNTL1,	16,	0,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO1_2,		16,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_3,		16,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_4,		16,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_5,		16,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_6,		16,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_7,		16,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_8,		16,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_9,		16,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMA_A_10,	17,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_11,	17,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_A_12,	17,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_BA_1,	17,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_BA_0,	17,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_CLK,		17,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, EMA_SDCKE,	17,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_CAS,	17,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, LCD_VSYNC,	17,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, NLCD_AC_ENB_CS,	17,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_MCLK,	17,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_5,		17,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, LCD_D_4,		17,	16,	0xf,	2,	false)
+	MUX_CFG(DA830, OBSCLK,		17,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, NEMA_CS_4,	17,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HHWIL,	17,	12,	0xf,	4,	false)
+	MUX_CFG(DA830, AHCLKR2,		17,	20,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO1_10,	17,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_11,	17,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_12,	17,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_13,	17,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_14,	17,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO1_15,	17,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_0,		17,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_1,		17,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, NEMA_RAS,	18,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_WE,		18,	4,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_CS_0,	18,	8,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_CS_2,	18,	12,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_CS_3,	18,	16,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_OE,		18,	20,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_WE_DQM_1,	18,	24,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_WE_DQM_0,	18,	28,	0xf,	1,	false)
+	MUX_CFG(DA830, NEMA_CS_5,	18,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, UHPI_HRNW,	18,	4,	0xf,	2,	false)
+	MUX_CFG(DA830, NUHPI_HAS,	18,	8,	0xf,	2,	false)
+	MUX_CFG(DA830, NUHPI_HCS,	18,	12,	0xf,	2,	false)
+	MUX_CFG(DA830, NUHPI_HDS1,	18,	20,	0xf,	2,	false)
+	MUX_CFG(DA830, NUHPI_HDS2,	18,	24,	0xf,	2,	false)
+	MUX_CFG(DA830, NUHPI_HINT,	18,	28,	0xf,	2,	false)
+	MUX_CFG(DA830, AXR0_12,		18,	4,	0xf,	4,	false)
+	MUX_CFG(DA830, AMUTE2,		18,	16,	0xf,	4,	false)
+	MUX_CFG(DA830, AXR0_13,		18,	20,	0xf,	4,	false)
+	MUX_CFG(DA830, AXR0_14,		18,	24,	0xf,	4,	false)
+	MUX_CFG(DA830, AXR0_15,		18,	28,	0xf,	4,	false)
+	MUX_CFG(DA830, GPIO2_2,		18,	0,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_3,		18,	4,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_4,		18,	8,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_5,		18,	12,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_6,		18,	16,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_7,		18,	20,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_8,		18,	24,	0xf,	8,	false)
+	MUX_CFG(DA830, GPIO2_9,		18,	28,	0xf,	8,	false)
+	MUX_CFG(DA830, EMA_WAIT_0,	19,	0,	0xf,	1,	false)
+	MUX_CFG(DA830, NUHPI_HRDY,	19,	0,	0xf,	2,	false)
+	MUX_CFG(DA830, GPIO2_10,	19,	0,	0xf,	8,	false)
+#endif
+};
+
+const short da830_emif25_pins[] __initdata = {
+	DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+	DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+	DA830_EMA_D_8, DA830_EMA_D_9, DA830_EMA_D_10, DA830_EMA_D_11,
+	DA830_EMA_D_12, DA830_EMA_D_13, DA830_EMA_D_14, DA830_EMA_D_15,
+	DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+	DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+	DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+	DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_EMA_CLK,
+	DA830_EMA_SDCKE, DA830_NEMA_CS_4, DA830_NEMA_CS_5, DA830_NEMA_WE,
+	DA830_NEMA_CS_0, DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE,
+	DA830_NEMA_WE_DQM_1, DA830_NEMA_WE_DQM_0, DA830_EMA_WAIT_0,
+	-1
+};
+
+const short da830_spi0_pins[] __initdata = {
+	DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA,
+	DA830_NSPI0_SCS_0,
+	-1
+};
+
+const short da830_spi1_pins[] __initdata = {
+	DA830_SPI1_SOMI_0, DA830_SPI1_SIMO_0, DA830_SPI1_CLK, DA830_NSPI1_ENA,
+	DA830_NSPI1_SCS_0,
+	-1
+};
+
+const short da830_mmc_sd_pins[] __initdata = {
+	DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
+	DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
+	DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
+	DA830_MMCSD_CMD,
+	-1
+};
+
+const short da830_uart0_pins[] __initdata = {
+	DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD,
+	-1
+};
+
+const short da830_uart1_pins[] __initdata = {
+	DA830_UART1_RXD, DA830_UART1_TXD,
+	-1
+};
+
+const short da830_uart2_pins[] __initdata = {
+	DA830_UART2_RXD, DA830_UART2_TXD,
+	-1
+};
+
+const short da830_usb20_pins[] __initdata = {
+	DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN,
+	-1
+};
+
+const short da830_usb11_pins[] __initdata = {
+	DA830_USB_REFCLKIN,
+	-1
+};
+
+const short da830_uhpi_pins[] __initdata = {
+	DA830_UHPI_HD_0, DA830_UHPI_HD_1, DA830_UHPI_HD_2, DA830_UHPI_HD_3,
+	DA830_UHPI_HD_4, DA830_UHPI_HD_5, DA830_UHPI_HD_6, DA830_UHPI_HD_7,
+	DA830_UHPI_HD_8, DA830_UHPI_HD_9, DA830_UHPI_HD_10, DA830_UHPI_HD_11,
+	DA830_UHPI_HD_12, DA830_UHPI_HD_13, DA830_UHPI_HD_14, DA830_UHPI_HD_15,
+	DA830_UHPI_HCNTL0, DA830_UHPI_HCNTL1, DA830_UHPI_HHWIL, DA830_UHPI_HRNW,
+	DA830_NUHPI_HAS, DA830_NUHPI_HCS, DA830_NUHPI_HDS1, DA830_NUHPI_HDS2,
+	DA830_NUHPI_HINT, DA830_NUHPI_HRDY,
+	-1
+};
+
+const short da830_cpgmac_pins[] __initdata = {
+	DA830_RMII_TXD_0, DA830_RMII_TXD_1, DA830_RMII_TXEN, DA830_RMII_CRS_DV,
+	DA830_RMII_RXD_0, DA830_RMII_RXD_1, DA830_RMII_RXER, DA830_MDIO_CLK,
+	DA830_MDIO_D,
+	-1
+};
+
+const short da830_emif3c_pins[] __initdata = {
+	DA830_EMB_SDCKE, DA830_EMB_CLK_GLUE, DA830_EMB_CLK, DA830_NEMB_CS_0,
+	DA830_NEMB_CAS, DA830_NEMB_RAS, DA830_NEMB_WE, DA830_EMB_BA_1,
+	DA830_EMB_BA_0, DA830_EMB_A_0, DA830_EMB_A_1, DA830_EMB_A_2,
+	DA830_EMB_A_3, DA830_EMB_A_4, DA830_EMB_A_5, DA830_EMB_A_6,
+	DA830_EMB_A_7, DA830_EMB_A_8, DA830_EMB_A_9, DA830_EMB_A_10,
+	DA830_EMB_A_11, DA830_EMB_A_12, DA830_NEMB_WE_DQM_3,
+	DA830_NEMB_WE_DQM_2, DA830_EMB_D_0, DA830_EMB_D_1, DA830_EMB_D_2,
+	DA830_EMB_D_3, DA830_EMB_D_4, DA830_EMB_D_5, DA830_EMB_D_6,
+	DA830_EMB_D_7, DA830_EMB_D_8, DA830_EMB_D_9, DA830_EMB_D_10,
+	DA830_EMB_D_11, DA830_EMB_D_12, DA830_EMB_D_13, DA830_EMB_D_14,
+	DA830_EMB_D_15, DA830_EMB_D_16, DA830_EMB_D_17, DA830_EMB_D_18,
+	DA830_EMB_D_19, DA830_EMB_D_20, DA830_EMB_D_21, DA830_EMB_D_22,
+	DA830_EMB_D_23, DA830_EMB_D_24, DA830_EMB_D_25, DA830_EMB_D_26,
+	DA830_EMB_D_27, DA830_EMB_D_28, DA830_EMB_D_29, DA830_EMB_D_30,
+	DA830_EMB_D_31, DA830_NEMB_WE_DQM_1, DA830_NEMB_WE_DQM_0,
+	-1
+};
+
+const short da830_mcasp0_pins[] __initdata = {
+	DA830_AHCLKX0, DA830_ACLKX0, DA830_AFSX0,
+	DA830_AHCLKR0, DA830_ACLKR0, DA830_AFSR0, DA830_AMUTE0,
+	DA830_AXR0_0, DA830_AXR0_1, DA830_AXR0_2, DA830_AXR0_3,
+	DA830_AXR0_4, DA830_AXR0_5, DA830_AXR0_6, DA830_AXR0_7,
+	DA830_AXR0_8, DA830_AXR0_9, DA830_AXR0_10, DA830_AXR0_11,
+	DA830_AXR0_12, DA830_AXR0_13, DA830_AXR0_14, DA830_AXR0_15,
+	-1
+};
+
+const short da830_mcasp1_pins[] __initdata = {
+	DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1,
+	DA830_AHCLKR1, DA830_ACLKR1, DA830_AFSR1, DA830_AMUTE1,
+	DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_3,
+	DA830_AXR1_4, DA830_AXR1_5, DA830_AXR1_6, DA830_AXR1_7,
+	DA830_AXR1_8, DA830_AXR1_9, DA830_AXR1_10, DA830_AXR1_11,
+	-1
+};
+
+const short da830_mcasp2_pins[] __initdata = {
+	DA830_AHCLKX2, DA830_ACLKX2, DA830_AFSX2,
+	DA830_AHCLKR2, DA830_ACLKR2, DA830_AFSR2, DA830_AMUTE2,
+	DA830_AXR2_0, DA830_AXR2_1, DA830_AXR2_2, DA830_AXR2_3,
+	-1
+};
+
+const short da830_i2c0_pins[] __initdata = {
+	DA830_I2C0_SDA, DA830_I2C0_SCL,
+	-1
+};
+
+const short da830_i2c1_pins[] __initdata = {
+	DA830_I2C1_SCL, DA830_I2C1_SDA,
+	-1
+};
+
+const short da830_lcdcntl_pins[] __initdata = {
+	DA830_LCD_D_0, DA830_LCD_D_1, DA830_LCD_D_2, DA830_LCD_D_3,
+	DA830_LCD_D_4, DA830_LCD_D_5, DA830_LCD_D_6, DA830_LCD_D_7,
+	DA830_LCD_D_8, DA830_LCD_D_9, DA830_LCD_D_10, DA830_LCD_D_11,
+	DA830_LCD_D_12, DA830_LCD_D_13, DA830_LCD_D_14, DA830_LCD_D_15,
+	DA830_LCD_PCLK, DA830_LCD_HSYNC, DA830_LCD_VSYNC, DA830_NLCD_AC_ENB_CS,
+	DA830_LCD_MCLK,
+	-1
+};
+
+const short da830_pwm_pins[] __initdata = {
+	DA830_ECAP0_APWM0, DA830_ECAP1_APWM1, DA830_EPWM0B, DA830_EPWM0A,
+	DA830_EPWMSYNCI, DA830_EPWMSYNC0, DA830_ECAP2_APWM2, DA830_EHRPWMGLUETZ,
+	DA830_EPWM2B, DA830_EPWM2A, DA830_EPWM1B, DA830_EPWM1A,
+	-1
+};
+
+const short da830_ecap0_pins[] __initdata = {
+	DA830_ECAP0_APWM0,
+	-1
+};
+
+const short da830_ecap1_pins[] __initdata = {
+	DA830_ECAP1_APWM1,
+	-1
+};
+
+const short da830_ecap2_pins[] __initdata = {
+	DA830_ECAP2_APWM2,
+	-1
+};
+
+const short da830_eqep0_pins[] __initdata = {
+	DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B,
+	-1
+};
+
+const short da830_eqep1_pins[] __initdata = {
+	DA830_EQEP1I, DA830_EQEP1S, DA830_EQEP1A, DA830_EQEP1B,
+	-1
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 da830_default_priorities[DA830_N_CP_INTC_IRQ] = {
+	[IRQ_DA8XX_COMMTX]		= 7,
+	[IRQ_DA8XX_COMMRX]		= 7,
+	[IRQ_DA8XX_NINT]		= 7,
+	[IRQ_DA8XX_EVTOUT0]		= 7,
+	[IRQ_DA8XX_EVTOUT1]		= 7,
+	[IRQ_DA8XX_EVTOUT2]		= 7,
+	[IRQ_DA8XX_EVTOUT3]		= 7,
+	[IRQ_DA8XX_EVTOUT4]		= 7,
+	[IRQ_DA8XX_EVTOUT5]		= 7,
+	[IRQ_DA8XX_EVTOUT6]		= 7,
+	[IRQ_DA8XX_EVTOUT6]		= 7,
+	[IRQ_DA8XX_EVTOUT7]		= 7,
+	[IRQ_DA8XX_CCINT0]		= 7,
+	[IRQ_DA8XX_CCERRINT]		= 7,
+	[IRQ_DA8XX_TCERRINT0]		= 7,
+	[IRQ_DA8XX_AEMIFINT]		= 7,
+	[IRQ_DA8XX_I2CINT0]		= 7,
+	[IRQ_DA8XX_MMCSDINT0]		= 7,
+	[IRQ_DA8XX_MMCSDINT1]		= 7,
+	[IRQ_DA8XX_ALLINT0]		= 7,
+	[IRQ_DA8XX_RTC]			= 7,
+	[IRQ_DA8XX_SPINT0]		= 7,
+	[IRQ_DA8XX_TINT12_0]		= 7,
+	[IRQ_DA8XX_TINT34_0]		= 7,
+	[IRQ_DA8XX_TINT12_1]		= 7,
+	[IRQ_DA8XX_TINT34_1]		= 7,
+	[IRQ_DA8XX_UARTINT0]		= 7,
+	[IRQ_DA8XX_KEYMGRINT]		= 7,
+	[IRQ_DA8XX_SECINT]		= 7,
+	[IRQ_DA8XX_SECKEYERR]		= 7,
+	[IRQ_DA830_MPUERR]		= 7,
+	[IRQ_DA830_IOPUERR]		= 7,
+	[IRQ_DA830_BOOTCFGERR]		= 7,
+	[IRQ_DA8XX_CHIPINT0]		= 7,
+	[IRQ_DA8XX_CHIPINT1]		= 7,
+	[IRQ_DA8XX_CHIPINT2]		= 7,
+	[IRQ_DA8XX_CHIPINT3]		= 7,
+	[IRQ_DA8XX_TCERRINT1]		= 7,
+	[IRQ_DA8XX_C0_RX_THRESH_PULSE]	= 7,
+	[IRQ_DA8XX_C0_RX_PULSE]		= 7,
+	[IRQ_DA8XX_C0_TX_PULSE]		= 7,
+	[IRQ_DA8XX_C0_MISC_PULSE]	= 7,
+	[IRQ_DA8XX_C1_RX_THRESH_PULSE]	= 7,
+	[IRQ_DA8XX_C1_RX_PULSE]		= 7,
+	[IRQ_DA8XX_C1_TX_PULSE]		= 7,
+	[IRQ_DA8XX_C1_MISC_PULSE]	= 7,
+	[IRQ_DA8XX_MEMERR]		= 7,
+	[IRQ_DA8XX_GPIO0]		= 7,
+	[IRQ_DA8XX_GPIO1]		= 7,
+	[IRQ_DA8XX_GPIO2]		= 7,
+	[IRQ_DA8XX_GPIO3]		= 7,
+	[IRQ_DA8XX_GPIO4]		= 7,
+	[IRQ_DA8XX_GPIO5]		= 7,
+	[IRQ_DA8XX_GPIO6]		= 7,
+	[IRQ_DA8XX_GPIO7]		= 7,
+	[IRQ_DA8XX_GPIO8]		= 7,
+	[IRQ_DA8XX_I2CINT1]		= 7,
+	[IRQ_DA8XX_LCDINT]		= 7,
+	[IRQ_DA8XX_UARTINT1]		= 7,
+	[IRQ_DA8XX_MCASPINT]		= 7,
+	[IRQ_DA8XX_ALLINT1]		= 7,
+	[IRQ_DA8XX_SPINT1]		= 7,
+	[IRQ_DA8XX_UHPI_INT1]		= 7,
+	[IRQ_DA8XX_USB_INT]		= 7,
+	[IRQ_DA8XX_IRQN]		= 7,
+	[IRQ_DA8XX_RWAKEUP]		= 7,
+	[IRQ_DA8XX_UARTINT2]		= 7,
+	[IRQ_DA8XX_DFTSSINT]		= 7,
+	[IRQ_DA8XX_EHRPWM0]		= 7,
+	[IRQ_DA8XX_EHRPWM0TZ]		= 7,
+	[IRQ_DA8XX_EHRPWM1]		= 7,
+	[IRQ_DA8XX_EHRPWM1TZ]		= 7,
+	[IRQ_DA830_EHRPWM2]		= 7,
+	[IRQ_DA830_EHRPWM2TZ]		= 7,
+	[IRQ_DA8XX_ECAP0]		= 7,
+	[IRQ_DA8XX_ECAP1]		= 7,
+	[IRQ_DA8XX_ECAP2]		= 7,
+	[IRQ_DA830_EQEP0]		= 7,
+	[IRQ_DA830_EQEP1]		= 7,
+	[IRQ_DA830_T12CMPINT0_0]	= 7,
+	[IRQ_DA830_T12CMPINT1_0]	= 7,
+	[IRQ_DA830_T12CMPINT2_0]	= 7,
+	[IRQ_DA830_T12CMPINT3_0]	= 7,
+	[IRQ_DA830_T12CMPINT4_0]	= 7,
+	[IRQ_DA830_T12CMPINT5_0]	= 7,
+	[IRQ_DA830_T12CMPINT6_0]	= 7,
+	[IRQ_DA830_T12CMPINT7_0]	= 7,
+	[IRQ_DA830_T12CMPINT0_1]	= 7,
+	[IRQ_DA830_T12CMPINT1_1]	= 7,
+	[IRQ_DA830_T12CMPINT2_1]	= 7,
+	[IRQ_DA830_T12CMPINT3_1]	= 7,
+	[IRQ_DA830_T12CMPINT4_1]	= 7,
+	[IRQ_DA830_T12CMPINT5_1]	= 7,
+	[IRQ_DA830_T12CMPINT6_1]	= 7,
+	[IRQ_DA830_T12CMPINT7_1]	= 7,
+	[IRQ_DA8XX_ARMCLKSTOPREQ]	= 7,
+};
+
+static struct map_desc da830_io_desc[] = {
+	{
+		.virtual	= IO_VIRT,
+		.pfn		= __phys_to_pfn(IO_PHYS),
+		.length		= IO_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= DA8XX_CP_INTC_VIRT,
+		.pfn		= __phys_to_pfn(DA8XX_CP_INTC_BASE),
+		.length		= DA8XX_CP_INTC_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+static void __iomem *da830_psc_bases[] = {
+	IO_ADDRESS(DA8XX_PSC0_BASE),
+	IO_ADDRESS(DA8XX_PSC1_BASE),
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id da830_ids[] = {
+	{
+		.variant	= 0x0,
+		.part_no	= 0xb7df,
+		.manufacturer	= 0x017,	/* 0x02f >> 1 */
+		.cpu_id		= DAVINCI_CPU_ID_DA830,
+		.name		= "da830/omap l137",
+	},
+};
+
+static struct davinci_timer_instance da830_timer_instance[2] = {
+	{
+		.base		= IO_ADDRESS(DA8XX_TIMER64P0_BASE),
+		.bottom_irq	= IRQ_DA8XX_TINT12_0,
+		.top_irq	= IRQ_DA8XX_TINT34_0,
+		.cmp_off	= DA830_CMP12_0,
+		.cmp_irq	= IRQ_DA830_T12CMPINT0_0,
+	},
+	{
+		.base		= IO_ADDRESS(DA8XX_TIMER64P1_BASE),
+		.bottom_irq	= IRQ_DA8XX_TINT12_1,
+		.top_irq	= IRQ_DA8XX_TINT34_1,
+		.cmp_off	= DA830_CMP12_0,
+		.cmp_irq	= IRQ_DA830_T12CMPINT0_1,
+	},
+};
+
+/*
+ * T0_BOT: Timer 0, bottom		: Used for clock_event & clocksource
+ * T0_TOP: Timer 0, top			: Used by DSP
+ * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ */
+static struct davinci_timer_info da830_timer_info = {
+	.timers		= da830_timer_instance,
+	.clockevent_id	= T0_BOT,
+	.clocksource_id	= T0_BOT,
+};
+
+static struct davinci_soc_info davinci_soc_info_da830 = {
+	.io_desc		= da830_io_desc,
+	.io_desc_num		= ARRAY_SIZE(da830_io_desc),
+	.jtag_id_base		= IO_ADDRESS(DA8XX_JTAG_ID_REG),
+	.ids			= da830_ids,
+	.ids_num		= ARRAY_SIZE(da830_ids),
+	.cpu_clks		= da830_clks,
+	.psc_bases		= da830_psc_bases,
+	.psc_bases_num		= ARRAY_SIZE(da830_psc_bases),
+	.pinmux_base		= IO_ADDRESS(DA8XX_BOOT_CFG_BASE + 0x120),
+	.pinmux_pins		= da830_pins,
+	.pinmux_pins_num	= ARRAY_SIZE(da830_pins),
+	.intc_base		= (void __iomem *)DA8XX_CP_INTC_VIRT,
+	.intc_type		= DAVINCI_INTC_TYPE_CP_INTC,
+	.intc_irq_prios		= da830_default_priorities,
+	.intc_irq_num		= DA830_N_CP_INTC_IRQ,
+	.timer_info		= &da830_timer_info,
+	.gpio_base		= IO_ADDRESS(DA8XX_GPIO_BASE),
+	.gpio_num		= 128,
+	.gpio_irq		= IRQ_DA8XX_GPIO0,
+	.serial_dev		= &da8xx_serial_device,
+	.emac_pdata		= &da8xx_emac_pdata,
+};
+
+void __init da830_init(void)
+{
+	davinci_common_init(&davinci_soc_info_da830);
+}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
new file mode 100644
index 0000000..192d719
--- /dev/null
+++ b/arch/arm/mach-davinci/da850.c
@@ -0,0 +1,820 @@
+/*
+ * TI DA850/OMAP-L138 chip specific setup
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Derived from: arch/arm/mach-davinci/da830.c
+ * Original Copyrights follow:
+ *
+ * 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/clock.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+
+#include "clock.h"
+#include "mux.h"
+
+#define DA850_PLL1_BASE		0x01e1a000
+#define DA850_TIMER64P2_BASE	0x01f0c000
+#define DA850_TIMER64P3_BASE	0x01f0d000
+
+#define DA850_REF_FREQ		24000000
+
+static struct pll_data pll0_data = {
+	.num		= 1,
+	.phys_base	= DA8XX_PLL0_BASE,
+	.flags		= PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct clk ref_clk = {
+	.name		= "ref_clk",
+	.rate		= DA850_REF_FREQ,
+};
+
+static struct clk pll0_clk = {
+	.name		= "pll0",
+	.parent		= &ref_clk,
+	.pll_data	= &pll0_data,
+	.flags		= CLK_PLL,
+};
+
+static struct clk pll0_aux_clk = {
+	.name		= "pll0_aux_clk",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll0_sysclk2 = {
+	.name		= "pll0_sysclk2",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV2,
+};
+
+static struct clk pll0_sysclk3 = {
+	.name		= "pll0_sysclk3",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV3,
+};
+
+static struct clk pll0_sysclk4 = {
+	.name		= "pll0_sysclk4",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV4,
+};
+
+static struct clk pll0_sysclk5 = {
+	.name		= "pll0_sysclk5",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV5,
+};
+
+static struct clk pll0_sysclk6 = {
+	.name		= "pll0_sysclk6",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV6,
+};
+
+static struct clk pll0_sysclk7 = {
+	.name		= "pll0_sysclk7",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV7,
+};
+
+static struct pll_data pll1_data = {
+	.num		= 2,
+	.phys_base	= DA850_PLL1_BASE,
+	.flags		= PLL_HAS_POSTDIV,
+};
+
+static struct clk pll1_clk = {
+	.name		= "pll1",
+	.parent		= &ref_clk,
+	.pll_data	= &pll1_data,
+	.flags		= CLK_PLL,
+};
+
+static struct clk pll1_aux_clk = {
+	.name		= "pll1_aux_clk",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk2 = {
+	.name		= "pll1_sysclk2",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+	.name		= "pll1_sysclk3",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+	.name		= "pll1_sysclk4",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+	.name		= "pll1_sysclk5",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+	.name		= "pll0_sysclk6",
+	.parent		= &pll0_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV6,
+};
+
+static struct clk pll1_sysclk7 = {
+	.name		= "pll1_sysclk7",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV7,
+};
+
+static struct clk i2c0_clk = {
+	.name		= "i2c0",
+	.parent		= &pll0_aux_clk,
+};
+
+static struct clk timerp64_0_clk = {
+	.name		= "timer0",
+	.parent		= &pll0_aux_clk,
+};
+
+static struct clk timerp64_1_clk = {
+	.name		= "timer1",
+	.parent		= &pll0_aux_clk,
+};
+
+static struct clk arm_rom_clk = {
+	.name		= "arm_rom",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_ARM_RAM_ROM,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk tpcc0_clk = {
+	.name		= "tpcc0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_TPCC,
+	.flags		= ALWAYS_ENABLED | CLK_PSC,
+};
+
+static struct clk tptc0_clk = {
+	.name		= "tptc0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_TPTC0,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk tptc1_clk = {
+	.name		= "tptc1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_TPTC1,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk tpcc1_clk = {
+	.name		= "tpcc1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA850_LPSC1_TPCC1,
+	.flags		= CLK_PSC | ALWAYS_ENABLED,
+	.psc_ctlr	= 1,
+};
+
+static struct clk tptc2_clk = {
+	.name		= "tptc2",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA850_LPSC1_TPTC2,
+	.flags		= ALWAYS_ENABLED,
+	.psc_ctlr	= 1,
+};
+
+static struct clk uart0_clk = {
+	.name		= "uart0",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_UART0,
+};
+
+static struct clk uart1_clk = {
+	.name		= "uart1",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_UART1,
+	.psc_ctlr	= 1,
+};
+
+static struct clk uart2_clk = {
+	.name		= "uart2",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_UART2,
+	.psc_ctlr	= 1,
+};
+
+static struct clk aintc_clk = {
+	.name		= "aintc",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC0_AINTC,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk gpio_clk = {
+	.name		= "gpio",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC1_GPIO,
+	.psc_ctlr	= 1,
+};
+
+static struct clk i2c1_clk = {
+	.name		= "i2c1",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC1_I2C,
+	.psc_ctlr	= 1,
+};
+
+static struct clk emif3_clk = {
+	.name		= "emif3",
+	.parent		= &pll0_sysclk5,
+	.lpsc		= DA8XX_LPSC1_EMIF3C,
+	.flags		= ALWAYS_ENABLED,
+	.psc_ctlr	= 1,
+};
+
+static struct clk arm_clk = {
+	.name		= "arm",
+	.parent		= &pll0_sysclk6,
+	.lpsc		= DA8XX_LPSC0_ARM,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk rmii_clk = {
+	.name		= "rmii",
+	.parent		= &pll0_sysclk7,
+};
+
+static struct clk emac_clk = {
+	.name		= "emac",
+	.parent		= &pll0_sysclk4,
+	.lpsc		= DA8XX_LPSC1_CPGMAC,
+	.psc_ctlr	= 1,
+};
+
+static struct clk mcasp_clk = {
+	.name		= "mcasp",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_McASP0,
+	.psc_ctlr	= 1,
+};
+
+static struct clk lcdc_clk = {
+	.name		= "lcdc",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC1_LCDC,
+	.psc_ctlr	= 1,
+};
+
+static struct clk mmcsd_clk = {
+	.name		= "mmcsd",
+	.parent		= &pll0_sysclk2,
+	.lpsc		= DA8XX_LPSC0_MMC_SD,
+};
+
+static struct clk aemif_clk = {
+	.name		= "aemif",
+	.parent		= &pll0_sysclk3,
+	.lpsc		= DA8XX_LPSC0_EMIF25,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct davinci_clk da850_clks[] = {
+	CLK(NULL,		"ref",		&ref_clk),
+	CLK(NULL,		"pll0",		&pll0_clk),
+	CLK(NULL,		"pll0_aux",	&pll0_aux_clk),
+	CLK(NULL,		"pll0_sysclk2",	&pll0_sysclk2),
+	CLK(NULL,		"pll0_sysclk3",	&pll0_sysclk3),
+	CLK(NULL,		"pll0_sysclk4",	&pll0_sysclk4),
+	CLK(NULL,		"pll0_sysclk5",	&pll0_sysclk5),
+	CLK(NULL,		"pll0_sysclk6",	&pll0_sysclk6),
+	CLK(NULL,		"pll0_sysclk7",	&pll0_sysclk7),
+	CLK(NULL,		"pll1",		&pll1_clk),
+	CLK(NULL,		"pll1_aux",	&pll1_aux_clk),
+	CLK(NULL,		"pll1_sysclk2",	&pll1_sysclk2),
+	CLK(NULL,		"pll1_sysclk3",	&pll1_sysclk3),
+	CLK(NULL,		"pll1_sysclk4",	&pll1_sysclk4),
+	CLK(NULL,		"pll1_sysclk5",	&pll1_sysclk5),
+	CLK(NULL,		"pll1_sysclk6",	&pll1_sysclk6),
+	CLK(NULL,		"pll1_sysclk7",	&pll1_sysclk7),
+	CLK("i2c_davinci.1",	NULL,		&i2c0_clk),
+	CLK(NULL,		"timer0",	&timerp64_0_clk),
+	CLK("watchdog",		NULL,		&timerp64_1_clk),
+	CLK(NULL,		"arm_rom",	&arm_rom_clk),
+	CLK(NULL,		"tpcc0",	&tpcc0_clk),
+	CLK(NULL,		"tptc0",	&tptc0_clk),
+	CLK(NULL,		"tptc1",	&tptc1_clk),
+	CLK(NULL,		"tpcc1",	&tpcc1_clk),
+	CLK(NULL,		"tptc2",	&tptc2_clk),
+	CLK(NULL,		"uart0",	&uart0_clk),
+	CLK(NULL,		"uart1",	&uart1_clk),
+	CLK(NULL,		"uart2",	&uart2_clk),
+	CLK(NULL,		"aintc",	&aintc_clk),
+	CLK(NULL,		"gpio",		&gpio_clk),
+	CLK("i2c_davinci.2",	NULL,		&i2c1_clk),
+	CLK(NULL,		"emif3",	&emif3_clk),
+	CLK(NULL,		"arm",		&arm_clk),
+	CLK(NULL,		"rmii",		&rmii_clk),
+	CLK("davinci_emac.1",	NULL,		&emac_clk),
+	CLK("davinci-mcasp.0",	NULL,		&mcasp_clk),
+	CLK("da8xx_lcdc.0",	NULL,		&lcdc_clk),
+	CLK("davinci_mmc.0",	NULL,		&mmcsd_clk),
+	CLK(NULL,		"aemif",	&aemif_clk),
+	CLK(NULL,		NULL,		NULL),
+};
+
+/*
+ * Device specific mux setup
+ *
+ *		soc	description	mux	mode	mode	mux	dbg
+ *					reg	offset	mask	mode
+ */
+static const struct mux_config da850_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+	/* UART0 function */
+	MUX_CFG(DA850, NUART0_CTS,	3,	24,	15,	2,	false)
+	MUX_CFG(DA850, NUART0_RTS,	3,	28,	15,	2,	false)
+	MUX_CFG(DA850, UART0_RXD,	3,	16,	15,	2,	false)
+	MUX_CFG(DA850, UART0_TXD,	3,	20,	15,	2,	false)
+	/* UART1 function */
+	MUX_CFG(DA850, UART1_RXD,	4,	24,	15,	2,	false)
+	MUX_CFG(DA850, UART1_TXD,	4,	28,	15,	2,	false)
+	/* UART2 function */
+	MUX_CFG(DA850, UART2_RXD,	4,	16,	15,	2,	false)
+	MUX_CFG(DA850, UART2_TXD,	4,	20,	15,	2,	false)
+	/* I2C1 function */
+	MUX_CFG(DA850, I2C1_SCL,	4,	16,	15,	4,	false)
+	MUX_CFG(DA850, I2C1_SDA,	4,	20,	15,	4,	false)
+	/* I2C0 function */
+	MUX_CFG(DA850, I2C0_SDA,	4,	12,	15,	2,	false)
+	MUX_CFG(DA850, I2C0_SCL,	4,	8,	15,	2,	false)
+	/* EMAC function */
+	MUX_CFG(DA850, MII_TXEN,	2,	4,	15,	8,	false)
+	MUX_CFG(DA850, MII_TXCLK,	2,	8,	15,	8,	false)
+	MUX_CFG(DA850, MII_COL,		2,	12,	15,	8,	false)
+	MUX_CFG(DA850, MII_TXD_3,	2,	16,	15,	8,	false)
+	MUX_CFG(DA850, MII_TXD_2,	2,	20,	15,	8,	false)
+	MUX_CFG(DA850, MII_TXD_1,	2,	24,	15,	8,	false)
+	MUX_CFG(DA850, MII_TXD_0,	2,	28,	15,	8,	false)
+	MUX_CFG(DA850, MII_RXCLK,	3,	0,	15,	8,	false)
+	MUX_CFG(DA850, MII_RXDV,	3,	4,	15,	8,	false)
+	MUX_CFG(DA850, MII_RXER,	3,	8,	15,	8,	false)
+	MUX_CFG(DA850, MII_CRS,		3,	12,	15,	8,	false)
+	MUX_CFG(DA850, MII_RXD_3,	3,	16,	15,	8,	false)
+	MUX_CFG(DA850, MII_RXD_2,	3,	20,	15,	8,	false)
+	MUX_CFG(DA850, MII_RXD_1,	3,	24,	15,	8,	false)
+	MUX_CFG(DA850, MII_RXD_0,	3,	28,	15,	8,	false)
+	MUX_CFG(DA850, MDIO_CLK,	4,	0,	15,	8,	false)
+	MUX_CFG(DA850, MDIO_D,		4,	4,	15,	8,	false)
+	/* McASP function */
+	MUX_CFG(DA850,	ACLKR,		0,	0,	15,	1,	false)
+	MUX_CFG(DA850,	ACLKX,		0,	4,	15,	1,	false)
+	MUX_CFG(DA850,	AFSR,		0,	8,	15,	1,	false)
+	MUX_CFG(DA850,	AFSX,		0,	12,	15,	1,	false)
+	MUX_CFG(DA850,	AHCLKR,		0,	16,	15,	1,	false)
+	MUX_CFG(DA850,	AHCLKX,		0,	20,	15,	1,	false)
+	MUX_CFG(DA850,	AMUTE,		0,	24,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_15,		1,	0,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_14,		1,	4,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_13,		1,	8,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_12,		1,	12,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_11,		1,	16,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_10,		1,	20,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_9,		1,	24,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_8,		1,	28,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_7,		2,	0,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_6,		2,	4,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_5,		2,	8,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_4,		2,	12,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_3,		2,	16,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_2,		2,	20,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_1,		2,	24,	15,	1,	false)
+	MUX_CFG(DA850,	AXR_0,		2,	28,	15,	1,	false)
+	/* LCD function */
+	MUX_CFG(DA850, LCD_D_7,		16,	8,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_6,		16,	12,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_5,		16,	16,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_4,		16,	20,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_3,		16,	24,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_2,		16,	28,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_1,		17,	0,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_0,		17,	4,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_15,	17,	8,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_14,	17,	12,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_13,	17,	16,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_12,	17,	20,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_11,	17,	24,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_10,	17,	28,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_9,		18,	0,	15,	2,	false)
+	MUX_CFG(DA850, LCD_D_8,		18,	4,	15,	2,	false)
+	MUX_CFG(DA850, LCD_PCLK,	18,	24,	15,	2,	false)
+	MUX_CFG(DA850, LCD_HSYNC,	19,	0,	15,	2,	false)
+	MUX_CFG(DA850, LCD_VSYNC,	19,	4,	15,	2,	false)
+	MUX_CFG(DA850, NLCD_AC_ENB_CS,	19,	24,	15,	2,	false)
+	/* MMC/SD0 function */
+	MUX_CFG(DA850, MMCSD0_DAT_0,	10,	8,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD0_DAT_1,	10,	12,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD0_DAT_2,	10,	16,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD0_DAT_3,	10,	20,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD0_CLK,	10,	0,	15,	2,	false)
+	MUX_CFG(DA850, MMCSD0_CMD,	10,	4,	15,	2,	false)
+	/* EMIF2.5/EMIFA function */
+	MUX_CFG(DA850, EMA_D_7,		9,	0,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_6,		9,	4,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_5,		9,	8,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_4,		9,	12,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_3,		9,	16,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_2,		9,	20,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_1,		9,	24,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_0,		9,	28,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_1,		12,	24,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_2,		12,	20,	15,	1,	false)
+	MUX_CFG(DA850, NEMA_CS_3,	7,	4,	15,	1,	false)
+	MUX_CFG(DA850, NEMA_CS_4,	7,	8,	15,	1,	false)
+	MUX_CFG(DA850, NEMA_WE,		7,	16,	15,	1,	false)
+	MUX_CFG(DA850, NEMA_OE,		7,	20,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_0,		12,	28,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_3,		12,	16,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_4,		12,	12,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_5,		12,	8,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_6,		12,	4,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_7,		12,	0,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_8,		11,	28,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_9,		11,	24,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_10,	11,	20,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_11,	11,	16,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_12,	11,	12,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_13,	11,	8,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_14,	11,	4,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_15,	11,	0,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_16,	10,	28,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_17,	10,	24,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_18,	10,	20,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_19,	10,	16,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_20,	10,	12,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_21,	10,	8,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_22,	10,	4,	15,	1,	false)
+	MUX_CFG(DA850, EMA_A_23,	10,	0,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_8,		8,	28,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_9,		8,	24,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_10,	8,	20,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_11,	8,	16,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_12,	8,	12,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_13,	8,	8,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_14,	8,	4,	15,	1,	false)
+	MUX_CFG(DA850, EMA_D_15,	8,	0,	15,	1,	false)
+	MUX_CFG(DA850, EMA_BA_1,	5,	24,	15,	1,	false)
+	MUX_CFG(DA850, EMA_CLK,		6,	0,	15,	1,	false)
+	MUX_CFG(DA850, EMA_WAIT_1,	6,	24,	15,	1,	false)
+	MUX_CFG(DA850, NEMA_CS_2,	7,	0,	15,	1,	false)
+	/* GPIO function */
+	MUX_CFG(DA850, GPIO2_15,	5,	0,	15,	8,	false)
+	MUX_CFG(DA850, GPIO8_10,	18,	28,	15,	8,	false)
+	MUX_CFG(DA850, GPIO4_0,		10,	28,	15,	8,	false)
+	MUX_CFG(DA850, GPIO4_1,		10,	24,	15,	8,	false)
+#endif
+};
+
+const short da850_uart0_pins[] __initdata = {
+	DA850_NUART0_CTS, DA850_NUART0_RTS, DA850_UART0_RXD, DA850_UART0_TXD,
+	-1
+};
+
+const short da850_uart1_pins[] __initdata = {
+	DA850_UART1_RXD, DA850_UART1_TXD,
+	-1
+};
+
+const short da850_uart2_pins[] __initdata = {
+	DA850_UART2_RXD, DA850_UART2_TXD,
+	-1
+};
+
+const short da850_i2c0_pins[] __initdata = {
+	DA850_I2C0_SDA, DA850_I2C0_SCL,
+	-1
+};
+
+const short da850_i2c1_pins[] __initdata = {
+	DA850_I2C1_SCL, DA850_I2C1_SDA,
+	-1
+};
+
+const short da850_cpgmac_pins[] __initdata = {
+	DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+	DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+	DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+	DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+	DA850_MDIO_D,
+	-1
+};
+
+const short da850_mcasp_pins[] __initdata = {
+	DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
+	DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE,
+	DA850_AXR_11, DA850_AXR_12,
+	-1
+};
+
+const short da850_lcdcntl_pins[] __initdata = {
+	DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3, DA850_LCD_D_4,
+	DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7, DA850_LCD_D_8,
+	DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11, DA850_LCD_D_12,
+	DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15, DA850_LCD_PCLK,
+	DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS, DA850_GPIO2_15,
+	DA850_GPIO8_10,
+	-1
+};
+
+const short da850_mmcsd0_pins[] __initdata = {
+	DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
+	DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
+	DA850_GPIO4_0, DA850_GPIO4_1,
+	-1
+};
+
+const short da850_nand_pins[] __initdata = {
+	DA850_EMA_D_7, DA850_EMA_D_6, DA850_EMA_D_5, DA850_EMA_D_4,
+	DA850_EMA_D_3, DA850_EMA_D_2, DA850_EMA_D_1, DA850_EMA_D_0,
+	DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4,
+	DA850_NEMA_WE, DA850_NEMA_OE,
+	-1
+};
+
+const short da850_nor_pins[] __initdata = {
+	DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2,
+	DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1,
+	DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5,
+	DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9,
+	DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13,
+	DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1,
+	DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5,
+	DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9,
+	DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
+	DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
+	DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
+	DA850_EMA_A_22, DA850_EMA_A_23,
+	-1
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 da850_default_priorities[DA850_N_CP_INTC_IRQ] = {
+	[IRQ_DA8XX_COMMTX]		= 7,
+	[IRQ_DA8XX_COMMRX]		= 7,
+	[IRQ_DA8XX_NINT]		= 7,
+	[IRQ_DA8XX_EVTOUT0]		= 7,
+	[IRQ_DA8XX_EVTOUT1]		= 7,
+	[IRQ_DA8XX_EVTOUT2]		= 7,
+	[IRQ_DA8XX_EVTOUT3]		= 7,
+	[IRQ_DA8XX_EVTOUT4]		= 7,
+	[IRQ_DA8XX_EVTOUT5]		= 7,
+	[IRQ_DA8XX_EVTOUT6]		= 7,
+	[IRQ_DA8XX_EVTOUT6]		= 7,
+	[IRQ_DA8XX_EVTOUT7]		= 7,
+	[IRQ_DA8XX_CCINT0]		= 7,
+	[IRQ_DA8XX_CCERRINT]		= 7,
+	[IRQ_DA8XX_TCERRINT0]		= 7,
+	[IRQ_DA8XX_AEMIFINT]		= 7,
+	[IRQ_DA8XX_I2CINT0]		= 7,
+	[IRQ_DA8XX_MMCSDINT0]		= 7,
+	[IRQ_DA8XX_MMCSDINT1]		= 7,
+	[IRQ_DA8XX_ALLINT0]		= 7,
+	[IRQ_DA8XX_RTC]			= 7,
+	[IRQ_DA8XX_SPINT0]		= 7,
+	[IRQ_DA8XX_TINT12_0]		= 7,
+	[IRQ_DA8XX_TINT34_0]		= 7,
+	[IRQ_DA8XX_TINT12_1]		= 7,
+	[IRQ_DA8XX_TINT34_1]		= 7,
+	[IRQ_DA8XX_UARTINT0]		= 7,
+	[IRQ_DA8XX_KEYMGRINT]		= 7,
+	[IRQ_DA8XX_SECINT]		= 7,
+	[IRQ_DA8XX_SECKEYERR]		= 7,
+	[IRQ_DA850_MPUADDRERR0]		= 7,
+	[IRQ_DA850_MPUPROTERR0]		= 7,
+	[IRQ_DA850_IOPUADDRERR0]	= 7,
+	[IRQ_DA850_IOPUPROTERR0]	= 7,
+	[IRQ_DA850_IOPUADDRERR1]	= 7,
+	[IRQ_DA850_IOPUPROTERR1]	= 7,
+	[IRQ_DA850_IOPUADDRERR2]	= 7,
+	[IRQ_DA850_IOPUPROTERR2]	= 7,
+	[IRQ_DA850_BOOTCFG_ADDR_ERR]	= 7,
+	[IRQ_DA850_BOOTCFG_PROT_ERR]	= 7,
+	[IRQ_DA850_MPUADDRERR1]		= 7,
+	[IRQ_DA850_MPUPROTERR1]		= 7,
+	[IRQ_DA850_IOPUADDRERR3]	= 7,
+	[IRQ_DA850_IOPUPROTERR3]	= 7,
+	[IRQ_DA850_IOPUADDRERR4]	= 7,
+	[IRQ_DA850_IOPUPROTERR4]	= 7,
+	[IRQ_DA850_IOPUADDRERR5]	= 7,
+	[IRQ_DA850_IOPUPROTERR5]	= 7,
+	[IRQ_DA850_MIOPU_BOOTCFG_ERR]	= 7,
+	[IRQ_DA8XX_CHIPINT0]		= 7,
+	[IRQ_DA8XX_CHIPINT1]		= 7,
+	[IRQ_DA8XX_CHIPINT2]		= 7,
+	[IRQ_DA8XX_CHIPINT3]		= 7,
+	[IRQ_DA8XX_TCERRINT1]		= 7,
+	[IRQ_DA8XX_C0_RX_THRESH_PULSE]	= 7,
+	[IRQ_DA8XX_C0_RX_PULSE]		= 7,
+	[IRQ_DA8XX_C0_TX_PULSE]		= 7,
+	[IRQ_DA8XX_C0_MISC_PULSE]	= 7,
+	[IRQ_DA8XX_C1_RX_THRESH_PULSE]	= 7,
+	[IRQ_DA8XX_C1_RX_PULSE]		= 7,
+	[IRQ_DA8XX_C1_TX_PULSE]		= 7,
+	[IRQ_DA8XX_C1_MISC_PULSE]	= 7,
+	[IRQ_DA8XX_MEMERR]		= 7,
+	[IRQ_DA8XX_GPIO0]		= 7,
+	[IRQ_DA8XX_GPIO1]		= 7,
+	[IRQ_DA8XX_GPIO2]		= 7,
+	[IRQ_DA8XX_GPIO3]		= 7,
+	[IRQ_DA8XX_GPIO4]		= 7,
+	[IRQ_DA8XX_GPIO5]		= 7,
+	[IRQ_DA8XX_GPIO6]		= 7,
+	[IRQ_DA8XX_GPIO7]		= 7,
+	[IRQ_DA8XX_GPIO8]		= 7,
+	[IRQ_DA8XX_I2CINT1]		= 7,
+	[IRQ_DA8XX_LCDINT]		= 7,
+	[IRQ_DA8XX_UARTINT1]		= 7,
+	[IRQ_DA8XX_MCASPINT]		= 7,
+	[IRQ_DA8XX_ALLINT1]		= 7,
+	[IRQ_DA8XX_SPINT1]		= 7,
+	[IRQ_DA8XX_UHPI_INT1]		= 7,
+	[IRQ_DA8XX_USB_INT]		= 7,
+	[IRQ_DA8XX_IRQN]		= 7,
+	[IRQ_DA8XX_RWAKEUP]		= 7,
+	[IRQ_DA8XX_UARTINT2]		= 7,
+	[IRQ_DA8XX_DFTSSINT]		= 7,
+	[IRQ_DA8XX_EHRPWM0]		= 7,
+	[IRQ_DA8XX_EHRPWM0TZ]		= 7,
+	[IRQ_DA8XX_EHRPWM1]		= 7,
+	[IRQ_DA8XX_EHRPWM1TZ]		= 7,
+	[IRQ_DA850_SATAINT]		= 7,
+	[IRQ_DA850_TINT12_2]		= 7,
+	[IRQ_DA850_TINT34_2]		= 7,
+	[IRQ_DA850_TINTALL_2]		= 7,
+	[IRQ_DA8XX_ECAP0]		= 7,
+	[IRQ_DA8XX_ECAP1]		= 7,
+	[IRQ_DA8XX_ECAP2]		= 7,
+	[IRQ_DA850_MMCSDINT0_1]		= 7,
+	[IRQ_DA850_MMCSDINT1_1]		= 7,
+	[IRQ_DA850_T12CMPINT0_2]	= 7,
+	[IRQ_DA850_T12CMPINT1_2]	= 7,
+	[IRQ_DA850_T12CMPINT2_2]	= 7,
+	[IRQ_DA850_T12CMPINT3_2]	= 7,
+	[IRQ_DA850_T12CMPINT4_2]	= 7,
+	[IRQ_DA850_T12CMPINT5_2]	= 7,
+	[IRQ_DA850_T12CMPINT6_2]	= 7,
+	[IRQ_DA850_T12CMPINT7_2]	= 7,
+	[IRQ_DA850_T12CMPINT0_3]	= 7,
+	[IRQ_DA850_T12CMPINT1_3]	= 7,
+	[IRQ_DA850_T12CMPINT2_3]	= 7,
+	[IRQ_DA850_T12CMPINT3_3]	= 7,
+	[IRQ_DA850_T12CMPINT4_3]	= 7,
+	[IRQ_DA850_T12CMPINT5_3]	= 7,
+	[IRQ_DA850_T12CMPINT6_3]	= 7,
+	[IRQ_DA850_T12CMPINT7_3]	= 7,
+	[IRQ_DA850_RPIINT]		= 7,
+	[IRQ_DA850_VPIFINT]		= 7,
+	[IRQ_DA850_CCINT1]		= 7,
+	[IRQ_DA850_CCERRINT1]		= 7,
+	[IRQ_DA850_TCERRINT2]		= 7,
+	[IRQ_DA850_TINT12_3]		= 7,
+	[IRQ_DA850_TINT34_3]		= 7,
+	[IRQ_DA850_TINTALL_3]		= 7,
+	[IRQ_DA850_MCBSP0RINT]		= 7,
+	[IRQ_DA850_MCBSP0XINT]		= 7,
+	[IRQ_DA850_MCBSP1RINT]		= 7,
+	[IRQ_DA850_MCBSP1XINT]		= 7,
+	[IRQ_DA8XX_ARMCLKSTOPREQ]	= 7,
+};
+
+static struct map_desc da850_io_desc[] = {
+	{
+		.virtual	= IO_VIRT,
+		.pfn		= __phys_to_pfn(IO_PHYS),
+		.length		= IO_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= DA8XX_CP_INTC_VIRT,
+		.pfn		= __phys_to_pfn(DA8XX_CP_INTC_BASE),
+		.length		= DA8XX_CP_INTC_SIZE,
+		.type		= MT_DEVICE
+	},
+};
+
+static void __iomem *da850_psc_bases[] = {
+	IO_ADDRESS(DA8XX_PSC0_BASE),
+	IO_ADDRESS(DA8XX_PSC1_BASE),
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id da850_ids[] = {
+	{
+		.variant	= 0x0,
+		.part_no	= 0xb7d1,
+		.manufacturer	= 0x017,	/* 0x02f >> 1 */
+		.cpu_id		= DAVINCI_CPU_ID_DA850,
+		.name		= "da850/omap-l138",
+	},
+};
+
+static struct davinci_timer_instance da850_timer_instance[4] = {
+	{
+		.base		= IO_ADDRESS(DA8XX_TIMER64P0_BASE),
+		.bottom_irq	= IRQ_DA8XX_TINT12_0,
+		.top_irq	= IRQ_DA8XX_TINT34_0,
+	},
+	{
+		.base		= IO_ADDRESS(DA8XX_TIMER64P1_BASE),
+		.bottom_irq	= IRQ_DA8XX_TINT12_1,
+		.top_irq	= IRQ_DA8XX_TINT34_1,
+	},
+	{
+		.base		= IO_ADDRESS(DA850_TIMER64P2_BASE),
+		.bottom_irq	= IRQ_DA850_TINT12_2,
+		.top_irq	= IRQ_DA850_TINT34_2,
+	},
+	{
+		.base		= IO_ADDRESS(DA850_TIMER64P3_BASE),
+		.bottom_irq	= IRQ_DA850_TINT12_3,
+		.top_irq	= IRQ_DA850_TINT34_3,
+	},
+};
+
+/*
+ * T0_BOT: Timer 0, bottom		: Used for clock_event
+ * T0_TOP: Timer 0, top			: Used for clocksource
+ * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ */
+static struct davinci_timer_info da850_timer_info = {
+	.timers		= da850_timer_instance,
+	.clockevent_id	= T0_BOT,
+	.clocksource_id	= T0_TOP,
+};
+
+static struct davinci_soc_info davinci_soc_info_da850 = {
+	.io_desc		= da850_io_desc,
+	.io_desc_num		= ARRAY_SIZE(da850_io_desc),
+	.jtag_id_base		= IO_ADDRESS(DA8XX_JTAG_ID_REG),
+	.ids			= da850_ids,
+	.ids_num		= ARRAY_SIZE(da850_ids),
+	.cpu_clks		= da850_clks,
+	.psc_bases		= da850_psc_bases,
+	.psc_bases_num		= ARRAY_SIZE(da850_psc_bases),
+	.pinmux_base		= IO_ADDRESS(DA8XX_BOOT_CFG_BASE + 0x120),
+	.pinmux_pins		= da850_pins,
+	.pinmux_pins_num	= ARRAY_SIZE(da850_pins),
+	.intc_base		= (void __iomem *)DA8XX_CP_INTC_VIRT,
+	.intc_type		= DAVINCI_INTC_TYPE_CP_INTC,
+	.intc_irq_prios		= da850_default_priorities,
+	.intc_irq_num		= DA850_N_CP_INTC_IRQ,
+	.timer_info		= &da850_timer_info,
+	.gpio_base		= IO_ADDRESS(DA8XX_GPIO_BASE),
+	.gpio_num		= 144,
+	.gpio_irq		= IRQ_DA8XX_GPIO0,
+	.serial_dev		= &da8xx_serial_device,
+	.emac_pdata		= &da8xx_emac_pdata,
+};
+
+void __init da850_init(void)
+{
+	davinci_common_init(&davinci_soc_info_da850);
+}
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
new file mode 100644
index 0000000..58ad5b6
--- /dev/null
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -0,0 +1,450 @@
+/*
+ * DA8XX/OMAP L1XX platform device data
+ *
+ * Copyright (c) 2007-2009, MontaVista Software, Inc. <source@mvista.com>
+ * Derived from code that was:
+ *	Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <video/da8xx-fb.h>
+
+#include "clock.h"
+
+#define DA8XX_TPCC_BASE			0x01c00000
+#define DA8XX_TPTC0_BASE		0x01c08000
+#define DA8XX_TPTC1_BASE		0x01c08400
+#define DA8XX_WDOG_BASE			0x01c21000 /* DA8XX_TIMER64P1_BASE */
+#define DA8XX_I2C0_BASE			0x01c22000
+#define DA8XX_EMAC_CPPI_PORT_BASE	0x01e20000
+#define DA8XX_EMAC_CPGMACSS_BASE	0x01e22000
+#define DA8XX_EMAC_CPGMAC_BASE		0x01e23000
+#define DA8XX_EMAC_MDIO_BASE		0x01e24000
+#define DA8XX_GPIO_BASE			0x01e26000
+#define DA8XX_I2C1_BASE			0x01e28000
+
+#define DA8XX_EMAC_CTRL_REG_OFFSET	0x3000
+#define DA8XX_EMAC_MOD_REG_OFFSET	0x2000
+#define DA8XX_EMAC_RAM_OFFSET		0x0000
+#define DA8XX_MDIO_REG_OFFSET		0x4000
+#define DA8XX_EMAC_CTRL_RAM_SIZE	SZ_8K
+
+static struct plat_serial8250_port da8xx_serial_pdata[] = {
+	{
+		.mapbase	= DA8XX_UART0_BASE,
+		.irq		= IRQ_DA8XX_UARTINT0,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+					UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	},
+	{
+		.mapbase	= DA8XX_UART1_BASE,
+		.irq		= IRQ_DA8XX_UARTINT1,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+					UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	},
+	{
+		.mapbase	= DA8XX_UART2_BASE,
+		.irq		= IRQ_DA8XX_UARTINT2,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+					UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	},
+	{
+		.flags	= 0,
+	},
+};
+
+struct platform_device da8xx_serial_device = {
+	.name	= "serial8250",
+	.id	= PLAT8250_DEV_PLATFORM,
+	.dev	= {
+		.platform_data	= da8xx_serial_pdata,
+	},
+};
+
+static const s8 da8xx_dma_chan_no_event[] = {
+	20, 21,
+	-1
+};
+
+static const s8 da8xx_queue_tc_mapping[][2] = {
+	/* {event queue no, TC no} */
+	{0, 0},
+	{1, 1},
+	{-1, -1}
+};
+
+static const s8 da8xx_queue_priority_mapping[][2] = {
+	/* {event queue no, Priority} */
+	{0, 3},
+	{1, 7},
+	{-1, -1}
+};
+
+static struct edma_soc_info da8xx_edma_info[] = {
+	{
+		.n_channel		= 32,
+		.n_region		= 4,
+		.n_slot			= 128,
+		.n_tc			= 2,
+		.n_cc			= 1,
+		.noevent		= da8xx_dma_chan_no_event,
+		.queue_tc_mapping	= da8xx_queue_tc_mapping,
+		.queue_priority_mapping	= da8xx_queue_priority_mapping,
+	},
+};
+
+static struct resource da8xx_edma_resources[] = {
+	{
+		.name	= "edma_cc0",
+		.start	= DA8XX_TPCC_BASE,
+		.end	= DA8XX_TPCC_BASE + SZ_32K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc0",
+		.start	= DA8XX_TPTC0_BASE,
+		.end	= DA8XX_TPTC0_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc1",
+		.start	= DA8XX_TPTC1_BASE,
+		.end	= DA8XX_TPTC1_BASE + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma0",
+		.start	= IRQ_DA8XX_CCINT0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "edma0_err",
+		.start	= IRQ_DA8XX_CCERRINT,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device da8xx_edma_device = {
+	.name		= "edma",
+	.id		= -1,
+	.dev = {
+		.platform_data	= da8xx_edma_info,
+	},
+	.num_resources	= ARRAY_SIZE(da8xx_edma_resources),
+	.resource	= da8xx_edma_resources,
+};
+
+int __init da8xx_register_edma(void)
+{
+	return platform_device_register(&da8xx_edma_device);
+}
+
+static struct resource da8xx_i2c_resources0[] = {
+	{
+		.start	= DA8XX_I2C0_BASE,
+		.end	= DA8XX_I2C0_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_DA8XX_I2CINT0,
+		.end	= IRQ_DA8XX_I2CINT0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device da8xx_i2c_device0 = {
+	.name		= "i2c_davinci",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(da8xx_i2c_resources0),
+	.resource	= da8xx_i2c_resources0,
+};
+
+static struct resource da8xx_i2c_resources1[] = {
+	{
+		.start	= DA8XX_I2C1_BASE,
+		.end	= DA8XX_I2C1_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_DA8XX_I2CINT1,
+		.end	= IRQ_DA8XX_I2CINT1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device da8xx_i2c_device1 = {
+	.name		= "i2c_davinci",
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(da8xx_i2c_resources1),
+	.resource	= da8xx_i2c_resources1,
+};
+
+int __init da8xx_register_i2c(int instance,
+		struct davinci_i2c_platform_data *pdata)
+{
+	struct platform_device *pdev;
+
+	if (instance == 0)
+		pdev = &da8xx_i2c_device0;
+	else if (instance == 1)
+		pdev = &da8xx_i2c_device1;
+	else
+		return -EINVAL;
+
+	pdev->dev.platform_data = pdata;
+	return platform_device_register(pdev);
+}
+
+static struct resource da8xx_watchdog_resources[] = {
+	{
+		.start	= DA8XX_WDOG_BASE,
+		.end	= DA8XX_WDOG_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device davinci_wdt_device = {
+	.name		= "watchdog",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(da8xx_watchdog_resources),
+	.resource	= da8xx_watchdog_resources,
+};
+
+int __init da8xx_register_watchdog(void)
+{
+	return platform_device_register(&davinci_wdt_device);
+}
+
+static struct resource da8xx_emac_resources[] = {
+	{
+		.start	= DA8XX_EMAC_CPPI_PORT_BASE,
+		.end	= DA8XX_EMAC_CPPI_PORT_BASE + 0x5000 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_DA8XX_C0_RX_THRESH_PULSE,
+		.end	= IRQ_DA8XX_C0_RX_THRESH_PULSE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_C0_RX_PULSE,
+		.end	= IRQ_DA8XX_C0_RX_PULSE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_C0_TX_PULSE,
+		.end	= IRQ_DA8XX_C0_TX_PULSE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DA8XX_C0_MISC_PULSE,
+		.end	= IRQ_DA8XX_C0_MISC_PULSE,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct emac_platform_data da8xx_emac_pdata = {
+	.ctrl_reg_offset	= DA8XX_EMAC_CTRL_REG_OFFSET,
+	.ctrl_mod_reg_offset	= DA8XX_EMAC_MOD_REG_OFFSET,
+	.ctrl_ram_offset	= DA8XX_EMAC_RAM_OFFSET,
+	.mdio_reg_offset	= DA8XX_MDIO_REG_OFFSET,
+	.ctrl_ram_size		= DA8XX_EMAC_CTRL_RAM_SIZE,
+	.version		= EMAC_VERSION_2,
+};
+
+static struct platform_device da8xx_emac_device = {
+	.name		= "davinci_emac",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &da8xx_emac_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(da8xx_emac_resources),
+	.resource	= da8xx_emac_resources,
+};
+
+static struct resource da830_mcasp1_resources[] = {
+	{
+		.name	= "mcasp1",
+		.start	= DAVINCI_DA830_MCASP1_REG_BASE,
+		.end	= DAVINCI_DA830_MCASP1_REG_BASE + (SZ_1K * 12) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	/* TX event */
+	{
+		.start	= DAVINCI_DA830_DMA_MCASP1_AXEVT,
+		.end	= DAVINCI_DA830_DMA_MCASP1_AXEVT,
+		.flags	= IORESOURCE_DMA,
+	},
+	/* RX event */
+	{
+		.start	= DAVINCI_DA830_DMA_MCASP1_AREVT,
+		.end	= DAVINCI_DA830_DMA_MCASP1_AREVT,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device da830_mcasp1_device = {
+	.name		= "davinci-mcasp",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(da830_mcasp1_resources),
+	.resource	= da830_mcasp1_resources,
+};
+
+static struct resource da850_mcasp_resources[] = {
+	{
+		.name	= "mcasp",
+		.start	= DAVINCI_DA8XX_MCASP0_REG_BASE,
+		.end	= DAVINCI_DA8XX_MCASP0_REG_BASE + (SZ_1K * 12) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	/* TX event */
+	{
+		.start	= DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+		.end	= DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+		.flags	= IORESOURCE_DMA,
+	},
+	/* RX event */
+	{
+		.start	= DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+		.end	= DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device da850_mcasp_device = {
+	.name		= "davinci-mcasp",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(da850_mcasp_resources),
+	.resource	= da850_mcasp_resources,
+};
+
+int __init da8xx_register_emac(void)
+{
+	return platform_device_register(&da8xx_emac_device);
+}
+
+void __init da8xx_init_mcasp(int id, struct snd_platform_data *pdata)
+{
+	/* DA830/OMAP-L137 has 3 instances of McASP */
+	if (cpu_is_davinci_da830() && id == 1) {
+		da830_mcasp1_device.dev.platform_data = pdata;
+		platform_device_register(&da830_mcasp1_device);
+	} else if (cpu_is_davinci_da850()) {
+		da850_mcasp_device.dev.platform_data = pdata;
+		platform_device_register(&da850_mcasp_device);
+	}
+}
+
+static const struct display_panel disp_panel = {
+	QVGA,
+	16,
+	16,
+	COLOR_ACTIVE,
+};
+
+static struct lcd_ctrl_config lcd_cfg = {
+	&disp_panel,
+	.ac_bias		= 255,
+	.ac_bias_intrpt		= 0,
+	.dma_burst_sz		= 16,
+	.bpp			= 16,
+	.fdd			= 255,
+	.tft_alt_mode		= 0,
+	.stn_565_mode		= 0,
+	.mono_8bit_mode		= 0,
+	.invert_line_clock	= 1,
+	.invert_frm_clock	= 1,
+	.sync_edge		= 0,
+	.sync_ctrl		= 1,
+	.raster_order		= 0,
+};
+
+static struct da8xx_lcdc_platform_data da850_evm_lcdc_pdata = {
+	.manu_name = "sharp",
+	.controller_data = &lcd_cfg,
+	.type = "Sharp_LK043T1DG01",
+};
+
+static struct resource da8xx_lcdc_resources[] = {
+	[0] = { /* registers */
+		.start  = DA8XX_LCD_CNTRL_BASE,
+		.end    = DA8XX_LCD_CNTRL_BASE + SZ_4K - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = { /* interrupt */
+		.start  = IRQ_DA8XX_LCDINT,
+		.end    = IRQ_DA8XX_LCDINT,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device da850_lcdc_device = {
+	.name		= "da8xx_lcdc",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(da8xx_lcdc_resources),
+	.resource	= da8xx_lcdc_resources,
+	.dev = {
+		.platform_data = &da850_evm_lcdc_pdata,
+	}
+};
+
+int __init da8xx_register_lcdc(void)
+{
+	return platform_device_register(&da850_lcdc_device);
+}
+
+static struct resource da8xx_mmcsd0_resources[] = {
+	{		/* registers */
+		.start	= DA8XX_MMCSD0_BASE,
+		.end	= DA8XX_MMCSD0_BASE + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{		/* interrupt */
+		.start	= IRQ_DA8XX_MMCSDINT0,
+		.end	= IRQ_DA8XX_MMCSDINT0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{		/* DMA RX */
+		.start	= EDMA_CTLR_CHAN(0, 16),
+		.end	= EDMA_CTLR_CHAN(0, 16),
+		.flags	= IORESOURCE_DMA,
+	},
+	{		/* DMA TX */
+		.start	= EDMA_CTLR_CHAN(0, 17),
+		.end	= EDMA_CTLR_CHAN(0, 17),
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device da8xx_mmcsd0_device = {
+	.name		= "davinci_mmc",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(da8xx_mmcsd0_resources),
+	.resource	= da8xx_mmcsd0_resources,
+};
+
+int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config)
+{
+	da8xx_mmcsd0_device.dev.platform_data = config;
+	return platform_device_register(&da8xx_mmcsd0_device);
+}
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index de16f34..a55b650 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -31,6 +31,8 @@
 #define DAVINCI_MMCSD0_BASE	     0x01E10000
 #define DM355_MMCSD0_BASE	     0x01E11000
 #define DM355_MMCSD1_BASE	     0x01E00000
+#define DM365_MMCSD0_BASE	     0x01D11000
+#define DM365_MMCSD1_BASE	     0x01D00000
 
 static struct resource i2c_resources[] = {
 	{
@@ -82,10 +84,10 @@ static struct resource mmcsd0_resources[] = {
 	},
 	/* DMA channels: RX, then TX */
 	{
-		.start = DAVINCI_DMA_MMCRXEVT,
+		.start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT),
 		.flags = IORESOURCE_DMA,
 	}, {
-		.start = DAVINCI_DMA_MMCTXEVT,
+		.start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT),
 		.flags = IORESOURCE_DMA,
 	},
 };
@@ -119,10 +121,10 @@ static struct resource mmcsd1_resources[] = {
 	},
 	/* DMA channels: RX, then TX */
 	{
-		.start = 30,	/* rx */
+		.start = EDMA_CTLR_CHAN(0, 30),	/* rx */
 		.flags = IORESOURCE_DMA,
 	}, {
-		.start = 31,	/* tx */
+		.start = EDMA_CTLR_CHAN(0, 31),	/* tx */
 		.flags = IORESOURCE_DMA,
 	},
 };
@@ -154,19 +156,31 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
 	 */
 	switch (module) {
 	case 1:
-		if (!cpu_is_davinci_dm355())
+		if (cpu_is_davinci_dm355()) {
+			/* REVISIT we may not need all these pins if e.g. this
+			 * is a hard-wired SDIO device...
+			 */
+			davinci_cfg_reg(DM355_SD1_CMD);
+			davinci_cfg_reg(DM355_SD1_CLK);
+			davinci_cfg_reg(DM355_SD1_DATA0);
+			davinci_cfg_reg(DM355_SD1_DATA1);
+			davinci_cfg_reg(DM355_SD1_DATA2);
+			davinci_cfg_reg(DM355_SD1_DATA3);
+		} else if (cpu_is_davinci_dm365()) {
+			void __iomem *pupdctl1 =
+				IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c);
+
+			/* Configure pull down control */
+			__raw_writel((__raw_readl(pupdctl1) & ~0x400),
+					pupdctl1);
+
+			mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
+			mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
+							SZ_4K - 1;
+			mmcsd0_resources[2].start = IRQ_DM365_SDIOINT1;
+		} else
 			break;
 
-		/* REVISIT we may not need all these pins if e.g. this
-		 * is a hard-wired SDIO device...
-		 */
-		davinci_cfg_reg(DM355_SD1_CMD);
-		davinci_cfg_reg(DM355_SD1_CLK);
-		davinci_cfg_reg(DM355_SD1_DATA0);
-		davinci_cfg_reg(DM355_SD1_DATA1);
-		davinci_cfg_reg(DM355_SD1_DATA2);
-		davinci_cfg_reg(DM355_SD1_DATA3);
-
 		pdev = &davinci_mmcsd1_device;
 		break;
 	case 0:
@@ -180,9 +194,12 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
 
 			/* enable RX EDMA */
 			davinci_cfg_reg(DM355_EVT26_MMC0_RX);
-		}
-
-		else if (cpu_is_davinci_dm644x()) {
+		} else if (cpu_is_davinci_dm365()) {
+			mmcsd0_resources[0].start = DM365_MMCSD0_BASE;
+			mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
+							SZ_4K - 1;
+			mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
+		} else if (cpu_is_davinci_dm644x()) {
 			/* REVISIT: should this be in board-init code? */
 			void __iomem *base =
 				IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
@@ -216,6 +233,8 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
 
 static struct resource wdt_resources[] = {
 	{
+		.start	= DAVINCI_WDOG_BASE,
+		.end	= DAVINCI_WDOG_BASE + SZ_1K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 };
@@ -229,11 +248,6 @@ struct platform_device davinci_wdt_device = {
 
 static void davinci_init_wdt(void)
 {
-	struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-	wdt_resources[0].start = (resource_size_t)soc_info->wdt_base;
-	wdt_resources[0].end = (resource_size_t)soc_info->wdt_base + SZ_1K - 1;
-
 	platform_device_register(&davinci_wdt_device);
 }
 
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index baaaf32..0596700 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -30,6 +30,7 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
+#include <mach/asp.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -360,8 +361,8 @@ static struct davinci_clk dm355_clks[] = {
 	CLK(NULL, "uart1", &uart1_clk),
 	CLK(NULL, "uart2", &uart2_clk),
 	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("soc-audio.0", NULL, &asp0_clk),
-	CLK("soc-audio.1", NULL, &asp1_clk),
+	CLK("davinci-asp.0", NULL, &asp0_clk),
+	CLK("davinci-asp.1", NULL, &asp1_clk),
 	CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
 	CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
 	CLK(NULL, "spi0", &spi0_clk),
@@ -481,6 +482,20 @@ INT_CFG(DM355,  INT_EDMA_TC1_ERR,     4,    1,    1,     false)
 EVT_CFG(DM355,  EVT8_ASP1_TX,	      0,    1,    0,     false)
 EVT_CFG(DM355,  EVT9_ASP1_RX,	      1,    1,    0,     false)
 EVT_CFG(DM355,  EVT26_MMC0_RX,	      2,    1,    0,     false)
+
+MUX_CFG(DM355,	VOUT_FIELD,	1,   18,    3,	  1,	 false)
+MUX_CFG(DM355,	VOUT_FIELD_G70,	1,   18,    3,	  0,	 false)
+MUX_CFG(DM355,	VOUT_HVSYNC,	1,   16,    1,	  0,	 false)
+MUX_CFG(DM355,	VOUT_COUTL_EN,	1,   0,     0xff, 0x55,  false)
+MUX_CFG(DM355,	VOUT_COUTH_EN,	1,   8,     0xff, 0x55,  false)
+
+MUX_CFG(DM355,	VIN_PCLK,	0,   14,    1,    1,	 false)
+MUX_CFG(DM355,	VIN_CAM_WEN,	0,   13,    1,    1,	 false)
+MUX_CFG(DM355,	VIN_CAM_VD,	0,   12,    1,    1,	 false)
+MUX_CFG(DM355,	VIN_CAM_HD,	0,   11,    1,    1,	 false)
+MUX_CFG(DM355,	VIN_YIN_EN,	0,   10,    1,    1,	 false)
+MUX_CFG(DM355,	VIN_CINL_EN,	0,   0,   0xff, 0x55,	 false)
+MUX_CFG(DM355,	VIN_CINH_EN,	0,   8,     3,    3,	 false)
 #endif
 };
 
@@ -558,17 +573,38 @@ static const s8 dma_chan_dm355_no_event[] = {
 	-1
 };
 
-static struct edma_soc_info dm355_edma_info = {
-	.n_channel	= 64,
-	.n_region	= 4,
-	.n_slot		= 128,
-	.n_tc		= 2,
-	.noevent	= dma_chan_dm355_no_event,
+static const s8
+queue_tc_mapping[][2] = {
+	/* {event queue no, TC no} */
+	{0, 0},
+	{1, 1},
+	{-1, -1},
+};
+
+static const s8
+queue_priority_mapping[][2] = {
+	/* {event queue no, Priority} */
+	{0, 3},
+	{1, 7},
+	{-1, -1},
+};
+
+static struct edma_soc_info dm355_edma_info[] = {
+	{
+		.n_channel		= 64,
+		.n_region		= 4,
+		.n_slot			= 128,
+		.n_tc			= 2,
+		.n_cc			= 1,
+		.noevent		= dma_chan_dm355_no_event,
+		.queue_tc_mapping	= queue_tc_mapping,
+		.queue_priority_mapping	= queue_priority_mapping,
+	},
 };
 
 static struct resource edma_resources[] = {
 	{
-		.name	= "edma_cc",
+		.name	= "edma_cc0",
 		.start	= 0x01c00000,
 		.end	= 0x01c00000 + SZ_64K - 1,
 		.flags	= IORESOURCE_MEM,
@@ -586,10 +622,12 @@ static struct resource edma_resources[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 	{
+		.name	= "edma0",
 		.start	= IRQ_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
+		.name	= "edma0_err",
 		.start	= IRQ_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -598,12 +636,98 @@ static struct resource edma_resources[] = {
 
 static struct platform_device dm355_edma_device = {
 	.name			= "edma",
-	.id			= -1,
-	.dev.platform_data	= &dm355_edma_info,
+	.id			= 0,
+	.dev.platform_data	= dm355_edma_info,
 	.num_resources		= ARRAY_SIZE(edma_resources),
 	.resource		= edma_resources,
 };
 
+static struct resource dm355_asp1_resources[] = {
+	{
+		.start	= DAVINCI_ASP1_BASE,
+		.end	= DAVINCI_ASP1_BASE + SZ_8K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP1_TX,
+		.end	= DAVINCI_DMA_ASP1_TX,
+		.flags	= IORESOURCE_DMA,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP1_RX,
+		.end	= DAVINCI_DMA_ASP1_RX,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device dm355_asp1_device = {
+	.name		= "davinci-asp",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(dm355_asp1_resources),
+	.resource	= dm355_asp1_resources,
+};
+
+static struct resource dm355_vpss_resources[] = {
+	{
+		/* VPSS BL Base address */
+		.name		= "vpss",
+		.start          = 0x01c70800,
+		.end            = 0x01c70800 + 0xff,
+		.flags          = IORESOURCE_MEM,
+	},
+	{
+		/* VPSS CLK Base address */
+		.name		= "vpss",
+		.start          = 0x01c70000,
+		.end            = 0x01c70000 + 0xf,
+		.flags          = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dm355_vpss_device = {
+	.name			= "vpss",
+	.id			= -1,
+	.dev.platform_data	= "dm355_vpss",
+	.num_resources		= ARRAY_SIZE(dm355_vpss_resources),
+	.resource		= dm355_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+	{
+		.start          = IRQ_VDINT0,
+		.end            = IRQ_VDINT0,
+		.flags          = IORESOURCE_IRQ,
+	},
+	{
+		.start          = IRQ_VDINT1,
+		.end            = IRQ_VDINT1,
+		.flags          = IORESOURCE_IRQ,
+	},
+	/* CCDC Base address */
+	{
+		.flags          = IORESOURCE_MEM,
+		.start          = 0x01c70600,
+		.end            = 0x01c70600 + 0x1ff,
+	},
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device vpfe_capture_dev = {
+	.name		= CAPTURE_DRV_NAME,
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(vpfe_resources),
+	.resource	= vpfe_resources,
+	.dev = {
+		.dma_mask		= &vpfe_capture_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void dm355_set_vpfe_config(struct vpfe_config *cfg)
+{
+	vpfe_capture_dev.dev.platform_data = cfg;
+}
+
 /*----------------------------------------------------------------------*/
 
 static struct map_desc dm355_io_desc[] = {
@@ -704,7 +828,6 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
 	.intc_irq_prios		= dm355_default_priorities,
 	.intc_irq_num		= DAVINCI_N_AINTC_IRQ,
 	.timer_info		= &dm355_timer_info,
-	.wdt_base		= IO_ADDRESS(DAVINCI_WDOG_BASE),
 	.gpio_base		= IO_ADDRESS(DAVINCI_GPIO_BASE),
 	.gpio_num		= 104,
 	.gpio_irq		= IRQ_DM355_GPIOBNK0,
@@ -713,6 +836,19 @@ static struct davinci_soc_info davinci_soc_info_dm355 = {
 	.sram_len		= SZ_32K,
 };
 
+void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata)
+{
+	/* we don't use ASP1 IRQs, or we'd need to mux them ... */
+	if (evt_enable & ASP1_TX_EVT_EN)
+		davinci_cfg_reg(DM355_EVT8_ASP1_TX);
+
+	if (evt_enable & ASP1_RX_EVT_EN)
+		davinci_cfg_reg(DM355_EVT9_ASP1_RX);
+
+	dm355_asp1_device.dev.platform_data = pdata;
+	platform_device_register(&dm355_asp1_device);
+}
+
 void __init dm355_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm355);
@@ -725,6 +861,20 @@ static int __init dm355_init_devices(void)
 
 	davinci_cfg_reg(DM355_INT_EDMA_CC);
 	platform_device_register(&dm355_edma_device);
+	platform_device_register(&dm355_vpss_device);
+	/*
+	 * setup Mux configuration for vpfe input and register
+	 * vpfe capture platform device
+	 */
+	davinci_cfg_reg(DM355_VIN_PCLK);
+	davinci_cfg_reg(DM355_VIN_CAM_WEN);
+	davinci_cfg_reg(DM355_VIN_CAM_VD);
+	davinci_cfg_reg(DM355_VIN_CAM_HD);
+	davinci_cfg_reg(DM355_VIN_YIN_EN);
+	davinci_cfg_reg(DM355_VIN_CINL_EN);
+	davinci_cfg_reg(DM355_VIN_CINH_EN);
+	platform_device_register(&vpfe_capture_dev);
+
 	return 0;
 }
 postcore_initcall(dm355_init_devices);
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
new file mode 100644
index 0000000..e815174
--- /dev/null
+++ b/arch/arm/mach-davinci/dm365.c
@@ -0,0 +1,926 @@
+/*
+ * TI DaVinci DM365 chip specific setup
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; 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/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm365.h>
+#include <mach/clock.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+
+#include "clock.h"
+#include "mux.h"
+
+#define DM365_REF_FREQ		24000000	/* 24 MHz on the DM365 EVM */
+
+static struct pll_data pll1_data = {
+	.num		= 1,
+	.phys_base	= DAVINCI_PLL1_BASE,
+	.flags		= PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
+};
+
+static struct pll_data pll2_data = {
+	.num		= 2,
+	.phys_base	= DAVINCI_PLL2_BASE,
+	.flags		= PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
+};
+
+static struct clk ref_clk = {
+	.name		= "ref_clk",
+	.rate		= DM365_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+	.name		= "pll1",
+	.parent		= &ref_clk,
+	.flags		= CLK_PLL,
+	.pll_data	= &pll1_data,
+};
+
+static struct clk pll1_aux_clk = {
+	.name		= "pll1_aux_clk",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclkbp = {
+	.name		= "pll1_sysclkbp",
+	.parent		= &pll1_clk,
+	.flags 		= CLK_PLL | PRE_PLL,
+	.div_reg	= BPDIV
+};
+
+static struct clk clkout0_clk = {
+	.name		= "clkout0",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+	.name		= "pll1_sysclk1",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+	.name		= "pll1_sysclk2",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+	.name		= "pll1_sysclk3",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+	.name		= "pll1_sysclk4",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+	.name		= "pll1_sysclk5",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+	.name		= "pll1_sysclk6",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV6,
+};
+
+static struct clk pll1_sysclk7 = {
+	.name		= "pll1_sysclk7",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV7,
+};
+
+static struct clk pll1_sysclk8 = {
+	.name		= "pll1_sysclk8",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV8,
+};
+
+static struct clk pll1_sysclk9 = {
+	.name		= "pll1_sysclk9",
+	.parent		= &pll1_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV9,
+};
+
+static struct clk pll2_clk = {
+	.name		= "pll2",
+	.parent		= &ref_clk,
+	.flags		= CLK_PLL,
+	.pll_data	= &pll2_data,
+};
+
+static struct clk pll2_aux_clk = {
+	.name		= "pll2_aux_clk",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL | PRE_PLL,
+};
+
+static struct clk clkout1_clk = {
+	.name		= "clkout1",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+	.name		= "pll2_sysclk1",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV1,
+};
+
+static struct clk pll2_sysclk2 = {
+	.name		= "pll2_sysclk2",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV2,
+};
+
+static struct clk pll2_sysclk3 = {
+	.name		= "pll2_sysclk3",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV3,
+};
+
+static struct clk pll2_sysclk4 = {
+	.name		= "pll2_sysclk4",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV4,
+};
+
+static struct clk pll2_sysclk5 = {
+	.name		= "pll2_sysclk5",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV5,
+};
+
+static struct clk pll2_sysclk6 = {
+	.name		= "pll2_sysclk6",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV6,
+};
+
+static struct clk pll2_sysclk7 = {
+	.name		= "pll2_sysclk7",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV7,
+};
+
+static struct clk pll2_sysclk8 = {
+	.name		= "pll2_sysclk8",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV8,
+};
+
+static struct clk pll2_sysclk9 = {
+	.name		= "pll2_sysclk9",
+	.parent		= &pll2_clk,
+	.flags		= CLK_PLL,
+	.div_reg	= PLLDIV9,
+};
+
+static struct clk vpss_dac_clk = {
+	.name		= "vpss_dac",
+	.parent		= &pll1_sysclk3,
+	.lpsc		= DM365_LPSC_DAC_CLK,
+};
+
+static struct clk vpss_master_clk = {
+	.name		= "vpss_master",
+	.parent		= &pll1_sysclk5,
+	.lpsc		= DM365_LPSC_VPSSMSTR,
+	.flags		= CLK_PSC,
+};
+
+static struct clk arm_clk = {
+	.name		= "arm_clk",
+	.parent		= &pll2_sysclk2,
+	.lpsc		= DAVINCI_LPSC_ARM,
+	.flags		= ALWAYS_ENABLED,
+};
+
+static struct clk uart0_clk = {
+	.name		= "uart0",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+	.name		= "uart1",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DAVINCI_LPSC_UART1,
+};
+
+static struct clk i2c_clk = {
+	.name		= "i2c",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_I2C,
+};
+
+static struct clk mmcsd0_clk = {
+	.name		= "mmcsd0",
+	.parent		= &pll1_sysclk8,
+	.lpsc		= DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk mmcsd1_clk = {
+	.name		= "mmcsd1",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DM365_LPSC_MMC_SD1,
+};
+
+static struct clk spi0_clk = {
+	.name		= "spi0",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DAVINCI_LPSC_SPI,
+};
+
+static struct clk spi1_clk = {
+	.name		= "spi1",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DM365_LPSC_SPI1,
+};
+
+static struct clk spi2_clk = {
+	.name		= "spi2",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DM365_LPSC_SPI2,
+};
+
+static struct clk spi3_clk = {
+	.name		= "spi3",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DM365_LPSC_SPI3,
+};
+
+static struct clk spi4_clk = {
+	.name		= "spi4",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DM365_LPSC_SPI4,
+};
+
+static struct clk gpio_clk = {
+	.name		= "gpio",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DAVINCI_LPSC_GPIO,
+};
+
+static struct clk aemif_clk = {
+	.name		= "aemif",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+	.name		= "pwm0",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+	.name		= "pwm1",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+	.name		= "pwm2",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_PWM2,
+};
+
+static struct clk pwm3_clk = {
+	.name		= "pwm3",
+	.parent		= &ref_clk,
+	.lpsc		= DM365_LPSC_PWM3,
+};
+
+static struct clk timer0_clk = {
+	.name		= "timer0",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+	.name		= "timer1",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+	.name		= "timer2",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DAVINCI_LPSC_TIMER2,
+	.usecount	= 1,
+};
+
+static struct clk timer3_clk = {
+	.name		= "timer3",
+	.parent		= &pll1_aux_clk,
+	.lpsc		= DM365_LPSC_TIMER3,
+};
+
+static struct clk usb_clk = {
+	.name		= "usb",
+	.parent		= &pll2_sysclk1,
+	.lpsc		= DAVINCI_LPSC_USB,
+};
+
+static struct clk emac_clk = {
+	.name		= "emac",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DM365_LPSC_EMAC,
+};
+
+static struct clk voicecodec_clk = {
+	.name		= "voice_codec",
+	.parent		= &pll2_sysclk4,
+	.lpsc		= DM365_LPSC_VOICE_CODEC,
+};
+
+static struct clk asp0_clk = {
+	.name		= "asp0",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DM365_LPSC_McBSP1,
+};
+
+static struct clk rto_clk = {
+	.name		= "rto",
+	.parent		= &pll1_sysclk4,
+	.lpsc		= DM365_LPSC_RTO,
+};
+
+static struct clk mjcp_clk = {
+	.name		= "mjcp",
+	.parent		= &pll1_sysclk3,
+	.lpsc		= DM365_LPSC_MJCP,
+};
+
+static struct davinci_clk dm365_clks[] = {
+	CLK(NULL, "ref", &ref_clk),
+	CLK(NULL, "pll1", &pll1_clk),
+	CLK(NULL, "pll1_aux", &pll1_aux_clk),
+	CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+	CLK(NULL, "clkout0", &clkout0_clk),
+	CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+	CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+	CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+	CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+	CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+	CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
+	CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+	CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
+	CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
+	CLK(NULL, "pll2", &pll2_clk),
+	CLK(NULL, "pll2_aux", &pll2_aux_clk),
+	CLK(NULL, "clkout1", &clkout1_clk),
+	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+	CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
+	CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
+	CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
+	CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
+	CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
+	CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
+	CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
+	CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
+	CLK(NULL, "vpss_dac", &vpss_dac_clk),
+	CLK(NULL, "vpss_master", &vpss_master_clk),
+	CLK(NULL, "arm", &arm_clk),
+	CLK(NULL, "uart0", &uart0_clk),
+	CLK(NULL, "uart1", &uart1_clk),
+	CLK("i2c_davinci.1", NULL, &i2c_clk),
+	CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+	CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+	CLK("spi_davinci.0", NULL, &spi0_clk),
+	CLK("spi_davinci.1", NULL, &spi1_clk),
+	CLK("spi_davinci.2", NULL, &spi2_clk),
+	CLK("spi_davinci.3", NULL, &spi3_clk),
+	CLK("spi_davinci.4", NULL, &spi4_clk),
+	CLK(NULL, "gpio", &gpio_clk),
+	CLK(NULL, "aemif", &aemif_clk),
+	CLK(NULL, "pwm0", &pwm0_clk),
+	CLK(NULL, "pwm1", &pwm1_clk),
+	CLK(NULL, "pwm2", &pwm2_clk),
+	CLK(NULL, "pwm3", &pwm3_clk),
+	CLK(NULL, "timer0", &timer0_clk),
+	CLK(NULL, "timer1", &timer1_clk),
+	CLK("watchdog", NULL, &timer2_clk),
+	CLK(NULL, "timer3", &timer3_clk),
+	CLK(NULL, "usb", &usb_clk),
+	CLK("davinci_emac.1", NULL, &emac_clk),
+	CLK("voice_codec", NULL, &voicecodec_clk),
+	CLK("soc-audio.0", NULL, &asp0_clk),
+	CLK(NULL, "rto", &rto_clk),
+	CLK(NULL, "mjcp", &mjcp_clk),
+	CLK(NULL, NULL, NULL),
+};
+
+/*----------------------------------------------------------------------*/
+
+#define PINMUX0		0x00
+#define PINMUX1		0x04
+#define PINMUX2		0x08
+#define PINMUX3		0x0c
+#define PINMUX4		0x10
+#define INTMUX		0x18
+#define EVTMUX		0x1c
+
+
+static const struct mux_config dm365_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM365,	MMCSD0,		0,   24,     1,	  0,	 false)
+
+MUX_CFG(DM365,	SD1_CLK,	0,   16,    3,	  1,	 false)
+MUX_CFG(DM365,	SD1_CMD,	4,   30,    3,	  1,	 false)
+MUX_CFG(DM365,	SD1_DATA3,	4,   28,    3,	  1,	 false)
+MUX_CFG(DM365,	SD1_DATA2,	4,   26,    3,	  1,	 false)
+MUX_CFG(DM365,	SD1_DATA1,	4,   24,    3,	  1,	 false)
+MUX_CFG(DM365,	SD1_DATA0,	4,   22,    3,	  1,	 false)
+
+MUX_CFG(DM365,	I2C_SDA,	3,   23,    3,	  2,	 false)
+MUX_CFG(DM365,	I2C_SCL,	3,   21,    3,	  2,	 false)
+
+MUX_CFG(DM365,	AEMIF_AR,	2,   0,     3,	  1,	 false)
+MUX_CFG(DM365,	AEMIF_A3,	2,   2,     3,	  1,	 false)
+MUX_CFG(DM365,	AEMIF_A7,	2,   4,     3,	  1,	 false)
+MUX_CFG(DM365,	AEMIF_D15_8,	2,   6,     1,	  1,	 false)
+MUX_CFG(DM365,	AEMIF_CE0,	2,   7,     1,	  0,	 false)
+
+MUX_CFG(DM365,	MCBSP0_BDX,	0,   23,    1,	  1,	 false)
+MUX_CFG(DM365,	MCBSP0_X,	0,   22,    1,	  1,	 false)
+MUX_CFG(DM365,	MCBSP0_BFSX,	0,   21,    1,	  1,	 false)
+MUX_CFG(DM365,	MCBSP0_BDR,	0,   20,    1,	  1,	 false)
+MUX_CFG(DM365,	MCBSP0_R,	0,   19,    1,	  1,	 false)
+MUX_CFG(DM365,	MCBSP0_BFSR,	0,   18,    1,	  1,	 false)
+
+MUX_CFG(DM365,	SPI0_SCLK,	3,   28,    1,    1,	 false)
+MUX_CFG(DM365,	SPI0_SDI,	3,   26,    3,    1,	 false)
+MUX_CFG(DM365,	SPI0_SDO,	3,   25,    1,    1,	 false)
+MUX_CFG(DM365,	SPI0_SDENA0,	3,   29,    3,    1,	 false)
+MUX_CFG(DM365,	SPI0_SDENA1,	3,   26,    3,    2,	 false)
+
+MUX_CFG(DM365,	UART0_RXD,	3,   20,    1,    1,	 false)
+MUX_CFG(DM365,	UART0_TXD,	3,   19,    1,    1,	 false)
+MUX_CFG(DM365,	UART1_RXD,	3,   17,    3,    2,	 false)
+MUX_CFG(DM365,	UART1_TXD,	3,   15,    3,    2,	 false)
+MUX_CFG(DM365,	UART1_RTS,	3,   23,    3,    1,	 false)
+MUX_CFG(DM365,	UART1_CTS,	3,   21,    3,    1,	 false)
+
+MUX_CFG(DM365,  EMAC_TX_EN,	3,   17,    3,    1,     false)
+MUX_CFG(DM365,  EMAC_TX_CLK,	3,   15,    3,    1,     false)
+MUX_CFG(DM365,  EMAC_COL,	3,   14,    1,    1,     false)
+MUX_CFG(DM365,  EMAC_TXD3,	3,   13,    1,    1,     false)
+MUX_CFG(DM365,  EMAC_TXD2,	3,   12,    1,    1,     false)
+MUX_CFG(DM365,  EMAC_TXD1,	3,   11,    1,    1,     false)
+MUX_CFG(DM365,  EMAC_TXD0,	3,   10,    1,    1,     false)
+MUX_CFG(DM365,  EMAC_RXD3,	3,   9,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_RXD2,	3,   8,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_RXD1,	3,   7,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_RXD0,	3,   6,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_RX_CLK,	3,   5,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_RX_DV,	3,   4,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_RX_ER,	3,   3,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_CRS,	3,   2,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_MDIO,	3,   1,     1,    1,     false)
+MUX_CFG(DM365,  EMAC_MDCLK,	3,   0,     1,    1,     false)
+
+MUX_CFG(DM365,	KEYPAD,		2,   0,     0x3f, 0x3f,  false)
+
+MUX_CFG(DM365,	PWM0,		1,   0,     3,    2,     false)
+MUX_CFG(DM365,	PWM0_G23,	3,   26,    3,    3,     false)
+MUX_CFG(DM365,	PWM1,		1,   2,     3,    2,     false)
+MUX_CFG(DM365,	PWM1_G25,	3,   29,    3,    2,     false)
+MUX_CFG(DM365,	PWM2_G87,	1,   10,    3,    2,     false)
+MUX_CFG(DM365,	PWM2_G88,	1,   8,     3,    2,     false)
+MUX_CFG(DM365,	PWM2_G89,	1,   6,     3,    2,     false)
+MUX_CFG(DM365,	PWM2_G90,	1,   4,     3,    2,     false)
+MUX_CFG(DM365,	PWM3_G80,	1,   20,    3,    3,     false)
+MUX_CFG(DM365,	PWM3_G81,	1,   18,    3,    3,     false)
+MUX_CFG(DM365,	PWM3_G85,	1,   14,    3,    2,     false)
+MUX_CFG(DM365,	PWM3_G86,	1,   12,    3,    2,     false)
+
+MUX_CFG(DM365,	SPI1_SCLK,	4,   2,     3,    1,	 false)
+MUX_CFG(DM365,	SPI1_SDI,	3,   31,    1,    1,	 false)
+MUX_CFG(DM365,	SPI1_SDO,	4,   0,     3,    1,	 false)
+MUX_CFG(DM365,	SPI1_SDENA0,	4,   4,     3,    1,	 false)
+MUX_CFG(DM365,	SPI1_SDENA1,	4,   0,     3,    2,	 false)
+
+MUX_CFG(DM365,	SPI2_SCLK,	4,   10,    3,    1,	 false)
+MUX_CFG(DM365,	SPI2_SDI,	4,   6,     3,    1,	 false)
+MUX_CFG(DM365,	SPI2_SDO,	4,   8,     3,    1,	 false)
+MUX_CFG(DM365,	SPI2_SDENA0,	4,   12,    3,    1,	 false)
+MUX_CFG(DM365,	SPI2_SDENA1,	4,   8,     3,    2,	 false)
+
+MUX_CFG(DM365,	SPI3_SCLK,	0,   0,	    3,    2,	 false)
+MUX_CFG(DM365,	SPI3_SDI,	0,   2,     3,    2,	 false)
+MUX_CFG(DM365,	SPI3_SDO,	0,   6,     3,    2,	 false)
+MUX_CFG(DM365,	SPI3_SDENA0,	0,   4,     3,    2,	 false)
+MUX_CFG(DM365,	SPI3_SDENA1,	0,   6,     3,    3,	 false)
+
+MUX_CFG(DM365,	SPI4_SCLK,	4,   18,    3,    1,	 false)
+MUX_CFG(DM365,	SPI4_SDI,	4,   14,    3,    1,	 false)
+MUX_CFG(DM365,	SPI4_SDO,	4,   16,    3,    1,	 false)
+MUX_CFG(DM365,	SPI4_SDENA0,	4,   20,    3,    1,	 false)
+MUX_CFG(DM365,	SPI4_SDENA1,	4,   16,    3,    2,	 false)
+
+MUX_CFG(DM365,	GPIO20,		3,   21,    3,    0,	 false)
+MUX_CFG(DM365,	GPIO33,		4,   12,    3,	  0,	 false)
+MUX_CFG(DM365,	GPIO40,		4,   26,    3,	  0,	 false)
+
+MUX_CFG(DM365,	VOUT_FIELD,	1,   18,    3,	  1,	 false)
+MUX_CFG(DM365,	VOUT_FIELD_G81,	1,   18,    3,	  0,	 false)
+MUX_CFG(DM365,	VOUT_HVSYNC,	1,   16,    1,	  0,	 false)
+MUX_CFG(DM365,	VOUT_COUTL_EN,	1,   0,     0xff, 0x55,  false)
+MUX_CFG(DM365,	VOUT_COUTH_EN,	1,   8,     0xff, 0x55,  false)
+MUX_CFG(DM365,	VIN_CAM_WEN,	0,   14,    3,	  0,	 false)
+MUX_CFG(DM365,	VIN_CAM_VD,	0,   13,    1,	  0,	 false)
+MUX_CFG(DM365,	VIN_CAM_HD,	0,   12,    1,	  0,	 false)
+MUX_CFG(DM365,	VIN_YIN4_7_EN,	0,   0,     0xff, 0,	 false)
+MUX_CFG(DM365,	VIN_YIN0_3_EN,	0,   8,     0xf,  0,	 false)
+
+INT_CFG(DM365,  INT_EDMA_CC,         2,     1,    1,     false)
+INT_CFG(DM365,  INT_EDMA_TC0_ERR,    3,     1,    1,     false)
+INT_CFG(DM365,  INT_EDMA_TC1_ERR,    4,     1,    1,     false)
+INT_CFG(DM365,  INT_EDMA_TC2_ERR,    22,    1,    1,     false)
+INT_CFG(DM365,  INT_EDMA_TC3_ERR,    23,    1,    1,     false)
+INT_CFG(DM365,  INT_PRTCSS,          10,    1,    1,     false)
+INT_CFG(DM365,  INT_EMAC_RXTHRESH,   14,    1,    1,     false)
+INT_CFG(DM365,  INT_EMAC_RXPULSE,    15,    1,    1,     false)
+INT_CFG(DM365,  INT_EMAC_TXPULSE,    16,    1,    1,     false)
+INT_CFG(DM365,  INT_EMAC_MISCPULSE,  17,    1,    1,     false)
+INT_CFG(DM365,  INT_IMX0_ENABLE,     0,     1,    0,     false)
+INT_CFG(DM365,  INT_IMX0_DISABLE,    0,     1,    1,     false)
+INT_CFG(DM365,  INT_HDVICP_ENABLE,   0,     1,    1,     false)
+INT_CFG(DM365,  INT_HDVICP_DISABLE,  0,     1,    0,     false)
+INT_CFG(DM365,  INT_IMX1_ENABLE,     24,    1,    1,     false)
+INT_CFG(DM365,  INT_IMX1_DISABLE,    24,    1,    0,     false)
+INT_CFG(DM365,  INT_NSF_ENABLE,      25,    1,    1,     false)
+INT_CFG(DM365,  INT_NSF_DISABLE,     25,    1,    0,     false)
+#endif
+};
+
+static struct emac_platform_data dm365_emac_pdata = {
+	.ctrl_reg_offset	= DM365_EMAC_CNTRL_OFFSET,
+	.ctrl_mod_reg_offset	= DM365_EMAC_CNTRL_MOD_OFFSET,
+	.ctrl_ram_offset	= DM365_EMAC_CNTRL_RAM_OFFSET,
+	.mdio_reg_offset	= DM365_EMAC_MDIO_OFFSET,
+	.ctrl_ram_size		= DM365_EMAC_CNTRL_RAM_SIZE,
+	.version		= EMAC_VERSION_2,
+};
+
+static struct resource dm365_emac_resources[] = {
+	{
+		.start	= DM365_EMAC_BASE,
+		.end	= DM365_EMAC_BASE + 0x47ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_DM365_EMAC_RXTHRESH,
+		.end	= IRQ_DM365_EMAC_RXTHRESH,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DM365_EMAC_RXPULSE,
+		.end	= IRQ_DM365_EMAC_RXPULSE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DM365_EMAC_TXPULSE,
+		.end	= IRQ_DM365_EMAC_TXPULSE,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= IRQ_DM365_EMAC_MISCPULSE,
+		.end	= IRQ_DM365_EMAC_MISCPULSE,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dm365_emac_device = {
+	.name		= "davinci_emac",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &dm365_emac_pdata,
+	},
+	.num_resources	= ARRAY_SIZE(dm365_emac_resources),
+	.resource	= dm365_emac_resources,
+};
+
+static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+	[IRQ_VDINT0]			= 2,
+	[IRQ_VDINT1]			= 6,
+	[IRQ_VDINT2]			= 6,
+	[IRQ_HISTINT]			= 6,
+	[IRQ_H3AINT]			= 6,
+	[IRQ_PRVUINT]			= 6,
+	[IRQ_RSZINT]			= 6,
+	[IRQ_DM365_INSFINT]		= 7,
+	[IRQ_VENCINT]			= 6,
+	[IRQ_ASQINT]			= 6,
+	[IRQ_IMXINT]			= 6,
+	[IRQ_DM365_IMCOPINT]		= 4,
+	[IRQ_USBINT]			= 4,
+	[IRQ_DM365_RTOINT]		= 7,
+	[IRQ_DM365_TINT5]		= 7,
+	[IRQ_DM365_TINT6]		= 5,
+	[IRQ_CCINT0]			= 5,
+	[IRQ_CCERRINT]			= 5,
+	[IRQ_TCERRINT0]			= 5,
+	[IRQ_TCERRINT]			= 7,
+	[IRQ_PSCIN]			= 4,
+	[IRQ_DM365_SPINT2_1]		= 7,
+	[IRQ_DM365_TINT7]		= 7,
+	[IRQ_DM365_SDIOINT0]		= 7,
+	[IRQ_MBXINT]			= 7,
+	[IRQ_MBRINT]			= 7,
+	[IRQ_MMCINT]			= 7,
+	[IRQ_DM365_MMCINT1]		= 7,
+	[IRQ_DM365_PWMINT3]		= 7,
+	[IRQ_DDRINT]			= 4,
+	[IRQ_AEMIFINT]			= 2,
+	[IRQ_DM365_SDIOINT1]		= 2,
+	[IRQ_TINT0_TINT12]		= 7,
+	[IRQ_TINT0_TINT34]		= 7,
+	[IRQ_TINT1_TINT12]		= 7,
+	[IRQ_TINT1_TINT34]		= 7,
+	[IRQ_PWMINT0]			= 7,
+	[IRQ_PWMINT1]			= 3,
+	[IRQ_PWMINT2]			= 3,
+	[IRQ_I2C]			= 3,
+	[IRQ_UARTINT0]			= 3,
+	[IRQ_UARTINT1]			= 3,
+	[IRQ_DM365_SPIINT0_0]		= 3,
+	[IRQ_DM365_SPIINT3_0]		= 3,
+	[IRQ_DM365_GPIO0]		= 3,
+	[IRQ_DM365_GPIO1]		= 7,
+	[IRQ_DM365_GPIO2]		= 4,
+	[IRQ_DM365_GPIO3]		= 4,
+	[IRQ_DM365_GPIO4]		= 7,
+	[IRQ_DM365_GPIO5]		= 7,
+	[IRQ_DM365_GPIO6]		= 7,
+	[IRQ_DM365_GPIO7]		= 7,
+	[IRQ_DM365_EMAC_RXTHRESH]	= 7,
+	[IRQ_DM365_EMAC_RXPULSE]	= 7,
+	[IRQ_DM365_EMAC_TXPULSE]	= 7,
+	[IRQ_DM365_EMAC_MISCPULSE]	= 7,
+	[IRQ_DM365_GPIO12]		= 7,
+	[IRQ_DM365_GPIO13]		= 7,
+	[IRQ_DM365_GPIO14]		= 7,
+	[IRQ_DM365_GPIO15]		= 7,
+	[IRQ_DM365_KEYINT]		= 7,
+	[IRQ_DM365_TCERRINT2]		= 7,
+	[IRQ_DM365_TCERRINT3]		= 7,
+	[IRQ_DM365_EMUINT]		= 7,
+};
+
+/* Four Transfer Controllers on DM365 */
+static const s8
+dm365_queue_tc_mapping[][2] = {
+	/* {event queue no, TC no} */
+	{0, 0},
+	{1, 1},
+	{2, 2},
+	{3, 3},
+	{-1, -1},
+};
+
+static const s8
+dm365_queue_priority_mapping[][2] = {
+	/* {event queue no, Priority} */
+	{0, 7},
+	{1, 7},
+	{2, 7},
+	{3, 0},
+	{-1, -1},
+};
+
+static struct edma_soc_info dm365_edma_info[] = {
+	{
+		.n_channel		= 64,
+		.n_region		= 4,
+		.n_slot			= 256,
+		.n_tc			= 4,
+		.n_cc			= 1,
+		.queue_tc_mapping	= dm365_queue_tc_mapping,
+		.queue_priority_mapping	= dm365_queue_priority_mapping,
+		.default_queue		= EVENTQ_2,
+	},
+};
+
+static struct resource edma_resources[] = {
+	{
+		.name	= "edma_cc0",
+		.start	= 0x01c00000,
+		.end	= 0x01c00000 + SZ_64K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc0",
+		.start	= 0x01c10000,
+		.end	= 0x01c10000 + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc1",
+		.start	= 0x01c10400,
+		.end	= 0x01c10400 + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc2",
+		.start	= 0x01c10800,
+		.end	= 0x01c10800 + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma_tc3",
+		.start	= 0x01c10c00,
+		.end	= 0x01c10c00 + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.name	= "edma0",
+		.start	= IRQ_CCINT0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.name	= "edma0_err",
+		.start	= IRQ_CCERRINT,
+		.flags	= IORESOURCE_IRQ,
+	},
+	/* not using TC*_ERR */
+};
+
+static struct platform_device dm365_edma_device = {
+	.name			= "edma",
+	.id			= 0,
+	.dev.platform_data	= dm365_edma_info,
+	.num_resources		= ARRAY_SIZE(edma_resources),
+	.resource		= edma_resources,
+};
+
+static struct map_desc dm365_io_desc[] = {
+	{
+		.virtual	= IO_VIRT,
+		.pfn		= __phys_to_pfn(IO_PHYS),
+		.length		= IO_SIZE,
+		.type		= MT_DEVICE
+	},
+	{
+		.virtual	= SRAM_VIRT,
+		.pfn		= __phys_to_pfn(0x00010000),
+		.length		= SZ_32K,
+		/* MT_MEMORY_NONCACHED requires supersection alignment */
+		.type		= MT_DEVICE,
+	},
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm365_ids[] = {
+	{
+		.variant	= 0x0,
+		.part_no	= 0xb83e,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DM365,
+		.name		= "dm365_rev1.1",
+	},
+	{
+		.variant	= 0x8,
+		.part_no	= 0xb83e,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DM365,
+		.name		= "dm365_rev1.2",
+	},
+};
+
+static void __iomem *dm365_psc_bases[] = {
+	IO_ADDRESS(DAVINCI_PWR_SLEEP_CNTRL_BASE),
+};
+
+struct davinci_timer_info dm365_timer_info = {
+	.timers		= davinci_timer_instance,
+	.clockevent_id	= T0_BOT,
+	.clocksource_id	= T0_TOP,
+};
+
+static struct plat_serial8250_port dm365_serial_platform_data[] = {
+	{
+		.mapbase	= DAVINCI_UART0_BASE,
+		.irq		= IRQ_UARTINT0,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+				  UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	},
+	{
+		.mapbase	= DAVINCI_UART1_BASE,
+		.irq		= IRQ_UARTINT1,
+		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+				  UPF_IOREMAP,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	},
+	{
+		.flags		= 0
+	},
+};
+
+static struct platform_device dm365_serial_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= dm365_serial_platform_data,
+	},
+};
+
+static struct davinci_soc_info davinci_soc_info_dm365 = {
+	.io_desc		= dm365_io_desc,
+	.io_desc_num		= ARRAY_SIZE(dm365_io_desc),
+	.jtag_id_base		= IO_ADDRESS(0x01c40028),
+	.ids			= dm365_ids,
+	.ids_num		= ARRAY_SIZE(dm365_ids),
+	.cpu_clks		= dm365_clks,
+	.psc_bases		= dm365_psc_bases,
+	.psc_bases_num		= ARRAY_SIZE(dm365_psc_bases),
+	.pinmux_base		= IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE),
+	.pinmux_pins		= dm365_pins,
+	.pinmux_pins_num	= ARRAY_SIZE(dm365_pins),
+	.intc_base		= IO_ADDRESS(DAVINCI_ARM_INTC_BASE),
+	.intc_type		= DAVINCI_INTC_TYPE_AINTC,
+	.intc_irq_prios		= dm365_default_priorities,
+	.intc_irq_num		= DAVINCI_N_AINTC_IRQ,
+	.timer_info		= &dm365_timer_info,
+	.gpio_base		= IO_ADDRESS(DAVINCI_GPIO_BASE),
+	.gpio_num		= 104,
+	.gpio_irq		= IRQ_DM365_GPIO0,
+	.gpio_unbanked		= 8,	/* really 16 ... skip muxed GPIOs */
+	.serial_dev		= &dm365_serial_device,
+	.emac_pdata		= &dm365_emac_pdata,
+	.sram_dma		= 0x00010000,
+	.sram_len		= SZ_32K,
+};
+
+void __init dm365_init(void)
+{
+	davinci_common_init(&davinci_soc_info_dm365);
+}
+
+static int __init dm365_init_devices(void)
+{
+	if (!cpu_is_davinci_dm365())
+		return 0;
+
+	davinci_cfg_reg(DM365_INT_EDMA_CC);
+	platform_device_register(&dm365_edma_device);
+	platform_device_register(&dm365_emac_device);
+
+	return 0;
+}
+postcore_initcall(dm365_init_devices);
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index fb5449b..d6e0fa5 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -27,6 +27,7 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
+#include <mach/asp.h>
 
 #include "clock.h"
 #include "mux.h"
@@ -303,7 +304,7 @@ struct davinci_clk dm644x_clks[] = {
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK("i2c_davinci.1", NULL, &i2c_clk),
 	CLK("palm_bk3710", NULL, &ide_clk),
-	CLK("soc-audio.0", NULL, &asp_clk),
+	CLK("davinci-asp", NULL, &asp_clk),
 	CLK("davinci_mmc.0", NULL, &mmcsd_clk),
 	CLK(NULL, "spi", &spi_clk),
 	CLK(NULL, "gpio", &gpio_clk),
@@ -484,17 +485,38 @@ static const s8 dma_chan_dm644x_no_event[] = {
 	-1
 };
 
-static struct edma_soc_info dm644x_edma_info = {
-	.n_channel	= 64,
-	.n_region	= 4,
-	.n_slot		= 128,
-	.n_tc		= 2,
-	.noevent	= dma_chan_dm644x_no_event,
+static const s8
+queue_tc_mapping[][2] = {
+	/* {event queue no, TC no} */
+	{0, 0},
+	{1, 1},
+	{-1, -1},
+};
+
+static const s8
+queue_priority_mapping[][2] = {
+	/* {event queue no, Priority} */
+	{0, 3},
+	{1, 7},
+	{-1, -1},
+};
+
+static struct edma_soc_info dm644x_edma_info[] = {
+	{
+		.n_channel		= 64,
+		.n_region		= 4,
+		.n_slot			= 128,
+		.n_tc			= 2,
+		.n_cc			= 1,
+		.noevent		= dma_chan_dm644x_no_event,
+		.queue_tc_mapping	= queue_tc_mapping,
+		.queue_priority_mapping	= queue_priority_mapping,
+	},
 };
 
 static struct resource edma_resources[] = {
 	{
-		.name	= "edma_cc",
+		.name	= "edma_cc0",
 		.start	= 0x01c00000,
 		.end	= 0x01c00000 + SZ_64K - 1,
 		.flags	= IORESOURCE_MEM,
@@ -512,10 +534,12 @@ static struct resource edma_resources[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 	{
+		.name	= "edma0",
 		.start	= IRQ_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
+		.name	= "edma0_err",
 		.start	= IRQ_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -524,12 +548,91 @@ static struct resource edma_resources[] = {
 
 static struct platform_device dm644x_edma_device = {
 	.name			= "edma",
-	.id			= -1,
-	.dev.platform_data	= &dm644x_edma_info,
+	.id			= 0,
+	.dev.platform_data	= dm644x_edma_info,
 	.num_resources		= ARRAY_SIZE(edma_resources),
 	.resource		= edma_resources,
 };
 
+/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
+static struct resource dm644x_asp_resources[] = {
+	{
+		.start	= DAVINCI_ASP0_BASE,
+		.end	= DAVINCI_ASP0_BASE + SZ_8K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP0_TX,
+		.end	= DAVINCI_DMA_ASP0_TX,
+		.flags	= IORESOURCE_DMA,
+	},
+	{
+		.start	= DAVINCI_DMA_ASP0_RX,
+		.end	= DAVINCI_DMA_ASP0_RX,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device dm644x_asp_device = {
+	.name		= "davinci-asp",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(dm644x_asp_resources),
+	.resource	= dm644x_asp_resources,
+};
+
+static struct resource dm644x_vpss_resources[] = {
+	{
+		/* VPSS Base address */
+		.name		= "vpss",
+		.start          = 0x01c73400,
+		.end            = 0x01c73400 + 0xff,
+		.flags          = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device dm644x_vpss_device = {
+	.name			= "vpss",
+	.id			= -1,
+	.dev.platform_data	= "dm644x_vpss",
+	.num_resources		= ARRAY_SIZE(dm644x_vpss_resources),
+	.resource		= dm644x_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+	{
+		.start          = IRQ_VDINT0,
+		.end            = IRQ_VDINT0,
+		.flags          = IORESOURCE_IRQ,
+	},
+	{
+		.start          = IRQ_VDINT1,
+		.end            = IRQ_VDINT1,
+		.flags          = IORESOURCE_IRQ,
+	},
+	{
+		.start          = 0x01c70400,
+		.end            = 0x01c70400 + 0xff,
+		.flags          = IORESOURCE_MEM,
+	},
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device vpfe_capture_dev = {
+	.name		= CAPTURE_DRV_NAME,
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(vpfe_resources),
+	.resource	= vpfe_resources,
+	.dev = {
+		.dma_mask		= &vpfe_capture_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void dm644x_set_vpfe_config(struct vpfe_config *cfg)
+{
+	vpfe_capture_dev.dev.platform_data = cfg;
+}
+
 /*----------------------------------------------------------------------*/
 
 static struct map_desc dm644x_io_desc[] = {
@@ -557,6 +660,13 @@ static struct davinci_id dm644x_ids[] = {
 		.cpu_id		= DAVINCI_CPU_ID_DM6446,
 		.name		= "dm6446",
 	},
+	{
+		.variant	= 0x1,
+		.part_no	= 0xb700,
+		.manufacturer	= 0x017,
+		.cpu_id		= DAVINCI_CPU_ID_DM6446,
+		.name		= "dm6446a",
+	},
 };
 
 static void __iomem *dm644x_psc_bases[] = {
@@ -630,7 +740,6 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
 	.intc_irq_prios 	= dm644x_default_priorities,
 	.intc_irq_num		= DAVINCI_N_AINTC_IRQ,
 	.timer_info		= &dm644x_timer_info,
-	.wdt_base		= IO_ADDRESS(DAVINCI_WDOG_BASE),
 	.gpio_base		= IO_ADDRESS(DAVINCI_GPIO_BASE),
 	.gpio_num		= 71,
 	.gpio_irq		= IRQ_GPIOBNK0,
@@ -640,6 +749,13 @@ static struct davinci_soc_info davinci_soc_info_dm644x = {
 	.sram_len		= SZ_16K,
 };
 
+void __init dm644x_init_asp(struct snd_platform_data *pdata)
+{
+	davinci_cfg_reg(DM644X_MCBSP);
+	dm644x_asp_device.dev.platform_data = pdata;
+	platform_device_register(&dm644x_asp_device);
+}
+
 void __init dm644x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm644x);
@@ -652,6 +768,9 @@ static int __init dm644x_init_devices(void)
 
 	platform_device_register(&dm644x_edma_device);
 	platform_device_register(&dm644x_emac_device);
+	platform_device_register(&dm644x_vpss_device);
+	platform_device_register(&vpfe_capture_dev);
+
 	return 0;
 }
 postcore_initcall(dm644x_init_devices);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 334f071..0976049 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -27,10 +27,20 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
+#include <mach/asp.h>
 
 #include "clock.h"
 #include "mux.h"
 
+#define DAVINCI_VPIF_BASE       (0x01C12000)
+#define VDD3P3V_PWDN_OFFSET	(0x48)
+#define VSCLKDIS_OFFSET		(0x6C)
+
+#define VDD3P3V_VID_MASK	(BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\
+					BIT_MASK(0))
+#define VSCLKDIS_MASK		(BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
+					BIT_MASK(8))
+
 /*
  * Device specific clocks
  */
@@ -162,6 +172,41 @@ static struct clk arm_clk = {
 	.flags = ALWAYS_ENABLED,
 };
 
+static struct clk edma_cc_clk = {
+	.name = "edma_cc",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPCC,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc0_clk = {
+	.name = "edma_tc0",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC0,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc1_clk = {
+	.name = "edma_tc1",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC1,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc2_clk = {
+	.name = "edma_tc2",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC2,
+	.flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc3_clk = {
+	.name = "edma_tc3",
+	.parent = &pll1_sysclk2,
+	.lpsc = DM646X_LPSC_TPTC3,
+	.flags = ALWAYS_ENABLED,
+};
+
 static struct clk uart0_clk = {
 	.name = "uart0",
 	.parent = &aux_clkin,
@@ -192,6 +237,18 @@ static struct clk gpio_clk = {
 	.lpsc = DM646X_LPSC_GPIO,
 };
 
+static struct clk mcasp0_clk = {
+	.name = "mcasp0",
+	.parent = &pll1_sysclk3,
+	.lpsc = DM646X_LPSC_McASP0,
+};
+
+static struct clk mcasp1_clk = {
+	.name = "mcasp1",
+	.parent = &pll1_sysclk3,
+	.lpsc = DM646X_LPSC_McASP1,
+};
+
 static struct clk aemif_clk = {
 	.name = "aemif",
 	.parent = &pll1_sysclk3,
@@ -237,6 +294,13 @@ static struct clk timer2_clk = {
 	.flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
 };
 
+
+static struct clk ide_clk = {
+	.name = "ide",
+	.parent = &pll1_sysclk4,
+	.lpsc = DAVINCI_LPSC_ATA,
+};
+
 static struct clk vpif0_clk = {
 	.name = "vpif0",
 	.parent = &ref_clk,
@@ -269,11 +333,18 @@ struct davinci_clk dm646x_clks[] = {
 	CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
 	CLK(NULL, "dsp", &dsp_clk),
 	CLK(NULL, "arm", &arm_clk),
+	CLK(NULL, "edma_cc", &edma_cc_clk),
+	CLK(NULL, "edma_tc0", &edma_tc0_clk),
+	CLK(NULL, "edma_tc1", &edma_tc1_clk),
+	CLK(NULL, "edma_tc2", &edma_tc2_clk),
+	CLK(NULL, "edma_tc3", &edma_tc3_clk),
 	CLK(NULL, "uart0", &uart0_clk),
 	CLK(NULL, "uart1", &uart1_clk),
 	CLK(NULL, "uart2", &uart2_clk),
 	CLK("i2c_davinci.1", NULL, &i2c_clk),
 	CLK(NULL, "gpio", &gpio_clk),
+	CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
+	CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
 	CLK(NULL, "aemif", &aemif_clk),
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK(NULL, "pwm0", &pwm0_clk),
@@ -281,6 +352,7 @@ struct davinci_clk dm646x_clks[] = {
 	CLK(NULL, "timer0", &timer0_clk),
 	CLK(NULL, "timer1", &timer1_clk),
 	CLK("watchdog", NULL, &timer2_clk),
+	CLK("palm_bk3710", NULL, &ide_clk),
 	CLK(NULL, "vpif0", &vpif0_clk),
 	CLK(NULL, "vpif1", &vpif1_clk),
 	CLK(NULL, NULL, NULL),
@@ -344,7 +416,7 @@ static struct platform_device dm646x_emac_device = {
  */
 static const struct mux_config dm646x_pins[] = {
 #ifdef CONFIG_DAVINCI_MUX
-MUX_CFG(DM646X, ATAEN,		0,   0,     1,	  1,	 true)
+MUX_CFG(DM646X, ATAEN,		0,   0,     5,	  1,	 true)
 
 MUX_CFG(DM646X, AUDCK1,		0,   29,    1,	  0,	 false)
 
@@ -451,17 +523,43 @@ static const s8 dma_chan_dm646x_no_event[] = {
 	-1
 };
 
-static struct edma_soc_info dm646x_edma_info = {
-	.n_channel	= 64,
-	.n_region	= 6,	/* 0-1, 4-7 */
-	.n_slot		= 512,
-	.n_tc		= 4,
-	.noevent	= dma_chan_dm646x_no_event,
+/* Four Transfer Controllers on DM646x */
+static const s8
+dm646x_queue_tc_mapping[][2] = {
+	/* {event queue no, TC no} */
+	{0, 0},
+	{1, 1},
+	{2, 2},
+	{3, 3},
+	{-1, -1},
+};
+
+static const s8
+dm646x_queue_priority_mapping[][2] = {
+	/* {event queue no, Priority} */
+	{0, 4},
+	{1, 0},
+	{2, 5},
+	{3, 1},
+	{-1, -1},
+};
+
+static struct edma_soc_info dm646x_edma_info[] = {
+	{
+		.n_channel		= 64,
+		.n_region		= 6,	/* 0-1, 4-7 */
+		.n_slot			= 512,
+		.n_tc			= 4,
+		.n_cc			= 1,
+		.noevent		= dma_chan_dm646x_no_event,
+		.queue_tc_mapping	= dm646x_queue_tc_mapping,
+		.queue_priority_mapping	= dm646x_queue_priority_mapping,
+	},
 };
 
 static struct resource edma_resources[] = {
 	{
-		.name	= "edma_cc",
+		.name	= "edma_cc0",
 		.start	= 0x01c00000,
 		.end	= 0x01c00000 + SZ_64K - 1,
 		.flags	= IORESOURCE_MEM,
@@ -491,10 +589,12 @@ static struct resource edma_resources[] = {
 		.flags	= IORESOURCE_MEM,
 	},
 	{
+		.name	= "edma0",
 		.start	= IRQ_CCINT0,
 		.flags	= IORESOURCE_IRQ,
 	},
 	{
+		.name	= "edma0_err",
 		.start	= IRQ_CCERRINT,
 		.flags	= IORESOURCE_IRQ,
 	},
@@ -503,12 +603,167 @@ static struct resource edma_resources[] = {
 
 static struct platform_device dm646x_edma_device = {
 	.name			= "edma",
-	.id			= -1,
-	.dev.platform_data	= &dm646x_edma_info,
+	.id			= 0,
+	.dev.platform_data	= dm646x_edma_info,
 	.num_resources		= ARRAY_SIZE(edma_resources),
 	.resource		= edma_resources,
 };
 
+static struct resource ide_resources[] = {
+	{
+		.start          = DM646X_ATA_REG_BASE,
+		.end            = DM646X_ATA_REG_BASE + 0x7ff,
+		.flags          = IORESOURCE_MEM,
+	},
+	{
+		.start          = IRQ_DM646X_IDE,
+		.end            = IRQ_DM646X_IDE,
+		.flags          = IORESOURCE_IRQ,
+	},
+};
+
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ide_dev = {
+	.name           = "palm_bk3710",
+	.id             = -1,
+	.resource       = ide_resources,
+	.num_resources  = ARRAY_SIZE(ide_resources),
+	.dev = {
+		.dma_mask		= &ide_dma_mask,
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+};
+
+static struct resource dm646x_mcasp0_resources[] = {
+	{
+		.name	= "mcasp0",
+		.start 	= DAVINCI_DM646X_MCASP0_REG_BASE,
+		.end 	= DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1,
+		.flags 	= IORESOURCE_MEM,
+	},
+	/* first TX, then RX */
+	{
+		.start	= DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+		.end	= DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+		.flags	= IORESOURCE_DMA,
+	},
+	{
+		.start	= DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+		.end	= DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct resource dm646x_mcasp1_resources[] = {
+	{
+		.name	= "mcasp1",
+		.start	= DAVINCI_DM646X_MCASP1_REG_BASE,
+		.end	= DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	/* DIT mode, only TX event */
+	{
+		.start	= DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+		.end	= DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+		.flags	= IORESOURCE_DMA,
+	},
+	/* DIT mode, dummy entry */
+	{
+		.start	= -1,
+		.end	= -1,
+		.flags	= IORESOURCE_DMA,
+	},
+};
+
+static struct platform_device dm646x_mcasp0_device = {
+	.name		= "davinci-mcasp",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm646x_mcasp0_resources),
+	.resource	= dm646x_mcasp0_resources,
+};
+
+static struct platform_device dm646x_mcasp1_device = {
+	.name		= "davinci-mcasp",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(dm646x_mcasp1_resources),
+	.resource	= dm646x_mcasp1_resources,
+};
+
+static struct platform_device dm646x_dit_device = {
+	.name	= "spdif-dit",
+	.id	= -1,
+};
+
+static u64 vpif_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource vpif_resource[] = {
+	{
+		.start	= DAVINCI_VPIF_BASE,
+		.end	= DAVINCI_VPIF_BASE + 0x03ff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device vpif_dev = {
+	.name		= "vpif",
+	.id		= -1,
+	.dev		= {
+			.dma_mask 		= &vpif_dma_mask,
+			.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= vpif_resource,
+	.num_resources	= ARRAY_SIZE(vpif_resource),
+};
+
+static struct resource vpif_display_resource[] = {
+	{
+		.start = IRQ_DM646X_VP_VERTINT2,
+		.end   = IRQ_DM646X_VP_VERTINT2,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_DM646X_VP_VERTINT3,
+		.end   = IRQ_DM646X_VP_VERTINT3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device vpif_display_dev = {
+	.name		= "vpif_display",
+	.id		= -1,
+	.dev		= {
+			.dma_mask 		= &vpif_dma_mask,
+			.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= vpif_display_resource,
+	.num_resources	= ARRAY_SIZE(vpif_display_resource),
+};
+
+static struct resource vpif_capture_resource[] = {
+	{
+		.start = IRQ_DM646X_VP_VERTINT0,
+		.end   = IRQ_DM646X_VP_VERTINT0,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_DM646X_VP_VERTINT1,
+		.end   = IRQ_DM646X_VP_VERTINT1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device vpif_capture_dev = {
+	.name		= "vpif_capture",
+	.id		= -1,
+	.dev		= {
+			.dma_mask 		= &vpif_dma_mask,
+			.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+	.resource	= vpif_capture_resource,
+	.num_resources	= ARRAY_SIZE(vpif_capture_resource),
+};
+
 /*----------------------------------------------------------------------*/
 
 static struct map_desc dm646x_io_desc[] = {
@@ -609,7 +864,6 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
 	.intc_irq_prios		= dm646x_default_priorities,
 	.intc_irq_num		= DAVINCI_N_AINTC_IRQ,
 	.timer_info		= &dm646x_timer_info,
-	.wdt_base		= IO_ADDRESS(DAVINCI_WDOG_BASE),
 	.gpio_base		= IO_ADDRESS(DAVINCI_GPIO_BASE),
 	.gpio_num		= 43, /* Only 33 usable */
 	.gpio_irq		= IRQ_DM646X_GPIOBNK0,
@@ -619,6 +873,51 @@ static struct davinci_soc_info davinci_soc_info_dm646x = {
 	.sram_len		= SZ_32K,
 };
 
+void __init dm646x_init_ide()
+{
+	davinci_cfg_reg(DM646X_ATAEN);
+	platform_device_register(&ide_dev);
+}
+
+void __init dm646x_init_mcasp0(struct snd_platform_data *pdata)
+{
+	dm646x_mcasp0_device.dev.platform_data = pdata;
+	platform_device_register(&dm646x_mcasp0_device);
+}
+
+void __init dm646x_init_mcasp1(struct snd_platform_data *pdata)
+{
+	dm646x_mcasp1_device.dev.platform_data = pdata;
+	platform_device_register(&dm646x_mcasp1_device);
+	platform_device_register(&dm646x_dit_device);
+}
+
+void dm646x_setup_vpif(struct vpif_display_config *display_config,
+		       struct vpif_capture_config *capture_config)
+{
+	unsigned int value;
+	void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
+
+	value = __raw_readl(base + VSCLKDIS_OFFSET);
+	value &= ~VSCLKDIS_MASK;
+	__raw_writel(value, base + VSCLKDIS_OFFSET);
+
+	value = __raw_readl(base + VDD3P3V_PWDN_OFFSET);
+	value &= ~VDD3P3V_VID_MASK;
+	__raw_writel(value, base + VDD3P3V_PWDN_OFFSET);
+
+	davinci_cfg_reg(DM646X_STSOMUX_DISABLE);
+	davinci_cfg_reg(DM646X_STSIMUX_DISABLE);
+	davinci_cfg_reg(DM646X_PTSOMUX_DISABLE);
+	davinci_cfg_reg(DM646X_PTSIMUX_DISABLE);
+
+	vpif_display_dev.dev.platform_data = display_config;
+	vpif_capture_dev.dev.platform_data = capture_config;
+	platform_device_register(&vpif_dev);
+	platform_device_register(&vpif_display_dev);
+	platform_device_register(&vpif_capture_dev);
+}
+
 void __init dm646x_init(void)
 {
 	davinci_common_init(&davinci_soc_info_dm646x);
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
index 15e9eb1..f2e57d2 100644
--- a/arch/arm/mach-davinci/dma.c
+++ b/arch/arm/mach-davinci/dma.c
@@ -100,132 +100,158 @@
 #define EDMA_SHADOW0	0x2000	/* 4 regions shadowing global channels */
 #define EDMA_PARM	0x4000	/* 128 param entries */
 
-#define DAVINCI_DMA_3PCC_BASE	0x01C00000
-
 #define PARM_OFFSET(param_no)	(EDMA_PARM + ((param_no) << 5))
 
+#define EDMA_DCHMAP	0x0100  /* 64 registers */
+#define CHMAP_EXIST	BIT(24)
+
 #define EDMA_MAX_DMACH           64
 #define EDMA_MAX_PARAMENTRY     512
-#define EDMA_MAX_EVQUE            2	/* FIXME too small */
+#define EDMA_MAX_CC               2
 
 
 /*****************************************************************************/
 
-static void __iomem *edmacc_regs_base;
+static void __iomem *edmacc_regs_base[EDMA_MAX_CC];
 
-static inline unsigned int edma_read(int offset)
+static inline unsigned int edma_read(unsigned ctlr, int offset)
 {
-	return (unsigned int)__raw_readl(edmacc_regs_base + offset);
+	return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset);
 }
 
-static inline void edma_write(int offset, int val)
+static inline void edma_write(unsigned ctlr, int offset, int val)
 {
-	__raw_writel(val, edmacc_regs_base + offset);
+	__raw_writel(val, edmacc_regs_base[ctlr] + offset);
 }
-static inline void edma_modify(int offset, unsigned and, unsigned or)
+static inline void edma_modify(unsigned ctlr, int offset, unsigned and,
+		unsigned or)
 {
-	unsigned val = edma_read(offset);
+	unsigned val = edma_read(ctlr, offset);
 	val &= and;
 	val |= or;
-	edma_write(offset, val);
+	edma_write(ctlr, offset, val);
 }
-static inline void edma_and(int offset, unsigned and)
+static inline void edma_and(unsigned ctlr, int offset, unsigned and)
 {
-	unsigned val = edma_read(offset);
+	unsigned val = edma_read(ctlr, offset);
 	val &= and;
-	edma_write(offset, val);
+	edma_write(ctlr, offset, val);
 }
-static inline void edma_or(int offset, unsigned or)
+static inline void edma_or(unsigned ctlr, int offset, unsigned or)
 {
-	unsigned val = edma_read(offset);
+	unsigned val = edma_read(ctlr, offset);
 	val |= or;
-	edma_write(offset, val);
+	edma_write(ctlr, offset, val);
 }
-static inline unsigned int edma_read_array(int offset, int i)
+static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i)
 {
-	return edma_read(offset + (i << 2));
+	return edma_read(ctlr, offset + (i << 2));
 }
-static inline void edma_write_array(int offset, int i, unsigned val)
+static inline void edma_write_array(unsigned ctlr, int offset, int i,
+		unsigned val)
 {
-	edma_write(offset + (i << 2), val);
+	edma_write(ctlr, offset + (i << 2), val);
 }
-static inline void edma_modify_array(int offset, int i,
+static inline void edma_modify_array(unsigned ctlr, int offset, int i,
 		unsigned and, unsigned or)
 {
-	edma_modify(offset + (i << 2), and, or);
+	edma_modify(ctlr, offset + (i << 2), and, or);
 }
-static inline void edma_or_array(int offset, int i, unsigned or)
+static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or)
 {
-	edma_or(offset + (i << 2), or);
+	edma_or(ctlr, offset + (i << 2), or);
 }
-static inline void edma_or_array2(int offset, int i, int j, unsigned or)
+static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j,
+		unsigned or)
 {
-	edma_or(offset + ((i*2 + j) << 2), or);
+	edma_or(ctlr, offset + ((i*2 + j) << 2), or);
 }
-static inline void edma_write_array2(int offset, int i, int j, unsigned val)
+static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j,
+		unsigned val)
 {
-	edma_write(offset + ((i*2 + j) << 2), val);
+	edma_write(ctlr, offset + ((i*2 + j) << 2), val);
 }
-static inline unsigned int edma_shadow0_read(int offset)
+static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset)
 {
-	return edma_read(EDMA_SHADOW0 + offset);
+	return edma_read(ctlr, EDMA_SHADOW0 + offset);
 }
-static inline unsigned int edma_shadow0_read_array(int offset, int i)
+static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset,
+		int i)
 {
-	return edma_read(EDMA_SHADOW0 + offset + (i << 2));
+	return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2));
 }
-static inline void edma_shadow0_write(int offset, unsigned val)
+static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val)
 {
-	edma_write(EDMA_SHADOW0 + offset, val);
+	edma_write(ctlr, EDMA_SHADOW0 + offset, val);
 }
-static inline void edma_shadow0_write_array(int offset, int i, unsigned val)
+static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i,
+		unsigned val)
 {
-	edma_write(EDMA_SHADOW0 + offset + (i << 2), val);
+	edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val);
 }
-static inline unsigned int edma_parm_read(int offset, int param_no)
+static inline unsigned int edma_parm_read(unsigned ctlr, int offset,
+		int param_no)
 {
-	return edma_read(EDMA_PARM + offset + (param_no << 5));
+	return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5));
 }
-static inline void edma_parm_write(int offset, int param_no, unsigned val)
+static inline void edma_parm_write(unsigned ctlr, int offset, int param_no,
+		unsigned val)
 {
-	edma_write(EDMA_PARM + offset + (param_no << 5), val);
+	edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val);
 }
-static inline void edma_parm_modify(int offset, int param_no,
+static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no,
 		unsigned and, unsigned or)
 {
-	edma_modify(EDMA_PARM + offset + (param_no << 5), and, or);
+	edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or);
 }
-static inline void edma_parm_and(int offset, int param_no, unsigned and)
+static inline void edma_parm_and(unsigned ctlr, int offset, int param_no,
+		unsigned and)
 {
-	edma_and(EDMA_PARM + offset + (param_no << 5), and);
+	edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and);
 }
-static inline void edma_parm_or(int offset, int param_no, unsigned or)
+static inline void edma_parm_or(unsigned ctlr, int offset, int param_no,
+		unsigned or)
 {
-	edma_or(EDMA_PARM + offset + (param_no << 5), or);
+	edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or);
 }
 
 /*****************************************************************************/
 
 /* actual number of DMA channels and slots on this silicon */
-static unsigned num_channels;
-static unsigned num_slots;
+struct edma {
+	/* how many dma resources of each type */
+	unsigned	num_channels;
+	unsigned	num_region;
+	unsigned	num_slots;
+	unsigned	num_tc;
+	unsigned	num_cc;
+	enum dma_event_q 	default_queue;
+
+	/* list of channels with no even trigger; terminated by "-1" */
+	const s8	*noevent;
+
+	/* The edma_inuse bit for each PaRAM slot is clear unless the
+	 * channel is in use ... by ARM or DSP, for QDMA, or whatever.
+	 */
+	DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
 
-static struct dma_interrupt_data {
-	void (*callback)(unsigned channel, unsigned short ch_status,
-			 void *data);
-	void *data;
-} intr_data[EDMA_MAX_DMACH];
+	/* The edma_noevent bit for each channel is clear unless
+	 * it doesn't trigger DMA events on this platform.  It uses a
+	 * bit of SOC-specific initialization code.
+	 */
+	DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
 
-/* The edma_inuse bit for each PaRAM slot is clear unless the
- * channel is in use ... by ARM or DSP, for QDMA, or whatever.
- */
-static DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+	unsigned	irq_res_start;
+	unsigned	irq_res_end;
 
-/* The edma_noevent bit for each channel is clear unless
- * it doesn't trigger DMA events on this platform.  It uses a
- * bit of SOC-specific initialization code.
- */
-static DECLARE_BITMAP(edma_noevent, EDMA_MAX_DMACH);
+	struct dma_interrupt_data {
+		void (*callback)(unsigned channel, unsigned short ch_status,
+				void *data);
+		void *data;
+	} intr_data[EDMA_MAX_DMACH];
+};
+
+static struct edma *edma_info[EDMA_MAX_CC];
 
 /* dummy param set used to (re)initialize parameter RAM slots */
 static const struct edmacc_param dummy_paramset = {
@@ -233,47 +259,52 @@ static const struct edmacc_param dummy_paramset = {
 	.ccnt = 1,
 };
 
-static const int __initconst
-queue_tc_mapping[EDMA_MAX_EVQUE + 1][2] = {
-/* {event queue no, TC no} */
-	{0, 0},
-	{1, 1},
-	{-1, -1}
-};
-
-static const int __initconst
-queue_priority_mapping[EDMA_MAX_EVQUE + 1][2] = {
-	/* {event queue no, Priority} */
-	{0, 3},
-	{1, 7},
-	{-1, -1}
-};
-
 /*****************************************************************************/
 
-static void map_dmach_queue(unsigned ch_no, enum dma_event_q queue_no)
+static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
+		enum dma_event_q queue_no)
 {
 	int bit = (ch_no & 0x7) * 4;
 
 	/* default to low priority queue */
 	if (queue_no == EVENTQ_DEFAULT)
-		queue_no = EVENTQ_1;
+		queue_no = edma_info[ctlr]->default_queue;
 
 	queue_no &= 7;
-	edma_modify_array(EDMA_DMAQNUM, (ch_no >> 3),
+	edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3),
 			~(0x7 << bit), queue_no << bit);
 }
 
-static void __init map_queue_tc(int queue_no, int tc_no)
+static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no)
 {
 	int bit = queue_no * 4;
-	edma_modify(EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
+	edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
 }
 
-static void __init assign_priority_to_queue(int queue_no, int priority)
+static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
+		int priority)
 {
 	int bit = queue_no * 4;
-	edma_modify(EDMA_QUEPRI, ~(0x7 << bit), ((priority & 0x7) << bit));
+	edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit),
+			((priority & 0x7) << bit));
+}
+
+/**
+ * map_dmach_param - Maps channel number to param entry number
+ *
+ * This maps the dma channel number to param entry numberter. In
+ * other words using the DMA channel mapping registers a param entry
+ * can be mapped to any channel
+ *
+ * Callers are responsible for ensuring the channel mapping logic is
+ * included in that particular EDMA variant (Eg : dm646x)
+ *
+ */
+static void __init map_dmach_param(unsigned ctlr)
+{
+	int i;
+	for (i = 0; i < EDMA_MAX_DMACH; i++)
+		edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5));
 }
 
 static inline void
@@ -281,22 +312,39 @@ setup_dma_interrupt(unsigned lch,
 	void (*callback)(unsigned channel, u16 ch_status, void *data),
 	void *data)
 {
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(lch);
+	lch = EDMA_CHAN_SLOT(lch);
+
 	if (!callback) {
-		edma_shadow0_write_array(SH_IECR, lch >> 5,
+		edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5,
 				(1 << (lch & 0x1f)));
 	}
 
-	intr_data[lch].callback = callback;
-	intr_data[lch].data = data;
+	edma_info[ctlr]->intr_data[lch].callback = callback;
+	edma_info[ctlr]->intr_data[lch].data = data;
 
 	if (callback) {
-		edma_shadow0_write_array(SH_ICR, lch >> 5,
+		edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5,
 				(1 << (lch & 0x1f)));
-		edma_shadow0_write_array(SH_IESR, lch >> 5,
+		edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5,
 				(1 << (lch & 0x1f)));
 	}
 }
 
+static int irq2ctlr(int irq)
+{
+	if (irq >= edma_info[0]->irq_res_start &&
+		irq <= edma_info[0]->irq_res_end)
+		return 0;
+	else if (irq >= edma_info[1]->irq_res_start &&
+		irq <= edma_info[1]->irq_res_end)
+		return 1;
+
+	return -1;
+}
+
 /******************************************************************************
  *
  * DMA interrupt handler
@@ -305,32 +353,39 @@ setup_dma_interrupt(unsigned lch,
 static irqreturn_t dma_irq_handler(int irq, void *data)
 {
 	int i;
+	unsigned ctlr;
 	unsigned int cnt = 0;
 
+	ctlr = irq2ctlr(irq);
+
 	dev_dbg(data, "dma_irq_handler\n");
 
-	if ((edma_shadow0_read_array(SH_IPR, 0) == 0)
-	    && (edma_shadow0_read_array(SH_IPR, 1) == 0))
+	if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0)
+	    && (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0))
 		return IRQ_NONE;
 
 	while (1) {
 		int j;
-		if (edma_shadow0_read_array(SH_IPR, 0))
+		if (edma_shadow0_read_array(ctlr, SH_IPR, 0))
 			j = 0;
-		else if (edma_shadow0_read_array(SH_IPR, 1))
+		else if (edma_shadow0_read_array(ctlr, SH_IPR, 1))
 			j = 1;
 		else
 			break;
 		dev_dbg(data, "IPR%d %08x\n", j,
-				edma_shadow0_read_array(SH_IPR, j));
+				edma_shadow0_read_array(ctlr, SH_IPR, j));
 		for (i = 0; i < 32; i++) {
 			int k = (j << 5) + i;
-			if (edma_shadow0_read_array(SH_IPR, j) & (1 << i)) {
+			if (edma_shadow0_read_array(ctlr, SH_IPR, j) &
+							(1 << i)) {
 				/* Clear the corresponding IPR bits */
-				edma_shadow0_write_array(SH_ICR, j, (1 << i));
-				if (intr_data[k].callback) {
-					intr_data[k].callback(k, DMA_COMPLETE,
-						intr_data[k].data);
+				edma_shadow0_write_array(ctlr, SH_ICR, j,
+							(1 << i));
+				if (edma_info[ctlr]->intr_data[k].callback) {
+					edma_info[ctlr]->intr_data[k].callback(
+						k, DMA_COMPLETE,
+						edma_info[ctlr]->intr_data[k].
+						data);
 				}
 			}
 		}
@@ -338,7 +393,7 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
 		if (cnt > 10)
 			break;
 	}
-	edma_shadow0_write(SH_IEVAL, 1);
+	edma_shadow0_write(ctlr, SH_IEVAL, 1);
 	return IRQ_HANDLED;
 }
 
@@ -350,78 +405,87 @@ static irqreturn_t dma_irq_handler(int irq, void *data)
 static irqreturn_t dma_ccerr_handler(int irq, void *data)
 {
 	int i;
+	unsigned ctlr;
 	unsigned int cnt = 0;
 
+	ctlr = irq2ctlr(irq);
+
 	dev_dbg(data, "dma_ccerr_handler\n");
 
-	if ((edma_read_array(EDMA_EMR, 0) == 0) &&
-	    (edma_read_array(EDMA_EMR, 1) == 0) &&
-	    (edma_read(EDMA_QEMR) == 0) && (edma_read(EDMA_CCERR) == 0))
+	if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+	    (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+	    (edma_read(ctlr, EDMA_QEMR) == 0) &&
+	    (edma_read(ctlr, EDMA_CCERR) == 0))
 		return IRQ_NONE;
 
 	while (1) {
 		int j = -1;
-		if (edma_read_array(EDMA_EMR, 0))
+		if (edma_read_array(ctlr, EDMA_EMR, 0))
 			j = 0;
-		else if (edma_read_array(EDMA_EMR, 1))
+		else if (edma_read_array(ctlr, EDMA_EMR, 1))
 			j = 1;
 		if (j >= 0) {
 			dev_dbg(data, "EMR%d %08x\n", j,
-					edma_read_array(EDMA_EMR, j));
+					edma_read_array(ctlr, EDMA_EMR, j));
 			for (i = 0; i < 32; i++) {
 				int k = (j << 5) + i;
-				if (edma_read_array(EDMA_EMR, j) & (1 << i)) {
+				if (edma_read_array(ctlr, EDMA_EMR, j) &
+							(1 << i)) {
 					/* Clear the corresponding EMR bits */
-					edma_write_array(EDMA_EMCR, j, 1 << i);
+					edma_write_array(ctlr, EDMA_EMCR, j,
+							1 << i);
 					/* Clear any SER */
-					edma_shadow0_write_array(SH_SECR, j,
-							(1 << i));
-					if (intr_data[k].callback) {
-						intr_data[k].callback(k,
-								DMA_CC_ERROR,
-								intr_data
-								[k].data);
+					edma_shadow0_write_array(ctlr, SH_SECR,
+								j, (1 << i));
+					if (edma_info[ctlr]->intr_data[k].
+								callback) {
+						edma_info[ctlr]->intr_data[k].
+						callback(k,
+						DMA_CC_ERROR,
+						edma_info[ctlr]->intr_data
+						[k].data);
 					}
 				}
 			}
-		} else if (edma_read(EDMA_QEMR)) {
+		} else if (edma_read(ctlr, EDMA_QEMR)) {
 			dev_dbg(data, "QEMR %02x\n",
-				edma_read(EDMA_QEMR));
+				edma_read(ctlr, EDMA_QEMR));
 			for (i = 0; i < 8; i++) {
-				if (edma_read(EDMA_QEMR) & (1 << i)) {
+				if (edma_read(ctlr, EDMA_QEMR) & (1 << i)) {
 					/* Clear the corresponding IPR bits */
-					edma_write(EDMA_QEMCR, 1 << i);
-					edma_shadow0_write(SH_QSECR, (1 << i));
+					edma_write(ctlr, EDMA_QEMCR, 1 << i);
+					edma_shadow0_write(ctlr, SH_QSECR,
+								(1 << i));
 
 					/* NOTE:  not reported!! */
 				}
 			}
-		} else if (edma_read(EDMA_CCERR)) {
+		} else if (edma_read(ctlr, EDMA_CCERR)) {
 			dev_dbg(data, "CCERR %08x\n",
-				edma_read(EDMA_CCERR));
+				edma_read(ctlr, EDMA_CCERR));
 			/* FIXME:  CCERR.BIT(16) ignored!  much better
 			 * to just write CCERRCLR with CCERR value...
 			 */
 			for (i = 0; i < 8; i++) {
-				if (edma_read(EDMA_CCERR) & (1 << i)) {
+				if (edma_read(ctlr, EDMA_CCERR) & (1 << i)) {
 					/* Clear the corresponding IPR bits */
-					edma_write(EDMA_CCERRCLR, 1 << i);
+					edma_write(ctlr, EDMA_CCERRCLR, 1 << i);
 
 					/* NOTE:  not reported!! */
 				}
 			}
 		}
-		if ((edma_read_array(EDMA_EMR, 0) == 0)
-		    && (edma_read_array(EDMA_EMR, 1) == 0)
-		    && (edma_read(EDMA_QEMR) == 0)
-		    && (edma_read(EDMA_CCERR) == 0)) {
+		if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0)
+		    && (edma_read_array(ctlr, EDMA_EMR, 1) == 0)
+		    && (edma_read(ctlr, EDMA_QEMR) == 0)
+		    && (edma_read(ctlr, EDMA_CCERR) == 0)) {
 			break;
 		}
 		cnt++;
 		if (cnt > 10)
 			break;
 	}
-	edma_write(EDMA_EEVAL, 1);
+	edma_write(ctlr, EDMA_EEVAL, 1);
 	return IRQ_HANDLED;
 }
 
@@ -445,6 +509,45 @@ static irqreturn_t dma_tc1err_handler(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static int reserve_contiguous_params(int ctlr, unsigned int id,
+				     unsigned int num_params,
+				     unsigned int start_param)
+{
+	int i, j;
+	unsigned int count = num_params;
+
+	for (i = start_param; i < edma_info[ctlr]->num_slots; ++i) {
+		j = EDMA_CHAN_SLOT(i);
+		if (!test_and_set_bit(j, edma_info[ctlr]->edma_inuse))
+			count--;
+			if (count == 0)
+				break;
+		else if (id == EDMA_CONT_PARAMS_FIXED_EXACT)
+			break;
+		else
+			count = num_params;
+	}
+
+	/*
+	 * We have to clear any bits that we set
+	 * if we run out parameter RAMs, i.e we do find a set
+	 * of contiguous parameter RAMs but do not find the exact number
+	 * requested as we may reach the total number of parameter RAMs
+	 */
+	if (count) {
+		for (j = i - num_params + count + 1; j <= i ; ++j)
+			clear_bit(j, edma_info[ctlr]->edma_inuse);
+
+		return -EBUSY;
+	}
+
+	for (j = i - num_params + 1; j <= i; ++j)
+		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
+			&dummy_paramset, PARM_SIZE);
+
+	return EDMA_CTLR_CHAN(ctlr, i - num_params + 1);
+}
+
 /*-----------------------------------------------------------------------*/
 
 /* Resource alloc/free:  dma channels, parameter RAM slots */
@@ -484,35 +587,53 @@ int edma_alloc_channel(int channel,
 		void *data,
 		enum dma_event_q eventq_no)
 {
+	unsigned i, done, ctlr = 0;
+
+	if (channel >= 0) {
+		ctlr = EDMA_CTLR(channel);
+		channel = EDMA_CHAN_SLOT(channel);
+	}
+
 	if (channel < 0) {
-		channel = 0;
-		for (;;) {
-			channel = find_next_bit(edma_noevent,
-					num_channels, channel);
-			if (channel == num_channels)
-				return -ENOMEM;
-			if (!test_and_set_bit(channel, edma_inuse))
+		for (i = 0; i < EDMA_MAX_CC; i++) {
+			channel = 0;
+			for (;;) {
+				channel = find_next_bit(edma_info[i]->
+						edma_noevent,
+						edma_info[i]->num_channels,
+						channel);
+				if (channel == edma_info[i]->num_channels)
+					return -ENOMEM;
+				if (!test_and_set_bit(channel,
+						edma_info[i]->edma_inuse)) {
+					done = 1;
+					ctlr = i;
+					break;
+				}
+				channel++;
+			}
+			if (done)
 				break;
-			channel++;
 		}
-	} else if (channel >= num_channels) {
+	} else if (channel >= edma_info[ctlr]->num_channels) {
 		return -EINVAL;
-	} else if (test_and_set_bit(channel, edma_inuse)) {
+	} else if (test_and_set_bit(channel, edma_info[ctlr]->edma_inuse)) {
 		return -EBUSY;
 	}
 
 	/* ensure access through shadow region 0 */
-	edma_or_array2(EDMA_DRAE, 0, channel >> 5, 1 << (channel & 0x1f));
+	edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, 1 << (channel & 0x1f));
 
 	/* ensure no events are pending */
-	edma_stop(channel);
-	memcpy_toio(edmacc_regs_base + PARM_OFFSET(channel),
+	edma_stop(EDMA_CTLR_CHAN(ctlr, channel));
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
 			&dummy_paramset, PARM_SIZE);
 
 	if (callback)
-		setup_dma_interrupt(channel, callback, data);
+		setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel),
+					callback, data);
 
-	map_dmach_queue(channel, eventq_no);
+	map_dmach_queue(ctlr, channel, eventq_no);
 
 	return channel;
 }
@@ -532,15 +653,20 @@ EXPORT_SYMBOL(edma_alloc_channel);
  */
 void edma_free_channel(unsigned channel)
 {
-	if (channel >= num_channels)
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel >= edma_info[ctlr]->num_channels)
 		return;
 
 	setup_dma_interrupt(channel, NULL, NULL);
 	/* REVISIT should probably take out of shadow region 0 */
 
-	memcpy_toio(edmacc_regs_base + PARM_OFFSET(channel),
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
 			&dummy_paramset, PARM_SIZE);
-	clear_bit(channel, edma_inuse);
+	clear_bit(channel, edma_info[ctlr]->edma_inuse);
 }
 EXPORT_SYMBOL(edma_free_channel);
 
@@ -558,28 +684,33 @@ EXPORT_SYMBOL(edma_free_channel);
  *
  * Returns the number of the slot, else negative errno.
  */
-int edma_alloc_slot(int slot)
+int edma_alloc_slot(unsigned ctlr, int slot)
 {
+	if (slot >= 0)
+		slot = EDMA_CHAN_SLOT(slot);
+
 	if (slot < 0) {
-		slot = num_channels;
+		slot = edma_info[ctlr]->num_channels;
 		for (;;) {
-			slot = find_next_zero_bit(edma_inuse,
-					num_slots, slot);
-			if (slot == num_slots)
+			slot = find_next_zero_bit(edma_info[ctlr]->edma_inuse,
+					edma_info[ctlr]->num_slots, slot);
+			if (slot == edma_info[ctlr]->num_slots)
 				return -ENOMEM;
-			if (!test_and_set_bit(slot, edma_inuse))
+			if (!test_and_set_bit(slot,
+						edma_info[ctlr]->edma_inuse))
 				break;
 		}
-	} else if (slot < num_channels || slot >= num_slots) {
+	} else if (slot < edma_info[ctlr]->num_channels ||
+			slot >= edma_info[ctlr]->num_slots) {
 		return -EINVAL;
-	} else if (test_and_set_bit(slot, edma_inuse)) {
+	} else if (test_and_set_bit(slot, edma_info[ctlr]->edma_inuse)) {
 		return -EBUSY;
 	}
 
-	memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot),
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
 			&dummy_paramset, PARM_SIZE);
 
-	return slot;
+	return EDMA_CTLR_CHAN(ctlr, slot);
 }
 EXPORT_SYMBOL(edma_alloc_slot);
 
@@ -593,15 +724,119 @@ EXPORT_SYMBOL(edma_alloc_slot);
  */
 void edma_free_slot(unsigned slot)
 {
-	if (slot < num_channels || slot >= num_slots)
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_info[ctlr]->num_channels ||
+		slot >= edma_info[ctlr]->num_slots)
 		return;
 
-	memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot),
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
 			&dummy_paramset, PARM_SIZE);
-	clear_bit(slot, edma_inuse);
+	clear_bit(slot, edma_info[ctlr]->edma_inuse);
 }
 EXPORT_SYMBOL(edma_free_slot);
 
+
+/**
+ * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
+ * The API will return the starting point of a set of
+ * contiguous PARAM's that have been requested
+ *
+ * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
+ * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ * @count: number of contiguous Paramter RAM's
+ * @param  - the start value of Parameter RAM that should be passed if id
+ * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ *
+ * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
+ * contiguous Parameter RAMs from parameter RAM 64 in the case of DaVinci SOCs
+ * and 32 in the case of Primus
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
+ * set of contiguous parameter RAMs from the "param" that is passed as an
+ * argument to the API.
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
+ * starts looking for a set of contiguous parameter RAMs from the "param"
+ * that is passed as an argument to the API. On failure the API will try to
+ * find a set of contiguous Parameter RAMs in the remaining Parameter RAMs
+ */
+int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
+{
+	/*
+	 * The start slot requested should be greater than
+	 * the number of channels and lesser than the total number
+	 * of slots
+	 */
+	if (slot < edma_info[ctlr]->num_channels ||
+		slot >= edma_info[ctlr]->num_slots)
+		return -EINVAL;
+
+	/*
+	 * The number of parameter RAMs requested cannot be less than 1
+	 * and cannot be more than the number of slots minus the number of
+	 * channels
+	 */
+	if (count < 1 || count >
+		(edma_info[ctlr]->num_slots - edma_info[ctlr]->num_channels))
+		return -EINVAL;
+
+	switch (id) {
+	case EDMA_CONT_PARAMS_ANY:
+		return reserve_contiguous_params(ctlr, id, count,
+						 edma_info[ctlr]->num_channels);
+	case EDMA_CONT_PARAMS_FIXED_EXACT:
+	case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
+		return reserve_contiguous_params(ctlr, id, count, slot);
+	default:
+		return -EINVAL;
+	}
+
+}
+EXPORT_SYMBOL(edma_alloc_cont_slots);
+
+/**
+ * edma_free_cont_slots - deallocate DMA parameter RAMs
+ * @slot: first parameter RAM of a set of parameter RAMs to be freed
+ * @count: the number of contiguous parameter RAMs to be freed
+ *
+ * This deallocates the parameter RAM slots allocated by
+ * edma_alloc_cont_slots.
+ * Callers/applications need to keep track of sets of contiguous
+ * parameter RAMs that have been allocated using the edma_alloc_cont_slots
+ * API.
+ * Callers are responsible for ensuring the slots are inactive, and will
+ * not be activated.
+ */
+int edma_free_cont_slots(unsigned slot, int count)
+{
+	unsigned ctlr;
+	int i;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_info[ctlr]->num_channels ||
+		slot >= edma_info[ctlr]->num_slots ||
+		count < 1)
+		return -EINVAL;
+
+	for (i = slot; i < slot + count; ++i) {
+		ctlr = EDMA_CTLR(i);
+		slot = EDMA_CHAN_SLOT(i);
+
+		memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+			&dummy_paramset, PARM_SIZE);
+		clear_bit(slot, edma_info[ctlr]->edma_inuse);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(edma_free_cont_slots);
+
 /*-----------------------------------------------------------------------*/
 
 /* Parameter RAM operations (i) -- read/write partial slots */
@@ -620,8 +855,13 @@ EXPORT_SYMBOL(edma_free_slot);
 void edma_set_src(unsigned slot, dma_addr_t src_port,
 				enum address_mode mode, enum fifo_width width)
 {
-	if (slot < num_slots) {
-		unsigned int i = edma_parm_read(PARM_OPT, slot);
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_info[ctlr]->num_slots) {
+		unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
 
 		if (mode) {
 			/* set SAM and program FWID */
@@ -630,11 +870,11 @@ void edma_set_src(unsigned slot, dma_addr_t src_port,
 			/* clear SAM */
 			i &= ~SAM;
 		}
-		edma_parm_write(PARM_OPT, slot, i);
+		edma_parm_write(ctlr, PARM_OPT, slot, i);
 
 		/* set the source port address
 		   in source register of param structure */
-		edma_parm_write(PARM_SRC, slot, src_port);
+		edma_parm_write(ctlr, PARM_SRC, slot, src_port);
 	}
 }
 EXPORT_SYMBOL(edma_set_src);
@@ -653,8 +893,13 @@ EXPORT_SYMBOL(edma_set_src);
 void edma_set_dest(unsigned slot, dma_addr_t dest_port,
 				 enum address_mode mode, enum fifo_width width)
 {
-	if (slot < num_slots) {
-		unsigned int i = edma_parm_read(PARM_OPT, slot);
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_info[ctlr]->num_slots) {
+		unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
 
 		if (mode) {
 			/* set DAM and program FWID */
@@ -663,10 +908,10 @@ void edma_set_dest(unsigned slot, dma_addr_t dest_port,
 			/* clear DAM */
 			i &= ~DAM;
 		}
-		edma_parm_write(PARM_OPT, slot, i);
+		edma_parm_write(ctlr, PARM_OPT, slot, i);
 		/* set the destination port address
 		   in dest register of param structure */
-		edma_parm_write(PARM_DST, slot, dest_port);
+		edma_parm_write(ctlr, PARM_DST, slot, dest_port);
 	}
 }
 EXPORT_SYMBOL(edma_set_dest);
@@ -683,8 +928,12 @@ EXPORT_SYMBOL(edma_set_dest);
 void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
 {
 	struct edmacc_param temp;
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
 
-	edma_read_slot(slot, &temp);
+	edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp);
 	if (src != NULL)
 		*src = temp.src;
 	if (dst != NULL)
@@ -704,10 +953,15 @@ EXPORT_SYMBOL(edma_get_position);
  */
 void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
 {
-	if (slot < num_slots) {
-		edma_parm_modify(PARM_SRC_DST_BIDX, slot,
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_info[ctlr]->num_slots) {
+		edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
 				0xffff0000, src_bidx);
-		edma_parm_modify(PARM_SRC_DST_CIDX, slot,
+		edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
 				0xffff0000, src_cidx);
 	}
 }
@@ -725,10 +979,15 @@ EXPORT_SYMBOL(edma_set_src_index);
  */
 void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
 {
-	if (slot < num_slots) {
-		edma_parm_modify(PARM_SRC_DST_BIDX, slot,
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_info[ctlr]->num_slots) {
+		edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
 				0x0000ffff, dest_bidx << 16);
-		edma_parm_modify(PARM_SRC_DST_CIDX, slot,
+		edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
 				0x0000ffff, dest_cidx << 16);
 	}
 }
@@ -767,16 +1026,21 @@ void edma_set_transfer_params(unsigned slot,
 		u16 acnt, u16 bcnt, u16 ccnt,
 		u16 bcnt_rld, enum sync_dimension sync_mode)
 {
-	if (slot < num_slots) {
-		edma_parm_modify(PARM_LINK_BCNTRLD, slot,
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot < edma_info[ctlr]->num_slots) {
+		edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot,
 				0x0000ffff, bcnt_rld << 16);
 		if (sync_mode == ASYNC)
-			edma_parm_and(PARM_OPT, slot, ~SYNCDIM);
+			edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM);
 		else
-			edma_parm_or(PARM_OPT, slot, SYNCDIM);
+			edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM);
 		/* Set the acount, bcount, ccount registers */
-		edma_parm_write(PARM_A_B_CNT, slot, (bcnt << 16) | acnt);
-		edma_parm_write(PARM_CCNT, slot, ccnt);
+		edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt);
+		edma_parm_write(ctlr, PARM_CCNT, slot, ccnt);
 	}
 }
 EXPORT_SYMBOL(edma_set_transfer_params);
@@ -790,11 +1054,19 @@ EXPORT_SYMBOL(edma_set_transfer_params);
  */
 void edma_link(unsigned from, unsigned to)
 {
-	if (from >= num_slots)
+	unsigned ctlr_from, ctlr_to;
+
+	ctlr_from = EDMA_CTLR(from);
+	from = EDMA_CHAN_SLOT(from);
+	ctlr_to = EDMA_CTLR(to);
+	to = EDMA_CHAN_SLOT(to);
+
+	if (from >= edma_info[ctlr_from]->num_slots)
 		return;
-	if (to >= num_slots)
+	if (to >= edma_info[ctlr_to]->num_slots)
 		return;
-	edma_parm_modify(PARM_LINK_BCNTRLD, from, 0xffff0000, PARM_OFFSET(to));
+	edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000,
+				PARM_OFFSET(to));
 }
 EXPORT_SYMBOL(edma_link);
 
@@ -807,9 +1079,14 @@ EXPORT_SYMBOL(edma_link);
  */
 void edma_unlink(unsigned from)
 {
-	if (from >= num_slots)
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(from);
+	from = EDMA_CHAN_SLOT(from);
+
+	if (from >= edma_info[ctlr]->num_slots)
 		return;
-	edma_parm_or(PARM_LINK_BCNTRLD, from, 0xffff);
+	edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff);
 }
 EXPORT_SYMBOL(edma_unlink);
 
@@ -829,9 +1106,15 @@ EXPORT_SYMBOL(edma_unlink);
  */
 void edma_write_slot(unsigned slot, const struct edmacc_param *param)
 {
-	if (slot >= num_slots)
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot >= edma_info[ctlr]->num_slots)
 		return;
-	memcpy_toio(edmacc_regs_base + PARM_OFFSET(slot), param, PARM_SIZE);
+	memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param,
+			PARM_SIZE);
 }
 EXPORT_SYMBOL(edma_write_slot);
 
@@ -845,9 +1128,15 @@ EXPORT_SYMBOL(edma_write_slot);
  */
 void edma_read_slot(unsigned slot, struct edmacc_param *param)
 {
-	if (slot >= num_slots)
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(slot);
+	slot = EDMA_CHAN_SLOT(slot);
+
+	if (slot >= edma_info[ctlr]->num_slots)
 		return;
-	memcpy_fromio(param, edmacc_regs_base + PARM_OFFSET(slot), PARM_SIZE);
+	memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+			PARM_SIZE);
 }
 EXPORT_SYMBOL(edma_read_slot);
 
@@ -864,10 +1153,15 @@ EXPORT_SYMBOL(edma_read_slot);
  */
 void edma_pause(unsigned channel)
 {
-	if (channel < num_channels) {
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_info[ctlr]->num_channels) {
 		unsigned int mask = (1 << (channel & 0x1f));
 
-		edma_shadow0_write_array(SH_EECR, channel >> 5, mask);
+		edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask);
 	}
 }
 EXPORT_SYMBOL(edma_pause);
@@ -880,10 +1174,15 @@ EXPORT_SYMBOL(edma_pause);
  */
 void edma_resume(unsigned channel)
 {
-	if (channel < num_channels) {
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_info[ctlr]->num_channels) {
 		unsigned int mask = (1 << (channel & 0x1f));
 
-		edma_shadow0_write_array(SH_EESR, channel >> 5, mask);
+		edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask);
 	}
 }
 EXPORT_SYMBOL(edma_resume);
@@ -901,28 +1200,33 @@ EXPORT_SYMBOL(edma_resume);
  */
 int edma_start(unsigned channel)
 {
-	if (channel < num_channels) {
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_info[ctlr]->num_channels) {
 		int j = channel >> 5;
 		unsigned int mask = (1 << (channel & 0x1f));
 
 		/* EDMA channels without event association */
-		if (test_bit(channel, edma_noevent)) {
+		if (test_bit(channel, edma_info[ctlr]->edma_noevent)) {
 			pr_debug("EDMA: ESR%d %08x\n", j,
-				edma_shadow0_read_array(SH_ESR, j));
-			edma_shadow0_write_array(SH_ESR, j, mask);
+				edma_shadow0_read_array(ctlr, SH_ESR, j));
+			edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
 			return 0;
 		}
 
 		/* EDMA channel with event association */
 		pr_debug("EDMA: ER%d %08x\n", j,
-			edma_shadow0_read_array(SH_ER, j));
+			edma_shadow0_read_array(ctlr, SH_ER, j));
 		/* Clear any pending error */
-		edma_write_array(EDMA_EMCR, j, mask);
+		edma_write_array(ctlr, EDMA_EMCR, j, mask);
 		/* Clear any SER */
-		edma_shadow0_write_array(SH_SECR, j, mask);
-		edma_shadow0_write_array(SH_EESR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_EESR, j, mask);
 		pr_debug("EDMA: EER%d %08x\n", j,
-			edma_shadow0_read_array(SH_EER, j));
+			edma_shadow0_read_array(ctlr, SH_EER, j));
 		return 0;
 	}
 
@@ -941,17 +1245,22 @@ EXPORT_SYMBOL(edma_start);
  */
 void edma_stop(unsigned channel)
 {
-	if (channel < num_channels) {
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_info[ctlr]->num_channels) {
 		int j = channel >> 5;
 		unsigned int mask = (1 << (channel & 0x1f));
 
-		edma_shadow0_write_array(SH_EECR, j, mask);
-		edma_shadow0_write_array(SH_ECR, j, mask);
-		edma_shadow0_write_array(SH_SECR, j, mask);
-		edma_write_array(EDMA_EMCR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_EECR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
+		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+		edma_write_array(ctlr, EDMA_EMCR, j, mask);
 
 		pr_debug("EDMA: EER%d %08x\n", j,
-				edma_shadow0_read_array(SH_EER, j));
+				edma_shadow0_read_array(ctlr, SH_EER, j));
 
 		/* REVISIT:  consider guarding against inappropriate event
 		 * chaining by overwriting with dummy_paramset.
@@ -975,18 +1284,23 @@ EXPORT_SYMBOL(edma_stop);
 
 void edma_clean_channel(unsigned channel)
 {
-	if (channel < num_channels) {
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel < edma_info[ctlr]->num_channels) {
 		int j = (channel >> 5);
 		unsigned int mask = 1 << (channel & 0x1f);
 
 		pr_debug("EDMA: EMR%d %08x\n", j,
-				edma_read_array(EDMA_EMR, j));
-		edma_shadow0_write_array(SH_ECR, j, mask);
+				edma_read_array(ctlr, EDMA_EMR, j));
+		edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
 		/* Clear the corresponding EMR bits */
-		edma_write_array(EDMA_EMCR, j, mask);
+		edma_write_array(ctlr, EDMA_EMCR, j, mask);
 		/* Clear any SER */
-		edma_shadow0_write_array(SH_SECR, j, mask);
-		edma_write(EDMA_CCERRCLR, (1 << 16) | 0x3);
+		edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+		edma_write(ctlr, EDMA_CCERRCLR, (1 << 16) | 0x3);
 	}
 }
 EXPORT_SYMBOL(edma_clean_channel);
@@ -998,12 +1312,17 @@ EXPORT_SYMBOL(edma_clean_channel);
  */
 void edma_clear_event(unsigned channel)
 {
-	if (channel >= num_channels)
+	unsigned ctlr;
+
+	ctlr = EDMA_CTLR(channel);
+	channel = EDMA_CHAN_SLOT(channel);
+
+	if (channel >= edma_info[ctlr]->num_channels)
 		return;
 	if (channel < 32)
-		edma_write(EDMA_ECR, 1 << channel);
+		edma_write(ctlr, EDMA_ECR, 1 << channel);
 	else
-		edma_write(EDMA_ECRH, 1 << (channel - 32));
+		edma_write(ctlr, EDMA_ECRH, 1 << (channel - 32));
 }
 EXPORT_SYMBOL(edma_clear_event);
 
@@ -1012,62 +1331,133 @@ EXPORT_SYMBOL(edma_clear_event);
 static int __init edma_probe(struct platform_device *pdev)
 {
 	struct edma_soc_info	*info = pdev->dev.platform_data;
-	int			i;
-	int			status;
+	const s8		(*queue_priority_mapping)[2];
+	const s8		(*queue_tc_mapping)[2];
+	int			i, j, found = 0;
+	int			status = -1;
 	const s8		*noevent;
-	int			irq = 0, err_irq = 0;
-	struct resource		*r;
-	resource_size_t		len;
+	int			irq[EDMA_MAX_CC] = {0, 0};
+	int			err_irq[EDMA_MAX_CC] = {0, 0};
+	struct resource		*r[EDMA_MAX_CC] = {NULL};
+	resource_size_t		len[EDMA_MAX_CC];
+	char			res_name[10];
+	char			irq_name[10];
 
 	if (!info)
 		return -ENODEV;
 
-	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "edma_cc");
-	if (!r)
-		return -ENODEV;
+	for (j = 0; j < EDMA_MAX_CC; j++) {
+		sprintf(res_name, "edma_cc%d", j);
+		r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						res_name);
+		if (!r[j]) {
+			if (found)
+				break;
+			else
+				return -ENODEV;
+		} else
+			found = 1;
+
+		len[j] = resource_size(r[j]);
+
+		r[j] = request_mem_region(r[j]->start, len[j],
+			dev_name(&pdev->dev));
+		if (!r[j]) {
+			status = -EBUSY;
+			goto fail1;
+		}
 
-	len = r->end - r->start + 1;
+		edmacc_regs_base[j] = ioremap(r[j]->start, len[j]);
+		if (!edmacc_regs_base[j]) {
+			status = -EBUSY;
+			goto fail1;
+		}
 
-	r = request_mem_region(r->start, len, r->name);
-	if (!r)
-		return -EBUSY;
+		edma_info[j] = kmalloc(sizeof(struct edma), GFP_KERNEL);
+		if (!edma_info[j]) {
+			status = -ENOMEM;
+			goto fail1;
+		}
+		memset(edma_info[j], 0, sizeof(struct edma));
+
+		edma_info[j]->num_channels = min_t(unsigned, info[j].n_channel,
+							EDMA_MAX_DMACH);
+		edma_info[j]->num_slots = min_t(unsigned, info[j].n_slot,
+							EDMA_MAX_PARAMENTRY);
+		edma_info[j]->num_cc = min_t(unsigned, info[j].n_cc,
+							EDMA_MAX_CC);
+
+		edma_info[j]->default_queue = info[j].default_queue;
+		if (!edma_info[j]->default_queue)
+			edma_info[j]->default_queue = EVENTQ_1;
+
+		dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
+			edmacc_regs_base[j]);
+
+		for (i = 0; i < edma_info[j]->num_slots; i++)
+			memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
+					&dummy_paramset, PARM_SIZE);
+
+		noevent = info[j].noevent;
+		if (noevent) {
+			while (*noevent != -1)
+				set_bit(*noevent++, edma_info[j]->edma_noevent);
+		}
 
-	edmacc_regs_base = ioremap(r->start, len);
-	if (!edmacc_regs_base) {
-		status = -EBUSY;
-		goto fail1;
-	}
+		sprintf(irq_name, "edma%d", j);
+		irq[j] = platform_get_irq_byname(pdev, irq_name);
+		edma_info[j]->irq_res_start = irq[j];
+		status = request_irq(irq[j], dma_irq_handler, 0, "edma",
+					&pdev->dev);
+		if (status < 0) {
+			dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+				irq[j], status);
+			goto fail;
+		}
 
-	num_channels = min_t(unsigned, info->n_channel, EDMA_MAX_DMACH);
-	num_slots = min_t(unsigned, info->n_slot, EDMA_MAX_PARAMENTRY);
+		sprintf(irq_name, "edma%d_err", j);
+		err_irq[j] = platform_get_irq_byname(pdev, irq_name);
+		edma_info[j]->irq_res_end = err_irq[j];
+		status = request_irq(err_irq[j], dma_ccerr_handler, 0,
+					"edma_error", &pdev->dev);
+		if (status < 0) {
+			dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+				err_irq[j], status);
+			goto fail;
+		}
 
-	dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n", edmacc_regs_base);
+		/* Everything lives on transfer controller 1 until otherwise
+		 * specified. This way, long transfers on the low priority queue
+		 * started by the codec engine will not cause audio defects.
+		 */
+		for (i = 0; i < edma_info[j]->num_channels; i++)
+			map_dmach_queue(j, i, EVENTQ_1);
 
-	for (i = 0; i < num_slots; i++)
-		memcpy_toio(edmacc_regs_base + PARM_OFFSET(i),
-				&dummy_paramset, PARM_SIZE);
+		queue_tc_mapping = info[j].queue_tc_mapping;
+		queue_priority_mapping = info[j].queue_priority_mapping;
 
-	noevent = info->noevent;
-	if (noevent) {
-		while (*noevent != -1)
-			set_bit(*noevent++, edma_noevent);
-	}
+		/* Event queue to TC mapping */
+		for (i = 0; queue_tc_mapping[i][0] != -1; i++)
+			map_queue_tc(j, queue_tc_mapping[i][0],
+					queue_tc_mapping[i][1]);
 
-	irq = platform_get_irq(pdev, 0);
-	status = request_irq(irq, dma_irq_handler, 0, "edma", &pdev->dev);
-	if (status < 0) {
-		dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
-			irq, status);
-		goto fail;
-	}
+		/* Event queue priority mapping */
+		for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+			assign_priority_to_queue(j,
+						queue_priority_mapping[i][0],
+						queue_priority_mapping[i][1]);
+
+		/* Map the channel to param entry if channel mapping logic
+		 * exist
+		 */
+		if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
+			map_dmach_param(j);
 
-	err_irq = platform_get_irq(pdev, 1);
-	status = request_irq(err_irq, dma_ccerr_handler, 0,
-				"edma_error", &pdev->dev);
-	if (status < 0) {
-		dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
-			err_irq, status);
-		goto fail;
+		for (i = 0; i < info[j].n_region; i++) {
+			edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
+			edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
+			edma_write_array(j, EDMA_QRAE, i, 0x0);
+		}
 	}
 
 	if (tc_errs_handled) {
@@ -1087,38 +1477,23 @@ static int __init edma_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* Everything lives on transfer controller 1 until otherwise specified.
-	 * This way, long transfers on the low priority queue
-	 * started by the codec engine will not cause audio defects.
-	 */
-	for (i = 0; i < num_channels; i++)
-		map_dmach_queue(i, EVENTQ_1);
-
-	/* Event queue to TC mapping */
-	for (i = 0; queue_tc_mapping[i][0] != -1; i++)
-		map_queue_tc(queue_tc_mapping[i][0], queue_tc_mapping[i][1]);
-
-	/* Event queue priority mapping */
-	for (i = 0; queue_priority_mapping[i][0] != -1; i++)
-		assign_priority_to_queue(queue_priority_mapping[i][0],
-					 queue_priority_mapping[i][1]);
-
-	for (i = 0; i < info->n_region; i++) {
-		edma_write_array2(EDMA_DRAE, i, 0, 0x0);
-		edma_write_array2(EDMA_DRAE, i, 1, 0x0);
-		edma_write_array(EDMA_QRAE, i, 0x0);
-	}
-
 	return 0;
 
 fail:
-	if (err_irq)
-		free_irq(err_irq, NULL);
-	if (irq)
-		free_irq(irq, NULL);
-	iounmap(edmacc_regs_base);
+	for (i = 0; i < EDMA_MAX_CC; i++) {
+		if (err_irq[i])
+			free_irq(err_irq[i], &pdev->dev);
+		if (irq[i])
+			free_irq(irq[i], &pdev->dev);
+	}
 fail1:
-	release_mem_region(r->start, len);
+	for (i = 0; i < EDMA_MAX_CC; i++) {
+		if (r[i])
+			release_mem_region(r[i]->start, len[i]);
+		if (edmacc_regs_base[i])
+			iounmap(edmacc_regs_base[i]);
+		kfree(edma_info[i]);
+	}
 	return status;
 }
 
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 1b65321..f6ea9db 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -34,6 +34,7 @@ static DEFINE_SPINLOCK(gpio_lock);
 struct davinci_gpio {
 	struct gpio_chip	chip;
 	struct gpio_controller	*__iomem regs;
+	int			irq_base;
 };
 
 static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
@@ -161,8 +162,7 @@ pure_initcall(davinci_gpio_setup);
  * used as output pins ... which is convenient for testing.
  *
  * NOTE:  The first few GPIOs also have direct INTC hookups in addition
- * to their GPIOBNK0 irq, with a bit less overhead but less flexibility
- * on triggering (e.g. no edge options).  We don't try to use those.
+ * to their GPIOBNK0 irq, with a bit less overhead.
  *
  * All those INTC hookups (direct, plus several IRQ banks) can also
  * serve as EDMA event triggers.
@@ -171,7 +171,7 @@ pure_initcall(davinci_gpio_setup);
 static void gpio_irq_disable(unsigned irq)
 {
 	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = __gpio_mask(irq_to_gpio(irq));
+	u32 mask = (u32) get_irq_data(irq);
 
 	__raw_writel(mask, &g->clr_falling);
 	__raw_writel(mask, &g->clr_rising);
@@ -180,7 +180,7 @@ static void gpio_irq_disable(unsigned irq)
 static void gpio_irq_enable(unsigned irq)
 {
 	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = __gpio_mask(irq_to_gpio(irq));
+	u32 mask = (u32) get_irq_data(irq);
 	unsigned status = irq_desc[irq].status;
 
 	status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
@@ -196,7 +196,7 @@ static void gpio_irq_enable(unsigned irq)
 static int gpio_irq_type(unsigned irq, unsigned trigger)
 {
 	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
-	u32 mask = __gpio_mask(irq_to_gpio(irq));
+	u32 mask = (u32) get_irq_data(irq);
 
 	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
 		return -EINVAL;
@@ -260,6 +260,45 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 	/* now it may re-trigger */
 }
 
+static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
+{
+	struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+
+	if (d->irq_base >= 0)
+		return d->irq_base + offset;
+	else
+		return -ENODEV;
+}
+
+static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
+{
+	struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+	/* NOTE:  we assume for now that only irqs in the first gpio_chip
+	 * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
+	 */
+	if (offset < soc_info->gpio_unbanked)
+		return soc_info->gpio_irq + offset;
+	else
+		return -ENODEV;
+}
+
+static int gpio_irq_type_unbanked(unsigned irq, unsigned trigger)
+{
+	struct gpio_controller *__iomem g = get_irq_chip_data(irq);
+	u32 mask = (u32) get_irq_data(irq);
+
+	if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+		return -EINVAL;
+
+	__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
+		     ? &g->set_falling : &g->clr_falling);
+	__raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
+		     ? &g->set_rising : &g->clr_rising);
+
+	return 0;
+}
+
 /*
  * NOTE:  for suspend/resume, probably best to make a platform_device with
  * suspend_late/resume_resume calls hooking into results of the set_wake()
@@ -275,6 +314,7 @@ static int __init davinci_gpio_irq_setup(void)
 	u32		binten = 0;
 	unsigned	ngpio, bank_irq;
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
+	struct gpio_controller	*__iomem g;
 
 	ngpio = soc_info->gpio_num;
 
@@ -292,12 +332,63 @@ static int __init davinci_gpio_irq_setup(void)
 	}
 	clk_enable(clk);
 
+	/* Arrange gpio_to_irq() support, handling either direct IRQs or
+	 * banked IRQs.  Having GPIOs in the first GPIO bank use direct
+	 * IRQs, while the others use banked IRQs, would need some setup
+	 * tweaks to recognize hardware which can do that.
+	 */
+	for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
+		chips[bank].chip.to_irq = gpio_to_irq_banked;
+		chips[bank].irq_base = soc_info->gpio_unbanked
+			? -EINVAL
+			: (soc_info->intc_irq_num + gpio);
+	}
+
+	/*
+	 * AINTC can handle direct/unbanked IRQs for GPIOs, with the GPIO
+	 * controller only handling trigger modes.  We currently assume no
+	 * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
+	 */
+	if (soc_info->gpio_unbanked) {
+		static struct irq_chip gpio_irqchip_unbanked;
+
+		/* pass "bank 0" GPIO IRQs to AINTC */
+		chips[0].chip.to_irq = gpio_to_irq_unbanked;
+		binten = BIT(0);
+
+		/* AINTC handles mask/unmask; GPIO handles triggering */
+		irq = bank_irq;
+		gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq));
+		gpio_irqchip_unbanked.name = "GPIO-AINTC";
+		gpio_irqchip_unbanked.set_type = gpio_irq_type_unbanked;
+
+		/* default trigger: both edges */
+		g = gpio2controller(0);
+		__raw_writel(~0, &g->set_falling);
+		__raw_writel(~0, &g->set_rising);
+
+		/* set the direct IRQs up to use that irqchip */
+		for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
+			set_irq_chip(irq, &gpio_irqchip_unbanked);
+			set_irq_data(irq, (void *) __gpio_mask(gpio));
+			set_irq_chip_data(irq, g);
+			irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH;
+		}
+
+		goto done;
+	}
+
+	/*
+	 * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
+	 * then chain through our own handler.
+	 */
 	for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
 			gpio < ngpio;
 			bank++, bank_irq++) {
-		struct gpio_controller	*__iomem g = gpio2controller(gpio);
 		unsigned		i;
 
+		/* disabled by default, enabled only as needed */
+		g = gpio2controller(gpio);
 		__raw_writel(~0, &g->clr_falling);
 		__raw_writel(~0, &g->clr_rising);
 
@@ -309,6 +400,7 @@ static int __init davinci_gpio_irq_setup(void)
 		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
 			set_irq_chip(irq, &gpio_irqchip);
 			set_irq_chip_data(irq, g);
+			set_irq_data(irq, (void *) __gpio_mask(gpio));
 			set_irq_handler(irq, handle_simple_irq);
 			set_irq_flags(irq, IRQF_VALID);
 		}
@@ -316,6 +408,7 @@ static int __init davinci_gpio_irq_setup(void)
 		binten |= BIT(bank);
 	}
 
+done:
 	/* BINTEN -- per-bank interrupt enable. genirq would also let these
 	 * bits be set/cleared dynamically.
 	 */
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h
index e0abc43..18e4ce3 100644
--- a/arch/arm/mach-davinci/include/mach/asp.h
+++ b/arch/arm/mach-davinci/include/mach/asp.h
@@ -5,21 +5,73 @@
 #define __ASM_ARCH_DAVINCI_ASP_H
 
 #include <mach/irqs.h>
+#include <mach/edma.h>
 
-/* Bases of register banks */
+/* Bases of dm644x and dm355 register banks */
 #define DAVINCI_ASP0_BASE	0x01E02000
 #define DAVINCI_ASP1_BASE	0x01E04000
 
-/* EDMA channels */
+/* Bases of dm646x register banks */
+#define	DAVINCI_DM646X_MCASP0_REG_BASE		0x01D01000
+#define DAVINCI_DM646X_MCASP1_REG_BASE		0x01D01800
+
+/* Bases of da850/da830 McASP0  register banks */
+#define DAVINCI_DA8XX_MCASP0_REG_BASE	0x01D00000
+
+/* Bases of da830 McASP1 register banks */
+#define DAVINCI_DA830_MCASP1_REG_BASE	0x01D04000
+
+/* EDMA channels of dm644x and dm355 */
 #define DAVINCI_DMA_ASP0_TX	2
 #define DAVINCI_DMA_ASP0_RX	3
 #define DAVINCI_DMA_ASP1_TX	8
 #define DAVINCI_DMA_ASP1_RX	9
 
+/* EDMA channels of dm646x */
+#define	DAVINCI_DM646X_DMA_MCASP0_AXEVT0	6
+#define	DAVINCI_DM646X_DMA_MCASP0_AREVT0	9
+#define	DAVINCI_DM646X_DMA_MCASP1_AXEVT1	12
+
+/* EDMA channels of da850/da830 McASP0 */
+#define	DAVINCI_DA8XX_DMA_MCASP0_AREVT	0
+#define	DAVINCI_DA8XX_DMA_MCASP0_AXEVT	1
+
+/* EDMA channels of da830 McASP1 */
+#define	DAVINCI_DA830_DMA_MCASP1_AREVT	2
+#define	DAVINCI_DA830_DMA_MCASP1_AXEVT	3
+
 /* Interrupts */
 #define DAVINCI_ASP0_RX_INT	IRQ_MBRINT
 #define DAVINCI_ASP0_TX_INT	IRQ_MBXINT
 #define DAVINCI_ASP1_RX_INT	IRQ_MBRINT
 #define DAVINCI_ASP1_TX_INT	IRQ_MBXINT
 
+struct snd_platform_data {
+	u32 tx_dma_offset;
+	u32 rx_dma_offset;
+	enum dma_event_q eventq_no;	/* event queue number */
+	unsigned int codec_fmt;
+
+	/* McASP specific fields */
+	int tdm_slots;
+	u8 op_mode;
+	u8 num_serializer;
+	u8 *serial_dir;
+	u8 version;
+	u8 txnumevt;
+	u8 rxnumevt;
+};
+
+enum {
+	MCASP_VERSION_1 = 0,	/* DM646x */
+	MCASP_VERSION_2,	/* DA8xx/OMAPL1x */
+};
+
+#define INACTIVE_MODE	0
+#define TX_MODE		1
+#define RX_MODE		2
+
+#define DAVINCI_MCASP_IIS_MODE	0
+#define DAVINCI_MCASP_DIT_MODE	1
+
 #endif /* __ASM_ARCH_DAVINCI_ASP_H */
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
index a1f03b6..1fd3917 100644
--- a/arch/arm/mach-davinci/include/mach/common.h
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -60,10 +60,10 @@ struct davinci_soc_info {
 	u8				*intc_irq_prios;
 	unsigned long			intc_irq_num;
 	struct davinci_timer_info	*timer_info;
-	void __iomem			*wdt_base;
 	void __iomem			*gpio_base;
 	unsigned			gpio_num;
 	unsigned			gpio_irq;
+	unsigned			gpio_unbanked;
 	struct platform_device		*serial_dev;
 	struct emac_platform_data	*emac_pdata;
 	dma_addr_t			sram_dma;
diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h
index d12a5ed..189b1ff 100644
--- a/arch/arm/mach-davinci/include/mach/cputype.h
+++ b/arch/arm/mach-davinci/include/mach/cputype.h
@@ -30,6 +30,9 @@ struct davinci_id {
 #define	DAVINCI_CPU_ID_DM6446		0x64460000
 #define	DAVINCI_CPU_ID_DM6467		0x64670000
 #define	DAVINCI_CPU_ID_DM355		0x03550000
+#define	DAVINCI_CPU_ID_DM365		0x03650000
+#define	DAVINCI_CPU_ID_DA830		0x08300000
+#define	DAVINCI_CPU_ID_DA850		0x08500000
 
 #define IS_DAVINCI_CPU(type, id)					\
 static inline int is_davinci_ ##type(void)				\
@@ -40,6 +43,9 @@ static inline int is_davinci_ ##type(void)				\
 IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446)
 IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467)
 IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
+IS_DAVINCI_CPU(dm365, DAVINCI_CPU_ID_DM365)
+IS_DAVINCI_CPU(da830, DAVINCI_CPU_ID_DA830)
+IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850)
 
 #ifdef CONFIG_ARCH_DAVINCI_DM644x
 #define cpu_is_davinci_dm644x() is_davinci_dm644x()
@@ -59,4 +65,22 @@ IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
 #define cpu_is_davinci_dm355() 0
 #endif
 
+#ifdef CONFIG_ARCH_DAVINCI_DM365
+#define cpu_is_davinci_dm365() is_davinci_dm365()
+#else
+#define cpu_is_davinci_dm365() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DA830
+#define cpu_is_davinci_da830() is_davinci_da830()
+#else
+#define cpu_is_davinci_da830() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+#define cpu_is_davinci_da850() is_davinci_da850()
+#else
+#define cpu_is_davinci_da850() 0
+#endif
+
 #endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
new file mode 100644
index 0000000..d4095d0
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -0,0 +1,121 @@
+/*
+ * Chip specific defines for DA8XX/OMAP L1XX SoC
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DAVINCI_DA8XX_H
+#define __ASM_ARCH_DAVINCI_DA8XX_H
+
+#include <mach/serial.h>
+#include <mach/edma.h>
+#include <mach/i2c.h>
+#include <mach/emac.h>
+#include <mach/asp.h>
+#include <mach/mmc.h>
+
+/*
+ * The cp_intc interrupt controller for the da8xx isn't in the same
+ * chunk of physical memory space as the other registers (like it is
+ * on the davincis) so it needs to be mapped separately.  It will be
+ * mapped early on when the I/O space is mapped and we'll put it just
+ * before the I/O space in the processor's virtual memory space.
+ */
+#define DA8XX_CP_INTC_BASE	0xfffee000
+#define DA8XX_CP_INTC_SIZE	SZ_8K
+#define DA8XX_CP_INTC_VIRT	(IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K)
+
+#define DA8XX_BOOT_CFG_BASE	(IO_PHYS + 0x14000)
+
+#define DA8XX_PSC0_BASE		0x01c10000
+#define DA8XX_PLL0_BASE		0x01c11000
+#define DA8XX_JTAG_ID_REG	0x01c14018
+#define DA8XX_TIMER64P0_BASE	0x01c20000
+#define DA8XX_TIMER64P1_BASE	0x01c21000
+#define DA8XX_GPIO_BASE		0x01e26000
+#define DA8XX_PSC1_BASE		0x01e27000
+#define DA8XX_LCD_CNTRL_BASE	0x01e13000
+#define DA8XX_MMCSD0_BASE	0x01c40000
+#define DA8XX_AEMIF_CS2_BASE	0x60000000
+#define DA8XX_AEMIF_CS3_BASE	0x62000000
+#define DA8XX_AEMIF_CTL_BASE	0x68000000
+
+#define PINMUX0			0x00
+#define PINMUX1			0x04
+#define PINMUX2			0x08
+#define PINMUX3			0x0c
+#define PINMUX4			0x10
+#define PINMUX5			0x14
+#define PINMUX6			0x18
+#define PINMUX7			0x1c
+#define PINMUX8			0x20
+#define PINMUX9			0x24
+#define PINMUX10		0x28
+#define PINMUX11		0x2c
+#define PINMUX12		0x30
+#define PINMUX13		0x34
+#define PINMUX14		0x38
+#define PINMUX15		0x3c
+#define PINMUX16		0x40
+#define PINMUX17		0x44
+#define PINMUX18		0x48
+#define PINMUX19		0x4c
+
+void __init da830_init(void);
+void __init da850_init(void);
+
+int da8xx_register_edma(void);
+int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
+int da8xx_register_watchdog(void);
+int da8xx_register_emac(void);
+int da8xx_register_lcdc(void);
+int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
+void __init da8xx_init_mcasp(int id, struct snd_platform_data *pdata);
+
+extern struct platform_device da8xx_serial_device;
+extern struct emac_platform_data da8xx_emac_pdata;
+
+extern const short da830_emif25_pins[];
+extern const short da830_spi0_pins[];
+extern const short da830_spi1_pins[];
+extern const short da830_mmc_sd_pins[];
+extern const short da830_uart0_pins[];
+extern const short da830_uart1_pins[];
+extern const short da830_uart2_pins[];
+extern const short da830_usb20_pins[];
+extern const short da830_usb11_pins[];
+extern const short da830_uhpi_pins[];
+extern const short da830_cpgmac_pins[];
+extern const short da830_emif3c_pins[];
+extern const short da830_mcasp0_pins[];
+extern const short da830_mcasp1_pins[];
+extern const short da830_mcasp2_pins[];
+extern const short da830_i2c0_pins[];
+extern const short da830_i2c1_pins[];
+extern const short da830_lcdcntl_pins[];
+extern const short da830_pwm_pins[];
+extern const short da830_ecap0_pins[];
+extern const short da830_ecap1_pins[];
+extern const short da830_ecap2_pins[];
+extern const short da830_eqep0_pins[];
+extern const short da830_eqep1_pins[];
+
+extern const short da850_uart0_pins[];
+extern const short da850_uart1_pins[];
+extern const short da850_uart2_pins[];
+extern const short da850_i2c0_pins[];
+extern const short da850_i2c1_pins[];
+extern const short da850_cpgmac_pins[];
+extern const short da850_mcasp_pins[];
+extern const short da850_lcdcntl_pins[];
+extern const short da850_mmcsd0_pins[];
+extern const short da850_nand_pins[];
+extern const short da850_nor_pins[];
+
+int da8xx_pinmux_setup(const short pins[]);
+
+#endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
index de3fc21..17ab523 100644
--- a/arch/arm/mach-davinci/include/mach/debug-macro.S
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -24,7 +24,15 @@
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x01000000	@ physical base address
 		movne	\rx, #0xfe000000	@ virtual base
+#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx)
+#error Cannot enable DaVinci and DA8XX platforms concurrently
+#elif defined(CONFIG_MACH_DAVINCI_DA830_EVM) || \
+	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
+		orr	\rx, \rx, #0x00d00000	@ physical base address
+		orr	\rx, \rx, #0x0000d000	@ of UART 2
+#else
 		orr	\rx, \rx, #0x00c20000   @ UART 0
+#endif
 		.endm
 
 		.macro	senduart,rd,rx
diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h
index 54903b7..85536d8 100644
--- a/arch/arm/mach-davinci/include/mach/dm355.h
+++ b/arch/arm/mach-davinci/include/mach/dm355.h
@@ -12,11 +12,18 @@
 #define __ASM_ARCH_DM355_H
 
 #include <mach/hardware.h>
+#include <mach/asp.h>
+#include <media/davinci/vpfe_capture.h>
+
+#define ASP1_TX_EVT_EN	1
+#define ASP1_RX_EVT_EN	2
 
 struct spi_board_info;
 
 void __init dm355_init(void);
 void dm355_init_spi0(unsigned chipselect_mask,
 		struct spi_board_info *info, unsigned len);
+void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
+void dm355_set_vpfe_config(struct vpfe_config *cfg);
 
 #endif /* __ASM_ARCH_DM355_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h
new file mode 100644
index 0000000..09db434
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm365.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ *
+ * This program is free software; 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ASM_ARCH_DM365_H
+#define __ASM_ARCH_DM665_H
+
+#include <linux/platform_device.h>
+#include <mach/hardware.h>
+#include <mach/emac.h>
+
+#define DM365_EMAC_BASE			(0x01D07000)
+#define DM365_EMAC_CNTRL_OFFSET		(0x0000)
+#define DM365_EMAC_CNTRL_MOD_OFFSET	(0x3000)
+#define DM365_EMAC_CNTRL_RAM_OFFSET	(0x1000)
+#define DM365_EMAC_MDIO_OFFSET		(0x4000)
+#define DM365_EMAC_CNTRL_RAM_SIZE	(0x2000)
+
+void __init dm365_init(void);
+
+#endif /* __ASM_ARCH_DM365_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
index 15d42b9..0efb738 100644
--- a/arch/arm/mach-davinci/include/mach/dm644x.h
+++ b/arch/arm/mach-davinci/include/mach/dm644x.h
@@ -25,6 +25,8 @@
 #include <linux/platform_device.h>
 #include <mach/hardware.h>
 #include <mach/emac.h>
+#include <mach/asp.h>
+#include <media/davinci/vpfe_capture.h>
 
 #define DM644X_EMAC_BASE		(0x01C80000)
 #define DM644X_EMAC_CNTRL_OFFSET	(0x0000)
@@ -34,5 +36,7 @@
 #define DM644X_EMAC_CNTRL_RAM_SIZE	(0x2000)
 
 void __init dm644x_init(void);
+void __init dm644x_init_asp(struct snd_platform_data *pdata);
+void dm644x_set_vpfe_config(struct vpfe_config *cfg);
 
 #endif /* __ASM_ARCH_DM644X_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h
index 1fc764c..8cec746 100644
--- a/arch/arm/mach-davinci/include/mach/dm646x.h
+++ b/arch/arm/mach-davinci/include/mach/dm646x.h
@@ -13,6 +13,9 @@
 
 #include <mach/hardware.h>
 #include <mach/emac.h>
+#include <mach/asp.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
 
 #define DM646X_EMAC_BASE		(0x01C80000)
 #define DM646X_EMAC_CNTRL_OFFSET	(0x0000)
@@ -21,6 +24,68 @@
 #define DM646X_EMAC_MDIO_OFFSET		(0x4000)
 #define DM646X_EMAC_CNTRL_RAM_SIZE	(0x2000)
 
+#define DM646X_ATA_REG_BASE		(0x01C66000)
+
 void __init dm646x_init(void);
+void __init dm646x_init_ide(void);
+void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
+void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
+
+void dm646x_video_init(void);
+
+enum vpif_if_type {
+	VPIF_IF_BT656,
+	VPIF_IF_BT1120,
+	VPIF_IF_RAW_BAYER
+};
+
+struct vpif_interface {
+	enum vpif_if_type if_type;
+	unsigned hd_pol:1;
+	unsigned vd_pol:1;
+	unsigned fid_pol:1;
+};
+
+struct vpif_subdev_info {
+	const char *name;
+	struct i2c_board_info board_info;
+	u32 input;
+	u32 output;
+	unsigned can_route:1;
+	struct vpif_interface vpif_if;
+};
+
+struct vpif_display_config {
+	int (*set_clock)(int, int);
+	struct vpif_subdev_info *subdevinfo;
+	int subdev_count;
+	const char **output;
+	int output_count;
+	const char *card_name;
+};
+
+struct vpif_input {
+	struct v4l2_input input;
+	const char *subdev_name;
+};
+
+#define VPIF_CAPTURE_MAX_CHANNELS	2
+
+struct vpif_capture_chan_config {
+	const struct vpif_input *inputs;
+	int input_count;
+};
+
+struct vpif_capture_config {
+	int (*setup_input_channel_mode)(int);
+	int (*setup_input_path)(int, const char *);
+	struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS];
+	struct vpif_subdev_info *subdev_info;
+	int subdev_count;
+	const char *card_name;
+};
+
+void dm646x_setup_vpif(struct vpif_display_config *,
+		       struct vpif_capture_config *);
 
 #endif /* __ASM_ARCH_DM646X_H */
diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h
index 24a3792..eb8bfd7 100644
--- a/arch/arm/mach-davinci/include/mach/edma.h
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -139,6 +139,54 @@ struct edmacc_param {
 #define DAVINCI_DMA_PWM1                 53
 #define DAVINCI_DMA_PWM2                 54
 
+/* DA830 specific EDMA3 information */
+#define EDMA_DA830_NUM_DMACH		32
+#define EDMA_DA830_NUM_TCC		32
+#define EDMA_DA830_NUM_PARAMENTRY	128
+#define EDMA_DA830_NUM_EVQUE		2
+#define EDMA_DA830_NUM_TC		2
+#define EDMA_DA830_CHMAP_EXIST		0
+#define EDMA_DA830_NUM_REGIONS		4
+#define DA830_DMACH2EVENT_MAP0		0x000FC03Fu
+#define DA830_DMACH2EVENT_MAP1		0x00000000u
+#define DA830_EDMA_ARM_OWN		0x30FFCCFFu
+
+/* DA830 specific EDMA3 Events Information */
+enum DA830_edma_ch {
+	DA830_DMACH_MCASP0_RX,
+	DA830_DMACH_MCASP0_TX,
+	DA830_DMACH_MCASP1_RX,
+	DA830_DMACH_MCASP1_TX,
+	DA830_DMACH_MCASP2_RX,
+	DA830_DMACH_MCASP2_TX,
+	DA830_DMACH_GPIO_BNK0INT,
+	DA830_DMACH_GPIO_BNK1INT,
+	DA830_DMACH_UART0_RX,
+	DA830_DMACH_UART0_TX,
+	DA830_DMACH_TMR64P0_EVTOUT12,
+	DA830_DMACH_TMR64P0_EVTOUT34,
+	DA830_DMACH_UART1_RX,
+	DA830_DMACH_UART1_TX,
+	DA830_DMACH_SPI0_RX,
+	DA830_DMACH_SPI0_TX,
+	DA830_DMACH_MMCSD_RX,
+	DA830_DMACH_MMCSD_TX,
+	DA830_DMACH_SPI1_RX,
+	DA830_DMACH_SPI1_TX,
+	DA830_DMACH_DMAX_EVTOUT6,
+	DA830_DMACH_DMAX_EVTOUT7,
+	DA830_DMACH_GPIO_BNK2INT,
+	DA830_DMACH_GPIO_BNK3INT,
+	DA830_DMACH_I2C0_RX,
+	DA830_DMACH_I2C0_TX,
+	DA830_DMACH_I2C1_RX,
+	DA830_DMACH_I2C1_TX,
+	DA830_DMACH_GPIO_BNK4INT,
+	DA830_DMACH_GPIO_BNK5INT,
+	DA830_DMACH_UART2_RX,
+	DA830_DMACH_UART2_TX
+};
+
 /*ch_status paramater of callback function possible values*/
 #define DMA_COMPLETE 1
 #define DMA_CC_ERROR 2
@@ -162,6 +210,8 @@ enum fifo_width {
 enum dma_event_q {
 	EVENTQ_0 = 0,
 	EVENTQ_1 = 1,
+	EVENTQ_2 = 2,
+	EVENTQ_3 = 3,
 	EVENTQ_DEFAULT = -1
 };
 
@@ -170,8 +220,15 @@ enum sync_dimension {
 	ABSYNC = 1
 };
 
+#define EDMA_CTLR_CHAN(ctlr, chan)	(((ctlr) << 16) | (chan))
+#define EDMA_CTLR(i)			((i) >> 16)
+#define EDMA_CHAN_SLOT(i)		((i) & 0xffff)
+
 #define EDMA_CHANNEL_ANY		-1	/* for edma_alloc_channel() */
 #define EDMA_SLOT_ANY			-1	/* for edma_alloc_slot() */
+#define EDMA_CONT_PARAMS_ANY		 1001
+#define EDMA_CONT_PARAMS_FIXED_EXACT	 1002
+#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
 
 /* alloc/free DMA channels and their dedicated parameter RAM slots */
 int edma_alloc_channel(int channel,
@@ -180,9 +237,13 @@ int edma_alloc_channel(int channel,
 void edma_free_channel(unsigned channel);
 
 /* alloc/free parameter RAM slots */
-int edma_alloc_slot(int slot);
+int edma_alloc_slot(unsigned ctlr, int slot);
 void edma_free_slot(unsigned slot);
 
+/* alloc/free a set of contiguous parameter RAM slots */
+int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count);
+int edma_free_cont_slots(unsigned slot, int count);
+
 /* calls that operate on part of a parameter RAM slot */
 void edma_set_src(unsigned slot, dma_addr_t src_port,
 				enum address_mode mode, enum fifo_width);
@@ -216,9 +277,13 @@ struct edma_soc_info {
 	unsigned	n_region;
 	unsigned	n_slot;
 	unsigned	n_tc;
+	unsigned	n_cc;
+	enum dma_event_q	default_queue;
 
 	/* list of channels with no even trigger; terminated by "-1" */
 	const s8	*noevent;
+	const s8	(*queue_tc_mapping)[2];
+	const s8	(*queue_priority_mapping)[2];
 };
 
 #endif
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index ae07455..f3b8ef8 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -42,6 +42,9 @@
  */
 #define	GPIO(X)		(X)		/* 0 <= X <= (DAVINCI_N_GPIO - 1) */
 
+/* Convert GPIO signal to GPIO pin number */
+#define GPIO_TO_PIN(bank, gpio)	(16 * (bank) + (gpio))
+
 struct gpio_controller {
 	u32	dir;
 	u32	out_data;
@@ -78,6 +81,8 @@ __gpio_to_controller(unsigned gpio)
 		ptr = base + 0x60;
 	else if (gpio < 32 * 4)
 		ptr = base + 0x88;
+	else if (gpio < 32 * 5)
+		ptr = base + 0xb0;
 	else
 		ptr = NULL;
 	return ptr;
@@ -142,15 +147,13 @@ static inline int gpio_cansleep(unsigned gpio)
 
 static inline int gpio_to_irq(unsigned gpio)
 {
-	if (gpio >= DAVINCI_N_GPIO)
-		return -EINVAL;
-	return davinci_soc_info.intc_irq_num + gpio;
+	return __gpio_to_irq(gpio);
 }
 
 static inline int irq_to_gpio(unsigned irq)
 {
-	/* caller guarantees gpio_to_irq() succeeded */
-	return irq - davinci_soc_info.intc_irq_num;
+	/* don't support the reverse mapping */
+	return -ENOSYS;
 }
 
 #endif				/* __DAVINCI_GPIO_H */
diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h
index 48c7793..41c8938 100644
--- a/arch/arm/mach-davinci/include/mach/hardware.h
+++ b/arch/arm/mach-davinci/include/mach/hardware.h
@@ -24,4 +24,21 @@
 /* System control register offsets */
 #define DM64XX_VDD3P3V_PWDN	0x48
 
+/*
+ * I/O mapping
+ */
+#define IO_PHYS				0x01c00000
+#define IO_OFFSET			0xfd000000 /* Virtual IO = 0xfec00000 */
+#define IO_SIZE				0x00400000
+#define IO_VIRT				(IO_PHYS + IO_OFFSET)
+#define io_v2p(va)			((va) - IO_OFFSET)
+#define __IO_ADDRESS(x)			((x) + IO_OFFSET)
+#define IO_ADDRESS(pa)			IOMEM(__IO_ADDRESS(pa))
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x)                	x
+#else
+#define IOMEM(x)                	((void __force __iomem *)(x))
+#endif
+
 #endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h
index 2479785..62b0a90 100644
--- a/arch/arm/mach-davinci/include/mach/io.h
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -14,18 +14,6 @@
 #define IO_SPACE_LIMIT 0xffffffff
 
 /*
- * ----------------------------------------------------------------------------
- * I/O mapping
- * ----------------------------------------------------------------------------
- */
-#define IO_PHYS		0x01c00000
-#define IO_OFFSET	0xfd000000 /* Virtual IO = 0xfec00000 */
-#define IO_SIZE		0x00400000
-#define IO_VIRT		(IO_PHYS + IO_OFFSET)
-#define io_v2p(va)	((va) - IO_OFFSET)
-#define __IO_ADDRESS(x)	((x) + IO_OFFSET)
-
-/*
  * We don't actually have real ISA nor PCI buses, but there is so many
  * drivers out there that might just work if we fake them...
  */
@@ -33,19 +21,12 @@
 #define __mem_pci(a)		(a)
 #define __mem_isa(a)		(a)
 
-#define IO_ADDRESS(pa)          IOMEM(__IO_ADDRESS(pa))
-
-#ifdef __ASSEMBLER__
-#define IOMEM(x)                x
-#else
-#define IOMEM(x)                ((void __force __iomem *)(x))
-
+#ifndef __ASSEMBLER__
 #define __arch_ioremap(p, s, t)	davinci_ioremap(p, s, t)
 #define __arch_iounmap(v)	davinci_iounmap(v)
 
 void __iomem *davinci_ioremap(unsigned long phys, size_t size,
 			      unsigned int type);
 void davinci_iounmap(volatile void __iomem *addr);
-
-#endif /* __ASSEMBLER__ */
+#endif
 #endif /* __ASM_ARCH_IO_H */
diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h
index bc5d6aa..3c918a7 100644
--- a/arch/arm/mach-davinci/include/mach/irqs.h
+++ b/arch/arm/mach-davinci/include/mach/irqs.h
@@ -99,9 +99,6 @@
 #define IRQ_EMUINT       63
 
 #define DAVINCI_N_AINTC_IRQ	64
-#define DAVINCI_N_GPIO		104
-
-#define NR_IRQS			(DAVINCI_N_AINTC_IRQ + DAVINCI_N_GPIO)
 
 #define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
 
@@ -206,4 +203,206 @@
 #define IRQ_DM355_GPIOBNK5	59
 #define IRQ_DM355_GPIOBNK6	60
 
+/* DaVinci DM365-specific Interrupts */
+#define IRQ_DM365_INSFINT	7
+#define IRQ_DM365_IMXINT1	8
+#define IRQ_DM365_IMXINT0	10
+#define IRQ_DM365_KLD_ARMINT	10
+#define IRQ_DM365_IMCOPINT	11
+#define IRQ_DM365_RTOINT	13
+#define IRQ_DM365_TINT5		14
+#define IRQ_DM365_TINT6		15
+#define IRQ_DM365_SPINT2_1	21
+#define IRQ_DM365_TINT7		22
+#define IRQ_DM365_SDIOINT0	23
+#define IRQ_DM365_MMCINT1	27
+#define IRQ_DM365_PWMINT3	28
+#define IRQ_DM365_SDIOINT1	31
+#define IRQ_DM365_SPIINT0_0	42
+#define IRQ_DM365_SPIINT3_0	43
+#define IRQ_DM365_GPIO0		44
+#define IRQ_DM365_GPIO1		45
+#define IRQ_DM365_GPIO2		46
+#define IRQ_DM365_GPIO3		47
+#define IRQ_DM365_GPIO4		48
+#define IRQ_DM365_GPIO5		49
+#define IRQ_DM365_GPIO6		50
+#define IRQ_DM365_GPIO7		51
+#define IRQ_DM365_EMAC_RXTHRESH	52
+#define IRQ_DM365_EMAC_RXPULSE	53
+#define IRQ_DM365_EMAC_TXPULSE	54
+#define IRQ_DM365_EMAC_MISCPULSE 55
+#define IRQ_DM365_GPIO12	56
+#define IRQ_DM365_GPIO13	57
+#define IRQ_DM365_GPIO14	58
+#define IRQ_DM365_GPIO15	59
+#define IRQ_DM365_ADCINT	59
+#define IRQ_DM365_KEYINT	60
+#define IRQ_DM365_TCERRINT2	61
+#define IRQ_DM365_TCERRINT3	62
+#define IRQ_DM365_EMUINT	63
+
+/* DA8XX interrupts */
+#define IRQ_DA8XX_COMMTX		0
+#define IRQ_DA8XX_COMMRX		1
+#define IRQ_DA8XX_NINT			2
+#define IRQ_DA8XX_EVTOUT0		3
+#define IRQ_DA8XX_EVTOUT1		4
+#define IRQ_DA8XX_EVTOUT2		5
+#define IRQ_DA8XX_EVTOUT3		6
+#define IRQ_DA8XX_EVTOUT4		7
+#define IRQ_DA8XX_EVTOUT5		8
+#define IRQ_DA8XX_EVTOUT6		9
+#define IRQ_DA8XX_EVTOUT7		10
+#define IRQ_DA8XX_CCINT0		11
+#define IRQ_DA8XX_CCERRINT		12
+#define IRQ_DA8XX_TCERRINT0		13
+#define IRQ_DA8XX_AEMIFINT		14
+#define IRQ_DA8XX_I2CINT0		15
+#define IRQ_DA8XX_MMCSDINT0		16
+#define IRQ_DA8XX_MMCSDINT1		17
+#define IRQ_DA8XX_ALLINT0		18
+#define IRQ_DA8XX_RTC			19
+#define IRQ_DA8XX_SPINT0		20
+#define IRQ_DA8XX_TINT12_0		21
+#define IRQ_DA8XX_TINT34_0		22
+#define IRQ_DA8XX_TINT12_1		23
+#define IRQ_DA8XX_TINT34_1		24
+#define IRQ_DA8XX_UARTINT0		25
+#define IRQ_DA8XX_KEYMGRINT		26
+#define IRQ_DA8XX_SECINT		26
+#define IRQ_DA8XX_SECKEYERR		26
+#define IRQ_DA8XX_CHIPINT0		28
+#define IRQ_DA8XX_CHIPINT1		29
+#define IRQ_DA8XX_CHIPINT2		30
+#define IRQ_DA8XX_CHIPINT3		31
+#define IRQ_DA8XX_TCERRINT1		32
+#define IRQ_DA8XX_C0_RX_THRESH_PULSE	33
+#define IRQ_DA8XX_C0_RX_PULSE		34
+#define IRQ_DA8XX_C0_TX_PULSE		35
+#define IRQ_DA8XX_C0_MISC_PULSE		36
+#define IRQ_DA8XX_C1_RX_THRESH_PULSE	37
+#define IRQ_DA8XX_C1_RX_PULSE		38
+#define IRQ_DA8XX_C1_TX_PULSE		39
+#define IRQ_DA8XX_C1_MISC_PULSE		40
+#define IRQ_DA8XX_MEMERR		41
+#define IRQ_DA8XX_GPIO0			42
+#define IRQ_DA8XX_GPIO1			43
+#define IRQ_DA8XX_GPIO2			44
+#define IRQ_DA8XX_GPIO3			45
+#define IRQ_DA8XX_GPIO4			46
+#define IRQ_DA8XX_GPIO5			47
+#define IRQ_DA8XX_GPIO6			48
+#define IRQ_DA8XX_GPIO7			49
+#define IRQ_DA8XX_GPIO8			50
+#define IRQ_DA8XX_I2CINT1		51
+#define IRQ_DA8XX_LCDINT		52
+#define IRQ_DA8XX_UARTINT1		53
+#define IRQ_DA8XX_MCASPINT		54
+#define IRQ_DA8XX_ALLINT1		55
+#define IRQ_DA8XX_SPINT1		56
+#define IRQ_DA8XX_UHPI_INT1		57
+#define IRQ_DA8XX_USB_INT		58
+#define IRQ_DA8XX_IRQN			59
+#define IRQ_DA8XX_RWAKEUP		60
+#define IRQ_DA8XX_UARTINT2		61
+#define IRQ_DA8XX_DFTSSINT		62
+#define IRQ_DA8XX_EHRPWM0		63
+#define IRQ_DA8XX_EHRPWM0TZ		64
+#define IRQ_DA8XX_EHRPWM1		65
+#define IRQ_DA8XX_EHRPWM1TZ		66
+#define IRQ_DA8XX_ECAP0			69
+#define IRQ_DA8XX_ECAP1			70
+#define IRQ_DA8XX_ECAP2			71
+#define IRQ_DA8XX_ARMCLKSTOPREQ		90
+
+/* DA830 specific interrupts */
+#define IRQ_DA830_MPUERR		27
+#define IRQ_DA830_IOPUERR		27
+#define IRQ_DA830_BOOTCFGERR		27
+#define IRQ_DA830_EHRPWM2		67
+#define IRQ_DA830_EHRPWM2TZ		68
+#define IRQ_DA830_EQEP0			72
+#define IRQ_DA830_EQEP1			73
+#define IRQ_DA830_T12CMPINT0_0		74
+#define IRQ_DA830_T12CMPINT1_0		75
+#define IRQ_DA830_T12CMPINT2_0		76
+#define IRQ_DA830_T12CMPINT3_0		77
+#define IRQ_DA830_T12CMPINT4_0		78
+#define IRQ_DA830_T12CMPINT5_0		79
+#define IRQ_DA830_T12CMPINT6_0		80
+#define IRQ_DA830_T12CMPINT7_0		81
+#define IRQ_DA830_T12CMPINT0_1		82
+#define IRQ_DA830_T12CMPINT1_1		83
+#define IRQ_DA830_T12CMPINT2_1		84
+#define IRQ_DA830_T12CMPINT3_1		85
+#define IRQ_DA830_T12CMPINT4_1		86
+#define IRQ_DA830_T12CMPINT5_1		87
+#define IRQ_DA830_T12CMPINT6_1		88
+#define IRQ_DA830_T12CMPINT7_1		89
+
+#define DA830_N_CP_INTC_IRQ		96
+
+/* DA850 speicific interrupts */
+#define IRQ_DA850_MPUADDRERR0		27
+#define IRQ_DA850_MPUPROTERR0		27
+#define IRQ_DA850_IOPUADDRERR0		27
+#define IRQ_DA850_IOPUPROTERR0		27
+#define IRQ_DA850_IOPUADDRERR1		27
+#define IRQ_DA850_IOPUPROTERR1		27
+#define IRQ_DA850_IOPUADDRERR2		27
+#define IRQ_DA850_IOPUPROTERR2		27
+#define IRQ_DA850_BOOTCFG_ADDR_ERR	27
+#define IRQ_DA850_BOOTCFG_PROT_ERR	27
+#define IRQ_DA850_MPUADDRERR1		27
+#define IRQ_DA850_MPUPROTERR1		27
+#define IRQ_DA850_IOPUADDRERR3		27
+#define IRQ_DA850_IOPUPROTERR3		27
+#define IRQ_DA850_IOPUADDRERR4		27
+#define IRQ_DA850_IOPUPROTERR4		27
+#define IRQ_DA850_IOPUADDRERR5		27
+#define IRQ_DA850_IOPUPROTERR5		27
+#define IRQ_DA850_MIOPU_BOOTCFG_ERR	27
+#define IRQ_DA850_SATAINT		67
+#define IRQ_DA850_TINT12_2		68
+#define IRQ_DA850_TINT34_2		68
+#define IRQ_DA850_TINTALL_2		68
+#define IRQ_DA850_MMCSDINT0_1		72
+#define IRQ_DA850_MMCSDINT1_1		73
+#define IRQ_DA850_T12CMPINT0_2		74
+#define IRQ_DA850_T12CMPINT1_2		75
+#define IRQ_DA850_T12CMPINT2_2		76
+#define IRQ_DA850_T12CMPINT3_2		77
+#define IRQ_DA850_T12CMPINT4_2		78
+#define IRQ_DA850_T12CMPINT5_2		79
+#define IRQ_DA850_T12CMPINT6_2		80
+#define IRQ_DA850_T12CMPINT7_2		81
+#define IRQ_DA850_T12CMPINT0_3		82
+#define IRQ_DA850_T12CMPINT1_3		83
+#define IRQ_DA850_T12CMPINT2_3		84
+#define IRQ_DA850_T12CMPINT3_3		85
+#define IRQ_DA850_T12CMPINT4_3		86
+#define IRQ_DA850_T12CMPINT5_3		87
+#define IRQ_DA850_T12CMPINT6_3		88
+#define IRQ_DA850_T12CMPINT7_3		89
+#define IRQ_DA850_RPIINT		91
+#define IRQ_DA850_VPIFINT		92
+#define IRQ_DA850_CCINT1		93
+#define IRQ_DA850_CCERRINT1		94
+#define IRQ_DA850_TCERRINT2		95
+#define IRQ_DA850_TINT12_3		96
+#define IRQ_DA850_TINT34_3		96
+#define IRQ_DA850_TINTALL_3		96
+#define IRQ_DA850_MCBSP0RINT		97
+#define IRQ_DA850_MCBSP0XINT		98
+#define IRQ_DA850_MCBSP1RINT		99
+#define IRQ_DA850_MCBSP1XINT		100
+
+#define DA850_N_CP_INTC_IRQ		101
+
+/* da850 currently has the most gpio pins (144) */
+#define DAVINCI_N_GPIO			144
+/* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */
+#define NR_IRQS				(DA850_N_CP_INTC_IRQ + DAVINCI_N_GPIO)
+
 #endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h
index c712c7c..80309ae 100644
--- a/arch/arm/mach-davinci/include/mach/memory.h
+++ b/arch/arm/mach-davinci/include/mach/memory.h
@@ -20,9 +20,16 @@
 /**************************************************************************
  * Definitions
  **************************************************************************/
-#define DAVINCI_DDR_BASE    0x80000000
+#define DAVINCI_DDR_BASE	0x80000000
+#define DA8XX_DDR_BASE		0xc0000000
 
+#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx)
+#error Cannot enable DaVinci and DA8XX platforms concurrently
+#elif defined(CONFIG_ARCH_DAVINCI_DA8XX)
+#define PHYS_OFFSET DA8XX_DDR_BASE
+#else
 #define PHYS_OFFSET DAVINCI_DDR_BASE
+#endif
 
 /*
  * Increase size of DMA-consistent memory region
diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h
index 2737845..bb84893 100644
--- a/arch/arm/mach-davinci/include/mach/mux.h
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -154,6 +154,737 @@ enum davinci_dm355_index {
 	DM355_EVT8_ASP1_TX,
 	DM355_EVT9_ASP1_RX,
 	DM355_EVT26_MMC0_RX,
+
+	/* Video Out */
+	DM355_VOUT_FIELD,
+	DM355_VOUT_FIELD_G70,
+	DM355_VOUT_HVSYNC,
+	DM355_VOUT_COUTL_EN,
+	DM355_VOUT_COUTH_EN,
+
+	/* Video In Pin Mux */
+	DM355_VIN_PCLK,
+	DM355_VIN_CAM_WEN,
+	DM355_VIN_CAM_VD,
+	DM355_VIN_CAM_HD,
+	DM355_VIN_YIN_EN,
+	DM355_VIN_CINL_EN,
+	DM355_VIN_CINH_EN,
+};
+
+enum davinci_dm365_index {
+	/* MMC/SD 0 */
+	DM365_MMCSD0,
+
+	/* MMC/SD 1 */
+	DM365_SD1_CLK,
+	DM365_SD1_CMD,
+	DM365_SD1_DATA3,
+	DM365_SD1_DATA2,
+	DM365_SD1_DATA1,
+	DM365_SD1_DATA0,
+
+	/* I2C */
+	DM365_I2C_SDA,
+	DM365_I2C_SCL,
+
+	/* AEMIF */
+	DM365_AEMIF_AR,
+	DM365_AEMIF_A3,
+	DM365_AEMIF_A7,
+	DM365_AEMIF_D15_8,
+	DM365_AEMIF_CE0,
+
+	/* ASP0 function */
+	DM365_MCBSP0_BDX,
+	DM365_MCBSP0_X,
+	DM365_MCBSP0_BFSX,
+	DM365_MCBSP0_BDR,
+	DM365_MCBSP0_R,
+	DM365_MCBSP0_BFSR,
+
+	/* SPI0 */
+	DM365_SPI0_SCLK,
+	DM365_SPI0_SDI,
+	DM365_SPI0_SDO,
+	DM365_SPI0_SDENA0,
+	DM365_SPI0_SDENA1,
+
+	/* UART */
+	DM365_UART0_RXD,
+	DM365_UART0_TXD,
+	DM365_UART1_RXD,
+	DM365_UART1_TXD,
+	DM365_UART1_RTS,
+	DM365_UART1_CTS,
+
+	/* EMAC */
+	DM365_EMAC_TX_EN,
+	DM365_EMAC_TX_CLK,
+	DM365_EMAC_COL,
+	DM365_EMAC_TXD3,
+	DM365_EMAC_TXD2,
+	DM365_EMAC_TXD1,
+	DM365_EMAC_TXD0,
+	DM365_EMAC_RXD3,
+	DM365_EMAC_RXD2,
+	DM365_EMAC_RXD1,
+	DM365_EMAC_RXD0,
+	DM365_EMAC_RX_CLK,
+	DM365_EMAC_RX_DV,
+	DM365_EMAC_RX_ER,
+	DM365_EMAC_CRS,
+	DM365_EMAC_MDIO,
+	DM365_EMAC_MDCLK,
+
+	/* Keypad */
+	DM365_KEYPAD,
+
+	/* PWM */
+	DM365_PWM0,
+	DM365_PWM0_G23,
+	DM365_PWM1,
+	DM365_PWM1_G25,
+	DM365_PWM2_G87,
+	DM365_PWM2_G88,
+	DM365_PWM2_G89,
+	DM365_PWM2_G90,
+	DM365_PWM3_G80,
+	DM365_PWM3_G81,
+	DM365_PWM3_G85,
+	DM365_PWM3_G86,
+
+	/* SPI1 */
+	DM365_SPI1_SCLK,
+	DM365_SPI1_SDO,
+	DM365_SPI1_SDI,
+	DM365_SPI1_SDENA0,
+	DM365_SPI1_SDENA1,
+
+	/* SPI2 */
+	DM365_SPI2_SCLK,
+	DM365_SPI2_SDO,
+	DM365_SPI2_SDI,
+	DM365_SPI2_SDENA0,
+	DM365_SPI2_SDENA1,
+
+	/* SPI3 */
+	DM365_SPI3_SCLK,
+	DM365_SPI3_SDO,
+	DM365_SPI3_SDI,
+	DM365_SPI3_SDENA0,
+	DM365_SPI3_SDENA1,
+
+	/* SPI4 */
+	DM365_SPI4_SCLK,
+	DM365_SPI4_SDO,
+	DM365_SPI4_SDI,
+	DM365_SPI4_SDENA0,
+	DM365_SPI4_SDENA1,
+
+	/* GPIO */
+	DM365_GPIO20,
+	DM365_GPIO33,
+	DM365_GPIO40,
+
+	/* Video */
+	DM365_VOUT_FIELD,
+	DM365_VOUT_FIELD_G81,
+	DM365_VOUT_HVSYNC,
+	DM365_VOUT_COUTL_EN,
+	DM365_VOUT_COUTH_EN,
+	DM365_VIN_CAM_WEN,
+	DM365_VIN_CAM_VD,
+	DM365_VIN_CAM_HD,
+	DM365_VIN_YIN4_7_EN,
+	DM365_VIN_YIN0_3_EN,
+
+	/* IRQ muxing */
+	DM365_INT_EDMA_CC,
+	DM365_INT_EDMA_TC0_ERR,
+	DM365_INT_EDMA_TC1_ERR,
+	DM365_INT_EDMA_TC2_ERR,
+	DM365_INT_EDMA_TC3_ERR,
+	DM365_INT_PRTCSS,
+	DM365_INT_EMAC_RXTHRESH,
+	DM365_INT_EMAC_RXPULSE,
+	DM365_INT_EMAC_TXPULSE,
+	DM365_INT_EMAC_MISCPULSE,
+	DM365_INT_IMX0_ENABLE,
+	DM365_INT_IMX0_DISABLE,
+	DM365_INT_HDVICP_ENABLE,
+	DM365_INT_HDVICP_DISABLE,
+	DM365_INT_IMX1_ENABLE,
+	DM365_INT_IMX1_DISABLE,
+	DM365_INT_NSF_ENABLE,
+	DM365_INT_NSF_DISABLE,
+
+	/* EDMA event muxing */
+	DM365_EVT2_ASP_TX,
+	DM365_EVT3_ASP_RX,
+	DM365_EVT26_MMC0_RX,
+};
+
+enum da830_index {
+	DA830_GPIO7_14,
+	DA830_RTCK,
+	DA830_GPIO7_15,
+	DA830_EMU_0,
+	DA830_EMB_SDCKE,
+	DA830_EMB_CLK_GLUE,
+	DA830_EMB_CLK,
+	DA830_NEMB_CS_0,
+	DA830_NEMB_CAS,
+	DA830_NEMB_RAS,
+	DA830_NEMB_WE,
+	DA830_EMB_BA_1,
+	DA830_EMB_BA_0,
+	DA830_EMB_A_0,
+	DA830_EMB_A_1,
+	DA830_EMB_A_2,
+	DA830_EMB_A_3,
+	DA830_EMB_A_4,
+	DA830_EMB_A_5,
+	DA830_GPIO7_0,
+	DA830_GPIO7_1,
+	DA830_GPIO7_2,
+	DA830_GPIO7_3,
+	DA830_GPIO7_4,
+	DA830_GPIO7_5,
+	DA830_GPIO7_6,
+	DA830_GPIO7_7,
+	DA830_EMB_A_6,
+	DA830_EMB_A_7,
+	DA830_EMB_A_8,
+	DA830_EMB_A_9,
+	DA830_EMB_A_10,
+	DA830_EMB_A_11,
+	DA830_EMB_A_12,
+	DA830_EMB_D_31,
+	DA830_GPIO7_8,
+	DA830_GPIO7_9,
+	DA830_GPIO7_10,
+	DA830_GPIO7_11,
+	DA830_GPIO7_12,
+	DA830_GPIO7_13,
+	DA830_GPIO3_13,
+	DA830_EMB_D_30,
+	DA830_EMB_D_29,
+	DA830_EMB_D_28,
+	DA830_EMB_D_27,
+	DA830_EMB_D_26,
+	DA830_EMB_D_25,
+	DA830_EMB_D_24,
+	DA830_EMB_D_23,
+	DA830_EMB_D_22,
+	DA830_EMB_D_21,
+	DA830_EMB_D_20,
+	DA830_EMB_D_19,
+	DA830_EMB_D_18,
+	DA830_EMB_D_17,
+	DA830_EMB_D_16,
+	DA830_NEMB_WE_DQM_3,
+	DA830_NEMB_WE_DQM_2,
+	DA830_EMB_D_0,
+	DA830_EMB_D_1,
+	DA830_EMB_D_2,
+	DA830_EMB_D_3,
+	DA830_EMB_D_4,
+	DA830_EMB_D_5,
+	DA830_EMB_D_6,
+	DA830_GPIO6_0,
+	DA830_GPIO6_1,
+	DA830_GPIO6_2,
+	DA830_GPIO6_3,
+	DA830_GPIO6_4,
+	DA830_GPIO6_5,
+	DA830_GPIO6_6,
+	DA830_EMB_D_7,
+	DA830_EMB_D_8,
+	DA830_EMB_D_9,
+	DA830_EMB_D_10,
+	DA830_EMB_D_11,
+	DA830_EMB_D_12,
+	DA830_EMB_D_13,
+	DA830_EMB_D_14,
+	DA830_GPIO6_7,
+	DA830_GPIO6_8,
+	DA830_GPIO6_9,
+	DA830_GPIO6_10,
+	DA830_GPIO6_11,
+	DA830_GPIO6_12,
+	DA830_GPIO6_13,
+	DA830_GPIO6_14,
+	DA830_EMB_D_15,
+	DA830_NEMB_WE_DQM_1,
+	DA830_NEMB_WE_DQM_0,
+	DA830_SPI0_SOMI_0,
+	DA830_SPI0_SIMO_0,
+	DA830_SPI0_CLK,
+	DA830_NSPI0_ENA,
+	DA830_NSPI0_SCS_0,
+	DA830_EQEP0I,
+	DA830_EQEP0S,
+	DA830_EQEP1I,
+	DA830_NUART0_CTS,
+	DA830_NUART0_RTS,
+	DA830_EQEP0A,
+	DA830_EQEP0B,
+	DA830_GPIO6_15,
+	DA830_GPIO5_14,
+	DA830_GPIO5_15,
+	DA830_GPIO5_0,
+	DA830_GPIO5_1,
+	DA830_GPIO5_2,
+	DA830_GPIO5_3,
+	DA830_GPIO5_4,
+	DA830_SPI1_SOMI_0,
+	DA830_SPI1_SIMO_0,
+	DA830_SPI1_CLK,
+	DA830_UART0_RXD,
+	DA830_UART0_TXD,
+	DA830_AXR1_10,
+	DA830_AXR1_11,
+	DA830_NSPI1_ENA,
+	DA830_I2C1_SCL,
+	DA830_I2C1_SDA,
+	DA830_EQEP1S,
+	DA830_I2C0_SDA,
+	DA830_I2C0_SCL,
+	DA830_UART2_RXD,
+	DA830_TM64P0_IN12,
+	DA830_TM64P0_OUT12,
+	DA830_GPIO5_5,
+	DA830_GPIO5_6,
+	DA830_GPIO5_7,
+	DA830_GPIO5_8,
+	DA830_GPIO5_9,
+	DA830_GPIO5_10,
+	DA830_GPIO5_11,
+	DA830_GPIO5_12,
+	DA830_NSPI1_SCS_0,
+	DA830_USB0_DRVVBUS,
+	DA830_AHCLKX0,
+	DA830_ACLKX0,
+	DA830_AFSX0,
+	DA830_AHCLKR0,
+	DA830_ACLKR0,
+	DA830_AFSR0,
+	DA830_UART2_TXD,
+	DA830_AHCLKX2,
+	DA830_ECAP0_APWM0,
+	DA830_RMII_MHZ_50_CLK,
+	DA830_ECAP1_APWM1,
+	DA830_USB_REFCLKIN,
+	DA830_GPIO5_13,
+	DA830_GPIO4_15,
+	DA830_GPIO2_11,
+	DA830_GPIO2_12,
+	DA830_GPIO2_13,
+	DA830_GPIO2_14,
+	DA830_GPIO2_15,
+	DA830_GPIO3_12,
+	DA830_AMUTE0,
+	DA830_AXR0_0,
+	DA830_AXR0_1,
+	DA830_AXR0_2,
+	DA830_AXR0_3,
+	DA830_AXR0_4,
+	DA830_AXR0_5,
+	DA830_AXR0_6,
+	DA830_RMII_TXD_0,
+	DA830_RMII_TXD_1,
+	DA830_RMII_TXEN,
+	DA830_RMII_CRS_DV,
+	DA830_RMII_RXD_0,
+	DA830_RMII_RXD_1,
+	DA830_RMII_RXER,
+	DA830_AFSR2,
+	DA830_ACLKX2,
+	DA830_AXR2_3,
+	DA830_AXR2_2,
+	DA830_AXR2_1,
+	DA830_AFSX2,
+	DA830_ACLKR2,
+	DA830_NRESETOUT,
+	DA830_GPIO3_0,
+	DA830_GPIO3_1,
+	DA830_GPIO3_2,
+	DA830_GPIO3_3,
+	DA830_GPIO3_4,
+	DA830_GPIO3_5,
+	DA830_GPIO3_6,
+	DA830_AXR0_7,
+	DA830_AXR0_8,
+	DA830_UART1_RXD,
+	DA830_UART1_TXD,
+	DA830_AXR0_11,
+	DA830_AHCLKX1,
+	DA830_ACLKX1,
+	DA830_AFSX1,
+	DA830_MDIO_CLK,
+	DA830_MDIO_D,
+	DA830_AXR0_9,
+	DA830_AXR0_10,
+	DA830_EPWM0B,
+	DA830_EPWM0A,
+	DA830_EPWMSYNCI,
+	DA830_AXR2_0,
+	DA830_EPWMSYNC0,
+	DA830_GPIO3_7,
+	DA830_GPIO3_8,
+	DA830_GPIO3_9,
+	DA830_GPIO3_10,
+	DA830_GPIO3_11,
+	DA830_GPIO3_14,
+	DA830_GPIO3_15,
+	DA830_GPIO4_10,
+	DA830_AHCLKR1,
+	DA830_ACLKR1,
+	DA830_AFSR1,
+	DA830_AMUTE1,
+	DA830_AXR1_0,
+	DA830_AXR1_1,
+	DA830_AXR1_2,
+	DA830_AXR1_3,
+	DA830_ECAP2_APWM2,
+	DA830_EHRPWMGLUETZ,
+	DA830_EQEP1A,
+	DA830_GPIO4_11,
+	DA830_GPIO4_12,
+	DA830_GPIO4_13,
+	DA830_GPIO4_14,
+	DA830_GPIO4_0,
+	DA830_GPIO4_1,
+	DA830_GPIO4_2,
+	DA830_GPIO4_3,
+	DA830_AXR1_4,
+	DA830_AXR1_5,
+	DA830_AXR1_6,
+	DA830_AXR1_7,
+	DA830_AXR1_8,
+	DA830_AXR1_9,
+	DA830_EMA_D_0,
+	DA830_EMA_D_1,
+	DA830_EQEP1B,
+	DA830_EPWM2B,
+	DA830_EPWM2A,
+	DA830_EPWM1B,
+	DA830_EPWM1A,
+	DA830_MMCSD_DAT_0,
+	DA830_MMCSD_DAT_1,
+	DA830_UHPI_HD_0,
+	DA830_UHPI_HD_1,
+	DA830_GPIO4_4,
+	DA830_GPIO4_5,
+	DA830_GPIO4_6,
+	DA830_GPIO4_7,
+	DA830_GPIO4_8,
+	DA830_GPIO4_9,
+	DA830_GPIO0_0,
+	DA830_GPIO0_1,
+	DA830_EMA_D_2,
+	DA830_EMA_D_3,
+	DA830_EMA_D_4,
+	DA830_EMA_D_5,
+	DA830_EMA_D_6,
+	DA830_EMA_D_7,
+	DA830_EMA_D_8,
+	DA830_EMA_D_9,
+	DA830_MMCSD_DAT_2,
+	DA830_MMCSD_DAT_3,
+	DA830_MMCSD_DAT_4,
+	DA830_MMCSD_DAT_5,
+	DA830_MMCSD_DAT_6,
+	DA830_MMCSD_DAT_7,
+	DA830_UHPI_HD_8,
+	DA830_UHPI_HD_9,
+	DA830_UHPI_HD_2,
+	DA830_UHPI_HD_3,
+	DA830_UHPI_HD_4,
+	DA830_UHPI_HD_5,
+	DA830_UHPI_HD_6,
+	DA830_UHPI_HD_7,
+	DA830_LCD_D_8,
+	DA830_LCD_D_9,
+	DA830_GPIO0_2,
+	DA830_GPIO0_3,
+	DA830_GPIO0_4,
+	DA830_GPIO0_5,
+	DA830_GPIO0_6,
+	DA830_GPIO0_7,
+	DA830_GPIO0_8,
+	DA830_GPIO0_9,
+	DA830_EMA_D_10,
+	DA830_EMA_D_11,
+	DA830_EMA_D_12,
+	DA830_EMA_D_13,
+	DA830_EMA_D_14,
+	DA830_EMA_D_15,
+	DA830_EMA_A_0,
+	DA830_EMA_A_1,
+	DA830_UHPI_HD_10,
+	DA830_UHPI_HD_11,
+	DA830_UHPI_HD_12,
+	DA830_UHPI_HD_13,
+	DA830_UHPI_HD_14,
+	DA830_UHPI_HD_15,
+	DA830_LCD_D_7,
+	DA830_MMCSD_CLK,
+	DA830_LCD_D_10,
+	DA830_LCD_D_11,
+	DA830_LCD_D_12,
+	DA830_LCD_D_13,
+	DA830_LCD_D_14,
+	DA830_LCD_D_15,
+	DA830_UHPI_HCNTL0,
+	DA830_GPIO0_10,
+	DA830_GPIO0_11,
+	DA830_GPIO0_12,
+	DA830_GPIO0_13,
+	DA830_GPIO0_14,
+	DA830_GPIO0_15,
+	DA830_GPIO1_0,
+	DA830_GPIO1_1,
+	DA830_EMA_A_2,
+	DA830_EMA_A_3,
+	DA830_EMA_A_4,
+	DA830_EMA_A_5,
+	DA830_EMA_A_6,
+	DA830_EMA_A_7,
+	DA830_EMA_A_8,
+	DA830_EMA_A_9,
+	DA830_MMCSD_CMD,
+	DA830_LCD_D_6,
+	DA830_LCD_D_3,
+	DA830_LCD_D_2,
+	DA830_LCD_D_1,
+	DA830_LCD_D_0,
+	DA830_LCD_PCLK,
+	DA830_LCD_HSYNC,
+	DA830_UHPI_HCNTL1,
+	DA830_GPIO1_2,
+	DA830_GPIO1_3,
+	DA830_GPIO1_4,
+	DA830_GPIO1_5,
+	DA830_GPIO1_6,
+	DA830_GPIO1_7,
+	DA830_GPIO1_8,
+	DA830_GPIO1_9,
+	DA830_EMA_A_10,
+	DA830_EMA_A_11,
+	DA830_EMA_A_12,
+	DA830_EMA_BA_1,
+	DA830_EMA_BA_0,
+	DA830_EMA_CLK,
+	DA830_EMA_SDCKE,
+	DA830_NEMA_CAS,
+	DA830_LCD_VSYNC,
+	DA830_NLCD_AC_ENB_CS,
+	DA830_LCD_MCLK,
+	DA830_LCD_D_5,
+	DA830_LCD_D_4,
+	DA830_OBSCLK,
+	DA830_NEMA_CS_4,
+	DA830_UHPI_HHWIL,
+	DA830_AHCLKR2,
+	DA830_GPIO1_10,
+	DA830_GPIO1_11,
+	DA830_GPIO1_12,
+	DA830_GPIO1_13,
+	DA830_GPIO1_14,
+	DA830_GPIO1_15,
+	DA830_GPIO2_0,
+	DA830_GPIO2_1,
+	DA830_NEMA_RAS,
+	DA830_NEMA_WE,
+	DA830_NEMA_CS_0,
+	DA830_NEMA_CS_2,
+	DA830_NEMA_CS_3,
+	DA830_NEMA_OE,
+	DA830_NEMA_WE_DQM_1,
+	DA830_NEMA_WE_DQM_0,
+	DA830_NEMA_CS_5,
+	DA830_UHPI_HRNW,
+	DA830_NUHPI_HAS,
+	DA830_NUHPI_HCS,
+	DA830_NUHPI_HDS1,
+	DA830_NUHPI_HDS2,
+	DA830_NUHPI_HINT,
+	DA830_AXR0_12,
+	DA830_AMUTE2,
+	DA830_AXR0_13,
+	DA830_AXR0_14,
+	DA830_AXR0_15,
+	DA830_GPIO2_2,
+	DA830_GPIO2_3,
+	DA830_GPIO2_4,
+	DA830_GPIO2_5,
+	DA830_GPIO2_6,
+	DA830_GPIO2_7,
+	DA830_GPIO2_8,
+	DA830_GPIO2_9,
+	DA830_EMA_WAIT_0,
+	DA830_NUHPI_HRDY,
+	DA830_GPIO2_10,
+};
+
+enum davinci_da850_index {
+	/* UART0 function */
+	DA850_NUART0_CTS,
+	DA850_NUART0_RTS,
+	DA850_UART0_RXD,
+	DA850_UART0_TXD,
+
+	/* UART1 function */
+	DA850_NUART1_CTS,
+	DA850_NUART1_RTS,
+	DA850_UART1_RXD,
+	DA850_UART1_TXD,
+
+	/* UART2 function */
+	DA850_NUART2_CTS,
+	DA850_NUART2_RTS,
+	DA850_UART2_RXD,
+	DA850_UART2_TXD,
+
+	/* I2C1 function */
+	DA850_I2C1_SCL,
+	DA850_I2C1_SDA,
+
+	/* I2C0 function */
+	DA850_I2C0_SDA,
+	DA850_I2C0_SCL,
+
+	/* EMAC function */
+	DA850_MII_TXEN,
+	DA850_MII_TXCLK,
+	DA850_MII_COL,
+	DA850_MII_TXD_3,
+	DA850_MII_TXD_2,
+	DA850_MII_TXD_1,
+	DA850_MII_TXD_0,
+	DA850_MII_RXER,
+	DA850_MII_CRS,
+	DA850_MII_RXCLK,
+	DA850_MII_RXDV,
+	DA850_MII_RXD_3,
+	DA850_MII_RXD_2,
+	DA850_MII_RXD_1,
+	DA850_MII_RXD_0,
+	DA850_MDIO_CLK,
+	DA850_MDIO_D,
+
+	/* McASP function */
+	DA850_ACLKR,
+	DA850_ACLKX,
+	DA850_AFSR,
+	DA850_AFSX,
+	DA850_AHCLKR,
+	DA850_AHCLKX,
+	DA850_AMUTE,
+	DA850_AXR_15,
+	DA850_AXR_14,
+	DA850_AXR_13,
+	DA850_AXR_12,
+	DA850_AXR_11,
+	DA850_AXR_10,
+	DA850_AXR_9,
+	DA850_AXR_8,
+	DA850_AXR_7,
+	DA850_AXR_6,
+	DA850_AXR_5,
+	DA850_AXR_4,
+	DA850_AXR_3,
+	DA850_AXR_2,
+	DA850_AXR_1,
+	DA850_AXR_0,
+
+	/* LCD function */
+	DA850_LCD_D_7,
+	DA850_LCD_D_6,
+	DA850_LCD_D_5,
+	DA850_LCD_D_4,
+	DA850_LCD_D_3,
+	DA850_LCD_D_2,
+	DA850_LCD_D_1,
+	DA850_LCD_D_0,
+	DA850_LCD_D_15,
+	DA850_LCD_D_14,
+	DA850_LCD_D_13,
+	DA850_LCD_D_12,
+	DA850_LCD_D_11,
+	DA850_LCD_D_10,
+	DA850_LCD_D_9,
+	DA850_LCD_D_8,
+	DA850_LCD_PCLK,
+	DA850_LCD_HSYNC,
+	DA850_LCD_VSYNC,
+	DA850_NLCD_AC_ENB_CS,
+
+	/* MMC/SD0 function */
+	DA850_MMCSD0_DAT_0,
+	DA850_MMCSD0_DAT_1,
+	DA850_MMCSD0_DAT_2,
+	DA850_MMCSD0_DAT_3,
+	DA850_MMCSD0_CLK,
+	DA850_MMCSD0_CMD,
+
+	/* EMIF2.5/EMIFA function */
+	DA850_EMA_D_7,
+	DA850_EMA_D_6,
+	DA850_EMA_D_5,
+	DA850_EMA_D_4,
+	DA850_EMA_D_3,
+	DA850_EMA_D_2,
+	DA850_EMA_D_1,
+	DA850_EMA_D_0,
+	DA850_EMA_A_1,
+	DA850_EMA_A_2,
+	DA850_NEMA_CS_3,
+	DA850_NEMA_CS_4,
+	DA850_NEMA_WE,
+	DA850_NEMA_OE,
+	DA850_EMA_D_15,
+	DA850_EMA_D_14,
+	DA850_EMA_D_13,
+	DA850_EMA_D_12,
+	DA850_EMA_D_11,
+	DA850_EMA_D_10,
+	DA850_EMA_D_9,
+	DA850_EMA_D_8,
+	DA850_EMA_A_0,
+	DA850_EMA_A_3,
+	DA850_EMA_A_4,
+	DA850_EMA_A_5,
+	DA850_EMA_A_6,
+	DA850_EMA_A_7,
+	DA850_EMA_A_8,
+	DA850_EMA_A_9,
+	DA850_EMA_A_10,
+	DA850_EMA_A_11,
+	DA850_EMA_A_12,
+	DA850_EMA_A_13,
+	DA850_EMA_A_14,
+	DA850_EMA_A_15,
+	DA850_EMA_A_16,
+	DA850_EMA_A_17,
+	DA850_EMA_A_18,
+	DA850_EMA_A_19,
+	DA850_EMA_A_20,
+	DA850_EMA_A_21,
+	DA850_EMA_A_22,
+	DA850_EMA_A_23,
+	DA850_EMA_BA_1,
+	DA850_EMA_CLK,
+	DA850_EMA_WAIT_1,
+	DA850_NEMA_CS_2,
+
+	/* GPIO function */
+	DA850_GPIO2_15,
+	DA850_GPIO8_10,
+	DA850_GPIO4_0,
+	DA850_GPIO4_1,
 };
 
 #ifdef CONFIG_DAVINCI_MUX
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
index ab8a258..171173c 100644
--- a/arch/arm/mach-davinci/include/mach/psc.h
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -81,6 +81,24 @@
 #define DM355_LPSC_RTO			12
 #define DM355_LPSC_VPSS_DAC		41
 
+/* DM365 */
+#define DM365_LPSC_TIMER3	5
+#define DM365_LPSC_SPI1		6
+#define DM365_LPSC_MMC_SD1	7
+#define DM365_LPSC_McBSP1	8
+#define DM365_LPSC_PWM3		10
+#define DM365_LPSC_SPI2		11
+#define DM365_LPSC_RTO		12
+#define DM365_LPSC_TIMER4	17
+#define DM365_LPSC_SPI0		22
+#define DM365_LPSC_SPI3		38
+#define DM365_LPSC_SPI4		39
+#define DM365_LPSC_EMAC		40
+#define DM365_LPSC_VOICE_CODEC	44
+#define DM365_LPSC_DAC_CLK	46
+#define DM365_LPSC_VPSSMSTR	47
+#define DM365_LPSC_MJCP		50
+
 /*
  * LPSC Assignments
  */
@@ -118,6 +136,50 @@
 #define DM646X_LPSC_TIMER1         35
 #define DM646X_LPSC_ARM_INTC       45
 
+/* PSC0 defines */
+#define DA8XX_LPSC0_TPCC		0
+#define DA8XX_LPSC0_TPTC0		1
+#define DA8XX_LPSC0_TPTC1		2
+#define DA8XX_LPSC0_EMIF25		3
+#define DA8XX_LPSC0_SPI0		4
+#define DA8XX_LPSC0_MMC_SD		5
+#define DA8XX_LPSC0_AINTC		6
+#define DA8XX_LPSC0_ARM_RAM_ROM		7
+#define DA8XX_LPSC0_SECU_MGR		8
+#define DA8XX_LPSC0_UART0		9
+#define DA8XX_LPSC0_SCR0_SS		10
+#define DA8XX_LPSC0_SCR1_SS		11
+#define DA8XX_LPSC0_SCR2_SS		12
+#define DA8XX_LPSC0_DMAX		13
+#define DA8XX_LPSC0_ARM			14
+#define DA8XX_LPSC0_GEM			15
+
+/* PSC1 defines */
+#define DA850_LPSC1_TPCC1		0
+#define DA8XX_LPSC1_USB20		1
+#define DA8XX_LPSC1_USB11		2
+#define DA8XX_LPSC1_GPIO		3
+#define DA8XX_LPSC1_UHPI		4
+#define DA8XX_LPSC1_CPGMAC		5
+#define DA8XX_LPSC1_EMIF3C		6
+#define DA8XX_LPSC1_McASP0		7
+#define DA830_LPSC1_McASP1		8
+#define DA850_LPSC1_SATA		8
+#define DA830_LPSC1_McASP2		9
+#define DA8XX_LPSC1_SPI1		10
+#define DA8XX_LPSC1_I2C			11
+#define DA8XX_LPSC1_UART1		12
+#define DA8XX_LPSC1_UART2		13
+#define DA8XX_LPSC1_LCDC		16
+#define DA8XX_LPSC1_PWM			17
+#define DA8XX_LPSC1_ECAP		20
+#define DA830_LPSC1_EQEP		21
+#define DA850_LPSC1_TPTC2		21
+#define DA8XX_LPSC1_SCR_P0_SS		24
+#define DA8XX_LPSC1_SCR_P1_SS		25
+#define DA8XX_LPSC1_CR_P3_SS		26
+#define DA8XX_LPSC1_L3_CBA_RAM		31
+
 extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
 extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
 		unsigned int id, char enable);
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
index 794fa5c..a584697 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -11,13 +11,17 @@
 #ifndef __ASM_ARCH_SERIAL_H
 #define __ASM_ARCH_SERIAL_H
 
-#include <mach/io.h>
+#include <mach/hardware.h>
 
 #define DAVINCI_MAX_NR_UARTS	3
 #define DAVINCI_UART0_BASE	(IO_PHYS + 0x20000)
 #define DAVINCI_UART1_BASE	(IO_PHYS + 0x20400)
 #define DAVINCI_UART2_BASE	(IO_PHYS + 0x20800)
 
+#define DA8XX_UART0_BASE	(IO_PHYS + 0x042000)
+#define DA8XX_UART1_BASE	(IO_PHYS + 0x10c000)
+#define DA8XX_UART2_BASE	(IO_PHYS + 0x10d000)
+
 /* DaVinci UART register offsets */
 #define UART_DAVINCI_PWREMU		0x0c
 #define UART_DM646X_SCR			0x10
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
index b7e7036..8e4f10f 100644
--- a/arch/arm/mach-davinci/include/mach/system.h
+++ b/arch/arm/mach-davinci/include/mach/system.h
@@ -16,12 +16,12 @@
 
 extern void davinci_watchdog_reset(void);
 
-static void arch_idle(void)
+static inline void arch_idle(void)
 {
 	cpu_do_idle();
 }
 
-static void arch_reset(char mode, const char *cmd)
+static inline void arch_reset(char mode, const char *cmd)
 {
 	davinci_watchdog_reset();
 }
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
index 1e27475..33796b4 100644
--- a/arch/arm/mach-davinci/include/mach/uncompress.h
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -21,8 +21,11 @@ static u32 *uart;
 
 static u32 *get_uart_base(void)
 {
-	/* Add logic here for new platforms, using __macine_arch_type */
-	return (u32 *)DAVINCI_UART0_BASE;
+	if (__machine_arch_type == MACH_TYPE_DAVINCI_DA830_EVM ||
+		__machine_arch_type == MACH_TYPE_DAVINCI_DA850_EVM)
+		return (u32 *)DA8XX_UART2_BASE;
+	else
+		return (u32 *)DAVINCI_UART0_BASE;
 }
 
 /* PORT_16C550A, in polled non-fifo mode */
diff --git a/arch/arm/mach-davinci/include/mach/vmalloc.h b/arch/arm/mach-davinci/include/mach/vmalloc.h
index ad51625..d49646a 100644
--- a/arch/arm/mach-davinci/include/mach/vmalloc.h
+++ b/arch/arm/mach-davinci/include/mach/vmalloc.h
@@ -8,7 +8,7 @@
  * is licensed "as is" without any warranty of any kind, whether express
  * or implied.
  */
-#include <mach/io.h>
+#include <mach/hardware.h>
 
 /* Allow vmalloc range until the IO virtual range minus a 2M "hole" */
 #define VMALLOC_END	  (IO_VIRT - (2<<20))
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
index d310f57..898905e 100644
--- a/arch/arm/mach-davinci/mux.c
+++ b/arch/arm/mach-davinci/mux.c
@@ -91,3 +91,17 @@ int __init_or_module davinci_cfg_reg(const unsigned long index)
 	return 0;
 }
 EXPORT_SYMBOL(davinci_cfg_reg);
+
+int da8xx_pinmux_setup(const short pins[])
+{
+	int i, error = -EINVAL;
+
+	if (pins)
+		for (i = 0; pins[i] >= 0; i++) {
+			error = davinci_cfg_reg(pins[i]);
+			if (error)
+				break;
+		}
+
+	return error;
+}
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
index db54b2a..4f1fc9b 100644
--- a/arch/arm/mach-davinci/sram.c
+++ b/arch/arm/mach-davinci/sram.c
@@ -60,7 +60,7 @@ static int __init sram_init(void)
 	int status = 0;
 
 	if (len) {
-		len = min(len, SRAM_SIZE);
+		len = min_t(unsigned, len, SRAM_SIZE);
 		sram_pool = gen_pool_create(ilog2(SRAM_GRANULARITY), -1);
 		if (!sram_pool)
 			status = -ENOMEM;
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 0884ca5..0d1b6d4 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -406,11 +406,11 @@ struct sys_timer davinci_timer = {
 void davinci_watchdog_reset(void)
 {
 	u32 tgcr, wdtcr;
-	struct davinci_soc_info *soc_info = &davinci_soc_info;
-	void __iomem *base = soc_info->wdt_base;
+	struct platform_device *pdev = &davinci_wdt_device;
+	void __iomem *base = IO_ADDRESS(pdev->resource[0].start);
 	struct clk *wd_clk;
 
-	wd_clk = clk_get(&davinci_wdt_device.dev, NULL);
+	wd_clk = clk_get(&pdev->dev, NULL);
 	if (WARN_ON(IS_ERR(wd_clk)))
 		return;
 	clk_enable(wd_clk);
@@ -420,11 +420,11 @@ void davinci_watchdog_reset(void)
 
 	/* reset timer, set mode to 64-bit watchdog, and unreset */
 	tgcr = 0;
-	__raw_writel(tgcr, base + TCR);
+	__raw_writel(tgcr, base + TGCR);
 	tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
 	tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
 		(TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
-	__raw_writel(tgcr, base + TCR);
+	__raw_writel(tgcr, base + TGCR);
 
 	/* clear counter and period regs */
 	__raw_writel(0, base + TIM12);
@@ -432,12 +432,8 @@ void davinci_watchdog_reset(void)
 	__raw_writel(0, base + PRD12);
 	__raw_writel(0, base + PRD34);
 
-	/* enable */
-	wdtcr = __raw_readl(base + WDTCR);
-	wdtcr |= WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT;
-	__raw_writel(wdtcr, base + WDTCR);
-
 	/* put watchdog in pre-active state */
+	wdtcr = __raw_readl(base + WDTCR);
 	wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
 		(WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
 	__raw_writel(wdtcr, base + WDTCR);
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
index abedb63..06f5593 100644
--- a/arch/arm/mach-davinci/usb.c
+++ b/arch/arm/mach-davinci/usb.c
@@ -13,6 +13,7 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/irqs.h>
+#include <mach/cputype.h>
 
 #define DAVINCI_USB_OTG_BASE 0x01C64000
 
@@ -64,6 +65,10 @@ static struct resource usb_resources[] = {
 		.start          = IRQ_USBINT,
 		.flags          = IORESOURCE_IRQ,
 	},
+	{
+		/* placeholder for the dedicated CPPI IRQ */
+		.flags          = IORESOURCE_IRQ,
+	},
 };
 
 static u64 usb_dmamask = DMA_BIT_MASK(32);
@@ -84,6 +89,14 @@ void __init setup_usb(unsigned mA, unsigned potpgt_msec)
 {
 	usb_data.power = mA / 2;
 	usb_data.potpgt = potpgt_msec / 2;
+
+	if (cpu_is_davinci_dm646x()) {
+		/* Override the defaults as DM6467 uses different IRQs. */
+		usb_dev.resource[1].start = IRQ_DM646X_USBINT;
+		usb_dev.resource[2].start = IRQ_DM646X_USBDMAINT;
+	} else	/* other devices don't have dedicated CPPI IRQ */
+		usb_dev.num_resources = 2;
+
 	platform_device_register(&usb_dev);
 }
 
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index 3fbd9b0..caf6d51 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -12,18 +12,15 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
+#include <linux/mtd/physmap.h>
+
 #include <mach/hardware.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+
 static struct physmap_flash_data adssphere_flash_data = {
 	.width		= 4,
 };
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 6c4c163..3dd0e2a 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -22,48 +22,39 @@
 #include <mach/hardware.h>
 
 
-/*
- * The EP93xx has two external crystal oscillators.  To generate the
- * required high-frequency clocks, the processor uses two phase-locked-
- * loops (PLLs) to multiply the incoming external clock signal to much
- * higher frequencies that are then divided down by programmable dividers
- * to produce the needed clocks.  The PLLs operate independently of one
- * another.
- */
-#define EP93XX_EXT_CLK_RATE	14745600
-#define EP93XX_EXT_RTC_RATE	32768
-
-
 struct clk {
 	unsigned long	rate;
 	int		users;
 	int		sw_locked;
-	u32		enable_reg;
+	void __iomem	*enable_reg;
 	u32		enable_mask;
 
 	unsigned long	(*get_rate)(struct clk *clk);
+	int		(*set_rate)(struct clk *clk, unsigned long rate);
 };
 
 
 static unsigned long get_uart_rate(struct clk *clk);
 
+static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
+
 
 static struct clk clk_uart1 = {
 	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVICE_CONFIG,
-	.enable_mask	= EP93XX_SYSCON_DEVICE_CONFIG_U1EN,
+	.enable_reg	= EP93XX_SYSCON_DEVCFG,
+	.enable_mask	= EP93XX_SYSCON_DEVCFG_U1EN,
 	.get_rate	= get_uart_rate,
 };
 static struct clk clk_uart2 = {
 	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVICE_CONFIG,
-	.enable_mask	= EP93XX_SYSCON_DEVICE_CONFIG_U2EN,
+	.enable_reg	= EP93XX_SYSCON_DEVCFG,
+	.enable_mask	= EP93XX_SYSCON_DEVCFG_U2EN,
 	.get_rate	= get_uart_rate,
 };
 static struct clk clk_uart3 = {
 	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVICE_CONFIG,
-	.enable_mask	= EP93XX_SYSCON_DEVICE_CONFIG_U3EN,
+	.enable_reg	= EP93XX_SYSCON_DEVCFG,
+	.enable_mask	= EP93XX_SYSCON_DEVCFG_U3EN,
 	.get_rate	= get_uart_rate,
 };
 static struct clk clk_pll1;
@@ -75,6 +66,15 @@ static struct clk clk_usb_host = {
 	.enable_reg	= EP93XX_SYSCON_PWRCNT,
 	.enable_mask	= EP93XX_SYSCON_PWRCNT_USH_EN,
 };
+static struct clk clk_keypad = {
+	.sw_locked	= 1,
+	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
+	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
+	.set_rate	= set_keytchclk_rate,
+};
+static struct clk clk_pwm = {
+	.rate		= EP93XX_EXT_CLK_RATE,
+};
 
 /* DMA Clocks */
 static struct clk clk_m2p0 = {
@@ -130,27 +130,29 @@ static struct clk clk_m2m1 = {
 	{ .dev_id = dev, .con_id = con, .clk = ck }
 
 static struct clk_lookup clocks[] = {
-	INIT_CK("apb:uart1", NULL, &clk_uart1),
-	INIT_CK("apb:uart2", NULL, &clk_uart2),
-	INIT_CK("apb:uart3", NULL, &clk_uart3),
-	INIT_CK(NULL, "pll1", &clk_pll1),
-	INIT_CK(NULL, "fclk", &clk_f),
-	INIT_CK(NULL, "hclk", &clk_h),
-	INIT_CK(NULL, "pclk", &clk_p),
-	INIT_CK(NULL, "pll2", &clk_pll2),
-	INIT_CK("ep93xx-ohci", NULL, &clk_usb_host),
-	INIT_CK(NULL, "m2p0", &clk_m2p0),
-	INIT_CK(NULL, "m2p1", &clk_m2p1),
-	INIT_CK(NULL, "m2p2", &clk_m2p2),
-	INIT_CK(NULL, "m2p3", &clk_m2p3),
-	INIT_CK(NULL, "m2p4", &clk_m2p4),
-	INIT_CK(NULL, "m2p5", &clk_m2p5),
-	INIT_CK(NULL, "m2p6", &clk_m2p6),
-	INIT_CK(NULL, "m2p7", &clk_m2p7),
-	INIT_CK(NULL, "m2p8", &clk_m2p8),
-	INIT_CK(NULL, "m2p9", &clk_m2p9),
-	INIT_CK(NULL, "m2m0", &clk_m2m0),
-	INIT_CK(NULL, "m2m1", &clk_m2m1),
+	INIT_CK("apb:uart1",		NULL,		&clk_uart1),
+	INIT_CK("apb:uart2",		NULL,		&clk_uart2),
+	INIT_CK("apb:uart3",		NULL,		&clk_uart3),
+	INIT_CK(NULL,			"pll1",		&clk_pll1),
+	INIT_CK(NULL,			"fclk",		&clk_f),
+	INIT_CK(NULL,			"hclk",		&clk_h),
+	INIT_CK(NULL,			"pclk",		&clk_p),
+	INIT_CK(NULL,			"pll2",		&clk_pll2),
+	INIT_CK("ep93xx-ohci",		NULL,		&clk_usb_host),
+	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
+	INIT_CK(NULL,			"pwm_clk",	&clk_pwm),
+	INIT_CK(NULL,			"m2p0",		&clk_m2p0),
+	INIT_CK(NULL,			"m2p1",		&clk_m2p1),
+	INIT_CK(NULL,			"m2p2",		&clk_m2p2),
+	INIT_CK(NULL,			"m2p3",		&clk_m2p3),
+	INIT_CK(NULL,			"m2p4",		&clk_m2p4),
+	INIT_CK(NULL,			"m2p5",		&clk_m2p5),
+	INIT_CK(NULL,			"m2p6",		&clk_m2p6),
+	INIT_CK(NULL,			"m2p7",		&clk_m2p7),
+	INIT_CK(NULL,			"m2p8",		&clk_m2p8),
+	INIT_CK(NULL,			"m2p9",		&clk_m2p9),
+	INIT_CK(NULL,			"m2m0",		&clk_m2m0),
+	INIT_CK(NULL,			"m2m1",		&clk_m2m1),
 };
 
 
@@ -160,9 +162,11 @@ int clk_enable(struct clk *clk)
 		u32 value;
 
 		value = __raw_readl(clk->enable_reg);
+		value |= clk->enable_mask;
 		if (clk->sw_locked)
-			__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-		__raw_writel(value | clk->enable_mask, clk->enable_reg);
+			ep93xx_syscon_swlocked_write(value, clk->enable_reg);
+		else
+			__raw_writel(value, clk->enable_reg);
 	}
 
 	return 0;
@@ -175,9 +179,11 @@ void clk_disable(struct clk *clk)
 		u32 value;
 
 		value = __raw_readl(clk->enable_reg);
+		value &= ~clk->enable_mask;
 		if (clk->sw_locked)
-			__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-		__raw_writel(value & ~clk->enable_mask, clk->enable_reg);
+			ep93xx_syscon_swlocked_write(value, clk->enable_reg);
+		else
+			__raw_writel(value, clk->enable_reg);
 	}
 }
 EXPORT_SYMBOL(clk_disable);
@@ -202,6 +208,43 @@ unsigned long clk_get_rate(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_get_rate);
 
+static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
+{
+	u32 val;
+	u32 div_bit;
+
+	val = __raw_readl(clk->enable_reg);
+
+	/*
+	 * The Key Matrix and ADC clocks are configured using the same
+	 * System Controller register.  The clock used will be either
+	 * 1/4 or 1/16 the external clock rate depending on the
+	 * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
+	 * bit being set or cleared.
+	 */
+	div_bit = clk->enable_mask >> 15;
+
+	if (rate == EP93XX_KEYTCHCLK_DIV4)
+		val |= div_bit;
+	else if (rate == EP93XX_KEYTCHCLK_DIV16)
+		val &= ~div_bit;
+	else
+		return -EINVAL;
+
+	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
+	clk->rate = rate;
+	return 0;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk->set_rate)
+		return clk->set_rate(clk, rate);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
 
 static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
 static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 204dc5c..16b92c3 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -16,40 +16,24 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/bitops.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_core.h>
-#include <linux/device.h>
-#include <linux/mm.h>
 #include <linux/dma-mapping.h>
-#include <linux/time.h>
 #include <linux/timex.h>
-#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
 #include <linux/termios.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/serial.h>
-#include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
 
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
 #include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/tlbflush.h>
-#include <asm/pgtable.h>
 
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
-#include <mach/gpio.h>
 
 #include <asm/hardware/vic.h>
 
@@ -98,7 +82,7 @@ void __init ep93xx_map_io(void)
  */
 static unsigned int last_jiffy_time;
 
-#define TIMER4_TICKS_PER_JIFFY		((CLOCK_TICK_RATE + (HZ/2)) / HZ)
+#define TIMER4_TICKS_PER_JIFFY		DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
 
 static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
 {
@@ -362,8 +346,8 @@ void __init ep93xx_init_irq(void)
 {
 	int gpio_irq;
 
-	vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
-	vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
+	vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
+	vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
 
 	for (gpio_irq = gpio_to_irq(0);
 	     gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
@@ -385,6 +369,47 @@ void __init ep93xx_init_irq(void)
 
 
 /*************************************************************************
+ * EP93xx System Controller Software Locked register handling
+ *************************************************************************/
+
+/*
+ * syscon_swlock prevents anything else from writing to the syscon
+ * block while a software locked register is being written.
+ */
+static DEFINE_SPINLOCK(syscon_swlock);
+
+void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&syscon_swlock, flags);
+
+	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+	__raw_writel(val, reg);
+
+	spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_syscon_swlocked_write);
+
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
+{
+	unsigned long flags;
+	unsigned int val;
+
+	spin_lock_irqsave(&syscon_swlock, flags);
+
+	val = __raw_readl(EP93XX_SYSCON_DEVCFG);
+	val |= set_bits;
+	val &= ~clear_bits;
+	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+	__raw_writel(val, EP93XX_SYSCON_DEVCFG);
+
+	spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
+
+
+/*************************************************************************
  * EP93xx peripheral handling
  *************************************************************************/
 #define EP93XX_UART_MCR_OFFSET		(0x0100)
@@ -517,10 +542,8 @@ static struct platform_device ep93xx_eth_device = {
 
 void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
 {
-	if (copy_addr) {
-		memcpy(data->dev_addr,
-			(void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
-	}
+	if (copy_addr)
+		memcpy_fromio(data->dev_addr, EP93XX_ETHERNET_BASE + 0x50, 6);
 
 	ep93xx_eth_data = *data;
 	platform_device_register(&ep93xx_eth_device);
@@ -546,19 +569,125 @@ void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num)
 	platform_device_register(&ep93xx_i2c_device);
 }
 
+
+/*************************************************************************
+ * EP93xx LEDs
+ *************************************************************************/
+static struct gpio_led ep93xx_led_pins[] = {
+	{
+		.name			= "platform:grled",
+		.gpio			= EP93XX_GPIO_LINE_GRLED,
+	}, {
+		.name			= "platform:rdled",
+		.gpio			= EP93XX_GPIO_LINE_RDLED,
+	},
+};
+
+static struct gpio_led_platform_data ep93xx_led_data = {
+	.num_leds	= ARRAY_SIZE(ep93xx_led_pins),
+	.leds		= ep93xx_led_pins,
+};
+
+static struct platform_device ep93xx_leds = {
+	.name		= "leds-gpio",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &ep93xx_led_data,
+	},
+};
+
+
+/*************************************************************************
+ * EP93xx pwm peripheral handling
+ *************************************************************************/
+static struct resource ep93xx_pwm0_resource[] = {
+	{
+		.start	= EP93XX_PWM_PHYS_BASE,
+		.end	= EP93XX_PWM_PHYS_BASE + 0x10 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ep93xx_pwm0_device = {
+	.name		= "ep93xx-pwm",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(ep93xx_pwm0_resource),
+	.resource	= ep93xx_pwm0_resource,
+};
+
+static struct resource ep93xx_pwm1_resource[] = {
+	{
+		.start	= EP93XX_PWM_PHYS_BASE + 0x20,
+		.end	= EP93XX_PWM_PHYS_BASE + 0x30 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ep93xx_pwm1_device = {
+	.name		= "ep93xx-pwm",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(ep93xx_pwm1_resource),
+	.resource	= ep93xx_pwm1_resource,
+};
+
+void __init ep93xx_register_pwm(int pwm0, int pwm1)
+{
+	if (pwm0)
+		platform_device_register(&ep93xx_pwm0_device);
+
+	/* NOTE: EP9307 does not have PWMOUT1 (pin EGPIO14) */
+	if (pwm1)
+		platform_device_register(&ep93xx_pwm1_device);
+}
+
+int ep93xx_pwm_acquire_gpio(struct platform_device *pdev)
+{
+	int err;
+
+	if (pdev->id == 0) {
+		err = 0;
+	} else if (pdev->id == 1) {
+		err = gpio_request(EP93XX_GPIO_LINE_EGPIO14,
+				   dev_name(&pdev->dev));
+		if (err)
+			return err;
+		err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0);
+		if (err)
+			goto fail;
+
+		/* PWM 1 output on EGPIO[14] */
+		ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG);
+	} else {
+		err = -ENODEV;
+	}
+
+	return err;
+
+fail:
+	gpio_free(EP93XX_GPIO_LINE_EGPIO14);
+	return err;
+}
+EXPORT_SYMBOL(ep93xx_pwm_acquire_gpio);
+
+void ep93xx_pwm_release_gpio(struct platform_device *pdev)
+{
+	if (pdev->id == 1) {
+		gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14);
+		gpio_free(EP93XX_GPIO_LINE_EGPIO14);
+
+		/* EGPIO[14] used for GPIO */
+		ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG);
+	}
+}
+EXPORT_SYMBOL(ep93xx_pwm_release_gpio);
+
+
 extern void ep93xx_gpio_init(void);
 
 void __init ep93xx_init_devices(void)
 {
-	unsigned int v;
-
-	/*
-	 * Disallow access to MaverickCrunch initially.
-	 */
-	v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
-	v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
-	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-	__raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
+	/* Disallow access to MaverickCrunch initially */
+	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
 
 	ep93xx_gpio_init();
 
@@ -568,4 +697,5 @@ void __init ep93xx_init_devices(void)
 
 	platform_device_register(&ep93xx_rtc_device);
 	platform_device_register(&ep93xx_ohci_device);
+	platform_device_register(&ep93xx_leds);
 }
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index e9e45b9..73145ae 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -26,18 +26,16 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <linux/io.h>
 #include <linux/i2c.h>
+#include <linux/mtd/physmap.h>
+
 #include <mach/hardware.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+
 static struct physmap_flash_data edb93xx_flash_data;
 
 static struct resource edb93xx_flash_resource = {
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index 3bad500..3da7ca8 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -12,18 +12,15 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
+#include <linux/mtd/physmap.h>
+
 #include <mach/hardware.h>
+
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+
 static struct physmap_flash_data gesbc9312_flash_data = {
 	.width		= 4,
 };
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index 482cf3d..1ea8871 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -17,15 +17,16 @@
 #include <linux/module.h>
 #include <linux/seq_file.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
 
-#include <mach/ep93xx-regs.h>
-#include <asm/gpio.h>
+#include <mach/hardware.h>
 
 struct ep93xx_gpio_chip {
 	struct gpio_chip	chip;
 
-	unsigned int		data_reg;
-	unsigned int		data_dir_reg;
+	void __iomem		*data_reg;
+	void __iomem		*data_dir_reg;
 };
 
 #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
@@ -111,15 +112,61 @@ static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
 	struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
 	u8 data_reg, data_dir_reg;
-	int i;
+	int gpio, i;
 
 	data_reg = __raw_readb(ep93xx_chip->data_reg);
 	data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg);
 
-	for (i = 0; i < chip->ngpio; i++)
-		seq_printf(s, "GPIO %s%d: %s %s\n", chip->label, i,
-			   (data_reg & (1 << i)) ? "set" : "clear",
-			   (data_dir_reg & (1 << i)) ? "out" : "in");
+	gpio = ep93xx_chip->chip.base;
+	for (i = 0; i < chip->ngpio; i++, gpio++) {
+		int is_out = data_dir_reg & (1 << i);
+
+		seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s",
+				chip->label, i, gpio,
+				gpiochip_is_requested(chip, i) ? : "",
+				is_out ? "out" : "in ",
+				(data_reg & (1 << i)) ? "hi" : "lo");
+
+		if (!is_out) {
+			int irq = gpio_to_irq(gpio);
+			struct irq_desc *desc = irq_desc + irq;
+
+			if (irq >= 0 && desc->action) {
+				char *trigger;
+
+				switch (desc->status & IRQ_TYPE_SENSE_MASK) {
+				case IRQ_TYPE_NONE:
+					trigger = "(default)";
+					break;
+				case IRQ_TYPE_EDGE_FALLING:
+					trigger = "edge-falling";
+					break;
+				case IRQ_TYPE_EDGE_RISING:
+					trigger = "edge-rising";
+					break;
+				case IRQ_TYPE_EDGE_BOTH:
+					trigger = "edge-both";
+					break;
+				case IRQ_TYPE_LEVEL_HIGH:
+					trigger = "level-high";
+					break;
+				case IRQ_TYPE_LEVEL_LOW:
+					trigger = "level-low";
+					break;
+				default:
+					trigger = "?trigger?";
+					break;
+				}
+
+				seq_printf(s, " irq-%d %s%s",
+						irq, trigger,
+						(desc->status & IRQ_WAKEUP)
+							? " wakeup" : "");
+			}
+		}
+
+		seq_printf(s, "\n");
+	}
 }
 
 #define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio)			\
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 967c079..ea78e90 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -52,40 +52,43 @@
 #define EP93XX_AHB_VIRT_BASE		0xfef00000
 #define EP93XX_AHB_SIZE			0x00100000
 
+#define EP93XX_AHB_IOMEM(x)		IOMEM(EP93XX_AHB_VIRT_BASE + (x))
+
 #define EP93XX_APB_PHYS_BASE		0x80800000
 #define EP93XX_APB_VIRT_BASE		0xfed00000
 #define EP93XX_APB_SIZE			0x00200000
 
+#define EP93XX_APB_IOMEM(x)		IOMEM(EP93XX_APB_VIRT_BASE + (x))
+
 
 /* AHB peripherals */
-#define EP93XX_DMA_BASE			((void __iomem *)		\
-					 (EP93XX_AHB_VIRT_BASE + 0x00000000))
+#define EP93XX_DMA_BASE			EP93XX_AHB_IOMEM(0x00000000)
 
-#define EP93XX_ETHERNET_BASE		(EP93XX_AHB_VIRT_BASE + 0x00010000)
 #define EP93XX_ETHERNET_PHYS_BASE	(EP93XX_AHB_PHYS_BASE + 0x00010000)
+#define EP93XX_ETHERNET_BASE		EP93XX_AHB_IOMEM(0x00010000)
 
-#define EP93XX_USB_BASE			(EP93XX_AHB_VIRT_BASE + 0x00020000)
 #define EP93XX_USB_PHYS_BASE		(EP93XX_AHB_PHYS_BASE + 0x00020000)
+#define EP93XX_USB_BASE			EP93XX_AHB_IOMEM(0x00020000)
 
-#define EP93XX_RASTER_BASE		(EP93XX_AHB_VIRT_BASE + 0x00030000)
+#define EP93XX_RASTER_BASE		EP93XX_AHB_IOMEM(0x00030000)
 
-#define EP93XX_GRAPHICS_ACCEL_BASE	(EP93XX_AHB_VIRT_BASE + 0x00040000)
+#define EP93XX_GRAPHICS_ACCEL_BASE	EP93XX_AHB_IOMEM(0x00040000)
 
-#define EP93XX_SDRAM_CONTROLLER_BASE	(EP93XX_AHB_VIRT_BASE + 0x00060000)
+#define EP93XX_SDRAM_CONTROLLER_BASE	EP93XX_AHB_IOMEM(0x00060000)
 
-#define EP93XX_PCMCIA_CONTROLLER_BASE	(EP93XX_AHB_VIRT_BASE + 0x00080000)
+#define EP93XX_PCMCIA_CONTROLLER_BASE	EP93XX_AHB_IOMEM(0x00080000)
 
-#define EP93XX_BOOT_ROM_BASE		(EP93XX_AHB_VIRT_BASE + 0x00090000)
+#define EP93XX_BOOT_ROM_BASE		EP93XX_AHB_IOMEM(0x00090000)
 
-#define EP93XX_IDE_BASE			(EP93XX_AHB_VIRT_BASE + 0x000a0000)
+#define EP93XX_IDE_BASE			EP93XX_AHB_IOMEM(0x000a0000)
 
-#define EP93XX_VIC1_BASE		(EP93XX_AHB_VIRT_BASE + 0x000b0000)
+#define EP93XX_VIC1_BASE		EP93XX_AHB_IOMEM(0x000b0000)
 
-#define EP93XX_VIC2_BASE		(EP93XX_AHB_VIRT_BASE + 0x000c0000)
+#define EP93XX_VIC2_BASE		EP93XX_AHB_IOMEM(0x000c0000)
 
 
 /* APB peripherals */
-#define EP93XX_TIMER_BASE		(EP93XX_APB_VIRT_BASE + 0x00010000)
+#define EP93XX_TIMER_BASE		EP93XX_APB_IOMEM(0x00010000)
 #define EP93XX_TIMER_REG(x)		(EP93XX_TIMER_BASE + (x))
 #define EP93XX_TIMER1_LOAD		EP93XX_TIMER_REG(0x00)
 #define EP93XX_TIMER1_VALUE		EP93XX_TIMER_REG(0x04)
@@ -102,11 +105,11 @@
 #define EP93XX_TIMER3_CONTROL		EP93XX_TIMER_REG(0x88)
 #define EP93XX_TIMER3_CLEAR		EP93XX_TIMER_REG(0x8c)
 
-#define EP93XX_I2S_BASE			(EP93XX_APB_VIRT_BASE + 0x00020000)
+#define EP93XX_I2S_BASE			EP93XX_APB_IOMEM(0x00020000)
 
-#define EP93XX_SECURITY_BASE		(EP93XX_APB_VIRT_BASE + 0x00030000)
+#define EP93XX_SECURITY_BASE		EP93XX_APB_IOMEM(0x00030000)
 
-#define EP93XX_GPIO_BASE		(EP93XX_APB_VIRT_BASE + 0x00040000)
+#define EP93XX_GPIO_BASE		EP93XX_APB_IOMEM(0x00040000)
 #define EP93XX_GPIO_REG(x)		(EP93XX_GPIO_BASE + (x))
 #define EP93XX_GPIO_F_INT_TYPE1		EP93XX_GPIO_REG(0x4c)
 #define EP93XX_GPIO_F_INT_TYPE2		EP93XX_GPIO_REG(0x50)
@@ -124,32 +127,33 @@
 #define EP93XX_GPIO_B_INT_ENABLE	EP93XX_GPIO_REG(0xb8)
 #define EP93XX_GPIO_B_INT_STATUS	EP93XX_GPIO_REG(0xbc)
 
-#define EP93XX_AAC_BASE			(EP93XX_APB_VIRT_BASE + 0x00080000)
+#define EP93XX_AAC_BASE			EP93XX_APB_IOMEM(0x00080000)
 
-#define EP93XX_SPI_BASE			(EP93XX_APB_VIRT_BASE + 0x000a0000)
+#define EP93XX_SPI_BASE			EP93XX_APB_IOMEM(0x000a0000)
 
-#define EP93XX_IRDA_BASE		(EP93XX_APB_VIRT_BASE + 0x000b0000)
+#define EP93XX_IRDA_BASE		EP93XX_APB_IOMEM(0x000b0000)
 
-#define EP93XX_UART1_BASE		(EP93XX_APB_VIRT_BASE + 0x000c0000)
 #define EP93XX_UART1_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x000c0000)
+#define EP93XX_UART1_BASE		EP93XX_APB_IOMEM(0x000c0000)
 
-#define EP93XX_UART2_BASE		(EP93XX_APB_VIRT_BASE + 0x000d0000)
 #define EP93XX_UART2_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x000d0000)
+#define EP93XX_UART2_BASE		EP93XX_APB_IOMEM(0x000d0000)
 
-#define EP93XX_UART3_BASE		(EP93XX_APB_VIRT_BASE + 0x000e0000)
 #define EP93XX_UART3_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x000e0000)
+#define EP93XX_UART3_BASE		EP93XX_APB_IOMEM(0x000e0000)
 
-#define EP93XX_KEY_MATRIX_BASE		(EP93XX_APB_VIRT_BASE + 0x000f0000)
+#define EP93XX_KEY_MATRIX_BASE		EP93XX_APB_IOMEM(0x000f0000)
 
-#define EP93XX_ADC_BASE			(EP93XX_APB_VIRT_BASE + 0x00100000)
-#define EP93XX_TOUCHSCREEN_BASE		(EP93XX_APB_VIRT_BASE + 0x00100000)
+#define EP93XX_ADC_BASE			EP93XX_APB_IOMEM(0x00100000)
+#define EP93XX_TOUCHSCREEN_BASE		EP93XX_APB_IOMEM(0x00100000)
 
-#define EP93XX_PWM_BASE			(EP93XX_APB_VIRT_BASE + 0x00110000)
+#define EP93XX_PWM_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x00110000)
+#define EP93XX_PWM_BASE			EP93XX_APB_IOMEM(0x00110000)
 
-#define EP93XX_RTC_BASE			(EP93XX_APB_VIRT_BASE + 0x00120000)
 #define EP93XX_RTC_PHYS_BASE		(EP93XX_APB_PHYS_BASE + 0x00120000)
+#define EP93XX_RTC_BASE			EP93XX_APB_IOMEM(0x00120000)
 
-#define EP93XX_SYSCON_BASE		(EP93XX_APB_VIRT_BASE + 0x00130000)
+#define EP93XX_SYSCON_BASE		EP93XX_APB_IOMEM(0x00130000)
 #define EP93XX_SYSCON_REG(x)		(EP93XX_SYSCON_BASE + (x))
 #define EP93XX_SYSCON_POWER_STATE	EP93XX_SYSCON_REG(0x00)
 #define EP93XX_SYSCON_PWRCNT		EP93XX_SYSCON_REG(0x04)
@@ -172,14 +176,45 @@
 #define EP93XX_SYSCON_STANDBY		EP93XX_SYSCON_REG(0x0c)
 #define EP93XX_SYSCON_CLOCK_SET1	EP93XX_SYSCON_REG(0x20)
 #define EP93XX_SYSCON_CLOCK_SET2	EP93XX_SYSCON_REG(0x24)
-#define EP93XX_SYSCON_DEVICE_CONFIG	EP93XX_SYSCON_REG(0x80)
-#define EP93XX_SYSCON_DEVICE_CONFIG_U3EN		(1<<24)
-#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE	(1<<23)
-#define EP93XX_SYSCON_DEVICE_CONFIG_U2EN		(1<<20)
-#define EP93XX_SYSCON_DEVICE_CONFIG_U1EN		(1<<18)
+#define EP93XX_SYSCON_DEVCFG		EP93XX_SYSCON_REG(0x80)
+#define EP93XX_SYSCON_DEVCFG_SWRST	(1<<31)
+#define EP93XX_SYSCON_DEVCFG_D1ONG	(1<<30)
+#define EP93XX_SYSCON_DEVCFG_D0ONG	(1<<29)
+#define EP93XX_SYSCON_DEVCFG_IONU2	(1<<28)
+#define EP93XX_SYSCON_DEVCFG_GONK	(1<<27)
+#define EP93XX_SYSCON_DEVCFG_TONG	(1<<26)
+#define EP93XX_SYSCON_DEVCFG_MONG	(1<<25)
+#define EP93XX_SYSCON_DEVCFG_U3EN	(1<<24)
+#define EP93XX_SYSCON_DEVCFG_CPENA	(1<<23)
+#define EP93XX_SYSCON_DEVCFG_A2ONG	(1<<22)
+#define EP93XX_SYSCON_DEVCFG_A1ONG	(1<<21)
+#define EP93XX_SYSCON_DEVCFG_U2EN	(1<<20)
+#define EP93XX_SYSCON_DEVCFG_EXVC	(1<<19)
+#define EP93XX_SYSCON_DEVCFG_U1EN	(1<<18)
+#define EP93XX_SYSCON_DEVCFG_TIN	(1<<17)
+#define EP93XX_SYSCON_DEVCFG_HC3IN	(1<<15)
+#define EP93XX_SYSCON_DEVCFG_HC3EN	(1<<14)
+#define EP93XX_SYSCON_DEVCFG_HC1IN	(1<<13)
+#define EP93XX_SYSCON_DEVCFG_HC1EN	(1<<12)
+#define EP93XX_SYSCON_DEVCFG_HONIDE	(1<<11)
+#define EP93XX_SYSCON_DEVCFG_GONIDE	(1<<10)
+#define EP93XX_SYSCON_DEVCFG_PONG	(1<<9)
+#define EP93XX_SYSCON_DEVCFG_EONIDE	(1<<8)
+#define EP93XX_SYSCON_DEVCFG_I2SONSSP	(1<<7)
+#define EP93XX_SYSCON_DEVCFG_I2SONAC97	(1<<6)
+#define EP93XX_SYSCON_DEVCFG_RASONP3	(1<<4)
+#define EP93XX_SYSCON_DEVCFG_RAS	(1<<3)
+#define EP93XX_SYSCON_DEVCFG_ADCPD	(1<<2)
+#define EP93XX_SYSCON_DEVCFG_KEYS	(1<<1)
+#define EP93XX_SYSCON_DEVCFG_SHENA	(1<<0)
+#define EP93XX_SYSCON_KEYTCHCLKDIV	EP93XX_SYSCON_REG(0x90)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	(1<<31)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	(1<<16)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	(1<<15)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV	(1<<0)
 #define EP93XX_SYSCON_SWLOCK		EP93XX_SYSCON_REG(0xc0)
 
-#define EP93XX_WATCHDOG_BASE		(EP93XX_APB_VIRT_BASE + 0x00140000)
+#define EP93XX_WATCHDOG_BASE		EP93XX_APB_IOMEM(0x00140000)
 
 
 #endif
diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h
index 2866297..349fa7c 100644
--- a/arch/arm/mach-ep93xx/include/mach/hardware.h
+++ b/arch/arm/mach-ep93xx/include/mach/hardware.h
@@ -4,12 +4,23 @@
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
-#include "ep93xx-regs.h"
+#include <mach/ep93xx-regs.h>
+#include <mach/platform.h>
 
 #define pcibios_assign_all_busses()	0
 
-#include "platform.h"
+/*
+ * The EP93xx has two external crystal oscillators.  To generate the
+ * required high-frequency clocks, the processor uses two phase-locked-
+ * loops (PLLs) to multiply the incoming external clock signal to much
+ * higher frequencies that are then divided down by programmable dividers
+ * to produce the needed clocks.  The PLLs operate independently of one
+ * another.
+ */
+#define EP93XX_EXT_CLK_RATE	14745600
+#define EP93XX_EXT_RTC_RATE	32768
 
-#include "ts72xx.h"
+#define EP93XX_KEYTCHCLK_DIV4	(EP93XX_EXT_CLK_RATE / 4)
+#define EP93XX_KEYTCHCLK_DIV16	(EP93XX_EXT_CLK_RATE / 16)
 
 #endif
diff --git a/arch/arm/mach-ep93xx/include/mach/io.h b/arch/arm/mach-ep93xx/include/mach/io.h
index fd5f081..cebcc1c 100644
--- a/arch/arm/mach-ep93xx/include/mach/io.h
+++ b/arch/arm/mach-ep93xx/include/mach/io.h
@@ -1,8 +1,21 @@
 /*
  * arch/arm/mach-ep93xx/include/mach/io.h
  */
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_IO_H
 
 #define IO_SPACE_LIMIT		0xffffffff
 
-#define __io(p)		__typesafe_io(p)
-#define __mem_pci(p)	(p)
+#define __io(p)			__typesafe_io(p)
+#define __mem_pci(p)		(p)
+
+/*
+ * A typesafe __io() variation for variable initialisers
+ */
+#ifdef __ASSEMBLER__
+#define IOMEM(p)		p
+#else
+#define IOMEM(p)		((void __iomem __force *)(p))
+#endif
+
+#endif /* __ASM_MACH_IO_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 05f0f4f..5f5fa65 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -5,6 +5,7 @@
 #ifndef __ASSEMBLY__
 
 struct i2c_board_info;
+struct platform_device;
 
 struct ep93xx_eth_data
 {
@@ -15,8 +16,27 @@ struct ep93xx_eth_data
 void ep93xx_map_io(void);
 void ep93xx_init_irq(void);
 void ep93xx_init_time(unsigned long);
+
+/* EP93xx System Controller software locked register write */
+void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
+
+static inline void ep93xx_devcfg_set_bits(unsigned int bits)
+{
+	ep93xx_devcfg_set_clear(bits, 0x00);
+}
+
+static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
+{
+	ep93xx_devcfg_set_clear(0x00, bits);
+}
+
 void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
 void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
+void ep93xx_register_pwm(int pwm0, int pwm1);
+int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
+void ep93xx_pwm_release_gpio(struct platform_device *pdev);
+
 void ep93xx_init_devices(void);
 extern struct sys_timer ep93xx_timer;
 
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h
index ed8f35e..6d661fe 100644
--- a/arch/arm/mach-ep93xx/include/mach/system.h
+++ b/arch/arm/mach-ep93xx/include/mach/system.h
@@ -11,15 +11,13 @@ static inline void arch_idle(void)
 
 static inline void arch_reset(char mode, const char *cmd)
 {
-	u32 devicecfg;
-
 	local_irq_disable();
 
-	devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
-	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-	__raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG);
-	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-	__raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG);
+	/*
+	 * Set then clear the SWRST bit to initiate a software reset
+	 */
+	ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST);
+	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST);
 
 	while (1)
 		;
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
index 4117344..3bd934e 100644
--- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -67,7 +67,6 @@
 
 
 #ifndef __ASSEMBLY__
-#include <linux/io.h>
 
 static inline int board_is_ts7200(void)
 {
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index 15d6815..0a313e8 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -9,21 +9,16 @@
  * published by the Free Software Foundation.
  */
 
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/mm.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
 #include <linux/mtd/physmap.h>
 
 #include <mach/hardware.h>
 
-#include <asm/mach/arch.h>
 #include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
 
 static struct ep93xx_eth_data micro9_eth_data = {
 	.phy_id		= 0x1f,
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index aaf1371..259f782 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -12,19 +12,18 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <linux/m48t86.h>
 #include <linux/io.h>
-#include <linux/i2c.h>
+#include <linux/m48t86.h>
+#include <linux/mtd/physmap.h>
+
 #include <mach/hardware.h>
+#include <mach/ts72xx.h>
+
 #include <asm/mach-types.h>
-#include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
 
 static struct map_desc ts72xx_io_desc[] __initdata = {
 	{
diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h
index 1251319..d795642 100644
--- a/arch/arm/mach-integrator/include/mach/hardware.h
+++ b/arch/arm/mach-integrator/include/mach/hardware.h
@@ -36,8 +36,12 @@
 #define PCIO_BASE		PCI_IO_VADDR
 #define PCIMEM_BASE		PCI_MEMORY_VADDR
 
+#ifdef CONFIG_MMU
 /* macro to get at IO space when running virtually */
 #define IO_ADDRESS(x) (((x) >> 4) + IO_BASE) 
+#else
+#define IO_ADDRESS(x) (x)
+#endif
 
 #define pcibios_assign_all_busses()	1
 
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 4ac0405..2a318eb 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -49,14 +49,14 @@
 
 #define INTCP_PA_CLCD_BASE		0xc0000000
 
-#define INTCP_VA_CIC_BASE		0xf1000040
-#define INTCP_VA_PIC_BASE		0xf1400000
-#define INTCP_VA_SIC_BASE		0xfca00000
+#define INTCP_VA_CIC_BASE		IO_ADDRESS(INTEGRATOR_HDR_BASE) + 0x40
+#define INTCP_VA_PIC_BASE		IO_ADDRESS(INTEGRATOR_IC_BASE)
+#define INTCP_VA_SIC_BASE		IO_ADDRESS(0xca000000)
 
 #define INTCP_PA_ETH_BASE		0xc8000000
 #define INTCP_ETH_SIZE			0x10
 
-#define INTCP_VA_CTRL_BASE		0xfcb00000
+#define INTCP_VA_CTRL_BASE		IO_ADDRESS(0xcb000000)
 #define INTCP_FLASHPROG			0x04
 #define CINTEGRATOR_FLASHPROG_FLVPPEN	(1 << 0)
 #define CINTEGRATOR_FLASHPROG_FLWREN	(1 << 1)
@@ -121,12 +121,12 @@ static struct map_desc intcp_io_desc[] __initdata = {
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= 0xfca00000,
+		.virtual	= IO_ADDRESS(0xca000000),
 		.pfn		= __phys_to_pfn(0xca000000),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
 	}, {
-		.virtual	= 0xfcb00000,
+		.virtual	= IO_ADDRESS(0xcb000000),
 		.pfn		= __phys_to_pfn(0xcb000000),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE
@@ -394,8 +394,8 @@ static struct platform_device *intcp_devs[] __initdata = {
  */
 static unsigned int mmc_status(struct device *dev)
 {
-	unsigned int status = readl(0xfca00004);
-	writel(8, 0xfcb00008);
+	unsigned int status = readl(IO_ADDRESS(0xca000000) + 4);
+	writel(8, IO_ADDRESS(0xcb000000) + 8);
 
 	return status & 8;
 }
@@ -403,6 +403,8 @@ static unsigned int mmc_status(struct device *dev)
 static struct mmc_platform_data mmc_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.status		= mmc_status,
+	.gpio_wp	= -1,
+	.gpio_cd	= -1,
 };
 
 static struct amba_device mmc_device = {
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 1e93dfe..5083f03 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -416,6 +416,7 @@ static struct clocksource clocksource_ixp4xx = {
 };
 
 unsigned long ixp4xx_timer_freq = FREQ;
+EXPORT_SYMBOL(ixp4xx_timer_freq);
 static int __init ixp4xx_clocksource_init(void)
 {
 	clocksource_ixp4xx.mult =
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index 25100f7..0aca451 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -38,6 +38,12 @@ config MACH_TS219
 	  Say 'Y' here if you want your kernel to support the
 	  QNAP TS-119 and TS-219 Turbo NAS devices.
 
+config MACH_OPENRD_BASE
+	bool "Marvell OpenRD Base Board"
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  Marvell OpenRD Base Board.
+
 endmenu
 
 endif
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 9dd680e..80ab0ec 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_MACH_RD88F6281)		+= rd88f6281-setup.o
 obj-$(CONFIG_MACH_MV88F6281GTW_GE)	+= mv88f6281gtw_ge-setup.o
 obj-$(CONFIG_MACH_SHEEVAPLUG)		+= sheevaplug-setup.o
 obj-$(CONFIG_MACH_TS219)		+= ts219-setup.o
+obj-$(CONFIG_MACH_OPENRD_BASE)		+= openrd_base-setup.o
 
 obj-$(CONFIG_CPU_IDLE)			+= cpuidle.o
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 0f69198..0acb61f 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -838,7 +838,8 @@ int __init kirkwood_find_tclk(void)
 	u32 dev, rev;
 
 	kirkwood_pcie_id(&dev, &rev);
-	if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0)
+	if (dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 ||
+					rev == MV88F6281_REV_A1))
 		return 200000000;
 
 	return 166666667;
@@ -872,6 +873,8 @@ static char * __init kirkwood_id(void)
 			return "MV88F6281-Z0";
 		else if (rev == MV88F6281_REV_A0)
 			return "MV88F6281-A0";
+		else if (rev == MV88F6281_REV_A1)
+			return "MV88F6281-A1";
 		else
 			return "MV88F6281-Rev-Unsupported";
 	} else if (dev == MV88F6192_DEV_ID) {
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index 07af858..54c1327 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -101,6 +101,7 @@
 #define MV88F6281_DEV_ID	0x6281
 #define MV88F6281_REV_Z0	0
 #define MV88F6281_REV_A0	2
+#define MV88F6281_REV_A1	3
 
 #define MV88F6192_DEV_ID	0x6192
 #define MV88F6192_REV_Z0	0
diff --git a/arch/arm/mach-kirkwood/openrd_base-setup.c b/arch/arm/mach-kirkwood/openrd_base-setup.c
new file mode 100644
index 0000000..947dfb8
--- /dev/null
+++ b/arch/arm/mach-kirkwood/openrd_base-setup.c
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-kirkwood/openrd_base-setup.c
+ *
+ * Marvell OpenRD Base Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition openrd_base_nand_parts[] = {
+	{
+		.name = "u-boot",
+		.offset = 0,
+		.size = SZ_1M
+	}, {
+		.name = "uImage",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = SZ_4M
+	}, {
+		.name = "root",
+		.offset = MTDPART_OFS_NXTBLK,
+		.size = MTDPART_SIZ_FULL
+	},
+};
+
+static struct mv643xx_eth_platform_data openrd_base_ge00_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data openrd_base_sata_data = {
+	.n_ports	= 2,
+};
+
+static struct mvsdio_platform_data openrd_base_mvsdio_data = {
+	.gpio_card_detect = 29,	/* MPP29 used as SD card detect */
+};
+
+static unsigned int openrd_base_mpp_config[] __initdata = {
+	MPP29_GPIO,
+	0
+};
+
+static void __init openrd_base_init(void)
+{
+	/*
+	 * Basic setup. Needs to be called early.
+	 */
+	kirkwood_init();
+	kirkwood_mpp_conf(openrd_base_mpp_config);
+
+	kirkwood_uart0_init();
+	kirkwood_nand_init(ARRAY_AND_SIZE(openrd_base_nand_parts), 25);
+
+	kirkwood_ehci_init();
+
+	kirkwood_ge00_init(&openrd_base_ge00_data);
+	kirkwood_sata_init(&openrd_base_sata_data);
+	kirkwood_sdio_init(&openrd_base_mvsdio_data);
+}
+
+MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
+	/* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+	.phys_io	= KIRKWOOD_REGS_PHYS_BASE,
+	.io_pg_offst	= ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x00000100,
+	.init_machine	= openrd_base_init,
+	.map_io		= kirkwood_map_io,
+	.init_irq	= kirkwood_init_irq,
+	.timer		= &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c
index 0d0f306..d1b5885 100644
--- a/arch/arm/mach-mx1/clock.c
+++ b/arch/arm/mach-mx1/clock.c
@@ -18,11 +18,14 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/list.h>
 #include <linux/math64.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
+#include <asm/clkdev.h>
+
 #include <mach/clock.h>
 #include <mach/hardware.h>
 #include <mach/common.h>
@@ -94,7 +97,6 @@ static unsigned long clk16m_get_rate(struct clk *clk)
 }
 
 static struct clk clk16m = {
-	.name = "CLK16M",
 	.get_rate = clk16m_get_rate,
 	.enable = _clk_enable,
 	.enable_reg = CCM_CSCR,
@@ -111,7 +113,6 @@ static unsigned long clk32_get_rate(struct clk *clk)
 }
 
 static struct clk clk32 = {
-	.name = "CLK32",
 	.get_rate = clk32_get_rate,
 };
 
@@ -121,7 +122,6 @@ static unsigned long clk32_premult_get_rate(struct clk *clk)
 }
 
 static struct clk clk32_premult = {
-	.name = "CLK32_premultiplier",
 	.parent = &clk32,
 	.get_rate = clk32_premult_get_rate,
 };
@@ -156,7 +156,6 @@ static int prem_clk_set_parent(struct clk *clk, struct clk *parent)
 }
 
 static struct clk prem_clk = {
-	.name = "prem_clk",
 	.set_parent = prem_clk_set_parent,
 };
 
@@ -167,7 +166,6 @@ static unsigned long system_clk_get_rate(struct clk *clk)
 }
 
 static struct clk system_clk = {
-	.name = "system_clk",
 	.parent = &prem_clk,
 	.get_rate = system_clk_get_rate,
 };
@@ -179,7 +177,6 @@ static unsigned long mcu_clk_get_rate(struct clk *clk)
 }
 
 static struct clk mcu_clk = {
-	.name = "mcu_clk",
 	.parent = &clk32_premult,
 	.get_rate = mcu_clk_get_rate,
 };
@@ -195,7 +192,6 @@ static unsigned long fclk_get_rate(struct clk *clk)
 }
 
 static struct clk fclk = {
-	.name = "fclk",
 	.parent = &mcu_clk,
 	.get_rate = fclk_get_rate,
 };
@@ -238,7 +234,6 @@ static int hclk_set_rate(struct clk *clk, unsigned long rate)
 }
 
 static struct clk hclk = {
-	.name = "hclk",
 	.parent = &system_clk,
 	.get_rate = hclk_get_rate,
 	.round_rate = hclk_round_rate,
@@ -280,7 +275,6 @@ static int clk48m_set_rate(struct clk *clk, unsigned long rate)
 }
 
 static struct clk clk48m = {
-	.name = "CLK48M",
 	.parent = &system_clk,
 	.get_rate = clk48m_get_rate,
 	.round_rate = clk48m_round_rate,
@@ -400,21 +394,18 @@ static int perclk3_set_rate(struct clk *clk, unsigned long rate)
 
 static struct clk perclk[] = {
 	{
-		.name = "perclk",
 		.id = 0,
 		.parent = &system_clk,
 		.get_rate = perclk1_get_rate,
 		.round_rate = perclk1_round_rate,
 		.set_rate = perclk1_set_rate,
 	}, {
-		.name = "perclk",
 		.id = 1,
 		.parent = &system_clk,
 		.get_rate = perclk2_get_rate,
 		.round_rate = perclk2_round_rate,
 		.set_rate = perclk2_set_rate,
 	}, {
-		.name = "perclk",
 		.id = 2,
 		.parent = &system_clk,
 		.get_rate = perclk3_get_rate,
@@ -457,12 +448,10 @@ static int clko_set_parent(struct clk *clk, struct clk *parent)
 }
 
 static struct clk clko_clk = {
-	.name = "clko_clk",
 	.set_parent = clko_set_parent,
 };
 
 static struct clk dma_clk = {
-	.name = "dma",
 	.parent = &hclk,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -473,7 +462,6 @@ static struct clk dma_clk = {
 };
 
 static struct clk csi_clk = {
-	.name = "csi_clk",
 	.parent = &hclk,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -484,7 +472,6 @@ static struct clk csi_clk = {
 };
 
 static struct clk mma_clk = {
-	.name = "mma_clk",
 	.parent = &hclk,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -495,7 +482,6 @@ static struct clk mma_clk = {
 };
 
 static struct clk usbd_clk = {
-	.name = "usbd_clk",
 	.parent = &clk48m,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
@@ -506,99 +492,85 @@ static struct clk usbd_clk = {
 };
 
 static struct clk gpt_clk = {
-	.name = "gpt_clk",
 	.parent = &perclk[0],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk uart_clk = {
-	.name = "uart",
 	.parent = &perclk[0],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk i2c_clk = {
-	.name = "i2c_clk",
 	.parent = &hclk,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk spi_clk = {
-	.name = "spi_clk",
 	.parent = &perclk[1],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk sdhc_clk = {
-	.name = "sdhc_clk",
 	.parent = &perclk[1],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk lcdc_clk = {
-	.name = "lcdc_clk",
 	.parent = &perclk[1],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk mshc_clk = {
-	.name = "mshc_clk",
 	.parent = &hclk,
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk ssi_clk = {
-	.name = "ssi_clk",
 	.parent = &perclk[2],
 	.round_rate = _clk_parent_round_rate,
 	.set_rate = _clk_parent_set_rate,
 };
 
 static struct clk rtc_clk = {
-	.name = "rtc_clk",
 	.parent = &clk32,
 };
 
-static struct clk *mxc_clks[] = {
-	&clk16m,
-	&clk32,
-	&clk32_premult,
-	&prem_clk,
-	&system_clk,
-	&mcu_clk,
-	&fclk,
-	&hclk,
-	&clk48m,
-	&perclk[0],
-	&perclk[1],
-	&perclk[2],
-	&clko_clk,
-	&dma_clk,
-	&csi_clk,
-	&mma_clk,
-	&usbd_clk,
-	&gpt_clk,
-	&uart_clk,
-	&i2c_clk,
-	&spi_clk,
-	&sdhc_clk,
-	&lcdc_clk,
-	&mshc_clk,
-	&ssi_clk,
-	&rtc_clk,
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+static struct clk_lookup lookups[] __initdata = {
+	_REGISTER_CLOCK(NULL, "dma", dma_clk)
+	_REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk)
+	_REGISTER_CLOCK(NULL, "mma", mma_clk)
+	_REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
+	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+	_REGISTER_CLOCK("spi_imx.0", NULL, spi_clk)
+	_REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
+	_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+	_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
+	_REGISTER_CLOCK(NULL, "ssi", ssi_clk)
+	_REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk)
 };
 
 int __init mx1_clocks_init(unsigned long fref)
 {
-	struct clk **clkp;
 	unsigned int reg;
+	int i;
 
 	/* disable clocks we are able to */
 	__raw_writel(0, SCM_GCCR);
@@ -620,13 +592,13 @@ int __init mx1_clocks_init(unsigned long fref)
 	reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
 	clko_clk.parent = (struct clk *)clko_clocks[reg];
 
-	for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
-		clk_register(*clkp);
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
 
 	clk_enable(&hclk);
 	clk_enable(&fclk);
 
-	mxc_timer_init(&gpt_clk);
+	mxc_timer_init(&gpt_clk, IO_ADDRESS(TIM1_BASE_ADDR), TIM1_INT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-mx1/devices.c b/arch/arm/mach-mx1/devices.c
index 76d1ffb..b6be29d 100644
--- a/arch/arm/mach-mx1/devices.c
+++ b/arch/arm/mach-mx1/devices.c
@@ -29,12 +29,11 @@
 #include "devices.h"
 
 static struct resource imx_csi_resources[] = {
-	[0] = {
+	{
 		.start  = 0x00224000,
 		.end    = 0x00224010,
 		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start  = CSI_INT,
 		.end    = CSI_INT,
 		.flags  = IORESOURCE_IRQ,
@@ -55,12 +54,11 @@ struct platform_device imx_csi_device = {
 };
 
 static struct resource imx_i2c_resources[] = {
-	[0] = {
+	{
 		.start  = 0x00217000,
 		.end    = 0x00217010,
 		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start  = I2C_INT,
 		.end    = I2C_INT,
 		.flags  = IORESOURCE_IRQ,
@@ -75,22 +73,19 @@ struct platform_device imx_i2c_device = {
 };
 
 static struct resource imx_uart1_resources[] = {
-	[0] = {
+	{
 		.start	= UART1_BASE_ADDR,
 		.end	= UART1_BASE_ADDR + 0xD0,
 		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start	= UART1_MINT_RX,
 		.end	= UART1_MINT_RX,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
+	}, {
 		.start	= UART1_MINT_TX,
 		.end	= UART1_MINT_TX,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
+	}, {
 		.start	= UART1_MINT_RTS,
 		.end	= UART1_MINT_RTS,
 		.flags	= IORESOURCE_IRQ,
@@ -105,22 +100,19 @@ struct platform_device imx_uart1_device = {
 };
 
 static struct resource imx_uart2_resources[] = {
-	[0] = {
+	{
 		.start	= UART2_BASE_ADDR,
 		.end	= UART2_BASE_ADDR + 0xD0,
 		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start	= UART2_MINT_RX,
 		.end	= UART2_MINT_RX,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
+	}, {
 		.start	= UART2_MINT_TX,
 		.end	= UART2_MINT_TX,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
+	}, {
 		.start	= UART2_MINT_RTS,
 		.end	= UART2_MINT_RTS,
 		.flags	= IORESOURCE_IRQ,
@@ -135,17 +127,15 @@ struct platform_device imx_uart2_device = {
 };
 
 static struct resource imx_rtc_resources[] = {
-	[0] = {
+	{
 		.start  = 0x00204000,
 		.end    = 0x00204024,
 		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start  = RTC_INT,
 		.end    = RTC_INT,
 		.flags  = IORESOURCE_IRQ,
-	},
-	[2] = {
+	}, {
 		.start  = RTC_SAMINT,
 		.end    = RTC_SAMINT,
 		.flags  = IORESOURCE_IRQ,
@@ -160,12 +150,11 @@ struct platform_device imx_rtc_device = {
 };
 
 static struct resource imx_wdt_resources[] = {
-	[0] = {
+	{
 		.start  = 0x00201000,
 		.end    = 0x00201008,
 		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start  = WDT_INT,
 		.end    = WDT_INT,
 		.flags  = IORESOURCE_IRQ,
@@ -180,42 +169,35 @@ struct platform_device imx_wdt_device = {
 };
 
 static struct resource imx_usb_resources[] = {
-	[0] = {
+	{
 		.start	= 0x00212000,
 		.end	= 0x00212148,
 		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start	= USBD_INT0,
 		.end	= USBD_INT0,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[2] = {
+	}, {
 		.start	= USBD_INT1,
 		.end	= USBD_INT1,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[3] = {
+	}, {
 		.start	= USBD_INT2,
 		.end	= USBD_INT2,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[4] = {
+	}, {
 		.start	= USBD_INT3,
 		.end	= USBD_INT3,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[5] = {
+	}, {
 		.start	= USBD_INT4,
 		.end	= USBD_INT4,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[6] = {
+	}, {
 		.start	= USBD_INT5,
 		.end	= USBD_INT5,
 		.flags	= IORESOURCE_IRQ,
-	},
-	[7] = {
+	}, {
 		.start	= USBD_INT6,
 		.end	= USBD_INT6,
 		.flags	= IORESOURCE_IRQ,
@@ -231,29 +213,26 @@ struct platform_device imx_usb_device = {
 
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
-	[0] = {
+	{
 		.chip.label = "gpio-0",
 		.base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR),
 		.irq = GPIO_INT_PORTA,
-		.virtual_irq_start = MXC_GPIO_IRQ_START
-	},
-	[1] = {
+		.virtual_irq_start = MXC_GPIO_IRQ_START,
+	}, {
 		.chip.label = "gpio-1",
 		.base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
 		.irq = GPIO_INT_PORTB,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32
-	},
-	[2] = {
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
+	}, {
 		.chip.label = "gpio-2",
 		.base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
 		.irq = GPIO_INT_PORTC,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 64
-	},
-	[3] = {
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
+	}, {
 		.chip.label = "gpio-3",
 		.base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
 		.irq = GPIO_INT_PORTD,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 96
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
 	}
 };
 
diff --git a/arch/arm/mach-mx1/generic.c b/arch/arm/mach-mx1/generic.c
index 7622c9b..7f9fc10 100644
--- a/arch/arm/mach-mx1/generic.c
+++ b/arch/arm/mach-mx1/generic.c
@@ -41,6 +41,13 @@ static struct map_desc imx_io_desc[] __initdata = {
 void __init mx1_map_io(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX1);
+	mxc_arch_reset_init(IO_ADDRESS(WDT_BASE_ADDR));
 
 	iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
 }
+
+void __init mx1_init_irq(void)
+{
+	mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
+}
+
diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c
index e5b0c0a..30f04e5 100644
--- a/arch/arm/mach-mx1/mx1ads.c
+++ b/arch/arm/mach-mx1/mx1ads.c
@@ -104,12 +104,10 @@ static struct imxi2c_platform_data mx1ads_i2c_data = {
 
 static struct i2c_board_info mx1ads_i2c_devices[] = {
 	{
-		I2C_BOARD_INFO("pcf857x", 0x22),
-		.type = "pcf8575",
+		I2C_BOARD_INFO("pcf8575", 0x22),
 		.platform_data = &pcf857x_data[0],
 	}, {
-		I2C_BOARD_INFO("pcf857x", 0x24),
-		.type = "pcf8575",
+		I2C_BOARD_INFO("pcf8575", 0x24),
 		.platform_data = &pcf857x_data[1],
 	},
 };
@@ -151,7 +149,7 @@ MACHINE_START(MX1ADS, "Freescale MX1ADS")
 	.io_pg_offst	= (IMX_IO_BASE >> 18) & 0xfffc,
 	.boot_params	= PHYS_OFFSET + 0x100,
 	.map_io		= mx1_map_io,
-	.init_irq	= mxc_init_irq,
+	.init_irq	= mx1_init_irq,
 	.timer		= &mx1ads_timer,
 	.init_machine	= mx1ads_init,
 MACHINE_END
@@ -161,7 +159,7 @@ MACHINE_START(MXLADS, "Freescale MXLADS")
 	.io_pg_offst	= (IMX_IO_BASE >> 18) & 0xfffc,
 	.boot_params	= PHYS_OFFSET + 0x100,
 	.map_io		= mx1_map_io,
-	.init_irq	= mxc_init_irq,
+	.init_irq	= mx1_init_irq,
 	.timer		= &mx1ads_timer,
 	.init_machine	= mx1ads_init,
 MACHINE_END
diff --git a/arch/arm/mach-mx1/scb9328.c b/arch/arm/mach-mx1/scb9328.c
index 20e0b5b..325d98d 100644
--- a/arch/arm/mach-mx1/scb9328.c
+++ b/arch/arm/mach-mx1/scb9328.c
@@ -68,22 +68,20 @@ static struct dm9000_plat_data dm9000_platdata = {
  * to gain access to address latch registers and the data path.
  */
 static struct resource dm9000x_resources[] = {
-	[0] = {
+	{
 		.name	= "address area",
 		.start	= IMX_CS5_PHYS,
 		.end	= IMX_CS5_PHYS + 1,
-		.flags	= IORESOURCE_MEM	/* address access */
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,	/* address access */
+	}, {
 		.name	= "data area",
 		.start	= IMX_CS5_PHYS + 4,
 		.end	= IMX_CS5_PHYS + 5,
-		.flags	= IORESOURCE_MEM	/* data access */
-	},
-	[2] = {
+		.flags	= IORESOURCE_MEM,	/* data access */
+	}, {
 		.start	= IRQ_GPIOC(3),
 		.end	= IRQ_GPIOC(3),
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL
+		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 	},
 };
 
@@ -154,7 +152,7 @@ MACHINE_START(SCB9328, "Synertronixx scb9328")
 	.io_pg_offst	= ((0xe0200000) >> 18) & 0xfffc,
 	.boot_params	= 0x08000100,
 	.map_io		= mx1_map_io,
-	.init_irq	= mxc_init_irq,
+	.init_irq	= mx1_init_irq,
 	.timer		= &scb9328_timer,
 	.init_machine	= scb9328_init,
 MACHINE_END
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig
index c77da58..c8a2eac 100644
--- a/arch/arm/mach-mx2/Kconfig
+++ b/arch/arm/mach-mx2/Kconfig
@@ -53,6 +53,34 @@ config MACH_PCM970_BASEBOARD
 
 endchoice
 
+config MACH_EUKREA_CPUIMX27
+	bool "Eukrea CPUIMX27 module"
+	depends on MACH_MX27
+	help
+	  Include support for Eukrea CPUIMX27 platform. This includes
+	  specific configurations for the module and its peripherals.
+
+config MACH_EUKREA_CPUIMX27_USESDHC2
+	bool "CPUIMX27 integrates SDHC2 module"
+	depends on MACH_EUKREA_CPUIMX27
+	help
+	  This adds support for the internal SDHC2 used on CPUIMX27 used
+	  for wifi or eMMC.
+
+choice
+	prompt "Baseboard"
+	depends on MACH_EUKREA_CPUIMX27
+	default MACH_EUKREA_MBIMX27_BASEBOARD
+
+config MACH_EUKREA_MBIMX27_BASEBOARD
+	prompt "Eukrea MBIMX27 development board"
+	bool
+	help
+	  This adds board specific devices that can be found on Eukrea's
+	  MBIMX27 evaluation board.
+
+endchoice
+
 config MACH_MX27_3DS
 	bool "MX27PDK platform"
 	depends on MACH_MX27
@@ -67,4 +95,11 @@ config MACH_MX27LITE
 	  Include support for MX27 LITEKIT platform. This includes specific
 	  configurations for the board and its peripherals.
 
+config MACH_PCA100
+	bool "Phytec phyCARD-s (pca100)"
+	depends on MACH_MX27
+	help
+	  Include support for phyCARD-s (aka pca100) platform. This
+	  includes specific configurations for the module and its peripherals.
+
 endif
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile
index b9b1cca..19560f0 100644
--- a/arch/arm/mach-mx2/Makefile
+++ b/arch/arm/mach-mx2/Makefile
@@ -17,4 +17,7 @@ obj-$(CONFIG_MACH_PCM038) += pcm038.o
 obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
 obj-$(CONFIG_MACH_MX27_3DS) += mx27pdk.o
 obj-$(CONFIG_MACH_MX27LITE) += mx27lite.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27.o
+obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
+obj-$(CONFIG_MACH_PCA100) += pca100.o
 
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c
index 0850fb8..eede798 100644
--- a/arch/arm/mach-mx2/clock_imx21.c
+++ b/arch/arm/mach-mx2/clock_imx21.c
@@ -1004,6 +1004,6 @@ int __init mx21_clocks_init(unsigned long lref, unsigned long href)
 	clk_enable(&uart_clk[0]);
 #endif
 
-	mxc_timer_init(&gpt_clk[0]);
+	mxc_timer_init(&gpt_clk[0], IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
 	return 0;
 }
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index 2c97144..4089951 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -643,7 +643,14 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
 	_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
 	_REGISTER_CLOCK(NULL, "csi", csi_clk)
-	_REGISTER_CLOCK(NULL, "usb", usb_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
 	_REGISTER_CLOCK(NULL, "ssi1", ssi1_clk)
 	_REGISTER_CLOCK(NULL, "ssi2", ssi2_clk)
 	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
@@ -748,7 +755,7 @@ int __init mx27_clocks_init(unsigned long fref)
 	clk_enable(&uart1_clk);
 #endif
 
-	mxc_timer_init(&gpt1_clk);
+	mxc_timer_init(&gpt1_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT1);
 
 	return 0;
 }
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c
index a0f1b36..50199af 100644
--- a/arch/arm/mach-mx2/devices.c
+++ b/arch/arm/mach-mx2/devices.c
@@ -40,45 +40,87 @@
 #include "devices.h"
 
 /*
- * Resource definition for the MXC IrDA
+ * SPI master controller
+ *
+ * - i.MX1: 2 channel (slighly different register setting)
+ * - i.MX21: 2 channel
+ * - i.MX27: 3 channel
  */
-static struct resource mxc_irda_resources[] = {
-	[0] = {
-		.start   = UART3_BASE_ADDR,
-		.end     = UART3_BASE_ADDR + SZ_4K - 1,
-		.flags   = IORESOURCE_MEM,
+static struct resource mxc_spi_resources0[] = {
+	{
+	       .start = CSPI1_BASE_ADDR,
+	       .end = CSPI1_BASE_ADDR + SZ_4K - 1,
+	       .flags = IORESOURCE_MEM,
+	}, {
+	       .start = MXC_INT_CSPI1,
+	       .end = MXC_INT_CSPI1,
+	       .flags = IORESOURCE_IRQ,
 	},
-	[1] = {
-		.start   = MXC_INT_UART3,
-		.end     = MXC_INT_UART3,
-		.flags   = IORESOURCE_IRQ,
+};
+
+static struct resource mxc_spi_resources1[] = {
+	{
+		.start = CSPI2_BASE_ADDR,
+		.end = CSPI2_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_CSPI2,
+		.end = MXC_INT_CSPI2,
+		.flags = IORESOURCE_IRQ,
 	},
 };
 
-/* Platform Data for MXC IrDA */
-struct platform_device mxc_irda_device = {
-	.name = "mxc_irda",
+#ifdef CONFIG_MACH_MX27
+static struct resource mxc_spi_resources2[] = {
+	{
+		.start = CSPI3_BASE_ADDR,
+		.end = CSPI3_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_CSPI3,
+		.end = MXC_INT_CSPI3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+#endif
+
+struct platform_device mxc_spi_device0 = {
+	.name = "spi_imx",
 	.id = 0,
-	.num_resources = ARRAY_SIZE(mxc_irda_resources),
-	.resource = mxc_irda_resources,
+	.num_resources = ARRAY_SIZE(mxc_spi_resources0),
+	.resource = mxc_spi_resources0,
+};
+
+struct platform_device mxc_spi_device1 = {
+	.name = "spi_imx",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_spi_resources1),
+	.resource = mxc_spi_resources1,
+};
+
+#ifdef CONFIG_MACH_MX27
+struct platform_device mxc_spi_device2 = {
+	.name = "spi_imx",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(mxc_spi_resources2),
+	.resource = mxc_spi_resources2,
 };
+#endif
 
 /*
  * General Purpose Timer
- * - i.MX1: 2 timer (slighly different register handling)
- * - i.MX21: 3 timer
- * - i.MX27: 6 timer
+ * - i.MX21: 3 timers
+ * - i.MX27: 6 timers
  */
 
 /* We use gpt0 as system timer, so do not add a device for this one */
 
 static struct resource timer1_resources[] = {
-	[0] = {
+	{
 		.start	= GPT2_BASE_ADDR,
 		.end	= GPT2_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start   = MXC_INT_GPT2,
 		.end     = MXC_INT_GPT2,
 		.flags   = IORESOURCE_IRQ,
@@ -89,16 +131,15 @@ struct platform_device mxc_gpt1 = {
 	.name = "imx_gpt",
 	.id = 1,
 	.num_resources = ARRAY_SIZE(timer1_resources),
-	.resource = timer1_resources
+	.resource = timer1_resources,
 };
 
 static struct resource timer2_resources[] = {
-	[0] = {
+	{
 		.start	= GPT3_BASE_ADDR,
 		.end	= GPT3_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start   = MXC_INT_GPT3,
 		.end     = MXC_INT_GPT3,
 		.flags   = IORESOURCE_IRQ,
@@ -109,17 +150,16 @@ struct platform_device mxc_gpt2 = {
 	.name = "imx_gpt",
 	.id = 2,
 	.num_resources = ARRAY_SIZE(timer2_resources),
-	.resource = timer2_resources
+	.resource = timer2_resources,
 };
 
 #ifdef CONFIG_MACH_MX27
 static struct resource timer3_resources[] = {
-	[0] = {
+	{
 		.start	= GPT4_BASE_ADDR,
 		.end	= GPT4_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start   = MXC_INT_GPT4,
 		.end     = MXC_INT_GPT4,
 		.flags   = IORESOURCE_IRQ,
@@ -130,16 +170,15 @@ struct platform_device mxc_gpt3 = {
 	.name = "imx_gpt",
 	.id = 3,
 	.num_resources = ARRAY_SIZE(timer3_resources),
-	.resource = timer3_resources
+	.resource = timer3_resources,
 };
 
 static struct resource timer4_resources[] = {
-	[0] = {
+	{
 		.start	= GPT5_BASE_ADDR,
 		.end	= GPT5_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start   = MXC_INT_GPT5,
 		.end     = MXC_INT_GPT5,
 		.flags   = IORESOURCE_IRQ,
@@ -150,16 +189,15 @@ struct platform_device mxc_gpt4 = {
 	.name = "imx_gpt",
 	.id = 4,
 	.num_resources = ARRAY_SIZE(timer4_resources),
-	.resource = timer4_resources
+	.resource = timer4_resources,
 };
 
 static struct resource timer5_resources[] = {
-	[0] = {
+	{
 		.start	= GPT6_BASE_ADDR,
 		.end	= GPT6_BASE_ADDR + 0x17,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start   = MXC_INT_GPT6,
 		.end     = MXC_INT_GPT6,
 		.flags   = IORESOURCE_IRQ,
@@ -170,7 +208,7 @@ struct platform_device mxc_gpt5 = {
 	.name = "imx_gpt",
 	.id = 5,
 	.num_resources = ARRAY_SIZE(timer5_resources),
-	.resource = timer5_resources
+	.resource = timer5_resources,
 };
 #endif
 
@@ -214,11 +252,11 @@ static struct resource mxc_nand_resources[] = {
 	{
 		.start	= NFC_BASE_ADDR,
 		.end	= NFC_BASE_ADDR + 0xfff,
-		.flags	= IORESOURCE_MEM
+		.flags	= IORESOURCE_MEM,
 	}, {
 		.start	= MXC_INT_NANDFC,
 		.end	= MXC_INT_NANDFC,
-		.flags	= IORESOURCE_IRQ
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -240,8 +278,7 @@ static struct resource mxc_fb[] = {
 		.start = LCDC_BASE_ADDR,
 		.end   = LCDC_BASE_ADDR + 0xFFF,
 		.flags = IORESOURCE_MEM,
-	},
-	{
+	}, {
 		.start = MXC_INT_LCDC,
 		.end   = MXC_INT_LCDC,
 		.flags = IORESOURCE_IRQ,
@@ -264,11 +301,11 @@ static struct resource mxc_fec_resources[] = {
 	{
 		.start	= FEC_BASE_ADDR,
 		.end	= FEC_BASE_ADDR + 0xfff,
-		.flags	= IORESOURCE_MEM
+		.flags	= IORESOURCE_MEM,
 	}, {
 		.start	= MXC_INT_FEC,
 		.end	= MXC_INT_FEC,
-		.flags	= IORESOURCE_IRQ
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -281,15 +318,14 @@ struct platform_device mxc_fec_device = {
 #endif
 
 static struct resource mxc_i2c_1_resources[] = {
-	[0] = {
+	{
 		.start	= I2C_BASE_ADDR,
 		.end	= I2C_BASE_ADDR + 0x0fff,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start	= MXC_INT_I2C,
 		.end	= MXC_INT_I2C,
-		.flags	= IORESOURCE_IRQ
+		.flags	= IORESOURCE_IRQ,
 	}
 };
 
@@ -297,20 +333,19 @@ struct platform_device mxc_i2c_device0 = {
 	.name = "imx-i2c",
 	.id = 0,
 	.num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
-	.resource = mxc_i2c_1_resources
+	.resource = mxc_i2c_1_resources,
 };
 
 #ifdef CONFIG_MACH_MX27
 static struct resource mxc_i2c_2_resources[] = {
-	[0] = {
+	{
 		.start	= I2C2_BASE_ADDR,
 		.end	= I2C2_BASE_ADDR + 0x0fff,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start	= MXC_INT_I2C2,
 		.end	= MXC_INT_I2C2,
-		.flags	= IORESOURCE_IRQ
+		.flags	= IORESOURCE_IRQ,
 	}
 };
 
@@ -318,17 +353,16 @@ struct platform_device mxc_i2c_device1 = {
 	.name = "imx-i2c",
 	.id = 1,
 	.num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
-	.resource = mxc_i2c_2_resources
+	.resource = mxc_i2c_2_resources,
 };
 #endif
 
 static struct resource mxc_pwm_resources[] = {
-	[0] = {
+	{
 		.start	= PWM_BASE_ADDR,
 		.end	= PWM_BASE_ADDR + 0x0fff,
-		.flags	= IORESOURCE_MEM
-	},
-	[1] = {
+		.flags	= IORESOURCE_MEM,
+	}, {
 		.start   = MXC_INT_PWM,
 		.end     = MXC_INT_PWM,
 		.flags   = IORESOURCE_IRQ,
@@ -339,28 +373,26 @@ struct platform_device mxc_pwm_device = {
 	.name = "mxc_pwm",
 	.id = 0,
 	.num_resources = ARRAY_SIZE(mxc_pwm_resources),
-	.resource = mxc_pwm_resources
+	.resource = mxc_pwm_resources,
 };
 
 /*
  * Resource definition for the MXC SDHC
  */
 static struct resource mxc_sdhc1_resources[] = {
-	[0] = {
-			.start = SDHC1_BASE_ADDR,
-			.end   = SDHC1_BASE_ADDR + SZ_4K - 1,
-			.flags = IORESOURCE_MEM,
-			},
-	[1] = {
-			.start = MXC_INT_SDHC1,
-			.end   = MXC_INT_SDHC1,
-			.flags = IORESOURCE_IRQ,
-			},
-	[2] = {
-			.start  = DMA_REQ_SDHC1,
-			.end    = DMA_REQ_SDHC1,
-			.flags  = IORESOURCE_DMA
-		},
+	{
+		.start = SDHC1_BASE_ADDR,
+		.end   = SDHC1_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_SDHC1,
+		.end   = MXC_INT_SDHC1,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start  = DMA_REQ_SDHC1,
+		.end    = DMA_REQ_SDHC1,
+		.flags  = IORESOURCE_DMA,
+	},
 };
 
 static u64 mxc_sdhc1_dmamask = 0xffffffffUL;
@@ -377,21 +409,19 @@ struct platform_device mxc_sdhc_device0 = {
 };
 
 static struct resource mxc_sdhc2_resources[] = {
-	[0] = {
-			.start = SDHC2_BASE_ADDR,
-			.end   = SDHC2_BASE_ADDR + SZ_4K - 1,
-			.flags = IORESOURCE_MEM,
-			},
-	[1] = {
-			.start = MXC_INT_SDHC2,
-			.end   = MXC_INT_SDHC2,
-			.flags = IORESOURCE_IRQ,
-			},
-	[2] = {
-			.start  = DMA_REQ_SDHC2,
-			.end    = DMA_REQ_SDHC2,
-			.flags  = IORESOURCE_DMA
-		},
+	{
+		.start = SDHC2_BASE_ADDR,
+		.end   = SDHC2_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_SDHC2,
+		.end   = MXC_INT_SDHC2,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start  = DMA_REQ_SDHC2,
+		.end    = DMA_REQ_SDHC2,
+		.flags  = IORESOURCE_DMA,
+	},
 };
 
 static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
@@ -407,35 +437,123 @@ struct platform_device mxc_sdhc_device1 = {
        .resource       = mxc_sdhc2_resources,
 };
 
+#ifdef CONFIG_MACH_MX27
+static struct resource otg_resources[] = {
+	{
+		.start	= OTG_BASE_ADDR,
+		.end	= OTG_BASE_ADDR + 0x1ff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= MXC_INT_USB3,
+		.end	= MXC_INT_USB3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 otg_dmamask = 0xffffffffUL;
+
+/* OTG gadget device */
+struct platform_device mxc_otg_udc_device = {
+	.name		= "fsl-usb2-udc",
+	.id		= -1,
+	.dev		= {
+		.dma_mask		= &otg_dmamask,
+		.coherent_dma_mask	= 0xffffffffUL,
+	},
+	.resource	= otg_resources,
+	.num_resources	= ARRAY_SIZE(otg_resources),
+};
+
+/* OTG host */
+struct platform_device mxc_otg_host = {
+	.name = "mxc-ehci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &otg_dmamask,
+	},
+	.resource = otg_resources,
+	.num_resources = ARRAY_SIZE(otg_resources),
+};
+
+/* USB host 1 */
+
+static u64 usbh1_dmamask = 0xffffffffUL;
+
+static struct resource mxc_usbh1_resources[] = {
+	{
+		.start = OTG_BASE_ADDR + 0x200,
+		.end = OTG_BASE_ADDR + 0x3ff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_USB1,
+		.end = MXC_INT_USB1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_usbh1 = {
+	.name = "mxc-ehci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &usbh1_dmamask,
+	},
+	.resource = mxc_usbh1_resources,
+	.num_resources = ARRAY_SIZE(mxc_usbh1_resources),
+};
+
+/* USB host 2 */
+static u64 usbh2_dmamask = 0xffffffffUL;
+
+static struct resource mxc_usbh2_resources[] = {
+	{
+		.start = OTG_BASE_ADDR + 0x400,
+		.end = OTG_BASE_ADDR + 0x5ff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_USB2,
+		.end = MXC_INT_USB2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_usbh2 = {
+	.name = "mxc-ehci",
+	.id = 2,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &usbh2_dmamask,
+	},
+	.resource = mxc_usbh2_resources,
+	.num_resources = ARRAY_SIZE(mxc_usbh2_resources),
+};
+#endif
+
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
-	[0] = {
+	{
 		.chip.label = "gpio-0",
 		.irq = MXC_INT_GPIO,
 		.base = IO_ADDRESS(GPIO_BASE_ADDR),
 		.virtual_irq_start = MXC_GPIO_IRQ_START,
-	},
-	[1] = {
+	}, {
 		.chip.label = "gpio-1",
 		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
-	},
-	[2] = {
+	}, {
 		.chip.label = "gpio-2",
 		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
-	},
-	[3] = {
+	}, {
 		.chip.label = "gpio-3",
 		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
-	},
-	[4] = {
+	}, {
 		.chip.label = "gpio-4",
 		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 128,
-	},
-	[5] = {
+	}, {
 		.chip.label = "gpio-5",
 		.base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 160,
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h
index 049005b..d315406 100644
--- a/arch/arm/mach-mx2/devices.h
+++ b/arch/arm/mach-mx2/devices.h
@@ -4,7 +4,6 @@ extern struct platform_device mxc_gpt3;
 extern struct platform_device mxc_gpt4;
 extern struct platform_device mxc_gpt5;
 extern struct platform_device mxc_wdt;
-extern struct platform_device mxc_irda_device;
 extern struct platform_device mxc_uart_device0;
 extern struct platform_device mxc_uart_device1;
 extern struct platform_device mxc_uart_device2;
@@ -20,3 +19,11 @@ extern struct platform_device mxc_i2c_device0;
 extern struct platform_device mxc_i2c_device1;
 extern struct platform_device mxc_sdhc_device0;
 extern struct platform_device mxc_sdhc_device1;
+extern struct platform_device mxc_otg_udc_device;
+extern struct platform_device mxc_otg_host;
+extern struct platform_device mxc_usbh1;
+extern struct platform_device mxc_usbh2;
+extern struct platform_device mxc_spi_device0;
+extern struct platform_device mxc_spi_device1;
+extern struct platform_device mxc_spi_device2;
+
diff --git a/arch/arm/mach-mx2/eukrea_cpuimx27.c b/arch/arm/mach-mx2/eukrea_cpuimx27.c
new file mode 100644
index 0000000..7b18760
--- /dev/null
+++ b/arch/arm/mach-mx2/eukrea_cpuimx27.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm038.c which is :
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-eukrea_cpuimx27.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+#include <mach/iomux.h>
+#include <mach/imx-uart.h>
+#include <mach/mxc_nand.h>
+
+#include "devices.h"
+
+static int eukrea_cpuimx27_pins[] = {
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* UART4 */
+	PB26_AF_UART4_RTS,
+	PB28_AF_UART4_TXD,
+	PB29_AF_UART4_CTS,
+	PB31_AF_UART4_RXD,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* I2C1 */
+	PD17_PF_I2C_DATA,
+	PD18_PF_I2C_CLK,
+	/* SDHC2 */
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+	/* Quad UART's IRQ */
+	GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN,
+	GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN,
+	GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN,
+	GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN,
+#endif
+};
+
+static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
+	.width = 2,
+};
+
+static struct resource eukrea_cpuimx27_flash_resource = {
+	.start = 0xc0000000,
+	.end   = 0xc3ffffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
+	.name = "physmap-flash",
+	.id = 0,
+	.dev = {
+		.platform_data = &eukrea_cpuimx27_flash_data,
+	},
+	.num_resources = 1,
+	.resource = &eukrea_cpuimx27_flash_resource,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	}, {
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&eukrea_cpuimx27_nor_mtd_device,
+	&mxc_fec_device,
+};
+
+static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
+	.bitrate = 100000,
+};
+
+static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	},
+};
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+static struct plat_serial8250_port serial_platform_data[] = {
+	{
+		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x200000),
+		.irq = IRQ_GPIOB(23),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x400000),
+		.irq = IRQ_GPIOB(22),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x800000),
+		.irq = IRQ_GPIOB(27),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+		.mapbase = (unsigned long)(CS3_BASE_ADDR + 0x1000000),
+		.irq = IRQ_GPIOB(30),
+		.uartclk = 14745600,
+		.regshift = 1,
+		.iotype = UPIO_MEM,
+		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+	}, {
+	}
+};
+
+static struct platform_device serial_device = {
+	.name = "serial8250",
+	.id = 0,
+	.dev = {
+		.platform_data = serial_platform_data,
+	},
+};
+#endif
+
+static void __init eukrea_cpuimx27_init(void)
+{
+	mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
+		ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+
+	mxc_register_device(&mxc_nand_device, &eukrea_cpuimx27_nand_board_info);
+
+	i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
+				ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
+	/* SDHC2 can be used for Wifi */
+	mxc_register_device(&mxc_sdhc_device1, NULL);
+	/* in which case UART4 is also used for Bluetooth */
+	mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
+#endif
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+	platform_device_register(&serial_device);
+#endif
+
+#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
+	eukrea_mbimx27_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx27_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer eukrea_cpuimx27_timer = {
+	.init = eukrea_cpuimx27_timer_init,
+};
+
+MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
+	.phys_io        = AIPI_BASE_ADDR,
+	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = mx27_map_io,
+	.init_irq       = mx27_init_irq,
+	.init_machine   = eukrea_cpuimx27_init,
+	.timer          = &eukrea_cpuimx27_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
new file mode 100644
index 0000000..7382b6d
--- /dev/null
+++ b/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/iomux.h>
+#include <mach/imxfb.h>
+#include <mach/hardware.h>
+#include <mach/mmc.h>
+#include <mach/imx-uart.h>
+
+#include "devices.h"
+
+static int eukrea_mbimx27_pins[] = {
+	/* UART2 */
+	PE3_PF_UART2_CTS,
+	PE4_PF_UART2_RTS,
+	PE6_PF_UART2_TXD,
+	PE7_PF_UART2_RXD,
+	/* UART3 */
+	PE8_PF_UART3_TXD,
+	PE9_PF_UART3_RXD,
+	PE10_PF_UART3_CTS,
+	PE11_PF_UART3_RTS,
+	/* UART4 */
+	PB26_AF_UART4_RTS,
+	PB28_AF_UART4_TXD,
+	PB29_AF_UART4_CTS,
+	PB31_AF_UART4_RXD,
+	/* SDHC1*/
+	PE18_PF_SD1_D0,
+	PE19_PF_SD1_D1,
+	PE20_PF_SD1_D2,
+	PE21_PF_SD1_D3,
+	PE22_PF_SD1_CMD,
+	PE23_PF_SD1_CLK,
+	/* display */
+	PA5_PF_LSCLK,
+	PA6_PF_LD0,
+	PA7_PF_LD1,
+	PA8_PF_LD2,
+	PA9_PF_LD3,
+	PA10_PF_LD4,
+	PA11_PF_LD5,
+	PA12_PF_LD6,
+	PA13_PF_LD7,
+	PA14_PF_LD8,
+	PA15_PF_LD9,
+	PA16_PF_LD10,
+	PA17_PF_LD11,
+	PA18_PF_LD12,
+	PA19_PF_LD13,
+	PA20_PF_LD14,
+	PA21_PF_LD15,
+	PA22_PF_LD16,
+	PA23_PF_LD17,
+	PA28_PF_HSYNC,
+	PA29_PF_VSYNC,
+	PA30_PF_CONTRAST,
+	PA31_PF_OE_ACD,
+	/* SPI1 */
+	PD28_PF_CSPI1_SS0,
+	PD29_PF_CSPI1_SCLK,
+	PD30_PF_CSPI1_MISO,
+	PD31_PF_CSPI1_MOSI,
+};
+
+static struct gpio_led gpio_leds[] = {
+	{
+		.name			= "led1",
+		.default_trigger	= "heartbeat",
+		.active_low		= 1,
+		.gpio			= GPIO_PORTF | 16,
+	},
+	{
+		.name			= "led2",
+		.default_trigger	= "none",
+		.active_low		= 1,
+		.gpio			= GPIO_PORTF | 19,
+	},
+	{
+		.name			= "backlight",
+		.default_trigger	= "backlight",
+		.active_low		= 0,
+		.gpio			= GPIO_PORTE | 5,
+	},
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+	.leds		= gpio_leds,
+	.num_leds	= ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &gpio_led_info,
+	},
+};
+
+static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
+	{
+		.mode = {
+			.name		= "CMO-QGVA",
+			.refresh	= 60,
+			.xres		= 320,
+			.yres		= 240,
+			.pixclock	= 156000,
+			.hsync_len	= 30,
+			.left_margin	= 38,
+			.right_margin	= 20,
+			.vsync_len	= 3,
+			.upper_margin	= 15,
+			.lower_margin	= 4,
+		},
+		.pcr		= 0xFAD08B80,
+		.bpp		= 16,
+	},
+};
+
+static struct imx_fb_platform_data eukrea_mbimx27_fb_data = {
+	.mode = eukrea_mbimx27_modes,
+	.num_modes = ARRAY_SIZE(eukrea_mbimx27_modes),
+
+	.pwmr		= 0x00A903FF,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00040060,
+};
+
+static struct imxuart_platform_data uart_pdata[] = {
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+	{
+		.flags = IMXUART_HAVE_RTSCTS,
+	},
+};
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846)
+	|| defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+#define ADS7846_PENDOWN (GPIO_PORTD | 25)
+
+static void ads7846_dev_init(void)
+{
+	if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) {
+		printk(KERN_ERR "can't get ads746 pen down GPIO\n");
+		return;
+	}
+
+	gpio_direction_input(ADS7846_PENDOWN);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+	return !gpio_get_value(ADS7846_PENDOWN);
+}
+
+static struct ads7846_platform_data ads7846_config __initdata = {
+	.get_pendown_state	= ads7846_get_pendown_state,
+	.keep_vref_on		= 1,
+};
+
+static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = {
+	[0] = {
+		.modalias	= "ads7846",
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.max_speed_hz	= 1500000,
+		.irq		= IRQ_GPIOD(25),
+		.platform_data	= &ads7846_config,
+		.mode           = SPI_MODE_2,
+	},
+};
+
+static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28};
+
+static struct spi_imx_master eukrea_mbimx27_spi_0_data = {
+	.chipselect	= eukrea_mbimx27_spi_cs,
+	.num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs),
+};
+#endif
+
+static struct platform_device *platform_devices[] __initdata = {
+	&leds_gpio,
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx27 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimx27_baseboard_init(void)
+{
+	mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
+		ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
+
+	mxc_register_device(&mxc_uart_device1, &uart_pdata[0]);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata[1]);
+
+	mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data);
+	mxc_register_device(&mxc_sdhc_device0, NULL);
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846)
+	|| defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+	/* SPI and ADS7846 Touchscreen controler init */
+	mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+	mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN);
+	mxc_register_device(&mxc_spi_device0, &eukrea_mbimx27_spi_0_data);
+	spi_register_board_info(eukrea_mbimx27_spi_board_info,
+			ARRAY_SIZE(eukrea_mbimx27_spi_board_info));
+	ads7846_dev_init();
+#endif
+
+	/* Leds configuration */
+	mxc_gpio_mode(GPIO_PORTF | 16 | GPIO_GPIO | GPIO_OUT);
+	mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT);
+	/* Backlight */
+	mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT);
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c
index 169372f..ae8f759 100644
--- a/arch/arm/mach-mx2/generic.c
+++ b/arch/arm/mach-mx2/generic.c
@@ -72,6 +72,7 @@ static struct map_desc mxc_io_desc[] __initdata = {
 void __init mx21_map_io(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX21);
+	mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
 
 	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
@@ -79,7 +80,18 @@ void __init mx21_map_io(void)
 void __init mx27_map_io(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX27);
+	mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
 
 	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
 
+void __init mx27_init_irq(void)
+{
+	mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
+}
+
+void __init mx21_init_irq(void)
+{
+	mx27_init_irq();
+}
+
diff --git a/arch/arm/mach-mx2/mx21ads.c b/arch/arm/mach-mx2/mx21ads.c
index a5ee461..cf5f77c 100644
--- a/arch/arm/mach-mx2/mx21ads.c
+++ b/arch/arm/mach-mx2/mx21ads.c
@@ -164,25 +164,33 @@ static void mx21ads_fb_exit(struct platform_device *pdev)
  * Connected is a portrait Sharp-QVGA display
  * of type: LQ035Q7DB02
  */
-static struct imx_fb_platform_data mx21ads_fb_data = {
-	.pixclock       = 188679, /* in ps */
-	.xres           = 240,
-	.yres           = 320,
-
-	.bpp            = 16,
-	.hsync_len      = 2,
-	.left_margin    = 6,
-	.right_margin   = 16,
+static struct imx_fb_videomode mx21ads_modes[] = {
+	{
+		.mode = {
+			.name		= "Sharp-LQ035Q7",
+			.refresh	= 60,
+			.xres		= 240,
+			.yres		= 320,
+			.pixclock	= 188679, /* in ps (5.3MHz) */
+			.hsync_len	= 2,
+			.left_margin	= 6,
+			.right_margin	= 16,
+			.vsync_len	= 1,
+			.upper_margin	= 8,
+			.lower_margin	= 10,
+		},
+		.pcr		= 0xfb108bc7,
+		.bpp		= 16,
+	},
+};
 
-	.vsync_len      = 1,
-	.upper_margin   = 8,
-	.lower_margin   = 10,
-	.fixed_screen_cpu = 0,
+static struct imx_fb_platform_data mx21ads_fb_data = {
+	.mode = mx21ads_modes,
+	.num_modes = ARRAY_SIZE(mx21ads_modes),
 
-	.pcr            = 0xFB108BC7,
-	.pwmr           = 0x00A901ff,
-	.lscr1          = 0x00120300,
-	.dmacr          = 0x00020008,
+	.pwmr		= 0x00a903ff,
+	.lscr1		= 0x00120300,
+	.dmacr		= 0x00020008,
 
 	.init = mx21ads_fb_init,
 	.exit = mx21ads_fb_exit,
@@ -280,7 +288,7 @@ MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
 	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx21ads_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx21_init_irq,
 	.init_machine   = mx21ads_board_init,
 	.timer          = &mx21ads_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c
index 02dadda..83e412b 100644
--- a/arch/arm/mach-mx2/mx27ads.c
+++ b/arch/arm/mach-mx2/mx27ads.c
@@ -183,20 +183,29 @@ void lcd_power(int on)
 		__raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
 }
 
-static struct imx_fb_platform_data mx27ads_fb_data = {
-	.pixclock	= 188679,
-	.xres		= 240,
-	.yres		= 320,
-
-	.bpp		= 16,
-	.hsync_len	= 1,
-	.left_margin	= 9,
-	.right_margin	= 16,
+static struct imx_fb_videomode mx27ads_modes[] = {
+	{
+		.mode = {
+			.name		= "Sharp-LQ035Q7",
+			.refresh	= 60,
+			.xres		= 240,
+			.yres		= 320,
+			.pixclock	= 188679, /* in ps (5.3MHz) */
+			.hsync_len	= 1,
+			.left_margin	= 9,
+			.right_margin	= 16,
+			.vsync_len	= 1,
+			.upper_margin	= 7,
+			.lower_margin	= 9,
+		},
+		.bpp		= 16,
+		.pcr		= 0xFB008BC0,
+	},
+};
 
-	.vsync_len	= 1,
-	.upper_margin	= 7,
-	.lower_margin	= 9,
-	.fixed_screen_cpu = 0,
+static struct imx_fb_platform_data mx27ads_fb_data = {
+	.mode = mx27ads_modes,
+	.num_modes = ARRAY_SIZE(mx27ads_modes),
 
 	/*
 	 * - HSYNC active high
@@ -207,7 +216,6 @@ static struct imx_fb_platform_data mx27ads_fb_data = {
 	 * - data enable low active
 	 * - enable sharp mode
 	 */
-	.pcr		= 0xFB008BC0,
 	.pwmr		= 0x00A903FF,
 	.lscr1		= 0x00120300,
 	.dmacr		= 0x00020010,
@@ -330,7 +338,7 @@ MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
 	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx27ads_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx27_init_irq,
 	.init_machine   = mx27ads_board_init,
 	.timer          = &mx27ads_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27lite.c b/arch/arm/mach-mx2/mx27lite.c
index 3ae11cb..82ea227 100644
--- a/arch/arm/mach-mx2/mx27lite.c
+++ b/arch/arm/mach-mx2/mx27lite.c
@@ -89,7 +89,7 @@ MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
 	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx27_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx27_init_irq,
 	.init_machine   = mx27lite_init,
 	.timer          = &mx27lite_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx2/mx27pdk.c b/arch/arm/mach-mx2/mx27pdk.c
index 1d9238c..6761d1b 100644
--- a/arch/arm/mach-mx2/mx27pdk.c
+++ b/arch/arm/mach-mx2/mx27pdk.c
@@ -89,7 +89,7 @@ MACHINE_START(MX27_3DS, "Freescale MX27PDK")
 	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx27_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx27_init_irq,
 	.init_machine   = mx27pdk_init,
 	.timer          = &mx27pdk_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx2/pca100.c b/arch/arm/mach-mx2/pca100.c
new file mode 100644
index 0000000..fe5b165
--- /dev/null
+++ b/arch/arm/mach-mx2/pca100.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2009 Sascha Hauer (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux.h>
+#include <mach/i2c.h>
+#include <asm/mach/time.h>
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+#include <mach/spi.h>
+#endif
+#include <mach/imx-uart.h>
+#include <mach/mxc_nand.h>
+#include <mach/irqs.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
+
+static int pca100_pins[] = {
+	/* UART1 */
+	PE12_PF_UART1_TXD,
+	PE13_PF_UART1_RXD,
+	PE14_PF_UART1_CTS,
+	PE15_PF_UART1_RTS,
+	/* SDHC */
+	PB4_PF_SD2_D0,
+	PB5_PF_SD2_D1,
+	PB6_PF_SD2_D2,
+	PB7_PF_SD2_D3,
+	PB8_PF_SD2_CMD,
+	PB9_PF_SD2_CLK,
+	/* FEC */
+	PD0_AIN_FEC_TXD0,
+	PD1_AIN_FEC_TXD1,
+	PD2_AIN_FEC_TXD2,
+	PD3_AIN_FEC_TXD3,
+	PD4_AOUT_FEC_RX_ER,
+	PD5_AOUT_FEC_RXD1,
+	PD6_AOUT_FEC_RXD2,
+	PD7_AOUT_FEC_RXD3,
+	PD8_AF_FEC_MDIO,
+	PD9_AIN_FEC_MDC,
+	PD10_AOUT_FEC_CRS,
+	PD11_AOUT_FEC_TX_CLK,
+	PD12_AOUT_FEC_RXD0,
+	PD13_AOUT_FEC_RX_DV,
+	PD14_AOUT_FEC_RX_CLK,
+	PD15_AOUT_FEC_COL,
+	PD16_AIN_FEC_TX_ER,
+	PF23_AIN_FEC_TX_EN,
+	/* SSI1 */
+	PC20_PF_SSI1_FS,
+	PC21_PF_SSI1_RXD,
+	PC22_PF_SSI1_TXD,
+	PC23_PF_SSI1_CLK,
+	/* onboard I2C */
+	PC5_PF_I2C2_SDA,
+	PC6_PF_I2C2_SCL,
+	/* external I2C */
+	PD17_PF_I2C_DATA,
+	PD18_PF_I2C_CLK,
+	/* SPI1 */
+	PD25_PF_CSPI1_RDY,
+	PD29_PF_CSPI1_SCLK,
+	PD30_PF_CSPI1_MISO,
+	PD31_PF_CSPI1_MOSI,
+};
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct mxc_nand_platform_data pca100_nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&mxc_w1_master_device,
+	&mxc_fec_device,
+};
+
+static struct imxi2c_platform_data pca100_i2c_1_data = {
+	.bitrate = 100000,
+};
+
+static struct at24_platform_data board_eeprom = {
+	.byte_len = 4096,
+	.page_size = 32,
+	.flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pca100_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+		.platform_data = &board_eeprom,
+	}, {
+		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
+		.type = "pcf8563"
+	}, {
+		I2C_BOARD_INFO("lm75", 0x4a),
+		.type = "lm75"
+	}
+};
+
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+static struct spi_eeprom at25320 = {
+	.name		= "at25320an",
+	.byte_len	= 4096,
+	.page_size	= 32,
+	.flags		= EE_ADDR2,
+};
+
+static struct spi_board_info pca100_spi_board_info[] __initdata = {
+	{
+		.modalias = "at25",
+		.max_speed_hz = 30000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.platform_data = &at25320,
+	},
+};
+
+static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
+
+static struct spi_imx_master pca100_spi_0_data = {
+	.chipselect	= pca100_spi_cs,
+	.num_chipselect = ARRAY_SIZE(pca100_spi_cs),
+};
+#endif
+
+static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+		void *data)
+{
+	int ret;
+
+	ret = request_irq(IRQ_GPIOC(29), detect_irq,
+			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  "imx-mmc-detect", data);
+	if (ret)
+		printk(KERN_ERR
+			"pca100: Failed to reuest irq for sd/mmc detection\n");
+
+	return ret;
+}
+
+static void pca100_sdhc2_exit(struct device *dev, void *data)
+{
+	free_irq(IRQ_GPIOC(29), data);
+}
+
+static struct imxmmc_platform_data sdhc_pdata = {
+	.init = pca100_sdhc2_init,
+	.exit = pca100_sdhc2_exit,
+};
+
+static void __init pca100_init(void)
+{
+	int ret;
+
+	ret = mxc_gpio_setup_multiple_pins(pca100_pins,
+			ARRAY_SIZE(pca100_pins), "PCA100");
+	if (ret)
+		printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
+
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+	mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN);
+	mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
+
+	mxc_register_device(&mxc_nand_device, &pca100_nand_board_info);
+
+	/* only the i2c master 1 is used on this CPU card */
+	i2c_register_board_info(1, pca100_i2c_devices,
+				ARRAY_SIZE(pca100_i2c_devices));
+
+	mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data);
+
+	mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+	mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT);
+
+	/* GPIO0_IRQ */
+	mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN);
+	/* GPIO1_IRQ */
+	mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN);
+	/* GPIO2_IRQ */
+	mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN);
+
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+	spi_register_board_info(pca100_spi_board_info,
+				ARRAY_SIZE(pca100_spi_board_info));
+	mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
+#endif
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init pca100_timer_init(void)
+{
+	mx27_clocks_init(26000000);
+}
+
+static struct sys_timer pca100_timer = {
+	.init = pca100_timer_init,
+};
+
+MACHINE_START(PCA100, "phyCARD-i.MX27")
+	.phys_io        = AIPI_BASE_ADDR,
+	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = mx27_map_io,
+	.init_irq       = mxc_init_irq,
+	.init_machine   = pca100_init,
+	.timer          = &pca100_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c
index a4628d0..ee65dda 100644
--- a/arch/arm/mach-mx2/pcm038.c
+++ b/arch/arm/mach-mx2/pcm038.c
@@ -186,17 +186,13 @@ static struct at24_platform_data board_eeprom = {
 };
 
 static struct i2c_board_info pcm038_i2c_devices[] = {
-	[0] = {
+	{
 		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
 		.platform_data = &board_eeprom,
-	},
-	[1] = {
-		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
-		.type = "pcf8563"
-	},
-	[2] = {
+	}, {
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	}, {
 		I2C_BOARD_INFO("lm75", 0x4a),
-		.type = "lm75"
 	}
 };
 
@@ -220,6 +216,9 @@ static void __init pcm038_init(void)
 
 	mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
 
+	/* PE18 for user-LED D40 */
+	mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
+
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 
 #ifdef CONFIG_MACH_PCM970_BASEBOARD
@@ -241,7 +240,7 @@ MACHINE_START(PCM038, "phyCORE-i.MX27")
 	.io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx27_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx27_init_irq,
 	.init_machine   = pcm038_init,
 	.timer          = &pcm038_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c
index 6a3acaf..c261f59 100644
--- a/arch/arm/mach-mx2/pcm970-baseboard.c
+++ b/arch/arm/mach-mx2/pcm970-baseboard.c
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
+#include <linux/can/platform/sja1000.h>
 
 #include <asm/mach/arch.h>
 
@@ -125,40 +126,96 @@ static struct imxmmc_platform_data sdhc_pdata = {
 	.exit = pcm970_sdhc2_exit,
 };
 
-/*
- * Connected is a portrait Sharp-QVGA display
- * of type: LQ035Q7DH06
- */
-static struct imx_fb_platform_data pcm038_fb_data = {
-	.pixclock	= 188679, /* in ps (5.3MHz) */
-	.xres		= 240,
-	.yres		= 320,
-
-	.bpp		= 16,
-	.hsync_len	= 7,
-	.left_margin	= 5,
-	.right_margin	= 16,
+static struct imx_fb_videomode pcm970_modes[] = {
+	{
+		.mode = {
+			.name		= "Sharp-LQ035Q7",
+			.refresh	= 60,
+			.xres		= 240,
+			.yres		= 320,
+			.pixclock	= 188679, /* in ps (5.3MHz) */
+			.hsync_len	= 7,
+			.left_margin	= 5,
+			.right_margin	= 16,
+			.vsync_len	= 1,
+			.upper_margin	= 7,
+			.lower_margin	= 9,
+		},
+		/*
+		 * - HSYNC active high
+		 * - VSYNC active high
+		 * - clk notenabled while idle
+		 * - clock not inverted
+		 * - data not inverted
+		 * - data enable low active
+		 * - enable sharp mode
+		 */
+		.pcr		= 0xF00080C0,
+		.bpp		= 16,
+	}, {
+		.mode = {
+			.name		= "TX090",
+			.refresh	= 60,
+			.xres		= 240,
+			.yres		= 320,
+			.pixclock	= 38255,
+			.left_margin	= 144,
+			.right_margin	= 0,
+			.upper_margin	= 7,
+			.lower_margin	= 40,
+			.hsync_len	= 96,
+			.vsync_len	= 1,
+		},
+		/*
+		 * - HSYNC active low (1 << 22)
+		 * - VSYNC active low (1 << 23)
+		 * - clk notenabled while idle
+		 * - clock not inverted
+		 * - data not inverted
+		 * - data enable low active
+		 * - enable sharp mode
+		 */
+		.pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19),
+		.bpp = 32,
+	},
+};
 
-	.vsync_len	= 1,
-	.upper_margin	= 7,
-	.lower_margin	= 9,
-	.fixed_screen_cpu = 0,
+static struct imx_fb_platform_data pcm038_fb_data = {
+	.mode = pcm970_modes,
+	.num_modes = ARRAY_SIZE(pcm970_modes),
 
-	/*
-	 * - HSYNC active high
-	 * - VSYNC active high
-	 * - clk notenabled while idle
-	 * - clock not inverted
-	 * - data not inverted
-	 * - data enable low active
-	 * - enable sharp mode
-	 */
-	.pcr		= 0xFA0080C0,
 	.pwmr		= 0x00A903FF,
 	.lscr1		= 0x00120300,
 	.dmacr		= 0x00020010,
 };
 
+static struct resource pcm970_sja1000_resources[] = {
+	{
+		.start   = CS4_BASE_ADDR,
+		.end     = CS4_BASE_ADDR + 0x100 - 1,
+		.flags   = IORESOURCE_MEM,
+	}, {
+		.start   = IRQ_GPIOE(19),
+		.end     = IRQ_GPIOE(19),
+		.flags   = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+	},
+};
+
+struct sja1000_platform_data pcm970_sja1000_platform_data = {
+	.clock		= 16000000 / 2,
+	.ocr		= 0x40 | 0x18,
+	.cdr		= 0x40,
+};
+
+static struct platform_device pcm970_sja1000 = {
+	.name = "sja1000_platform",
+	.dev = {
+		.platform_data = &pcm970_sja1000_platform_data,
+	},
+	.resource = pcm970_sja1000_resources,
+	.num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
+};
+
 /*
  * system init for baseboard usage. Will be called by pcm038 init.
  *
@@ -172,4 +229,5 @@ void __init pcm970_baseboard_init(void)
 
 	mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
 	mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
+	platform_device_register(&pcm970_sja1000);
 }
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
new file mode 100644
index 0000000..cc28f56
--- /dev/null
+++ b/arch/arm/mach-mx25/Kconfig
@@ -0,0 +1,9 @@
+if ARCH_MX25
+
+comment "MX25 platforms:"
+
+config MACH_MX25_3DS
+	select ARCH_MXC_IOMUX_V3
+	bool "Support MX25PDK (3DS) Platform"
+
+endif
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile
new file mode 100644
index 0000000..fe23836
--- /dev/null
+++ b/arch/arm/mach-mx25/Makefile
@@ -0,0 +1,3 @@
+obj-y				:= mm.o devices.o
+obj-$(CONFIG_ARCH_MX25)		+= clock.o
+obj-$(CONFIG_MACH_MX25_3DS)	+= mx25pdk.o
diff --git a/arch/arm/mach-mx25/Makefile.boot b/arch/arm/mach-mx25/Makefile.boot
new file mode 100644
index 0000000..e1dd366
--- /dev/null
+++ b/arch/arm/mach-mx25/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x80008000
+params_phys-y	:= 0x80000100
+initrd_phys-y	:= 0x80800000
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
new file mode 100644
index 0000000..ef26951
--- /dev/null
+++ b/arch/arm/mach-mx25/clock.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+
+#define CRM_BASE	MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
+
+#define CCM_MPCTL	0x00
+#define CCM_UPCTL	0x04
+#define CCM_CCTL	0x08
+#define CCM_CGCR0	0x0C
+#define CCM_CGCR1	0x10
+#define CCM_CGCR2	0x14
+#define CCM_PCDR0	0x18
+#define CCM_PCDR1	0x1C
+#define CCM_PCDR2	0x20
+#define CCM_PCDR3	0x24
+#define CCM_RCSR	0x28
+#define CCM_CRDR	0x2C
+#define CCM_DCVR0	0x30
+#define CCM_DCVR1	0x34
+#define CCM_DCVR2	0x38
+#define CCM_DCVR3	0x3c
+#define CCM_LTR0	0x40
+#define CCM_LTR1	0x44
+#define CCM_LTR2	0x48
+#define CCM_LTR3	0x4c
+
+static unsigned long get_rate_mpll(void)
+{
+	ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
+
+	return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_upll(void)
+{
+	ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
+
+	return mxc_decode_pll(mpctl, 24000000);
+}
+
+unsigned long get_rate_arm(struct clk *clk)
+{
+	unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+	unsigned long rate = get_rate_mpll();
+
+	if (cctl & (1 << 14))
+		rate = (rate * 3) >> 1;
+
+	return rate / ((cctl >> 30) + 1);
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+	unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+
+	return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+	return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_rate_per(int per)
+{
+	unsigned long ofs = (per & 0x3) * 8;
+	unsigned long reg = per & ~0x3;
+	unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
+	unsigned long fref;
+
+	if (readl(CRM_BASE + 0x64) & (1 << per))
+		fref = get_rate_upll();
+	else
+		fref = get_rate_ipg(NULL);
+
+	return fref / (val + 1);
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+	return get_rate_per(15);
+}
+
+static unsigned long get_rate_i2c(struct clk *clk)
+{
+	return get_rate_per(6);
+}
+
+static unsigned long get_rate_nfc(struct clk *clk)
+{
+	return get_rate_per(8);
+}
+
+static unsigned long get_rate_otg(struct clk *clk)
+{
+	return 48000000; /* FIXME */
+}
+
+static int clk_cgcr_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 1 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void clk_cgcr_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(1 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr)		\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= CRM_BASE + er,	\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.set_rate	= sr,			\
+		.enable		= clk_cgcr_enable,	\
+		.disable	= clk_cgcr_disable,	\
+	}
+
+DEFINE_CLOCK(gpt_clk,    0, CCM_CGCR0,  5, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi1_clk,  0, CCM_CGCR1,  5, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi2_clk,  0, CCM_CGCR1,  6, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi3_clk,  0, CCM_CGCR1,  7, get_rate_ipg, NULL);
+DEFINE_CLOCK(uart1_clk,  0, CCM_CGCR2, 14, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk,  0, CCM_CGCR2, 15, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk,  0, CCM_CGCR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart4_clk,  0, CCM_CGCR2, 17, get_rate_uart, NULL);
+DEFINE_CLOCK(uart5_clk,  0, CCM_CGCR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(nfc_clk,    0, CCM_CGCR0,  8, get_rate_nfc, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL);
+DEFINE_CLOCK(pwm1_clk,	 0, CCM_CGCR1, 31, get_rate_ipg, NULL);
+DEFINE_CLOCK(pwm2_clk,	 0, CCM_CGCR2,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(pwm3_clk,	 0, CCM_CGCR2,  1, get_rate_ipg, NULL);
+DEFINE_CLOCK(pwm4_clk,	 0, CCM_CGCR2,  2, get_rate_ipg, NULL);
+DEFINE_CLOCK(kpp_clk,	 0, CCM_CGCR1, 28, get_rate_ipg, NULL);
+DEFINE_CLOCK(tsc_clk,	 0, CCM_CGCR2, 13, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c_clk,	 0, CCM_CGCR0,  6, get_rate_i2c, NULL);
+
+#define _REGISTER_CLOCK(d, n, c)	\
+	{				\
+		.dev_id = d,		\
+		.con_id = n,		\
+		.clk = &c,		\
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+	_REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+	_REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
+	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+	_REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+	_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+	_REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+	_REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
+	_REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
+	_REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
+	_REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
+	_REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+	_REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
+	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
+};
+
+int __init mx25_clocks_init(unsigned long fref)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
new file mode 100644
index 0000000..eb12de1
--- /dev/null
+++ b/arch/arm/mach-mx25/devices.c
@@ -0,0 +1,402 @@
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <mach/mx25.h>
+#include <mach/irqs.h>
+
+static struct resource uart0[] = {
+	{
+		.start = 0x43f90000,
+		.end = 0x43f93fff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 45,
+		.end = 45,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device0 = {
+	.name = "imx-uart",
+	.id = 0,
+	.resource = uart0,
+	.num_resources = ARRAY_SIZE(uart0),
+};
+
+static struct resource uart1[] = {
+	{
+		.start = 0x43f94000,
+		.end = 0x43f97fff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 32,
+		.end = 32,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device1 = {
+	.name = "imx-uart",
+	.id = 1,
+	.resource = uart1,
+	.num_resources = ARRAY_SIZE(uart1),
+};
+
+static struct resource uart2[] = {
+	{
+		.start = 0x5000c000,
+		.end = 0x5000ffff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 18,
+		.end = 18,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device2 = {
+	.name = "imx-uart",
+	.id = 2,
+	.resource = uart2,
+	.num_resources = ARRAY_SIZE(uart2),
+};
+
+static struct resource uart3[] = {
+	{
+		.start = 0x50008000,
+		.end = 0x5000bfff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 5,
+		.end = 5,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device3 = {
+	.name = "imx-uart",
+	.id = 3,
+	.resource = uart3,
+	.num_resources = ARRAY_SIZE(uart3),
+};
+
+static struct resource uart4[] = {
+	{
+		.start = 0x5002c000,
+		.end = 0x5002ffff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 40,
+		.end = 40,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device4 = {
+	.name = "imx-uart",
+	.id = 4,
+	.resource = uart4,
+	.num_resources = ARRAY_SIZE(uart4),
+};
+
+#define MX25_OTG_BASE_ADDR 0x53FF4000
+
+static u64 otg_dmamask = DMA_BIT_MASK(32);
+
+static struct resource mxc_otg_resources[] = {
+	{
+		.start = MX25_OTG_BASE_ADDR,
+		.end = MX25_OTG_BASE_ADDR + 0x1ff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 37,
+		.end = 37,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_otg = {
+	.name = "mxc-ehci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &otg_dmamask,
+	},
+	.resource = mxc_otg_resources,
+	.num_resources = ARRAY_SIZE(mxc_otg_resources),
+};
+
+/* OTG gadget device */
+struct platform_device otg_udc_device = {
+	.name = "fsl-usb2-udc",
+	.id   = -1,
+	.dev  = {
+		.dma_mask          = &otg_dmamask,
+		.coherent_dma_mask = 0xffffffff,
+	},
+	.resource = mxc_otg_resources,
+	.num_resources = ARRAY_SIZE(mxc_otg_resources),
+};
+
+static u64 usbh2_dmamask = DMA_BIT_MASK(32);
+
+static struct resource mxc_usbh2_resources[] = {
+	{
+		.start = MX25_OTG_BASE_ADDR + 0x400,
+		.end = MX25_OTG_BASE_ADDR + 0x5ff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 35,
+		.end = 35,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_usbh2 = {
+	.name = "mxc-ehci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &usbh2_dmamask,
+	},
+	.resource = mxc_usbh2_resources,
+	.num_resources = ARRAY_SIZE(mxc_usbh2_resources),
+};
+
+static struct resource mxc_spi_resources0[] = {
+	{
+	       .start = 0x43fa4000,
+	       .end = 0x43fa7fff,
+	       .flags = IORESOURCE_MEM,
+	}, {
+	       .start = 14,
+	       .end = 14,
+	       .flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_spi_device0 = {
+	.name = "spi_imx",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_spi_resources0),
+	.resource = mxc_spi_resources0,
+};
+
+static struct resource mxc_spi_resources1[] = {
+	{
+	       .start = 0x50010000,
+	       .end = 0x50013fff,
+	       .flags = IORESOURCE_MEM,
+	}, {
+	       .start = 13,
+	       .end = 13,
+	       .flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_spi_device1 = {
+	.name = "spi_imx",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_spi_resources1),
+	.resource = mxc_spi_resources1,
+};
+
+static struct resource mxc_spi_resources2[] = {
+	{
+	       .start = 0x50004000,
+	       .end = 0x50007fff,
+	       .flags = IORESOURCE_MEM,
+	}, {
+	       .start = 0,
+	       .end = 0,
+	       .flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_spi_device2 = {
+	.name = "spi_imx",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(mxc_spi_resources2),
+	.resource = mxc_spi_resources2,
+};
+
+static struct resource mxc_pwm_resources0[] = {
+	{
+		.start	= 0x53fe0000,
+		.end	= 0x53fe3fff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start   = 26,
+		.end     = 26,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_pwm_device0 = {
+	.name = "mxc_pwm",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_pwm_resources0),
+	.resource = mxc_pwm_resources0,
+};
+
+static struct resource mxc_pwm_resources1[] = {
+	{
+		.start	= 0x53fa0000,
+		.end	= 0x53fa3fff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start   = 36,
+		.end     = 36,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_pwm_device1 = {
+	.name = "mxc_pwm",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_pwm_resources1),
+	.resource = mxc_pwm_resources1,
+};
+
+static struct resource mxc_pwm_resources2[] = {
+	{
+		.start	= 0x53fa8000,
+		.end	= 0x53fabfff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start   = 41,
+		.end     = 41,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_pwm_device2 = {
+	.name = "mxc_pwm",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(mxc_pwm_resources2),
+	.resource = mxc_pwm_resources2,
+};
+
+static struct resource mxc_keypad_resources[] = {
+	{
+		.start	= 0x43fa8000,
+		.end	= 0x43fabfff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start   = 24,
+		.end     = 24,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_keypad_device = {
+	.name = "mxc-keypad",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(mxc_keypad_resources),
+	.resource = mxc_keypad_resources,
+};
+
+static struct resource mxc_pwm_resources3[] = {
+	{
+		.start	= 0x53fc8000,
+		.end	= 0x53fcbfff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start   = 42,
+		.end     = 42,
+		.flags   = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_pwm_device3 = {
+	.name = "mxc_pwm",
+	.id = 3,
+	.num_resources = ARRAY_SIZE(mxc_pwm_resources3),
+	.resource = mxc_pwm_resources3,
+};
+
+static struct resource mxc_i2c_1_resources[] = {
+	{
+		.start	= 0x43f80000,
+		.end	= 0x43f83fff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= 3,
+		.end	= 3,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_i2c_device0 = {
+	.name = "imx-i2c",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
+	.resource = mxc_i2c_1_resources,
+};
+
+static struct resource mxc_i2c_2_resources[] = {
+	{
+		.start	= 0x43f98000,
+		.end	= 0x43f9bfff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= 4,
+		.end	= 4,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_i2c_device1 = {
+	.name = "imx-i2c",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
+	.resource = mxc_i2c_2_resources,
+};
+
+static struct resource mxc_i2c_3_resources[] = {
+	{
+		.start	= 0x43f84000,
+		.end	= 0x43f87fff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= 10,
+		.end	= 10,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device mxc_i2c_device2 = {
+	.name = "imx-i2c",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(mxc_i2c_3_resources),
+	.resource = mxc_i2c_3_resources,
+};
+
+static struct mxc_gpio_port imx_gpio_ports[] = {
+	{
+		.chip.label = "gpio-0",
+		.base = (void __iomem *)MX25_GPIO1_BASE_ADDR_VIRT,
+		.irq = 52,
+		.virtual_irq_start = MXC_GPIO_IRQ_START,
+	}, {
+		.chip.label = "gpio-1",
+		.base = (void __iomem *)MX25_GPIO2_BASE_ADDR_VIRT,
+		.irq = 51,
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
+	}, {
+		.chip.label = "gpio-2",
+		.base = (void __iomem *)MX25_GPIO3_BASE_ADDR_VIRT,
+		.irq = 16,
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
+	}, {
+		.chip.label = "gpio-3",
+		.base = (void __iomem *)MX25_GPIO4_BASE_ADDR_VIRT,
+		.irq = 23,
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
+	}
+};
+
+int __init mxc_register_gpios(void)
+{
+	return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
+}
+
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h
new file mode 100644
index 0000000..fe6bf88
--- /dev/null
+++ b/arch/arm/mach-mx25/devices.h
@@ -0,0 +1,19 @@
+extern struct platform_device mxc_uart_device0;
+extern struct platform_device mxc_uart_device1;
+extern struct platform_device mxc_uart_device2;
+extern struct platform_device mxc_uart_device3;
+extern struct platform_device mxc_uart_device4;
+extern struct platform_device mxc_otg;
+extern struct platform_device otg_udc_device;
+extern struct platform_device mxc_usbh2;
+extern struct platform_device mxc_spi_device0;
+extern struct platform_device mxc_spi_device1;
+extern struct platform_device mxc_spi_device2;
+extern struct platform_device mxc_pwm_device0;
+extern struct platform_device mxc_pwm_device1;
+extern struct platform_device mxc_pwm_device2;
+extern struct platform_device mxc_pwm_device3;
+extern struct platform_device mxc_keypad_device;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_i2c_device2;
diff --git a/arch/arm/mach-mx25/mm.c b/arch/arm/mach-mx25/mm.c
new file mode 100644
index 0000000..a7e587f
--- /dev/null
+++ b/arch/arm/mach-mx25/mm.c
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *    - add MX31 specific definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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/mm.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mx25.h>
+#include <mach/iomux-v3.h>
+
+/*
+ * This table defines static virtual address mappings for I/O regions.
+ * These are the mappings common across all MX3 boards.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+	{
+		.virtual	= MX25_AVIC_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MX25_AVIC_BASE_ADDR),
+		.length		= MX25_AVIC_SIZE,
+		.type		= MT_DEVICE_NONSHARED
+	}, {
+		.virtual	= MX25_AIPS1_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MX25_AIPS1_BASE_ADDR),
+		.length		= MX25_AIPS1_SIZE,
+		.type		= MT_DEVICE_NONSHARED
+	}, {
+		.virtual	= MX25_AIPS2_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MX25_AIPS2_BASE_ADDR),
+		.length		= MX25_AIPS2_SIZE,
+		.type		= MT_DEVICE_NONSHARED
+	},
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx25_map_io(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX25);
+	mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
+	mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
+
+	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
+
+void __init mx25_init_irq(void)
+{
+	mxc_init_irq((void __iomem *)MX25_AVIC_BASE_ADDR_VIRT);
+}
+
diff --git a/arch/arm/mach-mx25/mx25pdk.c b/arch/arm/mach-mx25/mx25pdk.c
new file mode 100644
index 0000000..92aa4fd
--- /dev/null
+++ b/arch/arm/mach-mx25/mx25pdk.c
@@ -0,0 +1,58 @@
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/mx25.h>
+#include <mach/mxc_nand.h>
+#include "devices.h"
+#include <mach/iomux-v3.h>
+
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct mxc_nand_platform_data nand_board_info = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static void __init mx25pdk_init(void)
+{
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_usbh2, NULL);
+	mxc_register_device(&mxc_nand_device, &nand_board_info);
+}
+
+
+static void __init mx25pdk_timer_init(void)
+{
+	mx25_clocks_init(26000000);
+}
+
+static struct sys_timer mx25pdk_timer = {
+	.init   = mx25pdk_timer_init,
+};
+
+MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.phys_io	= MX25_AIPS1_BASE_ADDR,
+	.io_pg_offst	= ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = mx25_map_io,
+	.init_irq       = mx25_init_irq,
+	.init_machine   = mx25pdk_init,
+	.timer          = &mx25pdk_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c
index ee331fd..776c0ee 100644
--- a/arch/arm/mach-mx3/armadillo5x0.c
+++ b/arch/arm/mach-mx3/armadillo5x0.c
@@ -352,7 +352,7 @@ MACHINE_START(ARMADILLO5X0, "Armadillo-500")
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params	= PHYS_OFFSET + 0x00000100,
 	.map_io		= mx31_map_io,
-	.init_irq	= mxc_init_irq,
+	.init_irq	= mx31_init_irq,
 	.timer		= &armadillo5x0_timer,
 	.init_machine	= armadillo5x0_init,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 577ee83..fe5c421 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -273,6 +273,19 @@ static unsigned long get_rate_csi(struct clk *clk)
 	return rate / get_3_3_div((pdr2 >> 16) & 0x3f);
 }
 
+static unsigned long get_rate_otg(struct clk *clk)
+{
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long rate;
+
+	if (pdr4 & (1 << 9))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	return rate / get_3_3_div((pdr4 >> 22) & 0x3f);
+}
+
 static unsigned long get_rate_ipg_per(struct clk *clk)
 {
 	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
@@ -365,7 +378,7 @@ DEFINE_CLOCK(ssi2_clk,   1, CCM_CGR2, 14, get_rate_ssi, NULL);
 DEFINE_CLOCK(uart1_clk,  0, CCM_CGR2, 16, get_rate_uart, NULL);
 DEFINE_CLOCK(uart2_clk,  1, CCM_CGR2, 18, get_rate_uart, NULL);
 DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20, get_rate_uart, NULL);
-DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
 DEFINE_CLOCK(wdog_clk,   0, CCM_CGR2, 24, NULL, NULL);
 DEFINE_CLOCK(max_clk,    0, CCM_CGR2, 26, NULL, NULL);
 DEFINE_CLOCK(admux_clk,  0, CCM_CGR2, 30, NULL, NULL);
@@ -426,7 +439,10 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
 	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
 	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
-	_REGISTER_CLOCK(NULL, "usbotg", usbotg_clk)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
 	_REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk)
 	_REGISTER_CLOCK(NULL, "max", max_clk)
 	_REGISTER_CLOCK(NULL, "admux", admux_clk)
@@ -456,7 +472,7 @@ int __init mx35_clocks_init()
 	__raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2);
 	__raw_writel(0, CCM_BASE + CCM_CGR3);
 
-	mxc_timer_init(&gpt_clk);
+	mxc_timer_init(&gpt_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
index 8b14239..06bd618 100644
--- a/arch/arm/mach-mx3/clock.c
+++ b/arch/arm/mach-mx3/clock.c
@@ -29,6 +29,7 @@
 
 #include <mach/clock.h>
 #include <mach/hardware.h>
+#include <mach/mx31.h>
 #include <mach/common.h>
 
 #include "crm_regs.h"
@@ -402,6 +403,11 @@ static unsigned long clk_ckih_get_rate(struct clk *clk)
 	return ckih_rate;
 }
 
+static unsigned long clk_ckil_get_rate(struct clk *clk)
+{
+	return CKIL_CLK_FREQ;
+}
+
 static struct clk ckih_clk = {
 	.get_rate = clk_ckih_get_rate,
 };
@@ -508,6 +514,7 @@ DEFINE_CLOCK(usb_clk1,    0, NULL,          0, usb_get_rate, NULL, &usb_pll_clk)
 DEFINE_CLOCK(nfc_clk,     0, NULL,          0, nfc_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(scc_clk,     0, NULL,          0, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 #define _REGISTER_CLOCK(d, n, c) \
 	{ \
@@ -518,9 +525,9 @@ DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
 
 static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK(NULL, "emi", emi_clk)
-	_REGISTER_CLOCK(NULL, "cspi", cspi1_clk)
-	_REGISTER_CLOCK(NULL, "cspi", cspi2_clk)
-	_REGISTER_CLOCK(NULL, "cspi", cspi3_clk)
+	_REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+	_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+	_REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
 	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
 	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
 	_REGISTER_CLOCK(NULL, "wdog", wdog_clk)
@@ -531,6 +538,12 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
 	_REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
 	_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
 	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
 	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
 	_REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
@@ -559,6 +572,7 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK(NULL, "iim", iim_clk)
 	_REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
 	_REGISTER_CLOCK(NULL, "mbx", mbx_clk)
+	_REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
 };
 
 int __init mx31_clocks_init(unsigned long fref)
@@ -609,7 +623,7 @@ int __init mx31_clocks_init(unsigned long fref)
 		__raw_writel(reg, MXC_CCM_PMCR1);
 	}
 
-	mxc_timer_init(&ipg_clk);
+	mxc_timer_init(&ipg_clk, IO_ADDRESS(GPT1_BASE_ADDR), MXC_INT_GPT);
 
 	return 0;
 }
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index 9e87e08..8a577f3 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -129,19 +129,17 @@ struct platform_device mxc_uart_device4 = {
 
 /* GPIO port description */
 static struct mxc_gpio_port imx_gpio_ports[] = {
-	[0] = {
+	{
 		.chip.label = "gpio-0",
 		.base = IO_ADDRESS(GPIO1_BASE_ADDR),
 		.irq = MXC_INT_GPIO1,
 		.virtual_irq_start = MXC_GPIO_IRQ_START,
-	},
-	[1] = {
+	}, {
 		.chip.label = "gpio-1",
 		.base = IO_ADDRESS(GPIO2_BASE_ADDR),
 		.irq = MXC_INT_GPIO2,
 		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
-	},
-	[2] = {
+	}, {
 		.chip.label = "gpio-2",
 		.base = IO_ADDRESS(GPIO3_BASE_ADDR),
 		.irq = MXC_INT_GPIO3,
@@ -173,11 +171,11 @@ static struct resource mxc_nand_resources[] = {
 	{
 		.start	= 0, /* runtime dependent */
 		.end	= 0,
-		.flags	= IORESOURCE_MEM
+		.flags	= IORESOURCE_MEM,
 	}, {
 		.start	= MXC_INT_NANDFC,
 		.end	= MXC_INT_NANDFC,
-		.flags	= IORESOURCE_IRQ
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -193,8 +191,7 @@ static struct resource mxc_i2c0_resources[] = {
 		.start = I2C_BASE_ADDR,
 		.end = I2C_BASE_ADDR + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
-	},
-	{
+	}, {
 		.start = MXC_INT_I2C,
 		.end = MXC_INT_I2C,
 		.flags = IORESOURCE_IRQ,
@@ -213,8 +210,7 @@ static struct resource mxc_i2c1_resources[] = {
 		.start = I2C2_BASE_ADDR,
 		.end = I2C2_BASE_ADDR + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
-	},
-	{
+	}, {
 		.start = MXC_INT_I2C2,
 		.end = MXC_INT_I2C2,
 		.flags = IORESOURCE_IRQ,
@@ -233,8 +229,7 @@ static struct resource mxc_i2c2_resources[] = {
 		.start = I2C3_BASE_ADDR,
 		.end = I2C3_BASE_ADDR + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
-	},
-	{
+	}, {
 		.start = MXC_INT_I2C3,
 		.end = MXC_INT_I2C3,
 		.flags = IORESOURCE_IRQ,
@@ -371,8 +366,8 @@ struct platform_device mx3_camera = {
 
 static struct resource otg_resources[] = {
 	{
-		.start	= OTG_BASE_ADDR,
-		.end	= OTG_BASE_ADDR + 0x1ff,
+		.start	= MX31_OTG_BASE_ADDR,
+		.end	= MX31_OTG_BASE_ADDR + 0x1ff,
 		.flags	= IORESOURCE_MEM,
 	}, {
 		.start	= MXC_INT_USB3,
@@ -395,16 +390,142 @@ struct platform_device mxc_otg_udc_device = {
 	.num_resources	= ARRAY_SIZE(otg_resources),
 };
 
+/* OTG host */
+struct platform_device mxc_otg_host = {
+	.name = "mxc-ehci",
+	.id = 0,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &otg_dmamask,
+	},
+	.resource = otg_resources,
+	.num_resources = ARRAY_SIZE(otg_resources),
+};
+
+/* USB host 1 */
+
+static u64 usbh1_dmamask = ~(u32)0;
+
+static struct resource mxc_usbh1_resources[] = {
+	{
+		.start = MX31_OTG_BASE_ADDR + 0x200,
+		.end = MX31_OTG_BASE_ADDR + 0x3ff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_USB1,
+		.end = MXC_INT_USB1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_usbh1 = {
+	.name = "mxc-ehci",
+	.id = 1,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &usbh1_dmamask,
+	},
+	.resource = mxc_usbh1_resources,
+	.num_resources = ARRAY_SIZE(mxc_usbh1_resources),
+};
+
+/* USB host 2 */
+static u64 usbh2_dmamask = ~(u32)0;
+
+static struct resource mxc_usbh2_resources[] = {
+	{
+		.start = MX31_OTG_BASE_ADDR + 0x400,
+		.end = MX31_OTG_BASE_ADDR + 0x5ff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_USB2,
+		.end = MXC_INT_USB2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_usbh2 = {
+	.name = "mxc-ehci",
+	.id = 2,
+	.dev = {
+		.coherent_dma_mask = 0xffffffff,
+		.dma_mask = &usbh2_dmamask,
+	},
+	.resource = mxc_usbh2_resources,
+	.num_resources = ARRAY_SIZE(mxc_usbh2_resources),
+};
+
+/*
+ * SPI master controller
+ * 3 channels
+ */
+static struct resource imx_spi_0_resources[] = {
+	{
+	       .start = CSPI1_BASE_ADDR,
+	       .end = CSPI1_BASE_ADDR + SZ_4K - 1,
+	       .flags = IORESOURCE_MEM,
+	}, {
+	       .start = MXC_INT_CSPI1,
+	       .end = MXC_INT_CSPI1,
+	       .flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource imx_spi_1_resources[] = {
+	{
+		.start = CSPI2_BASE_ADDR,
+		.end = CSPI2_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_CSPI2,
+		.end = MXC_INT_CSPI2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource imx_spi_2_resources[] = {
+	{
+		.start = CSPI3_BASE_ADDR,
+		.end = CSPI3_BASE_ADDR + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC_INT_CSPI3,
+		.end = MXC_INT_CSPI3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device imx_spi_device0 = {
+	.name = "spi_imx",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(imx_spi_0_resources),
+	.resource = imx_spi_0_resources,
+};
+
+struct platform_device imx_spi_device1 = {
+	.name = "spi_imx",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(imx_spi_1_resources),
+	.resource = imx_spi_1_resources,
+};
+
+struct platform_device imx_spi_device2 = {
+	.name = "spi_imx",
+	.id = 2,
+	.num_resources = ARRAY_SIZE(imx_spi_2_resources),
+	.resource = imx_spi_2_resources,
+};
+
 #ifdef CONFIG_ARCH_MX35
 static struct resource mxc_fec_resources[] = {
 	{
 		.start	= MXC_FEC_BASE_ADDR,
 		.end	= MXC_FEC_BASE_ADDR + 0xfff,
-		.flags	= IORESOURCE_MEM
+		.flags	= IORESOURCE_MEM,
 	}, {
 		.start	= MXC_INT_FEC,
 		.end	= MXC_INT_FEC,
-		.flags	= IORESOURCE_IRQ
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -426,6 +547,14 @@ static int mx3_devices_init(void)
 	if (cpu_is_mx35()) {
 		mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
 		mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff;
+		otg_resources[0].start = MX35_OTG_BASE_ADDR;
+		otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff;
+		otg_resources[1].start = MXC_INT_USBOTG;
+		otg_resources[1].end = MXC_INT_USBOTG;
+		mxc_usbh1_resources[0].start = MX35_OTG_BASE_ADDR + 0x400;
+		mxc_usbh1_resources[0].end = MX35_OTG_BASE_ADDR + 0x5ff;
+		mxc_usbh1_resources[1].start = MXC_INT_USBHS;
+		mxc_usbh1_resources[1].end = MXC_INT_USBHS;
 	}
 
 	return 0;
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index ffd494d..79f2be4 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -16,5 +16,11 @@ extern struct platform_device mxc_fec_device;
 extern struct platform_device mxcsdhc_device0;
 extern struct platform_device mxcsdhc_device1;
 extern struct platform_device mxc_otg_udc_device;
+extern struct platform_device mxc_otg_host;
+extern struct platform_device mxc_usbh1;
+extern struct platform_device mxc_usbh2;
 extern struct platform_device mxc_rnga_device;
+extern struct platform_device imx_spi_device0;
+extern struct platform_device imx_spi_device1;
+extern struct platform_device imx_spi_device2;
 
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index 1f5fdd4..ad5a112 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -30,6 +30,7 @@
 
 #include <mach/common.h>
 #include <mach/hardware.h>
+#include <mach/iomux-v3.h>
 
 /*!
  * @file mm.c
@@ -75,6 +76,7 @@ static struct map_desc mxc_io_desc[] __initdata = {
 void __init mx31_map_io(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX31);
+	mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
 
 	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
@@ -82,10 +84,22 @@ void __init mx31_map_io(void)
 void __init mx35_map_io(void)
 {
 	mxc_set_cpu_type(MXC_CPU_MX35);
+	mxc_iomux_v3_init(IO_ADDRESS(IOMUXC_BASE_ADDR));
+	mxc_arch_reset_init(IO_ADDRESS(WDOG_BASE_ADDR));
 
 	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
 }
 
+void __init mx31_init_irq(void)
+{
+	mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
+}
+
+void __init mx35_init_irq(void)
+{
+	mx31_init_irq();
+}
+
 #ifdef CONFIG_CACHE_L2X0
 static int mxc_init_l2x0(void)
 {
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
index 30e2767..0497c15 100644
--- a/arch/arm/mach-mx3/mx31ads.c
+++ b/arch/arm/mach-mx3/mx31ads.c
@@ -517,7 +517,7 @@ static void __init mx31ads_map_io(void)
 
 static void __init mx31ads_init_irq(void)
 {
-	mxc_init_irq();
+	mx31_init_irq();
 	mx31ads_init_expio();
 }
 
diff --git a/arch/arm/mach-mx3/mx31lilly.c b/arch/arm/mach-mx3/mx31lilly.c
index 6ab2f16..4230251 100644
--- a/arch/arm/mach-mx3/mx31lilly.c
+++ b/arch/arm/mach-mx3/mx31lilly.c
@@ -148,7 +148,7 @@ MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params	= PHYS_OFFSET + 0x100,
 	.map_io		= mx31_map_io,
-	.init_irq	= mxc_init_irq,
+	.init_irq	= mx31_init_irq,
 	.init_machine	= mx31lilly_board_init,
 	.timer		= &mx31lilly_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c
index 86fe70f..a8d57de 100644
--- a/arch/arm/mach-mx3/mx31lite.c
+++ b/arch/arm/mach-mx3/mx31lite.c
@@ -71,12 +71,11 @@ static struct smsc911x_platform_config smsc911x_config = {
 };
 
 static struct resource smsc911x_resources[] = {
-	[0] = {
+	{
 		.start		= CS4_BASE_ADDR,
 		.end		= CS4_BASE_ADDR + 0x100,
 		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start		= IOMUX_TO_IRQ(MX31_PIN_SFS6),
 		.end		= IOMUX_TO_IRQ(MX31_PIN_SFS6),
 		.flags		= IORESOURCE_IRQ,
@@ -162,7 +161,7 @@ MACHINE_START(MX31LITE, "LogicPD MX31 LITEKIT")
 	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx31lite_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx31_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31lite_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c
index b48581e..5592cdb 100644
--- a/arch/arm/mach-mx3/mx31moboard-devboard.c
+++ b/arch/arm/mach-mx3/mx31moboard-devboard.c
@@ -16,7 +16,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <linux/fsl_devices.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -40,18 +39,6 @@ static unsigned int devboard_pins[] = {
 	MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
 	MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
 	MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
-	/* USB OTG */
-	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
-	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
-	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
-	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
-	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
-	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
-	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
-	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
-	MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
-	MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
-	MX31_PIN_USB_OC__GPIO1_30,
 };
 
 static struct imxuart_platform_data uart_pdata = {
@@ -111,33 +98,6 @@ static struct imxmmc_platform_data sdhc2_pdata = {
 	.exit	= devboard_sdhc2_exit,
 };
 
-static struct fsl_usb2_platform_data usb_pdata = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-#define OTG_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)
-#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
-
-static void devboard_usbotg_init(void)
-{
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, OTG_PAD_CFG);
-
-	gpio_request(OTG_EN_B, "usb-udc-en");
-	gpio_direction_output(OTG_EN_B, 0);
-}
-
 /*
  * system init for baseboard usage. Will be called by mx31moboard init.
  */
@@ -151,7 +111,4 @@ void __init mx31moboard_devboard_init(void)
 	mxc_register_device(&mxc_uart_device1, &uart_pdata);
 
 	mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
-
-	devboard_usbotg_init();
-	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
 }
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c
index 901fb01..2bfaffb 100644
--- a/arch/arm/mach-mx3/mx31moboard-marxbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c
@@ -16,7 +16,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <linux/fsl_devices.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -48,18 +47,8 @@ static unsigned int marxbot_pins[] = {
 	MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC,
 	MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
 	MX31_PIN_TXD2__GPIO1_28,
-	/* USB OTG */
-	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
-	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
-	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
-	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
-	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
-	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
-	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
-	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
-	MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
-	MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
-	MX31_PIN_USB_OC__GPIO1_30,
+	/* dsPIC resets */
+	MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22,
 };
 
 #define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
@@ -115,31 +104,20 @@ static struct imxmmc_platform_data sdhc2_pdata = {
 	.exit	= marxbot_sdhc2_exit,
 };
 
-static struct fsl_usb2_platform_data usb_pdata = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-#define OTG_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST)
-#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
+#define TRSLAT_RST_B	IOMUX_TO_GPIO(MX31_PIN_STXD5)
+#define DSPICS_RST_B	IOMUX_TO_GPIO(MX31_PIN_SRXD5)
 
-static void marxbot_usbotg_init(void)
+static void dspics_resets_init(void)
 {
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, OTG_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, OTG_PAD_CFG);
-
-	gpio_request(OTG_EN_B, "usb-udc-en");
-	gpio_direction_output(OTG_EN_B, 0);
+	if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
+		gpio_direction_output(TRSLAT_RST_B, 1);
+		gpio_export(TRSLAT_RST_B, false);
+	}
+
+	if (!gpio_request(DSPICS_RST_B, "dspics-rst")) {
+		gpio_direction_output(DSPICS_RST_B, 1);
+		gpio_export(DSPICS_RST_B, false);
+	}
 }
 
 /*
@@ -152,8 +130,7 @@ void __init mx31moboard_marxbot_init(void)
 	mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins),
 		"marxbot");
 
-	mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
+	dspics_resets_init();
 
-	marxbot_usbotg_init();
-	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+	mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
 }
diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c
index 2a2da47..9243de5 100644
--- a/arch/arm/mach-mx3/mx31moboard.c
+++ b/arch/arm/mach-mx3/mx31moboard.c
@@ -16,9 +16,12 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/delay.h>
+#include <linux/fsl_devices.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/leds.h>
 #include <linux/memory.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
@@ -36,6 +39,7 @@
 #include <mach/iomux-mx3.h>
 #include <mach/i2c.h>
 #include <mach/mmc.h>
+#include <mach/mx31.h>
 
 #include "devices.h"
 
@@ -55,6 +59,26 @@ static unsigned int moboard_pins[] = {
 	MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0,
 	MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD,
 	MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
+	/* USB reset */
+	MX31_PIN_GPIO1_0__GPIO1_0,
+	/* USB OTG */
+	MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+	MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+	MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+	MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+	MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+	MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+	MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+	MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+	MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+	MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
+	MX31_PIN_USB_OC__GPIO1_30,
+	/* LEDs */
+	MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
+	MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
+	/* SEL */
+	MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+	MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
 };
 
 static struct physmap_flash_data mx31moboard_flash_data = {
@@ -142,8 +166,109 @@ static struct imxmmc_platform_data sdhc1_pdata = {
 	.exit	= moboard_sdhc1_exit,
 };
 
+/*
+ * this pin is dedicated for all mx31moboard systems, so we do it here
+ */
+#define USB_RESET_B	IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
+
+static void usb_xcvr_reset(void)
+{
+	gpio_request(USB_RESET_B, "usb-reset");
+	gpio_direction_output(USB_RESET_B, 0);
+	mdelay(1);
+	gpio_set_value(USB_RESET_B, 1);
+}
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
+
+static void moboard_usbotg_init(void)
+{
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+	gpio_request(OTG_EN_B, "usb-udc-en");
+	gpio_direction_output(OTG_EN_B, 0);
+}
+
+static struct fsl_usb2_platform_data usb_pdata = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_ULPI,
+};
+
+static struct gpio_led mx31moboard_leds[] = {
+	{
+		.name 	= "coreboard-led-0:red:running",
+		.default_trigger = "heartbeat",
+		.gpio 	= IOMUX_TO_GPIO(MX31_PIN_SVEN0),
+	}, {
+		.name	= "coreboard-led-1:red",
+		.gpio	= IOMUX_TO_GPIO(MX31_PIN_STX0),
+	}, {
+		.name	= "coreboard-led-2:red",
+		.gpio	= IOMUX_TO_GPIO(MX31_PIN_SRX0),
+	}, {
+		.name	= "coreboard-led-3:red",
+		.gpio	= IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
+	},
+};
+
+static struct gpio_led_platform_data mx31moboard_led_pdata = {
+	.num_leds 	= ARRAY_SIZE(mx31moboard_leds),
+	.leds		= mx31moboard_leds,
+};
+
+static struct platform_device mx31moboard_leds_device = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data = &mx31moboard_led_pdata,
+	},
+};
+
+#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void mx31moboard_init_sel_gpios(void)
+{
+	if (!gpio_request(SEL0, "sel0")) {
+		gpio_direction_input(SEL0);
+		gpio_export(SEL0, true);
+	}
+
+	if (!gpio_request(SEL1, "sel1")) {
+		gpio_direction_input(SEL1);
+		gpio_export(SEL1, true);
+	}
+
+	if (!gpio_request(SEL2, "sel2")) {
+		gpio_direction_input(SEL2);
+		gpio_export(SEL2, true);
+	}
+
+	if (!gpio_request(SEL3, "sel3")) {
+		gpio_direction_input(SEL3);
+		gpio_export(SEL3, true);
+	}
+}
+
 static struct platform_device *devices[] __initdata = {
 	&mx31moboard_flash,
+	&mx31moboard_leds_device,
 };
 
 static int mx31moboard_baseboard;
@@ -162,11 +287,18 @@ static void __init mxc_board_init(void)
 	mxc_register_device(&mxc_uart_device0, &uart_pdata);
 	mxc_register_device(&mxc_uart_device4, &uart_pdata);
 
+	mx31moboard_init_sel_gpios();
+
 	mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
 	mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
 
 	mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
 
+	usb_xcvr_reset();
+
+	moboard_usbotg_init();
+	mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+
 	switch (mx31moboard_baseboard) {
 	case MX31NOBOARD:
 		break;
@@ -197,7 +329,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx31_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx31_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31moboard_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c
index c19838d..0f7a2f0 100644
--- a/arch/arm/mach-mx3/mx31pdk.c
+++ b/arch/arm/mach-mx3/mx31pdk.c
@@ -265,7 +265,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx31pdk_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx31_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx31pdk_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/mx35pdk.c b/arch/arm/mach-mx3/mx35pdk.c
index 6d15374..6ff186e 100644
--- a/arch/arm/mach-mx3/mx35pdk.c
+++ b/arch/arm/mach-mx3/mx35pdk.c
@@ -98,7 +98,7 @@ MACHINE_START(MX35_3DS, "Freescale MX35PDK")
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx35_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx35_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &mx35pdk_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c
index 840cfda..6cbaabe 100644
--- a/arch/arm/mach-mx3/pcm037.c
+++ b/arch/arm/mach-mx3/pcm037.c
@@ -32,6 +32,7 @@
 #include <linux/spi/spi.h>
 #include <linux/irq.h>
 #include <linux/fsl_devices.h>
+#include <linux/can/platform/sja1000.h>
 
 #include <media/soc_camera.h>
 
@@ -169,6 +170,8 @@ static unsigned int pcm037_pins[] = {
 	MX31_PIN_CSI_MCLK__CSI_MCLK,
 	MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
 	MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+	/* GPIO */
+	IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO),
 };
 
 static struct physmap_flash_data pcm037_flash_data = {
@@ -244,12 +247,11 @@ static struct imxuart_platform_data uart_pdata = {
 };
 
 static struct resource smsc911x_resources[] = {
-	[0] = {
+	{
 		.start		= CS1_BASE_ADDR + 0x300,
 		.end		= CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
 		.flags		= IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
 		.end		= IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
 		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
@@ -339,8 +341,7 @@ static struct i2c_board_info pcm037_i2c_devices[] = {
 		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
 		.platform_data = &board_eeprom,
 	}, {
-		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
-		.type = "pcf8563",
+		I2C_BOARD_INFO("pcf8563", 0x51),
 	}
 };
 
@@ -515,6 +516,33 @@ static struct mx3fb_platform_data mx3fb_pdata = {
 	.num_modes	= ARRAY_SIZE(fb_modedb),
 };
 
+static struct resource pcm970_sja1000_resources[] = {
+	{
+		.start   = CS5_BASE_ADDR,
+		.end     = CS5_BASE_ADDR + 0x100 - 1,
+		.flags   = IORESOURCE_MEM,
+	}, {
+		.start   = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+		.end     = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+		.flags   = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+	},
+};
+
+struct sja1000_platform_data pcm970_sja1000_platform_data = {
+	.clock		= 16000000 / 2,
+	.ocr		= 0x40 | 0x18,
+	.cdr		= 0x40,
+};
+
+static struct platform_device pcm970_sja1000 = {
+	.name = "sja1000_platform",
+	.dev = {
+		.platform_data = &pcm970_sja1000_platform_data,
+	},
+	.resource = pcm970_sja1000_resources,
+	.num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
+};
+
 /*
  * Board specific initialization.
  */
@@ -575,6 +603,8 @@ static void __init mxc_board_init(void)
 
 	if (!pcm037_camera_alloc_dma(4 * 1024 * 1024))
 		mxc_register_device(&mx3_camera, &camera_pdata);
+
+	platform_device_register(&pcm970_sja1000);
 }
 
 static void __init pcm037_timer_init(void)
@@ -592,7 +622,7 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037")
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx31_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx31_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &pcm037_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/pcm043.c b/arch/arm/mach-mx3/pcm043.c
index 8d27c32..e18a224 100644
--- a/arch/arm/mach-mx3/pcm043.c
+++ b/arch/arm/mach-mx3/pcm043.c
@@ -133,8 +133,7 @@ static struct i2c_board_info pcm043_i2c_devices[] = {
 		I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
 		.platform_data = &board_eeprom,
 	}, {
-		I2C_BOARD_INFO("rtc-pcf8563", 0x51),
-		.type = "pcf8563",
+		I2C_BOARD_INFO("pcf8563", 0x51),
 	}
 };
 #endif
@@ -203,7 +202,8 @@ static struct pad_desc pcm043_pads[] = {
 	MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
 	MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
 	MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
-	MX35_PAD_D3_SPL__IPU_DISPB_D3_SPL
+	/* gpio */
+	MX35_PAD_ATA_CS0__GPIO2_6,
 };
 
 /*
@@ -245,7 +245,7 @@ MACHINE_START(PCM043, "Phytec Phycore pcm043")
 	.io_pg_offst	= ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx35_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx35_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &pcm043_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c
index 82b31c4..044511f 100644
--- a/arch/arm/mach-mx3/qong.c
+++ b/arch/arm/mach-mx3/qong.c
@@ -81,13 +81,12 @@ static inline void mxc_init_imx_uart(void)
 }
 
 static struct resource dnet_resources[] = {
-	[0] = {
+	{
 		.name	= "dnet-memory",
 		.start	= QONG_DNET_BASEADDR,
 		.end	= QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
 		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
+	}, {
 		.start	= QONG_FPGA_IRQ,
 		.end	= QONG_FPGA_IRQ,
 		.flags	= IORESOURCE_IRQ,
@@ -280,7 +279,7 @@ MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
 	.io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 	.boot_params    = PHYS_OFFSET + 0x100,
 	.map_io         = mx31_map_io,
-	.init_irq       = mxc_init_irq,
+	.init_irq       = mx31_init_irq,
 	.init_machine   = mxc_board_init,
 	.timer          = &qong_timer,
 MACHINE_END
diff --git a/arch/arm/mach-mxc91231/Kconfig b/arch/arm/mach-mxc91231/Kconfig
new file mode 100644
index 0000000..8e5fa38
--- /dev/null
+++ b/arch/arm/mach-mxc91231/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_MXC91231
+
+comment "MXC91231 platforms:"
+
+config MACH_MAGX_ZN5
+	bool "Support Motorola Zn5 GSM phone"
+	default n
+	help
+	  Include support for Motorola Zn5 GSM phone.
+
+endif
diff --git a/arch/arm/mach-mxc91231/Makefile b/arch/arm/mach-mxc91231/Makefile
new file mode 100644
index 0000000..011d5e1
--- /dev/null
+++ b/arch/arm/mach-mxc91231/Makefile
@@ -0,0 +1,2 @@
+obj-y	:= mm.o clock.o devices.o system.o iomux.o
+obj-$(CONFIG_MACH_MAGX_ZN5) += magx-zn5.o
diff --git a/arch/arm/mach-mxc91231/Makefile.boot b/arch/arm/mach-mxc91231/Makefile.boot
new file mode 100644
index 0000000..9939a19
--- /dev/null
+++ b/arch/arm/mach-mxc91231/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x90008000
+params_phys-y	:= 0x90000100
+initrd_phys-y	:= 0x90800000
diff --git a/arch/arm/mach-mxc91231/clock.c b/arch/arm/mach-mxc91231/clock.c
new file mode 100644
index 0000000..ecfa37f
--- /dev/null
+++ b/arch/arm/mach-mxc91231/clock.c
@@ -0,0 +1,642 @@
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include <asm/clkdev.h>
+#include <asm/bug.h>
+#include <asm/div64.h>
+
+#include "crm_regs.h"
+
+#define CRM_SMALL_DIVIDER(base, name) \
+	crm_small_divider(base, \
+			  base ## _ ## name ## _OFFSET, \
+			  base ## _ ## name ## _MASK)
+#define CRM_1DIVIDER(base, name) \
+	crm_divider(base, \
+		    base ## _ ## name ## _OFFSET, \
+		    base ## _ ## name ## _MASK, 1)
+#define CRM_16DIVIDER(base, name) \
+	crm_divider(base, \
+		    base ## _ ## name ## _OFFSET, \
+		    base ## _ ## name ## _MASK, 16)
+
+static u32 crm_small_divider(void __iomem *reg, u8 offset, u32 mask)
+{
+	static const u32 crm_small_dividers[] = {
+		2, 3, 4, 5, 6, 8, 10, 12
+	};
+	u8 idx;
+
+	idx = (__raw_readl(reg) & mask) >> offset;
+	if (idx > 7)
+		return 1;
+
+	return crm_small_dividers[idx];
+}
+
+static u32 crm_divider(void __iomem *reg, u8 offset, u32 mask, u32 z)
+{
+	u32 div;
+	div = (__raw_readl(reg) & mask) >> offset;
+	return div ? div : z;
+}
+
+static int _clk_1bit_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 1 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void _clk_1bit_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(1 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_3bit_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 0x7 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void _clk_3bit_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(0x7 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+static unsigned long ckih_rate;
+
+static unsigned long clk_ckih_get_rate(struct clk *clk)
+{
+	return ckih_rate;
+}
+
+static struct clk ckih_clk = {
+	.get_rate = clk_ckih_get_rate,
+};
+
+static unsigned long clk_ckih_x2_get_rate(struct clk *clk)
+{
+	return 2 * clk_get_rate(clk->parent);
+}
+
+static struct clk ckih_x2_clk = {
+	.parent = &ckih_clk,
+	.get_rate = clk_ckih_x2_get_rate,
+};
+
+static unsigned long clk_ckil_get_rate(struct clk *clk)
+{
+	return CKIL_CLK_FREQ;
+}
+
+static struct clk ckil_clk = {
+	.get_rate = clk_ckil_get_rate,
+};
+
+/* plls stuff */
+static struct clk mcu_pll_clk;
+static struct clk dsp_pll_clk;
+static struct clk usb_pll_clk;
+
+static struct clk *pll_clk(u8 sel)
+{
+	switch (sel) {
+	case 0:
+		return &mcu_pll_clk;
+	case 1:
+		return &dsp_pll_clk;
+	case 2:
+		return &usb_pll_clk;
+	}
+	BUG();
+}
+
+static void __iomem *pll_base(struct clk *clk)
+{
+	if (clk == &mcu_pll_clk)
+		return MXC_PLL0_BASE;
+	else if (clk == &dsp_pll_clk)
+		return MXC_PLL1_BASE;
+	else if (clk == &usb_pll_clk)
+		return MXC_PLL2_BASE;
+	BUG();
+}
+
+static unsigned long clk_pll_get_rate(struct clk *clk)
+{
+	const void __iomem *pllbase;
+	unsigned long dp_op, dp_mfd, dp_mfn, pll_hfsm, ref_clk, mfi;
+	long mfn, mfn_abs, mfd, pdf;
+	s64 temp;
+	pllbase = pll_base(clk);
+
+	pll_hfsm = __raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_HFSM;
+	if (pll_hfsm == 0) {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+	} else {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+	}
+
+	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+	mfi = (dp_op >> MXC_PLL_DP_OP_MFI_OFFSET) & MXC_PLL_DP_OP_PDF_MASK;
+	mfi = (mfi <= 5) ? 5 : mfi;
+	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+	mfn = dp_mfn & MXC_PLL_DP_MFN_MASK;
+	mfn = (mfn <= 0x4000000) ? mfn : (mfn - 0x10000000);
+
+	if (mfn < 0)
+		mfn_abs = -mfn;
+	else
+		mfn_abs = mfn;
+
+/* XXX: actually this asumes that ckih is fed to pll, but spec says
+ * that ckih_x2 is also possible. need to check this out.
+ */
+	ref_clk = clk_get_rate(&ckih_clk);
+
+	ref_clk *= 2;
+	ref_clk /= pdf + 1;
+
+	temp = (u64) ref_clk * mfn_abs;
+	do_div(temp, mfd);
+	if (mfn < 0)
+		temp = -temp;
+	temp += ref_clk * mfi;
+
+	return temp;
+}
+
+static int clk_pll_enable(struct clk *clk)
+{
+	void __iomem *ctl;
+	u32 reg;
+
+	ctl = pll_base(clk);
+	reg = __raw_readl(ctl);
+	reg |= (MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN);
+	__raw_writel(reg, ctl);
+	do {
+		reg = __raw_readl(ctl);
+	} while ((reg & MXC_PLL_DP_CTL_LRF) != MXC_PLL_DP_CTL_LRF);
+	return 0;
+}
+
+static void clk_pll_disable(struct clk *clk)
+{
+	void __iomem *ctl;
+	u32 reg;
+
+	ctl = pll_base(clk);
+	reg = __raw_readl(ctl);
+	reg &= ~(MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN);
+	__raw_writel(reg, ctl);
+}
+
+static struct clk mcu_pll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = clk_pll_get_rate,
+	.enable = clk_pll_enable,
+	.disable = clk_pll_disable,
+};
+
+static struct clk dsp_pll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = clk_pll_get_rate,
+	.enable = clk_pll_enable,
+	.disable = clk_pll_disable,
+};
+
+static struct clk usb_pll_clk = {
+	.parent = &ckih_clk,
+	.get_rate = clk_pll_get_rate,
+	.enable = clk_pll_enable,
+	.disable = clk_pll_disable,
+};
+/* plls stuff end */
+
+/* ap_ref_clk stuff */
+static struct clk ap_ref_clk;
+
+static unsigned long clk_ap_ref_get_rate(struct clk *clk)
+{
+	u32 ascsr, acsr;
+	u8 ap_pat_ref_div_2, ap_isel, acs, ads;
+
+	ascsr = __raw_readl(MXC_CRMAP_ASCSR);
+	acsr = __raw_readl(MXC_CRMAP_ACSR);
+
+	/* 0 for ckih, 1 for ckih*2 */
+	ap_isel = ascsr & MXC_CRMAP_ASCSR_APISEL;
+	/* reg divider */
+	ap_pat_ref_div_2 = (ascsr >> MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET) & 0x1;
+	/* undocumented, 1 for disabling divider */
+	ads = (acsr >> MXC_CRMAP_ACSR_ADS_OFFSET) & 0x1;
+	/* 0 for pat_ref, 1 for divider out */
+	acs = acsr & MXC_CRMAP_ACSR_ACS;
+
+	if (acs & !ads)
+		/* use divided clock */
+		return clk_get_rate(clk->parent) / (ap_pat_ref_div_2 ? 2 : 1);
+
+	return clk_get_rate(clk->parent) * (ap_isel ? 2 : 1);
+}
+
+static struct clk ap_ref_clk = {
+	.parent = &ckih_clk,
+	.get_rate = clk_ap_ref_get_rate,
+};
+/* ap_ref_clk stuff end */
+
+/* ap_pre_dfs_clk stuff */
+static struct clk ap_pre_dfs_clk;
+
+static unsigned long clk_ap_pre_dfs_get_rate(struct clk *clk)
+{
+	u32 acsr, ascsr;
+
+	acsr = __raw_readl(MXC_CRMAP_ACSR);
+	ascsr = __raw_readl(MXC_CRMAP_ASCSR);
+
+	if (acsr & MXC_CRMAP_ACSR_ACS) {
+		u8 sel;
+		sel = (ascsr & MXC_CRMAP_ASCSR_APSEL_MASK) >>
+			MXC_CRMAP_ASCSR_APSEL_OFFSET;
+		return clk_get_rate(pll_clk(sel)) /
+			CRM_SMALL_DIVIDER(MXC_CRMAP_ACDR, ARMDIV);
+	}
+	return clk_get_rate(&ap_ref_clk);
+}
+
+static struct clk ap_pre_dfs_clk = {
+	.get_rate = clk_ap_pre_dfs_get_rate,
+};
+/* ap_pre_dfs_clk stuff end */
+
+/* usb_clk stuff */
+static struct clk usb_clk;
+
+static struct clk *clk_usb_parent(struct clk *clk)
+{
+	u32 acsr, ascsr;
+
+	acsr = __raw_readl(MXC_CRMAP_ACSR);
+	ascsr = __raw_readl(MXC_CRMAP_ASCSR);
+
+	if (acsr & MXC_CRMAP_ACSR_ACS) {
+		u8 sel;
+		sel = (ascsr & MXC_CRMAP_ASCSR_USBSEL_MASK) >>
+			MXC_CRMAP_ASCSR_USBSEL_OFFSET;
+		return pll_clk(sel);
+	}
+	return &ap_ref_clk;
+}
+
+static unsigned long clk_usb_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) /
+		CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, USBDIV);
+}
+
+static struct clk usb_clk = {
+	.enable_reg = MXC_CRMAP_ACDER2,
+	.enable_shift = MXC_CRMAP_ACDER2_USBEN_OFFSET,
+	.get_rate = clk_usb_get_rate,
+	.enable = _clk_1bit_enable,
+	.disable = _clk_1bit_disable,
+};
+/* usb_clk stuff end */
+
+static unsigned long clk_ipg_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / CRM_16DIVIDER(MXC_CRMAP_ACDR, IPDIV);
+}
+
+static unsigned long clk_ahb_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) /
+		CRM_16DIVIDER(MXC_CRMAP_ACDR, AHBDIV);
+}
+
+static struct clk ipg_clk = {
+	.parent = &ap_pre_dfs_clk,
+	.get_rate = clk_ipg_get_rate,
+};
+
+static struct clk ahb_clk = {
+	.parent = &ap_pre_dfs_clk,
+	.get_rate = clk_ahb_get_rate,
+};
+
+/* perclk_clk stuff */
+static struct clk perclk_clk;
+
+static unsigned long clk_perclk_get_rate(struct clk *clk)
+{
+	u32 acder2;
+
+	acder2 = __raw_readl(MXC_CRMAP_ACDER2);
+	if (acder2 & MXC_CRMAP_ACDER2_BAUD_ISEL_MASK)
+		return 2 * clk_get_rate(clk->parent);
+
+	return clk_get_rate(clk->parent);
+}
+
+static struct clk perclk_clk = {
+	.parent = &ckih_clk,
+	.get_rate = clk_perclk_get_rate,
+};
+/* perclk_clk stuff end */
+
+/* uart_clk stuff */
+static struct clk uart_clk[];
+
+static unsigned long clk_uart_get_rate(struct clk *clk)
+{
+	u32 div;
+
+	switch (clk->id) {
+	case 0:
+	case 1:
+		div = CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, BAUDDIV);
+		break;
+	case 2:
+		div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRA, UART3DIV);
+		break;
+	default:
+		BUG();
+	}
+	return clk_get_rate(clk->parent) / div;
+}
+
+static struct clk uart_clk[] = {
+	{
+		.id = 0,
+		.parent = &perclk_clk,
+		.enable_reg = MXC_CRMAP_APRA,
+		.enable_shift = MXC_CRMAP_APRA_UART1EN_OFFSET,
+		.get_rate = clk_uart_get_rate,
+		.enable = _clk_1bit_enable,
+		.disable = _clk_1bit_disable,
+	}, {
+		.id = 1,
+		.parent = &perclk_clk,
+		.enable_reg = MXC_CRMAP_APRA,
+		.enable_shift = MXC_CRMAP_APRA_UART2EN_OFFSET,
+		.get_rate = clk_uart_get_rate,
+		.enable = _clk_1bit_enable,
+		.disable = _clk_1bit_disable,
+	}, {
+		.id = 2,
+		.parent = &perclk_clk,
+		.enable_reg = MXC_CRMAP_APRA,
+		.enable_shift = MXC_CRMAP_APRA_UART3EN_OFFSET,
+		.get_rate = clk_uart_get_rate,
+		.enable = _clk_1bit_enable,
+		.disable = _clk_1bit_disable,
+	},
+};
+/* uart_clk stuff end */
+
+/* sdhc_clk stuff */
+static struct clk nfc_clk;
+
+static unsigned long clk_nfc_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) /
+		CRM_1DIVIDER(MXC_CRMAP_ACDER2, NFCDIV);
+}
+
+static struct clk nfc_clk = {
+	.parent = &ahb_clk,
+	.enable_reg = MXC_CRMAP_ACDER2,
+	.enable_shift = MXC_CRMAP_ACDER2_NFCEN_OFFSET,
+	.get_rate = clk_nfc_get_rate,
+	.enable = _clk_1bit_enable,
+	.disable = _clk_1bit_disable,
+};
+/* sdhc_clk stuff end */
+
+/* sdhc_clk stuff */
+static struct clk sdhc_clk[];
+
+static struct clk *clk_sdhc_parent(struct clk *clk)
+{
+	u32 aprb;
+	u8 sel;
+	u32 mask;
+	int offset;
+
+	aprb = __raw_readl(MXC_CRMAP_APRB);
+
+	switch (clk->id) {
+	case 0:
+		mask = MXC_CRMAP_APRB_SDHC1_ISEL_MASK;
+		offset = MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET;
+		break;
+	case 1:
+		mask = MXC_CRMAP_APRB_SDHC2_ISEL_MASK;
+		offset = MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET;
+		break;
+	default:
+		BUG();
+	}
+	sel = (aprb & mask) >> offset;
+
+	switch (sel) {
+	case 0:
+		return &ckih_clk;
+	case 1:
+		return &ckih_x2_clk;
+	}
+	return &usb_clk;
+}
+
+static unsigned long clk_sdhc_get_rate(struct clk *clk)
+{
+	u32 div;
+
+	switch (clk->id) {
+	case 0:
+		div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC1_DIV);
+		break;
+	case 1:
+		div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC2_DIV);
+		break;
+	default:
+		BUG();
+	}
+
+	return clk_get_rate(clk->parent) / div;
+}
+
+static int clk_sdhc_enable(struct clk *clk)
+{
+	u32 amlpmre1, aprb;
+
+	amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1);
+	aprb = __raw_readl(MXC_CRMAP_APRB);
+	switch (clk->id) {
+	case 0:
+		amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET);
+		aprb |= (0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET);
+		break;
+	case 1:
+		amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET);
+		aprb |= (0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET);
+		break;
+	}
+	__raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1);
+	__raw_writel(aprb, MXC_CRMAP_APRB);
+	return 0;
+}
+
+static void clk_sdhc_disable(struct clk *clk)
+{
+	u32 amlpmre1, aprb;
+
+	amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1);
+	aprb = __raw_readl(MXC_CRMAP_APRB);
+	switch (clk->id) {
+	case 0:
+		amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET);
+		aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET);
+		break;
+	case 1:
+		amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET);
+		aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET);
+		break;
+	}
+	__raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1);
+	__raw_writel(aprb, MXC_CRMAP_APRB);
+}
+
+static struct clk sdhc_clk[] = {
+	{
+		.id = 0,
+		.get_rate = clk_sdhc_get_rate,
+		.enable = clk_sdhc_enable,
+		.disable = clk_sdhc_disable,
+	}, {
+		.id = 1,
+		.get_rate = clk_sdhc_get_rate,
+		.enable = clk_sdhc_enable,
+		.disable = clk_sdhc_disable,
+	},
+};
+/* sdhc_clk stuff end */
+
+/* wdog_clk stuff */
+static struct clk wdog_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable_reg = MXC_CRMAP_AMLPMRD,
+		.enable_shift = MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET,
+		.enable = _clk_3bit_enable,
+		.disable = _clk_3bit_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable_reg = MXC_CRMAP_AMLPMRD,
+		.enable_shift = MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET,
+		.enable = _clk_3bit_enable,
+		.disable = _clk_3bit_disable,
+	},
+};
+/* wdog_clk stuff end */
+
+/* gpt_clk stuff */
+static struct clk gpt_clk = {
+	.parent = &ipg_clk,
+	.enable_reg = MXC_CRMAP_AMLPMRC,
+	.enable_shift = MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET,
+	.enable = _clk_3bit_enable,
+	.disable = _clk_3bit_disable,
+};
+/* gpt_clk stuff end */
+
+/* cspi_clk stuff */
+static struct clk cspi_clk[] = {
+	{
+		.id = 0,
+		.parent = &ipg_clk,
+		.enable_reg = MXC_CRMAP_AMLPMRE2,
+		.enable_shift = MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET,
+		.enable = _clk_3bit_enable,
+		.disable = _clk_3bit_disable,
+	}, {
+		.id = 1,
+		.parent = &ipg_clk,
+		.enable_reg = MXC_CRMAP_AMLPMRE1,
+		.enable_shift = MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET,
+		.enable = _clk_3bit_enable,
+		.disable = _clk_3bit_disable,
+	},
+};
+/* cspi_clk stuff end */
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
+	_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc_clk[0])
+	_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc_clk[1])
+	_REGISTER_CLOCK("mxc-wdt.0", NULL, wdog_clk[0])
+	_REGISTER_CLOCK("spi_imx.0", NULL, cspi_clk[0])
+	_REGISTER_CLOCK("spi_imx.1", NULL, cspi_clk[1])
+};
+
+int __init mxc91231_clocks_init(unsigned long fref)
+{
+	void __iomem *gpt_base;
+	int i;
+
+	ckih_rate = fref;
+
+	usb_clk.parent = clk_usb_parent(&usb_clk);
+	sdhc_clk[0].parent = clk_sdhc_parent(&sdhc_clk[0]);
+	sdhc_clk[1].parent = clk_sdhc_parent(&sdhc_clk[1]);
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	gpt_base = MXC91231_IO_ADDRESS(MXC91231_GPT1_BASE_ADDR);
+	mxc_timer_init(&gpt_clk, gpt_base, MXC91231_INT_GPT);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mxc91231/crm_regs.h b/arch/arm/mach-mxc91231/crm_regs.h
new file mode 100644
index 0000000..ce4f590
--- /dev/null
+++ b/arch/arm/mach-mxc91231/crm_regs.h
@@ -0,0 +1,399 @@
+/*
+ * Copyright 2006 Freescale Semiconductor, Inc.
+ * Copyright 2006-2007 Motorola, 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 _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_
+#define _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_
+
+#define CKIL_CLK_FREQ			32768
+
+#define MXC_CRM_AP_BASE			MXC91231_IO_ADDRESS(MXC91231_CRM_AP_BASE_ADDR)
+#define MXC_CRM_COM_BASE		MXC91231_IO_ADDRESS(MXC91231_CRM_COM_BASE_ADDR)
+#define MXC_DSM_BASE			MXC91231_IO_ADDRESS(MXC91231_DSM_BASE_ADDR)
+#define MXC_PLL0_BASE			MXC91231_IO_ADDRESS(MXC91231_PLL0_BASE_ADDR)
+#define MXC_PLL1_BASE			MXC91231_IO_ADDRESS(MXC91231_PLL1_BASE_ADDR)
+#define MXC_PLL2_BASE			MXC91231_IO_ADDRESS(MXC91231_PLL2_BASE_ADDR)
+#define MXC_CLKCTL_BASE			MXC91231_IO_ADDRESS(MXC91231_CLKCTL_BASE_ADDR)
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL			0x00
+#define MXC_PLL_DP_CONFIG		0x04
+#define MXC_PLL_DP_OP			0x08
+#define MXC_PLL_DP_MFD			0x0C
+#define MXC_PLL_DP_MFN			0x10
+#define MXC_PLL_DP_HFS_OP		0x1C
+#define MXC_PLL_DP_HFS_MFD		0x20
+#define MXC_PLL_DP_HFS_MFN		0x24
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN	0x1000
+#define MXC_PLL_DP_CTL_ADE		0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV	0x400
+#define MXC_PLL_DP_CTL_HFSM		0x80
+#define MXC_PLL_DP_CTL_PRE		0x40
+#define MXC_PLL_DP_CTL_UPEN		0x20
+#define MXC_PLL_DP_CTL_RST		0x10
+#define MXC_PLL_DP_CTL_RCP		0x8
+#define MXC_PLL_DP_CTL_PLM		0x4
+#define MXC_PLL_DP_CTL_BRM0		0x2
+#define MXC_PLL_DP_CTL_LRF		0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET	4
+#define MXC_PLL_DP_OP_MFI_MASK		0xF
+#define MXC_PLL_DP_OP_PDF_OFFSET	0
+#define MXC_PLL_DP_OP_PDF_MASK		0xF
+
+#define MXC_PLL_DP_MFD_OFFSET		0
+#define MXC_PLL_DP_MFD_MASK		0x7FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET		0
+#define MXC_PLL_DP_MFN_MASK		0x7FFFFFF
+
+/* CRM AP Register Offsets */
+#define MXC_CRMAP_ASCSR			(MXC_CRM_AP_BASE + 0x00)
+#define MXC_CRMAP_ACDR			(MXC_CRM_AP_BASE + 0x04)
+#define MXC_CRMAP_ACDER1		(MXC_CRM_AP_BASE + 0x08)
+#define MXC_CRMAP_ACDER2		(MXC_CRM_AP_BASE + 0x0C)
+#define MXC_CRMAP_ACGCR			(MXC_CRM_AP_BASE + 0x10)
+#define MXC_CRMAP_ACCGCR		(MXC_CRM_AP_BASE + 0x14)
+#define MXC_CRMAP_AMLPMRA		(MXC_CRM_AP_BASE + 0x18)
+#define MXC_CRMAP_AMLPMRB		(MXC_CRM_AP_BASE + 0x1C)
+#define MXC_CRMAP_AMLPMRC		(MXC_CRM_AP_BASE + 0x20)
+#define MXC_CRMAP_AMLPMRD		(MXC_CRM_AP_BASE + 0x24)
+#define MXC_CRMAP_AMLPMRE1		(MXC_CRM_AP_BASE + 0x28)
+#define MXC_CRMAP_AMLPMRE2		(MXC_CRM_AP_BASE + 0x2C)
+#define MXC_CRMAP_AMLPMRF		(MXC_CRM_AP_BASE + 0x30)
+#define MXC_CRMAP_AMLPMRG		(MXC_CRM_AP_BASE + 0x34)
+#define MXC_CRMAP_APGCR			(MXC_CRM_AP_BASE + 0x38)
+#define MXC_CRMAP_ACSR			(MXC_CRM_AP_BASE + 0x3C)
+#define MXC_CRMAP_ADCR			(MXC_CRM_AP_BASE + 0x40)
+#define MXC_CRMAP_ACR			(MXC_CRM_AP_BASE + 0x44)
+#define MXC_CRMAP_AMCR			(MXC_CRM_AP_BASE + 0x48)
+#define MXC_CRMAP_APCR			(MXC_CRM_AP_BASE + 0x4C)
+#define MXC_CRMAP_AMORA			(MXC_CRM_AP_BASE + 0x50)
+#define MXC_CRMAP_AMORB			(MXC_CRM_AP_BASE + 0x54)
+#define MXC_CRMAP_AGPR			(MXC_CRM_AP_BASE + 0x58)
+#define MXC_CRMAP_APRA			(MXC_CRM_AP_BASE + 0x5C)
+#define MXC_CRMAP_APRB			(MXC_CRM_AP_BASE + 0x60)
+#define MXC_CRMAP_APOR			(MXC_CRM_AP_BASE + 0x64)
+#define MXC_CRMAP_ADFMR			(MXC_CRM_AP_BASE + 0x68)
+
+/* CRM AP Register Bit definitions */
+#define MXC_CRMAP_ASCSR_CRS			0x10000
+#define MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET	15
+#define MXC_CRMAP_ASCSR_AP_PATREF_DIV2		0x8000
+#define MXC_CRMAP_ASCSR_USBSEL_OFFSET		13
+#define MXC_CRMAP_ASCSR_USBSEL_MASK		(0x3 << 13)
+#define MXC_CRMAP_ASCSR_CSISEL_OFFSET		11
+#define MXC_CRMAP_ASCSR_CSISEL_MASK		(0x3 << 11)
+#define MXC_CRMAP_ASCSR_SSI2SEL_OFFSET		7
+#define MXC_CRMAP_ASCSR_SSI2SEL_MASK		(0x3 << 7)
+#define MXC_CRMAP_ASCSR_SSI1SEL_OFFSET		5
+#define MXC_CRMAP_ASCSR_SSI1SEL_MASK		(0x3 << 5)
+#define MXC_CRMAP_ASCSR_APSEL_OFFSET		3
+#define MXC_CRMAP_ASCSR_APSEL_MASK		(0x3 << 3)
+#define MXC_CRMAP_ASCSR_AP_PATDIV1_OFFSET	2
+#define MXC_CRMAP_ASCSR_AP_PATREF_DIV1		0x4
+#define MXC_CRMAP_ASCSR_APISEL			0x1
+
+#define MXC_CRMAP_ACDR_ARMDIV_OFFSET		8
+#define MXC_CRMAP_ACDR_ARMDIV_MASK		(0xF << 8)
+#define MXC_CRMAP_ACDR_AHBDIV_OFFSET		4
+#define MXC_CRMAP_ACDR_AHBDIV_MASK		(0xF << 4)
+#define MXC_CRMAP_ACDR_IPDIV_OFFSET		0
+#define MXC_CRMAP_ACDR_IPDIV_MASK		0xF
+
+#define MXC_CRMAP_ACDER1_CSIEN_OFFSET		30
+#define MXC_CRMAP_ACDER1_CSIDIV_OFFSET		24
+#define MXC_CRMAP_ACDER1_CSIDIV_MASK		(0x3F << 24)
+#define MXC_CRMAP_ACDER1_SSI2EN_OFFSET		14
+#define MXC_CRMAP_ACDER1_SSI2DIV_OFFSET		8
+#define MXC_CRMAP_ACDER1_SSI2DIV_MASK		(0x3F << 8)
+#define MXC_CRMAP_ACDER1_SSI1EN_OFFSET		6
+#define MXC_CRMAP_ACDER1_SSI1DIV_OFFSET		0
+#define MXC_CRMAP_ACDER1_SSI1DIV_MASK		0x3F
+
+#define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_OFFSET	24
+#define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_MASK	(0x7 << 24)
+#define MXC_CRMAP_ACDER2_NFCEN_OFFSET		20
+#define MXC_CRMAP_ACDER2_NFCDIV_OFFSET		16
+#define MXC_CRMAP_ACDER2_NFCDIV_MASK		(0xF << 16)
+#define MXC_CRMAP_ACDER2_USBEN_OFFSET		12
+#define MXC_CRMAP_ACDER2_USBDIV_OFFSET		8
+#define MXC_CRMAP_ACDER2_USBDIV_MASK		(0xF << 8)
+#define MXC_CRMAP_ACDER2_BAUD_ISEL_OFFSET	5
+#define MXC_CRMAP_ACDER2_BAUD_ISEL_MASK		(0x3 << 5)
+#define MXC_CRMAP_ACDER2_BAUDDIV_OFFSET		0
+#define MXC_CRMAP_ACDER2_BAUDDIV_MASK		0xF
+
+#define MXC_CRMAP_AMLPMRA_MLPMA7_OFFSET		22
+#define MXC_CRMAP_AMLPMRA_MLPMA7_MASK		(0x7 << 22)
+#define MXC_CRMAP_AMLPMRA_MLPMA6_OFFSET		19
+#define MXC_CRMAP_AMLPMRA_MLPMA6_MASK		(0x7 << 19)
+#define MXC_CRMAP_AMLPMRA_MLPMA4_OFFSET		12
+#define MXC_CRMAP_AMLPMRA_MLPMA4_MASK		(0x7 << 12)
+#define MXC_CRMAP_AMLPMRA_MLPMA3_OFFSET		9
+#define MXC_CRMAP_AMLPMRA_MLPMA3_MASK		(0x7 << 9)
+#define MXC_CRMAP_AMLPMRA_MLPMA2_OFFSET		6
+#define MXC_CRMAP_AMLPMRA_MLPMA2_MASK		(0x7 << 6)
+#define MXC_CRMAP_AMLPMRA_MLPMA1_OFFSET		3
+#define MXC_CRMAP_AMLPMRA_MLPMA1_MASK		(0x7 << 3)
+
+#define MXC_CRMAP_AMLPMRB_MLPMB0_OFFSET		0
+#define MXC_CRMAP_AMLPMRB_MLPMB0_MASK		0x7
+
+#define MXC_CRMAP_AMLPMRC_MLPMC9_OFFSET		28
+#define MXC_CRMAP_AMLPMRC_MLPMC9_MASK		(0x7 << 28)
+#define MXC_CRMAP_AMLPMRC_MLPMC7_OFFSET		22
+#define MXC_CRMAP_AMLPMRC_MLPMC7_MASK		(0x7 << 22)
+#define MXC_CRMAP_AMLPMRC_MLPMC5_OFFSET		16
+#define MXC_CRMAP_AMLPMRC_MLPMC5_MASK		(0x7 << 16)
+#define MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET		12
+#define MXC_CRMAP_AMLPMRC_MLPMC4_MASK		(0x7 << 12)
+#define MXC_CRMAP_AMLPMRC_MLPMC3_OFFSET		9
+#define MXC_CRMAP_AMLPMRC_MLPMC3_MASK		(0x7 << 9)
+#define MXC_CRMAP_AMLPMRC_MLPMC2_OFFSET		6
+#define MXC_CRMAP_AMLPMRC_MLPMC2_MASK		(0x7 << 6)
+#define MXC_CRMAP_AMLPMRC_MLPMC1_OFFSET		3
+#define MXC_CRMAP_AMLPMRC_MLPMC1_MASK		(0x7 << 3)
+#define MXC_CRMAP_AMLPMRC_MLPMC0_OFFSET		0
+#define MXC_CRMAP_AMLPMRC_MLPMC0_MASK		0x7
+
+#define MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET		22
+#define MXC_CRMAP_AMLPMRD_MLPMD7_MASK		(0x7 << 22)
+#define MXC_CRMAP_AMLPMRD_MLPMD4_OFFSET		12
+#define MXC_CRMAP_AMLPMRD_MLPMD4_MASK		(0x7 << 12)
+#define MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET		9
+#define MXC_CRMAP_AMLPMRD_MLPMD3_MASK		(0x7 << 9)
+#define MXC_CRMAP_AMLPMRD_MLPMD2_OFFSET		6
+#define MXC_CRMAP_AMLPMRD_MLPMD2_MASK		(0x7 << 6)
+#define MXC_CRMAP_AMLPMRD_MLPMD0_OFFSET		0
+#define MXC_CRMAP_AMLPMRD_MLPMD0_MASK		0x7
+
+#define MXC_CRMAP_AMLPMRE1_MLPME9_OFFSET	28
+#define MXC_CRMAP_AMLPMRE1_MLPME9_MASK		(0x7 << 28)
+#define MXC_CRMAP_AMLPMRE1_MLPME8_OFFSET	25
+#define MXC_CRMAP_AMLPMRE1_MLPME8_MASK		(0x7 << 25)
+#define MXC_CRMAP_AMLPMRE1_MLPME7_OFFSET	22
+#define MXC_CRMAP_AMLPMRE1_MLPME7_MASK		(0x7 << 22)
+#define MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET	19
+#define MXC_CRMAP_AMLPMRE1_MLPME6_MASK		(0x7 << 19)
+#define MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET	16
+#define MXC_CRMAP_AMLPMRE1_MLPME5_MASK		(0x7 << 16)
+#define MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET	12
+#define MXC_CRMAP_AMLPMRE1_MLPME4_MASK		(0x7 << 12)
+#define MXC_CRMAP_AMLPMRE1_MLPME3_OFFSET	9
+#define MXC_CRMAP_AMLPMRE1_MLPME3_MASK		(0x7 << 9)
+#define MXC_CRMAP_AMLPMRE1_MLPME2_OFFSET	6
+#define MXC_CRMAP_AMLPMRE1_MLPME2_MASK		(0x7 << 6)
+#define MXC_CRMAP_AMLPMRE1_MLPME1_OFFSET	3
+#define MXC_CRMAP_AMLPMRE1_MLPME1_MASK		(0x7 << 3)
+#define MXC_CRMAP_AMLPMRE1_MLPME0_OFFSET	0
+#define MXC_CRMAP_AMLPMRE1_MLPME0_MASK		0x7
+
+#define MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET	0
+#define MXC_CRMAP_AMLPMRE2_MLPME0_MASK		0x7
+
+#define MXC_CRMAP_AMLPMRF_MLPMF6_OFFSET		19
+#define MXC_CRMAP_AMLPMRF_MLPMF6_MASK		(0x7 << 19)
+#define MXC_CRMAP_AMLPMRF_MLPMF5_OFFSET		16
+#define MXC_CRMAP_AMLPMRF_MLPMF5_MASK		(0x7 << 16)
+#define MXC_CRMAP_AMLPMRF_MLPMF3_OFFSET		9
+#define MXC_CRMAP_AMLPMRF_MLPMF3_MASK		(0x7 << 9)
+#define MXC_CRMAP_AMLPMRF_MLPMF2_OFFSET		6
+#define MXC_CRMAP_AMLPMRF_MLPMF2_MASK		(0x7 << 6)
+#define MXC_CRMAP_AMLPMRF_MLPMF1_OFFSET		3
+#define MXC_CRMAP_AMLPMRF_MLPMF1_MASK		(0x7 << 3)
+#define MXC_CRMAP_AMLPMRF_MLPMF0_OFFSET		0
+#define MXC_CRMAP_AMLPMRF_MLPMF0_MASK		(0x7 << 0)
+
+#define MXC_CRMAP_AMLPMRG_MLPMG9_OFFSET		28
+#define MXC_CRMAP_AMLPMRG_MLPMG9_MASK		(0x7 << 28)
+#define MXC_CRMAP_AMLPMRG_MLPMG7_OFFSET		22
+#define MXC_CRMAP_AMLPMRG_MLPMG7_MASK		(0x7 << 22)
+#define MXC_CRMAP_AMLPMRG_MLPMG6_OFFSET		19
+#define MXC_CRMAP_AMLPMRG_MLPMG6_MASK		(0x7 << 19)
+#define MXC_CRMAP_AMLPMRG_MLPMG5_OFFSET		16
+#define MXC_CRMAP_AMLPMRG_MLPMG5_MASK		(0x7 << 16)
+#define MXC_CRMAP_AMLPMRG_MLPMG4_OFFSET		12
+#define MXC_CRMAP_AMLPMRG_MLPMG4_MASK		(0x7 << 12)
+#define MXC_CRMAP_AMLPMRG_MLPMG3_OFFSET		9
+#define MXC_CRMAP_AMLPMRG_MLPMG3_MASK		(0x7 << 9)
+#define MXC_CRMAP_AMLPMRG_MLPMG2_OFFSET		6
+#define MXC_CRMAP_AMLPMRG_MLPMG2_MASK		(0x7 << 6)
+#define MXC_CRMAP_AMLPMRG_MLPMG1_OFFSET		3
+#define MXC_CRMAP_AMLPMRG_MLPMG1_MASK		(0x7 << 3)
+#define MXC_CRMAP_AMLPMRG_MLPMG0_OFFSET		0
+#define MXC_CRMAP_AMLPMRG_MLPMG0_MASK		0x7
+
+#define MXC_CRMAP_AGPR_IPUPAD_OFFSET		20
+#define MXC_CRMAP_AGPR_IPUPAD_MASK		(0x7 << 20)
+
+#define MXC_CRMAP_APRA_EL1TEN_OFFSET		29
+#define MXC_CRMAP_APRA_SIMEN_OFFSET		24
+#define MXC_CRMAP_APRA_UART3DIV_OFFSET		17
+#define MXC_CRMAP_APRA_UART3DIV_MASK		(0xF << 17)
+#define MXC_CRMAP_APRA_UART3EN_OFFSET		16
+#define MXC_CRMAP_APRA_SAHARA_DIV2_CLKEN_OFFSET	14
+#define MXC_CRMAP_APRA_MQSPIEN_OFFSET		13
+#define MXC_CRMAP_APRA_UART2EN_OFFSET		8
+#define MXC_CRMAP_APRA_UART1EN_OFFSET		0
+
+#define MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET	13
+#define MXC_CRMAP_APRB_SDHC2_ISEL_MASK		(0x7 << 13)
+#define MXC_CRMAP_APRB_SDHC2_DIV_OFFSET		9
+#define MXC_CRMAP_APRB_SDHC2_DIV_MASK		(0xF << 9)
+#define MXC_CRMAP_APRB_SDHC2EN_OFFSET		8
+#define MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET	5
+#define MXC_CRMAP_APRB_SDHC1_ISEL_MASK		(0x7 << 5)
+#define MXC_CRMAP_APRB_SDHC1_DIV_OFFSET		1
+#define MXC_CRMAP_APRB_SDHC1_DIV_MASK		(0xF << 1)
+#define MXC_CRMAP_APRB_SDHC1EN_OFFSET		0
+
+#define MXC_CRMAP_ACSR_ADS_OFFSET		8
+#define MXC_CRMAP_ACSR_ADS			(0x1 << 8)
+#define MXC_CRMAP_ACSR_ACS			0x1
+
+#define MXC_CRMAP_ADCR_LFDF_0			(0x0 << 8)
+#define MXC_CRMAP_ADCR_LFDF_2			(0x1 << 8)
+#define MXC_CRMAP_ADCR_LFDF_4			(0x2 << 8)
+#define MXC_CRMAP_ADCR_LFDF_8			(0x3 << 8)
+#define MXC_CRMAP_ADCR_LFDF_OFFSET		8
+#define MXC_CRMAP_ADCR_LFDF_MASK		(0x3 << 8)
+#define MXC_CRMAP_ADCR_ALT_PLL			0x80
+#define MXC_CRMAP_ADCR_DFS_DIVEN		0x20
+#define MXC_CRMAP_ADCR_DIV_BYP			0x2
+#define MXC_CRMAP_ADCR_VSTAT			0x8
+#define MXC_CRMAP_ADCR_TSTAT			0x10
+#define MXC_CRMAP_ADCR_DVFS_VCTRL		0x10
+#define MXC_CRMAP_ADCR_CLK_ON			0x40
+
+#define MXC_CRMAP_ADFMR_FC_OFFSET		16
+#define MXC_CRMAP_ADFMR_FC_MASK			(0x1F << 16)
+#define MXC_CRMAP_ADFMR_MF_OFFSET		1
+#define MXC_CRMAP_ADFMR_MF_MASK			(0x3FF << 1)
+#define MXC_CRMAP_ADFMR_DFM_CLK_READY		0x1
+#define MXC_CRMAP_ADFMR_DFM_PWR_DOWN		0x8000
+
+#define MXC_CRMAP_ACR_CKOHS_HIGH		(1 << 18)
+#define MXC_CRMAP_ACR_CKOS_HIGH			(1 << 16)
+#define MXC_CRMAP_ACR_CKOHS_MASK		(0x7 << 12)
+#define MXC_CRMAP_ACR_CKOHD			(1 << 11)
+#define MXC_CRMAP_ACR_CKOHDIV_MASK		(0xF << 8)
+#define MXC_CRMAP_ACR_CKOHDIV_OFFSET		8
+#define MXC_CRMAP_ACR_CKOD			(1 << 7)
+#define MXC_CRMAP_ACR_CKOS_MASK			(0x7 << 4)
+
+/* AP Warm reset */
+#define MXC_CRMAP_AMCR_SW_AP			(1 << 14)
+
+/* Bit definitions of ACGCR in CRM_AP for tree level clock gating */
+#define MXC_CRMAP_ACGCR_ACG0_STOP_WAIT		0x00000001
+#define MXC_CRMAP_ACGCR_ACG0_STOP		0x00000003
+#define MXC_CRMAP_ACGCR_ACG0_RUN		0x00000007
+#define MXC_CRMAP_ACGCR_ACG0_DISABLED		0x00000000
+
+#define MXC_CRMAP_ACGCR_ACG1_STOP_WAIT		0x00000008
+#define MXC_CRMAP_ACGCR_ACG1_STOP		0x00000018
+#define MXC_CRMAP_ACGCR_ACG1_RUN		0x00000038
+#define MXC_CRMAP_ACGCR_ACG1_DISABLED		0x00000000
+
+#define MXC_CRMAP_ACGCR_ACG2_STOP_WAIT		0x00000040
+#define MXC_CRMAP_ACGCR_ACG2_STOP		0x000000C0
+#define MXC_CRMAP_ACGCR_ACG2_RUN		0x000001C0
+#define MXC_CRMAP_ACGCR_ACG2_DISABLED		0x00000000
+
+#define MXC_CRMAP_ACGCR_ACG3_STOP_WAIT		0x00000200
+#define MXC_CRMAP_ACGCR_ACG3_STOP		0x00000600
+#define MXC_CRMAP_ACGCR_ACG3_RUN		0x00000E00
+#define MXC_CRMAP_ACGCR_ACG3_DISABLED		0x00000000
+
+#define MXC_CRMAP_ACGCR_ACG4_STOP_WAIT		0x00001000
+#define MXC_CRMAP_ACGCR_ACG4_STOP		0x00003000
+#define MXC_CRMAP_ACGCR_ACG4_RUN		0x00007000
+#define MXC_CRMAP_ACGCR_ACG4_DISABLED		0x00000000
+
+#define MXC_CRMAP_ACGCR_ACG5_STOP_WAIT		0x00010000
+#define MXC_CRMAP_ACGCR_ACG5_STOP		0x00030000
+#define MXC_CRMAP_ACGCR_ACG5_RUN		0x00070000
+#define MXC_CRMAP_ACGCR_ACG5_DISABLED		0x00000000
+
+#define MXC_CRMAP_ACGCR_ACG6_STOP_WAIT		0x00080000
+#define MXC_CRMAP_ACGCR_ACG6_STOP		0x00180000
+#define MXC_CRMAP_ACGCR_ACG6_RUN		0x00380000
+#define MXC_CRMAP_ACGCR_ACG6_DISABLED		0x00000000
+
+#define NUM_GATE_CTRL				6
+
+/* CRM COM Register Offsets */
+#define MXC_CRMCOM_CSCR				(MXC_CRM_COM_BASE + 0x0C)
+#define MXC_CRMCOM_CCCR				(MXC_CRM_COM_BASE + 0x10)
+
+/* CRM COM Bit Definitions */
+#define MXC_CRMCOM_CSCR_PPD1			0x08000000
+#define MXC_CRMCOM_CSCR_CKOHSEL			(1 << 18)
+#define MXC_CRMCOM_CSCR_CKOSEL			(1 << 17)
+#define MXC_CRMCOM_CCCR_CC_DIV_OFFSET		8
+#define MXC_CRMCOM_CCCR_CC_DIV_MASK		(0x1F << 8)
+#define MXC_CRMCOM_CCCR_CC_SEL_OFFSET		0
+#define MXC_CRMCOM_CCCR_CC_SEL_MASK		0x3
+
+/* DSM Register Offsets */
+#define MXC_DSM_SLEEP_TIME			(MXC_DSM_BASE + 0x0c)
+#define MXC_DSM_CONTROL0			(MXC_DSM_BASE + 0x20)
+#define MXC_DSM_CONTROL1			(MXC_DSM_BASE + 0x24)
+#define MXC_DSM_CTREN				(MXC_DSM_BASE + 0x28)
+#define MXC_DSM_WARM_PER			(MXC_DSM_BASE + 0x40)
+#define MXC_DSM_LOCK_PER			(MXC_DSM_BASE + 0x44)
+#define MXC_DSM_MGPER				(MXC_DSM_BASE + 0x4c)
+#define MXC_DSM_CRM_CONTROL			(MXC_DSM_BASE + 0x50)
+
+/* Bit definitions of various registers in DSM */
+#define MXC_DSM_CRM_CTRL_DVFS_BYP		0x00000008
+#define MXC_DSM_CRM_CTRL_DVFS_VCTRL		0x00000004
+#define MXC_DSM_CRM_CTRL_LPMD1			0x00000002
+#define MXC_DSM_CRM_CTRL_LPMD0			0x00000001
+#define MXC_DSM_CRM_CTRL_LPMD_STOP_MODE		0x00000000
+#define MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE		0x00000001
+#define MXC_DSM_CRM_CTRL_LPMD_RUN_MODE		0x00000003
+#define MXC_DSM_CONTROL0_STBY_COMMIT_EN		0x00000200
+#define MXC_DSM_CONTROL0_MSTR_EN		0x00000001
+#define MXC_DSM_CONTROL0_RESTART		0x00000010
+/* Counter Block reset */
+#define MXC_DSM_CONTROL1_CB_RST			0x00000002
+/* State Machine reset */
+#define MXC_DSM_CONTROL1_SM_RST			0x00000004
+/* Bit needed to reset counter block */
+#define MXC_CONTROL1_RST_CNT32			0x00000008
+#define MXC_DSM_CONTROL1_RST_CNT32_EN		0x00000800
+#define MXC_DSM_CONTROL1_SLEEP			0x00000100
+#define MXC_DSM_CONTROL1_WAKEUP_DISABLE		0x00004000
+#define MXC_DSM_CTREN_CNT32			0x00000001
+
+/* Magic Fix enable bit */
+#define MXC_DSM_MGPER_EN_MGFX			0x80000000
+#define MXC_DSM_MGPER_PER_MASK			0x000003FF
+#define MXC_DSM_MGPER_PER(n)			(MXC_DSM_MGPER_PER_MASK & n)
+
+/* Address offsets of the CLKCTL registers */
+#define MXC_CLKCTL_GP_CTRL	(MXC_CLKCTL_BASE + 0x00)
+#define MXC_CLKCTL_GP_SER	(MXC_CLKCTL_BASE + 0x04)
+#define MXC_CLKCTL_GP_CER	(MXC_CLKCTL_BASE + 0x08)
+
+#endif /* _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_ */
diff --git a/arch/arm/mach-mxc91231/devices.c b/arch/arm/mach-mxc91231/devices.c
new file mode 100644
index 0000000..353bd97
--- /dev/null
+++ b/arch/arm/mach-mxc91231/devices.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/imx-uart.h>
+
+static struct resource uart0[] = {
+	{
+		.start = MXC91231_UART1_BASE_ADDR,
+		.end = MXC91231_UART1_BASE_ADDR + 0x0B5,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC91231_INT_UART1_RX,
+		.end = MXC91231_INT_UART1_RX,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC91231_INT_UART1_TX,
+		.end = MXC91231_INT_UART1_TX,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC91231_INT_UART1_MINT,
+		.end = MXC91231_INT_UART1_MINT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device0 = {
+	.name = "imx-uart",
+	.id = 0,
+	.resource = uart0,
+	.num_resources = ARRAY_SIZE(uart0),
+};
+
+static struct resource uart1[] = {
+	{
+		.start = MXC91231_UART2_BASE_ADDR,
+		.end = MXC91231_UART2_BASE_ADDR + 0x0B5,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC91231_INT_UART2_RX,
+		.end = MXC91231_INT_UART2_RX,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC91231_INT_UART2_TX,
+		.end = MXC91231_INT_UART2_TX,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC91231_INT_UART2_MINT,
+		.end = MXC91231_INT_UART2_MINT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device1 = {
+	.name = "imx-uart",
+	.id = 1,
+	.resource = uart1,
+	.num_resources = ARRAY_SIZE(uart1),
+};
+
+static struct resource uart2[] = {
+	{
+		.start = MXC91231_UART3_BASE_ADDR,
+		.end = MXC91231_UART3_BASE_ADDR + 0x0B5,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC91231_INT_UART3_RX,
+		.end = MXC91231_INT_UART3_RX,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC91231_INT_UART3_TX,
+		.end = MXC91231_INT_UART3_TX,
+		.flags = IORESOURCE_IRQ,
+	}, {
+		.start = MXC91231_INT_UART3_MINT,
+		.end = MXC91231_INT_UART3_MINT,
+		.flags = IORESOURCE_IRQ,
+
+	},
+};
+
+struct platform_device mxc_uart_device2 = {
+	.name = "imx-uart",
+	.id = 2,
+	.resource = uart2,
+	.num_resources = ARRAY_SIZE(uart2),
+};
+
+/* GPIO port description */
+static struct mxc_gpio_port mxc_gpio_ports[] = {
+	[0] = {
+		.chip.label = "gpio-0",
+		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO1_AP_BASE_ADDR),
+		.irq = MXC91231_INT_GPIO1,
+		.virtual_irq_start = MXC_GPIO_IRQ_START,
+	},
+	[1] = {
+		.chip.label = "gpio-1",
+		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO2_AP_BASE_ADDR),
+		.irq = MXC91231_INT_GPIO2,
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
+	},
+	[2] = {
+		.chip.label = "gpio-2",
+		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO3_AP_BASE_ADDR),
+		.irq = MXC91231_INT_GPIO3,
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
+	},
+	[3] = {
+		.chip.label = "gpio-3",
+		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO4_SH_BASE_ADDR),
+		.irq = MXC91231_INT_GPIO4,
+		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
+	},
+};
+
+int __init mxc_register_gpios(void)
+{
+	return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
+}
+
+static struct resource mxc_nand_resources[] = {
+	{
+		.start	= MXC91231_NFC_BASE_ADDR,
+		.end	= MXC91231_NFC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM
+	}, {
+		.start	= MXC91231_INT_NANDFC,
+		.end	= MXC91231_INT_NANDFC,
+		.flags	= IORESOURCE_IRQ
+	},
+};
+
+struct platform_device mxc_nand_device = {
+	.name = "mxc_nand",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_nand_resources),
+	.resource = mxc_nand_resources,
+};
+
+static struct resource mxc_sdhc0_resources[] = {
+	{
+		.start = MXC91231_MMC_SDHC1_BASE_ADDR,
+		.end = MXC91231_MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC91231_INT_MMC_SDHC1,
+		.end = MXC91231_INT_MMC_SDHC1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource mxc_sdhc1_resources[] = {
+	{
+		.start = MXC91231_MMC_SDHC2_BASE_ADDR,
+		.end = MXC91231_MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC91231_INT_MMC_SDHC2,
+		.end = MXC91231_INT_MMC_SDHC2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_sdhc_device0 = {
+	.name = "mxc-mmc",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_sdhc0_resources),
+	.resource = mxc_sdhc0_resources,
+};
+
+struct platform_device mxc_sdhc_device1 = {
+	.name = "mxc-mmc",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
+	.resource = mxc_sdhc1_resources,
+};
+
+static struct resource mxc_cspi0_resources[] = {
+	{
+		.start = MXC91231_CSPI1_BASE_ADDR,
+		.end = MXC91231_CSPI1_BASE_ADDR + 0x20,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC91231_INT_CSPI1,
+		.end = MXC91231_INT_CSPI1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_cspi_device0 = {
+	.name = "spi_imx",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_cspi0_resources),
+	.resource = mxc_cspi0_resources,
+};
+
+static struct resource mxc_cspi1_resources[] = {
+	{
+		.start = MXC91231_CSPI2_BASE_ADDR,
+		.end = MXC91231_CSPI2_BASE_ADDR + 0x20,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MXC91231_INT_CSPI2,
+		.end = MXC91231_INT_CSPI2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_cspi_device1 = {
+	.name = "spi_imx",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(mxc_cspi1_resources),
+	.resource = mxc_cspi1_resources,
+};
+
+static struct resource mxc_wdog0_resources[] = {
+	{
+		.start = MXC91231_WDOG1_BASE_ADDR,
+		.end = MXC91231_WDOG1_BASE_ADDR + 0x10,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device mxc_wdog_device0 = {
+	.name = "mxc-wdt",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_wdog0_resources),
+	.resource = mxc_wdog0_resources,
+};
diff --git a/arch/arm/mach-mxc91231/devices.h b/arch/arm/mach-mxc91231/devices.h
new file mode 100644
index 0000000..72a2136
--- /dev/null
+++ b/arch/arm/mach-mxc91231/devices.h
@@ -0,0 +1,13 @@
+extern struct platform_device mxc_uart_device0;
+extern struct platform_device mxc_uart_device1;
+extern struct platform_device mxc_uart_device2;
+
+extern struct platform_device mxc_nand_device;
+
+extern struct platform_device mxc_sdhc_device0;
+extern struct platform_device mxc_sdhc_device1;
+
+extern struct platform_device mxc_cspi_device0;
+extern struct platform_device mxc_cspi_device1;
+
+extern struct platform_device mxc_wdog_device0;
diff --git a/arch/arm/mach-mxc91231/iomux.c b/arch/arm/mach-mxc91231/iomux.c
new file mode 100644
index 0000000..405d9b1
--- /dev/null
+++ b/arch/arm/mach-mxc91231/iomux.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mxc91231.h>
+
+/*
+ * IOMUX register (base) addresses
+ */
+#define IOMUX_AP_BASE		MXC91231_IO_ADDRESS(MXC91231_IOMUX_AP_BASE_ADDR)
+#define IOMUX_COM_BASE		MXC91231_IO_ADDRESS(MXC91231_IOMUX_COM_BASE_ADDR)
+#define IOMUXSW_AP_MUX_CTL	(IOMUX_AP_BASE + 0x000)
+#define IOMUXSW_SP_MUX_CTL	(IOMUX_COM_BASE + 0x000)
+#define IOMUXSW_PAD_CTL		(IOMUX_COM_BASE + 0x200)
+
+#define IOMUXINT_OBS1		(IOMUX_AP_BASE + 0x600)
+#define IOMUXINT_OBS2		(IOMUX_AP_BASE + 0x004)
+
+static DEFINE_SPINLOCK(gpio_mux_lock);
+
+#define NB_PORTS			((PIN_MAX + 32) / 32)
+#define PIN_GLOBAL_NUM(pin) \
+	(((pin & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT)*PIN_AP_MAX +	\
+	 ((pin & MUX_REG_MASK) >> MUX_REG_SHIFT)*4 +		\
+	 ((pin & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT))
+
+unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
+/*
+ * set the mode for a IOMUX pin.
+ */
+int mxc_iomux_mode(const unsigned int pin_mode)
+{
+	u32 side, field, l, mode, ret = 0;
+	void __iomem *reg;
+
+	side = (pin_mode & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT;
+	switch (side) {
+	case MUX_SIDE_AP:
+		reg = IOMUXSW_AP_MUX_CTL;
+		break;
+	case MUX_SIDE_SP:
+		reg = IOMUXSW_SP_MUX_CTL;
+		break;
+	default:
+		return -EINVAL;
+	}
+	reg += ((pin_mode & MUX_REG_MASK) >> MUX_REG_SHIFT) * 4;
+	field = (pin_mode & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT;
+	mode = (pin_mode & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
+
+	spin_lock(&gpio_mux_lock);
+
+	l = __raw_readl(reg);
+	l &= ~(0xff << (field * 8));
+	l |= mode << (field * 8);
+	__raw_writel(l, reg);
+
+	spin_unlock(&gpio_mux_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_mode);
+
+/*
+ * This function configures the pad value for a IOMUX pin.
+ */
+void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
+{
+	u32 padgrp, field, l;
+	void __iomem *reg;
+
+	padgrp = (pin & MUX_PADGRP_MASK) >> MUX_PADGRP_SHIFT;
+	reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
+	field = (pin + 2) % 3;
+
+	pr_debug("%s: reg offset = 0x%x, field = %d\n",
+			__func__, (pin + 2) / 3, field);
+
+	spin_lock(&gpio_mux_lock);
+
+	l = __raw_readl(reg);
+	l &= ~(0x1ff << (field * 10));
+	l |= config << (field * 10);
+	__raw_writel(l, reg);
+
+	spin_unlock(&gpio_mux_lock);
+}
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+
+/*
+ * allocs a single pin:
+ * 	- reserves the pin so that it is not claimed by another driver
+ * 	- setups the iomux according to the configuration
+ */
+int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label)
+{
+	unsigned pad = PIN_GLOBAL_NUM(pin_mode);
+	if (pad >= (PIN_MAX + 1)) {
+		printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
+			pad, label ? label : "?");
+		return -EINVAL;
+	}
+
+	if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
+		printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
+			pad, label ? label : "?");
+		return -EBUSY;
+	}
+	mxc_iomux_mode(pin_mode);
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_alloc_pin);
+
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+		const char *label)
+{
+	unsigned int *p = pin_list;
+	int i;
+	int ret = -EINVAL;
+
+	for (i = 0; i < count; i++) {
+		ret = mxc_iomux_alloc_pin(*p, label);
+		if (ret)
+			goto setup_error;
+		p++;
+	}
+	return 0;
+
+setup_error:
+	mxc_iomux_release_multiple_pins(pin_list, i);
+	return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
+
+void mxc_iomux_release_pin(const unsigned int pin_mode)
+{
+	unsigned pad = PIN_GLOBAL_NUM(pin_mode);
+
+	if (pad < (PIN_MAX + 1))
+		clear_bit(pad, mxc_pin_alloc_map);
+}
+EXPORT_SYMBOL(mxc_iomux_release_pin);
+
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
+{
+	unsigned int *p = pin_list;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		mxc_iomux_release_pin(*p);
+		p++;
+	}
+}
+EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
diff --git a/arch/arm/mach-mxc91231/magx-zn5.c b/arch/arm/mach-mxc91231/magx-zn5.c
new file mode 100644
index 0000000..7dbe4ca
--- /dev/null
+++ b/arch/arm/mach-mxc91231/magx-zn5.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com>
+ *
+ * This file is released under the GPLv2 or later.
+ */
+
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mxc91231.h>
+#include <mach/mmc.h>
+#include <mach/imx-uart.h>
+
+#include "devices.h"
+
+static struct imxuart_platform_data uart_pdata = {
+};
+
+static struct imxmmc_platform_data sdhc_pdata = {
+};
+
+static void __init zn5_init(void)
+{
+	pm_power_off = mxc91231_power_off;
+
+	mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_DAT_VP__RXD2, "uart2-rx");
+	mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_SE0_VM__TXD2, "uart2-tx");
+
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+
+	mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata);
+
+	mxc_register_device(&mxc_wdog_device0, NULL);
+
+	return;
+}
+
+static void __init zn5_timer_init(void)
+{
+	mxc91231_clocks_init(26000000); /* 26mhz ckih */
+}
+
+struct sys_timer zn5_timer = {
+	.init = zn5_timer_init,
+};
+
+MACHINE_START(MAGX_ZN5, "Motorola Zn5")
+	.phys_io	= MXC91231_AIPS1_BASE_ADDR,
+	.io_pg_offst	= ((MXC91231_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params	= PHYS_OFFSET + 0x100,
+	.map_io		= mxc91231_map_io,
+	.init_irq	= mxc91231_init_irq,
+	.timer		= &zn5_timer,
+	.init_machine	= zn5_init,
+MACHINE_END
diff --git a/arch/arm/mach-mxc91231/mm.c b/arch/arm/mach-mxc91231/mm.c
new file mode 100644
index 0000000..6becda3
--- /dev/null
+++ b/arch/arm/mach-mxc91231/mm.c
@@ -0,0 +1,94 @@
+/*
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2004-2005 Freescale Semiconductor, Inc. All Rights Reserved.
+ *    - add MXC specific definitions
+ *  Copyright 2006 Motorola, 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 <linux/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+/*
+ * This structure defines the MXC memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+	{
+		.virtual	= MXC91231_L2CC_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_L2CC_BASE_ADDR),
+		.length		= MXC91231_L2CC_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MXC91231_X_MEMC_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_X_MEMC_BASE_ADDR),
+		.length		= MXC91231_X_MEMC_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MXC91231_ROMP_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_ROMP_BASE_ADDR),
+		.length		= MXC91231_ROMP_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MXC91231_AVIC_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_AVIC_BASE_ADDR),
+		.length		= MXC91231_AVIC_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MXC91231_AIPS1_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_AIPS1_BASE_ADDR),
+		.length		= MXC91231_AIPS1_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MXC91231_SPBA0_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_SPBA0_BASE_ADDR),
+		.length		= MXC91231_SPBA0_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MXC91231_SPBA1_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_SPBA1_BASE_ADDR),
+		.length		= MXC91231_SPBA1_SIZE,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= MXC91231_AIPS2_BASE_ADDR_VIRT,
+		.pfn		= __phys_to_pfn(MXC91231_AIPS2_BASE_ADDR),
+		.length		= MXC91231_AIPS2_SIZE,
+		.type		= MT_DEVICE,
+	},
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory map for
+ * the IO modules.
+ */
+void __init mxc91231_map_io(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MXC91231);
+
+	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
+
+void __init mxc91231_init_irq(void)
+{
+	mxc_init_irq(MXC91231_IO_ADDRESS(MXC91231_AVIC_BASE_ADDR));
+}
diff --git a/arch/arm/mach-mxc91231/system.c b/arch/arm/mach-mxc91231/system.c
new file mode 100644
index 0000000..736f7ef
--- /dev/null
+++ b/arch/arm/mach-mxc91231/system.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com>
+ *
+ * This file is released under the GPLv2 or later.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/proc-fns.h>
+#include <mach/hardware.h>
+
+#include "crm_regs.h"
+
+#define WDOG_WCR		MXC91231_IO_ADDRESS(MXC91231_WDOG1_BASE_ADDR)
+#define WDOG_WCR_OUT_ENABLE	(1 << 6)
+#define WDOG_WCR_ASSERT		(1 << 5)
+
+void mxc91231_power_off(void)
+{
+	u16 wcr;
+
+	wcr = __raw_readw(WDOG_WCR);
+	wcr |= WDOG_WCR_OUT_ENABLE;
+	wcr &= ~WDOG_WCR_ASSERT;
+	__raw_writew(wcr, WDOG_WCR);
+}
+
+void mxc91231_arch_reset(char mode, const char *cmd)
+{
+	u32 amcr;
+
+	/* Reset the AP using CRM */
+	amcr = __raw_readl(MXC_CRMAP_AMCR);
+	amcr &= ~MXC_CRMAP_AMCR_SW_AP;
+	__raw_writel(amcr, MXC_CRMAP_AMCR);
+
+	mdelay(10);
+	cpu_reset(0);
+}
+
+void mxc91231_prepare_idle(void)
+{
+	u32 crm_ctl;
+
+	/* Go to WAIT mode after WFI */
+	crm_ctl = __raw_readl(MXC_DSM_CRM_CONTROL);
+	crm_ctl &= ~(MXC_DSM_CRM_CTRL_LPMD0 | MXC_DSM_CRM_CTRL_LPMD1);
+	crm_ctl |=  MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE;
+	__raw_writel(crm_ctl, MXC_DSM_CRM_CONTROL);
+}
diff --git a/arch/arm/mach-netx/include/mach/entry-macro.S b/arch/arm/mach-netx/include/mach/entry-macro.S
index a1952a0..844f1f9 100644
--- a/arch/arm/mach-netx/include/mach/entry-macro.S
+++ b/arch/arm/mach-netx/include/mach/entry-macro.S
@@ -24,15 +24,13 @@
 		.endm
 
 		.macro  get_irqnr_preamble, base, tmp
+		ldr	\base, =io_p2v(0x001ff000)
 		.endm
 
 		.macro  arch_ret_to_user, tmp1, tmp2
 		.endm
 
 		.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	\base, #io_p2v(0x00100000)
-		add	\base, \base, #0x000ff000
-
 		ldr	\irqstat, [\base, #0]
 		clz	\irqnr, \irqstat
 		rsb     \irqnr, \irqnr, #31
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig
new file mode 100644
index 0000000..2a02b49
--- /dev/null
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -0,0 +1,21 @@
+if ARCH_NOMADIK
+
+menu "Nomadik boards"
+
+config MACH_NOMADIK_8815NHK
+	bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
+	select NOMADIK_8815
+
+endmenu
+
+config NOMADIK_8815
+	bool
+
+
+config I2C_BITBANG_8815NHK
+	tristate "Driver for bit-bang busses found on the 8815 NHK"
+	depends on I2C && MACH_NOMADIK_8815NHK
+	select I2C_ALGOBIT
+	default y
+
+endif
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile
new file mode 100644
index 0000000..4120409
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+# Object file lists.
+
+obj-y			+= clock.o timer.o gpio.o
+
+# Cpu revision
+obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
+
+# Specific board support
+obj-$(CONFIG_MACH_NOMADIK_8815NHK) += board-nhk8815.o
+
+# Nomadik extra devices
+obj-$(CONFIG_I2C_BITBANG_8815NHK) += i2c-8815nhk.o
diff --git a/arch/arm/mach-nomadik/Makefile.boot b/arch/arm/mach-nomadik/Makefile.boot
new file mode 100644
index 0000000..c7e75ac
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile.boot
@@ -0,0 +1,4 @@
+   zreladdr-y	:= 0x00008000
+params_phys-y	:= 0x00000100
+initrd_phys-y	:= 0x00800000
+
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
new file mode 100644
index 0000000..79bdea9
--- /dev/null
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -0,0 +1,111 @@
+/*
+ *  linux/arch/arm/mach-nomadik/board-8815nhk.c
+ *
+ *  Copyright (C) STMicroelectronics
+ *
+ * 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.
+ *
+ *  NHK15 board specifc driver definition
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/setup.h>
+#include "clock.h"
+
+#define __MEM_4K_RESOURCE(x) \
+	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+static struct amba_device uart0_device = {
+	.dev = { .init_name = "uart0" },
+	__MEM_4K_RESOURCE(NOMADIK_UART0_BASE),
+	.irq = {IRQ_UART0, NO_IRQ},
+};
+
+static struct amba_device uart1_device = {
+	.dev = { .init_name = "uart1" },
+	__MEM_4K_RESOURCE(NOMADIK_UART1_BASE),
+	.irq = {IRQ_UART1, NO_IRQ},
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	&uart0_device,
+	&uart1_device,
+};
+
+/* We have a fixed clock alone, by now */
+static struct clk nhk8815_clk_48 = {
+	.rate = 48*1000*1000,
+};
+
+static struct resource nhk8815_eth_resources[] = {
+	{
+		.name = "smc91x-regs",
+		.start = 0x34000000 + 0x300,
+		.end = 0x34000000 + SZ_64K - 1,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = NOMADIK_GPIO_TO_IRQ(115),
+		.end = NOMADIK_GPIO_TO_IRQ(115),
+		.flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
+	}
+};
+
+static struct platform_device nhk8815_eth_device = {
+	.name = "smc91x",
+	.resource = nhk8815_eth_resources,
+	.num_resources = ARRAY_SIZE(nhk8815_eth_resources),
+};
+
+static int __init nhk8815_eth_init(void)
+{
+	int gpio_nr = 115; /* hardwired in the board */
+	int err;
+
+	err = gpio_request(gpio_nr, "eth_irq");
+	if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO);
+	if (!err) err = gpio_direction_input(gpio_nr);
+	if (err)
+		pr_err("Error %i in %s\n", err, __func__);
+	return err;
+}
+device_initcall(nhk8815_eth_init);
+
+static struct platform_device *nhk8815_platform_devices[] __initdata = {
+	&nhk8815_eth_device,
+	/* will add more devices */
+};
+
+static void __init nhk8815_platform_init(void)
+{
+	int i;
+
+	cpu8815_platform_init();
+	platform_add_devices(nhk8815_platform_devices,
+			     ARRAY_SIZE(nhk8815_platform_devices));
+
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+		nmdk_clk_create(&nhk8815_clk_48, amba_devs[i]->dev.init_name);
+		amba_device_register(amba_devs[i], &iomem_resource);
+	}
+}
+
+MACHINE_START(NOMADIK, "NHK8815")
+	/* Maintainer: ST MicroElectronics */
+	.phys_io	= NOMADIK_UART0_BASE,
+	.io_pg_offst	= (IO_ADDRESS(NOMADIK_UART0_BASE) >> 18) & 0xfffc,
+	.boot_params	= 0x100,
+	.map_io		= cpu8815_map_io,
+	.init_irq	= cpu8815_init_irq,
+	.timer		= &nomadik_timer,
+	.init_machine	= nhk8815_platform_init,
+MACHINE_END
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
new file mode 100644
index 0000000..9f92502
--- /dev/null
+++ b/arch/arm/mach-nomadik/clock.c
@@ -0,0 +1,45 @@
+/*
+ *  linux/arch/arm/mach-nomadik/clock.c
+ *
+ *  Copyright (C) 2009 Alessandro Rubini
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <asm/clkdev.h>
+#include "clock.h"
+
+/*
+ * The nomadik board uses generic clocks, but the serial pl011 file
+ * calls clk_enable(), clk_disable(), clk_get_rate(), so we provide them
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* enable and disable do nothing */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Create a clock structure with the given name */
+int nmdk_clk_create(struct clk *clk, const char *dev_id)
+{
+	struct clk_lookup *clkdev;
+
+	clkdev = clkdev_alloc(clk, NULL, dev_id);
+	if (!clkdev)
+		return -ENOMEM;
+	clkdev_add(clkdev);
+	return 0;
+}
diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h
new file mode 100644
index 0000000..235faec
--- /dev/null
+++ b/arch/arm/mach-nomadik/clock.h
@@ -0,0 +1,14 @@
+
+/*
+ *  linux/arch/arm/mach-nomadik/clock.h
+ *
+ *  Copyright (C) 2009 Alessandro Rubini
+ *
+ * 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.
+ */
+struct clk {
+	unsigned long		rate;
+};
+extern int nmdk_clk_create(struct clk *clk, const char *dev_id);
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
new file mode 100644
index 0000000..f93c596
--- /dev/null
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright STMicroelectronics, 2007.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU 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/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/vic.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/* The 8815 has 4 GPIO blocks, let's register them immediately */
+static struct nmk_gpio_platform_data cpu8815_gpio[] = {
+	{
+		.name = "GPIO-0-31",
+		.first_gpio = 0,
+		.first_irq = NOMADIK_GPIO_TO_IRQ(0),
+		.parent_irq = IRQ_GPIO0,
+	}, {
+		.name = "GPIO-32-63",
+		.first_gpio = 32,
+		.first_irq = NOMADIK_GPIO_TO_IRQ(32),
+		.parent_irq = IRQ_GPIO1,
+	}, {
+		.name = "GPIO-64-95",
+		.first_gpio = 64,
+		.first_irq = NOMADIK_GPIO_TO_IRQ(64),
+		.parent_irq = IRQ_GPIO2,
+	}, {
+		.name = "GPIO-96-127", /* 124..127 not routed to pin */
+		.first_gpio = 96,
+		.first_irq = NOMADIK_GPIO_TO_IRQ(96),
+		.parent_irq = IRQ_GPIO3,
+	}
+};
+
+#define __MEM_4K_RESOURCE(x) \
+	.res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+static struct amba_device cpu8815_amba_gpio[] = {
+	{
+		.dev = {
+			.init_name = "gpio0",
+			.platform_data = cpu8815_gpio + 0,
+		},
+		__MEM_4K_RESOURCE(NOMADIK_GPIO0_BASE),
+	}, {
+		.dev = {
+			.init_name = "gpio1",
+			.platform_data = cpu8815_gpio + 1,
+		},
+		__MEM_4K_RESOURCE(NOMADIK_GPIO1_BASE),
+	}, {
+		.dev = {
+			.init_name = "gpio2",
+			.platform_data = cpu8815_gpio + 2,
+		},
+		__MEM_4K_RESOURCE(NOMADIK_GPIO2_BASE),
+	}, {
+		.dev = {
+			.init_name = "gpio3",
+			.platform_data = cpu8815_gpio + 3,
+		},
+		__MEM_4K_RESOURCE(NOMADIK_GPIO3_BASE),
+	},
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	cpu8815_amba_gpio + 0,
+	cpu8815_amba_gpio + 1,
+	cpu8815_amba_gpio + 2,
+	cpu8815_amba_gpio + 3,
+};
+
+static int __init cpu8815_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+		amba_device_register(amba_devs[i], &iomem_resource);
+	return 0;
+}
+arch_initcall(cpu8815_init);
+
+/* All SoC devices live in the same area (see hardware.h) */
+static struct map_desc nomadik_io_desc[] __initdata = {
+	{
+		.virtual =	NOMADIK_IO_VIRTUAL,
+		.pfn =		__phys_to_pfn(NOMADIK_IO_PHYSICAL),
+		.length =	NOMADIK_IO_SIZE,
+		.type = 	MT_DEVICE,
+	}
+	/* static ram and secured ram may be added later */
+};
+
+void __init cpu8815_map_io(void)
+{
+	iotable_init(nomadik_io_desc, ARRAY_SIZE(nomadik_io_desc));
+}
+
+void __init cpu8815_init_irq(void)
+{
+	/* This modified VIC cell has two register blocks, at 0 and 0x20 */
+	vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START +  0, ~0, 0);
+	vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0);
+}
+
+/*
+ * This function is called from the board init ("init_machine").
+ */
+ void __init cpu8815_platform_init(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+	/* At full speed latency must be >=2, so 0x249 in low bits */
+	l2x0_init(io_p2v(NOMADIK_L2CC_BASE), 0x00730249, 0xfe000fff);
+#endif
+	 return;
+}
diff --git a/arch/arm/mach-nomadik/gpio.c b/arch/arm/mach-nomadik/gpio.c
new file mode 100644
index 0000000..9a09b27
--- /dev/null
+++ b/arch/arm/mach-nomadik/gpio.c
@@ -0,0 +1,396 @@
+/*
+ * Generic GPIO driver for logic cells found in the Nomadik SoC
+ *
+ * Copyright (C) 2008,2009 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+
+/*
+ * The GPIO module in the Nomadik family of Systems-on-Chip is an
+ * AMBA device, managing 32 pins and alternate functions.  The logic block
+ * is currently only used in the Nomadik.
+ *
+ * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
+ */
+
+#define NMK_GPIO_PER_CHIP 32
+struct nmk_gpio_chip {
+	struct gpio_chip chip;
+	void __iomem *addr;
+	unsigned int parent_irq;
+	spinlock_t *lock;
+	/* Keep track of configured edges */
+	u32 edge_rising;
+	u32 edge_falling;
+};
+
+/* Mode functions */
+int nmk_gpio_set_mode(int gpio, int gpio_mode)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+	u32 afunc, bfunc, bit;
+
+	nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	bit = 1 << (gpio - nmk_chip->chip.base);
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
+	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
+	if (gpio_mode & NMK_GPIO_ALT_A)
+		afunc |= bit;
+	if (gpio_mode & NMK_GPIO_ALT_B)
+		bfunc |= bit;
+	writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
+	writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(nmk_gpio_set_mode);
+
+int nmk_gpio_get_mode(int gpio)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	u32 afunc, bfunc, bit;
+
+	nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	bit = 1 << (gpio - nmk_chip->chip.base);
+
+	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
+	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
+
+	return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
+}
+EXPORT_SYMBOL(nmk_gpio_get_mode);
+
+
+/* IRQ functions */
+static inline int nmk_gpio_get_bitmask(int gpio)
+{
+	return 1 << (gpio % 32);
+}
+
+static void nmk_gpio_irq_ack(unsigned int irq)
+{
+	int gpio;
+	struct nmk_gpio_chip *nmk_chip;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(irq);
+	nmk_chip = get_irq_chip_data(irq);
+	if (!nmk_chip)
+		return;
+	writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
+}
+
+static void nmk_gpio_irq_mask(unsigned int irq)
+{
+	int gpio;
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+	u32 bitmask, reg;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(irq);
+	nmk_chip = get_irq_chip_data(irq);
+	bitmask = nmk_gpio_get_bitmask(gpio);
+	if (!nmk_chip)
+		return;
+
+	/* we must individually clear the two edges */
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	if (nmk_chip->edge_rising & bitmask) {
+		reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
+		reg &= ~bitmask;
+		writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
+	}
+	if (nmk_chip->edge_falling & bitmask) {
+		reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
+		reg &= ~bitmask;
+		writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
+	}
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+};
+
+static void nmk_gpio_irq_unmask(unsigned int irq)
+{
+	int gpio;
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+	u32 bitmask, reg;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(irq);
+	nmk_chip = get_irq_chip_data(irq);
+	bitmask = nmk_gpio_get_bitmask(gpio);
+	if (!nmk_chip)
+		return;
+
+	/* we must individually set the two edges */
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	if (nmk_chip->edge_rising & bitmask) {
+		reg = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
+		reg |= bitmask;
+		writel(reg, nmk_chip->addr + NMK_GPIO_RWIMSC);
+	}
+	if (nmk_chip->edge_falling & bitmask) {
+		reg = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
+		reg |= bitmask;
+		writel(reg, nmk_chip->addr + NMK_GPIO_FWIMSC);
+	}
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+}
+
+static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
+{
+	int gpio;
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+	u32 bitmask;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(irq);
+	nmk_chip = get_irq_chip_data(irq);
+	bitmask = nmk_gpio_get_bitmask(gpio);
+	if (!nmk_chip)
+		return -EINVAL;
+
+	if (type & IRQ_TYPE_LEVEL_HIGH)
+		return -EINVAL;
+	if (type & IRQ_TYPE_LEVEL_LOW)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+
+	nmk_chip->edge_rising &= ~bitmask;
+	if (type & IRQ_TYPE_EDGE_RISING)
+		nmk_chip->edge_rising |= bitmask;
+	writel(nmk_chip->edge_rising, nmk_chip->addr + NMK_GPIO_RIMSC);
+
+	nmk_chip->edge_falling &= ~bitmask;
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		nmk_chip->edge_falling |= bitmask;
+	writel(nmk_chip->edge_falling, nmk_chip->addr + NMK_GPIO_FIMSC);
+
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	nmk_gpio_irq_unmask(irq);
+
+	return 0;
+}
+
+static struct irq_chip nmk_gpio_irq_chip = {
+	.name		= "Nomadik-GPIO",
+	.ack		= nmk_gpio_irq_ack,
+	.mask		= nmk_gpio_irq_mask,
+	.unmask		= nmk_gpio_irq_unmask,
+	.set_type	= nmk_gpio_irq_set_type,
+};
+
+static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	struct irq_chip *host_chip;
+	unsigned int gpio_irq;
+	u32 pending;
+	unsigned int first_irq;
+
+	nmk_chip = get_irq_data(irq);
+	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+	while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
+		gpio_irq = first_irq + __ffs(pending);
+		generic_handle_irq(gpio_irq);
+	}
+	if (0) {/* don't ack parent irq, as ack == disable */
+		host_chip = get_irq_chip(irq);
+		host_chip->ack(irq);
+	}
+}
+
+static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
+{
+	unsigned int first_irq;
+	int i;
+
+	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+	for (i = first_irq; i < first_irq + NMK_GPIO_PER_CHIP; i++) {
+		set_irq_chip(i, &nmk_gpio_irq_chip);
+		set_irq_handler(i, handle_edge_irq);
+		set_irq_flags(i, IRQF_VALID);
+		set_irq_chip_data(i, nmk_chip);
+	}
+	set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
+	set_irq_data(nmk_chip->parent_irq, nmk_chip);
+	return 0;
+}
+
+/* I/O Functions */
+static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+	return 0;
+}
+
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
+				int val)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+	return 0;
+}
+
+static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+	u32 bit = 1 << offset;
+
+	return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
+}
+
+static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
+				int val)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+	u32 bit = 1 << offset;
+
+	if (val)
+		writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
+	else
+		writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+/* This structure is replicated for each GPIO block allocated at probe time */
+static struct gpio_chip nmk_gpio_template = {
+	.direction_input	= nmk_gpio_make_input,
+	.get			= nmk_gpio_get_input,
+	.direction_output	= nmk_gpio_make_output,
+	.set			= nmk_gpio_set_output,
+	.ngpio			= NMK_GPIO_PER_CHIP,
+	.can_sleep		= 0,
+};
+
+static int __init nmk_gpio_probe(struct amba_device *dev, struct amba_id *id)
+{
+	struct nmk_gpio_platform_data *pdata;
+	struct nmk_gpio_chip *nmk_chip;
+	struct gpio_chip *chip;
+	int ret;
+
+	pdata = dev->dev.platform_data;
+	ret = amba_request_regions(dev, pdata->name);
+	if (ret)
+		return ret;
+
+	nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
+	if (!nmk_chip) {
+		ret = -ENOMEM;
+		goto out_amba;
+	}
+	/*
+	 * The virt address in nmk_chip->addr is in the nomadik register space,
+	 * so we can simply convert the resource address, without remapping
+	 */
+	nmk_chip->addr = io_p2v(dev->res.start);
+	nmk_chip->chip = nmk_gpio_template;
+	nmk_chip->parent_irq = pdata->parent_irq;
+
+	chip = &nmk_chip->chip;
+	chip->base = pdata->first_gpio;
+	chip->label = pdata->name;
+	chip->dev = &dev->dev;
+	chip->owner = THIS_MODULE;
+
+	ret = gpiochip_add(&nmk_chip->chip);
+	if (ret)
+		goto out_free;
+
+	amba_set_drvdata(dev, nmk_chip);
+
+	nmk_gpio_init_irq(nmk_chip);
+
+	dev_info(&dev->dev, "Bits %i-%i at address %p\n",
+		 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
+	return 0;
+
+ out_free:
+	kfree(nmk_chip);
+ out_amba:
+	amba_release_regions(dev);
+	dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
+		  pdata->first_gpio, pdata->first_gpio+31);
+	return ret;
+}
+
+static int nmk_gpio_remove(struct amba_device *dev)
+{
+	struct nmk_gpio_chip *nmk_chip;
+
+	nmk_chip = amba_get_drvdata(dev);
+	gpiochip_remove(&nmk_chip->chip);
+	kfree(nmk_chip);
+	amba_release_regions(dev);
+	return 0;
+}
+
+
+/* We have 0x1f080060 and 0x1f180060, accept both using the mask */
+static struct amba_id nmk_gpio_ids[] = {
+	{
+		.id	= 0x1f080060,
+		.mask	= 0xffefffff,
+	},
+	{0, 0},
+};
+
+static struct amba_driver nmk_gpio_driver = {
+	.drv = {
+		.owner = THIS_MODULE,
+		.name = "gpio",
+		},
+	.probe = nmk_gpio_probe,
+	.remove = nmk_gpio_remove,
+	.suspend = NULL, /* to be done */
+	.resume = NULL,
+	.id_table = nmk_gpio_ids,
+};
+
+static int __init nmk_gpio_init(void)
+{
+	return amba_driver_register(&nmk_gpio_driver);
+}
+
+arch_initcall(nmk_gpio_init);
+
+MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
+MODULE_DESCRIPTION("Nomadik GPIO Driver");
+MODULE_LICENSE("GPL");
+
+
diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c
new file mode 100644
index 0000000..abfe25a
--- /dev/null
+++ b/arch/arm/mach-nomadik/i2c-8815nhk.c
@@ -0,0 +1,65 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+/*
+ * There are two busses in the 8815NHK.
+ * They could, in theory, be driven by the hardware component, but we
+ * use bit-bang through GPIO by now, to keep things simple
+ */
+
+static struct i2c_gpio_platform_data nhk8815_i2c_data0 = {
+	/* keep defaults for timeouts; pins are push-pull bidirectional */
+	.scl_pin = 62,
+	.sda_pin = 63,
+};
+
+static struct i2c_gpio_platform_data nhk8815_i2c_data1 = {
+	/* keep defaults for timeouts; pins are push-pull bidirectional */
+	.scl_pin = 53,
+	.sda_pin = 54,
+};
+
+/* first bus: GPIO XX and YY */
+static struct platform_device nhk8815_i2c_dev0 = {
+	.name	= "i2c-gpio",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &nhk8815_i2c_data0,
+	},
+};
+/* second bus: GPIO XX and YY */
+static struct platform_device nhk8815_i2c_dev1 = {
+	.name	= "i2c-gpio",
+	.id	= 1,
+	.dev	= {
+		.platform_data = &nhk8815_i2c_data1,
+	},
+};
+
+static int __init nhk8815_i2c_init(void)
+{
+	nmk_gpio_set_mode(nhk8815_i2c_data0.scl_pin, NMK_GPIO_ALT_GPIO);
+	nmk_gpio_set_mode(nhk8815_i2c_data0.sda_pin, NMK_GPIO_ALT_GPIO);
+	platform_device_register(&nhk8815_i2c_dev0);
+
+	nmk_gpio_set_mode(nhk8815_i2c_data1.scl_pin, NMK_GPIO_ALT_GPIO);
+	nmk_gpio_set_mode(nhk8815_i2c_data1.sda_pin, NMK_GPIO_ALT_GPIO);
+	platform_device_register(&nhk8815_i2c_dev1);
+
+	return 0;
+}
+
+static void __exit nhk8815_i2c_exit(void)
+{
+	platform_device_unregister(&nhk8815_i2c_dev0);
+	platform_device_unregister(&nhk8815_i2c_dev1);
+	return;
+}
+
+module_init(nhk8815_i2c_init);
+module_exit(nhk8815_i2c_exit);
diff --git a/arch/arm/mach-nomadik/include/mach/clkdev.h b/arch/arm/mach-nomadik/include/mach/clkdev.h
new file mode 100644
index 0000000..04b37a8
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/debug-macro.S b/arch/arm/mach-nomadik/include/mach/debug-macro.S
new file mode 100644
index 0000000..e876990
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
+/*
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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.
+ *
+*/
+
+		.macro	addruart,rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1			@ MMU enabled?
+		moveq	\rx, #0x10000000	@ physical base address
+		movne	\rx, #0xf0000000	@ virtual base
+		add	\rx, \rx, #0x00100000
+		add	\rx, \rx, #0x000fb000
+		.endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-nomadik/include/mach/entry-macro.S b/arch/arm/mach-nomadik/include/mach/entry-macro.S
new file mode 100644
index 0000000..49f1aa3
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/entry-macro.S
@@ -0,0 +1,43 @@
+/*
+ * Low-level IRQ helper macros for Nomadik platforms
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	ldr	\base, =IO_ADDRESS(NOMADIK_IC_BASE)
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+	/* This stanza gets the irq mask from one of two status registers */
+	mov	\irqnr, #0
+	ldr	\irqstat, [\base, #VIC_REG_IRQSR0]	@ get masked status
+	cmp	\irqstat, #0
+	bne	1001f
+	add	\irqnr, \irqnr, #32
+	ldr	\irqstat, [\base, #VIC_REG_IRQSR1]	@ get masked status
+
+1001:	tst	\irqstat, #15
+	bne	1002f
+	add	\irqnr, \irqnr, #4
+	movs	\irqstat, \irqstat, lsr #4
+	bne	1001b
+1002:	tst	\irqstat, #1
+	bne	1003f
+	add	\irqnr, \irqnr, #1
+	movs	\irqstat, \irqstat, lsr #1
+	bne	1002b
+1003:	/* EQ will be set if no irqs pending */
+	.endm
diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h
new file mode 100644
index 0000000..61577c9
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/gpio.h
@@ -0,0 +1,71 @@
+/*
+ * Structures and registers for GPIO access in the Nomadik SoC
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ *     Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *
+ * 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 __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+/*
+ * These currently cause a function call to happen, they may be optimized
+ * if needed by adding cpu-specific defines to identify blocks
+ * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
+ */
+#define gpio_get_value  __gpio_get_value
+#define gpio_set_value  __gpio_set_value
+#define gpio_cansleep   __gpio_cansleep
+#define gpio_to_irq     __gpio_to_irq
+
+/*
+ * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
+ * the "gpio" namespace for generic and cross-machine functions
+ */
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT	0x00
+#define NMK_GPIO_DATS	0x04
+#define NMK_GPIO_DATC	0x08
+#define NMK_GPIO_PDIS	0x0c
+#define NMK_GPIO_DIR	0x10
+#define NMK_GPIO_DIRS	0x14
+#define NMK_GPIO_DIRC	0x18
+#define NMK_GPIO_SLPC	0x1c
+#define NMK_GPIO_AFSLA	0x20
+#define NMK_GPIO_AFSLB	0x24
+
+#define NMK_GPIO_RIMSC	0x40
+#define NMK_GPIO_FIMSC	0x44
+#define NMK_GPIO_IS	0x48
+#define NMK_GPIO_IC	0x4c
+#define NMK_GPIO_RWIMSC	0x50
+#define NMK_GPIO_FWIMSC	0x54
+#define NMK_GPIO_WKS	0x58
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO	0
+#define NMK_GPIO_ALT_A	1
+#define NMK_GPIO_ALT_B	2
+#define NMK_GPIO_ALT_C	(NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
+extern int nmk_gpio_get_mode(int gpio);
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+struct nmk_gpio_platform_data {
+	char *name;
+	int first_gpio;
+	int first_irq;
+	int parent_irq;
+};
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-nomadik/include/mach/hardware.h b/arch/arm/mach-nomadik/include/mach/hardware.h
new file mode 100644
index 0000000..6316dba
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/hardware.h
@@ -0,0 +1,90 @@
+/*
+ * This file contains the hardware definitions of the Nomadik.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Nomadik registers live from 0x1000.0000 to 0x1023.0000 -- currently */
+#define NOMADIK_IO_VIRTUAL	0xF0000000	/* VA of IO  */
+#define NOMADIK_IO_PHYSICAL	0x10000000	/* PA of IO */
+#define NOMADIK_IO_SIZE		0x00300000	/* 3MB for all regs */
+
+/* used in C code, so cast to proper type */
+#define io_p2v(x) ((void __iomem *)(x) \
+			- NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
+#define io_v2p(x) ((unsigned long)(x) \
+			- NOMADIK_IO_VIRTUAL + NOMADIK_IO_PHYSICAL)
+
+/* used in asm code, so no casts */
+#define IO_ADDRESS(x) ((x) - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
+
+/*
+ *   Base address defination for Nomadik Onchip Logic Block
+ */
+#define NOMADIK_FSMC_BASE	0x10100000	/* FSMC registers */
+#define NOMADIK_SDRAMC_BASE	0x10110000	/* SDRAM Controller */
+#define NOMADIK_CLCDC_BASE	0x10120000	/* CLCD Controller */
+#define NOMADIK_MDIF_BASE	0x10120000	/* MDIF */
+#define NOMADIK_DMA0_BASE	0x10130000	/* DMA0 Controller */
+#define NOMADIK_IC_BASE		0x10140000	/* Vectored Irq Controller */
+#define NOMADIK_DMA1_BASE	0x10150000	/* DMA1 Controller */
+#define NOMADIK_USB_BASE	0x10170000	/* USB-OTG conf reg base */
+#define NOMADIK_CRYP_BASE	0x10180000	/* Crypto processor */
+#define NOMADIK_SHA1_BASE	0x10190000	/* SHA-1 Processor */
+#define NOMADIK_XTI_BASE	0x101A0000	/* XTI */
+#define NOMADIK_RNG_BASE	0x101B0000	/* Random number generator */
+#define NOMADIK_SRC_BASE	0x101E0000	/* SRC base */
+#define NOMADIK_WDOG_BASE	0x101E1000	/* Watchdog */
+#define NOMADIK_MTU0_BASE	0x101E2000	/* Multiple Timer 0 */
+#define NOMADIK_MTU1_BASE	0x101E3000	/* Multiple Timer 1 */
+#define NOMADIK_GPIO0_BASE	0x101E4000	/* GPIO0 */
+#define NOMADIK_GPIO1_BASE	0x101E5000	/* GPIO1 */
+#define NOMADIK_GPIO2_BASE	0x101E6000	/* GPIO2 */
+#define NOMADIK_GPIO3_BASE	0x101E7000	/* GPIO3 */
+#define NOMADIK_RTC_BASE	0x101E8000	/* Real Time Clock base */
+#define NOMADIK_PMU_BASE	0x101E9000	/* Power Management Unit */
+#define NOMADIK_OWM_BASE	0x101EA000	/* One wire master */
+#define NOMADIK_SCR_BASE	0x101EF000	/* Secure Control registers */
+#define NOMADIK_MSP2_BASE	0x101F0000	/* MSP 2 interface */
+#define NOMADIK_MSP1_BASE	0x101F1000	/* MSP 1 interface */
+#define NOMADIK_UART2_BASE	0x101F2000	/* UART 2 interface */
+#define NOMADIK_SSIRx_BASE	0x101F3000	/* SSI 8-ch rx interface */
+#define NOMADIK_SSITx_BASE	0x101F4000	/* SSI 8-ch tx interface */
+#define NOMADIK_MSHC_BASE	0x101F5000	/* Memory Stick(Pro) Host */
+#define NOMADIK_SDI_BASE	0x101F6000	/* SD-card/MM-Card */
+#define NOMADIK_I2C1_BASE	0x101F7000	/* I2C1 interface */
+#define NOMADIK_I2C0_BASE	0x101F8000	/* I2C0 interface */
+#define NOMADIK_MSP0_BASE	0x101F9000	/* MSP 0 interface  */
+#define NOMADIK_FIRDA_BASE	0x101FA000	/* FIrDA interface  */
+#define NOMADIK_UART1_BASE	0x101FB000	/* UART 1 interface */
+#define NOMADIK_SSP_BASE	0x101FC000	/* SSP interface  */
+#define NOMADIK_UART0_BASE	0x101FD000	/* UART 0 interface */
+#define NOMADIK_SGA_BASE	0x101FE000	/* SGA interface */
+#define NOMADIK_L2CC_BASE	0x10210000	/* L2 Cache controller */
+
+/* Other ranges, not for p2v/v2p */
+#define NOMADIK_BACKUP_RAM	0x80010000
+#define NOMADIK_EBROM		0x80000000	/* Embedded boot ROM */
+#define NOMADIK_HAMACV_DMEM_BASE 0xA0100000	/* HAMACV Data Memory Start */
+#define NOMADIK_HAMACV_DMEM_END	0xA01FFFFF	/* HAMACV Data Memory End */
+#define NOMADIK_HAMACA_DMEM	0xA0200000	/* HAMACA Data Memory Space */
+
+#define NOMADIK_FSMC_VA		IO_ADDRESS(NOMADIK_FSMC_BASE)
+#define NOMADIK_MTU0_VA		IO_ADDRESS(NOMADIK_MTU0_BASE)
+#define NOMADIK_MTU1_VA		IO_ADDRESS(NOMADIK_MTU1_BASE)
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-nomadik/include/mach/io.h b/arch/arm/mach-nomadik/include/mach/io.h
new file mode 100644
index 0000000..2e1eca1
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-nomadik/include/mach/io.h   (copied from mach-sa1100)
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997  RMK     Created.
+ *  07-04-1999  RMK     Major cleanup
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)         __typesafe_io(a)
+#define __mem_pci(a)    (a)
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/irqs.h b/arch/arm/mach-nomadik/include/mach/irqs.h
new file mode 100644
index 0000000..8faabc5
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/irqs.h
@@ -0,0 +1,82 @@
+/*
+ *  mach-nomadik/include/mach/irqs.h
+ *
+ *  Copyright (C) ST Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#include <mach/hardware.h>
+
+#define IRQ_VIC_START		0	/* first VIC interrupt is 0 */
+
+/*
+ * Interrupt numbers generic for all Nomadik Chip cuts
+ */
+#define IRQ_WATCHDOG			0
+#define IRQ_SOFTINT			1
+#define IRQ_CRYPTO			2
+#define IRQ_OWM				3
+#define IRQ_MTU0			4
+#define IRQ_MTU1			5
+#define IRQ_GPIO0			6
+#define IRQ_GPIO1			7
+#define IRQ_GPIO2			8
+#define IRQ_GPIO3			9
+#define IRQ_RTC_RTT			10
+#define IRQ_SSP				11
+#define IRQ_UART0			12
+#define IRQ_DMA1			13
+#define IRQ_CLCD_MDIF			14
+#define IRQ_DMA0			15
+#define IRQ_PWRFAIL			16
+#define IRQ_UART1			17
+#define IRQ_FIRDA			18
+#define IRQ_MSP0			19
+#define IRQ_I2C0			20
+#define IRQ_I2C1			21
+#define IRQ_SDMMC			22
+#define IRQ_USBOTG			23
+#define IRQ_SVA_IT0			24
+#define IRQ_SVA_IT1			25
+#define IRQ_SAA_IT0			26
+#define IRQ_SAA_IT1			27
+#define IRQ_UART2			28
+#define IRQ_MSP2			31
+#define IRQ_L2CC			48
+#define IRQ_HPI				49
+#define IRQ_SKE				50
+#define IRQ_KP				51
+#define IRQ_MEMST			54
+#define IRQ_SGA_IT			58
+#define IRQ_USBM			60
+#define IRQ_MSP1			62
+
+#define NOMADIK_SOC_NR_IRQS		64
+
+/* After chip-specific IRQ numbers we have the GPIO ones */
+#define NOMADIK_NR_GPIO			128 /* last 4 not wired to pins */
+#define NOMADIK_GPIO_TO_IRQ(gpio)	((gpio) + NOMADIK_SOC_NR_IRQS)
+#define NOMADIK_IRQ_TO_GPIO(irq)	((irq) - NOMADIK_SOC_NR_IRQS)
+#define NR_IRQS				NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
+
+/* Following two are used by entry_macro.S, to access our dual-vic */
+#define VIC_REG_IRQSR0		0
+#define VIC_REG_IRQSR1		0x20
+
+#endif /* __ASM_ARCH_IRQS_H */
+
diff --git a/arch/arm/mach-nomadik/include/mach/memory.h b/arch/arm/mach-nomadik/include/mach/memory.h
new file mode 100644
index 0000000..1e5689d
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/memory.h
@@ -0,0 +1,28 @@
+/*
+ *  mach-nomadik/include/mach/memory.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET	UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h
new file mode 100644
index 0000000..76da7f0
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/mtu.h
@@ -0,0 +1,45 @@
+#ifndef __ASM_ARCH_MTU_H
+#define __ASM_ARCH_MTU_H
+
+/*
+ * The MTU device hosts four different counters, with 4 set of
+ * registers. These are register names.
+ */
+
+#define MTU_IMSC	0x00	/* Interrupt mask set/clear */
+#define MTU_RIS		0x04	/* Raw interrupt status */
+#define MTU_MIS		0x08	/* Masked interrupt status */
+#define MTU_ICR		0x0C	/* Interrupt clear register */
+
+/* per-timer registers take 0..3 as argument */
+#define MTU_LR(x)	(0x10 + 0x10 * (x) + 0x00)	/* Load value */
+#define MTU_VAL(x)	(0x10 + 0x10 * (x) + 0x04)	/* Current value */
+#define MTU_CR(x)	(0x10 + 0x10 * (x) + 0x08)	/* Control reg */
+#define MTU_BGLR(x)	(0x10 + 0x10 * (x) + 0x0c)	/* At next overflow */
+
+/* bits for the control register */
+#define MTU_CRn_ENA		0x80
+#define MTU_CRn_PERIODIC	0x40	/* if 0 = free-running */
+#define MTU_CRn_PRESCALE_MASK	0x0c
+#define MTU_CRn_PRESCALE_1		0x00
+#define MTU_CRn_PRESCALE_16		0x04
+#define MTU_CRn_PRESCALE_256		0x08
+#define MTU_CRn_32BITS		0x02
+#define MTU_CRn_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR*/
+
+/* Other registers are usual amba/primecell registers, currently not used */
+#define MTU_ITCR	0xff0
+#define MTU_ITOP	0xff4
+
+#define MTU_PERIPH_ID0	0xfe0
+#define MTU_PERIPH_ID1	0xfe4
+#define MTU_PERIPH_ID2	0xfe8
+#define MTU_PERIPH_ID3	0xfeC
+
+#define MTU_PCELL0	0xff0
+#define MTU_PCELL1	0xff4
+#define MTU_PCELL2	0xff8
+#define MTU_PCELL3	0xffC
+
+#endif /* __ASM_ARCH_MTU_H */
+
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h
new file mode 100644
index 0000000..a4e468c
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/setup.h
@@ -0,0 +1,22 @@
+
+/*
+ * These symbols are needed for board-specific files to call their
+ * own cpu-specific files
+ */
+
+#ifndef __ASM_ARCH_SETUP_H
+#define __ASM_ARCH_SETUP_H
+
+#include <asm/mach/time.h>
+#include <linux/init.h>
+
+#ifdef CONFIG_NOMADIK_8815
+
+extern void cpu8815_map_io(void);
+extern void cpu8815_platform_init(void);
+extern void cpu8815_init_irq(void);
+extern struct sys_timer nomadik_timer;
+
+#endif /* NOMADIK_8815 */
+
+#endif /*  __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h
new file mode 100644
index 0000000..7119f68
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/system.h
@@ -0,0 +1,45 @@
+/*
+ *  mach-nomadik/include/mach/system.h
+ *
+ *  Copyright (C) 2008 STMicroelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+	/*
+	 * This should do all the clock switching
+	 * and wait for interrupt tricks
+	 */
+	cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+	void __iomem *src_rstsr = io_p2v(NOMADIK_SRC_BASE + 0x18);
+
+	/* FIXME: use egpio when implemented */
+
+	/* Write anything to Reset status register */
+	writel(1, src_rstsr);
+}
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/timex.h b/arch/arm/mach-nomadik/include/mach/timex.h
new file mode 100644
index 0000000..318b889
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/timex.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE         2400000
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/uncompress.h b/arch/arm/mach-nomadik/include/mach/uncompress.h
new file mode 100644
index 0000000..071003b
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/uncompress.h
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (C) 2008 STMicroelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+
+/* we need the constants in amba/serial.h, but it refers to amba_device */
+struct amba_device;
+#include <linux/amba/serial.h>
+
+#define NOMADIK_UART_DR		0x101FB000
+#define NOMADIK_UART_LCRH	0x101FB02c
+#define NOMADIK_UART_CR		0x101FB030
+#define NOMADIK_UART_FR		0x101FB018
+
+static void putc(const char c)
+{
+	/* Do nothing if the UART is not enabled. */
+	if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
+		return;
+
+	if (c == '\n')
+		putc('\r');
+
+	while (readb(NOMADIK_UART_FR) & UART01x_FR_TXFF)
+		barrier();
+	writeb(c, NOMADIK_UART_DR);
+}
+
+static void flush(void)
+{
+	if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
+		return;
+	while (readb(NOMADIK_UART_FR) & UART01x_FR_BUSY)
+		barrier();
+}
+
+static inline void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog() /* nothing to do here */
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-nomadik/include/mach/vmalloc.h b/arch/arm/mach-nomadik/include/mach/vmalloc.h
new file mode 100644
index 0000000..be12e31
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/vmalloc.h
@@ -0,0 +1,2 @@
+
+#define VMALLOC_END       0xe8000000
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c
new file mode 100644
index 0000000..d1738e7
--- /dev/null
+++ b/arch/arm/mach-nomadik/timer.c
@@ -0,0 +1,164 @@
+/*
+ *  linux/arch/arm/mach-nomadik/timer.c
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/jiffies.h>
+#include <asm/mach/time.h>
+#include <mach/mtu.h>
+
+#define TIMER_CTRL	0x80	/* No divisor */
+#define TIMER_PERIODIC	0x40
+#define TIMER_SZ32BIT	0x02
+
+/* Initial value for SRC control register: all timers use MXTAL/8 source */
+#define SRC_CR_INIT_MASK	0x00007fff
+#define SRC_CR_INIT_VAL		0x2aaa8000
+
+static u32	nmdk_count;		/* accumulated count */
+static u32	nmdk_cycle;		/* write-once */
+static __iomem void *mtu_base;
+
+/*
+ * clocksource: the MTU device is a decrementing counters, so we negate
+ * the value being read.
+ */
+static cycle_t nmdk_read_timer(struct clocksource *cs)
+{
+	u32 count = readl(mtu_base + MTU_VAL(0));
+	return nmdk_count + nmdk_cycle - count;
+
+}
+
+static struct clocksource nmdk_clksrc = {
+	.name		= "mtu_0",
+	.rating		= 120,
+	.read		= nmdk_read_timer,
+	.shift		= 20,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Clockevent device: currently only periodic mode is supported
+ */
+static void nmdk_clkevt_mode(enum clock_event_mode mode,
+			     struct clock_event_device *dev)
+{
+	unsigned long flags;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		/* enable interrupts -- and count current value? */
+		raw_local_irq_save(flags);
+		writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
+		raw_local_irq_restore(flags);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		BUG(); /* Not supported, yet */
+		/* FALLTHROUGH */
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		/* disable irq */
+		raw_local_irq_save(flags);
+		writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
+		raw_local_irq_restore(flags);
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static struct clock_event_device nmdk_clkevt = {
+	.name		= "mtu_0",
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.shift		= 32,
+	.rating		= 100,
+	.set_mode	= nmdk_clkevt_mode,
+};
+
+/*
+ * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
+ * as we are the only users of mtu0 by now.
+ */
+static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
+{
+	/* ack: "interrupt clear register" */
+	writel( 1 << 0, mtu_base + MTU_ICR);
+
+	/* we can't count lost ticks, unfortunately */
+	nmdk_count += nmdk_cycle;
+	nmdk_clkevt.event_handler(&nmdk_clkevt);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static struct irqaction nmdk_timer_irq = {
+	.name		= "Nomadik Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER,
+	.handler	= nmdk_timer_interrupt,
+};
+
+static void nmdk_timer_reset(void)
+{
+	u32 cr;
+
+	writel(0, mtu_base + MTU_CR(0)); /* off */
+
+	/* configure load and background-load, and fire it up */
+	writel(nmdk_cycle, mtu_base + MTU_LR(0));
+	writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
+	cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
+	writel(cr, mtu_base + MTU_CR(0));
+	writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
+}
+
+static void __init nmdk_timer_init(void)
+{
+	u32 src_cr;
+	unsigned long rate;
+	int bits;
+
+	rate = CLOCK_TICK_RATE; /* 2.4MHz */
+	nmdk_cycle = (rate + HZ/2) / HZ;
+
+	/* Configure timer sources in "system reset controller" ctrl reg */
+	src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
+	src_cr &= SRC_CR_INIT_MASK;
+	src_cr |= SRC_CR_INIT_VAL;
+	writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
+
+	/* Save global pointer to mtu, used by functions above */
+	mtu_base = io_p2v(NOMADIK_MTU0_BASE);
+
+	/* Init the timer and register clocksource */
+	nmdk_timer_reset();
+
+	nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
+	bits =  8*sizeof(nmdk_count);
+	nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
+
+	clocksource_register(&nmdk_clksrc);
+
+	/* Register irq and clockevents */
+	setup_irq(IRQ_MTU0, &nmdk_timer_irq);
+	nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
+	nmdk_clkevt.cpumask = cpumask_of(0);
+	clockevents_register_device(&nmdk_clkevt);
+}
+
+struct sys_timer nomadik_timer = {
+	.init		= nmdk_timer_init,
+};
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index 8b40aac..42920f9 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -15,8 +15,11 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/serial_8250.h>
 
+#include <asm/serial.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -162,10 +165,6 @@ static struct omap_lcd_config ams_delta_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
-static struct omap_uart_config ams_delta_uart_config __initdata = {
-	.enabled_uarts = 1,
-};
-
 static struct omap_usb_config ams_delta_usb_config __initdata = {
 	.register_host	= 1,
 	.hmc_mode	= 16,
@@ -174,7 +173,6 @@ static struct omap_usb_config ams_delta_usb_config __initdata = {
 
 static struct omap_board_config_kernel ams_delta_config[] = {
 	{ OMAP_TAG_LCD,		&ams_delta_lcd_config },
-	{ OMAP_TAG_UART,	&ams_delta_uart_config },
 };
 
 static struct resource ams_delta_kp_resources[] = {
@@ -235,6 +233,41 @@ static void __init ams_delta_init(void)
 	platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
 }
 
+static struct plat_serial8250_port ams_delta_modem_ports[] = {
+	{
+		.membase	= (void *) AMS_DELTA_MODEM_VIRT,
+		.mapbase	= AMS_DELTA_MODEM_PHYS,
+		.irq		= -EINVAL, /* changed later */
+		.flags		= UPF_BOOT_AUTOCONF,
+		.irqflags	= IRQF_TRIGGER_RISING,
+		.iotype		= UPIO_MEM,
+		.regshift	= 1,
+		.uartclk	= BASE_BAUD * 16,
+	},
+	{ },
+};
+
+static struct platform_device ams_delta_modem_device = {
+	.name	= "serial8250",
+	.id	= PLAT8250_DEV_PLATFORM1,
+	.dev		= {
+		.platform_data = ams_delta_modem_ports,
+	},
+};
+
+static int __init ams_delta_modem_init(void)
+{
+	omap_cfg_reg(M14_1510_GPIO2);
+	ams_delta_modem_ports[0].irq = gpio_to_irq(2);
+
+	ams_delta_latch2_write(
+		AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC,
+		AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC);
+
+	return platform_device_register(&ams_delta_modem_device);
+}
+arch_initcall(ams_delta_modem_init);
+
 static void __init ams_delta_map_io(void)
 {
 	omap1_map_common_io();
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 19e0e92..a7ead1b 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -240,16 +240,11 @@ static int nand_dev_ready(struct omap_nand_platform_data *data)
 	return gpio_get_value(P2_NAND_RB_GPIO_PIN);
 }
 
-static struct omap_uart_config fsample_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1)),
-};
-
 static struct omap_lcd_config fsample_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
 static struct omap_board_config_kernel fsample_config[] = {
-	{ OMAP_TAG_UART,	&fsample_uart_config },
 	{ OMAP_TAG_LCD,		&fsample_lcd_config },
 };
 
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index e724940..fb47239 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -57,12 +57,7 @@ static struct omap_usb_config generic1610_usb_config __initdata = {
 };
 #endif
 
-static struct omap_uart_config generic_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_board_config_kernel generic_config[] __initdata = {
-	{ OMAP_TAG_UART,	&generic_uart_config },
 };
 
 static void __init omap_generic_init(void)
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index f695aa0..aab8603 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -360,16 +360,11 @@ static struct omap_usb_config h2_usb_config __initdata = {
 	.pins[1]	= 3,
 };
 
-static struct omap_uart_config h2_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_lcd_config h2_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
 static struct omap_board_config_kernel h2_config[] __initdata = {
-	{ OMAP_TAG_UART,	&h2_uart_config },
 	{ OMAP_TAG_LCD,		&h2_lcd_config },
 };
 
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index f597968..89586b8 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -313,16 +313,11 @@ static struct omap_usb_config h3_usb_config __initdata = {
 	.pins[1]	= 3,
 };
 
-static struct omap_uart_config h3_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_lcd_config h3_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
 static struct omap_board_config_kernel h3_config[] __initdata = {
-	{ OMAP_TAG_UART,	&h3_uart_config },
 	{ OMAP_TAG_LCD,		&h3_lcd_config },
 };
 
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 2fd9826..cc2abbb 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -368,13 +368,8 @@ static inline void innovator_mmc_init(void)
 }
 #endif
 
-static struct omap_uart_config innovator_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_board_config_kernel innovator_config[] = {
 	{ OMAP_TAG_LCD,		NULL },
-	{ OMAP_TAG_UART,	&innovator_uart_config },
 };
 
 static void __init innovator_init(void)
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index cf3247b..ed891b8 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -293,10 +293,6 @@ static struct omap_usb_config osk_usb_config __initdata = {
 	.pins[0]	= 2,
 };
 
-static struct omap_uart_config osk_uart_config __initdata = {
-	.enabled_uarts = (1 << 0),
-};
-
 #ifdef	CONFIG_OMAP_OSK_MISTRAL
 static struct omap_lcd_config osk_lcd_config __initdata = {
 	.ctrl_name	= "internal",
@@ -304,7 +300,6 @@ static struct omap_lcd_config osk_lcd_config __initdata = {
 #endif
 
 static struct omap_board_config_kernel osk_config[] __initdata = {
-	{ OMAP_TAG_UART,		&osk_uart_config },
 #ifdef	CONFIG_OMAP_OSK_MISTRAL
 	{ OMAP_TAG_LCD,			&osk_lcd_config },
 #endif
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 886b4c0..90dd043 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -212,10 +212,6 @@ static struct omap_lcd_config palmte_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
-static struct omap_uart_config palmte_uart_config __initdata = {
-	.enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
-};
-
 #ifdef CONFIG_APM
 /*
  * Values measured in 10 minute intervals averaged over 10 samples.
@@ -302,7 +298,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery)
 
 static struct omap_board_config_kernel palmte_config[] __initdata = {
 	{ OMAP_TAG_LCD,		&palmte_lcd_config },
-	{ OMAP_TAG_UART,	&palmte_uart_config },
 };
 
 static struct spi_board_info palmte_spi_info[] __initdata = {
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 4f1b448..8256139 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -274,13 +274,8 @@ static struct omap_lcd_config palmtt_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
-static struct omap_uart_config palmtt_uart_config __initdata = {
-	.enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
-};
-
 static struct omap_board_config_kernel palmtt_config[] __initdata = {
 	{ OMAP_TAG_LCD,		&palmtt_lcd_config	},
-	{ OMAP_TAG_UART,	&palmtt_uart_config	},
 };
 
 static void __init omap_mpu_wdt_mode(int mode) {
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 9a55c3c..81b6bde 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -244,13 +244,8 @@ static struct omap_lcd_config palmz71_lcd_config __initdata = {
 	.ctrl_name = "internal",
 };
 
-static struct omap_uart_config palmz71_uart_config __initdata = {
-	.enabled_uarts = (1 << 0) | (1 << 1) | (0 << 2),
-};
-
 static struct omap_board_config_kernel palmz71_config[] __initdata = {
 	{OMAP_TAG_LCD,	&palmz71_lcd_config},
-	{OMAP_TAG_UART,	&palmz71_uart_config},
 };
 
 static irqreturn_t
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index 3b9f907..8340669 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -208,16 +208,11 @@ static int nand_dev_ready(struct omap_nand_platform_data *data)
 	return gpio_get_value(P2_NAND_RB_GPIO_PIN);
 }
 
-static struct omap_uart_config perseus2_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1)),
-};
-
 static struct omap_lcd_config perseus2_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
 static struct omap_board_config_kernel perseus2_config[] __initdata = {
-	{ OMAP_TAG_UART,	&perseus2_uart_config },
 	{ OMAP_TAG_LCD,		&perseus2_lcd_config },
 };
 
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index c096577..02c85ca 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -369,13 +369,8 @@ static struct platform_device *sx1_devices[] __initdata = {
 };
 /*-----------------------------------------*/
 
-static struct omap_uart_config sx1_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_board_config_kernel sx1_config[] __initdata = {
 	{ OMAP_TAG_LCD,	&sx1_lcd_config },
-	{ OMAP_TAG_UART,	&sx1_uart_config },
 };
 
 /*-----------------------------------------*/
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 98275e0..c06e7a5 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -140,12 +140,7 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
 	.pins[2]	= 6,
 };
 
-static struct omap_uart_config voiceblue_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_board_config_kernel voiceblue_config[] = {
-	{ OMAP_TAG_UART, &voiceblue_uart_config },
 };
 
 static void __init voiceblue_init_irq(void)
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index bbbaeb0..0680843 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -71,7 +71,7 @@ static inline void omap_init_rtc(void) {}
 #  define INT_DSP_MAILBOX1	INT_1610_DSP_MAILBOX1
 #endif
 
-#define OMAP1_MBOX_BASE		IO_ADDRESS(OMAP16XX_MAILBOX_BASE)
+#define OMAP1_MBOX_BASE		OMAP1_IO_ADDRESS(OMAP16XX_MAILBOX_BASE)
 
 static struct resource mbox_resources[] = {
 	{
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index 3afe540..7030f92 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -29,9 +29,9 @@ extern void omapfb_reserve_sdram(void);
  */
 static struct map_desc omap_io_desc[] __initdata = {
 	{
-		.virtual	= IO_VIRT,
-		.pfn		= __phys_to_pfn(IO_PHYS),
-		.length		= IO_SIZE,
+		.virtual	= OMAP1_IO_VIRT,
+		.pfn		= __phys_to_pfn(OMAP1_IO_PHYS),
+		.length		= OMAP1_IO_SIZE,
 		.type		= MT_DEVICE
 	}
 };
diff --git a/arch/arm/mach-omap1/pm.h b/arch/arm/mach-omap1/pm.h
index 9ed5e2c..c4f05bd 100644
--- a/arch/arm/mach-omap1/pm.h
+++ b/arch/arm/mach-omap1/pm.h
@@ -39,11 +39,11 @@
  * Register and offset definitions to be used in PM assembler code
  * ----------------------------------------------------------------------------
  */
-#define CLKGEN_REG_ASM_BASE		IO_ADDRESS(0xfffece00)
+#define CLKGEN_REG_ASM_BASE		OMAP1_IO_ADDRESS(0xfffece00)
 #define ARM_IDLECT1_ASM_OFFSET		0x04
 #define ARM_IDLECT2_ASM_OFFSET		0x08
 
-#define TCMIF_ASM_BASE			IO_ADDRESS(0xfffecc00)
+#define TCMIF_ASM_BASE			OMAP1_IO_ADDRESS(0xfffecc00)
 #define EMIFS_CONFIG_ASM_OFFSET		0x0c
 #define EMIFF_SDRAM_CONFIG_ASM_OFFSET	0x20
 
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index f754cee..d496e50 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -64,7 +64,7 @@ static void __init omap_serial_reset(struct plat_serial8250_port *p)
 
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
-		.membase	= IO_ADDRESS(OMAP_UART1_BASE),
+		.membase	= OMAP1_IO_ADDRESS(OMAP_UART1_BASE),
 		.mapbase	= OMAP_UART1_BASE,
 		.irq		= INT_UART1,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -73,7 +73,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.uartclk	= OMAP16XX_BASE_BAUD * 16,
 	},
 	{
-		.membase	= IO_ADDRESS(OMAP_UART2_BASE),
+		.membase	= OMAP1_IO_ADDRESS(OMAP_UART2_BASE),
 		.mapbase	= OMAP_UART2_BASE,
 		.irq		= INT_UART2,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -82,7 +82,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.uartclk	= OMAP16XX_BASE_BAUD * 16,
 	},
 	{
-		.membase	= IO_ADDRESS(OMAP_UART3_BASE),
+		.membase	= OMAP1_IO_ADDRESS(OMAP_UART3_BASE),
 		.mapbase	= OMAP_UART3_BASE,
 		.irq		= INT_UART3,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -109,7 +109,6 @@ static struct platform_device serial_device = {
 void __init omap_serial_init(void)
 {
 	int i;
-	const struct omap_uart_config *info;
 
 	if (cpu_is_omap730()) {
 		serial_platform_data[0].regshift = 0;
@@ -131,19 +130,9 @@ void __init omap_serial_init(void)
 		serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
 	}
 
-	info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
-	if (info == NULL)
-		return;
-
 	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
 		unsigned char reg;
 
-		if (!((1 << i) & info->enabled_uarts)) {
-			serial_platform_data[i].membase = NULL;
-			serial_platform_data[i].mapbase = 0;
-			continue;
-		}
-
 		switch (i) {
 		case 0:
 			uart1_ck = clk_get(NULL, "uart1_ck");
diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S
index 261cdc4..7724e52 100644
--- a/arch/arm/mach-omap1/sram.S
+++ b/arch/arm/mach-omap1/sram.S
@@ -21,13 +21,13 @@
 ENTRY(omap1_sram_reprogram_clock)
 	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
 
-	mov	r2, #IO_ADDRESS(DPLL_CTL) & 0xff000000
-	orr	r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x00ff0000
-	orr	r2, r2, #IO_ADDRESS(DPLL_CTL) & 0x0000ff00
+	mov	r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0xff000000
+	orr	r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x00ff0000
+	orr	r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x0000ff00
 
-	mov	r3, #IO_ADDRESS(ARM_CKCTL) & 0xff000000
-	orr	r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x00ff0000
-	orr	r3, r3, #IO_ADDRESS(ARM_CKCTL) & 0x0000ff00
+	mov	r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0xff000000
+	orr	r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x00ff0000
+	orr	r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x0000ff00
 
 	tst	r0, #1 << 4			@ want lock mode?
 	beq	newck				@ nope
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 4d56408..1be6a21 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -62,8 +62,8 @@ typedef struct {
 	u32 read_tim;			/* READ_TIM,   R */
 } omap_mpu_timer_regs_t;
 
-#define omap_mpu_timer_base(n)						\
-((volatile omap_mpu_timer_regs_t*)IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
+#define omap_mpu_timer_base(n)							\
+((volatile omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
 				 (n)*OMAP_MPU_TIMER_OFFSET))
 
 static inline unsigned long omap_mpu_timer_read(int nr)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index a755eb5..75b1c7e 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -31,6 +31,11 @@ config MACH_OMAP_GENERIC
 	bool "Generic OMAP board"
 	depends on ARCH_OMAP2 && ARCH_OMAP24XX
 
+config MACH_OMAP2_TUSB6010
+	bool
+	depends on ARCH_OMAP2 && ARCH_OMAP2420
+	default y if MACH_NOKIA_N8X0
+
 config MACH_OMAP_H4
 	bool "OMAP 2420 H4 board"
 	depends on ARCH_OMAP2 && ARCH_OMAP24XX
@@ -68,6 +73,10 @@ config MACH_OMAP_3430SDP
 	bool "OMAP 3430 SDP board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
 
+config MACH_NOKIA_N8X0
+	bool "Nokia N800/N810"
+	depends on ARCH_OMAP2420
+
 config MACH_NOKIA_RX51
 	bool "Nokia RX-51 board"
 	depends on ARCH_OMAP3 && ARCH_OMAP34XX
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 735bae5..8cb1677 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -5,7 +5,7 @@
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
 
-omap-2-3-common				= irq.o sdrc.o
+omap-2-3-common				= irq.o sdrc.o omap_hwmod.o
 prcm-common				= prcm.o powerdomain.o
 clock-common				= clock.o clockdomain.o
 
@@ -35,6 +35,11 @@ obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 endif
 
+# PRCM
+obj-$(CONFIG_ARCH_OMAP2)		+= cm.o
+obj-$(CONFIG_ARCH_OMAP3)		+= cm.o
+obj-$(CONFIG_ARCH_OMAP4)		+= cm4xxx.o
+
 # Clock framework
 obj-$(CONFIG_ARCH_OMAP2)		+= clock24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= clock34xx.o
@@ -62,7 +67,7 @@ obj-$(CONFIG_MACH_OMAP3_PANDORA)	+= board-omap3pandora.o \
 					   mmc-twl4030.o
 obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o \
 					   mmc-twl4030.o
-
+obj-$(CONFIG_MACH_NOKIA_N8X0)		+= board-n8x0.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
 					   board-rx51-peripherals.o \
 					   mmc-twl4030.o
@@ -74,6 +79,7 @@ obj-$(CONFIG_MACH_OMAP_4430SDP)		+= board-4430sdp.o
 
 # Platform specific device init code
 obj-y					+= usb-musb.o
+obj-$(CONFIG_MACH_OMAP2_TUSB6010)	+= usb-tusb6010.o
 
 onenand-$(CONFIG_MTD_ONENAND_OMAP2)	:= gpmc-onenand.o
 obj-y					+= $(onenand-m) $(onenand-y)
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 8ec2a13..42217b3 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -139,23 +139,19 @@ static inline void board_smc91x_init(void)
 
 #endif
 
+static struct omap_board_config_kernel sdp2430_config[] = {
+	{OMAP_TAG_LCD, &sdp2430_lcd_config},
+};
+
 static void __init omap_2430sdp_init_irq(void)
 {
+	omap_board_config = sdp2430_config;
+	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
 	omap_gpio_init();
 }
 
-static struct omap_uart_config sdp2430_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
-static struct omap_board_config_kernel sdp2430_config[] = {
-	{OMAP_TAG_UART, &sdp2430_uart_config},
-	{OMAP_TAG_LCD, &sdp2430_lcd_config},
-};
-
-
 static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
@@ -205,8 +201,6 @@ static void __init omap_2430sdp_init(void)
 	omap2430_i2c_init();
 
 	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
-	omap_board_config = sdp2430_config;
-	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
 	omap_serial_init();
 	twl4030_mmc_init(mmc);
 	usb_musb_init();
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index ac262cd..bd57ec7 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -167,26 +167,23 @@ static struct platform_device *sdp3430_devices[] __initdata = {
 	&sdp3430_lcd_device,
 };
 
-static void __init omap_3430sdp_init_irq(void)
-{
-	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
-	omap_init_irq();
-	omap_gpio_init();
-}
-
-static struct omap_uart_config sdp3430_uart_config __initdata = {
-	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_lcd_config sdp3430_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
 
 static struct omap_board_config_kernel sdp3430_config[] __initdata = {
-	{ OMAP_TAG_UART,	&sdp3430_uart_config },
 	{ OMAP_TAG_LCD,		&sdp3430_lcd_config },
 };
 
+static void __init omap_3430sdp_init_irq(void)
+{
+	omap_board_config = sdp3430_config;
+	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+	omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
 static int sdp3430_batt_table[] = {
 /* 0 C*/
 30800, 29500, 28300, 27100,
@@ -478,12 +475,15 @@ static inline void board_smc91x_init(void)
 
 #endif
 
+static void enable_board_wakeup_source(void)
+{
+	omap_cfg_reg(AF26_34XX_SYS_NIRQ); /* T2 interrupt line (keypad) */
+}
+
 static void __init omap_3430sdp_init(void)
 {
 	omap3430_i2c_init();
 	platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices));
-	omap_board_config = sdp3430_config;
-	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
 	if (omap_rev() > OMAP3430_REV_ES1_0)
 		ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2;
 	else
@@ -495,6 +495,7 @@ static void __init omap_3430sdp_init(void)
 	omap_serial_init();
 	usb_musb_init();
 	board_smc91x_init();
+	enable_board_wakeup_source();
 }
 
 static void __init omap_3430sdp_map_io(void)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index b0c7402..eb37c40 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -39,7 +39,7 @@ static struct platform_device *sdp4430_devices[] __initdata = {
 };
 
 static struct omap_uart_config sdp4430_uart_config __initdata = {
-	.enabled_uarts	= (1 << 0) | (1 << 1) | (1 << 2),
+	.enabled_uarts	= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3),
 };
 
 static struct omap_lcd_config sdp4430_lcd_config __initdata = {
@@ -47,14 +47,13 @@ static struct omap_lcd_config sdp4430_lcd_config __initdata = {
 };
 
 static struct omap_board_config_kernel sdp4430_config[] __initdata = {
-	{ OMAP_TAG_UART,	&sdp4430_uart_config },
 	{ OMAP_TAG_LCD,		&sdp4430_lcd_config },
 };
 
 static void __init gic_init_irq(void)
 {
-	gic_dist_init(0, IO_ADDRESS(OMAP44XX_GIC_DIST_BASE), 29);
-	gic_cpu_init(0, IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
+	gic_dist_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_DIST_BASE), 29);
+	gic_cpu_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
 }
 
 static void __init omap_4430sdp_init_irq(void)
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index dcfc20d..7a2b54c 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -248,18 +248,6 @@ out:
 	clk_put(gpmc_fck);
 }
 
-static void __init omap_apollon_init_irq(void)
-{
-	omap2_init_common_hw(NULL, NULL);
-	omap_init_irq();
-	omap_gpio_init();
-	apollon_init_smc91x();
-}
-
-static struct omap_uart_config apollon_uart_config __initdata = {
-	.enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
-};
-
 static struct omap_usb_config apollon_usb_config __initdata = {
 	.register_dev	= 1,
 	.hmc_mode	= 0x14,	/* 0:dev 1:host1 2:disable */
@@ -272,10 +260,19 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
 };
 
 static struct omap_board_config_kernel apollon_config[] = {
-	{ OMAP_TAG_UART,	&apollon_uart_config },
 	{ OMAP_TAG_LCD,		&apollon_lcd_config },
 };
 
+static void __init omap_apollon_init_irq(void)
+{
+	omap_board_config = apollon_config;
+	omap_board_config_size = ARRAY_SIZE(apollon_config);
+	omap2_init_common_hw(NULL, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+	apollon_init_smc91x();
+}
+
 static void __init apollon_led_init(void)
 {
 	/* LED0 - AA10 */
@@ -324,8 +321,6 @@ static void __init omap_apollon_init(void)
 	 * if not needed.
 	 */
 	platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
-	omap_board_config = apollon_config;
-	omap_board_config_size = ARRAY_SIZE(apollon_config);
 	omap_serial_init();
 }
 
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index fd00aa0..2e09a1c 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -31,24 +31,19 @@
 #include <mach/board.h>
 #include <mach/common.h>
 
+static struct omap_board_config_kernel generic_config[] = {
+};
+
 static void __init omap_generic_init_irq(void)
 {
+	omap_board_config = generic_config;
+	omap_board_config_size = ARRAY_SIZE(generic_config);
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
 }
 
-static struct omap_uart_config generic_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
-static struct omap_board_config_kernel generic_config[] = {
-	{ OMAP_TAG_UART,	&generic_uart_config },
-};
-
 static void __init omap_generic_init(void)
 {
-	omap_board_config = generic_config;
-	omap_board_config_size = ARRAY_SIZE(generic_config);
 	omap_serial_init();
 }
 
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 7b1d61d..eaa02d0 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -268,18 +268,6 @@ static void __init h4_init_flash(void)
 	h4_flash_resource.end	= base + SZ_64M - 1;
 }
 
-static void __init omap_h4_init_irq(void)
-{
-	omap2_init_common_hw(NULL, NULL);
-	omap_init_irq();
-	omap_gpio_init();
-	h4_init_flash();
-}
-
-static struct omap_uart_config h4_uart_config __initdata = {
-	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_lcd_config h4_lcd_config __initdata = {
 	.ctrl_name	= "internal",
 };
@@ -318,10 +306,19 @@ static struct omap_usb_config h4_usb_config __initdata = {
 };
 
 static struct omap_board_config_kernel h4_config[] = {
-	{ OMAP_TAG_UART,	&h4_uart_config },
 	{ OMAP_TAG_LCD,		&h4_lcd_config },
 };
 
+static void __init omap_h4_init_irq(void)
+{
+	omap_board_config = h4_config;
+	omap_board_config_size = ARRAY_SIZE(h4_config);
+	omap2_init_common_hw(NULL, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+	h4_init_flash();
+}
+
 static struct at24_platform_data m24c01 = {
 	.byte_len	= SZ_1K / 8,
 	.page_size	= 16,
@@ -366,8 +363,6 @@ static void __init omap_h4_init(void)
 			ARRAY_SIZE(h4_i2c_board_info));
 
 	platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
-	omap_board_config = h4_config;
-	omap_board_config_size = ARRAY_SIZE(h4_config);
 	omap_usb_init(&h4_usb_config);
 	omap_serial_init();
 }
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index ea383f8..ec6854c 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -268,18 +268,6 @@ static inline void __init ldp_init_smsc911x(void)
 	gpio_direction_input(eth_gpio);
 }
 
-static void __init omap_ldp_init_irq(void)
-{
-	omap2_init_common_hw(NULL, NULL);
-	omap_init_irq();
-	omap_gpio_init();
-	ldp_init_smsc911x();
-}
-
-static struct omap_uart_config ldp_uart_config __initdata = {
-	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct platform_device ldp_lcd_device = {
 	.name		= "ldp_lcd",
 	.id		= -1,
@@ -290,10 +278,19 @@ static struct omap_lcd_config ldp_lcd_config __initdata = {
 };
 
 static struct omap_board_config_kernel ldp_config[] __initdata = {
-	{ OMAP_TAG_UART,	&ldp_uart_config },
 	{ OMAP_TAG_LCD,		&ldp_lcd_config },
 };
 
+static void __init omap_ldp_init_irq(void)
+{
+	omap_board_config = ldp_config;
+	omap_board_config_size = ARRAY_SIZE(ldp_config);
+	omap2_init_common_hw(NULL, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+	ldp_init_smsc911x();
+}
+
 static struct twl4030_usb_data ldp_usb_data = {
 	.usb_mode	= T2_USB_MODE_ULPI,
 };
@@ -377,8 +374,6 @@ static void __init omap_ldp_init(void)
 {
 	omap_i2c_init();
 	platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
-	omap_board_config = ldp_config;
-	omap_board_config_size = ARRAY_SIZE(ldp_config);
 	ts_gpio = 54;
 	ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
 	spi_register_board_info(ldp_spi_board_info,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
new file mode 100644
index 0000000..8341632
--- /dev/null
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -0,0 +1,150 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n8x0.c
+ *
+ * Copyright (C) 2005-2009 Nokia Corporation
+ * Author: Juha Yrjola <juha.yrjola@nokia.com>
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/stddef.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/musb.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/mcspi.h>
+#include <mach/onenand.h>
+#include <mach/serial.h>
+
+static struct omap2_mcspi_device_config p54spi_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel = 1,
+};
+
+static struct spi_board_info n800_spi_board_info[] __initdata = {
+	{
+		.modalias	= "p54spi",
+		.bus_num	= 2,
+		.chip_select	= 0,
+		.max_speed_hz   = 48000000,
+		.controller_data = &p54spi_mcspi_config,
+	},
+};
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+static struct mtd_partition onenand_partitions[] = {
+	{
+		.name           = "bootloader",
+		.offset         = 0,
+		.size           = 0x20000,
+		.mask_flags     = MTD_WRITEABLE,	/* Force read-only */
+	},
+	{
+		.name           = "config",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = 0x60000,
+	},
+	{
+		.name           = "kernel",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = 0x200000,
+	},
+	{
+		.name           = "initfs",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = 0x400000,
+	},
+	{
+		.name           = "rootfs",
+		.offset         = MTDPART_OFS_APPEND,
+		.size           = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct omap_onenand_platform_data board_onenand_data = {
+	.cs		= 0,
+	.gpio_irq	= 26,
+	.parts		= onenand_partitions,
+	.nr_parts	= ARRAY_SIZE(onenand_partitions),
+	.flags		= ONENAND_SYNC_READ,
+};
+
+static void __init n8x0_onenand_init(void)
+{
+	gpmc_onenand_init(&board_onenand_data);
+}
+
+#else
+
+static void __init n8x0_onenand_init(void) {}
+
+#endif
+
+static void __init n8x0_map_io(void)
+{
+	omap2_set_globals_242x();
+	omap2_map_common_io();
+}
+
+static void __init n8x0_init_irq(void)
+{
+	omap2_init_common_hw(NULL, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
+static void __init n8x0_init_machine(void)
+{
+	/* FIXME: add n810 spi devices */
+	spi_register_board_info(n800_spi_board_info,
+				ARRAY_SIZE(n800_spi_board_info));
+
+	omap_serial_init();
+	n8x0_onenand_init();
+}
+
+MACHINE_START(NOKIA_N800, "Nokia N800")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= n8x0_map_io,
+	.init_irq	= n8x0_init_irq,
+	.init_machine	= n8x0_init_machine,
+	.timer		= &omap_timer,
+MACHINE_END
+
+MACHINE_START(NOKIA_N810, "Nokia N810")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= n8x0_map_io,
+	.init_irq	= n8x0_init_irq,
+	.init_machine	= n8x0_init_machine,
+	.timer		= &omap_timer,
+MACHINE_END
+
+MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
+	.phys_io	= 0x48000000,
+	.io_pg_offst	= ((0xd8000000) >> 18) & 0xfffc,
+	.boot_params	= 0x80000100,
+	.map_io		= n8x0_map_io,
+	.init_irq	= n8x0_init_irq,
+	.init_machine	= n8x0_init_machine,
+	.timer		= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index e00ba12..500c995 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -108,10 +108,6 @@ static struct platform_device omap3beagle_nand_device = {
 
 #include "sdram-micron-mt46h32m32lf-6.h"
 
-static struct omap_uart_config omap3_beagle_uart_config __initdata = {
-	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct twl4030_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
@@ -249,11 +245,16 @@ static struct regulator_init_data beagle_vpll2 = {
 	.consumer_supplies	= &beagle_vdvi_supply,
 };
 
+static struct twl4030_usb_data beagle_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
 static struct twl4030_platform_data beagle_twldata = {
 	.irq_base	= TWL4030_IRQ_BASE,
 	.irq_end	= TWL4030_IRQ_END,
 
 	/* platform_data for children goes here */
+	.usb		= &beagle_usb_data,
 	.gpio		= &beagle_gpio_data,
 	.vmmc1		= &beagle_vmmc1,
 	.vsim		= &beagle_vsim,
@@ -280,17 +281,6 @@ static int __init omap3_beagle_i2c_init(void)
 	return 0;
 }
 
-static void __init omap3_beagle_init_irq(void)
-{
-	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
-			     mt46h32m32lf6_sdrc_params);
-	omap_init_irq();
-#ifdef CONFIG_OMAP_32K_TIMER
-	omap2_gp_clockevent_set_gptimer(12);
-#endif
-	omap_gpio_init();
-}
-
 static struct gpio_led gpio_leds[] = {
 	{
 		.name			= "beagleboard::usr0",
@@ -345,10 +335,22 @@ static struct platform_device keys_gpio = {
 };
 
 static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
-	{ OMAP_TAG_UART,	&omap3_beagle_uart_config },
 	{ OMAP_TAG_LCD,		&omap3_beagle_lcd_config },
 };
 
+static void __init omap3_beagle_init_irq(void)
+{
+	omap_board_config = omap3_beagle_config;
+	omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
+	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+			     mt46h32m32lf6_sdrc_params);
+	omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+	omap2_gp_clockevent_set_gptimer(12);
+#endif
+	omap_gpio_init();
+}
+
 static struct platform_device *omap3_beagle_devices[] __initdata = {
 	&omap3_beagle_lcd_device,
 	&leds_gpio,
@@ -398,8 +400,6 @@ static void __init omap3_beagle_init(void)
 	omap3_beagle_i2c_init();
 	platform_add_devices(omap3_beagle_devices,
 			ARRAY_SIZE(omap3_beagle_devices));
-	omap_board_config = omap3_beagle_config;
-	omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
 	omap_serial_init();
 
 	omap_cfg_reg(J25_34XX_GPIO170);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c4b1446..d50b9be 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -92,10 +92,6 @@ static inline void __init omap3evm_init_smc911x(void)
 	gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
 }
 
-static struct omap_uart_config omap3_evm_uart_config __initdata = {
-	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct twl4030_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
@@ -278,19 +274,20 @@ struct spi_board_info omap3evm_spi_board_info[] = {
 	},
 };
 
+static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
+	{ OMAP_TAG_LCD,		&omap3_evm_lcd_config },
+};
+
 static void __init omap3_evm_init_irq(void)
 {
+	omap_board_config = omap3_evm_config;
+	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 	omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
 	omap_init_irq();
 	omap_gpio_init();
 	omap3evm_init_smc911x();
 }
 
-static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
-	{ OMAP_TAG_UART,	&omap3_evm_uart_config },
-	{ OMAP_TAG_LCD,		&omap3_evm_lcd_config },
-};
-
 static struct platform_device *omap3_evm_devices[] __initdata = {
 	&omap3_evm_lcd_device,
 	&omap3evm_smc911x_device,
@@ -301,8 +298,6 @@ static void __init omap3_evm_init(void)
 	omap3_evm_i2c_init();
 
 	platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
-	omap_board_config = omap3_evm_config;
-	omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
 
 	spi_register_board_info(omap3evm_spi_board_info,
 				ARRAY_SIZE(omap3evm_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 864ee3d..b43f6e3 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -213,10 +213,6 @@ static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
 	{}	/* Terminator */
 };
 
-static struct omap_uart_config omap3pandora_uart_config __initdata = {
-	.enabled_uarts	= (1 << 2), /* UART3 */
-};
-
 static struct regulator_consumer_supply pandora_vmmc1_supply = {
 	.supply			= "vmmc",
 };
@@ -309,14 +305,6 @@ static int __init omap3pandora_i2c_init(void)
 	return 0;
 }
 
-static void __init omap3pandora_init_irq(void)
-{
-	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
-			     mt46h32m32lf6_sdrc_params);
-	omap_init_irq();
-	omap_gpio_init();
-}
-
 static void __init omap3pandora_ads7846_init(void)
 {
 	int gpio = OMAP3_PANDORA_TS_GPIO;
@@ -376,10 +364,19 @@ static struct omap_lcd_config omap3pandora_lcd_config __initdata = {
 };
 
 static struct omap_board_config_kernel omap3pandora_config[] __initdata = {
-	{ OMAP_TAG_UART,	&omap3pandora_uart_config },
 	{ OMAP_TAG_LCD,		&omap3pandora_lcd_config },
 };
 
+static void __init omap3pandora_init_irq(void)
+{
+	omap_board_config = omap3pandora_config;
+	omap_board_config_size = ARRAY_SIZE(omap3pandora_config);
+	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+			     mt46h32m32lf6_sdrc_params);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
 static struct platform_device *omap3pandora_devices[] __initdata = {
 	&omap3pandora_lcd_device,
 	&pandora_leds_gpio,
@@ -391,8 +388,6 @@ static void __init omap3pandora_init(void)
 	omap3pandora_i2c_init();
 	platform_add_devices(omap3pandora_devices,
 			ARRAY_SIZE(omap3pandora_devices));
-	omap_board_config = omap3pandora_config;
-	omap_board_config_size = ARRAY_SIZE(omap3pandora_config);
 	omap_serial_init();
 	spi_register_board_info(omap3pandora_spi_board_info,
 			ARRAY_SIZE(omap3pandora_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 6bce230..9917d2f 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -271,9 +271,6 @@ static void __init overo_flash_init(void)
 			printk(KERN_ERR "Unable to register NAND device\n");
 	}
 }
-static struct omap_uart_config overo_uart_config __initdata = {
-	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
-};
 
 static struct twl4030_hsmmc_info mmc[] = {
 	{
@@ -360,14 +357,6 @@ static int __init overo_i2c_init(void)
 	return 0;
 }
 
-static void __init overo_init_irq(void)
-{
-	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
-			     mt46h32m32lf6_sdrc_params);
-	omap_init_irq();
-	omap_gpio_init();
-}
-
 static struct platform_device overo_lcd_device = {
 	.name		= "overo_lcd",
 	.id		= -1,
@@ -378,10 +367,19 @@ static struct omap_lcd_config overo_lcd_config __initdata = {
 };
 
 static struct omap_board_config_kernel overo_config[] __initdata = {
-	{ OMAP_TAG_UART,	&overo_uart_config },
 	{ OMAP_TAG_LCD,		&overo_lcd_config },
 };
 
+static void __init overo_init_irq(void)
+{
+	omap_board_config = overo_config;
+	omap_board_config_size = ARRAY_SIZE(overo_config);
+	omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+			     mt46h32m32lf6_sdrc_params);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
 static struct platform_device *overo_devices[] __initdata = {
 	&overo_lcd_device,
 };
@@ -390,8 +388,6 @@ static void __init overo_init(void)
 {
 	overo_i2c_init();
 	platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
-	omap_board_config = overo_config;
-	omap_board_config_size = ARRAY_SIZE(overo_config);
 	omap_serial_init();
 	overo_flash_init();
 	usb_musb_init();
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 56d931a..e70baa7 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -1,5 +1,5 @@
 /*
- * linux/arch/arm/mach-omap2/board-rx51-flash.c
+ * linux/arch/arm/mach-omap2/board-rx51-peripherals.c
  *
  * Copyright (C) 2008-2009 Nokia
  *
@@ -282,7 +282,124 @@ static struct twl4030_usb_data rx51_usb_data = {
 	.usb_mode		= T2_USB_MODE_ULPI,
 };
 
-static struct twl4030_platform_data rx51_twldata = {
+static struct twl4030_ins sleep_on_seq[] __initdata = {
+/*
+ * Turn off VDD1 and VDD2.
+ */
+	{MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_OFF), 4},
+	{MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_OFF), 2},
+/*
+ * And also turn off the OMAP3 PLLs and the sysclk output.
+ */
+	{MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_OFF), 3},
+	{MSG_SINGULAR(DEV_GRP_P1, 0x17, RES_STATE_OFF), 3},
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+	.script = sleep_on_seq,
+	.size   = ARRAY_SIZE(sleep_on_seq),
+	.flags  = TWL4030_SLEEP_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_seq[] __initdata = {
+/*
+ * Reenable the OMAP3 PLLs.
+ * Wakeup VDD1 and VDD2.
+ * Reenable sysclk output.
+ */
+	{MSG_SINGULAR(DEV_GRP_P1, 0x7, RES_STATE_ACTIVE), 0x30},
+	{MSG_SINGULAR(DEV_GRP_P1, 0xf, RES_STATE_ACTIVE), 0x30},
+	{MSG_SINGULAR(DEV_GRP_P1, 0x10, RES_STATE_ACTIVE), 0x37},
+	{MSG_SINGULAR(DEV_GRP_P1, 0x19, RES_STATE_ACTIVE), 3},
+};
+
+static struct twl4030_script wakeup_script __initdata = {
+	.script	= wakeup_seq,
+	.size	= ARRAY_SIZE(wakeup_seq),
+	.flags	= TWL4030_WAKEUP12_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_p3_seq[] __initdata = {
+/*
+ * Wakeup VDD1 (dummy to be able to insert a delay)
+ * Enable CLKEN
+ */
+	{MSG_SINGULAR(DEV_GRP_P1, 0x17, RES_STATE_ACTIVE), 3},
+};
+
+static struct twl4030_script wakeup_p3_script __initdata = {
+	.script	= wakeup_p3_seq,
+	.size	= ARRAY_SIZE(wakeup_p3_seq),
+	.flags	= TWL4030_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_ins wrst_seq[] __initdata = {
+/*
+ * Reset twl4030.
+ * Reset VDD1 regulator.
+ * Reset VDD2 regulator.
+ * Reset VPLL1 regulator.
+ * Enable sysclk output.
+ * Reenable twl4030.
+ */
+	{MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2},
+	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 0, 1, RES_STATE_ACTIVE),
+		0x13},
+	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 2, RES_STATE_WRST), 0x13},
+	{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 3, RES_STATE_OFF), 0x13},
+	{MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x13},
+	{MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x13},
+	{MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x35},
+	{MSG_SINGULAR(DEV_GRP_P1, RES_HFCLKOUT, RES_STATE_ACTIVE), 2},
+	{MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wrst_script __initdata = {
+	.script = wrst_seq,
+	.size   = ARRAY_SIZE(wrst_seq),
+	.flags  = TWL4030_WRST_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+	/* wakeup12 script should be loaded before sleep script, otherwise a
+	   board might hit retention before loading of wakeup script is
+	   completed. This can cause boot failures depending on timing issues.
+	*/
+	&wakeup_script,
+	&sleep_on_script,
+	&wakeup_p3_script,
+	&wrst_script,
+};
+
+static struct twl4030_resconfig twl4030_rconfig[] __initdata = {
+	{ .resource = RES_VINTANA1, .devgroup = -1, .type = -1, .type2 = 1 },
+	{ .resource = RES_VINTANA2, .devgroup = -1, .type = -1, .type2 = 1 },
+	{ .resource = RES_VINTDIG, .devgroup = -1, .type = -1, .type2 = 1 },
+	{ .resource = RES_VMMC1, .devgroup = -1, .type = -1, .type2 = 3},
+	{ .resource = RES_VMMC2, .devgroup = DEV_GRP_NULL, .type = -1,
+	  .type2 = 3},
+	{ .resource = RES_VAUX1, .devgroup = -1, .type = -1, .type2 = 3},
+	{ .resource = RES_VAUX2, .devgroup = -1, .type = -1, .type2 = 3},
+	{ .resource = RES_VAUX3, .devgroup = -1, .type = -1, .type2 = 3},
+	{ .resource = RES_VAUX4, .devgroup = -1, .type = -1, .type2 = 3},
+	{ .resource = RES_VPLL2, .devgroup = -1, .type = -1, .type2 = 3},
+	{ .resource = RES_VDAC, .devgroup = -1, .type = -1, .type2 = 3},
+	{ .resource = RES_VSIM, .devgroup = DEV_GRP_NULL, .type = -1,
+	  .type2 = 3},
+	{ .resource = RES_CLKEN, .devgroup = DEV_GRP_P3, .type = -1,
+		.type2 = 1 },
+	{ 0, 0},
+};
+
+static struct twl4030_power_data rx51_t2scripts_data __initdata = {
+	.scripts        = twl4030_scripts,
+	.num = ARRAY_SIZE(twl4030_scripts),
+	.resource_config = twl4030_rconfig,
+};
+
+
+
+static struct twl4030_platform_data rx51_twldata __initdata = {
 	.irq_base		= TWL4030_IRQ_BASE,
 	.irq_end		= TWL4030_IRQ_END,
 
@@ -291,6 +408,7 @@ static struct twl4030_platform_data rx51_twldata = {
 	.keypad			= &rx51_kp_data,
 	.madc			= &rx51_madc_data,
 	.usb			= &rx51_usb_data,
+	.power			= &rx51_t2scripts_data,
 
 	.vaux1			= &rx51_vaux1,
 	.vaux2			= &rx51_vaux2,
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 1c9e07f..f9196c3 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -31,10 +31,6 @@
 #include <mach/gpmc.h>
 #include <mach/usb.h>
 
-static struct omap_uart_config rx51_uart_config = {
-	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
-};
-
 static struct omap_lcd_config rx51_lcd_config = {
 	.ctrl_name	= "internal",
 };
@@ -52,7 +48,6 @@ static struct omap_fbmem_config rx51_fbmem2_config = {
 };
 
 static struct omap_board_config_kernel rx51_config[] = {
-	{ OMAP_TAG_UART,	&rx51_uart_config },
 	{ OMAP_TAG_FBMEM,	&rx51_fbmem0_config },
 	{ OMAP_TAG_FBMEM,	&rx51_fbmem1_config },
 	{ OMAP_TAG_FBMEM,	&rx51_fbmem2_config },
@@ -61,6 +56,8 @@ static struct omap_board_config_kernel rx51_config[] = {
 
 static void __init rx51_init_irq(void)
 {
+	omap_board_config = rx51_config;
+	omap_board_config_size = ARRAY_SIZE(rx51_config);
 	omap2_init_common_hw(NULL, NULL);
 	omap_init_irq();
 	omap_gpio_init();
@@ -70,8 +67,6 @@ extern void __init rx51_peripherals_init(void);
 
 static void __init rx51_init(void)
 {
-	omap_board_config = rx51_config;
-	omap_board_config_size = ARRAY_SIZE(rx51_config);
 	omap_serial_init();
 	usb_musb_init();
 	rx51_peripherals_init();
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
index bac5c43..1f13e2a 100644
--- a/arch/arm/mach-omap2/board-zoom-debugboard.c
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -12,6 +12,7 @@
 #include <linux/gpio.h>
 #include <linux/serial_8250.h>
 #include <linux/smsc911x.h>
+#include <linux/interrupt.h>
 
 #include <mach/gpmc.h>
 
@@ -84,6 +85,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.mapbase	= 0x10000000,
 		.irq		= OMAP_GPIO_IRQ(102),
 		.flags		= UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ,
+		.irqflags	= IRQF_SHARED | IRQF_TRIGGER_RISING,
 		.iotype		= UPIO_MEM,
 		.regshift	= 1,
 		.uartclk	= QUART_CLK,
@@ -94,7 +96,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 
 static struct platform_device zoom2_debugboard_serial_device = {
 	.name			= "serial8250",
-	.id			= PLAT8250_DEV_PLATFORM1,
+	.id			= 3,
 	.dev			= {
 		.platform_data	= serial_platform_data,
 	},
@@ -127,6 +129,7 @@ static inline void __init zoom2_init_quaduart(void)
 static inline int omap_zoom2_debugboard_detect(void)
 {
 	int debug_board_detect = 0;
+	int ret = 1;
 
 	debug_board_detect = ZOOM2_SMSC911X_GPIO;
 
@@ -138,10 +141,10 @@ static inline int omap_zoom2_debugboard_detect(void)
 	gpio_direction_input(debug_board_detect);
 
 	if (!gpio_get_value(debug_board_detect)) {
-		gpio_free(debug_board_detect);
-		return 0;
+		ret = 0;
 	}
-	return 1;
+	gpio_free(debug_board_detect);
+	return ret;
 }
 
 static struct platform_device *zoom2_devices[] __initdata = {
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 427b7b8..324009e 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -12,36 +12,217 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/input.h>
 #include <linux/gpio.h>
 #include <linux/i2c/twl4030.h>
+#include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
 #include <mach/common.h>
 #include <mach/usb.h>
+#include <mach/keypad.h>
 
 #include "mmc-twl4030.h"
 
-static void __init omap_zoom2_init_irq(void)
+/* Zoom2 has Qwerty keyboard*/
+static int zoom2_twl4030_keymap[] = {
+	KEY(0, 0, KEY_E),
+	KEY(1, 0, KEY_R),
+	KEY(2, 0, KEY_T),
+	KEY(3, 0, KEY_HOME),
+	KEY(6, 0, KEY_I),
+	KEY(7, 0, KEY_LEFTSHIFT),
+	KEY(0, 1, KEY_D),
+	KEY(1, 1, KEY_F),
+	KEY(2, 1, KEY_G),
+	KEY(3, 1, KEY_SEND),
+	KEY(6, 1, KEY_K),
+	KEY(7, 1, KEY_ENTER),
+	KEY(0, 2, KEY_X),
+	KEY(1, 2, KEY_C),
+	KEY(2, 2, KEY_V),
+	KEY(3, 2, KEY_END),
+	KEY(6, 2, KEY_DOT),
+	KEY(7, 2, KEY_CAPSLOCK),
+	KEY(0, 3, KEY_Z),
+	KEY(1, 3, KEY_KPPLUS),
+	KEY(2, 3, KEY_B),
+	KEY(3, 3, KEY_F1),
+	KEY(6, 3, KEY_O),
+	KEY(7, 3, KEY_SPACE),
+	KEY(0, 4, KEY_W),
+	KEY(1, 4, KEY_Y),
+	KEY(2, 4, KEY_U),
+	KEY(3, 4, KEY_F2),
+	KEY(4, 4, KEY_VOLUMEUP),
+	KEY(6, 4, KEY_L),
+	KEY(7, 4, KEY_LEFT),
+	KEY(0, 5, KEY_S),
+	KEY(1, 5, KEY_H),
+	KEY(2, 5, KEY_J),
+	KEY(3, 5, KEY_F3),
+	KEY(5, 5, KEY_VOLUMEDOWN),
+	KEY(6, 5, KEY_M),
+	KEY(4, 5, KEY_ENTER),
+	KEY(7, 5, KEY_RIGHT),
+	KEY(0, 6, KEY_Q),
+	KEY(1, 6, KEY_A),
+	KEY(2, 6, KEY_N),
+	KEY(3, 6, KEY_BACKSPACE),
+	KEY(6, 6, KEY_P),
+	KEY(7, 6, KEY_UP),
+	KEY(6, 7, KEY_SELECT),
+	KEY(7, 7, KEY_DOWN),
+	KEY(0, 7, KEY_PROG1),	/*MACRO 1 <User defined> */
+	KEY(1, 7, KEY_PROG2),	/*MACRO 2 <User defined> */
+	KEY(2, 7, KEY_PROG3),	/*MACRO 3 <User defined> */
+	KEY(3, 7, KEY_PROG4),	/*MACRO 4 <User defined> */
+	0
+};
+
+static struct twl4030_keypad_data zoom2_kp_twl4030_data = {
+	.rows		= 8,
+	.cols		= 8,
+	.keymap		= zoom2_twl4030_keymap,
+	.keymapsize	= ARRAY_SIZE(zoom2_twl4030_keymap),
+	.rep		= 1,
+};
+
+static struct omap_board_config_kernel zoom2_config[] __initdata = {
+};
+
+static struct regulator_consumer_supply zoom2_vmmc1_supply = {
+	.supply		= "vmmc",
+};
+
+static struct regulator_consumer_supply zoom2_vsim_supply = {
+	.supply		= "vmmc_aux",
+};
+
+static struct regulator_consumer_supply zoom2_vmmc2_supply = {
+	.supply		= "vmmc",
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data zoom2_vmmc1 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 3150000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &zoom2_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data zoom2_vmmc2 = {
+	.constraints = {
+		.min_uV			= 1850000,
+		.max_uV			= 1850000,
+		.apply_uV		= true,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &zoom2_vmmc2_supply,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data zoom2_vsim = {
+	.constraints = {
+		.min_uV			= 1800000,
+		.max_uV			= 3000000,
+		.valid_modes_mask	= REGULATOR_MODE_NORMAL
+					| REGULATOR_MODE_STANDBY,
+		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
+					| REGULATOR_CHANGE_MODE
+					| REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = 1,
+	.consumer_supplies      = &zoom2_vsim_supply,
+};
+
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+	{
+		.mmc		= 1,
+		.wires		= 4,
+		.gpio_wp	= -EINVAL,
+	},
+	{
+		.mmc		= 2,
+		.wires		= 4,
+		.gpio_wp	= -EINVAL,
+	},
+	{}      /* Terminator */
+};
+
+static int zoom2_twl_gpio_setup(struct device *dev,
+		unsigned gpio, unsigned ngpio)
 {
-	omap2_init_common_hw(NULL, NULL);
-	omap_init_irq();
-	omap_gpio_init();
+	/* gpio + 0 is "mmc0_cd" (input/IRQ),
+	 * gpio + 1 is "mmc1_cd" (input/IRQ)
+	 */
+	mmc[0].gpio_cd = gpio + 0;
+	mmc[1].gpio_cd = gpio + 1;
+	twl4030_mmc_init(mmc);
+
+	/* link regulators to MMC adapters ... we "know" the
+	 * regulators will be set up only *after* we return.
+	*/
+	zoom2_vmmc1_supply.dev = mmc[0].dev;
+	zoom2_vsim_supply.dev = mmc[0].dev;
+	zoom2_vmmc2_supply.dev = mmc[1].dev;
+
+	return 0;
 }
 
-static struct omap_uart_config zoom2_uart_config __initdata = {
-	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
+
+static int zoom2_batt_table[] = {
+/* 0 C*/
+30800, 29500, 28300, 27100,
+26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
+17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
+11600, 11200, 10800, 10400, 10000, 9630,  9280,  8950,  8620,  8310,
+8020,  7730,  7460,  7200,  6950,  6710,  6470,  6250,  6040,  5830,
+5640,  5450,  5260,  5090,  4920,  4760,  4600,  4450,  4310,  4170,
+4040,  3910,  3790,  3670,  3550
 };
 
-static struct omap_board_config_kernel zoom2_config[] __initdata = {
-	{ OMAP_TAG_UART,	&zoom2_uart_config },
+static struct twl4030_bci_platform_data zoom2_bci_data = {
+	.battery_tmp_tbl	= zoom2_batt_table,
+	.tblsize		= ARRAY_SIZE(zoom2_batt_table),
 };
 
+static struct twl4030_usb_data zoom2_usb_data = {
+	.usb_mode	= T2_USB_MODE_ULPI,
+};
+
+static void __init omap_zoom2_init_irq(void)
+{
+	omap_board_config = zoom2_config;
+	omap_board_config_size = ARRAY_SIZE(zoom2_config);
+	omap2_init_common_hw(NULL, NULL);
+	omap_init_irq();
+	omap_gpio_init();
+}
+
 static struct twl4030_gpio_platform_data zoom2_gpio_data = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
+	.setup		= zoom2_twl_gpio_setup,
+};
+
+static struct twl4030_madc_platform_data zoom2_madc_data = {
+	.irq_line	= 1,
 };
 
 static struct twl4030_platform_data zoom2_twldata = {
@@ -49,7 +230,15 @@ static struct twl4030_platform_data zoom2_twldata = {
 	.irq_end	= TWL4030_IRQ_END,
 
 	/* platform_data for children goes here */
+	.bci		= &zoom2_bci_data,
+	.madc		= &zoom2_madc_data,
+	.usb		= &zoom2_usb_data,
 	.gpio		= &zoom2_gpio_data,
+	.keypad		= &zoom2_kp_twl4030_data,
+	.vmmc1          = &zoom2_vmmc1,
+	.vmmc2          = &zoom2_vmmc2,
+	.vsim           = &zoom2_vsim,
+
 };
 
 static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = {
@@ -70,26 +259,13 @@ static int __init omap_i2c_init(void)
 	return 0;
 }
 
-static struct twl4030_hsmmc_info mmc[] __initdata = {
-	{
-		.mmc		= 1,
-		.wires		= 4,
-		.gpio_cd	= -EINVAL,
-		.gpio_wp	= -EINVAL,
-	},
-	{}	/* Terminator */
-};
-
 extern int __init omap_zoom2_debugboard_init(void);
 
 static void __init omap_zoom2_init(void)
 {
 	omap_i2c_init();
-	omap_board_config = zoom2_config;
-	omap_board_config_size = ARRAY_SIZE(zoom2_config);
 	omap_serial_init();
 	omap_zoom2_debugboard_init();
-	twl4030_mmc_init(mmc);
 	usb_musb_init();
 }
 
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 456e2ad..f2a92d6 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -1043,5 +1043,7 @@ void omap2_clk_disable_unused(struct clk *clk)
 		omap2_clk_disable(clk);
 	} else
 		_omap2_clk_disable(clk);
+	if (clk->clkdm != NULL)
+		pwrdm_clkdm_state_switch(clk->clkdm);
 }
 #endif
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index cd7819c..fafcd32 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -27,6 +27,7 @@
 #include <linux/limits.h>
 #include <linux/bitops.h>
 
+#include <mach/cpu.h>
 #include <mach/clock.h>
 #include <mach/sram.h>
 #include <asm/div64.h>
@@ -1067,17 +1068,17 @@ static int __init omap2_clk_arch_init(void)
 		return -EINVAL;
 
 	/* REVISIT: not yet ready for 343x */
-#if 0
-	if (clk_set_rate(&virt_prcm_set, mpurate))
-		printk(KERN_ERR "Could not find matching MPU rate\n");
-#endif
+	if (clk_set_rate(&dpll1_ck, mpurate))
+		printk(KERN_ERR "*** Unable to set MPU rate\n");
 
 	recalculate_root_clocks();
 
-	printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL3/MPU): "
+	printk(KERN_INFO "Switched to new clocking rate (Crystal/Core/MPU): "
 	       "%ld.%01ld/%ld/%ld MHz\n",
-	       (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
-	       (core_ck.rate / 1000000), (dpll1_fck.rate / 1000000)) ;
+	       (osc_sys_ck.rate / 1000000), ((osc_sys_ck.rate / 100000) % 10),
+	       (core_ck.rate / 1000000), (arm_fck.rate / 1000000)) ;
+
+	calibrate_delay();
 
 	return 0;
 }
@@ -1136,7 +1137,7 @@ int __init omap2_clk_init(void)
 
 	recalculate_root_clocks();
 
-	printk(KERN_INFO "Clocking rate (Crystal/DPLL/ARM core): "
+	printk(KERN_INFO "Clocking rate (Crystal/Core/MPU): "
 	       "%ld.%01ld/%ld/%ld MHz\n",
 	       (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
 	       (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 57cc272..c811978 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -1020,6 +1020,7 @@ static struct clk arm_fck = {
 	.clksel_reg	= OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
 	.clksel_mask	= OMAP3430_ST_MPU_CLK_MASK,
 	.clksel		= arm_fck_clksel,
+	.clkdm_name	= "mpu_clkdm",
 	.recalc		= &omap2_clksel_recalc,
 };
 
@@ -1155,7 +1156,6 @@ static struct clk gfx_cg1_ck = {
 	.name		= "gfx_cg1_ck",
 	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES1_EN_2D_SHIFT,
 	.clkdm_name	= "gfx_3430es1_clkdm",
@@ -1166,7 +1166,6 @@ static struct clk gfx_cg2_ck = {
 	.name		= "gfx_cg2_ck",
 	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &gfx_l3_fck, /* REVISIT: correct? */
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES1_EN_3D_SHIFT,
 	.clkdm_name	= "gfx_3430es1_clkdm",
@@ -1210,7 +1209,6 @@ static struct clk sgx_ick = {
 	.name		= "sgx_ick",
 	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &l3_ick,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
 	.clkdm_name	= "sgx_clkdm",
@@ -1223,7 +1221,6 @@ static struct clk d2d_26m_fck = {
 	.name		= "d2d_26m_fck",
 	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &sys_ck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP3430ES1_EN_D2D_SHIFT,
 	.clkdm_name	= "d2d_clkdm",
@@ -1234,7 +1231,6 @@ static struct clk modem_fck = {
 	.name		= "modem_fck",
 	.ops		= &clkops_omap2_dflt_wait,
 	.parent		= &sys_ck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
 	.enable_bit	= OMAP3430_EN_MODEM_SHIFT,
 	.clkdm_name	= "d2d_clkdm",
@@ -1622,7 +1618,6 @@ static struct clk core_l3_ick = {
 	.name		= "core_l3_ick",
 	.ops		= &clkops_null,
 	.parent		= &l3_ick,
-	.init		= &omap2_init_clk_clkdm,
 	.clkdm_name	= "core_l3_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -1691,7 +1686,6 @@ static struct clk core_l4_ick = {
 	.name		= "core_l4_ick",
 	.ops		= &clkops_null,
 	.parent		= &l4_ick,
-	.init		= &omap2_init_clk_clkdm,
 	.clkdm_name	= "core_l4_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2089,7 +2083,6 @@ static struct clk dss_tv_fck = {
 	.name		= "dss_tv_fck",
 	.ops		= &clkops_omap2_dflt,
 	.parent		= &omap_54m_fck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_TV_SHIFT,
 	.clkdm_name	= "dss_clkdm",
@@ -2100,7 +2093,6 @@ static struct clk dss_96m_fck = {
 	.name		= "dss_96m_fck",
 	.ops		= &clkops_omap2_dflt,
 	.parent		= &omap_96m_fck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_TV_SHIFT,
 	.clkdm_name	= "dss_clkdm",
@@ -2111,7 +2103,6 @@ static struct clk dss2_alwon_fck = {
 	.name		= "dss2_alwon_fck",
 	.ops		= &clkops_omap2_dflt,
 	.parent		= &sys_ck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_DSS2_SHIFT,
 	.clkdm_name	= "dss_clkdm",
@@ -2123,7 +2114,6 @@ static struct clk dss_ick_3430es1 = {
 	.name		= "dss_ick",
 	.ops		= &clkops_omap2_dflt,
 	.parent		= &l4_ick,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
 	.clkdm_name	= "dss_clkdm",
@@ -2135,7 +2125,6 @@ static struct clk dss_ick_3430es2 = {
 	.name		= "dss_ick",
 	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
 	.parent		= &l4_ick,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
 	.clkdm_name	= "dss_clkdm",
@@ -2159,7 +2148,6 @@ static struct clk cam_ick = {
 	.name		= "cam_ick",
 	.ops		= &clkops_omap2_dflt,
 	.parent		= &l4_ick,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430_EN_CAM_SHIFT,
 	.clkdm_name	= "cam_clkdm",
@@ -2170,7 +2158,6 @@ static struct clk csi2_96m_fck = {
 	.name		= "csi2_96m_fck",
 	.ops		= &clkops_omap2_dflt,
 	.parent		= &core_96m_fck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430_EN_CSI2_SHIFT,
 	.clkdm_name	= "cam_clkdm",
@@ -2183,7 +2170,6 @@ static struct clk usbhost_120m_fck = {
 	.name		= "usbhost_120m_fck",
 	.ops		= &clkops_omap2_dflt,
 	.parent		= &dpll5_m2_ck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST2_SHIFT,
 	.clkdm_name	= "usbhost_clkdm",
@@ -2194,7 +2180,6 @@ static struct clk usbhost_48m_fck = {
 	.name		= "usbhost_48m_fck",
 	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
 	.parent		= &omap_48m_fck,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST1_SHIFT,
 	.clkdm_name	= "usbhost_clkdm",
@@ -2206,7 +2191,6 @@ static struct clk usbhost_ick = {
 	.name		= "usbhost_ick",
 	.ops		= &clkops_omap3430es2_dss_usbhost_wait,
 	.parent		= &l4_ick,
-	.init		= &omap2_init_clk_clkdm,
 	.enable_reg	= OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
 	.enable_bit	= OMAP3430ES2_EN_USBHOST_SHIFT,
 	.clkdm_name	= "usbhost_clkdm",
@@ -2268,7 +2252,6 @@ static struct clk gpt1_fck = {
 static struct clk wkup_32k_fck = {
 	.name		= "wkup_32k_fck",
 	.ops		= &clkops_null,
-	.init		= &omap2_init_clk_clkdm,
 	.parent		= &omap_32k_fck,
 	.clkdm_name	= "wkup_clkdm",
 	.recalc		= &followparent_recalc,
@@ -2383,7 +2366,6 @@ static struct clk per_96m_fck = {
 	.name		= "per_96m_fck",
 	.ops		= &clkops_null,
 	.parent		= &omap_96m_alwon_fck,
-	.init		= &omap2_init_clk_clkdm,
 	.clkdm_name	= "per_clkdm",
 	.recalc		= &followparent_recalc,
 };
@@ -2392,7 +2374,6 @@ static struct clk per_48m_fck = {
 	.name		= "per_48m_fck",
 	.ops		= &clkops_null,
 	.parent		= &omap_48m_fck,
-	.init		= &omap2_init_clk_clkdm,
 	.clkdm_name	= "per_clkdm",
 	.recalc		= &followparent_recalc,
 };
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 0e7d501..4ef7b4f 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -299,7 +299,8 @@ struct clockdomain *clkdm_lookup(const char *name)
  * anything else to indicate failure; or -EINVAL if the function pointer
  * is null.
  */
-int clkdm_for_each(int (*fn)(struct clockdomain *clkdm))
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
+			void *user)
 {
 	struct clockdomain *clkdm;
 	int ret = 0;
@@ -309,7 +310,7 @@ int clkdm_for_each(int (*fn)(struct clockdomain *clkdm))
 
 	mutex_lock(&clkdm_mutex);
 	list_for_each_entry(clkdm, &clkdm_list, node) {
-		ret = (*fn)(clkdm);
+		ret = (*fn)(clkdm, user);
 		if (ret)
 			break;
 	}
@@ -484,6 +485,8 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
 			    v << __ffs(clkdm->clktrctrl_mask),
 			    clkdm->pwrdm.ptr->prcm_offs,
 			    CM_CLKSTCTRL);
+
+	pwrdm_clkdm_state_switch(clkdm);
 }
 
 /**
@@ -572,6 +575,7 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
 		omap2_clkdm_wakeup(clkdm);
 
 	pwrdm_wait_transition(clkdm->pwrdm.ptr);
+	pwrdm_clkdm_state_switch(clkdm);
 
 	return 0;
 }
@@ -624,6 +628,8 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
 	else
 		omap2_clkdm_sleep(clkdm);
 
+	pwrdm_clkdm_state_switch(clkdm);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c
new file mode 100644
index 0000000..8eb2dab
--- /dev/null
+++ b/arch/arm/mach-omap2/cm.c
@@ -0,0 +1,70 @@
+/*
+ * OMAP2/3 CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/atomic.h>
+
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */
+#define MAX_MODULE_READY_TIME		20000
+
+static const u8 cm_idlest_offs[] = {
+	CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
+};
+
+/**
+ * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * XXX document
+ */
+int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+{
+	int ena = 0, i = 0;
+	u8 cm_idlest_reg;
+	u32 mask;
+
+	if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
+		return -EINVAL;
+
+	cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
+
+	if (cpu_is_omap24xx())
+		ena = idlest_shift;
+	else if (cpu_is_omap34xx())
+		ena = 0;
+	else
+		BUG();
+
+	mask = 1 << idlest_shift;
+
+	/* XXX should be OMAP2 CM */
+	while (((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) != ena) &&
+	       (i++ < MAX_MODULE_READY_TIME))
+		udelay(1);
+
+	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index f3c91a1..cfd0b72 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -17,11 +17,11 @@
 #include "prcm-common.h"
 
 #define OMAP2420_CM_REGADDR(module, reg)				\
-			IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
+			OMAP2_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
 #define OMAP2430_CM_REGADDR(module, reg)				\
-			IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
+			OMAP2_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
 #define OMAP34XX_CM_REGADDR(module, reg)				\
-			IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
+			OMAP2_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
 
 /*
  * Architecture-specific global CM registers
@@ -98,6 +98,10 @@ extern u32 cm_read_mod_reg(s16 module, u16 idx);
 extern void cm_write_mod_reg(u32 val, s16 module, u16 idx);
 extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
 
+extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
+				      u8 idlest_shift);
+extern int omap4_cm_wait_module_ready(u32 prcm_mod, u8 prcm_dev_offs);
+
 static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
 {
 	return cm_rmw_mod_reg_bits(bits, bits, module, idx);
diff --git a/arch/arm/mach-omap2/cm4xxx.c b/arch/arm/mach-omap2/cm4xxx.c
new file mode 100644
index 0000000..e4ebd6d
--- /dev/null
+++ b/arch/arm/mach-omap2/cm4xxx.c
@@ -0,0 +1,68 @@
+/*
+ * OMAP4 CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/atomic.h>
+
+#include "cm.h"
+#include "cm-regbits-4xxx.h"
+
+/* XXX move this to cm.h */
+/* MAX_MODULE_READY_TIME: max milliseconds for module to leave idle */
+#define MAX_MODULE_READY_TIME			20000
+
+/*
+ * OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK: isolates the IDLEST field in the
+ * CM_CLKCTRL register.
+ */
+#define OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK	(0x2 << 16)
+
+/*
+ * OMAP4 prcm_mod u32 fields contain packed data: the CM ID in bit 16 and
+ * the PRCM module offset address (from the CM module base) in bits 15-0.
+ */
+#define OMAP4_PRCM_MOD_CM_ID_SHIFT		16
+#define OMAP4_PRCM_MOD_OFFS_MASK		0xffff
+
+/**
+ * omap4_cm_wait_idlest_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset (XXX example)
+ * @prcm_dev_offs: PRCM device offset (e.g. MCASP XXX example)
+ *
+ * XXX document
+ */
+int omap4_cm_wait_idlest_ready(u32 prcm_mod, u8 prcm_dev_offs)
+{
+	int i = 0;
+	u8 cm_id;
+	u16 prcm_mod_offs;
+	u32 mask = OMAP4_PRCM_CM_CLKCTRL_IDLEST_MASK;
+
+	cm_id = prcm_mod >> OMAP4_PRCM_MOD_CM_ID_SHIFT;
+	prcm_mod_offs = prcm_mod & OMAP4_PRCM_MOD_OFFS_MASK;
+
+	while (((omap4_cm_read_mod_reg(cm_id, prcm_mod_offs, prcm_dev_offs,
+				       OMAP4_CM_CLKCTRL_DREG) & mask) != 0) &&
+	       (i++ < MAX_MODULE_READY_TIME))
+		udelay(1);
+
+	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 894cc35..a2e9156 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -513,6 +513,47 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
 			omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
 		}
 	}
+
+	if (cpu_is_omap3430()) {
+		if (controller_nr == 0) {
+			omap_cfg_reg(N28_3430_MMC1_CLK);
+			omap_cfg_reg(M27_3430_MMC1_CMD);
+			omap_cfg_reg(N27_3430_MMC1_DAT0);
+			if (mmc_controller->slots[0].wires == 4 ||
+				mmc_controller->slots[0].wires == 8) {
+				omap_cfg_reg(N26_3430_MMC1_DAT1);
+				omap_cfg_reg(N25_3430_MMC1_DAT2);
+				omap_cfg_reg(P28_3430_MMC1_DAT3);
+			}
+			if (mmc_controller->slots[0].wires == 8) {
+				omap_cfg_reg(P27_3430_MMC1_DAT4);
+				omap_cfg_reg(P26_3430_MMC1_DAT5);
+				omap_cfg_reg(R27_3430_MMC1_DAT6);
+				omap_cfg_reg(R25_3430_MMC1_DAT7);
+			}
+		}
+		if (controller_nr == 1) {
+			/* MMC2 */
+			omap_cfg_reg(AE2_3430_MMC2_CLK);
+			omap_cfg_reg(AG5_3430_MMC2_CMD);
+			omap_cfg_reg(AH5_3430_MMC2_DAT0);
+
+			/*
+			 * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed
+			 * in the board-*.c files
+			 */
+			if (mmc_controller->slots[0].wires == 4 ||
+				mmc_controller->slots[0].wires == 8) {
+				omap_cfg_reg(AH4_3430_MMC2_DAT1);
+				omap_cfg_reg(AG4_3430_MMC2_DAT2);
+				omap_cfg_reg(AF4_3430_MMC2_DAT3);
+			}
+		}
+
+		/*
+		 * For MMC3 the pins need to be muxed in the board-*.c files
+		 */
+	}
 }
 
 void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index e9b9bcb..7574b6f 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -32,17 +32,23 @@
 #include <mach/sram.h>
 #include <mach/sdrc.h>
 #include <mach/gpmc.h>
+#include <mach/serial.h>
 
 #ifndef CONFIG_ARCH_OMAP4	/* FIXME: Remove this once clkdev is ready */
 #include "clock.h"
 
+#include <mach/omap-pm.h>
 #include <mach/powerdomain.h>
-
 #include "powerdomains.h"
 
 #include <mach/clockdomain.h>
 #include "clockdomains.h"
 #endif
+#include <mach/omap_hwmod.h>
+#include "omap_hwmod_2420.h"
+#include "omap_hwmod_2430.h"
+#include "omap_hwmod_34xx.h"
+
 /*
  * The machine specific code may provide the extra mapping besides the
  * default mapping provided here.
@@ -279,11 +285,26 @@ static int __init _omap2_init_reprogram_sdrc(void)
 void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
 				 struct omap_sdrc_params *sdrc_cs1)
 {
+	struct omap_hwmod **hwmods = NULL;
+
+	if (cpu_is_omap2420())
+		hwmods = omap2420_hwmods;
+	else if (cpu_is_omap2430())
+		hwmods = omap2430_hwmods;
+	else if (cpu_is_omap34xx())
+		hwmods = omap34xx_hwmods;
+
+	omap_hwmod_init(hwmods);
 	omap2_mux_init();
 #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
+	/* The OPP tables have to be registered before a clk init */
+	omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
 	pwrdm_init(powerdomains_omap);
 	clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
 	omap2_clk_init();
+	omap_serial_early_init();
+	omap_hwmod_late_init();
+	omap_pm_if_init();
 	omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
 	_omap2_init_reprogram_sdrc();
 #endif
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index 015f22a..2d9b5cc 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -217,10 +217,19 @@ static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf)
 }
 
 #define pr_reg(name)							\
-	p += sprintf(p, "%20s: %08x\n",					\
-		     __stringify(name), iommu_read_reg(obj, MMU_##name));
-
-static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf)
+	do {								\
+		ssize_t bytes;						\
+		const char *str = "%20s: %08x\n";			\
+		const int maxcol = 32;					\
+		bytes = snprintf(p, maxcol, str, __stringify(name),	\
+				 iommu_read_reg(obj, MMU_##name));	\
+		p += bytes;						\
+		len -= bytes;						\
+		if (len < maxcol)					\
+			goto out;					\
+	} while (0)
+
+static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len)
 {
 	char *p = buf;
 
@@ -242,7 +251,7 @@ static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf)
 	pr_reg(READ_CAM);
 	pr_reg(READ_RAM);
 	pr_reg(EMU_FAULT_AD);
-
+out:
 	return p - buf;
 }
 
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 0447d26..a846aa1 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -173,6 +173,42 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
 #define OMAP34XX_MCBSP_PDATA_SZ		0
 #endif
 
+static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
+	{
+		.phys_base      = OMAP44XX_MCBSP1_BASE,
+		.dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
+		.dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
+		.rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
+		.tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
+		.ops            = &omap2_mcbsp_ops,
+	},
+	{
+		.phys_base      = OMAP44XX_MCBSP2_BASE,
+		.dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
+		.dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
+		.rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
+		.tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
+		.ops            = &omap2_mcbsp_ops,
+	},
+	{
+		.phys_base      = OMAP44XX_MCBSP3_BASE,
+		.dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
+		.dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
+		.rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
+		.tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
+		.ops            = &omap2_mcbsp_ops,
+	},
+	{
+		.phys_base      = OMAP44XX_MCBSP4_BASE,
+		.dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
+		.dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
+		.rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
+		.tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
+		.ops            = &omap2_mcbsp_ops,
+	},
+};
+#define OMAP44XX_MCBSP_PDATA_SZ		ARRAY_SIZE(omap44xx_mcbsp_pdata)
+
 static int __init omap2_mcbsp_init(void)
 {
 	if (cpu_is_omap2420())
@@ -181,6 +217,8 @@ static int __init omap2_mcbsp_init(void)
 		omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
 	if (cpu_is_omap34xx())
 		omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
+	if (cpu_is_omap44xx())
+		omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
 
 	mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
 								GFP_KERNEL);
@@ -196,6 +234,9 @@ static int __init omap2_mcbsp_init(void)
 	if (cpu_is_omap34xx())
 		omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
 						OMAP34XX_MCBSP_PDATA_SZ);
+	if (cpu_is_omap44xx())
+		omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
+						OMAP44XX_MCBSP_PDATA_SZ);
 
 	return omap_mcbsp_init();
 }
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 43d6b92..2daa595 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -492,6 +492,61 @@ MUX_CFG_34XX("H16_34XX_SDRC_CKE0", 0x262,
 		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT)
 MUX_CFG_34XX("H17_34XX_SDRC_CKE1", 0x264,
 		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT)
+
+/* MMC1 */
+MUX_CFG_34XX("N28_3430_MMC1_CLK", 0x144,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("M27_3430_MMC1_CMD", 0x146,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("N27_3430_MMC1_DAT0", 0x148,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("N26_3430_MMC1_DAT1", 0x14a,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("N25_3430_MMC1_DAT2", 0x14c,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("P28_3430_MMC1_DAT3", 0x14e,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("P27_3430_MMC1_DAT4", 0x150,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("P26_3430_MMC1_DAT5", 0x152,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("R27_3430_MMC1_DAT6", 0x154,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("R25_3430_MMC1_DAT7", 0x156,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+
+/* MMC2 */
+MUX_CFG_34XX("AE2_3430_MMC2_CLK", 0x158,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AG5_3430_MMC2_CMD", 0x15A,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AH5_3430_MMC2_DAT0", 0x15c,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AH4_3430_MMC2_DAT1", 0x15e,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AG4_3430_MMC2_DAT2", 0x160,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AF4_3430_MMC2_DAT3", 0x162,
+		OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+
+/* MMC3 */
+MUX_CFG_34XX("AF10_3430_MMC3_CLK", 0x5d8,
+		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AC3_3430_MMC3_CMD", 0x1d0,
+		OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AE11_3430_MMC3_DAT0", 0x5e4,
+		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AH9_3430_MMC3_DAT1", 0x5e6,
+		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AF13_3430_MMC3_DAT2", 0x5e8,
+		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AF13_3430_MMC3_DAT3", 0x5e2,
+		OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLUP)
+
+/* SYS_NIRQ T2 INT1 */
+MUX_CFG_34XX("AF26_34XX_SYS_NIRQ", 0x1E0,
+		OMAP3_WAKEUP_EN | OMAP34XX_PIN_INPUT_PULLUP |
+		OMAP34XX_MUX_MODE0)
 };
 
 #define OMAP34XX_PINS_SZ	ARRAY_SIZE(omap34xx_pins)
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 8fe8d23..48ee295 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -54,7 +54,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
 	 * for us: do so
 	 */
 
-	gic_cpu_init(0, IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
+	gic_cpu_init(0, OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE));
 
 	/*
 	 * Synchronise with the boot thread.
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
new file mode 100644
index 0000000..d2e0f1c
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -0,0 +1,1554 @@
+/*
+ * omap_hwmod implementation for OMAP2/3/4
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ * With fixes and testing from Kevin Hilman
+ *
+ * Created in collaboration with (alphabetical order): Benoit Cousson,
+ * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
+ * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
+ *
+ * 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 code manages "OMAP modules" (on-chip devices) and their
+ * integration with Linux device driver and bus code.
+ *
+ * References:
+ * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
+ * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
+ * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
+ * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
+ * - Open Core Protocol Specification 2.2
+ *
+ * To do:
+ * - pin mux handling
+ * - handle IO mapping
+ * - bus throughput & module latency measurement code
+ *
+ * XXX add tests at the beginning of each function to ensure the hwmod is
+ * in the appropriate state
+ * XXX error return values should be checked to ensure that they are
+ * appropriate
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/bootmem.h>
+
+#include <mach/cpu.h>
+#include <mach/clockdomain.h>
+#include <mach/powerdomain.h>
+#include <mach/clock.h>
+#include <mach/omap_hwmod.h>
+
+#include "cm.h"
+
+/* Maximum microseconds to wait for OMAP module to reset */
+#define MAX_MODULE_RESET_WAIT		10000
+
+/* Name of the OMAP hwmod for the MPU */
+#define MPU_INITIATOR_NAME		"mpu_hwmod"
+
+/* omap_hwmod_list contains all registered struct omap_hwmods */
+static LIST_HEAD(omap_hwmod_list);
+
+static DEFINE_MUTEX(omap_hwmod_mutex);
+
+/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
+static struct omap_hwmod *mpu_oh;
+
+/* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */
+static u8 inited;
+
+
+/* Private functions */
+
+/**
+ * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy
+ * @oh: struct omap_hwmod *
+ *
+ * Load the current value of the hwmod OCP_SYSCONFIG register into the
+ * struct omap_hwmod for later use.  Returns -EINVAL if the hwmod has no
+ * OCP_SYSCONFIG register or 0 upon success.
+ */
+static int _update_sysc_cache(struct omap_hwmod *oh)
+{
+	if (!oh->sysconfig) {
+		WARN(!oh->sysconfig, "omap_hwmod: %s: cannot read "
+		     "OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
+		return -EINVAL;
+	}
+
+	/* XXX ensure module interface clock is up */
+
+	oh->_sysc_cache = omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
+
+	oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
+
+	return 0;
+}
+
+/**
+ * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register
+ * @v: OCP_SYSCONFIG value to write
+ * @oh: struct omap_hwmod *
+ *
+ * Write @v into the module OCP_SYSCONFIG register, if it has one.  No
+ * return value.
+ */
+static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
+{
+	if (!oh->sysconfig) {
+		WARN(!oh->sysconfig, "omap_hwmod: %s: cannot write "
+		     "OCP_SYSCONFIG: not defined on hwmod\n", oh->name);
+		return;
+	}
+
+	/* XXX ensure module interface clock is up */
+
+	if (oh->_sysc_cache != v) {
+		oh->_sysc_cache = v;
+		omap_hwmod_writel(v, oh, oh->sysconfig->sysc_offs);
+	}
+}
+
+/**
+ * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v
+ * @oh: struct omap_hwmod *
+ * @standbymode: MIDLEMODE field bits
+ * @v: pointer to register contents to modify
+ *
+ * Update the master standby mode bits in @v to be @standbymode for
+ * the @oh hwmod.  Does not write to the hardware.  Returns -EINVAL
+ * upon error or 0 upon success.
+ */
+static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
+				   u32 *v)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE))
+		return -EINVAL;
+
+	*v &= ~SYSC_MIDLEMODE_MASK;
+	*v |= __ffs(standbymode) << SYSC_MIDLEMODE_SHIFT;
+
+	return 0;
+}
+
+/**
+ * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v
+ * @oh: struct omap_hwmod *
+ * @idlemode: SIDLEMODE field bits
+ * @v: pointer to register contents to modify
+ *
+ * Update the slave idle mode bits in @v to be @idlemode for the @oh
+ * hwmod.  Does not write to the hardware.  Returns -EINVAL upon error
+ * or 0 upon success.
+ */
+static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE))
+		return -EINVAL;
+
+	*v &= ~SYSC_SIDLEMODE_MASK;
+	*v |= __ffs(idlemode) << SYSC_SIDLEMODE_SHIFT;
+
+	return 0;
+}
+
+/**
+ * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
+ * @oh: struct omap_hwmod *
+ * @clockact: CLOCKACTIVITY field bits
+ * @v: pointer to register contents to modify
+ *
+ * Update the clockactivity mode bits in @v to be @clockact for the
+ * @oh hwmod.  Used for additional powersaving on some modules.  Does
+ * not write to the hardware.  Returns -EINVAL upon error or 0 upon
+ * success.
+ */
+static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
+		return -EINVAL;
+
+	*v &= ~SYSC_CLOCKACTIVITY_MASK;
+	*v |= clockact << SYSC_CLOCKACTIVITY_SHIFT;
+
+	return 0;
+}
+
+/**
+ * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
+ * @oh: struct omap_hwmod *
+ * @v: pointer to register contents to modify
+ *
+ * Set the SOFTRESET bit in @v for hwmod @oh.  Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _set_softreset(struct omap_hwmod *oh, u32 *v)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET))
+		return -EINVAL;
+
+	*v |= SYSC_SOFTRESET_MASK;
+
+	return 0;
+}
+
+/**
+ * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
+ * @oh: struct omap_hwmod *
+ *
+ * Allow the hardware module @oh to send wakeups.  Returns -EINVAL
+ * upon error or 0 upon success.
+ */
+static int _enable_wakeup(struct omap_hwmod *oh)
+{
+	u32 v;
+
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+		return -EINVAL;
+
+	v = oh->_sysc_cache;
+	v |= SYSC_ENAWAKEUP_MASK;
+	_write_sysconfig(v, oh);
+
+	/* XXX test pwrdm_get_wken for this hwmod's subsystem */
+
+	oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
+
+	return 0;
+}
+
+/**
+ * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
+ * @oh: struct omap_hwmod *
+ *
+ * Prevent the hardware module @oh to send wakeups.  Returns -EINVAL
+ * upon error or 0 upon success.
+ */
+static int _disable_wakeup(struct omap_hwmod *oh)
+{
+	u32 v;
+
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+		return -EINVAL;
+
+	v = oh->_sysc_cache;
+	v &= ~SYSC_ENAWAKEUP_MASK;
+	_write_sysconfig(v, oh);
+
+	/* XXX test pwrdm_get_wken for this hwmod's subsystem */
+
+	oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
+
+	return 0;
+}
+
+/**
+ * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active
+ * @oh: struct omap_hwmod *
+ *
+ * Prevent the hardware module @oh from entering idle while the
+ * hardare module initiator @init_oh is active.  Useful when a module
+ * will be accessed by a particular initiator (e.g., if a module will
+ * be accessed by the IVA, there should be a sleepdep between the IVA
+ * initiator and the module).  Only applies to modules in smart-idle
+ * mode.  Returns -EINVAL upon error or passes along
+ * pwrdm_add_sleepdep() value upon success.
+ */
+static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
+{
+	if (!oh->_clk)
+		return -EINVAL;
+
+	return pwrdm_add_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
+				  init_oh->_clk->clkdm->pwrdm.ptr);
+}
+
+/**
+ * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active
+ * @oh: struct omap_hwmod *
+ *
+ * Allow the hardware module @oh to enter idle while the hardare
+ * module initiator @init_oh is active.  Useful when a module will not
+ * be accessed by a particular initiator (e.g., if a module will not
+ * be accessed by the IVA, there should be no sleepdep between the IVA
+ * initiator and the module).  Only applies to modules in smart-idle
+ * mode.  Returns -EINVAL upon error or passes along
+ * pwrdm_add_sleepdep() value upon success.
+ */
+static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
+{
+	if (!oh->_clk)
+		return -EINVAL;
+
+	return pwrdm_del_sleepdep(oh->_clk->clkdm->pwrdm.ptr,
+				  init_oh->_clk->clkdm->pwrdm.ptr);
+}
+
+/**
+ * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
+ * @oh: struct omap_hwmod *
+ *
+ * Called from _init_clocks().  Populates the @oh _clk (main
+ * functional clock pointer) if a main_clk is present.  Returns 0 on
+ * success or -EINVAL on error.
+ */
+static int _init_main_clk(struct omap_hwmod *oh)
+{
+	struct clk *c;
+	int ret = 0;
+
+	if (!oh->clkdev_con_id)
+		return 0;
+
+	c = clk_get_sys(oh->clkdev_dev_id, oh->clkdev_con_id);
+	WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get main_clk %s.%s\n",
+	     oh->name, oh->clkdev_dev_id, oh->clkdev_con_id);
+	if (IS_ERR(c))
+		ret = -EINVAL;
+	oh->_clk = c;
+
+	return ret;
+}
+
+/**
+ * _init_interface_clk - get a struct clk * for the the hwmod's interface clks
+ * @oh: struct omap_hwmod *
+ *
+ * Called from _init_clocks().  Populates the @oh OCP slave interface
+ * clock pointers.  Returns 0 on success or -EINVAL on error.
+ */
+static int _init_interface_clks(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_ocp_if *os;
+	struct clk *c;
+	int i;
+	int ret = 0;
+
+	if (oh->slaves_cnt == 0)
+		return 0;
+
+	for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
+		if (!os->clkdev_con_id)
+			continue;
+
+		c = clk_get_sys(os->clkdev_dev_id, os->clkdev_con_id);
+		WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get "
+		     "interface_clk %s.%s\n", oh->name,
+		     os->clkdev_dev_id, os->clkdev_con_id);
+		if (IS_ERR(c))
+			ret = -EINVAL;
+		os->_clk = c;
+	}
+
+	return ret;
+}
+
+/**
+ * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks
+ * @oh: struct omap_hwmod *
+ *
+ * Called from _init_clocks().  Populates the @oh omap_hwmod_opt_clk
+ * clock pointers.  Returns 0 on success or -EINVAL on error.
+ */
+static int _init_opt_clks(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_opt_clk *oc;
+	struct clk *c;
+	int i;
+	int ret = 0;
+
+	for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
+		c = clk_get_sys(oc->clkdev_dev_id, oc->clkdev_con_id);
+		WARN(IS_ERR(c), "omap_hwmod: %s: cannot clk_get opt_clk "
+		     "%s.%s\n", oh->name, oc->clkdev_dev_id,
+		     oc->clkdev_con_id);
+		if (IS_ERR(c))
+			ret = -EINVAL;
+		oc->_clk = c;
+	}
+
+	return ret;
+}
+
+/**
+ * _enable_clocks - enable hwmod main clock and interface clocks
+ * @oh: struct omap_hwmod *
+ *
+ * Enables all clocks necessary for register reads and writes to succeed
+ * on the hwmod @oh.  Returns 0.
+ */
+static int _enable_clocks(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_ocp_if *os;
+	int i;
+
+	pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
+
+	if (oh->_clk && !IS_ERR(oh->_clk))
+		clk_enable(oh->_clk);
+
+	if (oh->slaves_cnt > 0) {
+		for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
+			struct clk *c = os->_clk;
+
+			if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE))
+				clk_enable(c);
+		}
+	}
+
+	/* The opt clocks are controlled by the device driver. */
+
+	return 0;
+}
+
+/**
+ * _disable_clocks - disable hwmod main clock and interface clocks
+ * @oh: struct omap_hwmod *
+ *
+ * Disables the hwmod @oh main functional and interface clocks.  Returns 0.
+ */
+static int _disable_clocks(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_ocp_if *os;
+	int i;
+
+	pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
+
+	if (oh->_clk && !IS_ERR(oh->_clk))
+		clk_disable(oh->_clk);
+
+	if (oh->slaves_cnt > 0) {
+		for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
+			struct clk *c = os->_clk;
+
+			if (c && !IS_ERR(c) && (os->flags & OCPIF_SWSUP_IDLE))
+				clk_disable(c);
+		}
+	}
+
+	/* The opt clocks are controlled by the device driver. */
+
+	return 0;
+}
+
+/**
+ * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
+ * @oh: struct omap_hwmod *
+ *
+ * Returns the array index of the OCP slave port that the MPU
+ * addresses the device on, or -EINVAL upon error or not found.
+ */
+static int _find_mpu_port_index(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_ocp_if *os;
+	int i;
+	int found = 0;
+
+	if (!oh || oh->slaves_cnt == 0)
+		return -EINVAL;
+
+	for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
+		if (os->user & OCP_USER_MPU) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found)
+		pr_debug("omap_hwmod: %s: MPU OCP slave port ID  %d\n",
+			 oh->name, i);
+	else
+		pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n",
+			 oh->name);
+
+	return (found) ? i : -EINVAL;
+}
+
+/**
+ * _find_mpu_rt_base - find hwmod register target base addr accessible by MPU
+ * @oh: struct omap_hwmod *
+ *
+ * Return the virtual address of the base of the register target of
+ * device @oh, or NULL on error.
+ */
+static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
+{
+	struct omap_hwmod_ocp_if *os;
+	struct omap_hwmod_addr_space *mem;
+	int i;
+	int found = 0;
+
+	if (!oh || oh->slaves_cnt == 0)
+		return NULL;
+
+	os = *oh->slaves + index;
+
+	for (i = 0, mem = os->addr; i < os->addr_cnt; i++, mem++) {
+		if (mem->flags & ADDR_TYPE_RT) {
+			found = 1;
+			break;
+		}
+	}
+
+	/* XXX use ioremap() instead? */
+
+	if (found)
+		pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
+			 oh->name, OMAP2_IO_ADDRESS(mem->pa_start));
+	else
+		pr_debug("omap_hwmod: %s: no MPU register target found\n",
+			 oh->name);
+
+	return (found) ? OMAP2_IO_ADDRESS(mem->pa_start) : NULL;
+}
+
+/**
+ * _sysc_enable - try to bring a module out of idle via OCP_SYSCONFIG
+ * @oh: struct omap_hwmod *
+ *
+ * If module is marked as SWSUP_SIDLE, force the module out of slave
+ * idle; otherwise, configure it for smart-idle.  If module is marked
+ * as SWSUP_MSUSPEND, force the module out of master standby;
+ * otherwise, configure it for smart-standby.  No return value.
+ */
+static void _sysc_enable(struct omap_hwmod *oh)
+{
+	u8 idlemode;
+	u32 v;
+
+	if (!oh->sysconfig)
+		return;
+
+	v = oh->_sysc_cache;
+
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
+		idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
+			HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+		_set_slave_idlemode(oh, idlemode, &v);
+	}
+
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
+		idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
+			HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+		_set_master_standbymode(oh, idlemode, &v);
+	}
+
+	/* XXX OCP AUTOIDLE bit? */
+
+	if (oh->flags & HWMOD_SET_DEFAULT_CLOCKACT &&
+	    oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY)
+		_set_clockactivity(oh, oh->sysconfig->clockact, &v);
+
+	_write_sysconfig(v, oh);
+}
+
+/**
+ * _sysc_idle - try to put a module into idle via OCP_SYSCONFIG
+ * @oh: struct omap_hwmod *
+ *
+ * If module is marked as SWSUP_SIDLE, force the module into slave
+ * idle; otherwise, configure it for smart-idle.  If module is marked
+ * as SWSUP_MSUSPEND, force the module into master standby; otherwise,
+ * configure it for smart-standby.  No return value.
+ */
+static void _sysc_idle(struct omap_hwmod *oh)
+{
+	u8 idlemode;
+	u32 v;
+
+	if (!oh->sysconfig)
+		return;
+
+	v = oh->_sysc_cache;
+
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE) {
+		idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
+			HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
+		_set_slave_idlemode(oh, idlemode, &v);
+	}
+
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE) {
+		idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
+			HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
+		_set_master_standbymode(oh, idlemode, &v);
+	}
+
+	_write_sysconfig(v, oh);
+}
+
+/**
+ * _sysc_shutdown - force a module into idle via OCP_SYSCONFIG
+ * @oh: struct omap_hwmod *
+ *
+ * Force the module into slave idle and master suspend. No return
+ * value.
+ */
+static void _sysc_shutdown(struct omap_hwmod *oh)
+{
+	u32 v;
+
+	if (!oh->sysconfig)
+		return;
+
+	v = oh->_sysc_cache;
+
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE)
+		_set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
+
+	if (oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE)
+		_set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
+
+	/* XXX clear OCP AUTOIDLE bit? */
+
+	_write_sysconfig(v, oh);
+}
+
+/**
+ * _lookup - find an omap_hwmod by name
+ * @name: find an omap_hwmod by name
+ *
+ * Return a pointer to an omap_hwmod by name, or NULL if not found.
+ * Caller must hold omap_hwmod_mutex.
+ */
+static struct omap_hwmod *_lookup(const char *name)
+{
+	struct omap_hwmod *oh, *temp_oh;
+
+	oh = NULL;
+
+	list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
+		if (!strcmp(name, temp_oh->name)) {
+			oh = temp_oh;
+			break;
+		}
+	}
+
+	return oh;
+}
+
+/**
+ * _init_clocks - clk_get() all clocks associated with this hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Called by omap_hwmod_late_init() (after omap2_clk_init()).
+ * Resolves all clock names embedded in the hwmod.  Must be called
+ * with omap_hwmod_mutex held.  Returns -EINVAL if the omap_hwmod
+ * has not yet been registered or if the clocks have already been
+ * initialized, 0 on success, or a non-zero error on failure.
+ */
+static int _init_clocks(struct omap_hwmod *oh)
+{
+	int ret = 0;
+
+	if (!oh || (oh->_state != _HWMOD_STATE_REGISTERED))
+		return -EINVAL;
+
+	pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
+
+	ret |= _init_main_clk(oh);
+	ret |= _init_interface_clks(oh);
+	ret |= _init_opt_clks(oh);
+
+	oh->_state = _HWMOD_STATE_CLKS_INITED;
+
+	return ret;
+}
+
+/**
+ * _wait_target_ready - wait for a module to leave slave idle
+ * @oh: struct omap_hwmod *
+ *
+ * Wait for a module @oh to leave slave idle.  Returns 0 if the module
+ * does not have an IDLEST bit or if the module successfully leaves
+ * slave idle; otherwise, pass along the return value of the
+ * appropriate *_cm_wait_module_ready() function.
+ */
+static int _wait_target_ready(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_ocp_if *os;
+	int ret;
+
+	if (!oh)
+		return -EINVAL;
+
+	if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+		return 0;
+
+	os = *oh->slaves + oh->_mpu_port_index;
+
+	if (!(os->flags & OCPIF_HAS_IDLEST))
+		return 0;
+
+	/* XXX check module SIDLEMODE */
+
+	/* XXX check clock enable states */
+
+	if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+		ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
+						 oh->prcm.omap2.idlest_reg_id,
+						 oh->prcm.omap2.idlest_idle_bit);
+#if 0
+	} else if (cpu_is_omap44xx()) {
+		ret = omap4_cm_wait_module_ready(oh->prcm.omap4.module_offs,
+						 oh->prcm.omap4.device_offs);
+#endif
+	} else {
+		BUG();
+	};
+
+	return ret;
+}
+
+/**
+ * _reset - reset an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit.  hwmod must be
+ * enabled for this to work.  Must be called with omap_hwmod_mutex
+ * held.  Returns -EINVAL if the hwmod cannot be reset this way or if
+ * the hwmod is in the wrong state, -ETIMEDOUT if the module did not
+ * reset in time, or 0 upon success.
+ */
+static int _reset(struct omap_hwmod *oh)
+{
+	u32 r, v;
+	int c;
+
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET) ||
+	    (oh->sysconfig->sysc_flags & SYSS_MISSING))
+		return -EINVAL;
+
+	/* clocks must be on for this operation */
+	if (oh->_state != _HWMOD_STATE_ENABLED) {
+		WARN(1, "omap_hwmod: %s: reset can only be entered from "
+		     "enabled state\n", oh->name);
+		return -EINVAL;
+	}
+
+	pr_debug("omap_hwmod: %s: resetting\n", oh->name);
+
+	v = oh->_sysc_cache;
+	r = _set_softreset(oh, &v);
+	if (r)
+		return r;
+	_write_sysconfig(v, oh);
+
+	c = 0;
+	while (c < MAX_MODULE_RESET_WAIT &&
+	       !(omap_hwmod_readl(oh, oh->sysconfig->syss_offs) &
+		 SYSS_RESETDONE_MASK)) {
+		udelay(1);
+		c++;
+	}
+
+	if (c == MAX_MODULE_RESET_WAIT)
+		WARN(1, "omap_hwmod: %s: failed to reset in %d usec\n",
+		     oh->name, MAX_MODULE_RESET_WAIT);
+	else
+		pr_debug("omap_hwmod: %s: reset in %d usec\n", oh->name, c);
+
+	/*
+	 * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
+	 * _wait_target_ready() or _reset()
+	 */
+
+	return (c == MAX_MODULE_RESET_WAIT) ? -ETIMEDOUT : 0;
+}
+
+/**
+ * _enable - enable an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
+ * register target.  Must be called with omap_hwmod_mutex held.
+ * Returns -EINVAL if the hwmod is in the wrong state or passes along
+ * the return value of _wait_target_ready().
+ */
+static int _enable(struct omap_hwmod *oh)
+{
+	int r;
+
+	if (oh->_state != _HWMOD_STATE_INITIALIZED &&
+	    oh->_state != _HWMOD_STATE_IDLE &&
+	    oh->_state != _HWMOD_STATE_DISABLED) {
+		WARN(1, "omap_hwmod: %s: enabled state can only be entered "
+		     "from initialized, idle, or disabled state\n", oh->name);
+		return -EINVAL;
+	}
+
+	pr_debug("omap_hwmod: %s: enabling\n", oh->name);
+
+	/* XXX mux balls */
+
+	_add_initiator_dep(oh, mpu_oh);
+	_enable_clocks(oh);
+
+	if (oh->sysconfig) {
+		if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
+			_update_sysc_cache(oh);
+		_sysc_enable(oh);
+	}
+
+	r = _wait_target_ready(oh);
+	if (!r)
+		oh->_state = _HWMOD_STATE_ENABLED;
+
+	return r;
+}
+
+/**
+ * _idle - idle an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Idles an omap_hwmod @oh.  This should be called once the hwmod has
+ * no further work.  Returns -EINVAL if the hwmod is in the wrong
+ * state or returns 0.
+ */
+static int _idle(struct omap_hwmod *oh)
+{
+	if (oh->_state != _HWMOD_STATE_ENABLED) {
+		WARN(1, "omap_hwmod: %s: idle state can only be entered from "
+		     "enabled state\n", oh->name);
+		return -EINVAL;
+	}
+
+	pr_debug("omap_hwmod: %s: idling\n", oh->name);
+
+	if (oh->sysconfig)
+		_sysc_idle(oh);
+	_del_initiator_dep(oh, mpu_oh);
+	_disable_clocks(oh);
+
+	oh->_state = _HWMOD_STATE_IDLE;
+
+	return 0;
+}
+
+/**
+ * _shutdown - shutdown an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Shut down an omap_hwmod @oh.  This should be called when the driver
+ * used for the hwmod is removed or unloaded or if the driver is not
+ * used by the system.  Returns -EINVAL if the hwmod is in the wrong
+ * state or returns 0.
+ */
+static int _shutdown(struct omap_hwmod *oh)
+{
+	if (oh->_state != _HWMOD_STATE_IDLE &&
+	    oh->_state != _HWMOD_STATE_ENABLED) {
+		WARN(1, "omap_hwmod: %s: disabled state can only be entered "
+		     "from idle, or enabled state\n", oh->name);
+		return -EINVAL;
+	}
+
+	pr_debug("omap_hwmod: %s: disabling\n", oh->name);
+
+	if (oh->sysconfig)
+		_sysc_shutdown(oh);
+	_del_initiator_dep(oh, mpu_oh);
+	/* XXX what about the other system initiators here? DMA, tesla, d2d */
+	_disable_clocks(oh);
+	/* XXX Should this code also force-disable the optional clocks? */
+
+	/* XXX mux any associated balls to safe mode */
+
+	oh->_state = _HWMOD_STATE_DISABLED;
+
+	return 0;
+}
+
+/**
+ * _write_clockact_lock - set the module's clockactivity bits
+ * @oh: struct omap_hwmod *
+ * @clockact: CLOCKACTIVITY field bits
+ *
+ * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
+ * OCP_SYSCONFIG register.  Returns -EINVAL if the hwmod is in the
+ * wrong state or returns 0.
+ */
+static int _write_clockact_lock(struct omap_hwmod *oh, u8 clockact)
+{
+	u32 v;
+
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	v = oh->_sysc_cache;
+	_set_clockactivity(oh, clockact, &v);
+	_write_sysconfig(v, oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
+
+
+/**
+ * _setup - do initial configuration of omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
+ * OCP_SYSCONFIG register.  Must be called with omap_hwmod_mutex
+ * held.  Returns -EINVAL if the hwmod is in the wrong state or returns
+ * 0.
+ */
+static int _setup(struct omap_hwmod *oh)
+{
+	struct omap_hwmod_ocp_if *os;
+	int i;
+
+	if (!oh)
+		return -EINVAL;
+
+	/* Set iclk autoidle mode */
+	if (oh->slaves_cnt > 0) {
+		for (i = 0, os = *oh->slaves; i < oh->slaves_cnt; i++, os++) {
+			struct clk *c = os->_clk;
+
+			if (!c || IS_ERR(c))
+				continue;
+
+			if (os->flags & OCPIF_SWSUP_IDLE) {
+				/* XXX omap_iclk_deny_idle(c); */
+			} else {
+				/* XXX omap_iclk_allow_idle(c); */
+				clk_enable(c);
+			}
+		}
+	}
+
+	oh->_state = _HWMOD_STATE_INITIALIZED;
+
+	_enable(oh);
+
+	if (!(oh->flags & HWMOD_INIT_NO_RESET))
+		_reset(oh);
+
+	/* XXX OCP AUTOIDLE bit? */
+	/* XXX OCP ENAWAKEUP bit? */
+
+	if (!(oh->flags & HWMOD_INIT_NO_IDLE))
+		_idle(oh);
+
+	return 0;
+}
+
+
+
+/* Public functions */
+
+u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
+{
+	return __raw_readl(oh->_rt_va + reg_offs);
+}
+
+void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
+{
+	__raw_writel(v, oh->_rt_va + reg_offs);
+}
+
+/**
+ * omap_hwmod_register - register a struct omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Registers the omap_hwmod @oh.  Returns -EEXIST if an omap_hwmod already
+ * has been registered by the same name; -EINVAL if the omap_hwmod is in the
+ * wrong state, or 0 on success.
+ *
+ * XXX The data should be copied into bootmem, so the original data
+ * should be marked __initdata and freed after init.  This would allow
+ * unneeded omap_hwmods to be freed on multi-OMAP configurations.  Note
+ * that the copy process would be relatively complex due to the large number
+ * of substructures.
+ */
+int omap_hwmod_register(struct omap_hwmod *oh)
+{
+	int ret, ms_id;
+
+	if (!oh || (oh->_state != _HWMOD_STATE_UNKNOWN))
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+
+	pr_debug("omap_hwmod: %s: registering\n", oh->name);
+
+	if (_lookup(oh->name)) {
+		ret = -EEXIST;
+		goto ohr_unlock;
+	}
+
+	ms_id = _find_mpu_port_index(oh);
+	if (!IS_ERR_VALUE(ms_id)) {
+		oh->_mpu_port_index = ms_id;
+		oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
+	} else {
+		oh->_int_flags |= _HWMOD_NO_MPU_PORT;
+	}
+
+	list_add_tail(&oh->node, &omap_hwmod_list);
+
+	oh->_state = _HWMOD_STATE_REGISTERED;
+
+	ret = 0;
+
+ohr_unlock:
+	mutex_unlock(&omap_hwmod_mutex);
+	return ret;
+}
+
+/**
+ * omap_hwmod_lookup - look up a registered omap_hwmod by name
+ * @name: name of the omap_hwmod to look up
+ *
+ * Given a @name of an omap_hwmod, return a pointer to the registered
+ * struct omap_hwmod *, or NULL upon error.
+ */
+struct omap_hwmod *omap_hwmod_lookup(const char *name)
+{
+	struct omap_hwmod *oh;
+
+	if (!name)
+		return NULL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	oh = _lookup(name);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return oh;
+}
+
+/**
+ * omap_hwmod_for_each - call function for each registered omap_hwmod
+ * @fn: pointer to a callback function
+ *
+ * Call @fn for each registered omap_hwmod, passing @data to each
+ * function.  @fn must return 0 for success or any other value for
+ * failure.  If @fn returns non-zero, the iteration across omap_hwmods
+ * will stop and the non-zero return value will be passed to the
+ * caller of omap_hwmod_for_each().  @fn is called with
+ * omap_hwmod_for_each() held.
+ */
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
+{
+	struct omap_hwmod *temp_oh;
+	int ret;
+
+	if (!fn)
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
+		ret = (*fn)(temp_oh);
+		if (ret)
+			break;
+	}
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return ret;
+}
+
+
+/**
+ * omap_hwmod_init - init omap_hwmod code and register hwmods
+ * @ohs: pointer to an array of omap_hwmods to register
+ *
+ * Intended to be called early in boot before the clock framework is
+ * initialized.  If @ohs is not null, will register all omap_hwmods
+ * listed in @ohs that are valid for this chip.  Returns -EINVAL if
+ * omap_hwmod_init() has already been called or 0 otherwise.
+ */
+int omap_hwmod_init(struct omap_hwmod **ohs)
+{
+	struct omap_hwmod *oh;
+	int r;
+
+	if (inited)
+		return -EINVAL;
+
+	inited = 1;
+
+	if (!ohs)
+		return 0;
+
+	oh = *ohs;
+	while (oh) {
+		if (omap_chip_is(oh->omap_chip)) {
+			r = omap_hwmod_register(oh);
+			WARN(r, "omap_hwmod: %s: omap_hwmod_register returned "
+			     "%d\n", oh->name, r);
+		}
+		oh = *++ohs;
+	}
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_late_init - do some post-clock framework initialization
+ *
+ * Must be called after omap2_clk_init().  Resolves the struct clk names
+ * to struct clk pointers for each registered omap_hwmod.  Also calls
+ * _setup() on each hwmod.  Returns 0.
+ */
+int omap_hwmod_late_init(void)
+{
+	int r;
+
+	/* XXX check return value */
+	r = omap_hwmod_for_each(_init_clocks);
+	WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
+
+	mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
+	WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
+	     MPU_INITIATOR_NAME);
+
+	omap_hwmod_for_each(_setup);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_unregister - unregister an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Unregisters a previously-registered omap_hwmod @oh.  There's probably
+ * no use case for this, so it is likely to be removed in a later version.
+ *
+ * XXX Free all of the bootmem-allocated structures here when that is
+ * implemented.  Make it clear that core code is the only code that is
+ * expected to unregister modules.
+ */
+int omap_hwmod_unregister(struct omap_hwmod *oh)
+{
+	if (!oh)
+		return -EINVAL;
+
+	pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
+
+	mutex_lock(&omap_hwmod_mutex);
+	list_del(&oh->node);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_enable - enable an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Enable an omap_hwomd @oh.  Intended to be called by omap_device_enable().
+ * Returns -EINVAL on error or passes along the return value from _enable().
+ */
+int omap_hwmod_enable(struct omap_hwmod *oh)
+{
+	int r;
+
+	if (!oh)
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	r = _enable(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return r;
+}
+
+/**
+ * omap_hwmod_idle - idle an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Idle an omap_hwomd @oh.  Intended to be called by omap_device_idle().
+ * Returns -EINVAL on error or passes along the return value from _idle().
+ */
+int omap_hwmod_idle(struct omap_hwmod *oh)
+{
+	if (!oh)
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	_idle(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_shutdown - shutdown an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Shutdown an omap_hwomd @oh.  Intended to be called by
+ * omap_device_shutdown().  Returns -EINVAL on error or passes along
+ * the return value from _shutdown().
+ */
+int omap_hwmod_shutdown(struct omap_hwmod *oh)
+{
+	if (!oh)
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	_shutdown(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_enable_clocks - enable main_clk, all interface clocks
+ * @oh: struct omap_hwmod *oh
+ *
+ * Intended to be called by the omap_device code.
+ */
+int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
+{
+	mutex_lock(&omap_hwmod_mutex);
+	_enable_clocks(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_disable_clocks - disable main_clk, all interface clocks
+ * @oh: struct omap_hwmod *oh
+ *
+ * Intended to be called by the omap_device code.
+ */
+int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
+{
+	mutex_lock(&omap_hwmod_mutex);
+	_disable_clocks(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete
+ * @oh: struct omap_hwmod *oh
+ *
+ * Intended to be called by drivers and core code when all posted
+ * writes to a device must complete before continuing further
+ * execution (for example, after clearing some device IRQSTATUS
+ * register bits)
+ *
+ * XXX what about targets with multiple OCP threads?
+ */
+void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
+{
+	BUG_ON(!oh);
+
+	if (!oh->sysconfig || !oh->sysconfig->sysc_flags) {
+		WARN(1, "omap_device: %s: OCP barrier impossible due to "
+		      "device configuration\n", oh->name);
+		return;
+	}
+
+	/*
+	 * Forces posted writes to complete on the OCP thread handling
+	 * register writes
+	 */
+	omap_hwmod_readl(oh, oh->sysconfig->sysc_offs);
+}
+
+/**
+ * omap_hwmod_reset - reset the hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Under some conditions, a driver may wish to reset the entire device.
+ * Called from omap_device code.  Returns -EINVAL on error or passes along
+ * the return value from _reset()/_enable().
+ */
+int omap_hwmod_reset(struct omap_hwmod *oh)
+{
+	int r;
+
+	if (!oh || !(oh->_state & _HWMOD_STATE_ENABLED))
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	r = _reset(oh);
+	if (!r)
+		r = _enable(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return r;
+}
+
+/**
+ * omap_hwmod_count_resources - count number of struct resources needed by hwmod
+ * @oh: struct omap_hwmod *
+ * @res: pointer to the first element of an array of struct resource to fill
+ *
+ * Count the number of struct resource array elements necessary to
+ * contain omap_hwmod @oh resources.  Intended to be called by code
+ * that registers omap_devices.  Intended to be used to determine the
+ * size of a dynamically-allocated struct resource array, before
+ * calling omap_hwmod_fill_resources().  Returns the number of struct
+ * resource array elements needed.
+ *
+ * XXX This code is not optimized.  It could attempt to merge adjacent
+ * resource IDs.
+ *
+ */
+int omap_hwmod_count_resources(struct omap_hwmod *oh)
+{
+	int ret, i;
+
+	ret = oh->mpu_irqs_cnt + oh->sdma_chs_cnt;
+
+	for (i = 0; i < oh->slaves_cnt; i++)
+		ret += (*oh->slaves + i)->addr_cnt;
+
+	return ret;
+}
+
+/**
+ * omap_hwmod_fill_resources - fill struct resource array with hwmod data
+ * @oh: struct omap_hwmod *
+ * @res: pointer to the first element of an array of struct resource to fill
+ *
+ * Fill the struct resource array @res with resource data from the
+ * omap_hwmod @oh.  Intended to be called by code that registers
+ * omap_devices.  See also omap_hwmod_count_resources().  Returns the
+ * number of array elements filled.
+ */
+int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
+{
+	int i, j;
+	int r = 0;
+
+	/* For each IRQ, DMA, memory area, fill in array.*/
+
+	for (i = 0; i < oh->mpu_irqs_cnt; i++) {
+		(res + r)->start = *(oh->mpu_irqs + i);
+		(res + r)->end = *(oh->mpu_irqs + i);
+		(res + r)->flags = IORESOURCE_IRQ;
+		r++;
+	}
+
+	for (i = 0; i < oh->sdma_chs_cnt; i++) {
+		(res + r)->name = (oh->sdma_chs + i)->name;
+		(res + r)->start = (oh->sdma_chs + i)->dma_ch;
+		(res + r)->end = (oh->sdma_chs + i)->dma_ch;
+		(res + r)->flags = IORESOURCE_DMA;
+		r++;
+	}
+
+	for (i = 0; i < oh->slaves_cnt; i++) {
+		struct omap_hwmod_ocp_if *os;
+
+		os = *oh->slaves + i;
+
+		for (j = 0; j < os->addr_cnt; j++) {
+			(res + r)->start = (os->addr + j)->pa_start;
+			(res + r)->end = (os->addr + j)->pa_end;
+			(res + r)->flags = IORESOURCE_MEM;
+			r++;
+		}
+	}
+
+	return r;
+}
+
+/**
+ * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain
+ * @oh: struct omap_hwmod *
+ *
+ * Return the powerdomain pointer associated with the OMAP module
+ * @oh's main clock.  If @oh does not have a main clk, return the
+ * powerdomain associated with the interface clock associated with the
+ * module's MPU port. (XXX Perhaps this should use the SDMA port
+ * instead?)  Returns NULL on error, or a struct powerdomain * on
+ * success.
+ */
+struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
+{
+	struct clk *c;
+
+	if (!oh)
+		return NULL;
+
+	if (oh->_clk) {
+		c = oh->_clk;
+	} else {
+		if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+			return NULL;
+		c = oh->slaves[oh->_mpu_port_index]->_clk;
+	}
+
+	return c->clkdm->pwrdm.ptr;
+
+}
+
+/**
+ * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
+ * @oh: struct omap_hwmod *
+ * @init_oh: struct omap_hwmod * (initiator)
+ *
+ * Add a sleep dependency between the initiator @init_oh and @oh.
+ * Intended to be called by DSP/Bridge code via platform_data for the
+ * DSP case; and by the DMA code in the sDMA case.  DMA code, *Bridge
+ * code needs to add/del initiator dependencies dynamically
+ * before/after accessing a device.  Returns the return value from
+ * _add_initiator_dep().
+ *
+ * XXX Keep a usecount in the clockdomain code
+ */
+int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
+				 struct omap_hwmod *init_oh)
+{
+	return _add_initiator_dep(oh, init_oh);
+}
+
+/*
+ * XXX what about functions for drivers to save/restore ocp_sysconfig
+ * for context save/restore operations?
+ */
+
+/**
+ * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh
+ * @oh: struct omap_hwmod *
+ * @init_oh: struct omap_hwmod * (initiator)
+ *
+ * Remove a sleep dependency between the initiator @init_oh and @oh.
+ * Intended to be called by DSP/Bridge code via platform_data for the
+ * DSP case; and by the DMA code in the sDMA case.  DMA code, *Bridge
+ * code needs to add/del initiator dependencies dynamically
+ * before/after accessing a device.  Returns the return value from
+ * _del_initiator_dep().
+ *
+ * XXX Keep a usecount in the clockdomain code
+ */
+int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
+				 struct omap_hwmod *init_oh)
+{
+	return _del_initiator_dep(oh, init_oh);
+}
+
+/**
+ * omap_hwmod_set_clockact_none - set clockactivity test to BOTH
+ * @oh: struct omap_hwmod *
+ *
+ * On some modules, this function can affect the wakeup latency vs.
+ * power consumption balance.  Intended to be called by the
+ * omap_device layer.  Passes along the return value from
+ * _write_clockact_lock().
+ */
+int omap_hwmod_set_clockact_both(struct omap_hwmod *oh)
+{
+	return _write_clockact_lock(oh, CLOCKACT_TEST_BOTH);
+}
+
+/**
+ * omap_hwmod_set_clockact_none - set clockactivity test to MAIN
+ * @oh: struct omap_hwmod *
+ *
+ * On some modules, this function can affect the wakeup latency vs.
+ * power consumption balance.  Intended to be called by the
+ * omap_device layer.  Passes along the return value from
+ * _write_clockact_lock().
+ */
+int omap_hwmod_set_clockact_main(struct omap_hwmod *oh)
+{
+	return _write_clockact_lock(oh, CLOCKACT_TEST_MAIN);
+}
+
+/**
+ * omap_hwmod_set_clockact_none - set clockactivity test to ICLK
+ * @oh: struct omap_hwmod *
+ *
+ * On some modules, this function can affect the wakeup latency vs.
+ * power consumption balance.  Intended to be called by the
+ * omap_device layer.  Passes along the return value from
+ * _write_clockact_lock().
+ */
+int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh)
+{
+	return _write_clockact_lock(oh, CLOCKACT_TEST_ICLK);
+}
+
+/**
+ * omap_hwmod_set_clockact_none - set clockactivity test to NONE
+ * @oh: struct omap_hwmod *
+ *
+ * On some modules, this function can affect the wakeup latency vs.
+ * power consumption balance.  Intended to be called by the
+ * omap_device layer.  Passes along the return value from
+ * _write_clockact_lock().
+ */
+int omap_hwmod_set_clockact_none(struct omap_hwmod *oh)
+{
+	return _write_clockact_lock(oh, CLOCKACT_TEST_NONE);
+}
+
+/**
+ * omap_hwmod_enable_wakeup - allow device to wake up the system
+ * @oh: struct omap_hwmod *
+ *
+ * Sets the module OCP socket ENAWAKEUP bit to allow the module to
+ * send wakeups to the PRCM.  Eventually this should sets PRCM wakeup
+ * registers to cause the PRCM to receive wakeup events from the
+ * module.  Does not set any wakeup routing registers beyond this
+ * point - if the module is to wake up any other module or subsystem,
+ * that must be set separately.  Called by omap_device code.  Returns
+ * -EINVAL on error or 0 upon success.
+ */
+int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	_enable_wakeup(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
+
+/**
+ * omap_hwmod_disable_wakeup - prevent device from waking the system
+ * @oh: struct omap_hwmod *
+ *
+ * Clears the module OCP socket ENAWAKEUP bit to prevent the module
+ * from sending wakeups to the PRCM.  Eventually this should clear
+ * PRCM wakeup registers to cause the PRCM to ignore wakeup events
+ * from the module.  Does not set any wakeup routing registers beyond
+ * this point - if the module is to wake up any other module or
+ * subsystem, that must be set separately.  Called by omap_device
+ * code.  Returns -EINVAL on error or 0 upon success.
+ */
+int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
+{
+	if (!oh->sysconfig ||
+	    !(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
+		return -EINVAL;
+
+	mutex_lock(&omap_hwmod_mutex);
+	_disable_wakeup(oh);
+	mutex_unlock(&omap_hwmod_mutex);
+
+	return 0;
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420.h b/arch/arm/mach-omap2/omap_hwmod_2420.h
new file mode 100644
index 0000000..767e496
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2420.h
@@ -0,0 +1,141 @@
+/*
+ * omap_hwmod_2420.h - hardware modules present on the OMAP2420 chips
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ * XXX handle crossbar/shared link difference for L3?
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2420_H
+
+#ifdef CONFIG_ARCH_OMAP2420
+
+#include <mach/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <mach/cpu.h>
+#include <mach/dma.h>
+
+#include "prm-regbits-24xx.h"
+
+static struct omap_hwmod omap2420_mpu_hwmod;
+static struct omap_hwmod omap2420_l3_hwmod;
+static struct omap_hwmod omap2420_l4_core_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap2420_l3__l4_core = {
+	.master	= &omap2420_l3_hwmod,
+	.slave	= &omap2420_l4_core_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap2420_mpu__l3 = {
+	.master = &omap2420_mpu_hwmod,
+	.slave	= &omap2420_l3_hwmod,
+	.user	= OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = {
+	&omap2420_mpu__l3,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
+	&omap2420_l3__l4_core,
+};
+
+/* L3 */
+static struct omap_hwmod omap2420_l3_hwmod = {
+	.name		= "l3_hwmod",
+	.masters	= omap2420_l3_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_l3_masters),
+	.slaves		= omap2420_l3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_l3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+static struct omap_hwmod omap2420_l4_wkup_hwmod;
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
+	.master	= &omap2420_l4_core_hwmod,
+	.slave	= &omap2420_l4_wkup_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
+	&omap2420_l3__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
+	&omap2420_l4_core__l4_wkup,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap2420_l4_core_hwmod = {
+	.name		= "l4_core_hwmod",
+	.masters	= omap2420_l4_core_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_l4_core_masters),
+	.slaves		= omap2420_l4_core_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_l4_core_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_wkup_slaves[] = {
+	&omap2420_l4_core__l4_wkup,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap2420_l4_wkup_hwmod = {
+	.name		= "l4_wkup_hwmod",
+	.masters	= omap2420_l4_wkup_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_l4_wkup_masters),
+	.slaves		= omap2420_l4_wkup_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2420_l4_wkup_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
+	&omap2420_mpu__l3,
+};
+
+/* MPU */
+static struct omap_hwmod omap2420_mpu_hwmod = {
+	.name		= "mpu_hwmod",
+	.clkdev_dev_id	= NULL,
+	.clkdev_con_id	= "mpu_ck",
+	.masters	= omap2420_mpu_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2420_mpu_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static __initdata struct omap_hwmod *omap2420_hwmods[] = {
+	&omap2420_l3_hwmod,
+	&omap2420_l4_core_hwmod,
+	&omap2420_l4_wkup_hwmod,
+	&omap2420_mpu_hwmod,
+	NULL,
+};
+
+#else
+# define omap2420_hwmods		0
+#endif
+
+#endif
+
+
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430.h b/arch/arm/mach-omap2/omap_hwmod_2430.h
new file mode 100644
index 0000000..a412be6
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2430.h
@@ -0,0 +1,143 @@
+/*
+ * omap_hwmod_2430.h - hardware modules present on the OMAP2430 chips
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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.
+ *
+ * XXX handle crossbar/shared link difference for L3?
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD2430_H
+
+#ifdef CONFIG_ARCH_OMAP2430
+
+#include <mach/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <mach/cpu.h>
+#include <mach/dma.h>
+
+#include "prm-regbits-24xx.h"
+
+static struct omap_hwmod omap2430_mpu_hwmod;
+static struct omap_hwmod omap2430_l3_hwmod;
+static struct omap_hwmod omap2430_l4_core_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap2430_l3__l4_core = {
+	.master	= &omap2430_l3_hwmod,
+	.slave	= &omap2430_l4_core_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap2430_mpu__l3 = {
+	.master = &omap2430_mpu_hwmod,
+	.slave	= &omap2430_l3_hwmod,
+	.user	= OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = {
+	&omap2430_mpu__l3,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
+	&omap2430_l3__l4_core,
+};
+
+/* L3 */
+static struct omap_hwmod omap2430_l3_hwmod = {
+	.name		= "l3_hwmod",
+	.masters	= omap2430_l3_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_l3_masters),
+	.slaves		= omap2430_l3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_l3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+static struct omap_hwmod omap2430_l4_wkup_hwmod;
+static struct omap_hwmod omap2430_mmc1_hwmod;
+static struct omap_hwmod omap2430_mmc2_hwmod;
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
+	.master	= &omap2430_l4_core_hwmod,
+	.slave	= &omap2430_l4_wkup_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
+	&omap2430_l3__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
+	&omap2430_l4_core__l4_wkup,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap2430_l4_core_hwmod = {
+	.name		= "l4_core_hwmod",
+	.masters	= omap2430_l4_core_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_l4_core_masters),
+	.slaves		= omap2430_l4_core_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_l4_core_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = {
+	&omap2430_l4_core__l4_wkup,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap2430_l4_wkup_hwmod = {
+	.name		= "l4_wkup_hwmod",
+	.masters	= omap2430_l4_wkup_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_l4_wkup_masters),
+	.slaves		= omap2430_l4_wkup_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap2430_l4_wkup_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
+	&omap2430_mpu__l3,
+};
+
+/* MPU */
+static struct omap_hwmod omap2430_mpu_hwmod = {
+	.name		= "mpu_hwmod",
+	.clkdev_dev_id	= NULL,
+	.clkdev_con_id	= "mpu_ck",
+	.masters	= omap2430_mpu_masters,
+	.masters_cnt	= ARRAY_SIZE(omap2430_mpu_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static __initdata struct omap_hwmod *omap2430_hwmods[] = {
+	&omap2430_l3_hwmod,
+	&omap2430_l4_core_hwmod,
+	&omap2430_l4_wkup_hwmod,
+	&omap2430_mpu_hwmod,
+	NULL,
+};
+
+#else
+# define omap2430_hwmods		0
+#endif
+
+#endif
+
+
diff --git a/arch/arm/mach-omap2/omap_hwmod_34xx.h b/arch/arm/mach-omap2/omap_hwmod_34xx.h
new file mode 100644
index 0000000..1e069f8
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_34xx.h
@@ -0,0 +1,168 @@
+/*
+ * omap_hwmod_34xx.h - hardware modules present on the OMAP34xx chips
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD34XX_H
+
+#ifdef CONFIG_ARCH_OMAP34XX
+
+#include <mach/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <mach/cpu.h>
+#include <mach/dma.h>
+
+#include "prm-regbits-34xx.h"
+
+static struct omap_hwmod omap34xx_mpu_hwmod;
+static struct omap_hwmod omap34xx_l3_hwmod;
+static struct omap_hwmod omap34xx_l4_core_hwmod;
+static struct omap_hwmod omap34xx_l4_per_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap34xx_l3__l4_core = {
+	.master	= &omap34xx_l3_hwmod,
+	.slave	= &omap34xx_l4_core_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L3 -> L4_PER interface */
+static struct omap_hwmod_ocp_if omap34xx_l3__l4_per = {
+	.master = &omap34xx_l3_hwmod,
+	.slave	= &omap34xx_l4_per_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap34xx_mpu__l3 = {
+	.master = &omap34xx_mpu_hwmod,
+	.slave	= &omap34xx_l3_hwmod,
+	.user	= OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l3_slaves[] = {
+	&omap34xx_mpu__l3,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l3_masters[] = {
+	&omap34xx_l3__l4_core,
+	&omap34xx_l3__l4_per,
+};
+
+/* L3 */
+static struct omap_hwmod omap34xx_l3_hwmod = {
+	.name		= "l3_hwmod",
+	.masters	= omap34xx_l3_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_l3_masters),
+	.slaves		= omap34xx_l3_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_l3_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+static struct omap_hwmod omap34xx_l4_wkup_hwmod;
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap34xx_l4_core__l4_wkup = {
+	.master	= &omap34xx_l4_core_hwmod,
+	.slave	= &omap34xx_l4_wkup_hwmod,
+	.user	= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l4_core_slaves[] = {
+	&omap34xx_l3__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l4_core_masters[] = {
+	&omap34xx_l4_core__l4_wkup,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap34xx_l4_core_hwmod = {
+	.name		= "l4_core_hwmod",
+	.masters	= omap34xx_l4_core_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_l4_core_masters),
+	.slaves		= omap34xx_l4_core_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_l4_core_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* Slave interfaces on the L4_PER interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l4_per_slaves[] = {
+	&omap34xx_l3__l4_per,
+};
+
+/* Master interfaces on the L4_PER interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l4_per_masters[] = {
+};
+
+/* L4 PER */
+static struct omap_hwmod omap34xx_l4_per_hwmod = {
+	.name		= "l4_per_hwmod",
+	.masters	= omap34xx_l4_per_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_l4_per_masters),
+	.slaves		= omap34xx_l4_per_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_l4_per_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_slaves[] = {
+	&omap34xx_l4_core__l4_wkup,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap34xx_l4_wkup_masters[] = {
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap34xx_l4_wkup_hwmod = {
+	.name		= "l4_wkup_hwmod",
+	.masters	= omap34xx_l4_wkup_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_l4_wkup_masters),
+	.slaves		= omap34xx_l4_wkup_slaves,
+	.slaves_cnt	= ARRAY_SIZE(omap34xx_l4_wkup_slaves),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap34xx_mpu_masters[] = {
+	&omap34xx_mpu__l3,
+};
+
+/* MPU */
+static struct omap_hwmod omap34xx_mpu_hwmod = {
+	.name		= "mpu_hwmod",
+	.clkdev_dev_id	= NULL,
+	.clkdev_con_id	= "arm_fck",
+	.masters	= omap34xx_mpu_masters,
+	.masters_cnt	= ARRAY_SIZE(omap34xx_mpu_masters),
+	.omap_chip	= OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static __initdata struct omap_hwmod *omap34xx_hwmods[] = {
+	&omap34xx_l3_hwmod,
+	&omap34xx_l4_core_hwmod,
+	&omap34xx_l4_per_hwmod,
+	&omap34xx_l4_wkup_hwmod,
+	&omap34xx_mpu_hwmod,
+	NULL,
+};
+
+#else
+# define omap34xx_hwmods		0
+#endif
+
+#endif
+
+
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 6cc375a..1b4c160 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -20,13 +20,16 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/timer.h>
+#include <linux/sched.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/module.h>
 
 #include <mach/clock.h>
 #include <mach/board.h>
+#include <mach/powerdomain.h>
+#include <mach/clockdomain.h>
 
 #include "prm.h"
 #include "cm.h"
@@ -48,7 +51,9 @@ int omap2_pm_debug;
 	regs[reg_count++].val = __raw_readl(reg)
 #define DUMP_INTC_REG(reg, off) \
 	regs[reg_count].name = #reg; \
-	regs[reg_count++].val = __raw_readl(IO_ADDRESS(0x480fe000 + (off)))
+	regs[reg_count++].val = __raw_readl(OMAP2_IO_ADDRESS(0x480fe000 + (off)))
+
+static int __init pm_dbg_init(void);
 
 void omap2_pm_dump(int mode, int resume, unsigned int us)
 {
@@ -150,3 +155,425 @@ void omap2_pm_dump(int mode, int resume, unsigned int us)
 	for (i = 0; i < reg_count; i++)
 		printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
 }
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static void pm_dbg_regset_store(u32 *ptr);
+
+struct dentry *pm_dbg_dir;
+
+static int pm_dbg_init_done;
+
+enum {
+	DEBUG_FILE_COUNTERS = 0,
+	DEBUG_FILE_TIMERS,
+};
+
+struct pm_module_def {
+	char name[8]; /* Name of the module */
+	short type; /* CM or PRM */
+	unsigned short offset;
+	int low; /* First register address on this module */
+	int high; /* Last register address on this module */
+};
+
+#define MOD_CM 0
+#define MOD_PRM 1
+
+static const struct pm_module_def *pm_dbg_reg_modules;
+static const struct pm_module_def omap3_pm_reg_modules[] = {
+	{ "IVA2", MOD_CM, OMAP3430_IVA2_MOD, 0, 0x4c },
+	{ "OCP", MOD_CM, OCP_MOD, 0, 0x10 },
+	{ "MPU", MOD_CM, MPU_MOD, 4, 0x4c },
+	{ "CORE", MOD_CM, CORE_MOD, 0, 0x4c },
+	{ "SGX", MOD_CM, OMAP3430ES2_SGX_MOD, 0, 0x4c },
+	{ "WKUP", MOD_CM, WKUP_MOD, 0, 0x40 },
+	{ "CCR", MOD_CM, PLL_MOD, 0, 0x70 },
+	{ "DSS", MOD_CM, OMAP3430_DSS_MOD, 0, 0x4c },
+	{ "CAM", MOD_CM, OMAP3430_CAM_MOD, 0, 0x4c },
+	{ "PER", MOD_CM, OMAP3430_PER_MOD, 0, 0x4c },
+	{ "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 },
+	{ "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 },
+	{ "USB", MOD_CM, OMAP3430ES2_USBHOST_MOD, 0, 0x4c },
+
+	{ "IVA2", MOD_PRM, OMAP3430_IVA2_MOD, 0x50, 0xfc },
+	{ "OCP", MOD_PRM, OCP_MOD, 4, 0x1c },
+	{ "MPU", MOD_PRM, MPU_MOD, 0x58, 0xe8 },
+	{ "CORE", MOD_PRM, CORE_MOD, 0x58, 0xf8 },
+	{ "SGX", MOD_PRM, OMAP3430ES2_SGX_MOD, 0x58, 0xe8 },
+	{ "WKUP", MOD_PRM, WKUP_MOD, 0xa0, 0xb0 },
+	{ "CCR", MOD_PRM, PLL_MOD, 0x40, 0x70 },
+	{ "DSS", MOD_PRM, OMAP3430_DSS_MOD, 0x58, 0xe8 },
+	{ "CAM", MOD_PRM, OMAP3430_CAM_MOD, 0x58, 0xe8 },
+	{ "PER", MOD_PRM, OMAP3430_PER_MOD, 0x58, 0xe8 },
+	{ "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 },
+	{ "GLBL", MOD_PRM, OMAP3430_GR_MOD, 0x20, 0xe4 },
+	{ "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 },
+	{ "USB", MOD_PRM, OMAP3430ES2_USBHOST_MOD, 0x58, 0xe8 },
+	{ "", 0, 0, 0, 0 },
+};
+
+#define PM_DBG_MAX_REG_SETS 4
+
+static void *pm_dbg_reg_set[PM_DBG_MAX_REG_SETS];
+
+static int pm_dbg_get_regset_size(void)
+{
+	static int regset_size;
+
+	if (regset_size == 0) {
+		int i = 0;
+
+		while (pm_dbg_reg_modules[i].name[0] != 0) {
+			regset_size += pm_dbg_reg_modules[i].high +
+				4 - pm_dbg_reg_modules[i].low;
+			i++;
+		}
+	}
+	return regset_size;
+}
+
+static int pm_dbg_show_regs(struct seq_file *s, void *unused)
+{
+	int i, j;
+	unsigned long val;
+	int reg_set = (int)s->private;
+	u32 *ptr;
+	void *store = NULL;
+	int regs;
+	int linefeed;
+
+	if (reg_set == 0) {
+		store = kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
+		ptr = store;
+		pm_dbg_regset_store(ptr);
+	} else {
+		ptr = pm_dbg_reg_set[reg_set - 1];
+	}
+
+	i = 0;
+
+	while (pm_dbg_reg_modules[i].name[0] != 0) {
+		regs = 0;
+		linefeed = 0;
+		if (pm_dbg_reg_modules[i].type == MOD_CM)
+			seq_printf(s, "MOD: CM_%s (%08x)\n",
+				pm_dbg_reg_modules[i].name,
+				(u32)(OMAP3430_CM_BASE +
+				pm_dbg_reg_modules[i].offset));
+		else
+			seq_printf(s, "MOD: PRM_%s (%08x)\n",
+				pm_dbg_reg_modules[i].name,
+				(u32)(OMAP3430_PRM_BASE +
+				pm_dbg_reg_modules[i].offset));
+
+		for (j = pm_dbg_reg_modules[i].low;
+			j <= pm_dbg_reg_modules[i].high; j += 4) {
+			val = *(ptr++);
+			if (val != 0) {
+				regs++;
+				if (linefeed) {
+					seq_printf(s, "\n");
+					linefeed = 0;
+				}
+				seq_printf(s, "  %02x => %08lx", j, val);
+				if (regs % 4 == 0)
+					linefeed = 1;
+			}
+		}
+		seq_printf(s, "\n");
+		i++;
+	}
+
+	if (store != NULL)
+		kfree(store);
+
+	return 0;
+}
+
+static void pm_dbg_regset_store(u32 *ptr)
+{
+	int i, j;
+	u32 val;
+
+	i = 0;
+
+	while (pm_dbg_reg_modules[i].name[0] != 0) {
+		for (j = pm_dbg_reg_modules[i].low;
+			j <= pm_dbg_reg_modules[i].high; j += 4) {
+			if (pm_dbg_reg_modules[i].type == MOD_CM)
+				val = cm_read_mod_reg(
+					pm_dbg_reg_modules[i].offset, j);
+			else
+				val = prm_read_mod_reg(
+					pm_dbg_reg_modules[i].offset, j);
+			*(ptr++) = val;
+		}
+		i++;
+	}
+}
+
+int pm_dbg_regset_save(int reg_set)
+{
+	if (pm_dbg_reg_set[reg_set-1] == NULL)
+		return -EINVAL;
+
+	pm_dbg_regset_store(pm_dbg_reg_set[reg_set-1]);
+
+	return 0;
+}
+
+static const char pwrdm_state_names[][4] = {
+	"OFF",
+	"RET",
+	"INA",
+	"ON"
+};
+
+void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
+{
+	s64 t;
+
+	if (!pm_dbg_init_done)
+		return ;
+
+	/* Update timer for previous state */
+	t = sched_clock();
+
+	pwrdm->state_timer[prev] += t - pwrdm->timer;
+
+	pwrdm->timer = t;
+}
+
+static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
+{
+	struct seq_file *s = (struct seq_file *)user;
+
+	if (strcmp(clkdm->name, "emu_clkdm") == 0 ||
+		strcmp(clkdm->name, "wkup_clkdm") == 0 ||
+		strncmp(clkdm->name, "dpll", 4) == 0)
+		return 0;
+
+	seq_printf(s, "%s->%s (%d)", clkdm->name,
+			clkdm->pwrdm.ptr->name,
+			atomic_read(&clkdm->usecount));
+	seq_printf(s, "\n");
+
+	return 0;
+}
+
+static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
+{
+	struct seq_file *s = (struct seq_file *)user;
+	int i;
+
+	if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
+		strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
+		strncmp(pwrdm->name, "dpll", 4) == 0)
+		return 0;
+
+	if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
+		printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n",
+			pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));
+
+	seq_printf(s, "%s (%s)", pwrdm->name,
+			pwrdm_state_names[pwrdm->state]);
+	for (i = 0; i < 4; i++)
+		seq_printf(s, ",%s:%d", pwrdm_state_names[i],
+			pwrdm->state_counter[i]);
+
+	seq_printf(s, "\n");
+
+	return 0;
+}
+
+static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
+{
+	struct seq_file *s = (struct seq_file *)user;
+	int i;
+
+	if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
+		strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
+		strncmp(pwrdm->name, "dpll", 4) == 0)
+		return 0;
+
+	pwrdm_state_switch(pwrdm);
+
+	seq_printf(s, "%s (%s)", pwrdm->name,
+		pwrdm_state_names[pwrdm->state]);
+
+	for (i = 0; i < 4; i++)
+		seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
+			pwrdm->state_timer[i]);
+
+	seq_printf(s, "\n");
+	return 0;
+}
+
+static int pm_dbg_show_counters(struct seq_file *s, void *unused)
+{
+	pwrdm_for_each(pwrdm_dbg_show_counter, s);
+	clkdm_for_each(clkdm_dbg_show_counter, s);
+
+	return 0;
+}
+
+static int pm_dbg_show_timers(struct seq_file *s, void *unused)
+{
+	pwrdm_for_each(pwrdm_dbg_show_timer, s);
+	return 0;
+}
+
+static int pm_dbg_open(struct inode *inode, struct file *file)
+{
+	switch ((int)inode->i_private) {
+	case DEBUG_FILE_COUNTERS:
+		return single_open(file, pm_dbg_show_counters,
+			&inode->i_private);
+	case DEBUG_FILE_TIMERS:
+	default:
+		return single_open(file, pm_dbg_show_timers,
+			&inode->i_private);
+	};
+}
+
+static int pm_dbg_reg_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, pm_dbg_show_regs, inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+	.open           = pm_dbg_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static const struct file_operations debug_reg_fops = {
+	.open           = pm_dbg_reg_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+int pm_dbg_regset_init(int reg_set)
+{
+	char name[2];
+
+	if (!pm_dbg_init_done)
+		pm_dbg_init();
+
+	if (reg_set < 1 || reg_set > PM_DBG_MAX_REG_SETS ||
+		pm_dbg_reg_set[reg_set-1] != NULL)
+		return -EINVAL;
+
+	pm_dbg_reg_set[reg_set-1] =
+		kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
+
+	if (pm_dbg_reg_set[reg_set-1] == NULL)
+		return -ENOMEM;
+
+	if (pm_dbg_dir != NULL) {
+		sprintf(name, "%d", reg_set);
+
+		(void) debugfs_create_file(name, S_IRUGO,
+			pm_dbg_dir, (void *)reg_set, &debug_reg_fops);
+	}
+
+	return 0;
+}
+
+static int pwrdm_suspend_get(void *data, u64 *val)
+{
+	*val = omap3_pm_get_suspend_state((struct powerdomain *)data);
+
+	if (*val >= 0)
+		return 0;
+	return *val;
+}
+
+static int pwrdm_suspend_set(void *data, u64 val)
+{
+	return omap3_pm_set_suspend_state((struct powerdomain *)data, (int)val);
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
+			pwrdm_suspend_set, "%llu\n");
+
+static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
+{
+	int i;
+	s64 t;
+	struct dentry *d;
+
+	t = sched_clock();
+
+	for (i = 0; i < 4; i++)
+		pwrdm->state_timer[i] = 0;
+
+	pwrdm->timer = t;
+
+	if (strncmp(pwrdm->name, "dpll", 4) == 0)
+		return 0;
+
+	d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir);
+
+	(void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d,
+			(void *)pwrdm, &pwrdm_suspend_fops);
+
+	return 0;
+}
+
+static int __init pm_dbg_init(void)
+{
+	int i;
+	struct dentry *d;
+	char name[2];
+
+	if (pm_dbg_init_done)
+		return 0;
+
+	if (cpu_is_omap34xx())
+		pm_dbg_reg_modules = omap3_pm_reg_modules;
+	else {
+		printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
+		return -ENODEV;
+	}
+		
+	d = debugfs_create_dir("pm_debug", NULL);
+	if (IS_ERR(d))
+		return PTR_ERR(d);
+
+	(void) debugfs_create_file("count", S_IRUGO,
+		d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
+	(void) debugfs_create_file("time", S_IRUGO,
+		d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
+
+	pwrdm_for_each(pwrdms_setup, (void *)d);
+
+	pm_dbg_dir = debugfs_create_dir("registers", d);
+	if (IS_ERR(pm_dbg_dir))
+		return PTR_ERR(pm_dbg_dir);
+
+	(void) debugfs_create_file("current", S_IRUGO,
+		pm_dbg_dir, (void *)0, &debug_reg_fops);
+
+	for (i = 0; i < PM_DBG_MAX_REG_SETS; i++)
+		if (pm_dbg_reg_set[i] != NULL) {
+			sprintf(name, "%d", i+1);
+			(void) debugfs_create_file(name, S_IRUGO,
+				pm_dbg_dir, (void *)(i+1), &debug_reg_fops);
+
+		}
+
+	pm_dbg_init_done = 1;
+
+	return 0;
+}
+arch_initcall(pm_dbg_init);
+
+#else
+void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) {}
+#endif
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 21201cd..8400f57 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -11,12 +11,23 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PM_H
 #define __ARCH_ARM_MACH_OMAP2_PM_H
 
+#include <mach/powerdomain.h>
+
+extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
+extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
+
 #ifdef CONFIG_PM_DEBUG
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
 extern int omap2_pm_debug;
+extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
+extern int pm_dbg_regset_save(int reg_set);
+extern int pm_dbg_regset_init(int reg_set);
 #else
 #define omap2_pm_dump(mode, resume, us)		do {} while (0);
 #define omap2_pm_debug				0
+#define pm_dbg_update_time(pwrdm, prev) do {} while (0);
+#define pm_dbg_regset_save(reg_set) do {} while (0);
+#define pm_dbg_regset_init(reg_set) do {} while (0);
 #endif /* CONFIG_PM_DEBUG */
 
 extern void omap24xx_idle_loop_suspend(void);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 528dbdc..bff5c4e 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -333,7 +333,7 @@ static struct platform_suspend_ops omap_pm_ops = {
 	.valid		= suspend_valid_only_mem,
 };
 
-static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm)
+static int _pm_clkdm_enable_hwsup(struct clockdomain *clkdm, void *unused)
 {
 	omap2_clkdm_allow_idle(clkdm);
 	return 0;
@@ -385,7 +385,7 @@ static void __init prcm_setup_regs(void)
 	omap2_clkdm_sleep(gfx_clkdm);
 
 	/* Enable clockdomain hardware-supervised control for all clkdms */
-	clkdm_for_each(_pm_clkdm_enable_hwsup);
+	clkdm_for_each(_pm_clkdm_enable_hwsup, NULL);
 
 	/* Enable clock autoidle for all domains */
 	cm_write_mod_reg(OMAP24XX_AUTO_CAM |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 488d595..0ff5a6c 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -170,6 +170,8 @@ static void omap_sram_idle(void)
 		printk(KERN_ERR "Invalid mpu state in sram_idle\n");
 		return;
 	}
+	pwrdm_pre_transition();
+
 	omap2_gpio_prepare_for_retention();
 	omap_uart_prepare_idle(0);
 	omap_uart_prepare_idle(1);
@@ -182,6 +184,9 @@ static void omap_sram_idle(void)
 	omap_uart_resume_idle(1);
 	omap_uart_resume_idle(0);
 	omap2_gpio_resume_after_retention();
+
+	pwrdm_post_transition();
+
 }
 
 /*
@@ -271,6 +276,7 @@ static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
 	if (sleep_switch) {
 		omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
 		pwrdm_wait_transition(pwrdm);
+		pwrdm_state_switch(pwrdm);
 	}
 
 err:
@@ -658,14 +664,38 @@ static void __init prcm_setup_regs(void)
 	omap3_d2d_idle();
 }
 
-static int __init pwrdms_setup(struct powerdomain *pwrdm)
+int omap3_pm_get_suspend_state(struct powerdomain *pwrdm)
+{
+	struct power_state *pwrst;
+
+	list_for_each_entry(pwrst, &pwrst_list, node) {
+		if (pwrst->pwrdm == pwrdm)
+			return pwrst->next_state;
+	}
+	return -EINVAL;
+}
+
+int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
+{
+	struct power_state *pwrst;
+
+	list_for_each_entry(pwrst, &pwrst_list, node) {
+		if (pwrst->pwrdm == pwrdm) {
+			pwrst->next_state = state;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 {
 	struct power_state *pwrst;
 
 	if (!pwrdm->pwrsts)
 		return 0;
 
-	pwrst = kmalloc(sizeof(struct power_state), GFP_KERNEL);
+	pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
 	if (!pwrst)
 		return -ENOMEM;
 	pwrst->pwrdm = pwrdm;
@@ -683,7 +713,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm)
  * supported. Initiate sleep transition for other clockdomains, if
  * they are not used
  */
-static int __init clkdms_setup(struct clockdomain *clkdm)
+static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
 {
 	if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
 		omap2_clkdm_allow_idle(clkdm);
@@ -716,13 +746,13 @@ static int __init omap3_pm_init(void)
 		goto err1;
 	}
 
-	ret = pwrdm_for_each(pwrdms_setup);
+	ret = pwrdm_for_each(pwrdms_setup, NULL);
 	if (ret) {
 		printk(KERN_ERR "Failed to setup powerdomains\n");
 		goto err2;
 	}
 
-	(void) clkdm_for_each(clkdms_setup);
+	(void) clkdm_for_each(clkdms_setup, NULL);
 
 	mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
 	if (mpu_pwrdm == NULL) {
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 983f1cb..2594cbf 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -35,6 +35,13 @@
 #include <mach/powerdomain.h>
 #include <mach/clockdomain.h>
 
+#include "pm.h"
+
+enum {
+	PWRDM_STATE_NOW = 0,
+	PWRDM_STATE_PREV,
+};
+
 /* pwrdm_list contains all registered struct powerdomains */
 static LIST_HEAD(pwrdm_list);
 
@@ -83,7 +90,7 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
 	if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
 		return ERR_PTR(-EINVAL);
 
-	for (pd = deps; pd; pd++) {
+	for (pd = deps; pd->pwrdm_name; pd++) {
 
 		if (!omap_chip_is(pd->omap_chip))
 			continue;
@@ -96,12 +103,71 @@ static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
 
 	}
 
-	if (!pd)
+	if (!pd->pwrdm_name)
 		return ERR_PTR(-ENOENT);
 
 	return pd->pwrdm;
 }
 
+static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
+{
+
+	int prev;
+	int state;
+
+	if (pwrdm == NULL)
+		return -EINVAL;
+
+	state = pwrdm_read_pwrst(pwrdm);
+
+	switch (flag) {
+	case PWRDM_STATE_NOW:
+		prev = pwrdm->state;
+		break;
+	case PWRDM_STATE_PREV:
+		prev = pwrdm_read_prev_pwrst(pwrdm);
+		if (pwrdm->state != prev)
+			pwrdm->state_counter[prev]++;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (state != prev)
+		pwrdm->state_counter[state]++;
+
+	pm_dbg_update_time(pwrdm, prev);
+
+	pwrdm->state = state;
+
+	return 0;
+}
+
+static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
+{
+	pwrdm_clear_all_prev_pwrst(pwrdm);
+	_pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+	return 0;
+}
+
+static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
+{
+	_pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
+	return 0;
+}
+
+static __init void _pwrdm_setup(struct powerdomain *pwrdm)
+{
+	int i;
+
+	for (i = 0; i < 4; i++)
+		pwrdm->state_counter[i] = 0;
+
+	pwrdm_wait_transition(pwrdm);
+	pwrdm->state = pwrdm_read_pwrst(pwrdm);
+	pwrdm->state_counter[pwrdm->state] = 1;
+
+}
 
 /* Public functions */
 
@@ -117,9 +183,12 @@ void pwrdm_init(struct powerdomain **pwrdm_list)
 {
 	struct powerdomain **p = NULL;
 
-	if (pwrdm_list)
-		for (p = pwrdm_list; *p; p++)
+	if (pwrdm_list) {
+		for (p = pwrdm_list; *p; p++) {
 			pwrdm_register(*p);
+			_pwrdm_setup(*p);
+		}
+	}
 }
 
 /**
@@ -217,7 +286,8 @@ struct powerdomain *pwrdm_lookup(const char *name)
  * anything else to indicate failure; or -EINVAL if the function
  * pointer is null.
  */
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user)
 {
 	struct powerdomain *temp_pwrdm;
 	unsigned long flags;
@@ -228,7 +298,7 @@ int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
 
 	read_lock_irqsave(&pwrdm_rwlock, flags);
 	list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
-		ret = (*fn)(temp_pwrdm);
+		ret = (*fn)(temp_pwrdm, user);
 		if (ret)
 			break;
 	}
@@ -1110,4 +1180,36 @@ int pwrdm_wait_transition(struct powerdomain *pwrdm)
 	return 0;
 }
 
+int pwrdm_state_switch(struct powerdomain *pwrdm)
+{
+	return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+}
+
+int pwrdm_clkdm_state_switch(struct clockdomain *clkdm)
+{
+	if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) {
+		pwrdm_wait_transition(clkdm->pwrdm.ptr);
+		return pwrdm_state_switch(clkdm->pwrdm.ptr);
+	}
+
+	return -EINVAL;
+}
+int pwrdm_clk_state_switch(struct clk *clk)
+{
+	if (clk != NULL && clk->clkdm != NULL)
+		return pwrdm_clkdm_state_switch(clk->clkdm);
+	return -EINVAL;
+}
+
+int pwrdm_pre_transition(void)
+{
+	pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
+	return 0;
+}
+
+int pwrdm_post_transition(void)
+{
+	pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
+	return 0;
+}
 
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index 9937e28..03c467c 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -17,11 +17,11 @@
 #include "prcm-common.h"
 
 #define OMAP2420_PRM_REGADDR(module, reg)				\
-			IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
+			OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
 #define OMAP2430_PRM_REGADDR(module, reg)				\
-			IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
+			OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
 #define OMAP34XX_PRM_REGADDR(module, reg)				\
-			IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
+			OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
 
 /*
  * Architecture-specific global PRM registers
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
index 1a8bbd0..0837eda 100644
--- a/arch/arm/mach-omap2/sdrc.h
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -48,9 +48,9 @@ static inline u32 sms_read_reg(u16 reg)
 	return __raw_readl(OMAP_SMS_REGADDR(reg));
 }
 #else
-#define OMAP242X_SDRC_REGADDR(reg)	IO_ADDRESS(OMAP2420_SDRC_BASE + (reg))
-#define OMAP243X_SDRC_REGADDR(reg)	IO_ADDRESS(OMAP243X_SDRC_BASE + (reg))
-#define OMAP34XX_SDRC_REGADDR(reg)	IO_ADDRESS(OMAP343X_SDRC_BASE + (reg))
+#define OMAP242X_SDRC_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE + (reg))
+#define OMAP243X_SDRC_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE + (reg))
+#define OMAP34XX_SDRC_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE + (reg))
 #endif	/* __ASSEMBLER__ */
 
 #endif
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index a7421a5..3a529c7 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -73,7 +73,7 @@ static LIST_HEAD(uart_list);
 
 static struct plat_serial8250_port serial_platform_data0[] = {
 	{
-		.membase	= IO_ADDRESS(OMAP_UART1_BASE),
+		.membase	= OMAP2_IO_ADDRESS(OMAP_UART1_BASE),
 		.mapbase	= OMAP_UART1_BASE,
 		.irq		= 72,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -87,7 +87,7 @@ static struct plat_serial8250_port serial_platform_data0[] = {
 
 static struct plat_serial8250_port serial_platform_data1[] = {
 	{
-		.membase	= IO_ADDRESS(OMAP_UART2_BASE),
+		.membase	= OMAP2_IO_ADDRESS(OMAP_UART2_BASE),
 		.mapbase	= OMAP_UART2_BASE,
 		.irq		= 73,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -101,7 +101,7 @@ static struct plat_serial8250_port serial_platform_data1[] = {
 
 static struct plat_serial8250_port serial_platform_data2[] = {
 	{
-		.membase	= IO_ADDRESS(OMAP_UART3_BASE),
+		.membase	= OMAP2_IO_ADDRESS(OMAP_UART3_BASE),
 		.mapbase	= OMAP_UART3_BASE,
 		.irq		= 74,
 		.flags		= UPF_BOOT_AUTOCONF,
@@ -109,10 +109,35 @@ static struct plat_serial8250_port serial_platform_data2[] = {
 		.regshift	= 2,
 		.uartclk	= OMAP24XX_BASE_BAUD * 16,
 	}, {
+#ifdef CONFIG_ARCH_OMAP4
+		.membase	= IO_ADDRESS(OMAP_UART4_BASE),
+		.mapbase	= OMAP_UART4_BASE,
+		.irq		= 70,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP24XX_BASE_BAUD * 16,
+	}, {
+#endif
 		.flags		= 0
 	}
 };
 
+#ifdef CONFIG_ARCH_OMAP4
+static struct plat_serial8250_port serial_platform_data3[] = {
+	{
+		.membase	= IO_ADDRESS(OMAP_UART4_BASE),
+		.mapbase	= OMAP_UART4_BASE,
+		.irq		= 70,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= OMAP24XX_BASE_BAUD * 16,
+	}, {
+		.flags		= 0
+	}
+};
+#endif
 static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
 					   int offset)
 {
@@ -460,7 +485,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 		uart->padconf = 0;
 	}
 
-	p->flags |= UPF_SHARE_IRQ;
+	p->irqflags |= IRQF_SHARED;
 	ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED,
 			  "serial idle", (void *)uart);
 	WARN_ON(ret);
@@ -550,12 +575,22 @@ static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = {
 			},
 		},
 	},
+#ifdef CONFIG_ARCH_OMAP4
+	{
+		.pdev = {
+			.name			= "serial8250",
+			.id			= 3
+			.dev			= {
+				.platform_data	= serial_platform_data3,
+			},
+		},
+	},
+#endif
 };
 
-void __init omap_serial_init(void)
+void __init omap_serial_early_init(void)
 {
 	int i;
-	const struct omap_uart_config *info;
 	char name[16];
 
 	/*
@@ -564,23 +599,12 @@ void __init omap_serial_init(void)
 	 * if not needed.
 	 */
 
-	info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
-
-	if (info == NULL)
-		return;
-
 	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
 		struct omap_uart_state *uart = &omap_uart[i];
 		struct platform_device *pdev = &uart->pdev;
 		struct device *dev = &pdev->dev;
 		struct plat_serial8250_port *p = dev->platform_data;
 
-		if (!(info->enabled_uarts & (1 << i))) {
-			p->membase = NULL;
-			p->mapbase = 0;
-			continue;
-		}
-
 		sprintf(name, "uart%d_ick", i+1);
 		uart->ick = clk_get(NULL, name);
 		if (IS_ERR(uart->ick)) {
@@ -595,8 +619,11 @@ void __init omap_serial_init(void)
 			uart->fck = NULL;
 		}
 
-		if (!uart->ick || !uart->fck)
-			continue;
+		/* FIXME: Remove this once the clkdev is ready */
+		if (!cpu_is_omap44xx()) {
+			if (!uart->ick || !uart->fck)
+				continue;
+		}
 
 		uart->num = i;
 		p->private_data = uart;
@@ -607,6 +634,18 @@ void __init omap_serial_init(void)
 			p->irq += 32;
 
 		omap_uart_enable_clocks(uart);
+	}
+}
+
+void __init omap_serial_init(void)
+{
+	int i;
+
+	for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+		struct omap_uart_state *uart = &omap_uart[i];
+		struct platform_device *pdev = &uart->pdev;
+		struct device *dev = &pdev->dev;
+
 		omap_uart_reset(uart);
 		omap_uart_idle_init(uart);
 
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
index bb29985..9b62208 100644
--- a/arch/arm/mach-omap2/sram242x.S
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -128,7 +128,7 @@ omap242x_sdi_prcm_voltctrl:
 prcm_mask_val:
 	.word 0xFFFF3FFC
 omap242x_sdi_timer_32ksynct_cr:
-	.word IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
+	.word OMAP2_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
 ENTRY(omap242x_sram_ddr_init_sz)
 	.word	. - omap242x_sram_ddr_init
 
@@ -224,7 +224,7 @@ omap242x_srs_prcm_voltctrl:
 ddr_prcm_mask_val:
 	.word 0xFFFF3FFC
 omap242x_srs_timer_32ksynct:
-	.word IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
+	.word OMAP2_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
 
 ENTRY(omap242x_sram_reprogram_sdrc_sz)
 	.word	. - omap242x_sram_reprogram_sdrc
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
index 9955abc..df2cd92 100644
--- a/arch/arm/mach-omap2/sram243x.S
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -128,7 +128,7 @@ omap243x_sdi_prcm_voltctrl:
 prcm_mask_val:
 	.word 0xFFFF3FFC
 omap243x_sdi_timer_32ksynct_cr:
-	.word IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
+	.word OMAP2_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
 ENTRY(omap243x_sram_ddr_init_sz)
 	.word	. - omap243x_sram_ddr_init
 
@@ -224,7 +224,7 @@ omap243x_srs_prcm_voltctrl:
 ddr_prcm_mask_val:
 	.word 0xFFFF3FFC
 omap243x_srs_timer_32ksynct:
-	.word IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
+	.word OMAP2_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
 
 ENTRY(omap243x_sram_reprogram_sdrc_sz)
 	.word	. - omap243x_sram_reprogram_sdrc
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 97eeeeb..e2338c0 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -231,7 +231,7 @@ static void __init omap2_gp_clocksource_init(void)
 static void __init omap2_gp_timer_init(void)
 {
 #ifdef CONFIG_LOCAL_TIMERS
-	twd_base = IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE);
+	twd_base = OMAP2_IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE);
 #endif
 	omap_dm_timer_init();
 
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 739e59e..1145a25 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -31,15 +31,6 @@
 #include <mach/mux.h>
 #include <mach/usb.h>
 
-#define OTG_SYSCONFIG	(OMAP34XX_HSUSB_OTG_BASE + 0x404)
-
-static void __init usb_musb_pm_init(void)
-{
-	/* Ensure force-idle mode for OTG controller */
-	if (cpu_is_omap34xx())
-		omap_writel(0, OTG_SYSCONFIG);
-}
-
 #ifdef CONFIG_USB_MUSB_SOC
 
 static struct resource musb_resources[] = {
@@ -173,13 +164,10 @@ void __init usb_musb_init(void)
 		printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n");
 		return;
 	}
-
-	usb_musb_pm_init();
 }
 
 #else
 void __init usb_musb_init(void)
 {
-	usb_musb_pm_init();
 }
 #endif /* CONFIG_USB_MUSB_SOC */
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 2c7035d..c3d513c 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -89,6 +89,27 @@ config MACH_EDMINI_V2
 	  Say 'Y' here if you want your kernel to support the
 	  LaCie Ethernet Disk mini V2.
 
+config MACH_D2NET
+	bool "LaCie d2 Network"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie d2 Network NAS.
+
+config MACH_BIGDISK
+	bool "LaCie Big Disk Network"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie Big Disk Network NAS.
+
+config MACH_NET2BIG
+	bool "LaCie 2Big Network"
+	select I2C_BOARDINFO
+	help
+	  Say 'Y' here if you want your kernel to support the
+	  LaCie 2Big Network NAS.
+
 config MACH_MSS2
 	bool "Maxtor Shared Storage II"
 	help
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index edc38e2..89772fc 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -12,6 +12,9 @@ obj-$(CONFIG_MACH_WRT350N_V2)	+= wrt350n-v2-setup.o
 obj-$(CONFIG_MACH_TS78XX)	+= ts78xx-setup.o
 obj-$(CONFIG_MACH_MV2120)	+= mv2120-setup.o
 obj-$(CONFIG_MACH_EDMINI_V2)	+= edmini_v2-setup.o
+obj-$(CONFIG_MACH_D2NET)	+= d2net-setup.o
+obj-$(CONFIG_MACH_BIGDISK)	+= d2net-setup.o
+obj-$(CONFIG_MACH_NET2BIG)	+= net2big-setup.o
 obj-$(CONFIG_MACH_MSS2)		+= mss2-setup.o
 obj-$(CONFIG_MACH_WNR854T)	+= wnr854t-setup.o
 obj-$(CONFIG_MACH_RD88F5181L_GE)	+= rd88f5181l-ge-setup.o
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index d78731e..1a5d6a0 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -84,7 +84,8 @@ static int __init orion5x_cpu_win_can_remap(int win)
 	orion5x_pcie_id(&dev, &rev);
 	if ((dev == MV88F5281_DEV_ID && win < 4)
 	    || (dev == MV88F5182_DEV_ID && win < 2)
-	    || (dev == MV88F5181_DEV_ID && win < 2))
+	    || (dev == MV88F5181_DEV_ID && win < 2)
+	    || (dev == MV88F6183_DEV_ID && win < 4))
 		return 1;
 
 	return 0;
diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c
new file mode 100644
index 0000000..9d4bf76
--- /dev/null
+++ b/arch/arm/mach-orion5x/d2net-setup.c
@@ -0,0 +1,365 @@
+/*
+ * arch/arm/mach-orion5x/d2net-setup.c
+ *
+ * LaCie d2Network and Big Disk Network NAS setup
+ *
+ * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * LaCie d2 Network Info
+ ****************************************************************************/
+
+/*
+ * 512KB NOR flash Device bus boot chip select
+ */
+
+#define D2NET_NOR_BOOT_BASE		0xfff80000
+#define D2NET_NOR_BOOT_SIZE		SZ_512K
+
+/*****************************************************************************
+ * 512KB NOR Flash on Boot Device
+ ****************************************************************************/
+
+/*
+ * TODO: Check write support on flash MX29LV400CBTC-70G
+ */
+
+static struct mtd_partition d2net_partitions[] = {
+	{
+		.name		= "Full512kb",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= 0,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+};
+
+static struct physmap_flash_data d2net_nor_flash_data = {
+	.width		= 1,
+	.parts		= d2net_partitions,
+	.nr_parts	= ARRAY_SIZE(d2net_partitions),
+};
+
+static struct resource d2net_nor_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+	.start			= D2NET_NOR_BOOT_BASE,
+	.end			= D2NET_NOR_BOOT_BASE
+					+ D2NET_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device d2net_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &d2net_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &d2net_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data d2net_eth_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+/*
+ * i2c addr | chip         | description
+ * 0x32     | Ricoh 5C372b | RTC
+ * 0x3e     | GMT G762     | PWM fan controller
+ * 0x50     | HT24LC08     | eeprom (1kB)
+ *
+ * TODO: Add G762 support to the g760a driver.
+ */
+static struct i2c_board_info __initdata d2net_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("rs5c372b", 0x32),
+	}, {
+		I2C_BOARD_INFO("24c08", 0x50),
+	},
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data d2net_sata_data = {
+	.n_ports	= 2,
+};
+
+#define D2NET_GPIO_SATA0_POWER	3
+#define D2NET_GPIO_SATA1_POWER	12
+
+static void __init d2net_sata_power_init(void)
+{
+	int err;
+
+	err = gpio_request(D2NET_GPIO_SATA0_POWER, "SATA0 power");
+	if (err == 0) {
+		err = gpio_direction_output(D2NET_GPIO_SATA0_POWER, 1);
+		if (err)
+			gpio_free(D2NET_GPIO_SATA0_POWER);
+	}
+	if (err)
+		pr_err("d2net: failed to configure SATA0 power GPIO\n");
+
+	err = gpio_request(D2NET_GPIO_SATA1_POWER, "SATA1 power");
+	if (err == 0) {
+		err = gpio_direction_output(D2NET_GPIO_SATA1_POWER, 1);
+		if (err)
+			gpio_free(D2NET_GPIO_SATA1_POWER);
+	}
+	if (err)
+		pr_err("d2net: failed to configure SATA1 power GPIO\n");
+}
+
+/*****************************************************************************
+ * GPIO LED's
+ ****************************************************************************/
+
+/*
+ * The blue front LED is wired to the CPLD and can blink in relation with the
+ * SATA activity. This feature is disabled to make this LED compatible with
+ * the leds-gpio driver: MPP14 and MPP15 are configured to act like output
+ * GPIO's and have to stay in an active state. This is needed to set the blue
+ * LED in a "fix on" state regardless of the SATA activity.
+ *
+ * The following array detail the different LED registers and the combination
+ * of their possible values:
+ *
+ * led_off   | blink_ctrl | SATA active | LED state
+ *           |            |             |
+ *    1      |     x      |      x      |  off
+ *    0      |     0      |      0      |  off
+ *    0      |     1      |      0      |  blink (rate 300ms)
+ *    0      |     x      |      1      |  on
+ *
+ * Notes: The blue and the red front LED's can't be on at the same time.
+ *        Red LED have priority.
+ */
+
+#define D2NET_GPIO_RED_LED		6
+#define D2NET_GPIO_BLUE_LED_BLINK_CTRL	16
+#define D2NET_GPIO_BLUE_LED_OFF		23
+#define D2NET_GPIO_SATA0_ACT		14
+#define D2NET_GPIO_SATA1_ACT		15
+
+static struct gpio_led d2net_leds[] = {
+	{
+		.name = "d2net:blue:power",
+		.gpio = D2NET_GPIO_BLUE_LED_OFF,
+		.active_low = 1,
+	},
+	{
+		.name = "d2net:red:fail",
+		.gpio = D2NET_GPIO_RED_LED,
+	},
+};
+
+static struct gpio_led_platform_data d2net_led_data = {
+	.num_leds = ARRAY_SIZE(d2net_leds),
+	.leds = d2net_leds,
+};
+
+static struct platform_device d2net_gpio_leds = {
+	.name           = "leds-gpio",
+	.id             = -1,
+	.dev            = {
+		.platform_data  = &d2net_led_data,
+	},
+};
+
+static void __init d2net_gpio_leds_init(void)
+{
+	/* Configure GPIO over MPP max number. */
+	orion_gpio_set_valid(D2NET_GPIO_BLUE_LED_OFF, 1);
+
+	if (gpio_request(D2NET_GPIO_SATA0_ACT, "LED SATA0 activity") != 0)
+		return;
+	if (gpio_direction_output(D2NET_GPIO_SATA0_ACT, 1) != 0)
+		goto err_free_1;
+	if (gpio_request(D2NET_GPIO_SATA1_ACT, "LED SATA1 activity") != 0)
+		goto err_free_1;
+	if (gpio_direction_output(D2NET_GPIO_SATA1_ACT, 1) != 0)
+		goto err_free_2;
+	platform_device_register(&d2net_gpio_leds);
+	return;
+
+err_free_2:
+	gpio_free(D2NET_GPIO_SATA1_ACT);
+err_free_1:
+	gpio_free(D2NET_GPIO_SATA0_ACT);
+	return;
+}
+
+/****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define D2NET_GPIO_PUSH_BUTTON		18
+#define D2NET_GPIO_POWER_SWITCH_ON	8
+#define D2NET_GPIO_POWER_SWITCH_OFF	9
+
+#define D2NET_SWITCH_POWER_ON		0x1
+#define D2NET_SWITCH_POWER_OFF		0x2
+
+static struct gpio_keys_button d2net_buttons[] = {
+	{
+		.type		= EV_SW,
+		.code		= D2NET_SWITCH_POWER_OFF,
+		.gpio		= D2NET_GPIO_POWER_SWITCH_OFF,
+		.desc		= "Power rocker switch (auto|off)",
+		.active_low	= 0,
+	},
+	{
+		.type		= EV_SW,
+		.code		= D2NET_SWITCH_POWER_ON,
+		.gpio		= D2NET_GPIO_POWER_SWITCH_ON,
+		.desc		= "Power rocker switch (on|auto)",
+		.active_low	= 0,
+	},
+	{
+		.type		= EV_KEY,
+		.code		= KEY_POWER,
+		.gpio		= D2NET_GPIO_PUSH_BUTTON,
+		.desc		= "Front Push Button",
+		.active_low	= 0,
+	},
+};
+
+static struct gpio_keys_platform_data d2net_button_data = {
+	.buttons	= d2net_buttons,
+	.nbuttons	= ARRAY_SIZE(d2net_buttons),
+};
+
+static struct platform_device d2net_gpio_buttons = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &d2net_button_data,
+	},
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct orion5x_mpp_mode d2net_mpp_modes[] __initdata = {
+	{  0, MPP_GPIO },	/* Board ID (bit 0) */
+	{  1, MPP_GPIO },	/* Board ID (bit 1) */
+	{  2, MPP_GPIO },	/* Board ID (bit 2) */
+	{  3, MPP_GPIO },	/* SATA 0 power */
+	{  4, MPP_UNUSED },
+	{  5, MPP_GPIO },	/* Fan fail detection */
+	{  6, MPP_GPIO },	/* Red front LED */
+	{  7, MPP_UNUSED },
+	{  8, MPP_GPIO },	/* Rear power switch (on|auto) */
+	{  9, MPP_GPIO },	/* Rear power switch (auto|off) */
+	{ 10, MPP_UNUSED },
+	{ 11, MPP_UNUSED },
+	{ 12, MPP_GPIO },	/* SATA 1 power */
+	{ 13, MPP_UNUSED },
+	{ 14, MPP_GPIO },	/* SATA 0 active */
+	{ 15, MPP_GPIO },	/* SATA 1 active */
+	{ 16, MPP_GPIO },	/* Blue front LED blink control */
+	{ 17, MPP_UNUSED },
+	{ 18, MPP_GPIO },	/* Front button (0 = Released, 1 = Pushed ) */
+	{ 19, MPP_UNUSED },
+	{ -1 }
+	/* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
+	/* 23: Blue front LED off */
+	/* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */
+};
+
+static void __init d2net_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion5x_init();
+
+	orion5x_mpp_conf(d2net_mpp_modes);
+
+	/*
+	 * Configure peripherals.
+	 */
+	orion5x_ehci0_init();
+	orion5x_eth_init(&d2net_eth_data);
+	orion5x_i2c_init();
+	orion5x_uart0_init();
+
+	d2net_sata_power_init();
+	orion5x_sata_init(&d2net_sata_data);
+
+	orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE,
+				D2NET_NOR_BOOT_SIZE);
+	platform_device_register(&d2net_nor_flash);
+
+	platform_device_register(&d2net_gpio_buttons);
+
+	d2net_gpio_leds_init();
+
+	pr_notice("d2net: Flash write are not yet supported.\n");
+
+	i2c_register_board_info(0, d2net_i2c_devices,
+				ARRAY_SIZE(d2net_i2c_devices));
+}
+
+/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
+
+#ifdef CONFIG_MACH_D2NET
+MACHINE_START(D2NET, "LaCie d2 Network")
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= d2net_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_BIGDISK
+MACHINE_START(BIGDISK, "LaCie Big Disk Network")
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= d2net_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
new file mode 100644
index 0000000..7bd6283
--- /dev/null
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -0,0 +1,431 @@
+/*
+ * arch/arm/mach-orion5x/net2big-setup.c
+ *
+ * LaCie 2Big Network NAS setup
+ *
+ * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * LaCie 2Big Network Info
+ ****************************************************************************/
+
+/*
+ * 512KB NOR flash Device bus boot chip select
+ */
+
+#define NET2BIG_NOR_BOOT_BASE		0xfff80000
+#define NET2BIG_NOR_BOOT_SIZE		SZ_512K
+
+/*****************************************************************************
+ * 512KB NOR Flash on Boot Device
+ ****************************************************************************/
+
+/*
+ * TODO: Check write support on flash MX29LV400CBTC-70G
+ */
+
+static struct mtd_partition net2big_partitions[] = {
+	{
+		.name		= "Full512kb",
+		.size		= MTDPART_SIZ_FULL,
+		.offset		= 0x00000000,
+		.mask_flags	= MTD_WRITEABLE,
+	},
+};
+
+static struct physmap_flash_data net2big_nor_flash_data = {
+	.width		= 1,
+	.parts		= net2big_partitions,
+	.nr_parts	= ARRAY_SIZE(net2big_partitions),
+};
+
+static struct resource net2big_nor_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+	.start			= NET2BIG_NOR_BOOT_BASE,
+	.end			= NET2BIG_NOR_BOOT_BASE
+					+ NET2BIG_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device net2big_nor_flash = {
+	.name			= "physmap-flash",
+	.id			= 0,
+	.dev		= {
+		.platform_data	= &net2big_nor_flash_data,
+	},
+	.num_resources		= 1,
+	.resource		= &net2big_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data net2big_eth_data = {
+	.phy_addr	= MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+/*
+ * i2c addr | chip         | description
+ * 0x32     | Ricoh 5C372b | RTC
+ * 0x50     | HT24LC08     | eeprom (1kB)
+ */
+static struct i2c_board_info __initdata net2big_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("rs5c372b", 0x32),
+	}, {
+		I2C_BOARD_INFO("24c08", 0x50),
+	},
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data net2big_sata_data = {
+	.n_ports	= 2,
+};
+
+#define NET2BIG_GPIO_SATA_POWER_REQ	19
+#define NET2BIG_GPIO_SATA0_POWER	23
+#define NET2BIG_GPIO_SATA1_POWER	25
+
+static void __init net2big_sata_power_init(void)
+{
+	int err;
+
+	/* Configure GPIOs over MPP max number. */
+	orion_gpio_set_valid(NET2BIG_GPIO_SATA0_POWER, 1);
+	orion_gpio_set_valid(NET2BIG_GPIO_SATA1_POWER, 1);
+
+	err = gpio_request(NET2BIG_GPIO_SATA0_POWER, "SATA0 power status");
+	if (err == 0) {
+		err = gpio_direction_input(NET2BIG_GPIO_SATA0_POWER);
+		if (err)
+			gpio_free(NET2BIG_GPIO_SATA0_POWER);
+	}
+	if (err) {
+		pr_err("net2big: failed to setup SATA0 power GPIO\n");
+		return;
+	}
+
+	err = gpio_request(NET2BIG_GPIO_SATA1_POWER, "SATA1 power status");
+	if (err == 0) {
+		err = gpio_direction_input(NET2BIG_GPIO_SATA1_POWER);
+		if (err)
+			gpio_free(NET2BIG_GPIO_SATA1_POWER);
+	}
+	if (err) {
+		pr_err("net2big: failed to setup SATA1 power GPIO\n");
+		goto err_free_1;
+	}
+
+	err = gpio_request(NET2BIG_GPIO_SATA_POWER_REQ, "SATA power request");
+	if (err == 0) {
+		err = gpio_direction_output(NET2BIG_GPIO_SATA_POWER_REQ, 0);
+		if (err)
+			gpio_free(NET2BIG_GPIO_SATA_POWER_REQ);
+	}
+	if (err) {
+		pr_err("net2big: failed to setup SATA power request GPIO\n");
+		goto err_free_2;
+	}
+
+	if (gpio_get_value(NET2BIG_GPIO_SATA0_POWER) &&
+		gpio_get_value(NET2BIG_GPIO_SATA1_POWER)) {
+		return;
+	}
+
+	/*
+	 * SATA power up on both disk is done by pulling high the CPLD power
+	 * request line. The 300ms delay is related to the CPLD clock and is
+	 * needed to be sure that the CPLD has take into account the low line
+	 * status.
+	 */
+	msleep(300);
+	gpio_set_value(NET2BIG_GPIO_SATA_POWER_REQ, 1);
+	pr_info("net2big: power up SATA hard disks\n");
+
+	return;
+
+err_free_2:
+	gpio_free(NET2BIG_GPIO_SATA1_POWER);
+err_free_1:
+	gpio_free(NET2BIG_GPIO_SATA0_POWER);
+
+	return;
+}
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+/*
+ * The power front LEDs (blue and red) and SATA red LEDs are controlled via a
+ * single GPIO line and are compatible with the leds-gpio driver.
+ *
+ * The SATA blue LEDs have some hardware blink capabilities which are detailled
+ * in the following array:
+ *
+ * SATAx blue LED | SATAx activity | LED state
+ *                |                |
+ *       0        |       0        |  blink (rate 300ms)
+ *       1        |       0        |  off
+ *       ?        |       1        |  on
+ *
+ * Notes: The blue and the red front LED's can't be on at the same time.
+ *        Blue LED have priority.
+ */
+
+#define NET2BIG_GPIO_PWR_RED_LED	6
+#define NET2BIG_GPIO_PWR_BLUE_LED	16
+#define NET2BIG_GPIO_PWR_LED_BLINK_STOP	7
+
+#define NET2BIG_GPIO_SATA0_RED_LED	11
+#define NET2BIG_GPIO_SATA1_RED_LED	10
+
+#define NET2BIG_GPIO_SATA0_BLUE_LED	17
+#define NET2BIG_GPIO_SATA1_BLUE_LED	13
+
+static struct gpio_led net2big_leds[] = {
+	{
+		.name = "net2big:red:power",
+		.gpio = NET2BIG_GPIO_PWR_RED_LED,
+	},
+	{
+		.name = "net2big:blue:power",
+		.gpio = NET2BIG_GPIO_PWR_BLUE_LED,
+	},
+	{
+		.name = "net2big:red:sata0",
+		.gpio = NET2BIG_GPIO_SATA0_RED_LED,
+	},
+	{
+		.name = "net2big:red:sata1",
+		.gpio = NET2BIG_GPIO_SATA1_RED_LED,
+	},
+};
+
+static struct gpio_led_platform_data net2big_led_data = {
+	.num_leds = ARRAY_SIZE(net2big_leds),
+	.leds = net2big_leds,
+};
+
+static struct platform_device net2big_gpio_leds = {
+	.name           = "leds-gpio",
+	.id             = -1,
+	.dev            = {
+		.platform_data  = &net2big_led_data,
+	},
+};
+
+static void __init net2big_gpio_leds_init(void)
+{
+	int err;
+
+	/* Stop initial CPLD slow red/blue blinking on power LED. */
+	err = gpio_request(NET2BIG_GPIO_PWR_LED_BLINK_STOP,
+			   "Power LED blink stop");
+	if (err == 0) {
+		err = gpio_direction_output(NET2BIG_GPIO_PWR_LED_BLINK_STOP, 1);
+		if (err)
+			gpio_free(NET2BIG_GPIO_PWR_LED_BLINK_STOP);
+	}
+	if (err)
+		pr_err("net2big: failed to setup power LED blink GPIO\n");
+
+	/*
+	 * Configure SATA0 and SATA1 blue LEDs to blink in relation with the
+	 * hard disk activity.
+	 */
+	err = gpio_request(NET2BIG_GPIO_SATA0_BLUE_LED,
+			   "SATA0 blue LED control");
+	if (err == 0) {
+		err = gpio_direction_output(NET2BIG_GPIO_SATA0_BLUE_LED, 1);
+		if (err)
+			gpio_free(NET2BIG_GPIO_SATA0_BLUE_LED);
+	}
+	if (err)
+		pr_err("net2big: failed to setup SATA0 blue LED GPIO\n");
+
+	err = gpio_request(NET2BIG_GPIO_SATA1_BLUE_LED,
+			   "SATA1 blue LED control");
+	if (err == 0) {
+		err = gpio_direction_output(NET2BIG_GPIO_SATA1_BLUE_LED, 1);
+		if (err)
+			gpio_free(NET2BIG_GPIO_SATA1_BLUE_LED);
+	}
+	if (err)
+		pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
+
+	platform_device_register(&net2big_gpio_leds);
+}
+
+/****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define NET2BIG_GPIO_PUSH_BUTTON	18
+#define NET2BIG_GPIO_POWER_SWITCH_ON	8
+#define NET2BIG_GPIO_POWER_SWITCH_OFF	9
+
+#define NET2BIG_SWITCH_POWER_ON		0x1
+#define NET2BIG_SWITCH_POWER_OFF	0x2
+
+static struct gpio_keys_button net2big_buttons[] = {
+	{
+		.type		= EV_SW,
+		.code		= NET2BIG_SWITCH_POWER_OFF,
+		.gpio		= NET2BIG_GPIO_POWER_SWITCH_OFF,
+		.desc		= "Power rocker switch (auto|off)",
+		.active_low	= 0,
+	},
+	{
+		.type		= EV_SW,
+		.code		= NET2BIG_SWITCH_POWER_ON,
+		.gpio		= NET2BIG_GPIO_POWER_SWITCH_ON,
+		.desc		= "Power rocker switch (on|auto)",
+		.active_low	= 0,
+	},
+	{
+		.type		= EV_KEY,
+		.code		= KEY_POWER,
+		.gpio		= NET2BIG_GPIO_PUSH_BUTTON,
+		.desc		= "Front Push Button",
+		.active_low	= 0,
+	},
+};
+
+static struct gpio_keys_platform_data net2big_button_data = {
+	.buttons	= net2big_buttons,
+	.nbuttons	= ARRAY_SIZE(net2big_buttons),
+};
+
+static struct platform_device net2big_gpio_buttons = {
+	.name		= "gpio-keys",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &net2big_button_data,
+	},
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static struct orion5x_mpp_mode net2big_mpp_modes[] __initdata = {
+	{  0, MPP_GPIO },	/* Raid mode (bit 0) */
+	{  1, MPP_GPIO },	/* USB port 2 fuse (0 = Fail, 1 = Ok) */
+	{  2, MPP_GPIO },	/* Raid mode (bit 1) */
+	{  3, MPP_GPIO },	/* Board ID (bit 0) */
+	{  4, MPP_GPIO },	/* Fan activity (0 = Off, 1 = On) */
+	{  5, MPP_GPIO },	/* Fan fail detection */
+	{  6, MPP_GPIO },	/* Red front LED (0 = Off, 1 = On) */
+	{  7, MPP_GPIO },	/* Disable initial blinking on front LED */
+	{  8, MPP_GPIO },	/* Rear power switch (on|auto) */
+	{  9, MPP_GPIO },	/* Rear power switch (auto|off) */
+	{ 10, MPP_GPIO },	/* SATA 1 red LED (0 = Off, 1 = On) */
+	{ 11, MPP_GPIO },	/* SATA 0 red LED (0 = Off, 1 = On) */
+	{ 12, MPP_GPIO },	/* Board ID (bit 1) */
+	{ 13, MPP_GPIO },	/* SATA 1 blue LED blink control */
+	{ 14, MPP_SATA_LED },
+	{ 15, MPP_SATA_LED },
+	{ 16, MPP_GPIO },	/* Blue front LED control */
+	{ 17, MPP_GPIO },	/* SATA 0 blue LED blink control */
+	{ 18, MPP_GPIO },	/* Front button (0 = Released, 1 = Pushed ) */
+	{ 19, MPP_GPIO },	/* SATA{0,1} power On/Off request */
+	{ -1 }
+	/* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
+	/* 23: SATA 0 power status */
+	/* 24: Board power off */
+	/* 25: SATA 1 power status */
+};
+
+#define NET2BIG_GPIO_POWER_OFF		24
+
+static void net2big_power_off(void)
+{
+	gpio_set_value(NET2BIG_GPIO_POWER_OFF, 1);
+}
+
+static void __init net2big_init(void)
+{
+	/*
+	 * Setup basic Orion functions. Need to be called early.
+	 */
+	orion5x_init();
+
+	orion5x_mpp_conf(net2big_mpp_modes);
+
+	/*
+	 * Configure peripherals.
+	 */
+	orion5x_ehci0_init();
+	orion5x_ehci1_init();
+	orion5x_eth_init(&net2big_eth_data);
+	orion5x_i2c_init();
+	orion5x_uart0_init();
+	orion5x_xor_init();
+
+	net2big_sata_power_init();
+	orion5x_sata_init(&net2big_sata_data);
+
+	orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE,
+				   NET2BIG_NOR_BOOT_SIZE);
+	platform_device_register(&net2big_nor_flash);
+
+	platform_device_register(&net2big_gpio_buttons);
+	net2big_gpio_leds_init();
+
+	i2c_register_board_info(0, net2big_i2c_devices,
+				ARRAY_SIZE(net2big_i2c_devices));
+
+	orion_gpio_set_valid(NET2BIG_GPIO_POWER_OFF, 1);
+
+	if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 &&
+	    gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0)
+		pm_power_off = net2big_power_off;
+	else
+		pr_err("net2big: failed to configure power-off GPIO\n");
+
+	pr_notice("net2big: Flash writing is not yet supported.\n");
+}
+
+/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
+MACHINE_START(NET2BIG, "LaCie 2Big Network")
+	.phys_io	= ORION5X_REGS_PHYS_BASE,
+	.io_pg_offst	= ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.init_machine	= net2big_init,
+	.map_io		= orion5x_map_io,
+	.init_irq	= orion5x_init_irq,
+	.timer		= &orion5x_timer,
+	.fixup		= tag_fixup_mem32,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h b/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
index d5a48a9..7b4eadc 100644
--- a/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
+++ b/arch/arm/mach-pxa/include/mach/pxa27x_keypad.h
@@ -2,9 +2,12 @@
 #define __ASM_ARCH_PXA27x_KEYPAD_H
 
 #include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
 
 #define MAX_MATRIX_KEY_ROWS	(8)
 #define MAX_MATRIX_KEY_COLS	(8)
+#define MATRIX_ROW_SHIFT	(3)
+#define MAX_DIRECT_KEY_NUM	(8)
 
 /* pxa3xx keypad platform specific parameters
  *
@@ -33,7 +36,7 @@ struct pxa27x_keypad_platform_data {
 
 	/* direct keys */
 	int		direct_key_num;
-	unsigned int	direct_key_map[8];
+	unsigned int	direct_key_map[MAX_DIRECT_KEY_NUM];
 
 	/* rotary encoders 0 */
 	int		enable_rotary0;
@@ -51,8 +54,6 @@ struct pxa27x_keypad_platform_data {
 	unsigned int	debounce_interval;
 };
 
-#define KEY(row, col, val)	(((row) << 28) | ((col) << 24) | (val))
-
 extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
 
 #endif /* __ASM_ARCH_PXA27x_KEYPAD_H */
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 2546c06..629e05d 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -678,8 +678,8 @@ static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enab
 		dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
 	}
 
-	if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) )
-	{
+	if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) ||
+	    (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)))	{
 		dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
 		corgi_goto_sleep(alarm_time, alarm_enable, state);
 		return 1;
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index d4cfa21..dfc9b0b 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -75,7 +75,7 @@ config MACH_REALVIEW_PBX
 
 config REALVIEW_HIGH_PHYS_OFFSET
 	bool "High physical base address for the RealView platform"
-	depends on !MACH_REALVIEW_PB1176
+	depends on MMU && !MACH_REALVIEW_PB1176
 	default y
 	help
 	  RealView boards other than PB1176 have the RAM available at
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index facbd49..dc3519c 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -221,6 +221,9 @@ arch_initcall(realview_i2c_init);
 
 #define REALVIEW_SYSMCI	(__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
 
+/*
+ * This is only used if GPIOLIB support is disabled
+ */
 static unsigned int realview_mmc_status(struct device *dev)
 {
 	struct amba_device *adev = container_of(dev, struct amba_device, dev);
@@ -237,11 +240,15 @@ static unsigned int realview_mmc_status(struct device *dev)
 struct mmc_platform_data realview_mmc0_plat_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.status		= realview_mmc_status,
+	.gpio_wp	= 17,
+	.gpio_cd	= 16,
 };
 
 struct mmc_platform_data realview_mmc1_plat_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.status		= realview_mmc_status,
+	.gpio_wp	= 19,
+	.gpio_cd	= 18,
 };
 
 /*
diff --git a/arch/arm/mach-realview/include/mach/gpio.h b/arch/arm/mach-realview/include/mach/gpio.h
new file mode 100644
index 0000000..94ff276
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h
index b42c14f..8a638d1 100644
--- a/arch/arm/mach-realview/include/mach/hardware.h
+++ b/arch/arm/mach-realview/include/mach/hardware.h
@@ -25,6 +25,7 @@
 #include <asm/sizes.h>
 
 /* macro to get at IO space when running virtually */
+#ifdef CONFIG_MMU
 /*
  * Statically mapped addresses:
  *
@@ -33,6 +34,9 @@
  * 1fxx xxxx -> fexx xxxx
  */
 #define IO_ADDRESS(x)		(((x) & 0x03ffffff) + 0xfb000000)
+#else
+#define IO_ADDRESS(x)		(x)
+#endif
 #define __io_address(n)		__io(IO_ADDRESS(n))
 
 #endif
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index ac0e83f..a88458b 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -20,6 +20,7 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/localtimer.h>
+#include <asm/unified.h>
 
 #include <mach/board-eb.h>
 #include <mach/board-pb11mp.h>
@@ -137,26 +138,19 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static void __init poke_milo(void)
 {
-	extern void secondary_startup(void);
-
 	/* nobody is to be released from the pen yet */
 	pen_release = -1;
 
 	/*
-	 * write the address of secondary startup into the system-wide
-	 * flags register, then clear the bottom two bits, which is what
-	 * BootMonitor is waiting for
+	 * Write the address of secondary startup into the system-wide flags
+	 * register. The BootMonitor waits for this register to become
+	 * non-zero.
 	 */
-#if 1
 #define REALVIEW_SYS_FLAGSS_OFFSET 0x30
-	__raw_writel(virt_to_phys(realview_secondary_startup),
-		     __io_address(REALVIEW_SYS_BASE) +
-		     REALVIEW_SYS_FLAGSS_OFFSET);
 #define REALVIEW_SYS_FLAGSC_OFFSET 0x34
-	__raw_writel(3,
+	__raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
 		     __io_address(REALVIEW_SYS_BASE) +
-		     REALVIEW_SYS_FLAGSC_OFFSET);
-#endif
+		     REALVIEW_SYS_FLAGSS_OFFSET);
 
 	mb();
 }
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 8dfa44e..abd13b4 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -113,6 +114,21 @@ static void __init realview_eb_map_io(void)
 		iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc));
 }
 
+static struct pl061_platform_data gpio0_plat_data = {
+	.gpio_base	= 0,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+	.gpio_base	= 8,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+	.gpio_base	= 16,
+	.irq_base	= -1,
+};
+
 /*
  * RealView EB AMBA devices
  */
@@ -189,9 +205,9 @@ AMBA_DEVICE(clcd,  "dev:20",  EB_CLCD,  &clcd_plat_data);
 AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
 AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
 AMBA_DEVICE(wdog,  "dev:e1",  EB_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:e4",  EB_GPIO0, NULL);
-AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    NULL);
-AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    NULL);
+AMBA_DEVICE(gpio0, "dev:e4",  EB_GPIO0, &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data);
+AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    &gpio2_plat_data);
 AMBA_DEVICE(rtc,   "dev:e8",  EB_RTC,   NULL);
 AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
 AMBA_DEVICE(uart0, "dev:f1",  EB_UART0, NULL);
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 25efe71..17fbb0e 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -107,6 +108,21 @@ static void __init realview_pb1176_map_io(void)
 	iotable_init(realview_pb1176_io_desc, ARRAY_SIZE(realview_pb1176_io_desc));
 }
 
+static struct pl061_platform_data gpio0_plat_data = {
+	.gpio_base	= 0,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+	.gpio_base	= 8,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+	.gpio_base	= 16,
+	.irq_base	= -1,
+};
+
 /*
  * RealView PB1176 AMBA devices
  */
@@ -164,9 +180,9 @@ AMBA_DEVICE(uart3,	"fpga:09",	PB1176_UART3,	NULL);
 AMBA_DEVICE(smc,	"dev:00",	PB1176_SMC,	NULL);
 AMBA_DEVICE(sctl,	"dev:e0",	SCTL,		NULL);
 AMBA_DEVICE(wdog,	"dev:e1",	PB1176_WATCHDOG,	NULL);
-AMBA_DEVICE(gpio0,	"dev:e4",	PB1176_GPIO0,	NULL);
-AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		NULL);
-AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		NULL);
+AMBA_DEVICE(gpio0,	"dev:e4",	PB1176_GPIO0,	&gpio0_plat_data);
+AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		&gpio1_plat_data);
+AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		&gpio2_plat_data);
 AMBA_DEVICE(rtc,	"dev:e8",	PB1176_RTC,	NULL);
 AMBA_DEVICE(sci0,	"dev:f0",	SCI,		NULL);
 AMBA_DEVICE(uart0,	"dev:f1",	PB1176_UART0,	NULL);
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index dc4b169..fdd042b 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -108,6 +109,21 @@ static void __init realview_pb11mp_map_io(void)
 	iotable_init(realview_pb11mp_io_desc, ARRAY_SIZE(realview_pb11mp_io_desc));
 }
 
+static struct pl061_platform_data gpio0_plat_data = {
+	.gpio_base	= 0,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+	.gpio_base	= 8,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+	.gpio_base	= 16,
+	.irq_base	= -1,
+};
+
 /*
  * RealView PB11MPCore AMBA devices
  */
@@ -166,9 +182,9 @@ AMBA_DEVICE(uart3,	"fpga:09",	PB11MP_UART3,	NULL);
 AMBA_DEVICE(smc,	"dev:00",	PB11MP_SMC,	NULL);
 AMBA_DEVICE(sctl,	"dev:e0",	SCTL,		NULL);
 AMBA_DEVICE(wdog,	"dev:e1",	PB11MP_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0,	"dev:e4",	PB11MP_GPIO0,	NULL);
-AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		NULL);
-AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		NULL);
+AMBA_DEVICE(gpio0,	"dev:e4",	PB11MP_GPIO0,	&gpio0_plat_data);
+AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		&gpio1_plat_data);
+AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		&gpio2_plat_data);
 AMBA_DEVICE(rtc,	"dev:e8",	PB11MP_RTC,	NULL);
 AMBA_DEVICE(sci0,	"dev:f0",	SCI,		NULL);
 AMBA_DEVICE(uart0,	"dev:f1",	PB11MP_UART0,	NULL);
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index d6ac1eb..70bba99 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -23,6 +23,7 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
 #include <linux/io.h>
 
 #include <asm/irq.h>
@@ -98,6 +99,21 @@ static void __init realview_pba8_map_io(void)
 	iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc));
 }
 
+static struct pl061_platform_data gpio0_plat_data = {
+	.gpio_base	= 0,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+	.gpio_base	= 8,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+	.gpio_base	= 16,
+	.irq_base	= -1,
+};
+
 /*
  * RealView PBA8Core AMBA devices
  */
@@ -156,9 +172,9 @@ AMBA_DEVICE(uart3,	"fpga:09",	PBA8_UART3,	NULL);
 AMBA_DEVICE(smc,	"dev:00",	PBA8_SMC,	NULL);
 AMBA_DEVICE(sctl,	"dev:e0",	SCTL,		NULL);
 AMBA_DEVICE(wdog,	"dev:e1",	PBA8_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0,	"dev:e4",	PBA8_GPIO0,	NULL);
-AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		NULL);
-AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		NULL);
+AMBA_DEVICE(gpio0,	"dev:e4",	PBA8_GPIO0,	&gpio0_plat_data);
+AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		&gpio1_plat_data);
+AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		&gpio2_plat_data);
 AMBA_DEVICE(rtc,	"dev:e8",	PBA8_RTC,	NULL);
 AMBA_DEVICE(sci0,	"dev:f0",	SCI,		NULL);
 AMBA_DEVICE(uart0,	"dev:f1",	PBA8_UART0,	NULL);
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index ede2a57..ce6c5d2 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
 #include <linux/io.h>
 
 #include <asm/irq.h>
@@ -118,6 +119,21 @@ static void __init realview_pbx_map_io(void)
 		iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc));
 }
 
+static struct pl061_platform_data gpio0_plat_data = {
+	.gpio_base	= 0,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+	.gpio_base	= 8,
+	.irq_base	= -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+	.gpio_base	= 16,
+	.irq_base	= -1,
+};
+
 /*
  * RealView PBXCore AMBA devices
  */
@@ -176,9 +192,9 @@ AMBA_DEVICE(uart3,	"fpga:09",	PBX_UART3,	NULL);
 AMBA_DEVICE(smc,	"dev:00",	PBX_SMC,	NULL);
 AMBA_DEVICE(sctl,	"dev:e0",	SCTL,		NULL);
 AMBA_DEVICE(wdog,	"dev:e1",	PBX_WATCHDOG, 	NULL);
-AMBA_DEVICE(gpio0,	"dev:e4",	PBX_GPIO0,	NULL);
-AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		NULL);
-AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		NULL);
+AMBA_DEVICE(gpio0,	"dev:e4",	PBX_GPIO0,	&gpio0_plat_data);
+AMBA_DEVICE(gpio1,	"dev:e5",	GPIO1,		&gpio1_plat_data);
+AMBA_DEVICE(gpio2,	"dev:e6",	GPIO2,		&gpio2_plat_data);
 AMBA_DEVICE(rtc,	"dev:e8",	PBX_RTC,	NULL);
 AMBA_DEVICE(sci0,	"dev:f0",	SCI,		NULL);
 AMBA_DEVICE(uart0,	"dev:f1",	PBX_UART0,	NULL);
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 41bb65d..d8c023d 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -12,6 +12,7 @@ config CPU_S3C2410
 	select S3C2410_GPIO
 	select CPU_LLSERIAL_S3C2410
 	select S3C2410_PM if PM
+	select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
 	help
 	  Support for S3C2410 and S3C2410A family from the S3C24XX line
 	  of Samsung Mobile CPUs.
@@ -45,6 +46,22 @@ config MACH_BAST_IDE
 	  Internal node for machines with an BAST style IDE
 	  interface
 
+# cpu frequency scaling support
+
+config S3C2410_CPUFREQ
+	bool
+	depends on CPU_FREQ_S3C24XX && CPU_S3C2410
+	select S3C2410_CPUFREQ_UTILS
+	help
+	  CPU Frequency scaling support for S3C2410
+
+config S3C2410_PLLTABLE
+	bool
+	depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL
+	default y
+	help
+	  Select the PLL table for the S3C2410
+
 menu "S3C2410 Machines"
 
 config ARCH_SMDK2410
@@ -79,6 +96,7 @@ config MACH_N30
 config ARCH_BAST
 	bool "Simtec Electronics BAST (EB2410ITX)"
 	select CPU_S3C2410
+	select S3C2410_IOTIMING if S3C2410_CPUFREQ
 	select PM_SIMTEC if PM
 	select SIMTEC_NOR
 	select MACH_BAST_IDE
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index fca02f8..2ab5ba4 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_CPU_S3C2410_DMA)	+= dma.o
 obj-$(CONFIG_CPU_S3C2410_DMA)	+= dma.o
 obj-$(CONFIG_S3C2410_PM)	+= pm.o sleep.o
 obj-$(CONFIG_S3C2410_GPIO)	+= gpio.o
+obj-$(CONFIG_S3C2410_CPUFREQ)	+= cpu-freq.o
+obj-$(CONFIG_S3C2410_PLLTABLE)	+= pll.o
 
 # Machine support
 
diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c
new file mode 100644
index 0000000..9d11868
--- /dev/null
+++ b/arch/arm/mach-s3c2410/cpu-freq.c
@@ -0,0 +1,159 @@
+/* linux/arch/arm/mach-s3c2410/cpu-freq.c
+ *
+ * Copyright (c) 2006,2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 CPU Frequency scaling
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */
+
+static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	u32 clkdiv = 0;
+
+	if (cfg->divs.h_divisor == 2)
+		clkdiv |= S3C2410_CLKDIVN_HDIVN;
+
+	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+		clkdiv |= S3C2410_CLKDIVN_PDIVN;
+
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+}
+
+static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long hclk, fclk, pclk;
+	unsigned int hdiv, pdiv;
+	unsigned long hclk_max;
+
+	fclk = cfg->freq.fclk;
+	hclk_max = cfg->max.hclk;
+
+	cfg->freq.armclk = fclk;
+
+	s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n",
+		      __func__, fclk, hclk_max);
+
+	hdiv = (fclk > cfg->max.hclk) ? 2 : 1;
+	hclk = fclk / hdiv;
+
+	if (hclk > cfg->max.hclk) {
+		s3c_freq_dbg("%s: hclk too big\n", __func__);
+		return -EINVAL;
+	}
+
+	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+	pclk = hclk / pdiv;
+
+	if (pclk > cfg->max.pclk) {
+		s3c_freq_dbg("%s: pclk too big\n", __func__);
+		return -EINVAL;
+	}
+
+	pdiv *= hdiv;
+
+	/* record the result */
+	cfg->divs.p_divisor = pdiv;
+	cfg->divs.h_divisor = hdiv;
+
+	return 0      ;
+}
+
+static struct s3c_cpufreq_info s3c2410_cpufreq_info = {
+	.max		= {
+		.fclk	= 200000000,
+		.hclk	= 100000000,
+		.pclk	=  50000000,
+	},
+
+	/* transition latency is about 5ms worst-case, so
+	 * set 10ms to be sure */
+	.latency	= 10000000,
+
+	.locktime_m	= 150,
+	.locktime_u	= 150,
+	.locktime_bits	= 12,
+
+	.need_pll	= 1,
+
+	.name		= "s3c2410",
+	.calc_iotiming	= s3c2410_iotiming_calc,
+	.set_iotiming	= s3c2410_iotiming_set,
+	.get_iotiming	= s3c2410_iotiming_get,
+	.resume_clocks	= s3c2410_setup_clocks,
+
+	.set_fvco	= s3c2410_set_fvco,
+	.set_refresh	= s3c2410_cpufreq_setrefresh,
+	.set_divs	= s3c2410_cpufreq_setdivs,
+	.calc_divs	= s3c2410_cpufreq_calcdivs,
+
+	.debug_io_show	= s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
+};
+
+static int s3c2410_cpufreq_add(struct sys_device *sysdev)
+{
+	return s3c_cpufreq_register(&s3c2410_cpufreq_info);
+}
+
+static struct sysdev_driver s3c2410_cpufreq_driver = {
+	.add		= s3c2410_cpufreq_add,
+};
+
+static int __init s3c2410_cpufreq_init(void)
+{
+	return sysdev_driver_register(&s3c2410_sysclass,
+				      &s3c2410_cpufreq_driver);
+}
+
+arch_initcall(s3c2410_cpufreq_init);
+
+static int s3c2410a_cpufreq_add(struct sys_device *sysdev)
+{
+	/* alter the maximum freq settings for S3C2410A. If a board knows
+	 * it only has a maximum of 200, then it should register its own
+	 * limits. */
+
+	s3c2410_cpufreq_info.max.fclk = 266000000;
+	s3c2410_cpufreq_info.max.hclk = 133000000;
+	s3c2410_cpufreq_info.max.pclk =  66500000;
+	s3c2410_cpufreq_info.name = "s3c2410a";
+
+	return s3c2410_cpufreq_add(sysdev);
+}
+
+static struct sysdev_driver s3c2410a_cpufreq_driver = {
+	.add		= s3c2410a_cpufreq_add,
+};
+
+static int __init s3c2410a_cpufreq_init(void)
+{
+	return sysdev_driver_register(&s3c2410a_sysclass,
+				      &s3c2410a_cpufreq_driver);
+}
+
+arch_initcall(s3c2410a_cpufreq_init);
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index dbf96e6..63b753f 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -164,6 +164,17 @@ static int __init s3c2410_dma_drvinit(void)
 }
 
 arch_initcall(s3c2410_dma_drvinit);
+
+static struct sysdev_driver s3c2410a_dma_driver = {
+	.add	= s3c2410_dma_add,
+};
+
+static int __init s3c2410a_dma_drvinit(void)
+{
+	return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_dma_driver);
+}
+
+arch_initcall(s3c2410a_dma_drvinit);
 #endif
 
 #if defined(CONFIG_CPU_S3C2442)
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
index 2a2384f..6c12c63 100644
--- a/arch/arm/mach-s3c2410/include/mach/irqs.h
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -164,6 +164,12 @@
 #define IRQ_S3CUART_TX3		IRQ_S3C2443_TX3
 #define IRQ_S3CUART_ERR3	IRQ_S3C2443_ERR3
 
+#ifdef CONFIG_CPU_S3C2440
+#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
+#else
+#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97
+#endif
+
 /* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
 #define FIQ_START		IRQ_EINT0
 
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index e99b212..b049e61 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -67,6 +67,13 @@
 #define S3C2443_PA_HSMMC   (0x4A800000)
 #define S3C2443_SZ_HSMMC   (256)
 
+/* S3C2412 memory and IO controls */
+#define S3C2412_PA_SSMC	(0x4F000000)
+#define S3C2412_VA_SSMC	S3C_ADDR_CPU(0x00000000)
+
+#define S3C2412_PA_EBI	(0x48800000)
+#define S3C2412_VA_EBI	S3C_ADDR_CPU(0x00010000)
+
 /* physical addresses of all the chip-select areas */
 
 #define S3C2410_CS0 (0x00000000)
@@ -103,5 +110,6 @@
 #define S3C_PA_UART	    S3C24XX_PA_UART
 #define S3C_PA_USBHOST	S3C2410_PA_USBHOST
 #define S3C_PA_HSMMC0	    S3C2443_PA_HSMMC
+#define S3C_PA_NAND	    S3C24XX_PA_NAND
 
 #endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
index b278d0c..f6e8eec 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -328,13 +328,15 @@
 
 #define S3C2410_GPD8_VD16	(0x02 << 16)
 #define S3C2400_GPD8_TOUT3	(0x02 << 16)
+#define S3C2440_GPD8_SPIMISO1	(0x03 << 16)
 
 #define S3C2410_GPD9_VD17	(0x02 << 18)
 #define S3C2400_GPD9_TCLK0	(0x02 << 18)
-#define S3C2410_GPD9_MASK       (0x03 << 18)
+#define S3C2440_GPD9_SPIMOSI1	(0x03 << 18)
 
 #define S3C2410_GPD10_VD18	(0x02 << 20)
 #define S3C2400_GPD10_nWAIT	(0x02 << 20)
+#define S3C2440_GPD10_SPICLK1	(0x03 << 20)
 
 #define S3C2410_GPD11_VD19	(0x02 << 22)
 
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h
index 5775980..7f7c529 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-mem.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-mem.h
@@ -73,6 +73,16 @@
 #define S3C2410_BWSCON_WS7		(1<<30)
 #define S3C2410_BWSCON_ST7		(1<<31)
 
+/* accesor functions for getting BANK(n) configuration. (n != 0) */
+
+#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf)
+
+#define S3C2410_BWSCON_DW8		(0)
+#define S3C2410_BWSCON_DW16		(1)
+#define S3C2410_BWSCON_DW32		(2)
+#define S3C2410_BWSCON_WS		(1 << 2)
+#define S3C2410_BWSCON_ST		(1 << 3)
+
 /* memory set (rom, ram) */
 #define S3C2410_BANKCON0		S3C2410_MEMREG(0x0004)
 #define S3C2410_BANKCON1		S3C2410_MEMREG(0x0008)
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
index a4bf271..fb63525 100644
--- a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
@@ -14,9 +14,11 @@
 #ifndef __ASM_ARM_REGS_S3C2412_MEM
 #define __ASM_ARM_REGS_S3C2412_MEM
 
-#ifndef S3C2412_MEMREG
 #define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
-#endif
+#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x))
+
+#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x))
+#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o)))
 
 #define S3C2412_BANKCFG			S3C2412_MEMREG(0x00)
 #define S3C2412_BANKCON1		S3C2412_MEMREG(0x04)
@@ -26,4 +28,21 @@
 #define S3C2412_REFRESH			S3C2412_MEMREG(0x10)
 #define S3C2412_TIMEOUT			S3C2412_MEMREG(0x14)
 
+/* EBI control registers */
+
+#define S3C2412_EBI_PR			S3C2412_EBIREG(0x00)
+#define S3C2412_EBI_BANKCFG		S3C2412_EBIREG(0x04)
+
+/* SSMC control registers */
+
+#define S3C2412_SSMC_BANK(x)		S3C2412_SSMC(x, 0x00)
+#define S3C2412_SMIDCYR(x)		S3C2412_SSMC(x, 0x00)
+#define S3C2412_SMBWSTRD(x)		S3C2412_SSMC(x, 0x04)
+#define S3C2412_SMBWSTWRR(x)		S3C2412_SSMC(x, 0x08)
+#define S3C2412_SMBWSTOENR(x)		S3C2412_SSMC(x, 0x0C)
+#define S3C2412_SMBWSTWENR(x)		S3C2412_SSMC(x, 0x10)
+#define S3C2412_SMBCR(x)		S3C2412_SSMC(x, 0x14)
+#define S3C2412_SMBSR(x)		S3C2412_SSMC(x, 0x18)
+#define S3C2412_SMBWSTBRDR(x)		S3C2412_SSMC(x, 0x1C)
+
 #endif /*  __ASM_ARM_REGS_S3C2412_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h
index 1d300fb..193b39d 100644
--- a/arch/arm/mach-s3c2410/include/mach/spi.h
+++ b/arch/arm/mach-s3c2410/include/mach/spi.h
@@ -30,4 +30,7 @@ extern void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
 extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
 					      int enable);
 
+extern void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
+					       int enable);
+
 #endif /* __ASM_ARCH_SPI_H */
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 9215039..5e2f353 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -39,9 +39,22 @@ static struct sysdev_driver s3c2410_irq_driver = {
 	.resume		= s3c24xx_irq_resume,
 };
 
-static int s3c2410_irq_init(void)
+static int __init s3c2410_irq_init(void)
 {
 	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
 }
 
 arch_initcall(s3c2410_irq_init);
+
+static struct sysdev_driver s3c2410a_irq_driver = {
+	.add		= s3c2410_irq_add,
+	.suspend	= s3c24xx_irq_suspend,
+	.resume		= s3c24xx_irq_resume,
+};
+
+static int __init s3c2410a_irq_init(void)
+{
+	return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_irq_driver);
+}
+
+arch_initcall(s3c2410a_irq_init);
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index ce3baba..647c9ad 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -45,6 +45,7 @@
 #include <mach/regs-mem.h>
 #include <mach/regs-lcd.h>
 
+#include <plat/hwmon.h>
 #include <plat/nand.h>
 #include <plat/iic.h>
 #include <mach/fb.h>
@@ -59,6 +60,7 @@
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/cpu-freq.h>
 
 #include "usb-simtec.h"
 #include "nor-simtec.h"
@@ -547,7 +549,35 @@ static struct i2c_board_info bast_i2c_devs[] __initdata = {
 	},
 };
 
+static struct s3c_hwmon_pdata bast_hwmon_info = {
+	/* LCD contrast (0-6.6V) */
+	.in[0] = &(struct s3c_hwmon_chcfg) {
+		.name		= "lcd-contrast",
+		.mult		= 3300,
+		.div		= 512,
+	},
+	/* LED current feedback */
+	.in[1] = &(struct s3c_hwmon_chcfg) {
+		.name		= "led-feedback",
+		.mult		= 3300,
+		.div		= 1024,
+	},
+	/* LCD feedback (0-6.6V) */
+	.in[2] = &(struct s3c_hwmon_chcfg) {
+		.name		= "lcd-feedback",
+		.mult		= 3300,
+		.div		= 512,
+	},
+	/* Vcore (1.8-2.0V), Vref 3.3V  */
+	.in[3] = &(struct s3c_hwmon_chcfg) {
+		.name		= "vcore",
+		.mult		= 3300,
+		.div		= 1024,
+	},
+};
+
 /* Standard BAST devices */
+// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
 
 static struct platform_device *bast_devices[] __initdata = {
 	&s3c_device_usb,
@@ -556,6 +586,8 @@ static struct platform_device *bast_devices[] __initdata = {
 	&s3c_device_i2c0,
  	&s3c_device_rtc,
 	&s3c_device_nand,
+	&s3c_device_adc,
+	&s3c_device_hwmon,
 	&bast_device_dm9k,
 	&bast_device_asix,
 	&bast_device_axpp,
@@ -570,6 +602,12 @@ static struct clk *bast_clocks[] __initdata = {
 	&s3c24xx_uclk,
 };
 
+static struct s3c_cpufreq_board __initdata bast_cpufreq = {
+	.refresh	= 7800, /* 7.8usec */
+	.auto_io	= 1,
+	.need_io	= 1,
+};
+
 static void __init bast_map_io(void)
 {
 	/* initialise the clocks */
@@ -588,6 +626,7 @@ static void __init bast_map_io(void)
 	s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
 
 	s3c_device_nand.dev.platform_data = &bast_nand_info;
+	s3c_device_hwmon.dev.platform_data = &bast_hwmon_info;
 
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
 	s3c24xx_init_clocks(0);
@@ -608,6 +647,8 @@ static void __init bast_init(void)
 
 	usb_simtec_init();
 	nor_simtec_init();
+
+	s3c_cpufreq_setboard(&bast_cpufreq);
 }
 
 MACHINE_START(BAST, "Simtec-BAST")
diff --git a/arch/arm/mach-s3c2410/pll.c b/arch/arm/mach-s3c2410/pll.c
new file mode 100644
index 0000000..f178c2f
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pll.c
@@ -0,0 +1,95 @@
+/* arch/arm/mach-s3c2410/pll.c
+ *
+ * Copyright (c) 2006,2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2410 CPU PLL tables
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table pll_vals_12MHz[] = {
+    { .frequency = 34000000,  .index = PLLVAL(82, 2, 3),   },
+    { .frequency = 45000000,  .index = PLLVAL(82, 1, 3),   },
+    { .frequency = 51000000,  .index = PLLVAL(161, 3, 3),  },
+    { .frequency = 48000000,  .index = PLLVAL(120, 2, 3),  },
+    { .frequency = 56000000,  .index = PLLVAL(142, 2, 3),  },
+    { .frequency = 68000000,  .index = PLLVAL(82, 2, 2),   },
+    { .frequency = 79000000,  .index = PLLVAL(71, 1, 2),   },
+    { .frequency = 85000000,  .index = PLLVAL(105, 2, 2),  },
+    { .frequency = 90000000,  .index = PLLVAL(112, 2, 2),  },
+    { .frequency = 101000000, .index = PLLVAL(127, 2, 2),  },
+    { .frequency = 113000000, .index = PLLVAL(105, 1, 2),  },
+    { .frequency = 118000000, .index = PLLVAL(150, 2, 2),  },
+    { .frequency = 124000000, .index = PLLVAL(116, 1, 2),  },
+    { .frequency = 135000000, .index = PLLVAL(82, 2, 1),   },
+    { .frequency = 147000000, .index = PLLVAL(90, 2, 1),   },
+    { .frequency = 152000000, .index = PLLVAL(68, 1, 1),   },
+    { .frequency = 158000000, .index = PLLVAL(71, 1, 1),   },
+    { .frequency = 170000000, .index = PLLVAL(77, 1, 1),   },
+    { .frequency = 180000000, .index = PLLVAL(82, 1, 1),   },
+    { .frequency = 186000000, .index = PLLVAL(85, 1, 1),   },
+    { .frequency = 192000000, .index = PLLVAL(88, 1, 1),   },
+    { .frequency = 203000000, .index = PLLVAL(161, 3, 1),  },
+
+    /* 2410A extras */
+
+    { .frequency = 210000000, .index = PLLVAL(132, 2, 1),  },
+    { .frequency = 226000000, .index = PLLVAL(105, 1, 1),  },
+    { .frequency = 266000000, .index = PLLVAL(125, 1, 1),  },
+    { .frequency = 268000000, .index = PLLVAL(126, 1, 1),  },
+    { .frequency = 270000000, .index = PLLVAL(127, 1, 1),  },
+};
+
+static int s3c2410_plls_add(struct sys_device *dev)
+{
+	return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz));
+}
+
+static struct sysdev_driver s3c2410_plls_drv = {
+	.add	= s3c2410_plls_add,
+};
+
+static int __init s3c2410_pll_init(void)
+{
+	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_plls_drv);
+
+}
+
+arch_initcall(s3c2410_pll_init);
+
+static struct sysdev_driver s3c2410a_plls_drv = {
+	.add	= s3c2410_plls_add,
+};
+
+static int __init s3c2410a_pll_init(void)
+{
+	return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_plls_drv);
+}
+
+arch_initcall(s3c2410a_pll_init);
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index 143e08a..966119c 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -119,6 +119,18 @@ static int __init s3c2410_pm_drvinit(void)
 }
 
 arch_initcall(s3c2410_pm_drvinit);
+
+static struct sysdev_driver s3c2410a_pm_driver = {
+	.add		= s3c2410_pm_add,
+	.resume		= s3c2410_pm_resume,
+};
+
+static int __init s3c2410a_pm_drvinit(void)
+{
+	return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_pm_driver);
+}
+
+arch_initcall(s3c2410a_pm_drvinit);
 #endif
 
 #if defined(CONFIG_CPU_S3C2440)
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index feb141b..91ba42f 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -105,17 +105,33 @@ void __init_or_cpufreq s3c2410_setup_clocks(void)
 	s3c24xx_setup_clocks(fclk, hclk, pclk);
 }
 
+/* fake ARMCLK for use with cpufreq, etc. */
+
+static struct clk s3c2410_armclk = {
+	.name	= "armclk",
+	.parent	= &clk_f,
+	.id	= -1,
+};
+
 void __init s3c2410_init_clocks(int xtal)
 {
 	s3c24xx_register_baseclocks(xtal);
 	s3c2410_setup_clocks();
 	s3c2410_baseclk_add();
+	s3c24xx_register_clock(&s3c2410_armclk);
 }
 
 struct sysdev_class s3c2410_sysclass = {
 	.name = "s3c2410-core",
 };
 
+/* Note, we would have liked to name this s3c2410-core, but we cannot
+ * register two sysdev_class with the same name.
+ */
+struct sysdev_class s3c2410a_sysclass = {
+	.name = "s3c2410a-core",
+};
+
 static struct sys_device s3c2410_sysdev = {
 	.cls		= &s3c2410_sysclass,
 };
@@ -133,9 +149,22 @@ static int __init s3c2410_core_init(void)
 
 core_initcall(s3c2410_core_init);
 
+static int __init s3c2410a_core_init(void)
+{
+	return sysdev_class_register(&s3c2410a_sysclass);
+}
+
+core_initcall(s3c2410a_core_init);
+
 int __init s3c2410_init(void)
 {
 	printk("S3C2410: Initialising architecture\n");
 
 	return sysdev_register(&s3c2410_sysdev);
 }
+
+int __init s3c2410a_init(void)
+{
+	s3c2410_sysdev.cls = &s3c2410a_sysclass;
+	return s3c2410_init();
+}
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
index 63586ff..35c1bde 100644
--- a/arch/arm/mach-s3c2412/Kconfig
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -32,6 +32,15 @@ config S3C2412_PM
 	help
 	  Internal config node to apply S3C2412 power management
 
+# Note, the S3C2412 IOtiming support is in plat-s3c24xx
+
+config S3C2412_CPUFREQ
+	bool
+	depends on CPU_FREQ_S3C24XX && CPU_S3C2412
+	select S3C2412_IOTIMING
+	default y
+	help
+	  CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
 
 menu "S3C2412 Machines"
 
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
index 20918d5..530ec46 100644
--- a/arch/arm/mach-s3c2412/Makefile
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_S3C2412)	+= clock.o
 obj-$(CONFIG_CPU_S3C2412)	+= gpio.o
 obj-$(CONFIG_S3C2412_DMA)	+= dma.o
 obj-$(CONFIG_S3C2412_PM)	+= pm.o sleep.o
+obj-$(CONFIG_S3C2412_CPUFREQ)	+= cpu-freq.o
 
 # Machine support
 
diff --git a/arch/arm/mach-s3c2412/cpu-freq.c b/arch/arm/mach-s3c2412/cpu-freq.c
new file mode 100644
index 0000000..eb3ea17
--- /dev/null
+++ b/arch/arm/mach-s3c2412/cpu-freq.c
@@ -0,0 +1,257 @@
+/* linux/arch/arm/mach-s3c2412/cpu-freq.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 CPU Frequency scalling
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-s3c2412-mem.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+/* our clock resources. */
+static struct clk *xtal;
+static struct clk *fclk;
+static struct clk *hclk;
+static struct clk *armclk;
+
+/* HDIV: 1, 2, 3, 4, 6, 8 */
+
+static int s3c2412_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned int hdiv, pdiv, armdiv, dvs;
+	unsigned long hclk, fclk, armclk, armdiv_clk;
+	unsigned long hclk_max;
+
+	fclk = cfg->freq.fclk;
+	armclk = cfg->freq.armclk;
+	hclk_max = cfg->max.hclk;
+
+	/* We can't run hclk above armclk as at the best we have to
+	 * have armclk and hclk in dvs mode. */
+
+	if (hclk_max > armclk)
+		hclk_max = armclk;
+
+	s3c_freq_dbg("%s: fclk=%lu, armclk=%lu, hclk_max=%lu\n",
+		     __func__, fclk, armclk, hclk_max);
+	s3c_freq_dbg("%s: want f=%lu, arm=%lu, h=%lu, p=%lu\n",
+		     __func__, cfg->freq.fclk, cfg->freq.armclk,
+		     cfg->freq.hclk, cfg->freq.pclk);
+
+	armdiv = fclk / armclk;
+
+	if (armdiv < 1)
+		armdiv = 1;
+	if (armdiv > 2)
+		armdiv = 2;
+
+	cfg->divs.arm_divisor = armdiv;
+	armdiv_clk = fclk / armdiv;
+
+	hdiv = armdiv_clk / hclk_max;
+	if (hdiv < 1)
+		hdiv = 1;
+
+	cfg->freq.hclk = hclk = armdiv_clk / hdiv;
+
+	/* set dvs depending on whether we reached armclk or not. */
+	cfg->divs.dvs = dvs = armclk < armdiv_clk;
+
+	/* update the actual armclk we achieved. */
+	cfg->freq.armclk = dvs ? hclk : armdiv_clk;
+
+	s3c_freq_dbg("%s: armclk %lu, hclk %lu, armdiv %d, hdiv %d, dvs %d\n",
+		     __func__, armclk, hclk, armdiv, hdiv, cfg->divs.dvs);
+
+	if (hdiv > 4)
+		goto invalid;
+
+	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+
+	if ((hclk / pdiv) > cfg->max.pclk)
+		pdiv++;
+
+	cfg->freq.pclk = hclk / pdiv;
+
+	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
+
+	if (pdiv > 2)
+		goto invalid;
+
+	pdiv *= hdiv;
+
+	/* store the result, and then return */
+
+	cfg->divs.h_divisor = hdiv * armdiv;
+	cfg->divs.p_divisor = pdiv * armdiv;
+
+	return 0;
+
+ invalid:
+	return -EINVAL;
+}
+
+static void s3c2412_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long clkdiv;
+	unsigned long olddiv;
+
+	olddiv = clkdiv = __raw_readl(S3C2410_CLKDIVN);
+
+	/* clear off current clock info */
+
+	clkdiv &= ~S3C2412_CLKDIVN_ARMDIVN;
+	clkdiv &= ~S3C2412_CLKDIVN_HDIVN_MASK;
+	clkdiv &= ~S3C2412_CLKDIVN_PDIVN;
+
+	if (cfg->divs.arm_divisor == 2)
+		clkdiv |= S3C2412_CLKDIVN_ARMDIVN;
+
+	clkdiv |= ((cfg->divs.h_divisor / cfg->divs.arm_divisor) - 1);
+
+	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+		clkdiv |= S3C2412_CLKDIVN_PDIVN;
+
+	s3c_freq_dbg("%s: div %08lx => %08lx\n", __func__, olddiv, clkdiv);
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
+}
+
+static void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+	struct s3c_cpufreq_board *board = cfg->board;
+	unsigned long refresh;
+
+	s3c_freq_dbg("%s: refresh %u ns, hclk %lu\n", __func__,
+		     board->refresh, cfg->freq.hclk);
+
+	/* Reduce both the refresh time (in ns) and the frequency (in MHz)
+	 * by 10 each to ensure that we do not overflow 32 bit numbers. This
+	 * should work for HCLK up to 133MHz and refresh period up to 30usec.
+	 */
+
+	refresh = (board->refresh / 10);
+	refresh *= (cfg->freq.hclk / 100);
+	refresh /= (1 * 1000 * 1000);	/* 10^6 */
+
+	s3c_freq_dbg("%s: setting refresh 0x%08lx\n", __func__, refresh);
+	__raw_writel(refresh, S3C2412_REFRESH);
+}
+
+/* set the default cpu frequency information, based on an 200MHz part
+ * as we have no other way of detecting the speed rating in software.
+ */
+
+static struct s3c_cpufreq_info s3c2412_cpufreq_info = {
+	.max		= {
+		.fclk	= 200000000,
+		.hclk	= 100000000,
+		.pclk	=  50000000,
+	},
+
+	.latency	= 5000000, /* 5ms */
+
+	.locktime_m	= 150,
+	.locktime_u	= 150,
+	.locktime_bits	= 16,
+
+	.name		= "s3c2412",
+	.set_refresh	= s3c2412_cpufreq_setrefresh,
+	.set_divs	= s3c2412_cpufreq_setdivs,
+	.calc_divs	= s3c2412_cpufreq_calcdivs,
+
+	.calc_iotiming	= s3c2412_iotiming_calc,
+	.set_iotiming	= s3c2412_iotiming_set,
+	.get_iotiming	= s3c2412_iotiming_get,
+
+	.resume_clocks	= s3c2412_setup_clocks,
+
+	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
+};
+
+static int s3c2412_cpufreq_add(struct sys_device *sysdev)
+{
+	unsigned long fclk_rate;
+
+	hclk = clk_get(NULL, "hclk");
+	if (IS_ERR(hclk)) {
+		printk(KERN_ERR "%s: cannot find hclk clock\n", __func__);
+		return -ENOENT;
+	}
+
+	fclk = clk_get(NULL, "fclk");
+	if (IS_ERR(fclk)) {
+		printk(KERN_ERR "%s: cannot find fclk clock\n", __func__);
+		goto err_fclk;
+	}
+
+	fclk_rate = clk_get_rate(fclk);
+	if (fclk_rate > 200000000) {
+		printk(KERN_INFO
+		       "%s: fclk %ld MHz, assuming 266MHz capable part\n",
+		       __func__, fclk_rate / 1000000);
+		s3c2412_cpufreq_info.max.fclk = 266000000;
+		s3c2412_cpufreq_info.max.hclk = 133000000;
+		s3c2412_cpufreq_info.max.pclk =  66000000;
+	}
+
+	armclk = clk_get(NULL, "armclk");
+	if (IS_ERR(armclk)) {
+		printk(KERN_ERR "%s: cannot find arm clock\n", __func__);
+		goto err_armclk;
+	}
+
+	xtal = clk_get(NULL, "xtal");
+	if (IS_ERR(xtal)) {
+		printk(KERN_ERR "%s: cannot find xtal clock\n", __func__);
+		goto err_xtal;
+	}
+
+	return s3c_cpufreq_register(&s3c2412_cpufreq_info);
+
+err_xtal:
+	clk_put(armclk);
+err_armclk:
+	clk_put(fclk);
+err_fclk:
+	clk_put(hclk);
+
+	return -ENOENT;
+}
+
+static struct sysdev_driver s3c2412_cpufreq_driver = {
+	.add		= s3c2412_cpufreq_add,
+};
+
+static int s3c2412_cpufreq_init(void)
+{
+	return sysdev_driver_register(&s3c2412_sysclass,
+				      &s3c2412_cpufreq_driver);
+}
+
+arch_initcall(s3c2412_cpufreq_init);
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index 5b5aba6..bef39f7 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -69,6 +69,18 @@ static struct map_desc s3c2412_iodesc[] __initdata = {
 	IODESC_ENT(CLKPWR),
 	IODESC_ENT(TIMER),
 	IODESC_ENT(WATCHDOG),
+	{
+		.virtual = (unsigned long)S3C2412_VA_SSMC,
+		.pfn	 = __phys_to_pfn(S3C2412_PA_SSMC),
+		.length	 = SZ_1M,
+		.type	 = MT_DEVICE,
+	},
+	{
+		.virtual = (unsigned long)S3C2412_VA_EBI,
+		.pfn	 = __phys_to_pfn(S3C2412_PA_EBI),
+		.length	 = SZ_1M,
+		.type	 = MT_DEVICE,
+	},
 };
 
 /* uart registration process */
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 8cfeaec..8ae1b28 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -33,6 +33,7 @@ config MACH_ANUBIS
 	select PM_SIMTEC if PM
 	select HAVE_PATA_PLATFORM
 	select S3C24XX_GPIO_EXTRA64
+	select S3C2440_XTAL_12000000
 	select S3C_DEV_USB_HOST
 	help
 	  Say Y here if you are using the Simtec Electronics ANUBIS
@@ -44,6 +45,8 @@ config MACH_OSIRIS
 	select S3C24XX_DCLK
 	select PM_SIMTEC if PM
 	select S3C24XX_GPIO_EXTRA128
+	select S3C2440_XTAL_12000000
+	select S3C2410_IOTIMING if S3C2440_CPUFREQ
 	select S3C_DEV_USB_HOST
 	help
 	  Say Y here if you are using the Simtec IM2440D20 module, also
@@ -52,6 +55,7 @@ config MACH_OSIRIS
 config MACH_RX3715
 	bool "HP iPAQ rx3715"
 	select CPU_S3C2440
+	select S3C2440_XTAL_16934400
 	select PM_H1940 if PM
 	help
 	  Say Y here if you are using the HP iPAQ rx3715.
@@ -59,6 +63,7 @@ config MACH_RX3715
 config ARCH_S3C2440
 	bool "SMDK2440"
 	select CPU_S3C2440
+	select S3C2440_XTAL_16934400
 	select MACH_SMDK
 	select S3C_DEV_USB_HOST
 	help
@@ -67,6 +72,7 @@ config ARCH_S3C2440
 config MACH_NEXCODER_2440
  	bool "NexVision NEXCODER 2440 Light Board"
  	select CPU_S3C2440
+	select S3C2440_XTAL_12000000
 	select S3C_DEV_USB_HOST
 	help
  	  Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
@@ -75,6 +81,7 @@ config SMDK2440_CPU2440
 	bool "SMDK2440 with S3C2440 CPU module"
 	depends on ARCH_S3C2440
 	default y if ARCH_S3C2440
+	select S3C2440_XTAL_16934400
 	select CPU_S3C2440
 
 config MACH_AT2440EVB
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index cba064b..2105a41 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -34,6 +34,7 @@
 #include <asm/irq.h>
 #include <asm/mach-types.h>
 
+#include <plat/cpu-freq.h>
 #include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-mem.h>
@@ -351,6 +352,12 @@ static struct clk *osiris_clocks[] __initdata = {
 	&s3c24xx_uclk,
 };
 
+static struct s3c_cpufreq_board __initdata osiris_cpufreq = {
+	.refresh	= 7800, /* refresh period is 7.8usec */
+	.auto_io	= 1,
+	.need_io	= 1,
+};
+
 static void __init osiris_map_io(void)
 {
 	unsigned long flags;
@@ -402,6 +409,8 @@ static void __init osiris_init(void)
 
 	s3c_i2c0_set_platdata(NULL);
 
+	s3c_cpufreq_setboard(&osiris_cpufreq);
+
 	i2c_register_board_info(0, osiris_i2c_devs,
 				ARRAY_SIZE(osiris_i2c_devs));
 
diff --git a/arch/arm/mach-s3c24a0/include/mach/map.h b/arch/arm/mach-s3c24a0/include/mach/map.h
index a011327..79e4d93 100644
--- a/arch/arm/mach-s3c24a0/include/mach/map.h
+++ b/arch/arm/mach-s3c24a0/include/mach/map.h
@@ -81,5 +81,6 @@
 
 #define S3C_PA_UART		S3C24A0_PA_UART
 #define S3C_PA_IIC		S3C24A0_PA_IIC
+#define S3C_PA_NAND		S3C24XX_PA_NAND
 
 #endif /* __ASM_ARCH_24A0_MAP_H */
diff --git a/arch/arm/mach-s3c6400/include/mach/map.h b/arch/arm/mach-s3c6400/include/mach/map.h
index 5057d99..fc8b223 100644
--- a/arch/arm/mach-s3c6400/include/mach/map.h
+++ b/arch/arm/mach-s3c6400/include/mach/map.h
@@ -38,18 +38,21 @@
 #define S3C_VA_UART2		S3C_VA_UARTx(2)
 #define S3C_VA_UART3		S3C_VA_UARTx(3)
 
+#define S3C64XX_PA_NAND		(0x70200000)
 #define S3C64XX_PA_FB		(0x77100000)
 #define S3C64XX_PA_USB_HSOTG	(0x7C000000)
 #define S3C64XX_PA_WATCHDOG	(0x7E004000)
 #define S3C64XX_PA_SYSCON	(0x7E00F000)
+#define S3C64XX_PA_AC97		(0x7F001000)
 #define S3C64XX_PA_IIS0		(0x7F002000)
 #define S3C64XX_PA_IIS1		(0x7F003000)
 #define S3C64XX_PA_TIMER	(0x7F006000)
 #define S3C64XX_PA_IIC0		(0x7F004000)
+#define S3C64XX_PA_IISV4	(0x7F00D000)
 #define S3C64XX_PA_IIC1		(0x7F00F000)
 
 #define S3C64XX_PA_GPIO		(0x7F008000)
-#define S3C64XX_VA_GPIO		S3C_ADDR(0x00500000)
+#define S3C64XX_VA_GPIO		S3C_ADDR_CPU(0x00000000)
 #define S3C64XX_SZ_GPIO		SZ_4K
 
 #define S3C64XX_PA_SDRAM	(0x50000000)
@@ -57,7 +60,7 @@
 #define S3C64XX_PA_VIC1		(0x71300000)
 
 #define S3C64XX_PA_MODEM	(0x74108000)
-#define S3C64XX_VA_MODEM	S3C_ADDR(0x00600000)
+#define S3C64XX_VA_MODEM	S3C_ADDR_CPU(0x00100000)
 
 #define S3C64XX_PA_USBHOST	(0x74300000)
 
@@ -72,6 +75,7 @@
 #define S3C_PA_HSMMC2		S3C64XX_PA_HSMMC2
 #define S3C_PA_IIC		S3C64XX_PA_IIC0
 #define S3C_PA_IIC1		S3C64XX_PA_IIC1
+#define S3C_PA_NAND		S3C64XX_PA_NAND
 #define S3C_PA_FB		S3C64XX_PA_FB
 #define S3C_PA_USBHOST		S3C64XX_PA_USBHOST
 #define S3C_PA_USB_HSOTG	S3C64XX_PA_USB_HSOTG
diff --git a/arch/arm/mach-s3c6400/s3c6400.c b/arch/arm/mach-s3c6400/s3c6400.c
index 1ece887..b42bdd0 100644
--- a/arch/arm/mach-s3c6400/s3c6400.c
+++ b/arch/arm/mach-s3c6400/s3c6400.c
@@ -48,6 +48,8 @@ void __init s3c6400_map_io(void)
 
 	/* the i2c devices are directly compatible with s3c2440 */
 	s3c_i2c0_setname("s3c2440-i2c");
+
+	s3c_device_nand.name = "s3c6400-nand";
 }
 
 void __init s3c6400_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c6410/Kconfig b/arch/arm/mach-s3c6410/Kconfig
index e63aac7..f9d0f09 100644
--- a/arch/arm/mach-s3c6410/Kconfig
+++ b/arch/arm/mach-s3c6410/Kconfig
@@ -97,3 +97,13 @@ config MACH_NCP
 	select S3C64XX_SETUP_I2C1
 	help
           Machine support for the Samsung NCP
+
+config MACH_HMT
+	bool "Airgoo HMT"
+	select CPU_S3C6410
+	select S3C_DEV_FB
+	select S3C_DEV_USB_HOST
+	select S3C64XX_SETUP_FB_24BPP
+	select HAVE_PWM
+	help
+	  Machine support for the Airgoo HMT
diff --git a/arch/arm/mach-s3c6410/Makefile b/arch/arm/mach-s3c6410/Makefile
index 6f9deac..3e48c3d 100644
--- a/arch/arm/mach-s3c6410/Makefile
+++ b/arch/arm/mach-s3c6410/Makefile
@@ -23,5 +23,4 @@ obj-$(CONFIG_S3C6410_SETUP_SDHCI)	+= setup-sdhci.o
 obj-$(CONFIG_MACH_ANW6410)	+= mach-anw6410.o
 obj-$(CONFIG_MACH_SMDK6410)	+= mach-smdk6410.o
 obj-$(CONFIG_MACH_NCP)		+= mach-ncp.o
-
-
+obj-$(CONFIG_MACH_HMT)		+= mach-hmt.o
diff --git a/arch/arm/mach-s3c6410/cpu.c b/arch/arm/mach-s3c6410/cpu.c
index ade904d..9b67c66 100644
--- a/arch/arm/mach-s3c6410/cpu.c
+++ b/arch/arm/mach-s3c6410/cpu.c
@@ -62,6 +62,8 @@ void __init s3c6410_map_io(void)
 	/* the i2c devices are directly compatible with s3c2440 */
 	s3c_i2c0_setname("s3c2440-i2c");
 	s3c_i2c1_setname("s3c2440-i2c");
+
+	s3c_device_nand.name = "s3c6400-nand";
 }
 
 void __init s3c6410_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c6410/mach-hmt.c b/arch/arm/mach-s3c6410/mach-hmt.c
new file mode 100644
index 0000000..c574105
--- /dev/null
+++ b/arch/arm/mach-s3c6410/mach-hmt.c
@@ -0,0 +1,276 @@
+/* mach-hmt.c - Platform code for Airgoo HMT
+ *
+ * Copyright 2009 Peter Korsgaard <jacmet@sunsite.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.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/pwm_backlight.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+
+#include <plat/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+};
+
+static int hmt_bl_init(struct device *dev)
+{
+	int ret;
+
+	ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
+	if (!ret)
+		ret = gpio_direction_output(S3C64XX_GPB(4), 0);
+
+	return ret;
+}
+
+static int hmt_bl_notify(int brightness)
+{
+	/*
+	 * translate from CIELUV/CIELAB L*->brightness, E.G. from
+	 * perceived luminance to light output. Assumes range 0..25600
+	 */
+	if (brightness < 0x800) {
+		/* Y = Yn * L / 903.3 */
+		brightness = (100*256 * brightness + 231245/2) / 231245;
+	} else {
+		/* Y = Yn * ((L + 16) / 116 )^3 */
+		int t = (brightness*4 + 16*1024 + 58)/116;
+		brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
+	}
+
+	gpio_set_value(S3C64XX_GPB(4), brightness);
+
+	return brightness;
+}
+
+static void hmt_bl_exit(struct device *dev)
+{
+	gpio_free(S3C64XX_GPB(4));
+}
+
+static struct platform_pwm_backlight_data hmt_backlight_data = {
+	.pwm_id		= 1,
+	.max_brightness	= 100 * 256,
+	.dft_brightness	= 40 * 256,
+	.pwm_period_ns	= 1000000000 / (100 * 256 * 20),
+	.init		= hmt_bl_init,
+	.notify		= hmt_bl_notify,
+	.exit		= hmt_bl_exit,
+
+};
+
+static struct platform_device hmt_backlight_device = {
+	.name		= "pwm-backlight",
+	.dev		= {
+		.parent	= &s3c_device_timer[1].dev,
+		.platform_data = &hmt_backlight_data,
+	},
+};
+
+static struct s3c_fb_pd_win hmt_fb_win0 = {
+	.win_mode	= {
+		.pixclock	= 41094,
+		.left_margin	= 8,
+		.right_margin	= 13,
+		.upper_margin	= 7,
+		.lower_margin	= 5,
+		.hsync_len	= 3,
+		.vsync_len	= 1,
+		.xres		= 800,
+		.yres		= 480,
+	},
+	.max_bpp	= 32,
+	.default_bpp	= 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
+	.setup_gpio	= s3c64xx_fb_gpio_setup_24bpp,
+	.win[0]		= &hmt_fb_win0,
+	.vidcon0	= VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+	.vidcon1	= VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition hmt_nand_part[] = {
+	[0] = {
+		.name	= "uboot",
+		.size	= SZ_512K,
+		.offset	= 0,
+	},
+	[1] = {
+		.name	= "uboot-env1",
+		.size	= SZ_256K,
+		.offset	= SZ_512K,
+	},
+	[2] = {
+		.name	= "uboot-env2",
+		.size	= SZ_256K,
+		.offset	= SZ_512K + SZ_256K,
+	},
+	[3] = {
+		.name	= "kernel",
+		.size	= SZ_2M,
+		.offset	= SZ_1M,
+	},
+	[4] = {
+		.name	= "rootfs",
+		.size	= MTDPART_SIZ_FULL,
+		.offset	= SZ_1M + SZ_2M,
+	},
+};
+
+static struct s3c2410_nand_set hmt_nand_sets[] = {
+	[0] = {
+		.name		= "nand",
+		.nr_chips	= 1,
+		.nr_partitions	= ARRAY_SIZE(hmt_nand_part),
+		.partitions	= hmt_nand_part,
+	},
+};
+
+static struct s3c2410_platform_nand hmt_nand_info = {
+	.tacls		= 25,
+	.twrph0		= 55,
+	.twrph1		= 40,
+	.nr_sets	= ARRAY_SIZE(hmt_nand_sets),
+	.sets		= hmt_nand_sets,
+};
+
+static struct gpio_led hmt_leds[] = {
+	{ /* left function keys */
+		.name			= "left:blue",
+		.gpio			= S3C64XX_GPO(12),
+		.default_trigger	= "default-on",
+	},
+	{ /* right function keys - red */
+		.name			= "right:red",
+		.gpio			= S3C64XX_GPO(13),
+	},
+	{ /* right function keys - green */
+		.name			= "right:green",
+		.gpio			= S3C64XX_GPO(14),
+	},
+	{ /* right function keys - blue */
+		.name			= "right:blue",
+		.gpio			= S3C64XX_GPO(15),
+		.default_trigger	= "default-on",
+	},
+};
+
+static struct gpio_led_platform_data hmt_led_data = {
+	.num_leds = ARRAY_SIZE(hmt_leds),
+	.leds = hmt_leds,
+};
+
+static struct platform_device hmt_leds_device = {
+	.name			= "leds-gpio",
+	.id			= -1,
+	.dev.platform_data	= &hmt_led_data,
+};
+
+static struct map_desc hmt_iodesc[] = {};
+
+static struct platform_device *hmt_devices[] __initdata = {
+	&s3c_device_i2c0,
+	&s3c_device_nand,
+	&s3c_device_fb,
+	&s3c_device_usb,
+	&s3c_device_timer[1],
+	&hmt_backlight_device,
+	&hmt_leds_device,
+};
+
+static void __init hmt_map_io(void)
+{
+	s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
+}
+
+static void __init hmt_machine_init(void)
+{
+	s3c_i2c0_set_platdata(NULL);
+	s3c_fb_set_platdata(&hmt_lcd_pdata);
+	s3c_device_nand.dev.platform_data = &hmt_nand_info;
+
+	gpio_request(S3C64XX_GPC(7), "usb power");
+	gpio_direction_output(S3C64XX_GPC(7), 0);
+	gpio_request(S3C64XX_GPM(0), "usb power");
+	gpio_direction_output(S3C64XX_GPM(0), 1);
+	gpio_request(S3C64XX_GPK(7), "usb power");
+	gpio_direction_output(S3C64XX_GPK(7), 1);
+	gpio_request(S3C64XX_GPF(13), "usb power");
+	gpio_direction_output(S3C64XX_GPF(13), 1);
+
+	platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
+}
+
+MACHINE_START(HMT, "Airgoo-HMT")
+	/* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
+	.phys_io	= S3C_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S3C_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S3C64XX_PA_SDRAM + 0x100,
+	.init_irq	= s3c6410_init_irq,
+	.map_io		= hmt_map_io,
+	.init_machine	= hmt_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c6410/mach-ncp.c b/arch/arm/mach-s3c6410/mach-ncp.c
index 6030636..55e9bbf 100644
--- a/arch/arm/mach-s3c6410/mach-ncp.c
+++ b/arch/arm/mach-s3c6410/mach-ncp.c
@@ -79,7 +79,7 @@ static struct platform_device *ncp_devices[] __initdata = {
 	&s3c_device_i2c0,
 };
 
-struct map_desc ncp_iodesc[] = {};
+static struct map_desc ncp_iodesc[] __initdata = {};
 
 static void __init ncp_map_io(void)
 {
diff --git a/arch/arm/mach-s3c6410/mach-smdk6410.c b/arch/arm/mach-s3c6410/mach-smdk6410.c
index bc9a7de..ea51dbe 100644
--- a/arch/arm/mach-s3c6410/mach-smdk6410.c
+++ b/arch/arm/mach-s3c6410/mach-smdk6410.c
@@ -65,16 +65,30 @@ static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
 	[0] = {
 		.hwport	     = 0,
 		.flags	     = 0,
-		.ucon	     = 0x3c5,
-		.ulcon	     = 0x03,
-		.ufcon	     = 0x51,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
 	},
 	[1] = {
 		.hwport	     = 1,
 		.flags	     = 0,
-		.ucon	     = 0x3c5,
-		.ulcon	     = 0x03,
-		.ufcon	     = 0x51,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
+	},
+	[3] = {
+		.hwport	     = 3,
+		.flags	     = 0,
+		.ucon	     = UCON,
+		.ulcon	     = ULCON,
+		.ufcon	     = UFCON,
 	},
 };
 
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
new file mode 100644
index 0000000..b1a4ba5
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -0,0 +1,22 @@
+# arch/arm/mach-s5pc100/Kconfig
+#
+# Copyright 2009 Samsung Electronics Co.
+#	Byungho Min <bhmin@samsung.com>
+#
+# Licensed under GPLv2
+
+# Configuration options for the S5PC100 CPU
+
+config CPU_S5PC100
+	bool
+	select CPU_S5PC100_INIT
+	select CPU_S5PC100_CLOCK
+	help
+	  Enable S5PC100 CPU support
+
+config MACH_SMDKC100
+	bool "SMDKC100"
+	select CPU_S5PC100
+	select S5PC1XX_SETUP_I2C1
+	help
+	  Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
new file mode 100644
index 0000000..afc89b3
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -0,0 +1,17 @@
+# arch/arm/mach-s5pc100/Makefile
+#
+# Copyright 2009 Samsung Electronics Co.
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:=
+obj-				:=
+
+# Core support for S5PC100 system
+
+obj-$(CONFIG_CPU_S5PC100)	+= cpu.o
+
+# machine support
+obj-$(CONFIG_MACH_SMDKC100)	+= mach-smdkc100.o
diff --git a/arch/arm/mach-s5pc100/Makefile.boot b/arch/arm/mach-s5pc100/Makefile.boot
new file mode 100644
index 0000000..ff90aa1
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Makefile.boot
@@ -0,0 +1,2 @@
+   zreladdr-y	:= 0x20008000
+params_phys-y	:= 0x20000100
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
new file mode 100644
index 0000000..0e71889
--- /dev/null
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -0,0 +1,97 @@
+/* linux/arch/arm/mach-s5pc100/cpu.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * Based on mach-s3c6410/cpu.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <plat/s5pc100.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5pc100_iodesc[] __initdata = {
+};
+
+/* s5pc100_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5pc100_map_io(void)
+{
+	iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
+
+	/* initialise device information early */
+}
+
+void __init s5pc100_init_clocks(int xtal)
+{
+	printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
+	s3c24xx_register_baseclocks(xtal);
+	s5pc1xx_register_clocks();
+	s5pc100_register_clocks();
+	s5pc100_setup_clocks();
+}
+
+void __init s5pc100_init_irq(void)
+{
+	u32 vic_valid[] = {~0, ~0, ~0};
+
+	/* VIC0, VIC1, and VIC2 are fully populated. */
+	s5pc1xx_init_irq(vic_valid, ARRAY_SIZE(vic_valid));
+}
+
+struct sysdev_class s5pc100_sysclass = {
+	.name	= "s5pc100-core",
+};
+
+static struct sys_device s5pc100_sysdev = {
+	.cls	= &s5pc100_sysclass,
+};
+
+static int __init s5pc100_core_init(void)
+{
+	return sysdev_class_register(&s5pc100_sysclass);
+}
+
+core_initcall(s5pc100_core_init);
+
+int __init s5pc100_init(void)
+{
+	printk(KERN_DEBUG "S5PC100: Initialising architecture\n");
+
+	return sysdev_register(&s5pc100_sysdev);
+}
diff --git a/arch/arm/mach-s5pc100/include/mach/debug-macro.S b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
new file mode 100644
index 0000000..9d142cc
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
+/* arch/arm/mach-s5pc100/include/mach/debug-macro.S
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ *
+ * Based on mach-s3c6400/include/mach/debug-macro.S
+ *
+ * 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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+	/* note, for the boot process to work we have to keep the UART
+	 * virtual address aligned to an 1MiB boundary for the L1
+	 * mapping the head code makes. We keep the UART virtual address
+	 * aligned and add in the offset when we load the value here.
+	 */
+
+	.macro addruart, rx
+		mrc	p15, 0, \rx, c1, c0
+		tst	\rx, #1
+		ldreq	\rx, = S3C_PA_UART
+		ldrne	\rx, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
+		add	\rx, \rx, #(0x400 * CONFIG_DEBUG_S3C_UART)
+	.endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5pc100/include/mach/entry-macro.S b/arch/arm/mach-s5pc100/include/mach/entry-macro.S
new file mode 100644
index 0000000..6713193
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/entry-macro.S
@@ -0,0 +1,50 @@
+/* arch/arm/mach-s5pc100/include/mach/entry-macro.S
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * Based on mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for the Samsung S5PC1XX series
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_preamble, base, tmp
+	ldr	\base, =S3C_VA_VIC0
+	.endm
+
+	.macro	arch_ret_to_user, tmp1, tmp2
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+	@ check the vic0
+	mov	\irqnr, # S3C_IRQ_OFFSET + 31
+	ldr	\irqstat, [ \base, # VIC_IRQ_STATUS ]
+	teq	\irqstat, #0
+
+	@ otherwise try vic1
+	addeq	\tmp, \base, #(S3C_VA_VIC1 - S3C_VA_VIC0)
+	addeq	\irqnr, \irqnr, #32
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	@ otherwise try vic2
+	addeq	\tmp, \base, #(S3C_VA_VIC2 - S3C_VA_VIC0)
+	addeq	\irqnr, \irqnr, #32
+	ldreq	\irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+	teqeq	\irqstat, #0
+
+	clzne	\irqstat, \irqstat
+	subne	\irqnr, \irqnr, \irqstat
+	.endm
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio-core.h b/arch/arm/mach-s5pc100/include/mach/gpio-core.h
new file mode 100644
index 0000000..ad28d8e
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/gpio-core.h
@@ -0,0 +1,21 @@
+/* arch/arm/mach-s5pc100/include/mach/gpio-core.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - GPIO core support
+ *
+ * Based on mach-s3c6400/include/mach/gpio-core.h
+ *
+ * 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 __ASM_ARCH_GPIO_CORE_H
+#define __ASM_ARCH_GPIO_CORE_H __FILE__
+
+/* currently we just include the platform support */
+#include <plat/gpio-core.h>
+
+#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
new file mode 100644
index 0000000..c74fc93
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -0,0 +1,146 @@
+/* arch/arm/mach-s5pc100/include/mach/gpio.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - GPIO lib support
+ *
+ * Base on mach-s3c6400/include/mach/gpio.h
+ *
+ * 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.
+*/
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
+
+/* GPIO bank sizes */
+#define S5PC1XX_GPIO_A0_NR	(8)
+#define S5PC1XX_GPIO_A1_NR	(5)
+#define S5PC1XX_GPIO_B_NR	(8)
+#define S5PC1XX_GPIO_C_NR	(5)
+#define S5PC1XX_GPIO_D_NR	(7)
+#define S5PC1XX_GPIO_E0_NR	(8)
+#define S5PC1XX_GPIO_E1_NR	(6)
+#define S5PC1XX_GPIO_F0_NR	(8)
+#define S5PC1XX_GPIO_F1_NR	(8)
+#define S5PC1XX_GPIO_F2_NR	(8)
+#define S5PC1XX_GPIO_F3_NR	(4)
+#define S5PC1XX_GPIO_G0_NR	(8)
+#define S5PC1XX_GPIO_G1_NR	(3)
+#define S5PC1XX_GPIO_G2_NR	(7)
+#define S5PC1XX_GPIO_G3_NR	(7)
+#define S5PC1XX_GPIO_H0_NR	(8)
+#define S5PC1XX_GPIO_H1_NR	(8)
+#define S5PC1XX_GPIO_H2_NR	(8)
+#define S5PC1XX_GPIO_H3_NR	(8)
+#define S5PC1XX_GPIO_I_NR	(8)
+#define S5PC1XX_GPIO_J0_NR	(8)
+#define S5PC1XX_GPIO_J1_NR	(5)
+#define S5PC1XX_GPIO_J2_NR	(8)
+#define S5PC1XX_GPIO_J3_NR	(8)
+#define S5PC1XX_GPIO_J4_NR	(4)
+#define S5PC1XX_GPIO_K0_NR	(8)
+#define S5PC1XX_GPIO_K1_NR	(6)
+#define S5PC1XX_GPIO_K2_NR	(8)
+#define S5PC1XX_GPIO_K3_NR	(8)
+#define S5PC1XX_GPIO_MP00_NR	(8)
+#define S5PC1XX_GPIO_MP01_NR	(8)
+#define S5PC1XX_GPIO_MP02_NR	(8)
+#define S5PC1XX_GPIO_MP03_NR	(8)
+#define S5PC1XX_GPIO_MP04_NR	(5)
+
+/* GPIO bank numbes */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5PC1XX_GPIO_NEXT(__gpio) \
+	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s3c_gpio_number {
+	S5PC1XX_GPIO_A0_START 	= 0,
+	S5PC1XX_GPIO_A1_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A0),
+	S5PC1XX_GPIO_B_START 	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_A1),
+	S5PC1XX_GPIO_C_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_B),
+	S5PC1XX_GPIO_D_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_C),
+	S5PC1XX_GPIO_E0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_D),
+	S5PC1XX_GPIO_E1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E0),
+	S5PC1XX_GPIO_F0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_E1),
+	S5PC1XX_GPIO_F1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F0),
+	S5PC1XX_GPIO_F2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F1),
+	S5PC1XX_GPIO_F3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F2),
+	S5PC1XX_GPIO_G0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_F3),
+	S5PC1XX_GPIO_G1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G0),
+	S5PC1XX_GPIO_G2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G1),
+	S5PC1XX_GPIO_G3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G2),
+	S5PC1XX_GPIO_H0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_G3),
+	S5PC1XX_GPIO_H1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H0),
+	S5PC1XX_GPIO_H2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H1),
+	S5PC1XX_GPIO_H3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H2),
+	S5PC1XX_GPIO_I_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_H3),
+	S5PC1XX_GPIO_J0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_I),
+	S5PC1XX_GPIO_J1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J0),
+	S5PC1XX_GPIO_J2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J1),
+	S5PC1XX_GPIO_J3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J2),
+	S5PC1XX_GPIO_J4_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J3),
+	S5PC1XX_GPIO_K0_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_J4),
+	S5PC1XX_GPIO_K1_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K0),
+	S5PC1XX_GPIO_K2_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K1),
+	S5PC1XX_GPIO_K3_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K2),
+	S5PC1XX_GPIO_MP00_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_K3),
+	S5PC1XX_GPIO_MP01_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP00),
+	S5PC1XX_GPIO_MP02_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP01),
+	S5PC1XX_GPIO_MP03_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP02),
+	S5PC1XX_GPIO_MP04_START	= S5PC1XX_GPIO_NEXT(S5PC1XX_GPIO_MP03),
+};
+
+/* S5PC1XX GPIO number definitions. */
+#define S5PC1XX_GPA0(_nr)	(S5PC1XX_GPIO_A0_START + (_nr))
+#define S5PC1XX_GPA1(_nr)	(S5PC1XX_GPIO_A1_START + (_nr))
+#define S5PC1XX_GPB(_nr)	(S5PC1XX_GPIO_B_START + (_nr))
+#define S5PC1XX_GPC(_nr)	(S5PC1XX_GPIO_C_START + (_nr))
+#define S5PC1XX_GPD(_nr)	(S5PC1XX_GPIO_D_START + (_nr))
+#define S5PC1XX_GPE0(_nr)	(S5PC1XX_GPIO_E0_START + (_nr))
+#define S5PC1XX_GPE1(_nr)	(S5PC1XX_GPIO_E1_START + (_nr))
+#define S5PC1XX_GPF0(_nr)	(S5PC1XX_GPIO_F0_START + (_nr))
+#define S5PC1XX_GPF1(_nr)	(S5PC1XX_GPIO_F1_START + (_nr))
+#define S5PC1XX_GPF2(_nr)	(S5PC1XX_GPIO_F2_START + (_nr))
+#define S5PC1XX_GPF3(_nr)	(S5PC1XX_GPIO_F3_START + (_nr))
+#define S5PC1XX_GPG0(_nr)	(S5PC1XX_GPIO_G0_START + (_nr))
+#define S5PC1XX_GPG1(_nr)	(S5PC1XX_GPIO_G1_START + (_nr))
+#define S5PC1XX_GPG2(_nr)	(S5PC1XX_GPIO_G2_START + (_nr))
+#define S5PC1XX_GPG3(_nr)	(S5PC1XX_GPIO_G3_START + (_nr))
+#define S5PC1XX_GPH0(_nr)	(S5PC1XX_GPIO_H0_START + (_nr))
+#define S5PC1XX_GPH1(_nr)	(S5PC1XX_GPIO_H1_START + (_nr))
+#define S5PC1XX_GPH2(_nr)	(S5PC1XX_GPIO_H2_START + (_nr))
+#define S5PC1XX_GPH3(_nr)	(S5PC1XX_GPIO_H3_START + (_nr))
+#define S5PC1XX_GPI(_nr)	(S5PC1XX_GPIO_I_START + (_nr))
+#define S5PC1XX_GPJ0(_nr)	(S5PC1XX_GPIO_J0_START + (_nr))
+#define S5PC1XX_GPJ1(_nr)	(S5PC1XX_GPIO_J1_START + (_nr))
+#define S5PC1XX_GPJ2(_nr)	(S5PC1XX_GPIO_J2_START + (_nr))
+#define S5PC1XX_GPJ3(_nr)	(S5PC1XX_GPIO_J3_START + (_nr))
+#define S5PC1XX_GPJ4(_nr)	(S5PC1XX_GPIO_J4_START + (_nr))
+#define S5PC1XX_GPK0(_nr)	(S5PC1XX_GPIO_K0_START + (_nr))
+#define S5PC1XX_GPK1(_nr)	(S5PC1XX_GPIO_K1_START + (_nr))
+#define S5PC1XX_GPK2(_nr)	(S5PC1XX_GPIO_K2_START + (_nr))
+#define S5PC1XX_GPK3(_nr)	(S5PC1XX_GPIO_K3_START + (_nr))
+#define S5PC1XX_MP00(_nr)	(S5PC1XX_GPIO_MP00_START + (_nr))
+#define S5PC1XX_MP01(_nr)	(S5PC1XX_GPIO_MP01_START + (_nr))
+#define S5PC1XX_MP02(_nr)	(S5PC1XX_GPIO_MP02_START + (_nr))
+#define S5PC1XX_MP03(_nr)	(S5PC1XX_GPIO_MP03_START + (_nr))
+#define S5PC1XX_MP04(_nr)	(S5PC1XX_GPIO_MP04_START + (_nr))
+
+/* the end of the S5PC1XX specific gpios */
+#define S5PC1XX_GPIO_END	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
+#define S3C_GPIO_END		S5PC1XX_GPIO_END
+
+/* define the number of gpios we need to the one after the MP04() range */
+#define ARCH_NR_GPIOS	(S5PC1XX_MP04(S5PC1XX_GPIO_MP04_NR) + 1)
+
+#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s5pc100/include/mach/hardware.h b/arch/arm/mach-s5pc100/include/mach/hardware.h
new file mode 100644
index 0000000..6b38618
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/hardware.h
@@ -0,0 +1,14 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/hardware.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - Hardware support
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
new file mode 100644
index 0000000..622720d
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -0,0 +1,14 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/irqs.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - IRQ definitions
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
new file mode 100644
index 0000000..9e9f391
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -0,0 +1,75 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/map.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * Based on mach-s3c6400/include/mach/map.h
+ *
+ * S5PC1XX - Memory map definitions
+ *
+ * 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 __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+
+
+/* Chip ID */
+#define S5PC100_PA_CHIPID	(0xE0000000)
+#define S5PC1XX_PA_CHIPID	S5PC100_PA_CHIPID
+#define S5PC1XX_VA_CHIPID	S3C_VA_SYS
+
+/* System */
+#define S5PC100_PA_SYS		(0xE0100000)
+#define S5PC100_PA_CLK		(S5PC100_PA_SYS + 0x0)
+#define S5PC100_PA_PWR		(S5PC100_PA_SYS + 0x8000)
+#define S5PC1XX_PA_CLK		S5PC100_PA_CLK
+#define S5PC1XX_PA_PWR		S5PC100_PA_PWR
+#define S5PC1XX_VA_CLK		(S3C_VA_SYS + 0x10000)
+#define S5PC1XX_VA_PWR		(S3C_VA_SYS + 0x20000)
+
+/* Interrupt */
+#define S5PC100_PA_VIC		(0xE4000000)
+#define S5PC100_VA_VIC		S3C_VA_IRQ
+#define S5PC100_PA_VIC_OFFSET	0x100000
+#define S5PC100_VA_VIC_OFFSET	0x10000
+#define S5PC1XX_PA_VIC(x)	(S5PC100_PA_VIC + ((x) * S5PC100_PA_VIC_OFFSET))
+#define S5PC1XX_VA_VIC(x)	(S5PC100_VA_VIC + ((x) * S5PC100_VA_VIC_OFFSET))
+
+/* Timer */
+#define S5PC100_PA_TIMER	(0xEA000000)
+#define S5PC1XX_PA_TIMER	S5PC100_PA_TIMER
+#define S5PC1XX_VA_TIMER	S3C_VA_TIMER
+
+/* UART */
+#define S5PC100_PA_UART		(0xEC000000)
+#define S5PC1XX_PA_UART		S5PC100_PA_UART
+#define S5PC1XX_VA_UART		S3C_VA_UART
+
+/* IIC */
+#define S5PC100_PA_IIC		(0xEC100000)
+
+/* ETC */
+#define S5PC100_PA_SDRAM	(0x20000000)
+
+/* compatibility defines. */
+#define S3C_PA_UART		S5PC100_PA_UART
+#define S3C_PA_UART0		(S5PC100_PA_UART + 0x0)
+#define S3C_PA_UART1		(S5PC100_PA_UART + 0x400)
+#define S3C_PA_UART2		(S5PC100_PA_UART + 0x800)
+#define S3C_PA_UART3		(S5PC100_PA_UART + 0xC00)
+#define S3C_VA_UART0		(S3C_VA_UART + 0x0)
+#define S3C_VA_UART1		(S3C_VA_UART + 0x400)
+#define S3C_VA_UART2		(S3C_VA_UART + 0x800)
+#define S3C_VA_UART3		(S3C_VA_UART + 0xC00)
+#define S3C_UART_OFFSET		0x400
+#define S3C_VA_VIC0		(S3C_VA_IRQ + 0x0)
+#define S3C_VA_VIC1		(S3C_VA_IRQ + 0x10000)
+#define S3C_VA_VIC2		(S3C_VA_IRQ + 0x20000)
+#define S3C_PA_IIC		S5PC100_PA_IIC
+
+#endif /* __ASM_ARCH_C100_MAP_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-s5pc100/include/mach/memory.h
new file mode 100644
index 0000000..4b60d18
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/memory.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s5pc100/include/mach/memory.h
+ *
+ * Copyright 2008 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * Based on mach-s3c6400/include/mach/memory.h
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET     	UL(0x20000000)
+
+#endif
diff --git a/arch/arm/mach-s5pc100/include/mach/pwm-clock.h b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
new file mode 100644
index 0000000..b34d2f7
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
@@ -0,0 +1,56 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - pwm clock and timer support
+ *
+ * Based on mach-s3c6400/include/mach/pwm-clock.h
+ */
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+	return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+	return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+	return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+	return ilog2(div);
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-irq.h b/arch/arm/mach-s5pc100/include/mach/regs-irq.h
new file mode 100644
index 0000000..751ac15
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-irq.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/regs-irq.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX - IRQ register definitions
+ *
+ * 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 __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <mach/map.h>
+#include <asm/hardware/vic.h>
+
+/* interrupt controller */
+#define S5PC1XX_VIC0REG(x)          		((x) + S5PC1XX_VA_VIC(0))
+#define S5PC1XX_VIC1REG(x)          		((x) + S5PC1XX_VA_VIC(1))
+#define S5PC1XX_VIC2REG(x)         		((x) + S5PC1XX_VA_VIC(2))
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
new file mode 100644
index 0000000..e390143
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/system.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/system.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX - system implementation
+ *
+ * Based on mach-s3c6400/include/mach/system.h
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+static void arch_idle(void)
+{
+	/* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+	/* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/tick.h b/arch/arm/mach-s5pc100/include/mach/tick.h
new file mode 100644
index 0000000..d3de0f3
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/tick.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/tick.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S3C64XX - Timer tick support definitions
+ *
+ * Based on mach-s3c6400/include/mach/tick.h
+ *
+ * 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 __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+/* note, the timer interrutps turn up in 2 places, the vic and then
+ * the timer block. We take the VIC as the base at the moment.
+ */
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+	u32 pend = __raw_readl(S3C_VA_VIC0 + VIC_RAW_STATUS);
+	return pend & 1 << (IRQ_TIMER4 - S5PC1XX_IRQ_VIC0(0));
+}
+
+#define TICK_MAX	(0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/uncompress.h b/arch/arm/mach-s5pc100/include/mach/uncompress.h
new file mode 100644
index 0000000..01ccf53
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/uncompress.h
@@ -0,0 +1,28 @@
+/* arch/arm/mach-s5pc100/include/mach/uncompress.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - uncompress code
+ *
+ * Based on mach-s3c6400/include/mach/uncompress.h
+ *
+ * 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+	/* we do not need to do any cpu detection here at the moment. */
+	fifo_mask = S3C2440_UFSTAT_TXMASK;
+	fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
new file mode 100644
index 0000000..214093c
--- /dev/null
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -0,0 +1,103 @@
+/* linux/arch/arm/mach-s5pc100/mach-smdkc100.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Author: Byungho Min <bhmin@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.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/s5pc100.h>
+
+#define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
+	[0] = {
+		.hwport	     = 0,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[1] = {
+		.hwport	     = 1,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[2] = {
+		.hwport	     = 2,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+	[3] = {
+		.hwport	     = 3,
+		.flags	     = 0,
+		.ucon	     = 0x3c5,
+		.ulcon	     = 0x03,
+		.ufcon	     = 0x51,
+	},
+};
+
+static struct map_desc smdkc100_iodesc[] = {};
+
+static struct platform_device *smdkc100_devices[] __initdata = {
+};
+
+static void __init smdkc100_map_io(void)
+{
+	s5pc1xx_init_io(smdkc100_iodesc, ARRAY_SIZE(smdkc100_iodesc));
+	s3c24xx_init_clocks(12000000);
+	s3c24xx_init_uarts(smdkc100_uartcfgs, ARRAY_SIZE(smdkc100_uartcfgs));
+}
+
+static void __init smdkc100_machine_init(void)
+{
+	platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
+}
+
+MACHINE_START(SMDKC100, "SMDKC100")
+	/* Maintainer: Byungho Min <bhmin@samsung.com> */
+	.phys_io	= S5PC1XX_PA_UART & 0xfff00000,
+	.io_pg_offst	= (((u32)S5PC1XX_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= S5PC100_PA_SDRAM + 0x100,
+
+	.init_irq	= s5pc100_init_irq,
+	.map_io		= smdkc100_map_io,
+	.init_machine	= smdkc100_machine_init,
+	.timer		= &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h
index 3959b20..28c2cf5 100644
--- a/arch/arm/mach-sa1100/include/mach/assabet.h
+++ b/arch/arm/mach-sa1100/include/mach/assabet.h
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-sa1100/include/mach/assabet.h
  *
- * Created 2000/06/05 by Nicolas Pitre <nico@cam.org>
+ * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
  *
  * This file contains the hardware specific definitions for Assabet
  * Only include this file from SA1100-specific files.
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
index 6071182..99f5856 100644
--- a/arch/arm/mach-sa1100/include/mach/hardware.h
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-sa1100/include/mach/hardware.h
  *
- * Copyright (C) 1998 Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 1998 Nicolas Pitre <nico@fluxnic.net>
  *
  * This file contains the hardware definitions for SA1100 architecture
  *
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
index e9f8eed..d5277f9 100644
--- a/arch/arm/mach-sa1100/include/mach/memory.h
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-sa1100/include/mach/memory.h
  *
- * Copyright (C) 1999-2000 Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 1999-2000 Nicolas Pitre <nico@fluxnic.net>
  */
 
 #ifndef __ASM_ARCH_MEMORY_H
diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h
index d3f044f..ffe2bc4 100644
--- a/arch/arm/mach-sa1100/include/mach/neponset.h
+++ b/arch/arm/mach-sa1100/include/mach/neponset.h
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-sa1100/include/mach/neponset.h
  *
- * Created 2000/06/05 by Nicolas Pitre <nico@cam.org>
+ * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
  *
  * This file contains the hardware specific definitions for Assabet
  * Only include this file from SA1100-specific files.
diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h
index 942b153..ba9da9f 100644
--- a/arch/arm/mach-sa1100/include/mach/system.h
+++ b/arch/arm/mach-sa1100/include/mach/system.h
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-sa1100/include/mach/system.h
  *
- * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
  */
 #include <mach/hardware.h>
 
diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h
index 714160b..6cb39dd 100644
--- a/arch/arm/mach-sa1100/include/mach/uncompress.h
+++ b/arch/arm/mach-sa1100/include/mach/uncompress.h
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-sa1100/include/mach/uncompress.h
  *
- * (C) 1999 Nicolas Pitre <nico@cam.org>
+ * (C) 1999 Nicolas Pitre <nico@fluxnic.net>
  *
  * Reorganised to be machine independent.
  */
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 111cce6..c83fdc8 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -15,7 +15,7 @@
  * 			Save more value for the resume function! Support
  * 			Bitsy/Assabet/Freebird board
  *
- * 2001-08-29:	Nicolas Pitre <nico@cam.org>
+ * 2001-08-29:	Nicolas Pitre <nico@fluxnic.net>
  * 			Cleaned up, pushed platform dependent stuff
  * 			in the platform specific files.
  *
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 711c029..95d92e8 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -4,7 +4,7 @@
  * Copyright (C) 1998 Deborah Wallach.
  * Twiddles  (C) 1999 Hugo Fiennes <hugo@empeg.com>
  *
- * 2000/03/29 (C) Nicolas Pitre <nico@cam.org>
+ * 2000/03/29 (C) Nicolas Pitre <nico@fluxnic.net>
  *	Rewritten: big cleanup, much simpler, better HZ accuracy.
  *
  */
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
index 3138d39..585cc01 100644
--- a/arch/arm/mach-u300/mmc.c
+++ b/arch/arm/mach-u300/mmc.c
@@ -156,6 +156,8 @@ int __devinit mmc_init(struct amba_device *adev)
 	mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29;
 	mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd;
 	mmci_card->mmc0_plat_data.status = mmc_status;
+	mmci_card->mmc0_plat_data.gpio_wp = -1;
+	mmci_card->mmc0_plat_data.gpio_cd = -1;
 
 	mmcsd_device->platform_data = (void *) &mmci_card->mmc0_plat_data;
 
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 31093af..975eae4 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/clcd.h>
+#include <linux/amba/pl061.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/cnt32_to_63.h>
@@ -371,6 +372,8 @@ unsigned int mmc_status(struct device *dev)
 static struct mmc_platform_data mmc0_plat_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.status		= mmc_status,
+	.gpio_wp	= -1,
+	.gpio_cd	= -1,
 };
 
 /*
@@ -705,6 +708,16 @@ static struct clcd_board clcd_plat_data = {
 	.remove		= versatile_clcd_remove,
 };
 
+static struct pl061_platform_data gpio0_plat_data = {
+	.gpio_base	= 0,
+	.irq_base	= IRQ_GPIO0_START,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+	.gpio_base	= 8,
+	.irq_base	= IRQ_GPIO1_START,
+};
+
 #define AACI_IRQ	{ IRQ_AACI, NO_IRQ }
 #define AACI_DMA	{ 0x80, 0x81 }
 #define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_SIC_MMCI0B }
@@ -767,8 +780,8 @@ AMBA_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data);
 AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL);
 AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);
 AMBA_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    NULL);
-AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    NULL);
+AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    &gpio1_plat_data);
 AMBA_DEVICE(rtc,   "dev:e8",  RTC,      NULL);
 AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);
 AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);
diff --git a/arch/arm/mach-versatile/include/mach/gpio.h b/arch/arm/mach-versatile/include/mach/gpio.h
new file mode 100644
index 0000000..94ff276
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+#define gpio_to_irq	__gpio_to_irq
diff --git a/arch/arm/mach-versatile/include/mach/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h
index 9bfdb30..bf44c61 100644
--- a/arch/arm/mach-versatile/include/mach/irqs.h
+++ b/arch/arm/mach-versatile/include/mach/irqs.h
@@ -122,4 +122,13 @@
 #define IRQ_SIC_PCI3		(IRQ_SIC_START + SIC_INT_PCI3)
 #define IRQ_SIC_END		63
 
-#define NR_IRQS			64
+#define IRQ_GPIO0_START		(IRQ_SIC_END + 1)
+#define IRQ_GPIO0_END		(IRQ_GPIO0_START + 31)
+#define IRQ_GPIO1_START		(IRQ_GPIO0_END + 1)
+#define IRQ_GPIO1_END		(IRQ_GPIO1_START + 31)
+#define IRQ_GPIO2_START		(IRQ_GPIO1_END + 1)
+#define IRQ_GPIO2_END		(IRQ_GPIO2_START + 31)
+#define IRQ_GPIO3_START		(IRQ_GPIO2_END + 1)
+#define IRQ_GPIO3_END		(IRQ_GPIO3_START + 31)
+
+#define NR_IRQS			(IRQ_GPIO3_END + 1)
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index aa051c0..9af8d81 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -23,6 +23,7 @@
 #include <linux/device.h>
 #include <linux/sysdev.h>
 #include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
 #include <linux/io.h>
 
 #include <mach/hardware.h>
@@ -43,6 +44,18 @@
 static struct mmc_platform_data mmc1_plat_data = {
 	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
 	.status		= mmc_status,
+	.gpio_wp	= -1,
+	.gpio_cd	= -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+	.gpio_base	= 16,
+	.irq_base	= IRQ_GPIO2_START,
+};
+
+static struct pl061_platform_data gpio3_plat_data = {
+	.gpio_base	= 24,
+	.irq_base	= IRQ_GPIO3_START,
 };
 
 #define UART3_IRQ	{ IRQ_SIC_UART3, NO_IRQ }
@@ -70,8 +83,8 @@ AMBA_DEVICE(sci1,  "fpga:0a", SCI1,     NULL);
 AMBA_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data);
 
 /* DevChip Primecells */
-AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    NULL);
-AMBA_DEVICE(gpio3, "dev:e7",  GPIO3,    NULL);
+AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    &gpio2_plat_data);
+AMBA_DEVICE(gpio3, "dev:e7",  GPIO3,    &gpio3_plat_data);
 
 static struct amba_device *amba_devs[] __initdata = {
 	&uart3_device,
diff --git a/arch/arm/mach-w90x900/Kconfig b/arch/arm/mach-w90x900/Kconfig
index 8e4178f..69bab32 100644
--- a/arch/arm/mach-w90x900/Kconfig
+++ b/arch/arm/mach-w90x900/Kconfig
@@ -5,6 +5,16 @@ config CPU_W90P910
 	help
 	  Support for W90P910 of Nuvoton W90X900 CPUs.
 
+config CPU_NUC950
+	bool
+	help
+	  Support for NUCP950 of Nuvoton NUC900 CPUs.
+
+config CPU_NUC960
+	bool
+	help
+	  Support for NUCP960 of Nuvoton NUC900 CPUs.
+
 menu "W90P910 Machines"
 
 config MACH_W90P910EVB
@@ -16,4 +26,24 @@ config MACH_W90P910EVB
 
 endmenu
 
+menu "NUC950 Machines"
+
+config MACH_W90P950EVB
+	bool "Nuvoton NUC950 Evaluation Board"
+	select CPU_NUC950
+	help
+	   Say Y here if you are using the Nuvoton NUC950EVB
+
+endmenu
+
+menu "NUC960 Machines"
+
+config MACH_W90N960EVB
+	bool "Nuvoton NUC960 Evaluation Board"
+	select CPU_NUC960
+	help
+	   Say Y here if you are using the Nuvoton NUC960EVB
+
+endmenu
+
 endif
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile
index d50c94f..828c032 100644
--- a/arch/arm/mach-w90x900/Makefile
+++ b/arch/arm/mach-w90x900/Makefile
@@ -4,12 +4,16 @@
 
 # Object file lists.
 
-obj-y				:= irq.o time.o mfp-w90p910.o gpio.o clock.o
-
+obj-y				:= irq.o time.o mfp.o gpio.o clock.o
+obj-y				+= clksel.o dev.o cpu.o
 # W90X900 CPU support files
 
-obj-$(CONFIG_CPU_W90P910)	+= w90p910.o
+obj-$(CONFIG_CPU_W90P910)	+= nuc910.o
+obj-$(CONFIG_CPU_NUC950)	+= nuc950.o
+obj-$(CONFIG_CPU_NUC960)	+= nuc960.o
 
 # machine support
 
-obj-$(CONFIG_MACH_W90P910EVB)	+= mach-w90p910evb.o
+obj-$(CONFIG_MACH_W90P910EVB)	+= mach-nuc910evb.o
+obj-$(CONFIG_MACH_W90P950EVB)	+= mach-nuc950evb.o
+obj-$(CONFIG_MACH_W90N960EVB)	+= mach-nuc960evb.o
diff --git a/arch/arm/mach-w90x900/clksel.c b/arch/arm/mach-w90x900/clksel.c
new file mode 100644
index 0000000..3de4a52
--- /dev/null
+++ b/arch/arm/mach-w90x900/clksel.c
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/arm/mach-w90x900/clksel.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+
+#define PLL0		0x00
+#define PLL1		0x01
+#define OTHER		0x02
+#define EXT		0x03
+#define MSOFFSET	0x0C
+#define ATAOFFSET	0x0a
+#define LCDOFFSET	0x06
+#define AUDOFFSET	0x04
+#define CPUOFFSET	0x00
+
+static DEFINE_MUTEX(clksel_sem);
+
+static void clock_source_select(const char *dev_id, unsigned int clkval)
+{
+	unsigned int clksel, offset;
+
+	clksel = __raw_readl(REG_CLKSEL);
+
+	if (strcmp(dev_id, "nuc900-ms") == 0)
+		offset = MSOFFSET;
+	else if (strcmp(dev_id, "nuc900-atapi") == 0)
+		offset = ATAOFFSET;
+	else if (strcmp(dev_id, "nuc900-lcd") == 0)
+		offset = LCDOFFSET;
+	else if (strcmp(dev_id, "nuc900-audio") == 0)
+		offset = AUDOFFSET;
+	else
+		offset = CPUOFFSET;
+
+	clksel &= ~(0x03 << offset);
+	clksel |= (clkval << offset);
+
+	__raw_writel(clksel, REG_CLKSEL);
+}
+
+void nuc900_clock_source(struct device *dev, unsigned char *src)
+{
+	unsigned int clkval;
+	const char *dev_id;
+
+	BUG_ON(!src);
+	clkval = 0;
+
+	mutex_lock(&clksel_sem);
+
+	if (dev)
+		dev_id = dev_name(dev);
+	else
+		dev_id = "cpufreq";
+
+	if (strcmp(src, "pll0") == 0)
+		clkval = PLL0;
+	else if (strcmp(src, "pll1") == 0)
+		clkval = PLL1;
+	else if (strcmp(src, "ext") == 0)
+		clkval = EXT;
+	else if (strcmp(src, "oth") == 0)
+		clkval = OTHER;
+
+	clock_source_select(dev_id, clkval);
+
+	mutex_unlock(&clksel_sem);
+}
+EXPORT_SYMBOL(nuc900_clock_source);
+
diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c
index f420613..b785994 100644
--- a/arch/arm/mach-w90x900/clock.c
+++ b/arch/arm/mach-w90x900/clock.c
@@ -25,6 +25,8 @@
 
 #include "clock.h"
 
+#define SUBCLK 0x24
+
 static DEFINE_SPINLOCK(clocks_lock);
 
 int clk_enable(struct clk *clk)
@@ -53,7 +55,13 @@ void clk_disable(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_disable);
 
-void w90x900_clk_enable(struct clk *clk, int enable)
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return 15000000;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void nuc900_clk_enable(struct clk *clk, int enable)
 {
 	unsigned int clocks = clk->cken;
 	unsigned long clken;
@@ -68,6 +76,22 @@ void w90x900_clk_enable(struct clk *clk, int enable)
 	__raw_writel(clken, W90X900_VA_CLKPWR);
 }
 
+void nuc900_subclk_enable(struct clk *clk, int enable)
+{
+	unsigned int clocks = clk->cken;
+	unsigned long clken;
+
+	clken = __raw_readl(W90X900_VA_CLKPWR + SUBCLK);
+
+	if (enable)
+		clken |= clocks;
+	else
+		clken &= ~clocks;
+
+	__raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
+}
+
+
 void clks_register(struct clk_lookup *clks, size_t num)
 {
 	int i;
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
index 4f27bda..f5816a0 100644
--- a/arch/arm/mach-w90x900/clock.h
+++ b/arch/arm/mach-w90x900/clock.h
@@ -12,7 +12,8 @@
 
 #include <asm/clkdev.h>
 
-void w90x900_clk_enable(struct clk *clk, int enable);
+void nuc900_clk_enable(struct clk *clk, int enable);
+void nuc900_subclk_enable(struct clk *clk, int enable);
 void clks_register(struct clk_lookup *clks, size_t num);
 
 struct clk {
@@ -23,10 +24,17 @@ struct clk {
 
 #define DEFINE_CLK(_name, _ctrlbit)			\
 struct clk clk_##_name = {				\
-		.enable	= w90x900_clk_enable,		\
+		.enable	= nuc900_clk_enable,		\
 		.cken	= (1 << _ctrlbit),		\
 	}
 
+#define DEFINE_SUBCLK(_name, _ctrlbit)			\
+struct clk clk_##_name = {				\
+		.enable	= nuc900_subclk_enable,	\
+		.cken	= (1 << _ctrlbit),		\
+	}
+
+
 #define DEF_CLKLOOK(_clk, _devname, _conname)		\
 	{						\
 		.clk		= _clk,			\
diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c
new file mode 100644
index 0000000..921cef9
--- /dev/null
+++ b/arch/arm/mach-w90x900/cpu.c
@@ -0,0 +1,212 @@
+/*
+ * linux/arch/arm/mach-w90x900/cpu.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC900 series cpu common support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ebi.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* Initial IO mappings */
+
+static struct map_desc nuc900_iodesc[] __initdata = {
+	IODESC_ENT(IRQ),
+	IODESC_ENT(GCR),
+	IODESC_ENT(UART),
+	IODESC_ENT(TIMER),
+	IODESC_ENT(EBI),
+};
+
+/* Initial clock declarations. */
+static DEFINE_CLK(lcd, 0);
+static DEFINE_CLK(audio, 1);
+static DEFINE_CLK(fmi, 4);
+static DEFINE_SUBCLK(ms, 0);
+static DEFINE_SUBCLK(sd, 1);
+static DEFINE_CLK(dmac, 5);
+static DEFINE_CLK(atapi, 6);
+static DEFINE_CLK(emc, 7);
+static DEFINE_SUBCLK(rmii, 2);
+static DEFINE_CLK(usbd, 8);
+static DEFINE_CLK(usbh, 9);
+static DEFINE_CLK(g2d, 10);;
+static DEFINE_CLK(pwm, 18);
+static DEFINE_CLK(ps2, 24);
+static DEFINE_CLK(kpi, 25);
+static DEFINE_CLK(wdt, 26);
+static DEFINE_CLK(gdma, 27);
+static DEFINE_CLK(adc, 28);
+static DEFINE_CLK(usi, 29);
+static DEFINE_CLK(ext, 0);
+
+static struct clk_lookup nuc900_clkregs[] = {
+	DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL),
+	DEF_CLKLOOK(&clk_audio, "nuc900-audio", NULL),
+	DEF_CLKLOOK(&clk_fmi, "nuc900-fmi", NULL),
+	DEF_CLKLOOK(&clk_ms, "nuc900-fmi", "MS"),
+	DEF_CLKLOOK(&clk_sd, "nuc900-fmi", "SD"),
+	DEF_CLKLOOK(&clk_dmac, "nuc900-dmac", NULL),
+	DEF_CLKLOOK(&clk_atapi, "nuc900-atapi", NULL),
+	DEF_CLKLOOK(&clk_emc, "nuc900-emc", NULL),
+	DEF_CLKLOOK(&clk_rmii, "nuc900-emc", "RMII"),
+	DEF_CLKLOOK(&clk_usbd, "nuc900-usbd", NULL),
+	DEF_CLKLOOK(&clk_usbh, "nuc900-usbh", NULL),
+	DEF_CLKLOOK(&clk_g2d, "nuc900-g2d", NULL),
+	DEF_CLKLOOK(&clk_pwm, "nuc900-pwm", NULL),
+	DEF_CLKLOOK(&clk_ps2, "nuc900-ps2", NULL),
+	DEF_CLKLOOK(&clk_kpi, "nuc900-kpi", NULL),
+	DEF_CLKLOOK(&clk_wdt, "nuc900-wdt", NULL),
+	DEF_CLKLOOK(&clk_gdma, "nuc900-gdma", NULL),
+	DEF_CLKLOOK(&clk_adc, "nuc900-adc", NULL),
+	DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
+	DEF_CLKLOOK(&clk_ext, NULL, "ext"),
+};
+
+/* Initial serial platform data */
+
+struct plat_serial8250_port nuc900_uart_data[] = {
+	NUC900_8250PORT(UART0),
+};
+
+struct platform_device nuc900_serial_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= nuc900_uart_data,
+	},
+};
+
+/*Set NUC900 series cpu frequence*/
+static int __init nuc900_set_clkval(unsigned int cpufreq)
+{
+	unsigned int pllclk, ahbclk, apbclk, val;
+
+	pllclk = 0;
+	ahbclk = 0;
+	apbclk = 0;
+
+	switch (cpufreq) {
+	case 66:
+		pllclk = PLL_66MHZ;
+		ahbclk = AHB_CPUCLK_1_1;
+		apbclk = APB_AHB_1_2;
+		break;
+
+	case 100:
+		pllclk = PLL_100MHZ;
+		ahbclk = AHB_CPUCLK_1_1;
+		apbclk = APB_AHB_1_2;
+		break;
+
+	case 120:
+		pllclk = PLL_120MHZ;
+		ahbclk = AHB_CPUCLK_1_2;
+		apbclk = APB_AHB_1_2;
+		break;
+
+	case 166:
+		pllclk = PLL_166MHZ;
+		ahbclk = AHB_CPUCLK_1_2;
+		apbclk = APB_AHB_1_2;
+		break;
+
+	case 200:
+		pllclk = PLL_200MHZ;
+		ahbclk = AHB_CPUCLK_1_2;
+		apbclk = APB_AHB_1_2;
+		break;
+	}
+
+	__raw_writel(pllclk, REG_PLLCON0);
+
+	val = __raw_readl(REG_CLKDIV);
+	val &= ~(0x03 << 24 | 0x03 << 26);
+	val |= (ahbclk << 24 | apbclk << 26);
+	__raw_writel(val, REG_CLKDIV);
+
+	return 	0;
+}
+static int __init nuc900_set_cpufreq(char *str)
+{
+	unsigned long cpufreq, val;
+
+	if (!*str)
+		return 0;
+
+	strict_strtoul(str, 0, &cpufreq);
+
+	nuc900_clock_source(NULL, "ext");
+
+	nuc900_set_clkval(cpufreq);
+
+	mdelay(1);
+
+	val = __raw_readl(REG_CKSKEW);
+	val &= ~0xff;
+	val |= DEFAULTSKEW;
+	__raw_writel(val, REG_CKSKEW);
+
+	nuc900_clock_source(NULL, "pll0");
+
+	return 1;
+}
+
+__setup("cpufreq=", nuc900_set_cpufreq);
+
+/*Init NUC900 evb io*/
+
+void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size)
+{
+	unsigned long idcode = 0x0;
+
+	iotable_init(mach_desc, mach_size);
+	iotable_init(nuc900_iodesc, ARRAY_SIZE(nuc900_iodesc));
+
+	idcode = __raw_readl(NUC900PDID);
+	if (idcode == NUC910_CPUID)
+		printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
+	else if (idcode == NUC920_CPUID)
+		printk(KERN_INFO "CPU type 0x%08lx is NUC920\n", idcode);
+	else if (idcode == NUC950_CPUID)
+		printk(KERN_INFO "CPU type 0x%08lx is NUC950\n", idcode);
+	else if (idcode == NUC960_CPUID)
+		printk(KERN_INFO "CPU type 0x%08lx is NUC960\n", idcode);
+}
+
+/*Init NUC900 clock*/
+
+void __init nuc900_init_clocks(void)
+{
+	clks_register(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
+}
+
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
index 57b5dba..4d58ba1 100644
--- a/arch/arm/mach-w90x900/cpu.h
+++ b/arch/arm/mach-w90x900/cpu.h
@@ -6,7 +6,7 @@
  * Copyright (c) 2008 Nuvoton technology corporation
  * All rights reserved.
  *
- * Header file for W90X900 CPU support
+ * Header file for NUC900 CPU support
  *
  * Wan ZongShun <mcuos.com@gmail.com>
  *
@@ -24,29 +24,7 @@
        .type    = MT_DEVICE,                           \
 }
 
-/*Cpu identifier register*/
-
-#define W90X900PDID	W90X900_VA_GCR
-#define W90P910_CPUID	0x02900910
-#define W90P920_CPUID	0x02900920
-#define W90P950_CPUID	0x02900950
-#define W90N960_CPUID	0x02900960
-
-struct w90x900_uartcfg;
-struct map_desc;
-struct sys_timer;
-
-/* core initialisation functions */
-
-extern void w90x900_init_irq(void);
-extern void w90p910_init_io(struct map_desc *mach_desc, int size);
-extern void w90p910_init_uarts(struct w90x900_uartcfg *cfg, int no);
-extern void w90p910_init_clocks(void);
-extern void w90p910_map_io(struct map_desc *mach_desc, int size);
-extern struct platform_device w90p910_serial_device;
-extern struct sys_timer w90x900_timer;
-
-#define W90X900_8250PORT(name)					\
+#define NUC900_8250PORT(name)					\
 {								\
 	.membase	= name##_BA,				\
 	.mapbase	= name##_PA,				\
@@ -56,3 +34,26 @@ extern struct sys_timer w90x900_timer;
 	.iotype		= UPIO_MEM,				\
 	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,	\
 }
+
+/*Cpu identifier register*/
+
+#define NUC900PDID	W90X900_VA_GCR
+#define NUC910_CPUID	0x02900910
+#define NUC920_CPUID	0x02900920
+#define NUC950_CPUID	0x02900950
+#define NUC960_CPUID	0x02900960
+
+/* extern file from cpu.c */
+
+extern void nuc900_clock_source(struct device *dev, unsigned char *src);
+extern void nuc900_init_clocks(void);
+extern void nuc900_map_io(struct map_desc *mach_desc, int mach_size);
+extern void nuc900_board_init(struct platform_device **device, int size);
+
+/* for either public between 910 and 920, or between 920 and 950 */
+
+extern struct platform_device nuc900_serial_device;
+extern struct platform_device nuc900_device_fmi;
+extern struct platform_device nuc900_device_kpi;
+extern struct platform_device nuc900_device_rtc;
+extern struct platform_device nuc900_device_ts;
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
new file mode 100644
index 0000000..2a6f98d
--- /dev/null
+++ b/arch/arm/mach-w90x900/dev.c
@@ -0,0 +1,389 @@
+/*
+ * linux/arch/arm/mach-w90x900/dev.c
+ *
+ * Copyright (C) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-serial.h>
+#include <mach/map.h>
+
+#include "cpu.h"
+
+/*NUC900 evb norflash driver data */
+
+#define NUC900_FLASH_BASE	0xA0000000
+#define NUC900_FLASH_SIZE	0x400000
+#define SPIOFFSET		0x200
+#define SPIOREG_SIZE		0x100
+
+static struct mtd_partition nuc900_flash_partitions[] = {
+	{
+		.name	=	"NOR Partition 1 for kernel (960K)",
+		.size	=	0xF0000,
+		.offset	=	0x10000,
+	},
+	{
+		.name	=	"NOR Partition 2 for image (1M)",
+		.size	=	0x100000,
+		.offset	=	0x100000,
+	},
+	{
+		.name	=	"NOR Partition 3 for user (2M)",
+		.size	=	0x200000,
+		.offset	=	0x00200000,
+	}
+};
+
+static struct physmap_flash_data nuc900_flash_data = {
+	.width		=	2,
+	.parts		=	nuc900_flash_partitions,
+	.nr_parts	=	ARRAY_SIZE(nuc900_flash_partitions),
+};
+
+static struct resource nuc900_flash_resources[] = {
+	{
+		.start	=	NUC900_FLASH_BASE,
+		.end	=	NUC900_FLASH_BASE + NUC900_FLASH_SIZE - 1,
+		.flags	=	IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device nuc900_flash_device = {
+	.name		=	"physmap-flash",
+	.id		=	0,
+	.dev		= {
+				.platform_data = &nuc900_flash_data,
+			},
+	.resource	=	nuc900_flash_resources,
+	.num_resources	=	ARRAY_SIZE(nuc900_flash_resources),
+};
+
+/* USB EHCI Host Controller */
+
+static struct resource nuc900_usb_ehci_resource[] = {
+	[0] = {
+		.start = W90X900_PA_USBEHCIHOST,
+		.end   = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBH,
+		.end   = IRQ_USBH,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 nuc900_device_usb_ehci_dmamask = 0xffffffffUL;
+
+static struct platform_device nuc900_device_usb_ehci = {
+	.name		  = "nuc900-ehci",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(nuc900_usb_ehci_resource),
+	.resource	  = nuc900_usb_ehci_resource,
+	.dev              = {
+		.dma_mask = &nuc900_device_usb_ehci_dmamask,
+		.coherent_dma_mask = 0xffffffffUL
+	}
+};
+
+/* USB OHCI Host Controller */
+
+static struct resource nuc900_usb_ohci_resource[] = {
+	[0] = {
+		.start = W90X900_PA_USBOHCIHOST,
+		.end   = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBH,
+		.end   = IRQ_USBH,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 nuc900_device_usb_ohci_dmamask = 0xffffffffUL;
+static struct platform_device nuc900_device_usb_ohci = {
+	.name		  = "nuc900-ohci",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(nuc900_usb_ohci_resource),
+	.resource	  = nuc900_usb_ohci_resource,
+	.dev              = {
+		.dma_mask = &nuc900_device_usb_ohci_dmamask,
+		.coherent_dma_mask = 0xffffffffUL
+	}
+};
+
+/* USB Device (Gadget)*/
+
+static struct resource nuc900_usbgadget_resource[] = {
+	[0] = {
+		.start = W90X900_PA_USBDEV,
+		.end   = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_USBD,
+		.end   = IRQ_USBD,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device nuc900_device_usbgadget = {
+	.name		= "nuc900-usbgadget",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(nuc900_usbgadget_resource),
+	.resource	= nuc900_usbgadget_resource,
+};
+
+/* MAC device */
+
+static struct resource nuc900_emc_resource[] = {
+	[0] = {
+		.start = W90X900_PA_EMC,
+		.end   = W90X900_PA_EMC + W90X900_SZ_EMC - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_EMCTX,
+		.end   = IRQ_EMCTX,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start = IRQ_EMCRX,
+		.end   = IRQ_EMCRX,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static u64 nuc900_device_emc_dmamask = 0xffffffffUL;
+static struct platform_device nuc900_device_emc = {
+	.name		= "nuc900-emc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(nuc900_emc_resource),
+	.resource	= nuc900_emc_resource,
+	.dev              = {
+		.dma_mask = &nuc900_device_emc_dmamask,
+		.coherent_dma_mask = 0xffffffffUL
+	}
+};
+
+/* SPI device */
+
+static struct resource nuc900_spi_resource[] = {
+	[0] = {
+		.start = W90X900_PA_I2C + SPIOFFSET,
+		.end   = W90X900_PA_I2C + SPIOFFSET + SPIOREG_SIZE - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_SSP,
+		.end   = IRQ_SSP,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device nuc900_device_spi = {
+	.name		= "nuc900-spi",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(nuc900_spi_resource),
+	.resource	= nuc900_spi_resource,
+};
+
+/* spi device, spi flash info */
+
+static struct mtd_partition nuc900_spi_flash_partitions[] = {
+	{
+		.name = "bootloader(spi)",
+		.size = 0x0100000,
+		.offset = 0,
+	},
+};
+
+static struct flash_platform_data nuc900_spi_flash_data = {
+	.name = "m25p80",
+	.parts =  nuc900_spi_flash_partitions,
+	.nr_parts = ARRAY_SIZE(nuc900_spi_flash_partitions),
+	.type = "w25x16",
+};
+
+static struct spi_board_info nuc900_spi_board_info[] __initdata = {
+	{
+		.modalias = "m25p80",
+		.max_speed_hz = 20000000,
+		.bus_num = 0,
+		.chip_select = 1,
+		.platform_data = &nuc900_spi_flash_data,
+		.mode = SPI_MODE_0,
+	},
+};
+
+/* WDT Device */
+
+static struct resource nuc900_wdt_resource[] = {
+	[0] = {
+		.start = W90X900_PA_TIMER,
+		.end   = W90X900_PA_TIMER + W90X900_SZ_TIMER - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_WDT,
+		.end   = IRQ_WDT,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device nuc900_device_wdt = {
+	.name		= "nuc900-wdt",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(nuc900_wdt_resource),
+	.resource	= nuc900_wdt_resource,
+};
+
+/*
+ * public device definition between 910 and 920, or 910
+ * and 950 or 950 and 960...,their dev platform register
+ * should be in specific file such as nuc950, nuc960 c
+ * files rather than the public dev.c file here. so the
+ * corresponding platform_device definition should not be
+ * static.
+*/
+
+/* RTC controller*/
+
+static struct resource nuc900_rtc_resource[] = {
+	[0] = {
+		.start = W90X900_PA_RTC,
+		.end   = W90X900_PA_RTC + 0xff,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_RTC,
+		.end   = IRQ_RTC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device nuc900_device_rtc = {
+	.name		= "nuc900-rtc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(nuc900_rtc_resource),
+	.resource	= nuc900_rtc_resource,
+};
+
+/*TouchScreen controller*/
+
+static struct resource nuc900_ts_resource[] = {
+	[0] = {
+		.start = W90X900_PA_ADC,
+		.end   = W90X900_PA_ADC + W90X900_SZ_ADC-1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_ADC,
+		.end   = IRQ_ADC,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device nuc900_device_ts = {
+	.name		= "nuc900-ts",
+	.id		= -1,
+	.resource	= nuc900_ts_resource,
+	.num_resources	= ARRAY_SIZE(nuc900_ts_resource),
+};
+
+/* FMI Device */
+
+static struct resource nuc900_fmi_resource[] = {
+	[0] = {
+		.start = W90X900_PA_FMI,
+		.end   = W90X900_PA_FMI + W90X900_SZ_FMI - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_FMI,
+		.end   = IRQ_FMI,
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+struct platform_device nuc900_device_fmi = {
+	.name		= "nuc900-fmi",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(nuc900_fmi_resource),
+	.resource	= nuc900_fmi_resource,
+};
+
+/* KPI controller*/
+
+static struct resource nuc900_kpi_resource[] = {
+	[0] = {
+		.start = W90X900_PA_KPI,
+		.end   = W90X900_PA_KPI + W90X900_SZ_KPI - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_KPI,
+		.end   = IRQ_KPI,
+		.flags = IORESOURCE_IRQ,
+	}
+
+};
+
+struct platform_device nuc900_device_kpi = {
+	.name		= "nuc900-kpi",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(nuc900_kpi_resource),
+	.resource	= nuc900_kpi_resource,
+};
+
+/*Here should be your evb resourse,such as LCD*/
+
+static struct platform_device *nuc900_public_dev[] __initdata = {
+	&nuc900_serial_device,
+	&nuc900_flash_device,
+	&nuc900_device_usb_ehci,
+	&nuc900_device_usb_ohci,
+	&nuc900_device_usbgadget,
+	&nuc900_device_emc,
+	&nuc900_device_spi,
+	&nuc900_device_wdt,
+};
+
+/* Provide adding specific CPU platform devices API */
+
+void __init nuc900_board_init(struct platform_device **device, int size)
+{
+	platform_add_devices(device, size);
+	platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
+	spi_register_board_info(nuc900_spi_board_info,
+					ARRAY_SIZE(nuc900_spi_board_info));
+}
+
diff --git a/arch/arm/mach-w90x900/gpio.c b/arch/arm/mach-w90x900/gpio.c
index c72e0df..ba05aec 100644
--- a/arch/arm/mach-w90x900/gpio.c
+++ b/arch/arm/mach-w90x900/gpio.c
@@ -1,7 +1,7 @@
 /*
- * linux/arch/arm/mach-w90p910/gpio.c
+ * linux/arch/arm/mach-w90x900/gpio.c
  *
- * Generic w90p910 GPIO handling
+ * Generic nuc900 GPIO handling
  *
  *  Wan ZongShun <mcuos.com@gmail.com>
  *
@@ -30,31 +30,31 @@
 #define GPIO_IN			(0x0C)
 #define GROUPINERV		(0x10)
 #define GPIO_GPIO(Nb)		(0x00000001 << (Nb))
-#define to_w90p910_gpio_chip(c) container_of(c, struct w90p910_gpio_chip, chip)
+#define to_nuc900_gpio_chip(c) container_of(c, struct nuc900_gpio_chip, chip)
 
-#define W90P910_GPIO_CHIP(name, base_gpio, nr_gpio)			\
+#define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio)			\
 	{								\
 		.chip = {						\
 			.label		  = name,			\
-			.direction_input  = w90p910_dir_input,		\
-			.direction_output = w90p910_dir_output,		\
-			.get		  = w90p910_gpio_get,		\
-			.set		  = w90p910_gpio_set,		\
+			.direction_input  = nuc900_dir_input,		\
+			.direction_output = nuc900_dir_output,		\
+			.get		  = nuc900_gpio_get,		\
+			.set		  = nuc900_gpio_set,		\
 			.base		  = base_gpio,			\
 			.ngpio		  = nr_gpio,			\
 		}							\
 	}
 
-struct w90p910_gpio_chip {
+struct nuc900_gpio_chip {
 	struct gpio_chip	chip;
 	void __iomem		*regbase;	/* Base of group register*/
 	spinlock_t 		gpio_lock;
 };
 
-static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset)
+static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-	struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
-	void __iomem *pio = w90p910_gpio->regbase + GPIO_IN;
+	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+	void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
 	unsigned int regval;
 
 	regval = __raw_readl(pio);
@@ -63,14 +63,14 @@ static int w90p910_gpio_get(struct gpio_chip *chip, unsigned offset)
 	return (regval != 0);
 }
 
-static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
 {
-	struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
-	void __iomem *pio = w90p910_gpio->regbase + GPIO_OUT;
+	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+	void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
 	unsigned int regval;
 	unsigned long flags;
 
-	spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
+	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
 
 	regval = __raw_readl(pio);
 
@@ -81,36 +81,36 @@ static void w90p910_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
 
 	__raw_writel(regval, pio);
 
-	spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
+	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
 }
 
-static int w90p910_dir_input(struct gpio_chip *chip, unsigned offset)
+static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
 {
-	struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
-	void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR;
+	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+	void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
 	unsigned int regval;
 	unsigned long flags;
 
-	spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
+	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
 
 	regval = __raw_readl(pio);
 	regval &= ~GPIO_GPIO(offset);
 	__raw_writel(regval, pio);
 
-	spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
+	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
 
 	return 0;
 }
 
-static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val)
+static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
 {
-	struct w90p910_gpio_chip *w90p910_gpio = to_w90p910_gpio_chip(chip);
-	void __iomem *outreg = w90p910_gpio->regbase + GPIO_OUT;
-	void __iomem *pio = w90p910_gpio->regbase + GPIO_DIR;
+	struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+	void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
+	void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
 	unsigned int regval;
 	unsigned long flags;
 
-	spin_lock_irqsave(&w90p910_gpio->gpio_lock, flags);
+	spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
 
 	regval = __raw_readl(pio);
 	regval |= GPIO_GPIO(offset);
@@ -125,28 +125,28 @@ static int w90p910_dir_output(struct gpio_chip *chip, unsigned offset, int val)
 
 	__raw_writel(regval, outreg);
 
-	spin_unlock_irqrestore(&w90p910_gpio->gpio_lock, flags);
+	spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
 
 	return 0;
 }
 
-static struct w90p910_gpio_chip w90p910_gpio[] = {
-	W90P910_GPIO_CHIP("GROUPC", 0, 16),
-	W90P910_GPIO_CHIP("GROUPD", 16, 10),
-	W90P910_GPIO_CHIP("GROUPE", 26, 14),
-	W90P910_GPIO_CHIP("GROUPF", 40, 10),
-	W90P910_GPIO_CHIP("GROUPG", 50, 17),
-	W90P910_GPIO_CHIP("GROUPH", 67, 8),
-	W90P910_GPIO_CHIP("GROUPI", 75, 17),
+static struct nuc900_gpio_chip nuc900_gpio[] = {
+	NUC900_GPIO_CHIP("GROUPC", 0, 16),
+	NUC900_GPIO_CHIP("GROUPD", 16, 10),
+	NUC900_GPIO_CHIP("GROUPE", 26, 14),
+	NUC900_GPIO_CHIP("GROUPF", 40, 10),
+	NUC900_GPIO_CHIP("GROUPG", 50, 17),
+	NUC900_GPIO_CHIP("GROUPH", 67, 8),
+	NUC900_GPIO_CHIP("GROUPI", 75, 17),
 };
 
-void __init w90p910_init_gpio(int nr_group)
+void __init nuc900_init_gpio(int nr_group)
 {
 	unsigned	i;
-	struct w90p910_gpio_chip *gpio_chip;
+	struct nuc900_gpio_chip *gpio_chip;
 
 	for (i = 0; i < nr_group; i++) {
-		gpio_chip = &w90p910_gpio[i];
+		gpio_chip = &nuc900_gpio[i];
 		spin_lock_init(&gpio_chip->gpio_lock);
 		gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
 		gpiochip_add(&gpio_chip->chip);
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h
index f10b6a8..516d6b4 100644
--- a/arch/arm/mach-w90x900/include/mach/regs-clock.h
+++ b/arch/arm/mach-w90x900/include/mach/regs-clock.h
@@ -28,4 +28,26 @@
 #define REG_CLKEN1	(CLK_BA + 0x24)
 #define REG_CLKDIV1	(CLK_BA + 0x28)
 
+/* Define PLL freq setting */
+#define PLL_DISABLE		0x12B63
+#define	PLL_66MHZ		0x2B63
+#define	PLL_100MHZ		0x4F64
+#define PLL_120MHZ		0x4F63
+#define	PLL_166MHZ		0x4124
+#define	PLL_200MHZ		0x4F24
+
+/* Define AHB:CPUFREQ ratio */
+#define	AHB_CPUCLK_1_1		0x00
+#define	AHB_CPUCLK_1_2		0x01
+#define	AHB_CPUCLK_1_4		0x02
+#define	AHB_CPUCLK_1_8		0x03
+
+/* Define APB:AHB ratio */
+#define APB_AHB_1_2		0x01
+#define APB_AHB_1_4		0x02
+#define APB_AHB_1_8		0x03
+
+/* Define clock skew */
+#define DEFAULTSKEW		0x48
+
 #endif /*  __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/include/mach/regs-ebi.h
new file mode 100644
index 0000000..b68455e
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-ebi.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-ebi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_EBI_H
+#define __ASM_ARCH_REGS_EBI_H
+
+/* EBI Control Registers */
+
+#define EBI_BA		W90X900_VA_EBI
+#define REG_EBICON	(EBI_BA + 0x00)
+#define REG_ROMCON	(EBI_BA + 0x04)
+#define REG_SDCONF0	(EBI_BA + 0x08)
+#define REG_SDCONF1	(EBI_BA + 0x0C)
+#define REG_SDTIME0	(EBI_BA + 0x10)
+#define REG_SDTIME1	(EBI_BA + 0x14)
+#define REG_EXT0CON	(EBI_BA + 0x18)
+#define REG_EXT1CON	(EBI_BA + 0x1C)
+#define REG_EXT2CON	(EBI_BA + 0x20)
+#define REG_EXT3CON	(EBI_BA + 0x24)
+#define REG_EXT4CON	(EBI_BA + 0x28)
+#define REG_CKSKEW	(EBI_BA + 0x2C)
+
+#endif /*  __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
new file mode 100644
index 0000000..556778e
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_ARCH_W90P910_KEYPAD_H
+#define __ASM_ARCH_W90P910_KEYPAD_H
+
+#include <linux/input/matrix_keypad.h>
+
+extern void mfp_set_groupi(struct device *dev);
+
+struct w90p910_keypad_platform_data {
+	const struct matrix_keymap_data *keymap_data;
+
+	unsigned int	prescale;
+	unsigned int	debounce;
+};
+
+#endif /* __ASM_ARCH_W90P910_KEYPAD_H */
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
index 0b4fc19..0ce9d8e 100644
--- a/arch/arm/mach-w90x900/irq.c
+++ b/arch/arm/mach-w90x900/irq.c
@@ -10,8 +10,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; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation;version 2 of the License.
  *
  */
 
@@ -29,9 +28,114 @@
 #include <mach/hardware.h>
 #include <mach/regs-irq.h>
 
-static void w90x900_irq_mask(unsigned int irq)
+struct group_irq {
+	unsigned long		gpen;
+	unsigned int		enabled;
+	void			(*enable)(struct group_irq *, int enable);
+};
+
+static DEFINE_SPINLOCK(groupirq_lock);
+
+#define DEFINE_GROUP(_name, _ctrlbit, _num)				\
+struct group_irq group_##_name = {					\
+		.enable		= nuc900_group_enable,			\
+		.gpen		= ((1 << _num) - 1) << _ctrlbit,	\
+	}
+
+static void nuc900_group_enable(struct group_irq *gpirq, int enable);
+
+static DEFINE_GROUP(nirq0, 0, 4);
+static DEFINE_GROUP(nirq1, 4, 4);
+static DEFINE_GROUP(usbh, 8, 2);
+static DEFINE_GROUP(ottimer, 16, 3);
+static DEFINE_GROUP(gdma, 20, 2);
+static DEFINE_GROUP(sc, 24, 2);
+static DEFINE_GROUP(i2c, 26, 2);
+static DEFINE_GROUP(ps2, 28, 2);
+
+static int group_irq_enable(struct group_irq *group_irq)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&groupirq_lock, flags);
+	if (group_irq->enabled++ == 0)
+		(group_irq->enable)(group_irq, 1);
+	spin_unlock_irqrestore(&groupirq_lock, flags);
+
+	return 0;
+}
+
+static void group_irq_disable(struct group_irq *group_irq)
 {
+	unsigned long flags;
+
+	WARN_ON(group_irq->enabled == 0);
+
+	spin_lock_irqsave(&groupirq_lock, flags);
+	if (--group_irq->enabled == 0)
+		(group_irq->enable)(group_irq, 0);
+	spin_unlock_irqrestore(&groupirq_lock, flags);
+}
+
+static void nuc900_group_enable(struct group_irq *gpirq, int enable)
+{
+	unsigned int groupen = gpirq->gpen;
+	unsigned long regval;
+
+	regval = __raw_readl(REG_AIC_GEN);
+
+	if (enable)
+		regval |= groupen;
+	else
+		regval &= ~groupen;
+
+	__raw_writel(regval, REG_AIC_GEN);
+}
+
+static void nuc900_irq_mask(unsigned int irq)
+{
+	struct group_irq *group_irq;
+
+	group_irq = NULL;
+
 	__raw_writel(1 << irq, REG_AIC_MDCR);
+
+	switch (irq) {
+	case IRQ_GROUP0:
+		group_irq = &group_nirq0;
+		break;
+
+	case IRQ_GROUP1:
+		group_irq = &group_nirq1;
+		break;
+
+	case IRQ_USBH:
+		group_irq = &group_usbh;
+		break;
+
+	case IRQ_T_INT_GROUP:
+		group_irq = &group_ottimer;
+		break;
+
+	case IRQ_GDMAGROUP:
+		group_irq = &group_gdma;
+		break;
+
+	case IRQ_SCGROUP:
+		group_irq = &group_sc;
+		break;
+
+	case IRQ_I2CGROUP:
+		group_irq = &group_i2c;
+		break;
+
+	case IRQ_P2SGROUP:
+		group_irq = &group_ps2;
+		break;
+	}
+
+	if (group_irq)
+		group_irq_disable(group_irq);
 }
 
 /*
@@ -39,37 +143,71 @@ static void w90x900_irq_mask(unsigned int irq)
  * to REG_AIC_EOSCR for ACK
  */
 
-static void w90x900_irq_ack(unsigned int irq)
+static void nuc900_irq_ack(unsigned int irq)
 {
 	__raw_writel(0x01, REG_AIC_EOSCR);
 }
 
-static void w90x900_irq_unmask(unsigned int irq)
+static void nuc900_irq_unmask(unsigned int irq)
 {
-	unsigned long mask;
+	struct group_irq *group_irq;
+
+	group_irq = NULL;
 
-	if (irq == IRQ_T_INT_GROUP) {
-		mask = __raw_readl(REG_AIC_GEN);
-		__raw_writel(TIME_GROUP_IRQ | mask, REG_AIC_GEN);
-		__raw_writel(1 << IRQ_T_INT_GROUP, REG_AIC_MECR);
-	}
 	__raw_writel(1 << irq, REG_AIC_MECR);
+
+	switch (irq) {
+	case IRQ_GROUP0:
+		group_irq = &group_nirq0;
+		break;
+
+	case IRQ_GROUP1:
+		group_irq = &group_nirq1;
+		break;
+
+	case IRQ_USBH:
+		group_irq = &group_usbh;
+		break;
+
+	case IRQ_T_INT_GROUP:
+		group_irq = &group_ottimer;
+		break;
+
+	case IRQ_GDMAGROUP:
+		group_irq = &group_gdma;
+		break;
+
+	case IRQ_SCGROUP:
+		group_irq = &group_sc;
+		break;
+
+	case IRQ_I2CGROUP:
+		group_irq = &group_i2c;
+		break;
+
+	case IRQ_P2SGROUP:
+		group_irq = &group_ps2;
+		break;
+	}
+
+	if (group_irq)
+		group_irq_enable(group_irq);
 }
 
-static struct irq_chip w90x900_irq_chip = {
-	.ack	   = w90x900_irq_ack,
-	.mask	   = w90x900_irq_mask,
-	.unmask	   = w90x900_irq_unmask,
+static struct irq_chip nuc900_irq_chip = {
+	.ack	   = nuc900_irq_ack,
+	.mask	   = nuc900_irq_mask,
+	.unmask	   = nuc900_irq_unmask,
 };
 
-void __init w90x900_init_irq(void)
+void __init nuc900_init_irq(void)
 {
 	int irqno;
 
 	__raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
 
 	for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) {
-		set_irq_chip(irqno, &w90x900_irq_chip);
+		set_irq_chip(irqno, &nuc900_irq_chip);
 		set_irq_handler(irqno, handle_level_irq);
 		set_irq_flags(irqno, IRQF_VALID);
 	}
diff --git a/arch/arm/mach-w90x900/mach-nuc910evb.c b/arch/arm/mach-w90x900/mach-nuc910evb.c
new file mode 100644
index 0000000..ec05bda
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc910evb.c
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc910evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc910.h"
+
+static void __init nuc910evb_map_io(void)
+{
+	nuc910_map_io();
+	nuc910_init_clocks();
+}
+
+static void __init nuc910evb_init(void)
+{
+	nuc910_board_init();
+}
+
+MACHINE_START(W90P910EVB, "W90P910EVB")
+	/* Maintainer: Wan ZongShun */
+	.phys_io	= W90X900_PA_UART,
+	.io_pg_offst	= (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= 0,
+	.map_io		= nuc910evb_map_io,
+	.init_irq	= nuc900_init_irq,
+	.init_machine	= nuc910evb_init,
+	.timer		= &nuc900_timer,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c
new file mode 100644
index 0000000..cef903b
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc950evb.c
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc950evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc950.h"
+
+static void __init nuc950evb_map_io(void)
+{
+	nuc950_map_io();
+	nuc950_init_clocks();
+}
+
+static void __init nuc950evb_init(void)
+{
+	nuc950_board_init();
+}
+
+MACHINE_START(W90P950EVB, "W90P950EVB")
+	/* Maintainer: Wan ZongShun */
+	.phys_io	= W90X900_PA_UART,
+	.io_pg_offst	= (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= 0,
+	.map_io		= nuc950evb_map_io,
+	.init_irq	= nuc900_init_irq,
+	.init_machine	= nuc950evb_init,
+	.timer		= &nuc900_timer,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc960evb.c b/arch/arm/mach-w90x900/mach-nuc960evb.c
new file mode 100644
index 0000000..e3a46f1
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc960evb.c
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc960evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc960.h"
+
+static void __init nuc960evb_map_io(void)
+{
+	nuc960_map_io();
+	nuc960_init_clocks();
+}
+
+static void __init nuc960evb_init(void)
+{
+	nuc960_board_init();
+}
+
+MACHINE_START(W90N960EVB, "W90N960EVB")
+	/* Maintainer: Wan ZongShun */
+	.phys_io	= W90X900_PA_UART,
+	.io_pg_offst	= (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
+	.boot_params	= 0,
+	.map_io		= nuc960evb_map_io,
+	.init_irq	= nuc900_init_irq,
+	.init_machine	= nuc960evb_init,
+	.timer		= &nuc900_timer,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-w90p910evb.c b/arch/arm/mach-w90x900/mach-w90p910evb.c
deleted file mode 100644
index 7a62bd3..0000000
--- a/arch/arm/mach-w90x900/mach-w90p910evb.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * linux/arch/arm/mach-w90x900/mach-w90p910evb.c
- *
- * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
- *
- * Copyright (C) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@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 of the License.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/regs-serial.h>
-#include <mach/map.h>
-
-#include "cpu.h"
-/*w90p910 evb norflash driver data */
-
-#define W90P910_FLASH_BASE	0xA0000000
-#define W90P910_FLASH_SIZE	0x400000
-
-static struct mtd_partition w90p910_flash_partitions[] = {
-	{
-		.name	=	"NOR Partition 1 for kernel (960K)",
-		.size	=	0xF0000,
-		.offset	=	0x10000,
-	},
-	{
-		.name	=	"NOR Partition 2 for image (1M)",
-		.size	=	0x100000,
-		.offset	=	0x100000,
-	},
-	{
-		.name	=	"NOR Partition 3 for user (2M)",
-		.size	=	0x200000,
-		.offset	=	0x00200000,
-	}
-};
-
-static struct physmap_flash_data w90p910_flash_data = {
-	.width		=	2,
-	.parts		=	w90p910_flash_partitions,
-	.nr_parts	=	ARRAY_SIZE(w90p910_flash_partitions),
-};
-
-static struct resource w90p910_flash_resources[] = {
-	{
-		.start	=	W90P910_FLASH_BASE,
-		.end	=	W90P910_FLASH_BASE + W90P910_FLASH_SIZE - 1,
-		.flags	=	IORESOURCE_MEM,
-	}
-};
-
-static struct platform_device w90p910_flash_device = {
-	.name		=	"physmap-flash",
-	.id		=	0,
-	.dev		= {
-				.platform_data = &w90p910_flash_data,
-			},
-	.resource	=	w90p910_flash_resources,
-	.num_resources	=	ARRAY_SIZE(w90p910_flash_resources),
-};
-
-/* USB EHCI Host Controller */
-
-static struct resource w90x900_usb_ehci_resource[] = {
-	[0] = {
-		.start = W90X900_PA_USBEHCIHOST,
-		.end   = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_USBH,
-		.end   = IRQ_USBH,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 w90x900_device_usb_ehci_dmamask = 0xffffffffUL;
-
-struct platform_device w90x900_device_usb_ehci = {
-	.name		  = "w90x900-ehci",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(w90x900_usb_ehci_resource),
-	.resource	  = w90x900_usb_ehci_resource,
-	.dev              = {
-		.dma_mask = &w90x900_device_usb_ehci_dmamask,
-		.coherent_dma_mask = 0xffffffffUL
-	}
-};
-EXPORT_SYMBOL(w90x900_device_usb_ehci);
-
-/* USB OHCI Host Controller */
-
-static struct resource w90x900_usb_ohci_resource[] = {
-	[0] = {
-		.start = W90X900_PA_USBOHCIHOST,
-		.end   = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_USBH,
-		.end   = IRQ_USBH,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static u64 w90x900_device_usb_ohci_dmamask = 0xffffffffUL;
-struct platform_device w90x900_device_usb_ohci = {
-	.name		  = "w90x900-ohci",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(w90x900_usb_ohci_resource),
-	.resource	  = w90x900_usb_ohci_resource,
-	.dev              = {
-		.dma_mask = &w90x900_device_usb_ohci_dmamask,
-		.coherent_dma_mask = 0xffffffffUL
-	}
-};
-EXPORT_SYMBOL(w90x900_device_usb_ohci);
-
-/*TouchScreen controller*/
-
-static struct resource w90x900_ts_resource[] = {
-	[0] = {
-		.start = W90X900_PA_ADC,
-		.end   = W90X900_PA_ADC + W90X900_SZ_ADC-1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_ADC,
-		.end   = IRQ_ADC,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device w90x900_device_ts = {
-	.name		= "w90x900-ts",
-	.id		= -1,
-	.resource	= w90x900_ts_resource,
-	.num_resources	= ARRAY_SIZE(w90x900_ts_resource),
-};
-EXPORT_SYMBOL(w90x900_device_ts);
-
-/* RTC controller*/
-
-static struct resource w90x900_rtc_resource[] = {
-	[0] = {
-		.start = W90X900_PA_RTC,
-		.end   = W90X900_PA_RTC + 0xff,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_RTC,
-		.end   = IRQ_RTC,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device w90x900_device_rtc = {
-	.name		= "w90x900-rtc",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(w90x900_rtc_resource),
-	.resource	= w90x900_rtc_resource,
-};
-EXPORT_SYMBOL(w90x900_device_rtc);
-
-/* KPI controller*/
-
-static struct resource w90x900_kpi_resource[] = {
-	[0] = {
-		.start = W90X900_PA_KPI,
-		.end   = W90X900_PA_KPI + W90X900_SZ_KPI - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_KPI,
-		.end   = IRQ_KPI,
-		.flags = IORESOURCE_IRQ,
-	}
-
-};
-
-struct platform_device w90x900_device_kpi = {
-	.name		= "w90x900-kpi",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(w90x900_kpi_resource),
-	.resource	= w90x900_kpi_resource,
-};
-EXPORT_SYMBOL(w90x900_device_kpi);
-
-/* USB Device (Gadget)*/
-
-static struct resource w90x900_usbgadget_resource[] = {
-	[0] = {
-		.start = W90X900_PA_USBDEV,
-		.end   = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_USBD,
-		.end   = IRQ_USBD,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-struct platform_device w90x900_device_usbgadget = {
-	.name		= "w90x900-usbgadget",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(w90x900_usbgadget_resource),
-	.resource	= w90x900_usbgadget_resource,
-};
-EXPORT_SYMBOL(w90x900_device_usbgadget);
-
-static struct map_desc w90p910_iodesc[] __initdata = {
-};
-
-/*Here should be your evb resourse,such as LCD*/
-
-static struct platform_device *w90p910evb_dev[] __initdata = {
-	&w90p910_serial_device,
-	&w90p910_flash_device,
-	&w90x900_device_usb_ehci,
-	&w90x900_device_usb_ohci,
-	&w90x900_device_ts,
-	&w90x900_device_rtc,
-	&w90x900_device_kpi,
-	&w90x900_device_usbgadget,
-};
-
-static void __init w90p910evb_map_io(void)
-{
-	w90p910_map_io(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc));
-	w90p910_init_clocks();
-}
-
-static void __init w90p910evb_init(void)
-{
-	platform_add_devices(w90p910evb_dev, ARRAY_SIZE(w90p910evb_dev));
-}
-
-MACHINE_START(W90P910EVB, "W90P910EVB")
-	/* Maintainer: Wan ZongShun */
-	.phys_io	= W90X900_PA_UART,
-	.io_pg_offst	= (((u32)W90X900_VA_UART) >> 18) & 0xfffc,
-	.boot_params	= 0,
-	.map_io		= w90p910evb_map_io,
-	.init_irq	= w90x900_init_irq,
-	.init_machine	= w90p910evb_init,
-	.timer		= &w90x900_timer,
-MACHINE_END
diff --git a/arch/arm/mach-w90x900/mfp-w90p910.c b/arch/arm/mach-w90x900/mfp-w90p910.c
deleted file mode 100644
index a3520fe..0000000
--- a/arch/arm/mach-w90x900/mfp-w90p910.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * linux/arch/arm/mach-w90x900/mfp-w90p910.c
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- *
- * Wan ZongShun <mcuos.com@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 of the License.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-
-#define REG_MFSEL	(W90X900_VA_GCR + 0xC)
-
-#define GPSELF		(0x01 << 1)
-
-#define GPSELC		(0x03 << 2)
-#define ENKPI		(0x02 << 2)
-#define ENNAND		(0x01 << 2)
-
-#define GPSELEI0	(0x01 << 26)
-#define GPSELEI1	(0x01 << 27)
-
-static DECLARE_MUTEX(mfp_sem);
-
-void mfp_set_groupf(struct device *dev)
-{
-	unsigned long mfpen;
-	const char *dev_id;
-
-	BUG_ON(!dev);
-
-	down(&mfp_sem);
-
-	dev_id = dev_name(dev);
-
-	mfpen = __raw_readl(REG_MFSEL);
-
-	if (strcmp(dev_id, "w90p910-emc") == 0)
-		mfpen |= GPSELF;/*enable mac*/
-	else
-		mfpen &= ~GPSELF;/*GPIOF[9:0]*/
-
-	__raw_writel(mfpen, REG_MFSEL);
-
-	up(&mfp_sem);
-}
-EXPORT_SYMBOL(mfp_set_groupf);
-
-void mfp_set_groupc(struct device *dev)
-{
-	unsigned long mfpen;
-	const char *dev_id;
-
-	BUG_ON(!dev);
-
-	down(&mfp_sem);
-
-	dev_id = dev_name(dev);
-
-	mfpen = __raw_readl(REG_MFSEL);
-
-	if (strcmp(dev_id, "w90p910-lcd") == 0)
-		mfpen |= GPSELC;/*enable lcd*/
-	else if (strcmp(dev_id, "w90p910-kpi") == 0) {
-			mfpen &= (~GPSELC);/*enable kpi*/
-			mfpen |= ENKPI;
-		} else if (strcmp(dev_id, "w90p910-nand") == 0) {
-				mfpen &= (~GPSELC);/*enable nand*/
-				mfpen |= ENNAND;
-			} else
-				mfpen &= (~GPSELC);/*GPIOC[14:0]*/
-
-	__raw_writel(mfpen, REG_MFSEL);
-
-	up(&mfp_sem);
-}
-EXPORT_SYMBOL(mfp_set_groupc);
-
-void mfp_set_groupi(struct device *dev, int gpio)
-{
-	unsigned long mfpen;
-	const char *dev_id;
-
-	BUG_ON(!dev);
-
-	down(&mfp_sem);
-
-	dev_id = dev_name(dev);
-
-	mfpen = __raw_readl(REG_MFSEL);
-
-	if (strcmp(dev_id, "w90p910-wdog") == 0)
-		mfpen |= GPSELEI1;/*enable wdog*/
-		else if (strcmp(dev_id, "w90p910-atapi") == 0)
-			mfpen |= GPSELEI0;/*enable atapi*/
-
-	__raw_writel(mfpen, REG_MFSEL);
-
-	up(&mfp_sem);
-}
-EXPORT_SYMBOL(mfp_set_groupi);
-
diff --git a/arch/arm/mach-w90x900/mfp.c b/arch/arm/mach-w90x900/mfp.c
new file mode 100644
index 0000000..a47dc9a
--- /dev/null
+++ b/arch/arm/mach-w90x900/mfp.c
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/mach-w90x900/mfp.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#define REG_MFSEL	(W90X900_VA_GCR + 0xC)
+
+#define GPSELF		(0x01 << 1)
+
+#define GPSELC		(0x03 << 2)
+#define ENKPI		(0x02 << 2)
+#define ENNAND		(0x01 << 2)
+
+#define GPSELEI0	(0x01 << 26)
+#define GPSELEI1	(0x01 << 27)
+
+#define GPIOG0TO1	(0x03 << 14)
+#define GPIOG2TO3	(0x03 << 16)
+#define ENSPI		(0x0a << 14)
+#define ENI2C0		(0x01 << 14)
+#define ENI2C1		(0x01 << 16)
+
+static DEFINE_MUTEX(mfp_mutex);
+
+void mfp_set_groupf(struct device *dev)
+{
+	unsigned long mfpen;
+	const char *dev_id;
+
+	BUG_ON(!dev);
+
+	mutex_lock(&mfp_mutex);
+
+	dev_id = dev_name(dev);
+
+	mfpen = __raw_readl(REG_MFSEL);
+
+	if (strcmp(dev_id, "nuc900-emc") == 0)
+		mfpen |= GPSELF;/*enable mac*/
+	else
+		mfpen &= ~GPSELF;/*GPIOF[9:0]*/
+
+	__raw_writel(mfpen, REG_MFSEL);
+
+	mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupf);
+
+void mfp_set_groupc(struct device *dev)
+{
+	unsigned long mfpen;
+	const char *dev_id;
+
+	BUG_ON(!dev);
+
+	mutex_lock(&mfp_mutex);
+
+	dev_id = dev_name(dev);
+
+	mfpen = __raw_readl(REG_MFSEL);
+
+	if (strcmp(dev_id, "nuc900-lcd") == 0)
+		mfpen |= GPSELC;/*enable lcd*/
+	else if (strcmp(dev_id, "nuc900-kpi") == 0) {
+		mfpen &= (~GPSELC);/*enable kpi*/
+		mfpen |= ENKPI;
+	} else if (strcmp(dev_id, "nuc900-nand") == 0) {
+		mfpen &= (~GPSELC);/*enable nand*/
+		mfpen |= ENNAND;
+	} else
+		mfpen &= (~GPSELC);/*GPIOC[14:0]*/
+
+	__raw_writel(mfpen, REG_MFSEL);
+
+	mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupc);
+
+void mfp_set_groupi(struct device *dev)
+{
+	unsigned long mfpen;
+	const char *dev_id;
+
+	BUG_ON(!dev);
+
+	mutex_lock(&mfp_mutex);
+
+	dev_id = dev_name(dev);
+
+	mfpen = __raw_readl(REG_MFSEL);
+
+	mfpen &= ~GPSELEI1;/*default gpio16*/
+
+	if (strcmp(dev_id, "nuc900-wdog") == 0)
+		mfpen |= GPSELEI1;/*enable wdog*/
+	else if (strcmp(dev_id, "nuc900-atapi") == 0)
+		mfpen |= GPSELEI0;/*enable atapi*/
+	else if (strcmp(dev_id, "nuc900-keypad") == 0)
+		mfpen &= ~GPSELEI0;/*enable keypad*/
+
+	__raw_writel(mfpen, REG_MFSEL);
+
+	mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupi);
+
+void mfp_set_groupg(struct device *dev)
+{
+	unsigned long mfpen;
+	const char *dev_id;
+
+	BUG_ON(!dev);
+
+	mutex_lock(&mfp_mutex);
+
+	dev_id = dev_name(dev);
+
+	mfpen = __raw_readl(REG_MFSEL);
+
+	if (strcmp(dev_id, "nuc900-spi") == 0) {
+		mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);
+		mfpen |= ENSPI;/*enable spi*/
+	} else if (strcmp(dev_id, "nuc900-i2c0") == 0) {
+		mfpen &= ~(GPIOG0TO1);
+		mfpen |= ENI2C0;/*enable i2c0*/
+	} else if (strcmp(dev_id, "nuc900-i2c1") == 0) {
+		mfpen &= ~(GPIOG2TO3);
+		mfpen |= ENI2C1;/*enable i2c1*/
+	} else {
+		mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
+	}
+
+	__raw_writel(mfpen, REG_MFSEL);
+
+	mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupg);
+
diff --git a/arch/arm/mach-w90x900/nuc910.c b/arch/arm/mach-w90x900/nuc910.c
new file mode 100644
index 0000000..656f03b
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc910.c
@@ -0,0 +1,60 @@
+/*
+ * linux/arch/arm/mach-w90x900/nuc910.c
+ *
+ * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC910 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include "cpu.h"
+#include "clock.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc910_dev[] __initdata = {
+	&nuc900_device_ts,
+	&nuc900_device_rtc,
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc910evb_iodesc[] __initdata = {
+	IODESC_ENT(USBEHCIHOST),
+	IODESC_ENT(USBOHCIHOST),
+	IODESC_ENT(KPI),
+	IODESC_ENT(USBDEV),
+	IODESC_ENT(ADC),
+};
+
+/*Init NUC910 evb io*/
+
+void __init nuc910_map_io(void)
+{
+	nuc900_map_io(nuc910evb_iodesc, ARRAY_SIZE(nuc910evb_iodesc));
+}
+
+/*Init NUC910 clock*/
+
+void __init nuc910_init_clocks(void)
+{
+	nuc900_init_clocks();
+}
+
+/*Init NUC910 board info*/
+
+void __init nuc910_board_init(void)
+{
+	nuc900_board_init(nuc910_dev, ARRAY_SIZE(nuc910_dev));
+}
diff --git a/arch/arm/mach-w90x900/nuc910.h b/arch/arm/mach-w90x900/nuc910.h
new file mode 100644
index 0000000..83e9ba5
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc910.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-w90x900/nuc910.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC900 CPU support
+ *
+ * Wan ZongShun <mcuos.com@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 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+struct map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc900_init_irq(void);
+extern struct sys_timer nuc900_timer;
+
+/* extern file from nuc910.c */
+
+extern void nuc910_board_init(void);
+extern void nuc910_init_clocks(void);
+extern void nuc910_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc950.c b/arch/arm/mach-w90x900/nuc950.c
new file mode 100644
index 0000000..1495081
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc950.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mach-w90x900/nuc950.c
+ *
+ * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC950 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include "cpu.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc950_dev[] __initdata = {
+	&nuc900_device_kpi,
+	&nuc900_device_fmi,
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc950evb_iodesc[] __initdata = {
+};
+
+/*Init NUC950 evb io*/
+
+void __init nuc950_map_io(void)
+{
+	nuc900_map_io(nuc950evb_iodesc, ARRAY_SIZE(nuc950evb_iodesc));
+}
+
+/*Init NUC950 clock*/
+
+void __init nuc950_init_clocks(void)
+{
+	nuc900_init_clocks();
+}
+
+/*Init NUC950 board info*/
+
+void __init nuc950_board_init(void)
+{
+	nuc900_board_init(nuc950_dev, ARRAY_SIZE(nuc950_dev));
+}
diff --git a/arch/arm/mach-w90x900/nuc950.h b/arch/arm/mach-w90x900/nuc950.h
new file mode 100644
index 0000000..98a1148
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc950.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-w90x900/nuc950.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC900 CPU support
+ *
+ * Wan ZongShun <mcuos.com@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 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+struct map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc900_init_irq(void);
+extern struct sys_timer nuc900_timer;
+
+/* extern file from nuc950.c */
+
+extern void nuc950_board_init(void);
+extern void nuc950_init_clocks(void);
+extern void nuc950_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc960.c b/arch/arm/mach-w90x900/nuc960.c
new file mode 100644
index 0000000..8851a3a
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc960.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mach-w90x900/nuc960.c
+ *
+ * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC960 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include "cpu.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc960_dev[] __initdata = {
+	&nuc900_device_kpi,
+	&nuc900_device_fmi,
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc960evb_iodesc[] __initdata = {
+};
+
+/*Init NUC960 evb io*/
+
+void __init nuc960_map_io(void)
+{
+	nuc900_map_io(nuc960evb_iodesc, ARRAY_SIZE(nuc960evb_iodesc));
+}
+
+/*Init NUC960 clock*/
+
+void __init nuc960_init_clocks(void)
+{
+	nuc900_init_clocks();
+}
+
+/*Init NUC960 board info*/
+
+void __init nuc960_board_init(void)
+{
+	nuc900_board_init(nuc960_dev, ARRAY_SIZE(nuc960_dev));
+}
diff --git a/arch/arm/mach-w90x900/nuc960.h b/arch/arm/mach-w90x900/nuc960.h
new file mode 100644
index 0000000..f0c07cb
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc960.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-w90x900/nuc960.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC900 CPU support
+ *
+ * Wan ZongShun <mcuos.com@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 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+struct map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc900_init_irq(void);
+extern struct sys_timer nuc900_timer;
+
+/* extern file from nuc960.c */
+
+extern void nuc960_board_init(void);
+extern void nuc960_init_clocks(void);
+extern void nuc960_map_io(void);
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
index bcc838f..4128af8 100644
--- a/arch/arm/mach-w90x900/time.c
+++ b/arch/arm/mach-w90x900/time.c
@@ -3,7 +3,7 @@
  *
  * Based on linux/arch/arm/plat-s3c24xx/time.c by Ben Dooks
  *
- * Copyright (c) 2008 Nuvoton technology corporation
+ * Copyright (c) 2009 Nuvoton technology corporation
  * All rights reserved.
  *
  * Wan ZongShun <mcuos.com@gmail.com>
@@ -23,6 +23,8 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/leds.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/irq.h>
@@ -31,49 +33,150 @@
 #include <mach/map.h>
 #include <mach/regs-timer.h>
 
-static unsigned long w90x900_gettimeoffset(void)
+#define RESETINT	0x1f
+#define PERIOD		(0x01 << 27)
+#define ONESHOT		(0x00 << 27)
+#define COUNTEN		(0x01 << 30)
+#define INTEN		(0x01 << 29)
+
+#define TICKS_PER_SEC	100
+#define PRESCALE	0x63 /* Divider = prescale + 1 */
+
+unsigned int timer0_load;
+
+static void nuc900_clockevent_setmode(enum clock_event_mode mode,
+		struct clock_event_device *clk)
 {
+	unsigned int val;
+
+	val = __raw_readl(REG_TCSR0);
+	val &= ~(0x03 << 27);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		__raw_writel(timer0_load, REG_TICR0);
+		val |= (PERIOD | COUNTEN | INTEN | PRESCALE);
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+		val |= (ONESHOT | COUNTEN | INTEN | PRESCALE);
+		break;
+
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+
+	__raw_writel(val, REG_TCSR0);
+}
+
+static int nuc900_clockevent_setnextevent(unsigned long evt,
+		struct clock_event_device *clk)
+{
+	unsigned int val;
+
+	__raw_writel(evt, REG_TICR0);
+
+	val = __raw_readl(REG_TCSR0);
+	val |= (COUNTEN | INTEN | PRESCALE);
+	__raw_writel(val, REG_TCSR0);
+
 	return 0;
 }
 
+static struct clock_event_device nuc900_clockevent_device = {
+	.name		= "nuc900-timer0",
+	.shift		= 32,
+	.features	= CLOCK_EVT_MODE_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= nuc900_clockevent_setmode,
+	.set_next_event	= nuc900_clockevent_setnextevent,
+	.rating		= 300,
+};
+
 /*IRQ handler for the timer*/
 
-static irqreturn_t
-w90x900_timer_interrupt(int irq, void *dev_id)
+static irqreturn_t nuc900_timer0_interrupt(int irq, void *dev_id)
 {
-	timer_tick();
+	struct clock_event_device *evt = &nuc900_clockevent_device;
+
 	__raw_writel(0x01, REG_TISR); /* clear TIF0 */
+
+	evt->event_handler(evt);
 	return IRQ_HANDLED;
 }
 
-static struct irqaction w90x900_timer_irq = {
-	.name		= "w90x900 Timer Tick",
+static struct irqaction nuc900_timer0_irq = {
+	.name		= "nuc900-timer0",
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= w90x900_timer_interrupt,
+	.handler	= nuc900_timer0_interrupt,
 };
 
-/*Set up timer reg.*/
+static void __init nuc900_clockevents_init(unsigned int rate)
+{
+	nuc900_clockevent_device.mult = div_sc(rate, NSEC_PER_SEC,
+					nuc900_clockevent_device.shift);
+	nuc900_clockevent_device.max_delta_ns = clockevent_delta2ns(0xffffffff,
+					&nuc900_clockevent_device);
+	nuc900_clockevent_device.min_delta_ns = clockevent_delta2ns(0xf,
+					&nuc900_clockevent_device);
+	nuc900_clockevent_device.cpumask = cpumask_of(0);
 
-static void w90x900_timer_setup(void)
+	clockevents_register_device(&nuc900_clockevent_device);
+}
+
+static cycle_t nuc900_get_cycles(struct clocksource *cs)
 {
-	__raw_writel(0, REG_TCSR0);
-	__raw_writel(0, REG_TCSR1);
-	__raw_writel(0, REG_TCSR2);
-	__raw_writel(0, REG_TCSR3);
-	__raw_writel(0, REG_TCSR4);
-	__raw_writel(0x1F, REG_TISR);
-	__raw_writel(15000000/(100 * 100), REG_TICR0);
-	__raw_writel(0x68000063, REG_TCSR0);
+	return ~__raw_readl(REG_TDR1);
 }
 
-static void __init w90x900_timer_init(void)
+static struct clocksource clocksource_nuc900 = {
+	.name	= "nuc900-timer1",
+	.rating	= 200,
+	.read	= nuc900_get_cycles,
+	.mask	= CLOCKSOURCE_MASK(32),
+	.shift	= 20,
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init nuc900_clocksource_init(unsigned int rate)
 {
-	w90x900_timer_setup();
-	setup_irq(IRQ_TIMER0, &w90x900_timer_irq);
+	unsigned int val;
+
+	__raw_writel(0xffffffff, REG_TICR1);
+
+	val = __raw_readl(REG_TCSR1);
+	val |= (COUNTEN | PERIOD);
+	__raw_writel(val, REG_TCSR1);
+
+	clocksource_nuc900.mult =
+		clocksource_khz2mult((rate / 1000), clocksource_nuc900.shift);
+	clocksource_register(&clocksource_nuc900);
+}
+
+static void __init nuc900_timer_init(void)
+{
+	struct clk *ck_ext = clk_get(NULL, "ext");
+	unsigned int	rate;
+
+	BUG_ON(IS_ERR(ck_ext));
+
+	rate = clk_get_rate(ck_ext);
+	clk_put(ck_ext);
+	rate = rate / (PRESCALE + 0x01);
+
+	 /* set a known state */
+	__raw_writel(0x00, REG_TCSR0);
+	__raw_writel(0x00, REG_TCSR1);
+	__raw_writel(RESETINT, REG_TISR);
+	timer0_load = (rate / TICKS_PER_SEC);
+
+	setup_irq(IRQ_TIMER0, &nuc900_timer0_irq);
+
+	nuc900_clocksource_init(rate);
+	nuc900_clockevents_init(rate);
 }
 
-struct sys_timer w90x900_timer = {
-	.init		= w90x900_timer_init,
-	.offset		= w90x900_gettimeoffset,
-	.resume		= w90x900_timer_setup
+struct sys_timer nuc900_timer = {
+	.init		= nuc900_timer_init,
 };
diff --git a/arch/arm/mach-w90x900/w90p910.c b/arch/arm/mach-w90x900/w90p910.c
deleted file mode 100644
index 1c97e49..0000000
--- a/arch/arm/mach-w90x900/w90p910.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * linux/arch/arm/mach-w90x900/w90p910.c
- *
- * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * W90P910 cpu support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation;version 2 of the License.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/serial_8250.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-serial.h>
-
-#include "cpu.h"
-#include "clock.h"
-
-/* Initial IO mappings */
-
-static struct map_desc w90p910_iodesc[] __initdata = {
-	IODESC_ENT(IRQ),
-	IODESC_ENT(GCR),
-	IODESC_ENT(UART),
-	IODESC_ENT(TIMER),
-	IODESC_ENT(EBI),
-	IODESC_ENT(USBEHCIHOST),
-	IODESC_ENT(USBOHCIHOST),
-	IODESC_ENT(ADC),
-	IODESC_ENT(RTC),
-	IODESC_ENT(KPI),
-	IODESC_ENT(USBDEV),
-	/*IODESC_ENT(LCD),*/
-};
-
-/* Initial clock declarations. */
-static DEFINE_CLK(lcd, 0);
-static DEFINE_CLK(audio, 1);
-static DEFINE_CLK(fmi, 4);
-static DEFINE_CLK(dmac, 5);
-static DEFINE_CLK(atapi, 6);
-static DEFINE_CLK(emc, 7);
-static DEFINE_CLK(usbd, 8);
-static DEFINE_CLK(usbh, 9);
-static DEFINE_CLK(g2d, 10);;
-static DEFINE_CLK(pwm, 18);
-static DEFINE_CLK(ps2, 24);
-static DEFINE_CLK(kpi, 25);
-static DEFINE_CLK(wdt, 26);
-static DEFINE_CLK(gdma, 27);
-static DEFINE_CLK(adc, 28);
-static DEFINE_CLK(usi, 29);
-
-static struct clk_lookup w90p910_clkregs[] = {
-	DEF_CLKLOOK(&clk_lcd, "w90p910-lcd", NULL),
-	DEF_CLKLOOK(&clk_audio, "w90p910-audio", NULL),
-	DEF_CLKLOOK(&clk_fmi, "w90p910-fmi", NULL),
-	DEF_CLKLOOK(&clk_dmac, "w90p910-dmac", NULL),
-	DEF_CLKLOOK(&clk_atapi, "w90p910-atapi", NULL),
-	DEF_CLKLOOK(&clk_emc, "w90p910-emc", NULL),
-	DEF_CLKLOOK(&clk_usbd, "w90p910-usbd", NULL),
-	DEF_CLKLOOK(&clk_usbh, "w90p910-usbh", NULL),
-	DEF_CLKLOOK(&clk_g2d, "w90p910-g2d", NULL),
-	DEF_CLKLOOK(&clk_pwm, "w90p910-pwm", NULL),
-	DEF_CLKLOOK(&clk_ps2, "w90p910-ps2", NULL),
-	DEF_CLKLOOK(&clk_kpi, "w90p910-kpi", NULL),
-	DEF_CLKLOOK(&clk_wdt, "w90p910-wdt", NULL),
-	DEF_CLKLOOK(&clk_gdma, "w90p910-gdma", NULL),
-	DEF_CLKLOOK(&clk_adc, "w90p910-adc", NULL),
-	DEF_CLKLOOK(&clk_usi, "w90p910-usi", NULL),
-};
-
-/* Initial serial platform data */
-
-struct plat_serial8250_port w90p910_uart_data[] = {
-	W90X900_8250PORT(UART0),
-};
-
-struct platform_device w90p910_serial_device = {
-	.name			= "serial8250",
-	.id			= PLAT8250_DEV_PLATFORM,
-	.dev			= {
-		.platform_data	= w90p910_uart_data,
-	},
-};
-
-/*Init W90P910 evb io*/
-
-void __init w90p910_map_io(struct map_desc *mach_desc, int mach_size)
-{
-	unsigned long idcode = 0x0;
-
-	iotable_init(w90p910_iodesc, ARRAY_SIZE(w90p910_iodesc));
-
-	idcode = __raw_readl(W90X900PDID);
-	if (idcode != W90P910_CPUID)
-		printk(KERN_ERR "CPU type 0x%08lx is not W90P910\n", idcode);
-}
-
-/*Init W90P910 clock*/
-
-void __init w90p910_init_clocks(void)
-{
-	clks_register(w90p910_clkregs, ARRAY_SIZE(w90p910_clkregs));
-}
-
-static int __init w90p910_init_cpu(void)
-{
-	return 0;
-}
-
-static int __init w90x900_arch_init(void)
-{
-	return w90p910_init_cpu();
-}
-arch_initcall(w90x900_arch_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 83c025e..5fe595a 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -758,7 +758,7 @@ config CACHE_FEROCEON_L2_WRITETHROUGH
 config CACHE_L2X0
 	bool "Enable the L2x0 outer cache controller"
 	depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
-		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX
+		   REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || ARCH_NOMADIK
 	default y
 	select OUTER_CACHE
 	help
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 03cd27d..b270d62 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -159,7 +159,9 @@ union offset_union {
 
 #define __get8_unaligned_check(ins,val,addr,err)	\
 	__asm__(					\
-	"1:	"ins"	%1, [%2], #1\n"			\
+ ARM(	"1:	"ins"	%1, [%2], #1\n"	)		\
+ THUMB(	"1:	"ins"	%1, [%2]\n"	)		\
+ THUMB(	"	add	%2, %2, #1\n"	)		\
 	"2:\n"						\
 	"	.section .fixup,\"ax\"\n"		\
 	"	.align	2\n"				\
@@ -215,7 +217,9 @@ union offset_union {
 	do {							\
 		unsigned int err = 0, v = val, a = addr;	\
 		__asm__( FIRST_BYTE_16				\
-		"1:	"ins"	%1, [%2], #1\n"			\
+	 ARM(	"1:	"ins"	%1, [%2], #1\n"	)		\
+	 THUMB(	"1:	"ins"	%1, [%2]\n"	)		\
+	 THUMB(	"	add	%2, %2, #1\n"	)		\
 		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"2:	"ins"	%1, [%2]\n"			\
 		"3:\n"						\
@@ -245,11 +249,17 @@ union offset_union {
 	do {							\
 		unsigned int err = 0, v = val, a = addr;	\
 		__asm__( FIRST_BYTE_32				\
-		"1:	"ins"	%1, [%2], #1\n"			\
+	 ARM(	"1:	"ins"	%1, [%2], #1\n"	)		\
+	 THUMB(	"1:	"ins"	%1, [%2]\n"	)		\
+	 THUMB(	"	add	%2, %2, #1\n"	)		\
 		"	mov	%1, %1, "NEXT_BYTE"\n"		\
-		"2:	"ins"	%1, [%2], #1\n"			\
+	 ARM(	"2:	"ins"	%1, [%2], #1\n"	)		\
+	 THUMB(	"2:	"ins"	%1, [%2]\n"	)		\
+	 THUMB(	"	add	%2, %2, #1\n"	)		\
 		"	mov	%1, %1, "NEXT_BYTE"\n"		\
-		"3:	"ins"	%1, [%2], #1\n"			\
+	 ARM(	"3:	"ins"	%1, [%2], #1\n"	)		\
+	 THUMB(	"3:	"ins"	%1, [%2]\n"	)		\
+	 THUMB(	"	add	%2, %2, #1\n"	)		\
 		"	mov	%1, %1, "NEXT_BYTE"\n"		\
 		"4:	"ins"	%1, [%2]\n"			\
 		"5:\n"						\
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index be93ff0..bda0ec3 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -21,7 +21,7 @@
  *
  *	Flush the whole D-cache.
  *
- *	Corrupted registers: r0-r5, r7, r9-r11
+ *	Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
  *
  *	- mm    - mm_struct describing address space
  */
@@ -51,8 +51,12 @@ loop1:
 loop2:
 	mov	r9, r4				@ create working copy of max way size
 loop3:
-	orr	r11, r10, r9, lsl r5		@ factor way and cache number into r11
-	orr	r11, r11, r7, lsl r2		@ factor index number into r11
+ ARM(	orr	r11, r10, r9, lsl r5	)	@ factor way and cache number into r11
+ THUMB(	lsl	r6, r9, r5		)
+ THUMB(	orr	r11, r10, r6		)	@ factor way and cache number into r11
+ ARM(	orr	r11, r11, r7, lsl r2	)	@ factor index number into r11
+ THUMB(	lsl	r6, r7, r2		)
+ THUMB(	orr	r11, r11, r6		)	@ factor index number into r11
 	mcr	p15, 0, r11, c7, c14, 2		@ clean & invalidate by set/way
 	subs	r9, r9, #1			@ decrement the way
 	bge	loop3
@@ -82,11 +86,13 @@ ENDPROC(v7_flush_dcache_all)
  *
  */
 ENTRY(v7_flush_kern_cache_all)
-	stmfd	sp!, {r4-r5, r7, r9-r11, lr}
+ ARM(	stmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
+ THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
 	bl	v7_flush_dcache_all
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c5, 0		@ I+BTB cache invalidate
-	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}
+ ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
+ THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
 	mov	pc, lr
 ENDPROC(v7_flush_kern_cache_all)
 
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 510c179..b30925f 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -36,7 +36,34 @@
 #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
 #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
 
+static u64 get_coherent_dma_mask(struct device *dev)
+{
+	u64 mask = ISA_DMA_THRESHOLD;
+
+	if (dev) {
+		mask = dev->coherent_dma_mask;
+
+		/*
+		 * Sanity check the DMA mask - it must be non-zero, and
+		 * must be able to be satisfied by a DMA allocation.
+		 */
+		if (mask == 0) {
+			dev_warn(dev, "coherent DMA mask is unset\n");
+			return 0;
+		}
+
+		if ((~mask) & ISA_DMA_THRESHOLD) {
+			dev_warn(dev, "coherent DMA mask %#llx is smaller "
+				 "than system GFP_DMA mask %#llx\n",
+				 mask, (unsigned long long)ISA_DMA_THRESHOLD);
+			return 0;
+		}
+	}
 
+	return mask;
+}
+
+#ifdef CONFIG_MMU
 /*
  * These are the page tables (2MB each) covering uncached, DMA consistent allocations
  */
@@ -152,7 +179,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
 	struct page *page;
 	struct arm_vm_region *c;
 	unsigned long order;
-	u64 mask = ISA_DMA_THRESHOLD, limit;
+	u64 mask = get_coherent_dma_mask(dev);
+	u64 limit;
 
 	if (!consistent_pte[0]) {
 		printk(KERN_ERR "%s: not initialised\n", __func__);
@@ -160,25 +188,8 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
 		return NULL;
 	}
 
-	if (dev) {
-		mask = dev->coherent_dma_mask;
-
-		/*
-		 * Sanity check the DMA mask - it must be non-zero, and
-		 * must be able to be satisfied by a DMA allocation.
-		 */
-		if (mask == 0) {
-			dev_warn(dev, "coherent DMA mask is unset\n");
-			goto no_page;
-		}
-
-		if ((~mask) & ISA_DMA_THRESHOLD) {
-			dev_warn(dev, "coherent DMA mask %#llx is smaller "
-				 "than system GFP_DMA mask %#llx\n",
-				 mask, (unsigned long long)ISA_DMA_THRESHOLD);
-			goto no_page;
-		}
-	}
+	if (!mask)
+		goto no_page;
 
 	/*
 	 * Sanity check the allocation size.
@@ -267,6 +278,31 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
 	*handle = ~0;
 	return NULL;
 }
+#else	/* !CONFIG_MMU */
+static void *
+__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
+	    pgprot_t prot)
+{
+	void *virt;
+	u64 mask = get_coherent_dma_mask(dev);
+
+	if (!mask)
+		goto error;
+
+	if (mask != 0xffffffff)
+		gfp |= GFP_DMA;
+	virt = kmalloc(size, gfp);
+	if (!virt)
+		goto error;
+
+	*handle =  virt_to_dma(dev, virt);
+	return virt;
+
+error:
+	*handle = ~0;
+	return NULL;
+}
+#endif	/* CONFIG_MMU */
 
 /*
  * Allocate DMA-coherent memory space and return both the kernel remapped
@@ -311,9 +347,10 @@ EXPORT_SYMBOL(dma_alloc_writecombine);
 static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
 		    void *cpu_addr, dma_addr_t dma_addr, size_t size)
 {
+	int ret = -ENXIO;
+#ifdef CONFIG_MMU
 	unsigned long flags, user_size, kern_size;
 	struct arm_vm_region *c;
-	int ret = -ENXIO;
 
 	user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 
@@ -334,6 +371,7 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
 					      vma->vm_page_prot);
 		}
 	}
+#endif	/* CONFIG_MMU */
 
 	return ret;
 }
@@ -358,6 +396,7 @@ EXPORT_SYMBOL(dma_mmap_writecombine);
  * free a page as defined by the above mapping.
  * Must not be called with IRQs disabled.
  */
+#ifdef CONFIG_MMU
 void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
 {
 	struct arm_vm_region *c;
@@ -444,6 +483,14 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
 	       __func__, cpu_addr);
 	dump_stack();
 }
+#else	/* !CONFIG_MMU */
+void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
+{
+	if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
+		return;
+	kfree(cpu_addr);
+}
+#endif	/* CONFIG_MMU */
 EXPORT_SYMBOL(dma_free_coherent);
 
 /*
@@ -451,10 +498,12 @@ EXPORT_SYMBOL(dma_free_coherent);
  */
 static int __init consistent_init(void)
 {
+	int ret = 0;
+#ifdef CONFIG_MMU
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *pte;
-	int ret = 0, i = 0;
+	int i = 0;
 	u32 base = CONSISTENT_BASE;
 
 	do {
@@ -477,6 +526,7 @@ static int __init consistent_init(void)
 		consistent_pte[i++] = pte;
 		base += (1 << PGDIR_SHIFT);
 	} while (base < CONSISTENT_END);
+#endif	/* !CONFIG_MMU */
 
 	return ret;
 }
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 6fdcbb7..cc8829d 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -16,6 +16,8 @@
 #include <linux/kprobes.h>
 #include <linux/uaccess.h>
 #include <linux/page-flags.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -23,6 +25,7 @@
 
 #include "fault.h"
 
+#ifdef CONFIG_MMU
 
 #ifdef CONFIG_KPROBES
 static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
@@ -97,6 +100,10 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
 
 	printk("\n");
 }
+#else					/* CONFIG_MMU */
+void show_pte(struct mm_struct *mm, unsigned long addr)
+{ }
+#endif					/* CONFIG_MMU */
 
 /*
  * Oops.  The kernel tried to access some page that wasn't present.
@@ -171,6 +178,7 @@ void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 		__do_kernel_fault(mm, addr, fsr, regs);
 }
 
+#ifdef CONFIG_MMU
 #define VM_FAULT_BADMAP		0x010000
 #define VM_FAULT_BADACCESS	0x020000
 
@@ -322,6 +330,13 @@ no_context:
 	__do_kernel_fault(mm, addr, fsr, regs);
 	return 0;
 }
+#else					/* CONFIG_MMU */
+static int
+do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+	return 0;
+}
+#endif					/* CONFIG_MMU */
 
 /*
  * First Level Translation Fault Handler
@@ -340,6 +355,7 @@ no_context:
  * interrupt or a critical region, and should only copy the information
  * from the master page table, nothing more.
  */
+#ifdef CONFIG_MMU
 static int __kprobes
 do_translation_fault(unsigned long addr, unsigned int fsr,
 		     struct pt_regs *regs)
@@ -378,6 +394,14 @@ bad_area:
 	do_bad_area(addr, fsr, regs);
 	return 0;
 }
+#else					/* CONFIG_MMU */
+static int
+do_translation_fault(unsigned long addr, unsigned int fsr,
+		     struct pt_regs *regs)
+{
+	return 0;
+}
+#endif					/* CONFIG_MMU */
 
 /*
  * Some section permission faults need to be handled gracefully.
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index c07222e..575f3ad 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -144,7 +144,14 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
 	 * page.  This ensures that data in the physical page is mutually
 	 * coherent with the kernels mapping.
 	 */
-	__cpuc_flush_dcache_page(page_address(page));
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * kmap_atomic() doesn't set the page virtual address, and
+	 * kunmap_atomic() takes care of cache flushing already.
+	 */
+	if (page_address(page))
+#endif
+		__cpuc_flush_dcache_page(page_address(page));
 
 	/*
 	 * If this is a page cache page, and we have an aliasing VIPT cache,
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index a34954d..73cae57 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -40,11 +40,16 @@ void *kmap_atomic(struct page *page, enum km_type type)
 {
 	unsigned int idx;
 	unsigned long vaddr;
+	void *kmap;
 
 	pagefault_disable();
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	kmap = kmap_high_get(page);
+	if (kmap)
+		return kmap;
+
 	idx = type + KM_TYPE_NR * smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
@@ -80,6 +85,9 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
 #else
 		(void) idx;  /* to kill a warning */
 #endif
+	} else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
+		/* this address was obtained through kmap_high_get() */
+		kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
 	}
 	pagefault_enable();
 }
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 3a7279c..ea36186 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,6 +15,7 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
+#include <linux/sort.h>
 #include <linux/highmem.h>
 
 #include <asm/mach-types.h>
@@ -349,12 +350,43 @@ static void __init bootmem_free_node(int node, struct meminfo *mi)
 	free_area_init_node(node, zone_size, min, zhole_size);
 }
 
+#ifndef CONFIG_SPARSEMEM
+int pfn_valid(unsigned long pfn)
+{
+	struct meminfo *mi = &meminfo;
+	unsigned int left = 0, right = mi->nr_banks;
+
+	do {
+		unsigned int mid = (right + left) / 2;
+		struct membank *bank = &mi->bank[mid];
+
+		if (pfn < bank_pfn_start(bank))
+			right = mid;
+		else if (pfn >= bank_pfn_end(bank))
+			left = mid + 1;
+		else
+			return 1;
+	} while (left < right);
+	return 0;
+}
+EXPORT_SYMBOL(pfn_valid);
+#endif
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+	const struct membank *a = _a, *b = _b;
+	long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
 void __init bootmem_init(void)
 {
 	struct meminfo *mi = &meminfo;
 	unsigned long min, max_low, max_high;
 	int node, initrd_node;
 
+	sort(&mi->bank, mi->nr_banks, sizeof(mi->bank[0]), meminfo_cmp, NULL);
+
 	/*
 	 * Locate which node contains the ramdisk image, if any.
 	 */
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index ad7bacc..900811c 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -12,6 +12,7 @@
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
 #include <asm/page.h>
+#include <asm/setup.h>
 #include <asm/mach/arch.h>
 
 #include "mm.h"
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 54b1f72..7d63bea 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -77,19 +77,15 @@
  * Sanity check the PTE configuration for the code below - which makes
  * certain assumptions about how these bits are layed out.
  */
+#ifdef CONFIG_MMU
 #if L_PTE_SHARED != PTE_EXT_SHARED
 #error PTE shared bit mismatch
 #endif
-#if L_PTE_BUFFERABLE != PTE_BUFFERABLE
-#error PTE bufferable bit mismatch
-#endif
-#if L_PTE_CACHEABLE != PTE_CACHEABLE
-#error PTE cacheable bit mismatch
-#endif
 #if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\
      L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
 #error Invalid Linux PTE bit settings
 #endif
+#endif	/* CONFIG_MMU */
 
 /*
  * The ARMv6 and ARMv7 set_pte_ext translation function.
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 180a08d..f3fa1c3 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -127,7 +127,9 @@ ENDPROC(cpu_v7_switch_mm)
  */
 ENTRY(cpu_v7_set_pte_ext)
 #ifdef CONFIG_MMU
-	str	r1, [r0], #-2048		@ linux version
+ ARM(	str	r1, [r0], #-2048	)	@ linux version
+ THUMB(	str	r1, [r0]		)	@ linux version
+ THUMB(	sub	r0, r0, #2048		)
 
 	bic	r3, r1, #0x000003f0
 	bic	r3, r3, #PTE_TYPE_MASK
@@ -232,7 +234,6 @@ __v7_setup:
 	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
 	mov	r10, #0x1f			@ domains 0, 1 = manager
 	mcr	p15, 0, r10, c3, c0, 0		@ load domain access register
-#endif
 	/*
 	 * Memory region attributes with SCTLR.TRE=1
 	 *
@@ -265,6 +266,7 @@ __v7_setup:
 	ldr	r6, =0x40e040e0			@ NMRR
 	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
 	mcr	p15, 0, r6, c10, c2, 1		@ write NMRR
+#endif
 	adr	r5, v7_crval
 	ldmia	r5, {r5, r6}
 #ifdef CONFIG_CPU_ENDIAN_BE8
@@ -273,6 +275,7 @@ __v7_setup:
    	mrc	p15, 0, r0, c1, c0, 0		@ read control register
 	bic	r0, r0, r5			@ clear bits them
 	orr	r0, r0, r6			@ set them
+ THUMB(	orr	r0, r0, #1 << 30	)	@ Thumb exceptions
 	mov	pc, lr				@ return to head.S:__ret
 ENDPROC(__v7_setup)
 
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 0cce37b..4233942 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -17,7 +17,7 @@
  *
  * 2001 Sep 08:
  *	Completely revisited, many important fixes
- *	Nicolas Pitre <nico@cam.org>
+ *	Nicolas Pitre <nico@fluxnic.net>
  */
 
 #include <linux/linkage.h>
diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c
index 9e573e7..bade586 100644
--- a/arch/arm/plat-iop/setup.c
+++ b/arch/arm/plat-iop/setup.c
@@ -1,7 +1,7 @@
 /*
  * arch/arm/plat-iop/setup.c
  *
- * Author: Nicolas Pitre <nico@cam.org>
+ * Author: Nicolas Pitre <nico@fluxnic.net>
  * Copyright (C) 2001 MontaVista Software, Inc.
  * Copyright (C) 2004 Intel Corporation.
  *
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 8986b74..ca5c7c2 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -9,6 +9,7 @@ choice
 config ARCH_MX1
 	bool "MX1-based"
 	select CPU_ARM920T
+	select COMMON_CLKDEV
 	help
 	  This enables support for systems based on the Freescale i.MX1 family
 
@@ -19,6 +20,13 @@ config ARCH_MX2
 	help
 	  This enables support for systems based on the Freescale i.MX2 family
 
+config ARCH_MX25
+	bool "MX25-based"
+	select CPU_ARM926T
+	select COMMON_CLKDEV
+	help
+	  This enables support for systems based on the Freescale i.MX25 family
+
 config ARCH_MX3
 	bool "MX3-based"
 	select CPU_V6
@@ -26,11 +34,20 @@ config ARCH_MX3
 	help
 	  This enables support for systems based on the Freescale i.MX3 family
 
+config ARCH_MXC91231
+	bool "MXC91231-based"
+	select CPU_V6
+	select COMMON_CLKDEV
+	help
+	  This enables support for systems based on the Freescale MXC91231 family
+
 endchoice
 
 source "arch/arm/mach-mx1/Kconfig"
 source "arch/arm/mach-mx2/Kconfig"
 source "arch/arm/mach-mx3/Kconfig"
+source "arch/arm/mach-mx25/Kconfig"
+source "arch/arm/mach-mxc91231/Kconfig"
 
 endmenu
 
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 92e1356..9e8fbd5 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -39,6 +39,7 @@
 #include <linux/string.h>
 
 #include <mach/clock.h>
+#include <mach/hardware.h>
 
 static LIST_HEAD(clocks);
 static DEFINE_MUTEX(clocks_mutex);
@@ -47,76 +48,6 @@ static DEFINE_MUTEX(clocks_mutex);
  * Standard clock functions defined in include/linux/clk.h
  *-------------------------------------------------------------------------*/
 
-/*
- * All the code inside #ifndef CONFIG_COMMON_CLKDEV can be removed once all
- * MXC architectures have switched to using clkdev.
- */
-#ifndef CONFIG_COMMON_CLKDEV
-/*
- * Retrieve a clock by name.
- *
- * Note that we first try to use device id on the bus
- * and clock name. If this fails, we try to use "<name>.<id>". If this fails,
- * we try to use clock name only.
- * The reference count to the clock's module owner ref count is incremented.
- */
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *p, *clk = ERR_PTR(-ENOENT);
-	int idno;
-	const char *str;
-
-	if (id == NULL)
-		return clk;
-
-	if (dev == NULL || dev->bus != &platform_bus_type)
-		idno = -1;
-	else
-		idno = to_platform_device(dev)->id;
-
-	mutex_lock(&clocks_mutex);
-
-	list_for_each_entry(p, &clocks, node) {
-		if (p->id == idno &&
-		    strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-			clk = p;
-			goto found;
-		}
-	}
-
-	str = strrchr(id, '.');
-	if (str) {
-		int cnt = str - id;
-		str++;
-		idno = simple_strtol(str, NULL, 10);
-		list_for_each_entry(p, &clocks, node) {
-			if (p->id == idno &&
-			    strlen(p->name) == cnt &&
-			    strncmp(id, p->name, cnt) == 0 &&
-			    try_module_get(p->owner)) {
-				clk = p;
-				goto found;
-			}
-		}
-	}
-
-	list_for_each_entry(p, &clocks, node) {
-		if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
-			clk = p;
-			goto found;
-		}
-	}
-
-	printk(KERN_WARNING "clk: Unable to get requested clock: %s\n", id);
-
-found:
-	mutex_unlock(&clocks_mutex);
-
-	return clk;
-}
-EXPORT_SYMBOL(clk_get);
-#endif
-
 static void __clk_disable(struct clk *clk)
 {
 	if (clk == NULL || IS_ERR(clk))
@@ -193,16 +124,6 @@ unsigned long clk_get_rate(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_get_rate);
 
-#ifndef CONFIG_COMMON_CLKDEV
-/* Decrement the clock's module reference count */
-void clk_put(struct clk *clk)
-{
-	if (clk && !IS_ERR(clk))
-		module_put(clk->owner);
-}
-EXPORT_SYMBOL(clk_put);
-#endif
-
 /* Round the requested clock rate to the nearest supported
  * rate that is less than or equal to the requested rate.
  * This is dependent on the clock's current parent.
@@ -265,80 +186,6 @@ struct clk *clk_get_parent(struct clk *clk)
 }
 EXPORT_SYMBOL(clk_get_parent);
 
-#ifndef CONFIG_COMMON_CLKDEV
-/*
- * Add a new clock to the clock tree.
- */
-int clk_register(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return -EINVAL;
-
-	mutex_lock(&clocks_mutex);
-	list_add(&clk->node, &clocks);
-	mutex_unlock(&clocks_mutex);
-
-	return 0;
-}
-EXPORT_SYMBOL(clk_register);
-
-/* Remove a clock from the clock tree */
-void clk_unregister(struct clk *clk)
-{
-	if (clk == NULL || IS_ERR(clk))
-		return;
-
-	mutex_lock(&clocks_mutex);
-	list_del(&clk->node);
-	mutex_unlock(&clocks_mutex);
-}
-EXPORT_SYMBOL(clk_unregister);
-
-#ifdef CONFIG_PROC_FS
-static int mxc_clock_read_proc(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
-{
-	struct clk *clkp;
-	char *p = page;
-	int len;
-
-	list_for_each_entry(clkp, &clocks, node) {
-		p += sprintf(p, "%s-%d:\t\t%lu, %d", clkp->name, clkp->id,
-				clk_get_rate(clkp), clkp->usecount);
-		if (clkp->parent)
-			p += sprintf(p, ", %s-%d\n", clkp->parent->name,
-				     clkp->parent->id);
-		else
-			p += sprintf(p, "\n");
-	}
-
-	len = (p - page) - off;
-	if (len < 0)
-		len = 0;
-
-	*eof = (len <= count) ? 1 : 0;
-	*start = page + off;
-
-	return len;
-}
-
-static int __init mxc_setup_proc_entry(void)
-{
-	struct proc_dir_entry *res;
-
-	res = create_proc_read_entry("cpu/clocks", 0, NULL,
-				     mxc_clock_read_proc, NULL);
-	if (!res) {
-		printk(KERN_ERR "Failed to create proc/cpu/clocks\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-late_initcall(mxc_setup_proc_entry);
-#endif /* CONFIG_PROC_FS */
-#endif
-
 /*
  * Get the resulting clock rate from a PLL register value and the input
  * frequency. PLLs with this register layout can at least be found on
@@ -363,12 +210,11 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
 
 	mfn_abs = mfn;
 
-#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21
-	if (mfn >= 0x200) {
-		mfn |= 0xFFFFFE00;
-		mfn_abs = -mfn;
-	}
-#endif
+	/* On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
+	 * 2's complements number
+	 */
+	if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
+		mfn_abs = 0x400 - mfn;
 
 	freq *= 2;
 	freq /= pd + 1;
@@ -376,8 +222,10 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
 	ll = (unsigned long long)freq * mfn_abs;
 
 	do_div(ll, mfd + 1);
-	if (mfn < 0)
+
+	if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
 		ll = -ll;
+
 	ll = (freq * mfi) + ll;
 
 	return ll;
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 7506d96..cfc4a8b 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -29,6 +29,23 @@
 static struct mxc_gpio_port *mxc_gpio_ports;
 static int gpio_table_size;
 
+#define cpu_is_mx1_mx2()	(cpu_is_mx1() || cpu_is_mx2())
+
+#define GPIO_DR		(cpu_is_mx1_mx2() ? 0x1c : 0x00)
+#define GPIO_GDIR	(cpu_is_mx1_mx2() ? 0x00 : 0x04)
+#define GPIO_PSR	(cpu_is_mx1_mx2() ? 0x24 : 0x08)
+#define GPIO_ICR1	(cpu_is_mx1_mx2() ? 0x28 : 0x0C)
+#define GPIO_ICR2	(cpu_is_mx1_mx2() ? 0x2C : 0x10)
+#define GPIO_IMR	(cpu_is_mx1_mx2() ? 0x30 : 0x14)
+#define GPIO_ISR	(cpu_is_mx1_mx2() ? 0x34 : 0x18)
+#define GPIO_ISR	(cpu_is_mx1_mx2() ? 0x34 : 0x18)
+
+#define GPIO_INT_LOW_LEV	(cpu_is_mx1_mx2() ? 0x3 : 0x0)
+#define GPIO_INT_HIGH_LEV	(cpu_is_mx1_mx2() ? 0x2 : 0x1)
+#define GPIO_INT_RISE_EDGE	(cpu_is_mx1_mx2() ? 0x0 : 0x2)
+#define GPIO_INT_FALL_EDGE	(cpu_is_mx1_mx2() ? 0x1 : 0x3)
+#define GPIO_INT_NONE		0x4
+
 /* Note: This driver assumes 32 GPIOs are handled in one register */
 
 static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
@@ -162,7 +179,6 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
 	}
 }
 
-#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX1)
 /* MX1 and MX3 has one interrupt *per* gpio port */
 static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 {
@@ -174,9 +190,7 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 
 	mxc_gpio_irq_handler(port, irq_stat);
 }
-#endif
 
-#ifdef CONFIG_ARCH_MX2
 /* MX2 has one interrupt *for all* gpio ports */
 static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 {
@@ -195,7 +209,6 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 			mxc_gpio_irq_handler(&port[i], irq_stat);
 	}
 }
-#endif
 
 static struct irq_chip gpio_irq_chip = {
 	.ack = gpio_ack_irq,
@@ -284,17 +297,18 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
 		/* its a serious configuration bug when it fails */
 		BUG_ON( gpiochip_add(&port[i].chip) < 0 );
 
-#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX1)
-		/* setup one handler for each entry */
-		set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
-		set_irq_data(port[i].irq, &port[i]);
-#endif
+		if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25()) {
+			/* setup one handler for each entry */
+			set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
+			set_irq_data(port[i].irq, &port[i]);
+		}
+	}
+
+	if (cpu_is_mx2()) {
+		/* setup one handler for all GPIO interrupts */
+		set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler);
+		set_irq_data(port[0].irq, port);
 	}
 
-#ifdef CONFIG_ARCH_MX2
-	/* setup one handler for all GPIO interrupts */
-	set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler);
-	set_irq_data(port[0].irq, port);
-#endif
 	return 0;
 }
diff --git a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
index 8769e91..0376c13 100644
--- a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
+++ b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
@@ -12,11 +12,4 @@
 #ifndef __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
 #define __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
 
-#include <mach/hardware.h>
-
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif
diff --git a/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h
new file mode 100644
index 0000000..a1fd583
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.com
+ *
+ * Based on board-pcm038.h which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__
+#define __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__
+
+#ifndef __ASSEMBLY__
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ * TODO: Add your own baseboard init function and call it from
+ * inside eukrea_cpuimx27_init().
+ *
+ * This example here is for the development board. Refer
+ * eukrea_mbimx27-baseboard.c
+ */
+
+extern void eukrea_mbimx27_baseboard_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx21ads.h b/arch/arm/plat-mxc/include/mach/board-mx21ads.h
index 06701df..0cf4fa2 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx21ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx21ads.h
@@ -15,12 +15,6 @@
 #define __ASM_ARCH_MXC_BOARD_MX21ADS_H__
 
 /*
- * MXC UART EVB board level configurations
- */
-#define MXC_LL_UART_PADDR       UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR       AIPI_IO_ADDRESS(UART1_BASE_ADDR)
-
-/*
  * Memory-mapped I/O on MX21ADS base board
  */
 #define MX21ADS_MMIO_BASE_ADDR   0xF5000000
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27ads.h b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
index d42f4e6..7776d23 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
@@ -26,12 +26,6 @@
 				MXC_MAX_VIRTUAL_INTS)
 
 /*
- * MXC UART EVB board level configurations
- */
-#define MXC_LL_UART_PADDR       UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR       AIPI_IO_ADDRESS(UART1_BASE_ADDR)
-
-/*
  * @name Memory Size parameters
  */
 
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27lite.h b/arch/arm/plat-mxc/include/mach/board-mx27lite.h
index a870f8e..ea87551 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27lite.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27lite.h
@@ -11,9 +11,4 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX27LITE_H__
 #define __ASM_ARCH_MXC_BOARD_MX27LITE_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /* __ASM_ARCH_MXC_BOARD_MX27LITE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h b/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
index 552b55d..fec1bcf 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
@@ -11,9 +11,4 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX27PDK_H__
 #define __ASM_ARCH_MXC_BOARD_MX27PDK_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /* __ASM_ARCH_MXC_BOARD_MX27PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
index 06e6895..2cbfa35 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
@@ -114,9 +114,4 @@
 
 #define MXC_MAX_EXP_IO_LINES	16
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
index 78cf31e..eb5a502 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
@@ -22,11 +22,6 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
 #define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
 
-/* mandatory for CONFIG_LL_DEBUG */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	(AIPI_BASE_ADDR_VIRT + 0x0A000)
-
 #ifndef __ASSEMBLY__
 
 enum mx31lilly_boards {
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lite.h b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
index 52fbdf2..8e64325 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31lite.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
@@ -11,8 +11,5 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__
 #define __ASM_ARCH_MXC_BOARD_MX31LITE_H__
 
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */
 
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
index 303fd24..d5be6b5 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
@@ -19,11 +19,6 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
 #define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	(AIPI_BASE_ADDR_VIRT + 0x0A000)
-
 #ifndef __ASSEMBLY__
 
 enum mx31moboard_boards {
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
index 519bab3..2bbd6ed 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31pdk.h
@@ -11,11 +11,6 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
 #define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 /* Definitions for components on the Debug board */
 
 /* Base address of CPLD controller on the Debug board */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
index 1111037..383f1c0 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
@@ -19,9 +19,4 @@
 #ifndef __ASM_ARCH_MXC_BOARD_MX35PDK_H__
 #define __ASM_ARCH_MXC_BOARD_MX35PDK_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /* __ASM_ARCH_MXC_BOARD_MX35PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm037.h b/arch/arm/plat-mxc/include/mach/board-pcm037.h
index f0a1fa1..1341170 100644
--- a/arch/arm/plat-mxc/include/mach/board-pcm037.h
+++ b/arch/arm/plat-mxc/include/mach/board-pcm037.h
@@ -19,9 +19,4 @@
 #ifndef __ASM_ARCH_MXC_BOARD_PCM037_H__
 #define __ASM_ARCH_MXC_BOARD_PCM037_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm038.h b/arch/arm/plat-mxc/include/mach/board-pcm038.h
index 4fcd749..410f978 100644
--- a/arch/arm/plat-mxc/include/mach/board-pcm038.h
+++ b/arch/arm/plat-mxc/include/mach/board-pcm038.h
@@ -19,11 +19,6 @@
 #ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__
 #define __ASM_ARCH_MXC_BOARD_PCM038_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	(AIPI_BASE_ADDR_VIRT + 0x0A000)
-
 #ifndef __ASSEMBLY__
 /*
  * This CPU module needs a baseboard to work. After basic initializing
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm043.h b/arch/arm/plat-mxc/include/mach/board-pcm043.h
index 15fbdf1..1ac4e16 100644
--- a/arch/arm/plat-mxc/include/mach/board-pcm043.h
+++ b/arch/arm/plat-mxc/include/mach/board-pcm043.h
@@ -19,9 +19,4 @@
 #ifndef __ASM_ARCH_MXC_BOARD_PCM043_H__
 #define __ASM_ARCH_MXC_BOARD_PCM043_H__
 
-/* mandatory for CONFIG_LL_DEBUG */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /* __ASM_ARCH_MXC_BOARD_PCM043_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-qong.h b/arch/arm/plat-mxc/include/mach/board-qong.h
index 04033ec..6d88c7a 100644
--- a/arch/arm/plat-mxc/include/mach/board-qong.h
+++ b/arch/arm/plat-mxc/include/mach/board-qong.h
@@ -11,11 +11,6 @@
 #ifndef __ASM_ARCH_MXC_BOARD_QONG_H__
 #define __ASM_ARCH_MXC_BOARD_QONG_H__
 
-/* mandatory for CONFIG_DEBUG_LL */
-
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
-
 /* NOR FLASH */
 #define QONG_NOR_SIZE		(128*1024*1024)
 
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 02c3cd0..286cb9b 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -16,18 +16,33 @@ struct clk;
 
 extern void mx1_map_io(void);
 extern void mx21_map_io(void);
+extern void mx25_map_io(void);
 extern void mx27_map_io(void);
 extern void mx31_map_io(void);
 extern void mx35_map_io(void);
-extern void mxc_init_irq(void);
-extern void mxc_timer_init(struct clk *timer_clk);
+extern void mxc91231_map_io(void);
+extern void mxc_init_irq(void __iomem *);
+extern void mx1_init_irq(void);
+extern void mx21_init_irq(void);
+extern void mx25_init_irq(void);
+extern void mx27_init_irq(void);
+extern void mx31_init_irq(void);
+extern void mx35_init_irq(void);
+extern void mxc91231_init_irq(void);
+extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
 extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
+extern int mx25_clocks_init(unsigned long fref);
 extern int mx27_clocks_init(unsigned long fref);
 extern int mx31_clocks_init(unsigned long fref);
 extern int mx35_clocks_init(void);
+extern int mxc91231_clocks_init(unsigned long fref);
 extern int mxc_register_gpios(void);
 extern int mxc_register_device(struct platform_device *pdev, void *data);
 extern void mxc_set_cpu_type(unsigned int type);
+extern void mxc_arch_reset_init(void __iomem *);
+extern void mxc91231_power_off(void);
+extern void mxc91231_arch_reset(int, const char *);
+extern void mxc91231_prepare_idle(void);
 
 #endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index bbc5f67..15b2b14 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -11,52 +11,52 @@
  *
  */
 
-#include <mach/hardware.h>
-
-#ifdef CONFIG_MACH_MX31ADS
-#include <mach/board-mx31ads.h>
-#endif
-#ifdef CONFIG_MACH_PCM037
-#include <mach/board-pcm037.h>
-#endif
-#ifdef CONFIG_MACH_MX31LITE
-#include <mach/board-mx31lite.h>
-#endif
-#ifdef CONFIG_MACH_MX27ADS
-#include <mach/board-mx27ads.h>
-#endif
-#ifdef CONFIG_MACH_MX21ADS
-#include <mach/board-mx21ads.h>
+#ifdef CONFIG_ARCH_MX1
+#include <mach/mx1.h>
+#define UART_PADDR	UART1_BASE_ADDR
+#define UART_VADDR	IO_ADDRESS(UART1_BASE_ADDR)
 #endif
-#ifdef CONFIG_MACH_PCM038
-#include <mach/board-pcm038.h>
+
+#ifdef CONFIG_ARCH_MX25
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
 #endif
-#ifdef CONFIG_MACH_MX31_3DS
-#include <mach/board-mx31pdk.h>
+#include <mach/mx25.h>
+#define UART_PADDR	UART1_BASE_ADDR
+#define UART_VADDR	MX25_AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
 #endif
-#ifdef CONFIG_MACH_QONG
-#include <mach/board-qong.h>
+
+#ifdef CONFIG_ARCH_MX2
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
 #endif
-#ifdef CONFIG_MACH_PCM043
-#include <mach/board-pcm043.h>
+#include <mach/mx2x.h>
+#define UART_PADDR	UART1_BASE_ADDR
+#define UART_VADDR	AIPI_IO_ADDRESS(UART1_BASE_ADDR)
 #endif
-#ifdef CONFIG_MACH_MX27_3DS
-#include <mach/board-mx27pdk.h>
+
+#ifdef CONFIG_ARCH_MX3
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
 #endif
-#ifdef CONFIG_MACH_ARMADILLO5X0
-#include <mach/board-armadillo5x0.h>
+#include <mach/mx3x.h>
+#define UART_PADDR	UART1_BASE_ADDR
+#define UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
 #endif
-#ifdef CONFIG_MACH_MX35_3DS
-#include <mach/board-mx35pdk.h>
+
+#ifdef CONFIG_ARCH_MXC91231
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
 #endif
-#ifdef CONFIG_MACH_MX27LITE
-#include <mach/board-mx27lite.h>
+#include <mach/mxc91231.h>
+#define UART_PADDR	MXC91231_UART2_BASE_ADDR
+#define UART_VADDR	MXC91231_AIPS1_IO_ADDRESS(MXC91231_UART2_BASE_ADDR)
 #endif
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
-		ldreq	\rx, =MXC_LL_UART_PADDR	@ physical
-		ldrne	\rx, =MXC_LL_UART_VADDR	@ virtual
+		ldreq	\rx, =UART_PADDR	@ physical
+		ldrne	\rx, =UART_VADDR	@ virtual
 		.endm
 
 		.macro	senduart,rd,rx
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 5f01d60..7cf290e 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -18,7 +18,8 @@
 	.endm
 
 	.macro  get_irqnr_preamble, base, tmp
-	ldr	\base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
+	ldr	\base, =avic_base
+	ldr	\base, [\base]
 #ifdef CONFIG_MXC_IRQ_PRIOR
 	ldr	r4, [\base, #AVIC_NIMASK]
 #endif
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 42e4ee3..78db754 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -42,6 +42,14 @@
 # include <mach/mx1.h>
 #endif
 
+#ifdef CONFIG_ARCH_MX25
+# include <mach/mx25.h>
+#endif
+
+#ifdef CONFIG_ARCH_MXC91231
+# include <mach/mxc91231.h>
+#endif
+
 #include <mach/mxc.h>
 
 #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h
index 9f01011..5263506 100644
--- a/arch/arm/plat-mxc/include/mach/imxfb.h
+++ b/arch/arm/plat-mxc/include/mach/imxfb.h
@@ -2,6 +2,8 @@
  * This structure describes the machine which we are running on.
  */
 
+#include <linux/fb.h>
+
 #define PCR_TFT		(1 << 31)
 #define PCR_COLOR	(1 << 30)
 #define PCR_PBSIZ_1	(0 << 28)
@@ -13,7 +15,8 @@
 #define PCR_BPIX_4	(2 << 25)
 #define PCR_BPIX_8	(3 << 25)
 #define PCR_BPIX_12	(4 << 25)
-#define PCR_BPIX_16	(4 << 25)
+#define PCR_BPIX_16	(5 << 25)
+#define PCR_BPIX_18	(6 << 25)
 #define PCR_PIXPOL	(1 << 24)
 #define PCR_FLMPOL	(1 << 23)
 #define PCR_LPPOL	(1 << 22)
@@ -46,29 +49,21 @@
 #define DMACR_HM(x)	(((x) & 0xf) << 16)
 #define DMACR_TM(x)	((x) & 0xf)
 
-struct imx_fb_platform_data {
-	u_long		pixclock;
-
-	u_short		xres;
-	u_short		yres;
-
-	u_int		nonstd;
-	u_char		bpp;
-	u_char		hsync_len;
-	u_char		left_margin;
-	u_char		right_margin;
+struct imx_fb_videomode {
+	struct fb_videomode mode;
+	u32 pcr;
+	unsigned char	bpp;
+};
 
-	u_char		vsync_len;
-	u_char		upper_margin;
-	u_char		lower_margin;
-	u_char		sync;
+struct imx_fb_platform_data {
+	struct imx_fb_videomode *mode;
+	int		num_modes;
 
 	u_int		cmap_greyscale:1,
 			cmap_inverse:1,
 			cmap_static:1,
 			unused:29;
 
-	u_int		pcr;
 	u_int		pwmr;
 	u_int		lscr1;
 	u_int		dmacr;
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
new file mode 100644
index 0000000..810c47f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
@@ -0,0 +1,517 @@
+/*
+ * arch/arm/plat-mxc/include/mach/iomux-mx25.h
+ *
+ * Copyright (C) 2009 by Lothar Wassmann <LW@KARO-electronics.de>
+ *
+ * based on arch/arm/mach-mx25/mx25_pins.h
+ *    Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * and
+ * arch/arm/plat-mxc/include/mach/iomux-mx35.h
+ *    Copyright (C, NO_PAD_CTRL) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __IOMUX_MX25_H__
+#define __IOMUX_MX25_H__
+
+#include <mach/iomux-v3.h>
+
+#ifndef GPIO_PORTA
+#error Please include mach/iomux.h
+#endif
+
+/*
+ *
+ * @brief MX25 I/O Pin List
+ *
+ * @ingroup GPIO_MX25
+ */
+
+#ifndef __ASSEMBLY__
+
+/*
+ * IOMUX/PAD Bit field definitions
+ */
+
+#define MX25_PAD_A10__A10		IOMUX_PAD(0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A10__GPIO_4_0		IOMUX_PAD(0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A13__A13		IOMUX_PAD(0x22C, 0x00c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A13__GPIO_4_1		IOMUX_PAD(0x22C, 0x00c, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A14__A14		IOMUX_PAD(0x230, 0x010, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A14__GPIO_2_0		IOMUX_PAD(0x230, 0x010, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A15__A15		IOMUX_PAD(0x234, 0x014, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A15__GPIO_2_1		IOMUX_PAD(0x234, 0x014, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A16__A16		IOMUX_PAD(0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A16__GPIO_2_2		IOMUX_PAD(0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A17__A17		IOMUX_PAD(0x238, 0x01c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A17__GPIO_2_3		IOMUX_PAD(0x238, 0x01c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A18__A18		IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A18__GPIO_2_4		IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A18__FEC_COL		IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTL)
+
+#define MX25_PAD_A19__A19		IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A19__FEC_RX_ER		IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTL)
+#define MX25_PAD_A19__GPIO_2_5		IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A20__A20		IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A20__GPIO_2_6		IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A20__FEC_RDATA2	IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTL)
+
+#define MX25_PAD_A21__A21		IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A21__GPIO_2_7		IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A21__FEC_RDATA3	IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTL)
+
+#define MX25_PAD_A22__A22		IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A22__GPIO_2_8		IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A23__A23		IOMUX_PAD(0x24c, 0x034, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A23__GPIO_2_9		IOMUX_PAD(0x24c, 0x034, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A24__A24		IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A24__GPIO_2_10		IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A24__FEC_RX_CLK	IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTL)
+
+#define MX25_PAD_A25__A25		IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A25__GPIO_2_11		IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A25__FEC_CRS		IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTL)
+
+#define MX25_PAD_EB0__EB0		IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB0__AUD4_TXD		IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB0__GPIO_2_12		IOMUX_PAD(0x258, 0x040, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_EB1__EB1		IOMUX_PAD(0x25c, 0x044, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB1__AUD4_RXD		IOMUX_PAD(0x25c, 0x044, 0x14, 0x460, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB1__GPIO_2_13		IOMUX_PAD(0x25c, 0x044, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_OE__OE			IOMUX_PAD(0x260, 0x048, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_OE__AUD4_TXC		IOMUX_PAD(0x260, 0x048, 0x14, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_OE__GPIO_2_14		IOMUX_PAD(0x260, 0x048, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS0__CS0		IOMUX_PAD(0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS0__GPIO_4_2		IOMUX_PAD(0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS1__CS1		IOMUX_PAD(0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS1__GPIO_4_3		IOMUX_PAD(0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS4__CS4		IOMUX_PAD(0x264, 0x054, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS4__UART5_CTS		IOMUX_PAD(0x264, 0x054, 0x13, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS4__GPIO_3_20		IOMUX_PAD(0x264, 0x054, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS5__CS5		IOMUX_PAD(0x268, 0x058, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS5__UART5_RTS		IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS5__GPIO_3_21		IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NF_CE0__NF_CE0		IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_NF_CE0__GPIO_3_22	IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_ECB__ECB		IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_ECB__UART5_TXD_MUX	IOMUX_PAD(0x270, 0x060, 0x13, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_ECB__GPIO_3_23		IOMUX_PAD(0x270, 0x060, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LBA__LBA		IOMUX_PAD(0x274, 0x064, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LBA__UART5_RXD_MUX	IOMUX_PAD(0x274, 0x064, 0x13, 0x578, 0, NO_PAD_CTRL)
+#define MX25_PAD_LBA__GPIO_3_24		IOMUX_PAD(0x274, 0x064, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_BCLK__BCLK		IOMUX_PAD(0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BCLK__GPIO_4_4		IOMUX_PAD(0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_RW__RW			IOMUX_PAD(0x278, 0x06c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_RW__AUD4_TXFS		IOMUX_PAD(0x278, 0x06c, 0x14, 0x474, 0, NO_PAD_CTRL)
+#define MX25_PAD_RW__GPIO_3_25		IOMUX_PAD(0x278, 0x06c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFWE_B__NFWE_B		IOMUX_PAD(0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFWE_B__GPIO_3_26	IOMUX_PAD(0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFRE_B__NFRE_B		IOMUX_PAD(0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFRE_B__GPIO_3_27	IOMUX_PAD(0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFALE__NFALE		IOMUX_PAD(0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFALE__GPIO_3_28	IOMUX_PAD(0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFCLE__NFCLE		IOMUX_PAD(0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFCLE__GPIO_3_29	IOMUX_PAD(0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFWP_B__NFWP_B		IOMUX_PAD(0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFWP_B__GPIO_3_30	IOMUX_PAD(0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFRB__NFRB		IOMUX_PAD(0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_NFRB__GPIO_3_31	IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D15__D15		IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D15__LD16		IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D15__GPIO_4_5		IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D14__D14		IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D14__LD17		IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D14__GPIO_4_6		IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D13__D13		IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D13__LD18		IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D13__GPIO_4_7		IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D12__D12		IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D12__GPIO_4_8		IOMUX_PAD(0x28c, 0x094, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D11__D11		IOMUX_PAD(0x290, 0x098, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D11__GPIO_4_9		IOMUX_PAD(0x290, 0x098, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D10__D10		IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D10__GPIO_4_10		IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D10__USBOTG_OC		IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_D9__D9			IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D9__GPIO_4_11		IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D9__USBH2_PWR		IOMUX_PAD(0x298, 0x0a0, 0x06, 0, 0, PAD_CTL_PKE)
+
+#define MX25_PAD_D8__D8			IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D8__GPIO_4_12		IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D8__USBH2_OC		IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_D7__D7			IOMUX_PAD(0x2a0, 0x0a8, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D7__GPIO_4_13		IOMUX_PAD(0x2a0, 0x0a8, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D6__D6			IOMUX_PAD(0x2a4, 0x0ac, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D6__GPIO_4_14		IOMUX_PAD(0x2a4, 0x0ac, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D5__D5			IOMUX_PAD(0x2a8, 0x0b0, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D5__GPIO_4_15		IOMUX_PAD(0x2a8, 0x0b0, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D4__D4			IOMUX_PAD(0x2ac, 0x0b4, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D4__GPIO_4_16		IOMUX_PAD(0x2ac, 0x0b4, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D3__D3			IOMUX_PAD(0x2b0, 0x0b8, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D3__GPIO_4_17		IOMUX_PAD(0x2b0, 0x0b8, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D2__D2			IOMUX_PAD(0x2b4, 0x0bc, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D2__GPIO_4_18		IOMUX_PAD(0x2b4, 0x0bc, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D1__D1			IOMUX_PAD(0x2b8, 0x0c0, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D1__GPIO_4_19		IOMUX_PAD(0x2b8, 0x0c0, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D0__D0			IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D0__GPIO_4_20		IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD0__LD0		IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD0__CSI_D0		IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD0__GPIO_2_15		IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD1__LD1		IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD1__CSI_D1		IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD1__GPIO_2_16		IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD2__LD2		IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD2__GPIO_2_17		IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD3__LD3		IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD3__GPIO_2_18		IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD4__LD4		IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD4__GPIO_2_19		IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD5__LD5		IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD5__GPIO_1_19		IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD6__LD6		IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD6__GPIO_1_20		IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD7__LD7		IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD7__GPIO_1_21		IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD8__LD8		IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD8__FEC_TX_ERR	IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTL)
+
+#define MX25_PAD_LD9__LD9		IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD9__FEC_COL		IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTL)
+
+#define MX25_PAD_LD10__LD10		IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD10__FEC_RX_ER	IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTL)
+
+#define MX25_PAD_LD11__LD11		IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD11__FEC_RDATA2	IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTL)
+
+#define MX25_PAD_LD12__LD12		IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD12__FEC_RDATA3	IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTL)
+
+#define MX25_PAD_LD13__LD13		IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD13__FEC_TDATA2	IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTL)
+
+#define MX25_PAD_LD14__LD14		IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD14__FEC_TDATA3	IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTL)
+
+#define MX25_PAD_LD15__LD15		IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD15__FEC_RX_CLK	IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTL)
+
+#define MX25_PAD_HSYNC__HSYNC		IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_HSYNC__GPIO_1_22	IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_VSYNC__VSYNC		IOMUX_PAD(0x304, 0x10c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSYNC__GPIO_1_23	IOMUX_PAD(0x304, 0x10c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LSCLK__LSCLK		IOMUX_PAD(0x308, 0x110, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LSCLK__GPIO_1_24	IOMUX_PAD(0x308, 0x110, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_OE_ACD__OE_ACD		IOMUX_PAD(0x30c, 0x114, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_OE_ACD__GPIO_1_25	IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CONTRAST__CONTRAST	IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CONTRAST__FEC_CRS	IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTL)
+
+#define MX25_PAD_PWM__PWM		IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_PWM__GPIO_1_26		IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_PWM__USBH2_OC		IOMUX_PAD(0x314, 0x11c, 0x16, 0x580, 1, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_CSI_D2__CSI_D2		IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D2__UART5_RXD_MUX	IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D2__GPIO_1_27	IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D3__CSI_D3		IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D3__GPIO_1_28	IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D4__CSI_D4		IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D4__UART5_RTS	IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D4__GPIO_1_29	IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D5__CSI_D5		IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D5__GPIO_1_30	IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D6__CSI_D6		IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D6__GPIO_1_31	IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D7__CSI_D7		IOMUX_PAD(0x32c, 0x134, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D7__GPIO_1_6	IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D8__CSI_D8		IOMUX_PAD(0x330, 0x138, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D8__GPIO_1_7	IOMUX_PAD(0x330, 0x138, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D9__CSI_D9		IOMUX_PAD(0x334, 0x13c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D9__GPIO_4_21	IOMUX_PAD(0x334, 0x13c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_MCLK__CSI_MCLK	IOMUX_PAD(0x338, 0x140, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_MCLK__GPIO_1_8	IOMUX_PAD(0x338, 0x140, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_VSYNC__CSI_VSYNC	IOMUX_PAD(0x33c, 0x144, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_VSYNC__GPIO_1_9	IOMUX_PAD(0x33c, 0x144, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_HSYNC__CSI_HSYNC	IOMUX_PAD(0x340, 0x148, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_HSYNC__GPIO_1_10	IOMUX_PAD(0x340, 0x148, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK	IOMUX_PAD(0x344, 0x14c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_PIXCLK__GPIO_1_11	IOMUX_PAD(0x344, 0x14c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_I2C1_CLK__I2C1_CLK	IOMUX_PAD(0x348, 0x150, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_I2C1_CLK__GPIO_1_12	IOMUX_PAD(0x348, 0x150, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_I2C1_DAT__I2C1_DAT	IOMUX_PAD(0x34c, 0x154, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_I2C1_DAT__GPIO_1_13	IOMUX_PAD(0x34c, 0x154, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI	IOMUX_PAD(0x350, 0x158, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_MOSI__GPIO_1_14	IOMUX_PAD(0x350, 0x158, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_MISO__CSPI1_MISO	IOMUX_PAD(0x354, 0x15c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_MISO__GPIO_1_15	IOMUX_PAD(0x354, 0x15c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_SS0__CSPI1_SS0	IOMUX_PAD(0x358, 0x160, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_SS0__GPIO_1_16	IOMUX_PAD(0x358, 0x160, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_SS1__CSPI1_SS1	IOMUX_PAD(0x35c, 0x164, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_SS1__GPIO_1_17	IOMUX_PAD(0x35c, 0x164, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK	IOMUX_PAD(0x360, 0x168, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_SCLK__GPIO_1_18	IOMUX_PAD(0x360, 0x168, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_RDY__CSPI1_RDY	IOMUX_PAD(0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_CSPI1_RDY__GPIO_2_22	IOMUX_PAD(0x364, 0x16c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_RXD__UART1_RXD	IOMUX_PAD(0x368, 0x170, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN)
+#define MX25_PAD_UART1_RXD__GPIO_4_22	IOMUX_PAD(0x368, 0x170, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_TXD__UART1_TXD	IOMUX_PAD(0x36c, 0x174, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART1_TXD__GPIO_4_23	IOMUX_PAD(0x36c, 0x174, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_RTS__UART1_RTS	IOMUX_PAD(0x370, 0x178, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_UART1_RTS__CSI_D0	IOMUX_PAD(0x370, 0x178, 0x11, 0x488, 1, NO_PAD_CTRL)
+#define MX25_PAD_UART1_RTS__GPIO_4_24	IOMUX_PAD(0x370, 0x178, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_CTS__UART1_CTS	IOMUX_PAD(0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_UART1_CTS__CSI_D1	IOMUX_PAD(0x374, 0x17c, 0x11, 0x48c, 1, NO_PAD_CTRL)
+#define MX25_PAD_UART1_CTS__GPIO_4_25	IOMUX_PAD(0x374, 0x17c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_RXD__UART2_RXD	IOMUX_PAD(0x378, 0x180, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_RXD__GPIO_4_26	IOMUX_PAD(0x378, 0x180, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_TXD__UART2_TXD	IOMUX_PAD(0x37c, 0x184, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_TXD__GPIO_4_27	IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_RTS__UART2_RTS	IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_RTS__FEC_COL	IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTL)
+#define MX25_PAD_UART2_RTS__GPIO_4_28	IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_CTS__FEC_RX_ER	IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTL)
+#define MX25_PAD_UART2_CTS__UART2_CTS	IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_CTS__GPIO_4_29	IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_CMD__SD1_CMD	IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_CMD__FEC_RDATA2	IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_CMD__GPIO_2_23	IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_CLK__SD1_CLK	IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_CLK__FEC_RDATA3	IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_CLK__GPIO_2_24	IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA0__SD1_DATA0	IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA0__GPIO_2_25	IOMUX_PAD(0x390, 0x198, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA1__SD1_DATA1	IOMUX_PAD(0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA1__AUD7_RXD	IOMUX_PAD(0x394, 0x19c, 0x13, 0x478, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA1__GPIO_2_26	IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA2__SD1_DATA2	IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA2__FEC_RX_CLK	IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_DATA2__GPIO_2_27	IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA3__SD1_DATA3	IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA3__FEC_CRS	IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTL)
+#define MX25_PAD_SD1_DATA3__GPIO_2_28	IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_ROW0__KPP_ROW0	IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_KPP_ROW0__GPIO_2_29	IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_ROW1__KPP_ROW1	IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_KPP_ROW1__GPIO_2_30	IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_ROW2__KPP_ROW2	IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_KPP_ROW2__CSI_D0	IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL)
+#define MX25_PAD_KPP_ROW2__GPIO_2_31	IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_ROW3__KPP_ROW3	IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_KPP_ROW3__CSI_LD1	IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL)
+#define MX25_PAD_KPP_ROW3__GPIO_3_0	IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL0__KPP_COL0	IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL0__GPIO_3_1	IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL1__KPP_COL1	IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL1__GPIO_3_2	IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL2__KPP_COL2	IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL2__GPIO_3_3	IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL3__KPP_COL3	IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL3__GPIO_3_4	IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_MDC__FEC_MDC	IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_MDC__AUD4_TXD	IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL)
+#define MX25_PAD_FEC_MDC__GPIO_3_5	IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_MDIO__FEC_MDIO	IOMUX_PAD(0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_22K_UP)
+#define MX25_PAD_FEC_MDIO__AUD4_RXD	IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL)
+#define MX25_PAD_FEC_MDIO__GPIO_3_6	IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TDATA0__FEC_TDATA0	IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_TDATA0__GPIO_3_7	IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TDATA1__FEC_TDATA1	IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_TDATA1__AUD4_TXFS	IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL)
+#define MX25_PAD_FEC_TDATA1__GPIO_3_8	IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TX_EN__FEC_TX_EN	IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTL)
+#define MX25_PAD_FEC_TX_EN__GPIO_3_9   	IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_RDATA0__FEC_RDATA0	IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
+#define MX25_PAD_FEC_RDATA0__GPIO_3_10	IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_RDATA1__FEC_RDATA1	IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
+#define MX25_PAD_FEC_RDATA1__GPIO_3_11	IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_RX_DV__FEC_RX_DV	IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTL)
+#define MX25_PAD_FEC_RX_DV__CAN2_RX	IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP)
+#define MX25_PAD_FEC_RX_DV__GPIO_3_12	IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK	IOMUX_PAD(0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN)
+#define MX25_PAD_FEC_TX_CLK__GPIO_3_13	IOMUX_PAD(0x3e0, 0x1e8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_RTCK__RTCK		IOMUX_PAD(0x3e4, 0x1ec, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_RTCK__OWIRE		IOMUX_PAD(0x3e4, 0x1ec, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_RTCK__GPIO_3_14	IOMUX_PAD(0x3e4, 0x1ec, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_DE_B__DE_B		IOMUX_PAD(0x3ec, 0x1f0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_DE_B__GPIO_2_20	IOMUX_PAD(0x3ec, 0x1f0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_TDO__TDO		IOMUX_PAD(0x3e8, 0x000, 0x00, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_GPIO_A__GPIO_A		IOMUX_PAD(0x3f0, 0x1f4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_A__CAN1_TX	IOMUX_PAD(0x3f0, 0x1f4, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
+#define MX25_PAD_GPIO_A__USBOTG_PWR	IOMUX_PAD(0x3f0, 0x1f4, 0x12, 0, 0, PAD_CTL_PKE)
+
+#define MX25_PAD_GPIO_B__GPIO_B		IOMUX_PAD(0x3f4, 0x1f8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_B__CAN1_RX	IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K)
+#define MX25_PAD_GPIO_B__USBOTG_OC	IOMUX_PAD(0x3f4, 0x1f8, 0x12, 0x57c, 1, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_GPIO_C__GPIO_C		IOMUX_PAD(0x3f8, 0x1fc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_C__CAN2_TX	IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
+
+#define MX25_PAD_GPIO_D__GPIO_D		IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_D__CAN2_RX	IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
+
+#define MX25_PAD_GPIO_E__GPIO_E		IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_E__AUD7_TXD	IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_GPIO_F__GPIO_F		IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_F__AUD7_TXC	IOMUX_PAD(0x404, 0x208, 0x14, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK	IOMUX_PAD(0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_EXT_ARMCLK__GPIO_3_15	IOMUX_PAD(0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK IOMUX_PAD(0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16	IOMUX_PAD(0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_VSTBY_REQ__VSTBY_REQ	IOMUX_PAD(0x408, 0x214, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_REQ__AUD7_TXFS	IOMUX_PAD(0x408, 0x214, 0x14, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_REQ__GPIO_3_17	IOMUX_PAD(0x408, 0x214, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_ACK__VSTBY_ACK	IOMUX_PAD(0x40c, 0x218, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_ACK__GPIO_3_18	IOMUX_PAD(0x40c, 0x218, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_POWER_FAIL__POWER_FAIL	IOMUX_PAD(0x410, 0x21c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_POWER_FAIL__AUD7_RXD	IOMUX_PAD(0x410, 0x21c, 0x14, 0x478, 1, NO_PAD_CTRL)
+#define MX25_PAD_POWER_FAIL__GPIO_3_19	IOMUX_PAD(0x410, 0x21c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CLKO__CLKO		IOMUX_PAD(0x414, 0x220, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CLKO__GPIO_2_21	IOMUX_PAD(0x414, 0x220, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_BOOT_MODE0__BOOT_MODE0	IOMUX_PAD(0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BOOT_MODE0__GPIO_4_30	IOMUX_PAD(0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BOOT_MODE1__BOOT_MODE1	IOMUX_PAD(0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BOOT_MODE1__GPIO_4_31	IOMUX_PAD(0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CTL_GRP_DVS_MISC	IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_FEC	IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_JTAG	IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_NFC	IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_CSI	IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_WEIM	IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_DDR	IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_CRM	IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_KPP	IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_SDHC1	IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_LCD	IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_UART	IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_NFC	IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_CSI	IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_CSPI1	IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DDRTYPE	IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_SDHC1	IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_LCD	IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+
+#endif // __ASSEMBLY__
+#endif // __IOMUX_MX25_H__
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index 2eb182f..446f867 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -635,6 +635,19 @@ enum iomux_pins {
 #define MX31_PIN_USBOTG_DIR__USBOTG_DIR        IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBOTG_NXT__USBOTG_NXT        IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USBOTG_STP__USBOTG_STP        IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM        IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_MISO__USBH1_RXDP        IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS0__USBH1_TXDM         IOMUX_MODE(MX31_PIN_CSPI1_SS0,  IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS1__USBH1_TXDP         IOMUX_MODE(MX31_PIN_CSPI1_SS1,  IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS2__USBH1_RCV          IOMUX_MODE(MX31_PIN_CSPI1_SS2,  IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SCLK__USBH1_OEB         IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS       IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_USBH2_DATA0__USBH2_DATA0      IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DATA1__USBH2_DATA1      IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_CLK__USBH2_CLK          IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DIR__USBH2_DIR          IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_NXT__USBH2_NXT          IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_STP__USBH2_STP          IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_USB_OC__GPIO1_30	IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_I2C_DAT__I2C1_SDA	IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_I2C_CLK__I2C1_SCL	IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC)
@@ -669,6 +682,18 @@ enum iomux_pins {
 #define MX31_PIN_GPIO3_0__GPIO3_0	IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_GPIO3_1__GPIO3_1	IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO)
 #define MX31_PIN_TXD2__GPIO1_28		IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_GPIO1_0__GPIO1_0	IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SVEN0__GPIO2_0		IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STX0__GPIO2_1		IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SRX0__GPIO2_2		IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SIMPD0__GPIO2_3	IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_DTR_DCE1__GPIO2_8	IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_DSR_DCE1__GPIO2_9	IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_RI_DCE1__GPIO2_10	IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_DCD_DCE1__GPIO2_11	IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STXD5__GPIO1_21       IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SRXD5__GPIO1_22       IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
+
 
 /*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0
  * cspi1_ss1*/
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
new file mode 100644
index 0000000..9f13061
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Dmitriy Taychenachev <dimichxp@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
+ */
+
+#ifndef __MACH_IOMUX_MXC91231_H__
+#define __MACH_IOMUX_MXC91231_H__
+
+/*
+ * various IOMUX output functions
+ */
+
+#define	IOMUX_OCONFIG_GPIO (0 << 4)	/* used as GPIO */
+#define	IOMUX_OCONFIG_FUNC (1 << 4)	/* used as function */
+#define	IOMUX_OCONFIG_ALT1 (2 << 4)	/* used as alternate function 1 */
+#define	IOMUX_OCONFIG_ALT2 (3 << 4)	/* used as alternate function 2 */
+#define	IOMUX_OCONFIG_ALT3 (4 << 4)	/* used as alternate function 3 */
+#define	IOMUX_OCONFIG_ALT4 (5 << 4)	/* used as alternate function 4 */
+#define	IOMUX_OCONFIG_ALT5 (6 << 4)	/* used as alternate function 5 */
+#define	IOMUX_OCONFIG_ALT6 (7 << 4)	/* used as alternate function 6 */
+#define	IOMUX_ICONFIG_NONE  0	 	/* not configured for input */
+#define	IOMUX_ICONFIG_GPIO  1		/* used as GPIO */
+#define	IOMUX_ICONFIG_FUNC  2		/* used as function */
+#define	IOMUX_ICONFIG_ALT1  4		/* used as alternate function 1 */
+#define	IOMUX_ICONFIG_ALT2  8		/* used as alternate function 2 */
+
+#define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO)
+#define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC)
+#define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1)
+#define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2)
+
+/*
+ * setups a single pin:
+ * 	- reserves the pin so that it is not claimed by another driver
+ * 	- setups the iomux according to the configuration
+ * 	- if the pin is configured as a GPIO, we claim it throug kernel gpiolib
+ */
+int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label);
+/*
+ * setups mutliple pins
+ * convenient way to call the above function with tables
+ */
+int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+		const char *label);
+
+/*
+ * releases a single pin:
+ * 	- make it available for a future use by another driver
+ * 	- frees the GPIO if the pin was configured as GPIO
+ * 	- DOES NOT reconfigure the IOMUX in its reset state
+ */
+void mxc_iomux_release_pin(const unsigned int pin_mode);
+/*
+ * releases multiple pins
+ * convenvient way to call the above function with tables
+ */
+void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count);
+
+#define MUX_SIDE_AP		(0)
+#define MUX_SIDE_SP		(1)
+
+#define MUX_SIDE_SHIFT		(26)
+#define MUX_SIDE_MASK		(0x1 << MUX_SIDE_SHIFT)
+
+#define MUX_GPIO_PORT_SHIFT	(23)
+#define MUX_GPIO_PORT_MASK	(0x7 << MUX_GPIO_PORT_SHIFT)
+
+#define MUX_GPIO_PIN_SHIFT	(20)
+#define MUX_GPIO_PIN_MASK	(0x1f << MUX_GPIO_PIN_SHIFT)
+
+#define MUX_REG_SHIFT		(15)
+#define MUX_REG_MASK		(0x1f << MUX_REG_SHIFT)
+
+#define MUX_FIELD_SHIFT		(13)
+#define MUX_FIELD_MASK		(0x3 << MUX_FIELD_SHIFT)
+
+#define MUX_PADGRP_SHIFT	(8)
+#define MUX_PADGRP_MASK		(0x1f << MUX_PADGRP_SHIFT)
+
+#define MUX_PIN_MASK		(0xffffff << 8)
+
+#define GPIO_PORT_MAX		(3)
+
+#define IOMUX_PIN(side, gport, gpin, ctlreg, ctlfield, padgrp) \
+	(((side) << MUX_SIDE_SHIFT) |		  \
+	 (gport << MUX_GPIO_PORT_SHIFT) |		\
+	 ((gpin) << MUX_GPIO_PIN_SHIFT) |		\
+	 ((ctlreg) << MUX_REG_SHIFT) |		\
+	 ((ctlfield) << MUX_FIELD_SHIFT) |		\
+	 ((padgrp) << MUX_PADGRP_SHIFT))
+
+#define MUX_MODE_OUT_SHIFT	(4)
+#define MUX_MODE_IN_SHIFT	(0)
+#define MUX_MODE_SHIFT		(0)
+#define MUX_MODE_MASK		(0xff << MUX_MODE_SHIFT)
+
+#define IOMUX_MODE(pin, mode) \
+	(pin | (mode << MUX_MODE_SHIFT))
+
+enum iomux_pins {
+	/* AP Side pins */
+	MXC91231_PIN_AP_CLE		= IOMUX_PIN(0, 0,  0,  0, 0, 24),
+	MXC91231_PIN_AP_ALE		= IOMUX_PIN(0, 0,  1,  0, 1, 24),
+	MXC91231_PIN_AP_CE_B		= IOMUX_PIN(0, 0,  2,  0, 2, 24),
+	MXC91231_PIN_AP_RE_B		= IOMUX_PIN(0, 0,  3,  0, 3, 24),
+	MXC91231_PIN_AP_WE_B		= IOMUX_PIN(0, 0,  4,  1, 0, 24),
+	MXC91231_PIN_AP_WP_B		= IOMUX_PIN(0, 0,  5,  1, 1, 24),
+	MXC91231_PIN_AP_BSY_B		= IOMUX_PIN(0, 0,  6,  1, 2, 24),
+	MXC91231_PIN_AP_U1_TXD		= IOMUX_PIN(0, 0,  7,  1, 3, 28),
+	MXC91231_PIN_AP_U1_RXD		= IOMUX_PIN(0, 0,  8,  2, 0, 28),
+	MXC91231_PIN_AP_U1_RTS_B	= IOMUX_PIN(0, 0,  9,  2, 1, 28),
+	MXC91231_PIN_AP_U1_CTS_B	= IOMUX_PIN(0, 0, 10,  2, 2, 28),
+	MXC91231_PIN_AP_AD1_TXD		= IOMUX_PIN(0, 0, 11,  2, 3,  9),
+	MXC91231_PIN_AP_AD1_RXD		= IOMUX_PIN(0, 0, 12,  3, 0,  9),
+	MXC91231_PIN_AP_AD1_TXC		= IOMUX_PIN(0, 0, 13,  3, 1,  9),
+	MXC91231_PIN_AP_AD1_TXFS	= IOMUX_PIN(0, 0, 14,  3, 2,  9),
+	MXC91231_PIN_AP_AD2_TXD		= IOMUX_PIN(0, 0, 15,  3, 3,  9),
+	MXC91231_PIN_AP_AD2_RXD		= IOMUX_PIN(0, 0, 16,  4, 0,  9),
+	MXC91231_PIN_AP_AD2_TXC		= IOMUX_PIN(0, 0, 17,  4, 1,  9),
+	MXC91231_PIN_AP_AD2_TXFS	= IOMUX_PIN(0, 0, 18,  4, 2,  9),
+	MXC91231_PIN_AP_OWDAT		= IOMUX_PIN(0, 0, 19,  4, 3, 28),
+	MXC91231_PIN_AP_IPU_LD17	= IOMUX_PIN(0, 0, 20,  5, 0, 28),
+	MXC91231_PIN_AP_IPU_D3_VSYNC	= IOMUX_PIN(0, 0, 21,  5, 1, 28),
+	MXC91231_PIN_AP_IPU_D3_HSYNC	= IOMUX_PIN(0, 0, 22,  5, 2, 28),
+	MXC91231_PIN_AP_IPU_D3_CLK	= IOMUX_PIN(0, 0, 23,  5, 3, 28),
+	MXC91231_PIN_AP_IPU_D3_DRDY	= IOMUX_PIN(0, 0, 24,  6, 0, 28),
+	MXC91231_PIN_AP_IPU_D3_CONTR	= IOMUX_PIN(0, 0, 25,  6, 1, 28),
+	MXC91231_PIN_AP_IPU_D0_CS	= IOMUX_PIN(0, 0, 26,  6, 2, 28),
+	MXC91231_PIN_AP_IPU_LD16	= IOMUX_PIN(0, 0, 27,  6, 3, 28),
+	MXC91231_PIN_AP_IPU_D2_CS	= IOMUX_PIN(0, 0, 28,  7, 0, 28),
+	MXC91231_PIN_AP_IPU_PAR_RS	= IOMUX_PIN(0, 0, 29,  7, 1, 28),
+	MXC91231_PIN_AP_IPU_D3_PS	= IOMUX_PIN(0, 0, 30,  7, 2, 28),
+	MXC91231_PIN_AP_IPU_D3_CLS	= IOMUX_PIN(0, 0, 31,  7, 3, 28),
+	MXC91231_PIN_AP_IPU_RD		= IOMUX_PIN(0, 1,  0,  8, 0, 28),
+	MXC91231_PIN_AP_IPU_WR		= IOMUX_PIN(0, 1,  1,  8, 1, 28),
+	MXC91231_PIN_AP_IPU_LD0		= IOMUX_PIN(0, 7,  0,  8, 2, 28),
+	MXC91231_PIN_AP_IPU_LD1		= IOMUX_PIN(0, 7,  0,  8, 3, 28),
+	MXC91231_PIN_AP_IPU_LD2		= IOMUX_PIN(0, 7,  0,  9, 0, 28),
+	MXC91231_PIN_AP_IPU_LD3		= IOMUX_PIN(0, 1,  2,  9, 1, 28),
+	MXC91231_PIN_AP_IPU_LD4		= IOMUX_PIN(0, 1,  3,  9, 2, 28),
+	MXC91231_PIN_AP_IPU_LD5		= IOMUX_PIN(0, 1,  4,  9, 3, 28),
+	MXC91231_PIN_AP_IPU_LD6		= IOMUX_PIN(0, 1,  5, 10, 0, 28),
+	MXC91231_PIN_AP_IPU_LD7		= IOMUX_PIN(0, 1,  6, 10, 1, 28),
+	MXC91231_PIN_AP_IPU_LD8		= IOMUX_PIN(0, 1,  7, 10, 2, 28),
+	MXC91231_PIN_AP_IPU_LD9		= IOMUX_PIN(0, 1,  8, 10, 3, 28),
+	MXC91231_PIN_AP_IPU_LD10	= IOMUX_PIN(0, 1,  9, 11, 0, 28),
+	MXC91231_PIN_AP_IPU_LD11	= IOMUX_PIN(0, 1, 10, 11, 1, 28),
+	MXC91231_PIN_AP_IPU_LD12	= IOMUX_PIN(0, 1, 11, 11, 2, 28),
+	MXC91231_PIN_AP_IPU_LD13	= IOMUX_PIN(0, 1, 12, 11, 3, 28),
+	MXC91231_PIN_AP_IPU_LD14	= IOMUX_PIN(0, 1, 13, 12, 0, 28),
+	MXC91231_PIN_AP_IPU_LD15	= IOMUX_PIN(0, 1, 14, 12, 1, 28),
+	MXC91231_PIN_AP_KPROW4		= IOMUX_PIN(0, 7,  0, 12, 2, 10),
+	MXC91231_PIN_AP_KPROW5		= IOMUX_PIN(0, 1, 16, 12, 3, 10),
+	MXC91231_PIN_AP_GPIO_AP_B17	= IOMUX_PIN(0, 1, 17, 13, 0, 10),
+	MXC91231_PIN_AP_GPIO_AP_B18	= IOMUX_PIN(0, 1, 18, 13, 1, 10),
+	MXC91231_PIN_AP_KPCOL3		= IOMUX_PIN(0, 1, 19, 13, 2, 11),
+	MXC91231_PIN_AP_KPCOL4		= IOMUX_PIN(0, 1, 20, 13, 3, 11),
+	MXC91231_PIN_AP_KPCOL5		= IOMUX_PIN(0, 1, 21, 14, 0, 11),
+	MXC91231_PIN_AP_GPIO_AP_B22	= IOMUX_PIN(0, 1, 22, 14, 1, 11),
+	MXC91231_PIN_AP_GPIO_AP_B23	= IOMUX_PIN(0, 1, 23, 14, 2, 11),
+	MXC91231_PIN_AP_CSI_D0		= IOMUX_PIN(0, 1, 24, 14, 3, 21),
+	MXC91231_PIN_AP_CSI_D1		= IOMUX_PIN(0, 1, 25, 15, 0, 21),
+	MXC91231_PIN_AP_CSI_D2		= IOMUX_PIN(0, 1, 26, 15, 1, 21),
+	MXC91231_PIN_AP_CSI_D3		= IOMUX_PIN(0, 1, 27, 15, 2, 21),
+	MXC91231_PIN_AP_CSI_D4		= IOMUX_PIN(0, 1, 28, 15, 3, 21),
+	MXC91231_PIN_AP_CSI_D5		= IOMUX_PIN(0, 1, 29, 16, 0, 21),
+	MXC91231_PIN_AP_CSI_D6		= IOMUX_PIN(0, 1, 30, 16, 1, 21),
+	MXC91231_PIN_AP_CSI_D7		= IOMUX_PIN(0, 1, 31, 16, 2, 21),
+	MXC91231_PIN_AP_CSI_D8		= IOMUX_PIN(0, 2,  0, 16, 3, 21),
+	MXC91231_PIN_AP_CSI_D9		= IOMUX_PIN(0, 2,  1, 17, 0, 21),
+	MXC91231_PIN_AP_CSI_MCLK	= IOMUX_PIN(0, 2,  2, 17, 1, 21),
+	MXC91231_PIN_AP_CSI_VSYNC	= IOMUX_PIN(0, 2,  3, 17, 2, 21),
+	MXC91231_PIN_AP_CSI_HSYNC	= IOMUX_PIN(0, 2,  4, 17, 3, 21),
+	MXC91231_PIN_AP_CSI_PIXCLK	= IOMUX_PIN(0, 2,  5, 18, 0, 21),
+	MXC91231_PIN_AP_I2CLK		= IOMUX_PIN(0, 2,  6, 18, 1, 12),
+	MXC91231_PIN_AP_I2DAT		= IOMUX_PIN(0, 2,  7, 18, 2, 12),
+	MXC91231_PIN_AP_GPIO_AP_C8	= IOMUX_PIN(0, 2,  8, 18, 3,  9),
+	MXC91231_PIN_AP_GPIO_AP_C9	= IOMUX_PIN(0, 2,  9, 19, 0,  9),
+	MXC91231_PIN_AP_GPIO_AP_C10	= IOMUX_PIN(0, 2, 10, 19, 1,  9),
+	MXC91231_PIN_AP_GPIO_AP_C11	= IOMUX_PIN(0, 2, 11, 19, 2,  9),
+	MXC91231_PIN_AP_GPIO_AP_C12	= IOMUX_PIN(0, 2, 12, 19, 3,  9),
+	MXC91231_PIN_AP_GPIO_AP_C13	= IOMUX_PIN(0, 2, 13, 20, 0, 28),
+	MXC91231_PIN_AP_GPIO_AP_C14	= IOMUX_PIN(0, 2, 14, 20, 1, 28),
+	MXC91231_PIN_AP_GPIO_AP_C15	= IOMUX_PIN(0, 2, 15, 20, 2,  9),
+	MXC91231_PIN_AP_GPIO_AP_C16	= IOMUX_PIN(0, 2, 16, 20, 3,  9),
+	MXC91231_PIN_AP_GPIO_AP_C17	= IOMUX_PIN(0, 2, 17, 21, 0,  9),
+	MXC91231_PIN_AP_ED_INT0		= IOMUX_PIN(0, 2, 18, 21, 1, 22),
+	MXC91231_PIN_AP_ED_INT1		= IOMUX_PIN(0, 2, 19, 21, 2, 22),
+	MXC91231_PIN_AP_ED_INT2		= IOMUX_PIN(0, 2, 20, 21, 3, 22),
+	MXC91231_PIN_AP_ED_INT3		= IOMUX_PIN(0, 2, 21, 22, 0, 22),
+	MXC91231_PIN_AP_ED_INT4		= IOMUX_PIN(0, 2, 22, 22, 1, 23),
+	MXC91231_PIN_AP_ED_INT5		= IOMUX_PIN(0, 2, 23, 22, 2, 23),
+	MXC91231_PIN_AP_ED_INT6		= IOMUX_PIN(0, 2, 24, 22, 3, 23),
+	MXC91231_PIN_AP_ED_INT7		= IOMUX_PIN(0, 2, 25, 23, 0, 23),
+	MXC91231_PIN_AP_U2_DSR_B	= IOMUX_PIN(0, 2, 26, 23, 1, 28),
+	MXC91231_PIN_AP_U2_RI_B		= IOMUX_PIN(0, 2, 27, 23, 2, 28),
+	MXC91231_PIN_AP_U2_CTS_B	= IOMUX_PIN(0, 2, 28, 23, 3, 28),
+	MXC91231_PIN_AP_U2_DTR_B	= IOMUX_PIN(0, 2, 29, 24, 0, 28),
+	MXC91231_PIN_AP_KPROW0		= IOMUX_PIN(0, 7,  0, 24, 1, 10),
+	MXC91231_PIN_AP_KPROW1		= IOMUX_PIN(0, 1, 15, 24, 2, 10),
+	MXC91231_PIN_AP_KPROW2		= IOMUX_PIN(0, 7,  0, 24, 3, 10),
+	MXC91231_PIN_AP_KPROW3		= IOMUX_PIN(0, 7,  0, 25, 0, 10),
+	MXC91231_PIN_AP_KPCOL0		= IOMUX_PIN(0, 7,  0, 25, 1, 11),
+	MXC91231_PIN_AP_KPCOL1		= IOMUX_PIN(0, 7,  0, 25, 2, 11),
+	MXC91231_PIN_AP_KPCOL2		= IOMUX_PIN(0, 7,  0, 25, 3, 11),
+
+	/* Shared pins */
+	MXC91231_PIN_SP_U3_TXD		= IOMUX_PIN(1, 3,  0,  0, 0, 28),
+	MXC91231_PIN_SP_U3_RXD		= IOMUX_PIN(1, 3,  1,  0, 1, 28),
+	MXC91231_PIN_SP_U3_RTS_B	= IOMUX_PIN(1, 3,  2,  0, 2, 28),
+	MXC91231_PIN_SP_U3_CTS_B	= IOMUX_PIN(1, 3,  3,  0, 3, 28),
+	MXC91231_PIN_SP_USB_TXOE_B	= IOMUX_PIN(1, 3,  4,  1, 0, 28),
+	MXC91231_PIN_SP_USB_DAT_VP	= IOMUX_PIN(1, 3,  5,  1, 1, 28),
+	MXC91231_PIN_SP_USB_SE0_VM	= IOMUX_PIN(1, 3,  6,  1, 2, 28),
+	MXC91231_PIN_SP_USB_RXD		= IOMUX_PIN(1, 3,  7,  1, 3, 28),
+	MXC91231_PIN_SP_UH2_TXOE_B	= IOMUX_PIN(1, 3,  8,  2, 0, 28),
+	MXC91231_PIN_SP_UH2_SPEED	= IOMUX_PIN(1, 3,  9,  2, 1, 28),
+	MXC91231_PIN_SP_UH2_SUSPEN	= IOMUX_PIN(1, 3, 10,  2, 2, 28),
+	MXC91231_PIN_SP_UH2_TXDP	= IOMUX_PIN(1, 3, 11,  2, 3, 28),
+	MXC91231_PIN_SP_UH2_RXDP	= IOMUX_PIN(1, 3, 12,  3, 0, 28),
+	MXC91231_PIN_SP_UH2_RXDM	= IOMUX_PIN(1, 3, 13,  3, 1, 28),
+	MXC91231_PIN_SP_UH2_OVR		= IOMUX_PIN(1, 3, 14,  3, 2, 28),
+	MXC91231_PIN_SP_UH2_PWR		= IOMUX_PIN(1, 3, 15,  3, 3, 28),
+	MXC91231_PIN_SP_SD1_DAT0	= IOMUX_PIN(1, 3, 16,  4, 0, 25),
+	MXC91231_PIN_SP_SD1_DAT1	= IOMUX_PIN(1, 3, 17,  4, 1, 25),
+	MXC91231_PIN_SP_SD1_DAT2	= IOMUX_PIN(1, 3, 18,  4, 2, 25),
+	MXC91231_PIN_SP_SD1_DAT3	= IOMUX_PIN(1, 3, 19,  4, 3, 25),
+	MXC91231_PIN_SP_SD1_CMD		= IOMUX_PIN(1, 3, 20,  5, 0, 25),
+	MXC91231_PIN_SP_SD1_CLK		= IOMUX_PIN(1, 3, 21,  5, 1, 25),
+	MXC91231_PIN_SP_SD2_DAT0	= IOMUX_PIN(1, 3, 22,  5, 2, 26),
+	MXC91231_PIN_SP_SD2_DAT1	= IOMUX_PIN(1, 3, 23,  5, 3, 26),
+	MXC91231_PIN_SP_SD2_DAT2	= IOMUX_PIN(1, 3, 24,  6, 0, 26),
+	MXC91231_PIN_SP_SD2_DAT3	= IOMUX_PIN(1, 3, 25,  6, 1, 26),
+	MXC91231_PIN_SP_GPIO_SP_A26	= IOMUX_PIN(1, 3, 26,  6, 2, 28),
+	MXC91231_PIN_SP_SPI1_CLK	= IOMUX_PIN(1, 3, 27,  6, 3, 13),
+	MXC91231_PIN_SP_SPI1_MOSI	= IOMUX_PIN(1, 3, 28,  7, 0, 13),
+	MXC91231_PIN_SP_SPI1_MISO	= IOMUX_PIN(1, 3, 29,  7, 1, 13),
+	MXC91231_PIN_SP_SPI1_SS0	= IOMUX_PIN(1, 3, 30,  7, 2, 13),
+	MXC91231_PIN_SP_SPI1_SS1	= IOMUX_PIN(1, 3, 31,  7, 3, 13),
+	MXC91231_PIN_SP_SD2_CMD		= IOMUX_PIN(1, 7,  0,  8, 0, 26),
+	MXC91231_PIN_SP_SD2_CLK		= IOMUX_PIN(1, 7,  0,  8, 1, 26),
+	MXC91231_PIN_SP_SIM1_RST_B	= IOMUX_PIN(1, 2, 30,  8, 2, 28),
+	MXC91231_PIN_SP_SIM1_SVEN	= IOMUX_PIN(1, 7,  0,  8, 3, 28),
+	MXC91231_PIN_SP_SIM1_CLK	= IOMUX_PIN(1, 7,  0,  9, 0, 28),
+	MXC91231_PIN_SP_SIM1_TRXD	= IOMUX_PIN(1, 7,  0,  9, 1, 28),
+	MXC91231_PIN_SP_SIM1_PD		= IOMUX_PIN(1, 2, 31,  9, 2, 28),
+	MXC91231_PIN_SP_UH2_TXDM	= IOMUX_PIN(1, 7,  0,  9, 3, 28),
+	MXC91231_PIN_SP_UH2_RXD		= IOMUX_PIN(1, 7,  0, 10, 0, 28),
+};
+
+#define PIN_AP_MAX	(104)
+#define PIN_SP_MAX	(41)
+
+#define PIN_MAX		(PIN_AP_MAX + PIN_SP_MAX)
+
+/*
+ * Convenience values for use with mxc_iomux_mode()
+ *
+ * Format here is MXC91231_PIN_(pin name)__(function)
+ */
+
+#define MXC91231_PIN_SP_USB_DAT_VP__USB_DAT_VP \
+	IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_FUNC)
+#define MXC91231_PIN_SP_USB_SE0_VM__USB_SE0_VM \
+	IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_FUNC)
+#define MXC91231_PIN_SP_USB_DAT_VP__RXD2 \
+	IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_ALT1)
+#define MXC91231_PIN_SP_USB_SE0_VM__TXD2 \
+	IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_ALT1)
+
+
+#endif /* __MACH_IOMUX_MXC91231_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
index 7cd8454..a0fa402 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
@@ -68,28 +68,24 @@ struct pad_desc {
 /*
  * Use to set PAD control
  */
-#define PAD_CTL_DRIVE_VOLTAGE_3_3_V	0
-#define PAD_CTL_DRIVE_VOLTAGE_1_8_V	1
 
-#define PAD_CTL_NO_HYSTERESIS		0
-#define PAD_CTL_HYSTERESIS		1
+#define PAD_CTL_DVS			(1 << 13)
+#define PAD_CTL_HYS			(1 << 8)
 
-#define PAD_CTL_PULL_DISABLED		0x0
-#define PAD_CTL_PULL_KEEPER		0xa
-#define PAD_CTL_PULL_DOWN_100K		0xc
-#define PAD_CTL_PULL_UP_47K		0xd
-#define PAD_CTL_PULL_UP_100K		0xe
-#define PAD_CTL_PULL_UP_22K		0xf
+#define PAD_CTL_PKE			(1 << 7)
+#define PAD_CTL_PUE			(1 << 6)
+#define PAD_CTL_PUS_100K_DOWN		(0 << 4)
+#define PAD_CTL_PUS_47K_UP		(1 << 4)
+#define PAD_CTL_PUS_100K_UP		(2 << 4)
+#define PAD_CTL_PUS_22K_UP		(3 << 4)
 
-#define PAD_CTL_OUTPUT_CMOS		0
-#define PAD_CTL_OUTPUT_OPEN_DRAIN	1
+#define PAD_CTL_ODE			(1 << 3)
 
-#define PAD_CTL_DRIVE_STRENGTH_NORM	0
-#define PAD_CTL_DRIVE_STRENGTH_HIGH	1
-#define PAD_CTL_DRIVE_STRENGTH_MAX	2
+#define PAD_CTL_DSE_STANDARD		(0 << 1)
+#define PAD_CTL_DSE_HIGH		(1 << 1)
+#define PAD_CTL_DSE_MAX			(2 << 1)
 
-#define PAD_CTL_SLEW_RATE_SLOW		0
-#define PAD_CTL_SLEW_RATE_FAST		1
+#define PAD_CTL_SRE_FAST		(1 << 0)
 
 /*
  * setups a single pad:
@@ -117,5 +113,10 @@ void mxc_iomux_v3_release_pad(struct pad_desc *pad);
  */
 void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count);
 
+/*
+ * Initialise the iomux controller
+ */
+void mxc_iomux_v3_init(void __iomem *iomux_v3_base);
+
 #endif /* __MACH_IOMUX_V3_H__*/
 
diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h
index 171f8ad..6d49f8a 100644
--- a/arch/arm/plat-mxc/include/mach/iomux.h
+++ b/arch/arm/plat-mxc/include/mach/iomux.h
@@ -49,6 +49,9 @@
 #ifdef CONFIG_ARCH_MX2
 # define GPIO_PORT_MAX  5
 #endif
+#ifdef CONFIG_ARCH_MX25
+# define GPIO_PORT_MAX  3
+#endif
 
 #ifndef GPIO_PORT_MAX
 # error "GPIO config port count unknown!"
@@ -107,6 +110,9 @@
 #include <mach/iomux-mx27.h>
 #endif
 #endif
+#ifdef CONFIG_ARCH_MX25
+#include <mach/iomux-mx25.h>
+#endif
 
 
 /* decode irq number to use with IMR(x), ISR(x) and friends */
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 518a365..ead9d59 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -24,6 +24,10 @@
 #define MXC_GPIO_IRQS		(32 * 6)
 #elif defined CONFIG_ARCH_MX3
 #define MXC_GPIO_IRQS		(32 * 3)
+#elif defined CONFIG_ARCH_MX25
+#define MXC_GPIO_IRQS		(32 * 4)
+#elif defined CONFIG_ARCH_MXC91231
+#define MXC_GPIO_IRQS		(32 * 4)
 #endif
 
 /*
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 6065e00..d3afafd 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -22,6 +22,10 @@
 #endif
 #elif defined CONFIG_ARCH_MX3
 #define PHYS_OFFSET		UL(0x80000000)
+#elif defined CONFIG_ARCH_MX25
+#define PHYS_OFFSET		UL(0x80000000)
+#elif defined CONFIG_ARCH_MXC91231
+#define PHYS_OFFSET		UL(0x90000000)
 #endif
 
 #if defined(CONFIG_MX1_VIDEO)
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/plat-mxc/include/mach/mx1.h
index 1000bf3..1b2890a 100644
--- a/arch/arm/plat-mxc/include/mach/mx1.h
+++ b/arch/arm/plat-mxc/include/mach/mx1.h
@@ -12,10 +12,6 @@
 #ifndef __ASM_ARCH_MXC_MX1_H__
 #define __ASM_ARCH_MXC_MX1_H__
 
-#ifndef __ASM_ARCH_MXC_HARDWARE_H__
-#error "Do not include directly."
-#endif
-
 #include <mach/vmalloc.h>
 
 /*
@@ -138,20 +134,6 @@
 #define GPIO_INT_PORTD		62
 #define WDT_INT			63
 
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR		 	0x1C
-#define GPIO_GDIR	 	0x00
-#define GPIO_PSR	 	0x24
-#define GPIO_ICR1	 	0x28
-#define GPIO_ICR2	 	0x2C
-#define GPIO_IMR	 	0x30
-#define GPIO_ISR	 	0x34
-#define GPIO_INT_LOW_LEV	0x3
-#define GPIO_INT_HIGH_LEV	0x2
-#define GPIO_INT_RISE_EDGE 	0x0
-#define GPIO_INT_FALL_EDGE	0x1
-#define GPIO_INT_NONE		0x4
-
 /* DMA */
 #define DMA_REQ_UART3_T		2
 #define DMA_REQ_UART3_R		3
@@ -179,8 +161,4 @@
 #define DMA_REQ_UART1_T		30
 #define DMA_REQ_UART1_R		31
 
-/* mandatory for CONFIG_DEBUG_LL */
-#define MXC_LL_UART_PADDR	UART1_BASE_ADDR
-#define MXC_LL_UART_VADDR	IO_ADDRESS(UART1_BASE_ADDR)
-
 #endif /*  __ASM_ARCH_MXC_MX1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h
index 8b070a0..21112c6 100644
--- a/arch/arm/plat-mxc/include/mach/mx21.h
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -25,11 +25,6 @@
 #ifndef __ASM_ARCH_MXC_MX21_H__
 #define __ASM_ARCH_MXC_MX21_H__
 
-#ifndef __ASM_ARCH_MXC_HARDWARE_H__
-#error "Do not include directly."
-#endif
-
-
 /* Memory regions and CS */
 #define SDRAM_BASE_ADDR         0xC0000000
 #define CSD1_BASE_ADDR          0xC4000000
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
new file mode 100644
index 0000000..ec64bd9
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -0,0 +1,44 @@
+#ifndef __MACH_MX25_H__
+#define __MACH_MX25_H__
+
+#define MX25_AIPS1_BASE_ADDR		0x43F00000
+#define MX25_AIPS1_BASE_ADDR_VIRT	0xFC000000
+#define MX25_AIPS1_SIZE			SZ_1M
+#define MX25_AIPS2_BASE_ADDR		0x53F00000
+#define MX25_AIPS2_BASE_ADDR_VIRT	0xFC200000
+#define MX25_AIPS2_SIZE			SZ_1M
+#define MX25_AVIC_BASE_ADDR		0x68000000
+#define MX25_AVIC_BASE_ADDR_VIRT	0xFC400000
+#define MX25_AVIC_SIZE			SZ_1M
+
+#define MX25_IOMUXC_BASE_ADDR		(MX25_AIPS1_BASE_ADDR + 0xac000)
+
+#define MX25_CRM_BASE_ADDR		(MX25_AIPS2_BASE_ADDR + 0x80000)
+#define MX25_GPT1_BASE_ADDR		(MX25_AIPS2_BASE_ADDR + 0x90000)
+#define MX25_WDOG_BASE_ADDR		(MX25_AIPS2_BASE_ADDR + 0xdc000)
+
+#define MX25_GPIO1_BASE_ADDR_VIRT	(MX25_AIPS2_BASE_ADDR_VIRT + 0xcc000)
+#define MX25_GPIO2_BASE_ADDR_VIRT	(MX25_AIPS2_BASE_ADDR_VIRT + 0xd0000)
+#define MX25_GPIO3_BASE_ADDR_VIRT	(MX25_AIPS2_BASE_ADDR_VIRT + 0xa4000)
+#define MX25_GPIO4_BASE_ADDR_VIRT	(MX25_AIPS2_BASE_ADDR_VIRT + 0x9c000)
+
+#define MX25_AIPS1_IO_ADDRESS(x)  \
+	(((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT)
+#define MX25_AIPS2_IO_ADDRESS(x)  \
+	(((x) - MX25_AIPS2_BASE_ADDR) + MX25_AIPS2_BASE_ADDR_VIRT)
+#define MX25_AVIC_IO_ADDRESS(x)  \
+	(((x) - MX25_AVIC_BASE_ADDR) + MX25_AVIC_BASE_ADDR_VIRT)
+
+#define __in_range(addr, name)	((addr) >= name##_BASE_ADDR && (addr) < name##_BASE_ADDR + name##_SIZE)
+
+#define MX25_IO_ADDRESS(x)					\
+	(void __force __iomem *)				\
+	(__in_range(x, MX25_AIPS1) ? MX25_AIPS1_IO_ADDRESS(x) :	\
+	__in_range(x, MX25_AIPS2) ? MX25_AIPS2_IO_ADDRESS(x) :	\
+	__in_range(x, MX25_AVIC) ? MX25_AVIC_IO_ADDRESS(x) :	\
+	0xDEADBEEF)
+
+#define UART1_BASE_ADDR			0x43f90000
+#define UART2_BASE_ADDR			0x43f94000
+
+#endif /* __MACH_MX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index 6e93f2c..dc3ad9a 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -24,10 +24,6 @@
 #ifndef __ASM_ARCH_MXC_MX27_H__
 #define __ASM_ARCH_MXC_MX27_H__
 
-#ifndef __ASM_ARCH_MXC_HARDWARE_H__
-#error "Do not include directly."
-#endif
-
 /* IRAM */
 #define IRAM_BASE_ADDR          0xFFFF4C00	/* internal ram */
 
@@ -120,7 +116,4 @@ extern int mx27_revision(void);
 
 /* Mandatory defines used globally */
 
-/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */
-#define ARCH_NR_GPIOS		(192 + 16)
-
 #endif /* __ASM_ARCH_MXC_MX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/plat-mxc/include/mach/mx2x.h
index fc40d3a..db5d921 100644
--- a/arch/arm/plat-mxc/include/mach/mx2x.h
+++ b/arch/arm/plat-mxc/include/mach/mx2x.h
@@ -23,10 +23,6 @@
 #ifndef __ASM_ARCH_MXC_MX2x_H__
 #define __ASM_ARCH_MXC_MX2x_H__
 
-#ifndef __ASM_ARCH_MXC_HARDWARE_H__
-#error "Do not include directly."
-#endif
-
 /* The following addresses are common between i.MX21 and i.MX27 */
 
 /* Register offests */
@@ -154,20 +150,6 @@
 #define MXC_INT_GPIO		8
 #define MXC_INT_CSPI3		6
 
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR		 	0x1C
-#define GPIO_GDIR	 	0x00
-#define GPIO_PSR	 	0x24
-#define GPIO_ICR1	 	0x28
-#define GPIO_ICR2	 	0x2C
-#define GPIO_IMR	 	0x30
-#define GPIO_ISR	 	0x34
-#define GPIO_INT_LOW_LEV	0x3
-#define GPIO_INT_HIGH_LEV	0x2
-#define GPIO_INT_RISE_EDGE 	0x0
-#define GPIO_INT_FALL_EDGE	0x1
-#define GPIO_INT_NONE		0x4
-
 /* fixed DMA request numbers */
 #define DMA_REQ_CSI_RX          31
 #define DMA_REQ_CSI_STAT        30
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index 0b06941..14ac0dc 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -4,7 +4,7 @@
 #define MX31_IRAM_BASE_ADDR		0x1FFC0000	/* internal ram */
 #define MX31_IRAM_SIZE			SZ_16K
 
-#define OTG_BASE_ADDR		(AIPS1_BASE_ADDR + 0x00088000)
+#define MX31_OTG_BASE_ADDR	(AIPS1_BASE_ADDR + 0x00088000)
 #define ATA_BASE_ADDR		(AIPS1_BASE_ADDR + 0x0008C000)
 #define UART4_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x000B0000)
 #define UART5_BASE_ADDR 	(AIPS1_BASE_ADDR + 0x000B4000)
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
index 6465fef..ab4cfec 100644
--- a/arch/arm/plat-mxc/include/mach/mx35.h
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -5,6 +5,7 @@
 #define MX35_IRAM_SIZE		SZ_128K
 
 #define MXC_FEC_BASE_ADDR	0x50038000
+#define MX35_OTG_BASE_ADDR	0x53ff4000
 #define MX35_NFC_BASE_ADDR	0xBB000000
 
 /*
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h
index b559a4b..009f444 100644
--- a/arch/arm/plat-mxc/include/mach/mx3x.h
+++ b/arch/arm/plat-mxc/include/mach/mx3x.h
@@ -11,10 +11,6 @@
 #ifndef __ASM_ARCH_MXC_MX31_H__
 #define __ASM_ARCH_MXC_MX31_H__
 
-#ifndef __ASM_ARCH_MXC_HARDWARE_H__
-#error "Do not include directly."
-#endif
-
 /*
  * MX31 memory map:
  *
@@ -263,25 +259,8 @@
 #define SYSTEM_REV_MIN		CHIP_REV_1_0
 #define SYSTEM_REV_NUM		3
 
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR		 	0x00
-#define GPIO_GDIR	 	0x04
-#define GPIO_PSR	 	0x08
-#define GPIO_ICR1	 	0x0C
-#define GPIO_ICR2	 	0x10
-#define GPIO_IMR	 	0x14
-#define GPIO_ISR	 	0x18
-#define GPIO_INT_LOW_LEV	0x0
-#define GPIO_INT_HIGH_LEV	0x1
-#define GPIO_INT_RISE_EDGE	0x2
-#define GPIO_INT_FALL_EDGE	0x3
-#define GPIO_INT_NONE		0x4
-
 /* Mandatory defines used globally */
 
-/* this CPU supports up to 96 GPIOs */
-#define ARCH_NR_GPIOS		96
-
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 
 extern unsigned int system_rev;
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 5fa2a07..5199053 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -26,9 +26,11 @@
 
 #define MXC_CPU_MX1		1
 #define MXC_CPU_MX21		21
+#define MXC_CPU_MX25		25
 #define MXC_CPU_MX27		27
 #define MXC_CPU_MX31		31
 #define MXC_CPU_MX35		35
+#define MXC_CPU_MXC91231	91231
 
 #ifndef __ASSEMBLY__
 extern unsigned int __mxc_cpu_type;
@@ -58,6 +60,18 @@ extern unsigned int __mxc_cpu_type;
 # define cpu_is_mx21()		(0)
 #endif
 
+#ifdef CONFIG_ARCH_MX25
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX25
+# endif
+# define cpu_is_mx25()		(mxc_cpu_type == MXC_CPU_MX25)
+#else
+# define cpu_is_mx25()		(0)
+#endif
+
 #ifdef CONFIG_MACH_MX27
 # ifdef mxc_cpu_type
 #  undef mxc_cpu_type
@@ -94,13 +108,25 @@ extern unsigned int __mxc_cpu_type;
 # define cpu_is_mx35()		(0)
 #endif
 
+#ifdef CONFIG_ARCH_MXC91231
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MXC91231
+# endif
+# define cpu_is_mxc91231()	(mxc_cpu_type == MXC_CPU_MXC91231)
+#else
+# define cpu_is_mxc91231()	(0)
+#endif
+
 #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
 #define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10)
 #define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4)
 #define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
 #endif
 
-#define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35())
+#define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
 #define cpu_is_mx2()	(cpu_is_mx21() || cpu_is_mx27())
 
 #endif /*  __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc91231.h b/arch/arm/plat-mxc/include/mach/mxc91231.h
new file mode 100644
index 0000000..81484d1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc91231.h
@@ -0,0 +1,315 @@
+/*
+ *  Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ *    - Platform specific register memory map
+ *
+ *  Copyright 2005-2007 Motorola, 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 __MACH_MXC91231_H__
+#define __MACH_MXC91231_H__
+
+/*
+ * L2CC
+ */
+#define MXC91231_L2CC_BASE_ADDR		0x30000000
+#define MXC91231_L2CC_BASE_ADDR_VIRT	0xF9000000
+#define MXC91231_L2CC_SIZE		SZ_64K
+
+/*
+ * AIPS 1
+ */
+#define MXC91231_AIPS1_BASE_ADDR	0x43F00000
+#define MXC91231_AIPS1_BASE_ADDR_VIRT	0xFC000000
+#define MXC91231_AIPS1_SIZE		SZ_1M
+
+#define MXC91231_AIPS1_CTRL_BASE_ADDR	MXC91231_AIPS1_BASE_ADDR
+#define MXC91231_MAX_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x04000)
+#define MXC91231_EVTMON_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x08000)
+#define MXC91231_CLKCTL_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x0C000)
+#define MXC91231_ETB_SLOT4_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x10000)
+#define MXC91231_ETB_SLOT5_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x14000)
+#define MXC91231_ECT_CTIO_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x18000)
+#define MXC91231_I2C_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x80000)
+#define MXC91231_MU_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x88000)
+#define MXC91231_UART1_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x90000)
+#define MXC91231_UART2_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x94000)
+#define MXC91231_DSM_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x98000)
+#define MXC91231_OWIRE_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x9C000)
+#define MXC91231_SSI1_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0xA0000)
+#define MXC91231_KPP_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0xA8000)
+#define MXC91231_IOMUX_AP_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0xAC000)
+#define MXC91231_CTI_AP_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0xB8000)
+
+/*
+ * AIPS 2
+ */
+#define MXC91231_AIPS2_BASE_ADDR	0x53F00000
+#define MXC91231_AIPS2_BASE_ADDR_VIRT	0xFC100000
+#define MXC91231_AIPS2_SIZE		SZ_1M
+
+#define MXC91231_GEMK_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0x8C000)
+#define MXC91231_GPT1_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0x90000)
+#define MXC91231_EPIT1_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0x94000)
+#define MXC91231_SCC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xAC000)
+#define MXC91231_RNGA_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xB0000)
+#define MXC91231_IPU_CTRL_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xC0000)
+#define MXC91231_AUDMUX_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xC4000)
+#define MXC91231_EDIO_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xC8000)
+#define MXC91231_GPIO1_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xCC000)
+#define MXC91231_GPIO2_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xD0000)
+#define MXC91231_SDMA_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xD4000)
+#define MXC91231_RTC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xD8000)
+#define MXC91231_WDOG1_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xDC000)
+#define MXC91231_PWM_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xE0000)
+#define MXC91231_GPIO3_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xE4000)
+#define MXC91231_WDOG2_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xE8000)
+#define MXC91231_RTIC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xEC000)
+#define MXC91231_LPMC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xF0000)
+
+/*
+ * SPBA global module 0
+ */
+#define MXC91231_SPBA0_BASE_ADDR	0x50000000
+#define MXC91231_SPBA0_BASE_ADDR_VIRT	0xFC200000
+#define MXC91231_SPBA0_SIZE		SZ_1M
+
+#define MXC91231_MMC_SDHC1_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x04000)
+#define MXC91231_MMC_SDHC2_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x08000)
+#define MXC91231_UART3_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x0C000)
+#define MXC91231_CSPI2_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x10000)
+#define MXC91231_SSI2_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x14000)
+#define MXC91231_SIM_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x18000)
+#define MXC91231_IIM_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x1C000)
+#define MXC91231_CTI_SDMA_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x20000)
+#define MXC91231_USBOTG_CTRL_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x24000)
+#define MXC91231_USBOTG_DATA_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x28000)
+#define MXC91231_CSPI1_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x30000)
+#define MXC91231_SPBA_CTRL_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x3C000)
+#define MXC91231_IOMUX_COM_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x40000)
+#define MXC91231_CRM_COM_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x44000)
+#define MXC91231_CRM_AP_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x48000)
+#define MXC91231_PLL0_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x4C000)
+#define MXC91231_PLL1_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x50000)
+#define MXC91231_PLL2_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x54000)
+#define MXC91231_GPIO4_SH_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x58000)
+#define MXC91231_HAC_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x5C000)
+#define MXC91231_SAHARA_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x5C000)
+#define MXC91231_PLL3_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x60000)
+
+/*
+ * SPBA global module 1
+ */
+#define MXC91231_SPBA1_BASE_ADDR	0x52000000
+#define MXC91231_SPBA1_BASE_ADDR_VIRT	0xFC300000
+#define MXC91231_SPBA1_SIZE		SZ_1M
+
+#define MXC91231_MQSPI_BASE_ADDR	(MXC91231_SPBA1_BASE_ADDR + 0x34000)
+#define MXC91231_EL1T_BASE_ADDR		(MXC91231_SPBA1_BASE_ADDR + 0x38000)
+
+/*!
+ * Defines for SPBA modules
+ */
+#define MXC91231_SPBA_SDHC1		0x04
+#define MXC91231_SPBA_SDHC2		0x08
+#define MXC91231_SPBA_UART3		0x0C
+#define MXC91231_SPBA_CSPI2		0x10
+#define MXC91231_SPBA_SSI2		0x14
+#define MXC91231_SPBA_SIM		0x18
+#define MXC91231_SPBA_IIM		0x1C
+#define MXC91231_SPBA_CTI_SDMA		0x20
+#define MXC91231_SPBA_USBOTG_CTRL_REGS	0x24
+#define MXC91231_SPBA_USBOTG_DATA_REGS	0x28
+#define MXC91231_SPBA_CSPI1		0x30
+#define MXC91231_SPBA_MQSPI		0x34
+#define MXC91231_SPBA_EL1T		0x38
+#define MXC91231_SPBA_IOMUX		0x40
+#define MXC91231_SPBA_CRM_COM		0x44
+#define MXC91231_SPBA_CRM_AP		0x48
+#define MXC91231_SPBA_PLL0		0x4C
+#define MXC91231_SPBA_PLL1		0x50
+#define MXC91231_SPBA_PLL2		0x54
+#define MXC91231_SPBA_GPIO4		0x58
+#define MXC91231_SPBA_SAHARA		0x5C
+
+/*
+ * ROMP and AVIC
+ */
+#define MXC91231_ROMP_BASE_ADDR		0x60000000
+#define MXC91231_ROMP_BASE_ADDR_VIRT	0xFC400000
+#define MXC91231_ROMP_SIZE		SZ_64K
+
+#define MXC91231_AVIC_BASE_ADDR		0x68000000
+#define MXC91231_AVIC_BASE_ADDR_VIRT	0xFC410000
+#define MXC91231_AVIC_SIZE		SZ_64K
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define MXC91231_X_MEMC_BASE_ADDR	0xB8000000
+#define MXC91231_X_MEMC_BASE_ADDR_VIRT	0xFC420000
+#define MXC91231_X_MEMC_SIZE		SZ_64K
+
+#define MXC91231_NFC_BASE_ADDR		(MXC91231_X_MEMC_BASE_ADDR + 0x0000)
+#define MXC91231_ESDCTL_BASE_ADDR	(MXC91231_X_MEMC_BASE_ADDR + 0x1000)
+#define MXC91231_WEIM_BASE_ADDR		(MXC91231_X_MEMC_BASE_ADDR + 0x2000)
+#define MXC91231_M3IF_BASE_ADDR		(MXC91231_X_MEMC_BASE_ADDR + 0x3000)
+#define MXC91231_EMI_CTL_BASE_ADDR	(MXC91231_X_MEMC_BASE_ADDR + 0x4000)
+
+/*
+ * Memory regions and CS
+ * CPLD is connected on CS4
+ * CS5 is TP1021 or it is not connected
+ * */
+#define MXC91231_FB_RAM_BASE_ADDR	0x78000000
+#define MXC91231_FB_RAM_SIZE		SZ_256K
+#define MXC91231_CSD0_BASE_ADDR		0x80000000
+#define MXC91231_CSD1_BASE_ADDR		0x90000000
+#define MXC91231_CS0_BASE_ADDR		0xA0000000
+#define MXC91231_CS1_BASE_ADDR		0xA8000000
+#define MXC91231_CS2_BASE_ADDR		0xB0000000
+#define MXC91231_CS3_BASE_ADDR		0xB2000000
+#define MXC91231_CS4_BASE_ADDR		0xB4000000
+#define MXC91231_CS5_BASE_ADDR		0xB6000000
+
+/* Is given address belongs to the specified memory region? */
+#define ADDRESS_IN_REGION(addr, start, size) \
+	(((addr) >= (start)) && ((addr) < (start)+(size)))
+
+/* Is given address belongs to the specified named `module'? */
+#define MXC91231_IS_MODULE(addr, module) \
+	ADDRESS_IN_REGION(addr, MXC91231_ ## module ## _BASE_ADDR, \
+	                        MXC91231_ ## module ## _SIZE)
+/*
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+
+#define MXC91231_IO_ADDRESS(x) \
+	(void __iomem *) \
+	(MXC91231_IS_MODULE(x, L2CC) ? MXC91231_L2CC_IO_ADDRESS(x) : \
+	 MXC91231_IS_MODULE(x, AIPS1) ? MXC91231_AIPS1_IO_ADDRESS(x) : \
+	 MXC91231_IS_MODULE(x, AIPS2) ? MXC91231_AIPS2_IO_ADDRESS(x) : \
+	 MXC91231_IS_MODULE(x, SPBA0) ? MXC91231_SPBA0_IO_ADDRESS(x) : \
+	 MXC91231_IS_MODULE(x, SPBA1) ? MXC91231_SPBA1_IO_ADDRESS(x) : \
+	 MXC91231_IS_MODULE(x, ROMP) ? MXC91231_ROMP_IO_ADDRESS(x) : \
+	 MXC91231_IS_MODULE(x, AVIC) ? MXC91231_AVIC_IO_ADDRESS(x) : \
+	 MXC91231_IS_MODULE(x, X_MEMC) ? MXC91231_X_MEMC_IO_ADDRESS(x) : \
+	 0xDEADBEEF)
+
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+#define MXC91231_L2CC_IO_ADDRESS(x)  \
+	(((x) - MXC91231_L2CC_BASE_ADDR) + MXC91231_L2CC_BASE_ADDR_VIRT)
+
+#define MXC91231_AIPS1_IO_ADDRESS(x)  \
+	(((x) - MXC91231_AIPS1_BASE_ADDR) + MXC91231_AIPS1_BASE_ADDR_VIRT)
+
+#define MXC91231_SPBA0_IO_ADDRESS(x)  \
+	(((x) - MXC91231_SPBA0_BASE_ADDR) + MXC91231_SPBA0_BASE_ADDR_VIRT)
+
+#define MXC91231_SPBA1_IO_ADDRESS(x)  \
+	(((x) - MXC91231_SPBA1_BASE_ADDR) + MXC91231_SPBA1_BASE_ADDR_VIRT)
+
+#define MXC91231_AIPS2_IO_ADDRESS(x)  \
+	(((x) - MXC91231_AIPS2_BASE_ADDR) + MXC91231_AIPS2_BASE_ADDR_VIRT)
+
+#define MXC91231_ROMP_IO_ADDRESS(x)  \
+	(((x) - MXC91231_ROMP_BASE_ADDR) + MXC91231_ROMP_BASE_ADDR_VIRT)
+
+#define MXC91231_AVIC_IO_ADDRESS(x)  \
+	(((x) - MXC91231_AVIC_BASE_ADDR) + MXC91231_AVIC_BASE_ADDR_VIRT)
+
+#define MXC91231_X_MEMC_IO_ADDRESS(x)  \
+	(((x) - MXC91231_X_MEMC_BASE_ADDR) + MXC91231_X_MEMC_BASE_ADDR_VIRT)
+
+/*
+ * Interrupt numbers
+ */
+#define MXC91231_INT_GPIO3		0
+#define MXC91231_INT_EL1T_CI		1
+#define MXC91231_INT_EL1T_RFCI		2
+#define MXC91231_INT_EL1T_RFI		3
+#define MXC91231_INT_EL1T_MCU		4
+#define MXC91231_INT_EL1T_IPI		5
+#define MXC91231_INT_MU_GEN		6
+#define MXC91231_INT_GPIO4		7
+#define MXC91231_INT_MMC_SDHC2		8
+#define MXC91231_INT_MMC_SDHC1		9
+#define MXC91231_INT_I2C		10
+#define MXC91231_INT_SSI2		11
+#define MXC91231_INT_SSI1		12
+#define MXC91231_INT_CSPI2		13
+#define MXC91231_INT_CSPI1		14
+#define MXC91231_INT_RTIC		15
+#define MXC91231_INT_SAHARA		15
+#define MXC91231_INT_HAC		15
+#define MXC91231_INT_UART3_RX		16
+#define MXC91231_INT_UART3_TX		17
+#define MXC91231_INT_UART3_MINT		18
+#define MXC91231_INT_ECT		19
+#define MXC91231_INT_SIM_IPB		20
+#define MXC91231_INT_SIM_DATA		21
+#define MXC91231_INT_RNGA		22
+#define MXC91231_INT_DSM_AP		23
+#define MXC91231_INT_KPP		24
+#define MXC91231_INT_RTC		25
+#define MXC91231_INT_PWM		26
+#define MXC91231_INT_GEMK_AP		27
+#define MXC91231_INT_EPIT		28
+#define MXC91231_INT_GPT		29
+#define MXC91231_INT_UART2_RX		30
+#define MXC91231_INT_UART2_TX		31
+#define MXC91231_INT_UART2_MINT		32
+#define MXC91231_INT_NANDFC		33
+#define MXC91231_INT_SDMA		34
+#define MXC91231_INT_USB_WAKEUP		35
+#define MXC91231_INT_USB_SOF		36
+#define MXC91231_INT_PMU_EVTMON		37
+#define MXC91231_INT_USB_FUNC		38
+#define MXC91231_INT_USB_DMA		39
+#define MXC91231_INT_USB_CTRL		40
+#define MXC91231_INT_IPU_ERR		41
+#define MXC91231_INT_IPU_SYN		42
+#define MXC91231_INT_UART1_RX		43
+#define MXC91231_INT_UART1_TX		44
+#define MXC91231_INT_UART1_MINT		45
+#define MXC91231_INT_IIM		46
+#define MXC91231_INT_MU_RX_OR		47
+#define MXC91231_INT_MU_TX_OR		48
+#define MXC91231_INT_SCC_SCM		49
+#define MXC91231_INT_SCC_SMN		50
+#define MXC91231_INT_GPIO2		51
+#define MXC91231_INT_GPIO1		52
+#define MXC91231_INT_MQSPI1		53
+#define MXC91231_INT_MQSPI2		54
+#define MXC91231_INT_WDOG2		55
+#define MXC91231_INT_EXT_INT7		56
+#define MXC91231_INT_EXT_INT6		57
+#define MXC91231_INT_EXT_INT5		58
+#define MXC91231_INT_EXT_INT4		59
+#define MXC91231_INT_EXT_INT3		60
+#define MXC91231_INT_EXT_INT2		61
+#define MXC91231_INT_EXT_INT1		62
+#define MXC91231_INT_EXT_INT0		63
+
+#define MXC91231_MAX_INT_LINES		63
+#define MXC91231_MAX_EXT_LINES		8
+
+#endif /* __MACH_MXC91231_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index e56241a..ef00199 100644
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -21,8 +21,18 @@
 #ifndef __ASM_ARCH_MXC_SYSTEM_H__
 #define __ASM_ARCH_MXC_SYSTEM_H__
 
+#include <mach/hardware.h>
+#include <mach/common.h>
+
 static inline void arch_idle(void)
 {
+#ifdef CONFIG_ARCH_MXC91231
+	if (cpu_is_mxc91231()) {
+		/* Need this to set DSM low-power mode */
+		mxc91231_prepare_idle();
+	}
+#endif
+
 	cpu_do_idle();
 }
 
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h
index 07b4a73..527a6c2 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/arch/arm/plat-mxc/include/mach/timex.h
@@ -26,6 +26,10 @@
 #define CLOCK_TICK_RATE		13300000
 #elif defined CONFIG_ARCH_MX3
 #define CLOCK_TICK_RATE		16625000
+#elif defined CONFIG_ARCH_MX25
+#define CLOCK_TICK_RATE		16000000
+#elif defined CONFIG_ARCH_MXC91231
+#define CLOCK_TICK_RATE		13000000
 #endif
 
 #endif				/* __ASM_ARCH_MXC_TIMEX_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index de6fe03..082a390 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -26,8 +26,11 @@
 #define __MXC_BOOT_UNCOMPRESS
 
 #include <mach/hardware.h>
+#include <asm/mach-types.h>
 
-#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
+static unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
 
 #define USR2 0x98
 #define USR2_TXFE (1<<14)
@@ -46,19 +49,10 @@
 
 static void putc(int ch)
 {
-	static unsigned long serial_port = 0;
-
-	if (unlikely(serial_port == 0)) {
-		do {
-			serial_port = UART1_BASE_ADDR;
-			if (UART(UCR1) & UCR1_UARTEN)
-				break;
-			serial_port = UART2_BASE_ADDR;
-			if (UART(UCR1) & UCR1_UARTEN)
-				break;
-			return;
-		} while (0);
-	}
+	if (!uart_base)
+		return;
+	if (!(UART(UCR1) & UCR1_UARTEN))
+		return;
 
 	while (!(UART(USR2) & USR2_TXFE))
 		barrier();
@@ -68,11 +62,49 @@ static void putc(int ch)
 
 #define flush() do { } while (0)
 
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
+#define MX1_UART1_BASE_ADDR	0x00206000
+#define MX25_UART1_BASE_ADDR	0x43f90000
+#define MX2X_UART1_BASE_ADDR	0x1000a000
+#define MX3X_UART1_BASE_ADDR	0x43F90000
+#define MX3X_UART2_BASE_ADDR	0x43F94000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+	switch (arch_id) {
+	case MACH_TYPE_MX1ADS:
+	case MACH_TYPE_SCB9328:
+		uart_base = MX1_UART1_BASE_ADDR;
+		break;
+	case MACH_TYPE_MX25_3DS:
+		uart_base = MX25_UART1_BASE_ADDR;
+		break;
+	case MACH_TYPE_IMX27LITE:
+	case MACH_TYPE_MX27_3DS:
+	case MACH_TYPE_MX27ADS:
+	case MACH_TYPE_PCM038:
+	case MACH_TYPE_MX21ADS:
+		uart_base = MX2X_UART1_BASE_ADDR;
+		break;
+	case MACH_TYPE_MX31LITE:
+	case MACH_TYPE_ARMADILLO5X0:
+	case MACH_TYPE_MX31MOBOARD:
+	case MACH_TYPE_QONG:
+	case MACH_TYPE_MX31_3DS:
+	case MACH_TYPE_PCM037:
+	case MACH_TYPE_MX31ADS:
+	case MACH_TYPE_MX35_3DS:
+	case MACH_TYPE_PCM043:
+		uart_base = MX3X_UART1_BASE_ADDR;
+		break;
+	case MACH_TYPE_MAGX_ZN5:
+		uart_base = MX3X_UART2_BASE_ADDR;
+		break;
+	default:
+		break;
+	}
+}
 
+#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
 #define arch_decomp_wdog()
 
 #endif				/* __ASM_ARCH_MXC_UNCOMPRESS_H__ */
diff --git a/arch/arm/plat-mxc/iomux-v3.c b/arch/arm/plat-mxc/iomux-v3.c
index 77a078f..851ca99 100644
--- a/arch/arm/plat-mxc/iomux-v3.c
+++ b/arch/arm/plat-mxc/iomux-v3.c
@@ -29,7 +29,7 @@
 #include <asm/mach/map.h>
 #include <mach/iomux-v3.h>
 
-#define IOMUX_BASE	IO_ADDRESS(IOMUXC_BASE_ADDR)
+static void __iomem *base;
 
 static unsigned long iomux_v3_pad_alloc_map[0x200 / BITS_PER_LONG];
 
@@ -45,14 +45,14 @@ int mxc_iomux_v3_setup_pad(struct pad_desc *pad)
 	if (test_and_set_bit(pad_ofs >> 2, iomux_v3_pad_alloc_map))
 		return -EBUSY;
 	if (pad->mux_ctrl_ofs)
-		__raw_writel(pad->mux_mode, IOMUX_BASE + pad->mux_ctrl_ofs);
+		__raw_writel(pad->mux_mode, base + pad->mux_ctrl_ofs);
 
 	if (pad->select_input_ofs)
 		__raw_writel(pad->select_input,
-				IOMUX_BASE + pad->select_input_ofs);
+				base + pad->select_input_ofs);
 
-	if (!(pad->pad_ctrl & NO_PAD_CTRL))
-		__raw_writel(pad->pad_ctrl, IOMUX_BASE + pad->pad_ctrl_ofs);
+	if (!(pad->pad_ctrl & NO_PAD_CTRL) && pad->pad_ctrl_ofs)
+		__raw_writel(pad->pad_ctrl, base + pad->pad_ctrl_ofs);
 	return 0;
 }
 EXPORT_SYMBOL(mxc_iomux_v3_setup_pad);
@@ -96,3 +96,8 @@ void mxc_iomux_v3_release_multiple_pads(struct pad_desc *pad_list, int count)
 	}
 }
 EXPORT_SYMBOL(mxc_iomux_v3_release_multiple_pads);
+
+void mxc_iomux_v3_init(void __iomem *iomux_v3_base)
+{
+	base = iomux_v3_base;
+}
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 8aee763..778ddfe 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -44,7 +44,7 @@
 #define AVIC_FIPNDH		0x60	/* fast int pending high */
 #define AVIC_FIPNDL		0x64	/* fast int pending low */
 
-static void __iomem *avic_base;
+void __iomem *avic_base;
 
 int imx_irq_set_priority(unsigned char irq, unsigned char prio)
 {
@@ -113,11 +113,11 @@ static struct irq_chip mxc_avic_chip = {
  * interrupts. It registers the interrupt enable and disable functions
  * to the kernel for each interrupt source.
  */
-void __init mxc_init_irq(void)
+void __init mxc_init_irq(void __iomem *irqbase)
 {
 	int i;
 
-	avic_base = IO_ADDRESS(AVIC_BASE_ADDR);
+	avic_base = irqbase;
 
 	/* put the AVIC into the reset value with
 	 * all interrupts disabled
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index ae34198..5cdbd60 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -32,6 +32,7 @@
 #define MX3_PWMPR                 0x10    /* PWM Period Register */
 #define MX3_PWMCR_PRESCALER(x)    (((x - 1) & 0xFFF) << 4)
 #define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
+#define MX3_PWMCR_CLKSRC_IPG      (1 << 16)
 #define MX3_PWMCR_EN              (1 << 0)
 
 
@@ -55,9 +56,11 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
 	if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
 		return -EINVAL;
 
-	if (cpu_is_mx27() || cpu_is_mx3()) {
+	if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) {
 		unsigned long long c;
 		unsigned long period_cycles, duty_cycles, prescale;
+		u32 cr;
+
 		c = clk_get_rate(pwm->clk);
 		c = c * period_ns;
 		do_div(c, 1000000000);
@@ -72,9 +75,15 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
 
 		writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
 		writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
-		writel(MX3_PWMCR_PRESCALER(prescale - 1) |
-			MX3_PWMCR_CLKSRC_IPG_HIGH | MX3_PWMCR_EN,
-			pwm->mmio_base + MX3_PWMCR);
+
+		cr = MX3_PWMCR_PRESCALER(prescale) | MX3_PWMCR_EN;
+
+		if (cpu_is_mx25())
+			cr |= MX3_PWMCR_CLKSRC_IPG;
+		else
+			cr |= MX3_PWMCR_CLKSRC_IPG_HIGH;
+
+		writel(cr, pwm->mmio_base + MX3_PWMCR);
 	} else if (cpu_is_mx1() || cpu_is_mx21()) {
 		/* The PWM subsystem allows for exact frequencies. However,
 		 * I cannot connect a scope on my device to the PWM line and
@@ -118,6 +127,8 @@ EXPORT_SYMBOL(pwm_enable);
 
 void pwm_disable(struct pwm_device *pwm)
 {
+	writel(0, pwm->mmio_base + MX3_PWMCR);
+
 	if (pwm->clk_enabled) {
 		clk_disable(pwm->clk);
 		pwm->clk_enabled = 0;
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index 79c3757..97f4279 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -27,32 +27,38 @@
 #include <linux/delay.h>
 
 #include <mach/hardware.h>
+#include <mach/common.h>
 #include <asm/proc-fns.h>
 #include <asm/system.h>
 
-#ifdef CONFIG_ARCH_MX1
-#define WDOG_WCR_REG		IO_ADDRESS(WDT_BASE_ADDR)
-#define WDOG_WCR_ENABLE		(1 << 0)
-#else
-#define WDOG_WCR_REG		IO_ADDRESS(WDOG_BASE_ADDR)
-#define WDOG_WCR_ENABLE		(1 << 2)
-#endif
+static void __iomem *wdog_base;
 
 /*
  * Reset the system. It is called by machine_restart().
  */
 void arch_reset(char mode, const char *cmd)
 {
-	if (!cpu_is_mx1()) {
+	unsigned int wcr_enable;
+
+#ifdef CONFIG_ARCH_MXC91231
+	if (cpu_is_mxc91231()) {
+		mxc91231_arch_reset(mode, cmd);
+		return;
+	}
+#endif
+	if (cpu_is_mx1()) {
+		wcr_enable = (1 << 0);
+	} else {
 		struct clk *clk;
 
 		clk = clk_get_sys("imx-wdt.0", NULL);
 		if (!IS_ERR(clk))
 			clk_enable(clk);
+		wcr_enable = (1 << 2);
 	}
 
 	/* Assert SRS signal */
-	__raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG);
+	__raw_writew(wcr_enable, wdog_base);
 
 	/* wait for reset to assert... */
 	mdelay(500);
@@ -65,3 +71,8 @@ void arch_reset(char mode, const char *cmd)
 	/* we'll take a jump through zero as a poor second */
 	cpu_reset(0);
 }
+
+void mxc_arch_reset_init(void __iomem *base)
+{
+	wdog_base = base;
+}
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 88fb3a5..844567e 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -47,7 +47,7 @@
 #define MX2_TSTAT_CAPT		(1 << 1)
 #define MX2_TSTAT_COMP		(1 << 0)
 
-/* MX31, MX35 */
+/* MX31, MX35, MX25, MXC91231 */
 #define MX3_TCTL_WAITEN		(1 << 3)
 #define MX3_TCTL_CLK_IPG	(1 << 6)
 #define MX3_TCTL_FRR		(1 << 9)
@@ -66,7 +66,7 @@ static inline void gpt_irq_disable(void)
 {
 	unsigned int tmp;
 
-	if (cpu_is_mx3())
+	if (cpu_is_mx3() || cpu_is_mx25())
 		__raw_writel(0, timer_base + MX3_IR);
 	else {
 		tmp = __raw_readl(timer_base + MXC_TCTL);
@@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void)
 
 static inline void gpt_irq_enable(void)
 {
-	if (cpu_is_mx3())
+	if (cpu_is_mx3() || cpu_is_mx25())
 		__raw_writel(1<<0, timer_base + MX3_IR);
 	else {
 		__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
@@ -90,7 +90,7 @@ static void gpt_irq_acknowledge(void)
 		__raw_writel(0, timer_base + MX1_2_TSTAT);
 	if (cpu_is_mx2())
 		__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT);
-	if (cpu_is_mx3())
+	if (cpu_is_mx3() || cpu_is_mx25())
 		__raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT);
 }
 
@@ -117,7 +117,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (cpu_is_mx3())
+	if (cpu_is_mx3() || cpu_is_mx25())
 		clocksource_mxc.read = mx3_get_cycles;
 
 	clocksource_mxc.mult = clocksource_hz2mult(c,
@@ -180,7 +180,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
 
 	if (mode != clockevent_mode) {
 		/* Set event time into far-far future */
-		if (cpu_is_mx3())
+		if (cpu_is_mx3() || cpu_is_mx25())
 			__raw_writel(__raw_readl(timer_base + MX3_TCN) - 3,
 					timer_base + MX3_TCMP);
 		else
@@ -233,7 +233,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 	struct clock_event_device *evt = &clockevent_mxc;
 	uint32_t tstat;
 
-	if (cpu_is_mx3())
+	if (cpu_is_mx3() || cpu_is_mx25())
 		tstat = __raw_readl(timer_base + MX3_TSTAT);
 	else
 		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
@@ -264,7 +264,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (cpu_is_mx3())
+	if (cpu_is_mx3() || cpu_is_mx25())
 		clockevent_mxc.set_next_event = mx3_set_next_event;
 
 	clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
@@ -281,30 +281,13 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
 	return 0;
 }
 
-void __init mxc_timer_init(struct clk *timer_clk)
+void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 {
 	uint32_t tctl_val;
-	int irq;
 
 	clk_enable(timer_clk);
 
-	if (cpu_is_mx1()) {
-#ifdef CONFIG_ARCH_MX1
-		timer_base = IO_ADDRESS(TIM1_BASE_ADDR);
-		irq = TIM1_INT;
-#endif
-	} else if (cpu_is_mx2()) {
-#ifdef CONFIG_ARCH_MX2
-		timer_base = IO_ADDRESS(GPT1_BASE_ADDR);
-		irq = MXC_INT_GPT1;
-#endif
-	} else if (cpu_is_mx3()) {
-#ifdef CONFIG_ARCH_MX3
-		timer_base = IO_ADDRESS(GPT1_BASE_ADDR);
-		irq = MXC_INT_GPT;
-#endif
-	} else
-		BUG();
+	timer_base = base;
 
 	/*
 	 * Initialise to a known state (all timers off, and timing reset)
@@ -313,7 +296,7 @@ void __init mxc_timer_init(struct clk *timer_clk)
 	__raw_writel(0, timer_base + MXC_TCTL);
 	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
 
-	if (cpu_is_mx3())
+	if (cpu_is_mx3() || cpu_is_mx25())
 		tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN;
 	else
 		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index efe85d0..64b3f52 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -120,6 +120,10 @@ config OMAP_MBOX_FWK
 config OMAP_IOMMU
 	tristate
 
+config OMAP_IOMMU_DEBUG
+	depends on OMAP_IOMMU
+	tristate
+
 choice
         prompt "System timer"
 	default OMAP_MPU_TIMER
@@ -183,6 +187,19 @@ config OMAP_SERIAL_WAKE
 	  to data on the serial RX line. This allows you to wake the
 	  system from serial console.
 
+choice
+	prompt "OMAP PM layer selection"
+	depends on ARCH_OMAP
+	default OMAP_PM_NOOP
+
+config OMAP_PM_NONE
+	bool "No PM layer"
+
+config OMAP_PM_NOOP
+	bool "No-op/debug PM layer"
+
+endchoice
+
 endmenu
 
 endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index a832795..98f0191 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -12,8 +12,13 @@ obj-  :=
 # OCPI interconnect support for 1710, 1610 and 5912
 obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
 
+# omap_device support (OMAP2+ only at the moment)
+obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
+
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
+obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
 
 obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
 obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
@@ -25,3 +30,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
 # OMAP mailbox framework
 obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
 
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
\ No newline at end of file
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index e8c327a..bf880e9 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -488,7 +488,7 @@ static int __init clk_debugfs_init(void)
 	}
 	return 0;
 err_out:
-	debugfs_remove(clk_debugfs_root); /* REVISIT: Cleanup correctly */
+	debugfs_remove_recursive(clk_debugfs_root);
 	return err;
 }
 late_initcall(clk_debugfs_init);
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index ebcf006..3a4768d 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -54,50 +54,6 @@ static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
 	struct omap_board_config_kernel *kinfo = NULL;
 	int i;
 
-#ifdef CONFIG_OMAP_BOOT_TAG
-	struct omap_board_config_entry *info = NULL;
-
-	if (omap_bootloader_tag_len > 4)
-		info = (struct omap_board_config_entry *) omap_bootloader_tag;
-	while (info != NULL) {
-		u8 *next;
-
-		if (info->tag == tag) {
-			if (skip == 0)
-				break;
-			skip--;
-		}
-
-		if ((info->len & 0x03) != 0) {
-			/* We bail out to avoid an alignment fault */
-			printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n",
-			       info->len, info->tag);
-			return NULL;
-		}
-		next = (u8 *) info + sizeof(*info) + info->len;
-		if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
-			info = NULL;
-		else
-			info = (struct omap_board_config_entry *) next;
-	}
-	if (info != NULL) {
-		/* Check the length as a lame attempt to check for
-		 * binary inconsistency. */
-		if (len != NO_LENGTH_CHECK) {
-			/* Word-align len */
-			if (len & 0x03)
-				len = (len + 3) & ~0x03;
-			if (info->len != len) {
-				printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
-				       tag, len, info->len);
-				return NULL;
-			}
-		}
-		if (len_out != NULL)
-			*len_out = info->len;
-		return info->data;
-	}
-#endif
 	/* Try to find the config from the board-specific structures
 	 * in the kernel. */
 	for (i = 0; i < omap_board_config_size; i++) {
@@ -127,50 +83,6 @@ const void *omap_get_var_config(u16 tag, size_t *len)
 }
 EXPORT_SYMBOL(omap_get_var_config);
 
-static int __init omap_add_serial_console(void)
-{
-	const struct omap_serial_console_config *con_info;
-	const struct omap_uart_config *uart_info;
-	static char speed[11], *opt = NULL;
-	int line, i, uart_idx;
-
-	uart_info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
-	con_info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
-					struct omap_serial_console_config);
-	if (uart_info == NULL || con_info == NULL)
-		return 0;
-
-	if (con_info->console_uart == 0)
-		return 0;
-
-	if (con_info->console_speed) {
-		snprintf(speed, sizeof(speed), "%u", con_info->console_speed);
-		opt = speed;
-	}
-
-	uart_idx = con_info->console_uart - 1;
-	if (uart_idx >= OMAP_MAX_NR_PORTS) {
-		printk(KERN_INFO "Console: external UART#%d. "
-			"Not adding it as console this time.\n",
-			uart_idx + 1);
-		return 0;
-	}
-	if (!(uart_info->enabled_uarts & (1 << uart_idx))) {
-		printk(KERN_ERR "Console: Selected UART#%d is "
-			"not enabled for this platform\n",
-			uart_idx + 1);
-		return -1;
-	}
-	line = 0;
-	for (i = 0; i < uart_idx; i++) {
-		if (uart_info->enabled_uarts & (1 << i))
-			line++;
-	}
-	return add_preferred_console("ttyS", line, opt);
-}
-console_initcall(omap_add_serial_console);
-
-
 /*
  * 32KHz clocksource ... always available, on pretty most chips except
  * OMAP 730 and 1510.  Other timers could be used as clocksources, with
@@ -253,11 +165,8 @@ static struct clocksource clocksource_32k = {
  */
 unsigned long long sched_clock(void)
 {
-	unsigned long long ret;
-
-	ret = (unsigned long long)clocksource_32k.read(&clocksource_32k);
-	ret = (ret * clocksource_32k.mult_orig) >> clocksource_32k.shift;
-	return ret;
+	return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
+				  clocksource_32k.mult, clocksource_32k.shift);
 }
 
 static int __init omap_init_clocksource_32k(void)
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c
index be4eefd..9395898 100644
--- a/arch/arm/plat-omap/debug-leds.c
+++ b/arch/arm/plat-omap/debug-leds.c
@@ -281,24 +281,27 @@ static int /* __init */ fpga_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int fpga_suspend_late(struct platform_device *pdev, pm_message_t mesg)
+static int fpga_suspend_noirq(struct device *dev)
 {
 	__raw_writew(~0, &fpga->leds);
 	return 0;
 }
 
-static int fpga_resume_early(struct platform_device *pdev)
+static int fpga_resume_noirq(struct device *dev)
 {
 	__raw_writew(~hw_led_state, &fpga->leds);
 	return 0;
 }
 
+static struct dev_pm_ops fpga_dev_pm_ops = {
+	.suspend_noirq = fpga_suspend_noirq,
+	.resume_noirq = fpga_resume_noirq,
+};
 
 static struct platform_driver led_driver = {
 	.driver.name	= "omap_dbg_led",
+	.driver.pm	= &fpga_dev_pm_ops,
 	.probe		= fpga_probe,
-	.suspend_late	= fpga_suspend_late,
-	.resume_early	= fpga_resume_early,
 };
 
 static int __init fpga_init(void)
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 9b00f4c..fd3154a 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2347,16 +2347,16 @@ static int __init omap_init_dma(void)
 	int ch, r;
 
 	if (cpu_class_is_omap1()) {
-		omap_dma_base = IO_ADDRESS(OMAP1_DMA_BASE);
+		omap_dma_base = OMAP1_IO_ADDRESS(OMAP1_DMA_BASE);
 		dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
 	} else if (cpu_is_omap24xx()) {
-		omap_dma_base = IO_ADDRESS(OMAP24XX_DMA4_BASE);
+		omap_dma_base = OMAP2_IO_ADDRESS(OMAP24XX_DMA4_BASE);
 		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
 	} else if (cpu_is_omap34xx()) {
-		omap_dma_base = IO_ADDRESS(OMAP34XX_DMA4_BASE);
+		omap_dma_base = OMAP2_IO_ADDRESS(OMAP34XX_DMA4_BASE);
 		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
 	} else if (cpu_is_omap44xx()) {
-		omap_dma_base = IO_ADDRESS(OMAP44XX_DMA4_BASE);
+		omap_dma_base = OMAP2_IO_ADDRESS(OMAP44XX_DMA4_BASE);
 		dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
 	} else {
 		pr_err("DMA init failed for unsupported omap\n");
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 7f50b61..d325b54 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -774,7 +774,10 @@ int __init omap_dm_timer_init(void)
 
 	for (i = 0; i < dm_timer_count; i++) {
 		timer = &dm_timers[i];
-		timer->io_base = IO_ADDRESS(timer->phys_base);
+		if (cpu_class_is_omap1())
+			timer->io_base = OMAP1_IO_ADDRESS(timer->phys_base);
+		else
+			timer->io_base = OMAP2_IO_ADDRESS(timer->phys_base);
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
 					defined(CONFIG_ARCH_OMAP4)
 		if (cpu_class_is_omap2()) {
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 9298bc0..693839c 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -31,7 +31,7 @@
 /*
  * OMAP1510 GPIO registers
  */
-#define OMAP1510_GPIO_BASE		IO_ADDRESS(0xfffce000)
+#define OMAP1510_GPIO_BASE		OMAP1_IO_ADDRESS(0xfffce000)
 #define OMAP1510_GPIO_DATA_INPUT	0x00
 #define OMAP1510_GPIO_DATA_OUTPUT	0x04
 #define OMAP1510_GPIO_DIR_CONTROL	0x08
@@ -45,10 +45,10 @@
 /*
  * OMAP1610 specific GPIO registers
  */
-#define OMAP1610_GPIO1_BASE		IO_ADDRESS(0xfffbe400)
-#define OMAP1610_GPIO2_BASE		IO_ADDRESS(0xfffbec00)
-#define OMAP1610_GPIO3_BASE		IO_ADDRESS(0xfffbb400)
-#define OMAP1610_GPIO4_BASE		IO_ADDRESS(0xfffbbc00)
+#define OMAP1610_GPIO1_BASE		OMAP1_IO_ADDRESS(0xfffbe400)
+#define OMAP1610_GPIO2_BASE		OMAP1_IO_ADDRESS(0xfffbec00)
+#define OMAP1610_GPIO3_BASE		OMAP1_IO_ADDRESS(0xfffbb400)
+#define OMAP1610_GPIO4_BASE		OMAP1_IO_ADDRESS(0xfffbbc00)
 #define OMAP1610_GPIO_REVISION		0x0000
 #define OMAP1610_GPIO_SYSCONFIG		0x0010
 #define OMAP1610_GPIO_SYSSTATUS		0x0014
@@ -70,12 +70,12 @@
 /*
  * OMAP730 specific GPIO registers
  */
-#define OMAP730_GPIO1_BASE		IO_ADDRESS(0xfffbc000)
-#define OMAP730_GPIO2_BASE		IO_ADDRESS(0xfffbc800)
-#define OMAP730_GPIO3_BASE		IO_ADDRESS(0xfffbd000)
-#define OMAP730_GPIO4_BASE		IO_ADDRESS(0xfffbd800)
-#define OMAP730_GPIO5_BASE		IO_ADDRESS(0xfffbe000)
-#define OMAP730_GPIO6_BASE		IO_ADDRESS(0xfffbe800)
+#define OMAP730_GPIO1_BASE		OMAP1_IO_ADDRESS(0xfffbc000)
+#define OMAP730_GPIO2_BASE		OMAP1_IO_ADDRESS(0xfffbc800)
+#define OMAP730_GPIO3_BASE		OMAP1_IO_ADDRESS(0xfffbd000)
+#define OMAP730_GPIO4_BASE		OMAP1_IO_ADDRESS(0xfffbd800)
+#define OMAP730_GPIO5_BASE		OMAP1_IO_ADDRESS(0xfffbe000)
+#define OMAP730_GPIO6_BASE		OMAP1_IO_ADDRESS(0xfffbe800)
 #define OMAP730_GPIO_DATA_INPUT		0x00
 #define OMAP730_GPIO_DATA_OUTPUT	0x04
 #define OMAP730_GPIO_DIR_CONTROL	0x08
@@ -86,12 +86,12 @@
 /*
  * OMAP850 specific GPIO registers
  */
-#define OMAP850_GPIO1_BASE		IO_ADDRESS(0xfffbc000)
-#define OMAP850_GPIO2_BASE		IO_ADDRESS(0xfffbc800)
-#define OMAP850_GPIO3_BASE		IO_ADDRESS(0xfffbd000)
-#define OMAP850_GPIO4_BASE		IO_ADDRESS(0xfffbd800)
-#define OMAP850_GPIO5_BASE		IO_ADDRESS(0xfffbe000)
-#define OMAP850_GPIO6_BASE		IO_ADDRESS(0xfffbe800)
+#define OMAP850_GPIO1_BASE		OMAP1_IO_ADDRESS(0xfffbc000)
+#define OMAP850_GPIO2_BASE		OMAP1_IO_ADDRESS(0xfffbc800)
+#define OMAP850_GPIO3_BASE		OMAP1_IO_ADDRESS(0xfffbd000)
+#define OMAP850_GPIO4_BASE		OMAP1_IO_ADDRESS(0xfffbd800)
+#define OMAP850_GPIO5_BASE		OMAP1_IO_ADDRESS(0xfffbe000)
+#define OMAP850_GPIO6_BASE		OMAP1_IO_ADDRESS(0xfffbe800)
 #define OMAP850_GPIO_DATA_INPUT		0x00
 #define OMAP850_GPIO_DATA_OUTPUT	0x04
 #define OMAP850_GPIO_DIR_CONTROL	0x08
@@ -99,19 +99,21 @@
 #define OMAP850_GPIO_INT_MASK		0x10
 #define OMAP850_GPIO_INT_STATUS		0x14
 
+#define OMAP1_MPUIO_VBASE		OMAP1_IO_ADDRESS(OMAP1_MPUIO_BASE)
+
 /*
  * omap24xx specific GPIO registers
  */
-#define OMAP242X_GPIO1_BASE		IO_ADDRESS(0x48018000)
-#define OMAP242X_GPIO2_BASE		IO_ADDRESS(0x4801a000)
-#define OMAP242X_GPIO3_BASE		IO_ADDRESS(0x4801c000)
-#define OMAP242X_GPIO4_BASE		IO_ADDRESS(0x4801e000)
+#define OMAP242X_GPIO1_BASE		OMAP2_IO_ADDRESS(0x48018000)
+#define OMAP242X_GPIO2_BASE		OMAP2_IO_ADDRESS(0x4801a000)
+#define OMAP242X_GPIO3_BASE		OMAP2_IO_ADDRESS(0x4801c000)
+#define OMAP242X_GPIO4_BASE		OMAP2_IO_ADDRESS(0x4801e000)
 
-#define OMAP243X_GPIO1_BASE		IO_ADDRESS(0x4900C000)
-#define OMAP243X_GPIO2_BASE		IO_ADDRESS(0x4900E000)
-#define OMAP243X_GPIO3_BASE		IO_ADDRESS(0x49010000)
-#define OMAP243X_GPIO4_BASE		IO_ADDRESS(0x49012000)
-#define OMAP243X_GPIO5_BASE		IO_ADDRESS(0x480B6000)
+#define OMAP243X_GPIO1_BASE		OMAP2_IO_ADDRESS(0x4900C000)
+#define OMAP243X_GPIO2_BASE		OMAP2_IO_ADDRESS(0x4900E000)
+#define OMAP243X_GPIO3_BASE		OMAP2_IO_ADDRESS(0x49010000)
+#define OMAP243X_GPIO4_BASE		OMAP2_IO_ADDRESS(0x49012000)
+#define OMAP243X_GPIO5_BASE		OMAP2_IO_ADDRESS(0x480B6000)
 
 #define OMAP24XX_GPIO_REVISION		0x0000
 #define OMAP24XX_GPIO_SYSCONFIG		0x0010
@@ -138,28 +140,52 @@
 #define OMAP24XX_GPIO_CLEARDATAOUT	0x0090
 #define OMAP24XX_GPIO_SETDATAOUT	0x0094
 
+#define OMAP4_GPIO_REVISION		0x0000
+#define OMAP4_GPIO_SYSCONFIG		0x0010
+#define OMAP4_GPIO_EOI			0x0020
+#define OMAP4_GPIO_IRQSTATUSRAW0	0x0024
+#define OMAP4_GPIO_IRQSTATUSRAW1	0x0028
+#define OMAP4_GPIO_IRQSTATUS0		0x002c
+#define OMAP4_GPIO_IRQSTATUS1		0x0030
+#define OMAP4_GPIO_IRQSTATUSSET0	0x0034
+#define OMAP4_GPIO_IRQSTATUSSET1	0x0038
+#define OMAP4_GPIO_IRQSTATUSCLR0	0x003c
+#define OMAP4_GPIO_IRQSTATUSCLR1	0x0040
+#define OMAP4_GPIO_IRQWAKEN0		0x0044
+#define OMAP4_GPIO_IRQWAKEN1		0x0048
+#define OMAP4_GPIO_SYSSTATUS		0x0104
+#define OMAP4_GPIO_CTRL			0x0130
+#define OMAP4_GPIO_OE			0x0134
+#define OMAP4_GPIO_DATAIN		0x0138
+#define OMAP4_GPIO_DATAOUT		0x013c
+#define OMAP4_GPIO_LEVELDETECT0		0x0140
+#define OMAP4_GPIO_LEVELDETECT1		0x0144
+#define OMAP4_GPIO_RISINGDETECT		0x0148
+#define OMAP4_GPIO_FALLINGDETECT	0x014c
+#define OMAP4_GPIO_DEBOUNCENABLE	0x0150
+#define OMAP4_GPIO_DEBOUNCINGTIME	0x0154
+#define OMAP4_GPIO_CLEARDATAOUT		0x0190
+#define OMAP4_GPIO_SETDATAOUT		0x0194
 /*
  * omap34xx specific GPIO registers
  */
 
-#define OMAP34XX_GPIO1_BASE		IO_ADDRESS(0x48310000)
-#define OMAP34XX_GPIO2_BASE		IO_ADDRESS(0x49050000)
-#define OMAP34XX_GPIO3_BASE		IO_ADDRESS(0x49052000)
-#define OMAP34XX_GPIO4_BASE		IO_ADDRESS(0x49054000)
-#define OMAP34XX_GPIO5_BASE		IO_ADDRESS(0x49056000)
-#define OMAP34XX_GPIO6_BASE		IO_ADDRESS(0x49058000)
+#define OMAP34XX_GPIO1_BASE		OMAP2_IO_ADDRESS(0x48310000)
+#define OMAP34XX_GPIO2_BASE		OMAP2_IO_ADDRESS(0x49050000)
+#define OMAP34XX_GPIO3_BASE		OMAP2_IO_ADDRESS(0x49052000)
+#define OMAP34XX_GPIO4_BASE		OMAP2_IO_ADDRESS(0x49054000)
+#define OMAP34XX_GPIO5_BASE		OMAP2_IO_ADDRESS(0x49056000)
+#define OMAP34XX_GPIO6_BASE		OMAP2_IO_ADDRESS(0x49058000)
 
 /*
  * OMAP44XX  specific GPIO registers
  */
-#define OMAP44XX_GPIO1_BASE             IO_ADDRESS(0x4a310000)
-#define OMAP44XX_GPIO2_BASE             IO_ADDRESS(0x48055000)
-#define OMAP44XX_GPIO3_BASE             IO_ADDRESS(0x48057000)
-#define OMAP44XX_GPIO4_BASE             IO_ADDRESS(0x48059000)
-#define OMAP44XX_GPIO5_BASE             IO_ADDRESS(0x4805B000)
-#define OMAP44XX_GPIO6_BASE             IO_ADDRESS(0x4805D000)
-
-#define OMAP_MPUIO_VBASE		IO_ADDRESS(OMAP_MPUIO_BASE)
+#define OMAP44XX_GPIO1_BASE             OMAP2_IO_ADDRESS(0x4a310000)
+#define OMAP44XX_GPIO2_BASE             OMAP2_IO_ADDRESS(0x48055000)
+#define OMAP44XX_GPIO3_BASE             OMAP2_IO_ADDRESS(0x48057000)
+#define OMAP44XX_GPIO4_BASE             OMAP2_IO_ADDRESS(0x48059000)
+#define OMAP44XX_GPIO5_BASE             OMAP2_IO_ADDRESS(0x4805B000)
+#define OMAP44XX_GPIO6_BASE             OMAP2_IO_ADDRESS(0x4805D000)
 
 struct gpio_bank {
 	void __iomem *base;
@@ -195,7 +221,7 @@ struct gpio_bank {
 
 #ifdef CONFIG_ARCH_OMAP16XX
 static struct gpio_bank gpio_bank_1610[5] = {
-	{ OMAP_MPUIO_VBASE,    INT_MPUIO,	    IH_MPUIO_BASE,     METHOD_MPUIO},
+	{ OMAP1_MPUIO_VBASE,    INT_MPUIO,	    IH_MPUIO_BASE,     METHOD_MPUIO},
 	{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1,	    IH_GPIO_BASE,      METHOD_GPIO_1610 },
 	{ OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 },
 	{ OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 },
@@ -205,14 +231,14 @@ static struct gpio_bank gpio_bank_1610[5] = {
 
 #ifdef CONFIG_ARCH_OMAP15XX
 static struct gpio_bank gpio_bank_1510[2] = {
-	{ OMAP_MPUIO_VBASE,   INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
+	{ OMAP1_MPUIO_VBASE,   INT_MPUIO,      IH_MPUIO_BASE, METHOD_MPUIO },
 	{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE,  METHOD_GPIO_1510 }
 };
 #endif
 
 #ifdef CONFIG_ARCH_OMAP730
 static struct gpio_bank gpio_bank_730[7] = {
-	{ OMAP_MPUIO_VBASE,    INT_730_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
+	{ OMAP1_MPUIO_VBASE,    INT_730_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
 	{ OMAP730_GPIO1_BASE,  INT_730_GPIO_BANK1,  IH_GPIO_BASE,	METHOD_GPIO_730 },
 	{ OMAP730_GPIO2_BASE,  INT_730_GPIO_BANK2,  IH_GPIO_BASE + 32,	METHOD_GPIO_730 },
 	{ OMAP730_GPIO3_BASE,  INT_730_GPIO_BANK3,  IH_GPIO_BASE + 64,	METHOD_GPIO_730 },
@@ -224,7 +250,7 @@ static struct gpio_bank gpio_bank_730[7] = {
 
 #ifdef CONFIG_ARCH_OMAP850
 static struct gpio_bank gpio_bank_850[7] = {
-	{ OMAP_MPUIO_BASE,     INT_850_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
+	{ OMAP1_MPUIO_BASE,     INT_850_MPUIO,	    IH_MPUIO_BASE,	METHOD_MPUIO },
 	{ OMAP850_GPIO1_BASE,  INT_850_GPIO_BANK1,  IH_GPIO_BASE,	METHOD_GPIO_850 },
 	{ OMAP850_GPIO2_BASE,  INT_850_GPIO_BANK2,  IH_GPIO_BASE + 32,	METHOD_GPIO_850 },
 	{ OMAP850_GPIO3_BASE,  INT_850_GPIO_BANK3,  IH_GPIO_BASE + 64,	METHOD_GPIO_850 },
@@ -386,12 +412,16 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
 		reg += OMAP850_GPIO_DIR_CONTROL;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_OE;
 		break;
 #endif
+#if defined(CONFIG_ARCH_OMAP4)
+	case METHOD_GPIO_24XX:
+		reg += OMAP4_GPIO_OE;
+		break;
+#endif
 	default:
 		WARN_ON(1);
 		return;
@@ -459,8 +489,7 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 			l &= ~(1 << gpio);
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		if (enable)
 			reg += OMAP24XX_GPIO_SETDATAOUT;
@@ -469,6 +498,15 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
 		l = 1 << gpio;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+	case METHOD_GPIO_24XX:
+		if (enable)
+			reg += OMAP4_GPIO_SETDATAOUT;
+		else
+			reg += OMAP4_GPIO_CLEARDATAOUT;
+		l = 1 << gpio;
+		break;
+#endif
 	default:
 		WARN_ON(1);
 		return;
@@ -509,12 +547,16 @@ static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
 		reg += OMAP850_GPIO_DATA_INPUT;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_DATAIN;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+	case METHOD_GPIO_24XX:
+		reg += OMAP4_GPIO_DATAIN;
+		break;
+#endif
 	default:
 		return -EINVAL;
 	}
@@ -589,7 +631,11 @@ void omap_set_gpio_debounce(int gpio, int enable)
 
 	bank = get_gpio_bank(gpio);
 	reg = bank->base;
+#ifdef CONFIG_ARCH_OMAP4
+	reg += OMAP4_GPIO_DEBOUNCENABLE;
+#else
 	reg += OMAP24XX_GPIO_DEBOUNCE_EN;
+#endif
 
 	spin_lock_irqsave(&bank->lock, flags);
 	val = __raw_readl(reg);
@@ -626,7 +672,11 @@ void omap_set_gpio_debounce_time(int gpio, int enc_time)
 	reg = bank->base;
 
 	enc_time &= 0xff;
+#ifdef CONFIG_ARCH_OMAP4
+	reg += OMAP4_GPIO_DEBOUNCINGTIME;
+#else
 	reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
+#endif
 	__raw_writel(enc_time, reg);
 }
 EXPORT_SYMBOL(omap_set_gpio_debounce_time);
@@ -638,23 +688,46 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
 {
 	void __iomem *base = bank->base;
 	u32 gpio_bit = 1 << gpio;
+	u32 val;
 
-	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
-		trigger & IRQ_TYPE_LEVEL_LOW);
-	MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
-		trigger & IRQ_TYPE_LEVEL_HIGH);
-	MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
-		trigger & IRQ_TYPE_EDGE_RISING);
-	MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
-		trigger & IRQ_TYPE_EDGE_FALLING);
-
+	if (cpu_is_omap44xx()) {
+		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_LOW);
+		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_HIGH);
+		MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_RISING);
+		MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_FALLING);
+	} else {
+		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_LOW);
+		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_HIGH);
+		MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_RISING);
+		MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_FALLING);
+	}
 	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
-		if (trigger != 0)
-			__raw_writel(1 << gpio, bank->base
+		if (cpu_is_omap44xx()) {
+			if (trigger != 0)
+				__raw_writel(1 << gpio, bank->base+
+						OMAP4_GPIO_IRQWAKEN0);
+			else {
+				val = __raw_readl(bank->base +
+							OMAP4_GPIO_IRQWAKEN0);
+				__raw_writel(val & (~(1 << gpio)), bank->base +
+							 OMAP4_GPIO_IRQWAKEN0);
+			}
+		} else {
+			if (trigger != 0)
+				__raw_writel(1 << gpio, bank->base
 					+ OMAP24XX_GPIO_SETWKUENA);
-		else
-			__raw_writel(1 << gpio, bank->base
+			else
+				__raw_writel(1 << gpio, bank->base
 					+ OMAP24XX_GPIO_CLEARWKUENA);
+		}
 	} else {
 		if (trigger != 0)
 			bank->enabled_non_wakeup_gpios |= gpio_bit;
@@ -662,9 +735,15 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
 			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
 	}
 
-	bank->level_mask =
-		__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
-		__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+	if (cpu_is_omap44xx()) {
+		bank->level_mask =
+			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) |
+			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
+	} else {
+		bank->level_mask =
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+	}
 }
 #endif
 
@@ -828,12 +907,16 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 		reg += OMAP850_GPIO_INT_STATUS;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQSTATUS1;
 		break;
 #endif
+#if defined(CONFIG_ARCH_OMAP4)
+	case METHOD_GPIO_24XX:
+		reg += OMAP4_GPIO_IRQSTATUS0;
+		break;
+#endif
 	default:
 		WARN_ON(1);
 		return;
@@ -843,12 +926,16 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
 	/* Workaround for clearing DSP GPIO interrupts to allow retention */
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	reg = bank->base + OMAP24XX_GPIO_IRQSTATUS2;
-	if (cpu_is_omap24xx() || cpu_is_omap34xx())
+#endif
+#if defined(CONFIG_ARCH_OMAP4)
+	reg = bank->base + OMAP4_GPIO_IRQSTATUS1;
+#endif
+	if (cpu_is_omap24xx() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
 		__raw_writel(gpio_mask, reg);
 
 	/* Flush posted write for the irq status to avoid spurious interrupts */
 	__raw_readl(reg);
-#endif
+	}
 }
 
 static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
@@ -898,13 +985,18 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
 		inv = 1;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		reg += OMAP24XX_GPIO_IRQENABLE1;
 		mask = 0xffffffff;
 		break;
 #endif
+#if defined(CONFIG_ARCH_OMAP4)
+	case METHOD_GPIO_24XX:
+		reg += OMAP4_GPIO_IRQSTATUSSET0;
+		mask = 0xffffffff;
+		break;
+#endif
 	default:
 		WARN_ON(1);
 		return 0;
@@ -972,8 +1064,7 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 			l |= gpio_mask;
 		break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-		defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	case METHOD_GPIO_24XX:
 		if (enable)
 			reg += OMAP24XX_GPIO_SETIRQENABLE1;
@@ -982,6 +1073,15 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab
 		l = gpio_mask;
 		break;
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+	case METHOD_GPIO_24XX:
+		if (enable)
+			reg += OMAP4_GPIO_IRQSTATUSSET0;
+		else
+			reg += OMAP4_GPIO_IRQSTATUSCLR0;
+		l = gpio_mask;
+		break;
+#endif
 	default:
 		WARN_ON(1);
 		return;
@@ -1157,11 +1257,14 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
 	if (bank->method == METHOD_GPIO_850)
 		isr_reg = bank->base + OMAP850_GPIO_INT_STATUS;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 	if (bank->method == METHOD_GPIO_24XX)
 		isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
 #endif
+#if defined(CONFIG_ARCH_OMAP4)
+	if (bank->method == METHOD_GPIO_24XX)
+		isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
+#endif
 	while(1) {
 		u32 isr_saved, level_mask = 0;
 		u32 enabled;
@@ -1315,8 +1418,9 @@ static struct irq_chip mpuio_irq_chip = {
 
 #include <linux/platform_device.h>
 
-static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t mesg)
+static int omap_mpuio_suspend_noirq(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct gpio_bank	*bank = platform_get_drvdata(pdev);
 	void __iomem		*mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
 	unsigned long		flags;
@@ -1329,8 +1433,9 @@ static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t me
 	return 0;
 }
 
-static int omap_mpuio_resume_early(struct platform_device *pdev)
+static int omap_mpuio_resume_noirq(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct gpio_bank	*bank = platform_get_drvdata(pdev);
 	void __iomem		*mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT;
 	unsigned long		flags;
@@ -1342,14 +1447,18 @@ static int omap_mpuio_resume_early(struct platform_device *pdev)
 	return 0;
 }
 
+static struct dev_pm_ops omap_mpuio_dev_pm_ops = {
+	.suspend_noirq = omap_mpuio_suspend_noirq,
+	.resume_noirq = omap_mpuio_resume_noirq,
+};
+
 /* use platform_driver for this, now that there's no longer any
  * point to sys_device (other than not disturbing old code).
  */
 static struct platform_driver omap_mpuio_driver = {
-	.suspend_late	= omap_mpuio_suspend_late,
-	.resume_early	= omap_mpuio_resume_early,
 	.driver		= {
 		.name	= "mpuio",
+		.pm	= &omap_mpuio_dev_pm_ops,
 	},
 };
 
@@ -1638,7 +1747,7 @@ static int __init _omap_gpio_init(void)
 
 		gpio_bank_count = OMAP34XX_NR_GPIOS;
 		gpio_bank = gpio_bank_44xx;
-		rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+		rev = __raw_readl(gpio_bank[0].base + OMAP4_GPIO_REVISION);
 		printk(KERN_INFO "OMAP44xx GPIO hardware version %d.%d\n",
 			(rev >> 4) & 0x0f, rev & 0x0f);
 	}
@@ -1672,7 +1781,16 @@ static int __init _omap_gpio_init(void)
 			static const u32 non_wakeup_gpios[] = {
 				0xe203ffc0, 0x08700040
 			};
-
+		if (cpu_is_omap44xx()) {
+			__raw_writel(0xffffffff, bank->base +
+						OMAP4_GPIO_IRQSTATUSCLR0);
+			__raw_writew(0x0015, bank->base +
+						OMAP4_GPIO_SYSCONFIG);
+			__raw_writel(0x00000000, bank->base +
+						 OMAP4_GPIO_DEBOUNCENABLE);
+			/* Initialize interface clock ungated, module enabled */
+			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
+		} else {
 			__raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1);
 			__raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1);
 			__raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG);
@@ -1680,12 +1798,12 @@ static int __init _omap_gpio_init(void)
 
 			/* Initialize interface clock ungated, module enabled */
 			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
+		}
 			if (i < ARRAY_SIZE(non_wakeup_gpios))
 				bank->non_wakeup_gpios = non_wakeup_gpios[i];
 			gpio_count = 32;
 		}
 #endif
-
 		/* REVISIT eventually switch from OMAP-specific gpio structs
 		 * over to the generic ones
 		 */
@@ -1771,14 +1889,20 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 		case METHOD_GPIO_24XX:
 			wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			break;
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+		case METHOD_GPIO_24XX:
+			wake_status = bank->base + OMAP4_GPIO_IRQWAKEN0;
+			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
+			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
+			break;
+#endif
 		default:
 			continue;
 		}
@@ -1813,13 +1937,18 @@ static int omap_gpio_resume(struct sys_device *dev)
 			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
 			break;
 #endif
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 		case METHOD_GPIO_24XX:
 			wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
 			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
 			break;
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+		case METHOD_GPIO_24XX:
+			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
+			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
+			break;
+#endif
 		default:
 			continue;
 		}
@@ -1863,21 +1992,29 @@ void omap2_gpio_prepare_for_retention(void)
 
 		if (!(bank->enabled_non_wakeup_gpios))
 			continue;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-				defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 		bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
 		l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
 		l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+		bank->saved_datain = __raw_readl(bank->base +
+							OMAP4_GPIO_DATAIN);
+		l1 = __raw_readl(bank->base + OMAP4_GPIO_FALLINGDETECT);
+		l2 = __raw_readl(bank->base + OMAP4_GPIO_RISINGDETECT);
+#endif
 		bank->saved_fallingdetect = l1;
 		bank->saved_risingdetect = l2;
 		l1 &= ~bank->enabled_non_wakeup_gpios;
 		l2 &= ~bank->enabled_non_wakeup_gpios;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 		__raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT);
 		__raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT);
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+		__raw_writel(l1, bank->base + OMAP4_GPIO_FALLINGDETECT);
+		__raw_writel(l2, bank->base + OMAP4_GPIO_RISINGDETECT);
+#endif
 		c++;
 	}
 	if (!c) {
@@ -1895,38 +2032,73 @@ void omap2_gpio_resume_after_retention(void)
 		return;
 	for (i = 0; i < gpio_bank_count; i++) {
 		struct gpio_bank *bank = &gpio_bank[i];
-		u32 l;
+		u32 l, gen, gen0, gen1;
 
 		if (!(bank->enabled_non_wakeup_gpios))
 			continue;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 		__raw_writel(bank->saved_fallingdetect,
 				 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
 		__raw_writel(bank->saved_risingdetect,
 				 bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+		__raw_writel(bank->saved_fallingdetect,
+				 bank->base + OMAP4_GPIO_FALLINGDETECT);
+		__raw_writel(bank->saved_risingdetect,
+				 bank->base + OMAP4_GPIO_RISINGDETECT);
+		l = __raw_readl(bank->base + OMAP4_GPIO_DATAIN);
 #endif
 		/* Check if any of the non-wakeup interrupt GPIOs have changed
 		 * state.  If so, generate an IRQ by software.  This is
 		 * horribly racy, but it's the best we can do to work around
 		 * this silicon bug. */
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
-		l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN);
-#endif
 		l ^= bank->saved_datain;
 		l &= bank->non_wakeup_gpios;
-		if (l) {
+
+		/*
+		 * No need to generate IRQs for the rising edge for gpio IRQs
+		 * configured with falling edge only; and vice versa.
+		 */
+		gen0 = l & bank->saved_fallingdetect;
+		gen0 &= bank->saved_datain;
+
+		gen1 = l & bank->saved_risingdetect;
+		gen1 &= ~(bank->saved_datain);
+
+		/* FIXME: Consider GPIO IRQs with level detections properly! */
+		gen = l & (~(bank->saved_fallingdetect) &
+				~(bank->saved_risingdetect));
+		/* Consider all GPIO IRQs needed to be updated */
+		gen |= gen0 | gen1;
+
+		if (gen) {
 			u32 old0, old1;
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
-			defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 			old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
 			old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-			__raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-			__raw_writel(old1 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+			__raw_writel(old0 | gen, bank->base +
+					OMAP24XX_GPIO_LEVELDETECT0);
+			__raw_writel(old1 | gen, bank->base +
+					OMAP24XX_GPIO_LEVELDETECT1);
 			__raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0);
 			__raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1);
 #endif
+#ifdef CONFIG_ARCH_OMAP4
+			old0 = __raw_readl(bank->base +
+						OMAP4_GPIO_LEVELDETECT0);
+			old1 = __raw_readl(bank->base +
+						OMAP4_GPIO_LEVELDETECT1);
+			__raw_writel(old0 | l, bank->base +
+						OMAP4_GPIO_LEVELDETECT0);
+			__raw_writel(old1 | l, bank->base +
+						OMAP4_GPIO_LEVELDETECT1);
+			__raw_writel(old0, bank->base +
+						OMAP4_GPIO_LEVELDETECT0);
+			__raw_writel(old1, bank->base +
+						OMAP4_GPIO_LEVELDETECT1);
+#endif
 		}
 	}
 
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index 50ea79a..8e913c3 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -16,10 +16,8 @@
 
 /* Different peripheral ids */
 #define OMAP_TAG_CLOCK		0x4f01
-#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
 #define OMAP_TAG_LCD		0x4f05
 #define OMAP_TAG_GPIO_SWITCH	0x4f06
-#define OMAP_TAG_UART		0x4f07
 #define OMAP_TAG_FBMEM		0x4f08
 #define OMAP_TAG_STI_CONSOLE	0x4f09
 #define OMAP_TAG_CAMERA_SENSOR	0x4f0a
diff --git a/arch/arm/plat-omap/include/mach/clockdomain.h b/arch/arm/plat-omap/include/mach/clockdomain.h
index b9d0dd2..99ebd88 100644
--- a/arch/arm/plat-omap/include/mach/clockdomain.h
+++ b/arch/arm/plat-omap/include/mach/clockdomain.h
@@ -95,7 +95,8 @@ int clkdm_register(struct clockdomain *clkdm);
 int clkdm_unregister(struct clockdomain *clkdm);
 struct clockdomain *clkdm_lookup(const char *name);
 
-int clkdm_for_each(int (*fn)(struct clockdomain *clkdm));
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
+			void *user);
 struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
 
 void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h
index 8140dbc..826d317 100644
--- a/arch/arm/plat-omap/include/mach/control.h
+++ b/arch/arm/plat-omap/include/mach/control.h
@@ -20,15 +20,15 @@
 
 #ifndef __ASSEMBLY__
 #define OMAP242X_CTRL_REGADDR(reg)					\
-	IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+	OMAP2_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
 #define OMAP243X_CTRL_REGADDR(reg)					\
-	IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+	OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
 #define OMAP343X_CTRL_REGADDR(reg)					\
-	IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+	OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
 #else
-#define OMAP242X_CTRL_REGADDR(reg)	IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
-#define OMAP243X_CTRL_REGADDR(reg)	IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
-#define OMAP343X_CTRL_REGADDR(reg)	IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#define OMAP242X_CTRL_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+#define OMAP243X_CTRL_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+#define OMAP343X_CTRL_REGADDR(reg)	OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
 #endif /* __ASSEMBLY__ */
 
 /*
diff --git a/arch/arm/plat-omap/include/mach/dma.h b/arch/arm/plat-omap/include/mach/dma.h
index 7b939cc..72f680b 100644
--- a/arch/arm/plat-omap/include/mach/dma.h
+++ b/arch/arm/plat-omap/include/mach/dma.h
@@ -122,6 +122,11 @@
 #define OMAP_DMA4_CCFN(n)		(0x60 * (n) + 0xc0)
 #define OMAP_DMA4_COLOR(n)		(0x60 * (n) + 0xc4)
 
+/* Additional registers available on OMAP4 */
+#define OMAP_DMA4_CDP(n)		(0x60 * (n) + 0xd0)
+#define OMAP_DMA4_CNDP(n)		(0x60 * (n) + 0xd4)
+#define OMAP_DMA4_CCDN(n)		(0x60 * (n) + 0xd8)
+
 /* Dummy defines to keep multi-omap compiles happy */
 #define OMAP1_DMA_REVISION		0
 #define OMAP1_DMA_IRQSTATUS_L0		0
@@ -311,6 +316,89 @@
 #define OMAP34XX_DMA_USIM_TX		79	/* S_DMA_78 */
 #define OMAP34XX_DMA_USIM_RX		80	/* S_DMA_79 */
 
+/* DMA request lines for 44xx */
+#define OMAP44XX_DMA_DSS_DISPC_REQ	6	/* S_DMA_5 */
+#define OMAP44XX_DMA_SYS_REQ2		7	/* S_DMA_6 */
+#define OMAP44XX_DMA_ISS_REQ1		9	/* S_DMA_8 */
+#define OMAP44XX_DMA_ISS_REQ2		10	/* S_DMA_9 */
+#define OMAP44XX_DMA_ISS_REQ3		12	/* S_DMA_11 */
+#define OMAP44XX_DMA_ISS_REQ4		13	/* S_DMA_12 */
+#define OMAP44XX_DMA_DSS_RFBI_REQ	14	/* S_DMA_13 */
+#define OMAP44XX_DMA_SPI3_TX0		15	/* S_DMA_14 */
+#define OMAP44XX_DMA_SPI3_RX0		16	/* S_DMA_15 */
+#define OMAP44XX_DMA_MCBSP2_TX		17	/* S_DMA_16 */
+#define OMAP44XX_DMA_MCBSP2_RX		18	/* S_DMA_17 */
+#define OMAP44XX_DMA_MCBSP3_TX		19	/* S_DMA_18 */
+#define OMAP44XX_DMA_MCBSP3_RX		20	/* S_DMA_19 */
+#define OMAP44XX_DMA_SPI3_TX1		23	/* S_DMA_22 */
+#define OMAP44XX_DMA_SPI3_RX1		24	/* S_DMA_23 */
+#define OMAP44XX_DMA_I2C3_TX		25	/* S_DMA_24 */
+#define OMAP44XX_DMA_I2C3_RX		26	/* S_DMA_25 */
+#define OMAP44XX_DMA_I2C1_TX		27	/* S_DMA_26 */
+#define OMAP44XX_DMA_I2C1_RX		28	/* S_DMA_27 */
+#define OMAP44XX_DMA_I2C2_TX		29	/* S_DMA_28 */
+#define OMAP44XX_DMA_I2C2_RX		30	/* S_DMA_29 */
+#define OMAP44XX_DMA_MCBSP4_TX		31	/* S_DMA_30 */
+#define OMAP44XX_DMA_MCBSP4_RX		32	/* S_DMA_31 */
+#define OMAP44XX_DMA_MCBSP1_TX		33	/* S_DMA_32 */
+#define OMAP44XX_DMA_MCBSP1_RX		34	/* S_DMA_33 */
+#define OMAP44XX_DMA_SPI1_TX0		35	/* S_DMA_34 */
+#define OMAP44XX_DMA_SPI1_RX0		36	/* S_DMA_35 */
+#define OMAP44XX_DMA_SPI1_TX1		37	/* S_DMA_36 */
+#define OMAP44XX_DMA_SPI1_RX1		38	/* S_DMA_37 */
+#define OMAP44XX_DMA_SPI1_TX2		39	/* S_DMA_38 */
+#define OMAP44XX_DMA_SPI1_RX2		40	/* S_DMA_39 */
+#define OMAP44XX_DMA_SPI1_TX3		41	/* S_DMA_40 */
+#define OMAP44XX_DMA_SPI1_RX3		42	/* S_DMA_41 */
+#define OMAP44XX_DMA_SPI2_TX0		43	/* S_DMA_42 */
+#define OMAP44XX_DMA_SPI2_RX0		44	/* S_DMA_43 */
+#define OMAP44XX_DMA_SPI2_TX1		45	/* S_DMA_44 */
+#define OMAP44XX_DMA_SPI2_RX1		46	/* S_DMA_45 */
+#define OMAP44XX_DMA_MMC2_TX		47	/* S_DMA_46 */
+#define OMAP44XX_DMA_MMC2_RX		48	/* S_DMA_47 */
+#define OMAP44XX_DMA_UART1_TX		49	/* S_DMA_48 */
+#define OMAP44XX_DMA_UART1_RX		50	/* S_DMA_49 */
+#define OMAP44XX_DMA_UART2_TX		51	/* S_DMA_50 */
+#define OMAP44XX_DMA_UART2_RX		52	/* S_DMA_51 */
+#define OMAP44XX_DMA_UART3_TX		53	/* S_DMA_52 */
+#define OMAP44XX_DMA_UART3_RX		54	/* S_DMA_53 */
+#define OMAP44XX_DMA_UART4_TX		55	/* S_DMA_54 */
+#define OMAP44XX_DMA_UART4_RX		56	/* S_DMA_55 */
+#define OMAP44XX_DMA_MMC4_TX		57	/* S_DMA_56 */
+#define OMAP44XX_DMA_MMC4_RX		58	/* S_DMA_57 */
+#define OMAP44XX_DMA_MMC5_TX		59	/* S_DMA_58 */
+#define OMAP44XX_DMA_MMC5_RX		60	/* S_DMA_59 */
+#define OMAP44XX_DMA_MMC1_TX		61	/* S_DMA_60 */
+#define OMAP44XX_DMA_MMC1_RX		62	/* S_DMA_61 */
+#define OMAP44XX_DMA_SYS_REQ3		64	/* S_DMA_63 */
+#define OMAP44XX_DMA_MCPDM_UP		65	/* S_DMA_64 */
+#define OMAP44XX_DMA_MCPDM_DL		66	/* S_DMA_65 */
+#define OMAP44XX_DMA_SPI4_TX0		70	/* S_DMA_69 */
+#define OMAP44XX_DMA_SPI4_RX0		71	/* S_DMA_70 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ0	72	/* S_DMA_71 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ1	73	/* S_DMA_72 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ2	74	/* S_DMA_73 */
+#define OMAP44XX_DMA_DSS_DSI1_REQ3	75	/* S_DMA_74 */
+#define OMAP44XX_DMA_DSS_HDMI_REQ	76	/* S_DMA_75 */
+#define OMAP44XX_DMA_MMC3_TX		77	/* S_DMA_76 */
+#define OMAP44XX_DMA_MMC3_RX		78	/* S_DMA_77 */
+#define OMAP44XX_DMA_USIM_TX		79	/* S_DMA_78 */
+#define OMAP44XX_DMA_USIM_RX		80	/* S_DMA_79 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ0	81	/* S_DMA_80 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ1	82	/* S_DMA_81 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ2	83	/* S_DMA_82 */
+#define OMAP44XX_DMA_DSS_DSI2_REQ3	84	/* S_DMA_83 */
+#define OMAP44XX_DMA_ABE_REQ0		101	/* S_DMA_100 */
+#define OMAP44XX_DMA_ABE_REQ1		102	/* S_DMA_101 */
+#define OMAP44XX_DMA_ABE_REQ2		103	/* S_DMA_102 */
+#define OMAP44XX_DMA_ABE_REQ3		104	/* S_DMA_103 */
+#define OMAP44XX_DMA_ABE_REQ4		105	/* S_DMA_104 */
+#define OMAP44XX_DMA_ABE_REQ5		106	/* S_DMA_105 */
+#define OMAP44XX_DMA_ABE_REQ6		107	/* S_DMA_106 */
+#define OMAP44XX_DMA_ABE_REQ7		108	/* S_DMA_107 */
+#define OMAP44XX_DMA_I2C4_TX		124	/* S_DMA_123 */
+#define OMAP44XX_DMA_I2C4_RX		125	/* S_DMA_124 */
+
 /*----------------------------------------------------------------------------*/
 
 /* Hardware registers for LCD DMA */
diff --git a/arch/arm/plat-omap/include/mach/entry-macro.S b/arch/arm/plat-omap/include/mach/entry-macro.S
index 56426ed..a559299 100644
--- a/arch/arm/plat-omap/include/mach/entry-macro.S
+++ b/arch/arm/plat-omap/include/mach/entry-macro.S
@@ -41,7 +41,7 @@
 		.endm
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\base, =IO_ADDRESS(OMAP_IH1_BASE)
+		ldr	\base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
 		ldr	\irqnr, [\base, #IRQ_ITR_REG_OFFSET]
 		ldr	\tmp, [\base, #IRQ_MIR_REG_OFFSET]
 		mov	\irqstat, #0xffffffff
@@ -53,7 +53,7 @@
 		cmp	\irqnr, #0
 		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
 		cmpeq	\irqnr, #INT_IH2_IRQ
-		ldreq	\base, =IO_ADDRESS(OMAP_IH2_BASE)
+		ldreq	\base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
 		ldreq	\irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
 		addeqs	\irqnr, \irqnr, #32
 1510:
@@ -68,9 +68,9 @@
 
 /* REVISIT: This should be set dynamically if CONFIG_MULTI_OMAP2 is selected */
 #if defined(CONFIG_ARCH_OMAP2420) || defined(CONFIG_ARCH_OMAP2430)
-#define OMAP2_VA_IC_BASE		IO_ADDRESS(OMAP24XX_IC_BASE)
+#define OMAP2_VA_IC_BASE		OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE)
 #elif defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP2_VA_IC_BASE		IO_ADDRESS(OMAP34XX_IC_BASE)
+#define OMAP2_VA_IC_BASE		OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE)
 #endif
 #if defined(CONFIG_ARCH_OMAP4)
 #include <mach/omap44xx.h>
diff --git a/arch/arm/plat-omap/include/mach/gpio.h b/arch/arm/plat-omap/include/mach/gpio.h
index 2b22a87..633ff68 100644
--- a/arch/arm/plat-omap/include/mach/gpio.h
+++ b/arch/arm/plat-omap/include/mach/gpio.h
@@ -29,7 +29,7 @@
 #include <linux/io.h>
 #include <mach/irqs.h>
 
-#define OMAP_MPUIO_BASE			0xfffb5000
+#define OMAP1_MPUIO_BASE			0xfffb5000
 
 #if (defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850))
 
diff --git a/arch/arm/plat-omap/include/mach/io.h b/arch/arm/plat-omap/include/mach/io.h
index 21fb0ef..8d32df3 100644
--- a/arch/arm/plat-omap/include/mach/io.h
+++ b/arch/arm/plat-omap/include/mach/io.h
@@ -54,17 +54,33 @@
  * ----------------------------------------------------------------------------
  */
 
-#if defined(CONFIG_ARCH_OMAP1)
+#ifdef __ASSEMBLER__
+#define IOMEM(x)		(x)
+#else
+#define IOMEM(x)		((void __force __iomem *)(x))
+#endif
+
+#define OMAP1_IO_OFFSET		0x01000000	/* Virtual IO = 0xfefb0000 */
+#define OMAP1_IO_ADDRESS(pa)	IOMEM((pa) - OMAP1_IO_OFFSET)
+
+#define OMAP2_IO_OFFSET		0x90000000
+#define OMAP2_IO_ADDRESS(pa)	IOMEM((pa) + OMAP2_IO_OFFSET) /* L3 and L4 */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap1 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
 
-#define IO_PHYS			0xFFFB0000
-#define IO_OFFSET		0x01000000	/* Virtual IO = 0xfefb0000 */
-#define IO_SIZE			0x40000
-#define IO_VIRT			(IO_PHYS - IO_OFFSET)
-#define __IO_ADDRESS(pa)	((pa) - IO_OFFSET)
-#define __OMAP1_IO_ADDRESS(pa)	((pa) - IO_OFFSET)
-#define io_v2p(va)		((va) + IO_OFFSET)
+#define OMAP1_IO_PHYS		0xFFFB0000
+#define OMAP1_IO_SIZE		0x40000
+#define OMAP1_IO_VIRT		(OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
 
-#elif defined(CONFIG_ARCH_OMAP2)
+/*
+ * ----------------------------------------------------------------------------
+ * Omap2 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
 
 /* We map both L3 and L4 on OMAP2 */
 #define L3_24XX_PHYS	L3_24XX_BASE	/* 0x68000000 */
@@ -87,11 +103,6 @@
 #define OMAP243X_SMS_VIRT	0xFC000000
 #define OMAP243X_SMS_SIZE	SZ_1M
 
-#define IO_OFFSET		0x90000000
-#define __IO_ADDRESS(pa)	((pa) + IO_OFFSET)	/* Works for L3 and L4 */
-#define __OMAP2_IO_ADDRESS(pa)	((pa) + IO_OFFSET)	/* Works for L3 and L4 */
-#define io_v2p(va)		((va) - IO_OFFSET)	/* Works for L3 and L4 */
-
 /* DSP */
 #define DSP_MEM_24XX_PHYS	OMAP2420_DSP_MEM_BASE	/* 0x58000000 */
 #define DSP_MEM_24XX_VIRT	0xe0000000
@@ -103,7 +114,11 @@
 #define DSP_MMU_24XX_VIRT	0xe2000000
 #define DSP_MMU_24XX_SIZE	SZ_4K
 
-#elif defined(CONFIG_ARCH_OMAP3)
+/*
+ * ----------------------------------------------------------------------------
+ * Omap3 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
 
 /* We map both L3 and L4 on OMAP3 */
 #define L3_34XX_PHYS		L3_34XX_BASE	/* 0x68000000 */
@@ -143,12 +158,6 @@
 #define OMAP343X_SDRC_VIRT	0xFD000000
 #define OMAP343X_SDRC_SIZE	SZ_1M
 
-
-#define IO_OFFSET		0x90000000
-#define __IO_ADDRESS(pa)	((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define __OMAP2_IO_ADDRESS(pa)	((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define io_v2p(va)		((va) - IO_OFFSET)/* Works for L3 and L4 */
-
 /* DSP */
 #define DSP_MEM_34XX_PHYS	OMAP34XX_DSP_MEM_BASE	/* 0x58000000 */
 #define DSP_MEM_34XX_VIRT	0xe0000000
@@ -160,8 +169,12 @@
 #define DSP_MMU_34XX_VIRT	0xe2000000
 #define DSP_MMU_34XX_SIZE	SZ_4K
 
+/*
+ * ----------------------------------------------------------------------------
+ * Omap4 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
 
-#elif defined(CONFIG_ARCH_OMAP4)
 /* We map both L3 and L4 on OMAP4 */
 #define L3_44XX_PHYS		L3_44XX_BASE
 #define L3_44XX_VIRT		0xd4000000
@@ -189,38 +202,24 @@
 #define OMAP44XX_GPMC_SIZE	SZ_1M
 
 
-#define IO_OFFSET		0x90000000
-#define __IO_ADDRESS(pa)	((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define __OMAP2_IO_ADDRESS(pa)	((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define io_v2p(va)		((va) - IO_OFFSET)/* Works for L3 and L4 */
-
-#endif
-
-#define IO_ADDRESS(pa)		IOMEM(__IO_ADDRESS(pa))
-#define OMAP1_IO_ADDRESS(pa)	IOMEM(__OMAP1_IO_ADDRESS(pa))
-#define OMAP2_IO_ADDRESS(pa)	IOMEM(__OMAP2_IO_ADDRESS(pa))
+/*
+ * ----------------------------------------------------------------------------
+ * Omap specific register access
+ * ----------------------------------------------------------------------------
+ */
 
-#ifdef __ASSEMBLER__
-#define IOMEM(x)		(x)
-#else
-#define IOMEM(x)		((void __force __iomem *)(x))
+#ifndef __ASSEMBLER__
 
 /*
- * Functions to access the OMAP IO region
- *
- * NOTE: - Use omap_read/write[bwl] for physical register addresses
- *	 - Use __raw_read/write[bwl]() for virtual register addresses
- *	 - Use IO_ADDRESS(phys_addr) to convert registers to virtual addresses
- *	 - DO NOT use hardcoded virtual addresses to allow changing the
- *	   IO address space again if needed
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
  */
-#define omap_readb(a)		__raw_readb(IO_ADDRESS(a))
-#define omap_readw(a)		__raw_readw(IO_ADDRESS(a))
-#define omap_readl(a)		__raw_readl(IO_ADDRESS(a))
 
-#define omap_writeb(v,a)	__raw_writeb(v, IO_ADDRESS(a))
-#define omap_writew(v,a)	__raw_writew(v, IO_ADDRESS(a))
-#define omap_writel(v,a)	__raw_writel(v, IO_ADDRESS(a))
+extern u8 omap_readb(u32 pa);
+extern u16 omap_readw(u32 pa);
+extern u32 omap_readl(u32 pa);
+extern void omap_writeb(u8 v, u32 pa);
+extern void omap_writew(u16 v, u32 pa);
+extern void omap_writel(u32 v, u32 pa);
 
 struct omap_sdrc_params;
 
diff --git a/arch/arm/plat-omap/include/mach/iommu.h b/arch/arm/plat-omap/include/mach/iommu.h
index 769b00b..46d41ac 100644
--- a/arch/arm/plat-omap/include/mach/iommu.h
+++ b/arch/arm/plat-omap/include/mach/iommu.h
@@ -95,7 +95,7 @@ struct iommu_functions {
 
 	void (*save_ctx)(struct iommu *obj);
 	void (*restore_ctx)(struct iommu *obj);
-	ssize_t (*dump_ctx)(struct iommu *obj, char *buf);
+	ssize_t (*dump_ctx)(struct iommu *obj, char *buf, ssize_t len);
 };
 
 struct iommu_platform_data {
@@ -162,7 +162,7 @@ extern void uninstall_iommu_arch(const struct iommu_functions *ops);
 extern int foreach_iommu_device(void *data,
 				int (*fn)(struct device *, void *));
 
-extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf);
-extern size_t dump_tlb_entries(struct iommu *obj, char *buf);
+extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len);
+extern size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t len);
 
 #endif /* __MACH_IOMMU_H */
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h
index 63a3f25..e0d6eca 100644
--- a/arch/arm/plat-omap/include/mach/mcbsp.h
+++ b/arch/arm/plat-omap/include/mach/mcbsp.h
@@ -53,6 +53,11 @@
 #define OMAP34XX_MCBSP4_BASE	0x49026000
 #define OMAP34XX_MCBSP5_BASE	0x48096000
 
+#define OMAP44XX_MCBSP1_BASE	0x49022000
+#define OMAP44XX_MCBSP2_BASE	0x49024000
+#define OMAP44XX_MCBSP3_BASE	0x49026000
+#define OMAP44XX_MCBSP4_BASE	0x48074000
+
 #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
 
 #define OMAP_MCBSP_REG_DRR2	0x00
@@ -98,7 +103,8 @@
 #define AUDIO_DMA_TX		OMAP_DMA_MCBSP1_TX
 #define AUDIO_DMA_RX		OMAP_DMA_MCBSP1_RX
 
-#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
+	defined(CONFIG_ARCH_OMAP4)
 
 #define OMAP_MCBSP_REG_DRR2	0x00
 #define OMAP_MCBSP_REG_DRR1	0x04
diff --git a/arch/arm/plat-omap/include/mach/mtd-xip.h b/arch/arm/plat-omap/include/mach/mtd-xip.h
index 39b591f..f82a8dc 100644
--- a/arch/arm/plat-omap/include/mach/mtd-xip.h
+++ b/arch/arm/plat-omap/include/mach/mtd-xip.h
@@ -25,7 +25,7 @@ typedef struct {
 } xip_omap_mpu_timer_regs_t;
 
 #define xip_omap_mpu_timer_base(n)					\
-((volatile xip_omap_mpu_timer_regs_t*)IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
+((volatile xip_omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
 	(n)*OMAP_MPU_TIMER_OFFSET))
 
 static inline unsigned long xip_omap_mpu_timer_read(int nr)
diff --git a/arch/arm/plat-omap/include/mach/mux.h b/arch/arm/plat-omap/include/mach/mux.h
index 80281c4..98dfab6 100644
--- a/arch/arm/plat-omap/include/mach/mux.h
+++ b/arch/arm/plat-omap/include/mach/mux.h
@@ -857,6 +857,37 @@ enum omap34xx_index {
 	/* OMAP3 SDRC CKE signals to SDR/DDR ram chips */
 	H16_34XX_SDRC_CKE0,
 	H17_34XX_SDRC_CKE1,
+
+	/* MMC1 */
+	N28_3430_MMC1_CLK,
+	M27_3430_MMC1_CMD,
+	N27_3430_MMC1_DAT0,
+	N26_3430_MMC1_DAT1,
+	N25_3430_MMC1_DAT2,
+	P28_3430_MMC1_DAT3,
+	P27_3430_MMC1_DAT4,
+	P26_3430_MMC1_DAT5,
+	R27_3430_MMC1_DAT6,
+	R25_3430_MMC1_DAT7,
+
+	/* MMC2 */
+	AE2_3430_MMC2_CLK,
+	AG5_3430_MMC2_CMD,
+	AH5_3430_MMC2_DAT0,
+	AH4_3430_MMC2_DAT1,
+	AG4_3430_MMC2_DAT2,
+	AF4_3430_MMC2_DAT3,
+
+	/* MMC3 */
+	AF10_3430_MMC3_CLK,
+	AC3_3430_MMC3_CMD,
+	AE11_3430_MMC3_DAT0,
+	AH9_3430_MMC3_DAT1,
+	AF13_3430_MMC3_DAT2,
+	AF13_3430_MMC3_DAT3,
+
+	/* SYS_NIRQ T2 INT1 */
+	AF26_34XX_SYS_NIRQ,
 };
 
 struct omap_mux_cfg {
diff --git a/arch/arm/plat-omap/include/mach/omap-pm.h b/arch/arm/plat-omap/include/mach/omap-pm.h
new file mode 100644
index 0000000..3ee41d7
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/omap-pm.h
@@ -0,0 +1,301 @@
+/*
+ * omap-pm.h - OMAP power management interface
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
+ * HÃ¶gander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
+ * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
+ * Richard Woodruff
+ */
+
+#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
+#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
+
+#include <linux/device.h>
+#include <linux/cpufreq.h>
+
+#include "powerdomain.h"
+
+/**
+ * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
+ * @rate: target clock rate
+ * @opp_id: OPP ID
+ * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
+ *
+ * Operating performance point data.  Can vary by OMAP chip and board.
+ */
+struct omap_opp {
+	unsigned long rate;
+	u8 opp_id;
+	u16 min_vdd;
+};
+
+extern struct omap_opp *mpu_opps;
+extern struct omap_opp *dsp_opps;
+extern struct omap_opp *l3_opps;
+
+/*
+ * agent_id values for use with omap_pm_set_min_bus_tput():
+ *
+ * OCP_INITIATOR_AGENT is only valid for devices that can act as
+ * initiators -- it represents the device's L3 interconnect
+ * connection.  OCP_TARGET_AGENT represents the device's L4
+ * interconnect connection.
+ */
+#define OCP_TARGET_AGENT		1
+#define OCP_INITIATOR_AGENT		2
+
+/**
+ * omap_pm_if_early_init - OMAP PM init code called before clock fw init
+ * @mpu_opp_table: array ptr to struct omap_opp for MPU
+ * @dsp_opp_table: array ptr to struct omap_opp for DSP
+ * @l3_opp_table : array ptr to struct omap_opp for CORE
+ *
+ * Initialize anything that must be configured before the clock
+ * framework starts.  The "_if_" is to avoid name collisions with the
+ * PM idle-loop code.
+ */
+int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
+				 struct omap_opp *dsp_opp_table,
+				 struct omap_opp *l3_opp_table);
+
+/**
+ * omap_pm_if_init - OMAP PM init code called after clock fw init
+ *
+ * The main initialization code.  OPP tables are passed in here.  The
+ * "_if_" is to avoid name collisions with the PM idle-loop code.
+ */
+int __init omap_pm_if_init(void);
+
+/**
+ * omap_pm_if_exit - OMAP PM exit code
+ *
+ * Exit code; currently unused.  The "_if_" is to avoid name
+ * collisions with the PM idle-loop code.
+ */
+void omap_pm_if_exit(void);
+
+/*
+ * Device-driver-originated constraints (via board-*.c files, platform_data)
+ */
+
+
+/**
+ * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
+ * @dev: struct device * requesting the constraint
+ * @t: maximum MPU wakeup latency in microseconds
+ *
+ * Request that the maximum interrupt latency for the MPU to be no
+ * greater than 't' microseconds. "Interrupt latency" in this case is
+ * defined as the elapsed time from the occurrence of a hardware or
+ * timer interrupt to the time when the device driver's interrupt
+ * service routine has been entered by the MPU.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the MPU powerdomain into, and
+ * possibly the CORE powerdomain as well, since interrupt handling
+ * code currently runs from SDRAM.  Advanced PM or board*.c code may
+ * also configure interrupt controller priorities, OCP bus priorities,
+ * CPU speed(s), etc.
+ *
+ * This function will not affect device wakeup latency, e.g., time
+ * elapsed from when a device driver enables a hardware device with
+ * clk_enable(), to when the device is ready for register access or
+ * other use.  To control this device wakeup latency, use
+ * set_max_dev_wakeup_lat()
+ *
+ * Multiple calls to set_max_mpu_wakeup_lat() will replace the
+ * previous t value.  To remove the latency target for the MPU, call
+ * with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
+ * @dev: struct device * requesting the constraint
+ * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
+ * @r: minimum throughput (in KiB/s)
+ *
+ * Request that the minimum data throughput on the OCP interconnect
+ * attached to device 'dev' interconnect agent 'tbus_id' be no less
+ * than 'r' KiB/s.
+ *
+ * It is expected that the OMAP PM or bus code will use this
+ * information to set the interconnect clock to run at the lowest
+ * possible speed that satisfies all current system users.  The PM or
+ * bus code will adjust the estimate based on its model of the bus, so
+ * device driver authors should attempt to specify an accurate
+ * quantity for their device use case, and let the PM or bus code
+ * overestimate the numbers as necessary to handle request/response
+ * latency, other competing users on the system, etc.  On OMAP2/3, if
+ * a driver requests a minimum L4 interconnect speed constraint, the
+ * code will also need to add an minimum L3 interconnect speed
+ * constraint,
+ *
+ * Multiple calls to set_min_bus_tput() will replace the previous rate
+ * value for this device.  To remove the interconnect throughput
+ * restriction for this device, call with r = 0.
+ *
+ * No return value.
+ */
+void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+
+
+/**
+ * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
+ * @dev: struct device *
+ * @t: maximum device wakeup latency in microseconds
+ *
+ * Request that the maximum amount of time necessary for a device to
+ * become accessible after its clocks are enabled should be no greater
+ * than 't' microseconds.  Specifically, this represents the time from
+ * when a device driver enables device clocks with clk_enable(), to
+ * when the register reads and writes on the device will succeed.
+ * This function should be called before clk_disable() is called,
+ * since the power state transition decision may be made during
+ * clk_disable().
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the powerdomain enclosing this
+ * device into.
+ *
+ * Multiple calls to set_max_dev_wakeup_lat() will replace the
+ * previous wakeup latency values for this device.  To remove the wakeup
+ * latency restriction for this device, call with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
+ * @dev: struct device *
+ * @t: maximum DMA transfer start latency in microseconds
+ *
+ * Request that the maximum system DMA transfer start latency for this
+ * device 'dev' should be no greater than 't' microseconds.  "DMA
+ * transfer start latency" here is defined as the elapsed time from
+ * when a device (e.g., McBSP) requests that a system DMA transfer
+ * start or continue, to the time at which data starts to flow into
+ * that device from the system DMA controller.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the CORE powerdomain into.
+ *
+ * Since system DMA transfers may not involve the MPU, this function
+ * will not affect MPU wakeup latency.  Use set_max_cpu_lat() to do
+ * so.  Similarly, this function will not affect device wakeup latency
+ * -- use set_max_dev_wakeup_lat() to affect that.
+ *
+ * Multiple calls to set_max_sdma_lat() will replace the previous t
+ * value for this device.  To remove the maximum DMA latency for this
+ * device, call with t = -1.
+ *
+ * No return value.
+ */
+void omap_pm_set_max_sdma_lat(struct device *dev, long t);
+
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+/**
+ * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
+ *
+ * Intended for use by DSPBridge.  Returns an array of OPP->DSP clock
+ * frequency entries.  The final item in the array should have .rate =
+ * .opp_id = 0.
+ */
+const struct omap_opp *omap_pm_dsp_get_opp_table(void);
+
+/**
+ * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
+ * @opp_id: target DSP OPP ID
+ *
+ * Set a minimum OPP ID for the DSP.  This is intended to be called
+ * only from the DSP Bridge MPU-side driver.  Unfortunately, the only
+ * information that code receives from the DSP/BIOS load estimator is the
+ * target OPP ID; hence, this interface.  No return value.
+ */
+void omap_pm_dsp_set_min_opp(u8 opp_id);
+
+/**
+ * omap_pm_dsp_get_opp - report the current DSP OPP ID
+ *
+ * Report the current OPP for the DSP.  Since on OMAP3, the DSP and
+ * MPU share a single voltage domain, the OPP ID returned back may
+ * represent a higher DSP speed than the OPP requested via
+ * omap_pm_dsp_set_min_opp().
+ *
+ * Returns the current VDD1 OPP ID, or 0 upon error.
+ */
+u8 omap_pm_dsp_get_opp(void);
+
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+/**
+ * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
+ *
+ * Provide a frequency table usable by CPUFreq for the current chip/board.
+ * Returns a pointer to a struct cpufreq_frequency_table array or NULL
+ * upon error.
+ */
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
+
+/**
+ * omap_pm_cpu_set_freq - set the current minimum MPU frequency
+ * @f: MPU frequency in Hz
+ *
+ * Set the current minimum CPU frequency.  The actual CPU frequency
+ * used could end up higher if the DSP requested a higher OPP.
+ * Intended to be called by plat-omap/cpu_omap.c:omap_target().  No
+ * return value.
+ */
+void omap_pm_cpu_set_freq(unsigned long f);
+
+/**
+ * omap_pm_cpu_get_freq - report the current CPU frequency
+ *
+ * Returns the current MPU frequency, or 0 upon error.
+ */
+unsigned long omap_pm_cpu_get_freq(void);
+
+
+/*
+ * Device context loss tracking
+ */
+
+/**
+ * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx
+ * @dev: struct device *
+ *
+ * This function returns the number of times that the device @dev has
+ * lost its internal context.  This generally occurs on a powerdomain
+ * transition to OFF.  Drivers use this as an optimization to avoid restoring
+ * context if the device hasn't lost it.  To use, drivers should initially
+ * call this in their context save functions and store the result.  Early in
+ * the driver's context restore function, the driver should call this function
+ * again, and compare the result to the stored counter.  If they differ, the
+ * driver must restore device context.   If the number of context losses
+ * exceeds the maximum positive integer, the function will wrap to 0 and
+ * continue counting.  Returns the number of context losses for this device,
+ * or -EINVAL upon error.
+ */
+int omap_pm_get_dev_context_loss_count(struct device *dev);
+
+
+#endif
diff --git a/arch/arm/plat-omap/include/mach/omap44xx.h b/arch/arm/plat-omap/include/mach/omap44xx.h
index 15dec7f..b3ba5ac 100644
--- a/arch/arm/plat-omap/include/mach/omap44xx.h
+++ b/arch/arm/plat-omap/include/mach/omap44xx.h
@@ -33,14 +33,14 @@
 #define IRQ_SIR_IRQ			0x0040
 #define OMAP44XX_GIC_DIST_BASE		0x48241000
 #define OMAP44XX_GIC_CPU_BASE		0x48240100
-#define OMAP44XX_VA_GIC_CPU_BASE	IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
+#define OMAP44XX_VA_GIC_CPU_BASE	OMAP2_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
 #define OMAP44XX_SCU_BASE		0x48240000
-#define OMAP44XX_VA_SCU_BASE		IO_ADDRESS(OMAP44XX_SCU_BASE)
+#define OMAP44XX_VA_SCU_BASE		OMAP2_IO_ADDRESS(OMAP44XX_SCU_BASE)
 #define OMAP44XX_LOCAL_TWD_BASE		0x48240600
-#define OMAP44XX_VA_LOCAL_TWD_BASE	IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE)
+#define OMAP44XX_VA_LOCAL_TWD_BASE	OMAP2_IO_ADDRESS(OMAP44XX_LOCAL_TWD_BASE)
 #define OMAP44XX_LOCAL_TWD_SIZE		0x00000100
 #define OMAP44XX_WKUPGEN_BASE		0x48281000
-#define OMAP44XX_VA_WKUPGEN_BASE	IO_ADDRESS(OMAP44XX_WKUPGEN_BASE)
+#define OMAP44XX_VA_WKUPGEN_BASE	OMAP2_IO_ADDRESS(OMAP44XX_WKUPGEN_BASE)
 
 #endif /* __ASM_ARCH_OMAP44XX_H */
 
diff --git a/arch/arm/plat-omap/include/mach/omap_device.h b/arch/arm/plat-omap/include/mach/omap_device.h
new file mode 100644
index 0000000..bd0e136
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/omap_device.h
@@ -0,0 +1,141 @@
+/*
+ * omap_device headers
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Developed in collaboration with (alphabetical order): Benoit
+ * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram
+ * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard
+ * Woodruff
+ *
+ * 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.
+ *
+ * Eventually this type of functionality should either be
+ * a) implemented via arch-specific pointers in platform_device
+ * or
+ * b) implemented as a proper omap_bus/omap_device in Linux, no more
+ *    platform_device
+ *
+ * omap_device differs from omap_hwmod in that it includes external
+ * (e.g., board- and system-level) integration details.  omap_hwmod
+ * stores hardware data that is invariant for a given OMAP chip.
+ *
+ * To do:
+ * - GPIO integration
+ * - regulator integration
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/omap_hwmod.h>
+
+/* omap_device._state values */
+#define OMAP_DEVICE_STATE_UNKNOWN	0
+#define OMAP_DEVICE_STATE_ENABLED	1
+#define OMAP_DEVICE_STATE_IDLE		2
+#define OMAP_DEVICE_STATE_SHUTDOWN	3
+
+/**
+ * struct omap_device - omap_device wrapper for platform_devices
+ * @pdev: platform_device
+ * @hwmods: (one .. many per omap_device)
+ * @hwmods_cnt: ARRAY_SIZE() of @hwmods
+ * @pm_lats: ptr to an omap_device_pm_latency table
+ * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
+ * @pm_lat_level: array index of the last odpl entry executed - -1 if never
+ * @dev_wakeup_lat: dev wakeup latency in microseconds
+ * @_dev_wakeup_lat_limit: dev wakeup latency limit in usec - set by OMAP PM
+ * @_state: one of OMAP_DEVICE_STATE_* (see above)
+ * @flags: device flags
+ *
+ * Integrates omap_hwmod data into Linux platform_device.
+ *
+ * Field names beginning with underscores are for the internal use of
+ * the omap_device code.
+ *
+ */
+struct omap_device {
+	struct platform_device		pdev;
+	struct omap_hwmod		**hwmods;
+	struct omap_device_pm_latency	*pm_lats;
+	u32				dev_wakeup_lat;
+	u32				_dev_wakeup_lat_limit;
+	u8				pm_lats_cnt;
+	s8				pm_lat_level;
+	u8				hwmods_cnt;
+	u8				_state;
+};
+
+/* Device driver interface (call via platform_data fn ptrs) */
+
+int omap_device_enable(struct platform_device *pdev);
+int omap_device_idle(struct platform_device *pdev);
+int omap_device_shutdown(struct platform_device *pdev);
+
+/* Core code interface */
+
+int omap_device_count_resources(struct omap_device *od);
+int omap_device_fill_resources(struct omap_device *od, struct resource *res);
+
+struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
+				      struct omap_hwmod *oh, void *pdata,
+				      int pdata_len,
+				      struct omap_device_pm_latency *pm_lats,
+				      int pm_lats_cnt);
+
+struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+					 struct omap_hwmod **oh, int oh_cnt,
+					 void *pdata, int pdata_len,
+					 struct omap_device_pm_latency *pm_lats,
+					 int pm_lats_cnt);
+
+int omap_device_register(struct omap_device *od);
+
+/* OMAP PM interface */
+int omap_device_align_pm_lat(struct platform_device *pdev,
+			     u32 new_wakeup_lat_limit);
+struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
+
+/* Other */
+
+int omap_device_idle_hwmods(struct omap_device *od);
+int omap_device_enable_hwmods(struct omap_device *od);
+
+int omap_device_disable_clocks(struct omap_device *od);
+int omap_device_enable_clocks(struct omap_device *od);
+
+
+/*
+ * Entries should be kept in latency order ascending
+ *
+ * deact_lat is the maximum number of microseconds required to complete
+ * deactivate_func() at the device's slowest OPP.
+ *
+ * act_lat is the maximum number of microseconds required to complete
+ * activate_func() at the device's slowest OPP.
+ *
+ * This will result in some suboptimal power management decisions at fast
+ * OPPs, but avoids having to recompute all device power management decisions
+ * if the system shifts from a fast OPP to a slow OPP (in order to meet
+ * latency requirements).
+ *
+ * XXX should deactivate_func/activate_func() take platform_device pointers
+ * rather than omap_device pointers?
+ */
+struct omap_device_pm_latency {
+	u32 deactivate_lat;
+	int (*deactivate_func)(struct omap_device *od);
+	u32 activate_lat;
+	int (*activate_func)(struct omap_device *od);
+};
+
+
+#endif
+
diff --git a/arch/arm/plat-omap/include/mach/omap_hwmod.h b/arch/arm/plat-omap/include/mach/omap_hwmod.h
new file mode 100644
index 0000000..1f79c20
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/omap_hwmod.h
@@ -0,0 +1,447 @@
+/*
+ * omap_hwmod macros, structures
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Created in collaboration with (alphabetical order): Benoit Cousson,
+ * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
+ * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
+ *
+ * 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.
+ *
+ * These headers and macros are used to define OMAP on-chip module
+ * data and their integration with other OMAP modules and Linux.
+ *
+ * References:
+ * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
+ * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
+ * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
+ * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
+ * - Open Core Protocol Specification 2.2
+ *
+ * To do:
+ * - add interconnect error log structures
+ * - add pinmuxing
+ * - init_conn_id_bit (CONNID_BIT_VECTOR)
+ * - implement default hwmod SMS/SDRC flags?
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+
+#include <mach/cpu.h>
+
+struct omap_device;
+
+/* OCP SYSCONFIG bit shifts/masks */
+#define SYSC_MIDLEMODE_SHIFT		12
+#define SYSC_MIDLEMODE_MASK		(0x3 << SYSC_MIDLEMODE_SHIFT)
+#define SYSC_CLOCKACTIVITY_SHIFT	8
+#define SYSC_CLOCKACTIVITY_MASK		(0x3 << SYSC_CLOCKACTIVITY_SHIFT)
+#define SYSC_SIDLEMODE_SHIFT		3
+#define SYSC_SIDLEMODE_MASK		(0x3 << SYSC_SIDLEMODE_SHIFT)
+#define SYSC_ENAWAKEUP_SHIFT		2
+#define SYSC_ENAWAKEUP_MASK		(1 << SYSC_ENAWAKEUP_SHIFT)
+#define SYSC_SOFTRESET_SHIFT		1
+#define SYSC_SOFTRESET_MASK		(1 << SYSC_SOFTRESET_SHIFT)
+
+/* OCP SYSSTATUS bit shifts/masks */
+#define SYSS_RESETDONE_SHIFT		0
+#define SYSS_RESETDONE_MASK		(1 << SYSS_RESETDONE_SHIFT)
+
+/* Master standby/slave idle mode flags */
+#define HWMOD_IDLEMODE_FORCE		(1 << 0)
+#define HWMOD_IDLEMODE_NO		(1 << 1)
+#define HWMOD_IDLEMODE_SMART		(1 << 2)
+
+
+/**
+ * struct omap_hwmod_dma_info - MPU address space handled by the hwmod
+ * @name: name of the DMA channel (module local name)
+ * @dma_ch: DMA channel ID
+ *
+ * @name should be something short, e.g., "tx" or "rx".  It is for use
+ * by platform_get_resource_byname().  It is defined locally to the
+ * hwmod.
+ */
+struct omap_hwmod_dma_info {
+	const char	*name;
+	u16		dma_ch;
+};
+
+/**
+ * struct omap_hwmod_opt_clk - optional clocks used by this hwmod
+ * @role: "sys", "32k", "tv", etc -- for use in clk_get()
+ * @clkdev_dev_id: opt clock: clkdev dev_id string
+ * @clkdev_con_id: opt clock: clkdev con_id string
+ * @_clk: pointer to the struct clk (filled in at runtime)
+ *
+ * The module's interface clock and main functional clock should not
+ * be added as optional clocks.
+ */
+struct omap_hwmod_opt_clk {
+	const char	*role;
+	const char	*clkdev_dev_id;
+	const char	*clkdev_con_id;
+	struct clk	*_clk;
+};
+
+
+/* omap_hwmod_omap2_firewall.flags bits */
+#define OMAP_FIREWALL_L3		(1 << 0)
+#define OMAP_FIREWALL_L4		(1 << 1)
+
+/**
+ * struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data
+ * @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_*
+ * @l4_fw_region: L4 firewall region ID
+ * @l4_prot_group: L4 protection group ID
+ * @flags: (see omap_hwmod_omap2_firewall.flags macros above)
+ */
+struct omap_hwmod_omap2_firewall {
+	u8 l3_perm_bit;
+	u8 l4_fw_region;
+	u8 l4_prot_group;
+	u8 flags;
+};
+
+
+/*
+ * omap_hwmod_addr_space.flags bits
+ *
+ * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
+ * ADDR_TYPE_RT: Address space contains module register target data.
+ */
+#define ADDR_MAP_ON_INIT	(1 << 0)
+#define ADDR_TYPE_RT		(1 << 1)
+
+/**
+ * struct omap_hwmod_addr_space - MPU address space handled by the hwmod
+ * @pa_start: starting physical address
+ * @pa_end: ending physical address
+ * @flags: (see omap_hwmod_addr_space.flags macros above)
+ *
+ * Address space doesn't necessarily follow physical interconnect
+ * structure.  GPMC is one example.
+ */
+struct omap_hwmod_addr_space {
+	u32 pa_start;
+	u32 pa_end;
+	u8 flags;
+};
+
+
+/*
+ * omap_hwmod_ocp_if.user bits: these indicate the initiators that use this
+ * interface to interact with the hwmod.  Used to add sleep dependencies
+ * when the module is enabled or disabled.
+ */
+#define OCP_USER_MPU			(1 << 0)
+#define OCP_USER_SDMA			(1 << 1)
+
+/* omap_hwmod_ocp_if.flags bits */
+#define OCPIF_HAS_IDLEST		(1 << 0)
+#define OCPIF_SWSUP_IDLE		(1 << 1)
+#define OCPIF_CAN_BURST			(1 << 2)
+
+/**
+ * struct omap_hwmod_ocp_if - OCP interface data
+ * @master: struct omap_hwmod that initiates OCP transactions on this link
+ * @slave: struct omap_hwmod that responds to OCP transactions on this link
+ * @addr: address space associated with this link
+ * @clkdev_dev_id: interface clock: clkdev dev_id string
+ * @clkdev_con_id: interface clock: clkdev con_id string
+ * @_clk: pointer to the interface struct clk (filled in at runtime)
+ * @fw: interface firewall data
+ * @addr_cnt: ARRAY_SIZE(@addr)
+ * @width: OCP data width
+ * @thread_cnt: number of threads
+ * @max_burst_len: maximum burst length in @width sized words (0 if unlimited)
+ * @user: initiators using this interface (see OCP_USER_* macros above)
+ * @flags: OCP interface flags (see OCPIF_* macros above)
+ *
+ * It may also be useful to add a tag_cnt field for OCP2.x devices.
+ *
+ * Parameter names beginning with an underscore are managed internally by
+ * the omap_hwmod code and should not be set during initialization.
+ */
+struct omap_hwmod_ocp_if {
+	struct omap_hwmod		*master;
+	struct omap_hwmod		*slave;
+	struct omap_hwmod_addr_space	*addr;
+	const char			*clkdev_dev_id;
+	const char			*clkdev_con_id;
+	struct clk			*_clk;
+	union {
+		struct omap_hwmod_omap2_firewall omap2;
+	}				fw;
+	u8				addr_cnt;
+	u8				width;
+	u8				thread_cnt;
+	u8				max_burst_len;
+	u8				user;
+	u8				flags;
+};
+
+
+/* Macros for use in struct omap_hwmod_sysconfig */
+
+/* Flags for use in omap_hwmod_sysconfig.idlemodes */
+#define MASTER_STANDBY_SHIFT	2
+#define SLAVE_IDLE_SHIFT	0
+#define SIDLE_FORCE		(HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
+#define SIDLE_NO		(HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
+#define SIDLE_SMART		(HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
+#define MSTANDBY_FORCE		(HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
+#define MSTANDBY_NO		(HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
+#define MSTANDBY_SMART		(HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
+
+/* omap_hwmod_sysconfig.sysc_flags capability flags */
+#define SYSC_HAS_AUTOIDLE	(1 << 0)
+#define SYSC_HAS_SOFTRESET	(1 << 1)
+#define SYSC_HAS_ENAWAKEUP	(1 << 2)
+#define SYSC_HAS_EMUFREE	(1 << 3)
+#define SYSC_HAS_CLOCKACTIVITY	(1 << 4)
+#define SYSC_HAS_SIDLEMODE	(1 << 5)
+#define SYSC_HAS_MIDLEMODE	(1 << 6)
+#define SYSS_MISSING		(1 << 7)
+
+/* omap_hwmod_sysconfig.clockact flags */
+#define CLOCKACT_TEST_BOTH	0x0
+#define CLOCKACT_TEST_MAIN	0x1
+#define CLOCKACT_TEST_ICLK	0x2
+#define CLOCKACT_TEST_NONE	0x3
+
+/**
+ * struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
+ * @rev_offs: IP block revision register offset (from module base addr)
+ * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
+ * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
+ * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
+ * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
+ * @clockact: the default value of the module CLOCKACTIVITY bits
+ *
+ * @clockact describes to the module which clocks are likely to be
+ * disabled when the PRCM issues its idle request to the module.  Some
+ * modules have separate clockdomains for the interface clock and main
+ * functional clock, and can check whether they should acknowledge the
+ * idle request based on the internal module functionality that has
+ * been associated with the clocks marked in @clockact.  This field is
+ * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
+ *
+ */
+struct omap_hwmod_sysconfig {
+	u16 rev_offs;
+	u16 sysc_offs;
+	u16 syss_offs;
+	u8 idlemodes;
+	u8 sysc_flags;
+	u8 clockact;
+};
+
+/**
+ * struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data
+ * @module_offs: PRCM submodule offset from the start of the PRM/CM
+ * @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3)
+ * @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs
+ * @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3)
+ * @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit
+ * @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit
+ *
+ * @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST,
+ * WKEN, GRPSEL registers.  In an ideal world, no extra information
+ * would be needed for IDLEST information, but alas, there are some
+ * exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit
+ * are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST)
+ */
+struct omap_hwmod_omap2_prcm {
+	s16 module_offs;
+	u8 prcm_reg_id;
+	u8 module_bit;
+	u8 idlest_reg_id;
+	u8 idlest_idle_bit;
+	u8 idlest_stdby_bit;
+};
+
+
+/**
+ * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
+ * @module_offs: PRCM submodule offset from the start of the PRM/CM1/CM2
+ * @device_offs: device register offset from @module_offs
+ * @submodule_wkdep_bit: bit shift of the WKDEP range
+ */
+struct omap_hwmod_omap4_prcm {
+	u32 module_offs;
+	u16 device_offs;
+	u8 submodule_wkdep_bit;
+};
+
+
+/*
+ * omap_hwmod.flags definitions
+ *
+ * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
+ *     of idle, rather than relying on module smart-idle
+ * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
+ *     of standby, rather than relying on module smart-standby
+ * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
+ *     SDRAM controller, etc.
+ * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
+ *     controller, etc.
+ * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
+ */
+#define HWMOD_SWSUP_SIDLE			(1 << 0)
+#define HWMOD_SWSUP_MSTANDBY			(1 << 1)
+#define HWMOD_INIT_NO_RESET			(1 << 2)
+#define HWMOD_INIT_NO_IDLE			(1 << 3)
+#define HWMOD_SET_DEFAULT_CLOCKACT		(1 << 4)
+
+/*
+ * omap_hwmod._int_flags definitions
+ * These are for internal use only and are managed by the omap_hwmod code.
+ *
+ * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
+ * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
+ * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
+ */
+#define _HWMOD_NO_MPU_PORT			(1 << 0)
+#define _HWMOD_WAKEUP_ENABLED			(1 << 1)
+#define _HWMOD_SYSCONFIG_LOADED			(1 << 2)
+
+/*
+ * omap_hwmod._state definitions
+ *
+ * INITIALIZED: reset (optionally), initialized, enabled, disabled
+ *              (optionally)
+ *
+ *
+ */
+#define _HWMOD_STATE_UNKNOWN			0
+#define _HWMOD_STATE_REGISTERED			1
+#define _HWMOD_STATE_CLKS_INITED		2
+#define _HWMOD_STATE_INITIALIZED		3
+#define _HWMOD_STATE_ENABLED			4
+#define _HWMOD_STATE_IDLE			5
+#define _HWMOD_STATE_DISABLED			6
+
+/**
+ * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
+ * @name: name of the hwmod
+ * @od: struct omap_device currently associated with this hwmod (internal use)
+ * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
+ * @sdma_chs: ptr to an array of SDMA channel IDs (see also sdma_chs_cnt)
+ * @prcm: PRCM data pertaining to this hwmod
+ * @clkdev_dev_id: main clock: clkdev dev_id string
+ * @clkdev_con_id: main clock: clkdev con_id string
+ * @_clk: pointer to the main struct clk (filled in at runtime)
+ * @opt_clks: other device clocks that drivers can request (0..*)
+ * @masters: ptr to array of OCP ifs that this hwmod can initiate on
+ * @slaves: ptr to array of OCP ifs that this hwmod can respond on
+ * @sysconfig: device SYSCONFIG/SYSSTATUS register data
+ * @dev_attr: arbitrary device attributes that can be passed to the driver
+ * @_sysc_cache: internal-use hwmod flags
+ * @_rt_va: cached register target start address (internal use)
+ * @_mpu_port_index: cached MPU register target slave ID (internal use)
+ * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
+ * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
+ * @mpu_irqs_cnt: number of @mpu_irqs
+ * @sdma_chs_cnt: number of @sdma_chs
+ * @opt_clks_cnt: number of @opt_clks
+ * @master_cnt: number of @master entries
+ * @slaves_cnt: number of @slave entries
+ * @response_lat: device OCP response latency (in interface clock cycles)
+ * @_int_flags: internal-use hwmod flags
+ * @_state: internal-use hwmod state
+ * @flags: hwmod flags (documented below)
+ * @omap_chip: OMAP chips this hwmod is present on
+ * @node: list node for hwmod list (internal use)
+ *
+ * @clkdev_dev_id, @clkdev_con_id, and @clk all refer to this module's "main
+ * clock," which for our purposes is defined as "the functional clock needed
+ * for register accesses to complete."  Modules may not have a main clock if
+ * the interface clock also serves as a main clock.
+ *
+ * Parameter names beginning with an underscore are managed internally by
+ * the omap_hwmod code and should not be set during initialization.
+ */
+struct omap_hwmod {
+	const char			*name;
+	struct omap_device		*od;
+	u8				*mpu_irqs;
+	struct omap_hwmod_dma_info	*sdma_chs;
+	union {
+		struct omap_hwmod_omap2_prcm omap2;
+		struct omap_hwmod_omap4_prcm omap4;
+	}				prcm;
+	const char			*clkdev_dev_id;
+	const char			*clkdev_con_id;
+	struct clk			*_clk;
+	struct omap_hwmod_opt_clk	*opt_clks;
+	struct omap_hwmod_ocp_if	**masters; /* connect to *_IA */
+	struct omap_hwmod_ocp_if	**slaves;  /* connect to *_TA */
+	struct omap_hwmod_sysconfig	*sysconfig;
+	void				*dev_attr;
+	u32				_sysc_cache;
+	void __iomem			*_rt_va;
+	struct list_head		node;
+	u16				flags;
+	u8				_mpu_port_index;
+	u8				msuspendmux_reg_id;
+	u8				msuspendmux_shift;
+	u8				response_lat;
+	u8				mpu_irqs_cnt;
+	u8				sdma_chs_cnt;
+	u8				opt_clks_cnt;
+	u8				masters_cnt;
+	u8				slaves_cnt;
+	u8				hwmods_cnt;
+	u8				_int_flags;
+	u8				_state;
+	const struct omap_chip_id	omap_chip;
+};
+
+int omap_hwmod_init(struct omap_hwmod **ohs);
+int omap_hwmod_register(struct omap_hwmod *oh);
+int omap_hwmod_unregister(struct omap_hwmod *oh);
+struct omap_hwmod *omap_hwmod_lookup(const char *name);
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
+int omap_hwmod_late_init(void);
+
+int omap_hwmod_enable(struct omap_hwmod *oh);
+int omap_hwmod_idle(struct omap_hwmod *oh);
+int omap_hwmod_shutdown(struct omap_hwmod *oh);
+
+int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
+int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
+
+int omap_hwmod_reset(struct omap_hwmod *oh);
+void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
+
+void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs);
+u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs);
+
+int omap_hwmod_count_resources(struct omap_hwmod *oh);
+int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
+
+struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
+
+int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
+				 struct omap_hwmod *init_oh);
+int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
+				 struct omap_hwmod *init_oh);
+
+int omap_hwmod_set_clockact_both(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_main(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
+
+int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
+int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
+
+#endif
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
index 69c9e67..6271d85 100644
--- a/arch/arm/plat-omap/include/mach/powerdomain.h
+++ b/arch/arm/plat-omap/include/mach/powerdomain.h
@@ -117,6 +117,13 @@ struct powerdomain {
 
 	struct list_head node;
 
+	int state;
+	unsigned state_counter[4];
+
+#ifdef CONFIG_PM_DEBUG
+	s64 timer;
+	s64 state_timer[4];
+#endif
 };
 
 
@@ -126,7 +133,8 @@ int pwrdm_register(struct powerdomain *pwrdm);
 int pwrdm_unregister(struct powerdomain *pwrdm);
 struct powerdomain *pwrdm_lookup(const char *name);
 
-int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm));
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+			void *user);
 
 int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
 int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
@@ -164,4 +172,9 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
 
 int pwrdm_wait_transition(struct powerdomain *pwrdm);
 
+int pwrdm_state_switch(struct powerdomain *pwrdm);
+int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
+int pwrdm_pre_transition(void);
+int pwrdm_post_transition(void);
+
 #endif
diff --git a/arch/arm/plat-omap/include/mach/sdrc.h b/arch/arm/plat-omap/include/mach/sdrc.h
index 0be18e4..1c09c78 100644
--- a/arch/arm/plat-omap/include/mach/sdrc.h
+++ b/arch/arm/plat-omap/include/mach/sdrc.h
@@ -21,19 +21,28 @@
 /* SDRC register offsets - read/write with sdrc_{read,write}_reg() */
 
 #define SDRC_SYSCONFIG		0x010
+#define SDRC_CS_CFG		0x040
+#define SDRC_SHARING		0x044
+#define SDRC_ERR_TYPE		0x04C
 #define SDRC_DLLA_CTRL		0x060
 #define SDRC_DLLA_STATUS	0x064
 #define SDRC_DLLB_CTRL		0x068
 #define SDRC_DLLB_STATUS	0x06C
 #define SDRC_POWER		0x070
+#define SDRC_MCFG_0		0x080
 #define SDRC_MR_0		0x084
+#define SDRC_EMR2_0		0x08c
 #define SDRC_ACTIM_CTRL_A_0	0x09c
 #define SDRC_ACTIM_CTRL_B_0	0x0a0
 #define SDRC_RFR_CTRL_0		0x0a4
+#define SDRC_MANUAL_0		0x0a8
+#define SDRC_MCFG_1		0x0B0
 #define SDRC_MR_1		0x0B4
+#define SDRC_EMR2_1		0x0BC
 #define SDRC_ACTIM_CTRL_A_1	0x0C4
 #define SDRC_ACTIM_CTRL_B_1	0x0C8
 #define SDRC_RFR_CTRL_1		0x0D4
+#define SDRC_MANUAL_1		0x0D8
 
 /*
  * These values represent the number of memory clock cycles between
@@ -71,11 +80,11 @@
  */
 
 #define OMAP242X_SMS_REGADDR(reg)					\
-			(void __iomem *)IO_ADDRESS(OMAP2420_SMS_BASE + reg)
+			(void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE + reg)
 #define OMAP243X_SMS_REGADDR(reg)					\
-			(void __iomem *)IO_ADDRESS(OMAP243X_SMS_BASE + reg)
+			(void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE + reg)
 #define OMAP343X_SMS_REGADDR(reg)					\
-			(void __iomem *)IO_ADDRESS(OMAP343X_SMS_BASE + reg)
+			(void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE + reg)
 
 /* SMS register offsets - read/write with sms_{read,write}_reg() */
 
diff --git a/arch/arm/plat-omap/include/mach/serial.h b/arch/arm/plat-omap/include/mach/serial.h
index def0529..e249186 100644
--- a/arch/arm/plat-omap/include/mach/serial.h
+++ b/arch/arm/plat-omap/include/mach/serial.h
@@ -13,6 +13,8 @@
 #ifndef __ASM_ARCH_SERIAL_H
 #define __ASM_ARCH_SERIAL_H
 
+#include <linux/init.h>
+
 #if defined(CONFIG_ARCH_OMAP1)
 /* OMAP1 serial ports */
 #define OMAP_UART1_BASE		0xfffb0000
@@ -53,6 +55,7 @@
 			})
 
 #ifndef __ASSEMBLER__
+extern void __init omap_serial_early_init(void);
 extern void omap_serial_init(void);
 extern int omap_uart_can_sleep(void);
 extern void omap_uart_check_wakeup(void);
diff --git a/arch/arm/plat-omap/include/mach/system.h b/arch/arm/plat-omap/include/mach/system.h
index 1060e34..ed8ec74 100644
--- a/arch/arm/plat-omap/include/mach/system.h
+++ b/arch/arm/plat-omap/include/mach/system.h
@@ -1,6 +1,6 @@
 /*
  * Copied from arch/arm/mach-sa1100/include/mach/system.h
- * Copyright (c) 1999 Nicolas Pitre <nico@cam.org>
+ * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
  */
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c
index 9b42d72..b6defa2 100644
--- a/arch/arm/plat-omap/io.c
+++ b/arch/arm/plat-omap/io.c
@@ -30,8 +30,8 @@ void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type)
 {
 #ifdef CONFIG_ARCH_OMAP1
 	if (cpu_class_is_omap1()) {
-		if (BETWEEN(p, IO_PHYS, IO_SIZE))
-			return XLATE(p, IO_PHYS, IO_VIRT);
+		if (BETWEEN(p, OMAP1_IO_PHYS, OMAP1_IO_SIZE))
+			return XLATE(p, OMAP1_IO_PHYS, OMAP1_IO_VIRT);
 	}
 	if (cpu_is_omap730()) {
 		if (BETWEEN(p, OMAP730_DSP_BASE, OMAP730_DSP_SIZE))
@@ -132,3 +132,61 @@ void omap_iounmap(volatile void __iomem *addr)
 		__iounmap(addr);
 }
 EXPORT_SYMBOL(omap_iounmap);
+
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+
+u8 omap_readb(u32 pa)
+{
+	if (cpu_class_is_omap1())
+		return __raw_readb(OMAP1_IO_ADDRESS(pa));
+	else
+		return __raw_readb(OMAP2_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readb);
+
+u16 omap_readw(u32 pa)
+{
+	if (cpu_class_is_omap1())
+		return __raw_readw(OMAP1_IO_ADDRESS(pa));
+	else
+		return __raw_readw(OMAP2_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readw);
+
+u32 omap_readl(u32 pa)
+{
+	if (cpu_class_is_omap1())
+		return __raw_readl(OMAP1_IO_ADDRESS(pa));
+	else
+		return __raw_readl(OMAP2_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readl);
+
+void omap_writeb(u8 v, u32 pa)
+{
+	if (cpu_class_is_omap1())
+		__raw_writeb(v, OMAP1_IO_ADDRESS(pa));
+	else
+		__raw_writeb(v, OMAP2_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writeb);
+
+void omap_writew(u16 v, u32 pa)
+{
+	if (cpu_class_is_omap1())
+		__raw_writew(v, OMAP1_IO_ADDRESS(pa));
+	else
+		__raw_writew(v, OMAP2_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writew);
+
+void omap_writel(u32 v, u32 pa)
+{
+	if (cpu_class_is_omap1())
+		__raw_writel(v, OMAP1_IO_ADDRESS(pa));
+	else
+		__raw_writel(v, OMAP2_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/plat-omap/iommu-debug.c b/arch/arm/plat-omap/iommu-debug.c
new file mode 100644
index 0000000..c799b3b
--- /dev/null
+++ b/arch/arm/plat-omap/iommu-debug.c
@@ -0,0 +1,415 @@
+/*
+ * omap iommu: debugfs interface
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@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.
+ */
+
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+
+#include <mach/iommu.h>
+#include <mach/iovmm.h>
+
+#include "iopgtable.h"
+
+#define MAXCOLUMN 100 /* for short messages */
+
+static DEFINE_MUTEX(iommu_debug_lock);
+
+static struct dentry *iommu_debug_root;
+
+static ssize_t debug_read_ver(struct file *file, char __user *userbuf,
+			      size_t count, loff_t *ppos)
+{
+	u32 ver = iommu_arch_version();
+	char buf[MAXCOLUMN], *p = buf;
+
+	p += sprintf(p, "H/W version: %d.%d\n", (ver >> 4) & 0xf , ver & 0xf);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+}
+
+static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	struct iommu *obj = file->private_data;
+	char *p, *buf;
+	ssize_t bytes;
+
+	buf = kmalloc(count, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	p = buf;
+
+	mutex_lock(&iommu_debug_lock);
+
+	bytes = iommu_dump_ctx(obj, p, count);
+	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, bytes);
+
+	mutex_unlock(&iommu_debug_lock);
+	kfree(buf);
+
+	return bytes;
+}
+
+static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
+			      size_t count, loff_t *ppos)
+{
+	struct iommu *obj = file->private_data;
+	char *p, *buf;
+	ssize_t bytes, rest;
+
+	buf = kmalloc(count, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	p = buf;
+
+	mutex_lock(&iommu_debug_lock);
+
+	p += sprintf(p, "%8s %8s\n", "cam:", "ram:");
+	p += sprintf(p, "-----------------------------------------\n");
+	rest = count - (p - buf);
+	p += dump_tlb_entries(obj, p, rest);
+
+	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+
+	mutex_unlock(&iommu_debug_lock);
+	kfree(buf);
+
+	return bytes;
+}
+
+static ssize_t debug_write_pagetable(struct file *file,
+		     const char __user *userbuf, size_t count, loff_t *ppos)
+{
+	struct iotlb_entry e;
+	struct cr_regs cr;
+	int err;
+	struct iommu *obj = file->private_data;
+	char buf[MAXCOLUMN], *p = buf;
+
+	count = min(count, sizeof(buf));
+
+	mutex_lock(&iommu_debug_lock);
+	if (copy_from_user(p, userbuf, count)) {
+		mutex_unlock(&iommu_debug_lock);
+		return -EFAULT;
+	}
+
+	sscanf(p, "%x %x", &cr.cam, &cr.ram);
+	if (!cr.cam || !cr.ram) {
+		mutex_unlock(&iommu_debug_lock);
+		return -EINVAL;
+	}
+
+	iotlb_cr_to_e(&cr, &e);
+	err = iopgtable_store_entry(obj, &e);
+	if (err)
+		dev_err(obj->dev, "%s: fail to store cr\n", __func__);
+
+	mutex_unlock(&iommu_debug_lock);
+	return count;
+}
+
+#define dump_ioptable_entry_one(lv, da, val)			\
+	({							\
+		int __err = 0;					\
+		ssize_t bytes;					\
+		const int maxcol = 22;				\
+		const char *str = "%d: %08x %08x\n";		\
+		bytes = snprintf(p, maxcol, str, lv, da, val);	\
+		p += bytes;					\
+		len -= bytes;					\
+		if (len < maxcol)				\
+			__err = -ENOMEM;			\
+		__err;						\
+	})
+
+static ssize_t dump_ioptable(struct iommu *obj, char *buf, ssize_t len)
+{
+	int i;
+	u32 *iopgd;
+	char *p = buf;
+
+	spin_lock(&obj->page_table_lock);
+
+	iopgd = iopgd_offset(obj, 0);
+	for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) {
+		int j, err;
+		u32 *iopte;
+		u32 da;
+
+		if (!*iopgd)
+			continue;
+
+		if (!(*iopgd & IOPGD_TABLE)) {
+			da = i << IOPGD_SHIFT;
+
+			err = dump_ioptable_entry_one(1, da, *iopgd);
+			if (err)
+				goto out;
+			continue;
+		}
+
+		iopte = iopte_offset(iopgd, 0);
+
+		for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) {
+			if (!*iopte)
+				continue;
+
+			da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT);
+			err = dump_ioptable_entry_one(2, da, *iopgd);
+			if (err)
+				goto out;
+		}
+	}
+out:
+	spin_unlock(&obj->page_table_lock);
+
+	return p - buf;
+}
+
+static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
+				    size_t count, loff_t *ppos)
+{
+	struct iommu *obj = file->private_data;
+	char *p, *buf;
+	size_t bytes;
+
+	buf = (char *)__get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	p = buf;
+
+	p += sprintf(p, "L: %8s %8s\n", "da:", "pa:");
+	p += sprintf(p, "-----------------------------------------\n");
+
+	mutex_lock(&iommu_debug_lock);
+
+	bytes = PAGE_SIZE - (p - buf);
+	p += dump_ioptable(obj, p, bytes);
+
+	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+
+	mutex_unlock(&iommu_debug_lock);
+	free_page((unsigned long)buf);
+
+	return bytes;
+}
+
+static ssize_t debug_read_mmap(struct file *file, char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	struct iommu *obj = file->private_data;
+	char *p, *buf;
+	struct iovm_struct *tmp;
+	int uninitialized_var(i);
+	ssize_t bytes;
+
+	buf = (char *)__get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	p = buf;
+
+	p += sprintf(p, "%-3s %-8s %-8s %6s %8s\n",
+		     "No", "start", "end", "size", "flags");
+	p += sprintf(p, "-------------------------------------------------\n");
+
+	mutex_lock(&iommu_debug_lock);
+
+	list_for_each_entry(tmp, &obj->mmap, list) {
+		size_t len;
+		const char *str = "%3d %08x-%08x %6x %8x\n";
+		const int maxcol = 39;
+
+		len = tmp->da_end - tmp->da_start;
+		p += snprintf(p, maxcol, str,
+			      i, tmp->da_start, tmp->da_end, len, tmp->flags);
+
+		if (PAGE_SIZE - (p - buf) < maxcol)
+			break;
+		i++;
+	}
+
+	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+
+	mutex_unlock(&iommu_debug_lock);
+	free_page((unsigned long)buf);
+
+	return bytes;
+}
+
+static ssize_t debug_read_mem(struct file *file, char __user *userbuf,
+			      size_t count, loff_t *ppos)
+{
+	struct iommu *obj = file->private_data;
+	char *p, *buf;
+	struct iovm_struct *area;
+	ssize_t bytes;
+
+	count = min_t(ssize_t, count, PAGE_SIZE);
+
+	buf = (char *)__get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	p = buf;
+
+	mutex_lock(&iommu_debug_lock);
+
+	area = find_iovm_area(obj, (u32)ppos);
+	if (IS_ERR(area)) {
+		bytes = -EINVAL;
+		goto err_out;
+	}
+	memcpy(p, area->va, count);
+	p += count;
+
+	bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+err_out:
+	mutex_unlock(&iommu_debug_lock);
+	free_page((unsigned long)buf);
+
+	return bytes;
+}
+
+static ssize_t debug_write_mem(struct file *file, const char __user *userbuf,
+			       size_t count, loff_t *ppos)
+{
+	struct iommu *obj = file->private_data;
+	struct iovm_struct *area;
+	char *p, *buf;
+
+	count = min_t(size_t, count, PAGE_SIZE);
+
+	buf = (char *)__get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	p = buf;
+
+	mutex_lock(&iommu_debug_lock);
+
+	if (copy_from_user(p, userbuf, count)) {
+		count =  -EFAULT;
+		goto err_out;
+	}
+
+	area = find_iovm_area(obj, (u32)ppos);
+	if (IS_ERR(area)) {
+		count = -EINVAL;
+		goto err_out;
+	}
+	memcpy(area->va, p, count);
+err_out:
+	mutex_unlock(&iommu_debug_lock);
+	free_page((unsigned long)buf);
+
+	return count;
+}
+
+static int debug_open_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+#define DEBUG_FOPS(name)						\
+	static const struct file_operations debug_##name##_fops = {	\
+		.open = debug_open_generic,				\
+		.read = debug_read_##name,				\
+		.write = debug_write_##name,				\
+	};
+
+#define DEBUG_FOPS_RO(name)						\
+	static const struct file_operations debug_##name##_fops = {	\
+		.open = debug_open_generic,				\
+		.read = debug_read_##name,				\
+	};
+
+DEBUG_FOPS_RO(ver);
+DEBUG_FOPS_RO(regs);
+DEBUG_FOPS_RO(tlb);
+DEBUG_FOPS(pagetable);
+DEBUG_FOPS_RO(mmap);
+DEBUG_FOPS(mem);
+
+#define __DEBUG_ADD_FILE(attr, mode)					\
+	{								\
+		struct dentry *dent;					\
+		dent = debugfs_create_file(#attr, mode, parent,		\
+					   obj, &debug_##attr##_fops);	\
+		if (!dent)						\
+			return -ENOMEM;					\
+	}
+
+#define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 600)
+#define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 400)
+
+static int iommu_debug_register(struct device *dev, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct iommu *obj = platform_get_drvdata(pdev);
+	struct dentry *d, *parent;
+
+	if (!obj || !obj->dev)
+		return -EINVAL;
+
+	d = debugfs_create_dir(obj->name, iommu_debug_root);
+	if (!d)
+		return -ENOMEM;
+	parent = d;
+
+	d = debugfs_create_u8("nr_tlb_entries", 400, parent,
+			      (u8 *)&obj->nr_tlb_entries);
+	if (!d)
+		return -ENOMEM;
+
+	DEBUG_ADD_FILE_RO(ver);
+	DEBUG_ADD_FILE_RO(regs);
+	DEBUG_ADD_FILE_RO(tlb);
+	DEBUG_ADD_FILE(pagetable);
+	DEBUG_ADD_FILE_RO(mmap);
+	DEBUG_ADD_FILE(mem);
+
+	return 0;
+}
+
+static int __init iommu_debug_init(void)
+{
+	struct dentry *d;
+	int err;
+
+	d = debugfs_create_dir("iommu", NULL);
+	if (!d)
+		return -ENOMEM;
+	iommu_debug_root = d;
+
+	err = foreach_iommu_device(d, iommu_debug_register);
+	if (err)
+		goto err_out;
+	return 0;
+
+err_out:
+	debugfs_remove_recursive(iommu_debug_root);
+	return err;
+}
+module_init(iommu_debug_init)
+
+static void __exit iommu_debugfs_exit(void)
+{
+	debugfs_remove_recursive(iommu_debug_root);
+}
+module_exit(iommu_debugfs_exit)
+
+MODULE_DESCRIPTION("omap iommu: debugfs interface");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index 4a03013..4b60127 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -351,16 +351,14 @@ EXPORT_SYMBOL_GPL(flush_iotlb_all);
 
 #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
 
-ssize_t iommu_dump_ctx(struct iommu *obj, char *buf)
+ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes)
 {
-	ssize_t bytes;
-
 	if (!obj || !buf)
 		return -EINVAL;
 
 	clk_enable(obj->clk);
 
-	bytes = arch_iommu->dump_ctx(obj, buf);
+	bytes = arch_iommu->dump_ctx(obj, buf, bytes);
 
 	clk_disable(obj->clk);
 
@@ -368,7 +366,7 @@ ssize_t iommu_dump_ctx(struct iommu *obj, char *buf)
 }
 EXPORT_SYMBOL_GPL(iommu_dump_ctx);
 
-static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs)
+static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num)
 {
 	int i;
 	struct iotlb_lock saved, l;
@@ -379,7 +377,7 @@ static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs)
 	iotlb_lock_get(obj, &saved);
 	memcpy(&l, &saved, sizeof(saved));
 
-	for (i = 0; i < obj->nr_tlb_entries; i++) {
+	for (i = 0; i < num; i++) {
 		struct cr_regs tmp;
 
 		iotlb_lock_get(obj, &l);
@@ -402,18 +400,21 @@ static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs)
  * @obj:	target iommu
  * @buf:	output buffer
  **/
-size_t dump_tlb_entries(struct iommu *obj, char *buf)
+size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t bytes)
 {
-	int i, n;
+	int i, num;
 	struct cr_regs *cr;
 	char *p = buf;
 
-	cr = kcalloc(obj->nr_tlb_entries, sizeof(*cr), GFP_KERNEL);
+	num = bytes / sizeof(*cr);
+	num = min(obj->nr_tlb_entries, num);
+
+	cr = kcalloc(num, sizeof(*cr), GFP_KERNEL);
 	if (!cr)
 		return 0;
 
-	n = __dump_tlb_entries(obj, cr);
-	for (i = 0; i < n; i++)
+	num = __dump_tlb_entries(obj, cr, num);
+	for (i = 0; i < num; i++)
 		p += iotlb_dump_cr(obj, cr + i, p);
 	kfree(cr);
 
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 2fce2c1..6fc52fc 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -199,7 +199,7 @@ static void *vmap_sg(const struct sg_table *sgt)
 		va += bytes;
 	}
 
-	flush_cache_vmap(new->addr, total);
+	flush_cache_vmap(new->addr, new->addr + total);
 	return new->addr;
 
 err_out:
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 8dc7927..88ac976 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -191,7 +191,7 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
 	OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
 	OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
 	OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
-	if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
 		OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr);
 		OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr);
 	}
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
new file mode 100644
index 0000000..e98f0a2
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -0,0 +1,296 @@
+/*
+ * omap-pm-noop.c - OMAP power management interface - dummy version
+ *
+ * This code implements the OMAP power management interface to
+ * drivers, CPUIdle, CPUFreq, and DSP Bridge.  It is strictly for
+ * debug/demonstration use, as it does nothing but printk() whenever a
+ * function is called (when DEBUG is defined, below)
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
+ * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+
+/* Interface documentation is in mach/omap-pm.h */
+#include <mach/omap-pm.h>
+
+#include <mach/powerdomain.h>
+
+struct omap_opp *dsp_opps;
+struct omap_opp *mpu_opps;
+struct omap_opp *l3_opps;
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ */
+
+void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the MPU to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on the MPU and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+}
+
+void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+{
+	if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+	    agent_id != OCP_TARGET_AGENT)) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (r == 0)
+		pr_debug("OMAP PM: remove min bus tput constraint: "
+			 "dev %s for agent_id %d\n", dev_name(dev), agent_id);
+	else
+		pr_debug("OMAP PM: add min bus tput constraint: "
+			 "dev %s for agent_id %d: rate %ld KiB\n",
+			 dev_name(dev), agent_id, r);
+
+	/*
+	 * This code should model the interconnect and compute the
+	 * required clock frequency, convert that to a VDD2 OPP ID, then
+	 * set the VDD2 OPP appropriately.
+	 *
+	 * TI CDP code can call constraint_set here on the VDD2 OPP.
+	 */
+}
+
+void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max device latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max device latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux, this needs to map the device to a
+	 * powerdomain, then go through the list of current max lat
+	 * constraints on that powerdomain and find the smallest.  If
+	 * the latency constraint has changed, the code should
+	 * recompute the state to enter for the next powerdomain
+	 * state.  Conceivably, this code should also determine
+	 * whether to actually disable the device clocks or not,
+	 * depending on how long it takes to re-enable the clocks.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+}
+
+void omap_pm_set_max_sdma_lat(struct device *dev, long t)
+{
+	if (!dev || t < -1) {
+		WARN_ON(1);
+		return;
+	};
+
+	if (t == -1)
+		pr_debug("OMAP PM: remove max DMA latency constraint: "
+			 "dev %s\n", dev_name(dev));
+	else
+		pr_debug("OMAP PM: add max DMA latency constraint: "
+			 "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+	/*
+	 * For current Linux PM QOS params, this code should scan the
+	 * list of maximum CPU and DMA latencies and select the
+	 * smallest, then set cpu_dma_latency pm_qos_param
+	 * accordingly.
+	 *
+	 * For future Linux PM QOS params, with separate CPU and DMA
+	 * latency params, this code should just set the dma_latency param.
+	 *
+	 * TI CDP code can call constraint_set here.
+	 */
+
+}
+
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+const struct omap_opp *omap_pm_dsp_get_opp_table(void)
+{
+	pr_debug("OMAP PM: DSP request for OPP table\n");
+
+	/*
+	 * Return DSP frequency table here:  The final item in the
+	 * array should have .rate = .opp_id = 0.
+	 */
+
+	return NULL;
+}
+
+void omap_pm_dsp_set_min_opp(u8 opp_id)
+{
+	if (opp_id == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
+
+	/*
+	 *
+	 * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
+	 * can just test to see which is higher, the CPU's desired OPP
+	 * ID or the DSP's desired OPP ID, and use whichever is
+	 * highest.
+	 *
+	 * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
+	 * rate is keyed on MPU speed, not the OPP ID.  So we need to
+	 * map the OPP ID to the MPU speed for use with clk_set_rate()
+	 * if it is higher than the current OPP clock rate.
+	 *
+	 */
+}
+
+
+u8 omap_pm_dsp_get_opp(void)
+{
+	pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
+
+	/*
+	 * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
+	 *
+	 * CDP12.14+:
+	 * Call clk_get_rate() on the OPP custom clock, map that to an
+	 * OPP ID using the tables defined in board-*.c/chip-*.c files.
+	 */
+
+	return 0;
+}
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
+{
+	pr_debug("OMAP PM: CPUFreq request for frequency table\n");
+
+	/*
+	 * Return CPUFreq frequency table here: loop over
+	 * all VDD1 clkrates, pull out the mpu_ck frequencies, build
+	 * table
+	 */
+
+	return NULL;
+}
+
+void omap_pm_cpu_set_freq(unsigned long f)
+{
+	if (f == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
+		 f);
+
+	/*
+	 * For l-o dev tree, determine whether MPU freq or DSP OPP id
+	 * freq is higher.  Find the OPP ID corresponding to the
+	 * higher frequency.  Call clk_round_rate() and clk_set_rate()
+	 * on the OPP custom clock.
+	 *
+	 * CDP should just be able to set the VDD1 OPP clock rate here.
+	 */
+}
+
+unsigned long omap_pm_cpu_get_freq(void)
+{
+	pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
+
+	/*
+	 * Call clk_get_rate() on the mpu_ck.
+	 */
+
+	return 0;
+}
+
+/*
+ * Device context loss tracking
+ */
+
+int omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+	if (!dev) {
+		WARN_ON(1);
+		return -EINVAL;
+	};
+
+	pr_debug("OMAP PM: returning context loss count for dev %s\n",
+		 dev_name(dev));
+
+	/*
+	 * Map the device to the powerdomain.  Return the powerdomain
+	 * off counter.
+	 */
+
+	return 0;
+}
+
+
+/* Should be called before clk framework init */
+int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
+				 struct omap_opp *dsp_opp_table,
+				 struct omap_opp *l3_opp_table)
+{
+	mpu_opps = mpu_opp_table;
+	dsp_opps = dsp_opp_table;
+	l3_opps = l3_opp_table;
+	return 0;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init(void)
+{
+	return 0;
+}
+
+void omap_pm_if_exit(void)
+{
+	/* Deallocate CPUFreq frequency table here */
+}
+
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
new file mode 100644
index 0000000..2c409fc
--- /dev/null
+++ b/arch/arm/plat-omap/omap_device.c
@@ -0,0 +1,687 @@
+/*
+ * omap_device implementation
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Developed in collaboration with (alphabetical order): Benoit
+ * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram
+ * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard
+ * Woodruff
+ *
+ * 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 code provides a consistent interface for OMAP device drivers
+ * to control power management and interconnect properties of their
+ * devices.
+ *
+ * In the medium- to long-term, this code should either be
+ * a) implemented via arch-specific pointers in platform_data
+ * or
+ * b) implemented as a proper omap_bus/omap_device in Linux, no more
+ *    platform_data func pointers
+ *
+ *
+ * Guidelines for usage by driver authors:
+ *
+ * 1. These functions are intended to be used by device drivers via
+ * function pointers in struct platform_data.  As an example,
+ * omap_device_enable() should be passed to the driver as
+ *
+ * struct foo_driver_platform_data {
+ * ...
+ *      int (*device_enable)(struct platform_device *pdev);
+ * ...
+ * }
+ *
+ * Note that the generic "device_enable" name is used, rather than
+ * "omap_device_enable".  This is so other architectures can pass in their
+ * own enable/disable functions here.
+ *
+ * This should be populated during device setup:
+ *
+ * ...
+ * pdata->device_enable = omap_device_enable;
+ * ...
+ *
+ * 2. Drivers should first check to ensure the function pointer is not null
+ * before calling it, as in:
+ *
+ * if (pdata->device_enable)
+ *     pdata->device_enable(pdev);
+ *
+ * This allows other architectures that don't use similar device_enable()/
+ * device_shutdown() functions to execute normally.
+ *
+ * ...
+ *
+ * Suggested usage by device drivers:
+ *
+ * During device initialization:
+ * device_enable()
+ *
+ * During device idle:
+ * (save remaining device context if necessary)
+ * device_idle();
+ *
+ * During device resume:
+ * device_enable();
+ * (restore context if necessary)
+ *
+ * During device shutdown:
+ * device_shutdown()
+ * (device must be reinitialized at this point to use it again)
+ *
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/omap_device.h>
+#include <mach/omap_hwmod.h>
+
+/* These parameters are passed to _omap_device_{de,}activate() */
+#define USE_WAKEUP_LAT			0
+#define IGNORE_WAKEUP_LAT		1
+
+/* XXX this should be moved into a separate file */
+#if defined(CONFIG_ARCH_OMAP2420)
+# define OMAP_32KSYNCT_BASE		0x48004000
+#elif defined(CONFIG_ARCH_OMAP2430)
+# define OMAP_32KSYNCT_BASE		0x49020000
+#elif defined(CONFIG_ARCH_OMAP3430)
+# define OMAP_32KSYNCT_BASE		0x48320000
+#else
+# error Unknown OMAP device
+#endif
+
+/* Private functions */
+
+/**
+ * _read_32ksynct - read the OMAP 32K sync timer
+ *
+ * Returns the current value of the 32KiHz synchronization counter.
+ * XXX this should be generalized to simply read the system clocksource.
+ * XXX this should be moved to a separate synctimer32k.c file
+ */
+static u32 _read_32ksynct(void)
+{
+	if (!cpu_class_is_omap2())
+		BUG();
+
+	return __raw_readl(OMAP2_IO_ADDRESS(OMAP_32KSYNCT_BASE + 0x010));
+}
+
+/**
+ * _omap_device_activate - increase device readiness
+ * @od: struct omap_device *
+ * @ignore_lat: increase to latency target (0) or full readiness (1)?
+ *
+ * Increase readiness of omap_device @od (thus decreasing device
+ * wakeup latency, but consuming more power).  If @ignore_lat is
+ * IGNORE_WAKEUP_LAT, make the omap_device fully active.  Otherwise,
+ * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
+ * latency is greater than the requested maximum wakeup latency, step
+ * backwards in the omap_device_pm_latency table to ensure the
+ * device's maximum wakeup latency is less than or equal to the
+ * requested maximum wakeup latency.  Returns 0.
+ */
+static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
+{
+	u32 a, b;
+
+	pr_debug("omap_device: %s: activating\n", od->pdev.name);
+
+	while (od->pm_lat_level > 0) {
+		struct omap_device_pm_latency *odpl;
+		int act_lat = 0;
+
+		od->pm_lat_level--;
+
+		odpl = od->pm_lats + od->pm_lat_level;
+
+		if (!ignore_lat &&
+		    (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit))
+			break;
+
+		a = _read_32ksynct();
+
+		/* XXX check return code */
+		odpl->activate_func(od);
+
+		b = _read_32ksynct();
+
+		act_lat = (b - a) >> 15; /* 32KiHz cycles to microseconds */
+
+		pr_debug("omap_device: %s: pm_lat %d: activate: elapsed time "
+			 "%d usec\n", od->pdev.name, od->pm_lat_level, act_lat);
+
+		WARN(act_lat > odpl->activate_lat, "omap_device: %s.%d: "
+		     "activate step %d took longer than expected (%d > %d)\n",
+		     od->pdev.name, od->pdev.id, od->pm_lat_level,
+		     act_lat, odpl->activate_lat);
+
+		od->dev_wakeup_lat -= odpl->activate_lat;
+	}
+
+	return 0;
+}
+
+/**
+ * _omap_device_deactivate - decrease device readiness
+ * @od: struct omap_device *
+ * @ignore_lat: decrease to latency target (0) or full inactivity (1)?
+ *
+ * Decrease readiness of omap_device @od (thus increasing device
+ * wakeup latency, but conserving power).  If @ignore_lat is
+ * IGNORE_WAKEUP_LAT, make the omap_device fully inactive.  Otherwise,
+ * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
+ * latency is less than the requested maximum wakeup latency, step
+ * forwards in the omap_device_pm_latency table to ensure the device's
+ * maximum wakeup latency is less than or equal to the requested
+ * maximum wakeup latency.  Returns 0.
+ */
+static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
+{
+	u32 a, b;
+
+	pr_debug("omap_device: %s: deactivating\n", od->pdev.name);
+
+	while (od->pm_lat_level < od->pm_lats_cnt) {
+		struct omap_device_pm_latency *odpl;
+		int deact_lat = 0;
+
+		odpl = od->pm_lats + od->pm_lat_level;
+
+		if (!ignore_lat &&
+		    ((od->dev_wakeup_lat + odpl->activate_lat) >
+		     od->_dev_wakeup_lat_limit))
+			break;
+
+		a = _read_32ksynct();
+
+		/* XXX check return code */
+		odpl->deactivate_func(od);
+
+		b = _read_32ksynct();
+
+		deact_lat = (b - a) >> 15; /* 32KiHz cycles to microseconds */
+
+		pr_debug("omap_device: %s: pm_lat %d: deactivate: elapsed time "
+			 "%d usec\n", od->pdev.name, od->pm_lat_level,
+			 deact_lat);
+
+		WARN(deact_lat > odpl->deactivate_lat, "omap_device: %s.%d: "
+		     "deactivate step %d took longer than expected (%d > %d)\n",
+		     od->pdev.name, od->pdev.id, od->pm_lat_level,
+		     deact_lat, odpl->deactivate_lat);
+
+		od->dev_wakeup_lat += odpl->activate_lat;
+
+		od->pm_lat_level++;
+	}
+
+	return 0;
+}
+
+static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
+{
+	return container_of(pdev, struct omap_device, pdev);
+}
+
+
+/* Public functions for use by core code */
+
+/**
+ * omap_device_count_resources - count number of struct resource entries needed
+ * @od: struct omap_device *
+ *
+ * Count the number of struct resource entries needed for this
+ * omap_device @od.  Used by omap_device_build_ss() to determine how
+ * much memory to allocate before calling
+ * omap_device_fill_resources().  Returns the count.
+ */
+int omap_device_count_resources(struct omap_device *od)
+{
+	struct omap_hwmod *oh;
+	int c = 0;
+	int i;
+
+	for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
+		c += omap_hwmod_count_resources(oh);
+
+	pr_debug("omap_device: %s: counted %d total resources across %d "
+		 "hwmods\n", od->pdev.name, c, od->hwmods_cnt);
+
+	return c;
+}
+
+/**
+ * omap_device_fill_resources - fill in array of struct resource
+ * @od: struct omap_device *
+ * @res: pointer to an array of struct resource to be filled in
+ *
+ * Populate one or more empty struct resource pointed to by @res with
+ * the resource data for this omap_device @od.  Used by
+ * omap_device_build_ss() after calling omap_device_count_resources().
+ * Ideally this function would not be needed at all.  If omap_device
+ * replaces platform_device, then we can specify our own
+ * get_resource()/ get_irq()/etc functions that use the underlying
+ * omap_hwmod information.  Or if platform_device is extended to use
+ * subarchitecture-specific function pointers, the various
+ * platform_device functions can simply call omap_device internal
+ * functions to get device resources.  Hacking around the existing
+ * platform_device code wastes memory.  Returns 0.
+ */
+int omap_device_fill_resources(struct omap_device *od, struct resource *res)
+{
+	struct omap_hwmod *oh;
+	int c = 0;
+	int i, r;
+
+	for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++) {
+		r = omap_hwmod_fill_resources(oh, res);
+		res += r;
+		c += r;
+	}
+
+	return 0;
+}
+
+/**
+ * omap_device_build - build and register an omap_device with one omap_hwmod
+ * @pdev_name: name of the platform_device driver to use
+ * @pdev_id: this platform_device's connection ID
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ *
+ * Convenience function for building and registering a single
+ * omap_device record, which in turn builds and registers a
+ * platform_device record.  See omap_device_build_ss() for more
+ * information.  Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise,
+ * passes along the return value of omap_device_build_ss().
+ */
+struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
+				      struct omap_hwmod *oh, void *pdata,
+				      int pdata_len,
+				      struct omap_device_pm_latency *pm_lats,
+				      int pm_lats_cnt)
+{
+	struct omap_hwmod *ohs[] = { oh };
+
+	if (!oh)
+		return ERR_PTR(-EINVAL);
+
+	return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata,
+				    pdata_len, pm_lats, pm_lats_cnt);
+}
+
+/**
+ * omap_device_build_ss - build and register an omap_device with multiple hwmods
+ * @pdev_name: name of the platform_device driver to use
+ * @pdev_id: this platform_device's connection ID
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ *
+ * Convenience function for building and registering an omap_device
+ * subsystem record.  Subsystem records consist of multiple
+ * omap_hwmods.  This function in turn builds and registers a
+ * platform_device record.  Returns an ERR_PTR() on error, or passes
+ * along the return value of omap_device_register().
+ */
+struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+					 struct omap_hwmod **ohs, int oh_cnt,
+					 void *pdata, int pdata_len,
+					 struct omap_device_pm_latency *pm_lats,
+					 int pm_lats_cnt)
+{
+	int ret = -ENOMEM;
+	struct omap_device *od;
+	char *pdev_name2;
+	struct resource *res = NULL;
+	int res_count;
+	struct omap_hwmod **hwmods;
+
+	if (!ohs || oh_cnt == 0 || !pdev_name)
+		return ERR_PTR(-EINVAL);
+
+	if (!pdata && pdata_len > 0)
+		return ERR_PTR(-EINVAL);
+
+	pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name,
+		 oh_cnt);
+
+	od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
+	if (!od)
+		return ERR_PTR(-ENOMEM);
+
+	od->hwmods_cnt = oh_cnt;
+
+	hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt,
+			 GFP_KERNEL);
+	if (!hwmods)
+		goto odbs_exit1;
+
+	memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt);
+	od->hwmods = hwmods;
+
+	pdev_name2 = kzalloc(strlen(pdev_name) + 1, GFP_KERNEL);
+	if (!pdev_name2)
+		goto odbs_exit2;
+	strcpy(pdev_name2, pdev_name);
+
+	od->pdev.name = pdev_name2;
+	od->pdev.id = pdev_id;
+
+	res_count = omap_device_count_resources(od);
+	if (res_count > 0) {
+		res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+		if (!res)
+			goto odbs_exit3;
+	}
+	omap_device_fill_resources(od, res);
+
+	od->pdev.num_resources = res_count;
+	od->pdev.resource = res;
+
+	platform_device_add_data(&od->pdev, pdata, pdata_len);
+
+	od->pm_lats = pm_lats;
+	od->pm_lats_cnt = pm_lats_cnt;
+
+	ret = omap_device_register(od);
+	if (ret)
+		goto odbs_exit4;
+
+	return od;
+
+odbs_exit4:
+	kfree(res);
+odbs_exit3:
+	kfree(pdev_name2);
+odbs_exit2:
+	kfree(hwmods);
+odbs_exit1:
+	kfree(od);
+
+	pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret);
+
+	return ERR_PTR(ret);
+}
+
+/**
+ * omap_device_register - register an omap_device with one omap_hwmod
+ * @od: struct omap_device * to register
+ *
+ * Register the omap_device structure.  This currently just calls
+ * platform_device_register() on the underlying platform_device.
+ * Returns the return value of platform_device_register().
+ */
+int omap_device_register(struct omap_device *od)
+{
+	pr_debug("omap_device: %s: registering\n", od->pdev.name);
+
+	return platform_device_register(&od->pdev);
+}
+
+
+/* Public functions for use by device drivers through struct platform_data */
+
+/**
+ * omap_device_enable - fully activate an omap_device
+ * @od: struct omap_device * to activate
+ *
+ * Do whatever is necessary for the hwmods underlying omap_device @od
+ * to be accessible and ready to operate.  This generally involves
+ * enabling clocks, setting SYSCONFIG registers; and in the future may
+ * involve remuxing pins.  Device drivers should call this function
+ * (through platform_data function pointers) where they would normally
+ * enable clocks, etc.  Returns -EINVAL if called when the omap_device
+ * is already enabled, or passes along the return value of
+ * _omap_device_activate().
+ */
+int omap_device_enable(struct platform_device *pdev)
+{
+	int ret;
+	struct omap_device *od;
+
+	od = _find_by_pdev(pdev);
+
+	if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+		WARN(1, "omap_device: %s.%d: omap_device_enable() called from "
+		     "invalid state\n", od->pdev.name, od->pdev.id);
+		return -EINVAL;
+	}
+
+	/* Enable everything if we're enabling this device from scratch */
+	if (od->_state == OMAP_DEVICE_STATE_UNKNOWN)
+		od->pm_lat_level = od->pm_lats_cnt;
+
+	ret = _omap_device_activate(od, IGNORE_WAKEUP_LAT);
+
+	od->dev_wakeup_lat = 0;
+	od->_dev_wakeup_lat_limit = INT_MAX;
+	od->_state = OMAP_DEVICE_STATE_ENABLED;
+
+	return ret;
+}
+
+/**
+ * omap_device_idle - idle an omap_device
+ * @od: struct omap_device * to idle
+ *
+ * Idle omap_device @od by calling as many .deactivate_func() entries
+ * in the omap_device's pm_lats table as is possible without exceeding
+ * the device's maximum wakeup latency limit, pm_lat_limit.  Device
+ * drivers should call this function (through platform_data function
+ * pointers) where they would normally disable clocks after operations
+ * complete, etc..  Returns -EINVAL if the omap_device is not
+ * currently enabled, or passes along the return value of
+ * _omap_device_deactivate().
+ */
+int omap_device_idle(struct platform_device *pdev)
+{
+	int ret;
+	struct omap_device *od;
+
+	od = _find_by_pdev(pdev);
+
+	if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
+		WARN(1, "omap_device: %s.%d: omap_device_idle() called from "
+		     "invalid state\n", od->pdev.name, od->pdev.id);
+		return -EINVAL;
+	}
+
+	ret = _omap_device_deactivate(od, USE_WAKEUP_LAT);
+
+	od->_state = OMAP_DEVICE_STATE_IDLE;
+
+	return ret;
+}
+
+/**
+ * omap_device_shutdown - shut down an omap_device
+ * @od: struct omap_device * to shut down
+ *
+ * Shut down omap_device @od by calling all .deactivate_func() entries
+ * in the omap_device's pm_lats table and then shutting down all of
+ * the underlying omap_hwmods.  Used when a device is being "removed"
+ * or a device driver is being unloaded.  Returns -EINVAL if the
+ * omap_device is not currently enabled or idle, or passes along the
+ * return value of _omap_device_deactivate().
+ */
+int omap_device_shutdown(struct platform_device *pdev)
+{
+	int ret, i;
+	struct omap_device *od;
+	struct omap_hwmod *oh;
+
+	od = _find_by_pdev(pdev);
+
+	if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
+	    od->_state != OMAP_DEVICE_STATE_IDLE) {
+		WARN(1, "omap_device: %s.%d: omap_device_shutdown() called "
+		     "from invalid state\n", od->pdev.name, od->pdev.id);
+		return -EINVAL;
+	}
+
+	ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT);
+
+	for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
+		omap_hwmod_shutdown(oh);
+
+	od->_state = OMAP_DEVICE_STATE_SHUTDOWN;
+
+	return ret;
+}
+
+/**
+ * omap_device_align_pm_lat - activate/deactivate device to match wakeup lat lim
+ * @od: struct omap_device *
+ *
+ * When a device's maximum wakeup latency limit changes, call some of
+ * the .activate_func or .deactivate_func function pointers in the
+ * omap_device's pm_lats array to ensure that the device's maximum
+ * wakeup latency is less than or equal to the new latency limit.
+ * Intended to be called by OMAP PM code whenever a device's maximum
+ * wakeup latency limit changes (e.g., via
+ * omap_pm_set_dev_wakeup_lat()).  Returns 0 if nothing needs to be
+ * done (e.g., if the omap_device is not currently idle, or if the
+ * wakeup latency is already current with the new limit) or passes
+ * along the return value of _omap_device_deactivate() or
+ * _omap_device_activate().
+ */
+int omap_device_align_pm_lat(struct platform_device *pdev,
+			     u32 new_wakeup_lat_limit)
+{
+	int ret = -EINVAL;
+	struct omap_device *od;
+
+	od = _find_by_pdev(pdev);
+
+	if (new_wakeup_lat_limit == od->dev_wakeup_lat)
+		return 0;
+
+	od->_dev_wakeup_lat_limit = new_wakeup_lat_limit;
+
+	if (od->_state != OMAP_DEVICE_STATE_IDLE)
+		return 0;
+	else if (new_wakeup_lat_limit > od->dev_wakeup_lat)
+		ret = _omap_device_deactivate(od, USE_WAKEUP_LAT);
+	else if (new_wakeup_lat_limit < od->dev_wakeup_lat)
+		ret = _omap_device_activate(od, USE_WAKEUP_LAT);
+
+	return ret;
+}
+
+/**
+ * omap_device_get_pwrdm - return the powerdomain * associated with @od
+ * @od: struct omap_device *
+ *
+ * Return the powerdomain associated with the first underlying
+ * omap_hwmod for this omap_device.  Intended for use by core OMAP PM
+ * code.  Returns NULL on error or a struct powerdomain * upon
+ * success.
+ */
+struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
+{
+	/*
+	 * XXX Assumes that all omap_hwmod powerdomains are identical.
+	 * This may not necessarily be true.  There should be a sanity
+	 * check in here to WARN() if any difference appears.
+	 */
+	if (!od->hwmods_cnt)
+		return NULL;
+
+	return omap_hwmod_get_pwrdm(od->hwmods[0]);
+}
+
+/*
+ * Public functions intended for use in omap_device_pm_latency
+ * .activate_func and .deactivate_func function pointers
+ */
+
+/**
+ * omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods
+ * @od: struct omap_device *od
+ *
+ * Enable all underlying hwmods.  Returns 0.
+ */
+int omap_device_enable_hwmods(struct omap_device *od)
+{
+	struct omap_hwmod *oh;
+	int i;
+
+	for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
+		omap_hwmod_enable(oh);
+
+	/* XXX pass along return value here? */
+	return 0;
+}
+
+/**
+ * omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods
+ * @od: struct omap_device *od
+ *
+ * Idle all underlying hwmods.  Returns 0.
+ */
+int omap_device_idle_hwmods(struct omap_device *od)
+{
+	struct omap_hwmod *oh;
+	int i;
+
+	for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
+		omap_hwmod_idle(oh);
+
+	/* XXX pass along return value here? */
+	return 0;
+}
+
+/**
+ * omap_device_disable_clocks - disable all main and interface clocks
+ * @od: struct omap_device *od
+ *
+ * Disable the main functional clock and interface clock for all of the
+ * omap_hwmods associated with the omap_device.  Returns 0.
+ */
+int omap_device_disable_clocks(struct omap_device *od)
+{
+	struct omap_hwmod *oh;
+	int i;
+
+	for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
+		omap_hwmod_disable_clocks(oh);
+
+	/* XXX pass along return value here? */
+	return 0;
+}
+
+/**
+ * omap_device_enable_clocks - enable all main and interface clocks
+ * @od: struct omap_device *od
+ *
+ * Enable the main functional clock and interface clock for all of the
+ * omap_hwmods associated with the omap_device.  Returns 0.
+ */
+int omap_device_enable_clocks(struct omap_device *od)
+{
+	struct omap_hwmod *oh;
+	int i;
+
+	for (i = 0, oh = *od->hwmods; i < od->hwmods_cnt; i++, oh++)
+		omap_hwmod_enable_clocks(oh);
+
+	/* XXX pass along return value here? */
+	return 0;
+}
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 5eae787..925f647 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -56,16 +56,16 @@
 #define SRAM_BOOTLOADER_SZ	0x80
 #endif
 
-#define OMAP24XX_VA_REQINFOPERM0	IO_ADDRESS(0x68005048)
-#define OMAP24XX_VA_READPERM0		IO_ADDRESS(0x68005050)
-#define OMAP24XX_VA_WRITEPERM0		IO_ADDRESS(0x68005058)
-
-#define OMAP34XX_VA_REQINFOPERM0	IO_ADDRESS(0x68012848)
-#define OMAP34XX_VA_READPERM0		IO_ADDRESS(0x68012850)
-#define OMAP34XX_VA_WRITEPERM0		IO_ADDRESS(0x68012858)
-#define OMAP34XX_VA_ADDR_MATCH2		IO_ADDRESS(0x68012880)
-#define OMAP34XX_VA_SMS_RG_ATT0		IO_ADDRESS(0x6C000048)
-#define OMAP34XX_VA_CONTROL_STAT	IO_ADDRESS(0x480022F0)
+#define OMAP24XX_VA_REQINFOPERM0	OMAP2_IO_ADDRESS(0x68005048)
+#define OMAP24XX_VA_READPERM0		OMAP2_IO_ADDRESS(0x68005050)
+#define OMAP24XX_VA_WRITEPERM0		OMAP2_IO_ADDRESS(0x68005058)
+
+#define OMAP34XX_VA_REQINFOPERM0	OMAP2_IO_ADDRESS(0x68012848)
+#define OMAP34XX_VA_READPERM0		OMAP2_IO_ADDRESS(0x68012850)
+#define OMAP34XX_VA_WRITEPERM0		OMAP2_IO_ADDRESS(0x68012858)
+#define OMAP34XX_VA_ADDR_MATCH2		OMAP2_IO_ADDRESS(0x68012880)
+#define OMAP34XX_VA_SMS_RG_ATT0		OMAP2_IO_ADDRESS(0x6C000048)
+#define OMAP34XX_VA_CONTROL_STAT	OMAP2_IO_ADDRESS(0x480022F0)
 
 #define GP_DEVICE		0x300
 
diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig
index 935c755..8931c5f 100644
--- a/arch/arm/plat-s3c/Kconfig
+++ b/arch/arm/plat-s3c/Kconfig
@@ -198,4 +198,9 @@ config S3C_DEV_USB_HSOTG
 	help
 	  Compile in platform device definition for USB high-speed OtG
 
+config S3C_DEV_NAND
+	bool
+	help
+	  Compile in platform device definition for NAND controller
+
 endif
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
index 0761766..3c09109 100644
--- a/arch/arm/plat-s3c/Makefile
+++ b/arch/arm/plat-s3c/Makefile
@@ -28,13 +28,17 @@ obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_PM)		+= pm-gpio.o
 obj-$(CONFIG_S3C2410_PM_CHECK)	+= pm-check.o
 
+# PWM support
+
+obj-$(CONFIG_HAVE_PWM)		+= pwm.o
+
 # devices
 
 obj-$(CONFIG_S3C_DEV_HSMMC)	+= dev-hsmmc.o
 obj-$(CONFIG_S3C_DEV_HSMMC1)	+= dev-hsmmc1.o
 obj-y				+= dev-i2c0.o
 obj-$(CONFIG_S3C_DEV_I2C1)	+= dev-i2c1.o
-obj-$(CONFIG_SND_S3C64XX_SOC_I2S)	+= dev-audio.o
 obj-$(CONFIG_S3C_DEV_FB)	+= dev-fb.o
 obj-$(CONFIG_S3C_DEV_USB_HOST)	+= dev-usb.o
 obj-$(CONFIG_S3C_DEV_USB_HSOTG)	+= dev-usb-hsotg.o
+obj-$(CONFIG_S3C_DEV_NAND)	+= dev-nand.o
diff --git a/arch/arm/plat-s3c/dev-audio.c b/arch/arm/plat-s3c/dev-audio.c
deleted file mode 100644
index 1322beb..0000000
--- a/arch/arm/plat-s3c/dev-audio.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/* linux/arch/arm/plat-s3c/dev-audio.c
- *
- * Copyright 2009 Wolfson Microelectronics
- *      Mark Brown <broonie@opensource.wolfsonmicro.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/kernel.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include <mach/map.h>
-
-#include <plat/devs.h>
-
-
-static struct resource s3c64xx_iis0_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_IIS0,
-		.end   = S3C64XX_PA_IIS0 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device s3c64xx_device_iis0 = {
-	.name		  = "s3c64xx-iis",
-	.id		  = 0,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_iis0_resource),
-	.resource	  = s3c64xx_iis0_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iis0);
-
-static struct resource s3c64xx_iis1_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_IIS1,
-		.end   = S3C64XX_PA_IIS1 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device s3c64xx_device_iis1 = {
-	.name		  = "s3c64xx-iis",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_iis1_resource),
-	.resource	  = s3c64xx_iis1_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iis1);
-
-static struct resource s3c64xx_iisv4_resource[] = {
-	[0] = {
-		.start = S3C64XX_PA_IISV4,
-		.end   = S3C64XX_PA_IISV4 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device s3c64xx_device_iisv4 = {
-	.name		  = "s3c64xx-iis-v4",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c64xx_iisv4_resource),
-	.resource	  = s3c64xx_iisv4_resource,
-};
-EXPORT_SYMBOL(s3c64xx_device_iisv4);
diff --git a/arch/arm/plat-s3c/dev-nand.c b/arch/arm/plat-s3c/dev-nand.c
new file mode 100644
index 0000000..4e53237
--- /dev/null
+++ b/arch/arm/plat-s3c/dev-nand.c
@@ -0,0 +1,30 @@
+/*
+ * S3C series device definition for nand device
+ *
+ * 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/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+
+static struct resource s3c_nand_resource[] = {
+	[0] = {
+		.start = S3C_PA_NAND,
+		.end   = S3C_PA_NAND + SZ_1M,
+		.flags = IORESOURCE_MEM,
+	}
+};
+
+struct platform_device s3c_device_nand = {
+	.name		  = "s3c2410-nand",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c_nand_resource),
+	.resource	  = s3c_nand_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_nand);
diff --git a/arch/arm/plat-s3c/include/plat/adc.h b/arch/arm/plat-s3c/include/plat/adc.h
index d847bd4..5f3b1cd 100644
--- a/arch/arm/plat-s3c/include/plat/adc.h
+++ b/arch/arm/plat-s3c/include/plat/adc.h
@@ -19,10 +19,14 @@ struct s3c_adc_client;
 extern int s3c_adc_start(struct s3c_adc_client *client,
 			 unsigned int channel, unsigned int nr_samples);
 
+extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
+
 extern struct s3c_adc_client *
 	s3c_adc_register(struct platform_device *pdev,
-			 void (*select)(unsigned selected),
-			 void (*conv)(unsigned d0, unsigned d1,
+			 void (*select)(struct s3c_adc_client *client,
+					unsigned selected),
+			 void (*conv)(struct s3c_adc_client *client,
+				      unsigned d0, unsigned d1,
 				      unsigned *samples_left),
 			 unsigned int is_ts);
 
diff --git a/arch/arm/plat-s3c/include/plat/cpu-freq.h b/arch/arm/plat-s3c/include/plat/cpu-freq.h
index c86a133..7b982b7 100644
--- a/arch/arm/plat-s3c/include/plat/cpu-freq.h
+++ b/arch/arm/plat-s3c/include/plat/cpu-freq.h
@@ -17,6 +17,21 @@ struct s3c_cpufreq_info;
 struct s3c_cpufreq_board;
 struct s3c_iotimings;
 
+/**
+ * struct s3c_freq - frequency information (mainly for core drivers)
+ * @fclk: The FCLK frequency in Hz.
+ * @armclk: The ARMCLK frequency in Hz.
+ * @hclk_tns: HCLK cycle time in 10ths of nano-seconds.
+ * @hclk: The HCLK frequency in Hz.
+ * @pclk: The PCLK frequency in Hz.
+ *
+ * This contains the frequency information about the current configuration
+ * mainly for the core drivers to ensure we do not end up passing about
+ * a large number of parameters.
+ *
+ * The @hclk_tns field is a useful cache for the parts of the drivers that
+ * need to calculate IO timings and suchlike.
+ */
 struct s3c_freq {
 	unsigned long	fclk;
 	unsigned long	armclk;
@@ -25,48 +40,84 @@ struct s3c_freq {
 	unsigned long	pclk;
 };
 
-/* wrapper 'struct cpufreq_freqs' so that any drivers receiving the
+/**
+ * struct s3c_cpufreq_freqs - s3c cpufreq notification information.
+ * @freqs: The cpufreq setting information.
+ * @old: The old clock settings.
+ * @new: The new clock settings.
+ * @pll_changing: Set if the PLL is changing.
+ *
+ * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the
  * notification can use this information that is not provided by just
  * having the core frequency alone.
+ *
+ * The pll_changing flag is used to indicate if the PLL itself is
+ * being set during this change. This is important as the clocks
+ * will temporarily be set to the XTAL clock during this time, so
+ * drivers may want to close down their output during this time.
+ *
+ * Note, this is not being used by any current drivers and therefore
+ * may be removed in the future.
  */
-
 struct s3c_cpufreq_freqs {
 	struct cpufreq_freqs	freqs;
 	struct s3c_freq		old;
 	struct s3c_freq		new;
+
+	unsigned int		pll_changing:1;
 };
 
 #define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs)
 
+/**
+ * struct s3c_clkdivs - clock divisor information
+ * @p_divisor: Divisor from FCLK to PCLK.
+ * @h_divisor: Divisor from FCLK to HCLK.
+ * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs).
+ * @dvs: Non-zero if using DVS mode for ARMCLK.
+ *
+ * Divisor settings for the core clocks.
+ */
 struct s3c_clkdivs {
-	int		p_divisor;	/* fclk / pclk */
-	int		h_divisor;	/* fclk / hclk */
-	int		arm_divisor;	/* not all cpus have this. */
-	unsigned char	dvs;		/* using dvs mode to arm. */
+	int		p_divisor;
+	int		h_divisor;
+	int		arm_divisor;
+	unsigned char	dvs;
 };
 
 #define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s))
 
+/**
+ * struct s3c_pllval - PLL value entry.
+ * @freq: The frequency for this entry in Hz.
+ * @pll_reg: The PLL register setting for this PLL value.
+ */
 struct s3c_pllval {
 	unsigned long		freq;
 	unsigned long		pll_reg;
 };
 
-struct s3c_cpufreq_config {
-	struct s3c_freq		freq;
-	struct s3c_pllval	pll;
-	struct s3c_clkdivs	divs;
-	struct s3c_cpufreq_info *info;	/* for core, not drivers */
-	struct s3c_cpufreq_board *board;
-};
-
-/* s3c_cpufreq_board
+/**
+ * struct s3c_cpufreq_board - per-board cpu frequency informatin
+ * @refresh: The SDRAM refresh period in nanoseconds.
+ * @auto_io: Set if the IO timing settings should be generated from the
+ *	initialisation time hardware registers.
+ * @need_io: Set if the board has external IO on any of the chipselect
+ *	lines that will require the hardware timing registers to be
+ *	updated on a clock change.
+ * @max: The maxium frequency limits for the system. Any field that
+ *	is left at zero will use the CPU's settings.
+ *
+ * This contains the board specific settings that affect how the CPU
+ * drivers chose settings. These include the memory refresh and IO
+ * timing information.
  *
- * per-board configuraton information, such as memory refresh and
- * how to initialise IO timings.
+ * Registration depends on the driver being used, the ARMCLK only
+ * implementation does not currently need this but the older style
+ * driver requires this to be available.
  */
 struct s3c_cpufreq_board {
-	unsigned int	refresh;	/* refresh period in ns */
+	unsigned int	refresh;
 	unsigned int	auto_io:1;	/* automatically init io timings. */
 	unsigned int	need_io:1;	/* set if needs io timing support. */
 
diff --git a/arch/arm/plat-s3c/include/plat/cpu.h b/arch/arm/plat-s3c/include/plat/cpu.h
index be541cb..fbc3d49 100644
--- a/arch/arm/plat-s3c/include/plat/cpu.h
+++ b/arch/arm/plat-s3c/include/plat/cpu.h
@@ -65,6 +65,7 @@ extern struct sys_timer s3c24xx_timer;
 /* system device classes */
 
 extern struct sysdev_class s3c2410_sysclass;
+extern struct sysdev_class s3c2410a_sysclass;
 extern struct sysdev_class s3c2412_sysclass;
 extern struct sysdev_class s3c2440_sysclass;
 extern struct sysdev_class s3c2442_sysclass;
diff --git a/arch/arm/plat-s3c/include/plat/devs.h b/arch/arm/plat-s3c/include/plat/devs.h
index 2e17082..0f540ea 100644
--- a/arch/arm/plat-s3c/include/plat/devs.h
+++ b/arch/arm/plat-s3c/include/plat/devs.h
@@ -46,6 +46,8 @@ extern struct platform_device s3c_device_hsmmc2;
 extern struct platform_device s3c_device_spi0;
 extern struct platform_device s3c_device_spi1;
 
+extern struct platform_device s3c_device_hwmon;
+
 extern struct platform_device s3c_device_nand;
 
 extern struct platform_device s3c_device_usbgadget;
@@ -56,5 +58,6 @@ extern struct platform_device s3c_device_usb_hsotg;
 #ifdef CONFIG_CPU_S3C2440
 
 extern struct platform_device s3c_device_camif;
+extern struct platform_device s3c_device_ac97;
 
 #endif
diff --git a/arch/arm/plat-s3c/include/plat/hwmon.h b/arch/arm/plat-s3c/include/plat/hwmon.h
new file mode 100644
index 0000000..1ba88ea
--- /dev/null
+++ b/arch/arm/plat-s3c/include/plat/hwmon.h
@@ -0,0 +1,41 @@
+/* linux/arch/arm/plat-s3c/include/plat/hwmon.h
+ *
+ * Copyright 2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * S3C - HWMon interface for ADC
+ *
+ * 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 __ASM_ARCH_ADC_HWMON_H
+#define __ASM_ARCH_ADC_HWMON_H __FILE__
+
+/**
+ * s3c_hwmon_chcfg - channel configuration
+ * @name: The name to give this channel.
+ * @mult: Multiply the ADC value read by this.
+ * @div: Divide the value from the ADC by this.
+ *
+ * The value read from the ADC is converted to a value that
+ * hwmon expects (mV) by result = (value_read * @mult) / @div.
+ */
+struct s3c_hwmon_chcfg {
+	const char	*name;
+	unsigned int	mult;
+	unsigned int	div;
+};
+
+/**
+ * s3c_hwmon_pdata - HWMON platform data
+ * @in: One configuration for each possible channel used.
+ */
+struct s3c_hwmon_pdata {
+	struct s3c_hwmon_chcfg	*in[8];
+};
+
+#endif /* __ASM_ARCH_ADC_HWMON_H */
+
diff --git a/arch/arm/plat-s3c/include/plat/map-base.h b/arch/arm/plat-s3c/include/plat/map-base.h
index b84289d..250be31 100644
--- a/arch/arm/plat-s3c/include/plat/map-base.h
+++ b/arch/arm/plat-s3c/include/plat/map-base.h
@@ -32,9 +32,15 @@
 
 #define S3C_VA_IRQ	S3C_ADDR(0x00000000)	/* irq controller(s) */
 #define S3C_VA_SYS	S3C_ADDR(0x00100000)	/* system control */
-#define S3C_VA_MEM	S3C_ADDR(0x00200000)	/* system control */
+#define S3C_VA_MEM	S3C_ADDR(0x00200000)	/* memory control */
 #define S3C_VA_TIMER	S3C_ADDR(0x00300000)	/* timer block */
 #define S3C_VA_WATCHDOG	S3C_ADDR(0x00400000)	/* watchdog */
 #define S3C_VA_UART	S3C_ADDR(0x01000000)	/* UART */
 
+/* This is used for the CPU specific mappings that may be needed, so that
+ * they do not need to directly used S3C_ADDR() and thus make it easier to
+ * modify the space for mapping.
+ */
+#define S3C_ADDR_CPU(x)	S3C_ADDR(0x00500000 + (x))
+
 #endif /* __ASM_PLAT_MAP_H */
diff --git a/arch/arm/plat-s3c/pwm.c b/arch/arm/plat-s3c/pwm.c
new file mode 100644
index 0000000..4fdc5b3
--- /dev/null
+++ b/arch/arm/plat-s3c/pwm.c
@@ -0,0 +1,410 @@
+/* arch/arm/plat-s3c/pwm.c
+ *
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * S3C series PWM device core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
+
+struct pwm_device {
+	struct list_head	 list;
+	struct platform_device	*pdev;
+
+	struct clk		*clk_div;
+	struct clk		*clk;
+	const char		*label;
+
+	unsigned int		 period_ns;
+	unsigned int		 duty_ns;
+
+	unsigned char		 tcon_base;
+	unsigned char		 running;
+	unsigned char		 use_count;
+	unsigned char		 pwm_id;
+};
+
+#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
+
+static struct clk *clk_scaler[2];
+
+/* Standard setup for a timer block. */
+
+#define TIMER_RESOURCE_SIZE (1)
+
+#define TIMER_RESOURCE(_tmr, _irq)			\
+	(struct resource [TIMER_RESOURCE_SIZE]) {	\
+		[0] = {					\
+			.start	= _irq,			\
+			.end	= _irq,			\
+			.flags	= IORESOURCE_IRQ	\
+		}					\
+	}
+
+#define DEFINE_S3C_TIMER(_tmr_no, _irq)			\
+	.name		= "s3c24xx-pwm",		\
+	.id		= _tmr_no,			\
+	.num_resources	= TIMER_RESOURCE_SIZE,		\
+	.resource	= TIMER_RESOURCE(_tmr_no, _irq),	\
+
+/* since we already have an static mapping for the timer, we do not
+ * bother setting any IO resource for the base.
+ */
+
+struct platform_device s3c_device_timer[] = {
+	[0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
+	[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
+	[2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
+	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
+	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
+};
+
+static inline int pwm_is_tdiv(struct pwm_device *pwm)
+{
+	return clk_get_parent(pwm->clk) == pwm->clk_div;
+}
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+	struct pwm_device *pwm;
+	int found = 0;
+
+	mutex_lock(&pwm_lock);
+
+	list_for_each_entry(pwm, &pwm_list, list) {
+		if (pwm->pwm_id == pwm_id) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		if (pwm->use_count == 0) {
+			pwm->use_count = 1;
+			pwm->label = label;
+		} else
+			pwm = ERR_PTR(-EBUSY);
+	} else
+		pwm = ERR_PTR(-ENOENT);
+
+	mutex_unlock(&pwm_lock);
+	return pwm;
+}
+
+EXPORT_SYMBOL(pwm_request);
+
+
+void pwm_free(struct pwm_device *pwm)
+{
+	mutex_lock(&pwm_lock);
+
+	if (pwm->use_count) {
+		pwm->use_count--;
+		pwm->label = NULL;
+	} else
+		printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
+
+	mutex_unlock(&pwm_lock);
+}
+
+EXPORT_SYMBOL(pwm_free);
+
+#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
+#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
+#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
+#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
+
+int pwm_enable(struct pwm_device *pwm)
+{
+	unsigned long flags;
+	unsigned long tcon;
+
+	local_irq_save(flags);
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon |= pwm_tcon_start(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+	pwm->running = 1;
+	return 0;
+}
+
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+	unsigned long flags;
+	unsigned long tcon;
+
+	local_irq_save(flags);
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon &= ~pwm_tcon_start(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+	pwm->running = 0;
+}
+
+EXPORT_SYMBOL(pwm_disable);
+
+static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
+{
+	unsigned long tin_parent_rate;
+	unsigned int div;
+
+	tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
+	pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
+
+	for (div = 2; div <= 16; div *= 2) {
+		if ((tin_parent_rate / (div << 16)) < freq)
+			return tin_parent_rate / div;
+	}
+
+	return tin_parent_rate / 16;
+}
+
+#define NS_IN_HZ (1000000000UL)
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	unsigned long tin_rate;
+	unsigned long tin_ns;
+	unsigned long period;
+	unsigned long flags;
+	unsigned long tcon;
+	unsigned long tcnt;
+	long tcmp;
+
+	/* We currently avoid using 64bit arithmetic by using the
+	 * fact that anything faster than 1Hz is easily representable
+	 * by 32bits. */
+
+	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+		return -ERANGE;
+
+	if (duty_ns > period_ns)
+		return -EINVAL;
+
+	if (period_ns == pwm->period_ns &&
+	    duty_ns == pwm->duty_ns)
+		return 0;
+
+	/* The TCMP and TCNT can be read without a lock, they're not
+	 * shared between the timers. */
+
+	tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
+	tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
+
+	period = NS_IN_HZ / period_ns;
+
+	pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
+		duty_ns, period_ns, period);
+
+	/* Check to see if we are changing the clock rate of the PWM */
+
+	if (pwm->period_ns != period_ns) {
+		if (pwm_is_tdiv(pwm)) {
+			tin_rate = pwm_calc_tin(pwm, period);
+			clk_set_rate(pwm->clk_div, tin_rate);
+		} else
+			tin_rate = clk_get_rate(pwm->clk);
+
+		pwm->period_ns = period_ns;
+
+		pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
+
+		tin_ns = NS_IN_HZ / tin_rate;
+		tcnt = period_ns / tin_ns;
+	} else
+		tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
+
+	/* Note, counters count down */
+
+	tcmp = duty_ns / tin_ns;
+	tcmp = tcnt - tcmp;
+	/* the pwm hw only checks the compare register after a decrement,
+	   so the pin never toggles if tcmp = tcnt */
+	if (tcmp == tcnt)
+		tcmp--;
+
+	pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
+
+	if (tcmp < 0)
+		tcmp = 0;
+
+	/* Update the PWM register block. */
+
+	local_irq_save(flags);
+
+	__raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
+	__raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon |= pwm_tcon_manulupdate(pwm);
+	tcon |= pwm_tcon_autoreload(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	tcon &= ~pwm_tcon_manulupdate(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(pwm_config);
+
+static int pwm_register(struct pwm_device *pwm)
+{
+	pwm->duty_ns = -1;
+	pwm->period_ns = -1;
+
+	mutex_lock(&pwm_lock);
+	list_add_tail(&pwm->list, &pwm_list);
+	mutex_unlock(&pwm_lock);
+
+	return 0;
+}
+
+static int s3c_pwm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct pwm_device *pwm;
+	unsigned long flags;
+	unsigned long tcon;
+	unsigned int id = pdev->id;
+	int ret;
+
+	if (id == 4) {
+		dev_err(dev, "TIMER4 is currently not supported\n");
+		return -ENXIO;
+	}
+
+	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+	if (pwm == NULL) {
+		dev_err(dev, "failed to allocate pwm_device\n");
+		return -ENOMEM;
+	}
+
+	pwm->pdev = pdev;
+	pwm->pwm_id = id;
+
+	/* calculate base of control bits in TCON */
+	pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+
+	pwm->clk = clk_get(dev, "pwm-tin");
+	if (IS_ERR(pwm->clk)) {
+		dev_err(dev, "failed to get pwm tin clk\n");
+		ret = PTR_ERR(pwm->clk);
+		goto err_alloc;
+	}
+
+	pwm->clk_div = clk_get(dev, "pwm-tdiv");
+	if (IS_ERR(pwm->clk_div)) {
+		dev_err(dev, "failed to get pwm tdiv clk\n");
+		ret = PTR_ERR(pwm->clk_div);
+		goto err_clk_tin;
+	}
+
+	local_irq_save(flags);
+
+	tcon = __raw_readl(S3C2410_TCON);
+	tcon |= pwm_tcon_invert(pwm);
+	__raw_writel(tcon, S3C2410_TCON);
+
+	local_irq_restore(flags);
+
+
+	ret = pwm_register(pwm);
+	if (ret) {
+		dev_err(dev, "failed to register pwm\n");
+		goto err_clk_tdiv;
+	}
+
+	pwm_dbg(pwm, "config bits %02x\n",
+		(__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
+
+	dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
+		 clk_get_rate(pwm->clk),
+		 clk_get_rate(pwm->clk_div),
+		 pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
+
+	platform_set_drvdata(pdev, pwm);
+	return 0;
+
+ err_clk_tdiv:
+	clk_put(pwm->clk_div);
+
+ err_clk_tin:
+	clk_put(pwm->clk);
+
+ err_alloc:
+	kfree(pwm);
+	return ret;
+}
+
+static int s3c_pwm_remove(struct platform_device *pdev)
+{
+	struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+	clk_put(pwm->clk_div);
+	clk_put(pwm->clk);
+	kfree(pwm);
+
+	return 0;
+}
+
+static struct platform_driver s3c_pwm_driver = {
+	.driver		= {
+		.name	= "s3c24xx-pwm",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= s3c_pwm_probe,
+	.remove		= __devexit_p(s3c_pwm_remove),
+};
+
+static int __init pwm_init(void)
+{
+	int ret;
+
+	clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
+	clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
+
+	if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
+		printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
+		return -EINVAL;
+	}
+
+	ret = platform_driver_register(&s3c_pwm_driver);
+	if (ret)
+		printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
+
+	return ret;
+}
+
+arch_initcall(pwm_init);
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
index 5b0bc91..9c7aca4 100644
--- a/arch/arm/plat-s3c24xx/Kconfig
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -10,6 +10,7 @@ config PLAT_S3C24XX
 	default y
 	select NO_IOPORT
 	select ARCH_REQUIRE_GPIOLIB
+	select S3C_DEVICE_NAND
 	help
 	  Base platform code for any Samsung S3C24XX device
 
@@ -34,6 +35,40 @@ config CPU_S3C244X
 	help
 	  Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
 
+config S3C2440_CPUFREQ
+	bool "S3C2440/S3C2442 CPU Frequency scaling support"
+	depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
+	select S3C2410_CPUFREQ_UTILS
+	default y
+	help
+	  CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
+
+config S3C2440_XTAL_12000000
+	bool
+	help
+	  Indicate that the build needs to support 12MHz system
+	  crystal.
+
+config S3C2440_XTAL_16934400
+	bool
+	help
+	  Indicate that the build needs to support 16.9344MHz system
+	  crystal.
+
+config S3C2440_PLL_12000000
+	bool
+	depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
+	default y if CPU_FREQ_S3C24XX_PLL
+	help
+	  PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+
+config S3C2440_PLL_16934400
+	bool
+	depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
+	default y if CPU_FREQ_S3C24XX_PLL
+	help
+	  PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+
 config S3C24XX_PWM
 	bool "PWM device support"
 	select HAVE_PWM
@@ -105,8 +140,39 @@ config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
 	  SPI GPIO configuration code for BUS 1 when connected to
 	  GPG5, GPG6 and GPG7.
 
+config S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10
+	bool
+	help
+	  SPI GPIO configuration code for BUS 1 when connected to
+	  GPD8, GPD9 and GPD10.
+
 # common code for s3c24xx based machines, such as the SMDKs.
 
+# cpu frequency items common between s3c2410 and s3c2440/s3c2442
+
+config S3C2410_IOTIMING
+	bool
+	depends on CPU_FREQ_S3C24XX
+	help
+	  Internal node to select io timing code that is common to the s3c2410
+	  and s3c2440/s3c2442 cpu frequency support.
+
+config S3C2410_CPUFREQ_UTILS
+	bool
+	depends on CPU_FREQ_S3C24XX
+	help
+	  Internal node to select timing code that is common to the s3c2410
+	  and s3c2440/s3c244 cpu frequency support.
+
+# cpu frequency support common to s3c2412, s3c2413 and s3c2442
+
+config S3C2412_IOTIMING
+	bool
+	depends on CPU_FREQ_S3C24XX && (CPU_S3C2412 || CPU_S3C2443)
+	help
+	  Intel node to select io timing code that is common to the s3c2412
+	  and the s3c2443.
+
 config MACH_SMDK
 	bool
 	help
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index 579a165..7780d2d 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -20,19 +20,28 @@ obj-y				+= gpiolib.o
 obj-y				+= clock.o
 obj-$(CONFIG_S3C24XX_DCLK)	+= clock-dclk.o
 
+obj-$(CONFIG_CPU_FREQ_S3C24XX)	+= cpu-freq.o
+obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
+
 # Architecture dependant builds
 
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-irq.o
 obj-$(CONFIG_CPU_S3C244X)	+= s3c244x-clock.o
+obj-$(CONFIG_S3C2440_CPUFREQ)	+= s3c2440-cpufreq.o
+obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
+obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o
+
 obj-$(CONFIG_PM_SIMTEC)		+= pm-simtec.o
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_PM)		+= irq-pm.o
 obj-$(CONFIG_PM)		+= sleep.o
-obj-$(CONFIG_S3C24XX_PWM)	+= pwm.o
 obj-$(CONFIG_S3C2410_CLOCK)	+= s3c2410-clock.o
 obj-$(CONFIG_S3C2410_DMA)	+= dma.o
 obj-$(CONFIG_S3C24XX_ADC)	+= adc.o
+obj-$(CONFIG_S3C2410_IOTIMING)	+= s3c2410-iotiming.o
+obj-$(CONFIG_S3C2412_IOTIMING)	+= s3c2412-iotiming.o
+obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
 
 # device specific setup and/or initialisation
 obj-$(CONFIG_ARCH_S3C2410)	+= setup-i2c.o
@@ -41,6 +50,7 @@ obj-$(CONFIG_ARCH_S3C2410)	+= setup-i2c.o
 
 obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o
 obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7)    += spi-bus1-gpg5_6_7.o
+obj-$(CONFIG_S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10)	 += spi-bus1-gpd8_9_10.o
 
 # machine common support
 
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c
index ee1baf1..11117a7 100644
--- a/arch/arm/plat-s3c24xx/adc.c
+++ b/arch/arm/plat-s3c24xx/adc.c
@@ -39,13 +39,16 @@
 struct s3c_adc_client {
 	struct platform_device	*pdev;
 	struct list_head	 pend;
+	wait_queue_head_t	*wait;
 
 	unsigned int		 nr_samples;
+	int			 result;
 	unsigned char		 is_ts;
 	unsigned char		 channel;
 
-	void	(*select_cb)(unsigned selected);
-	void	(*convert_cb)(unsigned val1, unsigned val2,
+	void	(*select_cb)(struct s3c_adc_client *c, unsigned selected);
+	void	(*convert_cb)(struct s3c_adc_client *c,
+			      unsigned val1, unsigned val2,
 			      unsigned *samples_left);
 };
 
@@ -81,7 +84,7 @@ static inline void s3c_adc_select(struct adc_device *adc,
 {
 	unsigned con = readl(adc->regs + S3C2410_ADCCON);
 
-	client->select_cb(1);
+	client->select_cb(client, 1);
 
 	con &= ~S3C2410_ADCCON_MUXMASK;
 	con &= ~S3C2410_ADCCON_STDBM;
@@ -153,25 +156,61 @@ int s3c_adc_start(struct s3c_adc_client *client,
 }
 EXPORT_SYMBOL_GPL(s3c_adc_start);
 
-static void s3c_adc_default_select(unsigned select)
+static void s3c_convert_done(struct s3c_adc_client *client,
+			     unsigned v, unsigned u, unsigned *left)
+{
+	client->result = v;
+	wake_up(client->wait);
+}
+
+int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch)
+{
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+	int ret;
+
+	client->convert_cb = s3c_convert_done;
+	client->wait = &wake;
+	client->result = -1;
+
+	ret = s3c_adc_start(client, ch, 1);
+	if (ret < 0)
+		goto err;
+
+	ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
+	if (client->result < 0) {
+		ret = -ETIMEDOUT;
+		goto err;
+	}
+
+	client->convert_cb = NULL;
+	return client->result;
+
+err:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_convert);
+
+static void s3c_adc_default_select(struct s3c_adc_client *client,
+				   unsigned select)
 {
 }
 
 struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
-					void (*select)(unsigned int selected),
-					void (*conv)(unsigned d0, unsigned d1,
+					void (*select)(struct s3c_adc_client *client,
+						       unsigned int selected),
+					void (*conv)(struct s3c_adc_client *client,
+						     unsigned d0, unsigned d1,
 						     unsigned *samples_left),
 					unsigned int is_ts)
 {
 	struct s3c_adc_client *client;
 
 	WARN_ON(!pdev);
-	WARN_ON(!conv);
 
 	if (!select)
 		select = s3c_adc_default_select;
 
-	if (!conv || !pdev)
+	if (!pdev)
 		return ERR_PTR(-EINVAL);
 
 	client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
@@ -230,16 +269,19 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw)
 	adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
 
 	client->nr_samples--;
-	(client->convert_cb)(data0 & 0x3ff, data1 & 0x3ff, &client->nr_samples);
+
+	if (client->convert_cb)
+		(client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff,
+				     &client->nr_samples);
 
 	if (client->nr_samples > 0) {
 		/* fire another conversion for this */
 
-		client->select_cb(1);
+		client->select_cb(client, 1);
 		s3c_adc_convert(adc);
 	} else {
 		local_irq_save(flags);
-		(client->select_cb)(0);
+		(client->select_cb)(client, 0);
 		adc->cur = NULL;
 
 		s3c_adc_try(adc);
diff --git a/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
new file mode 100644
index 0000000..a927666
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
@@ -0,0 +1,199 @@
+/* linux/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling - debugfs status support
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/err.h>
+
+#include <plat/cpu-freq-core.h>
+
+static struct dentry *dbgfs_root;
+static struct dentry *dbgfs_file_io;
+static struct dentry *dbgfs_file_info;
+static struct dentry *dbgfs_file_board;
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+static void show_max(struct seq_file *seq, struct s3c_freq *f)
+{
+	seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n",
+		   f->fclk, f->hclk, f->pclk, f->armclk);
+}
+
+static int board_show(struct seq_file *seq, void *p)
+{
+	struct s3c_cpufreq_config *cfg;
+	struct s3c_cpufreq_board *brd;
+
+	cfg = s3c_cpufreq_getconfig();
+	if (!cfg) {
+		seq_printf(seq, "no configuration registered\n");
+		return 0;
+	}
+
+	brd = cfg->board;
+	if (!brd) {
+		seq_printf(seq, "no board definition set?\n");
+		return 0;
+	}
+
+	seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh);
+	seq_printf(seq, "auto_io=%u\n", brd->auto_io);
+	seq_printf(seq, "need_io=%u\n", brd->need_io);
+
+	show_max(seq, &brd->max);
+
+
+	return 0;
+}
+
+static int fops_board_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, board_show, NULL);
+}
+
+static const struct file_operations fops_board = {
+	.open		= fops_board_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int info_show(struct seq_file *seq, void *p)
+{
+	struct s3c_cpufreq_config *cfg;
+
+	cfg = s3c_cpufreq_getconfig();
+	if (!cfg) {
+		seq_printf(seq, "no configuration registered\n");
+		return 0;
+	}
+
+	seq_printf(seq, "  FCLK %ld Hz\n", cfg->freq.fclk);
+	seq_printf(seq, "  HCLK %ld Hz (%lu.%lu ns)\n",
+		   cfg->freq.hclk, print_ns(cfg->freq.hclk_tns));
+	seq_printf(seq, "  PCLK %ld Hz\n", cfg->freq.hclk);
+	seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk);
+	seq_printf(seq, "\n");
+
+	show_max(seq, &cfg->max);
+
+	seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n",
+		   cfg->divs.h_divisor, cfg->divs.p_divisor,
+		   cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off");
+	seq_printf(seq, "\n");
+
+	seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll);
+
+	return 0;
+}
+
+static int fops_info_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, info_show, NULL);
+}
+
+static const struct file_operations fops_info = {
+	.open		= fops_info_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+static int io_show(struct seq_file *seq, void *p)
+{
+	void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *);
+	struct s3c_cpufreq_config *cfg;
+	struct s3c_iotimings *iot;
+	union s3c_iobank *iob;
+	int bank;
+
+	cfg = s3c_cpufreq_getconfig();
+	if (!cfg) {
+		seq_printf(seq, "no configuration registered\n");
+		return 0;
+	}
+
+	show_bank = cfg->info->debug_io_show;
+	if (!show_bank) {
+		seq_printf(seq, "no code to show bank timing\n");
+		return 0;
+	}
+
+	iot = s3c_cpufreq_getiotimings();
+	if (!iot) {
+		seq_printf(seq, "no io timings registered\n");
+		return 0;
+	}
+
+	seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns));
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		iob = &iot->bank[bank];
+
+		seq_printf(seq, "bank %d: ", bank);
+
+		if (!iob->io_2410) {
+			seq_printf(seq, "nothing set\n");
+			continue;
+		}
+
+		show_bank(seq, cfg, iob);
+	}
+
+	return 0;
+}
+
+static int fops_io_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, io_show, NULL);
+}
+
+static const struct file_operations fops_io = {
+	.open		= fops_io_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.owner		= THIS_MODULE,
+};
+
+
+static int __init s3c_freq_debugfs_init(void)
+{
+	dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL);
+	if (IS_ERR(dbgfs_root)) {
+		printk(KERN_ERR "%s: error creating debugfs root\n", __func__);
+		return PTR_ERR(dbgfs_root);
+	}
+
+	dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root,
+					    NULL, &fops_io);
+
+	dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root,
+					      NULL, &fops_info);
+
+	dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root,
+					       NULL, &fops_board);
+
+	return 0;
+}
+
+late_initcall(s3c_freq_debugfs_init);
+
diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c
new file mode 100644
index 0000000..4f1b789
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/cpu-freq.c
@@ -0,0 +1,716 @@
+/* linux/arch/arm/plat-s3c24xx/cpu-freq.c
+ *
+ * Copyright (c) 2006,2007,2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+#include <mach/regs-clock.h>
+
+/* note, cpufreq support deals in kHz, no Hz */
+
+static struct cpufreq_driver s3c24xx_driver;
+static struct s3c_cpufreq_config cpu_cur;
+static struct s3c_iotimings s3c24xx_iotiming;
+static struct cpufreq_frequency_table *pll_reg;
+static unsigned int last_target = ~0;
+static unsigned int ftab_size;
+static struct cpufreq_frequency_table *ftab;
+
+static struct clk *_clk_mpll;
+static struct clk *_clk_xtal;
+static struct clk *clk_fclk;
+static struct clk *clk_hclk;
+static struct clk *clk_pclk;
+static struct clk *clk_arm;
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
+struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void)
+{
+	return &cpu_cur;
+}
+
+struct s3c_iotimings *s3c_cpufreq_getiotimings(void)
+{
+	return &s3c24xx_iotiming;
+}
+#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */
+
+static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long fclk, pclk, hclk, armclk;
+
+	cfg->freq.fclk = fclk = clk_get_rate(clk_fclk);
+	cfg->freq.hclk = hclk = clk_get_rate(clk_hclk);
+	cfg->freq.pclk = pclk = clk_get_rate(clk_pclk);
+	cfg->freq.armclk = armclk = clk_get_rate(clk_arm);
+
+	cfg->pll.index = __raw_readl(S3C2410_MPLLCON);
+	cfg->pll.frequency = fclk;
+
+	cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
+
+	cfg->divs.h_divisor = fclk / hclk;
+	cfg->divs.p_divisor = fclk / pclk;
+}
+
+static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long pll = cfg->pll.frequency;
+
+	cfg->freq.fclk = pll;
+	cfg->freq.hclk = pll / cfg->divs.h_divisor;
+	cfg->freq.pclk = pll / cfg->divs.p_divisor;
+
+	/* convert hclk into 10ths of nanoseconds for io calcs */
+	cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
+}
+
+static inline int closer(unsigned int target, unsigned int n, unsigned int c)
+{
+	int diff_cur = abs(target - c);
+	int diff_new = abs(target - n);
+
+	return (diff_new < diff_cur);
+}
+
+static void s3c_cpufreq_show(const char *pfx,
+				 struct s3c_cpufreq_config *cfg)
+{
+	s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n",
+		     pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk,
+		     cfg->freq.hclk, cfg->divs.h_divisor,
+		     cfg->freq.pclk, cfg->divs.p_divisor);
+}
+
+/* functions to wrapper the driver info calls to do the cpu specific work */
+
+static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg)
+{
+	if (cfg->info->set_iotiming)
+		(cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming);
+}
+
+static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg)
+{
+	if (cfg->info->calc_iotiming)
+		return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming);
+
+	return 0;
+}
+
+static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+	(cfg->info->set_refresh)(cfg);
+}
+
+static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	(cfg->info->set_divs)(cfg);
+}
+
+static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	return (cfg->info->calc_divs)(cfg);
+}
+
+static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
+{
+	(cfg->info->set_fvco)(cfg);
+}
+
+static inline void s3c_cpufreq_resume_clocks(void)
+{
+	cpu_cur.info->resume_clocks();
+}
+
+static inline void s3c_cpufreq_updateclk(struct clk *clk,
+					 unsigned int freq)
+{
+	clk_set_rate(clk, freq);
+}
+
+static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
+				 unsigned int target_freq,
+				 struct cpufreq_frequency_table *pll)
+{
+	struct s3c_cpufreq_freqs freqs;
+	struct s3c_cpufreq_config cpu_new;
+	unsigned long flags;
+
+	cpu_new = cpu_cur;  /* copy new from current */
+
+	s3c_cpufreq_show("cur", &cpu_cur);
+
+	/* TODO - check for DMA currently outstanding */
+
+	cpu_new.pll = pll ? *pll : cpu_cur.pll;
+
+	if (pll)
+		freqs.pll_changing = 1;
+
+	/* update our frequencies */
+
+	cpu_new.freq.armclk = target_freq;
+	cpu_new.freq.fclk = cpu_new.pll.frequency;
+
+	if (s3c_cpufreq_calcdivs(&cpu_new) < 0) {
+		printk(KERN_ERR "no divisors for %d\n", target_freq);
+		goto err_notpossible;
+	}
+
+	s3c_freq_dbg("%s: got divs\n", __func__);
+
+	s3c_cpufreq_calc(&cpu_new);
+
+	s3c_freq_dbg("%s: calculated frequencies for new\n", __func__);
+
+	if (cpu_new.freq.hclk != cpu_cur.freq.hclk) {
+		if (s3c_cpufreq_calcio(&cpu_new) < 0) {
+			printk(KERN_ERR "%s: no IO timings\n", __func__);
+			goto err_notpossible;
+		}
+	}
+
+	s3c_cpufreq_show("new", &cpu_new);
+
+	/* setup our cpufreq parameters */
+
+	freqs.old = cpu_cur.freq;
+	freqs.new = cpu_new.freq;
+
+	freqs.freqs.cpu = 0;
+	freqs.freqs.old = cpu_cur.freq.armclk / 1000;
+	freqs.freqs.new = cpu_new.freq.armclk / 1000;
+
+	/* update f/h/p clock settings before we issue the change
+	 * notification, so that drivers do not need to do anything
+	 * special if they want to recalculate on CPUFREQ_PRECHANGE. */
+
+	s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency);
+	s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk);
+	s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk);
+	s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
+
+	/* start the frequency change */
+
+	if (policy)
+		cpufreq_notify_transition(&freqs.freqs, CPUFREQ_PRECHANGE);
+
+	/* If hclk is staying the same, then we do not need to
+	 * re-write the IO or the refresh timings whilst we are changing
+	 * speed. */
+
+	local_irq_save(flags);
+
+	/* is our memory clock slowing down? */
+	if (cpu_new.freq.hclk < cpu_cur.freq.hclk) {
+		s3c_cpufreq_setrefresh(&cpu_new);
+		s3c_cpufreq_setio(&cpu_new);
+	}
+
+	if (cpu_new.freq.fclk == cpu_cur.freq.fclk) {
+		/* not changing PLL, just set the divisors */
+
+		s3c_cpufreq_setdivs(&cpu_new);
+	} else {
+		if (cpu_new.freq.fclk < cpu_cur.freq.fclk) {
+			/* slow the cpu down, then set divisors */
+
+			s3c_cpufreq_setfvco(&cpu_new);
+			s3c_cpufreq_setdivs(&cpu_new);
+		} else {
+			/* set the divisors, then speed up */
+
+			s3c_cpufreq_setdivs(&cpu_new);
+			s3c_cpufreq_setfvco(&cpu_new);
+		}
+	}
+
+	/* did our memory clock speed up */
+	if (cpu_new.freq.hclk > cpu_cur.freq.hclk) {
+		s3c_cpufreq_setrefresh(&cpu_new);
+		s3c_cpufreq_setio(&cpu_new);
+	}
+
+	/* update our current settings */
+	cpu_cur = cpu_new;
+
+	local_irq_restore(flags);
+
+	/* notify everyone we've done this */
+	if (policy)
+		cpufreq_notify_transition(&freqs.freqs, CPUFREQ_POSTCHANGE);
+
+	s3c_freq_dbg("%s: finished\n", __func__);
+	return 0;
+
+ err_notpossible:
+	printk(KERN_ERR "no compatible settings for %d\n", target_freq);
+	return -EINVAL;
+}
+
+/* s3c_cpufreq_target
+ *
+ * called by the cpufreq core to adjust the frequency that the CPU
+ * is currently running at.
+ */
+
+static int s3c_cpufreq_target(struct cpufreq_policy *policy,
+			      unsigned int target_freq,
+			      unsigned int relation)
+{
+	struct cpufreq_frequency_table *pll;
+	unsigned int index;
+
+	/* avoid repeated calls which cause a needless amout of duplicated
+	 * logging output (and CPU time as the calculation process is
+	 * done) */
+	if (target_freq == last_target)
+		return 0;
+
+	last_target = target_freq;
+
+	s3c_freq_dbg("%s: policy %p, target %u, relation %u\n",
+		     __func__, policy, target_freq, relation);
+
+	if (ftab) {
+		if (cpufreq_frequency_table_target(policy, ftab,
+						   target_freq, relation,
+						   &index)) {
+			s3c_freq_dbg("%s: table failed\n", __func__);
+			return -EINVAL;
+		}
+
+		s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,
+			     target_freq, index, ftab[index].frequency);
+		target_freq = ftab[index].frequency;
+	}
+
+	target_freq *= 1000;  /* convert target to Hz */
+
+	/* find the settings for our new frequency */
+
+	if (!pll_reg || cpu_cur.lock_pll) {
+		/* either we've not got any PLL values, or we've locked
+		 * to the current one. */
+		pll = NULL;
+	} else {
+		struct cpufreq_policy tmp_policy;
+		int ret;
+
+		/* we keep the cpu pll table in Hz, to ensure we get an
+		 * accurate value for the PLL output. */
+
+		tmp_policy.min = policy->min * 1000;
+		tmp_policy.max = policy->max * 1000;
+		tmp_policy.cpu = policy->cpu;
+
+		/* cpufreq_frequency_table_target uses a pointer to 'index'
+		 * which is the number of the table entry, not the value of
+		 * the table entry's index field. */
+
+		ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg,
+						     target_freq, relation,
+						     &index);
+
+		if (ret < 0) {
+			printk(KERN_ERR "%s: no PLL available\n", __func__);
+			goto err_notpossible;
+		}
+
+		pll = pll_reg + index;
+
+		s3c_freq_dbg("%s: target %u => %u\n",
+			     __func__, target_freq, pll->frequency);
+
+		target_freq = pll->frequency;
+	}
+
+	return s3c_cpufreq_settarget(policy, target_freq, pll);
+
+ err_notpossible:
+	printk(KERN_ERR "no compatible settings for %d\n", target_freq);
+	return -EINVAL;
+}
+
+static unsigned int s3c_cpufreq_get(unsigned int cpu)
+{
+	return clk_get_rate(clk_arm) / 1000;
+}
+
+struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
+{
+	struct clk *clk;
+
+	clk = clk_get(dev, name);
+	if (IS_ERR(clk))
+		printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name);
+
+	return clk;
+}
+
+static int s3c_cpufreq_init(struct cpufreq_policy *policy)
+{
+	printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy);
+
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	policy->cur = s3c_cpufreq_get(0);
+	policy->min = policy->cpuinfo.min_freq = 0;
+	policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000;
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+	/* feed the latency information from the cpu driver */
+	policy->cpuinfo.transition_latency = cpu_cur.info->latency;
+
+	if (ftab)
+		cpufreq_frequency_table_cpuinfo(policy, ftab);
+
+	return 0;
+}
+
+static __init int s3c_cpufreq_initclks(void)
+{
+	_clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
+	_clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
+	clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk");
+	clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk");
+	clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk");
+	clk_arm = s3c_cpufreq_clk_get(NULL, "armclk");
+
+	if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) ||
+	    IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) {
+		printk(KERN_ERR "%s: could not get clock(s)\n", __func__);
+		return -ENOENT;
+	}
+
+	printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__,
+	       clk_get_rate(clk_fclk) / 1000,
+	       clk_get_rate(clk_hclk) / 1000,
+	       clk_get_rate(clk_pclk) / 1000,
+	       clk_get_rate(clk_arm) / 1000);
+
+	return 0;
+}
+
+static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	if (policy->cpu != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static struct cpufreq_frequency_table suspend_pll;
+static unsigned int suspend_freq;
+
+static int s3c_cpufreq_suspend(struct cpufreq_policy *policy, pm_message_t pmsg)
+{
+	suspend_pll.frequency = clk_get_rate(_clk_mpll);
+	suspend_pll.index = __raw_readl(S3C2410_MPLLCON);
+	suspend_freq = s3c_cpufreq_get(0) * 1000;
+
+	return 0;
+}
+
+static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
+{
+	int ret;
+
+	s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy);
+
+	last_target = ~0;	/* invalidate last_target setting */
+
+	/* first, find out what speed we resumed at. */
+	s3c_cpufreq_resume_clocks();
+
+	/* whilst we will be called later on, we try and re-set the
+	 * cpu frequencies as soon as possible so that we do not end
+	 * up resuming devices and then immediatley having to re-set
+	 * a number of settings once these devices have restarted.
+	 *
+	 * as a note, it is expected devices are not used until they
+	 * have been un-suspended and at that time they should have
+	 * used the updated clock settings.
+	 */
+
+	ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll);
+	if (ret) {
+		printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+#else
+#define s3c_cpufreq_resume NULL
+#define s3c_cpufreq_suspend NULL
+#endif
+
+static struct cpufreq_driver s3c24xx_driver = {
+	.flags		= CPUFREQ_STICKY,
+	.verify		= s3c_cpufreq_verify,
+	.target		= s3c_cpufreq_target,
+	.get		= s3c_cpufreq_get,
+	.init		= s3c_cpufreq_init,
+	.suspend	= s3c_cpufreq_suspend,
+	.resume		= s3c_cpufreq_resume,
+	.name		= "s3c24xx",
+};
+
+
+int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
+{
+	if (!info || !info->name) {
+		printk(KERN_ERR "%s: failed to pass valid information\n",
+		       __func__);
+		return -EINVAL;
+	}
+
+	printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n",
+	       info->name);
+
+	/* check our driver info has valid data */
+
+	BUG_ON(info->set_refresh == NULL);
+	BUG_ON(info->set_divs == NULL);
+	BUG_ON(info->calc_divs == NULL);
+
+	/* info->set_fvco is optional, depending on whether there
+	 * is a need to set the clock code. */
+
+	cpu_cur.info = info;
+
+	/* Note, driver registering should probably update locktime */
+
+	return 0;
+}
+
+int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
+{
+	struct s3c_cpufreq_board *ours;
+
+	if (!board) {
+		printk(KERN_INFO "%s: no board data\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Copy the board information so that each board can make this
+	 * initdata. */
+
+	ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
+	if (ours == NULL) {
+		printk(KERN_ERR "%s: no memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	*ours = *board;
+	cpu_cur.board = ours;
+
+	return 0;
+}
+
+int __init s3c_cpufreq_auto_io(void)
+{
+	int ret;
+
+	if (!cpu_cur.info->get_iotiming) {
+		printk(KERN_ERR "%s: get_iotiming undefined\n", __func__);
+		return -ENOENT;
+	}
+
+	printk(KERN_INFO "%s: working out IO settings\n", __func__);
+
+	ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming);
+	if (ret)
+		printk(KERN_ERR "%s: failed to get timings\n", __func__);
+
+	return ret;
+}
+
+/* if one or is zero, then return the other, otherwise return the min */
+#define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b))
+
+/**
+ * s3c_cpufreq_freq_min - find the minimum settings for the given freq.
+ * @dst: The destination structure
+ * @a: One argument.
+ * @b: The other argument.
+ *
+ * Create a minimum of each frequency entry in the 'struct s3c_freq',
+ * unless the entry is zero when it is ignored and the non-zero argument
+ * used.
+ */
+static void s3c_cpufreq_freq_min(struct s3c_freq *dst,
+				 struct s3c_freq *a, struct s3c_freq *b)
+{
+	dst->fclk = do_min(a->fclk, b->fclk);
+	dst->hclk = do_min(a->hclk, b->hclk);
+	dst->pclk = do_min(a->pclk, b->pclk);
+	dst->armclk = do_min(a->armclk, b->armclk);
+}
+
+static inline u32 calc_locktime(u32 freq, u32 time_us)
+{
+	u32 result;
+
+	result = freq * time_us;
+	result = DIV_ROUND_UP(result, 1000 * 1000);
+
+	return result;
+}
+
+static void s3c_cpufreq_update_loctkime(void)
+{
+	unsigned int bits = cpu_cur.info->locktime_bits;
+	u32 rate = (u32)clk_get_rate(_clk_xtal);
+	u32 val;
+
+	if (bits == 0) {
+		WARN_ON(1);
+		return;
+	}
+
+	val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits;
+	val |= calc_locktime(rate, cpu_cur.info->locktime_m);
+
+	printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val);
+	__raw_writel(val, S3C2410_LOCKTIME);
+}
+
+static int s3c_cpufreq_build_freq(void)
+{
+	int size, ret;
+
+	if (!cpu_cur.info->calc_freqtable)
+		return -EINVAL;
+
+	kfree(ftab);
+	ftab = NULL;
+
+	size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
+	size++;
+
+	ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
+	if (!ftab) {
+		printk(KERN_ERR "%s: no memory for tables\n", __func__);
+		return -ENOMEM;
+	}
+
+	ftab_size = size;
+
+	ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size);
+	s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END);
+
+	return 0;
+}
+
+static int __init s3c_cpufreq_initcall(void)
+{
+	int ret = 0;
+
+	if (cpu_cur.info && cpu_cur.board) {
+		ret = s3c_cpufreq_initclks();
+		if (ret)
+			goto out;
+
+		/* get current settings */
+		s3c_cpufreq_getcur(&cpu_cur);
+		s3c_cpufreq_show("cur", &cpu_cur);
+
+		if (cpu_cur.board->auto_io) {
+			ret = s3c_cpufreq_auto_io();
+			if (ret) {
+				printk(KERN_ERR "%s: failed to get io timing\n",
+				       __func__);
+				goto out;
+			}
+		}
+
+		if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) {
+			printk(KERN_ERR "%s: no IO support registered\n",
+			       __func__);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (!cpu_cur.info->need_pll)
+			cpu_cur.lock_pll = 1;
+
+		s3c_cpufreq_update_loctkime();
+
+		s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max,
+				     &cpu_cur.info->max);
+
+		if (cpu_cur.info->calc_freqtable)
+			s3c_cpufreq_build_freq();
+
+		ret = cpufreq_register_driver(&s3c24xx_driver);
+	}
+
+ out:
+	return ret;
+}
+
+late_initcall(s3c_cpufreq_initcall);
+
+/**
+ * s3c_plltab_register - register CPU PLL table.
+ * @plls: The list of PLL entries.
+ * @plls_no: The size of the PLL entries @plls.
+ *
+ * Register the given set of PLLs with the system.
+ */
+int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
+			       unsigned int plls_no)
+{
+	struct cpufreq_frequency_table *vals;
+	unsigned int size;
+
+	size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
+
+	vals = kmalloc(size, GFP_KERNEL);
+	if (vals) {
+		memcpy(vals, plls, size);
+		pll_reg = vals;
+
+		/* write a terminating entry, we don't store it in the
+		 * table that is stored in the kernel */
+		vals += plls_no;
+		vals->frequency = CPUFREQ_TABLE_END;
+
+		printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no);
+	} else
+		printk(KERN_ERR "cpufreq: no memory for PLL tables\n");
+
+	return vals ? 0 : -ENOMEM;
+}
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 1932b7e..5447e60 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -81,7 +81,7 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.map_io		= s3c2410_map_io,
 		.init_clocks	= s3c2410_init_clocks,
 		.init_uarts	= s3c2410_init_uarts,
-		.init		= s3c2410_init,
+		.init		= s3c2410a_init,
 		.name		= name_s3c2410a
 	},
 	{
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 4eb378c..f52a92c 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -26,6 +26,8 @@
 #include <asm/mach/irq.h>
 #include <mach/fb.h>
 #include <mach/hardware.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
 #include <asm/irq.h>
 
 #include <plat/regs-serial.h>
@@ -180,25 +182,6 @@ void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
 	}
 }
 
-/* NAND Controller */
-
-static struct resource s3c_nand_resource[] = {
-	[0] = {
-		.start = S3C24XX_PA_NAND,
-		.end   = S3C24XX_PA_NAND + S3C24XX_SZ_NAND - 1,
-		.flags = IORESOURCE_MEM,
-	}
-};
-
-struct platform_device s3c_device_nand = {
-	.name		  = "s3c2410-nand",
-	.id		  = -1,
-	.num_resources	  = ARRAY_SIZE(s3c_nand_resource),
-	.resource	  = s3c_nand_resource,
-};
-
-EXPORT_SYMBOL(s3c_device_nand);
-
 /* USB Device (Gadget)*/
 
 static struct resource s3c_usbgadget_resource[] = {
@@ -348,7 +331,7 @@ struct platform_device s3c_device_adc = {
 /* HWMON */
 
 struct platform_device s3c_device_hwmon = {
-	.name		= "s3c24xx-hwmon",
+	.name		= "s3c-hwmon",
 	.id		= -1,
 	.dev.parent	= &s3c_device_adc.dev,
 };
@@ -473,4 +456,52 @@ struct platform_device s3c_device_camif = {
 
 EXPORT_SYMBOL(s3c_device_camif);
 
+/* AC97 */
+
+static struct resource s3c_ac97_resource[] = {
+	[0] = {
+		.start = S3C2440_PA_AC97,
+		.end   = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_S3C244x_AC97,
+		.end   = IRQ_S3C244x_AC97,
+		.flags = IORESOURCE_IRQ,
+	},
+	[2] = {
+		.name  = "PCM out",
+		.start = DMACH_PCM_OUT,
+		.end   = DMACH_PCM_OUT,
+		.flags = IORESOURCE_DMA,
+	},
+	[3] = {
+		.name  = "PCM in",
+		.start = DMACH_PCM_IN,
+		.end   = DMACH_PCM_IN,
+		.flags = IORESOURCE_DMA,
+	},
+	[4] = {
+		.name  = "Mic in",
+		.start = DMACH_MIC_IN,
+		.end   = DMACH_MIC_IN,
+		.flags = IORESOURCE_DMA,
+	},
+};
+
+static u64 s3c_device_ac97_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_ac97 = {
+	.name		  = "s3c-ac97",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c_ac97_resource),
+	.resource	  = s3c_ac97_resource,
+	.dev              = {
+		.dma_mask = &s3c_device_ac97_dmamask,
+		.coherent_dma_mask = 0xffffffffUL
+	}
+};
+
+EXPORT_SYMBOL(s3c_device_ac97);
+
 #endif // CONFIG_CPU_S32440
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
new file mode 100644
index 0000000..efeb025
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
@@ -0,0 +1,282 @@
+/* arch/arm/plat-s3c/include/plat/cpu-freq.h
+ *
+ * Copyright (c) 2006,2007,2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C CPU frequency scaling support - core support
+ *
+ * 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 <plat/cpu-freq.h>
+
+struct seq_file;
+
+#define MAX_BANKS (8)
+#define S3C2412_MAX_IO	(8)
+
+/**
+ * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
+ * @bankcon: The cached version of settings in this structure.
+ * @tacp:
+ * @tacs: Time from address valid to nCS asserted.
+ * @tcos: Time from nCS asserted to nOE or nWE asserted.
+ * @tacc: Time that nOE or nWE is asserted.
+ * @tcoh: Time nCS is held after nOE or nWE are released.
+ * @tcah: Time address is held for after
+ * @nwait_en: Whether nWAIT is enabled for this bank.
+ *
+ * This structure represents the IO timings for a S3C2410 style IO bank
+ * used by the CPU frequency support if it needs to change the settings
+ * of the IO.
+ */
+struct s3c2410_iobank_timing {
+	unsigned long	bankcon;
+	unsigned int	tacp;
+	unsigned int	tacs;
+	unsigned int	tcos;
+	unsigned int	tacc;
+	unsigned int	tcoh;		/* nCS hold afrer nOE/nWE */
+	unsigned int	tcah;		/* Address hold after nCS */
+	unsigned char	nwait_en;	/* nWait enabled for bank. */
+};
+
+/**
+ * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO
+ * @idcy: The idle cycle time between transactions.
+ * @wstrd: nCS release to end of read cycle.
+ * @wstwr: nCS release to end of write cycle.
+ * @wstoen: nCS assertion to nOE assertion time.
+ * @wstwen: nCS assertion to nWE assertion time.
+ * @wstbrd: Burst ready delay.
+ * @smbidcyr: Register cache for smbidcyr value.
+ * @smbwstrd: Register cache for smbwstrd value.
+ * @smbwstwr: Register cache for smbwstwr value.
+ * @smbwstoen: Register cache for smbwstoen value.
+ * @smbwstwen: Register cache for smbwstwen value.
+ * @smbwstbrd: Register cache for smbwstbrd value.
+ *
+ * Timing information for a IO bank on an S3C2412 or similar system which
+ * uses a PL093 block.
+ */
+struct s3c2412_iobank_timing {
+	unsigned int	idcy;
+	unsigned int	wstrd;
+	unsigned int	wstwr;
+	unsigned int	wstoen;
+	unsigned int	wstwen;
+	unsigned int	wstbrd;
+
+	/* register cache */
+	unsigned char	smbidcyr;
+	unsigned char	smbwstrd;
+	unsigned char	smbwstwr;
+	unsigned char	smbwstoen;
+	unsigned char	smbwstwen;
+	unsigned char	smbwstbrd;
+};
+
+union s3c_iobank {
+	struct s3c2410_iobank_timing	*io_2410;
+	struct s3c2412_iobank_timing	*io_2412;
+};
+
+/**
+ * struct s3c_iotimings - Chip IO timings holder
+ * @bank: The timings for each IO bank.
+ */
+struct s3c_iotimings {
+	union s3c_iobank	bank[MAX_BANKS];
+};
+
+/**
+ * struct s3c_plltab - PLL table information.
+ * @vals: List of PLL values.
+ * @size: Size of the PLL table @vals.
+ */
+struct s3c_plltab {
+	struct s3c_pllval	*vals;
+	int			 size;
+};
+
+/**
+ * struct s3c_cpufreq_config - current cpu frequency configuration
+ * @freq: The current settings for the core clocks.
+ * @max: Maxium settings, derived from core, board and user settings.
+ * @pll: The PLL table entry for the current PLL settings.
+ * @divs: The divisor settings for the core clocks.
+ * @info: The current core driver information.
+ * @board: The information for the board we are running on.
+ * @lock_pll: Set if the PLL settings cannot be changed.
+ *
+ * This is for the core drivers that need to know information about
+ * the current settings and values. It should not be needed by any
+ * device drivers.
+*/
+struct s3c_cpufreq_config {
+	struct s3c_freq		freq;
+	struct s3c_freq		max;
+	struct cpufreq_frequency_table pll;
+	struct s3c_clkdivs	divs;
+	struct s3c_cpufreq_info *info;	/* for core, not drivers */
+	struct s3c_cpufreq_board *board;
+
+	unsigned int	lock_pll:1;
+};
+
+/**
+ * struct s3c_cpufreq_info - Information for the CPU frequency driver.
+ * @name: The name of this implementation.
+ * @max: The maximum frequencies for the system.
+ * @latency: Transition latency to give to cpufreq.
+ * @locktime_m: The lock-time in uS for the MPLL.
+ * @locktime_u: The lock-time in uS for the UPLL.
+ * @locttime_bits: The number of bits each LOCKTIME field.
+ * @need_pll: Set if this driver needs to change the PLL values to acheive
+ *	any frequency changes. This is really only need by devices like the
+ *	S3C2410 where there is no or limited divider between the PLL and the
+ *	ARMCLK.
+ * @resume_clocks: Update the clocks on resume.
+ * @get_iotiming: Get the current IO timing data, mainly for use at start.
+ * @set_iotiming: Update the IO timings from the cached copies calculated
+ *	from the @calc_iotiming entry when changing the frequency.
+ * @calc_iotiming: Calculate and update the cached copies of the IO timings
+ *	from the newly calculated frequencies.
+ * @calc_freqtable: Calculate (fill in) the given frequency table from the
+ *	current frequency configuration. If the table passed in is NULL,
+ *	then the return is the number of elements to be filled for allocation
+ *	of the table.
+ * @set_refresh: Set the memory refresh configuration.
+ * @set_fvco: Set the PLL frequencies.
+ * @set_divs: Update the clock divisors.
+ * @calc_divs: Calculate the clock divisors.
+ */
+struct s3c_cpufreq_info {
+	const char		*name;
+	struct s3c_freq		max;
+
+	unsigned int		latency;
+
+	unsigned int		locktime_m;
+	unsigned int		locktime_u;
+	unsigned char		locktime_bits;
+
+	unsigned int		need_pll:1;
+
+	/* driver routines */
+
+	void		(*resume_clocks)(void);
+
+	int		(*get_iotiming)(struct s3c_cpufreq_config *cfg,
+					struct s3c_iotimings *timings);
+
+	void		(*set_iotiming)(struct s3c_cpufreq_config *cfg,
+					struct s3c_iotimings *timings);
+
+	int		(*calc_iotiming)(struct s3c_cpufreq_config *cfg,
+					 struct s3c_iotimings *timings);
+
+	int		(*calc_freqtable)(struct s3c_cpufreq_config *cfg,
+					  struct cpufreq_frequency_table *t,
+					  size_t table_size);
+
+	void		(*debug_io_show)(struct seq_file *seq,
+					 struct s3c_cpufreq_config *cfg,
+					 union s3c_iobank *iob);
+
+	void		(*set_refresh)(struct s3c_cpufreq_config *cfg);
+	void		(*set_fvco)(struct s3c_cpufreq_config *cfg);
+	void		(*set_divs)(struct s3c_cpufreq_config *cfg);
+	int		(*calc_divs)(struct s3c_cpufreq_config *cfg);
+};
+
+extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
+
+extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no);
+
+/* exports and utilities for debugfs */
+extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
+extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
+
+extern void s3c2410_iotiming_debugfs(struct seq_file *seq,
+				     struct s3c_cpufreq_config *cfg,
+				     union s3c_iobank *iob);
+
+extern void s3c2412_iotiming_debugfs(struct seq_file *seq,
+				     struct s3c_cpufreq_config *cfg,
+				     union s3c_iobank *iob);
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
+#define s3c_cpufreq_debugfs_call(x) x
+#else
+#define s3c_cpufreq_debugfs_call(x) NULL
+#endif
+
+/* Useful utility functions. */
+
+extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
+
+/* S3C2410 and compatible exported functions */
+
+extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
+
+extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
+				 struct s3c_iotimings *iot);
+
+extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
+				struct s3c_iotimings *timings);
+
+extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
+				 struct s3c_iotimings *iot);
+
+extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
+
+/* S3C2412 compatible routines */
+
+extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+				struct s3c_iotimings *timings);
+
+extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+				struct s3c_iotimings *timings);
+
+extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
+				 struct s3c_iotimings *iot);
+
+extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
+				 struct s3c_iotimings *iot);
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
+#define s3c_freq_dbg(x...) printk(KERN_INFO x)
+#else
+#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
+#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
+#define s3c_freq_iodbg(x...) printk(KERN_INFO x)
+#else
+#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
+#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
+
+static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
+				      int index, size_t table_size,
+				      unsigned int freq)
+{
+	if (index < 0)
+		return index;
+
+	if (table) {
+		if (index >= table_size)
+			return -ENOMEM;
+
+		s3c_freq_dbg("%s: { %d = %u kHz }\n",
+			     __func__, index, freq);
+
+		table[index].index = index;
+		table[index].frequency = freq;
+	}
+
+	return index + 1;
+}
diff --git a/arch/arm/plat-s3c24xx/include/plat/fiq.h b/arch/arm/plat-s3c24xx/include/plat/fiq.h
new file mode 100644
index 0000000..8521b83
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/fiq.h
@@ -0,0 +1,13 @@
+/* linux/include/asm-arm/plat-s3c24xx/fiq.h
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU FIQ support
+ *
+ * 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.
+*/
+
+extern int s3c24xx_set_fiq(unsigned int irq, bool on);
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
index a9ac9e2..b6deeef 100644
--- a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
@@ -14,6 +14,7 @@
 #ifdef CONFIG_CPU_S3C2410
 
 extern  int s3c2410_init(void);
+extern  int s3c2410a_init(void);
 
 extern void s3c2410_map_io(void);
 
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 9587377..d02f5f0 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -493,6 +493,38 @@ s3c_irq_demux_extint4t7(unsigned int irq,
 	}
 }
 
+#ifdef CONFIG_FIQ
+/**
+ * s3c24xx_set_fiq - set the FIQ routing
+ * @irq: IRQ number to route to FIQ on processor.
+ * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
+ *
+ * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
+ * @on is true, the @irq is checked to see if it can be routed and the
+ * interrupt controller updated to route the IRQ. If @on is false, the FIQ
+ * routing is cleared, regardless of which @irq is specified.
+ */
+int s3c24xx_set_fiq(unsigned int irq, bool on)
+{
+	u32 intmod;
+	unsigned offs;
+
+	if (on) {
+		offs = irq - FIQ_START;
+		if (offs > 31)
+			return -EINVAL;
+
+		intmod = 1 << offs;
+	} else {
+		intmod = 0;
+	}
+
+	__raw_writel(intmod, S3C2410_INTMOD);
+	return 0;
+}
+#endif
+
+
 /* s3c24xx_init_irq
  *
  * Initialise S3C2410 IRQ system
@@ -505,6 +537,10 @@ void __init s3c24xx_init_irq(void)
 	int irqno;
 	int i;
 
+#ifdef CONFIG_FIQ
+	init_FIQ();
+#endif
+
 	irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
 
 	/* first, clear all interrupts pending... */
diff --git a/arch/arm/plat-s3c24xx/pwm.c b/arch/arm/plat-s3c24xx/pwm.c
deleted file mode 100644
index 82a6d4d..0000000
--- a/arch/arm/plat-s3c24xx/pwm.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/* arch/arm/plat-s3c24xx/pwm.c
- *
- * Copyright (c) 2007 Ben Dooks
- * Copyright (c) 2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C24XX PWM device core
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <mach/irqs.h>
-
-#include <plat/devs.h>
-#include <plat/regs-timer.h>
-
-struct pwm_device {
-	struct list_head	 list;
-	struct platform_device	*pdev;
-
-	struct clk		*clk_div;
-	struct clk		*clk;
-	const char		*label;
-
-	unsigned int		 period_ns;
-	unsigned int		 duty_ns;
-
-	unsigned char		 tcon_base;
-	unsigned char		 running;
-	unsigned char		 use_count;
-	unsigned char		 pwm_id;
-};
-
-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
-
-static struct clk *clk_scaler[2];
-
-/* Standard setup for a timer block. */
-
-#define TIMER_RESOURCE_SIZE (1)
-
-#define TIMER_RESOURCE(_tmr, _irq)			\
-	(struct resource [TIMER_RESOURCE_SIZE]) {	\
-		[0] = {					\
-			.start	= _irq,			\
-			.end	= _irq,			\
-			.flags	= IORESOURCE_IRQ	\
-		}					\
-	}
-
-#define DEFINE_S3C_TIMER(_tmr_no, _irq)			\
-	.name		= "s3c24xx-pwm",		\
-	.id		= _tmr_no,			\
-	.num_resources	= TIMER_RESOURCE_SIZE,		\
-	.resource	= TIMER_RESOURCE(_tmr_no, _irq),	\
-
-/* since we already have an static mapping for the timer, we do not
- * bother setting any IO resource for the base.
- */
-
-struct platform_device s3c_device_timer[] = {
-	[0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
-	[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
-	[2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
-	[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
-	[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
-};
-
-static inline int pwm_is_tdiv(struct pwm_device *pwm)
-{
-	return clk_get_parent(pwm->clk) == pwm->clk_div;
-}
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	struct pwm_device *pwm;
-	int found = 0;
-
-	mutex_lock(&pwm_lock);
-
-	list_for_each_entry(pwm, &pwm_list, list) {
-		if (pwm->pwm_id == pwm_id) {
-			found = 1;
-			break;
-		}
-	}
-
-	if (found) {
-		if (pwm->use_count == 0) {
-			pwm->use_count = 1;
-			pwm->label = label;
-		} else
-			pwm = ERR_PTR(-EBUSY);
-	} else
-		pwm = ERR_PTR(-ENOENT);
-
-	mutex_unlock(&pwm_lock);
-	return pwm;
-}
-
-EXPORT_SYMBOL(pwm_request);
-
-
-void pwm_free(struct pwm_device *pwm)
-{
-	mutex_lock(&pwm_lock);
-
-	if (pwm->use_count) {
-		pwm->use_count--;
-		pwm->label = NULL;
-	} else
-		printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
-
-	mutex_unlock(&pwm_lock);
-}
-
-EXPORT_SYMBOL(pwm_free);
-
-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
-
-int pwm_enable(struct pwm_device *pwm)
-{
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_start(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	pwm->running = 1;
-	return 0;
-}
-
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
-	unsigned long flags;
-	unsigned long tcon;
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon &= ~pwm_tcon_start(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	pwm->running = 0;
-}
-
-EXPORT_SYMBOL(pwm_disable);
-
-static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
-{
-	unsigned long tin_parent_rate;
-	unsigned int div;
-
-	tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
-	pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
-
-	for (div = 2; div <= 16; div *= 2) {
-		if ((tin_parent_rate / (div << 16)) < freq)
-			return tin_parent_rate / div;
-	}
-
-	return tin_parent_rate / 16;
-}
-
-#define NS_IN_HZ (1000000000UL)
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	unsigned long tin_rate;
-	unsigned long tin_ns;
-	unsigned long period;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned long tcnt;
-	long tcmp;
-
-	/* We currently avoid using 64bit arithmetic by using the
-	 * fact that anything faster than 1Hz is easily representable
-	 * by 32bits. */
-
-	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
-		return -ERANGE;
-
-	if (duty_ns > period_ns)
-		return -EINVAL;
-
-	if (period_ns == pwm->period_ns &&
-	    duty_ns == pwm->duty_ns)
-		return 0;
-
-	/* The TCMP and TCNT can be read without a lock, they're not
-	 * shared between the timers. */
-
-	tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
-	tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
-
-	period = NS_IN_HZ / period_ns;
-
-	pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
-		duty_ns, period_ns, period);
-
-	/* Check to see if we are changing the clock rate of the PWM */
-
-	if (pwm->period_ns != period_ns) {
-		if (pwm_is_tdiv(pwm)) {
-			tin_rate = pwm_calc_tin(pwm, period);
-			clk_set_rate(pwm->clk_div, tin_rate);
-		} else
-			tin_rate = clk_get_rate(pwm->clk);
-
-		pwm->period_ns = period_ns;
-
-		pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
-
-		tin_ns = NS_IN_HZ / tin_rate;
-		tcnt = period_ns / tin_ns;
-	} else
-		tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
-
-	/* Note, counters count down */
-
-	tcmp = duty_ns / tin_ns;
-	tcmp = tcnt - tcmp;
-	/* the pwm hw only checks the compare register after a decrement,
-	   so the pin never toggles if tcmp = tcnt */
-	if (tcmp == tcnt)
-		tcmp--;
-
-	pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
-
-	if (tcmp < 0)
-		tcmp = 0;
-
-	/* Update the PWM register block. */
-
-	local_irq_save(flags);
-
-	__raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
-	__raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_manulupdate(pwm);
-	tcon |= pwm_tcon_autoreload(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	tcon &= ~pwm_tcon_manulupdate(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pwm_config);
-
-static int pwm_register(struct pwm_device *pwm)
-{
-	pwm->duty_ns = -1;
-	pwm->period_ns = -1;
-
-	mutex_lock(&pwm_lock);
-	list_add_tail(&pwm->list, &pwm_list);
-	mutex_unlock(&pwm_lock);
-
-	return 0;
-}
-
-static int s3c_pwm_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct pwm_device *pwm;
-	unsigned long flags;
-	unsigned long tcon;
-	unsigned int id = pdev->id;
-	int ret;
-
-	if (id == 4) {
-		dev_err(dev, "TIMER4 is currently not supported\n");
-		return -ENXIO;
-	}
-
-	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
-	if (pwm == NULL) {
-		dev_err(dev, "failed to allocate pwm_device\n");
-		return -ENOMEM;
-	}
-
-	pwm->pdev = pdev;
-	pwm->pwm_id = id;
-
-	/* calculate base of control bits in TCON */
-	pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
-
-	pwm->clk = clk_get(dev, "pwm-tin");
-	if (IS_ERR(pwm->clk)) {
-		dev_err(dev, "failed to get pwm tin clk\n");
-		ret = PTR_ERR(pwm->clk);
-		goto err_alloc;
-	}
-
-	pwm->clk_div = clk_get(dev, "pwm-tdiv");
-	if (IS_ERR(pwm->clk_div)) {
-		dev_err(dev, "failed to get pwm tdiv clk\n");
-		ret = PTR_ERR(pwm->clk_div);
-		goto err_clk_tin;
-	}
-
-	local_irq_save(flags);
-
-	tcon = __raw_readl(S3C2410_TCON);
-	tcon |= pwm_tcon_invert(pwm);
-	__raw_writel(tcon, S3C2410_TCON);
-
-	local_irq_restore(flags);
-
-
-	ret = pwm_register(pwm);
-	if (ret) {
-		dev_err(dev, "failed to register pwm\n");
-		goto err_clk_tdiv;
-	}
-
-	pwm_dbg(pwm, "config bits %02x\n",
-		(__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
-
-	dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
-		 clk_get_rate(pwm->clk),
-		 clk_get_rate(pwm->clk_div),
-		 pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
-
-	platform_set_drvdata(pdev, pwm);
-	return 0;
-
- err_clk_tdiv:
-	clk_put(pwm->clk_div);
-
- err_clk_tin:
-	clk_put(pwm->clk);
-
- err_alloc:
-	kfree(pwm);
-	return ret;
-}
-
-static int s3c_pwm_remove(struct platform_device *pdev)
-{
-	struct pwm_device *pwm = platform_get_drvdata(pdev);
-
-	clk_put(pwm->clk_div);
-	clk_put(pwm->clk);
-	kfree(pwm);
-
-	return 0;
-}
-
-static struct platform_driver s3c_pwm_driver = {
-	.driver		= {
-		.name	= "s3c24xx-pwm",
-		.owner	= THIS_MODULE,
-	},
-	.probe		= s3c_pwm_probe,
-	.remove		= __devexit_p(s3c_pwm_remove),
-};
-
-static int __init pwm_init(void)
-{
-	int ret;
-
-	clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
-	clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
-
-	if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
-		printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
-		return -EINVAL;
-	}
-
-	ret = platform_driver_register(&s3c_pwm_driver);
-	if (ret)
-		printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
-
-	return ret;
-}
-
-arch_initcall(pwm_init);
diff --git a/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
new file mode 100644
index 0000000..43ea801
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
@@ -0,0 +1,64 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442
+ *
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+/**
+ * s3c2410_cpufreq_setrefresh - set SDRAM refresh value
+ * @cfg: The frequency configuration
+ *
+ * Set the SDRAM refresh value appropriately for the configured
+ * frequency.
+ */
+void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+	struct s3c_cpufreq_board *board = cfg->board;
+	unsigned long refresh;
+	unsigned long refval;
+
+	/* Reduce both the refresh time (in ns) and the frequency (in MHz)
+	 * down to ensure that we do not overflow 32 bit numbers.
+	 *
+	 * This should work for HCLK up to 133MHz and refresh period up
+	 * to 30usec.
+	 */
+
+	refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
+	refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale  */
+	refresh = (1 << 11) + 1 - refresh;
+
+	s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh);
+
+	refval = __raw_readl(S3C2410_REFRESH);
+	refval &= ~((1 << 12) - 1);
+	refval |= refresh;
+	__raw_writel(refval, S3C2410_REFRESH);
+}
+
+/**
+ * s3c2410_set_fvco - set the PLL value
+ * @cfg: The frequency configuration
+ */
+void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
+{
+	__raw_writel(cfg->pll.index, S3C2410_MPLLCON);
+}
diff --git a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
new file mode 100644
index 0000000..d0a3a14
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
@@ -0,0 +1,477 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
+ *
+ * Copyright (c) 2006,2008,2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling - IO timing for S3C2410/S3C2440/S3C2442
+ *
+ * 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/kernel.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+/**
+ * s3c2410_print_timing - print bank timing data for debug purposes
+ * @pfx: The prefix to put on the output
+ * @timings: The timing inforamtion to print.
+*/
+static void s3c2410_print_timing(const char *pfx,
+				 struct s3c_iotimings *timings)
+{
+	struct s3c2410_iobank_timing *bt;
+	int bank;
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		bt = timings->bank[bank].io_2410;
+		if (!bt)
+			continue;
+
+		printk(KERN_DEBUG "%s %d: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, "
+		       "Tcoh=%d.%d, Tcah=%d.%d\n", pfx, bank,
+		       print_ns(bt->tacs),
+		       print_ns(bt->tcos),
+		       print_ns(bt->tacc),
+		       print_ns(bt->tcoh),
+		       print_ns(bt->tcah));
+	}
+}
+
+/**
+ * bank_reg - convert bank number to pointer to the control register.
+ * @bank: The IO bank number.
+ */
+static inline void __iomem *bank_reg(unsigned int bank)
+{
+	return S3C2410_BANKCON0 + (bank << 2);
+}
+
+/**
+ * bank_is_io - test whether bank is used for IO
+ * @bankcon: The bank control register.
+ *
+ * This is a simplistic test to see if any BANKCON[x] is not an IO
+ * bank. It currently does not take into account whether BWSCON has
+ * an illegal width-setting in it, or if the pin connected to nCS[x]
+ * is actually being handled as a chip-select.
+ */
+static inline int bank_is_io(unsigned long bankcon)
+{
+	return !(bankcon & S3C2410_BANKCON_SDRAM);
+}
+
+/**
+ * to_div - convert cycle time to divisor
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ *
+ * Convert the given cycle time into the divisor to use to obtain it from
+ * HCLK.
+*/
+static inline unsigned int to_div(unsigned int cyc, unsigned int hclk_tns)
+{
+	if (cyc == 0)
+		return 0;
+
+	return DIV_ROUND_UP(cyc, hclk_tns);
+}
+
+/**
+ * calc_0124 - calculate divisor control for divisors that do /0, /1. /2 and /4
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @v: Pointer to register to alter.
+ * @shift: The shift to get to the control bits.
+ *
+ * Calculate the divisor, and turn it into the correct control bits to
+ * set in the result, @v.
+ */
+static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns,
+			      unsigned long *v, int shift)
+{
+	unsigned int div = to_div(cyc, hclk_tns);
+	unsigned long val;
+
+	s3c_freq_iodbg("%s: cyc=%d, hclk=%lu, shift=%d => div %d\n",
+		       __func__, cyc, hclk_tns, shift, div);
+
+	switch (div) {
+	case 0:
+		val = 0;
+		break;
+	case 1:
+		val = 1;
+		break;
+	case 2:
+		val = 2;
+		break;
+	case 3:
+	case 4:
+		val = 3;
+		break;
+	default:
+		return -1;
+	}
+
+	*v |= val << shift;
+	return 0;
+}
+
+int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v)
+{
+	/* Currently no support for Tacp calculations. */
+	return 0;
+}
+
+/**
+ * calc_tacc - calculate divisor control for tacc.
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @nwait_en: IS nWAIT enabled for this bank.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @v: Pointer to register to alter.
+ *
+ * Calculate the divisor control for tACC, taking into account whether
+ * the bank has nWAIT enabled. The result is used to modify the value
+ * pointed to by @v.
+*/
+static int calc_tacc(unsigned int cyc, int nwait_en,
+		     unsigned long hclk_tns, unsigned long *v)
+{
+	unsigned int div = to_div(cyc, hclk_tns);
+	unsigned long val;
+
+	s3c_freq_iodbg("%s: cyc=%u, nwait=%d, hclk=%lu => div=%u\n",
+		       __func__, cyc, nwait_en, hclk_tns, div);
+
+	/* if nWait enabled on an bank, Tacc must be at-least 4 cycles. */
+	if (nwait_en && div < 4)
+		div = 4;
+
+	switch (div) {
+	case 0:
+		val = 0;
+		break;
+
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+		val = div - 1;
+		break;
+
+	case 5:
+	case 6:
+		val = 4;
+		break;
+
+	case 7:
+	case 8:
+		val = 5;
+		break;
+
+	case 9:
+	case 10:
+		val = 6;
+		break;
+
+	case 11:
+	case 12:
+	case 13:
+	case 14:
+		val = 7;
+		break;
+
+	default:
+		return -1;
+	}
+
+	*v |= val << 8;
+	return 0;
+}
+
+/**
+ * s3c2410_calc_bank - calculate bank timing infromation
+ * @cfg: The configuration we need to calculate for.
+ * @bt: The bank timing information.
+ *
+ * Given the cycle timine for a bank @bt, calculate the new BANKCON
+ * setting for the @cfg timing. This updates the timing information
+ * ready for the cpu frequency change.
+ */
+static int s3c2410_calc_bank(struct s3c_cpufreq_config *cfg,
+			     struct s3c2410_iobank_timing *bt)
+{
+	unsigned long hclk = cfg->freq.hclk_tns;
+	unsigned long res;
+	int ret;
+
+	res  = bt->bankcon;
+	res &= (S3C2410_BANKCON_SDRAM | S3C2410_BANKCON_PMC16);
+
+	/* tacp: 2,3,4,5 */
+	/* tcah: 0,1,2,4 */
+	/* tcoh: 0,1,2,4 */
+	/* tacc: 1,2,3,4,6,7,10,14 (>4 for nwait) */
+	/* tcos: 0,1,2,4 */
+	/* tacs: 0,1,2,4 */
+
+	ret  = calc_0124(bt->tacs, hclk, &res, S3C2410_BANKCON_Tacs_SHIFT);
+	ret |= calc_0124(bt->tcos, hclk, &res, S3C2410_BANKCON_Tcos_SHIFT);
+	ret |= calc_0124(bt->tcah, hclk, &res, S3C2410_BANKCON_Tcah_SHIFT);
+	ret |= calc_0124(bt->tcoh, hclk, &res, S3C2410_BANKCON_Tcoh_SHIFT);
+
+	if (ret)
+		return -EINVAL;
+
+	ret |= calc_tacp(bt->tacp, hclk, &res);
+	ret |= calc_tacc(bt->tacc, bt->nwait_en, hclk, &res);
+
+	if (ret)
+		return -EINVAL;
+
+	bt->bankcon = res;
+	return 0;
+}
+
+static unsigned int tacc_tab[] = {
+	[0]	= 1,
+	[1]	= 2,
+	[2]	= 3,
+	[3]	= 4,
+	[4]	= 6,
+	[5]	= 9,
+	[6]	= 10,
+	[7]	= 14,
+};
+
+/**
+ * get_tacc - turn tACC value into cycle time
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @val: The bank timing register value, shifed down.
+ */
+static unsigned int get_tacc(unsigned long hclk_tns,
+			     unsigned long val)
+{
+	val &= 7;
+	return hclk_tns * tacc_tab[val];
+}
+
+/**
+ * get_0124 - turn 0/1/2/4 divider into cycle time
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @val: The bank timing register value, shifed down.
+ */
+static unsigned int get_0124(unsigned long hclk_tns,
+			     unsigned long val)
+{
+	val &= 3;
+	return hclk_tns * ((val == 3) ? 4 : val);
+}
+
+/**
+ * s3c2410_iotiming_getbank - turn BANKCON into cycle time information
+ * @cfg: The frequency configuration
+ * @bt: The bank timing to fill in (uses cached BANKCON)
+ *
+ * Given the BANKCON setting in @bt and the current frequency settings
+ * in @cfg, update the cycle timing information.
+ */
+void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg,
+			      struct s3c2410_iobank_timing *bt)
+{
+	unsigned long bankcon = bt->bankcon;
+	unsigned long hclk = cfg->freq.hclk_tns;
+
+	bt->tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
+	bt->tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
+	bt->tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
+	bt->tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
+	bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
+}
+
+/**
+ * s3c2410_iotiming_debugfs - debugfs show io bank timing information
+ * @seq: The seq_file to write output to using seq_printf().
+ * @cfg: The current configuration.
+ * @iob: The IO bank information to decode.
+ */
+void s3c2410_iotiming_debugfs(struct seq_file *seq,
+			      struct s3c_cpufreq_config *cfg,
+			      union s3c_iobank *iob)
+{
+	struct s3c2410_iobank_timing *bt = iob->io_2410;
+	unsigned long bankcon = bt->bankcon;
+	unsigned long hclk = cfg->freq.hclk_tns;
+	unsigned int tacs;
+	unsigned int tcos;
+	unsigned int tacc;
+	unsigned int tcoh;
+	unsigned int tcah;
+
+	seq_printf(seq, "BANKCON=0x%08lx\n", bankcon);
+
+	tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
+	tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
+	tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
+	tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
+	tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
+
+	seq_printf(seq,
+		   "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
+		   print_ns(bt->tacs),
+		   print_ns(bt->tcos),
+		   print_ns(bt->tacc),
+		   print_ns(bt->tcoh),
+		   print_ns(bt->tcah));
+
+	seq_printf(seq,
+		   "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
+		   print_ns(tacs),
+		   print_ns(tcos),
+		   print_ns(tacc),
+		   print_ns(tcoh),
+		   print_ns(tcah));
+}
+
+/**
+ * s3c2410_iotiming_calc - Calculate bank timing for frequency change.
+ * @cfg: The frequency configuration
+ * @iot: The IO timing information to fill out.
+ *
+ * Calculate the new values for the banks in @iot based on the new
+ * frequency information in @cfg. This is then used by s3c2410_iotiming_set()
+ * to update the timing when necessary.
+ */
+int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
+			  struct s3c_iotimings *iot)
+{
+	struct s3c2410_iobank_timing *bt;
+	unsigned long bankcon;
+	int bank;
+	int ret;
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		bankcon = __raw_readl(bank_reg(bank));
+		bt = iot->bank[bank].io_2410;
+
+		if (!bt)
+			continue;
+
+		bt->bankcon = bankcon;
+
+		ret = s3c2410_calc_bank(cfg, bt);
+		if (ret) {
+			printk(KERN_ERR "%s: cannot calculate bank %d io\n",
+			       __func__, bank);
+			goto err;
+		}
+
+		s3c_freq_iodbg("%s: bank %d: con=%08lx\n",
+			       __func__, bank, bt->bankcon);
+	}
+
+	return 0;
+ err:
+	return ret;
+}
+
+/**
+ * s3c2410_iotiming_set - set the IO timings from the given setup.
+ * @cfg: The frequency configuration
+ * @iot: The IO timing information to use.
+ *
+ * Set all the currently used IO bank timing information generated
+ * by s3c2410_iotiming_calc() once the core has validated that all
+ * the new values are within permitted bounds.
+ */
+void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
+			  struct s3c_iotimings *iot)
+{
+	struct s3c2410_iobank_timing *bt;
+	int bank;
+
+	/* set the io timings from the specifier */
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		bt = iot->bank[bank].io_2410;
+		if (!bt)
+			continue;
+
+		__raw_writel(bt->bankcon, bank_reg(bank));
+	}
+}
+
+/**
+ * s3c2410_iotiming_get - Get the timing information from current registers.
+ * @cfg: The frequency configuration
+ * @timings: The IO timing information to fill out.
+ *
+ * Calculate the @timings timing information from the current frequency
+ * information in @cfg, and the new frequency configur
+ * through all the IO banks, reading the state and then updating @iot
+ * as necessary.
+ *
+ * This is used at the moment on initialisation to get the current
+ * configuration so that boards do not have to carry their own setup
+ * if the timings are correct on initialisation.
+ */
+
+int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
+			 struct s3c_iotimings *timings)
+{
+	struct s3c2410_iobank_timing *bt;
+	unsigned long bankcon;
+	unsigned long bwscon;
+	int bank;
+
+	bwscon = __raw_readl(S3C2410_BWSCON);
+
+	/* look through all banks to see what is currently set. */
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		bankcon = __raw_readl(bank_reg(bank));
+
+		if (!bank_is_io(bankcon))
+			continue;
+
+		s3c_freq_iodbg("%s: bank %d: con %08lx\n",
+			       __func__, bank, bankcon);
+
+		bt = kzalloc(sizeof(struct s3c2410_iobank_timing), GFP_KERNEL);
+		if (!bt) {
+			printk(KERN_ERR "%s: no memory for bank\n", __func__);
+			return -ENOMEM;
+		}
+
+		/* find out in nWait is enabled for bank. */
+
+		if (bank != 0) {
+			unsigned long tmp  = S3C2410_BWSCON_GET(bwscon, bank);
+			if (tmp & S3C2410_BWSCON_WS)
+				bt->nwait_en = 1;
+		}
+
+		timings->bank[bank].io_2410 = bt;
+		bt->bankcon = bankcon;
+
+		s3c2410_iotiming_getbank(cfg, bt);
+	}
+
+	s3c2410_print_timing("get", timings);
+	return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
new file mode 100644
index 0000000..fd45e47
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
@@ -0,0 +1,285 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
+ *
+ * Copyright (c) 2006,2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412/S3C2443 (PL093 based) IO timing support
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/seq_file.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <linux/amba/pl093.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-s3c2412-mem.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+#include <plat/clock.h>
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+/**
+ * s3c2412_print_timing - print timing infromation via printk.
+ * @pfx: The prefix to print each line with.
+ * @iot: The IO timing information
+ */
+static void s3c2412_print_timing(const char *pfx, struct s3c_iotimings *iot)
+{
+	struct s3c2412_iobank_timing *bt;
+	unsigned int bank;
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		bt = iot->bank[bank].io_2412;
+		if (!bt)
+			continue;
+
+		printk(KERN_DEBUG "%s: %d: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
+		       "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", pfx, bank,
+		       print_ns(bt->idcy),
+		       print_ns(bt->wstrd),
+		       print_ns(bt->wstwr),
+		       print_ns(bt->wstoen),
+		       print_ns(bt->wstwen),
+		       print_ns(bt->wstbrd));
+	}
+}
+
+/**
+ * to_div - turn a cycle length into a divisor setting.
+ * @cyc_tns: The cycle time in 10ths of nanoseconds.
+ * @clk_tns: The clock period in 10ths of nanoseconds.
+ */
+static inline unsigned int to_div(unsigned int cyc_tns, unsigned int clk_tns)
+{
+	return cyc_tns ? DIV_ROUND_UP(cyc_tns, clk_tns) : 0;
+}
+
+/**
+ * calc_timing - calculate timing divisor value and check in range.
+ * @hwtm: The hardware timing in 10ths of nanoseconds.
+ * @clk_tns: The clock period in 10ths of nanoseconds.
+ * @err: Pointer to err variable to update in event of failure.
+ */
+static unsigned int calc_timing(unsigned int hwtm, unsigned int clk_tns,
+				unsigned int *err)
+{
+	unsigned int ret = to_div(hwtm, clk_tns);
+
+	if (ret > 0xf)
+		*err = -EINVAL;
+
+	return ret;
+}
+
+/**
+ * s3c2412_calc_bank - calculate the bank divisor settings.
+ * @cfg: The current frequency configuration.
+ * @bt: The bank timing.
+ */
+static int s3c2412_calc_bank(struct s3c_cpufreq_config *cfg,
+			     struct s3c2412_iobank_timing *bt)
+{
+	unsigned int hclk = cfg->freq.hclk_tns;
+	int err = 0;
+
+	bt->smbidcyr = calc_timing(bt->idcy, hclk, &err);
+	bt->smbwstrd = calc_timing(bt->wstrd, hclk, &err);
+	bt->smbwstwr = calc_timing(bt->wstwr, hclk, &err);
+	bt->smbwstoen = calc_timing(bt->wstoen, hclk, &err);
+	bt->smbwstwen = calc_timing(bt->wstwen, hclk, &err);
+	bt->smbwstbrd = calc_timing(bt->wstbrd, hclk, &err);
+
+	return err;
+}
+
+/**
+ * s3c2412_iotiming_debugfs - debugfs show io bank timing information
+ * @seq: The seq_file to write output to using seq_printf().
+ * @cfg: The current configuration.
+ * @iob: The IO bank information to decode.
+*/
+void s3c2412_iotiming_debugfs(struct seq_file *seq,
+			      struct s3c_cpufreq_config *cfg,
+			      union s3c_iobank *iob)
+{
+	struct s3c2412_iobank_timing *bt = iob->io_2412;
+
+	seq_printf(seq,
+		   "\tRead: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
+		   "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n",
+		   print_ns(bt->idcy),
+		   print_ns(bt->wstrd),
+		   print_ns(bt->wstwr),
+		   print_ns(bt->wstoen),
+		   print_ns(bt->wstwen),
+		   print_ns(bt->wstbrd));
+}
+
+/**
+ * s3c2412_iotiming_calc - calculate all the bank divisor settings.
+ * @cfg: The current frequency configuration.
+ * @iot: The bank timing information.
+ *
+ * Calculate the timing information for all the banks that are
+ * configured as IO, using s3c2412_calc_bank().
+ */
+int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
+			  struct s3c_iotimings *iot)
+{
+	struct s3c2412_iobank_timing *bt;
+	int bank;
+	int ret;
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		bt = iot->bank[bank].io_2412;
+		if (!bt)
+			continue;
+
+		ret = s3c2412_calc_bank(cfg, bt);
+		if (ret) {
+			printk(KERN_ERR "%s: cannot calculate bank %d io\n",
+			       __func__, bank);
+			goto err;
+		}
+	}
+
+	return 0;
+ err:
+	return ret;
+}
+
+/**
+ * s3c2412_iotiming_set - set the timing information
+ * @cfg: The current frequency configuration.
+ * @iot: The bank timing information.
+ *
+ * Set the IO bank information from the details calculated earlier from
+ * calling s3c2412_iotiming_calc().
+ */
+void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
+			  struct s3c_iotimings *iot)
+{
+	struct s3c2412_iobank_timing *bt;
+	void __iomem *regs;
+	int bank;
+
+	/* set the io timings from the specifier */
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		bt = iot->bank[bank].io_2412;
+		if (!bt)
+			continue;
+
+		regs = S3C2412_SSMC_BANK(bank);
+
+		__raw_writel(bt->smbidcyr, regs + SMBIDCYR);
+		__raw_writel(bt->smbwstrd, regs + SMBWSTRDR);
+		__raw_writel(bt->smbwstwr, regs + SMBWSTWRR);
+		__raw_writel(bt->smbwstoen, regs + SMBWSTOENR);
+		__raw_writel(bt->smbwstwen, regs + SMBWSTWENR);
+		__raw_writel(bt->smbwstbrd, regs + SMBWSTBRDR);
+	}
+}
+
+static inline unsigned int s3c2412_decode_timing(unsigned int clock, u32 reg)
+{
+	return (reg & 0xf) * clock;
+}
+
+static void s3c2412_iotiming_getbank(struct s3c_cpufreq_config *cfg,
+				     struct s3c2412_iobank_timing *bt,
+				     unsigned int bank)
+{
+	unsigned long clk = cfg->freq.hclk_tns;  /* ssmc clock??? */
+	void __iomem *regs = S3C2412_SSMC_BANK(bank);
+
+	bt->idcy = s3c2412_decode_timing(clk, __raw_readl(regs + SMBIDCYR));
+	bt->wstrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTRDR));
+	bt->wstoen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTOENR));
+	bt->wstwen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTWENR));
+	bt->wstbrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTBRDR));
+}
+
+/**
+ * bank_is_io - return true if bank is (possibly) IO.
+ * @bank: The bank number.
+ * @bankcfg: The value of S3C2412_EBI_BANKCFG.
+ */
+static inline bool bank_is_io(unsigned int bank, u32 bankcfg)
+{
+	if (bank < 2)
+		return true;
+
+	return !(bankcfg & (1 << bank));
+}
+
+int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+			 struct s3c_iotimings *timings)
+{
+	struct s3c2412_iobank_timing *bt;
+	u32 bankcfg = __raw_readl(S3C2412_EBI_BANKCFG);
+	unsigned int bank;
+
+	/* look through all banks to see what is currently set. */
+
+	for (bank = 0; bank < MAX_BANKS; bank++) {
+		if (!bank_is_io(bank, bankcfg))
+			continue;
+
+		bt = kzalloc(sizeof(struct s3c2412_iobank_timing), GFP_KERNEL);
+		if (!bt) {
+			printk(KERN_ERR "%s: no memory for bank\n", __func__);
+			return -ENOMEM;
+		}
+
+		timings->bank[bank].io_2412 = bt;
+		s3c2412_iotiming_getbank(cfg, bt, bank);
+	}
+
+	s3c2412_print_timing("get", timings);
+	return 0;
+}
+
+/* this is in here as it is so small, it doesn't currently warrant a file
+ * to itself. We expect that any s3c24xx needing this is going to also
+ * need the iotiming support.
+ */
+void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+	struct s3c_cpufreq_board *board = cfg->board;
+	u32 refresh;
+
+	WARN_ON(board == NULL);
+
+	/* Reduce both the refresh time (in ns) and the frequency (in MHz)
+	 * down to ensure that we do not overflow 32 bit numbers.
+	 *
+	 * This should work for HCLK up to 133MHz and refresh period up
+	 * to 30usec.
+	 */
+
+	refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
+	refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale  */
+	refresh &= ((1 << 16) - 1);
+
+	s3c_freq_dbg("%s: refresh value %u\n", __func__, (unsigned int)refresh);
+
+	__raw_writel(refresh, S3C2412_REFRESH);
+}
diff --git a/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
new file mode 100644
index 0000000..ae2e6c6
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
@@ -0,0 +1,311 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
+ *
+ * Copyright (c) 2006,2008,2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 CPU Frequency scaling
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+#include <plat/clock.h>
+
+static struct clk *xtal;
+static struct clk *fclk;
+static struct clk *hclk;
+static struct clk *armclk;
+
+/* HDIV: 1, 2, 3, 4, 6, 8 */
+
+static inline int within_khz(unsigned long a, unsigned long b)
+{
+	long diff = a - b;
+
+	return (diff >= -1000 && diff <= 1000);
+}
+
+/**
+ * s3c2440_cpufreq_calcdivs - calculate divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Calcualte the divider values for the given frequency settings
+ * specified in @cfg. The values are stored in @cfg for later use
+ * by the relevant set routine if the request settings can be reached.
+ */
+int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned int hdiv, pdiv;
+	unsigned long hclk, fclk, armclk;
+	unsigned long hclk_max;
+
+	fclk = cfg->freq.fclk;
+	armclk = cfg->freq.armclk;
+	hclk_max = cfg->max.hclk;
+
+	s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
+		     __func__, fclk, armclk, hclk_max);
+
+	if (armclk > fclk) {
+		printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
+		armclk = fclk;
+	}
+
+	/* if we are in DVS, we need HCLK to be <= ARMCLK */
+	if (armclk < fclk && armclk < hclk_max)
+		hclk_max = armclk;
+
+	for (hdiv = 1; hdiv < 9; hdiv++) {
+		if (hdiv == 5 || hdiv == 7)
+			hdiv++;
+
+		hclk = (fclk / hdiv);
+		if (hclk <= hclk_max || within_khz(hclk, hclk_max))
+			break;
+	}
+
+	s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
+
+	if (hdiv > 8)
+		goto invalid;
+
+	pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+
+	if ((hclk / pdiv) > cfg->max.pclk)
+		pdiv++;
+
+	s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
+
+	if (pdiv > 2)
+		goto invalid;
+
+	pdiv *= hdiv;
+
+	/* calculate a valid armclk */
+
+	if (armclk < hclk)
+		armclk = hclk;
+
+	/* if we're running armclk lower than fclk, this really means
+	 * that the system should go into dvs mode, which means that
+	 * armclk is connected to hclk. */
+	if (armclk < fclk) {
+		cfg->divs.dvs = 1;
+		armclk = hclk;
+	} else
+		cfg->divs.dvs = 0;
+
+	cfg->freq.armclk = armclk;
+
+	/* store the result, and then return */
+
+	cfg->divs.h_divisor = hdiv;
+	cfg->divs.p_divisor = pdiv;
+
+	return 0;
+
+ invalid:
+	return -EINVAL;
+}
+
+#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
+			   S3C2440_CAMDIVN_HCLK4_HALF)
+
+/**
+ * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Set the divisors from the settings in @cfg, which where generated
+ * during the calculation phase by s3c2440_cpufreq_calcdivs().
+ */
+static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+	unsigned long clkdiv, camdiv;
+
+	s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
+		     cfg->divs.h_divisor, cfg->divs.p_divisor);
+
+	clkdiv = __raw_readl(S3C2410_CLKDIVN);
+	camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+	clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
+	camdiv &= ~CAMDIVN_HCLK_HALF;
+
+	switch (cfg->divs.h_divisor) {
+	case 1:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
+		break;
+
+	case 2:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
+		break;
+
+	case 6:
+		camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
+	case 3:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
+		break;
+
+	case 8:
+		camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
+	case 4:
+		clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
+		break;
+
+	default:
+		BUG();	/* we don't expect to get here. */
+	}
+
+	if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+		clkdiv |= S3C2440_CLKDIVN_PDIVN;
+
+	/* todo - set pclk. */
+
+	/* Write the divisors first with hclk intentionally halved so that
+	 * when we write clkdiv we will under-frequency instead of over. We
+	 * then make a short delay and remove the hclk halving if necessary.
+	 */
+
+	__raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
+	__raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+	ndelay(20);
+	__raw_writel(camdiv, S3C2440_CAMDIVN);
+
+	clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
+}
+
+static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
+			int *divs,
+			struct cpufreq_frequency_table *table,
+			size_t table_size)
+{
+	unsigned long freq;
+	int index = 0;
+	int div;
+
+	for (div = *divs; div > 0; div = *divs++) {
+		freq = fclk / div;
+
+		if (freq > max_hclk && div != 1)
+			continue;
+
+		freq /= 1000; /* table is in kHz */
+		index = s3c_cpufreq_addfreq(table, index, table_size, freq);
+		if (index < 0)
+			break;
+	}
+
+	return index;
+}
+
+static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
+
+static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
+				     struct cpufreq_frequency_table *table,
+				     size_t table_size)
+{
+	int ret;
+
+	WARN_ON(cfg->info == NULL);
+	WARN_ON(cfg->board == NULL);
+
+	ret = run_freq_for(cfg->info->max.hclk,
+			   cfg->info->max.fclk,
+			   hclk_divs,
+			   table, table_size);
+
+	s3c_freq_dbg("%s: returning %d\n", __func__, ret);
+
+	return ret;
+}
+
+struct s3c_cpufreq_info s3c2440_cpufreq_info = {
+	.max		= {
+		.fclk	= 400000000,
+		.hclk	= 133333333,
+		.pclk	=  66666666,
+	},
+
+	.locktime_m	= 300,
+	.locktime_u	= 300,
+	.locktime_bits	= 16,
+
+	.name		= "s3c244x",
+	.calc_iotiming	= s3c2410_iotiming_calc,
+	.set_iotiming	= s3c2410_iotiming_set,
+	.get_iotiming	= s3c2410_iotiming_get,
+	.set_fvco	= s3c2410_set_fvco,
+
+	.set_refresh	= s3c2410_cpufreq_setrefresh,
+	.set_divs	= s3c2440_cpufreq_setdivs,
+	.calc_divs	= s3c2440_cpufreq_calcdivs,
+	.calc_freqtable	= s3c2440_cpufreq_calctable,
+
+	.resume_clocks	= s3c244x_setup_clocks,
+
+	.debug_io_show  = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
+};
+
+static int s3c2440_cpufreq_add(struct sys_device *sysdev)
+{
+	xtal = s3c_cpufreq_clk_get(NULL, "xtal");
+	hclk = s3c_cpufreq_clk_get(NULL, "hclk");
+	fclk = s3c_cpufreq_clk_get(NULL, "fclk");
+	armclk = s3c_cpufreq_clk_get(NULL, "armclk");
+
+	if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
+		printk(KERN_ERR "%s: failed to get clocks\n", __func__);
+		return -ENOENT;
+	}
+
+	return s3c_cpufreq_register(&s3c2440_cpufreq_info);
+}
+
+static struct sysdev_driver s3c2440_cpufreq_driver = {
+	.add		= s3c2440_cpufreq_add,
+};
+
+static int s3c2440_cpufreq_init(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass,
+				      &s3c2440_cpufreq_driver);
+}
+
+/* arch_initcall adds the clocks we need, so use subsys_initcall. */
+subsys_initcall(s3c2440_cpufreq_init);
+
+static struct sysdev_driver s3c2442_cpufreq_driver = {
+	.add		= s3c2440_cpufreq_add,
+};
+
+static int s3c2442_cpufreq_init(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass,
+				      &s3c2442_cpufreq_driver);
+}
+
+subsys_initcall(s3c2442_cpufreq_init);
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c b/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
new file mode 100644
index 0000000..ff9443b
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
@@ -0,0 +1,97 @@
+/* arch/arm/plat-s3c24xx/s3c2440-pll-12000000.c
+ *
+ * Copyright (c) 2006,2007 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
+	{ .frequency = 75000000,	.index = PLLVAL(0x75, 3, 3),  }, 	/* FVco 600.000000 */
+	{ .frequency = 80000000,	.index = PLLVAL(0x98, 4, 3),  }, 	/* FVco 640.000000 */
+	{ .frequency = 90000000,	.index = PLLVAL(0x70, 2, 3),  }, 	/* FVco 720.000000 */
+	{ .frequency = 100000000,	.index = PLLVAL(0x5c, 1, 3),  }, 	/* FVco 800.000000 */
+	{ .frequency = 110000000,	.index = PLLVAL(0x66, 1, 3),  }, 	/* FVco 880.000000 */
+	{ .frequency = 120000000,	.index = PLLVAL(0x70, 1, 3),  }, 	/* FVco 960.000000 */
+	{ .frequency = 150000000,	.index = PLLVAL(0x75, 3, 2),  }, 	/* FVco 600.000000 */
+	{ .frequency = 160000000,	.index = PLLVAL(0x98, 4, 2),  }, 	/* FVco 640.000000 */
+	{ .frequency = 170000000,	.index = PLLVAL(0x4d, 1, 2),  }, 	/* FVco 680.000000 */
+	{ .frequency = 180000000,	.index = PLLVAL(0x70, 2, 2),  }, 	/* FVco 720.000000 */
+	{ .frequency = 190000000,	.index = PLLVAL(0x57, 1, 2),  }, 	/* FVco 760.000000 */
+	{ .frequency = 200000000,	.index = PLLVAL(0x5c, 1, 2),  }, 	/* FVco 800.000000 */
+	{ .frequency = 210000000,	.index = PLLVAL(0x84, 2, 2),  }, 	/* FVco 840.000000 */
+	{ .frequency = 220000000,	.index = PLLVAL(0x66, 1, 2),  }, 	/* FVco 880.000000 */
+	{ .frequency = 230000000,	.index = PLLVAL(0x6b, 1, 2),  }, 	/* FVco 920.000000 */
+	{ .frequency = 240000000,	.index = PLLVAL(0x70, 1, 2),  }, 	/* FVco 960.000000 */
+	{ .frequency = 300000000,	.index = PLLVAL(0x75, 3, 1),  }, 	/* FVco 600.000000 */
+	{ .frequency = 310000000,	.index = PLLVAL(0x93, 4, 1),  }, 	/* FVco 620.000000 */
+	{ .frequency = 320000000,	.index = PLLVAL(0x98, 4, 1),  }, 	/* FVco 640.000000 */
+	{ .frequency = 330000000,	.index = PLLVAL(0x66, 2, 1),  }, 	/* FVco 660.000000 */
+	{ .frequency = 340000000,	.index = PLLVAL(0x4d, 1, 1),  }, 	/* FVco 680.000000 */
+	{ .frequency = 350000000,	.index = PLLVAL(0xa7, 4, 1),  }, 	/* FVco 700.000000 */
+	{ .frequency = 360000000,	.index = PLLVAL(0x70, 2, 1),  }, 	/* FVco 720.000000 */
+	{ .frequency = 370000000,	.index = PLLVAL(0xb1, 4, 1),  }, 	/* FVco 740.000000 */
+	{ .frequency = 380000000,	.index = PLLVAL(0x57, 1, 1),  }, 	/* FVco 760.000000 */
+	{ .frequency = 390000000,	.index = PLLVAL(0x7a, 2, 1),  }, 	/* FVco 780.000000 */
+	{ .frequency = 400000000,	.index = PLLVAL(0x5c, 1, 1),  }, 	/* FVco 800.000000 */
+};
+
+static int s3c2440_plls12_add(struct sys_device *dev)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+
+	xtal_clk = clk_get(NULL, "xtal");
+	if (IS_ERR(xtal_clk))
+		return PTR_ERR(xtal_clk);
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	if (xtal == 12000000) {
+		printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
+		return s3c_plltab_register(s3c2440_plls_12,
+					   ARRAY_SIZE(s3c2440_plls_12));
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_plls12_drv = {
+	.add	= s3c2440_plls12_add,
+};
+
+static int __init s3c2440_pll_12mhz(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv);
+
+}
+
+arch_initcall(s3c2440_pll_12mhz);
+
+static struct sysdev_driver s3c2442_plls12_drv = {
+	.add	= s3c2440_plls12_add,
+};
+
+static int __init s3c2442_pll_12mhz(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv);
+
+}
+
+arch_initcall(s3c2442_pll_12mhz);
diff --git a/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c b/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
new file mode 100644
index 0000000..7679af1
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
@@ -0,0 +1,127 @@
+/* arch/arm/plat-s3c24xx/s3c2440-pll-16934400.c
+ *
+ * Copyright (c) 2006-2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
+	{ .frequency = 78019200,	.index = PLLVAL(121, 5, 3), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 84067200,	.index = PLLVAL(131, 5, 3), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 90115200,	.index = PLLVAL(141, 5, 3), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 96163200,	.index = PLLVAL(151, 5, 3), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 102135600,	.index = PLLVAL(185, 6, 3), 	}, 	/* FVco 817.084800 */
+	{ .frequency = 108259200,	.index = PLLVAL(171, 5, 3), 	}, 	/* FVco 866.073600 */
+	{ .frequency = 114307200,	.index = PLLVAL(127, 3, 3), 	}, 	/* FVco 914.457600 */
+	{ .frequency = 120234240,	.index = PLLVAL(134, 3, 3), 	}, 	/* FVco 961.873920 */
+	{ .frequency = 126161280,	.index = PLLVAL(141, 3, 3), 	}, 	/* FVco 1009.290240 */
+	{ .frequency = 132088320,	.index = PLLVAL(148, 3, 3), 	}, 	/* FVco 1056.706560 */
+	{ .frequency = 138015360,	.index = PLLVAL(155, 3, 3), 	}, 	/* FVco 1104.122880 */
+	{ .frequency = 144789120,	.index = PLLVAL(163, 3, 3), 	}, 	/* FVco 1158.312960 */
+	{ .frequency = 150100363,	.index = PLLVAL(187, 9, 2), 	}, 	/* FVco 600.401454 */
+	{ .frequency = 156038400,	.index = PLLVAL(121, 5, 2), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 162086400,	.index = PLLVAL(126, 5, 2), 	}, 	/* FVco 648.345600 */
+	{ .frequency = 168134400,	.index = PLLVAL(131, 5, 2), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 174048000,	.index = PLLVAL(177, 7, 2), 	}, 	/* FVco 696.192000 */
+	{ .frequency = 180230400,	.index = PLLVAL(141, 5, 2), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 186278400,	.index = PLLVAL(124, 4, 2), 	}, 	/* FVco 745.113600 */
+	{ .frequency = 192326400,	.index = PLLVAL(151, 5, 2), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 198132480,	.index = PLLVAL(109, 3, 2), 	}, 	/* FVco 792.529920 */
+	{ .frequency = 204271200,	.index = PLLVAL(185, 6, 2), 	}, 	/* FVco 817.084800 */
+	{ .frequency = 210268800,	.index = PLLVAL(141, 4, 2), 	}, 	/* FVco 841.075200 */
+	{ .frequency = 216518400,	.index = PLLVAL(171, 5, 2), 	}, 	/* FVco 866.073600 */
+	{ .frequency = 222264000,	.index = PLLVAL(97, 2, 2), 	}, 	/* FVco 889.056000 */
+	{ .frequency = 228614400,	.index = PLLVAL(127, 3, 2), 	}, 	/* FVco 914.457600 */
+	{ .frequency = 234259200,	.index = PLLVAL(158, 4, 2), 	}, 	/* FVco 937.036800 */
+	{ .frequency = 240468480,	.index = PLLVAL(134, 3, 2), 	}, 	/* FVco 961.873920 */
+	{ .frequency = 246960000,	.index = PLLVAL(167, 4, 2), 	}, 	/* FVco 987.840000 */
+	{ .frequency = 252322560,	.index = PLLVAL(141, 3, 2), 	}, 	/* FVco 1009.290240 */
+	{ .frequency = 258249600,	.index = PLLVAL(114, 2, 2), 	}, 	/* FVco 1032.998400 */
+	{ .frequency = 264176640,	.index = PLLVAL(148, 3, 2), 	}, 	/* FVco 1056.706560 */
+	{ .frequency = 270950400,	.index = PLLVAL(120, 2, 2), 	}, 	/* FVco 1083.801600 */
+	{ .frequency = 276030720,	.index = PLLVAL(155, 3, 2), 	}, 	/* FVco 1104.122880 */
+	{ .frequency = 282240000,	.index = PLLVAL(92, 1, 2), 	}, 	/* FVco 1128.960000 */
+	{ .frequency = 289578240,	.index = PLLVAL(163, 3, 2), 	}, 	/* FVco 1158.312960 */
+	{ .frequency = 294235200,	.index = PLLVAL(131, 2, 2), 	}, 	/* FVco 1176.940800 */
+	{ .frequency = 300200727,	.index = PLLVAL(187, 9, 1), 	}, 	/* FVco 600.401454 */
+	{ .frequency = 306358690,	.index = PLLVAL(191, 9, 1), 	}, 	/* FVco 612.717380 */
+	{ .frequency = 312076800,	.index = PLLVAL(121, 5, 1), 	}, 	/* FVco 624.153600 */
+	{ .frequency = 318366720,	.index = PLLVAL(86, 3, 1), 	}, 	/* FVco 636.733440 */
+	{ .frequency = 324172800,	.index = PLLVAL(126, 5, 1), 	}, 	/* FVco 648.345600 */
+	{ .frequency = 330220800,	.index = PLLVAL(109, 4, 1), 	}, 	/* FVco 660.441600 */
+	{ .frequency = 336268800,	.index = PLLVAL(131, 5, 1), 	}, 	/* FVco 672.537600 */
+	{ .frequency = 342074880,	.index = PLLVAL(93, 3, 1), 	}, 	/* FVco 684.149760 */
+	{ .frequency = 348096000,	.index = PLLVAL(177, 7, 1), 	}, 	/* FVco 696.192000 */
+	{ .frequency = 355622400,	.index = PLLVAL(118, 4, 1), 	}, 	/* FVco 711.244800 */
+	{ .frequency = 360460800,	.index = PLLVAL(141, 5, 1), 	}, 	/* FVco 720.921600 */
+	{ .frequency = 366206400,	.index = PLLVAL(165, 6, 1), 	}, 	/* FVco 732.412800 */
+	{ .frequency = 372556800,	.index = PLLVAL(124, 4, 1), 	}, 	/* FVco 745.113600 */
+	{ .frequency = 378201600,	.index = PLLVAL(126, 4, 1), 	}, 	/* FVco 756.403200 */
+	{ .frequency = 384652800,	.index = PLLVAL(151, 5, 1), 	}, 	/* FVco 769.305600 */
+	{ .frequency = 391608000,	.index = PLLVAL(177, 6, 1), 	}, 	/* FVco 783.216000 */
+	{ .frequency = 396264960,	.index = PLLVAL(109, 3, 1), 	}, 	/* FVco 792.529920 */
+	{ .frequency = 402192000,	.index = PLLVAL(87, 2, 1), 	}, 	/* FVco 804.384000 */
+};
+
+static int s3c2440_plls169344_add(struct sys_device *dev)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+
+	xtal_clk = clk_get(NULL, "xtal");
+	if (IS_ERR(xtal_clk))
+		return PTR_ERR(xtal_clk);
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	if (xtal == 169344000) {
+		printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
+		return s3c_plltab_register(s3c2440_plls_169344,
+					   ARRAY_SIZE(s3c2440_plls_169344));
+	}
+
+	return 0;
+}
+
+static struct sysdev_driver s3c2440_plls169344_drv = {
+	.add	= s3c2440_plls169344_add,
+};
+
+static int __init s3c2440_pll_16934400(void)
+{
+	return sysdev_driver_register(&s3c2440_sysclass,
+				      &s3c2440_plls169344_drv);
+
+}
+
+arch_initcall(s3c2440_pll_16934400);
+
+static struct sysdev_driver s3c2442_plls169344_drv = {
+	.add	= s3c2440_plls169344_add,
+};
+
+static int __init s3c2442_pll_16934400(void)
+{
+	return sysdev_driver_register(&s3c2442_sysclass,
+				      &s3c2442_plls169344_drv);
+
+}
+
+arch_initcall(s3c2442_pll_16934400);
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
new file mode 100644
index 0000000..89fcf53
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
@@ -0,0 +1,38 @@
+/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpd8_9_10.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX SPI - gpio configuration for bus 1 on gpd8,9,10
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+#include <mach/spi.h>
+#include <mach/regs-gpio.h>
+
+void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
+					int enable)
+{
+
+	printk(KERN_INFO "%s(%d)\n", __func__, enable);
+	if (enable) {
+		s3c2410_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
+		s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
+		s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
+		s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
+		s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
+	} else {
+		s3c2410_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
+		s3c2410_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
+		s3c2410_gpio_pullup(S3C2410_GPD(10), 1);
+		s3c2410_gpio_pullup(S3C2410_GPD(9), 1);
+		s3c2410_gpio_pullup(S3C2410_GPD(8), 1);
+	}
+}
diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig
index 5ebd8b4..bcfa778 100644
--- a/arch/arm/plat-s3c64xx/Kconfig
+++ b/arch/arm/plat-s3c64xx/Kconfig
@@ -19,6 +19,7 @@ config PLAT_S3C64XX
 	select S3C_GPIO_PULL_UPDOWN
 	select S3C_GPIO_CFG_S3C24XX
 	select S3C_GPIO_CFG_S3C64XX
+	select S3C_DEV_NAND
 	select USB_ARCH_HAS_OHCI
 	help
 	  Base platform code for any Samsung S3C64XX device
diff --git a/arch/arm/plat-s3c64xx/Makefile b/arch/arm/plat-s3c64xx/Makefile
index 3c8882c..b85b435 100644
--- a/arch/arm/plat-s3c64xx/Makefile
+++ b/arch/arm/plat-s3c64xx/Makefile
@@ -40,4 +40,5 @@ obj-$(CONFIG_S3C64XX_DMA)	+= dma.o
 obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
 obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
 obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
-obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
\ No newline at end of file
+obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+obj-$(CONFIG_SND_S3C24XX_SOC) += dev-audio.o
diff --git a/arch/arm/plat-s3c64xx/dev-audio.c b/arch/arm/plat-s3c64xx/dev-audio.c
new file mode 100644
index 0000000..1322beb
--- /dev/null
+++ b/arch/arm/plat-s3c64xx/dev-audio.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-s3c/dev-audio.c
+ *
+ * Copyright 2009 Wolfson Microelectronics
+ *      Mark Brown <broonie@opensource.wolfsonmicro.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/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+
+static struct resource s3c64xx_iis0_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_IIS0,
+		.end   = S3C64XX_PA_IIS0 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device s3c64xx_device_iis0 = {
+	.name		  = "s3c64xx-iis",
+	.id		  = 0,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_iis0_resource),
+	.resource	  = s3c64xx_iis0_resource,
+};
+EXPORT_SYMBOL(s3c64xx_device_iis0);
+
+static struct resource s3c64xx_iis1_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_IIS1,
+		.end   = S3C64XX_PA_IIS1 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device s3c64xx_device_iis1 = {
+	.name		  = "s3c64xx-iis",
+	.id		  = 1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_iis1_resource),
+	.resource	  = s3c64xx_iis1_resource,
+};
+EXPORT_SYMBOL(s3c64xx_device_iis1);
+
+static struct resource s3c64xx_iisv4_resource[] = {
+	[0] = {
+		.start = S3C64XX_PA_IISV4,
+		.end   = S3C64XX_PA_IISV4 + 0x100 - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+struct platform_device s3c64xx_device_iisv4 = {
+	.name		  = "s3c64xx-iis-v4",
+	.id		  = -1,
+	.num_resources	  = ARRAY_SIZE(s3c64xx_iisv4_resource),
+	.resource	  = s3c64xx_iisv4_resource,
+};
+EXPORT_SYMBOL(s3c64xx_device_iisv4);
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
new file mode 100644
index 0000000..a8a711c
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -0,0 +1,50 @@
+# arch/arm/plat-s5pc1xx/Kconfig
+#
+# Copyright 2009 Samsung Electronics Co.
+#	Byungho Min <bhmin@samsung.com>
+#
+# Licensed under GPLv2
+
+config PLAT_S5PC1XX
+	bool
+	depends on ARCH_S5PC1XX
+	default y
+	select PLAT_S3C
+	select ARM_VIC
+	select NO_IOPORT
+	select ARCH_REQUIRE_GPIOLIB
+	select S3C_GPIO_TRACK
+	select S3C_GPIO_PULL_UPDOWN
+	help
+	  Base platform code for any Samsung S5PC1XX device
+
+if PLAT_S5PC1XX
+
+# Configuration options shared by all S3C64XX implementations
+
+config CPU_S5PC100_INIT
+	bool
+	help
+	  Common initialisation code for the S5PC1XX
+
+config CPU_S5PC100_CLOCK
+	bool
+	help
+	  Common clock support code for the S5PC1XX
+
+# platform specific device setup
+
+config S5PC100_SETUP_I2C0
+	bool
+	default y
+	help
+	  Common setup code for i2c bus 0.
+
+	  Note, currently since i2c0 is always compiled, this setup helper
+	  is always compiled with it.
+
+config S5PC100_SETUP_I2C1
+	bool
+	help
+	  Common setup code for i2c bus 1.
+endif
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
new file mode 100644
index 0000000..f1ecb2c
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -0,0 +1,26 @@
+# arch/arm/plat-s5pc1xx/Makefile
+#
+# Copyright 2009 Samsung Electronics Co.
+#
+# Licensed under GPLv2
+
+obj-y				:=
+obj-m				:=
+obj-n				:= dummy.o
+obj-				:=
+
+# Core files
+
+obj-y				+= dev-uart.o
+obj-y				+= cpu.o
+obj-y				+= irq.o
+
+# CPU support
+
+obj-$(CONFIG_CPU_S5PC100_INIT)	+= s5pc100-init.o
+obj-$(CONFIG_CPU_S5PC100_CLOCK)	+= s5pc100-clock.o
+
+# Device setup
+
+obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
new file mode 100644
index 0000000..715a733
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/cpu.c
@@ -0,0 +1,112 @@
+/* linux/arch/arm/plat-s5pc1xx/cpu.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX CPU Support
+ *
+ * Based on plat-s3c64xx/cpu.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/mach/map.h>
+
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+#include <plat/s5pc100.h>
+
+/* table of supported CPUs */
+
+static const char name_s5pc100[] = "S5PC100";
+
+static struct cpu_table cpu_ids[] __initdata = {
+	{
+		.idcode		= 0x43100000,
+		.idmask		= 0xfffff000,
+		.map_io		= s5pc100_map_io,
+		.init_clocks	= s5pc100_init_clocks,
+		.init_uarts	= s5pc100_init_uarts,
+		.init		= s5pc100_init,
+		.name		= name_s5pc100,
+	},
+};
+/* minimal IO mapping */
+
+/* see notes on uart map in arch/arm/mach-s5pc100/include/mach/debug-macro.S */
+#define UART_OFFS (S3C_PA_UART & 0xffff)
+
+static struct map_desc s5pc1xx_iodesc[] __initdata = {
+	{
+		.virtual	= (unsigned long)S5PC1XX_VA_CHIPID,
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_CHIPID),
+		.length		= SZ_16,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_CLK,
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_CLK),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_PWR,
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_PWR),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)(S5PC1XX_VA_UART),
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_UART),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_VIC(0),
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_VIC(0)),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_VIC(1),
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_VIC(1)),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_VIC(2),
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_VIC(2)),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}, {
+		.virtual	= (unsigned long)S5PC1XX_VA_TIMER,
+		.pfn		= __phys_to_pfn(S5PC1XX_PA_TIMER),
+		.length		= SZ_256,
+		.type		= MT_DEVICE,
+	},
+};
+
+/* read cpu identification code */
+
+void __init s5pc1xx_init_io(struct map_desc *mach_desc, int size)
+{
+	unsigned long idcode;
+
+	/* initialise the io descriptors we need for initialisation */
+	iotable_init(s5pc1xx_iodesc, ARRAY_SIZE(s5pc1xx_iodesc));
+	iotable_init(mach_desc, size);
+
+	idcode = __raw_readl(S5PC1XX_VA_CHIPID);
+	s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
diff --git a/arch/arm/plat-s5pc1xx/dev-uart.c b/arch/arm/plat-s5pc1xx/dev-uart.c
new file mode 100644
index 0000000..f749bc5
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/dev-uart.c
@@ -0,0 +1,174 @@
+/* linux/arch/arm/plat-s5pc1xx/dev-uart.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * Based on plat-s3c64xx/dev-uart.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+/* Serial port registrations */
+
+/* 64xx uarts are closer together */
+
+static struct resource s5pc1xx_uart0_resource[] = {
+	[0] = {
+		.start	= S3C_PA_UART0,
+		.end	= S3C_PA_UART0 + 0x100,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX0,
+		.end	= IRQ_S3CUART_RX0,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX0,
+		.end	= IRQ_S3CUART_TX0,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR0,
+		.end	= IRQ_S3CUART_ERR0,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct resource s5pc1xx_uart1_resource[] = {
+	[0] = {
+		.start = S3C_PA_UART1,
+		.end   = S3C_PA_UART1 + 0x100,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX1,
+		.end	= IRQ_S3CUART_RX1,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX1,
+		.end	= IRQ_S3CUART_TX1,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR1,
+		.end	= IRQ_S3CUART_ERR1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource s5pc1xx_uart2_resource[] = {
+	[0] = {
+		.start = S3C_PA_UART2,
+		.end   = S3C_PA_UART2 + 0x100,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX2,
+		.end	= IRQ_S3CUART_RX2,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX2,
+		.end	= IRQ_S3CUART_TX2,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR2,
+		.end	= IRQ_S3CUART_ERR2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct resource s5pc1xx_uart3_resource[] = {
+	[0] = {
+		.start = S3C_PA_UART3,
+		.end   = S3C_PA_UART3 + 0x100,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_S3CUART_RX3,
+		.end	= IRQ_S3CUART_RX3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= IRQ_S3CUART_TX3,
+		.end	= IRQ_S3CUART_TX3,
+		.flags	= IORESOURCE_IRQ,
+
+	},
+	[3] = {
+		.start	= IRQ_S3CUART_ERR3,
+		.end	= IRQ_S3CUART_ERR3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+
+struct s3c24xx_uart_resources s5pc1xx_uart_resources[] __initdata = {
+	[0] = {
+		.resources	= s5pc1xx_uart0_resource,
+		.nr_resources	= ARRAY_SIZE(s5pc1xx_uart0_resource),
+	},
+	[1] = {
+		.resources	= s5pc1xx_uart1_resource,
+		.nr_resources	= ARRAY_SIZE(s5pc1xx_uart1_resource),
+	},
+	[2] = {
+		.resources	= s5pc1xx_uart2_resource,
+		.nr_resources	= ARRAY_SIZE(s5pc1xx_uart2_resource),
+	},
+	[3] = {
+		.resources	= s5pc1xx_uart3_resource,
+		.nr_resources	= ARRAY_SIZE(s5pc1xx_uart3_resource),
+	},
+};
+
+/* uart devices */
+
+static struct platform_device s3c24xx_uart_device0 = {
+	.id		= 0,
+};
+
+static struct platform_device s3c24xx_uart_device1 = {
+	.id		= 1,
+};
+
+static struct platform_device s3c24xx_uart_device2 = {
+	.id		= 2,
+};
+
+static struct platform_device s3c24xx_uart_device3 = {
+	.id		= 3,
+};
+
+struct platform_device *s3c24xx_uart_src[4] = {
+	&s3c24xx_uart_device0,
+	&s3c24xx_uart_device1,
+	&s3c24xx_uart_device2,
+	&s3c24xx_uart_device3,
+};
+
+struct platform_device *s3c24xx_uart_devs[4] = {
+};
+
diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
new file mode 100644
index 0000000..f07d8c3
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
@@ -0,0 +1,182 @@
+/* linux/arch/arm/plat-s5pc1xx/include/plat/irqs.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX - Common IRQ support
+ *
+ * Based on plat-s3c64xx/include/plat/irqs.h
+ */
+
+#ifndef __ASM_PLAT_S5PC1XX_IRQS_H
+#define __ASM_PLAT_S5PC1XX_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S3C_IRQ_OFFSET		(32)
+
+#define S3C_IRQ(x)		((x) + S3C_IRQ_OFFSET)
+
+#define S3C_VIC0_BASE		S3C_IRQ(0)
+#define S3C_VIC1_BASE		S3C_IRQ(32)
+#define S3C_VIC2_BASE		S3C_IRQ(64)
+
+/* UART interrupts, each UART has 4 intterupts per channel so
+ * use the space between the ISA and S3C main interrupts. Note, these
+ * are not in the same order as the S3C24XX series! */
+
+#define IRQ_S3CUART_BASE0	(16)
+#define IRQ_S3CUART_BASE1	(20)
+#define IRQ_S3CUART_BASE2	(24)
+#define IRQ_S3CUART_BASE3	(28)
+
+#define UART_IRQ_RXD		(0)
+#define UART_IRQ_ERR		(1)
+#define UART_IRQ_TXD		(2)
+#define UART_IRQ_MODEM		(3)
+
+#define IRQ_S3CUART_RX0		(IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX0		(IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR0	(IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX1		(IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX1		(IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR1	(IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX2		(IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX2		(IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR2	(IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX3		(IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX3		(IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR3	(IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
+
+/* VIC based IRQs */
+
+#define S5PC1XX_IRQ_VIC0(x)	(S3C_VIC0_BASE + (x))
+#define S5PC1XX_IRQ_VIC1(x)	(S3C_VIC1_BASE + (x))
+#define S5PC1XX_IRQ_VIC2(x)	(S3C_VIC2_BASE + (x))
+
+/*
+ * VIC0: system, DMA, timer
+ */
+#define IRQ_EINT0		S5PC1XX_IRQ_VIC0(0)
+#define IRQ_EINT1		S5PC1XX_IRQ_VIC0(1)
+#define IRQ_EINT2		S5PC1XX_IRQ_VIC0(2)
+#define IRQ_EINT3		S5PC1XX_IRQ_VIC0(3)
+#define IRQ_EINT4		S5PC1XX_IRQ_VIC0(4)
+#define IRQ_EINT5		S5PC1XX_IRQ_VIC0(5)
+#define IRQ_EINT6		S5PC1XX_IRQ_VIC0(6)
+#define IRQ_EINT7		S5PC1XX_IRQ_VIC0(7)
+#define IRQ_EINT8		S5PC1XX_IRQ_VIC0(8)
+#define IRQ_EINT9		S5PC1XX_IRQ_VIC0(9)
+#define IRQ_EINT10		S5PC1XX_IRQ_VIC0(10)
+#define IRQ_EINT11		S5PC1XX_IRQ_VIC0(11)
+#define IRQ_EINT12		S5PC1XX_IRQ_VIC0(12)
+#define IRQ_EINT13		S5PC1XX_IRQ_VIC0(13)
+#define IRQ_EINT14		S5PC1XX_IRQ_VIC0(14)
+#define IRQ_EINT15		S5PC1XX_IRQ_VIC0(15)
+#define IRQ_EINT16_31		S5PC1XX_IRQ_VIC0(16)
+#define IRQ_BATF		S5PC1XX_IRQ_VIC0(17)
+#define IRQ_MDMA		S5PC1XX_IRQ_VIC0(18)
+#define IRQ_PDMA0		S5PC1XX_IRQ_VIC0(19)
+#define IRQ_PDMA1		S5PC1XX_IRQ_VIC0(20)
+#define IRQ_TIMER0		S5PC1XX_IRQ_VIC0(21)
+#define IRQ_TIMER1		S5PC1XX_IRQ_VIC0(22)
+#define IRQ_TIMER2		S5PC1XX_IRQ_VIC0(23)
+#define IRQ_TIMER3		S5PC1XX_IRQ_VIC0(24)
+#define IRQ_TIMER4		S5PC1XX_IRQ_VIC0(25)
+#define IRQ_SYSTIMER		S5PC1XX_IRQ_VIC0(26)
+#define IRQ_WDT			S5PC1XX_IRQ_VIC0(27)
+#define IRQ_RTC_ALARM		S5PC1XX_IRQ_VIC0(28)
+#define IRQ_RTC_TIC		S5PC1XX_IRQ_VIC0(29)
+#define IRQ_GPIOINT		S5PC1XX_IRQ_VIC0(30)
+
+/*
+ * VIC1: ARM, power, memory, connectivity
+ */
+#define IRQ_CORTEX0		S5PC1XX_IRQ_VIC1(0)
+#define IRQ_CORTEX1		S5PC1XX_IRQ_VIC1(1)
+#define IRQ_CORTEX2		S5PC1XX_IRQ_VIC1(2)
+#define IRQ_CORTEX3		S5PC1XX_IRQ_VIC1(3)
+#define IRQ_CORTEX4		S5PC1XX_IRQ_VIC1(4)
+#define IRQ_IEMAPC		S5PC1XX_IRQ_VIC1(5)
+#define IRQ_IEMIEC		S5PC1XX_IRQ_VIC1(6)
+#define IRQ_ONENAND		S5PC1XX_IRQ_VIC1(7)
+#define IRQ_NFC			S5PC1XX_IRQ_VIC1(8)
+#define IRQ_CFC			S5PC1XX_IRQ_VIC1(9)
+#define IRQ_UART0		S5PC1XX_IRQ_VIC1(10)
+#define IRQ_UART1		S5PC1XX_IRQ_VIC1(11)
+#define IRQ_UART2		S5PC1XX_IRQ_VIC1(12)
+#define IRQ_UART3		S5PC1XX_IRQ_VIC1(13)
+#define IRQ_IIC			S5PC1XX_IRQ_VIC1(14)
+#define IRQ_SPI0		S5PC1XX_IRQ_VIC1(15)
+#define IRQ_SPI1		S5PC1XX_IRQ_VIC1(16)
+#define IRQ_SPI2		S5PC1XX_IRQ_VIC1(17)
+#define IRQ_IRDA		S5PC1XX_IRQ_VIC1(18)
+#define IRQ_CAN0		S5PC1XX_IRQ_VIC1(19)
+#define IRQ_CAN1		S5PC1XX_IRQ_VIC1(20)
+#define IRQ_HSIRX		S5PC1XX_IRQ_VIC1(21)
+#define IRQ_HSITX		S5PC1XX_IRQ_VIC1(22)
+#define IRQ_UHOST		S5PC1XX_IRQ_VIC1(23)
+#define IRQ_OTG			S5PC1XX_IRQ_VIC1(24)
+#define IRQ_MSM			S5PC1XX_IRQ_VIC1(25)
+#define IRQ_HSMMC0		S5PC1XX_IRQ_VIC1(26)
+#define IRQ_HSMMC1		S5PC1XX_IRQ_VIC1(27)
+#define IRQ_HSMMC2		S5PC1XX_IRQ_VIC1(28)
+#define IRQ_MIPICSI		S5PC1XX_IRQ_VIC1(29)
+#define IRQ_MIPIDSI		S5PC1XX_IRQ_VIC1(30)
+
+/*
+ * VIC2: multimedia, audio, security
+ */
+#define IRQ_LCD0		S5PC1XX_IRQ_VIC2(0)
+#define IRQ_LCD1		S5PC1XX_IRQ_VIC2(1)
+#define IRQ_LCD2		S5PC1XX_IRQ_VIC2(2)
+#define IRQ_LCD3		S5PC1XX_IRQ_VIC2(3)
+#define IRQ_ROTATOR		S5PC1XX_IRQ_VIC2(4)
+#define IRQ_FIMC0		S5PC1XX_IRQ_VIC2(5)
+#define IRQ_FIMC1		S5PC1XX_IRQ_VIC2(6)
+#define IRQ_FIMC2		S5PC1XX_IRQ_VIC2(7)
+#define IRQ_JPEG		S5PC1XX_IRQ_VIC2(8)
+#define IRQ_2D			S5PC1XX_IRQ_VIC2(9)
+#define IRQ_3D			S5PC1XX_IRQ_VIC2(10)
+#define IRQ_MIXER		S5PC1XX_IRQ_VIC2(11)
+#define IRQ_HDMI		S5PC1XX_IRQ_VIC2(12)
+#define IRQ_IIC1		S5PC1XX_IRQ_VIC2(13)
+#define IRQ_MFC			S5PC1XX_IRQ_VIC2(14)
+#define IRQ_TVENC		S5PC1XX_IRQ_VIC2(15)
+#define IRQ_I2S0		S5PC1XX_IRQ_VIC2(16)
+#define IRQ_I2S1		S5PC1XX_IRQ_VIC2(17)
+#define IRQ_I2S2		S5PC1XX_IRQ_VIC2(18)
+#define IRQ_AC97		S5PC1XX_IRQ_VIC2(19)
+#define IRQ_PCM0		S5PC1XX_IRQ_VIC2(20)
+#define IRQ_PCM1		S5PC1XX_IRQ_VIC2(21)
+#define IRQ_SPDIF		S5PC1XX_IRQ_VIC2(22)
+#define IRQ_ADC			S5PC1XX_IRQ_VIC2(23)
+#define IRQ_PENDN		S5PC1XX_IRQ_VIC2(24)
+#define IRQ_TC			IRQ_PENDN
+#define IRQ_KEYPAD		S5PC1XX_IRQ_VIC2(25)
+#define IRQ_CG			S5PC1XX_IRQ_VIC2(26)
+#define IRQ_SEC			S5PC1XX_IRQ_VIC2(27)
+#define IRQ_SECRX		S5PC1XX_IRQ_VIC2(28)
+#define IRQ_SECTX		S5PC1XX_IRQ_VIC2(29)
+#define IRQ_SDMIRQ		S5PC1XX_IRQ_VIC2(30)
+#define IRQ_SDMFIQ		S5PC1XX_IRQ_VIC2(31)
+
+#define S3C_IRQ_EINT_BASE	(IRQ_SDMFIQ + 1)
+
+#define S3C_EINT(x)		((x) + S3C_IRQ_EINT_BASE)
+#define IRQ_EINT(x)		S3C_EINT(x)
+
+#define NR_IRQS 		(IRQ_EINT(31)+1)
+
+#endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
+
diff --git a/arch/arm/plat-s5pc1xx/include/plat/pll.h b/arch/arm/plat-s5pc1xx/include/plat/pll.h
new file mode 100644
index 0000000..21afef1
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/pll.h
@@ -0,0 +1,38 @@
+/* arch/arm/plat-s5pc1xx/include/plat/pll.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX PLL code
+ *
+ * Based on plat-s3c64xx/include/plat/pll.h
+ *
+ * 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.
+*/
+
+#define S5P_PLL_MDIV_MASK	((1 << (25-16+1)) - 1)
+#define S5P_PLL_PDIV_MASK	((1 << (13-8+1)) - 1)
+#define S5P_PLL_SDIV_MASK	((1 << (2-0+1)) - 1)
+#define S5P_PLL_MDIV_SHIFT	(16)
+#define S5P_PLL_PDIV_SHIFT	(8)
+#define S5P_PLL_SDIV_SHIFT	(0)
+
+#include <asm/div64.h>
+
+static inline unsigned long s5pc1xx_get_pll(unsigned long baseclk,
+					    u32 pllcon)
+{
+	u32 mdiv, pdiv, sdiv;
+	u64 fvco = baseclk;
+
+	mdiv = (pllcon >> S5P_PLL_MDIV_SHIFT) & S5P_PLL_MDIV_MASK;
+	pdiv = (pllcon >> S5P_PLL_PDIV_SHIFT) & S5P_PLL_PDIV_MASK;
+	sdiv = (pllcon >> S5P_PLL_SDIV_SHIFT) & S5P_PLL_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
new file mode 100644
index 0000000..75c8390
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
@@ -0,0 +1,421 @@
+/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX clock register definitions
+ *
+ * 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 __PLAT_REGS_CLOCK_H
+#define __PLAT_REGS_CLOCK_H __FILE__
+
+#define S5PC1XX_CLKREG(x)		(S5PC1XX_VA_CLK + (x))
+
+#define S5PC1XX_APLL_LOCK		S5PC1XX_CLKREG(0x00)
+#define S5PC1XX_MPLL_LOCK		S5PC1XX_CLKREG(0x04)
+#define S5PC1XX_EPLL_LOCK		S5PC1XX_CLKREG(0x08)
+#define S5PC100_HPLL_LOCK		S5PC1XX_CLKREG(0x0C)
+
+#define S5PC1XX_APLL_CON		S5PC1XX_CLKREG(0x100)
+#define S5PC1XX_MPLL_CON		S5PC1XX_CLKREG(0x104)
+#define S5PC1XX_EPLL_CON		S5PC1XX_CLKREG(0x108)
+#define S5PC100_HPLL_CON		S5PC1XX_CLKREG(0x10C)
+
+#define S5PC1XX_CLK_SRC0		S5PC1XX_CLKREG(0x200)
+#define S5PC1XX_CLK_SRC1		S5PC1XX_CLKREG(0x204)
+#define S5PC1XX_CLK_SRC2		S5PC1XX_CLKREG(0x208)
+#define S5PC1XX_CLK_SRC3		S5PC1XX_CLKREG(0x20C)
+
+#define S5PC1XX_CLK_DIV0		S5PC1XX_CLKREG(0x300)
+#define S5PC1XX_CLK_DIV1		S5PC1XX_CLKREG(0x304)
+#define S5PC1XX_CLK_DIV2		S5PC1XX_CLKREG(0x308)
+#define S5PC1XX_CLK_DIV3		S5PC1XX_CLKREG(0x30C)
+#define S5PC1XX_CLK_DIV4		S5PC1XX_CLKREG(0x310)
+
+#define S5PC100_CLK_OUT			S5PC1XX_CLKREG(0x400)
+
+#define S5PC100_CLKGATE_D00		S5PC1XX_CLKREG(0x500)
+#define S5PC100_CLKGATE_D01		S5PC1XX_CLKREG(0x504)
+#define S5PC100_CLKGATE_D02		S5PC1XX_CLKREG(0x508)
+
+#define S5PC100_CLKGATE_D10		S5PC1XX_CLKREG(0x520)
+#define S5PC100_CLKGATE_D11		S5PC1XX_CLKREG(0x524)
+#define S5PC100_CLKGATE_D12		S5PC1XX_CLKREG(0x528)
+#define S5PC100_CLKGATE_D13		S5PC1XX_CLKREG(0x52C)
+#define S5PC100_CLKGATE_D14		S5PC1XX_CLKREG(0x530)
+#define S5PC100_CLKGATE_D15		S5PC1XX_CLKREG(0x534)
+
+#define S5PC100_CLKGATE_D20		S5PC1XX_CLKREG(0x540)
+
+#define S5PC100_SCLKGATE0		S5PC1XX_CLKREG(0x560)
+#define S5PC100_SCLKGATE1		S5PC1XX_CLKREG(0x564)
+
+#define S5PC100_OTHERS          S5PC1XX_CLKREG(0x8200)
+
+#define S5PC1XX_EPLL_EN     (1<<31)
+#define S5PC1XX_EPLL_MASK   0xffffffff
+#define S5PC1XX_EPLLVAL(_m, _p, _s)   ((_m) << 16 | ((_p) << 8) | ((_s)))
+
+/* CLKSRC0 */
+#define S5PC1XX_CLKSRC0_APLL_MASK		(0x1<<0)
+#define S5PC1XX_CLKSRC0_APLL_SHIFT		(0)
+#define S5PC1XX_CLKSRC0_MPLL_MASK		(0x1<<4)
+#define S5PC1XX_CLKSRC0_MPLL_SHIFT		(4)
+#define S5PC1XX_CLKSRC0_EPLL_MASK		(0x1<<8)
+#define S5PC1XX_CLKSRC0_EPLL_SHIFT		(8)
+#define S5PC100_CLKSRC0_HPLL_MASK		(0x1<<12)
+#define S5PC100_CLKSRC0_HPLL_SHIFT		(12)
+#define S5PC100_CLKSRC0_AMMUX_MASK		(0x1<<16)
+#define S5PC100_CLKSRC0_AMMUX_SHIFT		(16)
+#define S5PC100_CLKSRC0_HREF_MASK		(0x1<<20)
+#define S5PC100_CLKSRC0_HREF_SHIFT		(20)
+#define S5PC1XX_CLKSRC0_ONENAND_MASK	(0x1<<24)
+#define S5PC1XX_CLKSRC0_ONENAND_SHIFT	(24)
+
+
+/* CLKSRC1 */
+#define S5PC100_CLKSRC1_UART_MASK		(0x1<<0)
+#define S5PC100_CLKSRC1_UART_SHIFT		(0)
+#define S5PC100_CLKSRC1_SPI0_MASK		(0x3<<4)
+#define S5PC100_CLKSRC1_SPI0_SHIFT		(4)
+#define S5PC100_CLKSRC1_SPI1_MASK		(0x3<<8)
+#define S5PC100_CLKSRC1_SPI1_SHIFT		(8)
+#define S5PC100_CLKSRC1_SPI2_MASK		(0x3<<12)
+#define S5PC100_CLKSRC1_SPI2_SHIFT		(12)
+#define S5PC100_CLKSRC1_IRDA_MASK		(0x3<<16)
+#define S5PC100_CLKSRC1_IRDA_SHIFT		(16)
+#define S5PC100_CLKSRC1_UHOST_MASK		(0x3<<20)
+#define S5PC100_CLKSRC1_UHOST_SHIFT		(20)
+#define S5PC100_CLKSRC1_CLK48M_MASK		(0x1<<24)
+#define S5PC100_CLKSRC1_CLK48M_SHIFT	(24)
+
+/* CLKSRC2 */
+#define S5PC100_CLKSRC2_MMC0_MASK		(0x3<<0)
+#define S5PC100_CLKSRC2_MMC0_SHIFT		(0)
+#define S5PC100_CLKSRC2_MMC1_MASK		(0x3<<4)
+#define S5PC100_CLKSRC2_MMC1_SHIFT		(4)
+#define S5PC100_CLKSRC2_MMC2_MASK		(0x3<<8)
+#define S5PC100_CLKSRC2_MMC2_SHIFT		(8)
+#define S5PC100_CLKSRC2_LCD_MASK		(0x3<<12)
+#define S5PC100_CLKSRC2_LCD_SHIFT		(12)
+#define S5PC100_CLKSRC2_FIMC0_MASK		(0x3<<16)
+#define S5PC100_CLKSRC2_FIMC0_SHIFT		(16)
+#define S5PC100_CLKSRC2_FIMC1_MASK		(0x3<<20)
+#define S5PC100_CLKSRC2_FIMC1_SHIFT		(20)
+#define S5PC100_CLKSRC2_FIMC2_MASK		(0x3<<24)
+#define S5PC100_CLKSRC2_FIMC2_SHIFT		(24)
+#define S5PC100_CLKSRC2_MIXER_MASK		(0x3<<28)
+#define S5PC100_CLKSRC2_MIXER_SHIFT		(28)
+
+/* CLKSRC3 */
+#define S5PC100_CLKSRC3_PWI_MASK		(0x3<<0)
+#define S5PC100_CLKSRC3_PWI_SHIFT		(0)
+#define S5PC100_CLKSRC3_HCLKD2_MASK		(0x1<<4)
+#define S5PC100_CLKSRC3_HCLKD2_SHIFT	(4)
+#define S5PC100_CLKSRC3_I2SD2_MASK		(0x3<<8)
+#define S5PC100_CLKSRC3_I2SD2_SHIFT		(8)
+#define S5PC100_CLKSRC3_AUDIO0_MASK		(0x7<<12)
+#define S5PC100_CLKSRC3_AUDIO0_SHIFT	(12)
+#define S5PC100_CLKSRC3_AUDIO1_MASK		(0x7<<16)
+#define S5PC100_CLKSRC3_AUDIO1_SHIFT	(16)
+#define S5PC100_CLKSRC3_AUDIO2_MASK		(0x7<<20)
+#define S5PC100_CLKSRC3_AUDIO2_SHIFT	(20)
+#define S5PC100_CLKSRC3_SPDIF_MASK		(0x3<<24)
+#define S5PC100_CLKSRC3_SPDIF_SHIFT		(24)
+
+
+/* CLKDIV0 */
+#define S5PC1XX_CLKDIV0_APLL_MASK		(0x1<<0)
+#define S5PC1XX_CLKDIV0_APLL_SHIFT		(0)
+#define S5PC100_CLKDIV0_ARM_MASK		(0x7<<4)
+#define S5PC100_CLKDIV0_ARM_SHIFT		(4)
+#define S5PC100_CLKDIV0_D0_MASK		(0x7<<8)
+#define S5PC100_CLKDIV0_D0_SHIFT		(8)
+#define S5PC100_CLKDIV0_PCLKD0_MASK		(0x7<<12)
+#define S5PC100_CLKDIV0_PCLKD0_SHIFT	(12)
+#define S5PC100_CLKDIV0_SECSS_MASK		(0x7<<16)
+#define S5PC100_CLKDIV0_SECSS_SHIFT		(16)
+
+/* CLKDIV1 */
+#define S5PC100_CLKDIV1_AM_MASK		(0x7<<0)
+#define S5PC100_CLKDIV1_AM_SHIFT		(0)
+#define S5PC100_CLKDIV1_MPLL_MASK		(0x3<<4)
+#define S5PC100_CLKDIV1_MPLL_SHIFT		(4)
+#define S5PC100_CLKDIV1_MPLL2_MASK		(0x1<<8)
+#define S5PC100_CLKDIV1_MPLL2_SHIFT		(8)
+#define S5PC100_CLKDIV1_D1_MASK		(0x7<<12)
+#define S5PC100_CLKDIV1_D1_SHIFT		(12)
+#define S5PC100_CLKDIV1_PCLKD1_MASK		(0x7<<16)
+#define S5PC100_CLKDIV1_PCLKD1_SHIFT	(16)
+#define S5PC100_CLKDIV1_ONENAND_MASK	(0x3<<20)
+#define S5PC100_CLKDIV1_ONENAND_SHIFT	(20)
+#define S5PC100_CLKDIV1_CAM_MASK		(0x1F<<24)
+#define S5PC100_CLKDIV1_CAM_SHIFT		(24)
+
+/* CLKDIV2 */
+#define S5PC100_CLKDIV2_UART_MASK		(0x7<<0)
+#define S5PC100_CLKDIV2_UART_SHIFT		(0)
+#define S5PC100_CLKDIV2_SPI0_MASK		(0xf<<4)
+#define S5PC100_CLKDIV2_SPI0_SHIFT		(4)
+#define S5PC100_CLKDIV2_SPI1_MASK		(0xf<<8)
+#define S5PC100_CLKDIV2_SPI1_SHIFT		(8)
+#define S5PC100_CLKDIV2_SPI2_MASK		(0xf<<12)
+#define S5PC100_CLKDIV2_SPI2_SHIFT		(12)
+#define S5PC100_CLKDIV2_IRDA_MASK		(0xf<<16)
+#define S5PC100_CLKDIV2_IRDA_SHIFT		(16)
+#define S5PC100_CLKDIV2_UHOST_MASK		(0xf<<20)
+#define S5PC100_CLKDIV2_UHOST_SHIFT		(20)
+
+/* CLKDIV3 */
+#define S5PC100_CLKDIV3_MMC0_MASK		(0xf<<0)
+#define S5PC100_CLKDIV3_MMC0_SHIFT		(0)
+#define S5PC100_CLKDIV3_MMC1_MASK		(0xf<<4)
+#define S5PC100_CLKDIV3_MMC1_SHIFT		(4)
+#define S5PC100_CLKDIV3_MMC2_MASK		(0xf<<8)
+#define S5PC100_CLKDIV3_MMC2_SHIFT		(8)
+#define S5PC100_CLKDIV3_LCD_MASK		(0xf<<12)
+#define S5PC100_CLKDIV3_LCD_SHIFT		(12)
+#define S5PC100_CLKDIV3_FIMC0_MASK		(0xf<<16)
+#define S5PC100_CLKDIV3_FIMC0_SHIFT		(16)
+#define S5PC100_CLKDIV3_FIMC1_MASK		(0xf<<20)
+#define S5PC100_CLKDIV3_FIMC1_SHIFT		(20)
+#define S5PC100_CLKDIV3_FIMC2_MASK		(0xf<<24)
+#define S5PC100_CLKDIV3_FIMC2_SHIFT		(24)
+#define S5PC100_CLKDIV3_HDMI_MASK		(0xf<<28)
+#define S5PC100_CLKDIV3_HDMI_SHIFT		(28)
+
+/* CLKDIV4 */
+#define S5PC100_CLKDIV4_PWI_MASK		(0x7<<0)
+#define S5PC100_CLKDIV4_PWI_SHIFT		(0)
+#define S5PC100_CLKDIV4_HCLKD2_MASK		(0x7<<4)
+#define S5PC100_CLKDIV4_HCLKD2_SHIFT	(4)
+#define S5PC100_CLKDIV4_I2SD2_MASK		(0xf<<8)
+#define S5PC100_CLKDIV4_I2SD2_SHIFT		(8)
+#define S5PC100_CLKDIV4_AUDIO0_MASK		(0xf<<12)
+#define S5PC100_CLKDIV4_AUDIO0_SHIFT	(12)
+#define S5PC100_CLKDIV4_AUDIO1_MASK		(0xf<<16)
+#define S5PC100_CLKDIV4_AUDIO1_SHIFT	(16)
+#define S5PC100_CLKDIV4_AUDIO2_MASK		(0xf<<20)
+#define S5PC100_CLKDIV4_AUDIO2_SHIFT	(20)
+
+
+/* HCLKD0/PCLKD0 Clock Gate 0 Registers */
+#define S5PC100_CLKGATE_D00_INTC		(1<<0)
+#define S5PC100_CLKGATE_D00_TZIC		(1<<1)
+#define S5PC100_CLKGATE_D00_CFCON		(1<<2)
+#define S5PC100_CLKGATE_D00_MDMA		(1<<3)
+#define S5PC100_CLKGATE_D00_G2D		(1<<4)
+#define S5PC100_CLKGATE_D00_SECSS		(1<<5)
+#define S5PC100_CLKGATE_D00_CSSYS		(1<<6)
+
+/* HCLKD0/PCLKD0 Clock Gate 1 Registers */
+#define S5PC100_CLKGATE_D01_DMC		(1<<0)
+#define S5PC100_CLKGATE_D01_SROMC		(1<<1)
+#define S5PC100_CLKGATE_D01_ONENAND		(1<<2)
+#define S5PC100_CLKGATE_D01_NFCON		(1<<3)
+#define S5PC100_CLKGATE_D01_INTMEM		(1<<4)
+#define S5PC100_CLKGATE_D01_EBI		(1<<5)
+
+/* PCLKD0 Clock Gate 2 Registers */
+#define S5PC100_CLKGATE_D02_SECKEY		(1<<1)
+#define S5PC100_CLKGATE_D02_SDM		(1<<2)
+
+/* HCLKD1/PCLKD1 Clock Gate 0 Registers */
+#define S5PC100_CLKGATE_D10_PDMA0		(1<<0)
+#define S5PC100_CLKGATE_D10_PDMA1		(1<<1)
+#define S5PC100_CLKGATE_D10_USBHOST		(1<<2)
+#define S5PC100_CLKGATE_D10_USBOTG		(1<<3)
+#define S5PC100_CLKGATE_D10_MODEMIF		(1<<4)
+#define S5PC100_CLKGATE_D10_HSMMC0		(1<<5)
+#define S5PC100_CLKGATE_D10_HSMMC1		(1<<6)
+#define S5PC100_CLKGATE_D10_HSMMC2		(1<<7)
+
+/* HCLKD1/PCLKD1 Clock Gate 1 Registers */
+#define S5PC100_CLKGATE_D11_LCD		(1<<0)
+#define S5PC100_CLKGATE_D11_ROTATOR		(1<<1)
+#define S5PC100_CLKGATE_D11_FIMC0		(1<<2)
+#define S5PC100_CLKGATE_D11_FIMC1		(1<<3)
+#define S5PC100_CLKGATE_D11_FIMC2		(1<<4)
+#define S5PC100_CLKGATE_D11_JPEG		(1<<5)
+#define S5PC100_CLKGATE_D11_DSI		(1<<6)
+#define S5PC100_CLKGATE_D11_CSI		(1<<7)
+#define S5PC100_CLKGATE_D11_G3D		(1<<8)
+
+/* HCLKD1/PCLKD1 Clock Gate 2 Registers */
+#define S5PC100_CLKGATE_D12_TV		(1<<0)
+#define S5PC100_CLKGATE_D12_VP		(1<<1)
+#define S5PC100_CLKGATE_D12_MIXER		(1<<2)
+#define S5PC100_CLKGATE_D12_HDMI		(1<<3)
+#define S5PC100_CLKGATE_D12_MFC		(1<<4)
+
+/* HCLKD1/PCLKD1 Clock Gate 3 Registers */
+#define S5PC100_CLKGATE_D13_CHIPID		(1<<0)
+#define S5PC100_CLKGATE_D13_GPIO		(1<<1)
+#define S5PC100_CLKGATE_D13_APC		(1<<2)
+#define S5PC100_CLKGATE_D13_IEC		(1<<3)
+#define S5PC100_CLKGATE_D13_PWM		(1<<6)
+#define S5PC100_CLKGATE_D13_SYSTIMER	(1<<7)
+#define S5PC100_CLKGATE_D13_WDT		(1<<8)
+#define S5PC100_CLKGATE_D13_RTC		(1<<9)
+
+/* HCLKD1/PCLKD1 Clock Gate 4 Registers */
+#define S5PC100_CLKGATE_D14_UART0		(1<<0)
+#define S5PC100_CLKGATE_D14_UART1		(1<<1)
+#define S5PC100_CLKGATE_D14_UART2		(1<<2)
+#define S5PC100_CLKGATE_D14_UART3		(1<<3)
+#define S5PC100_CLKGATE_D14_IIC		(1<<4)
+#define S5PC100_CLKGATE_D14_HDMI_IIC	(1<<5)
+#define S5PC100_CLKGATE_D14_SPI0		(1<<6)
+#define S5PC100_CLKGATE_D14_SPI1		(1<<7)
+#define S5PC100_CLKGATE_D14_SPI2		(1<<8)
+#define S5PC100_CLKGATE_D14_IRDA		(1<<9)
+#define S5PC100_CLKGATE_D14_CCAN0		(1<<10)
+#define S5PC100_CLKGATE_D14_CCAN1		(1<<11)
+#define S5PC100_CLKGATE_D14_HSITX		(1<<12)
+#define S5PC100_CLKGATE_D14_HSIRX		(1<<13)
+
+/* HCLKD1/PCLKD1 Clock Gate 5 Registers */
+#define S5PC100_CLKGATE_D15_IIS0		(1<<0)
+#define S5PC100_CLKGATE_D15_IIS1		(1<<1)
+#define S5PC100_CLKGATE_D15_IIS2		(1<<2)
+#define S5PC100_CLKGATE_D15_AC97		(1<<3)
+#define S5PC100_CLKGATE_D15_PCM0		(1<<4)
+#define S5PC100_CLKGATE_D15_PCM1		(1<<5)
+#define S5PC100_CLKGATE_D15_SPDIF		(1<<6)
+#define S5PC100_CLKGATE_D15_TSADC		(1<<7)
+#define S5PC100_CLKGATE_D15_KEYIF		(1<<8)
+#define S5PC100_CLKGATE_D15_CG		(1<<9)
+
+/* HCLKD2 Clock Gate 0 Registers */
+#define S5PC100_CLKGATE_D20_HCLKD2		(1<<0)
+#define S5PC100_CLKGATE_D20_I2SD2		(1<<1)
+
+/* Special Clock Gate 0 Registers */
+#define	S5PC1XX_CLKGATE_SCLK0_HPM		(1<<0)
+#define	S5PC1XX_CLKGATE_SCLK0_PWI		(1<<1)
+#define	S5PC100_CLKGATE_SCLK0_ONENAND	(1<<2)
+#define	S5PC100_CLKGATE_SCLK0_UART		(1<<3)
+#define	S5PC100_CLKGATE_SCLK0_SPI0		(1<<4)
+#define	S5PC100_CLKGATE_SCLK0_SPI1		(1<<5)
+#define	S5PC100_CLKGATE_SCLK0_SPI2		(1<<6)
+#define	S5PC100_CLKGATE_SCLK0_SPI0_48	(1<<7)
+#define	S5PC100_CLKGATE_SCLK0_SPI1_48	(1<<8)
+#define	S5PC100_CLKGATE_SCLK0_SPI2_48	(1<<9)
+#define	S5PC100_CLKGATE_SCLK0_IRDA		(1<<10)
+#define	S5PC100_CLKGATE_SCLK0_USBHOST	(1<<11)
+#define	S5PC100_CLKGATE_SCLK0_MMC0		(1<<12)
+#define	S5PC100_CLKGATE_SCLK0_MMC1		(1<<13)
+#define	S5PC100_CLKGATE_SCLK0_MMC2		(1<<14)
+#define	S5PC100_CLKGATE_SCLK0_MMC0_48	(1<<15)
+#define	S5PC100_CLKGATE_SCLK0_MMC1_48	(1<<16)
+#define	S5PC100_CLKGATE_SCLK0_MMC2_48	(1<<17)
+
+/* Special Clock Gate 1 Registers */
+#define	S5PC100_CLKGATE_SCLK1_LCD		(1<<0)
+#define	S5PC100_CLKGATE_SCLK1_FIMC0		(1<<1)
+#define	S5PC100_CLKGATE_SCLK1_FIMC1		(1<<2)
+#define	S5PC100_CLKGATE_SCLK1_FIMC2		(1<<3)
+#define	S5PC100_CLKGATE_SCLK1_TV54		(1<<4)
+#define	S5PC100_CLKGATE_SCLK1_VDAC54	(1<<5)
+#define	S5PC100_CLKGATE_SCLK1_MIXER		(1<<6)
+#define	S5PC100_CLKGATE_SCLK1_HDMI		(1<<7)
+#define	S5PC100_CLKGATE_SCLK1_AUDIO0	(1<<8)
+#define	S5PC100_CLKGATE_SCLK1_AUDIO1	(1<<9)
+#define	S5PC100_CLKGATE_SCLK1_AUDIO2	(1<<10)
+#define	S5PC100_CLKGATE_SCLK1_SPDIF		(1<<11)
+#define	S5PC100_CLKGATE_SCLK1_CAM		(1<<12)
+
+/* register for power management */
+#define S5PC100_PWR_CFG 		S5PC1XX_CLKREG(0x8000)
+#define S5PC100_EINT_WAKEUP_MASK 	S5PC1XX_CLKREG(0x8004)
+#define S5PC100_NORMAL_CFG 		S5PC1XX_CLKREG(0x8010)
+#define S5PC100_STOP_CFG 		S5PC1XX_CLKREG(0x8014)
+#define S5PC100_SLEEP_CFG 		S5PC1XX_CLKREG(0x8018)
+#define S5PC100_STOP_MEM_CFG 	S5PC1XX_CLKREG(0x801C)
+#define S5PC100_OSC_FREQ 		S5PC1XX_CLKREG(0x8100)
+#define S5PC100_OSC_STABLE 		S5PC1XX_CLKREG(0x8104)
+#define S5PC100_PWR_STABLE 		S5PC1XX_CLKREG(0x8108)
+#define S5PC100_MTC_STABLE 		S5PC1XX_CLKREG(0x8110)
+#define S5PC100_CLAMP_STABLE 	S5PC1XX_CLKREG(0x8114)
+#define S5PC100_OTHERS 		S5PC1XX_CLKREG(0x8200)
+#define S5PC100_RST_STAT 		S5PC1XX_CLKREG(0x8300)
+#define S5PC100_WAKEUP_STAT 	S5PC1XX_CLKREG(0x8304)
+#define S5PC100_BLK_PWR_STAT 	S5PC1XX_CLKREG(0x8308)
+#define S5PC100_INFORM0 		S5PC1XX_CLKREG(0x8400)
+#define S5PC100_INFORM1 		S5PC1XX_CLKREG(0x8404)
+#define S5PC100_INFORM2 		S5PC1XX_CLKREG(0x8408)
+#define S5PC100_INFORM3 		S5PC1XX_CLKREG(0x840C)
+#define S5PC100_INFORM4 		S5PC1XX_CLKREG(0x8410)
+#define S5PC100_INFORM5 		S5PC1XX_CLKREG(0x8414)
+#define S5PC100_INFORM6 		S5PC1XX_CLKREG(0x8418)
+#define S5PC100_INFORM7 		S5PC1XX_CLKREG(0x841C)
+#define S5PC100_DCGIDX_MAP0 	S5PC1XX_CLKREG(0x8500)
+#define S5PC100_DCGIDX_MAP1 	S5PC1XX_CLKREG(0x8504)
+#define S5PC100_DCGIDX_MAP2 	S5PC1XX_CLKREG(0x8508)
+#define S5PC100_DCGPERF_MAP0 	S5PC1XX_CLKREG(0x850C)
+#define S5PC100_DCGPERF_MAP1 	S5PC1XX_CLKREG(0x8510)
+#define S5PC100_DVCIDX_MAP 		S5PC1XX_CLKREG(0x8514)
+#define S5PC100_FREQ_CPU 		S5PC1XX_CLKREG(0x8518)
+#define S5PC100_FREQ_DPM 		S5PC1XX_CLKREG(0x851C)
+#define S5PC100_DVSEMCLK_EN 	S5PC1XX_CLKREG(0x8520)
+#define S5PC100_APLL_CON_L8 	S5PC1XX_CLKREG(0x8600)
+#define S5PC100_APLL_CON_L7 	S5PC1XX_CLKREG(0x8604)
+#define S5PC100_APLL_CON_L6 	S5PC1XX_CLKREG(0x8608)
+#define S5PC100_APLL_CON_L5 	S5PC1XX_CLKREG(0x860C)
+#define S5PC100_APLL_CON_L4 	S5PC1XX_CLKREG(0x8610)
+#define S5PC100_APLL_CON_L3 	S5PC1XX_CLKREG(0x8614)
+#define S5PC100_APLL_CON_L2 	S5PC1XX_CLKREG(0x8618)
+#define S5PC100_APLL_CON_L1 	S5PC1XX_CLKREG(0x861C)
+#define S5PC100_IEM_CONTROL 	S5PC1XX_CLKREG(0x8620)
+#define S5PC100_CLKDIV_IEM_L8 	S5PC1XX_CLKREG(0x8700)
+#define S5PC100_CLKDIV_IEM_L7 	S5PC1XX_CLKREG(0x8704)
+#define S5PC100_CLKDIV_IEM_L6 	S5PC1XX_CLKREG(0x8708)
+#define S5PC100_CLKDIV_IEM_L5 	S5PC1XX_CLKREG(0x870C)
+#define S5PC100_CLKDIV_IEM_L4 	S5PC1XX_CLKREG(0x8710)
+#define S5PC100_CLKDIV_IEM_L3 	S5PC1XX_CLKREG(0x8714)
+#define S5PC100_CLKDIV_IEM_L2 	S5PC1XX_CLKREG(0x8718)
+#define S5PC100_CLKDIV_IEM_L1 	S5PC1XX_CLKREG(0x871C)
+#define S5PC100_IEM_HPMCLK_DIV 	S5PC1XX_CLKREG(0x8724)
+
+#define S5PC100_SWRESET		S5PC1XX_CLKREG(0x100000)
+#define S5PC100_OND_SWRESET		S5PC1XX_CLKREG(0x100008)
+#define S5PC100_GEN_CTRL		S5PC1XX_CLKREG(0x100100)
+#define S5PC100_GEN_STATUS		S5PC1XX_CLKREG(0x100104)
+#define S5PC100_MEM_SYS_CFG		S5PC1XX_CLKREG(0x100200)
+#define S5PC100_CAM_MUX_SEL		S5PC1XX_CLKREG(0x100300)
+#define S5PC100_MIXER_OUT_SEL	S5PC1XX_CLKREG(0x100304)
+#define S5PC100_LPMP_MODE_SEL	S5PC1XX_CLKREG(0x100308)
+#define S5PC100_MIPI_PHY_CON0	S5PC1XX_CLKREG(0x100400)
+#define S5PC100_MIPI_PHY_CON1	S5PC1XX_CLKREG(0x100414)
+#define S5PC100_HDMI_PHY_CON0	S5PC1XX_CLKREG(0x100420)
+
+#define S5PC100_CFG_WFI_CLEAN	(~(3<<5))
+#define S5PC100_CFG_WFI_IDLE	(1<<5)
+#define S5PC100_CFG_WFI_STOP	(2<<5)
+#define S5PC100_CFG_WFI_SLEEP	(3<<5)
+
+#define S5PC100_OTHER_SYS_INT	24
+#define S5PC100_OTHER_STA_TYPE	23
+#define STA_TYPE_EXPON		0
+#define STA_TYPE_SFR		1
+
+#define S5PC100_PWR_STA_EXP_SCALE	0
+#define S5PC100_PWR_STA_CNT		4
+
+#define S5PC100_PWR_STABLE_COUNT	85500
+
+#define S5PC100_SLEEP_CFG_OSC_EN	0
+
+/* OTHERS Resgister */
+#define S5PC100_OTHERS_USB_SIG_MASK 	(1 << 16)
+#define S5PC100_OTHERS_MIPI_DPHY_EN		(1 << 28)
+
+/* MIPI D-PHY Control Register 0 */
+#define S5PC100_MIPI_PHY_CON0_M_RESETN	(1 << 1)
+#define S5PC100_MIPI_PHY_CON0_S_RESETN	(1 << 0)
+
+#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
new file mode 100644
index 0000000..45e2751
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
@@ -0,0 +1,65 @@
+/* arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * Header file for s5pc100 cpu support
+ *
+ * Based on plat-s3c64xx/include/plat/s3c6400.h
+ *
+ * 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.
+*/
+
+/* Common init code for S5PC100 related SoCs */
+extern  int s5pc100_init(void);
+extern void s5pc100_map_io(void);
+extern void s5pc100_init_clocks(int xtal);
+extern  int s5pc100_register_baseclocks(unsigned long xtal);
+extern void s5pc100_init_irq(void);
+extern void s5pc100_init_io(struct map_desc *mach_desc, int size);
+extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5pc100_register_clocks(void);
+extern void s5pc100_setup_clocks(void);
+extern struct sysdev_class s5pc100_sysclass;
+
+#define s5pc100_init_uarts s5pc100_common_init_uarts
+
+/* Some day, belows will be moved to plat-s5pc/include/plat/cpu.h */
+extern void s5pc1xx_init_irq(u32 *vic_valid, int num);
+extern void s5pc1xx_init_io(struct map_desc *mach_desc, int size);
+
+/* Some day, belows will be moved to plat-s5pc/include/plat/clock.h */
+extern struct clk clk_hpll;
+extern struct clk clk_hd0;
+extern struct clk clk_pd0;
+extern struct clk clk_54m;
+extern struct clk clk_dout_mpll2;
+extern void s5pc1xx_register_clocks(void);
+extern int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable);
+extern int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable);
+
+/* Some day, belows will be moved to plat-s5pc/include/plat/devs.h */
+extern struct s3c24xx_uart_resources s5pc1xx_uart_resources[];
+extern struct platform_device s3c_device_g2d;
+extern struct platform_device s3c_device_g3d;
+extern struct platform_device s3c_device_vpp;
+extern struct platform_device s3c_device_tvenc;
+extern struct platform_device s3c_device_tvscaler;
+extern struct platform_device s3c_device_rotator;
+extern struct platform_device s3c_device_jpeg;
+extern struct platform_device s3c_device_onenand;
+extern struct platform_device s3c_device_usb_otghcd;
+extern struct platform_device s3c_device_keypad;
+extern struct platform_device s3c_device_ts;
+extern struct platform_device s3c_device_g3d;
+extern struct platform_device s3c_device_smc911x;
+extern struct platform_device s3c_device_fimc0;
+extern struct platform_device s3c_device_fimc1;
+extern struct platform_device s3c_device_mfc;
+extern struct platform_device s3c_device_ac97;
+extern struct platform_device s3c_device_fimc0;
+extern struct platform_device s3c_device_fimc1;
+extern struct platform_device s3c_device_fimc2;
+
diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
new file mode 100644
index 0000000..80d6dd9
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/irq.c
@@ -0,0 +1,259 @@
+/* arch/arm/plat-s5pc1xx/irq.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC1XX - Interrupt handling
+ *
+ * Based on plat-s3c64xx/irq.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/cpu.h>
+
+/* Timer interrupt handling */
+
+static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
+{
+	generic_handle_irq(sub_irq);
+}
+
+static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_timer(irq, IRQ_TIMER0);
+}
+
+static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_timer(irq, IRQ_TIMER1);
+}
+
+static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_timer(irq, IRQ_TIMER2);
+}
+
+static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_timer(irq, IRQ_TIMER3);
+}
+
+static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
+{
+	s3c_irq_demux_timer(irq, IRQ_TIMER4);
+}
+
+/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
+
+static void s3c_irq_timer_mask(unsigned int irq)
+{
+	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+	reg &= 0x1f;  /* mask out pending interrupts */
+	reg &= ~(1 << (irq - IRQ_TIMER0));
+	__raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static void s3c_irq_timer_unmask(unsigned int irq)
+{
+	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+	reg &= 0x1f;  /* mask out pending interrupts */
+	reg |= 1 << (irq - IRQ_TIMER0);
+	__raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static void s3c_irq_timer_ack(unsigned int irq)
+{
+	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
+
+	reg &= 0x1f;
+	reg |= (1 << 5) << (irq - IRQ_TIMER0);
+	__raw_writel(reg, S3C64XX_TINT_CSTAT);
+}
+
+static struct irq_chip s3c_irq_timer = {
+	.name		= "s3c-timer",
+	.mask		= s3c_irq_timer_mask,
+	.unmask		= s3c_irq_timer_unmask,
+	.ack		= s3c_irq_timer_ack,
+};
+
+struct uart_irq {
+	void __iomem	*regs;
+	unsigned int	 base_irq;
+	unsigned int	 parent_irq;
+};
+
+/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
+ * are consecutive when looking up the interrupt in the demux routines.
+ */
+static struct uart_irq uart_irqs[] = {
+	[0] = {
+		.regs		= (void *)S3C_VA_UART0,
+		.base_irq	= IRQ_S3CUART_BASE0,
+		.parent_irq	= IRQ_UART0,
+	},
+	[1] = {
+		.regs		= (void *)S3C_VA_UART1,
+		.base_irq	= IRQ_S3CUART_BASE1,
+		.parent_irq	= IRQ_UART1,
+	},
+	[2] = {
+		.regs		= (void *)S3C_VA_UART2,
+		.base_irq	= IRQ_S3CUART_BASE2,
+		.parent_irq	= IRQ_UART2,
+	},
+	[3] = {
+		.regs		= (void *)S3C_VA_UART3,
+		.base_irq	= IRQ_S3CUART_BASE3,
+		.parent_irq	= IRQ_UART3,
+	},
+};
+
+static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
+{
+	struct uart_irq *uirq = get_irq_chip_data(irq);
+	return uirq->regs;
+}
+
+static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
+{
+	return irq & 3;
+}
+
+/* UART interrupt registers, not worth adding to seperate include header */
+#define S3C64XX_UINTP	0x30
+#define S3C64XX_UINTSP	0x34
+#define S3C64XX_UINTM	0x38
+
+static void s3c_irq_uart_mask(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+	u32 reg;
+
+	reg = __raw_readl(regs + S3C64XX_UINTM);
+	reg |= (1 << bit);
+	__raw_writel(reg, regs + S3C64XX_UINTM);
+}
+
+static void s3c_irq_uart_maskack(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+	u32 reg;
+
+	reg = __raw_readl(regs + S3C64XX_UINTM);
+	reg |= (1 << bit);
+	__raw_writel(reg, regs + S3C64XX_UINTM);
+	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
+}
+
+static void s3c_irq_uart_unmask(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+	u32 reg;
+
+	reg = __raw_readl(regs + S3C64XX_UINTM);
+	reg &= ~(1 << bit);
+	__raw_writel(reg, regs + S3C64XX_UINTM);
+}
+
+static void s3c_irq_uart_ack(unsigned int irq)
+{
+	void __iomem *regs = s3c_irq_uart_base(irq);
+	unsigned int bit = s3c_irq_uart_bit(irq);
+
+	__raw_writel(1 << bit, regs + S3C64XX_UINTP);
+}
+
+static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
+{
+	struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
+	u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
+	int base = uirq->base_irq;
+
+	if (pend & (1 << 0))
+		generic_handle_irq(base);
+	if (pend & (1 << 1))
+		generic_handle_irq(base + 1);
+	if (pend & (1 << 2))
+		generic_handle_irq(base + 2);
+	if (pend & (1 << 3))
+		generic_handle_irq(base + 3);
+}
+
+static struct irq_chip s3c_irq_uart = {
+	.name		= "s3c-uart",
+	.mask		= s3c_irq_uart_mask,
+	.unmask		= s3c_irq_uart_unmask,
+	.mask_ack	= s3c_irq_uart_maskack,
+	.ack		= s3c_irq_uart_ack,
+};
+
+static void __init s5pc1xx_uart_irq(struct uart_irq *uirq)
+{
+	void __iomem *reg_base = uirq->regs;
+	unsigned int irq;
+	int offs;
+
+	/* mask all interrupts at the start. */
+	__raw_writel(0xf, reg_base + S3C64XX_UINTM);
+
+	for (offs = 0; offs < 3; offs++) {
+		irq = uirq->base_irq + offs;
+
+		set_irq_chip(irq, &s3c_irq_uart);
+		set_irq_chip_data(irq, uirq);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
+}
+
+void __init s5pc1xx_init_irq(u32 *vic_valid, int num)
+{
+	int i;
+	int uart, irq;
+
+	printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
+
+	/* initialise the pair of VICs */
+	for (i = 0; i < num; i++)
+		vic_init((void *)S5PC1XX_VA_VIC(i), S3C_IRQ(i * S3C_IRQ_OFFSET),
+				vic_valid[i], 0);
+
+	/* add the timer sub-irqs */
+
+	set_irq_chained_handler(IRQ_TIMER0, s3c_irq_demux_timer0);
+	set_irq_chained_handler(IRQ_TIMER1, s3c_irq_demux_timer1);
+	set_irq_chained_handler(IRQ_TIMER2, s3c_irq_demux_timer2);
+	set_irq_chained_handler(IRQ_TIMER3, s3c_irq_demux_timer3);
+	set_irq_chained_handler(IRQ_TIMER4, s3c_irq_demux_timer4);
+
+	for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
+		set_irq_chip(irq, &s3c_irq_timer);
+		set_irq_handler(irq, handle_level_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+
+	for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
+		s5pc1xx_uart_irq(&uart_irqs[uart]);
+}
+
+
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
new file mode 100644
index 0000000..6b24035
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -0,0 +1,1139 @@
+/* linux/arch/arm/plat-s5pc1xx/s5pc100-clock.c
+ *
+ * Copyright 2009 Samsung Electronics, Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 based common clock support
+ *
+ * Based on plat-s3c64xx/s3c6400-clock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+
+#include <plat/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/devs.h>
+#include <plat/s5pc100.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * ext_xtal_mux for want of an actual name from the manual.
+*/
+
+static struct clk clk_ext_xtal_mux = {
+	.name		= "ext_xtal",
+	.id		= -1,
+};
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+#define clk_fin_hpll clk_ext_xtal_mux
+
+#define clk_fout_mpll	clk_mpll
+
+struct clk_sources {
+	unsigned int	nr_sources;
+	struct clk	**sources;
+};
+
+struct clksrc_clk {
+	struct clk		clk;
+	unsigned int		mask;
+	unsigned int		shift;
+
+	struct clk_sources	*sources;
+
+	unsigned int		divider_shift;
+	void __iomem		*reg_divider;
+	void __iomem		*reg_source;
+};
+
+static int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+	clk->rate = rate;
+	return 1;
+}
+
+struct clk clk_27m = {
+	.name		= "clk_27m",
+	.id		= -1,
+	.rate		= 27000000,
+};
+
+static int clk_48m_ctrl(struct clk *clk, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	/* can't rely on clock lock, this register has other usages */
+	local_irq_save(flags);
+
+	val = __raw_readl(S5PC1XX_CLK_SRC1);
+	if (enable)
+		val |= S5PC100_CLKSRC1_CLK48M_MASK;
+	else
+		val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
+
+	__raw_writel(val, S5PC1XX_CLK_SRC1);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+struct clk clk_48m = {
+	.name		= "clk_48m",
+	.id		= -1,
+	.rate		= 48000000,
+	.enable		= clk_48m_ctrl,
+};
+
+struct clk clk_54m = {
+	.name		= "clk_54m",
+	.id		= -1,
+	.rate		= 54000000,
+};
+
+struct clk clk_hpll = {
+	.name		= "hpll",
+	.id		= -1,
+};
+
+struct clk clk_hd0 = {
+	.name		= "hclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+};
+
+struct clk clk_pd0 = {
+	.name		= "pclkd0",
+	.id		= -1,
+	.rate		= 0,
+	.parent		= NULL,
+	.ctrlbit	= 0,
+	.set_rate	= clk_default_setrate,
+};
+
+static int s5pc1xx_clk_gate(void __iomem *reg,
+				struct clk *clk,
+				int enable)
+{
+	unsigned int ctrlbit = clk->ctrlbit;
+	u32 con;
+
+	con = __raw_readl(reg);
+
+	if (enable)
+		con |= ctrlbit;
+	else
+		con &= ~ctrlbit;
+
+	__raw_writel(con, reg);
+	return 0;
+}
+
+static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
+}
+
+static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
+}
+
+static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
+}
+
+static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
+}
+
+static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
+}
+
+static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
+}
+
+static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
+}
+
+static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
+}
+
+static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
+}
+
+static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
+}
+
+int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
+}
+
+int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable)
+{
+	return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
+}
+
+static struct clk init_clocks_disable[] = {
+	{
+		.name		= "dsi",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_DSI,
+	}, {
+		.name		= "csi",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_CSI,
+	}, {
+		.name		= "ccan0",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN0,
+	}, {
+		.name		= "ccan1",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_CCAN1,
+	}, {
+		.name		= "keypad",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
+	}, {
+		.name		= "hclkd2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc1xx_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_HCLKD2,
+	}, {
+		.name		= "iis-d2",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc1xx_clk_d20_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D20_I2SD2,
+	}, {
+		.name		= "otg",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBOTG,
+	},
+};
+
+static struct clk init_clocks[] = {
+	/* System1 (D0_0) devices */
+	{
+		.name		= "intc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_INTC,
+	}, {
+		.name		= "tzic",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_TZIC,
+	}, {
+		.name		= "cf-ata",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CFCON,
+	}, {
+		.name		= "mdma",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_MDMA,
+	}, {
+		.name		= "g2d",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_G2D,
+	}, {
+		.name		= "secss",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_SECSS,
+	}, {
+		.name		= "cssys",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d00_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D00_CSSYS,
+	},
+
+	/* Memory (D0_1) devices */
+	{
+		.name		= "dmc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_DMC,
+	}, {
+		.name		= "sromc",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_SROMC,
+	}, {
+		.name		= "onenand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_ONENAND,
+	}, {
+		.name		= "nand",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_NFCON,
+	}, {
+		.name		= "intmem",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_INTMEM,
+	}, {
+		.name		= "ebi",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d01_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D01_EBI,
+	},
+
+	/* System2 (D0_2) devices */
+	{
+		.name		= "seckey",
+		.id		= -1,
+		.parent		= &clk_pd0,
+		.enable		= s5pc1xx_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SECKEY,
+	}, {
+		.name		= "sdm",
+		.id		= -1,
+		.parent		= &clk_hd0,
+		.enable		= s5pc1xx_clk_d02_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D02_SDM,
+	},
+
+	/* File (D1_0) devices */
+	{
+		.name		= "pdma0",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA0,
+	}, {
+		.name		= "pdma1",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_PDMA1,
+	}, {
+		.name		= "usb-host",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_USBHOST,
+	}, {
+		.name		= "modem",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_MODEMIF,
+	}, {
+		.name		= "hsmmc",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC0,
+	}, {
+		.name		= "hsmmc",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC1,
+	}, {
+		.name		= "hsmmc",
+		.id		= 2,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d10_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D10_HSMMC2,
+	},
+
+	/* Multimedia1 (D1_1) devices */
+	{
+		.name		= "lcd",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_LCD,
+	}, {
+		.name		= "rotator",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_ROTATOR,
+	}, {
+		.name		= "fimc",
+		.id		= 0,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC0,
+	}, {
+		.name		= "fimc",
+		.id		= 1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC1,
+	}, {
+		.name		= "fimc",
+		.id		= 2,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_FIMC2,
+	}, {
+		.name		= "jpeg",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_JPEG,
+	}, {
+		.name		= "g3d",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d11_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D11_G3D,
+	},
+
+	/* Multimedia2 (D1_2) devices */
+	{
+		.name		= "tv",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_TV,
+	}, {
+		.name		= "vp",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_VP,
+	}, {
+		.name		= "mixer",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MIXER,
+	}, {
+		.name		= "hdmi",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_HDMI,
+	}, {
+		.name		= "mfc",
+		.id		= -1,
+		.parent		= &clk_h,
+		.enable		= s5pc1xx_clk_d12_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D12_MFC,
+	},
+
+	/* System (D1_3) devices */
+	{
+		.name		= "chipid",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_CHIPID,
+	}, {
+		.name		= "gpio",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_GPIO,
+	}, {
+		.name		= "apc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_APC,
+	}, {
+		.name		= "iec",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_IEC,
+	}, {
+		.name		= "timers",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_PWM,
+	}, {
+		.name		= "systimer",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_SYSTIMER,
+	}, {
+		.name		= "watchdog",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_WDT,
+	}, {
+		.name		= "rtc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d13_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D13_RTC,
+	},
+
+	/* Connectivity (D1_4) devices */
+	{
+		.name		= "uart",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART0,
+	}, {
+		.name		= "uart",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART1,
+	}, {
+		.name		= "uart",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART2,
+	}, {
+		.name		= "uart",
+		.id		= 3,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_UART3,
+	}, {
+		.name		= "i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IIC,
+	}, {
+		.name		= "hdmi-i2c",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HDMI_IIC,
+	}, {
+		.name		= "spi",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI0,
+	}, {
+		.name		= "spi",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI1,
+	}, {
+		.name		= "spi",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_SPI2,
+	}, {
+		.name		= "irda",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_IRDA,
+	}, {
+		.name		= "hsitx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSITX,
+	}, {
+		.name		= "hsirx",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d14_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D14_HSIRX,
+	},
+
+	/* Audio (D1_5) devices */
+	{
+		.name		= "iis",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS0,
+	}, {
+		.name		= "iis",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS1,
+	}, {
+		.name		= "iis",
+		.id		= 2,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_IIS2,
+	}, {
+		.name		= "ac97",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_AC97,
+	}, {
+		.name		= "pcm",
+		.id		= 0,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM0,
+	}, {
+		.name		= "pcm",
+		.id		= 1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_PCM1,
+	}, {
+		.name		= "spdif",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_SPDIF,
+	}, {
+		.name		= "adc",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_TSADC,
+	}, {
+		.name		= "keyif",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_KEYIF,
+	}, {
+		.name		= "cg",
+		.id		= -1,
+		.parent		= &clk_p,
+		.enable		= s5pc1xx_clk_d15_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_D15_CG,
+	},
+
+	/* Audio (D2_0) devices: all disabled */
+
+	/* Special Clocks 1 */
+	{
+		.name		= "sclk_hpm",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC1XX_CLKGATE_SCLK0_HPM,
+	}, {
+		.name		= "sclk_onenand",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_ONENAND,
+	}, {
+		.name		= "sclk_spi_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0_48,
+	}, {
+		.name		= "sclk_spi_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1_48,
+	}, {
+		.name		= "sclk_spi_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2_48,
+	}, {
+		.name		= "sclk_mmc_48",
+		.id		= 0,
+		.parent		= &clk_48m,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0_48,
+	}, {
+		.name		= "sclk_mmc_48",
+		.id		= 1,
+		.parent		= &clk_48m,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1_48,
+	}, {
+		.name		= "sclk_mmc_48",
+		.id		= 2,
+		.parent		= &clk_48m,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2_48,
+	},
+
+	/* Special Clocks 2 */
+	{
+		.name		= "sclk_tv_54",
+		.id		= -1,
+		.parent		= &clk_54m,
+		.enable		= s5pc1xx_sclk1_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_TV54,
+	}, {
+		.name		= "sclk_vdac_54",
+		.id		= -1,
+		.parent		= &clk_54m,
+		.enable		= s5pc1xx_sclk1_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_VDAC54,
+	}, {
+		.name		= "sclk_spdif",
+		.id		= -1,
+		.parent		= NULL,
+		.enable		= s5pc1xx_sclk1_ctrl,
+		.ctrlbit	= S5PC100_CLKGATE_SCLK1_SPDIF,
+	},
+};
+
+void __init s5pc1xx_register_clocks(void)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	clkp = init_clocks;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	clkp = init_clocks_disable;
+	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+
+		(clkp->enable)(clkp, 0);
+	}
+
+	s3c_pwmclk_init();
+}
+static struct clk clk_fout_apll = {
+	.name		= "fout_apll",
+	.id		= -1,
+};
+
+static struct clk *clk_src_apll_list[] = {
+	[0] = &clk_fin_apll,
+	[1] = &clk_fout_apll,
+};
+
+static struct clk_sources clk_src_apll = {
+	.sources	= clk_src_apll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
+};
+
+static struct clksrc_clk clk_mout_apll = {
+	.clk	= {
+		.name		= "mout_apll",
+		.id		= -1,
+	},
+	.shift		= S5PC1XX_CLKSRC0_APLL_SHIFT,
+	.mask		= S5PC1XX_CLKSRC0_APLL_MASK,
+	.sources	= &clk_src_apll,
+	.reg_source	= S5PC1XX_CLK_SRC0,
+};
+
+static struct clk clk_fout_epll = {
+	.name		= "fout_epll",
+	.id		= -1,
+};
+
+static struct clk *clk_src_epll_list[] = {
+	[0] = &clk_fin_epll,
+	[1] = &clk_fout_epll,
+};
+
+static struct clk_sources clk_src_epll = {
+	.sources	= clk_src_epll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_epll_list),
+};
+
+static struct clksrc_clk clk_mout_epll = {
+	.clk	= {
+		.name		= "mout_epll",
+		.id		= -1,
+	},
+	.shift		= S5PC1XX_CLKSRC0_EPLL_SHIFT,
+	.mask		= S5PC1XX_CLKSRC0_EPLL_MASK,
+	.sources	= &clk_src_epll,
+	.reg_source	= S5PC1XX_CLK_SRC0,
+};
+
+static struct clk *clk_src_mpll_list[] = {
+	[0] = &clk_fin_mpll,
+	[1] = &clk_fout_mpll,
+};
+
+static struct clk_sources clk_src_mpll = {
+	.sources	= clk_src_mpll_list,
+	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+	.clk = {
+		.name		= "mout_mpll",
+		.id		= -1,
+	},
+	.shift		= S5PC1XX_CLKSRC0_MPLL_SHIFT,
+	.mask		= S5PC1XX_CLKSRC0_MPLL_MASK,
+	.sources	= &clk_src_mpll,
+	.reg_source	= S5PC1XX_CLK_SRC0,
+};
+
+static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned long clkdiv;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK;
+	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
+
+	return rate;
+}
+
+static struct clk clk_dout_mpll = {
+	.name		= "dout_mpll",
+	.id		= -1,
+	.parent		= &clk_mout_mpll.clk,
+	.get_rate	= s5pc1xx_clk_doutmpll_get_rate,
+};
+
+static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
+{
+	unsigned long rate = clk_get_rate(clk->parent);
+	unsigned long clkdiv;
+
+	printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+	clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
+	rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
+
+	return rate;
+}
+
+struct clk clk_dout_mpll2 = {
+	.name		= "dout_mpll2",
+	.id		= -1,
+	.parent		= &clk_mout_mpll.clk,
+	.get_rate	= s5pc1xx_clk_doutmpll2_get_rate,
+};
+
+static struct clk *clkset_uart_list[] = {
+	&clk_mout_epll.clk,
+	&clk_dout_mpll,
+	NULL,
+	NULL
+};
+
+static struct clk_sources clkset_uart = {
+	.sources	= clkset_uart_list,
+	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
+};
+
+static inline struct clksrc_clk *to_clksrc(struct clk *clk)
+{
+	return container_of(clk, struct clksrc_clk, clk);
+}
+
+static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	unsigned long rate = clk_get_rate(clk->parent);
+	u32 clkdiv = __raw_readl(sclk->reg_divider);
+
+	clkdiv >>= sclk->divider_shift;
+	clkdiv &= 0xf;
+	clkdiv++;
+
+	rate /= clkdiv;
+	return rate;
+}
+
+static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	void __iomem *reg = sclk->reg_divider;
+	unsigned int div;
+	u32 val;
+
+	rate = clk_round_rate(clk, rate);
+	div = clk_get_rate(clk->parent) / rate;
+	if (div > 16)
+		return -EINVAL;
+
+	val = __raw_readl(reg);
+	val &= ~(0xf << sclk->shift);
+	val |= (div - 1) << sclk->shift;
+	__raw_writel(val, reg);
+
+	return 0;
+}
+
+static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	struct clk_sources *srcs = sclk->sources;
+	u32 clksrc = __raw_readl(sclk->reg_source);
+	int src_nr = -1;
+	int ptr;
+
+	for (ptr = 0; ptr < srcs->nr_sources; ptr++)
+		if (srcs->sources[ptr] == parent) {
+			src_nr = ptr;
+			break;
+		}
+
+	if (src_nr >= 0) {
+		clksrc &= ~sclk->mask;
+		clksrc |= src_nr << sclk->shift;
+
+		__raw_writel(clksrc, sclk->reg_source);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
+					      unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int div;
+
+	if (rate > parent_rate)
+		rate = parent_rate;
+	else {
+		div = rate / parent_rate;
+
+		if (div == 0)
+			div = 1;
+		if (div > 16)
+			div = 16;
+
+		rate = parent_rate / div;
+	}
+
+	return rate;
+}
+
+static struct clksrc_clk clk_uart_uclk1 = {
+	.clk	= {
+		.name		= "uclk1",
+		.id		= -1,
+		.ctrlbit        = S5PC100_CLKGATE_SCLK0_UART,
+		.enable		= s5pc1xx_sclk0_ctrl,
+		.set_parent	= s5pc1xx_setparent_clksrc,
+		.get_rate	= s5pc1xx_getrate_clksrc,
+		.set_rate	= s5pc1xx_setrate_clksrc,
+		.round_rate	= s5pc1xx_roundrate_clksrc,
+	},
+	.shift		= S5PC100_CLKSRC1_UART_SHIFT,
+	.mask		= S5PC100_CLKSRC1_UART_MASK,
+	.sources	= &clkset_uart,
+	.divider_shift	= S5PC100_CLKDIV2_UART_SHIFT,
+	.reg_divider	= S5PC1XX_CLK_DIV2,
+	.reg_source	= S5PC1XX_CLK_SRC1,
+};
+
+/* Clock initialisation code */
+
+static struct clksrc_clk *init_parents[] = {
+	&clk_mout_apll,
+	&clk_mout_epll,
+	&clk_mout_mpll,
+	&clk_uart_uclk1,
+};
+
+static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
+{
+	struct clk_sources *srcs = clk->sources;
+	u32 clksrc = __raw_readl(clk->reg_source);
+
+	clksrc &= clk->mask;
+	clksrc >>= clk->shift;
+
+	if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
+		printk(KERN_ERR "%s: bad source %d\n",
+		       clk->clk.name, clksrc);
+		return;
+	}
+
+	clk->clk.parent = srcs->sources[clksrc];
+
+	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
+	       clk->clk.name, clk->clk.parent->name, clksrc,
+	       clk_get_rate(&clk->clk));
+}
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+void __init_or_cpufreq s5pc100_setup_clocks(void)
+{
+	struct clk *xtal_clk;
+	unsigned long xtal;
+	unsigned long armclk;
+	unsigned long hclkd0;
+	unsigned long hclk;
+	unsigned long pclkd0;
+	unsigned long pclk;
+	unsigned long apll;
+	unsigned long mpll;
+	unsigned long hpll;
+	unsigned long epll;
+	unsigned int ptr;
+	u32 clkdiv0, clkdiv1;
+
+	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+	clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0);
+	clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1);
+
+	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
+			__func__, clkdiv0, clkdiv1);
+
+	xtal_clk = clk_get(NULL, "xtal");
+	BUG_ON(IS_ERR(xtal_clk));
+
+	xtal = clk_get_rate(xtal_clk);
+	clk_put(xtal_clk);
+
+	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+	apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON));
+	mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON));
+	epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON));
+	hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
+
+	printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
+	       apll, mpll, epll, hpll);
+
+	armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL);
+	armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
+	hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
+	pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
+	hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
+	pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
+
+	printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n",
+	       armclk, hclkd0, pclkd0, hclk, pclk);
+
+	clk_fout_apll.rate = apll;
+	clk_fout_mpll.rate = mpll;
+	clk_fout_epll.rate = epll;
+	clk_fout_apll.rate = apll;
+
+	clk_h.rate = hclk;
+	clk_p.rate = pclk;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+		s5pc1xx_set_clksrc(init_parents[ptr]);
+}
+
+static struct clk *clks[] __initdata = {
+	&clk_ext_xtal_mux,
+	&clk_mout_epll.clk,
+	&clk_fout_epll,
+	&clk_mout_mpll.clk,
+	&clk_dout_mpll,
+	&clk_uart_uclk1.clk,
+	&clk_ext,
+	&clk_epll,
+	&clk_27m,
+	&clk_48m,
+	&clk_54m,
+};
+
+void __init s5pc100_register_clocks(void)
+{
+	struct clk *clkp;
+	int ret;
+	int ptr;
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
+		clkp = clks[ptr];
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
+	clk_mpll.parent = &clk_mout_mpll.clk;
+	clk_epll.parent = &clk_mout_epll.clk;
+}
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-init.c b/arch/arm/plat-s5pc1xx/s5pc100-init.c
new file mode 100644
index 0000000..c587108
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/s5pc100-init.c
@@ -0,0 +1,27 @@
+/* linux/arch/arm/plat-s5pc1xx/s5pc100-init.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *      Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - CPU initialisation (common with other S5PC1XX chips)
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5pc100.h>
+
+/* uart registration process */
+
+void __init s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+	/* The driver name is s3c6400-uart to reuse s3c6400_serial_drv  */
+	s3c24xx_init_uartdevs("s3c6400-uart", s5pc1xx_uart_resources, cfg, no);
+}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c
new file mode 100644
index 0000000..3d00c02
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-i2c0.c
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s5pc1xx/setup-i2c0.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * Base S5PC1XX I2C bus 0 gpio configuration
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+	/* Pin configuration would be needed */
+}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c
new file mode 100644
index 0000000..c8f3ca4
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-i2c1.c
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ *	Byungho Min <bhmin@samsung.com>
+ *
+ * Base S5PC1XX I2C bus 1 gpio configuration
+ *
+ * Based on plat-s3c64xx/setup-i2c1.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+	/* Pin configuration would be needed */
+}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 33026ef..c8c55b4 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Sat Jun 20 22:28:39 2009
+# Last update: Sat Sep 12 12:00:16 2009
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -1769,7 +1769,7 @@ mx31cicada		MACH_MX31CICADA		MX31CICADA		1777
 mi424wr			MACH_MI424WR		MI424WR			1778
 axs_ultrax		MACH_AXS_ULTRAX		AXS_ULTRAX		1779
 at572d940deb		MACH_AT572D940DEB	AT572D940DEB		1780
-davinci_da8xx_evm	MACH_DAVINCI_DA8XX_EVM	DAVINCI_DA8XX_EVM	1781
+davinci_da830_evm	MACH_DAVINCI_DA830_EVM	DAVINCI_DA830_EVM	1781
 ep9302			MACH_EP9302		EP9302			1782
 at572d940hfek		MACH_AT572D940HFEB	AT572D940HFEB		1783
 cybook3			MACH_CYBOOK3		CYBOOK3			1784
@@ -1962,7 +1962,7 @@ ethernut5		MACH_ETHERNUT5		ETHERNUT5		1971
 arm11			MACH_ARM11		ARM11			1972
 cpuat9260		MACH_CPUAT9260		CPUAT9260		1973
 cpupxa255		MACH_CPUPXA255		CPUPXA255		1974
-cpuimx27		MACH_CPUIMX27		CPUIMX27		1975
+eukrea_cpuimx27		MACH_CPUIMX27		CPUIMX27		1975
 cheflux			MACH_CHEFLUX		CHEFLUX			1976
 eb_cpux9k2		MACH_EB_CPUX9K2		EB_CPUX9K2		1977
 opcotec			MACH_OPCOTEC		OPCOTEC			1978
@@ -2249,14 +2249,14 @@ omap3_phrazer		MACH_OMAP3_PHRAZER	OMAP3_PHRAZER		2261
 darwin			MACH_DARWIN		DARWIN			2262
 oratiscomu		MACH_ORATISCOMU		ORATISCOMU		2263
 rtsbc20			MACH_RTSBC20		RTSBC20			2264
-i780			MACH_I780		I780			2265
+sgh_i780		MACH_I780		I780			2265
 gemini324		MACH_GEMINI324		GEMINI324		2266
 oratislan		MACH_ORATISLAN		ORATISLAN		2267
 oratisalog		MACH_ORATISALOG		ORATISALOG		2268
 oratismadi		MACH_ORATISMADI		ORATISMADI		2269
 oratisot16		MACH_ORATISOT16		ORATISOT16		2270
 oratisdesk		MACH_ORATISDESK		ORATISDESK		2271
-v2p_ca9			MACH_V2P_CA9		V2P_CA9			2272
+v2_ca9			MACH_V2P_CA9		V2P_CA9			2272
 sintexo			MACH_SINTEXO		SINTEXO			2273
 cm3389			MACH_CM3389		CM3389			2274
 omap3_cio		MACH_OMAP3_CIO		OMAP3_CIO		2275
@@ -2280,3 +2280,132 @@ htcrhodium		MACH_HTCRHODIUM		HTCRHODIUM		2292
 htctopaz		MACH_HTCTOPAZ		HTCTOPAZ		2293
 matrix504		MACH_MATRIX504		MATRIX504		2294
 mrfsa			MACH_MRFSA		MRFSA			2295
+sc_p270			MACH_SC_P270		SC_P270			2296
+atlas5_evb		MACH_ATLAS5_EVB		ATLAS5_EVB		2297
+pelco_lobox		MACH_PELCO_LOBOX	PELCO_LOBOX		2298
+dilax_pcu200		MACH_DILAX_PCU200	DILAX_PCU200		2299
+leonardo		MACH_LEONARDO		LEONARDO		2300
+zoran_approach7		MACH_ZORAN_APPROACH7	ZORAN_APPROACH7		2301
+dp6xx			MACH_DP6XX		DP6XX			2302
+bcm2153_vesper		MACH_BCM2153_VESPER	BCM2153_VESPER		2303
+mahimahi		MACH_MAHIMAHI		MAHIMAHI		2304
+clickc			MACH_CLICKC		CLICKC			2305
+zb_gateway		MACH_ZB_GATEWAY		ZB_GATEWAY		2306
+tazcard			MACH_TAZCARD		TAZCARD			2307
+tazdev			MACH_TAZDEV		TAZDEV			2308
+annax_cb_arm		MACH_ANNAX_CB_ARM	ANNAX_CB_ARM		2309
+annax_dm3		MACH_ANNAX_DM3		ANNAX_DM3		2310
+cerebric		MACH_CEREBRIC		CEREBRIC		2311
+orca			MACH_ORCA		ORCA			2312
+pc9260			MACH_PC9260		PC9260			2313
+ems285a			MACH_EMS285A		EMS285A			2314
+gec2410			MACH_GEC2410		GEC2410			2315
+gec2440			MACH_GEC2440		GEC2440			2316
+mw903			MACH_ARCH_MW903		ARCH_MW903		2317
+mw2440			MACH_MW2440		MW2440			2318
+ecac2378		MACH_ECAC2378		ECAC2378		2319
+tazkiosk		MACH_TAZKIOSK		TAZKIOSK		2320
+whiterabbit_mch		MACH_WHITERABBIT_MCH	WHITERABBIT_MCH		2321
+sbox9263		MACH_SBOX9263		SBOX9263		2322
+oreo			MACH_OREO		OREO			2323
+smdk6442		MACH_SMDK6442		SMDK6442		2324
+openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325
+incredible		MACH_INCREDIBLE		INCREDIBLE		2326
+incrediblec		MACH_INCREDIBLEC	INCREDIBLEC		2327
+heroct			MACH_HEROCT		HEROCT			2328
+mmnet1000		MACH_MMNET1000		MMNET1000		2329
+devkit8000		MACH_DEVKIT8000		DEVKIT8000		2330
+devkit9000		MACH_DEVKIT9000		DEVKIT9000		2331
+mx31txtr		MACH_MX31TXTR		MX31TXTR		2332
+u380			MACH_U380		U380			2333
+oamp3_hualu		MACH_HUALU_BOARD	HUALU_BOARD		2334
+npcmx50			MACH_NPCMX50		NPCMX50			2335
+mx51_lange51		MACH_MX51_LANGE51	MX51_LANGE51		2336
+mx51_lange52		MACH_MX51_LANGE52	MX51_LANGE52		2337
+riom			MACH_RIOM		RIOM			2338
+comcas			MACH_COMCAS		COMCAS			2339
+wsi_mx27		MACH_WSI_MX27		WSI_MX27		2340
+cm_t35			MACH_CM_T35		CM_T35			2341
+net2big			MACH_NET2BIG		NET2BIG			2342
+motorola_a1600		MACH_MOTOROLA_A1600	MOTOROLA_A1600		2343
+igep0020		MACH_IGEP0020		IGEP0020		2344
+igep0010		MACH_IGEP0010		IGEP0010		2345
+mv6281gtwge2		MACH_MV6281GTWGE2	MV6281GTWGE2		2346
+scat100			MACH_SCAT100		SCAT100			2347
+sanmina			MACH_SANMINA		SANMINA			2348
+momento			MACH_MOMENTO		MOMENTO			2349
+nuc9xx			MACH_NUC9XX		NUC9XX			2350
+nuc910evb		MACH_NUC910EVB		NUC910EVB		2351
+nuc920evb		MACH_NUC920EVB		NUC920EVB		2352
+nuc950evb		MACH_NUC950EVB		NUC950EVB		2353
+nuc945evb		MACH_NUC945EVB		NUC945EVB		2354
+nuc960evb		MACH_NUC960EVB		NUC960EVB		2355
+nuc932evb		MACH_NUC932EVB		NUC932EVB		2356
+nuc900			MACH_NUC900		NUC900			2357
+sd1soc			MACH_SD1SOC		SD1SOC			2358
+ln2440bc		MACH_LN2440BC		LN2440BC		2359
+rsbc			MACH_RSBC		RSBC			2360
+openrd_client		MACH_OPENRD_CLIENT	OPENRD_CLIENT		2361
+hpipaq11x		MACH_HPIPAQ11X		HPIPAQ11X		2362
+wayland			MACH_WAYLAND		WAYLAND			2363
+acnbsx102		MACH_ACNBSX102		ACNBSX102		2364
+hwat91			MACH_HWAT91		HWAT91			2365
+at91sam9263cs		MACH_AT91SAM9263CS	AT91SAM9263CS		2366
+csb732			MACH_CSB732		CSB732			2367
+u8500			MACH_U8500		U8500			2368
+huqiu			MACH_HUQIU		HUQIU			2369
+mx51_kunlun		MACH_MX51_KUNLUN	MX51_KUNLUN		2370
+pmt1g			MACH_PMT1G		PMT1G			2371
+htcelf			MACH_HTCELF		HTCELF			2372
+armadillo420		MACH_ARMADILLO420	ARMADILLO420		2373
+armadillo440		MACH_ARMADILLO440	ARMADILLO440		2374
+u_chip_dual_arm		MACH_U_CHIP_DUAL_ARM	U_CHIP_DUAL_ARM		2375
+csr_bdb3		MACH_CSR_BDB3		CSR_BDB3		2376
+dolby_cat1018		MACH_DOLBY_CAT1018	DOLBY_CAT1018		2377
+hy9307			MACH_HY9307		HY9307			2378
+aspire_easystore	MACH_A_ES		A_ES			2379
+davinci_irif		MACH_DAVINCI_IRIF	DAVINCI_IRIF		2380
+agama9263		MACH_AGAMA9263		AGAMA9263		2381
+marvell_jasper		MACH_MARVELL_JASPER	MARVELL_JASPER		2382
+flint			MACH_FLINT		FLINT			2383
+tavorevb3		MACH_TAVOREVB3		TAVOREVB3		2384
+sch_m490		MACH_SCH_M490		SCH_M490		2386
+rbl01			MACH_RBL01		RBL01			2387
+omnifi			MACH_OMNIFI		OMNIFI			2388
+otavalo			MACH_OTAVALO		OTAVALO			2389
+sienna			MACH_SIENNA		SIENNA			2390
+htc_excalibur_s620	MACH_HTC_EXCALIBUR_S620	HTC_EXCALIBUR_S620	2391
+htc_opal		MACH_HTC_OPAL		HTC_OPAL		2392
+touchbook		MACH_TOUCHBOOK		TOUCHBOOK		2393
+latte			MACH_LATTE		LATTE			2394
+xa200			MACH_XA200		XA200			2395
+nimrod			MACH_NIMROD		NIMROD			2396
+cc9p9215_3g		MACH_CC9P9215_3G	CC9P9215_3G		2397
+cc9p9215_3gjs		MACH_CC9P9215_3GJS	CC9P9215_3GJS		2398
+tk71			MACH_TK71		TK71			2399
+comham3525		MACH_COMHAM3525		COMHAM3525		2400
+mx31erebus		MACH_MX31EREBUS		MX31EREBUS		2401
+mcardmx27		MACH_MCARDMX27		MCARDMX27		2402
+paradise		MACH_PARADISE		PARADISE		2403
+tide			MACH_TIDE		TIDE			2404
+wzl2440			MACH_WZL2440		WZL2440			2405
+sdrdemo			MACH_SDRDEMO		SDRDEMO			2406
+ethercan2		MACH_ETHERCAN2		ETHERCAN2		2407
+ecmimg20		MACH_ECMIMG20		ECMIMG20		2408
+omap_dragon		MACH_OMAP_DRAGON	OMAP_DRAGON		2409
+halo			MACH_HALO		HALO			2410
+huangshan		MACH_HUANGSHAN		HUANGSHAN		2411
+vl_ma2sc		MACH_VL_MA2SC		VL_MA2SC		2412
+raumfeld_rc		MACH_RAUMFELD_RC	RAUMFELD_RC		2413
+raumfeld_connector	MACH_RAUMFELD_CONNECTOR	RAUMFELD_CONNECTOR	2414
+raumfeld_speaker	MACH_RAUMFELD_SPEAKER	RAUMFELD_SPEAKER	2415
+multibus_master		MACH_MULTIBUS_MASTER	MULTIBUS_MASTER		2416
+multibus_pbk		MACH_MULTIBUS_PBK	MULTIBUS_PBK		2417
+tnetv107x		MACH_TNETV107X		TNETV107X		2418
+snake			MACH_SNAKE		SNAKE			2419
+cwmx27			MACH_CWMX27		CWMX27			2420
+sch_m480		MACH_SCH_M480		SCH_M480		2421
+platypus		MACH_PLATYPUS		PLATYPUS		2422
+pss2			MACH_PSS2		PSS2			2423
+davinci_apm150		MACH_DAVINCI_APM150	DAVINCI_APM150		2424
+str9100			MACH_STR9100		STR9100			2425
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index a2bed62..4fa9903 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -42,6 +42,7 @@ ENTRY(vfp_null_entry)
 	mov	pc, lr
 ENDPROC(vfp_null_entry)
 
+	.align	2
 .LCvfp:
 	.word	vfp_vector
 
@@ -61,6 +62,7 @@ ENTRY(vfp_testing_entry)
 	mov	pc, r9			@ we have handled the fault
 ENDPROC(vfp_testing_entry)
 
+	.align	2
 VFP_arch_address:
 	.word	VFP_arch
 
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 1aeae38..66dc2d0 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -209,40 +209,55 @@ ENDPROC(vfp_save_state)
 last_VFP_context_address:
 	.word	last_VFP_context
 
-ENTRY(vfp_get_float)
-	add	pc, pc, r0, lsl #3
+	.macro	tbl_branch, base, tmp, shift
+#ifdef CONFIG_THUMB2_KERNEL
+	adr	\tmp, 1f
+	add	\tmp, \tmp, \base, lsl \shift
+	mov	pc, \tmp
+#else
+	add	pc, pc, \base, lsl \shift
 	mov	r0, r0
+#endif
+1:
+	.endm
+
+ENTRY(vfp_get_float)
+	tbl_branch r0, r3, #3
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-	mrc	p10, 0, r0, c\dr, c0, 0	@ fmrs	r0, s0
+1:	mrc	p10, 0, r0, c\dr, c0, 0	@ fmrs	r0, s0
 	mov	pc, lr
-	mrc	p10, 0, r0, c\dr, c0, 4	@ fmrs	r0, s1
+	.org	1b + 8
+1:	mrc	p10, 0, r0, c\dr, c0, 4	@ fmrs	r0, s1
 	mov	pc, lr
+	.org	1b + 8
 	.endr
 ENDPROC(vfp_get_float)
 
 ENTRY(vfp_put_float)
-	add	pc, pc, r1, lsl #3
-	mov	r0, r0
+	tbl_branch r1, r3, #3
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-	mcr	p10, 0, r0, c\dr, c0, 0	@ fmsr	r0, s0
+1:	mcr	p10, 0, r0, c\dr, c0, 0	@ fmsr	r0, s0
 	mov	pc, lr
-	mcr	p10, 0, r0, c\dr, c0, 4	@ fmsr	r0, s1
+	.org	1b + 8
+1:	mcr	p10, 0, r0, c\dr, c0, 4	@ fmsr	r0, s1
 	mov	pc, lr
+	.org	1b + 8
 	.endr
 ENDPROC(vfp_put_float)
 
 ENTRY(vfp_get_double)
-	add	pc, pc, r0, lsl #3
-	mov	r0, r0
+	tbl_branch r0, r3, #3
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-	fmrrd	r0, r1, d\dr
+1:	fmrrd	r0, r1, d\dr
 	mov	pc, lr
+	.org	1b + 8
 	.endr
 #ifdef CONFIG_VFPv3
 	@ d16 - d31 registers
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-	mrrc	p11, 3, r0, r1, c\dr	@ fmrrd	r0, r1, d\dr
+1:	mrrc	p11, 3, r0, r1, c\dr	@ fmrrd	r0, r1, d\dr
 	mov	pc, lr
+	.org	1b + 8
 	.endr
 #endif
 
@@ -253,17 +268,18 @@ ENTRY(vfp_get_double)
 ENDPROC(vfp_get_double)
 
 ENTRY(vfp_put_double)
-	add	pc, pc, r2, lsl #3
-	mov	r0, r0
+	tbl_branch r2, r3, #3
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-	fmdrr	d\dr, r0, r1
+1:	fmdrr	d\dr, r0, r1
 	mov	pc, lr
+	.org	1b + 8
 	.endr
 #ifdef CONFIG_VFPv3
 	@ d16 - d31 registers
 	.irp	dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
-	mcrr	p11, 3, r1, r2, c\dr	@ fmdrr	r1, r2, d\dr
+1:	mcrr	p11, 3, r1, r2, c\dr	@ fmdrr	r1, r2, d\dr
 	mov	pc, lr
+	.org	1b + 8
 	.endr
 #endif
 ENDPROC(vfp_put_double)
diff --git a/arch/avr32/include/asm/socket.h b/arch/avr32/include/asm/socket.h
index 04c8606..fe863f9 100644
--- a/arch/avr32/include/asm/socket.h
+++ b/arch/avr32/include/asm/socket.h
@@ -57,4 +57,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* __ASM_AVR32_SOCKET_H */
diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S
index 7910d41..c4b5665 100644
--- a/arch/avr32/kernel/vmlinux.lds.S
+++ b/arch/avr32/kernel/vmlinux.lds.S
@@ -124,14 +124,11 @@ SECTIONS
 		_end = .;
 	}
 
+	DWARF_DEBUG
+
 	/* When something in the kernel is NOT compiled as a module, the module
 	 * cleanup code and data are put into these segments. Both can then be
 	 * thrown away, as cleanup code is never called unless it's a module.
 	 */
-	/DISCARD/       	: {
-		EXIT_DATA
-		*(.exitcall.exit)
-	}
-
-	DWARF_DEBUG
+	DISCARDS
 }
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 7faa2f5..9a01d44 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -342,8 +342,9 @@ config MEM_MT48LC64M4A2FB_7E
 config MEM_MT48LC16M16A2TG_75
 	bool
 	depends on (BFIN533_EZKIT || BFIN561_EZKIT \
-		|| BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM \
-		|| H8606_HVSISTEMAS || BFIN527_BLUETECHNIX_CM)
+		|| BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM_E \
+		|| BFIN537_BLUETECHNIX_CM_U || H8606_HVSISTEMAS \
+		|| BFIN527_BLUETECHNIX_CM)
 	default y
 
 config MEM_MT48LC32M8A2_75
@@ -459,7 +460,7 @@ config VCO_MULT
 	default "45" if BFIN533_STAMP
 	default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
 	default "22" if BFIN533_BLUETECHNIX_CM
-	default "20" if (BFIN537_BLUETECHNIX_CM || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
+	default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
 	default "20" if BFIN561_EZKIT
 	default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD)
 	help
@@ -574,8 +575,8 @@ config MAX_VCO_HZ
 	default 400000000 if BF514
 	default 400000000 if BF516
 	default 400000000 if BF518
-	default 600000000 if BF522
-	default 400000000 if BF523
+	default 400000000 if BF522
+	default 600000000 if BF523
 	default 400000000 if BF524
 	default 600000000 if BF525
 	default 400000000 if BF526
@@ -647,7 +648,7 @@ config CYCLES_CLOCKSOURCE
 	  writing the registers will most likely crash the kernel.
 
 config GPTMR0_CLOCKSOURCE
-	bool "Use GPTimer0 as a clocksource (higher rating)"
+	bool "Use GPTimer0 as a clocksource"
 	select BFIN_GPTIMERS
 	depends on GENERIC_CLOCKEVENTS
 	depends on !TICKSOURCE_GPTMR0
@@ -917,10 +918,6 @@ comment "Cache Support"
 config BFIN_ICACHE
 	bool "Enable ICACHE"
 	default y
-config BFIN_ICACHE_LOCK
-	bool "Enable Instruction Cache Locking"
-	depends on BFIN_ICACHE
-	default n
 config BFIN_EXTMEM_ICACHEABLE
 	bool "Enable ICACHE for external memory"
 	depends on BFIN_ICACHE
@@ -987,7 +984,7 @@ endchoice
 config BFIN_L2_DCACHEABLE
 	bool "Enable DCACHE for L2 SRAM"
 	depends on BFIN_DCACHE
-	depends on BF54x || BF561
+	depends on (BF54x || BF561) && !SMP
 	default n
 choice
 	prompt "L2 SRAM DCACHE policy"
@@ -995,11 +992,9 @@ choice
 	default BFIN_L2_WRITEBACK
 config BFIN_L2_WRITEBACK
 	bool "Write back"
-	depends on !SMP
 
 config BFIN_L2_WRITETHROUGH
 	bool "Write through"
-	depends on !SMP
 endchoice
 
 
@@ -1154,11 +1149,12 @@ source "fs/Kconfig.binfmt"
 endmenu
 
 menu "Power management options"
+	depends on !SMP
+
 source "kernel/power/Kconfig"
 
 config ARCH_SUSPEND_POSSIBLE
 	def_bool y
-	depends on !SMP
 
 choice
 	prompt "Standby Power Saving Mode"
@@ -1246,6 +1242,7 @@ config PM_BFIN_WAKE_GP
 endmenu
 
 menu "CPU Frequency scaling"
+	depends on !SMP
 
 source "drivers/cpufreq/Kconfig"
 
diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug
index 1fc4981..87f195e 100644
--- a/arch/blackfin/Kconfig.debug
+++ b/arch/blackfin/Kconfig.debug
@@ -252,4 +252,10 @@ config ACCESS_CHECK
 
 	  Say N here to disable that check to improve the performance.
 
+config BFIN_ISRAM_SELF_TEST
+	bool "isram boot self tests"
+	default n
+	help
+	  Run some self tests of the isram driver code at boot.
+
 endmenu
diff --git a/arch/blackfin/configs/BF518F-EZBRD_defconfig b/arch/blackfin/configs/BF518F-EZBRD_defconfig
index dcfb488..9905b26 100644
--- a/arch/blackfin/configs/BF518F-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF518F-EZBRD_defconfig
@@ -358,9 +358,9 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0xFFC0
+CONFIG_BANK_3=0x99B2
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index 48a3a7a..9dc6820 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -359,9 +359,9 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0xFFC0
+CONFIG_BANK_3=0x99B2
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index dd83527..77e35d4 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -363,9 +363,9 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
-CONFIG_BANK_3=0xFFC0
+CONFIG_BANK_3=0x99B2
 
 #
 # Bus options (PCI, PCMCIA, EISA, MCA, ISA)
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index b3d3cab..f773ad1 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -400,7 +400,7 @@ CONFIG_C_AMBEN_ALL=y
 # EBIU_AMBCTL Control
 #
 CONFIG_BANK_0=0x7BB0
-CONFIG_BANK_1=0x5554
+CONFIG_BANK_1=0x7BB0
 CONFIG_BANK_2=0x7BB0
 CONFIG_BANK_3=0x99B2
 CONFIG_EBIU_MBSCTLVAL=0x0
diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h
index e39277e..aef0594 100644
--- a/arch/blackfin/include/asm/bfin-global.h
+++ b/arch/blackfin/include/asm/bfin-global.h
@@ -66,7 +66,6 @@ extern void program_IAR(void);
 
 extern asmlinkage void lower_to_irq14(void);
 extern asmlinkage void bfin_return_from_exception(void);
-extern asmlinkage void evt14_softirq(void);
 extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
 extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
 
@@ -100,11 +99,6 @@ extern unsigned long bfin_sic_iwr[];
 extern unsigned vr_wakeup;
 extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */
 
-#ifdef CONFIG_BFIN_ICACHE_LOCK
-extern void cache_grab_lock(int way);
-extern void bfin_cache_lock(int way);
-#endif
-
 #endif
 
 #endif				/* _BLACKFIN_H_ */
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h
index aaeb4df..c281c63 100644
--- a/arch/blackfin/include/asm/bfin5xx_spi.h
+++ b/arch/blackfin/include/asm/bfin5xx_spi.h
@@ -127,6 +127,7 @@ struct bfin5xx_spi_chip {
 	u32 cs_gpio;
 	/* Value to send if no TX value is supplied, usually 0x0 or 0xFFFF */
 	u16 idle_tx_val;
+	u8 pio_interrupt; /* Enable spi data irq */
 };
 
 #endif /* _SPI_CHANNEL_H_ */
diff --git a/arch/blackfin/include/asm/bfin_rotary.h b/arch/blackfin/include/asm/bfin_rotary.h
new file mode 100644
index 0000000..425ece6
--- /dev/null
+++ b/arch/blackfin/include/asm/bfin_rotary.h
@@ -0,0 +1,39 @@
+/*
+ * board initialization should put one of these structures into platform_data
+ * and place the bfin-rotary onto platform_bus named "bfin-rotary".
+ */
+
+#ifndef _BFIN_ROTARY_H
+#define _BFIN_ROTARY_H
+
+/* mode bitmasks */
+#define ROT_QUAD_ENC	CNTMODE_QUADENC	/* quadrature/grey code encoder mode */
+#define ROT_BIN_ENC	CNTMODE_BINENC	/* binary encoder mode */
+#define ROT_UD_CNT	CNTMODE_UDCNT	/* rotary counter mode */
+#define ROT_DIR_CNT	CNTMODE_DIRCNT	/* direction counter mode */
+
+#define ROT_DEBE	DEBE		/* Debounce Enable */
+
+#define ROT_CDGINV	CDGINV		/* CDG Pin Polarity Invert */
+#define ROT_CUDINV	CUDINV		/* CUD Pin Polarity Invert */
+#define ROT_CZMINV	CZMINV		/* CZM Pin Polarity Invert */
+
+struct bfin_rotary_platform_data {
+	/* set rotary UP KEY_### or BTN_### in case you prefer
+	 * bfin-rotary to send EV_KEY otherwise set 0
+	 */
+	unsigned int rotary_up_key;
+	/* set rotary DOWN KEY_### or BTN_### in case you prefer
+	 * bfin-rotary to send EV_KEY otherwise set 0
+	 */
+	unsigned int rotary_down_key;
+	/* set rotary BUTTON KEY_### or BTN_### */
+	unsigned int rotary_button_key;
+	/* set rotary Relative Axis REL_### in case you prefer
+	 * bfin-rotary to send EV_REL otherwise set 0
+	 */
+	unsigned int rotary_rel_code;
+	unsigned short debounce;	/* 0..17 */
+	unsigned short mode;
+};
+#endif
diff --git a/arch/blackfin/include/asm/cplb.h b/arch/blackfin/include/asm/cplb.h
index c5dacf8..d18d168 100644
--- a/arch/blackfin/include/asm/cplb.h
+++ b/arch/blackfin/include/asm/cplb.h
@@ -125,4 +125,48 @@
 #define FAULT_USERSUPV  (1 << 17)
 #define FAULT_CPLBBITS  0x0000ffff
 
-#endif				/* _CPLB_H */
+#ifndef __ASSEMBLY__
+
+static inline void _disable_cplb(u32 mmr, u32 mask)
+{
+	u32 ctrl = bfin_read32(mmr) & ~mask;
+	/* CSYNC to ensure load store ordering */
+	__builtin_bfin_csync();
+	bfin_write32(mmr, ctrl);
+	__builtin_bfin_ssync();
+}
+static inline void disable_cplb(u32 mmr, u32 mask)
+{
+	u32 ctrl = bfin_read32(mmr) & ~mask;
+	CSYNC();
+	bfin_write32(mmr, ctrl);
+	SSYNC();
+}
+#define _disable_dcplb() _disable_cplb(DMEM_CONTROL, ENDCPLB)
+#define  disable_dcplb()  disable_cplb(DMEM_CONTROL, ENDCPLB)
+#define _disable_icplb() _disable_cplb(IMEM_CONTROL, ENICPLB)
+#define  disable_icplb()  disable_cplb(IMEM_CONTROL, ENICPLB)
+
+static inline void _enable_cplb(u32 mmr, u32 mask)
+{
+	u32 ctrl = bfin_read32(mmr) | mask;
+	/* CSYNC to ensure load store ordering */
+	__builtin_bfin_csync();
+	bfin_write32(mmr, ctrl);
+	__builtin_bfin_ssync();
+}
+static inline void enable_cplb(u32 mmr, u32 mask)
+{
+	u32 ctrl = bfin_read32(mmr) | mask;
+	CSYNC();
+	bfin_write32(mmr, ctrl);
+	SSYNC();
+}
+#define _enable_dcplb()  _enable_cplb(DMEM_CONTROL, ENDCPLB)
+#define  enable_dcplb()   enable_cplb(DMEM_CONTROL, ENDCPLB)
+#define _enable_icplb()  _enable_cplb(IMEM_CONTROL, ENICPLB)
+#define  enable_icplb()   enable_cplb(IMEM_CONTROL, ENICPLB)
+
+#endif		/* __ASSEMBLY__ */
+
+#endif		/* _CPLB_H */
diff --git a/arch/blackfin/include/asm/early_printk.h b/arch/blackfin/include/asm/early_printk.h
index 110f1c1..53a762b 100644
--- a/arch/blackfin/include/asm/early_printk.h
+++ b/arch/blackfin/include/asm/early_printk.h
@@ -21,8 +21,32 @@
  * GNU General Public License for more details.
  */
 
+
+#ifndef __ASM_EARLY_PRINTK_H__
+#define __ASM_EARLY_PRINTK_H__
+
 #ifdef CONFIG_EARLY_PRINTK
+/* For those that don't include it already */
+#include <linux/console.h>
+
 extern int setup_early_printk(char *);
+extern void enable_shadow_console(void);
+extern int shadow_console_enabled(void);
+extern void mark_shadow_error(void);
+extern void early_shadow_reg(unsigned long reg, unsigned int n);
+extern void early_shadow_write(struct console *con, const char *s,
+	unsigned int n) __attribute__((nonnull(2)));
+#define early_shadow_puts(str) early_shadow_write(NULL, str, strlen(str))
+#define early_shadow_stamp() \
+	do { \
+		early_shadow_puts(__FILE__ " : " __stringify(__LINE__) " ["); \
+		early_shadow_puts(__func__); \
+		early_shadow_puts("]\n"); \
+	} while (0)
 #else
 #define setup_early_printk(fmt) do { } while (0)
+#define enable_shadow_console(fmt)  do { } while (0)
+#define early_shadow_stamp() do { } while (0)
 #endif /* CONFIG_EARLY_PRINTK */
+
+#endif /* __ASM_EARLY_PRINTK_H__ */
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index 5a87baf..c823e8e 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -23,7 +23,7 @@ typedef unsigned long elf_greg_t;
 #define ELF_NGREG 40 /* (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) */
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
-typedef struct user_bfinfp_struct elf_fpregset_t;
+typedef struct { } elf_fpregset_t;
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
diff --git a/arch/blackfin/include/asm/entry.h b/arch/blackfin/include/asm/entry.h
index ec58efc..55b808f 100644
--- a/arch/blackfin/include/asm/entry.h
+++ b/arch/blackfin/include/asm/entry.h
@@ -36,6 +36,21 @@
 # define LOAD_IPIPE_IPEND
 #endif
 
+/*
+ * Workaround for anomalies 05000283 and 05000315
+ */
+#if ANOMALY_05000283 || ANOMALY_05000315
+# define ANOMALY_283_315_WORKAROUND(preg, dreg)		\
+	cc = dreg == dreg;				\
+	preg.h = HI(CHIPID);				\
+	preg.l = LO(CHIPID);				\
+	if cc jump 1f;					\
+	dreg.l = W[preg];				\
+1:
+#else
+# define ANOMALY_283_315_WORKAROUND(preg, dreg)
+#endif /* ANOMALY_05000283 || ANOMALY_05000315 */
+
 #ifndef CONFIG_EXACT_HWERR
 /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
  * otherwise it is a waste of cycles.
@@ -88,17 +103,22 @@
  * As you can see by the code - we actually need to do two SSYNCS - one to
  * make sure the read/writes complete, and another to make sure the hardware
  * error is recognized by the core.
+ *
+ * The extra nop before the SSYNC is to make sure we work around 05000244,
+ * since the 283/315 workaround includes a branch to the end
  */
 #define INTERRUPT_ENTRY(N)						\
-    SSYNC;								\
-    SSYNC;								\
     [--sp] = SYSCFG;							\
     [--sp] = P0;	/*orig_p0*/					\
     [--sp] = R0;	/*orig_r0*/					\
     [--sp] = (R7:0,P5:0);						\
     R1 = ASTAT;								\
+    ANOMALY_283_315_WORKAROUND(p0, r0)					\
     P0.L = LO(ILAT);							\
     P0.H = HI(ILAT);							\
+    NOP;								\
+    SSYNC;								\
+    SSYNC;								\
     R0 = [P0];								\
     CC = BITTST(R0, EVT_IVHW_P);					\
     IF CC JUMP 1f;							\
@@ -118,15 +138,17 @@
     RTI;
 
 #define TIMER_INTERRUPT_ENTRY(N)					\
-    SSYNC;								\
-    SSYNC;								\
     [--sp] = SYSCFG;							\
     [--sp] = P0;	/*orig_p0*/					\
     [--sp] = R0;	/*orig_r0*/					\
     [--sp] = (R7:0,P5:0);						\
     R1 = ASTAT;								\
+    ANOMALY_283_315_WORKAROUND(p0, r0)					\
     P0.L = LO(ILAT);							\
     P0.H = HI(ILAT);							\
+    NOP;								\
+    SSYNC;								\
+    SSYNC;								\
     R0 = [P0];								\
     CC = BITTST(R0, EVT_IVHW_P);					\
     IF CC JUMP 1f;							\
diff --git a/arch/blackfin/include/asm/ftrace.h b/arch/blackfin/include/asm/ftrace.h
index 8643680..90c9b40 100644
--- a/arch/blackfin/include/asm/ftrace.h
+++ b/arch/blackfin/include/asm/ftrace.h
@@ -8,6 +8,6 @@
 #ifndef __ASM_BFIN_FTRACE_H__
 #define __ASM_BFIN_FTRACE_H__
 
-#define MCOUNT_INSN_SIZE	8 /* sizeof mcount call: LINK + CALL */
+#define MCOUNT_INSN_SIZE	6 /* sizeof "[++sp] = rets; call __mcount;" */
 
 #endif
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h
index 87ba9ad..4617ba6 100644
--- a/arch/blackfin/include/asm/ipipe.h
+++ b/arch/blackfin/include/asm/ipipe.h
@@ -145,10 +145,6 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs);
 
 int __ipipe_get_irq_priority(unsigned irq);
 
-void __ipipe_stall_root_raw(void);
-
-void __ipipe_unstall_root_raw(void);
-
 void __ipipe_serial_debug(const char *fmt, ...);
 
 asmlinkage void __ipipe_call_irqtail(unsigned long addr);
@@ -234,9 +230,6 @@ int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc);
 #define task_hijacked(p)		0
 #define ipipe_trap_notify(t, r)  	0
 
-#define __ipipe_stall_root_raw()	do { } while (0)
-#define __ipipe_unstall_root_raw()	do { } while (0)
-
 #define ipipe_init_irq_threads()		do { } while (0)
 #define ipipe_start_irq_thread(irq, desc)	0
 
diff --git a/arch/blackfin/include/asm/irq_handler.h b/arch/blackfin/include/asm/irq_handler.h
index 139b520..7d9e2d3 100644
--- a/arch/blackfin/include/asm/irq_handler.h
+++ b/arch/blackfin/include/asm/irq_handler.h
@@ -17,6 +17,7 @@ asmlinkage void evt_evt10(void);
 asmlinkage void evt_evt11(void);
 asmlinkage void evt_evt12(void);
 asmlinkage void evt_evt13(void);
+asmlinkage void evt_evt14(void);
 asmlinkage void evt_soft_int1(void);
 asmlinkage void evt_system_call(void);
 asmlinkage void init_exception_buff(void);
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index 944e29f..040410b 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -127,17 +127,17 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr,
 	unsigned long idx = page >> 5;
 	unsigned long bit = 1 << (page & 31);
 
-	if (flags & VM_MAYREAD)
+	if (flags & VM_READ)
 		mask[idx] |= bit;
 	else
 		mask[idx] &= ~bit;
 	mask += page_mask_nelts;
-	if (flags & VM_MAYWRITE)
+	if (flags & VM_WRITE)
 		mask[idx] |= bit;
 	else
 		mask[idx] &= ~bit;
 	mask += page_mask_nelts;
-	if (flags & VM_MAYEXEC)
+	if (flags & VM_EXEC)
 		mask[idx] |= bit;
 	else
 		mask[idx] &= ~bit;
diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h
index b42555c..a6f9569 100644
--- a/arch/blackfin/include/asm/pda.h
+++ b/arch/blackfin/include/asm/pda.h
@@ -50,6 +50,7 @@ struct blackfin_pda {			/* Per-processor Data Area */
 	unsigned long ex_optr;
 	unsigned long ex_buf[4];
 	unsigned long ex_imask;		/* Saved imask from exception */
+	unsigned long ex_ipend;		/* Saved IPEND from exception */
 	unsigned long *ex_stack;	/* Exception stack space */
 
 #ifdef ANOMALY_05000261
@@ -60,6 +61,12 @@ struct blackfin_pda {			/* Per-processor Data Area */
 	unsigned long retx;
 	unsigned long seqstat;
 	unsigned int __nmi_count;	/* number of times NMI asserted on this CPU */
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+	unsigned long dcplb_doublefault_addr;
+	unsigned long icplb_doublefault_addr;
+	unsigned long retx_doublefault;
+	unsigned long seqstat_doublefault;
+#endif
 };
 
 extern struct blackfin_pda cpu_pda[];
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index c8e7ee4..02b1529 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -381,7 +381,7 @@
 #define __NR_preadv		366
 #define __NR_pwritev		367
 #define __NR_rt_tgsigqueueinfo	368
-#define __NR_perf_counter_open	369
+#define __NR_perf_event_open	369
 
 #define __NR_syscall		370
 #define NR_syscalls		__NR_syscall
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index 141d928..a8ddbc8 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MODULES)                += module.o
 obj-$(CONFIG_KGDB)                   += kgdb.o
 obj-$(CONFIG_KGDB_TESTS)             += kgdb_test.o
 obj-$(CONFIG_EARLY_PRINTK)           += early_printk.o
+obj-$(CONFIG_EARLY_PRINTK)           += shadow_console.o
 obj-$(CONFIG_STACKTRACE)             += stacktrace.o
 
 # the kgdb test puts code into L2 and without linker
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index b5df945..f05d1b9 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -145,6 +145,7 @@ int main(void)
 	DEFINE(PDA_EXBUF, offsetof(struct blackfin_pda, ex_buf));
 	DEFINE(PDA_EXIMASK, offsetof(struct blackfin_pda, ex_imask));
 	DEFINE(PDA_EXSTACK, offsetof(struct blackfin_pda, ex_stack));
+	DEFINE(PDA_EXIPEND, offsetof(struct blackfin_pda, ex_ipend));
 #ifdef ANOMALY_05000261
 	DEFINE(PDA_LFRETX, offsetof(struct blackfin_pda, last_cplb_fault_retx));
 #endif
@@ -152,6 +153,12 @@ int main(void)
 	DEFINE(PDA_ICPLB, offsetof(struct blackfin_pda, icplb_fault_addr));
 	DEFINE(PDA_RETX, offsetof(struct blackfin_pda, retx));
 	DEFINE(PDA_SEQSTAT, offsetof(struct blackfin_pda, seqstat));
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+	DEFINE(PDA_DF_DCPLB, offsetof(struct blackfin_pda, dcplb_doublefault_addr));
+	DEFINE(PDA_DF_ICPLB, offsetof(struct blackfin_pda, icplb_doublefault_addr));
+	DEFINE(PDA_DF_SEQSTAT, offsetof(struct blackfin_pda, seqstat_doublefault));
+	DEFINE(PDA_DF_RETX, offsetof(struct blackfin_pda, retx_doublefault));
+#endif
 #ifdef CONFIG_SMP
 	/* Inter-core lock (in L2 SRAM) */
 	DEFINE(SIZEOF_CORELOCK, sizeof(struct corelock_slot));
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 9f9b828..384868d 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -19,6 +19,7 @@
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
+#include <asm/early_printk.h>
 
 /*
  * To make sure we work around 05000119 - we always check DMA_DONE bit,
@@ -146,8 +147,8 @@ EXPORT_SYMBOL(request_dma);
 
 int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data)
 {
-	BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
-	       && channel < MAX_DMA_CHANNELS));
+	BUG_ON(channel >= MAX_DMA_CHANNELS ||
+			dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
 
 	if (callback != NULL) {
 		int ret;
@@ -181,8 +182,8 @@ static void clear_dma_buffer(unsigned int channel)
 void free_dma(unsigned int channel)
 {
 	pr_debug("freedma() : BEGIN \n");
-	BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
-	       && channel < MAX_DMA_CHANNELS));
+	BUG_ON(channel >= MAX_DMA_CHANNELS ||
+			dma_ch[channel].chan_status == DMA_CHANNEL_FREE);
 
 	/* Halt the DMA */
 	disable_dma(channel);
@@ -236,6 +237,7 @@ void blackfin_dma_resume(void)
  */
 void __init blackfin_dma_early_init(void)
 {
+	early_shadow_stamp();
 	bfin_write_MDMA_S0_CONFIG(0);
 	bfin_write_MDMA_S1_CONFIG(0);
 }
@@ -246,6 +248,8 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
 	unsigned long src = (unsigned long)psrc;
 	struct dma_register *dst_ch, *src_ch;
 
+	early_shadow_stamp();
+
 	/* We assume that everything is 4 byte aligned, so include
 	 * a basic sanity check
 	 */
@@ -300,6 +304,8 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
 
 void __init early_dma_memcpy_done(void)
 {
+	early_shadow_stamp();
+
 	while ((bfin_read_MDMA_S0_CONFIG() && !(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) ||
 	       (bfin_read_MDMA_S1_CONFIG() && !(bfin_read_MDMA_D1_IRQ_STATUS() & DMA_DONE)))
 		continue;
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 6b94462..fc4681c 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -722,7 +722,6 @@ void bfin_gpio_pm_hibernate_suspend(void)
 		gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer;
 		gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux;
 		gpio_bank_saved[bank].data = gpio_array[bank]->data;
-		gpio_bank_saved[bank].data = gpio_array[bank]->data;
 		gpio_bank_saved[bank].inen = gpio_array[bank]->inen;
 		gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set;
 	}
diff --git a/arch/blackfin/kernel/cplb-mpu/Makefile b/arch/blackfin/kernel/cplb-mpu/Makefile
index 7d70d3b..394d0b1 100644
--- a/arch/blackfin/kernel/cplb-mpu/Makefile
+++ b/arch/blackfin/kernel/cplb-mpu/Makefile
@@ -2,7 +2,7 @@
 # arch/blackfin/kernel/cplb-nompu/Makefile
 #
 
-obj-y := cplbinit.o cacheinit.o cplbmgr.o
+obj-y := cplbinit.o cplbmgr.o
 
 CFLAGS_cplbmgr.o := -ffixed-I0 -ffixed-I1 -ffixed-I2 -ffixed-I3 \
 		    -ffixed-L0 -ffixed-L1 -ffixed-L2 -ffixed-L3 \
diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
deleted file mode 100644
index d5a86c3..0000000
--- a/arch/blackfin/kernel/cplb-mpu/cacheinit.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *               Copyright 2004-2007 Analog Devices 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 the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/cpu.h>
-
-#include <asm/cacheflush.h>
-#include <asm/blackfin.h>
-#include <asm/cplb.h>
-#include <asm/cplbinit.h>
-
-#if defined(CONFIG_BFIN_ICACHE)
-void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
-{
-	unsigned long ctrl;
-	int i;
-
-	SSYNC();
-	for (i = 0; i < MAX_CPLBS; i++) {
-		bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
-		bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
-	}
-	ctrl = bfin_read_IMEM_CONTROL();
-	ctrl |= IMC | ENICPLB;
-	bfin_write_IMEM_CONTROL(ctrl);
-	SSYNC();
-}
-#endif
-
-#if defined(CONFIG_BFIN_DCACHE)
-void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
-{
-	unsigned long ctrl;
-	int i;
-
-	SSYNC();
-	for (i = 0; i < MAX_CPLBS; i++) {
-		bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
-		bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
-	}
-
-	ctrl = bfin_read_DMEM_CONTROL();
-
-	/*
-	 *  Anomaly notes:
-	 *  05000287 - We implement workaround #2 - Change the DMEM_CONTROL
-	 *  register, so that the port preferences for DAG0 and DAG1 are set
-	 *  to port B
-	 */
-	ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
-	bfin_write_DMEM_CONTROL(ctrl);
-	SSYNC();
-}
-#endif
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index bcdfe9b..8e1e9e9 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -22,6 +22,7 @@
 
 #include <asm/blackfin.h>
 #include <asm/cacheflush.h>
+#include <asm/cplb.h>
 #include <asm/cplbinit.h>
 #include <asm/mmu_context.h>
 
@@ -41,46 +42,6 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS];
 int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS];
 int nr_cplb_flush[NR_CPUS];
 
-static inline void disable_dcplb(void)
-{
-	unsigned long ctrl;
-	SSYNC();
-	ctrl = bfin_read_DMEM_CONTROL();
-	ctrl &= ~ENDCPLB;
-	bfin_write_DMEM_CONTROL(ctrl);
-	SSYNC();
-}
-
-static inline void enable_dcplb(void)
-{
-	unsigned long ctrl;
-	SSYNC();
-	ctrl = bfin_read_DMEM_CONTROL();
-	ctrl |= ENDCPLB;
-	bfin_write_DMEM_CONTROL(ctrl);
-	SSYNC();
-}
-
-static inline void disable_icplb(void)
-{
-	unsigned long ctrl;
-	SSYNC();
-	ctrl = bfin_read_IMEM_CONTROL();
-	ctrl &= ~ENICPLB;
-	bfin_write_IMEM_CONTROL(ctrl);
-	SSYNC();
-}
-
-static inline void enable_icplb(void)
-{
-	unsigned long ctrl;
-	SSYNC();
-	ctrl = bfin_read_IMEM_CONTROL();
-	ctrl |= ENICPLB;
-	bfin_write_IMEM_CONTROL(ctrl);
-	SSYNC();
-}
-
 /*
  * Given the contents of the status register, return the index of the
  * CPLB that caused the fault.
@@ -198,10 +159,10 @@ static noinline int dcplb_miss(unsigned int cpu)
 	dcplb_tbl[cpu][idx].addr = addr;
 	dcplb_tbl[cpu][idx].data = d_data;
 
-	disable_dcplb();
+	_disable_dcplb();
 	bfin_write32(DCPLB_DATA0 + idx * 4, d_data);
 	bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
-	enable_dcplb();
+	_enable_dcplb();
 
 	return 0;
 }
@@ -288,10 +249,10 @@ static noinline int icplb_miss(unsigned int cpu)
 	icplb_tbl[cpu][idx].addr = addr;
 	icplb_tbl[cpu][idx].data = i_data;
 
-	disable_icplb();
+	_disable_icplb();
 	bfin_write32(ICPLB_DATA0 + idx * 4, i_data);
 	bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
-	enable_icplb();
+	_enable_icplb();
 
 	return 0;
 }
@@ -319,7 +280,7 @@ static noinline int dcplb_protection_fault(unsigned int cpu)
 int cplb_hdr(int seqstat, struct pt_regs *regs)
 {
 	int cause = seqstat & 0x3f;
-	unsigned int cpu = smp_processor_id();
+	unsigned int cpu = raw_smp_processor_id();
 	switch (cause) {
 	case 0x23:
 		return dcplb_protection_fault(cpu);
@@ -340,19 +301,19 @@ void flush_switched_cplbs(unsigned int cpu)
 	nr_cplb_flush[cpu]++;
 
 	local_irq_save_hw(flags);
-	disable_icplb();
+	_disable_icplb();
 	for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
 		icplb_tbl[cpu][i].data = 0;
 		bfin_write32(ICPLB_DATA0 + i * 4, 0);
 	}
-	enable_icplb();
+	_enable_icplb();
 
-	disable_dcplb();
+	_disable_dcplb();
 	for (i = first_switched_dcplb; i < MAX_CPLBS; i++) {
 		dcplb_tbl[cpu][i].data = 0;
 		bfin_write32(DCPLB_DATA0 + i * 4, 0);
 	}
-	enable_dcplb();
+	_enable_dcplb();
 	local_irq_restore_hw(flags);
 
 }
@@ -385,7 +346,7 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
 #endif
 	}
 
-	disable_dcplb();
+	_disable_dcplb();
 	for (i = first_mask_dcplb; i < first_switched_dcplb; i++) {
 		dcplb_tbl[cpu][i].addr = addr;
 		dcplb_tbl[cpu][i].data = d_data;
@@ -393,6 +354,6 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
 		bfin_write32(DCPLB_ADDR0 + i * 4, addr);
 		addr += PAGE_SIZE;
 	}
-	enable_dcplb();
+	_enable_dcplb();
 	local_irq_restore_hw(flags);
 }
diff --git a/arch/blackfin/kernel/cplb-nompu/Makefile b/arch/blackfin/kernel/cplb-nompu/Makefile
index 7d70d3b..394d0b1 100644
--- a/arch/blackfin/kernel/cplb-nompu/Makefile
+++ b/arch/blackfin/kernel/cplb-nompu/Makefile
@@ -2,7 +2,7 @@
 # arch/blackfin/kernel/cplb-nompu/Makefile
 #
 
-obj-y := cplbinit.o cacheinit.o cplbmgr.o
+obj-y := cplbinit.o cplbmgr.o
 
 CFLAGS_cplbmgr.o := -ffixed-I0 -ffixed-I1 -ffixed-I2 -ffixed-I3 \
 		    -ffixed-L0 -ffixed-L1 -ffixed-L2 -ffixed-L3 \
diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
deleted file mode 100644
index d5a86c3..0000000
--- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *               Copyright 2004-2007 Analog Devices 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 the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/cpu.h>
-
-#include <asm/cacheflush.h>
-#include <asm/blackfin.h>
-#include <asm/cplb.h>
-#include <asm/cplbinit.h>
-
-#if defined(CONFIG_BFIN_ICACHE)
-void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
-{
-	unsigned long ctrl;
-	int i;
-
-	SSYNC();
-	for (i = 0; i < MAX_CPLBS; i++) {
-		bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
-		bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
-	}
-	ctrl = bfin_read_IMEM_CONTROL();
-	ctrl |= IMC | ENICPLB;
-	bfin_write_IMEM_CONTROL(ctrl);
-	SSYNC();
-}
-#endif
-
-#if defined(CONFIG_BFIN_DCACHE)
-void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
-{
-	unsigned long ctrl;
-	int i;
-
-	SSYNC();
-	for (i = 0; i < MAX_CPLBS; i++) {
-		bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
-		bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
-	}
-
-	ctrl = bfin_read_DMEM_CONTROL();
-
-	/*
-	 *  Anomaly notes:
-	 *  05000287 - We implement workaround #2 - Change the DMEM_CONTROL
-	 *  register, so that the port preferences for DAG0 and DAG1 are set
-	 *  to port B
-	 */
-	ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
-	bfin_write_DMEM_CONTROL(ctrl);
-	SSYNC();
-}
-#endif
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 685f160..5d8ad50 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -36,7 +36,7 @@ int first_switched_icplb PDT_ATTR;
 int first_switched_dcplb PDT_ATTR;
 
 struct cplb_boundary dcplb_bounds[9] PDT_ATTR;
-struct cplb_boundary icplb_bounds[7] PDT_ATTR;
+struct cplb_boundary icplb_bounds[9] PDT_ATTR;
 
 int icplb_nr_bounds PDT_ATTR;
 int dcplb_nr_bounds PDT_ATTR;
@@ -167,14 +167,21 @@ void __init generate_cplb_tables_all(void)
 		icplb_bounds[i_i++].data = (reserved_mem_icache_on ?
 					    SDRAM_IGENERIC : SDRAM_INON_CHBL);
 	}
+	/* Addressing hole up to the async bank.  */
+	icplb_bounds[i_i].eaddr = ASYNC_BANK0_BASE;
+	icplb_bounds[i_i++].data = 0;
+	/* ASYNC banks.  */
+	icplb_bounds[i_i].eaddr = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE;
+	icplb_bounds[i_i++].data = SDRAM_EBIU;
 	/* Addressing hole up to BootROM.  */
 	icplb_bounds[i_i].eaddr = BOOT_ROM_START;
 	icplb_bounds[i_i++].data = 0;
 	/* BootROM -- largest one should be less than 1 meg.  */
 	icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024);
 	icplb_bounds[i_i++].data = SDRAM_IGENERIC;
+
 	if (L2_LENGTH) {
-		/* Addressing hole up to L2 SRAM, including the async bank.  */
+		/* Addressing hole up to L2 SRAM.  */
 		icplb_bounds[i_i].eaddr = L2_START;
 		icplb_bounds[i_i++].data = 0;
 		/* L2 SRAM.  */
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index 12b0308..d9ea46c 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -48,36 +48,13 @@ int nr_cplb_flush[NR_CPUS], nr_dcplb_prot[NR_CPUS];
 #define MGR_ATTR
 #endif
 
-/*
- * We're in an exception handler.  The normal cli nop nop workaround
- * isn't going to do very much, as the only thing that can interrupt
- * us is an NMI, and the cli isn't going to stop that.
- */
-#define NOWA_SSYNC __asm__ __volatile__ ("ssync;")
-
-/* Anomaly handlers provide SSYNCs, so avoid extra if anomaly is present */
-#if ANOMALY_05000125
-
-#define bfin_write_DMEM_CONTROL_SSYNC(v)    bfin_write_DMEM_CONTROL(v)
-#define bfin_write_IMEM_CONTROL_SSYNC(v)    bfin_write_IMEM_CONTROL(v)
-
-#else
-
-#define bfin_write_DMEM_CONTROL_SSYNC(v) \
-    do { NOWA_SSYNC; bfin_write_DMEM_CONTROL(v); NOWA_SSYNC; } while (0)
-#define bfin_write_IMEM_CONTROL_SSYNC(v) \
-    do { NOWA_SSYNC; bfin_write_IMEM_CONTROL(v); NOWA_SSYNC; } while (0)
-
-#endif
-
 static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
 				    unsigned long addr)
 {
-	unsigned long ctrl = bfin_read_DMEM_CONTROL();
-	bfin_write_DMEM_CONTROL_SSYNC(ctrl & ~ENDCPLB);
+	_disable_dcplb();
 	bfin_write32(DCPLB_DATA0 + idx * 4, data);
 	bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
-	bfin_write_DMEM_CONTROL_SSYNC(ctrl);
+	_enable_dcplb();
 
 #ifdef CONFIG_CPLB_INFO
 	dcplb_tbl[cpu][idx].addr = addr;
@@ -88,12 +65,10 @@ static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
 static inline void write_icplb_data(int cpu, int idx, unsigned long data,
 				    unsigned long addr)
 {
-	unsigned long ctrl = bfin_read_IMEM_CONTROL();
-
-	bfin_write_IMEM_CONTROL_SSYNC(ctrl & ~ENICPLB);
+	_disable_icplb();
 	bfin_write32(ICPLB_DATA0 + idx * 4, data);
 	bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
-	bfin_write_IMEM_CONTROL_SSYNC(ctrl);
+	_enable_icplb();
 
 #ifdef CONFIG_CPLB_INFO
 	icplb_tbl[cpu][idx].addr = addr;
@@ -227,7 +202,7 @@ MGR_ATTR static int dcplb_miss(int cpu)
 MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
 {
 	int cause = seqstat & 0x3f;
-	unsigned int cpu = smp_processor_id();
+	unsigned int cpu = raw_smp_processor_id();
 	switch (cause) {
 	case VEC_CPLB_I_M:
 		return icplb_miss(cpu);
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
index 2ab5681..931c78b 100644
--- a/arch/blackfin/kernel/early_printk.c
+++ b/arch/blackfin/kernel/early_printk.c
@@ -27,6 +27,7 @@
 #include <linux/serial_core.h>
 #include <linux/console.h>
 #include <linux/string.h>
+#include <linux/reboot.h>
 #include <asm/blackfin.h>
 #include <asm/irq_handler.h>
 #include <asm/early_printk.h>
@@ -181,6 +182,22 @@ asmlinkage void __init init_early_exception_vectors(void)
 	u32 evt;
 	SSYNC();
 
+	/*
+	 * This starts up the shadow buffer, incase anything crashes before
+	 * setup arch
+	 */
+	mark_shadow_error();
+	early_shadow_puts(linux_banner);
+	early_shadow_stamp();
+
+	if (CPUID != bfin_cpuid()) {
+		early_shadow_puts("Running on wrong machine type, expected");
+		early_shadow_reg(CPUID, 16);
+		early_shadow_puts(", but running on");
+		early_shadow_reg(bfin_cpuid(), 16);
+		early_shadow_puts("\n");
+	}
+
 	/* cannot program in software:
 	 * evt0 - emulation (jtag)
 	 * evt1 - reset
@@ -199,6 +216,7 @@ asmlinkage void __init init_early_exception_vectors(void)
 
 }
 
+__attribute__((__noreturn__))
 asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
 {
 	/* This can happen before the uart is initialized, so initialize
@@ -210,10 +228,58 @@ asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
 	if (likely(early_console == NULL) && CPUID == bfin_cpuid())
 		setup_early_printk(DEFAULT_EARLY_PORT);
 
-	printk(KERN_EMERG "Early panic\n");
-	dump_bfin_mem(fp);
-	show_regs(fp);
-	dump_bfin_trace_buffer();
+	if (!shadow_console_enabled()) {
+		/* crap - we crashed before setup_arch() */
+		early_shadow_puts("panic before setup_arch\n");
+		early_shadow_puts("IPEND:");
+		early_shadow_reg(fp->ipend, 16);
+		if (fp->seqstat & SEQSTAT_EXCAUSE) {
+			early_shadow_puts("\nEXCAUSE:");
+			early_shadow_reg(fp->seqstat & SEQSTAT_EXCAUSE, 8);
+		}
+		if (fp->seqstat & SEQSTAT_HWERRCAUSE) {
+			early_shadow_puts("\nHWERRCAUSE:");
+			early_shadow_reg(
+				(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14, 8);
+		}
+		early_shadow_puts("\nErr @");
+		if (fp->ipend & EVT_EVX)
+			early_shadow_reg(fp->retx, 32);
+		else
+			early_shadow_reg(fp->pc, 32);
+#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
+		early_shadow_puts("\nTrace:");
+		if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
+			while (bfin_read_TBUFSTAT() & TBUFCNT) {
+				early_shadow_puts("\nT  :");
+				early_shadow_reg(bfin_read_TBUF(), 32);
+				early_shadow_puts("\n S :");
+				early_shadow_reg(bfin_read_TBUF(), 32);
+			}
+		}
+#endif
+		early_shadow_puts("\nUse bfin-elf-addr2line to determine "
+			"function names\n");
+		/*
+		 * We should panic(), but we can't - since panic calls printk,
+		 * and printk uses memcpy.
+		 * we want to reboot, but if the machine type is different,
+		 * can't due to machine specific reboot sequences
+		 */
+		if (CPUID == bfin_cpuid()) {
+			early_shadow_puts("Trying to restart\n");
+			machine_restart("");
+		}
+
+		early_shadow_puts("Halting, since it is not safe to restart\n");
+		while (1)
+			asm volatile ("EMUEXCPT; IDLE;\n");
+
+	} else {
+		printk(KERN_EMERG "Early panic\n");
+		show_regs(fp);
+		dump_bfin_trace_buffer();
+	}
 
 	panic("Died early");
 }
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
index a9cfba9..3f8769b 100644
--- a/arch/blackfin/kernel/entry.S
+++ b/arch/blackfin/kernel/entry.S
@@ -43,8 +43,28 @@
 
 ENTRY(_ret_from_fork)
 #ifdef CONFIG_IPIPE
-	[--sp] = reti; 		/* IRQs on. */
-	SP += 4;
+	/*
+	 * Hw IRQs are off on entry, and we don't want the scheduling tail
+	 * code to starve high priority domains from interrupts while it
+	 * runs. Therefore we first stall the root stage to have the
+	 * virtual interrupt state reflect IMASK.
+	 */
+	p0.l = ___ipipe_root_status;
+	p0.h = ___ipipe_root_status;
+	r4 = [p0];
+	bitset(r4, 0);
+	[p0] = r4;
+	/*
+	 * Then we may enable hw IRQs, allowing preemption from high
+	 * priority domains. schedule_tail() will do local_irq_enable()
+	 * since Blackfin does not define __ARCH_WANT_UNLOCKED_CTXSW, so
+	 * there is no need to unstall the root domain by ourselves
+	 * afterwards.
+	 */
+	p0.l = _bfin_irq_flags;
+	p0.h = _bfin_irq_flags;
+	r4 = [p0];
+	sti r4;
 #endif /* CONFIG_IPIPE */
 	SP += -12;
 	call _schedule_tail;
diff --git a/arch/blackfin/kernel/ftrace-entry.S b/arch/blackfin/kernel/ftrace-entry.S
index 6980b7a..76dd4fb 100644
--- a/arch/blackfin/kernel/ftrace-entry.S
+++ b/arch/blackfin/kernel/ftrace-entry.S
@@ -17,8 +17,8 @@
  * only one we can blow away.  With pointer registers, we have P0-P2.
  *
  * Upon entry, the RETS will point to the top of the current profiled
- * function.  And since GCC setup the frame for us, the previous function
- * will be waiting there.  mmmm pie.
+ * function.  And since GCC pushed the previous RETS for us, the previous
+ * function will be waiting there.  mmmm pie.
  */
 ENTRY(__mcount)
 	/* save third function arg early so we can do testing below */
@@ -70,14 +70,14 @@ ENTRY(__mcount)
 	/* setup the tracer function */
 	p0 = r3;
 
-	/* tracer(ulong frompc, ulong selfpc):
-	 *  frompc: the pc that did the call to ...
-	 *  selfpc: ... this location
-	 * the selfpc itself will need adjusting for the mcount call
+	/* function_trace_call(unsigned long ip, unsigned long parent_ip):
+	 *  ip: this point was called by ...
+	 *  parent_ip: ... this function
+	 * the ip itself will need adjusting for the mcount call
 	 */
-	r1 = rets;
-	r0 = [fp + 4];
-	r1 += -MCOUNT_INSN_SIZE;
+	r0 = rets;
+	r1 = [sp + 16];	/* skip the 4 local regs on stack */
+	r0 += -MCOUNT_INSN_SIZE;
 
 	/* call the tracer */
 	call (p0);
@@ -106,9 +106,10 @@ ENTRY(_ftrace_graph_caller)
 	[--sp] = r1;
 	[--sp] = rets;
 
-	r0 = fp;
+	/* prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) */
+	r0 = sp;
 	r1 = rets;
-	r0 += 4;
+	r0 += 16;	/* skip the 4 local regs on stack */
 	r1 += -MCOUNT_INSN_SIZE;
 	call _prepare_ftrace_return;
 
diff --git a/arch/blackfin/kernel/ftrace.c b/arch/blackfin/kernel/ftrace.c
index 905bfc4..f2c85ac 100644
--- a/arch/blackfin/kernel/ftrace.c
+++ b/arch/blackfin/kernel/ftrace.c
@@ -24,7 +24,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
 	if (unlikely(atomic_read(&current->tracing_graph_pause)))
 		return;
 
-	if (ftrace_push_return_trace(*parent, self_addr, &trace.depth) == -EBUSY)
+	if (ftrace_push_return_trace(*parent, self_addr, &trace.depth, 0) == -EBUSY)
 		return;
 
 	trace.func = self_addr;
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
index b8d2203..5d73823 100644
--- a/arch/blackfin/kernel/ipipe.c
+++ b/arch/blackfin/kernel/ipipe.c
@@ -30,10 +30,10 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kthread.h>
-#include <asm/unistd.h>
+#include <linux/unistd.h>
+#include <linux/io.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
-#include <asm/io.h>
 
 DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
 
@@ -90,6 +90,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
 	struct ipipe_percpu_domain_data *p = ipipe_root_cpudom_ptr();
 	struct ipipe_domain *this_domain, *next_domain;
 	struct list_head *head, *pos;
+	struct ipipe_irqdesc *idesc;
 	int m_ack, s = -1;
 
 	/*
@@ -100,17 +101,20 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
 	 */
 	m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR);
 	this_domain = __ipipe_current_domain;
+	idesc = &this_domain->irqs[irq];
 
-	if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control)))
+	if (unlikely(test_bit(IPIPE_STICKY_FLAG, &idesc->control)))
 		head = &this_domain->p_link;
 	else {
 		head = __ipipe_pipeline.next;
 		next_domain = list_entry(head, struct ipipe_domain, p_link);
-		if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) {
-			if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
-				next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq));
+		idesc = &next_domain->irqs[irq];
+		if (likely(test_bit(IPIPE_WIRED_FLAG, &idesc->control))) {
+			if (!m_ack && idesc->acknowledge != NULL)
+				idesc->acknowledge(irq, irq_to_desc(irq));
 			if (test_bit(IPIPE_SYNCDEFER_FLAG, &p->status))
-				s = __test_and_set_bit(IPIPE_STALL_FLAG, &p->status);
+				s = __test_and_set_bit(IPIPE_STALL_FLAG,
+						       &p->status);
 			__ipipe_dispatch_wired(next_domain, irq);
 			goto out;
 		}
@@ -121,14 +125,15 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
 	pos = head;
 	while (pos != &__ipipe_pipeline) {
 		next_domain = list_entry(pos, struct ipipe_domain, p_link);
-		if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) {
+		idesc = &next_domain->irqs[irq];
+		if (test_bit(IPIPE_HANDLE_FLAG, &idesc->control)) {
 			__ipipe_set_irq_pending(next_domain, irq);
-			if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) {
-				next_domain->irqs[irq].acknowledge(irq, irq_to_desc(irq));
+			if (!m_ack && idesc->acknowledge != NULL) {
+				idesc->acknowledge(irq, irq_to_desc(irq));
 				m_ack = 1;
 			}
 		}
-		if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control))
+		if (!test_bit(IPIPE_PASS_FLAG, &idesc->control))
 			break;
 		pos = next_domain->p_link.next;
 	}
@@ -159,11 +164,6 @@ out:
 		__clear_bit(IPIPE_STALL_FLAG, &p->status);
 }
 
-int __ipipe_check_root(void)
-{
-	return ipipe_root_domain_p;
-}
-
 void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
@@ -186,30 +186,6 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
 }
 EXPORT_SYMBOL(__ipipe_disable_irqdesc);
 
-void __ipipe_stall_root_raw(void)
-{
-	/*
-	 * This code is called by the ins{bwl} routines (see
-	 * arch/blackfin/lib/ins.S), which are heavily used by the
-	 * network stack. It masks all interrupts but those handled by
-	 * non-root domains, so that we keep decent network transfer
-	 * rates for Linux without inducing pathological jitter for
-	 * the real-time domain.
-	 */
-	__asm__ __volatile__ ("sti %0;" : : "d"(__ipipe_irq_lvmask));
-
-	__set_bit(IPIPE_STALL_FLAG,
-		  &ipipe_root_cpudom_var(status));
-}
-
-void __ipipe_unstall_root_raw(void)
-{
-	__clear_bit(IPIPE_STALL_FLAG,
-		    &ipipe_root_cpudom_var(status));
-
-	__asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags));
-}
-
 int __ipipe_syscall_root(struct pt_regs *regs)
 {
 	struct ipipe_percpu_domain_data *p;
@@ -333,12 +309,29 @@ asmlinkage void __ipipe_sync_root(void)
 
 void ___ipipe_sync_pipeline(unsigned long syncmask)
 {
-	if (__ipipe_root_domain_p) {
-		if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))
-			return;
-	}
+	if (__ipipe_root_domain_p &&
+	    test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))
+		return;
 
 	__ipipe_sync_stage(syncmask);
 }
 
-EXPORT_SYMBOL(show_stack);
+void __ipipe_disable_root_irqs_hw(void)
+{
+	/*
+	 * This code is called by the ins{bwl} routines (see
+	 * arch/blackfin/lib/ins.S), which are heavily used by the
+	 * network stack. It masks all interrupts but those handled by
+	 * non-root domains, so that we keep decent network transfer
+	 * rates for Linux without inducing pathological jitter for
+	 * the real-time domain.
+	 */
+	bfin_sti(__ipipe_irq_lvmask);
+	__set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+}
+
+void __ipipe_enable_root_irqs_hw(void)
+{
+	__clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+	bfin_sti(bfin_irq_flags);
+}
diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c
index dbcf3e4..59fc42d 100644
--- a/arch/blackfin/kernel/kgdb_test.c
+++ b/arch/blackfin/kernel/kgdb_test.c
@@ -54,7 +54,7 @@ void kgdb_l2_test(void)
 
 int kgdb_test(char *name, int len, int count, int z)
 {
-	printk(KERN_DEBUG "kgdb name(%d): %s, %d, %d\n", len, name, count, z);
+	printk(KERN_ALERT "kgdb name(%d): %s, %d, %d\n", len, name, count, z);
 	count = z;
 	return count;
 }
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index d5aee36..67fc7a5 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -27,6 +27,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#define pr_fmt(fmt) "module %s: " fmt
 
 #include <linux/moduleloader.h>
 #include <linux/elf.h>
@@ -36,6 +37,7 @@
 #include <linux/kernel.h>
 #include <asm/dma.h>
 #include <asm/cacheflush.h>
+#include <asm/uaccess.h>
 
 void *module_alloc(unsigned long size)
 {
@@ -52,7 +54,7 @@ void module_free(struct module *mod, void *module_region)
 
 /* Transfer the section to the L1 memory */
 int
-module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
+module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 			  char *secstrings, struct module *mod)
 {
 	/*
@@ -63,126 +65,119 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
 	 * NOTE: this breaks the semantic of mod->arch structure.
 	 */
 	Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
-	void *dest = NULL;
+	void *dest;
 
 	for (s = sechdrs; s < sechdrs_end; ++s) {
-		if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
-		    ((strcmp(".text", secstrings + s->sh_name) == 0) &&
-		     (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) {
+		const char *shname = secstrings + s->sh_name;
+
+		if (s->sh_size == 0)
+			continue;
+
+		if (!strcmp(".l1.text", shname) ||
+		    (!strcmp(".text", shname) &&
+		     (hdr->e_flags & EF_BFIN_CODE_IN_L1))) {
+
 			dest = l1_inst_sram_alloc(s->sh_size);
 			mod->arch.text_l1 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-				       "module %s: L1 instruction memory allocation failed\n",
-				       mod->name);
+				pr_err("L1 inst memory allocation failed\n",
+					mod->name);
 				return -1;
 			}
 			dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
-		if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
-		    ((strcmp(".data", secstrings + s->sh_name) == 0) &&
-		     (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) {
+
+		} else if (!strcmp(".l1.data", shname) ||
+		           (!strcmp(".data", shname) &&
+		            (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {
+
 			dest = l1_data_sram_alloc(s->sh_size);
 			mod->arch.data_a_l1 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-					"module %s: L1 data memory allocation failed\n",
+				pr_err("L1 data memory allocation failed\n",
 					mod->name);
 				return -1;
 			}
 			memcpy(dest, (void *)s->sh_addr, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
-		if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
-		    ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
-		     (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) {
-			dest = l1_data_sram_alloc(s->sh_size);
+
+		} else if (!strcmp(".l1.bss", shname) ||
+		           (!strcmp(".bss", shname) &&
+		            (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {
+
+			dest = l1_data_sram_zalloc(s->sh_size);
 			mod->arch.bss_a_l1 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-					"module %s: L1 data memory allocation failed\n",
+				pr_err("L1 data memory allocation failed\n",
 					mod->name);
 				return -1;
 			}
-			memset(dest, 0, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
-		if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
+
+		} else if (!strcmp(".l1.data.B", shname)) {
+
 			dest = l1_data_B_sram_alloc(s->sh_size);
 			mod->arch.data_b_l1 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-					"module %s: L1 data memory allocation failed\n",
+				pr_err("L1 data memory allocation failed\n",
 					mod->name);
 				return -1;
 			}
 			memcpy(dest, (void *)s->sh_addr, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
-		if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
+
+		} else if (!strcmp(".l1.bss.B", shname)) {
+
 			dest = l1_data_B_sram_alloc(s->sh_size);
 			mod->arch.bss_b_l1 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-					"module %s: L1 data memory allocation failed\n",
+				pr_err("L1 data memory allocation failed\n",
 					mod->name);
 				return -1;
 			}
 			memset(dest, 0, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
-		if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) ||
-		    ((strcmp(".text", secstrings + s->sh_name) == 0) &&
-		     (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) {
+
+		} else if (!strcmp(".l2.text", shname) ||
+		           (!strcmp(".text", shname) &&
+		            (hdr->e_flags & EF_BFIN_CODE_IN_L2))) {
+
 			dest = l2_sram_alloc(s->sh_size);
 			mod->arch.text_l2 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-				       "module %s: L2 SRAM allocation failed\n",
-				       mod->name);
+				pr_err("L2 SRAM allocation failed\n",
+					mod->name);
 				return -1;
 			}
 			memcpy(dest, (void *)s->sh_addr, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
-		if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) ||
-		    ((strcmp(".data", secstrings + s->sh_name) == 0) &&
-		     (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) {
+
+		} else if (!strcmp(".l2.data", shname) ||
+		           (!strcmp(".data", shname) &&
+		            (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {
+
 			dest = l2_sram_alloc(s->sh_size);
 			mod->arch.data_l2 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-					"module %s: L2 SRAM allocation failed\n",
+				pr_err("L2 SRAM allocation failed\n",
 					mod->name);
 				return -1;
 			}
 			memcpy(dest, (void *)s->sh_addr, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
-		if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 ||
-		    ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
-		     (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) {
-			dest = l2_sram_alloc(s->sh_size);
+
+		} else if (!strcmp(".l2.bss", shname) ||
+		           (!strcmp(".bss", shname) &&
+		            (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {
+
+			dest = l2_sram_zalloc(s->sh_size);
 			mod->arch.bss_l2 = dest;
 			if (dest == NULL) {
-				printk(KERN_ERR
-					"module %s: L2 SRAM allocation failed\n",
+				pr_err("L2 SRAM allocation failed\n",
 					mod->name);
 				return -1;
 			}
-			memset(dest, 0, s->sh_size);
-			s->sh_flags &= ~SHF_ALLOC;
-			s->sh_addr = (unsigned long)dest;
-		}
+
+		} else
+			continue;
+
+		s->sh_flags &= ~SHF_ALLOC;
+		s->sh_addr = (unsigned long)dest;
 	}
+
 	return 0;
 }
 
@@ -190,7 +185,7 @@ int
 apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
 	       unsigned int symindex, unsigned int relsec, struct module *me)
 {
-	printk(KERN_ERR "module %s: .rel unsupported\n", me->name);
+	pr_err(".rel unsupported\n", me->name);
 	return -ENOEXEC;
 }
 
@@ -205,109 +200,86 @@ apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
 /*            gas does not generate it.                                  */
 /*************************************************************************/
 int
-apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
+apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
 		   unsigned int symindex, unsigned int relsec,
 		   struct module *mod)
 {
 	unsigned int i;
-	unsigned short tmp;
 	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
 	Elf32_Sym *sym;
-	uint32_t *location32;
-	uint16_t *location16;
-	uint32_t value;
+	unsigned long location, value, size;
+
+	pr_debug("applying relocate section %u to %u\n", mod->name,
+		relsec, sechdrs[relsec].sh_info);
 
-	pr_debug("Applying relocate section %u to %u\n", relsec,
-	       sechdrs[relsec].sh_info);
 	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
 		/* This is where to make the change */
-		location16 =
-		    (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr +
-				  rel[i].r_offset);
-		location32 = (uint32_t *) location16;
+		location = sechdrs[sechdrs[relsec].sh_info].sh_addr +
+		           rel[i].r_offset;
+
 		/* This is the symbol it is referring to. Note that all
 		   undefined symbols have been resolved. */
 		sym = (Elf32_Sym *) sechdrs[symindex].sh_addr
 		    + ELF32_R_SYM(rel[i].r_info);
 		value = sym->st_value;
 		value += rel[i].r_addend;
-		pr_debug("location is %x, value is %x type is %d \n",
-			 (unsigned int) location32, value,
-			 ELF32_R_TYPE(rel[i].r_info));
+
 #ifdef CONFIG_SMP
-		if ((unsigned long)location16 >= COREB_L1_DATA_A_START) {
-			printk(KERN_ERR "module %s: cannot relocate in L1: %u (SMP kernel)",
-				       mod->name, ELF32_R_TYPE(rel[i].r_info));
+		if (location >= COREB_L1_DATA_A_START) {
+			pr_err("cannot relocate in L1: %u (SMP kernel)",
+				mod->name, ELF32_R_TYPE(rel[i].r_info));
 			return -ENOEXEC;
 		}
 #endif
+
+		pr_debug("location is %lx, value is %lx type is %d\n",
+			mod->name, location, value, ELF32_R_TYPE(rel[i].r_info));
+
 		switch (ELF32_R_TYPE(rel[i].r_info)) {
 
+		case R_BFIN_HUIMM16:
+			value >>= 16;
+		case R_BFIN_LUIMM16:
+		case R_BFIN_RIMM16:
+			size = 2;
+			break;
+		case R_BFIN_BYTE4_DATA:
+			size = 4;
+			break;
+
 		case R_BFIN_PCREL24:
 		case R_BFIN_PCREL24_JUMP_L:
-			/* Add the value, subtract its postition */
-			location16 =
-			    (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].
-					  sh_addr + rel[i].r_offset - 2);
-			location32 = (uint32_t *) location16;
-			value -= (uint32_t) location32;
-			value >>= 1;
-			if ((value & 0xFF000000) != 0 &&
-			    (value & 0xFF000000) != 0xFF000000) {
-				printk(KERN_ERR "module %s: relocation overflow\n",
-				       mod->name);
-				return -ENOEXEC;
-			}
-			pr_debug("value is %x, before %x-%x after %x-%x\n", value,
-			       *location16, *(location16 + 1),
-			       (*location16 & 0xff00) | (value >> 16 & 0x00ff),
-			       value & 0xffff);
-			*location16 =
-			    (*location16 & 0xff00) | (value >> 16 & 0x00ff);
-			*(location16 + 1) = value & 0xffff;
-			break;
 		case R_BFIN_PCREL12_JUMP:
 		case R_BFIN_PCREL12_JUMP_S:
-			value -= (uint32_t) location32;
-			value >>= 1;
-			*location16 = (value & 0xfff);
-			break;
 		case R_BFIN_PCREL10:
-			value -= (uint32_t) location32;
-			value >>= 1;
-			*location16 = (value & 0x3ff);
-			break;
-		case R_BFIN_LUIMM16:
-			pr_debug("before %x after %x\n", *location16,
-				       (value & 0xffff));
-			tmp = (value & 0xffff);
-			if ((unsigned long)location16 >= L1_CODE_START) {
-				dma_memcpy(location16, &tmp, 2);
-			} else
-				*location16 = tmp;
-			break;
-		case R_BFIN_HUIMM16:
-			pr_debug("before %x after %x\n", *location16,
-				       ((value >> 16) & 0xffff));
-			tmp = ((value >> 16) & 0xffff);
-			if ((unsigned long)location16 >= L1_CODE_START) {
-				dma_memcpy(location16, &tmp, 2);
-			} else
-				*location16 = tmp;
+			pr_err("unsupported relocation: %u (no -mlong-calls?)\n",
+				mod->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+
+		default:
+			pr_err("unknown relocation: %u\n", mod->name,
+				ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+
+		switch (bfin_mem_access_type(location, size)) {
+		case BFIN_MEM_ACCESS_CORE:
+		case BFIN_MEM_ACCESS_CORE_ONLY:
+			memcpy((void *)location, &value, size);
 			break;
-		case R_BFIN_RIMM16:
-			*location16 = (value & 0xffff);
+		case BFIN_MEM_ACCESS_DMA:
+			dma_memcpy((void *)location, &value, size);
 			break;
-		case R_BFIN_BYTE4_DATA:
-			pr_debug("before %x after %x\n", *location32, value);
-			*location32 = value;
+		case BFIN_MEM_ACCESS_ITEST:
+			isram_memcpy((void *)location, &value, size);
 			break;
 		default:
-			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
-			       mod->name, ELF32_R_TYPE(rel[i].r_info));
+			pr_err("invalid relocation for %#lx\n",
+				mod->name, location);
 			return -ENOEXEC;
 		}
 	}
+
 	return 0;
 }
 
@@ -332,22 +304,28 @@ module_finalize(const Elf_Ehdr * hdr,
 	for (i = 1; i < hdr->e_shnum; i++) {
 		const char *strtab = (char *)sechdrs[strindex].sh_addr;
 		unsigned int info = sechdrs[i].sh_info;
+		const char *shname = secstrings + sechdrs[i].sh_name;
 
 		/* Not a valid relocation section? */
 		if (info >= hdr->e_shnum)
 			continue;
 
-		if ((sechdrs[i].sh_type == SHT_RELA) &&
-		    ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) ||
-		    (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) ||
-		    ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
-			(hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) {
+		/* Only support RELA relocation types */
+		if (sechdrs[i].sh_type != SHT_RELA)
+			continue;
+
+		if (!strcmp(".rela.l2.text", shname) ||
+		    !strcmp(".rela.l1.text", shname) ||
+		    (!strcmp(".rela.text", shname) &&
+			 (hdr->e_flags & (EF_BFIN_CODE_IN_L1 | EF_BFIN_CODE_IN_L2)))) {
+
 			err = apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
 					   symindex, i, mod);
 			if (err < 0)
 				return -ENOEXEC;
 		}
 	}
+
 	return 0;
 }
 
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 9da36ba..f5b2861 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -282,25 +282,19 @@ void finish_atomic_sections (struct pt_regs *regs)
 {
 	int __user *up0 = (int __user *)regs->p0;
 
-	if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
-		return;
-
 	switch (regs->pc) {
 	case ATOMIC_XCHG32 + 2:
 		put_user(regs->r1, up0);
-		regs->pc += 2;
+		regs->pc = ATOMIC_XCHG32 + 4;
 		break;
 
 	case ATOMIC_CAS32 + 2:
 	case ATOMIC_CAS32 + 4:
 		if (regs->r0 == regs->r1)
+	case ATOMIC_CAS32 + 6:
 			put_user(regs->r2, up0);
 		regs->pc = ATOMIC_CAS32 + 8;
 		break;
-	case ATOMIC_CAS32 + 6:
-		put_user(regs->r2, up0);
-		regs->pc += 2;
-		break;
 
 	case ATOMIC_ADD32 + 2:
 		regs->r0 = regs->r1 + regs->r0;
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 6a387ee..30f4828 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -206,6 +206,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	int ret;
 	unsigned long __user *datap = (unsigned long __user *)data;
+	void *paddr = (void *)addr;
 
 	switch (request) {
 		/* when I and D space are separate, these will need to be fixed. */
@@ -215,42 +216,49 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 	case PTRACE_PEEKTEXT:	/* read word at location addr. */
 		{
 			unsigned long tmp = 0;
-			int copied;
+			int copied = 0, to_copy = sizeof(tmp);
 
 			ret = -EIO;
-			pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %ld\n", addr, sizeof(data));
-			if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0)
+			pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + %i\n", addr, to_copy);
+			if (is_user_addr_valid(child, addr, to_copy) < 0)
 				break;
 			pr_debug("ptrace: user address is valid\n");
 
-			if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start()
-			    && addr + sizeof(tmp) <= get_l1_code_start() + L1_CODE_LENGTH) {
-				safe_dma_memcpy (&tmp, (const void *)(addr), sizeof(tmp));
-				copied = sizeof(tmp);
-
-			} else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START
-			    && addr + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) {
-				memcpy(&tmp, (const void *)(addr), sizeof(tmp));
-				copied = sizeof(tmp);
-
-			} else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START
-			    && addr + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) {
-				memcpy(&tmp, (const void *)(addr), sizeof(tmp));
-				copied = sizeof(tmp);
-
-			} else if (addr >= FIXED_CODE_START
-			    && addr + sizeof(tmp) <= FIXED_CODE_END) {
-				copy_from_user_page(0, 0, 0, &tmp, (const void *)(addr), sizeof(tmp));
-				copied = sizeof(tmp);
-
-			} else
+			switch (bfin_mem_access_type(addr, to_copy)) {
+			case BFIN_MEM_ACCESS_CORE:
+			case BFIN_MEM_ACCESS_CORE_ONLY:
 				copied = access_process_vm(child, addr, &tmp,
-							   sizeof(tmp), 0);
+				                           to_copy, 0);
+				if (copied)
+					break;
+
+				/* hrm, why didn't that work ... maybe no mapping */
+				if (addr >= FIXED_CODE_START &&
+				    addr + to_copy <= FIXED_CODE_END) {
+					copy_from_user_page(0, 0, 0, &tmp, paddr, to_copy);
+					copied = to_copy;
+				} else if (addr >= BOOT_ROM_START) {
+					memcpy(&tmp, paddr, to_copy);
+					copied = to_copy;
+				}
 
-			pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
-			if (copied != sizeof(tmp))
 				break;
-			ret = put_user(tmp, datap);
+			case BFIN_MEM_ACCESS_DMA:
+				if (safe_dma_memcpy(&tmp, paddr, to_copy))
+					copied = to_copy;
+				break;
+			case BFIN_MEM_ACCESS_ITEST:
+				if (isram_memcpy(&tmp, paddr, to_copy))
+					copied = to_copy;
+				break;
+			default:
+				copied = 0;
+				break;
+			}
+
+			pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
+			if (copied == to_copy)
+				ret = put_user(tmp, datap);
 			break;
 		}
 
@@ -277,9 +285,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 				tmp = child->mm->start_data;
 #ifdef CONFIG_BINFMT_ELF_FDPIC
 			} else if (addr == (sizeof(struct pt_regs) + 12)) {
-				tmp = child->mm->context.exec_fdpic_loadmap;
+				goto case_PTRACE_GETFDPIC_EXEC;
 			} else if (addr == (sizeof(struct pt_regs) + 16)) {
-				tmp = child->mm->context.interp_fdpic_loadmap;
+				goto case_PTRACE_GETFDPIC_INTERP;
 #endif
 			} else {
 				tmp = get_reg(child, addr);
@@ -288,49 +296,78 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 			break;
 		}
 
+#ifdef CONFIG_BINFMT_ELF_FDPIC
+	case PTRACE_GETFDPIC: {
+		unsigned long tmp = 0;
+
+		switch (addr) {
+		case_PTRACE_GETFDPIC_EXEC:
+		case PTRACE_GETFDPIC_EXEC:
+			tmp = child->mm->context.exec_fdpic_loadmap;
+			break;
+		case_PTRACE_GETFDPIC_INTERP:
+		case PTRACE_GETFDPIC_INTERP:
+			tmp = child->mm->context.interp_fdpic_loadmap;
+			break;
+		default:
+			break;
+		}
+
+		ret = put_user(tmp, datap);
+		break;
+	}
+#endif
+
 		/* when I and D space are separate, this will have to be fixed. */
 	case PTRACE_POKEDATA:
 		pr_debug("ptrace: PTRACE_PEEKDATA\n");
 		/* fall through */
 	case PTRACE_POKETEXT:	/* write the word at location addr. */
 		{
-			int copied;
+			int copied = 0, to_copy = sizeof(data);
 
 			ret = -EIO;
-			pr_debug("ptrace: POKETEXT at addr 0x%08lx + %ld bytes %lx\n",
-			         addr, sizeof(data), data);
-			if (is_user_addr_valid(child, addr, sizeof(data)) < 0)
+			pr_debug("ptrace: POKETEXT at addr 0x%08lx + %i bytes %lx\n",
+			         addr, to_copy, data);
+			if (is_user_addr_valid(child, addr, to_copy) < 0)
 				break;
 			pr_debug("ptrace: user address is valid\n");
 
-			if (L1_CODE_LENGTH != 0 && addr >= get_l1_code_start()
-			    && addr + sizeof(data) <= get_l1_code_start() + L1_CODE_LENGTH) {
-				safe_dma_memcpy ((void *)(addr), &data, sizeof(data));
-				copied = sizeof(data);
-
-			} else if (L1_DATA_A_LENGTH != 0 && addr >= L1_DATA_A_START
-			    && addr + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) {
-				memcpy((void *)(addr), &data, sizeof(data));
-				copied = sizeof(data);
-
-			} else if (L1_DATA_B_LENGTH != 0 && addr >= L1_DATA_B_START
-			    && addr + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) {
-				memcpy((void *)(addr), &data, sizeof(data));
-				copied = sizeof(data);
-
-			} else if (addr >= FIXED_CODE_START
-			    && addr + sizeof(data) <= FIXED_CODE_END) {
-				copy_to_user_page(0, 0, 0, (void *)(addr), &data, sizeof(data));
-				copied = sizeof(data);
-
-			} else
+			switch (bfin_mem_access_type(addr, to_copy)) {
+			case BFIN_MEM_ACCESS_CORE:
+			case BFIN_MEM_ACCESS_CORE_ONLY:
 				copied = access_process_vm(child, addr, &data,
-							   sizeof(data), 1);
+				                           to_copy, 0);
+				if (copied)
+					break;
+
+				/* hrm, why didn't that work ... maybe no mapping */
+				if (addr >= FIXED_CODE_START &&
+				    addr + to_copy <= FIXED_CODE_END) {
+					copy_to_user_page(0, 0, 0, paddr, &data, to_copy);
+					copied = to_copy;
+				} else if (addr >= BOOT_ROM_START) {
+					memcpy(paddr, &data, to_copy);
+					copied = to_copy;
+				}
 
-			pr_debug("ptrace: copied size %d\n", copied);
-			if (copied != sizeof(data))
 				break;
-			ret = 0;
+			case BFIN_MEM_ACCESS_DMA:
+				if (safe_dma_memcpy(paddr, &data, to_copy))
+					copied = to_copy;
+				break;
+			case BFIN_MEM_ACCESS_ITEST:
+				if (isram_memcpy(paddr, &data, to_copy))
+					copied = to_copy;
+				break;
+			default:
+				copied = 0;
+				break;
+			}
+
+			pr_debug("ptrace: copied size %d\n", copied);
+			if (copied == to_copy)
+				ret = 0;
 			break;
 		}
 
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 6225eda..369535b 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -112,7 +112,7 @@ void __cpuinit bfin_setup_caches(unsigned int cpu)
 	/*
 	 * In cache coherence emulation mode, we need to have the
 	 * D-cache enabled before running any atomic operation which
-	 * might invove cache invalidation (i.e. spinlock, rwlock).
+	 * might involve cache invalidation (i.e. spinlock, rwlock).
 	 * So printk's are deferred until then.
 	 */
 #ifdef CONFIG_BFIN_ICACHE
@@ -187,6 +187,8 @@ void __init bfin_relocate_l1_mem(void)
 	unsigned long l1_data_b_length;
 	unsigned long l2_length;
 
+	early_shadow_stamp();
+
 	/*
 	 * due to the ALIGN(4) in the arch/blackfin/kernel/vmlinux.lds.S
 	 * we know that everything about l1 text/data is nice and aligned,
@@ -511,6 +513,7 @@ static __init void memory_setup(void)
 #ifdef CONFIG_MTD_UCLINUX
 	unsigned long mtd_phys = 0;
 #endif
+	unsigned long max_mem;
 
 	_rambase = (unsigned long)_stext;
 	_ramstart = (unsigned long)_end;
@@ -520,7 +523,22 @@ static __init void memory_setup(void)
 		panic("DMA region exceeds memory limit: %lu.",
 			_ramend - _ramstart);
 	}
-	memory_end = _ramend - DMA_UNCACHED_REGION;
+	max_mem = memory_end = _ramend - DMA_UNCACHED_REGION;
+
+#if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263)
+	/* Due to a Hardware Anomaly we need to limit the size of usable
+	 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
+	 * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+	 */
+# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
+	if (max_mem >= 56 * 1024 * 1024)
+		max_mem = 56 * 1024 * 1024;
+# else
+	if (max_mem >= 60 * 1024 * 1024)
+		max_mem = 60 * 1024 * 1024;
+# endif				/* CONFIG_DEBUG_HUNT_FOR_ZERO */
+#endif				/* ANOMALY_05000263 */
+
 
 #ifdef CONFIG_MPU
 	/* Round up to multiple of 4MB */
@@ -549,22 +567,16 @@ static __init void memory_setup(void)
 
 # if defined(CONFIG_ROMFS_FS)
 	if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0
-	    && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
+	    && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) {
 		mtd_size =
 		    PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
-#  if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263)
-	/* Due to a Hardware Anomaly we need to limit the size of usable
-	 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
-	 * 05000263 - Hardware loop corrupted when taking an ICPLB exception
-	 */
-#   if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
-	if (memory_end >= 56 * 1024 * 1024)
-		memory_end = 56 * 1024 * 1024;
-#   else
-	if (memory_end >= 60 * 1024 * 1024)
-		memory_end = 60 * 1024 * 1024;
-#   endif				/* CONFIG_DEBUG_HUNT_FOR_ZERO */
-#  endif				/* ANOMALY_05000263 */
+
+		/* ROM_FS is XIP, so if we found it, we need to limit memory */
+		if (memory_end > max_mem) {
+			pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20);
+			memory_end = max_mem;
+		}
+	}
 # endif				/* CONFIG_ROMFS_FS */
 
 	/* Since the default MTD_UCLINUX has no magic number, we just blindly
@@ -586,20 +598,14 @@ static __init void memory_setup(void)
 	}
 #endif				/* CONFIG_MTD_UCLINUX */
 
-#if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263)
-	/* Due to a Hardware Anomaly we need to limit the size of usable
-	 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
-	 * 05000263 - Hardware loop corrupted when taking an ICPLB exception
+	/* We need lo limit memory, since everything could have a text section
+	 * of userspace in it, and expose anomaly 05000263. If the anomaly
+	 * doesn't exist, or we don't need to - then dont.
 	 */
-#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO))
-	if (memory_end >= 56 * 1024 * 1024)
-		memory_end = 56 * 1024 * 1024;
-#else
-	if (memory_end >= 60 * 1024 * 1024)
-		memory_end = 60 * 1024 * 1024;
-#endif				/* CONFIG_DEBUG_HUNT_FOR_ZERO */
-	printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20);
-#endif				/* ANOMALY_05000263 */
+	if (memory_end > max_mem) {
+		pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20);
+		memory_end = max_mem;
+	}
 
 #ifdef CONFIG_MPU
 	page_mask_nelts = ((_ramend >> PAGE_SHIFT) + 31) / 32;
@@ -693,7 +699,7 @@ static __init void setup_bootmem_allocator(void)
 	sanitize_memmap(bfin_memmap.map, &bfin_memmap.nr_map);
 	print_memory_map("boot memmap");
 
-	/* intialize globals in linux/bootmem.h */
+	/* initialize globals in linux/bootmem.h */
 	find_min_max_pfn();
 	/* pfn of the last usable page frame */
 	if (max_pfn > memory_end >> PAGE_SHIFT)
@@ -806,6 +812,8 @@ void __init setup_arch(char **cmdline_p)
 {
 	unsigned long sclk, cclk;
 
+	enable_shadow_console();
+
 	/* Check to make sure we are running on the right processor */
 	if (unlikely(CPUID != bfin_cpuid()))
 		printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n",
@@ -1230,57 +1238,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 #ifdef __ARCH_SYNC_CORE_ICACHE
 	seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
 #endif
-#ifdef CONFIG_BFIN_ICACHE_LOCK
-	switch ((cpudata->imemctl >> 3) & WAYALL_L) {
-	case WAY0_L:
-		seq_printf(m, "Way0 Locked-Down\n");
-		break;
-	case WAY1_L:
-		seq_printf(m, "Way1 Locked-Down\n");
-		break;
-	case WAY01_L:
-		seq_printf(m, "Way0,Way1 Locked-Down\n");
-		break;
-	case WAY2_L:
-		seq_printf(m, "Way2 Locked-Down\n");
-		break;
-	case WAY02_L:
-		seq_printf(m, "Way0,Way2 Locked-Down\n");
-		break;
-	case WAY12_L:
-		seq_printf(m, "Way1,Way2 Locked-Down\n");
-		break;
-	case WAY012_L:
-		seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n");
-		break;
-	case WAY3_L:
-		seq_printf(m, "Way3 Locked-Down\n");
-		break;
-	case WAY03_L:
-		seq_printf(m, "Way0,Way3 Locked-Down\n");
-		break;
-	case WAY13_L:
-		seq_printf(m, "Way1,Way3 Locked-Down\n");
-		break;
-	case WAY013_L:
-		seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n");
-		break;
-	case WAY32_L:
-		seq_printf(m, "Way3,Way2 Locked-Down\n");
-		break;
-	case WAY320_L:
-		seq_printf(m, "Way3,Way2,Way0 Locked-Down\n");
-		break;
-	case WAY321_L:
-		seq_printf(m, "Way3,Way2,Way1 Locked-Down\n");
-		break;
-	case WAYALL_L:
-		seq_printf(m, "All Ways are locked\n");
-		break;
-	default:
-		seq_printf(m, "No Ways are locked\n");
-	}
-#endif
 
 	if (cpu_num != num_possible_cpus() - 1)
 		return 0;
@@ -1346,6 +1303,7 @@ const struct seq_operations cpuinfo_op = {
 
 void __init cmdline_init(const char *r0)
 {
+	early_shadow_stamp();
 	if (r0)
 		strncpy(command_line, r0, COMMAND_LINE_SIZE);
 }
diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c
new file mode 100644
index 0000000..8b8c710
--- /dev/null
+++ b/arch/blackfin/kernel/shadow_console.c
@@ -0,0 +1,113 @@
+/*
+ * manage a small early shadow of the log buffer which we can pass between the
+ * bootloader so early crash messages are communicated properly and easily
+ *
+ * Copyright 2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <asm/blackfin.h>
+#include <asm/irq_handler.h>
+#include <asm/early_printk.h>
+
+#define SHADOW_CONSOLE_START		(0x500)
+#define SHADOW_CONSOLE_END		(0x1000)
+#define SHADOW_CONSOLE_MAGIC_LOC	(0x4F0)
+#define SHADOW_CONSOLE_MAGIC		(0xDEADBEEF)
+
+static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START;
+
+__init void early_shadow_write(struct console *con, const char *s,
+				unsigned int n)
+{
+	unsigned int i;
+	/*
+	 * save 2 bytes for the double null at the end
+	 * once we fail on a long line, make sure we don't write a short line afterwards
+	 */
+	if ((shadow_console_buffer + n) <= (char *)(SHADOW_CONSOLE_END - 2)) {
+		/* can't use memcpy - it may not be relocated yet */
+		for (i = 0; i <= n; i++)
+			shadow_console_buffer[i] = s[i];
+		shadow_console_buffer += n;
+		shadow_console_buffer[0] = 0;
+		shadow_console_buffer[1] = 0;
+	} else
+		shadow_console_buffer = (char *)SHADOW_CONSOLE_END;
+}
+
+static __initdata struct console early_shadow_console = {
+	.name = "early_shadow",
+	.write = early_shadow_write,
+	.flags = CON_BOOT | CON_PRINTBUFFER,
+	.index = -1,
+	.device = 0,
+};
+
+__init int shadow_console_enabled(void)
+{
+	return early_shadow_console.flags & CON_ENABLED;
+}
+
+__init void mark_shadow_error(void)
+{
+	int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;
+	loc[0] = SHADOW_CONSOLE_MAGIC;
+	loc[1] = SHADOW_CONSOLE_START;
+}
+
+__init void enable_shadow_console(void)
+{
+	if (!shadow_console_enabled()) {
+		register_console(&early_shadow_console);
+		/* for now, assume things are going to fail */
+		mark_shadow_error();
+	}
+}
+
+static __init int disable_shadow_console(void)
+{
+	/*
+	 * by the time pure_initcall runs, the standard console is enabled,
+	 * and the early_console is off, so unset the magic numbers
+	 * unregistering the console is taken care of in common code (See
+	 * ./kernel/printk:disable_boot_consoles() )
+	 */
+	int *loc = (int *)SHADOW_CONSOLE_MAGIC_LOC;
+
+	loc[0] = 0;
+
+	return 0;
+}
+pure_initcall(disable_shadow_console);
+
+/*
+ * since we can't use printk, dump numbers (as hex), n = # bits
+ */
+__init void early_shadow_reg(unsigned long reg, unsigned int n)
+{
+	/*
+	 * can't use any "normal" kernel features, since thay
+	 * may not be relocated to their execute address yet
+	 */
+	int i;
+	char ascii[11] = " 0x";
+
+	n = n / 4;
+	reg = reg << ((8 - n) * 4);
+	n += 3;
+
+	for (i = 3; i <= n ; i++) {
+		ascii[i] = hex_asc_lo(reg >> 28);
+		reg <<= 4;
+	}
+	early_shadow_write(NULL, ascii, n);
+
+}
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 0791eba..f971576 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -66,7 +66,7 @@ static cycle_t bfin_read_cycles(struct clocksource *cs)
 
 static struct clocksource bfin_cs_cycles = {
 	.name		= "bfin_cs_cycles",
-	.rating		= 350,
+	.rating		= 400,
 	.read		= bfin_read_cycles,
 	.mask		= CLOCKSOURCE_MASK(64),
 	.shift		= 22,
@@ -115,7 +115,7 @@ static cycle_t bfin_read_gptimer0(void)
 
 static struct clocksource bfin_cs_gptimer0 = {
 	.name		= "bfin_cs_gptimer0",
-	.rating		= 400,
+	.rating		= 350,
 	.read		= bfin_read_gptimer0,
 	.mask		= CLOCKSOURCE_MASK(32),
 	.shift		= 22,
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index bf2b2d1..56464cb 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -100,7 +100,11 @@ static void decode_address(char *buf, unsigned long address)
 	char *modname;
 	char *delim = ":";
 	char namebuf[128];
+#endif
+
+	buf += sprintf(buf, "<0x%08lx> ", address);
 
+#ifdef CONFIG_KALLSYMS
 	/* look up the address and see if we are in kernel space */
 	symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
 
@@ -108,23 +112,33 @@ static void decode_address(char *buf, unsigned long address)
 		/* yeah! kernel space! */
 		if (!modname)
 			modname = delim = "";
-		sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }",
-		              (void *)address, delim, modname, delim, symname,
-		              (unsigned long)offset);
+		sprintf(buf, "{ %s%s%s%s + 0x%lx }",
+		        delim, modname, delim, symname,
+		        (unsigned long)offset);
 		return;
-
 	}
 #endif
 
-	/* Problem in fixed code section? */
 	if (address >= FIXED_CODE_START && address < FIXED_CODE_END) {
-		sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address);
+		/* Problem in fixed code section? */
+		strcat(buf, "/* Maybe fixed code section */");
+		return;
+
+	} else if (address < CONFIG_BOOT_LOAD) {
+		/* Problem somewhere before the kernel start address */
+		strcat(buf, "/* Maybe null pointer? */");
+		return;
+
+	} else if (address >= COREMMR_BASE) {
+		strcat(buf, "/* core mmrs */");
 		return;
-	}
 
-	/* Problem somewhere before the kernel start address */
-	if (address < CONFIG_BOOT_LOAD) {
-		sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address);
+	} else if (address >= SYSMMR_BASE) {
+		strcat(buf, "/* system mmrs */");
+		return;
+
+	} else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) {
+		strcat(buf, "/* on-chip L1 ROM */");
 		return;
 	}
 
@@ -172,18 +186,16 @@ static void decode_address(char *buf, unsigned long address)
 						offset = (address - vma->vm_start) +
 							 (vma->vm_pgoff << PAGE_SHIFT);
 
-					sprintf(buf, "<0x%p> [ %s + 0x%lx ]",
-						(void *)address, name, offset);
+					sprintf(buf, "[ %s + 0x%lx ]", name, offset);
 				} else
-					sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]",
-						(void *)address, name,
-						vma->vm_start, vma->vm_end);
+					sprintf(buf, "[ %s vma:0x%lx-0x%lx]",
+						name, vma->vm_start, vma->vm_end);
 
 				if (!in_atomic)
 					mmput(mm);
 
-				if (!strlen(buf))
-					sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name);
+				if (buf[0] == '\0')
+					sprintf(buf, "[ %s ] dynamic memory", name);
 
 				goto done;
 			}
@@ -193,7 +205,7 @@ static void decode_address(char *buf, unsigned long address)
 	}
 
 	/* we were unable to find this address anywhere */
-	sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address);
+	sprintf(buf, "/* kernel dynamic memory */");
 
 done:
 	write_unlock_irqrestore(&tasklist_lock, flags);
@@ -215,14 +227,14 @@ asmlinkage void double_fault_c(struct pt_regs *fp)
 	printk(KERN_EMERG "Double Fault\n");
 #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
 	if (((long)fp->seqstat &  SEQSTAT_EXCAUSE) == VEC_UNCOV) {
-		unsigned int cpu = smp_processor_id();
+		unsigned int cpu = raw_smp_processor_id();
 		char buf[150];
-		decode_address(buf, cpu_pda[cpu].retx);
+		decode_address(buf, cpu_pda[cpu].retx_doublefault);
 		printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n",
-			(unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf);
-		decode_address(buf, cpu_pda[cpu].dcplb_fault_addr);
+			(unsigned int)cpu_pda[cpu].seqstat_doublefault & SEQSTAT_EXCAUSE, buf);
+		decode_address(buf, cpu_pda[cpu].dcplb_doublefault_addr);
 		printk(KERN_NOTICE "   DCPLB_FAULT_ADDR: %s\n", buf);
-		decode_address(buf, cpu_pda[cpu].icplb_fault_addr);
+		decode_address(buf, cpu_pda[cpu].icplb_doublefault_addr);
 		printk(KERN_NOTICE "   ICPLB_FAULT_ADDR: %s\n", buf);
 
 		decode_address(buf, fp->retx);
@@ -245,13 +257,13 @@ static int kernel_mode_regs(struct pt_regs *regs)
 	return regs->ipend & 0xffc0;
 }
 
-asmlinkage void trap_c(struct pt_regs *fp)
+asmlinkage notrace void trap_c(struct pt_regs *fp)
 {
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
 	int j;
 #endif
 #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
-	unsigned int cpu = smp_processor_id();
+	unsigned int cpu = raw_smp_processor_id();
 #endif
 	const char *strerror = NULL;
 	int sig = 0;
@@ -267,11 +279,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
 	 * double faults if the stack has become corrupt
 	 */
 
-#ifndef CONFIG_KGDB
-	/* IPEND is skipped if KGDB isn't enabled (see entry code) */
-	fp->ipend = bfin_read_IPEND();
-#endif
-
 	/* trap_c() will be called for exceptions. During exceptions
 	 * processing, the pc value should be set with retx value.
 	 * With this change we can cleanup some code in signal.c- TODO
@@ -404,7 +411,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
 	/* 0x23 - Data CPLB protection violation, handled here */
 	case VEC_CPLB_VL:
 		info.si_code = ILL_CPLB_VI;
-		sig = SIGBUS;
+		sig = SIGSEGV;
 		strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE);
 		CHK_DEBUGGER_TRAP_MAYBE();
 		break;
@@ -904,7 +911,7 @@ void show_stack(struct task_struct *task, unsigned long *stack)
 		frame_no = 0;
 
 		for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0;
-		     addr <= endstack; addr++, i++) {
+		     addr < endstack; addr++, i++) {
 
 			ret_addr = 0;
 			if (!j && i % 8 == 0)
@@ -949,6 +956,7 @@ void show_stack(struct task_struct *task, unsigned long *stack)
 	}
 #endif
 }
+EXPORT_SYMBOL(show_stack);
 
 void dump_stack(void)
 {
@@ -1090,7 +1098,7 @@ void show_regs(struct pt_regs *fp)
 	struct irqaction *action;
 	unsigned int i;
 	unsigned long flags = 0;
-	unsigned int cpu = smp_processor_id();
+	unsigned int cpu = raw_smp_processor_id();
 	unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
 
 	verbose_printk(KERN_NOTICE "\n");
@@ -1116,10 +1124,16 @@ void show_regs(struct pt_regs *fp)
 
 	verbose_printk(KERN_NOTICE "%s", linux_banner);
 
-	verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n",
-		       print_tainted());
-	verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
-		       (long)fp->seqstat, fp->ipend, fp->syscfg);
+	verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted());
+	verbose_printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  IMASK: %04lx  SYSCFG: %04lx\n",
+		(long)fp->seqstat, fp->ipend, cpu_pda[raw_smp_processor_id()].ex_imask, fp->syscfg);
+	if (fp->ipend & EVT_IRPTEN)
+		verbose_printk(KERN_NOTICE "  Global Interrupts Disabled (IPEND[4])\n");
+	if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 |
+			EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR)))
+		verbose_printk(KERN_NOTICE "  Peripheral interrupts masked off\n");
+	if (!(cpu_pda[raw_smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14)))
+		verbose_printk(KERN_NOTICE "  Kernel interrupts masked off\n");
 	if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) {
 		verbose_printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
 			(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index 6ac307c..21ac7c2 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -221,7 +221,7 @@ SECTIONS
 		. = ALIGN(4);
 		__ebss_l1 = .;
 	}
-	ASSERT (SIZEOF(.data_a_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!")
+	ASSERT (SIZEOF(.data_l1) <= L1_DATA_A_LENGTH, "L1 data A overflow!")
 
 	.data_b_l1 L1_DATA_B_START : AT(LOADADDR(.data_l1) + SIZEOF(.data_l1))
 	{
@@ -262,7 +262,7 @@ SECTIONS
 		. = ALIGN(4);
 		__ebss_l2 = .;
 	}
-	ASSERT (SIZEOF(.text_data_l1) <= L2_LENGTH, "L2 overflow!")
+	ASSERT (SIZEOF(.text_data_l2) <= L2_LENGTH, "L2 overflow!")
 
 	/* Force trailing alignment of our init section so that when we
 	 * free our init memory, we don't leave behind a partial page.
@@ -277,8 +277,5 @@ SECTIONS
 
 	DWARF_DEBUG
 
-	/DISCARD/ :
-	{
-		*(.exitcall.exit)
-	}
+	DISCARDS
 }
diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S
index 1863a6b..3edbd8d 100644
--- a/arch/blackfin/lib/ins.S
+++ b/arch/blackfin/lib/ins.S
@@ -16,7 +16,7 @@
 	[--sp] = rets; \
 	[--sp] = (P5:0); \
 	sp += -12; \
-	call ___ipipe_stall_root_raw; \
+	call ___ipipe_disable_root_irqs_hw; \
 	sp += 12; \
 	(P5:0) = [sp++];
 # define CLI_INNER_NOP
@@ -28,7 +28,7 @@
 #ifdef CONFIG_IPIPE
 # define DO_STI \
 	sp += -12; \
-	call ___ipipe_unstall_root_raw; \
+	call ___ipipe_enable_root_irqs_hw; \
 	sp += 12; \
 2:	rets = [sp++];
 #else
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index 809be26..03e4a99 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -199,15 +199,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x4, /* send zero */
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
 	.enable_dma = 0,
@@ -296,24 +287,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 		.mode = SPI_MODE_3,
 	},
 #endif
-#if defined(CONFIG_PBX)
-	{
-		.modalias = "fxs-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J11_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-	{
-		.modalias = "fxo-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J19_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 	{
 		.modalias		= "ad7877",
@@ -539,7 +512,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
 	},
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
 		.irq = IRQ_PF8,
diff --git a/arch/blackfin/mach-bf518/include/mach/anomaly.h b/arch/blackfin/mach-bf518/include/mach/anomaly.h
index 753ed81..e9c6539 100644
--- a/arch/blackfin/mach-bf518/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf518/include/mach/anomaly.h
@@ -124,6 +124,7 @@
 #define ANOMALY_05000386 (0)
 #define ANOMALY_05000389 (0)
 #define ANOMALY_05000400 (0)
+#define ANOMALY_05000402 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000447 (0)
diff --git a/arch/blackfin/mach-bf518/include/mach/blackfin.h b/arch/blackfin/mach-bf518/include/mach/blackfin.h
index e8e14c2..83421d3 100644
--- a/arch/blackfin/mach-bf518/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf518/include/mach/blackfin.h
@@ -68,11 +68,6 @@
 #endif
 #endif
 
-/* UART_IIR Register */
-#define STATUS(x)	((x << 1) & 0x06)
-#define STATUS_P1	0x02
-#define STATUS_P0	0x01
-
 #define BFIN_UART_NR_PORTS	2
 
 #define OFFSET_THR              0x00	/* Transmit Holding register            */
@@ -88,11 +83,6 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks													*/
 #define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index b09484f..08a3f01 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -151,46 +151,6 @@ static struct platform_device musb_device = {
 };
 #endif
 
-#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
-static struct mtd_partition ezkit_partitions[] = {
-	{
-		.name       = "bootloader(nor)",
-		.size       = 0x40000,
-		.offset     = 0,
-	}, {
-		.name       = "linux kernel(nor)",
-		.size       = 0x1C0000,
-		.offset     = MTDPART_OFS_APPEND,
-	}, {
-		.name       = "file system(nor)",
-		.size       = MTDPART_SIZ_FULL,
-		.offset     = MTDPART_OFS_APPEND,
-	}
-};
-
-static struct physmap_flash_data ezkit_flash_data = {
-	.width      = 2,
-	.parts      = ezkit_partitions,
-	.nr_parts   = ARRAY_SIZE(ezkit_partitions),
-};
-
-static struct resource ezkit_flash_resource = {
-	.start = 0x20000000,
-	.end   = 0x201fffff,
-	.flags = IORESOURCE_MEM,
-};
-
-static struct platform_device ezkit_flash_device = {
-	.name          = "physmap-flash",
-	.id            = 0,
-	.dev = {
-		.platform_data = &ezkit_flash_data,
-	},
-	.num_resources = 1,
-	.resource      = &ezkit_flash_resource,
-};
-#endif
-
 #if defined(CONFIG_MTD_NAND_BF5XX) || defined(CONFIG_MTD_NAND_BF5XX_MODULE)
 static struct mtd_partition partition_info[] = {
 	{
@@ -275,6 +235,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -293,6 +261,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -300,10 +271,15 @@ static struct platform_device smc91x_device = {
 static struct resource dm9000_resources[] = {
 	[0] = {
 		.start	= 0x203FB800,
-		.end	= 0x203FB800 + 8,
+		.end	= 0x203FB800 + 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
+		.start	= 0x203FB804,
+		.end	= 0x203FB804 + 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
 		.start	= IRQ_PF9,
 		.end	= IRQ_PF9,
 		.flags	= (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
@@ -479,13 +455,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 	.enable_dma = 0,
@@ -493,15 +462,6 @@ static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x4, /* send zero */
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
 	.enable_dma = 0,
@@ -568,22 +528,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
 	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
 		.controller_data = &ad1836_spi_chip_info,
 	},
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-	{
-		.modalias = "ad9960-spi",
-		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &ad9960_spi_chip_info,
-	},
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
@@ -594,24 +545,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 		.mode = SPI_MODE_3,
 	},
 #endif
-#if defined(CONFIG_PBX)
-	{
-		.modalias = "fxs-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J11_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-	{
-		.modalias = "fxo-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J19_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 	{
 		.modalias		= "ad7877",
@@ -689,6 +622,55 @@ static struct platform_device bfin_fb_adv7393_device = {
 };
 #endif
 
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+static struct mtd_partition cm_partitions[] = {
+	{
+		.name   = "bootloader(nor)",
+		.size   = 0x40000,
+		.offset = 0,
+	}, {
+		.name   = "linux kernel(nor)",
+		.size   = 0x100000,
+		.offset = MTDPART_OFS_APPEND,
+	}, {
+		.name   = "file system(nor)",
+		.size   = MTDPART_SIZ_FULL,
+		.offset = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct physmap_flash_data cm_flash_data = {
+	.width    = 2,
+	.parts    = cm_partitions,
+	.nr_parts = ARRAY_SIZE(cm_partitions),
+};
+
+static unsigned cm_flash_gpios[] = { GPIO_PH9, GPIO_PG11 };
+
+static struct resource cm_flash_resource[] = {
+	{
+		.name  = "cfi_probe",
+		.start = 0x20000000,
+		.end   = 0x201fffff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = (unsigned long)cm_flash_gpios,
+		.end   = ARRAY_SIZE(cm_flash_gpios),
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device cm_flash_device = {
+	.name          = "gpio-addr-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &cm_flash_data,
+	},
+	.num_resources = ARRAY_SIZE(cm_flash_resource),
+	.resource      = cm_flash_resource,
+};
+#endif
+
 #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
 static struct resource bfin_uart_resources[] = {
 #ifdef CONFIG_SERIAL_BFIN_UART0
@@ -796,13 +778,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
-		.type = "pcf8574_lcd",
 	},
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
-		.type = "pcf8574_keypad",
 		.irq = IRQ_PF8,
 	},
 #endif
@@ -876,7 +856,7 @@ static struct platform_device bfin_dpmc = {
 	},
 };
 
-static struct platform_device *stamp_devices[] __initdata = {
+static struct platform_device *cmbf527_devices[] __initdata = {
 
 	&bfin_dpmc,
 
@@ -959,8 +939,8 @@ static struct platform_device *stamp_devices[] __initdata = {
 	&bfin_device_gpiokeys,
 #endif
 
-#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
-	&ezkit_flash_device,
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+	&cm_flash_device,
 #endif
 
 	&bfin_gpios_device,
@@ -971,7 +951,7 @@ static int __init cm_init(void)
 	printk(KERN_INFO "%s(): registering device resources\n", __func__);
 	i2c_register_board_info(0, bfin_i2c_board_info,
 				ARRAY_SIZE(bfin_i2c_board_info));
-	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+	platform_add_devices(cmbf527_devices, ARRAY_SIZE(cmbf527_devices));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 	return 0;
 }
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index 2ad68cd..68b4c80 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -263,15 +263,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x4, /* send zero */
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
 	.enable_dma = 0,
@@ -376,24 +367,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 		.mode = SPI_MODE_3,
 	},
 #endif
-#if defined(CONFIG_PBX)
-	{
-		.modalias = "fxs-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J11_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-	{
-		.modalias = "fxo-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J19_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 	{
 		.modalias		= "ad7877",
@@ -596,7 +569,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
 	},
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
 		.irq = IRQ_PF8,
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 75e563d..2849b09 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -292,6 +292,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -310,6 +318,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -501,13 +512,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 	.enable_dma = 0,
@@ -515,15 +519,6 @@ static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x4, /* send zero */
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
-};
-#endif
-
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
 	.enable_dma = 0,
@@ -614,22 +609,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
 	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
 		.controller_data = &ad1836_spi_chip_info,
 	},
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-	{
-		.modalias = "ad9960-spi",
-		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &ad9960_spi_chip_info,
-	},
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
@@ -641,24 +627,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 	},
 #endif
 
-#if defined(CONFIG_PBX)
-	{
-		.modalias = "fxs-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J11_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-	{
-		.modalias = "fxo-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J19_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 	{
 		.modalias		= "ad7877",
@@ -863,7 +831,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
 	},
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
 		.irq = IRQ_PF8,
diff --git a/arch/blackfin/mach-bf527/include/mach/anomaly.h b/arch/blackfin/mach-bf527/include/mach/anomaly.h
index c438ca8..3f90526 100644
--- a/arch/blackfin/mach-bf527/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf527/include/mach/anomaly.h
@@ -7,7 +7,7 @@
  */
 
 /* This file should be up to date with:
- *  - Revision C, 03/13/2009; ADSP-BF526 Blackfin Processor Anomaly List
+ *  - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List
  *  - Revision F, 03/03/2009; ADSP-BF527 Blackfin Processor Anomaly List
  */
 
@@ -176,7 +176,7 @@
 #define ANOMALY_05000443 (1)
 /* The WURESET Bit in the SYSCR Register is not Functional */
 #define ANOMALY_05000445 (1)
-/* USB DMA Short Packet Data Corruption */
+/* USB DMA Mode 1 Short Packet Data Corruption */
 #define ANOMALY_05000450 (1)
 /* BCODE_QUICKBOOT, BCODE_ALLBOOT, and BCODE_FULLBOOT Settings in SYSCR Register Not Functional */
 #define ANOMALY_05000451 (1)
@@ -186,12 +186,20 @@
 #define ANOMALY_05000456 (1)
 /* Host DMA Port Responds to Certain Bus Activity Without HOST_CE Assertion */
 #define ANOMALY_05000457 (1)
+/* USB DMA Mode 1 Failure When Multiple USB DMA Channels Are Concurrently Enabled */
+#define ANOMALY_05000460 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
+#define ANOMALY_05000462 (1)
 /* USB Rx DMA hang */
 #define ANOMALY_05000465 (1)
+/* TxPktRdy Bit Not Set for Transmit Endpoint When Core and DMA Access USB Endpoint FIFOs Simultaneously */
+#define ANOMALY_05000466 (1)
 /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */
 #define ANOMALY_05000467 (1)
+/* PLL Latches Incorrect Settings During Reset */
+#define ANOMALY_05000469 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
@@ -238,6 +246,7 @@
 #define ANOMALY_05000362 (1)
 #define ANOMALY_05000363 (0)
 #define ANOMALY_05000400 (0)
+#define ANOMALY_05000402 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
diff --git a/arch/blackfin/mach-bf527/include/mach/blackfin.h b/arch/blackfin/mach-bf527/include/mach/blackfin.h
index 03665a8..ea9cb0f 100644
--- a/arch/blackfin/mach-bf527/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf527/include/mach/blackfin.h
@@ -56,11 +56,6 @@
 #endif
 #endif
 
-/* UART_IIR Register */
-#define STATUS(x)	((x << 1) & 0x06)
-#define STATUS_P1	0x02
-#define STATUS_P0	0x01
-
 #define BFIN_UART_NR_PORTS	2
 
 #define OFFSET_THR              0x00	/* Transmit Holding register            */
@@ -76,11 +71,6 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks													*/
 #define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 38cf8ff..6c2b47f 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -88,6 +88,14 @@ static struct platform_device dm9000_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -110,6 +118,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -190,15 +201,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x1c04,
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
-};
-#endif
-
 /* Notice: for blackfin, the speed_hz is the value of register
  * SPI_BAUD, not the real baudrate */
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
@@ -229,7 +231,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 16,
 		.bus_num = 1,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -237,23 +239,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 	},
 #endif
 
-#if defined(CONFIG_PBX)
-	{
-		.modalias	 = "fxs-spi",
-		.max_speed_hz	 = 4,
-		.bus_num	 = 1,
-		.chip_select	 = 3,
-		.controller_data = &spi_si3xxx_chip_info,
-	},
-
-	{
-		.modalias	 = "fxo-spi",
-		.max_speed_hz	 = 4,
-		.bus_num	 = 1,
-		.chip_select	 = 2,
-		.controller_data = &spi_si3xxx_chip_info,
-	},
-#endif
 };
 
 /* SPI (0) */
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index 9ecdc36..8208d67 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -48,6 +48,14 @@ static struct platform_device rtc_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -66,6 +74,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index 1443e92..7443b26 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -31,8 +31,10 @@
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/spi/mmc_spi.h>
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
@@ -130,7 +132,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -141,9 +143,9 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
-		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
-		.chip_select = 5,
+		.chip_select = 1,
 		.controller_data = &mmc_spi_chip_info,
 		.mode = SPI_MODE_3,
 	},
@@ -195,6 +197,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.start = 0x20200300,
@@ -211,6 +221,43 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
+};
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+
+static struct resource smsc911x_resources[] = {
+	{
+		.name = "smsc911x-memory",
+		.start = 0x20308000,
+		.end = 0x20308000 + 0xFF,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PF8,
+		.end = IRQ_PF8,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.flags = SMSC911X_USE_16BIT,
+	.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+	.name = "smsc911x",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(smsc911x_resources),
+	.resource = smsc911x_resources,
+	.dev = {
+		.platform_data = &smsc911x_config,
+	},
 };
 #endif
 
@@ -324,6 +371,68 @@ static struct platform_device isp1362_hcd_device = {
 };
 #endif
 
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+	{
+		.start = 0x20300000,
+		.end = 0x20300000 + 0x100,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PF6,
+		.end = IRQ_PF6,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+static struct platform_device net2272_bfin_device = {
+	.name = "net2272",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(net2272_bfin_resources),
+	.resource = net2272_bfin_resources,
+};
+#endif
+
+
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition para_partitions[] = {
+	{
+		.name       = "bootloader(nor)",
+		.size       = 0x40000,
+		.offset     = 0,
+	}, {
+		.name       = "linux+rootfs(nor)",
+		.size       = MTDPART_SIZ_FULL,
+		.offset     = MTDPART_OFS_APPEND,
+	},
+};
+
+static struct physmap_flash_data para_flash_data = {
+	.width      = 2,
+	.parts      = para_partitions,
+	.nr_parts   = ARRAY_SIZE(para_partitions),
+};
+
+static struct resource para_flash_resource = {
+	.start = 0x20000000,
+	.end   = 0x201fffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device para_flash_device = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &para_flash_data,
+	},
+	.num_resources = 1,
+	.resource      = &para_flash_resource,
+};
+#endif
+
+
+
 static const unsigned int cclk_vlev_datasheet[] =
 {
 	VRPAIR(VLEV_085, 250000000),
@@ -382,10 +491,22 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
 	&smc91x_device,
 #endif
 
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+	&smsc911x_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+	&net2272_bfin_device,
+#endif
+
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 	&bfin_spi0_device,
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+	&para_flash_device,
+#endif
+
 	&bfin_gpios_device,
 };
 
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 4e3e511..fd518e3 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -67,6 +67,14 @@ static struct platform_device bfin_fb_adv7393_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -84,6 +92,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -263,7 +274,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 3d743cc..729fd7c 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -35,6 +35,7 @@
 #include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
+#include <linux/spi/mmc_spi.h>
 #if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
 #include <linux/usb/isp1362.h>
 #endif
@@ -62,6 +63,14 @@ static struct platform_device rtc_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -80,6 +89,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -207,19 +219,38 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x4, /* send zero */
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+static struct bfin5xx_spi_chip spidev_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
 };
 #endif
 
-#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
-static struct bfin5xx_spi_chip spidev_chip_info = {
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+#define MMC_SPI_CARD_DETECT_INT IRQ_PF5
+static int bfin_mmc_spi_init(struct device *dev,
+	irqreturn_t (*detect_int)(int, void *), void *data)
+{
+	return request_irq(MMC_SPI_CARD_DETECT_INT, detect_int,
+		IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+		"mmc-spi-detect", data);
+}
+
+static void bfin_mmc_spi_exit(struct device *dev, void *data)
+{
+	free_irq(MMC_SPI_CARD_DETECT_INT, data);
+}
+
+static struct mmc_spi_platform_data bfin_mmc_spi_pdata = {
+	.init = bfin_mmc_spi_init,
+	.exit = bfin_mmc_spi_exit,
+	.detect_delay = 100, /* msecs */
+};
+
+static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 8,
+	.pio_interrupt = 0,
 };
 #endif
 
@@ -250,33 +281,14 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
-		.max_speed_hz = 31250000,     /* max spi clock (SCK) speed in HZ */
+		.modalias = "ad1836",
+		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
 		.controller_data = &ad1836_spi_chip_info,
 	},
 #endif
 
-#if defined(CONFIG_PBX)
-	{
-		.modalias = "fxs-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J11_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-	{
-		.modalias = "fxo-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J19_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
-
 #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
 	{
 		.modalias = "spidev",
@@ -286,6 +298,17 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 		.controller_data = &spidev_chip_info,
 	},
 #endif
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+	{
+		.modalias = "mmc_spi",
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 4,
+		.platform_data = &bfin_mmc_spi_pdata,
+		.controller_data = &mmc_spi_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
 };
 
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
@@ -458,7 +481,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
 	},
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
 		.irq = 39,
diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c
index 0a6eb8f..7a443c3 100644
--- a/arch/blackfin/mach-bf533/dma.c
+++ b/arch/blackfin/mach-bf533/dma.c
@@ -76,12 +76,12 @@ int channel2irq(unsigned int channel)
 		ret_irq = IRQ_SPI;
 		break;
 
-	case CH_UART_RX:
-		ret_irq = IRQ_UART_RX;
+	case CH_UART0_RX:
+		ret_irq = IRQ_UART0_RX;
 		break;
 
-	case CH_UART_TX:
-		ret_irq = IRQ_UART_TX;
+	case CH_UART0_TX:
+		ret_irq = IRQ_UART0_TX;
 		break;
 
 	case CH_MEM_STREAM0_SRC:
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 4062e24..6965b40 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -131,11 +131,11 @@ struct bfin_serial_res {
 struct bfin_serial_res bfin_serial_resource[] = {
 	{
 	0xFFC00400,
-	IRQ_UART_RX,
-	IRQ_UART_ERROR,
+	IRQ_UART0_RX,
+	IRQ_UART0_ERROR,
 #ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART_TX,
-	CH_UART_RX,
+	CH_UART0_TX,
+	CH_UART0_RX,
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
 	CONFIG_UART0_CTS_PIN,
diff --git a/arch/blackfin/mach-bf533/include/mach/blackfin.h b/arch/blackfin/mach-bf533/include/mach/blackfin.h
index 39aa175..499e897 100644
--- a/arch/blackfin/mach-bf533/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf533/include/mach/blackfin.h
@@ -43,13 +43,6 @@
 
 #define BFIN_UART_NR_PORTS      1
 
-#define CH_UART_RX CH_UART0_RX
-#define CH_UART_TX CH_UART0_TX
-
-#define IRQ_UART_ERROR IRQ_UART0_ERROR
-#define IRQ_UART_RX    IRQ_UART0_RX
-#define IRQ_UART_TX    IRQ_UART0_TX
-
 #define OFFSET_THR              0x00	/* Transmit Holding register            */
 #define OFFSET_RBR              0x00	/* Receive Buffer register              */
 #define OFFSET_DLL              0x00	/* Divisor Latch (Low-Byte)             */
diff --git a/arch/blackfin/mach-bf537/boards/Kconfig b/arch/blackfin/mach-bf537/boards/Kconfig
index 77c59da..44132fd 100644
--- a/arch/blackfin/mach-bf537/boards/Kconfig
+++ b/arch/blackfin/mach-bf537/boards/Kconfig
@@ -9,11 +9,17 @@ config BFIN537_STAMP
 	help
 	  BF537-STAMP board support.
 
-config BFIN537_BLUETECHNIX_CM
-	bool "Bluetechnix CM-BF537"
+config BFIN537_BLUETECHNIX_CM_E
+	bool "Bluetechnix CM-BF537E"
 	depends on (BF537)
 	help
-	  CM-BF537 support for EVAL- and DEV-Board.
+	  CM-BF537E support for EVAL- and DEV-Board.
+
+config BFIN537_BLUETECHNIX_CM_U
+	bool "Bluetechnix CM-BF537U"
+	depends on (BF537)
+	help
+	  CM-BF537U support for EVAL- and DEV-Board.
 
 config BFIN537_BLUETECHNIX_TCM
 	bool "Bluetechnix TCM-BF537"
diff --git a/arch/blackfin/mach-bf537/boards/Makefile b/arch/blackfin/mach-bf537/boards/Makefile
index 68b98a7..7e6aa4e 100644
--- a/arch/blackfin/mach-bf537/boards/Makefile
+++ b/arch/blackfin/mach-bf537/boards/Makefile
@@ -3,7 +3,8 @@
 #
 
 obj-$(CONFIG_BFIN537_STAMP)            += stamp.o
-obj-$(CONFIG_BFIN537_BLUETECHNIX_CM)   += cm_bf537.o
+obj-$(CONFIG_BFIN537_BLUETECHNIX_CM_E) += cm_bf537e.o
+obj-$(CONFIG_BFIN537_BLUETECHNIX_CM_U) += cm_bf537u.o
 obj-$(CONFIG_BFIN537_BLUETECHNIX_TCM)  += tcm_bf537.o
 obj-$(CONFIG_PNAV10)                   += pnav10.o
 obj-$(CONFIG_CAMSIG_MINOTAUR)          += minotaur.o
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
deleted file mode 100644
index 2a87d1c..0000000
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * File:         arch/blackfin/mach-bf537/boards/cm_bf537.c
- * Based on:     arch/blackfin/mach-bf533/boards/ezkit.c
- * Author:       Aidan Williams <aidan@nicta.com.au>
- *
- * Created:      2005
- * Description:  Board description file
- *
- * Modified:
- *               Copyright 2005 National ICT Australia (NICTA)
- *               Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.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, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/device.h>
-#include <linux/etherdevice.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/flash.h>
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-#include <linux/usb/isp1362.h>
-#endif
-#include <linux/ata_platform.h>
-#include <linux/irq.h>
-#include <asm/dma.h>
-#include <asm/bfin5xx_spi.h>
-#include <asm/portmux.h>
-#include <asm/dpmc.h>
-
-/*
- * Name the Board for the /proc/cpuinfo
- */
-const char bfin_board_name[] = "Bluetechnix CM BF537";
-
-#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-/* all SPI peripherals info goes here */
-
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
-static struct mtd_partition bfin_spi_flash_partitions[] = {
-	{
-		.name = "bootloader(spi)",
-		.size = 0x00020000,
-		.offset = 0,
-		.mask_flags = MTD_CAP_ROM
-	}, {
-		.name = "linux kernel(spi)",
-		.size = 0xe0000,
-		.offset = 0x20000
-	}, {
-		.name = "file system(spi)",
-		.size = 0x700000,
-		.offset = 0x00100000,
-	}
-};
-
-static struct flash_platform_data bfin_spi_flash_data = {
-	.name = "m25p80",
-	.parts = bfin_spi_flash_partitions,
-	.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
-	.type = "m25p64",
-};
-
-/* SPI flash chip (m25p64) */
-static struct bfin5xx_spi_chip spi_flash_chip_info = {
-	.enable_dma = 0,         /* use dma transfer with this chip*/
-	.bits_per_word = 8,
-};
-#endif
-
-#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
-/* SPI ADC chip */
-static struct bfin5xx_spi_chip spi_adc_chip_info = {
-	.enable_dma = 1,         /* use dma transfer with this chip*/
-	.bits_per_word = 16,
-};
-#endif
-
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
-static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
-static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 8,
-};
-#endif
-
-static struct spi_board_info bfin_spi_board_info[] __initdata = {
-#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
-	{
-		/* the modalias must be the same as spi device driver name */
-		.modalias = "m25p80", /* Name of spi_driver for this device */
-		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0, /* Framework bus number */
-		.chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
-		.platform_data = &bfin_spi_flash_data,
-		.controller_data = &spi_flash_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
-
-#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
-	{
-		.modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
-		.max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0, /* Framework bus number */
-		.chip_select = 1, /* Framework chip select. */
-		.platform_data = NULL, /* No spi_driver specific config */
-		.controller_data = &spi_adc_chip_info,
-	},
-#endif
-
-#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
-	{
-		.modalias = "ad1836-spi",
-		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
-		.controller_data = &ad1836_spi_chip_info,
-	},
-#endif
-
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-	{
-		.modalias = "ad9960-spi",
-		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &ad9960_spi_chip_info,
-	},
-#endif
-
-#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
-	{
-		.modalias = "mmc_spi",
-		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &mmc_spi_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
-};
-
-/* SPI (0) */
-static struct resource bfin_spi0_resource[] = {
-	[0] = {
-		.start = SPI0_REGBASE,
-		.end   = SPI0_REGBASE + 0xFF,
-		.flags = IORESOURCE_MEM,
-		},
-	[1] = {
-		.start = CH_SPI,
-		.end   = CH_SPI,
-		.flags = IORESOURCE_DMA,
-	},
-	[2] = {
-		.start = IRQ_SPI,
-		.end   = IRQ_SPI,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-/* SPI controller data */
-static struct bfin5xx_spi_master bfin_spi0_info = {
-	.num_chipselect = 8,
-	.enable_dma = 1,  /* master has the ability to do dma transfer */
-	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
-};
-
-static struct platform_device bfin_spi0_device = {
-	.name = "bfin-spi",
-	.id = 0, /* Bus number */
-	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
-	.resource = bfin_spi0_resource,
-	.dev = {
-		.platform_data = &bfin_spi0_info, /* Passed to driver */
-	},
-};
-#endif  /* spi master and devices */
-
-#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
-static struct platform_device rtc_device = {
-	.name = "rtc-bfin",
-	.id   = -1,
-};
-#endif
-
-#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
-static struct platform_device hitachi_fb_device = {
-	.name = "hitachi-tx09",
-};
-#endif
-
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
-static struct resource smc91x_resources[] = {
-	{
-		.start = 0x20200300,
-		.end = 0x20200300 + 16,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = IRQ_PF14,
-		.end = IRQ_PF14,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-		},
-};
-
-static struct platform_device smc91x_device = {
-	.name = "smc91x",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(smc91x_resources),
-	.resource = smc91x_resources,
-};
-#endif
-
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-static struct resource isp1362_hcd_resources[] = {
-	{
-		.start = 0x20308000,
-		.end = 0x20308000,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0x20308004,
-		.end = 0x20308004,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = IRQ_PG15,
-		.end = IRQ_PG15,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-static struct isp1362_platform_data isp1362_priv = {
-	.sel15Kres = 1,
-	.clknotstop = 0,
-	.oc_enable = 0,
-	.int_act_high = 0,
-	.int_edge_triggered = 0,
-	.remote_wakeup_connected = 0,
-	.no_power_switching = 1,
-	.power_switching_mode = 0,
-};
-
-static struct platform_device isp1362_hcd_device = {
-	.name = "isp1362-hcd",
-	.id = 0,
-	.dev = {
-		.platform_data = &isp1362_priv,
-	},
-	.num_resources = ARRAY_SIZE(isp1362_hcd_resources),
-	.resource = isp1362_hcd_resources,
-};
-#endif
-
-#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
-static struct resource net2272_bfin_resources[] = {
-	{
-		.start = 0x20200000,
-		.end = 0x20200000 + 0x100,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = IRQ_PH14,
-		.end = IRQ_PH14,
-		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
-	},
-};
-
-static struct platform_device net2272_bfin_device = {
-	.name = "net2272",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(net2272_bfin_resources),
-	.resource = net2272_bfin_resources,
-};
-#endif
-
-static struct resource bfin_gpios_resources = {
-	.start = 0,
-	.end   = MAX_BLACKFIN_GPIOS - 1,
-	.flags = IORESOURCE_IRQ,
-};
-
-static struct platform_device bfin_gpios_device = {
-	.name = "simple-gpio",
-	.id = -1,
-	.num_resources = 1,
-	.resource = &bfin_gpios_resources,
-};
-
-#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
-static struct mtd_partition cm_partitions[] = {
-	{
-		.name   = "bootloader(nor)",
-		.size   = 0x40000,
-		.offset = 0,
-	}, {
-		.name   = "linux kernel(nor)",
-		.size   = 0xE0000,
-		.offset = MTDPART_OFS_APPEND,
-	}, {
-		.name   = "file system(nor)",
-		.size   = MTDPART_SIZ_FULL,
-		.offset = MTDPART_OFS_APPEND,
-	}
-};
-
-static struct physmap_flash_data cm_flash_data = {
-	.width    = 2,
-	.parts    = cm_partitions,
-	.nr_parts = ARRAY_SIZE(cm_partitions),
-};
-
-static unsigned cm_flash_gpios[] = { GPIO_PF4 };
-
-static struct resource cm_flash_resource[] = {
-	{
-		.name  = "cfi_probe",
-		.start = 0x20000000,
-		.end   = 0x201fffff,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = (unsigned long)cm_flash_gpios,
-		.end   = ARRAY_SIZE(cm_flash_gpios),
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static struct platform_device cm_flash_device = {
-	.name          = "gpio-addr-flash",
-	.id            = 0,
-	.dev = {
-		.platform_data = &cm_flash_data,
-	},
-	.num_resources = ARRAY_SIZE(cm_flash_resource),
-	.resource      = cm_flash_resource,
-};
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-static struct resource bfin_uart_resources[] = {
-	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device bfin_uart_device = {
-	.name = "bfin-uart",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_uart_resources),
-	.resource = bfin_uart_resources,
-};
-#endif
-
-#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
-#ifdef CONFIG_BFIN_SIR0
-static struct resource bfin_sir0_resources[] = {
-	{
-		.start = 0xFFC00400,
-		.end = 0xFFC004FF,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_UART0_RX,
-		.end = IRQ_UART0_RX+1,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = CH_UART0_RX,
-		.end = CH_UART0_RX+1,
-		.flags = IORESOURCE_DMA,
-	},
-};
-static struct platform_device bfin_sir0_device = {
-	.name = "bfin_sir",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(bfin_sir0_resources),
-	.resource = bfin_sir0_resources,
-};
-#endif
-#ifdef CONFIG_BFIN_SIR1
-static struct resource bfin_sir1_resources[] = {
-	{
-		.start = 0xFFC02000,
-		.end = 0xFFC020FF,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_UART1_RX,
-		.end = IRQ_UART1_RX+1,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = CH_UART1_RX,
-		.end = CH_UART1_RX+1,
-		.flags = IORESOURCE_DMA,
-	},
-};
-static struct platform_device bfin_sir1_device = {
-	.name = "bfin_sir",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(bfin_sir1_resources),
-	.resource = bfin_sir1_resources,
-};
-#endif
-#endif
-
-#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
-static struct resource bfin_twi0_resource[] = {
-	[0] = {
-		.start = TWI0_REGBASE,
-		.end   = TWI0_REGBASE,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = IRQ_TWI,
-		.end   = IRQ_TWI,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device i2c_bfin_twi_device = {
-	.name = "i2c-bfin-twi",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(bfin_twi0_resource),
-	.resource = bfin_twi0_resource,
-};
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
-static struct platform_device bfin_sport0_uart_device = {
-	.name = "bfin-sport-uart",
-	.id = 0,
-};
-
-static struct platform_device bfin_sport1_uart_device = {
-	.name = "bfin-sport-uart",
-	.id = 1,
-};
-#endif
-
-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
-static struct platform_device bfin_mii_bus = {
-	.name = "bfin_mii_bus",
-};
-
-static struct platform_device bfin_mac_device = {
-	.name = "bfin_mac",
-	.dev.platform_data = &bfin_mii_bus,
-};
-#endif
-
-#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-#define PATA_INT	IRQ_PF14
-
-static struct pata_platform_info bfin_pata_platform_data = {
-	.ioport_shift = 2,
-	.irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
-};
-
-static struct resource bfin_pata_resources[] = {
-	{
-		.start = 0x2030C000,
-		.end = 0x2030C01F,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = 0x2030D018,
-		.end = 0x2030D01B,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = PATA_INT,
-		.end = PATA_INT,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device bfin_pata_device = {
-	.name = "pata_platform",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(bfin_pata_resources),
-	.resource = bfin_pata_resources,
-	.dev = {
-		.platform_data = &bfin_pata_platform_data,
-	}
-};
-#endif
-
-static const unsigned int cclk_vlev_datasheet[] =
-{
-	VRPAIR(VLEV_085, 250000000),
-	VRPAIR(VLEV_090, 376000000),
-	VRPAIR(VLEV_095, 426000000),
-	VRPAIR(VLEV_100, 426000000),
-	VRPAIR(VLEV_105, 476000000),
-	VRPAIR(VLEV_110, 476000000),
-	VRPAIR(VLEV_115, 476000000),
-	VRPAIR(VLEV_120, 500000000),
-	VRPAIR(VLEV_125, 533000000),
-	VRPAIR(VLEV_130, 600000000),
-};
-
-static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
-	.tuple_tab = cclk_vlev_datasheet,
-	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
-	.vr_settling_time = 25 /* us */,
-};
-
-static struct platform_device bfin_dpmc = {
-	.name = "bfin dpmc",
-	.dev = {
-		.platform_data = &bfin_dmpc_vreg_data,
-	},
-};
-
-static struct platform_device *cm_bf537_devices[] __initdata = {
-
-	&bfin_dpmc,
-
-#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
-	&hitachi_fb_device,
-#endif
-
-#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
-	&rtc_device,
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
-	&bfin_uart_device,
-#endif
-
-#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
-#ifdef CONFIG_BFIN_SIR0
-	&bfin_sir0_device,
-#endif
-#ifdef CONFIG_BFIN_SIR1
-	&bfin_sir1_device,
-#endif
-#endif
-
-#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
-	&i2c_bfin_twi_device,
-#endif
-
-#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
-	&bfin_sport0_uart_device,
-	&bfin_sport1_uart_device,
-#endif
-
-#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
-	&isp1362_hcd_device,
-#endif
-
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
-	&smc91x_device,
-#endif
-
-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
-	&bfin_mii_bus,
-	&bfin_mac_device,
-#endif
-
-#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
-	&net2272_bfin_device,
-#endif
-
-#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-	&bfin_spi0_device,
-#endif
-
-#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-	&bfin_pata_device,
-#endif
-
-#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
-	&cm_flash_device,
-#endif
-
-	&bfin_gpios_device,
-};
-
-static int __init cm_bf537_init(void)
-{
-	printk(KERN_INFO "%s(): registering device resources\n", __func__);
-	platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices));
-#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
-	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
-#endif
-
-#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
-	irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
-#endif
-	return 0;
-}
-
-arch_initcall(cm_bf537_init);
-
-void bfin_get_ether_addr(char *addr)
-{
-	random_ether_addr(addr);
-	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
-}
-EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
new file mode 100644
index 0000000..87acb7d
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -0,0 +1,727 @@
+/*
+ * File:         arch/blackfin/mach-bf537/boards/cm_bf537.c
+ * Based on:     arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author:       Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:      2005
+ * Description:  Board description file
+ *
+ * Modified:
+ *               Copyright 2005 National ICT Australia (NICTA)
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb/isp1362.h>
+#endif
+#include <linux/ata_platform.h>
+#include <linux/irq.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Bluetechnix CM BF537E";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+	{
+		.name = "bootloader(spi)",
+		.size = 0x00020000,
+		.offset = 0,
+		.mask_flags = MTD_CAP_ROM
+	}, {
+		.name = "linux kernel(spi)",
+		.size = 0xe0000,
+		.offset = 0x20000
+	}, {
+		.name = "file system(spi)",
+		.size = 0x700000,
+		.offset = 0x00100000,
+	}
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+	.name = "m25p80",
+	.parts = bfin_spi_flash_partitions,
+	.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+	.type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+	.enable_dma = 0,         /* use dma transfer with this chip*/
+	.bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+	.enable_dma = 1,         /* use dma transfer with this chip*/
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+	{
+		/* the modalias must be the same as spi device driver name */
+		.modalias = "m25p80", /* Name of spi_driver for this device */
+		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+		.platform_data = &bfin_spi_flash_data,
+		.controller_data = &spi_flash_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+	{
+		.modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+		.max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 1, /* Framework chip select. */
+		.platform_data = NULL, /* No spi_driver specific config */
+		.controller_data = &spi_adc_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+	{
+		.modalias = "ad1836",
+		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+		.controller_data = &ad1836_spi_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+	{
+		.modalias = "mmc_spi",
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 1,
+		.controller_data = &mmc_spi_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+	[0] = {
+		.start = SPI0_REGBASE,
+		.end   = SPI0_REGBASE + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = CH_SPI,
+		.end   = CH_SPI,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = IRQ_SPI,
+		.end   = IRQ_SPI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+	.num_chipselect = 8,
+	.enable_dma = 1,  /* master has the ability to do dma transfer */
+	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct platform_device bfin_spi0_device = {
+	.name = "bfin-spi",
+	.id = 0, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
+	.resource = bfin_spi0_resource,
+	.dev = {
+		.platform_data = &bfin_spi0_info, /* Passed to driver */
+	},
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+	.name = "rtc-bfin",
+	.id   = -1,
+};
+#endif
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+static struct platform_device hitachi_fb_device = {
+	.name = "hitachi-tx09",
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+	{
+		.start = 0x20200300,
+		.end = 0x20200300 + 16,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PF14,
+		.end = IRQ_PF14,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+		},
+};
+
+static struct platform_device smc91x_device = {
+	.name = "smc91x",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(smc91x_resources),
+	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+	{
+		.start = 0x20308000,
+		.end = 0x20308000,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 0x20308004,
+		.end = 0x20308004,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PG15,
+		.end = IRQ_PG15,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+	.sel15Kres = 1,
+	.clknotstop = 0,
+	.oc_enable = 0,
+	.int_act_high = 0,
+	.int_edge_triggered = 0,
+	.remote_wakeup_connected = 0,
+	.no_power_switching = 1,
+	.power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+	.name = "isp1362-hcd",
+	.id = 0,
+	.dev = {
+		.platform_data = &isp1362_priv,
+	},
+	.num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+	.resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+	{
+		.start = 0x20300000,
+		.end = 0x20300000 + 0x100,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PG13,
+		.end = IRQ_PG13,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+static struct platform_device net2272_bfin_device = {
+	.name = "net2272",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(net2272_bfin_resources),
+	.resource = net2272_bfin_resources,
+};
+#endif
+
+static struct resource bfin_gpios_resources = {
+	.start = 0,
+	.end   = MAX_BLACKFIN_GPIOS - 1,
+	.flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+	.name = "simple-gpio",
+	.id = -1,
+	.num_resources = 1,
+	.resource = &bfin_gpios_resources,
+};
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+static struct mtd_partition cm_partitions[] = {
+	{
+		.name   = "bootloader(nor)",
+		.size   = 0x40000,
+		.offset = 0,
+	}, {
+		.name   = "linux kernel(nor)",
+		.size   = 0x100000,
+		.offset = MTDPART_OFS_APPEND,
+	}, {
+		.name   = "file system(nor)",
+		.size   = MTDPART_SIZ_FULL,
+		.offset = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct physmap_flash_data cm_flash_data = {
+	.width    = 2,
+	.parts    = cm_partitions,
+	.nr_parts = ARRAY_SIZE(cm_partitions),
+};
+
+static unsigned cm_flash_gpios[] = { GPIO_PF4 };
+
+static struct resource cm_flash_resource[] = {
+	{
+		.name  = "cfi_probe",
+		.start = 0x20000000,
+		.end   = 0x201fffff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = (unsigned long)cm_flash_gpios,
+		.end   = ARRAY_SIZE(cm_flash_gpios),
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device cm_flash_device = {
+	.name          = "gpio-addr-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &cm_flash_data,
+	},
+	.num_resources = ARRAY_SIZE(cm_flash_resource),
+	.resource      = cm_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+static struct resource bfin_uart0_resources[] = {
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART0_ERROR,
+		.end = IRQ_UART0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_TX,
+		.end = CH_UART0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+	{
+		/*
+		 * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+		 */
+		.start = -1,
+		.end = -1,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		/*
+		 * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+		 */
+		.start = -1,
+		.end = -1,
+		.flags = IORESOURCE_IO,
+	},
+#endif
+};
+
+static struct platform_device bfin_uart0_device = {
+	.name = "bfin-uart",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_uart0_resources),
+	.resource = bfin_uart0_resources,
+};
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+static struct resource bfin_uart1_resources[] = {
+	{
+		.start = 0xFFC02000,
+		.end = 0xFFC020FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_UART1_ERROR,
+		.end = IRQ_UART1_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_TX,
+		.end = CH_UART1_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX,
+		.flags = IORESOURCE_DMA,
+	},
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+	{
+		/*
+		 * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+		 */
+		.start = -1,
+		.end = -1,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		/*
+		 * Refer to arch/blackfin/mach-xxx/include/mach/gpio.h for the GPIO map.
+		 */
+		.start = -1,
+		.end = -1,
+		.flags = IORESOURCE_IO,
+	},
+#endif
+};
+
+static struct platform_device bfin_uart1_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart1_resources),
+	.resource = bfin_uart1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX+1,
+		.flags = IORESOURCE_DMA,
+	},
+};
+static struct platform_device bfin_sir0_device = {
+	.name = "bfin_sir",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sir0_resources),
+	.resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+	{
+		.start = 0xFFC02000,
+		.end = 0xFFC020FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX+1,
+		.flags = IORESOURCE_DMA,
+	},
+};
+static struct platform_device bfin_sir1_device = {
+	.name = "bfin_sir",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sir1_resources),
+	.resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+	[0] = {
+		.start = TWI0_REGBASE,
+		.end   = TWI0_REGBASE,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_TWI,
+		.end   = IRQ_TWI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+	.name = "i2c-bfin-twi",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_twi0_resource),
+	.resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT	IRQ_PF14
+
+static struct pata_platform_info bfin_pata_platform_data = {
+	.ioport_shift = 2,
+	.irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+	{
+		.start = 0x2030C000,
+		.end = 0x2030C01F,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0x2030D018,
+		.end = 0x2030D01B,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = PATA_INT,
+		.end = PATA_INT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_pata_device = {
+	.name = "pata_platform",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(bfin_pata_resources),
+	.resource = bfin_pata_resources,
+	.dev = {
+		.platform_data = &bfin_pata_platform_data,
+	}
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 376000000),
+	VRPAIR(VLEV_095, 426000000),
+	VRPAIR(VLEV_100, 426000000),
+	VRPAIR(VLEV_105, 476000000),
+	VRPAIR(VLEV_110, 476000000),
+	VRPAIR(VLEV_115, 476000000),
+	VRPAIR(VLEV_120, 500000000),
+	VRPAIR(VLEV_125, 533000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
+static struct platform_device *cm_bf537e_devices[] __initdata = {
+
+	&bfin_dpmc,
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+	&hitachi_fb_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+	&rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+#ifdef CONFIG_SERIAL_BFIN_UART0
+	&bfin_uart0_device,
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+	&bfin_uart1_device,
+#endif
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+	&bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+	&bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+	&i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+	&bfin_sport0_uart_device,
+	&bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+	&isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+	&smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
+	&bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+	&net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	&bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+	&bfin_pata_device,
+#endif
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+	&cm_flash_device,
+#endif
+
+	&bfin_gpios_device,
+};
+
+static int __init cm_bf537e_init(void)
+{
+	printk(KERN_INFO "%s(): registering device resources\n", __func__);
+	platform_add_devices(cm_bf537e_devices, ARRAY_SIZE(cm_bf537e_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+	irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+	return 0;
+}
+
+arch_initcall(cm_bf537e_init);
+
+void bfin_get_ether_addr(char *addr)
+{
+	random_ether_addr(addr);
+	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
new file mode 100644
index 0000000..8219dc3
--- /dev/null
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -0,0 +1,633 @@
+/*
+ * File:         arch/blackfin/mach-bf537/boards/cm_bf537u.c
+ * Based on:     arch/blackfin/mach-bf533/boards/ezkit.c
+ * Author:       Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:      2005
+ * Description:  Board description file
+ *
+ * Modified:
+ *               Copyright 2005 National ICT Australia (NICTA)
+ *               Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:         Enter bugs at http://blackfin.uclinux.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, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb/isp1362.h>
+#endif
+#include <linux/ata_platform.h>
+#include <linux/irq.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/portmux.h>
+#include <asm/dpmc.h>
+#include <linux/spi/mmc_spi.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "Bluetechnix CM BF537U";
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+	{
+		.name = "bootloader(spi)",
+		.size = 0x00020000,
+		.offset = 0,
+		.mask_flags = MTD_CAP_ROM
+	}, {
+		.name = "linux kernel(spi)",
+		.size = 0xe0000,
+		.offset = 0x20000
+	}, {
+		.name = "file system(spi)",
+		.size = 0x700000,
+		.offset = 0x00100000,
+	}
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+	.name = "m25p80",
+	.parts = bfin_spi_flash_partitions,
+	.nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+	.type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+	.enable_dma = 0,         /* use dma transfer with this chip*/
+	.bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+	.enable_dma = 1,         /* use dma transfer with this chip*/
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+	{
+		/* the modalias must be the same as spi device driver name */
+		.modalias = "m25p80", /* Name of spi_driver for this device */
+		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+		.platform_data = &bfin_spi_flash_data,
+		.controller_data = &spi_flash_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+
+#if defined(CONFIG_BFIN_SPI_ADC) || defined(CONFIG_BFIN_SPI_ADC_MODULE)
+	{
+		.modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+		.max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0, /* Framework bus number */
+		.chip_select = 1, /* Framework chip select. */
+		.platform_data = NULL, /* No spi_driver specific config */
+		.controller_data = &spi_adc_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+	{
+		.modalias = "ad1836",
+		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+		.controller_data = &ad1836_spi_chip_info,
+	},
+#endif
+
+#if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
+	{
+		.modalias = "mmc_spi",
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
+		.bus_num = 0,
+		.chip_select = 1,
+		.controller_data = &mmc_spi_chip_info,
+		.mode = SPI_MODE_3,
+	},
+#endif
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+	[0] = {
+		.start = SPI0_REGBASE,
+		.end   = SPI0_REGBASE + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = CH_SPI,
+		.end   = CH_SPI,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = IRQ_SPI,
+		.end   = IRQ_SPI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+	.num_chipselect = 8,
+	.enable_dma = 1,  /* master has the ability to do dma transfer */
+	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
+};
+
+static struct platform_device bfin_spi0_device = {
+	.name = "bfin-spi",
+	.id = 0, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_spi0_resource),
+	.resource = bfin_spi0_resource,
+	.dev = {
+		.platform_data = &bfin_spi0_info, /* Passed to driver */
+	},
+};
+#endif  /* spi master and devices */
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+	.name = "rtc-bfin",
+	.id   = -1,
+};
+#endif
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+static struct platform_device hitachi_fb_device = {
+	.name = "hitachi-tx09",
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+	{
+		.start = 0x20200300,
+		.end = 0x20200300 + 16,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PF14,
+		.end = IRQ_PF14,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+		},
+};
+
+static struct platform_device smc91x_device = {
+	.name = "smc91x",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(smc91x_resources),
+	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+	{
+		.start = 0x20308000,
+		.end = 0x20308000,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 0x20308004,
+		.end = 0x20308004,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PG15,
+		.end = IRQ_PG15,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+	.sel15Kres = 1,
+	.clknotstop = 0,
+	.oc_enable = 0,
+	.int_act_high = 0,
+	.int_edge_triggered = 0,
+	.remote_wakeup_connected = 0,
+	.no_power_switching = 1,
+	.power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+	.name = "isp1362-hcd",
+	.id = 0,
+	.dev = {
+		.platform_data = &isp1362_priv,
+	},
+	.num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+	.resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+	{
+		.start = 0x20200000,
+		.end = 0x20200000 + 0x100,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PH14,
+		.end = IRQ_PH14,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+static struct platform_device net2272_bfin_device = {
+	.name = "net2272",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(net2272_bfin_resources),
+	.resource = net2272_bfin_resources,
+};
+#endif
+
+static struct resource bfin_gpios_resources = {
+	.start = 0,
+	.end   = MAX_BLACKFIN_GPIOS - 1,
+	.flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device bfin_gpios_device = {
+	.name = "simple-gpio",
+	.id = -1,
+	.num_resources = 1,
+	.resource = &bfin_gpios_resources,
+};
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+static struct mtd_partition cm_partitions[] = {
+	{
+		.name   = "bootloader(nor)",
+		.size   = 0x40000,
+		.offset = 0,
+	}, {
+		.name   = "linux kernel(nor)",
+		.size   = 0x100000,
+		.offset = MTDPART_OFS_APPEND,
+	}, {
+		.name   = "file system(nor)",
+		.size   = MTDPART_SIZ_FULL,
+		.offset = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct physmap_flash_data cm_flash_data = {
+	.width    = 2,
+	.parts    = cm_partitions,
+	.nr_parts = ARRAY_SIZE(cm_partitions),
+};
+
+static unsigned cm_flash_gpios[] = { GPIO_PH0 };
+
+static struct resource cm_flash_resource[] = {
+	{
+		.name  = "cfi_probe",
+		.start = 0x20000000,
+		.end   = 0x201fffff,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = (unsigned long)cm_flash_gpios,
+		.end   = ARRAY_SIZE(cm_flash_gpios),
+		.flags = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device cm_flash_device = {
+	.name          = "gpio-addr-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &cm_flash_data,
+	},
+	.num_resources = ARRAY_SIZE(cm_flash_resource),
+	.resource      = cm_flash_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = 0xFFC02000,
+		.end = 0xFFC020FF,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device bfin_uart_device = {
+	.name = "bfin-uart",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_uart_resources),
+	.resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+static struct resource bfin_sir0_resources[] = {
+	{
+		.start = 0xFFC00400,
+		.end = 0xFFC004FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART0_RX,
+		.end = IRQ_UART0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART0_RX,
+		.end = CH_UART0_RX+1,
+		.flags = IORESOURCE_DMA,
+	},
+};
+static struct platform_device bfin_sir0_device = {
+	.name = "bfin_sir",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sir0_resources),
+	.resource = bfin_sir0_resources,
+};
+#endif
+#ifdef CONFIG_BFIN_SIR1
+static struct resource bfin_sir1_resources[] = {
+	{
+		.start = 0xFFC02000,
+		.end = 0xFFC020FF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_UART1_RX,
+		.end = IRQ_UART1_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_UART1_RX,
+		.end = CH_UART1_RX+1,
+		.flags = IORESOURCE_DMA,
+	},
+};
+static struct platform_device bfin_sir1_device = {
+	.name = "bfin_sir",
+	.id = 1,
+	.num_resources = ARRAY_SIZE(bfin_sir1_resources),
+	.resource = bfin_sir1_resources,
+};
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+	[0] = {
+		.start = TWI0_REGBASE,
+		.end   = TWI0_REGBASE,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_TWI,
+		.end   = IRQ_TWI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+	.name = "i2c-bfin-twi",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_twi0_resource),
+	.resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+	.name = "bfin-sport-uart",
+	.id = 1,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mii_bus = {
+	.name = "bfin_mii_bus",
+};
+
+static struct platform_device bfin_mac_device = {
+	.name = "bfin_mac",
+	.dev.platform_data = &bfin_mii_bus,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT	IRQ_PF14
+
+static struct pata_platform_info bfin_pata_platform_data = {
+	.ioport_shift = 2,
+	.irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+	{
+		.start = 0x2030C000,
+		.end = 0x2030C01F,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = 0x2030D018,
+		.end = 0x2030D01B,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = PATA_INT,
+		.end = PATA_INT,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bfin_pata_device = {
+	.name = "pata_platform",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(bfin_pata_resources),
+	.resource = bfin_pata_resources,
+	.dev = {
+		.platform_data = &bfin_pata_platform_data,
+	}
+};
+#endif
+
+static const unsigned int cclk_vlev_datasheet[] =
+{
+	VRPAIR(VLEV_085, 250000000),
+	VRPAIR(VLEV_090, 376000000),
+	VRPAIR(VLEV_095, 426000000),
+	VRPAIR(VLEV_100, 426000000),
+	VRPAIR(VLEV_105, 476000000),
+	VRPAIR(VLEV_110, 476000000),
+	VRPAIR(VLEV_115, 476000000),
+	VRPAIR(VLEV_120, 500000000),
+	VRPAIR(VLEV_125, 533000000),
+	VRPAIR(VLEV_130, 600000000),
+};
+
+static struct bfin_dpmc_platform_data bfin_dmpc_vreg_data = {
+	.tuple_tab = cclk_vlev_datasheet,
+	.tabsize = ARRAY_SIZE(cclk_vlev_datasheet),
+	.vr_settling_time = 25 /* us */,
+};
+
+static struct platform_device bfin_dpmc = {
+	.name = "bfin dpmc",
+	.dev = {
+		.platform_data = &bfin_dmpc_vreg_data,
+	},
+};
+
+static struct platform_device *cm_bf537u_devices[] __initdata = {
+
+	&bfin_dpmc,
+
+#if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
+	&hitachi_fb_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+	&rtc_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+	&bfin_uart_device,
+#endif
+
+#if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE)
+#ifdef CONFIG_BFIN_SIR0
+	&bfin_sir0_device,
+#endif
+#ifdef CONFIG_BFIN_SIR1
+	&bfin_sir1_device,
+#endif
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+	&i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+	&bfin_sport0_uart_device,
+	&bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+	&isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+	&smc91x_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	&bfin_mii_bus,
+	&bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+	&net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	&bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+	&bfin_pata_device,
+#endif
+
+#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
+	&cm_flash_device,
+#endif
+
+	&bfin_gpios_device,
+};
+
+static int __init cm_bf537u_init(void)
+{
+	printk(KERN_INFO "%s(): registering device resources\n", __func__);
+	platform_add_devices(cm_bf537u_devices, ARRAY_SIZE(cm_bf537u_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+	irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+	return 0;
+}
+
+arch_initcall(cm_bf537u_init);
+
+void bfin_get_ether_addr(char *addr)
+{
+	random_ether_addr(addr);
+	printk(KERN_WARNING "%s:%s: Setting Ethernet MAC to a random one\n", __FILE__, __func__);
+}
+EXPORT_SYMBOL(bfin_get_ether_addr);
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 838240f..10b35b8 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -92,6 +92,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -110,6 +118,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -282,13 +293,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip mmc_spi_chip_info = {
 	.enable_dma = 0,
@@ -348,22 +352,13 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
 	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
 		.controller_data = &ad1836_spi_chip_info,
 	},
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-	{
-		.modalias = "ad9960-spi",
-		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &ad9960_spi_chip_info,
-	},
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index bd65690..9db6b40 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -171,6 +171,14 @@ static struct platform_device rtc_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -189,6 +197,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -196,10 +207,15 @@ static struct platform_device smc91x_device = {
 static struct resource dm9000_resources[] = {
 	[0] = {
 		.start	= 0x203FB800,
-		.end	= 0x203FB800 + 8,
+		.end	= 0x203FB800 + 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
+		.start	= 0x203FB804,
+		.end	= 0x203FB804 + 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
 		.start	= IRQ_PF9,
 		.end	= IRQ_PF9,
 		.flags	= (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
@@ -516,19 +532,135 @@ static struct bfin5xx_spi_chip spi_adc_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+	|| defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+#if defined(CONFIG_SND_BF5XX_SOC_AD1938) \
+	|| defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
+static struct bfin5xx_spi_chip ad1938_spi_chip_info = {
+	.enable_dma = 0,
+	.bits_per_word = 8,
+	.cs_gpio = GPIO_PF5,
+};
+#endif
+
+#if defined(CONFIG_INPUT_EVAL_AD7147EBZ)
+#include <linux/input.h>
+#include <linux/input/ad714x.h>
+static struct bfin5xx_spi_chip ad7147_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 16,
 };
+
+static struct ad714x_slider_plat slider_plat[] = {
+	{
+		.start_stage = 0,
+		.end_stage = 7,
+		.max_coord = 128,
+	},
+};
+
+static struct ad714x_button_plat button_plat[] = {
+	{
+		.keycode = BTN_FORWARD,
+		.l_mask = 0,
+		.h_mask = 0x600,
+	},
+	{
+		.keycode = BTN_LEFT,
+		.l_mask = 0,
+		.h_mask = 0x500,
+	},
+	{
+		.keycode = BTN_MIDDLE,
+		.l_mask = 0,
+		.h_mask = 0x800,
+	},
+	{
+		.keycode = BTN_RIGHT,
+		.l_mask = 0x100,
+		.h_mask = 0x400,
+	},
+	{
+		.keycode = BTN_BACK,
+		.l_mask = 0x200,
+		.h_mask = 0x400,
+	},
+};
+static struct ad714x_platform_data ad7147_platfrom_data = {
+	.slider_num = 1,
+	.button_num = 5,
+	.slider = slider_plat,
+	.button = button_plat,
+	.stage_cfg_reg =  {
+		{0xFBFF, 0x1FFF, 0, 0x2626, 1600, 1600, 1600, 1600},
+		{0xEFFF, 0x1FFF, 0, 0x2626, 1650, 1650, 1650, 1650},
+		{0xFFFF, 0x1FFE, 0, 0x2626, 1650, 1650, 1650, 1650},
+		{0xFFFF, 0x1FFB, 0, 0x2626, 1650, 1650, 1650, 1650},
+		{0xFFFF, 0x1FEF, 0, 0x2626, 1650, 1650, 1650, 1650},
+		{0xFFFF, 0x1FBF, 0, 0x2626, 1650, 1650, 1650, 1650},
+		{0xFFFF, 0x1EFF, 0, 0x2626, 1650, 1650, 1650, 1650},
+		{0xFFFF, 0x1BFF, 0, 0x2626, 1600, 1600, 1600, 1600},
+		{0xFF7B, 0x3FFF, 0x506,  0x2626, 1100, 1100, 1150, 1150},
+		{0xFDFE, 0x3FFF, 0x606,  0x2626, 1100, 1100, 1150, 1150},
+		{0xFEBA, 0x1FFF, 0x1400, 0x2626, 1200, 1200, 1300, 1300},
+		{0xFFEF, 0x1FFF, 0x0,    0x2626, 1100, 1100, 1150, 1150},
+	},
+	.sys_cfg_reg = {0x2B2, 0x0, 0x3233, 0x819, 0x832, 0xCFF, 0xCFF, 0x0},
+};
+#endif
+
+#if defined(CONFIG_INPUT_EVAL_AD7142EB)
+#include <linux/input.h>
+#include <linux/input/ad714x.h>
+static struct ad714x_button_plat button_plat[] = {
+	{
+		.keycode = BTN_1,
+		.l_mask = 0,
+		.h_mask = 0x1,
+	},
+	{
+		.keycode = BTN_2,
+		.l_mask = 0,
+		.h_mask = 0x2,
+	},
+	{
+		.keycode = BTN_3,
+		.l_mask = 0,
+		.h_mask = 0x4,
+	},
+	{
+		.keycode = BTN_4,
+		.l_mask = 0x0,
+		.h_mask = 0x8,
+	},
+};
+static struct ad714x_platform_data ad7142_platfrom_data = {
+	.button_num = 4,
+	.button = button_plat,
+	.stage_cfg_reg =  {
+		/* fixme: figure out right setting for all comoponent according
+		 * to hardware feature of EVAL-AD7142EB board */
+		{0xE7FF, 0x3FFF, 0x0005, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+		{0xFDBF, 0x3FFF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+		{0xFFFF, 0x2DFF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+		{0xFFFF, 0x37BF, 0x0001, 0x2626, 0x01F4, 0x01F4, 0x028A, 0x028A},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+		{0xFFFF, 0x3FFF, 0x0000, 0x0606, 0x01F4, 0x01F4, 0x0320, 0x0320},
+	},
+	.sys_cfg_reg = {0x0B2, 0x0, 0x690, 0x664, 0x290F, 0xF, 0xF, 0x0},
+};
 #endif
 
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
@@ -555,15 +687,7 @@ static struct mmc_spi_platform_data bfin_mmc_spi_pdata = {
 static struct bfin5xx_spi_chip  mmc_spi_chip_info = {
 	.enable_dma = 0,
 	.bits_per_word = 8,
-};
-#endif
-
-#if defined(CONFIG_PBX)
-static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
-	.ctl_reg	= 0x4, /* send zero */
-	.enable_dma	= 0,
-	.bits_per_word	= 8,
-	.cs_change_per_word = 1,
+	.pio_interrupt = 0,
 };
 #endif
 
@@ -743,25 +867,42 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 	},
 #endif
 
-#if defined(CONFIG_SND_BLACKFIN_AD1836) \
-	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+	|| defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
-		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+		.chip_select = 4,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
 		.controller_data = &ad1836_spi_chip_info,
+		.mode = SPI_MODE_3,
 	},
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1938) || defined(CONFIG_SND_BF5XX_SOC_AD1938_MODULE)
 	{
-		.modalias = "ad9960-spi",
-		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
+		.modalias = "ad1938",
+		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &ad9960_spi_chip_info,
+		.chip_select = 0,/* CONFIG_SND_BLACKFIN_SPI_PFBIT */
+		.controller_data = &ad1938_spi_chip_info,
+		.mode = SPI_MODE_3,
 	},
 #endif
+
+#if defined(CONFIG_INPUT_EVAL_AD7147EBZ)
+	{
+		.modalias = "ad714x_captouch",
+		.max_speed_hz = 1000000,     /* max spi clock (SCK) speed in HZ */
+		.irq = IRQ_PF4,
+		.bus_num = 0,
+		.chip_select = 5,
+		.mode = SPI_MODE_3,
+		.platform_data = &ad7147_platfrom_data,
+		.controller_data = &ad7147_spi_chip_info,
+	},
+#endif
+
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
@@ -773,24 +914,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 		.mode = SPI_MODE_3,
 	},
 #endif
-#if defined(CONFIG_PBX)
-	{
-		.modalias = "fxs-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J11_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-	{
-		.modalias = "fxo-spi",
-		.max_speed_hz = 12500000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 8 - CONFIG_J19_JUMPER,
-		.controller_data = &spi_si3xxx_chip_info,
-		.mode = SPI_MODE_3,
-	},
-#endif
 #if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
 	{
 		.modalias		= "ad7877",
@@ -864,6 +987,11 @@ static struct resource bfin_spi0_resource[] = {
 	[1] = {
 		.start = CH_SPI,
 		.end   = CH_SPI,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = IRQ_SPI,
+		.end   = IRQ_SPI,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -1089,7 +1217,7 @@ static struct platform_device i2c_bfin_twi_device = {
 
 #if defined(CONFIG_KEYBOARD_ADP5588) || defined(CONFIG_KEYBOARD_ADP5588_MODULE)
 #include <linux/input.h>
-#include <linux/i2c/adp5588_keys.h>
+#include <linux/i2c/adp5588.h>
 static const unsigned short adp5588_keymap[ADP5588_KEYMAPSIZE] = {
 	[0]	 = KEY_GRAVE,
 	[1]	 = KEY_1,
@@ -1309,11 +1437,20 @@ static struct adp5520_platform_data adp5520_pdev_data = {
 
 #endif
 
+#if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
+#include <linux/i2c/adp5588.h>
+static struct adp5588_gpio_platfrom_data adp5588_gpio_data = {
+	.gpio_start = 50,
+	.pullup_dis_mask = 0,
+};
+#endif
+
 static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
-#if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
+#if defined(CONFIG_INPUT_EVAL_AD7142EB)
 	{
-		I2C_BOARD_INFO("ad7142_joystick", 0x2C),
+		I2C_BOARD_INFO("ad7142_captouch", 0x2C),
 		.irq = IRQ_PG5,
+		.platform_data = (void *)&ad7142_platfrom_data,
 	},
 #endif
 #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE)
@@ -1321,7 +1458,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
 	},
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
 		.irq = IRQ_PG6,
@@ -1355,6 +1492,12 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
 		.platform_data = (void *)&adxl34x_info,
 	},
 #endif
+#if defined(CONFIG_GPIO_ADP5588) || defined(CONFIG_GPIO_ADP5588_MODULE)
+	{
+		I2C_BOARD_INFO("adp5588-gpio", 0x34),
+		.platform_data = (void *)&adp5588_gpio_data,
+	},
+#endif
 };
 
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -1456,6 +1599,13 @@ static struct platform_device bfin_dpmc = {
 	},
 };
 
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+static struct platform_device bfin_tdm = {
+	.name = "bfin-tdm",
+	/* TODO: add platform data here */
+};
+#endif
+
 static struct platform_device *stamp_devices[] __initdata = {
 
 	&bfin_dpmc,
@@ -1561,6 +1711,10 @@ static struct platform_device *stamp_devices[] __initdata = {
 #if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
 	&stamp_flash_device,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+	&bfin_tdm,
+#endif
 };
 
 static int __init stamp_init(void)
@@ -1572,11 +1726,6 @@ static int __init stamp_init(void)
 	platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
 	spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
 
-#if (defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)) \
-	 && defined(PATA_INT)
-	irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
-#endif
-
 	return 0;
 }
 
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index e523e6e..61353f7 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -45,6 +45,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#include <linux/spi/mmc_spi.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -101,13 +102,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip mmc_spi_chip_info = {
 	.enable_dma = 0,
@@ -142,7 +136,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -150,22 +144,12 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 	},
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-	{
-		.modalias = "ad9960-spi",
-		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &ad9960_spi_chip_info,
-	},
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
 		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
-		.chip_select = 5,
+		.chip_select = 1,
 		.controller_data = &mmc_spi_chip_info,
 		.mode = SPI_MODE_3,
 	},
@@ -223,6 +207,14 @@ static struct platform_device hitachi_fb_device = {
 #endif
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.start = 0x20200300,
@@ -240,6 +232,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -285,12 +280,12 @@ static struct platform_device isp1362_hcd_device = {
 #if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
 static struct resource net2272_bfin_resources[] = {
 	{
-		.start = 0x20200000,
-		.end = 0x20200000 + 0x100,
+		.start = 0x20300000,
+		.end = 0x20300000 + 0x100,
 		.flags = IORESOURCE_MEM,
 	}, {
-		.start = IRQ_PH14,
-		.end = IRQ_PH14,
+		.start = IRQ_PG13,
+		.end = IRQ_PG13,
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
 	},
 };
@@ -324,7 +319,7 @@ static struct mtd_partition cm_partitions[] = {
 		.offset = 0,
 	}, {
 		.name   = "linux kernel(nor)",
-		.size   = 0xE0000,
+		.size   = 0x100000,
 		.offset = MTDPART_OFS_APPEND,
 	}, {
 		.name   = "file system(nor)",
diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c
index 8118505..d23fc0e 100644
--- a/arch/blackfin/mach-bf537/dma.c
+++ b/arch/blackfin/mach-bf537/dma.c
@@ -96,12 +96,12 @@ int channel2irq(unsigned int channel)
 		ret_irq = IRQ_SPI;
 		break;
 
-	case CH_UART_RX:
-		ret_irq = IRQ_UART_RX;
+	case CH_UART0_RX:
+		ret_irq = IRQ_UART0_RX;
 		break;
 
-	case CH_UART_TX:
-		ret_irq = IRQ_UART_TX;
+	case CH_UART0_TX:
+		ret_irq = IRQ_UART0_TX;
 		break;
 
 	case CH_MEM_STREAM0_SRC:
diff --git a/arch/blackfin/mach-bf537/include/mach/anomaly.h b/arch/blackfin/mach-bf537/include/mach/anomaly.h
index e66aa13..f091ad2 100644
--- a/arch/blackfin/mach-bf537/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf537/include/mach/anomaly.h
@@ -143,7 +143,7 @@
 /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */
 #define ANOMALY_05000371 (1)
 /* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */
-#define ANOMALY_05000402 (__SILICON_REVISION__ >= 5)
+#define ANOMALY_05000402 (__SILICON_REVISION__ == 2)
 /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */
 #define ANOMALY_05000403 (1)
 /* Speculative Fetches Can Cause Undesired External FIFO Operations */
diff --git a/arch/blackfin/mach-bf537/include/mach/blackfin.h b/arch/blackfin/mach-bf537/include/mach/blackfin.h
index f5e5015..9ee8834 100644
--- a/arch/blackfin/mach-bf537/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf537/include/mach/blackfin.h
@@ -45,96 +45,11 @@
 #if !defined(__ASSEMBLY__)
 #include "cdefBF534.h"
 
-/* UART 0*/
-#define bfin_read_UART_THR() bfin_read_UART0_THR()
-#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val)
-#define bfin_read_UART_RBR() bfin_read_UART0_RBR()
-#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val)
-#define bfin_read_UART_DLL() bfin_read_UART0_DLL()
-#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val)
-#define bfin_read_UART_IER() bfin_read_UART0_IER()
-#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val)
-#define bfin_read_UART_DLH() bfin_read_UART0_DLH()
-#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val)
-#define bfin_read_UART_IIR() bfin_read_UART0_IIR()
-#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val)
-#define bfin_read_UART_LCR() bfin_read_UART0_LCR()
-#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val)
-#define bfin_read_UART_MCR() bfin_read_UART0_MCR()
-#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val)
-#define bfin_read_UART_LSR() bfin_read_UART0_LSR()
-#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val)
-#define bfin_read_UART_SCR() bfin_read_UART0_SCR()
-#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val)
-#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL()
-#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val)
-
 #if defined(CONFIG_BF537) || defined(CONFIG_BF536)
 #include "cdefBF537.h"
 #endif
 #endif
 
-/* MAP used DEFINES from BF533 to BF537 - so we don't need to change them in the driver, kernel, etc. */
-
-/* UART_IIR Register */
-#define STATUS(x)	((x << 1) & 0x06)
-#define STATUS_P1	0x02
-#define STATUS_P0	0x01
-
-/* DMA Channel */
-#define bfin_read_CH_UART_RX() bfin_read_CH_UART0_RX()
-#define bfin_write_CH_UART_RX(val) bfin_write_CH_UART0_RX(val)
-#define CH_UART_RX CH_UART0_RX
-#define bfin_read_CH_UART_TX() bfin_read_CH_UART0_TX()
-#define bfin_write_CH_UART_TX(val) bfin_write_CH_UART0_TX(val)
-#define CH_UART_TX CH_UART0_TX
-
-/* System Interrupt Controller */
-#define bfin_read_IRQ_UART_RX() bfin_read_IRQ_UART0_RX()
-#define bfin_write_IRQ_UART_RX(val) bfin_write_IRQ_UART0_RX(val)
-#define IRQ_UART_RX IRQ_UART0_RX
-#define bfin_read_IRQ_UART_TX() bfin_read_IRQ_UART0_TX()
-#define bfin_write_IRQ_UART_TX(val) bfin_write_IRQ_UART0_TX(val)
-#define	IRQ_UART_TX IRQ_UART0_TX
-#define bfin_read_IRQ_UART_ERROR() bfin_read_IRQ_UART0_ERROR()
-#define bfin_write_IRQ_UART_ERROR(val) bfin_write_IRQ_UART0_ERROR(val)
-#define	IRQ_UART_ERROR IRQ_UART0_ERROR
-
-/* MMR Registers*/
-#define bfin_read_UART_THR() bfin_read_UART0_THR()
-#define bfin_write_UART_THR(val) bfin_write_UART0_THR(val)
-#define BFIN_UART_THR UART0_THR
-#define bfin_read_UART_RBR() bfin_read_UART0_RBR()
-#define bfin_write_UART_RBR(val) bfin_write_UART0_RBR(val)
-#define BFIN_UART_RBR UART0_RBR
-#define bfin_read_UART_DLL() bfin_read_UART0_DLL()
-#define bfin_write_UART_DLL(val) bfin_write_UART0_DLL(val)
-#define BFIN_UART_DLL UART0_DLL
-#define bfin_read_UART_IER() bfin_read_UART0_IER()
-#define bfin_write_UART_IER(val) bfin_write_UART0_IER(val)
-#define BFIN_UART_IER UART0_IER
-#define bfin_read_UART_DLH() bfin_read_UART0_DLH()
-#define bfin_write_UART_DLH(val) bfin_write_UART0_DLH(val)
-#define BFIN_UART_DLH UART0_DLH
-#define bfin_read_UART_IIR() bfin_read_UART0_IIR()
-#define bfin_write_UART_IIR(val) bfin_write_UART0_IIR(val)
-#define BFIN_UART_IIR UART0_IIR
-#define bfin_read_UART_LCR() bfin_read_UART0_LCR()
-#define bfin_write_UART_LCR(val) bfin_write_UART0_LCR(val)
-#define BFIN_UART_LCR UART0_LCR
-#define bfin_read_UART_MCR() bfin_read_UART0_MCR()
-#define bfin_write_UART_MCR(val) bfin_write_UART0_MCR(val)
-#define BFIN_UART_MCR UART0_MCR
-#define bfin_read_UART_LSR() bfin_read_UART0_LSR()
-#define bfin_write_UART_LSR(val) bfin_write_UART0_LSR(val)
-#define BFIN_UART_LSR UART0_LSR
-#define bfin_read_UART_SCR() bfin_read_UART0_SCR()
-#define bfin_write_UART_SCR(val) bfin_write_UART0_SCR(val)
-#define BFIN_UART_SCR  UART0_SCR
-#define bfin_read_UART_GCTL() bfin_read_UART0_GCTL()
-#define bfin_write_UART_GCTL(val) bfin_write_UART0_GCTL(val)
-#define BFIN_UART_GCTL UART0_GCTL
-
 #define BFIN_UART_NR_PORTS	2
 
 #define OFFSET_THR              0x00	/* Transmit Holding register            */
@@ -150,11 +65,6 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks													*/
 #define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c
index 57695b4..f2ac3b0 100644
--- a/arch/blackfin/mach-bf538/boards/ezkit.c
+++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -31,6 +31,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
 #include <linux/mtd/partitions.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
@@ -177,6 +178,14 @@ static struct platform_device bfin_sir2_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -194,6 +203,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -390,6 +402,11 @@ static struct resource bfin_spi2_resource[] = {
 	[1] = {
 		.start = CH_SPI2,
 		.end   = CH_SPI2,
+		.flags = IORESOURCE_DMA,
+	},
+	[2] = {
+		.start = IRQ_SPI2,
+		.end   = IRQ_SPI2,
 		.flags = IORESOURCE_IRQ,
 	}
 };
@@ -550,6 +567,50 @@ static struct platform_device bfin_dpmc = {
 	},
 };
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition ezkit_partitions[] = {
+	{
+		.name       = "bootloader(nor)",
+		.size       = 0x40000,
+		.offset     = 0,
+	}, {
+		.name       = "linux kernel(nor)",
+		.size       = 0x180000,
+		.offset     = MTDPART_OFS_APPEND,
+	}, {
+		.name       = "file system(nor)",
+		.size       = MTDPART_SIZ_FULL,
+		.offset     = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct physmap_flash_data ezkit_flash_data = {
+	.width      = 2,
+	.parts      = ezkit_partitions,
+	.nr_parts   = ARRAY_SIZE(ezkit_partitions),
+};
+
+static struct resource ezkit_flash_resource = {
+	.start = 0x20000000,
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+	.end   = 0x202fffff,
+#else
+	.end   = 0x203fffff,
+#endif
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ezkit_flash_device = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &ezkit_flash_data,
+	},
+	.num_resources = 1,
+	.resource      = &ezkit_flash_resource,
+};
+#endif
+
 static struct platform_device *cm_bf538_devices[] __initdata = {
 
 	&bfin_dpmc,
@@ -598,6 +659,10 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
 #endif
 
 	&bfin_gpios_device,
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+	&ezkit_flash_device,
+#endif
 };
 
 static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf538/include/mach/anomaly.h b/arch/blackfin/mach-bf538/include/mach/anomaly.h
index 451cf8a..26b7608 100644
--- a/arch/blackfin/mach-bf538/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf538/include/mach/anomaly.h
@@ -113,7 +113,7 @@
 /* GPIO Pins PC1 and PC4 Can Function as Normal Outputs */
 #define ANOMALY_05000375 (__SILICON_REVISION__ < 4)
 /* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */
-#define ANOMALY_05000402 (__SILICON_REVISION__ < 4)
+#define ANOMALY_05000402 (__SILICON_REVISION__ == 3)
 /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */
 #define ANOMALY_05000403 (1)
 /* Speculative Fetches Can Cause Undesired External FIFO Operations */
diff --git a/arch/blackfin/mach-bf538/include/mach/blackfin.h b/arch/blackfin/mach-bf538/include/mach/blackfin.h
index 9496196..5ecee16 100644
--- a/arch/blackfin/mach-bf538/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf538/include/mach/blackfin.h
@@ -47,11 +47,6 @@
 #endif
 #endif
 
-/* UART_IIR Register */
-#define STATUS(x)	((x << 1) & 0x06)
-#define STATUS_P1	0x02
-#define STATUS_P0	0x01
-
 #define BFIN_UART_NR_PORTS	3
 
 #define OFFSET_THR              0x00	/* Transmit Holding register            */
@@ -67,11 +62,6 @@
 #define OFFSET_SCR              0x1C	/* SCR Scratch Register                 */
 #define OFFSET_GCTL             0x24	/* Global Control Register              */
 
-/* DPMC*/
-#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
-#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
-#define STOPCK_OFF STOPCK
-
 /* PLL_DIV Masks													*/
 #define CCLK_DIV1 CSEL_DIV1	/*          CCLK = VCO / 1                                  */
 #define CCLK_DIV2 CSEL_DIV2	/*          CCLK = VCO / 2                                  */
diff --git a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
index 99ca3f4..1de6751 100644
--- a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
+++ b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
@@ -1310,6 +1310,7 @@
 #define bfin_write_PPI_CONTROL(val)    bfin_write16(PPI_CONTROL, val)
 #define bfin_read_PPI_STATUS()         bfin_read16(PPI_STATUS)
 #define bfin_write_PPI_STATUS(val)     bfin_write16(PPI_STATUS, val)
+#define bfin_clear_PPI_STATUS()        bfin_read_PPI_STATUS()
 #define bfin_read_PPI_DELAY()          bfin_read16(PPI_DELAY)
 #define bfin_write_PPI_DELAY(val)      bfin_write16(PPI_DELAY, val)
 #define bfin_read_PPI_COUNT()          bfin_read16(PPI_COUNT)
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index f5a3c30..e565aae 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -291,6 +291,8 @@ static struct platform_device bfin_sir3_device = {
 #endif
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+
 static struct resource smsc911x_resources[] = {
 	{
 		.name = "smsc911x-memory",
@@ -304,11 +306,22 @@ static struct resource smsc911x_resources[] = {
 		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 	},
 };
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.flags = SMSC911X_USE_16BIT,
+	.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
 static struct platform_device smsc911x_device = {
 	.name = "smsc911x",
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smsc911x_resources),
 	.resource = smsc911x_resources,
+	.dev = {
+		.platform_data = &smsc911x_config,
+	},
 };
 #endif
 
@@ -473,7 +486,7 @@ static struct mtd_partition para_partitions[] = {
 		.offset     = 0,
 	}, {
 		.name       = "linux kernel(nor)",
-		.size       = 0x400000,
+		.size       = 0x100000,
 		.offset     = MTDPART_OFS_APPEND,
 	}, {
 		.name       = "file system(nor)",
@@ -642,7 +655,7 @@ static struct resource bfin_spi1_resource[] = {
 
 /* SPI controller data */
 static struct bfin5xx_spi_master bf54x_spi_master_info0 = {
-	.num_chipselect = 8,
+	.num_chipselect = 3,
 	.enable_dma = 1,  /* master has the ability to do dma transfer */
 	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
 };
@@ -658,7 +671,7 @@ static struct platform_device bf54x_spi_master0 = {
 };
 
 static struct bfin5xx_spi_master bf54x_spi_master_info1 = {
-	.num_chipselect = 8,
+	.num_chipselect = 3,
 	.enable_dma = 1,  /* master has the ability to do dma transfer */
 	.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
 };
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index dc0dd9b..c66f380 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -99,8 +99,8 @@ static struct platform_device bfin_isp1760_device = {
 #include <mach/bf54x-lq043.h>
 
 static struct bfin_bf54xfb_mach_info bf54x_lq043_data = {
-	.width =	480,
-	.height =	272,
+	.width =	95,
+	.height =	54,
 	.xres =		{480, 480, 480},
 	.yres =		{272, 272, 272},
 	.bpp =		{24, 24, 24},
@@ -702,7 +702,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
 	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 1,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
@@ -783,7 +783,7 @@ static struct resource bfin_spi1_resource[] = {
 
 /* SPI controller data */
 static struct bfin5xx_spi_master bf54x_spi_master_info0 = {
-	.num_chipselect = 8,
+	.num_chipselect = 3,
 	.enable_dma = 1,  /* master has the ability to do dma transfer */
 	.pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0},
 };
@@ -799,7 +799,7 @@ static struct platform_device bf54x_spi_master0 = {
 };
 
 static struct bfin5xx_spi_master bf54x_spi_master_info1 = {
-	.num_chipselect = 8,
+	.num_chipselect = 3,
 	.enable_dma = 1,  /* master has the ability to do dma transfer */
 	.pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0},
 };
@@ -869,7 +869,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = {
 		I2C_BOARD_INFO("pcf8574_lcd", 0x22),
 	},
 #endif
-#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
+#if defined(CONFIG_INPUT_PCF8574) || defined(CONFIG_INPUT_PCF8574_MODULE)
 	{
 		I2C_BOARD_INFO("pcf8574_keypad", 0x27),
 		.irq = 212,
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index 5359806..d9239bc 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -91,16 +91,16 @@ int channel2irq(unsigned int channel)
 		ret_irq = IRQ_SPI1;
 		break;
 	case CH_UART0_RX:
-		ret_irq = IRQ_UART_RX;
+		ret_irq = IRQ_UART0_RX;
 		break;
 	case CH_UART0_TX:
-		ret_irq = IRQ_UART_TX;
+		ret_irq = IRQ_UART0_TX;
 		break;
 	case CH_UART1_RX:
-		ret_irq = IRQ_UART_RX;
+		ret_irq = IRQ_UART1_RX;
 		break;
 	case CH_UART1_TX:
-		ret_irq = IRQ_UART_TX;
+		ret_irq = IRQ_UART1_TX;
 		break;
 	case CH_EPPI0:
 		ret_irq = IRQ_EPPI0;
diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h
index cd040fe..52b116a 100644
--- a/arch/blackfin/mach-bf548/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h
@@ -7,7 +7,7 @@
  */
 
 /* This file should be up to date with:
- *  - Revision H, 01/16/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List
+ *  - Revision I, 07/23/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
@@ -162,6 +162,8 @@
 #define ANOMALY_05000430 (__SILICON_REVISION__ >= 2)
 /* Incorrect Use of Stack in Lockbox Firmware During Authentication */
 #define ANOMALY_05000431 (__SILICON_REVISION__ < 3)
+/* SW Breakpoints Ignored Upon Return From Lockbox Authentication */
+#define ANOMALY_05000434 (1)
 /* OTP Write Accesses Not Supported */
 #define ANOMALY_05000442 (__SILICON_REVISION__ < 1)
 /* IFLUSH Instruction at End of Hardware Loop Causes Infinite Stall */
@@ -176,12 +178,26 @@
 #define ANOMALY_05000449 (__SILICON_REVISION__ == 1)
 /* USB DMA Mode 1 Short Packet Data Corruption */
 #define ANOMALY_05000450 (1)
+/* Incorrect Default Hysteresis Setting for RESET, NMI, and BMODE Signals */
+#define ANOMALY_05000452 (__SILICON_REVISION__ < 1)
 /* USB Receive Interrupt Is Not Generated in DMA Mode 1 */
-#define ANOMALY_05000456 (__SILICON_REVISION__ < 3)
+#define ANOMALY_05000456 (1)
+/* Host DMA Port Responds to Certain Bus Activity Without HOST_CE Assertion */
+#define ANOMALY_05000457 (1)
+/* USB DMA Mode 1 Failure When Multiple USB DMA Channels Are Concurrently Enabled */
+#define ANOMALY_05000460 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
+#define ANOMALY_05000462 (1)
+/* USB DMA RX Data Corruption */
+#define ANOMALY_05000463 (1)
+/* USB TX DMA Hang */
+#define ANOMALY_05000464 (1)
 /* USB Rx DMA hang */
 #define ANOMALY_05000465 (1)
+/* TxPktRdy Bit Not Set for Transmit Endpoint When Core and DMA Access USB Endpoint FIFOs Simultaneously */
+#define ANOMALY_05000466 (1)
 /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */
 #define ANOMALY_05000467 (1)
 
@@ -230,6 +246,7 @@
 #define ANOMALY_05000364 (0)
 #define ANOMALY_05000380 (0)
 #define ANOMALY_05000400 (0)
+#define ANOMALY_05000402 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
diff --git a/arch/blackfin/mach-bf548/include/mach/blackfin.h b/arch/blackfin/mach-bf548/include/mach/blackfin.h
index 6b97396..318667b 100644
--- a/arch/blackfin/mach-bf548/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf548/include/mach/blackfin.h
@@ -72,97 +72,8 @@
 #include "cdefBF549.h"
 #endif
 
-/* UART 1*/
-#define bfin_read_UART_THR()		bfin_read_UART1_THR()
-#define bfin_write_UART_THR(val)	bfin_write_UART1_THR(val)
-#define bfin_read_UART_RBR()		bfin_read_UART1_RBR()
-#define bfin_write_UART_RBR(val)	bfin_write_UART1_RBR(val)
-#define bfin_read_UART_DLL()		bfin_read_UART1_DLL()
-#define bfin_write_UART_DLL(val)	bfin_write_UART1_DLL(val)
-#define bfin_read_UART_IER()		bfin_read_UART1_IER()
-#define bfin_write_UART_IER(val)	bfin_write_UART1_IER(val)
-#define bfin_read_UART_DLH()		bfin_read_UART1_DLH()
-#define bfin_write_UART_DLH(val)	bfin_write_UART1_DLH(val)
-#define bfin_read_UART_IIR()		bfin_read_UART1_IIR()
-#define bfin_write_UART_IIR(val)	bfin_write_UART1_IIR(val)
-#define bfin_read_UART_LCR()		bfin_read_UART1_LCR()
-#define bfin_write_UART_LCR(val)	bfin_write_UART1_LCR(val)
-#define bfin_read_UART_MCR()		bfin_read_UART1_MCR()
-#define bfin_write_UART_MCR(val)	bfin_write_UART1_MCR(val)
-#define bfin_read_UART_LSR()		bfin_read_UART1_LSR()
-#define bfin_write_UART_LSR(val)	bfin_write_UART1_LSR(val)
-#define bfin_read_UART_SCR()		bfin_read_UART1_SCR()
-#define bfin_write_UART_SCR(val)	bfin_write_UART1_SCR(val)
-#define bfin_read_UART_GCTL()		bfin_read_UART1_GCTL()
-#define bfin_write_UART_GCTL(val)	bfin_write_UART1_GCTL(val)
-
 #endif
 
-/* MAP used DEFINES from BF533 to BF54x - so we don't need to change 
- * them in the driver, kernel, etc. */
-
-/* UART_IIR Register */
-#define STATUS(x)	((x << 1) & 0x06)
-#define STATUS_P1	0x02
-#define STATUS_P0	0x01
-
-/* UART 0*/
-
-/* DMA Channel */
-#define bfin_read_CH_UART_RX()		bfin_read_CH_UART1_RX()
-#define bfin_write_CH_UART_RX(val)	bfin_write_CH_UART1_RX(val)
-#define bfin_read_CH_UART_TX()		bfin_read_CH_UART1_TX()
-#define bfin_write_CH_UART_TX(val)	bfin_write_CH_UART1_TX(val)
-#define CH_UART_RX			CH_UART1_RX
-#define CH_UART_TX			CH_UART1_TX
-
-/* System Interrupt Controller */
-#define bfin_read_IRQ_UART_RX()		bfin_read_IRQ_UART1_RX()
-#define bfin_write_IRQ_UART_RX(val)	bfin_write_IRQ_UART1_RX(val)
-#define bfin_read_IRQ_UART_TX()		bfin_read_IRQ_UART1_TX()
-#define bfin_write_IRQ_UART_TX(val)	bfin_write_IRQ_UART1_TX(val)
-#define bfin_read_IRQ_UART_ERROR()	bfin_read_IRQ_UART1_ERROR()
-#define bfin_write_IRQ_UART_ERROR(val)	bfin_write_IRQ_UART1_ERROR(val)
-#define IRQ_UART_RX			IRQ_UART1_RX
-#define	IRQ_UART_TX			IRQ_UART1_TX
-#define	IRQ_UART_ERROR			IRQ_UART1_ERROR
-
-/* MMR Registers*/
-#define bfin_read_UART_THR()		bfin_read_UART1_THR()
-#define bfin_write_UART_THR(val)	bfin_write_UART1_THR(val)
-#define bfin_read_UART_RBR()		bfin_read_UART1_RBR()
-#define bfin_write_UART_RBR(val)	bfin_write_UART1_RBR(val)
-#define bfin_read_UART_DLL()		bfin_read_UART1_DLL()
-#define bfin_write_UART_DLL(val)	bfin_write_UART1_DLL(val)
-#define bfin_read_UART_IER()		bfin_read_UART1_IER()
-#define bfin_write_UART_IER(val)	bfin_write_UART1_IER(val)
-#define bfin_read_UART_DLH()		bfin_read_UART1_DLH()
-#define bfin_write_UART_DLH(val)	bfin_write_UART1_DLH(val)
-#define bfin_read_UART_IIR()		bfin_read_UART1_IIR()
-#define bfin_write_UART_IIR(val)	bfin_write_UART1_IIR(val)
-#define bfin_read_UART_LCR()		bfin_read_UART1_LCR()
-#define bfin_write_UART_LCR(val)	bfin_write_UART1_LCR(val)
-#define bfin_read_UART_MCR()		bfin_read_UART1_MCR()
-#define bfin_write_UART_MCR(val)	bfin_write_UART1_MCR(val)
-#define bfin_read_UART_LSR()		bfin_read_UART1_LSR()
-#define bfin_write_UART_LSR(val)	bfin_write_UART1_LSR(val)
-#define bfin_read_UART_SCR()		bfin_read_UART1_SCR()
-#define bfin_write_UART_SCR(val)	bfin_write_UART1_SCR(val)
-#define bfin_read_UART_GCTL()		bfin_read_UART1_GCTL()
-#define bfin_write_UART_GCTL(val)	bfin_write_UART1_GCTL(val)
-
-#define BFIN_UART_THR			UART1_THR
-#define BFIN_UART_RBR			UART1_RBR
-#define BFIN_UART_DLL			UART1_DLL
-#define BFIN_UART_IER			UART1_IER
-#define BFIN_UART_DLH			UART1_DLH
-#define BFIN_UART_IIR			UART1_IIR
-#define BFIN_UART_LCR			UART1_LCR
-#define BFIN_UART_MCR			UART1_MCR
-#define BFIN_UART_LSR			UART1_LSR
-#define BFIN_UART_SCR			UART1_SCR
-#define BFIN_UART_GCTL			UART1_GCTL
-
 #define BFIN_UART_NR_PORTS	4
 
 #define OFFSET_DLL              0x00	/* Divisor Latch (Low-Byte)             */
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index 0c9d72c..6577ecf 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -42,6 +42,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#include <linux/mtd/physmap.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -98,13 +99,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
 };
 #endif
 
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
-	.enable_dma = 0,
-	.bits_per_word = 16,
-};
-#endif
-
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 static struct bfin5xx_spi_chip mmc_spi_chip_info = {
 	.enable_dma = 0,
@@ -139,28 +133,19 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 
 #if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
 		.controller_data = &ad1836_spi_chip_info,
 	},
 #endif
-#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
-	{
-		.modalias = "ad9960-spi",
-		.max_speed_hz = 10000000,     /* max spi clock (SCK) speed in HZ */
-		.bus_num = 0,
-		.chip_select = 1,
-		.controller_data = &ad9960_spi_chip_info,
-	},
-#endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
 	{
 		.modalias = "mmc_spi",
-		.max_speed_hz = 25000000,     /* max spi clock (SCK) speed in HZ */
+		.max_speed_hz = 20000000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
-		.chip_select = 5,
+		.chip_select = 1,
 		.controller_data = &mmc_spi_chip_info,
 		.mode = SPI_MODE_3,
 	},
@@ -213,6 +198,13 @@ static struct platform_device hitachi_fb_device = {
 
 
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
 
 static struct resource smc91x_resources[] = {
 	{
@@ -231,6 +223,65 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
+};
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+
+static struct resource smsc911x_resources[] = {
+	{
+		.name = "smsc911x-memory",
+		.start = 0x24008000,
+		.end = 0x24008000 + 0xFF,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_PF43,
+		.end = IRQ_PF43,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.flags = SMSC911X_USE_16BIT,
+	.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device smsc911x_device = {
+	.name = "smsc911x",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(smsc911x_resources),
+	.resource = smsc911x_resources,
+	.dev = {
+		.platform_data = &smsc911x_config,
+	},
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+	{
+		.start = 0x24000000,
+		.end = 0x24000000 + 0x100,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = IRQ_PF45,
+		.end = IRQ_PF45,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+static struct platform_device net2272_bfin_device = {
+	.name = "net2272",
+	.id = -1,
+	.num_resources = ARRAY_SIZE(net2272_bfin_resources),
+	.resource = net2272_bfin_resources,
 };
 #endif
 
@@ -369,6 +420,46 @@ static struct platform_device bfin_pata_device = {
 };
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition para_partitions[] = {
+	{
+		.name       = "bootloader(nor)",
+		.size       = 0x40000,
+		.offset     = 0,
+	}, {
+		.name       = "linux kernel(nor)",
+		.size       = 0x100000,
+		.offset     = MTDPART_OFS_APPEND,
+	}, {
+		.name       = "file system(nor)",
+		.size       = MTDPART_SIZ_FULL,
+		.offset     = MTDPART_OFS_APPEND,
+	}
+};
+
+static struct physmap_flash_data para_flash_data = {
+	.width      = 2,
+	.parts      = para_partitions,
+	.nr_parts   = ARRAY_SIZE(para_partitions),
+};
+
+static struct resource para_flash_resource = {
+	.start = 0x20000000,
+	.end   = 0x207fffff,
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device para_flash_device = {
+	.name          = "physmap-flash",
+	.id            = 0,
+	.dev = {
+		.platform_data = &para_flash_data,
+	},
+	.num_resources = 1,
+	.resource      = &para_flash_resource,
+};
+#endif
+
 static const unsigned int cclk_vlev_datasheet[] =
 {
 	VRPAIR(VLEV_085, 250000000),
@@ -422,6 +513,14 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
 	&smc91x_device,
 #endif
 
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+	&smsc911x_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+	&net2272_bfin_device,
+#endif
+
 #if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
 	&bfin_spi0_device,
 #endif
@@ -430,6 +529,10 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
 	&bfin_pata_device,
 #endif
 
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+	&para_flash_device,
+#endif
+
 	&bfin_gpios_device,
 };
 
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 4df904f..caed96b 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -147,6 +147,14 @@ static struct platform_device net2272_bfin_device = {
  *  Driver needs to know address, irq and flag pin.
  */
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+#include <linux/smc91x.h>
+
+static struct smc91x_platdata smc91x_info = {
+	.flags = SMC91X_USE_32BIT | SMC91X_NOWAIT,
+	.leda = RPC_LED_100_10,
+	.ledb = RPC_LED_TX_RX,
+};
+
 static struct resource smc91x_resources[] = {
 	{
 		.name = "smc91x-regs",
@@ -166,6 +174,9 @@ static struct platform_device smc91x_device = {
 	.id = 0,
 	.num_resources = ARRAY_SIZE(smc91x_resources),
 	.resource = smc91x_resources,
+	.dev	= {
+		.platform_data	= &smc91x_info,
+	},
 };
 #endif
 
@@ -334,7 +345,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_SND_BLACKFIN_AD1836) \
 	|| defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
 	{
-		.modalias = "ad1836-spi",
+		.modalias = "ad1836",
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
diff --git a/arch/blackfin/mach-bf561/include/mach/anomaly.h b/arch/blackfin/mach-bf561/include/mach/anomaly.h
index a5312b2..70da495 100644
--- a/arch/blackfin/mach-bf561/include/mach/anomaly.h
+++ b/arch/blackfin/mach-bf561/include/mach/anomaly.h
@@ -262,6 +262,8 @@
 #define ANOMALY_05000366 (1)
 /* Possible RETS Register Corruption when Subroutine Is under 5 Cycles in Duration */
 #define ANOMALY_05000371 (1)
+/* SSYNC Stalls Processor when Executed from Non-Cacheable Memory */
+#define ANOMALY_05000402 (__SILICON_REVISION__ == 4)
 /* Level-Sensitive External GPIO Wakeups May Cause Indefinite Stall */
 #define ANOMALY_05000403 (1)
 /* TESTSET Instruction Causes Data Corruption with Writeback Data Cache Enabled */
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S
index 35280f0..f72a6af 100644
--- a/arch/blackfin/mach-bf561/secondary.S
+++ b/arch/blackfin/mach-bf561/secondary.S
@@ -85,16 +85,10 @@ ENTRY(_coreb_trampoline_start)
 	R0 = ~ENICPLB;
 	R0 = R0 & R1;
 
-	/* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
-	CLI R2;
-	SSYNC;
-#endif
+	/* Disabling of CPLBs should be proceeded by a CSYNC */
+	CSYNC;
 	[p0] = R0;
 	SSYNC;
-#ifdef ANOMALY_05000125
-	STI R2;
-#endif
 
 	/* Turn off the dcache */
 	p0.l = LO(DMEM_CONTROL);
@@ -103,16 +97,10 @@ ENTRY(_coreb_trampoline_start)
 	R0 = ~ENDCPLB;
 	R0 = R0 & R1;
 
-	/* Anomaly 05000125 */
-#ifdef ANOMALY_05000125
-	CLI R2;
-	SSYNC;
-#endif
+	/* Disabling of CPLBs should be proceeded by a CSYNC */
+	CSYNC;
 	[p0] = R0;
 	SSYNC;
-#ifdef ANOMALY_05000125
-	STI R2;
-#endif
 
 	/* in case of double faults, save a few things */
 	p0.l = _init_retx_coreb;
@@ -126,22 +114,22 @@ ENTRY(_coreb_trampoline_start)
 	 * below
 	 */
 	GET_PDA(p0, r0);
-	r7 = [p0 + PDA_RETX];
+	r7 = [p0 + PDA_DF_RETX];
 	p1.l = _init_saved_retx_coreb;
 	p1.h = _init_saved_retx_coreb;
 	[p1] = r7;
 
-	r7 = [p0 + PDA_DCPLB];
+	r7 = [p0 + PDA_DF_DCPLB];
 	p1.l = _init_saved_dcplb_fault_addr_coreb;
 	p1.h = _init_saved_dcplb_fault_addr_coreb;
 	[p1] = r7;
 
-	r7 = [p0 + PDA_ICPLB];
+	r7 = [p0 + PDA_DF_ICPLB];
 	p1.l = _init_saved_icplb_fault_addr_coreb;
 	p1.h = _init_saved_icplb_fault_addr_coreb;
 	[p1] = r7;
 
-	r7 = [p0 + PDA_SEQSTAT];
+	r7 = [p0 + PDA_DF_SEQSTAT];
 	p1.l = _init_saved_seqstat_coreb;
 	p1.h = _init_saved_seqstat_coreb;
 	[p1] = r7;
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
index dd8b2dc..814cb48 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -6,7 +6,6 @@ obj-y := \
 	cache.o cache-c.o entry.o head.o \
 	interrupt.o arch_checks.o ints-priority.o
 
-obj-$(CONFIG_BFIN_ICACHE_LOCK) += lock.o
 obj-$(CONFIG_PM)          += pm.o dpmc_modes.o
 obj-$(CONFIG_CPU_FREQ)    += cpufreq.o
 obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
diff --git a/arch/blackfin/mach-common/cache-c.c b/arch/blackfin/mach-common/cache-c.c
index b59ce3c..4ebbd78 100644
--- a/arch/blackfin/mach-common/cache-c.c
+++ b/arch/blackfin/mach-common/cache-c.c
@@ -1,14 +1,16 @@
 /*
  * Blackfin cache control code (simpler control-style functions)
  *
- * Copyright 2004-2008 Analog Devices Inc.
+ * Copyright 2004-2009 Analog Devices Inc.
  *
  * Enter bugs at http://blackfin.uclinux.org/
  *
  * Licensed under the GPL-2 or later.
  */
 
+#include <linux/init.h>
 #include <asm/blackfin.h>
+#include <asm/cplbinit.h>
 
 /* Invalidate the Entire Data cache by
  * clearing DMC[1:0] bits
@@ -34,3 +36,43 @@ void blackfin_invalidate_entire_icache(void)
 	SSYNC();
 }
 
+#if defined(CONFIG_BFIN_ICACHE) || defined(CONFIG_BFIN_DCACHE)
+
+static void
+bfin_cache_init(struct cplb_entry *cplb_tbl, unsigned long cplb_addr,
+                unsigned long cplb_data, unsigned long mem_control,
+                unsigned long mem_mask)
+{
+	int i;
+
+	for (i = 0; i < MAX_CPLBS; i++) {
+		bfin_write32(cplb_addr + i * 4, cplb_tbl[i].addr);
+		bfin_write32(cplb_data + i * 4, cplb_tbl[i].data);
+	}
+
+	_enable_cplb(mem_control, mem_mask);
+}
+
+#ifdef CONFIG_BFIN_ICACHE
+void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
+{
+	bfin_cache_init(icplb_tbl, ICPLB_ADDR0, ICPLB_DATA0, IMEM_CONTROL,
+		(IMC | ENICPLB));
+}
+#endif
+
+#ifdef CONFIG_BFIN_DCACHE
+void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
+{
+	/*
+	 *  Anomaly notes:
+	 *  05000287 - We implement workaround #2 - Change the DMEM_CONTROL
+	 *  register, so that the port preferences for DAG0 and DAG1 are set
+	 *  to port B
+	 */
+	bfin_cache_init(dcplb_tbl, DCPLB_ADDR0, DCPLB_DATA0, DMEM_CONTROL,
+		(DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0)));
+}
+#endif
+
+#endif
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index fb1795d..1e7cac2 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -301,27 +301,31 @@ ENTRY(_ex_replaceable)
 	nop;
 
 ENTRY(_ex_trap_c)
+	/* The only thing that has been saved in this context is
+	 * (R7:6,P5:4), ASTAT & SP - don't use anything else
+	 */
+
+	GET_PDA(p5, r6);
+
 	/* Make sure we are not in a double fault */
 	p4.l = lo(IPEND);
 	p4.h = hi(IPEND);
 	r7 = [p4];
 	CC = BITTST (r7, 5);
 	if CC jump _double_fault;
+	[p5 + PDA_EXIPEND] = r7;
 
 	/* Call C code (trap_c) to handle the exception, which most
 	 * likely involves sending a signal to the current process.
 	 * To avoid double faults, lower our priority to IRQ5 first.
 	 */
-	P5.h = _exception_to_level5;
-	P5.l = _exception_to_level5;
+	r7.h = _exception_to_level5;
+	r7.l = _exception_to_level5;
 	p4.l = lo(EVT5);
 	p4.h = hi(EVT5);
-	[p4] = p5;
+	[p4] = r7;
 	csync;
 
-	GET_PDA(p5, r6);
-#ifndef CONFIG_DEBUG_DOUBLEFAULT
-
 	/*
 	 * Save these registers, as they are only valid in exception context
 	 *  (where we are now - as soon as we defer to IRQ5, they can change)
@@ -341,7 +345,10 @@ ENTRY(_ex_trap_c)
 
 	r6 = retx;
 	[p5 + PDA_RETX] = r6;
-#endif
+
+	r6 = SEQSTAT;
+	[p5 + PDA_SEQSTAT] = r6;
+
 	/* Save the state of single stepping */
 	r6 = SYSCFG;
 	[p5 + PDA_SYSCFG] = r6;
@@ -349,8 +356,7 @@ ENTRY(_ex_trap_c)
 	BITCLR(r6, SYSCFG_SSSTEP_P);
 	SYSCFG = r6;
 
-	/* Disable all interrupts, but make sure level 5 is enabled so
-	 * we can switch to that level.  Save the old mask.  */
+	/* Save the current IMASK, since we change in order to jump to level 5 */
 	cli r6;
 	[p5 + PDA_EXIMASK] = r6;
 
@@ -358,9 +364,21 @@ ENTRY(_ex_trap_c)
 	p4.h = hi(SAFE_USER_INSTRUCTION);
 	retx = p4;
 
+	/* Disable all interrupts, but make sure level 5 is enabled so
+	 * we can switch to that level.
+	 */
 	r6 = 0x3f;
 	sti r6;
 
+	/* In case interrupts are disabled IPEND[4] (global interrupt disable bit)
+	 * clear it (re-enabling interrupts again) by the special sequence of pushing
+	 * RETI onto the stack.  This way we can lower ourselves to IVG5 even if the
+	 * exception was taken after the interrupt handler was called but before it
+	 * got a chance to enable global interrupts itself.
+	 */
+	[--sp] = reti;
+	sp += 4;
+
 	raise 5;
 	jump.s _bfin_return_from_exception;
 ENDPROC(_ex_trap_c)
@@ -379,8 +397,7 @@ ENTRY(_double_fault)
 
 	R5 = [P4];              /* Control Register*/
 	BITCLR(R5,ENICPLB_P);
-	SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
-	.align 8;
+	CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
 	[P4] = R5;
 	SSYNC;
 
@@ -388,8 +405,7 @@ ENTRY(_double_fault)
 	P4.H = HI(DMEM_CONTROL);
 	R5 = [P4];
 	BITCLR(R5,ENDCPLB_P);
-	SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
-	.align 8;
+	CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
 	[P4] = R5;
 	SSYNC;
 
@@ -420,47 +436,55 @@ ENDPROC(_double_fault)
 ENTRY(_exception_to_level5)
 	SAVE_ALL_SYS
 
-	GET_PDA(p4, r7);        /* Fetch current PDA */
-	r6 = [p4 + PDA_RETX];
+	GET_PDA(p5, r7);        /* Fetch current PDA */
+	r6 = [p5 + PDA_RETX];
 	[sp + PT_PC] = r6;
 
-	r6 = [p4 + PDA_SYSCFG];
+	r6 = [p5 + PDA_SYSCFG];
 	[sp + PT_SYSCFG] = r6;
 
-	/* Restore interrupt mask.  We haven't pushed RETI, so this
-	 * doesn't enable interrupts until we return from this handler.  */
-	r6 = [p4 + PDA_EXIMASK];
-	sti r6;
+	r6 = [p5 + PDA_SEQSTAT]; /* Read back seqstat */
+	[sp + PT_SEQSTAT] = r6;
 
 	/* Restore the hardware error vector.  */
-	P5.h = _evt_ivhw;
-	P5.l = _evt_ivhw;
+	r7.h = _evt_ivhw;
+	r7.l = _evt_ivhw;
 	p4.l = lo(EVT5);
 	p4.h = hi(EVT5);
-	[p4] = p5;
+	[p4] = r7;
 	csync;
 
-	p2.l = lo(IPEND);
-	p2.h = hi(IPEND);
-	csync;
-	r0 = [p2];              /* Read current IPEND */
-	[sp + PT_IPEND] = r0;   /* Store IPEND */
+#ifdef CONFIG_DEBUG_DOUBLEFAULT
+	/* Now that we have the hardware error vector programmed properly
+	 * we can re-enable interrupts (IPEND[4]), so if the _trap_c causes
+	 * another hardware error, we can catch it (self-nesting).
+	 */
+	[--sp] = reti;
+	sp += 4;
+#endif
+
+	r7 = [p5 + PDA_EXIPEND]	/* Read the IPEND from the Exception state */
+	[sp + PT_IPEND] = r7;   /* Store IPEND onto the stack */
 
 	r0 = sp; 	/* stack frame pt_regs pointer argument ==> r0 */
 	SP += -12;
 	call _trap_c;
 	SP += 12;
 
-#ifdef CONFIG_DEBUG_DOUBLEFAULT
-	/* Grab ILAT */
-	p2.l = lo(ILAT);
-	p2.h = hi(ILAT);
-	r0 = [p2];
-	r1 = 0x20;  /* Did I just cause anther HW error? */
-	r0 = r0 & r1;
-	CC = R0 == R1;
-	if CC JUMP _double_fault;
-#endif
+	/* If interrupts were off during the exception (IPEND[4] = 1), turn them off
+	 * before we return.
+	 */
+	CC = BITTST(r7, EVT_IRPTEN_P)
+	if !CC jump 1f;
+	/* this will load a random value into the reti register - but that is OK,
+	 * since we do restore it to the correct value in the 'RESTORE_ALL_SYS' macro
+	 */
+	sp += -4;
+	reti = [sp++];
+1:
+	/* restore the interrupt mask (IMASK) */
+	r6 = [p5 + PDA_EXIMASK];
+	sti r6;
 
 	call _ret_from_exception;
 	RESTORE_ALL_SYS
@@ -474,7 +498,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
 	 */
 	EX_SCRATCH_REG = sp;
 	GET_PDA_SAFE(sp);
-	sp = [sp + PDA_EXSTACK]
+	sp = [sp + PDA_EXSTACK];
 	/* Try to deal with syscalls quickly.  */
 	[--sp] = ASTAT;
 	[--sp] = (R7:6,P5:4);
@@ -489,14 +513,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
 	ssync;
 #endif
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-	cc = r7 == r7;
-	p5.h = HI(CHIPID);
-	p5.l = LO(CHIPID);
-	if cc jump 1f;
-	r7.l = W[p5];
-1:
-#endif
+	ANOMALY_283_315_WORKAROUND(p5, r7)
 
 #ifdef CONFIG_DEBUG_DOUBLEFAULT
 	/*
@@ -510,18 +527,18 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
 	p4.l = lo(DCPLB_FAULT_ADDR);
 	p4.h = hi(DCPLB_FAULT_ADDR);
 	r7 = [p4];
-	[p5 + PDA_DCPLB] = r7;
+	[p5 + PDA_DF_DCPLB] = r7;
 
 	p4.l = lo(ICPLB_FAULT_ADDR);
 	p4.h = hi(ICPLB_FAULT_ADDR);
 	r7 = [p4];
-	[p5 + PDA_ICPLB] = r7;
+	[p5 + PDA_DF_ICPLB] = r7;
 
-	r6 = retx;
-	[p5 + PDA_RETX] = r6;
+	r7 = retx;
+	[p5 + PDA_DF_RETX] = r7;
 
 	r7 = SEQSTAT;		/* reason code is in bit 5:0 */
-	[p5 + PDA_SEQSTAT] = r7;
+	[p5 + PDA_DF_SEQSTAT] = r7;
 #else
 	r7 = SEQSTAT;           /* reason code is in bit 5:0 */
 #endif
@@ -686,8 +703,14 @@ ENTRY(_system_call)
 #ifdef CONFIG_IPIPE
 	cc = BITTST(r7, TIF_IRQ_SYNC);
 	if !cc jump .Lsyscall_no_irqsync;
+	/*
+	 * Clear IPEND[4] manually to undo what resume_userspace_1 just did;
+	 * we need this so that high priority domain interrupts may still
+	 * preempt the current domain while the pipeline log is being played
+	 * back.
+	 */
 	[--sp] = reti;
-	r0 = [sp++];
+	SP += 4; /* don't merge with next insn to keep the pattern obvious */
 	SP += -12;
 	call ___ipipe_sync_root;
 	SP += 12;
@@ -699,7 +722,7 @@ ENTRY(_system_call)
 
 	/* Reenable interrupts.  */
 	[--sp] = reti;
-	r0 = [sp++];
+	sp += 4;
 
 	SP += -12;
 	call _schedule;
@@ -715,7 +738,7 @@ ENTRY(_system_call)
 .Lsyscall_do_signals:
 	/* Reenable interrupts.  */
 	[--sp] = reti;
-	r0 = [sp++];
+	sp += 4;
 
 	r0 = sp;
 	SP += -12;
@@ -725,10 +748,6 @@ ENTRY(_system_call)
 .Lsyscall_really_exit:
 	r5 = [sp + PT_RESERVED];
 	rets = r5;
-#ifdef CONFIG_IPIPE
-	[--sp] = reti;
-	r5 = [sp++];
-#endif /* CONFIG_IPIPE */
 	rts;
 ENDPROC(_system_call)
 
@@ -816,13 +835,13 @@ ENDPROC(_resume)
 
 ENTRY(_ret_from_exception)
 #ifdef CONFIG_IPIPE
-	[--sp] = rets;
-	SP += -12;
-	call ___ipipe_check_root
-	SP += 12
-	rets = [sp++];
-	cc = r0 == 0;
-	if cc jump 4f;                /* not on behalf of Linux, get out */
+	p2.l = _per_cpu__ipipe_percpu_domain;
+	p2.h = _per_cpu__ipipe_percpu_domain;
+	r0.l = _ipipe_root;
+	r0.h = _ipipe_root;
+	r2 = [p2];
+	cc = r0 == r2;
+	if !cc jump 4f;  /* not on behalf of the root domain, get out */
 #endif /* CONFIG_IPIPE */
 	p2.l = lo(IPEND);
 	p2.h = hi(IPEND);
@@ -882,14 +901,9 @@ ENDPROC(_ret_from_exception)
 
 #ifdef CONFIG_IPIPE
 
-_sync_root_irqs:
-	[--sp] = reti;		/* Reenable interrupts */
-	r0 = [sp++];
-	jump.l ___ipipe_sync_root
-
 _resume_kernel_from_int:
-	r0.l = _sync_root_irqs
-	r0.h = _sync_root_irqs
+	r0.l = ___ipipe_sync_root;
+	r0.h = ___ipipe_sync_root;
 	[--sp] = rets;
 	[--sp] = ( r7:4, p5:3 );
 	SP += -12;
@@ -953,10 +967,10 @@ ENTRY(_lower_to_irq14)
 #endif
 
 #ifdef CONFIG_DEBUG_HWERR
-	/* enable irq14 & hwerr interrupt, until we transition to _evt14_softirq */
+	/* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */
 	r0 = (EVT_IVG14 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
 #else
-	/* Only enable irq14 interrupt, until we transition to _evt14_softirq */
+	/* Only enable irq14 interrupt, until we transition to _evt_evt14 */
 	r0 = (EVT_IVG14 | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
 #endif
 	sti r0;
@@ -964,7 +978,7 @@ ENTRY(_lower_to_irq14)
 	rti;
 ENDPROC(_lower_to_irq14)
 
-ENTRY(_evt14_softirq)
+ENTRY(_evt_evt14)
 #ifdef CONFIG_DEBUG_HWERR
 	r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
 	sti r0;
@@ -974,7 +988,7 @@ ENTRY(_evt14_softirq)
 	[--sp] = RETI;
 	SP += 4;
 	rts;
-ENDPROC(_evt14_softirq)
+ENDPROC(_evt_evt14)
 
 ENTRY(_schedule_and_signal_from_int)
 	/* To end up here, vector 15 was changed - so we have to change it
@@ -1004,6 +1018,12 @@ ENTRY(_schedule_and_signal_from_int)
 #endif
 	sti r0;
 
+	/* finish the userspace "atomic" functions for it */
+	r1 = FIXED_CODE_END;
+	r2 = [sp + PT_PC];
+	cc = r1 <= r2;
+	if cc jump .Lresume_userspace (bp);
+
 	r0 = sp;
 	sp += -12;
 	call _finish_atomic_sections;
@@ -1107,14 +1127,7 @@ ENTRY(_early_trap)
 	SAVE_ALL_SYS
 	trace_buffer_stop(p0,r0);
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-	cc = r5 == r5;
-	p4.h = HI(CHIPID);
-	p4.l = LO(CHIPID);
-	if cc jump 1f;
-	r5.l = W[p4];
-1:
-#endif
+	ANOMALY_283_315_WORKAROUND(p4, r5)
 
 	/* Turn caches off, to ensure we don't get double exceptions */
 
@@ -1123,9 +1136,7 @@ ENTRY(_early_trap)
 
 	R5 = [P4];              /* Control Register*/
 	BITCLR(R5,ENICPLB_P);
-	CLI R1;
-	SSYNC;          /* SSYNC required before writing to IMEM_CONTROL. */
-	.align 8;
+	CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
 	[P4] = R5;
 	SSYNC;
 
@@ -1133,11 +1144,9 @@ ENTRY(_early_trap)
 	P4.H = HI(DMEM_CONTROL);
 	R5 = [P4];
 	BITCLR(R5,ENDCPLB_P);
-	SSYNC;          /* SSYNC required before writing to DMEM_CONTROL. */
-	.align 8;
+	CSYNC;          /* Disabling of CPLBs should be proceeded by a CSYNC */
 	[P4] = R5;
 	SSYNC;
-	STI R1;
 
 	r0 = sp;        /* stack frame pt_regs pointer argument ==> r0 */
 	r1 = RETX;
@@ -1611,7 +1620,7 @@ ENTRY(_sys_call_table)
 	.long _sys_preadv
 	.long _sys_pwritev
 	.long _sys_rt_tgsigqueueinfo
-	.long _sys_perf_counter_open
+	.long _sys_perf_event_open
 
 	.rept NR_syscalls-(.-_sys_call_table)/4
 	.long _sys_ni_syscall
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index f826f6b..9c79dfe 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -124,22 +124,22 @@ ENTRY(__start)
 	 * below
 	 */
 	GET_PDA(p0, r0);
-	r6 = [p0 + PDA_RETX];
+	r6 = [p0 + PDA_DF_RETX];
 	p1.l = _init_saved_retx;
 	p1.h = _init_saved_retx;
 	[p1] = r6;
 
-	r6 = [p0 + PDA_DCPLB];
+	r6 = [p0 + PDA_DF_DCPLB];
 	p1.l = _init_saved_dcplb_fault_addr;
 	p1.h = _init_saved_dcplb_fault_addr;
 	[p1] = r6;
 
-	r6 = [p0 + PDA_ICPLB];
+	r6 = [p0 + PDA_DF_ICPLB];
 	p1.l = _init_saved_icplb_fault_addr;
 	p1.h = _init_saved_icplb_fault_addr;
 	[p1] = r6;
 
-	r6 = [p0 + PDA_SEQSTAT];
+	r6 = [p0 + PDA_DF_SEQSTAT];
 	p1.l = _init_saved_seqstat;
 	p1.h = _init_saved_seqstat;
 	[p1] = r6;
@@ -153,6 +153,8 @@ ENTRY(__start)
 
 #ifdef CONFIG_EARLY_PRINTK
 	call _init_early_exception_vectors;
+	r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+	sti r0;
 #endif
 
 	r0 = 0 (x);
@@ -212,12 +214,21 @@ ENTRY(__start)
 	[p0] = p1;
 	csync;
 
+#ifdef CONFIG_EARLY_PRINTK
+	r0 = (EVT_IVG15 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU) (z);
+#else
 	r0 = EVT_IVG15 (z);
+#endif
 	sti r0;
 
 	raise 15;
+#ifdef CONFIG_EARLY_PRINTK
+	p0.l = _early_trap;
+	p0.h = _early_trap;
+#else
 	p0.l = .LWAIT_HERE;
 	p0.h = .LWAIT_HERE;
+#endif
 	reti = p0;
 #if ANOMALY_05000281
 	nop; nop; nop;
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 9c46680..82d417e 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -119,14 +119,8 @@ __common_int_entry:
 	fp = 0;
 #endif
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-	cc = r7 == r7;
-	p5.h = HI(CHIPID);
-	p5.l = LO(CHIPID);
-	if cc jump 1f;
-	r7.l = W[p5];
-1:
-#endif
+	ANOMALY_283_315_WORKAROUND(p5, r7)
+
 	r1 =  sp;
 	SP += -12;
 #ifdef CONFIG_IPIPE
@@ -158,14 +152,7 @@ ENTRY(_evt_ivhw)
 	fp = 0;
 #endif
 
-#if ANOMALY_05000283 || ANOMALY_05000315
-	cc = r7 == r7;
-	p5.h = HI(CHIPID);
-	p5.l = LO(CHIPID);
-	if cc jump 1f;
-	r7.l = W[p5];
-1:
-#endif
+	ANOMALY_283_315_WORKAROUND(p5, r7)
 
 	/* Handle all stacked hardware errors
 	 * To make sure we don't hang forever, only do it 10 times
@@ -261,6 +248,31 @@ ENTRY(_evt_system_call)
 ENDPROC(_evt_system_call)
 
 #ifdef CONFIG_IPIPE
+/*
+ * __ipipe_call_irqtail: lowers the current priority level to EVT15
+ * before running a user-defined routine, then raises the priority
+ * level to EVT14 to prepare the caller for a normal interrupt
+ * return through RTI.
+ *
+ * We currently use this facility in two occasions:
+ *
+ * - to branch to __ipipe_irq_tail_hook as requested by a high
+ *   priority domain after the pipeline delivered an interrupt,
+ *   e.g. such as Xenomai, in order to start its rescheduling
+ *   procedure, since we may not switch tasks when IRQ levels are
+ *   nested on the Blackfin, so we have to fake an interrupt return
+ *   so that we may reschedule immediately.
+ *
+ * - to branch to sync_root_irqs, in order to play any interrupt
+ *   pending for the root domain (i.e. the Linux kernel). This lowers
+ *   the core priority level enough so that Linux IRQ handlers may
+ *   never delay interrupts handled by high priority domains; we defer
+ *   those handlers until this point instead. This is a substitute
+ *   to using a threaded interrupt model for the Linux kernel.
+ *
+ * r0: address of user-defined routine
+ * context: caller must have preempted EVT15, hw interrupts must be off.
+ */
 ENTRY(___ipipe_call_irqtail)
 	p0 = r0;
 	r0.l = 1f;
@@ -276,33 +288,19 @@ ENTRY(___ipipe_call_irqtail)
 	( r7:4, p5:3 ) = [sp++];
 	rets = [sp++];
 
-	[--sp] = reti;
-	reti = [sp++];          /* IRQs are off. */
-	r0.h = 3f;
-	r0.l = 3f;
-	p0.l = lo(EVT14);
-	p0.h = hi(EVT14);
-	[p0] = r0;
-	csync;
-	r0 = 0x401f (z);
+#ifdef CONFIG_DEBUG_HWERR
+	/* enable irq14 & hwerr interrupt, until we transition to _evt_evt14 */
+	r0 = (EVT_IVG14 | EVT_IVHW | \
+		EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+#else
+	/* Only enable irq14 interrupt, until we transition to _evt_evt14 */
+	r0 = (EVT_IVG14 | \
+		EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
+#endif
 	sti r0;
-	raise 14;
-	[--sp] = reti;          /* IRQs on. */
+	raise 14;		/* Branches to _evt_evt14 */
 2:
 	jump 2b;                /* Likely paranoid. */
-3:
-	sp += 4;                /* Discard saved RETI */
-	r0.h = _evt14_softirq;
-	r0.l = _evt14_softirq;
-	p0.l = lo(EVT14);
-	p0.h = hi(EVT14);
-	[p0] = r0;
-	csync;
-	p0.l = _bfin_irq_flags;
-	p0.h = _bfin_irq_flags;
-	r0 = [p0];
-	sti r0;
-	rts;
 ENDPROC(___ipipe_call_irqtail)
 
 #endif /* CONFIG_IPIPE */
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index b421501..6ffda78 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -967,7 +967,7 @@ void __cpuinit init_exception_vectors(void)
 	bfin_write_EVT11(evt_evt11);
 	bfin_write_EVT12(evt_evt12);
 	bfin_write_EVT13(evt_evt13);
-	bfin_write_EVT14(evt14_softirq);
+	bfin_write_EVT14(evt_evt14);
 	bfin_write_EVT15(evt_system_call);
 	CSYNC();
 }
@@ -1052,18 +1052,26 @@ int __init init_arch_irq(void)
 			set_irq_chained_handler(irq, bfin_demux_error_irq);
 			break;
 #endif
+
 #ifdef CONFIG_SMP
+#ifdef CONFIG_TICKSOURCE_GPTMR0
+		case IRQ_TIMER0:
+#endif
+#ifdef CONFIG_TICKSOURCE_CORETMR
+		case IRQ_CORETMR:
+#endif
 		case IRQ_SUPPLE_0:
 		case IRQ_SUPPLE_1:
 			set_irq_handler(irq, handle_percpu_irq);
 			break;
 #endif
+
 #ifdef CONFIG_IPIPE
 #ifndef CONFIG_TICKSOURCE_CORETMR
 		case IRQ_TIMER0:
 			set_irq_handler(irq, handle_simple_irq);
 			break;
-#endif /* !CONFIG_TICKSOURCE_CORETMR */
+#endif
 		case IRQ_CORETMR:
 			set_irq_handler(irq, handle_simple_irq);
 			break;
@@ -1071,15 +1079,10 @@ int __init init_arch_irq(void)
 			set_irq_handler(irq, handle_level_irq);
 			break;
 #else /* !CONFIG_IPIPE */
-#ifdef CONFIG_TICKSOURCE_GPTMR0
-		case IRQ_TIMER0:
-			set_irq_handler(irq, handle_percpu_irq);
-			break;
-#endif /* CONFIG_TICKSOURCE_GPTMR0 */
 		default:
 			set_irq_handler(irq, handle_simple_irq);
 			break;
-#endif	/* !CONFIG_IPIPE */
+#endif /* !CONFIG_IPIPE */
 		}
 	}
 
diff --git a/arch/blackfin/mach-common/lock.S b/arch/blackfin/mach-common/lock.S
deleted file mode 100644
index 6c5f5f0..0000000
--- a/arch/blackfin/mach-common/lock.S
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * File:         arch/blackfin/mach-common/lock.S
- * Based on:
- * Author:       LG Soft India
- *
- * Created:      ?
- * Description:  kernel locks
- *
- * Modified:
- *               Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.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, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <linux/linkage.h>
-#include <asm/blackfin.h>
-
-.text
-
-/* When you come here, it is assumed that
- * R0 - Which way to be locked
- */
-
-ENTRY(_cache_grab_lock)
-
-	[--SP]=( R7:0,P5:0 );
-
-	P1.H = HI(IMEM_CONTROL);
-	P1.L = LO(IMEM_CONTROL);
-	P5.H = HI(ICPLB_ADDR0);
-	P5.L = LO(ICPLB_ADDR0);
-	P4.H = HI(ICPLB_DATA0);
-	P4.L = LO(ICPLB_DATA0);
-	R7 = R0;
-
-	/* If the code of interest already resides in the cache
-	 * invalidate the entire cache itself.
-	 * invalidate_entire_icache;
-	 */
-
-	SP += -12;
-	[--SP] = RETS;
-	CALL _invalidate_entire_icache;
-	RETS = [SP++];
-	SP += 12;
-
-	/* Disable the Interrupts*/
-
-	CLI R3;
-
-.LLOCK_WAY:
-
-	/* Way0 - 0xFFA133E0
-	 * Way1 - 0xFFA137E0
-	 * Way2 - 0xFFA13BE0	Total Way Size = 4K
-	 * Way3 - 0xFFA13FE0
-	 */
-
-	/* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1]
-	 * Only Way0 of the instruction cache can now be
-	 * replaced by a new code
-	 */
-
-	R5 = R7;
-	CC = BITTST(R7,0);
-	IF CC JUMP .LCLEAR1;
-	R7 = 0;
-	BITSET(R7,0);
-	JUMP .LDONE1;
-
-.LCLEAR1:
-	R7 = 0;
-	BITCLR(R7,0);
-.LDONE1:	R4 = R7 << 3;
-	R7 = [P1];
-	R7 = R7 | R4;
-	SSYNC;		/* SSYNC required writing to IMEM_CONTROL. */
-	.align 8;
-	[P1] = R7;
-	SSYNC;
-
-	R7 = R5;
-	CC = BITTST(R7,1);
-	IF CC JUMP .LCLEAR2;
-	R7 = 0;
-	BITSET(R7,1);
-	JUMP .LDONE2;
-
-.LCLEAR2:
-	R7 = 0;
-	BITCLR(R7,1);
-.LDONE2:	R4 = R7 << 3;
-	R7 = [P1];
-	R7 = R7 | R4;
-	SSYNC;		/* SSYNC required writing to IMEM_CONTROL. */
-	.align 8;
-	[P1] = R7;
-	SSYNC;
-
-	R7 = R5;
-	CC = BITTST(R7,2);
-	IF CC JUMP .LCLEAR3;
-	R7 = 0;
-	BITSET(R7,2);
-	JUMP .LDONE3;
-.LCLEAR3:
-	R7 = 0;
-	BITCLR(R7,2);
-.LDONE3:	R4 = R7 << 3;
-	R7 = [P1];
-	R7 = R7 | R4;
-	SSYNC;		/* SSYNC required writing to IMEM_CONTROL. */
-	.align 8;
-	[P1] = R7;
-	SSYNC;
-
-
-	R7 = R5;
-	CC = BITTST(R7,3);
-	IF CC JUMP .LCLEAR4;
-	R7 = 0;
-	BITSET(R7,3);
-	JUMP .LDONE4;
-.LCLEAR4:
-	R7 = 0;
-	BITCLR(R7,3);
-.LDONE4:	R4 = R7 << 3;
-	R7 = [P1];
-	R7 = R7 | R4;
-	SSYNC;		/* SSYNC required writing to IMEM_CONTROL. */
-	.align 8;
-	[P1] = R7;
-	SSYNC;
-
-	STI R3;
-
-	( R7:0,P5:0 ) = [SP++];
-
-	RTS;
-ENDPROC(_cache_grab_lock)
-
-/* After the execution of critical code, the code is now locked into
- * the cache way. Now we need to set ILOC.
- *
- * R0 - Which way to be locked
- */
-
-ENTRY(_bfin_cache_lock)
-
-	[--SP]=( R7:0,P5:0 );
-
-	P1.H = HI(IMEM_CONTROL);
-	P1.L = LO(IMEM_CONTROL);
-
-	/* Disable the Interrupts*/
-	CLI R3;
-
-	R7 = [P1];
-	R2 = ~(0x78) (X);	/* mask out ILOC */
-	R7 = R7 & R2;
-	R0 = R0 << 3;
-	R7 = R0 | R7;
-	SSYNC;		/* SSYNC required writing to IMEM_CONTROL. */
-	.align 8;
-	[P1] = R7;
-	SSYNC;
-	/* Renable the Interrupts */
-	STI R3;
-
-	( R7:0,P5:0 ) = [SP++];
-	RTS;
-ENDPROC(_bfin_cache_lock)
-
-/* Invalidate the Entire Instruction cache by
- * disabling IMC bit
- */
-ENTRY(_invalidate_entire_icache)
-	[--SP] = ( R7:5);
-
-	P0.L = LO(IMEM_CONTROL);
-	P0.H = HI(IMEM_CONTROL);
-	R7 = [P0];
-
-	/* Clear the IMC bit , All valid bits in the instruction
-	 * cache are set to the invalid state
-	 */
-	BITCLR(R7,IMC_P);
-	CLI R6;
-	SSYNC;		/* SSYNC required before invalidating cache. */
-	.align 8;
-	[P0] = R7;
-	SSYNC;
-	STI R6;
-
-	/* Configures the instruction cache agian */
-	R6 = (IMC | ENICPLB);
-	R7 = R7 | R6;
-
-	CLI R6;
-	SSYNC;		/* SSYNC required before writing to IMEM_CONTROL. */
-	.align 8;
-	[P0] = R7;
-	SSYNC;
-	STI R6;
-
-	( R7:5) = [SP++];
-	RTS;
-ENDPROC(_invalidate_entire_icache)
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 9e7e27b..0e3d4ff 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -38,6 +38,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 
+#include <asm/cplb.h>
 #include <asm/gpio.h>
 #include <asm/dma.h>
 #include <asm/dpmc.h>
@@ -170,58 +171,6 @@ static void flushinv_all_dcache(void)
 }
 #endif
 
-static inline void dcache_disable(void)
-{
-#ifdef CONFIG_BFIN_DCACHE
-	unsigned long ctrl;
-
-#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
-	flushinv_all_dcache();
-#endif
-	SSYNC();
-	ctrl = bfin_read_DMEM_CONTROL();
-	ctrl &= ~ENDCPLB;
-	bfin_write_DMEM_CONTROL(ctrl);
-	SSYNC();
-#endif
-}
-
-static inline void dcache_enable(void)
-{
-#ifdef CONFIG_BFIN_DCACHE
-	unsigned long ctrl;
-	SSYNC();
-	ctrl = bfin_read_DMEM_CONTROL();
-	ctrl |= ENDCPLB;
-	bfin_write_DMEM_CONTROL(ctrl);
-	SSYNC();
-#endif
-}
-
-static inline void icache_disable(void)
-{
-#ifdef CONFIG_BFIN_ICACHE
-	unsigned long ctrl;
-	SSYNC();
-	ctrl = bfin_read_IMEM_CONTROL();
-	ctrl &= ~ENICPLB;
-	bfin_write_IMEM_CONTROL(ctrl);
-	SSYNC();
-#endif
-}
-
-static inline void icache_enable(void)
-{
-#ifdef CONFIG_BFIN_ICACHE
-	unsigned long ctrl;
-	SSYNC();
-	ctrl = bfin_read_IMEM_CONTROL();
-	ctrl |= ENICPLB;
-	bfin_write_IMEM_CONTROL(ctrl);
-	SSYNC();
-#endif
-}
-
 int bfin_pm_suspend_mem_enter(void)
 {
 	unsigned long flags;
@@ -258,16 +207,19 @@ int bfin_pm_suspend_mem_enter(void)
 
 	bfin_gpio_pm_hibernate_suspend();
 
-	dcache_disable();
-	icache_disable();
+#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
+	flushinv_all_dcache();
+#endif
+	_disable_dcplb();
+	_disable_icplb();
 	bf53x_suspend_l1_mem(memptr);
 
 	do_hibernate(wakeup | vr_wakeup);	/* Goodbye */
 
 	bf53x_resume_l1_mem(memptr);
 
-	icache_enable();
-	dcache_enable();
+	_enable_icplb();
+	_enable_dcplb();
 
 	bfin_gpio_pm_hibernate_restore();
 	blackfin_dma_resume();
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index 68bd0bd..b88ce7f 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -33,6 +33,7 @@
 #include <asm/bfin-global.h>
 #include <asm/pda.h>
 #include <asm/cplbinit.h>
+#include <asm/early_printk.h>
 #include "blackfin_sram.h"
 
 /*
@@ -113,6 +114,8 @@ asmlinkage void __init init_pda(void)
 {
 	unsigned int cpu = raw_smp_processor_id();
 
+	early_shadow_stamp();
+
 	/* Initialize the PDA fields holding references to other parts
 	   of the memory. The content of such memory is still
 	   undefined at the time of the call, we are only setting up
diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c
index c080e70..beb1a60 100644
--- a/arch/blackfin/mm/isram-driver.c
+++ b/arch/blackfin/mm/isram-driver.c
@@ -16,6 +16,8 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#define pr_fmt(fmt) "isram: " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -23,6 +25,7 @@
 #include <linux/sched.h>
 
 #include <asm/blackfin.h>
+#include <asm/dma.h>
 
 /*
  * IMPORTANT WARNING ABOUT THESE FUNCTIONS
@@ -50,10 +53,12 @@ static DEFINE_SPINLOCK(dtest_lock);
 #define IADDR2DTEST(x) \
 	({ unsigned long __addr = (unsigned long)(x); \
 		(__addr & 0x47F8)        | /* address bits 14 & 10:3 */ \
+		(__addr & 0x8000) << 23  | /* Bank A/B               */ \
 		(__addr & 0x0800) << 15  | /* address bit  11        */ \
-		(__addr  & 0x3000) << 4  | /* address bits 13:12     */ \
-		(__addr  & 0x8000) << 8  | /* address bit  15        */ \
-		(0x1000004);               /* isram access           */ \
+		(__addr & 0x3000) <<  4  | /* address bits 13:12     */ \
+		(__addr & 0x8000) <<  8  | /* address bit  15        */ \
+		(0x1000000)              | /* instruction access = 1 */ \
+		(0x4);                     /* data array = 1         */ \
 	})
 
 /* Takes a pointer, and returns the offset (in bits) which things should be shifted */
@@ -70,7 +75,7 @@ static void isram_write(const void *addr, uint64_t data)
 	if (addr >= (void *)(L1_CODE_START + L1_CODE_LENGTH))
 		return;
 
-	cmd = IADDR2DTEST(addr) | 1;             /* write */
+	cmd = IADDR2DTEST(addr) | 2;             /* write */
 
 	/*
 	 * Writes to DTEST_DATA[0:1] need to be atomic with write to DTEST_COMMAND
@@ -127,8 +132,7 @@ static bool isram_check_addr(const void *addr, size_t n)
 	    (addr < (void *)(L1_CODE_START + L1_CODE_LENGTH))) {
 		if ((addr + n) > (void *)(L1_CODE_START + L1_CODE_LENGTH)) {
 			show_stack(NULL, NULL);
-			printk(KERN_ERR "isram_memcpy: copy involving %p length "
-					"(%zu) too long\n", addr, n);
+			pr_err("copy involving %p length (%zu) too long\n", addr, n);
 		}
 		return true;
 	}
@@ -199,3 +203,209 @@ void *isram_memcpy(void *dest, const void *src, size_t n)
 }
 EXPORT_SYMBOL(isram_memcpy);
 
+#ifdef CONFIG_BFIN_ISRAM_SELF_TEST
+
+#define TEST_LEN 0x100
+
+static __init void hex_dump(unsigned char *buf, int len)
+{
+	while (len--)
+		pr_cont("%02x", *buf++);
+}
+
+static __init int isram_read_test(char *sdram, void *l1inst)
+{
+	int i, ret = 0;
+	uint64_t data1, data2;
+
+	pr_info("INFO: running isram_read tests\n");
+
+	/* setup some different data to play with */
+	for (i = 0; i < TEST_LEN; ++i)
+		sdram[i] = i;
+	dma_memcpy(l1inst, sdram, TEST_LEN);
+
+	/* make sure we can read the L1 inst */
+	for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) {
+		data1 = isram_read(l1inst + i);
+		memcpy(&data2, sdram + i, sizeof(data2));
+		if (memcmp(&data1, &data2, sizeof(uint64_t))) {
+			pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n",
+				l1inst + i, data1, data2);
+			++ret;
+		}
+	}
+
+	return ret;
+}
+
+static __init int isram_write_test(char *sdram, void *l1inst)
+{
+	int i, ret = 0;
+	uint64_t data1, data2;
+
+	pr_info("INFO: running isram_write tests\n");
+
+	/* setup some different data to play with */
+	memset(sdram, 0, TEST_LEN * 2);
+	dma_memcpy(l1inst, sdram, TEST_LEN);
+	for (i = 0; i < TEST_LEN; ++i)
+		sdram[i] = i;
+
+	/* make sure we can write the L1 inst */
+	for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) {
+		memcpy(&data1, sdram + i, sizeof(data1));
+		isram_write(l1inst + i, data1);
+		data2 = isram_read(l1inst + i);
+		if (memcmp(&data1, &data2, sizeof(uint64_t))) {
+			pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n",
+				l1inst + i, data1, data2);
+			++ret;
+		}
+	}
+
+	dma_memcpy(sdram + TEST_LEN, l1inst, TEST_LEN);
+	if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) {
+		pr_err("FAIL: isram_write() did not work properly\n");
+		++ret;
+	}
+
+	return ret;
+}
+
+static __init int
+_isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy,
+                   void *(*fmemcpy)(void *, const void *, size_t))
+{
+	memset(sdram, pattern, TEST_LEN);
+	fmemcpy(l1inst, sdram, TEST_LEN);
+	fmemcpy(sdram + TEST_LEN, l1inst, TEST_LEN);
+	if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) {
+		pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n",
+			smemcpy, l1inst, sdram, TEST_LEN, pattern);
+		return 1;
+	}
+	return 0;
+}
+#define _isram_memcpy_test(a, b, c, d) _isram_memcpy_test(a, b, c, #d, d)
+
+static __init int isram_memcpy_test(char *sdram, void *l1inst)
+{
+	int i, j, thisret, ret = 0;
+
+	/* check broad isram_memcpy() */
+	pr_info("INFO: running broad isram_memcpy tests\n");
+	for (i = 0xf; i >= 0; --i)
+		ret += _isram_memcpy_test(i, sdram, l1inst, isram_memcpy);
+
+	/* check read of small, unaligned, and hardware 64bit limits */
+	pr_info("INFO: running isram_memcpy (read) tests\n");
+
+	for (i = 0; i < TEST_LEN; ++i)
+		sdram[i] = i;
+	dma_memcpy(l1inst, sdram, TEST_LEN);
+
+	thisret = 0;
+	for (i = 0; i < TEST_LEN - 32; ++i) {
+		unsigned char cmp[32];
+		for (j = 1; j <= 32; ++j) {
+			memset(cmp, 0, sizeof(cmp));
+			isram_memcpy(cmp, l1inst + i, j);
+			if (memcmp(cmp, sdram + i, j)) {
+				pr_err("FAIL: %p:", l1inst + 1);
+				hex_dump(cmp, j);
+				pr_cont(" SDRAM:");
+				hex_dump(sdram + i, j);
+				pr_cont("\n");
+				if (++thisret > 20) {
+					pr_err("FAIL: skipping remaining series\n");
+					i = TEST_LEN;
+					break;
+				}
+			}
+		}
+	}
+	ret += thisret;
+
+	/* check write of small, unaligned, and hardware 64bit limits */
+	pr_info("INFO: running isram_memcpy (write) tests\n");
+
+	memset(sdram + TEST_LEN, 0, TEST_LEN);
+	dma_memcpy(l1inst, sdram + TEST_LEN, TEST_LEN);
+
+	thisret = 0;
+	for (i = 0; i < TEST_LEN - 32; ++i) {
+		unsigned char cmp[32];
+		for (j = 1; j <= 32; ++j) {
+			isram_memcpy(l1inst + i, sdram + i, j);
+			dma_memcpy(cmp, l1inst + i, j);
+			if (memcmp(cmp, sdram + i, j)) {
+				pr_err("FAIL: %p:", l1inst + i);
+				hex_dump(cmp, j);
+				pr_cont(" SDRAM:");
+				hex_dump(sdram + i, j);
+				pr_cont("\n");
+				if (++thisret > 20) {
+					pr_err("FAIL: skipping remaining series\n");
+					i = TEST_LEN;
+					break;
+				}
+			}
+		}
+	}
+	ret += thisret;
+
+	return ret;
+}
+
+static __init int isram_test_init(void)
+{
+	int ret;
+	char *sdram;
+	void *l1inst;
+
+	sdram = kmalloc(TEST_LEN * 2, GFP_KERNEL);
+	if (!sdram) {
+		pr_warning("SKIP: could not allocate sdram\n");
+		return 0;
+	}
+
+	l1inst = l1_inst_sram_alloc(TEST_LEN);
+	if (!l1inst) {
+		kfree(sdram);
+		pr_warning("SKIP: could not allocate L1 inst\n");
+		return 0;
+	}
+
+	/* sanity check initial L1 inst state */
+	ret = 1;
+	pr_info("INFO: running initial dma_memcpy checks\n");
+	if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy))
+		goto abort;
+	if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy))
+		goto abort;
+
+	ret = 0;
+	ret += isram_read_test(sdram, l1inst);
+	ret += isram_write_test(sdram, l1inst);
+	ret += isram_memcpy_test(sdram, l1inst);
+
+ abort:
+	sram_free(l1inst);
+	kfree(sdram);
+
+	if (ret)
+		return -EIO;
+
+	pr_info("PASS: all tests worked !\n");
+	return 0;
+}
+late_initcall(isram_test_init);
+
+static __exit void isram_test_exit(void)
+{
+	/* stub to allow unloading */
+}
+module_exit(isram_test_exit);
+
+#endif
diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c
index 0bc3c4e..eb63ab3 100644
--- a/arch/blackfin/mm/sram-alloc.c
+++ b/arch/blackfin/mm/sram-alloc.c
@@ -42,11 +42,6 @@
 #include <asm/mem_map.h>
 #include "blackfin_sram.h"
 
-static DEFINE_PER_CPU(spinlock_t, l1sram_lock) ____cacheline_aligned_in_smp;
-static DEFINE_PER_CPU(spinlock_t, l1_data_sram_lock) ____cacheline_aligned_in_smp;
-static DEFINE_PER_CPU(spinlock_t, l1_inst_sram_lock) ____cacheline_aligned_in_smp;
-static spinlock_t l2_sram_lock ____cacheline_aligned_in_smp;
-
 /* the data structure for L1 scratchpad and DATA SRAM */
 struct sram_piece {
 	void *paddr;
@@ -55,6 +50,7 @@ struct sram_piece {
 	struct sram_piece *next;
 };
 
+static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1sram_lock);
 static DEFINE_PER_CPU(struct sram_piece, free_l1_ssram_head);
 static DEFINE_PER_CPU(struct sram_piece, used_l1_ssram_head);
 
@@ -68,12 +64,18 @@ static DEFINE_PER_CPU(struct sram_piece, free_l1_data_B_sram_head);
 static DEFINE_PER_CPU(struct sram_piece, used_l1_data_B_sram_head);
 #endif
 
+#if L1_DATA_A_LENGTH || L1_DATA_B_LENGTH
+static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_data_sram_lock);
+#endif
+
 #if L1_CODE_LENGTH != 0
+static DEFINE_PER_CPU_SHARED_ALIGNED(spinlock_t, l1_inst_sram_lock);
 static DEFINE_PER_CPU(struct sram_piece, free_l1_inst_sram_head);
 static DEFINE_PER_CPU(struct sram_piece, used_l1_inst_sram_head);
 #endif
 
 #if L2_LENGTH != 0
+static spinlock_t l2_sram_lock ____cacheline_aligned_in_smp;
 static struct sram_piece free_l2_sram_head, used_l2_sram_head;
 #endif
 
@@ -225,10 +227,10 @@ static void __init l2_sram_init(void)
 	printk(KERN_INFO "Blackfin L2 SRAM: %d KB (%d KB free)\n",
 		L2_LENGTH >> 10,
 		free_l2_sram_head.next->size >> 10);
-#endif
 
 	/* mutex initialize */
 	spin_lock_init(&l2_sram_lock);
+#endif
 }
 
 static int __init bfin_sram_init(void)
@@ -416,18 +418,17 @@ EXPORT_SYMBOL(sram_free);
 
 void *l1_data_A_sram_alloc(size_t size)
 {
+#if L1_DATA_A_LENGTH != 0
 	unsigned long flags;
-	void *addr = NULL;
+	void *addr;
 	unsigned int cpu;
 
 	cpu = get_cpu();
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
-#if L1_DATA_A_LENGTH != 0
 	addr = _sram_alloc(size, &per_cpu(free_l1_data_A_sram_head, cpu),
 			&per_cpu(used_l1_data_A_sram_head, cpu));
-#endif
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
@@ -437,11 +438,15 @@ void *l1_data_A_sram_alloc(size_t size)
 		 (long unsigned int)addr, size);
 
 	return addr;
+#else
+	return NULL;
+#endif
 }
 EXPORT_SYMBOL(l1_data_A_sram_alloc);
 
 int l1_data_A_sram_free(const void *addr)
 {
+#if L1_DATA_A_LENGTH != 0
 	unsigned long flags;
 	int ret;
 	unsigned int cpu;
@@ -450,18 +455,17 @@ int l1_data_A_sram_free(const void *addr)
 	/* add mutex operation */
 	spin_lock_irqsave(&per_cpu(l1_data_sram_lock, cpu), flags);
 
-#if L1_DATA_A_LENGTH != 0
 	ret = _sram_free(addr, &per_cpu(free_l1_data_A_sram_head, cpu),
 			&per_cpu(used_l1_data_A_sram_head, cpu));
-#else
-	ret = -1;
-#endif
 
 	/* add mutex operation */
 	spin_unlock_irqrestore(&per_cpu(l1_data_sram_lock, cpu), flags);
 	put_cpu();
 
 	return ret;
+#else
+	return -1;
+#endif
 }
 EXPORT_SYMBOL(l1_data_A_sram_free);
 
diff --git a/arch/cris/include/asm/mmu_context.h b/arch/cris/include/asm/mmu_context.h
index 72ba08d..1d45fd6 100644
--- a/arch/cris/include/asm/mmu_context.h
+++ b/arch/cris/include/asm/mmu_context.h
@@ -17,7 +17,8 @@ extern void switch_mm(struct mm_struct *prev, struct mm_struct *next,
  * registers like cr3 on the i386
  */
 
-extern volatile DEFINE_PER_CPU(pgd_t *,current_pgd); /* defined in arch/cris/mm/fault.c */
+/* defined in arch/cris/mm/fault.c */
+DECLARE_PER_CPU(pgd_t *, current_pgd);
 
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 {
diff --git a/arch/cris/include/asm/socket.h b/arch/cris/include/asm/socket.h
index d5cf740..45ec49b 100644
--- a/arch/cris/include/asm/socket.h
+++ b/arch/cris/include/asm/socket.h
@@ -59,6 +59,9 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_SOCKET_H */
 
 
diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S
index 0d2adfc..6c81836 100644
--- a/arch/cris/kernel/vmlinux.lds.S
+++ b/arch/cris/kernel/vmlinux.lds.S
@@ -140,12 +140,7 @@ SECTIONS
 	_end = .;
 	__end = .;
 
-	/* Sections to be discarded */
-	/DISCARD/ : {
-		EXIT_TEXT
-		EXIT_DATA
-		*(.exitcall.exit)
-        }
-
 	dram_end = dram_start + (CONFIG_ETRAX_DRAM_SIZE - __CONFIG_ETRAX_VMEM_SIZE)*1024*1024;
+
+	DISCARDS
 }
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index f925115..4a7cdd9 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -29,7 +29,7 @@ extern void die_if_kernel(const char *, struct pt_regs *, long);
 
 /* current active page directory */
 
-volatile DEFINE_PER_CPU(pgd_t *,current_pgd);
+DEFINE_PER_CPU(pgd_t *, current_pgd);
 unsigned long cris_signal_return_page;
 
 /*
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index b86e19c..4b5830b 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -7,7 +7,7 @@ config FRV
 	default y
 	select HAVE_IDE
 	select HAVE_ARCH_TRACEHOOK
-	select HAVE_PERF_COUNTERS
+	select HAVE_PERF_EVENTS
 
 config ZONE_DMA
 	bool
diff --git a/arch/frv/include/asm/perf_counter.h b/arch/frv/include/asm/perf_counter.h
deleted file mode 100644
index ccf726e..0000000
--- a/arch/frv/include/asm/perf_counter.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* FRV performance counter support
- *
- * Copyright (C) 2009 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 _ASM_PERF_COUNTER_H
-#define _ASM_PERF_COUNTER_H
-
-#define PERF_COUNTER_INDEX_OFFSET	0
-
-#endif /* _ASM_PERF_COUNTER_H */
diff --git a/arch/frv/include/asm/perf_event.h b/arch/frv/include/asm/perf_event.h
new file mode 100644
index 0000000..a69e015
--- /dev/null
+++ b/arch/frv/include/asm/perf_event.h
@@ -0,0 +1,17 @@
+/* FRV performance event support
+ *
+ * Copyright (C) 2009 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 _ASM_PERF_EVENT_H
+#define _ASM_PERF_EVENT_H
+
+#define PERF_EVENT_INDEX_OFFSET	0
+
+#endif /* _ASM_PERF_EVENT_H */
diff --git a/arch/frv/include/asm/socket.h b/arch/frv/include/asm/socket.h
index 57c3d40..2dea726 100644
--- a/arch/frv/include/asm/socket.h
+++ b/arch/frv/include/asm/socket.h
@@ -57,5 +57,8 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_SOCKET_H */
 
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
index 4a8fb42..be6ef0f 100644
--- a/arch/frv/include/asm/unistd.h
+++ b/arch/frv/include/asm/unistd.h
@@ -342,7 +342,7 @@
 #define __NR_preadv		333
 #define __NR_pwritev		334
 #define __NR_rt_tgsigqueueinfo	335
-#define __NR_perf_counter_open	336
+#define __NR_perf_event_open	336
 
 #ifdef __KERNEL__
 
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index fde1e44..189397e 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1525,6 +1525,6 @@ sys_call_table:
 	.long sys_preadv
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo	/* 335 */
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
 
 syscall_table_size = (. - sys_call_table)
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index 22d9787..cbe811f 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -35,50 +35,13 @@ SECTIONS
 #endif
   }
   _einittext = .;
-  .init.data : { INIT_DATA }
-
-  . = ALIGN(8);
-  __setup_start = .;
-  .setup.init : { KEEP(*(.init.setup)) }
-  __setup_end = .;
-
-  __initcall_start = .;
-  .initcall.init : {
-	INITCALLS
-  }
-  __initcall_end = .;
-  __con_initcall_start = .;
-  .con_initcall.init : { *(.con_initcall.init) }
-  __con_initcall_end = .;
-  SECURITY_INIT
-  . = ALIGN(4);
-  __alt_instructions = .;
-  .altinstructions : { *(.altinstructions) }
-  __alt_instructions_end = .;
- .altinstr_replacement : { *(.altinstr_replacement) }
 
+  INIT_DATA_SECTION(8)
   PERCPU(4096)
 
-#ifdef CONFIG_BLK_DEV_INITRD
-  . = ALIGN(4096);
-  __initramfs_start = .;
-  .init.ramfs : { *(.init.ramfs) }
-  __initramfs_end = .;
-#endif
-
-  . = ALIGN(THREAD_SIZE);
+  . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
-  /* put sections together that have massive alignment issues */
-  . = ALIGN(THREAD_SIZE);
-  .data.init_task : {
-	  /* init task record & stack */
-	  *(.data.init_task)
-  }
-
-  . = ALIGN(L1_CACHE_BYTES);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-
   .trap : {
 	/* trap table management - read entry-table.S before modifying */
 	. = ALIGN(8192);
@@ -124,13 +87,12 @@ SECTIONS
 
 	}
 
-  . = ALIGN(8);		/* Exception table */
-  __start___ex_table = .;
-  __ex_table : { KEEP(*(__ex_table)) }
-  __stop___ex_table = .;
+  EXCEPTION_TABLE(8)
 
   _sdata = .;
   .data : {			/* Data */
+	INIT_TASK_DATA(THREAD_SIZE)
+	CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
 	DATA_DATA
 	*(.data.*)
 	EXIT_DATA
@@ -159,24 +121,12 @@ SECTIONS
   . = ALIGN(PAGE_SIZE);
   __kernel_image_end = .;
 
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-
-  .debug_line		0 : { *(.debug_line) }
-  .debug_info		0 : { *(.debug_info) }
-  .debug_abbrev		0 : { *(.debug_abbrev) }
-  .debug_aranges	0 : { *(.debug_aranges) }
-  .debug_frame		0 : { *(.debug_frame) }
-  .debug_pubnames	0 : { *(.debug_pubnames) }
-  .debug_str		0 : { *(.debug_str) }
-  .debug_ranges		0 : { *(.debug_ranges) }
+  STABS_DEBUG
+  DWARF_DEBUG
 
   .comment 0 : { *(.comment) }
+
+  DISCARDS
 }
 
 __kernel_image_size_no_bss = __bss_start - __kernel_image_start;
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index 0a37721..f470975 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -5,4 +5,4 @@
 lib-y := \
 	__ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
 	checksum.o memcpy.o memset.o atomic-ops.o atomic64-ops.o \
-	outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o perf_counter.o
+	outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o perf_event.o
diff --git a/arch/frv/lib/perf_counter.c b/arch/frv/lib/perf_counter.c
deleted file mode 100644
index 2000fee..0000000
--- a/arch/frv/lib/perf_counter.c
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Performance counter handling
- *
- * Copyright (C) 2009 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/perf_counter.h>
-
-/*
- * mark the performance counter as pending
- */
-void set_perf_counter_pending(void)
-{
-}
diff --git a/arch/frv/lib/perf_event.c b/arch/frv/lib/perf_event.c
new file mode 100644
index 0000000..9ac5acf
--- /dev/null
+++ b/arch/frv/lib/perf_event.c
@@ -0,0 +1,19 @@
+/* Performance event handling
+ *
+ * Copyright (C) 2009 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/perf_event.h>
+
+/*
+ * mark the performance event as pending
+ */
+void set_perf_event_pending(void)
+{
+}
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index 43d6753..566bdeb 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -86,7 +86,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
 	struct pci_bus *bus;
 	struct pci_dev *dev;
 	int idx;
-	struct resource *r, *pr;
+	struct resource *r;
 
 	/* Depth-First Search on bus tree */
 	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
@@ -96,8 +96,7 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
 				r = &dev->resource[idx];
 				if (!r->start)
 					continue;
-				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0)
+				if (pci_claim_resource(dev, idx) < 0)
 					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
 			}
 		}
@@ -110,7 +109,7 @@ static void __init pcibios_allocate_resources(int pass)
 	struct pci_dev *dev = NULL;
 	int idx, disabled;
 	u16 command;
-	struct resource *r, *pr;
+	struct resource *r;
 
 	for_each_pci_dev(dev) {
 		pci_read_config_word(dev, PCI_COMMAND, &command);
@@ -127,8 +126,7 @@ static void __init pcibios_allocate_resources(int pass)
 			if (pass == disabled) {
 				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
 				    r->start, r->end, r->flags, disabled, pass);
-				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0) {
+				if (pci_claim_resource(dev, idx) < 0) {
 					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev));
 					/* We'll assign a new address later */
 					r->end -= r->start;
diff --git a/arch/h8300/include/asm/pci.h b/arch/h8300/include/asm/pci.h
index 97389b3..cc97620 100644
--- a/arch/h8300/include/asm/pci.h
+++ b/arch/h8300/include/asm/pci.h
@@ -8,7 +8,6 @@
  */
 
 #define pcibios_assign_all_busses()	0
-#define pcibios_scan_all_fns(a, b)	0
 
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
diff --git a/arch/h8300/include/asm/socket.h b/arch/h8300/include/asm/socket.h
index 602518a..1547f01 100644
--- a/arch/h8300/include/asm/socket.h
+++ b/arch/h8300/include/asm/socket.h
@@ -57,4 +57,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 43a87b9..662b02e 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -152,9 +152,6 @@ SECTIONS
 	__end = . ;
 	__ramstart = .;
 	}
-	/DISCARD/ : {
-		*(.exitcall.exit)
-	}
         .romfs :	
 	{
 		*(.romfs*)
@@ -165,4 +162,6 @@ SECTIONS
 	COMMAND_START = . - 0x200 ;
 	__ramend = . ;
 	}
+
+	DISCARDS
 }
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 170042b..011a1cd 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -89,6 +89,9 @@ config GENERIC_TIME_VSYSCALL
 	bool
 	default y
 
+config HAVE_LEGACY_PER_CPU_AREA
+	def_bool y
+
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
@@ -112,6 +115,10 @@ config IA64_UNCACHED_ALLOCATOR
 	bool
 	select GENERIC_ALLOCATOR
 
+config ARCH_USES_PG_UNCACHED
+	def_bool y
+	depends on IA64_UNCACHED_ALLOCATOR
+
 config AUDIT_ARCH
 	bool
 	default y
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index e4d8fde..7e81966 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -412,7 +412,7 @@ simeth_tx(struct sk_buff *skb, struct net_device *dev)
 	 */
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static inline struct sk_buff *
diff --git a/arch/ia64/include/asm/agp.h b/arch/ia64/include/asm/agp.h
index c11fdd8..01d09c4 100644
--- a/arch/ia64/include/asm/agp.h
+++ b/arch/ia64/include/asm/agp.h
@@ -17,10 +17,6 @@
 #define unmap_page_from_agp(page)	/* nothing */
 #define flush_agp_cache()		mb()
 
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
 #define alloc_gatt_pages(order)		\
 	((char *)__get_free_pages(GFP_KERNEL, (order)))
diff --git a/arch/ia64/include/asm/device.h b/arch/ia64/include/asm/device.h
index 41ab85d..d66d446 100644
--- a/arch/ia64/include/asm/device.h
+++ b/arch/ia64/include/asm/device.h
@@ -15,4 +15,7 @@ struct dev_archdata {
 #endif
 };
 
+struct pdev_archdata {
+};
+
 #endif /* _ASM_IA64_DEVICE_H */
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 5f43697..d9b6325 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -235,7 +235,8 @@ struct kvm_vm_data {
 #define KVM_REQ_PTC_G		32
 #define KVM_REQ_RESUME		33
 
-#define KVM_PAGES_PER_HPAGE	1
+#define KVM_NR_PAGE_SIZES	1
+#define KVM_PAGES_PER_HPAGE(x)	1
 
 struct kvm;
 struct kvm_vcpu;
@@ -465,7 +466,6 @@ struct kvm_arch {
 	unsigned long	metaphysical_rr4;
 	unsigned long	vmm_init_rr;
 
-	int		online_vcpus;
 	int		is_sn2;
 
 	struct kvm_ioapic *vioapic;
diff --git a/arch/ia64/include/asm/kvm_para.h b/arch/ia64/include/asm/kvm_para.h
index 0d6d8ca..1588aee 100644
--- a/arch/ia64/include/asm/kvm_para.h
+++ b/arch/ia64/include/asm/kvm_para.h
@@ -19,9 +19,13 @@
  *
  */
 
+#ifdef __KERNEL__
+
 static inline unsigned int kvm_arch_para_features(void)
 {
 	return 0;
 }
 
 #endif
+
+#endif
diff --git a/arch/ia64/include/asm/mca.h b/arch/ia64/include/asm/mca.h
index 44a0b53..c171cdf 100644
--- a/arch/ia64/include/asm/mca.h
+++ b/arch/ia64/include/asm/mca.h
@@ -145,12 +145,14 @@ extern void ia64_mca_ucmc_handler(struct pt_regs *, struct ia64_sal_os_state *);
 extern void ia64_init_handler(struct pt_regs *,
 			      struct switch_stack *,
 			      struct ia64_sal_os_state *);
+extern void ia64_os_init_on_kdump(void);
 extern void ia64_monarch_init_handler(void);
 extern void ia64_slave_init_handler(void);
 extern void ia64_mca_cmc_vector_setup(void);
 extern int  ia64_reg_MCA_extension(int (*fn)(void *, struct ia64_sal_os_state *));
 extern void ia64_unreg_MCA_extension(void);
 extern unsigned long ia64_get_rnat(unsigned long *);
+extern void ia64_set_psr_mc(void);
 extern void ia64_mca_printk(const char * fmt, ...)
 	 __attribute__ ((format (printf, 1, 2)));
 
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index fcfca56..55281aa 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -17,7 +17,6 @@
  * loader.
  */
 #define pcibios_assign_all_busses()     0
-#define pcibios_scan_all_fns(a, b)	0
 
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
@@ -135,7 +134,18 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev,
 extern void pcibios_bus_to_resource(struct pci_dev *dev,
 		struct resource *res, struct pci_bus_region *region);
 
-#define pcibios_scan_all_fns(a, b)	0
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+	struct resource *root = NULL;
+
+	if (res->flags & IORESOURCE_IO)
+		root = &ioport_resource;
+	if (res->flags & IORESOURCE_MEM)
+		root = &iomem_resource;
+
+	return root;
+}
 
 #define HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
diff --git a/arch/ia64/include/asm/socket.h b/arch/ia64/include/asm/socket.h
index 7454212..0b0d5ff 100644
--- a/arch/ia64/include/asm/socket.h
+++ b/arch/ia64/include/asm/socket.h
@@ -66,4 +66,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_IA64_SOCKET_H */
diff --git a/arch/ia64/include/asm/topology.h b/arch/ia64/include/asm/topology.h
index 7b4c8c7..d0141fb 100644
--- a/arch/ia64/include/asm/topology.h
+++ b/arch/ia64/include/asm/topology.h
@@ -61,12 +61,13 @@ void build_cpu_to_node_map(void);
 	.cache_nice_tries	= 2,			\
 	.busy_idx		= 2,			\
 	.idle_idx		= 1,			\
-	.newidle_idx		= 2,			\
-	.wake_idx		= 1,			\
-	.forkexec_idx		= 1,			\
+	.newidle_idx		= 0,			\
+	.wake_idx		= 0,			\
+	.forkexec_idx		= 0,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_NEWIDLE	\
 				| SD_BALANCE_EXEC	\
+				| SD_BALANCE_FORK	\
 				| SD_WAKE_AFFINE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
@@ -85,14 +86,14 @@ void build_cpu_to_node_map(void);
 	.cache_nice_tries	= 2,			\
 	.busy_idx		= 3,			\
 	.idle_idx		= 2,			\
-	.newidle_idx		= 2,			\
-	.wake_idx		= 1,			\
-	.forkexec_idx		= 1,			\
+	.newidle_idx		= 0,			\
+	.wake_idx		= 0,			\
+	.forkexec_idx		= 0,			\
 	.flags			= SD_LOAD_BALANCE	\
+				| SD_BALANCE_NEWIDLE	\
 				| SD_BALANCE_EXEC	\
 				| SD_BALANCE_FORK	\
-				| SD_SERIALIZE		\
-				| SD_WAKE_BALANCE,	\
+				| SD_SERIALIZE,		\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 64,			\
 	.nr_balance_failed	= 0,			\
diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c
index f065093..6631a9d 100644
--- a/arch/ia64/kernel/crash.c
+++ b/arch/ia64/kernel/crash.c
@@ -23,6 +23,7 @@
 int kdump_status[NR_CPUS];
 static atomic_t kdump_cpu_frozen;
 atomic_t kdump_in_progress;
+static int kdump_freeze_monarch;
 static int kdump_on_init = 1;
 static int kdump_on_fatal_mca = 1;
 
@@ -108,10 +109,38 @@ machine_crash_shutdown(struct pt_regs *pt)
 	 */
 	kexec_disable_iosapic();
 #ifdef CONFIG_SMP
+	/*
+	 * If kdump_on_init is set and an INIT is asserted here, kdump will
+	 * be started again via INIT monarch.
+	 */
+	local_irq_disable();
+	ia64_set_psr_mc();	/* mask MCA/INIT */
+	if (atomic_inc_return(&kdump_in_progress) != 1)
+		unw_init_running(kdump_cpu_freeze, NULL);
+
+	/*
+	 * Now this cpu is ready for kdump.
+	 * Stop all others by IPI or INIT.  They could receive INIT from
+	 * outside and might be INIT monarch, but only thing they have to
+	 * do is falling into kdump_cpu_freeze().
+	 *
+	 * If an INIT is asserted here:
+	 * - All receivers might be slaves, since some of cpus could already
+	 *   be frozen and INIT might be masked on monarch.  In this case,
+	 *   all slaves will be frozen soon since kdump_in_progress will let
+	 *   them into DIE_INIT_SLAVE_LEAVE.
+	 * - One might be a monarch, but INIT rendezvous will fail since
+	 *   at least this cpu already have INIT masked so it never join
+	 *   to the rendezvous.  In this case, all slaves and monarch will
+	 *   be frozen soon with no wait since the INIT rendezvous is skipped
+	 *   by kdump_in_progress.
+	 */
 	kdump_smp_send_stop();
 	/* not all cpu response to IPI, send INIT to freeze them */
-	if (kdump_wait_cpu_freeze() && kdump_on_init) 	{
+	if (kdump_wait_cpu_freeze()) {
 		kdump_smp_send_init();
+		/* wait again, don't go ahead if possible */
+		kdump_wait_cpu_freeze();
 	}
 #endif
 }
@@ -129,17 +158,17 @@ void
 kdump_cpu_freeze(struct unw_frame_info *info, void *arg)
 {
 	int cpuid;
+
 	local_irq_disable();
 	cpuid = smp_processor_id();
 	crash_save_this_cpu();
 	current->thread.ksp = (__u64)info->sw - 16;
+
+	ia64_set_psr_mc();	/* mask MCA/INIT and stop reentrance */
+
 	atomic_inc(&kdump_cpu_frozen);
 	kdump_status[cpuid] = 1;
 	mb();
-#ifdef CONFIG_HOTPLUG_CPU
-	if (cpuid != 0)
-		ia64_jump_to_sal(&sal_boot_rendez_state[cpuid]);
-#endif
 	for (;;)
 		cpu_relax();
 }
@@ -150,6 +179,20 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
 	struct ia64_mca_notify_die *nd;
 	struct die_args *args = data;
 
+	if (atomic_read(&kdump_in_progress)) {
+		switch (val) {
+		case DIE_INIT_MONARCH_LEAVE:
+			if (!kdump_freeze_monarch)
+				break;
+			/* fall through */
+		case DIE_INIT_SLAVE_LEAVE:
+		case DIE_INIT_MONARCH_ENTER:
+		case DIE_MCA_RENDZVOUS_LEAVE:
+			unw_init_running(kdump_cpu_freeze, NULL);
+			break;
+		}
+	}
+
 	if (!kdump_on_init && !kdump_on_fatal_mca)
 		return NOTIFY_DONE;
 
@@ -162,43 +205,31 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
 	}
 
 	if (val != DIE_INIT_MONARCH_LEAVE &&
-	    val != DIE_INIT_SLAVE_LEAVE &&
 	    val != DIE_INIT_MONARCH_PROCESS &&
-	    val != DIE_MCA_RENDZVOUS_LEAVE &&
 	    val != DIE_MCA_MONARCH_LEAVE)
 		return NOTIFY_DONE;
 
 	nd = (struct ia64_mca_notify_die *)args->err;
-	/* Reason code 1 means machine check rendezvous*/
-	if ((val == DIE_INIT_MONARCH_LEAVE || val == DIE_INIT_SLAVE_LEAVE
-	    || val == DIE_INIT_MONARCH_PROCESS) && nd->sos->rv_rc == 1)
-		return NOTIFY_DONE;
 
 	switch (val) {
 	case DIE_INIT_MONARCH_PROCESS:
-		if (kdump_on_init) {
-			atomic_set(&kdump_in_progress, 1);
-			*(nd->monarch_cpu) = -1;
+		/* Reason code 1 means machine check rendezvous*/
+		if (kdump_on_init && (nd->sos->rv_rc != 1)) {
+			if (atomic_inc_return(&kdump_in_progress) != 1)
+				kdump_freeze_monarch = 1;
 		}
 		break;
 	case DIE_INIT_MONARCH_LEAVE:
-		if (kdump_on_init)
+		/* Reason code 1 means machine check rendezvous*/
+		if (kdump_on_init && (nd->sos->rv_rc != 1))
 			machine_kdump_on_init();
 		break;
-	case DIE_INIT_SLAVE_LEAVE:
-		if (atomic_read(&kdump_in_progress))
-			unw_init_running(kdump_cpu_freeze, NULL);
-		break;
-	case DIE_MCA_RENDZVOUS_LEAVE:
-		if (atomic_read(&kdump_in_progress))
-			unw_init_running(kdump_cpu_freeze, NULL);
-		break;
 	case DIE_MCA_MONARCH_LEAVE:
 		/* *(nd->data) indicate if MCA is recoverable */
 		if (kdump_on_fatal_mca && !(*(nd->data))) {
-			atomic_set(&kdump_in_progress, 1);
-			*(nd->monarch_cpu) = -1;
-			machine_kdump_on_init();
+			if (atomic_inc_return(&kdump_in_progress) == 1)
+				machine_kdump_on_init();
+			/* We got fatal MCA while kdump!? No way!! */
 		}
 		break;
 	}
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index 23f846d..1a6e445 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -167,7 +167,7 @@ RestRR:											\
 	mov _tmp2=((ia64_rid(IA64_REGION_ID_KERNEL, (num<<61)) << 8) | (pgsize << 2) | vhpt);; \
 	mov rr[_tmp1]=_tmp2
 
-	.section __special_page_section,"ax"
+	__PAGE_ALIGNED_DATA
 
 	.global empty_zero_page
 empty_zero_page:
@@ -181,7 +181,7 @@ swapper_pg_dir:
 halt_msg:
 	stringz "Halting kernel\n"
 
-	.section .text.head,"ax"
+	__REF
 
 	.global start_ap
 
@@ -1242,7 +1242,7 @@ GLOBAL_ENTRY(ia64_jump_to_sal)
 	movl r16=SAL_PSR_BITS_TO_SET;;
 	mov cr.ipsr=r16
 	mov cr.ifs=r0;;
-	rfi;;
+	rfi;;			// note: this unmask MCA/INIT (psr.mc)
 1:
 	/*
 	 * Invalidate all TLB data/inst
diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c
index 0823de1..3d3aeef 100644
--- a/arch/ia64/kernel/machine_kexec.c
+++ b/arch/ia64/kernel/machine_kexec.c
@@ -24,6 +24,8 @@
 #include <asm/delay.h>
 #include <asm/meminit.h>
 #include <asm/processor.h>
+#include <asm/sal.h>
+#include <asm/mca.h>
 
 typedef NORET_TYPE void (*relocate_new_kernel_t)(
 					unsigned long indirection_page,
@@ -85,13 +87,26 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
 	void *pal_addr = efi_get_pal_addr();
 	unsigned long code_addr = (unsigned long)page_address(image->control_code_page);
 	int ii;
+	u64 fp, gp;
+	ia64_fptr_t *init_handler = (ia64_fptr_t *)ia64_os_init_on_kdump;
 
 	BUG_ON(!image);
 	if (image->type == KEXEC_TYPE_CRASH) {
 		crash_save_this_cpu();
 		current->thread.ksp = (__u64)info->sw - 16;
+
+		/* Register noop init handler */
+		fp = ia64_tpa(init_handler->fp);
+		gp = ia64_tpa(ia64_getreg(_IA64_REG_GP));
+		ia64_sal_set_vectors(SAL_VECTOR_OS_INIT, fp, gp, 0, fp, gp, 0);
+	} else {
+		/* Unregister init handlers of current kernel */
+		ia64_sal_set_vectors(SAL_VECTOR_OS_INIT, 0, 0, 0, 0, 0, 0);
 	}
 
+	/* Unregister mca handler - No more recovery on current kernel */
+	ia64_sal_set_vectors(SAL_VECTOR_OS_MCA, 0, 0, 0, 0, 0, 0);
+
 	/* Interrupts aren't acceptable while we reboot */
 	local_irq_disable();
 
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 7b30d21..d2877a7 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -1682,14 +1682,25 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
 
 	if (!sos->monarch) {
 		ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
+
+#ifdef CONFIG_KEXEC
+		while (monarch_cpu == -1 && !atomic_read(&kdump_in_progress))
+			udelay(1000);
+#else
 		while (monarch_cpu == -1)
-		       cpu_relax();	/* spin until monarch enters */
+			cpu_relax();	/* spin until monarch enters */
+#endif
 
 		NOTIFY_INIT(DIE_INIT_SLAVE_ENTER, regs, (long)&nd, 1);
 		NOTIFY_INIT(DIE_INIT_SLAVE_PROCESS, regs, (long)&nd, 1);
 
+#ifdef CONFIG_KEXEC
+		while (monarch_cpu != -1 && !atomic_read(&kdump_in_progress))
+			udelay(1000);
+#else
 		while (monarch_cpu != -1)
-		       cpu_relax();	/* spin until monarch leaves */
+			cpu_relax();	/* spin until monarch leaves */
+#endif
 
 		NOTIFY_INIT(DIE_INIT_SLAVE_LEAVE, regs, (long)&nd, 1);
 
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index a06d465..7461d25 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -40,6 +40,7 @@
 
 	.global ia64_do_tlb_purge
 	.global ia64_os_mca_dispatch
+	.global ia64_os_init_on_kdump
 	.global ia64_os_init_dispatch_monarch
 	.global ia64_os_init_dispatch_slave
 
@@ -299,6 +300,25 @@ END(ia64_os_mca_virtual_begin)
 //StartMain////////////////////////////////////////////////////////////////////
 
 //
+// NOP init handler for kdump.  In panic situation, we may receive INIT
+// while kernel transition.  Since we initialize registers on leave from
+// current kernel, no longer monarch/slave handlers of current kernel in
+// virtual mode are called safely.
+// We can unregister these init handlers from SAL, however then the INIT
+// will result in warmboot by SAL and we cannot retrieve the crashdump.
+// Therefore register this NOP function to SAL, to prevent entering virtual
+// mode and resulting warmboot by SAL.
+//
+ia64_os_init_on_kdump:
+	mov		r8=r0		// IA64_INIT_RESUME
+	mov             r9=r10		// SAL_GP
+	mov		r22=r17		// *minstate
+	;;
+	mov		r10=r0		// return to same context
+	mov		b0=r12		// SAL_CHECK return address
+	br		b0
+
+//
 // SAL to OS entry point for INIT on all processors.  This has been defined for
 // registration purposes with SAL as a part of ia64_mca_init.  Monarch and
 // slave INIT have identical processing, except for the value of the
@@ -1073,3 +1093,30 @@ GLOBAL_ENTRY(ia64_get_rnat)
 	mov ar.rsc=3
 	br.ret.sptk.many rp
 END(ia64_get_rnat)
+
+
+// void ia64_set_psr_mc(void)
+//
+// Set psr.mc bit to mask MCA/INIT.
+GLOBAL_ENTRY(ia64_set_psr_mc)
+	rsm psr.i | psr.ic		// disable interrupts
+	;;
+	srlz.d
+	;;
+	mov r14 = psr			// get psr{36:35,31:0}
+	movl r15 = 1f
+	;;
+	dep r14 = -1, r14, PSR_MC, 1	// set psr.mc
+	;;
+	dep r14 = -1, r14, PSR_IC, 1	// set psr.ic
+	;;
+	dep r14 = -1, r14, PSR_BN, 1	// keep bank1 in use
+	;;
+	mov cr.ipsr = r14
+	mov cr.ifs = r0
+	mov cr.iip = r15
+	;;
+	rfi
+1:
+	br.ret.sptk.many rp
+END(ia64_set_psr_mc)
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 89969e9..9bcec99 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -161,6 +161,13 @@ show_regs (struct pt_regs *regs)
 		show_stack(NULL, NULL);
 }
 
+/* local support for deprecated console_print */
+void
+console_print(const char *s)
+{
+	printk(KERN_EMERG "%s", s);
+}
+
 void
 do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
 {
diff --git a/arch/ia64/kernel/relocate_kernel.S b/arch/ia64/kernel/relocate_kernel.S
index 903babd..32f6fc1 100644
--- a/arch/ia64/kernel/relocate_kernel.S
+++ b/arch/ia64/kernel/relocate_kernel.S
@@ -52,7 +52,7 @@ GLOBAL_ENTRY(relocate_new_kernel)
 	srlz.i
 	;;
 	mov ar.rnat=r18
-	rfi
+	rfi				// note: this unmask MCA/INIT (psr.mc)
 	;;
 1:
 	//physical mode code begin
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 1b23ec1..1de86c9 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -855,11 +855,17 @@ identify_cpu (struct cpuinfo_ia64 *c)
 	c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1));
 }
 
+/*
+ * In UP configuration, setup_per_cpu_areas() is defined in
+ * include/linux/percpu.h
+ */
+#ifdef CONFIG_SMP
 void __init
 setup_per_cpu_areas (void)
 {
 	/* start_kernel() requires this... */
 }
+#endif
 
 /*
  * Do the following calculations:
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index f0c521b..93ebfea 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -58,7 +58,8 @@ static struct local_tlb_flush_counts {
 	unsigned int count;
 } __attribute__((__aligned__(32))) local_tlb_flush_counts[NR_CPUS];
 
-static DEFINE_PER_CPU(unsigned short, shadow_flush_counts[NR_CPUS]) ____cacheline_aligned;
+static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned short [NR_CPUS],
+				     shadow_flush_counts);
 
 #define IPI_CALL_FUNC		0
 #define IPI_CPU_STOP		1
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 4a95e86..0a0c77b 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -24,14 +24,14 @@ PHDRS {
 }
 SECTIONS
 {
-  /* Sections to be discarded */
+  /* unwind exit sections must be discarded before the rest of the
+     sections get included. */
   /DISCARD/ : {
-	EXIT_TEXT
-	EXIT_DATA
-	*(.exitcall.exit)
 	*(.IA_64.unwind.exit.text)
 	*(.IA_64.unwind_info.exit.text)
-	}
+	*(.comment)
+	*(.note)
+  }
 
   v = PAGE_OFFSET;	/* this symbol is here to make debugging easier... */
   phys_start = _start - LOAD_OFFSET;
@@ -51,8 +51,6 @@ SECTIONS
 	KPROBES_TEXT
 	*(.gnu.linkonce.t*)
     }
-  .text.head : AT(ADDR(.text.head) - LOAD_OFFSET)
-	{ *(.text.head) }
   .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
 	{ *(.text2) }
 #ifdef CONFIG_SMP
@@ -66,14 +64,7 @@ SECTIONS
   NOTES :code :note		/* put .notes in text and mark in PT_NOTE  */
   code_continues : {} :code	/* switch back to regular program...  */
 
-  /* Exception table */
-  . = ALIGN(16);
-  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET)
-	{
-	  __start___ex_table = .;
-	  *(__ex_table)
-	  __stop___ex_table = .;
-	}
+  EXCEPTION_TABLE(16)
 
   /* MCA table */
   . = ALIGN(16);
@@ -115,38 +106,9 @@ SECTIONS
 
   . = ALIGN(PAGE_SIZE);
   __init_begin = .;
-  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
-	{
-	  _sinittext = .;
-	  INIT_TEXT
-	  _einittext = .;
-	}
 
-  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET)
-	{ INIT_DATA }
-
-#ifdef CONFIG_BLK_DEV_INITRD
-  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET)
-	{
-	  __initramfs_start = .;
-	  *(.init.ramfs)
-	  __initramfs_end = .;
-	}
-#endif
-
-   . = ALIGN(16);
-  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET)
-        {
-	  __setup_start = .;
-	  *(.init.setup)
-	  __setup_end = .;
-	}
-  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET)
-	{
-	  __initcall_start = .;
-	INITCALLS
-	  __initcall_end = .;
-	}
+  INIT_TEXT_SECTION(PAGE_SIZE)
+  INIT_DATA_SECTION(16)
 
   .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
 	{
@@ -204,24 +166,13 @@ SECTIONS
 	}
 #endif
 
-  . = ALIGN(8);
-   __con_initcall_start = .;
-  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET)
-	{ *(.con_initcall.init) }
-  __con_initcall_end = .;
-  __security_initcall_start = .;
-  .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET)
-	{ *(.security_initcall.init) }
-  __security_initcall_end = .;
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
-  /* The initial task and kernel stack */
-  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET)
-	{ *(.data.init_task) }
-
   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET)
-        { *(__special_page_section)
+        {
+	PAGE_ALIGNED_DATA(PAGE_SIZE)
+	  . = ALIGN(PAGE_SIZE);
 	  __start_gate_section = .;
 	  *(.data.gate)
 	  __stop_gate_section = .;
@@ -236,12 +187,6 @@ SECTIONS
   				 * kernel data
 				 */
 
-  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET)
-        { *(.data.read_mostly) }
-
-  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET)
-        { *(.data.cacheline_aligned) }
-
   /* Per-cpu data: */
   . = ALIGN(PERCPU_PAGE_SIZE);
   PERCPU_VADDR(PERCPU_ADDR, :percpu)
@@ -258,6 +203,9 @@ SECTIONS
 		__cpu0_per_cpu = .;
   . = . + PERCPU_PAGE_SIZE;	/* cpu0 per-cpu space */
 #endif
+		INIT_TASK_DATA(PAGE_SIZE)
+		CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES)
+		READ_MOSTLY_DATA(SMP_CACHE_BYTES)
 		DATA_DATA
 		*(.data1)
 		*(.gnu.linkonce.d*)
@@ -274,49 +222,16 @@ SECTIONS
   .sdata : AT(ADDR(.sdata) - LOAD_OFFSET)
 	{ *(.sdata) *(.sdata1) *(.srdata) }
   _edata  =  .;
-  __bss_start = .;
-  .sbss : AT(ADDR(.sbss) - LOAD_OFFSET)
-	{ *(.sbss) *(.scommon) }
-  .bss : AT(ADDR(.bss) - LOAD_OFFSET)
-	{ *(.bss) *(COMMON) }
-  __bss_stop = .;
+
+  BSS_SECTION(0, 0, 0)
 
   _end = .;
 
   code : { } :code
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  /* DWARF debug sections.
-     Symbols in the DWARF debugging sections are relative to the beginning
-     of the section so we begin them at 0.  */
-  /* DWARF 1 */
-  .debug          0 : { *(.debug) }
-  .line           0 : { *(.line) }
-  /* GNU DWARF 1 extensions */
-  .debug_srcinfo  0 : { *(.debug_srcinfo) }
-  .debug_sfnames  0 : { *(.debug_sfnames) }
-  /* DWARF 1.1 and DWARF 2 */
-  .debug_aranges  0 : { *(.debug_aranges) }
-  .debug_pubnames 0 : { *(.debug_pubnames) }
-  /* DWARF 2 */
-  .debug_info     0 : { *(.debug_info) }
-  .debug_abbrev   0 : { *(.debug_abbrev) }
-  .debug_line     0 : { *(.debug_line) }
-  .debug_frame    0 : { *(.debug_frame) }
-  .debug_str      0 : { *(.debug_str) }
-  .debug_loc      0 : { *(.debug_loc) }
-  .debug_macinfo  0 : { *(.debug_macinfo) }
-  /* SGI/MIPS DWARF 2 extensions */
-  .debug_weaknames 0 : { *(.debug_weaknames) }
-  .debug_funcnames 0 : { *(.debug_funcnames) }
-  .debug_typenames 0 : { *(.debug_typenames) }
-  .debug_varnames  0 : { *(.debug_varnames) }
-  /* These must appear regardless of  .  */
-  /DISCARD/ : { *(.comment) }
-  /DISCARD/ : { *(.note) }
+
+  STABS_DEBUG
+  DWARF_DEBUG
+
+  /* Default discards */
+  DISCARDS
 }
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 64d5209..ef3e7be 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -1,12 +1,8 @@
 #
 # KVM configuration
 #
-config HAVE_KVM
-	bool
 
-config HAVE_KVM_IRQCHIP
-       bool
-       default y
+source "virt/kvm/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -28,6 +24,8 @@ config KVM
 	depends on PCI
 	select PREEMPT_NOTIFIERS
 	select ANON_INODES
+	select HAVE_KVM_IRQCHIP
+	select KVM_APIC_ARCHITECTURE
 	---help---
 	  Support hosting fully virtualized guest machines using hardware
 	  virtualization extensions.  You will need a fairly recent
@@ -49,9 +47,6 @@ config KVM_INTEL
 	  Provides support for KVM on Itanium 2 processors equipped with the VT
 	  extensions.
 
-config KVM_TRACE
-       bool
-
 source drivers/virtio/Kconfig
 
 endif # VIRTUALIZATION
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 80c57b0..0ad09f0 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -210,16 +210,6 @@ int kvm_dev_ioctl_check_extension(long ext)
 
 }
 
-static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
-					gpa_t addr, int len, int is_write)
-{
-	struct kvm_io_device *dev;
-
-	dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write);
-
-	return dev;
-}
-
 static int handle_vm_error(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
@@ -231,6 +221,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	struct kvm_mmio_req *p;
 	struct kvm_io_device *mmio_dev;
+	int r;
 
 	p = kvm_get_vcpu_ioreq(vcpu);
 
@@ -247,16 +238,13 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	kvm_run->exit_reason = KVM_EXIT_MMIO;
 	return 0;
 mmio:
-	mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir);
-	if (mmio_dev) {
-		if (!p->dir)
-			kvm_iodevice_write(mmio_dev, p->addr, p->size,
-						&p->data);
-		else
-			kvm_iodevice_read(mmio_dev, p->addr, p->size,
-						&p->data);
-
-	} else
+	if (p->dir)
+		r = kvm_io_bus_read(&vcpu->kvm->mmio_bus, p->addr,
+				    p->size, &p->data);
+	else
+		r = kvm_io_bus_write(&vcpu->kvm->mmio_bus, p->addr,
+				     p->size, &p->data);
+	if (r)
 		printk(KERN_ERR"kvm: No iodevice found! addr:%lx\n", p->addr);
 	p->state = STATE_IORESP_READY;
 
@@ -337,13 +325,12 @@ static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id,
 {
 	union ia64_lid lid;
 	int i;
+	struct kvm_vcpu *vcpu;
 
-	for (i = 0; i < kvm->arch.online_vcpus; i++) {
-		if (kvm->vcpus[i]) {
-			lid.val = VCPU_LID(kvm->vcpus[i]);
-			if (lid.id == id && lid.eid == eid)
-				return kvm->vcpus[i];
-		}
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		lid.val = VCPU_LID(vcpu);
+		if (lid.id == id && lid.eid == eid)
+			return vcpu;
 	}
 
 	return NULL;
@@ -409,21 +396,21 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	struct kvm *kvm = vcpu->kvm;
 	struct call_data call_data;
 	int i;
+	struct kvm_vcpu *vcpui;
 
 	call_data.ptc_g_data = p->u.ptc_g_data;
 
-	for (i = 0; i < kvm->arch.online_vcpus; i++) {
-		if (!kvm->vcpus[i] || kvm->vcpus[i]->arch.mp_state ==
-						KVM_MP_STATE_UNINITIALIZED ||
-					vcpu == kvm->vcpus[i])
+	kvm_for_each_vcpu(i, vcpui, kvm) {
+		if (vcpui->arch.mp_state == KVM_MP_STATE_UNINITIALIZED ||
+				vcpu == vcpui)
 			continue;
 
-		if (waitqueue_active(&kvm->vcpus[i]->wq))
-			wake_up_interruptible(&kvm->vcpus[i]->wq);
+		if (waitqueue_active(&vcpui->wq))
+			wake_up_interruptible(&vcpui->wq);
 
-		if (kvm->vcpus[i]->cpu != -1) {
-			call_data.vcpu = kvm->vcpus[i];
-			smp_call_function_single(kvm->vcpus[i]->cpu,
+		if (vcpui->cpu != -1) {
+			call_data.vcpu = vcpui;
+			smp_call_function_single(vcpui->cpu,
 					vcpu_global_purge, &call_data, 1);
 		} else
 			printk(KERN_WARNING"kvm: Uninit vcpu received ipi!\n");
@@ -852,8 +839,6 @@ struct  kvm *kvm_arch_create_vm(void)
 
 	kvm_init_vm(kvm);
 
-	kvm->arch.online_vcpus = 0;
-
 	return kvm;
 
 }
@@ -1000,10 +985,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
 			goto out;
 		if (irqchip_in_kernel(kvm)) {
 			__s32 status;
-			mutex_lock(&kvm->lock);
+			mutex_lock(&kvm->irq_lock);
 			status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
 				    irq_event.irq, irq_event.level);
-			mutex_unlock(&kvm->lock);
+			mutex_unlock(&kvm->irq_lock);
 			if (ioctl == KVM_IRQ_LINE_STATUS) {
 				irq_event.status = status;
 				if (copy_to_user(argp, &irq_event,
@@ -1216,7 +1201,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 	if (IS_ERR(vmm_vcpu))
 		return PTR_ERR(vmm_vcpu);
 
-	if (vcpu->vcpu_id == 0) {
+	if (kvm_vcpu_is_bsp(vcpu)) {
 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 
 		/*Set entry address for first run.*/
@@ -1224,7 +1209,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 
 		/*Initialize itc offset for vcpus*/
 		itc_offset = 0UL - kvm_get_itc(vcpu);
-		for (i = 0; i < kvm->arch.online_vcpus; i++) {
+		for (i = 0; i < KVM_MAX_VCPUS; i++) {
 			v = (struct kvm_vcpu *)((char *)vcpu +
 					sizeof(struct kvm_vcpu_data) * i);
 			v->arch.itc_offset = itc_offset;
@@ -1356,8 +1341,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
 		goto fail;
 	}
 
-	kvm->arch.online_vcpus++;
-
 	return vcpu;
 fail:
 	return ERR_PTR(r);
@@ -1952,19 +1935,6 @@ int kvm_highest_pending_irq(struct kvm_vcpu *vcpu)
     return find_highest_bits((int *)&vpd->irr[0]);
 }
 
-int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
-{
-	if (kvm_highest_pending_irq(vcpu) != -1)
-		return 1;
-	return 0;
-}
-
-int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
-{
-	/* do real check here */
-	return 1;
-}
-
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 {
 	return vcpu->arch.timer_fired;
@@ -1977,7 +1947,8 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
 {
-	return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE;
+	return (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) ||
+		(kvm_highest_pending_irq(vcpu) != -1);
 }
 
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
diff --git a/arch/ia64/kvm/vcpu.c b/arch/ia64/kvm/vcpu.c
index cc406d0..dce75b7 100644
--- a/arch/ia64/kvm/vcpu.c
+++ b/arch/ia64/kvm/vcpu.c
@@ -830,8 +830,8 @@ static void vcpu_set_itc(struct kvm_vcpu *vcpu, u64 val)
 
 	kvm = (struct kvm *)KVM_VM_BASE;
 
-	if (vcpu->vcpu_id == 0) {
-		for (i = 0; i < kvm->arch.online_vcpus; i++) {
+	if (kvm_vcpu_is_bsp(vcpu)) {
+		for (i = 0; i < atomic_read(&kvm->online_vcpus); i++) {
 			v = (struct kvm_vcpu *)((char *)vcpu +
 					sizeof(struct kvm_vcpu_data) * i);
 			VMX(v, itc_offset) = itc_offset;
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index e456f06..ece1bf9 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -71,7 +71,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
 DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
 EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
 
-DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
+DEFINE_PER_CPU(short [MAX_COMPACT_NODES], __sn_cnodeid_to_nasid);
 EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
 
 DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
index 239b3ce..5bc34ea 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_ate.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
@@ -54,6 +54,8 @@ static int find_free_ate(struct ate_resource *ate_resource, int start,
 					break;
 				}
 			}
+			if (i >= ate_resource->num_ate)
+				return -1;
 		} else
 			index++;	/* Try next ate */
 	}
diff --git a/arch/m32r/include/asm/socket.h b/arch/m32r/include/asm/socket.h
index be7ed58..3390a86 100644
--- a/arch/m32r/include/asm/socket.h
+++ b/arch/m32r/include/asm/socket.h
@@ -57,4 +57,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_M32R_SOCKET_H */
diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S
index 4179adf..de5e21c 100644
--- a/arch/m32r/kernel/vmlinux.lds.S
+++ b/arch/m32r/kernel/vmlinux.lds.S
@@ -120,13 +120,6 @@ SECTIONS
 
   _end = . ;
 
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	EXIT_TEXT
-	EXIT_DATA
-	*(.exitcall.exit)
-	}
-
   /* Stabs debugging sections.  */
   .stab 0 : { *(.stab) }
   .stabstr 0 : { *(.stabstr) }
@@ -135,4 +128,7 @@ SECTIONS
   .stab.index 0 : { *(.stab.index) }
   .stab.indexstr 0 : { *(.stab.indexstr) }
   .comment 0 : { *(.comment) }
+
+  /* Sections to be discarded */
+  DISCARDS
 }
diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h
index 1cf5447..ec51448 100644
--- a/arch/m68k/include/asm/checksum.h
+++ b/arch/m68k/include/asm/checksum.h
@@ -1,5 +1,170 @@
-#ifdef __uClinux__
-#include "checksum_no.h"
+#ifndef _M68K_CHECKSUM_H
+#define _M68K_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+extern __wsum csum_partial_copy_from_user(const void __user *src,
+						void *dst,
+						int len, __wsum sum,
+						int *csum_err);
+
+extern __wsum csum_partial_copy_nocheck(const void *src,
+					      void *dst, int len,
+					      __wsum sum);
+
+
+#ifdef CONFIG_COLDFIRE
+
+/*
+ *	The ColdFire cores don't support all the 68k instructions used
+ *	in the optimized checksum code below. So it reverts back to using
+ *	more standard C coded checksums. The fast checksum code is
+ *	significantly larger than the optimized version, so it is not
+ *	inlined here.
+ */
+__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+	unsigned int tmp = (__force u32)sum;
+
+	tmp = (tmp & 0xffff) + (tmp >> 16);
+	tmp = (tmp & 0xffff) + (tmp >> 16);
+
+	return (__force __sum16)~tmp;
+}
+
 #else
-#include "checksum_mm.h"
-#endif
+
+/*
+ *	This is a version of ip_fast_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+	unsigned int sum = 0;
+	unsigned long tmp;
+
+	__asm__ ("subqw #1,%2\n"
+		 "1:\t"
+		 "movel %1@+,%3\n\t"
+		 "addxl %3,%0\n\t"
+		 "dbra  %2,1b\n\t"
+		 "movel %0,%3\n\t"
+		 "swap  %3\n\t"
+		 "addxw %3,%0\n\t"
+		 "clrw  %3\n\t"
+		 "addxw %3,%0\n\t"
+		 : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
+		 : "0" (sum), "1" (iph), "2" (ihl)
+		 : "memory");
+	return (__force __sum16)~sum;
+}
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+	unsigned int tmp = (__force u32)sum;
+
+	__asm__("swap %1\n\t"
+		"addw %1, %0\n\t"
+		"clrw %1\n\t"
+		"addxw %1, %0"
+		: "=&d" (sum), "=&d" (tmp)
+		: "0" (sum), "1" (tmp));
+
+	return (__force __sum16)~sum;
+}
+
+#endif /* CONFIG_COLDFIRE */
+
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+		  unsigned short proto, __wsum sum)
+{
+	__asm__ ("addl  %2,%0\n\t"
+		 "addxl %3,%0\n\t"
+		 "addxl %4,%0\n\t"
+		 "clrl %1\n\t"
+		 "addxl %1,%0"
+		 : "=&d" (sum), "=d" (saddr)
+		 : "g" (daddr), "1" (saddr), "d" (len + proto),
+		   "0" (sum));
+	return sum;
+}
+
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+		  unsigned short proto, __wsum sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static inline __sum16 ip_compute_csum(const void *buff, int len)
+{
+	return csum_fold (csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static __inline__ __sum16
+csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
+		__u32 len, unsigned short proto, __wsum sum)
+{
+	register unsigned long tmp;
+	__asm__("addl %2@,%0\n\t"
+		"movel %2@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %2@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@,%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(4),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(8),%1\n\t"
+		"addxl %1,%0\n\t"
+		"movel %3@(12),%1\n\t"
+		"addxl %1,%0\n\t"
+		"addxl %4,%0\n\t"
+		"clrl %1\n\t"
+		"addxl %1,%0"
+		: "=&d" (sum), "=&d" (tmp)
+		: "a" (saddr), "a" (daddr), "d" (len + proto),
+		  "0" (sum));
+
+	return csum_fold(sum);
+}
+
+#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/checksum_mm.h b/arch/m68k/include/asm/checksum_mm.h
deleted file mode 100644
index 494f9ae..0000000
--- a/arch/m68k/include/asm/checksum_mm.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef _M68K_CHECKSUM_H
-#define _M68K_CHECKSUM_H
-
-#include <linux/in6.h>
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern __wsum csum_partial_copy_from_user(const void __user *src,
-						void *dst,
-						int len, __wsum sum,
-						int *csum_err);
-
-extern __wsum csum_partial_copy_nocheck(const void *src,
-					      void *dst, int len,
-					      __wsum sum);
-
-/*
- *	This is a version of ip_compute_csum() optimized for IP headers,
- *	which always checksum on 4 octet boundaries.
- *
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
-	unsigned int sum = 0;
-	unsigned long tmp;
-
-	__asm__ ("subqw #1,%2\n"
-		 "1:\t"
-		 "movel %1@+,%3\n\t"
-		 "addxl %3,%0\n\t"
-		 "dbra  %2,1b\n\t"
-		 "movel %0,%3\n\t"
-		 "swap  %3\n\t"
-		 "addxw %3,%0\n\t"
-		 "clrw  %3\n\t"
-		 "addxw %3,%0\n\t"
-		 : "=d" (sum), "=&a" (iph), "=&d" (ihl), "=&d" (tmp)
-		 : "0" (sum), "1" (iph), "2" (ihl)
-		 : "memory");
-	return (__force __sum16)~sum;
-}
-
-/*
- *	Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
-	unsigned int tmp = (__force u32)sum;
-	__asm__("swap %1\n\t"
-		"addw %1, %0\n\t"
-		"clrw %1\n\t"
-		"addxw %1, %0"
-		: "=&d" (sum), "=&d" (tmp)
-		: "0" (sum), "1" (tmp));
-	return (__force __sum16)~sum;
-}
-
-
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
-		  unsigned short proto, __wsum sum)
-{
-	__asm__ ("addl  %2,%0\n\t"
-		 "addxl %3,%0\n\t"
-		 "addxl %4,%0\n\t"
-		 "clrl %1\n\t"
-		 "addxl %1,%0"
-		 : "=&d" (sum), "=d" (saddr)
-		 : "g" (daddr), "1" (saddr), "d" (len + proto),
-		   "0" (sum));
-	return sum;
-}
-
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
-		  unsigned short proto, __wsum sum)
-{
-	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
-static inline __sum16 ip_compute_csum(const void *buff, int len)
-{
-	return csum_fold (csum_partial(buff, len, 0));
-}
-
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16
-csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
-		__u32 len, unsigned short proto, __wsum sum)
-{
-	register unsigned long tmp;
-	__asm__("addl %2@,%0\n\t"
-		"movel %2@(4),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %2@(8),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %2@(12),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@,%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@(4),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@(8),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@(12),%1\n\t"
-		"addxl %1,%0\n\t"
-		"addxl %4,%0\n\t"
-		"clrl %1\n\t"
-		"addxl %1,%0"
-		: "=&d" (sum), "=&d" (tmp)
-		: "a" (saddr), "a" (daddr), "d" (len + proto),
-		  "0" (sum));
-
-	return csum_fold(sum);
-}
-
-#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/checksum_no.h b/arch/m68k/include/asm/checksum_no.h
deleted file mode 100644
index 8188348..0000000
--- a/arch/m68k/include/asm/checksum_no.h
+++ /dev/null
@@ -1,132 +0,0 @@
-#ifndef _M68K_CHECKSUM_H
-#define _M68K_CHECKSUM_H
-
-#include <linux/in6.h>
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-__wsum csum_partial_copy_nocheck(const void *src, void *dst,
-	int len, __wsum sum);
-
-
-/*
- * the same as csum_partial_copy, but copies from user space.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-extern __wsum csum_partial_copy_from_user(const void __user *src,
-	void *dst, int len, __wsum sum, int *csum_err);
-
-__sum16 ip_fast_csum(const void *iph, unsigned int ihl);
-
-/*
- *	Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
-	unsigned int tmp = (__force u32)sum;
-#ifdef CONFIG_COLDFIRE
-	tmp = (tmp & 0xffff) + (tmp >> 16);
-	tmp = (tmp & 0xffff) + (tmp >> 16);
-	return (__force __sum16)~tmp;
-#else
-	__asm__("swap %1\n\t"
-		"addw %1, %0\n\t"
-		"clrw %1\n\t"
-		"addxw %1, %0"
-		: "=&d" (sum), "=&d" (tmp)
-		: "0" (sum), "1" (sum));
-	return (__force __sum16)~sum;
-#endif
-}
-
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
-		  unsigned short proto, __wsum sum)
-{
-	__asm__ ("addl  %1,%0\n\t"
-		 "addxl %4,%0\n\t"
-		 "addxl %5,%0\n\t"
-		 "clrl %1\n\t"
-		 "addxl %1,%0"
-		 : "=&d" (sum), "=&d" (saddr)
-		 : "0" (daddr), "1" (saddr), "d" (len + proto),
-		   "d"(sum));
-	return sum;
-}
-
-static inline __sum16
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
-		  unsigned short proto, __wsum sum)
-{
-	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
-extern __sum16 ip_compute_csum(const void *buff, int len);
-
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16
-csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
-		__u32 len, unsigned short proto, __wsum sum)
-{
-	register unsigned long tmp;
-	__asm__("addl %2@,%0\n\t"
-		"movel %2@(4),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %2@(8),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %2@(12),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@,%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@(4),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@(8),%1\n\t"
-		"addxl %1,%0\n\t"
-		"movel %3@(12),%1\n\t"
-		"addxl %1,%0\n\t"
-		"addxl %4,%0\n\t"
-		"clrl %1\n\t"
-		"addxl %1,%0"
-		: "=&d" (sum), "=&d" (tmp)
-		: "a" (saddr), "a" (daddr), "d" (len + proto),
-		  "0" (sum));
-
-	return csum_fold(sum);
-}
-
-#endif /* _M68K_CHECKSUM_H */
diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h
index b82e660..6fbdfe8 100644
--- a/arch/m68k/include/asm/dma.h
+++ b/arch/m68k/include/asm/dma.h
@@ -1,5 +1,491 @@
-#ifdef __uClinux__
-#include "dma_no.h"
+#ifndef _M68K_DMA_H
+#define _M68K_DMA_H 1
+
+#ifdef CONFIG_COLDFIRE
+/*
+ * ColdFire DMA Model:
+ *   ColdFire DMA supports two forms of DMA: Single and Dual address. Single
+ * address mode emits a source address, and expects that the device will either
+ * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
+ * the device will place data on the correct byte(s) of the data bus, as the
+ * memory transactions are always 32 bits. This implies that only 32 bit
+ * devices will find single mode transfers useful. Dual address DMA mode
+ * performs two cycles: source read and destination write. ColdFire will
+ * align the data so that the device will always get the correct bytes, thus
+ * is useful for 8 and 16 bit devices. This is the mode that is supported
+ * below.
+ *
+ * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
+ *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
+ *
+ * APR/18/2002 : added proper support for MCF5272 DMA controller.
+ *               Arthur Shipkowski (art@videon-central.com)
+ */
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfdma.h>
+
+/*
+ * Set number of channels of DMA on ColdFire for different implementations.
+ */
+#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
+	defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#define MAX_M68K_DMA_CHANNELS 4
+#elif defined(CONFIG_M5272)
+#define MAX_M68K_DMA_CHANNELS 1
+#elif defined(CONFIG_M532x)
+#define MAX_M68K_DMA_CHANNELS 0
 #else
-#include "dma_mm.h"
+#define MAX_M68K_DMA_CHANNELS 2
 #endif
+
+extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
+extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+#if !defined(CONFIG_M5272)
+#define DMA_MODE_WRITE_BIT  0x01  /* Memory/IO to IO/Memory select */
+#define DMA_MODE_WORD_BIT   0x02  /* 8 or 16 bit transfers */
+#define DMA_MODE_LONG_BIT   0x04  /* or 32 bit transfers */
+#define DMA_MODE_SINGLE_BIT 0x08  /* single-address-mode */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ	            0
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE	            1
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD          2
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         3
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG          4
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         5
+/* I/O to memory, 8 bits, single-address-mode */
+#define DMA_MODE_READ_SINGLE        8
+/* memory to I/O, 8 bits, single-address-mode */
+#define DMA_MODE_WRITE_SINGLE       9
+/* I/O to memory, 16 bits, single-address-mode */
+#define DMA_MODE_READ_WORD_SINGLE  10
+/* memory to I/O, 16 bits, single-address-mode */
+#define DMA_MODE_WRITE_WORD_SINGLE 11
+/* I/O to memory, 32 bits, single-address-mode */
+#define DMA_MODE_READ_LONG_SINGLE  12
+/* memory to I/O, 32 bits, single-address-mode */
+#define DMA_MODE_WRITE_LONG_SINGLE 13
+
+#else /* CONFIG_M5272 is defined */
+
+/* Source static-address mode */
+#define DMA_MODE_SRC_SA_BIT 0x01
+/* Two bits to select between all four modes */
+#define DMA_MODE_SSIZE_MASK 0x06
+/* Offset to shift bits in */
+#define DMA_MODE_SSIZE_OFF  0x01
+/* Destination static-address mode */
+#define DMA_MODE_DES_SA_BIT 0x10
+/* Two bits to select between all four modes */
+#define DMA_MODE_DSIZE_MASK 0x60
+/* Offset to shift bits in */
+#define DMA_MODE_DSIZE_OFF  0x05
+/* Size modifiers */
+#define DMA_MODE_SIZE_LONG  0x00
+#define DMA_MODE_SIZE_BYTE  0x01
+#define DMA_MODE_SIZE_WORD  0x02
+#define DMA_MODE_SIZE_LINE  0x03
+
+/*
+ * Aliases to help speed quick ports; these may be suboptimal, however. They
+ * do not include the SINGLE mode modifiers since the MCF5272 does not have a
+ * mode where the device is in control of its addressing.
+ */
+
+/* I/O to memory, 8 bits, mode */
+#define DMA_MODE_READ	              ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 8 bits, mode */
+#define DMA_MODE_WRITE	            ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 16 bits, mode */
+#define DMA_MODE_READ_WORD	        ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 16 bits, mode */
+#define DMA_MODE_WRITE_WORD         ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+/* I/O to memory, 32 bits, mode */
+#define DMA_MODE_READ_LONG	        ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
+/* memory to I/O, 32 bits, mode */
+#define DMA_MODE_WRITE_LONG         ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
+
+#endif /* !defined(CONFIG_M5272) */
+
+#if !defined(CONFIG_M5272)
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned char  *dmapb;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmapb = (unsigned char *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
+  dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned char  *dmabp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+
+  dmabp = (unsigned char *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  /* Clear config errors */
+  dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE;
+
+  /* Set command register */
+  dmawp[MCFDMA_DCR] =
+    MCFDMA_DCR_INT |         /* Enable completion irq */
+    MCFDMA_DCR_CS |          /* Force one xfer per request */
+    MCFDMA_DCR_AA |          /* Enable auto alignment */
+    /* single-address-mode */
+    ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
+    /* sets s_rw (-> r/w) high if Memory to I/0 */
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
+    /* Memory to I/O or I/O to Memory */
+    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
+    /* 32 bit, 16 bit or 8 bit transfers */
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_SSIZE_WORD :
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
+                                   MCFDMA_DCR_SSIZE_BYTE)) |
+    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_DSIZE_WORD :
+     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
+                                   MCFDMA_DCR_DSIZE_BYTE));
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
+	 (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned short *dmawp;
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Determine which address registers are used for memory/device accesses */
+  if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
+    /* Source incrementing, must be memory */
+    dmalp[MCFDMA_SAR] = a;
+    /* Set dest address, must be device */
+    dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
+  } else {
+    /* Destination incrementing, must be memory */
+    dmalp[MCFDMA_DAR] = a;
+    /* Set source address, must be device */
+    dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
+	(int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
+	(int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  dmawp[MCFDMA_BCR] = (unsigned short)count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned short *dmawp;
+  unsigned short count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+  count = dmawp[MCFDMA_BCR];
+  return((int) count);
+}
+#else /* CONFIG_M5272 is defined */
+
+/*
+ * The MCF5272 DMA controller is very different than the controller defined above
+ * in terms of register mapping.  For instance, with the exception of the 16-bit
+ * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
+ *
+ * The big difference, however, is the lack of device-requested DMA.  All modes
+ * are dual address transfer, and there is no 'device' setup or direction bit.
+ * You can DMA between a device and memory, between memory and memory, or even between
+ * two devices directly, with any combination of incrementing and non-incrementing
+ * addresses you choose.  This puts a crimp in distinguishing between the 'device
+ * address' set up by set_dma_device_addr.
+ *
+ * Therefore, there are two options.  One is to use set_dma_addr and set_dma_device_addr,
+ * which will act exactly as above in -- it will look to see if the source is set to
+ * autoincrement, and if so it will make the source use the set_dma_addr value and the
+ * destination the set_dma_device_addr value.  Otherwise the source will be set to the
+ * set_dma_device_addr value and the destination will get the set_dma_addr value.
+ *
+ * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
+ * and make it explicit.  Depending on what you're doing, one of these two should work
+ * for you, but don't mix them in the same transfer setup.
+ */
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+  volatile unsigned int  *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("enable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("disable_dma(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Turn off external requests, and stop any DMA in progress */
+  dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+}
+
+/*
+ * Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ *
+ * This is a NOP for ColdFire. Provide a stub for compatibility.
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+
+  volatile unsigned int   *dmalp;
+  volatile unsigned short *dmawp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
+#endif
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmawp = (unsigned short *) dma_base_addr[dmanr];
+
+  /* Clear config errors */
+  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
+
+  /* Set command register */
+  dmalp[MCFDMA_DMR] =
+    MCFDMA_DMR_RQM_DUAL |         /* Mandatory Request Mode setting */
+    MCFDMA_DMR_DSTT_SD  |         /* Set up addressing types; set to supervisor-data. */
+    MCFDMA_DMR_SRCT_SD  |         /* Set up addressing types; set to supervisor-data. */
+    /* source static-address-mode */
+    ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
+    /* dest static-address-mode */
+    ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
+    /* burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272 */
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
+    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
+
+  dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN;   /* Enable completion interrupts */
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
+         dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
+	 (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
+#endif
+}
+
+/* Set transfer address for specific DMA channel */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+  volatile unsigned int   *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+
+  /* Determine which address registers are used for memory/device accesses */
+  if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
+    /* Source incrementing, must be memory */
+    dmalp[MCFDMA_DSAR] = a;
+    /* Set dest address, must be device */
+    dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
+  } else {
+    /* Destination incrementing, must be memory */
+    dmalp[MCFDMA_DDAR] = a;
+    /* Set source address, must be device */
+    dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
+  }
+
+#ifdef DEBUG_DMA
+  printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
+	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
+	(int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
+	(int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
+#endif
+}
+
+/*
+ * Specific for Coldfire - sets device address.
+ * Should be called after the mode set call, and before set DMA address.
+ */
+static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
+{
+#ifdef DMA_DEBUG
+  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
+#endif
+
+  dma_device_address[dmanr] = a;
+}
+
+/*
+ * NOTE 2: "count" represents _bytes_.
+ *
+ * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+  volatile unsigned int *dmalp;
+
+#ifdef DMA_DEBUG
+  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  dmalp[MCFDMA_DBCR] = count;
+}
+
+/*
+ * Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+  volatile unsigned int *dmalp;
+  unsigned int count;
+
+#ifdef DMA_DEBUG
+  printk("get_dma_residue(dmanr=%d)\n", dmanr);
+#endif
+
+  dmalp = (unsigned int *) dma_base_addr[dmanr];
+  count = dmalp[MCFDMA_DBCR];
+  return(count);
+}
+
+#endif /* !defined(CONFIG_M5272) */
+#endif /* CONFIG_COLDFIRE */
+
+/* it's useless on the m68k, but unfortunately needed by the new
+   bootmem allocator (but this should do it for this) */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
+
+#define MAX_DMA_CHANNELS 8
+
+extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+
+#define isa_dma_bridge_buggy    (0)
+
+#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/dma_mm.h b/arch/m68k/include/asm/dma_mm.h
deleted file mode 100644
index 4240fbc..0000000
--- a/arch/m68k/include/asm/dma_mm.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _M68K_DMA_H
-#define _M68K_DMA_H 1
-
-
-/* it's useless on the m68k, but unfortunately needed by the new
-   bootmem allocator (but this should do it for this) */
-#define MAX_DMA_ADDRESS PAGE_OFFSET
-
-#define MAX_DMA_CHANNELS 8
-
-extern int request_dma(unsigned int dmanr, const char * device_id);	/* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);	/* release it again */
-
-#define isa_dma_bridge_buggy    (0)
-
-#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/dma_no.h b/arch/m68k/include/asm/dma_no.h
deleted file mode 100644
index 939a020..0000000
--- a/arch/m68k/include/asm/dma_no.h
+++ /dev/null
@@ -1,494 +0,0 @@
-#ifndef _M68K_DMA_H
-#define _M68K_DMA_H 1
- 
-//#define	DMA_DEBUG	1
-
-
-#ifdef CONFIG_COLDFIRE
-/*
- * ColdFire DMA Model:
- *   ColdFire DMA supports two forms of DMA: Single and Dual address. Single
- * address mode emits a source address, and expects that the device will either
- * pick up the data (DMA READ) or source data (DMA WRITE). This implies that
- * the device will place data on the correct byte(s) of the data bus, as the
- * memory transactions are always 32 bits. This implies that only 32 bit
- * devices will find single mode transfers useful. Dual address DMA mode
- * performs two cycles: source read and destination write. ColdFire will
- * align the data so that the device will always get the correct bytes, thus
- * is useful for 8 and 16 bit devices. This is the mode that is supported
- * below.
- *
- * AUG/22/2000 : added support for 32-bit Dual-Address-Mode (K) 2000 
- *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
- *
- * AUG/25/2000 : addad support for 8, 16 and 32-bit Single-Address-Mode (K)2000
- *               Oliver Kamphenkel (O.Kamphenkel@tu-bs.de)
- *
- * APR/18/2002 : added proper support for MCF5272 DMA controller.
- *               Arthur Shipkowski (art@videon-central.com)
- */
-
-#include <asm/coldfire.h>
-#include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
-
-/*
- * Set number of channels of DMA on ColdFire for different implementations.
- */
-#if defined(CONFIG_M5249) || defined(CONFIG_M5307) || defined(CONFIG_M5407) || \
-	defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
-#define MAX_M68K_DMA_CHANNELS 4
-#elif defined(CONFIG_M5272)
-#define MAX_M68K_DMA_CHANNELS 1
-#elif defined(CONFIG_M532x)
-#define MAX_M68K_DMA_CHANNELS 0
-#else
-#define MAX_M68K_DMA_CHANNELS 2
-#endif
-
-extern unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
-extern unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
-
-#if !defined(CONFIG_M5272)
-#define DMA_MODE_WRITE_BIT  0x01  /* Memory/IO to IO/Memory select */
-#define DMA_MODE_WORD_BIT   0x02  /* 8 or 16 bit transfers */
-#define DMA_MODE_LONG_BIT   0x04  /* or 32 bit transfers */
-#define DMA_MODE_SINGLE_BIT 0x08  /* single-address-mode */
-
-/* I/O to memory, 8 bits, mode */
-#define DMA_MODE_READ	            0
-/* memory to I/O, 8 bits, mode */
-#define DMA_MODE_WRITE	            1
-/* I/O to memory, 16 bits, mode */
-#define DMA_MODE_READ_WORD          2
-/* memory to I/O, 16 bits, mode */
-#define DMA_MODE_WRITE_WORD         3
-/* I/O to memory, 32 bits, mode */
-#define DMA_MODE_READ_LONG          4
-/* memory to I/O, 32 bits, mode */
-#define DMA_MODE_WRITE_LONG         5
-/* I/O to memory, 8 bits, single-address-mode */     
-#define DMA_MODE_READ_SINGLE        8
-/* memory to I/O, 8 bits, single-address-mode */
-#define DMA_MODE_WRITE_SINGLE       9
-/* I/O to memory, 16 bits, single-address-mode */
-#define DMA_MODE_READ_WORD_SINGLE  10
-/* memory to I/O, 16 bits, single-address-mode */
-#define DMA_MODE_WRITE_WORD_SINGLE 11
-/* I/O to memory, 32 bits, single-address-mode */
-#define DMA_MODE_READ_LONG_SINGLE  12
-/* memory to I/O, 32 bits, single-address-mode */
-#define DMA_MODE_WRITE_LONG_SINGLE 13
-
-#else /* CONFIG_M5272 is defined */
-
-/* Source static-address mode */
-#define DMA_MODE_SRC_SA_BIT 0x01  
-/* Two bits to select between all four modes */
-#define DMA_MODE_SSIZE_MASK 0x06 
-/* Offset to shift bits in */
-#define DMA_MODE_SSIZE_OFF  0x01  
-/* Destination static-address mode */
-#define DMA_MODE_DES_SA_BIT 0x10  
-/* Two bits to select between all four modes */
-#define DMA_MODE_DSIZE_MASK 0x60  
-/* Offset to shift bits in */
-#define DMA_MODE_DSIZE_OFF  0x05
-/* Size modifiers */
-#define DMA_MODE_SIZE_LONG  0x00
-#define DMA_MODE_SIZE_BYTE  0x01
-#define DMA_MODE_SIZE_WORD  0x02
-#define DMA_MODE_SIZE_LINE  0x03
-
-/* 
- * Aliases to help speed quick ports; these may be suboptimal, however. They
- * do not include the SINGLE mode modifiers since the MCF5272 does not have a
- * mode where the device is in control of its addressing.
- */
-
-/* I/O to memory, 8 bits, mode */
-#define DMA_MODE_READ	              ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 8 bits, mode */
-#define DMA_MODE_WRITE	            ((DMA_MODE_SIZE_BYTE << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_BYTE << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-/* I/O to memory, 16 bits, mode */
-#define DMA_MODE_READ_WORD	        ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 16 bits, mode */
-#define DMA_MODE_WRITE_WORD         ((DMA_MODE_SIZE_WORD << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_WORD << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-/* I/O to memory, 32 bits, mode */
-#define DMA_MODE_READ_LONG	        ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_SRC_SA_BIT)
-/* memory to I/O, 32 bits, mode */
-#define DMA_MODE_WRITE_LONG         ((DMA_MODE_SIZE_LONG << DMA_MODE_DSIZE_OFF) | (DMA_MODE_SIZE_LONG << DMA_MODE_SSIZE_OFF) | DMA_DES_SA_BIT)
-
-#endif /* !defined(CONFIG_M5272) */
-
-#if !defined(CONFIG_M5272)
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("enable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmawp[MCFDMA_DCR] |= MCFDMA_DCR_EEXT;
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
-  volatile unsigned short *dmawp;
-  volatile unsigned char  *dmapb;
-
-#ifdef DMA_DEBUG
-  printk("disable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmapb = (unsigned char *) dma_base_addr[dmanr];
-
-  /* Turn off external requests, and stop any DMA in progress */
-  dmawp[MCFDMA_DCR] &= ~MCFDMA_DCR_EEXT;
-  dmapb[MCFDMA_DSR] = MCFDMA_DSR_DONE;
-}
-
-/*
- * Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
- *
- * This is a NOP for ColdFire. Provide a stub for compatibility.
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-
-  volatile unsigned char  *dmabp;
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
-#endif
-
-  dmabp = (unsigned char *) dma_base_addr[dmanr];
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-
-  // Clear config errors
-  dmabp[MCFDMA_DSR] = MCFDMA_DSR_DONE; 
-
-  // Set command register
-  dmawp[MCFDMA_DCR] =
-    MCFDMA_DCR_INT |         // Enable completion irq
-    MCFDMA_DCR_CS |          // Force one xfer per request
-    MCFDMA_DCR_AA |          // Enable auto alignment
-    // single-address-mode
-    ((mode & DMA_MODE_SINGLE_BIT) ? MCFDMA_DCR_SAA : 0) |
-    // sets s_rw (-> r/w) high if Memory to I/0
-    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_S_RW : 0) |
-    // Memory to I/O or I/O to Memory
-    ((mode & DMA_MODE_WRITE_BIT) ? MCFDMA_DCR_SINC : MCFDMA_DCR_DINC) |
-    // 32 bit, 16 bit or 8 bit transfers
-    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_SSIZE_WORD : 
-     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_SSIZE_LONG :
-                                   MCFDMA_DCR_SSIZE_BYTE)) |
-    ((mode & DMA_MODE_WORD_BIT)  ? MCFDMA_DCR_DSIZE_WORD :
-     ((mode & DMA_MODE_LONG_BIT) ? MCFDMA_DCR_DSIZE_LONG :
-                                   MCFDMA_DCR_DSIZE_BYTE));
-
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DSR[%x]=%x DCR[%x]=%x\n", __FILE__, __LINE__,
-         dmanr, (int) &dmabp[MCFDMA_DSR], dmabp[MCFDMA_DSR],
-	 (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR]);
-#endif
-}
-
-/* Set transfer address for specific DMA channel */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
-  volatile unsigned short *dmawp;
-  volatile unsigned int   *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-
-  // Determine which address registers are used for memory/device accesses
-  if (dmawp[MCFDMA_DCR] & MCFDMA_DCR_SINC) {
-    // Source incrementing, must be memory
-    dmalp[MCFDMA_SAR] = a;
-    // Set dest address, must be device
-    dmalp[MCFDMA_DAR] = dma_device_address[dmanr];
-  } else {
-    // Destination incrementing, must be memory
-    dmalp[MCFDMA_DAR] = a;
-    // Set source address, must be device
-    dmalp[MCFDMA_SAR] = dma_device_address[dmanr];
-  }
-
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DCR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
-	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DCR], dmawp[MCFDMA_DCR],
-	(int) &dmalp[MCFDMA_SAR], dmalp[MCFDMA_SAR],
-	(int) &dmalp[MCFDMA_DAR], dmalp[MCFDMA_DAR]);
-#endif
-}
-
-/*
- * Specific for Coldfire - sets device address.
- * Should be called after the mode set call, and before set DMA address.
- */
-static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
-{
-#ifdef DMA_DEBUG
-  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dma_device_address[dmanr] = a;
-}
-
-/*
- * NOTE 2: "count" represents _bytes_.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  dmawp[MCFDMA_BCR] = (unsigned short)count;
-}
-
-/*
- * Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
-  volatile unsigned short *dmawp;
-  unsigned short count;
-
-#ifdef DMA_DEBUG
-  printk("get_dma_residue(dmanr=%d)\n", dmanr);
-#endif
-
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-  count = dmawp[MCFDMA_BCR];
-  return((int) count);
-}
-#else /* CONFIG_M5272 is defined */
-
-/*
- * The MCF5272 DMA controller is very different than the controller defined above
- * in terms of register mapping.  For instance, with the exception of the 16-bit 
- * interrupt register (IRQ#85, for reference), all of the registers are 32-bit.
- *
- * The big difference, however, is the lack of device-requested DMA.  All modes
- * are dual address transfer, and there is no 'device' setup or direction bit.
- * You can DMA between a device and memory, between memory and memory, or even between
- * two devices directly, with any combination of incrementing and non-incrementing
- * addresses you choose.  This puts a crimp in distinguishing between the 'device 
- * address' set up by set_dma_device_addr.
- *
- * Therefore, there are two options.  One is to use set_dma_addr and set_dma_device_addr,
- * which will act exactly as above in -- it will look to see if the source is set to
- * autoincrement, and if so it will make the source use the set_dma_addr value and the
- * destination the set_dma_device_addr value.  Otherwise the source will be set to the
- * set_dma_device_addr value and the destination will get the set_dma_addr value.
- *
- * The other is to use the provided set_dma_src_addr and set_dma_dest_addr functions
- * and make it explicit.  Depending on what you're doing, one of these two should work
- * for you, but don't mix them in the same transfer setup.
- */
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
-  volatile unsigned int  *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("enable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_EN;
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
-  volatile unsigned int   *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("disable_dma(dmanr=%d)\n", dmanr);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-
-  /* Turn off external requests, and stop any DMA in progress */
-  dmalp[MCFDMA_DMR] &= ~MCFDMA_DMR_EN;
-  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET;
-}
-
-/*
- * Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
- *
- * This is a NOP for ColdFire. Provide a stub for compatibility.
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
-
-  volatile unsigned int   *dmalp;
-  volatile unsigned short *dmawp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_mode(dmanr=%d,mode=%d)\n", dmanr, mode);
-#endif
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  dmawp = (unsigned short *) dma_base_addr[dmanr];
-
-  // Clear config errors
-  dmalp[MCFDMA_DMR] |= MCFDMA_DMR_RESET; 
-
-  // Set command register
-  dmalp[MCFDMA_DMR] =
-    MCFDMA_DMR_RQM_DUAL |         // Mandatory Request Mode setting
-    MCFDMA_DMR_DSTT_SD  |         // Set up addressing types; set to supervisor-data.
-    MCFDMA_DMR_SRCT_SD  |         // Set up addressing types; set to supervisor-data. 
-    // source static-address-mode
-    ((mode & DMA_MODE_SRC_SA_BIT) ? MCFDMA_DMR_SRCM_SA : MCFDMA_DMR_SRCM_IA) |
-    // dest static-address-mode
-    ((mode & DMA_MODE_DES_SA_BIT) ? MCFDMA_DMR_DSTM_SA : MCFDMA_DMR_DSTM_IA) |
-    // burst, 32 bit, 16 bit or 8 bit transfers are separately configurable on the MCF5272
-    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_DSTS_OFF) |
-    (((mode & DMA_MODE_SSIZE_MASK) >> DMA_MODE_SSIZE_OFF) << MCFDMA_DMR_SRCS_OFF);
-    
-  dmawp[MCFDMA_DIR] |= MCFDMA_DIR_ASCEN;   /* Enable completion interrupts */
-  
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DMR[%x]=%x DIR[%x]=%x\n", __FILE__, __LINE__,
-         dmanr, (int) &dmalp[MCFDMA_DMR], dmabp[MCFDMA_DMR],
-	 (int) &dmawp[MCFDMA_DIR], dmawp[MCFDMA_DIR]);
-#endif
-}
-
-/* Set transfer address for specific DMA channel */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
-  volatile unsigned int   *dmalp;
-
-#ifdef DMA_DEBUG
-  printk("set_dma_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-
-  // Determine which address registers are used for memory/device accesses
-  if (dmalp[MCFDMA_DMR] & MCFDMA_DMR_SRCM) {
-    // Source incrementing, must be memory
-    dmalp[MCFDMA_DSAR] = a;
-    // Set dest address, must be device
-    dmalp[MCFDMA_DDAR] = dma_device_address[dmanr];
-  } else {
-    // Destination incrementing, must be memory
-    dmalp[MCFDMA_DDAR] = a;
-    // Set source address, must be device
-    dmalp[MCFDMA_DSAR] = dma_device_address[dmanr];
-  }
-
-#ifdef DEBUG_DMA
-  printk("%s(%d): dmanr=%d DMR[%x]=%x SAR[%x]=%08x DAR[%x]=%08x\n",
-	__FILE__, __LINE__, dmanr, (int) &dmawp[MCFDMA_DMR], dmawp[MCFDMA_DMR],
-	(int) &dmalp[MCFDMA_DSAR], dmalp[MCFDMA_DSAR],
-	(int) &dmalp[MCFDMA_DDAR], dmalp[MCFDMA_DDAR]);
-#endif
-}
-
-/*
- * Specific for Coldfire - sets device address.
- * Should be called after the mode set call, and before set DMA address.
- */
-static __inline__ void set_dma_device_addr(unsigned int dmanr, unsigned int a)
-{
-#ifdef DMA_DEBUG
-  printk("set_dma_device_addr(dmanr=%d,a=%x)\n", dmanr, a);
-#endif
-
-  dma_device_address[dmanr] = a;
-}
-
-/*
- * NOTE 2: "count" represents _bytes_.
- *
- * NOTE 3: While a 32-bit register, "count" is only a maximum 24-bit value.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-  volatile unsigned int *dmalp;
-  
-#ifdef DMA_DEBUG
-  printk("set_dma_count(dmanr=%d,count=%d)\n", dmanr, count);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  dmalp[MCFDMA_DBCR] = count;
-}
-
-/*
- * Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
-  volatile unsigned int *dmalp;
-  unsigned int count;
-
-#ifdef DMA_DEBUG
-  printk("get_dma_residue(dmanr=%d)\n", dmanr);
-#endif
-
-  dmalp = (unsigned int *) dma_base_addr[dmanr];
-  count = dmalp[MCFDMA_DBCR];
-  return(count);
-}
-
-#endif /* !defined(CONFIG_M5272) */
-#endif /* CONFIG_COLDFIRE */
- 
-#define MAX_DMA_CHANNELS 8
-
-/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k/coldfire and any
-   occurrence should be flagged as an error.  */
-/* under 2.4 it is actually needed by the new bootmem allocator */
-#define MAX_DMA_ADDRESS PAGE_OFFSET
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char *device_id);	/* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr);	/* release it again */
- 
-#endif /* _M68K_DMA_H */
diff --git a/arch/m68k/include/asm/elia.h b/arch/m68k/include/asm/elia.h
deleted file mode 100644
index e037d4e..0000000
--- a/arch/m68k/include/asm/elia.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/****************************************************************************/
-
-/*
- *	elia.h -- Lineo (formerly Moreton Bay) eLIA platform support.
- *
- *	(C) Copyright 1999-2000, Moreton Bay (www.moreton.com.au)
- *	(C) Copyright 1999-2000, Lineo (www.lineo.com)
- */
-
-/****************************************************************************/
-#ifndef	elia_h
-#define	elia_h
-/****************************************************************************/
-
-#include <asm/coldfire.h>
-
-#ifdef CONFIG_eLIA
-
-/*
- *	The serial port DTR and DCD lines are also on the Parallel I/O
- *	as well, so define those too.
- */
-
-#define	eLIA_DCD1		0x0001
-#define	eLIA_DCD0		0x0002
-#define	eLIA_DTR1		0x0004
-#define	eLIA_DTR0		0x0008
-
-#define	eLIA_PCIRESET		0x0020
-
-/*
- *	Kernel macros to set and unset the LEDs.
- */
-#ifndef __ASSEMBLY__
-extern unsigned short	ppdata;
-#endif /* __ASSEMBLY__ */
-
-#endif	/* CONFIG_eLIA */
-
-/****************************************************************************/
-#endif	/* elia_h */
diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h
new file mode 100644
index 0000000..283214d
--- /dev/null
+++ b/arch/m68k/include/asm/gpio.h
@@ -0,0 +1,238 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 coldfire_gpio_h
+#define coldfire_gpio_h
+
+#include <linux/io.h>
+#include <asm-generic/gpio.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*
+ * The Freescale Coldfire family is quite varied in how they implement GPIO.
+ * Some parts have 8 bit ports, some have 16bit and some have 32bit; some have
+ * only one port, others have multiple ports; some have a single data latch
+ * for both input and output, others have a separate pin data register to read
+ * input; some require a read-modify-write access to change an output, others
+ * have set and clear registers for some of the outputs; Some have all the
+ * GPIOs in a single control area, others have some GPIOs implemented in
+ * different modules.
+ *
+ * This implementation attempts accomodate the differences while presenting
+ * a generic interface that will optimize to as few instructions as possible.
+ */
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+    defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+    defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+
+/* These parts have GPIO organized by 8 bit ports */
+
+#define MCFGPIO_PORTTYPE		u8
+#define MCFGPIO_PORTSIZE		8
+#define mcfgpio_read(port)		__raw_readb(port)
+#define mcfgpio_write(data, port)	__raw_writeb(data, port)
+
+#elif defined(CONFIG_M5307) || defined(CONFIG_M5407) || defined(CONFIG_M5272)
+
+/* These parts have GPIO organized by 16 bit ports */
+
+#define MCFGPIO_PORTTYPE		u16
+#define MCFGPIO_PORTSIZE		16
+#define mcfgpio_read(port)		__raw_readw(port)
+#define mcfgpio_write(data, port)	__raw_writew(data, port)
+
+#elif defined(CONFIG_M5249)
+
+/* These parts have GPIO organized by 32 bit ports */
+
+#define MCFGPIO_PORTTYPE		u32
+#define MCFGPIO_PORTSIZE		32
+#define mcfgpio_read(port)		__raw_readl(port)
+#define mcfgpio_write(data, port)	__raw_writel(data, port)
+
+#endif
+
+#define mcfgpio_bit(gpio)		(1 << ((gpio) %  MCFGPIO_PORTSIZE))
+#define mcfgpio_port(gpio)		((gpio) / MCFGPIO_PORTSIZE)
+
+#if defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+    defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+/*
+ * These parts have an 'Edge' Port module (external interrupt/GPIO) which uses
+ * read-modify-write to change an output and a GPIO module which has separate
+ * set/clr registers to directly change outputs with a single write access.
+ */
+#if defined(CONFIG_M528x)
+/*
+ * The 528x also has GPIOs in other modules (GPT, QADC) which use
+ * read-modify-write as well as those controlled by the EPORT and GPIO modules.
+ */
+#define MCFGPIO_SCR_START		40
+#else
+#define MCFGPIO_SCR_START		8
+#endif
+
+#define MCFGPIO_SETR_PORT(gpio)		(MCFGPIO_SETR + \
+					mcfgpio_port(gpio - MCFGPIO_SCR_START))
+
+#define MCFGPIO_CLRR_PORT(gpio)		(MCFGPIO_CLRR + \
+					mcfgpio_port(gpio - MCFGPIO_SCR_START))
+#else
+
+#define MCFGPIO_SCR_START		MCFGPIO_PIN_MAX
+/* with MCFGPIO_SCR == MCFGPIO_PIN_MAX, these will be optimized away */
+#define MCFGPIO_SETR_PORT(gpio)		0
+#define MCFGPIO_CLRR_PORT(gpio)		0
+
+#endif
+/*
+ * Coldfire specific helper functions
+ */
+
+/* return the port pin data register for a gpio */
+static inline u32 __mcf_gpio_ppdr(unsigned gpio)
+{
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+    defined(CONFIG_M5307) || defined(CONFIG_M5407)
+	return MCFSIM_PADAT;
+#elif defined(CONFIG_M5272)
+	if (gpio < 16)
+		return MCFSIM_PADAT;
+	else if (gpio < 32)
+		return MCFSIM_PBDAT;
+	else
+		return MCFSIM_PCDAT;
+#elif defined(CONFIG_M5249)
+	if (gpio < 32)
+		return MCFSIM2_GPIOREAD;
+	else
+		return MCFSIM2_GPIO1READ;
+#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+	if (gpio < 8)
+		return MCFEPORT_EPPDR;
+#if defined(CONFIG_M528x)
+	else if (gpio < 16)
+		return MCFGPTA_GPTPORT;
+	else if (gpio < 24)
+		return MCFGPTB_GPTPORT;
+	else if (gpio < 32)
+		return MCFQADC_PORTQA;
+	else if (gpio < 40)
+		return MCFQADC_PORTQB;
+#endif
+	else
+		return MCFGPIO_PPDR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
+#endif
+}
+
+/* return the port output data register for a gpio */
+static inline u32 __mcf_gpio_podr(unsigned gpio)
+{
+#if defined(CONFIG_M5206) || defined(CONFIG_M5206e) || \
+    defined(CONFIG_M5307) || defined(CONFIG_M5407)
+	return MCFSIM_PADAT;
+#elif defined(CONFIG_M5272)
+	if (gpio < 16)
+		return MCFSIM_PADAT;
+	else if (gpio < 32)
+		return MCFSIM_PBDAT;
+	else
+		return MCFSIM_PCDAT;
+#elif defined(CONFIG_M5249)
+	if (gpio < 32)
+		return MCFSIM2_GPIOWRITE;
+	else
+		return MCFSIM2_GPIO1WRITE;
+#elif defined(CONFIG_M520x) || defined(CONFIG_M523x) || \
+      defined(CONFIG_M527x) || defined(CONFIG_M528x) || defined(CONFIG_M532x)
+	if (gpio < 8)
+		return MCFEPORT_EPDR;
+#if defined(CONFIG_M528x)
+	else if (gpio < 16)
+		return MCFGPTA_GPTPORT;
+	else if (gpio < 24)
+		return MCFGPTB_GPTPORT;
+	else if (gpio < 32)
+		return MCFQADC_PORTQA;
+	else if (gpio < 40)
+		return MCFQADC_PORTQB;
+#endif
+	else
+		return MCFGPIO_PODR + mcfgpio_port(gpio - MCFGPIO_SCR_START);
+#endif
+}
+
+/*
+ * The Generic GPIO functions
+ *
+ * If the gpio is a compile time constant and is one of the Coldfire gpios,
+ * use the inline version, otherwise dispatch thru gpiolib.
+ */
+
+static inline int gpio_get_value(unsigned gpio)
+{
+	if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX)
+		return mcfgpio_read(__mcf_gpio_ppdr(gpio)) & mcfgpio_bit(gpio);
+	else
+		return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+	if (__builtin_constant_p(gpio) && gpio < MCFGPIO_PIN_MAX) {
+		if (gpio < MCFGPIO_SCR_START) {
+			unsigned long flags;
+			MCFGPIO_PORTTYPE data;
+
+			local_irq_save(flags);
+			data = mcfgpio_read(__mcf_gpio_podr(gpio));
+			if (value)
+				data |= mcfgpio_bit(gpio);
+			else
+				data &= ~mcfgpio_bit(gpio);
+			mcfgpio_write(data, __mcf_gpio_podr(gpio));
+			local_irq_restore(flags);
+		} else {
+			if (value)
+				mcfgpio_write(mcfgpio_bit(gpio),
+						MCFGPIO_SETR_PORT(gpio));
+			else
+				mcfgpio_write(~mcfgpio_bit(gpio),
+						MCFGPIO_CLRR_PORT(gpio));
+		}
+	} else
+		__gpio_set_value(gpio, value);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+	return (gpio < MCFGPIO_IRQ_MAX) ? gpio + MCFGPIO_IRQ_VECBASE : -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+	return (irq >= MCFGPIO_IRQ_VECBASE &&
+		irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) ?
+		irq - MCFGPIO_IRQ_VECBASE : -ENXIO;
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+	return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio);
+}
+
+#endif
diff --git a/arch/m68k/include/asm/hardirq_no.h b/arch/m68k/include/asm/hardirq_no.h
index bfad281..b44b14b 100644
--- a/arch/m68k/include/asm/hardirq_no.h
+++ b/arch/m68k/include/asm/hardirq_no.h
@@ -1,16 +1,8 @@
 #ifndef __M68K_HARDIRQ_H
 #define __M68K_HARDIRQ_H
 
-#include <linux/cache.h>
-#include <linux/threads.h>
 #include <asm/irq.h>
 
-typedef struct {
-	unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-
 #define HARDIRQ_BITS	8
 
 /*
@@ -22,6 +14,6 @@ typedef struct {
 # error HARDIRQ_BITS is too low!
 #endif
 
-void ack_bad_irq(unsigned int irq);
+#include <asm-generic/hardirq.h>
 
 #endif /* __M68K_HARDIRQ_H */
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index 6adef1e..7f57436 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -134,7 +134,7 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
 #define insw(a,b,l) io_insw(a,b,l)
 #define insl(a,b,l) io_insl(a,b,l)
 
-#define IO_SPACE_LIMIT 0xffff
+#define IO_SPACE_LIMIT 0xffffffff
 
 
 /* Values for nocacheflag and cmode */
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index d031416..907eff1 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -1,5 +1,134 @@
-#ifdef __uClinux__
-#include "irq_no.h"
+#ifndef _M68K_IRQ_H_
+#define _M68K_IRQ_H_
+
+/*
+ * This should be the same as the max(NUM_X_SOURCES) for all the
+ * different m68k hosts compiled into the kernel.
+ * Currently the Atari has 72 and the Amiga 24, but if both are
+ * supported in the kernel it is better to make room for 72.
+ */
+#if defined(CONFIG_COLDFIRE)
+#define NR_IRQS 256
+#elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
+#define NR_IRQS 200
+#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#define NR_IRQS 72
+#elif defined(CONFIG_Q40)
+#define NR_IRQS	43
+#elif defined(CONFIG_AMIGA) || !defined(CONFIG_MMU)
+#define NR_IRQS	32
+#elif defined(CONFIG_APOLLO)
+#define NR_IRQS	24
+#elif defined(CONFIG_HP300)
+#define NR_IRQS	8
 #else
-#include "irq_mm.h"
+#define NR_IRQS	0
 #endif
+
+#ifdef CONFIG_MMU
+
+#include <linux/linkage.h>
+#include <linux/hardirq.h>
+#include <linux/irqreturn.h>
+#include <linux/spinlock_types.h>
+
+/*
+ * 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
+
+/*
+ * Interrupt source definitions
+ * General interrupt sources are the level 1-7.
+ * Adding an interrupt service routine for one of these sources
+ * results in the addition of that routine to a chain of routines.
+ * Each one is called in succession.  Each individual interrupt
+ * service routine should determine if the device associated with
+ * that routine requires service.
+ */
+
+#define IRQ_SPURIOUS	0
+
+#define IRQ_AUTO_1	1	/* level 1 interrupt */
+#define IRQ_AUTO_2	2	/* level 2 interrupt */
+#define IRQ_AUTO_3	3	/* level 3 interrupt */
+#define IRQ_AUTO_4	4	/* level 4 interrupt */
+#define IRQ_AUTO_5	5	/* level 5 interrupt */
+#define IRQ_AUTO_6	6	/* level 6 interrupt */
+#define IRQ_AUTO_7	7	/* level 7 interrupt (non-maskable) */
+
+#define IRQ_USER	8
+
+extern unsigned int irq_canonicalize(unsigned int irq);
+
+struct pt_regs;
+
+/*
+ * various flags for request_irq() - the Amiga now uses the standard
+ * mechanism like all other architectures - IRQF_DISABLED and
+ * IRQF_SHARED are your friends.
+ */
+#ifndef MACH_AMIGA_ONLY
+#define IRQ_FLG_LOCK	(0x0001)	/* handler is not replaceable	*/
+#define IRQ_FLG_REPLACE	(0x0002)	/* replace existing handler	*/
+#define IRQ_FLG_FAST	(0x0004)
+#define IRQ_FLG_SLOW	(0x0008)
+#define IRQ_FLG_STD	(0x8000)	/* internally used		*/
+#endif
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+	irqreturn_t	(*handler)(int, void *);
+	void		*dev_id;
+	struct irq_node *next;
+	unsigned long	flags;
+	const char	*devname;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+struct irq_handler {
+	int		(*handler)(int, void *);
+	unsigned long	flags;
+	void		*dev_id;
+	const char	*devname;
+};
+
+struct irq_controller {
+	const char *name;
+	spinlock_t lock;
+	int (*startup)(unsigned int irq);
+	void (*shutdown)(unsigned int irq);
+	void (*enable)(unsigned int irq);
+	void (*disable)(unsigned int irq);
+};
+
+extern int m68k_irq_startup(unsigned int);
+extern void m68k_irq_shutdown(unsigned int);
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
+extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
+				      void (*handler)(unsigned int, struct pt_regs *));
+extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
+
+asmlinkage void m68k_handle_int(unsigned int);
+asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
+
+#else
+#define irq_canonicalize(irq)  (irq)
+#endif /* CONFIG_MMU */
+
+#endif /* _M68K_IRQ_H_ */
diff --git a/arch/m68k/include/asm/irq_mm.h b/arch/m68k/include/asm/irq_mm.h
deleted file mode 100644
index 0cab42c..0000000
--- a/arch/m68k/include/asm/irq_mm.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef _M68K_IRQ_H_
-#define _M68K_IRQ_H_
-
-#include <linux/linkage.h>
-#include <linux/hardirq.h>
-#include <linux/irqreturn.h>
-#include <linux/spinlock_types.h>
-
-/*
- * This should be the same as the max(NUM_X_SOURCES) for all the
- * different m68k hosts compiled into the kernel.
- * Currently the Atari has 72 and the Amiga 24, but if both are
- * supported in the kernel it is better to make room for 72.
- */
-#if defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
-#define NR_IRQS 200
-#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
-#define NR_IRQS 72
-#elif defined(CONFIG_Q40)
-#define NR_IRQS	43
-#elif defined(CONFIG_AMIGA)
-#define NR_IRQS	32
-#elif defined(CONFIG_APOLLO)
-#define NR_IRQS	24
-#elif defined(CONFIG_HP300)
-#define NR_IRQS	8
-#else
-#define NR_IRQS	0
-#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) < NR_IRQS
-# error HARDIRQ_BITS is too low!
-#endif
-
-/*
- * Interrupt source definitions
- * General interrupt sources are the level 1-7.
- * Adding an interrupt service routine for one of these sources
- * results in the addition of that routine to a chain of routines.
- * Each one is called in succession.  Each individual interrupt
- * service routine should determine if the device associated with
- * that routine requires service.
- */
-
-#define IRQ_SPURIOUS	0
-
-#define IRQ_AUTO_1	1	/* level 1 interrupt */
-#define IRQ_AUTO_2	2	/* level 2 interrupt */
-#define IRQ_AUTO_3	3	/* level 3 interrupt */
-#define IRQ_AUTO_4	4	/* level 4 interrupt */
-#define IRQ_AUTO_5	5	/* level 5 interrupt */
-#define IRQ_AUTO_6	6	/* level 6 interrupt */
-#define IRQ_AUTO_7	7	/* level 7 interrupt (non-maskable) */
-
-#define IRQ_USER	8
-
-extern unsigned int irq_canonicalize(unsigned int irq);
-
-struct pt_regs;
-
-/*
- * various flags for request_irq() - the Amiga now uses the standard
- * mechanism like all other architectures - IRQF_DISABLED and
- * IRQF_SHARED are your friends.
- */
-#ifndef MACH_AMIGA_ONLY
-#define IRQ_FLG_LOCK	(0x0001)	/* handler is not replaceable	*/
-#define IRQ_FLG_REPLACE	(0x0002)	/* replace existing handler	*/
-#define IRQ_FLG_FAST	(0x0004)
-#define IRQ_FLG_SLOW	(0x0008)
-#define IRQ_FLG_STD	(0x8000)	/* internally used		*/
-#endif
-
-/*
- * This structure is used to chain together the ISRs for a particular
- * interrupt source (if it supports chaining).
- */
-typedef struct irq_node {
-	irqreturn_t	(*handler)(int, void *);
-	void		*dev_id;
-	struct irq_node *next;
-	unsigned long	flags;
-	const char	*devname;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-struct irq_handler {
-	int		(*handler)(int, void *);
-	unsigned long	flags;
-	void		*dev_id;
-	const char	*devname;
-};
-
-struct irq_controller {
-	const char *name;
-	spinlock_t lock;
-	int (*startup)(unsigned int irq);
-	void (*shutdown)(unsigned int irq);
-	void (*enable)(unsigned int irq);
-	void (*disable)(unsigned int irq);
-};
-
-extern int m68k_irq_startup(unsigned int);
-extern void m68k_irq_shutdown(unsigned int);
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
-
-extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
-				      void (*handler)(unsigned int, struct pt_regs *));
-extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int);
-
-asmlinkage void m68k_handle_int(unsigned int);
-asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *);
-
-#endif /* _M68K_IRQ_H_ */
diff --git a/arch/m68k/include/asm/irq_no.h b/arch/m68k/include/asm/irq_no.h
deleted file mode 100644
index 9373c31..0000000
--- a/arch/m68k/include/asm/irq_no.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _M68KNOMMU_IRQ_H_
-#define _M68KNOMMU_IRQ_H_
-
-#ifdef CONFIG_COLDFIRE
-/*
- * On the ColdFire we keep track of all vectors. That way drivers
- * can register whatever vector number they wish, and we can deal
- * with it.
- */
-#define	SYS_IRQS	256
-#define	NR_IRQS		SYS_IRQS
-
-#else
-
-/*
- * # of m68k interrupts
- */
-#define SYS_IRQS	8
-#define NR_IRQS		(24 + SYS_IRQS)
-
-#endif /* CONFIG_COLDFIRE */
-
-
-#define irq_canonicalize(irq)	(irq)
-
-#endif /* _M68KNOMMU_IRQ_H_ */
diff --git a/arch/m68k/include/asm/m5206sim.h b/arch/m68k/include/asm/m5206sim.h
index 7e3594d..9c384e2 100644
--- a/arch/m68k/include/asm/m5206sim.h
+++ b/arch/m68k/include/asm/m5206sim.h
@@ -85,8 +85,21 @@
 #define	MCFSIM_PAR		0xcb		/* Pin Assignment reg (r/w) */
 #endif
 
-#define	MCFSIM_PADDR		0x1c5		/* Parallel Direction (r/w) */
-#define	MCFSIM_PADAT		0x1c9		/* Parallel Port Value (r/w) */
+#define	MCFSIM_PADDR		(MCF_MBAR + 0x1c5)	/* Parallel Direction (r/w) */
+#define	MCFSIM_PADAT		(MCF_MBAR + 0x1c9)	/* Parallel Port Value (r/w) */
+
+/*
+ *	Define system peripheral IRQ usage.
+ */
+#define	MCF_IRQ_TIMER		30		/* Timer0, Level 6 */
+#define	MCF_IRQ_PROFILER	31		/* Timer1, Level 7 */
+
+/*
+ * Generic GPIO
+ */
+#define MCFGPIO_PIN_MAX		8
+#define MCFGPIO_IRQ_VECBASE	-1
+#define MCFGPIO_IRQ_MAX		-1
 
 /*
  *	Some symbol defines for the Parallel Port Pin Assignment Register
@@ -111,21 +124,5 @@
 #define	MCFSIM_DMA2ICR		MCFSIM_ICR15	/* DMA 2 ICR */
 #endif
 
-#if defined(CONFIG_M5206e)
-#define	MCFSIM_IMR_MASKALL	0xfffe		/* All SIM intr sources */
-#endif
-
-/*
- *	Macro to get and set IMR register. It is 16 bits on the 5206.
- */
-#define	mcf_getimr()		\
-	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR))
-
-#define	mcf_setimr(imr)		\
-	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IMR)) = (imr)
-
-#define	mcf_getipr()		\
-	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_IPR))
-
 /****************************************************************************/
 #endif	/* m5206sim_h */
diff --git a/arch/m68k/include/asm/m520xsim.h b/arch/m68k/include/asm/m520xsim.h
index 83bbcfd..ed2b69b 100644
--- a/arch/m68k/include/asm/m520xsim.h
+++ b/arch/m68k/include/asm/m520xsim.h
@@ -11,9 +11,8 @@
 #define m520xsim_h
 /****************************************************************************/
 
-
 /*
- *  Define the 5282 SIM register set addresses.
+ *  Define the 520x SIM register set addresses.
  */
 #define MCFICM_INTC0        0x48000     /* Base for Interrupt Ctrl 0 */
 #define MCFINTC_IPRH        0x00        /* Interrupt pending 32-63 */
@@ -22,8 +21,22 @@
 #define MCFINTC_IMRL        0x0c        /* Interrupt mask 1-31 */
 #define MCFINTC_INTFRCH     0x10        /* Interrupt force 32-63 */
 #define MCFINTC_INTFRCL     0x14        /* Interrupt force 1-31 */
+#define MCFINTC_SIMR        0x1c        /* Set interrupt mask 0-63 */
+#define MCFINTC_CIMR        0x1d        /* Clear interrupt mask 0-63 */
 #define MCFINTC_ICR0        0x40        /* Base ICR register */
 
+/*
+ *  The common interrupt controller code just wants to know the absolute
+ *  address to the SIMR and CIMR registers (not offsets into IPSBAR).
+ *  The 520x family only has a single INTC unit.
+ */
+#define MCFINTC0_SIMR       (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_SIMR)
+#define MCFINTC0_CIMR       (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_CIMR)
+#define	MCFINTC0_ICR0       (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0)
+#define MCFINTC1_SIMR       (0)
+#define MCFINTC1_CIMR       (0)
+#define	MCFINTC1_ICR0       (0)
+
 #define MCFINT_VECBASE      64
 #define MCFINT_UART0        26          /* Interrupt number for UART0 */
 #define MCFINT_UART1        27          /* Interrupt number for UART1 */
@@ -41,6 +54,62 @@
 #define MCFSIM_SDCS0        0x000a8110	/* SDRAM Chip Select 0 Configuration */
 #define MCFSIM_SDCS1        0x000a8114	/* SDRAM Chip Select 1 Configuration */
 
+#define MCFEPORT_EPDDR			0xFC088002
+#define MCFEPORT_EPDR			0xFC088004
+#define MCFEPORT_EPPDR			0xFC088005
+
+#define MCFGPIO_PODR_BUSCTL		0xFC0A4000
+#define MCFGPIO_PODR_BE			0xFC0A4001
+#define MCFGPIO_PODR_CS			0xFC0A4002
+#define MCFGPIO_PODR_FECI2C		0xFC0A4003
+#define MCFGPIO_PODR_QSPI		0xFC0A4004
+#define MCFGPIO_PODR_TIMER		0xFC0A4005
+#define MCFGPIO_PODR_UART		0xFC0A4006
+#define MCFGPIO_PODR_FECH		0xFC0A4007
+#define MCFGPIO_PODR_FECL		0xFC0A4008
+
+#define MCFGPIO_PDDR_BUSCTL		0xFC0A400C
+#define MCFGPIO_PDDR_BE			0xFC0A400D
+#define MCFGPIO_PDDR_CS			0xFC0A400E
+#define MCFGPIO_PDDR_FECI2C		0xFC0A400F
+#define MCFGPIO_PDDR_QSPI		0xFC0A4010
+#define MCFGPIO_PDDR_TIMER		0xFC0A4011
+#define MCFGPIO_PDDR_UART		0xFC0A4012
+#define MCFGPIO_PDDR_FECH		0xFC0A4013
+#define MCFGPIO_PDDR_FECL		0xFC0A4014
+
+#define MCFGPIO_PPDSDR_BUSCTL		0xFC0A401A
+#define MCFGPIO_PPDSDR_BE		0xFC0A401B
+#define MCFGPIO_PPDSDR_CS		0xFC0A401C
+#define MCFGPIO_PPDSDR_FECI2C		0xFC0A401D
+#define MCFGPIO_PPDSDR_QSPI		0xFC0A401E
+#define MCFGPIO_PPDSDR_TIMER		0xFC0A401F
+#define MCFGPIO_PPDSDR_UART		0xFC0A4021
+#define MCFGPIO_PPDSDR_FECH		0xFC0A4021
+#define MCFGPIO_PPDSDR_FECL		0xFC0A4022
+
+#define MCFGPIO_PCLRR_BUSCTL		0xFC0A4024
+#define MCFGPIO_PCLRR_BE		0xFC0A4025
+#define MCFGPIO_PCLRR_CS		0xFC0A4026
+#define MCFGPIO_PCLRR_FECI2C		0xFC0A4027
+#define MCFGPIO_PCLRR_QSPI		0xFC0A4028
+#define MCFGPIO_PCLRR_TIMER		0xFC0A4029
+#define MCFGPIO_PCLRR_UART		0xFC0A402A
+#define MCFGPIO_PCLRR_FECH		0xFC0A402B
+#define MCFGPIO_PCLRR_FECL		0xFC0A402C
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR			MCFGPIO_PODR_BUSCTL
+#define MCFGPIO_PDDR			MCFGPIO_PDDR_BUSCTL
+#define MCFGPIO_PPDR			MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_SETR			MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_CLRR			MCFGPIO_PCLRR_BUSCTL
+
+#define MCFGPIO_PIN_MAX			80
+#define MCFGPIO_IRQ_MAX			8
+#define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
+/****************************************************************************/
 
 #define MCF_GPIO_PAR_UART                   (0xA4036)
 #define MCF_GPIO_PAR_FECI2C                 (0xA4033)
@@ -55,10 +124,6 @@
 #define MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2   (0x02)
 #define MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2   (0x04)
 
-#define ICR_INTRCONF		0x05
-#define MCFPIT_IMR		MCFINTC_IMRL
-#define MCFPIT_IMR_IBIT		(1 << MCFINT_PIT1)
-
 /*
  *  Reset Controll Unit.
  */
diff --git a/arch/m68k/include/asm/m523xsim.h b/arch/m68k/include/asm/m523xsim.h
index 55183b5..a34894c 100644
--- a/arch/m68k/include/asm/m523xsim.h
+++ b/arch/m68k/include/asm/m523xsim.h
@@ -50,5 +50,82 @@
 #define	MCF_RCR_SWRESET		0x80		/* Software reset bit */
 #define	MCF_RCR_FRCSTOUT	0x40		/* Force external reset */
 
+#define MCFGPIO_PODR_ADDR	(MCF_IPSBAR + 0x100000)
+#define MCFGPIO_PODR_DATAH	(MCF_IPSBAR + 0x100001)
+#define MCFGPIO_PODR_DATAL	(MCF_IPSBAR + 0x100002)
+#define MCFGPIO_PODR_BUSCTL	(MCF_IPSBAR + 0x100003)
+#define MCFGPIO_PODR_BS		(MCF_IPSBAR + 0x100004)
+#define MCFGPIO_PODR_CS		(MCF_IPSBAR + 0x100005)
+#define MCFGPIO_PODR_SDRAM	(MCF_IPSBAR + 0x100006)
+#define MCFGPIO_PODR_FECI2C	(MCF_IPSBAR + 0x100007)
+#define MCFGPIO_PODR_UARTH	(MCF_IPSBAR + 0x100008)
+#define MCFGPIO_PODR_UARTL	(MCF_IPSBAR + 0x100009)
+#define MCFGPIO_PODR_QSPI	(MCF_IPSBAR + 0x10000A)
+#define MCFGPIO_PODR_TIMER	(MCF_IPSBAR + 0x10000B)
+#define MCFGPIO_PODR_ETPU	(MCF_IPSBAR + 0x10000C)
+
+#define MCFGPIO_PDDR_ADDR	(MCF_IPSBAR + 0x100010)
+#define MCFGPIO_PDDR_DATAH	(MCF_IPSBAR + 0x100011)
+#define MCFGPIO_PDDR_DATAL	(MCF_IPSBAR + 0x100012)
+#define MCFGPIO_PDDR_BUSCTL	(MCF_IPSBAR + 0x100013)
+#define MCFGPIO_PDDR_BS		(MCF_IPSBAR + 0x100014)
+#define MCFGPIO_PDDR_CS		(MCF_IPSBAR + 0x100015)
+#define MCFGPIO_PDDR_SDRAM	(MCF_IPSBAR + 0x100016)
+#define MCFGPIO_PDDR_FECI2C	(MCF_IPSBAR + 0x100017)
+#define MCFGPIO_PDDR_UARTH	(MCF_IPSBAR + 0x100018)
+#define MCFGPIO_PDDR_UARTL	(MCF_IPSBAR + 0x100019)
+#define MCFGPIO_PDDR_QSPI	(MCF_IPSBAR + 0x10001A)
+#define MCFGPIO_PDDR_TIMER	(MCF_IPSBAR + 0x10001B)
+#define MCFGPIO_PDDR_ETPU	(MCF_IPSBAR + 0x10001C)
+
+#define MCFGPIO_PPDSDR_ADDR	(MCF_IPSBAR + 0x100020)
+#define MCFGPIO_PPDSDR_DATAH	(MCF_IPSBAR + 0x100021)
+#define MCFGPIO_PPDSDR_DATAL	(MCF_IPSBAR + 0x100022)
+#define MCFGPIO_PPDSDR_BUSCTL	(MCF_IPSBAR + 0x100023)
+#define MCFGPIO_PPDSDR_BS	(MCF_IPSBAR + 0x100024)
+#define MCFGPIO_PPDSDR_CS	(MCF_IPSBAR + 0x100025)
+#define MCFGPIO_PPDSDR_SDRAM	(MCF_IPSBAR + 0x100026)
+#define MCFGPIO_PPDSDR_FECI2C	(MCF_IPSBAR + 0x100027)
+#define MCFGPIO_PPDSDR_UARTH	(MCF_IPSBAR + 0x100028)
+#define MCFGPIO_PPDSDR_UARTL	(MCF_IPSBAR + 0x100029)
+#define MCFGPIO_PPDSDR_QSPI	(MCF_IPSBAR + 0x10002A)
+#define MCFGPIO_PPDSDR_TIMER	(MCF_IPSBAR + 0x10002B)
+#define MCFGPIO_PPDSDR_ETPU	(MCF_IPSBAR + 0x10002C)
+
+#define MCFGPIO_PCLRR_ADDR	(MCF_IPSBAR + 0x100030)
+#define MCFGPIO_PCLRR_DATAH	(MCF_IPSBAR + 0x100031)
+#define MCFGPIO_PCLRR_DATAL	(MCF_IPSBAR + 0x100032)
+#define MCFGPIO_PCLRR_BUSCTL	(MCF_IPSBAR + 0x100033)
+#define MCFGPIO_PCLRR_BS	(MCF_IPSBAR + 0x100034)
+#define MCFGPIO_PCLRR_CS	(MCF_IPSBAR + 0x100035)
+#define MCFGPIO_PCLRR_SDRAM	(MCF_IPSBAR + 0x100036)
+#define MCFGPIO_PCLRR_FECI2C	(MCF_IPSBAR + 0x100037)
+#define MCFGPIO_PCLRR_UARTH	(MCF_IPSBAR + 0x100038)
+#define MCFGPIO_PCLRR_UARTL	(MCF_IPSBAR + 0x100039)
+#define MCFGPIO_PCLRR_QSPI	(MCF_IPSBAR + 0x10003A)
+#define MCFGPIO_PCLRR_TIMER	(MCF_IPSBAR + 0x10003B)
+#define MCFGPIO_PCLRR_ETPU	(MCF_IPSBAR + 0x10003C)
+
+/*
+ * EPort
+ */
+
+#define MCFEPORT_EPDDR		(MCF_IPSBAR + 0x130002)
+#define MCFEPORT_EPDR		(MCF_IPSBAR + 0x130004)
+#define MCFEPORT_EPPDR		(MCF_IPSBAR + 0x130005)
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR			MCFGPIO_PODR_ADDR
+#define MCFGPIO_PDDR			MCFGPIO_PDDR_ADDR
+#define MCFGPIO_PPDR			MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_SETR			MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_CLRR			MCFGPIO_PCLRR_ADDR
+
+#define MCFGPIO_PIN_MAX			107
+#define MCFGPIO_IRQ_MAX			8
+#define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
+
 /****************************************************************************/
 #endif	/* m523xsim_h */
diff --git a/arch/m68k/include/asm/m5249sim.h b/arch/m68k/include/asm/m5249sim.h
index 366eb86..14bce87 100644
--- a/arch/m68k/include/asm/m5249sim.h
+++ b/arch/m68k/include/asm/m5249sim.h
@@ -71,16 +71,22 @@
 #define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
 
 /*
+ *	Define system peripheral IRQ usage.
+ */
+#define	MCF_IRQ_TIMER		30		/* Timer0, Level 6 */
+#define	MCF_IRQ_PROFILER	31		/* Timer1, Level 7 */
+
+/*
  *	General purpose IO registers (in MBAR2).
  */
-#define	MCFSIM2_GPIOREAD	0x0		/* GPIO read values */
-#define	MCFSIM2_GPIOWRITE	0x4		/* GPIO write values */
-#define	MCFSIM2_GPIOENABLE	0x8		/* GPIO enabled */
-#define	MCFSIM2_GPIOFUNC	0xc		/* GPIO function */
-#define	MCFSIM2_GPIO1READ	0xb0		/* GPIO1 read values */
-#define	MCFSIM2_GPIO1WRITE	0xb4		/* GPIO1 write values */
-#define	MCFSIM2_GPIO1ENABLE	0xb8		/* GPIO1 enabled */
-#define	MCFSIM2_GPIO1FUNC	0xbc		/* GPIO1 function */
+#define	MCFSIM2_GPIOREAD	(MCF_MBAR2 + 0x000)	/* GPIO read values */
+#define	MCFSIM2_GPIOWRITE	(MCF_MBAR2 + 0x004)	/* GPIO write values */
+#define	MCFSIM2_GPIOENABLE	(MCF_MBAR2 + 0x008)	/* GPIO enabled */
+#define	MCFSIM2_GPIOFUNC	(MCF_MBAR2 + 0x00C)	/* GPIO function */
+#define	MCFSIM2_GPIO1READ	(MCF_MBAR2 + 0x0B0)	/* GPIO1 read values */
+#define	MCFSIM2_GPIO1WRITE	(MCF_MBAR2 + 0x0B4)	/* GPIO1 write values */
+#define	MCFSIM2_GPIO1ENABLE	(MCF_MBAR2 + 0x0B8)	/* GPIO1 enabled */
+#define	MCFSIM2_GPIO1FUNC	(MCF_MBAR2 + 0x0BC)	/* GPIO1 function */
 
 #define	MCFSIM2_GPIOINTSTAT	0xc0		/* GPIO interrupt status */
 #define	MCFSIM2_GPIOINTCLEAR	0xc0		/* GPIO interrupt clear */
@@ -100,20 +106,28 @@
 #define	MCFSIM2_IDECONFIG1	0x18c		/* IDEconfig1 */
 #define	MCFSIM2_IDECONFIG2	0x190		/* IDEconfig2 */
 
-
 /*
- *	Macro to set IMR register. It is 32 bits on the 5249.
+ * Define the base interrupt for the second interrupt controller.
+ * We set it to 128, out of the way of the base interrupts, and plenty
+ * of room for its 64 interrupts.
  */
-#define	MCFSIM_IMR_MASKALL	0x7fffe		/* All SIM intr sources */
+#define	MCFINTC2_VECBASE	128
 
-#define	mcf_getimr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
+#define	MCFINTC2_GPIOIRQ0	(MCFINTC2_VECBASE + 32)
+#define	MCFINTC2_GPIOIRQ1	(MCFINTC2_VECBASE + 33)
+#define	MCFINTC2_GPIOIRQ2	(MCFINTC2_VECBASE + 34)
+#define	MCFINTC2_GPIOIRQ3	(MCFINTC2_VECBASE + 35)
+#define	MCFINTC2_GPIOIRQ4	(MCFINTC2_VECBASE + 36)
+#define	MCFINTC2_GPIOIRQ5	(MCFINTC2_VECBASE + 37)
+#define	MCFINTC2_GPIOIRQ6	(MCFINTC2_VECBASE + 38)
+#define	MCFINTC2_GPIOIRQ7	(MCFINTC2_VECBASE + 39)
 
-#define	mcf_setimr(imr)		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define	mcf_getipr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX		64
+#define MCFGPIO_IRQ_MAX		-1
+#define MCFGPIO_IRQ_VECBASE	-1
 
 /****************************************************************************/
 
@@ -137,9 +151,9 @@
 	subql	#1,%a1				/* get MBAR2 address in a1 */
 
 	/*
-	 *      Move secondary interrupts to base at 128.
+	 *      Move secondary interrupts to their base (128).
 	 */
-	moveb	#0x80,%d0
+	moveb	#MCFINTC2_VECBASE,%d0
 	moveb	%d0,0x16b(%a1)			/* interrupt base register */
 
 	/*
diff --git a/arch/m68k/include/asm/m5272sim.h b/arch/m68k/include/asm/m5272sim.h
index 6217edc..df3332c 100644
--- a/arch/m68k/include/asm/m5272sim.h
+++ b/arch/m68k/include/asm/m5272sim.h
@@ -12,7 +12,6 @@
 #define	m5272sim_h
 /****************************************************************************/
 
-
 /*
  *	Define the 5272 SIM register set addresses.
  */
@@ -63,16 +62,59 @@
 #define	MCFSIM_DCMR1		0x5c		/* DRAM 1 Mask reg (r/w) */
 #define	MCFSIM_DCCR1		0x63		/* DRAM 1 Control reg (r/w) */
 
-#define	MCFSIM_PACNT		0x80		/* Port A Control (r/w) */
-#define	MCFSIM_PADDR		0x84		/* Port A Direction (r/w) */
-#define	MCFSIM_PADAT		0x86		/* Port A Data (r/w) */
-#define	MCFSIM_PBCNT		0x88		/* Port B Control (r/w) */
-#define	MCFSIM_PBDDR		0x8c		/* Port B Direction (r/w) */
-#define	MCFSIM_PBDAT		0x8e		/* Port B Data (r/w) */
-#define	MCFSIM_PCDDR		0x94		/* Port C Direction (r/w) */
-#define	MCFSIM_PCDAT		0x96		/* Port C Data (r/w) */
-#define	MCFSIM_PDCNT		0x98		/* Port D Control (r/w) */
+#define	MCFSIM_PACNT		(MCF_MBAR + 0x80) /* Port A Control (r/w) */
+#define	MCFSIM_PADDR		(MCF_MBAR + 0x84) /* Port A Direction (r/w) */
+#define	MCFSIM_PADAT		(MCF_MBAR + 0x86) /* Port A Data (r/w) */
+#define	MCFSIM_PBCNT		(MCF_MBAR + 0x88) /* Port B Control (r/w) */
+#define	MCFSIM_PBDDR		(MCF_MBAR + 0x8c) /* Port B Direction (r/w) */
+#define	MCFSIM_PBDAT		(MCF_MBAR + 0x8e) /* Port B Data (r/w) */
+#define	MCFSIM_PCDDR		(MCF_MBAR + 0x94) /* Port C Direction (r/w) */
+#define	MCFSIM_PCDAT		(MCF_MBAR + 0x96) /* Port C Data (r/w) */
+#define	MCFSIM_PDCNT		(MCF_MBAR + 0x98) /* Port D Control (r/w) */
+
+/*
+ *	Define system peripheral IRQ usage.
+ */
+#define	MCFINT_VECBASE		64		/* Base of interrupts */
+#define	MCF_IRQ_SPURIOUS	64		/* User Spurious */
+#define	MCF_IRQ_EINT1		65		/* External Interrupt 1 */
+#define	MCF_IRQ_EINT2		66		/* External Interrupt 2 */
+#define	MCF_IRQ_EINT3		67		/* External Interrupt 3 */
+#define	MCF_IRQ_EINT4		68		/* External Interrupt 4 */
+#define	MCF_IRQ_TIMER1		69		/* Timer 1 */
+#define	MCF_IRQ_TIMER2		70		/* Timer 2 */
+#define	MCF_IRQ_TIMER3		71		/* Timer 3 */
+#define	MCF_IRQ_TIMER4		72		/* Timer 4 */
+#define	MCF_IRQ_UART1		73		/* UART 1 */
+#define	MCF_IRQ_UART2		74		/* UART 2 */
+#define	MCF_IRQ_PLIP		75		/* PLIC 2Khz Periodic */
+#define	MCF_IRQ_PLIA		76		/* PLIC Asynchronous */
+#define	MCF_IRQ_USB0		77		/* USB Endpoint 0 */
+#define	MCF_IRQ_USB1		78		/* USB Endpoint 1 */
+#define	MCF_IRQ_USB2		79		/* USB Endpoint 2 */
+#define	MCF_IRQ_USB3		80		/* USB Endpoint 3 */
+#define	MCF_IRQ_USB4		81		/* USB Endpoint 4 */
+#define	MCF_IRQ_USB5		82		/* USB Endpoint 5 */
+#define	MCF_IRQ_USB6		83		/* USB Endpoint 6 */
+#define	MCF_IRQ_USB7		84		/* USB Endpoint 7 */
+#define	MCF_IRQ_DMA		85		/* DMA Controller */
+#define	MCF_IRQ_ERX		86		/* Ethernet Receiver */
+#define	MCF_IRQ_ETX		87		/* Ethernet Transmitter */
+#define	MCF_IRQ_ENTC		88		/* Ethernet Non-Time Critical */
+#define	MCF_IRQ_QSPI		89		/* Queued Serial Interface */
+#define	MCF_IRQ_EINT5		90		/* External Interrupt 5 */
+#define	MCF_IRQ_EINT6		91		/* External Interrupt 6 */
+#define	MCF_IRQ_SWTO		92		/* Software Watchdog */
+#define	MCFINT_VECMAX		95		/* Maxmum interrupt */
 
+#define	MCF_IRQ_TIMER		MCF_IRQ_TIMER1
+#define	MCF_IRQ_PROFILER	MCF_IRQ_TIMER2
 
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX			48
+#define MCFGPIO_IRQ_MAX			-1
+#define MCFGPIO_IRQ_VECBASE		-1
 /****************************************************************************/
 #endif	/* m5272sim_h */
diff --git a/arch/m68k/include/asm/m527xsim.h b/arch/m68k/include/asm/m527xsim.h
index 95f4f8e..453356d 100644
--- a/arch/m68k/include/asm/m527xsim.h
+++ b/arch/m68k/include/asm/m527xsim.h
@@ -54,6 +54,175 @@
 #define	MCFSIM_DMR1		0x5c		/* SDRAM address mask 1 */
 #endif
 
+
+#ifdef CONFIG_M5271
+#define MCFGPIO_PODR_ADDR	(MCF_IPSBAR + 0x100000)
+#define MCFGPIO_PODR_DATAH	(MCF_IPSBAR + 0x100001)
+#define MCFGPIO_PODR_DATAL	(MCF_IPSBAR + 0x100002)
+#define MCFGPIO_PODR_BUSCTL	(MCF_IPSBAR + 0x100003)
+#define MCFGPIO_PODR_BS		(MCF_IPSBAR + 0x100004)
+#define MCFGPIO_PODR_CS		(MCF_IPSBAR + 0x100005)
+#define MCFGPIO_PODR_SDRAM	(MCF_IPSBAR + 0x100006)
+#define MCFGPIO_PODR_FECI2C	(MCF_IPSBAR + 0x100007)
+#define MCFGPIO_PODR_UARTH	(MCF_IPSBAR + 0x100008)
+#define MCFGPIO_PODR_UARTL	(MCF_IPSBAR + 0x100009)
+#define MCFGPIO_PODR_QSPI	(MCF_IPSBAR + 0x10000A)
+#define MCFGPIO_PODR_TIMER	(MCF_IPSBAR + 0x10000B)
+
+#define MCFGPIO_PDDR_ADDR	(MCF_IPSBAR + 0x100010)
+#define MCFGPIO_PDDR_DATAH	(MCF_IPSBAR + 0x100011)
+#define MCFGPIO_PDDR_DATAL	(MCF_IPSBAR + 0x100012)
+#define MCFGPIO_PDDR_BUSCTL	(MCF_IPSBAR + 0x100013)
+#define MCFGPIO_PDDR_BS		(MCF_IPSBAR + 0x100014)
+#define MCFGPIO_PDDR_CS		(MCF_IPSBAR + 0x100015)
+#define MCFGPIO_PDDR_SDRAM	(MCF_IPSBAR + 0x100016)
+#define MCFGPIO_PDDR_FECI2C	(MCF_IPSBAR + 0x100017)
+#define MCFGPIO_PDDR_UARTH	(MCF_IPSBAR + 0x100018)
+#define MCFGPIO_PDDR_UARTL	(MCF_IPSBAR + 0x100019)
+#define MCFGPIO_PDDR_QSPI	(MCF_IPSBAR + 0x10001A)
+#define MCFGPIO_PDDR_TIMER	(MCF_IPSBAR + 0x10001B)
+
+#define MCFGPIO_PPDSDR_ADDR	(MCF_IPSBAR + 0x100020)
+#define MCFGPIO_PPDSDR_DATAH	(MCF_IPSBAR + 0x100021)
+#define MCFGPIO_PPDSDR_DATAL	(MCF_IPSBAR + 0x100022)
+#define MCFGPIO_PPDSDR_BUSCTL	(MCF_IPSBAR + 0x100023)
+#define MCFGPIO_PPDSDR_BS	(MCF_IPSBAR + 0x100024)
+#define MCFGPIO_PPDSDR_CS	(MCF_IPSBAR + 0x100025)
+#define MCFGPIO_PPDSDR_SDRAM	(MCF_IPSBAR + 0x100026)
+#define MCFGPIO_PPDSDR_FECI2C	(MCF_IPSBAR + 0x100027)
+#define MCFGPIO_PPDSDR_UARTH	(MCF_IPSBAR + 0x100028)
+#define MCFGPIO_PPDSDR_UARTL	(MCF_IPSBAR + 0x100029)
+#define MCFGPIO_PPDSDR_QSPI	(MCF_IPSBAR + 0x10002A)
+#define MCFGPIO_PPDSDR_TIMER	(MCF_IPSBAR + 0x10002B)
+
+#define MCFGPIO_PCLRR_ADDR	(MCF_IPSBAR + 0x100030)
+#define MCFGPIO_PCLRR_DATAH	(MCF_IPSBAR + 0x100031)
+#define MCFGPIO_PCLRR_DATAL	(MCF_IPSBAR + 0x100032)
+#define MCFGPIO_PCLRR_BUSCTL	(MCF_IPSBAR + 0x100033)
+#define MCFGPIO_PCLRR_BS	(MCF_IPSBAR + 0x100034)
+#define MCFGPIO_PCLRR_CS	(MCF_IPSBAR + 0x100035)
+#define MCFGPIO_PCLRR_SDRAM	(MCF_IPSBAR + 0x100036)
+#define MCFGPIO_PCLRR_FECI2C	(MCF_IPSBAR + 0x100037)
+#define MCFGPIO_PCLRR_UARTH	(MCF_IPSBAR + 0x100038)
+#define MCFGPIO_PCLRR_UARTL	(MCF_IPSBAR + 0x100039)
+#define MCFGPIO_PCLRR_QSPI	(MCF_IPSBAR + 0x10003A)
+#define MCFGPIO_PCLRR_TIMER	(MCF_IPSBAR + 0x10003B)
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR			MCFGPIO_PODR_ADDR
+#define MCFGPIO_PDDR			MCFGPIO_PDDR_ADDR
+#define MCFGPIO_PPDR			MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_SETR			MCFGPIO_PPDSDR_ADDR
+#define MCFGPIO_CLRR			MCFGPIO_PCLRR_ADDR
+
+#define MCFGPIO_PIN_MAX			100
+#define MCFGPIO_IRQ_MAX			8
+#define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
+#endif
+
+#ifdef CONFIG_M5275
+#define MCFGPIO_PODR_BUSCTL	(MCF_IPSBAR + 0x100004)
+#define MCFGPIO_PODR_ADDR	(MCF_IPSBAR + 0x100005)
+#define MCFGPIO_PODR_CS		(MCF_IPSBAR + 0x100008)
+#define MCFGPIO_PODR_FEC0H	(MCF_IPSBAR + 0x10000A)
+#define MCFGPIO_PODR_FEC0L	(MCF_IPSBAR + 0x10000B)
+#define MCFGPIO_PODR_FECI2C	(MCF_IPSBAR + 0x10000C)
+#define MCFGPIO_PODR_QSPI	(MCF_IPSBAR + 0x10000D)
+#define MCFGPIO_PODR_SDRAM	(MCF_IPSBAR + 0x10000E)
+#define MCFGPIO_PODR_TIMERH	(MCF_IPSBAR + 0x10000F)
+#define MCFGPIO_PODR_TIMERL	(MCF_IPSBAR + 0x100010)
+#define MCFGPIO_PODR_UARTL	(MCF_IPSBAR + 0x100011)
+#define MCFGPIO_PODR_FEC1H	(MCF_IPSBAR + 0x100012)
+#define MCFGPIO_PODR_FEC1L	(MCF_IPSBAR + 0x100013)
+#define MCFGPIO_PODR_BS		(MCF_IPSBAR + 0x100014)
+#define MCFGPIO_PODR_IRQ	(MCF_IPSBAR + 0x100015)
+#define MCFGPIO_PODR_USBH	(MCF_IPSBAR + 0x100016)
+#define MCFGPIO_PODR_USBL	(MCF_IPSBAR + 0x100017)
+#define MCFGPIO_PODR_UARTH	(MCF_IPSBAR + 0x100018)
+
+#define MCFGPIO_PDDR_BUSCTL	(MCF_IPSBAR + 0x100020)
+#define MCFGPIO_PDDR_ADDR	(MCF_IPSBAR + 0x100021)
+#define MCFGPIO_PDDR_CS		(MCF_IPSBAR + 0x100024)
+#define MCFGPIO_PDDR_FEC0H	(MCF_IPSBAR + 0x100026)
+#define MCFGPIO_PDDR_FEC0L	(MCF_IPSBAR + 0x100027)
+#define MCFGPIO_PDDR_FECI2C	(MCF_IPSBAR + 0x100028)
+#define MCFGPIO_PDDR_QSPI	(MCF_IPSBAR + 0x100029)
+#define MCFGPIO_PDDR_SDRAM	(MCF_IPSBAR + 0x10002A)
+#define MCFGPIO_PDDR_TIMERH	(MCF_IPSBAR + 0x10002B)
+#define MCFGPIO_PDDR_TIMERL	(MCF_IPSBAR + 0x10002C)
+#define MCFGPIO_PDDR_UARTL	(MCF_IPSBAR + 0x10002D)
+#define MCFGPIO_PDDR_FEC1H	(MCF_IPSBAR + 0x10002E)
+#define MCFGPIO_PDDR_FEC1L	(MCF_IPSBAR + 0x10002F)
+#define MCFGPIO_PDDR_BS		(MCF_IPSBAR + 0x100030)
+#define MCFGPIO_PDDR_IRQ	(MCF_IPSBAR + 0x100031)
+#define MCFGPIO_PDDR_USBH	(MCF_IPSBAR + 0x100032)
+#define MCFGPIO_PDDR_USBL	(MCF_IPSBAR + 0x100033)
+#define MCFGPIO_PDDR_UARTH	(MCF_IPSBAR + 0x100034)
+
+#define MCFGPIO_PPDSDR_BUSCTL	(MCF_IPSBAR + 0x10003C)
+#define MCFGPIO_PPDSDR_ADDR	(MCF_IPSBAR + 0x10003D)
+#define MCFGPIO_PPDSDR_CS	(MCF_IPSBAR + 0x100040)
+#define MCFGPIO_PPDSDR_FEC0H	(MCF_IPSBAR + 0x100042)
+#define MCFGPIO_PPDSDR_FEC0L	(MCF_IPSBAR + 0x100043)
+#define MCFGPIO_PPDSDR_FECI2C	(MCF_IPSBAR + 0x100044)
+#define MCFGPIO_PPDSDR_QSPI	(MCF_IPSBAR + 0x100045)
+#define MCFGPIO_PPDSDR_SDRAM	(MCF_IPSBAR + 0x100046)
+#define MCFGPIO_PPDSDR_TIMERH	(MCF_IPSBAR + 0x100047)
+#define MCFGPIO_PPDSDR_TIMERL	(MCF_IPSBAR + 0x100048)
+#define MCFGPIO_PPDSDR_UARTL	(MCF_IPSBAR + 0x100049)
+#define MCFGPIO_PPDSDR_FEC1H	(MCF_IPSBAR + 0x10004A)
+#define MCFGPIO_PPDSDR_FEC1L	(MCF_IPSBAR + 0x10004B)
+#define MCFGPIO_PPDSDR_BS	(MCF_IPSBAR + 0x10004C)
+#define MCFGPIO_PPDSDR_IRQ	(MCF_IPSBAR + 0x10004D)
+#define MCFGPIO_PPDSDR_USBH	(MCF_IPSBAR + 0x10004E)
+#define MCFGPIO_PPDSDR_USBL	(MCF_IPSBAR + 0x10004F)
+#define MCFGPIO_PPDSDR_UARTH	(MCF_IPSBAR + 0x100050)
+
+#define MCFGPIO_PCLRR_BUSCTL	(MCF_IPSBAR + 0x100058)
+#define MCFGPIO_PCLRR_ADDR	(MCF_IPSBAR + 0x100059)
+#define MCFGPIO_PCLRR_CS	(MCF_IPSBAR + 0x10005C)
+#define MCFGPIO_PCLRR_FEC0H	(MCF_IPSBAR + 0x10005E)
+#define MCFGPIO_PCLRR_FEC0L	(MCF_IPSBAR + 0x10005F)
+#define MCFGPIO_PCLRR_FECI2C	(MCF_IPSBAR + 0x100060)
+#define MCFGPIO_PCLRR_QSPI	(MCF_IPSBAR + 0x100061)
+#define MCFGPIO_PCLRR_SDRAM	(MCF_IPSBAR + 0x100062)
+#define MCFGPIO_PCLRR_TIMERH	(MCF_IPSBAR + 0x100063)
+#define MCFGPIO_PCLRR_TIMERL	(MCF_IPSBAR + 0x100064)
+#define MCFGPIO_PCLRR_UARTL	(MCF_IPSBAR + 0x100065)
+#define MCFGPIO_PCLRR_FEC1H	(MCF_IPSBAR + 0x100066)
+#define MCFGPIO_PCLRR_FEC1L	(MCF_IPSBAR + 0x100067)
+#define MCFGPIO_PCLRR_BS	(MCF_IPSBAR + 0x100068)
+#define MCFGPIO_PCLRR_IRQ	(MCF_IPSBAR + 0x100069)
+#define MCFGPIO_PCLRR_USBH	(MCF_IPSBAR + 0x10006A)
+#define MCFGPIO_PCLRR_USBL	(MCF_IPSBAR + 0x10006B)
+#define MCFGPIO_PCLRR_UARTH	(MCF_IPSBAR + 0x10006C)
+
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR			MCFGPIO_PODR_BUSCTL
+#define MCFGPIO_PDDR			MCFGPIO_PDDR_BUSCTL
+#define MCFGPIO_PPDR			MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_SETR			MCFGPIO_PPDSDR_BUSCTL
+#define MCFGPIO_CLRR			MCFGPIO_PCLRR_BUSCTL
+
+#define MCFGPIO_PIN_MAX			148
+#define MCFGPIO_IRQ_MAX			8
+#define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
+#endif
+
+/*
+ * EPort
+ */
+
+#define MCFEPORT_EPDDR		(MCF_IPSBAR + 0x130002)
+#define MCFEPORT_EPDR		(MCF_IPSBAR + 0x130004)
+#define MCFEPORT_EPPDR		(MCF_IPSBAR + 0x130005)
+
+
 /*
  *	GPIO pins setups to enable the UARTs.
  */
diff --git a/arch/m68k/include/asm/m528xsim.h b/arch/m68k/include/asm/m528xsim.h
index d79c49f..e2ad1f4 100644
--- a/arch/m68k/include/asm/m528xsim.h
+++ b/arch/m68k/include/asm/m528xsim.h
@@ -41,6 +41,157 @@
 #define	MCFSIM_DMR1		0x54		/* SDRAM address mask 1 */
 
 /*
+ * 	GPIO registers
+ */
+#define MCFGPIO_PORTA		(MCF_IPSBAR + 0x00100000)
+#define MCFGPIO_PORTB		(MCF_IPSBAR + 0x00100001)
+#define MCFGPIO_PORTC		(MCF_IPSBAR + 0x00100002)
+#define MCFGPIO_PORTD		(MCF_IPSBAR + 0x00100003)
+#define MCFGPIO_PORTE		(MCF_IPSBAR + 0x00100004)
+#define MCFGPIO_PORTF		(MCF_IPSBAR + 0x00100005)
+#define MCFGPIO_PORTG		(MCF_IPSBAR + 0x00100006)
+#define MCFGPIO_PORTH		(MCF_IPSBAR + 0x00100007)
+#define MCFGPIO_PORTJ		(MCF_IPSBAR + 0x00100008)
+#define MCFGPIO_PORTDD		(MCF_IPSBAR + 0x00100009)
+#define MCFGPIO_PORTEH		(MCF_IPSBAR + 0x0010000A)
+#define MCFGPIO_PORTEL		(MCF_IPSBAR + 0x0010000B)
+#define MCFGPIO_PORTAS		(MCF_IPSBAR + 0x0010000C)
+#define MCFGPIO_PORTQS		(MCF_IPSBAR + 0x0010000D)
+#define MCFGPIO_PORTSD		(MCF_IPSBAR + 0x0010000E)
+#define MCFGPIO_PORTTC		(MCF_IPSBAR + 0x0010000F)
+#define MCFGPIO_PORTTD		(MCF_IPSBAR + 0x00100010)
+#define MCFGPIO_PORTUA		(MCF_IPSBAR + 0x00100011)
+
+#define MCFGPIO_DDRA		(MCF_IPSBAR + 0x00100014)
+#define MCFGPIO_DDRB		(MCF_IPSBAR + 0x00100015)
+#define MCFGPIO_DDRC		(MCF_IPSBAR + 0x00100016)
+#define MCFGPIO_DDRD		(MCF_IPSBAR + 0x00100017)
+#define MCFGPIO_DDRE		(MCF_IPSBAR + 0x00100018)
+#define MCFGPIO_DDRF		(MCF_IPSBAR + 0x00100019)
+#define MCFGPIO_DDRG		(MCF_IPSBAR + 0x0010001A)
+#define MCFGPIO_DDRH		(MCF_IPSBAR + 0x0010001B)
+#define MCFGPIO_DDRJ		(MCF_IPSBAR + 0x0010001C)
+#define MCFGPIO_DDRDD		(MCF_IPSBAR + 0x0010001D)
+#define MCFGPIO_DDREH		(MCF_IPSBAR + 0x0010001E)
+#define MCFGPIO_DDREL		(MCF_IPSBAR + 0x0010001F)
+#define MCFGPIO_DDRAS		(MCF_IPSBAR + 0x00100020)
+#define MCFGPIO_DDRQS		(MCF_IPSBAR + 0x00100021)
+#define MCFGPIO_DDRSD		(MCF_IPSBAR + 0x00100022)
+#define MCFGPIO_DDRTC		(MCF_IPSBAR + 0x00100023)
+#define MCFGPIO_DDRTD		(MCF_IPSBAR + 0x00100024)
+#define MCFGPIO_DDRUA		(MCF_IPSBAR + 0x00100025)
+
+#define MCFGPIO_PORTAP		(MCF_IPSBAR + 0x00100028)
+#define MCFGPIO_PORTBP		(MCF_IPSBAR + 0x00100029)
+#define MCFGPIO_PORTCP		(MCF_IPSBAR + 0x0010002A)
+#define MCFGPIO_PORTDP		(MCF_IPSBAR + 0x0010002B)
+#define MCFGPIO_PORTEP		(MCF_IPSBAR + 0x0010002C)
+#define MCFGPIO_PORTFP		(MCF_IPSBAR + 0x0010002D)
+#define MCFGPIO_PORTGP		(MCF_IPSBAR + 0x0010002E)
+#define MCFGPIO_PORTHP		(MCF_IPSBAR + 0x0010002F)
+#define MCFGPIO_PORTJP		(MCF_IPSBAR + 0x00100030)
+#define MCFGPIO_PORTDDP		(MCF_IPSBAR + 0x00100031)
+#define MCFGPIO_PORTEHP		(MCF_IPSBAR + 0x00100032)
+#define MCFGPIO_PORTELP		(MCF_IPSBAR + 0x00100033)
+#define MCFGPIO_PORTASP		(MCF_IPSBAR + 0x00100034)
+#define MCFGPIO_PORTQSP		(MCF_IPSBAR + 0x00100035)
+#define MCFGPIO_PORTSDP		(MCF_IPSBAR + 0x00100036)
+#define MCFGPIO_PORTTCP		(MCF_IPSBAR + 0x00100037)
+#define MCFGPIO_PORTTDP		(MCF_IPSBAR + 0x00100038)
+#define MCFGPIO_PORTUAP		(MCF_IPSBAR + 0x00100039)
+
+#define MCFGPIO_SETA		(MCF_IPSBAR + 0x00100028)
+#define MCFGPIO_SETB		(MCF_IPSBAR + 0x00100029)
+#define MCFGPIO_SETC		(MCF_IPSBAR + 0x0010002A)
+#define MCFGPIO_SETD		(MCF_IPSBAR + 0x0010002B)
+#define MCFGPIO_SETE		(MCF_IPSBAR + 0x0010002C)
+#define MCFGPIO_SETF		(MCF_IPSBAR + 0x0010002D)
+#define MCFGPIO_SETG		(MCF_IPSBAR + 0x0010002E)
+#define MCFGPIO_SETH		(MCF_IPSBAR + 0x0010002F)
+#define MCFGPIO_SETJ		(MCF_IPSBAR + 0x00100030)
+#define MCFGPIO_SETDD		(MCF_IPSBAR + 0x00100031)
+#define MCFGPIO_SETEH		(MCF_IPSBAR + 0x00100032)
+#define MCFGPIO_SETEL		(MCF_IPSBAR + 0x00100033)
+#define MCFGPIO_SETAS		(MCF_IPSBAR + 0x00100034)
+#define MCFGPIO_SETQS		(MCF_IPSBAR + 0x00100035)
+#define MCFGPIO_SETSD		(MCF_IPSBAR + 0x00100036)
+#define MCFGPIO_SETTC		(MCF_IPSBAR + 0x00100037)
+#define MCFGPIO_SETTD		(MCF_IPSBAR + 0x00100038)
+#define MCFGPIO_SETUA		(MCF_IPSBAR + 0x00100039)
+
+#define MCFGPIO_CLRA		(MCF_IPSBAR + 0x0010003C)
+#define MCFGPIO_CLRB		(MCF_IPSBAR + 0x0010003D)
+#define MCFGPIO_CLRC		(MCF_IPSBAR + 0x0010003E)
+#define MCFGPIO_CLRD		(MCF_IPSBAR + 0x0010003F)
+#define MCFGPIO_CLRE		(MCF_IPSBAR + 0x00100040)
+#define MCFGPIO_CLRF		(MCF_IPSBAR + 0x00100041)
+#define MCFGPIO_CLRG		(MCF_IPSBAR + 0x00100042)
+#define MCFGPIO_CLRH		(MCF_IPSBAR + 0x00100043)
+#define MCFGPIO_CLRJ		(MCF_IPSBAR + 0x00100044)
+#define MCFGPIO_CLRDD		(MCF_IPSBAR + 0x00100045)
+#define MCFGPIO_CLREH		(MCF_IPSBAR + 0x00100046)
+#define MCFGPIO_CLREL		(MCF_IPSBAR + 0x00100047)
+#define MCFGPIO_CLRAS		(MCF_IPSBAR + 0x00100048)
+#define MCFGPIO_CLRQS		(MCF_IPSBAR + 0x00100049)
+#define MCFGPIO_CLRSD		(MCF_IPSBAR + 0x0010004A)
+#define MCFGPIO_CLRTC		(MCF_IPSBAR + 0x0010004B)
+#define MCFGPIO_CLRTD		(MCF_IPSBAR + 0x0010004C)
+#define MCFGPIO_CLRUA		(MCF_IPSBAR + 0x0010004D)
+
+#define MCFGPIO_PBCDPAR		(MCF_IPSBAR + 0x00100050)
+#define MCFGPIO_PFPAR		(MCF_IPSBAR + 0x00100051)
+#define MCFGPIO_PEPAR		(MCF_IPSBAR + 0x00100052)
+#define MCFGPIO_PJPAR		(MCF_IPSBAR + 0x00100054)
+#define MCFGPIO_PSDPAR		(MCF_IPSBAR + 0x00100055)
+#define MCFGPIO_PASPAR		(MCF_IPSBAR + 0x00100056)
+#define MCFGPIO_PEHLPAR		(MCF_IPSBAR + 0x00100058)
+#define MCFGPIO_PQSPAR		(MCF_IPSBAR + 0x00100059)
+#define MCFGPIO_PTCPAR		(MCF_IPSBAR + 0x0010005A)
+#define MCFGPIO_PTDPAR		(MCF_IPSBAR + 0x0010005B)
+#define MCFGPIO_PUAPAR		(MCF_IPSBAR + 0x0010005C)
+
+/*
+ * 	Edge Port registers
+ */
+#define MCFEPORT_EPPAR		(MCF_IPSBAR + 0x00130000)
+#define MCFEPORT_EPDDR		(MCF_IPSBAR + 0x00130002)
+#define MCFEPORT_EPIER		(MCF_IPSBAR + 0x00130003)
+#define MCFEPORT_EPDR		(MCF_IPSBAR + 0x00130004)
+#define MCFEPORT_EPPDR		(MCF_IPSBAR + 0x00130005)
+#define MCFEPORT_EPFR		(MCF_IPSBAR + 0x00130006)
+
+/*
+ * 	Queued ADC registers
+ */
+#define MCFQADC_PORTQA		(MCF_IPSBAR + 0x00190006)
+#define MCFQADC_PORTQB		(MCF_IPSBAR + 0x00190007)
+#define MCFQADC_DDRQA		(MCF_IPSBAR + 0x00190008)
+#define MCFQADC_DDRQB		(MCF_IPSBAR + 0x00190009)
+
+/*
+ * 	General Purpose Timers registers
+ */
+#define MCFGPTA_GPTPORT		(MCF_IPSBAR + 0x001A001D)
+#define MCFGPTA_GPTDDR		(MCF_IPSBAR + 0x001A001E)
+#define MCFGPTB_GPTPORT		(MCF_IPSBAR + 0x001B001D)
+#define MCFGPTB_GPTDDR		(MCF_IPSBAR + 0x001B001E)
+/*
+ *
+ * definitions for generic gpio support
+ *
+ */
+#define MCFGPIO_PODR		MCFGPIO_PORTA	/* port output data */
+#define MCFGPIO_PDDR		MCFGPIO_DDRA	/* port data direction */
+#define MCFGPIO_PPDR		MCFGPIO_PORTAP	/* port pin data */
+#define MCFGPIO_SETR		MCFGPIO_SETA	/* set output */
+#define MCFGPIO_CLRR		MCFGPIO_CLRA	/* clr output */
+
+#define MCFGPIO_IRQ_MAX		8
+#define MCFGPIO_IRQ_VECBASE	MCFINT_VECBASE
+#define MCFGPIO_PIN_MAX		180
+
+
+/*
  *	Derek Cheung - 6 Feb 2005
  *		add I2C and QSPI register definition using Freescale's MCF5282
  */
diff --git a/arch/m68k/include/asm/m5307sim.h b/arch/m68k/include/asm/m5307sim.h
index 5886728..c6830e5 100644
--- a/arch/m68k/include/asm/m5307sim.h
+++ b/arch/m68k/include/asm/m5307sim.h
@@ -90,8 +90,15 @@
 #define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
 #define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
 
-#define	MCFSIM_PADDR		0x244		/* Parallel Direction (r/w) */
-#define	MCFSIM_PADAT		0x248		/* Parallel Data (r/w) */
+#define	MCFSIM_PADDR		(MCF_MBAR + 0x244)
+#define	MCFSIM_PADAT		(MCF_MBAR + 0x248)
+
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX			16
+#define MCFGPIO_IRQ_MAX			-1
+#define MCFGPIO_IRQ_VECBASE		-1
 
 
 /* Definition offset address for CS2-7  -- old mask 5307 */
@@ -117,22 +124,6 @@
 #define	MCFSIM_DMA2ICR		MCFSIM_ICR8	/* DMA 2 ICR */
 #define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
 
-#if defined(CONFIG_M5307)
-#define	MCFSIM_IMR_MASKALL	0x3fffe		/* All SIM intr sources */
-#endif
-
-/*
- *	Macro to set IMR register. It is 32 bits on the 5307.
- */
-#define	mcf_getimr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
-
-#define	mcf_setimr(imr)		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define	mcf_getipr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
-
 
 /*
  *	Some symbol defines for the Parallel Port Pin Assignment Register
@@ -149,6 +140,11 @@
 #define IRQ3_LEVEL6	0x40
 #define IRQ1_LEVEL2	0x20
 
+/*
+ *	Define system peripheral IRQ usage.
+ */
+#define	MCF_IRQ_TIMER		30		/* Timer0, Level 6 */
+#define	MCF_IRQ_PROFILER	31		/* Timer1, Level 7 */
 
 /*
  *	Define the Cache register flags.
diff --git a/arch/m68k/include/asm/m532xsim.h b/arch/m68k/include/asm/m532xsim.h
index eb7fd44..36bf15a 100644
--- a/arch/m68k/include/asm/m532xsim.h
+++ b/arch/m68k/include/asm/m532xsim.h
@@ -56,47 +56,21 @@
 #define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
 
 
-#define	MCFSIM_IMR_MASKALL	0xFFFFFFFF	/* All SIM intr sources */
-
-#define MCFSIM_IMR_SIMR0	0xFC04801C
-#define MCFSIM_IMR_SIMR1	0xFC04C01C
-#define MCFSIM_IMR_CIMR0	0xFC04801D
-#define MCFSIM_IMR_CIMR1	0xFC04C01D
+#define	MCFINTC0_SIMR		0xFC04801C
+#define	MCFINTC0_CIMR		0xFC04801D
+#define	MCFINTC0_ICR0		0xFC048040
+#define	MCFINTC1_SIMR		0xFC04C01C
+#define	MCFINTC1_CIMR		0xFC04C01D
+#define	MCFINTC1_ICR0		0xFC04C040
 
 #define MCFSIM_ICR_TIMER1	(0xFC048040+32)
 #define MCFSIM_ICR_TIMER2	(0xFC048040+33)
 
-
 /*
- *	Macro to set IMR register. It is 32 bits on the 5307.
+ *	Define system peripheral IRQ usage.
  */
-#define	mcf_getimr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
-
-#define	mcf_setimr(imr)		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define	mcf_getipr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
-
-#define	mcf_getiprl()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRL))
-
-#define	mcf_getiprh()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPRH))
-
-
-#define mcf_enable_irq0(irq)		\
-	*((volatile unsigned char*) (MCFSIM_IMR_CIMR0)) = (irq);
-
-#define mcf_enable_irq1(irq)		\
-	*((volatile unsigned char*) (MCFSIM_IMR_CIMR1)) = (irq);
-
-#define mcf_disable_irq0(irq)		\
-	*((volatile unsigned char*) (MCFSIM_IMR_SIMR0)) = (irq);
-
-#define mcf_disable_irq1(irq)		\
-	*((volatile unsigned char*) (MCFSIM_IMR_SIMR1)) = (irq);
+#define	MCF_IRQ_TIMER		(64 + 32)	/* Timer0 */
+#define	MCF_IRQ_PROFILER	(64 + 33)	/* Timer1 */
 
 /*
  *	Define the Cache register flags.
@@ -422,70 +396,70 @@
  *********************************************************************/
 
 /* Register read/write macros */
-#define MCF_GPIO_PODR_FECH		MCF_REG08(0xFC0A4000)
-#define MCF_GPIO_PODR_FECL		MCF_REG08(0xFC0A4001)
-#define MCF_GPIO_PODR_SSI		MCF_REG08(0xFC0A4002)
-#define MCF_GPIO_PODR_BUSCTL		MCF_REG08(0xFC0A4003)
-#define MCF_GPIO_PODR_BE		MCF_REG08(0xFC0A4004)
-#define MCF_GPIO_PODR_CS		MCF_REG08(0xFC0A4005)
-#define MCF_GPIO_PODR_PWM		MCF_REG08(0xFC0A4006)
-#define MCF_GPIO_PODR_FECI2C		MCF_REG08(0xFC0A4007)
-#define MCF_GPIO_PODR_UART		MCF_REG08(0xFC0A4009)
-#define MCF_GPIO_PODR_QSPI		MCF_REG08(0xFC0A400A)
-#define MCF_GPIO_PODR_TIMER		MCF_REG08(0xFC0A400B)
-#define MCF_GPIO_PODR_LCDDATAH		MCF_REG08(0xFC0A400D)
-#define MCF_GPIO_PODR_LCDDATAM		MCF_REG08(0xFC0A400E)
-#define MCF_GPIO_PODR_LCDDATAL		MCF_REG08(0xFC0A400F)
-#define MCF_GPIO_PODR_LCDCTLH		MCF_REG08(0xFC0A4010)
-#define MCF_GPIO_PODR_LCDCTLL		MCF_REG08(0xFC0A4011)
-#define MCF_GPIO_PDDR_FECH		MCF_REG08(0xFC0A4014)
-#define MCF_GPIO_PDDR_FECL		MCF_REG08(0xFC0A4015)
-#define MCF_GPIO_PDDR_SSI		MCF_REG08(0xFC0A4016)
-#define MCF_GPIO_PDDR_BUSCTL		MCF_REG08(0xFC0A4017)
-#define MCF_GPIO_PDDR_BE		MCF_REG08(0xFC0A4018)
-#define MCF_GPIO_PDDR_CS		MCF_REG08(0xFC0A4019)
-#define MCF_GPIO_PDDR_PWM		MCF_REG08(0xFC0A401A)
-#define MCF_GPIO_PDDR_FECI2C		MCF_REG08(0xFC0A401B)
-#define MCF_GPIO_PDDR_UART		MCF_REG08(0xFC0A401C)
-#define MCF_GPIO_PDDR_QSPI		MCF_REG08(0xFC0A401E)
-#define MCF_GPIO_PDDR_TIMER		MCF_REG08(0xFC0A401F)
-#define MCF_GPIO_PDDR_LCDDATAH		MCF_REG08(0xFC0A4021)
-#define MCF_GPIO_PDDR_LCDDATAM		MCF_REG08(0xFC0A4022)
-#define MCF_GPIO_PDDR_LCDDATAL		MCF_REG08(0xFC0A4023)
-#define MCF_GPIO_PDDR_LCDCTLH		MCF_REG08(0xFC0A4024)
-#define MCF_GPIO_PDDR_LCDCTLL		MCF_REG08(0xFC0A4025)
-#define MCF_GPIO_PPDSDR_FECH		MCF_REG08(0xFC0A4028)
-#define MCF_GPIO_PPDSDR_FECL		MCF_REG08(0xFC0A4029)
-#define MCF_GPIO_PPDSDR_SSI		MCF_REG08(0xFC0A402A)
-#define MCF_GPIO_PPDSDR_BUSCTL		MCF_REG08(0xFC0A402B)
-#define MCF_GPIO_PPDSDR_BE		MCF_REG08(0xFC0A402C)
-#define MCF_GPIO_PPDSDR_CS		MCF_REG08(0xFC0A402D)
-#define MCF_GPIO_PPDSDR_PWM		MCF_REG08(0xFC0A402E)
-#define MCF_GPIO_PPDSDR_FECI2C		MCF_REG08(0xFC0A402F)
-#define MCF_GPIO_PPDSDR_UART		MCF_REG08(0xFC0A4031)
-#define MCF_GPIO_PPDSDR_QSPI		MCF_REG08(0xFC0A4032)
-#define MCF_GPIO_PPDSDR_TIMER		MCF_REG08(0xFC0A4033)
-#define MCF_GPIO_PPDSDR_LCDDATAH	MCF_REG08(0xFC0A4035)
-#define MCF_GPIO_PPDSDR_LCDDATAM	MCF_REG08(0xFC0A4036)
-#define MCF_GPIO_PPDSDR_LCDDATAL	MCF_REG08(0xFC0A4037)
-#define MCF_GPIO_PPDSDR_LCDCTLH		MCF_REG08(0xFC0A4038)
-#define MCF_GPIO_PPDSDR_LCDCTLL		MCF_REG08(0xFC0A4039)
-#define MCF_GPIO_PCLRR_FECH		MCF_REG08(0xFC0A403C)
-#define MCF_GPIO_PCLRR_FECL		MCF_REG08(0xFC0A403D)
-#define MCF_GPIO_PCLRR_SSI		MCF_REG08(0xFC0A403E)
-#define MCF_GPIO_PCLRR_BUSCTL		MCF_REG08(0xFC0A403F)
-#define MCF_GPIO_PCLRR_BE		MCF_REG08(0xFC0A4040)
-#define MCF_GPIO_PCLRR_CS		MCF_REG08(0xFC0A4041)
-#define MCF_GPIO_PCLRR_PWM		MCF_REG08(0xFC0A4042)
-#define MCF_GPIO_PCLRR_FECI2C		MCF_REG08(0xFC0A4043)
-#define MCF_GPIO_PCLRR_UART		MCF_REG08(0xFC0A4045)
-#define MCF_GPIO_PCLRR_QSPI		MCF_REG08(0xFC0A4046)
-#define MCF_GPIO_PCLRR_TIMER		MCF_REG08(0xFC0A4047)
-#define MCF_GPIO_PCLRR_LCDDATAH		MCF_REG08(0xFC0A4049)
-#define MCF_GPIO_PCLRR_LCDDATAM		MCF_REG08(0xFC0A404A)
-#define MCF_GPIO_PCLRR_LCDDATAL		MCF_REG08(0xFC0A404B)
-#define MCF_GPIO_PCLRR_LCDCTLH		MCF_REG08(0xFC0A404C)
-#define MCF_GPIO_PCLRR_LCDCTLL		MCF_REG08(0xFC0A404D)
+#define MCFGPIO_PODR_FECH		(0xFC0A4000)
+#define MCFGPIO_PODR_FECL		(0xFC0A4001)
+#define MCFGPIO_PODR_SSI		(0xFC0A4002)
+#define MCFGPIO_PODR_BUSCTL		(0xFC0A4003)
+#define MCFGPIO_PODR_BE			(0xFC0A4004)
+#define MCFGPIO_PODR_CS			(0xFC0A4005)
+#define MCFGPIO_PODR_PWM		(0xFC0A4006)
+#define MCFGPIO_PODR_FECI2C		(0xFC0A4007)
+#define MCFGPIO_PODR_UART		(0xFC0A4009)
+#define MCFGPIO_PODR_QSPI		(0xFC0A400A)
+#define MCFGPIO_PODR_TIMER		(0xFC0A400B)
+#define MCFGPIO_PODR_LCDDATAH		(0xFC0A400D)
+#define MCFGPIO_PODR_LCDDATAM		(0xFC0A400E)
+#define MCFGPIO_PODR_LCDDATAL		(0xFC0A400F)
+#define MCFGPIO_PODR_LCDCTLH		(0xFC0A4010)
+#define MCFGPIO_PODR_LCDCTLL		(0xFC0A4011)
+#define MCFGPIO_PDDR_FECH		(0xFC0A4014)
+#define MCFGPIO_PDDR_FECL		(0xFC0A4015)
+#define MCFGPIO_PDDR_SSI		(0xFC0A4016)
+#define MCFGPIO_PDDR_BUSCTL		(0xFC0A4017)
+#define MCFGPIO_PDDR_BE			(0xFC0A4018)
+#define MCFGPIO_PDDR_CS			(0xFC0A4019)
+#define MCFGPIO_PDDR_PWM		(0xFC0A401A)
+#define MCFGPIO_PDDR_FECI2C		(0xFC0A401B)
+#define MCFGPIO_PDDR_UART		(0xFC0A401C)
+#define MCFGPIO_PDDR_QSPI		(0xFC0A401E)
+#define MCFGPIO_PDDR_TIMER		(0xFC0A401F)
+#define MCFGPIO_PDDR_LCDDATAH		(0xFC0A4021)
+#define MCFGPIO_PDDR_LCDDATAM		(0xFC0A4022)
+#define MCFGPIO_PDDR_LCDDATAL		(0xFC0A4023)
+#define MCFGPIO_PDDR_LCDCTLH		(0xFC0A4024)
+#define MCFGPIO_PDDR_LCDCTLL		(0xFC0A4025)
+#define MCFGPIO_PPDSDR_FECH		(0xFC0A4028)
+#define MCFGPIO_PPDSDR_FECL		(0xFC0A4029)
+#define MCFGPIO_PPDSDR_SSI		(0xFC0A402A)
+#define MCFGPIO_PPDSDR_BUSCTL		(0xFC0A402B)
+#define MCFGPIO_PPDSDR_BE		(0xFC0A402C)
+#define MCFGPIO_PPDSDR_CS		(0xFC0A402D)
+#define MCFGPIO_PPDSDR_PWM		(0xFC0A402E)
+#define MCFGPIO_PPDSDR_FECI2C		(0xFC0A402F)
+#define MCFGPIO_PPDSDR_UART		(0xFC0A4031)
+#define MCFGPIO_PPDSDR_QSPI		(0xFC0A4032)
+#define MCFGPIO_PPDSDR_TIMER		(0xFC0A4033)
+#define MCFGPIO_PPDSDR_LCDDATAH		(0xFC0A4035)
+#define MCFGPIO_PPDSDR_LCDDATAM		(0xFC0A4036)
+#define MCFGPIO_PPDSDR_LCDDATAL		(0xFC0A4037)
+#define MCFGPIO_PPDSDR_LCDCTLH		(0xFC0A4038)
+#define MCFGPIO_PPDSDR_LCDCTLL		(0xFC0A4039)
+#define MCFGPIO_PCLRR_FECH		(0xFC0A403C)
+#define MCFGPIO_PCLRR_FECL		(0xFC0A403D)
+#define MCFGPIO_PCLRR_SSI		(0xFC0A403E)
+#define MCFGPIO_PCLRR_BUSCTL		(0xFC0A403F)
+#define MCFGPIO_PCLRR_BE		(0xFC0A4040)
+#define MCFGPIO_PCLRR_CS		(0xFC0A4041)
+#define MCFGPIO_PCLRR_PWM		(0xFC0A4042)
+#define MCFGPIO_PCLRR_FECI2C		(0xFC0A4043)
+#define MCFGPIO_PCLRR_UART		(0xFC0A4045)
+#define MCFGPIO_PCLRR_QSPI		(0xFC0A4046)
+#define MCFGPIO_PCLRR_TIMER		(0xFC0A4047)
+#define MCFGPIO_PCLRR_LCDDATAH		(0xFC0A4049)
+#define MCFGPIO_PCLRR_LCDDATAM		(0xFC0A404A)
+#define MCFGPIO_PCLRR_LCDDATAL		(0xFC0A404B)
+#define MCFGPIO_PCLRR_LCDCTLH		(0xFC0A404C)
+#define MCFGPIO_PCLRR_LCDCTLL		(0xFC0A404D)
 #define MCF_GPIO_PAR_FEC		MCF_REG08(0xFC0A4050)
 #define MCF_GPIO_PAR_PWM		MCF_REG08(0xFC0A4051)
 #define MCF_GPIO_PAR_BUSCTL		MCF_REG08(0xFC0A4052)
@@ -1187,6 +1161,20 @@
 /* Bit definitions and macros for MCF_GPIO_DSCR_IRQ */
 #define MCF_GPIO_DSCR_IRQ_IRQ_DSE(x)               (((x)&0x03)<<0)
 
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PODR			MCFGPIO_PODR_FECH
+#define MCFGPIO_PDDR			MCFGPIO_PDDR_FECH
+#define MCFGPIO_PPDR			MCFGPIO_PPDSDR_FECH
+#define MCFGPIO_SETR			MCFGPIO_PPDSDR_FECH
+#define MCFGPIO_CLRR			MCFGPIO_PCLRR_FECH
+
+#define MCFGPIO_PIN_MAX			136
+#define MCFGPIO_IRQ_MAX			8
+#define MCFGPIO_IRQ_VECBASE		MCFINT_VECBASE
+
+
 /*********************************************************************
  *
  * Interrupt Controller (INTC)
@@ -2154,12 +2142,12 @@
  *********************************************************************/
 
 /* Register read/write macros */
-#define MCF_EPORT_EPPAR                MCF_REG16(0xFC094000)
-#define MCF_EPORT_EPDDR                MCF_REG08(0xFC094002)
-#define MCF_EPORT_EPIER                MCF_REG08(0xFC094003)
-#define MCF_EPORT_EPDR                 MCF_REG08(0xFC094004)
-#define MCF_EPORT_EPPDR                MCF_REG08(0xFC094005)
-#define MCF_EPORT_EPFR                 MCF_REG08(0xFC094006)
+#define MCFEPORT_EPPAR                (0xFC094000)
+#define MCFEPORT_EPDDR                (0xFC094002)
+#define MCFEPORT_EPIER                (0xFC094003)
+#define MCFEPORT_EPDR                 (0xFC094004)
+#define MCFEPORT_EPPDR                (0xFC094005)
+#define MCFEPORT_EPFR                 (0xFC094006)
 
 /* Bit definitions and macros for MCF_EPORT_EPPAR */
 #define MCF_EPORT_EPPAR_EPPA1(x)       (((x)&0x0003)<<2)
diff --git a/arch/m68k/include/asm/m5407sim.h b/arch/m68k/include/asm/m5407sim.h
index cc22c4a..c399abb 100644
--- a/arch/m68k/include/asm/m5407sim.h
+++ b/arch/m68k/include/asm/m5407sim.h
@@ -73,9 +73,15 @@
 #define MCFSIM_DACR1		0x110		/* DRAM 1 Addr and Ctrl (r/w) */
 #define MCFSIM_DMR1		0x114		/* DRAM 1 Mask reg (r/w) */
 
-#define	MCFSIM_PADDR		0x244		/* Parallel Direction (r/w) */
-#define	MCFSIM_PADAT		0x248		/* Parallel Data (r/w) */
+#define	MCFSIM_PADDR		(MCF_MBAR + 0x244)
+#define	MCFSIM_PADAT		(MCF_MBAR + 0x248)
 
+/*
+ * Generic GPIO support
+ */
+#define MCFGPIO_PIN_MAX			16
+#define MCFGPIO_IRQ_MAX			-1
+#define MCFGPIO_IRQ_VECBASE		-1
 
 /*
  *	Some symbol defines for the above...
@@ -91,19 +97,6 @@
 #define	MCFSIM_DMA3ICR		MCFSIM_ICR9	/* DMA 3 ICR */
 
 /*
- *	Macro to set IMR register. It is 32 bits on the 5407.
- */
-#define	mcf_getimr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR))
-
-#define	mcf_setimr(imr)		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IMR)) = (imr);
-
-#define	mcf_getipr()		\
-	*((volatile unsigned long *) (MCF_MBAR + MCFSIM_IPR))
-
-
-/*
  *	Some symbol defines for the Parallel Port Pin Assignment Register
  */
 #define MCFSIM_PAR_DREQ0        0x40            /* Set to select DREQ0 input */
@@ -118,6 +111,11 @@
 #define IRQ3_LEVEL6	0x40
 #define IRQ1_LEVEL2	0x20
 
+/*
+ *	Define system peripheral IRQ usage.
+ */
+#define	MCF_IRQ_TIMER		30		/* Timer0, Level 6 */
+#define	MCF_IRQ_PROFILER	31		/* Timer1, Level 7 */
 
 /*
  *	Define the Cache register flags.
diff --git a/arch/m68k/include/asm/mcfgpio.h b/arch/m68k/include/asm/mcfgpio.h
new file mode 100644
index 0000000..ee5e4cc
--- /dev/null
+++ b/arch/m68k/include/asm/mcfgpio.h
@@ -0,0 +1,40 @@
+/*
+ * Coldfire generic GPIO support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 mcfgpio_h
+#define mcfgpio_h
+
+#include <linux/io.h>
+#include <asm-generic/gpio.h>
+
+struct mcf_gpio_chip {
+	struct gpio_chip gpio_chip;
+	void __iomem *pddr;
+	void __iomem *podr;
+	void __iomem *ppdr;
+	void __iomem *setr;
+	void __iomem *clrr;
+	const u8 *gpio_to_pinmux;
+};
+
+int mcf_gpio_direction_input(struct gpio_chip *, unsigned);
+int mcf_gpio_get_value(struct gpio_chip *, unsigned);
+int mcf_gpio_direction_output(struct gpio_chip *, unsigned, int);
+void mcf_gpio_set_value(struct gpio_chip *, unsigned, int);
+void mcf_gpio_set_value_fast(struct gpio_chip *, unsigned, int);
+int mcf_gpio_request(struct gpio_chip *, unsigned);
+void mcf_gpio_free(struct gpio_chip *, unsigned);
+
+#endif
diff --git a/arch/m68k/include/asm/mcfintc.h b/arch/m68k/include/asm/mcfintc.h
new file mode 100644
index 0000000..4183320
--- /dev/null
+++ b/arch/m68k/include/asm/mcfintc.h
@@ -0,0 +1,89 @@
+/****************************************************************************/
+
+/*
+ *	mcfintc.h -- support definitions for the simple ColdFire
+ *		     Interrupt Controller
+ *
+ * 	(C) Copyright 2009,  Greg Ungerer <gerg@uclinux.org>
+ */
+
+/****************************************************************************/
+#ifndef	mcfintc_h
+#define	mcfintc_h
+/****************************************************************************/
+
+/*
+ * Most of the older ColdFire parts use the same simple interrupt
+ * controller. This is currently used on the 5206, 5206e, 5249, 5307
+ * and 5407 parts.
+ *
+ * The builtin peripherals are masked through dedicated bits in the
+ * Interrupt Mask register (IMR) - and this is not indexed (or in any way
+ * related to) the actual interrupt number they use. So knowing the IRQ
+ * number doesn't explicitly map to a certain internal device for
+ * interrupt control purposes.
+ */
+
+/*
+ * Bit definitions for the ICR family of registers.
+ */
+#define	MCFSIM_ICR_AUTOVEC	0x80		/* Auto-vectored intr */
+#define	MCFSIM_ICR_LEVEL0	0x00		/* Level 0 intr */
+#define	MCFSIM_ICR_LEVEL1	0x04		/* Level 1 intr */
+#define	MCFSIM_ICR_LEVEL2	0x08		/* Level 2 intr */
+#define	MCFSIM_ICR_LEVEL3	0x0c		/* Level 3 intr */
+#define	MCFSIM_ICR_LEVEL4	0x10		/* Level 4 intr */
+#define	MCFSIM_ICR_LEVEL5	0x14		/* Level 5 intr */
+#define	MCFSIM_ICR_LEVEL6	0x18		/* Level 6 intr */
+#define	MCFSIM_ICR_LEVEL7	0x1c		/* Level 7 intr */
+
+#define	MCFSIM_ICR_PRI0		0x00		/* Priority 0 intr */
+#define	MCFSIM_ICR_PRI1		0x01		/* Priority 1 intr */
+#define	MCFSIM_ICR_PRI2		0x02		/* Priority 2 intr */
+#define	MCFSIM_ICR_PRI3		0x03		/* Priority 3 intr */
+
+/*
+ * IMR bit position definitions. Not all ColdFire parts with this interrupt
+ * controller actually support all of these interrupt sources. But the bit
+ * numbers are the same in all cores.
+ */
+#define	MCFINTC_EINT1		1		/* External int #1 */
+#define	MCFINTC_EINT2		2		/* External int #2 */
+#define	MCFINTC_EINT3		3		/* External int #3 */
+#define	MCFINTC_EINT4		4		/* External int #4 */
+#define	MCFINTC_EINT5		5		/* External int #5 */
+#define	MCFINTC_EINT6		6		/* External int #6 */
+#define	MCFINTC_EINT7		7		/* External int #7 */
+#define	MCFINTC_SWT		8		/* Software Watchdog */
+#define	MCFINTC_TIMER1		9
+#define	MCFINTC_TIMER2		10
+#define	MCFINTC_I2C		11		/* I2C / MBUS */
+#define	MCFINTC_UART0		12
+#define	MCFINTC_UART1		13
+#define	MCFINTC_DMA0		14
+#define	MCFINTC_DMA1		15
+#define	MCFINTC_DMA2		16
+#define	MCFINTC_DMA3		17
+#define	MCFINTC_QSPI		18
+
+#ifndef __ASSEMBLER__
+
+/*
+ * There is no one-is-one correspondance between the interrupt number (irq)
+ * and the bit fields on the mask register. So we create a per-cpu type
+ * mapping of irq to mask bit. The CPU platform code needs to register
+ * its supported irq's at init time, using this function.
+ */
+extern unsigned char mcf_irq2imr[];
+static inline void mcf_mapirq2imr(int irq, int imr)
+{
+	mcf_irq2imr[irq] = imr;
+}
+
+void mcf_autovector(int irq);
+void mcf_setimr(int index);
+void mcf_clrimr(int index);
+#endif
+
+/****************************************************************************/
+#endif	/* mcfintc_h */
diff --git a/arch/m68k/include/asm/mcfne.h b/arch/m68k/include/asm/mcfne.h
index 431f63a..bf638be 100644
--- a/arch/m68k/include/asm/mcfne.h
+++ b/arch/m68k/include/asm/mcfne.h
@@ -239,87 +239,4 @@ void ne2000_outsw(unsigned int addr, const void *vbuf, unsigned long len)
 #endif /* NE2000_OFFOFFSET */
 
 /****************************************************************************/
-
-#ifdef COLDFIRE_NE2000_FUNCS
-
-/*
- *	Lastly the interrupt set up code...
- *	Minor differences between the different board types.
- */
-
-#if defined(CONFIG_ARN5206)
-void ne2000_irqsetup(int irq)
-{
-	volatile unsigned char  *icrp;
-
-	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
-	*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2;
-	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
-}
-#endif
-
-#if defined(CONFIG_M5206eC3)
-void ne2000_irqsetup(int irq)
-{
-	volatile unsigned char  *icrp;
-
-	icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_ICR4);
-	*icrp = MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI2 | MCFSIM_ICR_AUTOVEC;
-	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT4);
-}
-#endif
-
-#if defined(CONFIG_M5206e) && defined(CONFIG_NETtel)
-void ne2000_irqsetup(int irq)
-{
-	mcf_autovector(irq);
-}
-#endif
-
-#if defined(CONFIG_M5272) && defined(CONFIG_NETtel)
-void ne2000_irqsetup(int irq)
-{
-	volatile unsigned long	*icrp;
-	volatile unsigned long	*pitr;
-
-	/* The NE2000 device uses external IRQ3 */
-	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-	*icrp = (*icrp & 0x77077777) | 0x00d00000;
-
-	pitr = (volatile unsigned long *) (MCF_MBAR + MCFSIM_PITR);
-	*pitr = *pitr | 0x20000000;
-}
-
-void ne2000_irqack(int irq)
-{
-	volatile unsigned long	*icrp;
-
-	/* The NE2000 device uses external IRQ3 */
-	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-	*icrp = (*icrp & 0x77777777) | 0x00800000;
-}
-#endif
-
-#if defined(CONFIG_M5307) || defined(CONFIG_M5407)
-#if defined(CONFIG_NETtel) || defined(CONFIG_SECUREEDGEMP3)
-
-void ne2000_irqsetup(int irq)
-{
-	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
-	mcf_autovector(irq);
-}
-
-#else
-
-void ne2000_irqsetup(int irq)
-{
-	mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_EINT3);
-}
-
-#endif /* ! CONFIG_NETtel || CONFIG_SECUREEDGEMP3 */
-#endif /* CONFIG_M5307 || CONFIG_M5407 */
-
-#endif /* COLDFIRE_NE2000_FUNCS */
-
-/****************************************************************************/
 #endif	/* mcfne_h */
diff --git a/arch/m68k/include/asm/mcfsim.h b/arch/m68k/include/asm/mcfsim.h
index da3f2ce..9c70a67 100644
--- a/arch/m68k/include/asm/mcfsim.h
+++ b/arch/m68k/include/asm/mcfsim.h
@@ -4,7 +4,7 @@
  *	mcfsim.h -- ColdFire System Integration Module support.
  *
  *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com)
- * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com) 
+ * 	(C) Copyright 2000, Lineo Inc. (www.lineo.com)
  */
 
 /****************************************************************************/
@@ -12,19 +12,21 @@
 #define	mcfsim_h
 /****************************************************************************/
 
-
 /*
- *	Include 5204, 5206/e, 5235, 5249, 5270/5271, 5272, 5280/5282,
- *	5307 or 5407 specific addresses.
+ * Include the appropriate ColdFire CPU specific System Integration Module
+ * (SIM) definitions.
  */
 #if defined(CONFIG_M5206) || defined(CONFIG_M5206e)
 #include <asm/m5206sim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M520x)
 #include <asm/m520xsim.h>
 #elif defined(CONFIG_M523x)
 #include <asm/m523xsim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M5249)
 #include <asm/m5249sim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M527x)
 #include <asm/m527xsim.h>
 #elif defined(CONFIG_M5272)
@@ -33,94 +35,13 @@
 #include <asm/m528xsim.h>
 #elif defined(CONFIG_M5307)
 #include <asm/m5307sim.h>
+#include <asm/mcfintc.h>
 #elif defined(CONFIG_M532x)
 #include <asm/m532xsim.h>
 #elif defined(CONFIG_M5407)
 #include <asm/m5407sim.h>
+#include <asm/mcfintc.h>
 #endif
 
-
-/*
- *	Define the base address of the SIM within the MBAR address space.
- */
-#define	MCFSIM_BASE		0x0		/* Base address of SIM */
-
-
-/*
- *	Bit definitions for the ICR family of registers.
- */
-#define	MCFSIM_ICR_AUTOVEC	0x80		/* Auto-vectored intr */
-#define	MCFSIM_ICR_LEVEL0	0x00		/* Level 0 intr */
-#define	MCFSIM_ICR_LEVEL1	0x04		/* Level 1 intr */
-#define	MCFSIM_ICR_LEVEL2	0x08		/* Level 2 intr */
-#define	MCFSIM_ICR_LEVEL3	0x0c		/* Level 3 intr */
-#define	MCFSIM_ICR_LEVEL4	0x10		/* Level 4 intr */
-#define	MCFSIM_ICR_LEVEL5	0x14		/* Level 5 intr */
-#define	MCFSIM_ICR_LEVEL6	0x18		/* Level 6 intr */
-#define	MCFSIM_ICR_LEVEL7	0x1c		/* Level 7 intr */
-
-#define	MCFSIM_ICR_PRI0		0x00		/* Priority 0 intr */
-#define	MCFSIM_ICR_PRI1		0x01		/* Priority 1 intr */
-#define	MCFSIM_ICR_PRI2		0x02		/* Priority 2 intr */
-#define	MCFSIM_ICR_PRI3		0x03		/* Priority 3 intr */
-
-/*
- *	Bit definitions for the Interrupt Mask register (IMR).
- */
-#define	MCFSIM_IMR_EINT1	0x0002		/* External intr # 1 */
-#define	MCFSIM_IMR_EINT2	0x0004		/* External intr # 2 */
-#define	MCFSIM_IMR_EINT3	0x0008		/* External intr # 3 */
-#define	MCFSIM_IMR_EINT4	0x0010		/* External intr # 4 */
-#define	MCFSIM_IMR_EINT5	0x0020		/* External intr # 5 */
-#define	MCFSIM_IMR_EINT6	0x0040		/* External intr # 6 */
-#define	MCFSIM_IMR_EINT7	0x0080		/* External intr # 7 */
-
-#define	MCFSIM_IMR_SWD		0x0100		/* Software Watchdog intr */
-#define	MCFSIM_IMR_TIMER1	0x0200		/* TIMER 1 intr */
-#define	MCFSIM_IMR_TIMER2	0x0400		/* TIMER 2 intr */
-#define MCFSIM_IMR_MBUS		0x0800		/* MBUS intr	*/
-#define	MCFSIM_IMR_UART1	0x1000		/* UART 1 intr */
-#define	MCFSIM_IMR_UART2	0x2000		/* UART 2 intr */
-
-#if defined(CONFIG_M5206e)
-#define	MCFSIM_IMR_DMA1		0x4000		/* DMA 1 intr */
-#define	MCFSIM_IMR_DMA2		0x8000		/* DMA 2 intr */
-#elif defined(CONFIG_M5249) || defined(CONFIG_M5307)
-#define	MCFSIM_IMR_DMA0		0x4000		/* DMA 0 intr */
-#define	MCFSIM_IMR_DMA1		0x8000		/* DMA 1 intr */
-#define	MCFSIM_IMR_DMA2		0x10000		/* DMA 2 intr */
-#define	MCFSIM_IMR_DMA3		0x20000		/* DMA 3 intr */
-#endif
-
-/*
- *	Mask for all of the SIM devices. Some parts have more or less
- *	SIM devices. This is a catchall for the sandard set.
- */
-#ifndef MCFSIM_IMR_MASKALL
-#define	MCFSIM_IMR_MASKALL	0x3ffe		/* All intr sources */
-#endif
-
-
-/*
- *	PIT interrupt settings, if not found in mXXXXsim.h file.
- */
-#ifndef	ICR_INTRCONF
-#define	ICR_INTRCONF		0x2b            /* PIT1 level 5, priority 3 */
-#endif
-#ifndef	MCFPIT_IMR
-#define	MCFPIT_IMR		MCFINTC_IMRH
-#endif
-#ifndef	MCFPIT_IMR_IBIT
-#define	MCFPIT_IMR_IBIT		(1 << (MCFINT_PIT1 - 32))
-#endif
-
-
-#ifndef __ASSEMBLY__
-/*
- *	Definition for the interrupt auto-vectoring support.
- */
-extern void	mcf_autovector(unsigned int vec);
-#endif /* __ASSEMBLY__ */
-
 /****************************************************************************/
 #endif	/* mcfsim_h */
diff --git a/arch/m68k/include/asm/mcfsmc.h b/arch/m68k/include/asm/mcfsmc.h
index 2d7a4db..527bea5 100644
--- a/arch/m68k/include/asm/mcfsmc.h
+++ b/arch/m68k/include/asm/mcfsmc.h
@@ -167,15 +167,15 @@ void smc_remap(unsigned int ioaddr)
 	static int		once = 0;
 	extern unsigned short	ppdata;
 	if (once++ == 0) {
-		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec;
+		*((volatile unsigned short *)MCFSIM_PADDR) = 0x00ec;
 		ppdata |= 0x0080;
-		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+		*((volatile unsigned short *)MCFSIM_PADAT) = ppdata;
 		outw(0x0001, ioaddr + BANK_SELECT);
 		outw(0x0001, ioaddr + BANK_SELECT);
 		outw(0x0067, ioaddr + BASE);
 
 		ppdata &= ~0x0080;
-		*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
+		*((volatile unsigned short *)MCFSIM_PADAT) = ppdata;
 	}
 	
 	*((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
diff --git a/arch/m68k/include/asm/nettel.h b/arch/m68k/include/asm/nettel.h
index 0299f6a..4dec2d9 100644
--- a/arch/m68k/include/asm/nettel.h
+++ b/arch/m68k/include/asm/nettel.h
@@ -48,14 +48,14 @@ extern volatile unsigned short ppdata;
 static __inline__ unsigned int mcf_getppdata(void)
 {
 	volatile unsigned short *pp;
-	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	pp = (volatile unsigned short *) MCFSIM_PADAT;
 	return((unsigned int) *pp);
 }
 
 static __inline__ void mcf_setppdata(unsigned int mask, unsigned int bits)
 {
 	volatile unsigned short *pp;
-	pp = (volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT);
+	pp = (volatile unsigned short *) MCFSIM_PADAT;
 	ppdata = (ppdata & ~mask) | bits;
 	*pp = ppdata;
 }
diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h
index 9aa3f90..1f31b06 100644
--- a/arch/m68k/include/asm/page_no.h
+++ b/arch/m68k/include/asm/page_no.h
@@ -1,10 +1,12 @@
 #ifndef _M68KNOMMU_PAGE_H
 #define _M68KNOMMU_PAGE_H
 
+#include <linux/const.h>
+
 /* PAGE_SHIFT determines the page size */
 
 #define PAGE_SHIFT	(12)
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
 #include <asm/setup.h>
diff --git a/arch/m68k/include/asm/pinmux.h b/arch/m68k/include/asm/pinmux.h
new file mode 100644
index 0000000..119ee68
--- /dev/null
+++ b/arch/m68k/include/asm/pinmux.h
@@ -0,0 +1,30 @@
+/*
+ * Coldfire generic GPIO pinmux support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 pinmux_h
+#define pinmux_h
+
+#define MCFPINMUX_NONE		-1
+
+extern int mcf_pinmux_request(unsigned, unsigned);
+extern void mcf_pinmux_release(unsigned, unsigned);
+
+static inline int mcf_pinmux_is_valid(unsigned pinmux)
+{
+	return pinmux != MCFPINMUX_NONE;
+}
+
+#endif
+
diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
index fc3f2c2..74fd674 100644
--- a/arch/m68k/include/asm/processor.h
+++ b/arch/m68k/include/asm/processor.h
@@ -1,5 +1,170 @@
-#ifdef __uClinux__
-#include "processor_no.h"
+/*
+ * include/asm-m68k/processor.h
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ */
+
+#ifndef __ASM_M68K_PROCESSOR_H
+#define __ASM_M68K_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/thread_info.h>
+#include <asm/segment.h>
+#include <asm/fpu.h>
+#include <asm/ptrace.h>
+
+static inline unsigned long rdusp(void)
+{
+#ifdef CONFIG_COLDFIRE
+	extern unsigned int sw_usp;
+	return sw_usp;
 #else
-#include "processor_mm.h"
+	unsigned long usp;
+	__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
+	return usp;
+#endif
+}
+
+static inline void wrusp(unsigned long usp)
+{
+#ifdef CONFIG_COLDFIRE
+	extern unsigned int sw_usp;
+	sw_usp = usp;
+#else
+	__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
+#endif
+}
+
+/*
+ * User space process size: 3.75GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#ifndef CONFIG_SUN3
+#define TASK_SIZE	(0xF0000000UL)
+#else
+#define TASK_SIZE	(0x0E000000UL)
+#endif
+
+#ifdef __KERNEL__
+#define STACK_TOP	TASK_SIZE
+#define STACK_TOP_MAX	STACK_TOP
+#endif
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#ifdef CONFIG_MMU
+#ifndef CONFIG_SUN3
+#define TASK_UNMAPPED_BASE	0xC0000000UL
+#else
+#define TASK_UNMAPPED_BASE	0x0A000000UL
+#endif
+#define TASK_UNMAPPED_ALIGN(addr, off)	PAGE_ALIGN(addr)
+#else
+#define TASK_UNMAPPED_BASE	0
+#endif
+
+struct thread_struct {
+	unsigned long  ksp;		/* kernel stack pointer */
+	unsigned long  usp;		/* user stack pointer */
+	unsigned short sr;		/* saved status register */
+	unsigned short fs;		/* saved fs (sfc, dfc) */
+	unsigned long  crp[2];		/* cpu root pointer */
+	unsigned long  esp0;		/* points to SR of stack frame */
+	unsigned long  faddr;		/* info about last fault */
+	int            signo, code;
+	unsigned long  fp[8*3];
+	unsigned long  fpcntl[3];	/* fp control regs */
+	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
+	struct thread_info info;
+};
+
+#define INIT_THREAD  {							\
+	.ksp	= sizeof(init_stack) + (unsigned long) init_stack,	\
+	.sr	= PS_S,							\
+	.fs	= __KERNEL_DS,						\
+	.info	= INIT_THREAD_INFO(init_task),				\
+}
+
+#ifdef CONFIG_MMU
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+static inline void start_thread(struct pt_regs * regs, unsigned long pc,
+				unsigned long usp)
+{
+	/* reads from user space */
+	set_fs(USER_DS);
+
+	regs->pc = pc;
+	regs->sr &= ~0x2000;
+	wrusp(usp);
+}
+
+#else
+
+/*
+ * Coldfire stacks need to be re-aligned on trap exit, conventional
+ * 68k can handle this case cleanly.
+ */
+#ifdef CONFIG_COLDFIRE
+#define reformat(_regs)		do { (_regs)->format = 0x4; } while(0)
+#else
+#define reformat(_regs)		do { } while (0)
+#endif
+
+#define start_thread(_regs, _pc, _usp)                  \
+do {                                                    \
+	set_fs(USER_DS); /* reads from user space */    \
+	(_regs)->pc = (_pc);                            \
+	((struct switch_stack *)(_regs))[-1].a6 = 0;    \
+	reformat(_regs);                                \
+	if (current->mm)                                \
+		(_regs)->d5 = current->mm->start_data;  \
+	(_regs)->sr &= ~0x2000;                         \
+	wrusp(_usp);                                    \
+} while(0)
+
+#endif
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)	do { } while (0)
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+/*
+ * Free current thread data structures etc..
+ */
+static inline void exit_thread(void)
+{
+}
+
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)	\
+    ({			\
+	unsigned long eip = 0;	 \
+	if ((tsk)->thread.esp0 > PAGE_SIZE && \
+	    (virt_addr_valid((tsk)->thread.esp0))) \
+	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
+	eip; })
+#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define cpu_relax()	barrier()
+
 #endif
diff --git a/arch/m68k/include/asm/processor_mm.h b/arch/m68k/include/asm/processor_mm.h
deleted file mode 100644
index 1f61ef5..0000000
--- a/arch/m68k/include/asm/processor_mm.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * include/asm-m68k/processor.h
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#ifndef __ASM_M68K_PROCESSOR_H
-#define __ASM_M68K_PROCESSOR_H
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-#include <linux/thread_info.h>
-#include <asm/segment.h>
-#include <asm/fpu.h>
-#include <asm/ptrace.h>
-
-static inline unsigned long rdusp(void)
-{
-	unsigned long usp;
-
-	__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
-	return usp;
-}
-
-static inline void wrusp(unsigned long usp)
-{
-	__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
-}
-
-/*
- * User space process size: 3.75GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#ifndef CONFIG_SUN3
-#define TASK_SIZE	(0xF0000000UL)
-#else
-#define TASK_SIZE	(0x0E000000UL)
-#endif
-
-#ifdef __KERNEL__
-#define STACK_TOP	TASK_SIZE
-#define STACK_TOP_MAX	STACK_TOP
-#endif
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#ifndef CONFIG_SUN3
-#define TASK_UNMAPPED_BASE	0xC0000000UL
-#else
-#define TASK_UNMAPPED_BASE	0x0A000000UL
-#endif
-#define TASK_UNMAPPED_ALIGN(addr, off)	PAGE_ALIGN(addr)
-
-struct thread_struct {
-	unsigned long  ksp;		/* kernel stack pointer */
-	unsigned long  usp;		/* user stack pointer */
-	unsigned short sr;		/* saved status register */
-	unsigned short fs;		/* saved fs (sfc, dfc) */
-	unsigned long  crp[2];		/* cpu root pointer */
-	unsigned long  esp0;		/* points to SR of stack frame */
-	unsigned long  faddr;		/* info about last fault */
-	int            signo, code;
-	unsigned long  fp[8*3];
-	unsigned long  fpcntl[3];	/* fp control regs */
-	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
-	struct thread_info info;
-};
-
-#define INIT_THREAD  {							\
-	.ksp	= sizeof(init_stack) + (unsigned long) init_stack,	\
-	.sr	= PS_S,							\
-	.fs	= __KERNEL_DS,						\
-	.info	= INIT_THREAD_INFO(init_task),				\
-}
-
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-static inline void start_thread(struct pt_regs * regs, unsigned long pc,
-				unsigned long usp)
-{
-	/* reads from user space */
-	set_fs(USER_DS);
-
-	regs->pc = pc;
-	regs->sr &= ~0x2000;
-	wrusp(usp);
-}
-
-/* Forward declaration, a strange C thing */
-struct task_struct;
-
-/* Free all resources held by a thread. */
-static inline void release_thread(struct task_struct *dead_task)
-{
-}
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)	do { } while (0)
-
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/*
- * Free current thread data structures etc..
- */
-static inline void exit_thread(void)
-{
-}
-
-extern unsigned long thread_saved_pc(struct task_struct *tsk);
-
-unsigned long get_wchan(struct task_struct *p);
-
-#define	KSTK_EIP(tsk)	\
-    ({			\
-	unsigned long eip = 0;	 \
-	if ((tsk)->thread.esp0 > PAGE_SIZE && \
-	    (virt_addr_valid((tsk)->thread.esp0))) \
-	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
-	eip; })
-#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
-
-#define cpu_relax()	barrier()
-
-#endif
diff --git a/arch/m68k/include/asm/processor_no.h b/arch/m68k/include/asm/processor_no.h
deleted file mode 100644
index 7a1e0ba..0000000
--- a/arch/m68k/include/asm/processor_no.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * include/asm-m68knommu/processor.h
- *
- * Copyright (C) 1995 Hamish Macdonald
- */
-
-#ifndef __ASM_M68K_PROCESSOR_H
-#define __ASM_M68K_PROCESSOR_H
-
-/*
- * Default implementation of macro that returns current
- * instruction pointer ("program counter").
- */
-#define current_text_addr() ({ __label__ _l; _l: &&_l;})
-
-#include <linux/compiler.h>
-#include <linux/threads.h>
-#include <asm/types.h>
-#include <asm/segment.h>
-#include <asm/fpu.h>
-#include <asm/ptrace.h>
-#include <asm/current.h>
-
-static inline unsigned long rdusp(void)
-{
-#ifdef CONFIG_COLDFIRE
-	extern unsigned int sw_usp;
-	return(sw_usp);
-#else
-  	unsigned long usp;
-	__asm__ __volatile__("move %/usp,%0" : "=a" (usp));
-	return usp;
-#endif
-}
-
-static inline void wrusp(unsigned long usp)
-{
-#ifdef CONFIG_COLDFIRE
-	extern unsigned int sw_usp;
-	sw_usp = usp;
-#else
-	__asm__ __volatile__("move %0,%/usp" : : "a" (usp));
-#endif
-}
-
-/*
- * User space process size: 3.75GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#define TASK_SIZE	(0xF0000000UL)
-
-/*
- * This decides where the kernel will search for a free chunk of vm
- * space during mmap's. We won't be using it
- */
-#define TASK_UNMAPPED_BASE	0
-
-/* 
- * if you change this structure, you must change the code and offsets
- * in m68k/machasm.S
- */
-   
-struct thread_struct {
-	unsigned long  ksp;		/* kernel stack pointer */
-	unsigned long  usp;		/* user stack pointer */
-	unsigned short sr;		/* saved status register */
-	unsigned short fs;		/* saved fs (sfc, dfc) */
-	unsigned long  crp[2];		/* cpu root pointer */
-	unsigned long  esp0;		/* points to SR of stack frame */
-	unsigned long  fp[8*3];
-	unsigned long  fpcntl[3];	/* fp control regs */
-	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
-};
-
-#define INIT_THREAD  {							\
-	.ksp	= sizeof(init_stack) + (unsigned long) init_stack,	\
-	.sr	= PS_S,							\
-	.fs	= __KERNEL_DS,						\
-}
-
-/*
- * Coldfire stacks need to be re-aligned on trap exit, conventional
- * 68k can handle this case cleanly.
- */
-#if defined(CONFIG_COLDFIRE)
-#define	reformat(_regs)		do { (_regs)->format = 0x4; } while(0)
-#else
-#define	reformat(_regs)		do { } while (0)
-#endif
-
-/*
- * Do necessary setup to start up a newly executed thread.
- *
- * pass the data segment into user programs if it exists,
- * it can't hurt anything as far as I can tell
- */
-#define start_thread(_regs, _pc, _usp)			\
-do {							\
-	set_fs(USER_DS); /* reads from user space */	\
-	(_regs)->pc = (_pc);				\
-	((struct switch_stack *)(_regs))[-1].a6 = 0;	\
-	reformat(_regs);				\
-	if (current->mm)				\
-		(_regs)->d5 = current->mm->start_data;	\
-	(_regs)->sr &= ~0x2000;				\
-	wrusp(_usp);					\
-} while(0)
-
-/* Forward declaration, a strange C thing */
-struct task_struct;
-
-/* Free all resources held by a thread. */
-static inline void release_thread(struct task_struct *dead_task)
-{
-}
-
-/* Prepare to copy thread state - unlazy all lazy status */
-#define prepare_to_copy(tsk)	do { } while (0)
-
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-/*
- * Free current thread data structures etc..
- */
-static inline void exit_thread(void)
-{
-}
-
-unsigned long thread_saved_pc(struct task_struct *tsk);
-unsigned long get_wchan(struct task_struct *p);
-
-#define	KSTK_EIP(tsk)	\
-    ({			\
-	unsigned long eip = 0;	 \
-	if ((tsk)->thread.esp0 > PAGE_SIZE && \
-	    (virt_addr_valid((tsk)->thread.esp0))) \
-	      eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
-	eip; })
-#define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
-
-#define cpu_relax()    barrier()
-
-#endif
diff --git a/arch/m68k/include/asm/socket.h b/arch/m68k/include/asm/socket.h
index ca87f93..eee01cc 100644
--- a/arch/m68k/include/asm/socket.h
+++ b/arch/m68k/include/asm/socket.h
@@ -57,4 +57,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/m68k/include/asm/timex.h b/arch/m68k/include/asm/timex.h
index b87f2f2..6759dad 100644
--- a/arch/m68k/include/asm/timex.h
+++ b/arch/m68k/include/asm/timex.h
@@ -3,10 +3,23 @@
  *
  * m68k architecture timex specifications
  */
-#ifndef _ASMm68k_TIMEX_H
-#define _ASMm68k_TIMEX_H
+#ifndef _ASMm68K_TIMEX_H
+#define _ASMm68K_TIMEX_H
 
+#ifdef CONFIG_COLDFIRE
+/*
+ * CLOCK_TICK_RATE should give the underlying frequency of the tick timer
+ * to make ntp work best.  For Coldfires, that's the main clock.
+ */
+#include <asm/coldfire.h>
+#define CLOCK_TICK_RATE	MCF_CLK
+#else
+/*
+ * This default CLOCK_TICK_RATE is probably wrong for many 68k boards
+ * Users of those boards will need to check and modify accordingly
+ */
 #define CLOCK_TICK_RATE	1193180 /* Underlying HZ */
+#endif
 
 typedef unsigned long cycles_t;
 
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index 946d869..48b87f5 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -335,7 +335,7 @@
 #define __NR_preadv		329
 #define __NR_pwritev		330
 #define __NR_rt_tgsigqueueinfo	331
-#define __NR_perf_counter_open	332
+#define __NR_perf_event_open	332
 
 #ifdef __KERNEL__
 
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 922f52e..c5b3363 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -756,5 +756,5 @@ sys_call_table:
 	.long sys_preadv
 	.long sys_pwritev		/* 330 */
 	.long sys_rt_tgsigqueueinfo
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
 
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 01d212b..47eac19 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -82,13 +82,6 @@ SECTIONS
 
   _end = . ;
 
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	EXIT_TEXT
-	EXIT_DATA
-	*(.exitcall.exit)
-	}
-
   /* Stabs debugging sections.  */
   .stab 0 : { *(.stab) }
   .stabstr 0 : { *(.stabstr) }
@@ -97,4 +90,7 @@ SECTIONS
   .stab.index 0 : { *(.stab.index) }
   .stab.indexstr 0 : { *(.stab.indexstr) }
   .comment 0 : { *(.comment) }
+
+  /* Sections to be discarded */
+  DISCARDS
 }
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index c192f77..03efaf0 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -77,13 +77,6 @@ __init_begin = .;
 
   _end = . ;
 
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	EXIT_TEXT
-	EXIT_DATA
-	*(.exitcall.exit)
-	}
-
   .crap : {
 	/* Stabs debugging sections.  */
 	*(.stab)
@@ -96,4 +89,6 @@ __init_begin = .;
 	*(.note)
   }
 
+  /* Sections to be discarded */
+  DISCARDS
 }
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 5343762..e2201b9 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -47,6 +47,10 @@ config GENERIC_FIND_NEXT_BIT
 	bool
 	default y
 
+config GENERIC_GPIO
+	bool
+	default n
+
 config GENERIC_HWEIGHT
 	bool
 	default y
@@ -182,6 +186,8 @@ config M527x
 config COLDFIRE
 	bool
 	depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407)
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
 	default y
 
 config CLOCK_SET
diff --git a/arch/m68knommu/kernel/irq.c b/arch/m68knommu/kernel/irq.c
index 56e0f4c..c9cac36 100644
--- a/arch/m68knommu/kernel/irq.c
+++ b/arch/m68knommu/kernel/irq.c
@@ -29,32 +29,6 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
 	set_irq_regs(oldregs);
 }
 
-void ack_bad_irq(unsigned int irq)
-{
-	printk(KERN_ERR "IRQ: unexpected irq=%d\n", irq);
-}
-
-static struct irq_chip m_irq_chip = {
-	.name		= "M68K-INTC",
-	.enable		= enable_vector,
-	.disable	= disable_vector,
-	.ack		= ack_vector,
-};
-
-void __init init_IRQ(void)
-{
-	int irq;
-
-	init_vectors();
-
-	for (irq = 0; (irq < NR_IRQS); irq++) {
-		irq_desc[irq].status = IRQ_DISABLED;
-		irq_desc[irq].action = NULL;
-		irq_desc[irq].depth = 1;
-		irq_desc[irq].chip = &m_irq_chip;
-	}
-}
-
 int show_interrupts(struct seq_file *p, void *v)
 {
 	struct irqaction *ap;
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
index 0ae123e..23535cc 100644
--- a/arch/m68knommu/kernel/syscalltable.S
+++ b/arch/m68knommu/kernel/syscalltable.S
@@ -350,7 +350,7 @@ ENTRY(sys_call_table)
 	.long sys_preadv
 	.long sys_pwritev		/* 330 */
 	.long sys_rt_tgsigqueueinfo
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
index d182b2f..a90acf5 100644
--- a/arch/m68knommu/kernel/time.c
+++ b/arch/m68knommu/kernel/time.c
@@ -69,12 +69,13 @@ static unsigned long read_rtc_mmss(void)
 	if ((year += 1900) < 1970)
 		year += 100;
 
-	return  mktime(year, mon, day, hour, min, sec);;
+	return  mktime(year, mon, day, hour, min, sec);
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-	return read_rtc_mmss();
+	ts->tv_sec = read_rtc_mmss();
+	ts->tv_nsec = 0;
 }
 
 int update_persistent_clock(struct timespec now)
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index b7fe505..2736a5e 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -184,12 +184,6 @@ SECTIONS {
 		__init_end = .;
 	} > INIT
 
-	/DISCARD/ : {
-		EXIT_TEXT
-		EXIT_DATA
-		*(.exitcall.exit)
-	}
-
 	.bss : {
 		. = ALIGN(4);
 		_sbss = . ;
@@ -200,5 +194,6 @@ SECTIONS {
 	 	_end = . ;
 	} > BSS
 
+	DISCARDS
 }
 
diff --git a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c
index 269d83b..eccf25d 100644
--- a/arch/m68knommu/lib/checksum.c
+++ b/arch/m68knommu/lib/checksum.c
@@ -92,6 +92,7 @@ out:
 	return result;
 }
 
+#ifdef CONFIG_COLDFIRE
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,
  *	which always checksum on 4 octet boundaries.
@@ -100,6 +101,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 {
 	return (__force __sum16)~do_csum(iph,ihl*4);
 }
+#endif
 
 /*
  * computes the checksum of a memory block at buff, length len,
@@ -127,15 +129,6 @@ __wsum csum_partial(const void *buff, int len, __wsum sum)
 EXPORT_SYMBOL(csum_partial);
 
 /*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-__sum16 ip_compute_csum(const void *buff, int len)
-{
-	return (__force __sum16)~do_csum(buff,len);
-}
-
-/*
  * copy from fs while checksumming, otherwise like csum_partial
  */
 
diff --git a/arch/m68knommu/platform/5206/Makefile b/arch/m68knommu/platform/5206/Makefile
index a439d9a..113c333 100644
--- a/arch/m68knommu/platform/5206/Makefile
+++ b/arch/m68knommu/platform/5206/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c
index f6f7987..9c33546 100644
--- a/arch/m68knommu/platform/5206/config.c
+++ b/arch/m68knommu/platform/5206/config.c
@@ -49,11 +49,11 @@ static void __init m5206_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);
-		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+		mcf_mapirq2imr(irq, MCFINTC_UART0);
 	} else if (line == 1) {
 		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
 		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
-		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+		mcf_mapirq2imr(irq, MCFINTC_UART1);
 	}
 }
 
@@ -68,38 +68,19 @@ static void __init m5206_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
+static void __init m5206_timers_init(void)
 {
-	volatile unsigned char  *mbar;
-	unsigned char		icr;
-
-	if ((vec >= 25) && (vec <= 31)) {
-		vec -= 25;
-		mbar = (volatile unsigned char *) MCF_MBAR;
-		icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
-		*(mbar + MCFSIM_ICR1 + vec) = icr;
-		vec = 0x1 << (vec + 1);
-		mcf_setimr(mcf_getimr() & ~vec);
-	}
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
-{
-	volatile unsigned char *icrp;
-	unsigned int icr, imr;
-
-	if (timer <= 2) {
-		switch (timer) {
-		case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-		default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-		}
-
-		icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-		*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-		mcf_setimr(mcf_getimr() & ~imr);
-	}
+	/* Timer1 is always used as system timer */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER1ICR);
+	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+	/* Timer2 is to be used as a high speed profile timer  */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER2ICR);
+	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -117,15 +98,20 @@ void m5206_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_setimr(MCFSIM_IMR_MASKALL);
 	mach_reset = m5206_cpu_reset;
+	m5206_timers_init();
+	m5206_uarts_init();
+
+	/* Only support the external interrupts on their primary level */
+	mcf_mapirq2imr(25, MCFINTC_EINT1);
+	mcf_mapirq2imr(28, MCFINTC_EINT4);
+	mcf_mapirq2imr(31, MCFINTC_EINT7);
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-	m5206_uarts_init();
 	platform_add_devices(m5206_devices, ARRAY_SIZE(m5206_devices));
 	return 0;
 }
diff --git a/arch/m68knommu/platform/5206/gpio.c b/arch/m68knommu/platform/5206/gpio.c
new file mode 100644
index 0000000..60f779c
--- /dev/null
+++ b/arch/m68knommu/platform/5206/gpio.c
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PP",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFSIM_PADDR,
+		.podr				= MCFSIM_PADAT,
+		.ppdr				= MCFSIM_PADAT,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5206e/Makefile b/arch/m68knommu/platform/5206e/Makefile
index a439d9a..113c333 100644
--- a/arch/m68knommu/platform/5206e/Makefile
+++ b/arch/m68knommu/platform/5206e/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
index 6588779..0f41ba8 100644
--- a/arch/m68knommu/platform/5206e/config.c
+++ b/arch/m68knommu/platform/5206e/config.c
@@ -15,6 +15,7 @@
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
+#include <asm/mcfuart.h>
 #include <asm/mcfdma.h>
 #include <asm/mcfuart.h>
 
@@ -49,11 +50,11 @@ static void __init m5206e_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);
-		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1);
+		mcf_mapirq2imr(irq, MCFINTC_UART0);
 	} else if (line == 1) {
 		writel(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
 		writeb(irq, MCFUART_BASE2 + MCFUART_UIVR);
-		mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2);
+		mcf_mapirq2imr(irq, MCFINTC_UART1);
 	}
 }
 
@@ -68,38 +69,19 @@ static void __init m5206e_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-	volatile unsigned char  *mbar;
-	unsigned char		icr;
-
-	if ((vec >= 25) && (vec <= 31)) {
-		vec -= 25;
-		mbar = (volatile unsigned char *) MCF_MBAR;
-		icr = MCFSIM_ICR_AUTOVEC | (vec << 3);
-		*(mbar + MCFSIM_ICR1 + vec) = icr;
-		vec = 0x1 << (vec + 1);
-		mcf_setimr(mcf_getimr() & ~vec);
-	}
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
+static void __init m5206e_timers_init(void)
 {
-	volatile unsigned char *icrp;
-	unsigned int icr, imr;
-
-	if (timer <= 2) {
-		switch (timer) {
-		case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-		default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-		}
-
-		icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-		*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-		mcf_setimr(mcf_getimr() & ~imr);
-	}
+	/* Timer1 is always used as system timer */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER1ICR);
+	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+	/* Timer2 is to be used as a high speed profile timer  */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER2ICR);
+	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -117,8 +99,6 @@ void m5206e_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_setimr(MCFSIM_IMR_MASKALL);
-
 #if defined(CONFIG_NETtel)
 	/* Copy command line from FLASH to local buffer... */
 	memcpy(commandp, (char *) 0xf0004000, size);
@@ -126,13 +106,19 @@ void __init config_BSP(char *commandp, int size)
 #endif /* CONFIG_NETtel */
 
 	mach_reset = m5206e_cpu_reset;
+	m5206e_timers_init();
+	m5206e_uarts_init();
+
+	/* Only support the external interrupts on their primary level */
+	mcf_mapirq2imr(25, MCFINTC_EINT1);
+	mcf_mapirq2imr(28, MCFINTC_EINT4);
+	mcf_mapirq2imr(31, MCFINTC_EINT7);
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-	m5206e_uarts_init();
 	platform_add_devices(m5206e_devices, ARRAY_SIZE(m5206e_devices));
 	return 0;
 }
diff --git a/arch/m68knommu/platform/5206e/gpio.c b/arch/m68knommu/platform/5206e/gpio.c
new file mode 100644
index 0000000..60f779c
--- /dev/null
+++ b/arch/m68knommu/platform/5206e/gpio.c
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PP",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFSIM_PADDR,
+		.podr				= MCFSIM_PADAT,
+		.ppdr				= MCFSIM_PADAT,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile
index a50e76a..435ab34 100644
--- a/arch/m68knommu/platform/520x/Makefile
+++ b/arch/m68knommu/platform/520x/Makefile
@@ -14,4 +14,4 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
index 1c43a8a..92614de 100644
--- a/arch/m68knommu/platform/520x/config.c
+++ b/arch/m68knommu/platform/520x/config.c
@@ -81,20 +81,11 @@ static struct platform_device *m520x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define	INTC0	(MCF_MBAR + MCFICM_INTC0)
-
 static void __init m520x_uart_init_line(int line, int irq)
 {
-	u32 imr;
 	u16 par;
 	u8 par2;
 
-	writeb(0x03, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
-	imr = readl(INTC0 + MCFINTC_IMRL);
-	imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-	writel(imr, INTC0 + MCFINTC_IMRL);
-
 	switch (line) {
 	case 0:
 		par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
@@ -131,18 +122,8 @@ static void __init m520x_uarts_init(void)
 
 static void __init m520x_fec_init(void)
 {
-	u32 imr;
 	u8 v;
 
-	/* Unmask FEC interrupts at ColdFire interrupt controller */
-	writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36);
-	writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40);
-	writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42);
-
-	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-	imr &= ~0x0001FFF0;
-	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-
 	/* Set multi-function pins to ethernet mode */
 	v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
 	writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
@@ -153,17 +134,6 @@ static void __init m520x_fec_init(void)
 
 /***************************************************************************/
 
-/*
- *  Program the vector to be an auto-vectored.
- */
-
-void mcf_autovector(unsigned int vec)
-{
-    /* Everything is auto-vectored on the 520x devices */
-}
-
-/***************************************************************************/
-
 static void m520x_cpu_reset(void)
 {
 	local_irq_disable();
diff --git a/arch/m68knommu/platform/520x/gpio.c b/arch/m68knommu/platform/520x/gpio.c
new file mode 100644
index 0000000..15b5bb6
--- /dev/null
+++ b/arch/m68knommu/platform/520x/gpio.c
@@ -0,0 +1,211 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PIRQ",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFEPORT_EPDDR,
+		.podr				= MCFEPORT_EPDR,
+		.ppdr				= MCFEPORT_EPPDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BUSCTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 8,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_BUSCTL,
+		.podr				= MCFGPIO_PODR_BUSCTL,
+		.ppdr				= MCFGPIO_PPDSDR_BUSCTL,
+		.setr				= MCFGPIO_PPDSDR_BUSCTL,
+		.clrr				= MCFGPIO_PCLRR_BUSCTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BE",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 16,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_BE,
+		.podr				= MCFGPIO_PODR_BE,
+		.ppdr				= MCFGPIO_PPDSDR_BE,
+		.setr				= MCFGPIO_PPDSDR_BE,
+		.clrr				= MCFGPIO_PCLRR_BE,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "CS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 25,
+			.ngpio			= 3,
+		},
+		.pddr				= MCFGPIO_PDDR_CS,
+		.podr				= MCFGPIO_PODR_CS,
+		.ppdr				= MCFGPIO_PPDSDR_CS,
+		.setr				= MCFGPIO_PPDSDR_CS,
+		.clrr				= MCFGPIO_PCLRR_CS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECI2C",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 32,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_FECI2C,
+		.podr				= MCFGPIO_PODR_FECI2C,
+		.ppdr				= MCFGPIO_PPDSDR_FECI2C,
+		.setr				= MCFGPIO_PPDSDR_FECI2C,
+		.clrr				= MCFGPIO_PCLRR_FECI2C,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QSPI",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 40,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_QSPI,
+		.podr				= MCFGPIO_PODR_QSPI,
+		.ppdr				= MCFGPIO_PPDSDR_QSPI,
+		.setr				= MCFGPIO_PPDSDR_QSPI,
+		.clrr				= MCFGPIO_PCLRR_QSPI,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TIMER",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 48,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_TIMER,
+		.podr				= MCFGPIO_PODR_TIMER,
+		.ppdr				= MCFGPIO_PPDSDR_TIMER,
+		.setr				= MCFGPIO_PPDSDR_TIMER,
+		.clrr				= MCFGPIO_PCLRR_TIMER,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UART",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 56,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_UART,
+		.podr				= MCFGPIO_PODR_UART,
+		.ppdr				= MCFGPIO_PPDSDR_UART,
+		.setr				= MCFGPIO_PPDSDR_UART,
+		.clrr				= MCFGPIO_PCLRR_UART,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 64,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FECH,
+		.podr				= MCFGPIO_PODR_FECH,
+		.ppdr				= MCFGPIO_PPDSDR_FECH,
+		.setr				= MCFGPIO_PPDSDR_FECH,
+		.clrr				= MCFGPIO_PCLRR_FECH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 72,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FECL,
+		.podr				= MCFGPIO_PODR_FECL,
+		.ppdr				= MCFGPIO_PPDSDR_FECL,
+		.setr				= MCFGPIO_PPDSDR_FECL,
+		.clrr				= MCFGPIO_PCLRR_FECL,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/523x/Makefile b/arch/m68knommu/platform/523x/Makefile
index 5694d59..b8f9b45 100644
--- a/arch/m68knommu/platform/523x/Makefile
+++ b/arch/m68knommu/platform/523x/Makefile
@@ -14,4 +14,4 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c
index 961fefe..6ba84f2 100644
--- a/arch/m68knommu/platform/523x/config.c
+++ b/arch/m68knommu/platform/523x/config.c
@@ -82,66 +82,20 @@ static struct platform_device *m523x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define	INTC0	(MCF_MBAR + MCFICM_INTC0)
-
-static void __init m523x_uart_init_line(int line, int irq)
-{
-	u32 imr;
-
-	if ((line < 0) || (line > 2))
-		return;
-
-	writeb(0x30+line, (INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line));
-
-	imr = readl(INTC0 + MCFINTC_IMRL);
-	imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-	writel(imr, INTC0 + MCFINTC_IMRL);
-}
-
-static void __init m523x_uarts_init(void)
-{
-	const int nrlines = ARRAY_SIZE(m523x_uart_platform);
-	int line;
-
-	for (line = 0; (line < nrlines); line++)
-		m523x_uart_init_line(line, m523x_uart_platform[line].irq);
-}
-
-/***************************************************************************/
-
 static void __init m523x_fec_init(void)
 {
-	u32 imr;
-
-	/* Unmask FEC interrupts at ColdFire interrupt controller */
-	writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
-	writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
-	writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
-
-	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-	imr &= ~0xf;
-	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-	imr &= ~0xff800001;
-	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-}
-
-/***************************************************************************/
-
-void mcf_disableall(void)
-{
-	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
-	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
+	u16 par;
+	u8 v;
+
+	/* Set multi-function pins to ethernet use */
+	par = readw(MCF_IPSBAR + 0x100082);
+	writew(par | 0xf00, MCF_IPSBAR + 0x100082);
+	v = readb(MCF_IPSBAR + 0x100078);
+	writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
 }
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-	/* Everything is auto-vectored on the 523x */
-}
-/***************************************************************************/
-
 static void m523x_cpu_reset(void)
 {
 	local_irq_disable();
@@ -152,16 +106,14 @@ static void m523x_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_disableall();
 	mach_reset = m523x_cpu_reset;
-	m523x_uarts_init();
-	m523x_fec_init();
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
+	m523x_fec_init();
 	platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
 	return 0;
 }
diff --git a/arch/m68knommu/platform/523x/gpio.c b/arch/m68knommu/platform/523x/gpio.c
new file mode 100644
index 0000000..f02840d
--- /dev/null
+++ b/arch/m68knommu/platform/523x/gpio.c
@@ -0,0 +1,283 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PIRQ",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFEPORT_EPDDR,
+		.podr				= MCFEPORT_EPDR,
+		.ppdr				= MCFEPORT_EPPDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "ADDR",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 13,
+			.ngpio			= 3,
+		},
+		.pddr				= MCFGPIO_PDDR_ADDR,
+		.podr				= MCFGPIO_PODR_ADDR,
+		.ppdr				= MCFGPIO_PPDSDR_ADDR,
+		.setr				= MCFGPIO_PPDSDR_ADDR,
+		.clrr				= MCFGPIO_PCLRR_ADDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "DATAH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 16,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_DATAH,
+		.podr				= MCFGPIO_PODR_DATAH,
+		.ppdr				= MCFGPIO_PPDSDR_DATAH,
+		.setr				= MCFGPIO_PPDSDR_DATAH,
+		.clrr				= MCFGPIO_PCLRR_DATAH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "DATAL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 24,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_DATAL,
+		.podr				= MCFGPIO_PODR_DATAL,
+		.ppdr				= MCFGPIO_PPDSDR_DATAL,
+		.setr				= MCFGPIO_PPDSDR_DATAL,
+		.clrr				= MCFGPIO_PCLRR_DATAL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BUSCTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 32,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_BUSCTL,
+		.podr				= MCFGPIO_PODR_BUSCTL,
+		.ppdr				= MCFGPIO_PPDSDR_BUSCTL,
+		.setr				= MCFGPIO_PPDSDR_BUSCTL,
+		.clrr				= MCFGPIO_PCLRR_BUSCTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 40,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_BS,
+		.podr				= MCFGPIO_PODR_BS,
+		.ppdr				= MCFGPIO_PPDSDR_BS,
+		.setr				= MCFGPIO_PPDSDR_BS,
+		.clrr				= MCFGPIO_PCLRR_BS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "CS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 49,
+			.ngpio			= 7,
+		},
+		.pddr				= MCFGPIO_PDDR_CS,
+		.podr				= MCFGPIO_PODR_CS,
+		.ppdr				= MCFGPIO_PPDSDR_CS,
+		.setr				= MCFGPIO_PPDSDR_CS,
+		.clrr				= MCFGPIO_PCLRR_CS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "SDRAM",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 56,
+			.ngpio			= 6,
+		},
+		.pddr				= MCFGPIO_PDDR_SDRAM,
+		.podr				= MCFGPIO_PODR_SDRAM,
+		.ppdr				= MCFGPIO_PPDSDR_SDRAM,
+		.setr				= MCFGPIO_PPDSDR_SDRAM,
+		.clrr				= MCFGPIO_PCLRR_SDRAM,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECI2C",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 64,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_FECI2C,
+		.podr				= MCFGPIO_PODR_FECI2C,
+		.ppdr				= MCFGPIO_PPDSDR_FECI2C,
+		.setr				= MCFGPIO_PPDSDR_FECI2C,
+		.clrr				= MCFGPIO_PCLRR_FECI2C,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UARTH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 72,
+			.ngpio			= 2,
+		},
+		.pddr				= MCFGPIO_PDDR_UARTH,
+		.podr				= MCFGPIO_PODR_UARTH,
+		.ppdr				= MCFGPIO_PPDSDR_UARTH,
+		.setr				= MCFGPIO_PPDSDR_UARTH,
+		.clrr				= MCFGPIO_PCLRR_UARTH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UARTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 80,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_UARTL,
+		.podr				= MCFGPIO_PODR_UARTL,
+		.ppdr				= MCFGPIO_PPDSDR_UARTL,
+		.setr				= MCFGPIO_PPDSDR_UARTL,
+		.clrr				= MCFGPIO_PCLRR_UARTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QSPI",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 88,
+			.ngpio			= 5,
+		},
+		.pddr				= MCFGPIO_PDDR_QSPI,
+		.podr				= MCFGPIO_PODR_QSPI,
+		.ppdr				= MCFGPIO_PPDSDR_QSPI,
+		.setr				= MCFGPIO_PPDSDR_QSPI,
+		.clrr				= MCFGPIO_PCLRR_QSPI,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TIMER",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 96,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_TIMER,
+		.podr				= MCFGPIO_PODR_TIMER,
+		.ppdr				= MCFGPIO_PPDSDR_TIMER,
+		.setr				= MCFGPIO_PPDSDR_TIMER,
+		.clrr				= MCFGPIO_PCLRR_TIMER,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "ETPU",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 104,
+			.ngpio			= 3,
+		},
+		.pddr				= MCFGPIO_PDDR_ETPU,
+		.podr				= MCFGPIO_PODR_ETPU,
+		.ppdr				= MCFGPIO_PPDSDR_ETPU,
+		.setr				= MCFGPIO_PPDSDR_ETPU,
+		.clrr				= MCFGPIO_PCLRR_ETPU,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5249/Makefile b/arch/m68knommu/platform/5249/Makefile
index a439d9a..f56225d 100644
--- a/arch/m68knommu/platform/5249/Makefile
+++ b/arch/m68knommu/platform/5249/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o intc2.o
 
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index 93d9988..646f5ba 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -48,11 +48,11 @@ static void __init m5249_uart_init_line(int line, int irq)
 	if (line == 0) {
 		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);
+		mcf_mapirq2imr(irq, MCFINTC_UART0);
 	} else if (line == 1) {
 		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);
+		mcf_mapirq2imr(irq, MCFINTC_UART1);
 	}
 }
 
@@ -65,38 +65,21 @@ static void __init m5249_uarts_init(void)
 		m5249_uart_init_line(line, m5249_uart_platform[line].irq);
 }
 
-
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
+static void __init m5249_timers_init(void)
 {
-	volatile unsigned char  *mbar;
-
-	if ((vec >= 25) && (vec <= 31)) {
-		mbar = (volatile unsigned char *) MCF_MBAR;
-		vec = 0x1 << (vec - 24);
-		*(mbar + MCFSIM_AVR) |= vec;
-		mcf_setimr(mcf_getimr() & ~vec);
-	}
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
-{
-	volatile unsigned char *icrp;
-	unsigned int icr, imr;
-
-	if (timer <= 2) {
-		switch (timer) {
-		case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-		default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-		}
-
-		icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-		*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-		mcf_setimr(mcf_getimr() & ~imr);
-	}
+	/* Timer1 is always used as system timer */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER1ICR);
+	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+	/* Timer2 is to be used as a high speed profile timer  */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER2ICR);
+	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -114,15 +97,15 @@ void m5249_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_setimr(MCFSIM_IMR_MASKALL);
 	mach_reset = m5249_cpu_reset;
+	m5249_timers_init();
+	m5249_uarts_init();
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-	m5249_uarts_init();
 	platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
 	return 0;
 }
diff --git a/arch/m68knommu/platform/5249/gpio.c b/arch/m68knommu/platform/5249/gpio.c
new file mode 100644
index 0000000..c611eab
--- /dev/null
+++ b/arch/m68knommu/platform/5249/gpio.c
@@ -0,0 +1,65 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "GPIO0",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 32,
+		},
+		.pddr				= MCFSIM2_GPIOENABLE,
+		.podr				= MCFSIM2_GPIOWRITE,
+		.ppdr				= MCFSIM2_GPIOREAD,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "GPIO1",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.base			= 32,
+			.ngpio			= 32,
+		},
+		.pddr				= MCFSIM2_GPIO1ENABLE,
+		.podr				= MCFSIM2_GPIO1WRITE,
+		.ppdr				= MCFSIM2_GPIO1READ,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5249/intc2.c b/arch/m68knommu/platform/5249/intc2.c
new file mode 100644
index 0000000..d09d9da
--- /dev/null
+++ b/arch/m68knommu/platform/5249/intc2.c
@@ -0,0 +1,59 @@
+/*
+ * intc2.c  -- support for the 2nd INTC controller of the 5249
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+static void intc2_irq_gpio_mask(unsigned int irq)
+{
+	u32 imr;
+	imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+	imr &= ~(0x1 << (irq - MCFINTC2_GPIOIRQ0));
+	writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+}
+
+static void intc2_irq_gpio_unmask(unsigned int irq)
+{
+	u32 imr;
+	imr = readl(MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+	imr |= (0x1 << (irq - MCFINTC2_GPIOIRQ0));
+	writel(imr, MCF_MBAR2 + MCFSIM2_GPIOINTENABLE);
+}
+
+static void intc2_irq_gpio_ack(unsigned int irq)
+{
+	writel(0x1 << (irq - MCFINTC2_GPIOIRQ0), MCF_MBAR2 + MCFSIM2_GPIOINTCLEAR);
+}
+
+static struct irq_chip intc2_irq_gpio_chip = {
+	.name		= "CF-INTC2",
+	.mask		= intc2_irq_gpio_mask,
+	.unmask		= intc2_irq_gpio_unmask,
+	.ack		= intc2_irq_gpio_ack,
+};
+
+static int __init mcf_intc2_init(void)
+{
+	int irq;
+
+	/* GPIO interrupt sources */
+	for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++)
+		irq_desc[irq].chip = &intc2_irq_gpio_chip;
+
+	return 0;
+}
+
+arch_initcall(mcf_intc2_init);
diff --git a/arch/m68knommu/platform/5272/Makefile b/arch/m68knommu/platform/5272/Makefile
index 26135d9..93673ef 100644
--- a/arch/m68knommu/platform/5272/Makefile
+++ b/arch/m68knommu/platform/5272/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o intc.o
 
diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c
index 5f95fcd..59278c0 100644
--- a/arch/m68knommu/platform/5272/config.c
+++ b/arch/m68knommu/platform/5272/config.c
@@ -20,12 +20,6 @@
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 /*
  *	Some platforms need software versions of the GPIO data registers.
  */
@@ -37,11 +31,11 @@ unsigned char ledbank = 0xff;
 static struct mcf_platform_uart m5272_uart_platform[] = {
 	{
 		.mapbase	= MCF_MBAR + MCFUART_BASE1,
-		.irq		= 73,
+		.irq		= MCF_IRQ_UART1,
 	},
 	{
 		.mapbase 	= MCF_MBAR + MCFUART_BASE2,
-		.irq		= 74,
+		.irq		= MCF_IRQ_UART2,
 	},
 	{ },
 };
@@ -59,18 +53,18 @@ static struct resource m5272_fec_resources[] = {
 		.flags		= IORESOURCE_MEM,
 	},
 	{
-		.start		= 86,
-		.end		= 86,
+		.start		= MCF_IRQ_ERX,
+		.end		= MCF_IRQ_ERX,
 		.flags		= IORESOURCE_IRQ,
 	},
 	{
-		.start		= 87,
-		.end		= 87,
+		.start		= MCF_IRQ_ETX,
+		.end		= MCF_IRQ_ETX,
 		.flags		= IORESOURCE_IRQ,
 	},
 	{
-		.start		= 88,
-		.end		= 88,
+		.start		= MCF_IRQ_ENTC,
+		.end		= MCF_IRQ_ENTC,
 		.flags		= IORESOURCE_IRQ,
 	},
 };
@@ -94,9 +88,6 @@ static void __init m5272_uart_init_line(int line, int irq)
 	u32 v;
 
 	if ((line >= 0) && (line < 2)) {
-		v = (line) ? 0x0e000000 : 0xe0000000;
-		writel(v, MCF_MBAR + MCFSIM_ICR2);
-
 		/* Enable the output lines for the serial ports */
 		v = readl(MCF_MBAR + MCFSIM_PBCNT);
 		v = (v & ~0x000000ff) | 0x00000055;
@@ -119,54 +110,6 @@ static void __init m5272_uarts_init(void)
 
 /***************************************************************************/
 
-static void __init m5272_fec_init(void)
-{
-	u32 imr;
-
-	/* Unmask FEC interrupts at ColdFire interrupt controller */
-	imr = readl(MCF_MBAR + MCFSIM_ICR3);
-	imr = (imr & ~0x00000fff) | 0x00000ddd;
-	writel(imr, MCF_MBAR + MCFSIM_ICR3);
-
-	imr = readl(MCF_MBAR + MCFSIM_ICR1);
-	imr = (imr & ~0x0f000000) | 0x0d000000;
-	writel(imr, MCF_MBAR + MCFSIM_ICR1);
-}
-
-/***************************************************************************/
-
-void mcf_disableall(void)
-{
-	volatile unsigned long	*icrp;
-
-	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-	icrp[0] = 0x88888888;
-	icrp[1] = 0x88888888;
-	icrp[2] = 0x88888888;
-	icrp[3] = 0x88888888;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
-{
-	/* Everything is auto-vectored on the 5272 */
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(int timer, int level)
-{
-	volatile unsigned long *icrp;
-
-	if ((timer >= 1 ) && (timer <= 4)) {
-		icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-		*icrp = (0x8 | level) << ((4 - timer) * 4);
-	}
-}
-
-/***************************************************************************/
-
 static void m5272_cpu_reset(void)
 {
 	local_irq_disable();
@@ -190,8 +133,6 @@ void __init config_BSP(char *commandp, int size)
 	*pivrp = 0x40;
 #endif
 
-	mcf_disableall();
-
 #if defined(CONFIG_NETtel) || defined(CONFIG_SCALES)
 	/* Copy command line from FLASH to local buffer... */
 	memcpy(commandp, (char *) 0xf0004000, size);
@@ -202,8 +143,6 @@ void __init config_BSP(char *commandp, int size)
 	commandp[size-1] = 0;
 #endif
 
-	mcf_timervector = 69;
-	mcf_profilevector = 70;
 	mach_reset = m5272_cpu_reset;
 }
 
@@ -212,7 +151,6 @@ void __init config_BSP(char *commandp, int size)
 static int __init init_BSP(void)
 {
 	m5272_uarts_init();
-	m5272_fec_init();
 	platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
 	return 0;
 }
diff --git a/arch/m68knommu/platform/5272/gpio.c b/arch/m68knommu/platform/5272/gpio.c
new file mode 100644
index 0000000..459db89
--- /dev/null
+++ b/arch/m68knommu/platform/5272/gpio.c
@@ -0,0 +1,81 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PA",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 16,
+		},
+		.pddr				= MCFSIM_PADDR,
+		.podr				= MCFSIM_PADAT,
+		.ppdr				= MCFSIM_PADAT,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "PB",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.base			= 16,
+			.ngpio			= 16,
+		},
+		.pddr				= MCFSIM_PBDDR,
+		.podr				= MCFSIM_PBDAT,
+		.ppdr				= MCFSIM_PBDAT,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "PC",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.base			= 32,
+			.ngpio			= 16,
+		},
+		.pddr				= MCFSIM_PCDDR,
+		.podr				= MCFSIM_PCDAT,
+		.ppdr				= MCFSIM_PCDAT,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c
new file mode 100644
index 0000000..7081e0a
--- /dev/null
+++ b/arch/m68knommu/platform/5272/intc.c
@@ -0,0 +1,138 @@
+/*
+ * intc.c  --  interrupt controller or ColdFire 5272 SoC
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+/*
+ * The 5272 ColdFire interrupt controller is nothing like any other
+ * ColdFire interrupt controller - it truly is completely different.
+ * Given its age it is unlikely to be used on any other ColdFire CPU.
+ */
+
+/*
+ * The masking and priproty setting of interrupts on the 5272 is done
+ * via a set of 4 "Interrupt Controller Registers" (ICR). There is a
+ * loose mapping of vector number to register and internal bits, but
+ * a table is the easiest and quickest way to map them.
+ */
+struct irqmap {
+	unsigned char	icr;
+	unsigned char	index;
+	unsigned char	ack;
+};
+
+static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = {
+	/*MCF_IRQ_SPURIOUS*/	{ .icr = 0,           .index = 0,  .ack = 0, },
+	/*MCF_IRQ_EINT1*/	{ .icr = MCFSIM_ICR1, .index = 28, .ack = 1, },
+	/*MCF_IRQ_EINT2*/	{ .icr = MCFSIM_ICR1, .index = 24, .ack = 1, },
+	/*MCF_IRQ_EINT3*/	{ .icr = MCFSIM_ICR1, .index = 20, .ack = 1, },
+	/*MCF_IRQ_EINT4*/	{ .icr = MCFSIM_ICR1, .index = 16, .ack = 1, },
+	/*MCF_IRQ_TIMER1*/	{ .icr = MCFSIM_ICR1, .index = 12, .ack = 0, },
+	/*MCF_IRQ_TIMER2*/	{ .icr = MCFSIM_ICR1, .index = 8,  .ack = 0, },
+	/*MCF_IRQ_TIMER3*/	{ .icr = MCFSIM_ICR1, .index = 4,  .ack = 0, },
+	/*MCF_IRQ_TIMER4*/	{ .icr = MCFSIM_ICR1, .index = 0,  .ack = 0, },
+	/*MCF_IRQ_UART1*/	{ .icr = MCFSIM_ICR2, .index = 28, .ack = 0, },
+	/*MCF_IRQ_UART2*/	{ .icr = MCFSIM_ICR2, .index = 24, .ack = 0, },
+	/*MCF_IRQ_PLIP*/	{ .icr = MCFSIM_ICR2, .index = 20, .ack = 0, },
+	/*MCF_IRQ_PLIA*/	{ .icr = MCFSIM_ICR2, .index = 16, .ack = 0, },
+	/*MCF_IRQ_USB0*/	{ .icr = MCFSIM_ICR2, .index = 12, .ack = 0, },
+	/*MCF_IRQ_USB1*/	{ .icr = MCFSIM_ICR2, .index = 8,  .ack = 0, },
+	/*MCF_IRQ_USB2*/	{ .icr = MCFSIM_ICR2, .index = 4,  .ack = 0, },
+	/*MCF_IRQ_USB3*/	{ .icr = MCFSIM_ICR2, .index = 0,  .ack = 0, },
+	/*MCF_IRQ_USB4*/	{ .icr = MCFSIM_ICR3, .index = 28, .ack = 0, },
+	/*MCF_IRQ_USB5*/	{ .icr = MCFSIM_ICR3, .index = 24, .ack = 0, },
+	/*MCF_IRQ_USB6*/	{ .icr = MCFSIM_ICR3, .index = 20, .ack = 0, },
+	/*MCF_IRQ_USB7*/	{ .icr = MCFSIM_ICR3, .index = 16, .ack = 0, },
+	/*MCF_IRQ_DMA*/		{ .icr = MCFSIM_ICR3, .index = 12, .ack = 0, },
+	/*MCF_IRQ_ERX*/		{ .icr = MCFSIM_ICR3, .index = 8,  .ack = 0, },
+	/*MCF_IRQ_ETX*/		{ .icr = MCFSIM_ICR3, .index = 4,  .ack = 0, },
+	/*MCF_IRQ_ENTC*/	{ .icr = MCFSIM_ICR3, .index = 0,  .ack = 0, },
+	/*MCF_IRQ_QSPI*/	{ .icr = MCFSIM_ICR4, .index = 28, .ack = 0, },
+	/*MCF_IRQ_EINT5*/	{ .icr = MCFSIM_ICR4, .index = 24, .ack = 1, },
+	/*MCF_IRQ_EINT6*/	{ .icr = MCFSIM_ICR4, .index = 20, .ack = 1, },
+	/*MCF_IRQ_SWTO*/	{ .icr = MCFSIM_ICR4, .index = 16, .ack = 0, },
+};
+
+static void intc_irq_mask(unsigned int irq)
+{
+	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
+		u32 v;
+		irq -= MCFINT_VECBASE;
+		v = 0x8 << intc_irqmap[irq].index;
+		writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+	}
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
+		u32 v;
+		irq -= MCFINT_VECBASE;
+		v = 0xd << intc_irqmap[irq].index;
+		writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+	}
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+	/* Only external interrupts are acked */
+	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) {
+		irq -= MCFINT_VECBASE;
+		if (intc_irqmap[irq].ack) {
+			u32 v;
+			v = 0xd << intc_irqmap[irq].index;
+			writel(v, MCF_MBAR + intc_irqmap[irq].icr);
+		}
+	}
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+	/* We can set the edge type here for external interrupts */
+	return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+	.name		= "CF-INTC",
+	.mask		= intc_irq_mask,
+	.unmask		= intc_irq_unmask,
+	.ack		= intc_irq_ack,
+	.set_type	= intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+	int irq;
+
+	init_vectors();
+
+	/* Mask all interrupt sources */
+	writel(0x88888888, MCF_MBAR + MCFSIM_ICR1);
+	writel(0x88888888, MCF_MBAR + MCFSIM_ICR2);
+	writel(0x88888888, MCF_MBAR + MCFSIM_ICR3);
+	writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
+
+	for (irq = 0; (irq < NR_IRQS); irq++) {
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = NULL;
+		irq_desc[irq].depth = 1;
+		irq_desc[irq].chip = &intc_irq_chip;
+		intc_irq_set_type(irq, 0);
+	}
+}
+
diff --git a/arch/m68knommu/platform/527x/Makefile b/arch/m68knommu/platform/527x/Makefile
index 26135d9..3d90e6d 100644
--- a/arch/m68knommu/platform/527x/Makefile
+++ b/arch/m68knommu/platform/527x/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c
index f746439..fa51be1 100644
--- a/arch/m68knommu/platform/527x/config.c
+++ b/arch/m68knommu/platform/527x/config.c
@@ -116,23 +116,13 @@ static struct platform_device *m527x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define	INTC0	(MCF_MBAR + MCFICM_INTC0)
-
 static void __init m527x_uart_init_line(int line, int irq)
 {
 	u16 sepmask;
-	u32 imr;
 
 	if ((line < 0) || (line > 2))
 		return;
 
-	/* level 6, line based priority */
-	writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
-	imr = readl(INTC0 + MCFINTC_IMRL);
-	imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-	writel(imr, INTC0 + MCFINTC_IMRL);
-
 	/*
 	 * External Pin Mask Setting & Enable External Pin for Interface
 	 */
@@ -157,32 +147,11 @@ static void __init m527x_uarts_init(void)
 
 /***************************************************************************/
 
-static void __init m527x_fec_irq_init(int nr)
-{
-	unsigned long base;
-	u32 imr;
-
-	base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0);
-
-	writeb(0x28, base + MCFINTC_ICR0 + 23);
-	writeb(0x27, base + MCFINTC_ICR0 + 27);
-	writeb(0x26, base + MCFINTC_ICR0 + 29);
-
-	imr = readl(base + MCFINTC_IMRH);
-	imr &= ~0xf;
-	writel(imr, base + MCFINTC_IMRH);
-	imr = readl(base + MCFINTC_IMRL);
-	imr &= ~0xff800001;
-	writel(imr, base + MCFINTC_IMRL);
-}
-
 static void __init m527x_fec_init(void)
 {
 	u16 par;
 	u8 v;
 
-	m527x_fec_irq_init(0);
-
 	/* Set multi-function pins to ethernet mode for fec0 */
 #if defined(CONFIG_M5271)
 	v = readb(MCF_IPSBAR + 0x100047);
@@ -195,8 +164,6 @@ static void __init m527x_fec_init(void)
 #endif
 
 #ifdef CONFIG_FEC2
-	m527x_fec_irq_init(1);
-
 	/* Set multi-function pins to ethernet mode for fec1 */
 	par = readw(MCF_IPSBAR + 0x100082);
 	writew(par | 0xa0, MCF_IPSBAR + 0x100082);
@@ -207,21 +174,6 @@ static void __init m527x_fec_init(void)
 
 /***************************************************************************/
 
-void mcf_disableall(void)
-{
-	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
-	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
-{
-	/* Everything is auto-vectored on the 5272 */
-}
-
-/***************************************************************************/
-
 static void m527x_cpu_reset(void)
 {
 	local_irq_disable();
@@ -232,7 +184,6 @@ static void m527x_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_disableall();
 	mach_reset = m527x_cpu_reset;
 	m527x_uarts_init();
 	m527x_fec_init();
diff --git a/arch/m68knommu/platform/527x/gpio.c b/arch/m68knommu/platform/527x/gpio.c
new file mode 100644
index 0000000..1028142
--- /dev/null
+++ b/arch/m68knommu/platform/527x/gpio.c
@@ -0,0 +1,607 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+#if defined(CONFIG_M5271)
+	{
+		.gpio_chip			= {
+			.label			= "PIRQ",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFEPORT_EPDDR,
+		.podr				= MCFEPORT_EPDR,
+		.ppdr				= MCFEPORT_EPPDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "ADDR",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 13,
+			.ngpio			= 3,
+		},
+		.pddr				= MCFGPIO_PDDR_ADDR,
+		.podr				= MCFGPIO_PODR_ADDR,
+		.ppdr				= MCFGPIO_PPDSDR_ADDR,
+		.setr				= MCFGPIO_PPDSDR_ADDR,
+		.clrr				= MCFGPIO_PCLRR_ADDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "DATAH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 16,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_DATAH,
+		.podr				= MCFGPIO_PODR_DATAH,
+		.ppdr				= MCFGPIO_PPDSDR_DATAH,
+		.setr				= MCFGPIO_PPDSDR_DATAH,
+		.clrr				= MCFGPIO_PCLRR_DATAH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "DATAL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 24,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_DATAL,
+		.podr				= MCFGPIO_PODR_DATAL,
+		.ppdr				= MCFGPIO_PPDSDR_DATAL,
+		.setr				= MCFGPIO_PPDSDR_DATAL,
+		.clrr				= MCFGPIO_PCLRR_DATAL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BUSCTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 32,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_BUSCTL,
+		.podr				= MCFGPIO_PODR_BUSCTL,
+		.ppdr				= MCFGPIO_PPDSDR_BUSCTL,
+		.setr				= MCFGPIO_PPDSDR_BUSCTL,
+		.clrr				= MCFGPIO_PCLRR_BUSCTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 40,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_BS,
+		.podr				= MCFGPIO_PODR_BS,
+		.ppdr				= MCFGPIO_PPDSDR_BS,
+		.setr				= MCFGPIO_PPDSDR_BS,
+		.clrr				= MCFGPIO_PCLRR_BS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "CS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 49,
+			.ngpio			= 7,
+		},
+		.pddr				= MCFGPIO_PDDR_CS,
+		.podr				= MCFGPIO_PODR_CS,
+		.ppdr				= MCFGPIO_PPDSDR_CS,
+		.setr				= MCFGPIO_PPDSDR_CS,
+		.clrr				= MCFGPIO_PCLRR_CS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "SDRAM",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 56,
+			.ngpio			= 6,
+		},
+		.pddr				= MCFGPIO_PDDR_SDRAM,
+		.podr				= MCFGPIO_PODR_SDRAM,
+		.ppdr				= MCFGPIO_PPDSDR_SDRAM,
+		.setr				= MCFGPIO_PPDSDR_SDRAM,
+		.clrr				= MCFGPIO_PCLRR_SDRAM,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECI2C",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 64,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_FECI2C,
+		.podr				= MCFGPIO_PODR_FECI2C,
+		.ppdr				= MCFGPIO_PPDSDR_FECI2C,
+		.setr				= MCFGPIO_PPDSDR_FECI2C,
+		.clrr				= MCFGPIO_PCLRR_FECI2C,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UARTH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 72,
+			.ngpio			= 2,
+		},
+		.pddr				= MCFGPIO_PDDR_UARTH,
+		.podr				= MCFGPIO_PODR_UARTH,
+		.ppdr				= MCFGPIO_PPDSDR_UARTH,
+		.setr				= MCFGPIO_PPDSDR_UARTH,
+		.clrr				= MCFGPIO_PCLRR_UARTH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UARTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 80,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_UARTL,
+		.podr				= MCFGPIO_PODR_UARTL,
+		.ppdr				= MCFGPIO_PPDSDR_UARTL,
+		.setr				= MCFGPIO_PPDSDR_UARTL,
+		.clrr				= MCFGPIO_PCLRR_UARTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QSPI",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 88,
+			.ngpio			= 5,
+		},
+		.pddr				= MCFGPIO_PDDR_QSPI,
+		.podr				= MCFGPIO_PODR_QSPI,
+		.ppdr				= MCFGPIO_PPDSDR_QSPI,
+		.setr				= MCFGPIO_PPDSDR_QSPI,
+		.clrr				= MCFGPIO_PCLRR_QSPI,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TIMER",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 96,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_TIMER,
+		.podr				= MCFGPIO_PODR_TIMER,
+		.ppdr				= MCFGPIO_PPDSDR_TIMER,
+		.setr				= MCFGPIO_PPDSDR_TIMER,
+		.clrr				= MCFGPIO_PCLRR_TIMER,
+	},
+#elif defined(CONFIG_M5275)
+	{
+		.gpio_chip			= {
+			.label			= "PIRQ",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFEPORT_EPDDR,
+		.podr				= MCFEPORT_EPDR,
+		.ppdr				= MCFEPORT_EPPDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BUSCTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 8,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_BUSCTL,
+		.podr				= MCFGPIO_PODR_BUSCTL,
+		.ppdr				= MCFGPIO_PPDSDR_BUSCTL,
+		.setr				= MCFGPIO_PPDSDR_BUSCTL,
+		.clrr				= MCFGPIO_PCLRR_BUSCTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "ADDR",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 21,
+			.ngpio			= 3,
+		},
+		.pddr				= MCFGPIO_PDDR_ADDR,
+		.podr				= MCFGPIO_PODR_ADDR,
+		.ppdr				= MCFGPIO_PPDSDR_ADDR,
+		.setr				= MCFGPIO_PPDSDR_ADDR,
+		.clrr				= MCFGPIO_PCLRR_ADDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "CS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 25,
+			.ngpio			= 7,
+		},
+		.pddr				= MCFGPIO_PDDR_CS,
+		.podr				= MCFGPIO_PODR_CS,
+		.ppdr				= MCFGPIO_PPDSDR_CS,
+		.setr				= MCFGPIO_PPDSDR_CS,
+		.clrr				= MCFGPIO_PCLRR_CS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FEC0H",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 32,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FEC0H,
+		.podr				= MCFGPIO_PODR_FEC0H,
+		.ppdr				= MCFGPIO_PPDSDR_FEC0H,
+		.setr				= MCFGPIO_PPDSDR_FEC0H,
+		.clrr				= MCFGPIO_PCLRR_FEC0H,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FEC0L",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 40,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FEC0L,
+		.podr				= MCFGPIO_PODR_FEC0L,
+		.ppdr				= MCFGPIO_PPDSDR_FEC0L,
+		.setr				= MCFGPIO_PPDSDR_FEC0L,
+		.clrr				= MCFGPIO_PCLRR_FEC0L,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECI2C",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 48,
+			.ngpio			= 6,
+		},
+		.pddr				= MCFGPIO_PDDR_FECI2C,
+		.podr				= MCFGPIO_PODR_FECI2C,
+		.ppdr				= MCFGPIO_PPDSDR_FECI2C,
+		.setr				= MCFGPIO_PPDSDR_FECI2C,
+		.clrr				= MCFGPIO_PCLRR_FECI2C,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QSPI",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 56,
+			.ngpio			= 7,
+		},
+		.pddr				= MCFGPIO_PDDR_QSPI,
+		.podr				= MCFGPIO_PODR_QSPI,
+		.ppdr				= MCFGPIO_PPDSDR_QSPI,
+		.setr				= MCFGPIO_PPDSDR_QSPI,
+		.clrr				= MCFGPIO_PCLRR_QSPI,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "SDRAM",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 64,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_SDRAM,
+		.podr				= MCFGPIO_PODR_SDRAM,
+		.ppdr				= MCFGPIO_PPDSDR_SDRAM,
+		.setr				= MCFGPIO_PPDSDR_SDRAM,
+		.clrr				= MCFGPIO_PCLRR_SDRAM,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TIMERH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 72,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_TIMERH,
+		.podr				= MCFGPIO_PODR_TIMERH,
+		.ppdr				= MCFGPIO_PPDSDR_TIMERH,
+		.setr				= MCFGPIO_PPDSDR_TIMERH,
+		.clrr				= MCFGPIO_PCLRR_TIMERH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TIMERL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 80,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_TIMERL,
+		.podr				= MCFGPIO_PODR_TIMERL,
+		.ppdr				= MCFGPIO_PPDSDR_TIMERL,
+		.setr				= MCFGPIO_PPDSDR_TIMERL,
+		.clrr				= MCFGPIO_PCLRR_TIMERL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UARTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 88,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_UARTL,
+		.podr				= MCFGPIO_PODR_UARTL,
+		.ppdr				= MCFGPIO_PPDSDR_UARTL,
+		.setr				= MCFGPIO_PPDSDR_UARTL,
+		.clrr				= MCFGPIO_PCLRR_UARTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FEC1H",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 96,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FEC1H,
+		.podr				= MCFGPIO_PODR_FEC1H,
+		.ppdr				= MCFGPIO_PPDSDR_FEC1H,
+		.setr				= MCFGPIO_PPDSDR_FEC1H,
+		.clrr				= MCFGPIO_PCLRR_FEC1H,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FEC1L",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 104,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FEC1L,
+		.podr				= MCFGPIO_PODR_FEC1L,
+		.ppdr				= MCFGPIO_PPDSDR_FEC1L,
+		.setr				= MCFGPIO_PPDSDR_FEC1L,
+		.clrr				= MCFGPIO_PCLRR_FEC1L,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 114,
+			.ngpio			= 2,
+		},
+		.pddr				= MCFGPIO_PDDR_BS,
+		.podr				= MCFGPIO_PODR_BS,
+		.ppdr				= MCFGPIO_PPDSDR_BS,
+		.setr				= MCFGPIO_PPDSDR_BS,
+		.clrr				= MCFGPIO_PCLRR_BS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "IRQ",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 121,
+			.ngpio			= 7,
+		},
+		.pddr				= MCFGPIO_PDDR_IRQ,
+		.podr				= MCFGPIO_PODR_IRQ,
+		.ppdr				= MCFGPIO_PPDSDR_IRQ,
+		.setr				= MCFGPIO_PPDSDR_IRQ,
+		.clrr				= MCFGPIO_PCLRR_IRQ,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "USBH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 128,
+			.ngpio			= 1,
+		},
+		.pddr				= MCFGPIO_PDDR_USBH,
+		.podr				= MCFGPIO_PODR_USBH,
+		.ppdr				= MCFGPIO_PPDSDR_USBH,
+		.setr				= MCFGPIO_PPDSDR_USBH,
+		.clrr				= MCFGPIO_PCLRR_USBH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "USBL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 136,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_USBL,
+		.podr				= MCFGPIO_PODR_USBL,
+		.ppdr				= MCFGPIO_PPDSDR_USBL,
+		.setr				= MCFGPIO_PPDSDR_USBL,
+		.clrr				= MCFGPIO_PCLRR_USBL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UARTH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 144,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_UARTH,
+		.podr				= MCFGPIO_PODR_UARTH,
+		.ppdr				= MCFGPIO_PPDSDR_UARTH,
+		.setr				= MCFGPIO_PPDSDR_UARTH,
+		.clrr				= MCFGPIO_PCLRR_UARTH,
+	},
+#endif
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/528x/Makefile b/arch/m68knommu/platform/528x/Makefile
index 26135d9..3d90e6d 100644
--- a/arch/m68knommu/platform/528x/Makefile
+++ b/arch/m68knommu/platform/528x/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c
index a1d1a61..6e608d1 100644
--- a/arch/m68knommu/platform/528x/config.c
+++ b/arch/m68knommu/platform/528x/config.c
@@ -3,8 +3,8 @@
 /*
  *	linux/arch/m68knommu/platform/528x/config.c
  *
- *	Sub-architcture dependant initialization code for the Motorola
- *	5280 and 5282 CPUs.
+ *	Sub-architcture dependant initialization code for the Freescale
+ *	5280, 5281 and 5282 CPUs.
  *
  *	Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
  *	Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
@@ -15,20 +15,13 @@
 #include <linux/kernel.h>
 #include <linux/param.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/flash.h>
 #include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include <asm/mcfuart.h>
 
-#ifdef CONFIG_MTD_PARTITIONS
-#include <linux/mtd/partitions.h>
-#endif
-
 /***************************************************************************/
 
 static struct mcf_platform_uart m528x_uart_platform[] = {
@@ -91,23 +84,13 @@ static struct platform_device *m528x_devices[] __initdata = {
 
 /***************************************************************************/
 
-#define	INTC0	(MCF_MBAR + MCFICM_INTC0)
-
 static void __init m528x_uart_init_line(int line, int irq)
 {
 	u8 port;
-	u32 imr;
 
 	if ((line < 0) || (line > 2))
 		return;
 
-	/* level 6, line based priority */
-	writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line);
-
-	imr = readl(INTC0 + MCFINTC_IMRL);
-	imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1);
-	writel(imr, INTC0 + MCFINTC_IMRL);
-
 	/* make sure PUAPAR is set for UART0 and UART1 */
 	if (line < 2) {
 		port = readb(MCF_MBAR + MCF5282_GPIO_PUAPAR);
@@ -129,21 +112,8 @@ static void __init m528x_uarts_init(void)
 
 static void __init m528x_fec_init(void)
 {
-	u32 imr;
 	u16 v16;
 
-	/* Unmask FEC interrupts at ColdFire interrupt controller */
-	writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
-	writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
-	writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
-
-	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-	imr &= ~0xf;
-	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-	imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-	imr &= ~0xff800001;
-	writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
-
 	/* Set multi-function pins to ethernet mode for fec0 */
 	v16 = readw(MCF_IPSBAR + 0x100056);
 	writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
@@ -152,21 +122,6 @@ static void __init m528x_fec_init(void)
 
 /***************************************************************************/
 
-void mcf_disableall(void)
-{
-	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
-	*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff;
-}
-
-/***************************************************************************/
-
-void mcf_autovector(unsigned int vec)
-{
-	/* Everything is auto-vectored on the 5272 */
-}
-
-/***************************************************************************/
-
 static void m528x_cpu_reset(void)
 {
 	local_irq_disable();
@@ -204,8 +159,6 @@ void wildfiremod_halt(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_disableall();
-
 #ifdef CONFIG_WILDFIRE
 	mach_halt = wildfire_halt;
 #endif
diff --git a/arch/m68knommu/platform/528x/gpio.c b/arch/m68knommu/platform/528x/gpio.c
new file mode 100644
index 0000000..ec59395
--- /dev/null
+++ b/arch/m68knommu/platform/528x/gpio.c
@@ -0,0 +1,438 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "NQ",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.base			= 1,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFEPORT_EPDDR,
+		.podr				= MCFEPORT_EPDR,
+		.ppdr				= MCFEPORT_EPPDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TA",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 8,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPTA_GPTDDR,
+		.podr				= MCFGPTA_GPTPORT,
+		.ppdr				= MCFGPTB_GPTPORT,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TB",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 16,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPTB_GPTDDR,
+		.podr				= MCFGPTB_GPTPORT,
+		.ppdr				= MCFGPTB_GPTPORT,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QA",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 24,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFQADC_DDRQA,
+		.podr				= MCFQADC_PORTQA,
+		.ppdr				= MCFQADC_PORTQA,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QB",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 32,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFQADC_DDRQB,
+		.podr				= MCFQADC_PORTQB,
+		.ppdr				= MCFQADC_PORTQB,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "A",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 40,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRA,
+		.podr				= MCFGPIO_PORTA,
+		.ppdr				= MCFGPIO_PORTAP,
+		.setr				= MCFGPIO_SETA,
+		.clrr				= MCFGPIO_CLRA,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "B",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 48,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRB,
+		.podr				= MCFGPIO_PORTB,
+		.ppdr				= MCFGPIO_PORTBP,
+		.setr				= MCFGPIO_SETB,
+		.clrr				= MCFGPIO_CLRB,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "C",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 56,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRC,
+		.podr				= MCFGPIO_PORTC,
+		.ppdr				= MCFGPIO_PORTCP,
+		.setr				= MCFGPIO_SETC,
+		.clrr				= MCFGPIO_CLRC,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "D",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 64,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRD,
+		.podr				= MCFGPIO_PORTD,
+		.ppdr				= MCFGPIO_PORTDP,
+		.setr				= MCFGPIO_SETD,
+		.clrr				= MCFGPIO_CLRD,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "E",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 72,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRE,
+		.podr				= MCFGPIO_PORTE,
+		.ppdr				= MCFGPIO_PORTEP,
+		.setr				= MCFGPIO_SETE,
+		.clrr				= MCFGPIO_CLRE,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "F",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 80,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRF,
+		.podr				= MCFGPIO_PORTF,
+		.ppdr				= MCFGPIO_PORTFP,
+		.setr				= MCFGPIO_SETF,
+		.clrr				= MCFGPIO_CLRF,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "G",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 88,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRG,
+		.podr				= MCFGPIO_PORTG,
+		.ppdr				= MCFGPIO_PORTGP,
+		.setr				= MCFGPIO_SETG,
+		.clrr				= MCFGPIO_CLRG,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "H",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 96,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRH,
+		.podr				= MCFGPIO_PORTH,
+		.ppdr				= MCFGPIO_PORTHP,
+		.setr				= MCFGPIO_SETH,
+		.clrr				= MCFGPIO_CLRH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "J",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 104,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRJ,
+		.podr				= MCFGPIO_PORTJ,
+		.ppdr				= MCFGPIO_PORTJP,
+		.setr				= MCFGPIO_SETJ,
+		.clrr				= MCFGPIO_CLRJ,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "DD",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 112,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDRDD,
+		.podr				= MCFGPIO_PORTDD,
+		.ppdr				= MCFGPIO_PORTDDP,
+		.setr				= MCFGPIO_SETDD,
+		.clrr				= MCFGPIO_CLRDD,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "EH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 120,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDREH,
+		.podr				= MCFGPIO_PORTEH,
+		.ppdr				= MCFGPIO_PORTEHP,
+		.setr				= MCFGPIO_SETEH,
+		.clrr				= MCFGPIO_CLREH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "EL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 128,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_DDREL,
+		.podr				= MCFGPIO_PORTEL,
+		.ppdr				= MCFGPIO_PORTELP,
+		.setr				= MCFGPIO_SETEL,
+		.clrr				= MCFGPIO_CLREL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "AS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 136,
+			.ngpio			= 6,
+		},
+		.pddr				= MCFGPIO_DDRAS,
+		.podr				= MCFGPIO_PORTAS,
+		.ppdr				= MCFGPIO_PORTASP,
+		.setr				= MCFGPIO_SETAS,
+		.clrr				= MCFGPIO_CLRAS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 144,
+			.ngpio			= 7,
+		},
+		.pddr				= MCFGPIO_DDRQS,
+		.podr				= MCFGPIO_PORTQS,
+		.ppdr				= MCFGPIO_PORTQSP,
+		.setr				= MCFGPIO_SETQS,
+		.clrr				= MCFGPIO_CLRQS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "SD",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 152,
+			.ngpio			= 6,
+		},
+		.pddr				= MCFGPIO_DDRSD,
+		.podr				= MCFGPIO_PORTSD,
+		.ppdr				= MCFGPIO_PORTSDP,
+		.setr				= MCFGPIO_SETSD,
+		.clrr				= MCFGPIO_CLRSD,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TC",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 160,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_DDRTC,
+		.podr				= MCFGPIO_PORTTC,
+		.ppdr				= MCFGPIO_PORTTCP,
+		.setr				= MCFGPIO_SETTC,
+		.clrr				= MCFGPIO_CLRTC,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TD",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 168,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_DDRTD,
+		.podr				= MCFGPIO_PORTTD,
+		.ppdr				= MCFGPIO_PORTTDP,
+		.setr				= MCFGPIO_SETTD,
+		.clrr				= MCFGPIO_CLRTD,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UA",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 176,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_DDRUA,
+		.podr				= MCFGPIO_PORTUA,
+		.ppdr				= MCFGPIO_PORTUAP,
+		.setr				= MCFGPIO_SETUA,
+		.clrr				= MCFGPIO_CLRUA,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5307/Makefile b/arch/m68knommu/platform/5307/Makefile
index cfd5868..667db65 100644
--- a/arch/m68knommu/platform/5307/Makefile
+++ b/arch/m68knommu/platform/5307/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y	+= config.o
+obj-y	+= config.o gpio.o
 
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index 39da9e9..00900ac 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -21,12 +21,6 @@
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 /*
  *	Some platforms need software versions of the GPIO data registers.
  */
@@ -64,11 +58,11 @@ static void __init m5307_uart_init_line(int line, int irq)
 	if (line == 0) {
 		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);
+		mcf_mapirq2imr(irq, MCFINTC_UART0);
 	} else if (line == 1) {
 		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);
+		mcf_mapirq2imr(irq, MCFINTC_UART1);
 	}
 }
 
@@ -83,35 +77,19 @@ static void __init m5307_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-	volatile unsigned char  *mbar;
-
-	if ((vec >= 25) && (vec <= 31)) {
-		mbar = (volatile unsigned char *) MCF_MBAR;
-		vec = 0x1 << (vec - 24);
-		*(mbar + MCFSIM_AVR) |= vec;
-		mcf_setimr(mcf_getimr() & ~vec);
-	}
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
+static void __init m5307_timers_init(void)
 {
-	volatile unsigned char *icrp;
-	unsigned int icr, imr;
-
-	if (timer <= 2) {
-		switch (timer) {
-		case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-		default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-		}
-
-		icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-		*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-		mcf_setimr(mcf_getimr() & ~imr);
-	}
+	/* Timer1 is always used as system timer */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER1ICR);
+	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+	/* Timer2 is to be used as a high speed profile timer  */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER2ICR);
+	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -129,20 +107,22 @@ void m5307_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_setimr(MCFSIM_IMR_MASKALL);
-
 #if defined(CONFIG_NETtel) || \
     defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
 	/* Copy command line from FLASH to local buffer... */
 	memcpy(commandp, (char *) 0xf0004000, size);
 	commandp[size-1] = 0;
-	/* Different timer setup - to prevent device clash */
-	mcf_timervector = 30;
-	mcf_profilevector = 31;
-	mcf_timerlevel = 6;
 #endif
 
 	mach_reset = m5307_cpu_reset;
+	m5307_timers_init();
+	m5307_uarts_init();
+
+	/* Only support the external interrupts on their primary level */
+	mcf_mapirq2imr(25, MCFINTC_EINT1);
+	mcf_mapirq2imr(27, MCFINTC_EINT3);
+	mcf_mapirq2imr(29, MCFINTC_EINT5);
+	mcf_mapirq2imr(31, MCFINTC_EINT7);
 
 #ifdef CONFIG_BDM_DISABLE
 	/*
@@ -158,7 +138,6 @@ void __init config_BSP(char *commandp, int size)
 
 static int __init init_BSP(void)
 {
-	m5307_uarts_init();
 	platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices));
 	return 0;
 }
diff --git a/arch/m68knommu/platform/5307/gpio.c b/arch/m68knommu/platform/5307/gpio.c
new file mode 100644
index 0000000..8da5880
--- /dev/null
+++ b/arch/m68knommu/platform/5307/gpio.c
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PP",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 16,
+		},
+		.pddr				= MCFSIM_PADDR,
+		.podr				= MCFSIM_PADAT,
+		.ppdr				= MCFSIM_PADAT,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/532x/Makefile b/arch/m68knommu/platform/532x/Makefile
index e431912..4cc2324 100644
--- a/arch/m68knommu/platform/532x/Makefile
+++ b/arch/m68knommu/platform/532x/Makefile
@@ -15,4 +15,4 @@
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 #obj-y := config.o usb-mcf532x.o spi-mcf532x.o
-obj-y := config.o
+obj-y := config.o gpio.o
diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c
index cdb7619..d632948 100644
--- a/arch/m68knommu/platform/532x/config.c
+++ b/arch/m68knommu/platform/532x/config.c
@@ -20,7 +20,6 @@
 #include <linux/kernel.h>
 #include <linux/param.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
@@ -31,12 +30,6 @@
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 static struct mcf_platform_uart m532x_uart_platform[] = {
 	{
 		.mapbase	= MCFUART_BASE1,
@@ -88,6 +81,7 @@ static struct platform_device m532x_fec = {
 	.num_resources		= ARRAY_SIZE(m532x_fec_resources),
 	.resource		= m532x_fec_resources,
 };
+
 static struct platform_device *m532x_devices[] __initdata = {
 	&m532x_uart,
 	&m532x_fec,
@@ -98,18 +92,11 @@ static struct platform_device *m532x_devices[] __initdata = {
 static void __init m532x_uart_init_line(int line, int irq)
 {
 	if (line == 0) {
-		MCF_INTC0_ICR26 = 0x3;
-		MCF_INTC0_CIMR = 26;
 		/* GPIO initialization */
 		MCF_GPIO_PAR_UART |= 0x000F;
 	} else if (line == 1) {
-		MCF_INTC0_ICR27 = 0x3;
-		MCF_INTC0_CIMR = 27;
 		/* GPIO initialization */
 		MCF_GPIO_PAR_UART |= 0x0FF0;
-	} else if (line == 2) {
-		MCF_INTC0_ICR28 = 0x3;
-		MCF_INTC0_CIMR = 28;
 	}
 }
 
@@ -125,14 +112,6 @@ static void __init m532x_uarts_init(void)
 
 static void __init m532x_fec_init(void)
 {
-	/* Unmask FEC interrupts at ColdFire interrupt controller */
-	MCF_INTC0_ICR36 = 0x2;
-	MCF_INTC0_ICR40 = 0x2;
-	MCF_INTC0_ICR42 = 0x2;
-
-	MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
-		MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
-
 	/* Set multi-function pins to ethernet mode for fec0 */
 	MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
 		MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
@@ -142,26 +121,6 @@ static void __init m532x_fec_init(void)
 
 /***************************************************************************/
 
-void mcf_settimericr(unsigned int timer, unsigned int level)
-{
-	volatile unsigned char *icrp;
-	unsigned int icr;
-	unsigned char irq;
-
-	if (timer <= 2) {
-		switch (timer) {
-		case 2:  irq = 33; icr = MCFSIM_ICR_TIMER2; break;
-		default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
-		}
-		
-		icrp = (volatile unsigned char *) (icr);
-		*icrp = level;
-		mcf_enable_irq0(irq);
-	}
-}
-
-/***************************************************************************/
-
 static void m532x_cpu_reset(void)
 {
 	local_irq_disable();
@@ -172,8 +131,6 @@ static void m532x_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_setimr(MCFSIM_IMR_MASKALL);
-
 #if !defined(CONFIG_BOOTPARAM)
 	/* Copy command line from FLASH to local buffer... */
 	memcpy(commandp, (char *) 0x4000, 4);
@@ -185,10 +142,6 @@ void __init config_BSP(char *commandp, int size)
 	}
 #endif
 
-	mcf_timervector = 64+32;
-	mcf_profilevector = 64+33;
-	mach_reset = m532x_cpu_reset;
-
 #ifdef CONFIG_BDM_DISABLE
 	/*
 	 * Disable the BDM clocking.  This also turns off most of the rest of
@@ -438,8 +391,8 @@ void gpio_init(void)
 	/* Initialize TIN3 as a GPIO output to enable the write
 	   half of the latch */
 	MCF_GPIO_PAR_TIMER = 0x00;
-	MCF_GPIO_PDDR_TIMER = 0x08;
-	MCF_GPIO_PCLRR_TIMER = 0x0;
+	__raw_writeb(0x08, MCFGPIO_PDDR_TIMER);
+	__raw_writeb(0x00, MCFGPIO_PCLRR_TIMER);
 
 }
 
diff --git a/arch/m68knommu/platform/532x/gpio.c b/arch/m68knommu/platform/532x/gpio.c
new file mode 100644
index 0000000..184b773
--- /dev/null
+++ b/arch/m68knommu/platform/532x/gpio.c
@@ -0,0 +1,337 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PIRQ",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFEPORT_EPDDR,
+		.podr				= MCFEPORT_EPDR,
+		.ppdr				= MCFEPORT_EPPDR,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 8,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FECH,
+		.podr				= MCFGPIO_PODR_FECH,
+		.ppdr				= MCFGPIO_PPDSDR_FECH,
+		.setr				= MCFGPIO_PPDSDR_FECH,
+		.clrr				= MCFGPIO_PCLRR_FECH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 16,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_FECL,
+		.podr				= MCFGPIO_PODR_FECL,
+		.ppdr				= MCFGPIO_PPDSDR_FECL,
+		.setr				= MCFGPIO_PPDSDR_FECL,
+		.clrr				= MCFGPIO_PCLRR_FECL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "SSI",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 24,
+			.ngpio			= 5,
+		},
+		.pddr				= MCFGPIO_PDDR_SSI,
+		.podr				= MCFGPIO_PODR_SSI,
+		.ppdr				= MCFGPIO_PPDSDR_SSI,
+		.setr				= MCFGPIO_PPDSDR_SSI,
+		.clrr				= MCFGPIO_PCLRR_SSI,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BUSCTL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 32,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_BUSCTL,
+		.podr				= MCFGPIO_PODR_BUSCTL,
+		.ppdr				= MCFGPIO_PPDSDR_BUSCTL,
+		.setr				= MCFGPIO_PPDSDR_BUSCTL,
+		.clrr				= MCFGPIO_PCLRR_BUSCTL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "BE",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 40,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_BE,
+		.podr				= MCFGPIO_PODR_BE,
+		.ppdr				= MCFGPIO_PPDSDR_BE,
+		.setr				= MCFGPIO_PPDSDR_BE,
+		.clrr				= MCFGPIO_PCLRR_BE,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "CS",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 49,
+			.ngpio			= 5,
+		},
+		.pddr				= MCFGPIO_PDDR_CS,
+		.podr				= MCFGPIO_PODR_CS,
+		.ppdr				= MCFGPIO_PPDSDR_CS,
+		.setr				= MCFGPIO_PPDSDR_CS,
+		.clrr				= MCFGPIO_PCLRR_CS,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "PWM",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 58,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_PWM,
+		.podr				= MCFGPIO_PODR_PWM,
+		.ppdr				= MCFGPIO_PPDSDR_PWM,
+		.setr				= MCFGPIO_PPDSDR_PWM,
+		.clrr				= MCFGPIO_PCLRR_PWM,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "FECI2C",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 64,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_FECI2C,
+		.podr				= MCFGPIO_PODR_FECI2C,
+		.ppdr				= MCFGPIO_PPDSDR_FECI2C,
+		.setr				= MCFGPIO_PPDSDR_FECI2C,
+		.clrr				= MCFGPIO_PCLRR_FECI2C,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "UART",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 72,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_UART,
+		.podr				= MCFGPIO_PODR_UART,
+		.ppdr				= MCFGPIO_PPDSDR_UART,
+		.setr				= MCFGPIO_PPDSDR_UART,
+		.clrr				= MCFGPIO_PCLRR_UART,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "QSPI",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 80,
+			.ngpio			= 6,
+		},
+		.pddr				= MCFGPIO_PDDR_QSPI,
+		.podr				= MCFGPIO_PODR_QSPI,
+		.ppdr				= MCFGPIO_PPDSDR_QSPI,
+		.setr				= MCFGPIO_PPDSDR_QSPI,
+		.clrr				= MCFGPIO_PCLRR_QSPI,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "TIMER",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 88,
+			.ngpio			= 4,
+		},
+		.pddr				= MCFGPIO_PDDR_TIMER,
+		.podr				= MCFGPIO_PODR_TIMER,
+		.ppdr				= MCFGPIO_PPDSDR_TIMER,
+		.setr				= MCFGPIO_PPDSDR_TIMER,
+		.clrr				= MCFGPIO_PCLRR_TIMER,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "LCDDATAH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 96,
+			.ngpio			= 2,
+		},
+		.pddr				= MCFGPIO_PDDR_LCDDATAH,
+		.podr				= MCFGPIO_PODR_LCDDATAH,
+		.ppdr				= MCFGPIO_PPDSDR_LCDDATAH,
+		.setr				= MCFGPIO_PPDSDR_LCDDATAH,
+		.clrr				= MCFGPIO_PCLRR_LCDDATAH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "LCDDATAM",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 104,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_LCDDATAM,
+		.podr				= MCFGPIO_PODR_LCDDATAM,
+		.ppdr				= MCFGPIO_PPDSDR_LCDDATAM,
+		.setr				= MCFGPIO_PPDSDR_LCDDATAM,
+		.clrr				= MCFGPIO_PCLRR_LCDDATAM,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "LCDDATAL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 112,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_LCDDATAL,
+		.podr				= MCFGPIO_PODR_LCDDATAL,
+		.ppdr				= MCFGPIO_PPDSDR_LCDDATAL,
+		.setr				= MCFGPIO_PPDSDR_LCDDATAL,
+		.clrr				= MCFGPIO_PCLRR_LCDDATAL,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "LCDCTLH",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 120,
+			.ngpio			= 1,
+		},
+		.pddr				= MCFGPIO_PDDR_LCDCTLH,
+		.podr				= MCFGPIO_PODR_LCDCTLH,
+		.ppdr				= MCFGPIO_PPDSDR_LCDCTLH,
+		.setr				= MCFGPIO_PPDSDR_LCDCTLH,
+		.clrr				= MCFGPIO_PCLRR_LCDCTLH,
+	},
+	{
+		.gpio_chip			= {
+			.label			= "LCDCTLL",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value_fast,
+			.base			= 128,
+			.ngpio			= 8,
+		},
+		.pddr				= MCFGPIO_PDDR_LCDCTLL,
+		.podr				= MCFGPIO_PODR_LCDCTLL,
+		.ppdr				= MCFGPIO_PPDSDR_LCDCTLL,
+		.setr				= MCFGPIO_PPDSDR_LCDCTLL,
+		.clrr				= MCFGPIO_PCLRR_LCDCTLL,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/5407/Makefile b/arch/m68knommu/platform/5407/Makefile
index e6035e7..dee62c5 100644
--- a/arch/m68knommu/platform/5407/Makefile
+++ b/arch/m68knommu/platform/5407/Makefile
@@ -14,5 +14,5 @@
 
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
-obj-y := config.o
+obj-y := config.o gpio.o
 
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
index b41d942..70ea789 100644
--- a/arch/m68knommu/platform/5407/config.c
+++ b/arch/m68knommu/platform/5407/config.c
@@ -20,12 +20,6 @@
 
 /***************************************************************************/
 
-extern unsigned int mcf_timervector;
-extern unsigned int mcf_profilevector;
-extern unsigned int mcf_timerlevel;
-
-/***************************************************************************/
-
 static struct mcf_platform_uart m5407_uart_platform[] = {
 	{
 		.mapbase	= MCF_MBAR + MCFUART_BASE1,
@@ -55,11 +49,11 @@ static void __init m5407_uart_init_line(int line, int irq)
 	if (line == 0) {
 		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);
+		mcf_mapirq2imr(irq, MCFINTC_UART0);
 	} else if (line == 1) {
 		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);
+		mcf_mapirq2imr(irq, MCFINTC_UART1);
 	}
 }
 
@@ -74,35 +68,19 @@ static void __init m5407_uarts_init(void)
 
 /***************************************************************************/
 
-void mcf_autovector(unsigned int vec)
-{
-	volatile unsigned char  *mbar;
-
-	if ((vec >= 25) && (vec <= 31)) {
-		mbar = (volatile unsigned char *) MCF_MBAR;
-		vec = 0x1 << (vec - 24);
-		*(mbar + MCFSIM_AVR) |= vec;
-		mcf_setimr(mcf_getimr() & ~vec);
-	}
-}
-
-/***************************************************************************/
-
-void mcf_settimericr(unsigned int timer, unsigned int level)
+static void __init m5407_timers_init(void)
 {
-	volatile unsigned char *icrp;
-	unsigned int icr, imr;
-
-	if (timer <= 2) {
-		switch (timer) {
-		case 2:  icr = MCFSIM_TIMER2ICR; imr = MCFSIM_IMR_TIMER2; break;
-		default: icr = MCFSIM_TIMER1ICR; imr = MCFSIM_IMR_TIMER1; break;
-		}
-
-		icrp = (volatile unsigned char *) (MCF_MBAR + icr);
-		*icrp = MCFSIM_ICR_AUTOVEC | (level << 2) | MCFSIM_ICR_PRI3;
-		mcf_setimr(mcf_getimr() & ~imr);
-	}
+	/* Timer1 is always used as system timer */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER1ICR);
+	mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
+
+#ifdef CONFIG_HIGHPROFILE
+	/* Timer2 is to be used as a high speed profile timer  */
+	writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
+		MCF_MBAR + MCFSIM_TIMER2ICR);
+	mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
+#endif
 }
 
 /***************************************************************************/
@@ -120,23 +98,21 @@ void m5407_cpu_reset(void)
 
 void __init config_BSP(char *commandp, int size)
 {
-	mcf_setimr(MCFSIM_IMR_MASKALL);
-
-#if defined(CONFIG_CLEOPATRA)
-	/* Different timer setup - to prevent device clash */
-	mcf_timervector = 30;
-	mcf_profilevector = 31;
-	mcf_timerlevel = 6;
-#endif
-
 	mach_reset = m5407_cpu_reset;
+	m5407_timers_init();
+	m5407_uarts_init();
+
+	/* Only support the external interrupts on their primary level */
+	mcf_mapirq2imr(25, MCFINTC_EINT1);
+	mcf_mapirq2imr(27, MCFINTC_EINT3);
+	mcf_mapirq2imr(29, MCFINTC_EINT5);
+	mcf_mapirq2imr(31, MCFINTC_EINT7);
 }
 
 /***************************************************************************/
 
 static int __init init_BSP(void)
 {
-	m5407_uarts_init();
 	platform_add_devices(m5407_devices, ARRAY_SIZE(m5407_devices));
 	return 0;
 }
diff --git a/arch/m68knommu/platform/5407/gpio.c b/arch/m68knommu/platform/5407/gpio.c
new file mode 100644
index 0000000..8da5880
--- /dev/null
+++ b/arch/m68knommu/platform/5407/gpio.c
@@ -0,0 +1,49 @@
+/*
+ * Coldfire generic GPIO support
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/mcfgpio.h>
+
+static struct mcf_gpio_chip mcf_gpio_chips[] = {
+	{
+		.gpio_chip			= {
+			.label			= "PP",
+			.request		= mcf_gpio_request,
+			.free			= mcf_gpio_free,
+			.direction_input	= mcf_gpio_direction_input,
+			.direction_output	= mcf_gpio_direction_output,
+			.get			= mcf_gpio_get_value,
+			.set			= mcf_gpio_set_value,
+			.ngpio			= 16,
+		},
+		.pddr				= MCFSIM_PADDR,
+		.podr				= MCFSIM_PADAT,
+		.ppdr				= MCFSIM_PADAT,
+	},
+};
+
+static int __init mcf_gpio_init(void)
+{
+	unsigned i = 0;
+	while (i < ARRAY_SIZE(mcf_gpio_chips))
+		(void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]);
+	return 0;
+}
+
+core_initcall(mcf_gpio_init);
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
index 72e56d5..b91ee85 100644
--- a/arch/m68knommu/platform/68328/ints.c
+++ b/arch/m68knommu/platform/68328/ints.c
@@ -73,34 +73,6 @@ extern e_vector *_ramvec;
 /* The number of spurious interrupts */
 volatile unsigned int num_spurious;
 
-/*
- * This function should be called during kernel startup to initialize
- * the machine vector table.
- */
-void __init init_vectors(void)
-{
-	int i;
-
-	/* set up the vectors */
-	for (i = 72; i < 256; ++i)
-		_ramvec[i] = (e_vector) bad_interrupt;
-
-	_ramvec[32] = system_call;
-
-	_ramvec[65] = (e_vector) inthandler1;
-	_ramvec[66] = (e_vector) inthandler2;
-	_ramvec[67] = (e_vector) inthandler3;
-	_ramvec[68] = (e_vector) inthandler4;
-	_ramvec[69] = (e_vector) inthandler5;
-	_ramvec[70] = (e_vector) inthandler6;
-	_ramvec[71] = (e_vector) inthandler7;
- 
-	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
-
-	/* turn off all interrupts */
-	IMR = ~0;
-}
-
 /* The 68k family did not have a good way to determine the source
  * of interrupts until later in the family.  The EC000 core does
  * not provide the vector number on the stack, we vector everything
@@ -163,18 +135,54 @@ void process_int(int vec, struct pt_regs *fp)
 	}
 }
 
-void enable_vector(unsigned int irq)
+static void intc_irq_unmask(unsigned int irq)
 {
 	IMR &= ~(1<<irq);
 }
 
-void disable_vector(unsigned int irq)
+static void intc_irq_mask(unsigned int irq)
 {
 	IMR |= (1<<irq);
 }
 
-void ack_vector(unsigned int irq)
+static struct irq_chip intc_irq_chip = {
+	.name		= "M68K-INTC",
+	.mask		= intc_irq_mask,
+	.unmask		= intc_irq_unmask,
+};
+
+/*
+ * This function should be called during kernel startup to initialize
+ * the machine vector table.
+ */
+void __init init_IRQ(void)
 {
-	/* Nothing needed */
+	int i;
+
+	/* set up the vectors */
+	for (i = 72; i < 256; ++i)
+		_ramvec[i] = (e_vector) bad_interrupt;
+
+	_ramvec[32] = system_call;
+
+	_ramvec[65] = (e_vector) inthandler1;
+	_ramvec[66] = (e_vector) inthandler2;
+	_ramvec[67] = (e_vector) inthandler3;
+	_ramvec[68] = (e_vector) inthandler4;
+	_ramvec[69] = (e_vector) inthandler5;
+	_ramvec[70] = (e_vector) inthandler6;
+	_ramvec[71] = (e_vector) inthandler7;
+
+	IVR = 0x40; /* Set DragonBall IVR (interrupt base) to 64 */
+
+	/* turn off all interrupts */
+	IMR = ~0;
+
+	for (i = 0; (i < NR_IRQS); i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].chip = &intc_irq_chip;
+	}
 }
 
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
index c367811..1143f77 100644
--- a/arch/m68knommu/platform/68360/ints.c
+++ b/arch/m68knommu/platform/68360/ints.c
@@ -37,11 +37,33 @@ extern void *_ramvec[];
 /* The number of spurious interrupts */
 volatile unsigned int num_spurious;
 
+static void intc_irq_unmask(unsigned int irq)
+{
+	pquicc->intr_cimr |= (1 << irq);
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+	pquicc->intr_cimr &= ~(1 << irq);
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+	pquicc->intr_cisr = (1 << irq);
+}
+
+static struct irq_chip intc_irq_chip = {
+	.name		= "M68K-INTC",
+	.mask		= intc_irq_mask,
+	.unmask		= intc_irq_unmask,
+	.ack		= intc_irq_ack,
+};
+
 /*
  * This function should be called during kernel startup to initialize
  * the vector table.
  */
-void init_vectors(void)
+void init_IRQ(void)
 {
 	int i;
 	int vba = (CPM_VECTOR_BASE<<4);
@@ -109,20 +131,12 @@ void init_vectors(void)
 
 	/* turn off all CPM interrupts */
 	pquicc->intr_cimr = 0x00000000;
-}
-
-void enable_vector(unsigned int irq)
-{
-	pquicc->intr_cimr |= (1 << irq);
-}
 
-void disable_vector(unsigned int irq)
-{
-	pquicc->intr_cimr &= ~(1 << irq);
-}
-
-void ack_vector(unsigned int irq)
-{
-	pquicc->intr_cisr = (1 << irq);
+	for (i = 0; (i < NR_IRQS); i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].chip = &intc_irq_chip;
+	}
 }
 
diff --git a/arch/m68knommu/platform/coldfire/Makefile b/arch/m68knommu/platform/coldfire/Makefile
index 1bcb937..f72a0e5 100644
--- a/arch/m68knommu/platform/coldfire/Makefile
+++ b/arch/m68knommu/platform/coldfire/Makefile
@@ -15,16 +15,17 @@
 asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1
 
 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
-obj-$(CONFIG_M523x)	+= pit.o dma_timer.o
-obj-$(CONFIG_M5249)	+= timers.o
-obj-$(CONFIG_M527x)	+= pit.o
+obj-$(CONFIG_M5206)	+= timers.o intc.o
+obj-$(CONFIG_M5206e)	+= timers.o intc.o
+obj-$(CONFIG_M520x)	+= pit.o intc-simr.o
+obj-$(CONFIG_M523x)	+= pit.o dma_timer.o intc-2.o
+obj-$(CONFIG_M5249)	+= timers.o intc.o
+obj-$(CONFIG_M527x)	+= pit.o intc-2.o
 obj-$(CONFIG_M5272)	+= timers.o
-obj-$(CONFIG_M528x)	+= pit.o
-obj-$(CONFIG_M5307)	+= timers.o
-obj-$(CONFIG_M532x)	+= timers.o
-obj-$(CONFIG_M5407)	+= timers.o
+obj-$(CONFIG_M528x)	+= pit.o intc-2.o
+obj-$(CONFIG_M5307)	+= timers.o intc.o
+obj-$(CONFIG_M532x)	+= timers.o intc-simr.o
+obj-$(CONFIG_M5407)	+= timers.o intc.o
 
+obj-y			+= pinmux.o gpio.o
 extra-y := head.o
diff --git a/arch/m68knommu/platform/coldfire/gpio.c b/arch/m68knommu/platform/coldfire/gpio.c
new file mode 100644
index 0000000..ff00457
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/gpio.c
@@ -0,0 +1,127 @@
+/*
+ * Coldfire generic GPIO support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/init.h>
+#include <linux/sysdev.h>
+
+#include <asm/gpio.h>
+#include <asm/pinmux.h>
+#include <asm/mcfgpio.h>
+
+#define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip)
+
+int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	unsigned long flags;
+	MCFGPIO_PORTTYPE dir;
+	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+	local_irq_save(flags);
+	dir = mcfgpio_read(mcf_chip->pddr);
+	dir &= ~mcfgpio_bit(chip->base + offset);
+	mcfgpio_write(dir, mcf_chip->pddr);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+	return mcfgpio_read(mcf_chip->ppdr) & mcfgpio_bit(chip->base + offset);
+}
+
+int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+		int value)
+{
+	unsigned long flags;
+	MCFGPIO_PORTTYPE data;
+	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+	local_irq_save(flags);
+	/* write the value to the output latch */
+	data = mcfgpio_read(mcf_chip->podr);
+	if (value)
+		data |= mcfgpio_bit(chip->base + offset);
+	else
+		data &= ~mcfgpio_bit(chip->base + offset);
+	mcfgpio_write(data, mcf_chip->podr);
+
+	/* now set the direction to output */
+	data = mcfgpio_read(mcf_chip->pddr);
+	data |= mcfgpio_bit(chip->base + offset);
+	mcfgpio_write(data, mcf_chip->pddr);
+	local_irq_restore(flags);
+
+	return 0;
+}
+
+void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+	unsigned long flags;
+	MCFGPIO_PORTTYPE data;
+
+	local_irq_save(flags);
+	data = mcfgpio_read(mcf_chip->podr);
+	if (value)
+		data |= mcfgpio_bit(chip->base + offset);
+	else
+		data &= ~mcfgpio_bit(chip->base + offset);
+	mcfgpio_write(data, mcf_chip->podr);
+	local_irq_restore(flags);
+}
+
+void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+	if (value)
+		mcfgpio_write(mcfgpio_bit(chip->base + offset), mcf_chip->setr);
+	else
+		mcfgpio_write(~mcfgpio_bit(chip->base + offset), mcf_chip->clrr);
+}
+
+int mcf_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+	return mcf_chip->gpio_to_pinmux ?
+		mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0;
+}
+
+void mcf_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
+
+	mcf_gpio_direction_input(chip, offset);
+
+	if (mcf_chip->gpio_to_pinmux)
+		mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0);
+}
+
+struct sysdev_class mcf_gpio_sysclass = {
+	.name	= "gpio",
+};
+
+static int __init mcf_gpio_sysinit(void)
+{
+	return sysdev_class_register(&mcf_gpio_sysclass);
+}
+
+core_initcall(mcf_gpio_sysinit);
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
new file mode 100644
index 0000000..5598c8b
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/intc-2.c
@@ -0,0 +1,93 @@
+/*
+ * intc-1.c
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+/*
+ *	Each vector needs a unique priority and level asscoiated with it.
+ *	We don't really care so much what they are, we don't rely on the
+ *	tranditional priority interrupt scheme of the m68k/ColdFire.
+ */
+static u8 intc_intpri = 0x36;
+
+static void intc_irq_mask(unsigned int irq)
+{
+	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+		unsigned long imraddr;
+		u32 val, imrbit;
+
+		irq -= MCFINT_VECBASE;
+		imraddr = MCF_IPSBAR;
+		imraddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+		imraddr += (irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL;
+		imrbit = 0x1 << (irq & 0x1f);
+
+		val = __raw_readl(imraddr);
+		__raw_writel(val | imrbit, imraddr);
+	}
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+	if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECBASE + 128)) {
+		unsigned long intaddr, imraddr, icraddr;
+		u32 val, imrbit;
+
+		irq -= MCFINT_VECBASE;
+		intaddr = MCF_IPSBAR;
+		intaddr += (irq & 0x40) ? MCFICM_INTC1 : MCFICM_INTC0;
+		imraddr = intaddr + ((irq & 0x20) ? MCFINTC_IMRH : MCFINTC_IMRL);
+		icraddr = intaddr + MCFINTC_ICR0 + (irq & 0x3f);
+		imrbit = 0x1 << (irq & 0x1f);
+
+		/* Don't set the "maskall" bit! */
+		if ((irq & 0x20) == 0)
+			imrbit |= 0x1;
+
+		if (__raw_readb(icraddr) == 0)
+			__raw_writeb(intc_intpri--, icraddr);
+
+		val = __raw_readl(imraddr);
+		__raw_writel(val & ~imrbit, imraddr);
+	}
+}
+
+static struct irq_chip intc_irq_chip = {
+	.name		= "CF-INTC",
+	.mask		= intc_irq_mask,
+	.unmask		= intc_irq_unmask,
+};
+
+void __init init_IRQ(void)
+{
+	int irq;
+
+	init_vectors();
+
+	/* Mask all interrupt sources */
+	__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
+	__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL);
+
+	for (irq = 0; (irq < NR_IRQS); irq++) {
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = NULL;
+		irq_desc[irq].depth = 1;
+		irq_desc[irq].chip = &intc_irq_chip;
+	}
+}
+
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c
new file mode 100644
index 0000000..1b01e79
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/intc-simr.c
@@ -0,0 +1,78 @@
+/*
+ * intc-simr.c
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/traps.h>
+
+static void intc_irq_mask(unsigned int irq)
+{
+	if (irq >= MCFINT_VECBASE) {
+		if (irq < MCFINT_VECBASE + 64)
+			__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_SIMR);
+		else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_SIMR)
+			__raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_SIMR);
+	}
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+	if (irq >= MCFINT_VECBASE) {
+		if (irq < MCFINT_VECBASE + 64)
+			__raw_writeb(irq - MCFINT_VECBASE, MCFINTC0_CIMR);
+		else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_CIMR)
+			__raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_CIMR);
+	}
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+	if (irq >= MCFINT_VECBASE) {
+		if (irq < MCFINT_VECBASE + 64)
+			__raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE);
+		else if ((irq < MCFINT_VECBASE) && MCFINTC1_ICR0)
+			__raw_writeb(5, MCFINTC1_ICR0 + irq - MCFINT_VECBASE - 64);
+	}
+	return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+	.name		= "CF-INTC",
+	.mask		= intc_irq_mask,
+	.unmask		= intc_irq_unmask,
+	.set_type	= intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+	int irq;
+
+	init_vectors();
+
+	/* Mask all interrupt sources */
+	__raw_writeb(0xff, MCFINTC0_SIMR);
+	if (MCFINTC1_SIMR)
+		__raw_writeb(0xff, MCFINTC1_SIMR);
+
+	for (irq = 0; (irq < NR_IRQS); irq++) {
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = NULL;
+		irq_desc[irq].depth = 1;
+		irq_desc[irq].chip = &intc_irq_chip;
+		intc_irq_set_type(irq, 0);
+	}
+}
+
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
new file mode 100644
index 0000000..a4560c8
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -0,0 +1,153 @@
+/*
+ * intc.c  -- support for the old ColdFire interrupt controller
+ *
+ * (C) Copyright 2009, Greg Ungerer <gerg@snapgear.com>
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/traps.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+
+/*
+ * The mapping of irq number to a mask register bit is not one-to-one.
+ * The irq numbers are either based on "level" of interrupt or fixed
+ * for an autovector-able interrupt. So we keep a local data structure
+ * that maps from irq to mask register. Not all interrupts will have
+ * an IMR bit.
+ */
+unsigned char mcf_irq2imr[NR_IRQS];
+
+/*
+ * Define the miniumun and maximum external interrupt numbers.
+ * This is also used as the "level" interrupt numbers.
+ */
+#define	EIRQ1	25
+#define	EIRQ7	31
+
+/*
+ * In the early version 2 core ColdFire parts the IMR register was 16 bits
+ * in size. Version 3 (and later version 2) core parts have a 32 bit
+ * sized IMR register. Provide some size independant methods to access the
+ * IMR register.
+ */
+#ifdef MCFSIM_IMR_IS_16BITS
+
+void mcf_setimr(int index)
+{
+	u16 imr;
+	imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+	__raw_writew(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_clrimr(int index)
+{
+	u16 imr;
+	imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+	__raw_writew(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_maskimr(unsigned int mask)
+{
+	u16 imr;
+	imr = __raw_readw(MCF_MBAR + MCFSIM_IMR);
+	imr |= mask;
+	__raw_writew(imr, MCF_MBAR + MCFSIM_IMR);
+}
+
+#else
+
+void mcf_setimr(int index)
+{
+	u32 imr;
+	imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+	__raw_writel(imr | (0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_clrimr(int index)
+{
+	u32 imr;
+	imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+	__raw_writel(imr & ~(0x1 << index), MCF_MBAR + MCFSIM_IMR);
+}
+
+void mcf_maskimr(unsigned int mask)
+{
+	u32 imr;
+	imr = __raw_readl(MCF_MBAR + MCFSIM_IMR);
+	imr |= mask;
+	__raw_writel(imr, MCF_MBAR + MCFSIM_IMR);
+}
+
+#endif
+
+/*
+ * Interrupts can be "vectored" on the ColdFire cores that support this old
+ * interrupt controller. That is, the device raising the interrupt can also
+ * supply the vector number to interrupt through. The AVR register of the
+ * interrupt controller enables or disables this for each external interrupt,
+ * so provide generic support for this. Setting this up is out-of-band for
+ * the interrupt system API's, and needs to be done by the driver that
+ * supports this device. Very few devices actually use this.
+ */
+void mcf_autovector(int irq)
+{
+#ifdef MCFSIM_AVR
+	if ((irq >= EIRQ1) && (irq <= EIRQ7)) {
+		u8 avec;
+		avec = __raw_readb(MCF_MBAR + MCFSIM_AVR);
+		avec |= (0x1 << (irq - EIRQ1 + 1));
+		__raw_writeb(avec, MCF_MBAR + MCFSIM_AVR);
+	}
+#endif
+}
+
+static void intc_irq_mask(unsigned int irq)
+{
+	if (mcf_irq2imr[irq])
+		mcf_setimr(mcf_irq2imr[irq]);
+}
+
+static void intc_irq_unmask(unsigned int irq)
+{
+	if (mcf_irq2imr[irq])
+		mcf_clrimr(mcf_irq2imr[irq]);
+}
+
+static int intc_irq_set_type(unsigned int irq, unsigned int type)
+{
+	return 0;
+}
+
+static struct irq_chip intc_irq_chip = {
+	.name		= "CF-INTC",
+	.mask		= intc_irq_mask,
+	.unmask		= intc_irq_unmask,
+	.set_type	= intc_irq_set_type,
+};
+
+void __init init_IRQ(void)
+{
+	int irq;
+
+	init_vectors();
+	mcf_maskimr(0xffffffff);
+
+	for (irq = 0; (irq < NR_IRQS); irq++) {
+		irq_desc[irq].status = IRQ_DISABLED;
+		irq_desc[irq].action = NULL;
+		irq_desc[irq].depth = 1;
+		irq_desc[irq].chip = &intc_irq_chip;
+		intc_irq_set_type(irq, 0);
+	}
+}
+
diff --git a/arch/m68knommu/platform/coldfire/pinmux.c b/arch/m68knommu/platform/coldfire/pinmux.c
new file mode 100644
index 0000000..8c62b82
--- /dev/null
+++ b/arch/m68knommu/platform/coldfire/pinmux.c
@@ -0,0 +1,28 @@
+/*
+ * Coldfire generic GPIO pinmux support.
+ *
+ * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; version 2 of the License.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT 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 <asm/pinmux.h>
+
+int mcf_pinmux_request(unsigned pinmux, unsigned func)
+{
+	return 0;
+}
+
+void mcf_pinmux_release(unsigned pinmux, unsigned func)
+{
+}
diff --git a/arch/m68knommu/platform/coldfire/pit.c b/arch/m68knommu/platform/coldfire/pit.c
index 61b9621..d8720ee 100644
--- a/arch/m68knommu/platform/coldfire/pit.c
+++ b/arch/m68knommu/platform/coldfire/pit.c
@@ -32,7 +32,6 @@
  */
 #define	FREQ	((MCF_CLK / 2) / 64)
 #define	TA(a)	(MCF_IPSBAR + MCFPIT_BASE1 + (a))
-#define	INTC0	(MCF_IPSBAR + MCFICM_INTC0)
 #define PIT_CYCLES_PER_JIFFY (FREQ / HZ)
 
 static u32 pit_cnt;
@@ -154,8 +153,6 @@ static struct clocksource pit_clk = {
 
 void hw_timer_init(void)
 {
-	u32 imr;
-
 	cf_pit_clockevent.cpumask = cpumask_of(smp_processor_id());
 	cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
 	cf_pit_clockevent.max_delta_ns =
@@ -166,11 +163,6 @@ void hw_timer_init(void)
 
 	setup_irq(MCFINT_VECBASE + MCFINT_PIT1, &pit_irq);
 
-	__raw_writeb(ICR_INTRCONF, INTC0 + MCFINTC_ICR0 + MCFINT_PIT1);
-	imr = __raw_readl(INTC0 + MCFPIT_IMR);
-	imr &= ~MCFPIT_IMR_IBIT;
-	__raw_writel(imr, INTC0 + MCFPIT_IMR);
-
 	pit_clk.mult = clocksource_hz2mult(FREQ, pit_clk.shift);
 	clocksource_register(&pit_clk);
 }
diff --git a/arch/m68knommu/platform/coldfire/timers.c b/arch/m68knommu/platform/coldfire/timers.c
index 1ba8a37..2304d73 100644
--- a/arch/m68knommu/platform/coldfire/timers.c
+++ b/arch/m68knommu/platform/coldfire/timers.c
@@ -31,19 +31,9 @@
 #define	TA(a)	(MCF_MBAR + MCFTIMER_BASE1 + (a))
 
 /*
- *	Default the timer and vector to use for ColdFire. Some ColdFire
- *	CPU's and some boards may want different. Their sub-architecture
- *	startup code (in config.c) can change these if they want.
- */
-unsigned int	mcf_timervector = 29;
-unsigned int	mcf_profilevector = 31;
-unsigned int	mcf_timerlevel = 5;
-
-/*
  *	These provide the underlying interrupt vector support.
  *	Unfortunately it is a little different on each ColdFire.
  */
-extern void mcf_settimericr(int timer, int level);
 void coldfire_profile_init(void);
 
 #if defined(CONFIG_M532x)
@@ -107,8 +97,6 @@ static struct clocksource mcftmr_clk = {
 
 void hw_timer_init(void)
 {
-	setup_irq(mcf_timervector, &mcftmr_timer_irq);
-
 	__raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR));
 	mcftmr_cycles_per_jiffy = FREQ / HZ;
 	/*
@@ -124,7 +112,7 @@ void hw_timer_init(void)
 	mcftmr_clk.mult = clocksource_hz2mult(FREQ, mcftmr_clk.shift);
 	clocksource_register(&mcftmr_clk);
 
-	mcf_settimericr(1, mcf_timerlevel);
+	setup_irq(MCF_IRQ_TIMER, &mcftmr_timer_irq);
 
 #ifdef CONFIG_HIGHPROFILE
 	coldfire_profile_init();
@@ -171,8 +159,6 @@ void coldfire_profile_init(void)
 	printk(KERN_INFO "PROFILE: lodging TIMER2 @ %dHz as profile timer\n",
 	       PROFILEHZ);
 
-	setup_irq(mcf_profilevector, &coldfire_profile_irq);
-
 	/* Set up TIMER 2 as high speed profile clock */
 	__raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR));
 
@@ -180,7 +166,7 @@ void coldfire_profile_init(void)
 	__raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 |
 		MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR));
 
-	mcf_settimericr(2, 7);
+	setup_irq(MCF_IRQ_PROFILER, &coldfire_profile_irq);
 }
 
 /***************************************************************************/
diff --git a/arch/m68knommu/platform/coldfire/vectors.c b/arch/m68knommu/platform/coldfire/vectors.c
index bdca029..a21d3f8 100644
--- a/arch/m68knommu/platform/coldfire/vectors.c
+++ b/arch/m68knommu/platform/coldfire/vectors.c
@@ -1,7 +1,7 @@
 /***************************************************************************/
 
 /*
- *	linux/arch/m68knommu/platform/5307/vectors.c
+ *	linux/arch/m68knommu/platform/coldfire/vectors.c
  *
  *	Copyright (C) 1999-2007, Greg Ungerer <gerg@snapgear.com>
  */
@@ -15,7 +15,6 @@
 #include <asm/machdep.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
-#include <asm/mcfdma.h>
 #include <asm/mcfwdebug.h>
 
 /***************************************************************************/
@@ -79,20 +78,3 @@ void __init init_vectors(void)
 }
 
 /***************************************************************************/
-
-void enable_vector(unsigned int irq)
-{
-	/* Currently no action on ColdFire */
-}
-
-void disable_vector(unsigned int irq)
-{
-	/* Currently no action on ColdFire */
-}
-
-void ack_vector(unsigned int irq)
-{
-	/* Currently no action on ColdFire */
-}
-
-/***************************************************************************/
diff --git a/arch/microblaze/include/asm/device.h b/arch/microblaze/include/asm/device.h
index c042830..30286db 100644
--- a/arch/microblaze/include/asm/device.h
+++ b/arch/microblaze/include/asm/device.h
@@ -16,6 +16,9 @@ struct dev_archdata {
 	struct device_node	*of_node;
 };
 
+struct pdev_archdata {
+};
+
 #endif /* _ASM_MICROBLAZE_DEVICE_H */
 
 
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index 0b85232..cb05a07 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -381,7 +381,7 @@
 #define __NR_preadv		363 /* new */
 #define __NR_pwritev		364 /* new */
 #define __NR_rt_tgsigqueueinfo	365 /* new */
-#define __NR_perf_counter_open	366 /* new */
+#define __NR_perf_event_open	366 /* new */
 
 #define __NR_syscalls		367
 
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 4572160..ecec191 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -370,4 +370,4 @@ ENTRY(sys_call_table)
 	.long sys_ni_syscall
 	.long sys_ni_syscall
 	.long sys_rt_tgsigqueueinfo	/* 365 */
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index d34d38d..ec5fa91 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -23,8 +23,8 @@ SECTIONS {
 		_stext = . ;
 		*(.text .text.*)
 		*(.fixup)
-
-		*(.exitcall.exit)
+               EXIT_TEXT
+               EXIT_CALL
 		SCHED_TEXT
 		LOCK_TEXT
 		KPROBES_TEXT
@@ -162,4 +162,6 @@ SECTIONS {
 	}
 	. = ALIGN(4096);
 	_end = .;
+
+	DISCARDS
 }
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3ca0fe1..705a7a9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -6,7 +6,7 @@ config MIPS
 	select HAVE_ARCH_KGDB
 	# Horrible source of confusion.  Die, die, die ...
 	select EMBEDDED
-	select RTC_LIB
+	select RTC_LIB if !LEMOTE_FULOONG2E
 
 mainmenu "Linux/MIPS Kernel Configuration"
 
@@ -80,6 +80,21 @@ config BCM47XX
 	help
 	 Support for BCM47XX based boards
 
+config BCM63XX
+	bool "Broadcom BCM63XX based boards"
+	select CEVT_R4K
+	select CSRC_R4K
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_HAS_EARLY_PRINTK
+	select SWAP_IO_SPACE
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	 Support for BCM63XX based boards
+
 config MIPS_COBALT
 	bool "Cobalt Server"
 	select CEVT_R4K
@@ -174,30 +189,15 @@ config LASAT
 	select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
 	select SYS_SUPPORTS_LITTLE_ENDIAN
 
-config LEMOTE_FULONG
-	bool "Lemote Fulong mini-PC"
-	select ARCH_SPARSEMEM_ENABLE
-	select CEVT_R4K
-	select CSRC_R4K
-	select SYS_HAS_CPU_LOONGSON2
-	select DMA_NONCOHERENT
-	select BOOT_ELF32
-	select BOARD_SCACHE
-	select HAVE_STD_PC_SERIAL_PORT
-	select HW_HAS_PCI
-	select I8259
-	select ISA
-	select IRQ_CPU
-	select SYS_SUPPORTS_32BIT_KERNEL
-	select SYS_SUPPORTS_64BIT_KERNEL
-	select SYS_SUPPORTS_LITTLE_ENDIAN
-	select SYS_SUPPORTS_HIGHMEM
-	select SYS_HAS_EARLY_PRINTK
-	select GENERIC_ISA_DMA_SUPPORT_BROKEN
-	select CPU_HAS_WB
+config MACH_LOONGSON
+	bool "Loongson family of machines"
 	help
-	  Lemote Fulong mini-PC board based on the Chinese Loongson-2E CPU and
-	  an FPGA northbridge
+	  This enables the support of Loongson family of machines.
+
+	  Loongson is a family of general-purpose MIPS-compatible CPUs.
+	  developed at Institute of Computing Technology (ICT),
+	  Chinese Academy of Sciences (CAS) in the People's Republic
+	  of China. The chief architect is Professor Weiwu Hu.
 
 config MIPS_MALTA
 	bool "MIPS Malta board"
@@ -660,6 +660,7 @@ endchoice
 
 source "arch/mips/alchemy/Kconfig"
 source "arch/mips/basler/excite/Kconfig"
+source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
@@ -668,6 +669,7 @@ source "arch/mips/sibyte/Kconfig"
 source "arch/mips/txx9/Kconfig"
 source "arch/mips/vr41xx/Kconfig"
 source "arch/mips/cavium-octeon/Kconfig"
+source "arch/mips/loongson/Kconfig"
 
 endmenu
 
@@ -1044,12 +1046,10 @@ choice
 	prompt "CPU type"
 	default CPU_R4X00
 
-config CPU_LOONGSON2
-	bool "Loongson 2"
-	depends on SYS_HAS_CPU_LOONGSON2
-	select CPU_SUPPORTS_32BIT_KERNEL
-	select CPU_SUPPORTS_64BIT_KERNEL
-	select CPU_SUPPORTS_HIGHMEM
+config CPU_LOONGSON2E
+	bool "Loongson 2E"
+	depends on SYS_HAS_CPU_LOONGSON2E
+	select CPU_LOONGSON2
 	help
 	  The Loongson 2E processor implements the MIPS III instruction set
 	  with many extensions.
@@ -1057,7 +1057,6 @@ config CPU_LOONGSON2
 config CPU_MIPS32_R1
 	bool "MIPS32 Release 1"
 	depends on SYS_HAS_CPU_MIPS32_R1
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
@@ -1075,7 +1074,6 @@ config CPU_MIPS32_R1
 config CPU_MIPS32_R2
 	bool "MIPS32 Release 2"
 	depends on SYS_HAS_CPU_MIPS32_R2
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
@@ -1089,7 +1087,6 @@ config CPU_MIPS32_R2
 config CPU_MIPS64_R1
 	bool "MIPS64 Release 1"
 	depends on SYS_HAS_CPU_MIPS64_R1
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
@@ -1109,7 +1106,6 @@ config CPU_MIPS64_R1
 config CPU_MIPS64_R2
 	bool "MIPS64 Release 2"
 	depends on SYS_HAS_CPU_MIPS64_R2
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
@@ -1155,7 +1151,6 @@ config CPU_VR41XX
 config CPU_R4300
 	bool "R4300"
 	depends on SYS_HAS_CPU_R4300
-	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	help
@@ -1164,7 +1159,6 @@ config CPU_R4300
 config CPU_R4X00
 	bool "R4x00"
 	depends on SYS_HAS_CPU_R4X00
-	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	help
@@ -1174,7 +1168,6 @@ config CPU_R4X00
 config CPU_TX49XX
 	bool "R49XX"
 	depends on SYS_HAS_CPU_TX49XX
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
@@ -1182,7 +1175,6 @@ config CPU_TX49XX
 config CPU_R5000
 	bool "R5000"
 	depends on SYS_HAS_CPU_R5000
-	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	help
@@ -1191,14 +1183,12 @@ config CPU_R5000
 config CPU_R5432
 	bool "R5432"
 	depends on SYS_HAS_CPU_R5432
-	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 
 config CPU_R5500
 	bool "R5500"
 	depends on SYS_HAS_CPU_R5500
-	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HUGEPAGES
@@ -1209,7 +1199,6 @@ config CPU_R5500
 config CPU_R6000
 	bool "R6000"
 	depends on EXPERIMENTAL
-	select CPU_HAS_LLSC
 	depends on SYS_HAS_CPU_R6000
 	select CPU_SUPPORTS_32BIT_KERNEL
 	help
@@ -1219,7 +1208,6 @@ config CPU_R6000
 config CPU_NEVADA
 	bool "RM52xx"
 	depends on SYS_HAS_CPU_NEVADA
-	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	help
@@ -1229,7 +1217,6 @@ config CPU_R8000
 	bool "R8000"
 	depends on EXPERIMENTAL
 	depends on SYS_HAS_CPU_R8000
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_64BIT_KERNEL
 	help
@@ -1239,7 +1226,6 @@ config CPU_R8000
 config CPU_R10000
 	bool "R10000"
 	depends on SYS_HAS_CPU_R10000
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
@@ -1250,7 +1236,6 @@ config CPU_R10000
 config CPU_RM7000
 	bool "RM7000"
 	depends on SYS_HAS_CPU_RM7000
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
@@ -1259,7 +1244,6 @@ config CPU_RM7000
 config CPU_RM9000
 	bool "RM9000"
 	depends on SYS_HAS_CPU_RM9000
-	select CPU_HAS_LLSC
 	select CPU_HAS_PREFETCH
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
@@ -1269,7 +1253,6 @@ config CPU_RM9000
 config CPU_SB1
 	bool "SB1"
 	depends on SYS_HAS_CPU_SB1
-	select CPU_HAS_LLSC
 	select CPU_SUPPORTS_32BIT_KERNEL
 	select CPU_SUPPORTS_64BIT_KERNEL
 	select CPU_SUPPORTS_HIGHMEM
@@ -1296,7 +1279,13 @@ config CPU_CAVIUM_OCTEON
 
 endchoice
 
-config SYS_HAS_CPU_LOONGSON2
+config CPU_LOONGSON2
+	bool
+	select CPU_SUPPORTS_32BIT_KERNEL
+	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HIGHMEM
+
+config SYS_HAS_CPU_LOONGSON2E
 	bool
 
 config SYS_HAS_CPU_MIPS32_R1
@@ -1683,9 +1672,6 @@ config SB1_PASS_2_1_WORKAROUNDS
 config 64BIT_PHYS_ADDR
 	bool
 
-config CPU_HAS_LLSC
-	bool
-
 config CPU_HAS_SMARTMIPS
 	depends on SYS_SUPPORTS_SMARTMIPS
 	bool "Support for the SmartMIPS ASE"
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 861da51..c825b14 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -120,7 +120,11 @@ cflags-$(CONFIG_CPU_R4300)	+= -march=r4300 -Wa,--trap
 cflags-$(CONFIG_CPU_VR41XX)	+= -march=r4100 -Wa,--trap
 cflags-$(CONFIG_CPU_R4X00)	+= -march=r4600 -Wa,--trap
 cflags-$(CONFIG_CPU_TX49XX)	+= -march=r4600 -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2)	+= -march=r4600 -Wa,--trap
+# only gcc >= 4.4 have the loongson-specific support
+cflags-$(CONFIG_CPU_LOONGSON2)	+= -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += \
+	$(call cc-option,-march=loongson2e,-march=r4600)
+
 cflags-$(CONFIG_CPU_MIPS32_R1)	+= $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
 			-Wa,-mips32 -Wa,--trap
 cflags-$(CONFIG_CPU_MIPS32_R2)	+= $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
@@ -314,11 +318,12 @@ cflags-$(CONFIG_WR_PPMC)		+= -I$(srctree)/arch/mips/include/asm/mach-wrppmc
 load-$(CONFIG_WR_PPMC)		+= 0xffffffff80100000
 
 #
-# lemote fulong mini-PC board
+# Loongson family
 #
-core-$(CONFIG_LEMOTE_FULONG) +=arch/mips/lemote/lm2e/
-load-$(CONFIG_LEMOTE_FULONG) +=0xffffffff80100000
-cflags-$(CONFIG_LEMOTE_FULONG) += -I$(srctree)/arch/mips/include/asm/mach-lemote
+core-$(CONFIG_MACH_LOONGSON) +=arch/mips/loongson/
+cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
+                    -mno-branch-likely
+load-$(CONFIG_LEMOTE_FULOONG2E) +=0xffffffff80100000
 
 #
 # MIPS Malta board
@@ -560,6 +565,13 @@ cflags-$(CONFIG_BCM47XX)	+= -I$(srctree)/arch/mips/include/asm/mach-bcm47xx
 load-$(CONFIG_BCM47XX)		:= 0xffffffff80001000
 
 #
+# Broadcom BCM63XX boards
+#
+core-$(CONFIG_BCM63XX)		+= arch/mips/bcm63xx/
+cflags-$(CONFIG_BCM63XX)	+= -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
+load-$(CONFIG_BCM63XX)		:= 0xffffffff80010000
+
+#
 # SNI RM
 #
 core-$(CONFIG_SNI_RM)		+= arch/mips/sni/
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
index 3f036b3..6184baa 100644
--- a/arch/mips/alchemy/common/setup.c
+++ b/arch/mips/alchemy/common/setup.c
@@ -27,6 +27,7 @@
 
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/pm.h>
 
@@ -53,6 +54,9 @@ void __init plat_mem_setup(void)
 	printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(),
 	       est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
 
+	/* this is faster than wasting cycles trying to approximate it */
+	preset_lpj = (est_freq >> 1) / HZ;
+
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
 	pm_power_off = au1000_power_off;
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
index 33fbae7..f34ff86 100644
--- a/arch/mips/alchemy/common/time.c
+++ b/arch/mips/alchemy/common/time.c
@@ -36,14 +36,13 @@
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
 
+#include <asm/processor.h>
 #include <asm/time.h>
 #include <asm/mach-au1x00/au1000.h>
 
 /* 32kHz clock enabled and detected */
 #define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
 
-extern int allow_au1k_wait; /* default off for CP0 Counter */
-
 static cycle_t au1x_counter1_read(struct clocksource *cs)
 {
 	return au_readl(SYS_RTCREAD);
@@ -153,13 +152,17 @@ void __init plat_time_init(void)
 
 	printk(KERN_INFO "Alchemy clocksource installed\n");
 
-	/* can now use 'wait' */
-	allow_au1k_wait = 1;
 	return;
 
 cntr_err:
-	/* counters unusable, use C0 counter */
+	/*
+	 * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this
+	 * function is called.  Because the Alchemy counters are unusable
+	 * the C0 timekeeping code is installed and use of the 'wait'
+	 * instruction must be prohibited, which is done most easily by
+	 * assigning NULL to cpu_wait.
+	 */
+	cpu_wait = NULL;
 	r4k_clockevent_init();
 	init_r4k_clocksource();
-	allow_au1k_wait = 0;
 }
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 2ecab61..e2278c0 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -32,6 +32,8 @@
 #include <linux/leds.h>
 #include <linux/string.h>
 #include <linux/etherdevice.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
 
 #include <asm/addrspace.h>
 #include <asm/mach-ar7/ar7.h>
@@ -208,6 +210,12 @@ static struct physmap_flash_data physmap_flash_data = {
 	.width = 2,
 };
 
+static struct fixed_phy_status fixed_phy_status __initdata = {
+	.link = 1,
+	.speed = 100,
+	.duplex = 1,
+};
+
 static struct plat_cpmac_data cpmac_low_data = {
 	.reset_bit = 17,
 	.power_bit = 20,
@@ -409,6 +417,20 @@ static struct platform_device ar7_udc = {
 	.num_resources = ARRAY_SIZE(usb_res),
 };
 
+static struct resource ar7_wdt_res = {
+	.name = "regs",
+	.start = -1, /* Filled at runtime */
+	.end = -1, /* Filled at runtime */
+	.flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ar7_wdt = {
+	.id = -1,
+	.name  = "ar7_wdt",
+	.resource = &ar7_wdt_res,
+	.num_resources = 1,
+};
+
 static inline unsigned char char2hex(char h)
 {
 	switch (h) {
@@ -479,6 +501,7 @@ static void __init detect_leds(void)
 
 static int __init ar7_register_devices(void)
 {
+	u16 chip_id;
 	int res;
 #ifdef CONFIG_SERIAL_8250
 	static struct uart_port uart_port[2];
@@ -530,6 +553,9 @@ static int __init ar7_register_devices(void)
 	}
 
 	if (ar7_has_high_cpmac()) {
+		res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
+		if (res && res != -ENODEV)
+			return res;
 		cpmac_get_mac(1, cpmac_high_data.dev_addr);
 		res = platform_device_register(&cpmac_high);
 		if (res)
@@ -538,6 +564,10 @@ static int __init ar7_register_devices(void)
 		cpmac_low_data.phy_mask = 0xffffffff;
 	}
 
+	res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
+	if (res && res != -ENODEV)
+		return res;
+
 	cpmac_get_mac(0, cpmac_low_data.dev_addr);
 	res = platform_device_register(&cpmac_low);
 	if (res)
@@ -550,6 +580,23 @@ static int __init ar7_register_devices(void)
 
 	res = platform_device_register(&ar7_udc);
 
+	chip_id = ar7_chip_id();
+	switch (chip_id) {
+	case AR7_CHIP_7100:
+	case AR7_CHIP_7200:
+		ar7_wdt_res.start = AR7_REGS_WDT;
+		break;
+	case AR7_CHIP_7300:
+		ar7_wdt_res.start = UR8_REGS_WDT;
+		break;
+	default:
+		break;
+	}
+
+	ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
+
+	res = platform_device_register(&ar7_wdt);
+
 	return res;
 }
 arch_initcall(ar7_register_devices);
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
new file mode 100644
index 0000000..fb177d6
--- /dev/null
+++ b/arch/mips/bcm63xx/Kconfig
@@ -0,0 +1,25 @@
+menu "CPU support"
+	depends on BCM63XX
+
+config BCM63XX_CPU_6338
+	bool "support 6338 CPU"
+	select HW_HAS_PCI
+	select USB_ARCH_HAS_OHCI
+	select USB_OHCI_BIG_ENDIAN_DESC
+	select USB_OHCI_BIG_ENDIAN_MMIO
+
+config BCM63XX_CPU_6345
+	bool "support 6345 CPU"
+	select USB_OHCI_BIG_ENDIAN_DESC
+	select USB_OHCI_BIG_ENDIAN_MMIO
+
+config BCM63XX_CPU_6348
+	bool "support 6348 CPU"
+	select HW_HAS_PCI
+
+config BCM63XX_CPU_6358
+	bool "support 6358 CPU"
+	select HW_HAS_PCI
+endmenu
+
+source "arch/mips/bcm63xx/boards/Kconfig"
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
new file mode 100644
index 0000000..aaa585c
--- /dev/null
+++ b/arch/mips/bcm63xx/Makefile
@@ -0,0 +1,7 @@
+obj-y		+= clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
+		   dev-dsp.o dev-enet.o
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+
+obj-y		+= boards/
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/bcm63xx/boards/Kconfig b/arch/mips/bcm63xx/boards/Kconfig
new file mode 100644
index 0000000..c6aed33
--- /dev/null
+++ b/arch/mips/bcm63xx/boards/Kconfig
@@ -0,0 +1,11 @@
+choice
+	prompt "Board support"
+	depends on BCM63XX
+	default BOARD_BCM963XX
+
+config BOARD_BCM963XX
+       bool "Generic Broadcom 963xx boards"
+	select SSB
+       help
+
+endchoice
diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile
new file mode 100644
index 0000000..e5cc86d
--- /dev/null
+++ b/arch/mips/bcm63xx/boards/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_BOARD_BCM963XX)		+= board_bcm963xx.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
new file mode 100644
index 0000000..fd77f54
--- /dev/null
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -0,0 +1,837 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/ssb/ssb.h>
+#include <asm/addrspace.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_dev_pci.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_dsp.h>
+#include <board_bcm963xx.h>
+
+#define PFX	"board_bcm963xx: "
+
+static struct bcm963xx_nvram nvram;
+static unsigned int mac_addr_used;
+static struct board_info board;
+
+/*
+ * known 6338 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6338
+static struct board_info __initdata board_96338gw = {
+	.name				= "96338GW",
+	.expected_cpu_id		= 0x6338,
+
+	.has_enet0			= 1,
+	.enet0 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+	.has_ohci0			= 1,
+
+	.leds = {
+		{
+			.name		= "adsl",
+			.gpio		= 3,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ses",
+			.gpio		= 5,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 4,
+			.active_low	= 1,
+		},
+		{
+			.name		= "power",
+			.gpio		= 0,
+			.active_low	= 1,
+			.default_trigger = "default-on",
+		},
+		{
+			.name		= "stop",
+			.gpio		= 1,
+			.active_low	= 1,
+		}
+	},
+};
+
+static struct board_info __initdata board_96338w = {
+	.name				= "96338W",
+	.expected_cpu_id		= 0x6338,
+
+	.has_enet0			= 1,
+	.enet0 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+	.leds = {
+		{
+			.name		= "adsl",
+			.gpio		= 3,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ses",
+			.gpio		= 5,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 4,
+			.active_low	= 1,
+		},
+		{
+			.name		= "power",
+			.gpio		= 0,
+			.active_low	= 1,
+			.default_trigger = "default-on",
+		},
+		{
+			.name		= "stop",
+			.gpio		= 1,
+			.active_low	= 1,
+		},
+	},
+};
+#endif
+
+/*
+ * known 6345 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6345
+static struct board_info __initdata board_96345gw2 = {
+	.name				= "96345GW2",
+	.expected_cpu_id		= 0x6345,
+};
+#endif
+
+/*
+ * known 6348 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6348
+static struct board_info __initdata board_96348r = {
+	.name				= "96348R",
+	.expected_cpu_id		= 0x6348,
+
+	.has_enet0			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+
+	.leds = {
+		{
+			.name		= "adsl-fail",
+			.gpio		= 2,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp",
+			.gpio		= 3,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 4,
+			.active_low	= 1,
+		},
+		{
+			.name		= "power",
+			.gpio		= 0,
+			.active_low	= 1,
+			.default_trigger = "default-on",
+
+		},
+		{
+			.name		= "stop",
+			.gpio		= 1,
+			.active_low	= 1,
+		},
+	},
+};
+
+static struct board_info __initdata board_96348gw_10 = {
+	.name				= "96348GW-10",
+	.expected_cpu_id		= 0x6348,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+	.has_ohci0			= 1,
+	.has_pccard			= 1,
+	.has_ehci0			= 1,
+
+	.has_dsp			= 1,
+	.dsp = {
+		.gpio_rst		= 6,
+		.gpio_int		= 34,
+		.cs			= 2,
+		.ext_irq		= 2,
+	},
+
+	.leds = {
+		{
+			.name		= "adsl-fail",
+			.gpio		= 2,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp",
+			.gpio		= 3,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 4,
+			.active_low	= 1,
+		},
+		{
+			.name		= "power",
+			.gpio		= 0,
+			.active_low	= 1,
+			.default_trigger = "default-on",
+		},
+		{
+			.name		= "stop",
+			.gpio		= 1,
+			.active_low	= 1,
+		},
+	},
+};
+
+static struct board_info __initdata board_96348gw_11 = {
+	.name				= "96348GW-11",
+	.expected_cpu_id		= 0x6348,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+
+	.has_ohci0 = 1,
+	.has_pccard = 1,
+	.has_ehci0 = 1,
+
+	.leds = {
+		{
+			.name		= "adsl-fail",
+			.gpio		= 2,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp",
+			.gpio		= 3,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 4,
+			.active_low	= 1,
+		},
+		{
+			.name		= "power",
+			.gpio		= 0,
+			.active_low	= 1,
+			.default_trigger = "default-on",
+		},
+		{
+			.name		= "stop",
+			.gpio		= 1,
+			.active_low	= 1,
+		},
+	},
+};
+
+static struct board_info __initdata board_96348gw = {
+	.name				= "96348GW",
+	.expected_cpu_id		= 0x6348,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+	.has_ohci0 = 1,
+
+	.has_dsp			= 1,
+	.dsp = {
+		.gpio_rst		= 6,
+		.gpio_int		= 34,
+		.ext_irq		= 2,
+		.cs			= 2,
+	},
+
+	.leds = {
+		{
+			.name		= "adsl-fail",
+			.gpio		= 2,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp",
+			.gpio		= 3,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 4,
+			.active_low	= 1,
+		},
+		{
+			.name		= "power",
+			.gpio		= 0,
+			.active_low	= 1,
+			.default_trigger = "default-on",
+		},
+		{
+			.name		= "stop",
+			.gpio		= 1,
+			.active_low	= 1,
+		},
+	},
+};
+
+static struct board_info __initdata board_FAST2404 = {
+        .name                           = "F@ST2404",
+        .expected_cpu_id                = 0x6348,
+
+        .has_enet0                      = 1,
+        .has_enet1                      = 1,
+        .has_pci                        = 1,
+
+        .enet0 = {
+                .has_phy                = 1,
+                .use_internal_phy       = 1,
+        },
+
+        .enet1 = {
+                .force_speed_100        = 1,
+                .force_duplex_full      = 1,
+        },
+
+
+        .has_ohci0 = 1,
+        .has_pccard = 1,
+        .has_ehci0 = 1,
+};
+
+static struct board_info __initdata board_DV201AMR = {
+	.name				= "DV201AMR",
+	.expected_cpu_id		= 0x6348,
+
+	.has_pci			= 1,
+	.has_ohci0			= 1,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+};
+
+static struct board_info __initdata board_96348gw_a = {
+	.name				= "96348GW-A",
+	.expected_cpu_id		= 0x6348,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+	.has_ohci0 = 1,
+};
+#endif
+
+/*
+ * known 6358 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6358
+static struct board_info __initdata board_96358vw = {
+	.name				= "96358VW",
+	.expected_cpu_id		= 0x6358,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+
+	.has_ohci0 = 1,
+	.has_pccard = 1,
+	.has_ehci0 = 1,
+
+	.leds = {
+		{
+			.name		= "adsl-fail",
+			.gpio		= 15,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp",
+			.gpio		= 22,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 23,
+			.active_low	= 1,
+		},
+		{
+			.name		= "power",
+			.gpio		= 4,
+			.default_trigger = "default-on",
+		},
+		{
+			.name		= "stop",
+			.gpio		= 5,
+		},
+	},
+};
+
+static struct board_info __initdata board_96358vw2 = {
+	.name				= "96358VW2",
+	.expected_cpu_id		= 0x6358,
+
+	.has_enet0			= 1,
+	.has_enet1			= 1,
+	.has_pci			= 1,
+
+	.enet0 = {
+		.has_phy		= 1,
+		.use_internal_phy	= 1,
+	},
+
+	.enet1 = {
+		.force_speed_100	= 1,
+		.force_duplex_full	= 1,
+	},
+
+
+	.has_ohci0 = 1,
+	.has_pccard = 1,
+	.has_ehci0 = 1,
+
+	.leds = {
+		{
+			.name		= "adsl",
+			.gpio		= 22,
+			.active_low	= 1,
+		},
+		{
+			.name		= "ppp-fail",
+			.gpio		= 23,
+		},
+		{
+			.name		= "power",
+			.gpio		= 5,
+			.active_low	= 1,
+			.default_trigger = "default-on",
+		},
+		{
+			.name		= "stop",
+			.gpio		= 4,
+			.active_low	= 1,
+		},
+	},
+};
+
+static struct board_info __initdata board_AGPFS0 = {
+	.name                           = "AGPF-S0",
+	.expected_cpu_id                = 0x6358,
+
+	.has_enet0                      = 1,
+	.has_enet1                      = 1,
+	.has_pci                        = 1,
+
+	.enet0 = {
+		.has_phy                = 1,
+		.use_internal_phy       = 1,
+	},
+
+	.enet1 = {
+		.force_speed_100        = 1,
+		.force_duplex_full      = 1,
+	},
+
+	.has_ohci0 = 1,
+	.has_ehci0 = 1,
+};
+#endif
+
+/*
+ * all boards
+ */
+static const struct board_info __initdata *bcm963xx_boards[] = {
+#ifdef CONFIG_BCM63XX_CPU_6338
+	&board_96338gw,
+	&board_96338w,
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6345
+	&board_96345gw2,
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+	&board_96348r,
+	&board_96348gw,
+	&board_96348gw_10,
+	&board_96348gw_11,
+	&board_FAST2404,
+	&board_DV201AMR,
+	&board_96348gw_a,
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6358
+	&board_96358vw,
+	&board_96358vw2,
+	&board_AGPFS0,
+#endif
+};
+
+/*
+ * early init callback, read nvram data from flash and checksum it
+ */
+void __init board_prom_init(void)
+{
+	unsigned int check_len, i;
+	u8 *boot_addr, *cfe, *p;
+	char cfe_version[32];
+	u32 val;
+
+	/* read base address of boot chip select (0)
+	 * 6345 does not have MPI but boots from standard
+	 * MIPS Flash address */
+	if (BCMCPU_IS_6345())
+		val = 0x1fc00000;
+	else {
+		val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+		val &= MPI_CSBASE_BASE_MASK;
+	}
+	boot_addr = (u8 *)KSEG1ADDR(val);
+
+	/* dump cfe version */
+	cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
+	if (!memcmp(cfe, "cfe-v", 5))
+		snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
+			 cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
+	else
+		strcpy(cfe_version, "unknown");
+	printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
+
+	/* extract nvram data */
+	memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
+
+	/* check checksum before using data */
+	if (nvram.version <= 4)
+		check_len = offsetof(struct bcm963xx_nvram, checksum_old);
+	else
+		check_len = sizeof(nvram);
+	val = 0;
+	p = (u8 *)&nvram;
+	while (check_len--)
+		val += *p;
+	if (val) {
+		printk(KERN_ERR PFX "invalid nvram checksum\n");
+		return;
+	}
+
+	/* find board by name */
+	for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
+		if (strncmp(nvram.name, bcm963xx_boards[i]->name,
+			    sizeof(nvram.name)))
+			continue;
+		/* copy, board desc array is marked initdata */
+		memcpy(&board, bcm963xx_boards[i], sizeof(board));
+		break;
+	}
+
+	/* bail out if board is not found, will complain later */
+	if (!board.name[0]) {
+		char name[17];
+		memcpy(name, nvram.name, 16);
+		name[16] = 0;
+		printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
+		       name);
+		return;
+	}
+
+	/* setup pin multiplexing depending on board enabled device,
+	 * this has to be done this early since PCI init is done
+	 * inside arch_initcall */
+	val = 0;
+
+#ifdef CONFIG_PCI
+	if (board.has_pci) {
+		bcm63xx_pci_enabled = 1;
+		if (BCMCPU_IS_6348())
+			val |= GPIO_MODE_6348_G2_PCI;
+	}
+#endif
+
+	if (board.has_pccard) {
+		if (BCMCPU_IS_6348())
+			val |= GPIO_MODE_6348_G1_MII_PCCARD;
+	}
+
+	if (board.has_enet0 && !board.enet0.use_internal_phy) {
+		if (BCMCPU_IS_6348())
+			val |= GPIO_MODE_6348_G3_EXT_MII |
+				GPIO_MODE_6348_G0_EXT_MII;
+	}
+
+	if (board.has_enet1 && !board.enet1.use_internal_phy) {
+		if (BCMCPU_IS_6348())
+			val |= GPIO_MODE_6348_G3_EXT_MII |
+				GPIO_MODE_6348_G0_EXT_MII;
+	}
+
+	bcm_gpio_writel(val, GPIO_MODE_REG);
+}
+
+/*
+ * second stage init callback, good time to panic if we couldn't
+ * identify on which board we're running since early printk is working
+ */
+void __init board_setup(void)
+{
+	if (!board.name[0])
+		panic("unable to detect bcm963xx board");
+	printk(KERN_INFO PFX "board name: %s\n", board.name);
+
+	/* make sure we're running on expected cpu */
+	if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
+		panic("unexpected CPU for bcm963xx board");
+}
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+	return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+	u8 *p;
+	int count;
+
+	if (mac_addr_used >= nvram.mac_addr_count) {
+		printk(KERN_ERR PFX "not enough mac address\n");
+		return -ENODEV;
+	}
+
+	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+	p = mac + ETH_ALEN - 1;
+	count = mac_addr_used;
+
+	while (count--) {
+		do {
+			(*p)++;
+			if (*p != 0)
+				break;
+			p--;
+		} while (p != mac);
+	}
+
+	if (p == mac) {
+		printk(KERN_ERR PFX "unable to fetch mac address\n");
+		return -ENODEV;
+	}
+
+	mac_addr_used++;
+	return 0;
+}
+
+static struct mtd_partition mtd_partitions[] = {
+	{
+		.name		= "cfe",
+		.offset		= 0x0,
+		.size		= 0x40000,
+	}
+};
+
+static struct physmap_flash_data flash_data = {
+	.width			= 2,
+	.nr_parts		= ARRAY_SIZE(mtd_partitions),
+	.parts			= mtd_partitions,
+};
+
+static struct resource mtd_resources[] = {
+	{
+		.start		= 0,	/* filled at runtime */
+		.end		= 0,	/* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device mtd_dev = {
+	.name			= "physmap-flash",
+	.resource		= mtd_resources,
+	.num_resources		= ARRAY_SIZE(mtd_resources),
+	.dev			= {
+		.platform_data	= &flash_data,
+	},
+};
+
+/*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+	.revision		= 0x02,
+	.board_rev		= 0x17,
+	.country_code		= 0x0,
+	.ant_available_bg 	= 0x3,
+	.pa0b0			= 0x15ae,
+	.pa0b1			= 0xfa85,
+	.pa0b2			= 0xfe8d,
+	.pa1b0			= 0xffff,
+	.pa1b1			= 0xffff,
+	.pa1b2			= 0xffff,
+	.gpio0			= 0xff,
+	.gpio1			= 0xff,
+	.gpio2			= 0xff,
+	.gpio3			= 0xff,
+	.maxpwr_bg		= 0x004c,
+	.itssi_bg		= 0x00,
+	.boardflags_lo		= 0x2848,
+	.boardflags_hi		= 0x0000,
+};
+#endif
+
+static struct gpio_led_platform_data bcm63xx_led_data;
+
+static struct platform_device bcm63xx_gpio_leds = {
+	.name			= "leds-gpio",
+	.id			= 0,
+	.dev.platform_data	= &bcm63xx_led_data,
+};
+
+/*
+ * third stage init callback, register all board devices.
+ */
+int __init board_register_devices(void)
+{
+	u32 val;
+
+	if (board.has_enet0 &&
+	    !board_get_mac_address(board.enet0.mac_addr))
+		bcm63xx_enet_register(0, &board.enet0);
+
+	if (board.has_enet1 &&
+	    !board_get_mac_address(board.enet1.mac_addr))
+		bcm63xx_enet_register(1, &board.enet1);
+
+	if (board.has_dsp)
+		bcm63xx_dsp_register(&board.dsp);
+
+	/* Generate MAC address for WLAN and
+	 * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+		if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+			printk(KERN_ERR "failed to register fallback SPROM\n");
+	}
+#endif
+
+	/* read base address of boot chip select (0) */
+	if (BCMCPU_IS_6345())
+		val = 0x1fc00000;
+	else {
+		val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+		val &= MPI_CSBASE_BASE_MASK;
+	}
+	mtd_resources[0].start = val;
+	mtd_resources[0].end = 0x1FFFFFFF;
+
+	platform_device_register(&mtd_dev);
+
+	bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
+	bcm63xx_led_data.leds = board.leds;
+
+	platform_device_register(&bcm63xx_gpio_leds);
+
+	return 0;
+}
+
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
new file mode 100644
index 0000000..2c68ee9
--- /dev/null
+++ b/arch/mips/bcm63xx/clk.c
@@ -0,0 +1,226 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_clk.h>
+
+static DEFINE_MUTEX(clocks_mutex);
+
+
+static void clk_enable_unlocked(struct clk *clk)
+{
+	if (clk->set && (clk->usage++) == 0)
+		clk->set(clk, 1);
+}
+
+static void clk_disable_unlocked(struct clk *clk)
+{
+	if (clk->set && (--clk->usage) == 0)
+		clk->set(clk, 0);
+}
+
+static void bcm_hwclock_set(u32 mask, int enable)
+{
+	u32 reg;
+
+	reg = bcm_perf_readl(PERF_CKCTL_REG);
+	if (enable)
+		reg |= mask;
+	else
+		reg &= ~mask;
+	bcm_perf_writel(reg, PERF_CKCTL_REG);
+}
+
+/*
+ * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
+ */
+static void enet_misc_set(struct clk *clk, int enable)
+{
+	u32 mask;
+
+	if (BCMCPU_IS_6338())
+		mask = CKCTL_6338_ENET_EN;
+	else if (BCMCPU_IS_6345())
+		mask = CKCTL_6345_ENET_EN;
+	else if (BCMCPU_IS_6348())
+		mask = CKCTL_6348_ENET_EN;
+	else
+		/* BCMCPU_IS_6358 */
+		mask = CKCTL_6358_EMUSB_EN;
+	bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_enet_misc = {
+	.set	= enet_misc_set,
+};
+
+/*
+ * Ethernet MAC clocks: only revelant on 6358, silently enable misc
+ * clocks
+ */
+static void enetx_set(struct clk *clk, int enable)
+{
+	if (enable)
+		clk_enable_unlocked(&clk_enet_misc);
+	else
+		clk_disable_unlocked(&clk_enet_misc);
+
+	if (BCMCPU_IS_6358()) {
+		u32 mask;
+
+		if (clk->id == 0)
+			mask = CKCTL_6358_ENET0_EN;
+		else
+			mask = CKCTL_6358_ENET1_EN;
+		bcm_hwclock_set(mask, enable);
+	}
+}
+
+static struct clk clk_enet0 = {
+	.id	= 0,
+	.set	= enetx_set,
+};
+
+static struct clk clk_enet1 = {
+	.id	= 1,
+	.set	= enetx_set,
+};
+
+/*
+ * Ethernet PHY clock
+ */
+static void ephy_set(struct clk *clk, int enable)
+{
+	if (!BCMCPU_IS_6358())
+		return;
+	bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
+}
+
+
+static struct clk clk_ephy = {
+	.set	= ephy_set,
+};
+
+/*
+ * PCM clock
+ */
+static void pcm_set(struct clk *clk, int enable)
+{
+	if (!BCMCPU_IS_6358())
+		return;
+	bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
+}
+
+static struct clk clk_pcm = {
+	.set	= pcm_set,
+};
+
+/*
+ * USB host clock
+ */
+static void usbh_set(struct clk *clk, int enable)
+{
+	if (!BCMCPU_IS_6348())
+		return;
+	bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
+}
+
+static struct clk clk_usbh = {
+	.set	= usbh_set,
+};
+
+/*
+ * SPI clock
+ */
+static void spi_set(struct clk *clk, int enable)
+{
+	u32 mask;
+
+	if (BCMCPU_IS_6338())
+		mask = CKCTL_6338_SPI_EN;
+	else if (BCMCPU_IS_6348())
+		mask = CKCTL_6348_SPI_EN;
+	else
+		/* BCMCPU_IS_6358 */
+		mask = CKCTL_6358_SPI_EN;
+	bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_spi = {
+	.set	= spi_set,
+};
+
+/*
+ * Internal peripheral clock
+ */
+static struct clk clk_periph = {
+	.rate	= (50 * 1000 * 1000),
+};
+
+
+/*
+ * Linux clock API implementation
+ */
+int clk_enable(struct clk *clk)
+{
+	mutex_lock(&clocks_mutex);
+	clk_enable_unlocked(clk);
+	mutex_unlock(&clocks_mutex);
+	return 0;
+}
+
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	mutex_lock(&clocks_mutex);
+	clk_disable_unlocked(clk);
+	mutex_unlock(&clocks_mutex);
+}
+
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	if (!strcmp(id, "enet0"))
+		return &clk_enet0;
+	if (!strcmp(id, "enet1"))
+		return &clk_enet1;
+	if (!strcmp(id, "ephy"))
+		return &clk_ephy;
+	if (!strcmp(id, "usbh"))
+		return &clk_usbh;
+	if (!strcmp(id, "spi"))
+		return &clk_spi;
+	if (!strcmp(id, "periph"))
+		return &clk_periph;
+	if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
+		return &clk_pcm;
+	return ERR_PTR(-ENOENT);
+}
+
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+
+EXPORT_SYMBOL(clk_put);
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
new file mode 100644
index 0000000..6dc43f0
--- /dev/null
+++ b/arch/mips/bcm63xx/cpu.c
@@ -0,0 +1,345 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/cpu.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_irq.h>
+
+const unsigned long *bcm63xx_regs_base;
+EXPORT_SYMBOL(bcm63xx_regs_base);
+
+const int *bcm63xx_irqs;
+EXPORT_SYMBOL(bcm63xx_irqs);
+
+static u16 bcm63xx_cpu_id;
+static u16 bcm63xx_cpu_rev;
+static unsigned int bcm63xx_cpu_freq;
+static unsigned int bcm63xx_memory_size;
+
+/*
+ * 6338 register sets and irqs
+ */
+static const unsigned long bcm96338_regs_base[] = {
+	[RSET_DSL_LMEM]		= BCM_6338_DSL_LMEM_BASE,
+	[RSET_PERF]		= BCM_6338_PERF_BASE,
+	[RSET_TIMER]		= BCM_6338_TIMER_BASE,
+	[RSET_WDT]		= BCM_6338_WDT_BASE,
+	[RSET_UART0]		= BCM_6338_UART0_BASE,
+	[RSET_GPIO]		= BCM_6338_GPIO_BASE,
+	[RSET_SPI]		= BCM_6338_SPI_BASE,
+	[RSET_OHCI0]		= BCM_6338_OHCI0_BASE,
+	[RSET_OHCI_PRIV]	= BCM_6338_OHCI_PRIV_BASE,
+	[RSET_USBH_PRIV]	= BCM_6338_USBH_PRIV_BASE,
+	[RSET_UDC0]		= BCM_6338_UDC0_BASE,
+	[RSET_MPI]		= BCM_6338_MPI_BASE,
+	[RSET_PCMCIA]		= BCM_6338_PCMCIA_BASE,
+	[RSET_SDRAM]		= BCM_6338_SDRAM_BASE,
+	[RSET_DSL]		= BCM_6338_DSL_BASE,
+	[RSET_ENET0]		= BCM_6338_ENET0_BASE,
+	[RSET_ENET1]		= BCM_6338_ENET1_BASE,
+	[RSET_ENETDMA]		= BCM_6338_ENETDMA_BASE,
+	[RSET_MEMC]		= BCM_6338_MEMC_BASE,
+	[RSET_DDR]		= BCM_6338_DDR_BASE,
+};
+
+static const int bcm96338_irqs[] = {
+	[IRQ_TIMER]		= BCM_6338_TIMER_IRQ,
+	[IRQ_UART0]		= BCM_6338_UART0_IRQ,
+	[IRQ_DSL]		= BCM_6338_DSL_IRQ,
+	[IRQ_ENET0]		= BCM_6338_ENET0_IRQ,
+	[IRQ_ENET_PHY]		= BCM_6338_ENET_PHY_IRQ,
+	[IRQ_ENET0_RXDMA]	= BCM_6338_ENET0_RXDMA_IRQ,
+	[IRQ_ENET0_TXDMA]	= BCM_6338_ENET0_TXDMA_IRQ,
+};
+
+/*
+ * 6345 register sets and irqs
+ */
+static const unsigned long bcm96345_regs_base[] = {
+	[RSET_DSL_LMEM]		= BCM_6345_DSL_LMEM_BASE,
+	[RSET_PERF]		= BCM_6345_PERF_BASE,
+	[RSET_TIMER]		= BCM_6345_TIMER_BASE,
+	[RSET_WDT]		= BCM_6345_WDT_BASE,
+	[RSET_UART0]		= BCM_6345_UART0_BASE,
+	[RSET_GPIO]		= BCM_6345_GPIO_BASE,
+	[RSET_SPI]		= BCM_6345_SPI_BASE,
+	[RSET_UDC0]		= BCM_6345_UDC0_BASE,
+	[RSET_OHCI0]		= BCM_6345_OHCI0_BASE,
+	[RSET_OHCI_PRIV]	= BCM_6345_OHCI_PRIV_BASE,
+	[RSET_USBH_PRIV]	= BCM_6345_USBH_PRIV_BASE,
+	[RSET_MPI]		= BCM_6345_MPI_BASE,
+	[RSET_PCMCIA]		= BCM_6345_PCMCIA_BASE,
+	[RSET_DSL]		= BCM_6345_DSL_BASE,
+	[RSET_ENET0]		= BCM_6345_ENET0_BASE,
+	[RSET_ENET1]		= BCM_6345_ENET1_BASE,
+	[RSET_ENETDMA]		= BCM_6345_ENETDMA_BASE,
+	[RSET_EHCI0]		= BCM_6345_EHCI0_BASE,
+	[RSET_SDRAM]		= BCM_6345_SDRAM_BASE,
+	[RSET_MEMC]		= BCM_6345_MEMC_BASE,
+	[RSET_DDR]		= BCM_6345_DDR_BASE,
+};
+
+static const int bcm96345_irqs[] = {
+	[IRQ_TIMER]		= BCM_6345_TIMER_IRQ,
+	[IRQ_UART0]		= BCM_6345_UART0_IRQ,
+	[IRQ_DSL]		= BCM_6345_DSL_IRQ,
+	[IRQ_ENET0]		= BCM_6345_ENET0_IRQ,
+	[IRQ_ENET_PHY]		= BCM_6345_ENET_PHY_IRQ,
+	[IRQ_ENET0_RXDMA]	= BCM_6345_ENET0_RXDMA_IRQ,
+	[IRQ_ENET0_TXDMA]	= BCM_6345_ENET0_TXDMA_IRQ,
+};
+
+/*
+ * 6348 register sets and irqs
+ */
+static const unsigned long bcm96348_regs_base[] = {
+	[RSET_DSL_LMEM]		= BCM_6348_DSL_LMEM_BASE,
+	[RSET_PERF]		= BCM_6348_PERF_BASE,
+	[RSET_TIMER]		= BCM_6348_TIMER_BASE,
+	[RSET_WDT]		= BCM_6348_WDT_BASE,
+	[RSET_UART0]		= BCM_6348_UART0_BASE,
+	[RSET_GPIO]		= BCM_6348_GPIO_BASE,
+	[RSET_SPI]		= BCM_6348_SPI_BASE,
+	[RSET_OHCI0]		= BCM_6348_OHCI0_BASE,
+	[RSET_OHCI_PRIV]	= BCM_6348_OHCI_PRIV_BASE,
+	[RSET_USBH_PRIV]	= BCM_6348_USBH_PRIV_BASE,
+	[RSET_MPI]		= BCM_6348_MPI_BASE,
+	[RSET_PCMCIA]		= BCM_6348_PCMCIA_BASE,
+	[RSET_SDRAM]		= BCM_6348_SDRAM_BASE,
+	[RSET_DSL]		= BCM_6348_DSL_BASE,
+	[RSET_ENET0]		= BCM_6348_ENET0_BASE,
+	[RSET_ENET1]		= BCM_6348_ENET1_BASE,
+	[RSET_ENETDMA]		= BCM_6348_ENETDMA_BASE,
+	[RSET_MEMC]		= BCM_6348_MEMC_BASE,
+	[RSET_DDR]		= BCM_6348_DDR_BASE,
+};
+
+static const int bcm96348_irqs[] = {
+	[IRQ_TIMER]		= BCM_6348_TIMER_IRQ,
+	[IRQ_UART0]		= BCM_6348_UART0_IRQ,
+	[IRQ_DSL]		= BCM_6348_DSL_IRQ,
+	[IRQ_ENET0]		= BCM_6348_ENET0_IRQ,
+	[IRQ_ENET1]		= BCM_6348_ENET1_IRQ,
+	[IRQ_ENET_PHY]		= BCM_6348_ENET_PHY_IRQ,
+	[IRQ_OHCI0]		= BCM_6348_OHCI0_IRQ,
+	[IRQ_PCMCIA]		= BCM_6348_PCMCIA_IRQ,
+	[IRQ_ENET0_RXDMA]	= BCM_6348_ENET0_RXDMA_IRQ,
+	[IRQ_ENET0_TXDMA]	= BCM_6348_ENET0_TXDMA_IRQ,
+	[IRQ_ENET1_RXDMA]	= BCM_6348_ENET1_RXDMA_IRQ,
+	[IRQ_ENET1_TXDMA]	= BCM_6348_ENET1_TXDMA_IRQ,
+	[IRQ_PCI]		= BCM_6348_PCI_IRQ,
+};
+
+/*
+ * 6358 register sets and irqs
+ */
+static const unsigned long bcm96358_regs_base[] = {
+	[RSET_DSL_LMEM]		= BCM_6358_DSL_LMEM_BASE,
+	[RSET_PERF]		= BCM_6358_PERF_BASE,
+	[RSET_TIMER]		= BCM_6358_TIMER_BASE,
+	[RSET_WDT]		= BCM_6358_WDT_BASE,
+	[RSET_UART0]		= BCM_6358_UART0_BASE,
+	[RSET_GPIO]		= BCM_6358_GPIO_BASE,
+	[RSET_SPI]		= BCM_6358_SPI_BASE,
+	[RSET_OHCI0]		= BCM_6358_OHCI0_BASE,
+	[RSET_EHCI0]		= BCM_6358_EHCI0_BASE,
+	[RSET_OHCI_PRIV]	= BCM_6358_OHCI_PRIV_BASE,
+	[RSET_USBH_PRIV]	= BCM_6358_USBH_PRIV_BASE,
+	[RSET_MPI]		= BCM_6358_MPI_BASE,
+	[RSET_PCMCIA]		= BCM_6358_PCMCIA_BASE,
+	[RSET_SDRAM]		= BCM_6358_SDRAM_BASE,
+	[RSET_DSL]		= BCM_6358_DSL_BASE,
+	[RSET_ENET0]		= BCM_6358_ENET0_BASE,
+	[RSET_ENET1]		= BCM_6358_ENET1_BASE,
+	[RSET_ENETDMA]		= BCM_6358_ENETDMA_BASE,
+	[RSET_MEMC]		= BCM_6358_MEMC_BASE,
+	[RSET_DDR]		= BCM_6358_DDR_BASE,
+};
+
+static const int bcm96358_irqs[] = {
+	[IRQ_TIMER]		= BCM_6358_TIMER_IRQ,
+	[IRQ_UART0]		= BCM_6358_UART0_IRQ,
+	[IRQ_DSL]		= BCM_6358_DSL_IRQ,
+	[IRQ_ENET0]		= BCM_6358_ENET0_IRQ,
+	[IRQ_ENET1]		= BCM_6358_ENET1_IRQ,
+	[IRQ_ENET_PHY]		= BCM_6358_ENET_PHY_IRQ,
+	[IRQ_OHCI0]		= BCM_6358_OHCI0_IRQ,
+	[IRQ_EHCI0]		= BCM_6358_EHCI0_IRQ,
+	[IRQ_PCMCIA]		= BCM_6358_PCMCIA_IRQ,
+	[IRQ_ENET0_RXDMA]	= BCM_6358_ENET0_RXDMA_IRQ,
+	[IRQ_ENET0_TXDMA]	= BCM_6358_ENET0_TXDMA_IRQ,
+	[IRQ_ENET1_RXDMA]	= BCM_6358_ENET1_RXDMA_IRQ,
+	[IRQ_ENET1_TXDMA]	= BCM_6358_ENET1_TXDMA_IRQ,
+	[IRQ_PCI]		= BCM_6358_PCI_IRQ,
+};
+
+u16 __bcm63xx_get_cpu_id(void)
+{
+	return bcm63xx_cpu_id;
+}
+
+EXPORT_SYMBOL(__bcm63xx_get_cpu_id);
+
+u16 bcm63xx_get_cpu_rev(void)
+{
+	return bcm63xx_cpu_rev;
+}
+
+EXPORT_SYMBOL(bcm63xx_get_cpu_rev);
+
+unsigned int bcm63xx_get_cpu_freq(void)
+{
+	return bcm63xx_cpu_freq;
+}
+
+unsigned int bcm63xx_get_memory_size(void)
+{
+	return bcm63xx_memory_size;
+}
+
+static unsigned int detect_cpu_clock(void)
+{
+	unsigned int tmp, n1 = 0, n2 = 0, m1 = 0;
+
+	/* BCM6338 has a fixed 240 Mhz frequency */
+	if (BCMCPU_IS_6338())
+		return 240000000;
+
+	/* BCM6345 has a fixed 140Mhz frequency */
+	if (BCMCPU_IS_6345())
+		return 140000000;
+
+	/*
+	 * frequency depends on PLL configuration:
+	 */
+	if (BCMCPU_IS_6348()) {
+		/* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
+		tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
+		n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
+		n2 = (tmp & MIPSPLLCTL_N2_MASK) >> MIPSPLLCTL_N2_SHIFT;
+		m1 = (tmp & MIPSPLLCTL_M1CPU_MASK) >> MIPSPLLCTL_M1CPU_SHIFT;
+		n1 += 1;
+		n2 += 2;
+		m1 += 1;
+	}
+
+	if (BCMCPU_IS_6358()) {
+		/* 16MHz * N1 * N2 / M1_CPU */
+		tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
+		n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
+		n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
+		m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
+	}
+
+	return (16 * 1000000 * n1 * n2) / m1;
+}
+
+/*
+ * attempt to detect the amount of memory installed
+ */
+static unsigned int detect_memory_size(void)
+{
+	unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
+	u32 val;
+
+	if (BCMCPU_IS_6345())
+		return (8 * 1024 * 1024);
+
+	if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
+		val = bcm_sdram_readl(SDRAM_CFG_REG);
+		rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
+		cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
+		is_32bits = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
+		banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
+	}
+
+	if (BCMCPU_IS_6358()) {
+		val = bcm_memc_readl(MEMC_CFG_REG);
+		rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
+		cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
+		is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
+		banks = 2;
+	}
+
+	/* 0 => 11 address bits ... 2 => 13 address bits */
+	rows += 11;
+
+	/* 0 => 8 address bits ... 2 => 10 address bits */
+	cols += 8;
+
+	return 1 << (cols + rows + (is_32bits + 1) + banks);
+}
+
+void __init bcm63xx_cpu_init(void)
+{
+	unsigned int tmp, expected_cpu_id;
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	/* soc registers location depends on cpu type */
+	expected_cpu_id = 0;
+
+	switch (c->cputype) {
+	/*
+	 * BCM6338 as the same PrId as BCM3302 see arch/mips/kernel/cpu-probe.c
+	 */
+	case CPU_BCM3302:
+		expected_cpu_id = BCM6338_CPU_ID;
+		bcm63xx_regs_base = bcm96338_regs_base;
+		bcm63xx_irqs = bcm96338_irqs;
+		break;
+	case CPU_BCM6345:
+		expected_cpu_id = BCM6345_CPU_ID;
+		bcm63xx_regs_base = bcm96345_regs_base;
+		bcm63xx_irqs = bcm96345_irqs;
+		break;
+	case CPU_BCM6348:
+		expected_cpu_id = BCM6348_CPU_ID;
+		bcm63xx_regs_base = bcm96348_regs_base;
+		bcm63xx_irqs = bcm96348_irqs;
+		break;
+	case CPU_BCM6358:
+		expected_cpu_id = BCM6358_CPU_ID;
+		bcm63xx_regs_base = bcm96358_regs_base;
+		bcm63xx_irqs = bcm96358_irqs;
+		break;
+	}
+
+	/*
+	 * really early to panic, but delaying panic would not help since we
+	 * will never get any working console
+	 */
+	if (!expected_cpu_id)
+		panic("unsupported Broadcom CPU");
+
+	/*
+	 * bcm63xx_regs_base is set, we can access soc registers
+	 */
+
+	/* double check CPU type */
+	tmp = bcm_perf_readl(PERF_REV_REG);
+	bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
+	bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
+
+	if (bcm63xx_cpu_id != expected_cpu_id)
+		panic("bcm63xx CPU id mismatch");
+
+	bcm63xx_cpu_freq = detect_cpu_clock();
+	bcm63xx_memory_size = detect_memory_size();
+
+	printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n",
+	       bcm63xx_cpu_id, bcm63xx_cpu_rev);
+	printk(KERN_INFO "CPU frequency is %u MHz\n",
+	       bcm63xx_cpu_freq / 1000000);
+	printk(KERN_INFO "%uMB of RAM installed\n",
+	       bcm63xx_memory_size >> 20);
+}
diff --git a/arch/mips/bcm63xx/cs.c b/arch/mips/bcm63xx/cs.c
new file mode 100644
index 0000000..50d8190
--- /dev/null
+++ b/arch/mips/bcm63xx/cs.c
@@ -0,0 +1,144 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/log2.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_cs.h>
+
+static DEFINE_SPINLOCK(bcm63xx_cs_lock);
+
+/*
+ * check if given chip select exists
+ */
+static int is_valid_cs(unsigned int cs)
+{
+	if (cs > 6)
+		return 0;
+	return 1;
+}
+
+/*
+ * Configure chipselect base address and size (bytes).
+ * Size must be a power of two between 8k and 256M.
+ */
+int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size)
+{
+	unsigned long flags;
+	u32 val;
+
+	if (!is_valid_cs(cs))
+		return -EINVAL;
+
+	/* sanity check on size */
+	if (size != roundup_pow_of_two(size))
+		return -EINVAL;
+
+	if (size < 8 * 1024 || size > 256 * 1024 * 1024)
+		return -EINVAL;
+
+	val = (base & MPI_CSBASE_BASE_MASK);
+	/* 8k => 0 - 256M => 15 */
+	val |= (ilog2(size) - ilog2(8 * 1024)) << MPI_CSBASE_SIZE_SHIFT;
+
+	spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+	bcm_mpi_writel(val, MPI_CSBASE_REG(cs));
+	spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_base);
+
+/*
+ * configure chipselect timing (ns)
+ */
+int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait,
+			   unsigned int setup, unsigned int hold)
+{
+	unsigned long flags;
+	u32 val;
+
+	if (!is_valid_cs(cs))
+		return -EINVAL;
+
+	spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+	val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+	val &= ~(MPI_CSCTL_WAIT_MASK);
+	val &= ~(MPI_CSCTL_SETUP_MASK);
+	val &= ~(MPI_CSCTL_HOLD_MASK);
+	val |= wait << MPI_CSCTL_WAIT_SHIFT;
+	val |= setup << MPI_CSCTL_SETUP_SHIFT;
+	val |= hold << MPI_CSCTL_HOLD_SHIFT;
+	bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+	spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_timing);
+
+/*
+ * configure other chipselect parameter (data bus size, ...)
+ */
+int bcm63xx_set_cs_param(unsigned int cs, u32 params)
+{
+	unsigned long flags;
+	u32 val;
+
+	if (!is_valid_cs(cs))
+		return -EINVAL;
+
+	/* none of this fields apply to pcmcia */
+	if (cs == MPI_CS_PCMCIA_COMMON ||
+	    cs == MPI_CS_PCMCIA_ATTR ||
+	    cs == MPI_CS_PCMCIA_IO)
+		return -EINVAL;
+
+	spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+	val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+	val &= ~(MPI_CSCTL_DATA16_MASK);
+	val &= ~(MPI_CSCTL_SYNCMODE_MASK);
+	val &= ~(MPI_CSCTL_TSIZE_MASK);
+	val &= ~(MPI_CSCTL_ENDIANSWAP_MASK);
+	val |= params;
+	bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+	spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+
+	return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_param);
+
+/*
+ * set cs status (enable/disable)
+ */
+int bcm63xx_set_cs_status(unsigned int cs, int enable)
+{
+	unsigned long flags;
+	u32 val;
+
+	if (!is_valid_cs(cs))
+		return -EINVAL;
+
+	spin_lock_irqsave(&bcm63xx_cs_lock, flags);
+	val = bcm_mpi_readl(MPI_CSCTL_REG(cs));
+	if (enable)
+		val |= MPI_CSCTL_ENABLE_MASK;
+	else
+		val &= ~MPI_CSCTL_ENABLE_MASK;
+	bcm_mpi_writel(val, MPI_CSCTL_REG(cs));
+	spin_unlock_irqrestore(&bcm63xx_cs_lock, flags);
+	return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_set_cs_status);
diff --git a/arch/mips/bcm63xx/dev-dsp.c b/arch/mips/bcm63xx/dev-dsp.c
new file mode 100644
index 0000000..da46d1d
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-dsp.c
@@ -0,0 +1,56 @@
+/*
+ * Broadcom BCM63xx VoIP DSP registration
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_dsp.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct resource voip_dsp_resources[] = {
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device bcm63xx_voip_dsp_device = {
+	.name		= "bcm63xx-voip-dsp",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(voip_dsp_resources),
+	.resource	= voip_dsp_resources,
+};
+
+int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd)
+{
+	struct bcm63xx_dsp_platform_data *dpd;
+	u32 val;
+
+	/* Get the memory window */
+	val = bcm_mpi_readl(MPI_CSBASE_REG(pd->cs - 1));
+	val &= MPI_CSBASE_BASE_MASK;
+	voip_dsp_resources[0].start = val;
+	voip_dsp_resources[0].end = val + 0xFFFFFFF;
+	voip_dsp_resources[1].start = pd->ext_irq;
+
+	/* copy given platform data */
+	dpd = bcm63xx_voip_dsp_device.dev.platform_data;
+	memcpy(dpd, pd, sizeof (*pd));
+
+	return platform_device_register(&bcm63xx_voip_dsp_device);
+}
diff --git a/arch/mips/bcm63xx/dev-enet.c b/arch/mips/bcm63xx/dev-enet.c
new file mode 100644
index 0000000..9f544ba
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-enet.c
@@ -0,0 +1,159 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static struct resource shared_res[] = {
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device bcm63xx_enet_shared_device = {
+	.name		= "bcm63xx_enet_shared",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(shared_res),
+	.resource	= shared_res,
+};
+
+static int shared_device_registered;
+
+static struct resource enet0_res[] = {
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct bcm63xx_enet_platform_data enet0_pd;
+
+static struct platform_device bcm63xx_enet0_device = {
+	.name		= "bcm63xx_enet",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(enet0_res),
+	.resource	= enet0_res,
+	.dev		= {
+		.platform_data = &enet0_pd,
+	},
+};
+
+static struct resource enet1_res[] = {
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+	{
+		.start		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct bcm63xx_enet_platform_data enet1_pd;
+
+static struct platform_device bcm63xx_enet1_device = {
+	.name		= "bcm63xx_enet",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(enet1_res),
+	.resource	= enet1_res,
+	.dev		= {
+		.platform_data = &enet1_pd,
+	},
+};
+
+int __init bcm63xx_enet_register(int unit,
+				 const struct bcm63xx_enet_platform_data *pd)
+{
+	struct platform_device *pdev;
+	struct bcm63xx_enet_platform_data *dpd;
+	int ret;
+
+	if (unit > 1)
+		return -ENODEV;
+
+	if (!shared_device_registered) {
+		shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA);
+		shared_res[0].end = shared_res[0].start;
+		if (BCMCPU_IS_6338())
+			shared_res[0].end += (RSET_ENETDMA_SIZE / 2)  - 1;
+		else
+			shared_res[0].end += (RSET_ENETDMA_SIZE)  - 1;
+
+		ret = platform_device_register(&bcm63xx_enet_shared_device);
+		if (ret)
+			return ret;
+		shared_device_registered = 1;
+	}
+
+	if (unit == 0) {
+		enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0);
+		enet0_res[0].end = enet0_res[0].start;
+		enet0_res[0].end += RSET_ENET_SIZE - 1;
+		enet0_res[1].start = bcm63xx_get_irq_number(IRQ_ENET0);
+		enet0_res[2].start = bcm63xx_get_irq_number(IRQ_ENET0_RXDMA);
+		enet0_res[3].start = bcm63xx_get_irq_number(IRQ_ENET0_TXDMA);
+		pdev = &bcm63xx_enet0_device;
+	} else {
+		enet1_res[0].start = bcm63xx_regset_address(RSET_ENET1);
+		enet1_res[0].end = enet1_res[0].start;
+		enet1_res[0].end += RSET_ENET_SIZE - 1;
+		enet1_res[1].start = bcm63xx_get_irq_number(IRQ_ENET1);
+		enet1_res[2].start = bcm63xx_get_irq_number(IRQ_ENET1_RXDMA);
+		enet1_res[3].start = bcm63xx_get_irq_number(IRQ_ENET1_TXDMA);
+		pdev = &bcm63xx_enet1_device;
+	}
+
+	/* copy given platform data */
+	dpd = pdev->dev.platform_data;
+	memcpy(dpd, pd, sizeof(*pd));
+
+	/* adjust them in case internal phy is used */
+	if (dpd->use_internal_phy) {
+
+		/* internal phy only exists for enet0 */
+		if (unit == 1)
+			return -ENODEV;
+
+		dpd->phy_id = 1;
+		dpd->has_phy_interrupt = 1;
+		dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
+	}
+
+	ret = platform_device_register(pdev);
+	if (ret)
+		return ret;
+	return 0;
+}
diff --git a/arch/mips/bcm63xx/early_printk.c b/arch/mips/bcm63xx/early_printk.c
new file mode 100644
index 0000000..bf353c9
--- /dev/null
+++ b/arch/mips/bcm63xx/early_printk.c
@@ -0,0 +1,30 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static void __init wait_xfered(void)
+{
+	unsigned int val;
+
+	/* wait for any previous char to be transmitted */
+	do {
+		val = bcm_uart0_readl(UART_IR_REG);
+		if (val & UART_IR_STAT(UART_IR_TXEMPTY))
+			break;
+	} while (1);
+}
+
+void __init prom_putchar(char c)
+{
+	wait_xfered();
+	bcm_uart0_writel(c, UART_FIFO_REG);
+	wait_xfered();
+}
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
new file mode 100644
index 0000000..87ca390
--- /dev/null
+++ b/arch/mips/bcm63xx/gpio.c
@@ -0,0 +1,134 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_gpio.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+static DEFINE_SPINLOCK(bcm63xx_gpio_lock);
+static u32 gpio_out_low, gpio_out_high;
+
+static void bcm63xx_gpio_set(struct gpio_chip *chip,
+			     unsigned gpio, int val)
+{
+	u32 reg;
+	u32 mask;
+	u32 *v;
+	unsigned long flags;
+
+	if (gpio >= chip->ngpio)
+		BUG();
+
+	if (gpio < 32) {
+		reg = GPIO_DATA_LO_REG;
+		mask = 1 << gpio;
+		v = &gpio_out_low;
+	} else {
+		reg = GPIO_DATA_HI_REG;
+		mask = 1 << (gpio - 32);
+		v = &gpio_out_high;
+	}
+
+	spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
+	if (val)
+		*v |= mask;
+	else
+		*v &= ~mask;
+	bcm_gpio_writel(*v, reg);
+	spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
+}
+
+static int bcm63xx_gpio_get(struct gpio_chip *chip, unsigned gpio)
+{
+	u32 reg;
+	u32 mask;
+
+	if (gpio >= chip->ngpio)
+		BUG();
+
+	if (gpio < 32) {
+		reg = GPIO_DATA_LO_REG;
+		mask = 1 << gpio;
+	} else {
+		reg = GPIO_DATA_HI_REG;
+		mask = 1 << (gpio - 32);
+	}
+
+	return !!(bcm_gpio_readl(reg) & mask);
+}
+
+static int bcm63xx_gpio_set_direction(struct gpio_chip *chip,
+				      unsigned gpio, int dir)
+{
+	u32 reg;
+	u32 mask;
+	u32 tmp;
+	unsigned long flags;
+
+	if (gpio >= chip->ngpio)
+		BUG();
+
+	if (gpio < 32) {
+		reg = GPIO_CTL_LO_REG;
+		mask = 1 << gpio;
+	} else {
+		reg = GPIO_CTL_HI_REG;
+		mask = 1 << (gpio - 32);
+	}
+
+	spin_lock_irqsave(&bcm63xx_gpio_lock, flags);
+	tmp = bcm_gpio_readl(reg);
+	if (dir == GPIO_DIR_IN)
+		tmp &= ~mask;
+	else
+		tmp |= mask;
+	bcm_gpio_writel(tmp, reg);
+	spin_unlock_irqrestore(&bcm63xx_gpio_lock, flags);
+
+	return 0;
+}
+
+static int bcm63xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_IN);
+}
+
+static int bcm63xx_gpio_direction_output(struct gpio_chip *chip,
+					 unsigned gpio, int value)
+{
+	bcm63xx_gpio_set(chip, gpio, value);
+	return bcm63xx_gpio_set_direction(chip, gpio, GPIO_DIR_OUT);
+}
+
+
+static struct gpio_chip bcm63xx_gpio_chip = {
+	.label			= "bcm63xx-gpio",
+	.direction_input	= bcm63xx_gpio_direction_input,
+	.direction_output	= bcm63xx_gpio_direction_output,
+	.get			= bcm63xx_gpio_get,
+	.set			= bcm63xx_gpio_set,
+	.base			= 0,
+};
+
+int __init bcm63xx_gpio_init(void)
+{
+	bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
+	pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
+
+	return gpiochip_add(&bcm63xx_gpio_chip);
+}
+
+arch_initcall(bcm63xx_gpio_init);
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
new file mode 100644
index 0000000..a0c5cd1
--- /dev/null
+++ b/arch/mips/bcm63xx/irq.c
@@ -0,0 +1,253 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Nicolas Schichan <nschichan@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_irq.h>
+
+/*
+ * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
+ * prioritize any interrupt relatively to another. the static counter
+ * will resume the loop where it ended the last time we left this
+ * function.
+ */
+static void bcm63xx_irq_dispatch_internal(void)
+{
+	u32 pending;
+	static int i;
+
+	pending = bcm_perf_readl(PERF_IRQMASK_REG) &
+		bcm_perf_readl(PERF_IRQSTAT_REG);
+
+	if (!pending)
+		return ;
+
+	while (1) {
+		int to_call = i;
+
+		i = (i + 1) & 0x1f;
+		if (pending & (1 << to_call)) {
+			do_IRQ(to_call + IRQ_INTERNAL_BASE);
+			break;
+		}
+	}
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	u32 cause;
+
+	do {
+		cause = read_c0_cause() & read_c0_status() & ST0_IM;
+
+		if (!cause)
+			break;
+
+		if (cause & CAUSEF_IP7)
+			do_IRQ(7);
+		if (cause & CAUSEF_IP2)
+			bcm63xx_irq_dispatch_internal();
+		if (cause & CAUSEF_IP3)
+			do_IRQ(IRQ_EXT_0);
+		if (cause & CAUSEF_IP4)
+			do_IRQ(IRQ_EXT_1);
+		if (cause & CAUSEF_IP5)
+			do_IRQ(IRQ_EXT_2);
+		if (cause & CAUSEF_IP6)
+			do_IRQ(IRQ_EXT_3);
+	} while (1);
+}
+
+/*
+ * internal IRQs operations: only mask/unmask on PERF irq mask
+ * register.
+ */
+static inline void bcm63xx_internal_irq_mask(unsigned int irq)
+{
+	u32 mask;
+
+	irq -= IRQ_INTERNAL_BASE;
+	mask = bcm_perf_readl(PERF_IRQMASK_REG);
+	mask &= ~(1 << irq);
+	bcm_perf_writel(mask, PERF_IRQMASK_REG);
+}
+
+static void bcm63xx_internal_irq_unmask(unsigned int irq)
+{
+	u32 mask;
+
+	irq -= IRQ_INTERNAL_BASE;
+	mask = bcm_perf_readl(PERF_IRQMASK_REG);
+	mask |= (1 << irq);
+	bcm_perf_writel(mask, PERF_IRQMASK_REG);
+}
+
+static unsigned int bcm63xx_internal_irq_startup(unsigned int irq)
+{
+	bcm63xx_internal_irq_unmask(irq);
+	return 0;
+}
+
+/*
+ * external IRQs operations: mask/unmask and clear on PERF external
+ * irq control register.
+ */
+static void bcm63xx_external_irq_mask(unsigned int irq)
+{
+	u32 reg;
+
+	irq -= IRQ_EXT_BASE;
+	reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+	reg &= ~EXTIRQ_CFG_MASK(irq);
+	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static void bcm63xx_external_irq_unmask(unsigned int irq)
+{
+	u32 reg;
+
+	irq -= IRQ_EXT_BASE;
+	reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+	reg |= EXTIRQ_CFG_MASK(irq);
+	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static void bcm63xx_external_irq_clear(unsigned int irq)
+{
+	u32 reg;
+
+	irq -= IRQ_EXT_BASE;
+	reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+	reg |= EXTIRQ_CFG_CLEAR(irq);
+	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+}
+
+static unsigned int bcm63xx_external_irq_startup(unsigned int irq)
+{
+	set_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
+	irq_enable_hazard();
+	bcm63xx_external_irq_unmask(irq);
+	return 0;
+}
+
+static void bcm63xx_external_irq_shutdown(unsigned int irq)
+{
+	bcm63xx_external_irq_mask(irq);
+	clear_c0_status(0x100 << (irq - IRQ_MIPS_BASE));
+	irq_disable_hazard();
+}
+
+static int bcm63xx_external_irq_set_type(unsigned int irq,
+					 unsigned int flow_type)
+{
+	u32 reg;
+	struct irq_desc *desc = irq_desc + irq;
+
+	irq -= IRQ_EXT_BASE;
+
+	flow_type &= IRQ_TYPE_SENSE_MASK;
+
+	if (flow_type == IRQ_TYPE_NONE)
+		flow_type = IRQ_TYPE_LEVEL_LOW;
+
+	reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+	switch (flow_type) {
+	case IRQ_TYPE_EDGE_BOTH:
+		reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+		reg |= EXTIRQ_CFG_BOTHEDGE(irq);
+		break;
+
+	case IRQ_TYPE_EDGE_RISING:
+		reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+		reg |= EXTIRQ_CFG_SENSE(irq);
+		reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+		break;
+
+	case IRQ_TYPE_EDGE_FALLING:
+		reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+		reg &= ~EXTIRQ_CFG_SENSE(irq);
+		reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+		break;
+
+	case IRQ_TYPE_LEVEL_HIGH:
+		reg |= EXTIRQ_CFG_LEVELSENSE(irq);
+		reg |= EXTIRQ_CFG_SENSE(irq);
+		break;
+
+	case IRQ_TYPE_LEVEL_LOW:
+		reg |= EXTIRQ_CFG_LEVELSENSE(irq);
+		reg &= ~EXTIRQ_CFG_SENSE(irq);
+		break;
+
+	default:
+		printk(KERN_ERR "bogus flow type combination given !\n");
+		return -EINVAL;
+	}
+	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+
+	if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))  {
+		desc->status |= IRQ_LEVEL;
+		desc->handle_irq = handle_level_irq;
+	} else {
+		desc->handle_irq = handle_edge_irq;
+	}
+
+	return 0;
+}
+
+static struct irq_chip bcm63xx_internal_irq_chip = {
+	.name		= "bcm63xx_ipic",
+	.startup	= bcm63xx_internal_irq_startup,
+	.shutdown	= bcm63xx_internal_irq_mask,
+
+	.mask		= bcm63xx_internal_irq_mask,
+	.mask_ack	= bcm63xx_internal_irq_mask,
+	.unmask		= bcm63xx_internal_irq_unmask,
+};
+
+static struct irq_chip bcm63xx_external_irq_chip = {
+	.name		= "bcm63xx_epic",
+	.startup	= bcm63xx_external_irq_startup,
+	.shutdown	= bcm63xx_external_irq_shutdown,
+
+	.ack		= bcm63xx_external_irq_clear,
+
+	.mask		= bcm63xx_external_irq_mask,
+	.unmask		= bcm63xx_external_irq_unmask,
+
+	.set_type	= bcm63xx_external_irq_set_type,
+};
+
+static struct irqaction cpu_ip2_cascade_action = {
+	.handler	= no_action,
+	.name		= "cascade_ip2",
+};
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	mips_cpu_irq_init();
+	for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
+		set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip,
+					 handle_level_irq);
+
+	for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
+		set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip,
+					 handle_edge_irq);
+
+	setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);
+}
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
new file mode 100644
index 0000000..fb284fb
--- /dev/null
+++ b/arch/mips/bcm63xx/prom.c
@@ -0,0 +1,55 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <asm/bootinfo.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_gpio.h>
+
+void __init prom_init(void)
+{
+	u32 reg, mask;
+
+	bcm63xx_cpu_init();
+
+	/* stop any running watchdog */
+	bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
+	bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
+
+	/* disable all hardware blocks clock for now */
+	if (BCMCPU_IS_6338())
+		mask = CKCTL_6338_ALL_SAFE_EN;
+	else if (BCMCPU_IS_6345())
+		mask = CKCTL_6345_ALL_SAFE_EN;
+	else if (BCMCPU_IS_6348())
+		mask = CKCTL_6348_ALL_SAFE_EN;
+	else
+		/* BCMCPU_IS_6358() */
+		mask = CKCTL_6358_ALL_SAFE_EN;
+
+	reg = bcm_perf_readl(PERF_CKCTL_REG);
+	reg &= ~mask;
+	bcm_perf_writel(reg, PERF_CKCTL_REG);
+
+	/* assign command line from kernel config */
+	strcpy(arcs_cmdline, CONFIG_CMDLINE);
+
+	/* register gpiochip */
+	bcm63xx_gpio_init();
+
+	/* do low level board init */
+	board_prom_init();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
new file mode 100644
index 0000000..b18a0ca
--- /dev/null
+++ b/arch/mips/bcm63xx/setup.c
@@ -0,0 +1,125 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+#include <asm/reboot.h>
+#include <asm/cacheflush.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+void bcm63xx_machine_halt(void)
+{
+	printk(KERN_INFO "System halted\n");
+	while (1)
+		;
+}
+
+static void bcm6348_a1_reboot(void)
+{
+	u32 reg;
+
+	/* soft reset all blocks */
+	printk(KERN_INFO "soft-reseting all blocks ...\n");
+	reg = bcm_perf_readl(PERF_SOFTRESET_REG);
+	reg &= ~SOFTRESET_6348_ALL;
+	bcm_perf_writel(reg, PERF_SOFTRESET_REG);
+	mdelay(10);
+
+	reg = bcm_perf_readl(PERF_SOFTRESET_REG);
+	reg |= SOFTRESET_6348_ALL;
+	bcm_perf_writel(reg, PERF_SOFTRESET_REG);
+	mdelay(10);
+
+	/* Jump to the power on address. */
+	printk(KERN_INFO "jumping to reset vector.\n");
+	/* set high vectors (base at 0xbfc00000 */
+	set_c0_status(ST0_BEV | ST0_ERL);
+	/* run uncached in kseg0 */
+	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+	__flush_cache_all();
+	/* remove all wired TLB entries */
+	write_c0_wired(0);
+	__asm__ __volatile__(
+		"jr\t%0"
+		:
+		: "r" (0xbfc00000));
+	while (1)
+		;
+}
+
+void bcm63xx_machine_reboot(void)
+{
+	u32 reg;
+
+	/* mask and clear all external irq */
+	reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+	reg &= ~EXTIRQ_CFG_MASK_ALL;
+	reg |= EXTIRQ_CFG_CLEAR_ALL;
+	bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+
+	if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
+		bcm6348_a1_reboot();
+
+	printk(KERN_INFO "triggering watchdog soft-reset...\n");
+	bcm_perf_writel(SYS_PLL_SOFT_RESET, PERF_SYS_PLL_CTL_REG);
+	while (1)
+		;
+}
+
+static void __bcm63xx_machine_reboot(char *p)
+{
+	bcm63xx_machine_reboot();
+}
+
+/*
+ * return system type in /proc/cpuinfo
+ */
+const char *get_system_type(void)
+{
+	static char buf[128];
+	snprintf(buf, sizeof(buf), "bcm63xx/%s (0x%04x/0x%04X)",
+		 board_get_name(),
+		 bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev());
+	return buf;
+}
+
+void __init plat_time_init(void)
+{
+	mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2;
+}
+
+void __init plat_mem_setup(void)
+{
+	add_memory_region(0, bcm63xx_get_memory_size(), BOOT_MEM_RAM);
+
+	_machine_halt = bcm63xx_machine_halt;
+	_machine_restart = __bcm63xx_machine_reboot;
+	pm_power_off = bcm63xx_machine_halt;
+
+	set_io_port_base(0);
+	ioport_resource.start = 0;
+	ioport_resource.end = ~0;
+
+	board_setup();
+}
+
+int __init bcm63xx_register_devices(void)
+{
+	return board_register_devices();
+}
+
+arch_initcall(bcm63xx_register_devices);
diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c
new file mode 100644
index 0000000..ba522bd
--- /dev/null
+++ b/arch/mips/bcm63xx/timer.c
@@ -0,0 +1,205 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_timer.h>
+#include <bcm63xx_regs.h>
+
+static DEFINE_SPINLOCK(timer_reg_lock);
+static DEFINE_SPINLOCK(timer_data_lock);
+static struct clk *periph_clk;
+
+static struct timer_data {
+	void	(*cb)(void *);
+	void	*data;
+} timer_data[BCM63XX_TIMER_COUNT];
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+	u32 stat;
+	int i;
+
+	spin_lock(&timer_reg_lock);
+	stat = bcm_timer_readl(TIMER_IRQSTAT_REG);
+	bcm_timer_writel(stat, TIMER_IRQSTAT_REG);
+	spin_unlock(&timer_reg_lock);
+
+	for (i = 0; i < BCM63XX_TIMER_COUNT; i++) {
+		if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i)))
+			continue;
+
+		spin_lock(&timer_data_lock);
+		if (!timer_data[i].cb) {
+			spin_unlock(&timer_data_lock);
+			continue;
+		}
+
+		timer_data[i].cb(timer_data[i].data);
+		spin_unlock(&timer_data_lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+int bcm63xx_timer_enable(int id)
+{
+	u32 reg;
+	unsigned long flags;
+
+	if (id >= BCM63XX_TIMER_COUNT)
+		return -EINVAL;
+
+	spin_lock_irqsave(&timer_reg_lock, flags);
+
+	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+	reg |= TIMER_CTL_ENABLE_MASK;
+	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+	reg |= TIMER_IRQSTAT_TIMER_IR_EN(id);
+	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+	spin_unlock_irqrestore(&timer_reg_lock, flags);
+	return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_enable);
+
+int bcm63xx_timer_disable(int id)
+{
+	u32 reg;
+	unsigned long flags;
+
+	if (id >= BCM63XX_TIMER_COUNT)
+		return -EINVAL;
+
+	spin_lock_irqsave(&timer_reg_lock, flags);
+
+	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+	reg &= ~TIMER_CTL_ENABLE_MASK;
+	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+	reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id);
+	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+	spin_unlock_irqrestore(&timer_reg_lock, flags);
+	return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_disable);
+
+int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data)
+{
+	unsigned long flags;
+	int ret;
+
+	if (id >= BCM63XX_TIMER_COUNT || !callback)
+		return -EINVAL;
+
+	ret = 0;
+	spin_lock_irqsave(&timer_data_lock, flags);
+	if (timer_data[id].cb) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	timer_data[id].cb = callback;
+	timer_data[id].data = data;
+
+out:
+	spin_unlock_irqrestore(&timer_data_lock, flags);
+	return ret;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_register);
+
+void bcm63xx_timer_unregister(int id)
+{
+	unsigned long flags;
+
+	if (id >= BCM63XX_TIMER_COUNT)
+		return;
+
+	spin_lock_irqsave(&timer_data_lock, flags);
+	timer_data[id].cb = NULL;
+	spin_unlock_irqrestore(&timer_data_lock, flags);
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_unregister);
+
+unsigned int bcm63xx_timer_countdown(unsigned int countdown_us)
+{
+	return (clk_get_rate(periph_clk) / (1000 * 1000)) * countdown_us;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_countdown);
+
+int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us)
+{
+	u32 reg, countdown;
+	unsigned long flags;
+
+	if (id >= BCM63XX_TIMER_COUNT)
+		return -EINVAL;
+
+	countdown = bcm63xx_timer_countdown(countdown_us);
+	if (countdown & ~TIMER_CTL_COUNTDOWN_MASK)
+		return -EINVAL;
+
+	spin_lock_irqsave(&timer_reg_lock, flags);
+	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
+
+	if (monotonic)
+		reg &= ~TIMER_CTL_MONOTONIC_MASK;
+	else
+		reg |= TIMER_CTL_MONOTONIC_MASK;
+
+	reg &= ~TIMER_CTL_COUNTDOWN_MASK;
+	reg |= countdown;
+	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
+
+	spin_unlock_irqrestore(&timer_reg_lock, flags);
+	return 0;
+}
+
+EXPORT_SYMBOL(bcm63xx_timer_set);
+
+int bcm63xx_timer_init(void)
+{
+	int ret, irq;
+	u32 reg;
+
+	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
+	reg &= ~TIMER_IRQSTAT_TIMER0_IR_EN;
+	reg &= ~TIMER_IRQSTAT_TIMER1_IR_EN;
+	reg &= ~TIMER_IRQSTAT_TIMER2_IR_EN;
+	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
+
+	periph_clk = clk_get(NULL, "periph");
+	if (IS_ERR(periph_clk))
+		return -ENODEV;
+
+	irq = bcm63xx_get_irq_number(IRQ_TIMER);
+	ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL);
+	if (ret) {
+		printk(KERN_ERR "bcm63xx_timer: failed to register irq\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+arch_initcall(bcm63xx_timer_init);
diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
index c5a7f30..e19d906 100644
--- a/arch/mips/boot/elf2ecoff.c
+++ b/arch/mips/boot/elf2ecoff.c
@@ -59,8 +59,8 @@ struct sect {
 };
 
 int *symTypeTable;
-int must_convert_endian = 0;
-int format_bigendian = 0;
+int must_convert_endian;
+int format_bigendian;
 
 static void copy(int out, int in, off_t offset, off_t size)
 {
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index d6903c3..1394362 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -6,10 +6,10 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2005-2008 Cavium Networks
+# Copyright (C) 2005-2009 Cavium Networks
 #
 
-obj-y := setup.o serial.o octeon-irq.o csrc-octeon.o
+obj-y := setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
 obj-y += dma-octeon.o flash_setup.o
 obj-y += octeon-memcpy.o
 
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
new file mode 100644
index 0000000..be711dd
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -0,0 +1,164 @@
+/*
+ * 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) 2004-2009 Cavium Networks
+ * Copyright (C) 2008 Wind River Systems
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-rnm-defs.h>
+
+static struct octeon_cf_data octeon_cf_data;
+
+static int __init octeon_cf_device_init(void)
+{
+	union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+	unsigned long base_ptr, region_base, region_size;
+	struct platform_device *pd;
+	struct resource cf_resources[3];
+	unsigned int num_resources;
+	int i;
+	int ret = 0;
+
+	/* Setup octeon-cf platform device if present. */
+	base_ptr = 0;
+	if (octeon_bootinfo->major_version == 1
+		&& octeon_bootinfo->minor_version >= 1) {
+		if (octeon_bootinfo->compact_flash_common_base_addr)
+			base_ptr =
+				octeon_bootinfo->compact_flash_common_base_addr;
+	} else {
+		base_ptr = 0x1d000800;
+	}
+
+	if (!base_ptr)
+		return ret;
+
+	/* Find CS0 region. */
+	for (i = 0; i < 8; i++) {
+		mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
+		region_base = mio_boot_reg_cfg.s.base << 16;
+		region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+		if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
+		    && base_ptr < region_base + region_size)
+			break;
+	}
+	if (i >= 7) {
+		/* i and i + 1 are CS0 and CS1, both must be less than 8. */
+		goto out;
+	}
+	octeon_cf_data.base_region = i;
+	octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
+	octeon_cf_data.base_region_bias = base_ptr - region_base;
+	memset(cf_resources, 0, sizeof(cf_resources));
+	num_resources = 0;
+	cf_resources[num_resources].flags	= IORESOURCE_MEM;
+	cf_resources[num_resources].start	= region_base;
+	cf_resources[num_resources].end	= region_base + region_size - 1;
+	num_resources++;
+
+
+	if (!(base_ptr & 0xfffful)) {
+		/*
+		 * Boot loader signals availability of DMA (true_ide
+		 * mode) by setting low order bits of base_ptr to
+		 * zero.
+		 */
+
+		/* Asume that CS1 immediately follows. */
+		mio_boot_reg_cfg.u64 =
+			cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
+		region_base = mio_boot_reg_cfg.s.base << 16;
+		region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+		if (!mio_boot_reg_cfg.s.en)
+			goto out;
+
+		cf_resources[num_resources].flags	= IORESOURCE_MEM;
+		cf_resources[num_resources].start	= region_base;
+		cf_resources[num_resources].end	= region_base + region_size - 1;
+		num_resources++;
+
+		octeon_cf_data.dma_engine = 0;
+		cf_resources[num_resources].flags	= IORESOURCE_IRQ;
+		cf_resources[num_resources].start	= OCTEON_IRQ_BOOTDMA;
+		cf_resources[num_resources].end	= OCTEON_IRQ_BOOTDMA;
+		num_resources++;
+	} else {
+		octeon_cf_data.dma_engine = -1;
+	}
+
+	pd = platform_device_alloc("pata_octeon_cf", -1);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	pd->dev.platform_data = &octeon_cf_data;
+
+	ret = platform_device_add_resources(pd, cf_resources, num_resources);
+	if (ret)
+		goto fail;
+
+	ret = platform_device_add(pd);
+	if (ret)
+		goto fail;
+
+	return ret;
+fail:
+	platform_device_put(pd);
+out:
+	return ret;
+}
+device_initcall(octeon_cf_device_init);
+
+/* Octeon Random Number Generator.  */
+static int __init octeon_rng_device_init(void)
+{
+	struct platform_device *pd;
+	int ret = 0;
+
+	struct resource rng_resources[] = {
+		{
+			.flags	= IORESOURCE_MEM,
+			.start	= XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS),
+			.end	= XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf
+		}, {
+			.flags	= IORESOURCE_MEM,
+			.start	= cvmx_build_io_address(8, 0),
+			.end	= cvmx_build_io_address(8, 0) + 0x7
+		}
+	};
+
+	pd = platform_device_alloc("octeon_rng", -1);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = platform_device_add_resources(pd, rng_resources,
+					    ARRAY_SIZE(rng_resources));
+	if (ret)
+		goto fail;
+
+	ret = platform_device_add(pd);
+	if (ret)
+		goto fail;
+
+	return ret;
+fail:
+	platform_device_put(pd);
+
+out:
+	return ret;
+}
+device_initcall(octeon_rng_device_init);
+
+MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Platform driver for Octeon SOC");
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index da55924..b321d3b 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -11,7 +11,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/irq.h>
 #include <linux/serial.h>
 #include <linux/smp.h>
 #include <linux/types.h>
@@ -824,105 +823,3 @@ void prom_free_prom_memory(void)
 	   CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
 	octeon_hal_setup_reserved32();
 }
-
-static struct octeon_cf_data octeon_cf_data;
-
-static int __init octeon_cf_device_init(void)
-{
-	union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
-	unsigned long base_ptr, region_base, region_size;
-	struct platform_device *pd;
-	struct resource cf_resources[3];
-	unsigned int num_resources;
-	int i;
-	int ret = 0;
-
-	/* Setup octeon-cf platform device if present. */
-	base_ptr = 0;
-	if (octeon_bootinfo->major_version == 1
-		&& octeon_bootinfo->minor_version >= 1) {
-		if (octeon_bootinfo->compact_flash_common_base_addr)
-			base_ptr =
-				octeon_bootinfo->compact_flash_common_base_addr;
-	} else {
-		base_ptr = 0x1d000800;
-	}
-
-	if (!base_ptr)
-		return ret;
-
-	/* Find CS0 region. */
-	for (i = 0; i < 8; i++) {
-		mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
-		region_base = mio_boot_reg_cfg.s.base << 16;
-		region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
-		if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
-		    && base_ptr < region_base + region_size)
-			break;
-	}
-	if (i >= 7) {
-		/* i and i + 1 are CS0 and CS1, both must be less than 8. */
-		goto out;
-	}
-	octeon_cf_data.base_region = i;
-	octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
-	octeon_cf_data.base_region_bias = base_ptr - region_base;
-	memset(cf_resources, 0, sizeof(cf_resources));
-	num_resources = 0;
-	cf_resources[num_resources].flags	= IORESOURCE_MEM;
-	cf_resources[num_resources].start	= region_base;
-	cf_resources[num_resources].end	= region_base + region_size - 1;
-	num_resources++;
-
-
-	if (!(base_ptr & 0xfffful)) {
-		/*
-		 * Boot loader signals availability of DMA (true_ide
-		 * mode) by setting low order bits of base_ptr to
-		 * zero.
-		 */
-
-		/* Asume that CS1 immediately follows. */
-		mio_boot_reg_cfg.u64 =
-			cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
-		region_base = mio_boot_reg_cfg.s.base << 16;
-		region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
-		if (!mio_boot_reg_cfg.s.en)
-			goto out;
-
-		cf_resources[num_resources].flags	= IORESOURCE_MEM;
-		cf_resources[num_resources].start	= region_base;
-		cf_resources[num_resources].end	= region_base + region_size - 1;
-		num_resources++;
-
-		octeon_cf_data.dma_engine = 0;
-		cf_resources[num_resources].flags	= IORESOURCE_IRQ;
-		cf_resources[num_resources].start	= OCTEON_IRQ_BOOTDMA;
-		cf_resources[num_resources].end	= OCTEON_IRQ_BOOTDMA;
-		num_resources++;
-	} else {
-		octeon_cf_data.dma_engine = -1;
-	}
-
-	pd = platform_device_alloc("pata_octeon_cf", -1);
-	if (!pd) {
-		ret = -ENOMEM;
-		goto out;
-	}
-	pd->dev.platform_data = &octeon_cf_data;
-
-	ret = platform_device_add_resources(pd, cf_resources, num_resources);
-	if (ret)
-		goto fail;
-
-	ret = platform_device_add(pd);
-	if (ret)
-		goto fail;
-
-	return ret;
-fail:
-	platform_device_put(pd);
-out:
-	return ret;
-}
-device_initcall(octeon_cf_device_init);
diff --git a/arch/mips/configs/ar7_defconfig b/arch/mips/configs/ar7_defconfig
index dad5b67..3564830 100644
--- a/arch/mips/configs/ar7_defconfig
+++ b/arch/mips/configs/ar7_defconfig
@@ -125,7 +125,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig
index d869433..94b7d57 100644
--- a/arch/mips/configs/bcm47xx_defconfig
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -111,7 +111,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/bcm63xx_defconfig b/arch/mips/configs/bcm63xx_defconfig
new file mode 100644
index 0000000..ea00c18
--- /dev/null
+++ b/arch/mips/configs/bcm63xx_defconfig
@@ -0,0 +1,972 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc6
+# Sun May 31 20:17:18 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+CONFIG_BCM63XX=y
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+
+#
+# CPU support
+#
+CONFIG_BCM63XX_CPU_6348=y
+CONFIG_BCM63XX_CPU_6358=y
+CONFIG_BOARD_BCM963XX=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 is not set
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+# CONFIG_64BIT is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=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 is not set
+# CONFIG_SYSVIPC is not set
+# 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=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_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 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_SHMEM is not set
+# CONFIG_AIO is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBD 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 is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_LEGACY is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_MMU=y
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+CONFIG_CARDBUS=y
+
+#
+# PC-card bridges
+#
+# CONFIG_YENTA is not set
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+CONFIG_PCMCIA_BCM63XX=y
+# CONFIG_HOTPLUG_PCI 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_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET 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_PHONET 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_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 is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# 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 is not set
+# CONFIG_MTD_BLKDEVS is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# 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 is not set
+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=y
+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 is not set
+
+#
+# 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_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV 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_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# 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
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET 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_BCM63XX_PHY=y
+# 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_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC 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
+# 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_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
+CONFIG_BCM63XX_ENET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_NET_PCMCIA is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI 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 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
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_BCM63XX=y
+CONFIG_SERIAL_BCM63XX_CONSOLE=y
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# 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=y
+CONFIG_SSB_SPROM=y
+CONFIG_SSB_PCIHOST_POSSIBLE=y
+CONFIG_SSB_PCIHOST=y
+# CONFIG_SSB_B43_PCI_BRIDGE is not set
+CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
+# CONFIG_SSB_PCMCIAHOST is not set
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
+# CONFIG_SSB_DRIVER_PCICORE is not set
+# CONFIG_SSB_DRIVER_MIPS 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_DRM is not set
+# 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=y
+
+#
+# Display hardware drivers
+#
+# CONFIG_SOUND is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=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
+# CONFIG_USB_OHCI_HCD_SSB is not set
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# 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_UWB 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_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# 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
+
+#
+# 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 is not set
+# 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
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_KCORE=y
+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 is not set
+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 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
+# 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_NILFS2_FS 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
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# 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_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE="console=ttyS0,115200"
+
+#
+# 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
+# CONFIG_BINARY_PRINTF 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_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index d6d35b2..13d9eb4 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -129,7 +129,6 @@ CONFIG_PAGE_SIZE_4KB=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index eb44b72..6c8cca8 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -112,7 +112,6 @@ CONFIG_PAGE_SIZE_4KB=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index a279165..dbdf3bb 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 8944d15..fa68144 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index ab17973..d73f1de 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index b65803f..ec3e028 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -116,7 +116,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index a190ac0..7631dae 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 4e465e9..1995d43 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -118,7 +118,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/fulong_defconfig b/arch/mips/configs/fulong_defconfig
deleted file mode 100644
index 786a9bc..0000000
--- a/arch/mips/configs/fulong_defconfig
+++ /dev/null
@@ -1,1912 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc6
-# Fri Nov 28 17:53:48 2008
-#
-CONFIG_MIPS=y
-
-#
-# Machine selection
-#
-# CONFIG_MACH_ALCHEMY is not set
-# CONFIG_BASLER_EXCITE is not set
-# CONFIG_BCM47XX is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_LASAT is not set
-CONFIG_LEMOTE_FULONG=y
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SIM is not set
-# CONFIG_MACH_EMMA is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_NXP_STB220 is not set
-# CONFIG_NXP_STB225 is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_PMC_MSP is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP28 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_SWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_MACH_TX39XX is not set
-# CONFIG_MACH_TX49XX is not set
-# CONFIG_MIKROTIK_RB532 is not set
-# CONFIG_WR_PPMC is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_ARCH_SUPPORTS_OPROFILE=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_CEVT_R4K=y
-CONFIG_CSRC_R4K=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
-CONFIG_I8259=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_ISA_DMA=y
-CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
-# CONFIG_CPU_BIG_ENDIAN is not set
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
-CONFIG_IRQ_CPU=y
-CONFIG_BOOT_ELF32=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_HAVE_STD_PC_SERIAL_PORT=y
-
-#
-# CPU selection
-#
-CONFIG_CPU_LOONGSON2=y
-# CONFIG_CPU_MIPS32_R1 is not set
-# CONFIG_CPU_MIPS32_R2 is not set
-# CONFIG_CPU_MIPS64_R1 is not set
-# CONFIG_CPU_MIPS64_R2 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R5500 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_SYS_HAS_CPU_LOONGSON2=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
-
-#
-# Kernel type
-#
-# CONFIG_32BIT is not set
-CONFIG_64BIT=y
-# CONFIG_PAGE_SIZE_4KB is not set
-# CONFIG_PAGE_SIZE_8KB is not set
-CONFIG_PAGE_SIZE_16KB=y
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_BOARD_SCACHE=y
-CONFIG_MIPS_MT_DISABLED=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_WB=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_SYS_SUPPORTS_HIGHMEM=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-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_SPARSEMEM_STATIC=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_TICK_ONESHOT=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
-# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
-# CONFIG_HZ_128 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_256 is not set
-# CONFIG_HZ_1000 is not set
-# CONFIG_HZ_1024 is not set
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=250
-# CONFIG_PREEMPT_NONE is not set
-CONFIG_PREEMPT_VOLUNTARY=y
-# CONFIG_PREEMPT is not set
-# CONFIG_KEXEC is not set
-CONFIG_SECCOMP=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_STACKTRACE_SUPPORT=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="lm32"
-# 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 is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT 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_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-CONFIG_USER_NS=y
-CONFIG_PID_NS=y
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SYSCTL=y
-CONFIG_EMBEDDED=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-# CONFIG_PCSPKR_PLATFORM 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_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_PROFILING=y
-# CONFIG_MARKERS is not set
-CONFIG_OPROFILE=m
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
-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
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-CONFIG_BLK_DEV_BSG=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-CONFIG_BLOCK_COMPAT=y
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-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_FREEZER=y
-
-#
-# Bus options (PCI, PCMCIA, EISA, ISA, TC)
-#
-CONFIG_HW_HAS_PCI=y
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-CONFIG_ISA=y
-CONFIG_MMU=y
-# CONFIG_PCCARD is not set
-# CONFIG_HOTPLUG_PCI 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=y
-CONFIG_MIPS32_COMPAT=y
-CONFIG_COMPAT=y
-CONFIG_SYSVIPC_COMPAT=y
-CONFIG_MIPS32_O32=y
-CONFIG_MIPS32_N32=y
-CONFIG_BINFMT_ELF32=y
-
-#
-# Power management options
-#
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_PM=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE 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=m
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_BEET=y
-# 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=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_NETFILTER_ADVANCED=y
-
-#
-# Core Netfilter Configuration
-#
-CONFIG_NETFILTER_NETLINK=m
-CONFIG_NETFILTER_NETLINK_QUEUE=m
-CONFIG_NETFILTER_NETLINK_LOG=m
-# CONFIG_NF_CONNTRACK is not set
-CONFIG_NETFILTER_XTABLES=m
-CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
-# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
-CONFIG_NETFILTER_XT_TARGET_MARK=m
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
-CONFIG_NETFILTER_XT_TARGET_RATEEST=m
-CONFIG_NETFILTER_XT_TARGET_TRACE=m
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
-CONFIG_NETFILTER_XT_MATCH_COMMENT=m
-CONFIG_NETFILTER_XT_MATCH_DCCP=m
-# 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_IPRANGE=m
-CONFIG_NETFILTER_XT_MATCH_LENGTH=m
-CONFIG_NETFILTER_XT_MATCH_LIMIT=m
-CONFIG_NETFILTER_XT_MATCH_MAC=m
-CONFIG_NETFILTER_XT_MATCH_MARK=m
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
-CONFIG_NETFILTER_XT_MATCH_OWNER=m
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
-CONFIG_NETFILTER_XT_MATCH_QUOTA=m
-CONFIG_NETFILTER_XT_MATCH_RATEEST=m
-CONFIG_NETFILTER_XT_MATCH_REALM=m
-CONFIG_NETFILTER_XT_MATCH_RECENT=m
-# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
-CONFIG_NETFILTER_XT_MATCH_SCTP=m
-CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
-CONFIG_NETFILTER_XT_MATCH_STRING=m
-CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
-CONFIG_NETFILTER_XT_MATCH_TIME=m
-CONFIG_NETFILTER_XT_MATCH_U32=m
-# CONFIG_IP_VS is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_NF_DEFRAG_IPV4 is not set
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ADDRTYPE=m
-CONFIG_IP_NF_MATCH_AH=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_TTL=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-# 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_NET_CLS_ROUTE=y
-
-#
-# 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=m
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-# CONFIG_MAC80211 is not set
-CONFIG_IEEE80211=m
-# CONFIG_IEEE80211_DEBUG is not set
-CONFIG_IEEE80211_CRYPT_WEP=m
-# CONFIG_IEEE80211_CRYPT_CCMP is not set
-# CONFIG_IEEE80211_CRYPT_TKIP is not set
-# CONFIG_RFKILL is not set
-CONFIG_NET_9P=m
-# CONFIG_NET_9P_DEBUG is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_MTD=m
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_PARTITIONS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLKDEVS=m
-CONFIG_MTD_BLOCK=m
-# CONFIG_MTD_BLOCK_RO is not set
-# 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=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=m
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_GEOMETRY 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_OTP is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=m
-CONFIG_MTD_CFI_STAA=m
-CONFIG_MTD_CFI_UTIL=m
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=m
-CONFIG_MTD_PHYSMAP_START=0x1fc00000
-CONFIG_MTD_PHYSMAP_LEN=0x80000
-CONFIG_MTD_PHYSMAP_BANKWIDTH=1
-# CONFIG_MTD_INTEL_VR_NOR is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# 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
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-# CONFIG_PNP is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_XIP is not set
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
-CONFIG_ATA_OVER_ETH=m
-# CONFIG_BLK_DEV_HD is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_HAVE_IDE=y
-CONFIG_IDE=y
-
-#
-# Please see Documentation/ide/ide.txt for help/info on IDE drives
-#
-CONFIG_IDE_TIMINGS=y
-CONFIG_IDE_ATAPI=y
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_IDE_GD=y
-CONFIG_IDE_GD_ATA=y
-# CONFIG_IDE_GD_ATAPI is not set
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDESCSI=y
-CONFIG_IDE_TASK_IOCTL=y
-CONFIG_IDE_PROC_FS=y
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_PLATFORM is not set
-CONFIG_BLK_DEV_IDEDMA_SFF=y
-
-#
-# PCI IDE chipsets support
-#
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_PCIBUS_ORDER=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-CONFIG_BLK_DEV_VIA82CXXX=y
-# CONFIG_BLK_DEV_TC86C001 is not set
-
-#
-# Other IDE chipsets support
-#
-
-#
-# Note: most of these also require special kernel boot parameters
-#
-# CONFIG_BLK_DEV_4DRIVES is not set
-# CONFIG_BLK_DEV_ALI14XX is not set
-# CONFIG_BLK_DEV_DTC2278 is not set
-# CONFIG_BLK_DEV_HT6560B is not set
-# CONFIG_BLK_DEV_QD65XX is not set
-# CONFIG_BLK_DEV_UMC8672 is not set
-CONFIG_BLK_DEV_IDEDMA=y
-
-#
-# 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=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
-# 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=y
-# 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_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_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-CONFIG_MACVLAN=m
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-CONFIG_VETH=m
-# CONFIG_ARCNET is not set
-CONFIG_PHYLIB=m
-
-#
-# MII PHY device drivers
-#
-CONFIG_MARVELL_PHY=m
-CONFIG_DAVICOM_PHY=m
-CONFIG_QSEMI_PHY=m
-CONFIG_LXT_PHY=m
-CONFIG_CICADA_PHY=m
-# 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_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_AX88796 is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_SMC91X is not set
-# CONFIG_DM9000 is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA 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_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_TC35815 is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-CONFIG_8139TOO=y
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_R6040 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
-# CONFIG_ATL2 is not set
-CONFIG_NETDEV_1000=y
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_IP1000 is not set
-# CONFIG_IGB is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E is not set
-# CONFIG_JME is not set
-CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# 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_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPPOL2TP=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLHC=m
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-CONFIG_NET_FC=y
-# 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=y
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=m
-# 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_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-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
-CONFIG_MOUSE_SERIAL=y
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_NOZOMI is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=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_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_DEVPORT=y
-CONFIG_I2C=m
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_HELPER_AUTO=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# PC SMBus host controller drivers
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_ISCH is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_VIA is not set
-CONFIG_I2C_VIAPRO=m
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# 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
-# CONFIG_I2C_TINY_USB is not set
-
-#
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_ELEKTOR is not set
-# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# 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
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI 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 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_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-CONFIG_VIDEO_DEV=m
-CONFIG_VIDEO_V4L2_COMMON=m
-CONFIG_VIDEO_ALLOW_V4L1=y
-CONFIG_VIDEO_V4L1_COMPAT=y
-# CONFIG_DVB_CORE is not set
-CONFIG_VIDEO_MEDIA=m
-
-#
-# Multimedia drivers
-#
-CONFIG_MEDIA_ATTACH=y
-CONFIG_MEDIA_TUNER=m
-CONFIG_MEDIA_TUNER_CUSTOMIZE=y
-CONFIG_MEDIA_TUNER_SIMPLE=m
-CONFIG_MEDIA_TUNER_TDA8290=m
-CONFIG_MEDIA_TUNER_TDA827X=m
-CONFIG_MEDIA_TUNER_TDA18271=m
-CONFIG_MEDIA_TUNER_TDA9887=m
-CONFIG_MEDIA_TUNER_TEA5761=m
-CONFIG_MEDIA_TUNER_TEA5767=m
-CONFIG_MEDIA_TUNER_MT20XX=m
-CONFIG_MEDIA_TUNER_MT2060=m
-CONFIG_MEDIA_TUNER_MT2266=m
-CONFIG_MEDIA_TUNER_MT2131=m
-CONFIG_MEDIA_TUNER_QT1010=m
-CONFIG_MEDIA_TUNER_XC2028=m
-CONFIG_MEDIA_TUNER_XC5000=m
-CONFIG_MEDIA_TUNER_MXL5005S=m
-CONFIG_MEDIA_TUNER_MXL5007T=m
-CONFIG_VIDEO_V4L2=m
-CONFIG_VIDEO_V4L1=m
-CONFIG_VIDEOBUF_GEN=m
-CONFIG_VIDEOBUF_VMALLOC=m
-CONFIG_VIDEOBUF_DMA_CONTIG=m
-CONFIG_VIDEO_CAPTURE_DRIVERS=y
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_CPIA2 is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_CAFE_CCIC is not set
-CONFIG_SOC_CAMERA=m
-CONFIG_SOC_CAMERA_MT9M001=m
-CONFIG_SOC_CAMERA_MT9M111=m
-CONFIG_SOC_CAMERA_MT9V022=m
-CONFIG_SOC_CAMERA_PLATFORM=m
-CONFIG_VIDEO_SH_MOBILE_CEU=m
-CONFIG_V4L_USB_DRIVERS=y
-CONFIG_USB_VIDEO_CLASS=m
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-CONFIG_USB_GSPCA=m
-CONFIG_USB_M5602=m
-CONFIG_USB_GSPCA_CONEX=m
-CONFIG_USB_GSPCA_ETOMS=m
-CONFIG_USB_GSPCA_FINEPIX=m
-CONFIG_USB_GSPCA_MARS=m
-CONFIG_USB_GSPCA_OV519=m
-CONFIG_USB_GSPCA_PAC207=m
-CONFIG_USB_GSPCA_PAC7311=m
-CONFIG_USB_GSPCA_SONIXB=m
-CONFIG_USB_GSPCA_SONIXJ=m
-CONFIG_USB_GSPCA_SPCA500=m
-CONFIG_USB_GSPCA_SPCA501=m
-CONFIG_USB_GSPCA_SPCA505=m
-CONFIG_USB_GSPCA_SPCA506=m
-CONFIG_USB_GSPCA_SPCA508=m
-CONFIG_USB_GSPCA_SPCA561=m
-CONFIG_USB_GSPCA_STK014=m
-CONFIG_USB_GSPCA_SUNPLUS=m
-CONFIG_USB_GSPCA_T613=m
-CONFIG_USB_GSPCA_TV8532=m
-CONFIG_USB_GSPCA_VC032X=m
-CONFIG_USB_GSPCA_ZC3XX=m
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_EM28XX is not set
-# CONFIG_VIDEO_USBVISION is not set
-CONFIG_VIDEO_USBVIDEO=m
-CONFIG_USB_VICAM=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_QUICKCAM_MESSENGER=m
-CONFIG_USB_ET61X251=m
-# CONFIG_VIDEO_OVCAMCHIP is not set
-CONFIG_USB_OV511=m
-CONFIG_USB_SE401=m
-CONFIG_USB_SN9C102=m
-CONFIG_USB_STV680=m
-CONFIG_USB_ZC0301=m
-CONFIG_USB_PWC=m
-# CONFIG_USB_PWC_DEBUG is not set
-# CONFIG_USB_ZR364XX is not set
-CONFIG_USB_STKWEBCAM=m
-CONFIG_USB_S2255=m
-CONFIG_RADIO_ADAPTERS=y
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-# CONFIG_USB_DSBR is not set
-CONFIG_USB_SI470X=m
-CONFIG_USB_MR800=m
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_DRM is not set
-# CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-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=y
-CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
-
-#
-# Frame buffer hardware drivers
-#
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_RADEON=y
-# CONFIG_FB_RADEON_I2C is not set
-CONFIG_FB_RADEON_BACKLIGHT=y
-# CONFIG_FB_RADEON_DEBUG is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_VIA is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_VT8623 is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_ARK is not set
-# CONFIG_FB_PM3 is not set
-# CONFIG_FB_CARMINE is not set
-# 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=m
-# CONFIG_LCD_ILI9320 is not set
-# CONFIG_LCD_PLATFORM is not set
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_BACKLIGHT_CORGI is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-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 is not set
-CONFIG_SOUND=y
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_PCM_OSS_PLUGINS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_VMASTER=y
-CONFIG_SND_MPU401_UART=m
-CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-CONFIG_SND_PCI=y
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_OXYGEN is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HIFIER is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-CONFIG_SND_VIA82XX=m
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
-CONFIG_SND_MIPS=y
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=m
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-CONFIG_HIDRAW=y
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_HID_PID=y
-CONFIG_USB_HIDDEV=y
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-
-#
-# Special HID drivers
-#
-CONFIG_HID_COMPAT=y
-CONFIG_HID_A4TECH=m
-CONFIG_HID_APPLE=m
-CONFIG_HID_BELKIN=m
-CONFIG_HID_BRIGHT=m
-CONFIG_HID_CHERRY=m
-CONFIG_HID_CHICONY=m
-CONFIG_HID_CYPRESS=m
-CONFIG_HID_DELL=m
-CONFIG_HID_EZKEY=m
-CONFIG_HID_GYRATION=m
-CONFIG_HID_LOGITECH=m
-CONFIG_LOGITECH_FF=y
-CONFIG_LOGIRUMBLEPAD2_FF=y
-CONFIG_HID_MICROSOFT=m
-CONFIG_HID_MONTEREY=m
-CONFIG_HID_PANTHERLORD=m
-# CONFIG_PANTHERLORD_FF is not set
-CONFIG_HID_PETALYNX=m
-CONFIG_HID_SAMSUNG=m
-CONFIG_HID_SONY=m
-CONFIG_HID_SUNPLUS=m
-# CONFIG_THRUSTMASTER_FF is not set
-CONFIG_ZEROPLUS_FF=m
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-CONFIG_USB_OTG_WHITELIST=y
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_MON is not set
-# CONFIG_USB_WUSB is not set
-CONFIG_USB_WUSB_CBAF=m
-# CONFIG_USB_WUSB_CBAF_DEBUG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_C67X00_HCD=m
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_ISP1760_HCD=m
-CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=m
-# CONFIG_USB_SL811_HCD is not set
-CONFIG_USB_R8A66597_HCD=m
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_ACM=y
-CONFIG_USB_PRINTER=y
-CONFIG_USB_WDM=m
-CONFIG_USB_TMC=m
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
-#
-
-#
-# see USB_STORAGE Help for more information
-#
-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
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-CONFIG_USB_STORAGE_ONETOUCH=y
-# CONFIG_USB_STORAGE_KARMA is not set
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
-CONFIG_USB_LIBUSUAL=y
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-CONFIG_USB_SEVSEG=m
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# 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
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
-CONFIG_USB_ISIGHTFW=m
-CONFIG_USB_VST=m
-# CONFIG_USB_GADGET is not set
-# CONFIG_UWB 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_INFINIBAND is not set
-CONFIG_RTC_LIB=y
-CONFIG_RTC_CLASS=m
-
-#
-# RTC interfaces
-#
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_DEV=y
-CONFIG_RTC_INTF_DEV_UIE_EMUL=y
-# 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 is not set
-# 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
-#
-
-#
-# Platform RTC drivers
-#
-CONFIG_RTC_DRV_CMOS=m
-# 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_DMADEVICES is not set
-CONFIG_UIO=m
-CONFIG_UIO_CIF=m
-# 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
-CONFIG_STAGING_EXCLUDE_BUILD=y
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT2_FS_XIP=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=m
-CONFIG_EXT4DEV_COMPAT=y
-CONFIG_EXT4_FS_XATTR=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_EXT4_FS_SECURITY=y
-CONFIG_FS_XIP=y
-CONFIG_JBD=y
-CONFIG_JBD2=m
-CONFIG_FS_MBCACHE=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-# CONFIG_JFS_FS is not set
-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_DNOTIFY=y
-CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_FUSE_FS=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=936
-CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-CONFIG_NTFS_RW=y
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-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 is not set
-
-#
-# Miscellaneous filesystems
-#
-# 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 is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_OMFS_FS=m
-# 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=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V2_ACL=y
-CONFIG_NFSD_V3=y
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_ACL_SUPPORT=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="cp936"
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-CONFIG_CIFS_STATS2=y
-CONFIG_CIFS_WEAK_PW_HASH=y
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-CONFIG_CIFS_DEBUG2=y
-CONFIG_CIFS_EXPERIMENTAL=y
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# 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=y
-# 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_TRACE_IRQFLAGS_SUPPORT=y
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=2048
-# 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_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-CONFIG_DYNAMIC_PRINTK_DEBUG=y
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_CMDLINE=""
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-CONFIG_SECURITY_FILE_CAPABILITIES=y
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-CONFIG_CRYPTO_FIPS=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_RNG=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_GF128MUL=m
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_AUTHENC=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-CONFIG_CRYPTO_CCM=m
-CONFIG_CRYPTO_GCM=m
-CONFIG_CRYPTO_SEQIV=m
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_CTR=m
-CONFIG_CRYPTO_CTS=m
-CONFIG_CRYPTO_ECB=m
-# CONFIG_CRYPTO_LRW is not set
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_XTS=m
-
-#
-# 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=m
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-CONFIG_CRYPTO_RMD128=m
-CONFIG_CRYPTO_RMD160=m
-CONFIG_CRYPTO_RMD256=m
-CONFIG_CRYPTO_RMD320=m
-CONFIG_CRYPTO_SHA1=m
-# 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=m
-# CONFIG_CRYPTO_ANUBIS is not set
-CONFIG_CRYPTO_ARC4=m
-# 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=m
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-CONFIG_CRYPTO_SALSA20=m
-CONFIG_CRYPTO_SEED=m
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_LZO=m
-
-#
-# Random Number Generation
-#
-CONFIG_CRYPTO_ANSI_CPRNG=m
-# CONFIG_CRYPTO_HW is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_CRC_CCITT=y
-CONFIG_CRC16=m
-# CONFIG_CRC_T10DIF is not set
-CONFIG_CRC_ITU_T=m
-CONFIG_CRC32=y
-CONFIG_CRC7=m
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
-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
diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig
new file mode 100644
index 0000000..0197f0d
--- /dev/null
+++ b/arch/mips/configs/fuloong2e_defconfig
@@ -0,0 +1,1819 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc1
+# Thu Jul  2 22:37:00 2009
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+CONFIG_MACH_LOONGSON=y
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_LEMOTE_FULOONG2E=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_I8259=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_ISA_DMA_SUPPORT_BROKEN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+CONFIG_CPU_LOONGSON2E=y
+# CONFIG_CPU_MIPS32_R1 is not set
+# CONFIG_CPU_MIPS32_R2 is not set
+# CONFIG_CPU_MIPS64_R1 is not set
+# CONFIG_CPU_MIPS64_R2 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+# CONFIG_CPU_CAVIUM_OCTEON is not set
+CONFIG_CPU_LOONGSON2=y
+CONFIG_SYS_HAS_CPU_LOONGSON2E=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
+
+#
+# Kernel type
+#
+# CONFIG_32BIT is not set
+CONFIG_64BIT=y
+# CONFIG_PAGE_SIZE_4KB is not set
+# CONFIG_PAGE_SIZE_8KB is not set
+CONFIG_PAGE_SIZE_16KB=y
+# CONFIG_PAGE_SIZE_32KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_CPU_HAS_WB=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="-fuloong2e"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# 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_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=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+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_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Performance Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_MARKERS=y
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+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_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+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
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+CONFIG_ISA=y
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI 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=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+# CONFIG_IP_MROUTE 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=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_TPROXY is not set
+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
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# 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=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+# 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_PHONET=m
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+CONFIG_NET_CLS_ROUTE=y
+# CONFIG_DCB is not set
+
+#
+# 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_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+CONFIG_NET_9P=m
+# CONFIG_NET_9P_DEBUG is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=m
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_TESTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+# CONFIG_MTD_BLOCK_RO is not set
+# 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=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_GEOMETRY 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_OTP is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES 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_TIMINGS=y
+CONFIG_IDE_ATAPI=y
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+CONFIG_BLK_DEV_IDEDMA_SFF=y
+
+#
+# PCI IDE chipsets support
+#
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_BLK_DEV_TC86C001 is not set
+
+#
+# Other IDE chipsets support
+#
+
+#
+# Note: most of these also require special kernel boot parameters
+#
+# CONFIG_BLK_DEV_4DRIVES is not set
+# CONFIG_BLK_DEV_ALI14XX is not set
+# CONFIG_BLK_DEV_DTC2278 is not set
+# CONFIG_BLK_DEV_HT6560B is not set
+# CONFIG_BLK_DEV_QD65XX is not set
+# CONFIG_BLK_DEV_UMC8672 is not set
+CONFIG_BLK_DEV_IDEDMA=y
+
+#
+# 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=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# 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_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_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+CONFIG_MACVLAN=m
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+CONFIG_VETH=m
+# CONFIG_ARCNET is not set
+CONFIG_PHYLIB=m
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+# 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_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA 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_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TC35815 is not set
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_R6040 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# 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
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# 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
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOL2TP=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLHC=m
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NET_FC=y
+# 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=y
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# 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_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=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_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_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+CONFIG_I2C_VIAPRO=m
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# 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
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_PCA_ISA is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS 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 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_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+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=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_RADEON=y
+# CONFIG_FB_RADEON_I2C is not set
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# 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=m
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+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 is not set
+CONFIG_SOUND=y
+CONFIG_SOUND_OSS_CORE=y
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_RAWMIDI=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_RTCTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+CONFIG_SND_RAWMIDI_SEQ=m
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_MPU401_UART=m
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
+CONFIG_SND_PCI=y
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AW2 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CTXFI is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# 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
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_HIFIER is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_LX6464ES is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+CONFIG_SND_VIA82XX=m
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+CONFIG_SND_MIPS=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+CONFIG_HIDRAW=y
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
+CONFIG_HID_PID=y
+
+#
+# USB HID Boot Protocol drivers
+#
+CONFIG_USB_KBD=y
+CONFIG_USB_MOUSE=y
+
+#
+# Special HID drivers
+#
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_OTG_WHITELIST=y
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+CONFIG_USB_WUSB_CBAF=m
+# CONFIG_USB_WUSB_CBAF_DEBUG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_C67X00_HCD=m
+# CONFIG_USB_XHCI_HCD is not set
+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=m
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=m
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=m
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+CONFIG_USB_PRINTER=y
+CONFIG_USB_WDM=m
+CONFIG_USB_TMC=m
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# 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_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+CONFIG_USB_STORAGE_ONETOUCH=y
+# CONFIG_USB_STORAGE_KARMA is not set
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_LIBUSUAL=y
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+CONFIG_USB_SEVSEG=m
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+CONFIG_USB_ISIGHTFW=m
+CONFIG_USB_VST=m
+# 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
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+CONFIG_UIO=m
+CONFIG_UIO_CIF=m
+# CONFIG_UIO_PDRV is not set
+# CONFIG_UIO_PDRV_GENIRQ is not set
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_AEC is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=m
+CONFIG_EXT4DEV_COMPAT=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=m
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_REISERFS_FS_XATTR is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=936
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_NTFS_FS=m
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+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 is not set
+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 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=m
+# 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_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp936"
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_STATS2=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DEBUG2=y
+CONFIG_CIFS_EXPERIMENTAL=y
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# 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=y
+# 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_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=2048
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_NOP_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_FILE_CAPABILITIES=y
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=m
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# 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=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA1=m
+# 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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# 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=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 1158228..f14d38b 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -130,7 +130,6 @@ CONFIG_IP22_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 0208723..1fc73aa 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -105,7 +105,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ip28_defconfig b/arch/mips/configs/ip28_defconfig
index 70a744e..539dccb 100644
--- a/arch/mips/configs/ip28_defconfig
+++ b/arch/mips/configs/ip28_defconfig
@@ -123,7 +123,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index de4c7a0..d934bde 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -118,7 +118,6 @@ CONFIG_RM7000_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig
index bbacc35..d22df61 100644
--- a/arch/mips/configs/jazz_defconfig
+++ b/arch/mips/configs/jazz_defconfig
@@ -119,7 +119,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/lasat_defconfig b/arch/mips/configs/lasat_defconfig
index bc9159f..044074d 100644
--- a/arch/mips/configs/lasat_defconfig
+++ b/arch/mips/configs/lasat_defconfig
@@ -108,7 +108,6 @@ CONFIG_R5000_CPU_SCACHE=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 1ecdd3b..3f01870 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -139,7 +139,6 @@ CONFIG_SYS_SUPPORTS_SCHED_SMT=y
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 CONFIG_MIPS_MT_FPAFF=y
 # CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
 # CONFIG_CPU_HAS_SMARTMIPS is not set
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_MIPSR2_IRQ_EI=y
diff --git a/arch/mips/configs/markeins_defconfig b/arch/mips/configs/markeins_defconfig
index bad8901..d001f7e 100644
--- a/arch/mips/configs/markeins_defconfig
+++ b/arch/mips/configs/markeins_defconfig
@@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 2c0a631..7358454 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_MIPS_VPE_LOADER is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/msp71xx_defconfig b/arch/mips/configs/msp71xx_defconfig
index 84d6491..ecbc030 100644
--- a/arch/mips/configs/msp71xx_defconfig
+++ b/arch/mips/configs/msp71xx_defconfig
@@ -129,7 +129,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_SYS_SUPPORTS_MULTITHREADING=y
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index fadb351..9477f04 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -116,7 +116,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 9e21e33..be8091e 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index af67ed4..e74ba79 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -114,7 +114,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 7956f56..1d896fd 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_64BIT_PHYS_ADDR=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335-stb225_defconfig
index 2728caa..fef4d31 100644
--- a/arch/mips/configs/pnx8335-stb225_defconfig
+++ b/arch/mips/configs/pnx8335-stb225_defconfig
@@ -112,7 +112,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 723bd51..e10c711 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig
index b5052fb..5ed3c8d 100644
--- a/arch/mips/configs/pnx8550-stb810_defconfig
+++ b/arch/mips/configs/pnx8550-stb810_defconfig
@@ -112,7 +112,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig
index f28dc32..f40c3a0 100644
--- a/arch/mips/configs/rb532_defconfig
+++ b/arch/mips/configs/rb532_defconfig
@@ -113,7 +113,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig
index 1efe977..c69813b 100644
--- a/arch/mips/configs/rbtx49xx_defconfig
+++ b/arch/mips/configs/rbtx49xx_defconfig
@@ -142,7 +142,6 @@ CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 0f4da03..e53b8d0 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -124,7 +124,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index a9acaa2..7f38c0b 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -133,7 +133,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
 CONFIG_SB1_PASS_2_WORKAROUNDS=y
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index fc2c567..06acc74 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -120,7 +120,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index ea8249c..69feaf8 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -115,7 +115,6 @@ CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMTC is not set
 # CONFIG_MIPS_VPE_LOADER is not set
 # CONFIG_64BIT_PHYS_ADDR is not set
-CONFIG_CPU_HAS_LLSC=y
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
index 5a557e2..e95ff30 100644
--- a/arch/mips/dec/prom/memory.c
+++ b/arch/mips/dec/prom/memory.c
@@ -18,7 +18,7 @@
 #include <asm/sections.h>
 
 
-volatile unsigned long mem_err = 0;	/* So we know an error occurred */
+volatile unsigned long mem_err;		/* So we know an error occurred */
 
 /*
  * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 463136e..02f505f 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -18,7 +18,7 @@
 #include <asm/dec/ioasic.h>
 #include <asm/dec/machtype.h>
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
 	unsigned int year, mon, day, hour, min, sec, real_year;
 	unsigned long flags;
@@ -53,7 +53,8 @@ unsigned long read_persistent_clock(void)
 
 	year += real_year - 72 + 2000;
 
-	return mktime(year, mon, day, hour, min, sec);
+	ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+	ts->tv_nsec = 0;
 }
 
 /*
diff --git a/arch/mips/emma/markeins/setup.c b/arch/mips/emma/markeins/setup.c
index 335dc8c..9b3f51e 100644
--- a/arch/mips/emma/markeins/setup.c
+++ b/arch/mips/emma/markeins/setup.c
@@ -32,7 +32,7 @@
 
 extern void markeins_led(const char *);
 
-static int bus_frequency = 0;
+static int bus_frequency;
 
 static void markeins_machine_restart(char *command)
 {
diff --git a/arch/mips/fw/arc/Makefile b/arch/mips/fw/arc/Makefile
index 4f349ec..e0aaad4 100644
--- a/arch/mips/fw/arc/Makefile
+++ b/arch/mips/fw/arc/Makefile
@@ -8,3 +8,5 @@ lib-y				+= cmdline.o env.o file.o identify.o init.o \
 lib-$(CONFIG_ARC_MEMORY)	+= memory.o
 lib-$(CONFIG_ARC_CONSOLE)	+= arc_con.o
 lib-$(CONFIG_ARC_PROMLIB)	+= promlib.o
+
+EXTRA_CFLAGS			+= -Werror
diff --git a/arch/mips/fw/cfe/cfe_api.c b/arch/mips/fw/cfe/cfe_api.c
index 717db74..d06dc5a 100644
--- a/arch/mips/fw/cfe/cfe_api.c
+++ b/arch/mips/fw/cfe/cfe_api.c
@@ -45,8 +45,8 @@ int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
  * passed in two registers each, and CFE expects one.
  */
 
-static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0;
-static u64 cfe_handle = 0;
+static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb);
+static u64 cfe_handle;
 
 int cfe_init(u64 handle, u64 ept)
 {
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index eb7f01c..dd75d67 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -49,7 +49,7 @@
  */
 static __inline__ void atomic_add(int i, atomic_t * v)
 {
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -61,7 +61,7 @@ static __inline__ void atomic_add(int i, atomic_t * v)
 		"	.set	mips0					\n"
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -94,7 +94,7 @@ static __inline__ void atomic_add(int i, atomic_t * v)
  */
 static __inline__ void atomic_sub(int i, atomic_t * v)
 {
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -106,7 +106,7 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
 		"	.set	mips0					\n"
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -139,7 +139,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -153,7 +153,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -191,7 +191,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -205,7 +205,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -251,7 +251,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -269,7 +269,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		int temp;
 
 		__asm__ __volatile__(
@@ -428,7 +428,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
  */
 static __inline__ void atomic64_add(long i, atomic64_t * v)
 {
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -440,7 +440,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
 		"	.set	mips0					\n"
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -473,7 +473,7 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
  */
 static __inline__ void atomic64_sub(long i, atomic64_t * v)
 {
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -485,7 +485,7 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
 		"	.set	mips0					\n"
 		: "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter));
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -518,7 +518,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -532,7 +532,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -570,7 +570,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -584,7 +584,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -630,7 +630,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		long temp;
 
 		__asm__ __volatile__(
@@ -648,7 +648,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 		: "=&r" (result), "=&r" (temp), "=m" (v->counter)
 		: "Ir" (i), "m" (v->counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		long temp;
 
 		__asm__ __volatile__(
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index b1e9e97..84a3838 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -61,7 +61,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long temp;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	" __LL "%0, %1			# set_bit	\n"
@@ -72,7 +72,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 		: "=&r" (temp), "=m" (*m)
 		: "ir" (1UL << bit), "m" (*m));
 #ifdef CONFIG_CPU_MIPSR2
-	} else if (__builtin_constant_p(bit)) {
+	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
 		__asm__ __volatile__(
 		"1:	" __LL "%0, %1			# set_bit	\n"
 		"	" __INS "%0, %4, %2, 1				\n"
@@ -84,7 +84,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 		: "=&r" (temp), "=m" (*m)
 		: "ir" (bit), "m" (*m), "r" (~0));
 #endif /* CONFIG_CPU_MIPSR2 */
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	" __LL "%0, %1			# set_bit	\n"
@@ -126,7 +126,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long temp;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	" __LL "%0, %1			# clear_bit	\n"
@@ -137,7 +137,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
 		: "=&r" (temp), "=m" (*m)
 		: "ir" (~(1UL << bit)), "m" (*m));
 #ifdef CONFIG_CPU_MIPSR2
-	} else if (__builtin_constant_p(bit)) {
+	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
 		__asm__ __volatile__(
 		"1:	" __LL "%0, %1			# clear_bit	\n"
 		"	" __INS "%0, $0, %2, 1				\n"
@@ -149,7 +149,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
 		: "=&r" (temp), "=m" (*m)
 		: "ir" (bit), "m" (*m));
 #endif /* CONFIG_CPU_MIPSR2 */
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		__asm__ __volatile__(
 		"	.set	mips3					\n"
 		"1:	" __LL "%0, %1			# clear_bit	\n"
@@ -202,7 +202,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 {
 	unsigned short bit = nr & SZLONG_MASK;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -215,7 +215,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 		"	.set	mips0				\n"
 		: "=&r" (temp), "=m" (*m)
 		: "ir" (1UL << bit), "m" (*m));
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -260,7 +260,7 @@ static inline int test_and_set_bit(unsigned long nr,
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -275,7 +275,7 @@ static inline int test_and_set_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -328,7 +328,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
 	unsigned short bit = nr & SZLONG_MASK;
 	unsigned long res;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -343,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -397,7 +397,7 @@ static inline int test_and_clear_bit(unsigned long nr,
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -414,7 +414,7 @@ static inline int test_and_clear_bit(unsigned long nr,
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
 #ifdef CONFIG_CPU_MIPSR2
-	} else if (__builtin_constant_p(nr)) {
+	} else if (kernel_uses_llsc && __builtin_constant_p(nr)) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -431,7 +431,7 @@ static inline int test_and_clear_bit(unsigned long nr,
 		: "ir" (bit), "m" (*m)
 		: "memory");
 #endif
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -487,7 +487,7 @@ static inline int test_and_change_bit(unsigned long nr,
 
 	smp_llsc_mb();
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
@@ -502,7 +502,7 @@ static inline int test_and_change_bit(unsigned long nr,
 		: "=&r" (temp), "=m" (*m), "=&r" (res)
 		: "r" (1UL << bit), "m" (*m)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
 		unsigned long temp;
 
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 610fe3a..f5dfaf6 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -7,6 +7,7 @@
  * Copyright (C) 1995, 1996 Andreas Busse
  * Copyright (C) 1995, 1996 Stoned Elipot
  * Copyright (C) 1995, 1996 Paul M. Antoine.
+ * Copyright (C) 2009       Zhang Le
  */
 #ifndef _ASM_BOOTINFO_H
 #define _ASM_BOOTINFO_H
@@ -57,6 +58,17 @@
 #define	MACH_MIKROTIK_RB532	0	/* Mikrotik RouterBoard 532 	*/
 #define MACH_MIKROTIK_RB532A	1	/* Mikrotik RouterBoard 532A 	*/
 
+/*
+ * Valid machtype for Loongson family
+ */
+#define MACH_LOONGSON_UNKNOWN  0
+#define MACH_LEMOTE_FL2E       1
+#define MACH_LEMOTE_FL2F       2
+#define MACH_LEMOTE_ML2F7      3
+#define MACH_LEMOTE_YL2F89     4
+#define MACH_DEXXON_GDIUM2F10  5
+#define MACH_LOONGSON_END      6
+
 #define CL_SIZE			COMMAND_LINE_SIZE
 
 extern char *system_type;
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
index 4a812c3..815a438 100644
--- a/arch/mips/include/asm/cmpxchg.h
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -16,7 +16,7 @@
 ({									\
 	__typeof(*(m)) __ret;						\
 									\
-	if (cpu_has_llsc && R10000_LLSC_WAR) {				\
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {				\
 		__asm__ __volatile__(					\
 		"	.set	push				\n"	\
 		"	.set	noat				\n"	\
@@ -33,7 +33,7 @@
 		: "=&r" (__ret), "=R" (*m)				\
 		: "R" (*m), "Jr" (old), "Jr" (new)			\
 		: "memory");						\
-	} else if (cpu_has_llsc) {					\
+	} else if (kernel_uses_llsc) {					\
 		__asm__ __volatile__(					\
 		"	.set	push				\n"	\
 		"	.set	noat				\n"	\
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 8ab1d12..1f4df64 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -80,6 +80,9 @@
 #ifndef cpu_has_llsc
 #define cpu_has_llsc		(cpu_data[0].options & MIPS_CPU_LLSC)
 #endif
+#ifndef kernel_uses_llsc
+#define kernel_uses_llsc	cpu_has_llsc
+#endif
 #ifndef cpu_has_mips16
 #define cpu_has_mips16		(cpu_data[0].ases & MIPS_ASE_MIPS16)
 #endif
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 3bdc0e3..4b96d1a 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -113,6 +113,12 @@
 
 #define PRID_IMP_BCM4710	0x4000
 #define PRID_IMP_BCM3302	0x9000
+#define PRID_IMP_BCM6338	0x9000
+#define PRID_IMP_BCM6345	0x8000
+#define PRID_IMP_BCM6348	0x9100
+#define PRID_IMP_BCM4350	0xA000
+#define PRID_REV_BCM6358	0x0010
+#define PRID_REV_BCM6368	0x0030
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
@@ -210,6 +216,7 @@ enum cpu_type_enum {
 	 */
 	CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
 	CPU_ALCHEMY, CPU_PR4450, CPU_BCM3302, CPU_BCM4710,
+	CPU_BCM6338, CPU_BCM6345, CPU_BCM6348, CPU_BCM6358,
 
 	/*
 	 * MIPS64 class processors
diff --git a/arch/mips/include/asm/delay.h b/arch/mips/include/asm/delay.h
index d2d8949..e7cd782 100644
--- a/arch/mips/include/asm/delay.h
+++ b/arch/mips/include/asm/delay.h
@@ -11,6 +11,8 @@
 #ifndef _ASM_DELAY_H
 #define _ASM_DELAY_H
 
+#include <linux/param.h>
+
 extern void __delay(unsigned int loops);
 extern void __ndelay(unsigned int ns);
 extern void __udelay(unsigned int us);
diff --git a/arch/mips/include/asm/fixmap.h b/arch/mips/include/asm/fixmap.h
index 0f5caa1..efeddc8 100644
--- a/arch/mips/include/asm/fixmap.h
+++ b/arch/mips/include/asm/fixmap.h
@@ -67,11 +67,15 @@ enum fixed_addresses {
  * the start of the fixmap, and leave one page empty
  * at the top of mem..
  */
+#ifdef CONFIG_BCM63XX
+#define FIXADDR_TOP     ((unsigned long)(long)(int)0xff000000)
+#else
 #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX)
 #define FIXADDR_TOP	((unsigned long)(long)(int)(0xff000000 - 0x20000))
 #else
 #define FIXADDR_TOP	((unsigned long)(long)(int)0xfffe0000)
 #endif
+#endif
 #define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
 
diff --git a/arch/mips/include/asm/hardirq.h b/arch/mips/include/asm/hardirq.h
index 90bf399..c977a86 100644
--- a/arch/mips/include/asm/hardirq.h
+++ b/arch/mips/include/asm/hardirq.h
@@ -10,15 +10,9 @@
 #ifndef _ASM_HARDIRQ_H
 #define _ASM_HARDIRQ_H
 
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-typedef struct {
-	unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-
 extern void ack_bad_irq(unsigned int irq);
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
 
 #endif /* _ASM_HARDIRQ_H */
diff --git a/arch/mips/include/asm/lasat/lasat.h b/arch/mips/include/asm/lasat/lasat.h
index caeba1e..a1ada1c 100644
--- a/arch/mips/include/asm/lasat/lasat.h
+++ b/arch/mips/include/asm/lasat/lasat.h
@@ -227,6 +227,7 @@ extern void lasat_write_eeprom_info(void);
  * It is used for the bit-banging rtc and eeprom drivers */
 
 #include <linux/delay.h>
+#include <linux/smp.h>
 
 /* calculating with the slowest board with 100 MHz clock */
 #define LASAT_100_DIVIDER 20
diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
index f96fd59..361f4f1 100644
--- a/arch/mips/include/asm/local.h
+++ b/arch/mips/include/asm/local.h
@@ -29,7 +29,7 @@ static __inline__ long local_add_return(long i, local_t * l)
 {
 	unsigned long result;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long temp;
 
 		__asm__ __volatile__(
@@ -43,7 +43,7 @@ static __inline__ long local_add_return(long i, local_t * l)
 		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
 		: "Ir" (i), "m" (l->a.counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long temp;
 
 		__asm__ __volatile__(
@@ -74,7 +74,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
 {
 	unsigned long result;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long temp;
 
 		__asm__ __volatile__(
@@ -88,7 +88,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
 		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
 		: "Ir" (i), "m" (l->a.counter)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long temp;
 
 		__asm__ __volatile__(
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
index 127d4ed..feea001 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
@@ -578,6 +578,15 @@ static inline int irq_to_gpio(int irq)
 	return alchemy_irq_to_gpio(irq);
 }
 
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+}
+
 #endif	/* !CONFIG_ALCHEMY_GPIO_INDIRECT */
 
 
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h
new file mode 100644
index 0000000..fa3e7e6
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_board.h
@@ -0,0 +1,12 @@
+#ifndef BCM63XX_BOARD_H_
+#define BCM63XX_BOARD_H_
+
+const char *board_get_name(void);
+
+void board_prom_init(void);
+
+void board_setup(void);
+
+int board_register_devices(void);
+
+#endif /* ! BCM63XX_BOARD_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h
new file mode 100644
index 0000000..8fcf8df
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_clk.h
@@ -0,0 +1,11 @@
+#ifndef BCM63XX_CLK_H_
+#define BCM63XX_CLK_H_
+
+struct clk {
+	void		(*set)(struct clk *, int);
+	unsigned int	rate;
+	unsigned int	usage;
+	int		id;
+};
+
+#endif /* ! BCM63XX_CLK_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
new file mode 100644
index 0000000..b12c4ac
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -0,0 +1,538 @@
+#ifndef BCM63XX_CPU_H_
+#define BCM63XX_CPU_H_
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+/*
+ * Macro to fetch bcm63xx cpu id and revision, should be optimized at
+ * compile time if only one CPU support is enabled (idea stolen from
+ * arm mach-types)
+ */
+#define BCM6338_CPU_ID		0x6338
+#define BCM6345_CPU_ID		0x6345
+#define BCM6348_CPU_ID		0x6348
+#define BCM6358_CPU_ID		0x6358
+
+void __init bcm63xx_cpu_init(void);
+u16 __bcm63xx_get_cpu_id(void);
+u16 bcm63xx_get_cpu_rev(void);
+unsigned int bcm63xx_get_cpu_freq(void);
+
+#ifdef CONFIG_BCM63XX_CPU_6338
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id()	__bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id()	BCM6338_CPU_ID
+# endif
+# define BCMCPU_IS_6338()	(bcm63xx_get_cpu_id() == BCM6338_CPU_ID)
+#else
+# define BCMCPU_IS_6338()	(0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6345
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id()	__bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id()	BCM6345_CPU_ID
+# endif
+# define BCMCPU_IS_6345()	(bcm63xx_get_cpu_id() == BCM6345_CPU_ID)
+#else
+# define BCMCPU_IS_6345()	(0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6348
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id()	__bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id()	BCM6348_CPU_ID
+# endif
+# define BCMCPU_IS_6348()	(bcm63xx_get_cpu_id() == BCM6348_CPU_ID)
+#else
+# define BCMCPU_IS_6348()	(0)
+#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6358
+# ifdef bcm63xx_get_cpu_id
+#  undef bcm63xx_get_cpu_id
+#  define bcm63xx_get_cpu_id()	__bcm63xx_get_cpu_id()
+#  define BCMCPU_RUNTIME_DETECT
+# else
+#  define bcm63xx_get_cpu_id()	BCM6358_CPU_ID
+# endif
+# define BCMCPU_IS_6358()	(bcm63xx_get_cpu_id() == BCM6358_CPU_ID)
+#else
+# define BCMCPU_IS_6358()	(0)
+#endif
+
+#ifndef bcm63xx_get_cpu_id
+#error "No CPU support configured"
+#endif
+
+/*
+ * While registers sets are (mostly) the same across 63xx CPU, base
+ * address of these sets do change.
+ */
+enum bcm63xx_regs_set {
+	RSET_DSL_LMEM = 0,
+	RSET_PERF,
+	RSET_TIMER,
+	RSET_WDT,
+	RSET_UART0,
+	RSET_GPIO,
+	RSET_SPI,
+	RSET_UDC0,
+	RSET_OHCI0,
+	RSET_OHCI_PRIV,
+	RSET_USBH_PRIV,
+	RSET_MPI,
+	RSET_PCMCIA,
+	RSET_DSL,
+	RSET_ENET0,
+	RSET_ENET1,
+	RSET_ENETDMA,
+	RSET_EHCI0,
+	RSET_SDRAM,
+	RSET_MEMC,
+	RSET_DDR,
+};
+
+#define RSET_DSL_LMEM_SIZE		(64 * 1024 * 4)
+#define RSET_DSL_SIZE			4096
+#define RSET_WDT_SIZE			12
+#define RSET_ENET_SIZE			2048
+#define RSET_ENETDMA_SIZE		2048
+#define RSET_UART_SIZE			24
+#define RSET_UDC_SIZE			256
+#define RSET_OHCI_SIZE			256
+#define RSET_EHCI_SIZE			256
+#define RSET_PCMCIA_SIZE		12
+
+/*
+ * 6338 register sets base address
+ */
+#define BCM_6338_DSL_LMEM_BASE		(0xfff00000)
+#define BCM_6338_PERF_BASE		(0xfffe0000)
+#define BCM_6338_BB_BASE		(0xfffe0100)
+#define BCM_6338_TIMER_BASE		(0xfffe0200)
+#define BCM_6338_WDT_BASE		(0xfffe021c)
+#define BCM_6338_UART0_BASE		(0xfffe0300)
+#define BCM_6338_GPIO_BASE		(0xfffe0400)
+#define BCM_6338_SPI_BASE		(0xfffe0c00)
+#define BCM_6338_UDC0_BASE		(0xdeadbeef)
+#define BCM_6338_USBDMA_BASE		(0xfffe2400)
+#define BCM_6338_OHCI0_BASE		(0xdeadbeef)
+#define BCM_6338_OHCI_PRIV_BASE		(0xfffe3000)
+#define BCM_6338_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_6338_MPI_BASE		(0xfffe3160)
+#define BCM_6338_PCMCIA_BASE		(0xdeadbeef)
+#define BCM_6338_SDRAM_REGS_BASE	(0xfffe3100)
+#define BCM_6338_DSL_BASE		(0xfffe1000)
+#define BCM_6338_SAR_BASE		(0xfffe2000)
+#define BCM_6338_UBUS_BASE		(0xdeadbeef)
+#define BCM_6338_ENET0_BASE		(0xfffe2800)
+#define BCM_6338_ENET1_BASE		(0xdeadbeef)
+#define BCM_6338_ENETDMA_BASE		(0xfffe2400)
+#define BCM_6338_EHCI0_BASE		(0xdeadbeef)
+#define BCM_6338_SDRAM_BASE		(0xfffe3100)
+#define BCM_6338_MEMC_BASE		(0xdeadbeef)
+#define BCM_6338_DDR_BASE		(0xdeadbeef)
+
+/*
+ * 6345 register sets base address
+ */
+#define BCM_6345_DSL_LMEM_BASE		(0xfff00000)
+#define BCM_6345_PERF_BASE		(0xfffe0000)
+#define BCM_6345_BB_BASE		(0xfffe0100)
+#define BCM_6345_TIMER_BASE		(0xfffe0200)
+#define BCM_6345_WDT_BASE		(0xfffe021c)
+#define BCM_6345_UART0_BASE		(0xfffe0300)
+#define BCM_6345_GPIO_BASE		(0xfffe0400)
+#define BCM_6345_SPI_BASE		(0xdeadbeef)
+#define BCM_6345_UDC0_BASE		(0xdeadbeef)
+#define BCM_6345_USBDMA_BASE		(0xfffe2800)
+#define BCM_6345_ENET0_BASE		(0xfffe1800)
+#define BCM_6345_ENETDMA_BASE		(0xfffe2800)
+#define BCM_6345_PCMCIA_BASE		(0xfffe2028)
+#define BCM_6345_MPI_BASE		(0xdeadbeef)
+#define BCM_6345_OHCI0_BASE		(0xfffe2100)
+#define BCM_6345_OHCI_PRIV_BASE		(0xfffe2200)
+#define BCM_6345_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_6345_SDRAM_REGS_BASE	(0xfffe2300)
+#define BCM_6345_DSL_BASE		(0xdeadbeef)
+#define BCM_6345_SAR_BASE		(0xdeadbeef)
+#define BCM_6345_UBUS_BASE		(0xdeadbeef)
+#define BCM_6345_ENET1_BASE		(0xdeadbeef)
+#define BCM_6345_EHCI0_BASE		(0xdeadbeef)
+#define BCM_6345_SDRAM_BASE		(0xfffe2300)
+#define BCM_6345_MEMC_BASE		(0xdeadbeef)
+#define BCM_6345_DDR_BASE		(0xdeadbeef)
+
+/*
+ * 6348 register sets base address
+ */
+#define BCM_6348_DSL_LMEM_BASE		(0xfff00000)
+#define BCM_6348_PERF_BASE		(0xfffe0000)
+#define BCM_6348_TIMER_BASE		(0xfffe0200)
+#define BCM_6348_WDT_BASE		(0xfffe021c)
+#define BCM_6348_UART0_BASE		(0xfffe0300)
+#define BCM_6348_GPIO_BASE		(0xfffe0400)
+#define BCM_6348_SPI_BASE		(0xfffe0c00)
+#define BCM_6348_UDC0_BASE		(0xfffe1000)
+#define BCM_6348_OHCI0_BASE		(0xfffe1b00)
+#define BCM_6348_OHCI_PRIV_BASE		(0xfffe1c00)
+#define BCM_6348_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_6348_MPI_BASE		(0xfffe2000)
+#define BCM_6348_PCMCIA_BASE		(0xfffe2054)
+#define BCM_6348_SDRAM_REGS_BASE	(0xfffe2300)
+#define BCM_6348_DSL_BASE		(0xfffe3000)
+#define BCM_6348_ENET0_BASE		(0xfffe6000)
+#define BCM_6348_ENET1_BASE		(0xfffe6800)
+#define BCM_6348_ENETDMA_BASE		(0xfffe7000)
+#define BCM_6348_EHCI0_BASE		(0xdeadbeef)
+#define BCM_6348_SDRAM_BASE		(0xfffe2300)
+#define BCM_6348_MEMC_BASE		(0xdeadbeef)
+#define BCM_6348_DDR_BASE		(0xdeadbeef)
+
+/*
+ * 6358 register sets base address
+ */
+#define BCM_6358_DSL_LMEM_BASE		(0xfff00000)
+#define BCM_6358_PERF_BASE		(0xfffe0000)
+#define BCM_6358_TIMER_BASE		(0xfffe0040)
+#define BCM_6358_WDT_BASE		(0xfffe005c)
+#define BCM_6358_UART0_BASE		(0xfffe0100)
+#define BCM_6358_GPIO_BASE		(0xfffe0080)
+#define BCM_6358_SPI_BASE		(0xdeadbeef)
+#define BCM_6358_UDC0_BASE		(0xfffe0800)
+#define BCM_6358_OHCI0_BASE		(0xfffe1400)
+#define BCM_6358_OHCI_PRIV_BASE		(0xdeadbeef)
+#define BCM_6358_USBH_PRIV_BASE		(0xfffe1500)
+#define BCM_6358_MPI_BASE		(0xfffe1000)
+#define BCM_6358_PCMCIA_BASE		(0xfffe1054)
+#define BCM_6358_SDRAM_REGS_BASE	(0xfffe2300)
+#define BCM_6358_DSL_BASE		(0xfffe3000)
+#define BCM_6358_ENET0_BASE		(0xfffe4000)
+#define BCM_6358_ENET1_BASE		(0xfffe4800)
+#define BCM_6358_ENETDMA_BASE		(0xfffe5000)
+#define BCM_6358_EHCI0_BASE		(0xfffe1300)
+#define BCM_6358_SDRAM_BASE		(0xdeadbeef)
+#define BCM_6358_MEMC_BASE		(0xfffe1200)
+#define BCM_6358_DDR_BASE		(0xfffe12a0)
+
+
+extern const unsigned long *bcm63xx_regs_base;
+
+static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+	return bcm63xx_regs_base[set];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6338
+	switch (set) {
+	case RSET_DSL_LMEM:
+		return BCM_6338_DSL_LMEM_BASE;
+	case RSET_PERF:
+		return BCM_6338_PERF_BASE;
+	case RSET_TIMER:
+		return BCM_6338_TIMER_BASE;
+	case RSET_WDT:
+		return BCM_6338_WDT_BASE;
+	case RSET_UART0:
+		return BCM_6338_UART0_BASE;
+	case RSET_GPIO:
+		return BCM_6338_GPIO_BASE;
+	case RSET_SPI:
+		return BCM_6338_SPI_BASE;
+	case RSET_UDC0:
+		return BCM_6338_UDC0_BASE;
+	case RSET_OHCI0:
+		return BCM_6338_OHCI0_BASE;
+	case RSET_OHCI_PRIV:
+		return BCM_6338_OHCI_PRIV_BASE;
+	case RSET_USBH_PRIV:
+		return BCM_6338_USBH_PRIV_BASE;
+	case RSET_MPI:
+		return BCM_6338_MPI_BASE;
+	case RSET_PCMCIA:
+		return BCM_6338_PCMCIA_BASE;
+	case RSET_DSL:
+		return BCM_6338_DSL_BASE;
+	case RSET_ENET0:
+		return BCM_6338_ENET0_BASE;
+	case RSET_ENET1:
+		return BCM_6338_ENET1_BASE;
+	case RSET_ENETDMA:
+		return BCM_6338_ENETDMA_BASE;
+	case RSET_EHCI0:
+		return BCM_6338_EHCI0_BASE;
+	case RSET_SDRAM:
+		return BCM_6338_SDRAM_BASE;
+	case RSET_MEMC:
+		return BCM_6338_MEMC_BASE;
+	case RSET_DDR:
+		return BCM_6338_DDR_BASE;
+	}
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6345
+	switch (set) {
+	case RSET_DSL_LMEM:
+		return BCM_6345_DSL_LMEM_BASE;
+	case RSET_PERF:
+		return BCM_6345_PERF_BASE;
+	case RSET_TIMER:
+		return BCM_6345_TIMER_BASE;
+	case RSET_WDT:
+		return BCM_6345_WDT_BASE;
+	case RSET_UART0:
+		return BCM_6345_UART0_BASE;
+	case RSET_GPIO:
+		return BCM_6345_GPIO_BASE;
+	case RSET_SPI:
+		return BCM_6345_SPI_BASE;
+	case RSET_UDC0:
+		return BCM_6345_UDC0_BASE;
+	case RSET_OHCI0:
+		return BCM_6345_OHCI0_BASE;
+	case RSET_OHCI_PRIV:
+		return BCM_6345_OHCI_PRIV_BASE;
+	case RSET_USBH_PRIV:
+		return BCM_6345_USBH_PRIV_BASE;
+	case RSET_MPI:
+		return BCM_6345_MPI_BASE;
+	case RSET_PCMCIA:
+		return BCM_6345_PCMCIA_BASE;
+	case RSET_DSL:
+		return BCM_6345_DSL_BASE;
+	case RSET_ENET0:
+		return BCM_6345_ENET0_BASE;
+	case RSET_ENET1:
+		return BCM_6345_ENET1_BASE;
+	case RSET_ENETDMA:
+		return BCM_6345_ENETDMA_BASE;
+	case RSET_EHCI0:
+		return BCM_6345_EHCI0_BASE;
+	case RSET_SDRAM:
+		return BCM_6345_SDRAM_BASE;
+	case RSET_MEMC:
+		return BCM_6345_MEMC_BASE;
+	case RSET_DDR:
+		return BCM_6345_DDR_BASE;
+	}
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+	switch (set) {
+	case RSET_DSL_LMEM:
+		return BCM_6348_DSL_LMEM_BASE;
+	case RSET_PERF:
+		return BCM_6348_PERF_BASE;
+	case RSET_TIMER:
+		return BCM_6348_TIMER_BASE;
+	case RSET_WDT:
+		return BCM_6348_WDT_BASE;
+	case RSET_UART0:
+		return BCM_6348_UART0_BASE;
+	case RSET_GPIO:
+		return BCM_6348_GPIO_BASE;
+	case RSET_SPI:
+		return BCM_6348_SPI_BASE;
+	case RSET_UDC0:
+		return BCM_6348_UDC0_BASE;
+	case RSET_OHCI0:
+		return BCM_6348_OHCI0_BASE;
+	case RSET_OHCI_PRIV:
+		return BCM_6348_OHCI_PRIV_BASE;
+	case RSET_USBH_PRIV:
+		return BCM_6348_USBH_PRIV_BASE;
+	case RSET_MPI:
+		return BCM_6348_MPI_BASE;
+	case RSET_PCMCIA:
+		return BCM_6348_PCMCIA_BASE;
+	case RSET_DSL:
+		return BCM_6348_DSL_BASE;
+	case RSET_ENET0:
+		return BCM_6348_ENET0_BASE;
+	case RSET_ENET1:
+		return BCM_6348_ENET1_BASE;
+	case RSET_ENETDMA:
+		return BCM_6348_ENETDMA_BASE;
+	case RSET_EHCI0:
+		return BCM_6348_EHCI0_BASE;
+	case RSET_SDRAM:
+		return BCM_6348_SDRAM_BASE;
+	case RSET_MEMC:
+		return BCM_6348_MEMC_BASE;
+	case RSET_DDR:
+		return BCM_6348_DDR_BASE;
+	}
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6358
+	switch (set) {
+	case RSET_DSL_LMEM:
+		return BCM_6358_DSL_LMEM_BASE;
+	case RSET_PERF:
+		return BCM_6358_PERF_BASE;
+	case RSET_TIMER:
+		return BCM_6358_TIMER_BASE;
+	case RSET_WDT:
+		return BCM_6358_WDT_BASE;
+	case RSET_UART0:
+		return BCM_6358_UART0_BASE;
+	case RSET_GPIO:
+		return BCM_6358_GPIO_BASE;
+	case RSET_SPI:
+		return BCM_6358_SPI_BASE;
+	case RSET_UDC0:
+		return BCM_6358_UDC0_BASE;
+	case RSET_OHCI0:
+		return BCM_6358_OHCI0_BASE;
+	case RSET_OHCI_PRIV:
+		return BCM_6358_OHCI_PRIV_BASE;
+	case RSET_USBH_PRIV:
+		return BCM_6358_USBH_PRIV_BASE;
+	case RSET_MPI:
+		return BCM_6358_MPI_BASE;
+	case RSET_PCMCIA:
+		return BCM_6358_PCMCIA_BASE;
+	case RSET_ENET0:
+		return BCM_6358_ENET0_BASE;
+	case RSET_ENET1:
+		return BCM_6358_ENET1_BASE;
+	case RSET_ENETDMA:
+		return BCM_6358_ENETDMA_BASE;
+	case RSET_DSL:
+		return BCM_6358_DSL_BASE;
+	case RSET_EHCI0:
+		return BCM_6358_EHCI0_BASE;
+	case RSET_SDRAM:
+		return BCM_6358_SDRAM_BASE;
+	case RSET_MEMC:
+		return BCM_6358_MEMC_BASE;
+	case RSET_DDR:
+		return BCM_6358_DDR_BASE;
+	}
+#endif
+#endif
+	/* unreached */
+	return 0;
+}
+
+/*
+ * IRQ number changes across CPU too
+ */
+enum bcm63xx_irq {
+	IRQ_TIMER = 0,
+	IRQ_UART0,
+	IRQ_DSL,
+	IRQ_ENET0,
+	IRQ_ENET1,
+	IRQ_ENET_PHY,
+	IRQ_OHCI0,
+	IRQ_EHCI0,
+	IRQ_PCMCIA0,
+	IRQ_ENET0_RXDMA,
+	IRQ_ENET0_TXDMA,
+	IRQ_ENET1_RXDMA,
+	IRQ_ENET1_TXDMA,
+	IRQ_PCI,
+	IRQ_PCMCIA,
+};
+
+/*
+ * 6338 irqs
+ */
+#define BCM_6338_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
+#define BCM_6338_SPI_IRQ		(IRQ_INTERNAL_BASE + 1)
+#define BCM_6338_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
+#define BCM_6338_DG_IRQ			(IRQ_INTERNAL_BASE + 4)
+#define BCM_6338_DSL_IRQ		(IRQ_INTERNAL_BASE + 5)
+#define BCM_6338_ATM_IRQ		(IRQ_INTERNAL_BASE + 6)
+#define BCM_6338_UDC0_IRQ		(IRQ_INTERNAL_BASE + 7)
+#define BCM_6338_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)
+#define BCM_6338_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 9)
+#define BCM_6338_SDRAM_IRQ		(IRQ_INTERNAL_BASE + 10)
+#define BCM_6338_USB_CNTL_RX_DMA_IRQ	(IRQ_INTERNAL_BASE + 11)
+#define BCM_6338_USB_CNTL_TX_DMA_IRQ	(IRQ_INTERNAL_BASE + 12)
+#define BCM_6338_USB_BULK_RX_DMA_IRQ	(IRQ_INTERNAL_BASE + 13)
+#define BCM_6338_USB_BULK_TX_DMA_IRQ	(IRQ_INTERNAL_BASE + 14)
+#define BCM_6338_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 15)
+#define BCM_6338_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 16)
+#define BCM_6338_SDIO_IRQ		(IRQ_INTERNAL_BASE + 17)
+
+/*
+ * 6345 irqs
+ */
+#define BCM_6345_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
+#define BCM_6345_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
+#define BCM_6345_DSL_IRQ		(IRQ_INTERNAL_BASE + 3)
+#define BCM_6345_ATM_IRQ		(IRQ_INTERNAL_BASE + 4)
+#define BCM_6345_USB_IRQ		(IRQ_INTERNAL_BASE + 5)
+#define BCM_6345_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)
+#define BCM_6345_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 12)
+#define BCM_6345_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 1)
+#define BCM_6345_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 2)
+#define BCM_6345_EBI_RX_IRQ		(IRQ_INTERNAL_BASE + 13 + 5)
+#define BCM_6345_EBI_TX_IRQ		(IRQ_INTERNAL_BASE + 13 + 6)
+#define BCM_6345_RESERVED_RX_IRQ	(IRQ_INTERNAL_BASE + 13 + 9)
+#define BCM_6345_RESERVED_TX_IRQ	(IRQ_INTERNAL_BASE + 13 + 10)
+#define BCM_6345_USB_BULK_RX_DMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 13)
+#define BCM_6345_USB_BULK_TX_DMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 14)
+#define BCM_6345_USB_CNTL_RX_DMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 15)
+#define BCM_6345_USB_CNTL_TX_DMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 16)
+#define BCM_6345_USB_ISO_RX_DMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 17)
+#define BCM_6345_USB_ISO_TX_DMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 18)
+
+/*
+ * 6348 irqs
+ */
+#define BCM_6348_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
+#define BCM_6348_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
+#define BCM_6348_DSL_IRQ		(IRQ_INTERNAL_BASE + 4)
+#define BCM_6348_ENET1_IRQ		(IRQ_INTERNAL_BASE + 7)
+#define BCM_6348_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)
+#define BCM_6348_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 9)
+#define BCM_6348_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 12)
+#define BCM_6348_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 20)
+#define BCM_6348_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 21)
+#define BCM_6348_ENET1_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 22)
+#define BCM_6348_ENET1_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 23)
+#define BCM_6348_PCMCIA_IRQ		(IRQ_INTERNAL_BASE + 24)
+#define BCM_6348_PCI_IRQ		(IRQ_INTERNAL_BASE + 24)
+
+/*
+ * 6358 irqs
+ */
+#define BCM_6358_TIMER_IRQ		(IRQ_INTERNAL_BASE + 0)
+#define BCM_6358_UART0_IRQ		(IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 5)
+#define BCM_6358_ENET1_IRQ		(IRQ_INTERNAL_BASE + 6)
+#define BCM_6358_ENET0_IRQ		(IRQ_INTERNAL_BASE + 8)
+#define BCM_6358_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 9)
+#define BCM_6358_EHCI0_IRQ		(IRQ_INTERNAL_BASE + 10)
+#define BCM_6358_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 15)
+#define BCM_6358_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 16)
+#define BCM_6358_ENET1_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 17)
+#define BCM_6358_ENET1_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 18)
+#define BCM_6358_DSL_IRQ		(IRQ_INTERNAL_BASE + 29)
+#define BCM_6358_PCI_IRQ		(IRQ_INTERNAL_BASE + 31)
+#define BCM_6358_PCMCIA_IRQ		(IRQ_INTERNAL_BASE + 24)
+
+extern const int *bcm63xx_irqs;
+
+static inline int bcm63xx_get_irq_number(enum bcm63xx_irq irq)
+{
+	return bcm63xx_irqs[irq];
+}
+
+/*
+ * return installed memory size
+ */
+unsigned int bcm63xx_get_memory_size(void);
+
+#endif /* !BCM63XX_CPU_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h
new file mode 100644
index 0000000..b1821c8
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cs.h
@@ -0,0 +1,10 @@
+#ifndef BCM63XX_CS_H
+#define BCM63XX_CS_H
+
+int bcm63xx_set_cs_base(unsigned int cs, u32 base, unsigned int size);
+int bcm63xx_set_cs_timing(unsigned int cs, unsigned int wait,
+			   unsigned int setup, unsigned int hold);
+int bcm63xx_set_cs_param(unsigned int cs, u32 flags);
+int bcm63xx_set_cs_status(unsigned int cs, int enable);
+
+#endif /* !BCM63XX_CS_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h
new file mode 100644
index 0000000..b587d45
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_dsp.h
@@ -0,0 +1,13 @@
+#ifndef __BCM63XX_DSP_H
+#define __BCM63XX_DSP_H
+
+struct bcm63xx_dsp_platform_data {
+	unsigned gpio_rst;
+	unsigned gpio_int;
+	unsigned cs;
+	unsigned ext_irq;
+};
+
+int __init bcm63xx_dsp_register(const struct bcm63xx_dsp_platform_data *pd);
+
+#endif /* __BCM63XX_DSP_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
new file mode 100644
index 0000000..d53f611
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
@@ -0,0 +1,45 @@
+#ifndef BCM63XX_DEV_ENET_H_
+#define BCM63XX_DEV_ENET_H_
+
+#include <linux/if_ether.h>
+#include <linux/init.h>
+
+/*
+ * on board ethernet platform data
+ */
+struct bcm63xx_enet_platform_data {
+	char mac_addr[ETH_ALEN];
+
+	int has_phy;
+
+	/* if has_phy, then set use_internal_phy */
+	int use_internal_phy;
+
+	/* or fill phy info to use an external one */
+	int phy_id;
+	int has_phy_interrupt;
+	int phy_interrupt;
+
+	/* if has_phy, use autonegociated pause parameters or force
+	 * them */
+	int pause_auto;
+	int pause_rx;
+	int pause_tx;
+
+	/* if !has_phy, set desired forced speed/duplex */
+	int force_speed_100;
+	int force_duplex_full;
+
+	/* if !has_phy, set callback to perform mii device
+	 * init/remove */
+	int (*mii_config)(struct net_device *dev, int probe,
+			  int (*mii_read)(struct net_device *dev,
+					  int phy_id, int reg),
+			  void (*mii_write)(struct net_device *dev,
+					    int phy_id, int reg, int val));
+};
+
+int __init bcm63xx_enet_register(int unit,
+				 const struct bcm63xx_enet_platform_data *pd);
+
+#endif /* ! BCM63XX_DEV_ENET_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h
new file mode 100644
index 0000000..c549344
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pci.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_PCI_H_
+#define BCM63XX_DEV_PCI_H_
+
+extern int bcm63xx_pci_enabled;
+
+#endif /* BCM63XX_DEV_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
new file mode 100644
index 0000000..76a0b72
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -0,0 +1,22 @@
+#ifndef BCM63XX_GPIO_H
+#define BCM63XX_GPIO_H
+
+#include <linux/init.h>
+
+int __init bcm63xx_gpio_init(void);
+
+static inline unsigned long bcm63xx_gpio_count(void)
+{
+	switch (bcm63xx_get_cpu_id()) {
+	case BCM6358_CPU_ID:
+		return 40;
+	case BCM6348_CPU_ID:
+	default:
+		return 37;
+	}
+}
+
+#define GPIO_DIR_OUT	0x0
+#define GPIO_DIR_IN	0x1
+
+#endif /* !BCM63XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
new file mode 100644
index 0000000..91180fa
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
@@ -0,0 +1,93 @@
+#ifndef BCM63XX_IO_H_
+#define BCM63XX_IO_H_
+
+#include "bcm63xx_cpu.h"
+
+/*
+ * Physical memory map, RAM is mapped at 0x0.
+ *
+ * Note that size MUST be a power of two.
+ */
+#define BCM_PCMCIA_COMMON_BASE_PA	(0x20000000)
+#define BCM_PCMCIA_COMMON_SIZE		(16 * 1024 * 1024)
+#define BCM_PCMCIA_COMMON_END_PA	(BCM_PCMCIA_COMMON_BASE_PA +	\
+					 BCM_PCMCIA_COMMON_SIZE - 1)
+
+#define BCM_PCMCIA_ATTR_BASE_PA		(0x21000000)
+#define BCM_PCMCIA_ATTR_SIZE		(16 * 1024 * 1024)
+#define BCM_PCMCIA_ATTR_END_PA		(BCM_PCMCIA_ATTR_BASE_PA +	\
+					 BCM_PCMCIA_ATTR_SIZE - 1)
+
+#define BCM_PCMCIA_IO_BASE_PA		(0x22000000)
+#define BCM_PCMCIA_IO_SIZE		(64 * 1024)
+#define BCM_PCMCIA_IO_END_PA		(BCM_PCMCIA_IO_BASE_PA +	\
+					BCM_PCMCIA_IO_SIZE - 1)
+
+#define BCM_PCI_MEM_BASE_PA		(0x30000000)
+#define BCM_PCI_MEM_SIZE		(128 * 1024 * 1024)
+#define BCM_PCI_MEM_END_PA		(BCM_PCI_MEM_BASE_PA +		\
+					BCM_PCI_MEM_SIZE - 1)
+
+#define BCM_PCI_IO_BASE_PA		(0x08000000)
+#define BCM_PCI_IO_SIZE			(64 * 1024)
+#define BCM_PCI_IO_END_PA		(BCM_PCI_IO_BASE_PA +		\
+					BCM_PCI_IO_SIZE - 1)
+#define BCM_PCI_IO_HALF_PA		(BCM_PCI_IO_BASE_PA +		\
+					(BCM_PCI_IO_SIZE / 2) - 1)
+
+#define BCM_CB_MEM_BASE_PA		(0x38000000)
+#define BCM_CB_MEM_SIZE			(128 * 1024 * 1024)
+#define BCM_CB_MEM_END_PA		(BCM_CB_MEM_BASE_PA +		\
+					BCM_CB_MEM_SIZE - 1)
+
+
+/*
+ * Internal registers are accessed through KSEG3
+ */
+#define BCM_REGS_VA(x)	((void __iomem *)(x))
+
+#define bcm_readb(a)	(*(volatile unsigned char *)	BCM_REGS_VA(a))
+#define bcm_readw(a)	(*(volatile unsigned short *)	BCM_REGS_VA(a))
+#define bcm_readl(a)	(*(volatile unsigned int *)	BCM_REGS_VA(a))
+#define bcm_writeb(v, a) (*(volatile unsigned char *) BCM_REGS_VA((a)) = (v))
+#define bcm_writew(v, a) (*(volatile unsigned short *) BCM_REGS_VA((a)) = (v))
+#define bcm_writel(v, a) (*(volatile unsigned int *) BCM_REGS_VA((a)) = (v))
+
+/*
+ * IO helpers to access register set for current CPU
+ */
+#define bcm_rset_readb(s, o)	bcm_readb(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_readw(s, o)	bcm_readw(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_readl(s, o)	bcm_readl(bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writeb(s, v, o)	bcm_writeb((v), \
+					bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writew(s, v, o)	bcm_writew((v), \
+					bcm63xx_regset_address(s) + (o))
+#define bcm_rset_writel(s, v, o)	bcm_writel((v), \
+					bcm63xx_regset_address(s) + (o))
+
+/*
+ * helpers for frequently used register sets
+ */
+#define bcm_perf_readl(o)	bcm_rset_readl(RSET_PERF, (o))
+#define bcm_perf_writel(v, o)	bcm_rset_writel(RSET_PERF, (v), (o))
+#define bcm_timer_readl(o)	bcm_rset_readl(RSET_TIMER, (o))
+#define bcm_timer_writel(v, o)	bcm_rset_writel(RSET_TIMER, (v), (o))
+#define bcm_wdt_readl(o)	bcm_rset_readl(RSET_WDT, (o))
+#define bcm_wdt_writel(v, o)	bcm_rset_writel(RSET_WDT, (v), (o))
+#define bcm_gpio_readl(o)	bcm_rset_readl(RSET_GPIO, (o))
+#define bcm_gpio_writel(v, o)	bcm_rset_writel(RSET_GPIO, (v), (o))
+#define bcm_uart0_readl(o)	bcm_rset_readl(RSET_UART0, (o))
+#define bcm_uart0_writel(v, o)	bcm_rset_writel(RSET_UART0, (v), (o))
+#define bcm_mpi_readl(o)	bcm_rset_readl(RSET_MPI, (o))
+#define bcm_mpi_writel(v, o)	bcm_rset_writel(RSET_MPI, (v), (o))
+#define bcm_pcmcia_readl(o)	bcm_rset_readl(RSET_PCMCIA, (o))
+#define bcm_pcmcia_writel(v, o)	bcm_rset_writel(RSET_PCMCIA, (v), (o))
+#define bcm_sdram_readl(o)	bcm_rset_readl(RSET_SDRAM, (o))
+#define bcm_sdram_writel(v, o)	bcm_rset_writel(RSET_SDRAM, (v), (o))
+#define bcm_memc_readl(o)	bcm_rset_readl(RSET_MEMC, (o))
+#define bcm_memc_writel(v, o)	bcm_rset_writel(RSET_MEMC, (v), (o))
+#define bcm_ddr_readl(o)	bcm_rset_readl(RSET_DDR, (o))
+#define bcm_ddr_writel(v, o)	bcm_rset_writel(RSET_DDR, (v), (o))
+
+#endif /* ! BCM63XX_IO_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
new file mode 100644
index 0000000..5f95577
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
@@ -0,0 +1,15 @@
+#ifndef BCM63XX_IRQ_H_
+#define BCM63XX_IRQ_H_
+
+#include <bcm63xx_cpu.h>
+
+#define IRQ_MIPS_BASE			0
+#define IRQ_INTERNAL_BASE		8
+
+#define IRQ_EXT_BASE			(IRQ_MIPS_BASE + 3)
+#define IRQ_EXT_0			(IRQ_EXT_BASE + 0)
+#define IRQ_EXT_1			(IRQ_EXT_BASE + 1)
+#define IRQ_EXT_2			(IRQ_EXT_BASE + 2)
+#define IRQ_EXT_3			(IRQ_EXT_BASE + 3)
+
+#endif /* ! BCM63XX_IRQ_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
new file mode 100644
index 0000000..ed4ccec
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -0,0 +1,773 @@
+#ifndef BCM63XX_REGS_H_
+#define BCM63XX_REGS_H_
+
+/*************************************************************************
+ * _REG relative to RSET_PERF
+ *************************************************************************/
+
+/* Chip Identifier / Revision register */
+#define PERF_REV_REG			0x0
+#define REV_CHIPID_SHIFT		16
+#define REV_CHIPID_MASK			(0xffff << REV_CHIPID_SHIFT)
+#define REV_REVID_SHIFT			0
+#define REV_REVID_MASK			(0xffff << REV_REVID_SHIFT)
+
+/* Clock Control register */
+#define PERF_CKCTL_REG			0x4
+
+#define CKCTL_6338_ADSLPHY_EN		(1 << 0)
+#define CKCTL_6338_MPI_EN		(1 << 1)
+#define CKCTL_6338_DRAM_EN		(1 << 2)
+#define CKCTL_6338_ENET_EN		(1 << 4)
+#define CKCTL_6338_USBS_EN		(1 << 4)
+#define CKCTL_6338_SAR_EN		(1 << 5)
+#define CKCTL_6338_SPI_EN		(1 << 9)
+
+#define CKCTL_6338_ALL_SAFE_EN		(CKCTL_6338_ADSLPHY_EN |	\
+					CKCTL_6338_MPI_EN |		\
+					CKCTL_6338_ENET_EN |		\
+					CKCTL_6338_SAR_EN |		\
+					CKCTL_6338_SPI_EN)
+
+#define CKCTL_6345_CPU_EN		(1 << 0)
+#define CKCTL_6345_BUS_EN		(1 << 1)
+#define CKCTL_6345_EBI_EN		(1 << 2)
+#define CKCTL_6345_UART_EN		(1 << 3)
+#define CKCTL_6345_ADSLPHY_EN		(1 << 4)
+#define CKCTL_6345_ENET_EN		(1 << 7)
+#define CKCTL_6345_USBH_EN		(1 << 8)
+
+#define CKCTL_6345_ALL_SAFE_EN		(CKCTL_6345_ENET_EN |	\
+					CKCTL_6345_USBH_EN |	\
+					CKCTL_6345_ADSLPHY_EN)
+
+#define CKCTL_6348_ADSLPHY_EN		(1 << 0)
+#define CKCTL_6348_MPI_EN		(1 << 1)
+#define CKCTL_6348_SDRAM_EN		(1 << 2)
+#define CKCTL_6348_M2M_EN		(1 << 3)
+#define CKCTL_6348_ENET_EN		(1 << 4)
+#define CKCTL_6348_SAR_EN		(1 << 5)
+#define CKCTL_6348_USBS_EN		(1 << 6)
+#define CKCTL_6348_USBH_EN		(1 << 8)
+#define CKCTL_6348_SPI_EN		(1 << 9)
+
+#define CKCTL_6348_ALL_SAFE_EN		(CKCTL_6348_ADSLPHY_EN |	\
+					CKCTL_6348_M2M_EN |		\
+					CKCTL_6348_ENET_EN |		\
+					CKCTL_6348_SAR_EN |		\
+					CKCTL_6348_USBS_EN |		\
+					CKCTL_6348_USBH_EN |		\
+					CKCTL_6348_SPI_EN)
+
+#define CKCTL_6358_ENET_EN		(1 << 4)
+#define CKCTL_6358_ADSLPHY_EN		(1 << 5)
+#define CKCTL_6358_PCM_EN		(1 << 8)
+#define CKCTL_6358_SPI_EN		(1 << 9)
+#define CKCTL_6358_USBS_EN		(1 << 10)
+#define CKCTL_6358_SAR_EN		(1 << 11)
+#define CKCTL_6358_EMUSB_EN		(1 << 17)
+#define CKCTL_6358_ENET0_EN		(1 << 18)
+#define CKCTL_6358_ENET1_EN		(1 << 19)
+#define CKCTL_6358_USBSU_EN		(1 << 20)
+#define CKCTL_6358_EPHY_EN		(1 << 21)
+
+#define CKCTL_6358_ALL_SAFE_EN		(CKCTL_6358_ENET_EN |		\
+					CKCTL_6358_ADSLPHY_EN |		\
+					CKCTL_6358_PCM_EN |		\
+					CKCTL_6358_SPI_EN |		\
+					CKCTL_6358_USBS_EN |		\
+					CKCTL_6358_SAR_EN |		\
+					CKCTL_6358_EMUSB_EN |		\
+					CKCTL_6358_ENET0_EN |		\
+					CKCTL_6358_ENET1_EN |		\
+					CKCTL_6358_USBSU_EN |		\
+					CKCTL_6358_EPHY_EN)
+
+/* System PLL Control register  */
+#define PERF_SYS_PLL_CTL_REG		0x8
+#define SYS_PLL_SOFT_RESET		0x1
+
+/* Interrupt Mask register */
+#define PERF_IRQMASK_REG		0xc
+#define PERF_IRQSTAT_REG		0x10
+
+/* Interrupt Status register */
+#define PERF_IRQSTAT_REG		0x10
+
+/* External Interrupt Configuration register */
+#define PERF_EXTIRQ_CFG_REG		0x14
+#define EXTIRQ_CFG_SENSE(x)		(1 << (x))
+#define EXTIRQ_CFG_STAT(x)		(1 << (x + 5))
+#define EXTIRQ_CFG_CLEAR(x)		(1 << (x + 10))
+#define EXTIRQ_CFG_MASK(x)		(1 << (x + 15))
+#define EXTIRQ_CFG_BOTHEDGE(x)		(1 << (x + 20))
+#define EXTIRQ_CFG_LEVELSENSE(x)	(1 << (x + 25))
+
+#define EXTIRQ_CFG_CLEAR_ALL		(0xf << 10)
+#define EXTIRQ_CFG_MASK_ALL		(0xf << 15)
+
+/* Soft Reset register */
+#define PERF_SOFTRESET_REG		0x28
+
+#define SOFTRESET_6338_SPI_MASK		(1 << 0)
+#define SOFTRESET_6338_ENET_MASK	(1 << 2)
+#define SOFTRESET_6338_USBH_MASK	(1 << 3)
+#define SOFTRESET_6338_USBS_MASK	(1 << 4)
+#define SOFTRESET_6338_ADSL_MASK	(1 << 5)
+#define SOFTRESET_6338_DMAMEM_MASK	(1 << 6)
+#define SOFTRESET_6338_SAR_MASK		(1 << 7)
+#define SOFTRESET_6338_ACLC_MASK	(1 << 8)
+#define SOFTRESET_6338_ADSLMIPSPLL_MASK	(1 << 10)
+#define SOFTRESET_6338_ALL	 (SOFTRESET_6338_SPI_MASK |		\
+				  SOFTRESET_6338_ENET_MASK |		\
+				  SOFTRESET_6338_USBH_MASK |		\
+				  SOFTRESET_6338_USBS_MASK |		\
+				  SOFTRESET_6338_ADSL_MASK |		\
+				  SOFTRESET_6338_DMAMEM_MASK |		\
+				  SOFTRESET_6338_SAR_MASK |		\
+				  SOFTRESET_6338_ACLC_MASK |		\
+				  SOFTRESET_6338_ADSLMIPSPLL_MASK)
+
+#define SOFTRESET_6348_SPI_MASK		(1 << 0)
+#define SOFTRESET_6348_ENET_MASK	(1 << 2)
+#define SOFTRESET_6348_USBH_MASK	(1 << 3)
+#define SOFTRESET_6348_USBS_MASK	(1 << 4)
+#define SOFTRESET_6348_ADSL_MASK	(1 << 5)
+#define SOFTRESET_6348_DMAMEM_MASK	(1 << 6)
+#define SOFTRESET_6348_SAR_MASK		(1 << 7)
+#define SOFTRESET_6348_ACLC_MASK	(1 << 8)
+#define SOFTRESET_6348_ADSLMIPSPLL_MASK	(1 << 10)
+
+#define SOFTRESET_6348_ALL	 (SOFTRESET_6348_SPI_MASK |		\
+				  SOFTRESET_6348_ENET_MASK |		\
+				  SOFTRESET_6348_USBH_MASK |		\
+				  SOFTRESET_6348_USBS_MASK |		\
+				  SOFTRESET_6348_ADSL_MASK |		\
+				  SOFTRESET_6348_DMAMEM_MASK |		\
+				  SOFTRESET_6348_SAR_MASK |		\
+				  SOFTRESET_6348_ACLC_MASK |		\
+				  SOFTRESET_6348_ADSLMIPSPLL_MASK)
+
+/* MIPS PLL control register */
+#define PERF_MIPSPLLCTL_REG		0x34
+#define MIPSPLLCTL_N1_SHIFT		20
+#define MIPSPLLCTL_N1_MASK		(0x7 << MIPSPLLCTL_N1_SHIFT)
+#define MIPSPLLCTL_N2_SHIFT		15
+#define MIPSPLLCTL_N2_MASK		(0x1f << MIPSPLLCTL_N2_SHIFT)
+#define MIPSPLLCTL_M1REF_SHIFT		12
+#define MIPSPLLCTL_M1REF_MASK		(0x7 << MIPSPLLCTL_M1REF_SHIFT)
+#define MIPSPLLCTL_M2REF_SHIFT		9
+#define MIPSPLLCTL_M2REF_MASK		(0x7 << MIPSPLLCTL_M2REF_SHIFT)
+#define MIPSPLLCTL_M1CPU_SHIFT		6
+#define MIPSPLLCTL_M1CPU_MASK		(0x7 << MIPSPLLCTL_M1CPU_SHIFT)
+#define MIPSPLLCTL_M1BUS_SHIFT		3
+#define MIPSPLLCTL_M1BUS_MASK		(0x7 << MIPSPLLCTL_M1BUS_SHIFT)
+#define MIPSPLLCTL_M2BUS_SHIFT		0
+#define MIPSPLLCTL_M2BUS_MASK		(0x7 << MIPSPLLCTL_M2BUS_SHIFT)
+
+/* ADSL PHY PLL Control register */
+#define PERF_ADSLPLLCTL_REG		0x38
+#define ADSLPLLCTL_N1_SHIFT		20
+#define ADSLPLLCTL_N1_MASK		(0x7 << ADSLPLLCTL_N1_SHIFT)
+#define ADSLPLLCTL_N2_SHIFT		15
+#define ADSLPLLCTL_N2_MASK		(0x1f << ADSLPLLCTL_N2_SHIFT)
+#define ADSLPLLCTL_M1REF_SHIFT		12
+#define ADSLPLLCTL_M1REF_MASK		(0x7 << ADSLPLLCTL_M1REF_SHIFT)
+#define ADSLPLLCTL_M2REF_SHIFT		9
+#define ADSLPLLCTL_M2REF_MASK		(0x7 << ADSLPLLCTL_M2REF_SHIFT)
+#define ADSLPLLCTL_M1CPU_SHIFT		6
+#define ADSLPLLCTL_M1CPU_MASK		(0x7 << ADSLPLLCTL_M1CPU_SHIFT)
+#define ADSLPLLCTL_M1BUS_SHIFT		3
+#define ADSLPLLCTL_M1BUS_MASK		(0x7 << ADSLPLLCTL_M1BUS_SHIFT)
+#define ADSLPLLCTL_M2BUS_SHIFT		0
+#define ADSLPLLCTL_M2BUS_MASK		(0x7 << ADSLPLLCTL_M2BUS_SHIFT)
+
+#define ADSLPLLCTL_VAL(n1, n2, m1ref, m2ref, m1cpu, m1bus, m2bus)	\
+				(((n1) << ADSLPLLCTL_N1_SHIFT) |	\
+				((n2) << ADSLPLLCTL_N2_SHIFT) |		\
+				((m1ref) << ADSLPLLCTL_M1REF_SHIFT) |	\
+				((m2ref) << ADSLPLLCTL_M2REF_SHIFT) |	\
+				((m1cpu) << ADSLPLLCTL_M1CPU_SHIFT) |	\
+				((m1bus) << ADSLPLLCTL_M1BUS_SHIFT) |	\
+				((m2bus) << ADSLPLLCTL_M2BUS_SHIFT))
+
+
+/*************************************************************************
+ * _REG relative to RSET_TIMER
+ *************************************************************************/
+
+#define BCM63XX_TIMER_COUNT		4
+#define TIMER_T0_ID			0
+#define TIMER_T1_ID			1
+#define TIMER_T2_ID			2
+#define TIMER_WDT_ID			3
+
+/* Timer irqstat register */
+#define TIMER_IRQSTAT_REG		0
+#define TIMER_IRQSTAT_TIMER_CAUSE(x)	(1 << (x))
+#define TIMER_IRQSTAT_TIMER0_CAUSE	(1 << 0)
+#define TIMER_IRQSTAT_TIMER1_CAUSE	(1 << 1)
+#define TIMER_IRQSTAT_TIMER2_CAUSE	(1 << 2)
+#define TIMER_IRQSTAT_WDT_CAUSE		(1 << 3)
+#define TIMER_IRQSTAT_TIMER_IR_EN(x)	(1 << ((x) + 8))
+#define TIMER_IRQSTAT_TIMER0_IR_EN	(1 << 8)
+#define TIMER_IRQSTAT_TIMER1_IR_EN	(1 << 9)
+#define TIMER_IRQSTAT_TIMER2_IR_EN	(1 << 10)
+
+/* Timer control register */
+#define TIMER_CTLx_REG(x)		(0x4 + (x * 4))
+#define TIMER_CTL0_REG			0x4
+#define TIMER_CTL1_REG			0x8
+#define TIMER_CTL2_REG			0xC
+#define TIMER_CTL_COUNTDOWN_MASK	(0x3fffffff)
+#define TIMER_CTL_MONOTONIC_MASK	(1 << 30)
+#define TIMER_CTL_ENABLE_MASK		(1 << 31)
+
+
+/*************************************************************************
+ * _REG relative to RSET_WDT
+ *************************************************************************/
+
+/* Watchdog default count register */
+#define WDT_DEFVAL_REG			0x0
+
+/* Watchdog control register */
+#define WDT_CTL_REG			0x4
+
+/* Watchdog control register constants */
+#define WDT_START_1			(0xff00)
+#define WDT_START_2			(0x00ff)
+#define WDT_STOP_1			(0xee00)
+#define WDT_STOP_2			(0x00ee)
+
+/* Watchdog reset length register */
+#define WDT_RSTLEN_REG			0x8
+
+
+/*************************************************************************
+ * _REG relative to RSET_UARTx
+ *************************************************************************/
+
+/* UART Control Register */
+#define UART_CTL_REG			0x0
+#define UART_CTL_RXTMOUTCNT_SHIFT	0
+#define UART_CTL_RXTMOUTCNT_MASK	(0x1f << UART_CTL_RXTMOUTCNT_SHIFT)
+#define UART_CTL_RSTTXDN_SHIFT		5
+#define UART_CTL_RSTTXDN_MASK		(1 << UART_CTL_RSTTXDN_SHIFT)
+#define UART_CTL_RSTRXFIFO_SHIFT		6
+#define UART_CTL_RSTRXFIFO_MASK		(1 << UART_CTL_RSTRXFIFO_SHIFT)
+#define UART_CTL_RSTTXFIFO_SHIFT		7
+#define UART_CTL_RSTTXFIFO_MASK		(1 << UART_CTL_RSTTXFIFO_SHIFT)
+#define UART_CTL_STOPBITS_SHIFT		8
+#define UART_CTL_STOPBITS_MASK		(0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_1		(0x7 << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_STOPBITS_2		(0xf << UART_CTL_STOPBITS_SHIFT)
+#define UART_CTL_BITSPERSYM_SHIFT	12
+#define UART_CTL_BITSPERSYM_MASK	(0x3 << UART_CTL_BITSPERSYM_SHIFT)
+#define UART_CTL_XMITBRK_SHIFT		14
+#define UART_CTL_XMITBRK_MASK		(1 << UART_CTL_XMITBRK_SHIFT)
+#define UART_CTL_RSVD_SHIFT		15
+#define UART_CTL_RSVD_MASK		(1 << UART_CTL_RSVD_SHIFT)
+#define UART_CTL_RXPAREVEN_SHIFT		16
+#define UART_CTL_RXPAREVEN_MASK		(1 << UART_CTL_RXPAREVEN_SHIFT)
+#define UART_CTL_RXPAREN_SHIFT		17
+#define UART_CTL_RXPAREN_MASK		(1 << UART_CTL_RXPAREN_SHIFT)
+#define UART_CTL_TXPAREVEN_SHIFT		18
+#define UART_CTL_TXPAREVEN_MASK		(1 << UART_CTL_TXPAREVEN_SHIFT)
+#define UART_CTL_TXPAREN_SHIFT		18
+#define UART_CTL_TXPAREN_MASK		(1 << UART_CTL_TXPAREN_SHIFT)
+#define UART_CTL_LOOPBACK_SHIFT		20
+#define UART_CTL_LOOPBACK_MASK		(1 << UART_CTL_LOOPBACK_SHIFT)
+#define UART_CTL_RXEN_SHIFT		21
+#define UART_CTL_RXEN_MASK		(1 << UART_CTL_RXEN_SHIFT)
+#define UART_CTL_TXEN_SHIFT		22
+#define UART_CTL_TXEN_MASK		(1 << UART_CTL_TXEN_SHIFT)
+#define UART_CTL_BRGEN_SHIFT		23
+#define UART_CTL_BRGEN_MASK		(1 << UART_CTL_BRGEN_SHIFT)
+
+/* UART Baudword register */
+#define UART_BAUD_REG			0x4
+
+/* UART Misc Control register */
+#define UART_MCTL_REG			0x8
+#define UART_MCTL_DTR_SHIFT		0
+#define UART_MCTL_DTR_MASK		(1 << UART_MCTL_DTR_SHIFT)
+#define UART_MCTL_RTS_SHIFT		1
+#define UART_MCTL_RTS_MASK		(1 << UART_MCTL_RTS_SHIFT)
+#define UART_MCTL_RXFIFOTHRESH_SHIFT	8
+#define UART_MCTL_RXFIFOTHRESH_MASK	(0xf << UART_MCTL_RXFIFOTHRESH_SHIFT)
+#define UART_MCTL_TXFIFOTHRESH_SHIFT	12
+#define UART_MCTL_TXFIFOTHRESH_MASK	(0xf << UART_MCTL_TXFIFOTHRESH_SHIFT)
+#define UART_MCTL_RXFIFOFILL_SHIFT	16
+#define UART_MCTL_RXFIFOFILL_MASK	(0x1f << UART_MCTL_RXFIFOFILL_SHIFT)
+#define UART_MCTL_TXFIFOFILL_SHIFT	24
+#define UART_MCTL_TXFIFOFILL_MASK	(0x1f << UART_MCTL_TXFIFOFILL_SHIFT)
+
+/* UART External Input Configuration register */
+#define UART_EXTINP_REG			0xc
+#define UART_EXTINP_RI_SHIFT		0
+#define UART_EXTINP_RI_MASK		(1 << UART_EXTINP_RI_SHIFT)
+#define UART_EXTINP_CTS_SHIFT		1
+#define UART_EXTINP_CTS_MASK		(1 << UART_EXTINP_CTS_SHIFT)
+#define UART_EXTINP_DCD_SHIFT		2
+#define UART_EXTINP_DCD_MASK		(1 << UART_EXTINP_DCD_SHIFT)
+#define UART_EXTINP_DSR_SHIFT		3
+#define UART_EXTINP_DSR_MASK		(1 << UART_EXTINP_DSR_SHIFT)
+#define UART_EXTINP_IRSTAT(x)		(1 << (x + 4))
+#define UART_EXTINP_IRMASK(x)		(1 << (x + 8))
+#define UART_EXTINP_IR_RI		0
+#define UART_EXTINP_IR_CTS		1
+#define UART_EXTINP_IR_DCD		2
+#define UART_EXTINP_IR_DSR		3
+#define UART_EXTINP_RI_NOSENSE_SHIFT	16
+#define UART_EXTINP_RI_NOSENSE_MASK	(1 << UART_EXTINP_RI_NOSENSE_SHIFT)
+#define UART_EXTINP_CTS_NOSENSE_SHIFT	17
+#define UART_EXTINP_CTS_NOSENSE_MASK	(1 << UART_EXTINP_CTS_NOSENSE_SHIFT)
+#define UART_EXTINP_DCD_NOSENSE_SHIFT	18
+#define UART_EXTINP_DCD_NOSENSE_MASK	(1 << UART_EXTINP_DCD_NOSENSE_SHIFT)
+#define UART_EXTINP_DSR_NOSENSE_SHIFT	19
+#define UART_EXTINP_DSR_NOSENSE_MASK	(1 << UART_EXTINP_DSR_NOSENSE_SHIFT)
+
+/* UART Interrupt register */
+#define UART_IR_REG			0x10
+#define UART_IR_MASK(x)			(1 << (x + 16))
+#define UART_IR_STAT(x)			(1 << (x))
+#define UART_IR_EXTIP			0
+#define UART_IR_TXUNDER			1
+#define UART_IR_TXOVER			2
+#define UART_IR_TXTRESH			3
+#define UART_IR_TXRDLATCH		4
+#define UART_IR_TXEMPTY			5
+#define UART_IR_RXUNDER			6
+#define UART_IR_RXOVER			7
+#define UART_IR_RXTIMEOUT		8
+#define UART_IR_RXFULL			9
+#define UART_IR_RXTHRESH		10
+#define UART_IR_RXNOTEMPTY		11
+#define UART_IR_RXFRAMEERR		12
+#define UART_IR_RXPARERR		13
+#define UART_IR_RXBRK			14
+#define UART_IR_TXDONE			15
+
+/* UART Fifo register */
+#define UART_FIFO_REG			0x14
+#define UART_FIFO_VALID_SHIFT		0
+#define UART_FIFO_VALID_MASK		0xff
+#define UART_FIFO_FRAMEERR_SHIFT	8
+#define UART_FIFO_FRAMEERR_MASK		(1 << UART_FIFO_FRAMEERR_SHIFT)
+#define UART_FIFO_PARERR_SHIFT		9
+#define UART_FIFO_PARERR_MASK		(1 << UART_FIFO_PARERR_SHIFT)
+#define UART_FIFO_BRKDET_SHIFT		10
+#define UART_FIFO_BRKDET_MASK		(1 << UART_FIFO_BRKDET_SHIFT)
+#define UART_FIFO_ANYERR_MASK		(UART_FIFO_FRAMEERR_MASK |	\
+					UART_FIFO_PARERR_MASK |		\
+					UART_FIFO_BRKDET_MASK)
+
+
+/*************************************************************************
+ * _REG relative to RSET_GPIO
+ *************************************************************************/
+
+/* GPIO registers */
+#define GPIO_CTL_HI_REG			0x0
+#define GPIO_CTL_LO_REG			0x4
+#define GPIO_DATA_HI_REG		0x8
+#define GPIO_DATA_LO_REG		0xC
+
+/* GPIO mux registers and constants */
+#define GPIO_MODE_REG			0x18
+
+#define GPIO_MODE_6348_G4_DIAG		0x00090000
+#define GPIO_MODE_6348_G4_UTOPIA	0x00080000
+#define GPIO_MODE_6348_G4_LEGACY_LED	0x00030000
+#define GPIO_MODE_6348_G4_MII_SNOOP	0x00020000
+#define GPIO_MODE_6348_G4_EXT_EPHY	0x00010000
+#define GPIO_MODE_6348_G3_DIAG		0x00009000
+#define GPIO_MODE_6348_G3_UTOPIA	0x00008000
+#define GPIO_MODE_6348_G3_EXT_MII	0x00007000
+#define GPIO_MODE_6348_G2_DIAG		0x00000900
+#define GPIO_MODE_6348_G2_PCI		0x00000500
+#define GPIO_MODE_6348_G1_DIAG		0x00000090
+#define GPIO_MODE_6348_G1_UTOPIA	0x00000080
+#define GPIO_MODE_6348_G1_SPI_UART	0x00000060
+#define GPIO_MODE_6348_G1_SPI_MASTER	0x00000060
+#define GPIO_MODE_6348_G1_MII_PCCARD	0x00000040
+#define GPIO_MODE_6348_G1_MII_SNOOP	0x00000020
+#define GPIO_MODE_6348_G1_EXT_EPHY	0x00000010
+#define GPIO_MODE_6348_G0_DIAG		0x00000009
+#define GPIO_MODE_6348_G0_EXT_MII	0x00000007
+
+#define GPIO_MODE_6358_EXTRACS		(1 << 5)
+#define GPIO_MODE_6358_UART1		(1 << 6)
+#define GPIO_MODE_6358_EXTRA_SPI_SS	(1 << 7)
+#define GPIO_MODE_6358_SERIAL_LED	(1 << 10)
+#define GPIO_MODE_6358_UTOPIA		(1 << 12)
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENET
+ *************************************************************************/
+
+/* Receiver Configuration register */
+#define ENET_RXCFG_REG			0x0
+#define ENET_RXCFG_ALLMCAST_SHIFT	1
+#define ENET_RXCFG_ALLMCAST_MASK	(1 << ENET_RXCFG_ALLMCAST_SHIFT)
+#define ENET_RXCFG_PROMISC_SHIFT	3
+#define ENET_RXCFG_PROMISC_MASK		(1 << ENET_RXCFG_PROMISC_SHIFT)
+#define ENET_RXCFG_LOOPBACK_SHIFT	4
+#define ENET_RXCFG_LOOPBACK_MASK	(1 << ENET_RXCFG_LOOPBACK_SHIFT)
+#define ENET_RXCFG_ENFLOW_SHIFT		5
+#define ENET_RXCFG_ENFLOW_MASK		(1 << ENET_RXCFG_ENFLOW_SHIFT)
+
+/* Receive Maximum Length register */
+#define ENET_RXMAXLEN_REG		0x4
+#define ENET_RXMAXLEN_SHIFT		0
+#define ENET_RXMAXLEN_MASK		(0x7ff << ENET_RXMAXLEN_SHIFT)
+
+/* Transmit Maximum Length register */
+#define ENET_TXMAXLEN_REG		0x8
+#define ENET_TXMAXLEN_SHIFT		0
+#define ENET_TXMAXLEN_MASK		(0x7ff << ENET_TXMAXLEN_SHIFT)
+
+/* MII Status/Control register */
+#define ENET_MIISC_REG			0x10
+#define ENET_MIISC_MDCFREQDIV_SHIFT	0
+#define ENET_MIISC_MDCFREQDIV_MASK	(0x7f << ENET_MIISC_MDCFREQDIV_SHIFT)
+#define ENET_MIISC_PREAMBLEEN_SHIFT	7
+#define ENET_MIISC_PREAMBLEEN_MASK	(1 << ENET_MIISC_PREAMBLEEN_SHIFT)
+
+/* MII Data register */
+#define ENET_MIIDATA_REG		0x14
+#define ENET_MIIDATA_DATA_SHIFT		0
+#define ENET_MIIDATA_DATA_MASK		(0xffff << ENET_MIIDATA_DATA_SHIFT)
+#define ENET_MIIDATA_TA_SHIFT		16
+#define ENET_MIIDATA_TA_MASK		(0x3 << ENET_MIIDATA_TA_SHIFT)
+#define ENET_MIIDATA_REG_SHIFT		18
+#define ENET_MIIDATA_REG_MASK		(0x1f << ENET_MIIDATA_REG_SHIFT)
+#define ENET_MIIDATA_PHYID_SHIFT	23
+#define ENET_MIIDATA_PHYID_MASK		(0x1f << ENET_MIIDATA_PHYID_SHIFT)
+#define ENET_MIIDATA_OP_READ_MASK	(0x6 << 28)
+#define ENET_MIIDATA_OP_WRITE_MASK	(0x5 << 28)
+
+/* Ethernet Interrupt Mask register */
+#define ENET_IRMASK_REG			0x18
+
+/* Ethernet Interrupt register */
+#define ENET_IR_REG			0x1c
+#define ENET_IR_MII			(1 << 0)
+#define ENET_IR_MIB			(1 << 1)
+#define ENET_IR_FLOWC			(1 << 2)
+
+/* Ethernet Control register */
+#define ENET_CTL_REG			0x2c
+#define ENET_CTL_ENABLE_SHIFT		0
+#define ENET_CTL_ENABLE_MASK		(1 << ENET_CTL_ENABLE_SHIFT)
+#define ENET_CTL_DISABLE_SHIFT		1
+#define ENET_CTL_DISABLE_MASK		(1 << ENET_CTL_DISABLE_SHIFT)
+#define ENET_CTL_SRESET_SHIFT		2
+#define ENET_CTL_SRESET_MASK		(1 << ENET_CTL_SRESET_SHIFT)
+#define ENET_CTL_EPHYSEL_SHIFT		3
+#define ENET_CTL_EPHYSEL_MASK		(1 << ENET_CTL_EPHYSEL_SHIFT)
+
+/* Transmit Control register */
+#define ENET_TXCTL_REG			0x30
+#define ENET_TXCTL_FD_SHIFT		0
+#define ENET_TXCTL_FD_MASK		(1 << ENET_TXCTL_FD_SHIFT)
+
+/* Transmit Watermask register */
+#define ENET_TXWMARK_REG		0x34
+#define ENET_TXWMARK_WM_SHIFT		0
+#define ENET_TXWMARK_WM_MASK		(0x3f << ENET_TXWMARK_WM_SHIFT)
+
+/* MIB Control register */
+#define ENET_MIBCTL_REG			0x38
+#define ENET_MIBCTL_RDCLEAR_SHIFT	0
+#define ENET_MIBCTL_RDCLEAR_MASK	(1 << ENET_MIBCTL_RDCLEAR_SHIFT)
+
+/* Perfect Match Data Low register */
+#define ENET_PML_REG(x)			(0x58 + (x) * 8)
+#define ENET_PMH_REG(x)			(0x5c + (x) * 8)
+#define ENET_PMH_DATAVALID_SHIFT	16
+#define ENET_PMH_DATAVALID_MASK		(1 << ENET_PMH_DATAVALID_SHIFT)
+
+/* MIB register */
+#define ENET_MIB_REG(x)			(0x200 + (x) * 4)
+#define ENET_MIB_REG_COUNT		55
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENETDMA
+ *************************************************************************/
+
+/* Controller Configuration Register */
+#define ENETDMA_CFG_REG			(0x0)
+#define ENETDMA_CFG_EN_SHIFT		0
+#define ENETDMA_CFG_EN_MASK		(1 << ENETDMA_CFG_EN_SHIFT)
+#define ENETDMA_CFG_FLOWCH_MASK(x)	(1 << ((x >> 1) + 1))
+
+/* Flow Control Descriptor Low Threshold register */
+#define ENETDMA_FLOWCL_REG(x)		(0x4 + (x) * 6)
+
+/* Flow Control Descriptor High Threshold register */
+#define ENETDMA_FLOWCH_REG(x)		(0x8 + (x) * 6)
+
+/* Flow Control Descriptor Buffer Alloca Threshold register */
+#define ENETDMA_BUFALLOC_REG(x)		(0xc + (x) * 6)
+#define ENETDMA_BUFALLOC_FORCE_SHIFT	31
+#define ENETDMA_BUFALLOC_FORCE_MASK	(1 << ENETDMA_BUFALLOC_FORCE_SHIFT)
+
+/* Channel Configuration register */
+#define ENETDMA_CHANCFG_REG(x)		(0x100 + (x) * 0x10)
+#define ENETDMA_CHANCFG_EN_SHIFT	0
+#define ENETDMA_CHANCFG_EN_MASK		(1 << ENETDMA_CHANCFG_EN_SHIFT)
+#define ENETDMA_CHANCFG_PKTHALT_SHIFT	1
+#define ENETDMA_CHANCFG_PKTHALT_MASK	(1 << ENETDMA_CHANCFG_PKTHALT_SHIFT)
+
+/* Interrupt Control/Status register */
+#define ENETDMA_IR_REG(x)		(0x104 + (x) * 0x10)
+#define ENETDMA_IR_BUFDONE_MASK		(1 << 0)
+#define ENETDMA_IR_PKTDONE_MASK		(1 << 1)
+#define ENETDMA_IR_NOTOWNER_MASK	(1 << 2)
+
+/* Interrupt Mask register */
+#define ENETDMA_IRMASK_REG(x)		(0x108 + (x) * 0x10)
+
+/* Maximum Burst Length */
+#define ENETDMA_MAXBURST_REG(x)		(0x10C + (x) * 0x10)
+
+/* Ring Start Address register */
+#define ENETDMA_RSTART_REG(x)		(0x200 + (x) * 0x10)
+
+/* State Ram Word 2 */
+#define ENETDMA_SRAM2_REG(x)		(0x204 + (x) * 0x10)
+
+/* State Ram Word 3 */
+#define ENETDMA_SRAM3_REG(x)		(0x208 + (x) * 0x10)
+
+/* State Ram Word 4 */
+#define ENETDMA_SRAM4_REG(x)		(0x20c + (x) * 0x10)
+
+
+/*************************************************************************
+ * _REG relative to RSET_OHCI_PRIV
+ *************************************************************************/
+
+#define OHCI_PRIV_REG			0x0
+#define OHCI_PRIV_PORT1_HOST_SHIFT	0
+#define OHCI_PRIV_PORT1_HOST_MASK	(1 << OHCI_PRIV_PORT1_HOST_SHIFT)
+#define OHCI_PRIV_REG_SWAP_SHIFT	3
+#define OHCI_PRIV_REG_SWAP_MASK		(1 << OHCI_PRIV_REG_SWAP_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_USBH_PRIV
+ *************************************************************************/
+
+#define USBH_PRIV_SWAP_REG		0x0
+#define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT	4
+#define USBH_PRIV_SWAP_EHCI_ENDN_MASK	(1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT)
+#define USBH_PRIV_SWAP_EHCI_DATA_SHIFT	3
+#define USBH_PRIV_SWAP_EHCI_DATA_MASK	(1 << USBH_PRIV_SWAP_EHCI_DATA_SHIFT)
+#define USBH_PRIV_SWAP_OHCI_ENDN_SHIFT	1
+#define USBH_PRIV_SWAP_OHCI_ENDN_MASK	(1 << USBH_PRIV_SWAP_OHCI_ENDN_SHIFT)
+#define USBH_PRIV_SWAP_OHCI_DATA_SHIFT	0
+#define USBH_PRIV_SWAP_OHCI_DATA_MASK	(1 << USBH_PRIV_SWAP_OHCI_DATA_SHIFT)
+
+#define USBH_PRIV_TEST_REG		0x24
+
+
+/*************************************************************************
+ * _REG relative to RSET_MPI
+ *************************************************************************/
+
+/* well known (hard wired) chip select */
+#define MPI_CS_PCMCIA_COMMON		4
+#define MPI_CS_PCMCIA_ATTR		5
+#define MPI_CS_PCMCIA_IO		6
+
+/* Chip select base register */
+#define MPI_CSBASE_REG(x)		(0x0 + (x) * 8)
+#define MPI_CSBASE_BASE_SHIFT		13
+#define MPI_CSBASE_BASE_MASK		(0x1ffff << MPI_CSBASE_BASE_SHIFT)
+#define MPI_CSBASE_SIZE_SHIFT		0
+#define MPI_CSBASE_SIZE_MASK		(0xf << MPI_CSBASE_SIZE_SHIFT)
+
+#define MPI_CSBASE_SIZE_8K		0
+#define MPI_CSBASE_SIZE_16K		1
+#define MPI_CSBASE_SIZE_32K		2
+#define MPI_CSBASE_SIZE_64K		3
+#define MPI_CSBASE_SIZE_128K		4
+#define MPI_CSBASE_SIZE_256K		5
+#define MPI_CSBASE_SIZE_512K		6
+#define MPI_CSBASE_SIZE_1M		7
+#define MPI_CSBASE_SIZE_2M		8
+#define MPI_CSBASE_SIZE_4M		9
+#define MPI_CSBASE_SIZE_8M		10
+#define MPI_CSBASE_SIZE_16M		11
+#define MPI_CSBASE_SIZE_32M		12
+#define MPI_CSBASE_SIZE_64M		13
+#define MPI_CSBASE_SIZE_128M		14
+#define MPI_CSBASE_SIZE_256M		15
+
+/* Chip select control register */
+#define MPI_CSCTL_REG(x)		(0x4 + (x) * 8)
+#define MPI_CSCTL_ENABLE_MASK		(1 << 0)
+#define MPI_CSCTL_WAIT_SHIFT		1
+#define MPI_CSCTL_WAIT_MASK		(0x7 << MPI_CSCTL_WAIT_SHIFT)
+#define MPI_CSCTL_DATA16_MASK		(1 << 4)
+#define MPI_CSCTL_SYNCMODE_MASK		(1 << 7)
+#define MPI_CSCTL_TSIZE_MASK		(1 << 8)
+#define MPI_CSCTL_ENDIANSWAP_MASK	(1 << 10)
+#define MPI_CSCTL_SETUP_SHIFT		16
+#define MPI_CSCTL_SETUP_MASK		(0xf << MPI_CSCTL_SETUP_SHIFT)
+#define MPI_CSCTL_HOLD_SHIFT		20
+#define MPI_CSCTL_HOLD_MASK		(0xf << MPI_CSCTL_HOLD_SHIFT)
+
+/* PCI registers */
+#define MPI_SP0_RANGE_REG		0x100
+#define MPI_SP0_REMAP_REG		0x104
+#define MPI_SP0_REMAP_ENABLE_MASK	(1 << 0)
+#define MPI_SP1_RANGE_REG		0x10C
+#define MPI_SP1_REMAP_REG		0x110
+#define MPI_SP1_REMAP_ENABLE_MASK	(1 << 0)
+
+#define MPI_L2PCFG_REG			0x11C
+#define MPI_L2PCFG_CFG_TYPE_SHIFT	0
+#define MPI_L2PCFG_CFG_TYPE_MASK	(0x3 << MPI_L2PCFG_CFG_TYPE_SHIFT)
+#define MPI_L2PCFG_REG_SHIFT		2
+#define MPI_L2PCFG_REG_MASK		(0x3f << MPI_L2PCFG_REG_SHIFT)
+#define MPI_L2PCFG_FUNC_SHIFT		8
+#define MPI_L2PCFG_FUNC_MASK		(0x7 << MPI_L2PCFG_FUNC_SHIFT)
+#define MPI_L2PCFG_DEVNUM_SHIFT		11
+#define MPI_L2PCFG_DEVNUM_MASK		(0x1f << MPI_L2PCFG_DEVNUM_SHIFT)
+#define MPI_L2PCFG_CFG_USEREG_MASK	(1 << 30)
+#define MPI_L2PCFG_CFG_SEL_MASK		(1 << 31)
+
+#define MPI_L2PMEMRANGE1_REG		0x120
+#define MPI_L2PMEMBASE1_REG		0x124
+#define MPI_L2PMEMREMAP1_REG		0x128
+#define MPI_L2PMEMRANGE2_REG		0x12C
+#define MPI_L2PMEMBASE2_REG		0x130
+#define MPI_L2PMEMREMAP2_REG		0x134
+#define MPI_L2PIORANGE_REG		0x138
+#define MPI_L2PIOBASE_REG		0x13C
+#define MPI_L2PIOREMAP_REG		0x140
+#define MPI_L2P_BASE_MASK		(0xffff8000)
+#define MPI_L2PREMAP_ENABLED_MASK	(1 << 0)
+#define MPI_L2PREMAP_IS_CARDBUS_MASK	(1 << 2)
+
+#define MPI_PCIMODESEL_REG		0x144
+#define MPI_PCIMODESEL_BAR1_NOSWAP_MASK	(1 << 0)
+#define MPI_PCIMODESEL_BAR2_NOSWAP_MASK	(1 << 1)
+#define MPI_PCIMODESEL_EXT_ARB_MASK	(1 << 2)
+#define MPI_PCIMODESEL_PREFETCH_SHIFT	4
+#define MPI_PCIMODESEL_PREFETCH_MASK	(0xf << MPI_PCIMODESEL_PREFETCH_SHIFT)
+
+#define MPI_LOCBUSCTL_REG		0x14C
+#define MPI_LOCBUSCTL_EN_PCI_GPIO_MASK	(1 << 0)
+#define MPI_LOCBUSCTL_U2P_NOSWAP_MASK	(1 << 1)
+
+#define MPI_LOCINT_REG			0x150
+#define MPI_LOCINT_MASK(x)		(1 << (x + 16))
+#define MPI_LOCINT_STAT(x)		(1 << (x))
+#define MPI_LOCINT_DIR_FAILED		6
+#define MPI_LOCINT_EXT_PCI_INT		7
+#define MPI_LOCINT_SERR			8
+#define MPI_LOCINT_CSERR		9
+
+#define MPI_PCICFGCTL_REG		0x178
+#define MPI_PCICFGCTL_CFGADDR_SHIFT	2
+#define MPI_PCICFGCTL_CFGADDR_MASK	(0x1f << MPI_PCICFGCTL_CFGADDR_SHIFT)
+#define MPI_PCICFGCTL_WRITEEN_MASK	(1 << 7)
+
+#define MPI_PCICFGDATA_REG		0x17C
+
+/* PCI host bridge custom register */
+#define BCMPCI_REG_TIMERS		0x40
+#define REG_TIMER_TRDY_SHIFT		0
+#define REG_TIMER_TRDY_MASK		(0xff << REG_TIMER_TRDY_SHIFT)
+#define REG_TIMER_RETRY_SHIFT		8
+#define REG_TIMER_RETRY_MASK		(0xff << REG_TIMER_RETRY_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_PCMCIA
+ *************************************************************************/
+
+#define PCMCIA_C1_REG			0x0
+#define PCMCIA_C1_CD1_MASK		(1 << 0)
+#define PCMCIA_C1_CD2_MASK		(1 << 1)
+#define PCMCIA_C1_VS1_MASK		(1 << 2)
+#define PCMCIA_C1_VS2_MASK		(1 << 3)
+#define PCMCIA_C1_VS1OE_MASK		(1 << 6)
+#define PCMCIA_C1_VS2OE_MASK		(1 << 7)
+#define PCMCIA_C1_CBIDSEL_SHIFT		(8)
+#define PCMCIA_C1_CBIDSEL_MASK		(0x1f << PCMCIA_C1_CBIDSEL_SHIFT)
+#define PCMCIA_C1_EN_PCMCIA_GPIO_MASK	(1 << 13)
+#define PCMCIA_C1_EN_PCMCIA_MASK	(1 << 14)
+#define PCMCIA_C1_EN_CARDBUS_MASK	(1 << 15)
+#define PCMCIA_C1_RESET_MASK		(1 << 18)
+
+#define PCMCIA_C2_REG			0x8
+#define PCMCIA_C2_DATA16_MASK		(1 << 0)
+#define PCMCIA_C2_BYTESWAP_MASK		(1 << 1)
+#define PCMCIA_C2_RWCOUNT_SHIFT		2
+#define PCMCIA_C2_RWCOUNT_MASK		(0x3f << PCMCIA_C2_RWCOUNT_SHIFT)
+#define PCMCIA_C2_INACTIVE_SHIFT	8
+#define PCMCIA_C2_INACTIVE_MASK		(0x3f << PCMCIA_C2_INACTIVE_SHIFT)
+#define PCMCIA_C2_SETUP_SHIFT		16
+#define PCMCIA_C2_SETUP_MASK		(0x3f << PCMCIA_C2_SETUP_SHIFT)
+#define PCMCIA_C2_HOLD_SHIFT		24
+#define PCMCIA_C2_HOLD_MASK		(0x3f << PCMCIA_C2_HOLD_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_SDRAM
+ *************************************************************************/
+
+#define SDRAM_CFG_REG			0x0
+#define SDRAM_CFG_ROW_SHIFT		4
+#define SDRAM_CFG_ROW_MASK		(0x3 << SDRAM_CFG_ROW_SHIFT)
+#define SDRAM_CFG_COL_SHIFT		6
+#define SDRAM_CFG_COL_MASK		(0x3 << SDRAM_CFG_COL_SHIFT)
+#define SDRAM_CFG_32B_SHIFT		10
+#define SDRAM_CFG_32B_MASK		(1 << SDRAM_CFG_32B_SHIFT)
+#define SDRAM_CFG_BANK_SHIFT		13
+#define SDRAM_CFG_BANK_MASK		(1 << SDRAM_CFG_BANK_SHIFT)
+
+#define SDRAM_PRIO_REG			0x2C
+#define SDRAM_PRIO_MIPS_SHIFT		29
+#define SDRAM_PRIO_MIPS_MASK		(1 << SDRAM_PRIO_MIPS_SHIFT)
+#define SDRAM_PRIO_ADSL_SHIFT		30
+#define SDRAM_PRIO_ADSL_MASK		(1 << SDRAM_PRIO_ADSL_SHIFT)
+#define SDRAM_PRIO_EN_SHIFT		31
+#define SDRAM_PRIO_EN_MASK		(1 << SDRAM_PRIO_EN_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_MEMC
+ *************************************************************************/
+
+#define MEMC_CFG_REG			0x4
+#define MEMC_CFG_32B_SHIFT		1
+#define MEMC_CFG_32B_MASK		(1 << MEMC_CFG_32B_SHIFT)
+#define MEMC_CFG_COL_SHIFT		3
+#define MEMC_CFG_COL_MASK		(0x3 << MEMC_CFG_COL_SHIFT)
+#define MEMC_CFG_ROW_SHIFT		6
+#define MEMC_CFG_ROW_MASK		(0x3 << MEMC_CFG_ROW_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_DDR
+ *************************************************************************/
+
+#define DDR_DMIPSPLLCFG_REG		0x18
+#define DMIPSPLLCFG_M1_SHIFT		0
+#define DMIPSPLLCFG_M1_MASK		(0xff << DMIPSPLLCFG_M1_SHIFT)
+#define DMIPSPLLCFG_N1_SHIFT		23
+#define DMIPSPLLCFG_N1_MASK		(0x3f << DMIPSPLLCFG_N1_SHIFT)
+#define DMIPSPLLCFG_N2_SHIFT		29
+#define DMIPSPLLCFG_N2_MASK		(0x7 << DMIPSPLLCFG_N2_SHIFT)
+
+#endif /* BCM63XX_REGS_H_ */
+
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
new file mode 100644
index 0000000..c0fce83
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
@@ -0,0 +1,11 @@
+#ifndef BCM63XX_TIMER_H_
+#define BCM63XX_TIMER_H_
+
+int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data);
+void bcm63xx_timer_unregister(int id);
+int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us);
+int bcm63xx_timer_enable(int id);
+int bcm63xx_timer_disable(int id);
+unsigned int bcm63xx_timer_countdown(unsigned int countdown_us);
+
+#endif /* !BCM63XX_TIMER_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
new file mode 100644
index 0000000..6479090
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -0,0 +1,60 @@
+#ifndef BOARD_BCM963XX_H_
+#define BOARD_BCM963XX_H_
+
+#include <linux/types.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_dsp.h>
+
+/*
+ * flash mapping
+ */
+#define BCM963XX_CFE_VERSION_OFFSET	0x570
+#define BCM963XX_NVRAM_OFFSET		0x580
+
+/*
+ * nvram structure
+ */
+struct bcm963xx_nvram {
+	u32	version;
+	u8	reserved1[256];
+	u8	name[16];
+	u32	main_tp_number;
+	u32	psi_size;
+	u32	mac_addr_count;
+	u8	mac_addr_base[6];
+	u8	reserved2[2];
+	u32	checksum_old;
+	u8	reserved3[720];
+	u32	checksum_high;
+};
+
+/*
+ * board definition
+ */
+struct board_info {
+	u8		name[16];
+	unsigned int	expected_cpu_id;
+
+	/* enabled feature/device */
+	unsigned int	has_enet0:1;
+	unsigned int	has_enet1:1;
+	unsigned int	has_pci:1;
+	unsigned int	has_pccard:1;
+	unsigned int	has_ohci0:1;
+	unsigned int	has_ehci0:1;
+	unsigned int	has_dsp:1;
+
+	/* ethernet config */
+	struct bcm63xx_enet_platform_data enet0;
+	struct bcm63xx_enet_platform_data enet1;
+
+	/* DSP config */
+	struct bcm63xx_dsp_platform_data dsp;
+
+	/* GPIO LEDs */
+	struct gpio_led leds[5];
+};
+
+#endif /* ! BOARD_BCM963XX_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
new file mode 100644
index 0000000..71742ba
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
@@ -0,0 +1,51 @@
+#ifndef __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H
+
+#include <bcm63xx_cpu.h>
+
+#define cpu_has_tlb			1
+#define cpu_has_4kex			1
+#define cpu_has_4k_cache		1
+#define cpu_has_fpu			0
+#define cpu_has_32fpr			0
+#define cpu_has_counter			1
+#define cpu_has_watch			0
+#define cpu_has_divec			1
+#define cpu_has_vce			0
+#define cpu_has_cache_cdex_p		0
+#define cpu_has_cache_cdex_s		0
+#define cpu_has_prefetch		1
+#define cpu_has_mcheck			1
+#define cpu_has_ejtag			1
+#define cpu_has_llsc			1
+#define cpu_has_mips16			0
+#define cpu_has_mdmx			0
+#define cpu_has_mips3d			0
+#define cpu_has_smartmips		0
+#define cpu_has_vtag_icache		0
+
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#define cpu_has_dc_aliases		0
+#endif
+
+#define cpu_has_ic_fills_f_dc		0
+#define cpu_has_pindexed_dcache		0
+
+#define cpu_has_mips32r1		1
+#define cpu_has_mips32r2		0
+#define cpu_has_mips64r1		0
+#define cpu_has_mips64r2		0
+
+#define cpu_has_dsp			0
+#define cpu_has_mipsmt			0
+#define cpu_has_userlocal		0
+
+#define cpu_has_nofpuex			0
+#define cpu_has_64bits			0
+#define cpu_has_64bit_zero_reg		0
+
+#define cpu_dcache_line_size()		16
+#define cpu_icache_line_size()		16
+#define cpu_scache_line_size()		0
+
+#endif /* __ASM_MACH_BCM963XX_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/gpio.h b/arch/mips/include/asm/mach-bcm63xx/gpio.h
new file mode 100644
index 0000000..7cda8c0
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/gpio.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_MIPS_MACH_BCM63XX_GPIO_H
+#define __ASM_MIPS_MACH_BCM63XX_GPIO_H
+
+#include <bcm63xx_gpio.h>
+
+#define gpio_to_irq(gpio)	NULL
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+
+#define gpio_cansleep __gpio_cansleep
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_MIPS_MACH_BCM63XX_GPIO_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/war.h b/arch/mips/include/asm/mach-bcm63xx/war.h
new file mode 100644
index 0000000..8e3f3fd
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/war.h
@@ -0,0 +1,25 @@
+/*
+ * 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_BCM63XX_WAR_H
+#define __ASM_MIPS_MACH_BCM63XX_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR	0
+#define R4600_V1_HIT_CACHEOP_WAR	0
+#define R4600_V2_HIT_CACHEOP_WAR	0
+#define R5432_CP0_INTERRUPT_WAR		0
+#define BCM1250_M3_WAR			0
+#define SIBYTE_1956_WAR			0
+#define MIPS4K_ICACHE_REFILL_WAR	0
+#define MIPS_CACHE_SYNC_WAR		0
+#define TX49XX_ICACHE_INDEX_INV_WAR	0
+#define RM9000_CDEX_SMP_WAR		0
+#define ICACHE_REFILLS_WORKAROUND_WAR	0
+#define R10000_LLSC_WAR			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MIPS_MACH_BCM63XX_WAR_H */
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index 3d83075..425e708 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -31,12 +31,16 @@
 #define cpu_has_cache_cdex_s	0
 #define cpu_has_prefetch	1
 
+#define cpu_has_llsc		1
 /*
- * We should disable LL/SC on non SMP systems as it is faster to
- * disable interrupts for atomic access than a LL/SC.  Unfortunatly we
- * cannot as this breaks asm/futex.h
+ * We Disable LL/SC on non SMP systems as it is faster to disable
+ * interrupts for atomic access than a LL/SC.
  */
-#define cpu_has_llsc		1
+#ifdef CONFIG_SMP
+# define kernel_uses_llsc	1
+#else
+# define kernel_uses_llsc	0
+#endif
 #define cpu_has_vtag_icache	1
 #define cpu_has_dc_aliases	0
 #define cpu_has_ic_fills_f_dc	0
diff --git a/arch/mips/include/asm/mach-ip27/topology.h b/arch/mips/include/asm/mach-ip27/topology.h
index 0754723..2305917 100644
--- a/arch/mips/include/asm/mach-ip27/topology.h
+++ b/arch/mips/include/asm/mach-ip27/topology.h
@@ -48,7 +48,6 @@ extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
 	.cache_nice_tries	= 1,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_EXEC	\
-				| SD_WAKE_BALANCE,	\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
 	.nr_balance_failed	= 0,			\
diff --git a/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h b/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h
deleted file mode 100644
index 550a10d..0000000
--- a/arch/mips/include/asm/mach-lemote/cpu-feature-overrides.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2009 Wu Zhangjin <wuzj@lemote.com>
- * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
- * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
- *
- * reference: /proc/cpuinfo,
- * 	arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
- * 	arch/mips/kernel/proc.c(show_cpuinfo),
- *      loongson2f user manual.
- */
-
-#ifndef __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H
-
-#define cpu_dcache_line_size()	32
-#define cpu_icache_line_size()	32
-#define cpu_scache_line_size()	32
-
-
-#define cpu_has_32fpr		1
-#define cpu_has_3k_cache	0
-#define cpu_has_4k_cache	1
-#define cpu_has_4kex		1
-#define cpu_has_64bits		1
-#define cpu_has_cache_cdex_p	0
-#define cpu_has_cache_cdex_s	0
-#define cpu_has_counter		1
-#define cpu_has_dc_aliases	1
-#define cpu_has_divec		0
-#define cpu_has_dsp		0
-#define cpu_has_ejtag		0
-#define cpu_has_fpu		1
-#define cpu_has_ic_fills_f_dc	0
-#define cpu_has_inclusive_pcaches	1
-#define cpu_has_llsc 		1
-#define cpu_has_mcheck		0
-#define cpu_has_mdmx		0
-#define cpu_has_mips16		0
-#define cpu_has_mips32r1	0
-#define cpu_has_mips32r2	0
-#define cpu_has_mips3d		0
-#define cpu_has_mips64r1	0
-#define cpu_has_mips64r2	0
-#define cpu_has_mipsmt		0
-#define cpu_has_prefetch	0
-#define cpu_has_smartmips	0
-#define cpu_has_tlb		1
-#define cpu_has_tx39_cache	0
-#define cpu_has_userlocal	0
-#define cpu_has_vce		0
-#define cpu_has_vtag_icache	0
-#define cpu_has_watch		1
-#define cpu_icache_snoops_remote_store	1
-
-#endif /* __ASM_MACH_LEMOTE_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-lemote/dma-coherence.h b/arch/mips/include/asm/mach-lemote/dma-coherence.h
deleted file mode 100644
index c8de5e7..0000000
--- a/arch/mips/include/asm/mach-lemote/dma-coherence.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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) 2006, 07  Ralf Baechle <ralf@linux-mips.org>
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- *
- */
-#ifndef __ASM_MACH_LEMOTE_DMA_COHERENCE_H
-#define __ASM_MACH_LEMOTE_DMA_COHERENCE_H
-
-struct device;
-
-static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
-					  size_t size)
-{
-	return virt_to_phys(addr) | 0x80000000;
-}
-
-static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
-					       struct page *page)
-{
-	return page_to_phys(page) | 0x80000000;
-}
-
-static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
-	dma_addr_t dma_addr)
-{
-	return dma_addr & 0x7fffffff;
-}
-
-static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
-	size_t size, enum dma_data_direction direction)
-{
-}
-
-static inline int plat_dma_supported(struct device *dev, u64 mask)
-{
-	/*
-	 * we fall back to GFP_DMA when the mask isn't all 1s,
-	 * so we can't guarantee allocations that must be
-	 * within a tighter range than GFP_DMA..
-	 */
-	if (mask < DMA_BIT_MASK(24))
-		return 0;
-
-	return 1;
-}
-
-static inline void plat_extra_sync_for_device(struct device *dev)
-{
-	return;
-}
-
-static inline int plat_dma_mapping_error(struct device *dev,
-					 dma_addr_t dma_addr)
-{
-	return 0;
-}
-
-static inline int plat_device_is_coherent(struct device *dev)
-{
-	return 0;
-}
-
-#endif /* __ASM_MACH_LEMOTE_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-lemote/mc146818rtc.h b/arch/mips/include/asm/mach-lemote/mc146818rtc.h
deleted file mode 100644
index ed5147e..0000000
--- a/arch/mips/include/asm/mach-lemote/mc146818rtc.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
- *
- * RTC routines for PC style attached Dallas chip.
- */
-#ifndef __ASM_MACH_LEMOTE_MC146818RTC_H
-#define __ASM_MACH_LEMOTE_MC146818RTC_H
-
-#include <linux/io.h>
-
-#define RTC_PORT(x)	(0x70 + (x))
-#define RTC_IRQ		8
-
-static inline unsigned char CMOS_READ(unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	return inb_p(RTC_PORT(1));
-}
-
-static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
-{
-	outb_p(addr, RTC_PORT(0));
-	outb_p(data, RTC_PORT(1));
-}
-
-#define RTC_ALWAYS_BCD	0
-
-#ifndef mc146818_decode_year
-#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
-#endif
-
-#endif /* __ASM_MACH_LEMOTE_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-lemote/pci.h b/arch/mips/include/asm/mach-lemote/pci.h
deleted file mode 100644
index ea6aa14..0000000
--- a/arch/mips/include/asm/mach-lemote/pci.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.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 _LEMOTE_PCI_H_
-#define _LEMOTE_PCI_H_
-
-#define LOONGSON2E_PCI_MEM_START	0x14000000UL
-#define LOONGSON2E_PCI_MEM_END		0x1fffffffUL
-#define LOONGSON2E_PCI_IO_START		0x00004000UL
-#define LOONGSON2E_IO_PORT_BASE		0x1fd00000UL
-
-#endif /* !_LEMOTE_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-lemote/war.h b/arch/mips/include/asm/mach-lemote/war.h
deleted file mode 100644
index 05f89e0..0000000
--- a/arch/mips/include/asm/mach-lemote/war.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
- */
-#ifndef __ASM_MIPS_MACH_LEMOTE_WAR_H
-#define __ASM_MIPS_MACH_LEMOTE_WAR_H
-
-#define R4600_V1_INDEX_ICACHEOP_WAR	0
-#define R4600_V1_HIT_CACHEOP_WAR	0
-#define R4600_V2_HIT_CACHEOP_WAR	0
-#define R5432_CP0_INTERRUPT_WAR		0
-#define BCM1250_M3_WAR			0
-#define SIBYTE_1956_WAR			0
-#define MIPS4K_ICACHE_REFILL_WAR	0
-#define MIPS_CACHE_SYNC_WAR		0
-#define TX49XX_ICACHE_INDEX_INV_WAR	0
-#define RM9000_CDEX_SMP_WAR		0
-#define ICACHE_REFILLS_WORKAROUND_WAR	0
-#define R10000_LLSC_WAR			0
-#define MIPS34K_MISSED_ITLB_WAR		0
-
-#endif /* __ASM_MIPS_MACH_LEMOTE_WAR_H */
diff --git a/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
new file mode 100644
index 0000000..ce5b6e2
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
@@ -0,0 +1,59 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Wu Zhangjin <wuzj@lemote.com>
+ * Copyright (C) 2009 Philippe Vachon <philippe@cowpig.ca>
+ * Copyright (C) 2009 Zhang Le <r0bertz@gentoo.org>
+ *
+ * reference: /proc/cpuinfo,
+ * 	arch/mips/kernel/cpu-probe.c(cpu_probe_legacy),
+ * 	arch/mips/kernel/proc.c(show_cpuinfo),
+ *      loongson2f user manual.
+ */
+
+#ifndef __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+#define cpu_scache_line_size()	32
+
+
+#define cpu_has_32fpr		1
+#define cpu_has_3k_cache	0
+#define cpu_has_4k_cache	1
+#define cpu_has_4kex		1
+#define cpu_has_64bits		1
+#define cpu_has_cache_cdex_p	0
+#define cpu_has_cache_cdex_s	0
+#define cpu_has_counter		1
+#define cpu_has_dc_aliases	1
+#define cpu_has_divec		0
+#define cpu_has_dsp		0
+#define cpu_has_ejtag		0
+#define cpu_has_fpu		1
+#define cpu_has_ic_fills_f_dc	0
+#define cpu_has_inclusive_pcaches	1
+#define cpu_has_llsc 		1
+#define cpu_has_mcheck		0
+#define cpu_has_mdmx		0
+#define cpu_has_mips16		0
+#define cpu_has_mips32r1	0
+#define cpu_has_mips32r2	0
+#define cpu_has_mips3d		0
+#define cpu_has_mips64r1	0
+#define cpu_has_mips64r2	0
+#define cpu_has_mipsmt		0
+#define cpu_has_prefetch	0
+#define cpu_has_smartmips	0
+#define cpu_has_tlb		1
+#define cpu_has_tx39_cache	0
+#define cpu_has_userlocal	0
+#define cpu_has_vce		0
+#define cpu_has_vtag_icache	0
+#define cpu_has_watch		1
+#define cpu_icache_snoops_remote_store	1
+
+#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h
new file mode 100644
index 0000000..71a6851
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h
@@ -0,0 +1,68 @@
+/*
+ * 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) 2006, 07  Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ */
+#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H
+#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H
+
+struct device;
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+					  size_t size)
+{
+	return virt_to_phys(addr) | 0x80000000;
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+					       struct page *page)
+{
+	return page_to_phys(page) | 0x80000000;
+}
+
+static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
+	dma_addr_t dma_addr)
+{
+	return dma_addr & 0x7fffffff;
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
+	size_t size, enum dma_data_direction direction)
+{
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+	/*
+	 * we fall back to GFP_DMA when the mask isn't all 1s,
+	 * so we can't guarantee allocations that must be
+	 * within a tighter range than GFP_DMA..
+	 */
+	if (mask < DMA_BIT_MASK(24))
+		return 0;
+
+	return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+	return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+					 dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+	return 0;
+}
+
+#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
new file mode 100644
index 0000000..da70bcf
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Wu Zhangjin <wuzj@lemote.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_MACH_LOONGSON_LOONGSON_H
+#define __ASM_MACH_LOONGSON_LOONGSON_H
+
+#include <linux/io.h>
+#include <linux/init.h>
+
+/* there is an internal bonito64-compatiable northbridge in loongson2e/2f */
+#include <asm/mips-boards/bonito64.h>
+
+/* loongson internal northbridge initialization */
+extern void bonito_irq_init(void);
+
+/* machine-specific reboot/halt operation */
+extern void mach_prepare_reboot(void);
+extern void mach_prepare_shutdown(void);
+
+/* environment arguments from bootloader */
+extern unsigned long bus_clock, cpu_clock_freq;
+extern unsigned long memsize, highmemsize;
+
+/* loongson-specific command line, env and memory initialization */
+extern void __init prom_init_memory(void);
+extern void __init prom_init_cmdline(void);
+extern void __init prom_init_env(void);
+
+/* irq operation functions */
+extern void bonito_irqdispatch(void);
+extern void __init bonito_irq_init(void);
+extern void __init set_irq_trigger_mode(void);
+extern void __init mach_init_irq(void);
+extern void mach_irq_dispatch(unsigned int pending);
+
+/* PCI Configuration Registers */
+#define LOONGSON_PCI_ISR4C  BONITO_PCI_REG(0x4c)
+
+/* PCI_Hit*_Sel_* */
+
+#define LOONGSON_PCI_HIT0_SEL_L     BONITO(BONITO_REGBASE + 0x50)
+#define LOONGSON_PCI_HIT0_SEL_H     BONITO(BONITO_REGBASE + 0x54)
+#define LOONGSON_PCI_HIT1_SEL_L     BONITO(BONITO_REGBASE + 0x58)
+#define LOONGSON_PCI_HIT1_SEL_H     BONITO(BONITO_REGBASE + 0x5c)
+#define LOONGSON_PCI_HIT2_SEL_L     BONITO(BONITO_REGBASE + 0x60)
+#define LOONGSON_PCI_HIT2_SEL_H     BONITO(BONITO_REGBASE + 0x64)
+
+/* PXArb Config & Status */
+
+#define LOONGSON_PXARB_CFG      BONITO(BONITO_REGBASE + 0x68)
+#define LOONGSON_PXARB_STATUS       BONITO(BONITO_REGBASE + 0x6c)
+
+/* loongson2-specific perf counter IRQ */
+#define LOONGSON2_PERFCNT_IRQ   (MIPS_CPU_IRQ_BASE + 6)
+
+#endif /* __ASM_MACH_LOONGSON_LOONGSON_H */
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h
new file mode 100644
index 0000000..206ea20
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/machine.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Wu Zhangjin <wuzj@lemote.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_MACH_LOONGSON_MACHINE_H
+#define __ASM_MACH_LOONGSON_MACHINE_H
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+#define LOONGSON_UART_BASE (BONITO_PCIIO_BASE + 0x3f8)
+
+#define LOONGSON_MACHTYPE MACH_LEMOTE_FL2E
+
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MACHINE_H */
diff --git a/arch/mips/include/asm/mach-loongson/mc146818rtc.h b/arch/mips/include/asm/mach-loongson/mc146818rtc.h
new file mode 100644
index 0000000..ed7fe97
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/mc146818rtc.h
@@ -0,0 +1,36 @@
+/*
+ * 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) 1998, 2001, 03, 07 by Ralf Baechle (ralf@linux-mips.org)
+ *
+ * RTC routines for PC style attached Dallas chip.
+ */
+#ifndef __ASM_MACH_LOONGSON_MC146818RTC_H
+#define __ASM_MACH_LOONGSON_MC146818RTC_H
+
+#include <linux/io.h>
+
+#define RTC_PORT(x)	(0x70 + (x))
+#define RTC_IRQ		8
+
+static inline unsigned char CMOS_READ(unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	return inb_p(RTC_PORT(1));
+}
+
+static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
+{
+	outb_p(addr, RTC_PORT(0));
+	outb_p(data, RTC_PORT(1));
+}
+
+#define RTC_ALWAYS_BCD	0
+
+#ifndef mc146818_decode_year
+#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-loongson/mem.h b/arch/mips/include/asm/mach-loongson/mem.h
new file mode 100644
index 0000000..bd7b3cb
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/mem.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Wu Zhangjin <wuzj@lemote.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_MACH_LOONGSON_MEM_H
+#define __ASM_MACH_LOONGSON_MEM_H
+
+/*
+ * On Lemote Loongson 2e
+ *
+ * the high memory space starts from 512M.
+ * the peripheral registers reside between 0x1000:0000 and 0x2000:0000.
+ */
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+#define LOONGSON_HIGHMEM_START  0x20000000
+
+#define LOONGSON_MMIO_MEM_START 0x10000000
+#define LOONGSON_MMIO_MEM_END   0x20000000
+
+#endif
+
+#endif /* __ASM_MACH_LOONGSON_MEM_H */
diff --git a/arch/mips/include/asm/mach-loongson/pci.h b/arch/mips/include/asm/mach-loongson/pci.h
new file mode 100644
index 0000000..f1663ca
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/pci.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.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 __ASM_MACH_LOONGSON_PCI_H_
+#define __ASM_MACH_LOONGSON_PCI_H_
+
+extern struct pci_ops bonito64_pci_ops;
+
+#ifdef CONFIG_LEMOTE_FULOONG2E
+
+/* this pci memory space is mapped by pcimap in pci.c */
+#define LOONGSON_PCI_MEM_START	BONITO_PCILO1_BASE
+#define LOONGSON_PCI_MEM_END	(BONITO_PCILO1_BASE + 0x04000000 * 2)
+/* this is an offset from mips_io_port_base */
+#define LOONGSON_PCI_IO_START	0x00004000UL
+
+#endif
+
+#endif /* !__ASM_MACH_LOONGSON_PCI_H_ */
diff --git a/arch/mips/include/asm/mach-loongson/war.h b/arch/mips/include/asm/mach-loongson/war.h
new file mode 100644
index 0000000..4b971c3
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/war.h
@@ -0,0 +1,25 @@
+/*
+ * 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_LOONGSON_WAR_H
+#define __ASM_MACH_LOONGSON_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR	0
+#define R4600_V1_HIT_CACHEOP_WAR	0
+#define R4600_V2_HIT_CACHEOP_WAR	0
+#define R5432_CP0_INTERRUPT_WAR		0
+#define BCM1250_M3_WAR			0
+#define SIBYTE_1956_WAR			0
+#define MIPS4K_ICACHE_REFILL_WAR	0
+#define MIPS_CACHE_SYNC_WAR		0
+#define TX49XX_ICACHE_INDEX_INV_WAR	0
+#define RM9000_CDEX_SMP_WAR		0
+#define ICACHE_REFILLS_WORKAROUND_WAR	0
+#define R10000_LLSC_WAR			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MACH_LEMOTE_WAR_H */
diff --git a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
index 7f3e3f9..2848cea 100644
--- a/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-malta/cpu-feature-overrides.h
@@ -28,11 +28,7 @@
 /* #define cpu_has_prefetch	? */
 #define cpu_has_mcheck		1
 /* #define cpu_has_ejtag	? */
-#ifdef CONFIG_CPU_HAS_LLSC
 #define cpu_has_llsc		1
-#else
-#define cpu_has_llsc		0
-#endif
 /* #define cpu_has_vtag_icache	? */
 /* #define cpu_has_dc_aliases	? */
 /* #define cpu_has_ic_fills_f_dc ? */
diff --git a/arch/mips/include/asm/mips-boards/bonito64.h b/arch/mips/include/asm/mips-boards/bonito64.h
index a0f04bb..a576ce0 100644
--- a/arch/mips/include/asm/mips-boards/bonito64.h
+++ b/arch/mips/include/asm/mips-boards/bonito64.h
@@ -26,7 +26,7 @@
 /* offsets from base register */
 #define BONITO(x)	(x)
 
-#elif defined(CONFIG_LEMOTE_FULONG)
+#elif defined(CONFIG_LEMOTE_FULOONG2E)
 
 #define BONITO(x) (*(volatile u32 *)((char *)CKSEG1ADDR(BONITO_REG_BASE) + (x)))
 #define BONITO_IRQ_BASE   32
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h
index c0da1a8..46c0856 100644
--- a/arch/mips/include/asm/mips-boards/generic.h
+++ b/arch/mips/include/asm/mips-boards/generic.h
@@ -87,8 +87,6 @@
 
 extern int mips_revision_sconid;
 
-extern void mips_reboot_setup(void);
-
 #ifdef CONFIG_PCI
 extern void mips_pcibios_init(void);
 #else
diff --git a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
new file mode 100644
index 0000000..4586958
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
@@ -0,0 +1,88 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file 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 file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_RNM_DEFS_H__
+#define __CVMX_RNM_DEFS_H__
+
+#include <linux/types.h>
+
+#define CVMX_RNM_BIST_STATUS \
+	 CVMX_ADD_IO_SEG(0x0001180040000008ull)
+#define CVMX_RNM_CTL_STATUS \
+	 CVMX_ADD_IO_SEG(0x0001180040000000ull)
+
+union cvmx_rnm_bist_status {
+	uint64_t u64;
+	struct cvmx_rnm_bist_status_s {
+		uint64_t reserved_2_63:62;
+		uint64_t rrc:1;
+		uint64_t mem:1;
+	} s;
+	struct cvmx_rnm_bist_status_s cn30xx;
+	struct cvmx_rnm_bist_status_s cn31xx;
+	struct cvmx_rnm_bist_status_s cn38xx;
+	struct cvmx_rnm_bist_status_s cn38xxp2;
+	struct cvmx_rnm_bist_status_s cn50xx;
+	struct cvmx_rnm_bist_status_s cn52xx;
+	struct cvmx_rnm_bist_status_s cn52xxp1;
+	struct cvmx_rnm_bist_status_s cn56xx;
+	struct cvmx_rnm_bist_status_s cn56xxp1;
+	struct cvmx_rnm_bist_status_s cn58xx;
+	struct cvmx_rnm_bist_status_s cn58xxp1;
+};
+
+union cvmx_rnm_ctl_status {
+	uint64_t u64;
+	struct cvmx_rnm_ctl_status_s {
+		uint64_t reserved_9_63:55;
+		uint64_t ent_sel:4;
+		uint64_t exp_ent:1;
+		uint64_t rng_rst:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_en:1;
+		uint64_t ent_en:1;
+	} s;
+	struct cvmx_rnm_ctl_status_cn30xx {
+		uint64_t reserved_4_63:60;
+		uint64_t rng_rst:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_en:1;
+		uint64_t ent_en:1;
+	} cn30xx;
+	struct cvmx_rnm_ctl_status_cn30xx cn31xx;
+	struct cvmx_rnm_ctl_status_cn30xx cn38xx;
+	struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
+	struct cvmx_rnm_ctl_status_s cn50xx;
+	struct cvmx_rnm_ctl_status_s cn52xx;
+	struct cvmx_rnm_ctl_status_s cn52xxp1;
+	struct cvmx_rnm_ctl_status_s cn56xx;
+	struct cvmx_rnm_ctl_status_s cn56xxp1;
+	struct cvmx_rnm_ctl_status_s cn58xx;
+	struct cvmx_rnm_ctl_status_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index e31e3fe..9d9381e 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -271,7 +271,7 @@ static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val)
 	 * what RSL read we do, so we choose CVMX_MIO_BOOT_BIST_STAT
 	 * because it is fast and harmless.
 	 */
-	if ((csr_addr >> 40) == (0x800118))
+	if (((csr_addr >> 40) & 0x7ffff) == (0x118))
 		cvmx_read64(CVMX_MIO_BOOT_BIST_STAT);
 }
 
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index 4320239..f266295 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -10,6 +10,7 @@
 #define _ASM_PAGE_H
 
 #include <spaces.h>
+#include <linux/const.h>
 
 /*
  * PAGE_SHIFT determines the page size
@@ -29,12 +30,12 @@
 #ifdef CONFIG_PAGE_SIZE_64KB
 #define PAGE_SHIFT	16
 #endif
-#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK       (~((1 << PAGE_SHIFT) - 1))
 
 #ifdef CONFIG_HUGETLB_PAGE
 #define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
-#define HPAGE_SIZE	((1UL) << HPAGE_SHIFT)
+#define HPAGE_SIZE	(_AC(1,UL) << HPAGE_SHIFT)
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
 #endif /* CONFIG_HUGETLB_PAGE */
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index a68d111..5ebf825 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -65,8 +65,6 @@ extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
 
 extern unsigned int pcibios_assign_all_busses(void);
 
-#define pcibios_scan_all_fns(a, b)	0
-
 extern unsigned long PCIBIOS_MIN_IO;
 extern unsigned long PCIBIOS_MIN_MEM;
 
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index 4ed9d1b..9cd5089 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -109,13 +109,13 @@
 
 #define VMALLOC_START		MAP_BASE
 #define VMALLOC_END	\
-	(VMALLOC_START + PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE)
+	(VMALLOC_START + \
+	 PTRS_PER_PGD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE - (1UL << 32))
 #if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
 	VMALLOC_START != CKSSEG
 /* Load modules into 32bit-compatible segment. */
 #define MODULE_START	CKSSEG
 #define MODULE_END	(FIXADDR_START-2*PAGE_SIZE)
-extern pgd_t module_pg_dir[PTRS_PER_PGD];
 #endif
 
 #define pte_ERROR(e) \
@@ -188,12 +188,7 @@ static inline void pud_clear(pud_t *pudp)
 #define __pmd_offset(address)	pmd_index(address)
 
 /* to find an entry in a kernel page-table-directory */
-#ifdef MODULE_START
-#define pgd_offset_k(address) \
-	((address) >= MODULE_START ? module_pg_dir : pgd_offset(&init_mm, 0UL))
-#else
-#define pgd_offset_k(address) pgd_offset(&init_mm, 0UL)
-#endif
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 #define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 #define pmd_index(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
diff --git a/arch/mips/include/asm/socket.h b/arch/mips/include/asm/socket.h
index 2abca17..ae05acc 100644
--- a/arch/mips/include/asm/socket.h
+++ b/arch/mips/include/asm/socket.h
@@ -42,6 +42,8 @@ To add: #define SO_REUSEPORT 0x0200	/* Allow local address and port reuse.  */
 #define SO_SNDTIMEO	0x1005	/* send timeout */
 #define SO_RCVTIMEO 	0x1006	/* receive timeout */
 #define SO_ACCEPTCONN	0x1009
+#define SO_PROTOCOL	0x1028	/* protocol type */
+#define SO_DOMAIN	0x1029	/* domain/socket family */
 
 /* linux-specific, might as well be the same as on i386 */
 #define SO_NO_CHECK	11
diff --git a/arch/mips/include/asm/system.h b/arch/mips/include/asm/system.h
index cd30f83..fcf5f98 100644
--- a/arch/mips/include/asm/system.h
+++ b/arch/mips/include/asm/system.h
@@ -32,6 +32,9 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti);
 
 struct task_struct;
 
+extern unsigned int ll_bit;
+extern struct task_struct *ll_task;
+
 #ifdef CONFIG_MIPS_MT_FPAFF
 
 /*
@@ -63,11 +66,18 @@ do {									\
 #define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0)
 #endif
 
+#define __clear_software_ll_bit()					\
+do {									\
+	if (!__builtin_constant_p(cpu_has_llsc) || !cpu_has_llsc)	\
+		ll_bit = 0;						\
+} while (0)
+
 #define switch_to(prev, next, last)					\
 do {									\
 	__mips_mt_fpaff_switch_to(prev);				\
 	if (cpu_has_dsp)						\
 		__save_dsp(prev);					\
+	__clear_software_ll_bit();					\
 	(last) = resume(prev, next, task_thread_info(next));		\
 } while (0)
 
@@ -84,7 +94,7 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
 {
 	__u32 retval;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long dummy;
 
 		__asm__ __volatile__(
@@ -99,7 +109,7 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
 		: "=&r" (retval), "=m" (*m), "=&r" (dummy)
 		: "R" (*m), "Jr" (val)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long dummy;
 
 		__asm__ __volatile__(
@@ -136,7 +146,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
 {
 	__u64 retval;
 
-	if (cpu_has_llsc && R10000_LLSC_WAR) {
+	if (kernel_uses_llsc && R10000_LLSC_WAR) {
 		unsigned long dummy;
 
 		__asm__ __volatile__(
@@ -149,7 +159,7 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
 		: "=&r" (retval), "=m" (*m), "=&r" (dummy)
 		: "R" (*m), "Jr" (val)
 		: "memory");
-	} else if (cpu_has_llsc) {
+	} else if (kernel_uses_llsc) {
 		unsigned long dummy;
 
 		__asm__ __volatile__(
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index e753a77..8c9dfa9 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -353,7 +353,7 @@
 #define __NR_preadv			(__NR_Linux + 330)
 #define __NR_pwritev			(__NR_Linux + 331)
 #define __NR_rt_tgsigqueueinfo		(__NR_Linux + 332)
-#define __NR_perf_counter_open		(__NR_Linux + 333)
+#define __NR_perf_event_open		(__NR_Linux + 333)
 #define __NR_accept4			(__NR_Linux + 334)
 
 /*
@@ -664,7 +664,7 @@
 #define __NR_preadv			(__NR_Linux + 289)
 #define __NR_pwritev			(__NR_Linux + 290)
 #define __NR_rt_tgsigqueueinfo		(__NR_Linux + 291)
-#define __NR_perf_counter_open		(__NR_Linux + 292)
+#define __NR_perf_event_open		(__NR_Linux + 292)
 #define __NR_accept4			(__NR_Linux + 293)
 
 /*
@@ -979,7 +979,7 @@
 #define __NR_preadv			(__NR_Linux + 293)
 #define __NR_pwritev			(__NR_Linux + 294)
 #define __NR_rt_tgsigqueueinfo		(__NR_Linux + 295)
-#define __NR_perf_counter_open		(__NR_Linux + 296)
+#define __NR_perf_event_open		(__NR_Linux + 296)
 #define __NR_accept4			(__NR_Linux + 297)
 
 /*
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 8d006ec..2c1e1d0 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -183,9 +183,6 @@ void output_mm_defines(void)
 	OFFSET(MM_PGD, mm_struct, pgd);
 	OFFSET(MM_CONTEXT, mm_struct, context);
 	BLANK();
-	DEFINE(_PAGE_SIZE, PAGE_SIZE);
-	DEFINE(_PAGE_SHIFT, PAGE_SHIFT);
-	BLANK();
 	DEFINE(_PGD_T_SIZE, sizeof(pgd_t));
 	DEFINE(_PMD_T_SIZE, sizeof(pmd_t));
 	DEFINE(_PTE_T_SIZE, sizeof(pte_t));
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index 02b7713..408d0a0 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -167,7 +167,7 @@ static inline void check_mult_sh(void)
 	panic(bug64hit, !R4000_WAR ? r4kwar : nowar);
 }
 
-static volatile int daddi_ov __cpuinitdata = 0;
+static volatile int daddi_ov __cpuinitdata;
 
 asmlinkage void __init do_daddi_ov(struct pt_regs *regs)
 {
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 1abe990..f709657 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -31,7 +31,7 @@
  * The wait instruction stops the pipeline and reduces the power consumption of
  * the CPU very much.
  */
-void (*cpu_wait)(void) = NULL;
+void (*cpu_wait)(void);
 
 static void r3081_wait(void)
 {
@@ -91,16 +91,13 @@ static void rm7k_wait_irqoff(void)
 	local_irq_enable();
 }
 
-/* The Au1xxx wait is available only if using 32khz counter or
- * external timer source, but specifically not CP0 Counter. */
-int allow_au1k_wait;
-
+/*
+ * The Au1xxx wait is available only if using 32khz counter or
+ * external timer source, but specifically not CP0 Counter.
+ * alchemy/common/time.c may override cpu_wait!
+ */
 static void au1k_wait(void)
 {
-	if (!allow_au1k_wait)
-		return;
-
-	/* using the wait instruction makes CP0 counter unusable */
 	__asm__("	.set	mips3			\n"
 		"	cache	0x14, 0(%0)		\n"
 		"	cache	0x14, 32(%0)		\n"
@@ -115,7 +112,7 @@ static void au1k_wait(void)
 		: : "r" (au1k_wait));
 }
 
-static int __initdata nowait = 0;
+static int __initdata nowait;
 
 static int __init wait_disable(char *s)
 {
@@ -159,6 +156,9 @@ void __init check_wait(void)
 	case CPU_25KF:
 	case CPU_PR4450:
 	case CPU_BCM3302:
+	case CPU_BCM6338:
+	case CPU_BCM6348:
+	case CPU_BCM6358:
 	case CPU_CAVIUM_OCTEON:
 		cpu_wait = r4k_wait;
 		break;
@@ -857,6 +857,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
 	decode_configs(c);
 	switch (c->processor_id & 0xff00) {
 	case PRID_IMP_BCM3302:
+	 /* same as PRID_IMP_BCM6338 */
 		c->cputype = CPU_BCM3302;
 		__cpu_name[cpu] = "Broadcom BCM3302";
 		break;
@@ -864,6 +865,25 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
 		c->cputype = CPU_BCM4710;
 		__cpu_name[cpu] = "Broadcom BCM4710";
 		break;
+	case PRID_IMP_BCM6345:
+		c->cputype = CPU_BCM6345;
+		__cpu_name[cpu] = "Broadcom BCM6345";
+		break;
+	case PRID_IMP_BCM6348:
+		c->cputype = CPU_BCM6348;
+		__cpu_name[cpu] = "Broadcom BCM6348";
+		break;
+	case PRID_IMP_BCM4350:
+		switch (c->processor_id & 0xf0) {
+		case PRID_REV_BCM6358:
+			c->cputype = CPU_BCM6358;
+			__cpu_name[cpu] = "Broadcom BCM6358";
+			break;
+		default:
+			c->cputype = CPU_UNKNOWN;
+			break;
+		}
+		break;
 	}
 }
 
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index fd6e512..f2397f0 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -31,7 +31,7 @@
 #include <asm/rtlx.h>
 #include <asm/kspd.h>
 
-static struct workqueue_struct *workqueue = NULL;
+static struct workqueue_struct *workqueue;
 static struct work_struct work;
 
 extern unsigned long cpu_khz;
@@ -58,7 +58,7 @@ struct mtsp_syscall_generic {
 };
 
 static struct list_head kspd_notifylist;
-static int sp_stopping = 0;
+static int sp_stopping;
 
 /* these should match with those in the SDE kit */
 #define MTSP_SYSCALL_BASE	0
@@ -328,7 +328,7 @@ static void sp_cleanup(void)
 	sys_chdir("/");
 }
 
-static int channel_open = 0;
+static int channel_open;
 
 /* the work handler */
 static void sp_work(struct work_struct *unused)
diff --git a/arch/mips/kernel/mips-mt-fpaff.c b/arch/mips/kernel/mips-mt-fpaff.c
index 4246131..cbc6182 100644
--- a/arch/mips/kernel/mips-mt-fpaff.c
+++ b/arch/mips/kernel/mips-mt-fpaff.c
@@ -18,7 +18,7 @@
 cpumask_t mt_fpu_cpumask;
 
 static int fpaff_threshold = -1;
-unsigned long mt_fpemul_threshold = 0;
+unsigned long mt_fpemul_threshold;
 
 /*
  * Replacement functions for the sys_sched_setaffinity() and
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index d01665a..b2259e7 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -125,10 +125,10 @@ void mips_mt_regdump(unsigned long mvpctl)
 	local_irq_restore(flags);
 }
 
-static int mt_opt_norps = 0;
+static int mt_opt_norps;
 static int mt_opt_rpsctl = -1;
 static int mt_opt_nblsu = -1;
-static int mt_opt_forceconfig7 = 0;
+static int mt_opt_forceconfig7;
 static int mt_opt_config7 = -1;
 
 static int __init rps_disable(char *s)
@@ -161,8 +161,8 @@ static int __init config7_set(char *str)
 __setup("config7=", config7_set);
 
 /* Experimental cache flush control parameters that should go away some day */
-int mt_protiflush = 0;
-int mt_protdflush = 0;
+int mt_protiflush;
+int mt_protdflush;
 int mt_n_iflushes = 1;
 int mt_n_dflushes = 1;
 
@@ -194,7 +194,7 @@ static int __init ndflush(char *s)
 }
 __setup("ndflush=", ndflush);
 
-static unsigned int itc_base = 0;
+static unsigned int itc_base;
 
 static int __init set_itc_base(char *str)
 {
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index d523896..3952b83 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -36,9 +36,6 @@
 	.align	7
 	LEAF(resume)
 	.set arch=octeon
-#ifndef CONFIG_CPU_HAS_LLSC
-	sw	zero, ll_bit
-#endif
 	mfc0	t1, CP0_STATUS
 	LONG_S	t1, THREAD_STATUS(a0)
 	cpu_save_nonscratch a0
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 656bde2..698414b 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -46,9 +46,6 @@
  *                     struct thread_info *next_ti) )
  */
 LEAF(resume)
-#ifndef CONFIG_CPU_HAS_LLSC
-	sw      zero, ll_bit
-#endif
 	mfc0	t1, CP0_STATUS
 	sw	t1, THREAD_STATUS(a0)
 	cpu_save_nonscratch a0
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index d9bfae5..8893ee1 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -45,9 +45,6 @@
  */
 	.align	5
 	LEAF(resume)
-#ifndef CONFIG_CPU_HAS_LLSC
-	sw	zero, ll_bit
-#endif
 	mfc0	t1, CP0_STATUS
 	LONG_S	t1, THREAD_STATUS(a0)
 	cpu_save_nonscratch a0
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 4ce93aa..a10ebfd 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -57,7 +57,7 @@ static struct chan_waitqueues {
 } channel_wqs[RTLX_CHANNELS];
 
 static struct vpe_notifications notify;
-static int sp_stopping = 0;
+static int sp_stopping;
 
 extern void *vpe_get_shared(int index);
 
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index b570821..fd2a9bb 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -187,78 +187,6 @@ illegal_syscall:
 	j	o32_syscall_exit
 	END(handle_sys)
 
-	LEAF(mips_atomic_set)
-	andi	v0, a1, 3			# must be word aligned
-	bnez	v0, bad_alignment
-
-	lw	v1, TI_ADDR_LIMIT($28)		# in legal address range?
-	addiu	a0, a1, 4
-	or	a0, a0, a1
-	and	a0, a0, v1
-	bltz	a0, bad_address
-
-#ifdef CONFIG_CPU_HAS_LLSC
-	/* Ok, this is the ll/sc case.  World is sane :-)  */
-1:	ll	v0, (a1)
-	move	a0, a2
-2:	sc	a0, (a1)
-#if R10000_LLSC_WAR
-	beqzl	a0, 1b
-#else
-	beqz	a0, 1b
-#endif
-
-	.section __ex_table,"a"
-	PTR	1b, bad_stack
-	PTR	2b, bad_stack
-	.previous
-#else
-	sw	a1, 16(sp)
-	sw	a2, 20(sp)
-
-	move	a0, sp
-	move	a2, a1
-	li	a1, 1
-	jal	do_page_fault
-
-	lw	a1, 16(sp)
-	lw	a2, 20(sp)
-
-	/*
-	 * At this point the page should be readable and writable unless
-	 * there was no more memory available.
-	 */
-1:	lw	v0, (a1)
-2:	sw	a2, (a1)
-
-	.section __ex_table,"a"
-	PTR	1b, no_mem
-	PTR	2b, no_mem
-	.previous
-#endif
-
-	sw	zero, PT_R7(sp)		# success
-	sw	v0, PT_R2(sp)		# result
-
-	j	o32_syscall_exit	# continue like a normal syscall
-
-no_mem:	li	v0, -ENOMEM
-	jr	ra
-
-bad_address:
-	li	v0, -EFAULT
-	jr	ra
-
-bad_alignment:
-	li	v0, -EINVAL
-	jr	ra
-	END(mips_atomic_set)
-
-	LEAF(sys_sysmips)
-	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
-	j	_sys_sysmips
-	END(sys_sysmips)
-
 	LEAF(sys_syscall)
 	subu	t0, a0, __NR_O32_Linux	# check syscall number
 	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
@@ -653,7 +581,7 @@ einval:	li	v0, -ENOSYS
 	sys	sys_preadv		6	/* 4330 */
 	sys	sys_pwritev		6
 	sys	sys_rt_tgsigqueueinfo	4
-	sys	sys_perf_counter_open	5
+	sys	sys_perf_event_open	5
 	sys	sys_accept4		4
 	.endm
 
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 3d866f2..18bf7f3 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -124,78 +124,6 @@ illegal_syscall:
 	j	n64_syscall_exit
 	END(handle_sys64)
 
-	LEAF(mips_atomic_set)
-	andi	v0, a1, 3			# must be word aligned
-	bnez	v0, bad_alignment
-
-	LONG_L	v1, TI_ADDR_LIMIT($28)		# in legal address range?
-	LONG_ADDIU	a0, a1, 4
-	or	a0, a0, a1
-	and	a0, a0, v1
-	bltz	a0, bad_address
-
-#ifdef CONFIG_CPU_HAS_LLSC
-	/* Ok, this is the ll/sc case.  World is sane :-)  */
-1:	ll	v0, (a1)
-	move	a0, a2
-2:	sc	a0, (a1)
-#if R10000_LLSC_WAR
-	beqzl	a0, 1b
-#else
-	beqz	a0, 1b
-#endif
-
-	.section __ex_table,"a"
-	PTR	1b, bad_stack
-	PTR	2b, bad_stack
-	.previous
-#else
-	sw	a1, 16(sp)
-	sw	a2, 20(sp)
-
-	move	a0, sp
-	move	a2, a1
-	li	a1, 1
-	jal	do_page_fault
-
-	lw	a1, 16(sp)
-	lw	a2, 20(sp)
-
-	/*
-	 * At this point the page should be readable and writable unless
-	 * there was no more memory available.
-	 */
-1:	lw	v0, (a1)
-2:	sw	a2, (a1)
-
-	.section __ex_table,"a"
-	PTR	1b, no_mem
-	PTR	2b, no_mem
-	.previous
-#endif
-
-	sd	zero, PT_R7(sp)		# success
-	sd	v0, PT_R2(sp)		# result
-
-	j	n64_syscall_exit	# continue like a normal syscall
-
-no_mem:	li	v0, -ENOMEM
-	jr	ra
-
-bad_address:
-	li	v0, -EFAULT
-	jr	ra
-
-bad_alignment:
-	li	v0, -EINVAL
-	jr	ra
-	END(mips_atomic_set)
-
-	LEAF(sys_sysmips)
-	beq	a0, MIPS_ATOMIC_SET, mips_atomic_set
-	j	_sys_sysmips
-	END(sys_sysmips)
-
 	.align	3
 sys_call_table:
 	PTR	sys_read			/* 5000 */
@@ -490,6 +418,6 @@ sys_call_table:
 	PTR	sys_preadv
 	PTR	sys_pwritev			/* 5390 */
 	PTR	sys_rt_tgsigqueueinfo
-	PTR	sys_perf_counter_open
+	PTR	sys_perf_event_open
 	PTR	sys_accept4
 	.size	sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index e855b11..6ebc079 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -164,7 +164,7 @@ EXPORT(sysn32_call_table)
 	PTR	sys_connect
 	PTR	sys_accept
 	PTR	sys_sendto
-	PTR	sys_recvfrom
+	PTR	compat_sys_recvfrom
 	PTR	compat_sys_sendmsg		/* 6045 */
 	PTR	compat_sys_recvmsg
 	PTR	sys_shutdown
@@ -416,6 +416,6 @@ EXPORT(sysn32_call_table)
 	PTR	sys_preadv
 	PTR	sys_pwritev
 	PTR	compat_sys_rt_tgsigqueueinfo	/* 5295 */
-	PTR	sys_perf_counter_open
+	PTR	sys_perf_event_open
 	PTR	sys_accept4
 	.size	sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 0c49f1a..9bbf977 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -378,8 +378,8 @@ sys_call_table:
 	PTR	sys_getsockname
 	PTR	sys_getsockopt
 	PTR	sys_listen
-	PTR	sys_recv			/* 4175 */
-	PTR	sys_recvfrom
+	PTR	compat_sys_recv			/* 4175 */
+	PTR	compat_sys_recvfrom
 	PTR	compat_sys_recvmsg
 	PTR	sys_send
 	PTR	compat_sys_sendmsg
@@ -536,6 +536,6 @@ sys_call_table:
 	PTR	compat_sys_preadv		/* 4330 */
 	PTR	compat_sys_pwritev
 	PTR	compat_sys_rt_tgsigqueueinfo
-	PTR	sys_perf_counter_open
+	PTR	sys_perf_event_open
 	PTR	sys_accept4
 	.size	sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 2950b97..2b290d7 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -441,7 +441,7 @@ static void __init bootmem_init(void)
  * initialization hook for anything else was introduced.
  */
 
-static int usermem __initdata = 0;
+static int usermem __initdata;
 
 static int __init early_parse_mem(char *p)
 {
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index bc7d9b0..64668a9 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -32,6 +32,7 @@
 #include <linux/cpumask.h>
 #include <linux/cpu.h>
 #include <linux/err.h>
+#include <linux/smp.h>
 
 #include <asm/atomic.h>
 #include <asm/cpu.h>
@@ -49,8 +50,6 @@ volatile cpumask_t cpu_callin_map;	/* Bitmask of started secondaries */
 int __cpu_number_map[NR_CPUS];		/* Map physical to logical */
 int __cpu_logical_map[NR_CPUS];		/* Map logical to physical */
 
-extern void cpu_idle(void);
-
 /* Number of TCs (or siblings in Intel speak) per CPU core */
 int smp_num_siblings = 1;
 EXPORT_SYMBOL(smp_num_siblings);
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index c16bb6d..1a466ba 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -95,14 +95,14 @@ void init_smtc_stats(void);
 
 /* Global SMTC Status */
 
-unsigned int smtc_status = 0;
+unsigned int smtc_status;
 
 /* Boot command line configuration overrides */
 
 static int vpe0limit;
-static int ipibuffers = 0;
-static int nostlb = 0;
-static int asidmask = 0;
+static int ipibuffers;
+static int nostlb;
+static int asidmask;
 unsigned long smtc_asid_mask = 0xff;
 
 static int __init vpe0tcs(char *str)
@@ -151,7 +151,7 @@ __setup("asidmask=", asidmask_set);
 
 #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
 
-static int hang_trig = 0;
+static int hang_trig;
 
 static int __init hangtrig_enable(char *s)
 {
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 8cf3846..3fe1fcf 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -28,7 +28,9 @@
 #include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/ipc.h>
+#include <linux/uaccess.h>
 
+#include <asm/asm.h>
 #include <asm/branch.h>
 #include <asm/cachectl.h>
 #include <asm/cacheflush.h>
@@ -290,12 +292,116 @@ SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
 	return 0;
 }
 
-asmlinkage int _sys_sysmips(long cmd, long arg1, long arg2, long arg3)
+static inline int mips_atomic_set(struct pt_regs *regs,
+	unsigned long addr, unsigned long new)
 {
+	unsigned long old, tmp;
+	unsigned int err;
+
+	if (unlikely(addr & 3))
+		return -EINVAL;
+
+	if (unlikely(!access_ok(VERIFY_WRITE, addr, 4)))
+		return -EINVAL;
+
+	if (cpu_has_llsc && R10000_LLSC_WAR) {
+		__asm__ __volatile__ (
+		"	li	%[err], 0				\n"
+		"1:	ll	%[old], (%[addr])			\n"
+		"	move	%[tmp], %[new]				\n"
+		"2:	sc	%[tmp], (%[addr])			\n"
+		"	beqzl	%[tmp], 1b				\n"
+		"3:							\n"
+		"	.section .fixup,\"ax\"				\n"
+		"4:	li	%[err], %[efault]			\n"
+		"	j	3b					\n"
+		"	.previous					\n"
+		"	.section __ex_table,\"a\"			\n"
+		"	"STR(PTR)"	1b, 4b				\n"
+		"	"STR(PTR)"	2b, 4b				\n"
+		"	.previous					\n"
+		: [old] "=&r" (old),
+		  [err] "=&r" (err),
+		  [tmp] "=&r" (tmp)
+		: [addr] "r" (addr),
+		  [new] "r" (new),
+		  [efault] "i" (-EFAULT)
+		: "memory");
+	} else if (cpu_has_llsc) {
+		__asm__ __volatile__ (
+		"	li	%[err], 0				\n"
+		"1:	ll	%[old], (%[addr])			\n"
+		"	move	%[tmp], %[new]				\n"
+		"2:	sc	%[tmp], (%[addr])			\n"
+		"	bnez	%[tmp], 4f				\n"
+		"3:							\n"
+		"	.subsection 2					\n"
+		"4:	b	1b					\n"
+		"	.previous					\n"
+		"							\n"
+		"	.section .fixup,\"ax\"				\n"
+		"5:	li	%[err], %[efault]			\n"
+		"	j	3b					\n"
+		"	.previous					\n"
+		"	.section __ex_table,\"a\"			\n"
+		"	"STR(PTR)"	1b, 5b				\n"
+		"	"STR(PTR)"	2b, 5b				\n"
+		"	.previous					\n"
+		: [old] "=&r" (old),
+		  [err] "=&r" (err),
+		  [tmp] "=&r" (tmp)
+		: [addr] "r" (addr),
+		  [new] "r" (new),
+		  [efault] "i" (-EFAULT)
+		: "memory");
+	} else {
+		do {
+			preempt_disable();
+			ll_bit = 1;
+			ll_task = current;
+			preempt_enable();
+
+			err = __get_user(old, (unsigned int *) addr);
+			err |= __put_user(new, (unsigned int *) addr);
+			if (err)
+				break;
+			rmb();
+		} while (!ll_bit);
+	}
+
+	if (unlikely(err))
+		return err;
+
+	regs->regs[2] = old;
+	regs->regs[7] = 0;	/* No error */
+
+	/*
+	 * Don't let your children do this ...
+	 */
+	__asm__ __volatile__(
+	"	move	$29, %0						\n"
+	"	j	syscall_exit					\n"
+	: /* no outputs */
+	: "r" (regs));
+
+	/* unreached.  Honestly.  */
+	while (1);
+}
+
+save_static_function(sys_sysmips);
+static int __used noinline
+_sys_sysmips(nabi_no_regargs struct pt_regs regs)
+{
+	long cmd, arg1, arg2, arg3;
+
+	cmd = regs.regs[4];
+	arg1 = regs.regs[5];
+	arg2 = regs.regs[6];
+	arg3 = regs.regs[7];
+
 	switch (cmd) {
 	case MIPS_ATOMIC_SET:
-		printk(KERN_CRIT "How did I get here?\n");
-		return -EINVAL;
+		return mips_atomic_set(&regs, arg1, arg2);
 
 	case MIPS_FIXADE:
 		if (arg1 & ~3)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 08f1edf..0a18b4c 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -466,9 +466,8 @@ asmlinkage void do_be(struct pt_regs *regs)
  * The ll_bit is cleared by r*_switch.S
  */
 
-unsigned long ll_bit;
-
-static struct task_struct *ll_task = NULL;
+unsigned int ll_bit;
+struct task_struct *ll_task;
 
 static inline int simulate_ll(struct pt_regs *regs, unsigned int opcode)
 {
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 58738c8..2769bed 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -1,4 +1,5 @@
 #include <asm/asm-offsets.h>
+#include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
 
 #undef mips
@@ -42,13 +43,7 @@ SECTIONS
 	} :text = 0
 	_etext = .;	/* End of text section */
 
-	/* Exception table */
-	. = ALIGN(16);
-	__ex_table : {
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-	}
+	EXCEPTION_TABLE(16)
 
 	/* Exception table for data bus errors */
 	__dbe_table : {
@@ -65,20 +60,10 @@ SECTIONS
 	/* writeable */
 	.data : {	/* Data */
 		. = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */
-		/*
-		 * This ALIGN is needed as a workaround for a bug a
-		 * gcc bug upto 4.1 which limits the maximum alignment
-		 * to at most 32kB and results in the following
-		 * warning:
-		 *
-		 *  CC      arch/mips/kernel/init_task.o
-		 * arch/mips/kernel/init_task.c:30: warning: alignment
-		 * of â€˜init_thread_unionâ€™ is greater than maximum
-		 * object file alignment.  Using 32768
-		 */
-		. = ALIGN(_PAGE_SIZE);
-		*(.data.init_task)
 
+		INIT_TASK_DATA(PAGE_SIZE)
+		NOSAVE_DATA
+		CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
 		DATA_DATA
 		CONSTRUCTORS
 	}
@@ -95,51 +80,13 @@ SECTIONS
 	.sdata : {
 		*(.sdata)
 	}
-
-	. = ALIGN(_PAGE_SIZE);
-	.data_nosave : {
-		__nosave_begin = .;
-		*(.data.nosave)
-	}
-	. = ALIGN(_PAGE_SIZE);
-	__nosave_end = .;
-
-	. = ALIGN(1 << CONFIG_MIPS_L1_CACHE_SHIFT);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
-	}
 	_edata =  .;			/* End of data section */
 
 	/* will be freed after init */
-	. = ALIGN(_PAGE_SIZE);		/* Init code and data */
+	. = ALIGN(PAGE_SIZE);		/* Init code and data */
 	__init_begin = .;
-	.init.text : {
-		_sinittext = .;
-		INIT_TEXT
-		_einittext = .;
-	}
-	.init.data : {
-		INIT_DATA
-	}
-	. = ALIGN(16);
-	.init.setup : {
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-	}
-
-	.initcall.init : {
-		__initcall_start = .;
-		INITCALLS
-		__initcall_end = .;
-	}
-
-	.con_initcall.init : {
-		__con_initcall_start = .;
-		*(.con_initcall.init)
-		__con_initcall_end = .;
-	}
-	SECURITY_INIT
+	INIT_TEXT_SECTION(PAGE_SIZE)
+	INIT_DATA_SECTION(16)
 
 	/* .exit.text is discarded at runtime, not link time, to deal with
 	 * references from .rodata
@@ -150,43 +97,16 @@ SECTIONS
 	.exit.data : {
 		EXIT_DATA
 	}
-#if defined(CONFIG_BLK_DEV_INITRD)
-	. = ALIGN(_PAGE_SIZE);
-	.init.ramfs : {
-		__initramfs_start = .;
-		*(.init.ramfs)
-		__initramfs_end = .;
-	}
-#endif
-	PERCPU(_PAGE_SIZE)
-	. = ALIGN(_PAGE_SIZE);
+
+	PERCPU(PAGE_SIZE)
+	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
 	/* freed after init ends here */
 
-	__bss_start = .;	/* BSS */
-	.sbss  : {
-		*(.sbss)
-		*(.scommon)
-	}
-	.bss : {
-		*(.bss)
-		*(COMMON)
-	}
-	__bss_stop = .;
+	BSS_SECTION(0, 0, 0)
 
 	_end = . ;
 
-	/* Sections to be discarded */
-	/DISCARD/ : {
-		*(.exitcall.exit)
-
-		/* ABI crap starts here */
-		*(.MIPS.options)
-		*(.options)
-		*(.pdr)
-		*(.reginfo)
-	}
-
 	/* These mark the ABI of the kernel for debuggers.  */
 	.mdebug.abi32 : {
 		KEEP(*(.mdebug.abi32))
@@ -212,4 +132,14 @@ SECTIONS
 		*(.gptab.bss)
 		*(.gptab.sbss)
 	}
+
+	/* Sections to be discarded */
+	DISCARDS
+	/DISCARD/ : {
+		/* ABI crap starts here */
+		*(.MIPS.options)
+		*(.options)
+		*(.pdr)
+		*(.reginfo)
+	}
 }
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 9a1ab7e..eb6c4c5 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -74,7 +74,7 @@ static const int minor = 1;	/* fixed for now  */
 
 #ifdef CONFIG_MIPS_APSP_KSPD
 static struct kspd_notifications kspd_events;
-static int kspd_events_reqd = 0;
+static int kspd_events_reqd;
 #endif
 
 /* grab the likely amount of memory we will need. */
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c
index 52cb143..c6fd96f 100644
--- a/arch/mips/lasat/ds1603.c
+++ b/arch/mips/lasat/ds1603.c
@@ -135,7 +135,7 @@ static void rtc_end_op(void)
 	lasat_ndelay(1000);
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
 	unsigned long word;
 	unsigned long flags;
@@ -147,7 +147,8 @@ unsigned long read_persistent_clock(void)
 	rtc_end_op();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
-	return word;
+	ts->tv_sec = word;
+	ts->tv_nsec = 0;
 }
 
 int rtc_mips_set_mmss(unsigned long time)
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
index 8f88886..3f04d4c 100644
--- a/arch/mips/lasat/sysctl.c
+++ b/arch/mips/lasat/sysctl.c
@@ -92,10 +92,12 @@ static int rtctmp;
 int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
+	struct timespec ts;
 	int r;
 
 	if (!write) {
-		rtctmp = read_persistent_clock();
+		read_persistent_clock(&ts);
+		rtctmp = ts.tv_sec;
 		/* check for time < 0 and set to 0 */
 		if (rtctmp < 0)
 			rtctmp = 0;
@@ -134,9 +136,11 @@ int sysctl_lasat_rtc(ctl_table *table,
 		    void *oldval, size_t *oldlenp,
 		    void *newval, size_t newlen)
 {
+	struct timespec ts;
 	int r;
 
-	rtctmp = read_persistent_clock();
+	read_persistent_clock(&ts);
+	rtctmp = ts.tv_sec;
 	if (rtctmp < 0)
 		rtctmp = 0;
 	r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
diff --git a/arch/mips/lemote/lm2e/Makefile b/arch/mips/lemote/lm2e/Makefile
deleted file mode 100644
index d34671d..0000000
--- a/arch/mips/lemote/lm2e/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for Lemote Fulong mini-PC board.
-#
-
-obj-y += setup.o prom.o reset.o irq.o pci.o bonito-irq.o dbg_io.o mem.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/lemote/lm2e/bonito-irq.c b/arch/mips/lemote/lm2e/bonito-irq.c
deleted file mode 100644
index 8fc3bce..0000000
--- a/arch/mips/lemote/lm2e/bonito-irq.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You 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.
- *
- */
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/mips-boards/bonito64.h>
-
-
-static inline void bonito_irq_enable(unsigned int irq)
-{
-	BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
-	mmiowb();
-}
-
-static inline void bonito_irq_disable(unsigned int irq)
-{
-	BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
-	mmiowb();
-}
-
-static struct irq_chip bonito_irq_type = {
-	.name	= "bonito_irq",
-	.ack	= bonito_irq_disable,
-	.mask	= bonito_irq_disable,
-	.mask_ack = bonito_irq_disable,
-	.unmask	= bonito_irq_enable,
-};
-
-static struct irqaction dma_timeout_irqaction = {
-	.handler	= no_action,
-	.name		= "dma_timeout",
-};
-
-void bonito_irq_init(void)
-{
-	u32 i;
-
-	for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++) {
-		set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
-	}
-
-	setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
-}
diff --git a/arch/mips/lemote/lm2e/dbg_io.c b/arch/mips/lemote/lm2e/dbg_io.c
deleted file mode 100644
index 6c95da3..0000000
--- a/arch/mips/lemote/lm2e/dbg_io.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2001 MontaVista Software Inc.
- * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You 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.
- *
- */
-
-#include <linux/io.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/serial.h>
-
-#define         UART16550_BAUD_2400             2400
-#define         UART16550_BAUD_4800             4800
-#define         UART16550_BAUD_9600             9600
-#define         UART16550_BAUD_19200            19200
-#define         UART16550_BAUD_38400            38400
-#define         UART16550_BAUD_57600            57600
-#define         UART16550_BAUD_115200           115200
-
-#define         UART16550_PARITY_NONE           0
-#define         UART16550_PARITY_ODD            0x08
-#define         UART16550_PARITY_EVEN           0x18
-#define         UART16550_PARITY_MARK           0x28
-#define         UART16550_PARITY_SPACE          0x38
-
-#define         UART16550_DATA_5BIT             0x0
-#define         UART16550_DATA_6BIT             0x1
-#define         UART16550_DATA_7BIT             0x2
-#define         UART16550_DATA_8BIT             0x3
-
-#define         UART16550_STOP_1BIT             0x0
-#define         UART16550_STOP_2BIT             0x4
-
-/* ----------------------------------------------------- */
-
-/* === CONFIG === */
-#ifdef CONFIG_64BIT
-#define         BASE                    (0xffffffffbfd003f8)
-#else
-#define         BASE                    (0xbfd003f8)
-#endif
-
-#define         MAX_BAUD                BASE_BAUD
-/* === END OF CONFIG === */
-
-#define         REG_OFFSET              1
-
-/* register offset */
-#define         OFS_RCV_BUFFER          0
-#define         OFS_TRANS_HOLD          0
-#define         OFS_SEND_BUFFER         0
-#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
-#define         OFS_INTR_ID             (2*REG_OFFSET)
-#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
-#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
-#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
-#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
-#define         OFS_LINE_STATUS         (5*REG_OFFSET)
-#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
-#define         OFS_RS232_INPUT         (6*REG_OFFSET)
-#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
-
-#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
-#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
-
-/* memory-mapped read/write of the port */
-#define         UART16550_READ(y)	readb((char *)BASE + (y))
-#define         UART16550_WRITE(y, z)	writeb(z, (char *)BASE + (y))
-
-void debugInit(u32 baud, u8 data, u8 parity, u8 stop)
-{
-	u32 divisor;
-
-	/* disable interrupts */
-	UART16550_WRITE(OFS_INTR_ENABLE, 0);
-
-	/* set up buad rate */
-	/* set DIAB bit */
-	UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
-
-	/* set divisor */
-	divisor = MAX_BAUD / baud;
-	UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
-	UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
-
-	/* clear DIAB bit */
-	UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
-
-	/* set data format */
-	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
-}
-
-static int remoteDebugInitialized;
-
-u8 getDebugChar(void)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		debugInit(UART16550_BAUD_115200,
-			  UART16550_DATA_8BIT,
-			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
-	}
-
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0) ;
-	return UART16550_READ(OFS_RCV_BUFFER);
-}
-
-int putDebugChar(u8 byte)
-{
-	if (!remoteDebugInitialized) {
-		remoteDebugInitialized = 1;
-		/*
-		   debugInit(UART16550_BAUD_115200,
-		   UART16550_DATA_8BIT,
-		   UART16550_PARITY_NONE, UART16550_STOP_1BIT); */
-	}
-
-	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0) ;
-	UART16550_WRITE(OFS_SEND_BUFFER, byte);
-	return 1;
-}
diff --git a/arch/mips/lemote/lm2e/irq.c b/arch/mips/lemote/lm2e/irq.c
deleted file mode 100644
index 1d0a09f..0000000
--- a/arch/mips/lemote/lm2e/irq.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You 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.
- *
- */
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/i8259.h>
-#include <asm/mipsregs.h>
-#include <asm/mips-boards/bonito64.h>
-
-
-/*
- * the first level int-handler will jump here if it is a bonito irq
- */
-static void bonito_irqdispatch(void)
-{
-	u32 int_status;
-	int i;
-
-	/* workaround the IO dma problem: let cpu looping to allow DMA finish */
-	int_status = BONITO_INTISR;
-	if (int_status & (1 << 10)) {
-		while (int_status & (1 << 10)) {
-			udelay(1);
-			int_status = BONITO_INTISR;
-		}
-	}
-
-	/* Get pending sources, masked by current enables */
-	int_status = BONITO_INTISR & BONITO_INTEN;
-
-	if (int_status != 0) {
-		i = __ffs(int_status);
-		int_status &= ~(1 << i);
-		do_IRQ(BONITO_IRQ_BASE + i);
-	}
-}
-
-static void i8259_irqdispatch(void)
-{
-	int irq;
-
-	irq = i8259_irq();
-	if (irq >= 0) {
-		do_IRQ(irq);
-	} else {
-		spurious_interrupt();
-	}
-
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
-
-	if (pending & CAUSEF_IP7) {
-		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
-	} else if (pending & CAUSEF_IP5) {
-		i8259_irqdispatch();
-	} else if (pending & CAUSEF_IP2) {
-		bonito_irqdispatch();
-	} else {
-		spurious_interrupt();
-	}
-}
-
-static struct irqaction cascade_irqaction = {
-	.handler = no_action,
-	.name = "cascade",
-};
-
-void __init arch_init_irq(void)
-{
-	extern void bonito_irq_init(void);
-
-	/*
-	 * Clear all of the interrupts while we change the able around a bit.
-	 * int-handler is not on bootstrap
-	 */
-	clear_c0_status(ST0_IM | ST0_BEV);
-	local_irq_disable();
-
-	/* most bonito irq should be level triggered */
-	BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
-		BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
-	BONITO_INTSTEER = 0;
-
-	/*
-	 * Mask out all interrupt by writing "1" to all bit position in
-	 * the interrupt reset reg.
-	 */
-	BONITO_INTENCLR = ~0;
-
-	/* init all controller
-	 *   0-15         ------> i8259 interrupt
-	 *   16-23        ------> mips cpu interrupt
-	 *   32-63        ------> bonito irq
-	 */
-
-	/* Sets the first-level interrupt dispatcher. */
-	mips_cpu_irq_init();
-	init_i8259_irqs();
-	bonito_irq_init();
-
-	/*
-	printk("GPIODATA=%x, GPIOIE=%x\n", BONITO_GPIODATA, BONITO_GPIOIE);
-	printk("INTEN=%x, INTSET=%x, INTCLR=%x, INTISR=%x\n",
-			BONITO_INTEN, BONITO_INTENSET,
-			BONITO_INTENCLR, BONITO_INTISR);
-	*/
-
-	/* bonito irq at IP2 */
-	setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
-	/* 8259 irq at IP5 */
-	setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
-
-}
diff --git a/arch/mips/lemote/lm2e/mem.c b/arch/mips/lemote/lm2e/mem.c
deleted file mode 100644
index 16cd215..0000000
--- a/arch/mips/lemote/lm2e/mem.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the 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/fs.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-
-/* override of arch/mips/mm/cache.c: __uncached_access */
-int __uncached_access(struct file *file, unsigned long addr)
-{
-	if (file->f_flags & O_SYNC)
-		return 1;
-
-	/*
-	 * On the Lemote Loongson 2e system, the peripheral registers
-	 * reside between 0x1000:0000 and 0x2000:0000.
-	 */
-	return addr >= __pa(high_memory) ||
-		((addr >= 0x10000000) && (addr < 0x20000000));
-}
diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c
deleted file mode 100644
index 8be03a8..0000000
--- a/arch/mips/lemote/lm2e/pci.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * pci.c
- *
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You 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.
- *
- */
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <asm/mips-boards/bonito64.h>
-#include <asm/mach-lemote/pci.h>
-
-extern struct pci_ops bonito64_pci_ops;
-
-static struct resource loongson2e_pci_mem_resource = {
-	.name   = "LOONGSON2E PCI MEM",
-	.start  = LOONGSON2E_PCI_MEM_START,
-	.end    = LOONGSON2E_PCI_MEM_END,
-	.flags  = IORESOURCE_MEM,
-};
-
-static struct resource loongson2e_pci_io_resource = {
-	.name   = "LOONGSON2E PCI IO MEM",
-	.start  = LOONGSON2E_PCI_IO_START,
-	.end    = IO_SPACE_LIMIT,
-	.flags  = IORESOURCE_IO,
-};
-
-static struct pci_controller  loongson2e_pci_controller = {
-	.pci_ops        = &bonito64_pci_ops,
-	.io_resource    = &loongson2e_pci_io_resource,
-	.mem_resource   = &loongson2e_pci_mem_resource,
-	.mem_offset     = 0x00000000UL,
-	.io_offset      = 0x00000000UL,
-};
-
-static void __init ict_pcimap(void)
-{
-	/*
-	 * local to PCI mapping: [256M,512M] -> [256M,512M]; differ from PMON
-	 *
-	 * CPU address space [256M,448M] is window for accessing pci space
-	 * we set pcimap_lo[0,1,2] to map it to pci space [256M,448M]
-	 * pcimap: bit18,pcimap_2; bit[17-12],lo2;bit[11-6],lo1;bit[5-0],lo0
-	 */
-	/* 1,00 0110 ,0001 01,00 0000 */
-	BONITO_PCIMAP = 0x46140;
-
-	/* 1, 00 0010, 0000,01, 00 0000 */
-	/* BONITO_PCIMAP = 0x42040; */
-
-	/*
-	 * PCI to local mapping: [2G,2G+256M] -> [0,256M]
-	 */
-	BONITO_PCIBASE0 = 0x80000000;
-	BONITO_PCIBASE1 = 0x00800000;
-	BONITO_PCIBASE2 = 0x90000000;
-
-}
-
-static int __init pcibios_init(void)
-{
-	ict_pcimap();
-
-	loongson2e_pci_controller.io_map_base =
-	    (unsigned long) ioremap(LOONGSON2E_IO_PORT_BASE,
-				    loongson2e_pci_io_resource.end -
-				    loongson2e_pci_io_resource.start + 1);
-
-	register_pci_controller(&loongson2e_pci_controller);
-
-	return 0;
-}
-
-arch_initcall(pcibios_init);
diff --git a/arch/mips/lemote/lm2e/prom.c b/arch/mips/lemote/lm2e/prom.c
deleted file mode 100644
index 7edc15d..0000000
--- a/arch/mips/lemote/lm2e/prom.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Based on Ocelot Linux port, which is
- * Copyright 2001 MontaVista Software Inc.
- * Author: jsun@mvista.com or jsun@junsun.net
- *
- * Copyright 2003 ICT CAS
- * Author: Michael Guo <guoyi@ict.ac.cn>
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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/init.h>
-#include <linux/bootmem.h>
-#include <asm/bootinfo.h>
-
-extern unsigned long bus_clock;
-extern unsigned long cpu_clock_freq;
-extern unsigned int memsize, highmemsize;
-extern int putDebugChar(unsigned char byte);
-
-static int argc;
-/* pmon passes arguments in 32bit pointers */
-static int *arg;
-static int *env;
-
-const char *get_system_type(void)
-{
-	return "lemote-fulong";
-}
-
-void __init prom_init_cmdline(void)
-{
-	int i;
-	long l;
-
-	/* arg[0] is "g", the rest is boot parameters */
-	arcs_cmdline[0] = '\0';
-	for (i = 1; i < argc; i++) {
-		l = (long)arg[i];
-		if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
-		    >= sizeof(arcs_cmdline))
-			break;
-		strcat(arcs_cmdline, ((char *)l));
-		strcat(arcs_cmdline, " ");
-	}
-}
-
-void __init prom_init(void)
-{
-	long l;
-	argc = fw_arg0;
-	arg = (int *)fw_arg1;
-	env = (int *)fw_arg2;
-
-	prom_init_cmdline();
-
-	if ((strstr(arcs_cmdline, "console=")) == NULL)
-		strcat(arcs_cmdline, " console=ttyS0,115200");
-	if ((strstr(arcs_cmdline, "root=")) == NULL)
-		strcat(arcs_cmdline, " root=/dev/hda1");
-
-#define parse_even_earlier(res, option, p)				\
-do {									\
-	if (strncmp(option, (char *)p, strlen(option)) == 0)		\
-		res = simple_strtol((char *)p + strlen(option"="),	\
-				    NULL, 10);				\
-} while (0)
-
-	l = (long)*env;
-	while (l != 0) {
-		parse_even_earlier(bus_clock, "busclock", l);
-		parse_even_earlier(cpu_clock_freq, "cpuclock", l);
-		parse_even_earlier(memsize, "memsize", l);
-		parse_even_earlier(highmemsize, "highmemsize", l);
-		env++;
-		l = (long)*env;
-	}
-	if (memsize == 0)
-		memsize = 256;
-
-	pr_info("busclock=%ld, cpuclock=%ld,memsize=%d,highmemsize=%d\n",
-	       bus_clock, cpu_clock_freq, memsize, highmemsize);
-}
-
-void __init prom_free_prom_memory(void)
-{
-}
-
-void prom_putchar(char c)
-{
-	putDebugChar(c);
-}
diff --git a/arch/mips/lemote/lm2e/reset.c b/arch/mips/lemote/lm2e/reset.c
deleted file mode 100644
index 099387a..0000000
--- a/arch/mips/lemote/lm2e/reset.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- *
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.com
- */
-#include <linux/pm.h>
-
-#include <asm/reboot.h>
-
-static void loongson2e_restart(char *command)
-{
-#ifdef CONFIG_32BIT
-	*(unsigned long *)0xbfe00104 &= ~(1 << 2);
-	*(unsigned long *)0xbfe00104 |= (1 << 2);
-#else
-	*(unsigned long *)0xffffffffbfe00104 &= ~(1 << 2);
-	*(unsigned long *)0xffffffffbfe00104 |= (1 << 2);
-#endif
-	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-static void loongson2e_halt(void)
-{
-	while (1) ;
-}
-
-static void loongson2e_power_off(void)
-{
-	loongson2e_halt();
-}
-
-void mips_reboot_setup(void)
-{
-	_machine_restart = loongson2e_restart;
-	_machine_halt = loongson2e_halt;
-	pm_power_off = loongson2e_power_off;
-}
diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c
deleted file mode 100644
index ebd6cea..0000000
--- a/arch/mips/lemote/lm2e/setup.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * setup.c - board dependent boot routines
- *
- * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You 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.
- *
- */
-#include <linux/bootmem.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/bootinfo.h>
-#include <asm/mc146818-time.h>
-#include <asm/time.h>
-#include <asm/wbflush.h>
-#include <asm/mach-lemote/pci.h>
-
-#ifdef CONFIG_VT
-#include <linux/console.h>
-#include <linux/screen_info.h>
-#endif
-
-extern void mips_reboot_setup(void);
-
-unsigned long cpu_clock_freq;
-unsigned long bus_clock;
-unsigned int memsize;
-unsigned int highmemsize = 0;
-
-void __init plat_time_init(void)
-{
-	/* setup mips r4k timer */
-	mips_hpt_frequency = cpu_clock_freq / 2;
-}
-
-unsigned long read_persistent_clock(void)
-{
-	return mc146818_get_cmos_time();
-}
-
-void (*__wbflush)(void);
-EXPORT_SYMBOL(__wbflush);
-
-static void wbflush_loongson2e(void)
-{
-	asm(".set\tpush\n\t"
-	    ".set\tnoreorder\n\t"
-	    ".set mips3\n\t"
-	    "sync\n\t"
-	    "nop\n\t"
-	    ".set\tpop\n\t"
-	    ".set mips0\n\t");
-}
-
-void __init plat_mem_setup(void)
-{
-	set_io_port_base((unsigned long)ioremap(LOONGSON2E_IO_PORT_BASE,
-				IO_SPACE_LIMIT - LOONGSON2E_PCI_IO_START + 1));
-	mips_reboot_setup();
-
-	__wbflush = wbflush_loongson2e;
-
-	add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
-#ifdef CONFIG_64BIT
-	if (highmemsize > 0) {
-		add_memory_region(0x20000000, highmemsize << 20, BOOT_MEM_RAM);
-	}
-#endif
-
-#ifdef CONFIG_VT
-#if defined(CONFIG_VGA_CONSOLE)
-	conswitchp = &vga_con;
-
-	screen_info = (struct screen_info) {
-		0, 25,		/* orig-x, orig-y */
-		    0,		/* unused */
-		    0,		/* orig-video-page */
-		    0,		/* orig-video-mode */
-		    80,		/* orig-video-cols */
-		    0, 0, 0,	/* ega_ax, ega_bx, ega_cx */
-		    25,		/* orig-video-lines */
-		    VIDEO_TYPE_VGAC,	/* orig-video-isVGA */
-		    16		/* orig-video-points */
-	};
-#elif defined(CONFIG_DUMMY_CONSOLE)
-	conswitchp = &dummy_con;
-#endif
-#endif
-
-}
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
new file mode 100644
index 0000000..d450925
--- /dev/null
+++ b/arch/mips/loongson/Kconfig
@@ -0,0 +1,31 @@
+choice
+    prompt "Machine Type"
+    depends on MACH_LOONGSON
+
+config LEMOTE_FULOONG2E
+    bool "Lemote Fuloong(2e) mini-PC"
+    select ARCH_SPARSEMEM_ENABLE
+    select CEVT_R4K
+    select CSRC_R4K
+    select SYS_HAS_CPU_LOONGSON2E
+    select DMA_NONCOHERENT
+    select BOOT_ELF32
+    select BOARD_SCACHE
+    select HW_HAS_PCI
+    select I8259
+    select ISA
+    select IRQ_CPU
+    select SYS_SUPPORTS_32BIT_KERNEL
+    select SYS_SUPPORTS_64BIT_KERNEL
+    select SYS_SUPPORTS_LITTLE_ENDIAN
+    select SYS_SUPPORTS_HIGHMEM
+    select SYS_HAS_EARLY_PRINTK
+    select GENERIC_HARDIRQS_NO__DO_IRQ
+    select GENERIC_ISA_DMA_SUPPORT_BROKEN
+    select CPU_HAS_WB
+    help
+      Lemote Fuloong(2e) mini-PC board based on the Chinese Loongson-2E CPU and
+      an FPGA northbridge
+
+      Lemote Fuloong(2e) mini PC have a VIA686B south bridge.
+endchoice
diff --git a/arch/mips/loongson/Makefile b/arch/mips/loongson/Makefile
new file mode 100644
index 0000000..39048c4
--- /dev/null
+++ b/arch/mips/loongson/Makefile
@@ -0,0 +1,11 @@
+#
+# Common code for all Loongson based systems
+#
+
+obj-$(CONFIG_MACH_LOONGSON) += common/
+
+#
+# Lemote Fuloong mini-PC (Loongson 2E-based)
+#
+
+obj-$(CONFIG_LEMOTE_FULOONG2E)  += fuloong-2e/
diff --git a/arch/mips/loongson/common/Makefile b/arch/mips/loongson/common/Makefile
new file mode 100644
index 0000000..656b3cc
--- /dev/null
+++ b/arch/mips/loongson/common/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for loongson based machines.
+#
+
+obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \
+    pci.o bonito-irq.o mem.o machtype.o
+
+#
+# Early printk support
+#
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c
new file mode 100644
index 0000000..3e31e7a
--- /dev/null
+++ b/arch/mips/loongson/common/bonito-irq.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org)
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/interrupt.h>
+
+#include <loongson.h>
+
+static inline void bonito_irq_enable(unsigned int irq)
+{
+	BONITO_INTENSET = (1 << (irq - BONITO_IRQ_BASE));
+	mmiowb();
+}
+
+static inline void bonito_irq_disable(unsigned int irq)
+{
+	BONITO_INTENCLR = (1 << (irq - BONITO_IRQ_BASE));
+	mmiowb();
+}
+
+static struct irq_chip bonito_irq_type = {
+	.name	= "bonito_irq",
+	.ack	= bonito_irq_disable,
+	.mask	= bonito_irq_disable,
+	.mask_ack = bonito_irq_disable,
+	.unmask	= bonito_irq_enable,
+};
+
+static struct irqaction dma_timeout_irqaction = {
+	.handler	= no_action,
+	.name		= "dma_timeout",
+};
+
+void bonito_irq_init(void)
+{
+	u32 i;
+
+	for (i = BONITO_IRQ_BASE; i < BONITO_IRQ_BASE + 32; i++)
+		set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
+
+	setup_irq(BONITO_IRQ_BASE + 10, &dma_timeout_irqaction);
+}
diff --git a/arch/mips/loongson/common/cmdline.c b/arch/mips/loongson/common/cmdline.c
new file mode 100644
index 0000000..75f1b24
--- /dev/null
+++ b/arch/mips/loongson/common/cmdline.c
@@ -0,0 +1,52 @@
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <asm/bootinfo.h>
+
+#include <loongson.h>
+
+int prom_argc;
+/* pmon passes arguments in 32bit pointers */
+int *_prom_argv;
+
+void __init prom_init_cmdline(void)
+{
+	int i;
+	long l;
+
+	/* firmware arguments are initialized in head.S */
+	prom_argc = fw_arg0;
+	_prom_argv = (int *)fw_arg1;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < prom_argc; i++) {
+		l = (long)_prom_argv[i];
+		if (strlen(arcs_cmdline) + strlen(((char *)l) + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, ((char *)l));
+		strcat(arcs_cmdline, " ");
+	}
+
+	if ((strstr(arcs_cmdline, "console=")) == NULL)
+		strcat(arcs_cmdline, " console=ttyS0,115200");
+	if ((strstr(arcs_cmdline, "root=")) == NULL)
+		strcat(arcs_cmdline, " root=/dev/hda1");
+}
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c
new file mode 100644
index 0000000..bc73edc
--- /dev/null
+++ b/arch/mips/loongson/common/early_printk.c
@@ -0,0 +1,38 @@
+/*  early printk support
+ *
+ *  Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *  Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ *  Author: Wu Zhangjin, wuzj@lemote.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/serial_reg.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+#define PORT(base, offset) (u8 *)(base + offset)
+
+static inline unsigned int serial_in(phys_addr_t base, int offset)
+{
+	return readb(PORT(base, offset));
+}
+
+static inline void serial_out(phys_addr_t base, int offset, int value)
+{
+	writeb(value, PORT(base, offset));
+}
+
+void prom_putchar(char c)
+{
+	phys_addr_t uart_base =
+		(phys_addr_t) ioremap_nocache(LOONGSON_UART_BASE, 8);
+
+	while ((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(uart_base, UART_TX, c);
+}
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
new file mode 100644
index 0000000..b9ef503
--- /dev/null
+++ b/arch/mips/loongson/common/env.c
@@ -0,0 +1,58 @@
+/*
+ * Based on Ocelot Linux port, which is
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: jsun@mvista.com or jsun@junsun.net
+ *
+ * Copyright 2003 ICT CAS
+ * Author: Michael Guo <guoyi@ict.ac.cn>
+ *
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <asm/bootinfo.h>
+
+#include <loongson.h>
+
+unsigned long bus_clock, cpu_clock_freq;
+unsigned long memsize, highmemsize;
+
+/* pmon passes arguments in 32bit pointers */
+int *_prom_envp;
+
+#define parse_even_earlier(res, option, p)				\
+do {									\
+	if (strncmp(option, (char *)p, strlen(option)) == 0)		\
+			strict_strtol((char *)p + strlen(option"="),	\
+					10, &res);			\
+} while (0)
+
+void __init prom_init_env(void)
+{
+	long l;
+
+	/* firmware arguments are initialized in head.S */
+	_prom_envp = (int *)fw_arg2;
+
+	l = (long)*_prom_envp;
+	while (l != 0) {
+		parse_even_earlier(bus_clock, "busclock", l);
+		parse_even_earlier(cpu_clock_freq, "cpuclock", l);
+		parse_even_earlier(memsize, "memsize", l);
+		parse_even_earlier(highmemsize, "highmemsize", l);
+		_prom_envp++;
+		l = (long)*_prom_envp;
+	}
+	if (memsize == 0)
+		memsize = 256;
+
+	pr_info("busclock=%ld, cpuclock=%ld, memsize=%ld, highmemsize=%ld\n",
+		bus_clock, cpu_clock_freq, memsize, highmemsize);
+}
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c
new file mode 100644
index 0000000..3abe927
--- /dev/null
+++ b/arch/mips/loongson/common/init.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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/bootmem.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+
+void __init prom_init(void)
+{
+    /* init base address of io space */
+	set_io_port_base((unsigned long)
+		ioremap(BONITO_PCIIO_BASE, BONITO_PCIIO_SIZE));
+
+	prom_init_cmdline();
+	prom_init_env();
+	prom_init_memory();
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
diff --git a/arch/mips/loongson/common/irq.c b/arch/mips/loongson/common/irq.c
new file mode 100644
index 0000000..f368c73
--- /dev/null
+++ b/arch/mips/loongson/common/irq.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/delay.h>
+#include <linux/interrupt.h>
+
+#include <loongson.h>
+/*
+ * the first level int-handler will jump here if it is a bonito irq
+ */
+void bonito_irqdispatch(void)
+{
+	u32 int_status;
+	int i;
+
+	/* workaround the IO dma problem: let cpu looping to allow DMA finish */
+	int_status = BONITO_INTISR;
+	if (int_status & (1 << 10)) {
+		while (int_status & (1 << 10)) {
+			udelay(1);
+			int_status = BONITO_INTISR;
+		}
+	}
+
+	/* Get pending sources, masked by current enables */
+	int_status = BONITO_INTISR & BONITO_INTEN;
+
+	if (int_status != 0) {
+		i = __ffs(int_status);
+		int_status &= ~(1 << i);
+		do_IRQ(BONITO_IRQ_BASE + i);
+	}
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned int pending;
+
+	pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+	/* machine-specific plat_irq_dispatch */
+	mach_irq_dispatch(pending);
+}
+
+void __init arch_init_irq(void)
+{
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM | ST0_BEV);
+	local_irq_disable();
+
+	/* setting irq trigger mode */
+	set_irq_trigger_mode();
+
+	/* no steer */
+	BONITO_INTSTEER = 0;
+
+	/*
+	 * Mask out all interrupt by writing "1" to all bit position in
+	 * the interrupt reset reg.
+	 */
+	BONITO_INTENCLR = ~0;
+
+	/* machine specific irq init */
+	mach_init_irq();
+}
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c
new file mode 100644
index 0000000..7b34824
--- /dev/null
+++ b/arch/mips/loongson/common/machtype.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.com
+ *
+ * Copyright (c) 2009 Zhang Le <r0bertz@gentoo.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.
+ */
+#include <linux/errno.h>
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <machine.h>
+
+static const char *system_types[] = {
+	[MACH_LOONGSON_UNKNOWN]         "unknown loongson machine",
+	[MACH_LEMOTE_FL2E]              "lemote-fuloong-2e-box",
+	[MACH_LEMOTE_FL2F]              "lemote-fuloong-2f-box",
+	[MACH_LEMOTE_ML2F7]             "lemote-mengloong-2f-7inches",
+	[MACH_LEMOTE_YL2F89]            "lemote-yeeloong-2f-8.9inches",
+	[MACH_DEXXON_GDIUM2F10]         "dexxon-gidum-2f-10inches",
+	[MACH_LOONGSON_END]             NULL,
+};
+
+const char *get_system_type(void)
+{
+	if (mips_machtype == MACH_UNKNOWN)
+		mips_machtype = LOONGSON_MACHTYPE;
+
+	return system_types[mips_machtype];
+}
+
+static __init int machtype_setup(char *str)
+{
+	int machtype = MACH_LEMOTE_FL2E;
+
+	if (!str)
+		return -EINVAL;
+
+	for (; system_types[machtype]; machtype++)
+		if (strstr(system_types[machtype], str)) {
+			mips_machtype = machtype;
+			break;
+		}
+	return 0;
+}
+__setup("machtype=", machtype_setup);
diff --git a/arch/mips/loongson/common/mem.c b/arch/mips/loongson/common/mem.c
new file mode 100644
index 0000000..7c92f79
--- /dev/null
+++ b/arch/mips/loongson/common/mem.c
@@ -0,0 +1,35 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/fs.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+
+#include <asm/bootinfo.h>
+
+#include <loongson.h>
+#include <mem.h>
+
+void __init prom_init_memory(void)
+{
+    add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+#ifdef CONFIG_64BIT
+    if (highmemsize > 0)
+	add_memory_region(LOONGSON_HIGHMEM_START,
+		highmemsize << 20, BOOT_MEM_RAM);
+#endif /* CONFIG_64BIT */
+}
+
+/* override of arch/mips/mm/cache.c: __uncached_access */
+int __uncached_access(struct file *file, unsigned long addr)
+{
+	if (file->f_flags & O_SYNC)
+		return 1;
+
+	return addr >= __pa(high_memory) ||
+		((addr >= LOONGSON_MMIO_MEM_START) &&
+		 (addr < LOONGSON_MMIO_MEM_END));
+}
diff --git a/arch/mips/loongson/common/pci.c b/arch/mips/loongson/common/pci.c
new file mode 100644
index 0000000..a3a4abf
--- /dev/null
+++ b/arch/mips/loongson/common/pci.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/pci.h>
+
+#include <pci.h>
+#include <loongson.h>
+
+static struct resource loongson_pci_mem_resource = {
+	.name   = "pci memory space",
+	.start  = LOONGSON_PCI_MEM_START,
+	.end    = LOONGSON_PCI_MEM_END,
+	.flags  = IORESOURCE_MEM,
+};
+
+static struct resource loongson_pci_io_resource = {
+	.name   = "pci io space",
+	.start  = LOONGSON_PCI_IO_START,
+	.end    = IO_SPACE_LIMIT,
+	.flags  = IORESOURCE_IO,
+};
+
+static struct pci_controller  loongson_pci_controller = {
+	.pci_ops        = &bonito64_pci_ops,
+	.io_resource    = &loongson_pci_io_resource,
+	.mem_resource   = &loongson_pci_mem_resource,
+	.mem_offset     = 0x00000000UL,
+	.io_offset      = 0x00000000UL,
+};
+
+static void __init setup_pcimap(void)
+{
+	/*
+	 * local to PCI mapping for CPU accessing PCI space
+	 * CPU address space [256M,448M] is window for accessing pci space
+	 * we set pcimap_lo[0,1,2] to map it to pci space[0M,64M], [320M,448M]
+	 *
+	 * pcimap: PCI_MAP2  PCI_Mem_Lo2 PCI_Mem_Lo1 PCI_Mem_Lo0
+	 * 	     [<2G]   [384M,448M] [320M,384M] [0M,64M]
+	 */
+	BONITO_PCIMAP = BONITO_PCIMAP_PCIMAP_2 |
+		BONITO_PCIMAP_WIN(2, BONITO_PCILO2_BASE) |
+		BONITO_PCIMAP_WIN(1, BONITO_PCILO1_BASE) |
+		BONITO_PCIMAP_WIN(0, 0);
+
+	/*
+	 * PCI-DMA to local mapping: [2G,2G+256M] -> [0M,256M]
+	 */
+	BONITO_PCIBASE0 = 0x80000000ul;   /* base: 2G -> mmap: 0M */
+	/* size: 256M, burst transmission, pre-fetch enable, 64bit */
+	LOONGSON_PCI_HIT0_SEL_L = 0xc000000cul;
+	LOONGSON_PCI_HIT0_SEL_H = 0xfffffffful;
+	LOONGSON_PCI_HIT1_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+	LOONGSON_PCI_HIT1_SEL_H = 0x00000000ul;
+	LOONGSON_PCI_HIT2_SEL_L = 0x00000006ul; /* set this BAR as invalid */
+	LOONGSON_PCI_HIT2_SEL_H = 0x00000000ul;
+
+	/* avoid deadlock of PCI reading/writing lock operation */
+	LOONGSON_PCI_ISR4C = 0xd2000001ul;
+
+	/* can not change gnt to break pci transfer when device's gnt not
+	deassert for some broken device */
+	LOONGSON_PXARB_CFG = 0x00fe0105ul;
+}
+
+static int __init pcibios_init(void)
+{
+	setup_pcimap();
+
+	loongson_pci_controller.io_map_base = mips_io_port_base;
+
+	register_pci_controller(&loongson_pci_controller);
+
+	return 0;
+}
+
+arch_initcall(pcibios_init);
diff --git a/arch/mips/loongson/common/reset.c b/arch/mips/loongson/common/reset.c
new file mode 100644
index 0000000..97e9182
--- /dev/null
+++ b/arch/mips/loongson/common/reset.c
@@ -0,0 +1,44 @@
+/*
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ * Copyright (C) 2009 Lemote, Inc. & Institute of Computing Technology
+ * Author: Zhangjin Wu, wuzj@lemote.com
+ */
+#include <linux/init.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+
+#include <loongson.h>
+
+static void loongson_restart(char *command)
+{
+	/* do preparation for reboot */
+	mach_prepare_reboot();
+
+	/* reboot via jumping to boot base address */
+	((void (*)(void))ioremap_nocache(BONITO_BOOT_BASE, 4)) ();
+}
+
+static void loongson_halt(void)
+{
+	mach_prepare_shutdown();
+	while (1)
+		;
+}
+
+static int __init mips_reboot_setup(void)
+{
+	_machine_restart = loongson_restart;
+	_machine_halt = loongson_halt;
+	pm_power_off = loongson_halt;
+
+	return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c
new file mode 100644
index 0000000..4cd2aa9
--- /dev/null
+++ b/arch/mips/loongson/common/setup.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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 <asm/wbflush.h>
+
+#include <loongson.h>
+
+#ifdef CONFIG_VT
+#include <linux/console.h>
+#include <linux/screen_info.h>
+#endif
+
+void (*__wbflush)(void);
+EXPORT_SYMBOL(__wbflush);
+
+static void wbflush_loongson(void)
+{
+	asm(".set\tpush\n\t"
+	    ".set\tnoreorder\n\t"
+	    ".set mips3\n\t"
+	    "sync\n\t"
+	    "nop\n\t"
+	    ".set\tpop\n\t"
+	    ".set mips0\n\t");
+}
+
+void __init plat_mem_setup(void)
+{
+	__wbflush = wbflush_loongson;
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+	conswitchp = &vga_con;
+
+	screen_info = (struct screen_info) {
+		0, 25,		/* orig-x, orig-y */
+		    0,		/* unused */
+		    0,		/* orig-video-page */
+		    0,		/* orig-video-mode */
+		    80,		/* orig-video-cols */
+		    0, 0, 0,	/* ega_ax, ega_bx, ega_cx */
+		    25,		/* orig-video-lines */
+		    VIDEO_TYPE_VGAC,	/* orig-video-isVGA */
+		    16		/* orig-video-points */
+	};
+#elif defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+#endif
+}
diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c
new file mode 100644
index 0000000..6e08c82
--- /dev/null
+++ b/arch/mips/loongson/common/time.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.com
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <asm/mc146818-time.h>
+#include <asm/time.h>
+
+#include <loongson.h>
+
+void __init plat_time_init(void)
+{
+	/* setup mips r4k timer */
+	mips_hpt_frequency = cpu_clock_freq / 2;
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+	ts->tv_sec = mc146818_get_cmos_time();
+	ts->tv_nsec = 0;
+}
diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile
new file mode 100644
index 0000000..3aba5fc
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2e/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for Lemote Fuloong2e mini-PC board.
+#
+
+obj-y += irq.o reset.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c
new file mode 100644
index 0000000..7888cf6
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2e/irq.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007 Lemote Inc. & Insititute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/interrupt.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/i8259.h>
+
+#include <loongson.h>
+
+static void i8259_irqdispatch(void)
+{
+	int irq;
+
+	irq = i8259_irq();
+	if (irq >= 0)
+		do_IRQ(irq);
+	else
+		spurious_interrupt();
+}
+
+asmlinkage void mach_irq_dispatch(unsigned int pending)
+{
+	if (pending & CAUSEF_IP7)
+		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
+	else if (pending & CAUSEF_IP6) /* perf counter loverflow */
+		do_IRQ(LOONGSON2_PERFCNT_IRQ);
+	else if (pending & CAUSEF_IP5)
+		i8259_irqdispatch();
+	else if (pending & CAUSEF_IP2)
+		bonito_irqdispatch();
+	else
+		spurious_interrupt();
+}
+
+static struct irqaction cascade_irqaction = {
+	.handler = no_action,
+	.name = "cascade",
+};
+
+void __init set_irq_trigger_mode(void)
+{
+	/* most bonito irq should be level triggered */
+	BONITO_INTEDGE = BONITO_ICU_SYSTEMERR | BONITO_ICU_MASTERERR |
+	    BONITO_ICU_RETRYERR | BONITO_ICU_MBOXES;
+}
+
+void __init mach_init_irq(void)
+{
+	/* init all controller
+	 *   0-15         ------> i8259 interrupt
+	 *   16-23        ------> mips cpu interrupt
+	 *   32-63        ------> bonito irq
+	 */
+
+	/* Sets the first-level interrupt dispatcher. */
+	mips_cpu_irq_init();
+	init_i8259_irqs();
+	bonito_irq_init();
+
+	/* bonito irq at IP2 */
+	setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction);
+	/* 8259 irq at IP5 */
+	setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction);
+}
diff --git a/arch/mips/loongson/fuloong-2e/reset.c b/arch/mips/loongson/fuloong-2e/reset.c
new file mode 100644
index 0000000..677fe18
--- /dev/null
+++ b/arch/mips/loongson/fuloong-2e/reset.c
@@ -0,0 +1,23 @@
+/* Board-specific reboot/shutdown routines
+ * Copyright (c) 2009 Philippe Vachon <philippe@cowpig.ca>
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Wu Zhangjin, wuzj@lemote.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 <loongson.h>
+
+void mach_prepare_reboot(void)
+{
+	BONITO_BONGENCFG &= ~(1 << 2);
+	BONITO_BONGENCFG |= (1 << 2);
+}
+
+void mach_prepare_shutdown(void)
+{
+}
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
index 7c7148e..2877675 100644
--- a/arch/mips/mipssim/sim_setup.c
+++ b/arch/mips/mipssim/sim_setup.c
@@ -37,7 +37,7 @@
 
 
 static void __init serial_init(void);
-unsigned int _isbonito = 0;
+unsigned int _isbonito;
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index f956ecb..e97a7a2 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -58,11 +58,17 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
 	 * only copy the information from the master page table,
 	 * nothing more.
 	 */
+#ifdef CONFIG_64BIT
+# define VMALLOC_FAULT_TARGET no_context
+#else
+# define VMALLOC_FAULT_TARGET vmalloc_fault
+#endif
+
 	if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
-		goto vmalloc_fault;
+		goto VMALLOC_FAULT_TARGET;
 #ifdef MODULE_START
 	if (unlikely(address >= MODULE_START && address < MODULE_END))
-		goto vmalloc_fault;
+		goto VMALLOC_FAULT_TARGET;
 #endif
 
 	/*
@@ -203,6 +209,7 @@ do_sigbus:
 	force_sig_info(SIGBUS, &info, tsk);
 
 	return;
+#ifndef CONFIG_64BIT
 vmalloc_fault:
 	{
 		/*
@@ -241,4 +248,5 @@ vmalloc_fault:
 			goto no_context;
 		return;
 	}
+#endif
 }
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 0e82050..38c79c5 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -475,9 +475,6 @@ unsigned long pgd_current[NR_CPUS];
  */
 pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER);
 #ifdef CONFIG_64BIT
-#ifdef MODULE_START
-pgd_t module_pg_dir[PTRS_PER_PGD] __page_aligned(PGD_ORDER);
-#endif
 pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER);
 #endif
 pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index e4b565a..1121019 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -59,9 +59,6 @@ void __init pagetable_init(void)
 
 	/* Initialize the entire pgd.  */
 	pgd_init((unsigned long)swapper_pg_dir);
-#ifdef MODULE_START
-	pgd_init((unsigned long)module_pg_dir);
-#endif
 	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
 
 	pgd_base = swapper_pg_dir;
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index cee502c..d73428b 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -475,7 +475,7 @@ static void __cpuinit probe_tlb(unsigned long config)
 	c->tlbsize = ((reg >> 25) & 0x3f) + 1;
 }
 
-static int __cpuinitdata ntlb = 0;
+static int __cpuinitdata ntlb;
 static int __init set_ntlb(char *str)
 {
 	get_option(&str, &ntlb);
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 9a17bf8..bb1719a 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -321,6 +321,10 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
 	case CPU_BCM3302:
 	case CPU_BCM4710:
 	case CPU_LOONGSON2:
+	case CPU_BCM6338:
+	case CPU_BCM6345:
+	case CPU_BCM6348:
+	case CPU_BCM6358:
 	case CPU_R5500:
 		if (m4kc_tlbp_war())
 			uasm_i_nop(p);
@@ -499,11 +503,7 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 	 * The vmalloc handling is not in the hotpath.
 	 */
 	uasm_i_dmfc0(p, tmp, C0_BADVADDR);
-#ifdef MODULE_START
-	uasm_il_bltz(p, r, tmp, label_module_alloc);
-#else
 	uasm_il_bltz(p, r, tmp, label_vmalloc);
-#endif
 	/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */
 
 #ifdef CONFIG_SMP
@@ -556,52 +556,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 {
 	long swpd = (long)swapper_pg_dir;
 
-#ifdef MODULE_START
-	long modd = (long)module_pg_dir;
-
-	uasm_l_module_alloc(l, *p);
-	/*
-	 * Assumption:
-	 * VMALLOC_START >= 0xc000000000000000UL
-	 * MODULE_START >= 0xe000000000000000UL
-	 */
-	UASM_i_SLL(p, ptr, bvaddr, 2);
-	uasm_il_bgez(p, r, ptr, label_vmalloc);
-
-	if (uasm_in_compat_space_p(MODULE_START) &&
-	    !uasm_rel_lo(MODULE_START)) {
-		uasm_i_lui(p, ptr, uasm_rel_hi(MODULE_START)); /* delay slot */
-	} else {
-		/* unlikely configuration */
-		uasm_i_nop(p); /* delay slot */
-		UASM_i_LA(p, ptr, MODULE_START);
-	}
-	uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
-
-	if (uasm_in_compat_space_p(modd) && !uasm_rel_lo(modd)) {
-		uasm_il_b(p, r, label_vmalloc_done);
-		uasm_i_lui(p, ptr, uasm_rel_hi(modd));
-	} else {
-		UASM_i_LA_mostly(p, ptr, modd);
-		uasm_il_b(p, r, label_vmalloc_done);
-		if (uasm_in_compat_space_p(modd))
-			uasm_i_addiu(p, ptr, ptr, uasm_rel_lo(modd));
-		else
-			uasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(modd));
-	}
-
 	uasm_l_vmalloc(l, *p);
-	if (uasm_in_compat_space_p(MODULE_START) &&
-	    !uasm_rel_lo(MODULE_START) &&
-	    MODULE_START << 32 == VMALLOC_START)
-		uasm_i_dsll32(p, ptr, ptr, 0);	/* typical case */
-	else
-		UASM_i_LA(p, ptr, VMALLOC_START);
-#else
-	uasm_l_vmalloc(l, *p);
-	UASM_i_LA(p, ptr, VMALLOC_START);
-#endif
-	uasm_i_dsubu(p, bvaddr, bvaddr, ptr);
 
 	if (uasm_in_compat_space_p(swpd) && !uasm_rel_lo(swpd)) {
 		uasm_il_b(p, r, label_vmalloc_done);
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 27c807b..f1b14c8 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -47,7 +47,7 @@ int *_prom_argv, *_prom_envp;
  */
 #define prom_envp(index) ((char *)(long)_prom_envp[(index)])
 
-int init_debug = 0;
+int init_debug;
 
 static int mips_revision_corid;
 int mips_revision_sconid;
diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c
index f48d60e..3294205 100644
--- a/arch/mips/mti-malta/malta-reset.c
+++ b/arch/mips/mti-malta/malta-reset.c
@@ -22,6 +22,7 @@
  * Reset the MIPS boards.
  *
  */
+#include <linux/init.h>
 #include <linux/pm.h>
 
 #include <asm/io.h>
@@ -45,9 +46,13 @@ static void mips_machine_halt(void)
 }
 
 
-void mips_reboot_setup(void)
+static int __init mips_reboot_setup(void)
 {
 	_machine_restart = mips_machine_restart;
 	_machine_halt = mips_machine_halt;
 	pm_power_off = mips_machine_halt;
+
+	return 0;
 }
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index dc78b89..b7f37d4 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -218,7 +218,6 @@ void __init plat_mem_setup(void)
 #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
 	screen_info_setup();
 #endif
-	mips_reboot_setup();
 
 	board_be_init = malta_be_init;
 	board_be_handler = malta_be_handler;
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 0b97d47..3c6f190 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -100,9 +100,10 @@ static unsigned int __init estimate_cpu_frequency(void)
 	return count;
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-	return mc146818_get_cmos_time();
+	ts->tv_sec = mc146818_get_cmos_time();
+	ts->tv_nsec = 0;
 }
 
 static void __init plat_perf_setup(void)
diff --git a/arch/mips/nxp/pnx833x/stb22x/board.c b/arch/mips/nxp/pnx833x/stb22x/board.c
index 90cc604..644eb7c 100644
--- a/arch/mips/nxp/pnx833x/stb22x/board.c
+++ b/arch/mips/nxp/pnx833x/stb22x/board.c
@@ -39,7 +39,7 @@
 #define PNX8335_DEBUG7 0x441c
 
 int prom_argc;
-char **prom_argv = 0, **prom_envp = 0;
+char **prom_argv, **prom_envp;
 
 extern void prom_init_cmdline(void);
 extern char *prom_getenv(char *envname);
diff --git a/arch/mips/nxp/pnx8550/common/proc.c b/arch/mips/nxp/pnx8550/common/proc.c
index acf1fa8..af094cd 100644
--- a/arch/mips/nxp/pnx8550/common/proc.c
+++ b/arch/mips/nxp/pnx8550/common/proc.c
@@ -69,9 +69,9 @@ static int pnx8550_registers_read(char* page, char** start, off_t offset, int co
         return len;
 }
 
-static struct proc_dir_entry* pnx8550_dir        = NULL;
-static struct proc_dir_entry* pnx8550_timers     = NULL;
-static struct proc_dir_entry* pnx8550_registers  = NULL;
+static struct proc_dir_entry* pnx8550_dir;
+static struct proc_dir_entry* pnx8550_timers;
+static struct proc_dir_entry* pnx8550_registers;
 
 static int pnx8550_proc_init( void )
 {
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
index bf3be6f..02cc65e 100644
--- a/arch/mips/oprofile/Makefile
+++ b/arch/mips/oprofile/Makefile
@@ -15,3 +15,4 @@ oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_R10000)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_SB1)		+= op_model_mipsxx.o
 oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
+oprofile-$(CONFIG_CPU_LOONGSON2)	+= op_model_loongson2.o
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index 3bf3354..7832ad2 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -16,6 +16,7 @@
 
 extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak));
 extern struct op_mips_model op_model_rm9000_ops __attribute__((weak));
+extern struct op_mips_model op_model_loongson2_ops __attribute__((weak));
 
 static struct op_mips_model *model;
 
@@ -93,6 +94,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 	case CPU_RM9000:
 		lmodel = &op_model_rm9000_ops;
 		break;
+	case CPU_LOONGSON2:
+		lmodel = &op_model_loongson2_ops;
+		break;
 	};
 
 	if (!lmodel)
diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
new file mode 100644
index 0000000..655cb8d
--- /dev/null
+++ b/arch/mips/oprofile/op_model_loongson2.c
@@ -0,0 +1,177 @@
+/*
+ * Loongson2 performance counter driver for oprofile
+ *
+ * Copyright (C) 2009 Lemote Inc. & Insititute of Computing Technology
+ * Author: Yanhua <yanh@lemote.com>
+ * Author: Wu Zhangjin <wuzj@lemote.com>
+ *
+ * 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.
+ *
+ */
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+
+#include <loongson.h>			/* LOONGSON2_PERFCNT_IRQ */
+#include "op_impl.h"
+
+/*
+ * a patch should be sent to oprofile with the loongson-specific support.
+ * otherwise, the oprofile tool will not recognize this and complain about
+ * "cpu_type 'unset' is not valid".
+ */
+#define LOONGSON2_CPU_TYPE	"mips/godson2"
+
+#define LOONGSON2_COUNTER1_EVENT(event)	((event & 0x0f) << 5)
+#define LOONGSON2_COUNTER2_EVENT(event)	((event & 0x0f) << 9)
+
+#define LOONGSON2_PERFCNT_EXL			(1UL	<<  0)
+#define LOONGSON2_PERFCNT_KERNEL		(1UL    <<  1)
+#define LOONGSON2_PERFCNT_SUPERVISOR	(1UL    <<  2)
+#define LOONGSON2_PERFCNT_USER			(1UL    <<  3)
+#define LOONGSON2_PERFCNT_INT_EN		(1UL    <<  4)
+#define LOONGSON2_PERFCNT_OVERFLOW		(1ULL   << 31)
+
+/* Loongson2 performance counter register */
+#define read_c0_perfctrl() __read_64bit_c0_register($24, 0)
+#define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val)
+#define read_c0_perfcnt() __read_64bit_c0_register($25, 0)
+#define write_c0_perfcnt(val) __write_64bit_c0_register($25, 0, val)
+
+static struct loongson2_register_config {
+	unsigned int ctrl;
+	unsigned long long reset_counter1;
+	unsigned long long reset_counter2;
+	int cnt1_enalbed, cnt2_enalbed;
+} reg;
+
+DEFINE_SPINLOCK(sample_lock);
+
+static char *oprofid = "LoongsonPerf";
+static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id);
+/* Compute all of the registers in preparation for enabling profiling.  */
+
+static void loongson2_reg_setup(struct op_counter_config *cfg)
+{
+	unsigned int ctrl = 0;
+
+	reg.reset_counter1 = 0;
+	reg.reset_counter2 = 0;
+	/* Compute the performance counter ctrl word.  */
+	/* For now count kernel and user mode */
+	if (cfg[0].enabled) {
+		ctrl |= LOONGSON2_COUNTER1_EVENT(cfg[0].event);
+		reg.reset_counter1 = 0x80000000ULL - cfg[0].count;
+	}
+
+	if (cfg[1].enabled) {
+		ctrl |= LOONGSON2_COUNTER2_EVENT(cfg[1].event);
+		reg.reset_counter2 = (0x80000000ULL - cfg[1].count);
+	}
+
+	if (cfg[0].enabled || cfg[1].enabled) {
+		ctrl |= LOONGSON2_PERFCNT_EXL | LOONGSON2_PERFCNT_INT_EN;
+		if (cfg[0].kernel || cfg[1].kernel)
+			ctrl |= LOONGSON2_PERFCNT_KERNEL;
+		if (cfg[0].user || cfg[1].user)
+			ctrl |= LOONGSON2_PERFCNT_USER;
+	}
+
+	reg.ctrl = ctrl;
+
+	reg.cnt1_enalbed = cfg[0].enabled;
+	reg.cnt2_enalbed = cfg[1].enabled;
+
+}
+
+/* Program all of the registers in preparation for enabling profiling.  */
+
+static void loongson2_cpu_setup(void *args)
+{
+	uint64_t perfcount;
+
+	perfcount = (reg.reset_counter2 << 32) | reg.reset_counter1;
+	write_c0_perfcnt(perfcount);
+}
+
+static void loongson2_cpu_start(void *args)
+{
+	/* Start all counters on current CPU */
+	if (reg.cnt1_enalbed || reg.cnt2_enalbed)
+		write_c0_perfctrl(reg.ctrl);
+}
+
+static void loongson2_cpu_stop(void *args)
+{
+	/* Stop all counters on current CPU */
+	write_c0_perfctrl(0);
+	memset(&reg, 0, sizeof(reg));
+}
+
+static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
+{
+	uint64_t counter, counter1, counter2;
+	struct pt_regs *regs = get_irq_regs();
+	int enabled;
+	unsigned long flags;
+
+	/*
+	 * LOONGSON2 defines two 32-bit performance counters.
+	 * To avoid a race updating the registers we need to stop the counters
+	 * while we're messing with
+	 * them ...
+	 */
+
+	/* Check whether the irq belongs to me */
+	enabled = reg.cnt1_enalbed | reg.cnt2_enalbed;
+	if (!enabled)
+		return IRQ_NONE;
+
+	counter = read_c0_perfcnt();
+	counter1 = counter & 0xffffffff;
+	counter2 = counter >> 32;
+
+	spin_lock_irqsave(&sample_lock, flags);
+
+	if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) {
+		if (reg.cnt1_enalbed)
+			oprofile_add_sample(regs, 0);
+		counter1 = reg.reset_counter1;
+	}
+	if (counter2 & LOONGSON2_PERFCNT_OVERFLOW) {
+		if (reg.cnt2_enalbed)
+			oprofile_add_sample(regs, 1);
+		counter2 = reg.reset_counter2;
+	}
+
+	spin_unlock_irqrestore(&sample_lock, flags);
+
+	write_c0_perfcnt((counter2 << 32) | counter1);
+
+	return IRQ_HANDLED;
+}
+
+static int __init loongson2_init(void)
+{
+	return request_irq(LOONGSON2_PERFCNT_IRQ, loongson2_perfcount_handler,
+			   IRQF_SHARED, "Perfcounter", oprofid);
+}
+
+static void loongson2_exit(void)
+{
+	write_c0_perfctrl(0);
+	free_irq(LOONGSON2_PERFCNT_IRQ, oprofid);
+}
+
+struct op_mips_model op_model_loongson2_ops = {
+	.reg_setup = loongson2_reg_setup,
+	.cpu_setup = loongson2_cpu_setup,
+	.init = loongson2_init,
+	.exit = loongson2_exit,
+	.cpu_start = loongson2_cpu_start,
+	.cpu_stop = loongson2_cpu_stop,
+	.cpu_type = LOONGSON2_CPU_TYPE,
+	.num_counters = 2
+};
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 63d8a29..91bfe73 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_PCI_VR41XX)	+= ops-vr41xx.o pci-vr41xx.o
 obj-$(CONFIG_NEC_MARKEINS)	+= ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
 obj-$(CONFIG_PCI_TX4927)	+= ops-tx4927.o
 obj-$(CONFIG_BCM47XX)		+= pci-bcm47xx.o
+obj-$(CONFIG_BCM63XX)		+= pci-bcm63xx.o fixup-bcm63xx.o \
+					ops-bcm63xx.o
 
 #
 # These are still pretty much in the old state, watch, go blind.
@@ -26,7 +28,7 @@ obj-$(CONFIG_MIPS_COBALT)	+= fixup-cobalt.o
 obj-$(CONFIG_SOC_AU1500)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_AU1550)	+= fixup-au1000.o ops-au1000.o
 obj-$(CONFIG_SOC_PNX8550)	+= fixup-pnx8550.o ops-pnx8550.o
-obj-$(CONFIG_LEMOTE_FULONG)	+= fixup-lm2e.o ops-bonito64.o
+obj-$(CONFIG_LEMOTE_FULOONG2E)	+= fixup-fuloong2e.o ops-bonito64.o
 obj-$(CONFIG_MIPS_MALTA)	+= fixup-malta.o
 obj-$(CONFIG_PMC_MSP7120_GW)	+= fixup-pmcmsp.o ops-pmcmsp.o
 obj-$(CONFIG_PMC_MSP7120_EVAL)	+= fixup-pmcmsp.o ops-pmcmsp.o
diff --git a/arch/mips/pci/fixup-bcm63xx.c b/arch/mips/pci/fixup-bcm63xx.c
new file mode 100644
index 0000000..3408630
--- /dev/null
+++ b/arch/mips/pci/fixup-bcm63xx.c
@@ -0,0 +1,21 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <bcm63xx_cpu.h>
+
+int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	return bcm63xx_get_irq_number(IRQ_PCI);
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
diff --git a/arch/mips/pci/fixup-fuloong2e.c b/arch/mips/pci/fixup-fuloong2e.c
new file mode 100644
index 0000000..0c4c7a8
--- /dev/null
+++ b/arch/mips/pci/fixup-fuloong2e.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2004 ICT CAS
+ * Author: Li xiaoyu, ICT CAS
+ *   lixy@ict.ac.cn
+ *
+ * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
+ * Author: Fuxin Zhang, zhangfx@lemote.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/init.h>
+#include <linux/pci.h>
+#include <asm/mips-boards/bonito64.h>
+
+/* South bridge slot number is set by the pci probe process */
+static u8 sb_slot = 5;
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	int irq = 0;
+
+	if (slot == sb_slot) {
+		switch (PCI_FUNC(dev->devfn)) {
+		case 2:
+			irq = 10;
+			break;
+		case 3:
+			irq = 11;
+			break;
+		case 5:
+			irq = 9;
+			break;
+		}
+	} else {
+		irq = BONITO_IRQ_BASE + 25 + pin;
+	}
+	return irq;
+
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
+{
+	unsigned int val;
+
+	/* Configues port 1, 2, 3, 4 to be validate*/
+	pci_read_config_dword(pdev, 0xe0, &val);
+	pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
+
+	/* System clock is 48-MHz Oscillator. */
+	pci_write_config_dword(pdev, 0xe4, 1 << 5);
+}
+
+static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)
+{
+	unsigned char c;
+
+	sb_slot = PCI_SLOT(pdev->devfn);
+
+	printk(KERN_INFO "via686b fix: ISA bridge\n");
+
+	/*  Enable I/O Recovery time */
+	pci_write_config_byte(pdev, 0x40, 0x08);
+
+	/*  Enable ISA refresh */
+	pci_write_config_byte(pdev, 0x41, 0x01);
+
+	/*  disable ISA line buffer */
+	pci_write_config_byte(pdev, 0x45, 0x00);
+
+	/*  Gate INTR, and flush line buffer */
+	pci_write_config_byte(pdev, 0x46, 0xe0);
+
+	/*  Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
+	/* pci_write_config_byte(pdev, 0x47, 0x20); */
+
+	/*
+	 *  enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
+	 *  enable time-out timer
+	 */
+	pci_write_config_byte(pdev, 0x47, 0xe6);
+
+	/*
+	 * enable level trigger on pci irqs: 9,10,11,13
+	 * important! without this PCI interrupts won't work
+	 */
+	outb(0x2e, 0x4d1);
+
+	/*  512 K PCI Decode */
+	pci_write_config_byte(pdev, 0x48, 0x01);
+
+	/*  Wait for PGNT before grant to ISA Master/DMA */
+	pci_write_config_byte(pdev, 0x4a, 0x84);
+
+	/*
+	 * Plug'n'Play
+	 *
+	 *  Parallel DRQ 3, Floppy DRQ 2 (default)
+	 */
+	pci_write_config_byte(pdev, 0x50, 0x0e);
+
+	/*
+	 * IRQ Routing for Floppy and Parallel port
+	 *
+	 *  IRQ 6 for floppy, IRQ 7 for parallel port
+	 */
+	pci_write_config_byte(pdev, 0x51, 0x76);
+
+	/* IRQ Routing for serial ports (take IRQ 3 and 4) */
+	pci_write_config_byte(pdev, 0x52, 0x34);
+
+	/*  All IRQ's level triggered. */
+	pci_write_config_byte(pdev, 0x54, 0x00);
+
+	/* route PIRQA-D irq */
+	pci_write_config_byte(pdev, 0x55, 0x90);	/* bit 7-4, PIRQA */
+	pci_write_config_byte(pdev, 0x56, 0xba);	/* bit 7-4, PIRQC; */
+							/* 3-0, PIRQB */
+	pci_write_config_byte(pdev, 0x57, 0xd0);	/* bit 7-4, PIRQD */
+
+	/* enable function 5/6, audio/modem */
+	pci_read_config_byte(pdev, 0x85, &c);
+	c &= ~(0x3 << 2);
+	pci_write_config_byte(pdev, 0x85, c);
+
+	printk(KERN_INFO"via686b fix: ISA bridge done\n");
+}
+
+static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)
+{
+	printk(KERN_INFO"via686b fix: IDE\n");
+
+	/* Modify IDE controller setup */
+	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
+	pci_write_config_byte(pdev, PCI_COMMAND,
+			      PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+			      PCI_COMMAND_MASTER);
+	pci_write_config_byte(pdev, 0x40, 0x0b);
+	/* legacy mode */
+	pci_write_config_byte(pdev, 0x42, 0x09);
+
+#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
+	/* disable read prefetch/write post buffers */
+	pci_write_config_byte(pdev, 0x41, 0x02);
+
+	/* use 3/4 as fifo thresh hold  */
+	pci_write_config_byte(pdev, 0x43, 0x0a);
+	pci_write_config_byte(pdev, 0x44, 0x00);
+
+	pci_write_config_byte(pdev, 0x45, 0x00);
+#else
+	pci_write_config_byte(pdev, 0x41, 0xc2);
+	pci_write_config_byte(pdev, 0x43, 0x35);
+	pci_write_config_byte(pdev, 0x44, 0x1c);
+
+	pci_write_config_byte(pdev, 0x45, 0x10);
+#endif
+
+	printk(KERN_INFO"via686b fix: IDE done\n");
+}
+
+static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev)
+{
+	/* irq routing */
+	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
+}
+
+static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev)
+{
+	/* irq routing */
+	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
+}
+
+static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev)
+{
+	unsigned int val;
+	unsigned char c;
+
+	/* enable IO */
+	pci_write_config_byte(pdev, PCI_COMMAND,
+			      PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+			      PCI_COMMAND_MASTER);
+	pci_read_config_dword(pdev, 0x4, &val);
+	pci_write_config_dword(pdev, 0x4, val | 1);
+
+	/* route ac97 IRQ */
+	pci_write_config_byte(pdev, 0x3c, 9);
+
+	pci_read_config_byte(pdev, 0x8, &c);
+
+	/* link control: enable link & SGD PCM output */
+	pci_write_config_byte(pdev, 0x41, 0xcc);
+
+	/* disable game port, FM, midi, sb, enable write to reg2c-2f */
+	pci_write_config_byte(pdev, 0x42, 0x20);
+
+	/* we are using Avance logic codec */
+	pci_write_config_word(pdev, 0x2c, 0x1005);
+	pci_write_config_word(pdev, 0x2e, 0x4710);
+	pci_read_config_dword(pdev, 0x2c, &val);
+
+	pci_write_config_byte(pdev, 0x42, 0x0);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
+			 loongson2e_686b_func0_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
+			 loongson2e_686b_func1_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
+			 loongson2e_686b_func2_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
+			 loongson2e_686b_func3_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
+			 loongson2e_686b_func5_fixup);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
+			 loongson2e_nec_fixup);
diff --git a/arch/mips/pci/fixup-lm2e.c b/arch/mips/pci/fixup-lm2e.c
deleted file mode 100644
index e18ae4f..0000000
--- a/arch/mips/pci/fixup-lm2e.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * fixup-lm2e.c
- *
- * Copyright (C) 2004 ICT CAS
- * Author: Li xiaoyu, ICT CAS
- *   lixy@ict.ac.cn
- *
- * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
- * Author: Fuxin Zhang, zhangfx@lemote.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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You 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.
- *
- */
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/mips-boards/bonito64.h>
-
-/* South bridge slot number is set by the pci probe process */
-static u8 sb_slot = 5;
-
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	int irq = 0;
-
-	if (slot == sb_slot) {
-		switch (PCI_FUNC(dev->devfn)) {
-		case 2:
-			irq = 10;
-			break;
-		case 3:
-			irq = 11;
-			break;
-		case 5:
-			irq = 9;
-			break;
-		}
-	} else {
-		irq = BONITO_IRQ_BASE + 25 + pin;
-	}
-	return irq;
-
-}
-
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
-	return 0;
-}
-
-static void __init loongson2e_nec_fixup(struct pci_dev *pdev)
-{
-	unsigned int val;
-
-	/* Configues port 1, 2, 3, 4 to be validate*/
-	pci_read_config_dword(pdev, 0xe0, &val);
-	pci_write_config_dword(pdev, 0xe0, (val & ~7) | 0x4);
-
-	/* System clock is 48-MHz Oscillator. */
-	pci_write_config_dword(pdev, 0xe4, 1 << 5);
-}
-
-static void __init loongson2e_686b_func0_fixup(struct pci_dev *pdev)
-{
-	unsigned char c;
-
-	sb_slot = PCI_SLOT(pdev->devfn);
-
-	printk(KERN_INFO "via686b fix: ISA bridge\n");
-
-	/*  Enable I/O Recovery time */
-	pci_write_config_byte(pdev, 0x40, 0x08);
-
-	/*  Enable ISA refresh */
-	pci_write_config_byte(pdev, 0x41, 0x01);
-
-	/*  disable ISA line buffer */
-	pci_write_config_byte(pdev, 0x45, 0x00);
-
-	/*  Gate INTR, and flush line buffer */
-	pci_write_config_byte(pdev, 0x46, 0xe0);
-
-	/*  Disable PCI Delay Transaction, Enable EISA ports 4D0/4D1. */
-	/* pci_write_config_byte(pdev, 0x47, 0x20); */
-
-	/*
-	 *  enable PCI Delay Transaction, Enable EISA ports 4D0/4D1.
-	 *  enable time-out timer
-	 */
-	pci_write_config_byte(pdev, 0x47, 0xe6);
-
-	/*
-	 * enable level trigger on pci irqs: 9,10,11,13
-	 * important! without this PCI interrupts won't work
-	 */
-	outb(0x2e, 0x4d1);
-
-	/*  512 K PCI Decode */
-	pci_write_config_byte(pdev, 0x48, 0x01);
-
-	/*  Wait for PGNT before grant to ISA Master/DMA */
-	pci_write_config_byte(pdev, 0x4a, 0x84);
-
-	/*
-	 * Plug'n'Play
-	 *
-	 *  Parallel DRQ 3, Floppy DRQ 2 (default)
-	 */
-	pci_write_config_byte(pdev, 0x50, 0x0e);
-
-	/*
-	 * IRQ Routing for Floppy and Parallel port
-	 *
-	 *  IRQ 6 for floppy, IRQ 7 for parallel port
-	 */
-	pci_write_config_byte(pdev, 0x51, 0x76);
-
-	/* IRQ Routing for serial ports (take IRQ 3 and 4) */
-	pci_write_config_byte(pdev, 0x52, 0x34);
-
-	/*  All IRQ's level triggered. */
-	pci_write_config_byte(pdev, 0x54, 0x00);
-
-	/* route PIRQA-D irq */
-	pci_write_config_byte(pdev, 0x55, 0x90);	/* bit 7-4, PIRQA */
-	pci_write_config_byte(pdev, 0x56, 0xba);	/* bit 7-4, PIRQC; */
-							/* 3-0, PIRQB */
-	pci_write_config_byte(pdev, 0x57, 0xd0);	/* bit 7-4, PIRQD */
-
-	/* enable function 5/6, audio/modem */
-	pci_read_config_byte(pdev, 0x85, &c);
-	c &= ~(0x3 << 2);
-	pci_write_config_byte(pdev, 0x85, c);
-
-	printk(KERN_INFO"via686b fix: ISA bridge done\n");
-}
-
-static void __init loongson2e_686b_func1_fixup(struct pci_dev *pdev)
-{
-	printk(KERN_INFO"via686b fix: IDE\n");
-
-	/* Modify IDE controller setup */
-	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 48);
-	pci_write_config_byte(pdev, PCI_COMMAND,
-			      PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-			      PCI_COMMAND_MASTER);
-	pci_write_config_byte(pdev, 0x40, 0x0b);
-	/* legacy mode */
-	pci_write_config_byte(pdev, 0x42, 0x09);
-
-#if 1/* play safe, otherwise we may see notebook's usb keyboard lockup */
-	/* disable read prefetch/write post buffers */
-	pci_write_config_byte(pdev, 0x41, 0x02);
-
-	/* use 3/4 as fifo thresh hold  */
-	pci_write_config_byte(pdev, 0x43, 0x0a);
-	pci_write_config_byte(pdev, 0x44, 0x00);
-
-	pci_write_config_byte(pdev, 0x45, 0x00);
-#else
-	pci_write_config_byte(pdev, 0x41, 0xc2);
-	pci_write_config_byte(pdev, 0x43, 0x35);
-	pci_write_config_byte(pdev, 0x44, 0x1c);
-
-	pci_write_config_byte(pdev, 0x45, 0x10);
-#endif
-
-	printk(KERN_INFO"via686b fix: IDE done\n");
-}
-
-static void __init loongson2e_686b_func2_fixup(struct pci_dev *pdev)
-{
-	/* irq routing */
-	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 10);
-}
-
-static void __init loongson2e_686b_func3_fixup(struct pci_dev *pdev)
-{
-	/* irq routing */
-	pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, 11);
-}
-
-static void __init loongson2e_686b_func5_fixup(struct pci_dev *pdev)
-{
-	unsigned int val;
-	unsigned char c;
-
-	/* enable IO */
-	pci_write_config_byte(pdev, PCI_COMMAND,
-			      PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
-			      PCI_COMMAND_MASTER);
-	pci_read_config_dword(pdev, 0x4, &val);
-	pci_write_config_dword(pdev, 0x4, val | 1);
-
-	/* route ac97 IRQ */
-	pci_write_config_byte(pdev, 0x3c, 9);
-
-	pci_read_config_byte(pdev, 0x8, &c);
-
-	/* link control: enable link & SGD PCM output */
-	pci_write_config_byte(pdev, 0x41, 0xcc);
-
-	/* disable game port, FM, midi, sb, enable write to reg2c-2f */
-	pci_write_config_byte(pdev, 0x42, 0x20);
-
-	/* we are using Avance logic codec */
-	pci_write_config_word(pdev, 0x2c, 0x1005);
-	pci_write_config_word(pdev, 0x2e, 0x4710);
-	pci_read_config_dword(pdev, 0x2c, &val);
-
-	pci_write_config_byte(pdev, 0x42, 0x0);
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686,
-			 loongson2e_686b_func0_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
-			 loongson2e_686b_func1_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2,
-			 loongson2e_686b_func2_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3,
-			 loongson2e_686b_func3_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5,
-			 loongson2e_686b_func5_fixup);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_USB,
-			 loongson2e_nec_fixup);
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c
new file mode 100644
index 0000000..822ae17
--- /dev/null
+++ b/arch/mips/pci/ops-bcm63xx.c
@@ -0,0 +1,467 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "pci-bcm63xx.h"
+
+/*
+ * swizzle 32bits data to return only the needed part
+ */
+static int postprocess_read(u32 data, int where, unsigned int size)
+{
+	u32 ret;
+
+	ret = 0;
+	switch (size) {
+	case 1:
+		ret = (data >> ((where & 3) << 3)) & 0xff;
+		break;
+	case 2:
+		ret = (data >> ((where & 3) << 3)) & 0xffff;
+		break;
+	case 4:
+		ret = data;
+		break;
+	}
+	return ret;
+}
+
+static int preprocess_write(u32 orig_data, u32 val, int where,
+			    unsigned int size)
+{
+	u32 ret;
+
+	ret = 0;
+	switch (size) {
+	case 1:
+		ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
+			(val << ((where & 3) << 3));
+		break;
+	case 2:
+		ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
+			(val << ((where & 3) << 3));
+		break;
+	case 4:
+		ret = val;
+		break;
+	}
+	return ret;
+}
+
+/*
+ * setup hardware for a configuration cycle with given parameters
+ */
+static int bcm63xx_setup_cfg_access(int type, unsigned int busn,
+				    unsigned int devfn, int where)
+{
+	unsigned int slot, func, reg;
+	u32 val;
+
+	slot = PCI_SLOT(devfn);
+	func = PCI_FUNC(devfn);
+	reg = where >> 2;
+
+	/* sanity check */
+	if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT))
+		return 1;
+
+	if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT))
+		return 1;
+
+	if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT))
+		return 1;
+
+	/* ok, setup config access */
+	val = (reg << MPI_L2PCFG_REG_SHIFT);
+	val |= (func << MPI_L2PCFG_FUNC_SHIFT);
+	val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
+	val |= MPI_L2PCFG_CFG_USEREG_MASK;
+	val |= MPI_L2PCFG_CFG_SEL_MASK;
+	/* type 0 cycle for local bus, type 1 cycle for anything else */
+	if (type != 0) {
+		/* FIXME: how to specify bus ??? */
+		val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
+	}
+	bcm_mpi_writel(val, MPI_L2PCFG_REG);
+
+	return 0;
+}
+
+static int bcm63xx_do_cfg_read(int type, unsigned int busn,
+				unsigned int devfn, int where, int size,
+				u32 *val)
+{
+	u32 data;
+
+	/* two phase cycle, first we write address, then read data at
+	 * another location, caller already has a spinlock so no need
+	 * to add one here  */
+	if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	iob();
+	data = le32_to_cpu(__raw_readl(pci_iospace_start));
+	/* restore IO space normal behaviour */
+	bcm_mpi_writel(0, MPI_L2PCFG_REG);
+
+	*val = postprocess_read(data, where, size);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_do_cfg_write(int type, unsigned int busn,
+				 unsigned int devfn, int where, int size,
+				 u32 val)
+{
+	u32 data;
+
+	/* two phase cycle, first we write address, then write data to
+	 * another location, caller already has a spinlock so no need
+	 * to add one here  */
+	if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	iob();
+
+	data = le32_to_cpu(__raw_readl(pci_iospace_start));
+	data = preprocess_write(data, val, where, size);
+
+	__raw_writel(cpu_to_le32(data), pci_iospace_start);
+	wmb();
+	/* no way to know the access is done, we have to wait */
+	udelay(500);
+	/* restore IO space normal behaviour */
+	bcm_mpi_writel(0, MPI_L2PCFG_REG);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_pci_read(struct pci_bus *bus, unsigned int devfn,
+			     int where, int size, u32 *val)
+{
+	int type;
+
+	type = bus->parent ? 1 : 0;
+
+	if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return bcm63xx_do_cfg_read(type, bus->number, devfn,
+				    where, size, val);
+}
+
+static int bcm63xx_pci_write(struct pci_bus *bus, unsigned int devfn,
+			      int where, int size, u32 val)
+{
+	int type;
+
+	type = bus->parent ? 1 : 0;
+
+	if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return bcm63xx_do_cfg_write(type, bus->number, devfn,
+				     where, size, val);
+}
+
+struct pci_ops bcm63xx_pci_ops = {
+	.read   = bcm63xx_pci_read,
+	.write  = bcm63xx_pci_write
+};
+
+#ifdef CONFIG_CARDBUS
+/*
+ * emulate configuration read access on a cardbus bridge
+ */
+#define FAKE_CB_BRIDGE_SLOT	0x1e
+
+static int fake_cb_bridge_bus_number = -1;
+
+static struct {
+	u16 pci_command;
+	u8 cb_latency;
+	u8 subordinate_busn;
+	u8 cardbus_busn;
+	u8 pci_busn;
+	int bus_assigned;
+	u16 bridge_control;
+
+	u32 mem_base0;
+	u32 mem_limit0;
+	u32 mem_base1;
+	u32 mem_limit1;
+
+	u32 io_base0;
+	u32 io_limit0;
+	u32 io_base1;
+	u32 io_limit1;
+} fake_cb_bridge_regs;
+
+static int fake_cb_bridge_read(int where, int size, u32 *val)
+{
+	unsigned int reg;
+	u32 data;
+
+	data = 0;
+	reg = where >> 2;
+	switch (reg) {
+	case (PCI_VENDOR_ID >> 2):
+	case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2):
+		/* create dummy vendor/device id from our cpu id */
+		data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM;
+		break;
+
+	case (PCI_COMMAND >> 2):
+		data = (PCI_STATUS_DEVSEL_SLOW << 16);
+		data |= fake_cb_bridge_regs.pci_command;
+		break;
+
+	case (PCI_CLASS_REVISION >> 2):
+		data = (PCI_CLASS_BRIDGE_CARDBUS << 16);
+		break;
+
+	case (PCI_CACHE_LINE_SIZE >> 2):
+		data = (PCI_HEADER_TYPE_CARDBUS << 16);
+		break;
+
+	case (PCI_INTERRUPT_LINE >> 2):
+		/* bridge control */
+		data = (fake_cb_bridge_regs.bridge_control << 16);
+		/* pin:intA line:0xff */
+		data |= (0x1 << 8) | 0xff;
+		break;
+
+	case (PCI_CB_PRIMARY_BUS >> 2):
+		data = (fake_cb_bridge_regs.cb_latency << 24);
+		data |= (fake_cb_bridge_regs.subordinate_busn << 16);
+		data |= (fake_cb_bridge_regs.cardbus_busn << 8);
+		data |= fake_cb_bridge_regs.pci_busn;
+		break;
+
+	case (PCI_CB_MEMORY_BASE_0 >> 2):
+		data = fake_cb_bridge_regs.mem_base0;
+		break;
+
+	case (PCI_CB_MEMORY_LIMIT_0 >> 2):
+		data = fake_cb_bridge_regs.mem_limit0;
+		break;
+
+	case (PCI_CB_MEMORY_BASE_1 >> 2):
+		data = fake_cb_bridge_regs.mem_base1;
+		break;
+
+	case (PCI_CB_MEMORY_LIMIT_1 >> 2):
+		data = fake_cb_bridge_regs.mem_limit1;
+		break;
+
+	case (PCI_CB_IO_BASE_0 >> 2):
+		/* | 1 for 32bits io support */
+		data = fake_cb_bridge_regs.io_base0 | 0x1;
+		break;
+
+	case (PCI_CB_IO_LIMIT_0 >> 2):
+		data = fake_cb_bridge_regs.io_limit0;
+		break;
+
+	case (PCI_CB_IO_BASE_1 >> 2):
+		/* | 1 for 32bits io support */
+		data = fake_cb_bridge_regs.io_base1 | 0x1;
+		break;
+
+	case (PCI_CB_IO_LIMIT_1 >> 2):
+		data = fake_cb_bridge_regs.io_limit1;
+		break;
+	}
+
+	*val = postprocess_read(data, where, size);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * emulate configuration write access on a cardbus bridge
+ */
+static int fake_cb_bridge_write(int where, int size, u32 val)
+{
+	unsigned int reg;
+	u32 data, tmp;
+	int ret;
+
+	ret = fake_cb_bridge_read((where & ~0x3), 4, &data);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return ret;
+
+	data = preprocess_write(data, val, where, size);
+
+	reg = where >> 2;
+	switch (reg) {
+	case (PCI_COMMAND >> 2):
+		fake_cb_bridge_regs.pci_command = (data & 0xffff);
+		break;
+
+	case (PCI_CB_PRIMARY_BUS >> 2):
+		fake_cb_bridge_regs.cb_latency = (data >> 24) & 0xff;
+		fake_cb_bridge_regs.subordinate_busn = (data >> 16) & 0xff;
+		fake_cb_bridge_regs.cardbus_busn = (data >> 8) & 0xff;
+		fake_cb_bridge_regs.pci_busn = data & 0xff;
+		if (fake_cb_bridge_regs.cardbus_busn)
+			fake_cb_bridge_regs.bus_assigned = 1;
+		break;
+
+	case (PCI_INTERRUPT_LINE >> 2):
+		tmp = (data >> 16) & 0xffff;
+		/* disable memory prefetch support */
+		tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
+		tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
+		fake_cb_bridge_regs.bridge_control = tmp;
+		break;
+
+	case (PCI_CB_MEMORY_BASE_0 >> 2):
+		fake_cb_bridge_regs.mem_base0 = data;
+		break;
+
+	case (PCI_CB_MEMORY_LIMIT_0 >> 2):
+		fake_cb_bridge_regs.mem_limit0 = data;
+		break;
+
+	case (PCI_CB_MEMORY_BASE_1 >> 2):
+		fake_cb_bridge_regs.mem_base1 = data;
+		break;
+
+	case (PCI_CB_MEMORY_LIMIT_1 >> 2):
+		fake_cb_bridge_regs.mem_limit1 = data;
+		break;
+
+	case (PCI_CB_IO_BASE_0 >> 2):
+		fake_cb_bridge_regs.io_base0 = data;
+		break;
+
+	case (PCI_CB_IO_LIMIT_0 >> 2):
+		fake_cb_bridge_regs.io_limit0 = data;
+		break;
+
+	case (PCI_CB_IO_BASE_1 >> 2):
+		fake_cb_bridge_regs.io_base1 = data;
+		break;
+
+	case (PCI_CB_IO_LIMIT_1 >> 2):
+		fake_cb_bridge_regs.io_limit1 = data;
+		break;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int bcm63xx_cb_read(struct pci_bus *bus, unsigned int devfn,
+			   int where, int size, u32 *val)
+{
+	/* snoop access to slot 0x1e on root bus, we fake a cardbus
+	 * bridge at this location */
+	if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
+		fake_cb_bridge_bus_number = bus->number;
+		return fake_cb_bridge_read(where, size, val);
+	}
+
+	/* a  configuration  cycle for  the  device  behind the  cardbus
+	 * bridge is  actually done as a  type 0 cycle  on the primary
+	 * bus. This means that only  one device can be on the cardbus
+	 * bus */
+	if (fake_cb_bridge_regs.bus_assigned &&
+	    bus->number == fake_cb_bridge_regs.cardbus_busn &&
+	    PCI_SLOT(devfn) == 0)
+		return bcm63xx_do_cfg_read(0, 0,
+					   PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
+					   where, size, val);
+
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int bcm63xx_cb_write(struct pci_bus *bus, unsigned int devfn,
+			    int where, int size, u32 val)
+{
+	if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
+		fake_cb_bridge_bus_number = bus->number;
+		return fake_cb_bridge_write(where, size, val);
+	}
+
+	if (fake_cb_bridge_regs.bus_assigned &&
+	    bus->number == fake_cb_bridge_regs.cardbus_busn &&
+	    PCI_SLOT(devfn) == 0)
+		return bcm63xx_do_cfg_write(0, 0,
+					    PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
+					    where, size, val);
+
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+struct pci_ops bcm63xx_cb_ops = {
+	.read   = bcm63xx_cb_read,
+	.write   = bcm63xx_cb_write,
+};
+
+/*
+ * only one IO window, so it  cannot be shared by PCI and cardbus, use
+ * fixup to choose and detect unhandled configuration
+ */
+static void bcm63xx_fixup(struct pci_dev *dev)
+{
+	static int io_window = -1;
+	int i, found, new_io_window;
+	u32 val;
+
+	/* look for any io resource */
+	found = 0;
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found)
+		return;
+
+	/* skip our fake bus with only cardbus bridge on it */
+	if (dev->bus->number == fake_cb_bridge_bus_number)
+		return;
+
+	/* find on which bus the device is */
+	if (fake_cb_bridge_regs.bus_assigned &&
+	    dev->bus->number == fake_cb_bridge_regs.cardbus_busn &&
+	    PCI_SLOT(dev->devfn) == 0)
+		new_io_window = 1;
+	else
+		new_io_window = 0;
+
+	if (new_io_window == io_window)
+		return;
+
+	if (io_window != -1) {
+		printk(KERN_ERR "bcm63xx: both PCI and cardbus devices "
+		       "need IO, which hardware cannot do\n");
+		return;
+	}
+
+	printk(KERN_INFO "bcm63xx: PCI IO window assigned to %s\n",
+	       (new_io_window == 0) ? "PCI" : "cardbus");
+
+	val = bcm_mpi_readl(MPI_L2PIOREMAP_REG);
+	if (io_window)
+		val |= MPI_L2PREMAP_IS_CARDBUS_MASK;
+	else
+		val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
+	bcm_mpi_writel(val, MPI_L2PIOREMAP_REG);
+
+	io_window = new_io_window;
+}
+
+DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
+#endif
diff --git a/arch/mips/pci/ops-bonito64.c b/arch/mips/pci/ops-bonito64.c
index f742c51..54e55e7 100644
--- a/arch/mips/pci/ops-bonito64.c
+++ b/arch/mips/pci/ops-bonito64.c
@@ -29,7 +29,7 @@
 #define PCI_ACCESS_READ  0
 #define PCI_ACCESS_WRITE 1
 
-#ifdef CONFIG_LEMOTE_FULONG
+#ifdef CONFIG_LEMOTE_FULOONG2E
 #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(BONITO_PCICFG_BASE | (offset))
 #define ID_SEL_BEGIN 11
 #else
@@ -77,7 +77,7 @@ static int bonito64_pcibios_config_access(unsigned char access_type,
 	addrp = CFG_SPACE_REG(addr & 0xffff);
 	if (access_type == PCI_ACCESS_WRITE) {
 		writel(cpu_to_le32(*data), addrp);
-#ifndef CONFIG_LEMOTE_FULONG
+#ifndef CONFIG_LEMOTE_FULOONG2E
 		/* Wait till done */
 		while (BONITO_PCIMSTAT & 0xF);
 #endif
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c
index a9060c7..6f5e24c 100644
--- a/arch/mips/pci/pci-bcm1480.c
+++ b/arch/mips/pci/pci-bcm1480.c
@@ -57,7 +57,7 @@ static void *cfg_space;
 #define PCI_BUS_ENABLED	1
 #define PCI_DEVICE_MODE	2
 
-static int bcm1480_bus_status = 0;
+static int bcm1480_bus_status;
 
 #define PCI_BRIDGE_DEVICE  0
 
diff --git a/arch/mips/pci/pci-bcm1480ht.c b/arch/mips/pci/pci-bcm1480ht.c
index f54f454..50cc6e9 100644
--- a/arch/mips/pci/pci-bcm1480ht.c
+++ b/arch/mips/pci/pci-bcm1480ht.c
@@ -56,7 +56,7 @@ static void *ht_cfg_space;
 #define PCI_BUS_ENABLED	1
 #define PCI_DEVICE_MODE	2
 
-static int bcm1480ht_bus_status = 0;
+static int bcm1480ht_bus_status;
 
 #define PCI_BRIDGE_DEVICE  0
 #define HT_BRIDGE_DEVICE   1
diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c
new file mode 100644
index 0000000..82e0fde
--- /dev/null
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -0,0 +1,224 @@
+/*
+ * 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) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+
+#include "pci-bcm63xx.h"
+
+/*
+ * Allow PCI to be disabled at runtime depending on board nvram
+ * configuration
+ */
+int bcm63xx_pci_enabled;
+
+static struct resource bcm_pci_mem_resource = {
+	.name   = "bcm63xx PCI memory space",
+	.start  = BCM_PCI_MEM_BASE_PA,
+	.end    = BCM_PCI_MEM_END_PA,
+	.flags  = IORESOURCE_MEM
+};
+
+static struct resource bcm_pci_io_resource = {
+	.name   = "bcm63xx PCI IO space",
+	.start  = BCM_PCI_IO_BASE_PA,
+#ifdef CONFIG_CARDBUS
+	.end    = BCM_PCI_IO_HALF_PA,
+#else
+	.end    = BCM_PCI_IO_END_PA,
+#endif
+	.flags  = IORESOURCE_IO
+};
+
+struct pci_controller bcm63xx_controller = {
+	.pci_ops	= &bcm63xx_pci_ops,
+	.io_resource	= &bcm_pci_io_resource,
+	.mem_resource	= &bcm_pci_mem_resource,
+};
+
+/*
+ * We handle cardbus  via a fake Cardbus bridge,  memory and io spaces
+ * have to be  clearly separated from PCI one  since we have different
+ * memory decoder.
+ */
+#ifdef CONFIG_CARDBUS
+static struct resource bcm_cb_mem_resource = {
+	.name   = "bcm63xx Cardbus memory space",
+	.start  = BCM_CB_MEM_BASE_PA,
+	.end    = BCM_CB_MEM_END_PA,
+	.flags  = IORESOURCE_MEM
+};
+
+static struct resource bcm_cb_io_resource = {
+	.name   = "bcm63xx Cardbus IO space",
+	.start  = BCM_PCI_IO_HALF_PA + 1,
+	.end    = BCM_PCI_IO_END_PA,
+	.flags  = IORESOURCE_IO
+};
+
+struct pci_controller bcm63xx_cb_controller = {
+	.pci_ops	= &bcm63xx_cb_ops,
+	.io_resource	= &bcm_cb_io_resource,
+	.mem_resource	= &bcm_cb_mem_resource,
+};
+#endif
+
+static u32 bcm63xx_int_cfg_readl(u32 reg)
+{
+	u32 tmp;
+
+	tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
+	tmp |= MPI_PCICFGCTL_WRITEEN_MASK;
+	bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG);
+	iob();
+	return bcm_mpi_readl(MPI_PCICFGDATA_REG);
+}
+
+static void bcm63xx_int_cfg_writel(u32 val, u32 reg)
+{
+	u32 tmp;
+
+	tmp = reg & MPI_PCICFGCTL_CFGADDR_MASK;
+	tmp |=  MPI_PCICFGCTL_WRITEEN_MASK;
+	bcm_mpi_writel(tmp, MPI_PCICFGCTL_REG);
+	bcm_mpi_writel(val, MPI_PCICFGDATA_REG);
+}
+
+void __iomem *pci_iospace_start;
+
+static int __init bcm63xx_pci_init(void)
+{
+	unsigned int mem_size;
+	u32 val;
+
+	if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
+		return -ENODEV;
+
+	if (!bcm63xx_pci_enabled)
+		return -ENODEV;
+
+	/*
+	 * configuration  access are  done through  IO space,  remap 4
+	 * first bytes to access it from CPU.
+	 *
+	 * this means that  no io access from CPU  should happen while
+	 * we do a configuration cycle,  but there's no way we can add
+	 * a spinlock for each io access, so this is currently kind of
+	 * broken on SMP.
+	 */
+	pci_iospace_start = ioremap_nocache(BCM_PCI_IO_BASE_PA, 4);
+	if (!pci_iospace_start)
+		return -ENOMEM;
+
+	/* setup local bus to PCI access (PCI memory) */
+	val = BCM_PCI_MEM_BASE_PA & MPI_L2P_BASE_MASK;
+	bcm_mpi_writel(val, MPI_L2PMEMBASE1_REG);
+	bcm_mpi_writel(~(BCM_PCI_MEM_SIZE - 1), MPI_L2PMEMRANGE1_REG);
+	bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PMEMREMAP1_REG);
+
+	/* set Cardbus IDSEL (type 0 cfg access on primary bus for
+	 * this IDSEL will be done on Cardbus instead) */
+	val = bcm_pcmcia_readl(PCMCIA_C1_REG);
+	val &= ~PCMCIA_C1_CBIDSEL_MASK;
+	val |= (CARDBUS_PCI_IDSEL << PCMCIA_C1_CBIDSEL_SHIFT);
+	bcm_pcmcia_writel(val, PCMCIA_C1_REG);
+
+#ifdef CONFIG_CARDBUS
+	/* setup local bus to PCI access (Cardbus memory) */
+	val = BCM_CB_MEM_BASE_PA & MPI_L2P_BASE_MASK;
+	bcm_mpi_writel(val, MPI_L2PMEMBASE2_REG);
+	bcm_mpi_writel(~(BCM_CB_MEM_SIZE - 1), MPI_L2PMEMRANGE2_REG);
+	val |= MPI_L2PREMAP_ENABLED_MASK | MPI_L2PREMAP_IS_CARDBUS_MASK;
+	bcm_mpi_writel(val, MPI_L2PMEMREMAP2_REG);
+#else
+	/* disable second access windows */
+	bcm_mpi_writel(0, MPI_L2PMEMREMAP2_REG);
+#endif
+
+	/* setup local bus  to PCI access (IO memory),  we have only 1
+	 * IO window  for both PCI  and cardbus, but it  cannot handle
+	 * both  at the  same time,  assume standard  PCI for  now, if
+	 * cardbus card has  IO zone, PCI fixup will  change window to
+	 * cardbus */
+	val = BCM_PCI_IO_BASE_PA & MPI_L2P_BASE_MASK;
+	bcm_mpi_writel(val, MPI_L2PIOBASE_REG);
+	bcm_mpi_writel(~(BCM_PCI_IO_SIZE - 1), MPI_L2PIORANGE_REG);
+	bcm_mpi_writel(val | MPI_L2PREMAP_ENABLED_MASK, MPI_L2PIOREMAP_REG);
+
+	/* enable PCI related GPIO pins */
+	bcm_mpi_writel(MPI_LOCBUSCTL_EN_PCI_GPIO_MASK, MPI_LOCBUSCTL_REG);
+
+	/* setup PCI to local bus access, used by PCI device to target
+	 * local RAM while bus mastering */
+	bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3);
+	if (BCMCPU_IS_6358())
+		val = MPI_SP0_REMAP_ENABLE_MASK;
+	else
+		val = 0;
+	bcm_mpi_writel(val, MPI_SP0_REMAP_REG);
+
+	bcm63xx_int_cfg_writel(0x0, PCI_BASE_ADDRESS_4);
+	bcm_mpi_writel(0, MPI_SP1_REMAP_REG);
+
+	mem_size = bcm63xx_get_memory_size();
+
+	/* 6348 before rev b0 exposes only 16 MB of RAM memory through
+	 * PCI, throw a warning if we have more memory */
+	if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() & 0xf0) == 0xa0) {
+		if (mem_size > (16 * 1024 * 1024))
+			printk(KERN_WARNING "bcm63xx: this CPU "
+			       "revision cannot handle more than 16MB "
+			       "of RAM for PCI bus mastering\n");
+	} else {
+		/* setup sp0 range to local RAM size */
+		bcm_mpi_writel(~(mem_size - 1), MPI_SP0_RANGE_REG);
+		bcm_mpi_writel(0, MPI_SP1_RANGE_REG);
+	}
+
+	/* change  host bridge  retry  counter to  infinite number  of
+	 * retry,  needed for  some broadcom  wifi cards  with Silicon
+	 * Backplane bus where access to srom seems very slow  */
+	val = bcm63xx_int_cfg_readl(BCMPCI_REG_TIMERS);
+	val &= ~REG_TIMER_RETRY_MASK;
+	bcm63xx_int_cfg_writel(val, BCMPCI_REG_TIMERS);
+
+	/* enable memory decoder and bus mastering */
+	val = bcm63xx_int_cfg_readl(PCI_COMMAND);
+	val |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	bcm63xx_int_cfg_writel(val, PCI_COMMAND);
+
+	/* enable read prefetching & disable byte swapping for bus
+	 * mastering transfers */
+	val = bcm_mpi_readl(MPI_PCIMODESEL_REG);
+	val &= ~MPI_PCIMODESEL_BAR1_NOSWAP_MASK;
+	val &= ~MPI_PCIMODESEL_BAR2_NOSWAP_MASK;
+	val &= ~MPI_PCIMODESEL_PREFETCH_MASK;
+	val |= (8 << MPI_PCIMODESEL_PREFETCH_SHIFT);
+	bcm_mpi_writel(val, MPI_PCIMODESEL_REG);
+
+	/* enable pci interrupt */
+	val = bcm_mpi_readl(MPI_LOCINT_REG);
+	val |= MPI_LOCINT_MASK(MPI_LOCINT_EXT_PCI_INT);
+	bcm_mpi_writel(val, MPI_LOCINT_REG);
+
+	register_pci_controller(&bcm63xx_controller);
+
+#ifdef CONFIG_CARDBUS
+	register_pci_controller(&bcm63xx_cb_controller);
+#endif
+
+	/* mark memory space used for IO mapping as reserved */
+	request_mem_region(BCM_PCI_IO_BASE_PA, BCM_PCI_IO_SIZE,
+			   "bcm63xx PCI IO space");
+	return 0;
+}
+
+arch_initcall(bcm63xx_pci_init);
diff --git a/arch/mips/pci/pci-bcm63xx.h b/arch/mips/pci/pci-bcm63xx.h
new file mode 100644
index 0000000..a6e594e
--- /dev/null
+++ b/arch/mips/pci/pci-bcm63xx.h
@@ -0,0 +1,27 @@
+#ifndef PCI_BCM63XX_H_
+#define PCI_BCM63XX_H_
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_dev_pci.h>
+
+/*
+ * Cardbus shares  the PCI bus, but has  no IDSEL, so a  special id is
+ * reserved for it.  If you have a standard PCI device at this id, you
+ * need to change the following definition.
+ */
+#define CARDBUS_PCI_IDSEL	0x8
+
+/*
+ * defined in ops-bcm63xx.c
+ */
+extern struct pci_ops bcm63xx_pci_ops;
+extern struct pci_ops bcm63xx_cb_ops;
+
+/*
+ * defined in pci-bcm63xx.c
+ */
+extern void __iomem *pci_iospace_start;
+
+#endif /* ! PCI_BCM63XX_H_ */
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c
index bf63959..ada24e6 100644
--- a/arch/mips/pci/pci-sb1250.c
+++ b/arch/mips/pci/pci-sb1250.c
@@ -58,7 +58,7 @@ static void *cfg_space;
 #define LDT_BUS_ENABLED	2
 #define PCI_DEVICE_MODE	4
 
-static int sb1250_bus_status = 0;
+static int sb1250_bus_status;
 
 #define PCI_BRIDGE_DEVICE  0
 #define LDT_BRIDGE_DEVICE  1
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index b0eb9e7..9a11c22 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -31,8 +31,8 @@ unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES;
 
 static struct pci_controller *hose_head, **hose_tail = &hose_head;
 
-unsigned long PCIBIOS_MIN_IO	= 0x0000;
-unsigned long PCIBIOS_MIN_MEM	= 0;
+unsigned long PCIBIOS_MIN_IO;
+unsigned long PCIBIOS_MIN_MEM;
 
 static int pci_initialized;
 
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 2d3c0dc..3498ac9 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -70,7 +70,7 @@ void __init bus_error_init(void)
 }
 
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
 	unsigned int year, month, day, hour, min, sec;
 	unsigned long flags;
@@ -92,7 +92,8 @@ unsigned long read_persistent_clock(void)
 	m48t37_base->control = 0x00;
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
-	return mktime(year, month, day, hour, min, sec);
+	ts->tv_sec = mktime(year, month, day, hour, min, sec);
+	ts->tv_nsec = 0;
 }
 
 int rtc_mips_set_time(unsigned long tim)
diff --git a/arch/mips/power/hibernate.S b/arch/mips/power/hibernate.S
index 4b8174b..0cf86fb 100644
--- a/arch/mips/power/hibernate.S
+++ b/arch/mips/power/hibernate.S
@@ -8,6 +8,7 @@
  *         Wu Zhangjin <wuzj@lemote.com>
  */
 #include <asm/asm-offsets.h>
+#include <asm/page.h>
 #include <asm/regdef.h>
 #include <asm/asm.h>
 
@@ -34,7 +35,7 @@ LEAF(swsusp_arch_resume)
 0:
 	PTR_L t1, PBE_ADDRESS(t0)   /* source */
 	PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */
-	PTR_ADDIU t3, t1, _PAGE_SIZE
+	PTR_ADDIU t3, t1, PAGE_SIZE
 1:
 	REG_L t8, (t1)
 	REG_S t8, (t2)
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index ef1564e..416b18f 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -10,4 +10,4 @@ obj-$(CONFIG_SGI_IP22) += ip22-berr.o
 obj-$(CONFIG_SGI_IP28) += ip28-berr.o
 obj-$(CONFIG_EISA)	+= ip22-eisa.o
 
-# EXTRA_CFLAGS += -Werror
+EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 672e45d..623ffc9 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -87,19 +87,26 @@ enum swarm_rtc_type {
 
 enum swarm_rtc_type swarm_rtc_type;
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
+	unsigned long sec;
+
 	switch (swarm_rtc_type) {
 	case RTC_XICOR:
-		return xicor_get_time();
+		sec = xicor_get_time();
+		break;
 
 	case RTC_M4LT81:
-		return m41t81_get_time();
+		sec = m41t81_get_time();
+		break;
 
 	case RTC_NONE:
 	default:
-		return mktime(2000, 1, 1, 0, 0, 0);
+		sec = mktime(2000, 1, 1, 0, 0, 0);
+		break;
 	}
+	ts->tv_sec = sec;
+	tv->tv_nsec = 0;
 }
 
 int rtc_mips_set_time(unsigned long sec)
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 0d9ec1a..62df6a5 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -182,7 +182,8 @@ void __init plat_time_init(void)
 	setup_pit_timer();
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-	return -1;
+	ts->tv_sec = -1;
+	ts->tv_nsec = 0;
 }
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
index 7b637a7..707cfa9 100644
--- a/arch/mips/txx9/generic/pci.c
+++ b/arch/mips/txx9/generic/pci.c
@@ -341,6 +341,15 @@ static void quirk_slc90e66_ide(struct pci_dev *dev)
 }
 #endif /* CONFIG_TOSHIBA_FPCIB0 */
 
+static void tc35815_fixup(struct pci_dev *dev)
+{
+	/* This device may have PM registers but not they are not suported. */
+	if (dev->pm_cap) {
+		dev_info(&dev->dev, "PM disabled\n");
+		dev->pm_cap = 0;
+	}
+}
+
 static void final_fixup(struct pci_dev *dev)
 {
 	unsigned char bist;
@@ -374,6 +383,10 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
 	quirk_slc90e66_ide);
 #endif
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
+			PCI_DEVICE_ID_TOSHIBA_TC35815_NWU, tc35815_fixup);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
+			PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939, tc35815_fixup);
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
 DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
 
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index a205e2b..c860810 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -782,7 +782,7 @@ void __init txx9_iocled_init(unsigned long baseaddr,
 		return;
 	iocled->mmioaddr = ioremap(baseaddr, 1);
 	if (!iocled->mmioaddr)
-		return;
+		goto out_free;
 	iocled->chip.get = txx9_iocled_get;
 	iocled->chip.set = txx9_iocled_set;
 	iocled->chip.direction_input = txx9_iocled_dir_in;
@@ -791,13 +791,13 @@ void __init txx9_iocled_init(unsigned long baseaddr,
 	iocled->chip.base = basenum;
 	iocled->chip.ngpio = num;
 	if (gpiochip_add(&iocled->chip))
-		return;
+		goto out_unmap;
 	if (basenum < 0)
 		basenum = iocled->chip.base;
 
 	pdev = platform_device_alloc("leds-gpio", basenum);
 	if (!pdev)
-		return;
+		goto out_gpio;
 	iocled->pdata.num_leds = num;
 	iocled->pdata.leds = iocled->leds;
 	for (i = 0; i < num; i++) {
@@ -812,7 +812,16 @@ void __init txx9_iocled_init(unsigned long baseaddr,
 	}
 	pdev->dev.platform_data = &iocled->pdata;
 	if (platform_device_add(pdev))
-		platform_device_put(pdev);
+		goto out_pdev;
+	return;
+out_pdev:
+	platform_device_put(pdev);
+out_gpio:
+	gpio_remove(&iocled->chip);
+out_unmap:
+	iounmap(iocled->mmioaddr);
+out_free:
+	kfree(iocled);
 }
 #else /* CONFIG_LEDS_GPIO */
 void __init txx9_iocled_init(unsigned long baseaddr,
diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h
index 19aecc9..6095a28 100644
--- a/arch/mn10300/include/asm/pci.h
+++ b/arch/mn10300/include/asm/pci.h
@@ -101,7 +101,18 @@ extern void pcibios_bus_to_resource(struct pci_dev *dev,
 				    struct resource *res,
 				    struct pci_bus_region *region);
 
-#define pcibios_scan_all_fns(a, b)	0
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+	struct resource *root = NULL;
+
+	if (res->flags & IORESOURCE_IO)
+		root = &ioport_resource;
+	if (res->flags & IORESOURCE_MEM)
+		root = &iomem_resource;
+
+	return root;
+}
 
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff --git a/arch/mn10300/include/asm/socket.h b/arch/mn10300/include/asm/socket.h
index fb5daf4..4df75af 100644
--- a/arch/mn10300/include/asm/socket.h
+++ b/arch/mn10300/include/asm/socket.h
@@ -57,4 +57,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h
index fad6861..2a98393 100644
--- a/arch/mn10300/include/asm/unistd.h
+++ b/arch/mn10300/include/asm/unistd.h
@@ -347,7 +347,7 @@
 #define __NR_preadv		334
 #define __NR_pwritev		335
 #define __NR_rt_tgsigqueueinfo	336
-#define __NR_perf_counter_open	337
+#define __NR_perf_event_open	337
 
 #ifdef __KERNEL__
 
diff --git a/arch/mn10300/kernel/asm-offsets.c b/arch/mn10300/kernel/asm-offsets.c
index 2646fcb..82b4007 100644
--- a/arch/mn10300/kernel/asm-offsets.c
+++ b/arch/mn10300/kernel/asm-offsets.c
@@ -95,7 +95,7 @@ void foo(void)
 	OFFSET(__iobase,		mn10300_serial_port, _iobase);
 
 	DEFINE(__UART_XMIT_SIZE,	UART_XMIT_SIZE);
-	OFFSET(__xmit_buffer,		uart_info, xmit.buf);
-	OFFSET(__xmit_head,		uart_info, xmit.head);
-	OFFSET(__xmit_tail,		uart_info, xmit.tail);
+	OFFSET(__xmit_buffer,		uart_state, xmit.buf);
+	OFFSET(__xmit_head,		uart_state, xmit.head);
+	OFFSET(__xmit_tail,		uart_state, xmit.tail);
 }
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index e0d2563..a94e7ea 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -723,7 +723,7 @@ ENTRY(sys_call_table)
 	.long sys_preadv
 	.long sys_pwritev		/* 335 */
 	.long sys_rt_tgsigqueueinfo
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
 
 
 nr_syscalls=(.-sys_call_table)/4
diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S
index f4aa079..76f41bd 100644
--- a/arch/mn10300/kernel/vmlinux.lds.S
+++ b/arch/mn10300/kernel/vmlinux.lds.S
@@ -115,12 +115,10 @@ SECTIONS
   . = ALIGN(PAGE_SIZE);
   pg0 = .;
 
-  /* Sections to be discarded */
-  /DISCARD/ : {
-	EXIT_CALL
-	}
-
   STABS_DEBUG
 
   DWARF_DEBUG
+
+  /* Sections to be discarded */
+  DISCARDS
 }
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 06f8d5b..f388dc6 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -16,7 +16,7 @@ config PARISC
 	select RTC_DRV_GENERIC
 	select INIT_ALL_POSSIBLE
 	select BUG
-	select HAVE_PERF_COUNTERS
+	select HAVE_PERF_EVENTS
 	select GENERIC_ATOMIC64 if !64BIT
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/include/asm/agp.h b/arch/parisc/include/asm/agp.h
index 9651660..d226ffa 100644
--- a/arch/parisc/include/asm/agp.h
+++ b/arch/parisc/include/asm/agp.h
@@ -11,10 +11,6 @@
 #define unmap_page_from_agp(page)	/* nothing */
 #define flush_agp_cache()		mb()
 
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
 #define alloc_gatt_pages(order)		\
 	((char *)__get_free_pages(GFP_KERNEL, (order)))
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 7d842d6..64c7aa5 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -233,7 +233,6 @@ static inline void pcibios_register_hba(struct pci_hba_data *x)
  *   rp7420/8420 boxes and then revisit this issue.
  */
 #define pcibios_assign_all_busses()     (1)
-#define pcibios_scan_all_fns(a, b)	(0)
 
 #define PCIBIOS_MIN_IO          0x10
 #define PCIBIOS_MIN_MEM         0x1000 /* NBPG - but pci/setup-res.c dies */
diff --git a/arch/parisc/include/asm/perf_counter.h b/arch/parisc/include/asm/perf_counter.h
deleted file mode 100644
index dc9e829..0000000
--- a/arch/parisc/include/asm/perf_counter.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_PARISC_PERF_COUNTER_H
-#define __ASM_PARISC_PERF_COUNTER_H
-
-/* parisc only supports software counters through this interface. */
-static inline void set_perf_counter_pending(void) { }
-
-#endif /* __ASM_PARISC_PERF_COUNTER_H */
diff --git a/arch/parisc/include/asm/perf_event.h b/arch/parisc/include/asm/perf_event.h
new file mode 100644
index 0000000..cc14642
--- /dev/null
+++ b/arch/parisc/include/asm/perf_event.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_PARISC_PERF_EVENT_H
+#define __ASM_PARISC_PERF_EVENT_H
+
+/* parisc only supports software events through this interface. */
+static inline void set_perf_event_pending(void) { }
+
+#endif /* __ASM_PARISC_PERF_EVENT_H */
diff --git a/arch/parisc/include/asm/socket.h b/arch/parisc/include/asm/socket.h
index 885472b..960b1e5 100644
--- a/arch/parisc/include/asm/socket.h
+++ b/arch/parisc/include/asm/socket.h
@@ -24,6 +24,8 @@
 #define SO_RCVTIMEO	0x1006
 #define SO_ERROR	0x1007
 #define SO_TYPE		0x1008
+#define SO_PROTOCOL	0x1028
+#define SO_DOMAIN	0x1029
 #define SO_PEERNAME	0x2000
 
 #define SO_NO_CHECK	0x400b
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index f3d3b8b..cda1583 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -810,9 +810,9 @@
 #define __NR_preadv		(__NR_Linux + 315)
 #define __NR_pwritev		(__NR_Linux + 316)
 #define __NR_rt_tgsigqueueinfo	(__NR_Linux + 317)
-#define __NR_perf_counter_open	(__NR_Linux + 318)
+#define __NR_perf_event_open	(__NR_Linux + 318)
 
-#define __NR_Linux_syscalls	(__NR_perf_counter_open + 1)
+#define __NR_Linux_syscalls	(__NR_perf_event_open + 1)
 
 
 #define __IGNORE_select		/* newselect */
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index cf145eb..843f423 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -416,7 +416,7 @@
 	ENTRY_COMP(preadv)		/* 315 */
 	ENTRY_COMP(pwritev)
 	ENTRY_COMP(rt_tgsigqueueinfo)
-	ENTRY_SAME(perf_counter_open)
+	ENTRY_SAME(perf_event_open)
 
 	/* Nothing yet */
 
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index fd2cc4f..aea1784 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -237,9 +237,12 @@ SECTIONS
 	/* freed after init ends here */
 	_end = . ;
 
+	STABS_DEBUG
+	.note 0 : { *(.note) }
+
 	/* Sections to be discarded */
+	DISCARDS
 	/DISCARD/ : {
-		*(.exitcall.exit)
 #ifdef CONFIG_64BIT
 		/* temporary hack until binutils is fixed to not emit these
 	 	 * for static binaries
@@ -252,7 +255,4 @@ SECTIONS
 		*(.gnu.hash)
 #endif
 	}
-
-	STABS_DEBUG
-	.note 0 : { *(.note) }	
 }
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d00131c..4fd4790 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -49,6 +49,9 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool PPC64
 
+config NEED_PER_CPU_EMBED_FIRST_CHUNK
+	def_bool PPC64
+
 config IRQ_PER_CPU
 	bool
 	default y
@@ -120,12 +123,13 @@ config PPC
 	select HAVE_KRETPROBES
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_LMB
-	select HAVE_DMA_ATTRS if PPC64
+	select HAVE_DMA_ATTRS
+	select HAVE_DMA_API_DEBUG
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select HAVE_OPROFILE
 	select HAVE_SYSCALL_WRAPPERS if PPC64
 	select GENERIC_ATOMIC64 if PPC32
-	select HAVE_PERF_COUNTERS
+	select HAVE_PERF_EVENTS
 
 config EARLY_PRINTK
 	bool
@@ -307,10 +311,6 @@ config SWIOTLB
 	  platforms where the size of a physical address is larger
 	  than the bus address.  Not all platforms support this.
 
-config PPC_NEED_DMA_SYNC_OPS
-	def_bool y
-	depends on (NOT_COHERENT_CACHE || SWIOTLB)
-
 config HOTPLUG_CPU
 	bool "Support for enabling/disabling CPUs"
 	depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
@@ -472,7 +472,7 @@ config PPC_16K_PAGES
 	bool "16k page size" if 44x
 
 config PPC_64K_PAGES
-	bool "64k page size" if 44x || PPC_STD_MMU_64
+	bool "64k page size" if 44x || PPC_STD_MMU_64 || PPC_BOOK3E_64
 	select PPC_HAS_HASH_64K if PPC_STD_MMU_64
 
 config PPC_256K_PAGES
@@ -492,16 +492,16 @@ endchoice
 
 config FORCE_MAX_ZONEORDER
 	int "Maximum zone order"
-	range 9 64 if PPC_STD_MMU_64 && PPC_64K_PAGES
-	default "9" if PPC_STD_MMU_64 && PPC_64K_PAGES
-	range 13 64 if PPC_STD_MMU_64 && !PPC_64K_PAGES
-	default "13" if PPC_STD_MMU_64 && !PPC_64K_PAGES
-	range 9 64 if PPC_STD_MMU_32 && PPC_16K_PAGES
-	default "9" if PPC_STD_MMU_32 && PPC_16K_PAGES
-	range 7 64 if PPC_STD_MMU_32 && PPC_64K_PAGES
-	default "7" if PPC_STD_MMU_32 && PPC_64K_PAGES
-	range 5 64 if PPC_STD_MMU_32 && PPC_256K_PAGES
-	default "5" if PPC_STD_MMU_32 && PPC_256K_PAGES
+	range 9 64 if PPC64 && PPC_64K_PAGES
+	default "9" if PPC64 && PPC_64K_PAGES
+	range 13 64 if PPC64 && !PPC_64K_PAGES
+	default "13" if PPC64 && !PPC_64K_PAGES
+	range 9 64 if PPC32 && PPC_16K_PAGES
+	default "9" if PPC32 && PPC_16K_PAGES
+	range 7 64 if PPC32 && PPC_64K_PAGES
+	default "7" if PPC32 && PPC_64K_PAGES
+	range 5 64 if PPC32 && PPC_256K_PAGES
+	default "5" if PPC32 && PPC_256K_PAGES
 	range 11 64
 	default "11"
 	help
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index bc35f4e..952a396 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -77,7 +77,7 @@ CPP		= $(CC) -E $(KBUILD_CFLAGS)
 CHECKFLAGS	+= -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__
 
 ifeq ($(CONFIG_PPC64),y)
-GCC_BROKEN_VEC	:= $(shell if [ $(call cc-version) -lt 0400 ] ; then echo "y"; fi)
+GCC_BROKEN_VEC	:= $(call cc-ifversion, -lt, 0400, y)
 
 ifeq ($(CONFIG_POWER4_ONLY),y)
 ifeq ($(CONFIG_ALTIVEC),y)
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index 325b310..27db893 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -8,6 +8,10 @@
  *   Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *   Copyright (c) 2003, 2004 Zultys Technologies
  *
+ * Copyright (C) 2009 Wind River Systems, Inc.
+ *   Updated for supporting PPC405EX on Kilauea.
+ *   Tiejun Chen <tiejun.chen@windriver.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
@@ -659,3 +663,141 @@ void ibm405ep_fixup_clocks(unsigned int sys_clk)
 	dt_fixup_clock("/plb/opb/serial@ef600300", uart0);
 	dt_fixup_clock("/plb/opb/serial@ef600400", uart1);
 }
+
+static u8 ibm405ex_fwdv_multi_bits[] = {
+	/* values for:  1 - 16 */
+	0x01, 0x02, 0x0e, 0x09, 0x04, 0x0b, 0x10, 0x0d, 0x0c, 0x05,
+	0x06, 0x0f, 0x0a, 0x07, 0x08, 0x03
+};
+
+u32 ibm405ex_get_fwdva(unsigned long cpr_fwdv)
+{
+	u32 index;
+
+	for (index = 0; index < ARRAY_SIZE(ibm405ex_fwdv_multi_bits); index++)
+		if (cpr_fwdv == (u32)ibm405ex_fwdv_multi_bits[index])
+			return index + 1;
+
+	return 0;
+}
+
+static u8 ibm405ex_fbdv_multi_bits[] = {
+	/* values for:  1 - 100 */
+	0x00, 0xff, 0x7e, 0xfd, 0x7a, 0xf5, 0x6a, 0xd5, 0x2a, 0xd4,
+	0x29, 0xd3, 0x26, 0xcc, 0x19, 0xb3, 0x67, 0xce, 0x1d, 0xbb,
+	0x77, 0xee, 0x5d, 0xba, 0x74, 0xe9, 0x52, 0xa5, 0x4b, 0x96,
+	0x2c, 0xd8, 0x31, 0xe3, 0x46, 0x8d, 0x1b, 0xb7, 0x6f, 0xde,
+	0x3d, 0xfb, 0x76, 0xed, 0x5a, 0xb5, 0x6b, 0xd6, 0x2d, 0xdb,
+	0x36, 0xec, 0x59, 0xb2, 0x64, 0xc9, 0x12, 0xa4, 0x48, 0x91,
+	0x23, 0xc7, 0x0e, 0x9c, 0x38, 0xf0, 0x61, 0xc2, 0x05, 0x8b,
+	0x17, 0xaf, 0x5f, 0xbe, 0x7c, 0xf9, 0x72, 0xe5, 0x4a, 0x95,
+	0x2b, 0xd7, 0x2e, 0xdc, 0x39, 0xf3, 0x66, 0xcd, 0x1a, 0xb4,
+	0x68, 0xd1, 0x22, 0xc4, 0x09, 0x93, 0x27, 0xcf, 0x1e, 0xbc,
+	/* values for:  101 - 200 */
+	0x78, 0xf1, 0x62, 0xc5, 0x0a, 0x94, 0x28, 0xd0, 0x21, 0xc3,
+	0x06, 0x8c, 0x18, 0xb0, 0x60, 0xc1, 0x02, 0x84, 0x08, 0x90,
+	0x20, 0xc0, 0x01, 0x83, 0x07, 0x8f, 0x1f, 0xbf, 0x7f, 0xfe,
+	0x7d, 0xfa, 0x75, 0xea, 0x55, 0xaa, 0x54, 0xa9, 0x53, 0xa6,
+	0x4c, 0x99, 0x33, 0xe7, 0x4e, 0x9d, 0x3b, 0xf7, 0x6e, 0xdd,
+	0x3a, 0xf4, 0x69, 0xd2, 0x25, 0xcb, 0x16, 0xac, 0x58, 0xb1,
+	0x63, 0xc6, 0x0d, 0x9b, 0x37, 0xef, 0x5e, 0xbd, 0x7b, 0xf6,
+	0x6d, 0xda, 0x35, 0xeb, 0x56, 0xad, 0x5b, 0xb6, 0x6c, 0xd9,
+	0x32, 0xe4, 0x49, 0x92, 0x24, 0xc8, 0x11, 0xa3, 0x47, 0x8e,
+	0x1c, 0xb8, 0x70, 0xe1, 0x42, 0x85, 0x0b, 0x97, 0x2f, 0xdf,
+	/* values for:  201 - 255 */
+	0x3e, 0xfc, 0x79, 0xf2, 0x65, 0xca, 0x15, 0xab, 0x57, 0xae,
+	0x5c, 0xb9, 0x73, 0xe6, 0x4d, 0x9a, 0x34, 0xe8, 0x51, 0xa2,
+	0x44, 0x89, 0x13, 0xa7, 0x4f, 0x9e, 0x3c, 0xf8, 0x71, 0xe2,
+	0x45, 0x8a, 0x14, 0xa8, 0x50, 0xa1, 0x43, 0x86, 0x0c, 0x98,
+	0x30, 0xe0, 0x41, 0x82, 0x04, 0x88, 0x10, 0xa0, 0x40, 0x81,
+	0x03, 0x87, 0x0f, 0x9f, 0x3f  /* END */
+};
+
+u32 ibm405ex_get_fbdv(unsigned long cpr_fbdv)
+{
+	u32 index;
+
+	for (index = 0; index < ARRAY_SIZE(ibm405ex_fbdv_multi_bits); index++)
+		if (cpr_fbdv == (u32)ibm405ex_fbdv_multi_bits[index])
+			return index + 1;
+
+	return 0;
+}
+
+void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk)
+{
+	/* PLL config */
+	u32 pllc  = CPR0_READ(DCRN_CPR0_PLLC);
+	u32 plld  = CPR0_READ(DCRN_CPR0_PLLD);
+	u32 cpud  = CPR0_READ(DCRN_CPR0_PRIMAD);
+	u32 plbd  = CPR0_READ(DCRN_CPR0_PRIMBD);
+	u32 opbd  = CPR0_READ(DCRN_CPR0_OPBD);
+	u32 perd  = CPR0_READ(DCRN_CPR0_PERD);
+
+	/* Dividers */
+	u32 fbdv   = ibm405ex_get_fbdv(__fix_zero((plld >> 24) & 0xff, 1));
+
+	u32 fwdva  = ibm405ex_get_fwdva(__fix_zero((plld >> 16) & 0x0f, 1));
+
+	u32 cpudv0 = __fix_zero((cpud >> 24) & 7, 8);
+
+	/* PLBDV0 is hardwared to 010. */
+	u32 plbdv0 = 2;
+	u32 plb2xdv0 = __fix_zero((plbd >> 16) & 7, 8);
+
+	u32 opbdv0 = __fix_zero((opbd >> 24) & 3, 4);
+
+	u32 perdv0 = __fix_zero((perd >> 24) & 3, 4);
+
+	/* Resulting clocks */
+	u32 cpu, plb, opb, ebc, vco, tb, uart0, uart1;
+
+	/* PLL's VCO is the source for primary forward ? */
+	if (pllc & 0x40000000) {
+		u32 m;
+
+		/* Feedback path */
+		switch ((pllc >> 24) & 7) {
+		case 0:
+			/* PLLOUTx */
+			m = fbdv;
+			break;
+		case 1:
+			/* CPU */
+			m = fbdv * fwdva * cpudv0;
+			break;
+		case 5:
+			/* PERClk */
+			m = fbdv * fwdva * plb2xdv0 * plbdv0 * opbdv0 * perdv0;
+			break;
+		default:
+			printf("WARNING ! Invalid PLL feedback source !\n");
+			goto bypass;
+		}
+
+		vco = (unsigned int)(sys_clk * m);
+	} else {
+bypass:
+		/* Bypass system PLL */
+		vco = 0;
+	}
+
+	/* CPU = VCO / ( FWDVA x CPUDV0) */
+	cpu = vco / (fwdva * cpudv0);
+	/* PLB = VCO / ( FWDVA x PLB2XDV0 x PLBDV0) */
+	plb = vco / (fwdva * plb2xdv0 * plbdv0);
+	/* OPB = PLB / OPBDV0 */
+	opb = plb / opbdv0;
+	/* EBC = OPB / PERDV0 */
+	ebc = opb / perdv0;
+
+	tb = cpu;
+	uart0 = uart1 = uart_clk;
+
+	dt_fixup_cpu_clocks(cpu, tb, 0);
+	dt_fixup_clock("/plb", plb);
+	dt_fixup_clock("/plb/opb", opb);
+	dt_fixup_clock("/plb/opb/ebc", ebc);
+	dt_fixup_clock("/plb/opb/serial@ef600200", uart0);
+	dt_fixup_clock("/plb/opb/serial@ef600300", uart1);
+}
diff --git a/arch/powerpc/boot/4xx.h b/arch/powerpc/boot/4xx.h
index 2606e64..7dc5d45 100644
--- a/arch/powerpc/boot/4xx.h
+++ b/arch/powerpc/boot/4xx.h
@@ -21,6 +21,7 @@ void ibm4xx_fixup_ebc_ranges(const char *ebc);
 
 void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
 void ibm405ep_fixup_clocks(unsigned int sys_clk);
+void ibm405ex_fixup_clocks(unsigned int sys_clk, unsigned int uart_clk);
 void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk);
 void ibm440ep_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk,
 			   unsigned int tmr_clk);
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 9ae7b7e..7bfc8ad 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -39,6 +39,7 @@ DTS_FLAGS	?= -p 1024
 
 $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405
 $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
+$(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405
 $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
 $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
 $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
@@ -67,7 +68,7 @@ src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \
 		cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
 		fsl-soc.c mpc8xx.c pq2.c
 src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
-		cuboot-ebony.c treeboot-ebony.c prpmc2800.c \
+		cuboot-ebony.c cuboot-hotfoot.c treeboot-ebony.c prpmc2800.c \
 		ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
 		cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c \
 		cuboot-bamboo.c cuboot-mpc7448hpc2.c cuboot-taishan.c \
@@ -75,7 +76,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c
 		cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \
 		cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
 		virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \
-		cuboot-acadia.c cuboot-amigaone.c
+		cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 
 src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -190,6 +191,7 @@ image-$(CONFIG_DEFAULT_UIMAGE)		+= uImage
 
 # Board ports in arch/powerpc/platform/40x/Kconfig
 image-$(CONFIG_EP405)			+= dtbImage.ep405
+image-$(CONFIG_HOTFOOT)			+= cuImage.hotfoot
 image-$(CONFIG_WALNUT)			+= treeImage.walnut
 image-$(CONFIG_ACADIA)			+= cuImage.acadia
 
diff --git a/arch/powerpc/boot/cuboot-hotfoot.c b/arch/powerpc/boot/cuboot-hotfoot.c
new file mode 100644
index 0000000..8f697b9
--- /dev/null
+++ b/arch/powerpc/boot/cuboot-hotfoot.c
@@ -0,0 +1,142 @@
+/*
+ * Old U-boot compatibility for Esteem 195E Hotfoot CPU Board
+ *
+ * Author: Solomon Peachy <solomon@linux-wlan.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 "ops.h"
+#include "stdio.h"
+#include "reg.h"
+#include "dcr.h"
+#include "4xx.h"
+#include "cuboot.h"
+
+#define TARGET_4xx
+#define TARGET_HOTFOOT
+
+#include "ppcboot-hotfoot.h"
+
+static bd_t bd;
+
+#define NUM_REGS 3
+
+static void hotfoot_fixups(void)
+{
+	u32 uart = mfdcr(DCRN_CPC0_UCR) & 0x7f;
+
+	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); 
+
+	dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_procfreq, 0);
+	dt_fixup_clock("/plb", bd.bi_plb_busfreq);
+	dt_fixup_clock("/plb/opb", bd.bi_opbfreq);
+	dt_fixup_clock("/plb/ebc", bd.bi_pci_busfreq);
+	dt_fixup_clock("/plb/opb/serial@ef600300", bd.bi_procfreq / uart); 
+	dt_fixup_clock("/plb/opb/serial@ef600400", bd.bi_procfreq / uart); 
+	
+	dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+	dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
+
+	/* Is this a single eth/serial board? */
+	if ((bd.bi_enet1addr[0] == 0) && 
+	    (bd.bi_enet1addr[1] == 0) &&
+	    (bd.bi_enet1addr[2] == 0) &&
+	    (bd.bi_enet1addr[3] == 0) &&
+	    (bd.bi_enet1addr[4] == 0) &&
+	    (bd.bi_enet1addr[5] == 0)) {
+		void *devp;
+
+		printf("Trimming devtree for single serial/eth board\n");
+
+		devp = finddevice("/plb/opb/serial@ef600300");
+		if (!devp)
+			fatal("Can't find node for /plb/opb/serial@ef600300");
+		del_node(devp);
+
+		devp = finddevice("/plb/opb/ethernet@ef600900");
+		if (!devp)
+			fatal("Can't find node for /plb/opb/ethernet@ef600900");
+		del_node(devp);
+	}
+
+	ibm4xx_quiesce_eth((u32 *)0xef600800, (u32 *)0xef600900);
+
+	/* Fix up flash size in fdt for 4M boards. */
+	if (bd.bi_flashsize < 0x800000) {
+		u32 regs[NUM_REGS];
+		void *devp = finddevice("/plb/ebc/nor_flash@0");
+		if (!devp)
+			fatal("Can't find FDT node for nor_flash!??");
+
+		printf("Fixing devtree for 4M Flash\n");
+		
+		/* First fix up the base addresse */
+		getprop(devp, "reg", regs, sizeof(regs));
+		regs[0] = 0;
+		regs[1] = 0xffc00000;
+		regs[2] = 0x00400000;
+		setprop(devp, "reg", regs, sizeof(regs));
+		
+		/* Then the offsets */
+		devp = finddevice("/plb/ebc/nor_flash@0/partition@0");
+		if (!devp)
+			fatal("Can't find FDT node for partition@0");
+		getprop(devp, "reg", regs, 2*sizeof(u32));
+		regs[0] -= 0x400000;
+		setprop(devp, "reg", regs,  2*sizeof(u32));
+
+		devp = finddevice("/plb/ebc/nor_flash@0/partition@1");
+		if (!devp)
+			fatal("Can't find FDT node for partition@1");
+		getprop(devp, "reg", regs, 2*sizeof(u32));
+		regs[0] -= 0x400000;
+		setprop(devp, "reg", regs,  2*sizeof(u32));
+
+		devp = finddevice("/plb/ebc/nor_flash@0/partition@2");
+		if (!devp)
+			fatal("Can't find FDT node for partition@2");
+		getprop(devp, "reg", regs, 2*sizeof(u32));
+		regs[0] -= 0x400000;
+		setprop(devp, "reg", regs,  2*sizeof(u32));
+
+		devp = finddevice("/plb/ebc/nor_flash@0/partition@3");
+		if (!devp)
+			fatal("Can't find FDT node for partition@3");
+		getprop(devp, "reg", regs, 2*sizeof(u32));
+		regs[0] -= 0x400000;
+		setprop(devp, "reg", regs,  2*sizeof(u32));
+
+		devp = finddevice("/plb/ebc/nor_flash@0/partition@4");
+		if (!devp)
+			fatal("Can't find FDT node for partition@4");
+		getprop(devp, "reg", regs, 2*sizeof(u32));
+		regs[0] -= 0x400000;
+		setprop(devp, "reg", regs,  2*sizeof(u32));
+
+		devp = finddevice("/plb/ebc/nor_flash@0/partition@6");
+		if (!devp)
+			fatal("Can't find FDT node for partition@6");
+		getprop(devp, "reg", regs, 2*sizeof(u32));
+		regs[0] -= 0x400000;
+		setprop(devp, "reg", regs,  2*sizeof(u32));
+
+		/* Delete the FeatFS node */
+		devp = finddevice("/plb/ebc/nor_flash@0/partition@5");
+		if (!devp)
+			fatal("Can't find FDT node for partition@5");
+		del_node(devp);
+	}
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+		   unsigned long r6, unsigned long r7)
+{
+	CUBOOT_INIT();
+	platform_ops.fixups = hotfoot_fixups;
+        platform_ops.exit = ibm40x_dbcr_reset;
+	fdt_init(_dtb_start);
+	serial_console_init();
+}
diff --git a/arch/powerpc/boot/cuboot-kilauea.c b/arch/powerpc/boot/cuboot-kilauea.c
new file mode 100644
index 0000000..80cdad6
--- /dev/null
+++ b/arch/powerpc/boot/cuboot-kilauea.c
@@ -0,0 +1,49 @@
+/*
+ * Old U-boot compatibility for PPC405EX. This image is already included
+ * a dtb.
+ *
+ * Author: Tiejun Chen <tiejun.chen@windriver.com>
+ *
+ * Copyright (C) 2009 Wind River Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "io.h"
+#include "dcr.h"
+#include "stdio.h"
+#include "4xx.h"
+#include "44x.h"
+#include "cuboot.h"
+
+#define TARGET_4xx
+#define TARGET_44x
+#include "ppcboot.h"
+
+#define KILAUEA_SYS_EXT_SERIAL_CLOCK     11059200        /* ext. 11.059MHz clk */
+
+static bd_t bd;
+
+static void kilauea_fixups(void)
+{
+	unsigned long sysclk = 33333333;
+
+	ibm405ex_fixup_clocks(sysclk, KILAUEA_SYS_EXT_SERIAL_CLOCK);
+	dt_fixup_memory(bd.bi_memstart, bd.bi_memsize);
+	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
+	dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr);
+	dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr);
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+		unsigned long r6, unsigned long r7)
+{
+	CUBOOT_INIT();
+	platform_ops.fixups = kilauea_fixups;
+	platform_ops.exit = ibm40x_dbcr_reset;
+	fdt_init(_dtb_start);
+	serial_console_init();
+}
diff --git a/arch/powerpc/boot/dcr.h b/arch/powerpc/boot/dcr.h
index 95b9f53..645a7c9 100644
--- a/arch/powerpc/boot/dcr.h
+++ b/arch/powerpc/boot/dcr.h
@@ -153,9 +153,7 @@ static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR,
 #define DCRN_CPC0_PLLMR1  0xf4
 #define DCRN_CPC0_UCR     0xf5
 
-/* 440GX Clock control etc */
-
-
+/* 440GX/405EX Clock Control reg */
 #define DCRN_CPR0_CLKUPD				0x020
 #define DCRN_CPR0_PLLC					0x040
 #define DCRN_CPR0_PLLD					0x060
diff --git a/arch/powerpc/boot/dts/arches.dts b/arch/powerpc/boot/dts/arches.dts
index d9113b1..414ef8b 100644
--- a/arch/powerpc/boot/dts/arches.dts
+++ b/arch/powerpc/boot/dts/arches.dts
@@ -124,6 +124,16 @@
 		dcr-reg = <0x00c 0x002>;
 	};
 
+	L2C0: l2c {
+		compatible = "ibm,l2-cache-460gt", "ibm,l2-cache";
+		dcr-reg = <0x020 0x008		/* Internal SRAM DCR's */
+			   0x030 0x008>;	/* L2 cache DCR's */
+		cache-line-size = <32>;		/* 32 bytes */
+		cache-size = <262144>;		/* L2, 256K */
+		interrupt-parent = <&UIC1>;
+		interrupts = <11 1>;
+	};
+
 	plb {
 		compatible = "ibm,plb-460gt", "ibm,plb4";
 		#address-cells = <2>;
@@ -168,6 +178,38 @@
 				/* ranges property is supplied by U-Boot */
 				interrupts = <0x6 0x4>;
 				interrupt-parent = <&UIC1>;
+
+				nor_flash@0,0 {
+					compatible = "amd,s29gl256n", "cfi-flash";
+					bank-width = <2>;
+					reg = <0x00000000 0x00000000 0x02000000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+					partition@0 {
+						label = "kernel";
+						reg = <0x00000000 0x001e0000>;
+					};
+					partition@1e0000 {
+						label = "dtb";
+						reg = <0x001e0000 0x00020000>;
+					};
+					partition@200000 {
+						label = "root";
+						reg = <0x00200000 0x00200000>;
+					};
+					partition@400000 {
+						label = "user";
+						reg = <0x00400000 0x01b60000>;
+					};
+					partition@1f60000 {
+						label = "env";
+						reg = <0x01f60000 0x00040000>;
+					};
+					partition@1fa0000 {
+						label = "u-boot";
+						reg = <0x01fa0000 0x00060000>;
+					};
+				};
 			};
 
 			UART0: serial@ef600300 {
@@ -186,6 +228,14 @@
 				reg = <0xef600700 0x00000014>;
 				interrupt-parent = <&UIC0>;
 				interrupts = <0x2 0x4>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				sttm@4a {
+					compatible = "ad,ad7414";
+					reg = <0x4a>;
+					interrupt-parent = <&UIC1>;
+					interrupts = <0x0 0x8>;
+				};
 			};
 
 			IIC1: i2c@ef600800 {
diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts
index 5fd1ad0..c920170 100644
--- a/arch/powerpc/boot/dts/canyonlands.dts
+++ b/arch/powerpc/boot/dts/canyonlands.dts
@@ -1,7 +1,7 @@
 /*
  * Device Tree Source for AMCC Canyonlands (460EX)
  *
- * Copyright 2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
+ * Copyright 2008-2009 DENX Software Engineering, Stefan Roese <sr@denx.de>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without
@@ -149,19 +149,19 @@
 					/*RXDE*/  0x5 0x4>;
 		};
 
-                USB0: ehci@bffd0400 {
-                        compatible = "ibm,usb-ehci-460ex", "usb-ehci";
-                        interrupt-parent = <&UIC2>;
-                        interrupts = <0x1d 4>;
-                        reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>;
-                };
+		USB0: ehci@bffd0400 {
+			compatible = "ibm,usb-ehci-460ex", "usb-ehci";
+			interrupt-parent = <&UIC2>;
+			interrupts = <0x1d 4>;
+			reg = <4 0xbffd0400 0x90 4 0xbffd0490 0x70>;
+		};
 
-                USB1: usb@bffd0000 {
-                        compatible = "ohci-le";
-                        reg = <4 0xbffd0000 0x60>;
-                        interrupt-parent = <&UIC2>;
-                        interrupts = <0x1e 4>;
-                };
+		USB1: usb@bffd0000 {
+			compatible = "ohci-le";
+			reg = <4 0xbffd0000 0x60>;
+			interrupt-parent = <&UIC2>;
+			interrupts = <0x1e 4>;
+		};
 
 		POB0: opb {
 			compatible = "ibm,opb-460ex", "ibm,opb";
@@ -215,6 +215,29 @@
 						reg = <0x03fa0000 0x00060000>;
 					};
 				};
+
+				ndfc@3,0 {
+					compatible = "ibm,ndfc";
+					reg = <0x00000003 0x00000000 0x00002000>;
+					ccr = <0x00001000>;
+					bank-settings = <0x80002222>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					nand {
+						#address-cells = <1>;
+						#size-cells = <1>;
+
+						partition@0 {
+							label = "u-boot";
+							reg = <0x00000000 0x00100000>;
+						};
+						partition@100000 {
+							label = "user";
+							reg = <0x00000000 0x03f00000>;
+						};
+					};
+				};
 			};
 
 			UART0: serial@ef600300 {
diff --git a/arch/powerpc/boot/dts/eiger.dts b/arch/powerpc/boot/dts/eiger.dts
new file mode 100644
index 0000000..c4a934f
--- /dev/null
+++ b/arch/powerpc/boot/dts/eiger.dts
@@ -0,0 +1,421 @@
+/*
+ * Device Tree Source for AMCC (AppliedMicro) Eiger(460SX)
+ *
+ * Copyright 2009 AMCC (AppliedMicro) <ttnguyen@amcc.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <1>;
+	model = "amcc,eiger";
+	compatible = "amcc,eiger";
+	dcr-parent = <&{/cpus/cpu@0}>;
+
+	aliases {
+		ethernet0 = &EMAC0;
+		ethernet1 = &EMAC1;
+		ethernet2 = &EMAC2;
+		ethernet3 = &EMAC3;
+		serial0 = &UART0;
+		serial1 = &UART1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			model = "PowerPC,460SX";
+			reg = <0x00000000>;
+			clock-frequency = <0>; /* Filled in by U-Boot */
+			timebase-frequency = <0>; /* Filled in by U-Boot */
+			i-cache-line-size = <32>;
+			d-cache-line-size = <32>;
+			i-cache-size = <32768>;
+			d-cache-size = <32768>;
+			dcr-controller;
+			dcr-access-method = "native";
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x00000000>; /* Filled in by U-Boot */
+	};
+
+	UIC0: interrupt-controller0 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <0>;
+		dcr-reg = <0x0c0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+	};
+
+	UIC1: interrupt-controller1 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <1>;
+		dcr-reg = <0x0d0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	UIC2: interrupt-controller2 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <2>;
+		dcr-reg = <0x0e0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0xa 0x4 0xb 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	UIC3: interrupt-controller3 {
+		compatible = "ibm,uic-460sx","ibm,uic";
+		interrupt-controller;
+		cell-index = <3>;
+		dcr-reg = <0x0f0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+		interrupts = <0x10 0x4 0x11 0x4>; /* cascade */
+		interrupt-parent = <&UIC0>;
+	};
+
+	SDR0: sdr {
+		compatible = "ibm,sdr-460sx";
+		dcr-reg = <0x00e 0x002>;
+	};
+
+	CPR0: cpr {
+		compatible = "ibm,cpr-460sx";
+		dcr-reg = <0x00c 0x002>;
+	};
+
+	plb {
+		compatible = "ibm,plb-460sx", "ibm,plb4";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges;
+		clock-frequency = <0>; /* Filled in by U-Boot */
+
+		SDRAM0: sdram {
+			compatible = "ibm,sdram-460sx", "ibm,sdram-405gp";
+			dcr-reg = <0x010 0x002>;
+		};
+
+		MAL0: mcmal {
+			compatible = "ibm,mcmal-460sx", "ibm,mcmal2";
+			dcr-reg = <0x180 0x62>;
+			num-tx-chans = <4>;
+			num-rx-chans = <32>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			interrupt-parent = <&UIC1>;
+			interrupts = <	/*TXEOB*/ 0x6 0x4
+					/*RXEOB*/ 0x7 0x4
+					/*SERR*/  0x1 0x4
+					/*TXDE*/  0x2 0x4
+					/*RXDE*/  0x3 0x4
+					/*COAL TX0*/ 0x18 0x2
+					/*COAL TX1*/ 0x19 0x2
+					/*COAL TX2*/ 0x1a 0x2
+					/*COAL TX3*/ 0x1b 0x2
+					/*COAL RX0*/ 0x1c 0x2
+					/*COAL RX1*/ 0x1d 0x2
+					/*COAL RX2*/ 0x1e 0x2
+					/*COAL RX3*/ 0x1f 0x2>;
+		};
+
+		POB0: opb {
+			compatible = "ibm,opb-460sx", "ibm,opb";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0xb0000000 0x00000004 0xb0000000 0x50000000>;
+			clock-frequency = <0>; /* Filled in by U-Boot */
+
+			EBC0: ebc {
+				compatible = "ibm,ebc-460sx", "ibm,ebc";
+				dcr-reg = <0x012 0x002>;
+				#address-cells = <2>;
+				#size-cells = <1>;
+				clock-frequency = <0>; /* Filled in by U-Boot */
+				/* ranges property is supplied by U-Boot */
+				interrupts = <0x6 0x4>;
+				interrupt-parent = <&UIC1>;
+
+				nor_flash@0,0 {
+					compatible = "amd,s29gl512n", "cfi-flash";
+					bank-width = <2>;
+					/* reg property is supplied in by U-Boot */
+					#address-cells = <1>;
+					#size-cells = <1>;
+					partition@0 {
+						label = "kernel";
+						reg = <0x00000000 0x001e0000>;
+					};
+					partition@1e0000 {
+						label = "dtb";
+						reg = <0x001e0000 0x00020000>;
+					};
+					partition@200000 {
+						label = "ramdisk";
+						reg = <0x00200000 0x01400000>;
+					};
+					partition@1600000 {
+						label = "jffs2";
+						reg = <0x01600000 0x00400000>;
+					};
+					partition@1a00000 {
+						label = "user";
+						reg = <0x01a00000 0x02560000>;
+					};
+					partition@3f60000 {
+						label = "env";
+						reg = <0x03f60000 0x00040000>;
+					};
+					partition@3fa0000 {
+						label = "u-boot";
+						reg = <0x03fa0000 0x00060000>;
+					};
+				};
+
+				ndfc@1,0 {
+					compatible = "ibm,ndfc";
+					/* reg property is supplied by U-boot */
+					ccr = <0x00003000>;
+					bank-settings = <0x80002222>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					nand {
+						#address-cells = <1>;
+						#size-cells = <1>;
+						partition@0 {
+							label = "uboot";
+							reg = <0x00000000 0x00200000>;
+						};
+						partition@200000 {
+							label = "uboot-environment";
+							reg = <0x00200000 0x00100000>;
+						};
+						partition@300000 {
+							label = "linux";
+							reg = <0x00300000 0x00300000>;
+						};
+						partition@600000 {
+							label = "root-file-system";
+							reg = <0x00600000 0x01900000>;
+						};
+						partition@1f00000 {
+							label = "device-tree";
+							reg = <0x01f00000 0x00020000>;
+						};
+						partition@1f20000 {
+							label = "data";
+							reg = <0x01f20000 0x060E0000>;
+						};
+					};
+				};
+			};
+
+			UART0: serial@ef600200 {
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0xef600200 0x00000008>;
+				virtual-reg = <0xef600200>;
+				clock-frequency = <0>; /* Filled in by U-Boot */
+				current-speed = <0>; /* Filled in by U-Boot */
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x0 0x4>;
+			};
+
+			UART1: serial@ef600300 {
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0xef600300 0x00000008>;
+				virtual-reg = <0xef600300>;
+				clock-frequency = <0>; /* Filled in by U-Boot */
+				current-speed = <0>; /* Filled in by U-Boot */
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x1 0x4>;
+			};
+
+			IIC0: i2c@ef600400 {
+				compatible = "ibm,iic-460sx", "ibm,iic";
+				reg = <0xef600400 0x00000014>;
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x2 0x4>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				index = <0>;
+			};
+
+			IIC1: i2c@ef600500 {
+				compatible = "ibm,iic-460sx", "ibm,iic";
+				reg = <0xef600500 0x00000014>;
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x3 0x4>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				index = <1>;
+			};
+
+			RGMII0: emac-rgmii@ef600900 {
+				compatible = "ibm,rgmii-460sx", "ibm,rgmii";
+				reg = <0xef600900 0x00000008>;
+				has-mdio;
+			};
+
+			RGMII1: emac-rgmii@ef600920 {
+				compatible = "ibm,rgmii-460sx", "ibm,rgmii";
+				reg = <0xef600920 0x00000008>;
+				has-mdio;
+			};
+
+			TAH0: emac-tah@ef600e50 {
+				compatible = "ibm,tah-460sx", "ibm,tah";
+				reg = <0xef600e50 0x00000030>;
+			};
+
+			TAH1: emac-tah@ef600f50 {
+				compatible = "ibm,tah-460sx", "ibm,tah";
+				reg = <0xef600f50 0x00000030>;
+			};
+
+			EMAC0: ethernet@ef600a00 {
+				device_type = "network";
+				compatible = "ibm,emac-460sx", "ibm,emac4";
+				interrupt-parent = <&EMAC0>;
+				interrupts = <0x0 0x1>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = </*Status*/ 0x0 &UIC0 0x13 0x4
+						 /*Wake*/   0x1 &UIC2 0x1d 0x4>;
+				reg = <0xef600a00 0x00000070>;
+				local-mac-address = [000000000000]; /* Filled in by U-Boot */
+				mal-device = <&MAL0>;
+				mal-tx-channel = <0>;
+				mal-rx-channel = <0>;
+				cell-index = <0>;
+				max-frame-size = <9000>;
+				rx-fifo-size = <4096>;
+				tx-fifo-size = <2048>;
+				phy-mode = "rgmii";
+				phy-map = <0x00000000>;
+				rgmii-device = <&RGMII0>;
+				rgmii-channel = <0>;
+				tah-device = <&TAH0>;
+				tah-channel = <0>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
+			};
+
+			EMAC1: ethernet@ef600b00 {
+				device_type = "network";
+				compatible = "ibm,emac-460sx", "ibm,emac4";
+				interrupt-parent = <&EMAC1>;
+				interrupts = <0x0 0x1>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = </*Status*/ 0x0 &UIC0 0x14 0x4
+						 /*Wake*/   0x1 &UIC2 0x1d 0x4>;
+				reg = <0xef600b00 0x00000070>;
+				local-mac-address = [000000000000]; /* Filled in by U-Boot */
+				mal-device = <&MAL0>;
+				mal-tx-channel = <1>;
+				mal-rx-channel = <8>;
+				cell-index = <1>;
+				max-frame-size = <9000>;
+				rx-fifo-size = <4096>;
+				tx-fifo-size = <2048>;
+				phy-mode = "rgmii";
+				phy-map = <0x00000000>;
+				rgmii-device = <&RGMII0>;
+				rgmii-channel = <1>;
+				tah-device = <&TAH1>;
+				tah-channel = <1>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
+				mdio-device = <&EMAC0>;
+			};
+
+			EMAC2: ethernet@ef600c00 {
+				device_type = "network";
+				compatible = "ibm,emac-460sx", "ibm,emac4";
+				interrupt-parent = <&EMAC2>;
+				interrupts = <0x0 0x1>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = </*Status*/ 0x0 &UIC0 0x15 0x4
+						 /*Wake*/   0x1 &UIC2 0x1d 0x4>;
+				reg = <0xef600c00 0x00000070>;
+				local-mac-address = [000000000000]; /* Filled in by U-Boot */
+				mal-device = <&MAL0>;
+				mal-tx-channel = <2>;
+				mal-rx-channel = <16>;
+				cell-index = <2>;
+				max-frame-size = <9000>;
+				rx-fifo-size = <4096>;
+				tx-fifo-size = <2048>;
+				phy-mode = "rgmii";
+				phy-map = <0x00000000>;
+				rgmii-device = <&RGMII1>;
+				rgmii-channel = <0>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
+				mdio-device = <&EMAC0>;
+			};
+
+			EMAC3: ethernet@ef600d00 {
+				device_type = "network";
+				compatible = "ibm,emac-460sx", "ibm,emac4";
+				interrupt-parent = <&EMAC3>;
+				interrupts = <0x0 0x1>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = </*Status*/ 0x0 &UIC0 0x16 0x4
+						 /*Wake*/   0x1 &UIC2 0x1d 0x4>;
+				reg = <0xef600d00 0x00000070>;
+				local-mac-address = [000000000000]; /* Filled in by U-Boot */
+				mal-device = <&MAL0>;
+				mal-tx-channel = <3>;
+				mal-rx-channel = <24>;
+				cell-index = <3>;
+				max-frame-size = <9000>;
+				rx-fifo-size = <4096>;
+				tx-fifo-size = <2048>;
+				phy-mode = "rgmii";
+				phy-map = <0x00000000>;
+				rgmii-device = <&RGMII1>;
+				rgmii-channel = <1>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
+				mdio-device = <&EMAC0>;
+			};
+		};
+
+	};
+	chosen {
+		linux,stdout-path = "/plb/opb/serial@ef600200";
+	};
+
+};
diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts
index 0f4c9ec..2107d3c 100644
--- a/arch/powerpc/boot/dts/gef_sbc310.dts
+++ b/arch/powerpc/boot/dts/gef_sbc310.dts
@@ -83,34 +83,34 @@
 
 		/* flash@0,0 is a mirror of part of the memory in flash@1,0
 		flash@0,0 {
-			compatible = "cfi-flash";
-			reg = <0 0 0x01000000>;
+			compatible = "gef,sbc310-firmware-mirror", "cfi-flash";
+			reg = <0x0 0x0 0x01000000>;
 			bank-width = <2>;
 			device-width = <2>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			partition@0 {
 				label = "firmware";
-				reg = <0x00000000 0x01000000>;
+				reg = <0x0 0x01000000>;
 				read-only;
 			};
 		};
 		*/
 
 		flash@1,0 {
-			compatible = "cfi-flash";
-			reg = <1 0 0x8000000>;
+			compatible = "gef,sbc310-paged-flash", "cfi-flash";
+			reg = <0x1 0x0 0x8000000>;
 			bank-width = <2>;
 			device-width = <2>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			partition@0 {
 				label = "user";
-				reg = <0x00000000 0x07800000>;
+				reg = <0x0 0x7800000>;
 			};
 			partition@7800000 {
 				label = "firmware";
-				reg = <0x07800000 0x00800000>;
+				reg = <0x7800000 0x800000>;
 				read-only;
 			};
 		};
@@ -121,18 +121,16 @@
 		};
 
 		wdt@4,2000 {
-			#interrupt-cells = <2>;
-			device_type = "watchdog";
-			compatible = "gef,fpga-wdt";
+			compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
+				"gef,fpga-wdt";
 			reg = <0x4 0x2000 0x8>;
 			interrupts = <0x1a 0x4>;
 			interrupt-parent = <&gef_pic>;
 		};
 /*
 		wdt@4,2010 {
-			#interrupt-cells = <2>;
-			device_type = "watchdog";
-			compatible = "gef,fpga-wdt";
+			compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00",
+				"gef,fpga-wdt";
 			reg = <0x4 0x2010 0x8>;
 			interrupts = <0x1b 0x4>;
 			interrupt-parent = <&gef_pic>;
@@ -141,7 +139,7 @@
 		gef_pic: pic@4,4000 {
 			#interrupt-cells = <1>;
 			interrupt-controller;
-			compatible = "gef,fpga-pic";
+			compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic";
 			reg = <0x4 0x4000 0x20>;
 			interrupts = <0x8
 				      0x9>;
@@ -161,7 +159,7 @@
 		#size-cells = <1>;
 		#interrupt-cells = <2>;
 		device_type = "soc";
-		compatible = "simple-bus";
+		compatible = "fsl,mpc8641-soc", "simple-bus";
 		ranges = <0x0 0xfef00000 0x00100000>;
 		bus-frequency = <33333333>;
 
@@ -376,4 +374,40 @@
 				  0x0 0x00400000>;
 		};
 	};
+
+	pci1: pcie@fef09000 {
+		compatible = "fsl,mpc8641-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xfef09000 0x1000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000
+			  0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <0x19 0x2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			0x0000 0x0 0x0 0x1 &mpic 0x4 0x2
+			0x0000 0x0 0x0 0x2 &mpic 0x5 0x2
+			0x0000 0x0 0x0 0x3 &mpic 0x6 0x2
+			0x0000 0x0 0x0 0x4 &mpic 0x7 0x2
+			>;
+
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0x0 0xc0000000
+				  0x02000000 0x0 0xc0000000
+				  0x0 0x20000000
+
+				  0x01000000 0x0 0x00000000
+				  0x01000000 0x0 0x00000000
+				  0x0 0x00400000>;
+		};
+	};
 };
diff --git a/arch/powerpc/boot/dts/hotfoot.dts b/arch/powerpc/boot/dts/hotfoot.dts
new file mode 100644
index 0000000..cad9c38
--- /dev/null
+++ b/arch/powerpc/boot/dts/hotfoot.dts
@@ -0,0 +1,294 @@
+/*
+ * Device Tree Source for ESTeem 195E Hotfoot
+ *
+ * Copyright 2009 AbsoluteValue Systems <solomon@linux-wlan.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	model = "est,hotfoot";
+	compatible = "est,hotfoot";
+	dcr-parent = <&{/cpus/cpu@0}>;
+
+	aliases {
+		ethernet0 = &EMAC0;
+		ethernet1 = &EMAC1;
+		serial0 = &UART0;
+		serial1 = &UART1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			model = "PowerPC,405EP";
+			reg = <0x00000000>;
+			clock-frequency = <0>; /* Filled in by zImage */
+			timebase-frequency = <0>; /* Filled in by zImage */
+			i-cache-line-size = <0x20>;
+			d-cache-line-size = <0x20>;
+			i-cache-size = <0x4000>;
+			d-cache-size = <0x4000>;
+			dcr-controller;
+			dcr-access-method = "native";
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000>; /* Filled in by zImage */
+	};
+
+	UIC0: interrupt-controller {
+		compatible = "ibm,uic";
+		interrupt-controller;
+		cell-index = <0>;
+		dcr-reg = <0x0c0 0x009>;
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#interrupt-cells = <2>;
+	};
+
+	plb {
+		compatible = "ibm,plb3";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		clock-frequency = <0>; /* Filled in by zImage */
+
+		SDRAM0: memory-controller {
+			compatible = "ibm,sdram-405ep";
+			dcr-reg = <0x010 0x002>;
+		};
+
+		MAL: mcmal {
+			compatible = "ibm,mcmal-405ep", "ibm,mcmal";
+			dcr-reg = <0x180 0x062>;
+			num-tx-chans = <4>;
+			num-rx-chans = <2>;
+			interrupt-parent = <&UIC0>;
+			interrupts = <
+				0xb 0x4 /* TXEOB */
+				0xc 0x4 /* RXEOB */
+				0xa 0x4 /* SERR */
+				0xd 0x4 /* TXDE */
+				0xe 0x4 /* RXDE */>;
+		};
+
+		POB0: opb {
+			compatible = "ibm,opb-405ep", "ibm,opb";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0xef600000 0xef600000 0x00a00000>;
+			dcr-reg = <0x0a0 0x005>;
+			clock-frequency = <0>; /* Filled in by zImage */
+
+			/* Hotfoot has UART0/UART1 swapped */
+
+			UART0: serial@ef600400 {
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0xef600400 0x00000008>;
+				virtual-reg = <0xef600400>;
+				clock-frequency = <0>; /* Filled in by zImage */
+				current-speed = <0x9600>;
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x1 0x4>;
+			};
+
+			UART1: serial@ef600300 {
+				device_type = "serial";
+				compatible = "ns16550";
+				reg = <0xef600300 0x00000008>;
+				virtual-reg = <0xef600300>;
+				clock-frequency = <0>; /* Filled in by zImage */
+				current-speed = <0x9600>;
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x0 0x4>;
+			};
+
+			IIC: i2c@ef600500 {
+				compatible = "ibm,iic-405ep", "ibm,iic";
+				reg = <0xef600500 0x00000011>;
+				interrupt-parent = <&UIC0>;
+				interrupts = <0x2 0x4>;
+
+				rtc@68 {
+					/* Actually a DS1339 */
+					compatible = "dallas,ds1307";
+					reg = <0x68>;
+				};
+
+				temp@4a {
+					/* Not present on all boards */
+					compatible = "national,lm75";
+					reg = <0x4a>;
+				};
+			};
+
+			GPIO: gpio@ef600700 {
+				#gpio-cells = <2>;
+				compatible = "ibm,ppc4xx-gpio";
+				reg = <0xef600700 0x00000020>;
+				gpio-controller;
+			};
+
+			gpio-leds {
+				compatible = "gpio-leds";
+				status {
+					label = "Status";
+					gpios = <&GPIO 1 0>;
+				};
+				radiorx {
+					label = "Rx";
+					gpios = <&GPIO 0xe 0>;
+				};
+			};
+
+			EMAC0: ethernet@ef600800 {
+				linux,network-index = <0x0>;
+				device_type = "network";
+				compatible = "ibm,emac-405ep", "ibm,emac";
+				interrupt-parent = <&UIC0>;
+				interrupts = <
+					0xf 0x4 /* Ethernet */
+					0x9 0x4 /* Ethernet Wake Up */>;
+				local-mac-address = [000000000000]; /* Filled in by zImage */
+				reg = <0xef600800 0x00000070>;
+				mal-device = <&MAL>;
+				mal-tx-channel = <0>;
+				mal-rx-channel = <0>;
+				cell-index = <0>;
+				max-frame-size = <0x5dc>;
+				rx-fifo-size = <0x1000>;
+				tx-fifo-size = <0x800>;
+				phy-mode = "mii";
+				phy-map = <0x00000000>;
+			};
+
+			EMAC1: ethernet@ef600900 {
+				linux,network-index = <0x1>;
+				device_type = "network";
+				compatible = "ibm,emac-405ep", "ibm,emac";
+				interrupt-parent = <&UIC0>;
+				interrupts = <
+					0x11 0x4 /* Ethernet */
+					0x9 0x4 /* Ethernet Wake Up */>;
+				local-mac-address = [000000000000]; /* Filled in by zImage */
+				reg = <0xef600900 0x00000070>;
+				mal-device = <&MAL>;
+				mal-tx-channel = <2>;
+				mal-rx-channel = <1>;
+				cell-index = <1>;
+				max-frame-size = <0x5dc>;
+				rx-fifo-size = <0x1000>;
+				tx-fifo-size = <0x800>;
+				mdio-device = <&EMAC0>;
+				phy-mode = "mii";
+				phy-map = <0x0000001>;
+			};
+		};
+
+		EBC0: ebc {
+			compatible = "ibm,ebc-405ep", "ibm,ebc";
+			dcr-reg = <0x012 0x002>;
+			#address-cells = <2>;
+			#size-cells = <1>;
+
+			/* The ranges property is supplied by the bootwrapper
+			 * and is based on the firmware's configuration of the
+			 * EBC bridge
+			 */
+			clock-frequency = <0>; /* Filled in by zImage */
+
+			nor_flash@0 {
+				compatible = "cfi-flash";
+				bank-width = <2>;
+				reg = <0x0 0xff800000 0x00800000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				/* This mapping is for the 8M flash
+				   4M flash has all ofssets -= 4M,
+				   and FeatFS partition is not present */
+				partition@0 {
+					label = "Bootloader";
+					reg = <0x7c0000 0x40000>;
+					/* read-only; */
+				};
+				partition@1 {
+					label = "Env_and_Config_Primary";
+					reg = <0x400000 0x10000>;
+				};
+				partition@2 {
+					label = "Kernel";
+					reg = <0x420000 0x100000>;
+				};
+				partition@3 {
+					label = "Filesystem";
+					reg = <0x520000 0x2a0000>;
+				};
+				partition@4 {
+					label = "Env_and_Config_Secondary";
+					reg = <0x410000 0x10000>;
+				};
+				partition@5 {
+					label = "FeatFS";
+					reg = <0x000000 0x400000>;
+				};
+				partition@6 {
+					label = "Bootloader_Env";
+					reg = <0x7d0000 0x10000>;
+				};
+			};
+		};
+
+		PCI0: pci@ec000000 {
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			compatible = "ibm,plb405ep-pci", "ibm,plb-pci";
+			primary;
+			reg = <0xeec00000 0x00000008    /* Config space access */
+				0xeed80000 0x00000004    /* IACK */
+				0xeed80000 0x00000004    /* Special cycle */
+				0xef480000 0x00000040>;  /* Internal registers */
+
+			/* Outbound ranges, one memory and one IO,
+			 * later cannot be changed. Chip supports a second
+			 * IO range but we don't use it for now
+			 */
+			ranges = <0x02000000 0x00000000 0x80000000 0x80000000 0x00000000 0x20000000
+				0x01000000 0x00000000 0x00000000 0xe8000000 0x00000000 0x00010000>;
+
+			/* Inbound 2GB range starting at 0 */
+			dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x80000000>;
+
+			interrupt-parent = <&UIC0>;
+			interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+			interrupt-map = <
+				/* IDSEL 3 -- slot1 (optional) 27/29 A/B IRQ2/4 */
+				0x1800 0x0 0x0 0x1 &UIC0 0x1b 0x8
+				0x1800 0x0 0x0 0x2 &UIC0 0x1d 0x8
+
+				/* IDSEL 4 -- slot0, 26/28 A/B IRQ1/3 */
+				0x2000 0x0 0x0 0x1 &UIC0 0x1a 0x8
+				0x2000 0x0 0x0 0x2 &UIC0 0x1c 0x8
+				>;
+		};
+	};
+
+	chosen {
+		linux,stdout-path = &UART0;
+	};
+};
diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts
index 5e6b08f..c465614 100644
--- a/arch/powerpc/boot/dts/kilauea.dts
+++ b/arch/powerpc/boot/dts/kilauea.dts
@@ -1,7 +1,7 @@
 /*
  * Device Tree Source for AMCC Kilauea (405EX)
  *
- * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
+ * Copyright 2007-2009 DENX Software Engineering, Stefan Roese <sr@denx.de>
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without
@@ -150,7 +150,11 @@
 					#size-cells = <1>;
 					partition@0 {
 						label = "kernel";
-						reg = <0x00000000 0x00200000>;
+						reg = <0x00000000 0x001e0000>;
+					};
+					partition@1e0000 {
+						label = "dtb";
+						reg = <0x001e0000 0x00020000>;
 					};
 					partition@200000 {
 						label = "root";
@@ -169,6 +173,29 @@
 						reg = <0x03fa0000 0x00060000>;
 					};
 				};
+
+				ndfc@1,0 {
+					compatible = "ibm,ndfc";
+					reg = <0x00000001 0x00000000 0x00002000>;
+					ccr = <0x00001000>;
+					bank-settings = <0x80002222>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					nand {
+						#address-cells = <1>;
+						#size-cells = <1>;
+
+						partition@0 {
+							label = "u-boot";
+							reg = <0x00000000 0x00100000>;
+						};
+						partition@100000 {
+							label = "user";
+							reg = <0x00000000 0x03f00000>;
+						};
+					};
+				};
 			};
 
 			UART0: serial@ef600200 {
@@ -198,6 +225,18 @@
 				reg = <0xef600400 0x00000014>;
 				interrupt-parent = <&UIC0>;
 				interrupts = <0x2 0x4>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				rtc@68 {
+					compatible = "dallas,ds1338";
+					reg = <0x68>;
+				};
+
+				dtt@48 {
+					compatible = "dallas,ds1775";
+					reg = <0x48>;
+				};
 			};
 
 			IIC1: i2c@ef600500 {
@@ -207,7 +246,6 @@
 				interrupts = <0x7 0x4>;
 			};
 
-
 			RGMII0: emac-rgmii@ef600b00 {
 				compatible = "ibm,rgmii-405ex", "ibm,rgmii";
 				reg = <0xef600b00 0x00000104>;
diff --git a/arch/powerpc/boot/dts/mgcoge.dts b/arch/powerpc/boot/dts/mgcoge.dts
index 633255a..0ce9664 100644
--- a/arch/powerpc/boot/dts/mgcoge.dts
+++ b/arch/powerpc/boot/dts/mgcoge.dts
@@ -162,6 +162,59 @@
 				fixed-link = <0 0 10 0 0>;
 			};
 
+			i2c@11860 {
+				compatible = "fsl,mpc8272-i2c",
+					     "fsl,cpm2-i2c";
+				reg = <0x11860 0x20 0x8afc 0x2>;
+				interrupts = <1 8>;
+				interrupt-parent = <&PIC>;
+				fsl,cpm-command = <0x29600000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			mdio@10d40 {
+				compatible = "fsl,cpm2-mdio-bitbang";
+				reg = <0x10d00 0x14>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				fsl,mdio-pin = <12>;
+				fsl,mdc-pin = <13>;
+
+				phy0: ethernet-phy@0 {
+					reg = <0x0>;
+				};
+
+				phy1: ethernet-phy@1 {
+					reg = <0x1>;
+				};
+			};
+
+			/* FCC1 management to switch */
+			ethernet@11300 {
+				device_type = "network";
+				compatible = "fsl,cpm2-fcc-enet";
+				reg = <0x11300 0x20 0x8400 0x100 0x11390 0x1>;
+				local-mac-address = [ 00 01 02 03 04 07 ];
+				interrupts = <32 8>;
+				interrupt-parent = <&PIC>;
+				phy-handle = <&phy0>;
+				linux,network-index = <1>;
+				fsl,cpm-command = <0x12000300>;
+			};
+
+			/* FCC2 to redundant core unit over backplane */
+			ethernet@11320 {
+				device_type = "network";
+				compatible = "fsl,cpm2-fcc-enet";
+				reg = <0x11320 0x20 0x8500 0x100 0x113b0 0x1>;
+				local-mac-address = [ 00 01 02 03 04 08 ];
+				interrupts = <33 8>;
+				interrupt-parent = <&PIC>;
+				phy-handle = <&phy1>;
+				linux,network-index = <2>;
+				fsl,cpm-command = <0x16200300>;
+			};
 		};
 
 		PIC: interrupt-controller@10c00 {
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 60f3327..e802ebd 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -173,6 +173,14 @@
 				fsl,cpm-command = <0xce00000>;
 			};
 
+			usb@11b60 {
+				compatible = "fsl,mpc8272-cpm-usb";
+				reg = <0x11b60 0x40 0x8b00 0x100>;
+				interrupts = <11 8>;
+				interrupt-parent = <&PIC>;
+				mode = "peripheral";
+			};
+
 			mdio@10d40 {
 				device_type = "mdio";
 				compatible = "fsl,mpc8272ads-mdio-bitbang",
diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts
index 4f06dbc..28e022a 100644
--- a/arch/powerpc/boot/dts/mpc8377_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts
@@ -174,7 +174,7 @@
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
 				/* Filled in by U-Boot */
-				clock-frequency = <0>;
+				clock-frequency = <111111111>;
 			};
 		};
 
diff --git a/arch/powerpc/boot/dts/mpc8377_wlan.dts b/arch/powerpc/boot/dts/mpc8377_wlan.dts
new file mode 100644
index 0000000..3febc4e
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8377_wlan.dts
@@ -0,0 +1,464 @@
+/*
+ * MPC8377E WLAN Device Tree Source
+ *
+ * Copyright 2007-2009 Freescale Semiconductor Inc.
+ * Copyright 2009 MontaVista Software, 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.
+ */
+
+/dts-v1/;
+
+/ {
+	compatible = "fsl,mpc8377wlan";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8377@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <32768>;
+			i-cache-size = <32768>;
+			timebase-frequency = <0>;
+			bus-frequency = <0>;
+			clock-frequency = <0>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x20000000>;	// 512MB at 0
+	};
+
+	localbus@e0005000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8377-elbc", "fsl,elbc", "simple-bus";
+		reg = <0xe0005000 0x1000>;
+		interrupts = <77 0x8>;
+		interrupt-parent = <&ipic>;
+		ranges = <0x0 0x0 0xfc000000 0x04000000>;
+
+		flash@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x4000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			partition@0 {
+				reg = <0 0x8000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@a0000 {
+				reg = <0xa0000 0x300000>;
+				label = "kernel";
+			};
+
+			partition@3a0000 {
+				reg = <0x3a0000 0x3c60000>;
+				label = "rootfs";
+			};
+		};
+	};
+
+	immr@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "simple-bus";
+		ranges = <0x0 0xe0000000 0x00100000>;
+		reg = <0xe0000000 0x00000200>;
+		bus-frequency = <0>;
+
+		wdt@200 {
+			device_type = "watchdog";
+			compatible = "mpc83xx_wdt";
+			reg = <0x200 0x100>;
+		};
+
+		gpio1: gpio-controller@c00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio";
+			reg = <0xc00 0x100>;
+			interrupts = <74 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
+		gpio2: gpio-controller@d00 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8377-gpio", "fsl,mpc8349-gpio";
+			reg = <0xd00 0x100>;
+			interrupts = <75 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
+		sleep-nexus {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "simple-bus";
+			sleep = <&pmc 0x0c000000>;
+			ranges;
+
+			i2c@3000 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				cell-index = <0>;
+				compatible = "fsl-i2c";
+				reg = <0x3000 0x100>;
+				interrupts = <14 0x8>;
+				interrupt-parent = <&ipic>;
+				dfsrr;
+
+				at24@50 {
+					compatible = "at24,24c256";
+					reg = <0x50>;
+				};
+
+				rtc@68 {
+					compatible = "dallas,ds1339";
+					reg = <0x68>;
+				};
+			};
+
+			sdhci@2e000 {
+				compatible = "fsl,mpc8377-esdhc", "fsl,esdhc";
+				reg = <0x2e000 0x1000>;
+				interrupts = <42 0x8>;
+				interrupt-parent = <&ipic>;
+				clock-frequency = <133333333>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <15 0x8>;
+			interrupt-parent = <&ipic>;
+			dfsrr;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			compatible = "fsl,spi";
+			reg = <0x7000 0x1000>;
+			interrupts = <16 0x8>;
+			interrupt-parent = <&ipic>;
+			mode = "cpu";
+		};
+
+		dma@82a8 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8377-dma", "fsl,elo-dma";
+			reg = <0x82a8 4>;
+			ranges = <0 0x8100 0x1a8>;
+			interrupt-parent = <&ipic>;
+			interrupts = <71 8>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
+				reg = <0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&ipic>;
+				interrupts = <71 8>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&ipic>;
+				interrupts = <71 8>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&ipic>;
+				interrupts = <71 8>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,mpc8377-dma-channel", "fsl,elo-dma-channel";
+				reg = <0x180 0x28>;
+				cell-index = <3>;
+				interrupt-parent = <&ipic>;
+				interrupts = <71 8>;
+			};
+		};
+
+		usb@23000 {
+			compatible = "fsl-usb2-dr";
+			reg = <0x23000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <&ipic>;
+			interrupts = <38 0x8>;
+			phy_type = "ulpi";
+			sleep = <&pmc 0x00c00000>;
+		};
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <32 0x8 33 0x8 34 0x8>;
+			phy-connection-type = "mii";
+			interrupt-parent = <&ipic>;
+			tbi-handle = <&tbi0>;
+			phy-handle = <&phy2>;
+			sleep = <&pmc 0xc0000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy2: ethernet-phy@2 {
+					interrupt-parent = <&ipic>;
+					interrupts = <17 0x8>;
+					reg = <0x2>;
+					device_type = "ethernet-phy";
+				};
+
+				phy3: ethernet-phy@3 {
+					interrupt-parent = <&ipic>;
+					interrupts = <18 0x8>;
+					reg = <0x3>;
+					device_type = "ethernet-phy";
+				};
+
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		enet1: ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <35 0x8 36 0x8 37 0x8>;
+			phy-connection-type = "mii";
+			interrupt-parent = <&ipic>;
+			phy-handle = <&phy3>;
+			tbi-handle = <&tbi1>;
+			sleep = <&pmc 0x30000000>;
+			fsl,magic-packet;
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <9 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <10 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2",
+				     "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <11 0x8>;
+			interrupt-parent = <&ipic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0x9fe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+			sleep = <&pmc 0x03000000>;
+		};
+
+		sata@18000 {
+			compatible = "fsl,mpc8377-sata", "fsl,pq-sata";
+			reg = <0x18000 0x1000>;
+			interrupts = <44 0x8>;
+			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x000000c0>;
+		};
+
+		sata@19000 {
+			compatible = "fsl,mpc8377-sata", "fsl,pq-sata";
+			reg = <0x19000 0x1000>;
+			interrupts = <45 0x8>;
+			interrupt-parent = <&ipic>;
+			sleep = <&pmc 0x00000030>;
+		};
+
+		/* IPIC
+		 * interrupts cell = <intr #, sense>
+		 * sense values match linux IORESOURCE_IRQ_* defines:
+		 * sense == 8: Level, low assertion
+		 * sense == 2: Edge, high-to-low change
+		 */
+		ipic: interrupt-controller@700 {
+			compatible = "fsl,ipic";
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x700 0x100>;
+		};
+
+		pmc: power@b00 {
+			compatible = "fsl,mpc8377-pmc", "fsl,mpc8349-pmc";
+			reg = <0xb00 0x100 0xa00 0x100>;
+			interrupts = <80 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+	};
+
+	pci0: pci@e0008500 {
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+				/* IRQ5 = 21 = 0x15, IRQ6 = 0x16, IRQ7 = 23 = 0x17 */
+
+				/* IDSEL AD14 IRQ6 inta */
+				 0x7000 0x0 0x0 0x1 &ipic 22 0x8
+
+				/* IDSEL AD15 IRQ5 inta */
+				 0x7800 0x0 0x0 0x1 &ipic 21 0x8>;
+		interrupt-parent = <&ipic>;
+		interrupts = <66 0x8>;
+		bus-range = <0 0>;
+		ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000
+		          0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000
+		          0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>;
+		sleep = <&pmc 0x00010000>;
+		clock-frequency = <66666666>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xe0008500 0x100		/* internal registers */
+		       0xe0008300 0x8>;		/* config space access registers */
+		compatible = "fsl,mpc8349-pci";
+		device_type = "pci";
+	};
+
+	pci1: pcie@e0009000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe0009000 0x00001000>;
+		ranges = <0x02000000 0 0xa8000000 0xa8000000 0 0x10000000
+		          0x01000000 0 0x00000000 0xb8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 1 8
+				 0 0 0 2 &ipic 1 8
+				 0 0 0 3 &ipic 1 8
+				 0 0 0 4 &ipic 1 8>;
+		sleep = <&pmc 0x00300000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xa8000000
+				  0x02000000 0 0xa8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
+
+	pci2: pcie@e000a000 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8377-pcie", "fsl,mpc8314-pcie";
+		reg = <0xe000a000 0x00001000>;
+		ranges = <0x02000000 0 0xc8000000 0xc8000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xd8000000 0 0x00800000>;
+		bus-range = <0 255>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <0 0 0 1 &ipic 2 8
+				 0 0 0 2 &ipic 2 8
+				 0 0 0 3 &ipic 2 8
+				 0 0 0 4 &ipic 2 8>;
+		sleep = <&pmc 0x000c0000>;
+		clock-frequency = <0>;
+
+		pcie@0 {
+			#address-cells = <3>;
+			#size-cells = <2>;
+			device_type = "pci";
+			reg = <0 0 0 0 0>;
+			ranges = <0x02000000 0 0xc8000000
+				  0x02000000 0 0xc8000000
+				  0 0x10000000
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00800000>;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts
index aabf343..a11ead8 100644
--- a/arch/powerpc/boot/dts/mpc8378_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts
@@ -174,7 +174,7 @@
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
 				/* Filled in by U-Boot */
-				clock-frequency = <0>;
+				clock-frequency = <111111111>;
 			};
 		};
 
diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts
index 9b1da86..e35dfba 100644
--- a/arch/powerpc/boot/dts/mpc8379_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts
@@ -172,7 +172,7 @@
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
 				/* Filled in by U-Boot */
-				clock-frequency = <0>;
+				clock-frequency = <111111111>;
 			};
 		};
 
diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts
index e781ad2..815cebb 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -14,8 +14,8 @@
 / {
 	model = "fsl,mpc8536ds";
 	compatible = "fsl,mpc8536ds";
-	#address-cells = <1>;
-	#size-cells = <1>;
+	#address-cells = <2>;
+	#size-cells = <2>;
 
 	aliases {
 		ethernet0 = &enet0;
@@ -42,7 +42,7 @@
 
 	memory {
 		device_type = "memory";
-		reg = <00000000 00000000>;	// Filled by U-Boot
+		reg = <0 0 0 0>;	// Filled by U-Boot
 	};
 
 	soc@ffe00000 {
@@ -50,7 +50,7 @@
 		#size-cells = <1>;
 		device_type = "soc";
 		compatible = "simple-bus";
-		ranges = <0x0 0xffe00000 0x100000>;
+		ranges = <0x0 0 0xffe00000 0x100000>;
 		bus-frequency = <0>;		// Filled out by uboot.
 
 		ecm-law@0 {
@@ -250,6 +250,14 @@
 			phy_type = "ulpi";
 		};
 
+		sdhci@2e000 {
+			compatible = "fsl,mpc8536-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			clock-frequency = <250000000>;
+		};
+
 		serial0: serial@4500 {
 			cell-index = <0>;
 			device_type = "serial";
@@ -347,13 +355,13 @@
 		interrupt-parent = <&mpic>;
 		interrupts = <24 0x2>;
 		bus-range = <0 0xff>;
-		ranges = <0x02000000 0 0x80000000 0x80000000 0 0x10000000
-			  0x01000000 0 0x00000000 0xffc00000 0 0x00010000>;
+		ranges = <0x02000000 0 0x80000000 0 0x80000000 0 0x10000000
+			  0x01000000 0 0x00000000 0 0xffc00000 0 0x00010000>;
 		clock-frequency = <66666666>;
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
 		#address-cells = <3>;
-		reg = <0xffe08000 0x1000>;
+		reg = <0 0xffe08000 0 0x1000>;
 	};
 
 	pci1: pcie@ffe09000 {
@@ -362,10 +370,10 @@
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
 		#address-cells = <3>;
-		reg = <0xffe09000 0x1000>;
+		reg = <0 0xffe09000 0 0x1000>;
 		bus-range = <0 0xff>;
-		ranges = <0x02000000 0 0x98000000 0x98000000 0 0x08000000
-			  0x01000000 0 0x00000000 0xffc20000 0 0x00010000>;
+		ranges = <0x02000000 0 0x98000000 0 0x98000000 0 0x08000000
+			  0x01000000 0 0x00000000 0 0xffc20000 0 0x00010000>;
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <25 0x2>;
@@ -398,10 +406,10 @@
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
 		#address-cells = <3>;
-		reg = <0xffe0a000 0x1000>;
+		reg = <0 0xffe0a000 0 0x1000>;
 		bus-range = <0 0xff>;
-		ranges = <0x02000000 0 0x90000000 0x90000000 0 0x08000000
-			  0x01000000 0 0x00000000 0xffc10000 0 0x00010000>;
+		ranges = <0x02000000 0 0x90000000 0 0x90000000 0 0x08000000
+			  0x01000000 0 0x00000000 0 0xffc10000 0 0x00010000>;
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <26 0x2>;
@@ -434,10 +442,10 @@
 		#interrupt-cells = <1>;
 		#size-cells = <2>;
 		#address-cells = <3>;
-		reg = <0xffe0b000 0x1000>;
+		reg = <0 0xffe0b000 0 0x1000>;
 		bus-range = <0 0xff>;
-		ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x20000000
-			  0x01000000 0 0x00000000 0xffc30000 0 0x00010000>;
+		ranges = <0x02000000 0 0xa0000000 0 0xa0000000 0 0x20000000
+			  0x01000000 0 0x00000000 0 0xffc30000 0 0x00010000>;
 		clock-frequency = <33333333>;
 		interrupt-parent = <&mpic>;
 		interrupts = <27 0x2>;
diff --git a/arch/powerpc/boot/dts/mpc8536ds_36b.dts b/arch/powerpc/boot/dts/mpc8536ds_36b.dts
new file mode 100644
index 0000000..d95b260
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8536ds_36b.dts
@@ -0,0 +1,475 @@
+/*
+ * MPC8536 DS Device Tree Source
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+	model = "fsl,mpc8536ds";
+	compatible = "fsl,mpc8536ds";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
+		pci3 = &pci3;
+	};
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8536@0 {
+			device_type = "cpu";
+			reg = <0>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0 0 0 0>;	// Filled by U-Boot
+	};
+
+	soc@fffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "simple-bus";
+		ranges = <0x0 0xf 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,mpc8536-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <17 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,mpc8536-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 0x2>;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,mpc8536-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <16 0x2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 0x2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 0x2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			rtc@68 {
+				compatible = "dallas,ds3232";
+				reg = <0x68>;
+				interrupts = <0 0x1>;
+				interrupt-parent = <&mpic>;
+			};
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,mpc8536-dma", "fsl,eloplus-dma";
+			reg = <0x21300 4>;
+			ranges = <0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,mpc8536-dma-channel",
+					     "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,mpc8536-dma-channel",
+					     "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,mpc8536-dma-channel",
+					     "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,mpc8536-dma-channel",
+					     "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph";
+			reg = <0x22000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+			phy_type = "ulpi";
+		};
+
+		usb@23000 {
+			compatible = "fsl,mpc8536-usb2-mph", "fsl-usb2-mph";
+			reg = <0x23000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <&mpic>;
+			interrupts = <46 0x2>;
+			phy_type = "ulpi";
+		};
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <29 2 30 2 34 2>;
+			interrupt-parent = <&mpic>;
+			tbi-handle = <&tbi0>;
+			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 0x1>;
+					reg = <0>;
+					device_type = "ethernet-phy";
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <10 0x1>;
+					reg = <1>;
+					device_type = "ethernet-phy";
+				};
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		enet1: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x26000 0x1000>;
+			ranges = <0x0 0x26000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <31 2 32 2 33 2>;
+			interrupt-parent = <&mpic>;
+			tbi-handle = <&tbi1>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi1: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		usb@2b000 {
+			compatible = "fsl,mpc8536-usb2-dr", "fsl-usb2-dr";
+			reg = <0x2b000 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupt-parent = <&mpic>;
+			interrupts = <60 0x2>;
+			dr_mode = "peripheral";
+			phy_type = "ulpi";
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,mpc8536-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			clock-frequency = <250000000>;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.0", "fsl,sec2.4", "fsl,sec2.2",
+				     "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0x9fe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		sata@18000 {
+			compatible = "fsl,mpc8536-sata", "fsl,pq-sata";
+			reg = <0x18000 0x1000>;
+			cell-index = <1>;
+			interrupts = <74 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		sata@19000 {
+			compatible = "fsl,mpc8536-sata", "fsl,pq-sata";
+			reg = <0x19000 0x1000>;
+			cell-index = <2>;
+			interrupts = <41 0x2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,mpc8548-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+
+		mpic: pic@40000 {
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+			big-endian;
+		};
+
+		msi@41600 {
+			compatible = "fsl,mpc8536-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+	};
+
+	pci0: pci@fffe08000 {
+		compatible = "fsl,mpc8540-pci";
+		device_type = "pci";
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+
+			/* IDSEL 0x11 J17 Slot 1 */
+			0x8800 0 0 1 &mpic 1 1
+			0x8800 0 0 2 &mpic 2 1
+			0x8800 0 0 3 &mpic 3 1
+			0x8800 0 0 4 &mpic 4 1>;
+
+		interrupt-parent = <&mpic>;
+		interrupts = <24 0x2>;
+		bus-range = <0 0xff>;
+		ranges = <0x02000000 0 0xf0000000 0xc 0x00000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xf 0xffc00000 0 0x00010000>;
+		clock-frequency = <66666666>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xffe08000 0 0x1000>;
+	};
+
+	pci1: pcie@fffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xffe09000 0 0x1000>;
+		bus-range = <0 0xff>;
+		ranges = <0x02000000 0 0xf8000000 0xc 0x18000000 0 0x08000000
+			  0x01000000 0 0x00000000 0xf 0xffc20000 0 0x00010000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <25 0x2>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 4 1
+			0000 0 0 2 &mpic 5 1
+			0000 0 0 3 &mpic 6 1
+			0000 0 0 4 &mpic 7 1
+			>;
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0 0xf8000000
+				  0x02000000 0 0xf8000000
+				  0 0x08000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci2: pcie@fffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xffe0a000 0 0x1000>;
+		bus-range = <0 0xff>;
+		ranges = <0x02000000 0 0xf8000000 0xc 0x10000000 0 0x08000000
+			  0x01000000 0 0x00000000 0xf 0xffc10000 0 0x00010000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <26 0x2>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 0 1
+			0000 0 0 2 &mpic 1 1
+			0000 0 0 3 &mpic 2 1
+			0000 0 0 4 &mpic 3 1
+			>;
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0 0xf8000000
+				  0x02000000 0 0xf8000000
+				  0 0x08000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci3: pcie@fffe0b000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0xf 0xffe0b000 0 0x1000>;
+		bus-range = <0 0xff>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x20000000 0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xffc30000 0 0x00010000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <27 0x2>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 8 1
+			0000 0 0 2 &mpic 9 1
+			0000 0 0 3 &mpic 10 1
+			0000 0 0 4 &mpic 11 1
+			>;
+
+		pcie@0 {
+			reg = <0 0 0 0 0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00100000>;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index 475be14..4173af3 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -100,6 +100,21 @@
 			interrupts = <43 2>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
+
+			eeprom@50 {
+				compatible = "atmel,24c64";
+				reg = <0x50>;
+			};
+
+			eeprom@56 {
+				compatible = "atmel,24c64";
+				reg = <0x56>;
+			};
+
+			eeprom@57 {
+				compatible = "atmel,24c64";
+				reg = <0x57>;
+			};
 		};
 
 		i2c@3100 {
@@ -111,6 +126,11 @@
 			interrupts = <43 2>;
 			interrupt-parent = <&mpic>;
 			dfsrr;
+
+			eeprom@50 {
+				compatible = "atmel,24c64";
+				reg = <0x50>;
+			};
 		};
 
 		dma@21300 {
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
index 9e4ce99..06332d6 100644
--- a/arch/powerpc/boot/dts/mpc8569mds.dts
+++ b/arch/powerpc/boot/dts/mpc8569mds.dts
@@ -99,8 +99,18 @@
 		};
 
 		bcsr@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
 			compatible = "fsl,mpc8569mds-bcsr";
 			reg = <1 0 0x8000>;
+			ranges = <0 1 0 0x8000>;
+
+			bcsr17: gpio-controller@11 {
+				#gpio-cells = <2>;
+				compatible = "fsl,mpc8569mds-bcsr-gpio";
+				reg = <0x11 0x1>;
+				gpio-controller;
+			};
 		};
 
 		nand@3,0 {
@@ -315,6 +325,14 @@
 				gpio-controller;
 			};
 
+			qe_pio_f: gpio-controller@a0 {
+				#gpio-cells = <2>;
+				compatible = "fsl,mpc8569-qe-pario-bank",
+					     "fsl,mpc8323-qe-pario-bank";
+				reg = <0xa0 0x18>;
+				gpio-controller;
+			};
+
 			pio1: ucc_pin@01 {
 				pio-map = <
 			/* port  pin  dir  open_drain  assignment  has_irq */
@@ -419,6 +437,16 @@
 			interrupt-parent = <&mpic>;
 		};
 
+		timer@440 {
+			compatible = "fsl,mpc8569-qe-gtm",
+				     "fsl,qe-gtm", "fsl,gtm";
+			reg = <0x440 0x40>;
+			interrupts = <12 13 14 15>;
+			interrupt-parent = <&qeic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
 		spi@4c0 {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -446,6 +474,23 @@
 			mode = "cpu";
 		};
 
+		usb@6c0 {
+			compatible = "fsl,mpc8569-qe-usb",
+				     "fsl,mpc8323-qe-usb";
+			reg = <0x6c0 0x40 0x8b00 0x100>;
+			interrupts = <11>;
+			interrupt-parent = <&qeic>;
+			fsl,fullspeed-clock = "clk5";
+			fsl,lowspeed-clock = "brg10";
+			gpios = <&qe_pio_f 3 0   /* USBOE */
+				 &qe_pio_f 4 0   /* USBTP */
+				 &qe_pio_f 5 0   /* USBTN */
+				 &qe_pio_f 6 0   /* USBRP */
+				 &qe_pio_f 8 0   /* USBRN */
+				 &bcsr17   6 0   /* SPEED */
+				 &bcsr17   5 1>; /* POWER */
+		};
+
 		enet0: ucc@2000 {
 			device_type = "network";
 			compatible = "ucc_geth";
diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/dts/p2020rdb.dts
new file mode 100644
index 0000000..da4cb0d
--- /dev/null
+++ b/arch/powerpc/boot/dts/p2020rdb.dts
@@ -0,0 +1,586 @@
+/*
+ * P2020 RDB Device Tree Source
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+	model = "fsl,P2020";
+	compatible = "fsl,P2020RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P2020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P2020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@ffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
+		reg = <0 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		/* NOR and NAND Flashes */
+		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+			  0x1 0x0 0x0 0xffa00000 0x00040000
+			  0x2 0x0 0x0 0xffb00000 0x00020000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x1000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 256KB for Vitesse 7385 Switch firmware */
+				reg = <0x0 0x00040000>;
+				label = "NOR (RO) Vitesse-7385 Firmware";
+				read-only;
+			};
+
+			partition@40000 {
+				/* 256KB for DTB Image */
+				reg = <0x00040000 0x00040000>;
+				label = "NOR (RO) DTB Image";
+				read-only;
+			};
+
+			partition@80000 {
+				/* 3.5 MB for Linux Kernel Image */
+				reg = <0x00080000 0x00380000>;
+				label = "NOR (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@400000 {
+				/* 11MB for JFFS2 based Root file System */
+				reg = <0x00400000 0x00b00000>;
+				label = "NOR (RW) JFFS2 Root File System";
+			};
+
+			partition@f00000 {
+				/* This location must not be altered  */
+				/* 512KB for u-boot Bootloader Image */
+				/* 512KB for u-boot Environment Variables */
+				reg = <0x00f00000 0x00100000>;
+				label = "NOR (RO) U-Boot Image";
+				read-only;
+			};
+		};
+
+		nand@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p2020-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x1 0x0 0x40000>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 1MB for u-boot Bootloader Image */
+				reg = <0x0 0x00100000>;
+				label = "NAND (RO) U-Boot Image";
+				read-only;
+			};
+
+			partition@100000 {
+				/* 1MB for DTB Image */
+				reg = <0x00100000 0x00100000>;
+				label = "NAND (RO) DTB Image";
+				read-only;
+			};
+
+			partition@200000 {
+				/* 4MB for Linux Kernel Image */
+				reg = <0x00200000 0x00400000>;
+				label = "NAND (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@600000 {
+				/* 4MB for Compressed Root file System Image */
+				reg = <0x00600000 0x00400000>;
+				label = "NAND (RO) Compressed RFS Image";
+				read-only;
+			};
+
+			partition@a00000 {
+				/* 7MB for JFFS2 based Root file System */
+				reg = <0x00a00000 0x00700000>;
+				label = "NAND (RW) JFFS2 Root File System";
+			};
+
+			partition@1100000 {
+				/* 15MB for JFFS2 based Root file System */
+				reg = <0x01100000 0x00f00000>;
+				label = "NAND (RW) Writable User area";
+			};
+		};
+
+		L2switch@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "vitesse-7385";
+			reg = <0x2 0x0 0x20000>;
+		};
+
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p2020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p2020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <17 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p2020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				modal = "s25sl128b";
+				spi-max-frequency = <50000000>;
+				mode = <0>;
+
+				partition@0 {
+					/* 512KB for u-boot Bootloader Image */
+					reg = <0x0 0x00080000>;
+					label = "SPI (RO) U-Boot Image";
+					read-only;
+				};
+
+				partition@80000 {
+					/* 512KB for DTB Image */
+					reg = <0x00080000 0x00080000>;
+					label = "SPI (RO) DTB Image";
+					read-only;
+				};
+
+				partition@100000 {
+					/* 4MB for Linux Kernel Image */
+					reg = <0x00100000 0x00400000>;
+					label = "SPI (RO) Linux Kernel Image";
+					read-only;
+				};
+
+				partition@500000 {
+					/* 4MB for Compressed RFS Image */
+					reg = <0x00500000 0x00400000>;
+					label = "SPI (RO) Compressed RFS Image";
+					read-only;
+				};
+
+				partition@900000 {
+					/* 7MB for JFFS2 based RFS */
+					reg = <0x00900000 0x00700000>;
+					label = "SPI (RW) JFFS2 RFS";
+				};
+			};
+		};
+
+		dma@c300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0xc300 0x4>;
+			ranges = <0x0 0xc100 0x200>;
+			cell-index = <1>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <76 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <77 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <78 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <79 2>;
+			};
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p2020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x80000>; // L2,512K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+			phy_type = "ulpi";
+		};
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <29 2 30 2 34 2>;
+			interrupt-parent = <&mpic>;
+			fixed-link = <1 1 1000 0 0>;
+			phy-connection-type = "rgmii-id";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+
+				phy0: ethernet-phy@0 {
+					interrupt-parent = <&mpic>;
+					interrupts = <3 1>;
+					reg = <0x0>;
+				};
+				phy1: ethernet-phy@1 {
+					interrupt-parent = <&mpic>;
+					interrupts = <3 1>;
+					reg = <0x1>;
+				};
+			};
+		};
+
+		enet1: ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <35 2 36 2 40 2>;
+			interrupt-parent = <&mpic>;
+			tbi-handle = <&tbi0>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "sgmii";
+
+			mdio@520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+
+				tbi0: tbi-phy@11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <2>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x26000 0x1000>;
+			ranges = <0x0 0x26000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <31 2 32 2 33 2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		msi@41600 {
+			compatible = "fsl,p2020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,p2020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <25 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xa0000000
+				  0x2000000 0x0 0xa0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <26 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xc0000000
+				  0x2000000 0x0 0xc0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff --git a/arch/powerpc/boot/dts/sbc8349.dts b/arch/powerpc/boot/dts/sbc8349.dts
index 2d9fa68..0dc90f9 100644
--- a/arch/powerpc/boot/dts/sbc8349.dts
+++ b/arch/powerpc/boot/dts/sbc8349.dts
@@ -146,18 +146,6 @@
 			phy_type = "ulpi";
 			port0;
 		};
-		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
-		usb@23000 {
-			device_type = "usb";
-			compatible = "fsl-usb2-dr";
-			reg = <0x23000 0x1000>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			interrupt-parent = <&ipic>;
-			interrupts = <38 0x8>;
-			dr_mode = "otg";
-			phy_type = "ulpi";
-		};
 
 		enet0: ethernet@24000 {
 			#address-cells = <1>;
@@ -277,15 +265,55 @@
 		};
 	};
 
+	localbus@e0005000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8349-localbus", "simple-bus";
+		reg = <0xe0005000 0x1000>;
+		interrupts = <77 0x8>;
+		interrupt-parent = <&ipic>;
+		ranges = <0x0 0x0 0xff800000 0x00800000		/* 8MB Flash */
+			  0x1 0x0 0xf8000000 0x00002000		/* 8KB EEPROM */
+			  0x2 0x0 0x10000000 0x04000000		/* 64MB SDRAM */
+			  0x3 0x0 0x10000000 0x04000000>;	/* 64MB SDRAM */
+
+		flash@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "intel,28F640J3A", "cfi-flash";
+			reg = <0x0 0x0 0x800000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			partition@0 {
+				label = "u-boot";
+				reg = <0x00000000 0x00040000>;
+				read-only;
+			};
+
+			partition@40000 {
+				label = "user";
+				reg = <0x00040000 0x006c0000>;
+			};
+
+			partition@700000 {
+				label = "legacy u-boot";
+				reg = <0x00700000 0x00100000>;
+				read-only;
+			};
+
+		};
+	};
+
 	pci0: pci@e0008500 {
 		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
 		interrupt-map = <
 
 				/* IDSEL 0x11 */
-				 0x8800 0x0 0x0 0x1 &ipic 20 0x8
-				 0x8800 0x0 0x0 0x2 &ipic 21 0x8
-				 0x8800 0x0 0x0 0x3 &ipic 22 0x8
-				 0x8800 0x0 0x0 0x4 &ipic 23 0x8>;
+				 0x8800 0x0 0x0 0x1 &ipic 48 0x8
+				 0x8800 0x0 0x0 0x2 &ipic 17 0x8
+				 0x8800 0x0 0x0 0x3 &ipic 18 0x8
+				 0x8800 0x0 0x0 0x4 &ipic 19 0x8>;
 
 		interrupt-parent = <&ipic>;
 		interrupts = <0x42 0x8>;
diff --git a/arch/powerpc/boot/dts/sbc8560.dts b/arch/powerpc/boot/dts/sbc8560.dts
index 239d57a..9e13ed8 100644
--- a/arch/powerpc/boot/dts/sbc8560.dts
+++ b/arch/powerpc/boot/dts/sbc8560.dts
@@ -303,7 +303,6 @@
 		global-utilities@e0000 {
 			compatible = "fsl,mpc8560-guts";
 			reg = <0xe0000 0x1000>;
-			fsl,has-rstcr;
 		};
 	};
 
diff --git a/arch/powerpc/boot/mktree.c b/arch/powerpc/boot/mktree.c
index c2baae0..e2ae243 100644
--- a/arch/powerpc/boot/mktree.c
+++ b/arch/powerpc/boot/mktree.c
@@ -36,7 +36,7 @@ typedef struct boot_block {
 } boot_block_t;
 
 #define IMGBLK	512
-char	tmpbuf[IMGBLK];
+unsigned int	tmpbuf[IMGBLK / sizeof(unsigned int)];
 
 int main(int argc, char *argv[])
 {
@@ -95,13 +95,13 @@ int main(int argc, char *argv[])
 
 	/* Assume zImage is an ELF file, and skip the 64K header.
 	*/
-	if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) {
+	if (read(in_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
 		fprintf(stderr, "%s is too small to be an ELF image\n",
 				argv[1]);
 		exit(4);
 	}
 
-	if ((*(unsigned int *)tmpbuf) != htonl(0x7f454c46)) {
+	if (tmpbuf[0] != htonl(0x7f454c46)) {
 		fprintf(stderr, "%s is not an ELF image\n", argv[1]);
 		exit(4);
 	}
@@ -121,11 +121,11 @@ int main(int argc, char *argv[])
 	}
 
 	while (nblks-- > 0) {
-		if (read(in_fd, tmpbuf, IMGBLK) < 0) {
+		if (read(in_fd, tmpbuf, sizeof(tmpbuf)) < 0) {
 			perror("zImage read");
 			exit(5);
 		}
-		cp = (unsigned int *)tmpbuf;
+		cp = tmpbuf;
 		for (i = 0; i < sizeof(tmpbuf) / sizeof(unsigned int); i++)
 			cksum += *cp++;
 		if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
diff --git a/arch/powerpc/boot/ppcboot-hotfoot.h b/arch/powerpc/boot/ppcboot-hotfoot.h
new file mode 100644
index 0000000..1a3e80b
--- /dev/null
+++ b/arch/powerpc/boot/ppcboot-hotfoot.h
@@ -0,0 +1,133 @@
+/*
+ * This interface is used for compatibility with old U-boots *ONLY*.
+ * Please do not imitate or extend this.
+ */
+
+/* 
+ * Unfortunately, the ESTeem Hotfoot board uses a mangled version of 
+ * ppcboot.h for historical reasons, and in the interest of having a 
+ * mainline kernel boot on the production board+bootloader, this was the 
+ * least-offensive solution.  Please direct all flames to:
+ *
+ *  Solomon Peachy <solomon@linux-wlan.com>
+ *
+ * (This header is identical to ppcboot.h except for the 
+ *  TARGET_HOTFOOT bits)
+ */
+
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU 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 __PPCBOOT_H__
+#define __PPCBOOT_H__
+
+/*
+ * Board information passed to kernel from PPCBoot
+ *
+ * include/asm-ppc/ppcboot.h
+ */
+
+#include "types.h"
+
+typedef struct bd_info {
+	unsigned long	bi_memstart;	/* start of DRAM memory */
+	unsigned long	bi_memsize;	/* size	 of DRAM memory in bytes */
+	unsigned long	bi_flashstart;	/* start of FLASH memory */
+	unsigned long	bi_flashsize;	/* size	 of FLASH memory */
+	unsigned long	bi_flashoffset; /* reserved area for startup monitor */
+	unsigned long	bi_sramstart;	/* start of SRAM memory */
+	unsigned long	bi_sramsize;	/* size	 of SRAM memory */
+#if defined(TARGET_8xx) || defined(TARGET_CPM2) || defined(TARGET_85xx) ||\
+	defined(TARGET_83xx)
+	unsigned long	bi_immr_base;	/* base of IMMR register */
+#endif
+#if defined(TARGET_PPC_MPC52xx)
+	unsigned long   bi_mbar_base;   /* base of internal registers */
+#endif
+	unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS) */
+	unsigned long	bi_ip_addr;	/* IP Address */
+	unsigned char	bi_enetaddr[6];	/* Ethernet address */
+#if defined(TARGET_HOTFOOT)
+	/* second onboard ethernet port */
+	unsigned char	bi_enet1addr[6];
+#define HAVE_ENET1ADDR
+#endif /* TARGET_HOOTFOOT */
+	unsigned short	bi_ethspeed;	/* Ethernet speed in Mbps */
+	unsigned long	bi_intfreq;	/* Internal Freq, in MHz */
+	unsigned long	bi_busfreq;	/* Bus Freq, in MHz */
+#if defined(TARGET_CPM2)
+	unsigned long	bi_cpmfreq;	/* CPM_CLK Freq, in MHz */
+	unsigned long	bi_brgfreq;	/* BRG_CLK Freq, in MHz */
+	unsigned long	bi_sccfreq;	/* SCC_CLK Freq, in MHz */
+	unsigned long	bi_vco;		/* VCO Out from PLL, in MHz */
+#endif
+#if defined(TARGET_PPC_MPC52xx)
+	unsigned long   bi_ipbfreq;     /* IPB Bus Freq, in MHz */
+	unsigned long   bi_pcifreq;     /* PCI Bus Freq, in MHz */
+#endif
+	unsigned long	bi_baudrate;	/* Console Baudrate */
+#if defined(TARGET_4xx)
+	unsigned char	bi_s_version[4];	/* Version of this structure */
+	unsigned char	bi_r_version[32];	/* Version of the ROM (IBM) */
+	unsigned int	bi_procfreq;	/* CPU (Internal) Freq, in Hz */
+	unsigned int	bi_plb_busfreq;	/* PLB Bus speed, in Hz */
+	unsigned int	bi_pci_busfreq;	/* PCI Bus speed, in Hz */
+	unsigned char	bi_pci_enetaddr[6];	/* PCI Ethernet MAC address */
+#endif
+#if defined(TARGET_HOTFOOT)
+	unsigned int     bi_pllouta_freq;       /* PLL OUTA speed, in Hz */
+#endif
+#if defined(TARGET_HYMOD)
+	hymod_conf_t	bi_hymod_conf;	/* hymod configuration information */
+#endif
+#if defined(TARGET_EVB64260) || defined(TARGET_405EP) || defined(TARGET_44x) || \
+	defined(TARGET_85xx) ||	defined(TARGET_83xx) || defined(TARGET_HAS_ETH1)
+	/* second onboard ethernet port */
+	unsigned char	bi_enet1addr[6];
+#define HAVE_ENET1ADDR
+#endif
+#if defined(TARGET_EVB64260) || defined(TARGET_440GX) || \
+    defined(TARGET_85xx) || defined(TARGET_HAS_ETH2)
+	/* third onboard ethernet ports */
+	unsigned char	bi_enet2addr[6];
+#define HAVE_ENET2ADDR
+#endif
+#if defined(TARGET_440GX) || defined(TARGET_HAS_ETH3)
+	/* fourth onboard ethernet ports */
+	unsigned char	bi_enet3addr[6];
+#define HAVE_ENET3ADDR
+#endif
+#if defined(TARGET_HOTFOOT)
+        int             bi_phynum[2];           /* Determines phy mapping */
+        int             bi_phymode[2];          /* Determines phy mode */
+#endif
+#if defined(TARGET_4xx)
+	unsigned int	bi_opbfreq;		/* OB clock in Hz */
+	int		bi_iic_fast[2];		/* Use fast i2c mode */
+#endif
+#if defined(TARGET_440GX)
+	int		bi_phynum[4];		/* phy mapping */
+	int		bi_phymode[4];		/* phy mode */
+#endif
+} bd_t;
+
+#define bi_tbfreq	bi_intfreq
+
+#endif	/* __PPCBOOT_H__ */
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 4db487d..ac9e9a5 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -46,6 +46,7 @@ CROSS=
 # directory for object and other files used by this script
 object=arch/powerpc/boot
 objbin=$object
+dtc=scripts/dtc/dtc
 
 # directory for working files
 tmpdir=.
@@ -124,7 +125,7 @@ if [ -n "$dts" ]; then
     if [ -z "$dtb" ]; then
 	dtb="$platform.dtb"
     fi
-    $object/dtc -O dtb -o "$dtb" -b 0 "$dts"
+    $dtc -O dtb -o "$dtb" -b 0 "$dts"
 fi
 
 if [ -z "$kernel" ]; then
diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig
index 865725e..9a05ec0 100644
--- a/arch/powerpc/configs/40x/kilauea_defconfig
+++ b/arch/powerpc/configs/40x/kilauea_defconfig
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30-rc7
-# Wed Jun  3 10:18:16 2009
+# Linux kernel version: 2.6.31-rc4
+# Wed Jul 29 13:28:37 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 CONFIG_40x=y
@@ -32,11 +32,11 @@ CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -57,6 +57,7 @@ CONFIG_PPC_DCR_NATIVE=y
 CONFIG_PPC_DCR=y
 CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -108,7 +109,6 @@ CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
-# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
@@ -121,9 +121,16 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
@@ -137,6 +144,11 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
 # CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
@@ -149,7 +161,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -220,6 +232,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_PPC_NEED_DMA_SYNC_OPS=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
@@ -239,9 +252,9 @@ CONFIG_MIGRATION=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
 CONFIG_HAVE_MLOCK=y
 CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
@@ -344,6 +357,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -393,9 +407,8 @@ CONFIG_MTD_OF_PARTS=y
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=m
-CONFIG_MTD_BLOCK=m
-# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
@@ -452,7 +465,17 @@ CONFIG_MTD_PHYSMAP_OF=y
 # 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_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_NDFC=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -465,6 +488,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 #
 # CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -504,14 +528,17 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS 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
@@ -546,6 +573,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
 # CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -621,20 +649,150 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_IBM_IIC=y
+# CONFIG_I2C_MPC is not set
+# 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
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# 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
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+CONFIG_SENSORS_LM75=y
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# 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
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
@@ -649,24 +807,15 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 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_AB3100_CORE 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
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -691,10 +840,69 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# 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=y
+# 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 is not set
+# 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
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_GENERIC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -708,11 +916,12 @@ CONFIG_EXT2_FS=y
 # 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_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -818,6 +1027,7 @@ CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -848,6 +1058,9 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -859,7 +1072,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # 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_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
@@ -873,16 +1085,15 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
@@ -891,6 +1102,9 @@ CONFIG_TRACING_SUPPORT=y
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
diff --git a/arch/powerpc/configs/44x/arches_defconfig b/arch/powerpc/configs/44x/arches_defconfig
index f7fd32c..6f976b5 100644
--- a/arch/powerpc/configs/44x/arches_defconfig
+++ b/arch/powerpc/configs/44x/arches_defconfig
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:31 2009
+# Linux kernel version: 2.6.31-rc5
+# Thu Aug 13 14:14:07 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -31,15 +31,16 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -53,11 +54,14 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -71,9 +75,19 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # 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_GROUP_SCHED is not set
@@ -84,8 +98,12 @@ CONFIG_SYSFS_DEPRECATED_V2=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_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -95,23 +113,30 @@ 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_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -119,6 +144,12 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -130,8 +161,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -147,11 +177,6 @@ CONFIG_DEFAULT_AS=y
 # 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
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -172,6 +197,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 CONFIG_ARCHES=y
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -214,6 +240,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_PPC_NEED_DMA_SYNC_OPS=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
@@ -233,10 +260,14 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -261,6 +292,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # 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
 # CONFIG_HAS_RAPIDIO is not set
@@ -278,14 +310,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -335,6 +365,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -347,7 +379,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
@@ -371,8 +402,92 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# 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_OF_PARTS=y
+# 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 is not set
+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 is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -412,7 +527,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -433,6 +552,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -451,6 +572,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
 # CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -461,7 +583,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 #
 # 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
@@ -533,13 +654,143 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_IBM_IIC=y
+# CONFIG_I2C_MPC is not set
+# 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
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+CONFIG_SENSORS_AD7414=y
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# 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
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# 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
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
@@ -556,24 +807,15 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 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_AB3100_CORE 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=y
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -600,7 +842,12 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -614,11 +861,12 @@ CONFIG_EXT2_FS=y
 # 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_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -628,6 +876,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -660,6 +913,17 @@ CONFIG_MISC_FILESYSTEMS=y
 # 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 is not set
+# 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
@@ -670,6 +934,7 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -681,7 +946,6 @@ 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
@@ -697,6 +961,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -711,11 +976,14 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -733,6 +1001,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -743,6 +1014,9 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -754,7 +1028,6 @@ CONFIG_SCHED_DEBUG=y
 # 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_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
@@ -762,27 +1035,36 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig
index 5e85412..b312b16 100644
--- a/arch/powerpc/configs/44x/canyonlands_defconfig
+++ b/arch/powerpc/configs/44x/canyonlands_defconfig
@@ -1,14 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc3
-# Mon Feb  2 13:13:04 2009
+# Linux kernel version: 2.6.31-rc4
+# Wed Jul 29 17:27:20 2009
 #
 # CONFIG_PPC64 is not set
 
 #
 # Processor support
 #
-# CONFIG_6xx is not set
+# CONFIG_PPC_BOOK3S_32 is not set
 # CONFIG_PPC_85xx is not set
 # CONFIG_PPC_8xx is not set
 # CONFIG_40x is not set
@@ -31,15 +31,16 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
@@ -53,11 +54,14 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -71,6 +75,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
@@ -93,8 +98,12 @@ CONFIG_SYSFS_DEPRECATED_V2=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_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -104,23 +113,30 @@ 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_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -128,6 +144,12 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -139,8 +161,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -176,6 +197,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 # CONFIG_ARCHES is not set
 CONFIG_CANYONLANDS=y
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -218,6 +240,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
 CONFIG_PPC_NEED_DMA_SYNC_OPS=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
 CONFIG_ARCH_HAS_WALK_MEMORY=y
@@ -237,10 +260,14 @@ CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -265,6 +292,7 @@ CONFIG_ARCH_SUPPORTS_MSI=y
 # 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
 # CONFIG_HAS_RAPIDIO is not set
@@ -282,14 +310,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -339,6 +365,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -351,7 +379,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # 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
@@ -375,7 +402,101 @@ CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=y
 CONFIG_PROC_EVENTS=y
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# 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_OF_PARTS=y
+# 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 is not set
+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 is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_NDFC=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
+# 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
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
@@ -418,7 +539,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -439,6 +564,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -457,6 +584,7 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
 # CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
@@ -467,7 +595,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 #
 # 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
@@ -542,7 +669,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
-# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -608,14 +734,17 @@ CONFIG_I2C_IBM_IIC=y
 # 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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
 # CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
@@ -640,6 +769,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_F71882FG is not set
 # CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
@@ -654,11 +784,14 @@ CONFIG_SENSORS_AD7414=y
 # 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
@@ -666,6 +799,7 @@ CONFIG_SENSORS_AD7414=y
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP401 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_SENSORS_VT8231 is not set
@@ -700,24 +834,9 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
 # CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE 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
-# CONFIG_USB_DABUSB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
@@ -759,6 +878,7 @@ CONFIG_USB_MON=y
 # USB Host Controller Drivers
 #
 # CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
 CONFIG_USB_EHCI_HCD=m
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
@@ -767,9 +887,9 @@ CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_ISP116X_HCD is not set
 # CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 CONFIG_USB_OHCI_HCD_PPC_OF_LE=y
+CONFIG_USB_OHCI_HCD_PPC_OF=y
 CONFIG_USB_OHCI_HCD_PCI=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
@@ -789,11 +909,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # 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=y
 
@@ -821,7 +941,6 @@ CONFIG_USB_LIBUSUAL=y
 # 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
@@ -837,6 +956,7 @@ CONFIG_USB_LIBUSUAL=y
 #
 # 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
@@ -844,9 +964,70 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# 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 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+CONFIG_RTC_DRV_M41T80=y
+# CONFIG_RTC_DRV_M41T80_WDT is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# 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_GENERIC is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -860,11 +1041,12 @@ CONFIG_EXT2_FS=y
 # 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_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -874,6 +1056,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -906,6 +1093,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # 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
@@ -916,6 +1104,7 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -927,7 +1116,6 @@ 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
@@ -941,8 +1129,48 @@ CONFIG_SUNRPC=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# 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 is not set
+# 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 is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -957,11 +1185,13 @@ CONFIG_CRC32=y
 # 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_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
 
 #
 # Kernel hacking
@@ -979,6 +1209,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -989,6 +1222,9 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
@@ -1000,7 +1236,6 @@ CONFIG_SCHED_DEBUG=y
 # 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_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
@@ -1008,27 +1243,36 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
-
-#
-# Tracers
-#
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
 # CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig
new file mode 100644
index 0000000..007f3bd
--- /dev/null
+++ b/arch/powerpc/configs/44x/eiger_defconfig
@@ -0,0 +1,1252 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc6
+# Wed Aug 19 13:06:50 2009
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_PPC_BOOK3S_32 is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# 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_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_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=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=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_FREEZER is not set
+CONFIG_PPC4xx_PCI_EXPRESS=y
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_BAMBOO is not set
+# CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+CONFIG_EIGER=y
+# CONFIG_YOSEMITE is not set
+# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
+CONFIG_PPC44x_SIMPLE=y
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_460SX=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# 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_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+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_MATH_EMULATION is not set
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_PPC_NEED_DMA_SYNC_OPS=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS=""
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIE_ECRC is not set
+# CONFIG_PCIEAER_INJECT is not set
+# CONFIG_PCIEASPM is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_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
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+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=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP 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=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_PHONET is not set
+# CONFIG_IEEE802154 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_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# 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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+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=y
+CONFIG_MTD_OF_PARTS=y
+# 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 is not set
+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 is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_NDFC=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
+# 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
+CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# 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_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE 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=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=y
+# CONFIG_CHR_DEV_SCH is not set
+# 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_ATTRS=y
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_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
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# 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_SCSI_BUSLOGIC is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# 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=y
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_MAX_SGE=128
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LOGGING is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+CONFIG_I2O=y
+CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y
+CONFIG_I2O_EXT_ADAPTEC=y
+# CONFIG_I2O_CONFIG is not set
+# CONFIG_I2O_BUS is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+# CONFIG_MACINTOSH_DRIVERS 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_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_NEW_EMAC_RXB=256
+CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32
+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256
+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0
+# CONFIG_IBM_NEW_EMAC_DEBUG is not set
+CONFIG_IBM_NEW_EMAC_ZMII=y
+CONFIG_IBM_NEW_EMAC_RGMII=y
+CONFIG_IBM_NEW_EMAC_TAH=y
+CONFIG_IBM_NEW_EMAC_EMAC4=y
+# 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_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_MV643XX_ETH is not set
+# CONFIG_XILINX_LL_TEMAC is not set
+# 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
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 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
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC 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 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=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_IBM_IIC=y
+# CONFIG_I2C_MPC is not set
+# 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
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB 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 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_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_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+# 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_UWB 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_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# 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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_KCORE=y
+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 is not set
+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 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_NILFS2_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_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 is not set
+# CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF 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_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# 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=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# 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_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR 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_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_KMEMCHECK is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_PPC_EMULATED_STATS is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG 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_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=y
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_CRYPTD=y
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_MD4=y
+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=y
+CONFIG_CRYPTO_SHA512=y
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+# 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 is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
diff --git a/arch/powerpc/configs/83xx/sbc834x_defconfig b/arch/powerpc/configs/83xx/sbc834x_defconfig
index a592b5e..3a68f86 100644
--- a/arch/powerpc/configs/83xx/sbc834x_defconfig
+++ b/arch/powerpc/configs/83xx/sbc834x_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:32:13 2009
+# Linux kernel version: 2.6.31-rc5
+# Tue Aug 11 19:57:51 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -420,7 +420,90 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
-# CONFIG_MTD 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=y
+CONFIG_MTD_OF_PARTS=y
+# 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 is not set
+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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# 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 is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_INTEL_VR_NOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
@@ -436,6 +519,7 @@ CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_CRYPTOLOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=32768
@@ -468,9 +552,38 @@ CONFIG_HAVE_IDE=y
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA 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 is not set
+
+#
+# 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
+# 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_SCSI_OSD_INITIATOR is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
@@ -578,11 +691,21 @@ CONFIG_GIANFAR=y
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
 #
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -633,9 +756,9 @@ CONFIG_DEVKMEM=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -700,6 +823,7 @@ CONFIG_I2C_MPC=y
 #
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
 
 #
 # Graphics adapter I2C/DDC channel drivers
@@ -814,6 +938,11 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
 CONFIG_SSB_POSSIBLE=y
 
 #
@@ -856,12 +985,134 @@ CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
 # CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+# CONFIG_USB_HID is not set
 # CONFIG_HID_PID is not set
 
 #
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+
+#
 # Special HID drivers
 #
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_XHCI_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_FSL=y
+CONFIG_USB_EHCI_HCD_PPC_OF=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 is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# 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_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# 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
@@ -882,9 +1133,14 @@ CONFIG_HID=y
 #
 # File systems
 #
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
 # CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -940,6 +1196,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # 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
@@ -977,7 +1234,46 @@ CONFIG_RPCSEC_GSS_KRB5=y
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# 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 is not set
+# 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 is not set
 # CONFIG_DLM is not set
 # CONFIG_BINARY_PRINTF is not set
 
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig
index e9491c1..30b68bf 100644
--- a/arch/powerpc/configs/mgcoge_defconfig
+++ b/arch/powerpc/configs/mgcoge_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc4
-# Wed Jul 29 23:31:51 2009
+# Linux kernel version: 2.6.31-rc5
+# Fri Aug  7 08:19:15 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -158,6 +158,7 @@ CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
 CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
@@ -506,6 +507,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
 CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
 CONFIG_OF_MDIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
@@ -582,7 +584,8 @@ CONFIG_PHYLIB=y
 # CONFIG_STE10XP is not set
 # CONFIG_LSI_ET1011C_PHY is not set
 CONFIG_FIXED_PHY=y
-# CONFIG_MDIO_BITBANG is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
 CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_MACE is not set
@@ -608,8 +611,8 @@ CONFIG_MII=y
 # CONFIG_ATL2 is not set
 CONFIG_FS_ENET=y
 CONFIG_FS_ENET_HAS_SCC=y
-# CONFIG_FS_ENET_HAS_FCC is not set
-# CONFIG_FS_ENET_MDIO_FCC is not set
+CONFIG_FS_ENET_HAS_FCC=y
+CONFIG_FS_ENET_MDIO_FCC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -680,7 +683,68 @@ CONFIG_HW_RANDOM=y
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
 CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# Mac SMBus host controller drivers
+#
+# CONFIG_I2C_POWERMAC is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_CPM=y
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_PCF8575 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 is not set
 
 #
@@ -699,6 +763,9 @@ CONFIG_GPIOLIB=y
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
 
 #
 # PCI GPIO expanders:
@@ -727,7 +794,14 @@ CONFIG_SSB_POSSIBLE=y
 # 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_AB3100_CORE is not set
 # CONFIG_REGULATOR is not set
 # CONFIG_MEDIA_SUPPORT is not set
 
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index ada5958..ee6acc6 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -203,6 +203,7 @@ CONFIG_MPC85xx_CDS=y
 CONFIG_MPC85xx_MDS=y
 CONFIG_MPC8536_DS=y
 CONFIG_MPC85xx_DS=y
+CONFIG_MPC85xx_RDB=y
 CONFIG_SOCRATES=y
 CONFIG_KSI8560=y
 # CONFIG_XES_MPC85xx is not set
diff --git a/arch/powerpc/include/asm/agp.h b/arch/powerpc/include/asm/agp.h
index 86455c4..416e12c 100644
--- a/arch/powerpc/include/asm/agp.h
+++ b/arch/powerpc/include/asm/agp.h
@@ -8,10 +8,6 @@
 #define unmap_page_from_agp(page)
 #define flush_agp_cache() mb()
 
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
 #define alloc_gatt_pages(order)		\
 	((char *)__get_free_pages(GFP_KERNEL, (order)))
diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index 897eade..56f2f2e 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -56,174 +56,102 @@
 #define BITOP_WORD(nr)		((nr) / BITS_PER_LONG)
 #define BITOP_LE_SWIZZLE	((BITS_PER_LONG-1) & ~0x7)
 
+/* Macro for generating the ***_bits() functions */
+#define DEFINE_BITOP(fn, op, prefix, postfix)	\
+static __inline__ void fn(unsigned long mask,	\
+		volatile unsigned long *_p)	\
+{						\
+	unsigned long old;			\
+	unsigned long *p = (unsigned long *)_p;	\
+	__asm__ __volatile__ (			\
+	prefix					\
+"1:"	PPC_LLARX "%0,0,%3\n"			\
+	stringify_in_c(op) "%0,%0,%2\n"		\
+	PPC405_ERR77(0,%3)			\
+	PPC_STLCX "%0,0,%3\n"			\
+	"bne- 1b\n"				\
+	postfix					\
+	: "=&r" (old), "+m" (*p)		\
+	: "r" (mask), "r" (p)			\
+	: "cc", "memory");			\
+}
+
+DEFINE_BITOP(set_bits, or, "", "")
+DEFINE_BITOP(clear_bits, andc, "", "")
+DEFINE_BITOP(clear_bits_unlock, andc, LWSYNC_ON_SMP, "")
+DEFINE_BITOP(change_bits, xor, "", "")
+
 static __inline__ void set_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long old;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-"1:"	PPC_LLARX "%0,0,%3	# set_bit\n"
-	"or	%0,%0,%2\n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%0,0,%3\n"
-	"bne-	1b"
-	: "=&r" (old), "+m" (*p)
-	: "r" (mask), "r" (p)
-	: "cc" );
+	set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
 }
 
 static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long old;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-"1:"	PPC_LLARX "%0,0,%3	# clear_bit\n"
-	"andc	%0,%0,%2\n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%0,0,%3\n"
-	"bne-	1b"
-	: "=&r" (old), "+m" (*p)
-	: "r" (mask), "r" (p)
-	: "cc" );
+	clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
 }
 
 static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr)
 {
-	unsigned long old;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-	LWSYNC_ON_SMP
-"1:"	PPC_LLARX "%0,0,%3	# clear_bit_unlock\n"
-	"andc	%0,%0,%2\n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%0,0,%3\n"
-	"bne-	1b"
-	: "=&r" (old), "+m" (*p)
-	: "r" (mask), "r" (p)
-	: "cc", "memory");
+	clear_bits_unlock(BITOP_MASK(nr), addr + BITOP_WORD(nr));
 }
 
 static __inline__ void change_bit(int nr, volatile unsigned long *addr)
 {
-	unsigned long old;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-"1:"	PPC_LLARX "%0,0,%3	# change_bit\n"
-	"xor	%0,%0,%2\n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%0,0,%3\n"
-	"bne-	1b"
-	: "=&r" (old), "+m" (*p)
-	: "r" (mask), "r" (p)
-	: "cc" );
+	change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr));
+}
+
+/* Like DEFINE_BITOP(), with changes to the arguments to 'op' and the output
+ * operands. */
+#define DEFINE_TESTOP(fn, op, prefix, postfix)	\
+static __inline__ unsigned long fn(		\
+		unsigned long mask,		\
+		volatile unsigned long *_p)	\
+{						\
+	unsigned long old, t;			\
+	unsigned long *p = (unsigned long *)_p;	\
+	__asm__ __volatile__ (			\
+	prefix					\
+"1:"	PPC_LLARX "%0,0,%3\n"			\
+	stringify_in_c(op) "%1,%0,%2\n"		\
+	PPC405_ERR77(0,%3)			\
+	PPC_STLCX "%1,0,%3\n"			\
+	"bne- 1b\n"				\
+	postfix					\
+	: "=&r" (old), "=&r" (t)		\
+	: "r" (mask), "r" (p)			\
+	: "cc", "memory");			\
+	return (old & mask);			\
 }
 
+DEFINE_TESTOP(test_and_set_bits, or, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_set_bits_lock, or, "", ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_clear_bits, andc, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+DEFINE_TESTOP(test_and_change_bits, xor, LWSYNC_ON_SMP, ISYNC_ON_SMP)
+
 static __inline__ int test_and_set_bit(unsigned long nr,
 				       volatile unsigned long *addr)
 {
-	unsigned long old, t;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-	LWSYNC_ON_SMP
-"1:"	PPC_LLARX "%0,0,%3		# test_and_set_bit\n"
-	"or	%1,%0,%2 \n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%1,0,%3 \n"
-	"bne-	1b"
-	ISYNC_ON_SMP
-	: "=&r" (old), "=&r" (t)
-	: "r" (mask), "r" (p)
-	: "cc", "memory");
-
-	return (old & mask) != 0;
+	return test_and_set_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_set_bit_lock(unsigned long nr,
 				       volatile unsigned long *addr)
 {
-	unsigned long old, t;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-"1:"	PPC_LLARX "%0,0,%3		# test_and_set_bit_lock\n"
-	"or	%1,%0,%2 \n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%1,0,%3 \n"
-	"bne-	1b"
-	ISYNC_ON_SMP
-	: "=&r" (old), "=&r" (t)
-	: "r" (mask), "r" (p)
-	: "cc", "memory");
-
-	return (old & mask) != 0;
+	return test_and_set_bits_lock(BITOP_MASK(nr),
+				addr + BITOP_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_clear_bit(unsigned long nr,
 					 volatile unsigned long *addr)
 {
-	unsigned long old, t;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-	LWSYNC_ON_SMP
-"1:"	PPC_LLARX "%0,0,%3		# test_and_clear_bit\n"
-	"andc	%1,%0,%2 \n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%1,0,%3 \n"
-	"bne-	1b"
-	ISYNC_ON_SMP
-	: "=&r" (old), "=&r" (t)
-	: "r" (mask), "r" (p)
-	: "cc", "memory");
-
-	return (old & mask) != 0;
+	return test_and_clear_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
 }
 
 static __inline__ int test_and_change_bit(unsigned long nr,
 					  volatile unsigned long *addr)
 {
-	unsigned long old, t;
-	unsigned long mask = BITOP_MASK(nr);
-	unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
-
-	__asm__ __volatile__(
-	LWSYNC_ON_SMP
-"1:"	PPC_LLARX "%0,0,%3		# test_and_change_bit\n"
-	"xor	%1,%0,%2 \n"
-	PPC405_ERR77(0,%3)
-	PPC_STLCX "%1,0,%3 \n"
-	"bne-	1b"
-	ISYNC_ON_SMP
-	: "=&r" (old), "=&r" (t)
-	: "r" (mask), "r" (p)
-	: "cc", "memory");
-
-	return (old & mask) != 0;
-}
-
-static __inline__ void set_bits(unsigned long mask, unsigned long *addr)
-{
-        unsigned long old;
-
-	__asm__ __volatile__(
-"1:"	PPC_LLARX "%0,0,%3         # set_bits\n"
-	"or	%0,%0,%2\n"
-	PPC_STLCX "%0,0,%3\n"
-	"bne-	1b"
-	: "=&r" (old), "+m" (*addr)
-	: "r" (mask), "r" (addr)
-	: "cc");
+	return test_and_change_bits(BITOP_MASK(nr), addr + BITOP_WORD(nr)) != 0;
 }
 
 #include <asm-generic/bitops/non-atomic.h>
diff --git a/arch/powerpc/include/asm/cell-regs.h b/arch/powerpc/include/asm/cell-regs.h
index fd6fd00..fdf64fd 100644
--- a/arch/powerpc/include/asm/cell-regs.h
+++ b/arch/powerpc/include/asm/cell-regs.h
@@ -303,6 +303,17 @@ struct cbe_mic_tm_regs {
 extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np);
 extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
 
+
+/* Cell page table entries */
+#define CBE_IOPTE_PP_W		0x8000000000000000ul /* protection: write */
+#define CBE_IOPTE_PP_R		0x4000000000000000ul /* protection: read */
+#define CBE_IOPTE_M		0x2000000000000000ul /* coherency required */
+#define CBE_IOPTE_SO_R		0x1000000000000000ul /* ordering: writes */
+#define CBE_IOPTE_SO_RW		0x1800000000000000ul /* ordering: r & w */
+#define CBE_IOPTE_RPN_Mask	0x07fffffffffff000ul /* RPN */
+#define CBE_IOPTE_H		0x0000000000000800ul /* cache hint */
+#define CBE_IOPTE_IOID_Mask	0x00000000000007fful /* ioid */
+
 /* some utility functions to deal with SMT */
 extern u32 cbe_get_hw_thread_id(int cpu);
 extern u32 cbe_cpu_to_node(int cpu);
diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h
index fb11b0c..a8e1844 100644
--- a/arch/powerpc/include/asm/cputhreads.h
+++ b/arch/powerpc/include/asm/cputhreads.h
@@ -5,6 +5,15 @@
 
 /*
  * Mapping of threads to cores
+ *
+ * Note: This implementation is limited to a power of 2 number of
+ * threads per core and the same number for each core in the system
+ * (though it would work if some processors had less threads as long
+ * as the CPU numbers are still allocated, just not brought offline).
+ *
+ * However, the API allows for a different implementation in the future
+ * if needed, as long as you only use the functions and not the variables
+ * directly.
  */
 
 #ifdef CONFIG_SMP
@@ -67,5 +76,12 @@ static inline int cpu_first_thread_in_core(int cpu)
 	return cpu & ~(threads_per_core - 1);
 }
 
+static inline int cpu_last_thread_in_core(int cpu)
+{
+	return cpu | (threads_per_core - 1);
+}
+
+
+
 #endif /* _ASM_POWERPC_CPUTHREADS_H */
 
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 7d2277c..9dade15 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -6,7 +6,7 @@
 #ifndef _ASM_POWERPC_DEVICE_H
 #define _ASM_POWERPC_DEVICE_H
 
-struct dma_mapping_ops;
+struct dma_map_ops;
 struct device_node;
 
 struct dev_archdata {
@@ -14,8 +14,11 @@ struct dev_archdata {
 	struct device_node	*of_node;
 
 	/* DMA operations on that device */
-	struct dma_mapping_ops	*dma_ops;
+	struct dma_map_ops	*dma_ops;
 	void			*dma_data;
+#ifdef CONFIG_SWIOTLB
+	dma_addr_t		max_direct_dma_addr;
+#endif
 };
 
 static inline void dev_archdata_set_node(struct dev_archdata *ad,
@@ -30,4 +33,7 @@ dev_archdata_get_node(const struct dev_archdata *ad)
 	return ad->of_node;
 }
 
+struct pdev_archdata {
+};
+
 #endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 0c34371..cb2ca41 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-attrs.h>
+#include <linux/dma-debug.h>
 #include <asm/io.h>
 #include <asm/swiotlb.h>
 
@@ -64,58 +65,14 @@ static inline unsigned long device_to_mask(struct device *dev)
 }
 
 /*
- * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
- */
-struct dma_mapping_ops {
-	void *		(*alloc_coherent)(struct device *dev, size_t size,
-				dma_addr_t *dma_handle, gfp_t flag);
-	void		(*free_coherent)(struct device *dev, size_t size,
-				void *vaddr, dma_addr_t dma_handle);
-	int		(*map_sg)(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction direction,
-				struct dma_attrs *attrs);
-	void		(*unmap_sg)(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction direction,
-				struct dma_attrs *attrs);
-	int		(*dma_supported)(struct device *dev, u64 mask);
-	int		(*set_dma_mask)(struct device *dev, u64 dma_mask);
-	dma_addr_t 	(*map_page)(struct device *dev, struct page *page,
-				unsigned long offset, size_t size,
-				enum dma_data_direction direction,
-				struct dma_attrs *attrs);
-	void		(*unmap_page)(struct device *dev,
-				dma_addr_t dma_address, size_t size,
-				enum dma_data_direction direction,
-				struct dma_attrs *attrs);
-	int		(*addr_needs_map)(struct device *dev, dma_addr_t addr,
-				size_t size);
-#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
-	void            (*sync_single_range_for_cpu)(struct device *hwdev,
-				dma_addr_t dma_handle, unsigned long offset,
-				size_t size,
-				enum dma_data_direction direction);
-	void            (*sync_single_range_for_device)(struct device *hwdev,
-				dma_addr_t dma_handle, unsigned long offset,
-				size_t size,
-				enum dma_data_direction direction);
-	void            (*sync_sg_for_cpu)(struct device *hwdev,
-				struct scatterlist *sg, int nelems,
-				enum dma_data_direction direction);
-	void            (*sync_sg_for_device)(struct device *hwdev,
-				struct scatterlist *sg, int nelems,
-				enum dma_data_direction direction);
-#endif
-};
-
-/*
  * Available generic sets of operations
  */
 #ifdef CONFIG_PPC64
-extern struct dma_mapping_ops dma_iommu_ops;
+extern struct dma_map_ops dma_iommu_ops;
 #endif
-extern struct dma_mapping_ops dma_direct_ops;
+extern struct dma_map_ops dma_direct_ops;
 
-static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
 	/* We don't handle the NULL dev case for ISA for now. We could
 	 * do it via an out of line call but it is not needed for now. The
@@ -128,14 +85,19 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
 	return dev->archdata.dma_ops;
 }
 
-static inline void set_dma_ops(struct device *dev, struct dma_mapping_ops *ops)
+static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
 {
 	dev->archdata.dma_ops = ops;
 }
 
+/* this will be removed soon */
+#define flush_write_buffers()
+
+#include <asm-generic/dma-mapping-common.h>
+
 static inline int dma_supported(struct device *dev, u64 mask)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
 	if (unlikely(dma_ops == NULL))
 		return 0;
@@ -149,7 +111,7 @@ static inline int dma_supported(struct device *dev, u64 mask)
 
 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
 	if (unlikely(dma_ops == NULL))
 		return -EIO;
@@ -161,262 +123,40 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
 	return 0;
 }
 
-/*
- * map_/unmap_single actually call through to map/unmap_page now that all the
- * dma_mapping_ops have been converted over. We just have to get the page and
- * offset to pass through to map_page
- */
-static inline dma_addr_t dma_map_single_attrs(struct device *dev,
-					      void *cpu_addr,
-					      size_t size,
-					      enum dma_data_direction direction,
-					      struct dma_attrs *attrs)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-
-	return dma_ops->map_page(dev, virt_to_page(cpu_addr),
-				 (unsigned long)cpu_addr % PAGE_SIZE, size,
-				 direction, attrs);
-}
-
-static inline void dma_unmap_single_attrs(struct device *dev,
-					  dma_addr_t dma_addr,
-					  size_t size,
-					  enum dma_data_direction direction,
-					  struct dma_attrs *attrs)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-
-	dma_ops->unmap_page(dev, dma_addr, size, direction, attrs);
-}
-
-static inline dma_addr_t dma_map_page_attrs(struct device *dev,
-					    struct page *page,
-					    unsigned long offset, size_t size,
-					    enum dma_data_direction direction,
-					    struct dma_attrs *attrs)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-
-	return dma_ops->map_page(dev, page, offset, size, direction, attrs);
-}
-
-static inline void dma_unmap_page_attrs(struct device *dev,
-					dma_addr_t dma_address,
-					size_t size,
-					enum dma_data_direction direction,
-					struct dma_attrs *attrs)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-
-	dma_ops->unmap_page(dev, dma_address, size, direction, attrs);
-}
-
-static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
-				   int nents, enum dma_data_direction direction,
-				   struct dma_attrs *attrs)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	return dma_ops->map_sg(dev, sg, nents, direction, attrs);
-}
-
-static inline void dma_unmap_sg_attrs(struct device *dev,
-				      struct scatterlist *sg,
-				      int nhwentries,
-				      enum dma_data_direction direction,
-				      struct dma_attrs *attrs)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs);
-}
-
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
-}
-
-static inline void dma_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_handle)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
-}
-
-static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
-					size_t size,
-					enum dma_data_direction direction)
-{
-	return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL);
-}
-
-static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-				    size_t size,
-				    enum dma_data_direction direction)
-{
-	dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL);
-}
-
-static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction direction)
-{
-	return dma_map_page_attrs(dev, page, offset, size, direction, NULL);
-}
-
-static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-				  size_t size,
-				  enum dma_data_direction direction)
-{
-	dma_unmap_page_attrs(dev, dma_address, size, direction, NULL);
-}
-
-static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
-			     int nents, enum dma_data_direction direction)
-{
-	return dma_map_sg_attrs(dev, sg, nents, direction, NULL);
-}
-
-static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-				int nhwentries,
-				enum dma_data_direction direction)
-{
-	dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
-}
-
-#ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
-static inline void dma_sync_single_for_cpu(struct device *dev,
-		dma_addr_t dma_handle, size_t size,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-
-	if (dma_ops->sync_single_range_for_cpu)
-		dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0,
-					   size, direction);
-}
-
-static inline void dma_sync_single_for_device(struct device *dev,
-		dma_addr_t dma_handle, size_t size,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-
-	if (dma_ops->sync_single_range_for_device)
-		dma_ops->sync_single_range_for_device(dev, dma_handle,
-					      0, size, direction);
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev,
-		struct scatterlist *sgl, int nents,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
+	void *cpu_addr;
 
 	BUG_ON(!dma_ops);
 
-	if (dma_ops->sync_sg_for_cpu)
-		dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction);
-}
-
-static inline void dma_sync_sg_for_device(struct device *dev,
-		struct scatterlist *sgl, int nents,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-
-	if (dma_ops->sync_sg_for_device)
-		dma_ops->sync_sg_for_device(dev, sgl, nents, direction);
-}
-
-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)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+	cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag);
 
-	BUG_ON(!dma_ops);
+	debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
 
-	if (dma_ops->sync_single_range_for_cpu)
-		dma_ops->sync_single_range_for_cpu(dev, dma_handle,
-					   offset, size, direction);
+	return cpu_addr;
 }
 
-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)
+static inline void dma_free_coherent(struct device *dev, size_t size,
+				     void *cpu_addr, dma_addr_t dma_handle)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
 	BUG_ON(!dma_ops);
 
-	if (dma_ops->sync_single_range_for_device)
-		dma_ops->sync_single_range_for_device(dev, dma_handle, offset,
-					      size, direction);
-}
-#else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */
-static inline void dma_sync_single_for_cpu(struct device *dev,
-		dma_addr_t dma_handle, size_t size,
-		enum dma_data_direction direction)
-{
-}
-
-static inline void dma_sync_single_for_device(struct device *dev,
-		dma_addr_t dma_handle, size_t size,
-		enum dma_data_direction direction)
-{
-}
-
-static inline void dma_sync_sg_for_cpu(struct device *dev,
-		struct scatterlist *sgl, int nents,
-		enum dma_data_direction direction)
-{
-}
+	debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
 
-static inline void dma_sync_sg_for_device(struct device *dev,
-		struct scatterlist *sgl, int nents,
-		enum dma_data_direction direction)
-{
+	dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
 }
 
-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)
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 {
-}
+	struct dma_map_ops *dma_ops = get_dma_ops(dev);
 
-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)
-{
-}
-#endif
+	if (dma_ops->mapping_error)
+		return dma_ops->mapping_error(dev, dma_addr);
 
-static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
 #ifdef CONFIG_PPC64
 	return (dma_addr == DMA_ERROR_CODE);
 #else
@@ -426,10 +166,12 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
 
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
-	struct dma_mapping_ops *ops = get_dma_ops(dev);
+#ifdef CONFIG_SWIOTLB
+	struct dev_archdata *sd = &dev->archdata;
 
-	if (ops->addr_needs_map && ops->addr_needs_map(dev, addr, size))
+	if (sd->max_direct_dma_addr && addr + size > sd->max_direct_dma_addr)
 		return 0;
+#endif
 
 	if (!dev->dma_mask)
 		return 0;
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h
new file mode 100644
index 0000000..6d53f31
--- /dev/null
+++ b/arch/powerpc/include/asm/exception-64e.h
@@ -0,0 +1,205 @@
+/*
+ *  Definitions for use by exception code on Book3-E
+ *
+ *  Copyright (C) 2008 Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_POWERPC_EXCEPTION_64E_H
+#define _ASM_POWERPC_EXCEPTION_64E_H
+
+/*
+ * SPRGs usage an other considerations...
+ *
+ * Since TLB miss and other standard exceptions can be interrupted by
+ * critical exceptions which can themselves be interrupted by machine
+ * checks, and since the two later can themselves cause a TLB miss when
+ * hitting the linear mapping for the kernel stacks, we need to be a bit
+ * creative on how we use SPRGs.
+ *
+ * The base idea is that we have one SRPG reserved for critical and one
+ * for machine check interrupts. Those are used to save a GPR that can
+ * then be used to get the PACA, and store as much context as we need
+ * to save in there. That includes saving the SPRGs used by the TLB miss
+ * handler for linear mapping misses and the associated SRR0/1 due to
+ * the above re-entrancy issue.
+ *
+ * So here's the current usage pattern. It's done regardless of which
+ * SPRGs are user-readable though, thus we might have to change some of
+ * this later. In order to do that more easily, we use special constants
+ * for naming them
+ *
+ * WARNING: Some of these SPRGs are user readable. We need to do something
+ * about it as some point by making sure they can't be used to leak kernel
+ * critical data
+ */
+
+
+/* We are out of SPRGs so we save some things in the PACA. The normal
+ * exception frame is smaller than the CRIT or MC one though
+ */
+#define EX_R1		(0 * 8)
+#define EX_CR		(1 * 8)
+#define EX_R10		(2 * 8)
+#define EX_R11		(3 * 8)
+#define EX_R14		(4 * 8)
+#define EX_R15		(5 * 8)
+
+/* The TLB miss exception uses different slots */
+
+#define EX_TLB_R10	( 0 * 8)
+#define EX_TLB_R11	( 1 * 8)
+#define EX_TLB_R12	( 2 * 8)
+#define EX_TLB_R13	( 3 * 8)
+#define EX_TLB_R14	( 4 * 8)
+#define EX_TLB_R15	( 5 * 8)
+#define EX_TLB_R16	( 6 * 8)
+#define EX_TLB_CR	( 7 * 8)
+#define EX_TLB_DEAR	( 8 * 8) /* Level 0 and 2 only */
+#define EX_TLB_ESR	( 9 * 8) /* Level 0 and 2 only */
+#define EX_TLB_SRR0	(10 * 8)
+#define EX_TLB_SRR1	(11 * 8)
+#define EX_TLB_MMUCR0	(12 * 8) /* Level 0 */
+#define EX_TLB_MAS1	(12 * 8) /* Level 0 */
+#define EX_TLB_MAS2	(13 * 8) /* Level 0 */
+#ifdef CONFIG_BOOK3E_MMU_TLB_STATS
+#define EX_TLB_R8	(14 * 8)
+#define EX_TLB_R9	(15 * 8)
+#define EX_TLB_LR	(16 * 8)
+#define EX_TLB_SIZE	(17 * 8)
+#else
+#define EX_TLB_SIZE	(14 * 8)
+#endif
+
+#define	START_EXCEPTION(label)						\
+	.globl exc_##label##_book3e;					\
+exc_##label##_book3e:
+
+/* TLB miss exception prolog
+ *
+ * This prolog handles re-entrancy (up to 3 levels supported in the PACA
+ * though we currently don't test for overflow). It provides you with a
+ * re-entrancy safe working space of r10...r16 and CR with r12 being used
+ * as the exception area pointer in the PACA for that level of re-entrancy
+ * and r13 containing the PACA pointer.
+ *
+ * SRR0 and SRR1 are saved, but DEAR and ESR are not, since they don't apply
+ * as-is for instruction exceptions. It's up to the actual exception code
+ * to save them as well if required.
+ */
+#define TLB_MISS_PROLOG							    \
+	mtspr	SPRN_SPRG_TLB_SCRATCH,r12;				    \
+	mfspr	r12,SPRN_SPRG_TLB_EXFRAME;				    \
+	std	r10,EX_TLB_R10(r12);					    \
+	mfcr	r10;							    \
+	std	r11,EX_TLB_R11(r12);					    \
+	mfspr	r11,SPRN_SPRG_TLB_SCRATCH;				    \
+	std	r13,EX_TLB_R13(r12);					    \
+	mfspr	r13,SPRN_SPRG_PACA;					    \
+	std	r14,EX_TLB_R14(r12);					    \
+	addi	r14,r12,EX_TLB_SIZE;					    \
+	std	r15,EX_TLB_R15(r12);					    \
+	mfspr	r15,SPRN_SRR1;						    \
+	std	r16,EX_TLB_R16(r12);					    \
+	mfspr	r16,SPRN_SRR0;						    \
+	std	r10,EX_TLB_CR(r12);					    \
+	std	r11,EX_TLB_R12(r12);					    \
+	mtspr	SPRN_SPRG_TLB_EXFRAME,r14;				    \
+	std	r15,EX_TLB_SRR1(r12);					    \
+	std	r16,EX_TLB_SRR0(r12);					    \
+	TLB_MISS_PROLOG_STATS
+
+/* And these are the matching epilogs that restores things
+ *
+ * There are 3 epilogs:
+ *
+ * - SUCCESS       : Unwinds one level
+ * - ERROR         : restore from level 0 and reset
+ * - ERROR_SPECIAL : restore from current level and reset
+ *
+ * Normal errors use ERROR, that is, they restore the initial fault context
+ * and trigger a fault. However, there is a special case for linear mapping
+ * errors. Those should basically never happen, but if they do happen, we
+ * want the error to point out the context that did that linear mapping
+ * fault, not the initial level 0 (basically, we got a bogus PGF or something
+ * like that). For userland errors on the linear mapping, there is no
+ * difference since those are always level 0 anyway
+ */
+
+#define TLB_MISS_RESTORE(freg)						    \
+	ld	r14,EX_TLB_CR(r12);					    \
+	ld	r10,EX_TLB_R10(r12);					    \
+	ld	r15,EX_TLB_SRR0(r12);					    \
+	ld	r16,EX_TLB_SRR1(r12);					    \
+	mtspr	SPRN_SPRG_TLB_EXFRAME,freg;				    \
+	ld	r11,EX_TLB_R11(r12);					    \
+	mtcr	r14;							    \
+	ld	r13,EX_TLB_R13(r12);					    \
+	ld	r14,EX_TLB_R14(r12);					    \
+	mtspr	SPRN_SRR0,r15;						    \
+	ld	r15,EX_TLB_R15(r12);					    \
+	mtspr	SPRN_SRR1,r16;						    \
+	TLB_MISS_RESTORE_STATS						    \
+	ld	r16,EX_TLB_R16(r12);					    \
+	ld	r12,EX_TLB_R12(r12);					    \
+
+#define TLB_MISS_EPILOG_SUCCESS						    \
+	TLB_MISS_RESTORE(r12)
+
+#define TLB_MISS_EPILOG_ERROR						    \
+	addi	r12,r13,PACA_EXTLB;					    \
+	TLB_MISS_RESTORE(r12)
+
+#define TLB_MISS_EPILOG_ERROR_SPECIAL					    \
+	addi	r11,r13,PACA_EXTLB;					    \
+	TLB_MISS_RESTORE(r11)
+
+#ifdef CONFIG_BOOK3E_MMU_TLB_STATS
+#define TLB_MISS_PROLOG_STATS						    \
+	mflr	r10;							    \
+	std	r8,EX_TLB_R8(r12);					    \
+	std	r9,EX_TLB_R9(r12);					    \
+	std	r10,EX_TLB_LR(r12);
+#define TLB_MISS_RESTORE_STATS					            \
+	ld	r16,EX_TLB_LR(r12);					    \
+	ld	r9,EX_TLB_R9(r12);					    \
+	ld	r8,EX_TLB_R8(r12);					    \
+	mtlr	r16;
+#define TLB_MISS_STATS_D(name)						    \
+	addi	r9,r13,MMSTAT_DSTATS+name;				    \
+	bl	.tlb_stat_inc;
+#define TLB_MISS_STATS_I(name)						    \
+	addi	r9,r13,MMSTAT_ISTATS+name;				    \
+	bl	.tlb_stat_inc;
+#define TLB_MISS_STATS_X(name)						    \
+	ld	r8,PACA_EXTLB+EX_TLB_ESR(r13);				    \
+	cmpdi	cr2,r8,-1;						    \
+	beq	cr2,61f;						    \
+	addi	r9,r13,MMSTAT_DSTATS+name;				    \
+	b	62f;							    \
+61:	addi	r9,r13,MMSTAT_ISTATS+name;				    \
+62:	bl	.tlb_stat_inc;
+#define TLB_MISS_STATS_SAVE_INFO					    \
+	std	r14,EX_TLB_ESR(r12);	/* save ESR */			    \
+
+
+#else
+#define TLB_MISS_PROLOG_STATS
+#define TLB_MISS_RESTORE_STATS
+#define TLB_MISS_STATS_D(name)
+#define TLB_MISS_STATS_I(name)
+#define TLB_MISS_STATS_X(name)
+#define TLB_MISS_STATS_Y(name)
+#define TLB_MISS_STATS_SAVE_INFO
+#endif
+
+#define SET_IVOR(vector_number, vector_offset)	\
+	li	r3,vector_offset@l; 		\
+	ori	r3,r3,interrupt_base_book3e@l;	\
+	mtspr	SPRN_IVOR##vector_number,r3;
+
+#endif /* _ASM_POWERPC_EXCEPTION_64E_H */
+
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
new file mode 100644
index 0000000..a98653b
--- /dev/null
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -0,0 +1,282 @@
+#ifndef _ASM_POWERPC_EXCEPTION_H
+#define _ASM_POWERPC_EXCEPTION_H
+/*
+ * Extracted from head_64.S
+ *
+ *  PowerPC version
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
+ *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
+ *  Adapted for Power Macintosh by Paul Mackerras.
+ *  Low-level exception handlers and MMU support
+ *  rewritten by Paul Mackerras.
+ *    Copyright (C) 1996 Paul Mackerras.
+ *
+ *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
+ *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
+ *
+ *  This file contains the low-level support and setup for the
+ *  PowerPC-64 platform, including trap and interrupt dispatch.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+/*
+ * The following macros define the code that appears as
+ * the prologue to each of the exception handlers.  They
+ * are split into two parts to allow a single kernel binary
+ * to be used for pSeries and iSeries.
+ *
+ * We make as much of the exception code common between native
+ * exception handlers (including pSeries LPAR) and iSeries LPAR
+ * implementations as possible.
+ */
+
+#define EX_R9		0
+#define EX_R10		8
+#define EX_R11		16
+#define EX_R12		24
+#define EX_R13		32
+#define EX_SRR0		40
+#define EX_DAR		48
+#define EX_DSISR	56
+#define EX_CCR		60
+#define EX_R3		64
+#define EX_LR		72
+
+/*
+ * We're short on space and time in the exception prolog, so we can't
+ * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
+ * low halfword of the address, but for Kdump we need the whole low
+ * word.
+ */
+#define LOAD_HANDLER(reg, label)					\
+	addi	reg,reg,(label)-_stext;	/* virt addr of handler ... */
+
+#define EXCEPTION_PROLOG_1(area)				\
+	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\
+	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
+	std	r10,area+EX_R10(r13);					\
+	std	r11,area+EX_R11(r13);					\
+	std	r12,area+EX_R12(r13);					\
+	mfspr	r9,SPRN_SPRG_SCRATCH0;					\
+	std	r9,area+EX_R13(r13);					\
+	mfcr	r9
+
+#define EXCEPTION_PROLOG_PSERIES_1(label)				\
+	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
+	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
+	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+	LOAD_HANDLER(r12,label)						\
+	mtspr	SPRN_SRR0,r12;						\
+	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
+	mtspr	SPRN_SRR1,r10;						\
+	rfid;								\
+	b	.	/* prevent speculative execution */
+
+#define EXCEPTION_PROLOG_PSERIES(area, label)				\
+	EXCEPTION_PROLOG_1(area);					\
+	EXCEPTION_PROLOG_PSERIES_1(label);
+
+/*
+ * The common exception prolog is used for all except a few exceptions
+ * such as a segment miss on a kernel address.  We have to be prepared
+ * to take another exception from the point where we first touch the
+ * kernel stack onwards.
+ *
+ * On entry r13 points to the paca, r9-r13 are saved in the paca,
+ * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
+ * SRR1, and relocation is on.
+ */
+#define EXCEPTION_PROLOG_COMMON(n, area)				   \
+	andi.	r10,r12,MSR_PR;		/* See if coming from user	*/ \
+	mr	r10,r1;			/* Save r1			*/ \
+	subi	r1,r1,INT_FRAME_SIZE;	/* alloc frame on kernel stack	*/ \
+	beq-	1f;							   \
+	ld	r1,PACAKSAVE(r13);	/* kernel stack to use		*/ \
+1:	cmpdi	cr1,r1,0;		/* check if r1 is in userspace	*/ \
+	bge-	cr1,2f;			/* abort if it is		*/ \
+	b	3f;							   \
+2:	li	r1,(n);			/* will be reloaded later	*/ \
+	sth	r1,PACA_TRAP_SAVE(r13);					   \
+	b	bad_stack;						   \
+3:	std	r9,_CCR(r1);		/* save CR in stackframe	*/ \
+	std	r11,_NIP(r1);		/* save SRR0 in stackframe	*/ \
+	std	r12,_MSR(r1);		/* save SRR1 in stackframe	*/ \
+	std	r10,0(r1);		/* make stack chain pointer	*/ \
+	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
+	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
+	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
+	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
+	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
+	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
+	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
+	ld	r10,area+EX_R10(r13);					   \
+	std	r9,GPR9(r1);						   \
+	std	r10,GPR10(r1);						   \
+	ld	r9,area+EX_R11(r13);	/* move r11 - r13 to stackframe	*/ \
+	ld	r10,area+EX_R12(r13);					   \
+	ld	r11,area+EX_R13(r13);					   \
+	std	r9,GPR11(r1);						   \
+	std	r10,GPR12(r1);						   \
+	std	r11,GPR13(r1);						   \
+	ld	r2,PACATOC(r13);	/* get kernel TOC into r2	*/ \
+	mflr	r9;			/* save LR in stackframe	*/ \
+	std	r9,_LINK(r1);						   \
+	mfctr	r10;			/* save CTR in stackframe	*/ \
+	std	r10,_CTR(r1);						   \
+	lbz	r10,PACASOFTIRQEN(r13);				   \
+	mfspr	r11,SPRN_XER;		/* save XER in stackframe	*/ \
+	std	r10,SOFTE(r1);						   \
+	std	r11,_XER(r1);						   \
+	li	r9,(n)+1;						   \
+	std	r9,_TRAP(r1);		/* set trap number		*/ \
+	li	r10,0;							   \
+	ld	r11,exception_marker@toc(r2);				   \
+	std	r10,RESULT(r1);		/* clear regs->result		*/ \
+	std	r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame	*/
+
+/*
+ * Exception vectors.
+ */
+#define STD_EXCEPTION_PSERIES(n, label)			\
+	. = n;						\
+	.globl label##_pSeries;				\
+label##_pSeries:					\
+	HMT_MEDIUM;					\
+	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
+#define HSTD_EXCEPTION_PSERIES(n, label)		\
+	. = n;						\
+	.globl label##_pSeries;				\
+label##_pSeries:					\
+	HMT_MEDIUM;					\
+	mtspr	SPRN_SPRG_SCRATCH0,r20;	/* save r20 */	\
+	mfspr	r20,SPRN_HSRR0;		/* copy HSRR0 to SRR0 */ \
+	mtspr	SPRN_SRR0,r20;				\
+	mfspr	r20,SPRN_HSRR1;		/* copy HSRR0 to SRR0 */ \
+	mtspr	SPRN_SRR1,r20;				\
+	mfspr	r20,SPRN_SPRG_SCRATCH0;	/* restore r20 */ \
+	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
+
+#define MASKABLE_EXCEPTION_PSERIES(n, label)				\
+	. = n;								\
+	.globl label##_pSeries;						\
+label##_pSeries:							\
+	HMT_MEDIUM;							\
+	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
+	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\
+	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
+	std	r10,PACA_EXGEN+EX_R10(r13);				\
+	lbz	r10,PACASOFTIRQEN(r13);					\
+	mfcr	r9;							\
+	cmpwi	r10,0;							\
+	beq	masked_interrupt;					\
+	mfspr	r10,SPRN_SPRG_SCRATCH0;					\
+	std	r10,PACA_EXGEN+EX_R13(r13);				\
+	std	r11,PACA_EXGEN+EX_R11(r13);				\
+	std	r12,PACA_EXGEN+EX_R12(r13);				\
+	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
+	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
+	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+	LOAD_HANDLER(r12,label##_common)				\
+	mtspr	SPRN_SRR0,r12;						\
+	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
+	mtspr	SPRN_SRR1,r10;						\
+	rfid;								\
+	b	.	/* prevent speculative execution */
+
+#ifdef CONFIG_PPC_ISERIES
+#define DISABLE_INTS				\
+	li	r11,0;				\
+	stb	r11,PACASOFTIRQEN(r13);		\
+BEGIN_FW_FTR_SECTION;				\
+	stb	r11,PACAHARDIRQEN(r13);		\
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);	\
+	TRACE_DISABLE_INTS;			\
+BEGIN_FW_FTR_SECTION;				\
+	mfmsr	r10;				\
+	ori	r10,r10,MSR_EE;			\
+	mtmsrd	r10,1;				\
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#else
+#define DISABLE_INTS				\
+	li	r11,0;				\
+	stb	r11,PACASOFTIRQEN(r13);		\
+	stb	r11,PACAHARDIRQEN(r13);		\
+	TRACE_DISABLE_INTS
+#endif /* CONFIG_PPC_ISERIES */
+
+#define ENABLE_INTS				\
+	ld	r12,_MSR(r1);			\
+	mfmsr	r11;				\
+	rlwimi	r11,r12,0,MSR_EE;		\
+	mtmsrd	r11,1
+
+#define STD_EXCEPTION_COMMON(trap, label, hdlr)		\
+	.align	7;					\
+	.globl label##_common;				\
+label##_common:						\
+	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
+	DISABLE_INTS;					\
+	bl	.save_nvgprs;				\
+	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
+	bl	hdlr;					\
+	b	.ret_from_except
+
+/*
+ * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
+ * in the idle task and therefore need the special idle handling.
+ */
+#define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr)	\
+	.align	7;					\
+	.globl label##_common;				\
+label##_common:						\
+	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
+	FINISH_NAP;					\
+	DISABLE_INTS;					\
+	bl	.save_nvgprs;				\
+	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
+	bl	hdlr;					\
+	b	.ret_from_except
+
+#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)	\
+	.align	7;					\
+	.globl label##_common;				\
+label##_common:						\
+	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
+	FINISH_NAP;					\
+	DISABLE_INTS;					\
+BEGIN_FTR_SECTION					\
+	bl	.ppc64_runlatch_on;			\
+END_FTR_SECTION_IFSET(CPU_FTR_CTRL)			\
+	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
+	bl	hdlr;					\
+	b	.ret_from_except_lite
+
+/*
+ * When the idle code in power4_idle puts the CPU into NAP mode,
+ * it has to do so in a loop, and relies on the external interrupt
+ * and decrementer interrupt entry code to get it out of the loop.
+ * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
+ * to signal that it is in the loop and needs help to get out.
+ */
+#ifdef CONFIG_PPC_970_NAP
+#define FINISH_NAP				\
+BEGIN_FTR_SECTION				\
+	clrrdi	r11,r1,THREAD_SHIFT;		\
+	ld	r9,TI_LOCAL_FLAGS(r11);		\
+	andi.	r10,r9,_TLF_NAPPING;		\
+	bnel	power4_fixup_nap;		\
+END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+#else
+#define FINISH_NAP
+#endif
+
+#endif	/* _ASM_POWERPC_EXCEPTION_H */
diff --git a/arch/powerpc/include/asm/exception.h b/arch/powerpc/include/asm/exception.h
deleted file mode 100644
index d3d4534..0000000
--- a/arch/powerpc/include/asm/exception.h
+++ /dev/null
@@ -1,279 +0,0 @@
-#ifndef _ASM_POWERPC_EXCEPTION_H
-#define _ASM_POWERPC_EXCEPTION_H
-/*
- * Extracted from head_64.S
- *
- *  PowerPC version
- *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
- *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
- *  Adapted for Power Macintosh by Paul Mackerras.
- *  Low-level exception handlers and MMU support
- *  rewritten by Paul Mackerras.
- *    Copyright (C) 1996 Paul Mackerras.
- *
- *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
- *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
- *
- *  This file contains the low-level support and setup for the
- *  PowerPC-64 platform, including trap and interrupt dispatch.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-/*
- * The following macros define the code that appears as
- * the prologue to each of the exception handlers.  They
- * are split into two parts to allow a single kernel binary
- * to be used for pSeries and iSeries.
- *
- * We make as much of the exception code common between native
- * exception handlers (including pSeries LPAR) and iSeries LPAR
- * implementations as possible.
- */
-
-#define EX_R9		0
-#define EX_R10		8
-#define EX_R11		16
-#define EX_R12		24
-#define EX_R13		32
-#define EX_SRR0		40
-#define EX_DAR		48
-#define EX_DSISR	56
-#define EX_CCR		60
-#define EX_R3		64
-#define EX_LR		72
-
-/*
- * We're short on space and time in the exception prolog, so we can't
- * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
- * low halfword of the address, but for Kdump we need the whole low
- * word.
- */
-#define LOAD_HANDLER(reg, label)					\
-	addi	reg,reg,(label)-_stext;	/* virt addr of handler ... */
-
-#define EXCEPTION_PROLOG_1(area)				\
-	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
-	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
-	std	r10,area+EX_R10(r13);					\
-	std	r11,area+EX_R11(r13);					\
-	std	r12,area+EX_R12(r13);					\
-	mfspr	r9,SPRN_SPRG1;						\
-	std	r9,area+EX_R13(r13);					\
-	mfcr	r9
-
-#define EXCEPTION_PROLOG_PSERIES(area, label)				\
-	EXCEPTION_PROLOG_1(area);					\
-	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
-	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
-	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
-	LOAD_HANDLER(r12,label)						\
-	mtspr	SPRN_SRR0,r12;						\
-	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
-	mtspr	SPRN_SRR1,r10;						\
-	rfid;								\
-	b	.	/* prevent speculative execution */
-
-/*
- * The common exception prolog is used for all except a few exceptions
- * such as a segment miss on a kernel address.  We have to be prepared
- * to take another exception from the point where we first touch the
- * kernel stack onwards.
- *
- * On entry r13 points to the paca, r9-r13 are saved in the paca,
- * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
- * SRR1, and relocation is on.
- */
-#define EXCEPTION_PROLOG_COMMON(n, area)				   \
-	andi.	r10,r12,MSR_PR;		/* See if coming from user	*/ \
-	mr	r10,r1;			/* Save r1			*/ \
-	subi	r1,r1,INT_FRAME_SIZE;	/* alloc frame on kernel stack	*/ \
-	beq-	1f;							   \
-	ld	r1,PACAKSAVE(r13);	/* kernel stack to use		*/ \
-1:	cmpdi	cr1,r1,0;		/* check if r1 is in userspace	*/ \
-	bge-	cr1,2f;			/* abort if it is		*/ \
-	b	3f;							   \
-2:	li	r1,(n);			/* will be reloaded later	*/ \
-	sth	r1,PACA_TRAP_SAVE(r13);					   \
-	b	bad_stack;						   \
-3:	std	r9,_CCR(r1);		/* save CR in stackframe	*/ \
-	std	r11,_NIP(r1);		/* save SRR0 in stackframe	*/ \
-	std	r12,_MSR(r1);		/* save SRR1 in stackframe	*/ \
-	std	r10,0(r1);		/* make stack chain pointer	*/ \
-	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
-	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
-	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
-	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
-	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
-	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
-	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
-	ld	r10,area+EX_R10(r13);					   \
-	std	r9,GPR9(r1);						   \
-	std	r10,GPR10(r1);						   \
-	ld	r9,area+EX_R11(r13);	/* move r11 - r13 to stackframe	*/ \
-	ld	r10,area+EX_R12(r13);					   \
-	ld	r11,area+EX_R13(r13);					   \
-	std	r9,GPR11(r1);						   \
-	std	r10,GPR12(r1);						   \
-	std	r11,GPR13(r1);						   \
-	ld	r2,PACATOC(r13);	/* get kernel TOC into r2	*/ \
-	mflr	r9;			/* save LR in stackframe	*/ \
-	std	r9,_LINK(r1);						   \
-	mfctr	r10;			/* save CTR in stackframe	*/ \
-	std	r10,_CTR(r1);						   \
-	lbz	r10,PACASOFTIRQEN(r13);				   \
-	mfspr	r11,SPRN_XER;		/* save XER in stackframe	*/ \
-	std	r10,SOFTE(r1);						   \
-	std	r11,_XER(r1);						   \
-	li	r9,(n)+1;						   \
-	std	r9,_TRAP(r1);		/* set trap number		*/ \
-	li	r10,0;							   \
-	ld	r11,exception_marker@toc(r2);				   \
-	std	r10,RESULT(r1);		/* clear regs->result		*/ \
-	std	r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame	*/
-
-/*
- * Exception vectors.
- */
-#define STD_EXCEPTION_PSERIES(n, label)			\
-	. = n;						\
-	.globl label##_pSeries;				\
-label##_pSeries:					\
-	HMT_MEDIUM;					\
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
-
-#define HSTD_EXCEPTION_PSERIES(n, label)		\
-	. = n;						\
-	.globl label##_pSeries;				\
-label##_pSeries:					\
-	HMT_MEDIUM;					\
-	mtspr	SPRN_SPRG1,r20;		/* save r20 */	\
-	mfspr	r20,SPRN_HSRR0;		/* copy HSRR0 to SRR0 */ \
-	mtspr	SPRN_SRR0,r20;				\
-	mfspr	r20,SPRN_HSRR1;		/* copy HSRR0 to SRR0 */ \
-	mtspr	SPRN_SRR1,r20;				\
-	mfspr	r20,SPRN_SPRG1;		/* restore r20 */ \
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
-
-
-#define MASKABLE_EXCEPTION_PSERIES(n, label)				\
-	. = n;								\
-	.globl label##_pSeries;						\
-label##_pSeries:							\
-	HMT_MEDIUM;							\
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
-	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
-	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
-	std	r10,PACA_EXGEN+EX_R10(r13);				\
-	lbz	r10,PACASOFTIRQEN(r13);					\
-	mfcr	r9;							\
-	cmpwi	r10,0;							\
-	beq	masked_interrupt;					\
-	mfspr	r10,SPRN_SPRG1;						\
-	std	r10,PACA_EXGEN+EX_R13(r13);				\
-	std	r11,PACA_EXGEN+EX_R11(r13);				\
-	std	r12,PACA_EXGEN+EX_R12(r13);				\
-	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
-	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
-	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
-	LOAD_HANDLER(r12,label##_common)				\
-	mtspr	SPRN_SRR0,r12;						\
-	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
-	mtspr	SPRN_SRR1,r10;						\
-	rfid;								\
-	b	.	/* prevent speculative execution */
-
-#ifdef CONFIG_PPC_ISERIES
-#define DISABLE_INTS				\
-	li	r11,0;				\
-	stb	r11,PACASOFTIRQEN(r13);		\
-BEGIN_FW_FTR_SECTION;				\
-	stb	r11,PACAHARDIRQEN(r13);		\
-END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES);	\
-	TRACE_DISABLE_INTS;			\
-BEGIN_FW_FTR_SECTION;				\
-	mfmsr	r10;				\
-	ori	r10,r10,MSR_EE;			\
-	mtmsrd	r10,1;				\
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#else
-#define DISABLE_INTS				\
-	li	r11,0;				\
-	stb	r11,PACASOFTIRQEN(r13);		\
-	stb	r11,PACAHARDIRQEN(r13);		\
-	TRACE_DISABLE_INTS
-#endif /* CONFIG_PPC_ISERIES */
-
-#define ENABLE_INTS				\
-	ld	r12,_MSR(r1);			\
-	mfmsr	r11;				\
-	rlwimi	r11,r12,0,MSR_EE;		\
-	mtmsrd	r11,1
-
-#define STD_EXCEPTION_COMMON(trap, label, hdlr)		\
-	.align	7;					\
-	.globl label##_common;				\
-label##_common:						\
-	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
-	DISABLE_INTS;					\
-	bl	.save_nvgprs;				\
-	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
-	bl	hdlr;					\
-	b	.ret_from_except
-
-/*
- * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
- * in the idle task and therefore need the special idle handling.
- */
-#define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr)	\
-	.align	7;					\
-	.globl label##_common;				\
-label##_common:						\
-	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
-	FINISH_NAP;					\
-	DISABLE_INTS;					\
-	bl	.save_nvgprs;				\
-	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
-	bl	hdlr;					\
-	b	.ret_from_except
-
-#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)	\
-	.align	7;					\
-	.globl label##_common;				\
-label##_common:						\
-	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
-	FINISH_NAP;					\
-	DISABLE_INTS;					\
-BEGIN_FTR_SECTION					\
-	bl	.ppc64_runlatch_on;			\
-END_FTR_SECTION_IFSET(CPU_FTR_CTRL)			\
-	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
-	bl	hdlr;					\
-	b	.ret_from_except_lite
-
-/*
- * When the idle code in power4_idle puts the CPU into NAP mode,
- * it has to do so in a loop, and relies on the external interrupt
- * and decrementer interrupt entry code to get it out of the loop.
- * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
- * to signal that it is in the loop and needs help to get out.
- */
-#ifdef CONFIG_PPC_970_NAP
-#define FINISH_NAP				\
-BEGIN_FTR_SECTION				\
-	clrrdi	r11,r1,THREAD_SHIFT;		\
-	ld	r9,TI_LOCAL_FLAGS(r11);		\
-	andi.	r10,r9,_TLF_NAPPING;		\
-	bnel	power4_fixup_nap;		\
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
-#else
-#define FINISH_NAP
-#endif
-
-#endif	/* _ASM_POWERPC_EXCEPTION_H */
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h
index 288e14d..fb3c05a 100644
--- a/arch/powerpc/include/asm/hardirq.h
+++ b/arch/powerpc/include/asm/hardirq.h
@@ -1,29 +1 @@
-#ifndef _ASM_POWERPC_HARDIRQ_H
-#define _ASM_POWERPC_HARDIRQ_H
-#ifdef __KERNEL__
-
-#include <asm/irq.h>
-#include <asm/bug.h>
-
-/* The __last_jiffy_stamp field is needed to ensure that no decrementer
- * interrupt is lost on SMP machines. Since on most CPUs it is in the same
- * cache line as local_irq_count, it is cheap to access and is also used on UP
- * for uniformity.
- */
-typedef struct {
-	unsigned int __softirq_pending;	/* set_bit is used on this */
-	unsigned int __last_jiffy_stamp;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-
-#define last_jiffy_stamp(cpu) __IRQ_STAT((cpu), __last_jiffy_stamp)
-
-static inline void ack_bad_irq(int irq)
-{
-	printk(KERN_CRIT "illegal vector %d received!\n", irq);
-	BUG();
-}
-
-#endif /* __KERNEL__ */
-#endif /* _ASM_POWERPC_HARDIRQ_H */
+#include <asm-generic/hardirq.h>
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 8b505ea..abbc2aa 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -49,8 +49,13 @@ extern void iseries_handle_interrupts(void);
 #define raw_irqs_disabled()		(local_get_flags() == 0)
 #define raw_irqs_disabled_flags(flags)	((flags) == 0)
 
+#ifdef CONFIG_PPC_BOOK3E
+#define __hard_irq_enable()	__asm__ __volatile__("wrteei 1": : :"memory");
+#define __hard_irq_disable()	__asm__ __volatile__("wrteei 0": : :"memory");
+#else
 #define __hard_irq_enable()	__mtmsrd(mfmsr() | MSR_EE, 1)
 #define __hard_irq_disable()	__mtmsrd(mfmsr() & ~MSR_EE, 1)
+#endif
 
 #define  hard_irq_disable()			\
 	do {					\
@@ -130,43 +135,43 @@ static inline int irqs_disabled_flags(unsigned long flags)
  */
 struct irq_chip;
 
-#ifdef CONFIG_PERF_COUNTERS
+#ifdef CONFIG_PERF_EVENTS
 
 #ifdef CONFIG_PPC64
-static inline unsigned long test_perf_counter_pending(void)
+static inline unsigned long test_perf_event_pending(void)
 {
 	unsigned long x;
 
 	asm volatile("lbz %0,%1(13)"
 		: "=r" (x)
-		: "i" (offsetof(struct paca_struct, perf_counter_pending)));
+		: "i" (offsetof(struct paca_struct, perf_event_pending)));
 	return x;
 }
 
-static inline void set_perf_counter_pending(void)
+static inline void set_perf_event_pending(void)
 {
 	asm volatile("stb %0,%1(13)" : :
 		"r" (1),
-		"i" (offsetof(struct paca_struct, perf_counter_pending)));
+		"i" (offsetof(struct paca_struct, perf_event_pending)));
 }
 
-static inline void clear_perf_counter_pending(void)
+static inline void clear_perf_event_pending(void)
 {
 	asm volatile("stb %0,%1(13)" : :
 		"r" (0),
-		"i" (offsetof(struct paca_struct, perf_counter_pending)));
+		"i" (offsetof(struct paca_struct, perf_event_pending)));
 }
 #endif /* CONFIG_PPC64 */
 
-#else  /* CONFIG_PERF_COUNTERS */
+#else  /* CONFIG_PERF_EVENTS */
 
-static inline unsigned long test_perf_counter_pending(void)
+static inline unsigned long test_perf_event_pending(void)
 {
 	return 0;
 }
 
-static inline void clear_perf_counter_pending(void) {}
-#endif /* CONFIG_PERF_COUNTERS */
+static inline void clear_perf_event_pending(void) {}
+#endif /* CONFIG_PERF_EVENTS */
 
 #endif	/* __KERNEL__ */
 #endif	/* _ASM_POWERPC_HW_IRQ_H */
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 7ead7c1..7464c0d 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -35,16 +35,6 @@
 #define IOMMU_PAGE_MASK       (~((1 << IOMMU_PAGE_SHIFT) - 1))
 #define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
 
-/* Cell page table entries */
-#define CBE_IOPTE_PP_W		0x8000000000000000ul /* protection: write */
-#define CBE_IOPTE_PP_R		0x4000000000000000ul /* protection: read */
-#define CBE_IOPTE_M		0x2000000000000000ul /* coherency required */
-#define CBE_IOPTE_SO_R		0x1000000000000000ul /* ordering: writes */
-#define CBE_IOPTE_SO_RW		0x1800000000000000ul /* ordering: r & w */
-#define CBE_IOPTE_RPN_Mask	0x07fffffffffff000ul /* RPN */
-#define CBE_IOPTE_H		0x0000000000000800ul /* cache hint */
-#define CBE_IOPTE_IOID_Mask	0x00000000000007fful /* ioid */
-
 /* Boot time flags */
 extern int iommu_is_off;
 extern int iommu_force_on;
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index 0a51376..bbcd1aa 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -302,7 +302,8 @@ extern void irq_free_virt(unsigned int virq, unsigned int count);
 
 /* -- OF helpers -- */
 
-/* irq_create_of_mapping - Map a hardware interrupt into linux virq space
+/**
+ * irq_create_of_mapping - Map a hardware interrupt into linux virq space
  * @controller: Device node of the interrupt controller
  * @inspec: Interrupt specifier from the device-tree
  * @intsize: Size of the interrupt specifier from the device-tree
@@ -314,8 +315,8 @@ extern void irq_free_virt(unsigned int virq, unsigned int count);
 extern unsigned int irq_create_of_mapping(struct device_node *controller,
 					  u32 *intspec, unsigned int intsize);
 
-
-/* irq_of_parse_and_map - Parse nad Map an interrupt into linux virq space
+/**
+ * irq_of_parse_and_map - Parse and Map an interrupt into linux virq space
  * @device: Device node of the device whose interrupt is to be mapped
  * @index: Index of the interrupt to map
  *
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index fddc3ed..c9c930e 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -34,7 +34,8 @@
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 
 /* We don't currently support large pages. */
-#define KVM_PAGES_PER_HPAGE (1UL << 31)
+#define KVM_NR_PAGE_SIZES	1
+#define KVM_PAGES_PER_HPAGE(x)	(1UL<<31)
 
 struct kvm;
 struct kvm_run;
@@ -153,7 +154,6 @@ struct kvm_vcpu_arch {
 	u32 pid;
 	u32 swap_pid;
 
-	u32 pvr;
 	u32 ccr0;
 	u32 ccr1;
 	u32 dbcr0;
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 11d1fc3..9efa2be 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -209,14 +209,14 @@ struct machdep_calls {
 	/*
 	 * optional PCI "hooks"
 	 */
-	/* Called in indirect_* to avoid touching devices */
-	int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
-
 	/* Called at then very end of pcibios_init() */
 	void (*pcibios_after_init)(void);
 
 #endif /* CONFIG_PPC32 */
 
+	/* Called in indirect_* to avoid touching devices */
+	int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
+
 	/* Called after PPC generic resource fixup to perform
 	   machine specific fixups */
 	void (*pcibios_fixup_resources)(struct pci_dev *);
diff --git a/arch/powerpc/include/asm/mmu-40x.h b/arch/powerpc/include/asm/mmu-40x.h
index 776f415..3491686 100644
--- a/arch/powerpc/include/asm/mmu-40x.h
+++ b/arch/powerpc/include/asm/mmu-40x.h
@@ -61,4 +61,7 @@ typedef struct {
 
 #endif /* !__ASSEMBLY__ */
 
+#define mmu_virtual_psize	MMU_PAGE_4K
+#define mmu_linear_psize	MMU_PAGE_256M
+
 #endif /* _ASM_POWERPC_MMU_40X_H_ */
diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/mmu-44x.h
index 3c86576..0372669 100644
--- a/arch/powerpc/include/asm/mmu-44x.h
+++ b/arch/powerpc/include/asm/mmu-44x.h
@@ -79,16 +79,22 @@ typedef struct {
 
 #if (PAGE_SHIFT == 12)
 #define PPC44x_TLBE_SIZE	PPC44x_TLB_4K
+#define mmu_virtual_psize	MMU_PAGE_4K
 #elif (PAGE_SHIFT == 14)
 #define PPC44x_TLBE_SIZE	PPC44x_TLB_16K
+#define mmu_virtual_psize	MMU_PAGE_16K
 #elif (PAGE_SHIFT == 16)
 #define PPC44x_TLBE_SIZE	PPC44x_TLB_64K
+#define mmu_virtual_psize	MMU_PAGE_64K
 #elif (PAGE_SHIFT == 18)
 #define PPC44x_TLBE_SIZE	PPC44x_TLB_256K
+#define mmu_virtual_psize	MMU_PAGE_256K
 #else
 #error "Unsupported PAGE_SIZE"
 #endif
 
+#define mmu_linear_psize	MMU_PAGE_256M
+
 #define PPC44x_PGD_OFF_SHIFT	(32 - PGDIR_SHIFT + PGD_T_LOG2)
 #define PPC44x_PGD_OFF_MASK_BIT	(PGDIR_SHIFT - PGD_T_LOG2)
 #define PPC44x_PTE_ADD_SHIFT	(32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2)
diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h
index 07865a3..3d11d3c 100644
--- a/arch/powerpc/include/asm/mmu-8xx.h
+++ b/arch/powerpc/include/asm/mmu-8xx.h
@@ -143,4 +143,7 @@ typedef struct {
 } mm_context_t;
 #endif /* !__ASSEMBLY__ */
 
+#define mmu_virtual_psize	MMU_PAGE_4K
+#define mmu_linear_psize	MMU_PAGE_8M
+
 #endif /* _ASM_POWERPC_MMU_8XX_H_ */
diff --git a/arch/powerpc/include/asm/mmu-book3e.h b/arch/powerpc/include/asm/mmu-book3e.h
index 7e74cff..7469581 100644
--- a/arch/powerpc/include/asm/mmu-book3e.h
+++ b/arch/powerpc/include/asm/mmu-book3e.h
@@ -38,58 +38,140 @@
 #define BOOK3E_PAGESZ_1TB	30
 #define BOOK3E_PAGESZ_2TB	31
 
-#define MAS0_TLBSEL(x)	((x << 28) & 0x30000000)
-#define MAS0_ESEL(x)	((x << 16) & 0x0FFF0000)
-#define MAS0_NV(x)	((x) & 0x00000FFF)
-
-#define MAS1_VALID 	0x80000000
-#define MAS1_IPROT	0x40000000
-#define MAS1_TID(x)	((x << 16) & 0x3FFF0000)
-#define MAS1_IND	0x00002000
-#define MAS1_TS		0x00001000
-#define MAS1_TSIZE(x)	((x << 7) & 0x00000F80)
-
-#define MAS2_EPN	0xFFFFF000
-#define MAS2_X0		0x00000040
-#define MAS2_X1		0x00000020
-#define MAS2_W		0x00000010
-#define MAS2_I		0x00000008
-#define MAS2_M		0x00000004
-#define MAS2_G		0x00000002
-#define MAS2_E		0x00000001
+/* MAS registers bit definitions */
+
+#define MAS0_TLBSEL(x)		((x << 28) & 0x30000000)
+#define MAS0_ESEL(x)		((x << 16) & 0x0FFF0000)
+#define MAS0_NV(x)		((x) & 0x00000FFF)
+#define MAS0_HES		0x00004000
+#define MAS0_WQ_ALLWAYS		0x00000000
+#define MAS0_WQ_COND		0x00001000
+#define MAS0_WQ_CLR_RSRV       	0x00002000
+
+#define MAS1_VALID		0x80000000
+#define MAS1_IPROT		0x40000000
+#define MAS1_TID(x)		((x << 16) & 0x3FFF0000)
+#define MAS1_IND		0x00002000
+#define MAS1_TS			0x00001000
+#define MAS1_TSIZE_MASK		0x00000f80
+#define MAS1_TSIZE_SHIFT	7
+#define MAS1_TSIZE(x)		((x << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK)
+
+#define MAS2_EPN		0xFFFFF000
+#define MAS2_X0			0x00000040
+#define MAS2_X1			0x00000020
+#define MAS2_W			0x00000010
+#define MAS2_I			0x00000008
+#define MAS2_M			0x00000004
+#define MAS2_G			0x00000002
+#define MAS2_E			0x00000001
 #define MAS2_EPN_MASK(size)		(~0 << (size + 10))
 #define MAS2_VAL(addr, size, flags)	((addr) & MAS2_EPN_MASK(size) | (flags))
 
-#define MAS3_RPN	0xFFFFF000
-#define MAS3_U0		0x00000200
-#define MAS3_U1		0x00000100
-#define MAS3_U2		0x00000080
-#define MAS3_U3		0x00000040
-#define MAS3_UX		0x00000020
-#define MAS3_SX		0x00000010
-#define MAS3_UW		0x00000008
-#define MAS3_SW		0x00000004
-#define MAS3_UR		0x00000002
-#define MAS3_SR		0x00000001
-
-#define MAS4_TLBSELD(x) MAS0_TLBSEL(x)
-#define MAS4_INDD	0x00008000
-#define MAS4_TSIZED(x)	MAS1_TSIZE(x)
-#define MAS4_X0D	0x00000040
-#define MAS4_X1D	0x00000020
-#define MAS4_WD		0x00000010
-#define MAS4_ID		0x00000008
-#define MAS4_MD		0x00000004
-#define MAS4_GD		0x00000002
-#define MAS4_ED		0x00000001
-
-#define MAS6_SPID0	0x3FFF0000
-#define MAS6_SPID1	0x00007FFE
-#define MAS6_ISIZE(x)	MAS1_TSIZE(x)
-#define MAS6_SAS	0x00000001
-#define MAS6_SPID	MAS6_SPID0
-
-#define MAS7_RPN	0xFFFFFFFF
+#define MAS3_RPN		0xFFFFF000
+#define MAS3_U0			0x00000200
+#define MAS3_U1			0x00000100
+#define MAS3_U2			0x00000080
+#define MAS3_U3			0x00000040
+#define MAS3_UX			0x00000020
+#define MAS3_SX			0x00000010
+#define MAS3_UW			0x00000008
+#define MAS3_SW			0x00000004
+#define MAS3_UR			0x00000002
+#define MAS3_SR			0x00000001
+#define MAS3_SPSIZE		0x0000003e
+#define MAS3_SPSIZE_SHIFT	1
+
+#define MAS4_TLBSELD(x) 	MAS0_TLBSEL(x)
+#define MAS4_INDD		0x00008000	/* Default IND */
+#define MAS4_TSIZED(x)		MAS1_TSIZE(x)
+#define MAS4_X0D		0x00000040
+#define MAS4_X1D		0x00000020
+#define MAS4_WD			0x00000010
+#define MAS4_ID			0x00000008
+#define MAS4_MD			0x00000004
+#define MAS4_GD			0x00000002
+#define MAS4_ED			0x00000001
+#define MAS4_WIMGED_MASK	0x0000001f	/* Default WIMGE */
+#define MAS4_WIMGED_SHIFT	0
+#define MAS4_VLED		MAS4_X1D	/* Default VLE */
+#define MAS4_ACMD		0x000000c0	/* Default ACM */
+#define MAS4_ACMD_SHIFT		6
+#define MAS4_TSIZED_MASK	0x00000f80	/* Default TSIZE */
+#define MAS4_TSIZED_SHIFT	7
+
+#define MAS6_SPID0		0x3FFF0000
+#define MAS6_SPID1		0x00007FFE
+#define MAS6_ISIZE(x)		MAS1_TSIZE(x)
+#define MAS6_SAS		0x00000001
+#define MAS6_SPID		MAS6_SPID0
+#define MAS6_SIND 		0x00000002	/* Indirect page */
+#define MAS6_SIND_SHIFT		1
+#define MAS6_SPID_MASK		0x3fff0000
+#define MAS6_SPID_SHIFT		16
+#define MAS6_ISIZE_MASK		0x00000f80
+#define MAS6_ISIZE_SHIFT	7
+
+#define MAS7_RPN		0xFFFFFFFF
+
+/* Bit definitions for MMUCSR0 */
+#define MMUCSR0_TLB1FI	0x00000002	/* TLB1 Flash invalidate */
+#define MMUCSR0_TLB0FI	0x00000004	/* TLB0 Flash invalidate */
+#define MMUCSR0_TLB2FI	0x00000040	/* TLB2 Flash invalidate */
+#define MMUCSR0_TLB3FI	0x00000020	/* TLB3 Flash invalidate */
+#define MMUCSR0_TLBFI	(MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
+			 MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
+#define MMUCSR0_TLB0PS	0x00000780	/* TLB0 Page Size */
+#define MMUCSR0_TLB1PS	0x00007800	/* TLB1 Page Size */
+#define MMUCSR0_TLB2PS	0x00078000	/* TLB2 Page Size */
+#define MMUCSR0_TLB3PS	0x00780000	/* TLB3 Page Size */
+
+/* TLBnCFG encoding */
+#define TLBnCFG_N_ENTRY		0x00000fff	/* number of entries */
+#define TLBnCFG_HES		0x00002000	/* HW select supported */
+#define TLBnCFG_IPROT		0x00008000	/* IPROT supported */
+#define TLBnCFG_GTWE		0x00010000	/* Guest can write */
+#define TLBnCFG_IND		0x00020000	/* IND entries supported */
+#define TLBnCFG_PT		0x00040000	/* Can load from page table */
+#define TLBnCFG_ASSOC		0xff000000	/* Associativity */
+
+/* TLBnPS encoding */
+#define TLBnPS_4K		0x00000004
+#define TLBnPS_8K		0x00000008
+#define TLBnPS_16K		0x00000010
+#define TLBnPS_32K		0x00000020
+#define TLBnPS_64K		0x00000040
+#define TLBnPS_128K		0x00000080
+#define TLBnPS_256K		0x00000100
+#define TLBnPS_512K		0x00000200
+#define TLBnPS_1M 		0x00000400
+#define TLBnPS_2M 		0x00000800
+#define TLBnPS_4M 		0x00001000
+#define TLBnPS_8M 		0x00002000
+#define TLBnPS_16M		0x00004000
+#define TLBnPS_32M		0x00008000
+#define TLBnPS_64M		0x00010000
+#define TLBnPS_128M		0x00020000
+#define TLBnPS_256M		0x00040000
+#define TLBnPS_512M		0x00080000
+#define TLBnPS_1G		0x00100000
+#define TLBnPS_2G		0x00200000
+#define TLBnPS_4G		0x00400000
+#define TLBnPS_8G		0x00800000
+#define TLBnPS_16G		0x01000000
+#define TLBnPS_32G		0x02000000
+#define TLBnPS_64G		0x04000000
+#define TLBnPS_128G		0x08000000
+#define TLBnPS_256G		0x10000000
+
+/* tlbilx action encoding */
+#define TLBILX_T_ALL			0
+#define TLBILX_T_TID			1
+#define TLBILX_T_FULLMATCH		3
+#define TLBILX_T_CLASS0			4
+#define TLBILX_T_CLASS1			5
+#define TLBILX_T_CLASS2			6
+#define TLBILX_T_CLASS3			7
 
 #ifndef __ASSEMBLY__
 
@@ -100,6 +182,34 @@ typedef struct {
 	unsigned int	active;
 	unsigned long	vdso_base;
 } mm_context_t;
+
+/* Page size definitions, common between 32 and 64-bit
+ *
+ *    shift : is the "PAGE_SHIFT" value for that page size
+ *    penc  : is the pte encoding mask
+ *
+ */
+struct mmu_psize_def
+{
+	unsigned int	shift;	/* number of bits */
+	unsigned int	enc;	/* PTE encoding */
+};
+extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
+
+/* The page sizes use the same names as 64-bit hash but are
+ * constants
+ */
+#if defined(CONFIG_PPC_4K_PAGES)
+#define mmu_virtual_psize	MMU_PAGE_4K
+#elif defined(CONFIG_PPC_64K_PAGES)
+#define mmu_virtual_psize	MMU_PAGE_64K
+#else
+#error Unsupported page size
+#endif
+
+extern int mmu_linear_psize;
+extern int mmu_vmemmap_psize;
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_MMU_BOOK3E_H_ */
diff --git a/arch/powerpc/include/asm/mmu-hash32.h b/arch/powerpc/include/asm/mmu-hash32.h
index 16b1a1e..16f513e 100644
--- a/arch/powerpc/include/asm/mmu-hash32.h
+++ b/arch/powerpc/include/asm/mmu-hash32.h
@@ -55,21 +55,25 @@ struct ppc_bat {
 
 #ifndef __ASSEMBLY__
 
-/* Hardware Page Table Entry */
+/*
+ * Hardware Page Table Entry
+ * Note that the xpn and x bitfields are used only by processors that
+ * support extended addressing; otherwise, those bits are reserved.
+ */
 struct hash_pte {
 	unsigned long v:1;	/* Entry is valid */
 	unsigned long vsid:24;	/* Virtual segment identifier */
 	unsigned long h:1;	/* Hash algorithm indicator */
 	unsigned long api:6;	/* Abbreviated page index */
 	unsigned long rpn:20;	/* Real (physical) page number */
-	unsigned long    :3;	/* Unused */
+	unsigned long xpn:3;	/* Real page number bits 0-2, optional */
 	unsigned long r:1;	/* Referenced */
 	unsigned long c:1;	/* Changed */
 	unsigned long w:1;	/* Write-thru cache mode */
 	unsigned long i:1;	/* Cache inhibited */
 	unsigned long m:1;	/* Memory coherence */
 	unsigned long g:1;	/* Guarded */
-	unsigned long  :1;	/* Unused */
+	unsigned long x:1;	/* Real page number bit 3, optional */
 	unsigned long pp:2;	/* Page protection */
 };
 
@@ -80,4 +84,10 @@ typedef struct {
 
 #endif /* !__ASSEMBLY__ */
 
+/* We happily ignore the smaller BATs on 601, we don't actually use
+ * those definitions on hash32 at the moment anyway
+ */
+#define mmu_virtual_psize	MMU_PAGE_4K
+#define mmu_linear_psize	MMU_PAGE_256M
+
 #endif /* _ASM_POWERPC_MMU_HASH32_H_ */
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 98c104a..bebe31c 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -41,6 +41,7 @@ extern char initial_stab[];
 
 #define SLB_NUM_BOLTED		3
 #define SLB_CACHE_ENTRIES	8
+#define SLB_MIN_SIZE		32
 
 /* Bits in the SLB ESID word */
 #define SLB_ESID_V		ASM_CONST(0x0000000008000000) /* valid */
@@ -139,26 +140,6 @@ struct mmu_psize_def
 #endif /* __ASSEMBLY__ */
 
 /*
- * The kernel use the constants below to index in the page sizes array.
- * The use of fixed constants for this purpose is better for performances
- * of the low level hash refill handlers.
- *
- * A non supported page size has a "shift" field set to 0
- *
- * Any new page size being implemented can get a new entry in here. Whether
- * the kernel will use it or not is a different matter though. The actual page
- * size used by hugetlbfs is not defined here and may be made variable
- */
-
-#define MMU_PAGE_4K		0	/* 4K */
-#define MMU_PAGE_64K		1	/* 64K */
-#define MMU_PAGE_64K_AP		2	/* 64K Admixed (in a 4K segment) */
-#define MMU_PAGE_1M		3	/* 1M */
-#define MMU_PAGE_16M		4	/* 16M */
-#define MMU_PAGE_16G		5	/* 16G */
-#define MMU_PAGE_COUNT		6
-
-/*
  * Segment sizes.
  * These are the values used by hardware in the B field of
  * SLB entries and the first dword of MMU hashtable entries.
@@ -296,6 +277,7 @@ extern void slb_flush_and_rebolt(void);
 extern void stab_initialize(unsigned long stab);
 
 extern void slb_vmalloc_update(void);
+extern void slb_set_size(u16 size);
 #endif /* __ASSEMBLY__ */
 
 /*
diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
index fb57ded..7ffbb65 100644
--- a/arch/powerpc/include/asm/mmu.h
+++ b/arch/powerpc/include/asm/mmu.h
@@ -17,6 +17,7 @@
 #define MMU_FTR_TYPE_40x		ASM_CONST(0x00000004)
 #define MMU_FTR_TYPE_44x		ASM_CONST(0x00000008)
 #define MMU_FTR_TYPE_FSL_E		ASM_CONST(0x00000010)
+#define MMU_FTR_TYPE_3E			ASM_CONST(0x00000020)
 
 /*
  * This is individual features
@@ -57,6 +58,15 @@
  */
 #define MMU_FTR_TLBIE_206		ASM_CONST(0x00400000)
 
+/* Enable use of TLB reservation.  Processor should support tlbsrx.
+ * instruction and MAS0[WQ].
+ */
+#define MMU_FTR_USE_TLBRSRV		ASM_CONST(0x00800000)
+
+/* Use paired MAS registers (MAS7||MAS3, etc.)
+ */
+#define MMU_FTR_USE_PAIRED_MAS		ASM_CONST(0x01000000)
+
 #ifndef __ASSEMBLY__
 #include <asm/cputable.h>
 
@@ -73,6 +83,41 @@ extern void early_init_mmu_secondary(void);
 
 #endif /* !__ASSEMBLY__ */
 
+/* The kernel use the constants below to index in the page sizes array.
+ * The use of fixed constants for this purpose is better for performances
+ * of the low level hash refill handlers.
+ *
+ * A non supported page size has a "shift" field set to 0
+ *
+ * Any new page size being implemented can get a new entry in here. Whether
+ * the kernel will use it or not is a different matter though. The actual page
+ * size used by hugetlbfs is not defined here and may be made variable
+ *
+ * Note: This array ended up being a false good idea as it's growing to the
+ * point where I wonder if we should replace it with something different,
+ * to think about, feedback welcome. --BenH.
+ */
+
+/* There are #define as they have to be used in assembly
+ *
+ * WARNING: If you change this list, make sure to update the array of
+ * names currently in arch/powerpc/mm/hugetlbpage.c or bad things will
+ * happen
+ */
+#define MMU_PAGE_4K	0
+#define MMU_PAGE_16K	1
+#define MMU_PAGE_64K	2
+#define MMU_PAGE_64K_AP	3	/* "Admixed pages" (hash64 only) */
+#define MMU_PAGE_256K	4
+#define MMU_PAGE_1M	5
+#define MMU_PAGE_8M	6
+#define MMU_PAGE_16M	7
+#define MMU_PAGE_256M	8
+#define MMU_PAGE_1G	9
+#define MMU_PAGE_16G	10
+#define MMU_PAGE_64G	11
+#define MMU_PAGE_COUNT	12
+
 
 #if defined(CONFIG_PPC_STD_MMU_64)
 /* 64-bit classic hash table MMU */
@@ -94,5 +139,6 @@ extern void early_init_mmu_secondary(void);
 #  include <asm/mmu-8xx.h>
 #endif
 
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_MMU_H_ */
diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h
index b706366..b34e94d 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -14,7 +14,6 @@
 /*
  * Most if the context management is out of line
  */
-extern void mmu_context_init(void);
 extern int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 extern void destroy_context(struct mm_struct *mm);
 
@@ -23,6 +22,12 @@ extern void switch_stab(struct task_struct *tsk, struct mm_struct *mm);
 extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm);
 extern void set_context(unsigned long id, pgd_t *pgd);
 
+#ifdef CONFIG_PPC_BOOK3S_64
+static inline void mmu_context_init(void) { }
+#else
+extern void mmu_context_init(void);
+#endif
+
 /*
  * switch_mm is the entry point called from the architecture independent
  * code in kernel/sched.c
@@ -38,6 +43,10 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 	tsk->thread.pgdir = next->pgd;
 #endif /* CONFIG_PPC32 */
 
+	/* 64-bit Book3E keeps track of current PGD in the PACA */
+#ifdef CONFIG_PPC_BOOK3E_64
+	get_paca()->pgd = next->pgd;
+#endif
 	/* Nothing else to do if we aren't actually switching */
 	if (prev == next)
 		return;
@@ -84,6 +93,10 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
 static inline void enter_lazy_tlb(struct mm_struct *mm,
 				  struct task_struct *tsk)
 {
+	/* 64-bit Book3E keeps track of current PGD in the PACA */
+#ifdef CONFIG_PPC_BOOK3E_64
+	get_paca()->pgd = NULL;
+#endif
 }
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h
index efde5ac..6c587ed 100644
--- a/arch/powerpc/include/asm/nvram.h
+++ b/arch/powerpc/include/asm/nvram.h
@@ -107,6 +107,9 @@ extern void	pmac_xpram_write(int xpaddr, u8 data);
 /* Synchronize NVRAM */
 extern void	nvram_sync(void);
 
+/* Determine NVRAM size */
+extern ssize_t nvram_get_size(void);
+
 /* Normal access to NVRAM */
 extern unsigned char nvram_read_byte(int i);
 extern void nvram_write_byte(unsigned char c, int i);
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index c8a3cbf..7d8514c 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -14,9 +14,11 @@
 #define _ASM_POWERPC_PACA_H
 #ifdef __KERNEL__
 
-#include	<asm/types.h>
-#include	<asm/lppaca.h>
-#include	<asm/mmu.h>
+#include <asm/types.h>
+#include <asm/lppaca.h>
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/exception-64e.h>
 
 register struct paca_struct *local_paca asm("r13");
 
@@ -91,6 +93,21 @@ struct paca_struct {
 	u16 slb_cache[SLB_CACHE_ENTRIES];
 #endif /* CONFIG_PPC_STD_MMU_64 */
 
+#ifdef CONFIG_PPC_BOOK3E
+	pgd_t *pgd;			/* Current PGD */
+	pgd_t *kernel_pgd;		/* Kernel PGD */
+	u64 exgen[8] __attribute__((aligned(0x80)));
+	u64 extlb[EX_TLB_SIZE*3] __attribute__((aligned(0x80)));
+	u64 exmc[8];		/* used for machine checks */
+	u64 excrit[8];		/* used for crit interrupts */
+	u64 exdbg[8];		/* used for debug interrupts */
+
+	/* Kernel stack pointers for use by special exceptions */
+	void *mc_kstack;
+	void *crit_kstack;
+	void *dbg_kstack;
+#endif /* CONFIG_PPC_BOOK3E */
+
 	mm_context_t context;
 
 	/*
@@ -105,7 +122,7 @@ struct paca_struct {
 	u8 soft_enabled;		/* irq soft-enable flag */
 	u8 hard_enabled;		/* set if irqs are enabled in MSR */
 	u8 io_sync;			/* writel() needs spin_unlock sync */
-	u8 perf_counter_pending;	/* PM interrupt while soft-disabled */
+	u8 perf_event_pending;		/* PM interrupt while soft-disabled */
 
 	/* Stuff for accurate time accounting */
 	u64 user_time;			/* accumulated usermode TB ticks */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 4940662..ff24254 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -139,7 +139,11 @@ extern phys_addr_t kernstart_addr;
  * Don't compare things with KERNELBASE or PAGE_OFFSET to test for
  * "kernelness", use is_kernel_addr() - it should do what you want.
  */
+#ifdef CONFIG_PPC_BOOK3E_64
+#define is_kernel_addr(x)	((x) >= 0x8000000000000000ul)
+#else
 #define is_kernel_addr(x)	((x) >= PAGE_OFFSET)
+#endif
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index 5817a3b..3f17b83 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -135,12 +135,22 @@ extern void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
 #endif /* __ASSEMBLY__ */
 #else
 #define slice_init()
+#ifdef CONFIG_PPC_STD_MMU_64
 #define get_slice_psize(mm, addr)	((mm)->context.user_psize)
 #define slice_set_user_psize(mm, psize)		\
 do {						\
 	(mm)->context.user_psize = (psize);	\
 	(mm)->context.sllp = SLB_VSID_USER | mmu_psize_defs[(psize)].sllp; \
 } while (0)
+#else /* CONFIG_PPC_STD_MMU_64 */
+#ifdef CONFIG_PPC_64K_PAGES
+#define get_slice_psize(mm, addr)	MMU_PAGE_64K
+#else /* CONFIG_PPC_64K_PAGES */
+#define get_slice_psize(mm, addr)	MMU_PAGE_4K
+#endif /* !CONFIG_PPC_64K_PAGES */
+#define slice_set_user_psize(mm, psize)	do { BUG(); } while(0)
+#endif /* !CONFIG_PPC_STD_MMU_64 */
+
 #define slice_set_range_psize(mm, start, len, psize)	\
 	slice_set_user_psize((mm), (psize))
 #define slice_mm_new_context(mm)	1
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 4c61fa0..76e1f31 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -77,9 +77,7 @@ struct pci_controller {
 
 	int first_busno;
 	int last_busno;
-#ifndef CONFIG_PPC64
 	int self_busno;
-#endif
 
 	void __iomem *io_base_virt;
 #ifdef CONFIG_PPC64
@@ -104,7 +102,6 @@ struct pci_controller {
 	unsigned int __iomem *cfg_addr;
 	void __iomem *cfg_data;
 
-#ifndef CONFIG_PPC64
 	/*
 	 * Used for variants of PCI indirect handling and possible quirks:
 	 *  SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
@@ -128,7 +125,6 @@ struct pci_controller {
 #define PPC_INDIRECT_TYPE_BIG_ENDIAN		0x00000010
 #define PPC_INDIRECT_TYPE_BROKEN_MRM		0x00000020
 	u32 indirect_type;
-#endif	/* !CONFIG_PPC64 */
 	/* Currently, we limit ourselves to 1 IO range and 3 mem
 	 * ranges since the common pci_bus structure can't handle more
 	 */
@@ -146,21 +142,6 @@ struct pci_controller {
 #endif	/* CONFIG_PPC64 */
 };
 
-#ifndef CONFIG_PPC64
-
-static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
-{
-	return bus->sysdata;
-}
-
-static inline int isa_vaddr_is_ioport(void __iomem *address)
-{
-	/* No specific ISA handling on ppc32 at this stage, it
-	 * all goes through PCI
-	 */
-	return 0;
-}
-
 /* These are used for config access before all the PCI probing
    has been done. */
 extern int early_read_config_byte(struct pci_controller *hose, int bus,
@@ -182,6 +163,22 @@ extern int early_find_capability(struct pci_controller *hose, int bus,
 extern void setup_indirect_pci(struct pci_controller* hose,
 			       resource_size_t cfg_addr,
 			       resource_size_t cfg_data, u32 flags);
+
+#ifndef CONFIG_PPC64
+
+static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
+{
+	return bus->sysdata;
+}
+
+static inline int isa_vaddr_is_ioport(void __iomem *address)
+{
+	/* No specific ISA handling on ppc32 at this stage, it
+	 * all goes through PCI
+	 */
+	return 0;
+}
+
 #else	/* CONFIG_PPC64 */
 
 /*
@@ -284,11 +281,6 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
 extern int pcibios_unmap_io_space(struct pci_bus *bus);
 extern int pcibios_map_io_space(struct pci_bus *bus);
 
-/* Return values for ppc_md.pci_probe_mode function */
-#define PCI_PROBE_NONE		-1	/* Don't look at this bus at all */
-#define PCI_PROBE_NORMAL	0	/* Do normal PCI probing */
-#define PCI_PROBE_DEVTREE	1	/* Instantiate from device tree */
-
 #ifdef CONFIG_NUMA
 #define PHB_SET_NODE(PHB, NODE)		((PHB)->node = (NODE))
 #else
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index d9483c5..b5ea626 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -22,6 +22,11 @@
 
 #include <asm-generic/pci-dma-compat.h>
 
+/* Return values for ppc_md.pci_probe_mode function */
+#define PCI_PROBE_NONE		-1	/* Don't look at this bus at all */
+#define PCI_PROBE_NORMAL	0	/* Do normal PCI probing */
+#define PCI_PROBE_DEVTREE	1	/* Instantiate from device tree */
+
 #define PCIBIOS_MIN_IO		0x1000
 #define PCIBIOS_MIN_MEM		0x10000000
 
@@ -40,7 +45,6 @@ struct pci_dev;
  */
 #define pcibios_assign_all_busses() \
 	(ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
-#define pcibios_scan_all_fns(a, b)	0
 
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
@@ -61,8 +65,8 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 }
 
 #ifdef CONFIG_PCI
-extern void set_pci_dma_ops(struct dma_mapping_ops *dma_ops);
-extern struct dma_mapping_ops *get_pci_dma_ops(void);
+extern void set_pci_dma_ops(struct dma_map_ops *dma_ops);
+extern struct dma_map_ops *get_pci_dma_ops(void);
 #else	/* CONFIG_PCI */
 #define set_pci_dma_ops(d)
 #define get_pci_dma_ops()	NULL
@@ -228,6 +232,8 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
 
 extern void pcibios_setup_bus_devices(struct pci_bus *bus);
 extern void pcibios_setup_bus_self(struct pci_bus *bus);
+extern void pcibios_setup_phb_io_space(struct pci_controller *hose);
+extern void pcibios_scan_phb(struct pci_controller *hose, void *sysdata);
 
 #endif	/* __KERNEL__ */
 #endif /* __ASM_POWERPC_PCI_H */
diff --git a/arch/powerpc/include/asm/perf_counter.h b/arch/powerpc/include/asm/perf_counter.h
deleted file mode 100644
index 0ea0639..0000000
--- a/arch/powerpc/include/asm/perf_counter.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Performance counter support - PowerPC-specific definitions.
- *
- * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/types.h>
-
-#include <asm/hw_irq.h>
-
-#define MAX_HWCOUNTERS		8
-#define MAX_EVENT_ALTERNATIVES	8
-#define MAX_LIMITED_HWCOUNTERS	2
-
-/*
- * This struct provides the constants and functions needed to
- * describe the PMU on a particular POWER-family CPU.
- */
-struct power_pmu {
-	const char	*name;
-	int		n_counter;
-	int		max_alternatives;
-	unsigned long	add_fields;
-	unsigned long	test_adder;
-	int		(*compute_mmcr)(u64 events[], int n_ev,
-				unsigned int hwc[], unsigned long mmcr[]);
-	int		(*get_constraint)(u64 event, unsigned long *mskp,
-				unsigned long *valp);
-	int		(*get_alternatives)(u64 event, unsigned int flags,
-				u64 alt[]);
-	void		(*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
-	int		(*limited_pmc_event)(u64 event);
-	u32		flags;
-	int		n_generic;
-	int		*generic_events;
-	int		(*cache_events)[PERF_COUNT_HW_CACHE_MAX]
-			       [PERF_COUNT_HW_CACHE_OP_MAX]
-			       [PERF_COUNT_HW_CACHE_RESULT_MAX];
-};
-
-/*
- * Values for power_pmu.flags
- */
-#define PPMU_LIMITED_PMC5_6	1	/* PMC5/6 have limited function */
-#define PPMU_ALT_SIPR		2	/* uses alternate posn for SIPR/HV */
-
-/*
- * Values for flags to get_alternatives()
- */
-#define PPMU_LIMITED_PMC_OK	1	/* can put this on a limited PMC */
-#define PPMU_LIMITED_PMC_REQD	2	/* have to put this on a limited PMC */
-#define PPMU_ONLY_COUNT_RUN	4	/* only counting in run state */
-
-extern int register_power_pmu(struct power_pmu *);
-
-struct pt_regs;
-extern unsigned long perf_misc_flags(struct pt_regs *regs);
-extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
-
-#define PERF_COUNTER_INDEX_OFFSET	1
-
-/*
- * Only override the default definitions in include/linux/perf_counter.h
- * if we have hardware PMU support.
- */
-#ifdef CONFIG_PPC_PERF_CTRS
-#define perf_misc_flags(regs)	perf_misc_flags(regs)
-#endif
-
-/*
- * The power_pmu.get_constraint function returns a 32/64-bit value and
- * a 32/64-bit mask that express the constraints between this event and
- * other events.
- *
- * The value and mask are divided up into (non-overlapping) bitfields
- * of three different types:
- *
- * Select field: this expresses the constraint that some set of bits
- * in MMCR* needs to be set to a specific value for this event.  For a
- * select field, the mask contains 1s in every bit of the field, and
- * the value contains a unique value for each possible setting of the
- * MMCR* bits.  The constraint checking code will ensure that two events
- * that set the same field in their masks have the same value in their
- * value dwords.
- *
- * Add field: this expresses the constraint that there can be at most
- * N events in a particular class.  A field of k bits can be used for
- * N <= 2^(k-1) - 1.  The mask has the most significant bit of the field
- * set (and the other bits 0), and the value has only the least significant
- * bit of the field set.  In addition, the 'add_fields' and 'test_adder'
- * in the struct power_pmu for this processor come into play.  The
- * add_fields value contains 1 in the LSB of the field, and the
- * test_adder contains 2^(k-1) - 1 - N in the field.
- *
- * NAND field: this expresses the constraint that you may not have events
- * in all of a set of classes.  (For example, on PPC970, you can't select
- * events from the FPU, ISU and IDU simultaneously, although any two are
- * possible.)  For N classes, the field is N+1 bits wide, and each class
- * is assigned one bit from the least-significant N bits.  The mask has
- * only the most-significant bit set, and the value has only the bit
- * for the event's class set.  The test_adder has the least significant
- * bit set in the field.
- *
- * If an event is not subject to the constraint expressed by a particular
- * field, then it will have 0 in both the mask and value for that field.
- */
diff --git a/arch/powerpc/include/asm/perf_event.h b/arch/powerpc/include/asm/perf_event.h
new file mode 100644
index 0000000..2499aaa
--- /dev/null
+++ b/arch/powerpc/include/asm/perf_event.h
@@ -0,0 +1,110 @@
+/*
+ * Performance event support - PowerPC-specific definitions.
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/types.h>
+
+#include <asm/hw_irq.h>
+
+#define MAX_HWEVENTS		8
+#define MAX_EVENT_ALTERNATIVES	8
+#define MAX_LIMITED_HWEVENTS	2
+
+/*
+ * This struct provides the constants and functions needed to
+ * describe the PMU on a particular POWER-family CPU.
+ */
+struct power_pmu {
+	const char	*name;
+	int		n_event;
+	int		max_alternatives;
+	unsigned long	add_fields;
+	unsigned long	test_adder;
+	int		(*compute_mmcr)(u64 events[], int n_ev,
+				unsigned int hwc[], unsigned long mmcr[]);
+	int		(*get_constraint)(u64 event_id, unsigned long *mskp,
+				unsigned long *valp);
+	int		(*get_alternatives)(u64 event_id, unsigned int flags,
+				u64 alt[]);
+	void		(*disable_pmc)(unsigned int pmc, unsigned long mmcr[]);
+	int		(*limited_pmc_event)(u64 event_id);
+	u32		flags;
+	int		n_generic;
+	int		*generic_events;
+	int		(*cache_events)[PERF_COUNT_HW_CACHE_MAX]
+			       [PERF_COUNT_HW_CACHE_OP_MAX]
+			       [PERF_COUNT_HW_CACHE_RESULT_MAX];
+};
+
+/*
+ * Values for power_pmu.flags
+ */
+#define PPMU_LIMITED_PMC5_6	1	/* PMC5/6 have limited function */
+#define PPMU_ALT_SIPR		2	/* uses alternate posn for SIPR/HV */
+
+/*
+ * Values for flags to get_alternatives()
+ */
+#define PPMU_LIMITED_PMC_OK	1	/* can put this on a limited PMC */
+#define PPMU_LIMITED_PMC_REQD	2	/* have to put this on a limited PMC */
+#define PPMU_ONLY_COUNT_RUN	4	/* only counting in run state */
+
+extern int register_power_pmu(struct power_pmu *);
+
+struct pt_regs;
+extern unsigned long perf_misc_flags(struct pt_regs *regs);
+extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
+
+#define PERF_EVENT_INDEX_OFFSET	1
+
+/*
+ * Only override the default definitions in include/linux/perf_event.h
+ * if we have hardware PMU support.
+ */
+#ifdef CONFIG_PPC_PERF_CTRS
+#define perf_misc_flags(regs)	perf_misc_flags(regs)
+#endif
+
+/*
+ * The power_pmu.get_constraint function returns a 32/64-bit value and
+ * a 32/64-bit mask that express the constraints between this event_id and
+ * other events.
+ *
+ * The value and mask are divided up into (non-overlapping) bitfields
+ * of three different types:
+ *
+ * Select field: this expresses the constraint that some set of bits
+ * in MMCR* needs to be set to a specific value for this event_id.  For a
+ * select field, the mask contains 1s in every bit of the field, and
+ * the value contains a unique value for each possible setting of the
+ * MMCR* bits.  The constraint checking code will ensure that two events
+ * that set the same field in their masks have the same value in their
+ * value dwords.
+ *
+ * Add field: this expresses the constraint that there can be at most
+ * N events in a particular class.  A field of k bits can be used for
+ * N <= 2^(k-1) - 1.  The mask has the most significant bit of the field
+ * set (and the other bits 0), and the value has only the least significant
+ * bit of the field set.  In addition, the 'add_fields' and 'test_adder'
+ * in the struct power_pmu for this processor come into play.  The
+ * add_fields value contains 1 in the LSB of the field, and the
+ * test_adder contains 2^(k-1) - 1 - N in the field.
+ *
+ * NAND field: this expresses the constraint that you may not have events
+ * in all of a set of classes.  (For example, on PPC970, you can't select
+ * events from the FPU, ISU and IDU simultaneously, although any two are
+ * possible.)  For N classes, the field is N+1 bits wide, and each class
+ * is assigned one bit from the least-significant N bits.  The mask has
+ * only the most-significant bit set, and the value has only the bit
+ * for the event_id's class set.  The test_adder has the least significant
+ * bit set in the field.
+ *
+ * If an event_id is not subject to the constraint expressed by a particular
+ * field, then it will have 0 in both the mask and value for that field.
+ */
diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h
index 1730e5e..f2e812d 100644
--- a/arch/powerpc/include/asm/pgalloc.h
+++ b/arch/powerpc/include/asm/pgalloc.h
@@ -4,6 +4,15 @@
 
 #include <linux/mm.h>
 
+#ifdef CONFIG_PPC_BOOK3E
+extern void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address);
+#else /* CONFIG_PPC_BOOK3E */
+static inline void tlb_flush_pgtable(struct mmu_gather *tlb,
+				     unsigned long address)
+{
+}
+#endif /* !CONFIG_PPC_BOOK3E */
+
 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 {
 	free_page((unsigned long)pte);
@@ -19,7 +28,12 @@ typedef struct pgtable_free {
 	unsigned long val;
 } pgtable_free_t;
 
-#define PGF_CACHENUM_MASK	0x7
+/* This needs to be big enough to allow for MMU_PAGE_COUNT + 2 to be stored
+ * and small enough to fit in the low bits of any naturally aligned page
+ * table cache entry. Arbitrarily set to 0x1f, that should give us some
+ * room to grow
+ */
+#define PGF_CACHENUM_MASK	0x1f
 
 static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
 						unsigned long mask)
@@ -35,19 +49,27 @@ static inline pgtable_free_t pgtable_free_cache(void *p, int cachenum,
 #include <asm/pgalloc-32.h>
 #endif
 
-extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
-
 #ifdef CONFIG_SMP
-#define __pte_free_tlb(tlb,ptepage,address)		\
-do { \
-	pgtable_page_dtor(ptepage); \
-	pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
-					PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
-} while (0)
-#else
-#define __pte_free_tlb(tlb, pte, address)	pte_free((tlb)->mm, (pte))
-#endif
+extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
+extern void pte_free_finish(void);
+#else /* CONFIG_SMP */
+static inline void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf)
+{
+	pgtable_free(pgf);
+}
+static inline void pte_free_finish(void) { }
+#endif /* !CONFIG_SMP */
 
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
+				  unsigned long address)
+{
+	pgtable_free_t pgf = pgtable_free_cache(page_address(ptepage),
+						PTE_NONCACHE_NUM,
+						PTE_TABLE_SIZE-1);
+	tlb_flush_pgtable(tlb, address);
+	pgtable_page_dtor(ptepage);
+	pgtable_free_tlb(tlb, pgf);
+}
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_PGALLOC_H */
diff --git a/arch/powerpc/include/asm/pgtable-ppc32.h b/arch/powerpc/include/asm/pgtable-ppc32.h
index c9ff9d7..55646ad 100644
--- a/arch/powerpc/include/asm/pgtable-ppc32.h
+++ b/arch/powerpc/include/asm/pgtable-ppc32.h
@@ -111,6 +111,8 @@ extern int icache_44x_need_flush;
 #include <asm/pte-40x.h>
 #elif defined(CONFIG_44x)
 #include <asm/pte-44x.h>
+#elif defined(CONFIG_FSL_BOOKE) && defined(CONFIG_PTE_64BIT)
+#include <asm/pte-book3e.h>
 #elif defined(CONFIG_FSL_BOOKE)
 #include <asm/pte-fsl-booke.h>
 #elif defined(CONFIG_8xx)
@@ -186,7 +188,7 @@ static inline unsigned long pte_update(pte_t *p,
 #endif /* !PTE_ATOMIC_UPDATES */
 
 #ifdef CONFIG_44x
-	if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+	if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
 		icache_44x_need_flush = 1;
 #endif
 	return old;
@@ -217,7 +219,7 @@ static inline unsigned long long pte_update(pte_t *p,
 #endif /* !PTE_ATOMIC_UPDATES */
 
 #ifdef CONFIG_44x
-	if ((old & _PAGE_USER) && (old & _PAGE_HWEXEC))
+	if ((old & _PAGE_USER) && (old & _PAGE_EXEC))
 		icache_44x_need_flush = 1;
 #endif
 	return old;
@@ -267,8 +269,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
 {
 	unsigned long bits = pte_val(entry) &
-		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
-		 _PAGE_HWEXEC | _PAGE_EXEC);
+		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
 	pte_update(ptep, 0, bits);
 }
 
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
index 6cc085b..90533dd 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
@@ -10,10 +10,10 @@
 #define PGD_INDEX_SIZE  4
 
 #ifndef __ASSEMBLY__
-
 #define PTE_TABLE_SIZE	(sizeof(real_pte_t) << PTE_INDEX_SIZE)
 #define PMD_TABLE_SIZE	(sizeof(pmd_t) << PMD_INDEX_SIZE)
 #define PGD_TABLE_SIZE	(sizeof(pgd_t) << PGD_INDEX_SIZE)
+#endif	/* __ASSEMBLY__ */
 
 #define PTRS_PER_PTE	(1 << PTE_INDEX_SIZE)
 #define PTRS_PER_PMD	(1 << PMD_INDEX_SIZE)
@@ -32,8 +32,6 @@
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
-#endif	/* __ASSEMBLY__ */
-
 /* Bits to mask out from a PMD to get to the PTE page */
 #define PMD_MASKED_BITS		0x1ff
 /* Bits to mask out from a PGD/PUD to get to the PMD page */
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 8cd083c..806abe7 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -5,11 +5,6 @@
  * the ppc64 hashed page table.
  */
 
-#ifndef __ASSEMBLY__
-#include <linux/stddef.h>
-#include <asm/tlbflush.h>
-#endif /* __ASSEMBLY__ */
-
 #ifdef CONFIG_PPC_64K_PAGES
 #include <asm/pgtable-ppc64-64k.h>
 #else
@@ -38,26 +33,47 @@
 #endif
 
 /*
- * Define the address range of the vmalloc VM area.
+ * Define the address range of the kernel non-linear virtual area
+ */
+
+#ifdef CONFIG_PPC_BOOK3E
+#define KERN_VIRT_START ASM_CONST(0x8000000000000000)
+#else
+#define KERN_VIRT_START ASM_CONST(0xD000000000000000)
+#endif
+#define KERN_VIRT_SIZE	PGTABLE_RANGE
+
+/*
+ * The vmalloc space starts at the beginning of that region, and
+ * occupies half of it on hash CPUs and a quarter of it on Book3E
+ * (we keep a quarter for the virtual memmap)
  */
-#define VMALLOC_START ASM_CONST(0xD000000000000000)
-#define VMALLOC_SIZE  (PGTABLE_RANGE >> 1)
-#define VMALLOC_END   (VMALLOC_START + VMALLOC_SIZE)
+#define VMALLOC_START	KERN_VIRT_START
+#ifdef CONFIG_PPC_BOOK3E
+#define VMALLOC_SIZE	(KERN_VIRT_SIZE >> 2)
+#else
+#define VMALLOC_SIZE	(KERN_VIRT_SIZE >> 1)
+#endif
+#define VMALLOC_END	(VMALLOC_START + VMALLOC_SIZE)
 
 /*
- * Define the address ranges for MMIO and IO space :
+ * The second half of the kernel virtual space is used for IO mappings,
+ * it's itself carved into the PIO region (ISA and PHB IO space) and
+ * the ioremap space
  *
- *  ISA_IO_BASE = VMALLOC_END, 64K reserved area
+ *  ISA_IO_BASE = KERN_IO_START, 64K reserved area
  *  PHB_IO_BASE = ISA_IO_BASE + 64K to ISA_IO_BASE + 2G, PHB IO spaces
  * IOREMAP_BASE = ISA_IO_BASE + 2G to VMALLOC_START + PGTABLE_RANGE
  */
+#define KERN_IO_START	(KERN_VIRT_START + (KERN_VIRT_SIZE >> 1))
 #define FULL_IO_SIZE	0x80000000ul
-#define  ISA_IO_BASE	(VMALLOC_END)
-#define  ISA_IO_END	(VMALLOC_END + 0x10000ul)
+#define  ISA_IO_BASE	(KERN_IO_START)
+#define  ISA_IO_END	(KERN_IO_START + 0x10000ul)
 #define  PHB_IO_BASE	(ISA_IO_END)
-#define  PHB_IO_END	(VMALLOC_END + FULL_IO_SIZE)
+#define  PHB_IO_END	(KERN_IO_START + FULL_IO_SIZE)
 #define IOREMAP_BASE	(PHB_IO_END)
-#define IOREMAP_END	(VMALLOC_START + PGTABLE_RANGE)
+#define IOREMAP_END	(KERN_VIRT_START + KERN_VIRT_SIZE)
+
 
 /*
  * Region IDs
@@ -68,23 +84,32 @@
 
 #define VMALLOC_REGION_ID	(REGION_ID(VMALLOC_START))
 #define KERNEL_REGION_ID	(REGION_ID(PAGE_OFFSET))
-#define VMEMMAP_REGION_ID	(0xfUL)
+#define VMEMMAP_REGION_ID	(0xfUL)	/* Server only */
 #define USER_REGION_ID		(0UL)
 
 /*
- * Defines the address of the vmemap area, in its own region
+ * Defines the address of the vmemap area, in its own region on
+ * hash table CPUs and after the vmalloc space on Book3E
  */
+#ifdef CONFIG_PPC_BOOK3E
+#define VMEMMAP_BASE		VMALLOC_END
+#define VMEMMAP_END		KERN_IO_START
+#else
 #define VMEMMAP_BASE		(VMEMMAP_REGION_ID << REGION_SHIFT)
+#endif
 #define vmemmap			((struct page *)VMEMMAP_BASE)
 
 
 /*
  * Include the PTE bits definitions
  */
+#ifdef CONFIG_PPC_BOOK3S
 #include <asm/pte-hash64.h>
+#else
+#include <asm/pte-book3e.h>
+#endif
 #include <asm/pte-common.h>
 
-
 #ifdef CONFIG_PPC_MM_SLICES
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
@@ -92,6 +117,9 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/stddef.h>
+#include <asm/tlbflush.h>
+
 /*
  * This is the default implementation of various PTE accessors, it's
  * used in all cases except Book3S with 64K pages where we have a
@@ -285,8 +313,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
 static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
 {
 	unsigned long bits = pte_val(entry) &
-		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW |
-		 _PAGE_EXEC | _PAGE_HWEXEC);
+		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
 
 #ifdef PTE_ATOMIC_UPDATES
 	unsigned long old, tmp;
diff --git a/arch/powerpc/include/asm/pmc.h b/arch/powerpc/include/asm/pmc.h
index d6a616a..ccc68b5 100644
--- a/arch/powerpc/include/asm/pmc.h
+++ b/arch/powerpc/include/asm/pmc.h
@@ -27,10 +27,22 @@ extern perf_irq_t perf_irq;
 
 int reserve_pmc_hardware(perf_irq_t new_perf_irq);
 void release_pmc_hardware(void);
+void ppc_enable_pmcs(void);
 
 #ifdef CONFIG_PPC64
-void power4_enable_pmcs(void);
-void pasemi_enable_pmcs(void);
+#include <asm/lppaca.h>
+
+static inline void ppc_set_pmu_inuse(int inuse)
+{
+	get_lppaca()->pmcregs_in_use = inuse;
+}
+
+extern void power4_enable_pmcs(void);
+
+#else /* CONFIG_PPC64 */
+
+static inline void ppc_set_pmu_inuse(int inuse) { }
+
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index b74f16d..ef9aa84 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -48,6 +48,8 @@
 #define PPC_INST_TLBIE			0x7c000264
 #define PPC_INST_TLBILX			0x7c000024
 #define PPC_INST_WAIT			0x7c00007c
+#define PPC_INST_TLBIVAX		0x7c000624
+#define PPC_INST_TLBSRX_DOT		0x7c0006a5
 
 /* macros to insert fields into opcodes */
 #define __PPC_RA(a)	(((a) & 0x1f) << 16)
@@ -76,6 +78,10 @@
 					__PPC_WC(w))
 #define PPC_TLBIE(lp,a) 	stringify_in_c(.long PPC_INST_TLBIE | \
 					       __PPC_RB(a) | __PPC_RS(lp))
+#define PPC_TLBSRX_DOT(a,b)	stringify_in_c(.long PPC_INST_TLBSRX_DOT | \
+					__PPC_RA(a) | __PPC_RB(b))
+#define PPC_TLBIVAX(a,b)	stringify_in_c(.long PPC_INST_TLBIVAX | \
+					__PPC_RA(a) | __PPC_RB(b))
 
 /*
  * Define what the VSX XX1 form instructions will look like, then add
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h
index 854ab71..2828f9d 100644
--- a/arch/powerpc/include/asm/ppc-pci.h
+++ b/arch/powerpc/include/asm/ppc-pci.h
@@ -39,7 +39,6 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
 
 extern void pci_devs_phb_init(void);
 extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
-extern void scan_phb(struct pci_controller *hose);
 
 /* From rtas_pci.h */
 extern void init_pci_config_tokens (void);
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index f972952..498fe09 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -98,13 +98,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR);					\
 #define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
 #define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
 
-#define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n));  stvx n,b,base
+#define SAVE_VR(n,b,base)	li b,THREAD_VR0+(16*(n));  stvx n,base,b
 #define SAVE_2VRS(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
 #define SAVE_4VRS(n,b,base)	SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
 #define SAVE_8VRS(n,b,base)	SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
 #define SAVE_16VRS(n,b,base)	SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
 #define SAVE_32VRS(n,b,base)	SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
-#define REST_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); lvx n,b,base
+#define REST_VR(n,b,base)	li b,THREAD_VR0+(16*(n)); lvx n,base,b
 #define REST_2VRS(n,b,base)	REST_VR(n,b,base); REST_VR(n+1,b,base)
 #define REST_4VRS(n,b,base)	REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
 #define REST_8VRS(n,b,base)	REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
@@ -112,26 +112,26 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR);					\
 #define REST_32VRS(n,b,base)	REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
 
 /* Save the lower 32 VSRs in the thread VSR region */
-#define SAVE_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n));  STXVD2X(n,b,base)
+#define SAVE_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n));  STXVD2X(n,base,b)
 #define SAVE_2VSRS(n,b,base)	SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
 #define SAVE_4VSRS(n,b,base)	SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base)
 #define SAVE_8VSRS(n,b,base)	SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base)
 #define SAVE_16VSRS(n,b,base)	SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base)
 #define SAVE_32VSRS(n,b,base)	SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base)
-#define REST_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n)); LXVD2X(n,b,base)
+#define REST_VSR(n,b,base)	li b,THREAD_VSR0+(16*(n)); LXVD2X(n,base,b)
 #define REST_2VSRS(n,b,base)	REST_VSR(n,b,base); REST_VSR(n+1,b,base)
 #define REST_4VSRS(n,b,base)	REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base)
 #define REST_8VSRS(n,b,base)	REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base)
 #define REST_16VSRS(n,b,base)	REST_8VSRS(n,b,base); REST_8VSRS(n+8,b,base)
 #define REST_32VSRS(n,b,base)	REST_16VSRS(n,b,base); REST_16VSRS(n+16,b,base)
 /* Save the upper 32 VSRs (32-63) in the thread VSX region (0-31) */
-#define SAVE_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n));  STXVD2X(n+32,b,base)
+#define SAVE_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n));  STXVD2X(n+32,base,b)
 #define SAVE_2VSRSU(n,b,base)	SAVE_VSRU(n,b,base); SAVE_VSRU(n+1,b,base)
 #define SAVE_4VSRSU(n,b,base)	SAVE_2VSRSU(n,b,base); SAVE_2VSRSU(n+2,b,base)
 #define SAVE_8VSRSU(n,b,base)	SAVE_4VSRSU(n,b,base); SAVE_4VSRSU(n+4,b,base)
 #define SAVE_16VSRSU(n,b,base)	SAVE_8VSRSU(n,b,base); SAVE_8VSRSU(n+8,b,base)
 #define SAVE_32VSRSU(n,b,base)	SAVE_16VSRSU(n,b,base); SAVE_16VSRSU(n+16,b,base)
-#define REST_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n)); LXVD2X(n+32,b,base)
+#define REST_VSRU(n,b,base)	li b,THREAD_VR0+(16*(n)); LXVD2X(n+32,base,b)
 #define REST_2VSRSU(n,b,base)	REST_VSRU(n,b,base); REST_VSRU(n+1,b,base)
 #define REST_4VSRSU(n,b,base)	REST_2VSRSU(n,b,base); REST_2VSRSU(n+2,b,base)
 #define REST_8VSRSU(n,b,base)	REST_4VSRSU(n,b,base); REST_4VSRSU(n+4,b,base)
@@ -375,8 +375,15 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define PPC440EP_ERR42
 #endif
 
-
-#if defined(CONFIG_BOOKE)
+/*
+ * toreal/fromreal/tophys/tovirt macros. 32-bit BookE makes them
+ * keep the address intact to be compatible with code shared with
+ * 32-bit classic.
+ *
+ * On the other hand, I find it useful to have them behave as expected
+ * by their name (ie always do the addition) on 64-bit BookE
+ */
+#if defined(CONFIG_BOOKE) && !defined(CONFIG_PPC64)
 #define toreal(rd)
 #define fromreal(rd)
 
@@ -426,10 +433,9 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 	.previous
 #endif
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3S_64
 #define RFI		rfid
 #define MTMSRD(r)	mtmsrd	r
-
 #else
 #define FIX_SRR1(ra, rb)
 #ifndef CONFIG_40x
diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/pte-40x.h
index 07630fa..6c3e1f4 100644
--- a/arch/powerpc/include/asm/pte-40x.h
+++ b/arch/powerpc/include/asm/pte-40x.h
@@ -46,7 +46,7 @@
 #define	_PAGE_RW	0x040	/* software: Writes permitted */
 #define	_PAGE_DIRTY	0x080	/* software: dirty page */
 #define _PAGE_HWWRITE	0x100	/* hardware: Dirty & RW, set in exception */
-#define _PAGE_HWEXEC	0x200	/* hardware: EX permission */
+#define _PAGE_EXEC	0x200	/* hardware: EX permission */
 #define _PAGE_ACCESSED	0x400	/* software: R: page referenced */
 
 #define _PMD_PRESENT	0x400	/* PMD points to page of PTEs */
diff --git a/arch/powerpc/include/asm/pte-44x.h b/arch/powerpc/include/asm/pte-44x.h
index 37e98bc..4192b9b 100644
--- a/arch/powerpc/include/asm/pte-44x.h
+++ b/arch/powerpc/include/asm/pte-44x.h
@@ -78,7 +78,7 @@
 #define _PAGE_PRESENT	0x00000001		/* S: PTE valid */
 #define _PAGE_RW	0x00000002		/* S: Write permission */
 #define _PAGE_FILE	0x00000004		/* S: nonlinear file mapping */
-#define _PAGE_HWEXEC	0x00000004		/* H: Execute permission */
+#define _PAGE_EXEC	0x00000004		/* H: Execute permission */
 #define _PAGE_ACCESSED	0x00000008		/* S: Page referenced */
 #define _PAGE_DIRTY	0x00000010		/* S: Page dirty */
 #define _PAGE_SPECIAL	0x00000020		/* S: Special page */
diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h
index 8c6e312..94e9797 100644
--- a/arch/powerpc/include/asm/pte-8xx.h
+++ b/arch/powerpc/include/asm/pte-8xx.h
@@ -36,7 +36,6 @@
 /* These five software bits must be masked out when the entry is loaded
  * into the TLB.
  */
-#define _PAGE_EXEC	0x0008	/* software: i-cache coherency required */
 #define _PAGE_GUARDED	0x0010	/* software: guarded access */
 #define _PAGE_DIRTY	0x0020	/* software: page changed */
 #define _PAGE_RW	0x0040	/* software: user write access allowed */
diff --git a/arch/powerpc/include/asm/pte-book3e.h b/arch/powerpc/include/asm/pte-book3e.h
new file mode 100644
index 0000000..082d515
--- /dev/null
+++ b/arch/powerpc/include/asm/pte-book3e.h
@@ -0,0 +1,84 @@
+#ifndef _ASM_POWERPC_PTE_BOOK3E_H
+#define _ASM_POWERPC_PTE_BOOK3E_H
+#ifdef __KERNEL__
+
+/* PTE bit definitions for processors compliant to the Book3E
+ * architecture 2.06 or later. The position of the PTE bits
+ * matches the HW definition of the optional Embedded Page Table
+ * category.
+ */
+
+/* Architected bits */
+#define _PAGE_PRESENT	0x000001 /* software: pte contains a translation */
+#define _PAGE_FILE	0x000002 /* (!present only) software: pte holds file offset */
+#define _PAGE_SW1	0x000002
+#define _PAGE_BAP_SR	0x000004
+#define _PAGE_BAP_UR	0x000008
+#define _PAGE_BAP_SW	0x000010
+#define _PAGE_BAP_UW	0x000020
+#define _PAGE_BAP_SX	0x000040
+#define _PAGE_BAP_UX	0x000080
+#define _PAGE_PSIZE_MSK	0x000f00
+#define _PAGE_PSIZE_4K	0x000200
+#define _PAGE_PSIZE_8K	0x000300
+#define _PAGE_PSIZE_16K	0x000400
+#define _PAGE_PSIZE_32K	0x000500
+#define _PAGE_PSIZE_64K	0x000600
+#define _PAGE_PSIZE_128K	0x000700
+#define _PAGE_PSIZE_256K	0x000800
+#define _PAGE_PSIZE_512K	0x000900
+#define _PAGE_PSIZE_1M	0x000a00
+#define _PAGE_PSIZE_2M	0x000b00
+#define _PAGE_PSIZE_4M	0x000c00
+#define _PAGE_PSIZE_8M	0x000d00
+#define _PAGE_PSIZE_16M	0x000e00
+#define _PAGE_PSIZE_32M	0x000f00
+#define _PAGE_DIRTY	0x001000 /* C: page changed */
+#define _PAGE_SW0	0x002000
+#define _PAGE_U3	0x004000
+#define _PAGE_U2	0x008000
+#define _PAGE_U1	0x010000
+#define _PAGE_U0	0x020000
+#define _PAGE_ACCESSED	0x040000
+#define _PAGE_LENDIAN	0x080000
+#define _PAGE_GUARDED	0x100000
+#define _PAGE_COHERENT	0x200000 /* M: enforce memory coherence */
+#define _PAGE_NO_CACHE	0x400000 /* I: cache inhibit */
+#define _PAGE_WRITETHRU	0x800000 /* W: cache write-through */
+
+/* "Higher level" linux bit combinations */
+#define _PAGE_EXEC		_PAGE_BAP_UX /* .. and was cache cleaned */
+#define _PAGE_RW		(_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
+#define _PAGE_KERNEL_RW		(_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
+#define _PAGE_KERNEL_RO		(_PAGE_BAP_SR)
+#define _PAGE_KERNEL_RWX	(_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
+#define _PAGE_KERNEL_ROX	(_PAGE_BAP_SR | _PAGE_BAP_SX)
+#define _PAGE_USER		(_PAGE_BAP_UR | _PAGE_BAP_SR) /* Can be read */
+
+#define _PAGE_HASHPTE	0
+#define _PAGE_BUSY	0
+
+#define _PAGE_SPECIAL	_PAGE_SW0
+
+/* Flags to be preserved on PTE modifications */
+#define _PAGE_HPTEFLAGS	_PAGE_BUSY
+
+/* Base page size */
+#ifdef CONFIG_PPC_64K_PAGES
+#define _PAGE_PSIZE	_PAGE_PSIZE_64K
+#define PTE_RPN_SHIFT	(28)
+#else
+#define _PAGE_PSIZE	_PAGE_PSIZE_4K
+#define	PTE_RPN_SHIFT	(24)
+#endif
+
+/* On 32-bit, we never clear the top part of the PTE */
+#ifdef CONFIG_PPC32
+#define _PTE_NONE_MASK	0xffffffff00000000ULL
+#define _PMD_PRESENT	0
+#define _PMD_PRESENT_MASK (PAGE_MASK)
+#define _PMD_BAD	(~PAGE_MASK)
+#endif
+
+#endif /* __KERNEL__ */
+#endif /*  _ASM_POWERPC_PTE_FSL_BOOKE_H */
diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h
index a7e210b..c3b6507 100644
--- a/arch/powerpc/include/asm/pte-common.h
+++ b/arch/powerpc/include/asm/pte-common.h
@@ -13,9 +13,6 @@
 #ifndef _PAGE_HWWRITE
 #define _PAGE_HWWRITE	0
 #endif
-#ifndef _PAGE_HWEXEC
-#define _PAGE_HWEXEC	0
-#endif
 #ifndef _PAGE_EXEC
 #define _PAGE_EXEC	0
 #endif
@@ -34,6 +31,9 @@
 #ifndef _PAGE_4K_PFN
 #define _PAGE_4K_PFN		0
 #endif
+#ifndef _PAGE_SAO
+#define _PAGE_SAO	0
+#endif
 #ifndef _PAGE_PSIZE
 #define _PAGE_PSIZE		0
 #endif
@@ -45,10 +45,16 @@
 #define PMD_PAGE_SIZE(pmd)	bad_call_to_PMD_PAGE_SIZE()
 #endif
 #ifndef _PAGE_KERNEL_RO
-#define _PAGE_KERNEL_RO	0
+#define _PAGE_KERNEL_RO		0
+#endif
+#ifndef _PAGE_KERNEL_ROX
+#define _PAGE_KERNEL_ROX	(_PAGE_EXEC)
 #endif
 #ifndef _PAGE_KERNEL_RW
-#define _PAGE_KERNEL_RW	(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#define _PAGE_KERNEL_RW		(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE)
+#endif
+#ifndef _PAGE_KERNEL_RWX
+#define _PAGE_KERNEL_RWX	(_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_EXEC)
 #endif
 #ifndef _PAGE_HPTEFLAGS
 #define _PAGE_HPTEFLAGS _PAGE_HASHPTE
@@ -93,8 +99,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
 #define PAGE_PROT_BITS	(_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \
 			 _PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \
 			 _PAGE_USER | _PAGE_ACCESSED | \
-			 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | \
-			 _PAGE_EXEC | _PAGE_HWEXEC)
+			 _PAGE_RW | _PAGE_HWWRITE | _PAGE_DIRTY | _PAGE_EXEC)
 
 /*
  * We define 2 sets of base prot bits, one for basic pages (ie,
@@ -151,11 +156,9 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void);
 				 _PAGE_NO_CACHE)
 #define PAGE_KERNEL_NCG	__pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \
 				 _PAGE_NO_CACHE | _PAGE_GUARDED)
-#define PAGE_KERNEL_X	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_EXEC | \
-				 _PAGE_HWEXEC)
+#define PAGE_KERNEL_X	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX)
 #define PAGE_KERNEL_RO	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RO)
-#define PAGE_KERNEL_ROX	__pgprot(_PAGE_BASE | _PAGE_KERNEL_RO | _PAGE_EXEC | \
-				 _PAGE_HWEXEC)
+#define PAGE_KERNEL_ROX	__pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX)
 
 /* Protection used for kernel text. We want the debuggers to be able to
  * set breakpoints anywhere, so don't write protect the kernel text
diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h
index 10820f5..2c12be5 100644
--- a/arch/powerpc/include/asm/pte-fsl-booke.h
+++ b/arch/powerpc/include/asm/pte-fsl-booke.h
@@ -23,7 +23,7 @@
 #define _PAGE_FILE	0x00002	/* S: when !present: nonlinear file mapping */
 #define _PAGE_RW	0x00004	/* S: Write permission (SW) */
 #define _PAGE_DIRTY	0x00008	/* S: Page dirty */
-#define _PAGE_HWEXEC	0x00010	/* H: SX permission */
+#define _PAGE_EXEC	0x00010	/* H: SX permission */
 #define _PAGE_ACCESSED	0x00020	/* S: Page referenced */
 
 #define _PAGE_ENDIAN	0x00040	/* H: E bit */
@@ -33,13 +33,6 @@
 #define _PAGE_WRITETHRU	0x00400	/* H: W bit */
 #define _PAGE_SPECIAL	0x00800 /* S: Special page */
 
-#ifdef CONFIG_PTE_64BIT
-/* ERPN in a PTE never gets cleared, ignore it */
-#define _PTE_NONE_MASK	0xffffffffffff0000ULL
-/* We extend the size of the PTE flags area when using 64-bit PTEs */
-#define PTE_RPN_SHIFT	(PAGE_SHIFT + 8)
-#endif
-
 #define _PMD_PRESENT	0
 #define _PMD_PRESENT_MASK (PAGE_MASK)
 #define _PMD_BAD	(~PAGE_MASK)
diff --git a/arch/powerpc/include/asm/pte-hash32.h b/arch/powerpc/include/asm/pte-hash32.h
index 16e571c..4aad413 100644
--- a/arch/powerpc/include/asm/pte-hash32.h
+++ b/arch/powerpc/include/asm/pte-hash32.h
@@ -26,7 +26,6 @@
 #define _PAGE_WRITETHRU	0x040	/* W: cache write-through */
 #define _PAGE_DIRTY	0x080	/* C: page changed */
 #define _PAGE_ACCESSED	0x100	/* R: page referenced */
-#define _PAGE_EXEC	0x200	/* software: i-cache coherency required */
 #define _PAGE_RW	0x400	/* software: user write access allowed */
 #define _PAGE_SPECIAL	0x800	/* software: Special page */
 
diff --git a/arch/powerpc/include/asm/qe.h b/arch/powerpc/include/asm/qe.h
index 157c5ca..f388f0a 100644
--- a/arch/powerpc/include/asm/qe.h
+++ b/arch/powerpc/include/asm/qe.h
@@ -154,6 +154,7 @@ int qe_get_snum(void);
 void qe_put_snum(u8 snum);
 unsigned int qe_get_num_of_risc(void);
 unsigned int qe_get_num_of_snums(void);
+int qe_alive_during_sleep(void);
 
 /* we actually use cpm_muram implementation, define this for convenience */
 #define qe_muram_init cpm_muram_init
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 1170267..6315edc 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -98,19 +98,15 @@
 #define MSR_RI		__MASK(MSR_RI_LG)	/* Recoverable Exception */
 #define MSR_LE		__MASK(MSR_LE_LG)	/* Little Endian */
 
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC_BOOK3S_64)
+/* Server variant */
 #define MSR_		MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV
 #define MSR_KERNEL      MSR_ | MSR_SF
-
 #define MSR_USER32	MSR_ | MSR_PR | MSR_EE
 #define MSR_USER64	MSR_USER32 | MSR_SF
-
-#else /* 32-bit */
+#elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_8xx)
 /* Default MSR for kernel mode. */
-#ifndef MSR_KERNEL	/* reg_booke.h also defines this */
 #define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_IR|MSR_DR)
-#endif
-
 #define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
 #endif
 
@@ -646,6 +642,137 @@
 #endif
 
 /*
+ * SPRG usage:
+ *
+ * All 64-bit:
+ *	- SPRG1 stores PACA pointer
+ *
+ * 64-bit server:
+ *	- SPRG0 unused (reserved for HV on Power4)
+ *	- SPRG2 scratch for exception vectors
+ *	- SPRG3 unused (user visible)
+ *
+ * 64-bit embedded
+ *	- SPRG0 generic exception scratch
+ *	- SPRG2 TLB exception stack
+ *	- SPRG3 unused (user visible)
+ *	- SPRG4 unused (user visible)
+ *	- SPRG6 TLB miss scratch (user visible, sorry !)
+ *	- SPRG7 critical exception scratch
+ *	- SPRG8 machine check exception scratch
+ *	- SPRG9 debug exception scratch
+ *
+ * All 32-bit:
+ *	- SPRG3 current thread_info pointer
+ *        (virtual on BookE, physical on others)
+ *
+ * 32-bit classic:
+ *	- SPRG0 scratch for exception vectors
+ *	- SPRG1 scratch for exception vectors
+ *	- SPRG2 indicator that we are in RTAS
+ *	- SPRG4 (603 only) pseudo TLB LRU data
+ *
+ * 32-bit 40x:
+ *	- SPRG0 scratch for exception vectors
+ *	- SPRG1 scratch for exception vectors
+ *	- SPRG2 scratch for exception vectors
+ *	- SPRG4 scratch for exception vectors (not 403)
+ *	- SPRG5 scratch for exception vectors (not 403)
+ *	- SPRG6 scratch for exception vectors (not 403)
+ *	- SPRG7 scratch for exception vectors (not 403)
+ *
+ * 32-bit 440 and FSL BookE:
+ *	- SPRG0 scratch for exception vectors
+ *	- SPRG1 scratch for exception vectors (*)
+ *	- SPRG2 scratch for crit interrupts handler
+ *	- SPRG4 scratch for exception vectors
+ *	- SPRG5 scratch for exception vectors
+ *	- SPRG6 scratch for machine check handler
+ *	- SPRG7 scratch for exception vectors
+ *	- SPRG9 scratch for debug vectors (e500 only)
+ *
+ *      Additionally, BookE separates "read" and "write"
+ *      of those registers. That allows to use the userspace
+ *      readable variant for reads, which can avoid a fault
+ *      with KVM type virtualization.
+ *
+ *      (*) Under KVM, the host SPRG1 is used to point to
+ *      the current VCPU data structure
+ *
+ * 32-bit 8xx:
+ *	- SPRG0 scratch for exception vectors
+ *	- SPRG1 scratch for exception vectors
+ *	- SPRG2 apparently unused but initialized
+ *
+ */
+#ifdef CONFIG_PPC64
+#define SPRN_SPRG_PACA 		SPRN_SPRG1
+#else
+#define SPRN_SPRG_THREAD 	SPRN_SPRG3
+#endif
+
+#ifdef CONFIG_PPC_BOOK3S_64
+#define SPRN_SPRG_SCRATCH0	SPRN_SPRG2
+#endif
+
+#ifdef CONFIG_PPC_BOOK3E_64
+#define SPRN_SPRG_MC_SCRATCH	SPRN_SPRG8
+#define SPRN_SPRG_CRIT_SCRATCH	SPRN_SPRG7
+#define SPRN_SPRG_DBG_SCRATCH	SPRN_SPRG9
+#define SPRN_SPRG_TLB_EXFRAME	SPRN_SPRG2
+#define SPRN_SPRG_TLB_SCRATCH	SPRN_SPRG6
+#define SPRN_SPRG_GEN_SCRATCH	SPRN_SPRG0
+#endif
+
+#ifdef CONFIG_PPC_BOOK3S_32
+#define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
+#define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
+#define SPRN_SPRG_RTAS		SPRN_SPRG2
+#define SPRN_SPRG_603_LRU	SPRN_SPRG4
+#endif
+
+#ifdef CONFIG_40x
+#define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
+#define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
+#define SPRN_SPRG_SCRATCH2	SPRN_SPRG2
+#define SPRN_SPRG_SCRATCH3	SPRN_SPRG4
+#define SPRN_SPRG_SCRATCH4	SPRN_SPRG5
+#define SPRN_SPRG_SCRATCH5	SPRN_SPRG6
+#define SPRN_SPRG_SCRATCH6	SPRN_SPRG7
+#endif
+
+#ifdef CONFIG_BOOKE
+#define SPRN_SPRG_RSCRATCH0	SPRN_SPRG0
+#define SPRN_SPRG_WSCRATCH0	SPRN_SPRG0
+#define SPRN_SPRG_RSCRATCH1	SPRN_SPRG1
+#define SPRN_SPRG_WSCRATCH1	SPRN_SPRG1
+#define SPRN_SPRG_RSCRATCH_CRIT	SPRN_SPRG2
+#define SPRN_SPRG_WSCRATCH_CRIT	SPRN_SPRG2
+#define SPRN_SPRG_RSCRATCH2	SPRN_SPRG4R
+#define SPRN_SPRG_WSCRATCH2	SPRN_SPRG4W
+#define SPRN_SPRG_RSCRATCH3	SPRN_SPRG5R
+#define SPRN_SPRG_WSCRATCH3	SPRN_SPRG5W
+#define SPRN_SPRG_RSCRATCH_MC	SPRN_SPRG6R
+#define SPRN_SPRG_WSCRATCH_MC	SPRN_SPRG6W
+#define SPRN_SPRG_RSCRATCH4	SPRN_SPRG7R
+#define SPRN_SPRG_WSCRATCH4	SPRN_SPRG7W
+#ifdef CONFIG_E200
+#define SPRN_SPRG_RSCRATCH_DBG	SPRN_SPRG6R
+#define SPRN_SPRG_WSCRATCH_DBG	SPRN_SPRG6W
+#else
+#define SPRN_SPRG_RSCRATCH_DBG	SPRN_SPRG9
+#define SPRN_SPRG_WSCRATCH_DBG	SPRN_SPRG9
+#endif
+#define SPRN_SPRG_RVCPU		SPRN_SPRG1
+#define SPRN_SPRG_WVCPU		SPRN_SPRG1
+#endif
+
+#ifdef CONFIG_8xx
+#define SPRN_SPRG_SCRATCH0	SPRN_SPRG0
+#define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
+#endif
+
+/*
  * An mtfsf instruction with the L bit set. On CPUs that support this a
  * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
  *
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 6bcf364..3bf7835 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -18,18 +18,26 @@
 #define MSR_IS		MSR_IR	/* Instruction Space */
 #define MSR_DS		MSR_DR	/* Data Space */
 #define MSR_PMM		(1<<2)	/* Performance monitor mark bit */
+#define MSR_CM		(1<<31) /* Computation Mode (0=32-bit, 1=64-bit) */
 
-/* Default MSR for kernel mode. */
-#if defined (CONFIG_40x)
+#if defined(CONFIG_PPC_BOOK3E_64)
+#define MSR_		MSR_ME | MSR_CE
+#define MSR_KERNEL      MSR_ | MSR_CM
+#define MSR_USER32	MSR_ | MSR_PR | MSR_EE
+#define MSR_USER64	MSR_USER32 | MSR_CM
+#elif defined (CONFIG_40x)
 #define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE)
-#elif defined(CONFIG_BOOKE)
+#define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
+#else
 #define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_CE)
+#define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
 #endif
 
 /* Special Purpose Registers (SPRNs)*/
 #define SPRN_DECAR	0x036	/* Decrementer Auto Reload Register */
 #define SPRN_IVPR	0x03F	/* Interrupt Vector Prefix Register */
 #define SPRN_USPRG0	0x100	/* User Special Purpose Register General 0 */
+#define SPRN_SPRG3R	0x103	/* Special Purpose Register General 3 Read */
 #define SPRN_SPRG4R	0x104	/* Special Purpose Register General 4 Read */
 #define SPRN_SPRG5R	0x105	/* Special Purpose Register General 5 Read */
 #define SPRN_SPRG6R	0x106	/* Special Purpose Register General 6 Read */
@@ -38,11 +46,18 @@
 #define SPRN_SPRG5W	0x115	/* Special Purpose Register General 5 Write */
 #define SPRN_SPRG6W	0x116	/* Special Purpose Register General 6 Write */
 #define SPRN_SPRG7W	0x117	/* Special Purpose Register General 7 Write */
+#define SPRN_EPCR	0x133	/* Embedded Processor Control Register */
 #define SPRN_DBCR2	0x136	/* Debug Control Register 2 */
 #define SPRN_IAC3	0x13A	/* Instruction Address Compare 3 */
 #define SPRN_IAC4	0x13B	/* Instruction Address Compare 4 */
 #define SPRN_DVC1	0x13E	/* Data Value Compare Register 1 */
 #define SPRN_DVC2	0x13F	/* Data Value Compare Register 2 */
+#define SPRN_MAS8	0x155	/* MMU Assist Register 8 */
+#define SPRN_TLB0PS	0x158	/* TLB 0 Page Size Register */
+#define SPRN_MAS5_MAS6	0x15c	/* MMU Assist Register 5 || 6 */
+#define SPRN_MAS8_MAS1	0x15d	/* MMU Assist Register 8 || 1 */
+#define SPRN_MAS7_MAS3	0x174	/* MMU Assist Register 7 || 3 */
+#define SPRN_MAS0_MAS1	0x175	/* MMU Assist Register 0 || 1 */
 #define SPRN_IVOR0	0x190	/* Interrupt Vector Offset Register 0 */
 #define SPRN_IVOR1	0x191	/* Interrupt Vector Offset Register 1 */
 #define SPRN_IVOR2	0x192	/* Interrupt Vector Offset Register 2 */
@@ -93,6 +108,8 @@
 #define SPRN_PID2	0x27A	/* Process ID Register 2 */
 #define SPRN_TLB0CFG	0x2B0	/* TLB 0 Config Register */
 #define SPRN_TLB1CFG	0x2B1	/* TLB 1 Config Register */
+#define SPRN_TLB2CFG	0x2B2	/* TLB 2 Config Register */
+#define SPRN_TLB3CFG	0x2B3	/* TLB 3 Config Register */
 #define SPRN_EPR	0x2BE	/* External Proxy Register */
 #define SPRN_CCR1	0x378	/* Core Configuration Register 1 */
 #define SPRN_ZPR	0x3B0	/* Zone Protection Register (40x) */
@@ -415,16 +432,31 @@
 #define L2CSR0_L2LOA	0x00000080	/* L2 Cache Lock Overflow Allocate */
 #define L2CSR0_L2LO	0x00000020	/* L2 Cache Lock Overflow */
 
-/* Bit definitions for MMUCSR0 */
-#define MMUCSR0_TLB1FI	0x00000002	/* TLB1 Flash invalidate */
-#define MMUCSR0_TLB0FI	0x00000004	/* TLB0 Flash invalidate */
-#define MMUCSR0_TLB2FI	0x00000040	/* TLB2 Flash invalidate */
-#define MMUCSR0_TLB3FI	0x00000020	/* TLB3 Flash invalidate */
-
 /* Bit definitions for SGR. */
 #define SGR_NORMAL	0		/* Speculative fetching allowed. */
 #define SGR_GUARDED	1		/* Speculative fetching disallowed. */
 
+/* Bit definitions for EPCR */
+#define SPRN_EPCR_EXTGS		0x80000000	/* External Input interrupt
+						 * directed to Guest state */
+#define SPRN_EPCR_DTLBGS	0x40000000	/* Data TLB Error interrupt
+						 * directed to guest state */
+#define SPRN_EPCR_ITLBGS	0x20000000	/* Instr. TLB error interrupt
+						 * directed to guest state */
+#define SPRN_EPCR_DSIGS		0x10000000	/* Data Storage interrupt
+						 * directed to guest state */
+#define SPRN_EPCR_ISIGS		0x08000000	/* Instr. Storage interrupt
+						 * directed to guest state */
+#define SPRN_EPCR_DUVD		0x04000000	/* Disable Hypervisor Debug */
+#define SPRN_EPCR_ICM		0x02000000	/* Interrupt computation mode
+						 * (copied to MSR:CM on intr) */
+#define SPRN_EPCR_GICM		0x01000000	/* Guest Interrupt Comp. mode */
+#define SPRN_EPCR_DGTMI		0x00800000	/* Disable TLB Guest Management
+						 * instructions */
+#define SPRN_EPCR_DMIUH		0x00400000	/* Disable MAS Interrupt updates
+						 * for hypervisor */
+
+
 /*
  * The IBM-403 is an even more odd special case, as it is much
  * older than the IBM-405 series.  We put these down here incase someone
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 817fac0..dae1934 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -1,6 +1,6 @@
 #ifndef _ASM_POWERPC_SETUP_H
 #define _ASM_POWERPC_SETUP_H
 
-#define COMMAND_LINE_SIZE	512
+#include <asm-generic/setup.h>
 
 #endif	/* _ASM_POWERPC_SETUP_H */
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index c25f73d..c0d3b8a 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -148,6 +148,16 @@ extern struct smp_ops_t *smp_ops;
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi(cpumask_t mask);
 
+/* Definitions relative to the secondary CPU spin loop
+ * and entry point. Not all of them exist on both 32 and
+ * 64-bit but defining them all here doesn't harm
+ */
+extern void generic_secondary_smp_init(void);
+extern void generic_secondary_thread_init(void);
+extern unsigned long __secondary_hold_spinloop;
+extern unsigned long __secondary_hold_acknowledge;
+extern char __secondary_hold;
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/socket.h b/arch/powerpc/include/asm/socket.h
index 1e5cfad..3ab8b3e 100644
--- a/arch/powerpc/include/asm/socket.h
+++ b/arch/powerpc/include/asm/socket.h
@@ -64,4 +64,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif	/* _ASM_POWERPC_SOCKET_H */
diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/include/asm/swiotlb.h
index 30891d6..8979d4c 100644
--- a/arch/powerpc/include/asm/swiotlb.h
+++ b/arch/powerpc/include/asm/swiotlb.h
@@ -13,15 +13,13 @@
 
 #include <linux/swiotlb.h>
 
-extern struct dma_mapping_ops swiotlb_dma_ops;
-extern struct dma_mapping_ops swiotlb_pci_dma_ops;
-
-int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t,
-				       size_t size);
+extern struct dma_map_ops swiotlb_dma_ops;
 
 static inline void dma_mark_clean(void *addr, size_t size) {}
 
 extern unsigned int ppc_swiotlb_enable;
 int __init swiotlb_setup_bus_notifier(void);
 
+extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev);
+
 #endif /* __ASM_SWIOTLB_H */
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 370600c..c7d671a 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -95,8 +95,8 @@ SYSCALL(reboot)
 SYSX(sys_ni_syscall,compat_sys_old_readdir,sys_old_readdir)
 SYSCALL_SPU(mmap)
 SYSCALL_SPU(munmap)
-SYSCALL_SPU(truncate)
-SYSCALL_SPU(ftruncate)
+COMPAT_SYS_SPU(truncate)
+COMPAT_SYS_SPU(ftruncate)
 SYSCALL_SPU(fchmod)
 SYSCALL_SPU(fchown)
 COMPAT_SYS_SPU(getpriority)
@@ -322,7 +322,7 @@ SYSCALL_SPU(epoll_create1)
 SYSCALL_SPU(dup3)
 SYSCALL_SPU(pipe2)
 SYSCALL(inotify_init1)
-SYSCALL_SPU(perf_counter_open)
+SYSCALL_SPU(perf_event_open)
 COMPAT_SYS_SPU(preadv)
 COMPAT_SYS_SPU(pwritev)
 COMPAT_SYS(rt_tgsigqueueinfo)
diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h
index e20ff75..e2b428b 100644
--- a/arch/powerpc/include/asm/tlb.h
+++ b/arch/powerpc/include/asm/tlb.h
@@ -25,57 +25,25 @@
 
 #include <linux/pagemap.h>
 
-struct mmu_gather;
-
 #define tlb_start_vma(tlb, vma)	do { } while (0)
 #define tlb_end_vma(tlb, vma)	do { } while (0)
 
-#if !defined(CONFIG_PPC_STD_MMU)
-
-#define tlb_flush(tlb)			flush_tlb_mm((tlb)->mm)
-
-#elif defined(__powerpc64__)
-
-extern void pte_free_finish(void);
-
-static inline void tlb_flush(struct mmu_gather *tlb)
-{
-	struct ppc64_tlb_batch *tlbbatch = &__get_cpu_var(ppc64_tlb_batch);
-
-	/* If there's a TLB batch pending, then we must flush it because the
-	 * pages are going to be freed and we really don't want to have a CPU
-	 * access a freed page because it has a stale TLB
-	 */
-	if (tlbbatch->index)
-		__flush_tlb_pending(tlbbatch);
-
-	pte_free_finish();
-}
-
-#else
-
 extern void tlb_flush(struct mmu_gather *tlb);
 
-#endif
-
 /* Get the generic bits... */
 #include <asm-generic/tlb.h>
 
-#if !defined(CONFIG_PPC_STD_MMU) || defined(__powerpc64__)
-
-#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while (0)
-
-#else
 extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
 			     unsigned long address);
 
 static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
-					unsigned long address)
+					  unsigned long address)
 {
+#ifdef CONFIG_PPC_STD_MMU_32
 	if (pte_val(*ptep) & _PAGE_HASHPTE)
 		flush_hash_entry(tlb->mm, ptep, address);
+#endif
 }
 
-#endif
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_TLB_H */
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
index abbe341..d50a380 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -6,7 +6,7 @@
  *
  *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
  *  - flush_tlb_page(vma, vmaddr) flushes one page
- *  - local_flush_tlb_mm(mm) flushes the specified mm context on
+ *  - local_flush_tlb_mm(mm, full) flushes the specified mm context on
  *                           the local processor
  *  - local_flush_tlb_page(vma, vmaddr) flushes one page on the local processor
  *  - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
@@ -29,7 +29,8 @@
  * specific tlbie's
  */
 
-#include <linux/mm.h>
+struct vm_area_struct;
+struct mm_struct;
 
 #define MMU_NO_CONTEXT      	((unsigned int)-1)
 
@@ -40,12 +41,18 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 extern void local_flush_tlb_mm(struct mm_struct *mm);
 extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
 
+extern void __local_flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
+				   int tsize, int ind);
+
 #ifdef CONFIG_SMP
 extern void flush_tlb_mm(struct mm_struct *mm);
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
+extern void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
+			     int tsize, int ind);
 #else
 #define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
 #define flush_tlb_page(vma,addr)	local_flush_tlb_page(vma,addr)
+#define __flush_tlb_page(mm,addr,p,i)	__local_flush_tlb_page(mm,addr,p,i)
 #endif
 #define flush_tlb_page_nohash(vma,addr)	flush_tlb_page(vma,addr)
 
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 054a16d..394edcb 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -57,14 +57,13 @@ static inline int pcibus_to_node(struct pci_bus *bus)
 	.cache_nice_tries	= 1,			\
 	.busy_idx		= 3,			\
 	.idle_idx		= 1,			\
-	.newidle_idx		= 2,			\
-	.wake_idx		= 1,			\
+	.newidle_idx		= 0,			\
+	.wake_idx		= 0,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_EXEC	\
+				| SD_BALANCE_FORK	\
 				| SD_BALANCE_NEWIDLE	\
-				| SD_WAKE_IDLE		\
-				| SD_SERIALIZE		\
-				| SD_WAKE_BALANCE,	\
+				| SD_SERIALIZE,		\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
 	.nr_balance_failed	= 0,			\
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index cef080b..f6ca761 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -341,7 +341,7 @@
 #define __NR_dup3		316
 #define __NR_pipe2		317
 #define __NR_inotify_init1	318
-#define __NR_perf_counter_open	319
+#define __NR_perf_event_open	319
 #define __NR_preadv		320
 #define __NR_pwritev		321
 #define __NR_rt_tgsigqueueinfo	322
diff --git a/arch/powerpc/include/asm/vdso.h b/arch/powerpc/include/asm/vdso.h
index 26fc449..dc0419b 100644
--- a/arch/powerpc/include/asm/vdso.h
+++ b/arch/powerpc/include/asm/vdso.h
@@ -7,9 +7,8 @@
 #define VDSO32_LBASE	0x100000
 #define VDSO64_LBASE	0x100000
 
-/* Default map addresses */
+/* Default map addresses for 32bit vDSO */
 #define VDSO32_MBASE	VDSO32_LBASE
-#define VDSO64_MBASE	VDSO64_LBASE
 
 #define VDSO_VERSION_STRING	LINUX_2.6.15
 
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 9619285..b23664a 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -33,10 +33,10 @@ obj-y				:= cputable.o ptrace.o syscalls.o \
 obj-y				+= vdso32/
 obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
 				   signal_64.o ptrace32.o \
-				   paca.o cpu_setup_ppc970.o \
-				   cpu_setup_pa6t.o \
-				   firmware.o nvram_64.o
+				   paca.o nvram_64.o firmware.o
+obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
 obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
+obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o
 obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
@@ -63,8 +63,8 @@ obj-$(CONFIG_MODULES)		+= module.o module_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_44x)		+= cpu_setup_44x.o
 obj-$(CONFIG_FSL_BOOKE)		+= cpu_setup_fsl_booke.o dbell.o
 
-extra-$(CONFIG_PPC_STD_MMU)	:= head_32.o
-extra-$(CONFIG_PPC64)		:= head_64.o
+extra-y				:= head_$(CONFIG_WORD_SIZE).o
+extra-$(CONFIG_PPC_BOOK3E_32)	:= head_new_booke.o
 extra-$(CONFIG_40x)		:= head_40x.o
 extra-$(CONFIG_44x)		:= head_44x.o
 extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_booke.o
@@ -88,7 +88,7 @@ obj-$(CONFIG_SWIOTLB)		+= dma-swiotlb.o
 
 pci64-$(CONFIG_PPC64)		+= pci_dn.o isa-bridge.o
 obj-$(CONFIG_PCI)		+= pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
-				   pci-common.o
+				   pci-common.o pci_of_scan.o
 obj-$(CONFIG_PCI_MSI)		+= msi.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o crash.o \
 				   machine_kexec_$(CONFIG_WORD_SIZE).o
@@ -97,7 +97,7 @@ obj64-$(CONFIG_AUDIT)		+= compat_audit.o
 
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
-obj-$(CONFIG_PPC_PERF_CTRS)	+= perf_counter.o perf_callchain.o
+obj-$(CONFIG_PPC_PERF_CTRS)	+= perf_event.o perf_callchain.o
 obj64-$(CONFIG_PPC_PERF_CTRS)	+= power4-pmu.o ppc970-pmu.o power5-pmu.o \
 				   power5+-pmu.o power6-pmu.o power7-pmu.o
 obj32-$(CONFIG_PPC_PERF_CTRS)	+= mpc7450-pmu.o
@@ -115,6 +115,13 @@ ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),)
 obj-y				+= ppc_save_regs.o
 endif
 
+# Disable GCOV in odd or sensitive code
+GCOV_PROFILE_prom_init.o := n
+GCOV_PROFILE_ftrace.o := n
+GCOV_PROFILE_machine_kexec_64.o := n
+GCOV_PROFILE_machine_kexec_32.o := n
+GCOV_PROFILE_kprobes.o := n
+
 extra-$(CONFIG_PPC_FPU)		+= fpu.o
 extra-$(CONFIG_ALTIVEC)		+= vector.o
 extra-$(CONFIG_PPC64)		+= entry_64.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 197b156..0812b0f 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -52,9 +52,11 @@
 #include <linux/kvm_host.h>
 #endif
 
+#ifdef CONFIG_PPC32
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
 #include "head_booke.h"
 #endif
+#endif
 
 #if defined(CONFIG_FSL_BOOKE)
 #include "../mm/mmu_decl.h"
@@ -131,7 +133,7 @@ int main(void)
 	DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
 	DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
 	DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
-	DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_counter_pending));
+	DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_event_pending));
 	DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
 #ifdef CONFIG_PPC_MM_SLICES
 	DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
@@ -140,6 +142,20 @@ int main(void)
 					    context.high_slices_psize));
 	DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
 #endif /* CONFIG_PPC_MM_SLICES */
+
+#ifdef CONFIG_PPC_BOOK3E
+	DEFINE(PACAPGD, offsetof(struct paca_struct, pgd));
+	DEFINE(PACA_KERNELPGD, offsetof(struct paca_struct, kernel_pgd));
+	DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
+	DEFINE(PACA_EXTLB, offsetof(struct paca_struct, extlb));
+	DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
+	DEFINE(PACA_EXCRIT, offsetof(struct paca_struct, excrit));
+	DEFINE(PACA_EXDBG, offsetof(struct paca_struct, exdbg));
+	DEFINE(PACA_MC_STACK, offsetof(struct paca_struct, mc_kstack));
+	DEFINE(PACA_CRIT_STACK, offsetof(struct paca_struct, crit_kstack));
+	DEFINE(PACA_DBG_STACK, offsetof(struct paca_struct, dbg_kstack));
+#endif /* CONFIG_PPC_BOOK3E */
+
 #ifdef CONFIG_PPC_STD_MMU_64
 	DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
 	DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
@@ -262,6 +278,7 @@ int main(void)
 	DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
 #endif /* CONFIG_PPC64 */
 
+#if defined(CONFIG_PPC32)
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
 	DEFINE(EXC_LVL_SIZE, STACK_EXC_LVL_FRAME_SIZE);
 	DEFINE(MAS0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, mas0));
@@ -280,7 +297,7 @@ int main(void)
 	DEFINE(_DSRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, dsrr1));
 	DEFINE(SAVED_KSP_LIMIT, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, saved_ksp_limit));
 #endif
-
+#endif
 	DEFINE(CLONE_VM, CLONE_VM);
 	DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
 
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index 1e9949e..55cba4a 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -21,7 +21,7 @@ _GLOBAL(__setup_cpu_603)
 	mflr	r4
 BEGIN_MMU_FTR_SECTION
 	li	r10,0
-	mtspr	SPRN_SPRG4,r10		/* init SW LRU tracking */
+	mtspr	SPRN_SPRG_603_LRU,r10		/* init SW LRU tracking */
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 BEGIN_FTR_SECTION
 	bl	__init_fpu_registers
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 4a24a2f..0b9c913 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -89,11 +89,15 @@ extern void __restore_cpu_power7(void);
 #define COMMON_USER_PA6T	(COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
 				 PPC_FEATURE_TRUE_LE | \
 				 PPC_FEATURE_HAS_ALTIVEC_COMP)
+#ifdef CONFIG_PPC_BOOK3E_64
+#define COMMON_USER_BOOKE	(COMMON_USER_PPC64 | PPC_FEATURE_BOOKE)
+#else
 #define COMMON_USER_BOOKE	(PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
 				 PPC_FEATURE_BOOKE)
+#endif
 
 static struct cpu_spec __initdata cpu_specs[] = {
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3S_64
 	{	/* Power3 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x00400000,
@@ -508,7 +512,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_generic,
 		.platform		= "power4",
 	}
-#endif	/* CONFIG_PPC64 */
+#endif	/* CONFIG_PPC_BOOK3S_64 */
+
 #ifdef CONFIG_PPC32
 #if CLASSIC_PPC
 	{	/* 601 */
@@ -1630,7 +1635,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.platform		= "ppc440",
 	},
 	{ /* 460EX */
-		.pvr_mask		= 0xffff0002,
+		.pvr_mask		= 0xffff0006,
 		.pvr_value		= 0x13020002,
 		.cpu_name		= "460EX",
 		.cpu_features		= CPU_FTRS_440x6,
@@ -1642,8 +1647,21 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_440A,
 		.platform		= "ppc440",
 	},
+	{ /* 460EX Rev B */
+		.pvr_mask		= 0xffff0007,
+		.pvr_value		= 0x13020004,
+		.cpu_name		= "460EX Rev. B",
+		.cpu_features		= CPU_FTRS_440x6,
+		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
+		.mmu_features		= MMU_FTR_TYPE_44x,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_460ex,
+		.machine_check		= machine_check_440A,
+		.platform		= "ppc440",
+	},
 	{ /* 460GT */
-		.pvr_mask		= 0xffff0002,
+		.pvr_mask		= 0xffff0006,
 		.pvr_value		= 0x13020000,
 		.cpu_name		= "460GT",
 		.cpu_features		= CPU_FTRS_440x6,
@@ -1655,6 +1673,19 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check		= machine_check_440A,
 		.platform		= "ppc440",
 	},
+	{ /* 460GT Rev B */
+		.pvr_mask		= 0xffff0007,
+		.pvr_value		= 0x13020005,
+		.cpu_name		= "460GT Rev. B",
+		.cpu_features		= CPU_FTRS_440x6,
+		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
+		.mmu_features		= MMU_FTR_TYPE_44x,
+		.icache_bsize		= 32,
+		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_460gt,
+		.machine_check		= machine_check_440A,
+		.platform		= "ppc440",
+	},
 	{ /* 460SX */
 		.pvr_mask		= 0xffffff00,
 		.pvr_value		= 0x13541800,
@@ -1797,6 +1828,29 @@ static struct cpu_spec __initdata cpu_specs[] = {
 	}
 #endif /* CONFIG_E500 */
 #endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC_BOOK3E_64
+	{	/* This is a default entry to get going, to be replaced by
+		 * a real one at some stage
+		 */
+#define CPU_FTRS_BASE_BOOK3E	(CPU_FTR_USE_TB | \
+	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_SMT | \
+	    CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
+		.pvr_mask		= 0x00000000,
+		.pvr_value		= 0x00000000,
+		.cpu_name		= "Book3E",
+		.cpu_features		= CPU_FTRS_BASE_BOOK3E,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.mmu_features		= MMU_FTR_TYPE_3E | MMU_FTR_USE_TLBILX |
+					  MMU_FTR_USE_TLBIVAX_BCAST |
+					  MMU_FTR_LOCK_BCAST_INVAL,
+		.icache_bsize		= 64,
+		.dcache_bsize		= 64,
+		.num_pmcs		= 0,
+		.machine_check		= machine_check_generic,
+		.platform		= "power6",
+	},
+#endif
 };
 
 static struct cpu_spec the_cpu_spec;
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 2983ada..87ddb3f 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -89,7 +89,7 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask)
 		return 1;
 }
 
-struct dma_mapping_ops dma_iommu_ops = {
+struct dma_map_ops dma_iommu_ops = {
 	.alloc_coherent	= dma_iommu_alloc_coherent,
 	.free_coherent	= dma_iommu_free_coherent,
 	.map_sg		= dma_iommu_map_sg,
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index e8a57de..e96cbbd 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -25,33 +25,13 @@ int swiotlb __read_mostly;
 unsigned int ppc_swiotlb_enable;
 
 /*
- * Determine if an address is reachable by a pci device, or if we must bounce.
- */
-static int
-swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
-{
-	dma_addr_t max;
-	struct pci_controller *hose;
-	struct pci_dev *pdev = to_pci_dev(hwdev);
-
-	hose = pci_bus_to_host(pdev->bus);
-	max = hose->dma_window_base_cur + hose->dma_window_size;
-
-	/* check that we're within mapped pci window space */
-	if ((addr + size > max) | (addr < hose->dma_window_base_cur))
-		return 1;
-
-	return 0;
-}
-
-/*
  * At the moment, all platforms that use this code only require
  * swiotlb to be used if we're operating on HIGHMEM.  Since
  * we don't ever call anything other than map_sg, unmap_sg,
  * map_page, and unmap_page on highmem, use normal dma_ops
  * for everything else.
  */
-struct dma_mapping_ops swiotlb_dma_ops = {
+struct dma_map_ops swiotlb_dma_ops = {
 	.alloc_coherent = dma_direct_alloc_coherent,
 	.free_coherent = dma_direct_free_coherent,
 	.map_sg = swiotlb_map_sg_attrs,
@@ -62,33 +42,34 @@ struct dma_mapping_ops swiotlb_dma_ops = {
 	.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
 	.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
 	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
-	.sync_sg_for_device = swiotlb_sync_sg_for_device
+	.sync_sg_for_device = swiotlb_sync_sg_for_device,
+	.mapping_error = swiotlb_dma_mapping_error,
 };
 
-struct dma_mapping_ops swiotlb_pci_dma_ops = {
-	.alloc_coherent = dma_direct_alloc_coherent,
-	.free_coherent = dma_direct_free_coherent,
-	.map_sg = swiotlb_map_sg_attrs,
-	.unmap_sg = swiotlb_unmap_sg_attrs,
-	.dma_supported = swiotlb_dma_supported,
-	.map_page = swiotlb_map_page,
-	.unmap_page = swiotlb_unmap_page,
-	.addr_needs_map = swiotlb_pci_addr_needs_map,
-	.sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
-	.sync_single_range_for_device = swiotlb_sync_single_range_for_device,
-	.sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
-	.sync_sg_for_device = swiotlb_sync_sg_for_device
-};
+void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
+{
+	struct pci_controller *hose;
+	struct dev_archdata *sd;
+
+	hose = pci_bus_to_host(pdev->bus);
+	sd = &pdev->dev.archdata;
+	sd->max_direct_dma_addr =
+		hose->dma_window_base_cur + hose->dma_window_size;
+}
 
 static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
 				  unsigned long action, void *data)
 {
 	struct device *dev = data;
+	struct dev_archdata *sd;
 
 	/* We are only intereted in device addition */
 	if (action != BUS_NOTIFY_ADD_DEVICE)
 		return 0;
 
+	sd = &dev->archdata;
+	sd->max_direct_dma_addr = 0;
+
 	/* May need to bounce if the device can't address all of DRAM */
 	if (dma_get_mask(dev) < lmb_end_of_DRAM())
 		set_dma_ops(dev, &swiotlb_dma_ops);
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index ccf129d..21b784d 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -7,6 +7,7 @@
 
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <linux/dma-debug.h>
 #include <linux/lmb.h>
 #include <asm/bug.h>
 #include <asm/abs_addr.h>
@@ -140,7 +141,7 @@ static inline void dma_direct_sync_single_range(struct device *dev,
 }
 #endif
 
-struct dma_mapping_ops dma_direct_ops = {
+struct dma_map_ops dma_direct_ops = {
 	.alloc_coherent	= dma_direct_alloc_coherent,
 	.free_coherent	= dma_direct_free_coherent,
 	.map_sg		= dma_direct_map_sg,
@@ -156,3 +157,13 @@ struct dma_mapping_ops dma_direct_ops = {
 #endif
 };
 EXPORT_SYMBOL(dma_direct_ops);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16)
+
+static int __init dma_init(void)
+{
+       dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+
+       return 0;
+}
+fs_initcall(dma_init);
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 3cadba6..1175a85 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -88,7 +88,7 @@ crit_transfer_to_handler:
 	mfspr	r0,SPRN_SRR1
 	stw	r0,_SRR1(r11)
 
-	mfspr	r8,SPRN_SPRG3
+	mfspr	r8,SPRN_SPRG_THREAD
 	lwz	r0,KSP_LIMIT(r8)
 	stw	r0,SAVED_KSP_LIMIT(r11)
 	rlwimi	r0,r1,0,0,(31-THREAD_SHIFT)
@@ -108,7 +108,7 @@ crit_transfer_to_handler:
 	mfspr	r0,SPRN_SRR1
 	stw	r0,crit_srr1@l(0)
 
-	mfspr	r8,SPRN_SPRG3
+	mfspr	r8,SPRN_SPRG_THREAD
 	lwz	r0,KSP_LIMIT(r8)
 	stw	r0,saved_ksp_limit@l(0)
 	rlwimi	r0,r1,0,0,(31-THREAD_SHIFT)
@@ -138,7 +138,7 @@ transfer_to_handler:
 	mfspr	r2,SPRN_XER
 	stw	r12,_CTR(r11)
 	stw	r2,_XER(r11)
-	mfspr	r12,SPRN_SPRG3
+	mfspr	r12,SPRN_SPRG_THREAD
 	addi	r2,r12,-THREAD
 	tovirt(r2,r2)			/* set r2 to current */
 	beq	2f			/* if from user, fix up THREAD.regs */
@@ -680,7 +680,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)
 
 	tophys(r0,r4)
 	CLR_TOP32(r0)
-	mtspr	SPRN_SPRG3,r0	/* Update current THREAD phys addr */
+	mtspr	SPRN_SPRG_THREAD,r0	/* Update current THREAD phys addr */
 	lwz	r1,KSP(r4)	/* Load new stack pointer */
 
 	/* save the old current 'last' for return value */
@@ -1057,7 +1057,7 @@ exc_exit_restart_end:
 #ifdef CONFIG_40x
 	.globl	ret_from_crit_exc
 ret_from_crit_exc:
-	mfspr	r9,SPRN_SPRG3
+	mfspr	r9,SPRN_SPRG_THREAD
 	lis	r10,saved_ksp_limit@ha;
 	lwz	r10,saved_ksp_limit@l(r10);
 	tovirt(r9,r9);
@@ -1074,7 +1074,7 @@ ret_from_crit_exc:
 #ifdef CONFIG_BOOKE
 	.globl	ret_from_crit_exc
 ret_from_crit_exc:
-	mfspr	r9,SPRN_SPRG3
+	mfspr	r9,SPRN_SPRG_THREAD
 	lwz	r10,SAVED_KSP_LIMIT(r1)
 	stw	r10,KSP_LIMIT(r9)
 	RESTORE_xSRR(SRR0,SRR1);
@@ -1083,7 +1083,7 @@ ret_from_crit_exc:
 
 	.globl	ret_from_debug_exc
 ret_from_debug_exc:
-	mfspr	r9,SPRN_SPRG3
+	mfspr	r9,SPRN_SPRG_THREAD
 	lwz	r10,SAVED_KSP_LIMIT(r1)
 	stw	r10,KSP_LIMIT(r9)
 	lwz	r9,THREAD_INFO-THREAD(r9)
@@ -1097,7 +1097,7 @@ ret_from_debug_exc:
 
 	.globl	ret_from_mcheck_exc
 ret_from_mcheck_exc:
-	mfspr	r9,SPRN_SPRG3
+	mfspr	r9,SPRN_SPRG_THREAD
 	lwz	r10,SAVED_KSP_LIMIT(r1)
 	stw	r10,KSP_LIMIT(r9)
 	RESTORE_xSRR(SRR0,SRR1);
@@ -1255,7 +1255,7 @@ _GLOBAL(enter_rtas)
 	MTMSRD(r0)		/* don't get trashed */
 	li	r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
 	mtlr	r6
-	mtspr	SPRN_SPRG2,r7
+	mtspr	SPRN_SPRG_RTAS,r7
 	mtspr	SPRN_SRR0,r8
 	mtspr	SPRN_SRR1,r9
 	RFI
@@ -1265,7 +1265,7 @@ _GLOBAL(enter_rtas)
 	FIX_SRR1(r9,r0)
 	addi	r1,r1,INT_FRAME_SIZE
 	li	r0,0
-	mtspr	SPRN_SPRG2,r0
+	mtspr	SPRN_SPRG_RTAS,r0
 	mtspr	SPRN_SRR0,r8
 	mtspr	SPRN_SRR1,r9
 	RFI			/* return to caller */
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 43e0734..900e0ee 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -120,9 +120,15 @@ BEGIN_FW_FTR_SECTION
 2:
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif /* CONFIG_PPC_ISERIES */
+
+	/* Hard enable interrupts */
+#ifdef CONFIG_PPC_BOOK3E
+	wrteei	1
+#else
 	mfmsr	r11
 	ori	r11,r11,MSR_EE
 	mtmsrd	r11,1
+#endif /* CONFIG_PPC_BOOK3E */
 
 #ifdef SHOW_SYSCALLS
 	bl	.do_show_syscall
@@ -168,15 +174,25 @@ syscall_exit:
 #endif
 	clrrdi	r12,r1,THREAD_SHIFT
 
-	/* disable interrupts so current_thread_info()->flags can't change,
-	   and so that we don't get interrupted after loading SRR0/1. */
 	ld	r8,_MSR(r1)
+#ifdef CONFIG_PPC_BOOK3S
+	/* No MSR:RI on BookE */
 	andi.	r10,r8,MSR_RI
 	beq-	unrecov_restore
+#endif
+
+	/* Disable interrupts so current_thread_info()->flags can't change,
+	 * and so that we don't get interrupted after loading SRR0/1.
+	 */
+#ifdef CONFIG_PPC_BOOK3E
+	wrteei	0
+#else
 	mfmsr	r10
 	rldicl	r10,r10,48,1
 	rotldi	r10,r10,16
 	mtmsrd	r10,1
+#endif /* CONFIG_PPC_BOOK3E */
+
 	ld	r9,TI_FLAGS(r12)
 	li	r11,-_LAST_ERRNO
 	andi.	r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
@@ -194,9 +210,13 @@ syscall_error_cont:
 	 * userspace and we take an exception after restoring r13,
 	 * we end up corrupting the userspace r13 value.
 	 */
+#ifdef CONFIG_PPC_BOOK3S
+	/* No MSR:RI on BookE */
 	li	r12,MSR_RI
 	andc	r11,r10,r12
 	mtmsrd	r11,1			/* clear MSR.RI */
+#endif /* CONFIG_PPC_BOOK3S */
+
 	beq-	1f
 	ACCOUNT_CPU_USER_EXIT(r11, r12)
 	ld	r13,GPR13(r1)	/* only restore r13 if returning to usermode */
@@ -206,7 +226,7 @@ syscall_error_cont:
 	mtcr	r5
 	mtspr	SPRN_SRR0,r7
 	mtspr	SPRN_SRR1,r8
-	rfid
+	RFI
 	b	.	/* prevent speculative execution */
 
 syscall_error:	
@@ -276,9 +296,13 @@ syscall_exit_work:
 	beq	.ret_from_except_lite
 
 	/* Re-enable interrupts */
+#ifdef CONFIG_PPC_BOOK3E
+	wrteei	1
+#else
 	mfmsr	r10
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1
+#endif /* CONFIG_PPC_BOOK3E */
 
 	bl	.save_nvgprs
 	addi	r3,r1,STACK_FRAME_OVERHEAD
@@ -380,7 +404,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	and.	r0,r0,r22
 	beq+	1f
 	andc	r22,r22,r0
-	mtmsrd	r22
+	MTMSRD(r22)
 	isync
 1:	std	r20,_NIP(r1)
 	mfcr	r23
@@ -399,6 +423,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	std	r6,PACACURRENT(r13)	/* Set new 'current' */
 
 	ld	r8,KSP(r4)	/* new stack pointer */
+#ifdef CONFIG_PPC_BOOK3S
 BEGIN_FTR_SECTION
   BEGIN_FTR_SECTION_NESTED(95)
 	clrrdi	r6,r8,28	/* get its ESID */
@@ -445,8 +470,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
 	slbie	r6		/* Workaround POWER5 < DD2.1 issue */
 	slbmte	r7,r0
 	isync
-
 2:
+#endif /* !CONFIG_PPC_BOOK3S */
+
 	clrrdi	r7,r8,THREAD_SHIFT	/* base of new stack */
 	/* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
 	   because we don't need to leave the 288-byte ABI gap at the
@@ -490,10 +516,14 @@ _GLOBAL(ret_from_except_lite)
 	 * can't change between when we test it and when we return
 	 * from the interrupt.
 	 */
+#ifdef CONFIG_PPC_BOOK3E
+	wrteei	0
+#else
 	mfmsr	r10		/* Get current interrupt state */
 	rldicl	r9,r10,48,1	/* clear MSR_EE */
 	rotldi	r9,r9,16
 	mtmsrd	r9,1		/* Update machine state */
+#endif /* CONFIG_PPC_BOOK3E */
 
 #ifdef CONFIG_PREEMPT
 	clrrdi	r9,r1,THREAD_SHIFT	/* current_thread_info() */
@@ -526,20 +556,23 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
 2:
 	TRACE_AND_RESTORE_IRQ(r5);
 
-#ifdef CONFIG_PERF_COUNTERS
-	/* check paca->perf_counter_pending if we're enabling ints */
+#ifdef CONFIG_PERF_EVENTS
+	/* check paca->perf_event_pending if we're enabling ints */
 	lbz	r3,PACAPERFPEND(r13)
 	and.	r3,r3,r5
 	beq	27f
-	bl	.perf_counter_do_pending
+	bl	.perf_event_do_pending
 27:
-#endif /* CONFIG_PERF_COUNTERS */
+#endif /* CONFIG_PERF_EVENTS */
 
 	/* extract EE bit and use it to restore paca->hard_enabled */
 	ld	r3,_MSR(r1)
 	rldicl	r4,r3,49,63		/* r0 = (r3 >> 15) & 1 */
 	stb	r4,PACAHARDIRQEN(r13)
 
+#ifdef CONFIG_PPC_BOOK3E
+	b	.exception_return_book3e
+#else
 	ld	r4,_CTR(r1)
 	ld	r0,_LINK(r1)
 	mtctr	r4
@@ -588,6 +621,8 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
 	rfid
 	b	.	/* prevent speculative execution */
 
+#endif /* CONFIG_PPC_BOOK3E */
+
 iseries_check_pending_irqs:
 #ifdef CONFIG_PPC_ISERIES
 	ld	r5,SOFTE(r1)
@@ -638,6 +673,11 @@ do_work:
 	li	r0,1
 	stb	r0,PACASOFTIRQEN(r13)
 	stb	r0,PACAHARDIRQEN(r13)
+#ifdef CONFIG_PPC_BOOK3E
+	wrteei	1
+	bl	.preempt_schedule
+	wrteei	0
+#else
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1		/* reenable interrupts */
 	bl	.preempt_schedule
@@ -646,6 +686,7 @@ do_work:
 	rldicl	r10,r10,48,1	/* disable interrupts again */
 	rotldi	r10,r10,16
 	mtmsrd	r10,1
+#endif /* CONFIG_PPC_BOOK3E */
 	ld	r4,TI_FLAGS(r9)
 	andi.	r0,r4,_TIF_NEED_RESCHED
 	bne	1b
@@ -654,8 +695,12 @@ do_work:
 user_work:
 #endif
 	/* Enable interrupts */
+#ifdef CONFIG_PPC_BOOK3E
+	wrteei	1
+#else
 	ori	r10,r10,MSR_EE
 	mtmsrd	r10,1
+#endif /* CONFIG_PPC_BOOK3E */
 
 	andi.	r0,r4,_TIF_NEED_RESCHED
 	beq	1f
@@ -762,7 +807,7 @@ _GLOBAL(enter_rtas)
 
 _STATIC(rtas_return_loc)
 	/* relocation is off at this point */
-	mfspr	r4,SPRN_SPRG3	        /* Get PACA */
+	mfspr	r4,SPRN_SPRG_PACA	/* Get PACA */
 	clrldi	r4,r4,2			/* convert to realmode address */
 
 	bcl	20,31,$+4
@@ -793,7 +838,7 @@ _STATIC(rtas_restore_regs)
 	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
 	REST_10GPRS(22, r1)		/* ditto */
 
-	mfspr	r13,SPRN_SPRG3
+	mfspr	r13,SPRN_SPRG_PACA
 
 	ld	r4,_CCR(r1)
 	mtcr	r4
@@ -823,33 +868,24 @@ _GLOBAL(enter_prom)
 	 * of all registers that it saves.  We therefore save those registers
 	 * PROM might touch to the stack.  (r0, r3-r13 are caller saved)
    	 */
-	SAVE_8GPRS(2, r1)
+	SAVE_GPR(2, r1)
 	SAVE_GPR(13, r1)
 	SAVE_8GPRS(14, r1)
 	SAVE_10GPRS(22, r1)
-	mfcr	r4
-	std	r4,_CCR(r1)
-	mfctr	r5
-	std	r5,_CTR(r1)
-	mfspr	r6,SPRN_XER
-	std	r6,_XER(r1)
-	mfdar	r7
-	std	r7,_DAR(r1)
-	mfdsisr	r8
-	std	r8,_DSISR(r1)
-	mfsrr0	r9
-	std	r9,_SRR0(r1)
-	mfsrr1	r10
-	std	r10,_SRR1(r1)
+	mfcr	r10
 	mfmsr	r11
+	std	r10,_CCR(r1)
 	std	r11,_MSR(r1)
 
 	/* Get the PROM entrypoint */
-	ld	r0,GPR4(r1)
-	mtlr	r0
+	mtlr	r4
 
 	/* Switch MSR to 32 bits mode
 	 */
+#ifdef CONFIG_PPC_BOOK3E
+	rlwinm	r11,r11,0,1,31
+	mtmsr	r11
+#else /* CONFIG_PPC_BOOK3E */
         mfmsr   r11
         li      r12,1
         rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
@@ -858,10 +894,10 @@ _GLOBAL(enter_prom)
         rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
         andc    r11,r11,r12
         mtmsrd  r11
+#endif /* CONFIG_PPC_BOOK3E */
         isync
 
-	/* Restore arguments & enter PROM here... */
-	ld	r3,GPR3(r1)
+	/* Enter PROM here... */
 	blrl
 
 	/* Just make sure that r1 top 32 bits didn't get
@@ -871,7 +907,7 @@ _GLOBAL(enter_prom)
 
 	/* Restore the MSR (back to 64 bits) */
 	ld	r0,_MSR(r1)
-	mtmsrd	r0
+	MTMSRD(r0)
         isync
 
 	/* Restore other registers */
@@ -881,18 +917,6 @@ _GLOBAL(enter_prom)
 	REST_10GPRS(22, r1)
 	ld	r4,_CCR(r1)
 	mtcr	r4
-	ld	r5,_CTR(r1)
-	mtctr	r5
-	ld	r6,_XER(r1)
-	mtspr	SPRN_XER,r6
-	ld	r7,_DAR(r1)
-	mtdar	r7
-	ld	r8,_DSISR(r1)
-	mtdsisr	r8
-	ld	r9,_SRR0(r1)
-	mtsrr0	r9
-	ld	r10,_SRR1(r1)
-	mtsrr1	r10
 	
         addi	r1,r1,PROM_FRAME_SIZE
 	ld	r0,16(r1)
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
new file mode 100644
index 0000000..9048f96
--- /dev/null
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -0,0 +1,1001 @@
+/*
+ *  Boot code and exception vectors for Book3E processors
+ *
+ *  Copyright (C) 2007 Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+#include <asm/setup.h>
+#include <asm/thread_info.h>
+#include <asm/reg.h>
+#include <asm/exception-64e.h>
+#include <asm/bug.h>
+#include <asm/irqflags.h>
+#include <asm/ptrace.h>
+#include <asm/ppc-opcode.h>
+#include <asm/mmu.h>
+
+/* XXX This will ultimately add space for a special exception save
+ *     structure used to save things like SRR0/SRR1, SPRGs, MAS, etc...
+ *     when taking special interrupts. For now we don't support that,
+ *     special interrupts from within a non-standard level will probably
+ *     blow you up
+ */
+#define	SPECIAL_EXC_FRAME_SIZE	INT_FRAME_SIZE
+
+/* Exception prolog code for all exceptions */
+#define EXCEPTION_PROLOG(n, type, addition)				    \
+	mtspr	SPRN_SPRG_##type##_SCRATCH,r13;	/* get spare registers */   \
+	mfspr	r13,SPRN_SPRG_PACA;	/* get PACA */			    \
+	std	r10,PACA_EX##type+EX_R10(r13);				    \
+	std	r11,PACA_EX##type+EX_R11(r13);				    \
+	mfcr	r10;			/* save CR */			    \
+	addition;			/* additional code for that exc. */ \
+	std	r1,PACA_EX##type+EX_R1(r13); /* save old r1 in the PACA */  \
+	stw	r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \
+	mfspr	r11,SPRN_##type##_SRR1;/* what are we coming from */	    \
+	type##_SET_KSTACK;		/* get special stack if necessary */\
+	andi.	r10,r11,MSR_PR;		/* save stack pointer */	    \
+	beq	1f;			/* branch around if supervisor */   \
+	ld	r1,PACAKSAVE(r13);	/* get kernel stack coming from usr */\
+1:	cmpdi	cr1,r1,0;		/* check if SP makes sense */	    \
+	bge-	cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \
+	mfspr	r10,SPRN_##type##_SRR0;	/* read SRR0 before touching stack */
+
+/* Exception type-specific macros */
+#define	GEN_SET_KSTACK							    \
+	subi	r1,r1,INT_FRAME_SIZE;	/* alloc frame on kernel stack */
+#define SPRN_GEN_SRR0	SPRN_SRR0
+#define SPRN_GEN_SRR1	SPRN_SRR1
+
+#define CRIT_SET_KSTACK						            \
+	ld	r1,PACA_CRIT_STACK(r13);				    \
+	subi	r1,r1,SPECIAL_EXC_FRAME_SIZE;
+#define SPRN_CRIT_SRR0	SPRN_CSRR0
+#define SPRN_CRIT_SRR1	SPRN_CSRR1
+
+#define DBG_SET_KSTACK						            \
+	ld	r1,PACA_DBG_STACK(r13);					    \
+	subi	r1,r1,SPECIAL_EXC_FRAME_SIZE;
+#define SPRN_DBG_SRR0	SPRN_DSRR0
+#define SPRN_DBG_SRR1	SPRN_DSRR1
+
+#define MC_SET_KSTACK						            \
+	ld	r1,PACA_MC_STACK(r13);					    \
+	subi	r1,r1,SPECIAL_EXC_FRAME_SIZE;
+#define SPRN_MC_SRR0	SPRN_MCSRR0
+#define SPRN_MC_SRR1	SPRN_MCSRR1
+
+#define NORMAL_EXCEPTION_PROLOG(n, addition)				    \
+	EXCEPTION_PROLOG(n, GEN, addition##_GEN)
+
+#define CRIT_EXCEPTION_PROLOG(n, addition)				    \
+	EXCEPTION_PROLOG(n, CRIT, addition##_CRIT)
+
+#define DBG_EXCEPTION_PROLOG(n, addition)				    \
+	EXCEPTION_PROLOG(n, DBG, addition##_DBG)
+
+#define MC_EXCEPTION_PROLOG(n, addition)				    \
+	EXCEPTION_PROLOG(n, MC, addition##_MC)
+
+
+/* Variants of the "addition" argument for the prolog
+ */
+#define PROLOG_ADDITION_NONE_GEN
+#define PROLOG_ADDITION_NONE_CRIT
+#define PROLOG_ADDITION_NONE_DBG
+#define PROLOG_ADDITION_NONE_MC
+
+#define PROLOG_ADDITION_MASKABLE_GEN					    \
+	lbz	r11,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */	    \
+	cmpwi	cr0,r11,0;		/* yes -> go out of line */	    \
+	beq	masked_interrupt_book3e;
+
+#define PROLOG_ADDITION_2REGS_GEN					    \
+	std	r14,PACA_EXGEN+EX_R14(r13);				    \
+	std	r15,PACA_EXGEN+EX_R15(r13)
+
+#define PROLOG_ADDITION_1REG_GEN					    \
+	std	r14,PACA_EXGEN+EX_R14(r13);
+
+#define PROLOG_ADDITION_2REGS_CRIT					    \
+	std	r14,PACA_EXCRIT+EX_R14(r13);				    \
+	std	r15,PACA_EXCRIT+EX_R15(r13)
+
+#define PROLOG_ADDITION_2REGS_DBG					    \
+	std	r14,PACA_EXDBG+EX_R14(r13);				    \
+	std	r15,PACA_EXDBG+EX_R15(r13)
+
+#define PROLOG_ADDITION_2REGS_MC					    \
+	std	r14,PACA_EXMC+EX_R14(r13);				    \
+	std	r15,PACA_EXMC+EX_R15(r13)
+
+/* Core exception code for all exceptions except TLB misses.
+ * XXX: Needs to make SPRN_SPRG_GEN depend on exception type
+ */
+#define EXCEPTION_COMMON(n, excf, ints)					    \
+	std	r0,GPR0(r1);		/* save r0 in stackframe */	    \
+	std	r2,GPR2(r1);		/* save r2 in stackframe */	    \
+	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe */    \
+	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe */	    \
+	std	r9,GPR9(r1);		/* save r9 in stackframe */	    \
+	std	r10,_NIP(r1);		/* save SRR0 to stackframe */	    \
+	std	r11,_MSR(r1);		/* save SRR1 to stackframe */	    \
+	ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */	    \
+	ld	r3,excf+EX_R10(r13);	/* get back r10 */		    \
+	ld	r4,excf+EX_R11(r13);	/* get back r11 */		    \
+	mfspr	r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 */		    \
+	std	r12,GPR12(r1);		/* save r12 in stackframe */	    \
+	ld	r2,PACATOC(r13);	/* get kernel TOC into r2 */	    \
+	mflr	r6;			/* save LR in stackframe */	    \
+	mfctr	r7;			/* save CTR in stackframe */	    \
+	mfspr	r8,SPRN_XER;		/* save XER in stackframe */	    \
+	ld	r9,excf+EX_R1(r13);	/* load orig r1 back from PACA */   \
+	lwz	r10,excf+EX_CR(r13);	/* load orig CR back from PACA	*/  \
+	lbz	r11,PACASOFTIRQEN(r13);	/* get current IRQ softe */	    \
+	ld	r12,exception_marker@toc(r2);				    \
+	li	r0,0;							    \
+	std	r3,GPR10(r1);		/* save r10 to stackframe */	    \
+	std	r4,GPR11(r1);		/* save r11 to stackframe */	    \
+	std	r5,GPR13(r1);		/* save it to stackframe */	    \
+	std	r6,_LINK(r1);						    \
+	std	r7,_CTR(r1);						    \
+	std	r8,_XER(r1);						    \
+	li	r3,(n)+1;		/* indicate partial regs in trap */ \
+	std	r9,0(r1);		/* store stack frame back link */   \
+	std	r10,_CCR(r1);		/* store orig CR in stackframe */   \
+	std	r9,GPR1(r1);		/* store stack frame back link */   \
+	std	r11,SOFTE(r1);		/* and save it to stackframe */     \
+	std	r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */	    \
+	std	r3,_TRAP(r1);		/* set trap number		*/  \
+	std	r0,RESULT(r1);		/* clear regs->result */	    \
+	ints;
+
+/* Variants for the "ints" argument */
+#define INTS_KEEP
+#define INTS_DISABLE_SOFT						    \
+	stb	r0,PACASOFTIRQEN(r13);	/* mark interrupts soft-disabled */ \
+	TRACE_DISABLE_INTS;
+#define INTS_DISABLE_HARD						    \
+	stb	r0,PACAHARDIRQEN(r13); /* and hard disabled */
+#define INTS_DISABLE_ALL						    \
+	INTS_DISABLE_SOFT						    \
+	INTS_DISABLE_HARD
+
+/* This is called by exceptions that used INTS_KEEP (that is did not clear
+ * neither soft nor hard IRQ indicators in the PACA. This will restore MSR:EE
+ * to it's previous value
+ *
+ * XXX In the long run, we may want to open-code it in order to separate the
+ *     load from the wrtee, thus limiting the latency caused by the dependency
+ *     but at this point, I'll favor code clarity until we have a near to final
+ *     implementation
+ */
+#define INTS_RESTORE_HARD						    \
+	ld	r11,_MSR(r1);						    \
+	wrtee	r11;
+
+/* XXX FIXME: Restore r14/r15 when necessary */
+#define BAD_STACK_TRAMPOLINE(n)						    \
+exc_##n##_bad_stack:							    \
+	li	r1,(n);			/* get exception number */	    \
+	sth	r1,PACA_TRAP_SAVE(r13);	/* store trap */		    \
+	b	bad_stack_book3e;	/* bad stack error */
+
+#define	EXCEPTION_STUB(loc, label)					\
+	. = interrupt_base_book3e + loc;				\
+	nop;	/* To make debug interrupts happy */			\
+	b	exc_##label##_book3e;
+
+#define ACK_NONE(r)
+#define ACK_DEC(r)							\
+	lis	r,TSR_DIS@h;						\
+	mtspr	SPRN_TSR,r
+#define ACK_FIT(r)							\
+	lis	r,TSR_FIS@h;						\
+	mtspr	SPRN_TSR,r
+
+#define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack)			\
+	START_EXCEPTION(label);						\
+	NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE)	\
+	EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE_ALL)		\
+	ack(r8);							\
+	addi	r3,r1,STACK_FRAME_OVERHEAD;				\
+	bl	hdlr;							\
+	b	.ret_from_except_lite;
+
+/* This value is used to mark exception frames on the stack. */
+	.section	".toc","aw"
+exception_marker:
+	.tc	ID_EXC_MARKER[TC],STACK_FRAME_REGS_MARKER
+
+
+/*
+ * And here we have the exception vectors !
+ */
+
+	.text
+	.balign	0x1000
+	.globl interrupt_base_book3e
+interrupt_base_book3e:					/* fake trap */
+	/* Note: If real debug exceptions are supported by the HW, the vector
+	 * below will have to be patched up to point to an appropriate handler
+	 */
+	EXCEPTION_STUB(0x000, machine_check)		/* 0x0200 */
+	EXCEPTION_STUB(0x020, critical_input)		/* 0x0580 */
+	EXCEPTION_STUB(0x040, debug_crit)		/* 0x0d00 */
+	EXCEPTION_STUB(0x060, data_storage)		/* 0x0300 */
+	EXCEPTION_STUB(0x080, instruction_storage)	/* 0x0400 */
+	EXCEPTION_STUB(0x0a0, external_input)		/* 0x0500 */
+	EXCEPTION_STUB(0x0c0, alignment)		/* 0x0600 */
+	EXCEPTION_STUB(0x0e0, program)			/* 0x0700 */
+	EXCEPTION_STUB(0x100, fp_unavailable)		/* 0x0800 */
+	EXCEPTION_STUB(0x120, system_call)		/* 0x0c00 */
+	EXCEPTION_STUB(0x140, ap_unavailable)		/* 0x0f20 */
+	EXCEPTION_STUB(0x160, decrementer)		/* 0x0900 */
+	EXCEPTION_STUB(0x180, fixed_interval)		/* 0x0980 */
+	EXCEPTION_STUB(0x1a0, watchdog)			/* 0x09f0 */
+	EXCEPTION_STUB(0x1c0, data_tlb_miss)
+	EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
+
+#if 0
+	EXCEPTION_STUB(0x280, processor_doorbell)
+	EXCEPTION_STUB(0x220, processor_doorbell_crit)
+#endif
+	.globl interrupt_end_book3e
+interrupt_end_book3e:
+
+/* Critical Input Interrupt */
+	START_EXCEPTION(critical_input);
+	CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE)
+//	EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE_ALL)
+//	bl	special_reg_save_crit
+//	addi	r3,r1,STACK_FRAME_OVERHEAD
+//	bl	.critical_exception
+//	b	ret_from_crit_except
+	b	.
+
+/* Machine Check Interrupt */
+	START_EXCEPTION(machine_check);
+	CRIT_EXCEPTION_PROLOG(0x200, PROLOG_ADDITION_NONE)
+//	EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE_ALL)
+//	bl	special_reg_save_mc
+//	addi	r3,r1,STACK_FRAME_OVERHEAD
+//	bl	.machine_check_exception
+//	b	ret_from_mc_except
+	b	.
+
+/* Data Storage Interrupt */
+	START_EXCEPTION(data_storage)
+	NORMAL_EXCEPTION_PROLOG(0x300, PROLOG_ADDITION_2REGS)
+	mfspr	r14,SPRN_DEAR
+	mfspr	r15,SPRN_ESR
+	EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_KEEP)
+	b	storage_fault_common
+
+/* Instruction Storage Interrupt */
+	START_EXCEPTION(instruction_storage);
+	NORMAL_EXCEPTION_PROLOG(0x400, PROLOG_ADDITION_2REGS)
+	li	r15,0
+	mr	r14,r10
+	EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_KEEP)
+	b	storage_fault_common
+
+/* External Input Interrupt */
+	MASKABLE_EXCEPTION(0x500, external_input, .do_IRQ, ACK_NONE)
+
+/* Alignment */
+	START_EXCEPTION(alignment);
+	NORMAL_EXCEPTION_PROLOG(0x600, PROLOG_ADDITION_2REGS)
+	mfspr	r14,SPRN_DEAR
+	mfspr	r15,SPRN_ESR
+	EXCEPTION_COMMON(0x600, PACA_EXGEN, INTS_KEEP)
+	b	alignment_more	/* no room, go out of line */
+
+/* Program Interrupt */
+	START_EXCEPTION(program);
+	NORMAL_EXCEPTION_PROLOG(0x700, PROLOG_ADDITION_1REG)
+	mfspr	r14,SPRN_ESR
+	EXCEPTION_COMMON(0x700, PACA_EXGEN, INTS_DISABLE_SOFT)
+	std	r14,_DSISR(r1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	ld	r14,PACA_EXGEN+EX_R14(r13)
+	bl	.save_nvgprs
+	INTS_RESTORE_HARD
+	bl	.program_check_exception
+	b	.ret_from_except
+
+/* Floating Point Unavailable Interrupt */
+	START_EXCEPTION(fp_unavailable);
+	NORMAL_EXCEPTION_PROLOG(0x800, PROLOG_ADDITION_NONE)
+	/* we can probably do a shorter exception entry for that one... */
+	EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP)
+	bne	1f			/* if from user, just load it up */
+	bl	.save_nvgprs
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	INTS_RESTORE_HARD
+	bl	.kernel_fp_unavailable_exception
+	BUG_OPCODE
+1:	ld	r12,_MSR(r1)
+	bl	.load_up_fpu
+	b	fast_exception_return
+
+/* Decrementer Interrupt */
+	MASKABLE_EXCEPTION(0x900, decrementer, .timer_interrupt, ACK_DEC)
+
+/* Fixed Interval Timer Interrupt */
+	MASKABLE_EXCEPTION(0x980, fixed_interval, .unknown_exception, ACK_FIT)
+
+/* Watchdog Timer Interrupt */
+	START_EXCEPTION(watchdog);
+	CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE)
+//	EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE_ALL)
+//	bl	special_reg_save_crit
+//	addi	r3,r1,STACK_FRAME_OVERHEAD
+//	bl	.unknown_exception
+//	b	ret_from_crit_except
+	b	.
+
+/* System Call Interrupt */
+	START_EXCEPTION(system_call)
+	mr	r9,r13			/* keep a copy of userland r13 */
+	mfspr	r11,SPRN_SRR0		/* get return address */
+	mfspr	r12,SPRN_SRR1		/* get previous MSR */
+	mfspr	r13,SPRN_SPRG_PACA	/* get our PACA */
+	b	system_call_common
+
+/* Auxillary Processor Unavailable Interrupt */
+	START_EXCEPTION(ap_unavailable);
+	NORMAL_EXCEPTION_PROLOG(0xf20, PROLOG_ADDITION_NONE)
+	EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_KEEP)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	.save_nvgprs
+	INTS_RESTORE_HARD
+	bl	.unknown_exception
+	b	.ret_from_except
+
+/* Debug exception as a critical interrupt*/
+	START_EXCEPTION(debug_crit);
+	CRIT_EXCEPTION_PROLOG(0xd00, PROLOG_ADDITION_2REGS)
+
+	/*
+	 * If there is a single step or branch-taken exception in an
+	 * exception entry sequence, it was probably meant to apply to
+	 * the code where the exception occurred (since exception entry
+	 * doesn't turn off DE automatically).  We simulate the effect
+	 * of turning off DE on entry to an exception handler by turning
+	 * off DE in the CSRR1 value and clearing the debug status.
+	 */
+
+	mfspr	r14,SPRN_DBSR		/* check single-step/branch taken */
+	andis.	r15,r14,DBSR_IC@h
+	beq+	1f
+
+	LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
+	LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
+	cmpld	cr0,r10,r14
+	cmpld	cr1,r10,r15
+	blt+	cr0,1f
+	bge+	cr1,1f
+
+	/* here it looks like we got an inappropriate debug exception. */
+	lis	r14,DBSR_IC@h		/* clear the IC event */
+	rlwinm	r11,r11,0,~MSR_DE	/* clear DE in the CSRR1 value */
+	mtspr	SPRN_DBSR,r14
+	mtspr	SPRN_CSRR1,r11
+	lwz	r10,PACA_EXCRIT+EX_CR(r13)	/* restore registers */
+	ld	r1,PACA_EXCRIT+EX_R1(r13)
+	ld	r14,PACA_EXCRIT+EX_R14(r13)
+	ld	r15,PACA_EXCRIT+EX_R15(r13)
+	mtcr	r10
+	ld	r10,PACA_EXCRIT+EX_R10(r13)	/* restore registers */
+	ld	r11,PACA_EXCRIT+EX_R11(r13)
+	mfspr	r13,SPRN_SPRG_CRIT_SCRATCH
+	rfci
+
+	/* Normal debug exception */
+	/* XXX We only handle coming from userspace for now since we can't
+	 *     quite save properly an interrupted kernel state yet
+	 */
+1:	andi.	r14,r11,MSR_PR;		/* check for userspace again */
+	beq	kernel_dbg_exc;		/* if from kernel mode */
+
+	/* Now we mash up things to make it look like we are coming on a
+	 * normal exception
+	 */
+	mfspr	r15,SPRN_SPRG_CRIT_SCRATCH
+	mtspr	SPRN_SPRG_GEN_SCRATCH,r15
+	mfspr	r14,SPRN_DBSR
+	EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE_ALL)
+	std	r14,_DSISR(r1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	mr	r4,r14
+	ld	r14,PACA_EXCRIT+EX_R14(r13)
+	ld	r15,PACA_EXCRIT+EX_R15(r13)
+	bl	.save_nvgprs
+	bl	.DebugException
+	b	.ret_from_except
+
+kernel_dbg_exc:
+	b	.	/* NYI */
+
+
+/*
+ * An interrupt came in while soft-disabled; clear EE in SRR1,
+ * clear paca->hard_enabled and return.
+ */
+masked_interrupt_book3e:
+	mtcr	r10
+	stb	r11,PACAHARDIRQEN(r13)
+	mfspr	r10,SPRN_SRR1
+	rldicl	r11,r10,48,1		/* clear MSR_EE */
+	rotldi	r10,r11,16
+	mtspr	SPRN_SRR1,r10
+	ld	r10,PACA_EXGEN+EX_R10(r13);	/* restore registers */
+	ld	r11,PACA_EXGEN+EX_R11(r13);
+	mfspr	r13,SPRN_SPRG_GEN_SCRATCH;
+	rfi
+	b	.
+
+/*
+ * This is called from 0x300 and 0x400 handlers after the prologs with
+ * r14 and r15 containing the fault address and error code, with the
+ * original values stashed away in the PACA
+ */
+storage_fault_common:
+	std	r14,_DAR(r1)
+	std	r15,_DSISR(r1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	mr	r4,r14
+	mr	r5,r15
+	ld	r14,PACA_EXGEN+EX_R14(r13)
+	ld	r15,PACA_EXGEN+EX_R15(r13)
+	INTS_RESTORE_HARD
+	bl	.do_page_fault
+	cmpdi	r3,0
+	bne-	1f
+	b	.ret_from_except_lite
+1:	bl	.save_nvgprs
+	mr	r5,r3
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	ld	r4,_DAR(r1)
+	bl	.bad_page_fault
+	b	.ret_from_except
+
+/*
+ * Alignment exception doesn't fit entirely in the 0x100 bytes so it
+ * continues here.
+ */
+alignment_more:
+	std	r14,_DAR(r1)
+	std	r15,_DSISR(r1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	ld	r14,PACA_EXGEN+EX_R14(r13)
+	ld	r15,PACA_EXGEN+EX_R15(r13)
+	bl	.save_nvgprs
+	INTS_RESTORE_HARD
+	bl	.alignment_exception
+	b	.ret_from_except
+
+/*
+ * We branch here from entry_64.S for the last stage of the exception
+ * return code path. MSR:EE is expected to be off at that point
+ */
+_GLOBAL(exception_return_book3e)
+	b	1f
+
+/* This is the return from load_up_fpu fast path which could do with
+ * less GPR restores in fact, but for now we have a single return path
+ */
+	.globl fast_exception_return
+fast_exception_return:
+	wrteei	0
+1:	mr	r0,r13
+	ld	r10,_MSR(r1)
+	REST_4GPRS(2, r1)
+	andi.	r6,r10,MSR_PR
+	REST_2GPRS(6, r1)
+	beq	1f
+	ACCOUNT_CPU_USER_EXIT(r10, r11)
+	ld	r0,GPR13(r1)
+
+1:	stdcx.	r0,0,r1		/* to clear the reservation */
+
+	ld	r8,_CCR(r1)
+	ld	r9,_LINK(r1)
+	ld	r10,_CTR(r1)
+	ld	r11,_XER(r1)
+	mtcr	r8
+	mtlr	r9
+	mtctr	r10
+	mtxer	r11
+	REST_2GPRS(8, r1)
+	ld	r10,GPR10(r1)
+	ld	r11,GPR11(r1)
+	ld	r12,GPR12(r1)
+	mtspr	SPRN_SPRG_GEN_SCRATCH,r0
+
+	std	r10,PACA_EXGEN+EX_R10(r13);
+	std	r11,PACA_EXGEN+EX_R11(r13);
+	ld	r10,_NIP(r1)
+	ld	r11,_MSR(r1)
+	ld	r0,GPR0(r1)
+	ld	r1,GPR1(r1)
+	mtspr	SPRN_SRR0,r10
+	mtspr	SPRN_SRR1,r11
+	ld	r10,PACA_EXGEN+EX_R10(r13)
+	ld	r11,PACA_EXGEN+EX_R11(r13)
+	mfspr	r13,SPRN_SPRG_GEN_SCRATCH
+	rfi
+
+/*
+ * Trampolines used when spotting a bad kernel stack pointer in
+ * the exception entry code.
+ *
+ * TODO: move some bits like SRR0 read to trampoline, pass PACA
+ * index around, etc... to handle crit & mcheck
+ */
+BAD_STACK_TRAMPOLINE(0x000)
+BAD_STACK_TRAMPOLINE(0x100)
+BAD_STACK_TRAMPOLINE(0x200)
+BAD_STACK_TRAMPOLINE(0x300)
+BAD_STACK_TRAMPOLINE(0x400)
+BAD_STACK_TRAMPOLINE(0x500)
+BAD_STACK_TRAMPOLINE(0x600)
+BAD_STACK_TRAMPOLINE(0x700)
+BAD_STACK_TRAMPOLINE(0x800)
+BAD_STACK_TRAMPOLINE(0x900)
+BAD_STACK_TRAMPOLINE(0x980)
+BAD_STACK_TRAMPOLINE(0x9f0)
+BAD_STACK_TRAMPOLINE(0xa00)
+BAD_STACK_TRAMPOLINE(0xb00)
+BAD_STACK_TRAMPOLINE(0xc00)
+BAD_STACK_TRAMPOLINE(0xd00)
+BAD_STACK_TRAMPOLINE(0xe00)
+BAD_STACK_TRAMPOLINE(0xf00)
+BAD_STACK_TRAMPOLINE(0xf20)
+
+	.globl	bad_stack_book3e
+bad_stack_book3e:
+	/* XXX: Needs to make SPRN_SPRG_GEN depend on exception type */
+	mfspr	r10,SPRN_SRR0;		  /* read SRR0 before touching stack */
+	ld	r1,PACAEMERGSP(r13)
+	subi	r1,r1,64+INT_FRAME_SIZE
+	std	r10,_NIP(r1)
+	std	r11,_MSR(r1)
+	ld	r10,PACA_EXGEN+EX_R1(r13) /* FIXME for crit & mcheck */
+	lwz	r11,PACA_EXGEN+EX_CR(r13) /* FIXME for crit & mcheck */
+	std	r10,GPR1(r1)
+	std	r11,_CCR(r1)
+	mfspr	r10,SPRN_DEAR
+	mfspr	r11,SPRN_ESR
+	std	r10,_DAR(r1)
+	std	r11,_DSISR(r1)
+	std	r0,GPR0(r1);		/* save r0 in stackframe */	    \
+	std	r2,GPR2(r1);		/* save r2 in stackframe */	    \
+	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe */    \
+	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe */	    \
+	std	r9,GPR9(r1);		/* save r9 in stackframe */	    \
+	ld	r3,PACA_EXGEN+EX_R10(r13);/* get back r10 */		    \
+	ld	r4,PACA_EXGEN+EX_R11(r13);/* get back r11 */		    \
+	mfspr	r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 XXX can be wrong */ \
+	std	r3,GPR10(r1);		/* save r10 to stackframe */	    \
+	std	r4,GPR11(r1);		/* save r11 to stackframe */	    \
+	std	r12,GPR12(r1);		/* save r12 in stackframe */	    \
+	std	r5,GPR13(r1);		/* save it to stackframe */	    \
+	mflr	r10
+	mfctr	r11
+	mfxer	r12
+	std	r10,_LINK(r1)
+	std	r11,_CTR(r1)
+	std	r12,_XER(r1)
+	SAVE_10GPRS(14,r1)
+	SAVE_8GPRS(24,r1)
+	lhz	r12,PACA_TRAP_SAVE(r13)
+	std	r12,_TRAP(r1)
+	addi	r11,r1,INT_FRAME_SIZE
+	std	r11,0(r1)
+	li	r12,0
+	std	r12,0(r11)
+	ld	r2,PACATOC(r13)
+1:	addi	r3,r1,STACK_FRAME_OVERHEAD
+	bl	.kernel_bad_stack
+	b	1b
+
+/*
+ * Setup the initial TLB for a core. This current implementation
+ * assume that whatever we are running off will not conflict with
+ * the new mapping at PAGE_OFFSET.
+ */
+_GLOBAL(initial_tlb_book3e)
+
+	/* Look for the first TLB with IPROT set */
+	mfspr	r4,SPRN_TLB0CFG
+	andi.	r3,r4,TLBnCFG_IPROT
+	lis	r3,MAS0_TLBSEL(0)@h
+	bne	found_iprot
+
+	mfspr	r4,SPRN_TLB1CFG
+	andi.	r3,r4,TLBnCFG_IPROT
+	lis	r3,MAS0_TLBSEL(1)@h
+	bne	found_iprot
+
+	mfspr	r4,SPRN_TLB2CFG
+	andi.	r3,r4,TLBnCFG_IPROT
+	lis	r3,MAS0_TLBSEL(2)@h
+	bne	found_iprot
+
+	lis	r3,MAS0_TLBSEL(3)@h
+	mfspr	r4,SPRN_TLB3CFG
+	/* fall through */
+
+found_iprot:
+	andi.	r5,r4,TLBnCFG_HES
+	bne	have_hes
+
+	mflr	r8				/* save LR */
+/* 1. Find the index of the entry we're executing in
+ *
+ * r3 = MAS0_TLBSEL (for the iprot array)
+ * r4 = SPRN_TLBnCFG
+ */
+	bl	invstr				/* Find our address */
+invstr:	mflr	r6				/* Make it accessible */
+	mfmsr	r7
+	rlwinm	r5,r7,27,31,31			/* extract MSR[IS] */
+	mfspr	r7,SPRN_PID
+	slwi	r7,r7,16
+	or	r7,r7,r5
+	mtspr	SPRN_MAS6,r7
+	tlbsx	0,r6				/* search MSR[IS], SPID=PID */
+
+	mfspr	r3,SPRN_MAS0
+	rlwinm	r5,r3,16,20,31			/* Extract MAS0(Entry) */
+
+	mfspr	r7,SPRN_MAS1			/* Insure IPROT set */
+	oris	r7,r7,MAS1_IPROT@h
+	mtspr	SPRN_MAS1,r7
+	tlbwe
+
+/* 2. Invalidate all entries except the entry we're executing in
+ *
+ * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in
+ * r4 = SPRN_TLBnCFG
+ * r5 = ESEL of entry we are running in
+ */
+	andi.	r4,r4,TLBnCFG_N_ENTRY		/* Extract # entries */
+	li	r6,0				/* Set Entry counter to 0 */
+1:	mr	r7,r3				/* Set MAS0(TLBSEL) */
+	rlwimi	r7,r6,16,4,15			/* Setup MAS0 = TLBSEL | ESEL(r6) */
+	mtspr	SPRN_MAS0,r7
+	tlbre
+	mfspr	r7,SPRN_MAS1
+	rlwinm	r7,r7,0,2,31			/* Clear MAS1 Valid and IPROT */
+	cmpw	r5,r6
+	beq	skpinv				/* Dont update the current execution TLB */
+	mtspr	SPRN_MAS1,r7
+	tlbwe
+	isync
+skpinv:	addi	r6,r6,1				/* Increment */
+	cmpw	r6,r4				/* Are we done? */
+	bne	1b				/* If not, repeat */
+
+	/* Invalidate all TLBs */
+	PPC_TLBILX_ALL(0,0)
+	sync
+	isync
+
+/* 3. Setup a temp mapping and jump to it
+ *
+ * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in
+ * r5 = ESEL of entry we are running in
+ */
+	andi.	r7,r5,0x1	/* Find an entry not used and is non-zero */
+	addi	r7,r7,0x1
+	mr	r4,r3		/* Set MAS0(TLBSEL) = 1 */
+	mtspr	SPRN_MAS0,r4
+	tlbre
+
+	rlwimi	r4,r7,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r7) */
+	mtspr	SPRN_MAS0,r4
+
+	mfspr	r7,SPRN_MAS1
+	xori	r6,r7,MAS1_TS		/* Setup TMP mapping in the other Address space */
+	mtspr	SPRN_MAS1,r6
+
+	tlbwe
+
+	mfmsr	r6
+	xori	r6,r6,MSR_IS
+	mtspr	SPRN_SRR1,r6
+	bl	1f		/* Find our address */
+1:	mflr	r6
+	addi	r6,r6,(2f - 1b)
+	mtspr	SPRN_SRR0,r6
+	rfi
+2:
+
+/* 4. Clear out PIDs & Search info
+ *
+ * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
+ * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
+ * r5 = MAS3
+ */
+	li	r6,0
+	mtspr   SPRN_MAS6,r6
+	mtspr	SPRN_PID,r6
+
+/* 5. Invalidate mapping we started in
+ *
+ * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
+ * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
+ * r5 = MAS3
+ */
+	mtspr	SPRN_MAS0,r3
+	tlbre
+	mfspr	r6,SPRN_MAS1
+	rlwinm	r6,r6,0,2,0	/* clear IPROT */
+	mtspr	SPRN_MAS1,r6
+	tlbwe
+
+	/* Invalidate TLB1 */
+	PPC_TLBILX_ALL(0,0)
+	sync
+	isync
+
+/* The mapping only needs to be cache-coherent on SMP */
+#ifdef CONFIG_SMP
+#define M_IF_SMP	MAS2_M
+#else
+#define M_IF_SMP	0
+#endif
+
+/* 6. Setup KERNELBASE mapping in TLB[0]
+ *
+ * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
+ * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
+ * r5 = MAS3
+ */
+	rlwinm	r3,r3,0,16,3	/* clear ESEL */
+	mtspr	SPRN_MAS0,r3
+	lis	r6,(MAS1_VALID|MAS1_IPROT)@h
+	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l
+	mtspr	SPRN_MAS1,r6
+
+	LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | M_IF_SMP)
+	mtspr	SPRN_MAS2,r6
+
+	rlwinm	r5,r5,0,0,25
+	ori	r5,r5,MAS3_SR | MAS3_SW | MAS3_SX
+	mtspr	SPRN_MAS3,r5
+	li	r5,-1
+	rlwinm	r5,r5,0,0,25
+
+	tlbwe
+
+/* 7. Jump to KERNELBASE mapping
+ *
+ * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
+ */
+	/* Now we branch the new virtual address mapped by this entry */
+	LOAD_REG_IMMEDIATE(r6,2f)
+	lis	r7,MSR_KERNEL@h
+	ori	r7,r7,MSR_KERNEL@l
+	mtspr	SPRN_SRR0,r6
+	mtspr	SPRN_SRR1,r7
+	rfi				/* start execution out of TLB1[0] entry */
+2:
+
+/* 8. Clear out the temp mapping
+ *
+ * r4 = MAS0 w/TLBSEL & ESEL for the entry we are running in
+ */
+	mtspr	SPRN_MAS0,r4
+	tlbre
+	mfspr	r5,SPRN_MAS1
+	rlwinm	r5,r5,0,2,0	/* clear IPROT */
+	mtspr	SPRN_MAS1,r5
+	tlbwe
+
+	/* Invalidate TLB1 */
+	PPC_TLBILX_ALL(0,0)
+	sync
+	isync
+
+	/* We translate LR and return */
+	tovirt(r8,r8)
+	mtlr	r8
+	blr
+
+have_hes:
+	/* Setup MAS 0,1,2,3 and 7 for tlbwe of a 1G entry that maps the
+	 * kernel linear mapping. We also set MAS8 once for all here though
+	 * that will have to be made dependent on whether we are running under
+	 * a hypervisor I suppose.
+	 */
+	ori	r3,r3,MAS0_HES | MAS0_WQ_ALLWAYS
+	mtspr	SPRN_MAS0,r3
+	lis	r3,(MAS1_VALID | MAS1_IPROT)@h
+	ori	r3,r3,BOOK3E_PAGESZ_1GB << MAS1_TSIZE_SHIFT
+	mtspr	SPRN_MAS1,r3
+	LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET | MAS2_M)
+	mtspr	SPRN_MAS2,r3
+	li	r3,MAS3_SR | MAS3_SW | MAS3_SX
+	mtspr	SPRN_MAS7_MAS3,r3
+	li	r3,0
+	mtspr	SPRN_MAS8,r3
+
+	/* Write the TLB entry */
+	tlbwe
+
+	/* Now we branch the new virtual address mapped by this entry */
+	LOAD_REG_IMMEDIATE(r3,1f)
+	mtctr	r3
+	bctr
+
+1:	/* We are now running at PAGE_OFFSET, clean the TLB of everything
+	 * else (XXX we should scan for bolted crap from the firmware too)
+	 */
+	PPC_TLBILX(0,0,0)
+	sync
+	isync
+
+	/* We translate LR and return */
+	mflr	r3
+	tovirt(r3,r3)
+	mtlr	r3
+	blr
+
+/*
+ * Main entry (boot CPU, thread 0)
+ *
+ * We enter here from head_64.S, possibly after the prom_init trampoline
+ * with r3 and r4 already saved to r31 and 30 respectively and in 64 bits
+ * mode. Anything else is as it was left by the bootloader
+ *
+ * Initial requirements of this port:
+ *
+ * - Kernel loaded at 0 physical
+ * - A good lump of memory mapped 0:0 by UTLB entry 0
+ * - MSR:IS & MSR:DS set to 0
+ *
+ * Note that some of the above requirements will be relaxed in the future
+ * as the kernel becomes smarter at dealing with different initial conditions
+ * but for now you have to be careful
+ */
+_GLOBAL(start_initialization_book3e)
+	mflr	r28
+
+	/* First, we need to setup some initial TLBs to map the kernel
+	 * text, data and bss at PAGE_OFFSET. We don't have a real mode
+	 * and always use AS 0, so we just set it up to match our link
+	 * address and never use 0 based addresses.
+	 */
+	bl	.initial_tlb_book3e
+
+	/* Init global core bits */
+	bl	.init_core_book3e
+
+	/* Init per-thread bits */
+	bl	.init_thread_book3e
+
+	/* Return to common init code */
+	tovirt(r28,r28)
+	mtlr	r28
+	blr
+
+
+/*
+ * Secondary core/processor entry
+ *
+ * This is entered for thread 0 of a secondary core, all other threads
+ * are expected to be stopped. It's similar to start_initialization_book3e
+ * except that it's generally entered from the holding loop in head_64.S
+ * after CPUs have been gathered by Open Firmware.
+ *
+ * We assume we are in 32 bits mode running with whatever TLB entry was
+ * set for us by the firmware or POR engine.
+ */
+_GLOBAL(book3e_secondary_core_init_tlb_set)
+	li	r4,1
+	b	.generic_secondary_smp_init
+
+_GLOBAL(book3e_secondary_core_init)
+	mflr	r28
+
+	/* Do we need to setup initial TLB entry ? */
+	cmplwi	r4,0
+	bne	2f
+
+	/* Setup TLB for this core */
+	bl	.initial_tlb_book3e
+
+	/* We can return from the above running at a different
+	 * address, so recalculate r2 (TOC)
+	 */
+	bl	.relative_toc
+
+	/* Init global core bits */
+2:	bl	.init_core_book3e
+
+	/* Init per-thread bits */
+3:	bl	.init_thread_book3e
+
+	/* Return to common init code at proper virtual address.
+	 *
+	 * Due to various previous assumptions, we know we entered this
+	 * function at either the final PAGE_OFFSET mapping or using a
+	 * 1:1 mapping at 0, so we don't bother doing a complicated check
+	 * here, we just ensure the return address has the right top bits.
+	 *
+	 * Note that if we ever want to be smarter about where we can be
+	 * started from, we have to be careful that by the time we reach
+	 * the code below we may already be running at a different location
+	 * than the one we were called from since initial_tlb_book3e can
+	 * have moved us already.
+	 */
+	cmpdi	cr0,r28,0
+	blt	1f
+	lis	r3,PAGE_OFFSET@highest
+	sldi	r3,r3,32
+	or	r28,r28,r3
+1:	mtlr	r28
+	blr
+
+_GLOBAL(book3e_secondary_thread_init)
+	mflr	r28
+	b	3b
+
+_STATIC(init_core_book3e)
+	/* Establish the interrupt vector base */
+	LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e)
+	mtspr	SPRN_IVPR,r3
+	sync
+	blr
+
+_STATIC(init_thread_book3e)
+	lis	r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h
+	mtspr	SPRN_EPCR,r3
+
+	/* Make sure interrupts are off */
+	wrteei	0
+
+	/* disable all timers and clear out status */
+	li	r3,0
+	mtspr	SPRN_TCR,r3
+	mfspr	r3,SPRN_TSR
+	mtspr	SPRN_TSR,r3
+
+	blr
+
+_GLOBAL(__setup_base_ivors)
+	SET_IVOR(0, 0x020) /* Critical Input */
+	SET_IVOR(1, 0x000) /* Machine Check */
+	SET_IVOR(2, 0x060) /* Data Storage */ 
+	SET_IVOR(3, 0x080) /* Instruction Storage */
+	SET_IVOR(4, 0x0a0) /* External Input */ 
+	SET_IVOR(5, 0x0c0) /* Alignment */ 
+	SET_IVOR(6, 0x0e0) /* Program */ 
+	SET_IVOR(7, 0x100) /* FP Unavailable */ 
+	SET_IVOR(8, 0x120) /* System Call */ 
+	SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */ 
+	SET_IVOR(10, 0x160) /* Decrementer */ 
+	SET_IVOR(11, 0x180) /* Fixed Interval Timer */ 
+	SET_IVOR(12, 0x1a0) /* Watchdog Timer */ 
+	SET_IVOR(13, 0x1c0) /* Data TLB Error */ 
+	SET_IVOR(14, 0x1e0) /* Instruction TLB Error */
+	SET_IVOR(15, 0x040) /* Debug */
+
+	sync
+
+	blr
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 8ac85e0..1808876 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -12,6 +12,8 @@
  *
  */
 
+#include <asm/exception-64s.h>
+
 /*
  * We layout physical memory as follows:
  * 0x0000 - 0x00ff : Secondary processor spin code
@@ -22,18 +24,6 @@
  * 0x8000 -        : Early init and support code
  */
 
-
-/*
- *   SPRG Usage
- *
- *   Register	Definition
- *
- *   SPRG0	reserved for hypervisor
- *   SPRG1	temp - used to save gpr
- *   SPRG2	temp - used to save gpr
- *   SPRG3	virt addr of paca
- */
-
 /*
  * This is the start of the interrupt handlers for pSeries
  * This code runs with relocation off.
@@ -51,34 +41,44 @@ __start_interrupts:
 	. = 0x200
 _machine_check_pSeries:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
+	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
 
 	. = 0x300
 	.globl data_access_pSeries
 data_access_pSeries:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13
+	mtspr	SPRN_SPRG_SCRATCH0,r13
 BEGIN_FTR_SECTION
-	mtspr	SPRN_SPRG2,r12
-	mfspr	r13,SPRN_DAR
-	mfspr	r12,SPRN_DSISR
-	srdi	r13,r13,60
-	rlwimi	r13,r12,16,0x20
-	mfcr	r12
-	cmpwi	r13,0x2c
+	mfspr	r13,SPRN_SPRG_PACA
+	std	r9,PACA_EXSLB+EX_R9(r13)
+	std	r10,PACA_EXSLB+EX_R10(r13)
+	mfspr	r10,SPRN_DAR
+	mfspr	r9,SPRN_DSISR
+	srdi	r10,r10,60
+	rlwimi	r10,r9,16,0x20
+	mfcr	r9
+	cmpwi	r10,0x2c
 	beq	do_stab_bolted_pSeries
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+	ld	r10,PACA_EXSLB+EX_R10(r13)
+	std	r11,PACA_EXGEN+EX_R11(r13)
+	ld	r11,PACA_EXSLB+EX_R9(r13)
+	std	r12,PACA_EXGEN+EX_R12(r13)
+	mfspr	r12,SPRN_SPRG_SCRATCH0
+	std	r10,PACA_EXGEN+EX_R10(r13)
+	std	r11,PACA_EXGEN+EX_R9(r13)
+	std	r12,PACA_EXGEN+EX_R13(r13)
+	EXCEPTION_PROLOG_PSERIES_1(data_access_common)
+FTR_SECTION_ELSE
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 
 	. = 0x380
 	.globl data_access_slb_pSeries
 data_access_slb_pSeries:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
+	mtspr	SPRN_SPRG_SCRATCH0,r13
+	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_DAR
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
@@ -91,7 +91,7 @@ data_access_slb_pSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
+	mfspr	r10,SPRN_SPRG_SCRATCH0
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
@@ -115,8 +115,8 @@ data_access_slb_pSeries:
 	.globl instruction_access_slb_pSeries
 instruction_access_slb_pSeries:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
+	mtspr	SPRN_SPRG_SCRATCH0,r13
+	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
@@ -129,7 +129,7 @@ instruction_access_slb_pSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
+	mfspr	r10,SPRN_SPRG_SCRATCH0
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
@@ -159,7 +159,7 @@ BEGIN_FTR_SECTION
 	beq-	1f
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
 	mr	r9,r13
-	mfspr	r13,SPRN_SPRG3
+	mfspr	r13,SPRN_SPRG_PACA
 	mfspr	r11,SPRN_SRR0
 	ld	r12,PACAKBASE(r13)
 	ld	r10,PACAKMSR(r13)
@@ -228,15 +228,17 @@ masked_interrupt:
 	rotldi	r10,r10,16
 	mtspr	SPRN_SRR1,r10
 	ld	r10,PACA_EXGEN+EX_R10(r13)
-	mfspr	r13,SPRN_SPRG1
+	mfspr	r13,SPRN_SPRG_SCRATCH0
 	rfid
 	b	.
 
 	.align	7
 do_stab_bolted_pSeries:
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-	EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+	std	r11,PACA_EXSLB+EX_R11(r13)
+	std	r12,PACA_EXSLB+EX_R12(r13)
+	mfspr	r10,SPRN_SPRG_SCRATCH0
+	std	r10,PACA_EXSLB+EX_R13(r13)
+	EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted)
 
 #ifdef CONFIG_PPC_PSERIES
 /*
@@ -246,14 +248,14 @@ do_stab_bolted_pSeries:
       .align 7
 system_reset_fwnmi:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
+	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
 
 	.globl machine_check_fwnmi
       .align 7
 machine_check_fwnmi:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
+	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
 	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
 
 #endif /* CONFIG_PPC_PSERIES */
@@ -268,7 +270,7 @@ slb_miss_user_pseries:
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r10,SPRG1
+	mfspr	r10,SPRG_SCRATCH0
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	ld	r12,PACA_EXSLB+EX_R3(r13)
 	std	r10,PACA_EXGEN+EX_R13(r13)
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 2436df3..fc8f5b1 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -91,7 +91,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 #endif /* CONFIG_SMP */
 	/* enable use of FP after return */
 #ifdef CONFIG_PPC32
-	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
+	mfspr	r5,SPRN_SPRG_THREAD		/* current task's THREAD (phys) */
 	lwz	r4,THREAD_FPEXC_MODE(r5)
 	ori	r9,r9,MSR_FP		/* enable FP for current */
 	or	r9,r9,r4
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index fc21329..829c3fe 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -244,8 +244,8 @@ __secondary_hold_acknowledge:
  * task's thread_struct.
  */
 #define EXCEPTION_PROLOG	\
-	mtspr	SPRN_SPRG0,r10;	\
-	mtspr	SPRN_SPRG1,r11;	\
+	mtspr	SPRN_SPRG_SCRATCH0,r10;	\
+	mtspr	SPRN_SPRG_SCRATCH1,r11;	\
 	mfcr	r10;		\
 	EXCEPTION_PROLOG_1;	\
 	EXCEPTION_PROLOG_2
@@ -255,7 +255,7 @@ __secondary_hold_acknowledge:
 	andi.	r11,r11,MSR_PR;	\
 	tophys(r11,r1);			/* use tophys(r1) if kernel */ \
 	beq	1f;		\
-	mfspr	r11,SPRN_SPRG3;	\
+	mfspr	r11,SPRN_SPRG_THREAD;	\
 	lwz	r11,THREAD_INFO-THREAD(r11);	\
 	addi	r11,r11,THREAD_SIZE;	\
 	tophys(r11,r11);	\
@@ -267,9 +267,9 @@ __secondary_hold_acknowledge:
 	stw	r10,_CCR(r11);		/* save registers */ \
 	stw	r12,GPR12(r11);	\
 	stw	r9,GPR9(r11);	\
-	mfspr	r10,SPRN_SPRG0;	\
+	mfspr	r10,SPRN_SPRG_SCRATCH0;	\
 	stw	r10,GPR10(r11);	\
-	mfspr	r12,SPRN_SPRG1;	\
+	mfspr	r12,SPRN_SPRG_SCRATCH1;	\
 	stw	r12,GPR11(r11);	\
 	mflr	r10;		\
 	stw	r10,_LINK(r11);	\
@@ -355,11 +355,11 @@ i##n:								\
  *	-- paulus.
  */
 	. = 0x200
-	mtspr	SPRN_SPRG0,r10
-	mtspr	SPRN_SPRG1,r11
+	mtspr	SPRN_SPRG_SCRATCH0,r10
+	mtspr	SPRN_SPRG_SCRATCH1,r11
 	mfcr	r10
 #ifdef CONFIG_PPC_CHRP
-	mfspr	r11,SPRN_SPRG2
+	mfspr	r11,SPRN_SPRG_RTAS
 	cmpwi	0,r11,0
 	bne	7f
 #endif /* CONFIG_PPC_CHRP */
@@ -367,7 +367,7 @@ i##n:								\
 7:	EXCEPTION_PROLOG_2
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 #ifdef CONFIG_PPC_CHRP
-	mfspr	r4,SPRN_SPRG2
+	mfspr	r4,SPRN_SPRG_RTAS
 	cmpwi	cr1,r4,0
 	bne	cr1,1f
 #endif
@@ -485,7 +485,7 @@ InstructionTLBMiss:
 	mfspr	r3,SPRN_IMISS
 	lis	r1,PAGE_OFFSET@h		/* check if kernel address */
 	cmplw	0,r1,r3
-	mfspr	r2,SPRN_SPRG3
+	mfspr	r2,SPRN_SPRG_THREAD
 	li	r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
 	lwz	r2,PGDIR(r2)
 	bge-	112f
@@ -559,7 +559,7 @@ DataLoadTLBMiss:
 	mfspr	r3,SPRN_DMISS
 	lis	r1,PAGE_OFFSET@h		/* check if kernel address */
 	cmplw	0,r1,r3
-	mfspr	r2,SPRN_SPRG3
+	mfspr	r2,SPRN_SPRG_THREAD
 	li	r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
 	lwz	r2,PGDIR(r2)
 	bge-	112f
@@ -598,12 +598,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 	mtcrf	0x80,r2
 BEGIN_MMU_FTR_SECTION
 	li	r0,1
-	mfspr	r1,SPRN_SPRG4
+	mfspr	r1,SPRN_SPRG_603_LRU
 	rlwinm	r2,r3,20,27,31		/* Get Address bits 15:19 */
 	slw	r0,r0,r2
 	xor	r1,r0,r1
 	srw	r0,r1,r2
-	mtspr   SPRN_SPRG4,r1
+	mtspr   SPRN_SPRG_603_LRU,r1
 	mfspr	r2,SPRN_SRR1
 	rlwimi	r2,r0,31-14,14,14
 	mtspr   SPRN_SRR1,r2
@@ -643,7 +643,7 @@ DataStoreTLBMiss:
 	mfspr	r3,SPRN_DMISS
 	lis	r1,PAGE_OFFSET@h		/* check if kernel address */
 	cmplw	0,r1,r3
-	mfspr	r2,SPRN_SPRG3
+	mfspr	r2,SPRN_SPRG_THREAD
 	li	r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
 	lwz	r2,PGDIR(r2)
 	bge-	112f
@@ -678,12 +678,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
 	mtcrf	0x80,r2
 BEGIN_MMU_FTR_SECTION
 	li	r0,1
-	mfspr	r1,SPRN_SPRG4
+	mfspr	r1,SPRN_SPRG_603_LRU
 	rlwinm	r2,r3,20,27,31		/* Get Address bits 15:19 */
 	slw	r0,r0,r2
 	xor	r1,r0,r1
 	srw	r0,r1,r2
-	mtspr   SPRN_SPRG4,r1
+	mtspr   SPRN_SPRG_603_LRU,r1
 	mfspr	r2,SPRN_SRR1
 	rlwimi	r2,r0,31-14,14,14
 	mtspr   SPRN_SRR1,r2
@@ -864,9 +864,9 @@ __secondary_start:
 	tophys(r4,r2)
 	addi	r4,r4,THREAD	/* phys address of our thread_struct */
 	CLR_TOP32(r4)
-	mtspr	SPRN_SPRG3,r4
+	mtspr	SPRN_SPRG_THREAD,r4
 	li	r3,0
-	mtspr	SPRN_SPRG2,r3	/* 0 => not in RTAS */
+	mtspr	SPRN_SPRG_RTAS,r3	/* 0 => not in RTAS */
 
 	/* enable MMU and jump to start_secondary */
 	li	r4,MSR_KERNEL
@@ -947,9 +947,9 @@ start_here:
 	tophys(r4,r2)
 	addi	r4,r4,THREAD	/* init task's THREAD */
 	CLR_TOP32(r4)
-	mtspr	SPRN_SPRG3,r4
+	mtspr	SPRN_SPRG_THREAD,r4
 	li	r3,0
-	mtspr	SPRN_SPRG2,r3	/* 0 => not in RTAS */
+	mtspr	SPRN_SPRG_RTAS,r3	/* 0 => not in RTAS */
 
 	/* stack */
 	lis	r1,init_thread_union@ha
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 0c96911..a90625f 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -103,21 +103,21 @@ _ENTRY(saved_ksp_limit)
 
 /*
  * Exception vector entry code. This code runs with address translation
- * turned off (i.e. using physical addresses). We assume SPRG3 has the
- * physical address of the current task thread_struct.
+ * turned off (i.e. using physical addresses). We assume SPRG_THREAD has
+ * the physical address of the current task thread_struct.
  * Note that we have to have decremented r1 before we write to any fields
  * of the exception frame, since a critical interrupt could occur at any
  * time, and it will write to the area immediately below the current r1.
  */
 #define NORMAL_EXCEPTION_PROLOG						     \
-	mtspr	SPRN_SPRG0,r10;		/* save two registers to work with */\
-	mtspr	SPRN_SPRG1,r11;						     \
-	mtspr	SPRN_SPRG2,r1;						     \
+	mtspr	SPRN_SPRG_SCRATCH0,r10;	/* save two registers to work with */\
+	mtspr	SPRN_SPRG_SCRATCH1,r11;					     \
+	mtspr	SPRN_SPRG_SCRATCH2,r1;					     \
 	mfcr	r10;			/* save CR in r10 for now	   */\
 	mfspr	r11,SPRN_SRR1;		/* check whether user or kernel    */\
 	andi.	r11,r11,MSR_PR;						     \
 	beq	1f;							     \
-	mfspr	r1,SPRN_SPRG3;		/* if from user, start at top of   */\
+	mfspr	r1,SPRN_SPRG_THREAD;	/* if from user, start at top of   */\
 	lwz	r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack   */\
 	addi	r1,r1,THREAD_SIZE;					     \
 1:	subi	r1,r1,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
@@ -125,13 +125,13 @@ _ENTRY(saved_ksp_limit)
 	stw	r10,_CCR(r11);          /* save various registers	   */\
 	stw	r12,GPR12(r11);						     \
 	stw	r9,GPR9(r11);						     \
-	mfspr	r10,SPRN_SPRG0;						     \
+	mfspr	r10,SPRN_SPRG_SCRATCH0;					     \
 	stw	r10,GPR10(r11);						     \
-	mfspr	r12,SPRN_SPRG1;						     \
+	mfspr	r12,SPRN_SPRG_SCRATCH1;					     \
 	stw	r12,GPR11(r11);						     \
 	mflr	r10;							     \
 	stw	r10,_LINK(r11);						     \
-	mfspr	r10,SPRN_SPRG2;						     \
+	mfspr	r10,SPRN_SPRG_SCRATCH2;					     \
 	mfspr	r12,SPRN_SRR0;						     \
 	stw	r10,GPR1(r11);						     \
 	mfspr	r9,SPRN_SRR1;						     \
@@ -160,7 +160,7 @@ _ENTRY(saved_ksp_limit)
 	lwz	r11,critirq_ctx@l(r11);					     \
 	beq	1f;							     \
 	/* COMING FROM USER MODE */					     \
-	mfspr	r11,SPRN_SPRG3;		/* if from user, start at top of   */\
+	mfspr	r11,SPRN_SPRG_THREAD;	/* if from user, start at top of   */\
 	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
 1:	addi	r11,r11,THREAD_SIZE-INT_FRAME_SIZE; /* Alloc an excpt frm  */\
 	tophys(r11,r11);						     \
@@ -265,8 +265,8 @@ label:
  * and exit.  Otherwise, we call heavywight functions to do the work.
  */
 	START_EXCEPTION(0x0300,	DataStorage)
-	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
-	mtspr	SPRN_SPRG1, r11
+	mtspr	SPRN_SPRG_SCRATCH0, r10 /* Save some working registers */
+	mtspr	SPRN_SPRG_SCRATCH1, r11
 #ifdef CONFIG_403GCX
 	stw     r12, 0(r0)
 	stw     r9, 4(r0)
@@ -275,12 +275,12 @@ label:
 	stw     r11, 8(r0)
 	stw     r12, 12(r0)
 #else
-	mtspr	SPRN_SPRG4, r12
-	mtspr	SPRN_SPRG5, r9
+	mtspr	SPRN_SPRG_SCRATCH3, r12
+	mtspr	SPRN_SPRG_SCRATCH4, r9
 	mfcr	r11
 	mfspr	r12, SPRN_PID
-	mtspr	SPRN_SPRG7, r11
-	mtspr	SPRN_SPRG6, r12
+	mtspr	SPRN_SPRG_SCRATCH6, r11
+	mtspr	SPRN_SPRG_SCRATCH5, r12
 #endif
 
 	/* First, check if it was a zone fault (which means a user
@@ -308,7 +308,7 @@ label:
 	/* Get the PGD for the current thread.
 	 */
 3:
-	mfspr	r11,SPRN_SPRG3
+	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 4:
 	tophys(r11, r11)
@@ -355,15 +355,15 @@ label:
 	lwz     r9, 4(r0)
 	lwz     r12, 0(r0)
 #else
-	mfspr	r12, SPRN_SPRG6
-	mfspr	r11, SPRN_SPRG7
+	mfspr	r12, SPRN_SPRG_SCRATCH5
+	mfspr	r11, SPRN_SPRG_SCRATCH6
 	mtspr	SPRN_PID, r12
 	mtcr	r11
-	mfspr	r9, SPRN_SPRG5
-	mfspr	r12, SPRN_SPRG4
+	mfspr	r9, SPRN_SPRG_SCRATCH4
+	mfspr	r12, SPRN_SPRG_SCRATCH3
 #endif
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r11, SPRN_SPRG_SCRATCH1
+	mfspr	r10, SPRN_SPRG_SCRATCH0
 	PPC405_ERR77_SYNC
 	rfi			/* Should sync shadow TLBs */
 	b	.		/* prevent prefetch past rfi */
@@ -380,15 +380,15 @@ label:
 	lwz     r9, 4(r0)
 	lwz     r12, 0(r0)
 #else
-	mfspr	r12, SPRN_SPRG6
-	mfspr	r11, SPRN_SPRG7
+	mfspr	r12, SPRN_SPRG_SCRATCH5
+	mfspr	r11, SPRN_SPRG_SCRATCH6
 	mtspr	SPRN_PID, r12
 	mtcr	r11
-	mfspr	r9, SPRN_SPRG5
-	mfspr	r12, SPRN_SPRG4
+	mfspr	r9, SPRN_SPRG_SCRATCH4
+	mfspr	r12, SPRN_SPRG_SCRATCH3
 #endif
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r11, SPRN_SPRG_SCRATCH1
+	mfspr	r10, SPRN_SPRG_SCRATCH0
 	b	DataAccess
 
 /*
@@ -466,8 +466,8 @@ label:
  * load TLB entries from the page table if they exist.
  */
 	START_EXCEPTION(0x1100,	DTLBMiss)
-	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
-	mtspr	SPRN_SPRG1, r11
+	mtspr	SPRN_SPRG_SCRATCH0, r10 /* Save some working registers */
+	mtspr	SPRN_SPRG_SCRATCH1, r11
 #ifdef CONFIG_403GCX
 	stw     r12, 0(r0)
 	stw     r9, 4(r0)
@@ -476,12 +476,12 @@ label:
 	stw     r11, 8(r0)
 	stw     r12, 12(r0)
 #else
-	mtspr	SPRN_SPRG4, r12
-	mtspr	SPRN_SPRG5, r9
+	mtspr	SPRN_SPRG_SCRATCH3, r12
+	mtspr	SPRN_SPRG_SCRATCH4, r9
 	mfcr	r11
 	mfspr	r12, SPRN_PID
-	mtspr	SPRN_SPRG7, r11
-	mtspr	SPRN_SPRG6, r12
+	mtspr	SPRN_SPRG_SCRATCH6, r11
+	mtspr	SPRN_SPRG_SCRATCH5, r12
 #endif
 	mfspr	r10, SPRN_DEAR		/* Get faulting address */
 
@@ -500,7 +500,7 @@ label:
 	/* Get the PGD for the current thread.
 	 */
 3:
-	mfspr	r11,SPRN_SPRG3
+	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 4:
 	tophys(r11, r11)
@@ -550,15 +550,15 @@ label:
 	lwz     r9, 4(r0)
 	lwz     r12, 0(r0)
 #else
-	mfspr	r12, SPRN_SPRG6
-	mfspr	r11, SPRN_SPRG7
+	mfspr	r12, SPRN_SPRG_SCRATCH5
+	mfspr	r11, SPRN_SPRG_SCRATCH6
 	mtspr	SPRN_PID, r12
 	mtcr	r11
-	mfspr	r9, SPRN_SPRG5
-	mfspr	r12, SPRN_SPRG4
+	mfspr	r9, SPRN_SPRG_SCRATCH4
+	mfspr	r12, SPRN_SPRG_SCRATCH3
 #endif
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r11, SPRN_SPRG_SCRATCH1
+	mfspr	r10, SPRN_SPRG_SCRATCH0
 	b	DataAccess
 
 /* 0x1200 - Instruction TLB Miss Exception
@@ -566,8 +566,8 @@ label:
  * registers and bailout to a different point.
  */
 	START_EXCEPTION(0x1200,	ITLBMiss)
-	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
-	mtspr	SPRN_SPRG1, r11
+	mtspr	SPRN_SPRG_SCRATCH0, r10	 /* Save some working registers */
+	mtspr	SPRN_SPRG_SCRATCH1, r11
 #ifdef CONFIG_403GCX
 	stw     r12, 0(r0)
 	stw     r9, 4(r0)
@@ -576,12 +576,12 @@ label:
 	stw     r11, 8(r0)
 	stw     r12, 12(r0)
 #else
-	mtspr	SPRN_SPRG4, r12
-	mtspr	SPRN_SPRG5, r9
+	mtspr	SPRN_SPRG_SCRATCH3, r12
+	mtspr	SPRN_SPRG_SCRATCH4, r9
 	mfcr	r11
 	mfspr	r12, SPRN_PID
-	mtspr	SPRN_SPRG7, r11
-	mtspr	SPRN_SPRG6, r12
+	mtspr	SPRN_SPRG_SCRATCH6, r11
+	mtspr	SPRN_SPRG_SCRATCH5, r12
 #endif
 	mfspr	r10, SPRN_SRR0		/* Get faulting address */
 
@@ -600,7 +600,7 @@ label:
 	/* Get the PGD for the current thread.
 	 */
 3:
-	mfspr	r11,SPRN_SPRG3
+	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 4:
 	tophys(r11, r11)
@@ -650,15 +650,15 @@ label:
 	lwz     r9, 4(r0)
 	lwz     r12, 0(r0)
 #else
-	mfspr	r12, SPRN_SPRG6
-	mfspr	r11, SPRN_SPRG7
+	mfspr	r12, SPRN_SPRG_SCRATCH5
+	mfspr	r11, SPRN_SPRG_SCRATCH6
 	mtspr	SPRN_PID, r12
 	mtcr	r11
-	mfspr	r9, SPRN_SPRG5
-	mfspr	r12, SPRN_SPRG4
+	mfspr	r9, SPRN_SPRG_SCRATCH4
+	mfspr	r12, SPRN_SPRG_SCRATCH3
 #endif
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r11, SPRN_SPRG_SCRATCH1
+	mfspr	r10, SPRN_SPRG_SCRATCH0
 	b	InstructionAccess
 
 	EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
@@ -803,15 +803,15 @@ finish_tlb_load:
 	lwz     r9, 4(r0)
 	lwz     r12, 0(r0)
 #else
-	mfspr	r12, SPRN_SPRG6
-	mfspr	r11, SPRN_SPRG7
+	mfspr	r12, SPRN_SPRG_SCRATCH5
+	mfspr	r11, SPRN_SPRG_SCRATCH6
 	mtspr	SPRN_PID, r12
 	mtcr	r11
-	mfspr	r9, SPRN_SPRG5
-	mfspr	r12, SPRN_SPRG4
+	mfspr	r9, SPRN_SPRG_SCRATCH4
+	mfspr	r12, SPRN_SPRG_SCRATCH3
 #endif
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r11, SPRN_SPRG_SCRATCH1
+	mfspr	r10, SPRN_SPRG_SCRATCH0
 	PPC405_ERR77_SYNC
 	rfi			/* Should sync shadow TLBs */
 	b	.		/* prevent prefetch past rfi */
@@ -835,7 +835,7 @@ start_here:
 	/* ptr to phys current thread */
 	tophys(r4,r2)
 	addi	r4,r4,THREAD	/* init task's THREAD */
-	mtspr	SPRN_SPRG3,r4
+	mtspr	SPRN_SPRG_THREAD,r4
 
 	/* stack */
 	lis	r1,init_thread_union@ha
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 18d8a16..711368b 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -239,7 +239,7 @@ skpinv:	addi	r4,r4,1				/* Increment */
 
 	/* ptr to current thread */
 	addi	r4,r2,THREAD	/* init task's THREAD */
-	mtspr	SPRN_SPRG3,r4
+	mtspr	SPRN_SPRG_THREAD,r4
 
 	/* stack */
 	lis	r1,init_thread_union@h
@@ -350,12 +350,12 @@ interrupt_base:
 
 	/* Data TLB Error Interrupt */
 	START_EXCEPTION(DataTLBError)
-	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
-	mtspr	SPRN_SPRG1, r11
-	mtspr	SPRN_SPRG4W, r12
-	mtspr	SPRN_SPRG5W, r13
+	mtspr	SPRN_SPRG_WSCRATCH0, r10		/* Save some working registers */
+	mtspr	SPRN_SPRG_WSCRATCH1, r11
+	mtspr	SPRN_SPRG_WSCRATCH2, r12
+	mtspr	SPRN_SPRG_WSCRATCH3, r13
 	mfcr	r11
-	mtspr	SPRN_SPRG7W, r11
+	mtspr	SPRN_SPRG_WSCRATCH4, r11
 	mfspr	r10, SPRN_DEAR		/* Get faulting address */
 
 	/* If we are faulting a kernel address, we have to use the
@@ -374,7 +374,7 @@ interrupt_base:
 
 	/* Get the PGD for the current thread */
 3:
-	mfspr	r11,SPRN_SPRG3
+	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 
 	/* Load PID into MMUCR TID */
@@ -446,12 +446,12 @@ tlb_44x_patch_hwater_D:
 	/* The bailout.  Restore registers to pre-exception conditions
 	 * and call the heavyweights to help us out.
 	 */
-	mfspr	r11, SPRN_SPRG7R
+	mfspr	r11, SPRN_SPRG_RSCRATCH4
 	mtcr	r11
-	mfspr	r13, SPRN_SPRG5R
-	mfspr	r12, SPRN_SPRG4R
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r13, SPRN_SPRG_RSCRATCH3
+	mfspr	r12, SPRN_SPRG_RSCRATCH2
+	mfspr	r11, SPRN_SPRG_RSCRATCH1
+	mfspr	r10, SPRN_SPRG_RSCRATCH0
 	b	DataStorage
 
 	/* Instruction TLB Error Interrupt */
@@ -461,12 +461,12 @@ tlb_44x_patch_hwater_D:
 	 * to a different point.
 	 */
 	START_EXCEPTION(InstructionTLBError)
-	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
-	mtspr	SPRN_SPRG1, r11
-	mtspr	SPRN_SPRG4W, r12
-	mtspr	SPRN_SPRG5W, r13
+	mtspr	SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
+	mtspr	SPRN_SPRG_WSCRATCH1, r11
+	mtspr	SPRN_SPRG_WSCRATCH2, r12
+	mtspr	SPRN_SPRG_WSCRATCH3, r13
 	mfcr	r11
-	mtspr	SPRN_SPRG7W, r11
+	mtspr	SPRN_SPRG_WSCRATCH4, r11
 	mfspr	r10, SPRN_SRR0		/* Get faulting address */
 
 	/* If we are faulting a kernel address, we have to use the
@@ -485,7 +485,7 @@ tlb_44x_patch_hwater_D:
 
 	/* Get the PGD for the current thread */
 3:
-	mfspr	r11,SPRN_SPRG3
+	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 
 	/* Load PID into MMUCR TID */
@@ -497,7 +497,7 @@ tlb_44x_patch_hwater_D:
 	mtspr	SPRN_MMUCR,r12
 
 	/* Make up the required permissions */
-	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
 
 	/* Compute pgdir/pmd offset */
 	rlwinm 	r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29
@@ -542,12 +542,12 @@ tlb_44x_patch_hwater_I:
 	/* The bailout.  Restore registers to pre-exception conditions
 	 * and call the heavyweights to help us out.
 	 */
-	mfspr	r11, SPRN_SPRG7R
+	mfspr	r11, SPRN_SPRG_RSCRATCH4
 	mtcr	r11
-	mfspr	r13, SPRN_SPRG5R
-	mfspr	r12, SPRN_SPRG4R
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r13, SPRN_SPRG_RSCRATCH3
+	mfspr	r12, SPRN_SPRG_RSCRATCH2
+	mfspr	r11, SPRN_SPRG_RSCRATCH1
+	mfspr	r10, SPRN_SPRG_RSCRATCH0
 	b	InstructionStorage
 
 	/* Debug Interrupt */
@@ -593,12 +593,12 @@ finish_tlb_load:
 
 	/* Done...restore registers and get out of here.
 	*/
-	mfspr	r11, SPRN_SPRG7R
+	mfspr	r11, SPRN_SPRG_RSCRATCH4
 	mtcr	r11
-	mfspr	r13, SPRN_SPRG5R
-	mfspr	r12, SPRN_SPRG4R
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r13, SPRN_SPRG_RSCRATCH3
+	mfspr	r12, SPRN_SPRG_RSCRATCH2
+	mfspr	r11, SPRN_SPRG_RSCRATCH1
+	mfspr	r10, SPRN_SPRG_RSCRATCH0
 	rfi					/* Force context change */
 
 /*
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 012505e..c38afdb 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -36,7 +36,6 @@
 #include <asm/thread_info.h>
 #include <asm/firmware.h>
 #include <asm/page_64.h>
-#include <asm/exception.h>
 #include <asm/irqflags.h>
 
 /* The physical memory is layed out such that the secondary processor
@@ -122,10 +121,11 @@ __run_at_load:
  */
 	.globl	__secondary_hold
 __secondary_hold:
+#ifndef CONFIG_PPC_BOOK3E
 	mfmsr	r24
 	ori	r24,r24,MSR_RI
 	mtmsrd	r24			/* RI on */
-
+#endif
 	/* Grab our physical cpu number */
 	mr	r24,r3
 
@@ -144,6 +144,7 @@ __secondary_hold:
 	ld	r4,0(r4)		/* deref function descriptor */
 	mtctr	r4
 	mr	r3,r24
+	li	r4,0
 	bctr
 #else
 	BUG_OPCODE
@@ -164,21 +165,49 @@ exception_marker:
 #include "exceptions-64s.S"
 #endif
 
+_GLOBAL(generic_secondary_thread_init)
+	mr	r24,r3
+
+	/* turn on 64-bit mode */
+	bl	.enable_64b_mode
+
+	/* get a valid TOC pointer, wherever we're mapped at */
+	bl	.relative_toc
+
+#ifdef CONFIG_PPC_BOOK3E
+	/* Book3E initialization */
+	mr	r3,r24
+	bl	.book3e_secondary_thread_init
+#endif
+	b	generic_secondary_common_init
 
 /*
  * On pSeries and most other platforms, secondary processors spin
  * in the following code.
  * At entry, r3 = this processor's number (physical cpu id)
+ *
+ * On Book3E, r4 = 1 to indicate that the initial TLB entry for
+ * this core already exists (setup via some other mechanism such
+ * as SCOM before entry).
  */
 _GLOBAL(generic_secondary_smp_init)
 	mr	r24,r3
-	
+	mr	r25,r4
+
 	/* turn on 64-bit mode */
 	bl	.enable_64b_mode
 
-	/* get the TOC pointer (real address) */
+	/* get a valid TOC pointer, wherever we're mapped at */
 	bl	.relative_toc
 
+#ifdef CONFIG_PPC_BOOK3E
+	/* Book3E initialization */
+	mr	r3,r24
+	mr	r4,r25
+	bl	.book3e_secondary_core_init
+#endif
+
+generic_secondary_common_init:
 	/* Set up a paca value for this processor. Since we have the
 	 * physical cpu id in r24, we need to search the pacas to find
 	 * which logical id maps to our physical one.
@@ -196,7 +225,12 @@ _GLOBAL(generic_secondary_smp_init)
 	mr	r3,r24			/* not found, copy phys to r3	 */
 	b	.kexec_wait		/* next kernel might do better	 */
 
-2:	mtspr	SPRN_SPRG3,r13		/* Save vaddr of paca in SPRG3	 */
+2:	mtspr	SPRN_SPRG_PACA,r13	/* Save vaddr of paca in an SPRG */
+#ifdef CONFIG_PPC_BOOK3E
+	addi	r12,r13,PACA_EXTLB	/* and TLB exc frame in another  */
+	mtspr	SPRN_SPRG_TLB_EXFRAME,r12
+#endif
+
 	/* From now on, r24 is expected to be logical cpuid */
 	mr	r24,r5
 3:	HMT_LOW
@@ -232,6 +266,7 @@ _GLOBAL(generic_secondary_smp_init)
  * Turn the MMU off.
  * Assumes we're mapped EA == RA if the MMU is on.
  */
+#ifdef CONFIG_PPC_BOOK3S
 _STATIC(__mmu_off)
 	mfmsr	r3
 	andi.	r0,r3,MSR_IR|MSR_DR
@@ -243,6 +278,7 @@ _STATIC(__mmu_off)
 	sync
 	rfid
 	b	.	/* prevent speculative execution */
+#endif
 
 
 /*
@@ -280,6 +316,10 @@ _GLOBAL(__start_initialization_multiplatform)
 	mr	r31,r3
 	mr	r30,r4
 
+#ifdef CONFIG_PPC_BOOK3E
+	bl	.start_initialization_book3e
+	b	.__after_prom_start
+#else
 	/* Setup some critical 970 SPRs before switching MMU off */
 	mfspr	r0,SPRN_PVR
 	srwi	r0,r0,16
@@ -297,6 +337,7 @@ _GLOBAL(__start_initialization_multiplatform)
 	/* Switch off MMU if not already off */
 	bl	.__mmu_off
 	b	.__after_prom_start
+#endif /* CONFIG_PPC_BOOK3E */
 
 _INIT_STATIC(__boot_from_prom)
 #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
@@ -359,10 +400,16 @@ _STATIC(__after_prom_start)
  * Note: This process overwrites the OF exception vectors.
  */
 	li	r3,0			/* target addr */
+#ifdef CONFIG_PPC_BOOK3E
+	tovirt(r3,r3)			/* on booke, we already run at PAGE_OFFSET */
+#endif
 	mr.	r4,r26			/* In some cases the loader may  */
 	beq	9f			/* have already put us at zero */
 	li	r6,0x100		/* Start offset, the first 0x100 */
 					/* bytes were copied earlier.	 */
+#ifdef CONFIG_PPC_BOOK3E
+	tovirt(r6,r6)			/* on booke, we already run at PAGE_OFFSET */
+#endif
 
 #ifdef CONFIG_CRASH_DUMP
 /*
@@ -485,7 +532,7 @@ _GLOBAL(pmac_secondary_start)
 	LOAD_REG_ADDR(r4,paca)		/* Get base vaddr of paca array	*/
 	mulli	r13,r24,PACA_SIZE	/* Calculate vaddr of right paca */
 	add	r13,r13,r4		/* for this processor.		*/
-	mtspr	SPRN_SPRG3,r13		/* Save vaddr of paca in SPRG3	*/
+	mtspr	SPRN_SPRG_PACA,r13	/* Save vaddr of paca in an SPRG*/
 
 	/* Create a temp kernel stack for use before relocation is on.	*/
 	ld	r1,PACAEMERGSP(r13)
@@ -503,11 +550,14 @@ _GLOBAL(pmac_secondary_start)
  *   1. Processor number
  *   2. Segment table pointer (virtual address)
  * On entry the following are set:
- *   r1	= stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
- *   r24   = cpu# (in Linux terms)
- *   r13   = paca virtual address
- *   SPRG3 = paca virtual address
+ *   r1	       = stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
+ *   r24       = cpu# (in Linux terms)
+ *   r13       = paca virtual address
+ *   SPRG_PACA = paca virtual address
  */
+	.section ".text";
+	.align 2 ;
+
 	.globl	__secondary_start
 __secondary_start:
 	/* Set thread priority to MEDIUM */
@@ -544,7 +594,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
 	mtspr	SPRN_SRR0,r3
 	mtspr	SPRN_SRR1,r4
-	rfid
+	RFI
 	b	.	/* prevent speculative execution */
 
 /* 
@@ -565,11 +615,16 @@ _GLOBAL(start_secondary_prolog)
  */
 _GLOBAL(enable_64b_mode)
 	mfmsr	r11			/* grab the current MSR */
+#ifdef CONFIG_PPC_BOOK3E
+	oris	r11,r11,0x8000		/* CM bit set, we'll set ICM later */
+	mtmsr	r11
+#else /* CONFIG_PPC_BOOK3E */
 	li	r12,(MSR_SF | MSR_ISF)@highest
 	sldi	r12,r12,48
 	or	r11,r11,r12
 	mtmsrd	r11
 	isync
+#endif
 	blr
 
 /*
@@ -613,9 +668,11 @@ _INIT_STATIC(start_here_multiplatform)
 	bdnz	3b
 4:
 
+#ifndef CONFIG_PPC_BOOK3E
 	mfmsr	r6
 	ori	r6,r6,MSR_RI
 	mtmsrd	r6			/* RI on */
+#endif
 
 #ifdef CONFIG_RELOCATABLE
 	/* Save the physical address we're running at in kernstart_addr */
@@ -642,13 +699,13 @@ _INIT_STATIC(start_here_multiplatform)
 
 	/* Restore parameters passed from prom_init/kexec */
 	mr	r3,r31
-	bl	.early_setup		/* also sets r13 and SPRG3 */
+	bl	.early_setup		/* also sets r13 and SPRG_PACA */
 
 	LOAD_REG_ADDR(r3, .start_here_common)
 	ld	r4,PACAKMSR(r13)
 	mtspr	SPRN_SRR0,r3
 	mtspr	SPRN_SRR1,r4
-	rfid
+	RFI
 	b	.	/* prevent speculative execution */
 	
 	/* This is where all platforms converge execution */
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 52ff8c5..6ded19d 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -110,8 +110,8 @@ turn_on_mmu:
  * task's thread_struct.
  */
 #define EXCEPTION_PROLOG	\
-	mtspr	SPRN_SPRG0,r10;	\
-	mtspr	SPRN_SPRG1,r11;	\
+	mtspr	SPRN_SPRG_SCRATCH0,r10;	\
+	mtspr	SPRN_SPRG_SCRATCH1,r11;	\
 	mfcr	r10;		\
 	EXCEPTION_PROLOG_1;	\
 	EXCEPTION_PROLOG_2
@@ -121,7 +121,7 @@ turn_on_mmu:
 	andi.	r11,r11,MSR_PR;	\
 	tophys(r11,r1);			/* use tophys(r1) if kernel */ \
 	beq	1f;		\
-	mfspr	r11,SPRN_SPRG3;	\
+	mfspr	r11,SPRN_SPRG_THREAD;	\
 	lwz	r11,THREAD_INFO-THREAD(r11);	\
 	addi	r11,r11,THREAD_SIZE;	\
 	tophys(r11,r11);	\
@@ -133,9 +133,9 @@ turn_on_mmu:
 	stw	r10,_CCR(r11);		/* save registers */ \
 	stw	r12,GPR12(r11);	\
 	stw	r9,GPR9(r11);	\
-	mfspr	r10,SPRN_SPRG0;	\
+	mfspr	r10,SPRN_SPRG_SCRATCH0;	\
 	stw	r10,GPR10(r11);	\
-	mfspr	r12,SPRN_SPRG1;	\
+	mfspr	r12,SPRN_SPRG_SCRATCH1;	\
 	stw	r12,GPR11(r11);	\
 	mflr	r10;		\
 	stw	r10,_LINK(r11);	\
@@ -603,8 +603,9 @@ start_here:
 	/* ptr to phys current thread */
 	tophys(r4,r2)
 	addi	r4,r4,THREAD	/* init task's THREAD */
-	mtspr	SPRN_SPRG3,r4
+	mtspr	SPRN_SPRG_THREAD,r4
 	li	r3,0
+	/* XXX What is that for ? SPRG2 appears otherwise unused on 8xx */
 	mtspr	SPRN_SPRG2,r3	/* 0 => r1 has kernel sp */
 
 	/* stack */
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 5f9febc..50504ae 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -20,14 +20,14 @@
 #endif
 
 #define NORMAL_EXCEPTION_PROLOG						     \
-	mtspr	SPRN_SPRG0,r10;		/* save two registers to work with */\
-	mtspr	SPRN_SPRG1,r11;						     \
-	mtspr	SPRN_SPRG4W,r1;						     \
+	mtspr	SPRN_SPRG_WSCRATCH0,r10;/* save two registers to work with */\
+	mtspr	SPRN_SPRG_WSCRATCH1,r11;				     \
+	mtspr	SPRN_SPRG_WSCRATCH2,r1;					     \
 	mfcr	r10;			/* save CR in r10 for now	   */\
 	mfspr	r11,SPRN_SRR1;		/* check whether user or kernel    */\
 	andi.	r11,r11,MSR_PR;						     \
 	beq	1f;							     \
-	mfspr	r1,SPRN_SPRG3;		/* if from user, start at top of   */\
+	mfspr	r1,SPRN_SPRG_THREAD;	/* if from user, start at top of   */\
 	lwz	r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack   */\
 	ALLOC_STACK_FRAME(r1, THREAD_SIZE);				     \
 1:	subi	r1,r1,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
@@ -35,13 +35,13 @@
 	stw	r10,_CCR(r11);          /* save various registers	   */\
 	stw	r12,GPR12(r11);						     \
 	stw	r9,GPR9(r11);						     \
-	mfspr	r10,SPRN_SPRG0;						     \
+	mfspr	r10,SPRN_SPRG_RSCRATCH0;					\
 	stw	r10,GPR10(r11);						     \
-	mfspr	r12,SPRN_SPRG1;						     \
+	mfspr	r12,SPRN_SPRG_RSCRATCH1;				     \
 	stw	r12,GPR11(r11);						     \
 	mflr	r10;							     \
 	stw	r10,_LINK(r11);						     \
-	mfspr	r10,SPRN_SPRG4R;					     \
+	mfspr	r10,SPRN_SPRG_RSCRATCH2;				     \
 	mfspr	r12,SPRN_SRR0;						     \
 	stw	r10,GPR1(r11);						     \
 	mfspr	r9,SPRN_SRR1;						     \
@@ -69,21 +69,11 @@
  * providing configurations that micro-optimize space usage.
  */
 
-/* CRIT_SPRG only used in critical exception handling */
-#define CRIT_SPRG	SPRN_SPRG2
-/* MCHECK_SPRG only used in machine check exception handling */
-#define MCHECK_SPRG	SPRN_SPRG6W
-
-#define MCHECK_STACK_BASE	mcheckirq_ctx
+#define MC_STACK_BASE		mcheckirq_ctx
 #define CRIT_STACK_BASE		critirq_ctx
 
 /* only on e500mc/e200 */
-#define DEBUG_STACK_BASE	dbgirq_ctx
-#ifdef CONFIG_E200
-#define DEBUG_SPRG		SPRN_SPRG6W
-#else
-#define DEBUG_SPRG		SPRN_SPRG9
-#endif
+#define DBG_STACK_BASE		dbgirq_ctx
 
 #define EXC_LVL_FRAME_OVERHEAD	(THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
 
@@ -110,7 +100,7 @@
  * critical/machine check exception stack at low physical addresses.
  */
 #define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
-	mtspr	exc_level##_SPRG,r8;					     \
+	mtspr	SPRN_SPRG_WSCRATCH_##exc_level,r8;			     \
 	BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
 	stw	r9,GPR9(r8);		/* save various registers	   */\
 	mfcr	r9;			/* save CR in r9 for now	   */\
@@ -119,7 +109,7 @@
 	stw	r9,_CCR(r8);		/* save CR on stack		   */\
 	mfspr	r10,exc_level_srr1;	/* check whether user or kernel    */\
 	andi.	r10,r10,MSR_PR;						     \
-	mfspr	r11,SPRN_SPRG3;		/* if from user, start at top of   */\
+	mfspr	r11,SPRN_SPRG_THREAD;	/* if from user, start at top of   */\
 	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
 	addi	r11,r11,EXC_LVL_FRAME_OVERHEAD;	/* allocate stack frame    */\
 	beq	1f;							     \
@@ -140,7 +130,7 @@
 	lwz	r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r11);			     \
 	stw	r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r8);			     \
 	mr	r11,r8;							     \
-2:	mfspr	r8,exc_level##_SPRG;					     \
+2:	mfspr	r8,SPRN_SPRG_RSCRATCH_##exc_level;			     \
 	stw	r12,GPR12(r11);		/* save various registers	   */\
 	mflr	r10;							     \
 	stw	r10,_LINK(r11);						     \
@@ -161,9 +151,9 @@
 #define CRITICAL_EXCEPTION_PROLOG \
 		EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
 #define DEBUG_EXCEPTION_PROLOG \
-		EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1)
+		EXC_LEVEL_EXCEPTION_PROLOG(DBG, SPRN_DSRR0, SPRN_DSRR1)
 #define MCHECK_EXCEPTION_PROLOG \
-		EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
+		EXC_LEVEL_EXCEPTION_PROLOG(MC, SPRN_MCSRR0, SPRN_MCSRR1)
 
 /*
  * Exception vectors.
@@ -282,13 +272,13 @@ label:
 	mtspr	SPRN_DSRR1,r9;						      \
 	lwz	r9,GPR9(r11);						      \
 	lwz	r12,GPR12(r11);						      \
-	mtspr	DEBUG_SPRG,r8;						      \
-	BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
+	mtspr	SPRN_SPRG_WSCRATCH_DBG,r8;				      \
+	BOOKE_LOAD_EXC_LEVEL_STACK(DBG); /* r8 points to the debug stack */ \
 	lwz	r10,GPR10(r8);						      \
 	lwz	r11,GPR11(r8);						      \
-	mfspr	r8,DEBUG_SPRG;						      \
+	mfspr	r8,SPRN_SPRG_RSCRATCH_DBG;				      \
 									      \
-	PPC_RFDI;								      \
+	PPC_RFDI;							      \
 	b	.;							      \
 									      \
 	/* continue normal handling for a debug exception... */		      \
@@ -335,11 +325,11 @@ label:
 	mtspr	SPRN_CSRR1,r9;						      \
 	lwz	r9,GPR9(r11);						      \
 	lwz	r12,GPR12(r11);						      \
-	mtspr	CRIT_SPRG,r8;						      \
+	mtspr	SPRN_SPRG_WSCRATCH_CRIT,r8;				      \
 	BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */  \
 	lwz	r10,GPR10(r8);						      \
 	lwz	r11,GPR11(r8);						      \
-	mfspr	r8,CRIT_SPRG;						      \
+	mfspr	r8,SPRN_SPRG_RSCRATCH_CRIT;				      \
 									      \
 	rfci;								      \
 	b	.;							      \
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 5bdcc06..975788c 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -361,7 +361,7 @@ skpinv:	addi	r6,r6,1				/* Increment */
 
 	/* ptr to current thread */
 	addi	r4,r2,THREAD	/* init task's THREAD */
-	mtspr	SPRN_SPRG3,r4
+	mtspr	SPRN_SPRG_THREAD,r4
 
 	/* stack */
 	lis	r1,init_thread_union@h
@@ -532,12 +532,12 @@ interrupt_base:
 
 	/* Data TLB Error Interrupt */
 	START_EXCEPTION(DataTLBError)
-	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
-	mtspr	SPRN_SPRG1, r11
-	mtspr	SPRN_SPRG4W, r12
-	mtspr	SPRN_SPRG5W, r13
+	mtspr	SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
+	mtspr	SPRN_SPRG_WSCRATCH1, r11
+	mtspr	SPRN_SPRG_WSCRATCH2, r12
+	mtspr	SPRN_SPRG_WSCRATCH3, r13
 	mfcr	r11
-	mtspr	SPRN_SPRG7W, r11
+	mtspr	SPRN_SPRG_WSCRATCH4, r11
 	mfspr	r10, SPRN_DEAR		/* Get faulting address */
 
 	/* If we are faulting a kernel address, we have to use the
@@ -557,7 +557,7 @@ interrupt_base:
 
 	/* Get the PGD for the current thread */
 3:
-	mfspr	r11,SPRN_SPRG3
+	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 
 4:
@@ -575,7 +575,12 @@ interrupt_base:
 	 *       place or can we save a couple of instructions here ?
 	 */
 	mfspr	r12,SPRN_ESR
+#ifdef CONFIG_PTE_64BIT
+	li	r13,_PAGE_PRESENT
+	oris	r13,r13,_PAGE_ACCESSED@h
+#else
 	li	r13,_PAGE_PRESENT|_PAGE_ACCESSED
+#endif
 	rlwimi	r13,r12,11,29,29
 
 	FIND_PTE
@@ -598,12 +603,12 @@ interrupt_base:
 	/* The bailout.  Restore registers to pre-exception conditions
 	 * and call the heavyweights to help us out.
 	 */
-	mfspr	r11, SPRN_SPRG7R
+	mfspr	r11, SPRN_SPRG_RSCRATCH4
 	mtcr	r11
-	mfspr	r13, SPRN_SPRG5R
-	mfspr	r12, SPRN_SPRG4R
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r13, SPRN_SPRG_RSCRATCH3
+	mfspr	r12, SPRN_SPRG_RSCRATCH2
+	mfspr	r11, SPRN_SPRG_RSCRATCH1
+	mfspr	r10, SPRN_SPRG_RSCRATCH0
 	b	DataStorage
 
 	/* Instruction TLB Error Interrupt */
@@ -613,12 +618,12 @@ interrupt_base:
 	 * to a different point.
 	 */
 	START_EXCEPTION(InstructionTLBError)
-	mtspr	SPRN_SPRG0, r10		/* Save some working registers */
-	mtspr	SPRN_SPRG1, r11
-	mtspr	SPRN_SPRG4W, r12
-	mtspr	SPRN_SPRG5W, r13
+	mtspr	SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
+	mtspr	SPRN_SPRG_WSCRATCH1, r11
+	mtspr	SPRN_SPRG_WSCRATCH2, r12
+	mtspr	SPRN_SPRG_WSCRATCH3, r13
 	mfcr	r11
-	mtspr	SPRN_SPRG7W, r11
+	mtspr	SPRN_SPRG_WSCRATCH4, r11
 	mfspr	r10, SPRN_SRR0		/* Get faulting address */
 
 	/* If we are faulting a kernel address, we have to use the
@@ -638,12 +643,17 @@ interrupt_base:
 
 	/* Get the PGD for the current thread */
 3:
-	mfspr	r11,SPRN_SPRG3
+	mfspr	r11,SPRN_SPRG_THREAD
 	lwz	r11,PGDIR(r11)
 
 4:
 	/* Make up the required permissions */
-	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
+#ifdef CONFIG_PTE_64BIT
+	li	r13,_PAGE_PRESENT | _PAGE_EXEC
+	oris	r13,r13,_PAGE_ACCESSED@h
+#else
+	li	r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
+#endif
 
 	FIND_PTE
 	andc.	r13,r13,r11		/* Check permission */
@@ -666,12 +676,12 @@ interrupt_base:
 	/* The bailout.  Restore registers to pre-exception conditions
 	 * and call the heavyweights to help us out.
 	 */
-	mfspr	r11, SPRN_SPRG7R
+	mfspr	r11, SPRN_SPRG_RSCRATCH4
 	mtcr	r11
-	mfspr	r13, SPRN_SPRG5R
-	mfspr	r12, SPRN_SPRG4R
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r13, SPRN_SPRG_RSCRATCH3
+	mfspr	r12, SPRN_SPRG_RSCRATCH2
+	mfspr	r11, SPRN_SPRG_RSCRATCH1
+	mfspr	r10, SPRN_SPRG_RSCRATCH0
 	b	InstructionStorage
 
 #ifdef CONFIG_SPE
@@ -733,7 +743,7 @@ finish_tlb_load:
 
 	mfspr	r12, SPRN_MAS2
 #ifdef CONFIG_PTE_64BIT
-	rlwimi	r12, r11, 26, 24, 31	/* extract ...WIMGE from pte */
+	rlwimi	r12, r11, 32-19, 27, 31	/* extract WIMGE from pte */
 #else
 	rlwimi	r12, r11, 26, 27, 31	/* extract WIMGE from pte */
 #endif
@@ -742,23 +752,27 @@ finish_tlb_load:
 #endif
 	mtspr	SPRN_MAS2, r12
 
-	li	r10, (_PAGE_HWEXEC | _PAGE_PRESENT)
-	rlwimi	r10, r11, 31, 29, 29	/* extract _PAGE_DIRTY into SW */
-	and	r12, r11, r10
-	andi.	r10, r11, _PAGE_USER	/* Test for _PAGE_USER */
-	slwi	r10, r12, 1
-	or	r10, r10, r12
-	iseleq	r12, r12, r10
-	
 #ifdef CONFIG_PTE_64BIT
-	rlwimi	r12, r13, 24, 0, 7	/* grab RPN[32:39] */
-	rlwimi	r12, r11, 24, 8, 19	/* grab RPN[40:51] */
+	rlwinm	r12, r11, 32-2, 26, 31	/* Move in perm bits */
+	andi.	r10, r11, _PAGE_DIRTY
+	bne	1f
+	li	r10, MAS3_SW | MAS3_UW
+	andc	r12, r12, r10
+1:	rlwimi	r12, r13, 20, 0, 11	/* grab RPN[32:43] */
+	rlwimi	r12, r11, 20, 12, 19	/* grab RPN[44:51] */
 	mtspr	SPRN_MAS3, r12
 BEGIN_MMU_FTR_SECTION
-	srwi	r10, r13, 8		/* grab RPN[8:31] */
+	srwi	r10, r13, 12		/* grab RPN[12:31] */
 	mtspr	SPRN_MAS7, r10
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
 #else
+	li	r10, (_PAGE_EXEC | _PAGE_PRESENT)
+	rlwimi	r10, r11, 31, 29, 29	/* extract _PAGE_DIRTY into SW */
+	and	r12, r11, r10
+	andi.	r10, r11, _PAGE_USER	/* Test for _PAGE_USER */
+	slwi	r10, r12, 1
+	or	r10, r10, r12
+	iseleq	r12, r12, r10
 	rlwimi	r11, r12, 0, 20, 31	/* Extract RPN from PTE and merge with perms */
 	mtspr	SPRN_MAS3, r11
 #endif
@@ -790,12 +804,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
 	tlbwe
 
 	/* Done...restore registers and get out of here.  */
-	mfspr	r11, SPRN_SPRG7R
+	mfspr	r11, SPRN_SPRG_RSCRATCH4
 	mtcr	r11
-	mfspr	r13, SPRN_SPRG5R
-	mfspr	r12, SPRN_SPRG4R
-	mfspr	r11, SPRN_SPRG1
-	mfspr	r10, SPRN_SPRG0
+	mfspr	r13, SPRN_SPRG_RSCRATCH3
+	mfspr	r12, SPRN_SPRG_RSCRATCH2
+	mfspr	r11, SPRN_SPRG_RSCRATCH1
+	mfspr	r10, SPRN_SPRG_RSCRATCH0
 	rfi					/* Force context change */
 
 #ifdef CONFIG_SPE
@@ -839,7 +853,7 @@ load_up_spe:
 #endif /* !CONFIG_SMP */
 	/* enable use of SPE after return */
 	oris	r9,r9,MSR_SPE@h
-	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
+	mfspr	r5,SPRN_SPRG_THREAD	/* current task's THREAD (phys) */
 	li	r4,1
 	li	r10,THREAD_ACC
 	stw	r4,THREAD_USED_SPE(r5)
@@ -1118,7 +1132,7 @@ __secondary_start:
 
 	/* ptr to current thread */
 	addi	r4,r2,THREAD	/* address of our thread_struct */
-	mtspr	SPRN_SPRG3,r4
+	mtspr	SPRN_SPRG_THREAD,r4
 
 	/* Setup the defaults for TLB entries */
 	li	r4,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 6e3f624..a4c8b38 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -127,7 +127,7 @@ static int ibmebus_dma_supported(struct device *dev, u64 mask)
 	return 1;
 }
 
-static struct dma_mapping_ops ibmebus_dma_ops = {
+static struct dma_map_ops ibmebus_dma_ops = {
 	.alloc_coherent = ibmebus_alloc_coherent,
 	.free_coherent  = ibmebus_free_coherent,
 	.map_sg         = ibmebus_map_sg,
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index f7f376e..e5d1211 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -53,7 +53,7 @@
 #include <linux/bootmem.h>
 #include <linux/pci.h>
 #include <linux/debugfs.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -138,9 +138,9 @@ notrace void raw_local_irq_restore(unsigned long en)
 	}
 #endif /* CONFIG_PPC_STD_MMU_64 */
 
-	if (test_perf_counter_pending()) {
-		clear_perf_counter_pending();
-		perf_counter_do_pending();
+	if (test_perf_event_pending()) {
+		clear_perf_event_pending();
+		perf_event_do_pending();
 	}
 
 	/*
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 2419cc7..ed0ac4e 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -35,6 +35,7 @@
 #include <asm/prom.h>
 #include <asm/vdso_datapage.h>
 #include <asm/vio.h>
+#include <asm/mmu.h>
 
 #define MODULE_VERS "1.8"
 #define MODULE_NAME "lparcfg"
@@ -537,6 +538,8 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
 
 	seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc);
 
+	seq_printf(m, "slb_size=%d\n", mmu_slb_size);
+
 	return 0;
 }
 
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 15f28e0..da9c0c4 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -342,10 +342,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
 	addi	r3,r3,L1_CACHE_BYTES
 	bdnz	1b
 	sync				/* wait for dcbst's to get to ram */
+#ifndef CONFIG_44x
 	mtctr	r4
 2:	icbi	0,r6
 	addi	r6,r6,L1_CACHE_BYTES
 	bdnz	2b
+#else
+	/* Flash invalidate on 44x because we are passed kmapped addresses and
+	   this doesn't work for userspace pages due to the virtually tagged
+	   icache.  Sigh. */
+	iccci	0, r0
+#endif
 	sync				/* additional sync needed on g4 */
 	isync
 	blr
diff --git a/arch/powerpc/kernel/mpc7450-pmu.c b/arch/powerpc/kernel/mpc7450-pmu.c
index cc466d0..09d7202 100644
--- a/arch/powerpc/kernel/mpc7450-pmu.c
+++ b/arch/powerpc/kernel/mpc7450-pmu.c
@@ -9,7 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/string.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <asm/reg.h>
 #include <asm/cputable.h>
 
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 87df428..1a4fc0d 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -276,7 +276,7 @@ static int __devinit of_pci_phb_probe(struct of_device *dev,
 #endif /* CONFIG_EEH */
 
 	/* Scan the bus */
-	scan_phb(phb);
+	pcibios_scan_phb(phb, dev->node);
 	if (phb->bus == NULL)
 		return -ENXIO;
 
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index e9962c7..d16b1ea 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -13,6 +13,7 @@
 #include <asm/lppaca.h>
 #include <asm/paca.h>
 #include <asm/sections.h>
+#include <asm/pgtable.h>
 
 /* This symbol is provided by the linker - let it fill in the paca
  * field correctly */
@@ -87,6 +88,8 @@ void __init initialise_pacas(void)
 
 #ifdef CONFIG_PPC_BOOK3S
 		new_paca->lppaca_ptr = &lppaca[cpu];
+#else
+		new_paca->kernel_pgd = swapper_pg_dir;
 #endif
 		new_paca->lock_token = 0x8000;
 		new_paca->paca_index = cpu;
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 5a56e97..e9f4840 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -50,14 +50,14 @@ resource_size_t isa_mem_base;
 unsigned int ppc_pci_flags = 0;
 
 
-static struct dma_mapping_ops *pci_dma_ops = &dma_direct_ops;
+static struct dma_map_ops *pci_dma_ops = &dma_direct_ops;
 
-void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
+void set_pci_dma_ops(struct dma_map_ops *dma_ops)
 {
 	pci_dma_ops = dma_ops;
 }
 
-struct dma_mapping_ops *get_pci_dma_ops(void)
+struct dma_map_ops *get_pci_dma_ops(void)
 {
 	return pci_dma_ops;
 }
@@ -176,8 +176,6 @@ int pci_domain_nr(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pci_domain_nr);
 
-#ifdef CONFIG_PPC_OF
-
 /* This routine is meant to be used early during boot, when the
  * PCI bus numbers have not yet been assigned, and you need to
  * issue PCI config cycles to an OF device.
@@ -210,17 +208,11 @@ static ssize_t pci_show_devspec(struct device *dev,
 	return sprintf(buf, "%s", np->full_name);
 }
 static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-#endif /* CONFIG_PPC_OF */
 
 /* Add sysfs properties */
 int pcibios_add_platform_entries(struct pci_dev *pdev)
 {
-#ifdef CONFIG_PPC_OF
 	return device_create_file(&pdev->dev, &dev_attr_devspec);
-#else
-	return 0;
-#endif /* CONFIG_PPC_OF */
-
 }
 
 char __devinit *pcibios_setup(char *str)
@@ -1626,3 +1618,122 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
 
 }
 
+/*
+ * Null PCI config access functions, for the case when we can't
+ * find a hose.
+ */
+#define NULL_PCI_OP(rw, size, type)					\
+static int								\
+null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{									\
+	return PCIBIOS_DEVICE_NOT_FOUND;    				\
+}
+
+static int
+null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		 int len, u32 *val)
+{
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int
+null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+		  int len, u32 val)
+{
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static struct pci_ops null_pci_ops =
+{
+	.read = null_read_config,
+	.write = null_write_config,
+};
+
+/*
+ * These functions are used early on before PCI scanning is done
+ * and all of the pci_dev and pci_bus structures have been created.
+ */
+static struct pci_bus *
+fake_pci_bus(struct pci_controller *hose, int busnr)
+{
+	static struct pci_bus bus;
+
+	if (hose == 0) {
+		printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
+	}
+	bus.number = busnr;
+	bus.sysdata = hose;
+	bus.ops = hose? hose->ops: &null_pci_ops;
+	return &bus;
+}
+
+#define EARLY_PCI_OP(rw, size, type)					\
+int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
+			       int devfn, int offset, type value)	\
+{									\
+	return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus),	\
+					    devfn, offset, value);	\
+}
+
+EARLY_PCI_OP(read, byte, u8 *)
+EARLY_PCI_OP(read, word, u16 *)
+EARLY_PCI_OP(read, dword, u32 *)
+EARLY_PCI_OP(write, byte, u8)
+EARLY_PCI_OP(write, word, u16)
+EARLY_PCI_OP(write, dword, u32)
+
+extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
+int early_find_capability(struct pci_controller *hose, int bus, int devfn,
+			  int cap)
+{
+	return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
+}
+
+/**
+ * pci_scan_phb - Given a pci_controller, setup and scan the PCI bus
+ * @hose: Pointer to the PCI host controller instance structure
+ * @sysdata: value to use for sysdata pointer.  ppc32 and ppc64 differ here
+ *
+ * Note: the 'data' pointer is a temporary measure.  As 32 and 64 bit
+ * pci code gets merged, this parameter should become unnecessary because
+ * both will use the same value.
+ */
+void __devinit pcibios_scan_phb(struct pci_controller *hose, void *sysdata)
+{
+	struct pci_bus *bus;
+	struct device_node *node = hose->dn;
+	int mode;
+
+	pr_debug("PCI: Scanning PHB %s\n",
+		 node ? node->full_name : "<NO NAME>");
+
+	/* Create an empty bus for the toplevel */
+	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops,
+			     sysdata);
+	if (bus == NULL) {
+		pr_err("Failed to create bus for PCI domain %04x\n",
+			hose->global_number);
+		return;
+	}
+	bus->secondary = hose->first_busno;
+	hose->bus = bus;
+
+	/* Get some IO space for the new PHB */
+	pcibios_setup_phb_io_space(hose);
+
+	/* Wire up PHB bus resources */
+	pcibios_setup_phb_resources(hose);
+
+	/* Get probe mode and perform scan */
+	mode = PCI_PROBE_NORMAL;
+	if (node && ppc_md.pci_probe_mode)
+		mode = ppc_md.pci_probe_mode(bus);
+	pr_debug("    probe mode: %d\n", mode);
+	if (mode == PCI_PROBE_DEVTREE) {
+		bus->subordinate = hose->last_busno;
+		of_scan_bus(node, bus);
+	}
+
+	if (mode == PCI_PROBE_NORMAL)
+		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 3ae1c66..c13668c 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -34,9 +34,7 @@ int pcibios_assign_bus_offset = 1;
 void pcibios_make_OF_bus_map(void);
 
 static void fixup_cpc710_pci64(struct pci_dev* dev);
-#ifdef CONFIG_PPC_OF
 static u8* pci_to_OF_bus_map;
-#endif
 
 /* By default, we don't re-assign bus numbers. We do this only on
  * some pmacs
@@ -83,7 +81,6 @@ fixup_cpc710_pci64(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CPC710_PCI64,	fixup_cpc710_pci64);
 
-#ifdef CONFIG_PPC_OF
 /*
  * Functions below are used on OpenFirmware machines.
  */
@@ -357,42 +354,15 @@ pci_create_OF_bus_map(void)
 	}
 }
 
-#else /* CONFIG_PPC_OF */
-void pcibios_make_OF_bus_map(void)
+void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose)
 {
-}
-#endif /* CONFIG_PPC_OF */
-
-static void __devinit pcibios_scan_phb(struct pci_controller *hose)
-{
-	struct pci_bus *bus;
-	struct device_node *node = hose->dn;
 	unsigned long io_offset;
 	struct resource *res = &hose->io_resource;
 
-	pr_debug("PCI: Scanning PHB %s\n",
-		 node ? node->full_name : "<NO NAME>");
-
-	/* Create an empty bus for the toplevel */
-	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
-	if (bus == NULL) {
-		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
-		       hose->global_number);
-		return;
-	}
-	bus->secondary = hose->first_busno;
-	hose->bus = bus;
-
 	/* Fixup IO space offset */
 	io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
 	res->start = (res->start + io_offset) & 0xffffffffu;
 	res->end = (res->end + io_offset) & 0xffffffffu;
-
-	/* Wire up PHB bus resources */
-	pcibios_setup_phb_resources(hose);
-
-	/* Scan children */
-	hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
 }
 
 static int __init pcibios_init(void)
@@ -410,7 +380,7 @@ static int __init pcibios_init(void)
 		if (pci_assign_all_buses)
 			hose->first_busno = next_busno;
 		hose->last_busno = 0xff;
-		pcibios_scan_phb(hose);
+		pcibios_scan_phb(hose, hose);
 		pci_bus_add_devices(hose->bus);
 		if (pci_assign_all_buses || next_busno <= hose->last_busno)
 			next_busno = hose->last_busno + pcibios_assign_bus_offset;
@@ -478,75 +448,4 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
 	return result;
 }
 
-/*
- * Null PCI config access functions, for the case when we can't
- * find a hose.
- */
-#define NULL_PCI_OP(rw, size, type)					\
-static int								\
-null_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
-{									\
-	return PCIBIOS_DEVICE_NOT_FOUND;    				\
-}
 
-static int
-null_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
-		 int len, u32 *val)
-{
-	return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-static int
-null_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
-		  int len, u32 val)
-{
-	return PCIBIOS_DEVICE_NOT_FOUND;
-}
-
-static struct pci_ops null_pci_ops =
-{
-	.read = null_read_config,
-	.write = null_write_config,
-};
-
-/*
- * These functions are used early on before PCI scanning is done
- * and all of the pci_dev and pci_bus structures have been created.
- */
-static struct pci_bus *
-fake_pci_bus(struct pci_controller *hose, int busnr)
-{
-	static struct pci_bus bus;
-
-	if (hose == 0) {
-		hose = pci_bus_to_hose(busnr);
-		if (hose == 0)
-			printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr);
-	}
-	bus.number = busnr;
-	bus.sysdata = hose;
-	bus.ops = hose? hose->ops: &null_pci_ops;
-	return &bus;
-}
-
-#define EARLY_PCI_OP(rw, size, type)					\
-int early_##rw##_config_##size(struct pci_controller *hose, int bus,	\
-			       int devfn, int offset, type value)	\
-{									\
-	return pci_bus_##rw##_config_##size(fake_pci_bus(hose, bus),	\
-					    devfn, offset, value);	\
-}
-
-EARLY_PCI_OP(read, byte, u8 *)
-EARLY_PCI_OP(read, word, u16 *)
-EARLY_PCI_OP(read, dword, u32 *)
-EARLY_PCI_OP(write, byte, u8)
-EARLY_PCI_OP(write, word, u16)
-EARLY_PCI_OP(write, dword, u32)
-
-extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
-int early_find_capability(struct pci_controller *hose, int bus, int devfn,
-			  int cap)
-{
-	return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
-}
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 9e8902f..ba949a2 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -43,334 +43,6 @@ unsigned long pci_probe_only = 1;
 unsigned long pci_io_base = ISA_IO_BASE;
 EXPORT_SYMBOL(pci_io_base);
 
-static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
-{
-	const u32 *prop;
-	int len;
-
-	prop = of_get_property(np, name, &len);
-	if (prop && len >= 4)
-		return *prop;
-	return def;
-}
-
-static unsigned int pci_parse_of_flags(u32 addr0, int bridge)
-{
-	unsigned int flags = 0;
-
-	if (addr0 & 0x02000000) {
-		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
-		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
-		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
-		if (addr0 & 0x40000000)
-			flags |= IORESOURCE_PREFETCH
-				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
-		/* Note: We don't know whether the ROM has been left enabled
-		 * by the firmware or not. We mark it as disabled (ie, we do
-		 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
-		 * do a config space read, it will be force-enabled if needed
-		 */
-		if (!bridge && (addr0 & 0xff) == 0x30)
-			flags |= IORESOURCE_READONLY;
-	} else if (addr0 & 0x01000000)
-		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
-	if (flags)
-		flags |= IORESOURCE_SIZEALIGN;
-	return flags;
-}
-
-
-static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
-{
-	u64 base, size;
-	unsigned int flags;
-	struct resource *res;
-	const u32 *addrs;
-	u32 i;
-	int proplen;
-
-	addrs = of_get_property(node, "assigned-addresses", &proplen);
-	if (!addrs)
-		return;
-	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
-	for (; proplen >= 20; proplen -= 20, addrs += 5) {
-		flags = pci_parse_of_flags(addrs[0], 0);
-		if (!flags)
-			continue;
-		base = of_read_number(&addrs[1], 2);
-		size = of_read_number(&addrs[3], 2);
-		if (!size)
-			continue;
-		i = addrs[0] & 0xff;
-		pr_debug("  base: %llx, size: %llx, i: %x\n",
-			 (unsigned long long)base,
-			 (unsigned long long)size, i);
-
-		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
-			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
-		} else if (i == dev->rom_base_reg) {
-			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
-		} else {
-			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
-			continue;
-		}
-		res->start = base;
-		res->end = base + size - 1;
-		res->flags = flags;
-		res->name = pci_name(dev);
-	}
-}
-
-struct pci_dev *of_create_pci_dev(struct device_node *node,
-				 struct pci_bus *bus, int devfn)
-{
-	struct pci_dev *dev;
-	const char *type;
-
-	dev = alloc_pci_dev();
-	if (!dev)
-		return NULL;
-	type = of_get_property(node, "device_type", NULL);
-	if (type == NULL)
-		type = "";
-
-	pr_debug("    create device, devfn: %x, type: %s\n", devfn, type);
-
-	dev->bus = bus;
-	dev->sysdata = node;
-	dev->dev.parent = bus->bridge;
-	dev->dev.bus = &pci_bus_type;
-	dev->devfn = devfn;
-	dev->multifunction = 0;		/* maybe a lie? */
-
-	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
-	dev->device = get_int_prop(node, "device-id", 0xffff);
-	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
-	dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
-
-	dev->cfg_size = pci_cfg_space_size(dev);
-
-	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
-		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
-	dev->class = get_int_prop(node, "class-code", 0);
-	dev->revision = get_int_prop(node, "revision-id", 0);
-
-	pr_debug("    class: 0x%x\n", dev->class);
-	pr_debug("    revision: 0x%x\n", dev->revision);
-
-	dev->current_state = 4;		/* unknown power state */
-	dev->error_state = pci_channel_io_normal;
-	dev->dma_mask = 0xffffffff;
-
-	if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
-		/* a PCI-PCI bridge */
-		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
-		dev->rom_base_reg = PCI_ROM_ADDRESS1;
-	} else if (!strcmp(type, "cardbus")) {
-		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
-	} else {
-		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
-		dev->rom_base_reg = PCI_ROM_ADDRESS;
-		/* Maybe do a default OF mapping here */
-		dev->irq = NO_IRQ;
-	}
-
-	pci_parse_of_addrs(node, dev);
-
-	pr_debug("    adding to system ...\n");
-
-	pci_device_add(dev, bus);
-
-	return dev;
-}
-EXPORT_SYMBOL(of_create_pci_dev);
-
-static void __devinit __of_scan_bus(struct device_node *node,
-				    struct pci_bus *bus, int rescan_existing)
-{
-	struct device_node *child;
-	const u32 *reg;
-	int reglen, devfn;
-	struct pci_dev *dev;
-
-	pr_debug("of_scan_bus(%s) bus no %d... \n",
-		 node->full_name, bus->number);
-
-	/* Scan direct children */
-	for_each_child_of_node(node, child) {
-		pr_debug("  * %s\n", child->full_name);
-		reg = of_get_property(child, "reg", &reglen);
-		if (reg == NULL || reglen < 20)
-			continue;
-		devfn = (reg[0] >> 8) & 0xff;
-
-		/* create a new pci_dev for this device */
-		dev = of_create_pci_dev(child, bus, devfn);
-		if (!dev)
-			continue;
-		pr_debug("    dev header type: %x\n", dev->hdr_type);
-	}
-
-	/* Apply all fixups necessary. We don't fixup the bus "self"
-	 * for an existing bridge that is being rescanned
-	 */
-	if (!rescan_existing)
-		pcibios_setup_bus_self(bus);
-	pcibios_setup_bus_devices(bus);
-
-	/* Now scan child busses */
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
-			struct device_node *child = pci_device_to_OF_node(dev);
-			if (dev)
-				of_scan_pci_bridge(child, dev);
-		}
-	}
-}
-
-void __devinit of_scan_bus(struct device_node *node,
-			   struct pci_bus *bus)
-{
-	__of_scan_bus(node, bus, 0);
-}
-EXPORT_SYMBOL_GPL(of_scan_bus);
-
-void __devinit of_rescan_bus(struct device_node *node,
-			     struct pci_bus *bus)
-{
-	__of_scan_bus(node, bus, 1);
-}
-EXPORT_SYMBOL_GPL(of_rescan_bus);
-
-void __devinit of_scan_pci_bridge(struct device_node *node,
-				  struct pci_dev *dev)
-{
-	struct pci_bus *bus;
-	const u32 *busrange, *ranges;
-	int len, i, mode;
-	struct resource *res;
-	unsigned int flags;
-	u64 size;
-
-	pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
-
-	/* parse bus-range property */
-	busrange = of_get_property(node, "bus-range", &len);
-	if (busrange == NULL || len != 8) {
-		printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
-		       node->full_name);
-		return;
-	}
-	ranges = of_get_property(node, "ranges", &len);
-	if (ranges == NULL) {
-		printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
-		       node->full_name);
-		return;
-	}
-
-	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
-	if (!bus) {
-		printk(KERN_ERR "Failed to create pci bus for %s\n",
-		       node->full_name);
-		return;
-	}
-
-	bus->primary = dev->bus->number;
-	bus->subordinate = busrange[1];
-	bus->bridge_ctl = 0;
-	bus->sysdata = node;
-
-	/* parse ranges property */
-	/* PCI #address-cells == 3 and #size-cells == 2 always */
-	res = &dev->resource[PCI_BRIDGE_RESOURCES];
-	for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
-		res->flags = 0;
-		bus->resource[i] = res;
-		++res;
-	}
-	i = 1;
-	for (; len >= 32; len -= 32, ranges += 8) {
-		flags = pci_parse_of_flags(ranges[0], 1);
-		size = of_read_number(&ranges[6], 2);
-		if (flags == 0 || size == 0)
-			continue;
-		if (flags & IORESOURCE_IO) {
-			res = bus->resource[0];
-			if (res->flags) {
-				printk(KERN_ERR "PCI: ignoring extra I/O range"
-				       " for bridge %s\n", node->full_name);
-				continue;
-			}
-		} else {
-			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
-				printk(KERN_ERR "PCI: too many memory ranges"
-				       " for bridge %s\n", node->full_name);
-				continue;
-			}
-			res = bus->resource[i];
-			++i;
-		}
-		res->start = of_read_number(&ranges[1], 2);
-		res->end = res->start + size - 1;
-		res->flags = flags;
-	}
-	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
-		bus->number);
-	pr_debug("    bus name: %s\n", bus->name);
-
-	mode = PCI_PROBE_NORMAL;
-	if (ppc_md.pci_probe_mode)
-		mode = ppc_md.pci_probe_mode(bus);
-	pr_debug("    probe mode: %d\n", mode);
-
-	if (mode == PCI_PROBE_DEVTREE)
-		of_scan_bus(node, bus);
-	else if (mode == PCI_PROBE_NORMAL)
-		pci_scan_child_bus(bus);
-}
-EXPORT_SYMBOL(of_scan_pci_bridge);
-
-void __devinit scan_phb(struct pci_controller *hose)
-{
-	struct pci_bus *bus;
-	struct device_node *node = hose->dn;
-	int mode;
-
-	pr_debug("PCI: Scanning PHB %s\n",
-		 node ? node->full_name : "<NO NAME>");
-
-	/* Create an empty bus for the toplevel */
-	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
-	if (bus == NULL) {
-		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
-		       hose->global_number);
-		return;
-	}
-	bus->secondary = hose->first_busno;
-	hose->bus = bus;
-
-	/* Get some IO space for the new PHB */
-	pcibios_map_io_space(bus);
-
-	/* Wire up PHB bus resources */
-	pcibios_setup_phb_resources(hose);
-
-	/* Get probe mode and perform scan */
-	mode = PCI_PROBE_NORMAL;
-	if (node && ppc_md.pci_probe_mode)
-		mode = ppc_md.pci_probe_mode(bus);
-	pr_debug("    probe mode: %d\n", mode);
-	if (mode == PCI_PROBE_DEVTREE) {
-		bus->subordinate = hose->last_busno;
-		of_scan_bus(node, bus);
-	}
-
-	if (mode == PCI_PROBE_NORMAL)
-		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
-}
-
 static int __init pcibios_init(void)
 {
 	struct pci_controller *hose, *tmp;
@@ -392,7 +64,7 @@ static int __init pcibios_init(void)
 
 	/* Scan all of the recorded PCI controllers.  */
 	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
-		scan_phb(hose);
+		pcibios_scan_phb(hose, hose->dn);
 		pci_bus_add_devices(hose->bus);
 	}
 
@@ -526,6 +198,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
 }
 EXPORT_SYMBOL_GPL(pcibios_map_io_space);
 
+void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose)
+{
+	pcibios_map_io_space(hose->bus);
+}
+
 #define IOBASE_BRIDGE_NUMBER	0
 #define IOBASE_MEMORY		1
 #define IOBASE_IO		2
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
new file mode 100644
index 0000000..7311fdf
--- /dev/null
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -0,0 +1,359 @@
+/*
+ * Helper routines to scan the device tree for PCI devices and busses
+ *
+ * Migrated out of PowerPC architecture pci_64.c file by Grant Likely
+ * <grant.likely@secretlab.ca> so that these routines are available for
+ * 32 bit also.
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ *   Rework, based on alpha PCI code.
+ * Copyright (c) 2009 Secret Lab Technologies 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/pci.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+
+/**
+ * get_int_prop - Decode a u32 from a device tree property
+ */
+static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
+{
+	const u32 *prop;
+	int len;
+
+	prop = of_get_property(np, name, &len);
+	if (prop && len >= 4)
+		return *prop;
+	return def;
+}
+
+/**
+ * pci_parse_of_flags - Parse the flags cell of a device tree PCI address
+ * @addr0: value of 1st cell of a device tree PCI address.
+ * @bridge: Set this flag if the address is from a bridge 'ranges' property
+ */
+unsigned int pci_parse_of_flags(u32 addr0, int bridge)
+{
+	unsigned int flags = 0;
+
+	if (addr0 & 0x02000000) {
+		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
+		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
+		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
+		if (addr0 & 0x40000000)
+			flags |= IORESOURCE_PREFETCH
+				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
+		/* Note: We don't know whether the ROM has been left enabled
+		 * by the firmware or not. We mark it as disabled (ie, we do
+		 * not set the IORESOURCE_ROM_ENABLE flag) for now rather than
+		 * do a config space read, it will be force-enabled if needed
+		 */
+		if (!bridge && (addr0 & 0xff) == 0x30)
+			flags |= IORESOURCE_READONLY;
+	} else if (addr0 & 0x01000000)
+		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+	if (flags)
+		flags |= IORESOURCE_SIZEALIGN;
+	return flags;
+}
+
+/**
+ * of_pci_parse_addrs - Parse PCI addresses assigned in the device tree node
+ * @node: device tree node for the PCI device
+ * @dev: pci_dev structure for the device
+ *
+ * This function parses the 'assigned-addresses' property of a PCI devices'
+ * device tree node and writes them into the associated pci_dev structure.
+ */
+static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
+{
+	u64 base, size;
+	unsigned int flags;
+	struct resource *res;
+	const u32 *addrs;
+	u32 i;
+	int proplen;
+
+	addrs = of_get_property(node, "assigned-addresses", &proplen);
+	if (!addrs)
+		return;
+	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
+	for (; proplen >= 20; proplen -= 20, addrs += 5) {
+		flags = pci_parse_of_flags(addrs[0], 0);
+		if (!flags)
+			continue;
+		base = of_read_number(&addrs[1], 2);
+		size = of_read_number(&addrs[3], 2);
+		if (!size)
+			continue;
+		i = addrs[0] & 0xff;
+		pr_debug("  base: %llx, size: %llx, i: %x\n",
+			 (unsigned long long)base,
+			 (unsigned long long)size, i);
+
+		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
+			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
+		} else if (i == dev->rom_base_reg) {
+			res = &dev->resource[PCI_ROM_RESOURCE];
+			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+		} else {
+			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
+			continue;
+		}
+		res->start = base;
+		res->end = base + size - 1;
+		res->flags = flags;
+		res->name = pci_name(dev);
+	}
+}
+
+/**
+ * of_create_pci_dev - Given a device tree node on a pci bus, create a pci_dev
+ * @node: device tree node pointer
+ * @bus: bus the device is sitting on
+ * @devfn: PCI function number, extracted from device tree by caller.
+ */
+struct pci_dev *of_create_pci_dev(struct device_node *node,
+				 struct pci_bus *bus, int devfn)
+{
+	struct pci_dev *dev;
+	const char *type;
+
+	dev = alloc_pci_dev();
+	if (!dev)
+		return NULL;
+	type = of_get_property(node, "device_type", NULL);
+	if (type == NULL)
+		type = "";
+
+	pr_debug("    create device, devfn: %x, type: %s\n", devfn, type);
+
+	dev->bus = bus;
+	dev->sysdata = node;
+	dev->dev.parent = bus->bridge;
+	dev->dev.bus = &pci_bus_type;
+	dev->devfn = devfn;
+	dev->multifunction = 0;		/* maybe a lie? */
+	dev->needs_freset = 0;		/* pcie fundamental reset required */
+
+	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
+	dev->device = get_int_prop(node, "device-id", 0xffff);
+	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
+	dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
+
+	dev->cfg_size = pci_cfg_space_size(dev);
+
+	dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+	dev->class = get_int_prop(node, "class-code", 0);
+	dev->revision = get_int_prop(node, "revision-id", 0);
+
+	pr_debug("    class: 0x%x\n", dev->class);
+	pr_debug("    revision: 0x%x\n", dev->revision);
+
+	dev->current_state = 4;		/* unknown power state */
+	dev->error_state = pci_channel_io_normal;
+	dev->dma_mask = 0xffffffff;
+
+	if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
+		/* a PCI-PCI bridge */
+		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
+		dev->rom_base_reg = PCI_ROM_ADDRESS1;
+	} else if (!strcmp(type, "cardbus")) {
+		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+	} else {
+		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
+		dev->rom_base_reg = PCI_ROM_ADDRESS;
+		/* Maybe do a default OF mapping here */
+		dev->irq = NO_IRQ;
+	}
+
+	of_pci_parse_addrs(node, dev);
+
+	pr_debug("    adding to system ...\n");
+
+	pci_device_add(dev, bus);
+
+	return dev;
+}
+EXPORT_SYMBOL(of_create_pci_dev);
+
+/**
+ * of_scan_pci_bridge - Set up a PCI bridge and scan for child nodes
+ * @node: device tree node of bridge
+ * @dev: pci_dev structure for the bridge
+ *
+ * of_scan_bus() calls this routine for each PCI bridge that it finds, and
+ * this routine in turn call of_scan_bus() recusively to scan for more child
+ * devices.
+ */
+void __devinit of_scan_pci_bridge(struct device_node *node,
+				  struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	const u32 *busrange, *ranges;
+	int len, i, mode;
+	struct resource *res;
+	unsigned int flags;
+	u64 size;
+
+	pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
+
+	/* parse bus-range property */
+	busrange = of_get_property(node, "bus-range", &len);
+	if (busrange == NULL || len != 8) {
+		printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
+		       node->full_name);
+		return;
+	}
+	ranges = of_get_property(node, "ranges", &len);
+	if (ranges == NULL) {
+		printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
+		       node->full_name);
+		return;
+	}
+
+	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+	if (!bus) {
+		printk(KERN_ERR "Failed to create pci bus for %s\n",
+		       node->full_name);
+		return;
+	}
+
+	bus->primary = dev->bus->number;
+	bus->subordinate = busrange[1];
+	bus->bridge_ctl = 0;
+	bus->sysdata = node;
+
+	/* parse ranges property */
+	/* PCI #address-cells == 3 and #size-cells == 2 always */
+	res = &dev->resource[PCI_BRIDGE_RESOURCES];
+	for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
+		res->flags = 0;
+		bus->resource[i] = res;
+		++res;
+	}
+	i = 1;
+	for (; len >= 32; len -= 32, ranges += 8) {
+		flags = pci_parse_of_flags(ranges[0], 1);
+		size = of_read_number(&ranges[6], 2);
+		if (flags == 0 || size == 0)
+			continue;
+		if (flags & IORESOURCE_IO) {
+			res = bus->resource[0];
+			if (res->flags) {
+				printk(KERN_ERR "PCI: ignoring extra I/O range"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+		} else {
+			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
+				printk(KERN_ERR "PCI: too many memory ranges"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+			res = bus->resource[i];
+			++i;
+		}
+		res->start = of_read_number(&ranges[1], 2);
+		res->end = res->start + size - 1;
+		res->flags = flags;
+	}
+	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
+		bus->number);
+	pr_debug("    bus name: %s\n", bus->name);
+
+	mode = PCI_PROBE_NORMAL;
+	if (ppc_md.pci_probe_mode)
+		mode = ppc_md.pci_probe_mode(bus);
+	pr_debug("    probe mode: %d\n", mode);
+
+	if (mode == PCI_PROBE_DEVTREE)
+		of_scan_bus(node, bus);
+	else if (mode == PCI_PROBE_NORMAL)
+		pci_scan_child_bus(bus);
+}
+EXPORT_SYMBOL(of_scan_pci_bridge);
+
+/**
+ * __of_scan_bus - given a PCI bus node, setup bus and scan for child devices
+ * @node: device tree node for the PCI bus
+ * @bus: pci_bus structure for the PCI bus
+ * @rescan_existing: Flag indicating bus has already been set up
+ */
+static void __devinit __of_scan_bus(struct device_node *node,
+				    struct pci_bus *bus, int rescan_existing)
+{
+	struct device_node *child;
+	const u32 *reg;
+	int reglen, devfn;
+	struct pci_dev *dev;
+
+	pr_debug("of_scan_bus(%s) bus no %d... \n",
+		 node->full_name, bus->number);
+
+	/* Scan direct children */
+	for_each_child_of_node(node, child) {
+		pr_debug("  * %s\n", child->full_name);
+		reg = of_get_property(child, "reg", &reglen);
+		if (reg == NULL || reglen < 20)
+			continue;
+		devfn = (reg[0] >> 8) & 0xff;
+
+		/* create a new pci_dev for this device */
+		dev = of_create_pci_dev(child, bus, devfn);
+		if (!dev)
+			continue;
+		pr_debug("    dev header type: %x\n", dev->hdr_type);
+	}
+
+	/* Apply all fixups necessary. We don't fixup the bus "self"
+	 * for an existing bridge that is being rescanned
+	 */
+	if (!rescan_existing)
+		pcibios_setup_bus_self(bus);
+	pcibios_setup_bus_devices(bus);
+
+	/* Now scan child busses */
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
+			struct device_node *child = pci_device_to_OF_node(dev);
+			if (dev)
+				of_scan_pci_bridge(child, dev);
+		}
+	}
+}
+
+/**
+ * of_scan_bus - given a PCI bus node, setup bus and scan for child devices
+ * @node: device tree node for the PCI bus
+ * @bus: pci_bus structure for the PCI bus
+ */
+void __devinit of_scan_bus(struct device_node *node,
+			   struct pci_bus *bus)
+{
+	__of_scan_bus(node, bus, 0);
+}
+EXPORT_SYMBOL_GPL(of_scan_bus);
+
+/**
+ * of_rescan_bus - given a PCI bus node, scan for child devices
+ * @node: device tree node for the PCI bus
+ * @bus: pci_bus structure for the PCI bus
+ *
+ * Same as of_scan_bus, but for a pci_bus structure that has already been
+ * setup.
+ */
+void __devinit of_rescan_bus(struct device_node *node,
+			     struct pci_bus *bus)
+{
+	__of_scan_bus(node, bus, 1);
+}
+EXPORT_SYMBOL_GPL(of_rescan_bus);
+
diff --git a/arch/powerpc/kernel/perf_callchain.c b/arch/powerpc/kernel/perf_callchain.c
index f74b62c..0a03cf7 100644
--- a/arch/powerpc/kernel/perf_callchain.c
+++ b/arch/powerpc/kernel/perf_callchain.c
@@ -10,7 +10,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/percpu.h>
 #include <linux/uaccess.h>
 #include <linux/mm.h>
diff --git a/arch/powerpc/kernel/perf_counter.c b/arch/powerpc/kernel/perf_counter.c
deleted file mode 100644
index 70e1f57..0000000
--- a/arch/powerpc/kernel/perf_counter.c
+++ /dev/null
@@ -1,1314 +0,0 @@
-/*
- * Performance counter support - powerpc architecture code
- *
- * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/perf_counter.h>
-#include <linux/percpu.h>
-#include <linux/hardirq.h>
-#include <asm/reg.h>
-#include <asm/pmc.h>
-#include <asm/machdep.h>
-#include <asm/firmware.h>
-#include <asm/ptrace.h>
-
-struct cpu_hw_counters {
-	int n_counters;
-	int n_percpu;
-	int disabled;
-	int n_added;
-	int n_limited;
-	u8  pmcs_enabled;
-	struct perf_counter *counter[MAX_HWCOUNTERS];
-	u64 events[MAX_HWCOUNTERS];
-	unsigned int flags[MAX_HWCOUNTERS];
-	unsigned long mmcr[3];
-	struct perf_counter *limited_counter[MAX_LIMITED_HWCOUNTERS];
-	u8  limited_hwidx[MAX_LIMITED_HWCOUNTERS];
-};
-DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters);
-
-struct power_pmu *ppmu;
-
-/*
- * Normally, to ignore kernel events we set the FCS (freeze counters
- * in supervisor mode) bit in MMCR0, but if the kernel runs with the
- * hypervisor bit set in the MSR, or if we are running on a processor
- * where the hypervisor bit is forced to 1 (as on Apple G5 processors),
- * then we need to use the FCHV bit to ignore kernel events.
- */
-static unsigned int freeze_counters_kernel = MMCR0_FCS;
-
-/*
- * 32-bit doesn't have MMCRA but does have an MMCR2,
- * and a few other names are different.
- */
-#ifdef CONFIG_PPC32
-
-#define MMCR0_FCHV		0
-#define MMCR0_PMCjCE		MMCR0_PMCnCE
-
-#define SPRN_MMCRA		SPRN_MMCR2
-#define MMCRA_SAMPLE_ENABLE	0
-
-static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
-{
-	return 0;
-}
-static inline void perf_set_pmu_inuse(int inuse) { }
-static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) { }
-static inline u32 perf_get_misc_flags(struct pt_regs *regs)
-{
-	return 0;
-}
-static inline void perf_read_regs(struct pt_regs *regs) { }
-static inline int perf_intr_is_nmi(struct pt_regs *regs)
-{
-	return 0;
-}
-
-#endif /* CONFIG_PPC32 */
-
-/*
- * Things that are specific to 64-bit implementations.
- */
-#ifdef CONFIG_PPC64
-
-static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
-{
-	unsigned long mmcra = regs->dsisr;
-
-	if ((mmcra & MMCRA_SAMPLE_ENABLE) && !(ppmu->flags & PPMU_ALT_SIPR)) {
-		unsigned long slot = (mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT;
-		if (slot > 1)
-			return 4 * (slot - 1);
-	}
-	return 0;
-}
-
-static inline void perf_set_pmu_inuse(int inuse)
-{
-	get_lppaca()->pmcregs_in_use = inuse;
-}
-
-/*
- * The user wants a data address recorded.
- * If we're not doing instruction sampling, give them the SDAR
- * (sampled data address).  If we are doing instruction sampling, then
- * only give them the SDAR if it corresponds to the instruction
- * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC
- * bit in MMCRA.
- */
-static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
-{
-	unsigned long mmcra = regs->dsisr;
-	unsigned long sdsync = (ppmu->flags & PPMU_ALT_SIPR) ?
-		POWER6_MMCRA_SDSYNC : MMCRA_SDSYNC;
-
-	if (!(mmcra & MMCRA_SAMPLE_ENABLE) || (mmcra & sdsync))
-		*addrp = mfspr(SPRN_SDAR);
-}
-
-static inline u32 perf_get_misc_flags(struct pt_regs *regs)
-{
-	unsigned long mmcra = regs->dsisr;
-
-	if (TRAP(regs) != 0xf00)
-		return 0;	/* not a PMU interrupt */
-
-	if (ppmu->flags & PPMU_ALT_SIPR) {
-		if (mmcra & POWER6_MMCRA_SIHV)
-			return PERF_EVENT_MISC_HYPERVISOR;
-		return (mmcra & POWER6_MMCRA_SIPR) ?
-			PERF_EVENT_MISC_USER : PERF_EVENT_MISC_KERNEL;
-	}
-	if (mmcra & MMCRA_SIHV)
-		return PERF_EVENT_MISC_HYPERVISOR;
-	return (mmcra & MMCRA_SIPR) ? PERF_EVENT_MISC_USER :
-		PERF_EVENT_MISC_KERNEL;
-}
-
-/*
- * Overload regs->dsisr to store MMCRA so we only need to read it once
- * on each interrupt.
- */
-static inline void perf_read_regs(struct pt_regs *regs)
-{
-	regs->dsisr = mfspr(SPRN_MMCRA);
-}
-
-/*
- * If interrupts were soft-disabled when a PMU interrupt occurs, treat
- * it as an NMI.
- */
-static inline int perf_intr_is_nmi(struct pt_regs *regs)
-{
-	return !regs->softe;
-}
-
-#endif /* CONFIG_PPC64 */
-
-static void perf_counter_interrupt(struct pt_regs *regs);
-
-void perf_counter_print_debug(void)
-{
-}
-
-/*
- * Read one performance monitor counter (PMC).
- */
-static unsigned long read_pmc(int idx)
-{
-	unsigned long val;
-
-	switch (idx) {
-	case 1:
-		val = mfspr(SPRN_PMC1);
-		break;
-	case 2:
-		val = mfspr(SPRN_PMC2);
-		break;
-	case 3:
-		val = mfspr(SPRN_PMC3);
-		break;
-	case 4:
-		val = mfspr(SPRN_PMC4);
-		break;
-	case 5:
-		val = mfspr(SPRN_PMC5);
-		break;
-	case 6:
-		val = mfspr(SPRN_PMC6);
-		break;
-#ifdef CONFIG_PPC64
-	case 7:
-		val = mfspr(SPRN_PMC7);
-		break;
-	case 8:
-		val = mfspr(SPRN_PMC8);
-		break;
-#endif /* CONFIG_PPC64 */
-	default:
-		printk(KERN_ERR "oops trying to read PMC%d\n", idx);
-		val = 0;
-	}
-	return val;
-}
-
-/*
- * Write one PMC.
- */
-static void write_pmc(int idx, unsigned long val)
-{
-	switch (idx) {
-	case 1:
-		mtspr(SPRN_PMC1, val);
-		break;
-	case 2:
-		mtspr(SPRN_PMC2, val);
-		break;
-	case 3:
-		mtspr(SPRN_PMC3, val);
-		break;
-	case 4:
-		mtspr(SPRN_PMC4, val);
-		break;
-	case 5:
-		mtspr(SPRN_PMC5, val);
-		break;
-	case 6:
-		mtspr(SPRN_PMC6, val);
-		break;
-#ifdef CONFIG_PPC64
-	case 7:
-		mtspr(SPRN_PMC7, val);
-		break;
-	case 8:
-		mtspr(SPRN_PMC8, val);
-		break;
-#endif /* CONFIG_PPC64 */
-	default:
-		printk(KERN_ERR "oops trying to write PMC%d\n", idx);
-	}
-}
-
-/*
- * Check if a set of events can all go on the PMU at once.
- * If they can't, this will look at alternative codes for the events
- * and see if any combination of alternative codes is feasible.
- * The feasible set is returned in event[].
- */
-static int power_check_constraints(u64 event[], unsigned int cflags[],
-				   int n_ev)
-{
-	unsigned long mask, value, nv;
-	u64 alternatives[MAX_HWCOUNTERS][MAX_EVENT_ALTERNATIVES];
-	unsigned long amasks[MAX_HWCOUNTERS][MAX_EVENT_ALTERNATIVES];
-	unsigned long avalues[MAX_HWCOUNTERS][MAX_EVENT_ALTERNATIVES];
-	unsigned long smasks[MAX_HWCOUNTERS], svalues[MAX_HWCOUNTERS];
-	int n_alt[MAX_HWCOUNTERS], choice[MAX_HWCOUNTERS];
-	int i, j;
-	unsigned long addf = ppmu->add_fields;
-	unsigned long tadd = ppmu->test_adder;
-
-	if (n_ev > ppmu->n_counter)
-		return -1;
-
-	/* First see if the events will go on as-is */
-	for (i = 0; i < n_ev; ++i) {
-		if ((cflags[i] & PPMU_LIMITED_PMC_REQD)
-		    && !ppmu->limited_pmc_event(event[i])) {
-			ppmu->get_alternatives(event[i], cflags[i],
-					       alternatives[i]);
-			event[i] = alternatives[i][0];
-		}
-		if (ppmu->get_constraint(event[i], &amasks[i][0],
-					 &avalues[i][0]))
-			return -1;
-	}
-	value = mask = 0;
-	for (i = 0; i < n_ev; ++i) {
-		nv = (value | avalues[i][0]) + (value & avalues[i][0] & addf);
-		if ((((nv + tadd) ^ value) & mask) != 0 ||
-		    (((nv + tadd) ^ avalues[i][0]) & amasks[i][0]) != 0)
-			break;
-		value = nv;
-		mask |= amasks[i][0];
-	}
-	if (i == n_ev)
-		return 0;	/* all OK */
-
-	/* doesn't work, gather alternatives... */
-	if (!ppmu->get_alternatives)
-		return -1;
-	for (i = 0; i < n_ev; ++i) {
-		choice[i] = 0;
-		n_alt[i] = ppmu->get_alternatives(event[i], cflags[i],
-						  alternatives[i]);
-		for (j = 1; j < n_alt[i]; ++j)
-			ppmu->get_constraint(alternatives[i][j],
-					     &amasks[i][j], &avalues[i][j]);
-	}
-
-	/* enumerate all possibilities and see if any will work */
-	i = 0;
-	j = -1;
-	value = mask = nv = 0;
-	while (i < n_ev) {
-		if (j >= 0) {
-			/* we're backtracking, restore context */
-			value = svalues[i];
-			mask = smasks[i];
-			j = choice[i];
-		}
-		/*
-		 * See if any alternative k for event i,
-		 * where k > j, will satisfy the constraints.
-		 */
-		while (++j < n_alt[i]) {
-			nv = (value | avalues[i][j]) +
-				(value & avalues[i][j] & addf);
-			if ((((nv + tadd) ^ value) & mask) == 0 &&
-			    (((nv + tadd) ^ avalues[i][j])
-			     & amasks[i][j]) == 0)
-				break;
-		}
-		if (j >= n_alt[i]) {
-			/*
-			 * No feasible alternative, backtrack
-			 * to event i-1 and continue enumerating its
-			 * alternatives from where we got up to.
-			 */
-			if (--i < 0)
-				return -1;
-		} else {
-			/*
-			 * Found a feasible alternative for event i,
-			 * remember where we got up to with this event,
-			 * go on to the next event, and start with
-			 * the first alternative for it.
-			 */
-			choice[i] = j;
-			svalues[i] = value;
-			smasks[i] = mask;
-			value = nv;
-			mask |= amasks[i][j];
-			++i;
-			j = -1;
-		}
-	}
-
-	/* OK, we have a feasible combination, tell the caller the solution */
-	for (i = 0; i < n_ev; ++i)
-		event[i] = alternatives[i][choice[i]];
-	return 0;
-}
-
-/*
- * Check if newly-added counters have consistent settings for
- * exclude_{user,kernel,hv} with each other and any previously
- * added counters.
- */
-static int check_excludes(struct perf_counter **ctrs, unsigned int cflags[],
-			  int n_prev, int n_new)
-{
-	int eu = 0, ek = 0, eh = 0;
-	int i, n, first;
-	struct perf_counter *counter;
-
-	n = n_prev + n_new;
-	if (n <= 1)
-		return 0;
-
-	first = 1;
-	for (i = 0; i < n; ++i) {
-		if (cflags[i] & PPMU_LIMITED_PMC_OK) {
-			cflags[i] &= ~PPMU_LIMITED_PMC_REQD;
-			continue;
-		}
-		counter = ctrs[i];
-		if (first) {
-			eu = counter->attr.exclude_user;
-			ek = counter->attr.exclude_kernel;
-			eh = counter->attr.exclude_hv;
-			first = 0;
-		} else if (counter->attr.exclude_user != eu ||
-			   counter->attr.exclude_kernel != ek ||
-			   counter->attr.exclude_hv != eh) {
-			return -EAGAIN;
-		}
-	}
-
-	if (eu || ek || eh)
-		for (i = 0; i < n; ++i)
-			if (cflags[i] & PPMU_LIMITED_PMC_OK)
-				cflags[i] |= PPMU_LIMITED_PMC_REQD;
-
-	return 0;
-}
-
-static void power_pmu_read(struct perf_counter *counter)
-{
-	s64 val, delta, prev;
-
-	if (!counter->hw.idx)
-		return;
-	/*
-	 * Performance monitor interrupts come even when interrupts
-	 * are soft-disabled, as long as interrupts are hard-enabled.
-	 * Therefore we treat them like NMIs.
-	 */
-	do {
-		prev = atomic64_read(&counter->hw.prev_count);
-		barrier();
-		val = read_pmc(counter->hw.idx);
-	} while (atomic64_cmpxchg(&counter->hw.prev_count, prev, val) != prev);
-
-	/* The counters are only 32 bits wide */
-	delta = (val - prev) & 0xfffffffful;
-	atomic64_add(delta, &counter->count);
-	atomic64_sub(delta, &counter->hw.period_left);
-}
-
-/*
- * On some machines, PMC5 and PMC6 can't be written, don't respect
- * the freeze conditions, and don't generate interrupts.  This tells
- * us if `counter' is using such a PMC.
- */
-static int is_limited_pmc(int pmcnum)
-{
-	return (ppmu->flags & PPMU_LIMITED_PMC5_6)
-		&& (pmcnum == 5 || pmcnum == 6);
-}
-
-static void freeze_limited_counters(struct cpu_hw_counters *cpuhw,
-				    unsigned long pmc5, unsigned long pmc6)
-{
-	struct perf_counter *counter;
-	u64 val, prev, delta;
-	int i;
-
-	for (i = 0; i < cpuhw->n_limited; ++i) {
-		counter = cpuhw->limited_counter[i];
-		if (!counter->hw.idx)
-			continue;
-		val = (counter->hw.idx == 5) ? pmc5 : pmc6;
-		prev = atomic64_read(&counter->hw.prev_count);
-		counter->hw.idx = 0;
-		delta = (val - prev) & 0xfffffffful;
-		atomic64_add(delta, &counter->count);
-	}
-}
-
-static void thaw_limited_counters(struct cpu_hw_counters *cpuhw,
-				  unsigned long pmc5, unsigned long pmc6)
-{
-	struct perf_counter *counter;
-	u64 val;
-	int i;
-
-	for (i = 0; i < cpuhw->n_limited; ++i) {
-		counter = cpuhw->limited_counter[i];
-		counter->hw.idx = cpuhw->limited_hwidx[i];
-		val = (counter->hw.idx == 5) ? pmc5 : pmc6;
-		atomic64_set(&counter->hw.prev_count, val);
-		perf_counter_update_userpage(counter);
-	}
-}
-
-/*
- * Since limited counters don't respect the freeze conditions, we
- * have to read them immediately after freezing or unfreezing the
- * other counters.  We try to keep the values from the limited
- * counters as consistent as possible by keeping the delay (in
- * cycles and instructions) between freezing/unfreezing and reading
- * the limited counters as small and consistent as possible.
- * Therefore, if any limited counters are in use, we read them
- * both, and always in the same order, to minimize variability,
- * and do it inside the same asm that writes MMCR0.
- */
-static void write_mmcr0(struct cpu_hw_counters *cpuhw, unsigned long mmcr0)
-{
-	unsigned long pmc5, pmc6;
-
-	if (!cpuhw->n_limited) {
-		mtspr(SPRN_MMCR0, mmcr0);
-		return;
-	}
-
-	/*
-	 * Write MMCR0, then read PMC5 and PMC6 immediately.
-	 * To ensure we don't get a performance monitor interrupt
-	 * between writing MMCR0 and freezing/thawing the limited
-	 * counters, we first write MMCR0 with the counter overflow
-	 * interrupt enable bits turned off.
-	 */
-	asm volatile("mtspr %3,%2; mfspr %0,%4; mfspr %1,%5"
-		     : "=&r" (pmc5), "=&r" (pmc6)
-		     : "r" (mmcr0 & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)),
-		       "i" (SPRN_MMCR0),
-		       "i" (SPRN_PMC5), "i" (SPRN_PMC6));
-
-	if (mmcr0 & MMCR0_FC)
-		freeze_limited_counters(cpuhw, pmc5, pmc6);
-	else
-		thaw_limited_counters(cpuhw, pmc5, pmc6);
-
-	/*
-	 * Write the full MMCR0 including the counter overflow interrupt
-	 * enable bits, if necessary.
-	 */
-	if (mmcr0 & (MMCR0_PMC1CE | MMCR0_PMCjCE))
-		mtspr(SPRN_MMCR0, mmcr0);
-}
-
-/*
- * Disable all counters to prevent PMU interrupts and to allow
- * counters to be added or removed.
- */
-void hw_perf_disable(void)
-{
-	struct cpu_hw_counters *cpuhw;
-	unsigned long flags;
-
-	if (!ppmu)
-		return;
-	local_irq_save(flags);
-	cpuhw = &__get_cpu_var(cpu_hw_counters);
-
-	if (!cpuhw->disabled) {
-		cpuhw->disabled = 1;
-		cpuhw->n_added = 0;
-
-		/*
-		 * Check if we ever enabled the PMU on this cpu.
-		 */
-		if (!cpuhw->pmcs_enabled) {
-			if (ppc_md.enable_pmcs)
-				ppc_md.enable_pmcs();
-			cpuhw->pmcs_enabled = 1;
-		}
-
-		/*
-		 * Disable instruction sampling if it was enabled
-		 */
-		if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) {
-			mtspr(SPRN_MMCRA,
-			      cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
-			mb();
-		}
-
-		/*
-		 * Set the 'freeze counters' bit.
-		 * The barrier is to make sure the mtspr has been
-		 * executed and the PMU has frozen the counters
-		 * before we return.
-		 */
-		write_mmcr0(cpuhw, mfspr(SPRN_MMCR0) | MMCR0_FC);
-		mb();
-	}
-	local_irq_restore(flags);
-}
-
-/*
- * Re-enable all counters if disable == 0.
- * If we were previously disabled and counters were added, then
- * put the new config on the PMU.
- */
-void hw_perf_enable(void)
-{
-	struct perf_counter *counter;
-	struct cpu_hw_counters *cpuhw;
-	unsigned long flags;
-	long i;
-	unsigned long val;
-	s64 left;
-	unsigned int hwc_index[MAX_HWCOUNTERS];
-	int n_lim;
-	int idx;
-
-	if (!ppmu)
-		return;
-	local_irq_save(flags);
-	cpuhw = &__get_cpu_var(cpu_hw_counters);
-	if (!cpuhw->disabled) {
-		local_irq_restore(flags);
-		return;
-	}
-	cpuhw->disabled = 0;
-
-	/*
-	 * If we didn't change anything, or only removed counters,
-	 * no need to recalculate MMCR* settings and reset the PMCs.
-	 * Just reenable the PMU with the current MMCR* settings
-	 * (possibly updated for removal of counters).
-	 */
-	if (!cpuhw->n_added) {
-		mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
-		mtspr(SPRN_MMCR1, cpuhw->mmcr[1]);
-		if (cpuhw->n_counters == 0)
-			perf_set_pmu_inuse(0);
-		goto out_enable;
-	}
-
-	/*
-	 * Compute MMCR* values for the new set of counters
-	 */
-	if (ppmu->compute_mmcr(cpuhw->events, cpuhw->n_counters, hwc_index,
-			       cpuhw->mmcr)) {
-		/* shouldn't ever get here */
-		printk(KERN_ERR "oops compute_mmcr failed\n");
-		goto out;
-	}
-
-	/*
-	 * Add in MMCR0 freeze bits corresponding to the
-	 * attr.exclude_* bits for the first counter.
-	 * We have already checked that all counters have the
-	 * same values for these bits as the first counter.
-	 */
-	counter = cpuhw->counter[0];
-	if (counter->attr.exclude_user)
-		cpuhw->mmcr[0] |= MMCR0_FCP;
-	if (counter->attr.exclude_kernel)
-		cpuhw->mmcr[0] |= freeze_counters_kernel;
-	if (counter->attr.exclude_hv)
-		cpuhw->mmcr[0] |= MMCR0_FCHV;
-
-	/*
-	 * Write the new configuration to MMCR* with the freeze
-	 * bit set and set the hardware counters to their initial values.
-	 * Then unfreeze the counters.
-	 */
-	perf_set_pmu_inuse(1);
-	mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
-	mtspr(SPRN_MMCR1, cpuhw->mmcr[1]);
-	mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE))
-				| MMCR0_FC);
-
-	/*
-	 * Read off any pre-existing counters that need to move
-	 * to another PMC.
-	 */
-	for (i = 0; i < cpuhw->n_counters; ++i) {
-		counter = cpuhw->counter[i];
-		if (counter->hw.idx && counter->hw.idx != hwc_index[i] + 1) {
-			power_pmu_read(counter);
-			write_pmc(counter->hw.idx, 0);
-			counter->hw.idx = 0;
-		}
-	}
-
-	/*
-	 * Initialize the PMCs for all the new and moved counters.
-	 */
-	cpuhw->n_limited = n_lim = 0;
-	for (i = 0; i < cpuhw->n_counters; ++i) {
-		counter = cpuhw->counter[i];
-		if (counter->hw.idx)
-			continue;
-		idx = hwc_index[i] + 1;
-		if (is_limited_pmc(idx)) {
-			cpuhw->limited_counter[n_lim] = counter;
-			cpuhw->limited_hwidx[n_lim] = idx;
-			++n_lim;
-			continue;
-		}
-		val = 0;
-		if (counter->hw.sample_period) {
-			left = atomic64_read(&counter->hw.period_left);
-			if (left < 0x80000000L)
-				val = 0x80000000L - left;
-		}
-		atomic64_set(&counter->hw.prev_count, val);
-		counter->hw.idx = idx;
-		write_pmc(idx, val);
-		perf_counter_update_userpage(counter);
-	}
-	cpuhw->n_limited = n_lim;
-	cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
-
- out_enable:
-	mb();
-	write_mmcr0(cpuhw, cpuhw->mmcr[0]);
-
-	/*
-	 * Enable instruction sampling if necessary
-	 */
-	if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) {
-		mb();
-		mtspr(SPRN_MMCRA, cpuhw->mmcr[2]);
-	}
-
- out:
-	local_irq_restore(flags);
-}
-
-static int collect_events(struct perf_counter *group, int max_count,
-			  struct perf_counter *ctrs[], u64 *events,
-			  unsigned int *flags)
-{
-	int n = 0;
-	struct perf_counter *counter;
-
-	if (!is_software_counter(group)) {
-		if (n >= max_count)
-			return -1;
-		ctrs[n] = group;
-		flags[n] = group->hw.counter_base;
-		events[n++] = group->hw.config;
-	}
-	list_for_each_entry(counter, &group->sibling_list, list_entry) {
-		if (!is_software_counter(counter) &&
-		    counter->state != PERF_COUNTER_STATE_OFF) {
-			if (n >= max_count)
-				return -1;
-			ctrs[n] = counter;
-			flags[n] = counter->hw.counter_base;
-			events[n++] = counter->hw.config;
-		}
-	}
-	return n;
-}
-
-static void counter_sched_in(struct perf_counter *counter, int cpu)
-{
-	counter->state = PERF_COUNTER_STATE_ACTIVE;
-	counter->oncpu = cpu;
-	counter->tstamp_running += counter->ctx->time - counter->tstamp_stopped;
-	if (is_software_counter(counter))
-		counter->pmu->enable(counter);
-}
-
-/*
- * Called to enable a whole group of counters.
- * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
- * Assumes the caller has disabled interrupts and has
- * frozen the PMU with hw_perf_save_disable.
- */
-int hw_perf_group_sched_in(struct perf_counter *group_leader,
-	       struct perf_cpu_context *cpuctx,
-	       struct perf_counter_context *ctx, int cpu)
-{
-	struct cpu_hw_counters *cpuhw;
-	long i, n, n0;
-	struct perf_counter *sub;
-
-	if (!ppmu)
-		return 0;
-	cpuhw = &__get_cpu_var(cpu_hw_counters);
-	n0 = cpuhw->n_counters;
-	n = collect_events(group_leader, ppmu->n_counter - n0,
-			   &cpuhw->counter[n0], &cpuhw->events[n0],
-			   &cpuhw->flags[n0]);
-	if (n < 0)
-		return -EAGAIN;
-	if (check_excludes(cpuhw->counter, cpuhw->flags, n0, n))
-		return -EAGAIN;
-	i = power_check_constraints(cpuhw->events, cpuhw->flags, n + n0);
-	if (i < 0)
-		return -EAGAIN;
-	cpuhw->n_counters = n0 + n;
-	cpuhw->n_added += n;
-
-	/*
-	 * OK, this group can go on; update counter states etc.,
-	 * and enable any software counters
-	 */
-	for (i = n0; i < n0 + n; ++i)
-		cpuhw->counter[i]->hw.config = cpuhw->events[i];
-	cpuctx->active_oncpu += n;
-	n = 1;
-	counter_sched_in(group_leader, cpu);
-	list_for_each_entry(sub, &group_leader->sibling_list, list_entry) {
-		if (sub->state != PERF_COUNTER_STATE_OFF) {
-			counter_sched_in(sub, cpu);
-			++n;
-		}
-	}
-	ctx->nr_active += n;
-
-	return 1;
-}
-
-/*
- * Add a counter to the PMU.
- * If all counters are not already frozen, then we disable and
- * re-enable the PMU in order to get hw_perf_enable to do the
- * actual work of reconfiguring the PMU.
- */
-static int power_pmu_enable(struct perf_counter *counter)
-{
-	struct cpu_hw_counters *cpuhw;
-	unsigned long flags;
-	int n0;
-	int ret = -EAGAIN;
-
-	local_irq_save(flags);
-	perf_disable();
-
-	/*
-	 * Add the counter to the list (if there is room)
-	 * and check whether the total set is still feasible.
-	 */
-	cpuhw = &__get_cpu_var(cpu_hw_counters);
-	n0 = cpuhw->n_counters;
-	if (n0 >= ppmu->n_counter)
-		goto out;
-	cpuhw->counter[n0] = counter;
-	cpuhw->events[n0] = counter->hw.config;
-	cpuhw->flags[n0] = counter->hw.counter_base;
-	if (check_excludes(cpuhw->counter, cpuhw->flags, n0, 1))
-		goto out;
-	if (power_check_constraints(cpuhw->events, cpuhw->flags, n0 + 1))
-		goto out;
-
-	counter->hw.config = cpuhw->events[n0];
-	++cpuhw->n_counters;
-	++cpuhw->n_added;
-
-	ret = 0;
- out:
-	perf_enable();
-	local_irq_restore(flags);
-	return ret;
-}
-
-/*
- * Remove a counter from the PMU.
- */
-static void power_pmu_disable(struct perf_counter *counter)
-{
-	struct cpu_hw_counters *cpuhw;
-	long i;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	perf_disable();
-
-	power_pmu_read(counter);
-
-	cpuhw = &__get_cpu_var(cpu_hw_counters);
-	for (i = 0; i < cpuhw->n_counters; ++i) {
-		if (counter == cpuhw->counter[i]) {
-			while (++i < cpuhw->n_counters)
-				cpuhw->counter[i-1] = cpuhw->counter[i];
-			--cpuhw->n_counters;
-			ppmu->disable_pmc(counter->hw.idx - 1, cpuhw->mmcr);
-			if (counter->hw.idx) {
-				write_pmc(counter->hw.idx, 0);
-				counter->hw.idx = 0;
-			}
-			perf_counter_update_userpage(counter);
-			break;
-		}
-	}
-	for (i = 0; i < cpuhw->n_limited; ++i)
-		if (counter == cpuhw->limited_counter[i])
-			break;
-	if (i < cpuhw->n_limited) {
-		while (++i < cpuhw->n_limited) {
-			cpuhw->limited_counter[i-1] = cpuhw->limited_counter[i];
-			cpuhw->limited_hwidx[i-1] = cpuhw->limited_hwidx[i];
-		}
-		--cpuhw->n_limited;
-	}
-	if (cpuhw->n_counters == 0) {
-		/* disable exceptions if no counters are running */
-		cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE);
-	}
-
-	perf_enable();
-	local_irq_restore(flags);
-}
-
-/*
- * Re-enable interrupts on a counter after they were throttled
- * because they were coming too fast.
- */
-static void power_pmu_unthrottle(struct perf_counter *counter)
-{
-	s64 val, left;
-	unsigned long flags;
-
-	if (!counter->hw.idx || !counter->hw.sample_period)
-		return;
-	local_irq_save(flags);
-	perf_disable();
-	power_pmu_read(counter);
-	left = counter->hw.sample_period;
-	counter->hw.last_period = left;
-	val = 0;
-	if (left < 0x80000000L)
-		val = 0x80000000L - left;
-	write_pmc(counter->hw.idx, val);
-	atomic64_set(&counter->hw.prev_count, val);
-	atomic64_set(&counter->hw.period_left, left);
-	perf_counter_update_userpage(counter);
-	perf_enable();
-	local_irq_restore(flags);
-}
-
-struct pmu power_pmu = {
-	.enable		= power_pmu_enable,
-	.disable	= power_pmu_disable,
-	.read		= power_pmu_read,
-	.unthrottle	= power_pmu_unthrottle,
-};
-
-/*
- * Return 1 if we might be able to put counter on a limited PMC,
- * or 0 if not.
- * A counter can only go on a limited PMC if it counts something
- * that a limited PMC can count, doesn't require interrupts, and
- * doesn't exclude any processor mode.
- */
-static int can_go_on_limited_pmc(struct perf_counter *counter, u64 ev,
-				 unsigned int flags)
-{
-	int n;
-	u64 alt[MAX_EVENT_ALTERNATIVES];
-
-	if (counter->attr.exclude_user
-	    || counter->attr.exclude_kernel
-	    || counter->attr.exclude_hv
-	    || counter->attr.sample_period)
-		return 0;
-
-	if (ppmu->limited_pmc_event(ev))
-		return 1;
-
-	/*
-	 * The requested event isn't on a limited PMC already;
-	 * see if any alternative code goes on a limited PMC.
-	 */
-	if (!ppmu->get_alternatives)
-		return 0;
-
-	flags |= PPMU_LIMITED_PMC_OK | PPMU_LIMITED_PMC_REQD;
-	n = ppmu->get_alternatives(ev, flags, alt);
-
-	return n > 0;
-}
-
-/*
- * Find an alternative event that goes on a normal PMC, if possible,
- * and return the event code, or 0 if there is no such alternative.
- * (Note: event code 0 is "don't count" on all machines.)
- */
-static u64 normal_pmc_alternative(u64 ev, unsigned long flags)
-{
-	u64 alt[MAX_EVENT_ALTERNATIVES];
-	int n;
-
-	flags &= ~(PPMU_LIMITED_PMC_OK | PPMU_LIMITED_PMC_REQD);
-	n = ppmu->get_alternatives(ev, flags, alt);
-	if (!n)
-		return 0;
-	return alt[0];
-}
-
-/* Number of perf_counters counting hardware events */
-static atomic_t num_counters;
-/* Used to avoid races in calling reserve/release_pmc_hardware */
-static DEFINE_MUTEX(pmc_reserve_mutex);
-
-/*
- * Release the PMU if this is the last perf_counter.
- */
-static void hw_perf_counter_destroy(struct perf_counter *counter)
-{
-	if (!atomic_add_unless(&num_counters, -1, 1)) {
-		mutex_lock(&pmc_reserve_mutex);
-		if (atomic_dec_return(&num_counters) == 0)
-			release_pmc_hardware();
-		mutex_unlock(&pmc_reserve_mutex);
-	}
-}
-
-/*
- * Translate a generic cache event config to a raw event code.
- */
-static int hw_perf_cache_event(u64 config, u64 *eventp)
-{
-	unsigned long type, op, result;
-	int ev;
-
-	if (!ppmu->cache_events)
-		return -EINVAL;
-
-	/* unpack config */
-	type = config & 0xff;
-	op = (config >> 8) & 0xff;
-	result = (config >> 16) & 0xff;
-
-	if (type >= PERF_COUNT_HW_CACHE_MAX ||
-	    op >= PERF_COUNT_HW_CACHE_OP_MAX ||
-	    result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
-		return -EINVAL;
-
-	ev = (*ppmu->cache_events)[type][op][result];
-	if (ev == 0)
-		return -EOPNOTSUPP;
-	if (ev == -1)
-		return -EINVAL;
-	*eventp = ev;
-	return 0;
-}
-
-const struct pmu *hw_perf_counter_init(struct perf_counter *counter)
-{
-	u64 ev;
-	unsigned long flags;
-	struct perf_counter *ctrs[MAX_HWCOUNTERS];
-	u64 events[MAX_HWCOUNTERS];
-	unsigned int cflags[MAX_HWCOUNTERS];
-	int n;
-	int err;
-
-	if (!ppmu)
-		return ERR_PTR(-ENXIO);
-	switch (counter->attr.type) {
-	case PERF_TYPE_HARDWARE:
-		ev = counter->attr.config;
-		if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0)
-			return ERR_PTR(-EOPNOTSUPP);
-		ev = ppmu->generic_events[ev];
-		break;
-	case PERF_TYPE_HW_CACHE:
-		err = hw_perf_cache_event(counter->attr.config, &ev);
-		if (err)
-			return ERR_PTR(err);
-		break;
-	case PERF_TYPE_RAW:
-		ev = counter->attr.config;
-		break;
-	default:
-		return ERR_PTR(-EINVAL);
-	}
-	counter->hw.config_base = ev;
-	counter->hw.idx = 0;
-
-	/*
-	 * If we are not running on a hypervisor, force the
-	 * exclude_hv bit to 0 so that we don't care what
-	 * the user set it to.
-	 */
-	if (!firmware_has_feature(FW_FEATURE_LPAR))
-		counter->attr.exclude_hv = 0;
-
-	/*
-	 * If this is a per-task counter, then we can use
-	 * PM_RUN_* events interchangeably with their non RUN_*
-	 * equivalents, e.g. PM_RUN_CYC instead of PM_CYC.
-	 * XXX we should check if the task is an idle task.
-	 */
-	flags = 0;
-	if (counter->ctx->task)
-		flags |= PPMU_ONLY_COUNT_RUN;
-
-	/*
-	 * If this machine has limited counters, check whether this
-	 * event could go on a limited counter.
-	 */
-	if (ppmu->flags & PPMU_LIMITED_PMC5_6) {
-		if (can_go_on_limited_pmc(counter, ev, flags)) {
-			flags |= PPMU_LIMITED_PMC_OK;
-		} else if (ppmu->limited_pmc_event(ev)) {
-			/*
-			 * The requested event is on a limited PMC,
-			 * but we can't use a limited PMC; see if any
-			 * alternative goes on a normal PMC.
-			 */
-			ev = normal_pmc_alternative(ev, flags);
-			if (!ev)
-				return ERR_PTR(-EINVAL);
-		}
-	}
-
-	/*
-	 * If this is in a group, check if it can go on with all the
-	 * other hardware counters in the group.  We assume the counter
-	 * hasn't been linked into its leader's sibling list at this point.
-	 */
-	n = 0;
-	if (counter->group_leader != counter) {
-		n = collect_events(counter->group_leader, ppmu->n_counter - 1,
-				   ctrs, events, cflags);
-		if (n < 0)
-			return ERR_PTR(-EINVAL);
-	}
-	events[n] = ev;
-	ctrs[n] = counter;
-	cflags[n] = flags;
-	if (check_excludes(ctrs, cflags, n, 1))
-		return ERR_PTR(-EINVAL);
-	if (power_check_constraints(events, cflags, n + 1))
-		return ERR_PTR(-EINVAL);
-
-	counter->hw.config = events[n];
-	counter->hw.counter_base = cflags[n];
-	counter->hw.last_period = counter->hw.sample_period;
-	atomic64_set(&counter->hw.period_left, counter->hw.last_period);
-
-	/*
-	 * See if we need to reserve the PMU.
-	 * If no counters are currently in use, then we have to take a
-	 * mutex to ensure that we don't race with another task doing
-	 * reserve_pmc_hardware or release_pmc_hardware.
-	 */
-	err = 0;
-	if (!atomic_inc_not_zero(&num_counters)) {
-		mutex_lock(&pmc_reserve_mutex);
-		if (atomic_read(&num_counters) == 0 &&
-		    reserve_pmc_hardware(perf_counter_interrupt))
-			err = -EBUSY;
-		else
-			atomic_inc(&num_counters);
-		mutex_unlock(&pmc_reserve_mutex);
-	}
-	counter->destroy = hw_perf_counter_destroy;
-
-	if (err)
-		return ERR_PTR(err);
-	return &power_pmu;
-}
-
-/*
- * A counter has overflowed; update its count and record
- * things if requested.  Note that interrupts are hard-disabled
- * here so there is no possibility of being interrupted.
- */
-static void record_and_restart(struct perf_counter *counter, unsigned long val,
-			       struct pt_regs *regs, int nmi)
-{
-	u64 period = counter->hw.sample_period;
-	s64 prev, delta, left;
-	int record = 0;
-
-	/* we don't have to worry about interrupts here */
-	prev = atomic64_read(&counter->hw.prev_count);
-	delta = (val - prev) & 0xfffffffful;
-	atomic64_add(delta, &counter->count);
-
-	/*
-	 * See if the total period for this counter has expired,
-	 * and update for the next period.
-	 */
-	val = 0;
-	left = atomic64_read(&counter->hw.period_left) - delta;
-	if (period) {
-		if (left <= 0) {
-			left += period;
-			if (left <= 0)
-				left = period;
-			record = 1;
-		}
-		if (left < 0x80000000LL)
-			val = 0x80000000LL - left;
-	}
-
-	/*
-	 * Finally record data if requested.
-	 */
-	if (record) {
-		struct perf_sample_data data = {
-			.regs	= regs,
-			.addr	= 0,
-			.period	= counter->hw.last_period,
-		};
-
-		if (counter->attr.sample_type & PERF_SAMPLE_ADDR)
-			perf_get_data_addr(regs, &data.addr);
-
-		if (perf_counter_overflow(counter, nmi, &data)) {
-			/*
-			 * Interrupts are coming too fast - throttle them
-			 * by setting the counter to 0, so it will be
-			 * at least 2^30 cycles until the next interrupt
-			 * (assuming each counter counts at most 2 counts
-			 * per cycle).
-			 */
-			val = 0;
-			left = ~0ULL >> 1;
-		}
-	}
-
-	write_pmc(counter->hw.idx, val);
-	atomic64_set(&counter->hw.prev_count, val);
-	atomic64_set(&counter->hw.period_left, left);
-	perf_counter_update_userpage(counter);
-}
-
-/*
- * Called from generic code to get the misc flags (i.e. processor mode)
- * for an event.
- */
-unsigned long perf_misc_flags(struct pt_regs *regs)
-{
-	u32 flags = perf_get_misc_flags(regs);
-
-	if (flags)
-		return flags;
-	return user_mode(regs) ? PERF_EVENT_MISC_USER :
-		PERF_EVENT_MISC_KERNEL;
-}
-
-/*
- * Called from generic code to get the instruction pointer
- * for an event.
- */
-unsigned long perf_instruction_pointer(struct pt_regs *regs)
-{
-	unsigned long ip;
-
-	if (TRAP(regs) != 0xf00)
-		return regs->nip;	/* not a PMU interrupt */
-
-	ip = mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
-	return ip;
-}
-
-/*
- * Performance monitor interrupt stuff
- */
-static void perf_counter_interrupt(struct pt_regs *regs)
-{
-	int i;
-	struct cpu_hw_counters *cpuhw = &__get_cpu_var(cpu_hw_counters);
-	struct perf_counter *counter;
-	unsigned long val;
-	int found = 0;
-	int nmi;
-
-	if (cpuhw->n_limited)
-		freeze_limited_counters(cpuhw, mfspr(SPRN_PMC5),
-					mfspr(SPRN_PMC6));
-
-	perf_read_regs(regs);
-
-	nmi = perf_intr_is_nmi(regs);
-	if (nmi)
-		nmi_enter();
-	else
-		irq_enter();
-
-	for (i = 0; i < cpuhw->n_counters; ++i) {
-		counter = cpuhw->counter[i];
-		if (!counter->hw.idx || is_limited_pmc(counter->hw.idx))
-			continue;
-		val = read_pmc(counter->hw.idx);
-		if ((int)val < 0) {
-			/* counter has overflowed */
-			found = 1;
-			record_and_restart(counter, val, regs, nmi);
-		}
-	}
-
-	/*
-	 * In case we didn't find and reset the counter that caused
-	 * the interrupt, scan all counters and reset any that are
-	 * negative, to avoid getting continual interrupts.
-	 * Any that we processed in the previous loop will not be negative.
-	 */
-	if (!found) {
-		for (i = 0; i < ppmu->n_counter; ++i) {
-			if (is_limited_pmc(i + 1))
-				continue;
-			val = read_pmc(i + 1);
-			if ((int)val < 0)
-				write_pmc(i + 1, 0);
-		}
-	}
-
-	/*
-	 * Reset MMCR0 to its normal value.  This will set PMXE and
-	 * clear FC (freeze counters) and PMAO (perf mon alert occurred)
-	 * and thus allow interrupts to occur again.
-	 * XXX might want to use MSR.PM to keep the counters frozen until
-	 * we get back out of this interrupt.
-	 */
-	write_mmcr0(cpuhw, cpuhw->mmcr[0]);
-
-	if (nmi)
-		nmi_exit();
-	else
-		irq_exit();
-}
-
-void hw_perf_counter_setup(int cpu)
-{
-	struct cpu_hw_counters *cpuhw = &per_cpu(cpu_hw_counters, cpu);
-
-	if (!ppmu)
-		return;
-	memset(cpuhw, 0, sizeof(*cpuhw));
-	cpuhw->mmcr[0] = MMCR0_FC;
-}
-
-int register_power_pmu(struct power_pmu *pmu)
-{
-	if (ppmu)
-		return -EBUSY;		/* something's already registered */
-
-	ppmu = pmu;
-	pr_info("%s performance monitor hardware support registered\n",
-		pmu->name);
-
-#ifdef MSR_HV
-	/*
-	 * Use FCHV to ignore kernel events if MSR.HV is set.
-	 */
-	if (mfmsr() & MSR_HV)
-		freeze_counters_kernel = MMCR0_FCHV;
-#endif /* CONFIG_PPC64 */
-
-	return 0;
-}
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
new file mode 100644
index 0000000..197b7d9
--- /dev/null
+++ b/arch/powerpc/kernel/perf_event.c
@@ -0,0 +1,1315 @@
+/*
+ * Performance event support - powerpc architecture code
+ *
+ * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/hardirq.h>
+#include <asm/reg.h>
+#include <asm/pmc.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
+#include <asm/ptrace.h>
+
+struct cpu_hw_events {
+	int n_events;
+	int n_percpu;
+	int disabled;
+	int n_added;
+	int n_limited;
+	u8  pmcs_enabled;
+	struct perf_event *event[MAX_HWEVENTS];
+	u64 events[MAX_HWEVENTS];
+	unsigned int flags[MAX_HWEVENTS];
+	unsigned long mmcr[3];
+	struct perf_event *limited_event[MAX_LIMITED_HWEVENTS];
+	u8  limited_hwidx[MAX_LIMITED_HWEVENTS];
+	u64 alternatives[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
+	unsigned long amasks[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
+	unsigned long avalues[MAX_HWEVENTS][MAX_EVENT_ALTERNATIVES];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+struct power_pmu *ppmu;
+
+/*
+ * Normally, to ignore kernel events we set the FCS (freeze counters
+ * in supervisor mode) bit in MMCR0, but if the kernel runs with the
+ * hypervisor bit set in the MSR, or if we are running on a processor
+ * where the hypervisor bit is forced to 1 (as on Apple G5 processors),
+ * then we need to use the FCHV bit to ignore kernel events.
+ */
+static unsigned int freeze_events_kernel = MMCR0_FCS;
+
+/*
+ * 32-bit doesn't have MMCRA but does have an MMCR2,
+ * and a few other names are different.
+ */
+#ifdef CONFIG_PPC32
+
+#define MMCR0_FCHV		0
+#define MMCR0_PMCjCE		MMCR0_PMCnCE
+
+#define SPRN_MMCRA		SPRN_MMCR2
+#define MMCRA_SAMPLE_ENABLE	0
+
+static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
+{
+	return 0;
+}
+static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp) { }
+static inline u32 perf_get_misc_flags(struct pt_regs *regs)
+{
+	return 0;
+}
+static inline void perf_read_regs(struct pt_regs *regs) { }
+static inline int perf_intr_is_nmi(struct pt_regs *regs)
+{
+	return 0;
+}
+
+#endif /* CONFIG_PPC32 */
+
+/*
+ * Things that are specific to 64-bit implementations.
+ */
+#ifdef CONFIG_PPC64
+
+static inline unsigned long perf_ip_adjust(struct pt_regs *regs)
+{
+	unsigned long mmcra = regs->dsisr;
+
+	if ((mmcra & MMCRA_SAMPLE_ENABLE) && !(ppmu->flags & PPMU_ALT_SIPR)) {
+		unsigned long slot = (mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT;
+		if (slot > 1)
+			return 4 * (slot - 1);
+	}
+	return 0;
+}
+
+/*
+ * The user wants a data address recorded.
+ * If we're not doing instruction sampling, give them the SDAR
+ * (sampled data address).  If we are doing instruction sampling, then
+ * only give them the SDAR if it corresponds to the instruction
+ * pointed to by SIAR; this is indicated by the [POWER6_]MMCRA_SDSYNC
+ * bit in MMCRA.
+ */
+static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
+{
+	unsigned long mmcra = regs->dsisr;
+	unsigned long sdsync = (ppmu->flags & PPMU_ALT_SIPR) ?
+		POWER6_MMCRA_SDSYNC : MMCRA_SDSYNC;
+
+	if (!(mmcra & MMCRA_SAMPLE_ENABLE) || (mmcra & sdsync))
+		*addrp = mfspr(SPRN_SDAR);
+}
+
+static inline u32 perf_get_misc_flags(struct pt_regs *regs)
+{
+	unsigned long mmcra = regs->dsisr;
+
+	if (TRAP(regs) != 0xf00)
+		return 0;	/* not a PMU interrupt */
+
+	if (ppmu->flags & PPMU_ALT_SIPR) {
+		if (mmcra & POWER6_MMCRA_SIHV)
+			return PERF_RECORD_MISC_HYPERVISOR;
+		return (mmcra & POWER6_MMCRA_SIPR) ?
+			PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL;
+	}
+	if (mmcra & MMCRA_SIHV)
+		return PERF_RECORD_MISC_HYPERVISOR;
+	return (mmcra & MMCRA_SIPR) ? PERF_RECORD_MISC_USER :
+		PERF_RECORD_MISC_KERNEL;
+}
+
+/*
+ * Overload regs->dsisr to store MMCRA so we only need to read it once
+ * on each interrupt.
+ */
+static inline void perf_read_regs(struct pt_regs *regs)
+{
+	regs->dsisr = mfspr(SPRN_MMCRA);
+}
+
+/*
+ * If interrupts were soft-disabled when a PMU interrupt occurs, treat
+ * it as an NMI.
+ */
+static inline int perf_intr_is_nmi(struct pt_regs *regs)
+{
+	return !regs->softe;
+}
+
+#endif /* CONFIG_PPC64 */
+
+static void perf_event_interrupt(struct pt_regs *regs);
+
+void perf_event_print_debug(void)
+{
+}
+
+/*
+ * Read one performance monitor counter (PMC).
+ */
+static unsigned long read_pmc(int idx)
+{
+	unsigned long val;
+
+	switch (idx) {
+	case 1:
+		val = mfspr(SPRN_PMC1);
+		break;
+	case 2:
+		val = mfspr(SPRN_PMC2);
+		break;
+	case 3:
+		val = mfspr(SPRN_PMC3);
+		break;
+	case 4:
+		val = mfspr(SPRN_PMC4);
+		break;
+	case 5:
+		val = mfspr(SPRN_PMC5);
+		break;
+	case 6:
+		val = mfspr(SPRN_PMC6);
+		break;
+#ifdef CONFIG_PPC64
+	case 7:
+		val = mfspr(SPRN_PMC7);
+		break;
+	case 8:
+		val = mfspr(SPRN_PMC8);
+		break;
+#endif /* CONFIG_PPC64 */
+	default:
+		printk(KERN_ERR "oops trying to read PMC%d\n", idx);
+		val = 0;
+	}
+	return val;
+}
+
+/*
+ * Write one PMC.
+ */
+static void write_pmc(int idx, unsigned long val)
+{
+	switch (idx) {
+	case 1:
+		mtspr(SPRN_PMC1, val);
+		break;
+	case 2:
+		mtspr(SPRN_PMC2, val);
+		break;
+	case 3:
+		mtspr(SPRN_PMC3, val);
+		break;
+	case 4:
+		mtspr(SPRN_PMC4, val);
+		break;
+	case 5:
+		mtspr(SPRN_PMC5, val);
+		break;
+	case 6:
+		mtspr(SPRN_PMC6, val);
+		break;
+#ifdef CONFIG_PPC64
+	case 7:
+		mtspr(SPRN_PMC7, val);
+		break;
+	case 8:
+		mtspr(SPRN_PMC8, val);
+		break;
+#endif /* CONFIG_PPC64 */
+	default:
+		printk(KERN_ERR "oops trying to write PMC%d\n", idx);
+	}
+}
+
+/*
+ * Check if a set of events can all go on the PMU at once.
+ * If they can't, this will look at alternative codes for the events
+ * and see if any combination of alternative codes is feasible.
+ * The feasible set is returned in event_id[].
+ */
+static int power_check_constraints(struct cpu_hw_events *cpuhw,
+				   u64 event_id[], unsigned int cflags[],
+				   int n_ev)
+{
+	unsigned long mask, value, nv;
+	unsigned long smasks[MAX_HWEVENTS], svalues[MAX_HWEVENTS];
+	int n_alt[MAX_HWEVENTS], choice[MAX_HWEVENTS];
+	int i, j;
+	unsigned long addf = ppmu->add_fields;
+	unsigned long tadd = ppmu->test_adder;
+
+	if (n_ev > ppmu->n_event)
+		return -1;
+
+	/* First see if the events will go on as-is */
+	for (i = 0; i < n_ev; ++i) {
+		if ((cflags[i] & PPMU_LIMITED_PMC_REQD)
+		    && !ppmu->limited_pmc_event(event_id[i])) {
+			ppmu->get_alternatives(event_id[i], cflags[i],
+					       cpuhw->alternatives[i]);
+			event_id[i] = cpuhw->alternatives[i][0];
+		}
+		if (ppmu->get_constraint(event_id[i], &cpuhw->amasks[i][0],
+					 &cpuhw->avalues[i][0]))
+			return -1;
+	}
+	value = mask = 0;
+	for (i = 0; i < n_ev; ++i) {
+		nv = (value | cpuhw->avalues[i][0]) +
+			(value & cpuhw->avalues[i][0] & addf);
+		if ((((nv + tadd) ^ value) & mask) != 0 ||
+		    (((nv + tadd) ^ cpuhw->avalues[i][0]) &
+		     cpuhw->amasks[i][0]) != 0)
+			break;
+		value = nv;
+		mask |= cpuhw->amasks[i][0];
+	}
+	if (i == n_ev)
+		return 0;	/* all OK */
+
+	/* doesn't work, gather alternatives... */
+	if (!ppmu->get_alternatives)
+		return -1;
+	for (i = 0; i < n_ev; ++i) {
+		choice[i] = 0;
+		n_alt[i] = ppmu->get_alternatives(event_id[i], cflags[i],
+						  cpuhw->alternatives[i]);
+		for (j = 1; j < n_alt[i]; ++j)
+			ppmu->get_constraint(cpuhw->alternatives[i][j],
+					     &cpuhw->amasks[i][j],
+					     &cpuhw->avalues[i][j]);
+	}
+
+	/* enumerate all possibilities and see if any will work */
+	i = 0;
+	j = -1;
+	value = mask = nv = 0;
+	while (i < n_ev) {
+		if (j >= 0) {
+			/* we're backtracking, restore context */
+			value = svalues[i];
+			mask = smasks[i];
+			j = choice[i];
+		}
+		/*
+		 * See if any alternative k for event_id i,
+		 * where k > j, will satisfy the constraints.
+		 */
+		while (++j < n_alt[i]) {
+			nv = (value | cpuhw->avalues[i][j]) +
+				(value & cpuhw->avalues[i][j] & addf);
+			if ((((nv + tadd) ^ value) & mask) == 0 &&
+			    (((nv + tadd) ^ cpuhw->avalues[i][j])
+			     & cpuhw->amasks[i][j]) == 0)
+				break;
+		}
+		if (j >= n_alt[i]) {
+			/*
+			 * No feasible alternative, backtrack
+			 * to event_id i-1 and continue enumerating its
+			 * alternatives from where we got up to.
+			 */
+			if (--i < 0)
+				return -1;
+		} else {
+			/*
+			 * Found a feasible alternative for event_id i,
+			 * remember where we got up to with this event_id,
+			 * go on to the next event_id, and start with
+			 * the first alternative for it.
+			 */
+			choice[i] = j;
+			svalues[i] = value;
+			smasks[i] = mask;
+			value = nv;
+			mask |= cpuhw->amasks[i][j];
+			++i;
+			j = -1;
+		}
+	}
+
+	/* OK, we have a feasible combination, tell the caller the solution */
+	for (i = 0; i < n_ev; ++i)
+		event_id[i] = cpuhw->alternatives[i][choice[i]];
+	return 0;
+}
+
+/*
+ * Check if newly-added events have consistent settings for
+ * exclude_{user,kernel,hv} with each other and any previously
+ * added events.
+ */
+static int check_excludes(struct perf_event **ctrs, unsigned int cflags[],
+			  int n_prev, int n_new)
+{
+	int eu = 0, ek = 0, eh = 0;
+	int i, n, first;
+	struct perf_event *event;
+
+	n = n_prev + n_new;
+	if (n <= 1)
+		return 0;
+
+	first = 1;
+	for (i = 0; i < n; ++i) {
+		if (cflags[i] & PPMU_LIMITED_PMC_OK) {
+			cflags[i] &= ~PPMU_LIMITED_PMC_REQD;
+			continue;
+		}
+		event = ctrs[i];
+		if (first) {
+			eu = event->attr.exclude_user;
+			ek = event->attr.exclude_kernel;
+			eh = event->attr.exclude_hv;
+			first = 0;
+		} else if (event->attr.exclude_user != eu ||
+			   event->attr.exclude_kernel != ek ||
+			   event->attr.exclude_hv != eh) {
+			return -EAGAIN;
+		}
+	}
+
+	if (eu || ek || eh)
+		for (i = 0; i < n; ++i)
+			if (cflags[i] & PPMU_LIMITED_PMC_OK)
+				cflags[i] |= PPMU_LIMITED_PMC_REQD;
+
+	return 0;
+}
+
+static void power_pmu_read(struct perf_event *event)
+{
+	s64 val, delta, prev;
+
+	if (!event->hw.idx)
+		return;
+	/*
+	 * Performance monitor interrupts come even when interrupts
+	 * are soft-disabled, as long as interrupts are hard-enabled.
+	 * Therefore we treat them like NMIs.
+	 */
+	do {
+		prev = atomic64_read(&event->hw.prev_count);
+		barrier();
+		val = read_pmc(event->hw.idx);
+	} while (atomic64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
+
+	/* The counters are only 32 bits wide */
+	delta = (val - prev) & 0xfffffffful;
+	atomic64_add(delta, &event->count);
+	atomic64_sub(delta, &event->hw.period_left);
+}
+
+/*
+ * On some machines, PMC5 and PMC6 can't be written, don't respect
+ * the freeze conditions, and don't generate interrupts.  This tells
+ * us if `event' is using such a PMC.
+ */
+static int is_limited_pmc(int pmcnum)
+{
+	return (ppmu->flags & PPMU_LIMITED_PMC5_6)
+		&& (pmcnum == 5 || pmcnum == 6);
+}
+
+static void freeze_limited_events(struct cpu_hw_events *cpuhw,
+				    unsigned long pmc5, unsigned long pmc6)
+{
+	struct perf_event *event;
+	u64 val, prev, delta;
+	int i;
+
+	for (i = 0; i < cpuhw->n_limited; ++i) {
+		event = cpuhw->limited_event[i];
+		if (!event->hw.idx)
+			continue;
+		val = (event->hw.idx == 5) ? pmc5 : pmc6;
+		prev = atomic64_read(&event->hw.prev_count);
+		event->hw.idx = 0;
+		delta = (val - prev) & 0xfffffffful;
+		atomic64_add(delta, &event->count);
+	}
+}
+
+static void thaw_limited_events(struct cpu_hw_events *cpuhw,
+				  unsigned long pmc5, unsigned long pmc6)
+{
+	struct perf_event *event;
+	u64 val;
+	int i;
+
+	for (i = 0; i < cpuhw->n_limited; ++i) {
+		event = cpuhw->limited_event[i];
+		event->hw.idx = cpuhw->limited_hwidx[i];
+		val = (event->hw.idx == 5) ? pmc5 : pmc6;
+		atomic64_set(&event->hw.prev_count, val);
+		perf_event_update_userpage(event);
+	}
+}
+
+/*
+ * Since limited events don't respect the freeze conditions, we
+ * have to read them immediately after freezing or unfreezing the
+ * other events.  We try to keep the values from the limited
+ * events as consistent as possible by keeping the delay (in
+ * cycles and instructions) between freezing/unfreezing and reading
+ * the limited events as small and consistent as possible.
+ * Therefore, if any limited events are in use, we read them
+ * both, and always in the same order, to minimize variability,
+ * and do it inside the same asm that writes MMCR0.
+ */
+static void write_mmcr0(struct cpu_hw_events *cpuhw, unsigned long mmcr0)
+{
+	unsigned long pmc5, pmc6;
+
+	if (!cpuhw->n_limited) {
+		mtspr(SPRN_MMCR0, mmcr0);
+		return;
+	}
+
+	/*
+	 * Write MMCR0, then read PMC5 and PMC6 immediately.
+	 * To ensure we don't get a performance monitor interrupt
+	 * between writing MMCR0 and freezing/thawing the limited
+	 * events, we first write MMCR0 with the event overflow
+	 * interrupt enable bits turned off.
+	 */
+	asm volatile("mtspr %3,%2; mfspr %0,%4; mfspr %1,%5"
+		     : "=&r" (pmc5), "=&r" (pmc6)
+		     : "r" (mmcr0 & ~(MMCR0_PMC1CE | MMCR0_PMCjCE)),
+		       "i" (SPRN_MMCR0),
+		       "i" (SPRN_PMC5), "i" (SPRN_PMC6));
+
+	if (mmcr0 & MMCR0_FC)
+		freeze_limited_events(cpuhw, pmc5, pmc6);
+	else
+		thaw_limited_events(cpuhw, pmc5, pmc6);
+
+	/*
+	 * Write the full MMCR0 including the event overflow interrupt
+	 * enable bits, if necessary.
+	 */
+	if (mmcr0 & (MMCR0_PMC1CE | MMCR0_PMCjCE))
+		mtspr(SPRN_MMCR0, mmcr0);
+}
+
+/*
+ * Disable all events to prevent PMU interrupts and to allow
+ * events to be added or removed.
+ */
+void hw_perf_disable(void)
+{
+	struct cpu_hw_events *cpuhw;
+	unsigned long flags;
+
+	if (!ppmu)
+		return;
+	local_irq_save(flags);
+	cpuhw = &__get_cpu_var(cpu_hw_events);
+
+	if (!cpuhw->disabled) {
+		cpuhw->disabled = 1;
+		cpuhw->n_added = 0;
+
+		/*
+		 * Check if we ever enabled the PMU on this cpu.
+		 */
+		if (!cpuhw->pmcs_enabled) {
+			ppc_enable_pmcs();
+			cpuhw->pmcs_enabled = 1;
+		}
+
+		/*
+		 * Disable instruction sampling if it was enabled
+		 */
+		if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) {
+			mtspr(SPRN_MMCRA,
+			      cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
+			mb();
+		}
+
+		/*
+		 * Set the 'freeze counters' bit.
+		 * The barrier is to make sure the mtspr has been
+		 * executed and the PMU has frozen the events
+		 * before we return.
+		 */
+		write_mmcr0(cpuhw, mfspr(SPRN_MMCR0) | MMCR0_FC);
+		mb();
+	}
+	local_irq_restore(flags);
+}
+
+/*
+ * Re-enable all events if disable == 0.
+ * If we were previously disabled and events were added, then
+ * put the new config on the PMU.
+ */
+void hw_perf_enable(void)
+{
+	struct perf_event *event;
+	struct cpu_hw_events *cpuhw;
+	unsigned long flags;
+	long i;
+	unsigned long val;
+	s64 left;
+	unsigned int hwc_index[MAX_HWEVENTS];
+	int n_lim;
+	int idx;
+
+	if (!ppmu)
+		return;
+	local_irq_save(flags);
+	cpuhw = &__get_cpu_var(cpu_hw_events);
+	if (!cpuhw->disabled) {
+		local_irq_restore(flags);
+		return;
+	}
+	cpuhw->disabled = 0;
+
+	/*
+	 * If we didn't change anything, or only removed events,
+	 * no need to recalculate MMCR* settings and reset the PMCs.
+	 * Just reenable the PMU with the current MMCR* settings
+	 * (possibly updated for removal of events).
+	 */
+	if (!cpuhw->n_added) {
+		mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
+		mtspr(SPRN_MMCR1, cpuhw->mmcr[1]);
+		if (cpuhw->n_events == 0)
+			ppc_set_pmu_inuse(0);
+		goto out_enable;
+	}
+
+	/*
+	 * Compute MMCR* values for the new set of events
+	 */
+	if (ppmu->compute_mmcr(cpuhw->events, cpuhw->n_events, hwc_index,
+			       cpuhw->mmcr)) {
+		/* shouldn't ever get here */
+		printk(KERN_ERR "oops compute_mmcr failed\n");
+		goto out;
+	}
+
+	/*
+	 * Add in MMCR0 freeze bits corresponding to the
+	 * attr.exclude_* bits for the first event.
+	 * We have already checked that all events have the
+	 * same values for these bits as the first event.
+	 */
+	event = cpuhw->event[0];
+	if (event->attr.exclude_user)
+		cpuhw->mmcr[0] |= MMCR0_FCP;
+	if (event->attr.exclude_kernel)
+		cpuhw->mmcr[0] |= freeze_events_kernel;
+	if (event->attr.exclude_hv)
+		cpuhw->mmcr[0] |= MMCR0_FCHV;
+
+	/*
+	 * Write the new configuration to MMCR* with the freeze
+	 * bit set and set the hardware events to their initial values.
+	 * Then unfreeze the events.
+	 */
+	ppc_set_pmu_inuse(1);
+	mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE);
+	mtspr(SPRN_MMCR1, cpuhw->mmcr[1]);
+	mtspr(SPRN_MMCR0, (cpuhw->mmcr[0] & ~(MMCR0_PMC1CE | MMCR0_PMCjCE))
+				| MMCR0_FC);
+
+	/*
+	 * Read off any pre-existing events that need to move
+	 * to another PMC.
+	 */
+	for (i = 0; i < cpuhw->n_events; ++i) {
+		event = cpuhw->event[i];
+		if (event->hw.idx && event->hw.idx != hwc_index[i] + 1) {
+			power_pmu_read(event);
+			write_pmc(event->hw.idx, 0);
+			event->hw.idx = 0;
+		}
+	}
+
+	/*
+	 * Initialize the PMCs for all the new and moved events.
+	 */
+	cpuhw->n_limited = n_lim = 0;
+	for (i = 0; i < cpuhw->n_events; ++i) {
+		event = cpuhw->event[i];
+		if (event->hw.idx)
+			continue;
+		idx = hwc_index[i] + 1;
+		if (is_limited_pmc(idx)) {
+			cpuhw->limited_event[n_lim] = event;
+			cpuhw->limited_hwidx[n_lim] = idx;
+			++n_lim;
+			continue;
+		}
+		val = 0;
+		if (event->hw.sample_period) {
+			left = atomic64_read(&event->hw.period_left);
+			if (left < 0x80000000L)
+				val = 0x80000000L - left;
+		}
+		atomic64_set(&event->hw.prev_count, val);
+		event->hw.idx = idx;
+		write_pmc(idx, val);
+		perf_event_update_userpage(event);
+	}
+	cpuhw->n_limited = n_lim;
+	cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
+
+ out_enable:
+	mb();
+	write_mmcr0(cpuhw, cpuhw->mmcr[0]);
+
+	/*
+	 * Enable instruction sampling if necessary
+	 */
+	if (cpuhw->mmcr[2] & MMCRA_SAMPLE_ENABLE) {
+		mb();
+		mtspr(SPRN_MMCRA, cpuhw->mmcr[2]);
+	}
+
+ out:
+	local_irq_restore(flags);
+}
+
+static int collect_events(struct perf_event *group, int max_count,
+			  struct perf_event *ctrs[], u64 *events,
+			  unsigned int *flags)
+{
+	int n = 0;
+	struct perf_event *event;
+
+	if (!is_software_event(group)) {
+		if (n >= max_count)
+			return -1;
+		ctrs[n] = group;
+		flags[n] = group->hw.event_base;
+		events[n++] = group->hw.config;
+	}
+	list_for_each_entry(event, &group->sibling_list, list_entry) {
+		if (!is_software_event(event) &&
+		    event->state != PERF_EVENT_STATE_OFF) {
+			if (n >= max_count)
+				return -1;
+			ctrs[n] = event;
+			flags[n] = event->hw.event_base;
+			events[n++] = event->hw.config;
+		}
+	}
+	return n;
+}
+
+static void event_sched_in(struct perf_event *event, int cpu)
+{
+	event->state = PERF_EVENT_STATE_ACTIVE;
+	event->oncpu = cpu;
+	event->tstamp_running += event->ctx->time - event->tstamp_stopped;
+	if (is_software_event(event))
+		event->pmu->enable(event);
+}
+
+/*
+ * Called to enable a whole group of events.
+ * Returns 1 if the group was enabled, or -EAGAIN if it could not be.
+ * Assumes the caller has disabled interrupts and has
+ * frozen the PMU with hw_perf_save_disable.
+ */
+int hw_perf_group_sched_in(struct perf_event *group_leader,
+	       struct perf_cpu_context *cpuctx,
+	       struct perf_event_context *ctx, int cpu)
+{
+	struct cpu_hw_events *cpuhw;
+	long i, n, n0;
+	struct perf_event *sub;
+
+	if (!ppmu)
+		return 0;
+	cpuhw = &__get_cpu_var(cpu_hw_events);
+	n0 = cpuhw->n_events;
+	n = collect_events(group_leader, ppmu->n_event - n0,
+			   &cpuhw->event[n0], &cpuhw->events[n0],
+			   &cpuhw->flags[n0]);
+	if (n < 0)
+		return -EAGAIN;
+	if (check_excludes(cpuhw->event, cpuhw->flags, n0, n))
+		return -EAGAIN;
+	i = power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n + n0);
+	if (i < 0)
+		return -EAGAIN;
+	cpuhw->n_events = n0 + n;
+	cpuhw->n_added += n;
+
+	/*
+	 * OK, this group can go on; update event states etc.,
+	 * and enable any software events
+	 */
+	for (i = n0; i < n0 + n; ++i)
+		cpuhw->event[i]->hw.config = cpuhw->events[i];
+	cpuctx->active_oncpu += n;
+	n = 1;
+	event_sched_in(group_leader, cpu);
+	list_for_each_entry(sub, &group_leader->sibling_list, list_entry) {
+		if (sub->state != PERF_EVENT_STATE_OFF) {
+			event_sched_in(sub, cpu);
+			++n;
+		}
+	}
+	ctx->nr_active += n;
+
+	return 1;
+}
+
+/*
+ * Add a event to the PMU.
+ * If all events are not already frozen, then we disable and
+ * re-enable the PMU in order to get hw_perf_enable to do the
+ * actual work of reconfiguring the PMU.
+ */
+static int power_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuhw;
+	unsigned long flags;
+	int n0;
+	int ret = -EAGAIN;
+
+	local_irq_save(flags);
+	perf_disable();
+
+	/*
+	 * Add the event to the list (if there is room)
+	 * and check whether the total set is still feasible.
+	 */
+	cpuhw = &__get_cpu_var(cpu_hw_events);
+	n0 = cpuhw->n_events;
+	if (n0 >= ppmu->n_event)
+		goto out;
+	cpuhw->event[n0] = event;
+	cpuhw->events[n0] = event->hw.config;
+	cpuhw->flags[n0] = event->hw.event_base;
+	if (check_excludes(cpuhw->event, cpuhw->flags, n0, 1))
+		goto out;
+	if (power_check_constraints(cpuhw, cpuhw->events, cpuhw->flags, n0 + 1))
+		goto out;
+
+	event->hw.config = cpuhw->events[n0];
+	++cpuhw->n_events;
+	++cpuhw->n_added;
+
+	ret = 0;
+ out:
+	perf_enable();
+	local_irq_restore(flags);
+	return ret;
+}
+
+/*
+ * Remove a event from the PMU.
+ */
+static void power_pmu_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuhw;
+	long i;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	perf_disable();
+
+	power_pmu_read(event);
+
+	cpuhw = &__get_cpu_var(cpu_hw_events);
+	for (i = 0; i < cpuhw->n_events; ++i) {
+		if (event == cpuhw->event[i]) {
+			while (++i < cpuhw->n_events)
+				cpuhw->event[i-1] = cpuhw->event[i];
+			--cpuhw->n_events;
+			ppmu->disable_pmc(event->hw.idx - 1, cpuhw->mmcr);
+			if (event->hw.idx) {
+				write_pmc(event->hw.idx, 0);
+				event->hw.idx = 0;
+			}
+			perf_event_update_userpage(event);
+			break;
+		}
+	}
+	for (i = 0; i < cpuhw->n_limited; ++i)
+		if (event == cpuhw->limited_event[i])
+			break;
+	if (i < cpuhw->n_limited) {
+		while (++i < cpuhw->n_limited) {
+			cpuhw->limited_event[i-1] = cpuhw->limited_event[i];
+			cpuhw->limited_hwidx[i-1] = cpuhw->limited_hwidx[i];
+		}
+		--cpuhw->n_limited;
+	}
+	if (cpuhw->n_events == 0) {
+		/* disable exceptions if no events are running */
+		cpuhw->mmcr[0] &= ~(MMCR0_PMXE | MMCR0_FCECE);
+	}
+
+	perf_enable();
+	local_irq_restore(flags);
+}
+
+/*
+ * Re-enable interrupts on a event after they were throttled
+ * because they were coming too fast.
+ */
+static void power_pmu_unthrottle(struct perf_event *event)
+{
+	s64 val, left;
+	unsigned long flags;
+
+	if (!event->hw.idx || !event->hw.sample_period)
+		return;
+	local_irq_save(flags);
+	perf_disable();
+	power_pmu_read(event);
+	left = event->hw.sample_period;
+	event->hw.last_period = left;
+	val = 0;
+	if (left < 0x80000000L)
+		val = 0x80000000L - left;
+	write_pmc(event->hw.idx, val);
+	atomic64_set(&event->hw.prev_count, val);
+	atomic64_set(&event->hw.period_left, left);
+	perf_event_update_userpage(event);
+	perf_enable();
+	local_irq_restore(flags);
+}
+
+struct pmu power_pmu = {
+	.enable		= power_pmu_enable,
+	.disable	= power_pmu_disable,
+	.read		= power_pmu_read,
+	.unthrottle	= power_pmu_unthrottle,
+};
+
+/*
+ * Return 1 if we might be able to put event on a limited PMC,
+ * or 0 if not.
+ * A event can only go on a limited PMC if it counts something
+ * that a limited PMC can count, doesn't require interrupts, and
+ * doesn't exclude any processor mode.
+ */
+static int can_go_on_limited_pmc(struct perf_event *event, u64 ev,
+				 unsigned int flags)
+{
+	int n;
+	u64 alt[MAX_EVENT_ALTERNATIVES];
+
+	if (event->attr.exclude_user
+	    || event->attr.exclude_kernel
+	    || event->attr.exclude_hv
+	    || event->attr.sample_period)
+		return 0;
+
+	if (ppmu->limited_pmc_event(ev))
+		return 1;
+
+	/*
+	 * The requested event_id isn't on a limited PMC already;
+	 * see if any alternative code goes on a limited PMC.
+	 */
+	if (!ppmu->get_alternatives)
+		return 0;
+
+	flags |= PPMU_LIMITED_PMC_OK | PPMU_LIMITED_PMC_REQD;
+	n = ppmu->get_alternatives(ev, flags, alt);
+
+	return n > 0;
+}
+
+/*
+ * Find an alternative event_id that goes on a normal PMC, if possible,
+ * and return the event_id code, or 0 if there is no such alternative.
+ * (Note: event_id code 0 is "don't count" on all machines.)
+ */
+static u64 normal_pmc_alternative(u64 ev, unsigned long flags)
+{
+	u64 alt[MAX_EVENT_ALTERNATIVES];
+	int n;
+
+	flags &= ~(PPMU_LIMITED_PMC_OK | PPMU_LIMITED_PMC_REQD);
+	n = ppmu->get_alternatives(ev, flags, alt);
+	if (!n)
+		return 0;
+	return alt[0];
+}
+
+/* Number of perf_events counting hardware events */
+static atomic_t num_events;
+/* Used to avoid races in calling reserve/release_pmc_hardware */
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+/*
+ * Release the PMU if this is the last perf_event.
+ */
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	if (!atomic_add_unless(&num_events, -1, 1)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_dec_return(&num_events) == 0)
+			release_pmc_hardware();
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+}
+
+/*
+ * Translate a generic cache event_id config to a raw event_id code.
+ */
+static int hw_perf_cache_event(u64 config, u64 *eventp)
+{
+	unsigned long type, op, result;
+	int ev;
+
+	if (!ppmu->cache_events)
+		return -EINVAL;
+
+	/* unpack config */
+	type = config & 0xff;
+	op = (config >> 8) & 0xff;
+	result = (config >> 16) & 0xff;
+
+	if (type >= PERF_COUNT_HW_CACHE_MAX ||
+	    op >= PERF_COUNT_HW_CACHE_OP_MAX ||
+	    result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return -EINVAL;
+
+	ev = (*ppmu->cache_events)[type][op][result];
+	if (ev == 0)
+		return -EOPNOTSUPP;
+	if (ev == -1)
+		return -EINVAL;
+	*eventp = ev;
+	return 0;
+}
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+	u64 ev;
+	unsigned long flags;
+	struct perf_event *ctrs[MAX_HWEVENTS];
+	u64 events[MAX_HWEVENTS];
+	unsigned int cflags[MAX_HWEVENTS];
+	int n;
+	int err;
+	struct cpu_hw_events *cpuhw;
+
+	if (!ppmu)
+		return ERR_PTR(-ENXIO);
+	switch (event->attr.type) {
+	case PERF_TYPE_HARDWARE:
+		ev = event->attr.config;
+		if (ev >= ppmu->n_generic || ppmu->generic_events[ev] == 0)
+			return ERR_PTR(-EOPNOTSUPP);
+		ev = ppmu->generic_events[ev];
+		break;
+	case PERF_TYPE_HW_CACHE:
+		err = hw_perf_cache_event(event->attr.config, &ev);
+		if (err)
+			return ERR_PTR(err);
+		break;
+	case PERF_TYPE_RAW:
+		ev = event->attr.config;
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+	event->hw.config_base = ev;
+	event->hw.idx = 0;
+
+	/*
+	 * If we are not running on a hypervisor, force the
+	 * exclude_hv bit to 0 so that we don't care what
+	 * the user set it to.
+	 */
+	if (!firmware_has_feature(FW_FEATURE_LPAR))
+		event->attr.exclude_hv = 0;
+
+	/*
+	 * If this is a per-task event, then we can use
+	 * PM_RUN_* events interchangeably with their non RUN_*
+	 * equivalents, e.g. PM_RUN_CYC instead of PM_CYC.
+	 * XXX we should check if the task is an idle task.
+	 */
+	flags = 0;
+	if (event->ctx->task)
+		flags |= PPMU_ONLY_COUNT_RUN;
+
+	/*
+	 * If this machine has limited events, check whether this
+	 * event_id could go on a limited event.
+	 */
+	if (ppmu->flags & PPMU_LIMITED_PMC5_6) {
+		if (can_go_on_limited_pmc(event, ev, flags)) {
+			flags |= PPMU_LIMITED_PMC_OK;
+		} else if (ppmu->limited_pmc_event(ev)) {
+			/*
+			 * The requested event_id is on a limited PMC,
+			 * but we can't use a limited PMC; see if any
+			 * alternative goes on a normal PMC.
+			 */
+			ev = normal_pmc_alternative(ev, flags);
+			if (!ev)
+				return ERR_PTR(-EINVAL);
+		}
+	}
+
+	/*
+	 * If this is in a group, check if it can go on with all the
+	 * other hardware events in the group.  We assume the event
+	 * hasn't been linked into its leader's sibling list at this point.
+	 */
+	n = 0;
+	if (event->group_leader != event) {
+		n = collect_events(event->group_leader, ppmu->n_event - 1,
+				   ctrs, events, cflags);
+		if (n < 0)
+			return ERR_PTR(-EINVAL);
+	}
+	events[n] = ev;
+	ctrs[n] = event;
+	cflags[n] = flags;
+	if (check_excludes(ctrs, cflags, n, 1))
+		return ERR_PTR(-EINVAL);
+
+	cpuhw = &get_cpu_var(cpu_hw_events);
+	err = power_check_constraints(cpuhw, events, cflags, n + 1);
+	put_cpu_var(cpu_hw_events);
+	if (err)
+		return ERR_PTR(-EINVAL);
+
+	event->hw.config = events[n];
+	event->hw.event_base = cflags[n];
+	event->hw.last_period = event->hw.sample_period;
+	atomic64_set(&event->hw.period_left, event->hw.last_period);
+
+	/*
+	 * See if we need to reserve the PMU.
+	 * If no events are currently in use, then we have to take a
+	 * mutex to ensure that we don't race with another task doing
+	 * reserve_pmc_hardware or release_pmc_hardware.
+	 */
+	err = 0;
+	if (!atomic_inc_not_zero(&num_events)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_read(&num_events) == 0 &&
+		    reserve_pmc_hardware(perf_event_interrupt))
+			err = -EBUSY;
+		else
+			atomic_inc(&num_events);
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+	event->destroy = hw_perf_event_destroy;
+
+	if (err)
+		return ERR_PTR(err);
+	return &power_pmu;
+}
+
+/*
+ * A counter has overflowed; update its count and record
+ * things if requested.  Note that interrupts are hard-disabled
+ * here so there is no possibility of being interrupted.
+ */
+static void record_and_restart(struct perf_event *event, unsigned long val,
+			       struct pt_regs *regs, int nmi)
+{
+	u64 period = event->hw.sample_period;
+	s64 prev, delta, left;
+	int record = 0;
+
+	/* we don't have to worry about interrupts here */
+	prev = atomic64_read(&event->hw.prev_count);
+	delta = (val - prev) & 0xfffffffful;
+	atomic64_add(delta, &event->count);
+
+	/*
+	 * See if the total period for this event has expired,
+	 * and update for the next period.
+	 */
+	val = 0;
+	left = atomic64_read(&event->hw.period_left) - delta;
+	if (period) {
+		if (left <= 0) {
+			left += period;
+			if (left <= 0)
+				left = period;
+			record = 1;
+		}
+		if (left < 0x80000000LL)
+			val = 0x80000000LL - left;
+	}
+
+	/*
+	 * Finally record data if requested.
+	 */
+	if (record) {
+		struct perf_sample_data data = {
+			.addr	= 0,
+			.period	= event->hw.last_period,
+		};
+
+		if (event->attr.sample_type & PERF_SAMPLE_ADDR)
+			perf_get_data_addr(regs, &data.addr);
+
+		if (perf_event_overflow(event, nmi, &data, regs)) {
+			/*
+			 * Interrupts are coming too fast - throttle them
+			 * by setting the event to 0, so it will be
+			 * at least 2^30 cycles until the next interrupt
+			 * (assuming each event counts at most 2 counts
+			 * per cycle).
+			 */
+			val = 0;
+			left = ~0ULL >> 1;
+		}
+	}
+
+	write_pmc(event->hw.idx, val);
+	atomic64_set(&event->hw.prev_count, val);
+	atomic64_set(&event->hw.period_left, left);
+	perf_event_update_userpage(event);
+}
+
+/*
+ * Called from generic code to get the misc flags (i.e. processor mode)
+ * for an event_id.
+ */
+unsigned long perf_misc_flags(struct pt_regs *regs)
+{
+	u32 flags = perf_get_misc_flags(regs);
+
+	if (flags)
+		return flags;
+	return user_mode(regs) ? PERF_RECORD_MISC_USER :
+		PERF_RECORD_MISC_KERNEL;
+}
+
+/*
+ * Called from generic code to get the instruction pointer
+ * for an event_id.
+ */
+unsigned long perf_instruction_pointer(struct pt_regs *regs)
+{
+	unsigned long ip;
+
+	if (TRAP(regs) != 0xf00)
+		return regs->nip;	/* not a PMU interrupt */
+
+	ip = mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
+	return ip;
+}
+
+/*
+ * Performance monitor interrupt stuff
+ */
+static void perf_event_interrupt(struct pt_regs *regs)
+{
+	int i;
+	struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
+	struct perf_event *event;
+	unsigned long val;
+	int found = 0;
+	int nmi;
+
+	if (cpuhw->n_limited)
+		freeze_limited_events(cpuhw, mfspr(SPRN_PMC5),
+					mfspr(SPRN_PMC6));
+
+	perf_read_regs(regs);
+
+	nmi = perf_intr_is_nmi(regs);
+	if (nmi)
+		nmi_enter();
+	else
+		irq_enter();
+
+	for (i = 0; i < cpuhw->n_events; ++i) {
+		event = cpuhw->event[i];
+		if (!event->hw.idx || is_limited_pmc(event->hw.idx))
+			continue;
+		val = read_pmc(event->hw.idx);
+		if ((int)val < 0) {
+			/* event has overflowed */
+			found = 1;
+			record_and_restart(event, val, regs, nmi);
+		}
+	}
+
+	/*
+	 * In case we didn't find and reset the event that caused
+	 * the interrupt, scan all events and reset any that are
+	 * negative, to avoid getting continual interrupts.
+	 * Any that we processed in the previous loop will not be negative.
+	 */
+	if (!found) {
+		for (i = 0; i < ppmu->n_event; ++i) {
+			if (is_limited_pmc(i + 1))
+				continue;
+			val = read_pmc(i + 1);
+			if ((int)val < 0)
+				write_pmc(i + 1, 0);
+		}
+	}
+
+	/*
+	 * Reset MMCR0 to its normal value.  This will set PMXE and
+	 * clear FC (freeze counters) and PMAO (perf mon alert occurred)
+	 * and thus allow interrupts to occur again.
+	 * XXX might want to use MSR.PM to keep the events frozen until
+	 * we get back out of this interrupt.
+	 */
+	write_mmcr0(cpuhw, cpuhw->mmcr[0]);
+
+	if (nmi)
+		nmi_exit();
+	else
+		irq_exit();
+}
+
+void hw_perf_event_setup(int cpu)
+{
+	struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu);
+
+	if (!ppmu)
+		return;
+	memset(cpuhw, 0, sizeof(*cpuhw));
+	cpuhw->mmcr[0] = MMCR0_FC;
+}
+
+int register_power_pmu(struct power_pmu *pmu)
+{
+	if (ppmu)
+		return -EBUSY;		/* something's already registered */
+
+	ppmu = pmu;
+	pr_info("%s performance monitor hardware support registered\n",
+		pmu->name);
+
+#ifdef MSR_HV
+	/*
+	 * Use FCHV to ignore kernel events if MSR.HV is set.
+	 */
+	if (mfmsr() & MSR_HV)
+		freeze_events_kernel = MMCR0_FCHV;
+#endif /* CONFIG_PPC64 */
+
+	return 0;
+}
diff --git a/arch/powerpc/kernel/power4-pmu.c b/arch/powerpc/kernel/power4-pmu.c
index 3c90a3d..2a361cd 100644
--- a/arch/powerpc/kernel/power4-pmu.c
+++ b/arch/powerpc/kernel/power4-pmu.c
@@ -9,7 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/string.h>
 #include <asm/reg.h>
 #include <asm/cputable.h>
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c
index 31918af..0f4c1c7 100644
--- a/arch/powerpc/kernel/power5+-pmu.c
+++ b/arch/powerpc/kernel/power5+-pmu.c
@@ -9,7 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/string.h>
 #include <asm/reg.h>
 #include <asm/cputable.h>
diff --git a/arch/powerpc/kernel/power5-pmu.c b/arch/powerpc/kernel/power5-pmu.c
index 867f6f6..c351b3a 100644
--- a/arch/powerpc/kernel/power5-pmu.c
+++ b/arch/powerpc/kernel/power5-pmu.c
@@ -9,7 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/string.h>
 #include <asm/reg.h>
 #include <asm/cputable.h>
diff --git a/arch/powerpc/kernel/power6-pmu.c b/arch/powerpc/kernel/power6-pmu.c
index fa21890..ca399ba 100644
--- a/arch/powerpc/kernel/power6-pmu.c
+++ b/arch/powerpc/kernel/power6-pmu.c
@@ -9,7 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/string.h>
 #include <asm/reg.h>
 #include <asm/cputable.h>
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c
index 018d094..28a4daa 100644
--- a/arch/powerpc/kernel/power7-pmu.c
+++ b/arch/powerpc/kernel/power7-pmu.c
@@ -9,7 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/string.h>
 #include <asm/reg.h>
 #include <asm/cputable.h>
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c
index 75dccb7..4795744 100644
--- a/arch/powerpc/kernel/ppc970-pmu.c
+++ b/arch/powerpc/kernel/ppc970-pmu.c
@@ -9,7 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/string.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <asm/reg.h>
 #include <asm/cputable.h>
 
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 892a9f2..0a32164 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -284,14 +284,13 @@ int set_dabr(unsigned long dabr)
 		return ppc_md.set_dabr(dabr);
 
 	/* XXX should we have a CPU_FTR_HAS_DABR ? */
-#if defined(CONFIG_PPC64) || defined(CONFIG_6xx)
-	mtspr(SPRN_DABR, dabr);
-#endif
-
 #if defined(CONFIG_BOOKE)
 	mtspr(SPRN_DAC1, dabr);
+#elif defined(CONFIG_PPC_BOOK3S)
+	mtspr(SPRN_DABR, dabr);
 #endif
 
+
 	return 0;
 }
 
@@ -372,15 +371,16 @@ struct task_struct *__switch_to(struct task_struct *prev,
 
 #endif /* CONFIG_SMP */
 
-	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
-		set_dabr(new->thread.dabr);
-
 #if defined(CONFIG_BOOKE)
 	/* If new thread DAC (HW breakpoint) is the same then leave it */
 	if (new->thread.dabr)
 		set_dabr(new->thread.dabr);
+#else
+	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
+		set_dabr(new->thread.dabr);
 #endif
 
+
 	new_thread = &new->thread;
 	old_thread = &current->thread;
 
@@ -664,6 +664,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 		sp_vsid |= SLB_VSID_KERNEL | llp;
 		p->thread.ksp_vsid = sp_vsid;
 	}
+#endif /* CONFIG_PPC_STD_MMU_64 */
 
 	/*
 	 * The PPC64 ABI makes use of a TOC to contain function 
@@ -671,6 +672,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 	 * to the TOC entry.  The first entry is a pointer to the actual
 	 * function.
  	 */
+#ifdef CONFIG_PPC64
 	kregs->nip = *((unsigned long *)ret_from_fork);
 #else
 	kregs->nip = (unsigned long)ret_from_fork;
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index a538824..864334b 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -190,6 +190,8 @@ static int __initdata of_platform;
 
 static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
 
+static unsigned long __initdata prom_memory_limit;
+
 static unsigned long __initdata alloc_top;
 static unsigned long __initdata alloc_top_high;
 static unsigned long __initdata alloc_bottom;
@@ -484,6 +486,67 @@ static int __init prom_setprop(phandle node, const char *nodename,
 	return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd);
 }
 
+/* We can't use the standard versions because of RELOC headaches. */
+#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
+			 || ('a' <= (c) && (c) <= 'f') \
+			 || ('A' <= (c) && (c) <= 'F'))
+
+#define isdigit(c)	('0' <= (c) && (c) <= '9')
+#define islower(c)	('a' <= (c) && (c) <= 'z')
+#define toupper(c)	(islower(c) ? ((c) - 'a' + 'A') : (c))
+
+unsigned long prom_strtoul(const char *cp, const char **endp)
+{
+	unsigned long result = 0, base = 10, value;
+
+	if (*cp == '0') {
+		base = 8;
+		cp++;
+		if (toupper(*cp) == 'X') {
+			cp++;
+			base = 16;
+		}
+	}
+
+	while (isxdigit(*cp) &&
+	       (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
+		result = result * base + value;
+		cp++;
+	}
+
+	if (endp)
+		*endp = cp;
+
+	return result;
+}
+
+unsigned long prom_memparse(const char *ptr, const char **retptr)
+{
+	unsigned long ret = prom_strtoul(ptr, retptr);
+	int shift = 0;
+
+	/*
+	 * We can't use a switch here because GCC *may* generate a
+	 * jump table which won't work, because we're not running at
+	 * the address we're linked at.
+	 */
+	if ('G' == **retptr || 'g' == **retptr)
+		shift = 30;
+
+	if ('M' == **retptr || 'm' == **retptr)
+		shift = 20;
+
+	if ('K' == **retptr || 'k' == **retptr)
+		shift = 10;
+
+	if (shift) {
+		ret <<= shift;
+		(*retptr)++;
+	}
+
+	return ret;
+}
+
 /*
  * Early parsing of the command line passed to the kernel, used for
  * "mem=x" and the options that affect the iommu
@@ -491,9 +554,8 @@ static int __init prom_setprop(phandle node, const char *nodename,
 static void __init early_cmdline_parse(void)
 {
 	struct prom_t *_prom = &RELOC(prom);
-#ifdef CONFIG_PPC64
 	const char *opt;
-#endif
+
 	char *p;
 	int l = 0;
 
@@ -521,6 +583,15 @@ static void __init early_cmdline_parse(void)
 			RELOC(prom_iommu_force_on) = 1;
 	}
 #endif
+	opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
+	if (opt) {
+		opt += 4;
+		RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
+#ifdef CONFIG_PPC64
+		/* Align to 16 MB == size of ppc64 large page */
+		RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
+#endif
+	}
 }
 
 #ifdef CONFIG_PPC_PSERIES
@@ -1027,6 +1098,29 @@ static void __init prom_init_mem(void)
 	}
 
 	/*
+	 * If prom_memory_limit is set we reduce the upper limits *except* for
+	 * alloc_top_high. This must be the real top of RAM so we can put
+	 * TCE's up there.
+	 */
+
+	RELOC(alloc_top_high) = RELOC(ram_top);
+
+	if (RELOC(prom_memory_limit)) {
+		if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
+			prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
+				RELOC(prom_memory_limit));
+			RELOC(prom_memory_limit) = 0;
+		} else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
+			prom_printf("Ignoring mem=%x >= ram_top.\n",
+				RELOC(prom_memory_limit));
+			RELOC(prom_memory_limit) = 0;
+		} else {
+			RELOC(ram_top) = RELOC(prom_memory_limit);
+			RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
+		}
+	}
+
+	/*
 	 * Setup our top alloc point, that is top of RMO or top of
 	 * segment 0 when running non-LPAR.
 	 * Some RS64 machines have buggy firmware where claims up at
@@ -1041,6 +1135,7 @@ static void __init prom_init_mem(void)
 	RELOC(alloc_top_high) = RELOC(ram_top);
 
 	prom_printf("memory layout at init:\n");
+	prom_printf("  memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
 	prom_printf("  alloc_bottom : %x\n", RELOC(alloc_bottom));
 	prom_printf("  alloc_top    : %x\n", RELOC(alloc_top));
 	prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
@@ -1259,10 +1354,6 @@ static void __init prom_initialize_tce_table(void)
  *
  * -- Cort
  */
-extern char __secondary_hold;
-extern unsigned long __secondary_hold_spinloop;
-extern unsigned long __secondary_hold_acknowledge;
-
 /*
  * We want to reference the copy of __secondary_hold_* in the
  * 0 - 0x100 address range
@@ -2399,6 +2490,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
 	/*
 	 * Fill in some infos for use by the kernel later on
 	 */
+	if (RELOC(prom_memory_limit))
+		prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
+			     &RELOC(prom_memory_limit),
+			     sizeof(prom_memory_limit));
 #ifdef CONFIG_PPC64
 	if (RELOC(prom_iommu_off))
 		prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index c434823..bf90361 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -39,6 +39,7 @@
 #include <asm/smp.h>
 #include <asm/atomic.h>
 #include <asm/time.h>
+#include <asm/mmu.h>
 
 struct rtas_t rtas = {
 	.lock = __RAW_SPIN_LOCK_UNLOCKED
@@ -713,6 +714,7 @@ static void rtas_percpu_suspend_me(void *info)
 {
 	long rc = H_SUCCESS;
 	unsigned long msr_save;
+	u16 slb_size = mmu_slb_size;
 	int cpu;
 	struct rtas_suspend_me_data *data =
 		(struct rtas_suspend_me_data *)info;
@@ -735,13 +737,16 @@ static void rtas_percpu_suspend_me(void *info)
 		/* All other cpus are in H_JOIN, this cpu does
 		 * the suspend.
 		 */
+		slb_set_size(SLB_MIN_SIZE);
 		printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n",
 		       smp_processor_id());
 		data->error = rtas_call(data->token, 0, 1, NULL);
 
-		if (data->error)
+		if (data->error) {
 			printk(KERN_DEBUG "ibm,suspend-me returned %d\n",
 			       data->error);
+			slb_set_size(slb_size);
+		}
 	} else {
 		printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n",
 		       smp_processor_id(), rc);
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index e1e3059..53bcf3d 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -210,6 +210,14 @@ void nvram_write_byte(unsigned char val, int addr)
 }
 EXPORT_SYMBOL(nvram_write_byte);
 
+ssize_t nvram_get_size(void)
+{
+	if (ppc_md.nvram_size)
+		return ppc_md.nvram_size();
+	return -1;
+}
+EXPORT_SYMBOL(nvram_get_size);
+
 void nvram_sync(void)
 {
 	if (ppc_md.nvram_sync)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 1f68160..797ea95 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -57,11 +57,13 @@
 #include <asm/cache.h>
 #include <asm/page.h>
 #include <asm/mmu.h>
+#include <asm/mmu-hash64.h>
 #include <asm/firmware.h>
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
 #include <asm/swiotlb.h>
+#include <asm/mmu_context.h>
 
 #include "setup.h"
 
@@ -142,11 +144,14 @@ early_param("smt-enabled", early_smt_enabled);
 #define check_smt_enabled()
 #endif /* CONFIG_SMP */
 
-/* Put the paca pointer into r13 and SPRG3 */
+/* Put the paca pointer into r13 and SPRG_PACA */
 void __init setup_paca(int cpu)
 {
 	local_paca = &paca[cpu];
-	mtspr(SPRN_SPRG3, local_paca);
+	mtspr(SPRN_SPRG_PACA, local_paca);
+#ifdef CONFIG_PPC_BOOK3E
+	mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
+#endif
 }
 
 /*
@@ -230,9 +235,6 @@ void early_setup_secondary(void)
 #endif /* CONFIG_SMP */
 
 #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
-extern unsigned long __secondary_hold_spinloop;
-extern void generic_secondary_smp_init(void);
-
 void smp_release_cpus(void)
 {
 	unsigned long *ptr;
@@ -453,6 +455,24 @@ static void __init irqstack_early_init(void)
 #define irqstack_early_init()
 #endif
 
+#ifdef CONFIG_PPC_BOOK3E
+static void __init exc_lvl_early_init(void)
+{
+	unsigned int i;
+
+	for_each_possible_cpu(i) {
+		critirq_ctx[i] = (struct thread_info *)
+			__va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+		dbgirq_ctx[i] = (struct thread_info *)
+			__va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+		mcheckirq_ctx[i] = (struct thread_info *)
+			__va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+	}
+}
+#else
+#define exc_lvl_early_init()
+#endif
+
 /*
  * Stack space used when we detect a bad kernel stack pointer, and
  * early in SMP boots before relocation is enabled.
@@ -512,6 +532,7 @@ void __init setup_arch(char **cmdline_p)
 	init_mm.brk = klimit;
 	
 	irqstack_early_init();
+	exc_lvl_early_init();
 	emergency_stack_init();
 
 #ifdef CONFIG_PPC_STD_MMU_64
@@ -534,6 +555,10 @@ void __init setup_arch(char **cmdline_p)
 #endif
 
 	paging_init();
+
+	/* Initialize the MMU context management stuff */
+	mmu_context_init();
+
 	ppc64_boot_msg(0x15, "Setup Done");
 }
 
@@ -569,25 +594,53 @@ void cpu_die(void)
 }
 
 #ifdef CONFIG_SMP
-void __init setup_per_cpu_areas(void)
+#define PCPU_DYN_SIZE		()
+
+static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
 {
-	int i;
-	unsigned long size;
-	char *ptr;
-
-	/* Copy section for each CPU (we discard the original) */
-	size = ALIGN(__per_cpu_end - __per_cpu_start, PAGE_SIZE);
-#ifdef CONFIG_MODULES
-	if (size < PERCPU_ENOUGH_ROOM)
-		size = PERCPU_ENOUGH_ROOM;
-#endif
+	return __alloc_bootmem_node(NODE_DATA(cpu_to_node(cpu)), size, align,
+				    __pa(MAX_DMA_ADDRESS));
+}
 
-	for_each_possible_cpu(i) {
-		ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size);
+static void __init pcpu_fc_free(void *ptr, size_t size)
+{
+	free_bootmem(__pa(ptr), size);
+}
 
-		paca[i].data_offset = ptr - __per_cpu_start;
-		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-	}
+static int pcpu_cpu_distance(unsigned int from, unsigned int to)
+{
+	if (cpu_to_node(from) == cpu_to_node(to))
+		return LOCAL_DISTANCE;
+	else
+		return REMOTE_DISTANCE;
+}
+
+void __init setup_per_cpu_areas(void)
+{
+	const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
+	size_t atom_size;
+	unsigned long delta;
+	unsigned int cpu;
+	int rc;
+
+	/*
+	 * Linear mapping is one of 4K, 1M and 16M.  For 4K, no need
+	 * to group units.  For larger mappings, use 1M atom which
+	 * should be large enough to contain a number of units.
+	 */
+	if (mmu_linear_psize == MMU_PAGE_4K)
+		atom_size = PAGE_SIZE;
+	else
+		atom_size = 1 << 20;
+
+	rc = pcpu_embed_first_chunk(0, dyn_size, atom_size, pcpu_cpu_distance,
+				    pcpu_fc_alloc, pcpu_fc_free);
+	if (rc < 0)
+		panic("cannot initialize percpu area (err=%d)", rc);
+
+	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+	for_each_possible_cpu(cpu)
+		paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu];
 }
 #endif
 
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 0b47de0..d387b39 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -269,7 +269,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 	cpu_callin_map[boot_cpuid] = 1;
 
 	if (smp_ops)
-		max_cpus = smp_ops->probe();
+		if (smp_ops->probe)
+			max_cpus = smp_ops->probe();
+		else
+			max_cpus = NR_CPUS;
 	else
 		max_cpus = 1;
  
@@ -412,9 +415,8 @@ int __cpuinit __cpu_up(unsigned int cpu)
 		 * CPUs can take much longer to come up in the
 		 * hotplug case.  Wait five seconds.
 		 */
-		for (c = 25; c && !cpu_callin_map[cpu]; c--) {
-			msleep(200);
-		}
+		for (c = 5000; c && !cpu_callin_map[cpu]; c--)
+			msleep(1);
 #endif
 
 	if (!cpu_callin_map[cpu]) {
@@ -494,7 +496,8 @@ int __devinit start_secondary(void *unused)
 	preempt_disable();
 	cpu_callin_map[cpu] = 1;
 
-	smp_ops->setup_cpu(cpu);
+	if (smp_ops->setup_cpu)
+		smp_ops->setup_cpu(cpu);
 	if (smp_ops->take_timebase)
 		smp_ops->take_timebase();
 
@@ -557,7 +560,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
 	old_mask = current->cpus_allowed;
 	set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid));
 	
-	if (smp_ops)
+	if (smp_ops && smp_ops->setup_cpu)
 		smp_ops->setup_cpu(boot_cpuid);
 
 	set_cpus_allowed(current, old_mask);
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index bb1cfcf..1cc5e9e 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -343,6 +343,18 @@ off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin)
 	return sys_lseek(fd, (int)offset, origin);
 }
 
+long compat_sys_truncate(const char __user * path, u32 length)
+{
+	/* sign extend length */
+	return sys_truncate(path, (int)length);
+}
+
+long compat_sys_ftruncate(int fd, u32 length)
+{
+	/* sign extend length */
+	return sys_ftruncate(fd, (int)length);
+}
+
 /* Note: it is necessary to treat bufsiz as an unsigned int,
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index f41aec8..956ab33 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -17,6 +17,7 @@
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/smp.h>
+#include <asm/pmc.h>
 
 #include "cacheinfo.h"
 
@@ -123,6 +124,8 @@ static DEFINE_PER_CPU(char, pmcs_enabled);
 
 void ppc_enable_pmcs(void)
 {
+	ppc_set_pmu_inuse(1);
+
 	/* Only need to enable them once */
 	if (__get_cpu_var(pmcs_enabled))
 		return;
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index eae4511..df45a74 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -53,7 +53,7 @@
 #include <linux/posix-timers.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 
 #include <asm/io.h>
 #include <asm/processor.h>
@@ -479,7 +479,8 @@ static int __init iSeries_tb_recal(void)
 		unsigned long tb_ticks = tb - iSeries_recal_tb;
 		unsigned long titan_usec = (titan - iSeries_recal_titan) >> 12;
 		unsigned long new_tb_ticks_per_sec   = (tb_ticks * USEC_PER_SEC)/titan_usec;
-		unsigned long new_tb_ticks_per_jiffy = (new_tb_ticks_per_sec+(HZ/2))/HZ;
+		unsigned long new_tb_ticks_per_jiffy =
+			DIV_ROUND_CLOSEST(new_tb_ticks_per_sec, HZ);
 		long tick_diff = new_tb_ticks_per_jiffy - tb_ticks_per_jiffy;
 		char sign = '+';		
 		/* make sure tb_ticks_per_sec and tb_ticks_per_jiffy are consistent */
@@ -526,25 +527,25 @@ void __init iSeries_time_init_early(void)
 }
 #endif /* CONFIG_PPC_ISERIES */
 
-#if defined(CONFIG_PERF_COUNTERS) && defined(CONFIG_PPC32)
-DEFINE_PER_CPU(u8, perf_counter_pending);
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_PPC32)
+DEFINE_PER_CPU(u8, perf_event_pending);
 
-void set_perf_counter_pending(void)
+void set_perf_event_pending(void)
 {
-	get_cpu_var(perf_counter_pending) = 1;
+	get_cpu_var(perf_event_pending) = 1;
 	set_dec(1);
-	put_cpu_var(perf_counter_pending);
+	put_cpu_var(perf_event_pending);
 }
 
-#define test_perf_counter_pending()	__get_cpu_var(perf_counter_pending)
-#define clear_perf_counter_pending()	__get_cpu_var(perf_counter_pending) = 0
+#define test_perf_event_pending()	__get_cpu_var(perf_event_pending)
+#define clear_perf_event_pending()	__get_cpu_var(perf_event_pending) = 0
 
-#else  /* CONFIG_PERF_COUNTERS && CONFIG_PPC32 */
+#else  /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
 
-#define test_perf_counter_pending()	0
-#define clear_perf_counter_pending()
+#define test_perf_event_pending()	0
+#define clear_perf_event_pending()
 
-#endif /* CONFIG_PERF_COUNTERS && CONFIG_PPC32 */
+#endif /* CONFIG_PERF_EVENTS && CONFIG_PPC32 */
 
 /*
  * For iSeries shared processors, we have to let the hypervisor
@@ -572,9 +573,9 @@ void timer_interrupt(struct pt_regs * regs)
 	set_dec(DECREMENTER_MAX);
 
 #ifdef CONFIG_PPC32
-	if (test_perf_counter_pending()) {
-		clear_perf_counter_pending();
-		perf_counter_do_pending();
+	if (test_perf_event_pending()) {
+		clear_perf_event_pending();
+		perf_event_do_pending();
 	}
 	if (atomic_read(&ppc_n_lost_interrupts) != 0)
 		do_IRQ(regs);
@@ -726,6 +727,18 @@ static int __init get_freq(char *name, int cells, unsigned long *val)
 	return found;
 }
 
+/* should become __cpuinit when secondary_cpu_time_init also is */
+void start_cpu_decrementer(void)
+{
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+	/* Clear any pending timer interrupts */
+	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+	/* Enable decrementer interrupt */
+	mtspr(SPRN_TCR, TCR_DIE);
+#endif /* defined(CONFIG_BOOKE) || defined(CONFIG_40x) */
+}
+
 void __init generic_calibrate_decr(void)
 {
 	ppc_tb_freq = DEFAULT_TB_FREQ;		/* hardcoded default */
@@ -745,14 +758,6 @@ void __init generic_calibrate_decr(void)
 		printk(KERN_ERR "WARNING: Estimating processor frequency "
 				"(not found)\n");
 	}
-
-#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
-	/* Clear any pending timer interrupts */
-	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
-
-	/* Enable decrementer interrupt */
-	mtspr(SPRN_TCR, TCR_DIE);
-#endif
 }
 
 int update_persistent_clock(struct timespec now)
@@ -769,11 +774,12 @@ int update_persistent_clock(struct timespec now)
 	return ppc_md.set_rtc_time(&tm);
 }
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
 	struct rtc_time tm;
 	static int first = 1;
 
+	ts->tv_nsec = 0;
 	/* XXX this is a litle fragile but will work okay in the short term */
 	if (first) {
 		first = 0;
@@ -781,14 +787,18 @@ unsigned long read_persistent_clock(void)
 			timezone_offset = ppc_md.time_init();
 
 		/* get_boot_time() isn't guaranteed to be safe to call late */
-		if (ppc_md.get_boot_time)
-			return ppc_md.get_boot_time() -timezone_offset;
+		if (ppc_md.get_boot_time) {
+			ts->tv_sec = ppc_md.get_boot_time() - timezone_offset;
+			return;
+		}
+	}
+	if (!ppc_md.get_rtc_time) {
+		ts->tv_sec = 0;
+		return;
 	}
-	if (!ppc_md.get_rtc_time)
-		return 0;
 	ppc_md.get_rtc_time(&tm);
-	return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
-		      tm.tm_hour, tm.tm_min, tm.tm_sec);
+	ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
+			    tm.tm_hour, tm.tm_min, tm.tm_sec);
 }
 
 /* clocksource code */
@@ -913,6 +923,11 @@ static void __init init_decrementer_clockevent(void)
 
 void secondary_cpu_time_init(void)
 {
+	/* Start the decrementer on CPUs that have manual control
+	 * such as BookE
+	 */
+	start_cpu_decrementer();
+
 	/* FIME: Should make unrelatred change to move snapshot_timebase
 	 * call here ! */
 	register_decrementer_clockevent(smp_processor_id());
@@ -1016,6 +1031,11 @@ void __init time_init(void)
 
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
+	/* Start the decrementer on CPUs that have manual control
+	 * such as BookE
+	 */
+	start_cpu_decrementer();
+
 	/* Register the clocksource, if we're not running on iSeries */
 	if (!firmware_has_feature(FW_FEATURE_ISERIES))
 		clocksource_init();
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index ad06d5c..a0abce2 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -203,7 +203,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	} else {
 		vdso_pagelist = vdso64_pagelist;
 		vdso_pages = vdso64_pages;
-		vdso_base = VDSO64_MBASE;
+		/*
+		 * On 64bit we don't have a preferred map address. This
+		 * allows get_unmapped_area to find an area near other mmaps
+		 * and most likely share a SLB entry.
+		 */
+		vdso_base = 0;
 	}
 #else
 	vdso_pagelist = vdso32_pagelist;
diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
index c3d57bd..b54b816 100644
--- a/arch/powerpc/kernel/vdso32/Makefile
+++ b/arch/powerpc/kernel/vdso32/Makefile
@@ -12,6 +12,7 @@ endif
 targets := $(obj-vdso32) vdso32.so vdso32.so.dbg
 obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
 
+GCOV_PROFILE := n
 
 EXTRA_CFLAGS := -shared -fno-common -fno-builtin
 EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
index fa7f1b8..dd0c8e9 100644
--- a/arch/powerpc/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
@@ -7,6 +7,8 @@ obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o
 targets := $(obj-vdso64) vdso64.so vdso64.so.dbg
 obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
 
+GCOV_PROFILE := n
+
 EXTRA_CFLAGS := -shared -fno-common -fno-builtin
 EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
 		$(call ld-option, -Wl$(comma)--hash-style=sysv)
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S
index ea4d646..67b6916 100644
--- a/arch/powerpc/kernel/vector.S
+++ b/arch/powerpc/kernel/vector.S
@@ -65,7 +65,7 @@ _GLOBAL(load_up_altivec)
 1:
 	/* enable use of VMX after return */
 #ifdef CONFIG_PPC32
-	mfspr	r5,SPRN_SPRG3		/* current task's THREAD (phys) */
+	mfspr	r5,SPRN_SPRG_THREAD		/* current task's THREAD (phys) */
 	oris	r9,r9,MSR_VEC@h
 #else
 	ld	r4,PACACURRENT(r13)
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 819e59f..bc7b41e 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -601,7 +601,7 @@ static void vio_dma_iommu_unmap_sg(struct device *dev,
 	vio_cmo_dealloc(viodev, alloc_size);
 }
 
-struct dma_mapping_ops vio_dma_mapping_ops = {
+struct dma_map_ops vio_dma_mapping_ops = {
 	.alloc_coherent = vio_dma_iommu_alloc_coherent,
 	.free_coherent  = vio_dma_iommu_free_coherent,
 	.map_sg         = vio_dma_iommu_map_sg,
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 8ef8a14..58da407 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -37,12 +37,6 @@ jiffies = jiffies_64 + 4;
 #endif
 SECTIONS
 {
-	/* Sections to be discarded. */
-	/DISCARD/ : {
-	*(.exitcall.exit)
-	EXIT_DATA
-	}
-
 	. = KERNELBASE;
 
 /*
@@ -245,10 +239,6 @@ SECTIONS
 	}
 #endif
 
-	. = ALIGN(PAGE_SIZE);
-	_edata  =  .;
-	PROVIDE32 (edata = .);
-
 	/* The initial task and kernel stack */
 #ifdef CONFIG_PPC32
 	. = ALIGN(8192);
@@ -282,6 +272,10 @@ SECTIONS
 		__nosave_end = .;
 	}
 
+	. = ALIGN(PAGE_SIZE);
+	_edata  =  .;
+	PROVIDE32 (edata = .);
+
 /*
  * And finally the bss
  */
@@ -298,4 +292,7 @@ SECTIONS
 	. = ALIGN(PAGE_SIZE);
 	_end = . ;
 	PROVIDE32 (end = .);
+
+	/* Sections to be discarded. */
+	DISCARDS
 }
diff --git a/arch/powerpc/kvm/44x.c b/arch/powerpc/kvm/44x.c
index 0cef809..f4d1b55 100644
--- a/arch/powerpc/kvm/44x.c
+++ b/arch/powerpc/kvm/44x.c
@@ -138,7 +138,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 	kmem_cache_free(kvm_vcpu_cache, vcpu_44x);
 }
 
-static int kvmppc_44x_init(void)
+static int __init kvmppc_44x_init(void)
 {
 	int r;
 
@@ -149,7 +149,7 @@ static int kvmppc_44x_init(void)
 	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_44x), THIS_MODULE);
 }
 
-static void kvmppc_44x_exit(void)
+static void __exit kvmppc_44x_exit(void)
 {
 	kvmppc_booke_exit();
 }
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 4a16f47..ff3cb63 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -30,6 +30,7 @@
 #include "timing.h"
 
 #include "44x_tlb.h"
+#include "trace.h"
 
 #ifndef PPC44x_TLBE_SIZE
 #define PPC44x_TLBE_SIZE	PPC44x_TLB_4K
@@ -263,7 +264,7 @@ static void kvmppc_44x_shadow_release(struct kvmppc_vcpu_44x *vcpu_44x,
 
 	/* XXX set tlb_44x_index to stlb_index? */
 
-	KVMTRACE_1D(STLB_INVAL, &vcpu_44x->vcpu, stlb_index, handler);
+	trace_kvm_stlb_inval(stlb_index);
 }
 
 void kvmppc_mmu_destroy(struct kvm_vcpu *vcpu)
@@ -365,8 +366,8 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gpa_t gpaddr,
 	/* Insert shadow mapping into hardware TLB. */
 	kvmppc_44x_tlbe_set_modified(vcpu_44x, victim);
 	kvmppc_44x_tlbwe(victim, &stlbe);
-	KVMTRACE_5D(STLB_WRITE, vcpu, victim, stlbe.tid, stlbe.word0, stlbe.word1,
-	            stlbe.word2, handler);
+	trace_kvm_stlb_write(victim, stlbe.tid, stlbe.word0, stlbe.word1,
+			     stlbe.word2);
 }
 
 /* For a particular guest TLB entry, invalidate the corresponding host TLB
@@ -485,8 +486,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
 		kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
 	}
 
-	KVMTRACE_5D(GTLB_WRITE, vcpu, gtlb_index, tlbe->tid, tlbe->word0,
-	            tlbe->word1, tlbe->word2, handler);
+	trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1,
+			     tlbe->word2);
 
 	kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS);
 	return EMULATE_DONE;
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 5a152a5..c299268 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -2,8 +2,7 @@
 # KVM configuration
 #
 
-config HAVE_KVM_IRQCHIP
-       bool
+source "virt/kvm/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -59,17 +58,6 @@ config KVM_E500
 
 	  If unsure, say N.
 
-config KVM_TRACE
-	bool "KVM trace support"
-	depends on KVM && MARKERS && SYSFS
-	select RELAY
-	select DEBUG_FS
-	default n
-	---help---
-	  This option allows reading a trace of kvm-related events through
-	  relayfs.  Note the ABI is not considered stable and will be
-	  modified in future updates.
-
 source drivers/virtio/Kconfig
 
 endif # VIRTUALIZATION
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 459c7ee..37655fe 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -8,7 +8,9 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm
 
 common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
 
-common-objs-$(CONFIG_KVM_TRACE)  += $(addprefix ../../../virt/kvm/, kvm_trace.o)
+CFLAGS_44x_tlb.o  := -I.
+CFLAGS_e500_tlb.o := -I.
+CFLAGS_emulate.o  := -I.
 
 kvm-objs := $(common-objs-y) powerpc.o emulate.o
 obj-$(CONFIG_KVM_EXIT_TIMING) += timing.o
diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
index 642e420..e7bf4d0 100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -520,7 +520,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 	return kvmppc_core_vcpu_translate(vcpu, tr);
 }
 
-int kvmppc_booke_init(void)
+int __init kvmppc_booke_init(void)
 {
 	unsigned long ivor[16];
 	unsigned long max_ivor = 0;
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index d0c6f84..380a78c 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -56,8 +56,8 @@
 .macro KVM_HANDLER ivor_nr
 _GLOBAL(kvmppc_handler_\ivor_nr)
 	/* Get pointer to vcpu and record exit number. */
-	mtspr	SPRN_SPRG0, r4
-	mfspr	r4, SPRN_SPRG1
+	mtspr	SPRN_SPRG_WSCRATCH0, r4
+	mfspr	r4, SPRN_SPRG_RVCPU
 	stw	r5, VCPU_GPR(r5)(r4)
 	stw	r6, VCPU_GPR(r6)(r4)
 	mfctr	r5
@@ -95,7 +95,7 @@ _GLOBAL(kvmppc_handler_len)
 
 
 /* Registers:
- *  SPRG0: guest r4
+ *  SPRG_SCRATCH0: guest r4
  *  r4: vcpu pointer
  *  r5: KVM exit number
  */
@@ -181,7 +181,7 @@ _GLOBAL(kvmppc_resume_host)
 	stw	r3, VCPU_LR(r4)
 	mfxer	r3
 	stw	r3, VCPU_XER(r4)
-	mfspr	r3, SPRN_SPRG0
+	mfspr	r3, SPRN_SPRG_RSCRATCH0
 	stw	r3, VCPU_GPR(r4)(r4)
 	mfspr	r3, SPRN_SRR0
 	stw	r3, VCPU_PC(r4)
@@ -374,7 +374,7 @@ lightweight_exit:
 	mtspr	SPRN_IVPR, r8
 
 	/* Save vcpu pointer for the exception handlers. */
-	mtspr	SPRN_SPRG1, r4
+	mtspr	SPRN_SPRG_WVCPU, r4
 
 	/* Can't switch the stack pointer until after IVPR is switched,
 	 * because host interrupt handlers would get confused. */
@@ -384,13 +384,13 @@ lightweight_exit:
 	/* Host interrupt handlers may have clobbered these guest-readable
 	 * SPRGs, so we need to reload them here with the guest's values. */
 	lwz	r3, VCPU_SPRG4(r4)
-	mtspr	SPRN_SPRG4, r3
+	mtspr	SPRN_SPRG4W, r3
 	lwz	r3, VCPU_SPRG5(r4)
-	mtspr	SPRN_SPRG5, r3
+	mtspr	SPRN_SPRG5W, r3
 	lwz	r3, VCPU_SPRG6(r4)
-	mtspr	SPRN_SPRG6, r3
+	mtspr	SPRN_SPRG6W, r3
 	lwz	r3, VCPU_SPRG7(r4)
-	mtspr	SPRN_SPRG7, r3
+	mtspr	SPRN_SPRG7W, r3
 
 #ifdef CONFIG_KVM_EXIT_TIMING
 	/* save enter time */
diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
index d8067fd..64949ee 100644
--- a/arch/powerpc/kvm/e500.c
+++ b/arch/powerpc/kvm/e500.c
@@ -60,9 +60,6 @@ int kvmppc_core_vcpu_setup(struct kvm_vcpu *vcpu)
 
 	kvmppc_e500_tlb_setup(vcpu_e500);
 
-	/* Use the same core vertion as host's */
-	vcpu->arch.pvr = mfspr(SPRN_PVR);
-
 	return 0;
 }
 
@@ -132,7 +129,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 	kmem_cache_free(kvm_vcpu_cache, vcpu_e500);
 }
 
-static int kvmppc_e500_init(void)
+static int __init kvmppc_e500_init(void)
 {
 	int r, i;
 	unsigned long ivor[3];
@@ -160,7 +157,7 @@ static int kvmppc_e500_init(void)
 	return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
 }
 
-static void kvmppc_e500_exit(void)
+static void __init kvmppc_e500_exit(void)
 {
 	kvmppc_booke_exit();
 }
diff --git a/arch/powerpc/kvm/e500_emulate.c b/arch/powerpc/kvm/e500_emulate.c
index 3f76041..be95b8d 100644
--- a/arch/powerpc/kvm/e500_emulate.c
+++ b/arch/powerpc/kvm/e500_emulate.c
@@ -180,6 +180,9 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
 	case SPRN_MMUCSR0:
 		vcpu->arch.gpr[rt] = 0; break;
 
+	case SPRN_MMUCFG:
+		vcpu->arch.gpr[rt] = mfspr(SPRN_MMUCFG); break;
+
 	/* extra exceptions */
 	case SPRN_IVOR32:
 		vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index 0e773fc..fb1e1dc 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -22,6 +22,7 @@
 
 #include "../mm/mmu_decl.h"
 #include "e500_tlb.h"
+#include "trace.h"
 
 #define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
 
@@ -224,9 +225,8 @@ static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
 
 	kvmppc_e500_shadow_release(vcpu_e500, tlbsel, esel);
 	stlbe->mas1 = 0;
-	KVMTRACE_5D(STLB_INVAL, &vcpu_e500->vcpu, index_of(tlbsel, esel),
-			stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7,
-			handler);
+	trace_kvm_stlb_inval(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
+			     stlbe->mas3, stlbe->mas7);
 }
 
 static void kvmppc_e500_tlb1_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
@@ -269,7 +269,7 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
 	tlbsel = (vcpu_e500->mas4 >> 28) & 0x1;
 	victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0;
 	pidsel = (vcpu_e500->mas4 >> 16) & 0xf;
-	tsized = (vcpu_e500->mas4 >> 8) & 0xf;
+	tsized = (vcpu_e500->mas4 >> 7) & 0x1f;
 
 	vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
 		| MAS0_NV(vcpu_e500->guest_tlb_nv[tlbsel]);
@@ -309,7 +309,7 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
 	vcpu_e500->shadow_pages[tlbsel][esel] = new_page;
 
 	/* Force TS=1 IPROT=0 TSIZE=4KB for all guest mappings. */
-	stlbe->mas1 = MAS1_TSIZE(BOOKE_PAGESZ_4K)
+	stlbe->mas1 = MAS1_TSIZE(BOOK3E_PAGESZ_4K)
 		| MAS1_TID(get_tlb_tid(gtlbe)) | MAS1_TS | MAS1_VALID;
 	stlbe->mas2 = (gvaddr & MAS2_EPN)
 		| e500_shadow_mas2_attrib(gtlbe->mas2,
@@ -319,9 +319,8 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
 				vcpu_e500->vcpu.arch.msr & MSR_PR);
 	stlbe->mas7 = (hpaddr >> 32) & MAS7_RPN;
 
-	KVMTRACE_5D(STLB_WRITE, &vcpu_e500->vcpu, index_of(tlbsel, esel),
-			stlbe->mas1, stlbe->mas2, stlbe->mas3, stlbe->mas7,
-			handler);
+	trace_kvm_stlb_write(index_of(tlbsel, esel), stlbe->mas1, stlbe->mas2,
+			     stlbe->mas3, stlbe->mas7);
 }
 
 /* XXX only map the one-one case, for now use TLB0 */
@@ -535,9 +534,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
 	gtlbe->mas3 = vcpu_e500->mas3;
 	gtlbe->mas7 = vcpu_e500->mas7;
 
-	KVMTRACE_5D(GTLB_WRITE, vcpu, vcpu_e500->mas0,
-			gtlbe->mas1, gtlbe->mas2, gtlbe->mas3, gtlbe->mas7,
-			handler);
+	trace_kvm_gtlb_write(vcpu_e500->mas0, gtlbe->mas1, gtlbe->mas2,
+			     gtlbe->mas3, gtlbe->mas7);
 
 	/* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
 	if (tlbe_is_host_safe(vcpu, gtlbe)) {
@@ -545,7 +543,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
 		case 0:
 			/* TLB0 */
 			gtlbe->mas1 &= ~MAS1_TSIZE(~0);
-			gtlbe->mas1 |= MAS1_TSIZE(BOOKE_PAGESZ_4K);
+			gtlbe->mas1 |= MAS1_TSIZE(BOOK3E_PAGESZ_4K);
 
 			stlbsel = 0;
 			sesel = kvmppc_e500_stlbe_map(vcpu_e500, 0, esel);
@@ -679,14 +677,14 @@ void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
 
 	/* Insert large initial mapping for guest. */
 	tlbe = &vcpu_e500->guest_tlb[1][0];
-	tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_256M);
+	tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_256M);
 	tlbe->mas2 = 0;
 	tlbe->mas3 = E500_TLB_SUPER_PERM_MASK;
 	tlbe->mas7 = 0;
 
 	/* 4K map for serial output. Used by kernel wrapper. */
 	tlbe = &vcpu_e500->guest_tlb[1][1];
-	tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOKE_PAGESZ_4K);
+	tlbe->mas1 = MAS1_VALID | MAS1_TSIZE(BOOK3E_PAGESZ_4K);
 	tlbe->mas2 = (0xe0004500 & 0xFFFFF000) | MAS2_I | MAS2_G;
 	tlbe->mas3 = (0xe0004500 & 0xFFFFF000) | E500_TLB_SUPER_PERM_MASK;
 	tlbe->mas7 = 0;
diff --git a/arch/powerpc/kvm/e500_tlb.h b/arch/powerpc/kvm/e500_tlb.h
index 45b064b..d28e301 100644
--- a/arch/powerpc/kvm/e500_tlb.h
+++ b/arch/powerpc/kvm/e500_tlb.h
@@ -16,7 +16,7 @@
 #define __KVM_E500_TLB_H__
 
 #include <linux/kvm_host.h>
-#include <asm/mmu-fsl-booke.h>
+#include <asm/mmu-book3e.h>
 #include <asm/tlb.h>
 #include <asm/kvm_e500.h>
 
@@ -59,7 +59,7 @@ extern void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *);
 /* TLB helper functions */
 static inline unsigned int get_tlb_size(const struct tlbe *tlbe)
 {
-	return (tlbe->mas1 >> 8) & 0xf;
+	return (tlbe->mas1 >> 7) & 0x1f;
 }
 
 static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
@@ -70,7 +70,7 @@ static inline gva_t get_tlb_eaddr(const struct tlbe *tlbe)
 static inline u64 get_tlb_bytes(const struct tlbe *tlbe)
 {
 	unsigned int pgsize = get_tlb_size(tlbe);
-	return 1ULL << 10 << (pgsize << 1);
+	return 1ULL << 10 << pgsize;
 }
 
 static inline gva_t get_tlb_end(const struct tlbe *tlbe)
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index a561d6e..7737146 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -29,6 +29,7 @@
 #include <asm/kvm_ppc.h>
 #include <asm/disassemble.h>
 #include "timing.h"
+#include "trace.h"
 
 #define OP_TRAP 3
 
@@ -187,7 +188,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
 			case SPRN_SRR1:
 				vcpu->arch.gpr[rt] = vcpu->arch.srr1; break;
 			case SPRN_PVR:
-				vcpu->arch.gpr[rt] = vcpu->arch.pvr; break;
+				vcpu->arch.gpr[rt] = mfspr(SPRN_PVR); break;
+			case SPRN_PIR:
+				vcpu->arch.gpr[rt] = mfspr(SPRN_PIR); break;
 
 			/* Note: mftb and TBRL/TBWL are user-accessible, so
 			 * the guest can always access the real TB anyways.
@@ -417,7 +420,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
 		}
 	}
 
-	KVMTRACE_3D(PPC_INSTR, vcpu, inst, (int)vcpu->arch.pc, emulated, entryexit);
+	trace_kvm_ppc_instr(inst, vcpu->arch.pc, emulated);
 
 	if (advance)
 		vcpu->arch.pc += 4; /* Advance past emulated instruction. */
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 2cf915e..2a4551f 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -31,25 +31,17 @@
 #include "timing.h"
 #include "../mm/mmu_decl.h"
 
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
 gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
 {
 	return gfn;
 }
 
-int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
-{
-	return !!(v->arch.pending_exceptions);
-}
-
-int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
-{
-	/* do real check here */
-	return 1;
-}
-
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
-	return !(v->arch.msr & MSR_WE);
+	return !(v->arch.msr & MSR_WE) || !!(v->arch.pending_exceptions);
 }
 
 
@@ -122,13 +114,17 @@ struct kvm *kvm_arch_create_vm(void)
 static void kvmppc_free_vcpus(struct kvm *kvm)
 {
 	unsigned int i;
+	struct kvm_vcpu *vcpu;
 
-	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		if (kvm->vcpus[i]) {
-			kvm_arch_vcpu_free(kvm->vcpus[i]);
-			kvm->vcpus[i] = NULL;
-		}
-	}
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		kvm_arch_vcpu_free(vcpu);
+
+	mutex_lock(&kvm->lock);
+	for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
+		kvm->vcpus[i] = NULL;
+
+	atomic_set(&kvm->online_vcpus, 0);
+	mutex_unlock(&kvm->lock);
 }
 
 void kvm_arch_sync_events(struct kvm *kvm)
diff --git a/arch/powerpc/kvm/trace.h b/arch/powerpc/kvm/trace.h
new file mode 100644
index 0000000..67f219d
--- /dev/null
+++ b/arch/powerpc/kvm/trace.h
@@ -0,0 +1,104 @@
+#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace
+
+/*
+ * Tracepoint for guest mode entry.
+ */
+TRACE_EVENT(kvm_ppc_instr,
+	TP_PROTO(unsigned int inst, unsigned long pc, unsigned int emulate),
+	TP_ARGS(inst, pc, emulate),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	inst		)
+		__field(	unsigned long,	pc		)
+		__field(	unsigned int,	emulate		)
+	),
+
+	TP_fast_assign(
+		__entry->inst		= inst;
+		__entry->pc		= pc;
+		__entry->emulate	= emulate;
+	),
+
+	TP_printk("inst %u pc 0x%lx emulate %u\n",
+		  __entry->inst, __entry->pc, __entry->emulate)
+);
+
+TRACE_EVENT(kvm_stlb_inval,
+	TP_PROTO(unsigned int stlb_index),
+	TP_ARGS(stlb_index),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	stlb_index	)
+	),
+
+	TP_fast_assign(
+		__entry->stlb_index	= stlb_index;
+	),
+
+	TP_printk("stlb_index %u", __entry->stlb_index)
+);
+
+TRACE_EVENT(kvm_stlb_write,
+	TP_PROTO(unsigned int victim, unsigned int tid, unsigned int word0,
+		 unsigned int word1, unsigned int word2),
+	TP_ARGS(victim, tid, word0, word1, word2),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	victim		)
+		__field(	unsigned int,	tid		)
+		__field(	unsigned int,	word0		)
+		__field(	unsigned int,	word1		)
+		__field(	unsigned int,	word2		)
+	),
+
+	TP_fast_assign(
+		__entry->victim		= victim;
+		__entry->tid		= tid;
+		__entry->word0		= word0;
+		__entry->word1		= word1;
+		__entry->word2		= word2;
+	),
+
+	TP_printk("victim %u tid %u w0 %u w1 %u w2 %u",
+		__entry->victim, __entry->tid, __entry->word0,
+		__entry->word1, __entry->word2)
+);
+
+TRACE_EVENT(kvm_gtlb_write,
+	TP_PROTO(unsigned int gtlb_index, unsigned int tid, unsigned int word0,
+		 unsigned int word1, unsigned int word2),
+	TP_ARGS(gtlb_index, tid, word0, word1, word2),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	gtlb_index	)
+		__field(	unsigned int,	tid		)
+		__field(	unsigned int,	word0		)
+		__field(	unsigned int,	word1		)
+		__field(	unsigned int,	word2		)
+	),
+
+	TP_fast_assign(
+		__entry->gtlb_index	= gtlb_index;
+		__entry->tid		= tid;
+		__entry->word0		= word0;
+		__entry->word1		= word1;
+		__entry->word2		= word2;
+	),
+
+	TP_printk("gtlb_index %u tid %u w0 %u w1 %u w2 %u",
+		__entry->gtlb_index, __entry->tid, __entry->word0,
+		__entry->word1, __entry->word2)
+);
+
+#endif /* _TRACE_KVM_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index 29954dc..f5e7b9c 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -105,7 +105,7 @@ unsigned long __init mmu_mapin_ram(void)
 
 	while (s >= LARGE_PAGE_SIZE_16M) {
 		pmd_t *pmdp;
-		unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+		unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_HWWRITE;
 
 		pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
 		pmd_val(*pmdp++) = val;
@@ -120,7 +120,7 @@ unsigned long __init mmu_mapin_ram(void)
 
 	while (s >= LARGE_PAGE_SIZE_4M) {
 		pmd_t *pmdp;
-		unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
+		unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_HWWRITE;
 
 		pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v);
 		pmd_val(*pmdp) = val;
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 3e68363..6fb8fc8 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -13,6 +13,7 @@ obj-y				:= fault.o mem.o pgtable.o gup.o \
 				   pgtable_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC_MMU_NOHASH)	+= mmu_context_nohash.o tlb_nohash.o \
 				   tlb_nohash_low.o
+obj-$(CONFIG_PPC_BOOK3E)	+= tlb_low_$(CONFIG_WORD_SIZE)e.o
 obj-$(CONFIG_PPC64)		+= mmap_64.o
 hash64-$(CONFIG_PPC_NATIVE)	:= hash_native_64.o
 obj-$(CONFIG_PPC_STD_MMU_64)	+= hash_utils_64.o \
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 830bef0..e7dae82 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -29,7 +29,7 @@
 #include <linux/module.h>
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 
 #include <asm/firmware.h>
 #include <asm/page.h>
@@ -171,7 +171,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
 		die("Weird page fault", regs, SIGSEGV);
 	}
 
-	perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
 	/* When running in the kernel we expect faults to occur only to
 	 * addresses in user space.  All other faults represent errors in the
@@ -312,7 +312,7 @@ good_area:
 	}
 	if (ret & VM_FAULT_MAJOR) {
 		current->maj_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
 				     regs, address);
 #ifdef CONFIG_PPC_SMLPAR
 		if (firmware_has_feature(FW_FEATURE_CMO)) {
@@ -323,7 +323,7 @@ good_area:
 #endif
 	} else {
 		current->min_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
 	up_read(&mm->mmap_sem);
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index bb3d659..dc93e95 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -161,7 +161,7 @@ unsigned long __init mmu_mapin_ram(void)
 	unsigned long virt = PAGE_OFFSET;
 	phys_addr_t phys = memstart_addr;
 
-	while (cam[tlbcam_index] && tlbcam_index < ARRAY_SIZE(cam)) {
+	while (tlbcam_index < ARRAY_SIZE(cam) && cam[tlbcam_index]) {
 		settlbcam(tlbcam_index, virt, phys, cam[tlbcam_index], PAGE_KERNEL_X, 0);
 		virt += cam[tlbcam_index];
 		phys += cam[tlbcam_index];
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
index 14af8ce..b13d589 100644
--- a/arch/powerpc/mm/hash_low_32.S
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -40,7 +40,7 @@ mmu_hash_lock:
  * The address is in r4, and r3 contains an access flag:
  * _PAGE_RW (0x400) if a write.
  * r9 contains the SRR1 value, from which we use the MSR_PR bit.
- * SPRG3 contains the physical address of the current task's thread.
+ * SPRG_THREAD contains the physical address of the current task's thread.
  *
  * Returns to the caller if the access is illegal or there is no
  * mapping for the address.  Otherwise it places an appropriate PTE
@@ -68,7 +68,7 @@ _GLOBAL(hash_page)
 	/* Get PTE (linux-style) and check access */
 	lis	r0,KERNELBASE@h		/* check if kernel address */
 	cmplw	0,r4,r0
-	mfspr	r8,SPRN_SPRG3		/* current task's THREAD (phys) */
+	mfspr	r8,SPRN_SPRG_THREAD	/* current task's THREAD (phys) */
 	ori	r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */
 	lwz	r5,PGDIR(r8)		/* virt page-table root */
 	blt+	112f			/* assume user more likely */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index c46ef2f..90df6ff 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -57,8 +57,10 @@ unsigned int mmu_huge_psizes[MMU_PAGE_COUNT] = { }; /* initialize all to 0 */
 #define HUGEPTE_CACHE_NAME(psize)	(huge_pgtable_cache_name[psize])
 
 static const char *huge_pgtable_cache_name[MMU_PAGE_COUNT] = {
-	"unused_4K", "hugepte_cache_64K", "unused_64K_AP",
-	"hugepte_cache_1M", "hugepte_cache_16M", "hugepte_cache_16G"
+	[MMU_PAGE_64K]	= "hugepte_cache_64K",
+	[MMU_PAGE_1M]	= "hugepte_cache_1M",
+	[MMU_PAGE_16M]	= "hugepte_cache_16M",
+	[MMU_PAGE_16G]	= "hugepte_cache_16G",
 };
 
 /* Flag to mark huge PD pointers.  This means pmd_bad() and pud_bad()
@@ -700,6 +702,8 @@ static void __init set_huge_psize(int psize)
 		if (mmu_huge_psizes[psize] ||
 		   mmu_psize_defs[psize].shift == PAGE_SHIFT)
 			return;
+		if (WARN_ON(HUGEPTE_CACHE_NAME(psize) == NULL))
+			return;
 		hugetlb_add_hstate(mmu_psize_defs[psize].shift - PAGE_SHIFT);
 
 		switch (mmu_psize_defs[psize].shift) {
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 3de6a0d..3ef5084 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -54,8 +54,6 @@
 #endif
 #define MAX_LOW_MEM	CONFIG_LOWMEM_SIZE
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 phys_addr_t total_memory;
 phys_addr_t total_lowmem;
 
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 68a821a..3158232 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -205,6 +205,47 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size)
 	return 0;
 }
 
+/* On hash-based CPUs, the vmemmap is bolted in the hash table.
+ *
+ * On Book3E CPUs, the vmemmap is currently mapped in the top half of
+ * the vmalloc space using normal page tables, though the size of
+ * pages encoded in the PTEs can be different
+ */
+
+#ifdef CONFIG_PPC_BOOK3E
+static void __meminit vmemmap_create_mapping(unsigned long start,
+					     unsigned long page_size,
+					     unsigned long phys)
+{
+	/* Create a PTE encoding without page size */
+	unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED |
+		_PAGE_KERNEL_RW;
+
+	/* PTEs only contain page size encodings up to 32M */
+	BUG_ON(mmu_psize_defs[mmu_vmemmap_psize].enc > 0xf);
+
+	/* Encode the size in the PTE */
+	flags |= mmu_psize_defs[mmu_vmemmap_psize].enc << 8;
+
+	/* For each PTE for that area, map things. Note that we don't
+	 * increment phys because all PTEs are of the large size and
+	 * thus must have the low bits clear
+	 */
+	for (i = 0; i < page_size; i += PAGE_SIZE)
+		BUG_ON(map_kernel_page(start + i, phys, flags));
+}
+#else /* CONFIG_PPC_BOOK3E */
+static void __meminit vmemmap_create_mapping(unsigned long start,
+					     unsigned long page_size,
+					     unsigned long phys)
+{
+	int  mapped = htab_bolt_mapping(start, start + page_size, phys,
+					PAGE_KERNEL, mmu_vmemmap_psize,
+					mmu_kernel_ssize);
+	BUG_ON(mapped < 0);
+}
+#endif /* CONFIG_PPC_BOOK3E */
+
 int __meminit vmemmap_populate(struct page *start_page,
 			       unsigned long nr_pages, int node)
 {
@@ -215,8 +256,11 @@ int __meminit vmemmap_populate(struct page *start_page,
 	/* Align to the page size of the linear mapping. */
 	start = _ALIGN_DOWN(start, page_size);
 
+	pr_debug("vmemmap_populate page %p, %ld pages, node %d\n",
+		 start_page, nr_pages, node);
+	pr_debug(" -> map %lx..%lx\n", start, end);
+
 	for (; start < end; start += page_size) {
-		int mapped;
 		void *p;
 
 		if (vmemmap_populated(start, page_size))
@@ -226,13 +270,10 @@ int __meminit vmemmap_populate(struct page *start_page,
 		if (!p)
 			return -ENOMEM;
 
-		pr_debug("vmemmap %08lx allocated at %p, physical %08lx.\n",
-			start, p, __pa(p));
+		pr_debug("      * %016lx..%016lx allocated at %p\n",
+			 start, start + page_size, p);
 
-		mapped = htab_bolt_mapping(start, start + page_size, __pa(p),
-					   pgprot_val(PAGE_KERNEL),
-					   mmu_vmemmap_psize, mmu_kernel_ssize);
-		BUG_ON(mapped < 0);
+		vmemmap_create_mapping(start, page_size, __pa(p));
 	}
 
 	return 0;
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c
index b1a727d..c2f93dc 100644
--- a/arch/powerpc/mm/mmu_context_nohash.c
+++ b/arch/powerpc/mm/mmu_context_nohash.c
@@ -25,10 +25,20 @@
  *     also clear mm->cpu_vm_mask bits when processes are migrated
  */
 
-#undef DEBUG
-#define DEBUG_STEAL_ONLY
-#undef DEBUG_MAP_CONSISTENCY
-/*#define DEBUG_CLAMP_LAST_CONTEXT   15 */
+#define DEBUG_MAP_CONSISTENCY
+#define DEBUG_CLAMP_LAST_CONTEXT   31
+//#define DEBUG_HARDER
+
+/* We don't use DEBUG because it tends to be compiled in always nowadays
+ * and this would generate way too much output
+ */
+#ifdef DEBUG_HARDER
+#define pr_hard(args...)	printk(KERN_DEBUG args)
+#define pr_hardcont(args...)	printk(KERN_CONT args)
+#else
+#define pr_hard(args...)	do { } while(0)
+#define pr_hardcont(args...)	do { } while(0)
+#endif
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -71,7 +81,7 @@ static DEFINE_SPINLOCK(context_lock);
 static unsigned int steal_context_smp(unsigned int id)
 {
 	struct mm_struct *mm;
-	unsigned int cpu, max;
+	unsigned int cpu, max, i;
 
 	max = last_context - first_context;
 
@@ -89,15 +99,22 @@ static unsigned int steal_context_smp(unsigned int id)
 				id = first_context;
 			continue;
 		}
-		pr_devel("[%d] steal context %d from mm @%p\n",
-			 smp_processor_id(), id, mm);
+		pr_hardcont(" | steal %d from 0x%p", id, mm);
 
 		/* Mark this mm has having no context anymore */
 		mm->context.id = MMU_NO_CONTEXT;
 
-		/* Mark it stale on all CPUs that used this mm */
-		for_each_cpu(cpu, mm_cpumask(mm))
-			__set_bit(id, stale_map[cpu]);
+		/* Mark it stale on all CPUs that used this mm. For threaded
+		 * implementations, we set it on all threads on each core
+		 * represented in the mask. A future implementation will use
+		 * a core map instead but this will do for now.
+		 */
+		for_each_cpu(cpu, mm_cpumask(mm)) {
+			for (i = cpu_first_thread_in_core(cpu);
+			     i <= cpu_last_thread_in_core(cpu); i++)
+				__set_bit(id, stale_map[i]);
+			cpu = i - 1;
+		}
 		return id;
 	}
 
@@ -126,7 +143,7 @@ static unsigned int steal_context_up(unsigned int id)
 	/* Pick up the victim mm */
 	mm = context_mm[id];
 
-	pr_devel("[%d] steal context %d from mm @%p\n", cpu, id, mm);
+	pr_hardcont(" | steal %d from 0x%p", id, mm);
 
 	/* Flush the TLB for that context */
 	local_flush_tlb_mm(mm);
@@ -173,25 +190,20 @@ static void context_check_map(void) { }
 
 void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
 {
-	unsigned int id, cpu = smp_processor_id();
+	unsigned int i, id, cpu = smp_processor_id();
 	unsigned long *map;
 
 	/* No lockless fast path .. yet */
 	spin_lock(&context_lock);
 
-#ifndef DEBUG_STEAL_ONLY
-	pr_devel("[%d] activating context for mm @%p, active=%d, id=%d\n",
-		 cpu, next, next->context.active, next->context.id);
-#endif
+	pr_hard("[%d] activating context for mm @%p, active=%d, id=%d",
+		cpu, next, next->context.active, next->context.id);
 
 #ifdef CONFIG_SMP
 	/* Mark us active and the previous one not anymore */
 	next->context.active++;
 	if (prev) {
-#ifndef DEBUG_STEAL_ONLY
-		pr_devel(" old context %p active was: %d\n",
-			 prev, prev->context.active);
-#endif
+		pr_hardcont(" (old=0x%p a=%d)", prev, prev->context.active);
 		WARN_ON(prev->context.active < 1);
 		prev->context.active--;
 	}
@@ -201,8 +213,14 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
 
 	/* If we already have a valid assigned context, skip all that */
 	id = next->context.id;
-	if (likely(id != MMU_NO_CONTEXT))
+	if (likely(id != MMU_NO_CONTEXT)) {
+#ifdef DEBUG_MAP_CONSISTENCY
+		if (context_mm[id] != next)
+			pr_err("MMU: mm 0x%p has id %d but context_mm[%d] says 0x%p\n",
+			       next, id, id, context_mm[id]);
+#endif
 		goto ctxt_ok;
+	}
 
 	/* We really don't have a context, let's try to acquire one */
 	id = next_context;
@@ -235,11 +253,7 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
 	next_context = id + 1;
 	context_mm[id] = next;
 	next->context.id = id;
-
-#ifndef DEBUG_STEAL_ONLY
-	pr_devel("[%d] picked up new id %d, nrf is now %d\n",
-		 cpu, id, nr_free_contexts);
-#endif
+	pr_hardcont(" | new id=%d,nrf=%d", id, nr_free_contexts);
 
 	context_check_map();
  ctxt_ok:
@@ -248,15 +262,21 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
 	 * local TLB for it and unmark it before we use it
 	 */
 	if (test_bit(id, stale_map[cpu])) {
-		pr_devel("[%d] flushing stale context %d for mm @%p !\n",
-			 cpu, id, next);
+		pr_hardcont(" | stale flush %d [%d..%d]",
+			    id, cpu_first_thread_in_core(cpu),
+			    cpu_last_thread_in_core(cpu));
+
 		local_flush_tlb_mm(next);
 
 		/* XXX This clear should ultimately be part of local_flush_tlb_mm */
-		__clear_bit(id, stale_map[cpu]);
+		for (i = cpu_first_thread_in_core(cpu);
+		     i <= cpu_last_thread_in_core(cpu); i++) {
+			__clear_bit(id, stale_map[i]);
+		}
 	}
 
 	/* Flick the MMU and release lock */
+	pr_hardcont(" -> %d\n", id);
 	set_context(id, next->pgd);
 	spin_unlock(&context_lock);
 }
@@ -266,6 +286,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
  */
 int init_new_context(struct task_struct *t, struct mm_struct *mm)
 {
+	pr_hard("initing context for mm @%p\n", mm);
+
 	mm->context.id = MMU_NO_CONTEXT;
 	mm->context.active = 0;
 
@@ -305,7 +327,9 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
 					    unsigned long action, void *hcpu)
 {
 	unsigned int cpu = (unsigned int)(long)hcpu;
-
+#ifdef CONFIG_HOTPLUG_CPU
+	struct task_struct *p;
+#endif
 	/* We don't touch CPU 0 map, it's allocated at aboot and kept
 	 * around forever
 	 */
@@ -324,8 +348,16 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self,
 		pr_devel("MMU: Freeing stale context map for CPU %d\n", cpu);
 		kfree(stale_map[cpu]);
 		stale_map[cpu] = NULL;
-		break;
-#endif
+
+		/* We also clear the cpu_vm_mask bits of CPUs going away */
+		read_lock(&tasklist_lock);
+		for_each_process(p) {
+			if (p->mm)
+				cpu_mask_clear_cpu(cpu, mm_cpumask(p->mm));
+		}
+		read_unlock(&tasklist_lock);
+	break;
+#endif /* CONFIG_HOTPLUG_CPU */
 	}
 	return NOTIFY_OK;
 }
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index d1f9c62..d2e5321 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -36,21 +36,37 @@ static inline void _tlbil_pid(unsigned int pid)
 {
 	asm volatile ("sync; tlbia; isync" : : : "memory");
 }
+#define _tlbil_pid_noind(pid)	_tlbil_pid(pid)
+
 #else /* CONFIG_40x || CONFIG_8xx */
 extern void _tlbil_all(void);
 extern void _tlbil_pid(unsigned int pid);
+#ifdef CONFIG_PPC_BOOK3E
+extern void _tlbil_pid_noind(unsigned int pid);
+#else
+#define _tlbil_pid_noind(pid)	_tlbil_pid(pid)
+#endif
 #endif /* !(CONFIG_40x || CONFIG_8xx) */
 
 /*
  * On 8xx, we directly inline tlbie, on others, it's extern
  */
 #ifdef CONFIG_8xx
-static inline void _tlbil_va(unsigned long address, unsigned int pid)
+static inline void _tlbil_va(unsigned long address, unsigned int pid,
+			     unsigned int tsize, unsigned int ind)
 {
 	asm volatile ("tlbie %0; sync" : : "r" (address) : "memory");
 }
-#else /* CONFIG_8xx */
-extern void _tlbil_va(unsigned long address, unsigned int pid);
+#elif defined(CONFIG_PPC_BOOK3E)
+extern void _tlbil_va(unsigned long address, unsigned int pid,
+		      unsigned int tsize, unsigned int ind);
+#else
+extern void __tlbil_va(unsigned long address, unsigned int pid);
+static inline void _tlbil_va(unsigned long address, unsigned int pid,
+			     unsigned int tsize, unsigned int ind)
+{
+	__tlbil_va(address, pid);
+}
 #endif /* CONIFG_8xx */
 
 /*
@@ -58,10 +74,16 @@ extern void _tlbil_va(unsigned long address, unsigned int pid);
  * implementation. When that becomes the case, this will be
  * an extern.
  */
-static inline void _tlbivax_bcast(unsigned long address, unsigned int pid)
+#ifdef CONFIG_PPC_BOOK3E
+extern void _tlbivax_bcast(unsigned long address, unsigned int pid,
+			   unsigned int tsize, unsigned int ind);
+#else
+static inline void _tlbivax_bcast(unsigned long address, unsigned int pid,
+				   unsigned int tsize, unsigned int ind)
 {
 	BUG();
 }
+#endif
 
 #else /* CONFIG_PPC_MMU_NOHASH */
 
@@ -99,7 +121,12 @@ extern unsigned int rtas_data, rtas_size;
 struct hash_pte;
 extern struct hash_pte *Hash, *Hash_end;
 extern unsigned long Hash_size, Hash_mask;
-#endif
+
+#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_PPC64
+extern int map_kernel_page(unsigned long ea, unsigned long pa, int flags);
+#endif /* CONFIG_PPC64 */
 
 extern unsigned long ioremap_bot;
 extern unsigned long __max_low_memory;
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 627767d..83f1551 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -30,6 +30,16 @@
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
 
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+#ifdef CONFIG_SMP
+
+/*
+ * Handle batching of page table freeing on SMP. Page tables are
+ * queued up and send to be freed later by RCU in order to avoid
+ * freeing a page table page that is being walked without locks
+ */
+
 static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
 static unsigned long pte_freelist_forced_free;
 
@@ -116,27 +126,7 @@ void pte_free_finish(void)
 	*batchp = NULL;
 }
 
-/*
- * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
- */
-static pte_t do_dcache_icache_coherency(pte_t pte)
-{
-	unsigned long pfn = pte_pfn(pte);
-	struct page *page;
-
-	if (unlikely(!pfn_valid(pfn)))
-		return pte;
-	page = pfn_to_page(pfn);
-
-	if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
-		pr_devel("do_dcache_icache_coherency... flushing\n");
-		flush_dcache_icache_page(page);
-		set_bit(PG_arch_1, &page->flags);
-	}
-	else
-		pr_devel("do_dcache_icache_coherency... already clean\n");
-	return __pte(pte_val(pte) | _PAGE_HWEXEC);
-}
+#endif /* CONFIG_SMP */
 
 static inline int is_exec_fault(void)
 {
@@ -145,49 +135,139 @@ static inline int is_exec_fault(void)
 
 /* We only try to do i/d cache coherency on stuff that looks like
  * reasonably "normal" PTEs. We currently require a PTE to be present
- * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE
+ * and we avoid _PAGE_SPECIAL and _PAGE_NO_CACHE. We also only do that
+ * on userspace PTEs
  */
 static inline int pte_looks_normal(pte_t pte)
 {
 	return (pte_val(pte) &
-		(_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE)) ==
-		(_PAGE_PRESENT);
+	    (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER)) ==
+	    (_PAGE_PRESENT | _PAGE_USER);
 }
 
-#if defined(CONFIG_PPC_STD_MMU)
+struct page * maybe_pte_to_page(pte_t pte)
+{
+	unsigned long pfn = pte_pfn(pte);
+	struct page *page;
+
+	if (unlikely(!pfn_valid(pfn)))
+		return NULL;
+	page = pfn_to_page(pfn);
+	if (PageReserved(page))
+		return NULL;
+	return page;
+}
+
+#if defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0
+
 /* Server-style MMU handles coherency when hashing if HW exec permission
- * is supposed per page (currently 64-bit only). Else, we always flush
- * valid PTEs in set_pte.
+ * is supposed per page (currently 64-bit only). If not, then, we always
+ * flush the cache for valid PTEs in set_pte. Embedded CPU without HW exec
+ * support falls into the same category.
  */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+
+static pte_t set_pte_filter(pte_t pte)
 {
-	return set_pte && pte_looks_normal(pte) &&
-		!(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
-		  cpu_has_feature(CPU_FTR_NOEXECUTE));
+	pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
+	if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
+				       cpu_has_feature(CPU_FTR_NOEXECUTE))) {
+		struct page *pg = maybe_pte_to_page(pte);
+		if (!pg)
+			return pte;
+		if (!test_bit(PG_arch_1, &pg->flags)) {
+			flush_dcache_icache_page(pg);
+			set_bit(PG_arch_1, &pg->flags);
+		}
+	}
+	return pte;
 }
-#elif _PAGE_HWEXEC == 0
-/* Embedded type MMU without HW exec support (8xx only so far), we flush
- * the cache for any present PTE
- */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
+				     int dirty)
 {
-	return set_pte && pte_looks_normal(pte);
+	return pte;
 }
-#else
-/* Other embedded CPUs with HW exec support per-page, we flush on exec
- * fault if HWEXEC is not set
+
+#else /* defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0 */
+
+/* Embedded type MMU with HW exec support. This is a bit more complicated
+ * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
+ * instead we "filter out" the exec permission for non clean pages.
  */
-static inline int pte_need_exec_flush(pte_t pte, int set_pte)
+static pte_t set_pte_filter(pte_t pte)
 {
-	return pte_looks_normal(pte) && is_exec_fault() &&
-		!(pte_val(pte) & _PAGE_HWEXEC);
+	struct page *pg;
+
+	/* No exec permission in the first place, move on */
+	if (!(pte_val(pte) & _PAGE_EXEC) || !pte_looks_normal(pte))
+		return pte;
+
+	/* If you set _PAGE_EXEC on weird pages you're on your own */
+	pg = maybe_pte_to_page(pte);
+	if (unlikely(!pg))
+		return pte;
+
+	/* If the page clean, we move on */
+	if (test_bit(PG_arch_1, &pg->flags))
+		return pte;
+
+	/* If it's an exec fault, we flush the cache and make it clean */
+	if (is_exec_fault()) {
+		flush_dcache_icache_page(pg);
+		set_bit(PG_arch_1, &pg->flags);
+		return pte;
+	}
+
+	/* Else, we filter out _PAGE_EXEC */
+	return __pte(pte_val(pte) & ~_PAGE_EXEC);
 }
-#endif
+
+static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
+				     int dirty)
+{
+	struct page *pg;
+
+	/* So here, we only care about exec faults, as we use them
+	 * to recover lost _PAGE_EXEC and perform I$/D$ coherency
+	 * if necessary. Also if _PAGE_EXEC is already set, same deal,
+	 * we just bail out
+	 */
+	if (dirty || (pte_val(pte) & _PAGE_EXEC) || !is_exec_fault())
+		return pte;
+
+#ifdef CONFIG_DEBUG_VM
+	/* So this is an exec fault, _PAGE_EXEC is not set. If it was
+	 * an error we would have bailed out earlier in do_page_fault()
+	 * but let's make sure of it
+	 */
+	if (WARN_ON(!(vma->vm_flags & VM_EXEC)))
+		return pte;
+#endif /* CONFIG_DEBUG_VM */
+
+	/* If you set _PAGE_EXEC on weird pages you're on your own */
+	pg = maybe_pte_to_page(pte);
+	if (unlikely(!pg))
+		goto bail;
+
+	/* If the page is already clean, we move on */
+	if (test_bit(PG_arch_1, &pg->flags))
+		goto bail;
+
+	/* Clean the page and set PG_arch_1 */
+	flush_dcache_icache_page(pg);
+	set_bit(PG_arch_1, &pg->flags);
+
+ bail:
+	return __pte(pte_val(pte) | _PAGE_EXEC);
+}
+
+#endif /* !(defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0) */
 
 /*
  * set_pte stores a linux PTE into the linux page table.
  */
-void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
+		pte_t pte)
 {
 #ifdef CONFIG_DEBUG_VM
 	WARN_ON(pte_present(*ptep));
@@ -196,9 +276,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte
 	 * this context might not have been activated yet when this
 	 * is called.
 	 */
-	pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
-	if (pte_need_exec_flush(pte, 1))
-		pte = do_dcache_icache_coherency(pte);
+	pte = set_pte_filter(pte);
 
 	/* Perform the setting of the PTE */
 	__set_pte_at(mm, addr, ptep, pte, 0);
@@ -215,8 +293,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 			  pte_t *ptep, pte_t entry, int dirty)
 {
 	int changed;
-	if (!dirty && pte_need_exec_flush(entry, 0))
-		entry = do_dcache_icache_coherency(entry);
+	entry = set_access_flags_filter(entry, vma, dirty);
 	changed = !pte_same(*(ptep), entry);
 	if (changed) {
 		if (!(vma->vm_flags & VM_HUGETLB))
@@ -242,7 +319,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
 	BUG_ON(pud_none(*pud));
 	pmd = pmd_offset(pud, addr);
 	BUG_ON(!pmd_present(*pmd));
-	BUG_ON(!spin_is_locked(pte_lockptr(mm, pmd)));
+	assert_spin_locked(pte_lockptr(mm, pmd));
 }
 #endif /* CONFIG_DEBUG_VM */
 
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 5422169..cb96cb2 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -142,7 +142,7 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
 		flags |= _PAGE_DIRTY | _PAGE_HWWRITE;
 
 	/* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
-	flags &= ~(_PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC);
+	flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
 	return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index bfa7db6..853d556 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -33,6 +33,8 @@
 #include <linux/stddef.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/lmb.h>
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
@@ -55,19 +57,36 @@
 
 unsigned long ioremap_bot = IOREMAP_BASE;
 
+
+#ifdef CONFIG_PPC_MMU_NOHASH
+static void *early_alloc_pgtable(unsigned long size)
+{
+	void *pt;
+
+	if (init_bootmem_done)
+		pt = __alloc_bootmem(size, size, __pa(MAX_DMA_ADDRESS));
+	else
+		pt = __va(lmb_alloc_base(size, size,
+					 __pa(MAX_DMA_ADDRESS)));
+	memset(pt, 0, size);
+
+	return pt;
+}
+#endif /* CONFIG_PPC_MMU_NOHASH */
+
 /*
- * map_io_page currently only called by __ioremap
- * map_io_page adds an entry to the ioremap page table
+ * map_kernel_page currently only called by __ioremap
+ * map_kernel_page adds an entry to the ioremap page table
  * and adds an entry to the HPT, possibly bolting it
  */
-static int map_io_page(unsigned long ea, unsigned long pa, int flags)
+int map_kernel_page(unsigned long ea, unsigned long pa, int flags)
 {
 	pgd_t *pgdp;
 	pud_t *pudp;
 	pmd_t *pmdp;
 	pte_t *ptep;
 
-	if (mem_init_done) {
+	if (slab_is_available()) {
 		pgdp = pgd_offset_k(ea);
 		pudp = pud_alloc(&init_mm, pgdp, ea);
 		if (!pudp)
@@ -81,6 +100,35 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
 		set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
 							  __pgprot(flags)));
 	} else {
+#ifdef CONFIG_PPC_MMU_NOHASH
+		/* Warning ! This will blow up if bootmem is not initialized
+		 * which our ppc64 code is keen to do that, we'll need to
+		 * fix it and/or be more careful
+		 */
+		pgdp = pgd_offset_k(ea);
+#ifdef PUD_TABLE_SIZE
+		if (pgd_none(*pgdp)) {
+			pudp = early_alloc_pgtable(PUD_TABLE_SIZE);
+			BUG_ON(pudp == NULL);
+			pgd_populate(&init_mm, pgdp, pudp);
+		}
+#endif /* PUD_TABLE_SIZE */
+		pudp = pud_offset(pgdp, ea);
+		if (pud_none(*pudp)) {
+			pmdp = early_alloc_pgtable(PMD_TABLE_SIZE);
+			BUG_ON(pmdp == NULL);
+			pud_populate(&init_mm, pudp, pmdp);
+		}
+		pmdp = pmd_offset(pudp, ea);
+		if (!pmd_present(*pmdp)) {
+			ptep = early_alloc_pgtable(PAGE_SIZE);
+			BUG_ON(ptep == NULL);
+			pmd_populate_kernel(&init_mm, pmdp, ptep);
+		}
+		ptep = pte_offset_kernel(pmdp, ea);
+		set_pte_at(&init_mm, ea, ptep, pfn_pte(pa >> PAGE_SHIFT,
+							  __pgprot(flags)));
+#else /* CONFIG_PPC_MMU_NOHASH */
 		/*
 		 * If the mm subsystem is not fully up, we cannot create a
 		 * linux page table entry for this mapping.  Simply bolt an
@@ -93,6 +141,7 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
 			       "memory at %016lx !\n", pa);
 			return -ENOMEM;
 		}
+#endif /* !CONFIG_PPC_MMU_NOHASH */
 	}
 	return 0;
 }
@@ -124,7 +173,7 @@ void __iomem * __ioremap_at(phys_addr_t pa, void *ea, unsigned long size,
 	WARN_ON(size & ~PAGE_MASK);
 
 	for (i = 0; i < size; i += PAGE_SIZE)
-		if (map_io_page((unsigned long)ea+i, pa+i, flags))
+		if (map_kernel_page((unsigned long)ea+i, pa+i, flags))
 			return NULL;
 
 	return (void __iomem *)ea;
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index a685652..1d98ecc 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -191,7 +191,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
 	unsigned long slbie_data = 0;
 	unsigned long pc = KSTK_EIP(tsk);
 	unsigned long stack = KSTK_ESP(tsk);
-	unsigned long unmapped_base;
+	unsigned long exec_base;
 
 	/*
 	 * We need interrupts hard-disabled here, not just soft-disabled,
@@ -227,42 +227,44 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
 
 	/*
 	 * preload some userspace segments into the SLB.
+	 * Almost all 32 and 64bit PowerPC executables are linked at
+	 * 0x10000000 so it makes sense to preload this segment.
 	 */
-	if (test_tsk_thread_flag(tsk, TIF_32BIT))
-		unmapped_base = TASK_UNMAPPED_BASE_USER32;
-	else
-		unmapped_base = TASK_UNMAPPED_BASE_USER64;
+	exec_base = 0x10000000;
 
-	if (is_kernel_addr(pc))
-		return;
-	slb_allocate(pc);
-
-	if (esids_match(pc,stack))
+	if (is_kernel_addr(pc) || is_kernel_addr(stack) ||
+	    is_kernel_addr(exec_base))
 		return;
 
-	if (is_kernel_addr(stack))
-		return;
-	slb_allocate(stack);
+	slb_allocate(pc);
 
-	if (esids_match(pc,unmapped_base) || esids_match(stack,unmapped_base))
-		return;
+	if (!esids_match(pc, stack))
+		slb_allocate(stack);
 
-	if (is_kernel_addr(unmapped_base))
-		return;
-	slb_allocate(unmapped_base);
+	if (!esids_match(pc, exec_base) &&
+	    !esids_match(stack, exec_base))
+		slb_allocate(exec_base);
 }
 
 static inline void patch_slb_encoding(unsigned int *insn_addr,
 				      unsigned int immed)
 {
-	/* Assume the instruction had a "0" immediate value, just
-	 * "or" in the new value
-	 */
-	*insn_addr |= immed;
+	*insn_addr = (*insn_addr & 0xffff0000) | immed;
 	flush_icache_range((unsigned long)insn_addr, 4+
 			   (unsigned long)insn_addr);
 }
 
+void slb_set_size(u16 size)
+{
+	extern unsigned int *slb_compare_rr_to_size;
+
+	if (mmu_slb_size == size)
+		return;
+
+	mmu_slb_size = size;
+	patch_slb_encoding(slb_compare_rr_to_size, mmu_slb_size);
+}
+
 void slb_initialize(void)
 {
 	unsigned long linear_llp, vmalloc_llp, io_llp;
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index ab5fb48..687fdda 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -31,7 +31,7 @@ struct stab_entry {
 
 #define NR_STAB_CACHE_ENTRIES 8
 static DEFINE_PER_CPU(long, stab_cache_ptr);
-static DEFINE_PER_CPU(long, stab_cache[NR_STAB_CACHE_ENTRIES]);
+static DEFINE_PER_CPU(long [NR_STAB_CACHE_ENTRIES], stab_cache);
 
 /*
  * Create a segment table entry for the given esid/vsid pair.
diff --git a/arch/powerpc/mm/tlb_hash32.c b/arch/powerpc/mm/tlb_hash32.c
index 6519058..8aaa8b7 100644
--- a/arch/powerpc/mm/tlb_hash32.c
+++ b/arch/powerpc/mm/tlb_hash32.c
@@ -71,6 +71,9 @@ void tlb_flush(struct mmu_gather *tlb)
 		 */
 		_tlbia();
 	}
+
+	/* Push out batch of freed page tables */
+	pte_free_finish();
 }
 
 /*
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
index 937eb90..2b2f35f 100644
--- a/arch/powerpc/mm/tlb_hash64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -33,11 +33,6 @@
 
 DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
 
-/* This is declared as we are using the more or less generic
- * arch/powerpc/include/asm/tlb.h file -- tgall
- */
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /*
  * A linux PTE was changed and the corresponding hash table entry
  * neesd to be flushed. This function will either perform the flush
@@ -154,6 +149,21 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
 	batch->index = 0;
 }
 
+void tlb_flush(struct mmu_gather *tlb)
+{
+	struct ppc64_tlb_batch *tlbbatch = &__get_cpu_var(ppc64_tlb_batch);
+
+	/* If there's a TLB batch pending, then we must flush it because the
+	 * pages are going to be freed and we really don't want to have a CPU
+	 * access a freed page because it has a stale TLB
+	 */
+	if (tlbbatch->index)
+		__flush_tlb_pending(tlbbatch);
+
+	/* Push out batch of freed page tables */
+	pte_free_finish();
+}
+
 /**
  * __flush_hash_table_range - Flush all HPTEs for a given address range
  *                            from the hash table (and the TLB). But keeps
diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S
new file mode 100644
index 0000000..ef1cccf
--- /dev/null
+++ b/arch/powerpc/mm/tlb_low_64e.S
@@ -0,0 +1,770 @@
+/*
+ *  Low leve TLB miss handlers for Book3E
+ *
+ *  Copyright (C) 2008-2009
+ *      Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/processor.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+#include <asm/pgtable.h>
+#include <asm/reg.h>
+#include <asm/exception-64e.h>
+#include <asm/ppc-opcode.h>
+
+#ifdef CONFIG_PPC_64K_PAGES
+#define VPTE_PMD_SHIFT	(PTE_INDEX_SIZE+1)
+#else
+#define VPTE_PMD_SHIFT	(PTE_INDEX_SIZE)
+#endif
+#define VPTE_PUD_SHIFT	(VPTE_PMD_SHIFT + PMD_INDEX_SIZE)
+#define VPTE_PGD_SHIFT	(VPTE_PUD_SHIFT + PUD_INDEX_SIZE)
+#define VPTE_INDEX_SIZE (VPTE_PGD_SHIFT + PGD_INDEX_SIZE)
+
+
+/**********************************************************************
+ *                                                                    *
+ * TLB miss handling for Book3E with TLB reservation and HES support  *
+ *                                                                    *
+ **********************************************************************/
+
+
+/* Data TLB miss */
+	START_EXCEPTION(data_tlb_miss)
+	TLB_MISS_PROLOG
+
+	/* Now we handle the fault proper. We only save DEAR in normal
+	 * fault case since that's the only interesting values here.
+	 * We could probably also optimize by not saving SRR0/1 in the
+	 * linear mapping case but I'll leave that for later
+	 */
+	mfspr	r14,SPRN_ESR
+	mfspr	r16,SPRN_DEAR		/* get faulting address */
+	srdi	r15,r16,60		/* get region */
+	cmpldi	cr0,r15,0xc		/* linear mapping ? */
+	TLB_MISS_STATS_SAVE_INFO
+	beq	tlb_load_linear		/* yes -> go to linear map load */
+
+	/* The page tables are mapped virtually linear. At this point, though,
+	 * we don't know whether we are trying to fault in a first level
+	 * virtual address or a virtual page table address. We can get that
+	 * from bit 0x1 of the region ID which we have set for a page table
+	 */
+	andi.	r10,r15,0x1
+	bne-	virt_page_table_tlb_miss
+
+	std	r14,EX_TLB_ESR(r12);	/* save ESR */
+	std	r16,EX_TLB_DEAR(r12);	/* save DEAR */
+
+	 /* We need _PAGE_PRESENT and  _PAGE_ACCESSED set */
+	li	r11,_PAGE_PRESENT
+	oris	r11,r11,_PAGE_ACCESSED@h
+
+	/* We do the user/kernel test for the PID here along with the RW test
+	 */
+	cmpldi	cr0,r15,0		/* Check for user region */
+
+	/* We pre-test some combination of permissions to avoid double
+	 * faults:
+	 *
+	 * We move the ESR:ST bit into the position of _PAGE_BAP_SW in the PTE
+	 * ESR_ST   is 0x00800000
+	 * _PAGE_BAP_SW is 0x00000010
+	 * So the shift is >> 19. This tests for supervisor writeability.
+	 * If the page happens to be supervisor writeable and not user
+	 * writeable, we will take a new fault later, but that should be
+	 * a rare enough case.
+	 *
+	 * We also move ESR_ST in _PAGE_DIRTY position
+	 * _PAGE_DIRTY is 0x00001000 so the shift is >> 11
+	 *
+	 * MAS1 is preset for all we need except for TID that needs to
+	 * be cleared for kernel translations
+	 */
+	rlwimi	r11,r14,32-19,27,27
+	rlwimi	r11,r14,32-16,19,19
+	beq	normal_tlb_miss
+	/* XXX replace the RMW cycles with immediate loads + writes */
+1:	mfspr	r10,SPRN_MAS1
+	cmpldi	cr0,r15,8		/* Check for vmalloc region */
+	rlwinm	r10,r10,0,16,1		/* Clear TID */
+	mtspr	SPRN_MAS1,r10
+	beq+	normal_tlb_miss
+
+	/* We got a crappy address, just fault with whatever DEAR and ESR
+	 * are here
+	 */
+	TLB_MISS_STATS_D(MMSTAT_TLB_MISS_NORM_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_data_storage_book3e
+
+/* Instruction TLB miss */
+	START_EXCEPTION(instruction_tlb_miss)
+	TLB_MISS_PROLOG
+
+	/* If we take a recursive fault, the second level handler may need
+	 * to know whether we are handling a data or instruction fault in
+	 * order to get to the right store fault handler. We provide that
+	 * info by writing a crazy value in ESR in our exception frame
+	 */
+	li	r14,-1	/* store to exception frame is done later */
+
+	/* Now we handle the fault proper. We only save DEAR in the non
+	 * linear mapping case since we know the linear mapping case will
+	 * not re-enter. We could indeed optimize and also not save SRR0/1
+	 * in the linear mapping case but I'll leave that for later
+	 *
+	 * Faulting address is SRR0 which is already in r16
+	 */
+	srdi	r15,r16,60		/* get region */
+	cmpldi	cr0,r15,0xc		/* linear mapping ? */
+	TLB_MISS_STATS_SAVE_INFO
+	beq	tlb_load_linear		/* yes -> go to linear map load */
+
+	/* We do the user/kernel test for the PID here along with the RW test
+	 */
+	li	r11,_PAGE_PRESENT|_PAGE_EXEC	/* Base perm */
+	oris	r11,r11,_PAGE_ACCESSED@h
+
+	cmpldi	cr0,r15,0			/* Check for user region */
+	std	r14,EX_TLB_ESR(r12)		/* write crazy -1 to frame */
+	beq	normal_tlb_miss
+	/* XXX replace the RMW cycles with immediate loads + writes */
+1:	mfspr	r10,SPRN_MAS1
+	cmpldi	cr0,r15,8			/* Check for vmalloc region */
+	rlwinm	r10,r10,0,16,1			/* Clear TID */
+	mtspr	SPRN_MAS1,r10
+	beq+	normal_tlb_miss
+
+	/* We got a crappy address, just fault */
+	TLB_MISS_STATS_I(MMSTAT_TLB_MISS_NORM_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_instruction_storage_book3e
+
+/*
+ * This is the guts of the first-level TLB miss handler for direct
+ * misses. We are entered with:
+ *
+ * r16 = faulting address
+ * r15 = region ID
+ * r14 = crap (free to use)
+ * r13 = PACA
+ * r12 = TLB exception frame in PACA
+ * r11 = PTE permission mask
+ * r10 = crap (free to use)
+ */
+normal_tlb_miss:
+	/* So we first construct the page table address. We do that by
+	 * shifting the bottom of the address (not the region ID) by
+	 * PAGE_SHIFT-3, clearing the bottom 3 bits (get a PTE ptr) and
+	 * or'ing the fourth high bit.
+	 *
+	 * NOTE: For 64K pages, we do things slightly differently in
+	 * order to handle the weird page table format used by linux
+	 */
+	ori	r10,r15,0x1
+#ifdef CONFIG_PPC_64K_PAGES
+	/* For the top bits, 16 bytes per PTE */
+	rldicl	r14,r16,64-(PAGE_SHIFT-4),PAGE_SHIFT-4+4
+	/* Now create the bottom bits as 0 in position 0x8000 and
+	 * the rest calculated for 8 bytes per PTE
+	 */
+	rldicl	r15,r16,64-(PAGE_SHIFT-3),64-15
+	/* Insert the bottom bits in */
+	rlwimi	r14,r15,0,16,31
+#else
+	rldicl	r14,r16,64-(PAGE_SHIFT-3),PAGE_SHIFT-3+4
+#endif
+	sldi	r15,r10,60
+	clrrdi	r14,r14,3
+	or	r10,r15,r14
+
+BEGIN_MMU_FTR_SECTION
+	/* Set the TLB reservation and seach for existing entry. Then load
+	 * the entry.
+	 */
+	PPC_TLBSRX_DOT(0,r16)
+	ld	r14,0(r10)
+	beq	normal_tlb_miss_done
+MMU_FTR_SECTION_ELSE
+	ld	r14,0(r10)
+ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBRSRV)
+
+finish_normal_tlb_miss:
+	/* Check if required permissions are met */
+	andc.	r15,r11,r14
+	bne-	normal_tlb_miss_access_fault
+
+	/* Now we build the MAS:
+	 *
+	 * MAS 0   :	Fully setup with defaults in MAS4 and TLBnCFG
+	 * MAS 1   :	Almost fully setup
+	 *               - PID already updated by caller if necessary
+	 *               - TSIZE need change if !base page size, not
+	 *                 yet implemented for now
+	 * MAS 2   :	Defaults not useful, need to be redone
+	 * MAS 3+7 :	Needs to be done
+	 *
+	 * TODO: mix up code below for better scheduling
+	 */
+	clrrdi	r11,r16,12		/* Clear low crap in EA */
+	rlwimi	r11,r14,32-19,27,31	/* Insert WIMGE */
+	mtspr	SPRN_MAS2,r11
+
+	/* Check page size, if not standard, update MAS1 */
+	rldicl	r11,r14,64-8,64-8
+#ifdef CONFIG_PPC_64K_PAGES
+	cmpldi	cr0,r11,BOOK3E_PAGESZ_64K
+#else
+	cmpldi	cr0,r11,BOOK3E_PAGESZ_4K
+#endif
+	beq-	1f
+	mfspr	r11,SPRN_MAS1
+	rlwimi	r11,r14,31,21,24
+	rlwinm	r11,r11,0,21,19
+	mtspr	SPRN_MAS1,r11
+1:
+	/* Move RPN in position */
+	rldicr	r11,r14,64-(PTE_RPN_SHIFT-PAGE_SHIFT),63-PAGE_SHIFT
+	clrldi	r15,r11,12		/* Clear crap at the top */
+	rlwimi	r15,r14,32-8,22,25	/* Move in U bits */
+	rlwimi	r15,r14,32-2,26,31	/* Move in BAP bits */
+
+	/* Mask out SW and UW if !DIRTY (XXX optimize this !) */
+	andi.	r11,r14,_PAGE_DIRTY
+	bne	1f
+	li	r11,MAS3_SW|MAS3_UW
+	andc	r15,r15,r11
+1:
+BEGIN_MMU_FTR_SECTION
+	srdi	r16,r15,32
+	mtspr	SPRN_MAS3,r15
+	mtspr	SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
+	mtspr	SPRN_MAS7_MAS3,r15
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
+
+	tlbwe
+
+normal_tlb_miss_done:
+	/* We don't bother with restoring DEAR or ESR since we know we are
+	 * level 0 and just going back to userland. They are only needed
+	 * if you are going to take an access fault
+	 */
+	TLB_MISS_STATS_X(MMSTAT_TLB_MISS_NORM_OK)
+	TLB_MISS_EPILOG_SUCCESS
+	rfi
+
+normal_tlb_miss_access_fault:
+	/* We need to check if it was an instruction miss */
+	andi.	r10,r11,_PAGE_EXEC
+	bne	1f
+	ld	r14,EX_TLB_DEAR(r12)
+	ld	r15,EX_TLB_ESR(r12)
+	mtspr	SPRN_DEAR,r14
+	mtspr	SPRN_ESR,r15
+	TLB_MISS_STATS_D(MMSTAT_TLB_MISS_NORM_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_data_storage_book3e
+1:	TLB_MISS_STATS_I(MMSTAT_TLB_MISS_NORM_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_instruction_storage_book3e
+
+
+/*
+ * This is the guts of the second-level TLB miss handler for direct
+ * misses. We are entered with:
+ *
+ * r16 = virtual page table faulting address
+ * r15 = region (top 4 bits of address)
+ * r14 = crap (free to use)
+ * r13 = PACA
+ * r12 = TLB exception frame in PACA
+ * r11 = crap (free to use)
+ * r10 = crap (free to use)
+ *
+ * Note that this should only ever be called as a second level handler
+ * with the current scheme when using SW load.
+ * That means we can always get the original fault DEAR at
+ * EX_TLB_DEAR-EX_TLB_SIZE(r12)
+ *
+ * It can be re-entered by the linear mapping miss handler. However, to
+ * avoid too much complication, it will restart the whole fault at level
+ * 0 so we don't care too much about clobbers
+ *
+ * XXX That code was written back when we couldn't clobber r14. We can now,
+ * so we could probably optimize things a bit
+ */
+virt_page_table_tlb_miss:
+	/* Are we hitting a kernel page table ? */
+	andi.	r10,r15,0x8
+
+	/* The cool thing now is that r10 contains 0 for user and 8 for kernel,
+	 * and we happen to have the swapper_pg_dir at offset 8 from the user
+	 * pgdir in the PACA :-).
+	 */
+	add	r11,r10,r13
+
+	/* If kernel, we need to clear MAS1 TID */
+	beq	1f
+	/* XXX replace the RMW cycles with immediate loads + writes */
+	mfspr	r10,SPRN_MAS1
+	rlwinm	r10,r10,0,16,1			/* Clear TID */
+	mtspr	SPRN_MAS1,r10
+1:
+BEGIN_MMU_FTR_SECTION
+	/* Search if we already have a TLB entry for that virtual address, and
+	 * if we do, bail out.
+	 */
+	PPC_TLBSRX_DOT(0,r16)
+	beq	virt_page_table_tlb_miss_done
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV)
+
+	/* Now, we need to walk the page tables. First check if we are in
+	 * range.
+	 */
+	rldicl.	r10,r16,64-(VPTE_INDEX_SIZE+3),VPTE_INDEX_SIZE+3+4
+	bne-	virt_page_table_tlb_miss_fault
+
+	/* Get the PGD pointer */
+	ld	r15,PACAPGD(r11)
+	cmpldi	cr0,r15,0
+	beq-	virt_page_table_tlb_miss_fault
+
+	/* Get to PGD entry */
+	rldicl	r11,r16,64-VPTE_PGD_SHIFT,64-PGD_INDEX_SIZE-3
+	clrrdi	r10,r11,3
+	ldx	r15,r10,r15
+	cmpldi	cr0,r15,0
+	beq	virt_page_table_tlb_miss_fault
+
+#ifndef CONFIG_PPC_64K_PAGES
+	/* Get to PUD entry */
+	rldicl	r11,r16,64-VPTE_PUD_SHIFT,64-PUD_INDEX_SIZE-3
+	clrrdi	r10,r11,3
+	ldx	r15,r10,r15
+	cmpldi	cr0,r15,0
+	beq	virt_page_table_tlb_miss_fault
+#endif /* CONFIG_PPC_64K_PAGES */
+
+	/* Get to PMD entry */
+	rldicl	r11,r16,64-VPTE_PMD_SHIFT,64-PMD_INDEX_SIZE-3
+	clrrdi	r10,r11,3
+	ldx	r15,r10,r15
+	cmpldi	cr0,r15,0
+	beq	virt_page_table_tlb_miss_fault
+
+	/* Ok, we're all right, we can now create a kernel translation for
+	 * a 4K or 64K page from r16 -> r15.
+	 */
+	/* Now we build the MAS:
+	 *
+	 * MAS 0   :	Fully setup with defaults in MAS4 and TLBnCFG
+	 * MAS 1   :	Almost fully setup
+	 *               - PID already updated by caller if necessary
+	 *               - TSIZE for now is base page size always
+	 * MAS 2   :	Use defaults
+	 * MAS 3+7 :	Needs to be done
+	 *
+	 * So we only do MAS 2 and 3 for now...
+	 */
+	clrldi	r11,r15,4		/* remove region ID from RPN */
+	ori	r10,r11,1		/* Or-in SR */
+
+BEGIN_MMU_FTR_SECTION
+	srdi	r16,r10,32
+	mtspr	SPRN_MAS3,r10
+	mtspr	SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
+	mtspr	SPRN_MAS7_MAS3,r10
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
+
+	tlbwe
+
+BEGIN_MMU_FTR_SECTION
+virt_page_table_tlb_miss_done:
+
+	/* We have overriden MAS2:EPN but currently our primary TLB miss
+	 * handler will always restore it so that should not be an issue,
+	 * if we ever optimize the primary handler to not write MAS2 on
+	 * some cases, we'll have to restore MAS2:EPN here based on the
+	 * original fault's DEAR. If we do that we have to modify the
+	 * ITLB miss handler to also store SRR0 in the exception frame
+	 * as DEAR.
+	 *
+	 * However, one nasty thing we did is we cleared the reservation
+	 * (well, potentially we did). We do a trick here thus if we
+	 * are not a level 0 exception (we interrupted the TLB miss) we
+	 * offset the return address by -4 in order to replay the tlbsrx
+	 * instruction there
+	 */
+	subf	r10,r13,r12
+	cmpldi	cr0,r10,PACA_EXTLB+EX_TLB_SIZE
+	bne-	1f
+	ld	r11,PACA_EXTLB+EX_TLB_SIZE+EX_TLB_SRR0(r13)
+	addi	r10,r11,-4
+	std	r10,PACA_EXTLB+EX_TLB_SIZE+EX_TLB_SRR0(r13)
+1:
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_TLBRSRV)
+	/* Return to caller, normal case */
+	TLB_MISS_STATS_X(MMSTAT_TLB_MISS_PT_OK);
+	TLB_MISS_EPILOG_SUCCESS
+	rfi
+
+virt_page_table_tlb_miss_fault:
+	/* If we fault here, things are a little bit tricky. We need to call
+	 * either data or instruction store fault, and we need to retreive
+	 * the original fault address and ESR (for data).
+	 *
+	 * The thing is, we know that in normal circumstances, this is
+	 * always called as a second level tlb miss for SW load or as a first
+	 * level TLB miss for HW load, so we should be able to peek at the
+	 * relevant informations in the first exception frame in the PACA.
+	 *
+	 * However, we do need to double check that, because we may just hit
+	 * a stray kernel pointer or a userland attack trying to hit those
+	 * areas. If that is the case, we do a data fault. (We can't get here
+	 * from an instruction tlb miss anyway).
+	 *
+	 * Note also that when going to a fault, we must unwind the previous
+	 * level as well. Since we are doing that, we don't need to clear or
+	 * restore the TLB reservation neither.
+	 */
+	subf	r10,r13,r12
+	cmpldi	cr0,r10,PACA_EXTLB+EX_TLB_SIZE
+	bne-	virt_page_table_tlb_miss_whacko_fault
+
+	/* We dig the original DEAR and ESR from slot 0 */
+	ld	r15,EX_TLB_DEAR+PACA_EXTLB(r13)
+	ld	r16,EX_TLB_ESR+PACA_EXTLB(r13)
+
+	/* We check for the "special" ESR value for instruction faults */
+	cmpdi	cr0,r16,-1
+	beq	1f
+	mtspr	SPRN_DEAR,r15
+	mtspr	SPRN_ESR,r16
+	TLB_MISS_STATS_D(MMSTAT_TLB_MISS_PT_FAULT);
+	TLB_MISS_EPILOG_ERROR
+	b	exc_data_storage_book3e
+1:	TLB_MISS_STATS_I(MMSTAT_TLB_MISS_PT_FAULT);
+	TLB_MISS_EPILOG_ERROR
+	b	exc_instruction_storage_book3e
+
+virt_page_table_tlb_miss_whacko_fault:
+	/* The linear fault will restart everything so ESR and DEAR will
+	 * not have been clobbered, let's just fault with what we have
+	 */
+	TLB_MISS_STATS_X(MMSTAT_TLB_MISS_PT_FAULT);
+	TLB_MISS_EPILOG_ERROR
+	b	exc_data_storage_book3e
+
+
+/**************************************************************
+ *                                                            *
+ * TLB miss handling for Book3E with hw page table support    *
+ *                                                            *
+ **************************************************************/
+
+
+/* Data TLB miss */
+	START_EXCEPTION(data_tlb_miss_htw)
+	TLB_MISS_PROLOG
+
+	/* Now we handle the fault proper. We only save DEAR in normal
+	 * fault case since that's the only interesting values here.
+	 * We could probably also optimize by not saving SRR0/1 in the
+	 * linear mapping case but I'll leave that for later
+	 */
+	mfspr	r14,SPRN_ESR
+	mfspr	r16,SPRN_DEAR		/* get faulting address */
+	srdi	r11,r16,60		/* get region */
+	cmpldi	cr0,r11,0xc		/* linear mapping ? */
+	TLB_MISS_STATS_SAVE_INFO
+	beq	tlb_load_linear		/* yes -> go to linear map load */
+
+	/* We do the user/kernel test for the PID here along with the RW test
+	 */
+	cmpldi	cr0,r11,0		/* Check for user region */
+	ld	r15,PACAPGD(r13)	/* Load user pgdir */
+	beq	htw_tlb_miss
+
+	/* XXX replace the RMW cycles with immediate loads + writes */
+1:	mfspr	r10,SPRN_MAS1
+	cmpldi	cr0,r11,8		/* Check for vmalloc region */
+	rlwinm	r10,r10,0,16,1		/* Clear TID */
+	mtspr	SPRN_MAS1,r10
+	ld	r15,PACA_KERNELPGD(r13)	/* Load kernel pgdir */
+	beq+	htw_tlb_miss
+
+	/* We got a crappy address, just fault with whatever DEAR and ESR
+	 * are here
+	 */
+	TLB_MISS_STATS_D(MMSTAT_TLB_MISS_NORM_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_data_storage_book3e
+
+/* Instruction TLB miss */
+	START_EXCEPTION(instruction_tlb_miss_htw)
+	TLB_MISS_PROLOG
+
+	/* If we take a recursive fault, the second level handler may need
+	 * to know whether we are handling a data or instruction fault in
+	 * order to get to the right store fault handler. We provide that
+	 * info by keeping a crazy value for ESR in r14
+	 */
+	li	r14,-1	/* store to exception frame is done later */
+
+	/* Now we handle the fault proper. We only save DEAR in the non
+	 * linear mapping case since we know the linear mapping case will
+	 * not re-enter. We could indeed optimize and also not save SRR0/1
+	 * in the linear mapping case but I'll leave that for later
+	 *
+	 * Faulting address is SRR0 which is already in r16
+	 */
+	srdi	r11,r16,60		/* get region */
+	cmpldi	cr0,r11,0xc		/* linear mapping ? */
+	TLB_MISS_STATS_SAVE_INFO
+	beq	tlb_load_linear		/* yes -> go to linear map load */
+
+	/* We do the user/kernel test for the PID here along with the RW test
+	 */
+	cmpldi	cr0,r11,0			/* Check for user region */
+	ld	r15,PACAPGD(r13)		/* Load user pgdir */
+	beq	htw_tlb_miss
+
+	/* XXX replace the RMW cycles with immediate loads + writes */
+1:	mfspr	r10,SPRN_MAS1
+	cmpldi	cr0,r11,8			/* Check for vmalloc region */
+	rlwinm	r10,r10,0,16,1			/* Clear TID */
+	mtspr	SPRN_MAS1,r10
+	ld	r15,PACA_KERNELPGD(r13)		/* Load kernel pgdir */
+	beq+	htw_tlb_miss
+
+	/* We got a crappy address, just fault */
+	TLB_MISS_STATS_I(MMSTAT_TLB_MISS_NORM_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_instruction_storage_book3e
+
+
+/*
+ * This is the guts of the second-level TLB miss handler for direct
+ * misses. We are entered with:
+ *
+ * r16 = virtual page table faulting address
+ * r15 = PGD pointer
+ * r14 = ESR
+ * r13 = PACA
+ * r12 = TLB exception frame in PACA
+ * r11 = crap (free to use)
+ * r10 = crap (free to use)
+ *
+ * It can be re-entered by the linear mapping miss handler. However, to
+ * avoid too much complication, it will save/restore things for us
+ */
+htw_tlb_miss:
+	/* Search if we already have a TLB entry for that virtual address, and
+	 * if we do, bail out.
+	 *
+	 * MAS1:IND should be already set based on MAS4
+	 */
+	PPC_TLBSRX_DOT(0,r16)
+	beq	htw_tlb_miss_done
+
+	/* Now, we need to walk the page tables. First check if we are in
+	 * range.
+	 */
+	rldicl.	r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4
+	bne-	htw_tlb_miss_fault
+
+	/* Get the PGD pointer */
+	cmpldi	cr0,r15,0
+	beq-	htw_tlb_miss_fault
+
+	/* Get to PGD entry */
+	rldicl	r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3
+	clrrdi	r10,r11,3
+	ldx	r15,r10,r15
+	cmpldi	cr0,r15,0
+	beq	htw_tlb_miss_fault
+
+#ifndef CONFIG_PPC_64K_PAGES
+	/* Get to PUD entry */
+	rldicl	r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3
+	clrrdi	r10,r11,3
+	ldx	r15,r10,r15
+	cmpldi	cr0,r15,0
+	beq	htw_tlb_miss_fault
+#endif /* CONFIG_PPC_64K_PAGES */
+
+	/* Get to PMD entry */
+	rldicl	r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3
+	clrrdi	r10,r11,3
+	ldx	r15,r10,r15
+	cmpldi	cr0,r15,0
+	beq	htw_tlb_miss_fault
+
+	/* Ok, we're all right, we can now create an indirect entry for
+	 * a 1M or 256M page.
+	 *
+	 * The last trick is now that because we use "half" pages for
+	 * the HTW (1M IND is 2K and 256M IND is 32K) we need to account
+	 * for an added LSB bit to the RPN. For 64K pages, there is no
+	 * problem as we already use 32K arrays (half PTE pages), but for
+	 * 4K page we need to extract a bit from the virtual address and
+	 * insert it into the "PA52" bit of the RPN.
+	 */
+#ifndef CONFIG_PPC_64K_PAGES
+	rlwimi	r15,r16,32-9,20,20
+#endif
+	/* Now we build the MAS:
+	 *
+	 * MAS 0   :	Fully setup with defaults in MAS4 and TLBnCFG
+	 * MAS 1   :	Almost fully setup
+	 *               - PID already updated by caller if necessary
+	 *               - TSIZE for now is base ind page size always
+	 * MAS 2   :	Use defaults
+	 * MAS 3+7 :	Needs to be done
+	 */
+#ifdef CONFIG_PPC_64K_PAGES
+	ori	r10,r15,(BOOK3E_PAGESZ_64K << MAS3_SPSIZE_SHIFT)
+#else
+	ori	r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT)
+#endif
+
+BEGIN_MMU_FTR_SECTION
+	srdi	r16,r10,32
+	mtspr	SPRN_MAS3,r10
+	mtspr	SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
+	mtspr	SPRN_MAS7_MAS3,r10
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
+
+	tlbwe
+
+htw_tlb_miss_done:
+	/* We don't bother with restoring DEAR or ESR since we know we are
+	 * level 0 and just going back to userland. They are only needed
+	 * if you are going to take an access fault
+	 */
+	TLB_MISS_STATS_X(MMSTAT_TLB_MISS_PT_OK)
+	TLB_MISS_EPILOG_SUCCESS
+	rfi
+
+htw_tlb_miss_fault:
+	/* We need to check if it was an instruction miss. We know this
+	 * though because r14 would contain -1
+	 */
+	cmpdi	cr0,r14,-1
+	beq	1f
+	mtspr	SPRN_DEAR,r16
+	mtspr	SPRN_ESR,r14
+	TLB_MISS_STATS_D(MMSTAT_TLB_MISS_PT_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_data_storage_book3e
+1:	TLB_MISS_STATS_I(MMSTAT_TLB_MISS_PT_FAULT)
+	TLB_MISS_EPILOG_ERROR
+	b	exc_instruction_storage_book3e
+
+/*
+ * This is the guts of "any" level TLB miss handler for kernel linear
+ * mapping misses. We are entered with:
+ *
+ *
+ * r16 = faulting address
+ * r15 = crap (free to use)
+ * r14 = ESR (data) or -1 (instruction)
+ * r13 = PACA
+ * r12 = TLB exception frame in PACA
+ * r11 = crap (free to use)
+ * r10 = crap (free to use)
+ *
+ * In addition we know that we will not re-enter, so in theory, we could
+ * use a simpler epilog not restoring SRR0/1 etc.. but we'll do that later.
+ *
+ * We also need to be careful about MAS registers here & TLB reservation,
+ * as we know we'll have clobbered them if we interrupt the main TLB miss
+ * handlers in which case we probably want to do a full restart at level
+ * 0 rather than saving / restoring the MAS.
+ *
+ * Note: If we care about performance of that core, we can easily shuffle
+ *       a few things around
+ */
+tlb_load_linear:
+	/* For now, we assume the linear mapping is contiguous and stops at
+	 * linear_map_top. We also assume the size is a multiple of 1G, thus
+	 * we only use 1G pages for now. That might have to be changed in a
+	 * final implementation, especially when dealing with hypervisors
+	 */
+	ld	r11,PACATOC(r13)
+	ld	r11,linear_map_top@got(r11)
+	ld	r10,0(r11)
+	cmpld	cr0,r10,r16
+	bge	tlb_load_linear_fault
+
+	/* MAS1 need whole new setup. */
+	li	r15,(BOOK3E_PAGESZ_1GB<<MAS1_TSIZE_SHIFT)
+	oris	r15,r15,MAS1_VALID@h	/* MAS1 needs V and TSIZE */
+	mtspr	SPRN_MAS1,r15
+
+	/* Already somebody there ? */
+	PPC_TLBSRX_DOT(0,r16)
+	beq	tlb_load_linear_done
+
+	/* Now we build the remaining MAS. MAS0 and 2 should be fine
+	 * with their defaults, which leaves us with MAS 3 and 7. The
+	 * mapping is linear, so we just take the address, clear the
+	 * region bits, and or in the permission bits which are currently
+	 * hard wired
+	 */
+	clrrdi	r10,r16,30		/* 1G page index */
+	clrldi	r10,r10,4		/* clear region bits */
+	ori	r10,r10,MAS3_SR|MAS3_SW|MAS3_SX
+
+BEGIN_MMU_FTR_SECTION
+	srdi	r16,r10,32
+	mtspr	SPRN_MAS3,r10
+	mtspr	SPRN_MAS7,r16
+MMU_FTR_SECTION_ELSE
+	mtspr	SPRN_MAS7_MAS3,r10
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS)
+
+	tlbwe
+
+tlb_load_linear_done:
+	/* We use the "error" epilog for success as we do want to
+	 * restore to the initial faulting context, whatever it was.
+	 * We do that because we can't resume a fault within a TLB
+	 * miss handler, due to MAS and TLB reservation being clobbered.
+	 */
+	TLB_MISS_STATS_X(MMSTAT_TLB_MISS_LINEAR)
+	TLB_MISS_EPILOG_ERROR
+	rfi
+
+tlb_load_linear_fault:
+	/* We keep the DEAR and ESR around, this shouldn't have happened */
+	cmpdi	cr0,r14,-1
+	beq	1f
+	TLB_MISS_EPILOG_ERROR_SPECIAL
+	b	exc_data_storage_book3e
+1:	TLB_MISS_EPILOG_ERROR_SPECIAL
+	b	exc_instruction_storage_book3e
+
+
+#ifdef CONFIG_BOOK3E_MMU_TLB_STATS
+.tlb_stat_inc:
+1:	ldarx	r8,0,r9
+	addi	r8,r8,1
+	stdcx.	r8,0,r9
+	bne-	1b
+	blr
+#endif
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index ad2eb4d..2fbc680 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -7,8 +7,8 @@
  *
  *  -- BenH
  *
- * Copyright 2008 Ben Herrenschmidt <benh@kernel.crashing.org>
- *                IBM Corp.
+ * Copyright 2008,2009 Ben Herrenschmidt <benh@kernel.crashing.org>
+ *                     IBM Corp.
  *
  *  Derived from arch/ppc/mm/init.c:
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -34,12 +34,71 @@
 #include <linux/pagemap.h>
 #include <linux/preempt.h>
 #include <linux/spinlock.h>
+#include <linux/lmb.h>
 
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
+#include <asm/code-patching.h>
 
 #include "mmu_decl.h"
 
+#ifdef CONFIG_PPC_BOOK3E
+struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT] = {
+	[MMU_PAGE_4K] = {
+		.shift	= 12,
+		.enc	= BOOK3E_PAGESZ_4K,
+	},
+	[MMU_PAGE_16K] = {
+		.shift	= 14,
+		.enc	= BOOK3E_PAGESZ_16K,
+	},
+	[MMU_PAGE_64K] = {
+		.shift	= 16,
+		.enc	= BOOK3E_PAGESZ_64K,
+	},
+	[MMU_PAGE_1M] = {
+		.shift	= 20,
+		.enc	= BOOK3E_PAGESZ_1M,
+	},
+	[MMU_PAGE_16M] = {
+		.shift	= 24,
+		.enc	= BOOK3E_PAGESZ_16M,
+	},
+	[MMU_PAGE_256M] = {
+		.shift	= 28,
+		.enc	= BOOK3E_PAGESZ_256M,
+	},
+	[MMU_PAGE_1G] = {
+		.shift	= 30,
+		.enc	= BOOK3E_PAGESZ_1GB,
+	},
+};
+static inline int mmu_get_tsize(int psize)
+{
+	return mmu_psize_defs[psize].enc;
+}
+#else
+static inline int mmu_get_tsize(int psize)
+{
+	/* This isn't used on !Book3E for now */
+	return 0;
+}
+#endif
+
+/* The variables below are currently only used on 64-bit Book3E
+ * though this will probably be made common with other nohash
+ * implementations at some point
+ */
+#ifdef CONFIG_PPC64
+
+int mmu_linear_psize;		/* Page size used for the linear mapping */
+int mmu_pte_psize;		/* Page size used for PTE pages */
+int mmu_vmemmap_psize;		/* Page size used for the virtual mem map */
+int book3e_htw_enabled;		/* Is HW tablewalk enabled ? */
+unsigned long linear_map_top;	/* Top of linear mapping */
+
+#endif /* CONFIG_PPC64 */
+
 /*
  * Base TLB flushing operations:
  *
@@ -67,18 +126,24 @@ void local_flush_tlb_mm(struct mm_struct *mm)
 }
 EXPORT_SYMBOL(local_flush_tlb_mm);
 
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+void __local_flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
+			    int tsize, int ind)
 {
 	unsigned int pid;
 
 	preempt_disable();
-	pid = vma ? vma->vm_mm->context.id : 0;
+	pid = mm ? mm->context.id : 0;
 	if (pid != MMU_NO_CONTEXT)
-		_tlbil_va(vmaddr, pid);
+		_tlbil_va(vmaddr, pid, tsize, ind);
 	preempt_enable();
 }
-EXPORT_SYMBOL(local_flush_tlb_page);
 
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+	__local_flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr,
+			       mmu_get_tsize(mmu_virtual_psize), 0);
+}
+EXPORT_SYMBOL(local_flush_tlb_page);
 
 /*
  * And here are the SMP non-local implementations
@@ -87,9 +152,17 @@ EXPORT_SYMBOL(local_flush_tlb_page);
 
 static DEFINE_SPINLOCK(tlbivax_lock);
 
+static int mm_is_core_local(struct mm_struct *mm)
+{
+	return cpumask_subset(mm_cpumask(mm),
+			      topology_thread_cpumask(smp_processor_id()));
+}
+
 struct tlb_flush_param {
 	unsigned long addr;
 	unsigned int pid;
+	unsigned int tsize;
+	unsigned int ind;
 };
 
 static void do_flush_tlb_mm_ipi(void *param)
@@ -103,7 +176,7 @@ static void do_flush_tlb_page_ipi(void *param)
 {
 	struct tlb_flush_param *p = param;
 
-	_tlbil_va(p->addr, p->pid);
+	_tlbil_va(p->addr, p->pid, p->tsize, p->ind);
 }
 
 
@@ -131,7 +204,7 @@ void flush_tlb_mm(struct mm_struct *mm)
 	pid = mm->context.id;
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		goto no_context;
-	if (!cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
+	if (!mm_is_core_local(mm)) {
 		struct tlb_flush_param p = { .pid = pid };
 		/* Ignores smp_processor_id() even if set. */
 		smp_call_function_many(mm_cpumask(mm),
@@ -143,37 +216,49 @@ void flush_tlb_mm(struct mm_struct *mm)
 }
 EXPORT_SYMBOL(flush_tlb_mm);
 
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+void __flush_tlb_page(struct mm_struct *mm, unsigned long vmaddr,
+		      int tsize, int ind)
 {
 	struct cpumask *cpu_mask;
 	unsigned int pid;
 
 	preempt_disable();
-	pid = vma ? vma->vm_mm->context.id : 0;
+	pid = mm ? mm->context.id : 0;
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		goto bail;
-	cpu_mask = mm_cpumask(vma->vm_mm);
-	if (!cpumask_equal(cpu_mask, cpumask_of(smp_processor_id()))) {
+	cpu_mask = mm_cpumask(mm);
+	if (!mm_is_core_local(mm)) {
 		/* If broadcast tlbivax is supported, use it */
 		if (mmu_has_feature(MMU_FTR_USE_TLBIVAX_BCAST)) {
 			int lock = mmu_has_feature(MMU_FTR_LOCK_BCAST_INVAL);
 			if (lock)
 				spin_lock(&tlbivax_lock);
-			_tlbivax_bcast(vmaddr, pid);
+			_tlbivax_bcast(vmaddr, pid, tsize, ind);
 			if (lock)
 				spin_unlock(&tlbivax_lock);
 			goto bail;
 		} else {
-			struct tlb_flush_param p = { .pid = pid, .addr = vmaddr };
+			struct tlb_flush_param p = {
+				.pid = pid,
+				.addr = vmaddr,
+				.tsize = tsize,
+				.ind = ind,
+			};
 			/* Ignores smp_processor_id() even if set in cpu_mask */
 			smp_call_function_many(cpu_mask,
 					       do_flush_tlb_page_ipi, &p, 1);
 		}
 	}
-	_tlbil_va(vmaddr, pid);
+	_tlbil_va(vmaddr, pid, tsize, ind);
  bail:
 	preempt_enable();
 }
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
+{
+	__flush_tlb_page(vma ? vma->vm_mm : NULL, vmaddr,
+			 mmu_get_tsize(mmu_virtual_psize), 0);
+}
 EXPORT_SYMBOL(flush_tlb_page);
 
 #endif /* CONFIG_SMP */
@@ -207,3 +292,156 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 	flush_tlb_mm(vma->vm_mm);
 }
 EXPORT_SYMBOL(flush_tlb_range);
+
+void tlb_flush(struct mmu_gather *tlb)
+{
+	flush_tlb_mm(tlb->mm);
+
+	/* Push out batch of freed page tables */
+	pte_free_finish();
+}
+
+/*
+ * Below are functions specific to the 64-bit variant of Book3E though that
+ * may change in the future
+ */
+
+#ifdef CONFIG_PPC64
+
+/*
+ * Handling of virtual linear page tables or indirect TLB entries
+ * flushing when PTE pages are freed
+ */
+void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
+{
+	int tsize = mmu_psize_defs[mmu_pte_psize].enc;
+
+	if (book3e_htw_enabled) {
+		unsigned long start = address & PMD_MASK;
+		unsigned long end = address + PMD_SIZE;
+		unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
+
+		/* This isn't the most optimal, ideally we would factor out the
+		 * while preempt & CPU mask mucking around, or even the IPI but
+		 * it will do for now
+		 */
+		while (start < end) {
+			__flush_tlb_page(tlb->mm, start, tsize, 1);
+			start += size;
+		}
+	} else {
+		unsigned long rmask = 0xf000000000000000ul;
+		unsigned long rid = (address & rmask) | 0x1000000000000000ul;
+		unsigned long vpte = address & ~rmask;
+
+#ifdef CONFIG_PPC_64K_PAGES
+		vpte = (vpte >> (PAGE_SHIFT - 4)) & ~0xfffful;
+#else
+		vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
+#endif
+		vpte |= rid;
+		__flush_tlb_page(tlb->mm, vpte, tsize, 0);
+	}
+}
+
+/*
+ * Early initialization of the MMU TLB code
+ */
+static void __early_init_mmu(int boot_cpu)
+{
+	extern unsigned int interrupt_base_book3e;
+	extern unsigned int exc_data_tlb_miss_htw_book3e;
+	extern unsigned int exc_instruction_tlb_miss_htw_book3e;
+
+	unsigned int *ibase = &interrupt_base_book3e;
+	unsigned int mas4;
+
+	/* XXX This will have to be decided at runtime, but right
+	 * now our boot and TLB miss code hard wires it. Ideally
+	 * we should find out a suitable page size and patch the
+	 * TLB miss code (either that or use the PACA to store
+	 * the value we want)
+	 */
+	mmu_linear_psize = MMU_PAGE_1G;
+
+	/* XXX This should be decided at runtime based on supported
+	 * page sizes in the TLB, but for now let's assume 16M is
+	 * always there and a good fit (which it probably is)
+	 */
+	mmu_vmemmap_psize = MMU_PAGE_16M;
+
+	/* Check if HW tablewalk is present, and if yes, enable it by:
+	 *
+	 * - patching the TLB miss handlers to branch to the
+	 *   one dedicates to it
+	 *
+	 * - setting the global book3e_htw_enabled
+	 *
+	 * - Set MAS4:INDD and default page size
+	 */
+
+	/* XXX This code only checks for TLB 0 capabilities and doesn't
+	 *     check what page size combos are supported by the HW. It
+	 *     also doesn't handle the case where a separate array holds
+	 *     the IND entries from the array loaded by the PT.
+	 */
+	if (boot_cpu) {
+		unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG);
+
+		/* Check if HW loader is supported */
+		if ((tlb0cfg & TLBnCFG_IND) &&
+		    (tlb0cfg & TLBnCFG_PT)) {
+			patch_branch(ibase + (0x1c0 / 4),
+			     (unsigned long)&exc_data_tlb_miss_htw_book3e, 0);
+			patch_branch(ibase + (0x1e0 / 4),
+			     (unsigned long)&exc_instruction_tlb_miss_htw_book3e, 0);
+			book3e_htw_enabled = 1;
+		}
+		pr_info("MMU: Book3E Page Tables %s\n",
+			book3e_htw_enabled ? "Enabled" : "Disabled");
+	}
+
+	/* Set MAS4 based on page table setting */
+
+	mas4 = 0x4 << MAS4_WIMGED_SHIFT;
+	if (book3e_htw_enabled) {
+		mas4 |= mas4 | MAS4_INDD;
+#ifdef CONFIG_PPC_64K_PAGES
+		mas4 |=	BOOK3E_PAGESZ_256M << MAS4_TSIZED_SHIFT;
+		mmu_pte_psize = MMU_PAGE_256M;
+#else
+		mas4 |=	BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT;
+		mmu_pte_psize = MMU_PAGE_1M;
+#endif
+	} else {
+#ifdef CONFIG_PPC_64K_PAGES
+		mas4 |=	BOOK3E_PAGESZ_64K << MAS4_TSIZED_SHIFT;
+#else
+		mas4 |=	BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
+#endif
+		mmu_pte_psize = mmu_virtual_psize;
+	}
+	mtspr(SPRN_MAS4, mas4);
+
+	/* Set the global containing the top of the linear mapping
+	 * for use by the TLB miss code
+	 */
+	linear_map_top = lmb_end_of_DRAM();
+
+	/* A sync won't hurt us after mucking around with
+	 * the MMU configuration
+	 */
+	mb();
+}
+
+void __init early_init_mmu(void)
+{
+	__early_init_mmu(1);
+}
+
+void __cpuinit early_init_mmu_secondary(void)
+{
+	__early_init_mmu(0);
+}
+
+#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index 3037911..bbdc5b5 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -39,7 +39,7 @@
 /*
  * 40x implementation needs only tlbil_va
  */
-_GLOBAL(_tlbil_va)
+_GLOBAL(__tlbil_va)
 	/* We run the search with interrupts disabled because we have to change
 	 * the PID and I don't want to preempt when that happens.
 	 */
@@ -71,7 +71,7 @@ _GLOBAL(_tlbil_va)
  * 440 implementation uses tlbsx/we for tlbil_va and a full sweep
  * of the TLB for everything else.
  */
-_GLOBAL(_tlbil_va)
+_GLOBAL(__tlbil_va)
 	mfspr	r5,SPRN_MMUCR
 	rlwimi	r5,r4,0,24,31			/* Set TID */
 
@@ -124,8 +124,6 @@ _GLOBAL(_tlbil_pid)
  * to have the larger code path before the _SECTION_ELSE
  */
 
-#define MMUCSR0_TLBFI	(MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
-			 MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
 /*
  * Flush MMU TLB on the local processor
  */
@@ -170,7 +168,7 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_USE_TLBILX)
  * Flush MMU TLB for a particular address, but only on the local processor
  * (no broadcast)
  */
-_GLOBAL(_tlbil_va)
+_GLOBAL(__tlbil_va)
 	mfmsr	r10
 	wrteei	0
 	slwi	r4,r4,16
@@ -191,6 +189,85 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_TLBILX)
 	isync
 1:	wrtee	r10
 	blr
+#elif defined(CONFIG_PPC_BOOK3E)
+/*
+ * New Book3E (>= 2.06) implementation
+ *
+ * Note: We may be able to get away without the interrupt masking stuff
+ * if we save/restore MAS6 on exceptions that might modify it
+ */
+_GLOBAL(_tlbil_pid)
+	slwi	r4,r3,MAS6_SPID_SHIFT
+	mfmsr	r10
+	wrteei	0
+	mtspr	SPRN_MAS6,r4
+	PPC_TLBILX_PID(0,0)
+	wrtee	r10
+	msync
+	isync
+	blr
+
+_GLOBAL(_tlbil_pid_noind)
+	slwi	r4,r3,MAS6_SPID_SHIFT
+	mfmsr	r10
+	ori	r4,r4,MAS6_SIND
+	wrteei	0
+	mtspr	SPRN_MAS6,r4
+	PPC_TLBILX_PID(0,0)
+	wrtee	r10
+	msync
+	isync
+	blr
+
+_GLOBAL(_tlbil_all)
+	PPC_TLBILX_ALL(0,0)
+	msync
+	isync
+	blr
+
+_GLOBAL(_tlbil_va)
+	mfmsr	r10
+	wrteei	0
+	cmpwi	cr0,r6,0
+	slwi	r4,r4,MAS6_SPID_SHIFT
+	rlwimi	r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK
+	beq	1f
+	rlwimi	r4,r6,MAS6_SIND_SHIFT,MAS6_SIND
+1:	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
+	PPC_TLBILX_VA(0,r3)
+	msync
+	isync
+	wrtee	r10
+	blr
+
+_GLOBAL(_tlbivax_bcast)
+	mfmsr	r10
+	wrteei	0
+	cmpwi	cr0,r6,0
+	slwi	r4,r4,MAS6_SPID_SHIFT
+	rlwimi	r4,r5,MAS6_ISIZE_SHIFT,MAS6_ISIZE_MASK
+	beq	1f
+	rlwimi	r4,r6,MAS6_SIND_SHIFT,MAS6_SIND
+1:	mtspr	SPRN_MAS6,r4		/* assume AS=0 for now */
+	PPC_TLBIVAX(0,r3)
+	eieio
+	tlbsync
+	sync
+	wrtee	r10
+	blr
+
+_GLOBAL(set_context)
+#ifdef CONFIG_BDI_SWITCH
+	/* Context switch the PTE pointer for the Abatron BDI2000.
+	 * The PGDIR is the second parameter.
+	 */
+	lis	r5, abatron_pteptrs@h
+	ori	r5, r5, abatron_pteptrs@l
+	stw	r4, 0x4(r5)
+#endif
+	mtspr	SPRN_PID,r3
+	isync			/* Force context change */
+	blr
 #else
 #error Unsupported processor type !
 #endif
diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig
index a6e43cb..ec64264 100644
--- a/arch/powerpc/platforms/40x/Kconfig
+++ b/arch/powerpc/platforms/40x/Kconfig
@@ -40,6 +40,16 @@ config HCU4
 	help
 	  This option enables support for the Nestal Maschinen HCU4 board.
 
+config HOTFOOT
+        bool "Hotfoot"
+	depends on 40x
+	default n
+	select 405EP
+	select PPC40x_SIMPLE
+	select PCI
+        help
+	 This option enables support for the ESTEEM 195E Hotfoot board.
+
 config KILAUEA
 	bool "Kilauea"
 	depends on 40x
diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c
index 5fd5a59..546bbc2 100644
--- a/arch/powerpc/platforms/40x/ppc40x_simple.c
+++ b/arch/powerpc/platforms/40x/ppc40x_simple.c
@@ -54,7 +54,8 @@ static char *board[] __initdata = {
 	"amcc,acadia",
 	"amcc,haleakala",
 	"amcc,kilauea",
-	"amcc,makalu"
+	"amcc,makalu",
+	"est,hotfoot"
 };
 
 static int __init ppc40x_probe(void)
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 90e3192..7486bff 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -129,6 +129,18 @@ config REDWOOD
 	help
 	  This option enables support for the AMCC PPC460SX Redwood board.
 
+config EIGER
+	bool "Eiger"
+	depends on 44x
+	default n
+	select PPC44x_SIMPLE
+	select 460SX
+	select PCI
+	select PPC4xx_PCI_EXPRESS
+	select IBM_NEW_EMAC_RGMII
+	help
+	  This option enables support for the AMCC PPC460SX evaluation board.
+
 config YOSEMITE
 	bool "Yosemite"
 	depends on 44x
diff --git a/arch/powerpc/platforms/44x/ppc44x_simple.c b/arch/powerpc/platforms/44x/ppc44x_simple.c
index 5bcd441..e8c23cc 100644
--- a/arch/powerpc/platforms/44x/ppc44x_simple.c
+++ b/arch/powerpc/platforms/44x/ppc44x_simple.c
@@ -55,6 +55,7 @@ static char *board[] __initdata = {
 	"amcc,canyonlands",
 	"amcc,glacier",
 	"ibm,ebony",
+	"amcc,eiger",
 	"amcc,katmai",
 	"amcc,rainier",
 	"amcc,redwood",
diff --git a/arch/powerpc/platforms/82xx/mgcoge.c b/arch/powerpc/platforms/82xx/mgcoge.c
index c2af169..7a5de9e 100644
--- a/arch/powerpc/platforms/82xx/mgcoge.c
+++ b/arch/powerpc/platforms/82xx/mgcoge.c
@@ -50,16 +50,63 @@ struct cpm_pin {
 static __initdata struct cpm_pin mgcoge_pins[] = {
 
 	/* SMC2 */
-	{1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
-	{1, 9, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{0, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{0, 9, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
 
 	/* SCC4 */
-	{3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
-	{3, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
-	{3,  9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
-	{3,  8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
-	{4, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
-	{4, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{2, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{2, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{2,  9, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{2,  8, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{3, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{3, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+
+	/* FCC1 */
+	{0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
+	{0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
+	{0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
+	{0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
+	{0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
+	{0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY},
+
+	{2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{2, 23, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+
+	/* FCC2 */
+	{1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY},
+	{1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+
+	{2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+
+	/* MDC */
+	{0, 13, CPM_PIN_OUTPUT | CPM_PIN_GPIO},
+
+#if defined(CONFIG_I2C_CPM)
+	/* I2C */
+	{3, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
+	{3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
+#endif
 };
 
 static void __init init_ioports(void)
@@ -68,12 +115,16 @@ static void __init init_ioports(void)
 
 	for (i = 0; i < ARRAY_SIZE(mgcoge_pins); i++) {
 		const struct cpm_pin *pin = &mgcoge_pins[i];
-		cpm2_set_pin(pin->port - 1, pin->pin, pin->flags);
+		cpm2_set_pin(pin->port, pin->pin, pin->flags);
 	}
 
 	cpm2_smc_clk_setup(CPM_CLK_SMC2, CPM_BRG8);
 	cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK7, CPM_CLK_RX);
 	cpm2_clk_setup(CPM_CLK_SCC4, CPM_CLK8, CPM_CLK_TX);
+	cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_RX);
+	cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK9,  CPM_CLK_TX);
+	cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX);
+	cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX);
 }
 
 static void __init mgcoge_setup_arch(void)
diff --git a/arch/powerpc/platforms/82xx/mpc8272_ads.c b/arch/powerpc/platforms/82xx/mpc8272_ads.c
index 8054c68..30394b4 100644
--- a/arch/powerpc/platforms/82xx/mpc8272_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc8272_ads.c
@@ -29,7 +29,6 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/cpm2_pic.h>
 
-#include "pq2ads.h"
 #include "pq2.h"
 
 static void __init mpc8272_ads_pic_init(void)
@@ -100,6 +99,15 @@ static struct cpm_pin mpc8272_ads_pins[] = {
 	/* I2C */
 	{3, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
 	{3, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_OPENDRAIN},
+
+	/* USB */
+	{2, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{2, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{2, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{2, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+	{3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
+	{3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
 };
 
 static void __init init_ioports(void)
@@ -113,6 +121,8 @@ static void __init init_ioports(void)
 
 	cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX);
 	cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX);
+	cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK8, CPM_CLK_RX);
+	cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK8, CPM_CLK_TX);
 	cpm2_clk_setup(CPM_CLK_SCC4, CPM_BRG4, CPM_CLK_RX);
 	cpm2_clk_setup(CPM_CLK_SCC4, CPM_BRG4, CPM_CLK_TX);
 	cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK11, CPM_CLK_RX);
@@ -144,12 +154,22 @@ static void __init mpc8272_ads_setup_arch(void)
 		return;
 	}
 
+#define BCSR1_FETHIEN		0x08000000
+#define BCSR1_FETH_RST		0x04000000
+#define BCSR1_RS232_EN1		0x02000000
+#define BCSR1_RS232_EN2		0x01000000
+#define BCSR3_USB_nEN		0x80000000
+#define BCSR3_FETHIEN2		0x10000000
+#define BCSR3_FETH2_RST		0x08000000
+
 	clrbits32(&bcsr[1], BCSR1_RS232_EN1 | BCSR1_RS232_EN2 | BCSR1_FETHIEN);
 	setbits32(&bcsr[1], BCSR1_FETH_RST);
 
 	clrbits32(&bcsr[3], BCSR3_FETHIEN2);
 	setbits32(&bcsr[3], BCSR3_FETH2_RST);
 
+	clrbits32(&bcsr[3], BCSR3_USB_nEN);
+
 	iounmap(bcsr);
 
 	init_ioports();
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 083ebee..f49a254 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -75,11 +75,11 @@ config MPC837x_MDS
 	  This option enables support for the MPC837x MDS Processor Board.
 
 config MPC837x_RDB
-	bool "Freescale MPC837x RDB"
+	bool "Freescale MPC837x RDB/WLAN"
 	select DEFAULT_UIMAGE
 	select PPC_MPC837x
 	help
-	  This option enables support for the MPC837x RDB Board.
+	  This option enables support for the MPC837x RDB and WLAN Boards.
 
 config SBC834x
 	bool "Wind River SBC834x"
diff --git a/arch/powerpc/platforms/83xx/mpc837x_rdb.c b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
index 76f3b32..a1908d2 100644
--- a/arch/powerpc/platforms/83xx/mpc837x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc837x_rdb.c
@@ -17,10 +17,32 @@
 #include <asm/time.h>
 #include <asm/ipic.h>
 #include <asm/udbg.h>
+#include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 
 #include "mpc83xx.h"
 
+static void mpc837x_rdb_sd_cfg(void)
+{
+	void __iomem *im;
+
+	im = ioremap(get_immrbase(), 0x1000);
+	if (!im) {
+		WARN_ON(1);
+		return;
+	}
+
+	/*
+	 * On RDB boards (in contrast to MDS) USBB pins are used for SD only,
+	 * so we can safely mux them away from the USB block.
+	 */
+	clrsetbits_be32(im + MPC83XX_SICRL_OFFS, MPC837X_SICRL_USBB_MASK,
+						 MPC837X_SICRL_SD);
+	clrsetbits_be32(im + MPC83XX_SICRH_OFFS, MPC837X_SICRH_SPI_MASK,
+						 MPC837X_SICRH_SD);
+	iounmap(im);
+}
+
 /* ************************************************************************
  *
  * Setup the architecture
@@ -42,6 +64,7 @@ static void __init mpc837x_rdb_setup_arch(void)
 		mpc83xx_add_bridge(np);
 #endif
 	mpc837x_usb_cfg();
+	mpc837x_rdb_sd_cfg();
 }
 
 static struct of_device_id mpc837x_ids[] = {
@@ -86,11 +109,12 @@ static int __init mpc837x_rdb_probe(void)
 
 	return of_flat_dt_is_compatible(root, "fsl,mpc8377rdb") ||
 	       of_flat_dt_is_compatible(root, "fsl,mpc8378rdb") ||
-	       of_flat_dt_is_compatible(root, "fsl,mpc8379rdb");
+	       of_flat_dt_is_compatible(root, "fsl,mpc8379rdb") ||
+	       of_flat_dt_is_compatible(root, "fsl,mpc8377wlan");
 }
 
 define_machine(mpc837x_rdb) {
-	.name			= "MPC837x RDB",
+	.name			= "MPC837x RDB/WLAN",
 	.probe			= mpc837x_rdb_probe,
 	.setup_arch		= mpc837x_rdb_setup_arch,
 	.init_IRQ		= mpc837x_rdb_init_IRQ,
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index d1dc5b0..0fea881 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -30,6 +30,8 @@
 #define MPC8315_SICRL_USB_ULPI     0x00000054
 #define MPC837X_SICRL_USB_MASK     0xf0000000
 #define MPC837X_SICRL_USB_ULPI     0x50000000
+#define MPC837X_SICRL_USBB_MASK    0x30000000
+#define MPC837X_SICRL_SD           0x20000000
 
 /* system i/o configuration register high */
 #define MPC83XX_SICRH_OFFS         0x118
@@ -38,6 +40,8 @@
 #define MPC831X_SICRH_USB_ULPI     0x000000a0
 #define MPC8315_SICRH_USB_MASK     0x0000ff00
 #define MPC8315_SICRH_USB_ULPI     0x00000000
+#define MPC837X_SICRH_SPI_MASK     0x00000003
+#define MPC837X_SICRH_SD           0x00000001
 
 /* USB Control Register */
 #define FSL_USB2_CONTROL_OFFS      0x500
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index a9b4166..d3a975e 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -55,6 +55,15 @@ config MPC85xx_DS
 	help
 	  This option enables support for the MPC85xx DS (MPC8544 DS) board
 
+config MPC85xx_RDB
+	bool "Freescale MPC85xx RDB"
+	select PPC_I8259
+	select DEFAULT_UIMAGE
+	select FSL_ULI1575
+	select SWIOTLB
+	help
+	  This option enables support for the MPC85xx RDB (P2020 RDB) board
+
 config SOCRATES
 	bool "Socrates"
 	select DEFAULT_UIMAGE
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 835733f..9098aea 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -9,10 +9,11 @@ obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
 obj-$(CONFIG_MPC8536_DS)  += mpc8536_ds.o
 obj-$(CONFIG_MPC85xx_DS)  += mpc85xx_ds.o
 obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
+obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o
 obj-$(CONFIG_STX_GP3)	  += stx_gp3.o
 obj-$(CONFIG_TQM85xx)	  += tqm85xx.o
 obj-$(CONFIG_SBC8560)     += sbc8560.o
 obj-$(CONFIG_SBC8548)     += sbc8548.o
 obj-$(CONFIG_SOCRATES)    += socrates.o socrates_fpga_pic.o
 obj-$(CONFIG_KSI8560)	  += ksi8560.o
-obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o
\ No newline at end of file
+obj-$(CONFIG_XES_MPC85xx) += xes_mpc85xx.o
diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/platforms/85xx/mpc8536_ds.c
index 055ff41..004b7d3 100644
--- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
@@ -96,7 +96,8 @@ static void __init mpc8536_ds_setup_arch(void)
 #ifdef CONFIG_SWIOTLB
 	if (lmb_end_of_DRAM() > max) {
 		ppc_swiotlb_enable = 1;
-		set_pci_dma_ops(&swiotlb_pci_dma_ops);
+		set_pci_dma_ops(&swiotlb_dma_ops);
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
 	}
 #endif
 
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 849c0ac..544011a 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -192,7 +192,8 @@ static void __init mpc85xx_ds_setup_arch(void)
 #ifdef CONFIG_SWIOTLB
 	if (lmb_end_of_DRAM() > max) {
 		ppc_swiotlb_enable = 1;
-		set_pci_dma_ops(&swiotlb_pci_dma_ops);
+		set_pci_dma_ops(&swiotlb_dma_ops);
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
 	}
 #endif
 
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index bfb3283..3909d57 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -47,6 +47,7 @@
 #include <asm/udbg.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
+#include <sysdev/simple_gpio.h>
 #include <asm/qe.h>
 #include <asm/qe_ic.h>
 #include <asm/mpic.h>
@@ -254,7 +255,8 @@ static void __init mpc85xx_mds_setup_arch(void)
 #ifdef CONFIG_SWIOTLB
 	if (lmb_end_of_DRAM() > max) {
 		ppc_swiotlb_enable = 1;
-		set_pci_dma_ops(&swiotlb_pci_dma_ops);
+		set_pci_dma_ops(&swiotlb_dma_ops);
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
 	}
 #endif
 }
@@ -304,6 +306,9 @@ static struct of_device_id mpc85xx_ids[] = {
 
 static int __init mpc85xx_publish_devices(void)
 {
+	if (machine_is(mpc8569_mds))
+		simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio");
+
 	/* Publish the QE devices */
 	of_platform_bus_probe(NULL, mpc85xx_ids, NULL);
 
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
new file mode 100644
index 0000000..c8468de
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -0,0 +1,141 @@
+/*
+ * MPC85xx RDB Board Setup
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/of_platform.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
+#else
+#define DBG(fmt, args...)
+#endif
+
+
+void __init mpc85xx_rdb_pic_init(void)
+{
+	struct mpic *mpic;
+	struct resource r;
+	struct device_node *np;
+
+	np = of_find_node_by_type(NULL, "open-pic");
+	if (np == NULL) {
+		printk(KERN_ERR "Could not find open-pic node\n");
+		return;
+	}
+
+	if (of_address_to_resource(np, 0, &r)) {
+		printk(KERN_ERR "Failed to map mpic register space\n");
+		of_node_put(np);
+		return;
+	}
+
+	mpic = mpic_alloc(np, r.start,
+		  MPIC_PRIMARY | MPIC_WANTS_RESET |
+		  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
+		  MPIC_SINGLE_DEST_CPU,
+		  0, 256, " OpenPIC  ");
+
+	BUG_ON(mpic == NULL);
+	of_node_put(np);
+
+	mpic_init(mpic);
+
+}
+
+/*
+ * Setup the architecture
+ */
+#ifdef CONFIG_SMP
+extern void __init mpc85xx_smp_init(void);
+#endif
+static void __init mpc85xx_rdb_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+	struct device_node *np;
+#endif
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc85xx_rdb_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+	for_each_node_by_type(np, "pci") {
+		if (of_device_is_compatible(np, "fsl,mpc8548-pcie"))
+			fsl_add_bridge(np, 0);
+	}
+
+#endif
+
+#ifdef CONFIG_SMP
+	mpc85xx_smp_init();
+#endif
+
+	printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n");
+}
+
+static struct of_device_id __initdata mpc85xxrdb_ids[] = {
+	{ .type = "soc", },
+	{ .compatible = "soc", },
+	{ .compatible = "simple-bus", },
+	{ .compatible = "gianfar", },
+	{},
+};
+
+static int __init mpc85xxrdb_publish_devices(void)
+{
+	return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL);
+}
+machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices);
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p2020_rdb_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "fsl,P2020RDB"))
+		return 1;
+	return 0;
+}
+
+define_machine(p2020_rdb) {
+	.name			= "P2020 RDB",
+	.probe			= p2020_rdb_probe,
+	.setup_arch		= mpc85xx_rdb_setup_arch,
+	.init_IRQ		= mpc85xx_rdb_pic_init,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index cc27807..a5ad1c7 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -267,6 +267,43 @@ arch_initcall(sbc8560_rtc_init);
 
 #endif	/* M48T59 */
 
+static __u8 __iomem *brstcr;
+
+static int __init sbc8560_bdrstcr_init(void)
+{
+	struct device_node *np;
+	struct resource res;
+
+	np = of_find_compatible_node(NULL, NULL, "wrs,sbc8560-brstcr");
+	if (np == NULL) {
+		printk(KERN_WARNING "sbc8560: No board specific RSTCR in DTB.\n");
+		return -ENODEV;
+	}
+
+	of_address_to_resource(np, 0, &res);
+
+	printk(KERN_INFO "sbc8560: Found BRSTCR at i/o 0x%x\n", res.start);
+
+	brstcr = ioremap(res.start, res.end - res.start);
+	if(!brstcr)
+		printk(KERN_WARNING "sbc8560: ioremap of brstcr failed.\n");
+
+	of_node_put(np);
+
+	return 0;
+}
+
+arch_initcall(sbc8560_bdrstcr_init);
+
+void sbc8560_rstcr_restart(char * cmd)
+{
+	local_irq_disable();
+	if(brstcr)
+		clrbits8(brstcr, 0x80);
+
+	while(1);
+}
+
 define_machine(sbc8560) {
 	.name			= "SBC8560",
 	.probe			= sbc8560_probe,
@@ -274,7 +311,7 @@ define_machine(sbc8560) {
 	.init_IRQ		= sbc8560_pic_init,
 	.show_cpuinfo		= sbc8560_show_cpuinfo,
 	.get_irq		= mpic_get_irq,
-	.restart		= fsl_rstcr_restart,
+	.restart		= sbc8560_rstcr_restart,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
 };
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 62c592e..04160a4 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -25,7 +25,6 @@
 
 #include <sysdev/fsl_soc.h>
 
-extern volatile unsigned long __secondary_hold_acknowledge;
 extern void __early_start(void);
 
 #define BOOT_ENTRY_ADDR_UPPER	0
@@ -80,46 +79,24 @@ smp_85xx_kick_cpu(int nr)
 }
 
 static void __init
-smp_85xx_basic_setup(int cpu_nr)
-{
-	/* Clear any pending timer interrupts */
-	mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
-
-	/* Enable decrementer interrupt */
-	mtspr(SPRN_TCR, TCR_DIE);
-}
-
-static void __init
 smp_85xx_setup_cpu(int cpu_nr)
 {
 	mpic_setup_this_cpu();
-
-	smp_85xx_basic_setup(cpu_nr);
 }
 
 struct smp_ops_t smp_85xx_ops = {
 	.kick_cpu = smp_85xx_kick_cpu,
 };
 
-static int __init smp_dummy_probe(void)
-{
-	return NR_CPUS;
-}
-
 void __init mpc85xx_smp_init(void)
 {
 	struct device_node *np;
 
-	smp_85xx_ops.message_pass = NULL;
-
 	np = of_find_node_by_type(NULL, "open-pic");
 	if (np) {
 		smp_85xx_ops.probe = smp_mpic_probe;
 		smp_85xx_ops.setup_cpu = smp_85xx_setup_cpu;
 		smp_85xx_ops.message_pass = smp_mpic_message_pass;
-	} else {
-		smp_85xx_ops.probe = smp_dummy_probe;
-		smp_85xx_ops.setup_cpu = smp_85xx_basic_setup;
 	}
 
 	if (cpu_has_feature(CPU_FTR_DBELL))
diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c
index 2efa052..287f7bd 100644
--- a/arch/powerpc/platforms/86xx/gef_ppc9a.c
+++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c
@@ -102,8 +102,8 @@ static unsigned int gef_ppc9a_get_pcb_rev(void)
 {
 	unsigned int reg;
 
-	reg = ioread32(ppc9a_regs);
-	return (reg >> 8) & 0xff;
+	reg = ioread32be(ppc9a_regs);
+	return (reg >> 16) & 0xff;
 }
 
 /* Return the board (software) revision */
@@ -111,8 +111,8 @@ static unsigned int gef_ppc9a_get_board_rev(void)
 {
 	unsigned int reg;
 
-	reg = ioread32(ppc9a_regs);
-	return (reg >> 16) & 0xff;
+	reg = ioread32be(ppc9a_regs);
+	return (reg >> 8) & 0xff;
 }
 
 /* Return the FPGA revision */
@@ -120,8 +120,26 @@ static unsigned int gef_ppc9a_get_fpga_rev(void)
 {
 	unsigned int reg;
 
-	reg = ioread32(ppc9a_regs);
-	return (reg >> 24) & 0xf;
+	reg = ioread32be(ppc9a_regs);
+	return reg & 0xf;
+}
+
+/* Return VME Geographical Address */
+static unsigned int gef_ppc9a_get_vme_geo_addr(void)
+{
+	unsigned int reg;
+
+	reg = ioread32be(ppc9a_regs + 0x4);
+	return reg & 0x1f;
+}
+
+/* Return VME System Controller Status */
+static unsigned int gef_ppc9a_get_vme_is_syscon(void)
+{
+	unsigned int reg;
+
+	reg = ioread32be(ppc9a_regs + 0x4);
+	return (reg >> 9) & 0x1;
 }
 
 static void gef_ppc9a_show_cpuinfo(struct seq_file *m)
@@ -131,10 +149,15 @@ static void gef_ppc9a_show_cpuinfo(struct seq_file *m)
 	seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n");
 
 	seq_printf(m, "Revision\t: %u%c\n", gef_ppc9a_get_pcb_rev(),
-		('A' + gef_ppc9a_get_board_rev() - 1));
+		('A' + gef_ppc9a_get_board_rev()));
 	seq_printf(m, "FPGA Revision\t: %u\n", gef_ppc9a_get_fpga_rev());
 
 	seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+	seq_printf(m, "VME geo. addr\t: %u\n", gef_ppc9a_get_vme_geo_addr());
+
+	seq_printf(m, "VME syscon\t: %s\n",
+		gef_ppc9a_get_vme_is_syscon() ? "yes" : "no");
 }
 
 static void __init gef_ppc9a_nec_fixup(struct pci_dev *pdev)
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 6632702..2aa69a6 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -105,7 +105,8 @@ mpc86xx_hpcn_setup_arch(void)
 #ifdef CONFIG_SWIOTLB
 	if (lmb_end_of_DRAM() > max) {
 		ppc_swiotlb_enable = 1;
-		set_pci_dma_ops(&swiotlb_pci_dma_ops);
+		set_pci_dma_ops(&swiotlb_dma_ops);
+		ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb;
 	}
 #endif
 }
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
index d84bbb5..eacea0e 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_smp.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c
@@ -27,7 +27,6 @@
 #include "mpc86xx.h"
 
 extern void __secondary_start_mpc86xx(void);
-extern unsigned long __secondary_hold_acknowledge;
 
 #define MCM_PORT_CONFIG_OFFSET	0x10
 
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 61187be..e382cae 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -57,15 +57,35 @@ config E200
 
 endchoice
 
-config PPC_BOOK3S_64
-	def_bool y
+choice
+	prompt "Processor Type"
 	depends on PPC64
+	help
+	  There are two families of 64 bit PowerPC chips supported.
+	  The most common ones are the desktop and server CPUs
+	  (POWER3, RS64, POWER4, POWER5, POWER5+, POWER6, ...)
+
+	  The other are the "embedded" processors compliant with the
+	  "Book 3E" variant of the architecture
+
+config PPC_BOOK3S_64
+	bool "Server processors"
 	select PPC_FPU
 
+config PPC_BOOK3E_64
+	bool "Embedded processors"
+	select PPC_FPU # Make it a choice ?
+
+endchoice
+
 config PPC_BOOK3S
 	def_bool y
 	depends on PPC_BOOK3S_32 || PPC_BOOK3S_64
 
+config PPC_BOOK3E
+	def_bool y
+	depends on PPC_BOOK3E_64
+
 config POWER4_ONLY
 	bool "Optimize for POWER4"
 	depends on PPC64 && PPC_BOOK3S
@@ -125,7 +145,7 @@ config 4xx
 
 config BOOKE
 	bool
-	depends on E200 || E500 || 44x
+	depends on E200 || E500 || 44x || PPC_BOOK3E
 	default y
 
 config FSL_BOOKE
@@ -223,9 +243,17 @@ config PPC_MMU_NOHASH
 	def_bool y
 	depends on !PPC_STD_MMU
 
+config PPC_MMU_NOHASH_32
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC32
+
+config PPC_MMU_NOHASH_64
+	def_bool y
+	depends on PPC_MMU_NOHASH && PPC64
+
 config PPC_BOOK3E_MMU
 	def_bool y
-	depends on FSL_BOOKE
+	depends on FSL_BOOKE || PPC_BOOK3E
 
 config PPC_MM_SLICES
 	bool
@@ -252,12 +280,12 @@ config PPC_HAVE_PMU_SUPPORT
 
 config PPC_PERF_CTRS
        def_bool y
-       depends on PERF_COUNTERS && PPC_HAVE_PMU_SUPPORT
+       depends on PERF_EVENTS && PPC_HAVE_PMU_SUPPORT
        help
-         This enables the powerpc-specific perf_counter back-end.
+         This enables the powerpc-specific perf_event back-end.
 
 config SMP
-	depends on PPC_STD_MMU || FSL_BOOKE
+	depends on PPC_BOOK3S || PPC_BOOK3E || FSL_BOOKE
 	bool "Symmetric multi-processing support"
 	---help---
 	  This enables support for systems with more than one CPU. If you have
diff --git a/arch/powerpc/platforms/amigaone/setup.c b/arch/powerpc/platforms/amigaone/setup.c
index 4430353..9290a7a 100644
--- a/arch/powerpc/platforms/amigaone/setup.c
+++ b/arch/powerpc/platforms/amigaone/setup.c
@@ -110,13 +110,16 @@ void __init amigaone_init_IRQ(void)
 	irq_set_default_host(i8259_get_host());
 }
 
-void __init amigaone_init(void)
+static int __init request_isa_regions(void)
 {
 	request_region(0x00, 0x20, "dma1");
 	request_region(0x40, 0x20, "timer");
 	request_region(0x80, 0x10, "dma page reg");
 	request_region(0xc0, 0x20, "dma2");
+
+	return 0;
 }
+machine_device_initcall(amigaone, request_isa_regions);
 
 void amigaone_restart(char *cmd)
 {
@@ -161,7 +164,6 @@ define_machine(amigaone) {
 	.name			= "AmigaOne",
 	.probe			= amigaone_probe,
 	.setup_arch		= amigaone_setup_arch,
-	.init			= amigaone_init,
 	.show_cpuinfo		= amigaone_show_cpuinfo,
 	.init_IRQ		= amigaone_init_IRQ,
 	.restart		= amigaone_restart,
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 50f17bd..48cd7d2 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -80,13 +80,6 @@ config SPU_FS_64K_LS
 	  uses 4K pages. This can improve performances of applications
 	  using multiple SPEs by lowering the TLB pressure on them.
 
-config SPU_TRACE
-	tristate "SPU event tracing support"
-	depends on SPU_FS && MARKERS
-	help
-	  This option allows reading a trace of spu-related events through
-	  the sputrace file in procfs.
-
 config SPU_BASE
 	bool
 	default n
diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c
index 07c234f..e538455 100644
--- a/arch/powerpc/platforms/cell/celleb_setup.c
+++ b/arch/powerpc/platforms/cell/celleb_setup.c
@@ -80,8 +80,7 @@ static void celleb_show_cpuinfo(struct seq_file *m)
 
 static int __init celleb_machine_type_hack(char *ptr)
 {
-	strncpy(celleb_machine_type, ptr, sizeof(celleb_machine_type));
-	celleb_machine_type[sizeof(celleb_machine_type)-1] = 0;
+	strlcpy(celleb_machine_type, ptr, sizeof(celleb_machine_type));
 	return 0;
 }
 
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 5b34fc2..416db17 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -642,7 +642,7 @@ static int dma_fixed_dma_supported(struct device *dev, u64 mask)
 
 static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
 
-struct dma_mapping_ops dma_iommu_fixed_ops = {
+struct dma_map_ops dma_iommu_fixed_ops = {
 	.alloc_coherent = dma_fixed_alloc_coherent,
 	.free_coherent  = dma_fixed_free_coherent,
 	.map_sg         = dma_fixed_map_sg,
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index bc97fad..f774530 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -58,8 +58,6 @@
  */
 static cpumask_t of_spin_map;
 
-extern void generic_secondary_smp_init(unsigned long);
-
 /**
  * smp_startup_cpu() - start the given cpu
  *
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
index 99610a6..b93f877 100644
--- a/arch/powerpc/platforms/cell/spufs/Makefile
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -4,7 +4,8 @@ spufs-y += inode.o file.o context.o syscalls.o coredump.o
 spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
 spufs-y += switch.o fault.o lscsa_alloc.o
 
-obj-$(CONFIG_SPU_TRACE)	+= sputrace.o
+# magic for the trace events
+CFLAGS_sched.o := -I$(src)
 
 # Rules to build switch.o with the help of SPU tool chain
 SPU_CROSS	:= spu-
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index db5398c..0c87bcd 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -28,6 +28,7 @@
 #include <asm/spu.h>
 #include <asm/spu_csa.h>
 #include "spufs.h"
+#include "sputrace.h"
 
 
 atomic_t nr_spu_contexts = ATOMIC_INIT(0);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index d6a519e..8f079b8 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -29,7 +29,6 @@
 #include <linux/poll.h>
 #include <linux/ptrace.h>
 #include <linux/seq_file.h>
-#include <linux/marker.h>
 
 #include <asm/io.h>
 #include <asm/time.h>
@@ -38,6 +37,7 @@
 #include <asm/uaccess.h>
 
 #include "spufs.h"
+#include "sputrace.h"
 
 #define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
 
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index f085369..4678078 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -39,7 +39,6 @@
 #include <linux/pid_namespace.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/marker.h>
 
 #include <asm/io.h>
 #include <asm/mmu_context.h>
@@ -47,6 +46,8 @@
 #include <asm/spu_csa.h>
 #include <asm/spu_priv1.h>
 #include "spufs.h"
+#define CREATE_TRACE_POINTS
+#include "sputrace.h"
 
 struct spu_prio_array {
 	DECLARE_BITMAP(bitmap, MAX_PRIO);
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index ae31573..c448bac 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -373,9 +373,4 @@ extern void spu_free_lscsa(struct spu_state *csa);
 extern void spuctx_switch_state(struct spu_context *ctx,
 		enum spu_utilization_state new_state);
 
-#define spu_context_trace(name, ctx, spu) \
-	trace_mark(name, "ctx %p spu %p", ctx, spu);
-#define spu_context_nospu_trace(name, ctx) \
-	trace_mark(name, "ctx %p", ctx);
-
 #endif
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
deleted file mode 100644
index d0b1f3f..0000000
--- a/arch/powerpc/platforms/cell/spufs/sputrace.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2007 IBM Deutschland Entwicklung GmbH
- *	Released under GPL v2.
- *
- * Partially based on net/ipv4/tcp_probe.c.
- *
- * Simple tracing facility for spu contexts.
- */
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/marker.h>
-#include <linux/proc_fs.h>
-#include <linux/wait.h>
-#include <asm/atomic.h>
-#include <asm/uaccess.h>
-#include "spufs.h"
-
-struct spu_probe {
-	const char *name;
-	const char *format;
-	marker_probe_func *probe_func;
-};
-
-struct sputrace {
-	ktime_t tstamp;
-	int owner_tid; /* owner */
-	int curr_tid;
-	const char *name;
-	int number;
-};
-
-static int bufsize __read_mostly = 16384;
-MODULE_PARM_DESC(bufsize, "Log buffer size (number of records)");
-module_param(bufsize, int, 0);
-
-
-static DEFINE_SPINLOCK(sputrace_lock);
-static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait);
-static ktime_t sputrace_start;
-static unsigned long sputrace_head, sputrace_tail;
-static struct sputrace *sputrace_log;
-static int sputrace_logging;
-
-static int sputrace_used(void)
-{
-	return (sputrace_head - sputrace_tail) % bufsize;
-}
-
-static inline int sputrace_avail(void)
-{
-	return bufsize - sputrace_used();
-}
-
-static int sputrace_sprint(char *tbuf, int n)
-{
-	const struct sputrace *t = sputrace_log + sputrace_tail % bufsize;
-	struct timespec tv =
-		ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
-
-	return snprintf(tbuf, n,
-		"[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n",
-		(unsigned long) tv.tv_sec,
-		(unsigned long) tv.tv_nsec,
-		t->curr_tid,
-		t->name,
-		t->owner_tid,
-		t->number);
-}
-
-static ssize_t sputrace_read(struct file *file, char __user *buf,
-		size_t len, loff_t *ppos)
-{
-	int error = 0, cnt = 0;
-
-	if (!buf || len < 0)
-		return -EINVAL;
-
-	while (cnt < len) {
-		char tbuf[128];
-		int width;
-
-		/* If we have data ready to return, don't block waiting
-		 * for more */
-		if (cnt > 0 && sputrace_used() == 0)
-			break;
-
-		error = wait_event_interruptible(sputrace_wait,
-						 sputrace_used() > 0);
-		if (error)
-			break;
-
-		spin_lock(&sputrace_lock);
-		if (sputrace_head == sputrace_tail) {
-			spin_unlock(&sputrace_lock);
-			continue;
-		}
-
-		width = sputrace_sprint(tbuf, sizeof(tbuf));
-		if (width < len)
-			sputrace_tail = (sputrace_tail + 1) % bufsize;
-		spin_unlock(&sputrace_lock);
-
-		if (width >= len)
-			break;
-
-		error = copy_to_user(buf + cnt, tbuf, width);
-		if (error)
-			break;
-		cnt += width;
-	}
-
-	return cnt == 0 ? error : cnt;
-}
-
-static int sputrace_open(struct inode *inode, struct file *file)
-{
-	int rc;
-
-	spin_lock(&sputrace_lock);
-	if (sputrace_logging) {
-		rc = -EBUSY;
-		goto out;
-	}
-
-	sputrace_logging = 1;
-	sputrace_head = sputrace_tail = 0;
-	sputrace_start = ktime_get();
-	rc = 0;
-
-out:
-	spin_unlock(&sputrace_lock);
-	return rc;
-}
-
-static int sputrace_release(struct inode *inode, struct file *file)
-{
-	spin_lock(&sputrace_lock);
-	sputrace_logging = 0;
-	spin_unlock(&sputrace_lock);
-	return 0;
-}
-
-static const struct file_operations sputrace_fops = {
-	.owner   = THIS_MODULE,
-	.open    = sputrace_open,
-	.read    = sputrace_read,
-	.release = sputrace_release,
-};
-
-static void sputrace_log_item(const char *name, struct spu_context *ctx,
-		struct spu *spu)
-{
-	spin_lock(&sputrace_lock);
-
-	if (!sputrace_logging) {
-		spin_unlock(&sputrace_lock);
-		return;
-	}
-
-	if (sputrace_avail() > 1) {
-		struct sputrace *t = sputrace_log + sputrace_head;
-
-		t->tstamp = ktime_get();
-		t->owner_tid = ctx->tid;
-		t->name = name;
-		t->curr_tid = current->pid;
-		t->number = spu ? spu->number : -1;
-
-		sputrace_head = (sputrace_head + 1) % bufsize;
-	} else {
-		printk(KERN_WARNING
-		       "sputrace: lost samples due to full buffer.\n");
-	}
-	spin_unlock(&sputrace_lock);
-
-	wake_up(&sputrace_wait);
-}
-
-static void spu_context_event(void *probe_private, void *call_data,
-		const char *format, va_list *args)
-{
-	struct spu_probe *p = probe_private;
-	struct spu_context *ctx;
-	struct spu *spu;
-
-	ctx = va_arg(*args, struct spu_context *);
-	spu = va_arg(*args, struct spu *);
-
-	sputrace_log_item(p->name, ctx, spu);
-}
-
-static void spu_context_nospu_event(void *probe_private, void *call_data,
-		const char *format, va_list *args)
-{
-	struct spu_probe *p = probe_private;
-	struct spu_context *ctx;
-
-	ctx = va_arg(*args, struct spu_context *);
-
-	sputrace_log_item(p->name, ctx, NULL);
-}
-
-struct spu_probe spu_probes[] = {
-	{ "spu_bind_context__enter", "ctx %p spu %p", spu_context_event },
-	{ "spu_unbind_context__enter", "ctx %p spu %p", spu_context_event },
-	{ "spu_get_idle__enter", "ctx %p", spu_context_nospu_event },
-	{ "spu_get_idle__found", "ctx %p spu %p", spu_context_event },
-	{ "spu_get_idle__not_found", "ctx %p", spu_context_nospu_event },
-	{ "spu_find_victim__enter", "ctx %p", spu_context_nospu_event },
-	{ "spusched_tick__preempt", "ctx %p spu %p", spu_context_event },
-	{ "spusched_tick__newslice", "ctx %p", spu_context_nospu_event },
-	{ "spu_yield__enter", "ctx %p", spu_context_nospu_event },
-	{ "spu_deactivate__enter", "ctx %p", spu_context_nospu_event },
-	{ "__spu_deactivate__unload", "ctx %p spu %p", spu_context_event },
-	{ "spufs_ps_fault__enter", "ctx %p", spu_context_nospu_event },
-	{ "spufs_ps_fault__sleep", "ctx %p", spu_context_nospu_event },
-	{ "spufs_ps_fault__wake", "ctx %p spu %p", spu_context_event },
-	{ "spufs_ps_fault__insert", "ctx %p spu %p", spu_context_event },
-	{ "spu_acquire_saved__enter", "ctx %p", spu_context_nospu_event },
-	{ "destroy_spu_context__enter", "ctx %p", spu_context_nospu_event },
-	{ "spufs_stop_callback__enter", "ctx %p spu %p", spu_context_event },
-};
-
-static int __init sputrace_init(void)
-{
-	struct proc_dir_entry *entry;
-	int i, error = -ENOMEM;
-
-	sputrace_log = kcalloc(bufsize, sizeof(struct sputrace), GFP_KERNEL);
-	if (!sputrace_log)
-		goto out;
-
-	entry = proc_create("sputrace", S_IRUSR, NULL, &sputrace_fops);
-	if (!entry)
-		goto out_free_log;
-
-	for (i = 0; i < ARRAY_SIZE(spu_probes); i++) {
-		struct spu_probe *p = &spu_probes[i];
-
-		error = marker_probe_register(p->name, p->format,
-					      p->probe_func, p);
-		if (error)
-			printk(KERN_INFO "Unable to register probe %s\n",
-					p->name);
-	}
-
-	return 0;
-
-out_free_log:
-	kfree(sputrace_log);
-out:
-	return -ENOMEM;
-}
-
-static void __exit sputrace_exit(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(spu_probes); i++)
-		marker_probe_unregister(spu_probes[i].name,
-			spu_probes[i].probe_func, &spu_probes[i]);
-
-	remove_proc_entry("sputrace", NULL);
-	kfree(sputrace_log);
-	marker_synchronize_unregister();
-}
-
-module_init(sputrace_init);
-module_exit(sputrace_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.h b/arch/powerpc/platforms/cell/spufs/sputrace.h
new file mode 100644
index 0000000..db2656a
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.h
@@ -0,0 +1,39 @@
+#if !defined(_TRACE_SPUFS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SPUFS_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM spufs
+
+TRACE_EVENT(spufs_context,
+	TP_PROTO(struct spu_context *ctx, struct spu *spu, const char *name),
+	TP_ARGS(ctx, spu, name),
+
+	TP_STRUCT__entry(
+		__field(const char *, name)
+		__field(int, owner_tid)
+		__field(int, number)
+	),
+
+	TP_fast_assign(
+		__entry->name = name;
+		__entry->owner_tid = ctx->tid;
+		__entry->number = spu ? spu->number : -1;
+	),
+
+	TP_printk("%s (ctxthread = %d, spu = %d)",
+		__entry->name, __entry->owner_tid, __entry->number)
+);
+
+#define spu_context_trace(name, ctx, spu) \
+	trace_spufs_context(ctx, spu, __stringify(name))
+#define spu_context_nospu_trace(name, ctx) \
+	trace_spufs_context(ctx, NULL, __stringify(name))
+
+#endif /* _TRACE_SPUFS_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE sputrace
+#include <trace/define_trace.h>
diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S
index 2f58152..5369653 100644
--- a/arch/powerpc/platforms/iseries/exception.S
+++ b/arch/powerpc/platforms/iseries/exception.S
@@ -47,7 +47,7 @@ system_reset_iSeries:
 	LOAD_REG_ADDR(r13, paca)
 	mulli	r0,r23,PACA_SIZE
 	add	r13,r13,r0
-	mtspr	SPRN_SPRG3,r13		/* Save it away for the future */
+	mtspr	SPRN_SPRG_PACA,r13	/* Save it away for the future */
 	mfmsr	r24
 	ori	r24,r24,MSR_RI
 	mtmsrd	r24			/* RI on */
@@ -116,7 +116,7 @@ iSeries_secondary_smp_loop:
 #endif /* CONFIG_SMP */
 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
 	sc				/* Invoke the hypervisor via a system call */
-	mfspr	r13,SPRN_SPRG3		/* Put r13 back ???? */
+	mfspr	r13,SPRN_SPRG_PACA	/* Put r13 back ???? */
 	b	2b			/* If SMP not configured, secondaries
 					 * loop forever */
 
@@ -126,34 +126,45 @@ iSeries_secondary_smp_loop:
 
 	.globl data_access_iSeries
 data_access_iSeries:
-	mtspr	SPRN_SPRG1,r13
+	mtspr	SPRN_SPRG_SCRATCH0,r13
 BEGIN_FTR_SECTION
-	mtspr	SPRN_SPRG2,r12
-	mfspr	r13,SPRN_DAR
-	mfspr	r12,SPRN_DSISR
-	srdi	r13,r13,60
-	rlwimi	r13,r12,16,0x20
-	mfcr	r12
-	cmpwi	r13,0x2c
+	mfspr	r13,SPRN_SPRG_PACA
+	std	r9,PACA_EXSLB+EX_R9(r13)
+	std	r10,PACA_EXSLB+EX_R10(r13)
+	mfspr	r10,SPRN_DAR
+	mfspr	r9,SPRN_DSISR
+	srdi	r10,r10,60
+	rlwimi	r10,r9,16,0x20
+	mfcr	r9
+	cmpwi	r10,0x2c
 	beq	.do_stab_bolted_iSeries
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+	ld	r10,PACA_EXSLB+EX_R10(r13)
+	std	r11,PACA_EXGEN+EX_R11(r13)
+	ld	r11,PACA_EXSLB+EX_R9(r13)
+	std	r12,PACA_EXGEN+EX_R12(r13)
+	mfspr	r12,SPRN_SPRG_SCRATCH0
+	std	r10,PACA_EXGEN+EX_R10(r13)
+	std	r11,PACA_EXGEN+EX_R9(r13)
+	std	r12,PACA_EXGEN+EX_R13(r13)
+	EXCEPTION_PROLOG_ISERIES_1
+FTR_SECTION_ELSE
 	EXCEPTION_PROLOG_1(PACA_EXGEN)
 	EXCEPTION_PROLOG_ISERIES_1
+ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
 	b	data_access_common
 
 .do_stab_bolted_iSeries:
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-	EXCEPTION_PROLOG_1(PACA_EXSLB)
+	std	r11,PACA_EXSLB+EX_R11(r13)
+	std	r12,PACA_EXSLB+EX_R12(r13)
+	mfspr	r10,SPRN_SPRG_SCRATCH0
+	std	r10,PACA_EXSLB+EX_R13(r13)
 	EXCEPTION_PROLOG_ISERIES_1
 	b	.do_stab_bolted
 
 	.globl	data_access_slb_iSeries
 data_access_slb_iSeries:
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
+	mtspr	SPRN_SPRG_SCRATCH0,r13	/* save r13 */
+	mfspr	r13,SPRN_SPRG_PACA	/* get paca address into r13 */
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_DAR
 	std	r9,PACA_EXSLB+EX_R9(r13)
@@ -165,7 +176,7 @@ data_access_slb_iSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
+	mfspr	r10,SPRN_SPRG_SCRATCH0
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	ld	r12,PACALPPACAPTR(r13)
 	ld	r12,LPPACASRR1(r12)
@@ -175,8 +186,8 @@ data_access_slb_iSeries:
 
 	.globl	instruction_access_slb_iSeries
 instruction_access_slb_iSeries:
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
+	mtspr	SPRN_SPRG_SCRATCH0,r13	/* save r13 */
+	mfspr	r13,SPRN_SPRG_PACA	/* get paca address into r13 */
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	ld	r3,PACALPPACAPTR(r13)
 	ld	r3,LPPACASRR0(r3)	/* get SRR0 value */
@@ -189,7 +200,7 @@ instruction_access_slb_iSeries:
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
+	mfspr	r10,SPRN_SPRG_SCRATCH0
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	ld	r12,PACALPPACAPTR(r13)
 	ld	r12,LPPACASRR1(r12)
@@ -200,7 +211,7 @@ slb_miss_user_iseries:
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r10,SPRG1
+	mfspr	r10,SPRG_SCRATCH0
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	ld	r12,PACA_EXSLB+EX_R3(r13)
 	std	r10,PACA_EXGEN+EX_R13(r13)
@@ -221,7 +232,7 @@ slb_miss_user_iseries:
 	.globl	system_call_iSeries
 system_call_iSeries:
 	mr	r9,r13
-	mfspr	r13,SPRN_SPRG3
+	mfspr	r13,SPRN_SPRG_PACA
 	EXCEPTION_PROLOG_ISERIES_1
 	b	system_call_common
 
diff --git a/arch/powerpc/platforms/iseries/exception.h b/arch/powerpc/platforms/iseries/exception.h
index ced45a8..bae3fba 100644
--- a/arch/powerpc/platforms/iseries/exception.h
+++ b/arch/powerpc/platforms/iseries/exception.h
@@ -24,7 +24,7 @@
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
-#include <asm/exception.h>
+#include <asm/exception-64s.h>
 
 #define EXCEPTION_PROLOG_ISERIES_1					\
 	mfmsr	r10;							\
@@ -38,7 +38,7 @@
 	.globl label##_iSeries;						\
 label##_iSeries:							\
 	HMT_MEDIUM;							\
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
+	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
 	EXCEPTION_PROLOG_1(area);					\
 	EXCEPTION_PROLOG_ISERIES_1;					\
 	b	label##_common
@@ -47,7 +47,7 @@ label##_iSeries:							\
 	.globl label##_iSeries;						\
 label##_iSeries:							\
 	HMT_MEDIUM;							\
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
+	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
 	EXCEPTION_PROLOG_1(PACA_EXGEN);					\
 	lbz	r10,PACASOFTIRQEN(r13);					\
 	cmpwi	0,r10,0;						\
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index fef4d51..0d9343d 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -872,7 +872,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
 		count = 256 - off;
 
 	dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE);
-	if (dma_mapping_error(NULL, dma_addr))
+	if (dma_addr == DMA_ERROR_CODE)
 		return -ENOMEM;
 	memset(page, 0, off + count);
 	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c
index 43911d8..75b296b 100644
--- a/arch/powerpc/platforms/pasemi/idle.c
+++ b/arch/powerpc/platforms/pasemi/idle.c
@@ -90,7 +90,7 @@ machine_late_initcall(pasemi, pasemi_idle_init);
 static int __init idle_param(char *p)
 {
 	int i;
-	for (i = 0; i < sizeof(modes)/sizeof(struct sleep_mode); i++) {
+	for (i = 0; i < ARRAY_SIZE(modes); i++) {
 		if (!strcmp(modes[i].name, p)) {
 			current_mode = i;
 			break;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 65c585b..08d94e4 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -44,14 +44,6 @@
  */
 #undef DEBUG_FREQ
 
-/*
- * There is a problem with the core cpufreq code on SMP kernels,
- * it won't recalculate the Bogomips properly
- */
-#ifdef CONFIG_SMP
-#warning "WARNING, CPUFREQ not recommended on SMP kernels"
-#endif
-
 extern void low_choose_7447a_dfs(int dfs);
 extern void low_choose_750fx_pll(int pll);
 extern void low_sleep_handler(void);
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index e6c0040..fbc9bbd 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2419,13 +2419,13 @@ static int __init probe_motherboard(void)
 	dt = of_find_node_by_name(NULL, "device-tree");
 	if (dt != NULL)
 		model = of_get_property(dt, "model", NULL);
-	for(i=0; model && i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+	for(i=0; model && i<ARRAY_SIZE(pmac_mb_defs); i++) {
 	    if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
 		pmac_mb = pmac_mb_defs[i];
 		goto found;
 	    }
 	}
-	for(i=0; i<(sizeof(pmac_mb_defs)/sizeof(struct pmac_mb_def)); i++) {
+	for(i=0; i<ARRAY_SIZE(pmac_mb_defs); i++) {
 	    if (machine_is_compatible(pmac_mb_defs[i].model_string)) {
 		pmac_mb = pmac_mb_defs[i];
 		goto found;
@@ -2589,9 +2589,16 @@ static void __init probe_uninorth(void)
 	if (address == 0)
 		return;
 	uninorth_base = ioremap(address, 0x40000);
+	if (uninorth_base == NULL)
+		return;
 	uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
-	if (uninorth_maj == 3 || uninorth_maj == 4)
+	if (uninorth_maj == 3 || uninorth_maj == 4) {
 		u3_ht_base = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
+		if (u3_ht_base == NULL) {
+			iounmap(uninorth_base);
+			return;
+		}
+	}
 
 	printk(KERN_INFO "Found %s memory controller & host bridge"
 	       " @ 0x%08x revision: 0x%02x\n", uninorth_maj == 3 ? "U3" :
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 04cdd32..e81403b 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -1286,3 +1286,64 @@ static void fixup_k2_sata(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
 
+/*
+ * On U4 (aka CPC945) the PCIe root complex "P2P" bridge resource ranges aren't
+ * configured by the firmware. The bridge itself seems to ignore them but it
+ * causes problems with Linux which then re-assigns devices below the bridge,
+ * thus changing addresses of those devices from what was in the device-tree,
+ * which sucks when those are video cards using offb
+ *
+ * We could just mark it transparent but I prefer fixing up the resources to
+ * properly show what's going on here, as I have some doubts about having them
+ * badly configured potentially being an issue for DMA.
+ *
+ * We leave PIO alone, it seems to be fine
+ *
+ * Oh and there's another funny bug. The OF properties advertize the region
+ * 0xf1000000..0xf1ffffff as being forwarded as memory space. But that's
+ * actually not true, this region is the memory mapped config space. So we
+ * also need to filter it out or we'll map things in the wrong place.
+ */
+static void fixup_u4_pcie(struct pci_dev* dev)
+{
+	struct pci_controller *host = pci_bus_to_host(dev->bus);
+	struct resource *region = NULL;
+	u32 reg;
+	int i;
+
+	/* Only do that on PowerMac */
+	if (!machine_is(powermac))
+		return;
+
+	/* Find the largest MMIO region */
+	for (i = 0; i < 3; i++) {
+		struct resource *r = &host->mem_resources[i];
+		if (!(r->flags & IORESOURCE_MEM))
+			continue;
+		/* Skip the 0xf0xxxxxx..f2xxxxxx regions, we know they
+		 * are reserved by HW for other things
+		 */
+		if (r->start >= 0xf0000000 && r->start < 0xf3000000)
+			continue;
+		if (!region || (r->end - r->start) >
+		    (region->end - region->start))
+			region = r;
+	}
+	/* Nothing found, bail */
+	if (region == 0)
+		return;
+
+	/* Print things out */
+	printk(KERN_INFO "PCI: Fixup U4 PCIe bridge range: %pR\n", region);
+
+	/* Fixup bridge config space. We know it's a Mac, resource aren't
+	 * offset so let's just blast them as-is. We also know that they
+	 * fit in 32 bits
+	 */
+	reg = ((region->start >> 16) & 0xfff0) | (region->end & 0xfff00000);
+	pci_write_config_dword(dev, PCI_MEMORY_BASE, reg);
+	pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0);
+	pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
+	pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U4_PCIE, fixup_u4_pcie);
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 6d4da7b..937a38e 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -408,7 +408,7 @@ static void __init smp_psurge_setup_cpu(int cpu_nr)
 	/* reset the entry point so if we get another intr we won't
 	 * try to startup again */
 	out_be32(psurge_start, 0x100);
-	if (setup_irq(30, &psurge_irqaction))
+	if (setup_irq(irq_create_mapping(NULL, 30), &psurge_irqaction))
 		printk(KERN_ERR "Couldn't get primary IPI interrupt");
 }
 
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 846eb8b..189a25b 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -23,8 +23,8 @@
 #include <linux/memory_hotplug.h>
 #include <linux/lmb.h>
 
+#include <asm/cell-regs.h>
 #include <asm/firmware.h>
-#include <asm/iommu.h>
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <asm/lv1call.h>
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index f6e04bc..51ffde4 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -37,7 +37,7 @@
   */
 
 #define MSG_COUNT 4
-static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]);
+static DEFINE_PER_CPU(unsigned int [MSG_COUNT], ps3_ipi_virqs);
 
 static void do_message_pass(int target, int msg)
 {
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 3f763c5..e34b305 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -27,7 +27,7 @@
 #include <asm/udbg.h>
 #include <asm/lv1call.h>
 #include <asm/firmware.h>
-#include <asm/iommu.h>
+#include <asm/cell-regs.h>
 
 #include "platform.h"
 
@@ -694,7 +694,7 @@ static int ps3_dma_supported(struct device *_dev, u64 mask)
 	return mask >= DMA_BIT_MASK(32);
 }
 
-static struct dma_mapping_ops ps3_sb_dma_ops = {
+static struct dma_map_ops ps3_sb_dma_ops = {
 	.alloc_coherent = ps3_alloc_coherent,
 	.free_coherent = ps3_free_coherent,
 	.map_sg = ps3_sb_map_sg,
@@ -704,7 +704,7 @@ static struct dma_mapping_ops ps3_sb_dma_ops = {
 	.unmap_page = ps3_unmap_page,
 };
 
-static struct dma_mapping_ops ps3_ioc0_dma_ops = {
+static struct dma_map_ops ps3_ioc0_dma_ops = {
 	.alloc_coherent = ps3_alloc_coherent,
 	.free_coherent = ps3_free_coherent,
 	.map_sg = ps3_ioc0_map_sg,
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 989d646..ccd8dd0 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -744,7 +744,15 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat
 
 static void __rtas_set_slot_reset(struct pci_dn *pdn)
 {
-	rtas_pci_slot_reset (pdn, 1);
+	struct pci_dev *dev = pdn->pcidev;
+
+	/* Determine type of EEH reset required by device,
+	 * default hot reset or fundamental reset
+	 */
+	if (dev->needs_freset)
+		rtas_pci_slot_reset(pdn, 3);
+	else
+		rtas_pci_slot_reset(pdn, 1);
 
 	/* The PCI bus requires that the reset be held high for at least
 	 * a 100 milliseconds. We wait a bit longer 'just in case'.  */
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index ad152a0..b6fa3e4 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -151,7 +151,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
 	if (dn->child)
 		eeh_add_device_tree_early(dn);
 
-	scan_phb(phb);
+	pcibios_scan_phb(phb, dn);
 	pcibios_finish_adding_to_bus(phb->bus);
 
 	return phb;
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index b6f1b13..2e2bbe1 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -20,6 +20,7 @@
 #include <asm/machdep.h>
 #include <asm/uaccess.h>
 #include <asm/pSeries_reconfig.h>
+#include <asm/mmu.h>
 
 
 
@@ -439,9 +440,15 @@ static int do_update_property(char *buf, size_t bufsize)
 	if (!newprop)
 		return -ENOMEM;
 
+	if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
+		slb_set_size(*(int *)value);
+
 	oldprop = of_find_property(np, name,NULL);
-	if (!oldprop)
+	if (!oldprop) {
+		if (strlen(name))
+			return prom_add_property(np, newprop);
 		return -ENODEV;
+	}
 
 	rc = prom_update_property(np, newprop, oldprop);
 	if (rc)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 8d75ea2..ca5f2e1 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -223,10 +223,6 @@ static void pseries_lpar_enable_pmcs(void)
 	set = 1UL << 63;
 	reset = 0;
 	plpar_hcall_norets(H_PERFMON, set, reset);
-
-	/* instruct hypervisor to maintain PMCs */
-	if (firmware_has_feature(FW_FEATURE_SPLPAR))
-		get_lppaca()->pmcregs_in_use = 1;
 }
 
 static void __init pseries_discover_pic(void)
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 1f8f6cf..440000c 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -56,8 +56,6 @@
  */
 static cpumask_t of_spin_map;
 
-extern void generic_secondary_smp_init(unsigned long);
-
 /**
  * smp_startup_cpu() - start the given cpu
  *
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index cbb3bed..757a83f 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -1057,6 +1057,10 @@ int fsl_rio_setup(struct of_device *dev)
 			law_start, law_size);
 
 	ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
+	if (!ops) {
+		rc = -ENOMEM;
+		goto err_ops;
+	}
 	ops->lcread = fsl_local_config_read;
 	ops->lcwrite = fsl_local_config_write;
 	ops->cread = fsl_rio_config_read;
@@ -1064,6 +1068,10 @@ int fsl_rio_setup(struct of_device *dev)
 	ops->dsend = fsl_rio_doorbell_send;
 
 	port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL);
+	if (!port) {
+		rc = -ENOMEM;
+		goto err_port;
+	}
 	port->id = 0;
 	port->index = 0;
 
@@ -1071,7 +1079,7 @@ int fsl_rio_setup(struct of_device *dev)
 	if (!priv) {
 		printk(KERN_ERR "Can't alloc memory for 'priv'\n");
 		rc = -ENOMEM;
-		goto err;
+		goto err_priv;
 	}
 
 	INIT_LIST_HEAD(&port->dbells);
@@ -1169,11 +1177,13 @@ int fsl_rio_setup(struct of_device *dev)
 
 	return 0;
 err:
-	if (priv)
-		iounmap(priv->regs_win);
-	kfree(ops);
+	iounmap(priv->regs_win);
 	kfree(priv);
+err_priv:
 	kfree(port);
+err_port:
+	kfree(ops);
+err_ops:
 	return rc;
 }
 
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 95dbc64..adca4af 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -37,6 +37,7 @@
 #include <asm/irq.h>
 #include <asm/time.h>
 #include <asm/prom.h>
+#include <asm/machdep.h>
 #include <sysdev/fsl_soc.h>
 #include <mm/mmu_decl.h>
 #include <asm/cpm2.h>
@@ -383,8 +384,9 @@ static int __init setup_rstcr(void)
 		if (!rstcr)
 			printk (KERN_EMERG "Error: reset control register "
 					"not mapped!\n");
-	} else
-		printk (KERN_INFO "rstcr compatible register does not exist!\n");
+	} else if (ppc_md.restart == fsl_rstcr_restart)
+		printk(KERN_ERR "No RSTCR register, warm reboot won't work\n");
+
 	if (np)
 		of_node_put(np);
 	return 0;
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 69e2630..cb7689c 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -735,8 +735,10 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 	ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
 				       NR_IPIC_INTS,
 				       &ipic_host_ops, 0);
-	if (ipic->irqhost == NULL)
+	if (ipic->irqhost == NULL) {
+		kfree(ipic);
 		return NULL;
+	}
 
 	ipic->regs = ioremap(res.start, res.end - res.start + 1);
 
@@ -781,6 +783,9 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 	primary_ipic = ipic;
 	irq_set_default_host(primary_ipic->irqhost);
 
+	ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
+	ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
+
 	printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
 			primary_ipic->regs);
 
diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c
index 7b49633..2073242 100644
--- a/arch/powerpc/sysdev/mmio_nvram.c
+++ b/arch/powerpc/sysdev/mmio_nvram.c
@@ -53,6 +53,23 @@ static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index)
 	return count;
 }
 
+static unsigned char mmio_nvram_read_val(int addr)
+{
+	unsigned long flags;
+	unsigned char val;
+
+	if (addr >= mmio_nvram_len)
+		return 0xff;
+
+	spin_lock_irqsave(&mmio_nvram_lock, flags);
+
+	val = ioread8(mmio_nvram_start + addr);
+
+	spin_unlock_irqrestore(&mmio_nvram_lock, flags);
+
+	return val;
+}
+
 static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index)
 {
 	unsigned long flags;
@@ -72,6 +89,19 @@ static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index)
 	return count;
 }
 
+void mmio_nvram_write_val(int addr, unsigned char val)
+{
+	unsigned long flags;
+
+	if (addr < mmio_nvram_len) {
+		spin_lock_irqsave(&mmio_nvram_lock, flags);
+
+		iowrite8(val, mmio_nvram_start + addr);
+
+		spin_unlock_irqrestore(&mmio_nvram_lock, flags);
+	}
+}
+
 static ssize_t mmio_nvram_get_size(void)
 {
 	return mmio_nvram_len;
@@ -114,6 +144,8 @@ int __init mmio_nvram_init(void)
 	printk(KERN_INFO "mmio NVRAM, %luk at 0x%lx mapped to %p\n",
 	       mmio_nvram_len >> 10, nvram_addr, mmio_nvram_start);
 
+	ppc_md.nvram_read_val	= mmio_nvram_read_val;
+	ppc_md.nvram_write_val	= mmio_nvram_write_val;
 	ppc_md.nvram_read	= mmio_nvram_read;
 	ppc_md.nvram_write	= mmio_nvram_write;
 	ppc_md.nvram_size	= mmio_nvram_get_size;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 3981ae4..30c44e6 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -230,14 +230,16 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne
 {
 	unsigned int	isu = src_no >> mpic->isu_shift;
 	unsigned int	idx = src_no & mpic->isu_mask;
+	unsigned int	val;
 
+	val = _mpic_read(mpic->reg_type, &mpic->isus[isu],
+			 reg + (idx * MPIC_INFO(IRQ_STRIDE)));
 #ifdef CONFIG_MPIC_BROKEN_REGREAD
 	if (reg == 0)
-		return mpic->isu_reg0_shadow[idx];
-	else
+		val = (val & (MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY)) |
+			mpic->isu_reg0_shadow[src_no];
 #endif
-		return _mpic_read(mpic->reg_type, &mpic->isus[isu],
-				  reg + (idx * MPIC_INFO(IRQ_STRIDE)));
+	return val;
 }
 
 static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -251,7 +253,8 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
 
 #ifdef CONFIG_MPIC_BROKEN_REGREAD
 	if (reg == 0)
-		mpic->isu_reg0_shadow[idx] = value;
+		mpic->isu_reg0_shadow[src_no] =
+			value & ~(MPIC_VECPRI_MASK | MPIC_VECPRI_ACTIVITY);
 #endif
 }
 
diff --git a/arch/powerpc/sysdev/qe_lib/gpio.c b/arch/powerpc/sysdev/qe_lib/gpio.c
index 3485288..8e7a776 100644
--- a/arch/powerpc/sysdev/qe_lib/gpio.c
+++ b/arch/powerpc/sysdev/qe_lib/gpio.c
@@ -105,14 +105,14 @@ static int qe_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 	struct qe_gpio_chip *qe_gc = to_qe_gpio_chip(mm_gc);
 	unsigned long flags;
 
+	qe_gpio_set(gc, gpio, val);
+
 	spin_lock_irqsave(&qe_gc->lock, flags);
 
 	__par_io_config_pin(mm_gc->regs, gpio, QE_PIO_DIR_OUT, 0, 0, 0);
 
 	spin_unlock_irqrestore(&qe_gc->lock, flags);
 
-	qe_gpio_set(gc, gpio, val);
-
 	return 0;
 }
 
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 237e365..464271b 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -65,6 +65,19 @@ static unsigned int qe_num_of_snum;
 
 static phys_addr_t qebase = -1;
 
+int qe_alive_during_sleep(void)
+{
+	static int ret = -1;
+
+	if (ret != -1)
+		return ret;
+
+	ret = !of_find_compatible_node(NULL, NULL, "fsl,mpc8569-pmc");
+
+	return ret;
+}
+EXPORT_SYMBOL(qe_alive_during_sleep);
+
 phys_addr_t get_qe_base(void)
 {
 	struct device_node *qe;
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 074905c..3faa42e 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -339,8 +339,10 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 
 	qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
 					NR_QE_IC_INTS, &qe_ic_host_ops, 0);
-	if (qe_ic->irqhost == NULL)
+	if (qe_ic->irqhost == NULL) {
+		kfree(qe_ic);
 		return;
+	}
 
 	qe_ic->regs = ioremap(res.start, res.end - res.start + 1);
 
@@ -352,6 +354,7 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
 
 	if (qe_ic->virq_low == NO_IRQ) {
 		printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
+		kfree(qe_ic);
 		return;
 	}
 
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index 85ab97a..faa81b6 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -2,6 +2,8 @@
 
 subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
 
+GCOV_PROFILE := n
+
 ifdef CONFIG_PPC64
 EXTRA_CFLAGS += -mno-minimal-toc
 endif
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index e1f33a8..0e09a45 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -2570,7 +2570,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
 	printf("%s", after);
 }
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3S_64
 static void dump_slb(void)
 {
 	int i;
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 1c866ef..43c0aca 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -94,7 +94,7 @@ config S390
 	select HAVE_KVM if 64BIT
 	select HAVE_ARCH_TRACEHOOK
 	select INIT_ALL_POSSIBLE
-	select HAVE_PERF_COUNTERS
+	select HAVE_PERF_EVENTS
 
 config SCHED_OMIT_FRAME_POINTER
 	bool
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
index 0b2f829..3dfcaeb 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -15,15 +15,6 @@
  */
 #include <linux/types.h>
 
-/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */
-struct kvm_pic_state {
-	/* no PIC for s390 */
-};
-
-struct kvm_ioapic_state {
-	/* no IOAPIC for s390 */
-};
-
 /* for KVM_GET_REGS and KVM_SET_REGS */
 struct kvm_regs {
 	/* general purpose regs for s390 */
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 698988f..27605b6 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -1,7 +1,7 @@
 /*
  * asm-s390/kvm_host.h - definition for kernel virtual machines on s390
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -40,7 +40,11 @@ struct sca_block {
 	struct sca_entry cpu[64];
 } __attribute__((packed));
 
-#define KVM_PAGES_PER_HPAGE 256
+#define KVM_NR_PAGE_SIZES 2
+#define KVM_HPAGE_SHIFT(x) (PAGE_SHIFT + ((x) - 1) * 8)
+#define KVM_HPAGE_SIZE(x) (1UL << KVM_HPAGE_SHIFT(x))
+#define KVM_HPAGE_MASK(x)	(~(KVM_HPAGE_SIZE(x) - 1))
+#define KVM_PAGES_PER_HPAGE(x)	(KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
 #define CPUSTAT_HOST       0x80000000
 #define CPUSTAT_WAIT       0x10000000
@@ -182,8 +186,9 @@ struct kvm_s390_interrupt_info {
 };
 
 /* for local_interrupt.action_flags */
-#define ACTION_STORE_ON_STOP 1
-#define ACTION_STOP_ON_STOP  2
+#define ACTION_STORE_ON_STOP		(1<<0)
+#define ACTION_STOP_ON_STOP		(1<<1)
+#define ACTION_RELOADVCPU_ON_STOP	(1<<2)
 
 struct kvm_s390_local_interrupt {
 	spinlock_t lock;
@@ -227,8 +232,6 @@ struct kvm_vm_stat {
 };
 
 struct kvm_arch{
-	unsigned long guest_origin;
-	unsigned long guest_memsize;
 	struct sca_block *sca;
 	debug_info_t *dbf;
 	struct kvm_s390_float_interrupt float_int;
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h
index 2c50379..6964db2 100644
--- a/arch/s390/include/asm/kvm_para.h
+++ b/arch/s390/include/asm/kvm_para.h
@@ -13,6 +13,8 @@
 #ifndef __S390_KVM_PARA_H
 #define __S390_KVM_PARA_H
 
+#ifdef __KERNEL__
+
 /*
  * Hypercalls for KVM on s390. The calling convention is similar to the
  * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1
@@ -147,4 +149,6 @@ static inline unsigned int kvm_arch_para_features(void)
 	return 0;
 }
 
+#endif
+
 #endif /* __S390_KVM_PARA_H */
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 408d60b..f7ad871 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -1,37 +1,21 @@
 #ifndef __ARCH_S390_PERCPU__
 #define __ARCH_S390_PERCPU__
 
-#include <linux/compiler.h>
-#include <asm/lowcore.h>
-
 /*
  * s390 uses its own implementation for per cpu data, the offset of
  * the cpu local data area is cached in the cpu's lowcore memory.
- * For 64 bit module code s390 forces the use of a GOT slot for the
- * address of the per cpu variable. This is needed because the module
- * may be more than 4G above the per cpu area.
  */
-#if defined(__s390x__) && defined(MODULE)
-
-#define SHIFT_PERCPU_PTR(ptr,offset) (({			\
-	extern int simple_identifier_##var(void);	\
-	unsigned long *__ptr;				\
-	asm ( "larl %0, %1@GOTENT"		\
-	    : "=a" (__ptr) : "X" (ptr) );		\
-	(typeof(ptr))((*__ptr) + (offset));	}))
-
-#else
-
-#define SHIFT_PERCPU_PTR(ptr, offset) (({				\
-	extern int simple_identifier_##var(void);		\
-	unsigned long __ptr;					\
-	asm ( "" : "=a" (__ptr) : "0" (ptr) );			\
-	(typeof(ptr)) (__ptr + (offset)); }))
+#define __my_cpu_offset S390_lowcore.percpu_offset
 
+/*
+ * For 64 bit module code, the module may be more than 4G above the
+ * per cpu area, use weak definitions to force the compiler to
+ * generate external references.
+ */
+#if defined(CONFIG_SMP) && defined(__s390x__) && defined(MODULE)
+#define ARCH_NEEDS_WEAK_PER_CPU
 #endif
 
-#define __my_cpu_offset S390_lowcore.percpu_offset
-
 #include <asm-generic/percpu.h>
 
 #endif /* __ARCH_S390_PERCPU__ */
diff --git a/arch/s390/include/asm/perf_counter.h b/arch/s390/include/asm/perf_counter.h
deleted file mode 100644
index 7015188..0000000
--- a/arch/s390/include/asm/perf_counter.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Performance counter support - s390 specific definitions.
- *
- * Copyright 2009 Martin Schwidefsky, IBM Corporation.
- */
-
-static inline void set_perf_counter_pending(void) {}
-static inline void clear_perf_counter_pending(void) {}
-
-#define PERF_COUNTER_INDEX_OFFSET 0
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h
new file mode 100644
index 0000000..3840cbe
--- /dev/null
+++ b/arch/s390/include/asm/perf_event.h
@@ -0,0 +1,10 @@
+/*
+ * Performance event support - s390 specific definitions.
+ *
+ * Copyright 2009 Martin Schwidefsky, IBM Corporation.
+ */
+
+static inline void set_perf_event_pending(void) {}
+static inline void clear_perf_event_pending(void) {}
+
+#define PERF_EVENT_INDEX_OFFSET 0
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h
index 02330c5..e42df89 100644
--- a/arch/s390/include/asm/socket.h
+++ b/arch/s390/include/asm/socket.h
@@ -65,4 +65,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* _ASM_SOCKET_H */
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h
index 24aa1cd..68d9fea 100644
--- a/arch/s390/include/asm/timex.h
+++ b/arch/s390/include/asm/timex.h
@@ -88,6 +88,14 @@ int get_sync_clock(unsigned long long *clock);
 void init_cpu_timer(void);
 unsigned long long monotonic_clock(void);
 
+void tod_to_timeval(__u64, struct timespec *);
+
+static inline
+void stck_to_timespec(unsigned long long stck, struct timespec *ts)
+{
+	tod_to_timeval(stck - TOD_UNIX_EPOCH, ts);
+}
+
 extern u64 sched_clock_base_cc;
 
 /**
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index c80602d..cb5232d 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -268,7 +268,7 @@
 #define	__NR_preadv		328
 #define	__NR_pwritev		329
 #define __NR_rt_tgsigqueueinfo	330
-#define __NR_perf_counter_open	331
+#define __NR_perf_event_open	331
 #define NR_syscalls 332
 
 /* 
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 88a8336..6247900 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1832,11 +1832,11 @@ compat_sys_rt_tgsigqueueinfo_wrapper:
 	llgtr	%r5,%r5			# struct compat_siginfo *
 	jg	compat_sys_rt_tgsigqueueinfo_wrapper # branch to system call
 
-	.globl	sys_perf_counter_open_wrapper
-sys_perf_counter_open_wrapper:
-	llgtr	%r2,%r2			# const struct perf_counter_attr *
+	.globl	sys_perf_event_open_wrapper
+sys_perf_event_open_wrapper:
+	llgtr	%r2,%r2			# const struct perf_event_attr *
 	lgfr	%r3,%r3			# pid_t
 	lgfr	%r4,%r4			# int
 	lgfr	%r5,%r5			# int
 	llgfr	%r6,%r6			# unsigned long
-	jg	sys_perf_counter_open	# branch to system call
+	jg	sys_perf_event_open	# branch to system call
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index be8bcea..4c51256 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -63,8 +63,6 @@ typedef struct
 } debug_sprintf_entry_t;
 
 
-extern void tod_to_timeval(uint64_t todval, struct timespec *xtime);
-
 /* internal function prototyes */
 
 static int debug_init(void);
@@ -1450,17 +1448,13 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
 			 int area, debug_entry_t * entry, char *out_buf)
 {
 	struct timespec time_spec;
-	unsigned long long time;
 	char *except_str;
 	unsigned long caller;
 	int rc = 0;
 	unsigned int level;
 
 	level = entry->id.fields.level;
-	time = entry->id.stck;
-	/* adjust todclock to 1970 */
-	time -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
-	tod_to_timeval(time, &time_spec);
+	stck_to_timespec(entry->id.stck, &time_spec);
 
 	if (entry->id.fields.exception)
 		except_str = "*";
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index c7ae4b1..e9d94f6 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -29,7 +29,6 @@
 #include <linux/personality.h>
 #include <linux/unistd.h>
 #include <linux/ipc.h>
-#include <linux/syscalls.h>
 #include <asm/uaccess.h>
 #include "entry.h"
 
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index ad1acd2..0b50836 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -339,4 +339,4 @@ SYSCALL(sys_epoll_create1,sys_epoll_create1,sys_epoll_create1_wrapper)
 SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
 SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
 SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */
-SYSCALL(sys_perf_counter_open,sys_perf_counter_open,sys_perf_counter_open_wrapper)
+SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 54e327e..34162a0 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -91,6 +91,7 @@ void tod_to_timeval(__u64 todval, struct timespec *xtime)
 	todval -= (sec * 1000000) << 12;
 	xtime->tv_nsec = ((todval * 1000) >> 12);
 }
+EXPORT_SYMBOL(tod_to_timeval);
 
 void clock_comparator_work(void)
 {
@@ -183,12 +184,14 @@ static void timing_alert_interrupt(__u16 code)
 static void etr_reset(void);
 static void stp_reset(void);
 
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-	struct timespec ts;
+	tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, ts);
+}
 
-	tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts);
-	return ts.tv_sec;
+void read_boot_clock(struct timespec *ts)
+{
+	tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, ts);
 }
 
 static cycle_t read_tod_clock(struct clocksource *cs)
@@ -206,6 +209,10 @@ static struct clocksource clocksource_tod = {
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+struct clocksource * __init clocksource_default_clock(void)
+{
+	return &clocksource_tod;
+}
 
 void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
 {
@@ -243,10 +250,6 @@ void update_vsyscall_tz(void)
  */
 void __init time_init(void)
 {
-	struct timespec ts;
-	unsigned long flags;
-	cycle_t now;
-
 	/* Reset time synchronization interfaces. */
 	etr_reset();
 	stp_reset();
@@ -262,26 +265,6 @@ void __init time_init(void)
 	if (clocksource_register(&clocksource_tod) != 0)
 		panic("Could not register TOD clock source");
 
-	/*
-	 * The TOD clock is an accurate clock. The xtime should be
-	 * initialized in a way that the difference between TOD and
-	 * xtime is reasonably small. Too bad that timekeeping_init
-	 * sets xtime.tv_nsec to zero. In addition the clock source
-	 * change from the jiffies clock source to the TOD clock
-	 * source add another error of up to 1/HZ second. The same
-	 * function sets wall_to_monotonic to a value that is too
-	 * small for /proc/uptime to be accurate.
-	 * Reset xtime and wall_to_monotonic to sane values.
-	 */
-	write_seqlock_irqsave(&xtime_lock, flags);
-	now = get_clock();
-	tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime);
-	clocksource_tod.cycle_last = now;
-	clocksource_tod.raw_time = xtime;
-	tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts);
-	set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec);
-	write_sequnlock_irqrestore(&xtime_lock, flags);
-
 	/* Enable TOD clock interrupts on the boot cpu. */
 	init_cpu_timer();
 
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 7315f9e..bc15ef9 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -84,13 +84,10 @@ SECTIONS
 
 	_end = . ;
 
-	/* Sections to be discarded */
-	/DISCARD/ : {
-		EXIT_DATA
-		*(.exitcall.exit)
-	}
-
 	/* Debugging sections.	*/
 	STABS_DEBUG
 	DWARF_DEBUG
+
+	/* Sections to be discarded */
+	DISCARDS
 }
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig
index 3e260b7..bf164fc 100644
--- a/arch/s390/kvm/Kconfig
+++ b/arch/s390/kvm/Kconfig
@@ -1,11 +1,7 @@
 #
 # KVM configuration
 #
-config HAVE_KVM
-       bool
-
-config HAVE_KVM_IRQCHIP
-       bool
+source "virt/kvm/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -38,9 +34,6 @@ config KVM
 
 	  If unsure, say N.
 
-config KVM_TRACE
-       bool
-
 # OK, it's a little counter-intuitive to do this, but it puts it neatly under
 # the virtualization menu.
 source drivers/virtio/Kconfig
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index ed60f3a..03c716a 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -1,7 +1,7 @@
 /*
  * gaccess.h -  access guest memory
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -16,13 +16,14 @@
 #include <linux/compiler.h>
 #include <linux/kvm_host.h>
 #include <asm/uaccess.h>
+#include "kvm-s390.h"
 
 static inline void __user *__guestaddr_to_user(struct kvm_vcpu *vcpu,
 					       unsigned long guestaddr)
 {
 	unsigned long prefix  = vcpu->arch.sie_block->prefix;
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if (guestaddr < 2 * PAGE_SIZE)
 		guestaddr += prefix;
@@ -158,8 +159,8 @@ static inline int copy_to_guest(struct kvm_vcpu *vcpu, unsigned long guestdest,
 				const void *from, unsigned long n)
 {
 	unsigned long prefix  = vcpu->arch.sie_block->prefix;
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if ((guestdest < 2 * PAGE_SIZE) && (guestdest + n > 2 * PAGE_SIZE))
 		goto slowpath;
@@ -209,8 +210,8 @@ static inline int copy_from_guest(struct kvm_vcpu *vcpu, void *to,
 				  unsigned long guestsrc, unsigned long n)
 {
 	unsigned long prefix  = vcpu->arch.sie_block->prefix;
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if ((guestsrc < 2 * PAGE_SIZE) && (guestsrc + n > 2 * PAGE_SIZE))
 		goto slowpath;
@@ -244,8 +245,8 @@ static inline int copy_to_guest_absolute(struct kvm_vcpu *vcpu,
 					 unsigned long guestdest,
 					 const void *from, unsigned long n)
 {
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if (guestdest + n > memsize)
 		return -EFAULT;
@@ -262,8 +263,8 @@ static inline int copy_from_guest_absolute(struct kvm_vcpu *vcpu, void *to,
 					   unsigned long guestsrc,
 					   unsigned long n)
 {
-	unsigned long origin  = vcpu->kvm->arch.guest_origin;
-	unsigned long memsize = vcpu->kvm->arch.guest_memsize;
+	unsigned long origin  = vcpu->arch.sie_block->gmsor;
+	unsigned long memsize = kvm_s390_vcpu_get_memsize(vcpu);
 
 	if (guestsrc + n > memsize)
 		return -EFAULT;
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 98997cc..ba9d8a7 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -1,7 +1,7 @@
 /*
  * intercept.c - in-kernel handling for sie intercepts
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -128,7 +128,7 @@ static int handle_noop(struct kvm_vcpu *vcpu)
 
 static int handle_stop(struct kvm_vcpu *vcpu)
 {
-	int rc;
+	int rc = 0;
 
 	vcpu->stat.exit_stop_request++;
 	atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags);
@@ -141,12 +141,18 @@ static int handle_stop(struct kvm_vcpu *vcpu)
 			rc = -ENOTSUPP;
 	}
 
+	if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) {
+		vcpu->arch.local_int.action_bits &= ~ACTION_RELOADVCPU_ON_STOP;
+		rc = SIE_INTERCEPT_RERUNVCPU;
+		vcpu->run->exit_reason = KVM_EXIT_INTR;
+	}
+
 	if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) {
 		vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP;
 		VCPU_EVENT(vcpu, 3, "%s", "cpu stopped");
 		rc = -ENOTSUPP;
-	} else
-		rc = 0;
+	}
+
 	spin_unlock_bh(&vcpu->arch.local_int.lock);
 	return rc;
 }
@@ -158,9 +164,9 @@ static int handle_validity(struct kvm_vcpu *vcpu)
 
 	vcpu->stat.exit_validity++;
 	if ((viwhy == 0x37) && (vcpu->arch.sie_block->prefix
-		<= vcpu->kvm->arch.guest_memsize - 2*PAGE_SIZE)){
+		<= kvm_s390_vcpu_get_memsize(vcpu) - 2*PAGE_SIZE)) {
 		rc = fault_in_pages_writeable((char __user *)
-			 vcpu->kvm->arch.guest_origin +
+			 vcpu->arch.sie_block->gmsor +
 			 vcpu->arch.sie_block->prefix,
 			 2*PAGE_SIZE);
 		if (rc)
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 4d61341..2c2f983 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -283,7 +283,7 @@ static int __try_deliver_ckc_interrupt(struct kvm_vcpu *vcpu)
 	return 1;
 }
 
-int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
+static int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
 {
 	struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
 	struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
@@ -320,12 +320,6 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
 	return rc;
 }
 
-int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
-{
-	/* do real check here */
-	return 1;
-}
-
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
 {
 	return 0;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 90d9d1b..07ced89 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1,7 +1,7 @@
 /*
  * s390host.c --  hosting zSeries kernel virtual machines
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -10,6 +10,7 @@
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
  *               Heiko Carstens <heiko.carstens@de.ibm.com>
+ *               Christian Ehrhardt <ehrhardt@de.ibm.com>
  */
 
 #include <linux/compiler.h>
@@ -210,13 +211,17 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 static void kvm_free_vcpus(struct kvm *kvm)
 {
 	unsigned int i;
+	struct kvm_vcpu *vcpu;
 
-	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		if (kvm->vcpus[i]) {
-			kvm_arch_vcpu_destroy(kvm->vcpus[i]);
-			kvm->vcpus[i] = NULL;
-		}
-	}
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		kvm_arch_vcpu_destroy(vcpu);
+
+	mutex_lock(&kvm->lock);
+	for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
+		kvm->vcpus[i] = NULL;
+
+	atomic_set(&kvm->online_vcpus, 0);
+	mutex_unlock(&kvm->lock);
 }
 
 void kvm_arch_sync_events(struct kvm *kvm)
@@ -278,16 +283,10 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
 	vcpu->arch.sie_block->gbea = 1;
 }
 
-/* The current code can have up to 256 pages for virtio */
-#define VIRTIODESCSPACE (256ul * 4096ul)
-
 int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
 {
 	atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH);
-	vcpu->arch.sie_block->gmslm = vcpu->kvm->arch.guest_memsize +
-				      vcpu->kvm->arch.guest_origin +
-				      VIRTIODESCSPACE - 1ul;
-	vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin;
+	set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests);
 	vcpu->arch.sie_block->ecb   = 2;
 	vcpu->arch.sie_block->eca   = 0xC1002001U;
 	vcpu->arch.sie_block->fac   = (int) (long) facilities;
@@ -319,8 +318,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
 	BUG_ON(!kvm->arch.sca);
 	if (!kvm->arch.sca->cpu[id].sda)
 		kvm->arch.sca->cpu[id].sda = (__u64) vcpu->arch.sie_block;
-	else
-		BUG_ON(!kvm->vcpus[id]); /* vcpu does already exist */
 	vcpu->arch.sie_block->scaoh = (__u32)(((__u64)kvm->arch.sca) >> 32);
 	vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
 
@@ -490,9 +487,15 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
 	vcpu_load(vcpu);
 
+rerun_vcpu:
+	if (vcpu->requests)
+		if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
+			kvm_s390_vcpu_set_mem(vcpu);
+
 	/* verify, that memory has been registered */
-	if (!vcpu->kvm->arch.guest_memsize) {
+	if (!vcpu->arch.sie_block->gmslm) {
 		vcpu_put(vcpu);
+		VCPU_EVENT(vcpu, 3, "%s", "no memory registered to run vcpu");
 		return -EINVAL;
 	}
 
@@ -509,6 +512,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr;
 		break;
 	case KVM_EXIT_UNKNOWN:
+	case KVM_EXIT_INTR:
 	case KVM_EXIT_S390_RESET:
 		break;
 	default:
@@ -522,8 +526,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		rc = kvm_handle_sie_intercept(vcpu);
 	} while (!signal_pending(current) && !rc);
 
-	if (signal_pending(current) && !rc)
+	if (rc == SIE_INTERCEPT_RERUNVCPU)
+		goto rerun_vcpu;
+
+	if (signal_pending(current) && !rc) {
+		kvm_run->exit_reason = KVM_EXIT_INTR;
 		rc = -EINTR;
+	}
 
 	if (rc == -ENOTSUPP) {
 		/* intercept cannot be handled in-kernel, prepare kvm-run */
@@ -676,6 +685,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
 				int user_alloc)
 {
 	int i;
+	struct kvm_vcpu *vcpu;
 
 	/* A few sanity checks. We can have exactly one memory slot which has
 	   to start at guest virtual zero and which has to be located at a
@@ -684,7 +694,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
 	   vmas. It is okay to mmap() and munmap() stuff in this slot after
 	   doing this call at any time */
 
-	if (mem->slot || kvm->arch.guest_memsize)
+	if (mem->slot)
 		return -EINVAL;
 
 	if (mem->guest_phys_addr)
@@ -699,36 +709,14 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
 	if (!user_alloc)
 		return -EINVAL;
 
-	/* lock all vcpus */
-	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		if (!kvm->vcpus[i])
+	/* request update of sie control block for all available vcpus */
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
 			continue;
-		if (!mutex_trylock(&kvm->vcpus[i]->mutex))
-			goto fail_out;
-	}
-
-	kvm->arch.guest_origin = mem->userspace_addr;
-	kvm->arch.guest_memsize = mem->memory_size;
-
-	/* update sie control blocks, and unlock all vcpus */
-	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		if (kvm->vcpus[i]) {
-			kvm->vcpus[i]->arch.sie_block->gmsor =
-				kvm->arch.guest_origin;
-			kvm->vcpus[i]->arch.sie_block->gmslm =
-				kvm->arch.guest_memsize +
-				kvm->arch.guest_origin +
-				VIRTIODESCSPACE - 1ul;
-			mutex_unlock(&kvm->vcpus[i]->mutex);
-		}
+		kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP);
 	}
 
 	return 0;
-
-fail_out:
-	for (; i >= 0; i--)
-		mutex_unlock(&kvm->vcpus[i]->mutex);
-	return -EINVAL;
 }
 
 void kvm_arch_flush_shadow(struct kvm *kvm)
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 748fee8..ec5eee7 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -1,7 +1,7 @@
 /*
  * kvm_s390.h -  definition for kvm on s390
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -9,6 +9,7 @@
  *
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
+ *               Christian Ehrhardt <ehrhardt@de.ibm.com>
  */
 
 #ifndef ARCH_S390_KVM_S390_H
@@ -18,8 +19,13 @@
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 
+/* The current code can have up to 256 pages for virtio */
+#define VIRTIODESCSPACE (256ul * 4096ul)
+
 typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
 
+/* negativ values are error codes, positive values for internal conditions */
+#define SIE_INTERCEPT_RERUNVCPU		(1<<0)
 int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
 
 #define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\
@@ -50,6 +56,30 @@ int kvm_s390_inject_vm(struct kvm *kvm,
 int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
 		struct kvm_s390_interrupt *s390int);
 int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
+int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
+
+static inline int kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.sie_block->gmslm
+		- vcpu->arch.sie_block->gmsor
+		- VIRTIODESCSPACE + 1ul;
+}
+
+static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu)
+{
+	struct kvm_memory_slot *mem;
+
+	down_read(&vcpu->kvm->slots_lock);
+	mem = &vcpu->kvm->memslots[0];
+
+	vcpu->arch.sie_block->gmsor = mem->userspace_addr;
+	vcpu->arch.sie_block->gmslm =
+		mem->userspace_addr +
+		(mem->npages << PAGE_SHIFT) +
+		VIRTIODESCSPACE - 1ul;
+
+	up_read(&vcpu->kvm->slots_lock);
+}
 
 /* implemented in priv.c */
 int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 0ef81d6..40c8c67 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -1,7 +1,7 @@
 /*
  * sigp.c - handlinge interprocessor communication
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008,2009
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License (version 2 only)
@@ -9,6 +9,7 @@
  *
  *    Author(s): Carsten Otte <cotte@de.ibm.com>
  *               Christian Borntraeger <borntraeger@de.ibm.com>
+ *               Christian Ehrhardt <ehrhardt@de.ibm.com>
  */
 
 #include <linux/kvm.h>
@@ -107,46 +108,57 @@ unlock:
 	return rc;
 }
 
-static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int store)
+static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
 {
-	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
-	struct kvm_s390_local_interrupt *li;
 	struct kvm_s390_interrupt_info *inti;
-	int rc;
-
-	if (cpu_addr >= KVM_MAX_VCPUS)
-		return 3; /* not operational */
 
 	inti = kzalloc(sizeof(*inti), GFP_KERNEL);
 	if (!inti)
 		return -ENOMEM;
-
 	inti->type = KVM_S390_SIGP_STOP;
 
-	spin_lock(&fi->lock);
-	li = fi->local_int[cpu_addr];
-	if (li == NULL) {
-		rc = 3; /* not operational */
-		kfree(inti);
-		goto unlock;
-	}
 	spin_lock_bh(&li->lock);
 	list_add_tail(&inti->list, &li->list);
 	atomic_set(&li->active, 1);
 	atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags);
-	if (store)
-		li->action_bits |= ACTION_STORE_ON_STOP;
-	li->action_bits |= ACTION_STOP_ON_STOP;
+	li->action_bits |= action;
 	if (waitqueue_active(&li->wq))
 		wake_up_interruptible(&li->wq);
 	spin_unlock_bh(&li->lock);
-	rc = 0; /* order accepted */
+
+	return 0; /* order accepted */
+}
+
+static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
+{
+	struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
+	struct kvm_s390_local_interrupt *li;
+	int rc;
+
+	if (cpu_addr >= KVM_MAX_VCPUS)
+		return 3; /* not operational */
+
+	spin_lock(&fi->lock);
+	li = fi->local_int[cpu_addr];
+	if (li == NULL) {
+		rc = 3; /* not operational */
+		goto unlock;
+	}
+
+	rc = __inject_sigp_stop(li, action);
+
 unlock:
 	spin_unlock(&fi->lock);
 	VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr);
 	return rc;
 }
 
+int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action)
+{
+	struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
+	return __inject_sigp_stop(li, action);
+}
+
 static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
 {
 	int rc;
@@ -177,9 +189,9 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
 	/* make sure that the new value is valid memory */
 	address = address & 0x7fffe000u;
 	if ((copy_from_guest(vcpu, &tmp,
-		(u64) (address + vcpu->kvm->arch.guest_origin) , 1)) ||
+		(u64) (address + vcpu->arch.sie_block->gmsor) , 1)) ||
 	   (copy_from_guest(vcpu, &tmp, (u64) (address +
-			vcpu->kvm->arch.guest_origin + PAGE_SIZE), 1))) {
+			vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) {
 		*reg |= SIGP_STAT_INVALID_PARAMETER;
 		return 1; /* invalid parameter */
 	}
@@ -262,11 +274,11 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
 		break;
 	case SIGP_STOP:
 		vcpu->stat.instruction_sigp_stop++;
-		rc = __sigp_stop(vcpu, cpu_addr, 0);
+		rc = __sigp_stop(vcpu, cpu_addr, ACTION_STOP_ON_STOP);
 		break;
 	case SIGP_STOP_STORE_STATUS:
 		vcpu->stat.instruction_sigp_stop++;
-		rc = __sigp_stop(vcpu, cpu_addr, 1);
+		rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP);
 		break;
 	case SIGP_SET_ARCH:
 		vcpu->stat.instruction_sigp_arch++;
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 1abbadd..6d50746 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -10,7 +10,7 @@
  *    Copyright (C) 1995  Linus Torvalds
  */
 
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -306,7 +306,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write)
 	 * interrupts again and then search the VMAs
 	 */
 	local_irq_enable();
-	perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 	down_read(&mm->mmap_sem);
 
 	si_code = SEGV_MAPERR;
@@ -366,11 +366,11 @@ good_area:
 	}
 	if (fault & VM_FAULT_MAJOR) {
 		tsk->maj_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
 				     regs, address);
 	} else {
 		tsk->min_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
         up_read(&mm->mmap_sem);
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
new file mode 100644
index 0000000..55d413e
--- /dev/null
+++ b/arch/score/Kconfig
@@ -0,0 +1,141 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+
+mainmenu "Linux/SCORE Kernel Configuration"
+
+menu "Machine selection"
+
+choice
+	prompt "System type"
+	default MACH_SPCT6600
+
+config ARCH_SCORE7
+	bool "SCORE7 processor"
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select CPU_SCORE7
+	select GENERIC_HAS_IOMAP
+
+config MACH_SPCT6600
+	bool "SPCT6600 series based machines"
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select CPU_SCORE7
+	select GENERIC_HAS_IOMAP
+
+config SCORE_SIM
+	bool "Score simulator"
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select CPU_SCORE7
+	select GENERIC_HAS_IOMAP
+endchoice
+
+endmenu
+
+config CPU_SCORE7
+	bool
+
+config GENERIC_IOMAP
+	def_bool y
+
+config NO_DMA
+	bool
+	default y
+
+config RWSEM_GENERIC_SPINLOCK
+	def_bool y
+
+config GENERIC_FIND_NEXT_BIT
+	def_bool y
+
+config GENERIC_HWEIGHT
+	def_bool y
+
+config GENERIC_CALIBRATE_DELAY
+	def_bool y
+
+config GENERIC_CLOCKEVENTS
+	def_bool y
+
+config GENERIC_TIME
+	def_bool y
+
+config SCHED_NO_NO_OMIT_FRAME_POINTER
+	def_bool y
+
+config GENERIC_HARDIRQS_NO__DO_IRQ
+	def_bool y
+
+config GENERIC_SYSCALL_TABLE
+	def_bool y
+
+config SCORE_L1_CACHE_SHIFT
+	int
+	default "4"
+
+menu "Kernel type"
+
+config 32BIT
+	def_bool y
+
+config GENERIC_HARDIRQS
+	def_bool y
+
+config ARCH_FLATMEM_ENABLE
+	def_bool y
+
+config ARCH_POPULATES_NODE_MAP
+	def_bool y
+
+source "mm/Kconfig"
+
+config MEMORY_START
+	hex
+	default	0xa0000000
+
+source "kernel/time/Kconfig"
+source "kernel/Kconfig.hz"
+source "kernel/Kconfig.preempt"
+
+endmenu
+
+config RWSEM_GENERIC_SPINLOCK
+	def_bool y
+
+config LOCKDEP_SUPPORT
+	def_bool y
+
+config STACKTRACE_SUPPORT
+	def_bool y
+
+source "init/Kconfig"
+
+config PROBE_INITRD_HEADER
+	bool "Probe initrd header created by addinitrd"
+	depends on BLK_DEV_INITRD
+	help
+	  Probe initrd header at the last page of kernel image.
+	  Say Y here if you are using arch/score/boot/addinitrd.c to
+	  add initrd or initramfs image to the kernel image.
+	  Otherwise, say N.
+
+config MMU
+	def_bool y
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/score/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/score/Kconfig.debug b/arch/score/Kconfig.debug
new file mode 100644
index 0000000..451ed54
--- /dev/null
+++ b/arch/score/Kconfig.debug
@@ -0,0 +1,37 @@
+menu "Kernel hacking"
+
+config TRACE_IRQFLAGS_SUPPORT
+	bool
+	default y
+
+source "lib/Kconfig.debug"
+
+config CMDLINE
+	string "Default kernel command string"
+	default ""
+	help
+	  On some platforms, there is currently no way for the boot loader to
+	  pass arguments to the kernel. For these platforms, you can supply
+	  some command-line options at build time by entering them here.  In
+	  other cases you can specify kernel args so that you don't have
+	  to set them up in board prom initialization routines.
+
+config DEBUG_STACK_USAGE
+	bool "Enable stack utilization instrumentation"
+	depends on DEBUG_KERNEL
+	help
+	  Enables the display of the minimum amount of free stack which each
+	  task has ever had available in the sysrq-T and sysrq-P debug output.
+
+	  This option will slow down process creation somewhat.
+
+config RUNTIME_DEBUG
+	bool "Enable run-time debugging"
+	depends on DEBUG_KERNEL
+	help
+	  If you say Y here, some debugging macros will do run-time checking.
+	  If you say N here, those macros will mostly turn to no-ops.  See
+	  include/asm-score/debug.h for debuging macros.
+	  If unsure, say N.
+
+endmenu
diff --git a/arch/score/Makefile b/arch/score/Makefile
new file mode 100644
index 0000000..68e0cd0
--- /dev/null
+++ b/arch/score/Makefile
@@ -0,0 +1,43 @@
+#
+# arch/score/Makefile
+#
+# 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.
+#
+
+KBUILD_DEFCONFIG := spct6600_defconfig
+CROSS_COMPILE := score-linux-
+
+#
+# CPU-dependent compiler/assembler options for optimization.
+#
+cflags-y += -G0 -pipe -mel -mnhwloop -D__SCOREEL__ \
+	-D__linux__ -ffunction-sections -ffreestanding
+
+#
+# Board-dependent options and extra files
+#
+KBUILD_AFLAGS += $(cflags-y)
+KBUILD_CFLAGS += $(cflags-y)
+MODFLAGS += -mlong-calls
+LDFLAGS += --oformat elf32-littlescore
+LDFLAGS_vmlinux	+= -G0 -static -nostdlib
+
+head-y := arch/score/kernel/head.o
+libs-y += arch/score/lib/
+core-y += arch/score/kernel/ arch/score/mm/
+
+boot := arch/score/boot
+
+vmlinux.bin: vmlinux
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+archclean:
+	@$(MAKE) $(clean)=$(boot)
+
+define archhelp
+	echo '  vmlinux.bin          - Raw binary boot image'
+	echo
+	echo '  These will be default as apropriate for a configured platform.'
+endef
diff --git a/arch/score/boot/Makefile b/arch/score/boot/Makefile
new file mode 100644
index 0000000..0c5fbd0
--- /dev/null
+++ b/arch/score/boot/Makefile
@@ -0,0 +1,15 @@
+#
+# arch/score/boot/Makefile
+#
+# 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.
+#
+
+targets	:= vmlinux.bin
+
+$(obj)/vmlinux.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+clean-files += vmlinux.bin
diff --git a/arch/score/configs/spct6600_defconfig b/arch/score/configs/spct6600_defconfig
new file mode 100644
index 0000000..e064943
--- /dev/null
+++ b/arch/score/configs/spct6600_defconfig
@@ -0,0 +1,717 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30-rc5
+# Fri Jun 12 18:57:07 2009
+#
+
+#
+# Machine selection
+#
+# CONFIG_ARCH_SCORE7 is not set
+CONFIG_MACH_SPCT6600=y
+# CONFIG_SCORE_SIM is not set
+CONFIG_CPU_SCORE7=y
+CONFIG_GENERIC_IOMAP=y
+CONFIG_NO_DMA=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_SYSCALL_TABLE=y
+CONFIG_SCORE_L1_CACHE_SHIFT=4
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+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_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_MEMORY_START=0xa0000000
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=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_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# 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=12
+# 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_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=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_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_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+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=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+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_PROBE_INITRD_HEADER is not set
+CONFIG_MMU=y
+
+#
+# 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=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+CONFIG_ARPD=y
+# 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=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_NETLABEL 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_PHONET 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_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 is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD 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=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+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_MISC_DEVICES 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_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
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET 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
+
+#
+# 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 is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_RIO is not set
+CONFIG_STALDRV=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+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 is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI 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 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT 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_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+# CONFIG_EXT2_FS_SECURITY is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+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
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_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_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
+# 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_NILFS2_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# 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 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# 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_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+# CONFIG_SECURITY_PATH is not set
+CONFIG_SECURITY_FILE_CAPABILITIES=y
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+# CONFIG_SECURITY_TOMOYO 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_RNG=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=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_CRYPTD=y
+# CONFIG_CRYPTO_AUTHENC is not set
+# 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=y
+
+#
+# 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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 is not set
+# 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 is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_NLATTR=y
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
new file mode 100644
index 0000000..b367abd
--- /dev/null
+++ b/arch/score/include/asm/Kbuild
@@ -0,0 +1,3 @@
+include include/asm-generic/Kbuild.asm
+
+header-y +=
diff --git a/arch/score/include/asm/asmmacro.h b/arch/score/include/asm/asmmacro.h
new file mode 100644
index 0000000..a04a54c
--- /dev/null
+++ b/arch/score/include/asm/asmmacro.h
@@ -0,0 +1,161 @@
+#ifndef _ASM_SCORE_ASMMACRO_H
+#define _ASM_SCORE_ASMMACRO_H
+
+#include <asm/asm-offsets.h>
+
+#ifdef __ASSEMBLY__
+
+.macro	SAVE_ALL
+	mfcr	r30, cr0
+	mv	r31, r0
+	nop
+	/* if UMs == 1, change stack. */
+	slli.c	r30, r30, 28
+	bpl	1f
+	la	r31, kernelsp
+	lw	r31, [r31]
+1:
+	mv	r30, r0
+	addri	r0, r31, -PT_SIZE
+
+	sw	r30, [r0, PT_R0]
+	.set	r1
+	sw	r1, [r0, PT_R1]
+	.set	nor1
+	sw	r2, [r0, PT_R2]
+	sw	r3, [r0, PT_R3]
+	sw	r4, [r0, PT_R4]
+	sw	r5, [r0, PT_R5]
+	sw	r6, [r0, PT_R6]
+	sw	r7, [r0, PT_R7]
+
+	sw	r8, [r0, PT_R8]
+	sw	r9, [r0, PT_R9]
+	sw	r10, [r0, PT_R10]
+	sw	r11, [r0, PT_R11]
+	sw	r12, [r0, PT_R12]
+	sw	r13, [r0, PT_R13]
+	sw	r14, [r0, PT_R14]
+	sw	r15, [r0, PT_R15]
+
+	sw	r16, [r0, PT_R16]
+	sw	r17, [r0, PT_R17]
+	sw	r18, [r0, PT_R18]
+	sw	r19, [r0, PT_R19]
+	sw	r20, [r0, PT_R20]
+	sw	r21, [r0, PT_R21]
+	sw	r22, [r0, PT_R22]
+	sw	r23, [r0, PT_R23]
+
+	sw	r24, [r0, PT_R24]
+	sw	r25, [r0, PT_R25]
+	sw	r25, [r0, PT_R25]
+	sw	r26, [r0, PT_R26]
+	sw	r27, [r0, PT_R27]
+
+	sw	r28, [r0, PT_R28]
+	sw	r29, [r0, PT_R29]
+	orri	r28, r0, 0x1fff
+	li	r31, 0x00001fff
+	xor	r28, r28, r31
+
+	mfcehl	r30, r31
+	sw	r30, [r0, PT_CEH]
+	sw	r31, [r0, PT_CEL]
+
+	mfcr	r31, cr0
+	sw	r31, [r0, PT_PSR]
+
+	mfcr	r31, cr1
+	sw	r31, [r0, PT_CONDITION]
+
+	mfcr	r31, cr2
+	sw	r31, [r0, PT_ECR]
+	
+	mfcr	r31, cr5
+	srli	r31, r31, 1
+	slli	r31, r31, 1
+	sw	r31, [r0, PT_EPC]
+.endm
+
+.macro	RESTORE_ALL_AND_RET
+	mfcr	r30, cr0
+	srli	r30, r30, 1
+	slli	r30, r30, 1
+	mtcr	r30, cr0
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	.set	r1
+	ldis	r1, 0x00ff
+	and	r30, r30, r1
+	not	r1, r1
+	lw	r31, [r0, PT_PSR]
+	and	r31, r31, r1
+	.set	nor1
+	or	r31, r31, r30
+	mtcr	r31, cr0
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	lw	r30, [r0, PT_CONDITION]
+	mtcr	r30, cr1
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	lw	r30, [r0, PT_CEH]
+	lw	r31, [r0, PT_CEL]
+	mtcehl	r30, r31
+
+	.set	r1
+	lw	r1, [r0, PT_R1]
+	.set	nor1
+	lw	r2, [r0, PT_R2]
+	lw	r3, [r0, PT_R3]
+	lw	r4, [r0, PT_R4]
+	lw	r5, [r0, PT_R5]
+	lw	r6, [r0, PT_R6]
+	lw	r7, [r0, PT_R7]
+
+	lw	r8, [r0, PT_R8]
+	lw	r9, [r0, PT_R9]
+	lw	r10, [r0, PT_R10]
+	lw	r11, [r0, PT_R11]
+	lw	r12, [r0, PT_R12]
+	lw	r13, [r0, PT_R13]
+	lw	r14, [r0, PT_R14]
+	lw	r15, [r0, PT_R15]
+
+	lw	r16, [r0, PT_R16]
+	lw	r17, [r0, PT_R17]
+	lw	r18, [r0, PT_R18]
+	lw	r19, [r0, PT_R19]
+	lw	r20, [r0, PT_R20]
+	lw	r21, [r0, PT_R21]
+	lw	r22, [r0, PT_R22]
+	lw	r23, [r0, PT_R23]
+
+	lw	r24, [r0, PT_R24]
+	lw	r25, [r0, PT_R25]
+	lw	r26, [r0, PT_R26]
+	lw	r27, [r0, PT_R27]
+	lw	r28, [r0, PT_R28]
+	lw	r29, [r0, PT_R29]
+
+	lw	r30, [r0, PT_EPC]
+	lw	r0, [r0, PT_R0]
+	mtcr	r30, cr5
+	rte
+.endm
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_SCORE_ASMMACRO_H */
diff --git a/arch/score/include/asm/atomic.h b/arch/score/include/asm/atomic.h
new file mode 100644
index 0000000..84eb8dd
--- /dev/null
+++ b/arch/score/include/asm/atomic.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_ATOMIC_H
+#define _ASM_SCORE_ATOMIC_H
+
+#include <asm-generic/atomic.h>
+
+#endif /* _ASM_SCORE_ATOMIC_H */
diff --git a/arch/score/include/asm/auxvec.h b/arch/score/include/asm/auxvec.h
new file mode 100644
index 0000000..f691515
--- /dev/null
+++ b/arch/score/include/asm/auxvec.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_SCORE_AUXVEC_H
+#define _ASM_SCORE_AUXVEC_H
+
+#endif /* _ASM_SCORE_AUXVEC_H */
diff --git a/arch/score/include/asm/bitops.h b/arch/score/include/asm/bitops.h
new file mode 100644
index 0000000..2763b05
--- /dev/null
+++ b/arch/score/include/asm/bitops.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_SCORE_BITOPS_H
+#define _ASM_SCORE_BITOPS_H
+
+#include <asm/byteorder.h> /* swab32 */
+#include <asm/system.h> /* save_flags */
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit()	barrier()
+#define smp_mb__after_clear_bit()	barrier()
+
+#include <asm-generic/bitops.h>
+#include <asm-generic/bitops/__fls.h>
+
+#endif /* _ASM_SCORE_BITOPS_H */
diff --git a/arch/score/include/asm/bitsperlong.h b/arch/score/include/asm/bitsperlong.h
new file mode 100644
index 0000000..86ff337
--- /dev/null
+++ b/arch/score/include/asm/bitsperlong.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_BITSPERLONG_H
+#define _ASM_SCORE_BITSPERLONG_H
+
+#include <asm-generic/bitsperlong.h>
+
+#endif /* _ASM_SCORE_BITSPERLONG_H */
diff --git a/arch/score/include/asm/bug.h b/arch/score/include/asm/bug.h
new file mode 100644
index 0000000..bb76a33
--- /dev/null
+++ b/arch/score/include/asm/bug.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_BUG_H
+#define _ASM_SCORE_BUG_H
+
+#include <asm-generic/bug.h>
+
+#endif /* _ASM_SCORE_BUG_H */
diff --git a/arch/score/include/asm/bugs.h b/arch/score/include/asm/bugs.h
new file mode 100644
index 0000000..a062e10
--- /dev/null
+++ b/arch/score/include/asm/bugs.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_BUGS_H
+#define _ASM_SCORE_BUGS_H
+
+#include <asm-generic/bugs.h>
+
+#endif /* _ASM_SCORE_BUGS_H */
diff --git a/arch/score/include/asm/byteorder.h b/arch/score/include/asm/byteorder.h
new file mode 100644
index 0000000..88cbebc
--- /dev/null
+++ b/arch/score/include/asm/byteorder.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_BYTEORDER_H
+#define _ASM_SCORE_BYTEORDER_H
+
+#include <linux/byteorder/little_endian.h>
+
+#endif /* _ASM_SCORE_BYTEORDER_H */
diff --git a/arch/score/include/asm/cache.h b/arch/score/include/asm/cache.h
new file mode 100644
index 0000000..ae3d59f
--- /dev/null
+++ b/arch/score/include/asm/cache.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_SCORE_CACHE_H
+#define _ASM_SCORE_CACHE_H
+
+#define L1_CACHE_SHIFT		4
+#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
+
+#endif /* _ASM_SCORE_CACHE_H */
diff --git a/arch/score/include/asm/cacheflush.h b/arch/score/include/asm/cacheflush.h
new file mode 100644
index 0000000..07cc8fc
--- /dev/null
+++ b/arch/score/include/asm/cacheflush.h
@@ -0,0 +1,45 @@
+#ifndef _ASM_SCORE_CACHEFLUSH_H
+#define _ASM_SCORE_CACHEFLUSH_H
+
+/* Keep includes the same across arches. */
+#include <linux/mm.h>
+
+extern void flush_cache_all(void);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct vm_area_struct *vma,
+				unsigned long start, unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma,
+				unsigned long page, unsigned long pfn);
+extern void flush_cache_sigtramp(unsigned long addr);
+extern void flush_icache_all(void);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void flush_dcache_range(unsigned long start, unsigned long end);
+
+#define flush_cache_dup_mm(mm)			do {} while (0)
+#define flush_dcache_page(page)			do {} while (0)
+#define flush_dcache_mmap_lock(mapping)		do {} while (0)
+#define flush_dcache_mmap_unlock(mapping)	do {} while (0)
+#define flush_cache_vmap(start, end)		do {} while (0)
+#define flush_cache_vunmap(start, end)		do {} while (0)
+
+static inline void flush_icache_page(struct vm_area_struct *vma,
+	struct page *page)
+{
+	if (vma->vm_flags & VM_EXEC) {
+		void *v = page_address(page);
+		flush_icache_range((unsigned long) v,
+				(unsigned long) v + PAGE_SIZE);
+	}
+}
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+	memcpy(dst, src, len)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)	\
+	do {							\
+		memcpy(dst, src, len);				\
+		if ((vma->vm_flags & VM_EXEC))			\
+			flush_cache_page(vma, vaddr, page_to_pfn(page));\
+	} while (0)
+
+#endif /* _ASM_SCORE_CACHEFLUSH_H */
diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h
new file mode 100644
index 0000000..f909ac3
--- /dev/null
+++ b/arch/score/include/asm/checksum.h
@@ -0,0 +1,235 @@
+#ifndef _ASM_SCORE_CHECKSUM_H
+#define _ASM_SCORE_CHECKSUM_H
+
+#include <linux/in6.h>
+#include <asm/uaccess.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+unsigned int csum_partial(const void *buff, int len, __wsum sum);
+unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len,
+					unsigned int sum, int *csum_err);
+unsigned int csum_partial_copy(const char *src, char *dst,
+					int len, unsigned int sum);
+
+/*
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ */
+
+/*
+ * Copy and checksum to user
+ */
+#define HAVE_CSUM_COPY_USER
+static inline
+__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,
+			__wsum sum, int *err_ptr)
+{
+	sum = csum_partial(src, len, sum);
+	if (copy_to_user(dst, src, len)) {
+		*err_ptr = -EFAULT;
+		return (__force __wsum) -1; /* invalid checksum */
+	}
+	return sum;
+}
+
+
+#define csum_partial_copy_nocheck csum_partial_copy
+/*
+ *	Fold a partial checksum without adding pseudo headers
+ */
+
+static inline __sum16 csum_fold(__wsum sum)
+{
+	/* the while loop is unnecessary really, it's always enough with two
+	   iterations */
+	__asm__ __volatile__(
+		".set volatile\n\t"
+		".set\tr1\n\t"
+		"slli\tr1,%0, 16\n\t"
+		"add\t%0,%0, r1\n\t"
+		"cmp.c\tr1, %0\n\t"
+		"srli\t%0, %0, 16\n\t"
+		"bleu\t1f\n\t"
+		"addi\t%0, 0x1\n\t"
+		"1:ldi\tr30, 0xffff\n\t"
+		"xor\t%0, %0, r30\n\t"
+		"slli\t%0, %0, 16\n\t"
+		"srli\t%0, %0, 16\n\t"
+		".set\tnor1\n\t"
+		".set optimize\n\t"
+		: "=r" (sum)
+		: "0" (sum));
+	return sum;
+}
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ *
+ *	By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
+ *	Arnt Gulbrandsen.
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+	unsigned int sum;
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+		".set volatile\n\t"
+		".set\tnor1\n\t"
+		"lw\t%0, [%1]\n\t"
+		"subri\t%2, %2, 4\n\t"
+		"slli\t%2, %2, 2\n\t"
+		"lw\t%3, [%1, 4]\n\t"
+		"add\t%2, %2, %1\n\t"
+		"add\t%0, %0, %3\n\t"
+		"cmp.c\t%3, %0\n\t"
+		"lw\t%3, [%1, 8]\n\t"
+		"bleu\t1f\n\t"
+		"addi\t%0, 0x1\n\t"
+		"1:\n\t"
+		"add\t%0, %0, %3\n\t"
+		"cmp.c\t%3, %0\n\t"
+		"lw\t%3, [%1, 12]\n\t"
+		"bleu\t1f\n\t"
+		"addi\t%0, 0x1\n\t"
+		"1:add\t%0, %0, %3\n\t"
+		"cmp.c\t%3, %0\n\t"
+		"bleu\t1f\n\t"
+		"addi\t%0, 0x1\n"
+
+		"1:\tlw\t%3, [%1, 16]\n\t"
+		"addi\t%1, 4\n\t"
+		"add\t%0, %0, %3\n\t"
+		"cmp.c\t%3, %0\n\t"
+		"bleu\t2f\n\t"
+		"addi\t%0, 0x1\n"
+		"2:cmp.c\t%2, %1\n\t"
+		"bne\t1b\n\t"
+
+		".set\tr1\n\t"
+		".set optimize\n\t"
+		: "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy)
+		: "1" (iph), "2" (ihl));
+
+	return csum_fold(sum);
+}
+
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+		unsigned short proto, __wsum sum)
+{
+	unsigned long tmp = (ntohs(len) << 16) + proto * 256;
+	__asm__ __volatile__(
+		".set volatile\n\t"
+		"add\t%0, %0, %2\n\t"
+		"cmp.c\t%2, %0\n\t"
+		"bleu\t1f\n\t"
+		"addi\t%0, 0x1\n\t"
+		"1:\n\t"
+		"add\t%0, %0, %3\n\t"
+		"cmp.c\t%3, %0\n\t"
+		"bleu\t1f\n\t"
+		"addi\t%0, 0x1\n\t"
+		"1:\n\t"
+		"add\t%0, %0, %4\n\t"
+		"cmp.c\t%4, %0\n\t"
+		"bleu\t1f\n\t"
+		"addi\t%0, 0x1\n\t"
+		"1:\n\t"
+		".set optimize\n\t"
+		: "=r" (sum)
+		: "0" (daddr), "r"(saddr),
+		"r" (tmp),
+		"r" (sum));
+	return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+		unsigned short proto, __wsum sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+
+static inline unsigned short ip_compute_csum(const void *buff, int len)
+{
+	return csum_fold(csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+				const struct in6_addr *daddr,
+				__u32 len, unsigned short proto,
+				__wsum sum)
+{
+	__asm__ __volatile__(
+		".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t"
+		".set\tnoat\n\t"
+		"addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t"
+		"sltu\t$1, %0, %5\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %6\t\t\t# csum\n\t"
+		"sltu\t$1, %0, %6\n\t"
+		"lw\t%1, 0(%2)\t\t\t# four words source address\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"lw\t%1, 4(%2)\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"lw\t%1, 8(%2)\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"lw\t%1, 12(%2)\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"lw\t%1, 0(%3)\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"lw\t%1, 4(%3)\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"lw\t%1, 8(%3)\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"lw\t%1, 12(%3)\n\t"
+		"addu\t%0, $1\n\t"
+		"addu\t%0, %1\n\t"
+		"sltu\t$1, %0, %1\n\t"
+		"addu\t%0, $1\t\t\t# Add final carry\n\t"
+		".set\tnoat\n\t"
+		".set\tnoreorder"
+		: "=r" (sum), "=r" (proto)
+		: "r" (saddr), "r" (daddr),
+		  "0" (htonl(len)), "1" (htonl(proto)), "r" (sum));
+
+	return csum_fold(sum);
+}
+#endif /* _ASM_SCORE_CHECKSUM_H */
diff --git a/arch/score/include/asm/cputime.h b/arch/score/include/asm/cputime.h
new file mode 100644
index 0000000..1fced99
--- /dev/null
+++ b/arch/score/include/asm/cputime.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_CPUTIME_H
+#define _ASM_SCORE_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* _ASM_SCORE_CPUTIME_H */
diff --git a/arch/score/include/asm/current.h b/arch/score/include/asm/current.h
new file mode 100644
index 0000000..16eae9c
--- /dev/null
+++ b/arch/score/include/asm/current.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_CURRENT_H
+#define _ASM_SCORE_CURRENT_H
+
+#include <asm-generic/current.h>
+
+#endif /* _ASM_SCORE_CURRENT_H */
diff --git a/arch/score/include/asm/delay.h b/arch/score/include/asm/delay.h
new file mode 100644
index 0000000..6726ec1
--- /dev/null
+++ b/arch/score/include/asm/delay.h
@@ -0,0 +1,26 @@
+#ifndef _ASM_SCORE_DELAY_H
+#define _ASM_SCORE_DELAY_H
+
+static inline void __delay(unsigned long loops)
+{
+	/* 3 cycles per loop. */
+	__asm__ __volatile__ (
+		"1:\tsubi\t%0, 3\n\t"
+		"cmpz.c\t%0\n\t"
+		"ble\t1b\n\t"
+		: "=r" (loops)
+		: "0" (loops));
+}
+
+static inline void __udelay(unsigned long usecs)
+{
+	unsigned long loops_per_usec;
+
+	loops_per_usec = (loops_per_jiffy * HZ) / 1000000;
+
+	__delay(usecs * loops_per_usec);
+}
+
+#define udelay(usecs) __udelay(usecs)
+
+#endif /* _ASM_SCORE_DELAY_H */
diff --git a/arch/score/include/asm/device.h b/arch/score/include/asm/device.h
new file mode 100644
index 0000000..2dc7cc5
--- /dev/null
+++ b/arch/score/include/asm/device.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_DEVICE_H
+#define _ASM_SCORE_DEVICE_H
+
+#include <asm-generic/device.h>
+
+#endif /* _ASM_SCORE_DEVICE_H */
diff --git a/arch/score/include/asm/div64.h b/arch/score/include/asm/div64.h
new file mode 100644
index 0000000..75fae19
--- /dev/null
+++ b/arch/score/include/asm/div64.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_DIV64_H
+#define _ASM_SCORE_DIV64_H
+
+#include <asm-generic/div64.h>
+
+#endif /* _ASM_SCORE_DIV64_H */
diff --git a/arch/score/include/asm/dma-mapping.h b/arch/score/include/asm/dma-mapping.h
new file mode 100644
index 0000000..f9c0193
--- /dev/null
+++ b/arch/score/include/asm/dma-mapping.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_DMA_MAPPING_H
+#define _ASM_SCORE_DMA_MAPPING_H
+
+#include <asm-generic/dma-mapping-broken.h>
+
+#endif /* _ASM_SCORE_DMA_MAPPING_H */
diff --git a/arch/score/include/asm/dma.h b/arch/score/include/asm/dma.h
new file mode 100644
index 0000000..9f44185
--- /dev/null
+++ b/arch/score/include/asm/dma.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_SCORE_DMA_H
+#define _ASM_SCORE_DMA_H
+
+#include <asm/io.h>
+
+#define MAX_DMA_ADDRESS		(0)
+
+#endif /* _ASM_SCORE_DMA_H */
diff --git a/arch/score/include/asm/elf.h b/arch/score/include/asm/elf.h
new file mode 100644
index 0000000..43526d9
--- /dev/null
+++ b/arch/score/include/asm/elf.h
@@ -0,0 +1,103 @@
+#ifndef _ASM_SCORE_ELF_H
+#define _ASM_SCORE_ELF_H
+
+#include <linux/ptrace.h>
+
+#define EM_SCORE7	135
+
+/* Relocation types. */
+#define R_SCORE_NONE		0
+#define R_SCORE_HI16		1
+#define R_SCORE_LO16		2
+#define R_SCORE_BCMP		3
+#define R_SCORE_24		4
+#define R_SCORE_PC19		5
+#define R_SCORE16_11		6
+#define R_SCORE16_PC8		7
+#define R_SCORE_ABS32		8
+#define R_SCORE_ABS16		9
+#define R_SCORE_DUMMY2		10
+#define R_SCORE_GP15		11
+#define R_SCORE_GNU_VTINHERIT	12
+#define R_SCORE_GNU_VTENTRY	13
+#define R_SCORE_GOT15		14
+#define R_SCORE_GOT_LO16	15
+#define R_SCORE_CALL15		16
+#define R_SCORE_GPREL32		17
+#define R_SCORE_REL32		18
+#define R_SCORE_DUMMY_HI16	19
+#define R_SCORE_IMM30		20
+#define R_SCORE_IMM32		21
+
+/* ELF register definitions */
+typedef unsigned long	elf_greg_t;
+
+#define ELF_NGREG	(sizeof(struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t	elf_gregset_t[ELF_NGREG];
+
+/* Score does not have fp regs. */
+typedef double		elf_fpreg_t;
+typedef elf_fpreg_t	elf_fpregset_t;
+
+#define elf_check_arch(x)	((x)->e_machine == EM_SCORE7)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_DATA	ELFDATA2LSB
+#define ELF_ARCH	EM_SCORE7
+
+#define SET_PERSONALITY(ex)					\
+do {								\
+	set_personality(PER_LINUX);				\
+} while (0)
+
+struct task_struct;
+struct pt_regs;
+
+#define CORE_DUMP_USE_REGSET
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	PAGE_SIZE
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  This could be done in userspace,
+   but it's not easy, and we've already done it here.  */
+
+#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.
+
+   For the moment, we have only optimizations for the Intel generations,
+   but that could change... */
+
+#define ELF_PLATFORM	(NULL)
+
+#define ELF_PLAT_INIT(_r, load_addr)					\
+do {									\
+	_r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0;	\
+	_r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0;	\
+	_r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0;	\
+	_r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0;	\
+	_r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0;	\
+	_r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0;	\
+	_r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0;	\
+	_r->regs[30] = _r->regs[31] = 0;				\
+} while (0)
+
+/* 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 ELF_ET_DYN_BASE
+#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
+#endif
+
+#endif /* _ASM_SCORE_ELF_H */
diff --git a/arch/score/include/asm/emergency-restart.h b/arch/score/include/asm/emergency-restart.h
new file mode 100644
index 0000000..ca31e98
--- /dev/null
+++ b/arch/score/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_EMERGENCY_RESTART_H
+#define _ASM_SCORE_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_SCORE_EMERGENCY_RESTART_H */
diff --git a/arch/score/include/asm/errno.h b/arch/score/include/asm/errno.h
new file mode 100644
index 0000000..29ff39d
--- /dev/null
+++ b/arch/score/include/asm/errno.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_ERRNO_H
+#define _ASM_SCORE_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif /* _ASM_SCORE_ERRNO_H */
diff --git a/arch/score/include/asm/fcntl.h b/arch/score/include/asm/fcntl.h
new file mode 100644
index 0000000..03968a3
--- /dev/null
+++ b/arch/score/include/asm/fcntl.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_FCNTL_H
+#define _ASM_SCORE_FCNTL_H
+
+#include <asm-generic/fcntl.h>
+
+#endif /* _ASM_SCORE_FCNTL_H */
diff --git a/arch/score/include/asm/fixmap.h b/arch/score/include/asm/fixmap.h
new file mode 100644
index 0000000..ee16766
--- /dev/null
+++ b/arch/score/include/asm/fixmap.h
@@ -0,0 +1,82 @@
+#ifndef _ASM_SCORE_FIXMAP_H
+#define _ASM_SCORE_FIXMAP_H
+
+#include <asm/page.h>
+
+#define PHY_RAM_BASE		0x00000000
+#define PHY_IO_BASE		0x10000000
+
+#define VIRTUAL_RAM_BASE	0xa0000000
+#define VIRTUAL_IO_BASE		0xb0000000
+
+#define RAM_SPACE_SIZE		0x10000000
+#define IO_SPACE_SIZE		0x10000000
+
+/* Kernel unmapped, cached 512MB */
+#define KSEG1			0xa0000000
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+
+/*
+ * on UP currently we will have no trace of the fixmap mechanizm,
+ * no page table allocations, etc. This might change in the
+ * future, say framebuffers for the console driver(s) could be
+ * fix-mapped?
+ */
+enum fixed_addresses {
+#define FIX_N_COLOURS 8
+	FIX_CMAP_BEGIN,
+	FIX_CMAP_END = FIX_CMAP_BEGIN + FIX_N_COLOURS,
+	__end_of_fixed_addresses
+};
+
+/*
+ * used by vmalloc.c.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap, and leave one page empty
+ * at the top of mem..
+ */
+#define FIXADDR_TOP	((unsigned long)(long)(int)0xfefe0000)
+#define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x)	\
+	((FIXADDR_TOP - ((x) & PAGE_MASK)) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+	return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+	return __virt_to_fix(vaddr);
+}
+
+#endif /* _ASM_SCORE_FIXMAP_H */
diff --git a/arch/score/include/asm/ftrace.h b/arch/score/include/asm/ftrace.h
new file mode 100644
index 0000000..79d6f10
--- /dev/null
+++ b/arch/score/include/asm/ftrace.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_SCORE_FTRACE_H
+#define _ASM_SCORE_FTRACE_H
+
+#endif /* _ASM_SCORE_FTRACE_H */
diff --git a/arch/score/include/asm/futex.h b/arch/score/include/asm/futex.h
new file mode 100644
index 0000000..1dca242
--- /dev/null
+++ b/arch/score/include/asm/futex.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_FUTEX_H
+#define _ASM_SCORE_FUTEX_H
+
+#include <asm-generic/futex.h>
+
+#endif /* _ASM_SCORE_FUTEX_H */
diff --git a/arch/score/include/asm/hardirq.h b/arch/score/include/asm/hardirq.h
new file mode 100644
index 0000000..dc932c5
--- /dev/null
+++ b/arch/score/include/asm/hardirq.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_HARDIRQ_H
+#define _ASM_SCORE_HARDIRQ_H
+
+#include <asm-generic/hardirq.h>
+
+#endif /* _ASM_SCORE_HARDIRQ_H */
diff --git a/arch/score/include/asm/hw_irq.h b/arch/score/include/asm/hw_irq.h
new file mode 100644
index 0000000..4caafb2
--- /dev/null
+++ b/arch/score/include/asm/hw_irq.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_SCORE_HW_IRQ_H
+#define _ASM_SCORE_HW_IRQ_H
+
+#endif /* _ASM_SCORE_HW_IRQ_H */
diff --git a/arch/score/include/asm/io.h b/arch/score/include/asm/io.h
new file mode 100644
index 0000000..fbbfd71
--- /dev/null
+++ b/arch/score/include/asm/io.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_SCORE_IO_H
+#define _ASM_SCORE_IO_H
+
+#include <asm-generic/io.h>
+
+#define virt_to_bus	virt_to_phys
+#define bus_to_virt	phys_to_virt
+
+#endif /* _ASM_SCORE_IO_H */
diff --git a/arch/score/include/asm/ioctl.h b/arch/score/include/asm/ioctl.h
new file mode 100644
index 0000000..a351d21
--- /dev/null
+++ b/arch/score/include/asm/ioctl.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_IOCTL_H
+#define _ASM_SCORE_IOCTL_H
+
+#include <asm-generic/ioctl.h>
+
+#endif /* _ASM_SCORE_IOCTL_H */
diff --git a/arch/score/include/asm/ioctls.h b/arch/score/include/asm/ioctls.h
new file mode 100644
index 0000000..ed01d2b
--- /dev/null
+++ b/arch/score/include/asm/ioctls.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_IOCTLS_H
+#define _ASM_SCORE_IOCTLS_H
+
+#include <asm-generic/ioctls.h>
+
+#endif /* _ASM_SCORE_IOCTLS_H */
diff --git a/arch/score/include/asm/ipcbuf.h b/arch/score/include/asm/ipcbuf.h
new file mode 100644
index 0000000..e082cef
--- /dev/null
+++ b/arch/score/include/asm/ipcbuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_IPCBUF_H
+#define _ASM_SCORE_IPCBUF_H
+
+#include <asm-generic/ipcbuf.h>
+
+#endif /* _ASM_SCORE_IPCBUF_H */
diff --git a/arch/score/include/asm/irq.h b/arch/score/include/asm/irq.h
new file mode 100644
index 0000000..c883f3d
--- /dev/null
+++ b/arch/score/include/asm/irq.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_SCORE_IRQ_H
+#define _ASM_SCORE_IRQ_H
+
+#define EXCEPTION_VECTOR_BASE_ADDR	0xa0000000
+#define VECTOR_ADDRESS_OFFSET_MODE4	0
+#define VECTOR_ADDRESS_OFFSET_MODE16	1
+
+#define DEBUG_VECTOR_SIZE		(0x4)
+#define DEBUG_VECTOR_BASE_ADDR		((EXCEPTION_VECTOR_BASE_ADDR) + 0x1fc)
+
+#define GENERAL_VECTOR_SIZE		(0x10)
+#define GENERAL_VECTOR_BASE_ADDR	((EXCEPTION_VECTOR_BASE_ADDR) + 0x200)
+
+#define NR_IRQS				64
+#define IRQ_VECTOR_SIZE			(0x10)
+#define IRQ_VECTOR_BASE_ADDR		((EXCEPTION_VECTOR_BASE_ADDR) + 0x210)
+#define IRQ_VECTOR_END_ADDR		((EXCEPTION_VECTOR_BASE_ADDR) + 0x5f0)
+
+#define irq_canonicalize(irq)	(irq)
+
+#define IRQ_TIMER (7)		/* Timer IRQ number of SPCT6600 */
+
+extern void interrupt_exception_vector(void);
+
+#endif /* _ASM_SCORE_IRQ_H */
diff --git a/arch/score/include/asm/irq_regs.h b/arch/score/include/asm/irq_regs.h
new file mode 100644
index 0000000..b8e881c
--- /dev/null
+++ b/arch/score/include/asm/irq_regs.h
@@ -0,0 +1,11 @@
+#ifndef _ASM_SCORE_IRQ_REGS_H
+#define _ASM_SCORE_IRQ_REGS_H
+
+#include <linux/thread_info.h>
+
+static inline struct pt_regs *get_irq_regs(void)
+{
+	return current_thread_info()->regs;
+}
+
+#endif /* _ASM_SCORE_IRQ_REGS_H */
diff --git a/arch/score/include/asm/irqflags.h b/arch/score/include/asm/irqflags.h
new file mode 100644
index 0000000..690a6ca
--- /dev/null
+++ b/arch/score/include/asm/irqflags.h
@@ -0,0 +1,109 @@
+#ifndef _ASM_SCORE_IRQFLAGS_H
+#define _ASM_SCORE_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+#define raw_local_irq_save(x)			\
+{						\
+	__asm__ __volatile__(			\
+		"mfcr	r8, cr0;"		\
+		"li	r9, 0xfffffffe;"	\
+		"nop;"				\
+		"mv	%0, r8;"		\
+		"and	r8, r8, r9;"		\
+		"mtcr	r8, cr0;"		\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		: "=r" (x)			\
+		:				\
+		: "r8", "r9"			\
+		);				\
+}
+
+#define raw_local_irq_restore(x)		\
+{						\
+	__asm__ __volatile__(			\
+		"mfcr	r8, cr0;"		\
+		"ldi	r9, 0x1;"		\
+		"and	%0, %0, r9;"		\
+		"or	r8, r8, %0;"		\
+		"mtcr	r8, cr0;"		\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		:				\
+		: "r"(x)			\
+		: "r8", "r9"			\
+		);				\
+}
+
+#define raw_local_irq_enable(void)		\
+{						\
+	__asm__ __volatile__(			\
+		"mfcr\tr8,cr0;"			\
+		"nop;"				\
+		"nop;"				\
+		"ori\tr8,0x1;"			\
+		"mtcr\tr8,cr0;"			\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		:				\
+		:				\
+		: "r8");			\
+}
+
+#define raw_local_irq_disable(void)		\
+{						\
+	__asm__ __volatile__(			\
+		"mfcr\tr8,cr0;"			\
+		"nop;"				\
+		"nop;"				\
+		"srli\tr8,r8,1;"		\
+		"slli\tr8,r8,1;"		\
+		"mtcr\tr8,cr0;"			\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		:				\
+		:				\
+		: "r8");			\
+}
+
+#define raw_local_save_flags(x)			\
+{						\
+	__asm__ __volatile__(			\
+		"mfcr	r8, cr0;"		\
+		"nop;"				\
+		"nop;"				\
+		"mv	%0, r8;"		\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"nop;"				\
+		"ldi	r9, 0x1;"		\
+		"and	%0, %0, r9;"		\
+		: "=r" (x)			\
+		:				\
+		: "r8", "r9"			\
+		);				\
+}
+
+static inline int raw_irqs_disabled_flags(unsigned long flags)
+{
+	return !(flags & 1);
+}
+
+#endif
+
+#endif /* _ASM_SCORE_IRQFLAGS_H */
diff --git a/arch/score/include/asm/kdebug.h b/arch/score/include/asm/kdebug.h
new file mode 100644
index 0000000..a666e51
--- /dev/null
+++ b/arch/score/include/asm/kdebug.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_KDEBUG_H
+#define _ASM_SCORE_KDEBUG_H
+
+#include <asm-generic/kdebug.h>
+
+#endif /* _ASM_SCORE_KDEBUG_H */
diff --git a/arch/score/include/asm/kmap_types.h b/arch/score/include/asm/kmap_types.h
new file mode 100644
index 0000000..6c46eb5
--- /dev/null
+++ b/arch/score/include/asm/kmap_types.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_KMAP_TYPES_H
+#define _ASM_SCORE_KMAP_TYPES_H
+
+#include <asm-generic/kmap_types.h>
+
+#endif /* _ASM_SCORE_KMAP_TYPES_H */
diff --git a/arch/score/include/asm/linkage.h b/arch/score/include/asm/linkage.h
new file mode 100644
index 0000000..2323a8e
--- /dev/null
+++ b/arch/score/include/asm/linkage.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_SCORE_LINKAGE_H
+#define _ASM_SCORE_LINKAGE_H
+
+#define __ALIGN .align 2
+#define __ALIGN_STR ".align 2"
+
+#endif /* _ASM_SCORE_LINKAGE_H */
diff --git a/arch/score/include/asm/local.h b/arch/score/include/asm/local.h
new file mode 100644
index 0000000..7e02f13
--- /dev/null
+++ b/arch/score/include/asm/local.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_LOCAL_H
+#define _ASM_SCORE_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _ASM_SCORE_LOCAL_H */
diff --git a/arch/score/include/asm/mman.h b/arch/score/include/asm/mman.h
new file mode 100644
index 0000000..84d85dd
--- /dev/null
+++ b/arch/score/include/asm/mman.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_MMAN_H
+#define _ASM_SCORE_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#endif /* _ASM_SCORE_MMAN_H */
diff --git a/arch/score/include/asm/mmu.h b/arch/score/include/asm/mmu.h
new file mode 100644
index 0000000..676828e
--- /dev/null
+++ b/arch/score/include/asm/mmu.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_MMU_H
+#define _ASM_SCORE_MMU_H
+
+typedef unsigned long mm_context_t;
+
+#endif /* _ASM_SCORE_MMU_H */
diff --git a/arch/score/include/asm/mmu_context.h b/arch/score/include/asm/mmu_context.h
new file mode 100644
index 0000000..2644577
--- /dev/null
+++ b/arch/score/include/asm/mmu_context.h
@@ -0,0 +1,113 @@
+#ifndef _ASM_SCORE_MMU_CONTEXT_H
+#define _ASM_SCORE_MMU_CONTEXT_H
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <asm-generic/mm_hooks.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/scoreregs.h>
+
+/*
+ * For the fast tlb miss handlers, we keep a per cpu array of pointers
+ * to the current pgd for each processor. Also, the proc. id is stuffed
+ * into the context register.
+ */
+extern unsigned long asid_cache;
+extern unsigned long pgd_current;
+
+#define TLBMISS_HANDLER_SETUP_PGD(pgd) (pgd_current = (unsigned long)(pgd))
+
+#define TLBMISS_HANDLER_SETUP()				\
+do {							\
+	write_c0_context(0);				\
+	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)	\
+} while (0)
+
+/*
+ * All unused by hardware upper bits will be considered
+ * as a software asid extension.
+ */
+#define ASID_VERSION_MASK	0xfffff000
+#define ASID_FIRST_VERSION	0x1000
+
+/* PEVN    --------- VPN ---------- --ASID--- -NA- */
+/* binary: 0000 0000 0000 0000 0000 0000 0001 0000 */
+/* binary: 0000 0000 0000 0000 0000 1111 1111 0000 */
+#define ASID_INC	0x10
+#define ASID_MASK	0xff0
+
+static inline void enter_lazy_tlb(struct mm_struct *mm,
+				struct task_struct *tsk)
+{}
+
+static inline void
+get_new_mmu_context(struct mm_struct *mm)
+{
+	unsigned long asid = asid_cache + ASID_INC;
+
+	if (!(asid & ASID_MASK)) {
+		local_flush_tlb_all();		/* start new asid cycle */
+		if (!asid)			/* fix version if needed */
+			asid = ASID_FIRST_VERSION;
+	}
+
+	mm->context = asid;
+	asid_cache = asid;
+}
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	mm->context = 0;
+	return 0;
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+			struct task_struct *tsk)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if ((next->context ^ asid_cache) & ASID_VERSION_MASK)
+		get_new_mmu_context(next);
+
+	pevn_set(next->context);
+	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
+	local_irq_restore(flags);
+}
+
+/*
+ * Destroy context related info for an mm_struct that is about
+ * to be put to rest.
+ */
+static inline void destroy_context(struct mm_struct *mm)
+{}
+
+static inline void
+deactivate_mm(struct task_struct *task, struct mm_struct *mm)
+{}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+static inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	get_new_mmu_context(next);
+	pevn_set(next->context);
+	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
+	local_irq_restore(flags);
+}
+
+#endif /* _ASM_SCORE_MMU_CONTEXT_H */
diff --git a/arch/score/include/asm/module.h b/arch/score/include/asm/module.h
new file mode 100644
index 0000000..f0b5dc0
--- /dev/null
+++ b/arch/score/include/asm/module.h
@@ -0,0 +1,39 @@
+#ifndef _ASM_SCORE_MODULE_H
+#define _ASM_SCORE_MODULE_H
+
+#include <linux/list.h>
+#include <asm/uaccess.h>
+
+struct mod_arch_specific {
+	/* Data Bus Error exception tables */
+	struct list_head dbe_list;
+	const struct exception_table_entry *dbe_start;
+	const struct exception_table_entry *dbe_end;
+};
+
+typedef uint8_t Elf64_Byte;		/* Type for a 8-bit quantity. */
+
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#define Elf_Ehdr	Elf32_Ehdr
+#define Elf_Addr	Elf32_Addr
+
+/* Given an address, look for it in the exception tables. */
+#ifdef CONFIG_MODULES
+const struct exception_table_entry *search_module_dbetables(unsigned long addr);
+#else
+static inline const struct exception_table_entry
+*search_module_dbetables(unsigned long addr)
+{
+	return NULL;
+}
+#endif
+
+#define MODULE_PROC_FAMILY "SCORE7"
+#define MODULE_KERNEL_TYPE "32BIT "
+#define MODULE_KERNEL_SMTC ""
+
+#define MODULE_ARCH_VERMAGIC \
+	MODULE_PROC_FAMILY MODULE_KERNEL_TYPE MODULE_KERNEL_SMTC
+
+#endif /* _ASM_SCORE_MODULE_H */
diff --git a/arch/score/include/asm/msgbuf.h b/arch/score/include/asm/msgbuf.h
new file mode 100644
index 0000000..7506721
--- /dev/null
+++ b/arch/score/include/asm/msgbuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_MSGBUF_H
+#define _ASM_SCORE_MSGBUF_H
+
+#include <asm-generic/msgbuf.h>
+
+#endif /* _ASM_SCORE_MSGBUF_H */
diff --git a/arch/score/include/asm/mutex.h b/arch/score/include/asm/mutex.h
new file mode 100644
index 0000000..10d48fe
--- /dev/null
+++ b/arch/score/include/asm/mutex.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_MUTEX_H
+#define _ASM_SCORE_MUTEX_H
+
+#include <asm-generic/mutex-dec.h>
+
+#endif /* _ASM_SCORE_MUTEX_H */
diff --git a/arch/score/include/asm/page.h b/arch/score/include/asm/page.h
new file mode 100644
index 0000000..ee58210
--- /dev/null
+++ b/arch/score/include/asm/page.h
@@ -0,0 +1,92 @@
+#ifndef _ASM_SCORE_PAGE_H
+#define _ASM_SCORE_PAGE_H
+
+#include <linux/pfn.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	(12)
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#define PAGE_UP(addr)	(((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1)))
+#define PAGE_DOWN(addr)	((addr)&(~((PAGE_SIZE)-1)))
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr, size)	(((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr, size)	((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr, size)	_ALIGN_UP(addr, size)
+
+/*
+ * PAGE_OFFSET -- the first address of the first page of memory. When not
+ * using MMU this corresponds to the first free page in physical memory (aligned
+ * on a page boundary).
+ */
+#define PAGE_OFFSET		(0xA0000000UL)
+
+#define clear_page(pgaddr)			memset((pgaddr), 0, PAGE_SIZE)
+#define copy_page(to, from)			memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(pgaddr, vaddr, page)	memset((pgaddr), 0, PAGE_SIZE)
+#define copy_user_page(vto, vfrom, vaddr, topg) \
+			memcpy((vto), (vfrom), PAGE_SIZE)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+
+typedef struct { unsigned long pte; } pte_t;		/* page table entry */
+typedef struct { unsigned long pgd; } pgd_t;		/* PGD table entry */
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct page *pgtable_t;
+
+#define pte_val(x)	((x).pte)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) })
+#define __pgd(x)	((pgd_t) { (x) })
+#define __pgprot(x)	((pgprot_t) { (x) })
+
+extern unsigned long max_low_pfn;
+extern unsigned long min_low_pfn;
+extern unsigned long max_pfn;
+
+#define __pa(x)		((unsigned long)(x) - PAGE_OFFSET)
+#define __va(x)		((void *)((unsigned long) (x) + PAGE_OFFSET))
+
+#define phys_to_pfn(phys)	(PFN_DOWN(phys))
+#define pfn_to_phys(pfn)	(PFN_PHYS(pfn))
+
+#define virt_to_pfn(vaddr)	(phys_to_pfn((__pa(vaddr))))
+#define pfn_to_virt(pfn)	__va(pfn_to_phys((pfn)))
+
+#define virt_to_page(vaddr)	(pfn_to_page(virt_to_pfn(vaddr)))
+#define page_to_virt(page)	(pfn_to_virt(page_to_pfn(page)))
+
+#define page_to_phys(page)	(pfn_to_phys(page_to_pfn(page)))
+#define page_to_bus(page)	(page_to_phys(page))
+#define phys_to_page(paddr)	(pfn_to_page(phys_to_pfn(paddr)))
+
+#define pfn_valid(pfn)		((pfn) >= min_low_pfn && (pfn) < max_mapnr)
+
+#define ARCH_PFN_OFFSET		(PAGE_OFFSET >> PAGE_SHIFT)
+
+#endif /* __ASSEMBLY__ */
+
+#define virt_addr_valid(vaddr)	(pfn_valid(virt_to_pfn(vaddr)))
+
+#endif /* __KERNEL__ */
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
+#endif /* _ASM_SCORE_PAGE_H */
diff --git a/arch/score/include/asm/param.h b/arch/score/include/asm/param.h
new file mode 100644
index 0000000..916b869
--- /dev/null
+++ b/arch/score/include/asm/param.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_PARAM_H
+#define _ASM_SCORE_PARAM_H
+
+#include <asm-generic/param.h>
+
+#endif /* _ASM_SCORE_PARAM_H */
diff --git a/arch/score/include/asm/pci.h b/arch/score/include/asm/pci.h
new file mode 100644
index 0000000..3f3cfd8
--- /dev/null
+++ b/arch/score/include/asm/pci.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_SCORE_PCI_H
+#define _ASM_SCORE_PCI_H
+
+#endif /* _ASM_SCORE_PCI_H */
diff --git a/arch/score/include/asm/percpu.h b/arch/score/include/asm/percpu.h
new file mode 100644
index 0000000..e7bd4e0
--- /dev/null
+++ b/arch/score/include/asm/percpu.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_PERCPU_H
+#define _ASM_SCORE_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif /* _ASM_SCORE_PERCPU_H */
diff --git a/arch/score/include/asm/pgalloc.h b/arch/score/include/asm/pgalloc.h
new file mode 100644
index 0000000..059a61b
--- /dev/null
+++ b/arch/score/include/asm/pgalloc.h
@@ -0,0 +1,83 @@
+#ifndef _ASM_SCORE_PGALLOC_H
+#define _ASM_SCORE_PGALLOC_H
+
+#include <linux/mm.h>
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+	pte_t *pte)
+{
+	set_pmd(pmd, __pmd((unsigned long)pte));
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+	pgtable_t pte)
+{
+	set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
+}
+
+#define pmd_pgtable(pmd)	pmd_page(pmd)
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+	pgd_t *ret, *init;
+
+	ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
+	if (ret) {
+		init = pgd_offset(&init_mm, 0UL);
+		pgd_init((unsigned long)ret);
+		memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+		(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+	}
+
+	return ret;
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+	free_pages((unsigned long)pgd, PGD_ORDER);
+}
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+	unsigned long address)
+{
+	pte_t *pte;
+
+	pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO,
+					PTE_ORDER);
+
+	return pte;
+}
+
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+	unsigned long address)
+{
+	struct page *pte;
+
+	pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
+	if (pte) {
+		clear_highpage(pte);
+		pgtable_page_ctor(pte);
+	}
+	return pte;
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	free_pages((unsigned long)pte, PTE_ORDER);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+	pgtable_page_dtor(pte);
+	__free_pages(pte, PTE_ORDER);
+}
+
+#define __pte_free_tlb(tlb, pte, buf)			\
+do {							\
+	pgtable_page_dtor(pte);				\
+	tlb_remove_page((tlb), pte);			\
+} while (0)
+
+#define check_pgt_cache()		do {} while (0)
+
+#endif /* _ASM_SCORE_PGALLOC_H */
diff --git a/arch/score/include/asm/pgtable-bits.h b/arch/score/include/asm/pgtable-bits.h
new file mode 100644
index 0000000..7d65a96
--- /dev/null
+++ b/arch/score/include/asm/pgtable-bits.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_SCORE_PGTABLE_BITS_H
+#define _ASM_SCORE_PGTABLE_BITS_H
+
+#define _PAGE_ACCESSED			(1<<5)	/* implemented in software */
+#define _PAGE_READ			(1<<6)	/* implemented in software */
+#define _PAGE_WRITE			(1<<7)	/* implemented in software */
+#define _PAGE_PRESENT			(1<<9)	/* implemented in software */
+#define _PAGE_MODIFIED			(1<<10)	/* implemented in software */
+#define _PAGE_FILE			(1<<10)
+
+#define _PAGE_GLOBAL			(1<<0)
+#define _PAGE_VALID			(1<<1)
+#define _PAGE_SILENT_READ		(1<<1)	/* synonym */
+#define _PAGE_DIRTY			(1<<2)	/* Write bit */
+#define _PAGE_SILENT_WRITE		(1<<2)
+#define _PAGE_CACHE			(1<<3)	/* cache */
+#define _CACHE_MASK			(1<<3)
+#define _PAGE_BUFFERABLE		(1<<4)	/*Fallow Spec. */
+
+#define __READABLE	(_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
+#define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
+#define _PAGE_CHG_MASK			\
+	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_CACHE)
+
+#endif /* _ASM_SCORE_PGTABLE_BITS_H */
diff --git a/arch/score/include/asm/pgtable.h b/arch/score/include/asm/pgtable.h
new file mode 100644
index 0000000..674934b
--- /dev/null
+++ b/arch/score/include/asm/pgtable.h
@@ -0,0 +1,287 @@
+#ifndef _ASM_SCORE_PGTABLE_H
+#define _ASM_SCORE_PGTABLE_H
+
+#include <linux/const.h>
+#include <asm-generic/pgtable-nopmd.h>
+
+#include <asm/fixmap.h>
+#include <asm/setup.h>
+#include <asm/pgtable-bits.h>
+
+extern void load_pgd(unsigned long pg_dir);
+extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT	22
+#define PGDIR_SIZE	(_AC(1, UL) << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE - 1))
+
+/*
+ * Entries per page directory level: we use two-level, so
+ * we don't really have any PUD/PMD directory physically.
+ */
+#define PGD_ORDER	0
+#define PTE_ORDER	0
+
+#define PTRS_PER_PGD	1024
+#define PTRS_PER_PTE	1024
+
+#define USER_PTRS_PER_PGD	(0x80000000UL/PGDIR_SIZE)
+#define FIRST_USER_ADDRESS	0
+
+#define VMALLOC_START		(0xc0000000UL)
+
+#define PKMAP_BASE		(0xfd000000UL)
+
+#define VMALLOC_END		(FIXADDR_START - 2*PAGE_SIZE)
+
+#define pte_ERROR(e) \
+	printk(KERN_ERR "%s:%d: bad pte %08lx.\n", \
+		__FILE__, __LINE__, pte_val(e))
+#define pgd_ERROR(e) \
+	printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", \
+		__FILE__, __LINE__, pgd_val(e))
+
+/*
+ * Empty pgd/pmd entries point to the invalid_pte_table.
+ */
+static inline int pmd_none(pmd_t pmd)
+{
+	return pmd_val(pmd) == (unsigned long) invalid_pte_table;
+}
+
+#define pmd_bad(pmd)		(pmd_val(pmd) & ~PAGE_MASK)
+
+static inline int pmd_present(pmd_t pmd)
+{
+	return pmd_val(pmd) != (unsigned long) invalid_pte_table;
+}
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+	pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
+}
+
+#define pte_page(x)		pfn_to_page(pte_pfn(x))
+#define pte_pfn(x)		((unsigned long)((x).pte >> PAGE_SHIFT))
+#define pfn_pte(pfn, prot)	\
+	__pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
+
+#define __pgd_offset(address)	pgd_index(address)
+#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address)	pgd_offset(&init_mm, address)
+#define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+/* to find an entry in a page-table-directory */
+#define pgd_offset(mm, addr)	((mm)->pgd + pgd_index(addr))
+
+/* Find an entry in the third-level page table.. */
+#define __pte_offset(address)		\
+	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset(dir, address)	\
+	((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
+#define pte_offset_kernel(dir, address)	\
+	((pte_t *) pmd_page_vaddr(*(dir)) + __pte_offset(address))
+
+#define pte_offset_map(dir, address)	\
+	((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
+#define pte_offset_map_nested(dir, address)	\
+	((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
+#define pte_unmap(pte) ((void)(pte))
+#define pte_unmap_nested(pte) ((void)(pte))
+
+/*
+ * Bits 9(_PAGE_PRESENT) and 10(_PAGE_FILE)are taken,
+ * split up 30 bits of offset into this range:
+ */
+#define PTE_FILE_MAX_BITS	30
+#define pte_to_pgoff(_pte)		\
+	(((_pte).pte & 0x1ff) | (((_pte).pte >> 11) << 9))
+#define pgoff_to_pte(off)		\
+	((pte_t) {((off) & 0x1ff) | (((off) >> 9) << 11) | _PAGE_FILE})
+#define __pte_to_swp_entry(pte)		\
+	((swp_entry_t) { pte_val(pte)})
+#define __swp_entry_to_pte(x)	((pte_t) {(x).val})
+
+#define pmd_phys(pmd)		__pa((void *)pmd_val(pmd))
+#define pmd_page(pmd)		(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
+#define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+#define pte_clear(mm, addr, xp)		\
+	do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)		\
+		remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+#define pgd_present(pgd)	(1)
+#define pgd_none(pgd)		(0)
+#define pgd_bad(pgd)		(0)
+#define pgd_clear(pgdp)		do { } while (0)
+
+#define kern_addr_valid(addr)	(1)
+#define pmd_page_vaddr(pmd)	pmd_val(pmd)
+
+#define pte_none(pte)		(!(pte_val(pte) & ~_PAGE_GLOBAL))
+#define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
+
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_CACHE)
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+				_PAGE_CACHE)
+#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_CACHE)
+#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_CACHE)
+#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+				_PAGE_GLOBAL | _PAGE_CACHE)
+#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
+				__WRITEABLE | _PAGE_GLOBAL & ~_PAGE_CACHE)
+
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+#define pgprot_noncached pgprot_noncached
+
+static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+{
+	unsigned long prot = pgprot_val(_prot);
+
+	prot = (prot & ~_CACHE_MASK);
+
+	return __pgprot(prot);
+}
+
+#define __swp_type(x)		((x).val & 0x1f)
+#define __swp_offset(x) 	((x).val >> 11)
+#define __swp_entry(type, offset) ((swp_entry_t){(type) | ((offset) << 11)})
+
+extern unsigned long empty_zero_page;
+extern unsigned long zero_page_mask;
+
+#define ZERO_PAGE(vaddr) \
+	(virt_to_page((void *)(empty_zero_page + \
+	 (((unsigned long)(vaddr)) & zero_page_mask))))
+
+#define pgtable_cache_init()	do {} while (0)
+
+#define arch_enter_lazy_cpu_mode()	do {} while (0)
+
+static inline int pte_write(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_WRITE;
+}
+
+static inline int pte_dirty(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_MODIFIED;
+}
+
+static inline int pte_young(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_ACCESSED;
+}
+
+static inline int pte_file(pte_t pte)
+{
+	return pte_val(pte) & _PAGE_FILE;
+}
+
+#define pte_special(pte)	(0)
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+	return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
+	return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
+	return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_WRITE;
+	if (pte_val(pte) & _PAGE_MODIFIED)
+		pte_val(pte) |= _PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_MODIFIED;
+	if (pte_val(pte) & _PAGE_WRITE)
+		pte_val(pte) |= _PAGE_SILENT_WRITE;
+	return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_ACCESSED;
+	if (pte_val(pte) & _PAGE_READ)
+		pte_val(pte) |= _PAGE_SILENT_READ;
+	return pte;
+}
+
+#define set_pmd(pmdptr, pmdval)		\
+	 do { *(pmdptr) = (pmdval); } while (0)
+#define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
+
+extern unsigned long pgd_current;
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern void paging_init(void);
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
+}
+
+extern void __update_tlb(struct vm_area_struct *vma,
+	unsigned long address,	pte_t pte);
+extern void __update_cache(struct vm_area_struct *vma,
+	unsigned long address,	pte_t pte);
+
+static inline void update_mmu_cache(struct vm_area_struct *vma,
+	unsigned long address, pte_t pte)
+{
+	__update_tlb(vma, address, pte);
+	__update_cache(vma, address, pte);
+}
+
+#ifndef __ASSEMBLY__
+#include <asm-generic/pgtable.h>
+
+void setup_memory(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_SCORE_PGTABLE_H */
diff --git a/arch/score/include/asm/poll.h b/arch/score/include/asm/poll.h
new file mode 100644
index 0000000..18532db
--- /dev/null
+++ b/arch/score/include/asm/poll.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_POLL_H
+#define _ASM_SCORE_POLL_H
+
+#include <asm-generic/poll.h>
+
+#endif /* _ASM_SCORE_POLL_H */
diff --git a/arch/score/include/asm/posix_types.h b/arch/score/include/asm/posix_types.h
new file mode 100644
index 0000000..b88acf8
--- /dev/null
+++ b/arch/score/include/asm/posix_types.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_POSIX_TYPES_H
+#define _ASM_SCORE_POSIX_TYPES_H
+
+#include <asm-generic/posix_types.h>
+
+#endif /* _ASM_SCORE_POSIX_TYPES_H */
diff --git a/arch/score/include/asm/processor.h b/arch/score/include/asm/processor.h
new file mode 100644
index 0000000..7e22f21
--- /dev/null
+++ b/arch/score/include/asm/processor.h
@@ -0,0 +1,106 @@
+#ifndef _ASM_SCORE_PROCESSOR_H
+#define _ASM_SCORE_PROCESSOR_H
+
+#include <linux/cpumask.h>
+#include <linux/threads.h>
+
+#include <asm/segment.h>
+
+struct task_struct;
+
+/*
+ * System setup and hardware flags..
+ */
+extern void (*cpu_wait)(void);
+
+extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+extern void start_thread(struct pt_regs *regs,
+			unsigned long pc, unsigned long sp);
+extern unsigned long get_wchan(struct task_struct *p);
+
+/*
+ * Return current * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+#define cpu_relax()		barrier()
+#define release_thread(thread)	do {} while (0)
+#define prepare_to_copy(tsk)	do {} while (0)
+
+/*
+ * User space process size: 2GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ */
+#define TASK_SIZE	0x7fff8000UL
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE	((TASK_SIZE / 3) & ~(PAGE_SIZE))
+
+#ifdef __KERNEL__
+#define STACK_TOP	TASK_SIZE
+#define STACK_TOP_MAX	TASK_SIZE
+#endif
+
+/*
+ * If you change thread_struct remember to change the #defines below too!
+ */
+struct thread_struct {
+	unsigned long reg0, reg2, reg3;
+	unsigned long reg12, reg13, reg14, reg15, reg16;
+	unsigned long reg17, reg18, reg19, reg20, reg21;
+
+	unsigned long cp0_psr;
+	unsigned long cp0_ema;		/* Last user fault */
+	unsigned long cp0_badvaddr;	/* Last user fault */
+	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */
+	unsigned long error_code;
+	unsigned long trap_no;
+
+	unsigned long mflags;
+	unsigned long reg29;
+
+	unsigned long single_step;
+	unsigned long ss_nextcnt;
+
+	unsigned long insn1_type;
+	unsigned long addr1;
+	unsigned long insn1;
+
+	unsigned long insn2_type;
+	unsigned long addr2;
+	unsigned long insn2;
+
+	mm_segment_t current_ds;
+};
+
+#define INIT_THREAD {						\
+	.reg0			= 0,				\
+	.reg2			= 0,				\
+	.reg3			= 0,				\
+	.reg12			= 0,				\
+	.reg13			= 0,				\
+	.reg14			= 0,				\
+	.reg15			= 0,				\
+	.reg16			= 0,				\
+	.reg17			= 0,				\
+	.reg18			= 0,				\
+	.reg19			= 0,				\
+	.reg20			= 0,				\
+	.reg21			= 0,				\
+	.cp0_psr		= 0,				\
+	.error_code		= 0,				\
+	.trap_no		= 0,				\
+}
+
+#define kstk_tos(tsk)		\
+	((unsigned long)task_stack_page(tsk) + THREAD_SIZE - 32)
+#define task_pt_regs(tsk)	((struct pt_regs *)kstk_tos(tsk) - 1)
+
+#define KSTK_EIP(tsk)		(task_pt_regs(tsk)->cp0_epc)
+#define KSTK_ESP(tsk)		(task_pt_regs(tsk)->regs[29])
+
+#endif /* _ASM_SCORE_PROCESSOR_H */
diff --git a/arch/score/include/asm/ptrace.h b/arch/score/include/asm/ptrace.h
new file mode 100644
index 0000000..d40e691
--- /dev/null
+++ b/arch/score/include/asm/ptrace.h
@@ -0,0 +1,97 @@
+#ifndef _ASM_SCORE_PTRACE_H
+#define _ASM_SCORE_PTRACE_H
+
+#define PTRACE_GETREGS		12
+#define PTRACE_SETREGS		13
+
+#define PC		32
+#define CONDITION	33
+#define ECR		34
+#define EMA		35
+#define CEH		36
+#define CEL		37
+#define COUNTER		38
+#define LDCR		39
+#define STCR		40
+#define PSR		41
+
+#define SINGLESTEP16_INSN	0x7006
+#define SINGLESTEP32_INSN	0x840C8000
+#define BREAKPOINT16_INSN	0x7002		/* work on SPG300 */
+#define BREAKPOINT32_INSN	0x84048000	/* work on SPG300 */
+
+/* Define instruction mask */
+#define INSN32_MASK	0x80008000
+
+#define J32	0x88008000	/* 1_00010_0000000000_1_000000000000000 */
+#define J32M	0xFC008000	/* 1_11111_0000000000_1_000000000000000 */
+
+#define B32	0x90008000	/* 1_00100_0000000000_1_000000000000000 */
+#define B32M	0xFC008000
+#define BL32	0x90008001	/* 1_00100_0000000000_1_000000000000001 */
+#define BL32M	B32
+#define BR32	0x80008008	/* 1_00000_0000000000_1_00000000_000100_0 */
+#define BR32M	0xFFE0807E
+#define BRL32	0x80008009	/* 1_00000_0000000000_1_00000000_000100_1 */
+#define BRL32M	BR32M
+
+#define B32_SET	(J32 | B32 | BL32 | BR32 | BRL32)
+
+#define J16	0x3000		/* 0_011_....... */
+#define J16M	0xF000
+#define B16	0x4000		/* 0_100_....... */
+#define B16M	0xF000
+#define BR16	0x0004		/* 0_000.......0100 */
+#define BR16M	0xF00F
+#define B16_SET (J16 | B16 | BR16)
+
+
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. As usual the registers k0/k1 aren't being saved.
+ */
+struct pt_regs {
+	unsigned long pad0[6];	/* stack arguments */
+	unsigned long orig_r4;
+	unsigned long orig_r7;
+	long is_syscall;
+
+	unsigned long regs[32];
+
+	unsigned long cel;
+	unsigned long ceh;
+
+	unsigned long sr0;	/* cnt */
+	unsigned long sr1;	/* lcr */
+	unsigned long sr2;	/* scr */
+
+	unsigned long cp0_epc;
+	unsigned long cp0_ema;
+	unsigned long cp0_psr;
+	unsigned long cp0_ecr;
+	unsigned long cp0_condition;
+};
+
+#ifdef __KERNEL__
+
+struct task_struct;
+
+/*
+ * Does the process account for user or for system time?
+ */
+#define user_mode(regs) 	((regs->cp0_psr & 8) == 8)
+
+#define instruction_pointer(regs)	((unsigned long)(regs)->cp0_epc)
+#define profile_pc(regs)		instruction_pointer(regs)
+
+extern void do_syscall_trace(struct pt_regs *regs, int entryexit);
+extern int read_tsk_long(struct task_struct *, unsigned long, unsigned long *);
+extern int read_tsk_short(struct task_struct *, unsigned long,
+			 unsigned short *);
+
+#define arch_has_single_step()	(1)
+extern void user_enable_single_step(struct task_struct *);
+extern void user_disable_single_step(struct task_struct *);
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SCORE_PTRACE_H */
diff --git a/arch/score/include/asm/resource.h b/arch/score/include/asm/resource.h
new file mode 100644
index 0000000..9ce22bc
--- /dev/null
+++ b/arch/score/include/asm/resource.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_RESOURCE_H
+#define _ASM_SCORE_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _ASM_SCORE_RESOURCE_H */
diff --git a/arch/score/include/asm/scatterlist.h b/arch/score/include/asm/scatterlist.h
new file mode 100644
index 0000000..9f533b8
--- /dev/null
+++ b/arch/score/include/asm/scatterlist.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SCATTERLIST_H
+#define _ASM_SCORE_SCATTERLIST_H
+
+#include <asm-generic/scatterlist.h>
+
+#endif /* _ASM_SCORE_SCATTERLIST_H */
diff --git a/arch/score/include/asm/scoreregs.h b/arch/score/include/asm/scoreregs.h
new file mode 100644
index 0000000..d0ad292
--- /dev/null
+++ b/arch/score/include/asm/scoreregs.h
@@ -0,0 +1,51 @@
+#ifndef _ASM_SCORE_SCOREREGS_H
+#define _ASM_SCORE_SCOREREGS_H
+
+#include <linux/linkage.h>
+
+/* TIMER register */
+#define TIME0BASE		0x96080000
+#define P_TIMER0_CTRL		(TIME0BASE + 0x00)
+#define P_TIMER0_CPP_CTRL	(TIME0BASE + 0x04)
+#define P_TIMER0_PRELOAD	(TIME0BASE + 0x08)
+#define P_TIMER0_CPP_REG	(TIME0BASE + 0x0C)
+#define P_TIMER0_UPCNT		(TIME0BASE + 0x10)
+
+/* Timer Controller Register */
+/* bit 0 Timer enable */
+#define TMR_DISABLE	0x0000
+#define TMR_ENABLE	0x0001
+
+/* bit 1 Interrupt enable */
+#define TMR_IE_DISABLE	0x0000
+#define TMR_IE_ENABLE	0x0002
+
+/* bit 2 Output enable */
+#define TMR_OE_DISABLE	0x0004
+#define TMR_OE_ENABLE	0x0000
+
+/* bit4 Up/Down counting selection */
+#define TMR_UD_DOWN	0x0000
+#define TMR_UD_UP	0x0010
+
+/* bit5 Up/Down counting control selection */
+#define TMR_UDS_UD	0x0000
+#define TMR_UDS_EXTUD	0x0020
+
+/* bit6 Time output mode */
+#define TMR_OM_TOGGLE	0x0000
+#define TMR_OM_PILSE	0x0040
+
+/* bit 8..9 External input active edge selection */
+#define TMR_ES_PE	0x0000
+#define TMR_ES_NE	0x0100
+#define TMR_ES_BOTH	0x0200
+
+/* bit 10..11 Operating mode */
+#define TMR_M_FREE	0x0000 /* free running timer mode */
+#define TMR_M_PERIODIC	0x0400 /* periodic timer mode */
+#define TMR_M_FC	0x0800 /* free running counter mode */
+#define TMR_M_PC	0x0c00 /* periodic counter mode */
+
+#define SYSTEM_CLOCK		(27*1000000/4)		/* 27 MHz */
+#endif /* _ASM_SCORE_SCOREREGS_H */
diff --git a/arch/score/include/asm/sections.h b/arch/score/include/asm/sections.h
new file mode 100644
index 0000000..9441d23
--- /dev/null
+++ b/arch/score/include/asm/sections.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SECTIONS_H
+#define _ASM_SCORE_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+#endif /* _ASM_SCORE_SECTIONS_H */
diff --git a/arch/score/include/asm/segment.h b/arch/score/include/asm/segment.h
new file mode 100644
index 0000000..e16cf6a
--- /dev/null
+++ b/arch/score/include/asm/segment.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_SCORE_SEGMENT_H
+#define _ASM_SCORE_SEGMENT_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define KERNEL_DS	((mm_segment_t){0})
+#define USER_DS	KERNEL_DS
+
+# define get_ds()	(KERNEL_DS)
+# define get_fs()	(current_thread_info()->addr_limit)
+# define set_fs(x)	\
+	do { current_thread_info()->addr_limit = (x); } while (0)
+
+# define segment_eq(a, b)	((a).seg == (b).seg)
+
+# endif /* __ASSEMBLY__ */
+#endif /* _ASM_SCORE_SEGMENT_H */
diff --git a/arch/score/include/asm/sembuf.h b/arch/score/include/asm/sembuf.h
new file mode 100644
index 0000000..dae5e83
--- /dev/null
+++ b/arch/score/include/asm/sembuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SEMBUF_H
+#define _ASM_SCORE_SEMBUF_H
+
+#include <asm-generic/sembuf.h>
+
+#endif /* _ASM_SCORE_SEMBUF_H */
diff --git a/arch/score/include/asm/setup.h b/arch/score/include/asm/setup.h
new file mode 100644
index 0000000..3cb944d
--- /dev/null
+++ b/arch/score/include/asm/setup.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_SCORE_SETUP_H
+#define _ASM_SCORE_SETUP_H
+
+#define COMMAND_LINE_SIZE	256
+#define MEMORY_START		0
+#define MEMORY_SIZE		0x2000000
+
+#ifdef __KERNEL__
+
+extern void pagetable_init(void);
+extern void pgd_init(unsigned long page);
+
+extern void setup_early_printk(void);
+extern void cpu_cache_init(void);
+extern void tlb_init(void);
+
+extern void handle_nmi(void);
+extern void handle_adelinsn(void);
+extern void handle_adedata(void);
+extern void handle_ibe(void);
+extern void handle_pel(void);
+extern void handle_sys(void);
+extern void handle_ccu(void);
+extern void handle_ri(void);
+extern void handle_tr(void);
+extern void handle_ades(void);
+extern void handle_cee(void);
+extern void handle_cpe(void);
+extern void handle_dve(void);
+extern void handle_dbe(void);
+extern void handle_reserved(void);
+extern void handle_tlb_refill(void);
+extern void handle_tlb_invaild(void);
+extern void handle_mod(void);
+extern void debug_exception_vector(void);
+extern void general_exception_vector(void);
+extern void interrupt_exception_vector(void);
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SCORE_SETUP_H */
diff --git a/arch/score/include/asm/shmbuf.h b/arch/score/include/asm/shmbuf.h
new file mode 100644
index 0000000..c85b242
--- /dev/null
+++ b/arch/score/include/asm/shmbuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SHMBUF_H
+#define _ASM_SCORE_SHMBUF_H
+
+#include <asm-generic/shmbuf.h>
+
+#endif /* _ASM_SCORE_SHMBUF_H */
diff --git a/arch/score/include/asm/shmparam.h b/arch/score/include/asm/shmparam.h
new file mode 100644
index 0000000..1d60813
--- /dev/null
+++ b/arch/score/include/asm/shmparam.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SHMPARAM_H
+#define _ASM_SCORE_SHMPARAM_H
+
+#include <asm-generic/shmparam.h>
+
+#endif /* _ASM_SCORE_SHMPARAM_H */
diff --git a/arch/score/include/asm/sigcontext.h b/arch/score/include/asm/sigcontext.h
new file mode 100644
index 0000000..5ffda39
--- /dev/null
+++ b/arch/score/include/asm/sigcontext.h
@@ -0,0 +1,22 @@
+#ifndef _ASM_SCORE_SIGCONTEXT_H
+#define _ASM_SCORE_SIGCONTEXT_H
+
+/*
+ * Keep this struct definition in sync with the sigcontext fragment
+ * in arch/score/tools/offset.c
+ */
+struct sigcontext {
+	unsigned int		sc_regmask;
+	unsigned int		sc_psr;
+	unsigned int		sc_condition;
+	unsigned long		sc_pc;
+	unsigned long		sc_regs[32];
+	unsigned int		sc_ssflags;
+	unsigned int		sc_mdceh;
+	unsigned int		sc_mdcel;
+	unsigned int		sc_ecr;
+	unsigned long		sc_ema;
+	unsigned long		sc_sigset[4];
+};
+
+#endif /* _ASM_SCORE_SIGCONTEXT_H */
diff --git a/arch/score/include/asm/siginfo.h b/arch/score/include/asm/siginfo.h
new file mode 100644
index 0000000..87ca356
--- /dev/null
+++ b/arch/score/include/asm/siginfo.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SIGINFO_H
+#define _ASM_SCORE_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_SCORE_SIGINFO_H */
diff --git a/arch/score/include/asm/signal.h b/arch/score/include/asm/signal.h
new file mode 100644
index 0000000..2605bc0
--- /dev/null
+++ b/arch/score/include/asm/signal.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SIGNAL_H
+#define _ASM_SCORE_SIGNAL_H
+
+#include <asm-generic/signal.h>
+
+#endif /* _ASM_SCORE_SIGNAL_H */
diff --git a/arch/score/include/asm/socket.h b/arch/score/include/asm/socket.h
new file mode 100644
index 0000000..612a70e
--- /dev/null
+++ b/arch/score/include/asm/socket.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SOCKET_H
+#define _ASM_SCORE_SOCKET_H
+
+#include <asm-generic/socket.h>
+
+#endif /* _ASM_SCORE_SOCKET_H */
diff --git a/arch/score/include/asm/sockios.h b/arch/score/include/asm/sockios.h
new file mode 100644
index 0000000..ba82564
--- /dev/null
+++ b/arch/score/include/asm/sockios.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SOCKIOS_H
+#define _ASM_SCORE_SOCKIOS_H
+
+#include <asm-generic/sockios.h>
+
+#endif /* _ASM_SCORE_SOCKIOS_H */
diff --git a/arch/score/include/asm/stat.h b/arch/score/include/asm/stat.h
new file mode 100644
index 0000000..5037055
--- /dev/null
+++ b/arch/score/include/asm/stat.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_STAT_H
+#define _ASM_SCORE_STAT_H
+
+#include <asm-generic/stat.h>
+
+#endif /* _ASM_SCORE_STAT_H */
diff --git a/arch/score/include/asm/statfs.h b/arch/score/include/asm/statfs.h
new file mode 100644
index 0000000..36e4100
--- /dev/null
+++ b/arch/score/include/asm/statfs.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_STATFS_H
+#define _ASM_SCORE_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _ASM_SCORE_STATFS_H */
diff --git a/arch/score/include/asm/string.h b/arch/score/include/asm/string.h
new file mode 100644
index 0000000..8a6bf50
--- /dev/null
+++ b/arch/score/include/asm/string.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_SCORE_STRING_H
+#define _ASM_SCORE_STRING_H
+
+extern void *memset(void *__s, int __c, size_t __count);
+extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
+extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
+
+#endif /* _ASM_SCORE_STRING_H */
diff --git a/arch/score/include/asm/swab.h b/arch/score/include/asm/swab.h
new file mode 100644
index 0000000..fadc3cc
--- /dev/null
+++ b/arch/score/include/asm/swab.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_SWAB_H
+#define _ASM_SCORE_SWAB_H
+
+#include <asm-generic/swab.h>
+
+#endif /* _ASM_SCORE_SWAB_H */
diff --git a/arch/score/include/asm/syscalls.h b/arch/score/include/asm/syscalls.h
new file mode 100644
index 0000000..1dd5e0d
--- /dev/null
+++ b/arch/score/include/asm/syscalls.h
@@ -0,0 +1,11 @@
+#ifndef _ASM_SCORE_SYSCALLS_H
+#define _ASM_SCORE_SYSCALLS_H
+
+asmlinkage long score_clone(struct pt_regs *regs);
+asmlinkage long score_execve(struct pt_regs *regs);
+asmlinkage long score_sigaltstack(struct pt_regs *regs);
+asmlinkage long score_rt_sigreturn(struct pt_regs *regs);
+
+#include <asm-generic/syscalls.h>
+
+#endif /* _ASM_SCORE_SYSCALLS_H */
diff --git a/arch/score/include/asm/system.h b/arch/score/include/asm/system.h
new file mode 100644
index 0000000..589d5c7
--- /dev/null
+++ b/arch/score/include/asm/system.h
@@ -0,0 +1,90 @@
+#ifndef _ASM_SCORE_SYSTEM_H
+#define _ASM_SCORE_SYSTEM_H
+
+#include <linux/types.h>
+#include <linux/irqflags.h>
+
+struct pt_regs;
+struct task_struct;
+
+extern void *resume(void *last, void *next, void *next_ti);
+
+#define switch_to(prev, next, last)				\
+do {								\
+	(last) = resume(prev, next, task_thread_info(next));	\
+} while (0)
+
+#define finish_arch_switch(prev)	do {} while (0)
+
+typedef void (*vi_handler_t)(void);
+extern unsigned long arch_align_stack(unsigned long sp);
+
+#define mb()		barrier()
+#define rmb()		barrier()
+#define wmb()		barrier()
+#define smp_mb()	barrier()
+#define smp_rmb()	barrier()
+#define smp_wmb()	barrier()
+
+#define read_barrier_depends()		do {} while (0)
+#define smp_read_barrier_depends()	do {} while (0)
+
+#define set_mb(var, value) 		do {var = value; wmb(); } while (0)
+
+#define __HAVE_ARCH_CMPXCHG	1
+
+#include <asm-generic/cmpxchg-local.h>
+
+#ifndef __ASSEMBLY__
+
+struct __xchg_dummy { unsigned long a[100]; };
+#define __xg(x) ((struct __xchg_dummy *)(x))
+
+static inline
+unsigned long __xchg(volatile unsigned long *m, unsigned long val)
+{
+	unsigned long retval;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	retval = *m;
+	*m = val;
+	local_irq_restore(flags);
+	return retval;
+}
+
+#define xchg(ptr, v)						\
+	((__typeof__(*(ptr))) __xchg((unsigned long *)(ptr),	\
+					(unsigned long)(v)))
+
+static inline unsigned long __cmpxchg(volatile unsigned long *m,
+				unsigned long old, unsigned long new)
+{
+	unsigned long retval;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	retval = *m;
+	if (retval == old)
+		*m = new;
+	local_irq_restore(flags);
+	return retval;
+}
+
+#define cmpxchg(ptr, o, n)					\
+	((__typeof__(*(ptr))) __cmpxchg((unsigned long *)(ptr),	\
+					(unsigned long)(o),	\
+					(unsigned long)(n)))
+
+extern void __die(const char *, struct pt_regs *, const char *,
+	const char *, unsigned long) __attribute__((noreturn));
+extern void __die_if_kernel(const char *, struct pt_regs *, const char *,
+	const char *, unsigned long);
+
+#define die(msg, regs)							\
+	__die(msg, regs, __FILE__ ":", __func__, __LINE__)
+#define die_if_kernel(msg, regs)					\
+	__die_if_kernel(msg, regs, __FILE__ ":", __func__, __LINE__)
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_SCORE_SYSTEM_H */
diff --git a/arch/score/include/asm/termbits.h b/arch/score/include/asm/termbits.h
new file mode 100644
index 0000000..9a95c14
--- /dev/null
+++ b/arch/score/include/asm/termbits.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_TERMBITS_H
+#define _ASM_SCORE_TERMBITS_H
+
+#include <asm-generic/termbits.h>
+
+#endif /* _ASM_SCORE_TERMBITS_H */
diff --git a/arch/score/include/asm/termios.h b/arch/score/include/asm/termios.h
new file mode 100644
index 0000000..40984e8
--- /dev/null
+++ b/arch/score/include/asm/termios.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_TERMIOS_H
+#define _ASM_SCORE_TERMIOS_H
+
+#include <asm-generic/termios.h>
+
+#endif /* _ASM_SCORE_TERMIOS_H */
diff --git a/arch/score/include/asm/thread_info.h b/arch/score/include/asm/thread_info.h
new file mode 100644
index 0000000..3a11228
--- /dev/null
+++ b/arch/score/include/asm/thread_info.h
@@ -0,0 +1,105 @@
+#ifndef _ASM_SCORE_THREAD_INFO_H
+#define _ASM_SCORE_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#define KU_MASK	0x08
+#define KU_USER	0x08
+#define KU_KERN	0x00
+
+#ifndef __ASSEMBLY__
+
+#include <asm/processor.h>
+
+/*
+ * low level task data that entry.S needs immediate access to
+ * - this struct should fit entirely inside of one cache line
+ * - this struct shares the supervisor stack pages
+ * - if the contents of this structure are changed, the assembly constants
+ *   must also be changed
+ */
+struct thread_info {
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+	unsigned long		tp_value;	/* thread pointer */
+	__u32			cpu;		/* current CPU */
+
+	/* 0 => preemptable, < 0 => BUG */
+	int			preempt_count;
+
+	/*
+	 * thread address space:
+	 * 0-0xBFFFFFFF for user-thead
+	 * 0-0xFFFFFFFF for kernel-thread
+	 */
+	mm_segment_t		addr_limit;
+	struct restart_block	restart_block;
+	struct pt_regs		*regs;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.exec_domain	= &default_exec_domain,	\
+	.cpu		= 0,			\
+	.preempt_count	= 1,			\
+	.addr_limit	= KERNEL_DS,		\
+	.restart_block	= {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/* How to get the thread information struct from C. */
+register struct thread_info *__current_thread_info __asm__("r28");
+#define current_thread_info()	__current_thread_info
+
+/* thread information allocation */
+#define THREAD_SIZE_ORDER 	(1)
+#define THREAD_SIZE 		(PAGE_SIZE << THREAD_SIZE_ORDER)
+#define THREAD_MASK 		(THREAD_SIZE - 1UL)
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+
+#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#define free_thread_info(info) kfree(info)
+
+#endif /* !__ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE		0x10000000
+
+/*
+ * thread information flags
+ * - these are process state flags that various assembly files may need to
+ *   access
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_SIGPENDING		1	/* signal pending */
+#define TIF_NEED_RESCHED	2	/* rescheduling necessary */
+#define TIF_NOTIFY_RESUME	5	/* callback before returning to user */
+#define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
+#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling
+						 TIF_NEED_RESCHED */
+#define TIF_MEMDIE		18
+
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+
+#define _TIF_WORK_MASK		(0x0000ffff)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_SCORE_THREAD_INFO_H */
diff --git a/arch/score/include/asm/timex.h b/arch/score/include/asm/timex.h
new file mode 100644
index 0000000..a524ae0
--- /dev/null
+++ b/arch/score/include/asm/timex.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_SCORE_TIMEX_H
+#define _ASM_SCORE_TIMEX_H
+
+#define CLOCK_TICK_RATE 27000000 /* Timer input freq. */
+
+#include <asm-generic/timex.h>
+
+#endif /* _ASM_SCORE_TIMEX_H */
diff --git a/arch/score/include/asm/tlb.h b/arch/score/include/asm/tlb.h
new file mode 100644
index 0000000..46882ed
--- /dev/null
+++ b/arch/score/include/asm/tlb.h
@@ -0,0 +1,17 @@
+#ifndef _ASM_SCORE_TLB_H
+#define _ASM_SCORE_TLB_H
+
+/*
+ * SCORE doesn't need any special per-pte or per-vma handling, except
+ * we need to flush cache for area to be unmapped.
+ */
+#define tlb_start_vma(tlb, vma)		do {} while (0)
+#define tlb_end_vma(tlb, vma)		do {} while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do {} while (0)
+#define tlb_flush(tlb)			flush_tlb_mm((tlb)->mm)
+
+extern void score7_FTLB_refill_Handler(void);
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_SCORE_TLB_H */
diff --git a/arch/score/include/asm/tlbflush.h b/arch/score/include/asm/tlbflush.h
new file mode 100644
index 0000000..9cce978
--- /dev/null
+++ b/arch/score/include/asm/tlbflush.h
@@ -0,0 +1,142 @@
+#ifndef _ASM_SCORE_TLBFLUSH_H
+#define _ASM_SCORE_TLBFLUSH_H
+
+#include <linux/mm.h>
+
+/*
+ * TLB flushing:
+ *
+ * - flush_tlb_all() flushes all processes TLB entries
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ * - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_range(vma, start, end) flushes a range of pages
+ * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ */
+extern void local_flush_tlb_all(void);
+extern void local_flush_tlb_mm(struct mm_struct *mm);
+extern void local_flush_tlb_range(struct vm_area_struct *vma,
+	unsigned long start, unsigned long end);
+extern void local_flush_tlb_kernel_range(unsigned long start,
+	unsigned long end);
+extern void local_flush_tlb_page(struct vm_area_struct *vma,
+	unsigned long page);
+extern void local_flush_tlb_one(unsigned long vaddr);
+
+#define flush_tlb_all()			local_flush_tlb_all()
+#define flush_tlb_mm(mm)		local_flush_tlb_mm(mm)
+#define flush_tlb_range(vma, vmaddr, end) \
+	local_flush_tlb_range(vma, vmaddr, end)
+#define flush_tlb_kernel_range(vmaddr, end) \
+	local_flush_tlb_kernel_range(vmaddr, end)
+#define flush_tlb_page(vma, page)	local_flush_tlb_page(vma, page)
+#define flush_tlb_one(vaddr)		local_flush_tlb_one(vaddr)
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned long pevn_get(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		"mfcr %0, cr11\n"
+		"nop\nnop\n"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void pevn_set(unsigned long val)
+{
+	__asm__ __volatile__(
+		"mtcr %0, cr11\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+	: : "r" (val));
+}
+
+static inline void pectx_set(unsigned long val)
+{
+	__asm__ __volatile__(
+		"mtcr %0, cr12\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+	: : "r" (val));
+}
+
+static inline unsigned long pectx_get(void)
+{
+	unsigned long val;
+	__asm__ __volatile__(
+		"mfcr %0, cr12\n"
+		"nop\nnop\n"
+	: "=r" (val));
+	return val;
+}
+static inline unsigned long tlblock_get(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__(
+		"mfcr %0, cr7\n"
+		"nop\nnop\n"
+	: "=r" (val));
+	return val;
+}
+static inline void tlblock_set(unsigned long val)
+{
+	__asm__ __volatile__(
+		"mtcr %0, cr7\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+	: : "r" (val));
+}
+
+static inline void tlbpt_set(unsigned long val)
+{
+	__asm__ __volatile__(
+		"mtcr %0, cr8\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+		: : "r" (val));
+}
+
+static inline long tlbpt_get(void)
+{
+	long val;
+
+	__asm__ __volatile__(
+		"mfcr %0, cr8\n"
+		"nop\nnop\n"
+		: "=r" (val));
+
+	return val;
+}
+
+static inline void peaddr_set(unsigned long val)
+{
+	__asm__ __volatile__(
+		"mtcr %0, cr9\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+		: : "r" (val));
+}
+
+/* TLB operations. */
+static inline void tlb_probe(void)
+{
+	__asm__ __volatile__("stlb;nop;nop;nop;nop;nop");
+}
+
+static inline void tlb_read(void)
+{
+	__asm__ __volatile__("mftlb;nop;nop;nop;nop;nop");
+}
+
+static inline void tlb_write_indexed(void)
+{
+	__asm__ __volatile__("mtptlb;nop;nop;nop;nop;nop");
+}
+
+static inline void tlb_write_random(void)
+{
+	__asm__ __volatile__("mtrtlb;nop;nop;nop;nop;nop");
+}
+
+#endif /* Not __ASSEMBLY__ */
+
+#endif /* _ASM_SCORE_TLBFLUSH_H */
diff --git a/arch/score/include/asm/topology.h b/arch/score/include/asm/topology.h
new file mode 100644
index 0000000..425fba3
--- /dev/null
+++ b/arch/score/include/asm/topology.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_TOPOLOGY_H
+#define _ASM_SCORE_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_SCORE_TOPOLOGY_H */
diff --git a/arch/score/include/asm/types.h b/arch/score/include/asm/types.h
new file mode 100644
index 0000000..2140032
--- /dev/null
+++ b/arch/score/include/asm/types.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_TYPES_H
+#define _ASM_SCORE_TYPES_H
+
+#include <asm-generic/types.h>
+
+#endif /* _ASM_SCORE_TYPES_H */
diff --git a/arch/score/include/asm/uaccess.h b/arch/score/include/asm/uaccess.h
new file mode 100644
index 0000000..ab66ddd
--- /dev/null
+++ b/arch/score/include/asm/uaccess.h
@@ -0,0 +1,424 @@
+#ifndef __SCORE_UACCESS_H
+#define __SCORE_UACCESS_H
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/thread_info.h>
+
+#define VERIFY_READ		0
+#define VERIFY_WRITE		1
+
+#define get_ds()		(KERNEL_DS)
+#define get_fs()		(current_thread_info()->addr_limit)
+#define segment_eq(a, b)	((a).seg == (b).seg)
+
+/*
+ * Is a address valid? This does a straighforward calculation rather
+ * than tests.
+ *
+ * Address valid if:
+ *  - "addr" doesn't have any high-bits set
+ *  - AND "size" doesn't have any high-bits set
+ *  - AND "addr+size" doesn't have any high-bits set
+ *  - OR we are in kernel mode.
+ *
+ * __ua_size() is a trick to avoid runtime checking of positive constant
+ * sizes; for those we already know at compile time that the size is ok.
+ */
+#define __ua_size(size)							\
+	((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
+
+/*
+ * access_ok: - Checks if a user space pointer is valid
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
+ *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
+ *        to write to a block, it is always safe to read from it.
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns true (nonzero) if the memory block may be valid, false (zero)
+ * if it is definitely invalid.
+ *
+ * Note that, depending on architecture, this function probably just
+ * checks that the pointer is in the user space range - after calling
+ * this function, memory access functions may still return -EFAULT.
+ */
+
+#define __access_ok(addr, size)					\
+	(((long)((get_fs().seg) &				\
+		 ((addr) | ((addr) + (size)) |			\
+		  __ua_size(size)))) == 0)
+
+#define access_ok(type, addr, size)				\
+	likely(__access_ok((unsigned long)(addr), (size)))
+
+/*
+ * put_user: - Write a simple value into user space.
+ * @x:   Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * get_user: - Get a simple variable from user space.
+ * @x:   Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * __put_user: - Write a simple value into user space, with less checking.
+ * @x:   Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ */
+#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+/*
+ * __get_user: - Get a simple variable from user space, with less checking.
+ * @x:   Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only.  This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space.  It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ */
+#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+struct __large_struct { unsigned long buf[100]; };
+#define __m(x) (*(struct __large_struct __user *)(x))
+
+/*
+ * Yuck.  We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+extern void __get_user_unknown(void);
+
+#define __get_user_common(val, size, ptr)				\
+do {									\
+	switch (size) {							\
+	case 1:								\
+		__get_user_asm(val, "lb", ptr);				\
+		break;							\
+	case 2:								\
+		__get_user_asm(val, "lh", ptr);				\
+		 break;							\
+	case 4:								\
+		__get_user_asm(val, "lw", ptr);				\
+		 break;							\
+	case 8: 							\
+		if ((copy_from_user((void *)&val, ptr, 8)) == 0)	\
+			__gu_err = 0;					\
+		else							\
+			__gu_err = -EFAULT;				\
+		break;							\
+	default:							\
+		__get_user_unknown();					\
+		break;							\
+	}								\
+} while (0)
+
+#define __get_user_nocheck(x, ptr, size)				\
+({									\
+	long __gu_err = 0;						\
+	__get_user_common((x), size, ptr);				\
+	__gu_err;							\
+})
+
+#define __get_user_check(x, ptr, size)					\
+({									\
+	long __gu_err = -EFAULT;					\
+	const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);		\
+									\
+	if (likely(access_ok(VERIFY_READ, __gu_ptr, size)))		\
+		__get_user_common((x), size, __gu_ptr);			\
+									\
+	__gu_err;							\
+})
+
+#define __get_user_asm(val, insn, addr)					\
+{									\
+	long __gu_tmp;							\
+									\
+	__asm__ __volatile__(						\
+		"1:" insn " %1, %3\n"					\
+		"2:\n"							\
+		".section .fixup,\"ax\"\n"				\
+		"3:li	%0, %4\n"					\
+		"j	2b\n"						\
+		".previous\n"						\
+		".section __ex_table,\"a\"\n"				\
+		".word	1b, 3b\n"					\
+		".previous\n"						\
+		: "=r" (__gu_err), "=r" (__gu_tmp)			\
+		: "0" (0), "o" (__m(addr)), "i" (-EFAULT));		\
+									\
+		(val) = (__typeof__(*(addr))) __gu_tmp;			\
+}
+
+/*
+ * Yuck.  We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#define __put_user_nocheck(val, ptr, size)				\
+({									\
+	__typeof__(*(ptr)) __pu_val;					\
+	long __pu_err = 0;						\
+									\
+	__pu_val = (val);						\
+	switch (size) {							\
+	case 1:								\
+		__put_user_asm("sb", ptr);				\
+		break;							\
+	case 2:								\
+		__put_user_asm("sh", ptr);				\
+		break;							\
+	case 4:								\
+		__put_user_asm("sw", ptr);				\
+		break;							\
+	case 8: 							\
+		if ((__copy_to_user((void *)ptr, &__pu_val, 8)) == 0)	\
+			__pu_err = 0;					\
+		else							\
+			__pu_err = -EFAULT;				\
+		break;							\
+	default:							\
+		 __put_user_unknown();					\
+		 break;							\
+	}								\
+	__pu_err;							\
+})
+
+
+#define __put_user_check(val, ptr, size)				\
+({									\
+	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
+	__typeof__(*(ptr)) __pu_val = (val);				\
+	long __pu_err = -EFAULT;					\
+									\
+	if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) {		\
+		switch (size) {						\
+		case 1:							\
+			__put_user_asm("sb", __pu_addr);		\
+			break;						\
+		case 2:							\
+			__put_user_asm("sh", __pu_addr);		\
+			break;						\
+		case 4:							\
+			__put_user_asm("sw", __pu_addr);		\
+			break;						\
+		case 8: 						\
+			if ((__copy_to_user((void *)__pu_addr, &__pu_val, 8)) == 0)\
+				__pu_err = 0;				\
+			else						\
+				__pu_err = -EFAULT;			\
+			break;						\
+		default:						\
+			__put_user_unknown();				\
+			break;						\
+		}							\
+	}								\
+	__pu_err;							\
+})
+
+#define __put_user_asm(insn, ptr)					\
+	__asm__ __volatile__(						\
+		"1:" insn " %2, %3\n"					\
+		"2:\n"							\
+		".section .fixup,\"ax\"\n"				\
+		"3:li %0, %4\n"						\
+		"j 2b\n"						\
+		".previous\n"						\
+		".section __ex_table,\"a\"\n"				\
+		".word 1b, 3b\n"					\
+		".previous\n"						\
+		: "=r" (__pu_err)					\
+		: "0" (0), "r" (__pu_val), "o" (__m(ptr)),		\
+		  "i" (-EFAULT));
+
+extern void __put_user_unknown(void);
+extern int __copy_tofrom_user(void *to, const void *from, unsigned long len);
+
+static inline unsigned long
+copy_from_user(void *to, const void *from, unsigned long len)
+{
+	unsigned long over;
+
+	if (access_ok(VERIFY_READ, from, len))
+		return __copy_tofrom_user(to, from, len);
+
+	if ((unsigned long)from < TASK_SIZE) {
+		over = (unsigned long)from + len - TASK_SIZE;
+		return __copy_tofrom_user(to, from, len - over) + over;
+	}
+	return len;
+}
+
+static inline unsigned long
+copy_to_user(void *to, const void *from, unsigned long len)
+{
+	unsigned long over;
+
+	if (access_ok(VERIFY_WRITE, to, len))
+		return __copy_tofrom_user(to, from, len);
+
+	if ((unsigned long)to < TASK_SIZE) {
+		over = (unsigned long)to + len - TASK_SIZE;
+		return __copy_tofrom_user(to, from, len - over) + over;
+	}
+	return len;
+}
+
+#define __copy_from_user(to, from, len)	\
+		__copy_tofrom_user((to), (from), (len))
+
+#define __copy_to_user(to, from, len)		\
+		__copy_tofrom_user((to), (from), (len))
+
+static inline unsigned long
+__copy_to_user_inatomic(void *to, const void *from, unsigned long len)
+{
+	return __copy_to_user(to, from, len);
+}
+
+static inline unsigned long
+__copy_from_user_inatomic(void *to, const void *from, unsigned long len)
+{
+	return __copy_from_user(to, from, len);
+}
+
+#define __copy_in_user(to, from, len)	__copy_from_user(to, from, len)
+
+static inline unsigned long
+copy_in_user(void *to, const void *from, unsigned long len)
+{
+	if (access_ok(VERIFY_READ, from, len) &&
+		      access_ok(VERFITY_WRITE, to, len))
+		return copy_from_user(to, from, len);
+}
+
+/*
+ * __clear_user: - Zero a block of memory in user space, with less checking.
+ * @to:   Destination address, in user space.
+ * @n:    Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
+extern unsigned long __clear_user(void __user *src, unsigned long size);
+
+static inline unsigned long clear_user(char *src, unsigned long size)
+{
+	if (access_ok(VERIFY_WRITE, src, size))
+		return __clear_user(src, size);
+
+	return -EFAULT;
+}
+/*
+ * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @src:   Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from userspace to kernel space.
+ * Caller must check the specified block with access_ok() before calling
+ * this function.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+extern int __strncpy_from_user(char *dst, const char *src, long len);
+
+static inline int strncpy_from_user(char *dst, const char *src, long len)
+{
+	if (access_ok(VERIFY_READ, src, 1))
+		return __strncpy_from_user(dst, src, len);
+
+	return -EFAULT;
+}
+
+extern int __strlen_user(const char *src);
+static inline long strlen_user(const char __user *src)
+{
+	return __strlen_user(src);
+}
+
+extern int __strnlen_user(const char *str, long len);
+static inline long strnlen_user(const char __user *str, long len)
+{
+	if (!access_ok(VERIFY_READ, str, 0))
+		return 0;
+	else		
+		return __strnlen_user(str, len);
+}
+
+struct exception_table_entry {
+	unsigned long insn;
+	unsigned long fixup;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#endif /* __SCORE_UACCESS_H */
+
diff --git a/arch/score/include/asm/ucontext.h b/arch/score/include/asm/ucontext.h
new file mode 100644
index 0000000..9bc07b9
--- /dev/null
+++ b/arch/score/include/asm/ucontext.h
@@ -0,0 +1 @@
+#include <asm-generic/ucontext.h>
diff --git a/arch/score/include/asm/unaligned.h b/arch/score/include/asm/unaligned.h
new file mode 100644
index 0000000..2fc06de
--- /dev/null
+++ b/arch/score/include/asm/unaligned.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SCORE_UNALIGNED_H
+#define _ASM_SCORE_UNALIGNED_H
+
+#include <asm-generic/unaligned.h>
+
+#endif /* _ASM_SCORE_UNALIGNED_H */
diff --git a/arch/score/include/asm/unistd.h b/arch/score/include/asm/unistd.h
new file mode 100644
index 0000000..4aa9573
--- /dev/null
+++ b/arch/score/include/asm/unistd.h
@@ -0,0 +1,13 @@
+#if !defined(_ASM_SCORE_UNISTD_H) || defined(__SYSCALL)
+#define _ASM_SCORE_UNISTD_H
+
+#define __ARCH_HAVE_MMU
+
+#define __ARCH_WANT_SYSCALL_NO_AT
+#define __ARCH_WANT_SYSCALL_NO_FLAGS
+#define __ARCH_WANT_SYSCALL_OFF_T
+#define __ARCH_WANT_SYSCALL_DEPRECATED
+
+#include <asm-generic/unistd.h>
+
+#endif /* _ASM_SCORE_UNISTD_H */
diff --git a/arch/score/include/asm/user.h b/arch/score/include/asm/user.h
new file mode 100644
index 0000000..7bfb8e2
--- /dev/null
+++ b/arch/score/include/asm/user.h
@@ -0,0 +1,21 @@
+#ifndef _ASM_SCORE_USER_H
+#define _ASM_SCORE_USER_H
+
+struct user_regs_struct {
+	unsigned long regs[32];
+
+	unsigned long cel;
+	unsigned long ceh;
+
+	unsigned long sr0;	/* cnt */
+	unsigned long sr1;	/* lcr */
+	unsigned long sr2;	/* scr */
+
+	unsigned long cp0_epc;
+	unsigned long cp0_ema;
+	unsigned long cp0_psr;
+	unsigned long cp0_ecr;
+	unsigned long cp0_condition;
+};
+
+#endif /* _ASM_SCORE_USER_H */
diff --git a/arch/score/kernel/Makefile b/arch/score/kernel/Makefile
new file mode 100644
index 0000000..f218673
--- /dev/null
+++ b/arch/score/kernel/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the Linux/SCORE kernel.
+#
+
+extra-y	:= head.o vmlinux.lds
+
+obj-y += entry.o init_task.o irq.o process.o ptrace.o \
+	setup.o signal.o sys_score.o time.o traps.o \
+	sys_call_table.o
+
+obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/score/kernel/asm-offsets.c b/arch/score/kernel/asm-offsets.c
new file mode 100644
index 0000000..57788f4
--- /dev/null
+++ b/arch/score/kernel/asm-offsets.c
@@ -0,0 +1,216 @@
+/*
+ * arch/score/kernel/asm-offsets.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kbuild.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+
+#include <asm-generic/cmpxchg-local.h>
+
+void output_ptreg_defines(void)
+{
+	COMMENT("SCORE pt_regs offsets.");
+	OFFSET(PT_R0, pt_regs, regs[0]);
+	OFFSET(PT_R1, pt_regs, regs[1]);
+	OFFSET(PT_R2, pt_regs, regs[2]);
+	OFFSET(PT_R3, pt_regs, regs[3]);
+	OFFSET(PT_R4, pt_regs, regs[4]);
+	OFFSET(PT_R5, pt_regs, regs[5]);
+	OFFSET(PT_R6, pt_regs, regs[6]);
+	OFFSET(PT_R7, pt_regs, regs[7]);
+	OFFSET(PT_R8, pt_regs, regs[8]);
+	OFFSET(PT_R9, pt_regs, regs[9]);
+	OFFSET(PT_R10, pt_regs, regs[10]);
+	OFFSET(PT_R11, pt_regs, regs[11]);
+	OFFSET(PT_R12, pt_regs, regs[12]);
+	OFFSET(PT_R13, pt_regs, regs[13]);
+	OFFSET(PT_R14, pt_regs, regs[14]);
+	OFFSET(PT_R15, pt_regs, regs[15]);
+	OFFSET(PT_R16, pt_regs, regs[16]);
+	OFFSET(PT_R17, pt_regs, regs[17]);
+	OFFSET(PT_R18, pt_regs, regs[18]);
+	OFFSET(PT_R19, pt_regs, regs[19]);
+	OFFSET(PT_R20, pt_regs, regs[20]);
+	OFFSET(PT_R21, pt_regs, regs[21]);
+	OFFSET(PT_R22, pt_regs, regs[22]);
+	OFFSET(PT_R23, pt_regs, regs[23]);
+	OFFSET(PT_R24, pt_regs, regs[24]);
+	OFFSET(PT_R25, pt_regs, regs[25]);
+	OFFSET(PT_R26, pt_regs, regs[26]);
+	OFFSET(PT_R27, pt_regs, regs[27]);
+	OFFSET(PT_R28, pt_regs, regs[28]);
+	OFFSET(PT_R29, pt_regs, regs[29]);
+	OFFSET(PT_R30, pt_regs, regs[30]);
+	OFFSET(PT_R31, pt_regs, regs[31]);
+
+	OFFSET(PT_ORIG_R4, pt_regs, orig_r4);
+	OFFSET(PT_ORIG_R7, pt_regs, orig_r7);
+	OFFSET(PT_CEL, pt_regs, cel);
+	OFFSET(PT_CEH, pt_regs, ceh);
+	OFFSET(PT_SR0, pt_regs, sr0);
+	OFFSET(PT_SR1, pt_regs, sr1);
+	OFFSET(PT_SR2, pt_regs, sr2);
+	OFFSET(PT_EPC, pt_regs, cp0_epc);
+	OFFSET(PT_EMA, pt_regs, cp0_ema);
+	OFFSET(PT_PSR, pt_regs, cp0_psr);
+	OFFSET(PT_ECR, pt_regs, cp0_ecr);
+	OFFSET(PT_CONDITION, pt_regs, cp0_condition);
+	OFFSET(PT_IS_SYSCALL, pt_regs, is_syscall);
+
+	DEFINE(PT_SIZE, sizeof(struct pt_regs));
+	BLANK();
+}
+
+void output_task_defines(void)
+{
+	COMMENT("SCORE task_struct offsets.");
+	OFFSET(TASK_STATE, task_struct, state);
+	OFFSET(TASK_THREAD_INFO, task_struct, stack);
+	OFFSET(TASK_FLAGS, task_struct, flags);
+	OFFSET(TASK_MM, task_struct, mm);
+	OFFSET(TASK_PID, task_struct, pid);
+	DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
+	BLANK();
+}
+
+void output_thread_info_defines(void)
+{
+	COMMENT("SCORE thread_info offsets.");
+	OFFSET(TI_TASK, thread_info, task);
+	OFFSET(TI_EXEC_DOMAIN, thread_info, exec_domain);
+	OFFSET(TI_FLAGS, thread_info, flags);
+	OFFSET(TI_TP_VALUE, thread_info, tp_value);
+	OFFSET(TI_CPU, thread_info, cpu);
+	OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
+	OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit);
+	OFFSET(TI_RESTART_BLOCK, thread_info, restart_block);
+	OFFSET(TI_REGS, thread_info, regs);
+	DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE);
+	DEFINE(KERNEL_STACK_MASK, THREAD_MASK);
+	BLANK();
+}
+
+void output_thread_defines(void)
+{
+	COMMENT("SCORE specific thread_struct offsets.");
+	OFFSET(THREAD_REG0, task_struct, thread.reg0);
+	OFFSET(THREAD_REG2, task_struct, thread.reg2);
+	OFFSET(THREAD_REG3, task_struct, thread.reg3);
+	OFFSET(THREAD_REG12, task_struct, thread.reg12);
+	OFFSET(THREAD_REG13, task_struct, thread.reg13);
+	OFFSET(THREAD_REG14, task_struct, thread.reg14);
+	OFFSET(THREAD_REG15, task_struct, thread.reg15);
+	OFFSET(THREAD_REG16, task_struct, thread.reg16);
+	OFFSET(THREAD_REG17, task_struct, thread.reg17);
+	OFFSET(THREAD_REG18, task_struct, thread.reg18);
+	OFFSET(THREAD_REG19, task_struct, thread.reg19);
+	OFFSET(THREAD_REG20, task_struct, thread.reg20);
+	OFFSET(THREAD_REG21, task_struct, thread.reg21);
+	OFFSET(THREAD_REG29, task_struct, thread.reg29);
+
+	OFFSET(THREAD_PSR, task_struct, thread.cp0_psr);
+	OFFSET(THREAD_EMA, task_struct, thread.cp0_ema);
+	OFFSET(THREAD_BADUADDR, task_struct, thread.cp0_baduaddr);
+	OFFSET(THREAD_ECODE, task_struct, thread.error_code);
+	OFFSET(THREAD_TRAPNO, task_struct, thread.trap_no);
+	BLANK();
+}
+
+void output_mm_defines(void)
+{
+	COMMENT("Size of struct page");
+	DEFINE(STRUCT_PAGE_SIZE, sizeof(struct page));
+	BLANK();
+	COMMENT("Linux mm_struct offsets.");
+	OFFSET(MM_USERS, mm_struct, mm_users);
+	OFFSET(MM_PGD, mm_struct, pgd);
+	OFFSET(MM_CONTEXT, mm_struct, context);
+	BLANK();
+	DEFINE(_PAGE_SIZE, PAGE_SIZE);
+	DEFINE(_PAGE_SHIFT, PAGE_SHIFT);
+	BLANK();
+	DEFINE(_PGD_T_SIZE, sizeof(pgd_t));
+	DEFINE(_PTE_T_SIZE, sizeof(pte_t));
+	BLANK();
+	DEFINE(_PGD_ORDER, PGD_ORDER);
+	DEFINE(_PTE_ORDER, PTE_ORDER);
+	BLANK();
+	DEFINE(_PGDIR_SHIFT, PGDIR_SHIFT);
+	BLANK();
+	DEFINE(_PTRS_PER_PGD, PTRS_PER_PGD);
+	DEFINE(_PTRS_PER_PTE, PTRS_PER_PTE);
+	BLANK();
+}
+
+void output_sc_defines(void)
+{
+	COMMENT("Linux sigcontext offsets.");
+	OFFSET(SC_REGS, sigcontext, sc_regs);
+	OFFSET(SC_MDCEH, sigcontext, sc_mdceh);
+	OFFSET(SC_MDCEL, sigcontext, sc_mdcel);
+	OFFSET(SC_PC, sigcontext, sc_pc);
+	OFFSET(SC_PSR, sigcontext, sc_psr);
+	OFFSET(SC_ECR, sigcontext, sc_ecr);
+	OFFSET(SC_EMA, sigcontext, sc_ema);
+	BLANK();
+}
+
+void output_signal_defined(void)
+{
+	COMMENT("Linux signal numbers.");
+	DEFINE(_SIGHUP, SIGHUP);
+	DEFINE(_SIGINT, SIGINT);
+	DEFINE(_SIGQUIT, SIGQUIT);
+	DEFINE(_SIGILL, SIGILL);
+	DEFINE(_SIGTRAP, SIGTRAP);
+	DEFINE(_SIGIOT, SIGIOT);
+	DEFINE(_SIGABRT, SIGABRT);
+	DEFINE(_SIGFPE, SIGFPE);
+	DEFINE(_SIGKILL, SIGKILL);
+	DEFINE(_SIGBUS, SIGBUS);
+	DEFINE(_SIGSEGV, SIGSEGV);
+	DEFINE(_SIGSYS, SIGSYS);
+	DEFINE(_SIGPIPE, SIGPIPE);
+	DEFINE(_SIGALRM, SIGALRM);
+	DEFINE(_SIGTERM, SIGTERM);
+	DEFINE(_SIGUSR1, SIGUSR1);
+	DEFINE(_SIGUSR2, SIGUSR2);
+	DEFINE(_SIGCHLD, SIGCHLD);
+	DEFINE(_SIGPWR, SIGPWR);
+	DEFINE(_SIGWINCH, SIGWINCH);
+	DEFINE(_SIGURG, SIGURG);
+	DEFINE(_SIGIO, SIGIO);
+	DEFINE(_SIGSTOP, SIGSTOP);
+	DEFINE(_SIGTSTP, SIGTSTP);
+	DEFINE(_SIGCONT, SIGCONT);
+	DEFINE(_SIGTTIN, SIGTTIN);
+	DEFINE(_SIGTTOU, SIGTTOU);
+	DEFINE(_SIGVTALRM, SIGVTALRM);
+	DEFINE(_SIGPROF, SIGPROF);
+	DEFINE(_SIGXCPU, SIGXCPU);
+	DEFINE(_SIGXFSZ, SIGXFSZ);
+	BLANK();
+}
diff --git a/arch/score/kernel/entry.S b/arch/score/kernel/entry.S
new file mode 100644
index 0000000..577abba
--- /dev/null
+++ b/arch/score/kernel/entry.S
@@ -0,0 +1,514 @@
+/*
+ * arch/score/kernel/entry.S
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+
+#include <asm/asmmacro.h>
+#include <asm/thread_info.h>
+#include <asm/unistd.h>
+
+/*
+ * disable interrupts.
+ */
+.macro	disable_irq
+	mfcr	r8, cr0
+	srli	r8, r8, 1
+	slli	r8, r8, 1
+	mtcr	r8, cr0
+	nop
+	nop
+	nop
+	nop
+	nop
+.endm
+
+/*
+ * enable interrupts.
+ */
+.macro	enable_irq
+	mfcr	r8, cr0
+	ori	r8, 1
+	mtcr	r8, cr0
+	nop
+	nop
+	nop
+	nop
+	nop
+.endm
+
+__INIT
+ENTRY(debug_exception_vector)
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+
+ENTRY(general_exception_vector)			# should move to addr 0x200
+	j	general_exception
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+
+ENTRY(interrupt_exception_vector)		# should move to addr 0x210
+	j	interrupt_exception
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+	nop!
+
+	.section ".text", "ax"
+	.align	2;
+general_exception:
+	mfcr	r31, cr2
+	nop
+	la	r30, exception_handlers
+	andi	r31, 0x1f			# get ecr.exc_code
+	slli	r31, r31, 2
+	add	r30, r30, r31
+	lw	r30, [r30]
+	br	r30
+
+interrupt_exception:
+	SAVE_ALL
+	mfcr	r4, cr2
+	nop
+	lw	r16, [r28, TI_REGS]
+	sw	r0, [r28, TI_REGS]
+	la	r3, ret_from_irq
+	srli	r4, r4, 18			# get ecr.ip[7:2], interrupt No.
+	mv	r5, r0
+	j	do_IRQ
+
+ENTRY(handle_nmi)				# NMI #1
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, nmi_exception_handler
+	brl	r8
+	j	restore_all
+
+ENTRY(handle_adelinsn)				# AdEL-instruction #2
+	SAVE_ALL
+	mfcr	r8, cr6
+	nop
+	nop
+	sw	r8, [r0, PT_EMA]
+	mv	r4, r0
+	la	r8, do_adelinsn
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_ibe)				# BusEL-instruction #5
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_be
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_pel)				# P-EL #6
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_pel
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_ccu)				# CCU #8
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_ccu
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_ri)				# RI #9
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_ri
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_tr)				# Trap #10
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_tr
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_adedata)				# AdES-instruction #12
+	SAVE_ALL
+	mfcr	r8, cr6
+	nop
+	nop
+	sw	r8, [r0, PT_EMA]
+	mv	r4, r0
+	la	r8, do_adedata
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_cee)				# CeE #16
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_cee
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_cpe)				# CpE #17
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_cpe
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_dbe)				# BusEL-data #18
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_be
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+ENTRY(handle_reserved)				# others
+	SAVE_ALL
+	mv	r4, r0
+	la	r8, do_reserved
+	brl	r8
+	mv	r4, r0
+	j	ret_from_exception
+	nop
+
+#ifndef CONFIG_PREEMPT
+#define resume_kernel	restore_all
+#else
+#define __ret_from_irq	ret_from_exception
+#endif
+
+	.align	2
+#ifndef CONFIG_PREEMPT
+ENTRY(ret_from_exception)
+	disable_irq			# preempt stop
+	nop
+	j	__ret_from_irq
+	nop
+#endif
+
+ENTRY(ret_from_irq)
+	sw	r16, [r28, TI_REGS]
+
+ENTRY(__ret_from_irq)
+	lw	r8, [r0, PT_PSR]	# returning to kernel mode?
+	andri.c	r8, r8, KU_USER
+	beq	resume_kernel
+
+resume_userspace:
+	disable_irq
+	lw	r6, [r28, TI_FLAGS]	# current->work
+	li	r8, _TIF_WORK_MASK
+	and.c	r8, r8, r6		# ignoring syscall_trace
+	bne	work_pending
+	nop
+	j	restore_all
+	nop
+
+#ifdef CONFIG_PREEMPT
+resume_kernel:
+	disable_irq
+	lw	r8, [r28, TI_PRE_COUNT]
+	cmpz.c	r8
+	bne	r8, restore_all
+need_resched:
+	lw	r8, [r28, TI_FLAGS]
+	andri.c	r9, r8, _TIF_NEED_RESCHED
+	beq	restore_all
+	lw	r8, [r28, PT_PSR]		# Interrupts off?
+	andri.c	r8, r8, 1
+	beq	restore_all
+	bl	preempt_schedule_irq
+	nop
+	j	need_resched
+	nop
+#endif
+
+ENTRY(ret_from_fork)
+	bl	schedule_tail			# r4=struct task_struct *prev
+
+ENTRY(syscall_exit)
+	nop
+	disable_irq
+	lw	r6, [r28, TI_FLAGS]		# current->work
+	li	r8, _TIF_WORK_MASK
+	and.c	r8, r6, r8
+	bne	syscall_exit_work
+
+ENTRY(restore_all)					# restore full frame
+	RESTORE_ALL_AND_RET
+
+work_pending:
+	andri.c	r8, r6, _TIF_NEED_RESCHED # r6 is preloaded with TI_FLAGS
+	beq	work_notifysig
+work_resched:
+	bl	schedule
+	nop
+	disable_irq
+	lw	r6, [r28, TI_FLAGS]
+	li	r8, _TIF_WORK_MASK
+	and.c	r8, r6, r8	# is there any work to be done
+				# other than syscall tracing?
+	beq	restore_all
+	andri.c	r8, r6, _TIF_NEED_RESCHED
+	bne	work_resched
+
+work_notifysig:
+	mv	r4, r0
+	li	r5, 0
+	bl	do_notify_resume	# r6 already loaded
+	nop
+	j	resume_userspace
+	nop
+
+ENTRY(syscall_exit_work)
+	li	r8, _TIF_SYSCALL_TRACE
+	and.c	r8, r8, r6		# r6 is preloaded with TI_FLAGS
+	beq	work_pending		# trace bit set?
+	nop
+	enable_irq
+	mv	r4, r0
+	li	r5, 1
+	bl	do_syscall_trace
+	nop
+	b	resume_userspace
+	nop
+
+.macro	save_context	reg
+	sw	r12, [\reg, THREAD_REG12];
+	sw	r13, [\reg, THREAD_REG13];
+	sw	r14, [\reg, THREAD_REG14];
+	sw	r15, [\reg, THREAD_REG15];
+	sw	r16, [\reg, THREAD_REG16];
+	sw	r17, [\reg, THREAD_REG17];
+	sw	r18, [\reg, THREAD_REG18];
+	sw	r19, [\reg, THREAD_REG19];
+	sw	r20, [\reg, THREAD_REG20];
+	sw	r21, [\reg, THREAD_REG21];
+	sw	r29, [\reg, THREAD_REG29];
+	sw	r2, [\reg, THREAD_REG2];
+	sw	r0, [\reg, THREAD_REG0]
+.endm
+
+.macro	restore_context	reg
+	lw	r12, [\reg, THREAD_REG12];
+	lw	r13, [\reg, THREAD_REG13];
+	lw	r14, [\reg, THREAD_REG14];
+	lw	r15, [\reg, THREAD_REG15];
+	lw	r16, [\reg, THREAD_REG16];
+	lw	r17, [\reg, THREAD_REG17];
+	lw	r18, [\reg, THREAD_REG18];
+	lw	r19, [\reg, THREAD_REG19];
+	lw	r20, [\reg, THREAD_REG20];
+	lw	r21, [\reg, THREAD_REG21];
+	lw	r29, [\reg, THREAD_REG29];
+	lw	r0, [\reg, THREAD_REG0];
+	lw	r2, [\reg, THREAD_REG2];
+	lw	r3, [\reg, THREAD_REG3]
+.endm
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next,
+ *			struct thread_info *next_ti)
+ */
+ENTRY(resume)
+	mfcr	r9, cr0
+	nop
+	nop
+	sw	r9, [r4, THREAD_PSR]
+	save_context	r4
+	sw	r3, [r4, THREAD_REG3]
+
+	mv	r28, r6
+	restore_context	r5
+	mv	r8, r6
+	addi	r8, KERNEL_STACK_SIZE
+	subi	r8, 32
+	la 	r9, kernelsp;
+	sw 	r8, [r9];
+
+	mfcr	r9, cr0
+	ldis	r7, 0x00ff
+	nop
+	and	r9, r9, r7
+	lw	r6, [r5, THREAD_PSR]
+	not	r7, r7
+	and	r6, r6, r7
+	or	r6, r6, r9
+	mtcr	r6, cr0
+	nop; nop; nop; nop; nop
+	br	r3
+
+ENTRY(handle_sys)
+	SAVE_ALL
+	sw	r8, [r0, 16]		# argument 5 from user r8
+	sw	r9, [r0, 20]		# argument 6 from user r9
+	enable_irq
+
+	sw	r4, [r0, PT_ORIG_R4]	#for restart syscall
+	sw	r7, [r0, PT_ORIG_R7]	#for restart syscall
+	sw	r27, [r0, PT_IS_SYSCALL] # it from syscall
+
+	lw	r9, [r0, PT_EPC]	# skip syscall on return
+	addi	r9, 4
+	sw	r9, [r0, PT_EPC]
+
+	cmpi.c	r27, __NR_syscalls 	# check syscall number
+	bgtu	illegal_syscall
+
+	slli	r8, r27, 2		# get syscall routine
+	la	r11, sys_call_table
+	add	r11, r11, r8
+	lw	r10, [r11]		# get syscall entry
+
+	cmpz.c	r10
+	beq	illegal_syscall
+
+	lw	r8, [r28, TI_FLAGS]
+	li	r9, _TIF_SYSCALL_TRACE
+	and.c	r8, r8, r9
+	bne	syscall_trace_entry
+
+	brl	r10			# Do The Real system call
+
+	cmpi.c	r4, 0
+	blt	1f
+	ldi	r8, 0
+	sw	r8, [r0, PT_R7]
+	b 2f
+1:
+	cmpi.c	r4, -MAX_ERRNO - 1
+	ble	2f
+	ldi	r8, 0x1;
+	sw	r8, [r0, PT_R7]
+	neg	r4, r4
+2:
+	sw	r4, [r0, PT_R4]		# save result
+
+syscall_return:
+	disable_irq
+	lw	r6, [r28, TI_FLAGS]	# current->work
+	li	r8, _TIF_WORK_MASK
+	and.c	r8, r6, r8
+	bne	syscall_return_work
+	j	restore_all
+
+syscall_return_work:
+	j	syscall_exit_work
+
+syscall_trace_entry:
+	mv	r16, r10
+	mv	r4, r0
+	li	r5, 0
+	bl	do_syscall_trace
+
+	mv	r8, r16
+	lw	r4, [r0, PT_R4]		# Restore argument registers
+	lw	r5, [r0, PT_R5]
+	lw	r6, [r0, PT_R6]
+	lw	r7, [r0, PT_R7]
+	brl	r8
+
+	li	r8, -MAX_ERRNO - 1
+	sw	r8, [r0, PT_R7]		# set error flag
+
+	neg	r4, r4			# error
+	sw	r4, [r0, PT_R0]		# set flag for syscall
+					# restarting
+1:	sw	r4, [r0, PT_R2]		# result
+	j	syscall_exit
+
+illegal_syscall:
+	ldi	r4, -ENOSYS		# error
+	sw	r4, [r0, PT_ORIG_R4]
+	sw	r4, [r0, PT_R4]
+	ldi	r9, 1			# set error flag
+	sw	r9, [r0, PT_R7]
+	j	syscall_return
+
+ENTRY(sys_execve)
+	mv	r4, r0
+	la	r8, score_execve
+	br	r8
+
+ENTRY(sys_clone)
+	mv	r4, r0
+	la	r8, score_clone
+	br	r8
+
+ENTRY(sys_rt_sigreturn)
+	mv	r4, r0
+	la	r8, score_rt_sigreturn
+	br	r8
+
+ENTRY(sys_sigaltstack)
+	mv	r4, r0
+	la	r8, score_sigaltstack
+	br	r8
+
+#ifdef __ARCH_WANT_SYSCALL_DEPRECATED
+ENTRY(sys_fork)
+	mv	r4, r0
+	la	r8, score_fork
+	br	r8
+
+ENTRY(sys_vfork)
+	mv	r4, r0
+	la	r8, score_vfork
+	br	r8
+#endif /* __ARCH_WANT_SYSCALL_DEPRECATED */
+
diff --git a/arch/score/kernel/head.S b/arch/score/kernel/head.S
new file mode 100644
index 0000000..22a7e3c
--- /dev/null
+++ b/arch/score/kernel/head.S
@@ -0,0 +1,70 @@
+/*
+ * arch/score/kernel/head.S
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+
+#include <asm/asm-offsets.h>
+
+	.extern start_kernel
+	.global init_thread_union
+	.global	kernelsp
+
+__INIT
+ENTRY(_stext)
+	la	r30, __bss_start	/* initialize BSS segment. */
+	la	r31, _end
+	xor	r8, r8, r8
+
+1:	cmp.c	r31, r30
+	beq	2f
+
+	sw	r8, [r30]		/* clean memory. */
+	addi	r30, 4
+	b	1b
+
+2:	la	r28, init_thread_union	/* set kernel stack. */
+	mv	r0, r28
+	addi	r0, KERNEL_STACK_SIZE - 32
+	la	r30, kernelsp
+	sw	r0, [r30]
+	subi	r0, 4*4
+	xor	r30, r30, r30
+	ori	r30, 0x02		/* enable MMU. */
+	mtcr	r30, cr4
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* there is no parameter */
+	xor	r4, r4, r4
+	xor	r5, r5, r5
+	xor	r6, r6, r6
+	xor	r7, r7, r7
+	la	r30, start_kernel	/* jump to init_arch */
+	br	r30
diff --git a/arch/score/kernel/init_task.c b/arch/score/kernel/init_task.c
new file mode 100644
index 0000000..ff952f6
--- /dev/null
+++ b/arch/score/kernel/init_task.c
@@ -0,0 +1,47 @@
+/*
+ * arch/score/kernel/init_task.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is THREAD_SIZE aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union
+	__attribute__((__section__(".data.init_task"), __aligned__(THREAD_SIZE))) =
+		{ INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
diff --git a/arch/score/kernel/irq.c b/arch/score/kernel/irq.c
new file mode 100644
index 0000000..47647dd
--- /dev/null
+++ b/arch/score/kernel/irq.c
@@ -0,0 +1,148 @@
+/*
+ * arch/score/kernel/irq.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+
+#include <asm/io.h>
+
+/* the interrupt controller is hardcoded at this address */
+#define SCORE_PIC		((u32 __iomem __force *)0x95F50000)
+
+#define INT_PNDL		0
+#define INT_PNDH		1
+#define INT_PRIORITY_M		2
+#define INT_PRIORITY_SG0	4
+#define INT_PRIORITY_SG1	5
+#define INT_PRIORITY_SG2	6
+#define INT_PRIORITY_SG3	7
+#define INT_MASKL		8
+#define INT_MASKH		9
+
+/*
+ * handles all normal device IRQs
+ */
+asmlinkage void do_IRQ(int irq)
+{
+	irq_enter();
+	generic_handle_irq(irq);
+	irq_exit();
+}
+
+static void score_mask(unsigned int irq_nr)
+{
+	unsigned int irq_source = 63 - irq_nr;
+
+	if (irq_source < 32)
+		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) | \
+			(1 << irq_source)), SCORE_PIC + INT_MASKL);
+	else
+		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKH) | \
+			(1 << (irq_source - 32))), SCORE_PIC + INT_MASKH);
+}
+
+static void score_unmask(unsigned int irq_nr)
+{
+	unsigned int irq_source = 63 - irq_nr;
+
+	if (irq_source < 32)
+		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) & \
+			~(1 << irq_source)), SCORE_PIC + INT_MASKL);
+	else
+		__raw_writel((__raw_readl(SCORE_PIC + INT_MASKH) & \
+			~(1 << (irq_source - 32))), SCORE_PIC + INT_MASKH);
+}
+
+struct irq_chip score_irq_chip = {
+	.name		= "Score7-level",
+	.mask		= score_mask,
+	.mask_ack	= score_mask,
+	.unmask		= score_unmask,
+};
+
+/*
+ * initialise the interrupt system
+ */
+void __init init_IRQ(void)
+{
+	int index;
+	unsigned long target_addr;
+
+	for (index = 0; index < NR_IRQS; ++index)
+		set_irq_chip_and_handler(index, &score_irq_chip,
+					 handle_level_irq);
+
+	for (target_addr = IRQ_VECTOR_BASE_ADDR;
+		target_addr <= IRQ_VECTOR_END_ADDR;
+		target_addr += IRQ_VECTOR_SIZE)
+		memcpy((void *)target_addr, \
+			interrupt_exception_vector, IRQ_VECTOR_SIZE);
+
+	__raw_writel(0xffffffff, SCORE_PIC + INT_MASKL);
+	__raw_writel(0xffffffff, SCORE_PIC + INT_MASKH);
+
+	__asm__ __volatile__(
+		"mtcr	%0, cr3\n\t"
+		: : "r" (EXCEPTION_VECTOR_BASE_ADDR | \
+			VECTOR_ADDRESS_OFFSET_MODE16));
+}
+
+/*
+ * Generic, controller-independent functions:
+ */
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i = *(loff_t *)v, cpu;
+	struct irqaction *action;
+	unsigned long flags;
+
+	if (i == 0) {
+		seq_puts(p, "           ");
+		for_each_online_cpu(cpu)
+			seq_printf(p, "CPU%d       ", cpu);
+		seq_putc(p, '\n');
+	}
+
+	if (i < NR_IRQS) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		action = irq_desc[i].action;
+		if (!action)
+			goto unlock;
+
+		seq_printf(p, "%3d: ", i);
+		seq_printf(p, "%10u ", kstat_irqs(i));
+		seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
+		seq_printf(p, "  %s", action->name);
+		for (action = action->next; action; action = action->next)
+			seq_printf(p, ", %s", action->name);
+
+		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+	}
+
+	return 0;
+}
diff --git a/arch/score/kernel/module.c b/arch/score/kernel/module.c
new file mode 100644
index 0000000..4de8d47
--- /dev/null
+++ b/arch/score/kernel/module.c
@@ -0,0 +1,165 @@
+/*
+ * arch/score/kernel/module.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/moduleloader.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+
+void *module_alloc(unsigned long size)
+{
+	return size ? vmalloc(size) : NULL;
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
+			char *secstrings, struct module *mod)
+{
+	return 0;
+}
+
+int apply_relocate(Elf_Shdr *sechdrs, const char *strtab,
+		unsigned int symindex, unsigned int relindex,
+		struct module *me)
+{
+	Elf32_Shdr *symsec = sechdrs + symindex;
+	Elf32_Shdr *relsec = sechdrs + relindex;
+	Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
+	Elf32_Rel *rel = (void *)relsec->sh_addr;
+	unsigned int i;
+
+	for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
+		unsigned long loc;
+		Elf32_Sym *sym;
+		s32 r_offset;
+
+		r_offset = ELF32_R_SYM(rel->r_info);
+		if ((r_offset < 0) ||
+		    (r_offset > (symsec->sh_size / sizeof(Elf32_Sym)))) {
+			printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n",
+				me->name, relindex, i);
+				return -ENOEXEC;
+		}
+
+		sym = ((Elf32_Sym *)symsec->sh_addr) + r_offset;
+
+		if ((rel->r_offset < 0) ||
+		    (rel->r_offset > dstsec->sh_size - sizeof(u32))) {
+			printk(KERN_ERR "%s: out of bounds relocation, "
+				"section %d reloc %d offset %d size %d\n",
+				me->name, relindex, i, rel->r_offset,
+				dstsec->sh_size);
+			return -ENOEXEC;
+		}
+
+		loc = dstsec->sh_addr + rel->r_offset;
+		switch (ELF32_R_TYPE(rel->r_info)) {
+		case R_SCORE_NONE:
+			break;
+		case R_SCORE_ABS32:
+			*(unsigned long *)loc += sym->st_value;
+			break;
+		case R_SCORE_HI16:
+			break;
+		case R_SCORE_LO16: {
+			unsigned long hi16_offset, offset;
+			unsigned long uvalue;
+			unsigned long temp, temp_hi;
+			temp_hi = *((unsigned long *)loc - 1);
+			temp = *(unsigned long *)loc;
+
+			hi16_offset = (((((temp_hi) >> 16) & 0x3) << 15) |
+					((temp_hi) & 0x7fff)) >> 1;
+			offset = ((temp >> 16 & 0x03) << 15) |
+					((temp & 0x7fff) >> 1);
+			offset = (hi16_offset << 16) | (offset & 0xffff);
+			uvalue = sym->st_value + offset;
+			hi16_offset = (uvalue >> 16) << 1;
+
+			temp_hi = ((temp_hi) & (~(0x37fff))) |
+					(hi16_offset & 0x7fff) |
+					((hi16_offset << 1) & 0x30000);
+			*((unsigned long *)loc - 1) = temp_hi;
+
+			offset = (uvalue & 0xffff) << 1;
+			temp = (temp & (~(0x37fff))) | (offset & 0x7fff) |
+				((offset << 1) & 0x30000);
+			*(unsigned long *)loc = temp;
+			break;
+		}
+		case R_SCORE_24: {
+			unsigned long hi16_offset, offset;
+			unsigned long uvalue;
+			unsigned long temp;
+
+			temp = *(unsigned long *)loc;
+			offset = (temp & 0x03FF7FFE);
+			hi16_offset = (offset & 0xFFFF0000);
+			offset = (hi16_offset | ((offset & 0xFFFF) << 1)) >> 2;
+
+			uvalue = (sym->st_value + offset) >> 1;
+			uvalue = uvalue & 0x00ffffff;
+
+			temp = (temp & 0xfc008001) |
+				((uvalue << 2) & 0x3ff0000) |
+				((uvalue & 0x3fff) << 1);
+			*(unsigned long *)loc = temp;
+			break;
+		}
+		default:
+			printk(KERN_ERR "%s: unknown relocation: %u\n",
+				me->name, ELF32_R_TYPE(rel->r_info));
+			return -ENOEXEC;
+		}
+	}
+
+	return 0;
+}
+
+int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
+		unsigned int symindex, unsigned int relsec,
+		struct module *me)
+{
+	return 0;
+}
+
+/* Given an address, look for it in the module exception tables. */
+const struct exception_table_entry *search_module_dbetables(unsigned long addr)
+{
+	return NULL;
+}
+
+/* Put in dbe list if necessary. */
+int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
+		struct module *me)
+{
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod) {}
diff --git a/arch/score/kernel/process.c b/arch/score/kernel/process.c
new file mode 100644
index 0000000..25d0803
--- /dev/null
+++ b/arch/score/kernel/process.c
@@ -0,0 +1,168 @@
+/*
+ * arch/score/kernel/process.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/elfcore.h>
+#include <linux/pm.h>
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+/* If or when software machine-restart is implemented, add code here. */
+void machine_restart(char *command) {}
+
+/* If or when software machine-halt is implemented, add code here. */
+void machine_halt(void) {}
+
+/* If or when software machine-power-off is implemented, add code here. */
+void machine_power_off(void) {}
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void __noreturn cpu_idle(void)
+{
+	/* endless idle loop with no priority at all */
+	while (1) {
+		while (!need_resched())
+			barrier();
+
+		preempt_enable_no_resched();
+		schedule();
+		preempt_disable();
+	}
+}
+
+void ret_from_fork(void);
+
+void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
+{
+	unsigned long status;
+
+	/* New thread loses kernel privileges. */
+	status = regs->cp0_psr & ~(KU_MASK);
+	status |= KU_USER;
+	regs->cp0_psr = status;
+	regs->cp0_epc = pc;
+	regs->regs[0] = sp;
+}
+
+void exit_thread(void) {}
+
+/*
+ * When a process does an "exec", machine state like FPU and debug
+ * registers need to be reset.  This is a hook function for that.
+ * Currently we don't have any such state to reset, so this is empty.
+ */
+void flush_thread(void) {}
+
+/*
+ * set up the kernel stack and exception frames for a new process
+ */
+int copy_thread(unsigned long clone_flags, unsigned long usp,
+		unsigned long unused,
+		struct task_struct *p, struct pt_regs *regs)
+{
+	struct thread_info *ti = task_thread_info(p);
+	struct pt_regs *childregs = task_pt_regs(p);
+
+	p->set_child_tid = NULL;
+	p->clear_child_tid = NULL;
+
+	*childregs = *regs;
+	childregs->regs[7] = 0;		/* Clear error flag */
+	childregs->regs[4] = 0;		/* Child gets zero as return value */
+	regs->regs[4] = p->pid;
+
+	if (childregs->cp0_psr & 0x8) {	/* test kernel fork or user fork */
+		childregs->regs[0] = usp;		/* user fork */
+	} else {
+		childregs->regs[28] = (unsigned long) ti; /* kernel fork */
+		childregs->regs[0] = (unsigned long) childregs;
+	}
+
+	p->thread.reg0 = (unsigned long) childregs;
+	p->thread.reg3 = (unsigned long) ret_from_fork;
+	p->thread.cp0_psr = 0;
+
+	return 0;
+}
+
+/* Fill in the fpu structure for a core dump. */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+{
+	return 1;
+}
+
+static void __noreturn
+kernel_thread_helper(void *unused0, int (*fn)(void *),
+		 void *arg, void *unused1)
+{
+	do_exit(fn(arg));
+}
+
+/*
+ * Create a kernel thread.
+ */
+long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	struct pt_regs regs;
+
+	memset(&regs, 0, sizeof(regs));
+
+	regs.regs[6] = (unsigned long) arg;
+	regs.regs[5] = (unsigned long) fn;
+	regs.cp0_epc = (unsigned long) kernel_thread_helper;
+	regs.cp0_psr = (regs.cp0_psr & ~(0x1|0x4|0x8)) | \
+			((regs.cp0_psr & 0x3) << 2);
+
+	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, \
+			0, &regs, 0, NULL, NULL);
+}
+
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	return task_pt_regs(tsk)->cp0_epc;
+}
+
+unsigned long get_wchan(struct task_struct *task)
+{
+	if (!task || task == current || task->state == TASK_RUNNING)
+		return 0;
+
+	if (!task_stack_page(task))
+		return 0;
+
+	return task_pt_regs(task)->cp0_epc;
+}
+
+unsigned long arch_align_stack(unsigned long sp)
+{
+	return sp;
+}
diff --git a/arch/score/kernel/ptrace.c b/arch/score/kernel/ptrace.c
new file mode 100644
index 0000000..174c642
--- /dev/null
+++ b/arch/score/kernel/ptrace.c
@@ -0,0 +1,382 @@
+/*
+ * arch/score/kernel/ptrace.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/elf.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/ptrace.h>
+#include <linux/regset.h>
+
+#include <asm/uaccess.h>
+
+/*
+ * retrieve the contents of SCORE userspace general registers
+ */
+static int genregs_get(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       void *kbuf, void __user *ubuf)
+{
+	const struct pt_regs *regs = task_pt_regs(target);
+	int ret;
+
+	/* skip 9 * sizeof(unsigned long) not use for pt_regs */
+	ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+					0, offsetof(struct pt_regs, regs));
+
+	/* r0 - r31, cel, ceh, sr0, sr1, sr2, epc, ema, psr, ecr, condition */
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				  regs->regs,
+				  offsetof(struct pt_regs, regs),
+				  offsetof(struct pt_regs, cp0_condition));
+
+	if (!ret)
+		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+						sizeof(struct pt_regs), -1);
+
+	return ret;
+}
+
+/*
+ * update the contents of the SCORE userspace general registers
+ */
+static int genregs_set(struct task_struct *target,
+		       const struct user_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+	int ret;
+
+	/* skip 9 * sizeof(unsigned long) */
+	ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+					0, offsetof(struct pt_regs, regs));
+
+	/* r0 - r31, cel, ceh, sr0, sr1, sr2, epc, ema, psr, ecr, condition */
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				  regs->regs,
+				  offsetof(struct pt_regs, regs),
+				  offsetof(struct pt_regs, cp0_condition));
+
+	if (!ret)
+		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+						sizeof(struct pt_regs), -1);
+
+	return ret;
+}
+
+/*
+ * Define the register sets available on the score7 under Linux
+ */
+enum score7_regset {
+	REGSET_GENERAL,
+};
+
+static const struct user_regset score7_regsets[] = {
+	[REGSET_GENERAL] = {
+		.core_note_type	= NT_PRSTATUS,
+		.n		= ELF_NGREG,
+		.size		= sizeof(long),
+		.align		= sizeof(long),
+		.get		= genregs_get,
+		.set		= genregs_set,
+	},
+};
+
+static const struct user_regset_view user_score_native_view = {
+	.name		= "score7",
+	.e_machine	= EM_SCORE7,
+	.regsets	= score7_regsets,
+	.n		= ARRAY_SIZE(score7_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+	return &user_score_native_view;
+}
+
+static int is_16bitinsn(unsigned long insn)
+{
+	if ((insn & INSN32_MASK) == INSN32_MASK)
+		return 0;
+	else
+		return 1;
+}
+
+int
+read_tsk_long(struct task_struct *child,
+		unsigned long addr, unsigned long *res)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+
+	return copied != sizeof(*res) ? -EIO : 0;
+}
+
+int
+read_tsk_short(struct task_struct *child,
+		unsigned long addr, unsigned short *res)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+
+	return copied != sizeof(*res) ? -EIO : 0;
+}
+
+static int
+write_tsk_short(struct task_struct *child,
+		unsigned long addr, unsigned short val)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+
+	return copied != sizeof(val) ? -EIO : 0;
+}
+
+static int
+write_tsk_long(struct task_struct *child,
+		unsigned long addr, unsigned long val)
+{
+	int copied;
+
+	copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+
+	return copied != sizeof(val) ? -EIO : 0;
+}
+
+void user_enable_single_step(struct task_struct *child)
+{
+	/* far_epc is the target of branch */
+	unsigned int epc, far_epc = 0;
+	unsigned long epc_insn, far_epc_insn;
+	int ninsn_type;			/* next insn type 0=16b, 1=32b */
+	unsigned int tmp, tmp2;
+	struct pt_regs *regs = task_pt_regs(child);
+	child->thread.single_step = 1;
+	child->thread.ss_nextcnt = 1;
+	epc = regs->cp0_epc;
+
+	read_tsk_long(child, epc, &epc_insn);
+
+	if (is_16bitinsn(epc_insn)) {
+		if ((epc_insn & J16M) == J16) {
+			tmp = epc_insn & 0xFFE;
+			epc = (epc & 0xFFFFF000) | tmp;
+		} else if ((epc_insn & B16M) == B16) {
+			child->thread.ss_nextcnt = 2;
+			tmp = (epc_insn & 0xFF) << 1;
+			tmp = tmp << 23;
+			tmp = (unsigned int)((int) tmp >> 23);
+			far_epc = epc + tmp;
+			epc += 2;
+		} else if ((epc_insn & BR16M) == BR16) {
+			child->thread.ss_nextcnt = 2;
+			tmp = (epc_insn >> 4) & 0xF;
+			far_epc = regs->regs[tmp];
+			epc += 2;
+		} else
+			epc += 2;
+	} else {
+		if ((epc_insn & J32M) == J32) {
+			tmp = epc_insn & 0x03FFFFFE;
+			tmp2 = tmp & 0x7FFF;
+			tmp = (((tmp >> 16) & 0x3FF) << 15) | tmp2;
+			epc = (epc & 0xFFC00000) | tmp;
+		} else if ((epc_insn & B32M) == B32) {
+			child->thread.ss_nextcnt = 2;
+			tmp = epc_insn & 0x03FFFFFE;	/* discard LK bit */
+			tmp2 = tmp & 0x3FF;
+			tmp = (((tmp >> 16) & 0x3FF) << 10) | tmp2; /* 20bit */
+			tmp = tmp << 12;
+			tmp = (unsigned int)((int) tmp >> 12);
+			far_epc = epc + tmp;
+			epc += 4;
+		} else if ((epc_insn & BR32M) == BR32) {
+			child->thread.ss_nextcnt = 2;
+			tmp = (epc_insn >> 16) & 0x1F;
+			far_epc = regs->regs[tmp];
+			epc += 4;
+		} else
+			epc += 4;
+	}
+
+	if (child->thread.ss_nextcnt == 1) {
+		read_tsk_long(child, epc, &epc_insn);
+
+		if (is_16bitinsn(epc_insn)) {
+			write_tsk_short(child, epc, SINGLESTEP16_INSN);
+			ninsn_type = 0;
+		} else {
+			write_tsk_long(child, epc, SINGLESTEP32_INSN);
+			ninsn_type = 1;
+		}
+
+		if (ninsn_type == 0) {  /* 16bits */
+			child->thread.insn1_type = 0;
+			child->thread.addr1 = epc;
+			 /* the insn may have 32bit data */
+			child->thread.insn1 = (short)epc_insn;
+		} else {
+			child->thread.insn1_type = 1;
+			child->thread.addr1 = epc;
+			child->thread.insn1 = epc_insn;
+		}
+	} else {
+		/* branch! have two target child->thread.ss_nextcnt=2 */
+		read_tsk_long(child, epc, &epc_insn);
+		read_tsk_long(child, far_epc, &far_epc_insn);
+		if (is_16bitinsn(epc_insn)) {
+			write_tsk_short(child, epc, SINGLESTEP16_INSN);
+			ninsn_type = 0;
+		} else {
+			write_tsk_long(child, epc, SINGLESTEP32_INSN);
+			ninsn_type = 1;
+		}
+
+		if (ninsn_type == 0) {  /* 16bits */
+			child->thread.insn1_type = 0;
+			child->thread.addr1 = epc;
+			 /* the insn may have 32bit data */
+			child->thread.insn1 = (short)epc_insn;
+		} else {
+			child->thread.insn1_type = 1;
+			child->thread.addr1 = epc;
+			child->thread.insn1 = epc_insn;
+		}
+
+		if (is_16bitinsn(far_epc_insn)) {
+			write_tsk_short(child, far_epc, SINGLESTEP16_INSN);
+			ninsn_type = 0;
+		} else {
+			write_tsk_long(child, far_epc, SINGLESTEP32_INSN);
+			ninsn_type = 1;
+		}
+
+		if (ninsn_type == 0) {  /* 16bits */
+			child->thread.insn2_type = 0;
+			child->thread.addr2 = far_epc;
+			 /* the insn may have 32bit data */
+			child->thread.insn2 = (short)far_epc_insn;
+		} else {
+			child->thread.insn2_type = 1;
+			child->thread.addr2 = far_epc;
+			child->thread.insn2 = far_epc_insn;
+		}
+	}
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	if (child->thread.insn1_type == 0)
+		write_tsk_short(child, child->thread.addr1,
+				child->thread.insn1);
+
+	if (child->thread.insn1_type == 1)
+		write_tsk_long(child, child->thread.addr1,
+				child->thread.insn1);
+
+	if (child->thread.ss_nextcnt == 2) {	/* branch */
+		if (child->thread.insn1_type == 0)
+			write_tsk_short(child, child->thread.addr1,
+					child->thread.insn1);
+		if (child->thread.insn1_type == 1)
+			write_tsk_long(child, child->thread.addr1,
+					child->thread.insn1);
+		if (child->thread.insn2_type == 0)
+			write_tsk_short(child, child->thread.addr2,
+					child->thread.insn2);
+		if (child->thread.insn2_type == 1)
+			write_tsk_long(child, child->thread.addr2,
+					child->thread.insn2);
+	}
+
+	child->thread.single_step = 0;
+	child->thread.ss_nextcnt = 0;
+}
+
+void ptrace_disable(struct task_struct *child)
+{
+	user_disable_single_step(child);
+}
+
+long
+arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+	int ret;
+	unsigned long __user *datap = (void __user *)data;
+
+	switch (request) {
+	case PTRACE_GETREGS:
+		ret = copy_regset_to_user(child, &user_score_native_view,
+						REGSET_GENERAL,
+						0, sizeof(struct pt_regs),
+						(void __user *)datap);
+		break;
+
+	case PTRACE_SETREGS:
+		ret = copy_regset_from_user(child, &user_score_native_view,
+						REGSET_GENERAL,
+						0, sizeof(struct pt_regs),
+						(const void __user *)datap);
+		break;
+
+	default:
+		ret = ptrace_request(child, request, addr, data);
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * Notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
+ */
+asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
+{
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+
+	/* The 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery. */
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ?
+			0x80 : 0));
+
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+}
diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c
new file mode 100644
index 0000000..6a2503c
--- /dev/null
+++ b/arch/score/kernel/setup.c
@@ -0,0 +1,159 @@
+/*
+ * arch/score/kernel/setup.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/seq_file.h>
+#include <linux/screen_info.h>
+
+#include <asm-generic/sections.h>
+#include <asm/setup.h>
+
+struct screen_info screen_info;
+unsigned long kernelsp;
+
+static char command_line[COMMAND_LINE_SIZE];
+static struct resource code_resource = { .name = "Kernel code",};
+static struct resource data_resource = { .name = "Kernel data",};
+
+static void __init bootmem_init(void)
+{
+	unsigned long start_pfn, bootmap_size;
+	unsigned long size = initrd_end - initrd_start;
+
+	start_pfn = PFN_UP(__pa(&_end));
+
+	min_low_pfn = PFN_UP(MEMORY_START);
+	max_low_pfn = PFN_UP(MEMORY_START + MEMORY_SIZE);
+
+	/* Initialize the boot-time allocator with low memory only. */
+	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
+					 min_low_pfn, max_low_pfn);
+	add_active_range(0, min_low_pfn, max_low_pfn);
+
+	free_bootmem(PFN_PHYS(start_pfn),
+		     (max_low_pfn - start_pfn) << PAGE_SHIFT);
+	memory_present(0, start_pfn, max_low_pfn);
+
+	/* Reserve space for the bootmem bitmap. */
+	reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size, BOOTMEM_DEFAULT);
+
+	if (size == 0) {
+		printk(KERN_INFO "Initrd not found or empty");
+		goto disable;
+	}
+
+	if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) {
+		printk(KERN_ERR "Initrd extends beyond end of memory");
+		goto disable;
+	}
+
+	/* Reserve space for the initrd bitmap. */
+	reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
+	initrd_below_start_ok = 1;
+
+	pr_info("Initial ramdisk at: 0x%lx (%lu bytes)\n",
+		 initrd_start, size);
+	return;
+disable:
+	printk(KERN_CONT " - disabling initrd\n");
+	initrd_start = 0;
+	initrd_end = 0;
+}
+
+static void __init resource_init(void)
+{
+	struct resource *res;
+
+	code_resource.start = __pa(&_text);
+	code_resource.end = __pa(&_etext) - 1;
+	data_resource.start = __pa(&_etext);
+	data_resource.end = __pa(&_edata) - 1;
+
+	res = alloc_bootmem(sizeof(struct resource));
+	res->name = "System RAM";
+	res->start = MEMORY_START;
+	res->end = MEMORY_START + MEMORY_SIZE - 1;
+	res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	request_resource(&iomem_resource, res);
+
+	request_resource(res, &code_resource);
+	request_resource(res, &data_resource);
+}
+
+void __init setup_arch(char **cmdline_p)
+{
+	randomize_va_space = 0;
+	*cmdline_p = command_line;
+
+	cpu_cache_init();
+	tlb_init();
+	bootmem_init();
+	paging_init();
+	resource_init();
+}
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+	unsigned long n = (unsigned long) v - 1;
+
+	seq_printf(m, "processor\t\t: %ld\n", n);
+	seq_printf(m, "\n");
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	unsigned long i = *pos;
+
+	return i < 1 ? (void *) (i + 1) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo,
+};
+
+static int __init topology_init(void)
+{
+	return 0;
+}
+
+subsys_initcall(topology_init);
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
new file mode 100644
index 0000000..aa57440
--- /dev/null
+++ b/arch/score/kernel/signal.c
@@ -0,0 +1,361 @@
+/*
+ * arch/score/kernel/signal.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/uaccess.h>
+
+#include <asm/cacheflush.h>
+#include <asm/syscalls.h>
+#include <asm/ucontext.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+struct rt_sigframe {
+	u32 rs_ass[4];		/* argument save space */
+	u32 rs_code[2];		/* signal trampoline */
+	struct siginfo rs_info;
+	struct ucontext rs_uc;
+};
+
+static int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+{
+	int err = 0;
+	unsigned long reg;
+
+	reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc);
+	err |= __put_user(regs->cp0_psr, &sc->sc_psr);
+	err |= __put_user(regs->cp0_condition, &sc->sc_condition);
+
+
+#define save_gp_reg(i) {				\
+	reg = regs->regs[i];				\
+	err |= __put_user(reg, &sc->sc_regs[i]);	\
+} while (0)
+	save_gp_reg(0); save_gp_reg(1); save_gp_reg(2);
+	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5);
+	save_gp_reg(6);	save_gp_reg(7); save_gp_reg(8);
+	save_gp_reg(9); save_gp_reg(10); save_gp_reg(11);
+	save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17);
+	save_gp_reg(18); save_gp_reg(19); save_gp_reg(20);
+	save_gp_reg(21); save_gp_reg(22); save_gp_reg(23);
+	save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29);
+#undef save_gp_reg
+
+	reg = regs->ceh; err |= __put_user(reg, &sc->sc_mdceh);
+	reg = regs->cel; err |= __put_user(reg, &sc->sc_mdcel);
+	err |= __put_user(regs->cp0_ecr, &sc->sc_ecr);
+	err |= __put_user(regs->cp0_ema, &sc->sc_ema);
+
+	return err;
+}
+
+static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+{
+	int err = 0;
+	u32 reg;
+
+	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+	err |= __get_user(regs->cp0_condition, &sc->sc_condition);
+
+	err |= __get_user(reg, &sc->sc_mdceh);
+	regs->ceh = (int) reg;
+	err |= __get_user(reg, &sc->sc_mdcel);
+	regs->cel = (int) reg;
+
+	err |= __get_user(reg, &sc->sc_psr);
+	regs->cp0_psr = (int) reg;
+	err |= __get_user(reg, &sc->sc_ecr);
+	regs->cp0_ecr = (int) reg;
+	err |= __get_user(reg, &sc->sc_ema);
+	regs->cp0_ema = (int) reg;
+
+#define restore_gp_reg(i) do {				\
+	err |= __get_user(reg, &sc->sc_regs[i]);	\
+	regs->regs[i] = reg;				\
+} while (0)
+	restore_gp_reg(0); restore_gp_reg(1); restore_gp_reg(2);
+	restore_gp_reg(3); restore_gp_reg(4); restore_gp_reg(5);
+	restore_gp_reg(6); restore_gp_reg(7); restore_gp_reg(8);
+	restore_gp_reg(9); restore_gp_reg(10); restore_gp_reg(11);
+	restore_gp_reg(12); restore_gp_reg(13); restore_gp_reg(14);
+	restore_gp_reg(15); restore_gp_reg(16); restore_gp_reg(17);
+	restore_gp_reg(18); restore_gp_reg(19);	restore_gp_reg(20);
+	restore_gp_reg(21); restore_gp_reg(22); restore_gp_reg(23);
+	restore_gp_reg(24); restore_gp_reg(25); restore_gp_reg(26);
+	restore_gp_reg(27); restore_gp_reg(28); restore_gp_reg(29);
+#undef restore_gp_reg
+
+	return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static void __user *get_sigframe(struct k_sigaction *ka,
+			struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long sp;
+
+	/* Default to using normal stack */
+	sp = regs->regs[0];
+	sp -= 32;
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (!on_sig_stack(sp)))
+		sp = current->sas_ss_sp + current->sas_ss_size;
+
+	return (void __user*)((sp - frame_size) & ~7);
+}
+
+asmlinkage long
+score_sigaltstack(struct pt_regs *regs)
+{
+	const stack_t __user *uss = (const stack_t __user *) regs->regs[4];
+	stack_t __user *uoss = (stack_t __user *) regs->regs[5];
+	unsigned long usp = regs->regs[0];
+
+	return do_sigaltstack(uss, uoss, usp);
+}
+
+asmlinkage long
+score_rt_sigreturn(struct pt_regs *regs)
+{
+	struct rt_sigframe __user *frame;
+	sigset_t set;
+	stack_t st;
+	int sig;
+
+	frame = (struct rt_sigframe __user *) regs->regs[0];
+	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	sig = restore_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+	if (sig < 0)
+		goto badframe;
+	else if (sig)
+		force_sig(sig, current);
+
+	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
+		goto badframe;
+
+	/* It is more difficult to avoid calling this function than to
+	   call it and ignore errors.  */
+	do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
+
+	__asm__ __volatile__(
+		"mv\tr0, %0\n\t"
+		"la\tr8, syscall_exit\n\t"
+		"br\tr8\n\t"
+		: : "r" (regs) : "r8");
+
+badframe:
+	force_sig(SIGSEGV, current);
+
+	return 0;
+}
+
+static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
+		int signr, sigset_t *set, siginfo_t *info)
+{
+	struct rt_sigframe __user *frame;
+	int err = 0;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+		goto give_sigsegv;
+
+	/*
+	 * Set up the return code ...
+	 *
+	 *         li      v0, __NR_rt_sigreturn
+	 *         syscall
+	 */
+	err |= __put_user(0x87788000 + __NR_rt_sigreturn*2,
+			frame->rs_code + 0);
+	err |= __put_user(0x80008002, frame->rs_code + 1);
+	flush_cache_sigtramp((unsigned long) frame->rs_code);
+
+	err |= copy_siginfo_to_user(&frame->rs_info, info);
+	err |= __put_user(0, &frame->rs_uc.uc_flags);
+	err |= __put_user(NULL, &frame->rs_uc.uc_link);
+	err |= __put_user((void __user *)current->sas_ss_sp,
+				&frame->rs_uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(regs->regs[0]),
+				&frame->rs_uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size,
+				&frame->rs_uc.uc_stack.ss_size);
+	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	regs->regs[0] = (unsigned long) frame;
+	regs->regs[3] = (unsigned long) frame->rs_code;
+	regs->regs[4] = signr;
+	regs->regs[5] = (unsigned long) &frame->rs_info;
+	regs->regs[6] = (unsigned long) &frame->rs_uc;
+	regs->regs[29] = (unsigned long) ka->sa.sa_handler;
+	regs->cp0_epc = (unsigned long) ka->sa.sa_handler;
+
+	return 0;
+
+give_sigsegv:
+	if (signr == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	return -EFAULT;
+}
+
+static int handle_signal(unsigned long sig, siginfo_t *info,
+	struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
+{
+	int ret;
+
+	if (regs->is_syscall) {
+		switch (regs->regs[4]) {
+		case ERESTART_RESTARTBLOCK:
+		case ERESTARTNOHAND:
+			regs->regs[4] = EINTR;
+			break;
+		case ERESTARTSYS:
+			if (!(ka->sa.sa_flags & SA_RESTART)) {
+				regs->regs[4] = EINTR;
+				break;
+			}
+		case ERESTARTNOINTR:
+			regs->regs[4] = regs->orig_r4;
+			regs->regs[7] = regs->orig_r7;
+			regs->cp0_epc -= 8;
+		}
+
+		regs->is_syscall = 0;
+	}
+
+	/*
+	 * Set up the stack frame
+	 */
+	ret = setup_rt_frame(ka, regs, sig, oldset, info);
+
+	spin_lock_irq(&current->sighand->siglock);
+	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
+	if (!(ka->sa.sa_flags & SA_NODEFER))
+		sigaddset(&current->blocked, sig);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	return ret;
+}
+
+static void do_signal(struct pt_regs *regs)
+{
+	struct k_sigaction ka;
+	sigset_t *oldset;
+	siginfo_t info;
+	int signr;
+
+	/*
+	 * We want the common case to go fast, which is why we may in certain
+	 * cases get here from kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return;
+
+	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+		oldset = &current->saved_sigmask;
+	else
+		oldset = &current->blocked;
+
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	if (signr > 0) {
+		/* Actually deliver the signal.  */
+		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+			/*
+			 * A signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag.
+			 */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+
+		return;
+	}
+
+	if (regs->is_syscall) {
+		if (regs->regs[4] == ERESTARTNOHAND ||
+		    regs->regs[4] == ERESTARTSYS ||
+		    regs->regs[4] == ERESTARTNOINTR) {
+			regs->regs[4] = regs->orig_r4;
+			regs->regs[7] = regs->orig_r7;
+			regs->cp0_epc -= 8;
+		}
+
+		if (regs->regs[4] == ERESTART_RESTARTBLOCK) {
+			regs->regs[27] = __NR_restart_syscall;
+			regs->regs[4] = regs->orig_r4;
+			regs->regs[7] = regs->orig_r7;
+			regs->cp0_epc -= 8;
+		}
+
+		regs->is_syscall = 0;	/* Don't deal with this again.  */
+	}
+
+	/*
+	 * If there's no signal to deliver, we just put the saved sigmask
+	 * back
+	 */
+	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+		clear_thread_flag(TIF_RESTORE_SIGMASK);
+		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+	}
+}
+
+/*
+ * notification of userspace execution resumption
+ * - triggered by the TIF_WORK_MASK flags
+ */
+asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
+				__u32 thread_info_flags)
+{
+	/* deal with pending signal delivery */
+	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+		do_signal(regs);
+}
diff --git a/arch/score/kernel/sys_call_table.c b/arch/score/kernel/sys_call_table.c
new file mode 100644
index 0000000..287369b
--- /dev/null
+++ b/arch/score/kernel/sys_call_table.c
@@ -0,0 +1,12 @@
+#include <linux/syscalls.h>
+#include <linux/signal.h>
+#include <linux/unistd.h>
+
+#include <asm/syscalls.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, call) [nr] = (call),
+
+void *sys_call_table[__NR_syscalls] = {
+#include <asm/unistd.h>
+};
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c
new file mode 100644
index 0000000..0012494
--- /dev/null
+++ b/arch/score/kernel/sys_score.c
@@ -0,0 +1,151 @@
+/*
+ * arch/score/kernel/syscall.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/module.h>
+#include <linux/unistd.h>
+#include <linux/syscalls.h>
+#include <asm/syscalls.h>
+
+asmlinkage long 
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+	  unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file *file = NULL;
+
+	if (pgoff & (~PAGE_MASK >> 12))
+		return -EINVAL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			return error;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+
+	return error;
+}
+
+asmlinkage long
+sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
+	unsigned long flags, unsigned long fd, off_t pgoff)
+{
+	return sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
+}
+
+asmlinkage long
+score_fork(struct pt_regs *regs)
+{
+	return do_fork(SIGCHLD, regs->regs[0], regs, 0, NULL, NULL);
+}
+
+/*
+ * Clone a task - this clones the calling program thread.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage long
+score_clone(struct pt_regs *regs)
+{
+	unsigned long clone_flags;
+	unsigned long newsp;
+	int __user *parent_tidptr, *child_tidptr;
+
+	clone_flags = regs->regs[4];
+	newsp = regs->regs[5];
+	if (!newsp)
+		newsp = regs->regs[0];
+	parent_tidptr = (int __user *)regs->regs[6];
+	child_tidptr = (int __user *)regs->regs[8];
+
+	return do_fork(clone_flags, newsp, regs, 0,
+			parent_tidptr, child_tidptr);
+}
+
+asmlinkage long
+score_vfork(struct pt_regs *regs)
+{
+	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
+			regs->regs[0], regs, 0, NULL, NULL);
+}
+
+/*
+ * sys_execve() executes a new program.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage long
+score_execve(struct pt_regs *regs)
+{
+	int error;
+	char *filename;
+
+	filename = getname((char __user*)regs->regs[4]);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		return error;
+
+	error = do_execve(filename, (char __user *__user*)regs->regs[5],
+			  (char __user *__user *) regs->regs[6], regs);
+
+	putname(filename);
+	return error;
+}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+{
+	register unsigned long __r4 asm("r4") = (unsigned long) filename;
+	register unsigned long __r5 asm("r5") = (unsigned long) argv;
+	register unsigned long __r6 asm("r6") = (unsigned long) envp;
+	register unsigned long __r7 asm("r7");
+
+	__asm__ __volatile__ ("	\n"
+		"ldi	r27, %5		\n"
+		"syscall		\n"
+		"mv	%0, r4		\n"
+		"mv	%1, r7		\n"
+		: "=&r" (__r4), "=r" (__r7)
+		: "r" (__r4), "r" (__r5), "r" (__r6), "i" (__NR_execve)
+		: "r8", "r9", "r10", "r11", "r22", "r23", "r24", "r25",
+		  "r26", "r27", "memory");
+
+	if (__r7 == 0)
+		return __r4;
+
+	return -__r4;
+}
diff --git a/arch/score/kernel/time.c b/arch/score/kernel/time.c
new file mode 100644
index 0000000..f0a43af
--- /dev/null
+++ b/arch/score/kernel/time.c
@@ -0,0 +1,99 @@
+/*
+ * arch/score/kernel/time.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+
+#include <asm/scoreregs.h>
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evdev = dev_id;
+
+	/* clear timer interrupt flag */
+	outl(1, P_TIMER0_CPP_REG);
+	evdev->event_handler(evdev);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction timer_irq = {
+	.handler = timer_interrupt,
+	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.name = "timer",
+};
+
+static int score_timer_set_next_event(unsigned long delta,
+		struct clock_event_device *evdev)
+{
+	outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL);
+	outl(delta, P_TIMER0_PRELOAD);
+	outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
+
+	return 0;
+}
+
+static void score_timer_set_mode(enum clock_event_mode mode,
+		struct clock_event_device *evdev)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		outl((TMR_M_PERIODIC | TMR_IE_ENABLE), P_TIMER0_CTRL);
+		outl(SYSTEM_CLOCK/HZ, P_TIMER0_PRELOAD);
+		outl(inl(P_TIMER0_CTRL) | TMR_ENABLE, P_TIMER0_CTRL);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+	case CLOCK_EVT_MODE_UNUSED:
+		break;
+	default:
+		BUG();
+	}
+}
+
+static struct clock_event_device score_clockevent = {
+	.name		= "score_clockevent",
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+	.shift		= 16,
+	.set_next_event	= score_timer_set_next_event,
+	.set_mode	= score_timer_set_mode,
+};
+
+void __init time_init(void)
+{
+	timer_irq.dev_id = &score_clockevent;
+	setup_irq(IRQ_TIMER , &timer_irq);
+
+	/* setup COMPARE clockevent */
+	score_clockevent.mult = div_sc(SYSTEM_CLOCK, NSEC_PER_SEC,
+					score_clockevent.shift);
+	score_clockevent.max_delta_ns = clockevent_delta2ns((u32)~0,
+					&score_clockevent);
+	score_clockevent.min_delta_ns = clockevent_delta2ns(50,
+						&score_clockevent) + 1;
+	score_clockevent.cpumask = cpumask_of(0);
+	clockevents_register_device(&score_clockevent);
+}
diff --git a/arch/score/kernel/traps.c b/arch/score/kernel/traps.c
new file mode 100644
index 0000000..0e46fb1
--- /dev/null
+++ b/arch/score/kernel/traps.c
@@ -0,0 +1,349 @@
+/*
+ * arch/score/kernel/traps.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include <asm/cacheflush.h>
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+
+unsigned long exception_handlers[32];
+
+/*
+ * The architecture-independent show_stack generator
+ */
+void show_stack(struct task_struct *task, unsigned long *sp)
+{
+	int i;
+	long stackdata;
+
+	sp = sp ? sp : (unsigned long *)&sp;
+
+	printk(KERN_NOTICE "Stack: ");
+	i = 1;
+	while ((long) sp & (PAGE_SIZE - 1)) {
+		if (i && ((i % 8) == 0))
+			printk(KERN_NOTICE "\n");
+		if (i > 40) {
+			printk(KERN_NOTICE " ...");
+			break;
+		}
+
+		if (__get_user(stackdata, sp++)) {
+			printk(KERN_NOTICE " (Bad stack address)");
+			break;
+		}
+
+		printk(KERN_NOTICE " %08lx", stackdata);
+		i++;
+	}
+	printk(KERN_NOTICE "\n");
+}
+
+static void show_trace(long *sp)
+{
+	int i;
+	long addr;
+
+	sp = sp ? sp : (long *) &sp;
+
+	printk(KERN_NOTICE "Call Trace:  ");
+	i = 1;
+	while ((long) sp & (PAGE_SIZE - 1)) {
+		if (__get_user(addr, sp++)) {
+			if (i && ((i % 6) == 0))
+				printk(KERN_NOTICE "\n");
+			printk(KERN_NOTICE " (Bad stack address)\n");
+			break;
+		}
+
+		if (kernel_text_address(addr)) {
+			if (i && ((i % 6) == 0))
+				printk(KERN_NOTICE "\n");
+			if (i > 40) {
+				printk(KERN_NOTICE " ...");
+				break;
+			}
+
+			printk(KERN_NOTICE " [<%08lx>]", addr);
+			i++;
+		}
+	}
+	printk(KERN_NOTICE "\n");
+}
+
+static void show_code(unsigned int *pc)
+{
+	long i;
+
+	printk(KERN_NOTICE "\nCode:");
+
+	for (i = -3; i < 6; i++) {
+		unsigned long insn;
+		if (__get_user(insn, pc + i)) {
+			printk(KERN_NOTICE " (Bad address in epc)\n");
+			break;
+		}
+		printk(KERN_NOTICE "%c%08lx%c", (i ? ' ' : '<'),
+			insn, (i ? ' ' : '>'));
+	}
+}
+
+/*
+ * FIXME: really the generic show_regs should take a const pointer argument.
+ */
+void show_regs(struct pt_regs *regs)
+{
+	printk("r0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+		regs->regs[0], regs->regs[1], regs->regs[2], regs->regs[3],
+		regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+	printk("r8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+		regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11],
+		regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
+	printk("r16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+		regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19],
+		regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
+	printk("r24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
+		regs->regs[24], regs->regs[25], regs->regs[26], regs->regs[27],
+		regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
+
+	printk("CEH : %08lx\n", regs->ceh);
+	printk("CEL : %08lx\n", regs->cel);
+
+	printk("EMA:%08lx, epc:%08lx %s\nPSR: %08lx\nECR:%08lx\nCondition : %08lx\n",
+		regs->cp0_ema, regs->cp0_epc, print_tainted(), regs->cp0_psr,
+		regs->cp0_ecr, regs->cp0_condition);
+}
+
+static void show_registers(struct pt_regs *regs)
+{
+	show_regs(regs);
+	printk(KERN_NOTICE "Process %s (pid: %d, stackpage=%08lx)\n",
+		current->comm, current->pid, (unsigned long) current);
+	show_stack(current_thread_info()->task, (long *) regs->regs[0]);
+	show_trace((long *) regs->regs[0]);
+	show_code((unsigned int *) regs->cp0_epc);
+	printk(KERN_NOTICE "\n");
+}
+
+/*
+ * The architecture-independent dump_stack generator
+ */
+void dump_stack(void)
+{
+	show_stack(current_thread_info()->task,
+		   (long *) get_irq_regs()->regs[0]);
+}
+EXPORT_SYMBOL(dump_stack);
+
+void __die(const char *str, struct pt_regs *regs, const char *file,
+	const char *func, unsigned long line)
+{
+	console_verbose();
+	printk("%s", str);
+	if (file && func)
+		printk(" in %s:%s, line %ld", file, func, line);
+	printk(":\n");
+	show_registers(regs);
+	do_exit(SIGSEGV);
+}
+
+void __die_if_kernel(const char *str, struct pt_regs *regs,
+		const char *file, const char *func, unsigned long line)
+{
+	if (!user_mode(regs))
+		__die(str, regs, file, func, line);
+}
+
+asmlinkage void do_adelinsn(struct pt_regs *regs)
+{
+	printk("do_ADE-linsn:ema:0x%08lx:epc:0x%08lx\n",
+		 regs->cp0_ema, regs->cp0_epc);
+	die_if_kernel("do_ade execution Exception\n", regs);
+	force_sig(SIGBUS, current);
+}
+
+asmlinkage void do_adedata(struct pt_regs *regs)
+{
+	const struct exception_table_entry *fixup;
+	fixup = search_exception_tables(regs->cp0_epc);
+	if (fixup) {
+		regs->cp0_epc = fixup->fixup;
+		return;
+	}
+	printk("do_ADE-data:ema:0x%08lx:epc:0x%08lx\n",
+		 regs->cp0_ema, regs->cp0_epc);
+	die_if_kernel("do_ade execution Exception\n", regs);
+	force_sig(SIGBUS, current);
+}
+
+asmlinkage void do_pel(struct pt_regs *regs)
+{
+	die_if_kernel("do_pel execution Exception", regs);
+	force_sig(SIGFPE, current);
+}
+
+asmlinkage void do_cee(struct pt_regs *regs)
+{
+	die_if_kernel("do_cee execution Exception", regs);
+	force_sig(SIGFPE, current);
+}
+
+asmlinkage void do_cpe(struct pt_regs *regs)
+{
+	die_if_kernel("do_cpe execution Exception", regs);
+	force_sig(SIGFPE, current);
+}
+
+asmlinkage void do_be(struct pt_regs *regs)
+{
+	die_if_kernel("do_be execution Exception", regs);
+	force_sig(SIGBUS, current);
+}
+
+asmlinkage void do_ov(struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	die_if_kernel("do_ov execution Exception", regs);
+
+	info.si_code = FPE_INTOVF;
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *)regs->cp0_epc;
+	force_sig_info(SIGFPE, &info, current);
+}
+
+asmlinkage void do_tr(struct pt_regs *regs)
+{
+	die_if_kernel("do_tr execution Exception", regs);
+	force_sig(SIGTRAP, current);
+}
+
+asmlinkage void do_ri(struct pt_regs *regs)
+{
+	unsigned long epc_insn;
+	unsigned long epc = regs->cp0_epc;
+
+	read_tsk_long(current, epc, &epc_insn);
+	if (current->thread.single_step == 1) {
+		if ((epc == current->thread.addr1) ||
+		    (epc == current->thread.addr2)) {
+			user_disable_single_step(current);
+			force_sig(SIGTRAP, current);
+			return;
+		} else
+			BUG();
+	} else if ((epc_insn == BREAKPOINT32_INSN) ||
+		   ((epc_insn & 0x0000FFFF) == 0x7002) ||
+		   ((epc_insn & 0xFFFF0000) == 0x70020000)) {
+			force_sig(SIGTRAP, current);
+			return;
+	} else {
+		die_if_kernel("do_ri execution Exception", regs);
+		force_sig(SIGILL, current);
+	}
+}
+
+asmlinkage void do_ccu(struct pt_regs *regs)
+{
+	die_if_kernel("do_ccu execution Exception", regs);
+	force_sig(SIGILL, current);
+}
+
+asmlinkage void do_reserved(struct pt_regs *regs)
+{
+	/*
+	 * Game over - no way to handle this if it ever occurs.  Most probably
+	 * caused by a new unknown cpu type or after another deadly
+	 * hard/software error.
+	 */
+	die_if_kernel("do_reserved execution Exception", regs);
+	show_regs(regs);
+	panic("Caught reserved exception - should not happen.");
+}
+
+/*
+ * NMI exception handler.
+ */
+void nmi_exception_handler(struct pt_regs *regs)
+{
+	die_if_kernel("nmi_exception_handler execution Exception", regs);
+	die("NMI", regs);
+}
+
+/* Install CPU exception handler */
+void *set_except_vector(int n, void *addr)
+{
+	unsigned long handler = (unsigned long) addr;
+	unsigned long old_handler = exception_handlers[n];
+
+	exception_handlers[n] = handler;
+	return (void *)old_handler;
+}
+
+void __init trap_init(void)
+{
+	int i;
+
+	pgd_current = (unsigned long)init_mm.pgd;
+	/* DEBUG EXCEPTION */
+	memcpy((void *)DEBUG_VECTOR_BASE_ADDR,
+			&debug_exception_vector, DEBUG_VECTOR_SIZE);
+	/* NMI EXCEPTION */
+	memcpy((void *)GENERAL_VECTOR_BASE_ADDR,
+			&general_exception_vector, GENERAL_VECTOR_SIZE);
+
+	/*
+	 * Initialise exception handlers
+	 */
+	for (i = 0; i <= 31; i++)
+		set_except_vector(i, handle_reserved);
+
+	set_except_vector(1, handle_nmi);
+	set_except_vector(2, handle_adelinsn);
+	set_except_vector(3, handle_tlb_refill);
+	set_except_vector(4, handle_tlb_invaild);
+	set_except_vector(5, handle_ibe);
+	set_except_vector(6, handle_pel);
+	set_except_vector(7, handle_sys);
+	set_except_vector(8, handle_ccu);
+	set_except_vector(9, handle_ri);
+	set_except_vector(10, handle_tr);
+	set_except_vector(11, handle_adedata);
+	set_except_vector(12, handle_adedata);
+	set_except_vector(13, handle_tlb_refill);
+	set_except_vector(14, handle_tlb_invaild);
+	set_except_vector(15, handle_mod);
+	set_except_vector(16, handle_cee);
+	set_except_vector(17, handle_cpe);
+	set_except_vector(18, handle_dbe);
+	flush_icache_range(DEBUG_VECTOR_BASE_ADDR, IRQ_VECTOR_BASE_ADDR);
+
+	atomic_inc(&init_mm.mm_count);
+	current->active_mm = &init_mm;
+	cpu_cache_init();
+}
diff --git a/arch/score/kernel/vmlinux.lds.S b/arch/score/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..f855698
--- /dev/null
+++ b/arch/score/kernel/vmlinux.lds.S
@@ -0,0 +1,148 @@
+/*
+ * arch/score/kernel/vmlinux.lds.S
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+
+OUTPUT_ARCH(score)
+ENTRY(_stext)
+
+jiffies = jiffies_64;
+
+SECTIONS
+{
+	. = CONFIG_MEMORY_START + 0x2000;
+	/* read-only */
+	.text : {
+		_text = .;	/* Text and read-only data */
+		TEXT_TEXT
+		SCHED_TEXT
+		LOCK_TEXT
+		KPROBES_TEXT
+		*(.text.*)
+		*(.fixup)
+		. = ALIGN (4) ;
+		_etext = .;	/* End of text section */
+	}
+
+	. = ALIGN(16);
+	RODATA
+
+	/* Exception table */
+	. = ALIGN(16);
+	__ex_table : {
+		__start___ex_table = .;
+		*(__ex_table)
+		__stop___ex_table = .;
+	}
+
+	/* writeable */
+	.data ALIGN (4096): {
+		*(.data.init_task)
+
+		DATA_DATA
+		CONSTRUCTORS
+	}
+
+	/* We want the small data sections together, so single-instruction offsets
+	   can access them all, and initialized data all before uninitialized, so
+	   we can shorten the on-disk segment size.  */
+	. = ALIGN(8);
+	.sdata : {
+		*(.sdata)
+	}
+
+	. = ALIGN(32);
+	.data.cacheline_aligned : {
+		*(.data.cacheline_aligned)
+	}
+	_edata =  .;			/* End of data section */
+
+	/* will be freed after init */
+	. = ALIGN(4096);		/* Init code and data */
+	__init_begin = .;
+
+	. = ALIGN(4096);
+	.init.text : {
+		_sinittext = .;
+		INIT_TEXT
+		_einittext = .;
+	}
+	.init.data : {
+		INIT_DATA
+	}
+	. = ALIGN(16);
+	.init.setup : {
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+	}
+
+	.initcall.init : {
+		__initcall_start = .;
+		INITCALLS
+		__initcall_end = .;
+	}
+
+	.con_initcall.init : {
+		__con_initcall_start = .;
+		*(.con_initcall.init)
+		__con_initcall_end = .;
+	}
+	SECURITY_INIT
+
+	/* .exit.text is discarded at runtime, not link time, to deal with
+	 * references from .rodata
+	 */
+	.exit.text : {
+		EXIT_TEXT
+	}
+	.exit.data : {
+		EXIT_DATA
+	}
+#if defined(CONFIG_BLK_DEV_INITRD)
+	.init.ramfs ALIGN(4096): {
+		__initramfs_start = .;
+		*(.init.ramfs)
+		__initramfs_end = .;
+		. = ALIGN(4);
+		LONG(0);
+	}
+#endif
+	. = ALIGN(4096);
+	__init_end = .;
+	/* freed after init ends here */
+
+	__bss_start = .;	/* BSS */
+	.sbss  : {
+		*(.sbss)
+		*(.scommon)
+	}
+	.bss : {
+		*(.bss)
+		*(COMMON)
+	}
+	__bss_stop = .;
+	_end = .;
+}
diff --git a/arch/score/lib/Makefile b/arch/score/lib/Makefile
new file mode 100644
index 0000000..553e30e
--- /dev/null
+++ b/arch/score/lib/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for SCORE-specific library files..
+#
+
+lib-y += string.o checksum.o checksum_copy.o
+
+# libgcc-style stuff needed in the kernel
+obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/score/lib/ashldi3.c b/arch/score/lib/ashldi3.c
new file mode 100644
index 0000000..15691a9
--- /dev/null
+++ b/arch/score/lib/ashldi3.c
@@ -0,0 +1,46 @@
+/*
+ * arch/score/lib/ashldi3.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include "libgcc.h"
+
+long long __ashldi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.low = 0;
+		w.s.high = (unsigned int) uu.s.low << -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.low >> bm;
+
+		w.s.low = (unsigned int) uu.s.low << b;
+		w.s.high = ((unsigned int) uu.s.high << b) | carries;
+	}
+
+	return w.ll;
+}
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/score/lib/ashrdi3.c b/arch/score/lib/ashrdi3.c
new file mode 100644
index 0000000..d9814a5
--- /dev/null
+++ b/arch/score/lib/ashrdi3.c
@@ -0,0 +1,48 @@
+/*
+ * arch/score/lib/ashrdi3.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include "libgcc.h"
+
+long long __ashrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		/* w.s.high = 1..1 or 0..0 */
+		w.s.high =
+		    uu.s.high >> 31;
+		w.s.low = uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/score/lib/checksum.S b/arch/score/lib/checksum.S
new file mode 100644
index 0000000..706157e
--- /dev/null
+++ b/arch/score/lib/checksum.S
@@ -0,0 +1,255 @@
+/*
+ * arch/score/lib/csum_partial.S
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/linkage.h>
+
+#define ADDC(sum,reg)			\
+	add	sum, sum, reg;		\
+	cmp.c	reg, sum;		\
+	bleu	9f;			\
+	addi	sum, 0x1;		\
+9:
+
+#define CSUM_BIGCHUNK(src, offset, sum)		\
+	lw	r8, [src, offset + 0x00];	\
+	lw	r9, [src, offset + 0x04];	\
+	lw	r10, [src, offset + 0x08];	\
+	lw	r11, [src, offset + 0x0c];	\
+	ADDC(sum, r8);				\
+	ADDC(sum, r9);				\
+	ADDC(sum, r10);				\
+	ADDC(sum, r11);				\
+	lw	r8, [src, offset + 0x10];	\
+	lw	r9, [src, offset + 0x14];	\
+	lw	r10, [src, offset + 0x18]; 	\
+	lw	r11, [src, offset + 0x1c]; 	\
+	ADDC(sum, r8);				\
+	ADDC(sum, r9);				\
+	ADDC(sum, r10);				\
+	ADDC(sum, r11);				\
+
+#define src r4
+#define dest r5
+#define sum r27
+
+	.text
+/* unknown src alignment and < 8 bytes to go */
+small_csumcpy:
+	mv	r5, r10
+	ldi	r9, 0x0
+	cmpi.c	r25, 0x1
+	beq pass_small_set_t7	/*already set, jump to pass_small_set_t7*/
+	andri.c	r25,r4 , 0x1	/*Is src 2 bytes aligned?*/
+
+pass_small_set_t7:
+	beq	aligned
+	cmpi.c	r5, 0x0
+	beq	fold
+	lbu	r9, [src]
+	slli	r9,r9, 0x8	/*Little endian*/
+	ADDC(sum, r9)
+	addi	src, 0x1
+	subi.c	r5, 0x1
+
+	/*len still a full word */
+aligned:
+	andri.c r8, r5, 0x4	/*Len >= 4?*/
+	beq	len_less_4bytes
+
+	/* Still a full word (4byte) to go,and the src is word aligned.*/
+	andri.c	r8, src, 0x3	/*src is 4bytes aligned, so use LW!!*/
+	beq	four_byte_aligned
+	lhu 	r9, [src]
+	addi	src, 2
+	ADDC(sum, r9)
+	lhu 	r9, [src]
+	addi	src, 2
+	ADDC(sum, r9)
+	b len_less_4bytes
+
+four_byte_aligned:		/* Len >=4 and four byte aligned */
+	lw	r9, [src]
+	addi	src, 4
+	ADDC(sum, r9)
+
+len_less_4bytes:		/* 2 byte aligned aligned and length<4B */
+	andri.c r8, r5, 0x2
+	beq	len_less_2bytes
+	lhu	r9, [src]
+	addi	src, 0x2	/* src+=2 */
+	ADDC(sum, r9)
+
+len_less_2bytes:		/* len = 1 */
+	andri.c r8, r5, 0x1
+	beq 	fold		/* less than 2 and not equal 1--> len=0 -> fold */
+	lbu	r9, [src]
+
+fold_ADDC:
+	ADDC(sum, r9)
+fold:
+	/* fold checksum */
+	slli	r26, sum, 16
+	add	sum, sum, r26
+	cmp.c	r26, sum
+	srli	sum, sum, 16
+	bleu 	1f 		/* if r26<=sum */
+	addi	sum, 0x1 	/* r26>sum */
+1:
+	/* odd buffer alignment? r25 was set in csum_partial */
+	cmpi.c	r25, 0x0
+	beq	1f
+	slli	r26, sum, 8
+	srli	sum, sum, 8
+	or	sum, sum, r26
+	andi	sum, 0xffff
+1:
+	.set	optimize
+	/* Add the passed partial csum. */
+	ADDC(sum, r6)
+	mv	r4, sum
+	br	r3
+	.set	volatile
+
+	.align	5
+ENTRY(csum_partial)
+	ldi sum, 0
+	ldi r25, 0
+	mv r10, r5
+	cmpi.c	r5, 0x8
+	blt	small_csumcpy		/* < 8(singed) bytes to copy */
+	cmpi.c	r5, 0x0
+	beq	out
+	andri.c	r25, src, 0x1		/* odd buffer? */
+
+	beq	word_align
+hword_align:				/* 1 byte */
+	lbu	r8, [src]
+	subi	r5, 0x1
+	slli	r8, r8, 8
+	ADDC(sum, r8)
+	addi	src, 0x1
+
+word_align:				/* 2 bytes */
+	andri.c r8, src, 0x2		/* 4bytes(dword)_aligned? */
+	beq	dword_align		/* not, maybe dword_align */
+	lhu	r8, [src]
+	subi	r5, 0x2
+	ADDC(sum, r8)
+	addi	src, 0x2
+
+dword_align:				/* 4bytes */
+	mv 	r26, r5			/* maybe useless when len >=56 */
+	ldi 	r8, 56
+	cmp.c	r8, r5
+	bgtu	do_end_words		/* if a1(len)<t0(56) ,unsigned */
+	andri.c	r26, src, 0x4
+	beq	qword_align
+	lw	r8, [src]
+	subi	r5, 0x4
+	ADDC(sum, r8)
+	addi	src, 0x4
+
+qword_align:				/* 8 bytes */
+	andri.c r26, src, 0x8
+	beq	oword_align
+	lw	r8, [src, 0x0]
+	lw	r9, [src, 0x4]
+	subi	r5, 0x8			/* len-=0x8 */
+	ADDC(sum, r8)
+	ADDC(sum, r9)
+	addi	src, 0x8
+
+oword_align:				/* 16bytes */
+	andri.c	r26, src, 0x10
+	beq	begin_movement
+	lw	r10, [src, 0x08]
+	lw	r11, [src, 0x0c]
+	lw	r8, [src, 0x00]
+	lw	r9, [src, 0x04]
+	ADDC(sum, r10)
+	ADDC(sum, r11)
+	ADDC(sum, r8)
+	ADDC(sum, r9)
+	subi	r5, 0x10
+	addi	src, 0x10
+
+begin_movement:
+	srli.c	r26, r5, 0x7		/* len>=128? */
+	beq	1f			/* len<128 */
+
+/* r26 is the result that computed in oword_align */
+move_128bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum)
+	CSUM_BIGCHUNK(src, 0x20, sum)
+	CSUM_BIGCHUNK(src, 0x40, sum)
+	CSUM_BIGCHUNK(src, 0x60, sum)
+	subi.c	r26, 0x01		/* r26 equals len/128 */
+	addi	src, 0x80
+	bne	move_128bytes
+
+1:	/* len<128,we process 64byte here */
+	andri.c	r10, r5, 0x40
+	beq	1f
+
+move_64bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum)
+	CSUM_BIGCHUNK(src, 0x20, sum)
+	addi	src, 0x40
+
+1:					/* len<64 */
+	andri	r26, r5, 0x1c		/* 0x1c=28 */
+	andri.c	r10, r5, 0x20
+	beq	do_end_words		/* decided by andri */
+
+move_32bytes:
+	CSUM_BIGCHUNK(src, 0x00, sum)
+	andri	r26, r5, 0x1c
+	addri	src, src, 0x20
+
+do_end_words:				/* len<32 */
+	/* r26 was set already in dword_align */
+	cmpi.c	r26, 0x0
+	beq	maybe_end_cruft		/* len<28 or len<56 */
+	srli	r26, r26, 0x2
+
+end_words:
+	lw	r8, [src]
+	subi.c	r26, 0x1		/* unit is 4 byte */
+	ADDC(sum, r8)
+	addi	src, 0x4
+	cmpi.c	r26, 0x0
+	bne	end_words		/* r26!=0 */
+
+maybe_end_cruft:			/* len<4 */
+	andri	r10, r5, 0x3
+
+small_memcpy:
+	mv	r5, r10
+	j	small_csumcpy
+
+out:
+	mv	r4, sum
+	br	r3
+
+END(csum_partial)
diff --git a/arch/score/lib/checksum_copy.c b/arch/score/lib/checksum_copy.c
new file mode 100644
index 0000000..04565dd
--- /dev/null
+++ b/arch/score/lib/checksum_copy.c
@@ -0,0 +1,52 @@
+/*
+ * arch/score/lib/csum_partial_copy.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <net/checksum.h>
+
+#include <asm/uaccess.h>
+
+unsigned int csum_partial_copy(const char *src, char *dst,
+				int len, unsigned int sum)
+{
+	sum = csum_partial(src, len, sum);
+	memcpy(dst, src, len);
+
+	return sum;
+}
+
+unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+					int len, unsigned int sum,
+					int *err_ptr)
+{
+	int missing;
+
+	missing = copy_from_user(dst, src, len);
+	if (missing) {
+		memset(dst + len - missing, 0, missing);
+		*err_ptr = -EFAULT;
+	}
+
+	return csum_partial(dst, len, sum);
+}
diff --git a/arch/score/lib/cmpdi2.c b/arch/score/lib/cmpdi2.c
new file mode 100644
index 0000000..1ed5290
--- /dev/null
+++ b/arch/score/lib/cmpdi2.c
@@ -0,0 +1,44 @@
+/*
+ * arch/score/lib/cmpdi2.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include "libgcc.h"
+
+word_type __cmpdi2(long long a, long long b)
+{
+	const DWunion au = {
+		.ll = a
+	};
+	const DWunion bu = {
+		.ll = b
+	};
+
+	if (au.s.high < bu.s.high)
+		return 0;
+	else if (au.s.high > bu.s.high)
+		return 2;
+
+	if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
+		return 0;
+	else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
+		return 2;
+
+	return 1;
+}
+EXPORT_SYMBOL(__cmpdi2);
diff --git a/arch/score/lib/libgcc.h b/arch/score/lib/libgcc.h
new file mode 100644
index 0000000..0f12543
--- /dev/null
+++ b/arch/score/lib/libgcc.h
@@ -0,0 +1,37 @@
+/*
+ * arch/score/lib/libgcc.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#ifndef __ASM_LIBGCC_H
+#define __ASM_LIBGCC_H
+
+#include <asm/byteorder.h>
+
+typedef int word_type __attribute__((mode(__word__)));
+
+struct DWstruct {
+	int low, high;
+};
+
+typedef union {
+	struct DWstruct s;
+	long long ll;
+} DWunion;
+
+#endif /* __ASM_LIBGCC_H */
diff --git a/arch/score/lib/lshrdi3.c b/arch/score/lib/lshrdi3.c
new file mode 100644
index 0000000..ce21175
--- /dev/null
+++ b/arch/score/lib/lshrdi3.c
@@ -0,0 +1,47 @@
+/*
+ * arch/score/lib/lshrdi3.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include <linux/module.h>
+#include "libgcc.h"
+
+long long __lshrdi3(long long u, word_type b)
+{
+	DWunion uu, w;
+	word_type bm;
+
+	if (b == 0)
+		return u;
+
+	uu.ll = u;
+	bm = 32 - b;
+
+	if (bm <= 0) {
+		w.s.high = 0;
+		w.s.low = (unsigned int) uu.s.high >> -bm;
+	} else {
+		const unsigned int carries = (unsigned int) uu.s.high << bm;
+
+		w.s.high = (unsigned int) uu.s.high >> b;
+		w.s.low = ((unsigned int) uu.s.low >> b) | carries;
+	}
+
+	return w.ll;
+}
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/score/lib/string.S b/arch/score/lib/string.S
new file mode 100644
index 0000000..00b7d3a
--- /dev/null
+++ b/arch/score/lib/string.S
@@ -0,0 +1,184 @@
+/*
+ * arch/score/lib/string.S
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/linkage.h>
+#include <asm-generic/errno.h>
+
+	.text
+	.align 2
+ENTRY(__strncpy_from_user)
+	cmpi.c	r6, 0
+	mv	r9, r6
+	ble	.L2
+0:	lbu	r7, [r5]
+	ldi	r8, 0
+1:	sb	r7, [r4]
+2:	lb	r6, [r5]
+	cmp.c	r6, r8
+	beq	.L2
+
+.L5:
+	addi	r8, 1
+	cmp.c	r8, r9
+	beq	.L7
+3:	lbu	r6, [r5, 1]+
+4:	sb	r6, [r4, 1]+
+5:	lb	r7, [r5]
+	cmpi.c	r7, 0
+	bne	.L5
+.L7:
+	mv	r4, r8
+	br	r3
+.L2:
+	ldi	r8, 0
+	mv	r4, r8
+	br	r3
+	.section .fixup, "ax"
+99:
+	ldi	r4, -EFAULT
+	br	r3
+	.previous
+	.section __ex_table, "a"
+	.align	2
+	.word	0b ,99b
+	.word	1b ,99b
+	.word	2b ,99b
+	.word	3b ,99b
+	.word	4b ,99b
+	.word	5b ,99b
+	.previous
+
+	.align 2
+ENTRY(__strnlen_user)
+	cmpi.c	r5, 0
+	ble	.L11
+0:	lb	r6, [r4]
+	ldi	r7, 0
+	cmp.c	r6, r7
+	beq	.L11
+.L15:
+	addi	r7, 1
+	cmp.c	r7, r5
+	beq	.L23
+1:	lb	r6, [r4,1]+
+	cmpi.c	r6, 0
+	bne	.L15
+.L23:
+	addri	r4, r7, 1
+	br	r3
+
+.L11:
+	ldi	r4, 1
+	br	r3
+	.section .fixup, "ax"
+99:
+	ldi	r4, 0
+	br	r3
+
+	.section __ex_table,"a"
+	.align 2
+	.word	0b, 99b
+	.word	1b, 99b
+	.previous
+
+	.align 2
+ENTRY(__strlen_user)
+0:	lb	r6, [r4]
+	mv	r7, r4
+	extsb	r6, r6
+	cmpi.c	r6, 0
+	mv	r4, r6
+	beq	.L27
+.L28:
+1:	lb	r6, [r7, 1]+
+	addi	r6, 1
+	cmpi.c	r6, 0
+	bne	.L28
+.L27:
+	br	r3
+	.section .fixup, "ax"
+	ldi	r4, 0x0
+	br	r3
+99:
+	ldi	r4, 0
+	br	r3
+	.previous
+	.section __ex_table, "a"
+	.align	2
+	.word	0b ,99b
+	.word	1b ,99b
+	.previous
+
+	.align 2
+ENTRY(__copy_tofrom_user)
+	cmpi.c	r6, 0
+	mv	r10,r6
+	beq	.L32
+	ldi	r9, 0
+.L34:
+	add	r6, r5, r9
+0:	lbu	r8, [r6]
+	add	r7, r4, r9
+1:	sb	r8, [r7]
+	addi	r9, 1
+	cmp.c	r9, r10
+	bne	.L34
+.L32:
+	ldi	r4, 0
+	br	r3
+	.section .fixup, "ax"
+99:
+	sub	r4, r10, r9
+	br	r3
+	.previous
+	.section __ex_table, "a"
+	.align	2
+	.word	0b, 99b
+	.word	1b, 99b
+	.previous
+
+	.align 2
+ENTRY(__clear_user)
+	cmpi.c	r5, 0
+	beq	.L38
+	ldi	r6, 0
+	mv	r7, r6
+.L40:
+	addi	r6, 1
+0:	sb	r7, [r4]+, 1
+	cmp.c	r6, r5
+	bne	.L40
+.L38:
+	ldi	r4, 0
+	br	r3
+
+	.section .fixup, "ax"
+	br	r3
+	.previous
+	.section __ex_table, "a"
+	.align	2
+99:
+	.word	0b, 99b
+	.previous
diff --git a/arch/score/lib/ucmpdi2.c b/arch/score/lib/ucmpdi2.c
new file mode 100644
index 0000000..b15241e
--- /dev/null
+++ b/arch/score/lib/ucmpdi2.c
@@ -0,0 +1,38 @@
+/*
+ * arch/score/lib/ucmpdi2.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+#include "libgcc.h"
+
+word_type __ucmpdi2(unsigned long long a, unsigned long long b)
+{
+	const DWunion au = {.ll = a};
+	const DWunion bu = {.ll = b};
+
+	if ((unsigned int) au.s.high < (unsigned int) bu.s.high)
+		return 0;
+	else if ((unsigned int) au.s.high > (unsigned int) bu.s.high)
+		return 2;
+	if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
+		return 0;
+	else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
+		return 2;
+	return 1;
+}
+EXPORT_SYMBOL(__ucmpdi2);
diff --git a/arch/score/mm/Makefile b/arch/score/mm/Makefile
new file mode 100644
index 0000000..7b1e29b
--- /dev/null
+++ b/arch/score/mm/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the Linux/SCORE-specific parts of the memory manager.
+#
+
+obj-y += cache.o extable.o fault.o init.o \
+	tlb-miss.o tlb-score.o pgtable.o
diff --git a/arch/score/mm/cache.c b/arch/score/mm/cache.c
new file mode 100644
index 0000000..dbac9d9
--- /dev/null
+++ b/arch/score/mm/cache.c
@@ -0,0 +1,257 @@
+/*
+ * arch/score/mm/cache.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+
+#include <asm/mmu_context.h>
+
+/*
+Just flush entire Dcache!!
+You must ensure the page doesn't include instructions, because
+the function will not flush the Icache.
+The addr must be cache aligned.
+*/
+static void flush_data_cache_page(unsigned long addr)
+{
+	unsigned int i;
+	for (i = 0; i < (PAGE_SIZE / L1_CACHE_BYTES); i += L1_CACHE_BYTES) {
+		__asm__ __volatile__(
+		"cache 0x0e, [%0, 0]\n"
+		"cache 0x1a, [%0, 0]\n"
+		"nop\n"
+		: : "r" (addr));
+		addr += L1_CACHE_BYTES;
+	}
+}
+
+/* called by update_mmu_cache. */
+void __update_cache(struct vm_area_struct *vma, unsigned long address,
+		pte_t pte)
+{
+	struct page *page;
+	unsigned long pfn, addr;
+	int exec = (vma->vm_flags & VM_EXEC);
+
+	pfn = pte_pfn(pte);
+	if (unlikely(!pfn_valid(pfn)))
+		return;
+	page = pfn_to_page(pfn);
+	if (page_mapping(page) && test_bit(PG_arch_1, &page->flags)) {
+		addr = (unsigned long) page_address(page);
+		if (exec)
+			flush_data_cache_page(addr);
+		clear_bit(PG_arch_1, &page->flags);
+	}
+}
+
+static inline void setup_protection_map(void)
+{
+	protection_map[0] = PAGE_NONE;
+	protection_map[1] = PAGE_READONLY;
+	protection_map[2] = PAGE_COPY;
+	protection_map[3] = PAGE_COPY;
+	protection_map[4] = PAGE_READONLY;
+	protection_map[5] = PAGE_READONLY;
+	protection_map[6] = PAGE_COPY;
+	protection_map[7] = PAGE_COPY;
+	protection_map[8] = PAGE_NONE;
+	protection_map[9] = PAGE_READONLY;
+	protection_map[10] = PAGE_SHARED;
+	protection_map[11] = PAGE_SHARED;
+	protection_map[12] = PAGE_READONLY;
+	protection_map[13] = PAGE_READONLY;
+	protection_map[14] = PAGE_SHARED;
+	protection_map[15] = PAGE_SHARED;
+}
+
+void __devinit cpu_cache_init(void)
+{
+	setup_protection_map();
+}
+
+void flush_icache_all(void)
+{
+	__asm__ __volatile__(
+	"la r8, flush_icache_all\n"
+	"cache 0x10, [r8, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\nnop\n"
+	: : : "r8");
+}
+
+void flush_dcache_all(void)
+{
+	__asm__ __volatile__(
+	"la r8, flush_dcache_all\n"
+	"cache 0x1f, [r8, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\nnop\n"
+	"cache 0x1a, [r8, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\nnop\n"
+	: : : "r8");
+}
+
+void flush_cache_all(void)
+{
+	__asm__ __volatile__(
+	"la r8, flush_cache_all\n"
+	"cache 0x10, [r8, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\nnop\n"
+	"cache 0x1f, [r8, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\nnop\n"
+	"cache 0x1a, [r8, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\nnop\n"
+	: : : "r8");
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+	if (!(mm->context))
+		return;
+	flush_cache_all();
+}
+
+/*if we flush a range precisely , the processing may be very long.
+We must check each page in the range whether present. If the page is present,
+we can flush the range in the page. Be careful, the range may be cross two
+page, a page is present and another is not present.
+*/
+/*
+The interface is provided in hopes that the port can find
+a suitably efficient method for removing multiple page
+sized regions from the cache.
+*/
+void flush_cache_range(struct vm_area_struct *vma,
+		unsigned long start, unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	int exec = vma->vm_flags & VM_EXEC;
+	pgd_t *pgdp;
+	pud_t *pudp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	if (!(mm->context))
+		return;
+
+	pgdp = pgd_offset(mm, start);
+	pudp = pud_offset(pgdp, start);
+	pmdp = pmd_offset(pudp, start);
+	ptep = pte_offset(pmdp, start);
+
+	while (start <= end) {
+		unsigned long tmpend;
+		pgdp = pgd_offset(mm, start);
+		pudp = pud_offset(pgdp, start);
+		pmdp = pmd_offset(pudp, start);
+		ptep = pte_offset(pmdp, start);
+
+		if (!(pte_val(*ptep) & _PAGE_PRESENT)) {
+			start = (start + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+			continue;
+		}
+		tmpend = (start | (PAGE_SIZE-1)) > end ?
+				 end : (start | (PAGE_SIZE-1));
+
+		flush_dcache_range(start, tmpend);
+		if (exec)
+			flush_icache_range(start, tmpend);
+		start = (start + PAGE_SIZE) & ~(PAGE_SIZE - 1);
+	}
+}
+
+void flush_cache_page(struct vm_area_struct *vma,
+		unsigned long addr, unsigned long pfn)
+{
+	int exec = vma->vm_flags & VM_EXEC;
+	unsigned long kaddr = 0xa0000000 | (pfn << PAGE_SHIFT);
+
+	flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
+
+	if (exec)
+		flush_icache_range(kaddr, kaddr + PAGE_SIZE);
+}
+
+void flush_cache_sigtramp(unsigned long addr)
+{
+	__asm__ __volatile__(
+	"cache 0x02, [%0, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\n"
+	"cache 0x02, [%0, 0x4]\n"
+	"nop\nnop\nnop\nnop\nnop\n"
+
+	"cache 0x0d, [%0, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\n"
+	"cache 0x0d, [%0, 0x4]\n"
+	"nop\nnop\nnop\nnop\nnop\n"
+
+	"cache 0x1a, [%0, 0]\n"
+	"nop\nnop\nnop\nnop\nnop\n"
+	: : "r" (addr));
+}
+
+/*
+1. WB and invalid a cache line of Dcache
+2. Drain Write Buffer
+the range must be smaller than PAGE_SIZE
+*/
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+	int size, i;
+
+	start = start & ~(L1_CACHE_BYTES - 1);
+	end = end & ~(L1_CACHE_BYTES - 1);
+	size = end - start;
+	/* flush dcache to ram, and invalidate dcache lines. */
+	for (i = 0; i < size; i += L1_CACHE_BYTES) {
+		__asm__ __volatile__(
+		"cache 0x0e, [%0, 0]\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+		"cache 0x1a, [%0, 0]\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+		: : "r" (start));
+		start += L1_CACHE_BYTES;
+	}
+}
+
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+	int size, i;
+	start = start & ~(L1_CACHE_BYTES - 1);
+	end = end & ~(L1_CACHE_BYTES - 1);
+
+	size = end - start;
+	/* invalidate icache lines. */
+	for (i = 0; i < size; i += L1_CACHE_BYTES) {
+		__asm__ __volatile__(
+		"cache 0x02, [%0, 0]\n"
+		"nop\nnop\nnop\nnop\nnop\n"
+		: : "r" (start));
+		start += L1_CACHE_BYTES;
+	}
+}
diff --git a/arch/score/mm/extable.c b/arch/score/mm/extable.c
new file mode 100644
index 0000000..01ff644
--- /dev/null
+++ b/arch/score/mm/extable.c
@@ -0,0 +1,38 @@
+/*
+ * arch/score/mm/extable.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/module.h>
+
+int fixup_exception(struct pt_regs *regs)
+{
+	const struct exception_table_entry *fixup;
+
+	fixup = search_exception_tables(regs->cp0_epc);
+	if (fixup) {
+		regs->cp0_epc = fixup->fixup;
+		return 1;
+	}
+	return 0;
+}
diff --git a/arch/score/mm/fault.c b/arch/score/mm/fault.c
new file mode 100644
index 0000000..47b600e
--- /dev/null
+++ b/arch/score/mm/fault.c
@@ -0,0 +1,235 @@
+/*
+ * arch/score/mm/fault.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+				unsigned long address)
+{
+	struct vm_area_struct *vma = NULL;
+	struct task_struct *tsk = current;
+	struct mm_struct *mm = tsk->mm;
+	const int field = sizeof(unsigned long) * 2;
+	siginfo_t info;
+	int fault;
+
+	info.si_code = SEGV_MAPERR;
+
+	/*
+	* We fault-in kernel-space virtual memory on-demand. The
+	* 'reference' page table is init_mm.pgd.
+	*
+	* NOTE! We MUST NOT take any locks for this case. We may
+	* be in an interrupt or a critical region, and should
+	* only copy the information from the master page table,
+	* nothing more.
+	*/
+	if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
+		goto vmalloc_fault;
+#ifdef MODULE_START
+	if (unlikely(address >= MODULE_START && address < MODULE_END))
+		goto vmalloc_fault;
+#endif
+
+	/*
+	* If we're in an interrupt or have no user
+	* context, we must not take the fault..
+	*/
+	if (in_atomic() || !mm)
+		goto bad_area_nosemaphore;
+
+	down_read(&mm->mmap_sem);
+	vma = find_vma(mm, address);
+	if (!vma)
+		goto bad_area;
+	if (vma->vm_start <= address)
+		goto good_area;
+	if (!(vma->vm_flags & VM_GROWSDOWN))
+		goto bad_area;
+	if (expand_stack(vma, address))
+		goto bad_area;
+	/*
+	* Ok, we have a good vm_area for this memory access, so
+	* we can handle it..
+	 */
+good_area:
+	info.si_code = SEGV_ACCERR;
+
+	if (write) {
+		if (!(vma->vm_flags & VM_WRITE))
+			goto bad_area;
+	} else {
+		if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
+			goto bad_area;
+	}
+
+survive:
+	/*
+	* If for any reason at all we couldn't handle the fault,
+	* make sure we exit gracefully rather than endlessly redo
+	* the fault.
+	*/
+	fault = handle_mm_fault(mm, vma, address, write);
+	if (unlikely(fault & VM_FAULT_ERROR)) {
+		if (fault & VM_FAULT_OOM)
+			goto out_of_memory;
+		else if (fault & VM_FAULT_SIGBUS)
+			goto do_sigbus;
+		BUG();
+	}
+	if (fault & VM_FAULT_MAJOR)
+		tsk->maj_flt++;
+	else
+		tsk->min_flt++;
+
+	up_read(&mm->mmap_sem);
+	return;
+
+	/*
+	* Something tried to access memory that isn't in our memory map..
+	* Fix it, but check if it's kernel or user first..
+	 */
+bad_area:
+	up_read(&mm->mmap_sem);
+
+bad_area_nosemaphore:
+	/* User mode accesses just cause a SIGSEGV */
+	if (user_mode(regs)) {
+		tsk->thread.cp0_badvaddr = address;
+		tsk->thread.error_code = write;
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		/* info.si_code has been set above */
+		info.si_addr = (void __user *) address;
+		force_sig_info(SIGSEGV, &info, tsk);
+		return;
+	}
+
+no_context:
+	/* Are we prepared to handle this kernel fault? */
+	if (fixup_exception(regs)) {
+		current->thread.cp0_baduaddr = address;
+		return;
+	}
+
+	/*
+	* Oops. The kernel tried to access some bad page. We'll have to
+	* terminate things with extreme prejudice.
+	*/
+	bust_spinlocks(1);
+
+	printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
+			"virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
+			0, field, address, field, regs->cp0_epc,
+			field, regs->regs[3]);
+	die("Oops", regs);
+
+	/*
+	* We ran out of memory, or some other thing happened to us that made
+	* us unable to handle the page fault gracefully.
+	*/
+out_of_memory:
+	up_read(&mm->mmap_sem);
+	if (is_global_init(tsk)) {
+		yield();
+		down_read(&mm->mmap_sem);
+		goto survive;
+	}
+	printk("VM: killing process %s\n", tsk->comm);
+	if (user_mode(regs))
+		do_group_exit(SIGKILL);
+	goto no_context;
+
+do_sigbus:
+	up_read(&mm->mmap_sem);
+	/* Kernel mode? Handle exceptions or die */
+	if (!user_mode(regs))
+		goto no_context;
+	else
+	/*
+	* Send a sigbus, regardless of whether we were in kernel
+	* or user mode.
+	*/
+	tsk->thread.cp0_badvaddr = address;
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRERR;
+	info.si_addr = (void __user *) address;
+	force_sig_info(SIGBUS, &info, tsk);
+	return;
+vmalloc_fault:
+	{
+		/*
+		* Synchronize this task's top level page-table
+		* with the 'reference' page table.
+		*
+		* Do _not_ use "tsk" here. We might be inside
+		* an interrupt in the middle of a task switch..
+		*/
+		int offset = __pgd_offset(address);
+		pgd_t *pgd, *pgd_k;
+		pud_t *pud, *pud_k;
+		pmd_t *pmd, *pmd_k;
+		pte_t *pte_k;
+
+		pgd = (pgd_t *) pgd_current + offset;
+		pgd_k = init_mm.pgd + offset;
+
+		if (!pgd_present(*pgd_k))
+			goto no_context;
+		set_pgd(pgd, *pgd_k);
+
+		pud = pud_offset(pgd, address);
+		pud_k = pud_offset(pgd_k, address);
+		if (!pud_present(*pud_k))
+			goto no_context;
+
+		pmd = pmd_offset(pud, address);
+		pmd_k = pmd_offset(pud_k, address);
+		if (!pmd_present(*pmd_k))
+			goto no_context;
+		set_pmd(pmd, *pmd_k);
+
+		pte_k = pte_offset_kernel(pmd_k, address);
+		if (!pte_present(*pte_k))
+			goto no_context;
+		return;
+	}
+}
diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c
new file mode 100644
index 0000000..4e3dcd0
--- /dev/null
+++ b/arch/score/mm/init.c
@@ -0,0 +1,161 @@
+/*
+ * arch/score/mm/init.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/errno.h>
+#include <linux/bootmem.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/pagemap.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/initrd.h>
+
+#include <asm/sections.h>
+#include <asm/tlb.h>
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+unsigned long empty_zero_page;
+EXPORT_SYMBOL_GPL(empty_zero_page);
+
+static struct kcore_list kcore_mem, kcore_vmalloc;
+
+static unsigned long setup_zero_page(void)
+{
+	struct page *page;
+
+	empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, 0);
+	if (!empty_zero_page)
+		panic("Oh boy, that early out of memory?");
+
+	page = virt_to_page((void *) empty_zero_page);
+	SetPageReserved(page);
+
+	return 1UL;
+}
+
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+static int __init page_is_ram(unsigned long pagenr)
+{
+	if (pagenr >= min_low_pfn && pagenr < max_low_pfn)
+		return 1;
+	else
+		return 0;
+}
+
+void __init paging_init(void)
+{
+	unsigned long max_zone_pfns[MAX_NR_ZONES];
+	unsigned long lastpfn;
+
+	pagetable_init();
+	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+	lastpfn = max_low_pfn;
+	free_area_init_nodes(max_zone_pfns);
+}
+
+void __init mem_init(void)
+{
+	unsigned long codesize, reservedpages, datasize, initsize;
+	unsigned long tmp, ram = 0;
+
+	max_mapnr = max_low_pfn;
+	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
+	totalram_pages += free_all_bootmem();
+	totalram_pages -= setup_zero_page();	/* Setup zeroed pages. */
+	reservedpages = 0;
+
+	for (tmp = 0; tmp < max_low_pfn; tmp++)
+		if (page_is_ram(tmp)) {
+			ram++;
+			if (PageReserved(pfn_to_page(tmp)))
+				reservedpages++;
+		}
+
+	num_physpages = ram;
+	codesize = (unsigned long) &_etext - (unsigned long) &_text;
+	datasize = (unsigned long) &_edata - (unsigned long) &_etext;
+	initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
+	kclist_add(&kcore_vmalloc, (void *) VMALLOC_START,
+			VMALLOC_END - VMALLOC_START);
+
+	printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
+			"%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n",
+			(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+			ram << (PAGE_SHIFT-10), codesize >> 10,
+			reservedpages << (PAGE_SHIFT-10), datasize >> 10,
+			initsize >> 10,
+			(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
+}
+#endif /* !CONFIG_NEED_MULTIPLE_NODES */
+
+static void free_init_pages(const char *what, unsigned long begin, unsigned long end)
+{
+	unsigned long pfn;
+
+	for (pfn = PFN_UP(begin); pfn < PFN_DOWN(end); pfn++) {
+		struct page *page = pfn_to_page(pfn);
+		void *addr = phys_to_virt(PFN_PHYS(pfn));
+
+		ClearPageReserved(page);
+		init_page_count(page);
+		memset(addr, POISON_FREE_INITMEM, PAGE_SIZE);
+		__free_page(page);
+		totalram_pages++;
+	}
+	printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	free_init_pages("initrd memory",
+		virt_to_phys((void *) start),
+		virt_to_phys((void *) end));
+}
+#endif
+
+void __init_refok free_initmem(void)
+{
+	free_init_pages("unused kernel memory",
+	__pa(&__init_begin),
+	__pa(&__init_end));
+}
+
+unsigned long pgd_current;
+
+#define __page_aligned(order) __attribute__((__aligned__(PAGE_SIZE<<order)))
+
+/*
+ * gcc 3.3 and older have trouble determining that PTRS_PER_PGD and PGD_ORDER
+ * are constants.  So we use the variants from asm-offset.h until that gcc
+ * will officially be retired.
+ */
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned(PTE_ORDER);
+pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
diff --git a/arch/score/mm/pgtable.c b/arch/score/mm/pgtable.c
new file mode 100644
index 0000000..6408bb7
--- /dev/null
+++ b/arch/score/mm/pgtable.c
@@ -0,0 +1,52 @@
+/*
+ * arch/score/mm/pgtable-32.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/pfn.h>
+#include <linux/mm.h>
+
+void pgd_init(unsigned long page)
+{
+	unsigned long *p = (unsigned long *) page;
+	int i;
+
+	for (i = 0; i < USER_PTRS_PER_PGD; i += 8) {
+		p[i + 0] = (unsigned long) invalid_pte_table;
+		p[i + 1] = (unsigned long) invalid_pte_table;
+		p[i + 2] = (unsigned long) invalid_pte_table;
+		p[i + 3] = (unsigned long) invalid_pte_table;
+		p[i + 4] = (unsigned long) invalid_pte_table;
+		p[i + 5] = (unsigned long) invalid_pte_table;
+		p[i + 6] = (unsigned long) invalid_pte_table;
+		p[i + 7] = (unsigned long) invalid_pte_table;
+	}
+}
+
+void __init pagetable_init(void)
+{
+	/* Initialize the entire pgd. */
+	pgd_init((unsigned long)swapper_pg_dir);
+}
diff --git a/arch/score/mm/tlb-miss.S b/arch/score/mm/tlb-miss.S
new file mode 100644
index 0000000..f276519
--- /dev/null
+++ b/arch/score/mm/tlb-miss.S
@@ -0,0 +1,199 @@
+/*
+ * arch/score/mm/tlbex.S
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <asm/asmmacro.h>
+#include <asm/pgtable-bits.h>
+#include <asm/scoreregs.h>
+
+/*
+* After this macro runs, the pte faulted on is
+* in register PTE, a ptr into the table in which
+* the pte belongs is in PTR.
+*/
+	.macro	load_pte, pte, ptr
+	la	\ptr, pgd_current
+	lw	\ptr, [\ptr, 0]
+	mfcr	\pte, cr6
+	srli	\pte, \pte, 22
+	slli	\pte, \pte, 2
+	add	\ptr, \ptr, \pte
+	lw	\ptr, [\ptr, 0]
+	mfcr	\pte, cr6
+	srli	\pte, \pte, 10
+	andi	\pte, 0xffc
+	add	\ptr, \ptr, \pte
+	lw	\pte, [\ptr, 0]
+	.endm
+
+	.macro	pte_reload, ptr
+	lw	\ptr, [\ptr, 0]
+	mtcr	\ptr, cr12
+	nop
+	nop
+	nop
+	nop
+	nop
+	.endm
+
+	.macro do_fault, write
+	SAVE_ALL
+	mfcr	r6, cr6
+	mv	r4, r0
+	ldi	r5, \write
+	la	r8, do_page_fault
+	brl	r8
+	j	ret_from_exception
+	.endm
+
+	.macro	pte_writable, pte, ptr, label
+	andi	\pte, 0x280
+	cmpi.c	\pte, 0x280
+	bne	\label
+	lw	\pte, [\ptr, 0]		/*reload PTE*/
+	.endm
+
+/*
+ * Make PTE writable, update software status bits as well,
+ * then store at PTR.
+ */
+	.macro	pte_makewrite, pte, ptr
+	ori	\pte, 0x426
+	sw	\pte, [\ptr, 0]
+	.endm
+
+	.text
+ENTRY(score7_FTLB_refill_Handler)
+	la	r31, pgd_current	/* get pgd pointer */
+	lw	r31, [r31, 0]		/* get the address of PGD */
+	mfcr	r30, cr6
+	srli	r30, r30, 22		/* PGDIR_SHIFT = 22*/
+	slli	r30, r30, 2
+	add	r31, r31, r30
+	lw	r31, [r31, 0]		/* get the address of the start address of PTE table */
+
+	mfcr	r30, cr9
+	andi	r30, 0xfff 		/* equivalent to get PET index and right shift 2 bits */
+	add	r31, r31, r30
+	lw	r30, [r31, 0]		/* load pte entry */
+	mtcr	r30, cr12
+	nop
+	nop
+	nop
+	nop
+	nop
+	mtrtlb
+	nop
+	nop
+	nop
+	nop
+	nop
+	rte				/* 6 cycles to make sure tlb entry works */
+
+ENTRY(score7_KSEG_refill_Handler)
+	la	r31, pgd_current	/* get pgd pointer */
+	lw	r31, [r31, 0]		/* get the address of PGD */
+	mfcr	r30, cr6
+	srli	r30, r30, 22		/* PGDIR_SHIFT = 22 */
+	slli	r30, r30, 2
+	add	r31, r31, r30
+	lw	r31, [r31, 0]		/* get the address of the start address of PTE table */
+
+	mfcr	r30, cr6		/* get Bad VPN */
+	srli	r30, r30, 10
+	andi	r30, 0xffc		/* PTE VPN mask (bit 11~2) */
+
+	add	r31, r31, r30
+	lw	r30, [r31, 0]		/* load pte entry */
+	mtcr	r30, cr12
+	nop
+	nop
+	nop
+	nop
+	nop
+	mtrtlb
+	nop
+	nop
+	nop
+	nop
+	nop
+	rte				/* 6 cycles to make sure tlb entry works */
+
+nopage_tlbl:
+	do_fault	0		/* Read */
+
+ENTRY(handle_tlb_refill)
+	load_pte	r30, r31
+	pte_writable	r30, r31, handle_tlb_refill_nopage
+	pte_makewrite	r30, r31	/* Access|Modify|Dirty|Valid */
+	pte_reload	r31
+	mtrtlb
+	nop
+	nop
+	nop
+	nop
+	nop
+	rte
+handle_tlb_refill_nopage:
+	do_fault	0		/* Read */
+
+ENTRY(handle_tlb_invaild)
+	load_pte	r30, r31
+	stlb				/* find faulting entry */
+	pte_writable	r30, r31, handle_tlb_invaild_nopage
+	pte_makewrite	r30, r31	/* Access|Modify|Dirty|Valid */
+	pte_reload	r31
+	mtptlb
+	nop
+	nop
+	nop
+	nop
+	nop
+	rte
+handle_tlb_invaild_nopage:
+	do_fault	0		/* Read */
+
+ENTRY(handle_mod)
+	load_pte	r30, r31
+	stlb				/* find faulting entry */
+	andi	r30, _PAGE_WRITE	/* Writable? */
+	cmpz.c	r30
+	beq	nowrite_mod
+	lw	r30, [r31, 0]		/* reload into r30 */
+
+	/* Present and writable bits set, set accessed and dirty bits. */
+	pte_makewrite	r30, r31
+
+	/* Now reload the entry into the tlb. */
+	pte_reload	r31
+	mtptlb
+	nop
+	nop
+	nop
+	nop
+	nop
+	rte
+
+nowrite_mod:
+	do_fault	1	/* Write */
diff --git a/arch/score/mm/tlb-score.c b/arch/score/mm/tlb-score.c
new file mode 100644
index 0000000..4fa5aa5
--- /dev/null
+++ b/arch/score/mm/tlb-score.c
@@ -0,0 +1,251 @@
+/*
+ * arch/score/mm/tlb-score.c
+ *
+ * Score Processor version.
+ *
+ * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
+ *  Lennox Wu <lennox.wu@sunplusct.com>
+ *  Chen Liqin <liqin.chen@sunplusct.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/highmem.h>
+#include <linux/module.h>
+
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/tlb.h>
+
+#define TLBSIZE 32
+
+unsigned long asid_cache = ASID_FIRST_VERSION;
+EXPORT_SYMBOL(asid_cache);
+
+void local_flush_tlb_all(void)
+{
+	unsigned long flags;
+	unsigned long old_ASID;
+	int entry;
+
+	local_irq_save(flags);
+	old_ASID = pevn_get() & ASID_MASK;
+	pectx_set(0);			/* invalid */
+	entry = tlblock_get();		/* skip locked entries*/
+
+	for (; entry < TLBSIZE; entry++) {
+		tlbpt_set(entry);
+		pevn_set(KSEG1);
+		barrier();
+		tlb_write_indexed();
+	}
+	pevn_set(old_ASID);
+	local_irq_restore(flags);
+}
+
+/*
+ * If mm is currently active_mm, we can't really drop it. Instead,
+ * we will get a new one for it.
+ */
+static inline void
+drop_mmu_context(struct mm_struct *mm)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	get_new_mmu_context(mm);
+	pevn_set(mm->context & ASID_MASK);
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	if (mm->context != 0)
+		drop_mmu_context(mm);
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+	unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long vma_mm_context = mm->context;
+	if (mm->context != 0) {
+		unsigned long flags;
+		int size;
+
+		local_irq_save(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		if (size <= TLBSIZE) {
+			int oldpid = pevn_get() & ASID_MASK;
+			int newpid = vma_mm_context & ASID_MASK;
+
+			start &= PAGE_MASK;
+			end += (PAGE_SIZE - 1);
+			end &= PAGE_MASK;
+			while (start < end) {
+				int idx;
+
+				pevn_set(start | newpid);
+				start += PAGE_SIZE;
+				barrier();
+				tlb_probe();
+				idx = tlbpt_get();
+				pectx_set(0);
+				pevn_set(KSEG1);
+				if (idx < 0)
+					continue;
+				tlb_write_indexed();
+			}
+			pevn_set(oldpid);
+		} else {
+			/* Bigger than TLBSIZE, get new ASID directly */
+			get_new_mmu_context(mm);
+			if (mm == current->active_mm)
+				pevn_set(vma_mm_context & ASID_MASK);
+		}
+		local_irq_restore(flags);
+	}
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	unsigned long flags;
+	int size;
+
+	local_irq_save(flags);
+	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+	if (size <= TLBSIZE) {
+		int pid = pevn_get();
+
+		start &= PAGE_MASK;
+		end += PAGE_SIZE - 1;
+		end &= PAGE_MASK;
+
+		while (start < end) {
+			long idx;
+
+			pevn_set(start);
+			start += PAGE_SIZE;
+			tlb_probe();
+			idx = tlbpt_get();
+			if (idx < 0)
+				continue;
+			pectx_set(0);
+			pevn_set(KSEG1);
+			barrier();
+			tlb_write_indexed();
+		}
+		pevn_set(pid);
+	} else {
+		local_flush_tlb_all();
+	}
+
+	local_irq_restore(flags);
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	if (!vma || vma->vm_mm->context != 0) {
+		unsigned long flags;
+		int oldpid, newpid, idx;
+		unsigned long vma_ASID = vma->vm_mm->context;
+
+		newpid = vma_ASID & ASID_MASK;
+		page &= PAGE_MASK;
+		local_irq_save(flags);
+		oldpid = pevn_get() & ASID_MASK;
+		pevn_set(page | newpid);
+		barrier();
+		tlb_probe();
+		idx = tlbpt_get();
+		pectx_set(0);
+		pevn_set(KSEG1);
+		if (idx < 0)		/* p_bit(31) - 1: miss, 0: hit*/
+			goto finish;
+		barrier();
+		tlb_write_indexed();
+finish:
+		pevn_set(oldpid);
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * This one is only used for pages with the global bit set so we don't care
+ * much about the ASID.
+ */
+void local_flush_tlb_one(unsigned long page)
+{
+	unsigned long flags;
+	int oldpid, idx;
+
+	local_irq_save(flags);
+	oldpid = pevn_get();
+	page &= (PAGE_MASK << 1);
+	pevn_set(page);
+	barrier();
+	tlb_probe();
+	idx = tlbpt_get();
+	pectx_set(0);
+	if (idx >= 0) {
+		/* Make sure all entries differ. */
+		pevn_set(KSEG1);
+		barrier();
+		tlb_write_indexed();
+	}
+	pevn_set(oldpid);
+	local_irq_restore(flags);
+}
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	unsigned long flags;
+	int idx, pid;
+
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
+	if (current->active_mm != vma->vm_mm)
+		return;
+
+	pid = pevn_get() & ASID_MASK;
+
+	local_irq_save(flags);
+	address &= PAGE_MASK;
+	pevn_set(address | pid);
+	barrier();
+	tlb_probe();
+	idx = tlbpt_get();
+	pectx_set(pte_val(pte));
+	pevn_set(address | pid);
+	if (idx < 0)
+		tlb_write_random();
+	else
+		tlb_write_indexed();
+
+	pevn_set(pid);
+	local_irq_restore(flags);
+}
+
+void __cpuinit tlb_init(void)
+{
+	tlblock_set(0);
+	local_flush_tlb_all();
+	memcpy((void *)(EXCEPTION_VECTOR_BASE_ADDR + 0x100),
+			&score7_FTLB_refill_Handler, 0xFC);
+	flush_icache_range(EXCEPTION_VECTOR_BASE_ADDR + 0x100,
+			EXCEPTION_VECTOR_BASE_ADDR + 0x1FC);
+}
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index e2bdd7b..b940424 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -10,12 +10,17 @@ config SUPERH
 	select EMBEDDED
 	select HAVE_CLK
 	select HAVE_IDE
+	select HAVE_LMB
 	select HAVE_OPROFILE
 	select HAVE_GENERIC_DMA_COHERENT
 	select HAVE_IOREMAP_PROT if MMU
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_DMA_API_DEBUG
-	select HAVE_PERF_COUNTERS
+	select HAVE_PERF_EVENTS
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_BZIP2
+	select HAVE_KERNEL_LZMA
+	select HAVE_SYSCALL_TRACEPOINTS
 	select RTC_LIB
 	select GENERIC_ATOMIC64
 	help
@@ -31,6 +36,9 @@ config SUPERH32
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_DYNAMIC_FTRACE
+	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
+	select HAVE_FTRACE_SYSCALLS
+	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_ARCH_KGDB
 	select ARCH_HIBERNATION_POSSIBLE if MMU
 
@@ -212,6 +220,8 @@ config CPU_SHX3
 config ARCH_SHMOBILE
 	bool
 	select ARCH_SUSPEND_POSSIBLE
+	select PM
+	select PM_RUNTIME
 
 if SUPERH32
 
@@ -389,6 +399,13 @@ config CPU_SUBTYPE_SH7724
 	help
 	  Select SH7724 if you have an SH-MobileR2R CPU.
 
+config CPU_SUBTYPE_SH7757
+	bool "Support SH7757 processor"
+	select CPU_SH4A
+	select CPU_SHX2
+	help
+	  Select SH7757 if you have a SH4A SH7757 CPU.
+
 config CPU_SUBTYPE_SH7763
 	bool "Support SH7763 processor"
 	select CPU_SH4A
@@ -751,12 +768,31 @@ config UBC_WAKEUP
 
 	  If unsure, say N.
 
-config CMDLINE_BOOL
-	bool "Default bootloader kernel arguments"
+choice
+	prompt "Kernel command line"
+	optional
+	default CMDLINE_OVERWRITE
+	help
+	  Setting this option allows the kernel command line arguments
+	  to be set.
+
+config CMDLINE_OVERWRITE
+	bool "Overwrite bootloader kernel arguments"
+	help
+	  Given string will overwrite any arguments passed in by
+	  a bootloader.
+
+config CMDLINE_EXTEND
+	bool "Extend bootloader kernel arguments"
+	help
+	  Given string will be concatenated with arguments passed in
+	  by a bootloader.
+
+endchoice
 
 config CMDLINE
-	string "Initial kernel command string"
-	depends on CMDLINE_BOOL
+	string "Kernel command line arguments string"
+	depends on CMDLINE_OVERWRITE || CMDLINE_EXTEND
 	default "console=ttySC1,115200"
 
 endmenu
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 39224b5..55907af 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -38,11 +38,13 @@ config EARLY_SCIF_CONSOLE_PORT
 	default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
 				CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
 				CPU_SUBTYPE_SH7343
-	default "0xffea0000" if CPU_SUBTYPE_SH7785
+	default "0xfe4c0000" if CPU_SUBTYPE_SH7757
+	default "0xffeb0000" if CPU_SUBTYPE_SH7785
 	default "0xffeb0000" if CPU_SUBTYPE_SH7786
 	default "0xfffe8000" if CPU_SUBTYPE_SH7203
 	default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
 	default "0xffe80000" if CPU_SH4
+	default "0xa4000150" if CPU_SH3
 	default "0x00000000"
 
 config EARLY_PRINTK
@@ -61,12 +63,14 @@ config EARLY_PRINTK
 	  select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using
 	  the kernel command line option to toggle back and forth.
 
-config DEBUG_STACKOVERFLOW
+config STACK_DEBUG
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL && SUPERH32
 	help
 	  This option will cause messages to be printed if free stack space
-	  drops below a certain limit.
+	  drops below a certain limit. Saying Y here will add overhead to
+	  every function call and will therefore incur a major
+	  performance hit. Most users should say N.
 
 config DEBUG_STACK_USAGE
 	bool "Stack utilization instrumentation"
@@ -107,6 +111,14 @@ config DUMP_CODE
 
 	  Those looking for more verbose debugging output should say Y.
 
+config DWARF_UNWINDER
+	bool "Enable the DWARF unwinder for stacktraces"
+	select FRAME_POINTER
+	default n
+	help
+	  Enabling this option will make stacktraces more accurate, at
+	  the cost of an increase in overall kernel size.
+
 config SH_NO_BSS_INIT
 	bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)"
 	depends on DEBUG_KERNEL
@@ -123,4 +135,9 @@ config SH64_SR_WATCH
 	bool "Debug: set SR.WATCH to enable hardware watchpoints and trace"
 	depends on SUPERH64
 
+config MCOUNT
+	def_bool y
+	depends on SUPERH32
+	depends on STACK_DEBUG || FUNCTION_TRACER
+
 endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 75d049b..fc51a91 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -136,6 +136,8 @@ machdir-$(CONFIG_SH_7751_SYSTEMH)		+= mach-systemh
 machdir-$(CONFIG_SH_EDOSK7705)			+= mach-edosk7705
 machdir-$(CONFIG_SH_HIGHLANDER)			+= mach-highlander
 machdir-$(CONFIG_SH_MIGOR)			+= mach-migor
+machdir-$(CONFIG_SH_KFR2R09)			+= mach-kfr2r09
+machdir-$(CONFIG_SH_ECOVEC)			+= mach-ecovec24
 machdir-$(CONFIG_SH_SDK7780)			+= mach-sdk7780
 machdir-$(CONFIG_SH_X3PROTO)			+= mach-x3proto
 machdir-$(CONFIG_SH_SH7763RDP)			+= mach-sh7763rdp
@@ -186,17 +188,27 @@ KBUILD_CFLAGS		+= -pipe $(cflags-y)
 KBUILD_CPPFLAGS		+= $(cflags-y)
 KBUILD_AFLAGS		+= $(cflags-y)
 
+ifeq ($(CONFIG_MCOUNT),y)
+  KBUILD_CFLAGS += -pg
+endif
+
+ifeq ($(CONFIG_DWARF_UNWINDER),y)
+  KBUILD_CFLAGS += -fasynchronous-unwind-tables
+endif
+
 libs-$(CONFIG_SUPERH32)		:= arch/sh/lib/	$(libs-y)
 libs-$(CONFIG_SUPERH64)		:= arch/sh/lib64/ $(libs-y)
 
-PHONY += maketools FORCE
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.srec \
+	       zImage vmlinux.srec romImage
+PHONY += maketools $(BOOT_TARGETS) FORCE
 
 maketools:  include/linux/version.h FORCE
 	$(Q)$(MAKE) $(build)=arch/sh/tools include/asm-sh/machtypes.h
 
 all: $(KBUILD_IMAGE)
 
-zImage uImage uImage.srec vmlinux.srec: vmlinux
+$(BOOT_TARGETS): vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 compressed: zImage
@@ -208,10 +220,14 @@ archclean:
 	$(Q)$(MAKE) $(clean)=arch/sh/kernel/vsyscall
 
 define archhelp
-	@echo '* zImage 	           - Compressed kernel image'
+	@echo '  zImage 	           - Compressed kernel image'
+	@echo '  romImage	           - Compressed ROM image, if supported'
 	@echo '  vmlinux.srec	           - Create an ELF S-record'
-	@echo '  uImage  	           - Create a bootable image for U-Boot'
-	@echo '  uImage.srec  	           - Create an S-record for U-Boot'
+	@echo '* uImage  	           - Alias to bootable U-Boot image'
+	@echo '  uImage.srec	           - Create an S-record for U-Boot'
+	@echo '* uImage.gz	           - Kernel-only image for U-Boot (gzip)'
+	@echo '  uImage.bz2	           - Kernel-only image for U-Boot (bzip2)'
+	@echo '  uImage.lzma	           - Kernel-only image for U-Boot (lzma)'
 endef
 
 CLEAN_FILES += include/asm-sh/machtypes.h
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 2b1af0e..aedd9de 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -160,7 +160,6 @@ config SH_SH7785LCR
 	bool "SH7785LCR"
 	depends on CPU_SUBTYPE_SH7785
 	select SYS_SUPPORTS_PCI
-	select IO_TRAPPED if MMU
 
 config SH_SH7785LCR_29BIT_PHYSMAPS
 	bool "SH7785LCR 29bit physmaps"
@@ -171,6 +170,13 @@ config SH_SH7785LCR_29BIT_PHYSMAPS
 	  DIP switch(S2-5). If you set the DIP switch for S2-5 = ON,
 	  you can access all on-board device in 29bit address mode.
 
+config SH_SH7785LCR_PT
+	bool "SH7785LCR prototype board on 32-bit MMU mode"
+	depends on SH_SH7785LCR && 32BIT
+	default n
+	help
+	  If you use prototype board, this option is enabled.
+
 config SH_URQUELL
 	bool "Urquell"
 	depends on CPU_SUBTYPE_SH7786
@@ -193,6 +199,20 @@ config SH_AP325RXA
 	  Renesas "AP-325RXA" support.
 	  Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
 
+config SH_KFR2R09
+	bool "KFR2R09"
+	depends on CPU_SUBTYPE_SH7724
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  "Kit For R2R for 2009" support.
+
+config SH_ECOVEC
+	bool "EcoVec"
+	depends on CPU_SUBTYPE_SH7724
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  Renesas "R0P7724LC0011/21RL (EcoVec)" support.
+
 config SH_SH7763RDP
 	bool "SH7763RDP"
 	depends on CPU_SUBTYPE_SH7763
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index b9c88cc..2d08073 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -188,7 +188,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
 			.name = "LB070WV1",
 			.xres = 800,
 			.yres = 480,
-			.left_margin = 40,
+			.left_margin = 32,
 			.right_margin = 160,
 			.hsync_len = 8,
 			.upper_margin = 63,
@@ -211,7 +211,7 @@ static struct resource lcdc_resources[] = {
 	[0] = {
 		.name	= "LCDC",
 		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe941fff,
+		.end	= 0xfe942fff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -227,6 +227,9 @@ static struct platform_device lcdc_device = {
 	.dev		= {
 		.platform_data	= &lcdc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
 };
 
 static void camera_power(int val)
@@ -307,8 +310,10 @@ static int camera_set_capture(struct soc_camera_platform_info *info,
 	return ret;
 }
 
+static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);
+static void ap325rxa_camera_del(struct soc_camera_link *icl);
+
 static struct soc_camera_platform_info camera_info = {
-	.iface = 0,
 	.format_name = "UYVY",
 	.format_depth = 16,
 	.format = {
@@ -320,24 +325,46 @@ static struct soc_camera_platform_info camera_info = {
 	.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
 	SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
 	.set_capture = camera_set_capture,
+	.link = {
+		.bus_id		= 0,
+		.add_device	= ap325rxa_camera_add,
+		.del_device	= ap325rxa_camera_del,
+		.module_name	= "soc_camera_platform",
+	},
 };
 
+static void dummy_release(struct device *dev)
+{
+}
+
 static struct platform_device camera_device = {
 	.name		= "soc_camera_platform",
 	.dev		= {
 		.platform_data	= &camera_info,
+		.release	= dummy_release,
 	},
 };
 
-static int __init camera_setup(void)
+static int ap325rxa_camera_add(struct soc_camera_link *icl,
+			       struct device *dev)
 {
-	if (camera_probe() > 0)
-		platform_device_register(&camera_device);
+	if (icl != &camera_info.link || camera_probe() <= 0)
+		return -ENODEV;
 
-	return 0;
+	camera_info.dev = dev;
+
+	return platform_device_register(&camera_device);
 }
-late_initcall(camera_setup);
 
+static void ap325rxa_camera_del(struct soc_camera_link *icl)
+{
+	if (icl != &camera_info.link)
+		return;
+
+	platform_device_unregister(&camera_device);
+	memset(&camera_device.dev.kobj, 0,
+	       sizeof(camera_device.dev.kobj));
+}
 #endif /* CONFIG_I2C */
 
 static int ov7725_power(struct device *dev, int mode)
@@ -377,6 +404,9 @@ static struct platform_device ceu_device = {
 	.dev		= {
 		.platform_data	= &sh_mobile_ceu_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU,
+	},
 };
 
 struct spi_gpio_platform_data sdcard_cn3_platform_data = {
@@ -410,6 +440,7 @@ static struct ov772x_camera_info ov7725_info = {
 	.flags		= OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
 	.edgectrl	= OV772X_AUTO_EDGECTRL(0xf, 0),
 	.link = {
+		.bus_id		= 0,
 		.power		= ov7725_power,
 		.board_info	= &ap325rxa_i2c_camera[0],
 		.i2c_adapter_id	= 0,
@@ -417,11 +448,19 @@ static struct ov772x_camera_info ov7725_info = {
 	},
 };
 
-static struct platform_device ap325rxa_camera = {
-	.name	= "soc-camera-pdrv",
-	.id	= 0,
-	.dev	= {
-		.platform_data = &ov7725_info.link,
+static struct platform_device ap325rxa_camera[] = {
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 0,
+		.dev	= {
+			.platform_data = &ov7725_info.link,
+		},
+	}, {
+		.name	= "soc-camera-pdrv",
+		.id	= 1,
+		.dev	= {
+			.platform_data = &camera_info.link,
+		},
 	},
 };
 
@@ -432,7 +471,8 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
 	&ceu_device,
 	&nand_flash_device,
 	&sdcard_cn3_device,
-	&ap325rxa_camera,
+	&ap325rxa_camera[0],
+	&ap325rxa_camera[1],
 };
 
 static struct spi_board_info ap325rxa_spi_devices[] = {
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index 42410a1..e5a8a2f 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -223,6 +223,19 @@ static struct platform_device sm501_device = {
 	.resource	= sm501_resources,
 };
 
+static struct resource i2c_proto_resources[] = {
+	[0] = {
+		.start	= PCA9564_PROTO_32BIT_ADDR,
+		.end	= PCA9564_PROTO_32BIT_ADDR + PCA9564_SIZE - 1,
+		.flags	= IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+	},
+	[1] = {
+		.start	= 12,
+		.end	= 12,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
 static struct resource i2c_resources[] = {
 	[0] = {
 		.start	= PCA9564_ADDR,
@@ -271,6 +284,11 @@ static int __init sh7785lcr_devices_setup(void)
 	i2c_register_board_info(0, sh7785lcr_i2c_devices,
 				ARRAY_SIZE(sh7785lcr_i2c_devices));
 
+	if (mach_is_sh7785lcr_pt()) {
+		i2c_device.resource = i2c_proto_resources;
+		i2c_device.num_resources = ARRAY_SIZE(i2c_proto_resources);
+	}
+
 	return platform_add_devices(sh7785lcr_devices,
 				    ARRAY_SIZE(sh7785lcr_devices));
 }
diff --git a/arch/sh/boards/mach-ecovec24/Makefile b/arch/sh/boards/mach-ecovec24/Makefile
new file mode 100644
index 0000000..51f8521
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the R0P7724LC0011/21RL (EcoVec)
+#
+# 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.
+#
+
+obj-y	 := setup.o
\ No newline at end of file
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
new file mode 100644
index 0000000..96bc169
--- /dev/null
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -0,0 +1,670 @@
+/*
+ * Copyright (C) 2009 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <video/sh_mobile_lcdc.h>
+#include <media/sh_mobile_ceu.h>
+#include <asm/heartbeat.h>
+#include <asm/sh_eth.h>
+#include <asm/sh_keysc.h>
+#include <asm/clock.h>
+#include <cpu/sh7724.h>
+
+/*
+ *  Address      Interface        BusWidth
+ *-----------------------------------------
+ *  0x0000_0000  uboot            16bit
+ *  0x0004_0000  Linux romImage   16bit
+ *  0x0014_0000  MTD for Linux    16bit
+ *  0x0400_0000  Internal I/O     16/32bit
+ *  0x0800_0000  DRAM             32bit
+ *  0x1800_0000  MFI              16bit
+ */
+
+/* Heartbeat */
+static unsigned char led_pos[] = { 0, 1, 2, 3 };
+static struct heartbeat_data heartbeat_data = {
+	.regsize = 8,
+	.nr_bits = 4,
+	.bit_pos = led_pos,
+};
+
+static struct resource heartbeat_resources[] = {
+	[0] = {
+		.start  = 0xA405012C, /* PTG */
+		.end    = 0xA405012E - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device heartbeat_device = {
+	.name           = "heartbeat",
+	.id             = -1,
+	.dev = {
+		.platform_data = &heartbeat_data,
+	},
+	.num_resources  = ARRAY_SIZE(heartbeat_resources),
+	.resource       = heartbeat_resources,
+};
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+	{
+		.name = "boot loader",
+		.offset = 0,
+		.size = (5 * 1024 * 1024),
+		.mask_flags = MTD_CAP_ROM,
+	}, {
+		.name = "free-area",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data nor_flash_data = {
+	.width		= 2,
+	.parts		= nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+	[0] = {
+		.name	= "NOR Flash",
+		.start	= 0x00000000,
+		.end	= 0x03ffffff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device nor_flash_device = {
+	.name		= "physmap-flash",
+	.resource	= nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(nor_flash_resources),
+	.dev		= {
+		.platform_data = &nor_flash_data,
+	},
+};
+
+/* SH Eth */
+#define SH_ETH_ADDR	(0xA4600000)
+#define SH_ETH_MAHR	(SH_ETH_ADDR + 0x1C0)
+#define SH_ETH_MALR	(SH_ETH_ADDR + 0x1C8)
+static struct resource sh_eth_resources[] = {
+	[0] = {
+		.start = SH_ETH_ADDR,
+		.end   = SH_ETH_ADDR + 0x1FC,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = 91,
+		.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+	},
+};
+
+struct sh_eth_plat_data sh_eth_plat = {
+	.phy = 0x1f, /* SMSC LAN8700 */
+	.edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh_eth_device = {
+	.name = "sh-eth",
+	.id	= 0,
+	.dev = {
+		.platform_data = &sh_eth_plat,
+	},
+	.num_resources = ARRAY_SIZE(sh_eth_resources),
+	.resource = sh_eth_resources,
+};
+
+/* USB0 host */
+void usb0_port_power(int port, int power)
+{
+	gpio_set_value(GPIO_PTB4, power);
+}
+
+static struct r8a66597_platdata usb0_host_data = {
+	.on_chip = 1,
+	.port_power = usb0_port_power,
+};
+
+static struct resource usb0_host_resources[] = {
+	[0] = {
+		.start	= 0xa4d80000,
+		.end	= 0xa4d80124 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 65,
+		.end	= 65,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device usb0_host_device = {
+	.name		= "r8a66597_hcd",
+	.id		= 0,
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usb0_host_data,
+	},
+	.num_resources	= ARRAY_SIZE(usb0_host_resources),
+	.resource	= usb0_host_resources,
+};
+
+/*
+ * USB1
+ *
+ * CN5 can use both host/function,
+ * and we can determine it by checking PTB[3]
+ *
+ * This time only USB1 host is supported.
+ */
+void usb1_port_power(int port, int power)
+{
+	if (!gpio_get_value(GPIO_PTB3)) {
+		printk(KERN_ERR "USB1 function is not supported\n");
+		return;
+	}
+
+	gpio_set_value(GPIO_PTB5, power);
+}
+
+static struct r8a66597_platdata usb1_host_data = {
+	.on_chip = 1,
+	.port_power = usb1_port_power,
+};
+
+static struct resource usb1_host_resources[] = {
+	[0] = {
+		.start	= 0xa4d90000,
+		.end	= 0xa4d90124 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 66,
+		.end	= 66,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device usb1_host_device = {
+	.name		= "r8a66597_hcd",
+	.id		= 1,
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usb1_host_data,
+	},
+	.num_resources	= ARRAY_SIZE(usb1_host_resources),
+	.resource	= usb1_host_resources,
+};
+
+/* LCDC */
+static struct sh_mobile_lcdc_info lcdc_info = {
+	.ch[0] = {
+		.interface_type = RGB18,
+		.chan = LCDC_CHAN_MAINLCD,
+		.bpp = 16,
+		.lcd_cfg = {
+			.sync = 0, /* hsync and vsync are active low */
+		},
+		.lcd_size_cfg = { /* 7.0 inch */
+			.width = 152,
+			.height = 91,
+		},
+		.board_cfg = {
+		},
+	}
+};
+
+static struct resource lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC",
+		.start	= 0xfe940000,
+		.end	= 0xfe942fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 106,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device lcdc_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(lcdc_resources),
+	.resource	= lcdc_resources,
+	.dev		= {
+		.platform_data	= &lcdc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
+};
+
+/* CEU0 */
+static struct sh_mobile_ceu_info sh_mobile_ceu0_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource ceu0_resources[] = {
+	[0] = {
+		.name	= "CEU0",
+		.start	= 0xfe910000,
+		.end	= 0xfe91009f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 52,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device ceu0_device = {
+	.name		= "sh_mobile_ceu",
+	.id             = 0, /* "ceu0" clock */
+	.num_resources	= ARRAY_SIZE(ceu0_resources),
+	.resource	= ceu0_resources,
+	.dev	= {
+		.platform_data	= &sh_mobile_ceu0_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU0,
+	},
+};
+
+/* CEU1 */
+static struct sh_mobile_ceu_info sh_mobile_ceu1_info = {
+	.flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource ceu1_resources[] = {
+	[0] = {
+		.name	= "CEU1",
+		.start	= 0xfe914000,
+		.end	= 0xfe91409f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 63,
+		.flags  = IORESOURCE_IRQ,
+	},
+	[2] = {
+		/* place holder for contiguous memory */
+	},
+};
+
+static struct platform_device ceu1_device = {
+	.name		= "sh_mobile_ceu",
+	.id             = 1, /* "ceu1" clock */
+	.num_resources	= ARRAY_SIZE(ceu1_resources),
+	.resource	= ceu1_resources,
+	.dev	= {
+		.platform_data	= &sh_mobile_ceu1_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU1,
+	},
+};
+
+/* I2C device */
+static struct i2c_board_info i2c1_devices[] = {
+	{
+		I2C_BOARD_INFO("r2025sd", 0x32),
+	},
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+	.mode		= SH_KEYSC_MODE_1,
+	.scan_timing	= 3,
+	.delay		= 50,
+	.kycr2_delay	= 100,
+	.keycodes	= { KEY_1, 0, 0, 0, 0,
+			    KEY_2, 0, 0, 0, 0,
+			    KEY_3, 0, 0, 0, 0,
+			    KEY_4, 0, 0, 0, 0,
+			    KEY_5, 0, 0, 0, 0,
+			    KEY_6, 0, 0, 0, 0, },
+};
+
+static struct resource keysc_resources[] = {
+	[0] = {
+		.name	= "KEYSC",
+		.start  = 0x044b0000,
+		.end    = 0x044b000f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 79,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device keysc_device = {
+	.name           = "sh_keysc",
+	.id             = 0, /* keysc0 clock */
+	.num_resources  = ARRAY_SIZE(keysc_resources),
+	.resource       = keysc_resources,
+	.dev	= {
+		.platform_data	= &keysc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
+};
+
+static struct platform_device *ecovec_devices[] __initdata = {
+	&heartbeat_device,
+	&nor_flash_device,
+	&sh_eth_device,
+	&usb0_host_device,
+	&usb1_host_device, /* USB1 host support */
+	&lcdc_device,
+	&ceu0_device,
+	&ceu1_device,
+	&keysc_device,
+};
+
+#define EEPROM_ADDR 0x50
+static u8 mac_read(struct i2c_adapter *a, u8 command)
+{
+	struct i2c_msg msg[2];
+	u8 buf;
+	int ret;
+
+	msg[0].addr  = EEPROM_ADDR;
+	msg[0].flags = 0;
+	msg[0].len   = 1;
+	msg[0].buf   = &command;
+
+	msg[1].addr  = EEPROM_ADDR;
+	msg[1].flags = I2C_M_RD;
+	msg[1].len   = 1;
+	msg[1].buf   = &buf;
+
+	ret = i2c_transfer(a, msg, 2);
+	if (ret < 0) {
+		printk(KERN_ERR "error %d\n", ret);
+		buf = 0xff;
+	}
+
+	return buf;
+}
+
+#define MAC_LEN 6
+static void __init sh_eth_init(void)
+{
+	struct i2c_adapter *a = i2c_get_adapter(1);
+	struct clk *eth_clk;
+	u8 mac[MAC_LEN];
+	int i;
+
+	if (!a) {
+		pr_err("can not get I2C 1\n");
+		return;
+	}
+
+	eth_clk = clk_get(NULL, "eth0");
+	if (!eth_clk) {
+		pr_err("can not get eth0 clk\n");
+		return;
+	}
+
+	/* read MAC address frome EEPROM */
+	for (i = 0; i < MAC_LEN; i++) {
+		mac[i] = mac_read(a, 0x10 + i);
+		msleep(10);
+	}
+
+	/* clock enable */
+	clk_enable(eth_clk);
+
+	/* reset sh-eth */
+	ctrl_outl(0x1, SH_ETH_ADDR + 0x0);
+
+	/* set MAC addr */
+	ctrl_outl((mac[0] << 24) |
+		  (mac[1] << 16) |
+		  (mac[2] <<  8) |
+		  (mac[3] <<  0), SH_ETH_MAHR);
+	ctrl_outl((mac[4] <<  8) |
+		  (mac[5] <<  0), SH_ETH_MALR);
+
+	clk_put(eth_clk);
+}
+
+#define PORT_HIZA 0xA4050158
+#define IODRIVEA  0xA405018A
+static int __init arch_setup(void)
+{
+	/* enable SCIFA0 */
+	gpio_request(GPIO_FN_SCIF0_TXD, NULL);
+	gpio_request(GPIO_FN_SCIF0_RXD, NULL);
+
+	/* enable debug LED */
+	gpio_request(GPIO_PTG0, NULL);
+	gpio_request(GPIO_PTG1, NULL);
+	gpio_request(GPIO_PTG2, NULL);
+	gpio_request(GPIO_PTG3, NULL);
+	gpio_direction_output(GPIO_PTG0, 0);
+	gpio_direction_output(GPIO_PTG1, 0);
+	gpio_direction_output(GPIO_PTG2, 0);
+	gpio_direction_output(GPIO_PTG3, 0);
+	ctrl_outw((ctrl_inw(PORT_HIZA) & ~(0x1 << 1)) , PORT_HIZA);
+
+	/* enable SH-Eth */
+	gpio_request(GPIO_PTA1, NULL);
+	gpio_direction_output(GPIO_PTA1, 1);
+	mdelay(20);
+
+	gpio_request(GPIO_FN_RMII_RXD0,    NULL);
+	gpio_request(GPIO_FN_RMII_RXD1,    NULL);
+	gpio_request(GPIO_FN_RMII_TXD0,    NULL);
+	gpio_request(GPIO_FN_RMII_TXD1,    NULL);
+	gpio_request(GPIO_FN_RMII_REF_CLK, NULL);
+	gpio_request(GPIO_FN_RMII_TX_EN,   NULL);
+	gpio_request(GPIO_FN_RMII_RX_ER,   NULL);
+	gpio_request(GPIO_FN_RMII_CRS_DV,  NULL);
+	gpio_request(GPIO_FN_MDIO,         NULL);
+	gpio_request(GPIO_FN_MDC,          NULL);
+	gpio_request(GPIO_FN_LNKSTA,       NULL);
+
+	/* enable USB */
+	ctrl_outw(0x0000, 0xA4D80000);
+	ctrl_outw(0x0000, 0xA4D90000);
+	gpio_request(GPIO_PTB3,  NULL);
+	gpio_request(GPIO_PTB4,  NULL);
+	gpio_request(GPIO_PTB5,  NULL);
+	gpio_direction_input(GPIO_PTB3);
+	gpio_direction_output(GPIO_PTB4, 0);
+	gpio_direction_output(GPIO_PTB5, 0);
+	ctrl_outw(0x0600, 0xa40501d4);
+	ctrl_outw(0x0600, 0xa4050192);
+
+	/* enable LCDC */
+	gpio_request(GPIO_FN_LCDD23,   NULL);
+	gpio_request(GPIO_FN_LCDD22,   NULL);
+	gpio_request(GPIO_FN_LCDD21,   NULL);
+	gpio_request(GPIO_FN_LCDD20,   NULL);
+	gpio_request(GPIO_FN_LCDD19,   NULL);
+	gpio_request(GPIO_FN_LCDD18,   NULL);
+	gpio_request(GPIO_FN_LCDD17,   NULL);
+	gpio_request(GPIO_FN_LCDD16,   NULL);
+	gpio_request(GPIO_FN_LCDD15,   NULL);
+	gpio_request(GPIO_FN_LCDD14,   NULL);
+	gpio_request(GPIO_FN_LCDD13,   NULL);
+	gpio_request(GPIO_FN_LCDD12,   NULL);
+	gpio_request(GPIO_FN_LCDD11,   NULL);
+	gpio_request(GPIO_FN_LCDD10,   NULL);
+	gpio_request(GPIO_FN_LCDD9,    NULL);
+	gpio_request(GPIO_FN_LCDD8,    NULL);
+	gpio_request(GPIO_FN_LCDD7,    NULL);
+	gpio_request(GPIO_FN_LCDD6,    NULL);
+	gpio_request(GPIO_FN_LCDD5,    NULL);
+	gpio_request(GPIO_FN_LCDD4,    NULL);
+	gpio_request(GPIO_FN_LCDD3,    NULL);
+	gpio_request(GPIO_FN_LCDD2,    NULL);
+	gpio_request(GPIO_FN_LCDD1,    NULL);
+	gpio_request(GPIO_FN_LCDD0,    NULL);
+	gpio_request(GPIO_FN_LCDDISP,  NULL);
+	gpio_request(GPIO_FN_LCDHSYN,  NULL);
+	gpio_request(GPIO_FN_LCDDCK,   NULL);
+	gpio_request(GPIO_FN_LCDVSYN,  NULL);
+	gpio_request(GPIO_FN_LCDDON,   NULL);
+	gpio_request(GPIO_FN_LCDLCLK,  NULL);
+	ctrl_outw((ctrl_inw(PORT_HIZA) & ~0x0001), PORT_HIZA);
+
+	gpio_request(GPIO_PTE6, NULL);
+	gpio_request(GPIO_PTU1, NULL);
+	gpio_request(GPIO_PTR1, NULL);
+	gpio_request(GPIO_PTA2, NULL);
+	gpio_direction_input(GPIO_PTE6);
+	gpio_direction_output(GPIO_PTU1, 0);
+	gpio_direction_output(GPIO_PTR1, 0);
+	gpio_direction_output(GPIO_PTA2, 0);
+
+	/* I/O buffer drive ability is low */
+	ctrl_outw((ctrl_inw(IODRIVEA) & ~0x00c0) | 0x0040 , IODRIVEA);
+
+	if (gpio_get_value(GPIO_PTE6)) {
+		/* DVI */
+		lcdc_info.clock_source			= LCDC_CLK_EXTERNAL;
+		lcdc_info.ch[0].clock_divider		= 1,
+		lcdc_info.ch[0].lcd_cfg.name		= "DVI";
+		lcdc_info.ch[0].lcd_cfg.xres		= 1280;
+		lcdc_info.ch[0].lcd_cfg.yres		= 720;
+		lcdc_info.ch[0].lcd_cfg.left_margin	= 220;
+		lcdc_info.ch[0].lcd_cfg.right_margin	= 110;
+		lcdc_info.ch[0].lcd_cfg.hsync_len	= 40;
+		lcdc_info.ch[0].lcd_cfg.upper_margin	= 20;
+		lcdc_info.ch[0].lcd_cfg.lower_margin	= 5;
+		lcdc_info.ch[0].lcd_cfg.vsync_len	= 5;
+
+		gpio_set_value(GPIO_PTA2, 1);
+		gpio_set_value(GPIO_PTU1, 1);
+	} else {
+		/* Panel */
+
+		lcdc_info.clock_source			= LCDC_CLK_PERIPHERAL;
+		lcdc_info.ch[0].clock_divider		= 2,
+		lcdc_info.ch[0].lcd_cfg.name		= "Panel";
+		lcdc_info.ch[0].lcd_cfg.xres		= 800;
+		lcdc_info.ch[0].lcd_cfg.yres		= 480;
+		lcdc_info.ch[0].lcd_cfg.left_margin	= 220;
+		lcdc_info.ch[0].lcd_cfg.right_margin	= 110;
+		lcdc_info.ch[0].lcd_cfg.hsync_len	= 70;
+		lcdc_info.ch[0].lcd_cfg.upper_margin	= 20;
+		lcdc_info.ch[0].lcd_cfg.lower_margin	= 5;
+		lcdc_info.ch[0].lcd_cfg.vsync_len	= 5;
+
+		gpio_set_value(GPIO_PTR1, 1);
+
+		/* FIXME
+		 *
+		 * LCDDON control is needed for Panel,
+		 * but current sh_mobile_lcdc driver doesn't control it.
+		 * It is temporary correspondence
+		 */
+		gpio_request(GPIO_PTF4, NULL);
+		gpio_direction_output(GPIO_PTF4, 1);
+	}
+
+	/* enable CEU0 */
+	gpio_request(GPIO_FN_VIO0_D15, NULL);
+	gpio_request(GPIO_FN_VIO0_D14, NULL);
+	gpio_request(GPIO_FN_VIO0_D13, NULL);
+	gpio_request(GPIO_FN_VIO0_D12, NULL);
+	gpio_request(GPIO_FN_VIO0_D11, NULL);
+	gpio_request(GPIO_FN_VIO0_D10, NULL);
+	gpio_request(GPIO_FN_VIO0_D9,  NULL);
+	gpio_request(GPIO_FN_VIO0_D8,  NULL);
+	gpio_request(GPIO_FN_VIO0_D7,  NULL);
+	gpio_request(GPIO_FN_VIO0_D6,  NULL);
+	gpio_request(GPIO_FN_VIO0_D5,  NULL);
+	gpio_request(GPIO_FN_VIO0_D4,  NULL);
+	gpio_request(GPIO_FN_VIO0_D3,  NULL);
+	gpio_request(GPIO_FN_VIO0_D2,  NULL);
+	gpio_request(GPIO_FN_VIO0_D1,  NULL);
+	gpio_request(GPIO_FN_VIO0_D0,  NULL);
+	gpio_request(GPIO_FN_VIO0_VD,  NULL);
+	gpio_request(GPIO_FN_VIO0_CLK, NULL);
+	gpio_request(GPIO_FN_VIO0_FLD, NULL);
+	gpio_request(GPIO_FN_VIO0_HD,  NULL);
+	platform_resource_setup_memory(&ceu0_device, "ceu0", 4 << 20);
+
+	/* enable CEU1 */
+	gpio_request(GPIO_FN_VIO1_D7,  NULL);
+	gpio_request(GPIO_FN_VIO1_D6,  NULL);
+	gpio_request(GPIO_FN_VIO1_D5,  NULL);
+	gpio_request(GPIO_FN_VIO1_D4,  NULL);
+	gpio_request(GPIO_FN_VIO1_D3,  NULL);
+	gpio_request(GPIO_FN_VIO1_D2,  NULL);
+	gpio_request(GPIO_FN_VIO1_D1,  NULL);
+	gpio_request(GPIO_FN_VIO1_D0,  NULL);
+	gpio_request(GPIO_FN_VIO1_FLD, NULL);
+	gpio_request(GPIO_FN_VIO1_HD,  NULL);
+	gpio_request(GPIO_FN_VIO1_VD,  NULL);
+	gpio_request(GPIO_FN_VIO1_CLK, NULL);
+	platform_resource_setup_memory(&ceu1_device, "ceu1", 4 << 20);
+
+	/* enable KEYSC */
+	gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+	gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+	gpio_request(GPIO_FN_KEYOUT3,     NULL);
+	gpio_request(GPIO_FN_KEYOUT2,     NULL);
+	gpio_request(GPIO_FN_KEYOUT1,     NULL);
+	gpio_request(GPIO_FN_KEYOUT0,     NULL);
+	gpio_request(GPIO_FN_KEYIN0,      NULL);
+
+	/* enable user debug switch */
+	gpio_request(GPIO_PTR0, NULL);
+	gpio_request(GPIO_PTR4, NULL);
+	gpio_request(GPIO_PTR5, NULL);
+	gpio_request(GPIO_PTR6, NULL);
+	gpio_direction_input(GPIO_PTR0);
+	gpio_direction_input(GPIO_PTR4);
+	gpio_direction_input(GPIO_PTR5);
+	gpio_direction_input(GPIO_PTR6);
+
+	/* enable I2C device */
+	i2c_register_board_info(1, i2c1_devices,
+				ARRAY_SIZE(i2c1_devices));
+
+	return platform_add_devices(ecovec_devices,
+				    ARRAY_SIZE(ecovec_devices));
+}
+arch_initcall(arch_setup);
+
+static int __init devices_setup(void)
+{
+	sh_eth_init();
+	return 0;
+}
+device_initcall(devices_setup);
+
+
+static struct sh_machine_vector mv_ecovec __initmv = {
+	.mv_name	= "R0P7724 (EcoVec)",
+};
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index 1639f89..566e69d 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
 #include <net/ax88796.h>
 #include <asm/machvec.h>
 #include <mach/highlander.h>
@@ -60,6 +61,11 @@ static struct platform_device r8a66597_usb_host_device = {
 	.resource	= r8a66597_usb_host_resources,
 };
 
+static struct m66592_platdata usbf_platdata = {
+	.xtal = M66592_PLATDATA_XTAL_24MHZ,
+	.vif = 1,
+};
+
 static struct resource m66592_usb_peripheral_resources[] = {
 	[0] = {
 		.name	= "m66592_udc",
@@ -81,6 +87,7 @@ static struct platform_device m66592_usb_peripheral_device = {
 	.dev = {
 		.dma_mask		= NULL,		/* don't use dma */
 		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usbf_platdata,
 	},
 	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
 	.resource	= m66592_usb_peripheral_resources,
diff --git a/arch/sh/boards/mach-kfr2r09/Makefile b/arch/sh/boards/mach-kfr2r09/Makefile
new file mode 100644
index 0000000..5d58678
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/Makefile
@@ -0,0 +1,2 @@
+obj-y	 := setup.o
+obj-$(CONFIG_FB_SH_MOBILE_LCDC)	+=  lcd_wqvga.o
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
new file mode 100644
index 0000000..8ccb1cc
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
@@ -0,0 +1,332 @@
+/*
+ * KFR2R09 LCD panel support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * Register settings based on the out-of-tree t33fb.c driver
+ * Copyright (C) 2008 Lineo Solutions, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <video/sh_mobile_lcdc.h>
+#include <mach/kfr2r09.h>
+#include <cpu/sh7724.h>
+
+/* The on-board LCD module is a Hitachi TX07D34VM0AAA. This module is made
+ * up of a 240x400 LCD hooked up to a R61517 driver IC. The driver IC is
+ * communicating with the main port of the LCDC using an 18-bit SYS interface.
+ *
+ * The device code for this LCD module is 0x01221517.
+ */
+
+static const unsigned char data_frame_if[] = {
+	0x02, /* WEMODE: 1=cont, 0=one-shot */
+	0x00, 0x00,
+	0x00, /* EPF, DFM */
+	0x02, /* RIM[1] : 1 (18bpp) */
+};
+
+static const unsigned char data_panel[] = {
+	0x0b,
+	0x63, /* 400 lines */
+	0x04, 0x00, 0x00, 0x04, 0x11, 0x00, 0x00,
+};
+
+static const unsigned char data_timing[] = {
+	0x00, 0x00, 0x13, 0x08, 0x08,
+};
+
+static const unsigned char data_timing_src[] = {
+	0x11, 0x01, 0x00, 0x01,
+};
+
+static const unsigned char data_gamma[] = {
+	0x01, 0x02, 0x08, 0x23,	0x03, 0x0c, 0x00, 0x06,	0x00, 0x00,
+	0x01, 0x00, 0x0c, 0x23, 0x03, 0x08, 0x02, 0x06, 0x00, 0x00,
+};
+
+static const unsigned char data_power[] = {
+	0x07, 0xc5, 0xdc, 0x02,	0x33, 0x0a,
+};
+
+static unsigned long read_reg(void *sohandle,
+			      struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	return so->read_data(sohandle);
+}
+
+static void write_reg(void *sohandle,
+		      struct sh_mobile_lcdc_sys_bus_ops *so,
+		      int i, unsigned long v)
+{
+	if (i)
+		so->write_data(sohandle, v); /* PTH4/LCDRS High [param, 17:0] */
+	else
+		so->write_index(sohandle, v); /* PTH4/LCDRS Low [cmd, 7:0] */
+}
+
+static void write_data(void *sohandle,
+		       struct sh_mobile_lcdc_sys_bus_ops *so,
+		       unsigned char const *data, int no_data)
+{
+	int i;
+
+	for (i = 0; i < no_data; i++)
+		write_reg(sohandle, so, 1, data[i]);
+}
+
+static unsigned long read_device_code(void *sohandle,
+				      struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	unsigned long device_code;
+
+	/* access protect OFF */
+	write_reg(sohandle, so, 0, 0xb0);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* deep standby OFF */
+	write_reg(sohandle, so, 0, 0xb1);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* device code command */
+	write_reg(sohandle, so, 0, 0xbf);
+	mdelay(50);
+
+	/* dummy read */
+	read_reg(sohandle, so);
+
+	/* read device code */
+	device_code = ((read_reg(sohandle, so) & 0xff) << 24);
+	device_code |= ((read_reg(sohandle, so) & 0xff) << 16);
+	device_code |= ((read_reg(sohandle, so) & 0xff) << 8);
+	device_code |= (read_reg(sohandle, so) & 0xff);
+
+	return device_code;
+}
+
+static void write_memory_start(void *sohandle,
+			       struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	write_reg(sohandle, so, 0, 0x2c);
+}
+
+static void clear_memory(void *sohandle,
+			 struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	int i;
+
+	/* write start */
+	write_memory_start(sohandle, so);
+
+	/* paint it black */
+	for (i = 0; i < (240 * 400); i++)
+		write_reg(sohandle, so, 1, 0x00);
+}
+
+static void display_on(void *sohandle,
+		       struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	/* access protect off */
+	write_reg(sohandle, so, 0, 0xb0);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* exit deep standby mode */
+	write_reg(sohandle, so, 0, 0xb1);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* frame memory I/F */
+	write_reg(sohandle, so, 0, 0xb3);
+	write_data(sohandle, so, data_frame_if, ARRAY_SIZE(data_frame_if));
+
+	/* display mode and frame memory write mode */
+	write_reg(sohandle, so, 0, 0xb4);
+	write_reg(sohandle, so, 1, 0x00); /* DBI, internal clock */
+
+	/* panel */
+	write_reg(sohandle, so, 0, 0xc0);
+	write_data(sohandle, so, data_panel, ARRAY_SIZE(data_panel));
+
+	/* timing (normal) */
+	write_reg(sohandle, so, 0, 0xc1);
+	write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+	/* timing (partial) */
+	write_reg(sohandle, so, 0, 0xc2);
+	write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+	/* timing (idle) */
+	write_reg(sohandle, so, 0, 0xc3);
+	write_data(sohandle, so, data_timing, ARRAY_SIZE(data_timing));
+
+	/* timing (source/VCOM/gate driving) */
+	write_reg(sohandle, so, 0, 0xc4);
+	write_data(sohandle, so, data_timing_src, ARRAY_SIZE(data_timing_src));
+
+	/* gamma (red) */
+	write_reg(sohandle, so, 0, 0xc8);
+	write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+	/* gamma (green) */
+	write_reg(sohandle, so, 0, 0xc9);
+	write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+	/* gamma (blue) */
+	write_reg(sohandle, so, 0, 0xca);
+	write_data(sohandle, so, data_gamma, ARRAY_SIZE(data_gamma));
+
+	/* power (common) */
+	write_reg(sohandle, so, 0, 0xd0);
+	write_data(sohandle, so, data_power, ARRAY_SIZE(data_power));
+
+	/* VCOM */
+	write_reg(sohandle, so, 0, 0xd1);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x0f);
+	write_reg(sohandle, so, 1, 0x02);
+
+	/* power (normal) */
+	write_reg(sohandle, so, 0, 0xd2);
+	write_reg(sohandle, so, 1, 0x63);
+	write_reg(sohandle, so, 1, 0x24);
+
+	/* power (partial) */
+	write_reg(sohandle, so, 0, 0xd3);
+	write_reg(sohandle, so, 1, 0x63);
+	write_reg(sohandle, so, 1, 0x24);
+
+	/* power (idle) */
+	write_reg(sohandle, so, 0, 0xd4);
+	write_reg(sohandle, so, 1, 0x63);
+	write_reg(sohandle, so, 1, 0x24);
+
+	write_reg(sohandle, so, 0, 0xd8);
+	write_reg(sohandle, so, 1, 0x77);
+	write_reg(sohandle, so, 1, 0x77);
+
+	/* TE signal */
+	write_reg(sohandle, so, 0, 0x35);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* TE signal line */
+	write_reg(sohandle, so, 0, 0x44);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+
+	/* column address */
+	write_reg(sohandle, so, 0, 0x2a);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0xef);
+
+	/* page address */
+	write_reg(sohandle, so, 0, 0x2b);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x00);
+	write_reg(sohandle, so, 1, 0x01);
+	write_reg(sohandle, so, 1, 0x8f);
+
+	/* exit sleep mode */
+	write_reg(sohandle, so, 0, 0x11);
+
+	mdelay(120);
+
+	/* clear vram */
+	clear_memory(sohandle, so);
+
+	/* display ON */
+	write_reg(sohandle, so, 0, 0x29);
+	mdelay(1);
+
+	write_memory_start(sohandle, so);
+}
+
+int kfr2r09_lcd_setup(void *board_data, void *sohandle,
+		      struct sh_mobile_lcdc_sys_bus_ops *so)
+{
+	/* power on */
+	gpio_set_value(GPIO_PTF4, 0);  /* PROTECT/ -> L */
+	gpio_set_value(GPIO_PTE4, 0);  /* LCD_RST/ -> L */
+	gpio_set_value(GPIO_PTF4, 1);  /* PROTECT/ -> H */
+	udelay(1100);
+	gpio_set_value(GPIO_PTE4, 1);  /* LCD_RST/ -> H */
+	udelay(10);
+	gpio_set_value(GPIO_PTF4, 0);  /* PROTECT/ -> L */
+	mdelay(20);
+
+	if (read_device_code(sohandle, so) != 0x01221517)
+		return -ENODEV;
+
+	pr_info("KFR2R09 WQVGA LCD Module detected.\n");
+
+	display_on(sohandle, so);
+	return 0;
+}
+
+#define CTRL_CKSW       0x10
+#define CTRL_C10        0x20
+#define CTRL_CPSW       0x80
+#define MAIN_MLED4      0x40
+#define MAIN_MSW        0x80
+
+static int kfr2r09_lcd_backlight(int on)
+{
+	struct i2c_adapter *a;
+	struct i2c_msg msg;
+	unsigned char buf[2];
+	int ret;
+
+	a = i2c_get_adapter(0);
+	if (!a)
+		return -ENODEV;
+
+	buf[0] = 0x00;
+	if (on)
+		buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW;
+	else
+		buf[1] = 0;
+
+	msg.addr = 0x75;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[0] = 0x01;
+	if (on)
+		buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c;
+	else
+		buf[1] = 0;
+
+	msg.addr = 0x75;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	return 0;
+}
+
+void kfr2r09_lcd_on(void *board_data)
+{
+	kfr2r09_lcd_backlight(1);
+}
+
+void kfr2r09_lcd_off(void *board_data)
+{
+	kfr2r09_lcd_backlight(0);
+}
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
new file mode 100644
index 0000000..c08d33f
--- /dev/null
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -0,0 +1,386 @@
+/*
+ * KFR2R09 board support code
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/onenand.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/usb/r8a66597.h>
+#include <video/sh_mobile_lcdc.h>
+#include <asm/clock.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/sh_keysc.h>
+#include <cpu/sh7724.h>
+#include <mach/kfr2r09.h>
+
+static struct mtd_partition kfr2r09_nor_flash_partitions[] =
+{
+	{
+		.name = "boot",
+		.offset = 0,
+		.size = (4 * 1024 * 1024),
+		.mask_flags = MTD_WRITEABLE,	/* Read-only */
+	},
+	{
+		.name = "other",
+		.offset = MTDPART_OFS_APPEND,
+		.size = MTDPART_SIZ_FULL,
+	},
+};
+
+static struct physmap_flash_data kfr2r09_nor_flash_data = {
+	.width		= 2,
+	.parts		= kfr2r09_nor_flash_partitions,
+	.nr_parts	= ARRAY_SIZE(kfr2r09_nor_flash_partitions),
+};
+
+static struct resource kfr2r09_nor_flash_resources[] = {
+	[0] = {
+		.name		= "NOR Flash",
+		.start		= 0x00000000,
+		.end		= 0x03ffffff,
+		.flags		= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device kfr2r09_nor_flash_device = {
+	.name		= "physmap-flash",
+	.resource	= kfr2r09_nor_flash_resources,
+	.num_resources	= ARRAY_SIZE(kfr2r09_nor_flash_resources),
+	.dev		= {
+		.platform_data = &kfr2r09_nor_flash_data,
+	},
+};
+
+static struct resource kfr2r09_nand_flash_resources[] = {
+	[0] = {
+		.name		= "NAND Flash",
+		.start		= 0x10000000,
+		.end		= 0x1001ffff,
+		.flags		= IORESOURCE_MEM,
+	}
+};
+
+static struct platform_device kfr2r09_nand_flash_device = {
+	.name		= "onenand-flash",
+	.resource	= kfr2r09_nand_flash_resources,
+	.num_resources	= ARRAY_SIZE(kfr2r09_nand_flash_resources),
+};
+
+static struct sh_keysc_info kfr2r09_sh_keysc_info = {
+	.mode = SH_KEYSC_MODE_1, /* KEYOUT0->4, KEYIN0->4 */
+	.scan_timing = 3,
+	.delay = 10,
+	.keycodes = {
+		KEY_PHONE, KEY_CLEAR, KEY_MAIL, KEY_WWW, KEY_ENTER,
+		KEY_1, KEY_2, KEY_3, 0, KEY_UP,
+		KEY_4, KEY_5, KEY_6, 0, KEY_LEFT,
+		KEY_7, KEY_8, KEY_9, KEY_PROG1, KEY_RIGHT,
+		KEY_S, KEY_0, KEY_P, KEY_PROG2, KEY_DOWN,
+		0, 0, 0, 0, 0
+	},
+};
+
+static struct resource kfr2r09_sh_keysc_resources[] = {
+	[0] = {
+		.name	= "KEYSC",
+		.start  = 0x044b0000,
+		.end    = 0x044b000f,
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = 79,
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kfr2r09_sh_keysc_device = {
+	.name           = "sh_keysc",
+	.id             = 0, /* "keysc0" clock */
+	.num_resources  = ARRAY_SIZE(kfr2r09_sh_keysc_resources),
+	.resource       = kfr2r09_sh_keysc_resources,
+	.dev	= {
+		.platform_data	= &kfr2r09_sh_keysc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
+};
+
+static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
+	.clock_source = LCDC_CLK_BUS,
+	.ch[0] = {
+		.chan = LCDC_CHAN_MAINLCD,
+		.bpp = 16,
+		.interface_type = SYS18,
+		.clock_divider = 6,
+		.flags = LCDC_FLAGS_DWPOL,
+		.lcd_cfg = {
+			.name = "TX07D34VM0AAA",
+			.xres = 240,
+			.yres = 400,
+			.left_margin = 0,
+			.right_margin = 16,
+			.hsync_len = 8,
+			.upper_margin = 0,
+			.lower_margin = 1,
+			.vsync_len = 1,
+			.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+		},
+		.lcd_size_cfg = {
+			.width = 35,
+			.height = 58,
+		},
+		.board_cfg = {
+			.setup_sys = kfr2r09_lcd_setup,
+			.display_on = kfr2r09_lcd_on,
+			.display_off = kfr2r09_lcd_off,
+		},
+		.sys_bus_cfg = {
+			.ldmt2r = 0x07010904,
+			.ldmt3r = 0x14012914,
+			/* set 1s delay to encourage fsync() */
+			.deferred_io_msec = 1000,
+		},
+	}
+};
+
+static struct resource kfr2r09_sh_lcdc_resources[] = {
+	[0] = {
+		.name	= "LCDC",
+		.start	= 0xfe940000, /* P4-only space */
+		.end	= 0xfe942fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 106,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device kfr2r09_sh_lcdc_device = {
+	.name		= "sh_mobile_lcdc_fb",
+	.num_resources	= ARRAY_SIZE(kfr2r09_sh_lcdc_resources),
+	.resource	= kfr2r09_sh_lcdc_resources,
+	.dev	= {
+		.platform_data	= &kfr2r09_sh_lcdc_info,
+	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
+};
+
+static struct r8a66597_platdata kfr2r09_usb0_gadget_data = {
+	.on_chip = 1,
+};
+
+static struct resource kfr2r09_usb0_gadget_resources[] = {
+	[0] = {
+		.start	= 0x04d80000,
+		.end	= 0x04d80123,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 65,
+		.end	= 65,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device kfr2r09_usb0_gadget_device = {
+	.name		= "r8a66597_udc",
+	.id		= 0,
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data	= &kfr2r09_usb0_gadget_data,
+	},
+	.num_resources	= ARRAY_SIZE(kfr2r09_usb0_gadget_resources),
+	.resource	= kfr2r09_usb0_gadget_resources,
+};
+
+static struct platform_device *kfr2r09_devices[] __initdata = {
+	&kfr2r09_nor_flash_device,
+	&kfr2r09_nand_flash_device,
+	&kfr2r09_sh_keysc_device,
+	&kfr2r09_sh_lcdc_device,
+};
+
+#define BSC_CS0BCR 0xfec10004
+#define BSC_CS0WCR 0xfec10024
+#define BSC_CS4BCR 0xfec10010
+#define BSC_CS4WCR 0xfec10030
+#define PORT_MSELCRB 0xa4050182
+
+#ifdef CONFIG_I2C
+static int kfr2r09_usb0_gadget_i2c_setup(void)
+{
+	struct i2c_adapter *a;
+	struct i2c_msg msg;
+	unsigned char buf[2];
+	int ret;
+
+	a = i2c_get_adapter(0);
+	if (!a)
+		return -ENODEV;
+
+	/* set bit 1 (the second bit) of chip at 0x09, register 0x13 */
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[0] = 0;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 1;
+	msg.flags = I2C_M_RD;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	buf[1] = buf[0] | (1 << 1);
+	buf[0] = 0x13;
+	msg.addr = 0x09;
+	msg.buf = buf;
+	msg.len = 2;
+	msg.flags = 0;
+	ret = i2c_transfer(a, &msg, 1);
+	if (ret != 1)
+		return -ENODEV;
+
+	return 0;
+}
+#else
+static int kfr2r09_usb0_gadget_i2c_setup(void)
+{
+	return -ENODEV;
+}
+#endif
+
+static int kfr2r09_usb0_gadget_setup(void)
+{
+	int plugged_in;
+
+	gpio_request(GPIO_PTN4, NULL); /* USB_DET */
+	gpio_direction_input(GPIO_PTN4);
+	plugged_in = gpio_get_value(GPIO_PTN4);
+	if (!plugged_in)
+		return -ENODEV; /* no cable plugged in */
+
+	if (kfr2r09_usb0_gadget_i2c_setup() != 0)
+		return -ENODEV; /* unable to configure using i2c */
+
+	ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
+	gpio_request(GPIO_FN_PDSTATUS, NULL); /* R-standby disables USB clock */
+	gpio_request(GPIO_PTV6, NULL); /* USBCLK_ON */
+	gpio_direction_output(GPIO_PTV6, 1); /* USBCLK_ON = H */
+	msleep(20); /* wait 20ms to let the clock settle */
+	clk_enable(clk_get(NULL, "usb0"));
+	ctrl_outw(0x0600, 0xa40501d4);
+
+	return 0;
+}
+
+static int __init kfr2r09_devices_setup(void)
+{
+	/* enable SCIF1 serial port for YC401 console support */
+	gpio_request(GPIO_FN_SCIF1_RXD, NULL);
+	gpio_request(GPIO_FN_SCIF1_TXD, NULL);
+
+	/* setup NOR flash at CS0 */
+	ctrl_outl(0x36db0400, BSC_CS0BCR);
+	ctrl_outl(0x00000500, BSC_CS0WCR);
+
+	/* setup NAND flash at CS4 */
+	ctrl_outl(0x36db0400, BSC_CS4BCR);
+	ctrl_outl(0x00000500, BSC_CS4WCR);
+
+	/* setup KEYSC pins */
+	gpio_request(GPIO_FN_KEYOUT0, NULL);
+	gpio_request(GPIO_FN_KEYOUT1, NULL);
+	gpio_request(GPIO_FN_KEYOUT2, NULL);
+	gpio_request(GPIO_FN_KEYOUT3, NULL);
+	gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+	gpio_request(GPIO_FN_KEYIN0, NULL);
+	gpio_request(GPIO_FN_KEYIN1, NULL);
+	gpio_request(GPIO_FN_KEYIN2, NULL);
+	gpio_request(GPIO_FN_KEYIN3, NULL);
+	gpio_request(GPIO_FN_KEYIN4, NULL);
+	gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+
+	/* setup LCDC pins for SYS panel */
+	gpio_request(GPIO_FN_LCDD17, NULL);
+	gpio_request(GPIO_FN_LCDD16, NULL);
+	gpio_request(GPIO_FN_LCDD15, NULL);
+	gpio_request(GPIO_FN_LCDD14, NULL);
+	gpio_request(GPIO_FN_LCDD13, NULL);
+	gpio_request(GPIO_FN_LCDD12, NULL);
+	gpio_request(GPIO_FN_LCDD11, NULL);
+	gpio_request(GPIO_FN_LCDD10, NULL);
+	gpio_request(GPIO_FN_LCDD9, NULL);
+	gpio_request(GPIO_FN_LCDD8, NULL);
+	gpio_request(GPIO_FN_LCDD7, NULL);
+	gpio_request(GPIO_FN_LCDD6, NULL);
+	gpio_request(GPIO_FN_LCDD5, NULL);
+	gpio_request(GPIO_FN_LCDD4, NULL);
+	gpio_request(GPIO_FN_LCDD3, NULL);
+	gpio_request(GPIO_FN_LCDD2, NULL);
+	gpio_request(GPIO_FN_LCDD1, NULL);
+	gpio_request(GPIO_FN_LCDD0, NULL);
+	gpio_request(GPIO_FN_LCDRS, NULL); /* LCD_RS */
+	gpio_request(GPIO_FN_LCDCS, NULL); /* LCD_CS/ */
+	gpio_request(GPIO_FN_LCDRD, NULL); /* LCD_RD/ */
+	gpio_request(GPIO_FN_LCDWR, NULL); /* LCD_WR/ */
+	gpio_request(GPIO_FN_LCDVSYN, NULL); /* LCD_VSYNC */
+	gpio_request(GPIO_PTE4, NULL); /* LCD_RST/ */
+	gpio_direction_output(GPIO_PTE4, 1);
+	gpio_request(GPIO_PTF4, NULL); /* PROTECT/ */
+	gpio_direction_output(GPIO_PTF4, 1);
+	gpio_request(GPIO_PTU0, NULL); /* LEDSTDBY/ */
+	gpio_direction_output(GPIO_PTU0, 1);
+
+	/* setup USB function */
+	if (kfr2r09_usb0_gadget_setup() == 0)
+		platform_device_register(&kfr2r09_usb0_gadget_device);
+
+	return platform_add_devices(kfr2r09_devices,
+				    ARRAY_SIZE(kfr2r09_devices));
+}
+device_initcall(kfr2r09_devices_setup);
+
+/* Return the board specific boot mode pin configuration */
+static int kfr2r09_mode_pins(void)
+{
+	/* MD0=1, MD1=1, MD2=0: Clock Mode 3
+	 * MD3=0: 16-bit Area0 Bus Width
+	 * MD5=1: Little Endian
+	 * MD8=1: Test Mode Disabled
+	 */
+	return MODE_PIN0 | MODE_PIN1 | MODE_PIN5 | MODE_PIN8;
+}
+
+/*
+ * The Machine Vector
+ */
+static struct sh_machine_vector mv_kfr2r09 __initmv = {
+	.mv_name		= "kfr2r09",
+	.mv_mode_pins		= kfr2r09_mode_pins,
+};
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index f9b2e4d..6ed1fd3 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -98,6 +98,9 @@ static struct platform_device sh_keysc_device = {
 	.dev	= {
 		.platform_data	= &sh_keysc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
 };
 
 static struct mtd_partition migor_nor_flash_partitions[] =
@@ -276,7 +279,7 @@ static struct resource migor_lcdc_resources[] = {
 	[0] = {
 		.name	= "LCDC",
 		.start	= 0xfe940000, /* P4-only space */
-		.end	= 0xfe941fff,
+		.end	= 0xfe942fff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -292,6 +295,9 @@ static struct platform_device migor_lcdc_device = {
 	.dev	= {
 		.platform_data	= &sh_mobile_lcdc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
 };
 
 static struct clk *camera_clk;
@@ -379,6 +385,9 @@ static struct platform_device migor_ceu_device = {
 	.dev	= {
 		.platform_data	= &sh_mobile_ceu_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU,
+	},
 };
 
 struct spi_gpio_platform_data sdcard_cn9_platform_data = {
diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c
index af84904..3637407 100644
--- a/arch/sh/boards/mach-se/7722/setup.c
+++ b/arch/sh/boards/mach-se/7722/setup.c
@@ -22,6 +22,7 @@
 #include <asm/io.h>
 #include <asm/heartbeat.h>
 #include <asm/sh_keysc.h>
+#include <cpu/sh7722.h>
 
 /* Heartbeat */
 static struct heartbeat_data heartbeat_data = {
@@ -137,6 +138,9 @@ static struct platform_device sh_keysc_device = {
 	.dev	= {
 		.platform_data	= &sh_keysc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
 };
 
 static struct platform_device *se7722_devices[] __initdata = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 15456a0..00973e0 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -39,7 +39,15 @@
  * SW41 : abxx xxxx  -> a = 0 : Analog  monitor
  *                          1 : Digital monitor
  *                      b = 0 : VGA
- *                          1 : SVGA
+ *                          1 : 720p
+ */
+
+/*
+ * about 720p
+ *
+ * When you use 1280 x 720 lcdc output,
+ * you should change OSC6 lcdc clock from 25.175MHz to 74.25MHz,
+ * and change SW41 to use 720p
  */
 
 /* Heartbeat */
@@ -158,7 +166,7 @@ static struct resource lcdc_resources[] = {
 	[0] = {
 		.name	= "LCDC",
 		.start	= 0xfe940000,
-		.end	= 0xfe941fff,
+		.end	= 0xfe942fff,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -174,6 +182,9 @@ static struct platform_device lcdc_device = {
 	.dev		= {
 		.platform_data	= &lcdc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_LCDC,
+	},
 };
 
 /* CEU0 */
@@ -205,6 +216,9 @@ static struct platform_device ceu0_device = {
 	.dev	= {
 		.platform_data	= &sh_mobile_ceu0_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU0,
+	},
 };
 
 /* CEU1 */
@@ -236,6 +250,9 @@ static struct platform_device ceu1_device = {
 	.dev	= {
 		.platform_data	= &sh_mobile_ceu1_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_CEU1,
+	},
 };
 
 /* KEYSC in SoC (Needs SW33-2 set to ON) */
@@ -274,6 +291,9 @@ static struct platform_device keysc_device = {
 	.dev	= {
 		.platform_data	= &keysc_info,
 	},
+	.archdata = {
+		.hwblk_id = HWBLK_KEYSC,
+	},
 };
 
 /* SH Eth */
@@ -302,15 +322,19 @@ static struct platform_device sh_eth_device = {
 	},
 	.num_resources = ARRAY_SIZE(sh_eth_resources),
 	.resource = sh_eth_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_ETHER,
+	},
 };
 
 static struct r8a66597_platdata sh7724_usb0_host_data = {
+	.on_chip = 1,
 };
 
 static struct resource sh7724_usb0_host_resources[] = {
 	[0] = {
 		.start	= 0xa4d80000,
-		.end	= 0xa4d800ff,
+		.end	= 0xa4d80124 - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -330,6 +354,38 @@ static struct platform_device sh7724_usb0_host_device = {
 	},
 	.num_resources	= ARRAY_SIZE(sh7724_usb0_host_resources),
 	.resource	= sh7724_usb0_host_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_USB0,
+	},
+};
+
+static struct r8a66597_platdata sh7724_usb1_gadget_data = {
+	.on_chip = 1,
+};
+
+static struct resource sh7724_usb1_gadget_resources[] = {
+	[0] = {
+		.start	= 0xa4d90000,
+		.end	= 0xa4d90123,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 66,
+		.end	= 66,
+		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+	},
+};
+
+static struct platform_device sh7724_usb1_gadget_device = {
+	.name		= "r8a66597_udc",
+	.id		= 1, /* USB1 */
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &sh7724_usb1_gadget_data,
+	},
+	.num_resources	= ARRAY_SIZE(sh7724_usb1_gadget_resources),
+	.resource	= sh7724_usb1_gadget_resources,
 };
 
 static struct platform_device *ms7724se_devices[] __initdata = {
@@ -342,6 +398,7 @@ static struct platform_device *ms7724se_devices[] __initdata = {
 	&keysc_device,
 	&sh_eth_device,
 	&sh7724_usb0_host_device,
+	&sh7724_usb1_gadget_device,
 };
 
 #define EEPROM_OP   0xBA206000
@@ -421,9 +478,38 @@ static int __init devices_setup(void)
 	/* turn on USB clocks, use external clock */
 	ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
 
+#ifdef CONFIG_PM
+	/* Let LED9 show STATUS2 */
+	gpio_request(GPIO_FN_STATUS2, NULL);
+
+	/* Lit LED10 show STATUS0 */
+	gpio_request(GPIO_FN_STATUS0, NULL);
+
+	/* Lit LED11 show PDSTATUS */
+	gpio_request(GPIO_FN_PDSTATUS, NULL);
+#else
+	/* Lit LED9 */
+	gpio_request(GPIO_PTJ6, NULL);
+	gpio_direction_output(GPIO_PTJ6, 1);
+	gpio_export(GPIO_PTJ6, 0);
+
+	/* Lit LED10 */
+	gpio_request(GPIO_PTJ5, NULL);
+	gpio_direction_output(GPIO_PTJ5, 1);
+	gpio_export(GPIO_PTJ5, 0);
+
+	/* Lit LED11 */
+	gpio_request(GPIO_PTJ7, NULL);
+	gpio_direction_output(GPIO_PTJ7, 1);
+	gpio_export(GPIO_PTJ7, 0);
+#endif
+
 	/* enable USB0 port */
 	ctrl_outw(0x0600, 0xa40501d4);
 
+	/* enable USB1 port */
+	ctrl_outw(0x0600, 0xa4050192);
+
 	/* enable IRQ 0,1,2 */
 	gpio_request(GPIO_FN_INTC_IRQ0, NULL);
 	gpio_request(GPIO_FN_INTC_IRQ1, NULL);
@@ -546,15 +632,15 @@ static int __init devices_setup(void)
 	sh_eth_init();
 
 	if (sw & SW41_B) {
-		/* SVGA */
-		lcdc_info.ch[0].lcd_cfg.xres         = 800;
-		lcdc_info.ch[0].lcd_cfg.yres         = 600;
-		lcdc_info.ch[0].lcd_cfg.left_margin  = 142;
-		lcdc_info.ch[0].lcd_cfg.right_margin = 52;
-		lcdc_info.ch[0].lcd_cfg.hsync_len    = 96;
-		lcdc_info.ch[0].lcd_cfg.upper_margin = 24;
-		lcdc_info.ch[0].lcd_cfg.lower_margin = 2;
-		lcdc_info.ch[0].lcd_cfg.vsync_len    = 2;
+		/* 720p */
+		lcdc_info.ch[0].lcd_cfg.xres         = 1280;
+		lcdc_info.ch[0].lcd_cfg.yres         = 720;
+		lcdc_info.ch[0].lcd_cfg.left_margin  = 220;
+		lcdc_info.ch[0].lcd_cfg.right_margin = 110;
+		lcdc_info.ch[0].lcd_cfg.hsync_len    = 40;
+		lcdc_info.ch[0].lcd_cfg.upper_margin = 20;
+		lcdc_info.ch[0].lcd_cfg.lower_margin = 5;
+		lcdc_info.ch[0].lcd_cfg.vsync_len    = 5;
 	} else {
 		/* VGA */
 		lcdc_info.ch[0].lcd_cfg.xres         = 640;
diff --git a/arch/sh/boards/mach-x3proto/setup.c b/arch/sh/boards/mach-x3proto/setup.c
index 8913ae3..efe4cb9 100644
--- a/arch/sh/boards/mach-x3proto/setup.c
+++ b/arch/sh/boards/mach-x3proto/setup.c
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/m66592.h>
 #include <asm/ilsel.h>
 
 static struct resource heartbeat_resources[] = {
@@ -89,6 +90,11 @@ static struct platform_device r8a66597_usb_host_device = {
 	.resource	= r8a66597_usb_host_resources,
 };
 
+static struct m66592_platdata usbf_platdata = {
+	.xtal = M66592_PLATDATA_XTAL_24MHZ,
+	.vif = 1,
+};
+
 static struct resource m66592_usb_peripheral_resources[] = {
 	[0] = {
 		.name	= "m66592_udc",
@@ -109,6 +115,7 @@ static struct platform_device m66592_usb_peripheral_device = {
 	.dev = {
 		.dma_mask		= NULL,		/* don't use dma */
 		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usbf_platdata,
 	},
 	.num_resources	= ARRAY_SIZE(m66592_usb_peripheral_resources),
 	.resource	= m66592_usb_peripheral_resources,
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
index aad5edd..541087d 100644
--- a/arch/sh/boot/.gitignore
+++ b/arch/sh/boot/.gitignore
@@ -1,4 +1,3 @@
 zImage
-vmlinux.srec
-uImage
-uImage.srec
+vmlinux*
+uImage*
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index 78efb04..a131687 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -20,8 +20,13 @@ CONFIG_BOOT_LINK_OFFSET	?= 0x00800000
 CONFIG_ZERO_PAGE_OFFSET	?= 0x00001000
 CONFIG_ENTRY_OFFSET	?= 0x00001000
 
-targets := zImage vmlinux.srec uImage uImage.srec
-subdir- := compressed
+suffix-$(CONFIG_KERNEL_GZIP)  := gz
+suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+suffix-$(CONFIG_KERNEL_LZMA)  := lzma
+
+targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz uImage.bz2 uImage.lzma
+extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
+subdir- := compressed romimage
 
 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
 	$(call if_changed,objcopy)
@@ -30,6 +35,13 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
 $(obj)/compressed/vmlinux: FORCE
 	$(Q)$(MAKE) $(build)=$(obj)/compressed $@
 
+$(obj)/romImage: $(obj)/romimage/vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo '  Kernel: $@ is ready'
+
+$(obj)/romimage/vmlinux: $(obj)/zImage FORCE
+	$(Q)$(MAKE) $(build)=$(obj)/romimage $@
+
 KERNEL_MEMORY := 0x00000000
 ifeq ($(CONFIG_PMB_FIXED),y)
 KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
@@ -40,9 +52,6 @@ KERNEL_MEMORY := $(shell /bin/bash -c 'printf "0x%08x" \
 		     $$[$(CONFIG_MEMORY_START)]')
 endif
 
-export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
-       CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY
-
 KERNEL_LOAD	:= $(shell /bin/bash -c 'printf "0x%08x" \
 		     $$[$(CONFIG_PAGE_OFFSET)  + \
 			$(KERNEL_MEMORY) + \
@@ -55,19 +64,30 @@ KERNEL_ENTRY	:= $(shell /bin/bash -c 'printf "0x%08x" \
 
 quiet_cmd_uimage = UIMAGE  $@
       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \
-		   -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
+		   -C $(2) -a $(KERNEL_LOAD) -e $(KERNEL_ENTRY) \
 		   -n 'Linux-$(KERNELRELEASE)' -d $< $@
 
-$(obj)/uImage: $(obj)/vmlinux.bin.gz FORCE
-	$(call if_changed,uimage)
-	@echo '  Image $@ is ready'
-
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
 
 $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,gzip)
 
+$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,bzip2)
+
+$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,lzma)
+
+$(obj)/uImage.bz2: $(obj)/vmlinux.bin.bz2
+	$(call if_changed,uimage,bzip2)
+
+$(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
+	$(call if_changed,uimage,gzip)
+
+$(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
+	$(call if_changed,uimage,lzma)
+
 OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec
 $(obj)/vmlinux.srec: $(obj)/compressed/vmlinux
 	$(call if_changed,objcopy)
@@ -76,5 +96,9 @@ OBJCOPYFLAGS_uImage.srec := -I binary -O srec
 $(obj)/uImage.srec: $(obj)/uImage
 	$(call if_changed,objcopy)
 
-clean-files	+= uImage uImage.srec vmlinux.srec \
-		   vmlinux.bin vmlinux.bin.gz
+$(obj)/uImage: $(obj)/uImage.$(suffix-y)
+	@ln -sf $(notdir $<) $@
+	@echo '  Image $@ is ready'
+
+export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
+       CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET KERNEL_MEMORY suffix-y
diff --git a/arch/sh/boot/compressed/.gitignore b/arch/sh/boot/compressed/.gitignore
new file mode 100644
index 0000000..2374a83
--- /dev/null
+++ b/arch/sh/boot/compressed/.gitignore
@@ -0,0 +1 @@
+vmlinux.bin.*
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 9531bf1..6182eca 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -5,9 +5,10 @@
 #
 
 targets		:= vmlinux vmlinux.bin vmlinux.bin.gz \
-		   head_$(BITS).o misc_$(BITS).o piggy.o
+		   vmlinux.bin.bz2 vmlinux.bin.lzma \
+		   head_$(BITS).o misc.o piggy.o
 
-OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc_$(BITS).o $(obj)/cache.o
+OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
 
 ifdef CONFIG_SH_STANDARD_BIOS
 OBJECTS += $(obj)/../../kernel/sh_bios.o
@@ -23,7 +24,7 @@ IMAGE_OFFSET	:= $(shell /bin/bash -c 'printf "0x%08x" \
 
 LIBGCC	:= $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
-ifeq ($(CONFIG_FUNCTION_TRACER),y)
+ifeq ($(CONFIG_MCOUNT),y)
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
 endif
@@ -38,10 +39,18 @@ $(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
 $(obj)/vmlinux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
 
-$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
+vmlinux.bin.all-y := $(obj)/vmlinux.bin
+
+$(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) FORCE
 	$(call if_changed,gzip)
+$(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,bzip2)
+$(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
+	$(call if_changed,lzma)
 
 OBJCOPYFLAGS += -R .empty_zero_page
 
-$(obj)/piggy.o: $(obj)/piggy.S $(obj)/vmlinux.bin.gz FORCE
-	$(call if_changed,as_o_S)
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
+	$(call if_changed,ld)
diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
index 06ac31f..02a3093 100644
--- a/arch/sh/boot/compressed/head_32.S
+++ b/arch/sh/boot/compressed/head_32.S
@@ -22,7 +22,7 @@ startup:
 	bt	clear_bss
 	sub	r0, r2
 	mov.l	bss_start_addr, r0
-	mov	#0xe0, r1
+	mov	#0xffffffe0, r1
 	and	r1, r0			! align cache line
 	mov.l	text_start_addr, r3
 	mov	r0, r1
diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c
new file mode 100644
index 0000000..fd56a71
--- /dev/null
+++ b/arch/sh/boot/compressed/misc.c
@@ -0,0 +1,149 @@
+/*
+ * arch/sh/boot/compressed/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Adapted for SH by Stuart Menefy, Aug 1999
+ *
+ * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
+ */
+
+#include <asm/uaccess.h>
+#include <asm/addrspace.h>
+#include <asm/page.h>
+#include <asm/sh_bios.h>
+
+/*
+ * gzip declarations
+ */
+
+#define STATIC static
+
+#undef memset
+#undef memcpy
+#define memzero(s, n)     memset ((s), 0, (n))
+
+/* cache.c */
+#define CACHE_ENABLE      0
+#define CACHE_DISABLE     1
+int cache_control(unsigned int command);
+
+extern char input_data[];
+extern int input_len;
+static unsigned char *output;
+
+static void error(char *m);
+
+int puts(const char *);
+
+extern int _text;		/* Defined in vmlinux.lds.S */
+extern int _end;
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#ifdef CONFIG_HAVE_KERNEL_BZIP2
+#define HEAP_SIZE	0x400000
+#else
+#define HEAP_SIZE	0x10000
+#endif
+
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_BZIP2
+#include "../../../../lib/decompress_bunzip2.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+#ifdef CONFIG_SH_STANDARD_BIOS
+size_t strlen(const char *s)
+{
+	int i = 0;
+
+	while (*s++)
+		i++;
+	return i;
+}
+
+int puts(const char *s)
+{
+	int len = strlen(s);
+	sh_bios_console_write(s, len);
+	return len;
+}
+#else
+int puts(const char *s)
+{
+	/* This should be updated to use the sh-sci routines */
+	return 0;
+}
+#endif
+
+void* memset(void* s, int c, size_t n)
+{
+	int i;
+	char *ss = (char*)s;
+
+	for (i=0;i<n;i++) ss[i] = c;
+	return s;
+}
+
+void* memcpy(void* __dest, __const void* __src,
+			    size_t __n)
+{
+	int i;
+	char *d = (char *)__dest, *s = (char *)__src;
+
+	for (i=0;i<__n;i++) d[i] = s[i];
+	return __dest;
+}
+
+static void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+#ifdef CONFIG_SUPERH64
+#define stackalign	8
+#else
+#define stackalign	4
+#endif
+
+#define STACK_SIZE (4096)
+long __attribute__ ((aligned(stackalign))) user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+void decompress_kernel(void)
+{
+	unsigned long output_addr;
+
+#ifdef CONFIG_SUPERH64
+	output_addr = (CONFIG_MEMORY_START + 0x2000);
+#else
+	output_addr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
+#ifdef CONFIG_29BIT
+	output_addr |= P2SEG;
+#endif
+#endif
+
+	output = (unsigned char *)output_addr;
+	free_mem_ptr = (unsigned long)&_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
+	puts("Uncompressing Linux... ");
+	cache_control(CACHE_ENABLE);
+	decompress(input_data, input_len, NULL, NULL, output, NULL, error);
+	cache_control(CACHE_DISABLE);
+	puts("Ok, booting the kernel.\n");
+}
diff --git a/arch/sh/boot/compressed/misc_32.c b/arch/sh/boot/compressed/misc_32.c
deleted file mode 100644
index efdba6b..0000000
--- a/arch/sh/boot/compressed/misc_32.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * arch/sh/boot/compressed/misc.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- *
- * Adapted for SH by Stuart Menefy, Aug 1999
- *
- * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
- */
-
-#include <asm/uaccess.h>
-#include <asm/addrspace.h>
-#include <asm/page.h>
-#ifdef CONFIG_SH_STANDARD_BIOS
-#include <asm/sh_bios.h>
-#endif
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-#undef memset
-#undef memcpy
-#define memzero(s, n)     memset ((s), 0, (n))
-
-typedef unsigned char  uch;
-typedef unsigned short ush;
-typedef unsigned long  ulg;
-
-#define WSIZE 0x8000		/* Window size must be at least 32k, */
-				/* and a power of two */
-
-static uch *inbuf;	     /* input buffer */
-static uch window[WSIZE];    /* Sliding window buffer */
-
-static unsigned insize = 0;  /* valid bytes in inbuf */
-static unsigned inptr = 0;   /* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0;  /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01 /* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
-#define COMMENT      0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED    0x20 /* bit 5 set: file is encrypted */
-#define RESERVED     0xC0 /* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static int  fill_inbuf(void);
-static void flush_window(void);
-static void error(char *m);
-
-extern char input_data[];
-extern int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
-static void error(char *m);
-
-int puts(const char *);
-
-extern int _text;		/* Defined in vmlinux.lds.S */
-extern int _end;
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#define HEAP_SIZE             0x10000
-
-#include "../../../../lib/inflate.c"
-
-#ifdef CONFIG_SH_STANDARD_BIOS
-size_t strlen(const char *s)
-{
-	int i = 0;
-
-	while (*s++)
-		i++;
-	return i;
-}
-
-int puts(const char *s)
-{
-	int len = strlen(s);
-	sh_bios_console_write(s, len);
-	return len;
-}
-#else
-int puts(const char *s)
-{
-	/* This should be updated to use the sh-sci routines */
-	return 0;
-}
-#endif
-
-void* memset(void* s, int c, size_t n)
-{
-	int i;
-	char *ss = (char*)s;
-
-	for (i=0;i<n;i++) ss[i] = c;
-	return s;
-}
-
-void* memcpy(void* __dest, __const void* __src,
-			    size_t __n)
-{
-	int i;
-	char *d = (char *)__dest, *s = (char *)__src;
-
-	for (i=0;i<__n;i++) d[i] = s[i];
-	return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-	if (insize != 0) {
-		error("ran out of input data");
-	}
-
-	inbuf = input_data;
-	insize = input_len;
-	inptr = 1;
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-    ulg c = crc;         /* temporary variable */
-    unsigned n;
-    uch *in, *out, ch;
-
-    in = window;
-    out = &output_data[output_ptr];
-    for (n = 0; n < outcnt; n++) {
-	    ch = *out++ = *in++;
-	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
-    }
-    crc = c;
-    bytes_out += (ulg)outcnt;
-    output_ptr += (ulg)outcnt;
-    outcnt = 0;
-}
-
-static void error(char *x)
-{
-	puts("\n\n");
-	puts(x);
-	puts("\n\n -- System halted");
-
-	while(1);	/* Halt */
-}
-
-#define STACK_SIZE (4096)
-long user_stack [STACK_SIZE];
-long* stack_start = &user_stack[STACK_SIZE];
-
-void decompress_kernel(void)
-{
-	output_data = NULL;
-	output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
-#ifdef CONFIG_29BIT
-	output_ptr |= P2SEG;
-#endif
-	free_mem_ptr = (unsigned long)&_end;
-	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-
-	makecrc();
-	puts("Uncompressing Linux... ");
-	gunzip();
-	puts("Ok, booting the kernel.\n");
-}
diff --git a/arch/sh/boot/compressed/misc_64.c b/arch/sh/boot/compressed/misc_64.c
deleted file mode 100644
index 2941657..0000000
--- a/arch/sh/boot/compressed/misc_64.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * arch/sh/boot/compressed/misc_64.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- *
- * Adapted for SHmedia from sh by Stuart Menefy, May 2002
- */
-
-#include <asm/uaccess.h>
-
-/* cache.c */
-#define CACHE_ENABLE      0
-#define CACHE_DISABLE     1
-int cache_control(unsigned int command);
-
-/*
- * gzip declarations
- */
-
-#define OF(args)  args
-#define STATIC static
-
-#undef memset
-#undef memcpy
-#define memzero(s, n)     memset ((s), 0, (n))
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define WSIZE 0x8000		/* Window size must be at least 32k, */
-				/* and a power of two */
-
-static uch *inbuf;		/* input buffer */
-static uch window[WSIZE];	/* Sliding window buffer */
-
-static unsigned insize = 0;	/* valid bytes in inbuf */
-static unsigned inptr = 0;	/* index of next byte to be processed in inbuf */
-static unsigned outcnt = 0;	/* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG   0x01	/* bit 0 set: file probably ASCII text */
-#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
-#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
-#define COMMENT      0x10	/* bit 4 set: file comment present */
-#define ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
-#define RESERVED     0xC0	/* bit 6,7:   reserved */
-
-#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
-
-/* Diagnostic functions */
-#ifdef DEBUG
-#  define Assert(cond,msg) {if(!(cond)) error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-static int fill_inbuf(void);
-static void flush_window(void);
-static void error(char *m);
-
-extern char input_data[];
-extern int input_len;
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-
-static void error(char *m);
-
-static void puts(const char *);
-
-extern int _text;		/* Defined in vmlinux.lds.S */
-extern int _end;
-static unsigned long free_mem_ptr;
-static unsigned long free_mem_end_ptr;
-
-#define HEAP_SIZE             0x10000
-
-#include "../../../../lib/inflate.c"
-
-void puts(const char *s)
-{
-}
-
-void *memset(void *s, int c, size_t n)
-{
-	int i;
-	char *ss = (char *) s;
-
-	for (i = 0; i < n; i++)
-		ss[i] = c;
-	return s;
-}
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
-	int i;
-	char *d = (char *) __dest, *s = (char *) __src;
-
-	for (i = 0; i < __n; i++)
-		d[i] = s[i];
-	return __dest;
-}
-
-/* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
- */
-static int fill_inbuf(void)
-{
-	if (insize != 0) {
-		error("ran out of input data\n");
-	}
-
-	inbuf = input_data;
-	insize = input_len;
-	inptr = 1;
-	return inbuf[0];
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-static void flush_window(void)
-{
-	ulg c = crc;		/* temporary variable */
-	unsigned n;
-	uch *in, *out, ch;
-
-	in = window;
-	out = &output_data[output_ptr];
-	for (n = 0; n < outcnt; n++) {
-		ch = *out++ = *in++;
-		c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
-	}
-	crc = c;
-	bytes_out += (ulg) outcnt;
-	output_ptr += (ulg) outcnt;
-	outcnt = 0;
-	puts(".");
-}
-
-static void error(char *x)
-{
-	puts("\n\n");
-	puts(x);
-	puts("\n\n -- System halted");
-
-	while (1) ;		/* Halt */
-}
-
-#define STACK_SIZE (4096)
-long __attribute__ ((aligned(8))) user_stack[STACK_SIZE];
-long *stack_start = &user_stack[STACK_SIZE];
-
-void decompress_kernel(void)
-{
-	output_data = (uch *) (CONFIG_MEMORY_START + 0x2000);
-	free_mem_ptr = (unsigned long) &_end;
-	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-
-	makecrc();
-	puts("Uncompressing Linux... ");
-	cache_control(CACHE_ENABLE);
-	gunzip();
-	puts("\n");
-
-#if 0
-	/* When booting from ROM may want to do something like this if the
-	 * boot loader doesn't.
-	 */
-
-	/* Set up the parameters and command line */
-	{
-		volatile unsigned int *parambase =
-		    (int *) (CONFIG_MEMORY_START + 0x1000);
-
-		parambase[0] = 0x1;	/* MOUNT_ROOT_RDONLY */
-		parambase[1] = 0x0;	/* RAMDISK_FLAGS */
-		parambase[2] = 0x0200;	/* ORIG_ROOT_DEV */
-		parambase[3] = 0x0;	/* LOADER_TYPE */
-		parambase[4] = 0x0;	/* INITRD_START */
-		parambase[5] = 0x0;	/* INITRD_SIZE */
-		parambase[6] = 0;
-
-		strcpy((char *) ((int) parambase + 0x100),
-		       "console=ttySC0,38400");
-	}
-#endif
-
-	puts("Ok, booting the kernel.\n");
-
-	cache_control(CACHE_DISABLE);
-}
diff --git a/arch/sh/boot/compressed/piggy.S b/arch/sh/boot/compressed/piggy.S
deleted file mode 100644
index 5660719..0000000
--- a/arch/sh/boot/compressed/piggy.S
+++ /dev/null
@@ -1,8 +0,0 @@
-	.global	input_len, input_data
-	.data
-input_len:
-	.long	input_data_end - input_data
-input_data:
-	.incbin	"arch/sh/boot/compressed/vmlinux.bin.gz"
-input_data_end:
-	.end
diff --git a/arch/sh/boot/compressed/vmlinux.scr b/arch/sh/boot/compressed/vmlinux.scr
new file mode 100644
index 0000000..f02382a
--- /dev/null
+++ b/arch/sh/boot/compressed/vmlinux.scr
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  .rodata.compressed : {
+	input_len = .;
+	LONG(input_data_end - input_data) input_data = .;
+	*(.data)
+	output_len = . - 4;
+	input_data_end = .;
+	}
+}
diff --git a/arch/sh/boot/romimage/Makefile b/arch/sh/boot/romimage/Makefile
new file mode 100644
index 0000000..5806eee
--- /dev/null
+++ b/arch/sh/boot/romimage/Makefile
@@ -0,0 +1,19 @@
+#
+# linux/arch/sh/boot/romimage/Makefile
+#
+# create an image suitable for burning to flash from zImage
+#
+
+targets		:= vmlinux head.o
+
+OBJECTS = $(obj)/head.o
+LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext 0 -e romstart
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE
+	$(call if_changed,ld)
+	@:
+
+LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
+
+$(obj)/piggy.o: $(obj)/vmlinux.scr arch/sh/boot/zImage FORCE
+	$(call if_changed,ld)
diff --git a/arch/sh/boot/romimage/head.S b/arch/sh/boot/romimage/head.S
new file mode 100644
index 0000000..219bc62
--- /dev/null
+++ b/arch/sh/boot/romimage/head.S
@@ -0,0 +1,10 @@
+/*
+ *  linux/arch/sh/boot/romimage/head.S
+ *
+ * Board specific setup code, executed before zImage loader
+ */
+
+.text
+	.global	romstart
+romstart:
+#include <mach/romimage.h>
diff --git a/arch/sh/boot/romimage/vmlinux.scr b/arch/sh/boot/romimage/vmlinux.scr
new file mode 100644
index 0000000..287c08f
--- /dev/null
+++ b/arch/sh/boot/romimage/vmlinux.scr
@@ -0,0 +1,6 @@
+SECTIONS
+{
+  .text : {
+	*(.data)
+	}
+}
diff --git a/arch/sh/configs/ecovec24-romimage_defconfig b/arch/sh/configs/ecovec24-romimage_defconfig
new file mode 100644
index 0000000..9a22c64
--- /dev/null
+++ b/arch/sh/configs/ecovec24-romimage_defconfig
@@ -0,0 +1,1032 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc7
+# Tue Sep  8 13:56:18 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=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_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# 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_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_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA 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 is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+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_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF 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=y
+CONFIG_IOSCHED_DEADLINE=y
+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
+
+#
+# System type
+#
+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
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7757 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# 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
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB 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_SPARSEMEM_STATIC=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_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+# CONFIG_SH_KFR2R09 is not set
+CONFIG_SH_ECOVEC=y
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# 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 is not set
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC0,115200"
+
+#
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_RUNTIME=y
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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_PHONET is not set
+# CONFIG_IEEE802154 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_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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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_UB is not set
+# CONFIG_BLK_DEV_RAM 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=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
+# 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
+
+#
+# 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_SCSI_OSD_INITIATOR 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=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# 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
+# 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_KS8842 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
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# 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 is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# 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
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS 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_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_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_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# 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
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# 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_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# 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 is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# 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_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER 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
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS 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=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# 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 is not set
+# 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 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# 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=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER 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
+# CONFIG_BINARY_PRINTF 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_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig
new file mode 100644
index 0000000..2050a76
--- /dev/null
+++ b/arch/sh/configs/ecovec24_defconfig
@@ -0,0 +1,1558 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc7
+# Wed Aug 26 09:09:07 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=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_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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 is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# 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
+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 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 is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+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_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+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=y
+
+#
+# System type
+#
+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
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7757 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# 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
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB 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_SPARSEMEM_STATIC=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_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+# CONFIG_SH_KFR2R09 is not set
+CONFIG_SH_ECOVEC=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_TMU=y
+# CONFIG_SH_TIMER_CMT is not set
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# 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 is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 root=/dev/nfs ip=dhcp mem=120M memchunk.vpu=4m"
+
+#
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_RUNTIME=y
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+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=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_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=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_PHONET is not set
+# CONFIG_IEEE802154 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_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
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+CONFIG_MAC80211_DEFAULT_PS_VALUE=0
+# 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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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=y
+# 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 is not set
+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 is not set
+
+#
+# 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 is not set
+
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG 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_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+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=y
+# 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_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE 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
+# 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=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE 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_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=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=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SH_ETH=y
+# 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_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_KS8842 is not set
+# CONFIG_KS8851 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
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# 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_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SH_KEYSC=y
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# 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
+# CONFIG_I2C_TINY_USB 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_SH_SCI is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# 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 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_AB3100_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+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_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+CONFIG_SOC_CAMERA=y
+# CONFIG_SOC_CAMERA_MT9M001 is not set
+# CONFIG_SOC_CAMERA_MT9M111 is not set
+# CONFIG_SOC_CAMERA_MT9T031 is not set
+# CONFIG_SOC_CAMERA_MT9V022 is not set
+# CONFIG_SOC_CAMERA_TW9910 is not set
+# CONFIG_SOC_CAMERA_PLATFORM is not set
+# CONFIG_SOC_CAMERA_OV772X is not set
+CONFIG_VIDEO_SH_MOBILE_CEU=y
+# CONFIG_V4L_USB_DRIVERS is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+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 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=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_DEFERRED_IO=y
+# 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_SH_MOBILE_LCDC=y
+# 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
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# 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 is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+CONFIG_LOGO_SUPERH_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
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# 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
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# 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_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# 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=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_SPI=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# 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
+# CONFIG_RTC_DRV_RX8025 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_SH is not set
+# CONFIG_RTC_DRV_GENERIC 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
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=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_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# 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 is not set
+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=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+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 is not set
+# CONFIG_UBIFS_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
+# 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_NILFS2_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=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# 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 is not set
+# 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=y
+# 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 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# 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=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER 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_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+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
+
+#
+# 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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 is not set
+# 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 is not set
+# 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 is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF 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=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/kfr2r09-romimage_defconfig b/arch/sh/configs/kfr2r09-romimage_defconfig
new file mode 100644
index 0000000..c0f9263
--- /dev/null
+++ b/arch/sh/configs/kfr2r09-romimage_defconfig
@@ -0,0 +1,774 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc6
+# Thu Aug 20 15:09:16 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=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_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# 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_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_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+CONFIG_INITRAMFS_COMPRESSION_GZIP=y
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA 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 is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+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_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+# CONFIG_BLOCK is not set
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+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
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# 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
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB 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_SPARSEMEM_STATIC=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_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+CONFIG_SH_KFR2R09=y
+# CONFIG_SH_ECOVEC is not set
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_KEXEC=y
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttySC1,115200 quiet"
+
+#
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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_PHONET is not set
+# CONFIG_IEEE802154 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_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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_NETDEVICES 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 is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# 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
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS 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_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_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_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT 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
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_R8A66597=y
+CONFIG_USB_R8A66597=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# 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_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=y
+
+#
+# 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_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_INOTIFY_USER 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
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS 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
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# 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=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER 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
+# CONFIG_BINARY_PRINTF 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_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig
new file mode 100644
index 0000000..cef6131
--- /dev/null
+++ b/arch/sh/configs/kfr2r09_defconfig
@@ -0,0 +1,1059 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.31-rc6
+# Thu Aug 20 21:58:52 2009
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_CMT=y
+CONFIG_SYS_SUPPORTS_TMU=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_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# 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 is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# 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_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_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA 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 is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
+
+#
+# Performance Counters
+#
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+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_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# 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 is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+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
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+CONFIG_CPU_SUBTYPE_SH7724=y
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# 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
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_X2TLB is not set
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB 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_SPARSEMEM_STATIC=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_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7724_SOLUTION_ENGINE is not set
+CONFIG_SH_KFR2R09=y
+# CONFIG_SH_ECOVEC is not set
+
+#
+# Timer and clock configuration
+#
+# CONFIG_SH_TIMER_TMU is not set
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_SH_CLK_CPG=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+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
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_GUSA=y
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=tty0 console=ttySC1,115200"
+
+#
+# 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
+
+#
+# Power management options (EXPERIMENTAL)
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_SUSPEND is not set
+# CONFIG_HIBERNATION is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_GOV_LADDER=y
+CONFIG_CPU_IDLE_GOV_MENU=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+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_PHONET is not set
+# CONFIG_IEEE802154 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_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=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# 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=y
+# 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 is not set
+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=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# 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 is not set
+
+#
+# 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_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# 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
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG 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 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=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_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SH_KEYSC=y
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=6
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+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_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# 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_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS 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_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_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_AB3100_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+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 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=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_DEFERRED_IO=y
+# 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_SH_MOBILE_LCDC=y
+# 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
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_FONT_MINI_4x6=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_SUPERH_MONO is not set
+CONFIG_LOGO_SUPERH_VGA16=y
+# CONFIG_LOGO_SUPERH_CLUT224 is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_R8A66597=y
+CONFIG_USB_R8A66597=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# 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_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_CDC_COMPOSITE=y
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+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_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# 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 is not set
+# 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
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# 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_SH=y
+# CONFIG_RTC_DRV_GENERIC 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
+# CONFIG_UIO_SMX is not set
+# CONFIG_UIO_SERCOS3 is not set
+
+#
+# TI VLYNQ
+#
+# 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_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE 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_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS 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
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# 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=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FTRACE_SYSCALLS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER 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
+# CONFIG_BINARY_PRINTF 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_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/snapgear_defconfig
index ca3c88a..2be2d75 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.30
-# Thu Jun 18 13:11:58 2009
+# Linux kernel version: 2.6.31-rc6
+# Thu Aug 20 15:03:04 2009
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
@@ -14,6 +14,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
 # CONFIG_GENERIC_GPIO is not set
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CLOCKEVENTS=y
@@ -28,7 +29,9 @@ CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
 CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -38,6 +41,12 @@ CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
 # CONFIG_SWAP is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_POSIX_MQUEUE is not set
@@ -86,10 +95,12 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
 
 #
 # Performance Counters
 #
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 # CONFIG_STRIP_ASM_SYMS is not set
@@ -106,6 +117,10 @@ CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
 # CONFIG_SLOW_WORK is not set
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
@@ -113,7 +128,7 @@ CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 # CONFIG_MODULES is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
+CONFIG_LBDAF=y
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -534,7 +549,11 @@ CONFIG_HAVE_IDE=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# See the help texts for more information.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
@@ -686,6 +705,11 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 # CONFIG_I2C is not set
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
@@ -732,7 +756,44 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# 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
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+CONFIG_RTC_DRV_DS1302=y
+# 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_SH is not set
+# CONFIG_RTC_DRV_GENERIC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
@@ -754,6 +815,7 @@ CONFIG_EXT2_FS=y
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
 # 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_FILE_LOCKING=y
@@ -856,8 +918,11 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_FTRACE_SYSCALLS=y
 CONFIG_TRACING_SUPPORT=y
 # CONFIG_FTRACE is not set
 # CONFIG_DMA_API_DEBUG is not set
@@ -865,6 +930,7 @@ CONFIG_TRACING_SUPPORT=y
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
+# CONFIG_DWARF_UNWINDER is not set
 
 #
 # Security options
@@ -893,5 +959,6 @@ CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
 CONFIG_NLATTR=y
 CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 63e9dd3..b91fa8d 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -27,12 +27,12 @@ config NR_ONCHIP_DMA_CHANNELS
 	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
 		       CPU_SUBTYPE_SH7760
 	default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780  || \
-			CPU_SUBTYPE_SH7785
+			CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7724
 	default "6"
 	help
 	  This allows you to specify the number of channels that the on-chip
-	  DMAC supports. This will be 4 for SH7091/SH7750/SH7751 and 8 for the
-	  SH7750R/SH7751R.
+	  DMAC supports. This will be 4 for SH7750/SH7751/Sh7750S/SH7091 and 8 for the
+	  SH7750R/SH7751R/SH7760, 12 for the SH7723/SH7780/SH7785/SH7724, default is 6.
 
 config NR_DMA_CHANNELS_BOOL
 	depends on SH_DMA
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index 938817e..a9339a6 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -40,14 +40,19 @@ static inline void heartbeat_toggle_bit(struct heartbeat_data *hd,
 	if (inverted)
 		new = ~new;
 
+	new &= hd->mask;
+
 	switch (hd->regsize) {
 	case 32:
+		new |= ioread32(hd->base) & ~hd->mask;
 		iowrite32(new, hd->base);
 		break;
 	case 16:
+		new |= ioread16(hd->base) & ~hd->mask;
 		iowrite16(new, hd->base);
 		break;
 	default:
+		new |= ioread8(hd->base) & ~hd->mask;
 		iowrite8(new, hd->base);
 		break;
 	}
@@ -72,6 +77,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
 {
 	struct resource *res;
 	struct heartbeat_data *hd;
+	int i;
 
 	if (unlikely(pdev->num_resources != 1)) {
 		dev_err(&pdev->dev, "invalid number of resources\n");
@@ -107,6 +113,10 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
 		hd->nr_bits = ARRAY_SIZE(default_bit_pos);
 	}
 
+	hd->mask = 0;
+	for (i = 0; i < hd->nr_bits; i++)
+		hd->mask |= (1 << hd->bit_pos[i]);
+
 	if (!hd->regsize)
 		hd->regsize = 8;	/* default access size */
 
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 9a1c423..c481df6 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -295,6 +295,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       vma->vm_page_prot);
 }
 
+#ifndef CONFIG_GENERIC_IOMAP
+
 static void __iomem *ioport_map_pci(struct pci_dev *dev,
 				    unsigned long port, unsigned int nr)
 {
@@ -346,6 +348,8 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
 }
 EXPORT_SYMBOL(pci_iounmap);
 
+#endif /* CONFIG_GENERIC_IOMAP */
+
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pcibios_resource_to_bus);
 EXPORT_SYMBOL(pcibios_bus_to_resource);
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 43910cd..e121c30 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -1,6 +1,6 @@
 include include/asm-generic/Kbuild.asm
 
-header-y += cpu-features.h
+header-y += cachectl.h cpu-features.h
 
 unifdef-y += unistd_32.h
 unifdef-y += unistd_64.h
diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index c017180..d02c01b 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -2,6 +2,7 @@
 #define __ASM_SH_BUG_H
 
 #define TRAPA_BUG_OPCODE	0xc33e	/* trapa #0x3e */
+#define BUGFLAG_UNWINDER	(1 << 1)
 
 #ifdef CONFIG_GENERIC_BUG
 #define HAVE_ARCH_BUG
@@ -72,6 +73,36 @@ do {							\
 	unlikely(__ret_warn_on);				\
 })
 
+#define UNWINDER_BUG()					\
+do {							\
+	__asm__ __volatile__ (				\
+		"1:\t.short %O0\n"			\
+		_EMIT_BUG_ENTRY				\
+		 :					\
+		 : "n" (TRAPA_BUG_OPCODE),		\
+		   "i" (__FILE__),			\
+		   "i" (__LINE__),			\
+		   "i" (BUGFLAG_UNWINDER),		\
+		   "i" (sizeof(struct bug_entry)));	\
+} while (0)
+
+#define UNWINDER_BUG_ON(x) ({					\
+	int __ret_unwinder_on = !!(x);				\
+	if (__builtin_constant_p(__ret_unwinder_on)) {		\
+		if (__ret_unwinder_on)				\
+			UNWINDER_BUG();				\
+	} else {						\
+		if (unlikely(__ret_unwinder_on))		\
+			UNWINDER_BUG();				\
+	}							\
+	unlikely(__ret_unwinder_on);				\
+})
+
+#else
+
+#define UNWINDER_BUG	BUG
+#define UNWINDER_BUG_ON	BUG_ON
+
 #endif /* CONFIG_GENERIC_BUG */
 
 #include <asm-generic/bug.h>
diff --git a/arch/sh/include/asm/bugs.h b/arch/sh/include/asm/bugs.h
index 4924ff6..46260fc 100644
--- a/arch/sh/include/asm/bugs.h
+++ b/arch/sh/include/asm/bugs.h
@@ -21,25 +21,25 @@ static void __init check_bugs(void)
 
 	current_cpu_data.loops_per_jiffy = loops_per_jiffy;
 
-	switch (current_cpu_data.type) {
-	case CPU_SH7619:
+	switch (current_cpu_data.family) {
+	case CPU_FAMILY_SH2:
 		*p++ = '2';
 		break;
-	case CPU_SH7201 ... CPU_MXG:
+	case CPU_FAMILY_SH2A:
 		*p++ = '2';
 		*p++ = 'a';
 		break;
-	case CPU_SH7705 ... CPU_SH7729:
+	case CPU_FAMILY_SH3:
 		*p++ = '3';
 		break;
-	case CPU_SH7750 ... CPU_SH4_501:
+	case CPU_FAMILY_SH4:
 		*p++ = '4';
 		break;
-	case CPU_SH7763 ... CPU_SHX3:
+	case CPU_FAMILY_SH4A:
 		*p++ = '4';
 		*p++ = 'a';
 		break;
-	case CPU_SH7343 ... CPU_SH7366:
+	case CPU_FAMILY_SH4AL_DSP:
 		*p++ = '4';
 		*p++ = 'a';
 		*p++ = 'l';
@@ -48,15 +48,15 @@ static void __init check_bugs(void)
 		*p++ = 's';
 		*p++ = 'p';
 		break;
-	case CPU_SH5_101 ... CPU_SH5_103:
+	case CPU_FAMILY_SH5:
 		*p++ = '6';
 		*p++ = '4';
 		break;
-	case CPU_SH_NONE:
+	case CPU_FAMILY_UNKNOWN:
 		/*
-		 * Specifically use CPU_SH_NONE rather than default:,
-		 * so we're able to have the compiler whine about
-		 * unhandled enumerations.
+		 * Specifically use CPU_FAMILY_UNKNOWN rather than
+		 * default:, so we're able to have the compiler whine
+		 * about unhandled enumerations.
 		 */
 		break;
 	}
diff --git a/arch/sh/include/asm/cachectl.h b/arch/sh/include/asm/cachectl.h
new file mode 100644
index 0000000..6ffb4b7
--- /dev/null
+++ b/arch/sh/include/asm/cachectl.h
@@ -0,0 +1,19 @@
+#ifndef _SH_CACHECTL_H
+#define _SH_CACHECTL_H
+
+/* Definitions for the cacheflush system call.  */
+
+#define CACHEFLUSH_D_INVAL	0x1	/* invalidate (without write back) */
+#define CACHEFLUSH_D_WB		0x2	/* write back (without invalidate) */
+#define CACHEFLUSH_D_PURGE	0x3	/* writeback and invalidate */
+
+#define CACHEFLUSH_I		0x4
+
+/*
+ * Options for cacheflush system call
+ */
+#define ICACHE	CACHEFLUSH_I		/* flush instruction cache */
+#define DCACHE	CACHEFLUSH_D_PURGE	/* writeback and flush data cache */
+#define BCACHE	(ICACHE|DCACHE)		/* flush both caches */
+
+#endif /* _SH_CACHECTL_H */
diff --git a/arch/sh/include/asm/cacheflush.h b/arch/sh/include/asm/cacheflush.h
index 4c5462d..c29918f 100644
--- a/arch/sh/include/asm/cacheflush.h
+++ b/arch/sh/include/asm/cacheflush.h
@@ -3,45 +3,65 @@
 
 #ifdef __KERNEL__
 
-#ifdef CONFIG_CACHE_OFF
+#include <linux/mm.h>
+
 /*
- * Nothing to do when the cache is disabled, initial flush and explicit
- * disabling is handled at CPU init time.
+ * Cache flushing:
+ *
+ *  - flush_cache_all() flushes entire cache
+ *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
+ *  - flush_cache_dup mm(mm) handles cache flushing when forking
+ *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
+ *  - flush_cache_range(vma, start, end) flushes a range of pages
  *
- * See arch/sh/kernel/cpu/init.c:cache_init().
+ *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
+ *  - flush_icache_range(start, end) flushes(invalidates) a range for icache
+ *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
+ *  - flush_cache_sigtramp(vaddr) flushes the signal trampoline
  */
-#define p3_cache_init()				do { } while (0)
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_dup_mm(mm)			do { } while (0)
-#define flush_cache_range(vma, start, end)	do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
-#define flush_dcache_page(page)			do { } while (0)
-#define flush_icache_range(start, end)		do { } while (0)
-#define flush_icache_page(vma,pg)		do { } while (0)
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-#define __flush_wback_region(start, size)	do { (void)(start); } while (0)
-#define __flush_purge_region(start, size)	do { (void)(start); } while (0)
-#define __flush_invalidate_region(start, size)	do { (void)(start); } while (0)
-#else
-#include <cpu/cacheflush.h>
+extern void (*local_flush_cache_all)(void *args);
+extern void (*local_flush_cache_mm)(void *args);
+extern void (*local_flush_cache_dup_mm)(void *args);
+extern void (*local_flush_cache_page)(void *args);
+extern void (*local_flush_cache_range)(void *args);
+extern void (*local_flush_dcache_page)(void *args);
+extern void (*local_flush_icache_range)(void *args);
+extern void (*local_flush_icache_page)(void *args);
+extern void (*local_flush_cache_sigtramp)(void *args);
 
-/*
- * Consistent DMA requires that the __flush_xxx() primitives must be set
- * for any of the enabled non-coherent caches (most of the UP CPUs),
- * regardless of PIPT or VIPT cache configurations.
- */
+static inline void cache_noop(void *args) { }
+
+extern void (*__flush_wback_region)(void *start, int size);
+extern void (*__flush_purge_region)(void *start, int size);
+extern void (*__flush_invalidate_region)(void *start, int size);
+
+extern void flush_cache_all(void);
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_dup_mm(struct mm_struct *mm);
+extern void flush_cache_page(struct vm_area_struct *vma,
+				unsigned long addr, unsigned long pfn);
+extern void flush_cache_range(struct vm_area_struct *vma,
+				 unsigned long start, unsigned long end);
+extern void flush_dcache_page(struct page *page);
+extern void flush_icache_range(unsigned long start, unsigned long end);
+extern void flush_icache_page(struct vm_area_struct *vma,
+				 struct page *page);
+extern void flush_cache_sigtramp(unsigned long address);
+
+struct flusher_data {
+	struct vm_area_struct *vma;
+	unsigned long addr1, addr2;
+};
 
-/* Flush (write-back only) a region (smaller than a page) */
-extern void __flush_wback_region(void *start, int size);
-/* Flush (write-back & invalidate) a region (smaller than a page) */
-extern void __flush_purge_region(void *start, int size);
-/* Flush (invalidate only) a region (smaller than a page) */
-extern void __flush_invalidate_region(void *start, int size);
-#endif
+#define ARCH_HAS_FLUSH_ANON_PAGE
+extern void __flush_anon_page(struct page *page, unsigned long);
+
+static inline void flush_anon_page(struct vm_area_struct *vma,
+				   struct page *page, unsigned long vmaddr)
+{
+	if (boot_cpu_data.dcache.n_aliases && PageAnon(page))
+		__flush_anon_page(page, vmaddr);
+}
 
 #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
 static inline void flush_kernel_dcache_page(struct page *page)
@@ -49,7 +69,6 @@ static inline void flush_kernel_dcache_page(struct page *page)
 	flush_dcache_page(page);
 }
 
-#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_CACHE_OFF)
 extern void copy_to_user_page(struct vm_area_struct *vma,
 	struct page *page, unsigned long vaddr, void *dst, const void *src,
 	unsigned long len);
@@ -57,23 +76,20 @@ extern void copy_to_user_page(struct vm_area_struct *vma,
 extern void copy_from_user_page(struct vm_area_struct *vma,
 	struct page *page, unsigned long vaddr, void *dst, const void *src,
 	unsigned long len);
-#else
-#define copy_to_user_page(vma, page, vaddr, dst, src, len)	\
-	do {							\
-		flush_cache_page(vma, vaddr, page_to_pfn(page));\
-		memcpy(dst, src, len);				\
-		flush_icache_user_range(vma, page, vaddr, len);	\
-	} while (0)
-
-#define copy_from_user_page(vma, page, vaddr, dst, src, len)	\
-	do {							\
-		flush_cache_page(vma, vaddr, page_to_pfn(page));\
-		memcpy(dst, src, len);				\
-	} while (0)
-#endif
 
 #define flush_cache_vmap(start, end)		flush_cache_all()
 #define flush_cache_vunmap(start, end)		flush_cache_all()
 
+#define flush_dcache_mmap_lock(mapping)		do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
+
+void kmap_coherent_init(void);
+void *kmap_coherent(struct page *page, unsigned long addr);
+void kunmap_coherent(void *kvaddr);
+
+#define PG_dcache_dirty	PG_arch_1
+
+void cpu_cache_init(void);
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_SH_CACHEFLUSH_H */
diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h
index 8688a88..b16debf 100644
--- a/arch/sh/include/asm/device.h
+++ b/arch/sh/include/asm/device.h
@@ -3,7 +3,9 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+
+struct dev_archdata {
+};
 
 struct platform_device;
 /* allocate contiguous memory chunk and fill in struct resource */
@@ -12,3 +14,15 @@ int platform_resource_setup_memory(struct platform_device *pdev,
 
 void plat_early_device_setup(void);
 
+#define PDEV_ARCHDATA_FLAG_INIT 0
+#define PDEV_ARCHDATA_FLAG_IDLE 1
+#define PDEV_ARCHDATA_FLAG_SUSP 2
+
+struct pdev_archdata {
+	int hwblk_id;
+#ifdef CONFIG_PM_RUNTIME
+	unsigned long flags;
+	struct list_head entry;
+	struct mutex mutex;
+#endif
+};
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
index 0c8f8e1..68a5f4c 100644
--- a/arch/sh/include/asm/dma-sh.h
+++ b/arch/sh/include/asm/dma-sh.h
@@ -16,6 +16,7 @@
 
 /* DMAOR contorl: The DMAOR access size is different by CPU.*/
 #if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+    defined(CONFIG_CPU_SUBTYPE_SH7724)	|| \
     defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
     defined(CONFIG_CPU_SUBTYPE_SH7785)
 #define dmaor_read_reg(n) \
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h
new file mode 100644
index 0000000..ced6795
--- /dev/null
+++ b/arch/sh/include/asm/dwarf.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef __ASM_SH_DWARF_H
+#define __ASM_SH_DWARF_H
+
+#ifdef CONFIG_DWARF_UNWINDER
+
+/*
+ * DWARF expression operations
+ */
+#define DW_OP_addr	0x03
+#define DW_OP_deref	0x06
+#define DW_OP_const1u	0x08
+#define DW_OP_const1s	0x09
+#define DW_OP_const2u	0x0a
+#define DW_OP_const2s	0x0b
+#define DW_OP_const4u	0x0c
+#define DW_OP_const4s	0x0d
+#define DW_OP_const8u	0x0e
+#define DW_OP_const8s	0x0f
+#define DW_OP_constu	0x10
+#define DW_OP_consts	0x11
+#define DW_OP_dup	0x12
+#define DW_OP_drop	0x13
+#define DW_OP_over	0x14
+#define DW_OP_pick	0x15
+#define DW_OP_swap	0x16
+#define DW_OP_rot	0x17
+#define DW_OP_xderef	0x18
+#define DW_OP_abs	0x19
+#define DW_OP_and	0x1a
+#define DW_OP_div	0x1b
+#define DW_OP_minus	0x1c
+#define DW_OP_mod	0x1d
+#define DW_OP_mul	0x1e
+#define DW_OP_neg	0x1f
+#define DW_OP_not	0x20
+#define DW_OP_or	0x21
+#define DW_OP_plus	0x22
+#define DW_OP_plus_uconst	0x23
+#define DW_OP_shl	0x24
+#define DW_OP_shr	0x25
+#define DW_OP_shra	0x26
+#define DW_OP_xor	0x27
+#define DW_OP_skip	0x2f
+#define DW_OP_bra	0x28
+#define DW_OP_eq	0x29
+#define DW_OP_ge	0x2a
+#define DW_OP_gt	0x2b
+#define DW_OP_le	0x2c
+#define DW_OP_lt	0x2d
+#define DW_OP_ne	0x2e
+#define DW_OP_lit0	0x30
+#define DW_OP_lit1	0x31
+#define DW_OP_lit2	0x32
+#define DW_OP_lit3	0x33
+#define DW_OP_lit4	0x34
+#define DW_OP_lit5	0x35
+#define DW_OP_lit6	0x36
+#define DW_OP_lit7	0x37
+#define DW_OP_lit8	0x38
+#define DW_OP_lit9	0x39
+#define DW_OP_lit10	0x3a
+#define DW_OP_lit11	0x3b
+#define DW_OP_lit12	0x3c
+#define DW_OP_lit13	0x3d
+#define DW_OP_lit14	0x3e
+#define DW_OP_lit15	0x3f
+#define DW_OP_lit16	0x40
+#define DW_OP_lit17	0x41
+#define DW_OP_lit18	0x42
+#define DW_OP_lit19	0x43
+#define DW_OP_lit20	0x44
+#define DW_OP_lit21	0x45
+#define DW_OP_lit22	0x46
+#define DW_OP_lit23	0x47
+#define DW_OP_lit24	0x48
+#define DW_OP_lit25	0x49
+#define DW_OP_lit26	0x4a
+#define DW_OP_lit27	0x4b
+#define DW_OP_lit28	0x4c
+#define DW_OP_lit29	0x4d
+#define DW_OP_lit30	0x4e
+#define DW_OP_lit31	0x4f
+#define DW_OP_reg0	0x50
+#define DW_OP_reg1	0x51
+#define DW_OP_reg2	0x52
+#define DW_OP_reg3	0x53
+#define DW_OP_reg4	0x54
+#define DW_OP_reg5	0x55
+#define DW_OP_reg6	0x56
+#define DW_OP_reg7	0x57
+#define DW_OP_reg8	0x58
+#define DW_OP_reg9	0x59
+#define DW_OP_reg10	0x5a
+#define DW_OP_reg11	0x5b
+#define DW_OP_reg12	0x5c
+#define DW_OP_reg13	0x5d
+#define DW_OP_reg14	0x5e
+#define DW_OP_reg15	0x5f
+#define DW_OP_reg16	0x60
+#define DW_OP_reg17	0x61
+#define DW_OP_reg18	0x62
+#define DW_OP_reg19	0x63
+#define DW_OP_reg20	0x64
+#define DW_OP_reg21	0x65
+#define DW_OP_reg22	0x66
+#define DW_OP_reg23	0x67
+#define DW_OP_reg24	0x68
+#define DW_OP_reg25	0x69
+#define DW_OP_reg26	0x6a
+#define DW_OP_reg27	0x6b
+#define DW_OP_reg28	0x6c
+#define DW_OP_reg29	0x6d
+#define DW_OP_reg30	0x6e
+#define DW_OP_reg31	0x6f
+#define DW_OP_breg0	0x70
+#define DW_OP_breg1	0x71
+#define DW_OP_breg2	0x72
+#define DW_OP_breg3	0x73
+#define DW_OP_breg4	0x74
+#define DW_OP_breg5	0x75
+#define DW_OP_breg6	0x76
+#define DW_OP_breg7	0x77
+#define DW_OP_breg8	0x78
+#define DW_OP_breg9	0x79
+#define DW_OP_breg10	0x7a
+#define DW_OP_breg11	0x7b
+#define DW_OP_breg12	0x7c
+#define DW_OP_breg13	0x7d
+#define DW_OP_breg14	0x7e
+#define DW_OP_breg15	0x7f
+#define DW_OP_breg16	0x80
+#define DW_OP_breg17	0x81
+#define DW_OP_breg18	0x82
+#define DW_OP_breg19	0x83
+#define DW_OP_breg20	0x84
+#define DW_OP_breg21	0x85
+#define DW_OP_breg22	0x86
+#define DW_OP_breg23	0x87
+#define DW_OP_breg24	0x88
+#define DW_OP_breg25	0x89
+#define DW_OP_breg26	0x8a
+#define DW_OP_breg27	0x8b
+#define DW_OP_breg28	0x8c
+#define DW_OP_breg29	0x8d
+#define DW_OP_breg30	0x8e
+#define DW_OP_breg31	0x8f
+#define DW_OP_regx	0x90
+#define DW_OP_fbreg	0x91
+#define DW_OP_bregx	0x92
+#define DW_OP_piece	0x93
+#define DW_OP_deref_size	0x94
+#define DW_OP_xderef_size	0x95
+#define DW_OP_nop	0x96
+#define DW_OP_push_object_address	0x97
+#define DW_OP_call2	0x98
+#define DW_OP_call4	0x99
+#define DW_OP_call_ref	0x9a
+#define DW_OP_form_tls_address	0x9b
+#define DW_OP_call_frame_cfa	0x9c
+#define DW_OP_bit_piece	0x9d
+#define DW_OP_lo_user	0xe0
+#define DW_OP_hi_user	0xff
+
+/*
+ * Addresses used in FDE entries in the .eh_frame section may be encoded
+ * using one of the following encodings.
+ */
+#define DW_EH_PE_absptr	0x00
+#define DW_EH_PE_omit	0xff
+#define DW_EH_PE_uleb128	0x01
+#define DW_EH_PE_udata2	0x02
+#define DW_EH_PE_udata4	0x03
+#define DW_EH_PE_udata8	0x04
+#define DW_EH_PE_sleb128	0x09
+#define DW_EH_PE_sdata2	0x0a
+#define DW_EH_PE_sdata4	0x0b
+#define DW_EH_PE_sdata8	0x0c
+#define DW_EH_PE_signed	0x09
+
+#define DW_EH_PE_pcrel	0x10
+
+/*
+ * The architecture-specific register number that contains the return
+ * address in the .debug_frame table.
+ */
+#define DWARF_ARCH_RA_REG	17
+
+#ifndef __ASSEMBLY__
+/*
+ * Read either the frame pointer (r14) or the stack pointer (r15).
+ * NOTE: this MUST be inlined.
+ */
+static __always_inline unsigned long dwarf_read_arch_reg(unsigned int reg)
+{
+	unsigned long value = 0;
+
+	switch (reg) {
+	case 14:
+		__asm__ __volatile__("mov r14, %0\n" : "=r" (value));
+		break;
+	case 15:
+		__asm__ __volatile__("mov r15, %0\n" : "=r" (value));
+		break;
+	default:
+		BUG();
+	}
+
+	return value;
+}
+
+/**
+ *	dwarf_cie - Common Information Entry
+ */
+struct dwarf_cie {
+	unsigned long length;
+	unsigned long cie_id;
+	unsigned char version;
+	const char *augmentation;
+	unsigned int code_alignment_factor;
+	int data_alignment_factor;
+
+	/* Which column in the rule table represents return addr of func. */
+	unsigned int return_address_reg;
+
+	unsigned char *initial_instructions;
+	unsigned char *instructions_end;
+
+	unsigned char encoding;
+
+	unsigned long cie_pointer;
+
+	struct list_head link;
+
+	unsigned long flags;
+#define DWARF_CIE_Z_AUGMENTATION	(1 << 0)
+};
+
+/**
+ *	dwarf_fde - Frame Description Entry
+ */
+struct dwarf_fde {
+	unsigned long length;
+	unsigned long cie_pointer;
+	struct dwarf_cie *cie;
+	unsigned long initial_location;
+	unsigned long address_range;
+	unsigned char *instructions;
+	unsigned char *end;
+	struct list_head link;
+};
+
+/**
+ *	dwarf_frame - DWARF information for a frame in the call stack
+ */
+struct dwarf_frame {
+	struct dwarf_frame *prev, *next;
+
+	unsigned long pc;
+
+	struct list_head reg_list;
+
+	unsigned long cfa;
+
+	/* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */
+	unsigned int cfa_register;
+	unsigned int cfa_offset;
+
+	/* Valid when DW_FRAME_CFA_REG_EXP is set in flags */
+	unsigned char *cfa_expr;
+	unsigned int cfa_expr_len;
+
+	unsigned long flags;
+#define DWARF_FRAME_CFA_REG_OFFSET	(1 << 0)
+#define DWARF_FRAME_CFA_REG_EXP		(1 << 1)
+
+	unsigned long return_addr;
+};
+
+/**
+ *	dwarf_reg - DWARF register
+ *	@flags: Describes how to calculate the value of this register
+ */
+struct dwarf_reg {
+	struct list_head link;
+
+	unsigned int number;
+
+	unsigned long addr;
+	unsigned long flags;
+#define DWARF_REG_OFFSET	(1 << 0)
+#define DWARF_VAL_OFFSET	(1 << 1)
+#define DWARF_UNDEFINED		(1 << 2)
+};
+
+/*
+ * Call Frame instruction opcodes.
+ */
+#define DW_CFA_advance_loc	0x40
+#define DW_CFA_offset		0x80
+#define DW_CFA_restore		0xc0
+#define DW_CFA_nop		0x00
+#define DW_CFA_set_loc		0x01
+#define DW_CFA_advance_loc1	0x02
+#define DW_CFA_advance_loc2	0x03
+#define DW_CFA_advance_loc4	0x04
+#define DW_CFA_offset_extended	0x05
+#define DW_CFA_restore_extended	0x06
+#define DW_CFA_undefined	0x07
+#define DW_CFA_same_value	0x08
+#define DW_CFA_register		0x09
+#define DW_CFA_remember_state	0x0a
+#define DW_CFA_restore_state	0x0b
+#define DW_CFA_def_cfa		0x0c
+#define DW_CFA_def_cfa_register	0x0d
+#define DW_CFA_def_cfa_offset	0x0e
+#define DW_CFA_def_cfa_expression	0x0f
+#define DW_CFA_expression	0x10
+#define DW_CFA_offset_extended_sf	0x11
+#define DW_CFA_def_cfa_sf	0x12
+#define DW_CFA_def_cfa_offset_sf	0x13
+#define DW_CFA_val_offset	0x14
+#define DW_CFA_val_offset_sf	0x15
+#define DW_CFA_val_expression	0x16
+#define DW_CFA_lo_user		0x1c
+#define DW_CFA_hi_user		0x3f
+
+/* GNU extension opcodes  */
+#define DW_CFA_GNU_args_size	0x2e
+#define DW_CFA_GNU_negative_offset_extended 0x2f
+
+/*
+ * Some call frame instructions encode their operands in the opcode. We
+ * need some helper functions to extract both the opcode and operands
+ * from an instruction.
+ */
+static inline unsigned int DW_CFA_opcode(unsigned long insn)
+{
+	return (insn & 0xc0);
+}
+
+static inline unsigned int DW_CFA_operand(unsigned long insn)
+{
+	return (insn & 0x3f);
+}
+
+#define DW_EH_FRAME_CIE	0		/* .eh_frame CIE IDs are 0 */
+#define DW_CIE_ID	0xffffffff
+#define DW64_CIE_ID	0xffffffffffffffffULL
+
+/*
+ * DWARF FDE/CIE length field values.
+ */
+#define DW_EXT_LO	0xfffffff0
+#define DW_EXT_HI	0xffffffff
+#define DW_EXT_DWARF64	DW_EXT_HI
+
+extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
+					      struct dwarf_frame *);
+#endif /* !__ASSEMBLY__ */
+
+#define CFI_STARTPROC	.cfi_startproc
+#define CFI_ENDPROC	.cfi_endproc
+#define CFI_DEF_CFA	.cfi_def_cfa
+#define CFI_REGISTER	.cfi_register
+#define CFI_REL_OFFSET	.cfi_rel_offset
+#define CFI_UNDEFINED	.cfi_undefined
+
+#else
+
+/*
+ * Use the asm comment character to ignore the rest of the line.
+ */
+#define CFI_IGNORE	!
+
+#define CFI_STARTPROC	CFI_IGNORE
+#define CFI_ENDPROC	CFI_IGNORE
+#define CFI_DEF_CFA	CFI_IGNORE
+#define CFI_REGISTER	CFI_IGNORE
+#define CFI_REL_OFFSET	CFI_IGNORE
+#define CFI_UNDEFINED	CFI_IGNORE
+
+#ifndef __ASSEMBLY__
+static inline void dwarf_unwinder_init(void)
+{
+}
+#endif
+
+#endif /* CONFIG_DWARF_UNWINDER */
+
+#endif /* __ASM_SH_DWARF_H */
diff --git a/arch/sh/include/asm/entry-macros.S b/arch/sh/include/asm/entry-macros.S
index 3a4752a..cc43a55 100644
--- a/arch/sh/include/asm/entry-macros.S
+++ b/arch/sh/include/asm/entry-macros.S
@@ -7,7 +7,7 @@
 	.endm
 
 	.macro	sti
-	mov	#0xf0, r11
+	mov	#0xfffffff0, r11
 	extu.b	r11, r11
 	not	r11, r11
 	stc	sr, r10
@@ -31,8 +31,92 @@
 #endif	
 	.endm
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+	.macro	TRACE_IRQS_ON
+	mov.l	r0, @-r15
+	mov.l	r1, @-r15
+	mov.l	r2, @-r15
+	mov.l	r3, @-r15
+	mov.l	r4, @-r15
+	mov.l	r5, @-r15
+	mov.l	r6, @-r15
+	mov.l	r7, @-r15
+
+	mov.l   7834f, r0
+	jsr	@r0
+	 nop
+
+	mov.l	@r15+, r7
+	mov.l	@r15+, r6
+	mov.l	@r15+, r5
+	mov.l	@r15+, r4
+	mov.l	@r15+, r3
+	mov.l	@r15+, r2
+	mov.l	@r15+, r1
+	mov.l	@r15+, r0
+	mov.l	7834f, r0
+
+	bra	7835f
+	 nop
+	.balign	4
+7834:	.long	trace_hardirqs_on
+7835:
+	.endm
+	.macro	TRACE_IRQS_OFF
+
+	mov.l	r0, @-r15
+	mov.l	r1, @-r15
+	mov.l	r2, @-r15
+	mov.l	r3, @-r15
+	mov.l	r4, @-r15
+	mov.l	r5, @-r15
+	mov.l	r6, @-r15
+	mov.l	r7, @-r15
+
+	mov.l	7834f, r0
+	jsr	@r0
+	 nop
+
+	mov.l	@r15+, r7
+	mov.l	@r15+, r6
+	mov.l	@r15+, r5
+	mov.l	@r15+, r4
+	mov.l	@r15+, r3
+	mov.l	@r15+, r2
+	mov.l	@r15+, r1
+	mov.l	@r15+, r0
+	mov.l	7834f, r0
+
+	bra	7835f
+	 nop
+	.balign	4
+7834:	.long	trace_hardirqs_off
+7835:
+	.endm
+
+#else
+	.macro	TRACE_IRQS_ON
+	.endm
+
+	.macro	TRACE_IRQS_OFF
+	.endm
+#endif
+
 #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
 # define PREF(x)	pref	@x
 #else
 # define PREF(x)	nop
 #endif
+
+	/*
+	 * Macro for use within assembly. Because the DWARF unwinder
+	 * needs to use the frame register to unwind the stack, we
+	 * need to setup r14 with the value of the stack pointer as
+	 * the return address is usually on the stack somewhere.
+	 */
+	.macro	setup_frame_reg
+#ifdef CONFIG_DWARF_UNWINDER
+	mov	r15, r14
+#endif
+	.endm
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 8fea7d8..12f3a31 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -4,6 +4,7 @@
 #ifdef CONFIG_FUNCTION_TRACER
 
 #define MCOUNT_INSN_SIZE	4 /* sizeof mcount call */
+#define FTRACE_SYSCALL_MAX	NR_syscalls
 
 #ifndef __ASSEMBLY__
 extern void mcount(void);
@@ -11,10 +12,13 @@ extern void mcount(void);
 #define MCOUNT_ADDR		((long)(mcount))
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-#define CALLER_ADDR		((long)(ftrace_caller))
+#define CALL_ADDR		((long)(ftrace_call))
 #define STUB_ADDR		((long)(ftrace_stub))
+#define GRAPH_ADDR		((long)(ftrace_graph_call))
+#define CALLER_ADDR		((long)(ftrace_caller))
 
-#define MCOUNT_INSN_OFFSET	((STUB_ADDR - CALLER_ADDR) >> 1)
+#define MCOUNT_INSN_OFFSET	((STUB_ADDR - CALL_ADDR) - 4)
+#define GRAPH_INSN_OFFSET	((CALLER_ADDR - GRAPH_ADDR) - 4)
 
 struct dyn_arch_ftrace {
 	/* No extra data needed on sh */
diff --git a/arch/sh/include/asm/hardirq.h b/arch/sh/include/asm/hardirq.h
index 715ee23..a5be4af 100644
--- a/arch/sh/include/asm/hardirq.h
+++ b/arch/sh/include/asm/hardirq.h
@@ -1,16 +1,9 @@
 #ifndef __ASM_SH_HARDIRQ_H
 #define __ASM_SH_HARDIRQ_H
 
-#include <linux/threads.h>
-#include <linux/irq.h>
-
-/* entry.S is sensitive to the offsets of these fields */
-typedef struct {
-	unsigned int __softirq_pending;
-} ____cacheline_aligned irq_cpustat_t;
-
-#include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-
 extern void ack_bad_irq(unsigned int irq);
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
 
 #endif /* __ASM_SH_HARDIRQ_H */
diff --git a/arch/sh/include/asm/heartbeat.h b/arch/sh/include/asm/heartbeat.h
index 724a43e..caaafe5 100644
--- a/arch/sh/include/asm/heartbeat.h
+++ b/arch/sh/include/asm/heartbeat.h
@@ -11,6 +11,7 @@ struct heartbeat_data {
 	unsigned int nr_bits;
 	struct timer_list timer;
 	unsigned int regsize;
+	unsigned int mask;
 	unsigned long flags;
 };
 
diff --git a/arch/sh/include/asm/hwblk.h b/arch/sh/include/asm/hwblk.h
new file mode 100644
index 0000000..5d3ccae
--- /dev/null
+++ b/arch/sh/include/asm/hwblk.h
@@ -0,0 +1,72 @@
+#ifndef __ASM_SH_HWBLK_H
+#define __ASM_SH_HWBLK_H
+
+#include <asm/clock.h>
+#include <asm/io.h>
+
+#define HWBLK_CNT_USAGE 0
+#define HWBLK_CNT_IDLE 1
+#define HWBLK_CNT_DEVICES 2
+#define HWBLK_CNT_NR 3
+
+#define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */
+
+#define HWBLK_AREA(_flags, _parent)		\
+{						\
+	.flags = _flags,			\
+	.parent = _parent,			\
+}
+
+struct hwblk_area {
+	int cnt[HWBLK_CNT_NR];
+	unsigned char parent;
+	unsigned char flags;
+};
+
+#define HWBLK(_mstp, _bit, _area)		\
+{						\
+	.mstp = (void __iomem *)_mstp,		\
+	.bit = _bit,				\
+	.area = _area,				\
+}
+
+struct hwblk {
+	void __iomem *mstp;
+	unsigned char bit;
+	unsigned char area;
+	int cnt[HWBLK_CNT_NR];
+};
+
+struct hwblk_info {
+	struct hwblk_area *areas;
+	int nr_areas;
+	struct hwblk *hwblks;
+	int nr_hwblks;
+};
+
+/* Should be defined by processor-specific code */
+int arch_hwblk_init(void);
+int arch_hwblk_sleep_mode(void);
+
+int hwblk_register(struct hwblk_info *info);
+int hwblk_init(void);
+
+void hwblk_enable(struct hwblk_info *info, int hwblk);
+void hwblk_disable(struct hwblk_info *info, int hwblk);
+
+void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt);
+void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt);
+
+/* allow clocks to enable and disable hardware blocks */
+#define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags)	\
+{							\
+	.name		= _name,			\
+	.id		= _id,				\
+	.parent		= _parent,			\
+	.arch_flags	= _hwblk,			\
+	.flags		= _flags,			\
+}
+
+int sh_hwblk_clk_register(struct clk *clks, int nr);
+
+#endif /* __ASM_SH_HWBLK_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 2534814..5be45ea 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -92,8 +92,12 @@
 
 static inline void ctrl_delay(void)
 {
-#ifdef P2SEG
+#ifdef CONFIG_CPU_SH4
+	__raw_readw(CCN_PVR);
+#elif defined(P2SEG)
 	__raw_readw(P2SEG);
+#else
+#error "Need a dummy address for delay"
 #endif
 }
 
@@ -146,6 +150,7 @@ __BUILD_MEMORY_STRING(q, u64)
 #define readl_relaxed(a)	readl(a)
 #define readq_relaxed(a)	readq(a)
 
+#ifndef CONFIG_GENERIC_IOMAP
 /* Simple MMIO */
 #define ioread8(a)		__raw_readb(a)
 #define ioread16(a)		__raw_readw(a)
@@ -166,6 +171,15 @@ __BUILD_MEMORY_STRING(q, u64)
 #define iowrite8_rep(a, s, c)	__raw_writesb((a), (s), (c))
 #define iowrite16_rep(a, s, c)	__raw_writesw((a), (s), (c))
 #define iowrite32_rep(a, s, c)	__raw_writesl((a), (s), (c))
+#endif
+
+#define mmio_insb(p,d,c)	__raw_readsb(p,d,c)
+#define mmio_insw(p,d,c)	__raw_readsw(p,d,c)
+#define mmio_insl(p,d,c)	__raw_readsl(p,d,c)
+
+#define mmio_outsb(p,s,c)	__raw_writesb(p,s,c)
+#define mmio_outsw(p,s,c)	__raw_writesw(p,s,c)
+#define mmio_outsl(p,s,c)	__raw_writesl(p,s,c)
 
 /* synco on SH-4A, otherwise a nop */
 #define mmiowb()		wmb()
diff --git a/arch/sh/include/asm/kdebug.h b/arch/sh/include/asm/kdebug.h
index 0b9f896..985219f 100644
--- a/arch/sh/include/asm/kdebug.h
+++ b/arch/sh/include/asm/kdebug.h
@@ -4,6 +4,7 @@
 /* Grossly misnamed. */
 enum die_val {
 	DIE_TRAP,
+	DIE_NMI,
 	DIE_OOPS,
 };
 
diff --git a/arch/sh/include/asm/kgdb.h b/arch/sh/include/asm/kgdb.h
index 72704ed..4235e22 100644
--- a/arch/sh/include/asm/kgdb.h
+++ b/arch/sh/include/asm/kgdb.h
@@ -30,9 +30,6 @@ static inline void arch_kgdb_breakpoint(void)
 	__asm__ __volatile__ ("trapa #0x3c\n");
 }
 
-/* State info */
-extern char in_nmi;		/* Debounce flag to prevent NMI reentry*/
-
 #define BUFMAX                 2048
 
 #define CACHE_FLUSH_IS_SAFE	1
diff --git a/arch/sh/include/asm/lmb.h b/arch/sh/include/asm/lmb.h
new file mode 100644
index 0000000..9b437f6
--- /dev/null
+++ b/arch/sh/include/asm/lmb.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_SH_LMB_H
+#define __ASM_SH_LMB_H
+
+#define LMB_REAL_LIMIT	0
+
+#endif /* __ASM_SH_LMB_H */
diff --git a/arch/sh/include/asm/mmu_context.h b/arch/sh/include/asm/mmu_context.h
index 67d8946..41080b1 100644
--- a/arch/sh/include/asm/mmu_context.h
+++ b/arch/sh/include/asm/mmu_context.h
@@ -69,7 +69,7 @@ static inline void get_mmu_context(struct mm_struct *mm, unsigned int cpu)
 		 * We exhaust ASID of this version.
 		 * Flush all TLB and start new cycle.
 		 */
-		flush_tlb_all();
+		local_flush_tlb_all();
 
 #ifdef CONFIG_SUPERH64
 		/*
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 49592c7..81bffc0 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -50,26 +50,24 @@ extern unsigned long shm_align_mask;
 extern unsigned long max_low_pfn, min_low_pfn;
 extern unsigned long memory_start, memory_end;
 
-extern void clear_page(void *to);
+static inline unsigned long
+pages_do_alias(unsigned long addr1, unsigned long addr2)
+{
+	return (addr1 ^ addr2) & shm_align_mask;
+}
+
+
+#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
 extern void copy_page(void *to, void *from);
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
-	(defined(CONFIG_CPU_SH5) || defined(CONFIG_CPU_SH4) || \
-	 defined(CONFIG_SH7705_CACHE_32KB))
 struct page;
 struct vm_area_struct;
-extern void clear_user_page(void *to, unsigned long address, struct page *page);
-extern void copy_user_page(void *to, void *from, unsigned long address,
-			   struct page *page);
-#if defined(CONFIG_CPU_SH4)
+
 extern void copy_user_highpage(struct page *to, struct page *from,
 			       unsigned long vaddr, struct vm_area_struct *vma);
 #define __HAVE_ARCH_COPY_USER_HIGHPAGE
-#endif
-#else
-#define clear_user_page(page, vaddr, pg)	clear_page(page)
-#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
-#endif
+extern void clear_user_highpage(struct page *page, unsigned long vaddr);
+#define clear_user_highpage	clear_user_highpage
 
 /*
  * These are used to make use of C type-checking..
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index d3633f5..4163950 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -10,7 +10,6 @@
    or architectures with incomplete PCI setup by the loader */
 
 #define pcibios_assign_all_busses()	1
-#define pcibios_scan_all_fns(a, b)	0
 
 /*
  * A board can define one or more PCI channels that represent built-in (or
diff --git a/arch/sh/include/asm/perf_counter.h b/arch/sh/include/asm/perf_counter.h
deleted file mode 100644
index d8e6bb9..0000000
--- a/arch/sh/include/asm/perf_counter.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __ASM_SH_PERF_COUNTER_H
-#define __ASM_SH_PERF_COUNTER_H
-
-/* SH only supports software counters through this interface. */
-static inline void set_perf_counter_pending(void) {}
-
-#define PERF_COUNTER_INDEX_OFFSET	0
-
-#endif /* __ASM_SH_PERF_COUNTER_H */
diff --git a/arch/sh/include/asm/perf_event.h b/arch/sh/include/asm/perf_event.h
new file mode 100644
index 0000000..11a3022
--- /dev/null
+++ b/arch/sh/include/asm/perf_event.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_SH_PERF_EVENT_H
+#define __ASM_SH_PERF_EVENT_H
+
+/* SH only supports software events through this interface. */
+static inline void set_perf_event_pending(void) {}
+
+#define PERF_EVENT_INDEX_OFFSET	0
+
+#endif /* __ASM_SH_PERF_EVENT_H */
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index 2a011b1..4f3efa7 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -36,6 +36,12 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 #define	NEFF_SIGN	(1LL << (NEFF - 1))
 #define	NEFF_MASK	(-1LL << NEFF)
 
+static inline unsigned long long neff_sign_extend(unsigned long val)
+{
+	unsigned long long extended = val;
+	return (extended & NEFF_SIGN) ? (extended | NEFF_MASK) : extended;
+}
+
 #ifdef CONFIG_29BIT
 #define NPHYS		29
 #else
@@ -133,27 +139,25 @@ typedef pte_t *pte_addr_t;
  */
 #define pgtable_cache_init()	do { } while (0)
 
-#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \
-	defined(CONFIG_SH7705_CACHE_32KB))
-struct mm_struct;
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
-#endif
-
 struct vm_area_struct;
-extern void update_mmu_cache(struct vm_area_struct * vma,
-			     unsigned long address, pte_t pte);
+
+extern void __update_cache(struct vm_area_struct *vma,
+			   unsigned long address, pte_t pte);
+extern void __update_tlb(struct vm_area_struct *vma,
+			 unsigned long address, pte_t pte);
+
+static inline void
+update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+	__update_cache(vma, address, pte);
+	__update_tlb(vma, address, pte);
+}
+
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
 extern void paging_init(void);
 extern void page_table_range_init(unsigned long start, unsigned long end,
 				  pgd_t *pgd);
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_CPU_SH4) && defined(CONFIG_MMU)
-extern void kmap_coherent_init(void);
-#else
-#define kmap_coherent_init()	do { } while (0)
-#endif
-
 /* arch/sh/mm/mmap.c */
 #define HAVE_ARCH_UNMAPPED_AREA
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index 72ea209..c0d359c 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -20,7 +20,7 @@
  * - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE.
  *
  * - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages.
- *   Bit 10 is used for _PAGE_ACCESSED, bit 11 remains unused.
+ *   Bit 10 is used for _PAGE_ACCESSED, and bit 11 is used for _PAGE_SPECIAL.
  *
  * - On 29 bit platforms, bits 31 to 29 are used for the space attributes
  *   and timing control which (together with bit 0) are moved into the
@@ -52,6 +52,7 @@
 #define _PAGE_PROTNONE	0x200		/* software: if not present  */
 #define _PAGE_ACCESSED	0x400		/* software: page referenced */
 #define _PAGE_FILE	_PAGE_WT	/* software: pagecache or swap? */
+#define _PAGE_SPECIAL	0x800		/* software: special page */
 
 #define _PAGE_SZ_MASK	(_PAGE_SZ0 | _PAGE_SZ1)
 #define _PAGE_PR_MASK	(_PAGE_RW | _PAGE_USER)
@@ -86,6 +87,14 @@
 #define _PAGE_PCC_ATR8	0x60000000	/* Attribute Memory space, 8 bit bus */
 #define _PAGE_PCC_ATR16	0x60000001	/* Attribute Memory space, 6 bit bus */
 
+#ifndef CONFIG_X2TLB
+/* copy the ptea attributes */
+static inline unsigned long copy_ptea_attributes(unsigned long x)
+{
+	return	((x >> 28) & 0xe) | (x & 0x1);
+}
+#endif
+
 /* Mask which drops unused bits from the PTEL value */
 #if defined(CONFIG_CPU_SH3)
 #define _PAGE_CLEAR_FLAGS	(_PAGE_PROTNONE | _PAGE_ACCESSED| \
@@ -148,8 +157,12 @@
 # define _PAGE_SZHUGE	(_PAGE_FLAGS_HARD)
 #endif
 
+/*
+ * Mask of bits that are to be preserved accross pgprot changes.
+ */
 #define _PAGE_CHG_MASK \
-	(PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | _PAGE_DIRTY)
+	(PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \
+	 _PAGE_DIRTY | _PAGE_SPECIAL)
 
 #ifndef __ASSEMBLY__
 
@@ -328,7 +341,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
 #define pte_dirty(pte)		((pte).pte_low & _PAGE_DIRTY)
 #define pte_young(pte)		((pte).pte_low & _PAGE_ACCESSED)
 #define pte_file(pte)		((pte).pte_low & _PAGE_FILE)
-#define pte_special(pte)	(0)
+#define pte_special(pte)	((pte).pte_low & _PAGE_SPECIAL)
 
 #ifdef CONFIG_X2TLB
 #define pte_write(pte)		((pte).pte_high & _PAGE_EXT_USER_WRITE)
@@ -358,8 +371,9 @@ PTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY);
 PTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY);
 PTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED);
 PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED);
+PTE_BIT_FUNC(low, mkspecial, |= _PAGE_SPECIAL);
 
-static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+#define __HAVE_ARCH_PTE_SPECIAL
 
 /*
  * Macro and implementation to make a page protection as uncachable.
@@ -394,13 +408,19 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 
 /* to find an entry in a page-table-directory. */
 #define pgd_index(address)	(((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-#define pgd_offset(mm, address)	((mm)->pgd+pgd_index(address))
+#define pgd_offset(mm, address)	((mm)->pgd + pgd_index(address))
+#define __pgd_offset(address)	pgd_index(address)
 
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address)	pgd_offset(&init_mm, address)
 
+#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
 /* Find an entry in the third-level page table.. */
 #define pte_index(address)	((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define __pte_offset(address)	pte_index(address)
+
 #define pte_offset_kernel(dir, address) \
 	((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
 #define pte_offset_map(dir, address)		pte_offset_kernel(dir, address)
diff --git a/arch/sh/include/asm/pgtable_64.h b/arch/sh/include/asm/pgtable_64.h
index c78990c..17cdbec 100644
--- a/arch/sh/include/asm/pgtable_64.h
+++ b/arch/sh/include/asm/pgtable_64.h
@@ -60,6 +60,9 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
 /* To find an entry in a kernel PGD. */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
+#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
 /*
  * PMD level access routines. Same notes as above.
  */
@@ -80,6 +83,8 @@ static __inline__ void pmd_set(pmd_t *pmdp,pte_t *ptep)
 #define pte_index(address) \
 		((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
 
+#define __pte_offset(address)	pte_index(address)
+
 #define pte_offset_kernel(dir, addr) \
 		((pte_t *) ((pmd_val(*(dir))) & PAGE_MASK) + pte_index((addr)))
 
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index ff7daaf..017e0c1 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -32,7 +32,7 @@ enum cpu_type {
 
 	/* SH-4A types */
 	CPU_SH7763, CPU_SH7770, CPU_SH7780, CPU_SH7781, CPU_SH7785, CPU_SH7786,
-	CPU_SH7723, CPU_SH7724, CPU_SHX3,
+	CPU_SH7723, CPU_SH7724, CPU_SH7757, CPU_SHX3,
 
 	/* SH4AL-DSP types */
 	CPU_SH7343, CPU_SH7722, CPU_SH7366,
@@ -44,6 +44,17 @@ enum cpu_type {
 	CPU_SH_NONE
 };
 
+enum cpu_family {
+	CPU_FAMILY_SH2,
+	CPU_FAMILY_SH2A,
+	CPU_FAMILY_SH3,
+	CPU_FAMILY_SH4,
+	CPU_FAMILY_SH4A,
+	CPU_FAMILY_SH4AL_DSP,
+	CPU_FAMILY_SH5,
+	CPU_FAMILY_UNKNOWN,
+};
+
 /*
  * TLB information structure
  *
@@ -61,7 +72,7 @@ struct tlb_info {
 };
 
 struct sh_cpuinfo {
-	unsigned int type;
+	unsigned int type, family;
 	int cut_major, cut_minor;
 	unsigned long loops_per_jiffy;
 	unsigned long asid_cache;
diff --git a/arch/sh/include/asm/romimage-macros.h b/arch/sh/include/asm/romimage-macros.h
new file mode 100644
index 0000000..ae17a15
--- /dev/null
+++ b/arch/sh/include/asm/romimage-macros.h
@@ -0,0 +1,73 @@
+#ifndef __ROMIMAGE_MACRO_H
+#define __ROMIMAGE_MACRO_H
+
+/* The LIST command is used to include comments in the script */
+.macro	LIST comment
+.endm
+
+/* The ED command is used to write a 32-bit word */
+.macro  ED, addr, data
+	mov.l 1f, r1
+	mov.l 2f, r0
+	mov.l r0, @r1
+	bra 3f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :	.long \data
+3 :
+.endm
+
+/* The EW command is used to write a 16-bit word */
+.macro  EW, addr, data
+	mov.l 1f, r1
+	mov.l 2f, r0
+	mov.w r0, @r1
+	bra 3f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :	.long \data
+3 :
+.endm
+
+/* The EB command is used to write an 8-bit word */
+.macro  EB, addr, data
+	mov.l 1f, r1
+	mov.l 2f, r0
+	mov.b r0, @r1
+	bra 3f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :	.long \data
+3 :
+.endm
+
+/* The WAIT command is used to delay the execution */
+.macro  WAIT, time
+	mov.l  2f, r3
+1 :
+	nop
+	tst     r3, r3
+	bf/s    1b
+	dt      r3
+	bra	3f
+	 nop
+	.align 2
+2 :	.long \time * 100
+3 :
+.endm
+
+/* The DD command is used to read a 32-bit word */
+.macro  DD, addr, addr2, nr
+	mov.l 1f, r1
+	mov.l @r1, r0
+	bra 2f
+	 nop
+	.align 2
+1 :	.long \addr
+2 :
+.endm
+
+#endif /* __ROMIMAGE_MACRO_H */
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h
index 01a4076..a78701d 100644
--- a/arch/sh/include/asm/sections.h
+++ b/arch/sh/include/asm/sections.h
@@ -7,6 +7,7 @@ extern void __nosave_begin, __nosave_end;
 extern long __machvec_start, __machvec_end;
 extern char __uncached_start, __uncached_end;
 extern char _ebss[];
+extern char __start_eh_frame[], __stop_eh_frame[];
 
 #endif /* __ASM_SH_SECTIONS_H */
 
diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
index bb83258..acf9970 100644
--- a/arch/sh/include/asm/sh_eth.h
+++ b/arch/sh/include/asm/sh_eth.h
@@ -6,6 +6,9 @@ enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
 struct sh_eth_plat_data {
 	int phy;
 	int edmac_endian;
+
+	unsigned no_ether_link:1;
+	unsigned ether_link_active_low:1;
 };
 
 #endif
diff --git a/arch/sh/include/asm/sh_keysc.h b/arch/sh/include/asm/sh_keysc.h
index b5a4dd5..4a65b1e 100644
--- a/arch/sh/include/asm/sh_keysc.h
+++ b/arch/sh/include/asm/sh_keysc.h
@@ -7,6 +7,7 @@ struct sh_keysc_info {
 	enum { SH_KEYSC_MODE_1, SH_KEYSC_MODE_2, SH_KEYSC_MODE_3 } mode;
 	int scan_timing; /* 0 -> 7, see KYCR1, SCN[2:0] */
 	int delay;
+	int kycr2_delay;
 	int keycodes[SH_KEYSC_MAXKEYS];
 };
 
diff --git a/arch/sh/include/asm/stacktrace.h b/arch/sh/include/asm/stacktrace.h
new file mode 100644
index 0000000..7970182
--- /dev/null
+++ b/arch/sh/include/asm/stacktrace.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009  Matt Fleming
+ *
+ * Based on:
+ *	The x86 implementation - arch/x86/include/asm/stacktrace.h
+ */
+#ifndef _ASM_SH_STACKTRACE_H
+#define _ASM_SH_STACKTRACE_H
+
+/* Generic stack tracer with callbacks */
+
+struct stacktrace_ops {
+	void (*warning)(void *data, char *msg);
+	/* msg must contain %s for the symbol */
+	void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
+	void (*address)(void *data, unsigned long address, int reliable);
+	/* On negative return stop dumping */
+	int (*stack)(void *data, char *name);
+};
+
+void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
+		unsigned long *stack,
+		const struct stacktrace_ops *ops, void *data);
+
+#endif /* _ASM_SH_STACKTRACE_H */
diff --git a/arch/sh/include/asm/suspend.h b/arch/sh/include/asm/suspend.h
index b1b9953..5c8ea28 100644
--- a/arch/sh/include/asm/suspend.h
+++ b/arch/sh/include/asm/suspend.h
@@ -10,6 +10,15 @@ struct swsusp_arch_regs {
 	struct pt_regs user_regs;
 	unsigned long bank1_regs[8];
 };
+
+void sh_mobile_call_standby(unsigned long mode);
+
+#ifdef CONFIG_CPU_IDLE
+void sh_mobile_setup_cpuidle(void);
+#else
+static inline void sh_mobile_setup_cpuidle(void) {}
+#endif
+
 #endif
 
 /* flags passed to assembly suspend code */
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
index 6f83f2c..7d80df4 100644
--- a/arch/sh/include/asm/syscall_32.h
+++ b/arch/sh/include/asm/syscall_32.h
@@ -65,6 +65,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
 	case 3: args[2] = regs->regs[6];
 	case 2: args[1] = regs->regs[5];
 	case 1:	args[0] = regs->regs[4];
+	case 0:
 		break;
 	default:
 		BUG();
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index ab79e1f..b5c5acd 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -14,18 +14,6 @@
 
 #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */
 
-#if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5)
-#define __icbi()			\
-{					\
-	unsigned long __addr;		\
-	__addr = 0xa8000000;		\
-	__asm__ __volatile__(		\
-		"icbi   %0\n\t"		\
-		: /* no output */	\
-		: "m" (__m(__addr)));	\
-}
-#endif
-
 /*
  * A brief note on ctrl_barrier(), the control register write barrier.
  *
@@ -44,7 +32,7 @@
 #define mb()		__asm__ __volatile__ ("synco": : :"memory")
 #define rmb()		mb()
 #define wmb()		__asm__ __volatile__ ("synco": : :"memory")
-#define ctrl_barrier()	__icbi()
+#define ctrl_barrier()	__icbi(0xa8000000)
 #define read_barrier_depends()	do { } while(0)
 #else
 #define mb()		__asm__ __volatile__ ("": : :"memory")
@@ -181,6 +169,11 @@ BUILD_TRAP_HANDLER(breakpoint);
 BUILD_TRAP_HANDLER(singlestep);
 BUILD_TRAP_HANDLER(fpu_error);
 BUILD_TRAP_HANDLER(fpu_state_restore);
+BUILD_TRAP_HANDLER(nmi);
+
+#ifdef CONFIG_BUG
+extern void handle_BUG(struct pt_regs *);
+#endif
 
 #define arch_align_stack(x) (x)
 
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 6c68a51..607d413 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -14,12 +14,12 @@ do {									\
 			(u32 *)&tsk->thread.dsp_status;			\
 	__asm__ __volatile__ (						\
 		".balign 4\n\t"						\
+		"movs.l	@r2+, a0\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"					\
@@ -39,20 +39,20 @@ do {									\
 									\
 	__asm__ __volatile__ (						\
 		".balign 4\n\t"						\
-		"stc.l	mod, @-r2\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"	\
+		"sts.l	dsr, @-r2\n\t"					\
+		"movs.l	y1, @-r2\n\t"					\
+		"movs.l	y0, @-r2\n\t"					\
+		"movs.l	x1, @-r2\n\t"					\
+		"movs.l	x0, @-r2\n\t"					\
+		"movs.l	m1, @-r2\n\t"					\
+		"movs.l	m0, @-r2\n\t"					\
+		"movs.l	a1g, @-r2\n\t"					\
+		"movs.l	a0g, @-r2\n\t"					\
+		"movs.l	a1, @-r2\n\t"					\
+		"movs.l	a0, @-r2\n\t"					\
 		: : "r" (__ts2));					\
 } while (0)
 
@@ -63,6 +63,16 @@ do {									\
 #define __restore_dsp(tsk)	do { } while (0)
 #endif
 
+#if defined(CONFIG_CPU_SH4A)
+#define __icbi(addr)	__asm__ __volatile__ ( "icbi @%0\n\t" : : "r" (addr))
+#else
+#define __icbi(addr)	mb()
+#endif
+
+#define __ocbp(addr)	__asm__ __volatile__ ( "ocbp @%0\n\t" : : "r" (addr))
+#define __ocbi(addr)	__asm__ __volatile__ ( "ocbi @%0\n\t" : : "r" (addr))
+#define __ocbwb(addr)	__asm__ __volatile__ ( "ocbwb @%0\n\t" : : "r" (addr))
+
 struct task_struct *__switch_to(struct task_struct *prev,
 				struct task_struct *next);
 
@@ -198,8 +208,13 @@ do {							\
 })
 #endif
 
+static inline reg_size_t register_align(void *val)
+{
+	return (unsigned long)(signed long)val;
+}
+
 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
-			    struct mem_access *ma);
+			    struct mem_access *ma, int);
 
 asmlinkage void do_address_error(struct pt_regs *regs,
 				 unsigned long writeaccess,
diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h
index 943acf5..8e4a03e 100644
--- a/arch/sh/include/asm/system_64.h
+++ b/arch/sh/include/asm/system_64.h
@@ -37,4 +37,14 @@ do {								\
 #define jump_to_uncached()	do { } while (0)
 #define back_to_cached()	do { } while (0)
 
+#define __icbi(addr)	__asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr))
+#define __ocbp(addr)	__asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr))
+#define __ocbi(addr)	__asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr))
+#define __ocbwb(addr)	__asm__ __volatile__ ( "ocbwb %0, 0\n\t" : : "r" (addr))
+
+static inline reg_size_t register_align(void *val)
+{
+	return (unsigned long long)(signed long long)(signed long)val;
+}
+
 #endif /* __ASM_SH_SYSTEM_64_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index d570ac2..bdeb9d4 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -97,7 +97,7 @@ static inline struct thread_info *current_thread_info(void)
 
 extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
 extern void free_thread_info(struct thread_info *ti);
- 
+
 #endif /* THREAD_SHIFT < PAGE_SHIFT */
 
 #endif /* __ASSEMBLY__ */
@@ -116,6 +116,7 @@ extern void free_thread_info(struct thread_info *ti);
 #define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
 #define TIF_SECCOMP		6	/* secure computing */
 #define TIF_NOTIFY_RESUME	7	/* callback before returning to user */
+#define TIF_SYSCALL_TRACEPOINT	8	/* for ftrace syscall instrumentation */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
 #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18
@@ -129,25 +130,27 @@ extern void free_thread_info(struct thread_info *ti);
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
+#define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
 #define _TIF_USEDFPU		(1 << TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_FREEZE		(1 << TIF_FREEZE)
 
 /*
- * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within a byte, or we
+ * _TIF_ALLWORK_MASK and _TIF_WORK_MASK need to fit within 2 bytes, or we
  * blow the tst immediate size constraints and need to fix up
  * arch/sh/kernel/entry-common.S.
  */
 
 /* work to do in syscall trace */
 #define _TIF_WORK_SYSCALL_MASK	(_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | \
-				 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP)
+				 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP    | \
+				 _TIF_SYSCALL_TRACEPOINT)
 
 /* work to do on any return to u-space */
 #define _TIF_ALLWORK_MASK	(_TIF_SYSCALL_TRACE | _TIF_SIGPENDING      | \
 				 _TIF_NEED_RESCHED  | _TIF_SYSCALL_AUDIT   | \
 				 _TIF_SINGLESTEP    | _TIF_RESTORE_SIGMASK | \
-				 _TIF_NOTIFY_RESUME)
+				 _TIF_NOTIFY_RESUME | _TIF_SYSCALL_TRACEPOINT)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK		(_TIF_ALLWORK_MASK & ~(_TIF_SYSCALL_TRACE | \
diff --git a/arch/sh/include/asm/topology.h b/arch/sh/include/asm/topology.h
index b69ee85..f8c40cc 100644
--- a/arch/sh/include/asm/topology.h
+++ b/arch/sh/include/asm/topology.h
@@ -15,14 +15,14 @@
 	.cache_nice_tries	= 2,			\
 	.busy_idx		= 3,			\
 	.idle_idx		= 2,			\
-	.newidle_idx		= 2,			\
-	.wake_idx		= 1,			\
-	.forkexec_idx		= 1,			\
+	.newidle_idx		= 0,			\
+	.wake_idx		= 0,			\
+	.forkexec_idx		= 0,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_FORK	\
 				| SD_BALANCE_EXEC	\
-				| SD_SERIALIZE		\
-				| SD_WAKE_BALANCE,	\
+				| SD_BALANCE_NEWIDLE	\
+				| SD_SERIALIZE,		\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
 	.nr_balance_failed	= 0,			\
diff --git a/arch/sh/include/asm/types.h b/arch/sh/include/asm/types.h
index c7f3c94..f8421f7 100644
--- a/arch/sh/include/asm/types.h
+++ b/arch/sh/include/asm/types.h
@@ -11,8 +11,10 @@
 
 #ifdef CONFIG_SUPERH32
 typedef u16 insn_size_t;
+typedef u32 reg_size_t;
 #else
 typedef u32 insn_size_t;
+typedef u64 reg_size_t;
 #endif
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h
index 61d6ad9..f3fd1b9 100644
--- a/arch/sh/include/asm/unistd_32.h
+++ b/arch/sh/include/asm/unistd_32.h
@@ -132,7 +132,7 @@
 #define __NR_clone		120
 #define __NR_setdomainname	121
 #define __NR_uname		122
-#define __NR_modify_ldt		123
+#define __NR_cacheflush		123
 #define __NR_adjtimex		124
 #define __NR_mprotect		125
 #define __NR_sigprocmask	126
@@ -344,7 +344,7 @@
 #define __NR_preadv		333
 #define __NR_pwritev		334
 #define __NR_rt_tgsigqueueinfo	335
-#define __NR_perf_counter_open	336
+#define __NR_perf_event_open	336
 
 #define NR_syscalls 337
 
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index a751699..343ce8f 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -137,7 +137,7 @@
 #define __NR_clone		120
 #define __NR_setdomainname	121
 #define __NR_uname		122
-#define __NR_modify_ldt		123
+#define __NR_cacheflush		123
 #define __NR_adjtimex		124
 #define __NR_mprotect		125
 #define __NR_sigprocmask	126
@@ -384,7 +384,7 @@
 #define __NR_preadv		361
 #define __NR_pwritev		362
 #define __NR_rt_tgsigqueueinfo	363
-#define __NR_perf_counter_open	364
+#define __NR_perf_event_open	364
 
 #ifdef __KERNEL__
 
diff --git a/arch/sh/include/asm/unwinder.h b/arch/sh/include/asm/unwinder.h
new file mode 100644
index 0000000..1e65c07
--- /dev/null
+++ b/arch/sh/include/asm/unwinder.h
@@ -0,0 +1,31 @@
+#ifndef _LINUX_UNWINDER_H
+#define _LINUX_UNWINDER_H
+
+#include <asm/stacktrace.h>
+
+struct unwinder {
+	const char *name;
+	struct list_head list;
+	int rating;
+	void (*dump)(struct task_struct *, struct pt_regs *,
+		     unsigned long *, const struct stacktrace_ops *, void *);
+};
+
+extern int unwinder_init(void);
+extern int unwinder_register(struct unwinder *);
+
+extern void unwind_stack(struct task_struct *, struct pt_regs *,
+			 unsigned long *, const struct stacktrace_ops *,
+			 void *);
+
+extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
+			      unsigned long *, const struct stacktrace_ops *,
+			      void *);
+
+/*
+ * Used by fault handling code to signal to the unwinder code that it
+ * should switch to a different unwinder.
+ */
+extern int unwinder_faulted;
+
+#endif /* _LINUX_UNWINDER_H */
diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h
new file mode 100644
index 0000000..244ec4a
--- /dev/null
+++ b/arch/sh/include/asm/vmlinux.lds.h
@@ -0,0 +1,17 @@
+#ifndef __ASM_SH_VMLINUX_LDS_H
+#define __ASM_SH_VMLINUX_LDS_H
+
+#include <asm-generic/vmlinux.lds.h>
+
+#ifdef CONFIG_DWARF_UNWINDER
+#define DWARF_EH_FRAME							\
+	.eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) {			\
+		  VMLINUX_SYMBOL(__start_eh_frame) = .;			\
+		  *(.eh_frame)						\
+		  VMLINUX_SYMBOL(__stop_eh_frame) = .;			\
+	}
+#else
+#define DWARF_EH_FRAME
+#endif
+
+#endif /* __ASM_SH_VMLINUX_LDS_H */
diff --git a/arch/sh/include/asm/watchdog.h b/arch/sh/include/asm/watchdog.h
index f024fed..2fe7cee 100644
--- a/arch/sh/include/asm/watchdog.h
+++ b/arch/sh/include/asm/watchdog.h
@@ -13,10 +13,18 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
+#include <linux/io.h>
+
+#define WTCNT_HIGH	0x5a
+#define WTCSR_HIGH	0xa5
+
+#define WTCSR_CKS2	0x04
+#define WTCSR_CKS1	0x02
+#define WTCSR_CKS0	0x01
+
 #include <cpu/watchdog.h>
-#include <asm/io.h>
 
-/* 
+/*
  * See cpu-sh2/watchdog.h for explanation of this stupidity..
  */
 #ifndef WTCNT_R
@@ -27,13 +35,6 @@
 #  define WTCSR_R	WTCSR
 #endif
 
-#define WTCNT_HIGH	0x5a
-#define WTCSR_HIGH	0xa5
-
-#define WTCSR_CKS2	0x04
-#define WTCSR_CKS1	0x02
-#define WTCSR_CKS0	0x01
-
 /*
  * CKS0-2 supports a number of clock division ratios. At the time the watchdog
  * is enabled, it defaults to a 41 usec overflow period .. we overload this to
diff --git a/arch/sh/include/cpu-common/cpu/cacheflush.h b/arch/sh/include/cpu-common/cpu/cacheflush.h
deleted file mode 100644
index c3db00b..0000000
--- a/arch/sh/include/cpu-common/cpu/cacheflush.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * include/asm-sh/cpu-sh2/cacheflush.h
- *
- * Copyright (C) 2003 Paul Mundt
- *
- * 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.
- */
-#ifndef __ASM_CPU_SH2_CACHEFLUSH_H
-#define __ASM_CPU_SH2_CACHEFLUSH_H
-
-/*
- * Cache flushing:
- *
- *  - flush_cache_all() flushes entire cache
- *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
- *  - flush_cache_dup mm(mm) handles cache flushing when forking
- *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
- *  - flush_cache_range(vma, start, end) flushes a range of pages
- *
- *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
- *  - flush_icache_range(start, end) flushes(invalidates) a range for icache
- *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
- *
- *  Caches are indexed (effectively) by physical address on SH-2, so
- *  we don't need them.
- */
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_dup_mm(mm)			do { } while (0)
-#define flush_cache_range(vma, start, end)	do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
-#define flush_dcache_page(page)			do { } while (0)
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-#define flush_icache_range(start, end)		do { } while (0)
-#define flush_icache_page(vma,pg)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-
-#define p3_cache_init()				do { } while (0)
-
-#endif /* __ASM_CPU_SH2_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh2a/cpu/cacheflush.h b/arch/sh/include/cpu-sh2a/cpu/cacheflush.h
deleted file mode 100644
index 3d3b920..0000000
--- a/arch/sh/include/cpu-sh2a/cpu/cacheflush.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __ASM_CPU_SH2A_CACHEFLUSH_H
-#define __ASM_CPU_SH2A_CACHEFLUSH_H
-
-/* 
- * Cache flushing:
- *
- *  - flush_cache_all() flushes entire cache
- *  - flush_cache_mm(mm) flushes the specified mm context's cache lines
- *  - flush_cache_dup mm(mm) handles cache flushing when forking
- *  - flush_cache_page(mm, vmaddr, pfn) flushes a single page
- *  - flush_cache_range(vma, start, end) flushes a range of pages
- *
- *  - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache
- *  - flush_icache_range(start, end) flushes(invalidates) a range for icache
- *  - flush_icache_page(vma, pg) flushes(invalidates) a page for icache
- *
- *  Caches are indexed (effectively) by physical address on SH-2, so
- *  we don't need them.
- */
-#define flush_cache_all()			do { } while (0)
-#define flush_cache_mm(mm)			do { } while (0)
-#define flush_cache_dup_mm(mm)			do { } while (0)
-#define flush_cache_range(vma, start, end)	do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
-#define flush_dcache_page(page)			do { } while (0)
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-void flush_icache_range(unsigned long start, unsigned long end);
-#define flush_icache_page(vma,pg)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-
-#define p3_cache_init()				do { } while (0)
-#endif /* __ASM_CPU_SH2A_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh3/cpu/cacheflush.h b/arch/sh/include/cpu-sh3/cpu/cacheflush.h
deleted file mode 100644
index 1ac27aa..0000000
--- a/arch/sh/include/cpu-sh3/cpu/cacheflush.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * include/asm-sh/cpu-sh3/cacheflush.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- *
- * 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.
- */
-#ifndef __ASM_CPU_SH3_CACHEFLUSH_H
-#define __ASM_CPU_SH3_CACHEFLUSH_H
-
-#if defined(CONFIG_SH7705_CACHE_32KB)
-/* SH7705 is an SH3 processor with 32KB cache. This has alias issues like the
- * SH4. Unlike the SH4 this is a unified cache so we need to do some work
- * in mmap when 'exec'ing a new binary
- */
- /* 32KB cache, 4kb PAGE sizes need to check bit 12 */
-#define CACHE_ALIAS 0x00001000
-
-#define PG_mapped	PG_arch_1
-
-void flush_cache_all(void);
-void flush_cache_mm(struct mm_struct *mm);
-#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-                              unsigned long end);
-void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn);
-void flush_dcache_page(struct page *pg);
-void flush_icache_range(unsigned long start, unsigned long end);
-void flush_icache_page(struct vm_area_struct *vma, struct page *page);
-
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-
-/* SH3 has unified cache so no special action needed here */
-#define flush_cache_sigtramp(vaddr)		do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
-
-#define p3_cache_init()				do { } while (0)
-
-#else
-#include <cpu-common/cpu/cacheflush.h>
-#endif
-
-#endif /* __ASM_CPU_SH3_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/cacheflush.h b/arch/sh/include/cpu-sh4/cpu/cacheflush.h
deleted file mode 100644
index 065306d..0000000
--- a/arch/sh/include/cpu-sh4/cpu/cacheflush.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * include/asm-sh/cpu-sh4/cacheflush.h
- *
- * Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 Paul Mundt
- *
- * 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.
- */
-#ifndef __ASM_CPU_SH4_CACHEFLUSH_H
-#define __ASM_CPU_SH4_CACHEFLUSH_H
-
-/*
- *  Caches are broken on SH-4 (unless we use write-through
- *  caching; in which case they're only semi-broken),
- *  so we need them.
- */
-void flush_cache_all(void);
-void flush_dcache_all(void);
-void flush_cache_mm(struct mm_struct *mm);
-#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end);
-void flush_cache_page(struct vm_area_struct *vma, unsigned long addr,
-		      unsigned long pfn);
-void flush_dcache_page(struct page *pg);
-
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-
-void flush_icache_range(unsigned long start, unsigned long end);
-void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
-			     unsigned long addr, int len);
-
-#define flush_icache_page(vma,pg)		do { } while (0)
-
-/* Initialization of P3 area for copy_user_page */
-void p3_cache_init(void);
-
-#define PG_mapped	PG_arch_1
-
-#endif /* __ASM_CPU_SH4_CACHEFLUSH_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
index 0ed5178..f0886bc 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -16,7 +16,8 @@
 #define DMAE0_IRQ	38
 #define SH_DMAC_BASE0	0xFF608020
 #define SH_DMARS_BASE	0xFF609000
-#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7724)
 #define DMTE0_IRQ	48	/* DMAC0A*/
 #define DMTE4_IRQ	40	/* DMAC0B */
 #define DMTE6_IRQ	42
diff --git a/arch/sh/include/cpu-sh4/cpu/freq.h b/arch/sh/include/cpu-sh4/cpu/freq.h
index ccf1d99..e1e9096 100644
--- a/arch/sh/include/cpu-sh4/cpu/freq.h
+++ b/arch/sh/include/cpu-sh4/cpu/freq.h
@@ -22,6 +22,10 @@
 #define MSTPCR0			0xa4150030
 #define MSTPCR1			0xa4150034
 #define MSTPCR2			0xa4150038
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+#define	FRQCR			0xffc80000
+#define	OSCCR			0xffc80018
+#define	PLLCR			0xffc80024
 #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
       defined(CONFIG_CPU_SUBTYPE_SH7780)
 #define	FRQCR			0xffc80000
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h
index 738ea43..4856040 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7722.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h
@@ -221,4 +221,18 @@ enum {
 	GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYOUT5_IN5,
 };
 
+enum {
+	HWBLK_UNKNOWN = 0,
+	HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_URAM, HWBLK_XYMEM,
+	HWBLK_INTC, HWBLK_DMAC, HWBLK_SHYWAY, HWBLK_HUDI,
+	HWBLK_UBC, HWBLK_TMU, HWBLK_CMT, HWBLK_RWDT, HWBLK_FLCTL,
+	HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SIO,
+	HWBLK_SIOF0, HWBLK_SIOF1, HWBLK_IIC, HWBLK_RTC,
+	HWBLK_TPU, HWBLK_IRDA, HWBLK_SDHI, HWBLK_SIM, HWBLK_KEYSC,
+	HWBLK_TSIF, HWBLK_USBF, HWBLK_2DG, HWBLK_SIU, HWBLK_VOU,
+	HWBLK_JPU, HWBLK_BEU, HWBLK_CEU, HWBLK_VEU, HWBLK_VPU,
+	HWBLK_LCDC,
+	HWBLK_NR,
+};
+
 #endif /* __ASM_SH7722_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7723.h b/arch/sh/include/cpu-sh4/cpu/sh7723.h
index 14c8ca9..9b36fae 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7723.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7723.h
@@ -265,4 +265,21 @@ enum {
 	GPIO_FN_IDEA1, GPIO_FN_IDEA0,
 };
 
+enum {
+	HWBLK_UNKNOWN = 0,
+	HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_L2C, HWBLK_ILMEM, HWBLK_FPU,
+	HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
+	HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC, HWBLK_SUBC,
+	HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
+	HWBLK_FLCTL,
+	HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2,
+	HWBLK_SCIF3, HWBLK_SCIF4, HWBLK_SCIF5,
+	HWBLK_MSIOF0, HWBLK_MSIOF1, HWBLK_MERAM, HWBLK_IIC, HWBLK_RTC,
+	HWBLK_ATAPI, HWBLK_ADC, HWBLK_TPU, HWBLK_IRDA, HWBLK_TSIF, HWBLK_ICB,
+	HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_KEYSC, HWBLK_USB,
+	HWBLK_2DG, HWBLK_SIU, HWBLK_VEU2H1, HWBLK_VOU, HWBLK_BEU, HWBLK_CEU,
+	HWBLK_VEU2H0, HWBLK_VPU, HWBLK_LCDC,
+	HWBLK_NR,
+};
+
 #endif /* __ASM_SH7723_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
index 66fd118..0cd1f71 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7724.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -266,4 +266,21 @@ enum {
 	GPIO_FN_INTC_IRQ1, GPIO_FN_INTC_IRQ0,
 };
 
+enum {
+	HWBLK_UNKNOWN = 0,
+	HWBLK_TLB, HWBLK_IC, HWBLK_OC, HWBLK_RSMEM, HWBLK_ILMEM, HWBLK_L2C,
+	HWBLK_FPU, HWBLK_INTC, HWBLK_DMAC0, HWBLK_SHYWAY,
+	HWBLK_HUDI, HWBLK_DBG, HWBLK_UBC,
+	HWBLK_TMU0, HWBLK_CMT, HWBLK_RWDT, HWBLK_DMAC1, HWBLK_TMU1,
+	HWBLK_SCIF0, HWBLK_SCIF1, HWBLK_SCIF2, HWBLK_SCIF3,
+	HWBLK_SCIF4, HWBLK_SCIF5, HWBLK_MSIOF0, HWBLK_MSIOF1,
+	HWBLK_KEYSC, HWBLK_RTC, HWBLK_IIC0, HWBLK_IIC1,
+	HWBLK_MMC, HWBLK_ETHER, HWBLK_ATAPI, HWBLK_TPU, HWBLK_IRDA,
+	HWBLK_TSIF, HWBLK_USB1, HWBLK_USB0, HWBLK_2DG,
+	HWBLK_SDHI0, HWBLK_SDHI1, HWBLK_VEU1, HWBLK_CEU1, HWBLK_BEU1,
+	HWBLK_2DDMAC, HWBLK_SPU, HWBLK_JPU, HWBLK_VOU,
+	HWBLK_BEU0, HWBLK_CEU0,	HWBLK_VEU0, HWBLK_VPU, HWBLK_LCDC,
+	HWBLK_NR,
+};
+
 #endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h
new file mode 100644
index 0000000..f4d267e
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h
@@ -0,0 +1,243 @@
+#ifndef __ASM_SH7757_H__
+#define __ASM_SH7757_H__
+
+enum {
+	/* PTA */
+	GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
+	GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+
+	/* PTB */
+	GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
+	GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+
+	/* PTC */
+	GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
+	GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+
+	/* PTD */
+	GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
+	GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+
+	/* PTE */
+	GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4,
+	GPIO_PTE3, GPIO_PTE2, GPIO_PTE1, GPIO_PTE0,
+
+	/* PTF */
+	GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4,
+	GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+
+	/* PTG */
+	GPIO_PTG7, GPIO_PTG6, GPIO_PTG5, GPIO_PTG4,
+	GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0,
+
+	/* PTH */
+	GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
+	GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+
+	/* PTI */
+	GPIO_PTI7, GPIO_PTI6, GPIO_PTI5, GPIO_PTI4,
+	GPIO_PTI3, GPIO_PTI2, GPIO_PTI1, GPIO_PTI0,
+
+	/* PTJ */
+	GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5, GPIO_PTJ4,
+	GPIO_PTJ3, GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0,
+
+	/* PTK */
+	GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4,
+	GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+
+	/* PTL */
+	GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
+	GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+
+	/* PTM */
+		   GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
+	GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+
+	/* PTN */
+	GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
+	GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+
+	/* PTO */
+	GPIO_PTO7, GPIO_PTO6, GPIO_PTO5, GPIO_PTO4,
+	GPIO_PTO3, GPIO_PTO2, GPIO_PTO1, GPIO_PTO0,
+
+	/* PTP */
+		   GPIO_PTP6, GPIO_PTP5, GPIO_PTP4,
+	GPIO_PTP3, GPIO_PTP2, GPIO_PTP1, GPIO_PTP0,
+
+	/* PTQ */
+		   GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
+	GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+
+	/* PTR */
+	GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
+	GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+
+	/* PTS */
+	GPIO_PTS7, GPIO_PTS6, GPIO_PTS5, GPIO_PTS4,
+	GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+
+	/* PTT */
+			      GPIO_PTT5, GPIO_PTT4,
+	GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+
+	/* PTU */
+	GPIO_PTU7, GPIO_PTU6, GPIO_PTU5, GPIO_PTU4,
+	GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+
+	/* PTV */
+	GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4,
+	GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+
+	/* PTW */
+	GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4,
+	GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+
+	/* PTX */
+	GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4,
+	GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+
+	/* PTY */
+	GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4,
+	GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0,
+
+	/* PTZ */
+	GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4,
+	GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0,
+
+
+	/* PTA (mobule: LBSC, CPG, LPC) */
+	GPIO_FN_BS,	GPIO_FN_RDWR,	GPIO_FN_WE1,	GPIO_FN_RDY,
+	GPIO_FN_MD10,	GPIO_FN_MD9,	GPIO_FN_MD8,
+	GPIO_FN_LGPIO7,	GPIO_FN_LGPIO6,	GPIO_FN_LGPIO5,	GPIO_FN_LGPIO4,
+	GPIO_FN_LGPIO3,	GPIO_FN_LGPIO2,	GPIO_FN_LGPIO1,	GPIO_FN_LGPIO0,
+
+	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	GPIO_FN_D15,	GPIO_FN_D14,	GPIO_FN_D13,	GPIO_FN_D12,
+	GPIO_FN_D11,	GPIO_FN_D10,	GPIO_FN_D9,	GPIO_FN_D8,
+	GPIO_FN_ET0_MDC,		GPIO_FN_ET0_MDIO,
+	GPIO_FN_ET1_MDC,		GPIO_FN_ET1_MDIO,
+	GPIO_FN_SIM_D,	GPIO_FN_SIM_CLK,		GPIO_FN_SIM_RST,
+	GPIO_FN_WPSZ1,	GPIO_FN_WPSZ0,	GPIO_FN_FWID,	GPIO_FN_FLSHSZ,
+	GPIO_FN_LPC_SPIEN,		GPIO_FN_BASEL,
+
+	/* PTC (mobule: SD) */
+	GPIO_FN_SD_WP,	GPIO_FN_SD_CD,	GPIO_FN_SD_CLK,	GPIO_FN_SD_CMD,
+	GPIO_FN_SD_D3,	GPIO_FN_SD_D2,	GPIO_FN_SD_D1,	GPIO_FN_SD_D0,
+
+	/* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+	GPIO_FN_IRQ7,	GPIO_FN_IRQ6,	GPIO_FN_IRQ5,	GPIO_FN_IRQ4,
+	GPIO_FN_IRQ3,	GPIO_FN_IRQ2,	GPIO_FN_IRQ1,	GPIO_FN_IRQ0,
+	GPIO_FN_MD6,	GPIO_FN_MD5,	GPIO_FN_MD3,	GPIO_FN_MD2,
+	GPIO_FN_MD1,	GPIO_FN_MD0,	GPIO_FN_ADTRG1,	GPIO_FN_ADTRG0,
+
+	/* PTE (mobule: EtherC) */
+	GPIO_FN_ET0_CRS_DV,		GPIO_FN_ET0_TXD1,
+	GPIO_FN_ET0_TXD0,		GPIO_FN_ET0_TX_EN,
+	GPIO_FN_ET0_REF_CLK,		GPIO_FN_ET0_RXD1,
+	GPIO_FN_ET0_RXD0,		GPIO_FN_ET0_RX_ER,
+
+	/* PTF (mobule: EtherC) */
+	GPIO_FN_ET1_CRS_DV,		GPIO_FN_ET1_TXD1,
+	GPIO_FN_ET1_TXD0,		GPIO_FN_ET1_TX_EN,
+	GPIO_FN_ET1_REF_CLK,		GPIO_FN_ET1_RXD1,
+	GPIO_FN_ET1_RXD0,		GPIO_FN_ET1_RX_ER,
+
+	/* PTG (mobule: SYSTEM, PWMX, LPC) */
+	GPIO_FN_STATUS0,		GPIO_FN_STATUS1,
+	GPIO_FN_PWX0,	GPIO_FN_PWX1,	GPIO_FN_PWX2,	GPIO_FN_PWX3,
+	GPIO_FN_SERIRQ,	GPIO_FN_CLKRUN,	GPIO_FN_LPCPD,	GPIO_FN_LDRQ,
+
+	/* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
+	GPIO_FN_TCLK,	GPIO_FN_RXD4,	GPIO_FN_TXD4,
+	GPIO_FN_SP1_MOSI,		GPIO_FN_SP1_MISO,
+	GPIO_FN_SP1_SCK,		GPIO_FN_SP1_SCK_FB,
+	GPIO_FN_SP1_SS0,		GPIO_FN_SP1_SS1,
+	GPIO_FN_SP0_SS1,
+
+	/* PTI (mobule: INTC) */
+	GPIO_FN_IRQ15,	GPIO_FN_IRQ14,	GPIO_FN_IRQ13,	GPIO_FN_IRQ12,
+	GPIO_FN_IRQ11,	GPIO_FN_IRQ10,	GPIO_FN_IRQ9,	GPIO_FN_IRQ8,
+
+	/* PTJ (mobule: SCIF234, SERMUX) */
+	GPIO_FN_RXD3,	GPIO_FN_TXD3,	GPIO_FN_RXD2,	GPIO_FN_TXD2,
+	GPIO_FN_COM1_TXD,		GPIO_FN_COM1_RXD,
+	GPIO_FN_COM1_RTS,		GPIO_FN_COM1_CTS,
+
+	/* PTK (mobule: SERMUX) */
+	GPIO_FN_COM2_TXD,		GPIO_FN_COM2_RXD,
+	GPIO_FN_COM2_RTS,		GPIO_FN_COM2_CTS,
+	GPIO_FN_COM2_DTR,		GPIO_FN_COM2_DSR,
+	GPIO_FN_COM2_DCD,		GPIO_FN_COM2_RI,
+
+	/* PTL (mobule: SERMUX) */
+	GPIO_FN_RAC_TXD,		GPIO_FN_RAC_RXD,
+	GPIO_FN_RAC_RTS,		GPIO_FN_RAC_CTS,
+	GPIO_FN_RAC_DTR,		GPIO_FN_RAC_DSR,
+	GPIO_FN_RAC_DCD,		GPIO_FN_RAC_RI,
+
+	/* PTM (mobule: IIC, LPC) */
+	GPIO_FN_SDA6,	GPIO_FN_SCL6,	GPIO_FN_SDA7,	GPIO_FN_SCL7,
+	GPIO_FN_WP,	GPIO_FN_FMS0,	GPIO_FN_FMS1,
+
+	/* PTN (mobule: SCIF234, EVC) */
+	GPIO_FN_SCK2,	GPIO_FN_RTS4,	GPIO_FN_RTS3,	GPIO_FN_RTS2,
+	GPIO_FN_CTS4,	GPIO_FN_CTS3,	GPIO_FN_CTS2,
+	GPIO_FN_EVENT7,	GPIO_FN_EVENT6,	GPIO_FN_EVENT5,	GPIO_FN_EVENT4,
+	GPIO_FN_EVENT3,	GPIO_FN_EVENT2,	GPIO_FN_EVENT1,	GPIO_FN_EVENT0,
+
+	/* PTO (mobule: SGPIO) */
+	GPIO_FN_SGPIO0_CLK,		GPIO_FN_SGPIO0_LOAD,
+	GPIO_FN_SGPIO0_DI,		GPIO_FN_SGPIO0_DO,
+	GPIO_FN_SGPIO1_CLK,		GPIO_FN_SGPIO1_LOAD,
+	GPIO_FN_SGPIO1_DI,		GPIO_FN_SGPIO1_DO,
+
+	/* PTP (mobule: JMC, SCIF234) */
+	GPIO_FN_JMCTCK,	GPIO_FN_JMCTMS,	GPIO_FN_JMCTDO,	GPIO_FN_JMCTDI,
+	GPIO_FN_JMCRST,	GPIO_FN_SCK4,	GPIO_FN_SCK3,
+
+	/* PTQ (mobule: LPC) */
+	GPIO_FN_LAD3,	GPIO_FN_LAD2,	GPIO_FN_LAD1,	GPIO_FN_LAD0,
+	GPIO_FN_LFRAME,	GPIO_FN_LRESET,	GPIO_FN_LCLK,
+
+	/* PTR (mobule: GRA, IIC) */
+	GPIO_FN_DDC3,	GPIO_FN_DDC2,
+	GPIO_FN_SDA8,	GPIO_FN_SCL8,	GPIO_FN_SDA2,	GPIO_FN_SCL2,
+	GPIO_FN_SDA1,	GPIO_FN_SCL1,	GPIO_FN_SDA0,	GPIO_FN_SCL0,
+
+	/* PTS (mobule: GRA, IIC) */
+	GPIO_FN_DDC1,	GPIO_FN_DDC0,
+	GPIO_FN_SDA9,	GPIO_FN_SCL9,	GPIO_FN_SDA5,	GPIO_FN_SCL5,
+	GPIO_FN_SDA4,	GPIO_FN_SCL4,	GPIO_FN_SDA3,	GPIO_FN_SCL3,
+
+	/* PTT (mobule: SYSTEM, PWMX) */
+	GPIO_FN_AUDSYNC,		GPIO_FN_AUDCK,
+	GPIO_FN_AUDATA3,		GPIO_FN_AUDATA2,
+	GPIO_FN_AUDATA1,		GPIO_FN_AUDATA0,
+	GPIO_FN_PWX7,	GPIO_FN_PWX6,	GPIO_FN_PWX5,	GPIO_FN_PWX4,
+
+	/* PTU (mobule: LBSC, DMAC) */
+	GPIO_FN_CS6,	GPIO_FN_CS5,	GPIO_FN_CS4,	GPIO_FN_CS0,
+	GPIO_FN_RD,	GPIO_FN_WE0,	GPIO_FN_A25,	GPIO_FN_A24,
+	GPIO_FN_DREQ0,	GPIO_FN_DACK0,
+
+	/* PTV (mobule: LBSC, DMAC) */
+	GPIO_FN_A23,	GPIO_FN_A22,	GPIO_FN_A21,	GPIO_FN_A20,
+	GPIO_FN_A19,	GPIO_FN_A18,	GPIO_FN_A17,	GPIO_FN_A16,
+	GPIO_FN_TEND0,	GPIO_FN_DREQ1,	GPIO_FN_DACK1,	GPIO_FN_TEND1,
+
+	/* PTW (mobule: LBSC) */
+	GPIO_FN_A15,	GPIO_FN_A14,	GPIO_FN_A13,	GPIO_FN_A12,
+	GPIO_FN_A11,	GPIO_FN_A10,	GPIO_FN_A9,	GPIO_FN_A8,
+
+	/* PTX (mobule: LBSC) */
+	GPIO_FN_A7,	GPIO_FN_A6,	GPIO_FN_A5,	GPIO_FN_A4,
+	GPIO_FN_A3,	GPIO_FN_A2,	GPIO_FN_A1,	GPIO_FN_A0,
+
+	/* PTY (mobule: LBSC) */
+	GPIO_FN_D7,	GPIO_FN_D6,	GPIO_FN_D5,	GPIO_FN_D4,
+	GPIO_FN_D3,	GPIO_FN_D2,	GPIO_FN_D1,	GPIO_FN_D0,
+};
+
+#endif /* __ASM_SH7757_H__ */
diff --git a/arch/sh/include/cpu-sh5/cpu/cacheflush.h b/arch/sh/include/cpu-sh5/cpu/cacheflush.h
deleted file mode 100644
index 5a11f0b..0000000
--- a/arch/sh/include/cpu-sh5/cpu/cacheflush.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __ASM_SH_CPU_SH5_CACHEFLUSH_H
-#define __ASM_SH_CPU_SH5_CACHEFLUSH_H
-
-#ifndef __ASSEMBLY__
-
-struct vm_area_struct;
-struct page;
-struct mm_struct;
-
-extern void flush_cache_all(void);
-extern void flush_cache_mm(struct mm_struct *mm);
-extern void flush_cache_sigtramp(unsigned long vaddr);
-extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-			      unsigned long end);
-extern void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn);
-extern void flush_dcache_page(struct page *pg);
-extern void flush_icache_range(unsigned long start, unsigned long end);
-extern void flush_icache_user_range(struct vm_area_struct *vma,
-				    struct page *page, unsigned long addr,
-				    int len);
-
-#define flush_cache_dup_mm(mm)	flush_cache_mm(mm)
-
-#define flush_dcache_mmap_lock(mapping)		do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
-
-#define flush_icache_page(vma, page)	do { } while (0)
-void p3_cache_init(void);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_SH_CPU_SH5_CACHEFLUSH_H */
-
diff --git a/arch/sh/include/mach-common/mach/migor.h b/arch/sh/include/mach-common/mach/migor.h
deleted file mode 100644
index e451f02..0000000
--- a/arch/sh/include/mach-common/mach/migor.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef __ASM_SH_MIGOR_H
-#define __ASM_SH_MIGOR_H
-
-/*
- * linux/include/asm-sh/migor.h
- *
- * Copyright (C) 2008 Renesas Solutions
- *
- * Portions Copyright (C) 2007 Nobuhiro Iwamatsu
- *
- * 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.
- *
- */
-#include <asm/addrspace.h>
-
-/* GPIO */
-#define PORT_PACR 0xa4050100
-#define PORT_PDCR 0xa4050106
-#define PORT_PECR 0xa4050108
-#define PORT_PHCR 0xa405010e
-#define PORT_PJCR 0xa4050110
-#define PORT_PKCR 0xa4050112
-#define PORT_PLCR 0xa4050114
-#define PORT_PMCR 0xa4050116
-#define PORT_PRCR 0xa405011c
-#define PORT_PTCR 0xa4050140
-#define PORT_PUCR 0xa4050142
-#define PORT_PVCR 0xa4050144
-#define PORT_PWCR 0xa4050146
-#define PORT_PXCR 0xa4050148
-#define PORT_PYCR 0xa405014a
-#define PORT_PZCR 0xa405014c
-#define PORT_PADR 0xa4050120
-#define PORT_PHDR 0xa405012e
-#define PORT_PTDR 0xa4050160
-#define PORT_PWDR 0xa4050166
-
-#define PORT_HIZCRA 0xa4050158
-#define PORT_HIZCRC 0xa405015c
-
-#define PORT_MSELCRB 0xa4050182
-
-#define PORT_PSELA 0xa405014e
-#define PORT_PSELB 0xa4050150
-#define PORT_PSELC 0xa4050152
-#define PORT_PSELD 0xa4050154
-#define PORT_PSELE 0xa4050156
-
-#define PORT_HIZCRA 0xa4050158
-#define PORT_HIZCRB 0xa405015a
-#define PORT_HIZCRC 0xa405015c
-
-#define BSC_CS4BCR 0xfec10010
-#define BSC_CS6ABCR 0xfec1001c
-#define BSC_CS4WCR 0xfec10030
-
-#include <video/sh_mobile_lcdc.h>
-
-int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
-			 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-
-#endif /* __ASM_SH_MIGOR_H */
diff --git a/arch/sh/include/mach-common/mach/romimage.h b/arch/sh/include/mach-common/mach/romimage.h
new file mode 100644
index 0000000..267e241
--- /dev/null
+++ b/arch/sh/include/mach-common/mach/romimage.h
@@ -0,0 +1 @@
+/* do nothing here by default */
diff --git a/arch/sh/include/mach-common/mach/sh7785lcr.h b/arch/sh/include/mach-common/mach/sh7785lcr.h
index 90011d4..1292ae5 100644
--- a/arch/sh/include/mach-common/mach/sh7785lcr.h
+++ b/arch/sh/include/mach-common/mach/sh7785lcr.h
@@ -35,6 +35,8 @@
 #define PCA9564_ADDR		0x06000000	/* I2C */
 #define PCA9564_SIZE		0x00000100
 
+#define PCA9564_PROTO_32BIT_ADDR	0x14000000
+
 #define SM107_MEM_ADDR		0x10000000
 #define SM107_MEM_SIZE		0x00e00000
 #define SM107_REG_ADDR		0x13e00000
diff --git a/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt b/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
new file mode 100644
index 0000000..8b8e4fa
--- /dev/null
+++ b/arch/sh/include/mach-ecovec24/mach/partner-jet-setup.txt
@@ -0,0 +1,82 @@
+LIST "partner-jet-setup.txt"
+LIST "(C) Copyright 2009 Renesas Solutions Corp"
+LIST "Kuninori Morimoto <morimoto.kuninori@renesas.com>"
+LIST "--------------------------------"
+LIST "zImage (RAM boot)"
+LIST "This script can be used to boot the kernel from RAM via JTAG:"
+LIST "> < partner-jet-setup.txt"
+LIST "> RD zImage, 0xa8800000"
+LIST "> G=0xa8800000"
+LIST "--------------------------------"
+LIST "romImage (Flash boot)"
+LIST "Use the following command to burn the zImage to flash via JTAG:"
+LIST "> RD romImage, 0"
+LIST "--------------------------------"
+
+LIST "disable watchdog"
+EW 0xa4520004, 0xa507
+
+LIST "MMU"
+ED 0xff000010, 0x00000004
+
+LIST "setup clocks"
+ED 0xa4150024, 0x00004000
+ED 0xa4150000, 0x8E003508
+ED 0xa4150004, 0x00000000
+
+WAIT 1
+
+LIST "BSC"
+ED 0xff800020, 0xa5a50000
+ED 0xfec10000, 0x00000013
+ED 0xfec10004, 0x11110400
+ED 0xfec10024, 0x00000440
+
+WAIT 1
+
+LIST "setup sdram"
+ED 0xfd000108, 0x00000181
+ED 0xfd000020, 0x015B0002
+ED 0xfd000030, 0x03061502
+ED 0xfd000034, 0x02020102
+ED 0xfd000038, 0x01090305
+ED 0xfd00003c, 0x00000002
+ED 0xfd000008, 0x00000005
+ED 0xfd000018, 0x00000001
+
+WAIT 1
+
+ED 0xfd000014, 0x00000002
+ED 0xfd000060, 0x00020000
+ED 0xfd000060, 0x00030000
+ED 0xfd000060, 0x00010040
+ED 0xfd000060, 0x00000532
+ED 0xfd000014, 0x00000002
+ED 0xfd000014, 0x00000004
+ED 0xfd000014, 0x00000004
+ED 0xfd000060, 0x00000432
+ED 0xfd000060, 0x000103C0
+ED 0xfd000060, 0x00010040
+
+WAIT 1
+
+ED 0xfd000010, 0x00000001
+ED 0xfd000044, 0x00000613
+ED 0xfd000048, 0x238C003A
+ED 0xfd000014, 0x00000002
+
+LIST "Dummy read"
+DD 0x0c400000, 0x0c400000
+
+ED 0xfd000014, 0x00000002
+ED 0xfd000014, 0x00000004
+ED 0xfd000108, 0x00000080
+ED 0xfd000040, 0x00010000
+
+WAIT 1
+
+LIST "setup cache"
+ED 0xff00001c, 0x0000090b
+
+LIST "disable USB"
+EW 0xA4D80000, 0x0000
diff --git a/arch/sh/include/mach-ecovec24/mach/romimage.h b/arch/sh/include/mach-ecovec24/mach/romimage.h
new file mode 100644
index 0000000..1c8787e
--- /dev/null
+++ b/arch/sh/include/mach-ecovec24/mach/romimage.h
@@ -0,0 +1,20 @@
+/* EcoVec board specific boot code:
+ * converts the "partner-jet-script.txt" script into assembly
+ * the assembly code is the first code to be executed in the romImage
+ */
+
+#include <asm/romimage-macros.h>
+#include "partner-jet-setup.txt"
+
+	/* execute icbi after enabling cache */
+	mov.l	1f, r0
+	icbi	@r0
+
+	/* jump to cached area */
+	mova	2f, r0
+	jmp	@r0
+	nop
+
+	.align 2
+1 :	.long 0xa8000000
+2 :
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
new file mode 100644
index 0000000..174374e
--- /dev/null
+++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_SH_KFR2R09_H
+#define __ASM_SH_KFR2R09_H
+
+#include <video/sh_mobile_lcdc.h>
+
+#ifdef CONFIG_FB_SH_MOBILE_LCDC
+void kfr2r09_lcd_on(void *board_data);
+void kfr2r09_lcd_off(void *board_data);
+int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+		      struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
+#else
+static inline void kfr2r09_lcd_on(void *board_data) {}
+static inline void kfr2r09_lcd_off(void *board_data) {}
+static inline int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+				    struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
+{
+	return -ENODEV;
+}
+#endif
+
+#endif /* __ASM_SH_KFR2R09_H */
diff --git a/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt b/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
new file mode 100644
index 0000000..3a65503
--- /dev/null
+++ b/arch/sh/include/mach-kfr2r09/mach/partner-jet-setup.txt
@@ -0,0 +1,143 @@
+LIST "partner-jet-setup.txt - 20090729 Magnus Damm"
+LIST "set up enough of the kfr2r09 hardware to boot the kernel"
+
+LIST "zImage (RAM boot)"
+LIST "This script can be used to boot the kernel from RAM via JTAG:"
+LIST "> < partner-jet-setup.txt"
+LIST "> RD zImage, 0xa8800000"
+LIST "> G=0xa8800000"
+
+LIST "romImage (Flash boot)"
+LIST "Use the following command to burn the zImage to flash via JTAG:"
+LIST "> RD romImage, 0"
+
+LIST "--------------------------------"
+
+LIST "disable watchdog"
+EW 0xa4520004, 0xa507
+
+LIST "invalidate instruction cache"
+ED 0xff00001c, 0x00000800
+
+LIST "invalidate TLBs"
+ED 0xff000010, 0x00000004
+
+LIST "select mode for cs5 + cs6"
+ED 0xff800020, 0xa5a50001
+ED 0xfec10000, 0x0000001b
+
+LIST "setup clocks"
+LIST "The PLL and FLL values are updated here for the optimal"
+LIST "RF frequency and improved reception sensitivity."
+ED 0xa4150004, 0x00000050
+ED 0xa4150000, 0x91053508
+WAIT 1
+ED 0xa4150050, 0x00000340
+ED 0xa4150024, 0x00005000
+
+LIST "setup pins"
+EB 0xa4050120, 0x00
+EB 0xa4050122, 0x00
+EB 0xa4050124, 0x00
+EB 0xa4050126, 0x00
+EB 0xa4050128, 0xA0
+EB 0xa405012A, 0x10
+EB 0xa405012C, 0x00
+EB 0xa405012E, 0x00
+EB 0xa4050130, 0x00
+EB 0xa4050132, 0x00
+EB 0xa4050134, 0x01
+EB 0xa4050136, 0x40
+EB 0xa4050138, 0x00
+EB 0xa405013A, 0x00
+EB 0xa405013C, 0x00
+EB 0xa405013E, 0x20
+EB 0xa4050160, 0x00
+EB 0xa4050162, 0x40
+EB 0xa4050164, 0x03
+EB 0xa4050166, 0x00
+EB 0xa4050168, 0x00
+EB 0xa405016A, 0x00
+EB 0xa405016C, 0x00
+
+EW 0xa405014E, 0x5660
+EW 0xa4050150, 0x0145
+EW 0xa4050152, 0x1550
+EW 0xa4050154, 0x0200
+EW 0xa4050156, 0x0040
+
+EW 0xa4050158, 0x0000
+EW 0xa405015a, 0x0000
+EW 0xa405015c, 0x0000
+EW 0xa405015e, 0x0000
+
+EW 0xa4050180, 0x0000
+EW 0xa4050182, 0x8002
+EW 0xa4050184, 0x0000
+
+EW 0xa405018a, 0x9991
+EW 0xa405018c, 0x8011
+EW 0xa405018e, 0x9550
+
+EW 0xa4050100, 0x0000
+EW 0xa4050102, 0x5540
+EW 0xa4050104, 0x0000
+EW 0xa4050106, 0x0000
+EW 0xa4050108, 0x4550
+EW 0xa405010a, 0x0130
+EW 0xa405010c, 0x0555
+EW 0xa405010e, 0x0000
+EW 0xa4050110, 0x0000
+EW 0xa4050112, 0xAAA8
+EW 0xa4050114, 0x8305
+EW 0xa4050116, 0x10F0
+EW 0xa4050118, 0x0F50
+EW 0xa405011a, 0x0000
+EW 0xa405011c, 0x0000
+EW 0xa405011e, 0x0555
+EW 0xa4050140, 0x0000
+EW 0xa4050142, 0x5141
+EW 0xa4050144, 0x5005
+EW 0xa4050146, 0xAAA9
+EW 0xa4050148, 0xFAA9
+EW 0xa405014a, 0x3000
+EW 0xa405014c, 0x0000
+
+LIST "setup sdram"
+ED 0xFD000108, 0x40000301
+ED 0xFD000020, 0x011B0002
+ED 0xFD000030, 0x03060E02
+ED 0xFD000034, 0x01020102
+ED 0xFD000038, 0x01090406
+ED 0xFD000008, 0x00000004
+ED 0xFD000040, 0x00000001
+ED 0xFD000040, 0x00000000
+ED 0xFD000018, 0x00000001
+
+WAIT 1
+
+ED 0xFD000014, 0x00000002
+ED 0xFD000060, 0x00000032
+ED 0xFD000060, 0x00020000
+ED 0xFD000014, 0x00000004
+ED 0xFD000014, 0x00000004
+ED 0xFD000010, 0x00000001
+ED 0xFD000044, 0x000004AF
+ED 0xFD000048, 0x20CF0037
+
+LIST "read 16 bytes from sdram"
+DD 0xa8000000, 0xa8000000, 1
+DD 0xa8000004, 0xa8000004, 1
+DD 0xa8000008, 0xa8000008, 1
+DD 0xa800000c, 0xa800000c, 1
+
+ED 0xFD000014, 0x00000002
+ED 0xFD000014, 0x00000004
+ED 0xFD000108, 0x40000300
+ED 0xFD000040, 0x00010000
+
+LIST "write to internal ram"
+ED 0xfd8007fc, 0
+
+LIST "setup cache"
+ED 0xff00001c, 0x0000090b
diff --git a/arch/sh/include/mach-kfr2r09/mach/romimage.h b/arch/sh/include/mach-kfr2r09/mach/romimage.h
new file mode 100644
index 0000000..a110823
--- /dev/null
+++ b/arch/sh/include/mach-kfr2r09/mach/romimage.h
@@ -0,0 +1,20 @@
+/* kfr2r09 board specific boot code:
+ * converts the "partner-jet-script.txt" script into assembly
+ * the assembly code is the first code to be executed in the romImage
+ */
+
+#include <asm/romimage-macros.h>
+#include "partner-jet-setup.txt"
+
+	/* execute icbi after enabling cache */
+	mov.l	1f, r0
+	icbi	@r0
+
+	/* jump to cached area */
+	mova	2f, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+1:	.long 0xa8000000
+2:
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
new file mode 100644
index 0000000..cee6cb8
--- /dev/null
+++ b/arch/sh/include/mach-migor/mach/migor.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_SH_MIGOR_H
+#define __ASM_SH_MIGOR_H
+
+#define PORT_MSELCRB 0xa4050182
+#define BSC_CS4BCR 0xfec10010
+#define BSC_CS6ABCR 0xfec1001c
+#define BSC_CS4WCR 0xfec10030
+
+#include <video/sh_mobile_lcdc.h>
+
+int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
+			 struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
+
+#endif /* __ASM_SH_MIGOR_H */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 349d833..a2d0a40 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -1,5 +1,41 @@
-ifeq ($(CONFIG_SUPERH32),y)
-include ${srctree}/arch/sh/kernel/Makefile_32
-else
-include ${srctree}/arch/sh/kernel/Makefile_64
+#
+# Makefile for the Linux/SuperH kernel.
+#
+
+extra-y	:= head_$(BITS).o init_task.o vmlinux.lds
+
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o = -pg
 endif
+
+obj-y	:= debugtraps.o dumpstack.o idle.o io.o io_generic.o irq.o	\
+	   machvec.o nmi_debug.o process_$(BITS).o ptrace_$(BITS).o	\
+	   setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o		\
+	   syscalls_$(BITS).o time.o topology.o traps.o			\
+	   traps_$(BITS).o unwinder.o
+
+obj-y				+= cpu/
+obj-$(CONFIG_VSYSCALL)		+= vsyscall/
+obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
+obj-$(CONFIG_KGDB)		+= kgdb.o
+obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
+obj-$(CONFIG_MODULES)		+= sh_ksyms_$(BITS).o module.o
+obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
+obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
+obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
+obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o
+obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
+obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
+obj-$(CONFIG_HIBERNATION)	+= swsusp.o
+obj-$(CONFIG_DWARF_UNWINDER)	+= dwarf.o
+
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
deleted file mode 100644
index 9411e3e..0000000
--- a/arch/sh/kernel/Makefile_32
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Makefile for the Linux/SuperH kernel.
-#
-
-extra-y	:= head_32.o init_task.o vmlinux.lds
-
-ifdef CONFIG_FUNCTION_TRACER
-# Do not profile debug and lowlevel utilities
-CFLAGS_REMOVE_ftrace.o = -pg
-endif
-
-obj-y	:= debugtraps.o idle.o io.o io_generic.o irq.o			\
-	   machvec.o process_32.o ptrace_32.o setup.o signal_32.o	\
-	   sys_sh.o sys_sh32.o syscalls_32.o time.o topology.o	\
-	   traps.o traps_32.o
-
-obj-y				+= cpu/
-obj-$(CONFIG_VSYSCALL)		+= vsyscall/
-obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_SH_STANDARD_BIOS)	+= sh_bios.o
-obj-$(CONFIG_KGDB)		+= kgdb.o
-obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
-obj-$(CONFIG_MODULES)		+= sh_ksyms_32.o module.o
-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
-obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
-obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
-obj-$(CONFIG_KPROBES)		+= kprobes.o
-obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
-obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
-obj-$(CONFIG_DUMP_CODE)		+= disassemble.o
-obj-$(CONFIG_HIBERNATION)	+= swsusp.o
-
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
deleted file mode 100644
index 67b9f6c..0000000
--- a/arch/sh/kernel/Makefile_64
+++ /dev/null
@@ -1,19 +0,0 @@
-extra-y	:= head_64.o init_task.o vmlinux.lds
-
-obj-y	:= debugtraps.o idle.o io.o io_generic.o irq.o machvec.o process_64.o \
-	   ptrace_64.o setup.o signal_64.o sys_sh.o sys_sh64.o \
-	   syscalls_64.o time.o topology.o traps.o traps_64.o
-
-obj-y				+= cpu/
-obj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_SH_CPU_FREQ)	+= cpufreq.o
-obj-$(CONFIG_MODULES)		+= sh_ksyms_64.o module.o
-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
-obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
-obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
-obj-$(CONFIG_IO_TRAPPED)	+= io_trapped.o
-obj-$(CONFIG_GENERIC_GPIO)	+= gpio.o
-
-obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= localtimer.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/asm-offsets.c b/arch/sh/kernel/asm-offsets.c
index 99aceb2..d218e80 100644
--- a/arch/sh/kernel/asm-offsets.c
+++ b/arch/sh/kernel/asm-offsets.c
@@ -26,6 +26,7 @@ int main(void)
 	DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
 	DEFINE(TI_PRE_COUNT,	offsetof(struct thread_info, preempt_count));
 	DEFINE(TI_RESTART_BLOCK,offsetof(struct thread_info, restart_block));
+	DEFINE(TI_SIZE,		sizeof(struct thread_info));
 
 #ifdef CONFIG_HIBERNATION
 	DEFINE(PBE_ADDRESS, offsetof(struct pbe, address));
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index eecad7c..3d6b931 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -19,4 +19,4 @@ obj-$(CONFIG_UBC_WAKEUP)	+= ubc.o
 obj-$(CONFIG_SH_ADC)		+= adc.o
 obj-$(CONFIG_SH_CLK_CPG)	+= clock-cpg.o
 
-obj-y	+= irq/ init.o clock.o
+obj-y	+= irq/ init.o clock.o hwblk.o
diff --git a/arch/sh/kernel/cpu/hwblk.c b/arch/sh/kernel/cpu/hwblk.c
new file mode 100644
index 0000000..c0ad7d4
--- /dev/null
+++ b/arch/sh/kernel/cpu/hwblk.c
@@ -0,0 +1,155 @@
+#include <linux/clk.h>
+#include <linux/compiler.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <asm/clock.h>
+
+static DEFINE_SPINLOCK(hwblk_lock);
+
+static void hwblk_area_mod_cnt(struct hwblk_info *info,
+			       int area, int counter, int value, int goal)
+{
+	struct hwblk_area *hap = info->areas + area;
+
+	hap->cnt[counter] += value;
+
+	if (hap->cnt[counter] != goal)
+		return;
+
+	if (hap->flags & HWBLK_AREA_FLAG_PARENT)
+		hwblk_area_mod_cnt(info, hap->parent, counter, value, goal);
+}
+
+
+static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
+			  int counter, int value, int goal)
+{
+	struct hwblk *hp = info->hwblks + hwblk;
+
+	hp->cnt[counter] += value;
+	if (hp->cnt[counter] == goal)
+		hwblk_area_mod_cnt(info, hp->area, counter, value, goal);
+
+	return hp->cnt[counter];
+}
+
+static void hwblk_mod_cnt(struct hwblk_info *info, int hwblk,
+			  int counter, int value, int goal)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&hwblk_lock, flags);
+	__hwblk_mod_cnt(info, hwblk, counter, value, goal);
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int counter)
+{
+	hwblk_mod_cnt(info, hwblk, counter, 1, 1);
+}
+
+void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int counter)
+{
+	hwblk_mod_cnt(info, hwblk, counter, -1, 0);
+}
+
+void hwblk_enable(struct hwblk_info *info, int hwblk)
+{
+	struct hwblk *hp = info->hwblks + hwblk;
+	unsigned long tmp;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&hwblk_lock, flags);
+
+	ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, 1, 1);
+	if (ret == 1) {
+		tmp = __raw_readl(hp->mstp);
+		tmp &= ~(1 << hp->bit);
+		__raw_writel(tmp, hp->mstp);
+	}
+
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+void hwblk_disable(struct hwblk_info *info, int hwblk)
+{
+	struct hwblk *hp = info->hwblks + hwblk;
+	unsigned long tmp;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&hwblk_lock, flags);
+
+	ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, -1, 0);
+	if (ret == 0) {
+		tmp = __raw_readl(hp->mstp);
+		tmp |= 1 << hp->bit;
+		__raw_writel(tmp, hp->mstp);
+	}
+
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+struct hwblk_info *hwblk_info;
+
+int __init hwblk_register(struct hwblk_info *info)
+{
+	hwblk_info = info;
+	return 0;
+}
+
+int __init __weak arch_hwblk_init(void)
+{
+	return 0;
+}
+
+int __weak arch_hwblk_sleep_mode(void)
+{
+	return SUSP_SH_SLEEP;
+}
+
+int __init hwblk_init(void)
+{
+	return arch_hwblk_init();
+}
+
+/* allow clocks to enable and disable hardware blocks */
+static int sh_hwblk_clk_enable(struct clk *clk)
+{
+	if (!hwblk_info)
+		return -ENOENT;
+
+	hwblk_enable(hwblk_info, clk->arch_flags);
+	return 0;
+}
+
+static void sh_hwblk_clk_disable(struct clk *clk)
+{
+	if (hwblk_info)
+		hwblk_disable(hwblk_info, clk->arch_flags);
+}
+
+static struct clk_ops sh_hwblk_clk_ops = {
+	.enable		= sh_hwblk_clk_enable,
+	.disable	= sh_hwblk_clk_disable,
+	.recalc		= followparent_recalc,
+};
+
+int __init sh_hwblk_clk_register(struct clk *clks, int nr)
+{
+	struct clk *clkp;
+	int ret = 0;
+	int k;
+
+	for (k = 0; !ret && (k < nr); k++) {
+		clkp = clks + k;
+		clkp->ops = &sh_hwblk_clk_ops;
+		ret |= clk_register(clkp);
+	}
+
+	return ret;
+}
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index ad85421..e932ebe 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -3,7 +3,7 @@
  *
  * CPU init code
  *
- * Copyright (C) 2002 - 2007  Paul Mundt
+ * Copyright (C) 2002 - 2009  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -62,6 +62,37 @@ static void __init speculative_execution_init(void)
 #define speculative_execution_init()	do { } while (0)
 #endif
 
+#ifdef CONFIG_CPU_SH4A
+#define EXPMASK			0xff2f0004
+#define EXPMASK_RTEDS		(1 << 0)
+#define EXPMASK_BRDSSLP		(1 << 1)
+#define EXPMASK_MMCAW		(1 << 4)
+
+static void __init expmask_init(void)
+{
+	unsigned long expmask = __raw_readl(EXPMASK);
+
+	/*
+	 * Future proofing.
+	 *
+	 * Disable support for slottable sleep instruction
+	 * and non-nop instructions in the rte delay slot.
+	 */
+	expmask &= ~(EXPMASK_RTEDS | EXPMASK_BRDSSLP);
+
+	/*
+	 * Enable associative writes to the memory-mapped cache array
+	 * until the cache flush ops have been rewritten.
+	 */
+	expmask |= EXPMASK_MMCAW;
+
+	__raw_writel(expmask, EXPMASK);
+	ctrl_barrier();
+}
+#else
+#define expmask_init()	do { } while (0)
+#endif
+
 /* 2nd-level cache init */
 void __uses_jump_to_uncached __attribute__ ((weak)) l2_cache_init(void)
 {
@@ -268,11 +299,9 @@ asmlinkage void __init sh_cpu_init(void)
 	cache_init();
 
 	if (raw_smp_processor_id() == 0) {
-#ifdef CONFIG_MMU
 		shm_align_mask = max_t(unsigned long,
 				       current_cpu_data.dcache.way_size - 1,
 				       PAGE_SIZE - 1);
-#endif
 
 		/* Boot CPU sets the cache shape */
 		detect_cache_shape();
@@ -321,4 +350,5 @@ asmlinkage void __init sh_cpu_init(void)
 #endif
 
 	speculative_execution_init();
+	expmask_init();
 }
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 808d99a..c1508a9 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -35,6 +35,7 @@ static void disable_ipr_irq(unsigned int irq)
 	unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
 	/* Set the priority in IPR to 0 */
 	__raw_writew(__raw_readw(addr) & (0xffff ^ (0xf << p->shift)), addr);
+	(void)__raw_readw(addr);	/* Read back to flush write posting */
 }
 
 static void enable_ipr_irq(unsigned int irq)
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index becc54c..c8a4331 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -227,8 +227,9 @@ ENTRY(sh_bios_handler)
 	mov.l	@r15+, r14
 	add	#8,r15
 	lds.l	@r15+, pr
+	mov.l	@r15+,r15
 	rte
-	 mov.l	@r15+,r15
+	 nop
 	.align	2
 1:	.long	gdb_vbr_vector
 #endif /* CONFIG_SH_STANDARD_BIOS */
diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c
index 5916d90..1db6d88 100644
--- a/arch/sh/kernel/cpu/sh2/probe.c
+++ b/arch/sh/kernel/cpu/sh2/probe.c
@@ -29,6 +29,7 @@ int __init detect_cpu_and_cache_system(void)
 	 */
 	boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
 	boot_cpu_data.icache = boot_cpu_data.dcache;
+	boot_cpu_data.family = CPU_FAMILY_SH2;
 
 	return 0;
 }
diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S
index ab3903e..222742d 100644
--- a/arch/sh/kernel/cpu/sh2a/entry.S
+++ b/arch/sh/kernel/cpu/sh2a/entry.S
@@ -176,8 +176,9 @@ ENTRY(sh_bios_handler)
 	movml.l	@r15+,r14
 	add	#8,r15
 	lds.l	@r15+, pr
+	mov.l	@r15+,r15
 	rte
-	 mov.l	@r15+,r15
+	 nop
 	.align	2
 1:	.long	gdb_vbr_vector
 #endif /* CONFIG_SH_STANDARD_BIOS */
diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c
index e098e2f..6825d65 100644
--- a/arch/sh/kernel/cpu/sh2a/probe.c
+++ b/arch/sh/kernel/cpu/sh2a/probe.c
@@ -15,6 +15,8 @@
 
 int __init detect_cpu_and_cache_system(void)
 {
+	boot_cpu_data.family			= CPU_FAMILY_SH2A;
+
 	/* All SH-2A CPUs have support for 16 and 32-bit opcodes.. */
 	boot_cpu_data.flags			|= CPU_HAS_OP32;
 
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
index fa30b60..e874950 100644
--- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c
@@ -22,13 +22,6 @@ static int stc_multipliers[] = { 1, 2, 4, 8, 3, 6, 1, 1 };
 static int ifc_divisors[]    = { 1, 2, 4, 1, 3, 1, 1, 1 };
 static int pfc_divisors[]    = { 1, 2, 4, 1, 3, 6, 1, 1 };
 
-static void set_bus_parent(struct clk *clk)
-{
-	struct clk *bus_clk = clk_get(NULL, "bus_clk");
-	clk->parent = bus_clk;
-	clk_put(bus_clk);
-}
-
 static void master_clk_init(struct clk *clk)
 {
 	int frqcr = ctrl_inw(FRQCR);
@@ -50,9 +43,6 @@ static unsigned long module_clk_recalc(struct clk *clk)
 }
 
 static struct clk_ops sh7709_module_clk_ops = {
-#ifdef CLOCK_MODE_0_1_2_7
-	.init		= set_bus_parent,
-#endif
 	.recalc		= module_clk_recalc,
 };
 
@@ -78,7 +68,6 @@ static unsigned long cpu_clk_recalc(struct clk *clk)
 }
 
 static struct clk_ops sh7709_cpu_clk_ops = {
-	.init		= set_bus_parent,
 	.recalc		= cpu_clk_recalc,
 };
 
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 3cb531f..0151933 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -53,10 +53,6 @@
  *	syscall #
  *
  */
-#if defined(CONFIG_KGDB)
-NMI_VEC = 0x1c0			! Must catch early for debounce
-#endif
-
 /* Offsets to the stack */
 OFF_R0  =  0		/* Return value. New ABI also arg4 */
 OFF_R1  =  4     	/* New ABI: arg5 */
@@ -71,7 +67,6 @@ OFF_PC  =  (16*4)
 OFF_SR	=  (16*4+8)
 OFF_TRA	=  (16*4+6*4)
 
-
 #define k0	r0
 #define k1	r1
 #define k2	r2
@@ -113,34 +108,34 @@ OFF_TRA	=  (16*4+6*4)
 #if defined(CONFIG_MMU)
 	.align	2
 ENTRY(tlb_miss_load)
-	bra	call_dpf
+	bra	call_handle_tlbmiss
 	 mov	#0, r5
 
 	.align	2
 ENTRY(tlb_miss_store)
-	bra	call_dpf
+	bra	call_handle_tlbmiss
 	 mov	#1, r5
 
 	.align	2
 ENTRY(initial_page_write)
-	bra	call_dpf
-	 mov	#1, r5
+	bra	call_handle_tlbmiss
+	 mov	#2, r5
 
 	.align	2
 ENTRY(tlb_protection_violation_load)
-	bra	call_dpf
+	bra	call_do_page_fault
 	 mov	#0, r5
 
 	.align	2
 ENTRY(tlb_protection_violation_store)
-	bra	call_dpf
+	bra	call_do_page_fault
 	 mov	#1, r5
 
-call_dpf:
+call_handle_tlbmiss:
+	setup_frame_reg
 	mov.l	1f, r0
 	mov	r5, r8
 	mov.l	@r0, r6
-	mov	r6, r9
 	mov.l	2f, r0
 	sts	pr, r10
 	jsr	@r0
@@ -151,16 +146,25 @@ call_dpf:
 	 lds	r10, pr
 	rts
 	 nop
-0:	mov.l	3f, r0
-	mov	r9, r6
+0:
 	mov	r8, r5
+call_do_page_fault:
+	mov.l	1f, r0
+	mov.l	@r0, r6
+
+	sti
+
+	mov.l	3f, r0
+	mov.l	4f, r1
+	mov	r15, r4
 	jmp	@r0
-	 mov	r15, r4
+	 lds	r1, pr
 
 	.align 2
 1:	.long	MMU_TEA
-2:	.long	__do_page_fault
+2:	.long	handle_tlbmiss
 3:	.long	do_page_fault
+4:	.long	ret_from_exception
 
 	.align	2
 ENTRY(address_error_load)
@@ -256,7 +260,7 @@ restore_all:
 	!
 	! Calculate new SR value
 	mov	k3, k2			! original SR value
-	mov	#0xf0, k1
+	mov	#0xfffffff0, k1
 	extu.b	k1, k1
 	not	k1, k1
 	and	k1, k2			! Mask original SR value
@@ -272,21 +276,12 @@ restore_all:
 6:	or	k0, k2			! Set the IMASK-bits
 	ldc	k2, ssr
 	!
-#if defined(CONFIG_KGDB)
-	! Clear in_nmi
-	mov.l	6f, k0
-	mov	#0, k1
-	mov.b	k1, @k0
-#endif
 	mov	k4, r15
 	rte
 	 nop
 
 	.align	2
 5:	.long	0x00001000	! DSP
-#ifdef CONFIG_KGDB
-6:	.long	in_nmi
-#endif
 7:	.long	0x30000000
 
 ! common exception handler
@@ -478,23 +473,6 @@ ENTRY(save_low_regs)
 !
 	.balign 	512,0,512
 ENTRY(handle_interrupt)
-#if defined(CONFIG_KGDB)
-	mov.l	2f, k2
-	! Debounce (filter nested NMI)
-	mov.l	@k2, k0
-	mov.l	9f, k1
-	cmp/eq	k1, k0
-	bf	11f
-	mov.l	10f, k1
-	tas.b	@k1
-	bt	11f
-	rte
-	 nop
-	.align	2
-9:	.long	NMI_VEC
-10:	.long	in_nmi
-11:
-#endif /* defined(CONFIG_KGDB) */
 	sts	pr, k3		! save original pr value in k3
 	mova	exception_data, k0
 
@@ -507,13 +485,49 @@ ENTRY(handle_interrupt)
 	bsr	save_regs	! needs original pr value in k3
 	 mov	#-1, k2		! default vector kept in k2
 
+	setup_frame_reg
+
+	stc	sr, r0	! get status register
+	shlr2	r0
+	and	#0x3c, r0
+	cmp/eq	#0x3c, r0
+	bf	9f
+	TRACE_IRQS_OFF
+9:
+
 	! Setup return address and jump to do_IRQ
 	mov.l	4f, r9		! fetch return address
 	lds	r9, pr		! put return address in pr
 	mov.l	2f, r4
 	mov.l	3f, r9
 	mov.l	@r4, r4		! pass INTEVT vector as arg0
+
+	shlr2	r4
+	shlr	r4
+	mov	r4, r0		! save vector->jmp table offset for later
+
+	shlr2	r4		! vector to IRQ# conversion
+	add	#-0x10, r4
+
+	cmp/pz	r4		! is it a valid IRQ?
+	bt	10f
+
+	/*
+	 * We got here as a result of taking the INTEVT path for something
+	 * that isn't a valid hard IRQ, therefore we bypass the do_IRQ()
+	 * path and special case the event dispatch instead.  This is the
+	 * expected path for the NMI (and any other brilliantly implemented
+	 * exception), which effectively wants regular exception dispatch
+	 * but is unfortunately reported through INTEVT rather than
+	 * EXPEVT.  Grr.
+	 */
+	mov.l	6f, r9
+	mov.l	@(r0, r9), r9
 	jmp	@r9
+	 mov	r15, r8		! trap handlers take saved regs in r8
+
+10:
+	jmp	@r9		! Off to do_IRQ() we go.
 	 mov	r15, r5		! pass saved registers as arg1
 
 ENTRY(exception_none)
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index e5a0de3..46610c3 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -48,9 +48,7 @@ ENTRY(exception_handling_table)
 	.long	system_call	! Unconditional Trap	 /* 160 */
 	.long	exception_error	! reserved_instruction (filled by trap_init) /* 180 */
 	.long	exception_error	! illegal_slot_instruction (filled by trap_init) /*1A0*/
-ENTRY(nmi_slot)
-	.long	kgdb_handle_exception	/* 1C0 */	! Allow trap to debugger
-ENTRY(user_break_point_trap)
+	.long	nmi_trap_handler	/* 1C0 */	! Allow trap to debugger
 	.long	break_point_trap	/* 1E0 */
 
 	/*
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index 10f2a76..f9c7df6 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -107,5 +107,7 @@ int __uses_jump_to_uncached detect_cpu_and_cache_system(void)
 	boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED;
 	boot_cpu_data.icache = boot_cpu_data.dcache;
 
+	boot_cpu_data.family = CPU_FAMILY_SH3;
+
 	return 0;
 }
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 6c78d0a..d36f0c4 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -57,8 +57,12 @@ int __init detect_cpu_and_cache_system(void)
 	 * Setup some generic flags we can probe on SH-4A parts
 	 */
 	if (((pvr >> 16) & 0xff) == 0x10) {
-		if ((cvr & 0x10000000) == 0)
+		boot_cpu_data.family = CPU_FAMILY_SH4A;
+
+		if ((cvr & 0x10000000) == 0) {
 			boot_cpu_data.flags |= CPU_HAS_DSP;
+			boot_cpu_data.family = CPU_FAMILY_SH4AL_DSP;
+		}
 
 		boot_cpu_data.flags |= CPU_HAS_LLSC | CPU_HAS_PERF_COUNTER;
 		boot_cpu_data.cut_major = pvr & 0x7f;
@@ -68,6 +72,7 @@ int __init detect_cpu_and_cache_system(void)
 	} else {
 		/* And some SH-4 defaults.. */
 		boot_cpu_data.flags |= CPU_HAS_PTEA;
+		boot_cpu_data.family = CPU_FAMILY_SH4;
 	}
 
 	/* FPU detection works for everyone */
@@ -139,8 +144,15 @@ int __init detect_cpu_and_cache_system(void)
 		}
 		break;
 	case 0x300b:
-		boot_cpu_data.type = CPU_SH7724;
-		boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
+		switch (prr) {
+		case 0x20:
+			boot_cpu_data.type = CPU_SH7724;
+			boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
+			break;
+		case 0x50:
+			boot_cpu_data.type = CPU_SH7757;
+			break;
+		}
 		break;
 	case 0x4000:	/* 1st cut */
 	case 0x4001:	/* 2nd cut */
@@ -173,9 +185,6 @@ int __init detect_cpu_and_cache_system(void)
 		boot_cpu_data.dcache.ways = 2;
 
 		break;
-	default:
-		boot_cpu_data.type = CPU_SH_NONE;
-		break;
 	}
 
 	/*
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index ebdd391..490d5dc 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -3,6 +3,7 @@
 #
 
 # CPU subtype setup
+obj-$(CONFIG_CPU_SUBTYPE_SH7757)	+= setup-sh7757.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7763)	+= setup-sh7763.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7770)	+= setup-sh7770.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7780)	+= setup-sh7780.o
@@ -19,15 +20,16 @@ obj-$(CONFIG_CPU_SUBTYPE_SHX3)		+= setup-shx3.o
 smp-$(CONFIG_CPU_SHX3)			:= smp-shx3.o
 
 # Primary on-chip clocks (common)
+clock-$(CONFIG_CPU_SUBTYPE_SH7757)	:= clock-sh7757.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7763)	:= clock-sh7763.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7770)	:= clock-sh7770.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7780)	:= clock-sh7780.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7785)	:= clock-sh7785.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7786)	:= clock-sh7786.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7343)	:= clock-sh7343.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7722)	:= clock-sh7722.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7723)	:= clock-sh7723.o
-clock-$(CONFIG_CPU_SUBTYPE_SH7724)	:= clock-sh7724.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7722)	:= clock-sh7722.o hwblk-sh7722.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7723)	:= clock-sh7723.o hwblk-sh7723.o
+clock-$(CONFIG_CPU_SUBTYPE_SH7724)	:= clock-sh7724.o hwblk-sh7724.o
 clock-$(CONFIG_CPU_SUBTYPE_SH7366)	:= clock-sh7366.o
 clock-$(CONFIG_CPU_SUBTYPE_SHX3)	:= clock-shx3.o
 
@@ -35,6 +37,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SHX3)	:= clock-shx3.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7722)	:= pinmux-sh7722.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7723)	:= pinmux-sh7723.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7724)	:= pinmux-sh7724.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7757)	:= pinmux-sh7757.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7785)	:= pinmux-sh7785.o
 pinmux-$(CONFIG_CPU_SUBTYPE_SH7786)	:= pinmux-sh7786.o
 
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 40f8593..ea38b55 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7722.h>
 
 /* SH7722 registers */
 #define FRQCR		0xa4150000
@@ -30,9 +32,6 @@
 #define SCLKBCR		0xa415000c
 #define IRDACLKCR	0xa4150018
 #define PLLCR		0xa4150024
-#define MSTPCR0		0xa4150030
-#define MSTPCR1		0xa4150034
-#define MSTPCR2		0xa4150038
 #define DLLFRQ		0xa4150050
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -140,35 +139,37 @@ struct clk div6_clks[] = {
 	SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _flags) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _flags)
+#define R_CLK &r_clk
+#define P_CLK &div4_clks[DIV4_P]
+#define B_CLK &div4_clks[DIV4_B]
+#define U_CLK &div4_clks[DIV4_U]
 
 static struct clk mstp_clks[] = {
-	MSTP("uram0", &div4_clks[DIV4_U], MSTPCR0, 28, CLK_ENABLE_ON_INIT),
-	MSTP("xymem0", &div4_clks[DIV4_B], MSTPCR0, 26, CLK_ENABLE_ON_INIT),
-	MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0),
-	MSTP("cmt0", &r_clk, MSTPCR0, 14, 0),
-	MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0),
-	MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0),
-	MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 7, 0),
-	MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 6, 0),
-	MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 5, 0),
-
-	MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0),
-	MSTP("rtc0", &r_clk, MSTPCR1, 8, 0),
-
-	MSTP("sdhi0", &div4_clks[DIV4_P], MSTPCR2, 18, 0),
-	MSTP("keysc0", &r_clk, MSTPCR2, 14, 0),
-	MSTP("usbf0", &div4_clks[DIV4_P], MSTPCR2, 11, 0),
-	MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 9, 0),
-	MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0),
-	MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0),
-	MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, CLK_ENABLE_ON_INIT),
-	MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0),
-	MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0),
-	MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, CLK_ENABLE_ON_INIT),
-	MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, CLK_ENABLE_ON_INIT),
-	MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0),
+	SH_HWBLK_CLK("uram0", -1, U_CLK, HWBLK_URAM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("xymem0", -1, B_CLK, HWBLK_XYMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU, 0),
+	SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+	SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+	SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
+	SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+	SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+	SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+
+	SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
+	SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
+
+	SH_HWBLK_CLK("sdhi0", -1, P_CLK, HWBLK_SDHI, 0),
+	SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+	SH_HWBLK_CLK("usbf0", -1, P_CLK, HWBLK_USBF, 0),
+	SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+	SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
+	SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+	SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0),
+	SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
+	SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
+	SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU, 0),
+	SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
+	SH_HWBLK_CLK("lcdc0", -1, P_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -191,7 +192,7 @@ int __init arch_clk_init(void)
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
-		ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+		ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
 	return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index e67c267..20a31c2 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7723.h>
 
 /* SH7723 registers */
 #define FRQCR		0xa4150000
@@ -30,9 +32,6 @@
 #define SCLKBCR		0xa415000c
 #define IRDACLKCR	0xa4150018
 #define PLLCR		0xa4150024
-#define MSTPCR0		0xa4150030
-#define MSTPCR1		0xa4150034
-#define MSTPCR2		0xa4150038
 #define DLLFRQ		0xa4150050
 
 /* Fixed 32 KHz root clock for RTC and Power Management purposes */
@@ -140,60 +139,64 @@ struct clk div6_clks[] = {
 	SH_CLK_DIV6("video_clk", &pll_clk, VCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
+#define R_CLK (&r_clk)
+#define P_CLK (&div4_clks[DIV4_P])
+#define B_CLK (&div4_clks[DIV4_B])
+#define U_CLK (&div4_clks[DIV4_U])
+#define I_CLK (&div4_clks[DIV4_I])
+#define SH_CLK (&div4_clks[DIV4_SH])
 
 static struct clk mstp_clks[] = {
 	/* See page 60 of Datasheet V1.0: Overview -> Block Diagram */
-	MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
-	MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
-	MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
-	MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 28, 1, 1, 0),
-	MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
-	MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
-	MSTP("intc0", &div4_clks[DIV4_I], MSTPCR0, 22, 1, 1, 0),
-	MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
-	MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
-	MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
-	MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
-	MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
-	MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
-	MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
-	MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
-	MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 11, 0, 1, 0),
-	MSTP("flctl0", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
-	MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
-	MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
-	MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
-	MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
-	MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
-	MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
-	MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
-	MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
-	MSTP("meram0", &div4_clks[DIV4_SH], MSTPCR0, 0, 1, 1, 0),
-
-	MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
-	MSTP("rtc0", &r_clk, MSTPCR1, 8, 0, 0, 0),
-
-	MSTP("atapi0", &div4_clks[DIV4_SH], MSTPCR2, 28, 0, 1, 0),
-	MSTP("adc0", &div4_clks[DIV4_P], MSTPCR2, 27, 0, 1, 0),
-	MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
-	MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
-	MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
-	MSTP("icb0", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
-	MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
-	MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
-	MSTP("keysc0", &r_clk, MSTPCR2, 14, 0, 0, 0),
-	MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 11, 0, 1, 0),
-	MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 10, 0, 1, 1),
-	MSTP("siu0", &div4_clks[DIV4_B], MSTPCR2, 8, 0, 1, 0),
-	MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
-	MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
-	MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
-	MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
-	MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
-	MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
-	MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
+	SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("intc0", -1, I_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
+	SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
+	SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
+	SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
+	SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+	SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+	SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
+	SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
+	SH_HWBLK_CLK("flctl0", -1, P_CLK, HWBLK_FLCTL, 0),
+	SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+	SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+	SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+	SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
+	SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
+	SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
+	SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
+	SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
+	SH_HWBLK_CLK("meram0", -1, SH_CLK, HWBLK_MERAM, 0),
+
+	SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC, 0),
+	SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
+
+	SH_HWBLK_CLK("atapi0", -1, SH_CLK, HWBLK_ATAPI, 0),
+	SH_HWBLK_CLK("adc0", -1, P_CLK, HWBLK_ADC, 0),
+	SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
+	SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
+	SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
+	SH_HWBLK_CLK("icb0", -1, B_CLK, HWBLK_ICB, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
+	SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
+	SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+	SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB, 0),
+	SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+	SH_HWBLK_CLK("siu0", -1, B_CLK, HWBLK_SIU, 0),
+	SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU2H1, 0),
+	SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+	SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU, 0),
+	SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU, 0),
+	SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU2H0, 0),
+	SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
+	SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -216,7 +219,7 @@ int __init arch_clk_init(void)
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
-		ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+		ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
 	return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 5d5c9b9..dfe9192 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -22,6 +22,8 @@
 #include <linux/kernel.h>
 #include <linux/io.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7724.h>
 
 /* SH7724 registers */
 #define FRQCRA		0xa4150000
@@ -31,9 +33,6 @@
 #define FCLKBCR		0xa415000c
 #define IRDACLKCR	0xa4150018
 #define PLLCR		0xa4150024
-#define MSTPCR0		0xa4150030
-#define MSTPCR1		0xa4150034
-#define MSTPCR2		0xa4150038
 #define SPUCLKCR	0xa415003c
 #define FLLFRQ		0xa4150050
 #define LSTATS		0xa4150060
@@ -128,7 +127,7 @@ struct clk *main_clks[] = {
 	&div3_clk,
 };
 
-static int divisors[] = { 2, 0, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 0, 24, 32, 36, 48, 0, 72 };
 
 static struct clk_div_mult_table div4_table = {
 	.divisors = divisors,
@@ -156,64 +155,67 @@ struct clk div6_clks[] = {
 	SH_CLK_DIV6("spu_clk", &div3_clk, SPUCLKCR, 0),
 };
 
-#define MSTP(_str, _parent, _reg, _bit, _force_on, _need_cpg, _need_ram) \
-  SH_CLK_MSTP32(_str, -1, _parent, _reg, _bit, _force_on * CLK_ENABLE_ON_INIT)
+#define R_CLK (&r_clk)
+#define P_CLK (&div4_clks[DIV4_P])
+#define B_CLK (&div4_clks[DIV4_B])
+#define I_CLK (&div4_clks[DIV4_I])
+#define SH_CLK (&div4_clks[DIV4_SH])
 
 static struct clk mstp_clks[] = {
-	MSTP("tlb0", &div4_clks[DIV4_I], MSTPCR0, 31, 1, 1, 0),
-	MSTP("ic0", &div4_clks[DIV4_I], MSTPCR0, 30, 1, 1, 0),
-	MSTP("oc0", &div4_clks[DIV4_I], MSTPCR0, 29, 1, 1, 0),
-	MSTP("rs0", &div4_clks[DIV4_B], MSTPCR0, 28, 1, 1, 0),
-	MSTP("ilmem0", &div4_clks[DIV4_I], MSTPCR0, 27, 1, 1, 0),
-	MSTP("l2c0", &div4_clks[DIV4_SH], MSTPCR0, 26, 1, 1, 0),
-	MSTP("fpu0", &div4_clks[DIV4_I], MSTPCR0, 24, 1, 1, 0),
-	MSTP("intc0", &div4_clks[DIV4_P], MSTPCR0, 22, 1, 1, 0),
-	MSTP("dmac0", &div4_clks[DIV4_B], MSTPCR0, 21, 0, 1, 1),
-	MSTP("sh0", &div4_clks[DIV4_SH], MSTPCR0, 20, 0, 1, 0),
-	MSTP("hudi0", &div4_clks[DIV4_P], MSTPCR0, 19, 0, 1, 0),
-	MSTP("ubc0", &div4_clks[DIV4_I], MSTPCR0, 17, 0, 1, 0),
-	MSTP("tmu0", &div4_clks[DIV4_P], MSTPCR0, 15, 0, 1, 0),
-	MSTP("cmt0", &r_clk, MSTPCR0, 14, 0, 0, 0),
-	MSTP("rwdt0", &r_clk, MSTPCR0, 13, 0, 0, 0),
-	MSTP("dmac1", &div4_clks[DIV4_B], MSTPCR0, 12, 0, 1, 1),
-	MSTP("tmu1", &div4_clks[DIV4_P], MSTPCR0, 10, 0, 1, 0),
-	MSTP("scif0", &div4_clks[DIV4_P], MSTPCR0, 9, 0, 1, 0),
-	MSTP("scif1", &div4_clks[DIV4_P], MSTPCR0, 8, 0, 1, 0),
-	MSTP("scif2", &div4_clks[DIV4_P], MSTPCR0, 7, 0, 1, 0),
-	MSTP("scif3", &div4_clks[DIV4_B], MSTPCR0, 6, 0, 1, 0),
-	MSTP("scif4", &div4_clks[DIV4_B], MSTPCR0, 5, 0, 1, 0),
-	MSTP("scif5", &div4_clks[DIV4_B], MSTPCR0, 4, 0, 1, 0),
-	MSTP("msiof0", &div4_clks[DIV4_B], MSTPCR0, 2, 0, 1, 0),
-	MSTP("msiof1", &div4_clks[DIV4_B], MSTPCR0, 1, 0, 1, 0),
-
-	MSTP("keysc0", &r_clk, MSTPCR1, 12, 0, 0, 0),
-	MSTP("rtc0", &r_clk, MSTPCR1, 11, 0, 0, 0),
-	MSTP("i2c0", &div4_clks[DIV4_P], MSTPCR1, 9, 0, 1, 0),
-	MSTP("i2c1", &div4_clks[DIV4_P], MSTPCR1, 8, 0, 1, 0),
-
-	MSTP("mmc0", &div4_clks[DIV4_B], MSTPCR2, 29, 0, 1, 0),
-	MSTP("eth0", &div4_clks[DIV4_B], MSTPCR2, 28, 0, 1, 0),
-	MSTP("atapi0", &div4_clks[DIV4_B], MSTPCR2, 26, 0, 1, 0),
-	MSTP("tpu0", &div4_clks[DIV4_B], MSTPCR2, 25, 0, 1, 0),
-	MSTP("irda0", &div4_clks[DIV4_P], MSTPCR2, 24, 0, 1, 0),
-	MSTP("tsif0", &div4_clks[DIV4_B], MSTPCR2, 22, 0, 1, 0),
-	MSTP("usb1", &div4_clks[DIV4_B], MSTPCR2, 21, 0, 1, 1),
-	MSTP("usb0", &div4_clks[DIV4_B], MSTPCR2, 20, 0, 1, 1),
-	MSTP("2dg0", &div4_clks[DIV4_B], MSTPCR2, 19, 0, 1, 1),
-	MSTP("sdhi0", &div4_clks[DIV4_B], MSTPCR2, 18, 0, 1, 0),
-	MSTP("sdhi1", &div4_clks[DIV4_B], MSTPCR2, 17, 0, 1, 0),
-	MSTP("veu1", &div4_clks[DIV4_B], MSTPCR2, 15, 1, 1, 1),
-	MSTP("ceu1", &div4_clks[DIV4_B], MSTPCR2, 13, 0, 1, 1),
-	MSTP("beu1", &div4_clks[DIV4_B], MSTPCR2, 12, 0, 1, 1),
-	MSTP("2ddmac0", &div4_clks[DIV4_SH], MSTPCR2, 10, 0, 1, 1),
-	MSTP("spu0", &div4_clks[DIV4_B], MSTPCR2, 9, 0, 1, 0),
-	MSTP("jpu0", &div4_clks[DIV4_B], MSTPCR2, 6, 1, 1, 1),
-	MSTP("vou0", &div4_clks[DIV4_B], MSTPCR2, 5, 0, 1, 1),
-	MSTP("beu0", &div4_clks[DIV4_B], MSTPCR2, 4, 0, 1, 1),
-	MSTP("ceu0", &div4_clks[DIV4_B], MSTPCR2, 3, 0, 1, 1),
-	MSTP("veu0", &div4_clks[DIV4_B], MSTPCR2, 2, 1, 1, 1),
-	MSTP("vpu0", &div4_clks[DIV4_B], MSTPCR2, 1, 1, 1, 1),
-	MSTP("lcdc0", &div4_clks[DIV4_B], MSTPCR2, 0, 0, 1, 1),
+	SH_HWBLK_CLK("tlb0", -1, I_CLK, HWBLK_TLB, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ic0", -1, I_CLK, HWBLK_IC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("oc0", -1, I_CLK, HWBLK_OC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("rs0", -1, B_CLK, HWBLK_RSMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("ilmem0", -1, I_CLK, HWBLK_ILMEM, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("l2c0", -1, SH_CLK, HWBLK_L2C, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("fpu0", -1, I_CLK, HWBLK_FPU, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("intc0", -1, P_CLK, HWBLK_INTC, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("dmac0", -1, B_CLK, HWBLK_DMAC0, 0),
+	SH_HWBLK_CLK("sh0", -1, SH_CLK, HWBLK_SHYWAY, CLK_ENABLE_ON_INIT),
+	SH_HWBLK_CLK("hudi0", -1, P_CLK, HWBLK_HUDI, 0),
+	SH_HWBLK_CLK("ubc0", -1, I_CLK, HWBLK_UBC, 0),
+	SH_HWBLK_CLK("tmu0", -1, P_CLK, HWBLK_TMU0, 0),
+	SH_HWBLK_CLK("cmt0", -1, R_CLK, HWBLK_CMT, 0),
+	SH_HWBLK_CLK("rwdt0", -1, R_CLK, HWBLK_RWDT, 0),
+	SH_HWBLK_CLK("dmac1", -1, B_CLK, HWBLK_DMAC1, 0),
+	SH_HWBLK_CLK("tmu1", -1, P_CLK, HWBLK_TMU1, 0),
+	SH_HWBLK_CLK("scif0", -1, P_CLK, HWBLK_SCIF0, 0),
+	SH_HWBLK_CLK("scif1", -1, P_CLK, HWBLK_SCIF1, 0),
+	SH_HWBLK_CLK("scif2", -1, P_CLK, HWBLK_SCIF2, 0),
+	SH_HWBLK_CLK("scif3", -1, B_CLK, HWBLK_SCIF3, 0),
+	SH_HWBLK_CLK("scif4", -1, B_CLK, HWBLK_SCIF4, 0),
+	SH_HWBLK_CLK("scif5", -1, B_CLK, HWBLK_SCIF5, 0),
+	SH_HWBLK_CLK("msiof0", -1, B_CLK, HWBLK_MSIOF0, 0),
+	SH_HWBLK_CLK("msiof1", -1, B_CLK, HWBLK_MSIOF1, 0),
+
+	SH_HWBLK_CLK("keysc0", -1, R_CLK, HWBLK_KEYSC, 0),
+	SH_HWBLK_CLK("rtc0", -1, R_CLK, HWBLK_RTC, 0),
+	SH_HWBLK_CLK("i2c0", -1, P_CLK, HWBLK_IIC0, 0),
+	SH_HWBLK_CLK("i2c1", -1, P_CLK, HWBLK_IIC1, 0),
+
+	SH_HWBLK_CLK("mmc0", -1, B_CLK, HWBLK_MMC, 0),
+	SH_HWBLK_CLK("eth0", -1, B_CLK, HWBLK_ETHER, 0),
+	SH_HWBLK_CLK("atapi0", -1, B_CLK, HWBLK_ATAPI, 0),
+	SH_HWBLK_CLK("tpu0", -1, B_CLK, HWBLK_TPU, 0),
+	SH_HWBLK_CLK("irda0", -1, P_CLK, HWBLK_IRDA, 0),
+	SH_HWBLK_CLK("tsif0", -1, B_CLK, HWBLK_TSIF, 0),
+	SH_HWBLK_CLK("usb1", -1, B_CLK, HWBLK_USB1, 0),
+	SH_HWBLK_CLK("usb0", -1, B_CLK, HWBLK_USB0, 0),
+	SH_HWBLK_CLK("2dg0", -1, B_CLK, HWBLK_2DG, 0),
+	SH_HWBLK_CLK("sdhi0", -1, B_CLK, HWBLK_SDHI0, 0),
+	SH_HWBLK_CLK("sdhi1", -1, B_CLK, HWBLK_SDHI1, 0),
+	SH_HWBLK_CLK("veu1", -1, B_CLK, HWBLK_VEU1, 0),
+	SH_HWBLK_CLK("ceu1", -1, B_CLK, HWBLK_CEU1, 0),
+	SH_HWBLK_CLK("beu1", -1, B_CLK, HWBLK_BEU1, 0),
+	SH_HWBLK_CLK("2ddmac0", -1, SH_CLK, HWBLK_2DDMAC, 0),
+	SH_HWBLK_CLK("spu0", -1, B_CLK, HWBLK_SPU, 0),
+	SH_HWBLK_CLK("jpu0", -1, B_CLK, HWBLK_JPU, 0),
+	SH_HWBLK_CLK("vou0", -1, B_CLK, HWBLK_VOU, 0),
+	SH_HWBLK_CLK("beu0", -1, B_CLK, HWBLK_BEU0, 0),
+	SH_HWBLK_CLK("ceu0", -1, B_CLK, HWBLK_CEU0, 0),
+	SH_HWBLK_CLK("veu0", -1, B_CLK, HWBLK_VEU0, 0),
+	SH_HWBLK_CLK("vpu0", -1, B_CLK, HWBLK_VPU, 0),
+	SH_HWBLK_CLK("lcdc0", -1, B_CLK, HWBLK_LCDC, 0),
 };
 
 int __init arch_clk_init(void)
@@ -236,7 +238,7 @@ int __init arch_clk_init(void)
 		ret = sh_clk_div6_register(div6_clks, ARRAY_SIZE(div6_clks));
 
 	if (!ret)
-		ret = sh_clk_mstp32_register(mstp_clks, ARRAY_SIZE(mstp_clks));
+		ret = sh_hwblk_clk_register(mstp_clks, ARRAY_SIZE(mstp_clks));
 
 	return ret;
 }
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
new file mode 100644
index 0000000..ddc235c
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -0,0 +1,130 @@
+/*
+ * arch/sh/kernel/cpu/sh4/clock-sh7757.c
+ *
+ * SH7757 support for the clock framework
+ *
+ *  Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/clock.h>
+#include <asm/freq.h>
+
+static int ifc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			      16, 1, 1, 32, 1, 1, 1, 1 };
+static int sfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			      16, 1, 1, 32, 1, 1, 1, 1 };
+static int bfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			      16, 1, 1, 32, 1, 1, 1, 1 };
+static int p1fc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
+			       16, 1, 1, 32, 1, 1, 1, 1 };
+
+static void master_clk_init(struct clk *clk)
+{
+	clk->rate = CONFIG_SH_PCLK_FREQ * 16;
+}
+
+static struct clk_ops sh7757_master_clk_ops = {
+	.init		= master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+	int idx = ctrl_inl(FRQCR) & 0x0000000f;
+	clk->rate = clk->parent->rate / p1fc_divisors[idx];
+}
+
+static struct clk_ops sh7757_module_clk_ops = {
+	.recalc		= module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 8) & 0x0000000f;
+	clk->rate = clk->parent->rate / bfc_divisors[idx];
+}
+
+static struct clk_ops sh7757_bus_clk_ops = {
+	.recalc		= bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 20) & 0x0000000f;
+	clk->rate = clk->parent->rate / ifc_divisors[idx];
+}
+
+static struct clk_ops sh7757_cpu_clk_ops = {
+	.recalc		= cpu_clk_recalc,
+};
+
+static struct clk_ops *sh7757_clk_ops[] = {
+	&sh7757_master_clk_ops,
+	&sh7757_module_clk_ops,
+	&sh7757_bus_clk_ops,
+	&sh7757_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+	if (idx < ARRAY_SIZE(sh7757_clk_ops))
+		*ops = sh7757_clk_ops[idx];
+}
+
+static void shyway_clk_recalc(struct clk *clk)
+{
+	int idx = (ctrl_inl(FRQCR) >> 12) & 0x0000000f;
+	clk->rate = clk->parent->rate / sfc_divisors[idx];
+}
+
+static struct clk_ops sh7757_shyway_clk_ops = {
+	.recalc		= shyway_clk_recalc,
+};
+
+static struct clk sh7757_shyway_clk = {
+	.name		= "shyway_clk",
+	.flags		= CLK_ENABLE_ON_INIT,
+	.ops		= &sh7757_shyway_clk_ops,
+};
+
+/*
+ * Additional sh7757-specific on-chip clocks that aren't already part of the
+ * clock framework
+ */
+static struct clk *sh7757_onchip_clocks[] = {
+	&sh7757_shyway_clk,
+};
+
+static int __init sh7757_clk_init(void)
+{
+	struct clk *clk = clk_get(NULL, "master_clk");
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(sh7757_onchip_clocks); i++) {
+		struct clk *clkp = sh7757_onchip_clocks[i];
+
+		clkp->parent = clk;
+		clk_register(clkp);
+		clk_enable(clkp);
+	}
+
+	/*
+	 * Now that we have the rest of the clocks registered, we need to
+	 * force the parent clock to propagate so that these clocks will
+	 * automatically figure out their rate. We cheat by handing the
+	 * parent clock its current rate and forcing child propagation.
+	 */
+	clk_set_rate(clk, clk_get_rate(clk));
+
+	clk_put(clk);
+
+	return 0;
+}
+
+arch_initcall(sh7757_clk_init);
+
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
new file mode 100644
index 0000000..a288b5d
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
@@ -0,0 +1,106 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c
+ *
+ * SH7722 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7722.h>
+
+/* SH7722 registers */
+#define MSTPCR0		0xa4150030
+#define MSTPCR1		0xa4150034
+#define MSTPCR2		0xa4150038
+
+/* SH7722 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7722_hwblk_area[] = {
+	[CORE_AREA] = HWBLK_AREA(0, 0),
+	[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+	[SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7722_hwblk[HWBLK_NR] = {
+	[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+	[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+	[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+	[HWBLK_URAM] = HWBLK(MSTPCR0, 28, CORE_AREA),
+	[HWBLK_XYMEM] = HWBLK(MSTPCR0, 26, CORE_AREA),
+	[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+	[HWBLK_DMAC] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+	[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+	[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+	[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+	[HWBLK_TMU] = HWBLK(MSTPCR0, 15, CORE_AREA),
+	[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+	[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+	[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
+	[HWBLK_SCIF0] = HWBLK(MSTPCR0, 7, CORE_AREA),
+	[HWBLK_SCIF1] = HWBLK(MSTPCR0, 6, CORE_AREA),
+	[HWBLK_SCIF2] = HWBLK(MSTPCR0, 5, CORE_AREA),
+	[HWBLK_SIO] = HWBLK(MSTPCR0, 3, CORE_AREA),
+	[HWBLK_SIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+	[HWBLK_SIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+
+	[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
+	[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
+
+	[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+	[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+	[HWBLK_SDHI] = HWBLK(MSTPCR2, 18, CORE_AREA),
+	[HWBLK_SIM] = HWBLK(MSTPCR2, 16, CORE_AREA),
+	[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
+	[HWBLK_TSIF] = HWBLK(MSTPCR2, 13, SUB_AREA),
+	[HWBLK_USBF] = HWBLK(MSTPCR2, 11, CORE_AREA),
+	[HWBLK_2DG] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
+	[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
+	[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+	[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+	[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+	[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+	[HWBLK_VEU] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+	[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+	[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7722_hwblk_info = {
+	.areas = sh7722_hwblk_area,
+	.nr_areas = ARRAY_SIZE(sh7722_hwblk_area),
+	.hwblks = sh7722_hwblk,
+	.nr_hwblks = ARRAY_SIZE(sh7722_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+	if (!sh7722_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+	if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+	return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+	return hwblk_register(&sh7722_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
new file mode 100644
index 0000000..a7f4684
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
@@ -0,0 +1,117 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7723.c
+ *
+ * SH7723 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7723.h>
+
+/* SH7723 registers */
+#define MSTPCR0		0xa4150030
+#define MSTPCR1		0xa4150034
+#define MSTPCR2		0xa4150038
+
+/* SH7723 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7723_hwblk_area[] = {
+	[CORE_AREA] = HWBLK_AREA(0, 0),
+	[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+	[SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7723_hwblk[HWBLK_NR] = {
+	[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+	[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+	[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+	[HWBLK_L2C] = HWBLK(MSTPCR0, 28, CORE_AREA),
+	[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
+	[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
+	[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+	[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+	[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+	[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+	[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
+	[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+	[HWBLK_SUBC] = HWBLK(MSTPCR0, 16, CORE_AREA),
+	[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
+	[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+	[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+	[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
+	[HWBLK_TMU1] = HWBLK(MSTPCR0, 11, CORE_AREA),
+	[HWBLK_FLCTL] = HWBLK(MSTPCR0, 10, CORE_AREA),
+	[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
+	[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
+	[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
+	[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
+	[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
+	[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
+	[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+	[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+	[HWBLK_MERAM] = HWBLK(MSTPCR0, 0, CORE_AREA),
+
+	[HWBLK_IIC] = HWBLK(MSTPCR1, 9, CORE_AREA),
+	[HWBLK_RTC] = HWBLK(MSTPCR1, 8, SUB_AREA),
+
+	[HWBLK_ATAPI] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
+	[HWBLK_ADC] = HWBLK(MSTPCR2, 27, CORE_AREA),
+	[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+	[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+	[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
+	[HWBLK_ICB] = HWBLK(MSTPCR2, 21, CORE_AREA_BM),
+	[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
+	[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
+	[HWBLK_KEYSC] = HWBLK(MSTPCR2, 14, SUB_AREA),
+	[HWBLK_USB] = HWBLK(MSTPCR2, 11, CORE_AREA),
+	[HWBLK_2DG] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
+	[HWBLK_SIU] = HWBLK(MSTPCR2, 8, CORE_AREA),
+	[HWBLK_VEU2H1] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+	[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+	[HWBLK_BEU] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+	[HWBLK_CEU] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+	[HWBLK_VEU2H0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+	[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+	[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7723_hwblk_info = {
+	.areas = sh7723_hwblk_area,
+	.nr_areas = ARRAY_SIZE(sh7723_hwblk_area),
+	.hwblks = sh7723_hwblk,
+	.nr_hwblks = ARRAY_SIZE(sh7723_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+	if (!sh7723_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+	if (!sh7723_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+	return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+	return hwblk_register(&sh7723_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
new file mode 100644
index 0000000..1613ad6
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
@@ -0,0 +1,121 @@
+/*
+ * arch/sh/kernel/cpu/sh4a/hwblk-sh7724.c
+ *
+ * SH7724 hardware block support
+ *
+ * Copyright (C) 2009 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/suspend.h>
+#include <asm/hwblk.h>
+#include <cpu/sh7724.h>
+
+/* SH7724 registers */
+#define MSTPCR0		0xa4150030
+#define MSTPCR1		0xa4150034
+#define MSTPCR2		0xa4150038
+
+/* SH7724 Power Domains */
+enum { CORE_AREA, SUB_AREA, CORE_AREA_BM };
+static struct hwblk_area sh7724_hwblk_area[] = {
+	[CORE_AREA] = HWBLK_AREA(0, 0),
+	[CORE_AREA_BM] = HWBLK_AREA(HWBLK_AREA_FLAG_PARENT, CORE_AREA),
+	[SUB_AREA] = HWBLK_AREA(0, 0),
+};
+
+/* Table mapping HWBLK to Module Stop Bit and Power Domain */
+static struct hwblk sh7724_hwblk[HWBLK_NR] = {
+	[HWBLK_TLB] = HWBLK(MSTPCR0, 31, CORE_AREA),
+	[HWBLK_IC] = HWBLK(MSTPCR0, 30, CORE_AREA),
+	[HWBLK_OC] = HWBLK(MSTPCR0, 29, CORE_AREA),
+	[HWBLK_RSMEM] = HWBLK(MSTPCR0, 28, CORE_AREA),
+	[HWBLK_ILMEM] = HWBLK(MSTPCR0, 27, CORE_AREA),
+	[HWBLK_L2C] = HWBLK(MSTPCR0, 26, CORE_AREA),
+	[HWBLK_FPU] = HWBLK(MSTPCR0, 24, CORE_AREA),
+	[HWBLK_INTC] = HWBLK(MSTPCR0, 22, CORE_AREA),
+	[HWBLK_DMAC0] = HWBLK(MSTPCR0, 21, CORE_AREA_BM),
+	[HWBLK_SHYWAY] = HWBLK(MSTPCR0, 20, CORE_AREA),
+	[HWBLK_HUDI] = HWBLK(MSTPCR0, 19, CORE_AREA),
+	[HWBLK_DBG] = HWBLK(MSTPCR0, 18, CORE_AREA),
+	[HWBLK_UBC] = HWBLK(MSTPCR0, 17, CORE_AREA),
+	[HWBLK_TMU0] = HWBLK(MSTPCR0, 15, CORE_AREA),
+	[HWBLK_CMT] = HWBLK(MSTPCR0, 14, SUB_AREA),
+	[HWBLK_RWDT] = HWBLK(MSTPCR0, 13, SUB_AREA),
+	[HWBLK_DMAC1] = HWBLK(MSTPCR0, 12, CORE_AREA_BM),
+	[HWBLK_TMU1] = HWBLK(MSTPCR0, 10, CORE_AREA),
+	[HWBLK_SCIF0] = HWBLK(MSTPCR0, 9, CORE_AREA),
+	[HWBLK_SCIF1] = HWBLK(MSTPCR0, 8, CORE_AREA),
+	[HWBLK_SCIF2] = HWBLK(MSTPCR0, 7, CORE_AREA),
+	[HWBLK_SCIF3] = HWBLK(MSTPCR0, 6, CORE_AREA),
+	[HWBLK_SCIF4] = HWBLK(MSTPCR0, 5, CORE_AREA),
+	[HWBLK_SCIF5] = HWBLK(MSTPCR0, 4, CORE_AREA),
+	[HWBLK_MSIOF0] = HWBLK(MSTPCR0, 2, CORE_AREA),
+	[HWBLK_MSIOF1] = HWBLK(MSTPCR0, 1, CORE_AREA),
+
+	[HWBLK_KEYSC] = HWBLK(MSTPCR1, 12, SUB_AREA),
+	[HWBLK_RTC] = HWBLK(MSTPCR1, 11, SUB_AREA),
+	[HWBLK_IIC0] = HWBLK(MSTPCR1, 9, CORE_AREA),
+	[HWBLK_IIC1] = HWBLK(MSTPCR1, 8, CORE_AREA),
+
+	[HWBLK_MMC] = HWBLK(MSTPCR2, 29, CORE_AREA),
+	[HWBLK_ETHER] = HWBLK(MSTPCR2, 28, CORE_AREA_BM),
+	[HWBLK_ATAPI] = HWBLK(MSTPCR2, 26, CORE_AREA_BM),
+	[HWBLK_TPU] = HWBLK(MSTPCR2, 25, CORE_AREA),
+	[HWBLK_IRDA] = HWBLK(MSTPCR2, 24, CORE_AREA),
+	[HWBLK_TSIF] = HWBLK(MSTPCR2, 22, CORE_AREA),
+	[HWBLK_USB1] = HWBLK(MSTPCR2, 21, CORE_AREA),
+	[HWBLK_USB0] = HWBLK(MSTPCR2, 20, CORE_AREA),
+	[HWBLK_2DG] = HWBLK(MSTPCR2, 19, CORE_AREA_BM),
+	[HWBLK_SDHI0] = HWBLK(MSTPCR2, 18, CORE_AREA),
+	[HWBLK_SDHI1] = HWBLK(MSTPCR2, 17, CORE_AREA),
+	[HWBLK_VEU1] = HWBLK(MSTPCR2, 15, CORE_AREA_BM),
+	[HWBLK_CEU1] = HWBLK(MSTPCR2, 13, CORE_AREA_BM),
+	[HWBLK_BEU1] = HWBLK(MSTPCR2, 12, CORE_AREA_BM),
+	[HWBLK_2DDMAC] = HWBLK(MSTPCR2, 10, CORE_AREA_BM),
+	[HWBLK_SPU] = HWBLK(MSTPCR2, 9, CORE_AREA_BM),
+	[HWBLK_JPU] = HWBLK(MSTPCR2, 6, CORE_AREA_BM),
+	[HWBLK_VOU] = HWBLK(MSTPCR2, 5, CORE_AREA_BM),
+	[HWBLK_BEU0] = HWBLK(MSTPCR2, 4, CORE_AREA_BM),
+	[HWBLK_CEU0] = HWBLK(MSTPCR2, 3, CORE_AREA_BM),
+	[HWBLK_VEU0] = HWBLK(MSTPCR2, 2, CORE_AREA_BM),
+	[HWBLK_VPU] = HWBLK(MSTPCR2, 1, CORE_AREA_BM),
+	[HWBLK_LCDC] = HWBLK(MSTPCR2, 0, CORE_AREA_BM),
+};
+
+static struct hwblk_info sh7724_hwblk_info = {
+	.areas = sh7724_hwblk_area,
+	.nr_areas = ARRAY_SIZE(sh7724_hwblk_area),
+	.hwblks = sh7724_hwblk,
+	.nr_hwblks = ARRAY_SIZE(sh7724_hwblk),
+};
+
+int arch_hwblk_sleep_mode(void)
+{
+	if (!sh7724_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_STANDBY | SUSP_SH_SF;
+
+	if (!sh7724_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE])
+		return SUSP_SH_SLEEP | SUSP_SH_SF;
+
+	return SUSP_SH_SLEEP;
+}
+
+int __init arch_hwblk_init(void)
+{
+	return hwblk_register(&sh7724_hwblk_info);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
new file mode 100644
index 0000000..ed23b15
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
@@ -0,0 +1,2019 @@
+/*
+ * SH7757 (A0 step) Pinmux
+ *
+ *  Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ *  Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * Based on SH7757 Pinmux
+ *  Copyright (C) 2008  Magnus Damm
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7757.h>
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+	PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA,
+	PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+	PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA,
+	PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+	PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA,
+	PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+	PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA,
+	PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+	PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA,
+	PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+	PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA,
+	PTG7_DATA, PTG6_DATA, PTG5_DATA, PTG4_DATA,
+	PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA,
+	PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+	PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
+	PTI7_DATA, PTI6_DATA, PTI5_DATA, PTI4_DATA,
+	PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA,
+	PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+	PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA,
+	PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+	PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
+	PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+	PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
+	PTM6_DATA, PTM5_DATA, PTM4_DATA,
+	PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
+	PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+	PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA,
+	PTO7_DATA, PTO6_DATA, PTO5_DATA, PTO4_DATA,
+	PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA,
+	PTP6_DATA, PTP5_DATA, PTP4_DATA,
+	PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA,
+	PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+	PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA,
+	PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+	PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
+	PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
+	PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
+	PTT5_DATA, PTT4_DATA,
+	PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
+	PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
+	PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
+	PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+	PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA,
+	PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+	PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA,
+	PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+	PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA,
+	PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+	PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA,
+	PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+	PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA,
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	PTA7_IN, PTA6_IN, PTA5_IN, PTA4_IN,
+	PTA3_IN, PTA2_IN, PTA1_IN, PTA0_IN,
+	PTB7_IN, PTB6_IN, PTB5_IN, PTB4_IN,
+	PTB3_IN, PTB2_IN, PTB1_IN, PTB0_IN,
+	PTC7_IN, PTC6_IN, PTC5_IN, PTC4_IN,
+	PTC3_IN, PTC2_IN, PTC1_IN, PTC0_IN,
+	PTD7_IN, PTD6_IN, PTD5_IN, PTD4_IN,
+	PTD3_IN, PTD2_IN, PTD1_IN, PTD0_IN,
+	PTE7_IN, PTE6_IN, PTE5_IN, PTE4_IN,
+	PTE3_IN, PTE2_IN, PTE1_IN, PTE0_IN,
+	PTF7_IN, PTF6_IN, PTF5_IN, PTF4_IN,
+	PTF3_IN, PTF2_IN, PTF1_IN, PTF0_IN,
+	PTG7_IN, PTG6_IN, PTG5_IN, PTG4_IN,
+	PTG3_IN, PTG2_IN, PTG1_IN, PTG0_IN,
+	PTH7_IN, PTH6_IN, PTH5_IN, PTH4_IN,
+	PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN,
+	PTI7_IN, PTI6_IN, PTI5_IN, PTI4_IN,
+	PTI3_IN, PTI2_IN, PTI1_IN, PTI0_IN,
+	PTJ7_IN, PTJ6_IN, PTJ5_IN, PTJ4_IN,
+	PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN,
+	PTK7_IN, PTK6_IN, PTK5_IN, PTK4_IN,
+	PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN,
+	PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN,
+	PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
+	PTM6_IN, PTM5_IN, PTM4_IN,
+	PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
+	PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN,
+	PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN,
+	PTO7_IN, PTO6_IN, PTO5_IN, PTO4_IN,
+	PTO3_IN, PTO2_IN, PTO1_IN, PTO0_IN,
+	PTP6_IN, PTP5_IN, PTP4_IN,
+	PTP3_IN, PTP2_IN, PTP1_IN, PTP0_IN,
+	PTQ6_IN, PTQ5_IN, PTQ4_IN,
+	PTQ3_IN, PTQ2_IN, PTQ1_IN, PTQ0_IN,
+	PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN,
+	PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN,
+	PTS7_IN, PTS6_IN, PTS5_IN, PTS4_IN,
+	PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN,
+	PTT5_IN, PTT4_IN,
+	PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN,
+	PTU7_IN, PTU6_IN, PTU5_IN, PTU4_IN,
+	PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
+	PTV7_IN, PTV6_IN, PTV5_IN, PTV4_IN,
+	PTV3_IN, PTV2_IN, PTV1_IN, PTV0_IN,
+	PTW7_IN, PTW6_IN, PTW5_IN, PTW4_IN,
+	PTW3_IN, PTW2_IN, PTW1_IN, PTW0_IN,
+	PTX7_IN, PTX6_IN, PTX5_IN, PTX4_IN,
+	PTX3_IN, PTX2_IN, PTX1_IN, PTX0_IN,
+	PTY7_IN, PTY6_IN, PTY5_IN, PTY4_IN,
+	PTY3_IN, PTY2_IN, PTY1_IN, PTY0_IN,
+	PTZ7_IN, PTZ6_IN, PTZ5_IN, PTZ4_IN,
+	PTZ3_IN, PTZ2_IN, PTZ1_IN, PTZ0_IN,
+	PINMUX_INPUT_END,
+
+	PINMUX_INPUT_PULLUP_BEGIN,
+	PTU7_IN_PU, PTU6_IN_PU, PTU5_IN_PU, PTU4_IN_PU,
+	PTU3_IN_PU, PTU2_IN_PU, PTU1_IN_PU, PTU0_IN_PU,
+	PTV7_IN_PU, PTV6_IN_PU, PTV5_IN_PU, PTV4_IN_PU,
+	PTV3_IN_PU, PTV2_IN_PU, PTV1_IN_PU, PTV0_IN_PU,
+	PTW7_IN_PU, PTW6_IN_PU, PTW5_IN_PU, PTW4_IN_PU,
+	PTW3_IN_PU, PTW2_IN_PU, PTW1_IN_PU, PTW0_IN_PU,
+	PTX7_IN_PU, PTX6_IN_PU, PTX5_IN_PU, PTX4_IN_PU,
+	PTX3_IN_PU, PTX2_IN_PU, PTX1_IN_PU, PTX0_IN_PU,
+	PTY7_IN_PU, PTY6_IN_PU, PTY5_IN_PU, PTY4_IN_PU,
+	PTY3_IN_PU, PTY2_IN_PU, PTY1_IN_PU, PTY0_IN_PU,
+	PINMUX_INPUT_PULLUP_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	PTA7_OUT, PTA6_OUT, PTA5_OUT, PTA4_OUT,
+	PTA3_OUT, PTA2_OUT, PTA1_OUT, PTA0_OUT,
+	PTB7_OUT, PTB6_OUT, PTB5_OUT, PTB4_OUT,
+	PTB3_OUT, PTB2_OUT, PTB1_OUT, PTB0_OUT,
+	PTC7_OUT, PTC6_OUT, PTC5_OUT, PTC4_OUT,
+	PTC3_OUT, PTC2_OUT, PTC1_OUT, PTC0_OUT,
+	PTD7_OUT, PTD6_OUT, PTD5_OUT, PTD4_OUT,
+	PTD3_OUT, PTD2_OUT, PTD1_OUT, PTD0_OUT,
+	PTE7_OUT, PTE6_OUT, PTE5_OUT, PTE4_OUT,
+	PTE3_OUT, PTE2_OUT, PTE1_OUT, PTE0_OUT,
+	PTF7_OUT, PTF6_OUT, PTF5_OUT, PTF4_OUT,
+	PTF3_OUT, PTF2_OUT, PTF1_OUT, PTF0_OUT,
+	PTG7_OUT, PTG6_OUT, PTG5_OUT, PTG4_OUT,
+	PTG3_OUT, PTG2_OUT, PTG1_OUT, PTG0_OUT,
+	PTH7_OUT, PTH6_OUT, PTH5_OUT, PTH4_OUT,
+	PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
+	PTI7_OUT, PTI6_OUT, PTI5_OUT, PTI4_OUT,
+	PTI3_OUT, PTI2_OUT, PTI1_OUT, PTI0_OUT,
+	PTJ7_OUT, PTJ6_OUT, PTJ5_OUT, PTJ4_OUT,
+	PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT,
+	PTK7_OUT, PTK6_OUT, PTK5_OUT, PTK4_OUT,
+	PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT,
+	PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT,
+	PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
+	PTM6_OUT, PTM5_OUT, PTM4_OUT,
+	PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
+	PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT,
+	PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT,
+	PTO7_OUT, PTO6_OUT, PTO5_OUT, PTO4_OUT,
+	PTO3_OUT, PTO2_OUT, PTO1_OUT, PTO0_OUT,
+	PTP6_OUT, PTP5_OUT, PTP4_OUT,
+	PTP3_OUT, PTP2_OUT, PTP1_OUT, PTP0_OUT,
+	PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
+	PTQ3_OUT, PTQ2_OUT, PTQ1_OUT, PTQ0_OUT,
+	PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT,
+	PTR3_OUT, PTR2_OUT, PTR1_OUT, PTR0_OUT,
+	PTS7_OUT, PTS6_OUT, PTS5_OUT, PTS4_OUT,
+	PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT,
+	PTT5_OUT, PTT4_OUT,
+	PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT,
+	PTU7_OUT, PTU6_OUT, PTU5_OUT, PTU4_OUT,
+	PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT,
+	PTV7_OUT, PTV6_OUT, PTV5_OUT, PTV4_OUT,
+	PTV3_OUT, PTV2_OUT, PTV1_OUT, PTV0_OUT,
+	PTW7_OUT, PTW6_OUT, PTW5_OUT, PTW4_OUT,
+	PTW3_OUT, PTW2_OUT, PTW1_OUT, PTW0_OUT,
+	PTX7_OUT, PTX6_OUT, PTX5_OUT, PTX4_OUT,
+	PTX3_OUT, PTX2_OUT, PTX1_OUT, PTX0_OUT,
+	PTY7_OUT, PTY6_OUT, PTY5_OUT, PTY4_OUT,
+	PTY3_OUT, PTY2_OUT, PTY1_OUT, PTY0_OUT,
+	PTZ7_OUT, PTZ6_OUT, PTZ5_OUT, PTZ4_OUT,
+	PTZ3_OUT, PTZ2_OUT, PTZ1_OUT, PTZ0_OUT,
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	PTA7_FN, PTA6_FN, PTA5_FN, PTA4_FN,
+	PTA3_FN, PTA2_FN, PTA1_FN, PTA0_FN,
+	PTB7_FN, PTB6_FN, PTB5_FN, PTB4_FN,
+	PTB3_FN, PTB2_FN, PTB1_FN, PTB0_FN,
+	PTC7_FN, PTC6_FN, PTC5_FN, PTC4_FN,
+	PTC3_FN, PTC2_FN, PTC1_FN, PTC0_FN,
+	PTD7_FN, PTD6_FN, PTD5_FN, PTD4_FN,
+	PTD3_FN, PTD2_FN, PTD1_FN, PTD0_FN,
+	PTE7_FN, PTE6_FN, PTE5_FN, PTE4_FN,
+	PTE3_FN, PTE2_FN, PTE1_FN, PTE0_FN,
+	PTF7_FN, PTF6_FN, PTF5_FN, PTF4_FN,
+	PTF3_FN, PTF2_FN, PTF1_FN, PTF0_FN,
+	PTG7_FN, PTG6_FN, PTG5_FN, PTG4_FN,
+	PTG3_FN, PTG2_FN, PTG1_FN, PTG0_FN,
+	PTH7_FN, PTH6_FN, PTH5_FN, PTH4_FN,
+	PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN,
+	PTI7_FN, PTI6_FN, PTI5_FN, PTI4_FN,
+	PTI3_FN, PTI2_FN, PTI1_FN, PTI0_FN,
+	PTJ7_FN, PTJ6_FN, PTJ5_FN, PTJ4_FN,
+	PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN,
+	PTK7_FN, PTK6_FN, PTK5_FN, PTK4_FN,
+	PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN,
+	PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN,
+	PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN,
+	PTM6_FN, PTM5_FN, PTM4_FN,
+	PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
+	PTN7_FN, PTN6_FN, PTN5_FN, PTN4_FN,
+	PTN3_FN, PTN2_FN, PTN1_FN, PTN0_FN,
+	PTO7_FN, PTO6_FN, PTO5_FN, PTO4_FN,
+	PTO3_FN, PTO2_FN, PTO1_FN, PTO0_FN,
+	PTP6_FN, PTP5_FN, PTP4_FN,
+	PTP3_FN, PTP2_FN, PTP1_FN, PTP0_FN,
+	PTQ6_FN, PTQ5_FN, PTQ4_FN,
+	PTQ3_FN, PTQ2_FN, PTQ1_FN, PTQ0_FN,
+	PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN,
+	PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN,
+	PTS7_FN, PTS6_FN, PTS5_FN, PTS4_FN,
+	PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN,
+	PTT5_FN, PTT4_FN,
+	PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN,
+	PTU7_FN, PTU6_FN, PTU5_FN, PTU4_FN,
+	PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN,
+	PTV7_FN, PTV6_FN, PTV5_FN, PTV4_FN,
+	PTV3_FN, PTV2_FN, PTV1_FN, PTV0_FN,
+	PTW7_FN, PTW6_FN, PTW5_FN, PTW4_FN,
+	PTW3_FN, PTW2_FN, PTW1_FN, PTW0_FN,
+	PTX7_FN, PTX6_FN, PTX5_FN, PTX4_FN,
+	PTX3_FN, PTX2_FN, PTX1_FN, PTX0_FN,
+	PTY7_FN, PTY6_FN, PTY5_FN, PTY4_FN,
+	PTY3_FN, PTY2_FN, PTY1_FN, PTY0_FN,
+	PTZ7_FN, PTZ6_FN, PTZ5_FN, PTZ4_FN,
+	PTZ3_FN, PTZ2_FN, PTZ1_FN, PTZ0_FN,
+
+	PS0_15_FN1, PS0_15_FN3,
+	PS0_14_FN1, PS0_14_FN3,
+	PS0_13_FN1, PS0_13_FN3,
+	PS0_12_FN1, PS0_12_FN3,
+	PS0_7_FN1, PS0_7_FN2,
+	PS0_6_FN1, PS0_6_FN2,
+	PS0_5_FN1, PS0_5_FN2,
+	PS0_4_FN1, PS0_4_FN2,
+	PS0_3_FN1, PS0_3_FN2,
+	PS0_2_FN1, PS0_2_FN2,
+	PS0_1_FN1, PS0_1_FN2,
+
+	PS1_7_FN1, PS1_7_FN3,
+	PS1_6_FN1, PS1_6_FN3,
+
+	PS2_13_FN1, PS2_13_FN3,
+	PS2_12_FN1, PS2_12_FN3,
+	PS2_1_FN1, PS2_1_FN2,
+	PS2_0_FN1, PS2_0_FN2,
+
+	PS4_15_FN1, PS4_15_FN2,
+	PS4_14_FN1, PS4_14_FN2,
+	PS4_13_FN1, PS4_13_FN2,
+	PS4_12_FN1, PS4_12_FN2,
+	PS4_11_FN1, PS4_11_FN2,
+	PS4_10_FN1, PS4_10_FN2,
+	PS4_9_FN1, PS4_9_FN2,
+	PS4_3_FN1, PS4_3_FN2,
+	PS4_2_FN1, PS4_2_FN2,
+	PS4_1_FN1, PS4_1_FN2,
+	PS4_0_FN1, PS4_0_FN2,
+
+	PS5_9_FN1, PS5_9_FN2,
+	PS5_8_FN1, PS5_8_FN2,
+	PS5_7_FN1, PS5_7_FN2,
+	PS5_6_FN1, PS5_6_FN2,
+	PS5_5_FN1, PS5_5_FN2,
+	PS5_4_FN1, PS5_4_FN2,
+
+	/* AN15 to 8 : EVENT15 to 8 */
+	PS6_7_FN_AN, PS6_7_FN_EV,
+	PS6_6_FN_AN, PS6_6_FN_EV,
+	PS6_5_FN_AN, PS6_5_FN_EV,
+	PS6_4_FN_AN, PS6_4_FN_EV,
+	PS6_3_FN_AN, PS6_3_FN_EV,
+	PS6_2_FN_AN, PS6_2_FN_EV,
+	PS6_1_FN_AN, PS6_1_FN_EV,
+	PS6_0_FN_AN, PS6_0_FN_EV,
+
+	PINMUX_FUNCTION_END,
+
+	PINMUX_MARK_BEGIN,
+	/* PTA (mobule: LBSC, CPG, LPC) */
+	BS_MARK,	RDWR_MARK,	WE1_MARK,	RDY_MARK,
+	MD10_MARK,	MD9_MARK,	MD8_MARK,
+	LGPIO7_MARK,	LGPIO6_MARK,	LGPIO5_MARK,	LGPIO4_MARK,
+	LGPIO3_MARK,	LGPIO2_MARK,	LGPIO1_MARK,	LGPIO0_MARK,
+
+	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	D15_MARK,	D14_MARK,	D13_MARK,	D12_MARK,
+	D11_MARK,	D10_MARK,	D9_MARK,	D8_MARK,
+	ET0_MDC_MARK,	ET0_MDIO_MARK,	ET1_MDC_MARK,	ET1_MDIO_MARK,
+	SIM_D_MARK,	SIM_CLK_MARK,	SIM_RST_MARK,
+	WPSZ1_MARK,	WPSZ0_MARK,	FWID_MARK,	FLSHSZ_MARK,
+	LPC_SPIEN_MARK,	BASEL_MARK,
+
+	/* PTC (mobule: SD) */
+	SD_WP_MARK,	SD_CD_MARK,	SD_CLK_MARK,	SD_CMD_MARK,
+	SD_D3_MARK,	SD_D2_MARK,	SD_D1_MARK,	SD_D0_MARK,
+
+	/* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+	IRQ7_MARK,	IRQ6_MARK,	IRQ5_MARK,	IRQ4_MARK,
+	IRQ3_MARK,	IRQ2_MARK,	IRQ1_MARK,	IRQ0_MARK,
+	MD6_MARK,	MD5_MARK,	MD3_MARK,	MD2_MARK,
+	MD1_MARK,	MD0_MARK,	ADTRG1_MARK,	ADTRG0_MARK,
+
+	/* PTE (mobule: EtherC) */
+	ET0_CRS_DV_MARK,	ET0_TXD1_MARK,
+	ET0_TXD0_MARK,		ET0_TX_EN_MARK,
+	ET0_REF_CLK_MARK,	ET0_RXD1_MARK,
+	ET0_RXD0_MARK,		ET0_RX_ER_MARK,
+
+	/* PTF (mobule: EtherC) */
+	ET1_CRS_DV_MARK,	ET1_TXD1_MARK,
+	ET1_TXD0_MARK,		ET1_TX_EN_MARK,
+	ET1_REF_CLK_MARK,	ET1_RXD1_MARK,
+	ET1_RXD0_MARK,		ET1_RX_ER_MARK,
+
+	/* PTG (mobule: SYSTEM, PWMX, LPC) */
+	STATUS0_MARK,	STATUS1_MARK,
+	PWX0_MARK,	PWX1_MARK,	PWX2_MARK,	PWX3_MARK,
+	SERIRQ_MARK,	CLKRUN_MARK,	LPCPD_MARK,	LDRQ_MARK,
+
+	/* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
+	TCLK_MARK,	RXD4_MARK,	TXD4_MARK,
+	SP1_MOSI_MARK,	SP1_MISO_MARK,	SP1_SCK_MARK,	SP1_SCK_FB_MARK,
+	SP1_SS0_MARK,	SP1_SS1_MARK,	SP0_SS1_MARK,
+
+	/* PTI (mobule: INTC) */
+	IRQ15_MARK,	IRQ14_MARK,	IRQ13_MARK,	IRQ12_MARK,
+	IRQ11_MARK,	IRQ10_MARK,	IRQ9_MARK,	IRQ8_MARK,
+
+	/* PTJ (mobule: SCIF234, SERMUX) */
+	RXD3_MARK,	TXD3_MARK,	RXD2_MARK,	TXD2_MARK,
+	COM1_TXD_MARK,	COM1_RXD_MARK,	COM1_RTS_MARK,	COM1_CTS_MARK,
+
+	/* PTK (mobule: SERMUX) */
+	COM2_TXD_MARK,	COM2_RXD_MARK,	COM2_RTS_MARK,	COM2_CTS_MARK,
+	COM2_DTR_MARK,	COM2_DSR_MARK,	COM2_DCD_MARK,	COM2_RI_MARK,
+
+	/* PTL (mobule: SERMUX) */
+	RAC_TXD_MARK,	RAC_RXD_MARK,	RAC_RTS_MARK,	RAC_CTS_MARK,
+	RAC_DTR_MARK,	RAC_DSR_MARK,	RAC_DCD_MARK,	RAC_RI_MARK,
+
+	/* PTM (mobule: IIC, LPC) */
+	SDA6_MARK,	SCL6_MARK,	SDA7_MARK,	SCL7_MARK,
+	WP_MARK,	FMS0_MARK,	FMS1_MARK,
+
+	/* PTN (mobule: SCIF234, EVC) */
+	SCK2_MARK,	RTS4_MARK,	RTS3_MARK,	RTS2_MARK,
+	CTS4_MARK,	CTS3_MARK,	CTS2_MARK,
+	EVENT7_MARK,	EVENT6_MARK,	EVENT5_MARK,	EVENT4_MARK,
+	EVENT3_MARK,	EVENT2_MARK,	EVENT1_MARK,	EVENT0_MARK,
+
+	/* PTO (mobule: SGPIO) */
+	SGPIO0_CLK_MARK,	SGPIO0_LOAD_MARK,
+	SGPIO0_DI_MARK,		SGPIO0_DO_MARK,
+	SGPIO1_CLK_MARK,	SGPIO1_LOAD_MARK,
+	SGPIO1_DI_MARK,		SGPIO1_DO_MARK,
+
+	/* PTP (mobule: JMC, SCIF234) */
+	JMCTCK_MARK,	JMCTMS_MARK,	JMCTDO_MARK,	JMCTDI_MARK,
+	JMCRST_MARK,	SCK4_MARK,	SCK3_MARK,
+
+	/* PTQ (mobule: LPC) */
+	LAD3_MARK,	LAD2_MARK,	LAD1_MARK,	LAD0_MARK,
+	LFRAME_MARK,	LRESET_MARK,	LCLK_MARK,
+
+	/* PTR (mobule: GRA, IIC) */
+	DDC3_MARK,	DDC2_MARK,
+	SDA8_MARK,	SCL8_MARK,	SDA2_MARK,	SCL2_MARK,
+	SDA1_MARK,	SCL1_MARK,	SDA0_MARK,	SCL0_MARK,
+
+	/* PTS (mobule: GRA, IIC) */
+	DDC1_MARK,	DDC0_MARK,
+	SDA9_MARK,	SCL9_MARK,	SDA5_MARK,	SCL5_MARK,
+	SDA4_MARK,	SCL4_MARK,	SDA3_MARK,	SCL3_MARK,
+
+	/* PTT (mobule: SYSTEM, PWMX) */
+	AUDSYNC_MARK,		AUDCK_MARK,
+	AUDATA3_MARK,		AUDATA2_MARK,
+	AUDATA1_MARK,		AUDATA0_MARK,
+	PWX7_MARK,	PWX6_MARK,	PWX5_MARK,	PWX4_MARK,
+
+	/* PTU (mobule: LBSC, DMAC) */
+	CS6_MARK,	CS5_MARK,	CS4_MARK,	CS0_MARK,
+	RD_MARK,	WE0_MARK,	A25_MARK,	A24_MARK,
+	DREQ0_MARK,	DACK0_MARK,
+
+	/* PTV (mobule: LBSC, DMAC) */
+	A23_MARK,	A22_MARK,	A21_MARK,	A20_MARK,
+	A19_MARK,	A18_MARK,	A17_MARK,	A16_MARK,
+	TEND0_MARK,	DREQ1_MARK,	DACK1_MARK,	TEND1_MARK,
+
+	/* PTW (mobule: LBSC) */
+	A15_MARK,	A14_MARK,	A13_MARK,	A12_MARK,
+	A11_MARK,	A10_MARK,	A9_MARK,	A8_MARK,
+
+	/* PTX (mobule: LBSC) */
+	A7_MARK,	A6_MARK,	A5_MARK,	A4_MARK,
+	A3_MARK,	A2_MARK,	A1_MARK,	A0_MARK,
+
+	/* PTY (mobule: LBSC) */
+	D7_MARK,	D6_MARK,	D5_MARK,	D4_MARK,
+	D3_MARK,	D2_MARK,	D1_MARK,	D0_MARK,
+	PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+	/* PTA GPIO */
+	PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT),
+	PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT),
+	PINMUX_DATA(PTA5_DATA, PTA5_IN, PTA5_OUT),
+	PINMUX_DATA(PTA4_DATA, PTA4_IN, PTA4_OUT),
+	PINMUX_DATA(PTA3_DATA, PTA3_IN, PTA3_OUT),
+	PINMUX_DATA(PTA2_DATA, PTA2_IN, PTA2_OUT),
+	PINMUX_DATA(PTA1_DATA, PTA1_IN, PTA1_OUT),
+	PINMUX_DATA(PTA0_DATA, PTA0_IN, PTA0_OUT),
+
+	/* PTB GPIO */
+	PINMUX_DATA(PTB7_DATA, PTB7_IN, PTB7_OUT),
+	PINMUX_DATA(PTB6_DATA, PTB6_IN, PTB6_OUT),
+	PINMUX_DATA(PTB5_DATA, PTB5_IN, PTB5_OUT),
+	PINMUX_DATA(PTB4_DATA, PTB4_IN, PTB4_OUT),
+	PINMUX_DATA(PTB3_DATA, PTB3_IN, PTB3_OUT),
+	PINMUX_DATA(PTB2_DATA, PTB2_IN, PTB2_OUT),
+	PINMUX_DATA(PTB1_DATA, PTB1_IN, PTB1_OUT),
+	PINMUX_DATA(PTB0_DATA, PTB0_IN, PTB0_OUT),
+
+	/* PTC GPIO */
+	PINMUX_DATA(PTC7_DATA, PTC7_IN, PTC7_OUT),
+	PINMUX_DATA(PTC6_DATA, PTC6_IN, PTC6_OUT),
+	PINMUX_DATA(PTC5_DATA, PTC5_IN, PTC5_OUT),
+	PINMUX_DATA(PTC4_DATA, PTC4_IN, PTC4_OUT),
+	PINMUX_DATA(PTC3_DATA, PTC3_IN, PTC3_OUT),
+	PINMUX_DATA(PTC2_DATA, PTC2_IN, PTC2_OUT),
+	PINMUX_DATA(PTC1_DATA, PTC1_IN, PTC1_OUT),
+	PINMUX_DATA(PTC0_DATA, PTC0_IN, PTC0_OUT),
+
+	/* PTD GPIO */
+	PINMUX_DATA(PTD7_DATA, PTD7_IN, PTD7_OUT),
+	PINMUX_DATA(PTD6_DATA, PTD6_IN, PTD6_OUT),
+	PINMUX_DATA(PTD5_DATA, PTD5_IN, PTD5_OUT),
+	PINMUX_DATA(PTD4_DATA, PTD4_IN, PTD4_OUT),
+	PINMUX_DATA(PTD3_DATA, PTD3_IN, PTD3_OUT),
+	PINMUX_DATA(PTD2_DATA, PTD2_IN, PTD2_OUT),
+	PINMUX_DATA(PTD1_DATA, PTD1_IN, PTD1_OUT),
+	PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT),
+
+	/* PTE GPIO */
+	PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT),
+	PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT),
+	PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT),
+	PINMUX_DATA(PTE2_DATA, PTE2_IN, PTE2_OUT),
+	PINMUX_DATA(PTE1_DATA, PTE1_IN, PTE1_OUT),
+	PINMUX_DATA(PTE0_DATA, PTE0_IN, PTE0_OUT),
+
+	/* PTF GPIO */
+	PINMUX_DATA(PTF7_DATA, PTF7_IN, PTF7_OUT),
+	PINMUX_DATA(PTF6_DATA, PTF6_IN, PTF6_OUT),
+	PINMUX_DATA(PTF5_DATA, PTF5_IN, PTF5_OUT),
+	PINMUX_DATA(PTF4_DATA, PTF4_IN, PTF4_OUT),
+	PINMUX_DATA(PTF3_DATA, PTF3_IN, PTF3_OUT),
+	PINMUX_DATA(PTF2_DATA, PTF2_IN, PTF2_OUT),
+	PINMUX_DATA(PTF1_DATA, PTF1_IN, PTF1_OUT),
+	PINMUX_DATA(PTF0_DATA, PTF0_IN, PTF0_OUT),
+
+	/* PTG GPIO */
+	PINMUX_DATA(PTG7_DATA, PTG7_IN, PTG7_OUT),
+	PINMUX_DATA(PTG6_DATA, PTG6_IN, PTG6_OUT),
+	PINMUX_DATA(PTG5_DATA, PTG5_IN, PTG5_OUT),
+	PINMUX_DATA(PTG4_DATA, PTG4_IN, PTG4_OUT),
+	PINMUX_DATA(PTG3_DATA, PTG3_IN, PTG3_OUT),
+	PINMUX_DATA(PTG2_DATA, PTG2_IN, PTG2_OUT),
+	PINMUX_DATA(PTG1_DATA, PTG1_IN, PTG1_OUT),
+	PINMUX_DATA(PTG0_DATA, PTG0_IN, PTG0_OUT),
+
+	/* PTH GPIO */
+	PINMUX_DATA(PTH7_DATA, PTH7_IN, PTH7_OUT),
+	PINMUX_DATA(PTH6_DATA, PTH6_IN, PTH6_OUT),
+	PINMUX_DATA(PTH5_DATA, PTH5_IN, PTH5_OUT),
+	PINMUX_DATA(PTH4_DATA, PTH4_IN, PTH4_OUT),
+	PINMUX_DATA(PTH3_DATA, PTH3_IN, PTH3_OUT),
+	PINMUX_DATA(PTH2_DATA, PTH2_IN, PTH2_OUT),
+	PINMUX_DATA(PTH1_DATA, PTH1_IN, PTH1_OUT),
+	PINMUX_DATA(PTH0_DATA, PTH0_IN, PTH0_OUT),
+
+	/* PTI GPIO */
+	PINMUX_DATA(PTI7_DATA, PTI7_IN, PTI7_OUT),
+	PINMUX_DATA(PTI6_DATA, PTI6_IN, PTI6_OUT),
+	PINMUX_DATA(PTI5_DATA, PTI5_IN, PTI5_OUT),
+	PINMUX_DATA(PTI4_DATA, PTI4_IN, PTI4_OUT),
+	PINMUX_DATA(PTI3_DATA, PTI3_IN, PTI3_OUT),
+	PINMUX_DATA(PTI2_DATA, PTI2_IN, PTI2_OUT),
+	PINMUX_DATA(PTI1_DATA, PTI1_IN, PTI1_OUT),
+	PINMUX_DATA(PTI0_DATA, PTI0_IN, PTI0_OUT),
+
+	/* PTJ GPIO */
+	PINMUX_DATA(PTJ7_DATA, PTJ7_IN, PTJ7_OUT),
+	PINMUX_DATA(PTJ6_DATA, PTJ6_IN, PTJ6_OUT),
+	PINMUX_DATA(PTJ5_DATA, PTJ5_IN, PTJ5_OUT),
+	PINMUX_DATA(PTJ4_DATA, PTJ4_IN, PTJ4_OUT),
+	PINMUX_DATA(PTJ3_DATA, PTJ3_IN, PTJ3_OUT),
+	PINMUX_DATA(PTJ2_DATA, PTJ2_IN, PTJ2_OUT),
+	PINMUX_DATA(PTJ1_DATA, PTJ1_IN, PTJ1_OUT),
+	PINMUX_DATA(PTJ0_DATA, PTJ0_IN, PTJ0_OUT),
+
+	/* PTK GPIO */
+	PINMUX_DATA(PTK7_DATA, PTK7_IN, PTK7_OUT),
+	PINMUX_DATA(PTK6_DATA, PTK6_IN, PTK6_OUT),
+	PINMUX_DATA(PTK5_DATA, PTK5_IN, PTK5_OUT),
+	PINMUX_DATA(PTK4_DATA, PTK4_IN, PTK4_OUT),
+	PINMUX_DATA(PTK3_DATA, PTK3_IN, PTK3_OUT),
+	PINMUX_DATA(PTK2_DATA, PTK2_IN, PTK2_OUT),
+	PINMUX_DATA(PTK1_DATA, PTK1_IN, PTK1_OUT),
+	PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT),
+
+	/* PTL GPIO */
+	PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT),
+	PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT),
+	PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT),
+	PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT),
+	PINMUX_DATA(PTL3_DATA, PTL3_IN, PTL3_OUT),
+	PINMUX_DATA(PTL2_DATA, PTL2_IN, PTL2_OUT),
+	PINMUX_DATA(PTL1_DATA, PTL1_IN, PTL1_OUT),
+	PINMUX_DATA(PTL0_DATA, PTL0_IN, PTL0_OUT),
+
+	/* PTM GPIO */
+	PINMUX_DATA(PTM6_DATA, PTM6_IN, PTM6_OUT),
+	PINMUX_DATA(PTM5_DATA, PTM5_IN, PTM5_OUT),
+	PINMUX_DATA(PTM4_DATA, PTM4_IN, PTM4_OUT),
+	PINMUX_DATA(PTM3_DATA, PTM3_IN, PTM3_OUT),
+	PINMUX_DATA(PTM2_DATA, PTM2_IN, PTM2_OUT),
+	PINMUX_DATA(PTM1_DATA, PTM1_IN, PTM1_OUT),
+	PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT),
+
+	/* PTN GPIO */
+	PINMUX_DATA(PTN7_DATA, PTN7_IN, PTN7_OUT),
+	PINMUX_DATA(PTN6_DATA, PTN6_IN, PTN6_OUT),
+	PINMUX_DATA(PTN5_DATA, PTN5_IN, PTN5_OUT),
+	PINMUX_DATA(PTN4_DATA, PTN4_IN, PTN4_OUT),
+	PINMUX_DATA(PTN3_DATA, PTN3_IN, PTN3_OUT),
+	PINMUX_DATA(PTN2_DATA, PTN2_IN, PTN2_OUT),
+	PINMUX_DATA(PTN1_DATA, PTN1_IN, PTN1_OUT),
+	PINMUX_DATA(PTN0_DATA, PTN0_IN, PTN0_OUT),
+
+	/* PTO GPIO */
+	PINMUX_DATA(PTO7_DATA, PTO7_IN, PTO7_OUT),
+	PINMUX_DATA(PTO6_DATA, PTO6_IN, PTO6_OUT),
+	PINMUX_DATA(PTO5_DATA, PTO5_IN, PTO5_OUT),
+	PINMUX_DATA(PTO4_DATA, PTO4_IN, PTO4_OUT),
+	PINMUX_DATA(PTO3_DATA, PTO3_IN, PTO3_OUT),
+	PINMUX_DATA(PTO2_DATA, PTO2_IN, PTO2_OUT),
+	PINMUX_DATA(PTO1_DATA, PTO1_IN, PTO1_OUT),
+	PINMUX_DATA(PTO0_DATA, PTO0_IN, PTO0_OUT),
+
+	/* PTQ GPIO */
+	PINMUX_DATA(PTQ6_DATA, PTQ6_IN, PTQ6_OUT),
+	PINMUX_DATA(PTQ5_DATA, PTQ5_IN, PTQ5_OUT),
+	PINMUX_DATA(PTQ4_DATA, PTQ4_IN, PTQ4_OUT),
+	PINMUX_DATA(PTQ3_DATA, PTQ3_IN, PTQ3_OUT),
+	PINMUX_DATA(PTQ2_DATA, PTQ2_IN, PTQ2_OUT),
+	PINMUX_DATA(PTQ1_DATA, PTQ1_IN, PTQ1_OUT),
+	PINMUX_DATA(PTQ0_DATA, PTQ0_IN, PTQ0_OUT),
+
+	/* PTR GPIO */
+	PINMUX_DATA(PTR7_DATA, PTR7_IN, PTR7_OUT),
+	PINMUX_DATA(PTR6_DATA, PTR6_IN, PTR6_OUT),
+	PINMUX_DATA(PTR5_DATA, PTR5_IN, PTR5_OUT),
+	PINMUX_DATA(PTR4_DATA, PTR4_IN, PTR4_OUT),
+	PINMUX_DATA(PTR3_DATA, PTR3_IN, PTR3_OUT),
+	PINMUX_DATA(PTR2_DATA, PTR2_IN, PTR2_OUT),
+	PINMUX_DATA(PTR1_DATA, PTR1_IN, PTR1_OUT),
+	PINMUX_DATA(PTR0_DATA, PTR0_IN, PTR0_OUT),
+
+	/* PTS GPIO */
+	PINMUX_DATA(PTS7_DATA, PTS7_IN, PTS7_OUT),
+	PINMUX_DATA(PTS6_DATA, PTS6_IN, PTS6_OUT),
+	PINMUX_DATA(PTS5_DATA, PTS5_IN, PTS5_OUT),
+	PINMUX_DATA(PTS4_DATA, PTS4_IN, PTS4_OUT),
+	PINMUX_DATA(PTS3_DATA, PTS3_IN, PTS3_OUT),
+	PINMUX_DATA(PTS2_DATA, PTS2_IN, PTS2_OUT),
+	PINMUX_DATA(PTS1_DATA, PTS1_IN, PTS1_OUT),
+	PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT),
+
+	/* PTT GPIO */
+	PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT),
+	PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT),
+	PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT),
+	PINMUX_DATA(PTT2_DATA, PTT2_IN, PTT2_OUT),
+	PINMUX_DATA(PTT1_DATA, PTT1_IN, PTT1_OUT),
+	PINMUX_DATA(PTT0_DATA, PTT0_IN, PTT0_OUT),
+
+	/* PTU GPIO */
+	PINMUX_DATA(PTU7_DATA, PTU7_IN, PTU7_OUT),
+	PINMUX_DATA(PTU6_DATA, PTU6_IN, PTU6_OUT),
+	PINMUX_DATA(PTU5_DATA, PTU5_IN, PTU5_OUT),
+	PINMUX_DATA(PTU4_DATA, PTU4_IN, PTU4_OUT),
+	PINMUX_DATA(PTU3_DATA, PTU3_IN, PTU3_OUT),
+	PINMUX_DATA(PTU2_DATA, PTU2_IN, PTU2_OUT),
+	PINMUX_DATA(PTU1_DATA, PTU1_IN, PTU1_OUT),
+	PINMUX_DATA(PTU0_DATA, PTU0_IN, PTU0_OUT),
+
+	/* PTV GPIO */
+	PINMUX_DATA(PTV7_DATA, PTV7_IN, PTV7_OUT),
+	PINMUX_DATA(PTV6_DATA, PTV6_IN, PTV6_OUT),
+	PINMUX_DATA(PTV5_DATA, PTV5_IN, PTV5_OUT),
+	PINMUX_DATA(PTV4_DATA, PTV4_IN, PTV4_OUT),
+	PINMUX_DATA(PTV3_DATA, PTV3_IN, PTV3_OUT),
+	PINMUX_DATA(PTV2_DATA, PTV2_IN, PTV2_OUT),
+	PINMUX_DATA(PTV1_DATA, PTV1_IN, PTV1_OUT),
+	PINMUX_DATA(PTV0_DATA, PTV0_IN, PTV0_OUT),
+
+	/* PTW GPIO */
+	PINMUX_DATA(PTW7_DATA, PTW7_IN, PTW7_OUT),
+	PINMUX_DATA(PTW6_DATA, PTW6_IN, PTW6_OUT),
+	PINMUX_DATA(PTW5_DATA, PTW5_IN, PTW5_OUT),
+	PINMUX_DATA(PTW4_DATA, PTW4_IN, PTW4_OUT),
+	PINMUX_DATA(PTW3_DATA, PTW3_IN, PTW3_OUT),
+	PINMUX_DATA(PTW2_DATA, PTW2_IN, PTW2_OUT),
+	PINMUX_DATA(PTW1_DATA, PTW1_IN, PTW1_OUT),
+	PINMUX_DATA(PTW0_DATA, PTW0_IN, PTW0_OUT),
+
+	/* PTX GPIO */
+	PINMUX_DATA(PTX7_DATA, PTX7_IN, PTX7_OUT),
+	PINMUX_DATA(PTX6_DATA, PTX6_IN, PTX6_OUT),
+	PINMUX_DATA(PTX5_DATA, PTX5_IN, PTX5_OUT),
+	PINMUX_DATA(PTX4_DATA, PTX4_IN, PTX4_OUT),
+	PINMUX_DATA(PTX3_DATA, PTX3_IN, PTX3_OUT),
+	PINMUX_DATA(PTX2_DATA, PTX2_IN, PTX2_OUT),
+	PINMUX_DATA(PTX1_DATA, PTX1_IN, PTX1_OUT),
+	PINMUX_DATA(PTX0_DATA, PTX0_IN, PTX0_OUT),
+
+	/* PTY GPIO */
+	PINMUX_DATA(PTY7_DATA, PTY7_IN, PTY7_OUT),
+	PINMUX_DATA(PTY6_DATA, PTY6_IN, PTY6_OUT),
+	PINMUX_DATA(PTY5_DATA, PTY5_IN, PTY5_OUT),
+	PINMUX_DATA(PTY4_DATA, PTY4_IN, PTY4_OUT),
+	PINMUX_DATA(PTY3_DATA, PTY3_IN, PTY3_OUT),
+	PINMUX_DATA(PTY2_DATA, PTY2_IN, PTY2_OUT),
+	PINMUX_DATA(PTY1_DATA, PTY1_IN, PTY1_OUT),
+	PINMUX_DATA(PTY0_DATA, PTY0_IN, PTY0_OUT),
+
+	/* PTZ GPIO */
+	PINMUX_DATA(PTZ7_DATA, PTZ7_IN, PTZ7_OUT),
+	PINMUX_DATA(PTZ6_DATA, PTZ6_IN, PTZ6_OUT),
+	PINMUX_DATA(PTZ5_DATA, PTZ5_IN, PTZ5_OUT),
+	PINMUX_DATA(PTZ4_DATA, PTZ4_IN, PTZ4_OUT),
+	PINMUX_DATA(PTZ3_DATA, PTZ3_IN, PTZ3_OUT),
+	PINMUX_DATA(PTZ2_DATA, PTZ2_IN, PTZ2_OUT),
+	PINMUX_DATA(PTZ1_DATA, PTZ1_IN, PTZ1_OUT),
+	PINMUX_DATA(PTZ0_DATA, PTZ0_IN, PTZ0_OUT),
+
+	/* PTA FN */
+	PINMUX_DATA(BS_MARK, PS0_15_FN1, PTA7_FN),
+	PINMUX_DATA(LGPIO7_MARK, PS0_15_FN3, PTA7_FN),
+	PINMUX_DATA(RDWR_MARK, PS0_14_FN1, PTA6_FN),
+	PINMUX_DATA(LGPIO6_MARK, PS0_14_FN3, PTA6_FN),
+	PINMUX_DATA(WE1_MARK, PS0_13_FN1, PTA5_FN),
+	PINMUX_DATA(LGPIO5_MARK, PS0_13_FN3, PTA5_FN),
+	PINMUX_DATA(RDY_MARK, PS0_12_FN1, PTA4_FN),
+	PINMUX_DATA(LGPIO4_MARK, PS0_12_FN3, PTA4_FN),
+	PINMUX_DATA(LGPIO3_MARK, PTA3_FN),
+	PINMUX_DATA(LGPIO2_MARK, PTA2_FN),
+	PINMUX_DATA(LGPIO1_MARK, PTA1_FN),
+	PINMUX_DATA(LGPIO0_MARK, PTA0_FN),
+
+	/* PTB FN */
+	PINMUX_DATA(D15_MARK, PS0_7_FN1, PTB7_FN),
+	PINMUX_DATA(ET0_MDC_MARK, PS0_7_FN2, PTB7_FN),
+	PINMUX_DATA(D14_MARK, PS0_6_FN1, PTB6_FN),
+	PINMUX_DATA(ET0_MDIO_MARK, PS0_6_FN2, PTB6_FN),
+	PINMUX_DATA(D13_MARK, PS0_5_FN1, PTB5_FN),
+	PINMUX_DATA(ET1_MDC_MARK, PS0_5_FN2, PTB5_FN),
+	PINMUX_DATA(D12_MARK, PS0_4_FN1, PTB4_FN),
+	PINMUX_DATA(ET1_MDIO_MARK, PS0_4_FN2, PTB4_FN),
+	PINMUX_DATA(D11_MARK, PS0_3_FN1, PTB3_FN),
+	PINMUX_DATA(SIM_D_MARK, PS0_3_FN2, PTB3_FN),
+	PINMUX_DATA(D10_MARK, PS0_2_FN1, PTB2_FN),
+	PINMUX_DATA(SIM_CLK_MARK, PS0_2_FN2, PTB2_FN),
+	PINMUX_DATA(D9_MARK, PS0_1_FN1, PTB1_FN),
+	PINMUX_DATA(SIM_RST_MARK, PS0_1_FN2, PTB1_FN),
+	PINMUX_DATA(D8_MARK, PTB0_FN),
+
+	/* PTC FN */
+	PINMUX_DATA(SD_WP_MARK, PTC7_FN),
+	PINMUX_DATA(SD_CD_MARK, PTC6_FN),
+	PINMUX_DATA(SD_CLK_MARK, PTC5_FN),
+	PINMUX_DATA(SD_CMD_MARK, PTC4_FN),
+	PINMUX_DATA(SD_D3_MARK, PTC3_FN),
+	PINMUX_DATA(SD_D2_MARK, PTC2_FN),
+	PINMUX_DATA(SD_D1_MARK, PTC1_FN),
+	PINMUX_DATA(SD_D0_MARK, PTC0_FN),
+
+	/* PTD FN */
+	PINMUX_DATA(IRQ7_MARK, PS1_7_FN1, PTD7_FN),
+	PINMUX_DATA(ADTRG1_MARK, PS1_7_FN3, PTD7_FN),
+	PINMUX_DATA(IRQ6_MARK, PS1_6_FN1, PTD6_FN),
+	PINMUX_DATA(ADTRG0_MARK, PS1_6_FN3, PTD6_FN),
+	PINMUX_DATA(IRQ5_MARK, PTD5_FN),
+	PINMUX_DATA(IRQ4_MARK, PTD4_FN),
+	PINMUX_DATA(IRQ3_MARK, PTD3_FN),
+	PINMUX_DATA(IRQ2_MARK, PTD2_FN),
+	PINMUX_DATA(IRQ1_MARK, PTD1_FN),
+	PINMUX_DATA(IRQ0_MARK, PTD0_FN),
+
+	/* PTE FN */
+	PINMUX_DATA(ET0_CRS_DV_MARK, PTE7_FN),
+	PINMUX_DATA(ET0_TXD1_MARK, PTE6_FN),
+	PINMUX_DATA(ET0_TXD0_MARK, PTE5_FN),
+	PINMUX_DATA(ET0_TX_EN_MARK, PTE4_FN),
+	PINMUX_DATA(ET0_REF_CLK_MARK, PTE3_FN),
+	PINMUX_DATA(ET0_RXD1_MARK, PTE2_FN),
+	PINMUX_DATA(ET0_RXD0_MARK, PTE1_FN),
+	PINMUX_DATA(ET0_RX_ER_MARK, PTE0_FN),
+
+	/* PTF FN */
+	PINMUX_DATA(ET1_CRS_DV_MARK, PTF7_FN),
+	PINMUX_DATA(ET1_TXD1_MARK, PTF6_FN),
+	PINMUX_DATA(ET1_TXD0_MARK, PTF5_FN),
+	PINMUX_DATA(ET1_TX_EN_MARK, PTF4_FN),
+	PINMUX_DATA(ET1_REF_CLK_MARK, PTF3_FN),
+	PINMUX_DATA(ET1_RXD1_MARK, PTF2_FN),
+	PINMUX_DATA(ET1_RXD0_MARK, PTF1_FN),
+	PINMUX_DATA(ET1_RX_ER_MARK, PTF0_FN),
+
+	/* PTG FN */
+	PINMUX_DATA(PWX0_MARK, PTG7_FN),
+	PINMUX_DATA(PWX1_MARK, PTG6_FN),
+	PINMUX_DATA(STATUS0_MARK, PS2_13_FN1, PTG5_FN),
+	PINMUX_DATA(PWX2_MARK, PS2_13_FN3, PTG5_FN),
+	PINMUX_DATA(STATUS1_MARK, PS2_12_FN1, PTG4_FN),
+	PINMUX_DATA(PWX3_MARK, PS2_12_FN3, PTG4_FN),
+	PINMUX_DATA(SERIRQ_MARK, PTG3_FN),
+	PINMUX_DATA(CLKRUN_MARK, PTG2_FN),
+	PINMUX_DATA(LPCPD_MARK, PTG1_FN),
+	PINMUX_DATA(LDRQ_MARK, PTG0_FN),
+
+	/* PTH FN */
+	PINMUX_DATA(SP1_MOSI_MARK, PTH7_FN),
+	PINMUX_DATA(SP1_MISO_MARK, PTH6_FN),
+	PINMUX_DATA(SP1_SCK_MARK, PTH5_FN),
+	PINMUX_DATA(SP1_SCK_FB_MARK, PTH4_FN),
+	PINMUX_DATA(SP1_SS0_MARK, PTH3_FN),
+	PINMUX_DATA(TCLK_MARK, PTH2_FN),
+	PINMUX_DATA(RXD4_MARK, PS2_1_FN1, PTH1_FN),
+	PINMUX_DATA(SP1_SS1_MARK, PS2_1_FN2, PTH1_FN),
+	PINMUX_DATA(TXD4_MARK, PS2_0_FN1, PTH0_FN),
+	PINMUX_DATA(SP0_SS1_MARK, PS2_0_FN2, PTH0_FN),
+
+	/* PTI FN */
+	PINMUX_DATA(IRQ15_MARK, PTI7_FN),
+	PINMUX_DATA(IRQ14_MARK, PTI6_FN),
+	PINMUX_DATA(IRQ13_MARK, PTI5_FN),
+	PINMUX_DATA(IRQ12_MARK, PTI4_FN),
+	PINMUX_DATA(IRQ11_MARK, PTI3_FN),
+	PINMUX_DATA(IRQ10_MARK, PTI2_FN),
+	PINMUX_DATA(IRQ9_MARK, PTI1_FN),
+	PINMUX_DATA(IRQ8_MARK, PTI0_FN),
+
+	/* PTJ FN */
+	PINMUX_DATA(RXD3_MARK, PTJ7_FN),
+	PINMUX_DATA(TXD3_MARK, PTJ6_FN),
+	PINMUX_DATA(RXD2_MARK, PTJ5_FN),
+	PINMUX_DATA(TXD2_MARK, PTJ4_FN),
+	PINMUX_DATA(COM1_TXD_MARK, PTJ3_FN),
+	PINMUX_DATA(COM1_RXD_MARK, PTJ2_FN),
+	PINMUX_DATA(COM1_RTS_MARK, PTJ1_FN),
+	PINMUX_DATA(COM1_CTS_MARK, PTJ0_FN),
+
+	/* PTK FN */
+	PINMUX_DATA(COM2_TXD_MARK, PTK7_FN),
+	PINMUX_DATA(COM2_RXD_MARK, PTK6_FN),
+	PINMUX_DATA(COM2_RTS_MARK, PTK5_FN),
+	PINMUX_DATA(COM2_CTS_MARK, PTK4_FN),
+	PINMUX_DATA(COM2_DTR_MARK, PTK3_FN),
+	PINMUX_DATA(COM2_DSR_MARK, PTK2_FN),
+	PINMUX_DATA(COM2_DCD_MARK, PTK1_FN),
+	PINMUX_DATA(COM2_RI_MARK, PTK0_FN),
+
+	/* PTL FN */
+	PINMUX_DATA(RAC_TXD_MARK, PTL7_FN),
+	PINMUX_DATA(RAC_RXD_MARK, PTL6_FN),
+	PINMUX_DATA(RAC_RTS_MARK, PTL5_FN),
+	PINMUX_DATA(RAC_CTS_MARK, PTL4_FN),
+	PINMUX_DATA(RAC_DTR_MARK, PTL3_FN),
+	PINMUX_DATA(RAC_DSR_MARK, PTL2_FN),
+	PINMUX_DATA(RAC_DCD_MARK, PTL1_FN),
+	PINMUX_DATA(RAC_RI_MARK, PTL0_FN),
+
+	/* PTM FN */
+	PINMUX_DATA(WP_MARK, PTM6_FN),
+	PINMUX_DATA(FMS0_MARK, PTM5_FN),
+	PINMUX_DATA(FMS1_MARK, PTM4_FN),
+	PINMUX_DATA(SDA6_MARK, PTM3_FN),
+	PINMUX_DATA(SCL6_MARK, PTM2_FN),
+	PINMUX_DATA(SDA7_MARK, PTM1_FN),
+	PINMUX_DATA(SCL7_MARK, PTM0_FN),
+
+	/* PTN FN */
+	PINMUX_DATA(SCK2_MARK, PS4_15_FN1, PTN7_FN),
+	PINMUX_DATA(EVENT7_MARK, PS4_15_FN2, PTN7_FN),
+	PINMUX_DATA(RTS4_MARK, PS4_14_FN1, PTN6_FN),
+	PINMUX_DATA(EVENT6_MARK, PS4_14_FN2, PTN6_FN),
+	PINMUX_DATA(RTS3_MARK, PS4_13_FN1, PTN5_FN),
+	PINMUX_DATA(EVENT5_MARK, PS4_13_FN2, PTN5_FN),
+	PINMUX_DATA(RTS2_MARK, PS4_12_FN1, PTN4_FN),
+	PINMUX_DATA(EVENT4_MARK, PS4_12_FN2, PTN4_FN),
+	PINMUX_DATA(CTS4_MARK, PS4_11_FN1, PTN3_FN),
+	PINMUX_DATA(EVENT3_MARK, PS4_11_FN2, PTN3_FN),
+	PINMUX_DATA(CTS3_MARK, PS4_10_FN1, PTN2_FN),
+	PINMUX_DATA(EVENT2_MARK, PS4_10_FN2, PTN2_FN),
+	PINMUX_DATA(CTS2_MARK, PS4_9_FN1, PTN1_FN),
+	PINMUX_DATA(EVENT1_MARK, PS4_9_FN2, PTN1_FN),
+	PINMUX_DATA(EVENT0_MARK, PTN0_FN),
+
+	/* PTO FN */
+	PINMUX_DATA(SGPIO0_CLK_MARK, PTO7_FN),
+	PINMUX_DATA(SGPIO0_LOAD_MARK, PTO6_FN),
+	PINMUX_DATA(SGPIO0_DI_MARK, PTO5_FN),
+	PINMUX_DATA(SGPIO0_DO_MARK, PTO4_FN),
+	PINMUX_DATA(SGPIO1_CLK_MARK, PTO3_FN),
+	PINMUX_DATA(SGPIO1_LOAD_MARK, PTO2_FN),
+	PINMUX_DATA(SGPIO1_DI_MARK, PTO1_FN),
+	PINMUX_DATA(SGPIO1_DO_MARK, PTO0_FN),
+
+	/* PTP FN */
+	PINMUX_DATA(JMCTCK_MARK, PTP6_FN),
+	PINMUX_DATA(JMCTMS_MARK, PTP5_FN),
+	PINMUX_DATA(JMCTDO_MARK, PTP4_FN),
+	PINMUX_DATA(JMCTDI_MARK, PTP3_FN),
+	PINMUX_DATA(JMCRST_MARK, PTP2_FN),
+	PINMUX_DATA(SCK4_MARK, PTP1_FN),
+	PINMUX_DATA(SCK3_MARK, PTP0_FN),
+
+	/* PTQ FN */
+	PINMUX_DATA(LAD3_MARK, PTQ6_FN),
+	PINMUX_DATA(LAD2_MARK, PTQ5_FN),
+	PINMUX_DATA(LAD1_MARK, PTQ4_FN),
+	PINMUX_DATA(LAD0_MARK, PTQ3_FN),
+	PINMUX_DATA(LFRAME_MARK, PTQ2_FN),
+	PINMUX_DATA(SCK4_MARK, PTQ1_FN),
+	PINMUX_DATA(SCK3_MARK, PTQ0_FN),
+
+	/* PTR FN */
+	PINMUX_DATA(SDA8_MARK, PTR7_FN),	/* DDC3? */
+	PINMUX_DATA(SCL8_MARK, PTR6_FN),	/* DDC2? */
+	PINMUX_DATA(SDA2_MARK, PTR5_FN),
+	PINMUX_DATA(SCL2_MARK, PTR4_FN),
+	PINMUX_DATA(SDA1_MARK, PTR3_FN),
+	PINMUX_DATA(SCL1_MARK, PTR2_FN),
+	PINMUX_DATA(SDA0_MARK, PTR1_FN),
+	PINMUX_DATA(SCL0_MARK, PTR0_FN),
+
+	/* PTS FN */
+	PINMUX_DATA(SDA9_MARK, PTS7_FN),	/* DDC1? */
+	PINMUX_DATA(SCL9_MARK, PTS6_FN),	/* DDC0? */
+	PINMUX_DATA(SDA5_MARK, PTS5_FN),
+	PINMUX_DATA(SCL5_MARK, PTS4_FN),
+	PINMUX_DATA(SDA4_MARK, PTS3_FN),
+	PINMUX_DATA(SCL4_MARK, PTS2_FN),
+	PINMUX_DATA(SDA3_MARK, PTS1_FN),
+	PINMUX_DATA(SCL3_MARK, PTS0_FN),
+
+	/* PTT FN */
+	PINMUX_DATA(AUDSYNC_MARK, PTS5_FN),
+	PINMUX_DATA(AUDCK_MARK, PTS4_FN),
+	PINMUX_DATA(AUDATA3_MARK, PS4_3_FN1, PTS3_FN),
+	PINMUX_DATA(PWX7_MARK, PS4_3_FN2, PTS3_FN),
+	PINMUX_DATA(AUDATA2_MARK, PS4_2_FN1, PTS2_FN),
+	PINMUX_DATA(PWX6_MARK, PS4_2_FN2, PTS2_FN),
+	PINMUX_DATA(AUDATA1_MARK, PS4_1_FN1, PTS1_FN),
+	PINMUX_DATA(PWX5_MARK, PS4_1_FN2, PTS1_FN),
+	PINMUX_DATA(AUDATA0_MARK, PS4_0_FN1, PTS0_FN),
+	PINMUX_DATA(PWX4_MARK, PS4_0_FN2, PTS0_FN),
+
+	/* PTU FN */
+	PINMUX_DATA(CS6_MARK, PTU7_FN),
+	PINMUX_DATA(CS5_MARK, PTU6_FN),
+	PINMUX_DATA(CS4_MARK, PTU5_FN),
+	PINMUX_DATA(CS0_MARK, PTU4_FN),
+	PINMUX_DATA(RD_MARK, PTU3_FN),
+	PINMUX_DATA(WE0_MARK, PTU2_FN),
+	PINMUX_DATA(A25_MARK, PS5_9_FN1, PTU1_FN),
+	PINMUX_DATA(DREQ0_MARK, PS5_9_FN2, PTU1_FN),
+	PINMUX_DATA(A24_MARK, PS5_8_FN1, PTU0_FN),
+	PINMUX_DATA(DACK0_MARK, PS5_8_FN2, PTU0_FN),
+
+	/* PTV FN */
+	PINMUX_DATA(A23_MARK, PS5_7_FN1, PTV7_FN),
+	PINMUX_DATA(TEND0_MARK, PS5_7_FN2, PTV7_FN),
+	PINMUX_DATA(A22_MARK, PS5_6_FN1, PTV6_FN),
+	PINMUX_DATA(DREQ1_MARK, PS5_6_FN2, PTV6_FN),
+	PINMUX_DATA(A21_MARK, PS5_5_FN1, PTV5_FN),
+	PINMUX_DATA(DACK1_MARK, PS5_5_FN2, PTV5_FN),
+	PINMUX_DATA(A20_MARK, PS5_4_FN1, PTV4_FN),
+	PINMUX_DATA(TEND1_MARK, PS5_4_FN2, PTV4_FN),
+	PINMUX_DATA(A19_MARK, PTV3_FN),
+	PINMUX_DATA(A18_MARK, PTV2_FN),
+	PINMUX_DATA(A17_MARK, PTV1_FN),
+	PINMUX_DATA(A16_MARK, PTV0_FN),
+
+	/* PTW FN */
+	PINMUX_DATA(A15_MARK, PTW7_FN),
+	PINMUX_DATA(A14_MARK, PTW6_FN),
+	PINMUX_DATA(A13_MARK, PTW5_FN),
+	PINMUX_DATA(A12_MARK, PTW4_FN),
+	PINMUX_DATA(A11_MARK, PTW3_FN),
+	PINMUX_DATA(A10_MARK, PTW2_FN),
+	PINMUX_DATA(A9_MARK, PTW1_FN),
+	PINMUX_DATA(A8_MARK, PTW0_FN),
+
+	/* PTX FN */
+	PINMUX_DATA(A7_MARK, PTX7_FN),
+	PINMUX_DATA(A6_MARK, PTX6_FN),
+	PINMUX_DATA(A5_MARK, PTX5_FN),
+	PINMUX_DATA(A4_MARK, PTX4_FN),
+	PINMUX_DATA(A3_MARK, PTX3_FN),
+	PINMUX_DATA(A2_MARK, PTX2_FN),
+	PINMUX_DATA(A1_MARK, PTX1_FN),
+	PINMUX_DATA(A0_MARK, PTX0_FN),
+
+	/* PTY FN */
+	PINMUX_DATA(D7_MARK, PTY7_FN),
+	PINMUX_DATA(D6_MARK, PTY6_FN),
+	PINMUX_DATA(D5_MARK, PTY5_FN),
+	PINMUX_DATA(D4_MARK, PTY4_FN),
+	PINMUX_DATA(D3_MARK, PTY3_FN),
+	PINMUX_DATA(D2_MARK, PTY2_FN),
+	PINMUX_DATA(D1_MARK, PTY1_FN),
+	PINMUX_DATA(D0_MARK, PTY0_FN),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+	/* PTA */
+	PINMUX_GPIO(GPIO_PTA7, PTA7_DATA),
+	PINMUX_GPIO(GPIO_PTA6, PTA6_DATA),
+	PINMUX_GPIO(GPIO_PTA5, PTA5_DATA),
+	PINMUX_GPIO(GPIO_PTA4, PTA4_DATA),
+	PINMUX_GPIO(GPIO_PTA3, PTA3_DATA),
+	PINMUX_GPIO(GPIO_PTA2, PTA2_DATA),
+	PINMUX_GPIO(GPIO_PTA1, PTA1_DATA),
+	PINMUX_GPIO(GPIO_PTA0, PTA0_DATA),
+
+	/* PTB */
+	PINMUX_GPIO(GPIO_PTB7, PTB7_DATA),
+	PINMUX_GPIO(GPIO_PTB6, PTB6_DATA),
+	PINMUX_GPIO(GPIO_PTB5, PTB5_DATA),
+	PINMUX_GPIO(GPIO_PTB4, PTB4_DATA),
+	PINMUX_GPIO(GPIO_PTB3, PTB3_DATA),
+	PINMUX_GPIO(GPIO_PTB2, PTB2_DATA),
+	PINMUX_GPIO(GPIO_PTB1, PTB1_DATA),
+	PINMUX_GPIO(GPIO_PTB0, PTB0_DATA),
+
+	/* PTC */
+	PINMUX_GPIO(GPIO_PTC7, PTC7_DATA),
+	PINMUX_GPIO(GPIO_PTC6, PTC6_DATA),
+	PINMUX_GPIO(GPIO_PTC5, PTC5_DATA),
+	PINMUX_GPIO(GPIO_PTC4, PTC4_DATA),
+	PINMUX_GPIO(GPIO_PTC3, PTC3_DATA),
+	PINMUX_GPIO(GPIO_PTC2, PTC2_DATA),
+	PINMUX_GPIO(GPIO_PTC1, PTC1_DATA),
+	PINMUX_GPIO(GPIO_PTC0, PTC0_DATA),
+
+	/* PTD */
+	PINMUX_GPIO(GPIO_PTD7, PTD7_DATA),
+	PINMUX_GPIO(GPIO_PTD6, PTD6_DATA),
+	PINMUX_GPIO(GPIO_PTD5, PTD5_DATA),
+	PINMUX_GPIO(GPIO_PTD4, PTD4_DATA),
+	PINMUX_GPIO(GPIO_PTD3, PTD3_DATA),
+	PINMUX_GPIO(GPIO_PTD2, PTD2_DATA),
+	PINMUX_GPIO(GPIO_PTD1, PTD1_DATA),
+	PINMUX_GPIO(GPIO_PTD0, PTD0_DATA),
+
+	/* PTE */
+	PINMUX_GPIO(GPIO_PTE7, PTE7_DATA),
+	PINMUX_GPIO(GPIO_PTE6, PTE6_DATA),
+	PINMUX_GPIO(GPIO_PTE5, PTE5_DATA),
+	PINMUX_GPIO(GPIO_PTE4, PTE4_DATA),
+	PINMUX_GPIO(GPIO_PTE3, PTE3_DATA),
+	PINMUX_GPIO(GPIO_PTE2, PTE2_DATA),
+	PINMUX_GPIO(GPIO_PTE1, PTE1_DATA),
+	PINMUX_GPIO(GPIO_PTE0, PTE0_DATA),
+
+	/* PTF */
+	PINMUX_GPIO(GPIO_PTF7, PTF7_DATA),
+	PINMUX_GPIO(GPIO_PTF6, PTF6_DATA),
+	PINMUX_GPIO(GPIO_PTF5, PTF5_DATA),
+	PINMUX_GPIO(GPIO_PTF4, PTF4_DATA),
+	PINMUX_GPIO(GPIO_PTF3, PTF3_DATA),
+	PINMUX_GPIO(GPIO_PTF2, PTF2_DATA),
+	PINMUX_GPIO(GPIO_PTF1, PTF1_DATA),
+	PINMUX_GPIO(GPIO_PTF0, PTF0_DATA),
+
+	/* PTG */
+	PINMUX_GPIO(GPIO_PTG7, PTG7_DATA),
+	PINMUX_GPIO(GPIO_PTG6, PTG6_DATA),
+	PINMUX_GPIO(GPIO_PTG5, PTG5_DATA),
+	PINMUX_GPIO(GPIO_PTG4, PTG4_DATA),
+	PINMUX_GPIO(GPIO_PTG3, PTG3_DATA),
+	PINMUX_GPIO(GPIO_PTG2, PTG2_DATA),
+	PINMUX_GPIO(GPIO_PTG1, PTG1_DATA),
+	PINMUX_GPIO(GPIO_PTG0, PTG0_DATA),
+
+	/* PTH */
+	PINMUX_GPIO(GPIO_PTH7, PTH7_DATA),
+	PINMUX_GPIO(GPIO_PTH6, PTH6_DATA),
+	PINMUX_GPIO(GPIO_PTH5, PTH5_DATA),
+	PINMUX_GPIO(GPIO_PTH4, PTH4_DATA),
+	PINMUX_GPIO(GPIO_PTH3, PTH3_DATA),
+	PINMUX_GPIO(GPIO_PTH2, PTH2_DATA),
+	PINMUX_GPIO(GPIO_PTH1, PTH1_DATA),
+	PINMUX_GPIO(GPIO_PTH0, PTH0_DATA),
+
+	/* PTI */
+	PINMUX_GPIO(GPIO_PTI7, PTI7_DATA),
+	PINMUX_GPIO(GPIO_PTI6, PTI6_DATA),
+	PINMUX_GPIO(GPIO_PTI5, PTI5_DATA),
+	PINMUX_GPIO(GPIO_PTI4, PTI4_DATA),
+	PINMUX_GPIO(GPIO_PTI3, PTI3_DATA),
+	PINMUX_GPIO(GPIO_PTI2, PTI2_DATA),
+	PINMUX_GPIO(GPIO_PTI1, PTI1_DATA),
+	PINMUX_GPIO(GPIO_PTI0, PTI0_DATA),
+
+	/* PTJ */
+	PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA),
+	PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA),
+	PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
+	PINMUX_GPIO(GPIO_PTJ4, PTJ4_DATA),
+	PINMUX_GPIO(GPIO_PTJ3, PTJ3_DATA),
+	PINMUX_GPIO(GPIO_PTJ2, PTJ2_DATA),
+	PINMUX_GPIO(GPIO_PTJ1, PTJ1_DATA),
+	PINMUX_GPIO(GPIO_PTJ0, PTJ0_DATA),
+
+	/* PTK */
+	PINMUX_GPIO(GPIO_PTK7, PTK7_DATA),
+	PINMUX_GPIO(GPIO_PTK6, PTK6_DATA),
+	PINMUX_GPIO(GPIO_PTK5, PTK5_DATA),
+	PINMUX_GPIO(GPIO_PTK4, PTK4_DATA),
+	PINMUX_GPIO(GPIO_PTK3, PTK3_DATA),
+	PINMUX_GPIO(GPIO_PTK2, PTK2_DATA),
+	PINMUX_GPIO(GPIO_PTK1, PTK1_DATA),
+	PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
+
+	/* PTL */
+	PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
+	PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
+	PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
+	PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
+	PINMUX_GPIO(GPIO_PTL3, PTL3_DATA),
+	PINMUX_GPIO(GPIO_PTL2, PTL2_DATA),
+	PINMUX_GPIO(GPIO_PTL1, PTL1_DATA),
+	PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
+
+	/* PTM */
+	PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
+	PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
+	PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
+	PINMUX_GPIO(GPIO_PTM3, PTM3_DATA),
+	PINMUX_GPIO(GPIO_PTM2, PTM2_DATA),
+	PINMUX_GPIO(GPIO_PTM1, PTM1_DATA),
+	PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
+
+	/* PTN */
+	PINMUX_GPIO(GPIO_PTN7, PTN7_DATA),
+	PINMUX_GPIO(GPIO_PTN6, PTN6_DATA),
+	PINMUX_GPIO(GPIO_PTN5, PTN5_DATA),
+	PINMUX_GPIO(GPIO_PTN4, PTN4_DATA),
+	PINMUX_GPIO(GPIO_PTN3, PTN3_DATA),
+	PINMUX_GPIO(GPIO_PTN2, PTN2_DATA),
+	PINMUX_GPIO(GPIO_PTN1, PTN1_DATA),
+	PINMUX_GPIO(GPIO_PTN0, PTN0_DATA),
+
+	/* PTO */
+	PINMUX_GPIO(GPIO_PTO7, PTO7_DATA),
+	PINMUX_GPIO(GPIO_PTO6, PTO6_DATA),
+	PINMUX_GPIO(GPIO_PTO5, PTO5_DATA),
+	PINMUX_GPIO(GPIO_PTO4, PTO4_DATA),
+	PINMUX_GPIO(GPIO_PTO3, PTO3_DATA),
+	PINMUX_GPIO(GPIO_PTO2, PTO2_DATA),
+	PINMUX_GPIO(GPIO_PTO1, PTO1_DATA),
+	PINMUX_GPIO(GPIO_PTO0, PTO0_DATA),
+
+	/* PTP */
+	PINMUX_GPIO(GPIO_PTP6, PTP6_DATA),
+	PINMUX_GPIO(GPIO_PTP5, PTP5_DATA),
+	PINMUX_GPIO(GPIO_PTP4, PTP4_DATA),
+	PINMUX_GPIO(GPIO_PTP3, PTP3_DATA),
+	PINMUX_GPIO(GPIO_PTP2, PTP2_DATA),
+	PINMUX_GPIO(GPIO_PTP1, PTP1_DATA),
+	PINMUX_GPIO(GPIO_PTP0, PTP0_DATA),
+
+	/* PTQ */
+	PINMUX_GPIO(GPIO_PTQ6, PTQ6_DATA),
+	PINMUX_GPIO(GPIO_PTQ5, PTQ5_DATA),
+	PINMUX_GPIO(GPIO_PTQ4, PTQ4_DATA),
+	PINMUX_GPIO(GPIO_PTQ3, PTQ3_DATA),
+	PINMUX_GPIO(GPIO_PTQ2, PTQ2_DATA),
+	PINMUX_GPIO(GPIO_PTQ1, PTQ1_DATA),
+	PINMUX_GPIO(GPIO_PTQ0, PTQ0_DATA),
+
+	/* PTR */
+	PINMUX_GPIO(GPIO_PTR7, PTR7_DATA),
+	PINMUX_GPIO(GPIO_PTR6, PTR6_DATA),
+	PINMUX_GPIO(GPIO_PTR5, PTR5_DATA),
+	PINMUX_GPIO(GPIO_PTR4, PTR4_DATA),
+	PINMUX_GPIO(GPIO_PTR3, PTR3_DATA),
+	PINMUX_GPIO(GPIO_PTR2, PTR2_DATA),
+	PINMUX_GPIO(GPIO_PTR1, PTR1_DATA),
+	PINMUX_GPIO(GPIO_PTR0, PTR0_DATA),
+
+	/* PTS */
+	PINMUX_GPIO(GPIO_PTS7, PTS7_DATA),
+	PINMUX_GPIO(GPIO_PTS6, PTS6_DATA),
+	PINMUX_GPIO(GPIO_PTS5, PTS5_DATA),
+	PINMUX_GPIO(GPIO_PTS4, PTS4_DATA),
+	PINMUX_GPIO(GPIO_PTS3, PTS3_DATA),
+	PINMUX_GPIO(GPIO_PTS2, PTS2_DATA),
+	PINMUX_GPIO(GPIO_PTS1, PTS1_DATA),
+	PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
+
+	/* PTT */
+	PINMUX_GPIO(GPIO_PTT5, PTT5_DATA),
+	PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
+	PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
+	PINMUX_GPIO(GPIO_PTT2, PTT2_DATA),
+	PINMUX_GPIO(GPIO_PTT1, PTT1_DATA),
+	PINMUX_GPIO(GPIO_PTT0, PTT0_DATA),
+
+	/* PTU */
+	PINMUX_GPIO(GPIO_PTU7, PTU7_DATA),
+	PINMUX_GPIO(GPIO_PTU6, PTU6_DATA),
+	PINMUX_GPIO(GPIO_PTU5, PTU5_DATA),
+	PINMUX_GPIO(GPIO_PTU4, PTU4_DATA),
+	PINMUX_GPIO(GPIO_PTU3, PTU3_DATA),
+	PINMUX_GPIO(GPIO_PTU2, PTU2_DATA),
+	PINMUX_GPIO(GPIO_PTU1, PTU1_DATA),
+	PINMUX_GPIO(GPIO_PTU0, PTU0_DATA),
+
+	/* PTV */
+	PINMUX_GPIO(GPIO_PTV7, PTV7_DATA),
+	PINMUX_GPIO(GPIO_PTV6, PTV6_DATA),
+	PINMUX_GPIO(GPIO_PTV5, PTV5_DATA),
+	PINMUX_GPIO(GPIO_PTV4, PTV4_DATA),
+	PINMUX_GPIO(GPIO_PTV3, PTV3_DATA),
+	PINMUX_GPIO(GPIO_PTV2, PTV2_DATA),
+	PINMUX_GPIO(GPIO_PTV1, PTV1_DATA),
+	PINMUX_GPIO(GPIO_PTV0, PTV0_DATA),
+
+	/* PTW */
+	PINMUX_GPIO(GPIO_PTW7, PTW7_DATA),
+	PINMUX_GPIO(GPIO_PTW6, PTW6_DATA),
+	PINMUX_GPIO(GPIO_PTW5, PTW5_DATA),
+	PINMUX_GPIO(GPIO_PTW4, PTW4_DATA),
+	PINMUX_GPIO(GPIO_PTW3, PTW3_DATA),
+	PINMUX_GPIO(GPIO_PTW2, PTW2_DATA),
+	PINMUX_GPIO(GPIO_PTW1, PTW1_DATA),
+	PINMUX_GPIO(GPIO_PTW0, PTW0_DATA),
+
+	/* PTX */
+	PINMUX_GPIO(GPIO_PTX7, PTX7_DATA),
+	PINMUX_GPIO(GPIO_PTX6, PTX6_DATA),
+	PINMUX_GPIO(GPIO_PTX5, PTX5_DATA),
+	PINMUX_GPIO(GPIO_PTX4, PTX4_DATA),
+	PINMUX_GPIO(GPIO_PTX3, PTX3_DATA),
+	PINMUX_GPIO(GPIO_PTX2, PTX2_DATA),
+	PINMUX_GPIO(GPIO_PTX1, PTX1_DATA),
+	PINMUX_GPIO(GPIO_PTX0, PTX0_DATA),
+
+	/* PTY */
+	PINMUX_GPIO(GPIO_PTY7, PTY7_DATA),
+	PINMUX_GPIO(GPIO_PTY6, PTY6_DATA),
+	PINMUX_GPIO(GPIO_PTY5, PTY5_DATA),
+	PINMUX_GPIO(GPIO_PTY4, PTY4_DATA),
+	PINMUX_GPIO(GPIO_PTY3, PTY3_DATA),
+	PINMUX_GPIO(GPIO_PTY2, PTY2_DATA),
+	PINMUX_GPIO(GPIO_PTY1, PTY1_DATA),
+	PINMUX_GPIO(GPIO_PTY0, PTY0_DATA),
+
+	/* PTZ */
+	PINMUX_GPIO(GPIO_PTZ7, PTZ7_DATA),
+	PINMUX_GPIO(GPIO_PTZ6, PTZ6_DATA),
+	PINMUX_GPIO(GPIO_PTZ5, PTZ5_DATA),
+	PINMUX_GPIO(GPIO_PTZ4, PTZ4_DATA),
+	PINMUX_GPIO(GPIO_PTZ3, PTZ3_DATA),
+	PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA),
+	PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
+	PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA),
+
+	/* PTA (mobule: LBSC, CPG, LPC) */
+	PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
+	PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK),
+	PINMUX_GPIO(GPIO_FN_WE1, WE1_MARK),
+	PINMUX_GPIO(GPIO_FN_RDY, RDY_MARK),
+	PINMUX_GPIO(GPIO_FN_MD10, MD10_MARK),
+	PINMUX_GPIO(GPIO_FN_MD9, MD9_MARK),
+	PINMUX_GPIO(GPIO_FN_MD8, MD8_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO7, LGPIO7_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO6, LGPIO6_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO5, LGPIO5_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO4, LGPIO4_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO3, LGPIO3_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO2, LGPIO2_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO1, LGPIO1_MARK),
+	PINMUX_GPIO(GPIO_FN_LGPIO0, LGPIO0_MARK),
+
+	/* PTB (mobule: LBSC, EtherC, SIM, LPC) */
+	PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
+	PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
+	PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
+	PINMUX_GPIO(GPIO_FN_D12, D12_MARK),
+	PINMUX_GPIO(GPIO_FN_D11, D11_MARK),
+	PINMUX_GPIO(GPIO_FN_D10, D10_MARK),
+	PINMUX_GPIO(GPIO_FN_D9, D9_MARK),
+	PINMUX_GPIO(GPIO_FN_D8, D8_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_MDC, ET0_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDIO_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_MDC, ET1_MDC_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDIO_MARK),
+	PINMUX_GPIO(GPIO_FN_WPSZ1, WPSZ1_MARK),
+	PINMUX_GPIO(GPIO_FN_WPSZ0, WPSZ0_MARK),
+	PINMUX_GPIO(GPIO_FN_FWID, FWID_MARK),
+	PINMUX_GPIO(GPIO_FN_FLSHSZ, FLSHSZ_MARK),
+	PINMUX_GPIO(GPIO_FN_LPC_SPIEN, LPC_SPIEN_MARK),
+	PINMUX_GPIO(GPIO_FN_BASEL, BASEL_MARK),
+
+	/* PTC (mobule: SD) */
+	PINMUX_GPIO(GPIO_FN_SD_WP, SD_WP_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_CD, SD_CD_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_CLK, SD_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_CMD, SD_CMD_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D3, SD_D3_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D2, SD_D2_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D1, SD_D1_MARK),
+	PINMUX_GPIO(GPIO_FN_SD_D0, SD_D0_MARK),
+
+	/* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+	PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK),
+	PINMUX_GPIO(GPIO_FN_MD6, MD6_MARK),
+	PINMUX_GPIO(GPIO_FN_MD5, MD5_MARK),
+	PINMUX_GPIO(GPIO_FN_MD3, MD3_MARK),
+	PINMUX_GPIO(GPIO_FN_MD2, MD2_MARK),
+	PINMUX_GPIO(GPIO_FN_MD1, MD1_MARK),
+	PINMUX_GPIO(GPIO_FN_MD0, MD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK),
+	PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK),
+
+	/* PTE (mobule: EtherC) */
+	PINMUX_GPIO(GPIO_FN_ET0_CRS_DV, ET0_CRS_DV_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_TXD1, ET0_TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_TXD0, ET0_TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_TX_EN, ET0_TX_EN_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_REF_CLK, ET0_REF_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_RXD1, ET0_RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_RXD0, ET0_RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET0_RX_ER, ET0_RX_ER_MARK),
+
+	/* PTF (mobule: EtherC) */
+	PINMUX_GPIO(GPIO_FN_ET1_CRS_DV, ET1_CRS_DV_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_TXD1, ET1_TXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_TXD0, ET1_TXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_TX_EN, ET1_TX_EN_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_REF_CLK, ET1_REF_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_RXD1, ET1_RXD1_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_RXD0, ET1_RXD0_MARK),
+	PINMUX_GPIO(GPIO_FN_ET1_RX_ER, ET1_RX_ER_MARK),
+
+	/* PTG (mobule: SYSTEM, PWMX, LPC) */
+	PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+	PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX0, PWX0_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX1, PWX1_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX2, PWX2_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX3, PWX3_MARK),
+	PINMUX_GPIO(GPIO_FN_SERIRQ, SERIRQ_MARK),
+	PINMUX_GPIO(GPIO_FN_CLKRUN, CLKRUN_MARK),
+	PINMUX_GPIO(GPIO_FN_LPCPD, LPCPD_MARK),
+	PINMUX_GPIO(GPIO_FN_LDRQ, LDRQ_MARK),
+
+	/* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
+	PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_MOSI, SP1_MOSI_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_MISO, SP1_MISO_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SCK, SP1_SCK_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SCK_FB, SP1_SCK_FB_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SS0, SP1_SS0_MARK),
+	PINMUX_GPIO(GPIO_FN_SP1_SS1, SP1_SS1_MARK),
+	PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK),
+
+	/* PTI (mobule: INTC) */
+	PINMUX_GPIO(GPIO_FN_IRQ15, IRQ15_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ14, IRQ14_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ13, IRQ13_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ12, IRQ12_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ11, IRQ11_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ10, IRQ10_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ9, IRQ9_MARK),
+	PINMUX_GPIO(GPIO_FN_IRQ8, IRQ8_MARK),
+
+	/* PTJ (mobule: SCIF234, SERMUX) */
+	PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK),
+	PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_TXD, COM1_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_RXD, COM1_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_RTS, COM1_RTS_MARK),
+	PINMUX_GPIO(GPIO_FN_COM1_CTS, COM1_CTS_MARK),
+
+	/* PTK (mobule: SERMUX) */
+	PINMUX_GPIO(GPIO_FN_COM2_TXD, COM2_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_RXD, COM2_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_RTS, COM2_RTS_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_CTS, COM2_CTS_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_DTR, COM2_DTR_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_DSR, COM2_DSR_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_DCD, COM2_DCD_MARK),
+	PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK),
+
+	/* PTL (mobule: SERMUX) */
+	PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_RXD, RAC_RXD_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_RTS, RAC_RTS_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_CTS, RAC_CTS_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_DTR, RAC_DTR_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_DSR, RAC_DSR_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_DCD, RAC_DCD_MARK),
+	PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK),
+
+	/* PTM (mobule: IIC, LPC) */
+	PINMUX_GPIO(GPIO_FN_SDA6, SDA6_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL6, SCL6_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA7, SDA7_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL7, SCL7_MARK),
+	PINMUX_GPIO(GPIO_FN_WP, WP_MARK),
+	PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK),
+	PINMUX_GPIO(GPIO_FN_FMS1, FMS1_MARK),
+
+	/* PTN (mobule: SCIF234, EVC) */
+	PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS4, RTS4_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
+	PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
+	PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT5, EVENT5_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT4, EVENT4_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT3, EVENT3_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT2, EVENT2_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT1, EVENT1_MARK),
+	PINMUX_GPIO(GPIO_FN_EVENT0, EVENT0_MARK),
+
+	/* PTO (mobule: SGPIO) */
+	PINMUX_GPIO(GPIO_FN_SGPIO0_CLK, SGPIO0_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO0_LOAD, SGPIO0_LOAD_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO0_DI, SGPIO0_DI_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO0_DO, SGPIO0_DO_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_CLK, SGPIO1_CLK_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_LOAD, SGPIO1_LOAD_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_DI, SGPIO1_DI_MARK),
+	PINMUX_GPIO(GPIO_FN_SGPIO1_DO, SGPIO1_DO_MARK),
+
+	/* PTP (mobule: JMC, SCIF234) */
+	PINMUX_GPIO(GPIO_FN_JMCTCK, JMCTCK_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCTMS, JMCTMS_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCTDO, JMCTDO_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCTDI, JMCTDI_MARK),
+	PINMUX_GPIO(GPIO_FN_JMCRST, JMCRST_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK),
+	PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
+
+	/* PTQ (mobule: LPC) */
+	PINMUX_GPIO(GPIO_FN_LAD3, LAD3_MARK),
+	PINMUX_GPIO(GPIO_FN_LAD2, LAD2_MARK),
+	PINMUX_GPIO(GPIO_FN_LAD1, LAD1_MARK),
+	PINMUX_GPIO(GPIO_FN_LAD0, LAD0_MARK),
+	PINMUX_GPIO(GPIO_FN_LFRAME, LFRAME_MARK),
+	PINMUX_GPIO(GPIO_FN_LRESET, LRESET_MARK),
+	PINMUX_GPIO(GPIO_FN_LCLK, LCLK_MARK),
+
+	/* PTR (mobule: GRA, IIC) */
+	PINMUX_GPIO(GPIO_FN_DDC3, DDC3_MARK),
+	PINMUX_GPIO(GPIO_FN_DDC2, DDC2_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA8, SDA8_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL8, SCL8_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA2, SDA2_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL2, SCL2_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA1, SDA1_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL1, SCL1_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA0, SDA0_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL0, SCL0_MARK),
+
+	/* PTS (mobule: GRA, IIC) */
+	PINMUX_GPIO(GPIO_FN_DDC1, DDC1_MARK),
+	PINMUX_GPIO(GPIO_FN_DDC0, DDC0_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA9, SDA9_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL9, SCL9_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA5, SDA5_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL5, SCL5_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA4, SDA4_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL4, SCL4_MARK),
+	PINMUX_GPIO(GPIO_FN_SDA3, SDA3_MARK),
+	PINMUX_GPIO(GPIO_FN_SCL3, SCL3_MARK),
+
+	/* PTT (mobule: SYSTEM, PWMX) */
+	PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
+	PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX7, PWX7_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX6, PWX6_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX5, PWX5_MARK),
+	PINMUX_GPIO(GPIO_FN_PWX4, PWX4_MARK),
+
+	/* PTU (mobule: LBSC, DMAC) */
+	PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
+	PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
+	PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
+	PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK),
+	PINMUX_GPIO(GPIO_FN_RD, RD_MARK),
+	PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK),
+	PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+	PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+
+	/* PTV (mobule: LBSC, DMAC) */
+	PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
+	PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
+	PINMUX_GPIO(GPIO_FN_A21, A21_MARK),
+	PINMUX_GPIO(GPIO_FN_A20, A20_MARK),
+	PINMUX_GPIO(GPIO_FN_A19, A19_MARK),
+	PINMUX_GPIO(GPIO_FN_A18, A18_MARK),
+	PINMUX_GPIO(GPIO_FN_A17, A17_MARK),
+	PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
+	PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
+	PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+	PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+	PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+
+	/* PTW (mobule: LBSC) */
+	PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
+	PINMUX_GPIO(GPIO_FN_A15, A15_MARK),
+	PINMUX_GPIO(GPIO_FN_A14, A14_MARK),
+	PINMUX_GPIO(GPIO_FN_A13, A13_MARK),
+	PINMUX_GPIO(GPIO_FN_A12, A12_MARK),
+	PINMUX_GPIO(GPIO_FN_A11, A11_MARK),
+	PINMUX_GPIO(GPIO_FN_A10, A10_MARK),
+	PINMUX_GPIO(GPIO_FN_A9, A9_MARK),
+	PINMUX_GPIO(GPIO_FN_A8, A8_MARK),
+
+	/* PTX (mobule: LBSC) */
+	PINMUX_GPIO(GPIO_FN_A7, A7_MARK),
+	PINMUX_GPIO(GPIO_FN_A6, A6_MARK),
+	PINMUX_GPIO(GPIO_FN_A5, A5_MARK),
+	PINMUX_GPIO(GPIO_FN_A4, A4_MARK),
+	PINMUX_GPIO(GPIO_FN_A3, A3_MARK),
+	PINMUX_GPIO(GPIO_FN_A2, A2_MARK),
+	PINMUX_GPIO(GPIO_FN_A1, A1_MARK),
+	PINMUX_GPIO(GPIO_FN_A0, A0_MARK),
+
+	/* PTY (mobule: LBSC) */
+	PINMUX_GPIO(GPIO_FN_D7, D7_MARK),
+	PINMUX_GPIO(GPIO_FN_D6, D6_MARK),
+	PINMUX_GPIO(GPIO_FN_D5, D5_MARK),
+	PINMUX_GPIO(GPIO_FN_D4, D4_MARK),
+	PINMUX_GPIO(GPIO_FN_D3, D3_MARK),
+	PINMUX_GPIO(GPIO_FN_D2, D2_MARK),
+	PINMUX_GPIO(GPIO_FN_D1, D1_MARK),
+	PINMUX_GPIO(GPIO_FN_D0, D0_MARK),
+ };
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("PACR", 0xffec0000, 16, 2) {
+		PTA7_FN, PTA7_OUT, PTA7_IN, 0,
+		PTA6_FN, PTA6_OUT, PTA6_IN, 0,
+		PTA5_FN, PTA5_OUT, PTA5_IN, 0,
+		PTA4_FN, PTA4_OUT, PTA4_IN, 0,
+		PTA3_FN, PTA3_OUT, PTA3_IN, 0,
+		PTA2_FN, PTA2_OUT, PTA2_IN, 0,
+		PTA1_FN, PTA1_OUT, PTA1_IN, 0,
+		PTA0_FN, PTA0_OUT, PTA0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PBCR", 0xffec0002, 16, 2) {
+		PTB7_FN, PTB7_OUT, PTB7_IN, 0,
+		PTB6_FN, PTB6_OUT, PTB6_IN, 0,
+		PTB5_FN, PTB5_OUT, PTB5_IN, 0,
+		PTB4_FN, PTB4_OUT, PTB4_IN, 0,
+		PTB3_FN, PTB3_OUT, PTB3_IN, 0,
+		PTB2_FN, PTB2_OUT, PTB2_IN, 0,
+		PTB1_FN, PTB1_OUT, PTB1_IN, 0,
+		PTB0_FN, PTB0_OUT, PTB0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PCCR", 0xffec0004, 16, 2) {
+		PTC7_FN, PTC7_OUT, PTC7_IN, 0,
+		PTC6_FN, PTC6_OUT, PTC6_IN, 0,
+		PTC5_FN, PTC5_OUT, PTC5_IN, 0,
+		PTC4_FN, PTC4_OUT, PTC4_IN, 0,
+		PTC3_FN, PTC3_OUT, PTC3_IN, 0,
+		PTC2_FN, PTC2_OUT, PTC2_IN, 0,
+		PTC1_FN, PTC1_OUT, PTC1_IN, 0,
+		PTC0_FN, PTC0_OUT, PTC0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PDCR", 0xffec0006, 16, 2) {
+		PTD7_FN, PTD7_OUT, PTD7_IN, 0,
+		PTD6_FN, PTD6_OUT, PTD6_IN, 0,
+		PTD5_FN, PTD5_OUT, PTD5_IN, 0,
+		PTD4_FN, PTD4_OUT, PTD4_IN, 0,
+		PTD3_FN, PTD3_OUT, PTD3_IN, 0,
+		PTD2_FN, PTD2_OUT, PTD2_IN, 0,
+		PTD1_FN, PTD1_OUT, PTD1_IN, 0,
+		PTD0_FN, PTD0_OUT, PTD0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PECR", 0xffec0008, 16, 2) {
+		PTE7_FN, PTE7_OUT, PTE7_IN, 0,
+		PTE6_FN, PTE6_OUT, PTE6_IN, 0,
+		PTE5_FN, PTE5_OUT, PTE5_IN, 0,
+		PTE4_FN, PTE4_OUT, PTE4_IN, 0,
+		PTE3_FN, PTE3_OUT, PTE3_IN, 0,
+		PTE2_FN, PTE2_OUT, PTE2_IN, 0,
+		PTE1_FN, PTE1_OUT, PTE1_IN, 0,
+		PTE0_FN, PTE0_OUT, PTE0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PFCR", 0xffec000a, 16, 2) {
+		PTF7_FN, PTF7_OUT, PTF7_IN, 0,
+		PTF6_FN, PTF6_OUT, PTF6_IN, 0,
+		PTF5_FN, PTF5_OUT, PTF5_IN, 0,
+		PTF4_FN, PTF4_OUT, PTF4_IN, 0,
+		PTF3_FN, PTF3_OUT, PTF3_IN, 0,
+		PTF2_FN, PTF2_OUT, PTF2_IN, 0,
+		PTF1_FN, PTF1_OUT, PTF1_IN, 0,
+		PTF0_FN, PTF0_OUT, PTF0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PGCR", 0xffec000c, 16, 2) {
+		PTG7_FN, PTG7_OUT, PTG7_IN, 0,
+		PTG6_FN, PTG6_OUT, PTG6_IN, 0,
+		PTG5_FN, PTG5_OUT, PTG5_IN, 0,
+		PTG4_FN, PTG4_OUT, PTG4_IN, 0,
+		PTG3_FN, PTG3_OUT, PTG3_IN, 0,
+		PTG2_FN, PTG2_OUT, PTG2_IN, 0,
+		PTG1_FN, PTG1_OUT, PTG1_IN, 0,
+		PTG0_FN, PTG0_OUT, PTG0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PHCR", 0xffec000e, 16, 2) {
+		PTH7_FN, PTH7_OUT, PTH7_IN, 0,
+		PTH6_FN, PTH6_OUT, PTH6_IN, 0,
+		PTH5_FN, PTH5_OUT, PTH5_IN, 0,
+		PTH4_FN, PTH4_OUT, PTH4_IN, 0,
+		PTH3_FN, PTH3_OUT, PTH3_IN, 0,
+		PTH2_FN, PTH2_OUT, PTH2_IN, 0,
+		PTH1_FN, PTH1_OUT, PTH1_IN, 0,
+		PTH0_FN, PTH0_OUT, PTH0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PICR", 0xffec0010, 16, 2) {
+		PTI7_FN, PTI7_OUT, PTI7_IN, 0,
+		PTI6_FN, PTI6_OUT, PTI6_IN, 0,
+		PTI5_FN, PTI5_OUT, PTI5_IN, 0,
+		PTI4_FN, PTI4_OUT, PTI4_IN, 0,
+		PTI3_FN, PTI3_OUT, PTI3_IN, 0,
+		PTI2_FN, PTI2_OUT, PTI2_IN, 0,
+		PTI1_FN, PTI1_OUT, PTI1_IN, 0,
+		PTI0_FN, PTI0_OUT, PTI0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PJCR", 0xffec0012, 16, 2) {
+		PTJ7_FN, PTJ7_OUT, PTJ7_IN, 0,
+		PTJ6_FN, PTJ6_OUT, PTJ6_IN, 0,
+		PTJ5_FN, PTJ5_OUT, PTJ5_IN, 0,
+		PTJ4_FN, PTJ4_OUT, PTJ4_IN, 0,
+		PTJ3_FN, PTJ3_OUT, PTJ3_IN, 0,
+		PTJ2_FN, PTJ2_OUT, PTJ2_IN, 0,
+		PTJ1_FN, PTJ1_OUT, PTJ1_IN, 0,
+		PTJ0_FN, PTJ0_OUT, PTJ0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PKCR", 0xffec0014, 16, 2) {
+		PTK7_FN, PTK7_OUT, PTK7_IN, 0,
+		PTK6_FN, PTK6_OUT, PTK6_IN, 0,
+		PTK5_FN, PTK5_OUT, PTK5_IN, 0,
+		PTK4_FN, PTK4_OUT, PTK4_IN, 0,
+		PTK3_FN, PTK3_OUT, PTK3_IN, 0,
+		PTK2_FN, PTK2_OUT, PTK2_IN, 0,
+		PTK1_FN, PTK1_OUT, PTK1_IN, 0,
+		PTK0_FN, PTK0_OUT, PTK0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PLCR", 0xffec0016, 16, 2) {
+		PTL7_FN, PTL7_OUT, PTL7_IN, 0,
+		PTL6_FN, PTL6_OUT, PTL6_IN, 0,
+		PTL5_FN, PTL5_OUT, PTL5_IN, 0,
+		PTL4_FN, PTL4_OUT, PTL4_IN, 0,
+		PTL3_FN, PTL3_OUT, PTL3_IN, 0,
+		PTL2_FN, PTL2_OUT, PTL2_IN, 0,
+		PTL1_FN, PTL1_OUT, PTL1_IN, 0,
+		PTL0_FN, PTL0_OUT, PTL0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PMCR", 0xffec0018, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTM6_FN, PTM6_OUT, PTM6_IN, 0,
+		PTM5_FN, PTM5_OUT, PTM5_IN, 0,
+		PTM4_FN, PTM4_OUT, PTM4_IN, 0,
+		PTM3_FN, PTM3_OUT, PTM3_IN, 0,
+		PTM2_FN, PTM2_OUT, PTM2_IN, 0,
+		PTM1_FN, PTM1_OUT, PTM1_IN, 0,
+		PTM0_FN, PTM0_OUT, PTM0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PNCR", 0xffec001a, 16, 2) {
+		PTN7_FN, PTN7_OUT, PTN7_IN, 0,
+		PTN6_FN, PTN6_OUT, PTN6_IN, 0,
+		PTN5_FN, PTN5_OUT, PTN5_IN, 0,
+		PTN4_FN, PTN4_OUT, PTN4_IN, 0,
+		PTN3_FN, PTN3_OUT, PTN3_IN, 0,
+		PTN2_FN, PTN2_OUT, PTN2_IN, 0,
+		PTN1_FN, PTN1_OUT, PTN1_IN, 0,
+		PTN0_FN, PTN0_OUT, PTN0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("POCR", 0xffec001c, 16, 2) {
+		PTO7_FN, PTO7_OUT, PTO7_IN, 0,
+		PTO6_FN, PTO6_OUT, PTO6_IN, 0,
+		PTO5_FN, PTO5_OUT, PTO5_IN, 0,
+		PTO4_FN, PTO4_OUT, PTO4_IN, 0,
+		PTO3_FN, PTO3_OUT, PTO3_IN, 0,
+		PTO2_FN, PTO2_OUT, PTO2_IN, 0,
+		PTO1_FN, PTO1_OUT, PTO1_IN, 0,
+		PTO0_FN, PTO0_OUT, PTO0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PPCR", 0xffec001e, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTP6_FN, PTP6_OUT, PTP6_IN, 0,
+		PTP5_FN, PTP5_OUT, PTP5_IN, 0,
+		PTP4_FN, PTP4_OUT, PTP4_IN, 0,
+		PTP3_FN, PTP3_OUT, PTP3_IN, 0,
+		PTP2_FN, PTP2_OUT, PTP2_IN, 0,
+		PTP1_FN, PTP1_OUT, PTP1_IN, 0,
+		PTP0_FN, PTP0_OUT, PTP0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PQCR", 0xffec0020, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTQ6_FN, PTQ6_OUT, PTQ6_IN, 0,
+		PTQ5_FN, PTQ5_OUT, PTQ5_IN, 0,
+		PTQ4_FN, PTQ4_OUT, PTQ4_IN, 0,
+		PTQ3_FN, PTQ3_OUT, PTQ3_IN, 0,
+		PTQ2_FN, PTQ2_OUT, PTQ2_IN, 0,
+		PTQ1_FN, PTQ1_OUT, PTQ1_IN, 0,
+		PTQ0_FN, PTQ0_OUT, PTQ0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PRCR", 0xffec0022, 16, 2) {
+		PTR7_FN, PTR7_OUT, PTR7_IN, 0,
+		PTR6_FN, PTR6_OUT, PTR6_IN, 0,
+		PTR5_FN, PTR5_OUT, PTR5_IN, 0,
+		PTR4_FN, PTR4_OUT, PTR4_IN, 0,
+		PTR3_FN, PTR3_OUT, PTR3_IN, 0,
+		PTR2_FN, PTR2_OUT, PTR2_IN, 0,
+		PTR1_FN, PTR1_OUT, PTR1_IN, 0,
+		PTR0_FN, PTR0_OUT, PTR0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PSCR", 0xffec0024, 16, 2) {
+		PTS7_FN, PTS7_OUT, PTS7_IN, 0,
+		PTS6_FN, PTS6_OUT, PTS6_IN, 0,
+		PTS5_FN, PTS5_OUT, PTS5_IN, 0,
+		PTS4_FN, PTS4_OUT, PTS4_IN, 0,
+		PTS3_FN, PTS3_OUT, PTS3_IN, 0,
+		PTS2_FN, PTS2_OUT, PTS2_IN, 0,
+		PTS1_FN, PTS1_OUT, PTS1_IN, 0,
+		PTS0_FN, PTS0_OUT, PTS0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PTCR", 0xffec0026, 16, 2) {
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		0, 0, 0, 0,	/* reserved: always set 1 */
+		PTT5_FN, PTT5_OUT, PTT5_IN, 0,
+		PTT4_FN, PTT4_OUT, PTT4_IN, 0,
+		PTT3_FN, PTT3_OUT, PTT3_IN, 0,
+		PTT2_FN, PTT2_OUT, PTT2_IN, 0,
+		PTT1_FN, PTT1_OUT, PTT1_IN, 0,
+		PTT0_FN, PTT0_OUT, PTT0_IN, 0 }
+	},
+	{ PINMUX_CFG_REG("PUCR", 0xffec0028, 16, 2) {
+		PTU7_FN, PTU7_OUT, PTU7_IN, PTU7_IN_PU,
+		PTU6_FN, PTU6_OUT, PTU6_IN, PTU6_IN_PU,
+		PTU5_FN, PTU5_OUT, PTU5_IN, PTU5_IN_PU,
+		PTU4_FN, PTU4_OUT, PTU4_IN, PTU4_IN_PU,
+		PTU3_FN, PTU3_OUT, PTU3_IN, PTU3_IN_PU,
+		PTU2_FN, PTU2_OUT, PTU2_IN, PTU2_IN_PU,
+		PTU1_FN, PTU1_OUT, PTU1_IN, PTU1_IN_PU,
+		PTU0_FN, PTU0_OUT, PTU0_IN, PTU0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PVCR", 0xffec002a, 16, 2) {
+		PTV7_FN, PTV7_OUT, PTV7_IN, PTV7_IN_PU,
+		PTV6_FN, PTV6_OUT, PTV6_IN, PTV6_IN_PU,
+		PTV5_FN, PTV5_OUT, PTV5_IN, PTV5_IN_PU,
+		PTV4_FN, PTV4_OUT, PTV4_IN, PTV4_IN_PU,
+		PTV3_FN, PTV3_OUT, PTV3_IN, PTV3_IN_PU,
+		PTV2_FN, PTV2_OUT, PTV2_IN, PTV2_IN_PU,
+		PTV1_FN, PTV1_OUT, PTV1_IN, PTV1_IN_PU,
+		PTV0_FN, PTV0_OUT, PTV0_IN, PTV0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PWCR", 0xffec002c, 16, 2) {
+		PTW7_FN, PTW7_OUT, PTW7_IN, PTW7_IN_PU,
+		PTW6_FN, PTW6_OUT, PTW6_IN, PTW6_IN_PU,
+		PTW5_FN, PTW5_OUT, PTW5_IN, PTW5_IN_PU,
+		PTW4_FN, PTW4_OUT, PTW4_IN, PTW4_IN_PU,
+		PTW3_FN, PTW3_OUT, PTW3_IN, PTW3_IN_PU,
+		PTW2_FN, PTW2_OUT, PTW2_IN, PTW2_IN_PU,
+		PTW1_FN, PTW1_OUT, PTW1_IN, PTW1_IN_PU,
+		PTW0_FN, PTW0_OUT, PTW0_IN, PTW0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PXCR", 0xffec002e, 16, 2) {
+		PTX7_FN, PTX7_OUT, PTX7_IN, PTX7_IN_PU,
+		PTX6_FN, PTX6_OUT, PTX6_IN, PTX6_IN_PU,
+		PTX5_FN, PTX5_OUT, PTX5_IN, PTX5_IN_PU,
+		PTX4_FN, PTX4_OUT, PTX4_IN, PTX4_IN_PU,
+		PTX3_FN, PTX3_OUT, PTX3_IN, PTX3_IN_PU,
+		PTX2_FN, PTX2_OUT, PTX2_IN, PTX2_IN_PU,
+		PTX1_FN, PTX1_OUT, PTX1_IN, PTX1_IN_PU,
+		PTX0_FN, PTX0_OUT, PTX0_IN, PTX0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PYCR", 0xffec0030, 16, 2) {
+		PTY7_FN, PTY7_OUT, PTY7_IN, PTY7_IN_PU,
+		PTY6_FN, PTY6_OUT, PTY6_IN, PTY6_IN_PU,
+		PTY5_FN, PTY5_OUT, PTY5_IN, PTY5_IN_PU,
+		PTY4_FN, PTY4_OUT, PTY4_IN, PTY4_IN_PU,
+		PTY3_FN, PTY3_OUT, PTY3_IN, PTY3_IN_PU,
+		PTY2_FN, PTY2_OUT, PTY2_IN, PTY2_IN_PU,
+		PTY1_FN, PTY1_OUT, PTY1_IN, PTY1_IN_PU,
+		PTY0_FN, PTY0_OUT, PTY0_IN, PTY0_IN_PU }
+	},
+	{ PINMUX_CFG_REG("PZCR", 0xffec0032, 16, 2) {
+		0, PTZ7_OUT, PTZ7_IN, 0,
+		0, PTZ6_OUT, PTZ6_IN, 0,
+		0, PTZ5_OUT, PTZ5_IN, 0,
+		0, PTZ4_OUT, PTZ4_IN, 0,
+		0, PTZ3_OUT, PTZ3_IN, 0,
+		0, PTZ2_OUT, PTZ2_IN, 0,
+		0, PTZ1_OUT, PTZ1_IN, 0,
+		0, PTZ0_OUT, PTZ0_IN, 0 }
+	},
+
+	{ PINMUX_CFG_REG("PSEL0", 0xffec0070, 16, 1) {
+		PS0_15_FN3, PS0_15_FN1,
+		PS0_14_FN3, PS0_14_FN1,
+		PS0_13_FN3, PS0_13_FN1,
+		PS0_12_FN3, PS0_12_FN1,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS0_7_FN2, PS0_7_FN1,
+		PS0_6_FN2, PS0_6_FN1,
+		PS0_5_FN2, PS0_5_FN1,
+		PS0_4_FN2, PS0_4_FN1,
+		PS0_3_FN2, PS0_3_FN1,
+		PS0_2_FN2, PS0_2_FN1,
+		PS0_1_FN2, PS0_1_FN1,
+		0, 0, }
+	},
+	{ PINMUX_CFG_REG("PSEL1", 0xffec0072, 16, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS1_7_FN1, PS1_7_FN3,
+		PS1_6_FN1, PS1_6_FN3,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0, }
+	},
+	{ PINMUX_CFG_REG("PSEL2", 0xffec0074, 16, 1) {
+		0, 0,
+		0, 0,
+		PS2_13_FN3, PS2_13_FN1,
+		PS2_12_FN3, PS2_12_FN1,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS2_1_FN1, PS2_1_FN2,
+		PS2_0_FN1, PS2_0_FN2, }
+	},
+	{ PINMUX_CFG_REG("PSEL4", 0xffec0078, 16, 1) {
+		PS4_15_FN2, PS4_15_FN1,
+		PS4_14_FN2, PS4_14_FN1,
+		PS4_13_FN2, PS4_13_FN1,
+		PS4_12_FN2, PS4_12_FN1,
+		PS4_11_FN2, PS4_11_FN1,
+		PS4_10_FN2, PS4_10_FN1,
+		PS4_9_FN2, PS4_9_FN1,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS4_3_FN2, PS4_3_FN1,
+		PS4_2_FN2, PS4_2_FN1,
+		PS4_1_FN2, PS4_1_FN1,
+		PS4_0_FN2, PS4_0_FN1, }
+	},
+	{ PINMUX_CFG_REG("PSEL5", 0xffec007a, 16, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS5_9_FN1, PS5_9_FN2,
+		PS5_8_FN1, PS5_8_FN2,
+		PS5_7_FN1, PS5_7_FN2,
+		PS5_6_FN1, PS5_6_FN2,
+		PS5_5_FN1, PS5_5_FN2,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0, }
+	},
+	{ PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		PS6_7_FN_AN, PS6_7_FN_EV,
+		PS6_6_FN_AN, PS6_6_FN_EV,
+		PS6_5_FN_AN, PS6_5_FN_EV,
+		PS6_4_FN_AN, PS6_4_FN_EV,
+		PS6_3_FN_AN, PS6_3_FN_EV,
+		PS6_2_FN_AN, PS6_2_FN_EV,
+		PS6_1_FN_AN, PS6_1_FN_EV,
+		PS6_0_FN_AN, PS6_0_FN_EV, }
+	},
+	{}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("PADR", 0xffec0034, 8) {
+		PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+		PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA }
+	},
+	{ PINMUX_DATA_REG("PBDR", 0xffec0036, 8) {
+		PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+		PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA }
+	},
+	{ PINMUX_DATA_REG("PCDR", 0xffec0038, 8) {
+		PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+		PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA }
+	},
+	{ PINMUX_DATA_REG("PDDR", 0xffec003a, 8) {
+		PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+		PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA }
+	},
+	{ PINMUX_DATA_REG("PEDR", 0xffec003c, 8) {
+		PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+		PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA }
+	},
+	{ PINMUX_DATA_REG("PFDR", 0xffec003e, 8) {
+		PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+		PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA }
+	},
+	{ PINMUX_DATA_REG("PGDR", 0xffec0040, 8) {
+		PTG7_DATA, PTG6_DATA, PTG5_DATA, PTG4_DATA,
+		PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA }
+	},
+	{ PINMUX_DATA_REG("PHDR", 0xffec0042, 8) {
+		PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+		PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA }
+	},
+	{ PINMUX_DATA_REG("PIDR", 0xffec0044, 8) {
+		PTI7_DATA, PTI6_DATA, PTI5_DATA, PTI4_DATA,
+		PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA }
+	},
+	{ PINMUX_DATA_REG("PJDR", 0xffec0046, 8) {
+		PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+		PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
+	},
+	{ PINMUX_DATA_REG("PKDR", 0xffec0048, 8) {
+		PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+		PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
+	},
+	{ PINMUX_DATA_REG("PLDR", 0xffec004a, 8) {
+		PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+		PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA }
+	},
+	{ PINMUX_DATA_REG("PMDR", 0xffec004c, 8) {
+		0, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+		PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
+	},
+	{ PINMUX_DATA_REG("PNDR", 0xffec004e, 8) {
+		PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+		PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
+	},
+	{ PINMUX_DATA_REG("PODR", 0xffec0050, 8) {
+		PTO7_DATA, PTO6_DATA, PTO5_DATA, PTO4_DATA,
+		PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA }
+	},
+	{ PINMUX_DATA_REG("PPDR", 0xffec0052, 8) {
+		0, PTP6_DATA, PTP5_DATA, PTP4_DATA,
+		PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA }
+	},
+	{ PINMUX_DATA_REG("PQDR", 0xffec0054, 8) {
+		0, PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+		PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA }
+	},
+	{ PINMUX_DATA_REG("PRDR", 0xffec0056, 8) {
+		PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+		PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA }
+	},
+	{ PINMUX_DATA_REG("PSDR", 0xffec0058, 8) {
+		PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
+		PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
+	},
+	{ PINMUX_DATA_REG("PTDR", 0xffec005a, 8) {
+		0, 0, PTT5_DATA, PTT4_DATA,
+		PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
+	},
+	{ PINMUX_DATA_REG("PUDR", 0xffec005c, 8) {
+		PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
+		PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA }
+	},
+	{ PINMUX_DATA_REG("PVDR", 0xffec005e, 8) {
+		PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+		PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA }
+	},
+	{ PINMUX_DATA_REG("PWDR", 0xffec0060, 8) {
+		PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+		PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA }
+	},
+	{ PINMUX_DATA_REG("PXDR", 0xffec0062, 8) {
+		PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+		PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA }
+	},
+	{ PINMUX_DATA_REG("PYDR", 0xffec0064, 8) {
+		PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+		PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA }
+	},
+	{ PINMUX_DATA_REG("PZDR", 0xffec0066, 8) {
+		PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+		PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA }
+	},
+	{ },
+};
+
+static struct pinmux_info sh7757_pinmux_info = {
+	.name = "sh7757_pfc",
+	.reserved_id = PINMUX_RESERVED,
+	.data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+	.input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+	.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.first_gpio = GPIO_PTA7,
+	.last_gpio = GPIO_FN_D0,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+	return register_pinmux(&sh7757_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
index 1a956b1..4a9010b 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c
@@ -40,7 +40,7 @@ static struct platform_device iic_device = {
 };
 
 static struct r8a66597_platdata r8a66597_data = {
-	/* This set zero to all members */
+	.on_chip = 1,
 };
 
 static struct resource usb_host_resources[] = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
index cda76eb..3509775 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c
@@ -13,9 +13,11 @@
 #include <linux/serial_sci.h>
 #include <linux/mm.h>
 #include <linux/uio_driver.h>
+#include <linux/usb/m66592.h>
 #include <linux/sh_timer.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
+#include <cpu/sh7722.h>
 
 static struct resource rtc_resources[] = {
 	[0] = {
@@ -45,11 +47,18 @@ static struct platform_device rtc_device = {
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 	.resource	= rtc_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_RTC,
+	},
+};
+
+static struct m66592_platdata usbf_platdata = {
+	.on_chip = 1,
 };
 
 static struct resource usbf_resources[] = {
 	[0] = {
-		.name	= "m66592_udc",
+		.name	= "USBF",
 		.start	= 0x04480000,
 		.end	= 0x044800FF,
 		.flags	= IORESOURCE_MEM,
@@ -67,9 +76,13 @@ static struct platform_device usbf_device = {
 	.dev = {
 		.dma_mask		= NULL,
 		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usbf_platdata,
 	},
 	.num_resources	= ARRAY_SIZE(usbf_resources),
 	.resource	= usbf_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_USBF,
+	},
 };
 
 static struct resource iic_resources[] = {
@@ -91,6 +104,9 @@ static struct platform_device iic_device = {
 	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic_resources),
 	.resource       = iic_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC,
+	},
 };
 
 static struct uio_info vpu_platform_data = {
@@ -119,6 +135,9 @@ static struct platform_device vpu_device = {
 	},
 	.resource	= vpu_resources,
 	.num_resources	= ARRAY_SIZE(vpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VPU,
+	},
 };
 
 static struct uio_info veu_platform_data = {
@@ -147,6 +166,9 @@ static struct platform_device veu_device = {
 	},
 	.resource	= veu_resources,
 	.num_resources	= ARRAY_SIZE(veu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU,
+	},
 };
 
 static struct uio_info jpu_platform_data = {
@@ -175,6 +197,9 @@ static struct platform_device jpu_device = {
 	},
 	.resource	= jpu_resources,
 	.num_resources	= ARRAY_SIZE(jpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_JPU,
+	},
 };
 
 static struct sh_timer_config cmt_platform_data = {
@@ -207,6 +232,9 @@ static struct platform_device cmt_device = {
 	},
 	.resource	= cmt_resources,
 	.num_resources	= ARRAY_SIZE(cmt_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_CMT,
+	},
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -238,6 +266,9 @@ static struct platform_device tmu0_device = {
 	},
 	.resource	= tmu0_resources,
 	.num_resources	= ARRAY_SIZE(tmu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU,
+	},
 };
 
 static struct sh_timer_config tmu1_platform_data = {
@@ -269,6 +300,9 @@ static struct platform_device tmu1_device = {
 	},
 	.resource	= tmu1_resources,
 	.num_resources	= ARRAY_SIZE(tmu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU,
+	},
 };
 
 static struct sh_timer_config tmu2_platform_data = {
@@ -299,6 +333,9 @@ static struct platform_device tmu2_device = {
 	},
 	.resource	= tmu2_resources,
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU,
+	},
 };
 
 static struct plat_sci_port sci_platform_data[] = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
index b45dace..4caa5a7 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
+#include <cpu/sh7723.h>
 
 static struct uio_info vpu_platform_data = {
 	.name = "VPU5",
@@ -45,6 +46,9 @@ static struct platform_device vpu_device = {
 	},
 	.resource	= vpu_resources,
 	.num_resources	= ARRAY_SIZE(vpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VPU,
+	},
 };
 
 static struct uio_info veu0_platform_data = {
@@ -73,6 +77,9 @@ static struct platform_device veu0_device = {
 	},
 	.resource	= veu0_resources,
 	.num_resources	= ARRAY_SIZE(veu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU2H0,
+	},
 };
 
 static struct uio_info veu1_platform_data = {
@@ -101,6 +108,9 @@ static struct platform_device veu1_device = {
 	},
 	.resource	= veu1_resources,
 	.num_resources	= ARRAY_SIZE(veu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU2H1,
+	},
 };
 
 static struct sh_timer_config cmt_platform_data = {
@@ -133,6 +143,9 @@ static struct platform_device cmt_device = {
 	},
 	.resource	= cmt_resources,
 	.num_resources	= ARRAY_SIZE(cmt_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_CMT,
+	},
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -164,6 +177,9 @@ static struct platform_device tmu0_device = {
 	},
 	.resource	= tmu0_resources,
 	.num_resources	= ARRAY_SIZE(tmu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu1_platform_data = {
@@ -195,6 +211,9 @@ static struct platform_device tmu1_device = {
 	},
 	.resource	= tmu1_resources,
 	.num_resources	= ARRAY_SIZE(tmu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu2_platform_data = {
@@ -225,6 +244,9 @@ static struct platform_device tmu2_device = {
 	},
 	.resource	= tmu2_resources,
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu3_platform_data = {
@@ -255,6 +277,9 @@ static struct platform_device tmu3_device = {
 	},
 	.resource	= tmu3_resources,
 	.num_resources	= ARRAY_SIZE(tmu3_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu4_platform_data = {
@@ -285,6 +310,9 @@ static struct platform_device tmu4_device = {
 	},
 	.resource	= tmu4_resources,
 	.num_resources	= ARRAY_SIZE(tmu4_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu5_platform_data = {
@@ -315,6 +343,9 @@ static struct platform_device tmu5_device = {
 	},
 	.resource	= tmu5_resources,
 	.num_resources	= ARRAY_SIZE(tmu5_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct plat_sci_port sci_platform_data[] = {
@@ -395,10 +426,13 @@ static struct platform_device rtc_device = {
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 	.resource	= rtc_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_RTC,
+	},
 };
 
 static struct r8a66597_platdata r8a66597_data = {
-	/* This set zero to all members */
+	.on_chip = 1,
 };
 
 static struct resource sh7723_usb_host_resources[] = {
@@ -424,6 +458,9 @@ static struct platform_device sh7723_usb_host_device = {
 	},
 	.num_resources	= ARRAY_SIZE(sh7723_usb_host_resources),
 	.resource	= sh7723_usb_host_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_USB,
+	},
 };
 
 static struct resource iic_resources[] = {
@@ -445,6 +482,9 @@ static struct platform_device iic_device = {
 	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic_resources),
 	.resource       = iic_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC,
+	},
 };
 
 static struct platform_device *sh7723_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
index a04edaa..f3851fd 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <asm/clock.h>
 #include <asm/mmzone.h>
+#include <cpu/sh7724.h>
 
 /* Serial */
 static struct plat_sci_port sci_platform_data[] = {
@@ -103,6 +104,9 @@ static struct platform_device rtc_device = {
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(rtc_resources),
 	.resource	= rtc_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_RTC,
+	},
 };
 
 /* I2C0 */
@@ -125,6 +129,9 @@ static struct platform_device iic0_device = {
 	.id             = 0, /* "i2c0" clock */
 	.num_resources  = ARRAY_SIZE(iic0_resources),
 	.resource       = iic0_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC0,
+	},
 };
 
 /* I2C1 */
@@ -147,6 +154,9 @@ static struct platform_device iic1_device = {
 	.id             = 1, /* "i2c1" clock */
 	.num_resources  = ARRAY_SIZE(iic1_resources),
 	.resource       = iic1_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_IIC1,
+	},
 };
 
 /* VPU */
@@ -176,6 +186,9 @@ static struct platform_device vpu_device = {
 	},
 	.resource	= vpu_resources,
 	.num_resources	= ARRAY_SIZE(vpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VPU,
+	},
 };
 
 /* VEU0 */
@@ -205,6 +218,9 @@ static struct platform_device veu0_device = {
 	},
 	.resource	= veu0_resources,
 	.num_resources	= ARRAY_SIZE(veu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU0,
+	},
 };
 
 /* VEU1 */
@@ -234,6 +250,9 @@ static struct platform_device veu1_device = {
 	},
 	.resource	= veu1_resources,
 	.num_resources	= ARRAY_SIZE(veu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_VEU1,
+	},
 };
 
 static struct sh_timer_config cmt_platform_data = {
@@ -266,6 +285,9 @@ static struct platform_device cmt_device = {
 	},
 	.resource	= cmt_resources,
 	.num_resources	= ARRAY_SIZE(cmt_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_CMT,
+	},
 };
 
 static struct sh_timer_config tmu0_platform_data = {
@@ -297,6 +319,9 @@ static struct platform_device tmu0_device = {
 	},
 	.resource	= tmu0_resources,
 	.num_resources	= ARRAY_SIZE(tmu0_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu1_platform_data = {
@@ -328,6 +353,9 @@ static struct platform_device tmu1_device = {
 	},
 	.resource	= tmu1_resources,
 	.num_resources	= ARRAY_SIZE(tmu1_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 static struct sh_timer_config tmu2_platform_data = {
@@ -358,6 +386,9 @@ static struct platform_device tmu2_device = {
 	},
 	.resource	= tmu2_resources,
 	.num_resources	= ARRAY_SIZE(tmu2_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU0,
+	},
 };
 
 
@@ -389,6 +420,9 @@ static struct platform_device tmu3_device = {
 	},
 	.resource	= tmu3_resources,
 	.num_resources	= ARRAY_SIZE(tmu3_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu4_platform_data = {
@@ -419,6 +453,9 @@ static struct platform_device tmu4_device = {
 	},
 	.resource	= tmu4_resources,
 	.num_resources	= ARRAY_SIZE(tmu4_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 static struct sh_timer_config tmu5_platform_data = {
@@ -449,6 +486,9 @@ static struct platform_device tmu5_device = {
 	},
 	.resource	= tmu5_resources,
 	.num_resources	= ARRAY_SIZE(tmu5_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_TMU1,
+	},
 };
 
 /* JPU */
@@ -478,6 +518,9 @@ static struct platform_device jpu_device = {
 	},
 	.resource	= jpu_resources,
 	.num_resources	= ARRAY_SIZE(jpu_resources),
+	.archdata = {
+		.hwblk_id = HWBLK_JPU,
+	},
 };
 
 static struct platform_device *sh7724_devices[] __initdata = {
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
new file mode 100644
index 0000000..c470e15
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -0,0 +1,513 @@
+/*
+ * SH7757 Setup
+ *
+ * Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ *  based on setup-sh7785.c : Copyright (C) 2007  Paul Mundt
+ *
+ * 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.
+ */
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_sci.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/sh_timer.h>
+
+static struct sh_timer_config tmu0_platform_data = {
+	.name = "TMU0",
+	.channel_offset = 0x04,
+	.timer_bit = 0,
+	.clk = "peripheral_clk",
+	.clockevent_rating = 200,
+};
+
+static struct resource tmu0_resources[] = {
+	[0] = {
+		.name	= "TMU0",
+		.start	= 0xfe430008,
+		.end	= 0xfe430013,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 28,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu0_device = {
+	.name		= "sh_tmu",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &tmu0_platform_data,
+	},
+	.resource	= tmu0_resources,
+	.num_resources	= ARRAY_SIZE(tmu0_resources),
+};
+
+static struct sh_timer_config tmu1_platform_data = {
+	.name = "TMU1",
+	.channel_offset = 0x10,
+	.timer_bit = 1,
+	.clk = "peripheral_clk",
+	.clocksource_rating = 200,
+};
+
+static struct resource tmu1_resources[] = {
+	[0] = {
+		.name	= "TMU1",
+		.start	= 0xfe430014,
+		.end	= 0xfe43001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 29,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu1_device = {
+	.name		= "sh_tmu",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &tmu1_platform_data,
+	},
+	.resource	= tmu1_resources,
+	.num_resources	= ARRAY_SIZE(tmu1_resources),
+};
+
+static struct plat_sci_port sci_platform_data[] = {
+	{
+		.mapbase	= 0xfe4b0000,		/* SCIF2 */
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 40, 40, 40, 40 },
+	}, {
+		.mapbase	= 0xfe4c0000,		/* SCIF3 */
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 76, 76, 76, 76 },
+	}, {
+		.mapbase	= 0xfe4d0000,		/* SCIF4 */
+		.flags		= UPF_BOOT_AUTOCONF,
+		.type		= PORT_SCIF,
+		.irqs		= { 104, 104, 104, 104 },
+	}, {
+		.flags = 0,
+	}
+};
+
+static struct platform_device sci_device = {
+	.name		= "sh-sci",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= sci_platform_data,
+	},
+};
+
+static struct platform_device *sh7757_devices[] __initdata = {
+	&tmu0_device,
+	&tmu1_device,
+	&sci_device,
+};
+
+static int __init sh7757_devices_setup(void)
+{
+	return platform_add_devices(sh7757_devices,
+				    ARRAY_SIZE(sh7757_devices));
+}
+arch_initcall(sh7757_devices_setup);
+
+enum {
+	UNUSED = 0,
+
+	/* interrupt sources */
+
+	IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+	IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+	IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+	IRL0_HHLL, IRL0_HHLH, IRL0_HHHL,
+
+	IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+	IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+	IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+	IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
+	IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
+
+	SDHI,
+	DVC,
+	IRQ8, IRQ9, IRQ10,
+	WDT0,
+	TMU0, TMU1, TMU2, TMU2_TICPI,
+	HUDI,
+
+	ARC4,
+	DMAC0,
+	IRQ11,
+	SCIF2,
+	DMAC1_6,
+	USB0,
+	IRQ12,
+	JMC,
+	SPI1,
+	IRQ13, IRQ14,
+	USB1,
+	TMR01, TMR23, TMR45,
+	WDT1,
+	FRT,
+	LPC,
+	SCIF0, SCIF1, SCIF3,
+	PECI0I, PECI1I, PECI2I,
+	IRQ15,
+	ETHERC,
+	SPI0,
+	ADC1,
+	DMAC1_8,
+	SIM,
+	TMU3, TMU4, TMU5,
+	ADC0,
+	SCIF4,
+	IIC0_0, IIC0_1, IIC0_2, IIC0_3,
+	IIC1_0, IIC1_1, IIC1_2, IIC1_3,
+	IIC2_0, IIC2_1, IIC2_2, IIC2_3,
+	IIC3_0, IIC3_1, IIC3_2, IIC3_3,
+	IIC4_0, IIC4_1, IIC4_2, IIC4_3,
+	IIC5_0, IIC5_1, IIC5_2, IIC5_3,
+	IIC6_0, IIC6_1, IIC6_2, IIC6_3,
+	IIC7_0, IIC7_1, IIC7_2, IIC7_3,
+	IIC8_0, IIC8_1, IIC8_2, IIC8_3,
+	IIC9_0, IIC9_1, IIC9_2, IIC9_3,
+	PCIINTA,
+	PCIE,
+	SGPIO,
+
+	/* interrupt groups */
+
+	TMU012, TMU345,
+};
+
+static struct intc_vect vectors[] __initdata = {
+	INTC_VECT(SDHI, 0x480), INTC_VECT(SDHI, 0x04a0),
+	INTC_VECT(SDHI, 0x4c0),
+	INTC_VECT(DVC, 0x4e0),
+	INTC_VECT(IRQ8, 0x500), INTC_VECT(IRQ9, 0x520),
+	INTC_VECT(IRQ10, 0x540),
+	INTC_VECT(WDT0, 0x560),
+	INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
+	INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
+	INTC_VECT(HUDI, 0x600),
+	INTC_VECT(ARC4, 0x620),
+	INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
+	INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
+	INTC_VECT(DMAC0, 0x6c0),
+	INTC_VECT(IRQ11, 0x6e0),
+	INTC_VECT(SCIF2, 0x700), INTC_VECT(SCIF2, 0x720),
+	INTC_VECT(SCIF2, 0x740), INTC_VECT(SCIF2, 0x760),
+	INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
+	INTC_VECT(DMAC1_6, 0x7c0), INTC_VECT(DMAC1_6, 0x7e0),
+	INTC_VECT(USB0, 0x840),
+	INTC_VECT(IRQ12, 0x880),
+	INTC_VECT(JMC, 0x8a0),
+	INTC_VECT(SPI1, 0x8c0),
+	INTC_VECT(IRQ13, 0x8e0), INTC_VECT(IRQ14, 0x900),
+	INTC_VECT(USB1, 0x920),
+	INTC_VECT(TMR01, 0xa00), INTC_VECT(TMR23, 0xa20),
+	INTC_VECT(TMR45, 0xa40),
+	INTC_VECT(WDT1, 0xa60),
+	INTC_VECT(FRT, 0xa80),
+	INTC_VECT(LPC, 0xaa0), INTC_VECT(LPC, 0xac0),
+	INTC_VECT(LPC, 0xae0), INTC_VECT(LPC, 0xb00),
+	INTC_VECT(LPC, 0xb20),
+	INTC_VECT(SCIF0, 0xb40), INTC_VECT(SCIF1, 0xb60),
+	INTC_VECT(SCIF3, 0xb80), INTC_VECT(SCIF3, 0xba0),
+	INTC_VECT(SCIF3, 0xbc0), INTC_VECT(SCIF3, 0xbe0),
+	INTC_VECT(PECI0I, 0xc00), INTC_VECT(PECI1I, 0xc20),
+	INTC_VECT(PECI2I, 0xc40),
+	INTC_VECT(IRQ15, 0xc60),
+	INTC_VECT(ETHERC, 0xc80), INTC_VECT(ETHERC, 0xca0),
+	INTC_VECT(SPI0, 0xcc0),
+	INTC_VECT(ADC1, 0xce0),
+	INTC_VECT(DMAC1_8, 0xd00), INTC_VECT(DMAC1_8, 0xd20),
+	INTC_VECT(DMAC1_8, 0xd40), INTC_VECT(DMAC1_8, 0xd60),
+	INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
+	INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
+	INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
+	INTC_VECT(TMU5, 0xe40),
+	INTC_VECT(ADC0, 0xe60),
+	INTC_VECT(SCIF4, 0xf00), INTC_VECT(SCIF4, 0xf20),
+	INTC_VECT(SCIF4, 0xf40), INTC_VECT(SCIF4, 0xf60),
+	INTC_VECT(IIC0_0, 0x1400), INTC_VECT(IIC0_1, 0x1420),
+	INTC_VECT(IIC0_2, 0x1440), INTC_VECT(IIC0_3, 0x1460),
+	INTC_VECT(IIC1_0, 0x1480), INTC_VECT(IIC1_1, 0x14e0),
+	INTC_VECT(IIC1_2, 0x1500), INTC_VECT(IIC1_3, 0x1520),
+	INTC_VECT(IIC2_0, 0x1540), INTC_VECT(IIC2_1, 0x1560),
+	INTC_VECT(IIC2_2, 0x1580), INTC_VECT(IIC2_3, 0x1600),
+	INTC_VECT(IIC3_0, 0x1620), INTC_VECT(IIC3_1, 0x1640),
+	INTC_VECT(IIC3_2, 0x16e0), INTC_VECT(IIC3_3, 0x1700),
+	INTC_VECT(IIC4_0, 0x17c0), INTC_VECT(IIC4_1, 0x1800),
+	INTC_VECT(IIC4_2, 0x1820), INTC_VECT(IIC4_3, 0x1840),
+	INTC_VECT(IIC5_0, 0x1860), INTC_VECT(IIC5_1, 0x1880),
+	INTC_VECT(IIC5_2, 0x18a0), INTC_VECT(IIC5_3, 0x18c0),
+	INTC_VECT(IIC6_0, 0x18e0), INTC_VECT(IIC6_1, 0x1900),
+	INTC_VECT(IIC6_2, 0x1920), INTC_VECT(IIC6_3, 0x1980),
+	INTC_VECT(IIC7_0, 0x19a0), INTC_VECT(IIC7_1, 0x1a00),
+	INTC_VECT(IIC7_2, 0x1a20), INTC_VECT(IIC7_3, 0x1a40),
+	INTC_VECT(IIC8_0, 0x1a60), INTC_VECT(IIC8_1, 0x1a80),
+	INTC_VECT(IIC8_2, 0x1aa0), INTC_VECT(IIC8_3, 0x1b40),
+	INTC_VECT(IIC9_0, 0x1b60), INTC_VECT(IIC9_1, 0x1b80),
+	INTC_VECT(IIC9_2, 0x1c00), INTC_VECT(IIC9_3, 0x1c20),
+	INTC_VECT(PCIINTA, 0x1ce0),
+	INTC_VECT(PCIE, 0x1e00),
+	INTC_VECT(SGPIO, 0x1f80),
+	INTC_VECT(SGPIO, 0x1fa0),
+};
+
+static struct intc_group groups[] __initdata = {
+	INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI),
+	INTC_GROUP(TMU345, TMU3, TMU4, TMU5),
+};
+
+static struct intc_mask_reg mask_registers[] __initdata = {
+	{ 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */
+	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+
+	{ 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */
+	  { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH,
+	    IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH,
+	    IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH,
+	    IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0,
+	    IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH,
+	    IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH,
+	    IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH,
+	    IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } },
+
+	{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
+	  { 0, 0, 0, 0, 0, 0, 0, 0,
+	    0, DMAC1_8, 0, PECI0I, LPC, FRT, WDT1, TMR45,
+	    TMR23, TMR01, 0, 0, 0, 0, 0, DMAC0,
+	    HUDI, 0, WDT0, SCIF3, SCIF2, SDHI, TMU345, TMU012
+	     } },
+
+	{ 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
+	  { IRQ15, IRQ14, IRQ13, IRQ12, IRQ11, IRQ10, SCIF4, ETHERC,
+	    IRQ9, IRQ8, SCIF1, SCIF0, USB0, 0, 0, USB1,
+	    ADC1, 0, DMAC1_6, ADC0, SPI0, SIM, PECI2I, PECI1I,
+	    ARC4, 0, SPI1, JMC, 0, 0, 0, DVC
+	     } },
+
+	{ 0xffd10038, 0xffd1003c, 32, /* INT2MSKR2 / INT2MSKCR2 */
+	  { IIC4_1, IIC4_2, IIC5_0, 0, 0, 0, SGPIO, 0,
+	    0, 0, 0, IIC9_2, IIC8_2, IIC8_1, IIC8_0, IIC7_3,
+	    IIC7_2, IIC7_1, IIC6_3, IIC0_0, IIC0_1, IIC0_2, IIC0_3, IIC3_1,
+	    IIC2_3, 0, IIC2_1, IIC9_1, IIC3_3, IIC1_0, PCIE, IIC2_2
+	     } },
+
+	{ 0xffd100d0, 0xff1400d4, 32, /* INT2MSKR3 / INT2MSKCR4 */
+	  { 0, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, 0, 0,
+	    IIC1_3, IIC1_2, IIC9_0, IIC8_3, IIC4_3, IIC7_0, 0, IIC6_2,
+	    PCIINTA, 0, IIC4_0, 0, 0, 0, 0, IIC9_3,
+	    IIC3_0, 0, IIC5_3, IIC5_2, 0, 0, 0, IIC1_1
+	     } },
+};
+
+#define INTPRI		0xffd00010
+#define INT2PRI0	0xffd40000
+#define INT2PRI1	0xffd40004
+#define INT2PRI2	0xffd40008
+#define INT2PRI3	0xffd4000c
+#define INT2PRI4	0xffd40010
+#define INT2PRI5	0xffd40014
+#define INT2PRI6	0xffd40018
+#define INT2PRI7	0xffd4001c
+#define INT2PRI8	0xffd400a0
+#define INT2PRI9	0xffd400a4
+#define INT2PRI10	0xffd400a8
+#define INT2PRI11	0xffd400ac
+#define INT2PRI12	0xffd400b0
+#define INT2PRI13	0xffd400b4
+#define INT2PRI14	0xffd400b8
+#define INT2PRI15	0xffd400bc
+#define INT2PRI16	0xffd10000
+#define INT2PRI17	0xffd10004
+#define INT2PRI18	0xffd10008
+#define INT2PRI19	0xffd1000c
+#define INT2PRI20	0xffd10010
+#define INT2PRI21	0xffd10014
+#define INT2PRI22	0xffd10018
+#define INT2PRI23	0xffd1001c
+#define INT2PRI24	0xffd100a0
+#define INT2PRI25	0xffd100a4
+#define INT2PRI26	0xffd100a8
+#define INT2PRI27	0xffd100ac
+#define INT2PRI28	0xffd100b0
+#define INT2PRI29	0xffd100b4
+#define INT2PRI30	0xffd100b8
+#define INT2PRI31	0xffd100bc
+
+static struct intc_prio_reg prio_registers[] __initdata = {
+	{ INTPRI, 0, 32, 4, { IRQ0, IRQ1, IRQ2, IRQ3,
+			      IRQ4, IRQ5, IRQ6, IRQ7 } },
+
+	{ INT2PRI0, 0, 32, 8, { TMU0, TMU1, TMU2, TMU2_TICPI } },
+	{ INT2PRI1, 0, 32, 8, { TMU3, TMU4, TMU5, SDHI } },
+	{ INT2PRI2, 0, 32, 8, { SCIF2, SCIF3, WDT0, IRQ8 } },
+	{ INT2PRI3, 0, 32, 8, { HUDI, DMAC0, ADC0, IRQ9 } },
+	{ INT2PRI4, 0, 32, 8, { IRQ10, 0, TMR01, TMR23 } },
+	{ INT2PRI5, 0, 32, 8, { TMR45, WDT1, FRT, LPC } },
+	{ INT2PRI6, 0, 32, 8, { PECI0I, ETHERC, DMAC1_8, 0 } },
+	{ INT2PRI7, 0, 32, 8, { SCIF4, 0, IRQ11, IRQ12 } },
+	{ INT2PRI8, 0, 32, 8, { 0, 0, 0, DVC } },
+	{ INT2PRI9, 0, 32, 8, { ARC4, 0, SPI1, JMC } },
+	{ INT2PRI10, 0, 32, 8, { SPI0, SIM, PECI2I, PECI1I } },
+	{ INT2PRI11, 0, 32, 8, { ADC1, IRQ13, DMAC1_6, IRQ14 } },
+	{ INT2PRI12, 0, 32, 8, { USB0, 0, IRQ15, USB1 } },
+	{ INT2PRI13, 0, 32, 8, { 0, 0, SCIF1, SCIF0 } },
+
+	{ INT2PRI16, 0, 32, 8, { IIC2_2, 0, 0, 0 } },
+	{ INT2PRI17, 0, 32, 8, { PCIE, 0, 0, IIC1_0 } },
+	{ INT2PRI18, 0, 32, 8, { IIC3_3, IIC9_1, IIC2_1, IIC1_2 } },
+	{ INT2PRI19, 0, 32, 8, { IIC2_3, IIC3_1, 0, IIC1_3 } },
+	{ INT2PRI20, 0, 32, 8, { IIC2_0, IIC6_3, IIC7_1, IIC7_2 } },
+	{ INT2PRI21, 0, 32, 8, { IIC7_3, IIC8_0, IIC8_1, IIC8_2 } },
+	{ INT2PRI22, 0, 32, 8, { IIC9_2, 0, 0, 0 } },
+	{ INT2PRI23, 0, 32, 8, { 0, SGPIO, IIC3_2, IIC5_1 } },
+	{ INT2PRI24, 0, 32, 8, { 0, 0, 0, IIC1_1 } },
+	{ INT2PRI25, 0, 32, 8, { IIC3_0, 0, IIC5_3, IIC5_2 } },
+	{ INT2PRI26, 0, 32, 8, { 0, 0, 0, IIC9_3 } },
+	{ INT2PRI27, 0, 32, 8, { PCIINTA, IIC6_0, IIC4_0, IIC6_1 } },
+	{ INT2PRI28, 0, 32, 8, { IIC4_3, IIC7_0, 0, IIC6_2 } },
+	{ INT2PRI29, 0, 32, 8, { 0, 0, IIC9_0, IIC8_3 } },
+	{ INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, 0 } },
+	{ INT2PRI31, 0, 32, 8, { IIC0_0, IIC0_1, IIC0_2, IIC0_3 } },
+};
+
+static DECLARE_INTC_DESC(intc_desc, "sh7757", vectors, groups,
+			 mask_registers, prio_registers, NULL);
+
+/* Support for external interrupt pins in IRQ mode */
+static struct intc_vect vectors_irq0123[] __initdata = {
+	INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
+	INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
+};
+
+static struct intc_vect vectors_irq4567[] __initdata = {
+	INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
+	INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
+};
+
+static struct intc_sense_reg sense_registers[] __initdata = {
+	{ 0xffd0001c, 32, 2, /* ICR1 */   { IRQ0, IRQ1, IRQ2, IRQ3,
+					    IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static struct intc_mask_reg ack_registers[] __initdata = {
+	{ 0xffd00024, 0, 32, /* INTREQ */
+	  { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } },
+};
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh7757-irq0123",
+			     vectors_irq0123, NULL, mask_registers,
+			     prio_registers, sense_registers, ack_registers);
+
+static DECLARE_INTC_DESC_ACK(intc_desc_irq4567, "sh7757-irq4567",
+			     vectors_irq4567, NULL, mask_registers,
+			     prio_registers, sense_registers, ack_registers);
+
+/* External interrupt pins in IRL mode */
+static struct intc_vect vectors_irl0123[] __initdata = {
+	INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220),
+	INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260),
+	INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0),
+	INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0),
+	INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320),
+	INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360),
+	INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0),
+	INTC_VECT(IRL0_HHHL, 0x3c0),
+};
+
+static struct intc_vect vectors_irl4567[] __initdata = {
+	INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20),
+	INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60),
+	INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0),
+	INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0),
+	INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20),
+	INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60),
+	INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0),
+	INTC_VECT(IRL4_HHHL, 0xcc0),
+};
+
+static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7757-irl0123", vectors_irl0123,
+			 NULL, mask_registers, NULL, NULL);
+
+static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7757-irl4567", vectors_irl4567,
+			 NULL, mask_registers, NULL, NULL);
+
+#define INTC_ICR0	0xffd00000
+#define INTC_INTMSK0	0xffd00044
+#define INTC_INTMSK1	0xffd00048
+#define INTC_INTMSK2	0xffd40080
+#define INTC_INTMSKCLR1	0xffd00068
+#define INTC_INTMSKCLR2	0xffd40084
+
+void __init plat_irq_setup(void)
+{
+	/* disable IRQ3-0 + IRQ7-4 */
+	ctrl_outl(0xff000000, INTC_INTMSK0);
+
+	/* disable IRL3-0 + IRL7-4 */
+	ctrl_outl(0xc0000000, INTC_INTMSK1);
+	ctrl_outl(0xfffefffe, INTC_INTMSK2);
+
+	/* select IRL mode for IRL3-0 + IRL7-4 */
+	ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0);
+
+	/* disable holding function, ie enable "SH-4 Mode" */
+	ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0);
+
+	register_intc_controller(&intc_desc);
+}
+
+void __init plat_irq_setup_pins(int mode)
+{
+	switch (mode) {
+	case IRQ_MODE_IRQ7654:
+		/* select IRQ mode for IRL7-4 */
+		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0);
+		register_intc_controller(&intc_desc_irq4567);
+		break;
+	case IRQ_MODE_IRQ3210:
+		/* select IRQ mode for IRL3-0 */
+		ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0);
+		register_intc_controller(&intc_desc_irq0123);
+		break;
+	case IRQ_MODE_IRL7654:
+		/* enable IRL7-4 but don't provide any masking */
+		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		ctrl_outl(0x0000fffe, INTC_INTMSKCLR2);
+		break;
+	case IRQ_MODE_IRL3210:
+		/* enable IRL0-3 but don't provide any masking */
+		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		ctrl_outl(0xfffe0000, INTC_INTMSKCLR2);
+		break;
+	case IRQ_MODE_IRL7654_MASK:
+		/* enable IRL7-4 and mask using cpu intc controller */
+		ctrl_outl(0x40000000, INTC_INTMSKCLR1);
+		register_intc_controller(&intc_desc_irl4567);
+		break;
+	case IRQ_MODE_IRL3210_MASK:
+		/* enable IRL0-3 and mask using cpu intc controller */
+		ctrl_outl(0x80000000, INTC_INTMSKCLR1);
+		register_intc_controller(&intc_desc_irl0123);
+		break;
+	default:
+		BUG();
+	}
+}
+
+void __init plat_mem_setup(void)
+{
+}
diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
index 07f0789..e848443 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c
@@ -268,11 +268,7 @@ enum {
 	UNUSED = 0,
 
 	/* interrupt sources */
-	IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
-	IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
-	IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
-	IRL_HHLL, IRL_HHLH, IRL_HHHL,
-	IRQ0, IRQ1, IRQ2, IRQ3,
+	IRL, IRQ0, IRQ1, IRQ2, IRQ3,
 	HUDII,
 	TMU0, TMU1, TMU2, TMU3, TMU4, TMU5,
 	PCII0, PCII1, PCII2, PCII3, PCII4,
@@ -287,10 +283,7 @@ enum {
 	DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9,
 	DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE,
 	IIC, VIN0, VIN1, VCORE0, ATAPI,
-	DTU0_TEND, DTU0_AE, DTU0_TMISS,
-	DTU1_TEND, DTU1_AE, DTU1_TMISS,
-	DTU2_TEND, DTU2_AE, DTU2_TMISS,
-	DTU3_TEND, DTU3_AE, DTU3_TMISS,
+	DTU0, DTU1, DTU2, DTU3,
 	FE0, FE1,
 	GPIO0, GPIO1, GPIO2, GPIO3,
 	PAM, IRM,
@@ -298,8 +291,8 @@ enum {
 	INTICI4, INTICI5, INTICI6, INTICI7,
 
 	/* interrupt groups */
-	IRL, PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
-	DMAC0, DMAC1, DTU0, DTU1, DTU2, DTU3,
+	PCII56789, SCIF0, SCIF1, SCIF2, SCIF3,
+	DMAC0, DMAC1,
 };
 
 static struct intc_vect vectors[] __initdata = {
@@ -332,14 +325,14 @@ static struct intc_vect vectors[] __initdata = {
 	INTC_VECT(IIC, 0xae0),
 	INTC_VECT(VIN0, 0xb00), INTC_VECT(VIN1, 0xb20),
 	INTC_VECT(VCORE0, 0xb00), INTC_VECT(ATAPI, 0xb60),
-	INTC_VECT(DTU0_TEND, 0xc00), INTC_VECT(DTU0_AE, 0xc20),
-	INTC_VECT(DTU0_TMISS, 0xc40),
-	INTC_VECT(DTU1_TEND, 0xc60), INTC_VECT(DTU1_AE, 0xc80),
-	INTC_VECT(DTU1_TMISS, 0xca0),
-	INTC_VECT(DTU2_TEND, 0xcc0), INTC_VECT(DTU2_AE, 0xce0),
-	INTC_VECT(DTU2_TMISS, 0xd00),
-	INTC_VECT(DTU3_TEND, 0xd20), INTC_VECT(DTU3_AE, 0xd40),
-	INTC_VECT(DTU3_TMISS, 0xd60),
+	INTC_VECT(DTU0, 0xc00), INTC_VECT(DTU0, 0xc20),
+	INTC_VECT(DTU0, 0xc40),
+	INTC_VECT(DTU1, 0xc60), INTC_VECT(DTU1, 0xc80),
+	INTC_VECT(DTU1, 0xca0),
+	INTC_VECT(DTU2, 0xcc0), INTC_VECT(DTU2, 0xce0),
+	INTC_VECT(DTU2, 0xd00),
+	INTC_VECT(DTU3, 0xd20), INTC_VECT(DTU3, 0xd40),
+	INTC_VECT(DTU3, 0xd60),
 	INTC_VECT(FE0, 0xe00), INTC_VECT(FE1, 0xe20),
 	INTC_VECT(GPIO0, 0xe40), INTC_VECT(GPIO1, 0xe60),
 	INTC_VECT(GPIO2, 0xe80), INTC_VECT(GPIO3, 0xea0),
@@ -351,10 +344,6 @@ static struct intc_vect vectors[] __initdata = {
 };
 
 static struct intc_group groups[] __initdata = {
-	INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH,
-		   IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH,
-		   IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH,
-		   IRL_HHLL, IRL_HHLH, IRL_HHHL),
 	INTC_GROUP(PCII56789, PCII5, PCII6, PCII7, PCII8, PCII9),
 	INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI),
 	INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI),
@@ -364,10 +353,6 @@ static struct intc_group groups[] __initdata = {
 		   DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE),
 	INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8,
 		   DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11),
-	INTC_GROUP(DTU0, DTU0_TEND, DTU0_AE, DTU0_TMISS),
-	INTC_GROUP(DTU1, DTU1_TEND, DTU1_AE, DTU1_TMISS),
-	INTC_GROUP(DTU2, DTU2_TEND, DTU2_AE, DTU2_TMISS),
-	INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS),
 };
 
 static struct intc_mask_reg mask_registers[] __initdata = {
@@ -434,14 +419,14 @@ static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups,
 
 /* External interrupt pins in IRL mode */
 static struct intc_vect vectors_irl[] __initdata = {
-	INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220),
-	INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260),
-	INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0),
-	INTC_VECT(IRL_LHHL, 0x2c0), INTC_VECT(IRL_LHHH, 0x2e0),
-	INTC_VECT(IRL_HLLL, 0x300), INTC_VECT(IRL_HLLH, 0x320),
-	INTC_VECT(IRL_HLHL, 0x340), INTC_VECT(IRL_HLHH, 0x360),
-	INTC_VECT(IRL_HHLL, 0x380), INTC_VECT(IRL_HHLH, 0x3a0),
-	INTC_VECT(IRL_HHHL, 0x3c0),
+	INTC_VECT(IRL, 0x200), INTC_VECT(IRL, 0x220),
+	INTC_VECT(IRL, 0x240), INTC_VECT(IRL, 0x260),
+	INTC_VECT(IRL, 0x280), INTC_VECT(IRL, 0x2a0),
+	INTC_VECT(IRL, 0x2c0), INTC_VECT(IRL, 0x2e0),
+	INTC_VECT(IRL, 0x300), INTC_VECT(IRL, 0x320),
+	INTC_VECT(IRL, 0x340), INTC_VECT(IRL, 0x360),
+	INTC_VECT(IRL, 0x380), INTC_VECT(IRL, 0x3a0),
+	INTC_VECT(IRL, 0x3c0),
 };
 
 static DECLARE_INTC_DESC(intc_desc_irl, "shx3-irl", vectors_irl, groups,
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
index 2b6b0d5..185ec39 100644
--- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -57,6 +57,8 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
 {
 	int i;
 
+	local_timer_setup(0);
+
 	BUILD_BUG_ON(SMP_MSG_NR >= 8);
 
 	for (i = 0; i < SMP_MSG_NR; i++)
diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c
index 92ad844..521d05b 100644
--- a/arch/sh/kernel/cpu/sh5/probe.c
+++ b/arch/sh/kernel/cpu/sh5/probe.c
@@ -34,6 +34,8 @@ int __init detect_cpu_and_cache_system(void)
 		/* CPU.VCR aliased at CIR address on SH5-101 */
 		boot_cpu_data.type = CPU_SH5_101;
 
+	boot_cpu_data.family = CPU_FAMILY_SH5;
+
 	/*
 	 * First, setup some sane values for the I-cache.
 	 */
diff --git a/arch/sh/kernel/cpu/shmobile/Makefile b/arch/sh/kernel/cpu/shmobile/Makefile
index 08bfa7c..a39f88e 100644
--- a/arch/sh/kernel/cpu/shmobile/Makefile
+++ b/arch/sh/kernel/cpu/shmobile/Makefile
@@ -4,3 +4,5 @@
 
 # Power Management & Sleep mode
 obj-$(CONFIG_PM)	+= pm.o sleep.o
+obj-$(CONFIG_CPU_IDLE)	+= cpuidle.o
+obj-$(CONFIG_PM_RUNTIME)	+= pm_runtime.o
diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
new file mode 100644
index 0000000..1c504bd
--- /dev/null
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -0,0 +1,113 @@
+/*
+ * arch/sh/kernel/cpu/shmobile/cpuidle.c
+ *
+ * Cpuidle support code for SuperH Mobile
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/cpuidle.h>
+#include <asm/suspend.h>
+#include <asm/uaccess.h>
+#include <asm/hwblk.h>
+
+static unsigned long cpuidle_mode[] = {
+	SUSP_SH_SLEEP, /* regular sleep mode */
+	SUSP_SH_SLEEP | SUSP_SH_SF, /* sleep mode + self refresh */
+	SUSP_SH_STANDBY | SUSP_SH_SF, /* software standby mode + self refresh */
+};
+
+static int cpuidle_sleep_enter(struct cpuidle_device *dev,
+			       struct cpuidle_state *state)
+{
+	unsigned long allowed_mode = arch_hwblk_sleep_mode();
+	ktime_t before, after;
+	int requested_state = state - &dev->states[0];
+	int allowed_state;
+	int k;
+
+	/* convert allowed mode to allowed state */
+	for (k = ARRAY_SIZE(cpuidle_mode) - 1; k > 0; k--)
+		if (cpuidle_mode[k] == allowed_mode)
+			break;
+
+	allowed_state = k;
+
+	/* take the following into account for sleep mode selection:
+	 * - allowed_state: best mode allowed by hardware (clock deps)
+	 * - requested_state: best mode allowed by software (latencies)
+	 */
+	k = min_t(int, allowed_state, requested_state);
+
+	dev->last_state = &dev->states[k];
+	before = ktime_get();
+	sh_mobile_call_standby(cpuidle_mode[k]);
+	after = ktime_get();
+	return ktime_to_ns(ktime_sub(after, before)) >> 10;
+}
+
+static struct cpuidle_device cpuidle_dev;
+static struct cpuidle_driver cpuidle_driver = {
+	.name =		"sh_idle",
+	.owner =	THIS_MODULE,
+};
+
+void sh_mobile_setup_cpuidle(void)
+{
+	struct cpuidle_device *dev = &cpuidle_dev;
+	struct cpuidle_state *state;
+	int i;
+
+	cpuidle_register_driver(&cpuidle_driver);
+
+	for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
+		dev->states[i].name[0] = '\0';
+		dev->states[i].desc[0] = '\0';
+	}
+
+	i = CPUIDLE_DRIVER_STATE_START;
+
+	state = &dev->states[i++];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C0");
+	strncpy(state->desc, "SuperH Sleep Mode", CPUIDLE_DESC_LEN);
+	state->exit_latency = 1;
+	state->target_residency = 1 * 2;
+	state->power_usage = 3;
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_SHALLOW;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+	state->enter = cpuidle_sleep_enter;
+
+	dev->safe_state = state;
+
+	state = &dev->states[i++];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+	strncpy(state->desc, "SuperH Sleep Mode [SF]", CPUIDLE_DESC_LEN);
+	state->exit_latency = 100;
+	state->target_residency = 1 * 2;
+	state->power_usage = 1;
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+	state->enter = cpuidle_sleep_enter;
+
+	state = &dev->states[i++];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+	strncpy(state->desc, "SuperH Mobile Standby Mode [SF]", CPUIDLE_DESC_LEN);
+	state->exit_latency = 2300;
+	state->target_residency = 1 * 2;
+	state->power_usage = 1;
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+	state->enter = cpuidle_sleep_enter;
+
+	dev->state_count = i;
+
+	cpuidle_register_device(dev);
+}
diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c
index 8c067ad..ee3c2aa 100644
--- a/arch/sh/kernel/cpu/shmobile/pm.c
+++ b/arch/sh/kernel/cpu/shmobile/pm.c
@@ -1,5 +1,5 @@
 /*
- * arch/sh/kernel/cpu/sh4a/pm-sh_mobile.c
+ * arch/sh/kernel/cpu/shmobile/pm.c
  *
  * Power management support code for SuperH Mobile
  *
@@ -32,40 +32,20 @@
  *
  * R-standby mode is unsupported, but will be added in the future
  * U-standby mode is low priority since it needs bootloader hacks
- *
- * All modes should be tied in with cpuidle. But before that can
- * happen we need to keep track of enabled hardware blocks so we
- * can avoid entering sleep modes that stop clocks to hardware
- * blocks that are in use even though the cpu core is idle.
  */
 
+#define ILRAM_BASE 0xe5200000
+
 extern const unsigned char sh_mobile_standby[];
 extern const unsigned int sh_mobile_standby_size;
 
-static void sh_mobile_call_standby(unsigned long mode)
+void sh_mobile_call_standby(unsigned long mode)
 {
-	extern void *vbr_base;
-	void *onchip_mem = (void *)0xe5200000; /* ILRAM */
-	void (*standby_onchip_mem)(unsigned long) = onchip_mem;
-
-	/* Note: Wake up from sleep may generate exceptions!
-	 * Setup VBR to point to on-chip ram if self-refresh is
-	 * going to be used.
-	 */
-	if (mode & SUSP_SH_SF)
-		asm volatile("ldc %0, vbr" : : "r" (onchip_mem) : "memory");
-
-	/* Copy the assembly snippet to the otherwise ununsed ILRAM */
-	memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
-	wmb();
-	ctrl_barrier();
+	void *onchip_mem = (void *)ILRAM_BASE;
+	void (*standby_onchip_mem)(unsigned long, unsigned long) = onchip_mem;
 
 	/* Let assembly snippet in on-chip memory handle the rest */
-	standby_onchip_mem(mode);
-
-	/* Put VBR back in System RAM again */
-	if (mode & SUSP_SH_SF)
-		asm volatile("ldc %0, vbr" : : "r" (&vbr_base) : "memory");
+	standby_onchip_mem(mode, ILRAM_BASE);
 }
 
 static int sh_pm_enter(suspend_state_t state)
@@ -85,7 +65,15 @@ static struct platform_suspend_ops sh_pm_ops = {
 
 static int __init sh_pm_init(void)
 {
+	void *onchip_mem = (void *)ILRAM_BASE;
+
+	/* Copy the assembly snippet to the otherwise ununsed ILRAM */
+	memcpy(onchip_mem, sh_mobile_standby, sh_mobile_standby_size);
+	wmb();
+	ctrl_barrier();
+
 	suspend_set_ops(&sh_pm_ops);
+	sh_mobile_setup_cpuidle();
 	return 0;
 }
 
diff --git a/arch/sh/kernel/cpu/shmobile/pm_runtime.c b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
new file mode 100644
index 0000000..7c615b1
--- /dev/null
+++ b/arch/sh/kernel/cpu/shmobile/pm_runtime.c
@@ -0,0 +1,303 @@
+/*
+ * arch/sh/kernel/cpu/shmobile/pm_runtime.c
+ *
+ * Runtime PM support code for SuperH Mobile
+ *
+ *  Copyright (C) 2009 Magnus Damm
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <asm/hwblk.h>
+
+static DEFINE_SPINLOCK(hwblk_lock);
+static LIST_HEAD(hwblk_idle_list);
+static struct work_struct hwblk_work;
+
+extern struct hwblk_info *hwblk_info;
+
+static void platform_pm_runtime_not_idle(struct platform_device *pdev)
+{
+	unsigned long flags;
+
+	/* remove device from idle list */
+	spin_lock_irqsave(&hwblk_lock, flags);
+	if (test_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags)) {
+		list_del(&pdev->archdata.entry);
+		__clear_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags);
+	}
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+}
+
+static int __platform_pm_runtime_resume(struct platform_device *pdev)
+{
+	struct device *d = &pdev->dev;
+	struct pdev_archdata *ad = &pdev->archdata;
+	int hwblk = ad->hwblk_id;
+	int ret = -ENOSYS;
+
+	dev_dbg(d, "__platform_pm_runtime_resume() [%d]\n", hwblk);
+
+	if (d->driver && d->driver->pm && d->driver->pm->runtime_resume) {
+		hwblk_enable(hwblk_info, hwblk);
+		ret = 0;
+
+		if (test_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags)) {
+			ret = d->driver->pm->runtime_resume(d);
+			if (!ret)
+				clear_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
+			else
+				hwblk_disable(hwblk_info, hwblk);
+		}
+	}
+
+	dev_dbg(d, "__platform_pm_runtime_resume() [%d] - returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+static int __platform_pm_runtime_suspend(struct platform_device *pdev)
+{
+	struct device *d = &pdev->dev;
+	struct pdev_archdata *ad = &pdev->archdata;
+	int hwblk = ad->hwblk_id;
+	int ret = -ENOSYS;
+
+	dev_dbg(d, "__platform_pm_runtime_suspend() [%d]\n", hwblk);
+
+	if (d->driver && d->driver->pm && d->driver->pm->runtime_suspend) {
+		BUG_ON(!test_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags));
+
+		hwblk_enable(hwblk_info, hwblk);
+		ret = d->driver->pm->runtime_suspend(d);
+		hwblk_disable(hwblk_info, hwblk);
+
+		if (!ret) {
+			set_bit(PDEV_ARCHDATA_FLAG_SUSP, &ad->flags);
+			platform_pm_runtime_not_idle(pdev);
+			hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
+		}
+	}
+
+	dev_dbg(d, "__platform_pm_runtime_suspend() [%d] - returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+static void platform_pm_runtime_work(struct work_struct *work)
+{
+	struct platform_device *pdev;
+	unsigned long flags;
+	int ret;
+
+	/* go through the idle list and suspend one device at a time */
+	do {
+		spin_lock_irqsave(&hwblk_lock, flags);
+		if (list_empty(&hwblk_idle_list))
+			pdev = NULL;
+		else
+			pdev = list_first_entry(&hwblk_idle_list,
+						struct platform_device,
+						archdata.entry);
+		spin_unlock_irqrestore(&hwblk_lock, flags);
+
+		if (pdev) {
+			mutex_lock(&pdev->archdata.mutex);
+			ret = __platform_pm_runtime_suspend(pdev);
+
+			/* at this point the platform device may be:
+			 * suspended: ret = 0, FLAG_SUSP set, clock stopped
+			 * failed: ret < 0, FLAG_IDLE set, clock stopped
+			 */
+			mutex_unlock(&pdev->archdata.mutex);
+		} else {
+			ret = -ENODEV;
+		}
+	} while (!ret);
+}
+
+/* this function gets called from cpuidle context when all devices in the
+ * main power domain are unused but some are counted as idle, ie the hwblk
+ * counter values are (HWBLK_CNT_USAGE == 0) && (HWBLK_CNT_IDLE != 0)
+ */
+void platform_pm_runtime_suspend_idle(void)
+{
+	queue_work(pm_wq, &hwblk_work);
+}
+
+int platform_pm_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pdev_archdata *ad = &pdev->archdata;
+	unsigned long flags;
+	int hwblk = ad->hwblk_id;
+	int ret = 0;
+
+	dev_dbg(dev, "platform_pm_runtime_suspend() [%d]\n", hwblk);
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		goto out;
+
+	/* interrupt context not allowed */
+	might_sleep();
+
+	/* catch misconfigured drivers not starting with resume */
+	if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* serialize */
+	mutex_lock(&ad->mutex);
+
+	/* disable clock */
+	hwblk_disable(hwblk_info, hwblk);
+
+	/* put device on idle list */
+	spin_lock_irqsave(&hwblk_lock, flags);
+	list_add_tail(&pdev->archdata.entry, &hwblk_idle_list);
+	__set_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags);
+	spin_unlock_irqrestore(&hwblk_lock, flags);
+
+	/* increase idle count */
+	hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_IDLE);
+
+	/* at this point the platform device is:
+	 * idle: ret = 0, FLAG_IDLE set, clock stopped
+	 */
+	mutex_unlock(&ad->mutex);
+
+out:
+	dev_dbg(dev, "platform_pm_runtime_suspend() [%d] returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+int platform_pm_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pdev_archdata *ad = &pdev->archdata;
+	int hwblk = ad->hwblk_id;
+	int ret = 0;
+
+	dev_dbg(dev, "platform_pm_runtime_resume() [%d]\n", hwblk);
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		goto out;
+
+	/* interrupt context not allowed */
+	might_sleep();
+
+	/* serialize */
+	mutex_lock(&ad->mutex);
+
+	/* make sure device is removed from idle list */
+	platform_pm_runtime_not_idle(pdev);
+
+	/* decrease idle count */
+	if (!test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags) &&
+	    !test_bit(PDEV_ARCHDATA_FLAG_SUSP, &pdev->archdata.flags))
+		hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_IDLE);
+
+	/* resume the device if needed */
+	ret = __platform_pm_runtime_resume(pdev);
+
+	/* the driver has been initialized now, so clear the init flag */
+	clear_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+
+	/* at this point the platform device may be:
+	 * resumed: ret = 0, flags = 0, clock started
+	 * failed: ret < 0, FLAG_SUSP set, clock stopped
+	 */
+	mutex_unlock(&ad->mutex);
+out:
+	dev_dbg(dev, "platform_pm_runtime_resume() [%d] returns %d\n",
+		hwblk, ret);
+
+	return ret;
+}
+
+int platform_pm_runtime_idle(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int hwblk = pdev->archdata.hwblk_id;
+	int ret = 0;
+
+	dev_dbg(dev, "platform_pm_runtime_idle() [%d]\n", hwblk);
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		goto out;
+
+	/* interrupt context not allowed, use pm_runtime_put()! */
+	might_sleep();
+
+	/* suspend synchronously to disable clocks immediately */
+	ret = pm_runtime_suspend(dev);
+out:
+	dev_dbg(dev, "platform_pm_runtime_idle() [%d] done!\n", hwblk);
+	return ret;
+}
+
+static int platform_bus_notify(struct notifier_block *nb,
+			       unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct platform_device *pdev = to_platform_device(dev);
+	int hwblk = pdev->archdata.hwblk_id;
+
+	/* ignore off-chip platform devices */
+	if (!hwblk)
+		return 0;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		INIT_LIST_HEAD(&pdev->archdata.entry);
+		mutex_init(&pdev->archdata.mutex);
+		/* platform devices without drivers should be disabled */
+		hwblk_enable(hwblk_info, hwblk);
+		hwblk_disable(hwblk_info, hwblk);
+		/* make sure driver re-inits itself once */
+		__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+		break;
+	/* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */
+	case BUS_NOTIFY_BOUND_DRIVER:
+		/* keep track of number of devices in use per hwblk */
+		hwblk_cnt_inc(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		/* keep track of number of devices in use per hwblk */
+		hwblk_cnt_dec(hwblk_info, hwblk, HWBLK_CNT_DEVICES);
+		/* make sure driver re-inits itself once */
+		__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+		break;
+	case BUS_NOTIFY_DEL_DEVICE:
+		break;
+	}
+	return 0;
+}
+
+static struct notifier_block platform_bus_notifier = {
+	.notifier_call = platform_bus_notify
+};
+
+static int __init sh_pm_runtime_init(void)
+{
+	INIT_WORK(&hwblk_work, platform_pm_runtime_work);
+
+	bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
+	return 0;
+}
+core_initcall(sh_pm_runtime_init);
diff --git a/arch/sh/kernel/cpu/shmobile/sleep.S b/arch/sh/kernel/cpu/shmobile/sleep.S
index baf2d7d..a439e6c 100644
--- a/arch/sh/kernel/cpu/shmobile/sleep.S
+++ b/arch/sh/kernel/cpu/shmobile/sleep.S
@@ -16,19 +16,52 @@
 #include <asm/asm-offsets.h>
 #include <asm/suspend.h>
 
+/*
+ * Kernel mode register usage, see entry.S:
+ *	k0	scratch
+ *	k1	scratch
+ *	k4	scratch
+ */
+#define k0	r0
+#define k1	r1
+#define k4	r4
+
 /* manage self-refresh and enter standby mode.
  * this code will be copied to on-chip memory and executed from there.
  */
 
 	.balign 	4096,0,4096
 ENTRY(sh_mobile_standby)
+
+	/* save original vbr */
+	stc	vbr, r1
+	mova	saved_vbr, r0
+	mov.l	r1, @r0
+
+	/* point vbr to our on-chip memory page */
+	ldc	r5, vbr
+
+	/* save return address */
+	mova	saved_spc, r0
+	sts	pr, r5
+	mov.l	r5, @r0
+
+	/* save sr */
+	mova	saved_sr, r0
+	stc	sr, r5
+	mov.l	r5, @r0
+
+	/* save mode flags */
+	mova	saved_mode, r0
+	mov.l	r4, @r0
+
+	/* put mode flags in r0 */
 	mov	r4, r0
 
 	tst	#SUSP_SH_SF, r0
 	bt	skip_set_sf
 #ifdef CONFIG_CPU_SUBTYPE_SH7724
 	/* DBSC: put memory in self-refresh mode */
-
 	mov.l	dben_reg, r4
 	mov.l	dben_data0, r1
 	mov.l	r1, @r4
@@ -60,14 +93,6 @@ ENTRY(sh_mobile_standby)
 #endif
 
 skip_set_sf:
-	tst	#SUSP_SH_SLEEP, r0
-	bt	test_standby
-
-	/* set mode to "sleep mode" */
-	bra	do_sleep
-	 mov	#0x00, r1
-
-test_standby:
 	tst	#SUSP_SH_STANDBY, r0
 	bt	test_rstandby
 
@@ -85,77 +110,107 @@ test_rstandby:
 
 test_ustandby:
 	tst	#SUSP_SH_USTANDBY, r0
-	bt	done_sleep
+	bt	force_sleep
 
 	/* set mode to "u-standby mode" */
-	mov	#0x10, r1
+	bra	do_sleep
+	 mov	#0x10, r1
 
-	/* fall-through */
+force_sleep:
+
+	/* set mode to "sleep mode" */
+	mov	#0x00, r1
 
 do_sleep:
 	/* setup and enter selected standby mode */
 	mov.l	5f, r4
 	mov.l	r1, @r4
+again:
 	sleep
+	bra	again
+	 nop
+
+restore_jump_vbr:
+	/* setup spc with return address to c code */
+	mov.l	saved_spc, k0
+	ldc	k0, spc
+
+	/* restore vbr */
+	mov.l	saved_vbr, k0
+	ldc	k0, vbr
+
+	/* setup ssr with saved sr */
+	mov.l	saved_sr, k0
+	ldc	k0, ssr
+
+	/* get mode flags */
+	mov.l	saved_mode, k0
 
 done_sleep:
 	/* reset standby mode to sleep mode */
-	mov.l	5f, r4
-	mov	#0x00, r1
-	mov.l	r1, @r4
+	mov.l	5f, k4
+	mov	#0x00, k1
+	mov.l	k1, @k4
 
-	tst	#SUSP_SH_SF, r0
+	tst	#SUSP_SH_SF, k0
 	bt	skip_restore_sf
 
 #ifdef CONFIG_CPU_SUBTYPE_SH7724
 	/* DBSC: put memory in auto-refresh mode */
+	mov.l	dbrfpdn0_reg, k4
+	mov.l	dbrfpdn0_data0, k1
+	mov.l	k1, @k4
 
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data0, r1
-	mov.l	r1, @r4
-
-	/* sleep 140 ns */
-	nop
+	nop /* sleep 140 ns */
 	nop
 	nop
 	nop
 
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data0, r1
-	mov.l	r1, @r4
+	mov.l	dbcmdcnt_reg, k4
+	mov.l	dbcmdcnt_data0, k1
+	mov.l	k1, @k4
 
-	mov.l	dbcmdcnt_reg, r4
-	mov.l	dbcmdcnt_data1, r1
-	mov.l	r1, @r4
+	mov.l	dbcmdcnt_reg, k4
+	mov.l	dbcmdcnt_data1, k1
+	mov.l	k1, @k4
 
-	mov.l	dben_reg, r4
-	mov.l	dben_data1, r1
-	mov.l	r1, @r4
+	mov.l	dben_reg, k4
+	mov.l	dben_data1, k1
+	mov.l	k1, @k4
 
-	mov.l	dbrfpdn0_reg, r4
-	mov.l	dbrfpdn0_data2, r1
-	mov.l	r1, @r4
+	mov.l	dbrfpdn0_reg, k4
+	mov.l	dbrfpdn0_data2, k1
+	mov.l	k1, @k4
 #else
 	/* SBSC: set auto-refresh mode */
-	mov.l	1f, r4
-	mov.l	@r4, r2
-	mov.l   4f, r3
-	and	r3, r2
-	mov.l	r2, @r4
-	mov.l	6f, r4
-	mov.l	7f, r1
-	mov.l	8f, r2
-	mov.l	@r4, r3
-	mov	#-1, r4
-	add	r4, r3
-	or	r2, r3
-	mov.l	r3, @r1
+	mov.l	1f, k4
+	mov.l	@k4, k0
+	mov.l   4f, k1
+	and	k1, k0
+	mov.l	k0, @k4
+	mov.l	6f, k4
+	mov.l	8f, k0
+	mov.l	@k4, k1
+	mov	#-1, k4
+	add	k4, k1
+	or	k1, k0
+	mov.l	7f, k1
+	mov.l	k0, @k1
 #endif
 skip_restore_sf:
-	rts
+	/* jump to vbr vector */
+	mov.l	saved_vbr, k0
+	mov.l	offset_vbr, k4
+	add	k4, k0
+	jmp	@k0
 	 nop
 
 	.balign 4
+saved_mode:	.long	0
+saved_spc:	.long	0
+saved_sr:	.long	0
+saved_vbr:	.long	0
+offset_vbr:	.long	0x600
 #ifdef CONFIG_CPU_SUBTYPE_SH7724
 dben_reg:	.long	0xfd000010 /* DBEN */
 dben_data0:	.long	0
@@ -178,12 +233,12 @@ dbcmdcnt_data1:	.long	4
 7:	.long   0xfe400018 /* RTCNT */
 8:	.long   0xa55a0000
 
+
 /* interrupt vector @ 0x600 */
 	.balign 	0x400,0,0x400
 	.long	0xdeadbeef
 	.balign 	0x200,0,0x200
-	/* sh7722 will end up here in sleep mode */
-	rte
+	bra	restore_jump_vbr
 	 nop
 sh_mobile_standby_end:
 
diff --git a/arch/sh/kernel/cpufreq.c b/arch/sh/kernel/cpufreq.c
index e0590ff..dce4f3f 100644
--- a/arch/sh/kernel/cpufreq.c
+++ b/arch/sh/kernel/cpufreq.c
@@ -82,7 +82,8 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
 	cpuclk = clk_get(NULL, "cpu_clk");
 	if (IS_ERR(cpuclk)) {
-		printk(KERN_ERR "cpufreq: couldn't get CPU clk\n");
+		printk(KERN_ERR "cpufreq: couldn't get CPU#%d clk\n",
+		       policy->cpu);
 		return PTR_ERR(cpuclk);
 	}
 
@@ -95,22 +96,21 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	policy->min		= policy->cpuinfo.min_freq;
 	policy->max		= policy->cpuinfo.max_freq;
 
-
 	/*
 	 * Catch the cases where the clock framework hasn't been wired up
 	 * properly to support scaling.
 	 */
 	if (unlikely(policy->min == policy->max)) {
 		printk(KERN_ERR "cpufreq: clock framework rate rounding "
-		       "not supported on this CPU.\n");
+		       "not supported on CPU#%d.\n", policy->cpu);
 
 		clk_put(cpuclk);
 		return -EINVAL;
 	}
 
-	printk(KERN_INFO "cpufreq: Frequencies - Minimum %u.%03u MHz, "
+	printk(KERN_INFO "cpufreq: CPU#%d Frequencies - Minimum %u.%03u MHz, "
 	       "Maximum %u.%03u MHz.\n",
-	       policy->min / 1000, policy->min % 1000,
+	       policy->cpu, policy->min / 1000, policy->min % 1000,
 	       policy->max / 1000, policy->max % 1000);
 
 	return 0;
diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c
new file mode 100644
index 0000000..6f5ad15
--- /dev/null
+++ b/arch/sh/kernel/dumpstack.c
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs
+ *  Copyright (C) 2009  Matt Fleming
+ */
+#include <linux/kallsyms.h>
+#include <linux/ftrace.h>
+#include <linux/debug_locks.h>
+#include <asm/unwinder.h>
+#include <asm/stacktrace.h>
+
+void printk_address(unsigned long address, int reliable)
+{
+	printk(" [<%p>] %s%pS\n", (void *) address,
+			reliable ? "" : "? ", (void *) address);
+}
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+			const struct stacktrace_ops *ops,
+			struct thread_info *tinfo, int *graph)
+{
+	struct task_struct *task = tinfo->task;
+	unsigned long ret_addr;
+	int index = task->curr_ret_stack;
+
+	if (addr != (unsigned long)return_to_handler)
+		return;
+
+	if (!task->ret_stack || index < *graph)
+		return;
+
+	index -= *graph;
+	ret_addr = task->ret_stack[index].ret;
+
+	ops->address(data, ret_addr, 1);
+
+	(*graph)++;
+}
+#else
+static inline void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+			const struct stacktrace_ops *ops,
+			struct thread_info *tinfo, int *graph)
+{ }
+#endif
+
+void
+stack_reader_dump(struct task_struct *task, struct pt_regs *regs,
+		  unsigned long *sp, const struct stacktrace_ops *ops,
+		  void *data)
+{
+	struct thread_info *context;
+	int graph = 0;
+
+	context = (struct thread_info *)
+		((unsigned long)sp & (~(THREAD_SIZE - 1)));
+
+	while (!kstack_end(sp)) {
+		unsigned long addr = *sp++;
+
+		if (__kernel_text_address(addr)) {
+			ops->address(data, addr, 1);
+
+			print_ftrace_graph_addr(addr, data, ops,
+						context, &graph);
+		}
+	}
+}
+
+static void
+print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+	printk(data);
+	print_symbol(msg, symbol);
+	printk("\n");
+}
+
+static void print_trace_warning(void *data, char *msg)
+{
+	printk("%s%s\n", (char *)data, msg);
+}
+
+static int print_trace_stack(void *data, char *name)
+{
+	printk("%s <%s> ", (char *)data, name);
+	return 0;
+}
+
+/*
+ * Print one address/symbol entries per line.
+ */
+static void print_trace_address(void *data, unsigned long addr, int reliable)
+{
+	printk(data);
+	printk_address(addr, reliable);
+}
+
+static const struct stacktrace_ops print_trace_ops = {
+	.warning = print_trace_warning,
+	.warning_symbol = print_trace_warning_symbol,
+	.stack = print_trace_stack,
+	.address = print_trace_address,
+};
+
+void show_trace(struct task_struct *tsk, unsigned long *sp,
+		struct pt_regs *regs)
+{
+	if (regs && user_mode(regs))
+		return;
+
+	printk("\nCall trace:\n");
+
+	unwind_stack(tsk, regs, sp, &print_trace_ops, "");
+
+	printk("\n");
+
+	if (!tsk)
+		tsk = current;
+
+	debug_show_held_locks(tsk);
+}
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
new file mode 100644
index 0000000..bc4d8d7
--- /dev/null
+++ b/arch/sh/kernel/dwarf.c
@@ -0,0 +1,972 @@
+/*
+ * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * This is an implementation of a DWARF unwinder. Its main purpose is
+ * for generating stacktrace information. Based on the DWARF 3
+ * specification from http://www.dwarfstd.org.
+ *
+ * TODO:
+ *	- DWARF64 doesn't work.
+ *	- Registers with DWARF_VAL_OFFSET rules aren't handled properly.
+ */
+
+/* #define DEBUG */
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/mempool.h>
+#include <linux/mm.h>
+#include <asm/dwarf.h>
+#include <asm/unwinder.h>
+#include <asm/sections.h>
+#include <asm/unaligned.h>
+#include <asm/dwarf.h>
+#include <asm/stacktrace.h>
+
+/* Reserve enough memory for two stack frames */
+#define DWARF_FRAME_MIN_REQ	2
+/* ... with 4 registers per frame. */
+#define DWARF_REG_MIN_REQ	(DWARF_FRAME_MIN_REQ * 4)
+
+static struct kmem_cache *dwarf_frame_cachep;
+static mempool_t *dwarf_frame_pool;
+
+static struct kmem_cache *dwarf_reg_cachep;
+static mempool_t *dwarf_reg_pool;
+
+static LIST_HEAD(dwarf_cie_list);
+static DEFINE_SPINLOCK(dwarf_cie_lock);
+
+static LIST_HEAD(dwarf_fde_list);
+static DEFINE_SPINLOCK(dwarf_fde_lock);
+
+static struct dwarf_cie *cached_cie;
+
+/**
+ *	dwarf_frame_alloc_reg - allocate memory for a DWARF register
+ *	@frame: the DWARF frame whose list of registers we insert on
+ *	@reg_num: the register number
+ *
+ *	Allocate space for, and initialise, a dwarf reg from
+ *	dwarf_reg_pool and insert it onto the (unsorted) linked-list of
+ *	dwarf registers for @frame.
+ *
+ *	Return the initialised DWARF reg.
+ */
+static struct dwarf_reg *dwarf_frame_alloc_reg(struct dwarf_frame *frame,
+					       unsigned int reg_num)
+{
+	struct dwarf_reg *reg;
+
+	reg = mempool_alloc(dwarf_reg_pool, GFP_ATOMIC);
+	if (!reg) {
+		printk(KERN_WARNING "Unable to allocate a DWARF register\n");
+		/*
+		 * Let's just bomb hard here, we have no way to
+		 * gracefully recover.
+		 */
+		UNWINDER_BUG();
+	}
+
+	reg->number = reg_num;
+	reg->addr = 0;
+	reg->flags = 0;
+
+	list_add(&reg->link, &frame->reg_list);
+
+	return reg;
+}
+
+static void dwarf_frame_free_regs(struct dwarf_frame *frame)
+{
+	struct dwarf_reg *reg, *n;
+
+	list_for_each_entry_safe(reg, n, &frame->reg_list, link) {
+		list_del(&reg->link);
+		mempool_free(reg, dwarf_reg_pool);
+	}
+}
+
+/**
+ *	dwarf_frame_reg - return a DWARF register
+ *	@frame: the DWARF frame to search in for @reg_num
+ *	@reg_num: the register number to search for
+ *
+ *	Lookup and return the dwarf reg @reg_num for this frame. Return
+ *	NULL if @reg_num is an register invalid number.
+ */
+static struct dwarf_reg *dwarf_frame_reg(struct dwarf_frame *frame,
+					 unsigned int reg_num)
+{
+	struct dwarf_reg *reg;
+
+	list_for_each_entry(reg, &frame->reg_list, link) {
+		if (reg->number == reg_num)
+			return reg;
+	}
+
+	return NULL;
+}
+
+/**
+ *	dwarf_read_addr - read dwarf data
+ *	@src: source address of data
+ *	@dst: destination address to store the data to
+ *
+ *	Read 'n' bytes from @src, where 'n' is the size of an address on
+ *	the native machine. We return the number of bytes read, which
+ *	should always be 'n'. We also have to be careful when reading
+ *	from @src and writing to @dst, because they can be arbitrarily
+ *	aligned. Return 'n' - the number of bytes read.
+ */
+static inline int dwarf_read_addr(unsigned long *src, unsigned long *dst)
+{
+	u32 val = get_unaligned(src);
+	put_unaligned(val, dst);
+	return sizeof(unsigned long *);
+}
+
+/**
+ *	dwarf_read_uleb128 - read unsigned LEB128 data
+ *	@addr: the address where the ULEB128 data is stored
+ *	@ret: address to store the result
+ *
+ *	Decode an unsigned LEB128 encoded datum. The algorithm is taken
+ *	from Appendix C of the DWARF 3 spec. For information on the
+ *	encodings refer to section "7.6 - Variable Length Data". Return
+ *	the number of bytes read.
+ */
+static inline unsigned long dwarf_read_uleb128(char *addr, unsigned int *ret)
+{
+	unsigned int result;
+	unsigned char byte;
+	int shift, count;
+
+	result = 0;
+	shift = 0;
+	count = 0;
+
+	while (1) {
+		byte = __raw_readb(addr);
+		addr++;
+		count++;
+
+		result |= (byte & 0x7f) << shift;
+		shift += 7;
+
+		if (!(byte & 0x80))
+			break;
+	}
+
+	*ret = result;
+
+	return count;
+}
+
+/**
+ *	dwarf_read_leb128 - read signed LEB128 data
+ *	@addr: the address of the LEB128 encoded data
+ *	@ret: address to store the result
+ *
+ *	Decode signed LEB128 data. The algorithm is taken from Appendix
+ *	C of the DWARF 3 spec. Return the number of bytes read.
+ */
+static inline unsigned long dwarf_read_leb128(char *addr, int *ret)
+{
+	unsigned char byte;
+	int result, shift;
+	int num_bits;
+	int count;
+
+	result = 0;
+	shift = 0;
+	count = 0;
+
+	while (1) {
+		byte = __raw_readb(addr);
+		addr++;
+		result |= (byte & 0x7f) << shift;
+		shift += 7;
+		count++;
+
+		if (!(byte & 0x80))
+			break;
+	}
+
+	/* The number of bits in a signed integer. */
+	num_bits = 8 * sizeof(result);
+
+	if ((shift < num_bits) && (byte & 0x40))
+		result |= (-1 << shift);
+
+	*ret = result;
+
+	return count;
+}
+
+/**
+ *	dwarf_read_encoded_value - return the decoded value at @addr
+ *	@addr: the address of the encoded value
+ *	@val: where to write the decoded value
+ *	@encoding: the encoding with which we can decode @addr
+ *
+ *	GCC emits encoded address in the .eh_frame FDE entries. Decode
+ *	the value at @addr using @encoding. The decoded value is written
+ *	to @val and the number of bytes read is returned.
+ */
+static int dwarf_read_encoded_value(char *addr, unsigned long *val,
+				    char encoding)
+{
+	unsigned long decoded_addr = 0;
+	int count = 0;
+
+	switch (encoding & 0x70) {
+	case DW_EH_PE_absptr:
+		break;
+	case DW_EH_PE_pcrel:
+		decoded_addr = (unsigned long)addr;
+		break;
+	default:
+		pr_debug("encoding=0x%x\n", (encoding & 0x70));
+		UNWINDER_BUG();
+	}
+
+	if ((encoding & 0x07) == 0x00)
+		encoding |= DW_EH_PE_udata4;
+
+	switch (encoding & 0x0f) {
+	case DW_EH_PE_sdata4:
+	case DW_EH_PE_udata4:
+		count += 4;
+		decoded_addr += get_unaligned((u32 *)addr);
+		__raw_writel(decoded_addr, val);
+		break;
+	default:
+		pr_debug("encoding=0x%x\n", encoding);
+		UNWINDER_BUG();
+	}
+
+	return count;
+}
+
+/**
+ *	dwarf_entry_len - return the length of an FDE or CIE
+ *	@addr: the address of the entry
+ *	@len: the length of the entry
+ *
+ *	Read the initial_length field of the entry and store the size of
+ *	the entry in @len. We return the number of bytes read. Return a
+ *	count of 0 on error.
+ */
+static inline int dwarf_entry_len(char *addr, unsigned long *len)
+{
+	u32 initial_len;
+	int count;
+
+	initial_len = get_unaligned((u32 *)addr);
+	count = 4;
+
+	/*
+	 * An initial length field value in the range DW_LEN_EXT_LO -
+	 * DW_LEN_EXT_HI indicates an extension, and should not be
+	 * interpreted as a length. The only extension that we currently
+	 * understand is the use of DWARF64 addresses.
+	 */
+	if (initial_len >= DW_EXT_LO && initial_len <= DW_EXT_HI) {
+		/*
+		 * The 64-bit length field immediately follows the
+		 * compulsory 32-bit length field.
+		 */
+		if (initial_len == DW_EXT_DWARF64) {
+			*len = get_unaligned((u64 *)addr + 4);
+			count = 12;
+		} else {
+			printk(KERN_WARNING "Unknown DWARF extension\n");
+			count = 0;
+		}
+	} else
+		*len = initial_len;
+
+	return count;
+}
+
+/**
+ *	dwarf_lookup_cie - locate the cie
+ *	@cie_ptr: pointer to help with lookup
+ */
+static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr)
+{
+	struct dwarf_cie *cie;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwarf_cie_lock, flags);
+
+	/*
+	 * We've cached the last CIE we looked up because chances are
+	 * that the FDE wants this CIE.
+	 */
+	if (cached_cie && cached_cie->cie_pointer == cie_ptr) {
+		cie = cached_cie;
+		goto out;
+	}
+
+	list_for_each_entry(cie, &dwarf_cie_list, link) {
+		if (cie->cie_pointer == cie_ptr) {
+			cached_cie = cie;
+			break;
+		}
+	}
+
+	/* Couldn't find the entry in the list. */
+	if (&cie->link == &dwarf_cie_list)
+		cie = NULL;
+out:
+	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+	return cie;
+}
+
+/**
+ *	dwarf_lookup_fde - locate the FDE that covers pc
+ *	@pc: the program counter
+ */
+struct dwarf_fde *dwarf_lookup_fde(unsigned long pc)
+{
+	struct dwarf_fde *fde;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dwarf_fde_lock, flags);
+
+	list_for_each_entry(fde, &dwarf_fde_list, link) {
+		unsigned long start, end;
+
+		start = fde->initial_location;
+		end = fde->initial_location + fde->address_range;
+
+		if (pc >= start && pc < end)
+			break;
+	}
+
+	/* Couldn't find the entry in the list. */
+	if (&fde->link == &dwarf_fde_list)
+		fde = NULL;
+
+	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+
+	return fde;
+}
+
+/**
+ *	dwarf_cfa_execute_insns - execute instructions to calculate a CFA
+ *	@insn_start: address of the first instruction
+ *	@insn_end: address of the last instruction
+ *	@cie: the CIE for this function
+ *	@fde: the FDE for this function
+ *	@frame: the instructions calculate the CFA for this frame
+ *	@pc: the program counter of the address we're interested in
+ *
+ *	Execute the Call Frame instruction sequence starting at
+ *	@insn_start and ending at @insn_end. The instructions describe
+ *	how to calculate the Canonical Frame Address of a stackframe.
+ *	Store the results in @frame.
+ */
+static int dwarf_cfa_execute_insns(unsigned char *insn_start,
+				   unsigned char *insn_end,
+				   struct dwarf_cie *cie,
+				   struct dwarf_fde *fde,
+				   struct dwarf_frame *frame,
+				   unsigned long pc)
+{
+	unsigned char insn;
+	unsigned char *current_insn;
+	unsigned int count, delta, reg, expr_len, offset;
+	struct dwarf_reg *regp;
+
+	current_insn = insn_start;
+
+	while (current_insn < insn_end && frame->pc <= pc) {
+		insn = __raw_readb(current_insn++);
+
+		/*
+		 * Firstly, handle the opcodes that embed their operands
+		 * in the instructions.
+		 */
+		switch (DW_CFA_opcode(insn)) {
+		case DW_CFA_advance_loc:
+			delta = DW_CFA_operand(insn);
+			delta *= cie->code_alignment_factor;
+			frame->pc += delta;
+			continue;
+			/* NOTREACHED */
+		case DW_CFA_offset:
+			reg = DW_CFA_operand(insn);
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			offset *= cie->data_alignment_factor;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->addr = offset;
+			regp->flags |= DWARF_REG_OFFSET;
+			continue;
+			/* NOTREACHED */
+		case DW_CFA_restore:
+			reg = DW_CFA_operand(insn);
+			continue;
+			/* NOTREACHED */
+		}
+
+		/*
+		 * Secondly, handle the opcodes that don't embed their
+		 * operands in the instruction.
+		 */
+		switch (insn) {
+		case DW_CFA_nop:
+			continue;
+		case DW_CFA_advance_loc1:
+			delta = *current_insn++;
+			frame->pc += delta * cie->code_alignment_factor;
+			break;
+		case DW_CFA_advance_loc2:
+			delta = get_unaligned((u16 *)current_insn);
+			current_insn += 2;
+			frame->pc += delta * cie->code_alignment_factor;
+			break;
+		case DW_CFA_advance_loc4:
+			delta = get_unaligned((u32 *)current_insn);
+			current_insn += 4;
+			frame->pc += delta * cie->code_alignment_factor;
+			break;
+		case DW_CFA_offset_extended:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			offset *= cie->data_alignment_factor;
+			break;
+		case DW_CFA_restore_extended:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			break;
+		case DW_CFA_undefined:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_UNDEFINED;
+			break;
+		case DW_CFA_def_cfa:
+			count = dwarf_read_uleb128(current_insn,
+						   &frame->cfa_register);
+			current_insn += count;
+			count = dwarf_read_uleb128(current_insn,
+						   &frame->cfa_offset);
+			current_insn += count;
+
+			frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
+			break;
+		case DW_CFA_def_cfa_register:
+			count = dwarf_read_uleb128(current_insn,
+						   &frame->cfa_register);
+			current_insn += count;
+			frame->flags |= DWARF_FRAME_CFA_REG_OFFSET;
+			break;
+		case DW_CFA_def_cfa_offset:
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			frame->cfa_offset = offset;
+			break;
+		case DW_CFA_def_cfa_expression:
+			count = dwarf_read_uleb128(current_insn, &expr_len);
+			current_insn += count;
+
+			frame->cfa_expr = current_insn;
+			frame->cfa_expr_len = expr_len;
+			current_insn += expr_len;
+
+			frame->flags |= DWARF_FRAME_CFA_REG_EXP;
+			break;
+		case DW_CFA_offset_extended_sf:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_leb128(current_insn, &offset);
+			current_insn += count;
+			offset *= cie->data_alignment_factor;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_REG_OFFSET;
+			regp->addr = offset;
+			break;
+		case DW_CFA_val_offset:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_leb128(current_insn, &offset);
+			offset *= cie->data_alignment_factor;
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_VAL_OFFSET;
+			regp->addr = offset;
+			break;
+		case DW_CFA_GNU_args_size:
+			count = dwarf_read_uleb128(current_insn, &offset);
+			current_insn += count;
+			break;
+		case DW_CFA_GNU_negative_offset_extended:
+			count = dwarf_read_uleb128(current_insn, &reg);
+			current_insn += count;
+			count = dwarf_read_uleb128(current_insn, &offset);
+			offset *= cie->data_alignment_factor;
+
+			regp = dwarf_frame_alloc_reg(frame, reg);
+			regp->flags |= DWARF_REG_OFFSET;
+			regp->addr = -offset;
+			break;
+		default:
+			pr_debug("unhandled DWARF instruction 0x%x\n", insn);
+			UNWINDER_BUG();
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ *	dwarf_unwind_stack - recursively unwind the stack
+ *	@pc: address of the function to unwind
+ *	@prev: struct dwarf_frame of the previous stackframe on the callstack
+ *
+ *	Return a struct dwarf_frame representing the most recent frame
+ *	on the callstack. Each of the lower (older) stack frames are
+ *	linked via the "prev" member.
+ */
+struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
+					struct dwarf_frame *prev)
+{
+	struct dwarf_frame *frame;
+	struct dwarf_cie *cie;
+	struct dwarf_fde *fde;
+	struct dwarf_reg *reg;
+	unsigned long addr;
+
+	/*
+	 * If this is the first invocation of this recursive function we
+	 * need get the contents of a physical register to get the CFA
+	 * in order to begin the virtual unwinding of the stack.
+	 *
+	 * NOTE: the return address is guaranteed to be setup by the
+	 * time this function makes its first function call.
+	 */
+	if (!pc && !prev)
+		pc = (unsigned long)current_text_addr();
+
+	frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC);
+	if (!frame) {
+		printk(KERN_ERR "Unable to allocate a dwarf frame\n");
+		UNWINDER_BUG();
+	}
+
+	INIT_LIST_HEAD(&frame->reg_list);
+	frame->flags = 0;
+	frame->prev = prev;
+	frame->return_addr = 0;
+
+	fde = dwarf_lookup_fde(pc);
+	if (!fde) {
+		/*
+		 * This is our normal exit path - the one that stops the
+		 * recursion. There's two reasons why we might exit
+		 * here,
+		 *
+		 *	a) pc has no asscociated DWARF frame info and so
+		 *	we don't know how to unwind this frame. This is
+		 *	usually the case when we're trying to unwind a
+		 *	frame that was called from some assembly code
+		 *	that has no DWARF info, e.g. syscalls.
+		 *
+		 *	b) the DEBUG info for pc is bogus. There's
+		 *	really no way to distinguish this case from the
+		 *	case above, which sucks because we could print a
+		 *	warning here.
+		 */
+		goto bail;
+	}
+
+	cie = dwarf_lookup_cie(fde->cie_pointer);
+
+	frame->pc = fde->initial_location;
+
+	/* CIE initial instructions */
+	dwarf_cfa_execute_insns(cie->initial_instructions,
+				cie->instructions_end, cie, fde,
+				frame, pc);
+
+	/* FDE instructions */
+	dwarf_cfa_execute_insns(fde->instructions, fde->end, cie,
+				fde, frame, pc);
+
+	/* Calculate the CFA */
+	switch (frame->flags) {
+	case DWARF_FRAME_CFA_REG_OFFSET:
+		if (prev) {
+			reg = dwarf_frame_reg(prev, frame->cfa_register);
+			UNWINDER_BUG_ON(!reg);
+			UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET);
+
+			addr = prev->cfa + reg->addr;
+			frame->cfa = __raw_readl(addr);
+
+		} else {
+			/*
+			 * Again, this is the first invocation of this
+			 * recurisve function. We need to physically
+			 * read the contents of a register in order to
+			 * get the Canonical Frame Address for this
+			 * function.
+			 */
+			frame->cfa = dwarf_read_arch_reg(frame->cfa_register);
+		}
+
+		frame->cfa += frame->cfa_offset;
+		break;
+	default:
+		UNWINDER_BUG();
+	}
+
+	reg = dwarf_frame_reg(frame, DWARF_ARCH_RA_REG);
+
+	/*
+	 * If we haven't seen the return address register or the return
+	 * address column is undefined then we must assume that this is
+	 * the end of the callstack.
+	 */
+	if (!reg || reg->flags == DWARF_UNDEFINED)
+		goto bail;
+
+	UNWINDER_BUG_ON(reg->flags != DWARF_REG_OFFSET);
+
+	addr = frame->cfa + reg->addr;
+	frame->return_addr = __raw_readl(addr);
+
+	return frame;
+
+bail:
+	dwarf_frame_free_regs(frame);
+	mempool_free(frame, dwarf_frame_pool);
+	return NULL;
+}
+
+static int dwarf_parse_cie(void *entry, void *p, unsigned long len,
+			   unsigned char *end)
+{
+	struct dwarf_cie *cie;
+	unsigned long flags;
+	int count;
+
+	cie = kzalloc(sizeof(*cie), GFP_KERNEL);
+	if (!cie)
+		return -ENOMEM;
+
+	cie->length = len;
+
+	/*
+	 * Record the offset into the .eh_frame section
+	 * for this CIE. It allows this CIE to be
+	 * quickly and easily looked up from the
+	 * corresponding FDE.
+	 */
+	cie->cie_pointer = (unsigned long)entry;
+
+	cie->version = *(char *)p++;
+	UNWINDER_BUG_ON(cie->version != 1);
+
+	cie->augmentation = p;
+	p += strlen(cie->augmentation) + 1;
+
+	count = dwarf_read_uleb128(p, &cie->code_alignment_factor);
+	p += count;
+
+	count = dwarf_read_leb128(p, &cie->data_alignment_factor);
+	p += count;
+
+	/*
+	 * Which column in the rule table contains the
+	 * return address?
+	 */
+	if (cie->version == 1) {
+		cie->return_address_reg = __raw_readb(p);
+		p++;
+	} else {
+		count = dwarf_read_uleb128(p, &cie->return_address_reg);
+		p += count;
+	}
+
+	if (cie->augmentation[0] == 'z') {
+		unsigned int length, count;
+		cie->flags |= DWARF_CIE_Z_AUGMENTATION;
+
+		count = dwarf_read_uleb128(p, &length);
+		p += count;
+
+		UNWINDER_BUG_ON((unsigned char *)p > end);
+
+		cie->initial_instructions = p + length;
+		cie->augmentation++;
+	}
+
+	while (*cie->augmentation) {
+		/*
+		 * "L" indicates a byte showing how the
+		 * LSDA pointer is encoded. Skip it.
+		 */
+		if (*cie->augmentation == 'L') {
+			p++;
+			cie->augmentation++;
+		} else if (*cie->augmentation == 'R') {
+			/*
+			 * "R" indicates a byte showing
+			 * how FDE addresses are
+			 * encoded.
+			 */
+			cie->encoding = *(char *)p++;
+			cie->augmentation++;
+		} else if (*cie->augmentation == 'P') {
+			/*
+			 * "R" indicates a personality
+			 * routine in the CIE
+			 * augmentation.
+			 */
+			UNWINDER_BUG();
+		} else if (*cie->augmentation == 'S') {
+			UNWINDER_BUG();
+		} else {
+			/*
+			 * Unknown augmentation. Assume
+			 * 'z' augmentation.
+			 */
+			p = cie->initial_instructions;
+			UNWINDER_BUG_ON(!p);
+			break;
+		}
+	}
+
+	cie->initial_instructions = p;
+	cie->instructions_end = end;
+
+	/* Add to list */
+	spin_lock_irqsave(&dwarf_cie_lock, flags);
+	list_add_tail(&cie->link, &dwarf_cie_list);
+	spin_unlock_irqrestore(&dwarf_cie_lock, flags);
+
+	return 0;
+}
+
+static int dwarf_parse_fde(void *entry, u32 entry_type,
+			   void *start, unsigned long len,
+			   unsigned char *end)
+{
+	struct dwarf_fde *fde;
+	struct dwarf_cie *cie;
+	unsigned long flags;
+	int count;
+	void *p = start;
+
+	fde = kzalloc(sizeof(*fde), GFP_KERNEL);
+	if (!fde)
+		return -ENOMEM;
+
+	fde->length = len;
+
+	/*
+	 * In a .eh_frame section the CIE pointer is the
+	 * delta between the address within the FDE
+	 */
+	fde->cie_pointer = (unsigned long)(p - entry_type - 4);
+
+	cie = dwarf_lookup_cie(fde->cie_pointer);
+	fde->cie = cie;
+
+	if (cie->encoding)
+		count = dwarf_read_encoded_value(p, &fde->initial_location,
+						 cie->encoding);
+	else
+		count = dwarf_read_addr(p, &fde->initial_location);
+
+	p += count;
+
+	if (cie->encoding)
+		count = dwarf_read_encoded_value(p, &fde->address_range,
+						 cie->encoding & 0x0f);
+	else
+		count = dwarf_read_addr(p, &fde->address_range);
+
+	p += count;
+
+	if (fde->cie->flags & DWARF_CIE_Z_AUGMENTATION) {
+		unsigned int length;
+		count = dwarf_read_uleb128(p, &length);
+		p += count + length;
+	}
+
+	/* Call frame instructions. */
+	fde->instructions = p;
+	fde->end = end;
+
+	/* Add to list. */
+	spin_lock_irqsave(&dwarf_fde_lock, flags);
+	list_add_tail(&fde->link, &dwarf_fde_list);
+	spin_unlock_irqrestore(&dwarf_fde_lock, flags);
+
+	return 0;
+}
+
+static void dwarf_unwinder_dump(struct task_struct *task,
+				struct pt_regs *regs,
+				unsigned long *sp,
+				const struct stacktrace_ops *ops,
+				void *data)
+{
+	struct dwarf_frame *frame, *_frame;
+	unsigned long return_addr;
+
+	_frame = NULL;
+	return_addr = 0;
+
+	while (1) {
+		frame = dwarf_unwind_stack(return_addr, _frame);
+
+		if (_frame) {
+			dwarf_frame_free_regs(_frame);
+			mempool_free(_frame, dwarf_frame_pool);
+		}
+
+		_frame = frame;
+
+		if (!frame || !frame->return_addr)
+			break;
+
+		return_addr = frame->return_addr;
+		ops->address(data, return_addr, 1);
+	}
+}
+
+static struct unwinder dwarf_unwinder = {
+	.name = "dwarf-unwinder",
+	.dump = dwarf_unwinder_dump,
+	.rating = 150,
+};
+
+static void dwarf_unwinder_cleanup(void)
+{
+	struct dwarf_cie *cie;
+	struct dwarf_fde *fde;
+
+	/*
+	 * Deallocate all the memory allocated for the DWARF unwinder.
+	 * Traverse all the FDE/CIE lists and remove and free all the
+	 * memory associated with those data structures.
+	 */
+	list_for_each_entry(cie, &dwarf_cie_list, link)
+		kfree(cie);
+
+	list_for_each_entry(fde, &dwarf_fde_list, link)
+		kfree(fde);
+
+	kmem_cache_destroy(dwarf_reg_cachep);
+	kmem_cache_destroy(dwarf_frame_cachep);
+}
+
+/**
+ *	dwarf_unwinder_init - initialise the dwarf unwinder
+ *
+ *	Build the data structures describing the .dwarf_frame section to
+ *	make it easier to lookup CIE and FDE entries. Because the
+ *	.eh_frame section is packed as tightly as possible it is not
+ *	easy to lookup the FDE for a given PC, so we build a list of FDE
+ *	and CIE entries that make it easier.
+ */
+static int __init dwarf_unwinder_init(void)
+{
+	u32 entry_type;
+	void *p, *entry;
+	int count, err = 0;
+	unsigned long len;
+	unsigned int c_entries, f_entries;
+	unsigned char *end;
+	INIT_LIST_HEAD(&dwarf_cie_list);
+	INIT_LIST_HEAD(&dwarf_fde_list);
+
+	c_entries = 0;
+	f_entries = 0;
+	entry = &__start_eh_frame;
+
+	dwarf_frame_cachep = kmem_cache_create("dwarf_frames",
+			sizeof(struct dwarf_frame), 0,
+			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
+
+	dwarf_reg_cachep = kmem_cache_create("dwarf_regs",
+			sizeof(struct dwarf_reg), 0,
+			SLAB_PANIC | SLAB_HWCACHE_ALIGN | SLAB_NOTRACK, NULL);
+
+	dwarf_frame_pool = mempool_create(DWARF_FRAME_MIN_REQ,
+					  mempool_alloc_slab,
+					  mempool_free_slab,
+					  dwarf_frame_cachep);
+
+	dwarf_reg_pool = mempool_create(DWARF_REG_MIN_REQ,
+					 mempool_alloc_slab,
+					 mempool_free_slab,
+					 dwarf_reg_cachep);
+
+	while ((char *)entry < __stop_eh_frame) {
+		p = entry;
+
+		count = dwarf_entry_len(p, &len);
+		if (count == 0) {
+			/*
+			 * We read a bogus length field value. There is
+			 * nothing we can do here apart from disabling
+			 * the DWARF unwinder. We can't even skip this
+			 * entry and move to the next one because 'len'
+			 * tells us where our next entry is.
+			 */
+			goto out;
+		} else
+			p += count;
+
+		/* initial length does not include itself */
+		end = p + len;
+
+		entry_type = get_unaligned((u32 *)p);
+		p += 4;
+
+		if (entry_type == DW_EH_FRAME_CIE) {
+			err = dwarf_parse_cie(entry, p, len, end);
+			if (err < 0)
+				goto out;
+			else
+				c_entries++;
+		} else {
+			err = dwarf_parse_fde(entry, entry_type, p, len, end);
+			if (err < 0)
+				goto out;
+			else
+				f_entries++;
+		}
+
+		entry = (char *)entry + len + 4;
+	}
+
+	printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n",
+	       c_entries, f_entries);
+
+	err = unwinder_register(&dwarf_unwinder);
+	if (err)
+		goto out;
+
+	return 0;
+
+out:
+	printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err);
+	dwarf_unwinder_cleanup();
+	return -EINVAL;
+}
+early_initcall(dwarf_unwinder_init);
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index a952dcf..81a4614 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -134,7 +134,7 @@ static void scif_sercon_init(char *s)
 	sci_out(&scif_port, SCFCR, 0x0030);	/* TTRG=b'11 */
 	sci_out(&scif_port, SCSCR, 0x0030);	/* TE, RE */
 }
-#elif defined(CONFIG_CPU_SH4)
+#elif defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
 #define DEFAULT_BAUD 115200
 /*
  * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4
@@ -220,8 +220,7 @@ static int __init setup_early_printk(char *buf)
 		early_console = &scif_console;
 
 #if !defined(CONFIG_SH_STANDARD_BIOS)
-#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SH3)
 		scif_sercon_init(buf + 6);
 #endif
 #endif
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index d62359c..68d9223 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -43,9 +43,10 @@
  *	syscall #
  *
  */
+#include <asm/dwarf.h>
 
 #if defined(CONFIG_PREEMPT)
-#  define preempt_stop()	cli
+#  define preempt_stop()	cli ; TRACE_IRQS_OFF
 #else
 #  define preempt_stop()
 #  define resume_kernel		__restore_all
@@ -55,11 +56,7 @@
 	.align	2
 ENTRY(exception_error)
 	!
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	2f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_ON
 	sti
 	mov.l	1f, r0
 	jmp	@r0
@@ -67,18 +64,15 @@ ENTRY(exception_error)
 
 	.align	2
 1:	.long	do_exception_error
-#ifdef CONFIG_TRACE_IRQFLAGS
-2:	.long	trace_hardirqs_on
-#endif
 
 	.align	2
 ret_from_exception:
+	CFI_STARTPROC simple
+	CFI_DEF_CFA r14, 0
+	CFI_REL_OFFSET 17, 64
+	CFI_REL_OFFSET 15, 0
+	CFI_REL_OFFSET 14, 56
 	preempt_stop()
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	4f, r0
-	jsr	@r0
-	 nop
-#endif
 ENTRY(ret_from_irq)
 	!
 	mov	#OFF_SR, r0
@@ -93,6 +87,7 @@ ENTRY(ret_from_irq)
 	 nop
 ENTRY(resume_kernel)
 	cli
+	TRACE_IRQS_OFF
 	mov.l	@(TI_PRE_COUNT,r8), r0	! current_thread_info->preempt_count
 	tst	r0, r0
 	bf	noresched
@@ -103,8 +98,9 @@ need_resched:
 
 	mov	#OFF_SR, r0
 	mov.l	@(r0,r15), r0		! get status register
-	and	#0xf0, r0		! interrupts off (exception path)?
-	cmp/eq	#0xf0, r0
+	shlr	r0
+	and	#(0xf0>>1), r0		! interrupts off (exception path)?
+	cmp/eq	#(0xf0>>1), r0
 	bt	noresched
 	mov.l	3f, r0
 	jsr	@r0			! call preempt_schedule_irq
@@ -125,13 +121,9 @@ noresched:
 ENTRY(resume_userspace)
 	! r8: current_thread_info
 	cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_OfF
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
-	tst	#_TIF_WORK_MASK, r0
+	tst	#(_TIF_WORK_MASK & 0xff), r0
 	bt/s	__restore_all
 	 tst	#_TIF_NEED_RESCHED, r0
 
@@ -156,14 +148,10 @@ work_resched:
 	jsr	@r1				! schedule
 	 nop
 	cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_OFF
 	!
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
-	tst	#_TIF_WORK_MASK, r0
+	tst	#(_TIF_WORK_MASK & 0xff), r0
 	bt	__restore_all
 	bra	work_pending
 	 tst	#_TIF_NEED_RESCHED, r0
@@ -172,23 +160,15 @@ work_resched:
 1:	.long	schedule
 2:	.long	do_notify_resume
 3:	.long	resume_userspace
-#ifdef CONFIG_TRACE_IRQFLAGS
-4:	.long	trace_hardirqs_on
-5:	.long	trace_hardirqs_off
-#endif
 
 	.align	2
 syscall_exit_work:
 	! r0: current_thread_info->flags
 	! r8: current_thread_info
-	tst	#_TIF_WORK_SYSCALL_MASK, r0
+	tst	#(_TIF_WORK_SYSCALL_MASK & 0xff), r0
 	bt/s	work_pending
 	 tst	#_TIF_NEED_RESCHED, r0
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_ON
 	sti
 	mov	r15, r4
 	mov.l	8f, r0			! do_syscall_trace_leave
@@ -226,12 +206,25 @@ syscall_trace_entry:
 	 mov.l	r0, @(OFF_R0,r15)	! Return value
 
 __restore_all:
-	mov.l	1f, r0
+	mov	#OFF_SR, r0
+	mov.l	@(r0,r15), r0	! get status register
+
+	shlr2	r0
+	and	#0x3c, r0
+	cmp/eq	#0x3c, r0
+	bt	1f
+	TRACE_IRQS_ON
+	bra	2f
+	 nop
+1:
+	TRACE_IRQS_OFF
+2:
+	mov.l	3f, r0
 	jmp	@r0
 	 nop
 
 	.align	2
-1:	.long	restore_all
+3:	.long	restore_all
 
 	.align	2
 syscall_badsys:			! Bad syscall number
@@ -259,6 +252,7 @@ debug_trap:
 	 nop
 	bra	__restore_all
 	 nop
+	CFI_ENDPROC
 
 	.align	2
 1:	.long	debug_trap_table
@@ -304,6 +298,7 @@ ret_from_fork:
  * system calls and debug traps through their respective jump tables.
  */
 ENTRY(system_call)
+	setup_frame_reg
 #if !defined(CONFIG_CPU_SH2)
 	mov.l	1f, r9
 	mov.l	@r9, r8		! Read from TRA (Trap Address) Register
@@ -321,18 +316,18 @@ ENTRY(system_call)
 	bt/s	debug_trap		! it's a debug trap..
 	 nop
 
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	5f, r10
-	jsr	@r10
-	 nop
-#endif
+	TRACE_IRQS_ON
 	sti
 
 	!
 	get_current_thread_info r8, r10
 	mov.l	@(TI_FLAGS,r8), r8
-	mov	#_TIF_WORK_SYSCALL_MASK, r10
+	mov	#(_TIF_WORK_SYSCALL_MASK & 0xff), r10
+	mov	#(_TIF_WORK_SYSCALL_MASK >> 8), r9
 	tst	r10, r8
+	shll8	r9
+	bf	syscall_trace_entry
+	tst	r9, r8
 	bf	syscall_trace_entry
 	!
 	mov.l	2f, r8			! Number of syscalls
@@ -351,15 +346,15 @@ syscall_call:
 	!
 syscall_exit:
 	cli
-#ifdef CONFIG_TRACE_IRQFLAGS
-	mov.l	6f, r0
-	jsr	@r0
-	 nop
-#endif
+	TRACE_IRQS_OFF
 	!
 	get_current_thread_info r8, r0
 	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
-	tst	#_TIF_ALLWORK_MASK, r0
+	tst	#(_TIF_ALLWORK_MASK & 0xff), r0
+	mov	#(_TIF_ALLWORK_MASK >> 8), r1
+	bf	syscall_exit_work
+	shlr8	r0
+	tst	r0, r1
 	bf	syscall_exit_work
 	bra	__restore_all
 	 nop
@@ -369,9 +364,5 @@ syscall_exit:
 #endif
 2:	.long	NR_syscalls
 3:	.long	sys_call_table
-#ifdef CONFIG_TRACE_IRQFLAGS
-5:	.long	trace_hardirqs_on
-6:	.long	trace_hardirqs_off
-#endif
 7:	.long	do_syscall_trace_enter
 8:	.long	do_syscall_trace_leave
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index 066f37d..a3dcc6d 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -16,9 +16,13 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/kernel.h>
 #include <asm/ftrace.h>
 #include <asm/cacheflush.h>
+#include <asm/unistd.h>
+#include <trace/syscall.h>
 
+#ifdef CONFIG_DYNAMIC_FTRACE
 static unsigned char ftrace_replaced_code[MCOUNT_INSN_SIZE];
 
 static unsigned char ftrace_nop[4];
@@ -131,3 +135,187 @@ int __init ftrace_dyn_arch_init(void *data)
 
 	return 0;
 }
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+static int ftrace_mod(unsigned long ip, unsigned long old_addr,
+		      unsigned long new_addr)
+{
+	unsigned char code[MCOUNT_INSN_SIZE];
+
+	if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE))
+		return -EFAULT;
+
+	if (old_addr != __raw_readl((unsigned long *)code))
+		return -EINVAL;
+
+	__raw_writel(new_addr, ip);
+	return 0;
+}
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+	unsigned long ip, old_addr, new_addr;
+
+	ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
+	old_addr = (unsigned long)(&skip_trace);
+	new_addr = (unsigned long)(&ftrace_graph_caller);
+
+	return ftrace_mod(ip, old_addr, new_addr);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+	unsigned long ip, old_addr, new_addr;
+
+	ip = (unsigned long)(&ftrace_graph_call) + GRAPH_INSN_OFFSET;
+	old_addr = (unsigned long)(&ftrace_graph_caller);
+	new_addr = (unsigned long)(&skip_trace);
+
+	return ftrace_mod(ip, old_addr, new_addr);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in the current thread info.
+ *
+ * This is the main routine for the function graph tracer. The function
+ * graph tracer essentially works like this:
+ *
+ * parent is the stack address containing self_addr's return address.
+ * We pull the real return address out of parent and store it in
+ * current's ret_stack. Then, we replace the return address on the stack
+ * with the address of return_to_handler. self_addr is the function that
+ * called mcount.
+ *
+ * When self_addr returns, it will jump to return_to_handler which calls
+ * ftrace_return_to_handler. ftrace_return_to_handler will pull the real
+ * return address off of current's ret_stack and jump to it.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
+{
+	unsigned long old;
+	int faulted, err;
+	struct ftrace_graph_ent trace;
+	unsigned long return_hooker = (unsigned long)&return_to_handler;
+
+	if (unlikely(atomic_read(&current->tracing_graph_pause)))
+		return;
+
+	/*
+	 * Protect against fault, even if it shouldn't
+	 * happen. This tool is too much intrusive to
+	 * ignore such a protection.
+	 */
+	__asm__ __volatile__(
+		"1:						\n\t"
+		"mov.l		@%2, %0				\n\t"
+		"2:						\n\t"
+		"mov.l		%3, @%2				\n\t"
+		"mov		#0, %1				\n\t"
+		"3:						\n\t"
+		".section .fixup, \"ax\"			\n\t"
+		"4:						\n\t"
+		"mov.l		5f, %0				\n\t"
+		"jmp		@%0				\n\t"
+		" mov		#1, %1				\n\t"
+		".balign 4					\n\t"
+		"5:	.long 3b				\n\t"
+		".previous					\n\t"
+		".section __ex_table,\"a\"			\n\t"
+		".long 1b, 4b					\n\t"
+		".long 2b, 4b					\n\t"
+		".previous					\n\t"
+		: "=&r" (old), "=r" (faulted)
+		: "r" (parent), "r" (return_hooker)
+	);
+
+	if (unlikely(faulted)) {
+		ftrace_graph_stop();
+		WARN_ON(1);
+		return;
+	}
+
+	err = ftrace_push_return_trace(old, self_addr, &trace.depth, 0);
+	if (err == -EBUSY) {
+		__raw_writel(old, parent);
+		return;
+	}
+
+	trace.func = self_addr;
+
+	/* Only trace if the calling function expects to */
+	if (!ftrace_graph_entry(&trace)) {
+		current->curr_ret_stack--;
+		__raw_writel(old, parent);
+	}
+}
+#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 /* CONFIG_FTRACE_SYSCALLS */
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index 4f85fff..4770c24 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -1,12 +1,9 @@
 /*
- * linux/arch/sh/kernel/io.c
+ * arch/sh/kernel/io.c - Machine independent I/O functions.
  *
- * Copyright (C) 2000  Stuart Menefy
+ * Copyright (C) 2000 - 2009  Stuart Menefy
  * Copyright (C) 2005  Paul Mundt
  *
- * Provide real functions which expand to whatever the header file defined.
- * Also definitions of machine independent IO functions.
- *
  * 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.
@@ -18,33 +15,87 @@
 
 /*
  * Copy data from IO memory space to "real" memory space.
- * This needs to be optimized.
  */
 void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned long count)
 {
-	unsigned char *p = to;
-        while (count) {
-                count--;
-                *p = readb(from);
-                p++;
-                from++;
-        }
+	/*
+	 * Would it be worthwhile doing byte and long transfers first
+	 * to try and get aligned?
+	 */
+#ifdef CONFIG_CPU_SH4
+	if ((count >= 0x20) &&
+	     (((u32)to & 0x1f) == 0) && (((u32)from & 0x3) == 0)) {
+		int tmp2, tmp3, tmp4, tmp5, tmp6;
+
+		__asm__ __volatile__(
+			"1:			\n\t"
+			"mov.l	@%7+, r0	\n\t"
+			"mov.l	@%7+, %2	\n\t"
+			"movca.l r0, @%0	\n\t"
+			"mov.l	@%7+, %3	\n\t"
+			"mov.l	@%7+, %4	\n\t"
+			"mov.l	@%7+, %5	\n\t"
+			"mov.l	@%7+, %6	\n\t"
+			"mov.l	@%7+, r7	\n\t"
+			"mov.l	@%7+, r0	\n\t"
+			"mov.l	%2, @(0x04,%0)	\n\t"
+			"mov	#0x20, %2	\n\t"
+			"mov.l	%3, @(0x08,%0)	\n\t"
+			"sub	%2, %1		\n\t"
+			"mov.l	%4, @(0x0c,%0)	\n\t"
+			"cmp/hi	%1, %2		! T if 32 > count	\n\t"
+			"mov.l	%5, @(0x10,%0)	\n\t"
+			"mov.l	%6, @(0x14,%0)	\n\t"
+			"mov.l	r7, @(0x18,%0)	\n\t"
+			"mov.l	r0, @(0x1c,%0)	\n\t"
+			"bf.s	1b		\n\t"
+			" add	#0x20, %0	\n\t"
+			: "=&r" (to), "=&r" (count),
+			  "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4),
+			  "=&r" (tmp5), "=&r" (tmp6), "=&r" (from)
+			: "7"(from), "0" (to), "1" (count)
+			: "r0", "r7", "t", "memory");
+	}
+#endif
+
+	if ((((u32)to | (u32)from) & 0x3) == 0) {
+		for (; count > 3; count -= 4) {
+			*(u32 *)to = *(volatile u32 *)from;
+			to += 4;
+			from += 4;
+		}
+	}
+
+	for (; count > 0; count--) {
+		*(u8 *)to = *(volatile u8 *)from;
+		to++;
+		from++;
+	}
+
+	mb();
 }
 EXPORT_SYMBOL(memcpy_fromio);
 
 /*
  * Copy data from "real" memory space to IO memory space.
- * This needs to be optimized.
  */
 void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count)
 {
-	const unsigned char *p = from;
-        while (count) {
-                count--;
-                writeb(*p, to);
-                p++;
-                to++;
-        }
+	if ((((u32)to | (u32)from) & 0x3) == 0) {
+		for ( ; count > 3; count -= 4) {
+			*(volatile u32 *)to = *(u32 *)from;
+			to += 4;
+			from += 4;
+		}
+	}
+
+	for (; count > 0; count--) {
+		*(volatile u8 *)to = *(u8 *)from;
+		to++;
+		from++;
+	}
+
+	mb();
 }
 EXPORT_SYMBOL(memcpy_toio);
 
@@ -62,6 +113,8 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count)
 }
 EXPORT_SYMBOL(memset_io);
 
+#ifndef CONFIG_GENERIC_IOMAP
+
 void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
 	void __iomem *ret;
@@ -79,3 +132,5 @@ void ioport_unmap(void __iomem *addr)
 	sh_mv.mv_ioport_unmap(addr);
 }
 EXPORT_SYMBOL(ioport_unmap);
+
+#endif /* CONFIG_GENERIC_IOMAP */
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 5a7f554..4ff5072 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -73,35 +73,19 @@ u32 generic_inl_p(unsigned long port)
 
 void generic_insb(unsigned long port, void *dst, unsigned long count)
 {
-	volatile u8 *port_addr;
-	u8 *buf = dst;
-
-	port_addr = (volatile u8 __force *)__ioport_map(port, 1);
-	while (count--)
-		*buf++ = *port_addr;
+	__raw_readsb(__ioport_map(port, 1), dst, count);
+	dummy_read();
 }
 
 void generic_insw(unsigned long port, void *dst, unsigned long count)
 {
-	volatile u16 *port_addr;
-	u16 *buf = dst;
-
-	port_addr = (volatile u16 __force *)__ioport_map(port, 2);
-	while (count--)
-		*buf++ = *port_addr;
-
+	__raw_readsw(__ioport_map(port, 2), dst, count);
 	dummy_read();
 }
 
 void generic_insl(unsigned long port, void *dst, unsigned long count)
 {
-	volatile u32 *port_addr;
-	u32 *buf = dst;
-
-	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
-	while (count--)
-		*buf++ = *port_addr;
-
+	__raw_readsl(__ioport_map(port, 4), dst, count);
 	dummy_read();
 }
 
@@ -145,37 +129,19 @@ void generic_outl_p(u32 b, unsigned long port)
  */
 void generic_outsb(unsigned long port, const void *src, unsigned long count)
 {
-	volatile u8 *port_addr;
-	const u8 *buf = src;
-
-	port_addr = (volatile u8 __force *)__ioport_map(port, 1);
-
-	while (count--)
-		*port_addr = *buf++;
+	__raw_writesb(__ioport_map(port, 1), src, count);
+	dummy_read();
 }
 
 void generic_outsw(unsigned long port, const void *src, unsigned long count)
 {
-	volatile u16 *port_addr;
-	const u16 *buf = src;
-
-	port_addr = (volatile u16 __force *)__ioport_map(port, 2);
-
-	while (count--)
-		*port_addr = *buf++;
-
+	__raw_writesw(__ioport_map(port, 2), src, count);
 	dummy_read();
 }
 
 void generic_outsl(unsigned long port, const void *src, unsigned long count)
 {
-	volatile u32 *port_addr;
-	const u32 *buf = src;
-
-	port_addr = (volatile u32 __force *)__ioport_map(port, 4);
-	while (count--)
-		*port_addr = *buf++;
-
+	__raw_writesl(__ioport_map(port, 4), src, count);
 	dummy_read();
 }
 
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 77dfecb..69be603 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -112,14 +112,15 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
 	struct trapped_io *tiop;
 	struct resource *res;
 	int k, len;
+	unsigned long flags;
 
-	spin_lock_irq(&trapped_lock);
+	spin_lock_irqsave(&trapped_lock, flags);
 	list_for_each_entry(tiop, list, list) {
 		voffs = 0;
 		for (k = 0; k < tiop->num_resources; k++) {
 			res = tiop->resource + k;
 			if (res->start == offset) {
-				spin_unlock_irq(&trapped_lock);
+				spin_unlock_irqrestore(&trapped_lock, flags);
 				return tiop->virt_base + voffs;
 			}
 
@@ -127,7 +128,7 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
 			voffs += roundup(len, PAGE_SIZE);
 		}
 	}
-	spin_unlock_irq(&trapped_lock);
+	spin_unlock_irqrestore(&trapped_lock, flags);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(match_trapped_io_handler);
@@ -283,7 +284,8 @@ int handle_trapped_io(struct pt_regs *regs, unsigned long address)
 		return 0;
 	}
 
-	tmp = handle_unaligned_access(instruction, regs, &trapped_io_access);
+	tmp = handle_unaligned_access(instruction, regs,
+				      &trapped_io_access, 1);
 	set_fs(oldfs);
 	return tmp == 0;
 }
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 3d09062..60f8af4 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -114,24 +114,7 @@ asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs)
 #endif
 
 	irq_enter();
-
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
-	/* Debugging check for stack overflow: is there less than 1KB free? */
-	{
-		long sp;
-
-		__asm__ __volatile__ ("and r15, %0" :
-					"=r" (sp) : "0" (THREAD_SIZE - 1));
-
-		if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
-			printk("do_IRQ: stack overflow: %ld\n",
-			       sp - sizeof(struct thread_info));
-			dump_stack();
-		}
-	}
-#endif
-
-	irq = irq_demux(intc_evt2irq(irq));
+	irq = irq_demux(irq);
 
 #ifdef CONFIG_IRQSTACKS
 	curctx = (union irq_ctx *)current_thread_info();
diff --git a/arch/sh/kernel/kgdb.c b/arch/sh/kernel/kgdb.c
index 305aad7..3e532d0 100644
--- a/arch/sh/kernel/kgdb.c
+++ b/arch/sh/kernel/kgdb.c
@@ -15,8 +15,6 @@
 #include <linux/io.h>
 #include <asm/cacheflush.h>
 
-char in_nmi = 0;	/* Set during NMI to prevent re-entry */
-
 /* Macros for single step instruction identification */
 #define OPCODE_BT(op)		(((op) & 0xff00) == 0x8900)
 #define OPCODE_BF(op)		(((op) & 0xff00) == 0x8b00)
@@ -195,8 +193,6 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 	regs->gbr = gdb_regs[GDB_GBR];
 	regs->mach = gdb_regs[GDB_MACH];
 	regs->macl = gdb_regs[GDB_MACL];
-
-	__asm__ __volatile__ ("ldc %0, vbr" : : "r" (gdb_regs[GDB_VBR]));
 }
 
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c
index 96e8eae..0b04e7d 100644
--- a/arch/sh/kernel/localtimer.c
+++ b/arch/sh/kernel/localtimer.c
@@ -22,6 +22,7 @@
 #include <linux/jiffies.h>
 #include <linux/percpu.h>
 #include <linux/clockchips.h>
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 
 static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
@@ -33,7 +34,9 @@ void local_timer_interrupt(void)
 {
 	struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
 
+	irq_enter();
 	clk->event_handler(clk);
+	irq_exit();
 }
 
 static void dummy_timer_set_mode(enum clock_event_mode mode,
@@ -46,8 +49,10 @@ void __cpuinit local_timer_setup(unsigned int cpu)
 	struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
 
 	clk->name		= "dummy_timer";
-	clk->features		= CLOCK_EVT_FEAT_DUMMY;
-	clk->rating		= 200;
+	clk->features		= CLOCK_EVT_FEAT_ONESHOT |
+				  CLOCK_EVT_FEAT_PERIODIC |
+				  CLOCK_EVT_FEAT_DUMMY;
+	clk->rating		= 400;
 	clk->mult		= 1;
 	clk->set_mode		= dummy_timer_set_mode;
 	clk->broadcast		= smp_timer_broadcast;
diff --git a/arch/sh/kernel/nmi_debug.c b/arch/sh/kernel/nmi_debug.c
new file mode 100644
index 0000000..ff0abbd
--- /dev/null
+++ b/arch/sh/kernel/nmi_debug.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/kdebug.h>
+#include <linux/notifier.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+
+enum nmi_action {
+	NMI_SHOW_STATE	= 1 << 0,
+	NMI_SHOW_REGS	= 1 << 1,
+	NMI_DIE		= 1 << 2,
+	NMI_DEBOUNCE	= 1 << 3,
+};
+
+static unsigned long nmi_actions;
+
+static int nmi_debug_notify(struct notifier_block *self,
+		unsigned long val, void *data)
+{
+	struct die_args *args = data;
+
+	if (likely(val != DIE_NMI))
+		return NOTIFY_DONE;
+
+	if (nmi_actions & NMI_SHOW_STATE)
+		show_state();
+	if (nmi_actions & NMI_SHOW_REGS)
+		show_regs(args->regs);
+	if (nmi_actions & NMI_DEBOUNCE)
+		mdelay(10);
+	if (nmi_actions & NMI_DIE)
+		return NOTIFY_BAD;
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block nmi_debug_nb = {
+	.notifier_call = nmi_debug_notify,
+};
+
+static int __init nmi_debug_setup(char *str)
+{
+	char *p, *sep;
+
+	register_die_notifier(&nmi_debug_nb);
+
+	if (*str != '=')
+		return 0;
+
+	for (p = str + 1; *p; p = sep + 1) {
+		sep = strchr(p, ',');
+		if (sep)
+			*sep = 0;
+		if (strcmp(p, "state") == 0)
+			nmi_actions |= NMI_SHOW_STATE;
+		else if (strcmp(p, "regs") == 0)
+			nmi_actions |= NMI_SHOW_REGS;
+		else if (strcmp(p, "debounce") == 0)
+			nmi_actions |= NMI_DEBOUNCE;
+		else if (strcmp(p, "die") == 0)
+			nmi_actions |= NMI_DIE;
+		else
+			printk(KERN_WARNING "NMI: Unrecognized action `%s'\n",
+				p);
+		if (!sep)
+			break;
+	}
+
+	return 0;
+}
+__setup("nmi_debug", nmi_debug_setup);
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 92d7740..0673c47 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -23,6 +23,7 @@
 #include <linux/tick.h>
 #include <linux/reboot.h>
 #include <linux/fs.h>
+#include <linux/ftrace.h>
 #include <linux/preempt.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -31,15 +32,35 @@
 #include <asm/ubc.h>
 #include <asm/fpu.h>
 #include <asm/syscalls.h>
+#include <asm/watchdog.h>
 
 int ubc_usercnt = 0;
 
+#ifdef CONFIG_32BIT
+static void watchdog_trigger_immediate(void)
+{
+	sh_wdt_write_cnt(0xFF);
+	sh_wdt_write_csr(0xC2);
+}
+
+void machine_restart(char * __unused)
+{
+	local_irq_disable();
+
+	/* Use watchdog timer to trigger reset */
+	watchdog_trigger_immediate();
+
+	while (1)
+		cpu_sleep();
+}
+#else
 void machine_restart(char * __unused)
 {
 	/* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
 	asm volatile("ldc %0, sr\n\t"
 		     "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
 }
+#endif
 
 void machine_halt(void)
 {
@@ -264,8 +285,8 @@ static void ubc_set_tracing(int asid, unsigned long pc)
  *	switch_to(x,y) should switch tasks from x to y.
  *
  */
-struct task_struct *__switch_to(struct task_struct *prev,
-				struct task_struct *next)
+__notrace_funcgraph struct task_struct *
+__switch_to(struct task_struct *prev, struct task_struct *next)
 {
 #if defined(CONFIG_SH_FPU)
 	unlazy_fpu(prev, task_pt_regs(prev));
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 24de742..1192398 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -425,7 +425,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 		struct task_struct *p, struct pt_regs *regs)
 {
 	struct pt_regs *childregs;
-	unsigned long long se;			/* Sign extension */
 
 #ifdef CONFIG_SH_FPU
 	if(last_task_used_math == current) {
@@ -441,11 +440,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 
 	*childregs = *regs;
 
+	/*
+	 * Sign extend the edited stack.
+	 * Note that thread.pc and thread.pc will stay
+	 * 32-bit wide and context switch must take care
+	 * of NEFF sign extension.
+	 */
 	if (user_mode(regs)) {
-		childregs->regs[15] = usp;
+		childregs->regs[15] = neff_sign_extend(usp);
 		p->thread.uregs = childregs;
 	} else {
-		childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+		childregs->regs[15] =
+			neff_sign_extend((unsigned long)task_stack_page(p) +
+					 THREAD_SIZE);
 	}
 
 	childregs->regs[9] = 0; /* Set return value for child */
@@ -454,17 +461,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
 	p->thread.sp = (unsigned long) childregs;
 	p->thread.pc = (unsigned long) ret_from_fork;
 
-	/*
-	 * Sign extend the edited stack.
-         * Note that thread.pc and thread.pc will stay
-	 * 32-bit wide and context switch must take care
-	 * of NEFF sign extension.
-	 */
-
-	se = childregs->regs[15];
-	se = (se & NEFF_SIGN) ? (se | NEFF_MASK) : se;
-	childregs->regs[15] = se;
-
 	return 0;
 }
 
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 3392e83..9be35f3 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -34,6 +34,9 @@
 #include <asm/syscalls.h>
 #include <asm/fpu.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 /*
  * This routine will get a word off of the process kernel stack.
  */
@@ -459,6 +462,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 		 */
 		ret = -1L;
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_enter(regs, regs->regs[0]);
+
 	if (unlikely(current->audit_context))
 		audit_syscall_entry(audit_arch(), regs->regs[3],
 				    regs->regs[4], regs->regs[5],
@@ -475,6 +481,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
 				   regs->regs[0]);
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_exit(regs, regs->regs[0]);
+
 	step = test_thread_flag(TIF_SINGLESTEP);
 	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, step);
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 6950974..952da83 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -40,6 +40,9 @@
 #include <asm/syscalls.h>
 #include <asm/fpu.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 /* This mask defines the bits of the SR which the user is not allowed to
    change, which are everything except S, Q, M, PR, SZ, FR. */
 #define SR_MASK      (0xffff8cfd)
@@ -438,6 +441,9 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
 		 */
 		ret = -1LL;
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_enter(regs, regs->regs[9]);
+
 	if (unlikely(current->audit_context))
 		audit_syscall_entry(audit_arch(), regs->regs[1],
 				    regs->regs[2], regs->regs[3],
@@ -452,6 +458,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
 		audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
 				   regs->regs[9]);
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_exit(regs, regs->regs[9]);
+
 	if (test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, 0);
 }
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index dd38338..f9d44f8 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -30,6 +30,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/lmb.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/page.h>
@@ -48,6 +49,7 @@
 struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = {
 	[0] = {
 		.type			= CPU_SH_NONE,
+		.family			= CPU_FAMILY_UNKNOWN,
 		.loops_per_jiffy	= 10000000,
 	},
 };
@@ -233,39 +235,45 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
 void __init setup_bootmem_allocator(unsigned long free_pfn)
 {
 	unsigned long bootmap_size;
+	unsigned long bootmap_pages, bootmem_paddr;
+	u64 total_pages = (lmb_end_of_DRAM() - __MEMORY_START) >> PAGE_SHIFT;
+	int i;
+
+	bootmap_pages = bootmem_bootmap_pages(total_pages);
+
+	bootmem_paddr = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
 
 	/*
 	 * Find a proper area for the bootmem bitmap. After this
 	 * bootstrap step all allocations (until the page allocator
 	 * is intact) must be done via bootmem_alloc().
 	 */
-	bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
+	bootmap_size = init_bootmem_node(NODE_DATA(0),
+					 bootmem_paddr >> PAGE_SHIFT,
 					 min_low_pfn, max_low_pfn);
 
-	__add_active_range(0, min_low_pfn, max_low_pfn);
-	register_bootmem_low_pages();
-
-	node_set_online(0);
+	/* Add active regions with valid PFNs. */
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		unsigned long start_pfn, end_pfn;
+		start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+		end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+		__add_active_range(0, start_pfn, end_pfn);
+	}
 
 	/*
-	 * Reserve the kernel text and
-	 * Reserve the bootmem bitmap. We do this in two steps (first step
-	 * was init_bootmem()), because this catches the (definitely buggy)
-	 * case of us accidentally initializing the bootmem allocator with
-	 * an invalid RAM area.
+	 * Add all physical memory to the bootmem map and mark each
+	 * area as present.
 	 */
-	reserve_bootmem(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
-			(PFN_PHYS(free_pfn) + bootmap_size + PAGE_SIZE - 1) -
-			(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET),
-			BOOTMEM_DEFAULT);
+	register_bootmem_low_pages();
 
-	/*
-	 * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
-	 */
-	if (CONFIG_ZERO_PAGE_OFFSET != 0)
-		reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
+	/* Reserve the sections we're already using. */
+	for (i = 0; i < lmb.reserved.cnt; i++)
+		reserve_bootmem(lmb.reserved.region[i].base,
+				lmb_size_bytes(&lmb.reserved, i),
 				BOOTMEM_DEFAULT);
 
+	node_set_online(0);
+
 	sparse_memory_present_with_active_regions(0);
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -296,12 +304,37 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
 static void __init setup_memory(void)
 {
 	unsigned long start_pfn;
+	u64 base = min_low_pfn << PAGE_SHIFT;
+	u64 size = (max_low_pfn << PAGE_SHIFT) - base;
 
 	/*
 	 * Partially used pages are not usable - thus
 	 * we are rounding upwards:
 	 */
 	start_pfn = PFN_UP(__pa(_end));
+
+	lmb_add(base, size);
+
+	/*
+	 * Reserve the kernel text and
+	 * Reserve the bootmem bitmap. We do this in two steps (first step
+	 * was init_bootmem()), because this catches the (definitely buggy)
+	 * case of us accidentally initializing the bootmem allocator with
+	 * an invalid RAM area.
+	 */
+	lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+		    (PFN_PHYS(start_pfn) + PAGE_SIZE - 1) -
+		    (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
+
+	/*
+	 * Reserve physical pages below CONFIG_ZERO_PAGE_OFFSET.
+	 */
+	if (CONFIG_ZERO_PAGE_OFFSET != 0)
+		lmb_reserve(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET);
+
+	lmb_analyze();
+	lmb_dump_all();
+
 	setup_bootmem_allocator(start_pfn);
 }
 #else
@@ -372,10 +405,14 @@ void __init setup_arch(char **cmdline_p)
 	if (!memory_end)
 		memory_end = memory_start + __MEMORY_SIZE;
 
-#ifdef CONFIG_CMDLINE_BOOL
+#ifdef CONFIG_CMDLINE_OVERWRITE
 	strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
 #else
 	strlcpy(command_line, COMMAND_LINE, sizeof(command_line));
+#ifdef CONFIG_CMDLINE_EXTEND
+	strlcat(command_line, " ", sizeof(command_line));
+	strlcat(command_line, CONFIG_CMDLINE, sizeof(command_line));
+#endif
 #endif
 
 	/* Save unparsed command line copy for /proc/cmdline */
@@ -402,6 +439,7 @@ void __init setup_arch(char **cmdline_p)
 	nodes_clear(node_online_map);
 
 	/* Setup bootmem with available RAM */
+	lmb_init();
 	setup_memory();
 	sparse_init();
 
@@ -448,7 +486,7 @@ static const char *cpu_name[] = {
 	[CPU_SH7763]	= "SH7763",	[CPU_SH7770]	= "SH7770",
 	[CPU_SH7780]	= "SH7780",	[CPU_SH7781]	= "SH7781",
 	[CPU_SH7343]	= "SH7343",	[CPU_SH7785]	= "SH7785",
-	[CPU_SH7786]	= "SH7786",
+	[CPU_SH7786]	= "SH7786",	[CPU_SH7757]	= "SH7757",
 	[CPU_SH7722]	= "SH7722",	[CPU_SHX3]	= "SH-X3",
 	[CPU_SH5_101]	= "SH5-101",	[CPU_SH5_103]	= "SH5-103",
 	[CPU_MXG]	= "MX-G",	[CPU_SH7723]	= "SH7723",
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index fcc5de3..8dbe26b 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -101,20 +101,14 @@ EXPORT_SYMBOL(flush_cache_range);
 EXPORT_SYMBOL(flush_dcache_page);
 #endif
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \
-	(defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB))
-EXPORT_SYMBOL(clear_user_page);
-#endif
-
-#ifdef CONFIG_FUNCTION_TRACER
-EXPORT_SYMBOL(mcount);
+#ifdef CONFIG_MCOUNT
+DECLARE_EXPORT(mcount);
 #endif
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
 #ifdef CONFIG_IPV6
 EXPORT_SYMBOL(csum_ipv6_magic);
 #endif
-EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(_ebss);
diff --git a/arch/sh/kernel/sh_ksyms_64.c b/arch/sh/kernel/sh_ksyms_64.c
index f5bd156..d008e17 100644
--- a/arch/sh/kernel/sh_ksyms_64.c
+++ b/arch/sh/kernel/sh_ksyms_64.c
@@ -30,14 +30,6 @@ extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
 EXPORT_SYMBOL(dump_fpu);
 EXPORT_SYMBOL(kernel_thread);
 
-#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU)
-EXPORT_SYMBOL(clear_user_page);
-#endif
-
-#ifndef CONFIG_CACHE_OFF
-EXPORT_SYMBOL(flush_dcache_page);
-#endif
-
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
@@ -52,7 +44,6 @@ EXPORT_SYMBOL(__get_user_asm_l);
 EXPORT_SYMBOL(__get_user_asm_q);
 EXPORT_SYMBOL(__strnlen_user);
 EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__copy_user);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 04a2188..6729703 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -41,6 +41,16 @@ struct fdpic_func_descriptor {
 };
 
 /*
+ * The following define adds a 64 byte gap between the signal
+ * stack frame and previous contents of the stack.  This allows
+ * frame unwinding in a function epilogue but only if a frame
+ * pointer is used in the function.  This is necessary because
+ * current gcc compilers (<4.3) do not generate unwind info on
+ * SH for function epilogues.
+ */
+#define UNWINDGUARD 64
+
+/*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
 asmlinkage int
@@ -327,7 +337,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 			sp = current->sas_ss_sp + current->sas_ss_size;
 	}
 
-	return (void __user *)((sp - frame_size) & -8ul);
+	return (void __user *)((sp - (frame_size+UNWINDGUARD)) & -8ul);
 }
 
 /* These symbols are defined with the addresses in the vsyscall page.
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 9e5c9b1..74793c8 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -561,13 +561,11 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
-		DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
-
 		/*
 		 * On SH5 all edited pointers are subject to NEFF
 		 */
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			ka->sa.sa_restorer | 0x1);
 	} else {
 		/*
 		 * Different approach on SH5.
@@ -580,9 +578,8 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 		 * . being code, linker turns ShMedia bit on, always
 		 *   dereference index -1.
 		 */
-		DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			frame->retcode | 0x01);
 
 		if (__copy_to_user(frame->retcode,
 			(void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
@@ -596,9 +593,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 	 * Set up registers for signal handler.
 	 * All edited pointers are subject to NEFF.
 	 */
-	regs->regs[REG_SP] = (unsigned long) frame;
-	regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
-		 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+	regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
 	regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
 
         /* FIXME:
@@ -613,8 +608,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 	regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
 	regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
 
-	regs->pc = (unsigned long) ka->sa.sa_handler;
-	regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
+	regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
 
 	set_fs(USER_DS);
 
@@ -676,13 +670,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	/* Set up to return from userspace.  If provided, use a stub
 	   already in userspace.  */
 	if (ka->sa.sa_flags & SA_RESTORER) {
-		DEREF_REG_PR = (unsigned long) ka->sa.sa_restorer | 0x1;
-
 		/*
 		 * On SH5 all edited pointers are subject to NEFF
 		 */
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			ka->sa.sa_restorer | 0x1);
 	} else {
 		/*
 		 * Different approach on SH5.
@@ -695,15 +687,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 		 * . being code, linker turns ShMedia bit on, always
 		 *   dereference index -1.
 		 */
-
-		DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
-		DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
-			(DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+		DEREF_REG_PR = neff_sign_extend((unsigned long)
+			frame->retcode | 0x01);
 
 		if (__copy_to_user(frame->retcode,
 			(void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
 			goto give_sigsegv;
 
+		/* Cohere the trampoline with the I-cache. */
 		flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
 	}
 
@@ -711,14 +702,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	 * Set up registers for signal handler.
 	 * All edited pointers are subject to NEFF.
 	 */
-	regs->regs[REG_SP] = (unsigned long) frame;
-	regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
-		 (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+	regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
 	regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
 	regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
 	regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
-	regs->pc = (unsigned long) ka->sa.sa_handler;
-	regs->pc = (regs->pc & NEFF_SIGN) ? (regs->pc | NEFF_MASK) : regs->pc;
+	regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
 
 	set_fs(USER_DS);
 
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 1a2a5eb..c2e45c4 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -13,47 +13,93 @@
 #include <linux/stacktrace.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
+#include <asm/unwinder.h>
 #include <asm/ptrace.h>
+#include <asm/stacktrace.h>
+
+static void save_stack_warning(void *data, char *msg)
+{
+}
+
+static void
+save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+}
+
+static int save_stack_stack(void *data, char *name)
+{
+	return 0;
+}
 
 /*
  * Save stack-backtrace addresses into a stack_trace buffer.
  */
+static void save_stack_address(void *data, unsigned long addr, int reliable)
+{
+	struct stack_trace *trace = data;
+
+	if (!reliable)
+		return;
+
+	if (trace->skip > 0) {
+		trace->skip--;
+		return;
+	}
+
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = addr;
+}
+
+static const struct stacktrace_ops save_stack_ops = {
+	.warning = save_stack_warning,
+	.warning_symbol = save_stack_warning_symbol,
+	.stack = save_stack_stack,
+	.address = save_stack_address,
+};
+
 void save_stack_trace(struct stack_trace *trace)
 {
 	unsigned long *sp = (unsigned long *)current_stack_pointer;
 
-	while (!kstack_end(sp)) {
-		unsigned long addr = *sp++;
-
-		if (__kernel_text_address(addr)) {
-			if (trace->skip > 0)
-				trace->skip--;
-			else
-				trace->entries[trace->nr_entries++] = addr;
-			if (trace->nr_entries >= trace->max_entries)
-				break;
-		}
-	}
+	unwind_stack(current, NULL, sp,  &save_stack_ops, trace);
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = ULONG_MAX;
 }
 EXPORT_SYMBOL_GPL(save_stack_trace);
 
+static void
+save_stack_address_nosched(void *data, unsigned long addr, int reliable)
+{
+	struct stack_trace *trace = (struct stack_trace *)data;
+
+	if (!reliable)
+		return;
+
+	if (in_sched_functions(addr))
+		return;
+
+	if (trace->skip > 0) {
+		trace->skip--;
+		return;
+	}
+
+	if (trace->nr_entries < trace->max_entries)
+		trace->entries[trace->nr_entries++] = addr;
+}
+
+static const struct stacktrace_ops save_stack_ops_nosched = {
+	.warning = save_stack_warning,
+	.warning_symbol = save_stack_warning_symbol,
+	.stack = save_stack_stack,
+	.address = save_stack_address_nosched,
+};
+
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
 	unsigned long *sp = (unsigned long *)tsk->thread.sp;
 
-	while (!kstack_end(sp)) {
-		unsigned long addr = *sp++;
-
-		if (__kernel_text_address(addr)) {
-			if (in_sched_functions(addr))
-				break;
-			if (trace->skip > 0)
-				trace->skip--;
-			else
-				trace->entries[trace->nr_entries++] = addr;
-			if (trace->nr_entries >= trace->max_entries)
-				break;
-		}
-	}
+	unwind_stack(current, NULL, sp,  &save_stack_ops_nosched, 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/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 90d00e4..8aa5d1c 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -25,6 +25,8 @@
 #include <asm/syscalls.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include <asm/cacheflush.h>
+#include <asm/cachectl.h>
 
 static inline long
 do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
@@ -179,6 +181,47 @@ asmlinkage int sys_ipc(uint call, int first, int second,
 	return -EINVAL;
 }
 
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
+{
+	struct vm_area_struct *vma;
+
+	if ((op <= 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I)))
+		return -EINVAL;
+
+	/*
+	 * Verify that the specified address region actually belongs
+	 * to this process.
+	 */
+	if (addr + len < addr)
+		return -EFAULT;
+
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma (current->mm, addr);
+	if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) {
+		up_read(&current->mm->mmap_sem);
+		return -EFAULT;
+	}
+
+	switch (op & CACHEFLUSH_D_PURGE) {
+		case CACHEFLUSH_D_INVAL:
+			__flush_invalidate_region((void *)addr, len);
+			break;
+		case CACHEFLUSH_D_WB:
+			__flush_wback_region((void *)addr, len);
+			break;
+		case CACHEFLUSH_D_PURGE:
+			__flush_purge_region((void *)addr, len);
+			break;
+	}
+
+	if (op & CACHEFLUSH_I)
+		flush_cache_all();
+
+	up_read(&current->mm->mmap_sem);
+	return 0;
+}
+
 asmlinkage int sys_uname(struct old_utsname __user *name)
 {
 	int err;
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S
index f9e21fa..19fd11d 100644
--- a/arch/sh/kernel/syscalls_32.S
+++ b/arch/sh/kernel/syscalls_32.S
@@ -139,7 +139,7 @@ ENTRY(sys_call_table)
 	.long sys_clone		/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
-	.long sys_ni_syscall	/* sys_modify_ldt */
+	.long sys_cacheflush	/* x86: sys_modify_ldt */
 	.long sys_adjtimex
 	.long sys_mprotect		/* 125 */
 	.long sys_sigprocmask
@@ -352,4 +352,4 @@ ENTRY(sys_call_table)
 	.long sys_preadv
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo	/* 335 */
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S
index bf420b6..5bfde6c 100644
--- a/arch/sh/kernel/syscalls_64.S
+++ b/arch/sh/kernel/syscalls_64.S
@@ -143,7 +143,7 @@ sys_call_table:
 	.long sys_clone			/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
-	.long sys_ni_syscall	/* sys_modify_ldt */
+	.long sys_cacheflush	/* x86: sys_modify_ldt */
 	.long sys_adjtimex
 	.long sys_mprotect		/* 125 */
 	.long sys_sigprocmask
@@ -390,4 +390,4 @@ sys_call_table:
 	.long sys_preadv
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 9b352a1..953fa16 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -21,6 +21,7 @@
 #include <linux/smp.h>
 #include <linux/rtc.h>
 #include <asm/clock.h>
+#include <asm/hwblk.h>
 #include <asm/rtc.h>
 
 /* Dummy RTC ops */
@@ -39,11 +40,9 @@ void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
 int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
 
 #ifdef CONFIG_GENERIC_CMOS_UPDATE
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
-	struct timespec tv;
-	rtc_sh_get_time(&tv);
-	return tv.tv_sec;
+	rtc_sh_get_time(ts);
 }
 
 int update_persistent_clock(struct timespec now)
@@ -91,21 +90,8 @@ module_init(rtc_generic_init);
 
 void (*board_time_init)(void);
 
-void __init time_init(void)
+static void __init sh_late_time_init(void)
 {
-	if (board_time_init)
-		board_time_init();
-
-	clk_init();
-
-	rtc_sh_get_time(&xtime);
-	set_normalized_timespec(&wall_to_monotonic,
-				-xtime.tv_sec, -xtime.tv_nsec);
-
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-	local_timer_setup(smp_processor_id());
-#endif
-
 	/*
 	 * Make sure all compiled-in early timers register themselves.
 	 *
@@ -118,3 +104,18 @@ void __init time_init(void)
 	early_platform_driver_register_all("earlytimer");
 	early_platform_driver_probe("earlytimer", 2, 0);
 }
+
+void __init time_init(void)
+{
+	if (board_time_init)
+		board_time_init();
+
+	hwblk_init();
+	clk_init();
+
+	rtc_sh_get_time(&xtime);
+	set_normalized_timespec(&wall_to_monotonic,
+				-xtime.tv_sec, -xtime.tv_nsec);
+
+	late_time_init = sh_late_time_init;
+}
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index b3e0067..a8396f3 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -5,18 +5,33 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/uaccess.h>
+#include <linux/hardirq.h>
+#include <asm/unwinder.h>
 #include <asm/system.h>
 
 #ifdef CONFIG_BUG
-static void handle_BUG(struct pt_regs *regs)
+void handle_BUG(struct pt_regs *regs)
 {
+	const struct bug_entry *bug;
+	unsigned long bugaddr = regs->pc;
 	enum bug_trap_type tt;
-	tt = report_bug(regs->pc, regs);
+
+	if (!is_valid_bugaddr(bugaddr))
+		goto invalid;
+
+	bug = find_bug(bugaddr);
+
+	/* Switch unwinders when unwind_stack() is called */
+	if (bug->flags & BUGFLAG_UNWINDER)
+		unwinder_faulted = 1;
+
+	tt = report_bug(bugaddr, regs);
 	if (tt == BUG_TRAP_TYPE_WARN) {
-		regs->pc += instruction_size(regs->pc);
+		regs->pc += instruction_size(bugaddr);
 		return;
 	}
 
+invalid:
 	die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff);
 }
 
@@ -28,8 +43,10 @@ int is_valid_bugaddr(unsigned long addr)
 		return 0;
 	if (probe_kernel_address((insn_size_t *)addr, opcode))
 		return 0;
+	if (opcode == TRAPA_BUG_OPCODE)
+		return 1;
 
-	return opcode == TRAPA_BUG_OPCODE;
+	return 0;
 }
 #endif
 
@@ -75,3 +92,23 @@ BUILD_TRAP_HANDLER(bug)
 
 	force_sig(SIGTRAP, current);
 }
+
+BUILD_TRAP_HANDLER(nmi)
+{
+	TRAP_HANDLER_DECL;
+
+	nmi_enter();
+
+	switch (notify_die(DIE_NMI, "NMI", regs, 0, vec & 0xff, SIGINT)) {
+	case NOTIFY_OK:
+	case NOTIFY_STOP:
+		break;
+	case NOTIFY_BAD:
+		die("Fatal Non-Maskable Interrupt", regs, SIGINT);
+	default:
+		printk(KERN_ALERT "Got NMI, but nobody cared. Ignoring...\n");
+		break;
+	}
+
+	nmi_exit();
+}
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 2b77277..6aba9af 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -24,6 +24,7 @@
 #include <linux/kdebug.h>
 #include <linux/kexec.h>
 #include <linux/limits.h>
+#include <linux/proc_fs.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/fpu.h>
@@ -44,6 +45,85 @@
 #define TRAP_ILLEGAL_SLOT_INST	13
 #endif
 
+static unsigned long se_user;
+static unsigned long se_sys;
+static unsigned long se_half;
+static unsigned long se_word;
+static unsigned long se_dword;
+static unsigned long se_multi;
+/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
+   valid! */
+static int se_usermode = 3;
+/* 0: no warning 1: print a warning message */
+static int se_kernmode_warn = 1;
+
+#ifdef CONFIG_PROC_FS
+static const char *se_usermode_action[] = {
+	"ignored",
+	"warn",
+	"fixup",
+	"fixup+warn",
+	"signal",
+	"signal+warn"
+};
+
+static int
+proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
+		    void *data)
+{
+	char *p = page;
+	int len;
+
+	p += sprintf(p, "User:\t\t%lu\n", se_user);
+	p += sprintf(p, "System:\t\t%lu\n", se_sys);
+	p += sprintf(p, "Half:\t\t%lu\n", se_half);
+	p += sprintf(p, "Word:\t\t%lu\n", se_word);
+	p += sprintf(p, "DWord:\t\t%lu\n", se_dword);
+	p += sprintf(p, "Multi:\t\t%lu\n", se_multi);
+	p += sprintf(p, "User faults:\t%i (%s)\n", se_usermode,
+			se_usermode_action[se_usermode]);
+	p += sprintf(p, "Kernel faults:\t%i (fixup%s)\n", se_kernmode_warn,
+			se_kernmode_warn ? "+warn" : "");
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
+}
+
+static int proc_alignment_write(struct file *file, const char __user *buffer,
+				unsigned long count, void *data)
+{
+	char mode;
+
+	if (count > 0) {
+		if (get_user(mode, buffer))
+			return -EFAULT;
+		if (mode >= '0' && mode <= '5')
+			se_usermode = mode - '0';
+	}
+	return count;
+}
+
+static int proc_alignment_kern_write(struct file *file, const char __user *buffer,
+				     unsigned long count, void *data)
+{
+	char mode;
+
+	if (count > 0) {
+		if (get_user(mode, buffer))
+			return -EFAULT;
+		if (mode >= '0' && mode <= '1')
+			se_kernmode_warn = mode - '0';
+	}
+	return count;
+}
+#endif
+
 static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 {
 	unsigned long p;
@@ -136,6 +216,7 @@ static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
 			regs->pc = fixup->fixup;
 			return;
 		}
+
 		die(str, regs, err);
 	}
 }
@@ -193,6 +274,13 @@ static int handle_unaligned_ins(insn_size_t instruction, struct pt_regs *regs,
 
 	count = 1<<(instruction&3);
 
+	switch (count) {
+	case 1: se_half  += 1; break;
+	case 2: se_word  += 1; break;
+	case 4: se_dword += 1; break;
+	case 8: se_multi += 1; break; /* ??? */
+	}
+
 	ret = -EFAULT;
 	switch (instruction>>12) {
 	case 0: /* mov.[bwl] to/from memory via r0+rn */
@@ -358,15 +446,8 @@ static inline int handle_delayslot(struct pt_regs *regs,
 #define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4)
 #define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4)
 
-/*
- * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit
- * opcodes..
- */
-
-static int handle_unaligned_notify_count = 10;
-
 int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
-			    struct mem_access *ma)
+			    struct mem_access *ma, int expected)
 {
 	u_int rm;
 	int ret, index;
@@ -374,15 +455,13 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
 	index = (instruction>>8)&15;	/* 0x0F00 */
 	rm = regs->regs[index];
 
-	/* shout about the first ten userspace fixups */
-	if (user_mode(regs) && handle_unaligned_notify_count>0) {
-		handle_unaligned_notify_count--;
-
-		printk(KERN_NOTICE "Fixing up unaligned userspace access "
+	/* shout about fixups */
+	if (!expected && printk_ratelimit())
+		printk(KERN_NOTICE "Fixing up unaligned %s access "
 		       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+		       user_mode(regs) ? "userspace" : "kernel",
 		       current->comm, task_pid_nr(current),
 		       (void *)regs->pc, instruction);
-	}
 
 	ret = -EFAULT;
 	switch (instruction&0xF000) {
@@ -538,6 +617,36 @@ asmlinkage void do_address_error(struct pt_regs *regs,
 
 		local_irq_enable();
 
+		se_user += 1;
+
+#ifndef CONFIG_CPU_SH2A
+		set_fs(USER_DS);
+		if (copy_from_user(&instruction, (u16 *)(regs->pc & ~1), 2)) {
+			set_fs(oldfs);
+			goto uspace_segv;
+		}
+		set_fs(oldfs);
+
+		/* shout about userspace fixups */
+		if (se_usermode & 1)
+			printk(KERN_NOTICE "Unaligned userspace access "
+			       "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+			       current->comm, current->pid, (void *)regs->pc,
+			       instruction);
+#endif
+
+		if (se_usermode & 2)
+			goto fixup;
+
+		if (se_usermode & 4)
+			goto uspace_segv;
+		else {
+			/* ignore */
+			regs->pc += instruction_size(instruction);
+			return;
+		}
+
+fixup:
 		/* bad PC is not something we can fix */
 		if (regs->pc & 1) {
 			si_code = BUS_ADRALN;
@@ -545,17 +654,8 @@ asmlinkage void do_address_error(struct pt_regs *regs,
 		}
 
 		set_fs(USER_DS);
-		if (copy_from_user(&instruction, (void __user *)(regs->pc),
-				   sizeof(instruction))) {
-			/* Argh. Fault on the instruction itself.
-			   This should never happen non-SMP
-			*/
-			set_fs(oldfs);
-			goto uspace_segv;
-		}
-
 		tmp = handle_unaligned_access(instruction, regs,
-					      &user_mem_access);
+					      &user_mem_access, 0);
 		set_fs(oldfs);
 
 		if (tmp==0)
@@ -571,6 +671,14 @@ uspace_segv:
 		info.si_addr = (void __user *)address;
 		force_sig_info(SIGBUS, &info, current);
 	} else {
+		se_sys += 1;
+
+		if (se_kernmode_warn)
+			printk(KERN_NOTICE "Unaligned kernel access "
+			       "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
+			       current->comm, current->pid, (void *)regs->pc,
+			       instruction);
+
 		if (regs->pc & 1)
 			die("unaligned program counter", regs, error_code);
 
@@ -584,7 +692,8 @@ uspace_segv:
 			die("insn faulting in do_address_error", regs, 0);
 		}
 
-		handle_unaligned_access(instruction, regs, &user_mem_access);
+		handle_unaligned_access(instruction, regs,
+					&user_mem_access, 0);
 		set_fs(oldfs);
 	}
 }
@@ -858,30 +967,6 @@ void __init trap_init(void)
 	per_cpu_trap_init();
 }
 
-void show_trace(struct task_struct *tsk, unsigned long *sp,
-		struct pt_regs *regs)
-{
-	unsigned long addr;
-
-	if (regs && user_mode(regs))
-		return;
-
-	printk("\nCall trace:\n");
-
-	while (!kstack_end(sp)) {
-		addr = *sp++;
-		if (kernel_text_address(addr))
-			print_ip_sym(addr);
-	}
-
-	printk("\n");
-
-	if (!tsk)
-		tsk = current;
-
-	debug_show_held_locks(tsk);
-}
-
 void show_stack(struct task_struct *tsk, unsigned long *sp)
 {
 	unsigned long stack;
@@ -904,3 +989,38 @@ void dump_stack(void)
 	show_stack(NULL, NULL);
 }
 EXPORT_SYMBOL(dump_stack);
+
+#ifdef CONFIG_PROC_FS
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten.  Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+	struct proc_dir_entry *dir, *res;
+
+	dir = proc_mkdir("cpu", NULL);
+	if (!dir)
+		return -ENOMEM;
+
+	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, dir);
+	if (!res)
+		return -ENOMEM;
+
+	res->read_proc = proc_alignment_read;
+	res->write_proc = proc_alignment_write;
+
+        res = create_proc_entry("kernel_alignment", S_IWUSR | S_IRUGO, dir);
+        if (!res)
+                return -ENOMEM;
+
+        res->read_proc = proc_alignment_read;
+        res->write_proc = proc_alignment_kern_write;
+
+	return 0;
+}
+
+fs_initcall(alignment_init);
+#endif
diff --git a/arch/sh/kernel/unwinder.c b/arch/sh/kernel/unwinder.c
new file mode 100644
index 0000000..468889d
--- /dev/null
+++ b/arch/sh/kernel/unwinder.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2009  Matt Fleming
+ *
+ * Based, in part, on kernel/time/clocksource.c.
+ *
+ * This file provides arbitration code for stack unwinders.
+ *
+ * Multiple stack unwinders can be available on a system, usually with
+ * the most accurate unwinder being the currently active one.
+ */
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <asm/unwinder.h>
+#include <asm/atomic.h>
+
+/*
+ * This is the most basic stack unwinder an architecture can
+ * provide. For architectures without reliable frame pointers, e.g.
+ * RISC CPUs, it can be implemented by looking through the stack for
+ * addresses that lie within the kernel text section.
+ *
+ * Other CPUs, e.g. x86, can use their frame pointer register to
+ * construct more accurate stack traces.
+ */
+static struct list_head unwinder_list;
+static struct unwinder stack_reader = {
+	.name = "stack-reader",
+	.dump = stack_reader_dump,
+	.rating = 50,
+	.list = {
+		.next = &unwinder_list,
+		.prev = &unwinder_list,
+	},
+};
+
+/*
+ * "curr_unwinder" points to the stack unwinder currently in use. This
+ * is the unwinder with the highest rating.
+ *
+ * "unwinder_list" is a linked-list of all available unwinders, sorted
+ * by rating.
+ *
+ * All modifications of "curr_unwinder" and "unwinder_list" must be
+ * performed whilst holding "unwinder_lock".
+ */
+static struct unwinder *curr_unwinder = &stack_reader;
+
+static struct list_head unwinder_list = {
+	.next = &stack_reader.list,
+	.prev = &stack_reader.list,
+};
+
+static DEFINE_SPINLOCK(unwinder_lock);
+
+/**
+ * select_unwinder - Select the best registered stack unwinder.
+ *
+ * Private function. Must hold unwinder_lock when called.
+ *
+ * Select the stack unwinder with the best rating. This is useful for
+ * setting up curr_unwinder.
+ */
+static struct unwinder *select_unwinder(void)
+{
+	struct unwinder *best;
+
+	if (list_empty(&unwinder_list))
+		return NULL;
+
+	best = list_entry(unwinder_list.next, struct unwinder, list);
+	if (best == curr_unwinder)
+		return NULL;
+
+	return best;
+}
+
+/*
+ * Enqueue the stack unwinder sorted by rating.
+ */
+static int unwinder_enqueue(struct unwinder *ops)
+{
+	struct list_head *tmp, *entry = &unwinder_list;
+
+	list_for_each(tmp, &unwinder_list) {
+		struct unwinder *o;
+
+		o = list_entry(tmp, struct unwinder, list);
+		if (o == ops)
+			return -EBUSY;
+		/* Keep track of the place, where to insert */
+		if (o->rating >= ops->rating)
+			entry = tmp;
+	}
+	list_add(&ops->list, entry);
+
+	return 0;
+}
+
+/**
+ * unwinder_register - Used to install new stack unwinder
+ * @u: unwinder to be registered
+ *
+ * Install the new stack unwinder on the unwinder list, which is sorted
+ * by rating.
+ *
+ * Returns -EBUSY if registration fails, zero otherwise.
+ */
+int unwinder_register(struct unwinder *u)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&unwinder_lock, flags);
+	ret = unwinder_enqueue(u);
+	if (!ret)
+		curr_unwinder = select_unwinder();
+	spin_unlock_irqrestore(&unwinder_lock, flags);
+
+	return ret;
+}
+
+int unwinder_faulted = 0;
+
+/*
+ * Unwind the call stack and pass information to the stacktrace_ops
+ * functions. Also handle the case where we need to switch to a new
+ * stack dumper because the current one faulted unexpectedly.
+ */
+void unwind_stack(struct task_struct *task, struct pt_regs *regs,
+		  unsigned long *sp, const struct stacktrace_ops *ops,
+		  void *data)
+{
+	unsigned long flags;
+
+	/*
+	 * The problem with unwinders with high ratings is that they are
+	 * inherently more complicated than the simple ones with lower
+	 * ratings. We are therefore more likely to fault in the
+	 * complicated ones, e.g. hitting BUG()s. If we fault in the
+	 * code for the current stack unwinder we try to downgrade to
+	 * one with a lower rating.
+	 *
+	 * Hopefully this will give us a semi-reliable stacktrace so we
+	 * can diagnose why curr_unwinder->dump() faulted.
+	 */
+	if (unwinder_faulted) {
+		spin_lock_irqsave(&unwinder_lock, flags);
+
+		/* Make sure no one beat us to changing the unwinder */
+		if (unwinder_faulted && !list_is_singular(&unwinder_list)) {
+			list_del(&curr_unwinder->list);
+			curr_unwinder = select_unwinder();
+
+			unwinder_faulted = 0;
+		}
+
+		spin_unlock_irqrestore(&unwinder_lock, flags);
+	}
+
+	curr_unwinder->dump(task, regs, sp, ops, data);
+}
+EXPORT_SYMBOL_GPL(unwind_stack);
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index f53c76a..a1e4ec2 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -12,7 +12,7 @@ OUTPUT_ARCH(sh)
 
 #include <asm/thread_info.h>
 #include <asm/cache.h>
-#include <asm-generic/vmlinux.lds.h>
+#include <asm/vmlinux.lds.h>
 
 ENTRY(_start)
 SECTIONS
@@ -50,12 +50,7 @@ SECTIONS
 		_etext = .;		/* End of text section */
 	} = 0x0009
 
-	. = ALIGN(16);		/* Exception table */
-	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-	}
+	EXCEPTION_TABLE(16)
 
 	NOTES
 	RO_DATA(PAGE_SIZE)
@@ -71,69 +66,16 @@ SECTIONS
 		__uncached_end = .;
 	}
 
-	. = ALIGN(THREAD_SIZE);
-	.data : AT(ADDR(.data) - LOAD_OFFSET) {		/* Data */
-		*(.data.init_task)
-
-		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.cacheline_aligned)
-
-		. = ALIGN(L1_CACHE_BYTES);
-		*(.data.read_mostly)
-
-		. = ALIGN(PAGE_SIZE);
-		*(.data.page_aligned)
-
-		__nosave_begin = .;
-		*(.data.nosave)
-		. = ALIGN(PAGE_SIZE);
-		__nosave_end = .;
-
-		DATA_DATA
-		CONSTRUCTORS
-	}
+	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
 	_edata = .;			/* End of data section */
 
-	. = ALIGN(PAGE_SIZE);		/* Init code and data */
-	.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
-		__init_begin = .;
-		_sinittext = .;
-		INIT_TEXT
-		_einittext = .;
-	}
-
-	.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { INIT_DATA }
-
-	. = ALIGN(16);
-	.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-	}
-
-	.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
-		__initcall_start = .;
-		INITCALLS
-		__initcall_end = .;
-	}
+	DWARF_EH_FRAME
 
-	.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
-		__con_initcall_start = .;
-		*(.con_initcall.init)
-		__con_initcall_end = .;
-	}
-
-	SECURITY_INIT
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	. = ALIGN(PAGE_SIZE);
-	.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
-		__initramfs_start = .;
-		*(.init.ramfs)
-		__initramfs_end = .;
-	}
-#endif
+	. = ALIGN(PAGE_SIZE);		/* Init code and data */
+	__init_begin = .;
+	INIT_TEXT_SECTION(PAGE_SIZE)
+	INIT_DATA_SECTION(16)
 
 	. = ALIGN(4);
 	.machvec.init : AT(ADDR(.machvec.init) - LOAD_OFFSET) {
@@ -152,27 +94,13 @@ SECTIONS
 	.exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { EXIT_DATA }
 
 	. = ALIGN(PAGE_SIZE);
-	.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
-		__init_end = .;
-		__bss_start = .;		/* BSS */
-		*(.bss.page_aligned)
-		*(.bss)
-		*(COMMON)
-		. = ALIGN(4);
-		_ebss = .;			/* uClinux MTD sucks */
-		_end = . ;
-	}
-
-	/*
-	 * When something in the kernel is NOT compiled as a module, the
-	 * module cleanup code and data are put into these segments. Both
-	 * can then be thrown away, as cleanup code is never called unless
-	 * it's a module.
-	 */
-	/DISCARD/ : {
-		*(.exitcall.exit)
-	}
+	__init_end = .;
+	BSS_SECTION(0, PAGE_SIZE, 4)
+	_ebss = .;			/* uClinux MTD sucks */
+	_end = . ;
 
 	STABS_DEBUG
 	DWARF_DEBUG
+
+	DISCARDS
 }
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index aaea580..a969b47 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -23,8 +23,8 @@ obj-y				+= io.o
 memcpy-y			:= memcpy.o
 memcpy-$(CONFIG_CPU_SH4)	:= memcpy-sh4.o
 
-lib-$(CONFIG_MMU)		+= copy_page.o clear_page.o
-lib-$(CONFIG_FUNCTION_TRACER)	+= mcount.o
+lib-$(CONFIG_MMU)		+= copy_page.o __clear_user.o
+lib-$(CONFIG_MCOUNT)		+= mcount.o
 lib-y				+= $(memcpy-y) $(udivsi3-y)
 
 EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/lib/__clear_user.S b/arch/sh/lib/__clear_user.S
new file mode 100644
index 0000000..db1dca7
--- /dev/null
+++ b/arch/sh/lib/__clear_user.S
@@ -0,0 +1,108 @@
+/*
+ * __clear_user_page, __clear_user, clear_page implementation of SuperH
+ *
+ * Copyright (C) 2001  Kaz Kojima
+ * Copyright (C) 2001, 2002  Niibe Yutaka
+ * Copyright (C) 2006  Paul Mundt
+ */
+#include <linux/linkage.h>
+#include <asm/page.h>
+
+ENTRY(__clear_user)
+	!
+	mov	#0, r0
+	mov	#0xffffffe0, r1
+	!
+	! r4..(r4+31)&~32 	   -------- not aligned	[ Area 0 ]
+	! (r4+31)&~32..(r4+r5)&~32 -------- aligned	[ Area 1 ]
+	! (r4+r5)&~32..r4+r5       -------- not aligned	[ Area 2 ]
+	!
+	! Clear area 0
+	mov	r4, r2
+	!
+	tst	r1, r5		! length < 32
+	bt	.Larea2		! skip to remainder
+	!
+	add	#31, r2
+	and	r1, r2
+	cmp/eq	r4, r2
+	bt	.Larea1
+	mov	r2, r3
+	sub	r4, r3
+	mov	r3, r7
+	mov	r4, r2
+	!
+.L0:	dt	r3
+0:	mov.b	r0, @r2
+	bf/s	.L0
+	 add	#1, r2
+	!
+	sub	r7, r5
+	mov	r2, r4
+.Larea1:
+	mov	r4, r3
+	add	r5, r3
+	and	r1, r3
+	cmp/hi	r2, r3
+	bf	.Larea2
+	!
+	! Clear area 1
+#if defined(CONFIG_CPU_SH4)
+1:	movca.l	r0, @r2
+#else
+1:	mov.l	r0, @r2
+#endif
+	add	#4, r2
+2:	mov.l	r0, @r2
+	add	#4, r2
+3:	mov.l	r0, @r2
+	add	#4, r2
+4:	mov.l	r0, @r2
+	add	#4, r2
+5:	mov.l	r0, @r2
+	add	#4, r2
+6:	mov.l	r0, @r2
+	add	#4, r2
+7:	mov.l	r0, @r2
+	add	#4, r2
+8:	mov.l	r0, @r2
+	add	#4, r2
+	cmp/hi	r2, r3
+	bt/s	1b
+	 nop
+	!
+	! Clear area 2
+.Larea2:
+	mov	r4, r3
+	add	r5, r3
+	cmp/hs	r3, r2
+	bt/s	.Ldone
+	 sub	r2, r3
+.L2:	dt	r3
+9:	mov.b	r0, @r2
+	bf/s	.L2
+	 add	#1, r2
+	!
+.Ldone:	rts
+	 mov	#0, r0	! return 0 as normal return
+
+	! return the number of bytes remained
+.Lbad_clear_user:
+	mov	r4, r0
+	add	r5, r0
+	rts
+	 sub	r2, r0
+
+.section __ex_table,"a"
+	.align 2
+	.long	0b, .Lbad_clear_user
+	.long	1b, .Lbad_clear_user
+	.long	2b, .Lbad_clear_user
+	.long	3b, .Lbad_clear_user
+	.long	4b, .Lbad_clear_user
+	.long	5b, .Lbad_clear_user
+	.long	6b, .Lbad_clear_user
+	.long	7b, .Lbad_clear_user
+	.long	8b, .Lbad_clear_user
+	.long	9b, .Lbad_clear_user
+.previous
diff --git a/arch/sh/lib/clear_page.S b/arch/sh/lib/clear_page.S
deleted file mode 100644
index 8342bfb..0000000
--- a/arch/sh/lib/clear_page.S
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * __clear_user_page, __clear_user, clear_page implementation of SuperH
- *
- * Copyright (C) 2001  Kaz Kojima
- * Copyright (C) 2001, 2002  Niibe Yutaka
- * Copyright (C) 2006  Paul Mundt
- */
-#include <linux/linkage.h>
-#include <asm/page.h>
-
-/*
- * clear_page
- * @to: P1 address
- *
- * void clear_page(void *to)
- */
-
-/*
- * r0 --- scratch
- * r4 --- to
- * r5 --- to + PAGE_SIZE
- */
-ENTRY(clear_page)
-	mov	r4,r5
-	mov.l	.Llimit,r0
-	add	r0,r5
-	mov	#0,r0
-	!
-1:
-#if defined(CONFIG_CPU_SH4)
-	movca.l	r0,@r4
-	mov	r4,r1
-#else
-	mov.l	r0,@r4
-#endif
-	add	#32,r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-	mov.l	r0,@-r4
-#if defined(CONFIG_CPU_SH4)
-	ocbwb	@r1
-#endif
-	cmp/eq	r5,r4
-	bf/s	1b
-	 add	#28,r4
-	!
-	rts
-	 nop
-
-	.balign 4
-.Llimit:	.long	(PAGE_SIZE-28)
-
-ENTRY(__clear_user)
-	!
-	mov	#0, r0
-	mov	#0xe0, r1	! 0xffffffe0
-	!
-	! r4..(r4+31)&~32 	   -------- not aligned	[ Area 0 ]
-	! (r4+31)&~32..(r4+r5)&~32 -------- aligned	[ Area 1 ]
-	! (r4+r5)&~32..r4+r5       -------- not aligned	[ Area 2 ]
-	!
-	! Clear area 0
-	mov	r4, r2
-	!
-	tst	r1, r5		! length < 32
-	bt	.Larea2		! skip to remainder
-	!
-	add	#31, r2
-	and	r1, r2
-	cmp/eq	r4, r2
-	bt	.Larea1
-	mov	r2, r3
-	sub	r4, r3
-	mov	r3, r7
-	mov	r4, r2
-	!
-.L0:	dt	r3
-0:	mov.b	r0, @r2
-	bf/s	.L0
-	 add	#1, r2
-	!
-	sub	r7, r5
-	mov	r2, r4
-.Larea1:
-	mov	r4, r3
-	add	r5, r3
-	and	r1, r3
-	cmp/hi	r2, r3
-	bf	.Larea2
-	!
-	! Clear area 1
-#if defined(CONFIG_CPU_SH4)
-1:	movca.l	r0, @r2
-#else
-1:	mov.l	r0, @r2
-#endif
-	add	#4, r2
-2:	mov.l	r0, @r2
-	add	#4, r2
-3:	mov.l	r0, @r2
-	add	#4, r2
-4:	mov.l	r0, @r2
-	add	#4, r2
-5:	mov.l	r0, @r2
-	add	#4, r2
-6:	mov.l	r0, @r2
-	add	#4, r2
-7:	mov.l	r0, @r2
-	add	#4, r2
-8:	mov.l	r0, @r2
-	add	#4, r2
-	cmp/hi	r2, r3
-	bt/s	1b
-	 nop
-	!
-	! Clear area 2
-.Larea2:
-	mov	r4, r3
-	add	r5, r3
-	cmp/hs	r3, r2
-	bt/s	.Ldone
-	 sub	r2, r3
-.L2:	dt	r3
-9:	mov.b	r0, @r2
-	bf/s	.L2
-	 add	#1, r2
-	!
-.Ldone:	rts
-	 mov	#0, r0	! return 0 as normal return
-
-	! return the number of bytes remained
-.Lbad_clear_user:
-	mov	r4, r0
-	add	r5, r0
-	rts
-	 sub	r2, r0
-
-.section __ex_table,"a"
-	.align 2
-	.long	0b, .Lbad_clear_user
-	.long	1b, .Lbad_clear_user
-	.long	2b, .Lbad_clear_user
-	.long	3b, .Lbad_clear_user
-	.long	4b, .Lbad_clear_user
-	.long	5b, .Lbad_clear_user
-	.long	6b, .Lbad_clear_user
-	.long	7b, .Lbad_clear_user
-	.long	8b, .Lbad_clear_user
-	.long	9b, .Lbad_clear_user
-.previous
diff --git a/arch/sh/lib/copy_page.S b/arch/sh/lib/copy_page.S
index 43de7e8..9d7b8bc 100644
--- a/arch/sh/lib/copy_page.S
+++ b/arch/sh/lib/copy_page.S
@@ -30,7 +30,9 @@ ENTRY(copy_page)
 	mov	r4,r10
 	mov	r5,r11
 	mov	r5,r8
-	mov.l	.Lpsz,r0
+	mov	#(PAGE_SIZE >> 10), r0
+	shll8	r0
+	shll2	r0
 	add	r0,r8
 	!
 1:	mov.l	@r11+,r0
@@ -43,7 +45,6 @@ ENTRY(copy_page)
 	mov.l	@r11+,r7
 #if defined(CONFIG_CPU_SH4)
 	movca.l	r0,@r10
-	mov	r10,r0
 #else
 	mov.l	r0,@r10
 #endif
@@ -55,9 +56,6 @@ ENTRY(copy_page)
 	mov.l	r3,@-r10
 	mov.l	r2,@-r10
 	mov.l	r1,@-r10
-#if defined(CONFIG_CPU_SH4)
-	ocbwb	@r0
-#endif
 	cmp/eq	r11,r8
 	bf/s	1b
 	 add	#28,r10
@@ -68,9 +66,6 @@ ENTRY(copy_page)
 	rts
 	 nop
 
-	.balign 4
-.Lpsz:	.long	PAGE_SIZE
-
 /*
  * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
  * Return the number of bytes NOT copied
diff --git a/arch/sh/lib/delay.c b/arch/sh/lib/delay.c
index f3ddd21..faa8f86 100644
--- a/arch/sh/lib/delay.c
+++ b/arch/sh/lib/delay.c
@@ -21,13 +21,14 @@ void __delay(unsigned long loops)
 
 inline void __const_udelay(unsigned long xloops)
 {
+	xloops *= 4;
 	__asm__("dmulu.l	%0, %2\n\t"
 		"sts	mach, %0"
 		: "=r" (xloops)
 		: "0" (xloops),
-		  "r" (HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy)
+		  "r" (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4))
 		: "macl", "mach");
-	__delay(xloops);
+	__delay(++xloops);
 }
 
 void __udelay(unsigned long usecs)
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S
index 110fbfe..84a5776 100644
--- a/arch/sh/lib/mcount.S
+++ b/arch/sh/lib/mcount.S
@@ -1,14 +1,16 @@
 /*
  * arch/sh/lib/mcount.S
  *
- *  Copyright (C) 2008  Paul Mundt
- *  Copyright (C) 2008  Matt Fleming
+ *  Copyright (C) 2008, 2009  Paul Mundt
+ *  Copyright (C) 2008, 2009  Matt Fleming
  *
  * 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.
  */
 #include <asm/ftrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
 
 #define MCOUNT_ENTER()		\
 	mov.l	r4, @-r15;	\
@@ -28,6 +30,55 @@
 	rts;			\
 	 mov.l	@r15+, r4
 
+#ifdef CONFIG_STACK_DEBUG
+/*
+ * Perform diagnostic checks on the state of the kernel stack.
+ *
+ * Check for stack overflow. If there is less than 1KB free
+ * then it has overflowed.
+ *
+ * Make sure the stack pointer contains a valid address. Valid
+ * addresses for kernel stacks are anywhere after the bss
+ * (after _ebss) and anywhere in init_thread_union (init_stack).
+ */
+#define STACK_CHECK()					\
+	mov	#(THREAD_SIZE >> 10), r0;		\
+	shll8	r0;					\
+	shll2	r0;					\
+							\
+	/* r1 = sp & (THREAD_SIZE - 1) */		\
+	mov	#-1, r1;				\
+	add	r0, r1;					\
+	and	r15, r1;				\
+							\
+	mov	#TI_SIZE, r3;				\
+	mov	#(STACK_WARN >> 8), r2;			\
+	shll8	r2;					\
+	add	r3, r2;					\
+							\
+	/* Is the stack overflowing? */			\
+	cmp/hi	r2, r1;					\
+	bf	stack_panic;				\
+							\
+	/* If sp > _ebss then we're OK. */		\
+	mov.l	.L_ebss, r1;				\
+	cmp/hi	r1, r15;				\
+	bt	1f;					\
+							\
+	/* If sp < init_stack, we're not OK. */		\
+	mov.l	.L_init_thread_union, r1;		\
+	cmp/hs	r1, r15;				\
+	bf	stack_panic;				\
+							\
+	/* If sp > init_stack && sp < _ebss, not OK. */	\
+	add	r0, r1;					\
+	cmp/hs	r1, r15;				\
+	bt	stack_panic;				\
+1:
+#else
+#define STACK_CHECK()
+#endif /* CONFIG_STACK_DEBUG */
+
 	.align 2
 	.globl	_mcount
 	.type	_mcount,@function
@@ -35,6 +86,19 @@
 	.type	mcount,@function
 _mcount:
 mcount:
+	STACK_CHECK()
+
+#ifndef CONFIG_FUNCTION_TRACER
+	rts
+	 nop
+#else
+#ifndef CONFIG_DYNAMIC_FTRACE
+	mov.l	.Lfunction_trace_stop, r0
+	mov.l	@r0, r0
+	tst	r0, r0
+	bf	ftrace_stub
+#endif
+
 	MCOUNT_ENTER()
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -52,16 +116,69 @@ mcount_call:
 	jsr	@r6
 	 nop
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	mov.l   .Lftrace_graph_return, r6
+	mov.l   .Lftrace_stub, r7
+	cmp/eq  r6, r7
+	bt      1f
+
+	mov.l   .Lftrace_graph_caller, r0
+	jmp     @r0
+	 nop
+
+1:
+	mov.l	.Lftrace_graph_entry, r6
+	mov.l	.Lftrace_graph_entry_stub, r7
+	cmp/eq	r6, r7
+	bt	skip_trace
+
+	mov.l   .Lftrace_graph_caller, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+.Lftrace_graph_return:
+	.long   ftrace_graph_return
+.Lftrace_graph_entry:
+	.long   ftrace_graph_entry
+.Lftrace_graph_entry_stub:
+	.long   ftrace_graph_entry_stub
+.Lftrace_graph_caller:
+	.long   ftrace_graph_caller
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+	.globl skip_trace
 skip_trace:
 	MCOUNT_LEAVE()
 
 	.align 2
 .Lftrace_trace_function:
-	.long	ftrace_trace_function
+	.long   ftrace_trace_function
 
 #ifdef CONFIG_DYNAMIC_FTRACE
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * NOTE: Do not move either ftrace_graph_call or ftrace_caller
+ * as this will affect the calculation of GRAPH_INSN_OFFSET.
+ */
+	.globl ftrace_graph_call
+ftrace_graph_call:
+	mov.l	.Lskip_trace, r0
+	jmp	@r0
+	 nop
+
+	.align 2
+.Lskip_trace:
+	.long	skip_trace
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
 	.globl ftrace_caller
 ftrace_caller:
+	mov.l	.Lfunction_trace_stop, r0
+	mov.l	@r0, r0
+	tst	r0, r0
+	bf	ftrace_stub
+
 	MCOUNT_ENTER()
 
 	.globl ftrace_call
@@ -70,9 +187,18 @@ ftrace_call:
 	jsr	@r6
 	 nop
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	bra	ftrace_graph_call
+	 nop
+#else
 	MCOUNT_LEAVE()
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
+	.align 2
+.Lfunction_trace_stop:
+	.long	function_trace_stop
+
 /*
  * NOTE: From here on the locations of the .Lftrace_stub label and
  * ftrace_stub itself are fixed. Adding additional data here will skew
@@ -80,7 +206,6 @@ ftrace_call:
  * Place new labels either after the ftrace_stub body, or before
  * ftrace_caller. You have been warned.
  */
-	.align 2
 .Lftrace_stub:
 	.long	ftrace_stub
 
@@ -88,3 +213,98 @@ ftrace_call:
 ftrace_stub:
 	rts
 	 nop
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	.globl	ftrace_graph_caller
+ftrace_graph_caller:
+	mov.l	2f, r0
+	mov.l	@r0, r0
+	tst	r0, r0
+	bt	1f
+
+	mov.l	3f, r1
+	jmp	@r1
+	 nop
+1:
+	/*
+	 * MCOUNT_ENTER() pushed 5 registers onto the stack, so
+	 * the stack address containing our return address is
+	 * r15 + 20.
+	 */
+	mov	#20, r0
+	add	r15, r0
+	mov	r0, r4
+
+	mov.l	.Lprepare_ftrace_return, r0
+	jsr	@r0
+	 nop
+
+	MCOUNT_LEAVE()
+
+	.align 2
+2:	.long	function_trace_stop
+3:	.long	skip_trace
+.Lprepare_ftrace_return:
+	.long	prepare_ftrace_return
+
+	.globl	return_to_handler
+return_to_handler:
+	/*
+	 * Save the return values.
+	 */
+	mov.l	r0, @-r15
+	mov.l	r1, @-r15
+
+	mov	#0, r4
+
+	mov.l	.Lftrace_return_to_handler, r0
+	jsr	@r0
+	 nop
+
+	/*
+	 * The return value from ftrace_return_handler has the real
+	 * address that we should return to.
+	 */
+	lds	r0, pr
+	mov.l	@r15+, r1
+	rts
+	 mov.l	@r15+, r0
+
+
+	.align 2
+.Lftrace_return_to_handler:
+	.long	ftrace_return_to_handler
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+#endif /* CONFIG_FUNCTION_TRACER */
+
+#ifdef CONFIG_STACK_DEBUG
+	.globl	stack_panic
+stack_panic:
+	mov.l	.Ldump_stack, r0
+	jsr	@r0
+	 nop
+
+	mov.l	.Lpanic, r0
+	jsr	@r0
+	 mov.l	.Lpanic_s, r4
+
+	rts
+	 nop
+
+	.align 2
+.L_ebss:
+	.long	_ebss
+.L_init_thread_union:
+	.long	init_thread_union
+.Lpanic:
+	.long	panic
+.Lpanic_s:
+	.long	.Lpanic_str
+.Ldump_stack:
+	.long	dump_stack
+
+	.section	.rodata
+	.align 2
+.Lpanic_str:
+	.string "Stack error"
+#endif /* CONFIG_STACK_DEBUG */
diff --git a/arch/sh/lib64/Makefile b/arch/sh/lib64/Makefile
index 334bb2d..1fee75a 100644
--- a/arch/sh/lib64/Makefile
+++ b/arch/sh/lib64/Makefile
@@ -11,7 +11,7 @@
 
 # Panic should really be compiled as PIC
 lib-y  := udelay.o dbg.o panic.o memcpy.o memset.o \
-	  copy_user_memcpy.o copy_page.o clear_page.o strcpy.o strlen.o
+	  copy_user_memcpy.o copy_page.o strcpy.o strlen.o
 
 # Extracted from libgcc
 lib-y	+= udivsi3.o udivdi3.o sdivsi3.o
diff --git a/arch/sh/lib64/clear_page.S b/arch/sh/lib64/clear_page.S
deleted file mode 100644
index 007ab48..0000000
--- a/arch/sh/lib64/clear_page.S
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-   Copyright 2003 Richard Curnow, SuperH (UK) Ltd.
-
-   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.
-
-   Tight version of memset for the case of just clearing a page.  It turns out
-   that having the alloco's spaced out slightly due to the increment/branch
-   pair causes them to contend less for access to the cache.  Similarly,
-   keeping the stores apart from the allocos causes less contention.  => Do two
-   separate loops.  Do multiple stores per loop to amortise the
-   increment/branch cost a little.
-
-   Parameters:
-   r2 : source effective address (start of page)
-
-   Always clears 4096 bytes.
-
-   Note : alloco guarded by synco to avoid TAKum03020 erratum
-
-*/
-
-	.section .text..SHmedia32,"ax"
-	.little
-
-	.balign 8
-	.global clear_page
-clear_page:
-	pta/l 1f, tr1
-	pta/l 2f, tr2
-	ptabs/l r18, tr0
-
-	movi 4096, r7
-	add  r2, r7, r7
-	add  r2, r63, r6
-1:
-	alloco r6, 0
-	synco	! TAKum03020
-	addi	r6, 32, r6
-	bgt/l	r7, r6, tr1
-
-	add  r2, r63, r6
-2:
-	st.q  r6,   0, r63
-	st.q  r6,   8, r63
-	st.q  r6,  16, r63
-	st.q  r6,  24, r63
-	addi r6, 32, r6
-	bgt/l r7, r6, tr2
-
-	blink tr0, r63
-
-
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 2795618..64dc1ad 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -82,7 +82,7 @@ config 32BIT
 
 config PMB_ENABLE
 	bool "Support 32-bit physical addressing through PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
 	select 32BIT
 	default y
 	help
@@ -97,7 +97,7 @@ choice
 
 config PMB
 	bool "PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785)
 	select 32BIT
 	help
 	  If you say Y here, physical addressing will be extended to
@@ -106,7 +106,8 @@ config PMB
 
 config PMB_FIXED
 	bool "fixed PMB"
-	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7780 || \
+	depends on MMU && EXPERIMENTAL && (CPU_SUBTYPE_SH7757 || \
+					   CPU_SUBTYPE_SH7780 || \
 					   CPU_SUBTYPE_SH7785)
 	select 32BIT
 	help
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 9f4bc3d..3759bf8 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -1,5 +1,65 @@
-ifeq ($(CONFIG_SUPERH32),y)
-include ${srctree}/arch/sh/mm/Makefile_32
-else
-include ${srctree}/arch/sh/mm/Makefile_64
+#
+# Makefile for the Linux SuperH-specific parts of the memory manager.
+#
+
+obj-y			:= cache.o init.o consistent.o mmap.o
+
+cacheops-$(CONFIG_CPU_SH2)		:= cache-sh2.o
+cacheops-$(CONFIG_CPU_SH2A)		:= cache-sh2a.o
+cacheops-$(CONFIG_CPU_SH3)		:= cache-sh3.o
+cacheops-$(CONFIG_CPU_SH4)		:= cache-sh4.o flush-sh4.o
+cacheops-$(CONFIG_CPU_SH5)		:= cache-sh5.o flush-sh4.o
+cacheops-$(CONFIG_SH7705_CACHE_32KB)	+= cache-sh7705.o
+
+obj-y			+= $(cacheops-y)
+
+mmu-y			:= nommu.o extable_32.o
+mmu-$(CONFIG_MMU)	:= extable_$(BITS).o fault_$(BITS).o \
+			   ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o
+
+obj-y			+= $(mmu-y)
+obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
+
+ifdef CONFIG_DEBUG_FS
+obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
 endif
+
+ifdef CONFIG_MMU
+tlb-$(CONFIG_CPU_SH3)		:= tlb-sh3.o
+tlb-$(CONFIG_CPU_SH4)		:= tlb-sh4.o
+tlb-$(CONFIG_CPU_SH5)		:= tlb-sh5.o
+tlb-$(CONFIG_CPU_HAS_PTEAEX)	:= tlb-pteaex.o
+obj-y				+= $(tlb-y)
+endif
+
+obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+obj-$(CONFIG_PMB)		+= pmb.o
+obj-$(CONFIG_PMB_FIXED)		+= pmb-fixed.o
+obj-$(CONFIG_NUMA)		+= numa.o
+
+# Special flags for fault_64.o.  This puts restrictions on the number of
+# caller-save registers that the compiler can target when building this file.
+# This is required because the code is called from a context in entry.S where
+# very few registers have been saved in the exception handler (for speed
+# reasons).
+# The caller save registers that have been saved and which can be used are
+# r2,r3,r4,r5 : argument passing
+# r15, r18 : SP and LINK
+# tr0-4 : allow all caller-save TR's.  The compiler seems to be able to make
+#         use of them, so it's probably beneficial to performance to save them
+#         and have them available for it.
+#
+# The resources not listed below are callee save, i.e. the compiler is free to
+# use any of them and will spill them to the stack itself.
+
+CFLAGS_fault_64.o += -ffixed-r7 \
+	-ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \
+	-ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \
+	-ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \
+	-ffixed-r24 -ffixed-r25 -ffixed-r26 -ffixed-r27 \
+	-ffixed-r36 -ffixed-r37 -ffixed-r38 -ffixed-r39 -ffixed-r40 \
+	-ffixed-r41 -ffixed-r42 -ffixed-r43  \
+	-ffixed-r60 -ffixed-r61 -ffixed-r62 \
+	-fomit-frame-pointer
+
+EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Makefile_32 b/arch/sh/mm/Makefile_32
deleted file mode 100644
index 986a1e0..0000000
--- a/arch/sh/mm/Makefile_32
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Makefile for the Linux SuperH-specific parts of the memory manager.
-#
-
-obj-y			:= init.o extable_32.o consistent.o mmap.o
-
-ifndef CONFIG_CACHE_OFF
-cache-$(CONFIG_CPU_SH2)		:= cache-sh2.o
-cache-$(CONFIG_CPU_SH2A)	:= cache-sh2a.o
-cache-$(CONFIG_CPU_SH3)		:= cache-sh3.o
-cache-$(CONFIG_CPU_SH4)		:= cache-sh4.o
-cache-$(CONFIG_SH7705_CACHE_32KB)	+= cache-sh7705.o
-endif
-
-obj-y			+= $(cache-y)
-
-mmu-y			:= tlb-nommu.o pg-nommu.o
-mmu-$(CONFIG_MMU)	:= fault_32.o tlbflush_32.o ioremap_32.o
-
-obj-y			+= $(mmu-y)
-obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
-
-ifdef CONFIG_DEBUG_FS
-obj-$(CONFIG_CPU_SH4)	+= cache-debugfs.o
-endif
-
-ifdef CONFIG_MMU
-tlb-$(CONFIG_CPU_SH3)		:= tlb-sh3.o
-tlb-$(CONFIG_CPU_SH4)		:= tlb-sh4.o
-tlb-$(CONFIG_CPU_HAS_PTEAEX)	:= tlb-pteaex.o
-obj-y				+= $(tlb-y)
-ifndef CONFIG_CACHE_OFF
-obj-$(CONFIG_CPU_SH4)		+= pg-sh4.o
-obj-$(CONFIG_SH7705_CACHE_32KB)	+= pg-sh7705.o
-endif
-endif
-
-obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_PMB)		+= pmb.o
-obj-$(CONFIG_PMB_FIXED)		+= pmb-fixed.o
-obj-$(CONFIG_NUMA)		+= numa.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/mm/Makefile_64 b/arch/sh/mm/Makefile_64
deleted file mode 100644
index 2863ffb..0000000
--- a/arch/sh/mm/Makefile_64
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Makefile for the Linux SuperH-specific parts of the memory manager.
-#
-
-obj-y			:= init.o consistent.o mmap.o
-
-mmu-y			:= tlb-nommu.o pg-nommu.o extable_32.o
-mmu-$(CONFIG_MMU)	:= fault_64.o ioremap_64.o tlbflush_64.o tlb-sh5.o \
-			   extable_64.o
-
-ifndef CONFIG_CACHE_OFF
-obj-y			+= cache-sh5.o
-endif
-
-obj-y			+= $(mmu-y)
-obj-$(CONFIG_DEBUG_FS)	+= asids-debugfs.o
-
-obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
-obj-$(CONFIG_NUMA)		+= numa.o
-
-EXTRA_CFLAGS += -Werror
-
-# Special flags for fault_64.o.  This puts restrictions on the number of
-# caller-save registers that the compiler can target when building this file.
-# This is required because the code is called from a context in entry.S where
-# very few registers have been saved in the exception handler (for speed
-# reasons).
-# The caller save registers that have been saved and which can be used are
-# r2,r3,r4,r5 : argument passing
-# r15, r18 : SP and LINK
-# tr0-4 : allow all caller-save TR's.  The compiler seems to be able to make
-#         use of them, so it's probably beneficial to performance to save them
-#         and have them available for it.
-#
-# The resources not listed below are callee save, i.e. the compiler is free to
-# use any of them and will spill them to the stack itself.
-
-CFLAGS_fault_64.o += -ffixed-r7 \
-	-ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12 \
-	-ffixed-r13 -ffixed-r14 -ffixed-r16 -ffixed-r17 -ffixed-r19 \
-	-ffixed-r20 -ffixed-r21 -ffixed-r22 -ffixed-r23 \
-	-ffixed-r24 -ffixed-r25 -ffixed-r26 -ffixed-r27 \
-	-ffixed-r36 -ffixed-r37 -ffixed-r38 -ffixed-r39 -ffixed-r40 \
-	-ffixed-r41 -ffixed-r42 -ffixed-r43  \
-	-ffixed-r60 -ffixed-r61 -ffixed-r62 \
-	-fomit-frame-pointer
diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c
index c4e80d2..699a71f 100644
--- a/arch/sh/mm/cache-sh2.c
+++ b/arch/sh/mm/cache-sh2.c
@@ -16,7 +16,7 @@
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 
-void __flush_wback_region(void *start, int size)
+static void sh2__flush_wback_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -37,7 +37,7 @@ void __flush_wback_region(void *start, int size)
 	}
 }
 
-void __flush_purge_region(void *start, int size)
+static void sh2__flush_purge_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -51,7 +51,7 @@ void __flush_purge_region(void *start, int size)
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 }
 
-void __flush_invalidate_region(void *start, int size)
+static void sh2__flush_invalidate_region(void *start, int size)
 {
 #ifdef CONFIG_CACHE_WRITEBACK
 	/*
@@ -82,3 +82,10 @@ void __flush_invalidate_region(void *start, int size)
 			  CACHE_OC_ADDRESS_ARRAY | (v & 0x00000ff0) | 0x00000008);
 #endif
 }
+
+void __init sh2_cache_init(void)
+{
+	__flush_wback_region		= sh2__flush_wback_region;
+	__flush_purge_region		= sh2__flush_purge_region;
+	__flush_invalidate_region	= sh2__flush_invalidate_region;
+}
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index 24d86a7..975899d 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -15,7 +15,7 @@
 #include <asm/cacheflush.h>
 #include <asm/io.h>
 
-void __flush_wback_region(void *start, int size)
+static void sh2a__flush_wback_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -44,7 +44,7 @@ void __flush_wback_region(void *start, int size)
 	local_irq_restore(flags);
 }
 
-void __flush_purge_region(void *start, int size)
+static void sh2a__flush_purge_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -65,7 +65,7 @@ void __flush_purge_region(void *start, int size)
 	local_irq_restore(flags);
 }
 
-void __flush_invalidate_region(void *start, int size)
+static void sh2a__flush_invalidate_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -97,13 +97,15 @@ void __flush_invalidate_region(void *start, int size)
 }
 
 /* WBack O-Cache and flush I-Cache */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh2a_flush_icache_range(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long start, end;
 	unsigned long v;
 	unsigned long flags;
 
-	start = start & ~(L1_CACHE_BYTES-1);
-	end = (end + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
+	start = data->addr1 & ~(L1_CACHE_BYTES-1);
+	end = (data->addr2 + L1_CACHE_BYTES-1) & ~(L1_CACHE_BYTES-1);
 
 	local_irq_save(flags);
 	jump_to_uncached();
@@ -127,3 +129,12 @@ void flush_icache_range(unsigned long start, unsigned long end)
 	back_to_cached();
 	local_irq_restore(flags);
 }
+
+void __init sh2a_cache_init(void)
+{
+	local_flush_icache_range	= sh2a_flush_icache_range;
+
+	__flush_wback_region		= sh2a__flush_wback_region;
+	__flush_purge_region		= sh2a__flush_purge_region;
+	__flush_invalidate_region	= sh2a__flush_invalidate_region;
+}
diff --git a/arch/sh/mm/cache-sh3.c b/arch/sh/mm/cache-sh3.c
index 6d1dbec..faef80c 100644
--- a/arch/sh/mm/cache-sh3.c
+++ b/arch/sh/mm/cache-sh3.c
@@ -32,7 +32,7 @@
  * SIZE: Size of the region.
  */
 
-void __flush_wback_region(void *start, int size)
+static void sh3__flush_wback_region(void *start, int size)
 {
 	unsigned long v, j;
 	unsigned long begin, end;
@@ -71,7 +71,7 @@ void __flush_wback_region(void *start, int size)
  * START: Virtual Address (U0, P1, or P3)
  * SIZE: Size of the region.
  */
-void __flush_purge_region(void *start, int size)
+static void sh3__flush_purge_region(void *start, int size)
 {
 	unsigned long v;
 	unsigned long begin, end;
@@ -90,11 +90,16 @@ void __flush_purge_region(void *start, int size)
 	}
 }
 
-/*
- * No write back please
- *
- * Except I don't think there's any way to avoid the writeback. So we
- * just alias it to __flush_purge_region(). dwmw2.
- */
-void __flush_invalidate_region(void *start, int size)
-	__attribute__((alias("__flush_purge_region")));
+void __init sh3_cache_init(void)
+{
+	__flush_wback_region = sh3__flush_wback_region;
+	__flush_purge_region = sh3__flush_purge_region;
+
+	/*
+	 * No write back please
+	 *
+	 * Except I don't think there's any way to avoid the writeback.
+	 * So we just alias it to sh3__flush_purge_region(). dwmw2.
+	 */
+	__flush_invalidate_region = sh3__flush_purge_region;
+}
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 5cfe08d..b2453bb 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/io.h>
 #include <linux/mutex.h>
+#include <linux/fs.h>
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
@@ -25,13 +26,6 @@
 #define MAX_DCACHE_PAGES	64	/* XXX: Tune for ways */
 #define MAX_ICACHE_PAGES	32
 
-static void __flush_dcache_segment_1way(unsigned long start,
-					unsigned long extent);
-static void __flush_dcache_segment_2way(unsigned long start,
-					unsigned long extent);
-static void __flush_dcache_segment_4way(unsigned long start,
-					unsigned long extent);
-
 static void __flush_cache_4096(unsigned long addr, unsigned long phys,
 			       unsigned long exec_offset);
 
@@ -43,182 +37,56 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys,
 static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
 	(void (*)(unsigned long, unsigned long))0xdeadbeef;
 
-static void compute_alias(struct cache_info *c)
+/*
+ * Write back the range of D-cache, and purge the I-cache.
+ *
+ * Called from kernel/module.c:sys_init_module and routine for a.out format,
+ * signal handler code and kprobes code
+ */
+static void sh4_flush_icache_range(void *args)
 {
-	c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1);
-	c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0;
-}
+	struct flusher_data *data = args;
+	unsigned long start, end;
+	unsigned long flags, v;
+	int i;
 
-static void __init emit_cache_params(void)
-{
-	printk("PVR=%08x CVR=%08x PRR=%08x\n",
-		ctrl_inl(CCN_PVR),
-		ctrl_inl(CCN_CVR),
-		ctrl_inl(CCN_PRR));
-	printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-		boot_cpu_data.icache.ways,
-		boot_cpu_data.icache.sets,
-		boot_cpu_data.icache.way_incr);
-	printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-		boot_cpu_data.icache.entry_mask,
-		boot_cpu_data.icache.alias_mask,
-		boot_cpu_data.icache.n_aliases);
-	printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-		boot_cpu_data.dcache.ways,
-		boot_cpu_data.dcache.sets,
-		boot_cpu_data.dcache.way_incr);
-	printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-		boot_cpu_data.dcache.entry_mask,
-		boot_cpu_data.dcache.alias_mask,
-		boot_cpu_data.dcache.n_aliases);
+	start = data->addr1;
+	end = data->addr2;
 
-	/*
-	 * Emit Secondary Cache parameters if the CPU has a probed L2.
-	 */
-	if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
-		printk("S-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-			boot_cpu_data.scache.ways,
-			boot_cpu_data.scache.sets,
-			boot_cpu_data.scache.way_incr);
-		printk("S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-			boot_cpu_data.scache.entry_mask,
-			boot_cpu_data.scache.alias_mask,
-			boot_cpu_data.scache.n_aliases);
+	/* If there are too many pages then just blow away the caches */
+	if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
+		local_flush_cache_all(NULL);
+		return;
 	}
 
-	if (!__flush_dcache_segment_fn)
-		panic("unknown number of cache ways\n");
-}
+	/*
+	 * Selectively flush d-cache then invalidate the i-cache.
+	 * This is inefficient, so only use this for small ranges.
+	 */
+	start &= ~(L1_CACHE_BYTES-1);
+	end += L1_CACHE_BYTES-1;
+	end &= ~(L1_CACHE_BYTES-1);
 
-/*
- * SH-4 has virtually indexed and physically tagged cache.
- */
-void __init p3_cache_init(void)
-{
-	compute_alias(&boot_cpu_data.icache);
-	compute_alias(&boot_cpu_data.dcache);
-	compute_alias(&boot_cpu_data.scache);
-
-	switch (boot_cpu_data.dcache.ways) {
-	case 1:
-		__flush_dcache_segment_fn = __flush_dcache_segment_1way;
-		break;
-	case 2:
-		__flush_dcache_segment_fn = __flush_dcache_segment_2way;
-		break;
-	case 4:
-		__flush_dcache_segment_fn = __flush_dcache_segment_4way;
-		break;
-	default:
-		__flush_dcache_segment_fn = NULL;
-		break;
-	}
+	local_irq_save(flags);
+	jump_to_uncached();
 
-	emit_cache_params();
-}
+	for (v = start; v < end; v += L1_CACHE_BYTES) {
+		unsigned long icacheaddr;
 
-/*
- * Write back the dirty D-caches, but not invalidate them.
- *
- * START: Virtual Address (U0, P1, or P3)
- * SIZE: Size of the region.
- */
-void __flush_wback_region(void *start, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-
-	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
-	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
-		& ~(L1_CACHE_BYTES-1);
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbwb	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
-	}
-}
+		__ocbwb(v);
 
-/*
- * Write back the dirty D-caches and invalidate them.
- *
- * START: Virtual Address (U0, P1, or P3)
- * SIZE: Size of the region.
- */
-void __flush_purge_region(void *start, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-
-	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
-	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
-		& ~(L1_CACHE_BYTES-1);
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbp	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
-	}
-}
+		icacheaddr = CACHE_IC_ADDRESS_ARRAY | (v &
+				cpu_data->icache.entry_mask);
 
-/*
- * No write back please
- */
-void __flush_invalidate_region(void *start, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-
-	begin = (unsigned long)start & ~(L1_CACHE_BYTES-1);
-	end = ((unsigned long)start + size + L1_CACHE_BYTES-1)
-		& ~(L1_CACHE_BYTES-1);
-	for (v = begin; v < end; v+=L1_CACHE_BYTES) {
-		asm volatile("ocbi	%0"
-			     : /* no output */
-			     : "m" (__m(v)));
+		/* Clear i-cache line valid-bit */
+		for (i = 0; i < cpu_data->icache.ways; i++) {
+			__raw_writel(0, icacheaddr);
+			icacheaddr += cpu_data->icache.way_incr;
+		}
 	}
-}
-
-/*
- * Write back the range of D-cache, and purge the I-cache.
- *
- * Called from kernel/module.c:sys_init_module and routine for a.out format,
- * signal handler code and kprobes code
- */
-void flush_icache_range(unsigned long start, unsigned long end)
-{
-	int icacheaddr;
-	unsigned long flags, v;
-	int i;
 
-       /* If there are too many pages then just blow the caches */
-        if (((end - start) >> PAGE_SHIFT) >= MAX_ICACHE_PAGES) {
-                flush_cache_all();
-       } else {
-               /* selectively flush d-cache then invalidate the i-cache */
-               /* this is inefficient, so only use for small ranges */
-               start &= ~(L1_CACHE_BYTES-1);
-               end += L1_CACHE_BYTES-1;
-               end &= ~(L1_CACHE_BYTES-1);
-
-               local_irq_save(flags);
-               jump_to_uncached();
-
-               for (v = start; v < end; v+=L1_CACHE_BYTES) {
-                       asm volatile("ocbwb     %0"
-                                    : /* no output */
-                                    : "m" (__m(v)));
-
-                       icacheaddr = CACHE_IC_ADDRESS_ARRAY | (
-                                       v & cpu_data->icache.entry_mask);
-
-                       for (i = 0; i < cpu_data->icache.ways;
-                               i++, icacheaddr += cpu_data->icache.way_incr)
-                                       /* Clear i-cache line valid-bit */
-                                       ctrl_outl(0, icacheaddr);
-               }
-
-		back_to_cached();
-		local_irq_restore(flags);
-	}
+	back_to_cached();
+	local_irq_restore(flags);
 }
 
 static inline void flush_cache_4096(unsigned long start,
@@ -244,9 +112,17 @@ static inline void flush_cache_4096(unsigned long start,
  * Write back & invalidate the D-cache of the page.
  * (To avoid "alias" issues)
  */
-void flush_dcache_page(struct page *page)
+static void sh4_flush_dcache_page(void *arg)
 {
-	if (test_bit(PG_mapped, &page->flags)) {
+	struct page *page = arg;
+#ifndef CONFIG_SMP
+	struct address_space *mapping = page_mapping(page);
+
+	if (mapping && !mapping_mapped(mapping))
+		set_bit(PG_dcache_dirty, &page->flags);
+	else
+#endif
+	{
 		unsigned long phys = PHYSADDR(page_address(page));
 		unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
 		int i, n;
@@ -282,13 +158,13 @@ static void __uses_jump_to_uncached flush_icache_all(void)
 	local_irq_restore(flags);
 }
 
-void flush_dcache_all(void)
+static inline void flush_dcache_all(void)
 {
 	(*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);
 	wmb();
 }
 
-void flush_cache_all(void)
+static void sh4_flush_cache_all(void *unused)
 {
 	flush_dcache_all();
 	flush_icache_all();
@@ -380,8 +256,13 @@ loop_exit:
  *
  * Caller takes mm->mmap_sem.
  */
-void flush_cache_mm(struct mm_struct *mm)
+static void sh4_flush_cache_mm(void *arg)
 {
+	struct mm_struct *mm = arg;
+
+	if (cpu_context(smp_processor_id(), mm) == NO_CONTEXT)
+		return;
+
 	/*
 	 * If cache is only 4k-per-way, there are never any 'aliases'.  Since
 	 * the cache is physically tagged, the data can just be left in there.
@@ -417,12 +298,21 @@ void flush_cache_mm(struct mm_struct *mm)
  * ADDR: Virtual Address (U0 address)
  * PFN: Physical page number
  */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
-		      unsigned long pfn)
+static void sh4_flush_cache_page(void *args)
 {
-	unsigned long phys = pfn << PAGE_SHIFT;
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long address, pfn, phys;
 	unsigned int alias_mask;
 
+	vma = data->vma;
+	address = data->addr1;
+	pfn = data->addr2;
+	phys = pfn << PAGE_SHIFT;
+
+	if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
+		return;
+
 	alias_mask = boot_cpu_data.dcache.alias_mask;
 
 	/* We only need to flush D-cache when we have alias */
@@ -462,9 +352,19 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
  * Flushing the cache lines for U0 only isn't enough.
  * We need to flush for P1 too, which may contain aliases.
  */
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end)
+static void sh4_flush_cache_range(void *args)
 {
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long start, end;
+
+	vma = data->vma;
+	start = data->addr1;
+	end = data->addr2;
+
+	if (cpu_context(smp_processor_id(), vma->vm_mm) == NO_CONTEXT)
+		return;
+
 	/*
 	 * If cache is only 4k-per-way, there are never any 'aliases'.  Since
 	 * the cache is physically tagged, the data can just be left in there.
@@ -492,20 +392,6 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
 	}
 }
 
-/*
- * flush_icache_user_range
- * @vma: VMA of the process
- * @page: page
- * @addr: U0 address
- * @len: length of the range (< page size)
- */
-void flush_icache_user_range(struct vm_area_struct *vma,
-			     struct page *page, unsigned long addr, int len)
-{
-	flush_cache_page(vma, addr, page_to_pfn(page));
-	mb();
-}
-
 /**
  * __flush_cache_4096
  *
@@ -581,7 +467,49 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys,
  * Break the 1, 2 and 4 way variants of this out into separate functions to
  * avoid nearly all the overhead of having the conditional stuff in the function
  * bodies (+ the 1 and 2 way cases avoid saving any registers too).
+ *
+ * We want to eliminate unnecessary bus transactions, so this code uses
+ * a non-obvious technique.
+ *
+ * Loop over a cache way sized block of, one cache line at a time. For each
+ * line, use movca.a to cause the current cache line contents to be written
+ * back, but without reading anything from main memory. However this has the
+ * side effect that the cache is now caching that memory location. So follow
+ * this with a cache invalidate to mark the cache line invalid. And do all
+ * this with interrupts disabled, to avoid the cache line being accidently
+ * evicted while it is holding garbage.
+ *
+ * This also breaks in a number of circumstances:
+ * - if there are modifications to the region of memory just above
+ *   empty_zero_page (for example because a breakpoint has been placed
+ *   there), then these can be lost.
+ *
+ *   This is because the the memory address which the cache temporarily
+ *   caches in the above description is empty_zero_page. So the
+ *   movca.l hits the cache (it is assumed that it misses, or at least
+ *   isn't dirty), modifies the line and then invalidates it, losing the
+ *   required change.
+ *
+ * - If caches are disabled or configured in write-through mode, then
+ *   the movca.l writes garbage directly into memory.
  */
+static void __flush_dcache_segment_writethrough(unsigned long start,
+					        unsigned long extent_per_way)
+{
+	unsigned long addr;
+	int i;
+
+	addr = CACHE_OC_ADDRESS_ARRAY | (start & cpu_data->dcache.entry_mask);
+
+	while (extent_per_way) {
+		for (i = 0; i < cpu_data->dcache.ways; i++)
+			__raw_writel(0, addr + cpu_data->dcache.way_incr * i);
+
+		addr += cpu_data->dcache.linesz;
+		extent_per_way -= cpu_data->dcache.linesz;
+	}
+}
+
 static void __flush_dcache_segment_1way(unsigned long start,
 					unsigned long extent_per_way)
 {
@@ -773,3 +701,47 @@ static void __flush_dcache_segment_4way(unsigned long start,
 		a3 += linesz;
 	} while (a0 < a0e);
 }
+
+extern void __weak sh4__flush_region_init(void);
+
+/*
+ * SH-4 has virtually indexed and physically tagged cache.
+ */
+void __init sh4_cache_init(void)
+{
+	unsigned int wt_enabled = !!(__raw_readl(CCR) & CCR_CACHE_WT);
+
+	printk("PVR=%08x CVR=%08x PRR=%08x\n",
+		ctrl_inl(CCN_PVR),
+		ctrl_inl(CCN_CVR),
+		ctrl_inl(CCN_PRR));
+
+	if (wt_enabled)
+		__flush_dcache_segment_fn = __flush_dcache_segment_writethrough;
+	else {
+		switch (boot_cpu_data.dcache.ways) {
+		case 1:
+			__flush_dcache_segment_fn = __flush_dcache_segment_1way;
+			break;
+		case 2:
+			__flush_dcache_segment_fn = __flush_dcache_segment_2way;
+			break;
+		case 4:
+			__flush_dcache_segment_fn = __flush_dcache_segment_4way;
+			break;
+		default:
+			panic("unknown number of cache ways\n");
+			break;
+		}
+	}
+
+	local_flush_icache_range	= sh4_flush_icache_range;
+	local_flush_dcache_page		= sh4_flush_dcache_page;
+	local_flush_cache_all		= sh4_flush_cache_all;
+	local_flush_cache_mm		= sh4_flush_cache_mm;
+	local_flush_cache_dup_mm	= sh4_flush_cache_mm;
+	local_flush_cache_page		= sh4_flush_cache_page;
+	local_flush_cache_range		= sh4_flush_cache_range;
+
+	sh4__flush_region_init();
+}
diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c
index 8676209..467ff8e 100644
--- a/arch/sh/mm/cache-sh5.c
+++ b/arch/sh/mm/cache-sh5.c
@@ -20,23 +20,11 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 
+extern void __weak sh4__flush_region_init(void);
+
 /* Wired TLB entry for the D-cache */
 static unsigned long long dtlb_cache_slot;
 
-void __init p3_cache_init(void)
-{
-	/* Reserve a slot for dcache colouring in the DTLB */
-	dtlb_cache_slot	= sh64_get_wired_dtlb_entry();
-}
-
-#ifdef CONFIG_DCACHE_DISABLED
-#define sh64_dcache_purge_all()					do { } while (0)
-#define sh64_dcache_purge_coloured_phy_page(paddr, eaddr)	do { } while (0)
-#define sh64_dcache_purge_user_range(mm, start, end)		do { } while (0)
-#define sh64_dcache_purge_phy_page(paddr)			do { } while (0)
-#define sh64_dcache_purge_virt_page(mm, eaddr)			do { } while (0)
-#endif
-
 /*
  * The following group of functions deal with mapping and unmapping a
  * temporary page into a DTLB slot that has been set aside for exclusive
@@ -56,7 +44,6 @@ static inline void sh64_teardown_dtlb_cache_slot(void)
 	local_irq_enable();
 }
 
-#ifndef CONFIG_ICACHE_DISABLED
 static inline void sh64_icache_inv_all(void)
 {
 	unsigned long long addr, flag, data;
@@ -214,52 +201,6 @@ static void sh64_icache_inv_user_page_range(struct mm_struct *mm,
 	}
 }
 
-/*
- * Invalidate a small range of user context I-cache, not necessarily page
- * (or even cache-line) aligned.
- *
- * Since this is used inside ptrace, the ASID in the mm context typically
- * won't match current_asid.  We'll have to switch ASID to do this.  For
- * safety, and given that the range will be small, do all this under cli.
- *
- * Note, there is a hazard that the ASID in mm->context is no longer
- * actually associated with mm, i.e. if the mm->context has started a new
- * cycle since mm was last active.  However, this is just a performance
- * issue: all that happens is that we invalidate lines belonging to
- * another mm, so the owning process has to refill them when that mm goes
- * live again.  mm itself can't have any cache entries because there will
- * have been a flush_cache_all when the new mm->context cycle started.
- */
-static void sh64_icache_inv_user_small_range(struct mm_struct *mm,
-						unsigned long start, int len)
-{
-	unsigned long long eaddr = start;
-	unsigned long long eaddr_end = start + len;
-	unsigned long current_asid, mm_asid;
-	unsigned long flags;
-	unsigned long long epage_start;
-
-	/*
-	 * Align to start of cache line.  Otherwise, suppose len==8 and
-	 * start was at 32N+28 : the last 4 bytes wouldn't get invalidated.
-	 */
-	eaddr = L1_CACHE_ALIGN(start);
-	eaddr_end = start + len;
-
-	mm_asid = cpu_asid(smp_processor_id(), mm);
-	local_irq_save(flags);
-	current_asid = switch_and_save_asid(mm_asid);
-
-	epage_start = eaddr & PAGE_MASK;
-
-	while (eaddr < eaddr_end) {
-		__asm__ __volatile__("icbi %0, 0" : : "r" (eaddr));
-		eaddr += L1_CACHE_BYTES;
-	}
-	switch_and_save_asid(current_asid);
-	local_irq_restore(flags);
-}
-
 static void sh64_icache_inv_current_user_range(unsigned long start, unsigned long end)
 {
 	/* The icbi instruction never raises ITLBMISS.  i.e. if there's not a
@@ -287,9 +228,7 @@ static void sh64_icache_inv_current_user_range(unsigned long start, unsigned lon
 		addr += L1_CACHE_BYTES;
 	}
 }
-#endif /* !CONFIG_ICACHE_DISABLED */
 
-#ifndef CONFIG_DCACHE_DISABLED
 /* Buffer used as the target of alloco instructions to purge data from cache
    sets by natural eviction. -- RPC */
 #define DUMMY_ALLOCO_AREA_SIZE ((L1_CACHE_BYTES << 10) + (1024 * 4))
@@ -541,59 +480,10 @@ static void sh64_dcache_purge_user_range(struct mm_struct *mm,
 }
 
 /*
- * Purge the range of addresses from the D-cache.
- *
- * The addresses lie in the superpage mapping. There's no harm if we
- * overpurge at either end - just a small performance loss.
- */
-void __flush_purge_region(void *start, int size)
-{
-	unsigned long long ullend, addr, aligned_start;
-
-	aligned_start = (unsigned long long)(signed long long)(signed long) start;
-	addr = L1_CACHE_ALIGN(aligned_start);
-	ullend = (unsigned long long) (signed long long) (signed long) start + size;
-
-	while (addr <= ullend) {
-		__asm__ __volatile__ ("ocbp %0, 0" : : "r" (addr));
-		addr += L1_CACHE_BYTES;
-	}
-}
-
-void __flush_wback_region(void *start, int size)
-{
-	unsigned long long ullend, addr, aligned_start;
-
-	aligned_start = (unsigned long long)(signed long long)(signed long) start;
-	addr = L1_CACHE_ALIGN(aligned_start);
-	ullend = (unsigned long long) (signed long long) (signed long) start + size;
-
-	while (addr < ullend) {
-		__asm__ __volatile__ ("ocbwb %0, 0" : : "r" (addr));
-		addr += L1_CACHE_BYTES;
-	}
-}
-
-void __flush_invalidate_region(void *start, int size)
-{
-	unsigned long long ullend, addr, aligned_start;
-
-	aligned_start = (unsigned long long)(signed long long)(signed long) start;
-	addr = L1_CACHE_ALIGN(aligned_start);
-	ullend = (unsigned long long) (signed long long) (signed long) start + size;
-
-	while (addr < ullend) {
-		__asm__ __volatile__ ("ocbi %0, 0" : : "r" (addr));
-		addr += L1_CACHE_BYTES;
-	}
-}
-#endif /* !CONFIG_DCACHE_DISABLED */
-
-/*
  * Invalidate the entire contents of both caches, after writing back to
  * memory any dirty data from the D-cache.
  */
-void flush_cache_all(void)
+static void sh5_flush_cache_all(void *unused)
 {
 	sh64_dcache_purge_all();
 	sh64_icache_inv_all();
@@ -620,7 +510,7 @@ void flush_cache_all(void)
  * I-cache.  This is similar to the lack of action needed in
  * flush_tlb_mm - see fault.c.
  */
-void flush_cache_mm(struct mm_struct *mm)
+static void sh5_flush_cache_mm(void *unused)
 {
 	sh64_dcache_purge_all();
 }
@@ -632,13 +522,18 @@ void flush_cache_mm(struct mm_struct *mm)
  *
  * Note, 'end' is 1 byte beyond the end of the range to flush.
  */
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end)
+static void sh5_flush_cache_range(void *args)
 {
-	struct mm_struct *mm = vma->vm_mm;
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long start, end;
+
+	vma = data->vma;
+	start = data->addr1;
+	end = data->addr2;
 
-	sh64_dcache_purge_user_range(mm, start, end);
-	sh64_icache_inv_user_page_range(mm, start, end);
+	sh64_dcache_purge_user_range(vma->vm_mm, start, end);
+	sh64_icache_inv_user_page_range(vma->vm_mm, start, end);
 }
 
 /*
@@ -650,16 +545,23 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
  *
  * Note, this is called with pte lock held.
  */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long eaddr,
-		      unsigned long pfn)
+static void sh5_flush_cache_page(void *args)
 {
+	struct flusher_data *data = args;
+	struct vm_area_struct *vma;
+	unsigned long eaddr, pfn;
+
+	vma = data->vma;
+	eaddr = data->addr1;
+	pfn = data->addr2;
+
 	sh64_dcache_purge_phy_page(pfn << PAGE_SHIFT);
 
 	if (vma->vm_flags & VM_EXEC)
 		sh64_icache_inv_user_page(vma, eaddr);
 }
 
-void flush_dcache_page(struct page *page)
+static void sh5_flush_dcache_page(void *page)
 {
 	sh64_dcache_purge_phy_page(page_to_phys(page));
 	wmb();
@@ -673,162 +575,47 @@ void flush_dcache_page(struct page *page)
  * mapping, therefore it's guaranteed that there no cache entries for
  * the range in cache sets of the wrong colour.
  */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh5_flush_icache_range(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long start, end;
+
+	start = data->addr1;
+	end = data->addr2;
+
 	__flush_purge_region((void *)start, end);
 	wmb();
 	sh64_icache_inv_kernel_range(start, end);
 }
 
 /*
- * Flush the range of user (defined by vma->vm_mm) address space starting
- * at 'addr' for 'len' bytes from the cache.  The range does not straddle
- * a page boundary, the unique physical page containing the range is
- * 'page'.  This seems to be used mainly for invalidating an address
- * range following a poke into the program text through the ptrace() call
- * from another process (e.g. for BRK instruction insertion).
- */
-void flush_icache_user_range(struct vm_area_struct *vma,
-			struct page *page, unsigned long addr, int len)
-{
-
-	sh64_dcache_purge_coloured_phy_page(page_to_phys(page), addr);
-	mb();
-
-	if (vma->vm_flags & VM_EXEC)
-		sh64_icache_inv_user_small_range(vma->vm_mm, addr, len);
-}
-
-/*
  * For the address range [start,end), write back the data from the
  * D-cache and invalidate the corresponding region of the I-cache for the
  * current process.  Used to flush signal trampolines on the stack to
  * make them executable.
  */
-void flush_cache_sigtramp(unsigned long vaddr)
+static void sh5_flush_cache_sigtramp(void *vaddr)
 {
-	unsigned long end = vaddr + L1_CACHE_BYTES;
+	unsigned long end = (unsigned long)vaddr + L1_CACHE_BYTES;
 
-	__flush_wback_region((void *)vaddr, L1_CACHE_BYTES);
+	__flush_wback_region(vaddr, L1_CACHE_BYTES);
 	wmb();
-	sh64_icache_inv_current_user_range(vaddr, end);
+	sh64_icache_inv_current_user_range((unsigned long)vaddr, end);
 }
 
-#ifdef CONFIG_MMU
-/*
- * These *MUST* lie in an area of virtual address space that's otherwise
- * unused.
- */
-#define UNIQUE_EADDR_START 0xe0000000UL
-#define UNIQUE_EADDR_END   0xe8000000UL
-
-/*
- * Given a physical address paddr, and a user virtual address user_eaddr
- * which will eventually be mapped to it, create a one-off kernel-private
- * eaddr mapped to the same paddr.  This is used for creating special
- * destination pages for copy_user_page and clear_user_page.
- */
-static unsigned long sh64_make_unique_eaddr(unsigned long user_eaddr,
-					    unsigned long paddr)
-{
-	static unsigned long current_pointer = UNIQUE_EADDR_START;
-	unsigned long coloured_pointer;
-
-	if (current_pointer == UNIQUE_EADDR_END) {
-		sh64_dcache_purge_all();
-		current_pointer = UNIQUE_EADDR_START;
-	}
-
-	coloured_pointer = (current_pointer & ~CACHE_OC_SYN_MASK) |
-				(user_eaddr & CACHE_OC_SYN_MASK);
-	sh64_setup_dtlb_cache_slot(coloured_pointer, get_asid(), paddr);
-
-	current_pointer += (PAGE_SIZE << CACHE_OC_N_SYNBITS);
-
-	return coloured_pointer;
-}
-
-static void sh64_copy_user_page_coloured(void *to, void *from,
-					 unsigned long address)
+void __init sh5_cache_init(void)
 {
-	void *coloured_to;
+	local_flush_cache_all		= sh5_flush_cache_all;
+	local_flush_cache_mm		= sh5_flush_cache_mm;
+	local_flush_cache_dup_mm	= sh5_flush_cache_mm;
+	local_flush_cache_page		= sh5_flush_cache_page;
+	local_flush_cache_range		= sh5_flush_cache_range;
+	local_flush_dcache_page		= sh5_flush_dcache_page;
+	local_flush_icache_range	= sh5_flush_icache_range;
+	local_flush_cache_sigtramp	= sh5_flush_cache_sigtramp;
 
-	/*
-	 * Discard any existing cache entries of the wrong colour.  These are
-	 * present quite often, if the kernel has recently used the page
-	 * internally, then given it up, then it's been allocated to the user.
-	 */
-	sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long)to);
-
-	coloured_to = (void *)sh64_make_unique_eaddr(address, __pa(to));
-	copy_page(from, coloured_to);
-
-	sh64_teardown_dtlb_cache_slot();
-}
-
-static void sh64_clear_user_page_coloured(void *to, unsigned long address)
-{
-	void *coloured_to;
-
-	/*
-	 * Discard any existing kernel-originated lines of the wrong
-	 * colour (as above)
-	 */
-	sh64_dcache_purge_coloured_phy_page(__pa(to), (unsigned long)to);
-
-	coloured_to = (void *)sh64_make_unique_eaddr(address, __pa(to));
-	clear_page(coloured_to);
-
-	sh64_teardown_dtlb_cache_slot();
-}
-
-/*
- * 'from' and 'to' are kernel virtual addresses (within the superpage
- * mapping of the physical RAM).  'address' is the user virtual address
- * where the copy 'to' will be mapped after.  This allows a custom
- * mapping to be used to ensure that the new copy is placed in the
- * right cache sets for the user to see it without having to bounce it
- * out via memory.  Note however : the call to flush_page_to_ram in
- * (generic)/mm/memory.c:(break_cow) undoes all this good work in that one
- * very important case!
- *
- * TBD : can we guarantee that on every call, any cache entries for
- * 'from' are in the same colour sets as 'address' also?  i.e. is this
- * always used just to deal with COW?  (I suspect not).
- *
- * There are two possibilities here for when the page 'from' was last accessed:
- * - by the kernel : this is OK, no purge required.
- * - by the/a user (e.g. for break_COW) : need to purge.
- *
- * If the potential user mapping at 'address' is the same colour as
- * 'from' there is no need to purge any cache lines from the 'from'
- * page mapped into cache sets of colour 'address'.  (The copy will be
- * accessing the page through 'from').
- */
-void copy_user_page(void *to, void *from, unsigned long address,
-		    struct page *page)
-{
-	if (((address ^ (unsigned long) from) & CACHE_OC_SYN_MASK) != 0)
-		sh64_dcache_purge_coloured_phy_page(__pa(from), address);
-
-	if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0)
-		copy_page(to, from);
-	else
-		sh64_copy_user_page_coloured(to, from, address);
-}
+	/* Reserve a slot for dcache colouring in the DTLB */
+	dtlb_cache_slot	= sh64_get_wired_dtlb_entry();
 
-/*
- * 'to' is a kernel virtual address (within the superpage mapping of the
- * physical RAM).  'address' is the user virtual address where the 'to'
- * page will be mapped after.  This allows a custom mapping to be used to
- * ensure that the new copy is placed in the right cache sets for the
- * user to see it without having to bounce it out via memory.
- */
-void clear_user_page(void *to, unsigned long address, struct page *page)
-{
-	if (((address ^ (unsigned long) to) & CACHE_OC_SYN_MASK) == 0)
-		clear_page(to);
-	else
-		sh64_clear_user_page_coloured(to, address);
+	sh4__flush_region_init();
 }
-#endif
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 22dacc7..2cadee2 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
+#include <linux/fs.h>
 #include <linux/threads.h>
 #include <asm/addrspace.h>
 #include <asm/page.h>
@@ -63,15 +64,21 @@ static inline void cache_wback_all(void)
  *
  * Called from kernel/module.c:sys_init_module and routine for a.out format.
  */
-void flush_icache_range(unsigned long start, unsigned long end)
+static void sh7705_flush_icache_range(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long start, end;
+
+	start = data->addr1;
+	end = data->addr2;
+
 	__flush_wback_region((void *)start, end - start);
 }
 
 /*
  * Writeback&Invalidate the D-cache of the page
  */
-static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
+static void __flush_dcache_page(unsigned long phys)
 {
 	unsigned long ways, waysize, addrstart;
 	unsigned long flags;
@@ -126,13 +133,18 @@ static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
  * Write back & invalidate the D-cache of the page.
  * (To avoid "alias" issues)
  */
-void flush_dcache_page(struct page *page)
+static void sh7705_flush_dcache_page(void *arg)
 {
-	if (test_bit(PG_mapped, &page->flags))
+	struct page *page = arg;
+	struct address_space *mapping = page_mapping(page);
+
+	if (mapping && !mapping_mapped(mapping))
+		set_bit(PG_dcache_dirty, &page->flags);
+	else
 		__flush_dcache_page(PHYSADDR(page_address(page)));
 }
 
-void __uses_jump_to_uncached flush_cache_all(void)
+static void sh7705_flush_cache_all(void *args)
 {
 	unsigned long flags;
 
@@ -144,44 +156,16 @@ void __uses_jump_to_uncached flush_cache_all(void)
 	local_irq_restore(flags);
 }
 
-void flush_cache_mm(struct mm_struct *mm)
-{
-	/* Is there any good way? */
-	/* XXX: possibly call flush_cache_range for each vm area */
-	flush_cache_all();
-}
-
-/*
- * Write back and invalidate D-caches.
- *
- * START, END: Virtual Address (U0 address)
- *
- * NOTE: We need to flush the _physical_ page entry.
- * Flushing the cache lines for U0 only isn't enough.
- * We need to flush for P1 too, which may contain aliases.
- */
-void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
-		       unsigned long end)
-{
-
-	/*
-	 * We could call flush_cache_page for the pages of these range,
-	 * but it's not efficient (scan the caches all the time...).
-	 *
-	 * We can't use A-bit magic, as there's the case we don't have
-	 * valid entry on TLB.
-	 */
-	flush_cache_all();
-}
-
 /*
  * Write back and invalidate I/D-caches for the page.
  *
  * ADDRESS: Virtual Address (U0 address)
  */
-void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
-		      unsigned long pfn)
+static void sh7705_flush_cache_page(void *args)
 {
+	struct flusher_data *data = args;
+	unsigned long pfn = data->addr2;
+
 	__flush_dcache_page(pfn << PAGE_SHIFT);
 }
 
@@ -193,7 +177,19 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
  * Not entirely sure why this is necessary on SH3 with 32K cache but
  * without it we get occasional "Memory fault" when loading a program.
  */
-void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+static void sh7705_flush_icache_page(void *page)
 {
 	__flush_purge_region(page_address(page), PAGE_SIZE);
 }
+
+void __init sh7705_cache_init(void)
+{
+	local_flush_icache_range	= sh7705_flush_icache_range;
+	local_flush_dcache_page		= sh7705_flush_dcache_page;
+	local_flush_cache_all		= sh7705_flush_cache_all;
+	local_flush_cache_mm		= sh7705_flush_cache_all;
+	local_flush_cache_dup_mm	= sh7705_flush_cache_all;
+	local_flush_cache_range		= sh7705_flush_cache_all;
+	local_flush_cache_page		= sh7705_flush_cache_page;
+	local_flush_icache_page		= sh7705_flush_icache_page;
+}
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
new file mode 100644
index 0000000..35c37b7
--- /dev/null
+++ b/arch/sh/mm/cache.c
@@ -0,0 +1,316 @@
+/*
+ * arch/sh/mm/cache.c
+ *
+ * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
+ * Copyright (C) 2002 - 2009  Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/smp.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+void (*local_flush_cache_all)(void *args) = cache_noop;
+void (*local_flush_cache_mm)(void *args) = cache_noop;
+void (*local_flush_cache_dup_mm)(void *args) = cache_noop;
+void (*local_flush_cache_page)(void *args) = cache_noop;
+void (*local_flush_cache_range)(void *args) = cache_noop;
+void (*local_flush_dcache_page)(void *args) = cache_noop;
+void (*local_flush_icache_range)(void *args) = cache_noop;
+void (*local_flush_icache_page)(void *args) = cache_noop;
+void (*local_flush_cache_sigtramp)(void *args) = cache_noop;
+
+void (*__flush_wback_region)(void *start, int size);
+void (*__flush_purge_region)(void *start, int size);
+void (*__flush_invalidate_region)(void *start, int size);
+
+static inline void noop__flush_region(void *start, int size)
+{
+}
+
+static inline void cacheop_on_each_cpu(void (*func) (void *info), void *info,
+                                   int wait)
+{
+	preempt_disable();
+	smp_call_function(func, info, wait);
+	func(info);
+	preempt_enable();
+}
+
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+		       unsigned long vaddr, void *dst, const void *src,
+		       unsigned long len)
+{
+	if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+	    !test_bit(PG_dcache_dirty, &page->flags)) {
+		void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+		memcpy(vto, src, len);
+		kunmap_coherent(vto);
+	} else {
+		memcpy(dst, src, len);
+		if (boot_cpu_data.dcache.n_aliases)
+			set_bit(PG_dcache_dirty, &page->flags);
+	}
+
+	if (vma->vm_flags & VM_EXEC)
+		flush_cache_page(vma, vaddr, page_to_pfn(page));
+}
+
+void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+			 unsigned long vaddr, void *dst, const void *src,
+			 unsigned long len)
+{
+	if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+	    !test_bit(PG_dcache_dirty, &page->flags)) {
+		void *vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
+		memcpy(dst, vfrom, len);
+		kunmap_coherent(vfrom);
+	} else {
+		memcpy(dst, src, len);
+		if (boot_cpu_data.dcache.n_aliases)
+			set_bit(PG_dcache_dirty, &page->flags);
+	}
+}
+
+void copy_user_highpage(struct page *to, struct page *from,
+			unsigned long vaddr, struct vm_area_struct *vma)
+{
+	void *vfrom, *vto;
+
+	vto = kmap_atomic(to, KM_USER1);
+
+	if (boot_cpu_data.dcache.n_aliases && page_mapped(from) &&
+	    !test_bit(PG_dcache_dirty, &from->flags)) {
+		vfrom = kmap_coherent(from, vaddr);
+		copy_page(vto, vfrom);
+		kunmap_coherent(vfrom);
+	} else {
+		vfrom = kmap_atomic(from, KM_USER0);
+		copy_page(vto, vfrom);
+		kunmap_atomic(vfrom, KM_USER0);
+	}
+
+	if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK))
+		__flush_purge_region(vto, PAGE_SIZE);
+
+	kunmap_atomic(vto, KM_USER1);
+	/* Make sure this page is cleared on other CPU's too before using it */
+	smp_wmb();
+}
+EXPORT_SYMBOL(copy_user_highpage);
+
+void clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+	void *kaddr = kmap_atomic(page, KM_USER0);
+
+	clear_page(kaddr);
+
+	if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK))
+		__flush_purge_region(kaddr, PAGE_SIZE);
+
+	kunmap_atomic(kaddr, KM_USER0);
+}
+EXPORT_SYMBOL(clear_user_highpage);
+
+void __update_cache(struct vm_area_struct *vma,
+		    unsigned long address, pte_t pte)
+{
+	struct page *page;
+	unsigned long pfn = pte_pfn(pte);
+
+	if (!boot_cpu_data.dcache.n_aliases)
+		return;
+
+	page = pfn_to_page(pfn);
+	if (pfn_valid(pfn) && page_mapping(page)) {
+		int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
+		if (dirty) {
+			unsigned long addr = (unsigned long)page_address(page);
+
+			if (pages_do_alias(addr, address & PAGE_MASK))
+				__flush_purge_region((void *)addr, PAGE_SIZE);
+		}
+	}
+}
+
+void __flush_anon_page(struct page *page, unsigned long vmaddr)
+{
+	unsigned long addr = (unsigned long) page_address(page);
+
+	if (pages_do_alias(addr, vmaddr)) {
+		if (boot_cpu_data.dcache.n_aliases && page_mapped(page) &&
+		    !test_bit(PG_dcache_dirty, &page->flags)) {
+			void *kaddr;
+
+			kaddr = kmap_coherent(page, vmaddr);
+			/* XXX.. For now kunmap_coherent() does a purge */
+			/* __flush_purge_region((void *)kaddr, PAGE_SIZE); */
+			kunmap_coherent(kaddr);
+		} else
+			__flush_purge_region((void *)addr, PAGE_SIZE);
+	}
+}
+
+void flush_cache_all(void)
+{
+	cacheop_on_each_cpu(local_flush_cache_all, NULL, 1);
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+	cacheop_on_each_cpu(local_flush_cache_mm, mm, 1);
+}
+
+void flush_cache_dup_mm(struct mm_struct *mm)
+{
+	cacheop_on_each_cpu(local_flush_cache_dup_mm, mm, 1);
+}
+
+void flush_cache_page(struct vm_area_struct *vma, unsigned long addr,
+		      unsigned long pfn)
+{
+	struct flusher_data data;
+
+	data.vma = vma;
+	data.addr1 = addr;
+	data.addr2 = pfn;
+
+	cacheop_on_each_cpu(local_flush_cache_page, (void *)&data, 1);
+}
+
+void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
+		       unsigned long end)
+{
+	struct flusher_data data;
+
+	data.vma = vma;
+	data.addr1 = start;
+	data.addr2 = end;
+
+	cacheop_on_each_cpu(local_flush_cache_range, (void *)&data, 1);
+}
+
+void flush_dcache_page(struct page *page)
+{
+	cacheop_on_each_cpu(local_flush_dcache_page, page, 1);
+}
+
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+	struct flusher_data data;
+
+	data.vma = NULL;
+	data.addr1 = start;
+	data.addr2 = end;
+
+	cacheop_on_each_cpu(local_flush_icache_range, (void *)&data, 1);
+}
+
+void flush_icache_page(struct vm_area_struct *vma, struct page *page)
+{
+	/* Nothing uses the VMA, so just pass the struct page along */
+	cacheop_on_each_cpu(local_flush_icache_page, page, 1);
+}
+
+void flush_cache_sigtramp(unsigned long address)
+{
+	cacheop_on_each_cpu(local_flush_cache_sigtramp, (void *)address, 1);
+}
+
+static void compute_alias(struct cache_info *c)
+{
+	c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1);
+	c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0;
+}
+
+static void __init emit_cache_params(void)
+{
+	printk(KERN_NOTICE "I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
+		boot_cpu_data.icache.ways,
+		boot_cpu_data.icache.sets,
+		boot_cpu_data.icache.way_incr);
+	printk(KERN_NOTICE "I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
+		boot_cpu_data.icache.entry_mask,
+		boot_cpu_data.icache.alias_mask,
+		boot_cpu_data.icache.n_aliases);
+	printk(KERN_NOTICE "D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
+		boot_cpu_data.dcache.ways,
+		boot_cpu_data.dcache.sets,
+		boot_cpu_data.dcache.way_incr);
+	printk(KERN_NOTICE "D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
+		boot_cpu_data.dcache.entry_mask,
+		boot_cpu_data.dcache.alias_mask,
+		boot_cpu_data.dcache.n_aliases);
+
+	/*
+	 * Emit Secondary Cache parameters if the CPU has a probed L2.
+	 */
+	if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
+		printk(KERN_NOTICE "S-cache : n_ways=%d n_sets=%d way_incr=%d\n",
+			boot_cpu_data.scache.ways,
+			boot_cpu_data.scache.sets,
+			boot_cpu_data.scache.way_incr);
+		printk(KERN_NOTICE "S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
+			boot_cpu_data.scache.entry_mask,
+			boot_cpu_data.scache.alias_mask,
+			boot_cpu_data.scache.n_aliases);
+	}
+}
+
+void __init cpu_cache_init(void)
+{
+	compute_alias(&boot_cpu_data.icache);
+	compute_alias(&boot_cpu_data.dcache);
+	compute_alias(&boot_cpu_data.scache);
+
+	__flush_wback_region		= noop__flush_region;
+	__flush_purge_region		= noop__flush_region;
+	__flush_invalidate_region	= noop__flush_region;
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH2) {
+		extern void __weak sh2_cache_init(void);
+
+		sh2_cache_init();
+	}
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH2A) {
+		extern void __weak sh2a_cache_init(void);
+
+		sh2a_cache_init();
+	}
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH3) {
+		extern void __weak sh3_cache_init(void);
+
+		sh3_cache_init();
+
+		if ((boot_cpu_data.type == CPU_SH7705) &&
+		    (boot_cpu_data.dcache.sets == 512)) {
+			extern void __weak sh7705_cache_init(void);
+
+			sh7705_cache_init();
+		}
+	}
+
+	if ((boot_cpu_data.family == CPU_FAMILY_SH4) ||
+	    (boot_cpu_data.family == CPU_FAMILY_SH4A) ||
+	    (boot_cpu_data.family == CPU_FAMILY_SH4AL_DSP)) {
+		extern void __weak sh4_cache_init(void);
+
+		sh4_cache_init();
+	}
+
+	if (boot_cpu_data.family == CPU_FAMILY_SH5) {
+		extern void __weak sh5_cache_init(void);
+
+		sh5_cache_init();
+	}
+
+	emit_cache_params();
+}
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index 7192594..4753010 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -2,7 +2,7 @@
  * Page fault handler for SH with an MMU.
  *
  *  Copyright (C) 1999  Niibe Yutaka
- *  Copyright (C) 2003 - 2008  Paul Mundt
+ *  Copyright (C) 2003 - 2009  Paul Mundt
  *
  *  Based on linux/arch/i386/mm/fault.c:
  *   Copyright (C) 1995  Linus Torvalds
@@ -15,7 +15,7 @@
 #include <linux/mm.h>
 #include <linux/hardirq.h>
 #include <linux/kprobes.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <asm/io_trapped.h>
 #include <asm/system.h>
 #include <asm/mmu_context.h>
@@ -25,18 +25,91 @@ static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
 	int ret = 0;
 
-#ifdef CONFIG_KPROBES
-	if (!user_mode(regs)) {
+	if (kprobes_built_in() && !user_mode(regs)) {
 		preempt_disable();
 		if (kprobe_running() && kprobe_fault_handler(regs, trap))
 			ret = 1;
 		preempt_enable();
 	}
-#endif
 
 	return ret;
 }
 
+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
+{
+	unsigned index = pgd_index(address);
+	pgd_t *pgd_k;
+	pud_t *pud, *pud_k;
+	pmd_t *pmd, *pmd_k;
+
+	pgd += index;
+	pgd_k = init_mm.pgd + index;
+
+	if (!pgd_present(*pgd_k))
+		return NULL;
+
+	pud = pud_offset(pgd, address);
+	pud_k = pud_offset(pgd_k, address);
+	if (!pud_present(*pud_k))
+		return NULL;
+
+	pmd = pmd_offset(pud, address);
+	pmd_k = pmd_offset(pud_k, address);
+	if (!pmd_present(*pmd_k))
+		return NULL;
+
+	if (!pmd_present(*pmd))
+		set_pmd(pmd, *pmd_k);
+	else {
+		/*
+		 * The page tables are fully synchronised so there must
+		 * be another reason for the fault. Return NULL here to
+		 * signal that we have not taken care of the fault.
+		 */
+		BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
+		return NULL;
+	}
+
+	return pmd_k;
+}
+
+/*
+ * Handle a fault on the vmalloc or module mapping area
+ */
+static noinline int vmalloc_fault(unsigned long address)
+{
+	pgd_t *pgd_k;
+	pmd_t *pmd_k;
+	pte_t *pte_k;
+
+	/* Make sure we are in vmalloc/module/P3 area: */
+	if (!(address >= VMALLOC_START && address < P3_ADDR_MAX))
+		return -1;
+
+	/*
+	 * Synchronize this task's top level page-table
+	 * with the 'reference' page table.
+	 *
+	 * Do _not_ use "current" here. We might be inside
+	 * an interrupt in the middle of a task switch..
+	 */
+	pgd_k = get_TTB();
+	pmd_k = vmalloc_sync_one(pgd_k, address);
+	if (!pmd_k)
+		return -1;
+
+	pte_k = pte_offset_kernel(pmd_k, address);
+	if (!pte_present(*pte_k))
+		return -1;
+
+	return 0;
+}
+
+static int fault_in_kernel_space(unsigned long address)
+{
+	return address >= TASK_SIZE;
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
@@ -46,6 +119,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
 					unsigned long writeaccess,
 					unsigned long address)
 {
+	unsigned long vec;
 	struct task_struct *tsk;
 	struct mm_struct *mm;
 	struct vm_area_struct * vma;
@@ -53,70 +127,41 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
 	int fault;
 	siginfo_t info;
 
-	/*
-	 * We don't bother with any notifier callbacks here, as they are
-	 * all handled through the __do_page_fault() fast-path.
-	 */
-
 	tsk = current;
+	mm = tsk->mm;
 	si_code = SEGV_MAPERR;
+	vec = lookup_exception_vector();
 
-	if (unlikely(address >= TASK_SIZE)) {
-		/*
-		 * Synchronize this task's top level page-table
-		 * with the 'reference' page table.
-		 *
-		 * Do _not_ use "tsk" here. We might be inside
-		 * an interrupt in the middle of a task switch..
-		 */
-		int offset = pgd_index(address);
-		pgd_t *pgd, *pgd_k;
-		pud_t *pud, *pud_k;
-		pmd_t *pmd, *pmd_k;
-
-		pgd = get_TTB() + offset;
-		pgd_k = swapper_pg_dir + offset;
-
-		if (!pgd_present(*pgd)) {
-			if (!pgd_present(*pgd_k))
-				goto bad_area_nosemaphore;
-			set_pgd(pgd, *pgd_k);
+	/*
+	 * We fault-in kernel-space virtual memory on-demand. The
+	 * 'reference' page table is init_mm.pgd.
+	 *
+	 * NOTE! We MUST NOT take any locks for this case. We may
+	 * be in an interrupt or a critical region, and should
+	 * only copy the information from the master page table,
+	 * nothing more.
+	 */
+	if (unlikely(fault_in_kernel_space(address))) {
+		if (vmalloc_fault(address) >= 0)
 			return;
-		}
-
-		pud = pud_offset(pgd, address);
-		pud_k = pud_offset(pgd_k, address);
-
-		if (!pud_present(*pud)) {
-			if (!pud_present(*pud_k))
-				goto bad_area_nosemaphore;
-			set_pud(pud, *pud_k);
+		if (notify_page_fault(regs, vec))
 			return;
-		}
 
-		pmd = pmd_offset(pud, address);
-		pmd_k = pmd_offset(pud_k, address);
-		if (pmd_present(*pmd) || !pmd_present(*pmd_k))
-			goto bad_area_nosemaphore;
-		set_pmd(pmd, *pmd_k);
-
-		return;
+		goto bad_area_nosemaphore;
 	}
 
-	mm = tsk->mm;
-
-	if (unlikely(notify_page_fault(regs, lookup_exception_vector())))
+	if (unlikely(notify_page_fault(regs, vec)))
 		return;
 
 	/* Only enable interrupts if they were on before the fault */
 	if ((regs->sr & SR_IMASK) != SR_IMASK)
 		local_irq_enable();
 
-	perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
 	/*
-	 * If we're in an interrupt or have no user
-	 * context, we must not take the fault..
+	 * If we're in an interrupt, have no user context or are running
+	 * in an atomic region then we must not take the fault:
 	 */
 	if (in_atomic() || !mm)
 		goto no_context;
@@ -132,10 +177,11 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
 		goto bad_area;
 	if (expand_stack(vma, address))
 		goto bad_area;
-/*
- * Ok, we have a good vm_area for this memory access, so
- * we can handle it..
- */
+
+	/*
+	 * Ok, we have a good vm_area for this memory access, so
+	 * we can handle it..
+	 */
 good_area:
 	si_code = SEGV_ACCERR;
 	if (writeaccess) {
@@ -162,21 +208,21 @@ survive:
 	}
 	if (fault & VM_FAULT_MAJOR) {
 		tsk->maj_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
 				     regs, address);
 	} else {
 		tsk->min_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
 
 	up_read(&mm->mmap_sem);
 	return;
 
-/*
- * Something tried to access memory that isn't in our memory map..
- * Fix it, but check if it's kernel or user first..
- */
+	/*
+	 * Something tried to access memory that isn't in our memory map..
+	 * Fix it, but check if it's kernel or user first..
+	 */
 bad_area:
 	up_read(&mm->mmap_sem);
 
@@ -272,16 +318,15 @@ do_sigbus:
 /*
  * Called with interrupts disabled.
  */
-asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
-					 unsigned long writeaccess,
-					 unsigned long address)
+asmlinkage int __kprobes
+handle_tlbmiss(struct pt_regs *regs, unsigned long writeaccess,
+	       unsigned long address)
 {
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 	pte_t entry;
-	int ret = 1;
 
 	/*
 	 * We don't take page faults for P1, P2, and parts of P4, these
@@ -292,40 +337,41 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
 		pgd = pgd_offset_k(address);
 	} else {
 		if (unlikely(address >= TASK_SIZE || !current->mm))
-			goto out;
+			return 1;
 
 		pgd = pgd_offset(current->mm, address);
 	}
 
 	pud = pud_offset(pgd, address);
 	if (pud_none_or_clear_bad(pud))
-		goto out;
+		return 1;
 	pmd = pmd_offset(pud, address);
 	if (pmd_none_or_clear_bad(pmd))
-		goto out;
+		return 1;
 	pte = pte_offset_kernel(pmd, address);
 	entry = *pte;
 	if (unlikely(pte_none(entry) || pte_not_present(entry)))
-		goto out;
+		return 1;
 	if (unlikely(writeaccess && !pte_write(entry)))
-		goto out;
+		return 1;
 
 	if (writeaccess)
 		entry = pte_mkdirty(entry);
 	entry = pte_mkyoung(entry);
 
+	set_pte(pte, entry);
+
 #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SMP)
 	/*
-	 * ITLB is not affected by "ldtlb" instruction.
-	 * So, we need to flush the entry by ourselves.
+	 * SH-4 does not set MMUCR.RC to the corresponding TLB entry in
+	 * the case of an initial page write exception, so we need to
+	 * flush it in order to avoid potential TLB entry duplication.
 	 */
-	local_flush_tlb_one(get_asid(), address & PAGE_MASK);
+	if (writeaccess == 2)
+		local_flush_tlb_one(get_asid(), address & PAGE_MASK);
 #endif
 
-	set_pte(pte, entry);
 	update_mmu_cache(NULL, address, entry);
 
-	ret = 0;
-out:
-	return ret;
+	return 0;
 }
diff --git a/arch/sh/mm/fault_64.c b/arch/sh/mm/fault_64.c
index bd63b96..2b356ce 100644
--- a/arch/sh/mm/fault_64.c
+++ b/arch/sh/mm/fault_64.c
@@ -56,16 +56,7 @@ inline void __do_tlb_refill(unsigned long address,
 	/*
 	 * Set PTEH register
 	 */
-	pteh = address & MMU_VPN_MASK;
-
-	/* Sign extend based on neff. */
-#if (NEFF == 32)
-	/* Faster sign extension */
-	pteh = (unsigned long long)(signed long long)(signed long)pteh;
-#else
-	/* General case */
-	pteh = (pteh & NEFF_SIGN) ? (pteh | NEFF_MASK) : pteh;
-#endif
+	pteh = neff_sign_extend(address & MMU_VPN_MASK);
 
 	/* Set the ASID. */
 	pteh |= get_asid() << PTEH_ASID_SHIFT;
diff --git a/arch/sh/mm/flush-sh4.c b/arch/sh/mm/flush-sh4.c
new file mode 100644
index 0000000..cef4026
--- /dev/null
+++ b/arch/sh/mm/flush-sh4.c
@@ -0,0 +1,108 @@
+#include <linux/mm.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Write back the dirty D-caches, but not invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+static void sh4__flush_wback_region(void *start, int size)
+{
+	reg_size_t aligned_start, v, cnt, end;
+
+	aligned_start = register_align(start);
+	v = aligned_start & ~(L1_CACHE_BYTES-1);
+	end = (aligned_start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	cnt = (end - v) / L1_CACHE_BYTES;
+
+	while (cnt >= 8) {
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		cnt -= 8;
+	}
+
+	while (cnt) {
+		__ocbwb(v); v += L1_CACHE_BYTES;
+		cnt--;
+	}
+}
+
+/*
+ * Write back the dirty D-caches and invalidate them.
+ *
+ * START: Virtual Address (U0, P1, or P3)
+ * SIZE: Size of the region.
+ */
+static void sh4__flush_purge_region(void *start, int size)
+{
+	reg_size_t aligned_start, v, cnt, end;
+
+	aligned_start = register_align(start);
+	v = aligned_start & ~(L1_CACHE_BYTES-1);
+	end = (aligned_start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	cnt = (end - v) / L1_CACHE_BYTES;
+
+	while (cnt >= 8) {
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		__ocbp(v); v += L1_CACHE_BYTES;
+		cnt -= 8;
+	}
+	while (cnt) {
+		__ocbp(v); v += L1_CACHE_BYTES;
+		cnt--;
+	}
+}
+
+/*
+ * No write back please
+ */
+static void sh4__flush_invalidate_region(void *start, int size)
+{
+	reg_size_t aligned_start, v, cnt, end;
+
+	aligned_start = register_align(start);
+	v = aligned_start & ~(L1_CACHE_BYTES-1);
+	end = (aligned_start + size + L1_CACHE_BYTES-1)
+		& ~(L1_CACHE_BYTES-1);
+	cnt = (end - v) / L1_CACHE_BYTES;
+
+	while (cnt >= 8) {
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		__ocbi(v); v += L1_CACHE_BYTES;
+		cnt -= 8;
+	}
+
+	while (cnt) {
+		__ocbi(v); v += L1_CACHE_BYTES;
+		cnt--;
+	}
+}
+
+void __init sh4__flush_region_init(void)
+{
+	__flush_wback_region		= sh4__flush_wback_region;
+	__flush_invalidate_region	= sh4__flush_invalidate_region;
+	__flush_purge_region		= sh4__flush_purge_region;
+}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index fe532ae..edc842f 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -106,27 +106,31 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
 	pgd_t *pgd;
 	pud_t *pud;
 	pmd_t *pmd;
-	int pgd_idx;
+	pte_t *pte;
+	int i, j, k;
 	unsigned long vaddr;
 
-	vaddr = start & PMD_MASK;
-	end = (end + PMD_SIZE - 1) & PMD_MASK;
-	pgd_idx = pgd_index(vaddr);
-	pgd = pgd_base + pgd_idx;
-
-	for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
-		BUG_ON(pgd_none(*pgd));
-		pud = pud_offset(pgd, 0);
-		BUG_ON(pud_none(*pud));
-		pmd = pmd_offset(pud, 0);
-
-		if (!pmd_present(*pmd)) {
-			pte_t *pte_table;
-			pte_table = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
-			pmd_populate_kernel(&init_mm, pmd, pte_table);
+	vaddr = start;
+	i = __pgd_offset(vaddr);
+	j = __pud_offset(vaddr);
+	k = __pmd_offset(vaddr);
+	pgd = pgd_base + i;
+
+	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+		pud = (pud_t *)pgd;
+		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+			pmd = (pmd_t *)pud;
+			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+				if (pmd_none(*pmd)) {
+					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+					pmd_populate_kernel(&init_mm, pmd, pte);
+					BUG_ON(pte != pte_offset_kernel(pmd, 0));
+				}
+				vaddr += PMD_SIZE;
+			}
+			k = 0;
 		}
-
-		vaddr += PMD_SIZE;
+		j = 0;
 	}
 }
 #endif	/* CONFIG_MMU */
@@ -137,7 +141,7 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
 void __init paging_init(void)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
-	unsigned long vaddr;
+	unsigned long vaddr, end;
 	int nid;
 
 	/* We don't need to map the kernel through the TLB, as
@@ -155,7 +159,8 @@ void __init paging_init(void)
 	 * pte's will be filled in by __set_fixmap().
 	 */
 	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
-	page_table_range_init(vaddr, 0, swapper_pg_dir);
+	end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
+	page_table_range_init(vaddr, end, swapper_pg_dir);
 
 	kmap_coherent_init();
 
@@ -210,6 +215,9 @@ void __init mem_init(void)
 			high_memory = node_high_memory;
 	}
 
+	/* Set this up early, so we can take care of the zero page */
+	cpu_cache_init();
+
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
 	__flush_wback_region(empty_zero_page, PAGE_SIZE);
@@ -230,8 +238,6 @@ void __init mem_init(void)
 		datasize >> 10,
 		initsize >> 10);
 
-	p3_cache_init();
-
 	/* Initialize the vDSO */
 	vsyscall_init();
 }
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index da2f418..c325061 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -57,14 +57,6 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
 	if (is_pci_memory_fixed_range(phys_addr, size))
 		return (void __iomem *)phys_addr;
 
-#if !defined(CONFIG_PMB_FIXED)
-	/*
-	 * Don't allow anybody to remap normal RAM that we're using..
-	 */
-	if (phys_addr < virt_to_phys(high_memory))
-		return NULL;
-#endif
-
 	/*
 	 * Mappings have to be page-aligned
 	 */
diff --git a/arch/sh/mm/ioremap_64.c b/arch/sh/mm/ioremap_64.c
index 828c859..b16843d 100644
--- a/arch/sh/mm/ioremap_64.c
+++ b/arch/sh/mm/ioremap_64.c
@@ -94,7 +94,6 @@ static struct resource *shmedia_find_resource(struct resource *root,
 static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
 				      const char *name, unsigned long flags)
 {
-	static int printed_full;
 	struct xresource *xres;
 	struct resource *res;
 	char *tack;
@@ -108,11 +107,8 @@ static void __iomem *shmedia_alloc_io(unsigned long phys, unsigned long size,
 		tack = xres->xname;
 		res = &xres->xres;
 	} else {
-		if (!printed_full) {
-			printk(KERN_NOTICE "%s: done with statics, "
+		printk_once(KERN_NOTICE "%s: done with statics, "
 			       "switching to kmalloc\n", __func__);
-			printed_full = 1;
-		}
 		tlen = strlen(name);
 		tack = kmalloc(sizeof(struct resource) + tlen + 1, GFP_KERNEL);
 		if (!tack)
diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c
new file mode 100644
index 0000000..16e01b5
--- /dev/null
+++ b/arch/sh/mm/kmap.c
@@ -0,0 +1,65 @@
+/*
+ * arch/sh/mm/kmap.c
+ *
+ * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
+ * Copyright (C) 2002 - 2009  Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+#define kmap_get_fixmap_pte(vaddr)                                     \
+	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
+
+static pte_t *kmap_coherent_pte;
+
+void __init kmap_coherent_init(void)
+{
+	unsigned long vaddr;
+
+	/* cache the first coherent kmap pte */
+	vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
+	kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
+}
+
+void *kmap_coherent(struct page *page, unsigned long addr)
+{
+	enum fixed_addresses idx;
+	unsigned long vaddr;
+
+	BUG_ON(test_bit(PG_dcache_dirty, &page->flags));
+
+	pagefault_disable();
+
+	idx = FIX_CMAP_END -
+		((addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT);
+	vaddr = __fix_to_virt(idx);
+
+	BUG_ON(!pte_none(*(kmap_coherent_pte - idx)));
+	set_pte(kmap_coherent_pte - idx, mk_pte(page, PAGE_KERNEL));
+
+	return (void *)vaddr;
+}
+
+void kunmap_coherent(void *kvaddr)
+{
+	if (kvaddr >= (void *)FIXADDR_START) {
+		unsigned long vaddr = (unsigned long)kvaddr & PAGE_MASK;
+		enum fixed_addresses idx = __virt_to_fix(vaddr);
+
+		/* XXX.. Kill this later, here for sanity at the moment.. */
+		__flush_purge_region((void *)vaddr, PAGE_SIZE);
+
+		pte_clear(&init_mm, vaddr, kmap_coherent_pte - idx);
+		local_flush_tlb_one(get_asid(), vaddr);
+	}
+
+	pagefault_enable();
+}
diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c
index 1b5fdfb..d2984fa 100644
--- a/arch/sh/mm/mmap.c
+++ b/arch/sh/mm/mmap.c
@@ -14,10 +14,10 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 
-#ifdef CONFIG_MMU
 unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
 EXPORT_SYMBOL(shm_align_mask);
 
+#ifdef CONFIG_MMU
 /*
  * To avoid cache aliases, we map the shared page with same color.
  */
diff --git a/arch/sh/mm/nommu.c b/arch/sh/mm/nommu.c
new file mode 100644
index 0000000..ac16c05
--- /dev/null
+++ b/arch/sh/mm/nommu.c
@@ -0,0 +1,96 @@
+/*
+ * arch/sh/mm/nommu.c
+ *
+ * Various helper routines and stubs for MMUless SH.
+ *
+ * Copyright (C) 2002 - 2009 Paul Mundt
+ *
+ * Released under the terms of the GNU GPL v2.0.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+
+/*
+ * Nothing too terribly exciting here ..
+ */
+void copy_page(void *to, void *from)
+{
+	memcpy(to, from, PAGE_SIZE);
+}
+
+__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n)
+{
+	memcpy(to, from, n);
+	return 0;
+}
+
+__kernel_size_t __clear_user(void *to, __kernel_size_t n)
+{
+	memset(to, 0, n);
+	return 0;
+}
+
+void local_flush_tlb_all(void)
+{
+	BUG();
+}
+
+void local_flush_tlb_mm(struct mm_struct *mm)
+{
+	BUG();
+}
+
+void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+			    unsigned long end)
+{
+	BUG();
+}
+
+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	BUG();
+}
+
+void local_flush_tlb_one(unsigned long asid, unsigned long page)
+{
+	BUG();
+}
+
+void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	BUG();
+}
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+}
+
+void __init kmap_coherent_init(void)
+{
+}
+
+void *kmap_coherent(struct page *page, unsigned long addr)
+{
+	BUG();
+	return NULL;
+}
+
+void kunmap_coherent(void *kvaddr)
+{
+	BUG();
+}
+
+void __init page_table_range_init(unsigned long start, unsigned long end,
+				  pgd_t *pgd_base)
+{
+}
+
+void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
+{
+}
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
index 095d93b..9b784fd 100644
--- a/arch/sh/mm/numa.c
+++ b/arch/sh/mm/numa.c
@@ -9,6 +9,7 @@
  */
 #include <linux/module.h>
 #include <linux/bootmem.h>
+#include <linux/lmb.h>
 #include <linux/mm.h>
 #include <linux/numa.h>
 #include <linux/pfn.h>
@@ -26,6 +27,15 @@ EXPORT_SYMBOL_GPL(node_data);
 void __init setup_memory(void)
 {
 	unsigned long free_pfn = PFN_UP(__pa(_end));
+	u64 base = min_low_pfn << PAGE_SHIFT;
+	u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn;
+
+	lmb_add(base, size);
+
+	/* Reserve the LMB regions used by the kernel, initrd, etc.. */
+	lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+		    (PFN_PHYS(free_pfn) + PAGE_SIZE - 1) -
+		    (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET));
 
 	/*
 	 * Node 0 sets up its pgdat at the first available pfn,
@@ -45,24 +55,23 @@ void __init setup_memory(void)
 
 void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
 {
-	unsigned long bootmap_pages, bootmap_start, bootmap_size;
-	unsigned long start_pfn, free_pfn, end_pfn;
+	unsigned long bootmap_pages;
+	unsigned long start_pfn, end_pfn;
+	unsigned long bootmem_paddr;
 
 	/* Don't allow bogus node assignment */
 	BUG_ON(nid > MAX_NUMNODES || nid == 0);
 
-	/*
-	 * The free pfn starts at the beginning of the range, and is
-	 * advanced as necessary for pgdat and node map allocations.
-	 */
-	free_pfn = start_pfn = start >> PAGE_SHIFT;
+	start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
 
+	lmb_add(start, end - start);
+
 	__add_active_range(nid, start_pfn, end_pfn);
 
 	/* Node-local pgdat */
-	NODE_DATA(nid) = pfn_to_kaddr(free_pfn);
-	free_pfn += PFN_UP(sizeof(struct pglist_data));
+	NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data),
+					     SMP_CACHE_BYTES, end_pfn));
 	memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
 
 	NODE_DATA(nid)->bdata = &bootmem_node_data[nid];
@@ -71,16 +80,17 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
 
 	/* Node-local bootmap */
 	bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
-	bootmap_start = (unsigned long)pfn_to_kaddr(free_pfn);
-	bootmap_size = init_bootmem_node(NODE_DATA(nid), free_pfn, start_pfn,
-				    end_pfn);
+	bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT,
+				       PAGE_SIZE, end_pfn);
+	init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
+			  start_pfn, end_pfn);
 
 	free_bootmem_with_active_regions(nid, end_pfn);
 
 	/* Reserve the pgdat and bootmap space with the bootmem allocator */
 	reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT,
 			     sizeof(struct pglist_data), BOOTMEM_DEFAULT);
-	reserve_bootmem_node(NODE_DATA(nid), free_pfn << PAGE_SHIFT,
+	reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr,
 			     bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
 
 	/* It's up */
diff --git a/arch/sh/mm/pg-nommu.c b/arch/sh/mm/pg-nommu.c
deleted file mode 100644
index 91ed4e6..0000000
--- a/arch/sh/mm/pg-nommu.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * arch/sh/mm/pg-nommu.c
- *
- * clear_page()/copy_page() implementation for MMUless SH.
- *
- * Copyright (C) 2003  Paul Mundt
- *
- * 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.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-void copy_page(void *to, void *from)
-{
-	memcpy(to, from, PAGE_SIZE);
-}
-
-void clear_page(void *to)
-{
-	memset(to, 0, PAGE_SIZE);
-}
-
-__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n)
-{
-	memcpy(to, from, n);
-	return 0;
-}
-
-__kernel_size_t __clear_user(void *to, __kernel_size_t n)
-{
-	memset(to, 0, n);
-	return 0;
-}
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
deleted file mode 100644
index 2fe14da..0000000
--- a/arch/sh/mm/pg-sh4.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * arch/sh/mm/pg-sh4.c
- *
- * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- * Copyright (C) 2002 - 2007  Paul Mundt
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/fs.h>
-#include <linux/highmem.h>
-#include <linux/module.h>
-#include <asm/mmu_context.h>
-#include <asm/cacheflush.h>
-
-#define CACHE_ALIAS (current_cpu_data.dcache.alias_mask)
-
-#define kmap_get_fixmap_pte(vaddr)                                     \
-	pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr))
-
-static pte_t *kmap_coherent_pte;
-
-void __init kmap_coherent_init(void)
-{
-	unsigned long vaddr;
-
-	/* cache the first coherent kmap pte */
-	vaddr = __fix_to_virt(FIX_CMAP_BEGIN);
-	kmap_coherent_pte = kmap_get_fixmap_pte(vaddr);
-}
-
-static inline void *kmap_coherent(struct page *page, unsigned long addr)
-{
-	enum fixed_addresses idx;
-	unsigned long vaddr, flags;
-	pte_t pte;
-
-	inc_preempt_count();
-
-	idx = (addr & current_cpu_data.dcache.alias_mask) >> PAGE_SHIFT;
-	vaddr = __fix_to_virt(FIX_CMAP_END - idx);
-	pte = mk_pte(page, PAGE_KERNEL);
-
-	local_irq_save(flags);
-	flush_tlb_one(get_asid(), vaddr);
-	local_irq_restore(flags);
-
-	update_mmu_cache(NULL, vaddr, pte);
-
-	set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte);
-
-	return (void *)vaddr;
-}
-
-static inline void kunmap_coherent(struct page *page)
-{
-	dec_preempt_count();
-	preempt_check_resched();
-}
-
-/*
- * clear_user_page
- * @to: P1 address
- * @address: U0 address to be mapped
- * @page: page (virt_to_page(to))
- */
-void clear_user_page(void *to, unsigned long address, struct page *page)
-{
-	__set_bit(PG_mapped, &page->flags);
-
-	clear_page(to);
-	if ((((address & PAGE_MASK) ^ (unsigned long)to) & CACHE_ALIAS))
-		__flush_wback_region(to, PAGE_SIZE);
-}
-
-void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
-		       unsigned long vaddr, void *dst, const void *src,
-		       unsigned long len)
-{
-	void *vto;
-
-	__set_bit(PG_mapped, &page->flags);
-
-	vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
-	memcpy(vto, src, len);
-	kunmap_coherent(vto);
-
-	if (vma->vm_flags & VM_EXEC)
-		flush_cache_page(vma, vaddr, page_to_pfn(page));
-}
-
-void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
-			 unsigned long vaddr, void *dst, const void *src,
-			 unsigned long len)
-{
-	void *vfrom;
-
-	__set_bit(PG_mapped, &page->flags);
-
-	vfrom = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
-	memcpy(dst, vfrom, len);
-	kunmap_coherent(vfrom);
-}
-
-void copy_user_highpage(struct page *to, struct page *from,
-			unsigned long vaddr, struct vm_area_struct *vma)
-{
-	void *vfrom, *vto;
-
-	__set_bit(PG_mapped, &to->flags);
-
-	vto = kmap_atomic(to, KM_USER1);
-	vfrom = kmap_coherent(from, vaddr);
-	copy_page(vto, vfrom);
-	kunmap_coherent(vfrom);
-
-	if (((vaddr ^ (unsigned long)vto) & CACHE_ALIAS))
-		__flush_wback_region(vto, PAGE_SIZE);
-
-	kunmap_atomic(vto, KM_USER1);
-	/* Make sure this page is cleared on other CPU's too before using it */
-	smp_wmb();
-}
-EXPORT_SYMBOL(copy_user_highpage);
-
-/*
- * For SH-4, we have our own implementation for ptep_get_and_clear
- */
-pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-	pte_t pte = *ptep;
-
-	pte_clear(mm, addr, ptep);
-	if (!pte_not_present(pte)) {
-		unsigned long pfn = pte_pfn(pte);
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-			struct address_space *mapping = page_mapping(page);
-			if (!mapping || !mapping_writably_mapped(mapping))
-				__clear_bit(PG_mapped, &page->flags);
-		}
-	}
-	return pte;
-}
diff --git a/arch/sh/mm/pg-sh7705.c b/arch/sh/mm/pg-sh7705.c
deleted file mode 100644
index eaf2514..0000000
--- a/arch/sh/mm/pg-sh7705.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * arch/sh/mm/pg-sh7705.c
- *
- * Copyright (C) 1999, 2000  Niibe Yutaka
- * Copyright (C) 2004  Alex Song
- *
- * 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.
- *
- */
-
-#include <linux/init.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/threads.h>
-#include <linux/fs.h>
-#include <asm/addrspace.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/cache.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-#include <asm/mmu_context.h>
-#include <asm/cacheflush.h>
-
-static inline void __flush_purge_virtual_region(void *p1, void *virt, int size)
-{
-	unsigned long v;
-	unsigned long begin, end;
-	unsigned long p1_begin;
-
-
-	begin = L1_CACHE_ALIGN((unsigned long)virt);
-	end = L1_CACHE_ALIGN((unsigned long)virt + size);
-
-	p1_begin = (unsigned long)p1 & ~(L1_CACHE_BYTES - 1);
-
-	/* do this the slow way as we may not have TLB entries
-	 * for virt yet. */
-	for (v = begin; v < end; v += L1_CACHE_BYTES) {
-		unsigned long p;
-	        unsigned long ways, addr;
-
-		p = __pa(p1_begin);
-
-	        ways = current_cpu_data.dcache.ways;
-		addr = CACHE_OC_ADDRESS_ARRAY;
-
-		do {
-			unsigned long data;
-
-			addr |= (v & current_cpu_data.dcache.entry_mask);
-
-			data = ctrl_inl(addr);
-			if ((data & CACHE_PHYSADDR_MASK) ==
-			       (p & CACHE_PHYSADDR_MASK)) {
-				data &= ~(SH_CACHE_UPDATED|SH_CACHE_VALID);
-				ctrl_outl(data, addr);
-			}
-
-			addr += current_cpu_data.dcache.way_incr;
-		} while (--ways);
-
-		p1_begin += L1_CACHE_BYTES;
-	}
-}
-
-/*
- * clear_user_page
- * @to: P1 address
- * @address: U0 address to be mapped
- */
-void clear_user_page(void *to, unsigned long address, struct page *pg)
-{
-	struct page *page = virt_to_page(to);
-
-	__set_bit(PG_mapped, &page->flags);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
-		clear_page(to);
-		__flush_wback_region(to, PAGE_SIZE);
-	} else {
-		__flush_purge_virtual_region(to,
-					     (void *)(address & 0xfffff000),
-					     PAGE_SIZE);
-		clear_page(to);
-		__flush_wback_region(to, PAGE_SIZE);
-	}
-}
-
-/*
- * copy_user_page
- * @to: P1 address
- * @from: P1 address
- * @address: U0 address to be mapped
- */
-void copy_user_page(void *to, void *from, unsigned long address, struct page *pg)
-{
-	struct page *page = virt_to_page(to);
-
-
-	__set_bit(PG_mapped, &page->flags);
-	if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) {
-		copy_page(to, from);
-		__flush_wback_region(to, PAGE_SIZE);
-	} else {
-		__flush_purge_virtual_region(to,
-					     (void *)(address & 0xfffff000),
-					     PAGE_SIZE);
-		copy_page(to, from);
-		__flush_wback_region(to, PAGE_SIZE);
-	}
-}
-
-/*
- * For SH7705, we have our own implementation for ptep_get_and_clear
- * Copied from pg-sh4.c
- */
-pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-	pte_t pte = *ptep;
-
-	pte_clear(mm, addr, ptep);
-	if (!pte_not_present(pte)) {
-		unsigned long pfn = pte_pfn(pte);
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-			struct address_space *mapping = page_mapping(page);
-			if (!mapping || !mapping_writably_mapped(mapping))
-				__clear_bit(PG_mapped, &page->flags);
-		}
-	}
-
-	return pte;
-}
-
diff --git a/arch/sh/mm/tlb-nommu.c b/arch/sh/mm/tlb-nommu.c
deleted file mode 100644
index 71c742b..0000000
--- a/arch/sh/mm/tlb-nommu.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * arch/sh/mm/tlb-nommu.c
- *
- * TLB Operations for MMUless SH.
- *
- * Copyright (C) 2002 Paul Mundt
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-
-/*
- * Nothing too terribly exciting here ..
- */
-void local_flush_tlb_all(void)
-{
-	BUG();
-}
-
-void local_flush_tlb_mm(struct mm_struct *mm)
-{
-	BUG();
-}
-
-void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
-			    unsigned long end)
-{
-	BUG();
-}
-
-void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
-{
-	BUG();
-}
-
-void local_flush_tlb_one(unsigned long asid, unsigned long page)
-{
-	BUG();
-}
-
-void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
-{
-	BUG();
-}
-
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
-{
-	BUG();
-}
-
-void __init page_table_range_init(unsigned long start, unsigned long end,
-				  pgd_t *pgd_base)
-{
-}
-
-void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
-{
-}
diff --git a/arch/sh/mm/tlb-pteaex.c b/arch/sh/mm/tlb-pteaex.c
index 2aab3ea..409b7c2 100644
--- a/arch/sh/mm/tlb-pteaex.c
+++ b/arch/sh/mm/tlb-pteaex.c
@@ -16,34 +16,16 @@
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	unsigned long flags;
-	unsigned long pteval;
-	unsigned long vpn;
+	unsigned long flags, pteval, vpn;
 
-	/* Ptrace may call this routine. */
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
 	if (vma && current->active_mm != vma->vm_mm)
 		return;
 
-#ifndef CONFIG_CACHE_OFF
-	{
-		unsigned long pfn = pte_pfn(pte);
-
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-
-			if (!test_bit(PG_mapped, &page->flags)) {
-				unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-				__flush_wback_region((void *)P1SEGADDR(phys),
-						     PAGE_SIZE);
-				__set_bit(PG_mapped, &page->flags);
-			}
-		}
-	}
-#endif
-
 	local_irq_save(flags);
 
 	/* Set PTEH register */
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c
index 17cb7c3..ace8e6d 100644
--- a/arch/sh/mm/tlb-sh3.c
+++ b/arch/sh/mm/tlb-sh3.c
@@ -27,32 +27,16 @@
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	unsigned long flags;
-	unsigned long pteval;
-	unsigned long vpn;
+	unsigned long flags, pteval, vpn;
 
-	/* Ptrace may call this routine. */
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
 	if (vma && current->active_mm != vma->vm_mm)
 		return;
 
-#if defined(CONFIG_SH7705_CACHE_32KB)
-	{
-		struct page *page = pte_page(pte);
-		unsigned long pfn = pte_pfn(pte);
-
-		if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
-			unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-
-			__flush_wback_region((void *)P1SEGADDR(phys),
-					     PAGE_SIZE);
-			__set_bit(PG_mapped, &page->flags);
-		}
-	}
-#endif
-
 	local_irq_save(flags);
 
 	/* Set PTEH register */
@@ -93,4 +77,3 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
 	for (i = 0; i < ways; i++)
 		ctrl_outl(data, addr + (i << 8));
 }
-
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index f0c7b73..8cf550e 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -15,34 +15,16 @@
 #include <asm/mmu_context.h>
 #include <asm/cacheflush.h>
 
-void update_mmu_cache(struct vm_area_struct * vma,
-		      unsigned long address, pte_t pte)
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
-	unsigned long flags;
-	unsigned long pteval;
-	unsigned long vpn;
+	unsigned long flags, pteval, vpn;
 
-	/* Ptrace may call this routine. */
+	/*
+	 * Handle debugger faulting in for debugee.
+	 */
 	if (vma && current->active_mm != vma->vm_mm)
 		return;
 
-#ifndef CONFIG_CACHE_OFF
-	{
-		unsigned long pfn = pte_pfn(pte);
-
-		if (pfn_valid(pfn)) {
-			struct page *page = pfn_to_page(pfn);
-
-			if (!test_bit(PG_mapped, &page->flags)) {
-				unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-				__flush_wback_region((void *)P1SEGADDR(phys),
-						     PAGE_SIZE);
-				__set_bit(PG_mapped, &page->flags);
-			}
-		}
-	}
-#endif
-
 	local_irq_save(flags);
 
 	/* Set PTEH register */
@@ -61,9 +43,12 @@ void update_mmu_cache(struct vm_area_struct * vma,
 	 */
 	ctrl_outl(pte.pte_high, MMU_PTEA);
 #else
-	if (cpu_data->flags & CPU_HAS_PTEA)
-		/* TODO: make this look less hacky */
-		ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
+	if (cpu_data->flags & CPU_HAS_PTEA) {
+		/* The last 3 bits and the first one of pteval contains
+		 * the PTEA timing control and space attribute bits
+		 */
+		ctrl_outl(copy_ptea_attributes(pteval), MMU_PTEA);
+	}
 #endif
 
 	/* Set PTEL register */
diff --git a/arch/sh/mm/tlb-sh5.c b/arch/sh/mm/tlb-sh5.c
index dae1312..fdb64e4 100644
--- a/arch/sh/mm/tlb-sh5.c
+++ b/arch/sh/mm/tlb-sh5.c
@@ -117,26 +117,15 @@ int sh64_put_wired_dtlb_entry(unsigned long long entry)
  * Load up a virtual<->physical translation for @eaddr<->@paddr in the
  * pre-allocated TLB slot @config_addr (see sh64_get_wired_dtlb_entry).
  */
-inline void sh64_setup_tlb_slot(unsigned long long config_addr,
-				unsigned long eaddr,
-				unsigned long asid,
-				unsigned long paddr)
+void sh64_setup_tlb_slot(unsigned long long config_addr, unsigned long eaddr,
+			 unsigned long asid, unsigned long paddr)
 {
 	unsigned long long pteh, ptel;
 
-	/* Sign extension */
-#if (NEFF == 32)
-	pteh = (unsigned long long)(signed long long)(signed long) eaddr;
-#else
-#error "Can't sign extend more than 32 bits yet"
-#endif
+	pteh = neff_sign_extend(eaddr);
 	pteh &= PAGE_MASK;
 	pteh |= (asid << PTEH_ASID_SHIFT) | PTEH_VALID;
-#if (NEFF == 32)
-	ptel = (unsigned long long)(signed long long)(signed long) paddr;
-#else
-#error "Can't sign extend more than 32 bits yet"
-#endif
+	ptel = neff_sign_extend(paddr);
 	ptel &= PAGE_MASK;
 	ptel |= (_PAGE_CACHABLE | _PAGE_READ | _PAGE_WRITE);
 
@@ -152,5 +141,5 @@ inline void sh64_setup_tlb_slot(unsigned long long config_addr,
  *
  * Teardown any existing mapping in the TLB slot @config_addr.
  */
-inline void sh64_teardown_tlb_slot(unsigned long long config_addr)
+void sh64_teardown_tlb_slot(unsigned long long config_addr)
 	__attribute__ ((alias("__flush_tlb_slot")));
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index 3ce40ea..de0b0e8 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -20,7 +20,7 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/interrupt.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -116,7 +116,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
 	/* Not an IO address, so reenable interrupts */
 	local_irq_enable();
 
-	perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
 	/*
 	 * If we're in an interrupt or have no user
@@ -201,11 +201,11 @@ survive:
 
 	if (fault & VM_FAULT_MAJOR) {
 		tsk->maj_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
 				     regs, address);
 	} else {
 		tsk->min_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
 
@@ -329,22 +329,6 @@ do_sigbus:
 		goto no_context;
 }
 
-void update_mmu_cache(struct vm_area_struct * vma,
-			unsigned long address, pte_t pte)
-{
-	/*
-	 * This appears to get called once for every pte entry that gets
-	 * established => I don't think it's efficient to try refilling the
-	 * TLBs with the pages - some may not get accessed even.  Also, for
-	 * executable pages, it is impossible to determine reliably here which
-	 * TLB they should be mapped into (or both even).
-	 *
-	 * So, just do nothing here and handle faults on demand.  In the
-	 * TLBMISS handling case, the refill is now done anyway after the pte
-	 * has been fixed up, so that deals with most useful cases.
-	 */
-}
-
 void local_flush_tlb_one(unsigned long asid, unsigned long page)
 {
 	unsigned long long match, pteh=0, lpage;
@@ -353,7 +337,7 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page)
 	/*
 	 * Sign-extend based on neff.
 	 */
-	lpage = (page & NEFF_SIGN) ? (page | NEFF_MASK) : page;
+	lpage = neff_sign_extend(page);
 	match = (asid << PTEH_ASID_SHIFT) | PTEH_VALID;
 	match |= lpage;
 
@@ -482,3 +466,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
         /* FIXME: Optimize this later.. */
         flush_tlb_all();
 }
+
+void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
+{
+}
diff --git a/arch/sh/oprofile/backtrace.c b/arch/sh/oprofile/backtrace.c
index 9499a29..2bc74de 100644
--- a/arch/sh/oprofile/backtrace.c
+++ b/arch/sh/oprofile/backtrace.c
@@ -17,9 +17,43 @@
 #include <linux/sched.h>
 #include <linux/kallsyms.h>
 #include <linux/mm.h>
+#include <asm/unwinder.h>
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
 #include <asm/sections.h>
+#include <asm/stacktrace.h>
+
+static void backtrace_warning_symbol(void *data, char *msg,
+				     unsigned long symbol)
+{
+	/* Ignore warnings */
+}
+
+static void backtrace_warning(void *data, char *msg)
+{
+	/* Ignore warnings */
+}
+
+static int backtrace_stack(void *data, char *name)
+{
+	/* Yes, we want all stacks */
+	return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr, int reliable)
+{
+	unsigned int *depth = data;
+
+	if ((*depth)--)
+		oprofile_add_trace(addr);
+}
+
+static struct stacktrace_ops backtrace_ops = {
+	.warning = backtrace_warning,
+	.warning_symbol = backtrace_warning_symbol,
+	.stack = backtrace_stack,
+	.address = backtrace_address,
+};
 
 /* Limit to stop backtracing too far. */
 static int backtrace_limit = 20;
@@ -47,50 +81,6 @@ user_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
 	return stackaddr;
 }
 
-/*
- * |             | /\ Higher addresses
- * |             |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * .             .
- * |    stack    |
- * --------------- saved regs->regs[15] value if valid
- * .             .
- * --------------- struct pt_regs stored on stack (struct pt_regs *)
- * |             |
- * .             .
- * |             |
- * --------------- ???
- * |             |
- * |             | \/ Lower addresses
- *
- * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
- */
-static int valid_kernel_stack(unsigned long *stackaddr, struct pt_regs *regs)
-{
-	unsigned long stack = (unsigned long)regs;
-	unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
-	return ((unsigned long)stackaddr > stack) && ((unsigned long)stackaddr < stack_base);
-}
-
-static unsigned long *
-kernel_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
-{
-	unsigned long addr;
-
-	/*
-	 * If not a valid kernel address, keep going till we find one
-	 * or the SP stops being a valid address.
-	 */
-	do {
-		addr = *stackaddr++;
-		oprofile_add_trace(addr);
-	} while (valid_kernel_stack(stackaddr, regs));
-
-	return stackaddr;
-}
-
 void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
 {
 	unsigned long *stackaddr;
@@ -103,9 +93,9 @@ void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
 
 	stackaddr = (unsigned long *)regs->regs[15];
 	if (!user_mode(regs)) {
-		while (depth-- && valid_kernel_stack(stackaddr, regs))
-			stackaddr = kernel_backtrace(stackaddr, regs);
-
+		if (depth)
+			unwind_stack(NULL, regs, stackaddr,
+				     &backtrace_ops, &depth);
 		return;
 	}
 
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index fec3a53..6639b25 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -53,6 +53,9 @@ RSK7203			SH_RSK7203
 AP325RXA		SH_AP325RXA
 SH7763RDP		SH_SH7763RDP
 SH7785LCR		SH_SH7785LCR
+SH7785LCR_PT		SH_SH7785LCR_PT
 URQUELL			SH_URQUELL
 ESPT			SH_ESPT
 POLARIS			SH_POLARIS
+KFR2R09			SH_KFR2R09
+ECOVEC			SH_ECOVEC
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 233cff5..97fca46 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -25,6 +25,7 @@ config SPARC
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select RTC_CLASS
 	select RTC_DRV_M48T59
+	select HAVE_PERF_EVENTS
 	select HAVE_DMA_ATTRS
 	select HAVE_DMA_API_DEBUG
 
@@ -46,6 +47,7 @@ config SPARC64
 	select RTC_DRV_BQ4802
 	select RTC_DRV_SUN4V
 	select RTC_DRV_STARFIRE
+	select HAVE_PERF_EVENTS
 
 config ARCH_DEFCONFIG
 	string
@@ -97,7 +99,7 @@ config AUDIT_ARCH
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y if SPARC64
 
-config HAVE_DYNAMIC_PER_CPU_AREA
+config NEED_PER_CPU_EMBED_FIRST_CHUNK
 	def_bool y if SPARC64
 
 config GENERIC_HARDIRQS_NO__DO_IRQ
@@ -439,6 +441,17 @@ config SERIAL_CONSOLE
 
 	  If unsure, say N.
 
+config SPARC_LEON
+	bool "Sparc Leon processor family"
+	depends on SPARC32
+	---help---
+	  If you say Y here if you are running on a SPARC-LEON processor.
+	  The LEON processor is a synthesizable VHDL model of the
+	  SPARC-v8 standard. LEON is  part of the GRLIB collection of
+	  IP cores that are distributed under GPL. GRLIB can be downloaded
+	  from www.gaisler.com. You can download a sparc-linux cross-compilation
+	  toolchain at www.gaisler.com.
+
 endmenu
 
 menu "Bus options (PCI etc.)"
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index 2003ded..467221d 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -38,10 +38,6 @@ CPPFLAGS_vmlinux.lds += -m32
 #  Actual linking is done with "make image".
 LDFLAGS_vmlinux = -r
 
-# Default target
-all: zImage
-
-
 else
 #####
 # sparc64
@@ -91,6 +87,9 @@ endif
 
 boot := arch/sparc/boot
 
+# Default target
+all: zImage
+
 image zImage tftpboot.img vmlinux.aout: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
@@ -109,8 +108,9 @@ define archhelp
 endef
 else
 define archhelp
-  echo  '* vmlinux       - Standard sparc64 kernel'
-  echo  '  vmlinux.aout  - a.out kernel for sparc64'
+  echo  '* vmlinux      - standard sparc64 kernel'
+  echo  '* zImage       - stripped and compressed sparc64 kernel ($(boot)/zImage)'
+  echo  '  vmlinux.aout - a.out kernel for sparc64'
   echo  '  tftpboot.img - image prepared for tftp'
 endef
 endif
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile
index 1ff0fd9..97e3feb 100644
--- a/arch/sparc/boot/Makefile
+++ b/arch/sparc/boot/Makefile
@@ -79,6 +79,9 @@ $(obj)/image: vmlinux FORCE
 	$(call if_changed,strip)
 	@echo '  kernel: $@ is ready'
 
+$(obj)/zImage: $(obj)/image
+	$(call if_changed,gzip)
+
 $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE
 	$(call if_changed,elftoaout)
 	$(call if_changed,piggy)
diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig
index a0f62a8..983d598 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc1
-# Tue Aug 18 23:45:52 2009
+# Linux kernel version: 2.6.31
+# Wed Sep 16 00:03:43 2009
 #
 # CONFIG_64BIT is not set
 CONFIG_SPARC=y
@@ -39,11 +39,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT 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
@@ -87,10 +88,12 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
 
 #
 # Performance Counters
 #
+# CONFIG_PERF_COUNTERS is not set
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 # CONFIG_STRIP_ASM_SYMS is not set
@@ -102,6 +105,8 @@ CONFIG_SLAB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -169,6 +174,7 @@ CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SUN_PM=y
 # CONFIG_SPARC_LED is not set
 CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SPARC_LEON is not set
 
 #
 # Bus options (PCI etc.)
@@ -259,6 +265,7 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -288,6 +295,7 @@ CONFIG_NET_PKTGEN=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
 CONFIG_WIRELESS_OLD_REGULATORY=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
@@ -295,7 +303,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 #
 # CFG80211 needs to be enabled for MAC80211
 #
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -426,6 +433,7 @@ CONFIG_SCSI_QLOGICPTI=m
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SCSI_SUNESP=y
+# CONFIG_SCSI_PMCRAID is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
@@ -524,12 +532,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -569,11 +572,11 @@ CONFIG_INPUT_EVBUG=m
 #
 CONFIG_INPUT_KEYBOARD=y
 CONFIG_KEYBOARD_ATKBD=m
-CONFIG_KEYBOARD_SUNKBD=m
 # 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_SUNKBD=m
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=m
 CONFIG_MOUSE_PS2_ALPS=y
@@ -581,6 +584,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=m
 # CONFIG_MOUSE_APPLETOUCH is not set
@@ -708,12 +712,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Console display driver support
 #
-# CONFIG_PROM_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=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
 
@@ -814,6 +816,7 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -877,7 +880,6 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y
 CONFIG_ROMFS_ON_BLOCK=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
@@ -984,14 +986,17 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SYSCTL_SYSCALL_CHECK is not set
 # CONFIG_PAGE_POISONING is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_KGDB=y
@@ -1014,7 +1019,6 @@ 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
@@ -1057,11 +1061,13 @@ CONFIG_CRYPTO_PCBC=m
 #
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index fdddf7a..f80b881 100644
--- a/arch/sparc/configs/sparc64_defconfig
+++ b/arch/sparc/configs/sparc64_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc1
-# Tue Aug 18 23:56:02 2009
+# Linux kernel version: 2.6.31
+# Tue Sep 15 17:06:03 2009
 #
 CONFIG_64BIT=y
 CONFIG_SPARC=y
@@ -19,7 +19,7 @@ CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_AUDIT_ARCH=y
 CONFIG_HAVE_SETUP_PER_CPU_AREA=y
-CONFIG_HAVE_DYNAMIC_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
 CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_MMU=y
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
@@ -48,11 +48,12 @@ CONFIG_POSIX_MQUEUE_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT 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=18
 CONFIG_GROUP_SCHED=y
@@ -96,10 +97,13 @@ CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+CONFIG_HAVE_PERF_COUNTERS=y
 
 #
 # Performance Counters
 #
+CONFIG_PERF_COUNTERS=y
+CONFIG_EVENT_PROFILE=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
@@ -119,7 +123,9 @@ CONFIG_KRETPROBES=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
 
 #
 # GCOV-based kernel profiling
@@ -317,6 +323,7 @@ CONFIG_IPV6_TUNNEL=m
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
@@ -349,6 +356,7 @@ CONFIG_NET_TCPPROBE=m
 # CONFIG_AF_RXRPC is not set
 CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_CFG80211_DEFAULT_PS_VALUE=0
 CONFIG_WIRELESS_OLD_REGULATORY=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_LIB80211 is not set
@@ -356,7 +364,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y
 #
 # CFG80211 needs to be enabled for MAC80211
 #
-CONFIG_MAC80211_DEFAULT_PS_VALUE=0
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
@@ -549,6 +556,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SUNESP is not set
+# CONFIG_SCSI_PMCRAID is not set
 # CONFIG_SCSI_SRP is not set
 # CONFIG_SCSI_DH is not set
 # CONFIG_SCSI_OSD_INITIATOR is not set
@@ -704,12 +712,7 @@ CONFIG_NIU=m
 # CONFIG_SFC is not set
 # CONFIG_BE2NET is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -768,11 +771,11 @@ CONFIG_INPUT_EVDEV=y
 #
 CONFIG_INPUT_KEYBOARD=y
 CONFIG_KEYBOARD_ATKBD=y
-CONFIG_KEYBOARD_SUNKBD=y
 CONFIG_KEYBOARD_LKKBD=m
-# CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_SUNKBD=y
+# CONFIG_KEYBOARD_XTKBD is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_PS2_ALPS=y
@@ -780,6 +783,7 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
 # CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_SENTELIC is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 CONFIG_MOUSE_SERIAL=y
 # CONFIG_MOUSE_APPLETOUCH is not set
@@ -883,7 +887,6 @@ CONFIG_I2C_ALGOBIT=y
 #
 # I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_I2C_DESIGNWARE is not set
 # CONFIG_I2C_OCORES is not set
 # CONFIG_I2C_SIMTEC is not set
 
@@ -1102,7 +1105,6 @@ CONFIG_FB_ATY_GX=y
 #
 # Console display driver support
 #
-# CONFIG_PROM_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
@@ -1124,6 +1126,7 @@ CONFIG_LOGO=y
 CONFIG_LOGO_SUN_CLUT224=y
 CONFIG_SOUND=m
 CONFIG_SOUND_OSS_CORE=y
+CONFIG_SOUND_OSS_CORE_PRECLAIM=y
 CONFIG_SND=m
 CONFIG_SND_TIMER=m
 CONFIG_SND_PCM=m
@@ -1232,7 +1235,6 @@ CONFIG_SND_SUN_CS4231=m
 CONFIG_AC97_BUS=m
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
 # CONFIG_HIDRAW is not set
 
 #
@@ -1256,6 +1258,7 @@ CONFIG_HID_DRAGONRISE=y
 CONFIG_HID_EZKEY=y
 CONFIG_HID_KYE=y
 CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
 CONFIG_HID_KENSINGTON=y
 CONFIG_HID_LOGITECH=y
 # CONFIG_LOGITECH_FF is not set
@@ -1289,6 +1292,7 @@ CONFIG_USB=y
 #
 # Miscellaneous USB options
 #
+# CONFIG_USB_DEVICEFS is not set
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_OTG is not set
@@ -1379,6 +1383,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_LD is not set
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
@@ -1493,6 +1498,7 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_FILE_LOCKING=y
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
@@ -1553,7 +1559,6 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 # CONFIG_NFS_FS is not set
 # CONFIG_NFSD is not set
@@ -1656,12 +1661,14 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
@@ -1692,6 +1699,7 @@ CONFIG_BLK_DEV_IO_TRACE=y
 # CONFIG_FTRACE_STARTUP_TEST is not set
 # CONFIG_RING_BUFFER_BENCHMARK is not set
 # CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
@@ -1716,7 +1724,6 @@ 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
@@ -1759,11 +1766,13 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=y
+# CONFIG_CRYPTO_VMAC is not set
 
 #
 # Digest
 #
 CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
 CONFIG_CRYPTO_MD4=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
diff --git a/arch/sparc/include/asm/agp.h b/arch/sparc/include/asm/agp.h
index c245687..70f52c1 100644
--- a/arch/sparc/include/asm/agp.h
+++ b/arch/sparc/include/asm/agp.h
@@ -7,10 +7,6 @@
 #define unmap_page_from_agp(page)
 #define flush_agp_cache() mb()
 
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
 #define alloc_gatt_pages(order)		\
 	((char *)__get_free_pages(GFP_KERNEL, (order)))
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/asm/asi.h
index 74703c5..b2e3db6 100644
--- a/arch/sparc/include/asm/asi.h
+++ b/arch/sparc/include/asm/asi.h
@@ -40,7 +40,11 @@
 #define ASI_M_UNA01         0x01   /* Same here... */
 #define ASI_M_MXCC          0x02   /* Access to TI VIKING MXCC registers */
 #define ASI_M_FLUSH_PROBE   0x03   /* Reference MMU Flush/Probe; rw, ss */
+#ifndef CONFIG_SPARC_LEON
 #define ASI_M_MMUREGS       0x04   /* MMU Registers; rw, ss */
+#else
+#define ASI_M_MMUREGS       0x19
+#endif /* CONFIG_SPARC_LEON */
 #define ASI_M_TLBDIAG       0x05   /* MMU TLB only Diagnostics */
 #define ASI_M_DIAGS         0x06   /* Reference MMU Diagnostics */
 #define ASI_M_IODIAG        0x07   /* MMU I/O TLB only Diagnostics */
diff --git a/arch/sparc/include/asm/device.h b/arch/sparc/include/asm/device.h
index 3702e08..f3b85b6 100644
--- a/arch/sparc/include/asm/device.h
+++ b/arch/sparc/include/asm/device.h
@@ -32,4 +32,7 @@ dev_archdata_get_node(const struct dev_archdata *ad)
 	return ad->prom_node;
 }
 
+struct pdev_archdata {
+};
+
 #endif /* _ASM_SPARC_DEVICE_H */
diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h
new file mode 100644
index 0000000..28a42b7
--- /dev/null
+++ b/arch/sparc/include/asm/leon.h
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com) Gaisler Research
+ * Copyright (C) 2004 Stefan Holst (mail@s-holst.de) Uni-Stuttgart
+ * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
+ * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
+ */
+
+#ifndef LEON_H_INCLUDE
+#define LEON_H_INCLUDE
+
+#ifdef CONFIG_SPARC_LEON
+
+#define ASI_LEON_NOCACHE	0x01
+
+#define ASI_LEON_DCACHE_MISS	0x1
+
+#define ASI_LEON_CACHEREGS	0x02
+#define ASI_LEON_IFLUSH		0x10
+#define ASI_LEON_DFLUSH		0x11
+
+#define ASI_LEON_MMUFLUSH	0x18
+#define ASI_LEON_MMUREGS	0x19
+#define ASI_LEON_BYPASS		0x1c
+#define ASI_LEON_FLUSH_PAGE	0x10
+
+/* mmu register access, ASI_LEON_MMUREGS */
+#define LEON_CNR_CTRL		0x000
+#define LEON_CNR_CTXP		0x100
+#define LEON_CNR_CTX		0x200
+#define LEON_CNR_F		0x300
+#define LEON_CNR_FADDR		0x400
+
+#define LEON_CNR_CTX_NCTX	256	/*number of MMU ctx */
+
+#define LEON_CNR_CTRL_TLBDIS	0x80000000
+
+#define LEON_MMUTLB_ENT_MAX	64
+
+/*
+ * diagnostic access from mmutlb.vhd:
+ * 0: pte address
+ * 4: pte
+ * 8: additional flags
+ */
+#define LEON_DIAGF_LVL		0x3
+#define LEON_DIAGF_WR		0x8
+#define LEON_DIAGF_WR_SHIFT	3
+#define LEON_DIAGF_HIT		0x10
+#define LEON_DIAGF_HIT_SHIFT	4
+#define LEON_DIAGF_CTX		0x1fe0
+#define LEON_DIAGF_CTX_SHIFT	5
+#define LEON_DIAGF_VALID	0x2000
+#define LEON_DIAGF_VALID_SHIFT	13
+
+/*
+ *  Interrupt Sources
+ *
+ *  The interrupt source numbers directly map to the trap type and to
+ *  the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
+ *  and the Interrupt Pending Registers.
+ */
+#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR	1
+#define LEON_INTERRUPT_UART_1_RX_TX		2
+#define LEON_INTERRUPT_UART_0_RX_TX		3
+#define LEON_INTERRUPT_EXTERNAL_0		4
+#define LEON_INTERRUPT_EXTERNAL_1		5
+#define LEON_INTERRUPT_EXTERNAL_2		6
+#define LEON_INTERRUPT_EXTERNAL_3		7
+#define LEON_INTERRUPT_TIMER1			8
+#define LEON_INTERRUPT_TIMER2			9
+#define LEON_INTERRUPT_EMPTY1			10
+#define LEON_INTERRUPT_EMPTY2			11
+#define LEON_INTERRUPT_OPEN_ETH			12
+#define LEON_INTERRUPT_EMPTY4			13
+#define LEON_INTERRUPT_EMPTY5			14
+#define LEON_INTERRUPT_EMPTY6			15
+
+/* irq masks */
+#define LEON_HARD_INT(x)	(1 << (x))	/* irq 0-15 */
+#define LEON_IRQMASK_R		0x0000fffe	/* bit 15- 1 of lregs.irqmask */
+#define LEON_IRQPRIO_R		0xfffe0000	/* bit 31-17 of lregs.irqmask */
+
+/* leon uart register definitions */
+#define LEON_OFF_UDATA	0x0
+#define LEON_OFF_USTAT	0x4
+#define LEON_OFF_UCTRL	0x8
+#define LEON_OFF_USCAL	0xc
+
+#define LEON_UCTRL_RE	0x01
+#define LEON_UCTRL_TE	0x02
+#define LEON_UCTRL_RI	0x04
+#define LEON_UCTRL_TI	0x08
+#define LEON_UCTRL_PS	0x10
+#define LEON_UCTRL_PE	0x20
+#define LEON_UCTRL_FL	0x40
+#define LEON_UCTRL_LB	0x80
+
+#define LEON_USTAT_DR	0x01
+#define LEON_USTAT_TS	0x02
+#define LEON_USTAT_TH	0x04
+#define LEON_USTAT_BR	0x08
+#define LEON_USTAT_OV	0x10
+#define LEON_USTAT_PE	0x20
+#define LEON_USTAT_FE	0x40
+
+#define LEON_MCFG2_SRAMDIS		0x00002000
+#define LEON_MCFG2_SDRAMEN		0x00004000
+#define LEON_MCFG2_SRAMBANKSZ		0x00001e00	/* [12-9] */
+#define LEON_MCFG2_SRAMBANKSZ_SHIFT	9
+#define LEON_MCFG2_SDRAMBANKSZ		0x03800000	/* [25-23] */
+#define LEON_MCFG2_SDRAMBANKSZ_SHIFT	23
+
+#define LEON_TCNT0_MASK	0x7fffff
+
+#define LEON_USTAT_ERROR (LEON_USTAT_OV | LEON_USTAT_PE | LEON_USTAT_FE)
+/* no break yet */
+
+#define ASI_LEON3_SYSCTRL		0x02
+#define ASI_LEON3_SYSCTRL_ICFG		0x08
+#define ASI_LEON3_SYSCTRL_DCFG		0x0c
+#define ASI_LEON3_SYSCTRL_CFG_SNOOPING (1 << 27)
+#define ASI_LEON3_SYSCTRL_CFG_SSIZE(c) (1 << ((c >> 20) & 0xf))
+
+#ifndef __ASSEMBLY__
+
+/* do a virtual address read without cache */
+static inline unsigned long leon_readnobuffer_reg(unsigned long paddr)
+{
+	unsigned long retval;
+	__asm__ __volatile__("lda [%1] %2, %0\n\t" :
+			     "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE));
+	return retval;
+}
+
+/* do a physical address bypass write, i.e. for 0x80000000 */
+static inline void leon_store_reg(unsigned long paddr, unsigned long value)
+{
+	__asm__ __volatile__("sta %0, [%1] %2\n\t" : : "r"(value), "r"(paddr),
+			     "i"(ASI_LEON_BYPASS) : "memory");
+}
+
+/* do a physical address bypass load, i.e. for 0x80000000 */
+static inline unsigned long leon_load_reg(unsigned long paddr)
+{
+	unsigned long retval;
+	__asm__ __volatile__("lda [%1] %2, %0\n\t" :
+			     "=r"(retval) : "r"(paddr), "i"(ASI_LEON_BYPASS));
+	return retval;
+}
+
+extern inline void leon_srmmu_disabletlb(void)
+{
+	unsigned int retval;
+	__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
+			     "i"(ASI_LEON_MMUREGS));
+	retval |= LEON_CNR_CTRL_TLBDIS;
+	__asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
+			     "i"(ASI_LEON_MMUREGS) : "memory");
+}
+
+extern inline void leon_srmmu_enabletlb(void)
+{
+	unsigned int retval;
+	__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
+			     "i"(ASI_LEON_MMUREGS));
+	retval = retval & ~LEON_CNR_CTRL_TLBDIS;
+	__asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
+			     "i"(ASI_LEON_MMUREGS) : "memory");
+}
+
+/* macro access for leon_load_reg() and leon_store_reg() */
+#define LEON3_BYPASS_LOAD_PA(x)	    (leon_load_reg((unsigned long)(x)))
+#define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v)))
+#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v)
+#define LEON3_BYPASS_ORIN_PA(x, v)  LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v)
+#define LEON_BYPASS_LOAD_PA(x)      leon_load_reg((unsigned long)(x))
+#define LEON_BYPASS_STORE_PA(x, v)  leon_store_reg((unsigned long)(x), (unsigned long)(v))
+#define LEON_REGLOAD_PA(x)          leon_load_reg((unsigned long)(x)+LEON_PREGS)
+#define LEON_REGSTORE_PA(x, v)      leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v))
+#define LEON_REGSTORE_OR_PA(x, v)   LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v))
+#define LEON_REGSTORE_AND_PA(x, v)  LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v))
+
+/* macro access for leon_readnobuffer_reg() */
+#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
+
+extern void sparc_leon_eirq_register(int eirq);
+extern void leon_init(void);
+extern void leon_switch_mm(void);
+extern void leon_init_IRQ(void);
+
+extern unsigned long last_valid_pfn;
+
+extern inline unsigned long sparc_leon3_get_dcachecfg(void)
+{
+	unsigned int retval;
+	__asm__ __volatile__("lda [%1] %2, %0\n\t" :
+			     "=r"(retval) :
+			     "r"(ASI_LEON3_SYSCTRL_DCFG),
+			     "i"(ASI_LEON3_SYSCTRL));
+	return retval;
+}
+
+/* enable snooping */
+extern inline void sparc_leon3_enable_snooping(void)
+{
+	__asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
+			  "set 0x800000, %%l2\n\t"
+			  "or  %%l2, %%l1, %%l2\n\t"
+			  "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
+};
+
+extern inline void sparc_leon3_disable_cache(void)
+{
+	__asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
+			  "set 0x00000f, %%l2\n\t"
+			  "andn  %%l2, %%l1, %%l2\n\t"
+			  "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
+};
+
+#endif /*!__ASSEMBLY__*/
+
+#ifdef CONFIG_SMP
+# define LEON3_IRQ_RESCHEDULE		13
+# define LEON3_IRQ_TICKER		(leon_percpu_timer_dev[0].irq)
+# define LEON3_IRQ_CROSS_CALL		15
+#endif
+
+#if defined(PAGE_SIZE_LEON_8K)
+#define LEON_PAGE_SIZE_LEON 1
+#elif defined(PAGE_SIZE_LEON_16K)
+#define LEON_PAGE_SIZE_LEON 2)
+#else
+#define LEON_PAGE_SIZE_LEON 0
+#endif
+
+#if LEON_PAGE_SIZE_LEON == 0
+/* [ 8, 6, 6 ] + 12 */
+#define LEON_PGD_SH    24
+#define LEON_PGD_M     0xff
+#define LEON_PMD_SH    18
+#define LEON_PMD_SH_V  (LEON_PGD_SH-2)
+#define LEON_PMD_M     0x3f
+#define LEON_PTE_SH    12
+#define LEON_PTE_M     0x3f
+#elif LEON_PAGE_SIZE_LEON == 1
+/* [ 7, 6, 6 ] + 13 */
+#define LEON_PGD_SH    25
+#define LEON_PGD_M     0x7f
+#define LEON_PMD_SH    19
+#define LEON_PMD_SH_V  (LEON_PGD_SH-1)
+#define LEON_PMD_M     0x3f
+#define LEON_PTE_SH    13
+#define LEON_PTE_M     0x3f
+#elif LEON_PAGE_SIZE_LEON == 2
+/* [ 6, 6, 6 ] + 14 */
+#define LEON_PGD_SH    26
+#define LEON_PGD_M     0x3f
+#define LEON_PMD_SH    20
+#define LEON_PMD_SH_V  (LEON_PGD_SH-0)
+#define LEON_PMD_M     0x3f
+#define LEON_PTE_SH    14
+#define LEON_PTE_M     0x3f
+#elif LEON_PAGE_SIZE_LEON == 3
+/* [ 4, 7, 6 ] + 15 */
+#define LEON_PGD_SH    28
+#define LEON_PGD_M     0x0f
+#define LEON_PMD_SH    21
+#define LEON_PMD_SH_V  (LEON_PGD_SH-0)
+#define LEON_PMD_M     0x7f
+#define LEON_PTE_SH    15
+#define LEON_PTE_M     0x3f
+#else
+#error cannot determine LEON_PAGE_SIZE_LEON
+#endif
+
+#define PAGE_MIN_SHIFT   (12)
+#define PAGE_MIN_SIZE    (1UL << PAGE_MIN_SHIFT)
+
+#define LEON3_XCCR_SETS_MASK  0x07000000UL
+#define LEON3_XCCR_SSIZE_MASK 0x00f00000UL
+
+#define LEON2_CCR_DSETS_MASK 0x03000000UL
+#define LEON2_CFG_SSIZE_MASK 0x00007000UL
+
+#ifndef __ASSEMBLY__
+extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
+extern void leon_flush_icache_all(void);
+extern void leon_flush_dcache_all(void);
+extern void leon_flush_cache_all(void);
+extern void leon_flush_tlb_all(void);
+extern int leon_flush_during_switch;
+extern int leon_flush_needed(void);
+
+struct vm_area_struct;
+extern void leon_flush_icache_all(void);
+extern void leon_flush_dcache_all(void);
+extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
+extern void leon_flush_cache_all(void);
+extern void leon_flush_tlb_all(void);
+extern int leon_flush_during_switch;
+extern int leon_flush_needed(void);
+extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
+
+/* struct that hold LEON3 cache configuration registers */
+struct leon3_cacheregs {
+	unsigned long ccr;	/* 0x00 - Cache Control Register  */
+	unsigned long iccr;     /* 0x08 - Instruction Cache Configuration Register */
+	unsigned long dccr;	/* 0x0c - Data Cache Configuration Register */
+};
+
+/* struct that hold LEON2 cache configuration register
+ * & configuration register
+ */
+struct leon2_cacheregs {
+	unsigned long ccr, cfg;
+};
+
+#ifdef __KERNEL__
+
+#include <linux/interrupt.h>
+
+struct device_node;
+extern int sparc_leon_eirq_get(int eirq, int cpu);
+extern irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id);
+extern void sparc_leon_eirq_register(int eirq);
+extern void leon_clear_clock_irq(void);
+extern void leon_load_profile_irq(int cpu, unsigned int limit);
+extern void leon_init_timers(irq_handler_t counter_fn);
+extern void leon_clear_clock_irq(void);
+extern void leon_load_profile_irq(int cpu, unsigned int limit);
+extern void leon_trans_init(struct device_node *dp);
+extern void leon_node_init(struct device_node *dp, struct device_node ***nextp);
+extern void leon_init_IRQ(void);
+extern void leon_init(void);
+extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
+extern void init_leon(void);
+extern void poke_leonsparc(void);
+extern void leon3_getCacheRegs(struct leon3_cacheregs *regs);
+extern int leon_flush_needed(void);
+extern void leon_switch_mm(void);
+extern int srmmu_swprobe_trace;
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+/* macros used in leon_mm.c */
+#define PFN(x)           ((x) >> PAGE_SHIFT)
+#define _pfn_valid(pfn)	 ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base)))
+#define _SRMMU_PTE_PMASK_LEON 0xffffffff
+
+#else /* defined(CONFIG_SPARC_LEON) */
+
+/* nop definitions for !LEON case */
+#define leon_init() do {} while (0)
+#define leon_switch_mm() do {} while (0)
+#define leon_init_IRQ() do {} while (0)
+#define init_leon() do {} while (0)
+
+#endif /* !defined(CONFIG_SPARC_LEON) */
+
+#endif
diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h
new file mode 100644
index 0000000..618e888
--- /dev/null
+++ b/arch/sparc/include/asm/leon_amba.h
@@ -0,0 +1,263 @@
+/*
+*Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com), Gaisler Research
+*Copyright (C) 2004 Stefan Holst (mail@s-holst.de), Uni-Stuttgart
+*Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com),Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
+*/
+
+#ifndef LEON_AMBA_H_INCLUDE
+#define LEON_AMBA_H_INCLUDE
+
+#ifndef __ASSEMBLY__
+
+struct amba_prom_registers {
+	unsigned int phys_addr;	/* The physical address of this register */
+	unsigned int reg_size;	/* How many bytes does this register take up? */
+};
+
+#endif
+
+/*
+ *  The following defines the bits in the LEON UART Status Registers.
+ */
+
+#define LEON_REG_UART_STATUS_DR   0x00000001	/* Data Ready */
+#define LEON_REG_UART_STATUS_TSE  0x00000002	/* TX Send Register Empty */
+#define LEON_REG_UART_STATUS_THE  0x00000004	/* TX Hold Register Empty */
+#define LEON_REG_UART_STATUS_BR   0x00000008	/* Break Error */
+#define LEON_REG_UART_STATUS_OE   0x00000010	/* RX Overrun Error */
+#define LEON_REG_UART_STATUS_PE   0x00000020	/* RX Parity Error */
+#define LEON_REG_UART_STATUS_FE   0x00000040	/* RX Framing Error */
+#define LEON_REG_UART_STATUS_ERR  0x00000078	/* Error Mask */
+
+/*
+ *  The following defines the bits in the LEON UART Ctrl Registers.
+ */
+
+#define LEON_REG_UART_CTRL_RE     0x00000001	/* Receiver enable */
+#define LEON_REG_UART_CTRL_TE     0x00000002	/* Transmitter enable */
+#define LEON_REG_UART_CTRL_RI     0x00000004	/* Receiver interrupt enable */
+#define LEON_REG_UART_CTRL_TI     0x00000008	/* Transmitter irq */
+#define LEON_REG_UART_CTRL_PS     0x00000010	/* Parity select */
+#define LEON_REG_UART_CTRL_PE     0x00000020	/* Parity enable */
+#define LEON_REG_UART_CTRL_FL     0x00000040	/* Flow control enable */
+#define LEON_REG_UART_CTRL_LB     0x00000080	/* Loop Back enable */
+
+#define LEON3_GPTIMER_EN 1
+#define LEON3_GPTIMER_RL 2
+#define LEON3_GPTIMER_LD 4
+#define LEON3_GPTIMER_IRQEN 8
+#define LEON3_GPTIMER_SEPIRQ 8
+
+#define LEON23_REG_TIMER_CONTROL_EN    0x00000001 /* 1 = enable counting */
+/* 0 = hold scalar and counter */
+#define LEON23_REG_TIMER_CONTROL_RL    0x00000002 /* 1 = reload at 0 */
+						  /* 0 = stop at 0 */
+#define LEON23_REG_TIMER_CONTROL_LD    0x00000004 /* 1 = load counter */
+						  /* 0 = no function */
+#define LEON23_REG_TIMER_CONTROL_IQ    0x00000008 /* 1 = irq enable */
+						  /* 0 = no function */
+
+/*
+ *  The following defines the bits in the LEON PS/2 Status Registers.
+ */
+
+#define LEON_REG_PS2_STATUS_DR   0x00000001	/* Data Ready */
+#define LEON_REG_PS2_STATUS_PE   0x00000002	/* Parity error */
+#define LEON_REG_PS2_STATUS_FE   0x00000004	/* Framing error */
+#define LEON_REG_PS2_STATUS_KI   0x00000008	/* Keyboard inhibit */
+#define LEON_REG_PS2_STATUS_RF   0x00000010	/* RX buffer full */
+#define LEON_REG_PS2_STATUS_TF   0x00000020	/* TX buffer full */
+
+/*
+ *  The following defines the bits in the LEON PS/2 Ctrl Registers.
+ */
+
+#define LEON_REG_PS2_CTRL_RE 0x00000001	/* Receiver enable */
+#define LEON_REG_PS2_CTRL_TE 0x00000002	/* Transmitter enable */
+#define LEON_REG_PS2_CTRL_RI 0x00000004	/* Keyboard receive irq  */
+#define LEON_REG_PS2_CTRL_TI 0x00000008	/* Keyboard transmit irq */
+
+#define LEON3_IRQMPSTATUS_CPUNR     28
+#define LEON3_IRQMPSTATUS_BROADCAST 27
+
+#define GPTIMER_CONFIG_IRQNT(a)          (((a) >> 3) & 0x1f)
+#define GPTIMER_CONFIG_ISSEP(a)          ((a) & (1 << 8))
+#define GPTIMER_CONFIG_NTIMERS(a)        ((a) & (0x7))
+#define LEON3_GPTIMER_CTRL_PENDING       0x10
+#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7)
+#define LEON3_GPTIMER_CTRL_ISPENDING(r)  (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0)
+
+#ifdef CONFIG_SPARC_LEON
+
+#ifndef __ASSEMBLY__
+
+struct leon3_irqctrl_regs_map {
+	u32 ilevel;
+	u32 ipend;
+	u32 iforce;
+	u32 iclear;
+	u32 mpstatus;
+	u32 mpbroadcast;
+	u32 notused02;
+	u32 notused03;
+	u32 notused10;
+	u32 notused11;
+	u32 notused12;
+	u32 notused13;
+	u32 notused20;
+	u32 notused21;
+	u32 notused22;
+	u32 notused23;
+	u32 mask[16];
+	u32 force[16];
+	/* Extended IRQ registers */
+	u32 intid[16];	/* 0xc0 */
+};
+
+struct leon3_apbuart_regs_map {
+	u32 data;
+	u32 status;
+	u32 ctrl;
+	u32 scaler;
+};
+
+struct leon3_gptimerelem_regs_map {
+	u32 val;
+	u32 rld;
+	u32 ctrl;
+	u32 unused;
+};
+
+struct leon3_gptimer_regs_map {
+	u32 scalar;
+	u32 scalar_reload;
+	u32 config;
+	u32 unused;
+	struct leon3_gptimerelem_regs_map e[8];
+};
+
+/*
+ *  Types and structure used for AMBA Plug & Play bus scanning
+ */
+
+#define AMBA_MAXAPB_DEVS 64
+#define AMBA_MAXAPB_DEVS_PERBUS 16
+
+struct amba_device_table {
+	int devnr;		   /* number of devices on AHB or APB bus */
+	unsigned int *addr[16];    /* addresses to the devices configuration tables */
+	unsigned int allocbits[1]; /* 0=unallocated, 1=allocated driver */
+};
+
+struct amba_apbslv_device_table {
+	int devnr;		                  /* number of devices on AHB or APB bus */
+	unsigned int *addr[AMBA_MAXAPB_DEVS];     /* addresses to the devices configuration tables */
+	unsigned int apbmst[AMBA_MAXAPB_DEVS];    /* apb master if a entry is a apb slave */
+	unsigned int apbmstidx[AMBA_MAXAPB_DEVS]; /* apb master idx if a entry is a apb slave */
+	unsigned int allocbits[4];                /* 0=unallocated, 1=allocated driver */
+};
+
+struct amba_confarea_type {
+	struct amba_confarea_type *next;/* next bus in chain */
+	struct amba_device_table ahbmst;
+	struct amba_device_table ahbslv;
+	struct amba_apbslv_device_table apbslv;
+	unsigned int apbmst;
+};
+
+/* collect apb slaves */
+struct amba_apb_device {
+	unsigned int start, irq, bus_id;
+	struct amba_confarea_type *bus;
+};
+
+/* collect ahb slaves */
+struct amba_ahb_device {
+	unsigned int start[4], irq, bus_id;
+	struct amba_confarea_type *bus;
+};
+
+struct device_node;
+void _amba_init(struct device_node *dp, struct device_node ***nextp);
+
+extern struct leon3_irqctrl_regs_map *leon3_irqctrl_regs;
+extern struct leon3_gptimer_regs_map *leon3_gptimer_regs;
+extern struct amba_apb_device leon_percpu_timer_dev[16];
+extern int leondebug_irq_disable;
+extern int leon_debug_irqout;
+extern unsigned long leon3_gptimer_irq;
+extern unsigned int sparc_leon_eirq;
+
+#endif /* __ASSEMBLY__ */
+
+#define LEON3_IO_AREA 0xfff00000
+#define LEON3_CONF_AREA 0xff000
+#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
+
+#define LEON3_AHB_CONF_WORDS 8
+#define LEON3_APB_CONF_WORDS 2
+#define LEON3_AHB_MASTERS 16
+#define LEON3_AHB_SLAVES 16
+#define LEON3_APB_SLAVES 16
+#define LEON3_APBUARTS 8
+
+/* Vendor codes */
+#define VENDOR_GAISLER   1
+#define VENDOR_PENDER    2
+#define VENDOR_ESA       4
+#define VENDOR_OPENCORES 8
+
+/* Gaisler Research device id's */
+#define GAISLER_LEON3    0x003
+#define GAISLER_LEON3DSU 0x004
+#define GAISLER_ETHAHB   0x005
+#define GAISLER_APBMST   0x006
+#define GAISLER_AHBUART  0x007
+#define GAISLER_SRCTRL   0x008
+#define GAISLER_SDCTRL   0x009
+#define GAISLER_APBUART  0x00C
+#define GAISLER_IRQMP    0x00D
+#define GAISLER_AHBRAM   0x00E
+#define GAISLER_GPTIMER  0x011
+#define GAISLER_PCITRG   0x012
+#define GAISLER_PCISBRG  0x013
+#define GAISLER_PCIFBRG  0x014
+#define GAISLER_PCITRACE 0x015
+#define GAISLER_PCIDMA   0x016
+#define GAISLER_AHBTRACE 0x017
+#define GAISLER_ETHDSU   0x018
+#define GAISLER_PIOPORT  0x01A
+#define GAISLER_GRGPIO   0x01A
+#define GAISLER_AHBJTAG  0x01c
+#define GAISLER_ETHMAC   0x01D
+#define GAISLER_AHB2AHB  0x020
+#define GAISLER_USBDC    0x021
+#define GAISLER_ATACTRL  0x024
+#define GAISLER_DDRSPA   0x025
+#define GAISLER_USBEHC   0x026
+#define GAISLER_USBUHC   0x027
+#define GAISLER_I2CMST   0x028
+#define GAISLER_SPICTRL  0x02D
+#define GAISLER_DDR2SPA  0x02E
+#define GAISLER_SPIMCTRL 0x045
+#define GAISLER_LEON4    0x048
+#define GAISLER_LEON4DSU 0x049
+#define GAISLER_AHBSTAT  0x052
+#define GAISLER_FTMCTRL  0x054
+#define GAISLER_KBD      0x060
+#define GAISLER_VGA      0x061
+#define GAISLER_SVGA     0x063
+#define GAISLER_GRSYSMON 0x066
+#define GAISLER_GRACECTRL 0x067
+
+#define GAISLER_L2TIME   0xffd	/* internal device: leon2 timer */
+#define GAISLER_L2C      0xffe	/* internal device: leon2compat */
+#define GAISLER_PLUGPLAY 0xfff	/* internal device: plug & play configarea */
+
+#define amba_vendor(x) (((x) >> 24) & 0xff)
+
+#define amba_device(x) (((x) >> 12) & 0xfff)
+
+#endif /* !defined(CONFIG_SPARC_LEON) */
+
+#endif
diff --git a/arch/sparc/include/asm/machines.h b/arch/sparc/include/asm/machines.h
index c28c2f2..cd9c099 100644
--- a/arch/sparc/include/asm/machines.h
+++ b/arch/sparc/include/asm/machines.h
@@ -15,7 +15,7 @@ struct Sun_Machine_Models {
 /* Current number of machines we know about that has an IDPROM
  * machtype entry including one entry for the 0x80 OBP machines.
  */
-#define NUM_SUN_MACHINES   15
+#define NUM_SUN_MACHINES   16
 
 /* The machine type in the idprom area looks like this:
  *
@@ -30,6 +30,7 @@ struct Sun_Machine_Models {
 
 #define SM_ARCH_MASK  0xf0
 #define SM_SUN4       0x20
+#define  M_LEON       0x30
 #define SM_SUN4C      0x50
 #define SM_SUN4M      0x70
 #define SM_SUN4M_OBP  0x80
@@ -41,6 +42,9 @@ struct Sun_Machine_Models {
 #define SM_4_330      0x03    /* Sun 4/300 series */
 #define SM_4_470      0x04    /* Sun 4/400 series */
 
+/* Leon machines */
+#define M_LEON3_SOC   0x02    /* Leon3 SoC */
+
 /* Sun4c machines                Full Name              - PROM NAME */
 #define SM_4C_SS1     0x01    /* Sun4c SparcStation 1   - Sun 4/60  */
 #define SM_4C_IPC     0x02    /* Sun4c SparcStation IPC - Sun 4/40  */
diff --git a/arch/sparc/include/asm/nmi.h b/arch/sparc/include/asm/nmi.h
index fbd546d..72e6500 100644
--- a/arch/sparc/include/asm/nmi.h
+++ b/arch/sparc/include/asm/nmi.h
@@ -5,6 +5,9 @@ extern int __init nmi_init(void);
 extern void perfctr_irq(int irq, struct pt_regs *regs);
 extern void nmi_adjust_hz(unsigned int new_hz);
 
-extern int nmi_usable;
+extern atomic_t nmi_active;
+
+extern void start_nmi_watchdog(void *unused);
+extern void stop_nmi_watchdog(void *unused);
 
 #endif /* __NMI_H */
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index ac0e836..e769f66 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -10,7 +10,6 @@
  * or architectures with incomplete PCI setup by the loader.
  */
 #define pcibios_assign_all_busses()	0
-#define pcibios_scan_all_fns(a, b)	0
 
 #define PCIBIOS_MIN_IO		0UL
 #define PCIBIOS_MIN_MEM		0UL
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 5cc9f6a..b63e51c 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -10,7 +10,6 @@
  * or architectures with incomplete PCI setup by the loader.
  */
 #define pcibios_assign_all_busses()	0
-#define pcibios_scan_all_fns(a, b)	0
 
 #define PCIBIOS_MIN_IO		0UL
 #define PCIBIOS_MIN_MEM		0UL
diff --git a/arch/sparc/include/asm/perf_event.h b/arch/sparc/include/asm/perf_event.h
new file mode 100644
index 0000000..7e26698
--- /dev/null
+++ b/arch/sparc/include/asm/perf_event.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_SPARC_PERF_EVENT_H
+#define __ASM_SPARC_PERF_EVENT_H
+
+extern void set_perf_event_pending(void);
+
+#define	PERF_EVENT_INDEX_OFFSET	0
+
+#ifdef CONFIG_PERF_EVENTS
+extern void init_hw_perf_events(void);
+#else
+static inline void init_hw_perf_events(void)	{ }
+#endif
+
+#endif
diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h
index 808555f..1407c07 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -267,6 +267,7 @@ static inline void srmmu_flush_tlb_page(unsigned long page)
 
 }
 
+#ifndef CONFIG_SPARC_LEON
 static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
 {
 	unsigned long retval;
@@ -278,6 +279,9 @@ static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
 
 	return retval;
 }
+#else
+#define srmmu_hwprobe(addr) (srmmu_swprobe(addr, 0) & SRMMU_PTE_PMASK)
+#endif
 
 static inline int
 srmmu_get_pte (unsigned long addr)
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index be8d7aa..82a190d 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -118,5 +118,8 @@ extern struct device_node *of_console_device;
 extern char *of_console_path;
 extern char *of_console_options;
 
+extern void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);
+extern char *build_full_name(struct device_node *dp);
+
 #endif /* __KERNEL__ */
 #endif /* _SPARC_PROM_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/asm/socket.h
index 982a12f..3a5ae3d 100644
--- a/arch/sparc/include/asm/socket.h
+++ b/arch/sparc/include/asm/socket.h
@@ -29,6 +29,9 @@
 #define SO_RCVBUFFORCE	0x100b
 #define SO_ERROR	0x1007
 #define SO_TYPE		0x1008
+#define SO_PROTOCOL	0x1028
+#define SO_DOMAIN	0x1029
+
 
 /* Linux specific, keep the same. */
 #define SO_NO_CHECK	0x000b
diff --git a/arch/sparc/include/asm/system_32.h b/arch/sparc/include/asm/system_32.h
index 751c8c1..890036b 100644
--- a/arch/sparc/include/asm/system_32.h
+++ b/arch/sparc/include/asm/system_32.h
@@ -32,6 +32,7 @@ enum sparc_cpu {
   sun4u       = 0x05, /* V8 ploos ploos */
   sun_unknown = 0x06,
   ap1000      = 0x07, /* almost a sun4m */
+  sparc_leon  = 0x08, /* Leon SoC */
 };
 
 /* Really, userland should not be looking at any of this... */
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h
index 6c07781..25e848f 100644
--- a/arch/sparc/include/asm/system_64.h
+++ b/arch/sparc/include/asm/system_64.h
@@ -29,6 +29,10 @@ enum sparc_cpu {
 /* This cannot ever be a sun4c :) That's just history. */
 #define ARCH_SUN4C 0
 
+extern const char *sparc_cpu_type;
+extern const char *sparc_fpu_type;
+extern const char *sparc_pmu_type;
+
 extern char reboot_command[];
 
 /* These are here in an effort to more fully work around Spitfire Errata
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h
index e5ea8d3..26cd25c 100644
--- a/arch/sparc/include/asm/topology_64.h
+++ b/arch/sparc/include/asm/topology_64.h
@@ -52,13 +52,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
 	.busy_idx		= 3,			\
 	.idle_idx		= 2,			\
 	.newidle_idx		= 0, 			\
-	.wake_idx		= 1,			\
-	.forkexec_idx		= 1,			\
+	.wake_idx		= 0,			\
+	.forkexec_idx		= 0,			\
 	.flags			= SD_LOAD_BALANCE	\
 				| SD_BALANCE_FORK	\
 				| SD_BALANCE_EXEC	\
-				| SD_SERIALIZE		\
-				| SD_WAKE_BALANCE,	\
+				| SD_SERIALIZE,		\
 	.last_balance		= jiffies,		\
 	.balance_interval	= 1,			\
 }
diff --git a/arch/sparc/include/asm/types.h b/arch/sparc/include/asm/types.h
index de671d7..09c79a9 100644
--- a/arch/sparc/include/asm/types.h
+++ b/arch/sparc/include/asm/types.h
@@ -8,9 +8,8 @@
  * need to be careful to avoid a name clashes.
  */
 
-#if defined(__sparc__) && defined(__arch64__)
+#if defined(__sparc__)
 
-/*** SPARC 64 bit ***/
 #include <asm-generic/int-ll64.h>
 
 #ifndef __ASSEMBLY__
@@ -26,33 +25,21 @@ typedef unsigned short umode_t;
 /* Dma addresses come in generic and 64-bit flavours.  */
 
 typedef u32 dma_addr_t;
-typedef u64 dma64_addr_t;
 
-#endif /* __ASSEMBLY__ */
+#if defined(__arch64__)
 
-#endif /* __KERNEL__ */
+/*** SPARC 64 bit ***/
+typedef u64 dma64_addr_t;
 #else
-
 /*** SPARC 32 bit ***/
-#include <asm-generic/int-ll64.h>
-
-#ifndef __ASSEMBLY__
-
-typedef unsigned short umode_t;
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
-
-#ifndef __ASSEMBLY__
-
-typedef u32 dma_addr_t;
 typedef u32 dma64_addr_t;
 
+#endif /* defined(__arch64__) */
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
 
-#endif /* defined(__sparc__) && defined(__arch64__) */
+#endif /* defined(__sparc__) */
 
 #endif /* defined(_SPARC_TYPES_H) */
diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
index a38c032..9ea271e 100644
--- a/arch/sparc/include/asm/uaccess_64.h
+++ b/arch/sparc/include/asm/uaccess_64.h
@@ -7,8 +7,8 @@
 
 #ifdef __KERNEL__
 #include <linux/compiler.h>
-#include <linux/sched.h>
 #include <linux/string.h>
+#include <linux/thread_info.h>
 #include <asm/asi.h>
 #include <asm/system.h>
 #include <asm/spitfire.h>
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index b2c406d..42f2316 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -395,8 +395,9 @@
 #define __NR_preadv		324
 #define __NR_pwritev		325
 #define __NR_rt_tgsigqueueinfo	326
+#define __NR_perf_event_open	327
 
-#define NR_SYSCALLS		327
+#define NR_SYSCALLS		328
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 29b88a5..3a048fa 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -41,6 +41,8 @@ obj-y                   += of_device_common.o
 obj-y                   += of_device_$(BITS).o
 obj-$(CONFIG_SPARC64)   += prom_irqtrans.o
 
+obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o
+
 obj-$(CONFIG_SPARC64)   += reboot.o
 obj-$(CONFIG_SPARC64)   += sysfs.o
 obj-$(CONFIG_SPARC64)   += iommu.o
@@ -101,3 +103,6 @@ obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
 obj-$(CONFIG_AUDIT)     += audit.o
 audit--$(CONFIG_AUDIT)  := compat_audit.o
 obj-$(CONFIG_COMPAT)    += $(audit--y)
+
+pc--$(CONFIG_PERF_EVENTS) := perf_event.o
+obj-$(CONFIG_SPARC64)	+= $(pc--y)
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index d85c3dc..1446df9 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -312,7 +312,12 @@ void __cpuinit cpu_probe(void)
 
 	psr = get_psr();
 	put_psr(psr | PSR_EF);
+#ifdef CONFIG_SPARC_LEON
+	fpu_vers = 7;
+#else
 	fpu_vers = ((get_fsr() >> 17) & 0x7);
+#endif
+
 	put_psr(psr);
 
 	set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers);
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index 6b4d8ac..439d82a 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -809,6 +809,11 @@ found_version:
 		 nop
 
 got_prop:
+#ifdef CONFIG_SPARC_LEON
+	        /* no cpu-type check is needed, it is a SPARC-LEON */
+		ba sun4c_continue_boot
+		 nop
+#endif
 		set	cputypval, %o2
 		ldub	[%o2 + 0x4], %l1
 
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c
index 57922f6..52a15fe 100644
--- a/arch/sparc/kernel/idprom.c
+++ b/arch/sparc/kernel/idprom.c
@@ -31,6 +31,8 @@ static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
 { .name = "Sun 4/200 Series",        .id_machtype = (SM_SUN4 | SM_4_260) },
 { .name = "Sun 4/300 Series",        .id_machtype = (SM_SUN4 | SM_4_330) },
 { .name = "Sun 4/400 Series",        .id_machtype = (SM_SUN4 | SM_4_470) },
+/* Now Leon */
+{ .name = "Leon3 System-on-a-Chip",  .id_machtype = (M_LEON | M_LEON3_SOC) },
 /* Now, Sun4c's */
 { .name = "Sun4c SparcStation 1",    .id_machtype = (SM_SUN4C | SM_4C_SS1) },
 { .name = "Sun4c SparcStation IPC",  .id_machtype = (SM_SUN4C | SM_4C_IPC) },
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index edbea23..9f61fd8 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -35,6 +35,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>		/* struct pci_dev */
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/scatterlist.h>
 #include <linux/of_device.h>
 
@@ -683,26 +684,33 @@ EXPORT_SYMBOL(dma_set_mask);
 
 #ifdef CONFIG_PROC_FS
 
-static int
-_sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof,
-    void *data)
+static int sparc_io_proc_show(struct seq_file *m, void *v)
 {
-	char *p = buf, *e = buf + length;
-	struct resource *r;
+	struct resource *root = m->private, *r;
 	const char *nm;
 
-	for (r = ((struct resource *)data)->child; r != NULL; r = r->sibling) {
-		if (p + 32 >= e)	/* Better than nothing */
-			break;
+	for (r = root->child; r != NULL; r = r->sibling) {
 		if ((nm = r->name) == 0) nm = "???";
-		p += sprintf(p, "%016llx-%016llx: %s\n",
+		seq_printf(m, "%016llx-%016llx: %s\n",
 				(unsigned long long)r->start,
 				(unsigned long long)r->end, nm);
 	}
 
-	return p-buf;
+	return 0;
 }
 
+static int sparc_io_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sparc_io_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations sparc_io_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sparc_io_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 #endif /* CONFIG_PROC_FS */
 
 /*
@@ -727,7 +735,7 @@ static struct resource *_sparc_find_resource(struct resource *root,
 static void register_proc_sparc_ioport(void)
 {
 #ifdef CONFIG_PROC_FS
-	create_proc_read_entry("io_map",0,NULL,_sparc_io_get_info,&sparc_iomap);
-	create_proc_read_entry("dvma_map",0,NULL,_sparc_io_get_info,&_sparc_dvma);
+	proc_create_data("io_map", 0, NULL, &sparc_io_proc_fops, &sparc_iomap);
+	proc_create_data("dvma_map", 0, NULL, &sparc_io_proc_fops, &_sparc_dvma);
 #endif
 }
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index ad800b8..e1af437 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -45,6 +45,7 @@
 #include <asm/pcic.h>
 #include <asm/cacheflush.h>
 #include <asm/irq_regs.h>
+#include <asm/leon.h>
 
 #include "kernel.h"
 #include "irq.h"
@@ -661,6 +662,10 @@ void __init init_IRQ(void)
 		sun4d_init_IRQ();
 		break;
 
+	case sparc_leon:
+		leon_init_IRQ();
+		break;
+
 	default:
 		prom_printf("Cannot initialize IRQs on this Sun machine...");
 		break;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
new file mode 100644
index 0000000..54d8a5b
--- /dev/null
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
+ * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/interrupt.h>
+#include <linux/of_device.h>
+#include <asm/oplib.h>
+#include <asm/timer.h>
+#include <asm/prom.h>
+#include <asm/leon.h>
+#include <asm/leon_amba.h>
+
+#include "prom.h"
+#include "irq.h"
+
+struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */
+struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */
+struct amba_apb_device leon_percpu_timer_dev[16];
+
+int leondebug_irq_disable;
+int leon_debug_irqout;
+static int dummy_master_l10_counter;
+
+unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */
+unsigned int sparc_leon_eirq;
+#define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
+
+/* Return the IRQ of the pending IRQ on the extended IRQ controller */
+int sparc_leon_eirq_get(int eirq, int cpu)
+{
+	return LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->intid[cpu]) & 0x1f;
+}
+
+irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id)
+{
+	printk(KERN_ERR "sparc_leon_eirq_isr: ERROR EXTENDED IRQ\n");
+	return IRQ_HANDLED;
+}
+
+/* The extended IRQ controller has been found, this function registers it */
+void sparc_leon_eirq_register(int eirq)
+{
+	int irq;
+
+	/* Register a "BAD" handler for this interrupt, it should never happen */
+	irq = request_irq(eirq, sparc_leon_eirq_isr,
+			  (IRQF_DISABLED | SA_STATIC_ALLOC), "extirq", NULL);
+
+	if (irq) {
+		printk(KERN_ERR
+		       "sparc_leon_eirq_register: unable to attach IRQ%d\n",
+		       eirq);
+	} else {
+		sparc_leon_eirq = eirq;
+	}
+
+}
+
+static inline unsigned long get_irqmask(unsigned int irq)
+{
+	unsigned long mask;
+
+	if (!irq || ((irq > 0xf) && !sparc_leon_eirq)
+	    || ((irq > 0x1f) && sparc_leon_eirq)) {
+		printk(KERN_ERR
+		       "leon_get_irqmask: false irq number: %d\n", irq);
+		mask = 0;
+	} else {
+		mask = LEON_HARD_INT(irq);
+	}
+	return mask;
+}
+
+static void leon_enable_irq(unsigned int irq_nr)
+{
+	unsigned long mask, flags;
+	mask = get_irqmask(irq_nr);
+	local_irq_save(flags);
+	LEON3_BYPASS_STORE_PA(LEON_IMASK,
+			      (LEON3_BYPASS_LOAD_PA(LEON_IMASK) | (mask)));
+	local_irq_restore(flags);
+}
+
+static void leon_disable_irq(unsigned int irq_nr)
+{
+	unsigned long mask, flags;
+	mask = get_irqmask(irq_nr);
+	local_irq_save(flags);
+	LEON3_BYPASS_STORE_PA(LEON_IMASK,
+			      (LEON3_BYPASS_LOAD_PA(LEON_IMASK) & ~(mask)));
+	local_irq_restore(flags);
+
+}
+
+void __init leon_init_timers(irq_handler_t counter_fn)
+{
+	int irq;
+
+	leondebug_irq_disable = 0;
+	leon_debug_irqout = 0;
+	master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
+	dummy_master_l10_counter = 0;
+
+	if (leon3_gptimer_regs && leon3_irqctrl_regs) {
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
+				      (((1000000 / 100) - 1)));
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
+
+	} else {
+		printk(KERN_ERR "No Timer/irqctrl found\n");
+		BUG();
+	}
+
+	irq = request_irq(leon3_gptimer_irq,
+			  counter_fn,
+			  (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
+
+	if (irq) {
+		printk(KERN_ERR "leon_time_init: unable to attach IRQ%d\n",
+		       LEON_INTERRUPT_TIMER1);
+		prom_halt();
+	}
+
+	if (leon3_gptimer_regs) {
+		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl,
+				      LEON3_GPTIMER_EN |
+				      LEON3_GPTIMER_RL |
+				      LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+	}
+}
+
+void leon_clear_clock_irq(void)
+{
+}
+
+void leon_load_profile_irq(int cpu, unsigned int limit)
+{
+	BUG();
+}
+
+
+
+
+void __init leon_trans_init(struct device_node *dp)
+{
+	if (strcmp(dp->type, "cpu") == 0 && strcmp(dp->name, "<NULL>") == 0) {
+		struct property *p;
+		p = of_find_property(dp, "mid", (void *)0);
+		if (p) {
+			int mid;
+			dp->name = prom_early_alloc(5 + 1);
+			memcpy(&mid, p->value, p->length);
+			sprintf((char *)dp->name, "cpu%.2d", mid);
+		}
+	}
+}
+
+void __initdata (*prom_amba_init)(struct device_node *dp, struct device_node ***nextp) = 0;
+
+void __init leon_node_init(struct device_node *dp, struct device_node ***nextp)
+{
+	if (prom_amba_init &&
+	    strcmp(dp->type, "ambapp") == 0 &&
+	    strcmp(dp->name, "ambapp0") == 0) {
+		prom_amba_init(dp, nextp);
+	}
+}
+
+void __init leon_init_IRQ(void)
+{
+	sparc_init_timers = leon_init_timers;
+
+	BTFIXUPSET_CALL(enable_irq, leon_enable_irq, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(disable_irq, leon_disable_irq, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(enable_pil_irq, leon_enable_irq, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(disable_pil_irq, leon_disable_irq, BTFIXUPCALL_NORM);
+
+	BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq,
+			BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(load_profile_irq, leon_load_profile_irq,
+			BTFIXUPCALL_NOP);
+
+#ifdef CONFIG_SMP
+	BTFIXUPSET_CALL(set_cpu_int, leon_set_cpu_int, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(clear_cpu_int, leon_clear_ipi, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(set_irq_udt, leon_set_udt, BTFIXUPCALL_NORM);
+#endif
+
+}
+
+void __init leon_init(void)
+{
+	prom_build_more = &leon_node_init;
+}
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index b75bf50..b129611 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/smp.h>
 
+#include <asm/perf_event.h>
 #include <asm/ptrace.h>
 #include <asm/local.h>
 #include <asm/pcr.h>
@@ -31,13 +32,19 @@
  * level 14 as our IRQ off level.
  */
 
-static int nmi_watchdog_active;
 static int panic_on_timeout;
 
-int nmi_usable;
-EXPORT_SYMBOL_GPL(nmi_usable);
+/* nmi_active:
+ * >0: the NMI watchdog is active, but can be disabled
+ * <0: the NMI watchdog has not been set up, and cannot be enabled
+ *  0: the NMI watchdog is disabled, but can be enabled
+ */
+atomic_t nmi_active = ATOMIC_INIT(0);		/* oprofile uses this */
+EXPORT_SYMBOL(nmi_active);
 
 static unsigned int nmi_hz = HZ;
+static DEFINE_PER_CPU(short, wd_enabled);
+static int endflag __initdata;
 
 static DEFINE_PER_CPU(unsigned int, last_irq_sum);
 static DEFINE_PER_CPU(local_t, alert_counter);
@@ -45,7 +52,7 @@ static DEFINE_PER_CPU(int, nmi_touch);
 
 void touch_nmi_watchdog(void)
 {
-	if (nmi_watchdog_active) {
+	if (atomic_read(&nmi_active)) {
 		int cpu;
 
 		for_each_present_cpu(cpu) {
@@ -78,6 +85,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
 	if (do_panic || panic_on_oops)
 		panic("Non maskable interrupt");
 
+	nmi_exit();
 	local_irq_enable();
 	do_exit(SIGBUS);
 }
@@ -92,6 +100,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 
 	local_cpu_data().__nmi_count++;
 
+	nmi_enter();
+
 	if (notify_die(DIE_NMI, "nmi", regs, 0,
 		       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
 		touched = 1;
@@ -110,10 +120,12 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 		__get_cpu_var(last_irq_sum) = sum;
 		local_set(&__get_cpu_var(alert_counter), 0);
 	}
-	if (nmi_usable) {
+	if (__get_cpu_var(wd_enabled)) {
 		write_pic(picl_value(nmi_hz));
 		pcr_ops->write(pcr_enable);
 	}
+
+	nmi_exit();
 }
 
 static inline unsigned int get_nmi_count(int cpu)
@@ -121,8 +133,6 @@ static inline unsigned int get_nmi_count(int cpu)
 	return cpu_data(cpu).__nmi_count;
 }
 
-static int endflag __initdata;
-
 static __init void nmi_cpu_busy(void *data)
 {
 	local_irq_enable_in_hardirq();
@@ -143,12 +153,15 @@ static void report_broken_nmi(int cpu, int *prev_nmi_count)
 	printk(KERN_WARNING
 		"and attach the output of the 'dmesg' command.\n");
 
-	nmi_usable = 0;
+	per_cpu(wd_enabled, cpu) = 0;
+	atomic_dec(&nmi_active);
 }
 
-static void stop_watchdog(void *unused)
+void stop_nmi_watchdog(void *unused)
 {
 	pcr_ops->write(PCR_PIC_PRIV);
+	__get_cpu_var(wd_enabled) = 0;
+	atomic_dec(&nmi_active);
 }
 
 static int __init check_nmi_watchdog(void)
@@ -156,6 +169,9 @@ static int __init check_nmi_watchdog(void)
 	unsigned int *prev_nmi_count;
 	int cpu, err;
 
+	if (!atomic_read(&nmi_active))
+		return 0;
+
 	prev_nmi_count = kmalloc(nr_cpu_ids * sizeof(unsigned int), GFP_KERNEL);
 	if (!prev_nmi_count) {
 		err = -ENOMEM;
@@ -172,12 +188,15 @@ static int __init check_nmi_watchdog(void)
 	mdelay((20 * 1000) / nmi_hz); /* wait 20 ticks */
 
 	for_each_online_cpu(cpu) {
+		if (!per_cpu(wd_enabled, cpu))
+			continue;
 		if (get_nmi_count(cpu) - prev_nmi_count[cpu] <= 5)
 			report_broken_nmi(cpu, prev_nmi_count);
 	}
 	endflag = 1;
-	if (!nmi_usable) {
+	if (!atomic_read(&nmi_active)) {
 		kfree(prev_nmi_count);
+		atomic_set(&nmi_active, -1);
 		err = -ENODEV;
 		goto error;
 	}
@@ -188,12 +207,26 @@ static int __init check_nmi_watchdog(void)
 	kfree(prev_nmi_count);
 	return 0;
 error:
-	on_each_cpu(stop_watchdog, NULL, 1);
+	on_each_cpu(stop_nmi_watchdog, NULL, 1);
 	return err;
 }
 
-static void start_watchdog(void *unused)
+void start_nmi_watchdog(void *unused)
 {
+	__get_cpu_var(wd_enabled) = 1;
+	atomic_inc(&nmi_active);
+
+	pcr_ops->write(PCR_PIC_PRIV);
+	write_pic(picl_value(nmi_hz));
+
+	pcr_ops->write(pcr_enable);
+}
+
+static void nmi_adjust_hz_one(void *unused)
+{
+	if (!__get_cpu_var(wd_enabled))
+		return;
+
 	pcr_ops->write(PCR_PIC_PRIV);
 	write_pic(picl_value(nmi_hz));
 
@@ -203,13 +236,13 @@ static void start_watchdog(void *unused)
 void nmi_adjust_hz(unsigned int new_hz)
 {
 	nmi_hz = new_hz;
-	on_each_cpu(start_watchdog, NULL, 1);
+	on_each_cpu(nmi_adjust_hz_one, NULL, 1);
 }
 EXPORT_SYMBOL_GPL(nmi_adjust_hz);
 
 static int nmi_shutdown(struct notifier_block *nb, unsigned long cmd, void *p)
 {
-	on_each_cpu(stop_watchdog, NULL, 1);
+	on_each_cpu(stop_nmi_watchdog, NULL, 1);
 	return 0;
 }
 
@@ -221,18 +254,19 @@ int __init nmi_init(void)
 {
 	int err;
 
-	nmi_usable = 1;
-
-	on_each_cpu(start_watchdog, NULL, 1);
+	on_each_cpu(start_nmi_watchdog, NULL, 1);
 
 	err = check_nmi_watchdog();
 	if (!err) {
 		err = register_reboot_notifier(&nmi_reboot_notifier);
 		if (err) {
-			nmi_usable = 0;
-			on_each_cpu(stop_watchdog, NULL, 1);
+			on_each_cpu(stop_nmi_watchdog, NULL, 1);
+			atomic_set(&nmi_active, -1);
 		}
 	}
+	if (!err)
+		init_hw_perf_events();
+
 	return err;
 }
 
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 9039670..4c26eb5 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -9,6 +9,8 @@
 #include <linux/irq.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
+#include <asm/leon.h>
+#include <asm/leon_amba.h>
 
 #include "of_device_common.h"
 
@@ -97,6 +99,35 @@ static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
 	return IORESOURCE_MEM;
 }
 
+ /*
+ * AMBAPP bus specific translator
+ */
+
+static int of_bus_ambapp_match(struct device_node *np)
+{
+	return !strcmp(np->name, "ambapp");
+}
+
+static void of_bus_ambapp_count_cells(struct device_node *child,
+				      int *addrc, int *sizec)
+{
+	if (addrc)
+		*addrc = 1;
+	if (sizec)
+		*sizec = 1;
+}
+
+static int of_bus_ambapp_map(u32 *addr, const u32 *range,
+			     int na, int ns, int pna)
+{
+	return of_bus_default_map(addr, range, na, ns, pna);
+}
+
+static unsigned long of_bus_ambapp_get_flags(const u32 *addr,
+					     unsigned long flags)
+{
+	return IORESOURCE_MEM;
+}
 
 /*
  * Array of bus specific translators
@@ -121,6 +152,15 @@ static struct of_bus of_busses[] = {
 		.map = of_bus_default_map,
 		.get_flags = of_bus_sbus_get_flags,
 	},
+	/* AMBA */
+	{
+		.name = "ambapp",
+		.addr_prop_name = "reg",
+		.match = of_bus_ambapp_match,
+		.count_cells = of_bus_ambapp_count_cells,
+		.map = of_bus_ambapp_map,
+		.get_flags = of_bus_ambapp_get_flags,
+	},
 	/* Default */
 	{
 		.name = "default",
diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c
index 1ae8cdd..2d94e7a 100644
--- a/arch/sparc/kernel/pcr.c
+++ b/arch/sparc/kernel/pcr.c
@@ -7,13 +7,15 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 
+#include <linux/perf_event.h>
+
 #include <asm/pil.h>
 #include <asm/pcr.h>
 #include <asm/nmi.h>
 
 /* This code is shared between various users of the performance
  * counters.  Users will be oprofile, pseudo-NMI watchdog, and the
- * perf_counter support layer.
+ * perf_event support layer.
  */
 
 #define PCR_SUN4U_ENABLE	(PCR_PIC_PRIV | PCR_STRACE | PCR_UTRACE)
@@ -34,10 +36,20 @@ unsigned int picl_shift;
  */
 void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
 {
+	struct pt_regs *old_regs;
+
 	clear_softint(1 << PIL_DEFERRED_PCR_WORK);
+
+	old_regs = set_irq_regs(regs);
+	irq_enter();
+#ifdef CONFIG_PERF_EVENTS
+	perf_event_do_pending();
+#endif
+	irq_exit();
+	set_irq_regs(old_regs);
 }
 
-void schedule_deferred_pcr_work(void)
+void set_perf_event_pending(void)
 {
 	set_softint(1 << PIL_DEFERRED_PCR_WORK);
 }
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
new file mode 100644
index 0000000..2d6a1b1
--- /dev/null
+++ b/arch/sparc/kernel/perf_event.c
@@ -0,0 +1,556 @@
+/* Performance event support for sparc64.
+ *
+ * Copyright (C) 2009 David S. Miller <davem@davemloft.net>
+ *
+ * This code is based almost entirely upon the x86 perf event
+ * code, which is:
+ *
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ */
+
+#include <linux/perf_event.h>
+#include <linux/kprobes.h>
+#include <linux/kernel.h>
+#include <linux/kdebug.h>
+#include <linux/mutex.h>
+
+#include <asm/cpudata.h>
+#include <asm/atomic.h>
+#include <asm/nmi.h>
+#include <asm/pcr.h>
+
+/* Sparc64 chips have two performance counters, 32-bits each, with
+ * overflow interrupts generated on transition from 0xffffffff to 0.
+ * The counters are accessed in one go using a 64-bit register.
+ *
+ * Both counters are controlled using a single control register.  The
+ * only way to stop all sampling is to clear all of the context (user,
+ * supervisor, hypervisor) sampling enable bits.  But these bits apply
+ * to both counters, thus the two counters can't be enabled/disabled
+ * individually.
+ *
+ * The control register has two event fields, one for each of the two
+ * counters.  It's thus nearly impossible to have one counter going
+ * while keeping the other one stopped.  Therefore it is possible to
+ * get overflow interrupts for counters not currently "in use" and
+ * that condition must be checked in the overflow interrupt handler.
+ *
+ * So we use a hack, in that we program inactive counters with the
+ * "sw_count0" and "sw_count1" events.  These count how many times
+ * the instruction "sethi %hi(0xfc000), %g0" is executed.  It's an
+ * unusual way to encode a NOP and therefore will not trigger in
+ * normal code.
+ */
+
+#define MAX_HWEVENTS			2
+#define MAX_PERIOD			((1UL << 32) - 1)
+
+#define PIC_UPPER_INDEX			0
+#define PIC_LOWER_INDEX			1
+
+struct cpu_hw_events {
+	struct perf_event	*events[MAX_HWEVENTS];
+	unsigned long		used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+	unsigned long		active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+	int enabled;
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
+
+struct perf_event_map {
+	u16	encoding;
+	u8	pic_mask;
+#define PIC_NONE	0x00
+#define PIC_UPPER	0x01
+#define PIC_LOWER	0x02
+};
+
+struct sparc_pmu {
+	const struct perf_event_map	*(*event_map)(int);
+	int				max_events;
+	int				upper_shift;
+	int				lower_shift;
+	int				event_mask;
+	int				hv_bit;
+	int				irq_bit;
+	int				upper_nop;
+	int				lower_nop;
+};
+
+static const struct perf_event_map ultra3i_perfmon_event_map[] = {
+	[PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER },
+	[PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER },
+	[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER },
+	[PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER },
+};
+
+static const struct perf_event_map *ultra3i_event_map(int event_id)
+{
+	return &ultra3i_perfmon_event_map[event_id];
+}
+
+static const struct sparc_pmu ultra3i_pmu = {
+	.event_map	= ultra3i_event_map,
+	.max_events	= ARRAY_SIZE(ultra3i_perfmon_event_map),
+	.upper_shift	= 11,
+	.lower_shift	= 4,
+	.event_mask	= 0x3f,
+	.upper_nop	= 0x1c,
+	.lower_nop	= 0x14,
+};
+
+static const struct perf_event_map niagara2_perfmon_event_map[] = {
+	[PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER },
+	[PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER },
+	[PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0208, PIC_UPPER | PIC_LOWER },
+	[PERF_COUNT_HW_CACHE_MISSES] = { 0x0302, PIC_UPPER | PIC_LOWER },
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x0201, PIC_UPPER | PIC_LOWER },
+	[PERF_COUNT_HW_BRANCH_MISSES] = { 0x0202, PIC_UPPER | PIC_LOWER },
+};
+
+static const struct perf_event_map *niagara2_event_map(int event_id)
+{
+	return &niagara2_perfmon_event_map[event_id];
+}
+
+static const struct sparc_pmu niagara2_pmu = {
+	.event_map	= niagara2_event_map,
+	.max_events	= ARRAY_SIZE(niagara2_perfmon_event_map),
+	.upper_shift	= 19,
+	.lower_shift	= 6,
+	.event_mask	= 0xfff,
+	.hv_bit		= 0x8,
+	.irq_bit	= 0x03,
+	.upper_nop	= 0x220,
+	.lower_nop	= 0x220,
+};
+
+static const struct sparc_pmu *sparc_pmu __read_mostly;
+
+static u64 event_encoding(u64 event_id, int idx)
+{
+	if (idx == PIC_UPPER_INDEX)
+		event_id <<= sparc_pmu->upper_shift;
+	else
+		event_id <<= sparc_pmu->lower_shift;
+	return event_id;
+}
+
+static u64 mask_for_index(int idx)
+{
+	return event_encoding(sparc_pmu->event_mask, idx);
+}
+
+static u64 nop_for_index(int idx)
+{
+	return event_encoding(idx == PIC_UPPER_INDEX ?
+			      sparc_pmu->upper_nop :
+			      sparc_pmu->lower_nop, idx);
+}
+
+static inline void sparc_pmu_enable_event(struct hw_perf_event *hwc,
+					    int idx)
+{
+	u64 val, mask = mask_for_index(idx);
+
+	val = pcr_ops->read();
+	pcr_ops->write((val & ~mask) | hwc->config);
+}
+
+static inline void sparc_pmu_disable_event(struct hw_perf_event *hwc,
+					     int idx)
+{
+	u64 mask = mask_for_index(idx);
+	u64 nop = nop_for_index(idx);
+	u64 val = pcr_ops->read();
+
+	pcr_ops->write((val & ~mask) | nop);
+}
+
+void hw_perf_enable(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	u64 val;
+	int i;
+
+	if (cpuc->enabled)
+		return;
+
+	cpuc->enabled = 1;
+	barrier();
+
+	val = pcr_ops->read();
+
+	for (i = 0; i < MAX_HWEVENTS; i++) {
+		struct perf_event *cp = cpuc->events[i];
+		struct hw_perf_event *hwc;
+
+		if (!cp)
+			continue;
+		hwc = &cp->hw;
+		val |= hwc->config_base;
+	}
+
+	pcr_ops->write(val);
+}
+
+void hw_perf_disable(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	u64 val;
+
+	if (!cpuc->enabled)
+		return;
+
+	cpuc->enabled = 0;
+
+	val = pcr_ops->read();
+	val &= ~(PCR_UTRACE | PCR_STRACE |
+		 sparc_pmu->hv_bit | sparc_pmu->irq_bit);
+	pcr_ops->write(val);
+}
+
+static u32 read_pmc(int idx)
+{
+	u64 val;
+
+	read_pic(val);
+	if (idx == PIC_UPPER_INDEX)
+		val >>= 32;
+
+	return val & 0xffffffff;
+}
+
+static void write_pmc(int idx, u64 val)
+{
+	u64 shift, mask, pic;
+
+	shift = 0;
+	if (idx == PIC_UPPER_INDEX)
+		shift = 32;
+
+	mask = ((u64) 0xffffffff) << shift;
+	val <<= shift;
+
+	read_pic(pic);
+	pic &= ~mask;
+	pic |= val;
+	write_pic(pic);
+}
+
+static int sparc_perf_event_set_period(struct perf_event *event,
+					 struct hw_perf_event *hwc, int idx)
+{
+	s64 left = atomic64_read(&hwc->period_left);
+	s64 period = hwc->sample_period;
+	int ret = 0;
+
+	if (unlikely(left <= -period)) {
+		left = period;
+		atomic64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+
+	if (unlikely(left <= 0)) {
+		left += period;
+		atomic64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+	if (left > MAX_PERIOD)
+		left = MAX_PERIOD;
+
+	atomic64_set(&hwc->prev_count, (u64)-left);
+
+	write_pmc(idx, (u64)(-left) & 0xffffffff);
+
+	perf_event_update_userpage(event);
+
+	return ret;
+}
+
+static int sparc_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	if (test_and_set_bit(idx, cpuc->used_mask))
+		return -EAGAIN;
+
+	sparc_pmu_disable_event(hwc, idx);
+
+	cpuc->events[idx] = event;
+	set_bit(idx, cpuc->active_mask);
+
+	sparc_perf_event_set_period(event, hwc, idx);
+	sparc_pmu_enable_event(hwc, idx);
+	perf_event_update_userpage(event);
+	return 0;
+}
+
+static u64 sparc_perf_event_update(struct perf_event *event,
+				     struct hw_perf_event *hwc, int idx)
+{
+	int shift = 64 - 32;
+	u64 prev_raw_count, new_raw_count;
+	s64 delta;
+
+again:
+	prev_raw_count = atomic64_read(&hwc->prev_count);
+	new_raw_count = read_pmc(idx);
+
+	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			     new_raw_count) != prev_raw_count)
+		goto again;
+
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	atomic64_add(delta, &event->count);
+	atomic64_sub(delta, &hwc->period_left);
+
+	return new_raw_count;
+}
+
+static void sparc_pmu_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	clear_bit(idx, cpuc->active_mask);
+	sparc_pmu_disable_event(hwc, idx);
+
+	barrier();
+
+	sparc_perf_event_update(event, hwc, idx);
+	cpuc->events[idx] = NULL;
+	clear_bit(idx, cpuc->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+static void sparc_pmu_read(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	sparc_perf_event_update(event, hwc, hwc->idx);
+}
+
+static void sparc_pmu_unthrottle(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	sparc_pmu_enable_event(hwc, hwc->idx);
+}
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmc_grab_mutex);
+
+void perf_event_grab_pmc(void)
+{
+	if (atomic_inc_not_zero(&active_events))
+		return;
+
+	mutex_lock(&pmc_grab_mutex);
+	if (atomic_read(&active_events) == 0) {
+		if (atomic_read(&nmi_active) > 0) {
+			on_each_cpu(stop_nmi_watchdog, NULL, 1);
+			BUG_ON(atomic_read(&nmi_active) != 0);
+		}
+		atomic_inc(&active_events);
+	}
+	mutex_unlock(&pmc_grab_mutex);
+}
+
+void perf_event_release_pmc(void)
+{
+	if (atomic_dec_and_mutex_lock(&active_events, &pmc_grab_mutex)) {
+		if (atomic_read(&nmi_active) == 0)
+			on_each_cpu(start_nmi_watchdog, NULL, 1);
+		mutex_unlock(&pmc_grab_mutex);
+	}
+}
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	perf_event_release_pmc();
+}
+
+static int __hw_perf_event_init(struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	struct hw_perf_event *hwc = &event->hw;
+	const struct perf_event_map *pmap;
+	u64 enc;
+
+	if (atomic_read(&nmi_active) < 0)
+		return -ENODEV;
+
+	if (attr->type != PERF_TYPE_HARDWARE)
+		return -EOPNOTSUPP;
+
+	if (attr->config >= sparc_pmu->max_events)
+		return -EINVAL;
+
+	perf_event_grab_pmc();
+	event->destroy = hw_perf_event_destroy;
+
+	/* We save the enable bits in the config_base.  So to
+	 * turn off sampling just write 'config', and to enable
+	 * things write 'config | config_base'.
+	 */
+	hwc->config_base = sparc_pmu->irq_bit;
+	if (!attr->exclude_user)
+		hwc->config_base |= PCR_UTRACE;
+	if (!attr->exclude_kernel)
+		hwc->config_base |= PCR_STRACE;
+	if (!attr->exclude_hv)
+		hwc->config_base |= sparc_pmu->hv_bit;
+
+	if (!hwc->sample_period) {
+		hwc->sample_period = MAX_PERIOD;
+		hwc->last_period = hwc->sample_period;
+		atomic64_set(&hwc->period_left, hwc->sample_period);
+	}
+
+	pmap = sparc_pmu->event_map(attr->config);
+
+	enc = pmap->encoding;
+	if (pmap->pic_mask & PIC_UPPER) {
+		hwc->idx = PIC_UPPER_INDEX;
+		enc <<= sparc_pmu->upper_shift;
+	} else {
+		hwc->idx = PIC_LOWER_INDEX;
+		enc <<= sparc_pmu->lower_shift;
+	}
+
+	hwc->config |= enc;
+	return 0;
+}
+
+static const struct pmu pmu = {
+	.enable		= sparc_pmu_enable,
+	.disable	= sparc_pmu_disable,
+	.read		= sparc_pmu_read,
+	.unthrottle	= sparc_pmu_unthrottle,
+};
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+	int err = __hw_perf_event_init(event);
+
+	if (err)
+		return ERR_PTR(err);
+	return &pmu;
+}
+
+void perf_event_print_debug(void)
+{
+	unsigned long flags;
+	u64 pcr, pic;
+	int cpu;
+
+	if (!sparc_pmu)
+		return;
+
+	local_irq_save(flags);
+
+	cpu = smp_processor_id();
+
+	pcr = pcr_ops->read();
+	read_pic(pic);
+
+	pr_info("\n");
+	pr_info("CPU#%d: PCR[%016llx] PIC[%016llx]\n",
+		cpu, pcr, pic);
+
+	local_irq_restore(flags);
+}
+
+static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
+					      unsigned long cmd, void *__args)
+{
+	struct die_args *args = __args;
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct pt_regs *regs;
+	int idx;
+
+	if (!atomic_read(&active_events))
+		return NOTIFY_DONE;
+
+	switch (cmd) {
+	case DIE_NMI:
+		break;
+
+	default:
+		return NOTIFY_DONE;
+	}
+
+	regs = args->regs;
+
+	data.addr = 0;
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+	for (idx = 0; idx < MAX_HWEVENTS; idx++) {
+		struct perf_event *event = cpuc->events[idx];
+		struct hw_perf_event *hwc;
+		u64 val;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+		hwc = &event->hw;
+		val = sparc_perf_event_update(event, hwc, idx);
+		if (val & (1ULL << 31))
+			continue;
+
+		data.period = event->hw.last_period;
+		if (!sparc_perf_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, 1, &data, regs))
+			sparc_pmu_disable_event(hwc, idx);
+	}
+
+	return NOTIFY_STOP;
+}
+
+static __read_mostly struct notifier_block perf_event_nmi_notifier = {
+	.notifier_call		= perf_event_nmi_handler,
+};
+
+static bool __init supported_pmu(void)
+{
+	if (!strcmp(sparc_pmu_type, "ultra3i")) {
+		sparc_pmu = &ultra3i_pmu;
+		return true;
+	}
+	if (!strcmp(sparc_pmu_type, "niagara2")) {
+		sparc_pmu = &niagara2_pmu;
+		return true;
+	}
+	return false;
+}
+
+void __init init_hw_perf_events(void)
+{
+	pr_info("Performance events: ");
+
+	if (!supported_pmu()) {
+		pr_cont("No support for PMU type '%s'\n", sparc_pmu_type);
+		return;
+	}
+
+	pr_cont("Supported PMU type is '%s'\n", sparc_pmu_type);
+
+	/* All sparc64 PMUs currently have 2 events.  But this simple
+	 * driver only supports one active event at a time.
+	 */
+	perf_max_events = 1;
+
+	register_die_notifier(&perf_event_nmi_notifier);
+}
diff --git a/arch/sparc/kernel/prom_32.c b/arch/sparc/kernel/prom_32.c
index fe43e80..0a37e8c 100644
--- a/arch/sparc/kernel/prom_32.c
+++ b/arch/sparc/kernel/prom_32.c
@@ -24,6 +24,8 @@
 
 #include <asm/prom.h>
 #include <asm/oplib.h>
+#include <asm/leon.h>
+#include <asm/leon_amba.h>
 
 #include "prom.h"
 
@@ -131,6 +133,35 @@ static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
 		regs->which_io, regs->phys_addr);
 }
 
+/* "name:vendor:device@irq,addrlo" */
+static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
+{
+	struct amba_prom_registers *regs; unsigned int *intr;
+	unsigned int *device, *vendor;
+	struct property *prop;
+
+	prop = of_find_property(dp, "reg", NULL);
+	if (!prop)
+		return;
+	regs = prop->value;
+	prop = of_find_property(dp, "interrupts", NULL);
+	if (!prop)
+		return;
+	intr = prop->value;
+	prop = of_find_property(dp, "vendor", NULL);
+	if (!prop)
+		return;
+	vendor = prop->value;
+	prop = of_find_property(dp, "device", NULL);
+	if (!prop)
+		return;
+	device = prop->value;
+
+	sprintf(tmp_buf, "%s:%d:%d@%x,%x",
+		dp->name, *vendor, *device,
+		*intr, regs->phys_addr);
+}
+
 static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
 {
 	struct device_node *parent = dp->parent;
@@ -143,6 +174,8 @@ static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
 			return sbus_path_component(dp, tmp_buf);
 		if (!strcmp(parent->type, "ebus"))
 			return ebus_path_component(dp, tmp_buf);
+		if (!strcmp(parent->type, "ambapp"))
+			return ambapp_path_component(dp, tmp_buf);
 
 		/* "isa" is handled with platform naming */
 	}
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 0fb5789..138910c 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -22,9 +22,12 @@
 #include <linux/of.h>
 #include <asm/prom.h>
 #include <asm/oplib.h>
+#include <asm/leon.h>
 
 #include "prom.h"
 
+void (*prom_build_more)(struct device_node *dp, struct device_node ***nextp);
+
 struct device_node *of_console_device;
 EXPORT_SYMBOL(of_console_device);
 
@@ -161,7 +164,7 @@ static struct property * __init build_one_prop(phandle node, char *prev,
 			name = prom_nextprop(node, prev, p->name);
 		}
 
-		if (strlen(name) == 0) {
+		if (!name || strlen(name) == 0) {
 			tmp = p;
 			return NULL;
 		}
@@ -242,7 +245,7 @@ static struct device_node * __init prom_create_node(phandle node,
 	return dp;
 }
 
-static char * __init build_full_name(struct device_node *dp)
+char * __init build_full_name(struct device_node *dp)
 {
 	int len, ourlen, plen;
 	char *n;
@@ -289,6 +292,9 @@ static struct device_node * __init prom_build_tree(struct device_node *parent,
 
 		dp->child = prom_build_tree(dp, prom_getchild(node), nextp);
 
+		if (prom_build_more)
+			prom_build_more(dp, nextp);
+
 		node = prom_getsibling(node);
 	}
 
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index 998cadb..9be2af5 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -235,6 +235,8 @@ void __init setup_arch(char **cmdline_p)
 		sparc_cpu_model = sun4e;
 	if (!strcmp(&cputypval,"sun4u"))
 		sparc_cpu_model = sun4u;
+	if (!strncmp(&cputypval, "leon" , 4))
+		sparc_cpu_model = sparc_leon;
 
 	printk("ARCH: ");
 	switch(sparc_cpu_model) {
@@ -256,6 +258,9 @@ void __init setup_arch(char **cmdline_p)
 	case sun4u:
 		printk("SUN4U\n");
 		break;
+	case sparc_leon:
+		printk("LEON\n");
+		break;
 	default:
 		printk("UNKNOWN!\n");
 		break;
@@ -263,8 +268,6 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
-#elif defined(CONFIG_PROM_CONSOLE)
-	conswitchp = &prom_con;
 #endif
 	boot_flags_init(*cmdline_p);
 
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index f2bcfd2..2118033 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -295,8 +295,6 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
-#elif defined(CONFIG_PROM_CONSOLE)
-	conswitchp = &prom_con;
 #endif
 
 	idprom_init();
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 3691907..ff68373 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1389,8 +1389,8 @@ void smp_send_stop(void)
  * RETURNS:
  * Pointer to the allocated area on success, NULL on failure.
  */
-static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size,
-					unsigned long align)
+static void * __init pcpu_alloc_bootmem(unsigned int cpu, size_t size,
+					size_t align)
 {
 	const unsigned long goal = __pa(MAX_DMA_ADDRESS);
 #ifdef CONFIG_NEED_MULTIPLE_NODES
@@ -1415,127 +1415,35 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size,
 #endif
 }
 
-static size_t pcpur_size __initdata;
-static void **pcpur_ptrs __initdata;
-
-static struct page * __init pcpur_get_page(unsigned int cpu, int pageno)
+static void __init pcpu_free_bootmem(void *ptr, size_t size)
 {
-	size_t off = (size_t)pageno << PAGE_SHIFT;
-
-	if (off >= pcpur_size)
-		return NULL;
-
-	return virt_to_page(pcpur_ptrs[cpu] + off);
+	free_bootmem(__pa(ptr), size);
 }
 
-#define PCPU_CHUNK_SIZE (4UL * 1024UL * 1024UL)
-
-static void __init pcpu_map_range(unsigned long start, unsigned long end,
-				  struct page *page)
+static int pcpu_cpu_distance(unsigned int from, unsigned int to)
 {
-	unsigned long pfn = page_to_pfn(page);
-	unsigned long pte_base;
-
-	BUG_ON((pfn<<PAGE_SHIFT)&(PCPU_CHUNK_SIZE - 1UL));
-
-	pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4U |
-		    _PAGE_CP_4U | _PAGE_CV_4U |
-		    _PAGE_P_4U | _PAGE_W_4U);
-	if (tlb_type == hypervisor)
-		pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
-			    _PAGE_CP_4V | _PAGE_CV_4V |
-			    _PAGE_P_4V | _PAGE_W_4V);
-
-	while (start < end) {
-		pgd_t *pgd = pgd_offset_k(start);
-		unsigned long this_end;
-		pud_t *pud;
-		pmd_t *pmd;
-		pte_t *pte;
-
-		pud = pud_offset(pgd, start);
-		if (pud_none(*pud)) {
-			pmd_t *new;
-
-			new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
-			pud_populate(&init_mm, pud, new);
-		}
-
-		pmd = pmd_offset(pud, start);
-		if (!pmd_present(*pmd)) {
-			pte_t *new;
-
-			new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
-			pmd_populate_kernel(&init_mm, pmd, new);
-		}
-
-		pte = pte_offset_kernel(pmd, start);
-		this_end = (start + PMD_SIZE) & PMD_MASK;
-		if (this_end > end)
-			this_end = end;
-
-		while (start < this_end) {
-			unsigned long paddr = pfn << PAGE_SHIFT;
-
-			pte_val(*pte) = (paddr | pte_base);
-
-			start += PAGE_SIZE;
-			pte++;
-			pfn++;
-		}
-	}
+	if (cpu_to_node(from) == cpu_to_node(to))
+		return LOCAL_DISTANCE;
+	else
+		return REMOTE_DISTANCE;
 }
 
 void __init setup_per_cpu_areas(void)
 {
-	size_t dyn_size, static_size = __per_cpu_end - __per_cpu_start;
-	static struct vm_struct vm;
-	unsigned long delta, cpu;
-	size_t pcpu_unit_size;
-	size_t ptrs_size;
-
-	pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
-			       PERCPU_DYNAMIC_RESERVE);
-	dyn_size = pcpur_size - static_size - PERCPU_MODULE_RESERVE;
-
+	unsigned long delta;
+	unsigned int cpu;
+	int rc;
 
-	ptrs_size = PFN_ALIGN(nr_cpu_ids * sizeof(pcpur_ptrs[0]));
-	pcpur_ptrs = alloc_bootmem(ptrs_size);
-
-	for_each_possible_cpu(cpu) {
-		pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PCPU_CHUNK_SIZE,
-						     PCPU_CHUNK_SIZE);
-
-		free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size),
-			     PCPU_CHUNK_SIZE - pcpur_size);
-
-		memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size);
-	}
-
-	/* allocate address and map */
-	vm.flags = VM_ALLOC;
-	vm.size = nr_cpu_ids * PCPU_CHUNK_SIZE;
-	vm_area_register_early(&vm, PCPU_CHUNK_SIZE);
-
-	for_each_possible_cpu(cpu) {
-		unsigned long start = (unsigned long) vm.addr;
-		unsigned long end;
-
-		start += cpu * PCPU_CHUNK_SIZE;
-		end = start + PCPU_CHUNK_SIZE;
-		pcpu_map_range(start, end, virt_to_page(pcpur_ptrs[cpu]));
-	}
-
-	pcpu_unit_size = pcpu_setup_first_chunk(pcpur_get_page, static_size,
-						PERCPU_MODULE_RESERVE, dyn_size,
-						PCPU_CHUNK_SIZE, vm.addr, NULL);
-
-	free_bootmem(__pa(pcpur_ptrs), ptrs_size);
+	rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
+				    PERCPU_DYNAMIC_RESERVE, 4 << 20,
+				    pcpu_cpu_distance, pcpu_alloc_bootmem,
+				    pcpu_free_bootmem);
+	if (rc)
+		panic("failed to initialize first chunk (%d)", rc);
 
 	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
-	for_each_possible_cpu(cpu) {
-		__per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size;
-	}
+	for_each_possible_cpu(cpu)
+		__per_cpu_offset(cpu) = delta + pcpu_unit_offsets[cpu];
 
 	/* Setup %g5 for the boot cpu.  */
 	__local_per_cpu_offset = __per_cpu_offset(smp_processor_id());
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S
index aed9486..e706113 100644
--- a/arch/sparc/kernel/sys32.S
+++ b/arch/sparc/kernel/sys32.S
@@ -121,7 +121,7 @@ SIGN2(sys32_syslog, sys_syslog, %o0, %o2)
 SIGN1(sys32_umask, sys_umask, %o0)
 SIGN3(sys32_tgkill, sys_tgkill, %o0, %o1, %o2)
 SIGN1(sys32_sendto, sys_sendto, %o0)
-SIGN1(sys32_recvfrom, sys_recvfrom, %o0)
+SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0)
 SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2)
 SIGN2(sys32_connect, sys_connect, %o0, %o2)
 SIGN2(sys32_bind, sys_bind, %o0, %o2)
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c
index d28f496..ca39c60 100644
--- a/arch/sparc/kernel/sysfs.c
+++ b/arch/sparc/kernel/sysfs.c
@@ -2,6 +2,7 @@
  *
  * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
  */
+#include <linux/sched.h>
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 6909016..0f1658d 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -82,5 +82,5 @@ sys_call_table:
 /*310*/	.long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
 /*315*/	.long sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/	.long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-/*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo
+/*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open
 
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 2ee7250..009825f 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -83,7 +83,7 @@ sys_call_table32:
 /*310*/	.word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate
 	.word compat_sys_timerfd_settime, compat_sys_timerfd_gettime, compat_sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
-	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo
+	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open
 
 #endif /* CONFIG_COMPAT */
 
@@ -158,4 +158,4 @@ sys_call_table:
 /*310*/	.word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
 	.word sys_timerfd_settime, sys_timerfd_gettime, sys_signalfd4, sys_eventfd2, sys_epoll_create1
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
-	.word sys_pwritev, sys_rt_tgsigqueueinfo
+	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index fcbbd00..4e59925 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -51,70 +51,27 @@ SECTIONS
 	_etext = .;
 
 	RO_DATA(PAGE_SIZE)
-	.data :	{
-		DATA_DATA
-		CONSTRUCTORS
-	}
 	.data1 : {
 		*(.data1)
 	}
-	. = ALIGN(SMP_CACHE_BYTES);
-	.data.cacheline_aligned : {
-		*(.data.cacheline_aligned)
-	}
-	. = ALIGN(SMP_CACHE_BYTES);
-	.data.read_mostly : {
-		*(.data.read_mostly)
-	}
+	RW_DATA_SECTION(SMP_CACHE_BYTES, 0, THREAD_SIZE)
+
 	/* End of data section */
 	_edata = .;
 
-	/* init_task */
-	. = ALIGN(THREAD_SIZE);
-	.data.init_task : {
-		*(.data.init_task)
-	}
 	.fixup : {
 		__start___fixup = .;
 		*(.fixup)
 		__stop___fixup = .;
 	}
-	. = ALIGN(16);
-	__ex_table : {
-		__start___ex_table = .;
-		*(__ex_table)
-		__stop___ex_table = .;
-	}
+	EXCEPTION_TABLE(16)
 	NOTES
 
 	. = ALIGN(PAGE_SIZE);
-	.init.text : {
-		__init_begin = .;
-		_sinittext = .;
-		INIT_TEXT
-		_einittext = .;
-	}
+	__init_begin = ALIGN(PAGE_SIZE);
+	INIT_TEXT_SECTION(PAGE_SIZE)
 	__init_text_end = .;
-	.init.data : {
-		INIT_DATA
-	}
-	. = ALIGN(16);
-	.init.setup : {
-		__setup_start = .;
-		*(.init.setup)
-		__setup_end = .;
-	}
-	.initcall.init : {
-		__initcall_start = .;
-		INITCALLS
-		__initcall_end = .;
-	}
-	.con_initcall.init : {
-		__con_initcall_start = .;
-		*(.con_initcall.init)
-		__con_initcall_end = .;
-	}
-	SECURITY_INIT
+	INIT_DATA_SECTION(16)
 
 	. = ALIGN(4);
 	.tsb_ldquad_phys_patch : {
@@ -146,37 +103,15 @@ SECTIONS
 		__sun4v_2insn_patch_end = .;
 	}
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	. = ALIGN(PAGE_SIZE);
-	.init.ramfs : {
-		__initramfs_start = .;
-		*(.init.ramfs)
-		__initramfs_end = .;
-	}
-#endif
-
 	PERCPU(PAGE_SIZE)
 
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
-	__bss_start = .;
-	.sbss : {
-		*(.sbss)
-		*(.scommon)
-	}
-	.bss : {
-		*(.dynbss)
-		*(.bss)
-		*(COMMON)
-	}
+	BSS_SECTION(0, 0, 0)
 	_end = . ;
 
-	/DISCARD/ : {
-		EXIT_TEXT
-		EXIT_DATA
-		*(.exitcall.exit)
-	}
-
 	STABS_DEBUG
 	DWARF_DEBUG
+
+	DISCARDS
 }
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 681abe0..79836a7 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SPARC32)   += loadmmu.o
 obj-y                   += generic_$(BITS).o
 obj-$(CONFIG_SPARC32)   += extable.o btfixup.o srmmu.o iommu.o io-unit.o
 obj-$(CONFIG_SPARC32)   += hypersparc.o viking.o tsunami.o swift.o
+obj-$(CONFIG_SPARC_LEON)+= leon_mm.o
 
 # Only used by sparc64
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index 26bb391..54114ad 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -34,6 +34,7 @@
 #include <asm/pgalloc.h>	/* bug in asm-generic/tlb.h: check_pgt_cache */
 #include <asm/tlb.h>
 #include <asm/prom.h>
+#include <asm/leon.h>
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
@@ -326,6 +327,9 @@ void __init paging_init(void)
 		sparc_unmapped_base = 0xe0000000;
 		BTFIXUPSET_SETHI(sparc_unmapped_base, 0xe0000000);
 		break;
+	case sparc_leon:
+		leon_init();
+		/* fall through */
 	case sun4m:
 	case sun4d:
 		srmmu_paging_init();
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c
new file mode 100644
index 0000000..c0e0129
--- /dev/null
+++ b/arch/sparc/mm/leon_mm.c
@@ -0,0 +1,260 @@
+/*
+ *  linux/arch/sparc/mm/leon_m.c
+ *
+ * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de, konrad@gaisler.com) Gaisler Research
+ * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
+ * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
+ *
+ * do srmmu probe in software
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/asi.h>
+#include <asm/leon.h>
+#include <asm/tlbflush.h>
+
+int leon_flush_during_switch = 1;
+int srmmu_swprobe_trace;
+
+unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr)
+{
+
+	unsigned int ctxtbl;
+	unsigned int pgd, pmd, ped;
+	unsigned int ptr;
+	unsigned int lvl, pte, paddrbase;
+	unsigned int ctx;
+	unsigned int paddr_calc;
+
+	paddrbase = 0;
+
+	if (srmmu_swprobe_trace)
+		printk(KERN_INFO "swprobe: trace on\n");
+
+	ctxtbl = srmmu_get_ctable_ptr();
+	if (!(ctxtbl)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: srmmu_get_ctable_ptr returned 0=>0\n");
+		return 0;
+	}
+	if (!_pfn_valid(PFN(ctxtbl))) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO
+			       "swprobe: !_pfn_valid(%x)=>0\n",
+			       PFN(ctxtbl));
+		return 0;
+	}
+
+	ctx = srmmu_get_context();
+	if (srmmu_swprobe_trace)
+		printk(KERN_INFO "swprobe:  --- ctx (%x) ---\n", ctx);
+
+	pgd = LEON_BYPASS_LOAD_PA(ctxtbl + (ctx * 4));
+
+	if (((pgd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: pgd is entry level 3\n");
+		lvl = 3;
+		pte = pgd;
+		paddrbase = pgd & _SRMMU_PTE_PMASK_LEON;
+		goto ready;
+	}
+	if (((pgd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: pgd is invalid => 0\n");
+		return 0;
+	}
+
+	if (srmmu_swprobe_trace)
+		printk(KERN_INFO "swprobe:  --- pgd (%x) ---\n", pgd);
+
+	ptr = (pgd & SRMMU_PTD_PMASK) << 4;
+	ptr += ((((vaddr) >> LEON_PGD_SH) & LEON_PGD_M) * 4);
+	if (!_pfn_valid(PFN(ptr)))
+		return 0;
+
+	pmd = LEON_BYPASS_LOAD_PA(ptr);
+	if (((pmd & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: pmd is entry level 2\n");
+		lvl = 2;
+		pte = pmd;
+		paddrbase = pmd & _SRMMU_PTE_PMASK_LEON;
+		goto ready;
+	}
+	if (((pmd & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: pmd is invalid => 0\n");
+		return 0;
+	}
+
+	if (srmmu_swprobe_trace)
+		printk(KERN_INFO "swprobe:  --- pmd (%x) ---\n", pmd);
+
+	ptr = (pmd & SRMMU_PTD_PMASK) << 4;
+	ptr += (((vaddr >> LEON_PMD_SH) & LEON_PMD_M) * 4);
+	if (!_pfn_valid(PFN(ptr))) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: !_pfn_valid(%x)=>0\n",
+			       PFN(ptr));
+		return 0;
+	}
+
+	ped = LEON_BYPASS_LOAD_PA(ptr);
+
+	if (((ped & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: ped is entry level 1\n");
+		lvl = 1;
+		pte = ped;
+		paddrbase = ped & _SRMMU_PTE_PMASK_LEON;
+		goto ready;
+	}
+	if (((ped & SRMMU_ET_MASK) != SRMMU_ET_PTD)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: ped is invalid => 0\n");
+		return 0;
+	}
+
+	if (srmmu_swprobe_trace)
+		printk(KERN_INFO "swprobe:  --- ped (%x) ---\n", ped);
+
+	ptr = (ped & SRMMU_PTD_PMASK) << 4;
+	ptr += (((vaddr >> LEON_PTE_SH) & LEON_PTE_M) * 4);
+	if (!_pfn_valid(PFN(ptr)))
+		return 0;
+
+	ptr = LEON_BYPASS_LOAD_PA(ptr);
+	if (((ptr & SRMMU_ET_MASK) == SRMMU_ET_PTE)) {
+		if (srmmu_swprobe_trace)
+			printk(KERN_INFO "swprobe: ptr is entry level 0\n");
+		lvl = 0;
+		pte = ptr;
+		paddrbase = ptr & _SRMMU_PTE_PMASK_LEON;
+		goto ready;
+	}
+	if (srmmu_swprobe_trace)
+		printk(KERN_INFO "swprobe: ptr is invalid => 0\n");
+	return 0;
+
+ready:
+	switch (lvl) {
+	case 0:
+		paddr_calc =
+		    (vaddr & ~(-1 << LEON_PTE_SH)) | ((pte & ~0xff) << 4);
+		break;
+	case 1:
+		paddr_calc =
+		    (vaddr & ~(-1 << LEON_PMD_SH)) | ((pte & ~0xff) << 4);
+		break;
+	case 2:
+		paddr_calc =
+		    (vaddr & ~(-1 << LEON_PGD_SH)) | ((pte & ~0xff) << 4);
+		break;
+	default:
+	case 3:
+		paddr_calc = vaddr;
+		break;
+	}
+	if (srmmu_swprobe_trace)
+		printk(KERN_INFO "swprobe: padde %x\n", paddr_calc);
+	if (paddr)
+		*paddr = paddr_calc;
+	return paddrbase;
+}
+
+void leon_flush_icache_all(void)
+{
+	__asm__ __volatile__(" flush ");	/*iflush*/
+}
+
+void leon_flush_dcache_all(void)
+{
+	__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+			     "i"(ASI_LEON_DFLUSH) : "memory");
+}
+
+void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page)
+{
+	if (vma->vm_flags & VM_EXEC)
+		leon_flush_icache_all();
+	leon_flush_dcache_all();
+}
+
+void leon_flush_cache_all(void)
+{
+	__asm__ __volatile__(" flush ");	/*iflush*/
+	__asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
+			     "i"(ASI_LEON_DFLUSH) : "memory");
+}
+
+void leon_flush_tlb_all(void)
+{
+	leon_flush_cache_all();
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : "r"(0x400),
+			     "i"(ASI_LEON_MMUFLUSH) : "memory");
+}
+
+/* get all cache regs */
+void leon3_getCacheRegs(struct leon3_cacheregs *regs)
+{
+	unsigned long ccr, iccr, dccr;
+
+	if (!regs)
+		return;
+	/* Get Cache regs from "Cache ASI" address 0x0, 0x8 and 0xC */
+	__asm__ __volatile__("lda [%%g0] %3, %0\n\t"
+			     "mov 0x08, %%g1\n\t"
+			     "lda [%%g1] %3, %1\n\t"
+			     "mov 0x0c, %%g1\n\t"
+			     "lda [%%g1] %3, %2\n\t"
+			     : "=r"(ccr), "=r"(iccr), "=r"(dccr)
+			       /* output */
+			     : "i"(ASI_LEON_CACHEREGS)	/* input */
+			     : "g1"	/* clobber list */
+	    );
+	regs->ccr = ccr;
+	regs->iccr = iccr;
+	regs->dccr = dccr;
+}
+
+/* Due to virtual cache we need to check cache configuration if
+ * it is possible to skip flushing in some cases.
+ *
+ * Leon2 and Leon3 differ in their way of telling cache information
+ *
+ */
+int leon_flush_needed(void)
+{
+	int flush_needed = -1;
+	unsigned int ssize, sets;
+	char *setStr[4] =
+	    { "direct mapped", "2-way associative", "3-way associative",
+		"4-way associative"
+	};
+	/* leon 3 */
+	struct leon3_cacheregs cregs;
+	leon3_getCacheRegs(&cregs);
+	sets = (cregs.dccr & LEON3_XCCR_SETS_MASK) >> 24;
+	/* (ssize=>realsize) 0=>1k, 1=>2k, 2=>4k, 3=>8k ... */
+	ssize = 1 << ((cregs.dccr & LEON3_XCCR_SSIZE_MASK) >> 20);
+
+	printk(KERN_INFO "CACHE: %s cache, set size %dk\n",
+	       sets > 3 ? "unknown" : setStr[sets], ssize);
+	if ((ssize <= (PAGE_SIZE / 1024)) && (sets == 0)) {
+		/* Set Size <= Page size  ==>
+		   flush on every context switch not needed. */
+		flush_needed = 0;
+		printk(KERN_INFO "CACHE: not flushing on every context switch\n");
+	}
+	return flush_needed;
+}
+
+void leon_switch_mm(void)
+{
+	flush_tlb_mm((void *)0);
+	if (leon_flush_during_switch)
+		leon_flush_cache_all();
+}
diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c
index 652be05..82ec8f6 100644
--- a/arch/sparc/mm/loadmmu.c
+++ b/arch/sparc/mm/loadmmu.c
@@ -33,6 +33,7 @@ void __init load_mmu(void)
 		break;
 	case sun4m:
 	case sun4d:
+	case sparc_leon:
 		ld_mmu_srmmu();
 		break;
 	default:
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index ade4eb3..509b1ff 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -46,6 +46,7 @@
 #include <asm/tsunami.h>
 #include <asm/swift.h>
 #include <asm/turbosparc.h>
+#include <asm/leon.h>
 
 #include <asm/btfixup.h>
 
@@ -569,6 +570,9 @@ static void srmmu_switch_mm(struct mm_struct *old_mm, struct mm_struct *mm,
 		srmmu_ctxd_set(&srmmu_context_table[mm->context], mm->pgd);
 	}
 
+	if (sparc_cpu_model == sparc_leon)
+		leon_switch_mm();
+
 	if (is_hypersparc)
 		hyper_flush_whole_icache();
 
@@ -1977,6 +1981,45 @@ static void __init init_viking(void)
 	poke_srmmu = poke_viking;
 }
 
+#ifdef CONFIG_SPARC_LEON
+
+void __init poke_leonsparc(void)
+{
+}
+
+void __init init_leon(void)
+{
+
+	srmmu_name = "Leon";
+
+	BTFIXUPSET_CALL(flush_cache_all, leon_flush_cache_all,
+			BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(flush_cache_mm, leon_flush_cache_all,
+			BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(flush_cache_page, leon_flush_pcache_all,
+			BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(flush_cache_range, leon_flush_cache_all,
+			BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(flush_page_for_dma, leon_flush_dcache_all,
+			BTFIXUPCALL_NORM);
+
+	BTFIXUPSET_CALL(flush_tlb_all, leon_flush_tlb_all, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(flush_tlb_mm, leon_flush_tlb_all, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(flush_tlb_page, leon_flush_tlb_all, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(flush_tlb_range, leon_flush_tlb_all, BTFIXUPCALL_NORM);
+
+	BTFIXUPSET_CALL(__flush_page_to_ram, leon_flush_cache_all,
+			BTFIXUPCALL_NOP);
+	BTFIXUPSET_CALL(flush_sig_insns, leon_flush_cache_all, BTFIXUPCALL_NOP);
+
+	poke_srmmu = poke_leonsparc;
+
+	srmmu_cache_pagetables = 0;
+
+	leon_flush_during_switch = leon_flush_needed();
+}
+#endif
+
 /* Probe for the srmmu chip version. */
 static void __init get_srmmu_type(void)
 {
@@ -1992,7 +2035,15 @@ static void __init get_srmmu_type(void)
 	psr_typ = (psr >> 28) & 0xf;
 	psr_vers = (psr >> 24) & 0xf;
 
-	/* First, check for HyperSparc or Cypress. */
+	/* First, check for sparc-leon. */
+	if (sparc_cpu_model == sparc_leon) {
+		psr_typ = 0xf;	/* hardcoded ids for older models/simulators */
+		psr_vers = 2;
+		init_leon();
+		return;
+	}
+
+	/* Second, check for HyperSparc or Cypress. */
 	if(mod_typ == 1) {
 		switch(mod_rev) {
 		case 7:
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c
index d172f86..f97cb8b 100644
--- a/arch/sparc/oprofile/init.c
+++ b/arch/sparc/oprofile/init.c
@@ -21,7 +21,7 @@
 static int profile_timer_exceptions_notify(struct notifier_block *self,
 					   unsigned long val, void *data)
 {
-	struct die_args *args = (struct die_args *)data;
+	struct die_args *args = data;
 	int ret = NOTIFY_DONE;
 
 	switch (val) {
@@ -57,7 +57,7 @@ static void timer_stop(void)
 
 static int op_nmi_timer_init(struct oprofile_operations *ops)
 {
-	if (!nmi_usable)
+	if (atomic_read(&nmi_active) <= 0)
 		return -ENODEV;
 
 	ops->start = timer_start;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 3b44b47..f114813 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -245,7 +245,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void uml_net_set_multicast_list(struct net_device *dev)
@@ -285,7 +285,7 @@ static void uml_net_get_drvinfo(struct net_device *dev,
 	strcpy(info->version, "42");
 }
 
-static struct ethtool_ops uml_net_ethtool_ops = {
+static const struct ethtool_ops uml_net_ethtool_ops = {
 	.get_drvinfo	= uml_net_get_drvinfo,
 	.get_link	= ethtool_op_get_link,
 };
diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S
index cb02486..37ecc55 100644
--- a/arch/um/include/asm/common.lds.S
+++ b/arch/um/include/asm/common.lds.S
@@ -123,8 +123,3 @@
 	__initramfs_end = .;
   }
 
-  /* Sections to be discarded */
-  /DISCARD/ : {
- 	*(.exitcall.exit)
-  }
-
diff --git a/arch/um/include/asm/pci.h b/arch/um/include/asm/pci.h
index 5992319..b44cf59 100644
--- a/arch/um/include/asm/pci.h
+++ b/arch/um/include/asm/pci.h
@@ -2,6 +2,5 @@
 #define __UM_PCI_H
 
 #define PCI_DMA_BUS_IS_PHYS     (1)
-#define pcibios_scan_all_fns(a, b)	0
 
 #endif
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 9975e1a..715a188 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -156,4 +156,6 @@ SECTIONS
   STABS_DEBUG
 
   DWARF_DEBUG
+
+  DISCARDS
 }
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 11b8352..2ebd397 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -100,4 +100,6 @@ SECTIONS
   STABS_DEBUG
 
   DWARF_DEBUG
+
+  DISCARDS
 }
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index 30860b8..b6b1096 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -15,7 +15,6 @@
 #include "os.h"
 #include "um_malloc.h"
 #include "user.h"
-#include <linux/limits.h>
 
 struct helper_data {
 	void (*pre_exec)(void*);
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index fc20fdc..e4ff5d1 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -24,7 +24,7 @@ config X86
 	select HAVE_UNSTABLE_SCHED_CLOCK
 	select HAVE_IDE
 	select HAVE_OPROFILE
-	select HAVE_PERF_COUNTERS if (!M386 && !M486)
+	select HAVE_PERF_EVENTS if (!M386 && !M486)
 	select HAVE_IOREMAP_PROT
 	select HAVE_KPROBES
 	select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -150,7 +150,10 @@ config ARCH_HAS_CACHE_LINE_SIZE
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
-config HAVE_DYNAMIC_PER_CPU_AREA
+config NEED_PER_CPU_EMBED_FIRST_CHUNK
+	def_bool y
+
+config NEED_PER_CPU_PAGE_FIRST_CHUNK
 	def_bool y
 
 config HAVE_CPUMASK_OF_CPU_MAP
@@ -179,6 +182,10 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
 	def_bool y
 
+config HAVE_INTEL_TXT
+	def_bool y
+	depends on EXPERIMENTAL && DMAR && ACPI
+
 # Use the generic interrupt handling code in kernel/irq/:
 config GENERIC_HARDIRQS
 	bool
@@ -318,6 +325,7 @@ config X86_EXTENDED_PLATFORM
 		SGI 320/540 (Visual Workstation)
 		Summit/EXA (IBM x440)
 		Unisys ES7000 IA32 series
+		Moorestown MID devices
 
 	  If you have one of these systems, or if you want to build a
 	  generic distribution kernel, say Y here - otherwise say N.
@@ -377,6 +385,18 @@ config X86_ELAN
 
 	  If unsure, choose "PC-compatible" instead.
 
+config X86_MRST
+       bool "Moorestown MID platform"
+	depends on X86_32
+	depends on X86_EXTENDED_PLATFORM
+	---help---
+	  Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
+	  Internet Device(MID) platform. Moorestown consists of two chips:
+	  Lincroft (CPU core, graphics, and memory controller) and Langwell IOH.
+	  Unlike standard x86 PCs, Moorestown does not have many legacy devices
+	  nor standard legacy replacement devices/features. e.g. Moorestown does
+	  not contain i8259, i8254, HPET, legacy BIOS, most of the io ports.
+
 config X86_RDC321X
 	bool "RDC R-321x SoC"
 	depends on X86_32
@@ -776,41 +796,17 @@ config X86_REROUTE_FOR_BROKEN_BOOT_IRQS
 	  increased on these systems.
 
 config X86_MCE
-	bool "Machine Check Exception"
+	bool "Machine Check / overheating reporting"
 	---help---
-	  Machine Check Exception support allows the processor to notify the
-	  kernel if it detects a problem (e.g. overheating, component failure).
+	  Machine Check support allows the processor to notify the
+	  kernel if it detects a problem (e.g. overheating, data corruption).
 	  The action the kernel takes depends on the severity of the problem,
-	  ranging from a warning message on the console, to halting the machine.
-	  Your processor must be a Pentium or newer to support this - check the
-	  flags in /proc/cpuinfo for mce.  Note that some older Pentium systems
-	  have a design flaw which leads to false MCE events - hence MCE is
-	  disabled on all P5 processors, unless explicitly enabled with "mce"
-	  as a boot argument.  Similarly, if MCE is built in and creates a
-	  problem on some new non-standard machine, you can boot with "nomce"
-	  to disable it.  MCE support simply ignores non-MCE processors like
-	  the 386 and 486, so nearly everyone can say Y here.
-
-config X86_OLD_MCE
-	depends on X86_32 && X86_MCE
-	bool "Use legacy machine check code (will go away)"
-	default n
-	select X86_ANCIENT_MCE
-	---help---
-	  Use the old i386 machine check code. This is merely intended for
-	  testing in a transition period. Try this if you run into any machine
-	  check related software problems, but report the problem to
-	  linux-kernel.  When in doubt say no.
-
-config X86_NEW_MCE
-	depends on X86_MCE
-	bool
-	default y if (!X86_OLD_MCE && X86_32) || X86_64
+	  ranging from warning messages to halting the machine.
 
 config X86_MCE_INTEL
 	def_bool y
 	prompt "Intel MCE features"
-	depends on X86_NEW_MCE && X86_LOCAL_APIC
+	depends on X86_MCE && X86_LOCAL_APIC
 	---help---
 	   Additional support for intel specific MCE features such as
 	   the thermal monitor.
@@ -818,14 +814,14 @@ config X86_MCE_INTEL
 config X86_MCE_AMD
 	def_bool y
 	prompt "AMD MCE features"
-	depends on X86_NEW_MCE && X86_LOCAL_APIC
+	depends on X86_MCE && X86_LOCAL_APIC
 	---help---
 	   Additional support for AMD specific MCE features such as
 	   the DRAM Error Threshold.
 
 config X86_ANCIENT_MCE
 	def_bool n
-	depends on X86_32
+	depends on X86_32 && X86_MCE
 	prompt "Support for old Pentium 5 / WinChip machine checks"
 	---help---
 	  Include support for machine check handling on old Pentium 5 or WinChip
@@ -838,36 +834,16 @@ config X86_MCE_THRESHOLD
 	default y
 
 config X86_MCE_INJECT
-	depends on X86_NEW_MCE
+	depends on X86_MCE
 	tristate "Machine check injector support"
 	---help---
 	  Provide support for injecting machine checks for testing purposes.
 	  If you don't know what a machine check is and you don't do kernel
 	  QA it is safe to say n.
 
-config X86_MCE_NONFATAL
-	tristate "Check for non-fatal errors on AMD Athlon/Duron / Intel Pentium 4"
-	depends on X86_OLD_MCE
-	---help---
-	  Enabling this feature starts a timer that triggers every 5 seconds which
-	  will look at the machine check registers to see if anything happened.
-	  Non-fatal problems automatically get corrected (but still logged).
-	  Disable this if you don't want to see these messages.
-	  Seeing the messages this option prints out may be indicative of dying
-	  or out-of-spec (ie, overclocked) hardware.
-	  This option only does something on certain CPUs.
-	  (AMD Athlon/Duron and Intel Pentium 4)
-
-config X86_MCE_P4THERMAL
-	bool "check for P4 thermal throttling interrupt."
-	depends on X86_OLD_MCE && X86_MCE && (X86_UP_APIC || SMP)
-	---help---
-	  Enabling this feature will cause a message to be printed when the P4
-	  enters thermal throttling.
-
 config X86_THERMAL_VECTOR
 	def_bool y
-	depends on X86_MCE_P4THERMAL || X86_MCE_INTEL
+	depends on X86_MCE_INTEL
 
 config VM86
 	bool "Enable VM86 support" if EMBEDDED
@@ -1413,6 +1389,10 @@ config X86_PAT
 
 	  If unsure, say Y.
 
+config ARCH_USES_PG_UNCACHED
+	def_bool y
+	depends on X86_PAT
+
 config EFI
 	bool "EFI runtime service support"
 	depends on ACPI
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 8130334..527519b 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -262,6 +262,15 @@ config MCORE2
 	  family in /proc/cpuinfo. Newer ones have 6 and older ones 15
 	  (not a typo)
 
+config MATOM
+	bool "Intel Atom"
+	---help---
+
+	  Select this for the Intel Atom platform. Intel Atom CPUs have an
+	  in-order pipelining architecture and thus can benefit from
+	  accordingly optimized code. Use a recent GCC with specific Atom
+	  support in order to fully benefit from selecting this option.
+
 config GENERIC_CPU
 	bool "Generic-x86-64"
 	depends on X86_64
@@ -295,7 +304,7 @@ config X86_CPU
 config X86_L1_CACHE_BYTES
 	int
 	default "128" if MPSC
-	default "64" if GENERIC_CPU || MK8 || MCORE2 || X86_32
+	default "64" if GENERIC_CPU || MK8 || MCORE2 || MATOM || X86_32
 
 config X86_INTERNODE_CACHE_BYTES
 	int
@@ -310,7 +319,7 @@ config X86_L1_CACHE_SHIFT
 	default "7" if MPENTIUM4 || MPSC
 	default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
-	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 || X86_GENERIC || GENERIC_CPU
+	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
 
 config X86_XADD
 	def_bool y
@@ -359,7 +368,7 @@ config X86_INTEL_USERCOPY
 
 config X86_USE_PPRO_CHECKSUM
 	def_bool y
-	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2
+	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
 
 config X86_USE_3DNOW
 	def_bool y
@@ -387,7 +396,7 @@ config X86_P6_NOP
 
 config X86_TSC
 	def_bool y
-	depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ) || X86_64
+	depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ) || X86_64
 
 config X86_CMPXCHG64
 	def_bool y
@@ -397,7 +406,7 @@ config X86_CMPXCHG64
 # generates cmov.
 config X86_CMOV
 	def_bool y
-	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64)
+	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM)
 
 config X86_MINIMUM_CPU_FAMILY
 	int
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 1b68659..7983c42 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -32,8 +32,8 @@ ifeq ($(CONFIG_X86_32),y)
 
         # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
         # a lot more stack due to the lack of sharing of stacklots:
-        KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
-                echo $(call cc-option,-fno-unit-at-a-time); fi ;)
+        KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0400, \
+				$(call cc-option,-fno-unit-at-a-time))
 
         # CPU-specific tuning. Anything which can be shared with UML should go here.
         include $(srctree)/arch/x86/Makefile_32.cpu
@@ -55,6 +55,8 @@ else
 
         cflags-$(CONFIG_MCORE2) += \
                 $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
+	cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \
+		$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
         cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
         KBUILD_CFLAGS += $(cflags-y)
 
@@ -72,7 +74,7 @@ endif
 
 ifdef CONFIG_CC_STACKPROTECTOR
 	cc_has_sp := $(srctree)/scripts/gcc-x86_$(BITS)-has-stack-protector.sh
-        ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC)),y)
+        ifeq ($(shell $(CONFIG_SHELL) $(cc_has_sp) $(CC) $(biarch)),y)
                 stackp-y := -fstack-protector
                 stackp-$(CONFIG_CC_STACKPROTECTOR_ALL) += -fstack-protector-all
                 KBUILD_CFLAGS += $(stackp-y)
diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
index 80177ec..30e9a26 100644
--- a/arch/x86/Makefile_32.cpu
+++ b/arch/x86/Makefile_32.cpu
@@ -33,6 +33,8 @@ cflags-$(CONFIG_MCYRIXIII)	+= $(call cc-option,-march=c3,-march=i486) $(align)-f
 cflags-$(CONFIG_MVIAC3_2)	+= $(call cc-option,-march=c3-2,-march=i686)
 cflags-$(CONFIG_MVIAC7)		+= -march=i686
 cflags-$(CONFIG_MCORE2)		+= -march=i686 $(call tune,core2)
+cflags-$(CONFIG_MATOM)		+= $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \
+	$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
 
 # AMD Elan support
 cflags-$(CONFIG_X86_ELAN)	+= -march=i486
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 275dd17..11e8c6e 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -31,7 +31,6 @@ static inline void vesa_store_mode_params_graphics(void) {}
 
 static int vesa_probe(void)
 {
-#if defined(CONFIG_VIDEO_VESA) || defined(CONFIG_FIRMWARE_EDID)
 	struct biosregs ireg, oreg;
 	u16 mode;
 	addr_t mode_ptr;
@@ -49,8 +48,7 @@ static int vesa_probe(void)
 	    vginfo.signature != VESA_MAGIC ||
 	    vginfo.version < 0x0102)
 		return 0;	/* Not present */
-#endif /* CONFIG_VIDEO_VESA || CONFIG_FIRMWARE_EDID */
-#ifdef CONFIG_VIDEO_VESA
+
 	set_fs(vginfo.video_mode_ptr.seg);
 	mode_ptr = vginfo.video_mode_ptr.off;
 
@@ -102,9 +100,6 @@ static int vesa_probe(void)
 	}
 
 	return nmodes;
-#else
-	return 0;
-#endif /* CONFIG_VIDEO_VESA */
 }
 
 static int vesa_set_mode(struct mode_info *mode)
diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
index 8f8d827..819caa1 100644
--- a/arch/x86/boot/video-vga.c
+++ b/arch/x86/boot/video-vga.c
@@ -47,14 +47,6 @@ static u8 vga_set_basic_mode(void)
 
 	initregs(&ireg);
 
-#ifdef CONFIG_VIDEO_400_HACK
-	if (adapter >= ADAPTER_VGA) {
-		ireg.ax = 0x1202;
-		ireg.bx = 0x0030;
-		intcall(0x10, &ireg, NULL);
-	}
-#endif
-
 	ax = 0x0f00;
 	intcall(0x10, &ireg, &oreg);
 	mode = oreg.al;
@@ -62,11 +54,9 @@ static u8 vga_set_basic_mode(void)
 	set_fs(0);
 	rows = rdfs8(0x484);	/* rows minus one */
 
-#ifndef CONFIG_VIDEO_400_HACK
 	if ((oreg.ax == 0x5003 || oreg.ax == 0x5007) &&
 	    (rows == 0 || rows == 24))
 		return mode;
-#endif
 
 	if (mode != 3 && mode != 7)
 		mode = 3;
diff --git a/arch/x86/boot/video.c b/arch/x86/boot/video.c
index bad728b..d42da38 100644
--- a/arch/x86/boot/video.c
+++ b/arch/x86/boot/video.c
@@ -221,7 +221,6 @@ static unsigned int mode_menu(void)
 	}
 }
 
-#ifdef CONFIG_VIDEO_RETAIN
 /* Save screen content to the heap */
 static struct saved_screen {
 	int x, y;
@@ -299,10 +298,6 @@ static void restore_screen(void)
 	ireg.dl = saved.curx;
 	intcall(0x10, &ireg, NULL);
 }
-#else
-#define save_screen()		((void)0)
-#define restore_screen()	((void)0)
-#endif
 
 void set_video(void)
 {
diff --git a/arch/x86/boot/video.h b/arch/x86/boot/video.h
index 5bb174a..ff339c5 100644
--- a/arch/x86/boot/video.h
+++ b/arch/x86/boot/video.h
@@ -17,19 +17,8 @@
 
 #include <linux/types.h>
 
-/* Enable autodetection of SVGA adapters and modes. */
-#undef CONFIG_VIDEO_SVGA
-
-/* Enable autodetection of VESA modes */
-#define CONFIG_VIDEO_VESA
-
-/* Retain screen contents when switching modes */
-#define CONFIG_VIDEO_RETAIN
-
-/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
-#undef CONFIG_VIDEO_400_HACK
-
-/* This code uses an extended set of video mode numbers. These include:
+/*
+ * This code uses an extended set of video mode numbers. These include:
  * Aliases for standard modes
  *      NORMAL_VGA (-1)
  *      EXTENDED_VGA (-2)
@@ -67,13 +56,8 @@
 /* The "recalculate timings" flag */
 #define VIDEO_RECALC 0x8000
 
-/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
-#ifdef CONFIG_VIDEO_RETAIN
 void store_screen(void);
 #define DO_STORE() store_screen()
-#else
-#define DO_STORE() ((void)0)
-#endif /* CONFIG_VIDEO_RETAIN */
 
 /*
  * Mode table structures
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index d3ec8d5..585edeb 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -59,13 +59,6 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out,
 asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
 			      const u8 *in, unsigned int len, u8 *iv);
 
-static inline int kernel_fpu_using(void)
-{
-	if (in_interrupt() && !(read_cr0() & X86_CR0_TS))
-		return 1;
-	return 0;
-}
-
 static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx)
 {
 	unsigned long addr = (unsigned long)raw_ctx;
@@ -89,7 +82,7 @@ static int aes_set_key_common(struct crypto_tfm *tfm, void *raw_ctx,
 		return -EINVAL;
 	}
 
-	if (kernel_fpu_using())
+	if (irq_fpu_usable())
 		err = crypto_aes_expand_key(ctx, in_key, key_len);
 	else {
 		kernel_fpu_begin();
@@ -110,7 +103,7 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
 	struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
 
-	if (kernel_fpu_using())
+	if (irq_fpu_usable())
 		crypto_aes_encrypt_x86(ctx, dst, src);
 	else {
 		kernel_fpu_begin();
@@ -123,7 +116,7 @@ static void aes_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
 	struct crypto_aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(tfm));
 
-	if (kernel_fpu_using())
+	if (irq_fpu_usable())
 		crypto_aes_decrypt_x86(ctx, dst, src);
 	else {
 		kernel_fpu_begin();
@@ -349,7 +342,7 @@ static int ablk_encrypt(struct ablkcipher_request *req)
 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
 	struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 
-	if (kernel_fpu_using()) {
+	if (irq_fpu_usable()) {
 		struct ablkcipher_request *cryptd_req =
 			ablkcipher_request_ctx(req);
 		memcpy(cryptd_req, req, sizeof(*req));
@@ -370,7 +363,7 @@ static int ablk_decrypt(struct ablkcipher_request *req)
 	struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
 	struct async_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
 
-	if (kernel_fpu_using()) {
+	if (irq_fpu_usable()) {
 		struct ablkcipher_request *cryptd_req =
 			ablkcipher_request_ctx(req);
 		memcpy(cryptd_req, req, sizeof(*req));
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index e590261..74619c4 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -537,7 +537,7 @@ ia32_sys_call_table:
 	.quad sys_mkdir
 	.quad sys_rmdir		/* 40 */
 	.quad sys_dup
-	.quad sys32_pipe
+	.quad sys_pipe
 	.quad compat_sys_times
 	.quad quiet_ni_syscall			/* old prof syscall holder */
 	.quad sys_brk		/* 45 */
@@ -831,5 +831,5 @@ ia32_sys_call_table:
 	.quad compat_sys_preadv
 	.quad compat_sys_pwritev
 	.quad compat_sys_rt_tgsigqueueinfo	/* 335 */
-	.quad sys_perf_counter_open
+	.quad sys_perf_event_open
 ia32_syscall_end:
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index 085a8c3..9f55271 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -189,20 +189,6 @@ asmlinkage long sys32_mprotect(unsigned long start, size_t len,
 	return sys_mprotect(start, len, prot);
 }
 
-asmlinkage long sys32_pipe(int __user *fd)
-{
-	int retval;
-	int fds[2];
-
-	retval = do_pipe_flags(fds, 0);
-	if (retval)
-		goto out;
-	if (copy_to_user(fd, fds, sizeof(fds)))
-		retval = -EFAULT;
-out:
-	return retval;
-}
-
 asmlinkage long sys32_rt_sigaction(int sig, struct sigaction32 __user *act,
 				   struct sigaction32 __user *oact,
 				   unsigned int sigsetsize)
diff --git a/arch/x86/include/asm/agp.h b/arch/x86/include/asm/agp.h
index 9825cd6..eec2a70 100644
--- a/arch/x86/include/asm/agp.h
+++ b/arch/x86/include/asm/agp.h
@@ -22,10 +22,6 @@
  */
 #define flush_agp_cache() wbinvd()
 
-/* Convert a physical address to an address suitable for the GART. */
-#define phys_to_gart(x) (x)
-#define gart_to_phys(x) (x)
-
 /* GATT allocation. Returns/accepts GATT kernel virtual address. */
 #define alloc_gatt_pages(order)		\
 	((char *)__get_free_pages(GFP_KERNEL, (order)))
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 1a37bcd..c240efc 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -73,8 +73,6 @@ static inline void alternatives_smp_module_del(struct module *mod) {}
 static inline void alternatives_smp_switch(int smp) {}
 #endif	/* CONFIG_SMP */
 
-const unsigned char *const *find_nop_table(void);
-
 /* alternative assembly primitive: */
 #define ALTERNATIVE(oldinstr, newinstr, feature)			\
 									\
@@ -144,8 +142,6 @@ static inline void apply_paravirt(struct paravirt_patch_site *start,
 #define __parainstructions_end	NULL
 #endif
 
-extern void add_nops(void *insns, unsigned int len);
-
 /*
  * Clear and restore the kernel write-protection flag on the local CPU.
  * Allows the kernel to edit read-only pages.
@@ -161,10 +157,7 @@ extern void add_nops(void *insns, unsigned int len);
  * Intel's errata.
  * On the local CPU you need to be protected again NMI or MCE handlers seeing an
  * inconsistent instruction while you patch.
- * The _early version expects the memory to already be RW.
  */
-
 extern void *text_poke(void *addr, const void *opcode, size_t len);
-extern void *text_poke_early(void *addr, const void *opcode, size_t len);
 
 #endif /* _ASM_X86_ALTERNATIVE_H */
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index bb7d479..474d80d 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -66,13 +66,23 @@ static inline void default_inquire_remote_apic(int apicid)
 }
 
 /*
+ * With 82489DX we can't rely on apic feature bit
+ * retrieved via cpuid but still have to deal with
+ * such an apic chip so we assume that SMP configuration
+ * is found from MP table (64bit case uses ACPI mostly
+ * which set smp presence flag as well so we are safe
+ * to use this helper too).
+ */
+static inline bool apic_from_smp_config(void)
+{
+	return smp_found_config && !disable_apic;
+}
+
+/*
  * Basic functions accessing APICs.
  */
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
-#else
-#define setup_boot_clock setup_boot_APIC_clock
-#define setup_secondary_clock setup_secondary_APIC_clock
 #endif
 
 #ifdef CONFIG_X86_64
@@ -183,6 +193,10 @@ static inline int x2apic_enabled(void)
 }
 
 #define x2apic_supported()	(cpu_has_x2apic)
+static inline void x2apic_force_phys(void)
+{
+	x2apic_phys = 1;
+}
 #else
 static inline void check_x2apic(void)
 {
@@ -194,6 +208,9 @@ static inline int x2apic_enabled(void)
 {
 	return 0;
 }
+static inline void x2apic_force_phys(void)
+{
+}
 
 #define	x2apic_preenabled 0
 #define	x2apic_supported()	0
@@ -245,6 +262,8 @@ static inline void lapic_shutdown(void) { }
 static inline void init_apic_mappings(void) { }
 static inline void disable_local_APIC(void) { }
 static inline void apic_disable(void) { }
+# define setup_boot_APIC_clock x86_init_noop
+# define setup_secondary_APIC_clock x86_init_noop
 #endif /* !CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_64
@@ -293,7 +312,7 @@ struct apic {
 	int (*cpu_present_to_apicid)(int mps_cpu);
 	physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
 	void (*setup_portio_remap)(void);
-	int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
+	int (*check_phys_apicid_present)(int phys_apicid);
 	void (*enable_apic_mode)(void);
 	int (*phys_pkg_id)(int cpuid_apic, int index_msb);
 
@@ -427,7 +446,7 @@ extern struct apic apic_x2apic_uv_x;
 DECLARE_PER_CPU(int, x2apic_extra_bits);
 
 extern int default_cpu_present_to_apicid(int mps_cpu);
-extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
+extern int default_check_phys_apicid_present(int phys_apicid);
 #endif
 
 static inline void default_wait_for_init_deassert(atomic_t *deassert)
@@ -543,9 +562,9 @@ static inline int __default_cpu_present_to_apicid(int mps_cpu)
 }
 
 static inline int
-__default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+__default_check_phys_apicid_present(int phys_apicid)
 {
-	return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
+	return physid_isset(phys_apicid, phys_cpu_present_map);
 }
 
 #ifdef CONFIG_X86_32
@@ -555,13 +574,13 @@ static inline int default_cpu_present_to_apicid(int mps_cpu)
 }
 
 static inline int
-default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+default_check_phys_apicid_present(int phys_apicid)
 {
-	return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
+	return __default_check_phys_apicid_present(phys_apicid);
 }
 #else
 extern int default_cpu_present_to_apicid(int mps_cpu);
-extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
+extern int default_check_phys_apicid_present(int phys_apicid);
 #endif
 
 static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid)
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 7ddb36a..3b62da9 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -8,12 +8,14 @@
  * Ingo Molnar <mingo@redhat.com>, 1999, 2000
  */
 
-#define	APIC_DEFAULT_PHYS_BASE	0xfee00000
+#define IO_APIC_DEFAULT_PHYS_BASE	0xfec00000
+#define	APIC_DEFAULT_PHYS_BASE		0xfee00000
 
 #define	APIC_ID		0x20
 
 #define	APIC_LVR	0x30
 #define		APIC_LVR_MASK		0xFF00FF
+#define		APIC_LVR_DIRECTED_EOI	(1 << 24)
 #define		GET_APIC_VERSION(x)	((x) & 0xFFu)
 #define		GET_APIC_MAXLVT(x)	(((x) >> 16) & 0xFFu)
 #ifdef CONFIG_X86_32
@@ -40,6 +42,7 @@
 #define		APIC_DFR_CLUSTER		0x0FFFFFFFul
 #define		APIC_DFR_FLAT			0xFFFFFFFFul
 #define	APIC_SPIV	0xF0
+#define		APIC_SPIV_DIRECTED_EOI		(1 << 12)
 #define		APIC_SPIV_FOCUS_DISABLED	(1 << 9)
 #define		APIC_SPIV_APIC_ENABLED		(1 << 8)
 #define	APIC_ISR	0x100
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 56be78f..b3ed1e1 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -3,7 +3,7 @@
 
 #ifdef __ASSEMBLY__
 # define __ASM_FORM(x)	x
-# define __ASM_EX_SEC	.section __ex_table
+# define __ASM_EX_SEC	.section __ex_table, "a"
 #else
 # define __ASM_FORM(x)	" " #x " "
 # define __ASM_EX_SEC	" .section __ex_table,\"a\"\n"
@@ -38,10 +38,18 @@
 #define _ASM_DI		__ASM_REG(di)
 
 /* Exception table entry */
+#ifdef __ASSEMBLY__
+# define _ASM_EXTABLE(from,to)	    \
+	__ASM_EX_SEC ;		    \
+	_ASM_ALIGN ;		    \
+	_ASM_PTR from , to ;	    \
+	.previous
+#else
 # define _ASM_EXTABLE(from,to) \
 	__ASM_EX_SEC	\
 	_ASM_ALIGN "\n" \
 	_ASM_PTR #from "," #to "\n" \
 	" .previous\n"
+#endif
 
 #endif /* _ASM_X86_ASM_H */
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 1724e8d..6be33d8 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -85,7 +85,8 @@ struct efi_info {
 struct boot_params {
 	struct screen_info screen_info;			/* 0x000 */
 	struct apm_bios_info apm_bios_info;		/* 0x040 */
-	__u8  _pad2[12];				/* 0x054 */
+	__u8  _pad2[4];					/* 0x054 */
+	__u64  tboot_addr;				/* 0x058 */
 	struct ist_info ist_info;			/* 0x060 */
 	__u8  _pad3[16];				/* 0x070 */
 	__u8  hd0_info[16];	/* obsolete! */		/* 0x080 */
@@ -109,4 +110,14 @@ struct boot_params {
 	__u8  _pad9[276];				/* 0xeec */
 } __attribute__((packed));
 
+enum {
+	X86_SUBARCH_PC = 0,
+	X86_SUBARCH_LGUEST,
+	X86_SUBARCH_XEN,
+	X86_SUBARCH_MRST,
+	X86_NR_SUBARCHS,
+};
+
+
+
 #endif /* _ASM_X86_BOOTPARAM_H */
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index e55dfc1..b54f6af 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -43,8 +43,58 @@ static inline void copy_from_user_page(struct vm_area_struct *vma,
 	memcpy(dst, src, len);
 }
 
-#define PG_non_WB				PG_arch_1
-PAGEFLAG(NonWB, non_WB)
+#define PG_WC				PG_arch_1
+PAGEFLAG(WC, WC)
+
+#ifdef CONFIG_X86_PAT
+/*
+ * X86 PAT uses page flags WC and Uncached together to keep track of
+ * memory type of pages that have backing page struct. X86 PAT supports 3
+ * different memory types, _PAGE_CACHE_WB, _PAGE_CACHE_WC and
+ * _PAGE_CACHE_UC_MINUS and fourth state where page's memory type has not
+ * been changed from its default (value of -1 used to denote this).
+ * Note we do not support _PAGE_CACHE_UC here.
+ *
+ * Caller must hold memtype_lock for atomicity.
+ */
+static inline unsigned long get_page_memtype(struct page *pg)
+{
+	if (!PageUncached(pg) && !PageWC(pg))
+		return -1;
+	else if (!PageUncached(pg) && PageWC(pg))
+		return _PAGE_CACHE_WC;
+	else if (PageUncached(pg) && !PageWC(pg))
+		return _PAGE_CACHE_UC_MINUS;
+	else
+		return _PAGE_CACHE_WB;
+}
+
+static inline void set_page_memtype(struct page *pg, unsigned long memtype)
+{
+	switch (memtype) {
+	case _PAGE_CACHE_WC:
+		ClearPageUncached(pg);
+		SetPageWC(pg);
+		break;
+	case _PAGE_CACHE_UC_MINUS:
+		SetPageUncached(pg);
+		ClearPageWC(pg);
+		break;
+	case _PAGE_CACHE_WB:
+		SetPageUncached(pg);
+		SetPageWC(pg);
+		break;
+	default:
+	case -1:
+		ClearPageUncached(pg);
+		ClearPageWC(pg);
+		break;
+	}
+}
+#else
+static inline unsigned long get_page_memtype(struct page *pg) { return -1; }
+static inline void set_page_memtype(struct page *pg, unsigned long memtype) { }
+#endif
 
 /*
  * The set_memory_* API can be used to change various attributes of a virtual
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 4a28d22..9cfc88b 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -95,6 +95,8 @@
 #define X86_FEATURE_NONSTOP_TSC	(3*32+24) /* TSC does not stop in C states */
 #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */
 #define X86_FEATURE_EXTD_APICID	(3*32+26) /* has extended APICID (8 bits) */
+#define X86_FEATURE_AMD_DCM     (3*32+27) /* multi-node processor */
+#define X86_FEATURE_APERFMPERF	(3*32+28) /* APERFMPERF */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h
index c68c361..4d447b7 100644
--- a/arch/x86/include/asm/current.h
+++ b/arch/x86/include/asm/current.h
@@ -11,7 +11,7 @@ DECLARE_PER_CPU(struct task_struct *, current_task);
 
 static __always_inline struct task_struct *get_current(void)
 {
-	return percpu_read(current_task);
+	return percpu_read_stable(current_task);
 }
 
 #define current get_current()
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index c993e9e..e8de2f6 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -291,11 +291,24 @@ static inline unsigned long get_desc_base(const struct desc_struct *desc)
 	return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24);
 }
 
+static inline void set_desc_base(struct desc_struct *desc, unsigned long base)
+{
+	desc->base0 = base & 0xffff;
+	desc->base1 = (base >> 16) & 0xff;
+	desc->base2 = (base >> 24) & 0xff;
+}
+
 static inline unsigned long get_desc_limit(const struct desc_struct *desc)
 {
 	return desc->limit0 | (desc->limit << 16);
 }
 
+static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit)
+{
+	desc->limit0 = limit & 0xffff;
+	desc->limit = (limit >> 16) & 0xf;
+}
+
 static inline void _set_gate(int gate, unsigned type, void *addr,
 			     unsigned dpl, unsigned ist, unsigned seg)
 {
diff --git a/arch/x86/include/asm/desc_defs.h b/arch/x86/include/asm/desc_defs.h
index a6adefa..9d66848 100644
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -34,6 +34,12 @@ struct desc_struct {
 	};
 } __attribute__((packed));
 
+#define GDT_ENTRY_INIT(flags, base, limit) { { { \
+		.a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \
+		.b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \
+			((limit) & 0xf0000) | ((base) & 0xff000000), \
+	} } }
+
 enum {
 	GATE_INTERRUPT = 0xE,
 	GATE_TRAP = 0xF,
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index 4994a20..cee34e9 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -13,4 +13,7 @@ struct dma_map_ops *dma_ops;
 #endif
 };
 
+struct pdev_archdata {
+};
+
 #endif /* _ASM_X86_DEVICE_H */
diff --git a/arch/x86/include/asm/do_timer.h b/arch/x86/include/asm/do_timer.h
deleted file mode 100644
index 23ecda0..0000000
--- a/arch/x86/include/asm/do_timer.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* defines for inline arch setup functions */
-#include <linux/clockchips.h>
-
-#include <asm/i8259.h>
-#include <asm/i8253.h>
-
-/**
- * do_timer_interrupt_hook - hook into timer tick
- *
- * Call the pit clock event handler. see asm/i8253.h
- **/
-
-static inline void do_timer_interrupt_hook(void)
-{
-	global_clock_event->event_handler(global_clock_event);
-}
diff --git a/arch/x86/include/asm/dwarf2.h b/arch/x86/include/asm/dwarf2.h
index 3afc5e8..ae6253a 100644
--- a/arch/x86/include/asm/dwarf2.h
+++ b/arch/x86/include/asm/dwarf2.h
@@ -87,9 +87,25 @@
 	CFI_RESTORE \reg
 	.endm
 #else /*!CONFIG_X86_64*/
+	.macro pushl_cfi reg
+	pushl \reg
+	CFI_ADJUST_CFA_OFFSET 4
+	.endm
 
-	/* 32bit defenitions are missed yet */
+	.macro popl_cfi reg
+	popl \reg
+	CFI_ADJUST_CFA_OFFSET -4
+	.endm
 
+	.macro movl_cfi reg offset=0
+	movl %\reg, \offset(%esp)
+	CFI_REL_OFFSET \reg, \offset
+	.endm
+
+	.macro movl_cfi_restore offset reg
+	movl \offset(%esp), %\reg
+	CFI_RESTORE \reg
+	.endm
 #endif /*!CONFIG_X86_64*/
 #endif /*__ASSEMBLY__*/
 
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 7ecba4d..40b4e61 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -126,8 +126,6 @@ extern void e820_reserve_resources(void);
 extern void e820_reserve_resources_late(void);
 extern void setup_memory_map(void);
 extern char *default_machine_specific_memory_setup(void);
-extern char *machine_specific_memory_setup(void);
-extern char *memory_setup(void);
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 83c1bc8..456a304 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -299,6 +299,8 @@ do {									\
 
 #ifdef CONFIG_X86_32
 
+#define STACK_RND_MASK (0x7ff)
+
 #define VDSO_HIGH_BASE		(__fix_to_virt(FIX_VDSO))
 
 #define ARCH_DLINFO		ARCH_DLINFO_IA32(vdso_enabled)
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index ff8cbfa..f5693c8 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -49,7 +49,7 @@ BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
 BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
 BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
 
-#ifdef CONFIG_PERF_COUNTERS
+#ifdef CONFIG_PERF_EVENTS
 BUILD_INTERRUPT(perf_pending_interrupt, LOCAL_PENDING_VECTOR)
 #endif
 
@@ -61,7 +61,7 @@ BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
 BUILD_INTERRUPT(threshold_interrupt,THRESHOLD_APIC_VECTOR)
 #endif
 
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
 BUILD_INTERRUPT(mce_self_interrupt,MCE_SELF_VECTOR)
 #endif
 
diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h
index 7b2d71d..14f9890 100644
--- a/arch/x86/include/asm/fixmap.h
+++ b/arch/x86/include/asm/fixmap.h
@@ -132,6 +132,9 @@ enum fixed_addresses {
 #ifdef CONFIG_X86_32
 	FIX_WP_TEST,
 #endif
+#ifdef CONFIG_INTEL_TXT
+	FIX_TBOOT_BASE,
+#endif
 	__end_of_fixed_addresses
 };
 
diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h
index 369f5c5..b78c094 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -20,7 +20,7 @@
 #ifndef ASM_X86__HYPERVISOR_H
 #define ASM_X86__HYPERVISOR_H
 
-extern unsigned long get_hypervisor_tsc_freq(void);
 extern void init_hypervisor(struct cpuinfo_x86 *c);
+extern void init_hypervisor_platform(void);
 
 #endif
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index 175adf5..0b20bbb 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -26,6 +26,7 @@ extern void fpu_init(void);
 extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
 extern asmlinkage void math_state_restore(void);
+extern void __math_state_restore(void);
 extern void init_thread_xstate(void);
 extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
 
@@ -301,6 +302,14 @@ static inline void kernel_fpu_end(void)
 	preempt_enable();
 }
 
+static inline bool irq_fpu_usable(void)
+{
+	struct pt_regs *regs;
+
+	return !in_interrupt() || !(regs = get_irq_regs()) || \
+		user_mode(regs) || (read_cr0() & X86_CR0_TS);
+}
+
 /*
  * Some instructions like VIA's padlock instructions generate a spurious
  * DNA fault but don't modify SSE registers. And these instructions
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 330ee80..7c7c16c 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -143,6 +143,8 @@ extern int noioapicreroute;
 /* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
 extern int timer_through_8259;
 
+extern void io_apic_disable_legacy(void);
+
 /*
  * If we use the IO-APIC for IRQ routing, disable automatic
  * assignment of PCI IRQ's.
@@ -150,11 +152,10 @@ extern int timer_through_8259;
 #define io_apic_assign_pci_irqs \
 	(mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
 
-#ifdef CONFIG_ACPI
+extern u8 io_apic_unique_id(u8 id);
 extern int io_apic_get_unique_id(int ioapic, int apic_id);
 extern int io_apic_get_version(int ioapic);
 extern int io_apic_get_redir_entries(int ioapic);
-#endif /* CONFIG_ACPI */
 
 struct io_apic_irq_attr;
 extern int io_apic_set_pci_routing(struct device *dev, int irq,
@@ -177,13 +178,26 @@ extern int setup_ioapic_entry(int apic, int irq,
 			      int polarity, int vector, int pin);
 extern void ioapic_write_entry(int apic, int pin,
 			       struct IO_APIC_route_entry e);
+extern void setup_ioapic_ids_from_mpc(void);
+
+struct mp_ioapic_gsi{
+	int gsi_base;
+	int gsi_end;
+};
+extern struct mp_ioapic_gsi  mp_gsi_routing[];
+int mp_find_ioapic(int gsi);
+int mp_find_ioapic_pin(int ioapic, int gsi);
+void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
+
 #else  /* !CONFIG_X86_IO_APIC */
+
 #define io_apic_assign_pci_irqs 0
+#define setup_ioapic_ids_from_mpc x86_init_noop
 static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
 static inline void ioapic_insert_resources(void) { }
-
 static inline void probe_nr_irqs_gsi(void)	{ }
+
 #endif
 
 #endif /* _ASM_X86_IO_APIC_H */
diff --git a/arch/x86/include/asm/ioctls.h b/arch/x86/include/asm/ioctls.h
index 0d5b23b..ec34c76 100644
--- a/arch/x86/include/asm/ioctls.h
+++ b/arch/x86/include/asm/ioctls.h
@@ -1,94 +1 @@
-#ifndef _ASM_X86_IOCTLS_H
-#define _ASM_X86_IOCTLS_H
-
-#include <asm/ioctl.h>
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS		0x5401
-#define TCSETS		0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
-#define TCSETSW		0x5403
-#define TCSETSF		0x5404
-#define TCGETA		0x5405
-#define TCSETA		0x5406
-#define TCSETAW		0x5407
-#define TCSETAF		0x5408
-#define TCSBRK		0x5409
-#define TCXONC		0x540A
-#define TCFLSH		0x540B
-#define TIOCEXCL	0x540C
-#define TIOCNXCL	0x540D
-#define TIOCSCTTY	0x540E
-#define TIOCGPGRP	0x540F
-#define TIOCSPGRP	0x5410
-#define TIOCOUTQ	0x5411
-#define TIOCSTI		0x5412
-#define TIOCGWINSZ	0x5413
-#define TIOCSWINSZ	0x5414
-#define TIOCMGET	0x5415
-#define TIOCMBIS	0x5416
-#define TIOCMBIC	0x5417
-#define TIOCMSET	0x5418
-#define TIOCGSOFTCAR	0x5419
-#define TIOCSSOFTCAR	0x541A
-#define FIONREAD	0x541B
-#define TIOCINQ		FIONREAD
-#define TIOCLINUX	0x541C
-#define TIOCCONS	0x541D
-#define TIOCGSERIAL	0x541E
-#define TIOCSSERIAL	0x541F
-#define TIOCPKT		0x5420
-#define FIONBIO		0x5421
-#define TIOCNOTTY	0x5422
-#define TIOCSETD	0x5423
-#define TIOCGETD	0x5424
-#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
-/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
-#define TIOCSBRK	0x5427  /* BSD compatibility */
-#define TIOCCBRK	0x5428  /* BSD compatibility */
-#define TIOCGSID	0x5429  /* Return the session ID of FD */
-#define TCGETS2		_IOR('T', 0x2A, struct termios2)
-#define TCSETS2		_IOW('T', 0x2B, struct termios2)
-#define TCSETSW2	_IOW('T', 0x2C, struct termios2)
-#define TCSETSF2	_IOW('T', 0x2D, struct termios2)
-#define TIOCGRS485	0x542E
-#define TIOCSRS485	0x542F
-#define TIOCGPTN	_IOR('T', 0x30, unsigned int)
-				/* Get Pty Number (of pty-mux device) */
-#define TIOCSPTLCK	_IOW('T', 0x31, int)  /* Lock/unlock Pty */
-#define TCGETX		0x5432 /* SYS5 TCGETX compatibility */
-#define TCSETX		0x5433
-#define TCSETXF		0x5434
-#define TCSETXW		0x5435
-
-#define FIONCLEX	0x5450
-#define FIOCLEX		0x5451
-#define FIOASYNC	0x5452
-#define TIOCSERCONFIG	0x5453
-#define TIOCSERGWILD	0x5454
-#define TIOCSERSWILD	0x5455
-#define TIOCGLCKTRMIOS	0x5456
-#define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
-#define TIOCSERGETLSR   0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
-#define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
-#define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
-#define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
-#define FIOQSIZE	0x5460
-
-/* Used for packet mode */
-#define TIOCPKT_DATA		 0
-#define TIOCPKT_FLUSHREAD	 1
-#define TIOCPKT_FLUSHWRITE	 2
-#define TIOCPKT_STOP		 4
-#define TIOCPKT_START		 8
-#define TIOCPKT_NOSTOP		16
-#define TIOCPKT_DOSTOP		32
-
-#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
-
-#endif /* _ASM_X86_IOCTLS_H */
+#include <asm-generic/ioctls.h>
diff --git a/arch/x86/include/asm/iomap.h b/arch/x86/include/asm/iomap.h
index 0e9fe1d..f35eb45 100644
--- a/arch/x86/include/asm/iomap.h
+++ b/arch/x86/include/asm/iomap.h
@@ -26,13 +26,16 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 
-int
-is_io_mapping_possible(resource_size_t base, unsigned long size);
-
 void *
 iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
 
 void
 iounmap_atomic(void *kvaddr, enum km_type type);
 
+int
+iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot);
+
+void
+iomap_free(resource_size_t base, unsigned long size);
+
 #endif /* _ASM_X86_IOMAP_H */
diff --git a/arch/x86/include/asm/ipcbuf.h b/arch/x86/include/asm/ipcbuf.h
index ee678fd..84c7e51 100644
--- a/arch/x86/include/asm/ipcbuf.h
+++ b/arch/x86/include/asm/ipcbuf.h
@@ -1,28 +1 @@
-#ifndef _ASM_X86_IPCBUF_H
-#define _ASM_X86_IPCBUF_H
-
-/*
- * The ipc64_perm structure for x86 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space is left for:
- * - 32-bit mode_t and seq
- * - 2 miscellaneous 32-bit values
- */
-
-struct ipc64_perm {
-	__kernel_key_t		key;
-	__kernel_uid32_t	uid;
-	__kernel_gid32_t	gid;
-	__kernel_uid32_t	cuid;
-	__kernel_gid32_t	cgid;
-	__kernel_mode_t		mode;
-	unsigned short		__pad1;
-	unsigned short		seq;
-	unsigned short		__pad2;
-	unsigned long		__unused1;
-	unsigned long		__unused2;
-};
-
-#endif /* _ASM_X86_IPCBUF_H */
+#include <asm-generic/ipcbuf.h>
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index f38481b..ddda6cb 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -37,7 +37,6 @@ extern void fixup_irqs(void);
 #endif
 
 extern void (*generic_interrupt_extension)(void);
-extern void init_IRQ(void);
 extern void native_init_IRQ(void);
 extern bool handle_irq(unsigned irq, struct pt_regs *regs);
 
@@ -47,4 +46,6 @@ extern unsigned int do_IRQ(struct pt_regs *regs);
 extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
 extern int vector_used_by_percpu_irq(unsigned int vector);
 
+extern void init_ISA_irqs(void);
+
 #endif /* _ASM_X86_IRQ_H */
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
index c6ccbe7..9e2b952 100644
--- a/arch/x86/include/asm/irqflags.h
+++ b/arch/x86/include/asm/irqflags.h
@@ -13,14 +13,13 @@ static inline unsigned long native_save_fl(void)
 	unsigned long flags;
 
 	/*
-	 * Note: this needs to be "=r" not "=rm", because we have the
-	 * stack offset from what gcc expects at the time the "pop" is
-	 * executed, and so a memory reference with respect to the stack
-	 * would end up using the wrong address.
+	 * "=rm" is safe here, because "pop" adjusts the stack before
+	 * it evaluates its effective address -- this is part of the
+	 * documented behavior of the "pop" instruction.
 	 */
 	asm volatile("# __raw_save_flags\n\t"
 		     "pushf ; pop %0"
-		     : "=r" (flags)
+		     : "=rm" (flags)
 		     : /* no input */
 		     : "memory");
 
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 125be8b..4a5fe91 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -17,6 +17,8 @@
 #define __KVM_HAVE_USER_NMI
 #define __KVM_HAVE_GUEST_DEBUG
 #define __KVM_HAVE_MSIX
+#define __KVM_HAVE_MCE
+#define __KVM_HAVE_PIT_STATE2
 
 /* Architectural interrupt line count. */
 #define KVM_NR_INTERRUPTS 256
@@ -236,6 +238,14 @@ struct kvm_pit_state {
 	struct kvm_pit_channel_state channels[3];
 };
 
+#define KVM_PIT_FLAGS_HPET_LEGACY  0x00000001
+
+struct kvm_pit_state2 {
+	struct kvm_pit_channel_state channels[3];
+	__u32 flags;
+	__u32 reserved[9];
+};
+
 struct kvm_reinject_control {
 	__u8 pit_reinject;
 	__u8 reserved[31];
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
new file mode 100644
index 0000000..b7ed2c4
--- /dev/null
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -0,0 +1,187 @@
+/******************************************************************************
+ * x86_emulate.h
+ *
+ * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
+ *
+ * Copyright (c) 2005 Keir Fraser
+ *
+ * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
+ */
+
+#ifndef _ASM_X86_KVM_X86_EMULATE_H
+#define _ASM_X86_KVM_X86_EMULATE_H
+
+struct x86_emulate_ctxt;
+
+/*
+ * x86_emulate_ops:
+ *
+ * These operations represent the instruction emulator's interface to memory.
+ * There are two categories of operation: those that act on ordinary memory
+ * regions (*_std), and those that act on memory regions known to require
+ * special treatment or emulation (*_emulated).
+ *
+ * The emulator assumes that an instruction accesses only one 'emulated memory'
+ * location, that this location is the given linear faulting address (cr2), and
+ * that this is one of the instruction's data operands. Instruction fetches and
+ * stack operations are assumed never to access emulated memory. The emulator
+ * automatically deduces which operand of a string-move operation is accessing
+ * emulated memory, and assumes that the other operand accesses normal memory.
+ *
+ * NOTES:
+ *  1. The emulator isn't very smart about emulated vs. standard memory.
+ *     'Emulated memory' access addresses should be checked for sanity.
+ *     'Normal memory' accesses may fault, and the caller must arrange to
+ *     detect and handle reentrancy into the emulator via recursive faults.
+ *     Accesses may be unaligned and may cross page boundaries.
+ *  2. If the access fails (cannot emulate, or a standard access faults) then
+ *     it is up to the memop to propagate the fault to the guest VM via
+ *     some out-of-band mechanism, unknown to the emulator. The memop signals
+ *     failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will
+ *     then immediately bail.
+ *  3. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only
+ *     cmpxchg8b_emulated need support 8-byte accesses.
+ *  4. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
+ */
+/* Access completed successfully: continue emulation as normal. */
+#define X86EMUL_CONTINUE        0
+/* Access is unhandleable: bail from emulation and return error to caller. */
+#define X86EMUL_UNHANDLEABLE    1
+/* Terminate emulation but return success to the caller. */
+#define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
+#define X86EMUL_RETRY_INSTR     2 /* retry the instruction for some reason */
+#define X86EMUL_CMPXCHG_FAILED  2 /* cmpxchg did not see expected value */
+struct x86_emulate_ops {
+	/*
+	 * read_std: Read bytes of standard (non-emulated/special) memory.
+	 *           Used for instruction fetch, stack operations, and others.
+	 *  @addr:  [IN ] Linear address from which to read.
+	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
+	 *  @bytes: [IN ] Number of bytes to read from memory.
+	 */
+	int (*read_std)(unsigned long addr, void *val,
+			unsigned int bytes, struct kvm_vcpu *vcpu);
+
+	/*
+	 * read_emulated: Read bytes from emulated/special memory area.
+	 *  @addr:  [IN ] Linear address from which to read.
+	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
+	 *  @bytes: [IN ] Number of bytes to read from memory.
+	 */
+	int (*read_emulated)(unsigned long addr,
+			     void *val,
+			     unsigned int bytes,
+			     struct kvm_vcpu *vcpu);
+
+	/*
+	 * write_emulated: Read bytes from emulated/special memory area.
+	 *  @addr:  [IN ] Linear address to which to write.
+	 *  @val:   [IN ] Value to write to memory (low-order bytes used as
+	 *                required).
+	 *  @bytes: [IN ] Number of bytes to write to memory.
+	 */
+	int (*write_emulated)(unsigned long addr,
+			      const void *val,
+			      unsigned int bytes,
+			      struct kvm_vcpu *vcpu);
+
+	/*
+	 * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
+	 *                   emulated/special memory area.
+	 *  @addr:  [IN ] Linear address to access.
+	 *  @old:   [IN ] Value expected to be current at @addr.
+	 *  @new:   [IN ] Value to write to @addr.
+	 *  @bytes: [IN ] Number of bytes to access using CMPXCHG.
+	 */
+	int (*cmpxchg_emulated)(unsigned long addr,
+				const void *old,
+				const void *new,
+				unsigned int bytes,
+				struct kvm_vcpu *vcpu);
+
+};
+
+/* Type, address-of, and value of an instruction's operand. */
+struct operand {
+	enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
+	unsigned int bytes;
+	unsigned long val, orig_val, *ptr;
+};
+
+struct fetch_cache {
+	u8 data[15];
+	unsigned long start;
+	unsigned long end;
+};
+
+struct decode_cache {
+	u8 twobyte;
+	u8 b;
+	u8 lock_prefix;
+	u8 rep_prefix;
+	u8 op_bytes;
+	u8 ad_bytes;
+	u8 rex_prefix;
+	struct operand src;
+	struct operand src2;
+	struct operand dst;
+	bool has_seg_override;
+	u8 seg_override;
+	unsigned int d;
+	unsigned long regs[NR_VCPU_REGS];
+	unsigned long eip;
+	/* modrm */
+	u8 modrm;
+	u8 modrm_mod;
+	u8 modrm_reg;
+	u8 modrm_rm;
+	u8 use_modrm_ea;
+	bool rip_relative;
+	unsigned long modrm_ea;
+	void *modrm_ptr;
+	unsigned long modrm_val;
+	struct fetch_cache fetch;
+};
+
+#define X86_SHADOW_INT_MOV_SS  1
+#define X86_SHADOW_INT_STI     2
+
+struct x86_emulate_ctxt {
+	/* Register state before/after emulation. */
+	struct kvm_vcpu *vcpu;
+
+	unsigned long eflags;
+	/* Emulated execution mode, represented by an X86EMUL_MODE value. */
+	int mode;
+	u32 cs_base;
+
+	/* interruptibility state, as a result of execution of STI or MOV SS */
+	int interruptibility;
+
+	/* decode cache */
+	struct decode_cache decode;
+};
+
+/* Repeat String Operation Prefix */
+#define REPE_PREFIX	1
+#define REPNE_PREFIX	2
+
+/* Execution mode, passed to the emulator. */
+#define X86EMUL_MODE_REAL     0	/* Real mode.             */
+#define X86EMUL_MODE_PROT16   2	/* 16-bit protected mode. */
+#define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */
+#define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */
+
+/* Host execution mode. */
+#if defined(CONFIG_X86_32)
+#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
+#elif defined(CONFIG_X86_64)
+#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
+#endif
+
+int x86_decode_insn(struct x86_emulate_ctxt *ctxt,
+		    struct x86_emulate_ops *ops);
+int x86_emulate_insn(struct x86_emulate_ctxt *ctxt,
+		     struct x86_emulate_ops *ops);
+
+#endif /* _ASM_X86_KVM_X86_EMULATE_H */
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index eabdc1c..3be0004 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/mmu_notifier.h>
+#include <linux/tracepoint.h>
 
 #include <linux/kvm.h>
 #include <linux/kvm_para.h>
@@ -37,12 +38,14 @@
 #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS |	\
 				  0xFFFFFF0000000000ULL)
 
-#define KVM_GUEST_CR0_MASK				   \
-	(X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE \
-	 | X86_CR0_NW | X86_CR0_CD)
+#define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST				\
+	(X86_CR0_WP | X86_CR0_NE | X86_CR0_NW | X86_CR0_CD)
+#define KVM_GUEST_CR0_MASK						\
+	(KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
+#define KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST				\
+	(X86_CR0_WP | X86_CR0_NE | X86_CR0_TS | X86_CR0_MP)
 #define KVM_VM_CR0_ALWAYS_ON						\
-	(X86_CR0_PG | X86_CR0_PE | X86_CR0_WP | X86_CR0_NE | X86_CR0_TS \
-	 | X86_CR0_MP)
+	(KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST | X86_CR0_PG | X86_CR0_PE)
 #define KVM_GUEST_CR4_MASK						\
 	(X86_CR4_VME | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_PGE | X86_CR4_VMXE)
 #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
@@ -51,12 +54,12 @@
 #define INVALID_PAGE (~(hpa_t)0)
 #define UNMAPPED_GVA (~(gpa_t)0)
 
-/* shadow tables are PAE even on non-PAE hosts */
-#define KVM_HPAGE_SHIFT 21
-#define KVM_HPAGE_SIZE (1UL << KVM_HPAGE_SHIFT)
-#define KVM_HPAGE_MASK (~(KVM_HPAGE_SIZE - 1))
-
-#define KVM_PAGES_PER_HPAGE (KVM_HPAGE_SIZE / PAGE_SIZE)
+/* KVM Hugepage definitions for x86 */
+#define KVM_NR_PAGE_SIZES	3
+#define KVM_HPAGE_SHIFT(x)	(PAGE_SHIFT + (((x) - 1) * 9))
+#define KVM_HPAGE_SIZE(x)	(1UL << KVM_HPAGE_SHIFT(x))
+#define KVM_HPAGE_MASK(x)	(~(KVM_HPAGE_SIZE(x) - 1))
+#define KVM_PAGES_PER_HPAGE(x)	(KVM_HPAGE_SIZE(x) / PAGE_SIZE)
 
 #define DE_VECTOR 0
 #define DB_VECTOR 1
@@ -120,6 +123,10 @@ enum kvm_reg {
 	NR_VCPU_REGS
 };
 
+enum kvm_reg_ex {
+	VCPU_EXREG_PDPTR = NR_VCPU_REGS,
+};
+
 enum {
 	VCPU_SREG_ES,
 	VCPU_SREG_CS,
@@ -131,7 +138,7 @@ enum {
 	VCPU_SREG_LDTR,
 };
 
-#include <asm/kvm_x86_emulate.h>
+#include <asm/kvm_emulate.h>
 
 #define KVM_NR_MEM_OBJS 40
 
@@ -308,7 +315,6 @@ struct kvm_vcpu_arch {
 	struct {
 		gfn_t gfn;	/* presumed gfn during guest pte update */
 		pfn_t pfn;	/* pfn corresponding to that gfn */
-		int largepage;
 		unsigned long mmu_seq;
 	} update_pte;
 
@@ -334,16 +340,6 @@ struct kvm_vcpu_arch {
 		u8 nr;
 	} interrupt;
 
-	struct {
-		int vm86_active;
-		u8 save_iopl;
-		struct kvm_save_segment {
-			u16 selector;
-			unsigned long base;
-			u32 limit;
-			u32 ar;
-		} tr, es, ds, fs, gs;
-	} rmode;
 	int halt_request; /* real mode on Intel only */
 
 	int cpuid_nent;
@@ -366,13 +362,15 @@ struct kvm_vcpu_arch {
 	u32 pat;
 
 	int switch_db_regs;
-	unsigned long host_db[KVM_NR_DB_REGS];
-	unsigned long host_dr6;
-	unsigned long host_dr7;
 	unsigned long db[KVM_NR_DB_REGS];
 	unsigned long dr6;
 	unsigned long dr7;
 	unsigned long eff_db[KVM_NR_DB_REGS];
+
+	u64 mcg_cap;
+	u64 mcg_status;
+	u64 mcg_ctl;
+	u64 *mce_banks;
 };
 
 struct kvm_mem_alias {
@@ -409,6 +407,7 @@ struct kvm_arch{
 
 	struct page *ept_identity_pagetable;
 	bool ept_identity_pagetable_done;
+	gpa_t ept_identity_map_addr;
 
 	unsigned long irq_sources_bitmap;
 	unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
@@ -526,6 +525,9 @@ struct kvm_x86_ops {
 	int (*set_tss_addr)(struct kvm *kvm, unsigned int addr);
 	int (*get_tdp_level)(void);
 	u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio);
+	bool (*gb_page_enable)(void);
+
+	const struct trace_print_flags *exit_reasons_str;
 };
 
 extern struct kvm_x86_ops *kvm_x86_ops;
@@ -618,6 +620,7 @@ void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr);
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
 			   u32 error_code);
+bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
 
 int kvm_pic_set_irq(void *opaque, int irq, int level);
 
@@ -752,8 +755,6 @@ static inline void kvm_inject_gp(struct kvm_vcpu *vcpu, u32 error_code)
 	kvm_queue_exception_e(vcpu, GP_VECTOR, error_code);
 }
 
-#define MSR_IA32_TIME_STAMP_COUNTER		0x010
-
 #define TSS_IOPB_BASE_OFFSET 0x66
 #define TSS_BASE_SIZE 0x68
 #define TSS_IOPB_SIZE (65536 / 8)
@@ -796,5 +797,8 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
 int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
 int kvm_age_hva(struct kvm *kvm, unsigned long hva);
 int cpuid_maxphyaddr(struct kvm_vcpu *vcpu);
+int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu);
+int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
+int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
 
 #endif /* _ASM_X86_KVM_HOST_H */
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index b8a3305..c584076 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -1,6 +1,8 @@
 #ifndef _ASM_X86_KVM_PARA_H
 #define _ASM_X86_KVM_PARA_H
 
+#include <linux/types.h>
+
 /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
  * should be used to determine that a VM is running under KVM.
  */
diff --git a/arch/x86/include/asm/kvm_x86_emulate.h b/arch/x86/include/asm/kvm_x86_emulate.h
deleted file mode 100644
index b7ed2c4..0000000
--- a/arch/x86/include/asm/kvm_x86_emulate.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/******************************************************************************
- * x86_emulate.h
- *
- * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
- *
- * Copyright (c) 2005 Keir Fraser
- *
- * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
- */
-
-#ifndef _ASM_X86_KVM_X86_EMULATE_H
-#define _ASM_X86_KVM_X86_EMULATE_H
-
-struct x86_emulate_ctxt;
-
-/*
- * x86_emulate_ops:
- *
- * These operations represent the instruction emulator's interface to memory.
- * There are two categories of operation: those that act on ordinary memory
- * regions (*_std), and those that act on memory regions known to require
- * special treatment or emulation (*_emulated).
- *
- * The emulator assumes that an instruction accesses only one 'emulated memory'
- * location, that this location is the given linear faulting address (cr2), and
- * that this is one of the instruction's data operands. Instruction fetches and
- * stack operations are assumed never to access emulated memory. The emulator
- * automatically deduces which operand of a string-move operation is accessing
- * emulated memory, and assumes that the other operand accesses normal memory.
- *
- * NOTES:
- *  1. The emulator isn't very smart about emulated vs. standard memory.
- *     'Emulated memory' access addresses should be checked for sanity.
- *     'Normal memory' accesses may fault, and the caller must arrange to
- *     detect and handle reentrancy into the emulator via recursive faults.
- *     Accesses may be unaligned and may cross page boundaries.
- *  2. If the access fails (cannot emulate, or a standard access faults) then
- *     it is up to the memop to propagate the fault to the guest VM via
- *     some out-of-band mechanism, unknown to the emulator. The memop signals
- *     failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will
- *     then immediately bail.
- *  3. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only
- *     cmpxchg8b_emulated need support 8-byte accesses.
- *  4. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
- */
-/* Access completed successfully: continue emulation as normal. */
-#define X86EMUL_CONTINUE        0
-/* Access is unhandleable: bail from emulation and return error to caller. */
-#define X86EMUL_UNHANDLEABLE    1
-/* Terminate emulation but return success to the caller. */
-#define X86EMUL_PROPAGATE_FAULT 2 /* propagate a generated fault to guest */
-#define X86EMUL_RETRY_INSTR     2 /* retry the instruction for some reason */
-#define X86EMUL_CMPXCHG_FAILED  2 /* cmpxchg did not see expected value */
-struct x86_emulate_ops {
-	/*
-	 * read_std: Read bytes of standard (non-emulated/special) memory.
-	 *           Used for instruction fetch, stack operations, and others.
-	 *  @addr:  [IN ] Linear address from which to read.
-	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
-	 *  @bytes: [IN ] Number of bytes to read from memory.
-	 */
-	int (*read_std)(unsigned long addr, void *val,
-			unsigned int bytes, struct kvm_vcpu *vcpu);
-
-	/*
-	 * read_emulated: Read bytes from emulated/special memory area.
-	 *  @addr:  [IN ] Linear address from which to read.
-	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
-	 *  @bytes: [IN ] Number of bytes to read from memory.
-	 */
-	int (*read_emulated)(unsigned long addr,
-			     void *val,
-			     unsigned int bytes,
-			     struct kvm_vcpu *vcpu);
-
-	/*
-	 * write_emulated: Read bytes from emulated/special memory area.
-	 *  @addr:  [IN ] Linear address to which to write.
-	 *  @val:   [IN ] Value to write to memory (low-order bytes used as
-	 *                required).
-	 *  @bytes: [IN ] Number of bytes to write to memory.
-	 */
-	int (*write_emulated)(unsigned long addr,
-			      const void *val,
-			      unsigned int bytes,
-			      struct kvm_vcpu *vcpu);
-
-	/*
-	 * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
-	 *                   emulated/special memory area.
-	 *  @addr:  [IN ] Linear address to access.
-	 *  @old:   [IN ] Value expected to be current at @addr.
-	 *  @new:   [IN ] Value to write to @addr.
-	 *  @bytes: [IN ] Number of bytes to access using CMPXCHG.
-	 */
-	int (*cmpxchg_emulated)(unsigned long addr,
-				const void *old,
-				const void *new,
-				unsigned int bytes,
-				struct kvm_vcpu *vcpu);
-
-};
-
-/* Type, address-of, and value of an instruction's operand. */
-struct operand {
-	enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
-	unsigned int bytes;
-	unsigned long val, orig_val, *ptr;
-};
-
-struct fetch_cache {
-	u8 data[15];
-	unsigned long start;
-	unsigned long end;
-};
-
-struct decode_cache {
-	u8 twobyte;
-	u8 b;
-	u8 lock_prefix;
-	u8 rep_prefix;
-	u8 op_bytes;
-	u8 ad_bytes;
-	u8 rex_prefix;
-	struct operand src;
-	struct operand src2;
-	struct operand dst;
-	bool has_seg_override;
-	u8 seg_override;
-	unsigned int d;
-	unsigned long regs[NR_VCPU_REGS];
-	unsigned long eip;
-	/* modrm */
-	u8 modrm;
-	u8 modrm_mod;
-	u8 modrm_reg;
-	u8 modrm_rm;
-	u8 use_modrm_ea;
-	bool rip_relative;
-	unsigned long modrm_ea;
-	void *modrm_ptr;
-	unsigned long modrm_val;
-	struct fetch_cache fetch;
-};
-
-#define X86_SHADOW_INT_MOV_SS  1
-#define X86_SHADOW_INT_STI     2
-
-struct x86_emulate_ctxt {
-	/* Register state before/after emulation. */
-	struct kvm_vcpu *vcpu;
-
-	unsigned long eflags;
-	/* Emulated execution mode, represented by an X86EMUL_MODE value. */
-	int mode;
-	u32 cs_base;
-
-	/* interruptibility state, as a result of execution of STI or MOV SS */
-	int interruptibility;
-
-	/* decode cache */
-	struct decode_cache decode;
-};
-
-/* Repeat String Operation Prefix */
-#define REPE_PREFIX	1
-#define REPNE_PREFIX	2
-
-/* Execution mode, passed to the emulator. */
-#define X86EMUL_MODE_REAL     0	/* Real mode.             */
-#define X86EMUL_MODE_PROT16   2	/* 16-bit protected mode. */
-#define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */
-#define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */
-
-/* Host execution mode. */
-#if defined(CONFIG_X86_32)
-#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
-#elif defined(CONFIG_X86_64)
-#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
-#endif
-
-int x86_decode_insn(struct x86_emulate_ctxt *ctxt,
-		    struct x86_emulate_ops *ops);
-int x86_emulate_insn(struct x86_emulate_ctxt *ctxt,
-		     struct x86_emulate_ops *ops);
-
-#endif /* _ASM_X86_KVM_X86_EMULATE_H */
diff --git a/arch/x86/include/asm/lguest.h b/arch/x86/include/asm/lguest.h
index 5136dad..0d97deb 100644
--- a/arch/x86/include/asm/lguest.h
+++ b/arch/x86/include/asm/lguest.h
@@ -90,8 +90,9 @@ static inline void lguest_set_ts(void)
 }
 
 /* Full 4G segment descriptors, suitable for CS and DS. */
-#define FULL_EXEC_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9b00} } })
-#define FULL_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9300} } })
+#define FULL_EXEC_SEGMENT \
+	((struct desc_struct)GDT_ENTRY_INIT(0xc09b, 0, 0xfffff))
+#define FULL_SEGMENT ((struct desc_struct)GDT_ENTRY_INIT(0xc093, 0, 0xfffff))
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 5cdd8d1..b608a64 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -9,7 +9,7 @@
  */
 
 #define MCG_BANKCNT_MASK	0xff         /* Number of Banks */
-#define MCG_CTL_P		(1ULL<<8)    /* MCG_CAP register available */
+#define MCG_CTL_P		(1ULL<<8)    /* MCG_CTL register available */
 #define MCG_EXT_P		(1ULL<<9)    /* Extended registers available */
 #define MCG_CMCI_P		(1ULL<<10)   /* CMCI supported */
 #define MCG_EXT_CNT_MASK	0xff0000     /* Number of Extended registers */
@@ -38,6 +38,14 @@
 #define MCM_ADDR_MEM	 3	/* memory address */
 #define MCM_ADDR_GENERIC 7	/* generic */
 
+#define MCJ_CTX_MASK		3
+#define MCJ_CTX(flags)		((flags) & MCJ_CTX_MASK)
+#define MCJ_CTX_RANDOM		0    /* inject context: random */
+#define MCJ_CTX_PROCESS		1    /* inject context: process */
+#define MCJ_CTX_IRQ		2    /* inject context: IRQ */
+#define MCJ_NMI_BROADCAST	4    /* do NMI broadcasting */
+#define MCJ_EXCEPTION		8    /* raise as exception */
+
 /* Fields are zero when not available */
 struct mce {
 	__u64 status;
@@ -48,8 +56,8 @@ struct mce {
 	__u64 tsc;	/* cpu time stamp counter */
 	__u64 time;	/* wall time_t when error was detected */
 	__u8  cpuvendor;	/* cpu vendor as encoded in system.h */
-	__u8  pad1;
-	__u16 pad2;
+	__u8  inject_flags;	/* software inject flags */
+	__u16  pad;
 	__u32 cpuid;	/* CPUID 1 EAX */
 	__u8  cs;		/* code segment */
 	__u8  bank;	/* machine check bank */
@@ -115,13 +123,6 @@ void mcheck_init(struct cpuinfo_x86 *c);
 static inline void mcheck_init(struct cpuinfo_x86 *c) {}
 #endif
 
-#ifdef CONFIG_X86_OLD_MCE
-extern int nr_mce_banks;
-void amd_mcheck_init(struct cpuinfo_x86 *c);
-void intel_p4_mcheck_init(struct cpuinfo_x86 *c);
-void intel_p6_mcheck_init(struct cpuinfo_x86 *c);
-#endif
-
 #ifdef CONFIG_X86_ANCIENT_MCE
 void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
 void winchip_mcheck_init(struct cpuinfo_x86 *c);
@@ -137,10 +138,11 @@ void mce_log(struct mce *m);
 DECLARE_PER_CPU(struct sys_device, mce_dev);
 
 /*
- * To support more than 128 would need to escape the predefined
- * Linux defined extended banks first.
+ * Maximum banks number.
+ * This is the limit of the current register layout on
+ * Intel CPUs.
  */
-#define MAX_NR_BANKS (MCE_EXTENDED_BANK - 1)
+#define MAX_NR_BANKS 32
 
 #ifdef CONFIG_X86_MCE_INTEL
 extern int mce_cmci_disabled;
@@ -208,11 +210,7 @@ extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
 
 void intel_init_thermal(struct cpuinfo_x86 *c);
 
-#ifdef CONFIG_X86_NEW_MCE
 void mce_log_therm_throt_event(__u64 status);
-#else
-static inline void mce_log_therm_throt_event(__u64 status) {}
-#endif
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_X86_MCE_H */
diff --git a/arch/x86/include/asm/mman.h b/arch/x86/include/asm/mman.h
index 751af25..593e51d 100644
--- a/arch/x86/include/asm/mman.h
+++ b/arch/x86/include/asm/mman.h
@@ -1,20 +1,8 @@
 #ifndef _ASM_X86_MMAN_H
 #define _ASM_X86_MMAN_H
 
-#include <asm-generic/mman-common.h>
-
 #define MAP_32BIT	0x40		/* only give out 32bit addresses */
 
-#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
-#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
-#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
-#define MAP_LOCKED	0x2000		/* pages are locked */
-#define MAP_NORESERVE	0x4000		/* don't check for reservations */
-#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
-#define MAP_NONBLOCK	0x10000		/* do not block on IO */
-#define MAP_STACK	0x20000		/* give out an address that is best suited for process/thread stacks */
-
-#define MCL_CURRENT	1		/* lock all current mappings */
-#define MCL_FUTURE	2		/* lock all future mappings */
+#include <asm-generic/mman.h>
 
 #endif /* _ASM_X86_MMAN_H */
diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
index 47d6274..3e2ce58 100644
--- a/arch/x86/include/asm/module.h
+++ b/arch/x86/include/asm/module.h
@@ -1,18 +1,7 @@
 #ifndef _ASM_X86_MODULE_H
 #define _ASM_X86_MODULE_H
 
-/* x86_32/64 are simple */
-struct mod_arch_specific {};
-
-#ifdef CONFIG_X86_32
-# define Elf_Shdr Elf32_Shdr
-# define Elf_Sym Elf32_Sym
-# define Elf_Ehdr Elf32_Ehdr
-#else
-# define Elf_Shdr Elf64_Shdr
-# define Elf_Sym Elf64_Sym
-# define Elf_Ehdr Elf64_Ehdr
-#endif
+#include <asm-generic/module.h>
 
 #ifdef CONFIG_X86_64
 /* X86_64 does not define MODULE_PROC_FAMILY */
@@ -28,6 +17,8 @@ struct mod_arch_specific {};
 #define MODULE_PROC_FAMILY "586MMX "
 #elif defined CONFIG_MCORE2
 #define MODULE_PROC_FAMILY "CORE2 "
+#elif defined CONFIG_MATOM
+#define MODULE_PROC_FAMILY "ATOM "
 #elif defined CONFIG_M686
 #define MODULE_PROC_FAMILY "686 "
 #elif defined CONFIG_MPENTIUMII
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index e2a1bb6..79c9450 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 
 #include <asm/mpspec_def.h>
+#include <asm/x86_init.h>
 
 extern int apic_version[MAX_APICS];
 extern int pic_mode;
@@ -41,9 +42,6 @@ extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 
 #endif /* CONFIG_X86_64 */
 
-extern void early_find_smp_config(void);
-extern void early_get_smp_config(void);
-
 #if defined(CONFIG_MCA) || defined(CONFIG_EISA)
 extern int mp_bus_id_to_type[MAX_MP_BUSSES];
 #endif
@@ -52,20 +50,55 @@ extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
 
 extern unsigned int boot_cpu_physical_apicid;
 extern unsigned int max_physical_apicid;
-extern int smp_found_config;
 extern int mpc_default_type;
 extern unsigned long mp_lapic_addr;
 
-extern void get_smp_config(void);
+#ifdef CONFIG_X86_LOCAL_APIC
+extern int smp_found_config;
+#else
+# define smp_found_config 0
+#endif
+
+static inline void get_smp_config(void)
+{
+	x86_init.mpparse.get_smp_config(0);
+}
+
+static inline void early_get_smp_config(void)
+{
+	x86_init.mpparse.get_smp_config(1);
+}
+
+static inline void find_smp_config(void)
+{
+	x86_init.mpparse.find_smp_config(1);
+}
+
+static inline void early_find_smp_config(void)
+{
+	x86_init.mpparse.find_smp_config(0);
+}
 
 #ifdef CONFIG_X86_MPPARSE
-extern void find_smp_config(void);
 extern void early_reserve_e820_mpc_new(void);
 extern int enable_update_mptable;
+extern int default_mpc_apic_id(struct mpc_cpu *m);
+extern void default_smp_read_mpc_oem(struct mpc_table *mpc);
+# ifdef CONFIG_X86_IO_APIC
+extern void default_mpc_oem_bus_info(struct mpc_bus *m, char *str);
+# else
+#  define default_mpc_oem_bus_info NULL
+# endif
+extern void default_find_smp_config(unsigned int reserve);
+extern void default_get_smp_config(unsigned int early);
 #else
-static inline void find_smp_config(void) { }
 static inline void early_reserve_e820_mpc_new(void) { }
 #define enable_update_mptable 0
+#define default_mpc_apic_id NULL
+#define default_smp_read_mpc_oem NULL
+#define default_mpc_oem_bus_info NULL
+#define default_find_smp_config x86_init_uint_noop
+#define default_get_smp_config x86_init_uint_noop
 #endif
 
 void __cpuinit generic_processor_info(int apicid, int version);
diff --git a/arch/x86/include/asm/msgbuf.h b/arch/x86/include/asm/msgbuf.h
index 7e4e948..809134c 100644
--- a/arch/x86/include/asm/msgbuf.h
+++ b/arch/x86/include/asm/msgbuf.h
@@ -1,39 +1 @@
-#ifndef _ASM_X86_MSGBUF_H
-#define _ASM_X86_MSGBUF_H
-
-/*
- * The msqid64_ds structure for i386 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space on i386 is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- *
- * Pad space on x8664 is left for:
- * - 2 miscellaneous 64-bit values
- */
-struct msqid64_ds {
-	struct ipc64_perm msg_perm;
-	__kernel_time_t msg_stime;	/* last msgsnd time */
-#ifdef __i386__
-	unsigned long	__unused1;
-#endif
-	__kernel_time_t msg_rtime;	/* last msgrcv time */
-#ifdef __i386__
-	unsigned long	__unused2;
-#endif
-	__kernel_time_t msg_ctime;	/* last change time */
-#ifdef __i386__
-	unsigned long	__unused3;
-#endif
-	unsigned long  msg_cbytes;	/* current number of bytes on queue */
-	unsigned long  msg_qnum;	/* number of messages in queue */
-	unsigned long  msg_qbytes;	/* max number of bytes on queue */
-	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */
-	__kernel_pid_t msg_lrpid;	/* last receive pid */
-	unsigned long  __unused4;
-	unsigned long  __unused5;
-};
-
-#endif /* _ASM_X86_MSGBUF_H */
+#include <asm-generic/msgbuf.h>
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6be7fc2..4ffe09b 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -81,8 +81,15 @@
 #define MSR_IA32_MC0_ADDR		0x00000402
 #define MSR_IA32_MC0_MISC		0x00000403
 
+#define MSR_IA32_MCx_CTL(x)		(MSR_IA32_MC0_CTL + 4*(x))
+#define MSR_IA32_MCx_STATUS(x)		(MSR_IA32_MC0_STATUS + 4*(x))
+#define MSR_IA32_MCx_ADDR(x)		(MSR_IA32_MC0_ADDR + 4*(x))
+#define MSR_IA32_MCx_MISC(x)		(MSR_IA32_MC0_MISC + 4*(x))
+
 /* These are consecutive and not in the normal 4er MCE bank block */
 #define MSR_IA32_MC0_CTL2		0x00000280
+#define MSR_IA32_MCx_CTL2(x)		(MSR_IA32_MC0_CTL2 + (x))
+
 #define CMCI_EN			(1ULL << 30)
 #define CMCI_THRESHOLD_MASK		0xffffULL
 
@@ -215,6 +222,10 @@
 
 #define THERM_STATUS_PROCHOT		(1 << 0)
 
+#define MSR_THERM2_CTL			0x0000019d
+
+#define MSR_THERM2_CTL_TM_SELECT	(1ULL << 16)
+
 #define MSR_IA32_MISC_ENABLE		0x000001a0
 
 /* MISC_ENABLE bits: architectural */
@@ -374,6 +385,7 @@
 /* AMD-V MSRs */
 
 #define MSR_VM_CR                       0xc0010114
+#define MSR_VM_IGNNE                    0xc0010115
 #define MSR_VM_HSAVE_PA                 0xc0010117
 
 #endif /* _ASM_X86_MSR_INDEX_H */
diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
index 48ad9d2..7e2b6ba 100644
--- a/arch/x86/include/asm/msr.h
+++ b/arch/x86/include/asm/msr.h
@@ -3,10 +3,16 @@
 
 #include <asm/msr-index.h>
 
-#ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define X86_IOC_RDMSR_REGS	_IOWR('c', 0xA0, __u32[8])
+#define X86_IOC_WRMSR_REGS	_IOWR('c', 0xA1, __u32[8])
+
+#ifdef __KERNEL__
+
 #include <asm/asm.h>
 #include <asm/errno.h>
 #include <asm/cpumask.h>
@@ -67,23 +73,7 @@ static inline unsigned long long native_read_msr_safe(unsigned int msr,
 		     ".previous\n\t"
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=r" (*err), EAX_EDX_RET(val, low, high)
-		     : "c" (msr), [fault] "i" (-EFAULT));
-	return EAX_EDX_VAL(val, low, high);
-}
-
-static inline unsigned long long native_read_msr_amd_safe(unsigned int msr,
-						      int *err)
-{
-	DECLARE_ARGS(val, low, high);
-
-	asm volatile("2: rdmsr ; xor %0,%0\n"
-		     "1:\n\t"
-		     ".section .fixup,\"ax\"\n\t"
-		     "3:  mov %3,%0 ; jmp 1b\n\t"
-		     ".previous\n\t"
-		     _ASM_EXTABLE(2b, 3b)
-		     : "=r" (*err), EAX_EDX_RET(val, low, high)
-		     : "c" (msr), "D" (0x9c5a203a), "i" (-EFAULT));
+		     : "c" (msr), [fault] "i" (-EIO));
 	return EAX_EDX_VAL(val, low, high);
 }
 
@@ -106,13 +96,16 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
 		     _ASM_EXTABLE(2b, 3b)
 		     : [err] "=a" (err)
 		     : "c" (msr), "0" (low), "d" (high),
-		       [fault] "i" (-EFAULT)
+		       [fault] "i" (-EIO)
 		     : "memory");
 	return err;
 }
 
 extern unsigned long long native_read_tsc(void);
 
+extern int native_rdmsr_safe_regs(u32 regs[8]);
+extern int native_wrmsr_safe_regs(u32 regs[8]);
+
 static __always_inline unsigned long long __native_read_tsc(void)
 {
 	DECLARE_ARGS(val, low, high);
@@ -181,14 +174,44 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 	*p = native_read_msr_safe(msr, &err);
 	return err;
 }
+
 static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
 {
+	u32 gprs[8] = { 0 };
 	int err;
 
-	*p = native_read_msr_amd_safe(msr, &err);
+	gprs[1] = msr;
+	gprs[7] = 0x9c5a203a;
+
+	err = native_rdmsr_safe_regs(gprs);
+
+	*p = gprs[0] | ((u64)gprs[2] << 32);
+
 	return err;
 }
 
+static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
+{
+	u32 gprs[8] = { 0 };
+
+	gprs[0] = (u32)val;
+	gprs[1] = msr;
+	gprs[2] = val >> 32;
+	gprs[7] = 0x9c5a203a;
+
+	return native_wrmsr_safe_regs(gprs);
+}
+
+static inline int rdmsr_safe_regs(u32 regs[8])
+{
+	return native_rdmsr_safe_regs(regs);
+}
+
+static inline int wrmsr_safe_regs(u32 regs[8])
+{
+	return native_wrmsr_safe_regs(regs);
+}
+
 #define rdtscl(low)						\
 	((low) = (u32)__native_read_tsc())
 
@@ -228,6 +251,8 @@ void rdmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
 void wrmsr_on_cpus(const cpumask_t *mask, u32 msr_no, struct msr *msrs);
 int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
 int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
 #else  /*  CONFIG_SMP  */
 static inline int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
 {
@@ -258,7 +283,15 @@ static inline int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 {
 	return wrmsr_safe(msr_no, l, h);
 }
+static inline int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
+{
+	return rdmsr_safe_regs(regs);
+}
+static inline int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8])
+{
+	return wrmsr_safe_regs(regs);
+}
 #endif  /* CONFIG_SMP */
-#endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
 #endif /* _ASM_X86_MSR_H */
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index a51ada8..4365ffd 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -121,6 +121,9 @@ extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
 extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
 extern void mtrr_ap_init(void);
 extern void mtrr_bp_init(void);
+extern void set_mtrr_aps_delayed_init(void);
+extern void mtrr_aps_init(void);
+extern void mtrr_bp_restore(void);
 extern int mtrr_trim_uncached_memory(unsigned long end_pfn);
 extern int amd_special_default_mtrr(void);
 #  else
@@ -161,6 +164,9 @@ static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
 
 #define mtrr_ap_init() do {} while (0)
 #define mtrr_bp_init() do {} while (0)
+#define set_mtrr_aps_delayed_init() do {} while (0)
+#define mtrr_aps_init() do {} while (0)
+#define mtrr_bp_restore() do {} while (0)
 #  endif
 
 #ifdef CONFIG_COMPAT
diff --git a/arch/x86/include/asm/nops.h b/arch/x86/include/asm/nops.h
index ad2668e..6d8723a 100644
--- a/arch/x86/include/asm/nops.h
+++ b/arch/x86/include/asm/nops.h
@@ -65,6 +65,8 @@
    6: osp nopl 0x00(%eax,%eax,1)
    7: nopl 0x00000000(%eax)
    8: nopl 0x00000000(%eax,%eax,1)
+   Note: All the above are assumed to be a single instruction.
+	There is kernel code that depends on this.
 */
 #define P6_NOP1	GENERIC_NOP1
 #define P6_NOP2	".byte 0x66,0x90\n"
diff --git a/arch/x86/include/asm/param.h b/arch/x86/include/asm/param.h
index 6f0d042..965d454 100644
--- a/arch/x86/include/asm/param.h
+++ b/arch/x86/include/asm/param.h
@@ -1,22 +1 @@
-#ifndef _ASM_X86_PARAM_H
-#define _ASM_X86_PARAM_H
-
-#ifdef __KERNEL__
-# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
-# define USER_HZ	100		/* some user interfaces are */
-# define CLOCKS_PER_SEC	(USER_HZ)       /* in "ticks" like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE	4096
-
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
-
-#endif /* _ASM_X86_PARAM_H */
+#include <asm-generic/param.h>
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 4fb37c8..8aebcc4 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -7,689 +7,11 @@
 #include <asm/pgtable_types.h>
 #include <asm/asm.h>
 
-/* Bitmask of what can be clobbered: usually at least eax. */
-#define CLBR_NONE 0
-#define CLBR_EAX  (1 << 0)
-#define CLBR_ECX  (1 << 1)
-#define CLBR_EDX  (1 << 2)
-#define CLBR_EDI  (1 << 3)
-
-#ifdef CONFIG_X86_32
-/* CLBR_ANY should match all regs platform has. For i386, that's just it */
-#define CLBR_ANY  ((1 << 4) - 1)
-
-#define CLBR_ARG_REGS	(CLBR_EAX | CLBR_EDX | CLBR_ECX)
-#define CLBR_RET_REG	(CLBR_EAX | CLBR_EDX)
-#define CLBR_SCRATCH	(0)
-#else
-#define CLBR_RAX  CLBR_EAX
-#define CLBR_RCX  CLBR_ECX
-#define CLBR_RDX  CLBR_EDX
-#define CLBR_RDI  CLBR_EDI
-#define CLBR_RSI  (1 << 4)
-#define CLBR_R8   (1 << 5)
-#define CLBR_R9   (1 << 6)
-#define CLBR_R10  (1 << 7)
-#define CLBR_R11  (1 << 8)
-
-#define CLBR_ANY  ((1 << 9) - 1)
-
-#define CLBR_ARG_REGS	(CLBR_RDI | CLBR_RSI | CLBR_RDX | \
-			 CLBR_RCX | CLBR_R8 | CLBR_R9)
-#define CLBR_RET_REG	(CLBR_RAX)
-#define CLBR_SCRATCH	(CLBR_R10 | CLBR_R11)
-
-#include <asm/desc_defs.h>
-#endif /* X86_64 */
-
-#define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG)
+#include <asm/paravirt_types.h>
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
 #include <linux/cpumask.h>
-#include <asm/kmap_types.h>
-#include <asm/desc_defs.h>
-
-struct page;
-struct thread_struct;
-struct desc_ptr;
-struct tss_struct;
-struct mm_struct;
-struct desc_struct;
-struct task_struct;
-
-/*
- * Wrapper type for pointers to code which uses the non-standard
- * calling convention.  See PV_CALL_SAVE_REGS_THUNK below.
- */
-struct paravirt_callee_save {
-	void *func;
-};
-
-/* general info */
-struct pv_info {
-	unsigned int kernel_rpl;
-	int shared_kernel_pmd;
-	int paravirt_enabled;
-	const char *name;
-};
-
-struct pv_init_ops {
-	/*
-	 * Patch may replace one of the defined code sequences with
-	 * arbitrary code, subject to the same register constraints.
-	 * This generally means the code is not free to clobber any
-	 * registers other than EAX.  The patch function should return
-	 * the number of bytes of code generated, as we nop pad the
-	 * rest in generic code.
-	 */
-	unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
-			  unsigned long addr, unsigned len);
-
-	/* Basic arch-specific setup */
-	void (*arch_setup)(void);
-	char *(*memory_setup)(void);
-	void (*post_allocator_init)(void);
-
-	/* Print a banner to identify the environment */
-	void (*banner)(void);
-};
-
-
-struct pv_lazy_ops {
-	/* Set deferred update mode, used for batching operations. */
-	void (*enter)(void);
-	void (*leave)(void);
-};
-
-struct pv_time_ops {
-	void (*time_init)(void);
-
-	/* Set and set time of day */
-	unsigned long (*get_wallclock)(void);
-	int (*set_wallclock)(unsigned long);
-
-	unsigned long long (*sched_clock)(void);
-	unsigned long (*get_tsc_khz)(void);
-};
-
-struct pv_cpu_ops {
-	/* hooks for various privileged instructions */
-	unsigned long (*get_debugreg)(int regno);
-	void (*set_debugreg)(int regno, unsigned long value);
-
-	void (*clts)(void);
-
-	unsigned long (*read_cr0)(void);
-	void (*write_cr0)(unsigned long);
-
-	unsigned long (*read_cr4_safe)(void);
-	unsigned long (*read_cr4)(void);
-	void (*write_cr4)(unsigned long);
-
-#ifdef CONFIG_X86_64
-	unsigned long (*read_cr8)(void);
-	void (*write_cr8)(unsigned long);
-#endif
-
-	/* Segment descriptor handling */
-	void (*load_tr_desc)(void);
-	void (*load_gdt)(const struct desc_ptr *);
-	void (*load_idt)(const struct desc_ptr *);
-	void (*store_gdt)(struct desc_ptr *);
-	void (*store_idt)(struct desc_ptr *);
-	void (*set_ldt)(const void *desc, unsigned entries);
-	unsigned long (*store_tr)(void);
-	void (*load_tls)(struct thread_struct *t, unsigned int cpu);
-#ifdef CONFIG_X86_64
-	void (*load_gs_index)(unsigned int idx);
-#endif
-	void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum,
-				const void *desc);
-	void (*write_gdt_entry)(struct desc_struct *,
-				int entrynum, const void *desc, int size);
-	void (*write_idt_entry)(gate_desc *,
-				int entrynum, const gate_desc *gate);
-	void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries);
-	void (*free_ldt)(struct desc_struct *ldt, unsigned entries);
-
-	void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t);
-
-	void (*set_iopl_mask)(unsigned mask);
-
-	void (*wbinvd)(void);
-	void (*io_delay)(void);
-
-	/* cpuid emulation, mostly so that caps bits can be disabled */
-	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
-		      unsigned int *ecx, unsigned int *edx);
-
-	/* MSR, PMC and TSR operations.
-	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-	u64 (*read_msr_amd)(unsigned int msr, int *err);
-	u64 (*read_msr)(unsigned int msr, int *err);
-	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
-
-	u64 (*read_tsc)(void);
-	u64 (*read_pmc)(int counter);
-	unsigned long long (*read_tscp)(unsigned int *aux);
-
-	/*
-	 * Atomically enable interrupts and return to userspace.  This
-	 * is only ever used to return to 32-bit processes; in a
-	 * 64-bit kernel, it's used for 32-on-64 compat processes, but
-	 * never native 64-bit processes.  (Jump, not call.)
-	 */
-	void (*irq_enable_sysexit)(void);
-
-	/*
-	 * Switch to usermode gs and return to 64-bit usermode using
-	 * sysret.  Only used in 64-bit kernels to return to 64-bit
-	 * processes.  Usermode register state, including %rsp, must
-	 * already be restored.
-	 */
-	void (*usergs_sysret64)(void);
-
-	/*
-	 * Switch to usermode gs and return to 32-bit usermode using
-	 * sysret.  Used to return to 32-on-64 compat processes.
-	 * Other usermode register state, including %esp, must already
-	 * be restored.
-	 */
-	void (*usergs_sysret32)(void);
-
-	/* Normal iret.  Jump to this with the standard iret stack
-	   frame set up. */
-	void (*iret)(void);
-
-	void (*swapgs)(void);
-
-	void (*start_context_switch)(struct task_struct *prev);
-	void (*end_context_switch)(struct task_struct *next);
-};
-
-struct pv_irq_ops {
-	void (*init_IRQ)(void);
-
-	/*
-	 * Get/set interrupt state.  save_fl and restore_fl are only
-	 * expected to use X86_EFLAGS_IF; all other bits
-	 * returned from save_fl are undefined, and may be ignored by
-	 * restore_fl.
-	 *
-	 * NOTE: These functions callers expect the callee to preserve
-	 * more registers than the standard C calling convention.
-	 */
-	struct paravirt_callee_save save_fl;
-	struct paravirt_callee_save restore_fl;
-	struct paravirt_callee_save irq_disable;
-	struct paravirt_callee_save irq_enable;
-
-	void (*safe_halt)(void);
-	void (*halt)(void);
-
-#ifdef CONFIG_X86_64
-	void (*adjust_exception_frame)(void);
-#endif
-};
-
-struct pv_apic_ops {
-#ifdef CONFIG_X86_LOCAL_APIC
-	void (*setup_boot_clock)(void);
-	void (*setup_secondary_clock)(void);
-
-	void (*startup_ipi_hook)(int phys_apicid,
-				 unsigned long start_eip,
-				 unsigned long start_esp);
-#endif
-};
-
-struct pv_mmu_ops {
-	/*
-	 * Called before/after init_mm pagetable setup. setup_start
-	 * may reset %cr3, and may pre-install parts of the pagetable;
-	 * pagetable setup is expected to preserve any existing
-	 * mapping.
-	 */
-	void (*pagetable_setup_start)(pgd_t *pgd_base);
-	void (*pagetable_setup_done)(pgd_t *pgd_base);
-
-	unsigned long (*read_cr2)(void);
-	void (*write_cr2)(unsigned long);
-
-	unsigned long (*read_cr3)(void);
-	void (*write_cr3)(unsigned long);
-
-	/*
-	 * Hooks for intercepting the creation/use/destruction of an
-	 * mm_struct.
-	 */
-	void (*activate_mm)(struct mm_struct *prev,
-			    struct mm_struct *next);
-	void (*dup_mmap)(struct mm_struct *oldmm,
-			 struct mm_struct *mm);
-	void (*exit_mmap)(struct mm_struct *mm);
-
-
-	/* TLB operations */
-	void (*flush_tlb_user)(void);
-	void (*flush_tlb_kernel)(void);
-	void (*flush_tlb_single)(unsigned long addr);
-	void (*flush_tlb_others)(const struct cpumask *cpus,
-				 struct mm_struct *mm,
-				 unsigned long va);
-
-	/* Hooks for allocating and freeing a pagetable top-level */
-	int  (*pgd_alloc)(struct mm_struct *mm);
-	void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd);
-
-	/*
-	 * Hooks for allocating/releasing pagetable pages when they're
-	 * attached to a pagetable
-	 */
-	void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
-	void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
-	void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
-	void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
-	void (*release_pte)(unsigned long pfn);
-	void (*release_pmd)(unsigned long pfn);
-	void (*release_pud)(unsigned long pfn);
-
-	/* Pagetable manipulation functions */
-	void (*set_pte)(pte_t *ptep, pte_t pteval);
-	void (*set_pte_at)(struct mm_struct *mm, unsigned long addr,
-			   pte_t *ptep, pte_t pteval);
-	void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval);
-	void (*pte_update)(struct mm_struct *mm, unsigned long addr,
-			   pte_t *ptep);
-	void (*pte_update_defer)(struct mm_struct *mm,
-				 unsigned long addr, pte_t *ptep);
-
-	pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr,
-					pte_t *ptep);
-	void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr,
-					pte_t *ptep, pte_t pte);
-
-	struct paravirt_callee_save pte_val;
-	struct paravirt_callee_save make_pte;
-
-	struct paravirt_callee_save pgd_val;
-	struct paravirt_callee_save make_pgd;
-
-#if PAGETABLE_LEVELS >= 3
-#ifdef CONFIG_X86_PAE
-	void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
-	void (*pte_clear)(struct mm_struct *mm, unsigned long addr,
-			  pte_t *ptep);
-	void (*pmd_clear)(pmd_t *pmdp);
-
-#endif	/* CONFIG_X86_PAE */
-
-	void (*set_pud)(pud_t *pudp, pud_t pudval);
-
-	struct paravirt_callee_save pmd_val;
-	struct paravirt_callee_save make_pmd;
-
-#if PAGETABLE_LEVELS == 4
-	struct paravirt_callee_save pud_val;
-	struct paravirt_callee_save make_pud;
-
-	void (*set_pgd)(pgd_t *pudp, pgd_t pgdval);
-#endif	/* PAGETABLE_LEVELS == 4 */
-#endif	/* PAGETABLE_LEVELS >= 3 */
-
-#ifdef CONFIG_HIGHPTE
-	void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
-#endif
-
-	struct pv_lazy_ops lazy_mode;
-
-	/* dom0 ops */
-
-	/* Sometimes the physical address is a pfn, and sometimes its
-	   an mfn.  We can tell which is which from the index. */
-	void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
-			   phys_addr_t phys, pgprot_t flags);
-};
-
-struct raw_spinlock;
-struct pv_lock_ops {
-	int (*spin_is_locked)(struct raw_spinlock *lock);
-	int (*spin_is_contended)(struct raw_spinlock *lock);
-	void (*spin_lock)(struct raw_spinlock *lock);
-	void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags);
-	int (*spin_trylock)(struct raw_spinlock *lock);
-	void (*spin_unlock)(struct raw_spinlock *lock);
-};
-
-/* This contains all the paravirt structures: we get a convenient
- * number for each function using the offset which we use to indicate
- * what to patch. */
-struct paravirt_patch_template {
-	struct pv_init_ops pv_init_ops;
-	struct pv_time_ops pv_time_ops;
-	struct pv_cpu_ops pv_cpu_ops;
-	struct pv_irq_ops pv_irq_ops;
-	struct pv_apic_ops pv_apic_ops;
-	struct pv_mmu_ops pv_mmu_ops;
-	struct pv_lock_ops pv_lock_ops;
-};
-
-extern struct pv_info pv_info;
-extern struct pv_init_ops pv_init_ops;
-extern struct pv_time_ops pv_time_ops;
-extern struct pv_cpu_ops pv_cpu_ops;
-extern struct pv_irq_ops pv_irq_ops;
-extern struct pv_apic_ops pv_apic_ops;
-extern struct pv_mmu_ops pv_mmu_ops;
-extern struct pv_lock_ops pv_lock_ops;
-
-#define PARAVIRT_PATCH(x)					\
-	(offsetof(struct paravirt_patch_template, x) / sizeof(void *))
-
-#define paravirt_type(op)				\
-	[paravirt_typenum] "i" (PARAVIRT_PATCH(op)),	\
-	[paravirt_opptr] "i" (&(op))
-#define paravirt_clobber(clobber)		\
-	[paravirt_clobber] "i" (clobber)
-
-/*
- * Generate some code, and mark it as patchable by the
- * apply_paravirt() alternate instruction patcher.
- */
-#define _paravirt_alt(insn_string, type, clobber)	\
-	"771:\n\t" insn_string "\n" "772:\n"		\
-	".pushsection .parainstructions,\"a\"\n"	\
-	_ASM_ALIGN "\n"					\
-	_ASM_PTR " 771b\n"				\
-	"  .byte " type "\n"				\
-	"  .byte 772b-771b\n"				\
-	"  .short " clobber "\n"			\
-	".popsection\n"
-
-/* Generate patchable code, with the default asm parameters. */
-#define paravirt_alt(insn_string)					\
-	_paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
-
-/* Simple instruction patching code. */
-#define DEF_NATIVE(ops, name, code) 					\
-	extern const char start_##ops##_##name[], end_##ops##_##name[];	\
-	asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
-
-unsigned paravirt_patch_nop(void);
-unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
-unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
-unsigned paravirt_patch_ignore(unsigned len);
-unsigned paravirt_patch_call(void *insnbuf,
-			     const void *target, u16 tgt_clobbers,
-			     unsigned long addr, u16 site_clobbers,
-			     unsigned len);
-unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
-			    unsigned long addr, unsigned len);
-unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
-				unsigned long addr, unsigned len);
-
-unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
-			      const char *start, const char *end);
-
-unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
-		      unsigned long addr, unsigned len);
-
-int paravirt_disable_iospace(void);
-
-/*
- * This generates an indirect call based on the operation type number.
- * The type number, computed in PARAVIRT_PATCH, is derived from the
- * offset into the paravirt_patch_template structure, and can therefore be
- * freely converted back into a structure offset.
- */
-#define PARAVIRT_CALL	"call *%c[paravirt_opptr];"
-
-/*
- * These macros are intended to wrap calls through one of the paravirt
- * ops structs, so that they can be later identified and patched at
- * runtime.
- *
- * Normally, a call to a pv_op function is a simple indirect call:
- * (pv_op_struct.operations)(args...).
- *
- * Unfortunately, this is a relatively slow operation for modern CPUs,
- * because it cannot necessarily determine what the destination
- * address is.  In this case, the address is a runtime constant, so at
- * the very least we can patch the call to e a simple direct call, or
- * ideally, patch an inline implementation into the callsite.  (Direct
- * calls are essentially free, because the call and return addresses
- * are completely predictable.)
- *
- * For i386, these macros rely on the standard gcc "regparm(3)" calling
- * convention, in which the first three arguments are placed in %eax,
- * %edx, %ecx (in that order), and the remaining arguments are placed
- * on the stack.  All caller-save registers (eax,edx,ecx) are expected
- * to be modified (either clobbered or used for return values).
- * X86_64, on the other hand, already specifies a register-based calling
- * conventions, returning at %rax, with parameteres going on %rdi, %rsi,
- * %rdx, and %rcx. Note that for this reason, x86_64 does not need any
- * special handling for dealing with 4 arguments, unlike i386.
- * However, x86_64 also have to clobber all caller saved registers, which
- * unfortunately, are quite a bit (r8 - r11)
- *
- * The call instruction itself is marked by placing its start address
- * and size into the .parainstructions section, so that
- * apply_paravirt() in arch/i386/kernel/alternative.c can do the
- * appropriate patching under the control of the backend pv_init_ops
- * implementation.
- *
- * Unfortunately there's no way to get gcc to generate the args setup
- * for the call, and then allow the call itself to be generated by an
- * inline asm.  Because of this, we must do the complete arg setup and
- * return value handling from within these macros.  This is fairly
- * cumbersome.
- *
- * There are 5 sets of PVOP_* macros for dealing with 0-4 arguments.
- * It could be extended to more arguments, but there would be little
- * to be gained from that.  For each number of arguments, there are
- * the two VCALL and CALL variants for void and non-void functions.
- *
- * When there is a return value, the invoker of the macro must specify
- * the return type.  The macro then uses sizeof() on that type to
- * determine whether its a 32 or 64 bit value, and places the return
- * in the right register(s) (just %eax for 32-bit, and %edx:%eax for
- * 64-bit). For x86_64 machines, it just returns at %rax regardless of
- * the return value size.
- *
- * 64-bit arguments are passed as a pair of adjacent 32-bit arguments
- * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments
- * in low,high order
- *
- * Small structures are passed and returned in registers.  The macro
- * calling convention can't directly deal with this, so the wrapper
- * functions must do this.
- *
- * These PVOP_* macros are only defined within this header.  This
- * means that all uses must be wrapped in inline functions.  This also
- * makes sure the incoming and outgoing types are always correct.
- */
-#ifdef CONFIG_X86_32
-#define PVOP_VCALL_ARGS				\
-	unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx
-#define PVOP_CALL_ARGS			PVOP_VCALL_ARGS
-
-#define PVOP_CALL_ARG1(x)		"a" ((unsigned long)(x))
-#define PVOP_CALL_ARG2(x)		"d" ((unsigned long)(x))
-#define PVOP_CALL_ARG3(x)		"c" ((unsigned long)(x))
-
-#define PVOP_VCALL_CLOBBERS		"=a" (__eax), "=d" (__edx),	\
-					"=c" (__ecx)
-#define PVOP_CALL_CLOBBERS		PVOP_VCALL_CLOBBERS
-
-#define PVOP_VCALLEE_CLOBBERS		"=a" (__eax), "=d" (__edx)
-#define PVOP_CALLEE_CLOBBERS		PVOP_VCALLEE_CLOBBERS
-
-#define EXTRA_CLOBBERS
-#define VEXTRA_CLOBBERS
-#else  /* CONFIG_X86_64 */
-#define PVOP_VCALL_ARGS					\
-	unsigned long __edi = __edi, __esi = __esi,	\
-		__edx = __edx, __ecx = __ecx
-#define PVOP_CALL_ARGS		PVOP_VCALL_ARGS, __eax
-
-#define PVOP_CALL_ARG1(x)		"D" ((unsigned long)(x))
-#define PVOP_CALL_ARG2(x)		"S" ((unsigned long)(x))
-#define PVOP_CALL_ARG3(x)		"d" ((unsigned long)(x))
-#define PVOP_CALL_ARG4(x)		"c" ((unsigned long)(x))
-
-#define PVOP_VCALL_CLOBBERS	"=D" (__edi),				\
-				"=S" (__esi), "=d" (__edx),		\
-				"=c" (__ecx)
-#define PVOP_CALL_CLOBBERS	PVOP_VCALL_CLOBBERS, "=a" (__eax)
-
-#define PVOP_VCALLEE_CLOBBERS	"=a" (__eax)
-#define PVOP_CALLEE_CLOBBERS	PVOP_VCALLEE_CLOBBERS
-
-#define EXTRA_CLOBBERS	 , "r8", "r9", "r10", "r11"
-#define VEXTRA_CLOBBERS	 , "rax", "r8", "r9", "r10", "r11"
-#endif	/* CONFIG_X86_32 */
-
-#ifdef CONFIG_PARAVIRT_DEBUG
-#define PVOP_TEST_NULL(op)	BUG_ON(op == NULL)
-#else
-#define PVOP_TEST_NULL(op)	((void)op)
-#endif
-
-#define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr,		\
-		      pre, post, ...)					\
-	({								\
-		rettype __ret;						\
-		PVOP_CALL_ARGS;						\
-		PVOP_TEST_NULL(op);					\
-		/* This is 32-bit specific, but is okay in 64-bit */	\
-		/* since this condition will never hold */		\
-		if (sizeof(rettype) > sizeof(unsigned long)) {		\
-			asm volatile(pre				\
-				     paravirt_alt(PARAVIRT_CALL)	\
-				     post				\
-				     : call_clbr			\
-				     : paravirt_type(op),		\
-				       paravirt_clobber(clbr),		\
-				       ##__VA_ARGS__			\
-				     : "memory", "cc" extra_clbr);	\
-			__ret = (rettype)((((u64)__edx) << 32) | __eax); \
-		} else {						\
-			asm volatile(pre				\
-				     paravirt_alt(PARAVIRT_CALL)	\
-				     post				\
-				     : call_clbr			\
-				     : paravirt_type(op),		\
-				       paravirt_clobber(clbr),		\
-				       ##__VA_ARGS__			\
-				     : "memory", "cc" extra_clbr);	\
-			__ret = (rettype)__eax;				\
-		}							\
-		__ret;							\
-	})
-
-#define __PVOP_CALL(rettype, op, pre, post, ...)			\
-	____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS,	\
-		      EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__)
-
-#define __PVOP_CALLEESAVE(rettype, op, pre, post, ...)			\
-	____PVOP_CALL(rettype, op.func, CLBR_RET_REG,			\
-		      PVOP_CALLEE_CLOBBERS, ,				\
-		      pre, post, ##__VA_ARGS__)
-
-
-#define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...)	\
-	({								\
-		PVOP_VCALL_ARGS;					\
-		PVOP_TEST_NULL(op);					\
-		asm volatile(pre					\
-			     paravirt_alt(PARAVIRT_CALL)		\
-			     post					\
-			     : call_clbr				\
-			     : paravirt_type(op),			\
-			       paravirt_clobber(clbr),			\
-			       ##__VA_ARGS__				\
-			     : "memory", "cc" extra_clbr);		\
-	})
-
-#define __PVOP_VCALL(op, pre, post, ...)				\
-	____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS,		\
-		       VEXTRA_CLOBBERS,					\
-		       pre, post, ##__VA_ARGS__)
-
-#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...)			\
-	____PVOP_CALL(rettype, op.func, CLBR_RET_REG,			\
-		      PVOP_VCALLEE_CLOBBERS, ,				\
-		      pre, post, ##__VA_ARGS__)
-
-
-
-#define PVOP_CALL0(rettype, op)						\
-	__PVOP_CALL(rettype, op, "", "")
-#define PVOP_VCALL0(op)							\
-	__PVOP_VCALL(op, "", "")
-
-#define PVOP_CALLEE0(rettype, op)					\
-	__PVOP_CALLEESAVE(rettype, op, "", "")
-#define PVOP_VCALLEE0(op)						\
-	__PVOP_VCALLEESAVE(op, "", "")
-
-
-#define PVOP_CALL1(rettype, op, arg1)					\
-	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
-#define PVOP_VCALL1(op, arg1)						\
-	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1))
-
-#define PVOP_CALLEE1(rettype, op, arg1)					\
-	__PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
-#define PVOP_VCALLEE1(op, arg1)						\
-	__PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1))
-
-
-#define PVOP_CALL2(rettype, op, arg1, arg2)				\
-	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1),		\
-		    PVOP_CALL_ARG2(arg2))
-#define PVOP_VCALL2(op, arg1, arg2)					\
-	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1),			\
-		     PVOP_CALL_ARG2(arg2))
-
-#define PVOP_CALLEE2(rettype, op, arg1, arg2)				\
-	__PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1),	\
-			  PVOP_CALL_ARG2(arg2))
-#define PVOP_VCALLEE2(op, arg1, arg2)					\
-	__PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1),		\
-			   PVOP_CALL_ARG2(arg2))
-
-
-#define PVOP_CALL3(rettype, op, arg1, arg2, arg3)			\
-	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1),		\
-		    PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
-#define PVOP_VCALL3(op, arg1, arg2, arg3)				\
-	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1),			\
-		     PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
-
-/* This is the only difference in x86_64. We can make it much simpler */
-#ifdef CONFIG_X86_32
-#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4)			\
-	__PVOP_CALL(rettype, op,					\
-		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\
-		    PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),		\
-		    PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4)))
-#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4)				\
-	__PVOP_VCALL(op,						\
-		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\
-		    "0" ((u32)(arg1)), "1" ((u32)(arg2)),		\
-		    "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))
-#else
-#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4)			\
-	__PVOP_CALL(rettype, op, "", "",				\
-		    PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),		\
-		    PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
-#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4)				\
-	__PVOP_VCALL(op, "", "",					\
-		     PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),	\
-		     PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
-#endif
 
 static inline int paravirt_enabled(void)
 {
@@ -702,22 +24,6 @@ static inline void load_sp0(struct tss_struct *tss,
 	PVOP_VCALL2(pv_cpu_ops.load_sp0, tss, thread);
 }
 
-#define ARCH_SETUP			pv_init_ops.arch_setup();
-static inline unsigned long get_wallclock(void)
-{
-	return PVOP_CALL0(unsigned long, pv_time_ops.get_wallclock);
-}
-
-static inline int set_wallclock(unsigned long nowtime)
-{
-	return PVOP_CALL1(int, pv_time_ops.set_wallclock, nowtime);
-}
-
-static inline void (*choose_time_init(void))(void)
-{
-	return pv_time_ops.time_init;
-}
-
 /* The paravirtualized CPUID instruction. */
 static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
 			   unsigned int *ecx, unsigned int *edx)
@@ -820,15 +126,22 @@ static inline u64 paravirt_read_msr(unsigned msr, int *err)
 {
 	return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);
 }
-static inline u64 paravirt_read_msr_amd(unsigned msr, int *err)
+
+static inline int paravirt_rdmsr_regs(u32 *regs)
 {
-	return PVOP_CALL2(u64, pv_cpu_ops.read_msr_amd, msr, err);
+	return PVOP_CALL1(int, pv_cpu_ops.rdmsr_regs, regs);
 }
+
 static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high)
 {
 	return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);
 }
 
+static inline int paravirt_wrmsr_regs(u32 *regs)
+{
+	return PVOP_CALL1(int, pv_cpu_ops.wrmsr_regs, regs);
+}
+
 /* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr, val1, val2)			\
 do {						\
@@ -862,6 +175,9 @@ do {						\
 	_err;					\
 })
 
+#define rdmsr_safe_regs(regs)	paravirt_rdmsr_regs(regs)
+#define wrmsr_safe_regs(regs)	paravirt_wrmsr_regs(regs)
+
 static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 {
 	int err;
@@ -871,12 +187,31 @@ static inline int rdmsrl_safe(unsigned msr, unsigned long long *p)
 }
 static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
 {
+	u32 gprs[8] = { 0 };
 	int err;
 
-	*p = paravirt_read_msr_amd(msr, &err);
+	gprs[1] = msr;
+	gprs[7] = 0x9c5a203a;
+
+	err = paravirt_rdmsr_regs(gprs);
+
+	*p = gprs[0] | ((u64)gprs[2] << 32);
+
 	return err;
 }
 
+static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
+{
+	u32 gprs[8] = { 0 };
+
+	gprs[0] = (u32)val;
+	gprs[1] = msr;
+	gprs[2] = val >> 32;
+	gprs[7] = 0x9c5a203a;
+
+	return paravirt_wrmsr_regs(gprs);
+}
+
 static inline u64 paravirt_read_tsc(void)
 {
 	return PVOP_CALL0(u64, pv_cpu_ops.read_tsc);
@@ -894,7 +229,6 @@ static inline unsigned long long paravirt_sched_clock(void)
 {
 	return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);
 }
-#define calibrate_tsc() (pv_time_ops.get_tsc_khz())
 
 static inline unsigned long long paravirt_read_pmc(int counter)
 {
@@ -1012,34 +346,6 @@ static inline void slow_down_io(void)
 #endif
 }
 
-#ifdef CONFIG_X86_LOCAL_APIC
-static inline void setup_boot_clock(void)
-{
-	PVOP_VCALL0(pv_apic_ops.setup_boot_clock);
-}
-
-static inline void setup_secondary_clock(void)
-{
-	PVOP_VCALL0(pv_apic_ops.setup_secondary_clock);
-}
-#endif
-
-static inline void paravirt_post_allocator_init(void)
-{
-	if (pv_init_ops.post_allocator_init)
-		(*pv_init_ops.post_allocator_init)();
-}
-
-static inline void paravirt_pagetable_setup_start(pgd_t *base)
-{
-	(*pv_mmu_ops.pagetable_setup_start)(base);
-}
-
-static inline void paravirt_pagetable_setup_done(pgd_t *base)
-{
-	(*pv_mmu_ops.pagetable_setup_done)(base);
-}
-
 #ifdef CONFIG_SMP
 static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
 				    unsigned long start_esp)
@@ -1393,20 +699,6 @@ static inline void pmd_clear(pmd_t *pmdp)
 }
 #endif	/* CONFIG_X86_PAE */
 
-/* Lazy mode for batching updates / context switch */
-enum paravirt_lazy_mode {
-	PARAVIRT_LAZY_NONE,
-	PARAVIRT_LAZY_MMU,
-	PARAVIRT_LAZY_CPU,
-};
-
-enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
-void paravirt_start_context_switch(struct task_struct *prev);
-void paravirt_end_context_switch(struct task_struct *next);
-
-void paravirt_enter_lazy_mmu(void);
-void paravirt_leave_lazy_mmu(void);
-
 #define  __HAVE_ARCH_START_CONTEXT_SWITCH
 static inline void arch_start_context_switch(struct task_struct *prev)
 {
@@ -1437,12 +729,6 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
 	pv_mmu_ops.set_fixmap(idx, phys, flags);
 }
 
-void _paravirt_nop(void);
-u32 _paravirt_ident_32(u32);
-u64 _paravirt_ident_64(u64);
-
-#define paravirt_nop	((void *)_paravirt_nop)
-
 #if defined(CONFIG_SMP) && defined(CONFIG_PARAVIRT_SPINLOCKS)
 
 static inline int __raw_spin_is_locked(struct raw_spinlock *lock)
@@ -1479,17 +765,6 @@ static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
 
 #endif
 
-/* These all sit in the .parainstructions section to tell us what to patch. */
-struct paravirt_patch_site {
-	u8 *instr; 		/* original instructions */
-	u8 instrtype;		/* type of this instruction */
-	u8 len;			/* length of original instruction */
-	u16 clobbers;		/* what registers you may clobber */
-};
-
-extern struct paravirt_patch_site __parainstructions[],
-	__parainstructions_end[];
-
 #ifdef CONFIG_X86_32
 #define PV_SAVE_REGS "pushl %ecx; pushl %edx;"
 #define PV_RESTORE_REGS "popl %edx; popl %ecx;"
@@ -1628,6 +903,8 @@ static inline unsigned long __raw_local_irq_save(void)
 #undef PVOP_VCALL4
 #undef PVOP_CALL4
 
+extern void default_banner(void);
+
 #else  /* __ASSEMBLY__ */
 
 #define _PVSITE(ptype, clobbers, ops, word, algn)	\
@@ -1768,5 +1045,7 @@ static inline unsigned long __raw_local_irq_save(void)
 #endif	/* CONFIG_X86_32 */
 
 #endif /* __ASSEMBLY__ */
-#endif /* CONFIG_PARAVIRT */
+#else  /* CONFIG_PARAVIRT */
+# define default_banner x86_init_noop
+#endif /* !CONFIG_PARAVIRT */
 #endif /* _ASM_X86_PARAVIRT_H */
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
new file mode 100644
index 0000000..dd0f5b3
--- /dev/null
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -0,0 +1,693 @@
+#ifndef _ASM_X86_PARAVIRT_TYPES_H
+#define _ASM_X86_PARAVIRT_TYPES_H
+
+/* Bitmask of what can be clobbered: usually at least eax. */
+#define CLBR_NONE 0
+#define CLBR_EAX  (1 << 0)
+#define CLBR_ECX  (1 << 1)
+#define CLBR_EDX  (1 << 2)
+#define CLBR_EDI  (1 << 3)
+
+#ifdef CONFIG_X86_32
+/* CLBR_ANY should match all regs platform has. For i386, that's just it */
+#define CLBR_ANY  ((1 << 4) - 1)
+
+#define CLBR_ARG_REGS	(CLBR_EAX | CLBR_EDX | CLBR_ECX)
+#define CLBR_RET_REG	(CLBR_EAX | CLBR_EDX)
+#define CLBR_SCRATCH	(0)
+#else
+#define CLBR_RAX  CLBR_EAX
+#define CLBR_RCX  CLBR_ECX
+#define CLBR_RDX  CLBR_EDX
+#define CLBR_RDI  CLBR_EDI
+#define CLBR_RSI  (1 << 4)
+#define CLBR_R8   (1 << 5)
+#define CLBR_R9   (1 << 6)
+#define CLBR_R10  (1 << 7)
+#define CLBR_R11  (1 << 8)
+
+#define CLBR_ANY  ((1 << 9) - 1)
+
+#define CLBR_ARG_REGS	(CLBR_RDI | CLBR_RSI | CLBR_RDX | \
+			 CLBR_RCX | CLBR_R8 | CLBR_R9)
+#define CLBR_RET_REG	(CLBR_RAX)
+#define CLBR_SCRATCH	(CLBR_R10 | CLBR_R11)
+
+#endif /* X86_64 */
+
+#define CLBR_CALLEE_SAVE ((CLBR_ARG_REGS | CLBR_SCRATCH) & ~CLBR_RET_REG)
+
+#ifndef __ASSEMBLY__
+
+#include <asm/desc_defs.h>
+#include <asm/kmap_types.h>
+
+struct page;
+struct thread_struct;
+struct desc_ptr;
+struct tss_struct;
+struct mm_struct;
+struct desc_struct;
+struct task_struct;
+struct cpumask;
+
+/*
+ * Wrapper type for pointers to code which uses the non-standard
+ * calling convention.  See PV_CALL_SAVE_REGS_THUNK below.
+ */
+struct paravirt_callee_save {
+	void *func;
+};
+
+/* general info */
+struct pv_info {
+	unsigned int kernel_rpl;
+	int shared_kernel_pmd;
+	int paravirt_enabled;
+	const char *name;
+};
+
+struct pv_init_ops {
+	/*
+	 * Patch may replace one of the defined code sequences with
+	 * arbitrary code, subject to the same register constraints.
+	 * This generally means the code is not free to clobber any
+	 * registers other than EAX.  The patch function should return
+	 * the number of bytes of code generated, as we nop pad the
+	 * rest in generic code.
+	 */
+	unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
+			  unsigned long addr, unsigned len);
+};
+
+
+struct pv_lazy_ops {
+	/* Set deferred update mode, used for batching operations. */
+	void (*enter)(void);
+	void (*leave)(void);
+};
+
+struct pv_time_ops {
+	unsigned long long (*sched_clock)(void);
+	unsigned long (*get_tsc_khz)(void);
+};
+
+struct pv_cpu_ops {
+	/* hooks for various privileged instructions */
+	unsigned long (*get_debugreg)(int regno);
+	void (*set_debugreg)(int regno, unsigned long value);
+
+	void (*clts)(void);
+
+	unsigned long (*read_cr0)(void);
+	void (*write_cr0)(unsigned long);
+
+	unsigned long (*read_cr4_safe)(void);
+	unsigned long (*read_cr4)(void);
+	void (*write_cr4)(unsigned long);
+
+#ifdef CONFIG_X86_64
+	unsigned long (*read_cr8)(void);
+	void (*write_cr8)(unsigned long);
+#endif
+
+	/* Segment descriptor handling */
+	void (*load_tr_desc)(void);
+	void (*load_gdt)(const struct desc_ptr *);
+	void (*load_idt)(const struct desc_ptr *);
+	void (*store_gdt)(struct desc_ptr *);
+	void (*store_idt)(struct desc_ptr *);
+	void (*set_ldt)(const void *desc, unsigned entries);
+	unsigned long (*store_tr)(void);
+	void (*load_tls)(struct thread_struct *t, unsigned int cpu);
+#ifdef CONFIG_X86_64
+	void (*load_gs_index)(unsigned int idx);
+#endif
+	void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum,
+				const void *desc);
+	void (*write_gdt_entry)(struct desc_struct *,
+				int entrynum, const void *desc, int size);
+	void (*write_idt_entry)(gate_desc *,
+				int entrynum, const gate_desc *gate);
+	void (*alloc_ldt)(struct desc_struct *ldt, unsigned entries);
+	void (*free_ldt)(struct desc_struct *ldt, unsigned entries);
+
+	void (*load_sp0)(struct tss_struct *tss, struct thread_struct *t);
+
+	void (*set_iopl_mask)(unsigned mask);
+
+	void (*wbinvd)(void);
+	void (*io_delay)(void);
+
+	/* cpuid emulation, mostly so that caps bits can be disabled */
+	void (*cpuid)(unsigned int *eax, unsigned int *ebx,
+		      unsigned int *ecx, unsigned int *edx);
+
+	/* MSR, PMC and TSR operations.
+	   err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
+	u64 (*read_msr)(unsigned int msr, int *err);
+	int (*rdmsr_regs)(u32 *regs);
+	int (*write_msr)(unsigned int msr, unsigned low, unsigned high);
+	int (*wrmsr_regs)(u32 *regs);
+
+	u64 (*read_tsc)(void);
+	u64 (*read_pmc)(int counter);
+	unsigned long long (*read_tscp)(unsigned int *aux);
+
+	/*
+	 * Atomically enable interrupts and return to userspace.  This
+	 * is only ever used to return to 32-bit processes; in a
+	 * 64-bit kernel, it's used for 32-on-64 compat processes, but
+	 * never native 64-bit processes.  (Jump, not call.)
+	 */
+	void (*irq_enable_sysexit)(void);
+
+	/*
+	 * Switch to usermode gs and return to 64-bit usermode using
+	 * sysret.  Only used in 64-bit kernels to return to 64-bit
+	 * processes.  Usermode register state, including %rsp, must
+	 * already be restored.
+	 */
+	void (*usergs_sysret64)(void);
+
+	/*
+	 * Switch to usermode gs and return to 32-bit usermode using
+	 * sysret.  Used to return to 32-on-64 compat processes.
+	 * Other usermode register state, including %esp, must already
+	 * be restored.
+	 */
+	void (*usergs_sysret32)(void);
+
+	/* Normal iret.  Jump to this with the standard iret stack
+	   frame set up. */
+	void (*iret)(void);
+
+	void (*swapgs)(void);
+
+	void (*start_context_switch)(struct task_struct *prev);
+	void (*end_context_switch)(struct task_struct *next);
+};
+
+struct pv_irq_ops {
+	/*
+	 * Get/set interrupt state.  save_fl and restore_fl are only
+	 * expected to use X86_EFLAGS_IF; all other bits
+	 * returned from save_fl are undefined, and may be ignored by
+	 * restore_fl.
+	 *
+	 * NOTE: These functions callers expect the callee to preserve
+	 * more registers than the standard C calling convention.
+	 */
+	struct paravirt_callee_save save_fl;
+	struct paravirt_callee_save restore_fl;
+	struct paravirt_callee_save irq_disable;
+	struct paravirt_callee_save irq_enable;
+
+	void (*safe_halt)(void);
+	void (*halt)(void);
+
+#ifdef CONFIG_X86_64
+	void (*adjust_exception_frame)(void);
+#endif
+};
+
+struct pv_apic_ops {
+#ifdef CONFIG_X86_LOCAL_APIC
+	void (*startup_ipi_hook)(int phys_apicid,
+				 unsigned long start_eip,
+				 unsigned long start_esp);
+#endif
+};
+
+struct pv_mmu_ops {
+	unsigned long (*read_cr2)(void);
+	void (*write_cr2)(unsigned long);
+
+	unsigned long (*read_cr3)(void);
+	void (*write_cr3)(unsigned long);
+
+	/*
+	 * Hooks for intercepting the creation/use/destruction of an
+	 * mm_struct.
+	 */
+	void (*activate_mm)(struct mm_struct *prev,
+			    struct mm_struct *next);
+	void (*dup_mmap)(struct mm_struct *oldmm,
+			 struct mm_struct *mm);
+	void (*exit_mmap)(struct mm_struct *mm);
+
+
+	/* TLB operations */
+	void (*flush_tlb_user)(void);
+	void (*flush_tlb_kernel)(void);
+	void (*flush_tlb_single)(unsigned long addr);
+	void (*flush_tlb_others)(const struct cpumask *cpus,
+				 struct mm_struct *mm,
+				 unsigned long va);
+
+	/* Hooks for allocating and freeing a pagetable top-level */
+	int  (*pgd_alloc)(struct mm_struct *mm);
+	void (*pgd_free)(struct mm_struct *mm, pgd_t *pgd);
+
+	/*
+	 * Hooks for allocating/releasing pagetable pages when they're
+	 * attached to a pagetable
+	 */
+	void (*alloc_pte)(struct mm_struct *mm, unsigned long pfn);
+	void (*alloc_pmd)(struct mm_struct *mm, unsigned long pfn);
+	void (*alloc_pmd_clone)(unsigned long pfn, unsigned long clonepfn, unsigned long start, unsigned long count);
+	void (*alloc_pud)(struct mm_struct *mm, unsigned long pfn);
+	void (*release_pte)(unsigned long pfn);
+	void (*release_pmd)(unsigned long pfn);
+	void (*release_pud)(unsigned long pfn);
+
+	/* Pagetable manipulation functions */
+	void (*set_pte)(pte_t *ptep, pte_t pteval);
+	void (*set_pte_at)(struct mm_struct *mm, unsigned long addr,
+			   pte_t *ptep, pte_t pteval);
+	void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval);
+	void (*pte_update)(struct mm_struct *mm, unsigned long addr,
+			   pte_t *ptep);
+	void (*pte_update_defer)(struct mm_struct *mm,
+				 unsigned long addr, pte_t *ptep);
+
+	pte_t (*ptep_modify_prot_start)(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep);
+	void (*ptep_modify_prot_commit)(struct mm_struct *mm, unsigned long addr,
+					pte_t *ptep, pte_t pte);
+
+	struct paravirt_callee_save pte_val;
+	struct paravirt_callee_save make_pte;
+
+	struct paravirt_callee_save pgd_val;
+	struct paravirt_callee_save make_pgd;
+
+#if PAGETABLE_LEVELS >= 3
+#ifdef CONFIG_X86_PAE
+	void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
+	void (*pte_clear)(struct mm_struct *mm, unsigned long addr,
+			  pte_t *ptep);
+	void (*pmd_clear)(pmd_t *pmdp);
+
+#endif	/* CONFIG_X86_PAE */
+
+	void (*set_pud)(pud_t *pudp, pud_t pudval);
+
+	struct paravirt_callee_save pmd_val;
+	struct paravirt_callee_save make_pmd;
+
+#if PAGETABLE_LEVELS == 4
+	struct paravirt_callee_save pud_val;
+	struct paravirt_callee_save make_pud;
+
+	void (*set_pgd)(pgd_t *pudp, pgd_t pgdval);
+#endif	/* PAGETABLE_LEVELS == 4 */
+#endif	/* PAGETABLE_LEVELS >= 3 */
+
+#ifdef CONFIG_HIGHPTE
+	void *(*kmap_atomic_pte)(struct page *page, enum km_type type);
+#endif
+
+	struct pv_lazy_ops lazy_mode;
+
+	/* dom0 ops */
+
+	/* Sometimes the physical address is a pfn, and sometimes its
+	   an mfn.  We can tell which is which from the index. */
+	void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
+			   phys_addr_t phys, pgprot_t flags);
+};
+
+struct raw_spinlock;
+struct pv_lock_ops {
+	int (*spin_is_locked)(struct raw_spinlock *lock);
+	int (*spin_is_contended)(struct raw_spinlock *lock);
+	void (*spin_lock)(struct raw_spinlock *lock);
+	void (*spin_lock_flags)(struct raw_spinlock *lock, unsigned long flags);
+	int (*spin_trylock)(struct raw_spinlock *lock);
+	void (*spin_unlock)(struct raw_spinlock *lock);
+};
+
+/* This contains all the paravirt structures: we get a convenient
+ * number for each function using the offset which we use to indicate
+ * what to patch. */
+struct paravirt_patch_template {
+	struct pv_init_ops pv_init_ops;
+	struct pv_time_ops pv_time_ops;
+	struct pv_cpu_ops pv_cpu_ops;
+	struct pv_irq_ops pv_irq_ops;
+	struct pv_apic_ops pv_apic_ops;
+	struct pv_mmu_ops pv_mmu_ops;
+	struct pv_lock_ops pv_lock_ops;
+};
+
+extern struct pv_info pv_info;
+extern struct pv_init_ops pv_init_ops;
+extern struct pv_time_ops pv_time_ops;
+extern struct pv_cpu_ops pv_cpu_ops;
+extern struct pv_irq_ops pv_irq_ops;
+extern struct pv_apic_ops pv_apic_ops;
+extern struct pv_mmu_ops pv_mmu_ops;
+extern struct pv_lock_ops pv_lock_ops;
+
+#define PARAVIRT_PATCH(x)					\
+	(offsetof(struct paravirt_patch_template, x) / sizeof(void *))
+
+#define paravirt_type(op)				\
+	[paravirt_typenum] "i" (PARAVIRT_PATCH(op)),	\
+	[paravirt_opptr] "i" (&(op))
+#define paravirt_clobber(clobber)		\
+	[paravirt_clobber] "i" (clobber)
+
+/*
+ * Generate some code, and mark it as patchable by the
+ * apply_paravirt() alternate instruction patcher.
+ */
+#define _paravirt_alt(insn_string, type, clobber)	\
+	"771:\n\t" insn_string "\n" "772:\n"		\
+	".pushsection .parainstructions,\"a\"\n"	\
+	_ASM_ALIGN "\n"					\
+	_ASM_PTR " 771b\n"				\
+	"  .byte " type "\n"				\
+	"  .byte 772b-771b\n"				\
+	"  .short " clobber "\n"			\
+	".popsection\n"
+
+/* Generate patchable code, with the default asm parameters. */
+#define paravirt_alt(insn_string)					\
+	_paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
+
+/* Simple instruction patching code. */
+#define DEF_NATIVE(ops, name, code) 					\
+	extern const char start_##ops##_##name[], end_##ops##_##name[];	\
+	asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
+
+unsigned paravirt_patch_nop(void);
+unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
+unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
+unsigned paravirt_patch_ignore(unsigned len);
+unsigned paravirt_patch_call(void *insnbuf,
+			     const void *target, u16 tgt_clobbers,
+			     unsigned long addr, u16 site_clobbers,
+			     unsigned len);
+unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
+			    unsigned long addr, unsigned len);
+unsigned paravirt_patch_default(u8 type, u16 clobbers, void *insnbuf,
+				unsigned long addr, unsigned len);
+
+unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
+			      const char *start, const char *end);
+
+unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
+		      unsigned long addr, unsigned len);
+
+int paravirt_disable_iospace(void);
+
+/*
+ * This generates an indirect call based on the operation type number.
+ * The type number, computed in PARAVIRT_PATCH, is derived from the
+ * offset into the paravirt_patch_template structure, and can therefore be
+ * freely converted back into a structure offset.
+ */
+#define PARAVIRT_CALL	"call *%c[paravirt_opptr];"
+
+/*
+ * These macros are intended to wrap calls through one of the paravirt
+ * ops structs, so that they can be later identified and patched at
+ * runtime.
+ *
+ * Normally, a call to a pv_op function is a simple indirect call:
+ * (pv_op_struct.operations)(args...).
+ *
+ * Unfortunately, this is a relatively slow operation for modern CPUs,
+ * because it cannot necessarily determine what the destination
+ * address is.  In this case, the address is a runtime constant, so at
+ * the very least we can patch the call to e a simple direct call, or
+ * ideally, patch an inline implementation into the callsite.  (Direct
+ * calls are essentially free, because the call and return addresses
+ * are completely predictable.)
+ *
+ * For i386, these macros rely on the standard gcc "regparm(3)" calling
+ * convention, in which the first three arguments are placed in %eax,
+ * %edx, %ecx (in that order), and the remaining arguments are placed
+ * on the stack.  All caller-save registers (eax,edx,ecx) are expected
+ * to be modified (either clobbered or used for return values).
+ * X86_64, on the other hand, already specifies a register-based calling
+ * conventions, returning at %rax, with parameteres going on %rdi, %rsi,
+ * %rdx, and %rcx. Note that for this reason, x86_64 does not need any
+ * special handling for dealing with 4 arguments, unlike i386.
+ * However, x86_64 also have to clobber all caller saved registers, which
+ * unfortunately, are quite a bit (r8 - r11)
+ *
+ * The call instruction itself is marked by placing its start address
+ * and size into the .parainstructions section, so that
+ * apply_paravirt() in arch/i386/kernel/alternative.c can do the
+ * appropriate patching under the control of the backend pv_init_ops
+ * implementation.
+ *
+ * Unfortunately there's no way to get gcc to generate the args setup
+ * for the call, and then allow the call itself to be generated by an
+ * inline asm.  Because of this, we must do the complete arg setup and
+ * return value handling from within these macros.  This is fairly
+ * cumbersome.
+ *
+ * There are 5 sets of PVOP_* macros for dealing with 0-4 arguments.
+ * It could be extended to more arguments, but there would be little
+ * to be gained from that.  For each number of arguments, there are
+ * the two VCALL and CALL variants for void and non-void functions.
+ *
+ * When there is a return value, the invoker of the macro must specify
+ * the return type.  The macro then uses sizeof() on that type to
+ * determine whether its a 32 or 64 bit value, and places the return
+ * in the right register(s) (just %eax for 32-bit, and %edx:%eax for
+ * 64-bit). For x86_64 machines, it just returns at %rax regardless of
+ * the return value size.
+ *
+ * 64-bit arguments are passed as a pair of adjacent 32-bit arguments
+ * i386 also passes 64-bit arguments as a pair of adjacent 32-bit arguments
+ * in low,high order
+ *
+ * Small structures are passed and returned in registers.  The macro
+ * calling convention can't directly deal with this, so the wrapper
+ * functions must do this.
+ *
+ * These PVOP_* macros are only defined within this header.  This
+ * means that all uses must be wrapped in inline functions.  This also
+ * makes sure the incoming and outgoing types are always correct.
+ */
+#ifdef CONFIG_X86_32
+#define PVOP_VCALL_ARGS				\
+	unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx
+#define PVOP_CALL_ARGS			PVOP_VCALL_ARGS
+
+#define PVOP_CALL_ARG1(x)		"a" ((unsigned long)(x))
+#define PVOP_CALL_ARG2(x)		"d" ((unsigned long)(x))
+#define PVOP_CALL_ARG3(x)		"c" ((unsigned long)(x))
+
+#define PVOP_VCALL_CLOBBERS		"=a" (__eax), "=d" (__edx),	\
+					"=c" (__ecx)
+#define PVOP_CALL_CLOBBERS		PVOP_VCALL_CLOBBERS
+
+#define PVOP_VCALLEE_CLOBBERS		"=a" (__eax), "=d" (__edx)
+#define PVOP_CALLEE_CLOBBERS		PVOP_VCALLEE_CLOBBERS
+
+#define EXTRA_CLOBBERS
+#define VEXTRA_CLOBBERS
+#else  /* CONFIG_X86_64 */
+#define PVOP_VCALL_ARGS					\
+	unsigned long __edi = __edi, __esi = __esi,	\
+		__edx = __edx, __ecx = __ecx
+#define PVOP_CALL_ARGS		PVOP_VCALL_ARGS, __eax
+
+#define PVOP_CALL_ARG1(x)		"D" ((unsigned long)(x))
+#define PVOP_CALL_ARG2(x)		"S" ((unsigned long)(x))
+#define PVOP_CALL_ARG3(x)		"d" ((unsigned long)(x))
+#define PVOP_CALL_ARG4(x)		"c" ((unsigned long)(x))
+
+#define PVOP_VCALL_CLOBBERS	"=D" (__edi),				\
+				"=S" (__esi), "=d" (__edx),		\
+				"=c" (__ecx)
+#define PVOP_CALL_CLOBBERS	PVOP_VCALL_CLOBBERS, "=a" (__eax)
+
+#define PVOP_VCALLEE_CLOBBERS	"=a" (__eax)
+#define PVOP_CALLEE_CLOBBERS	PVOP_VCALLEE_CLOBBERS
+
+#define EXTRA_CLOBBERS	 , "r8", "r9", "r10", "r11"
+#define VEXTRA_CLOBBERS	 , "rax", "r8", "r9", "r10", "r11"
+#endif	/* CONFIG_X86_32 */
+
+#ifdef CONFIG_PARAVIRT_DEBUG
+#define PVOP_TEST_NULL(op)	BUG_ON(op == NULL)
+#else
+#define PVOP_TEST_NULL(op)	((void)op)
+#endif
+
+#define ____PVOP_CALL(rettype, op, clbr, call_clbr, extra_clbr,		\
+		      pre, post, ...)					\
+	({								\
+		rettype __ret;						\
+		PVOP_CALL_ARGS;						\
+		PVOP_TEST_NULL(op);					\
+		/* This is 32-bit specific, but is okay in 64-bit */	\
+		/* since this condition will never hold */		\
+		if (sizeof(rettype) > sizeof(unsigned long)) {		\
+			asm volatile(pre				\
+				     paravirt_alt(PARAVIRT_CALL)	\
+				     post				\
+				     : call_clbr			\
+				     : paravirt_type(op),		\
+				       paravirt_clobber(clbr),		\
+				       ##__VA_ARGS__			\
+				     : "memory", "cc" extra_clbr);	\
+			__ret = (rettype)((((u64)__edx) << 32) | __eax); \
+		} else {						\
+			asm volatile(pre				\
+				     paravirt_alt(PARAVIRT_CALL)	\
+				     post				\
+				     : call_clbr			\
+				     : paravirt_type(op),		\
+				       paravirt_clobber(clbr),		\
+				       ##__VA_ARGS__			\
+				     : "memory", "cc" extra_clbr);	\
+			__ret = (rettype)__eax;				\
+		}							\
+		__ret;							\
+	})
+
+#define __PVOP_CALL(rettype, op, pre, post, ...)			\
+	____PVOP_CALL(rettype, op, CLBR_ANY, PVOP_CALL_CLOBBERS,	\
+		      EXTRA_CLOBBERS, pre, post, ##__VA_ARGS__)
+
+#define __PVOP_CALLEESAVE(rettype, op, pre, post, ...)			\
+	____PVOP_CALL(rettype, op.func, CLBR_RET_REG,			\
+		      PVOP_CALLEE_CLOBBERS, ,				\
+		      pre, post, ##__VA_ARGS__)
+
+
+#define ____PVOP_VCALL(op, clbr, call_clbr, extra_clbr, pre, post, ...)	\
+	({								\
+		PVOP_VCALL_ARGS;					\
+		PVOP_TEST_NULL(op);					\
+		asm volatile(pre					\
+			     paravirt_alt(PARAVIRT_CALL)		\
+			     post					\
+			     : call_clbr				\
+			     : paravirt_type(op),			\
+			       paravirt_clobber(clbr),			\
+			       ##__VA_ARGS__				\
+			     : "memory", "cc" extra_clbr);		\
+	})
+
+#define __PVOP_VCALL(op, pre, post, ...)				\
+	____PVOP_VCALL(op, CLBR_ANY, PVOP_VCALL_CLOBBERS,		\
+		       VEXTRA_CLOBBERS,					\
+		       pre, post, ##__VA_ARGS__)
+
+#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...)			\
+	____PVOP_CALL(rettype, op.func, CLBR_RET_REG,			\
+		      PVOP_VCALLEE_CLOBBERS, ,				\
+		      pre, post, ##__VA_ARGS__)
+
+
+
+#define PVOP_CALL0(rettype, op)						\
+	__PVOP_CALL(rettype, op, "", "")
+#define PVOP_VCALL0(op)							\
+	__PVOP_VCALL(op, "", "")
+
+#define PVOP_CALLEE0(rettype, op)					\
+	__PVOP_CALLEESAVE(rettype, op, "", "")
+#define PVOP_VCALLEE0(op)						\
+	__PVOP_VCALLEESAVE(op, "", "")
+
+
+#define PVOP_CALL1(rettype, op, arg1)					\
+	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
+#define PVOP_VCALL1(op, arg1)						\
+	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1))
+
+#define PVOP_CALLEE1(rettype, op, arg1)					\
+	__PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1))
+#define PVOP_VCALLEE1(op, arg1)						\
+	__PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1))
+
+
+#define PVOP_CALL2(rettype, op, arg1, arg2)				\
+	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1),		\
+		    PVOP_CALL_ARG2(arg2))
+#define PVOP_VCALL2(op, arg1, arg2)					\
+	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1),			\
+		     PVOP_CALL_ARG2(arg2))
+
+#define PVOP_CALLEE2(rettype, op, arg1, arg2)				\
+	__PVOP_CALLEESAVE(rettype, op, "", "", PVOP_CALL_ARG1(arg1),	\
+			  PVOP_CALL_ARG2(arg2))
+#define PVOP_VCALLEE2(op, arg1, arg2)					\
+	__PVOP_VCALLEESAVE(op, "", "", PVOP_CALL_ARG1(arg1),		\
+			   PVOP_CALL_ARG2(arg2))
+
+
+#define PVOP_CALL3(rettype, op, arg1, arg2, arg3)			\
+	__PVOP_CALL(rettype, op, "", "", PVOP_CALL_ARG1(arg1),		\
+		    PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
+#define PVOP_VCALL3(op, arg1, arg2, arg3)				\
+	__PVOP_VCALL(op, "", "", PVOP_CALL_ARG1(arg1),			\
+		     PVOP_CALL_ARG2(arg2), PVOP_CALL_ARG3(arg3))
+
+/* This is the only difference in x86_64. We can make it much simpler */
+#ifdef CONFIG_X86_32
+#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4)			\
+	__PVOP_CALL(rettype, op,					\
+		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\
+		    PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),		\
+		    PVOP_CALL_ARG3(arg3), [_arg4] "mr" ((u32)(arg4)))
+#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4)				\
+	__PVOP_VCALL(op,						\
+		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\
+		    "0" ((u32)(arg1)), "1" ((u32)(arg2)),		\
+		    "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))
+#else
+#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4)			\
+	__PVOP_CALL(rettype, op, "", "",				\
+		    PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),		\
+		    PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
+#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4)				\
+	__PVOP_VCALL(op, "", "",					\
+		     PVOP_CALL_ARG1(arg1), PVOP_CALL_ARG2(arg2),	\
+		     PVOP_CALL_ARG3(arg3), PVOP_CALL_ARG4(arg4))
+#endif
+
+/* Lazy mode for batching updates / context switch */
+enum paravirt_lazy_mode {
+	PARAVIRT_LAZY_NONE,
+	PARAVIRT_LAZY_MMU,
+	PARAVIRT_LAZY_CPU,
+};
+
+enum paravirt_lazy_mode paravirt_get_lazy_mode(void);
+void paravirt_start_context_switch(struct task_struct *prev);
+void paravirt_end_context_switch(struct task_struct *next);
+
+void paravirt_enter_lazy_mmu(void);
+void paravirt_leave_lazy_mmu(void);
+
+void _paravirt_nop(void);
+u32 _paravirt_ident_32(u32);
+u64 _paravirt_ident_64(u64);
+
+#define paravirt_nop	((void *)_paravirt_nop)
+
+/* These all sit in the .parainstructions section to tell us what to patch. */
+struct paravirt_patch_site {
+	u8 *instr; 		/* original instructions */
+	u8 instrtype;		/* type of this instruction */
+	u8 len;			/* length of original instruction */
+	u16 clobbers;		/* what registers you may clobber */
+};
+
+extern struct paravirt_patch_site __parainstructions[],
+	__parainstructions_end[];
+
+#endif	/* __ASSEMBLY__ */
+
+#endif	/* _ASM_X86_PARAVIRT_TYPES_H */
diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
index 7af14e5..e2c1668 100644
--- a/arch/x86/include/asm/pat.h
+++ b/arch/x86/include/asm/pat.h
@@ -19,4 +19,9 @@ extern int free_memtype(u64 start, u64 end);
 extern int kernel_map_sync_memtype(u64 base, unsigned long size,
 		unsigned long flag);
 
+int io_reserve_memtype(resource_size_t start, resource_size_t end,
+			unsigned long *type);
+
+void io_free_memtype(resource_size_t start, resource_size_t end);
+
 #endif /* _ASM_X86_PAT_H */
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 1ff685c..f76a162 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -48,7 +48,6 @@ extern unsigned int pcibios_assign_all_busses(void);
 #else
 #define pcibios_assign_all_busses()	0
 #endif
-#define pcibios_scan_all_fns(a, b)	0
 
 extern unsigned long pci_mem_start;
 #define PCIBIOS_MIN_IO		0x1000
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 103f1dd..b65a36d 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -49,7 +49,7 @@
 #define __percpu_arg(x)		"%%"__stringify(__percpu_seg)":%P" #x
 #define __my_cpu_offset		percpu_read(this_cpu_off)
 #else
-#define __percpu_arg(x)		"%" #x
+#define __percpu_arg(x)		"%P" #x
 #endif
 
 /*
@@ -104,36 +104,48 @@ do {							\
 	}						\
 } while (0)
 
-#define percpu_from_op(op, var)				\
+#define percpu_from_op(op, var, constraint)		\
 ({							\
 	typeof(var) ret__;				\
 	switch (sizeof(var)) {				\
 	case 1:						\
 		asm(op "b "__percpu_arg(1)",%0"		\
 		    : "=q" (ret__)			\
-		    : "m" (var));			\
+		    : constraint);			\
 		break;					\
 	case 2:						\
 		asm(op "w "__percpu_arg(1)",%0"		\
 		    : "=r" (ret__)			\
-		    : "m" (var));			\
+		    : constraint);			\
 		break;					\
 	case 4:						\
 		asm(op "l "__percpu_arg(1)",%0"		\
 		    : "=r" (ret__)			\
-		    : "m" (var));			\
+		    : constraint);			\
 		break;					\
 	case 8:						\
 		asm(op "q "__percpu_arg(1)",%0"		\
 		    : "=r" (ret__)			\
-		    : "m" (var));			\
+		    : constraint);			\
 		break;					\
 	default: __bad_percpu_size();			\
 	}						\
 	ret__;						\
 })
 
-#define percpu_read(var)	percpu_from_op("mov", per_cpu__##var)
+/*
+ * percpu_read() makes gcc load the percpu variable every time it is
+ * accessed while percpu_read_stable() allows the value to be cached.
+ * percpu_read_stable() is more efficient and can be used if its value
+ * is guaranteed to be valid across cpus.  The current users include
+ * get_current() and get_thread_info() both of which are actually
+ * per-thread variables implemented as per-cpu variables and thus
+ * stable for the duration of the respective task.
+ */
+#define percpu_read(var)	percpu_from_op("mov", per_cpu__##var,	\
+					       "m" (per_cpu__##var))
+#define percpu_read_stable(var)	percpu_from_op("mov", per_cpu__##var,	\
+					       "p" (&per_cpu__##var))
 #define percpu_write(var, val)	percpu_to_op("mov", per_cpu__##var, val)
 #define percpu_add(var, val)	percpu_to_op("add", per_cpu__##var, val)
 #define percpu_sub(var, val)	percpu_to_op("sub", per_cpu__##var, val)
@@ -156,15 +168,6 @@ do {							\
 /* We can use this directly for local CPU (faster). */
 DECLARE_PER_CPU(unsigned long, this_cpu_off);
 
-#ifdef CONFIG_NEED_MULTIPLE_NODES
-void *pcpu_lpage_remapped(void *kaddr);
-#else
-static inline void *pcpu_lpage_remapped(void *kaddr)
-{
-	return NULL;
-}
-#endif
-
 #endif /* !__ASSEMBLY__ */
 
 #ifdef CONFIG_SMP
diff --git a/arch/x86/include/asm/perf_counter.h b/arch/x86/include/asm/perf_counter.h
deleted file mode 100644
index e7b7c93..0000000
--- a/arch/x86/include/asm/perf_counter.h
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef _ASM_X86_PERF_COUNTER_H
-#define _ASM_X86_PERF_COUNTER_H
-
-/*
- * Performance counter hw details:
- */
-
-#define X86_PMC_MAX_GENERIC					8
-#define X86_PMC_MAX_FIXED					3
-
-#define X86_PMC_IDX_GENERIC				        0
-#define X86_PMC_IDX_FIXED				       32
-#define X86_PMC_IDX_MAX					       64
-
-#define MSR_ARCH_PERFMON_PERFCTR0			      0xc1
-#define MSR_ARCH_PERFMON_PERFCTR1			      0xc2
-
-#define MSR_ARCH_PERFMON_EVENTSEL0			     0x186
-#define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
-
-#define ARCH_PERFMON_EVENTSEL0_ENABLE			  (1 << 22)
-#define ARCH_PERFMON_EVENTSEL_INT			  (1 << 20)
-#define ARCH_PERFMON_EVENTSEL_OS			  (1 << 17)
-#define ARCH_PERFMON_EVENTSEL_USR			  (1 << 16)
-
-/*
- * Includes eventsel and unit mask as well:
- */
-#define ARCH_PERFMON_EVENT_MASK				    0xffff
-
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL		      0x3c
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK		(0x00 << 8)
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 		 0
-#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
-		(1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
-
-#define ARCH_PERFMON_BRANCH_MISSES_RETIRED			 6
-
-/*
- * Intel "Architectural Performance Monitoring" CPUID
- * detection/enumeration details:
- */
-union cpuid10_eax {
-	struct {
-		unsigned int version_id:8;
-		unsigned int num_counters:8;
-		unsigned int bit_width:8;
-		unsigned int mask_length:8;
-	} split;
-	unsigned int full;
-};
-
-union cpuid10_edx {
-	struct {
-		unsigned int num_counters_fixed:4;
-		unsigned int reserved:28;
-	} split;
-	unsigned int full;
-};
-
-
-/*
- * Fixed-purpose performance counters:
- */
-
-/*
- * All 3 fixed-mode PMCs are configured via this single MSR:
- */
-#define MSR_ARCH_PERFMON_FIXED_CTR_CTRL			0x38d
-
-/*
- * The counts are available in three separate MSRs:
- */
-
-/* Instr_Retired.Any: */
-#define MSR_ARCH_PERFMON_FIXED_CTR0			0x309
-#define X86_PMC_IDX_FIXED_INSTRUCTIONS			(X86_PMC_IDX_FIXED + 0)
-
-/* CPU_CLK_Unhalted.Core: */
-#define MSR_ARCH_PERFMON_FIXED_CTR1			0x30a
-#define X86_PMC_IDX_FIXED_CPU_CYCLES			(X86_PMC_IDX_FIXED + 1)
-
-/* CPU_CLK_Unhalted.Ref: */
-#define MSR_ARCH_PERFMON_FIXED_CTR2			0x30b
-#define X86_PMC_IDX_FIXED_BUS_CYCLES			(X86_PMC_IDX_FIXED + 2)
-
-/*
- * We model BTS tracing as another fixed-mode PMC.
- *
- * We choose a value in the middle of the fixed counter range, since lower
- * values are used by actual fixed counters and higher values are used
- * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr.
- */
-#define X86_PMC_IDX_FIXED_BTS				(X86_PMC_IDX_FIXED + 16)
-
-
-#ifdef CONFIG_PERF_COUNTERS
-extern void init_hw_perf_counters(void);
-extern void perf_counters_lapic_init(void);
-
-#define PERF_COUNTER_INDEX_OFFSET			0
-
-#else
-static inline void init_hw_perf_counters(void)		{ }
-static inline void perf_counters_lapic_init(void)	{ }
-#endif
-
-#endif /* _ASM_X86_PERF_COUNTER_H */
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
new file mode 100644
index 0000000..ad7ce3f
--- /dev/null
+++ b/arch/x86/include/asm/perf_event.h
@@ -0,0 +1,108 @@
+#ifndef _ASM_X86_PERF_EVENT_H
+#define _ASM_X86_PERF_EVENT_H
+
+/*
+ * Performance event hw details:
+ */
+
+#define X86_PMC_MAX_GENERIC					8
+#define X86_PMC_MAX_FIXED					3
+
+#define X86_PMC_IDX_GENERIC				        0
+#define X86_PMC_IDX_FIXED				       32
+#define X86_PMC_IDX_MAX					       64
+
+#define MSR_ARCH_PERFMON_PERFCTR0			      0xc1
+#define MSR_ARCH_PERFMON_PERFCTR1			      0xc2
+
+#define MSR_ARCH_PERFMON_EVENTSEL0			     0x186
+#define MSR_ARCH_PERFMON_EVENTSEL1			     0x187
+
+#define ARCH_PERFMON_EVENTSEL0_ENABLE			  (1 << 22)
+#define ARCH_PERFMON_EVENTSEL_INT			  (1 << 20)
+#define ARCH_PERFMON_EVENTSEL_OS			  (1 << 17)
+#define ARCH_PERFMON_EVENTSEL_USR			  (1 << 16)
+
+/*
+ * Includes eventsel and unit mask as well:
+ */
+#define ARCH_PERFMON_EVENT_MASK				    0xffff
+
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL		      0x3c
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK		(0x00 << 8)
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX 		 0
+#define ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT \
+		(1 << (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX))
+
+#define ARCH_PERFMON_BRANCH_MISSES_RETIRED			 6
+
+/*
+ * Intel "Architectural Performance Monitoring" CPUID
+ * detection/enumeration details:
+ */
+union cpuid10_eax {
+	struct {
+		unsigned int version_id:8;
+		unsigned int num_events:8;
+		unsigned int bit_width:8;
+		unsigned int mask_length:8;
+	} split;
+	unsigned int full;
+};
+
+union cpuid10_edx {
+	struct {
+		unsigned int num_events_fixed:4;
+		unsigned int reserved:28;
+	} split;
+	unsigned int full;
+};
+
+
+/*
+ * Fixed-purpose performance events:
+ */
+
+/*
+ * All 3 fixed-mode PMCs are configured via this single MSR:
+ */
+#define MSR_ARCH_PERFMON_FIXED_CTR_CTRL			0x38d
+
+/*
+ * The counts are available in three separate MSRs:
+ */
+
+/* Instr_Retired.Any: */
+#define MSR_ARCH_PERFMON_FIXED_CTR0			0x309
+#define X86_PMC_IDX_FIXED_INSTRUCTIONS			(X86_PMC_IDX_FIXED + 0)
+
+/* CPU_CLK_Unhalted.Core: */
+#define MSR_ARCH_PERFMON_FIXED_CTR1			0x30a
+#define X86_PMC_IDX_FIXED_CPU_CYCLES			(X86_PMC_IDX_FIXED + 1)
+
+/* CPU_CLK_Unhalted.Ref: */
+#define MSR_ARCH_PERFMON_FIXED_CTR2			0x30b
+#define X86_PMC_IDX_FIXED_BUS_CYCLES			(X86_PMC_IDX_FIXED + 2)
+
+/*
+ * We model BTS tracing as another fixed-mode PMC.
+ *
+ * We choose a value in the middle of the fixed event range, since lower
+ * values are used by actual fixed events and higher values are used
+ * to indicate other overflow conditions in the PERF_GLOBAL_STATUS msr.
+ */
+#define X86_PMC_IDX_FIXED_BTS				(X86_PMC_IDX_FIXED + 16)
+
+
+#ifdef CONFIG_PERF_EVENTS
+extern void init_hw_perf_events(void);
+extern void perf_events_lapic_init(void);
+
+#define PERF_EVENT_INDEX_OFFSET			0
+
+#else
+static inline void init_hw_perf_events(void)		{ }
+static inline void perf_events_lapic_init(void)	{ }
+#endif
+
+#endif /* _ASM_X86_PERF_EVENT_H */
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 1674807..af6fd36 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -56,16 +56,6 @@ extern struct list_head pgd_list;
 #define pte_update(mm, addr, ptep)              do { } while (0)
 #define pte_update_defer(mm, addr, ptep)        do { } while (0)
 
-static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
-{
-	native_pagetable_setup_start(base);
-}
-
-static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
-{
-	native_pagetable_setup_done(base);
-}
-
 #define pgd_val(x)	native_pgd_val(x)
 #define __pgd(x)	native_make_pgd(x)
 
@@ -135,6 +125,11 @@ static inline unsigned long pte_pfn(pte_t pte)
 	return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
 }
 
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+	return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
+}
+
 #define pte_page(pte)	pfn_to_page(pte_pfn(pte))
 
 static inline int pmd_large(pmd_t pte)
@@ -359,7 +354,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
  * this macro returns the index of the entry in the pmd page which would
  * control the given virtual address
  */
-static inline unsigned pmd_index(unsigned long address)
+static inline unsigned long pmd_index(unsigned long address)
 {
 	return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
 }
@@ -379,7 +374,7 @@ static inline unsigned pmd_index(unsigned long address)
  * this function returns the index of the entry in the pte page which would
  * control the given virtual address
  */
-static inline unsigned pte_index(unsigned long address)
+static inline unsigned long pte_index(unsigned long address)
 {
 	return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
 }
@@ -430,11 +425,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
 	return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
 }
 
-static inline unsigned long pmd_pfn(pmd_t pmd)
-{
-	return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT;
-}
-
 static inline int pud_large(pud_t pud)
 {
 	return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
@@ -470,7 +460,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd)
 #define pgd_page(pgd)		pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
 
 /* to find an entry in a page-table-directory. */
-static inline unsigned pud_index(unsigned long address)
+static inline unsigned long pud_index(unsigned long address)
 {
 	return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
 }
diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h
index 54cb697..7b467bf 100644
--- a/arch/x86/include/asm/pgtable_types.h
+++ b/arch/x86/include/asm/pgtable_types.h
@@ -299,8 +299,8 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pte);
 extern void native_pagetable_setup_start(pgd_t *base);
 extern void native_pagetable_setup_done(pgd_t *base);
 #else
-static inline void native_pagetable_setup_start(pgd_t *base) {}
-static inline void native_pagetable_setup_done(pgd_t *base) {}
+#define native_pagetable_setup_start x86_init_pgd_noop
+#define native_pagetable_setup_done  x86_init_pgd_noop
 #endif
 
 struct seq_file;
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c776826..c3429e8 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -27,6 +27,7 @@ struct mm_struct;
 #include <linux/cpumask.h>
 #include <linux/cache.h>
 #include <linux/threads.h>
+#include <linux/math64.h>
 #include <linux/init.h>
 
 /*
@@ -403,7 +404,17 @@ extern unsigned long kernel_eflags;
 extern asmlinkage void ignore_sysret(void);
 #else	/* X86_64 */
 #ifdef CONFIG_CC_STACKPROTECTOR
-DECLARE_PER_CPU(unsigned long, stack_canary);
+/*
+ * Make sure stack canary segment base is cached-aligned:
+ *   "For Intel Atom processors, avoid non zero segment base address
+ *    that is not aligned to cache line boundary at all cost."
+ * (Optim Ref Manual Assembly/Compiler Coding Rule 15.)
+ */
+struct stack_canary {
+	char __pad[20];		/* canary at %gs:20 */
+	unsigned long canary;
+};
+DECLARE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
 #endif
 #endif	/* X86_64 */
 
@@ -703,13 +714,23 @@ static inline void cpu_relax(void)
 	rep_nop();
 }
 
-/* Stop speculative execution: */
+/* Stop speculative execution and prefetching of modified code. */
 static inline void sync_core(void)
 {
 	int tmp;
 
-	asm volatile("cpuid" : "=a" (tmp) : "0" (1)
-		     : "ebx", "ecx", "edx", "memory");
+#if defined(CONFIG_M386) || defined(CONFIG_M486)
+	if (boot_cpu_data.x86 < 5)
+		/* There is no speculative execution.
+		 * jmp is a barrier to prefetching. */
+		asm volatile("jmp 1f\n1:\n" ::: "memory");
+	else
+#endif
+		/* cpuid is a barrier to speculative execution.
+		 * Prefetched instructions are automatically
+		 * invalidated when modified. */
+		asm volatile("cpuid" : "=a" (tmp) : "0" (1)
+			     : "ebx", "ecx", "edx", "memory");
 }
 
 static inline void __monitor(const void *eax, unsigned long ecx,
@@ -1000,4 +1021,35 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
 extern int get_tsc_mode(unsigned long adr);
 extern int set_tsc_mode(unsigned int val);
 
+extern int amd_get_nb_id(int cpu);
+
+struct aperfmperf {
+	u64 aperf, mperf;
+};
+
+static inline void get_aperfmperf(struct aperfmperf *am)
+{
+	WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF));
+
+	rdmsrl(MSR_IA32_APERF, am->aperf);
+	rdmsrl(MSR_IA32_MPERF, am->mperf);
+}
+
+#define APERFMPERF_SHIFT 10
+
+static inline
+unsigned long calc_aperfmperf_ratio(struct aperfmperf *old,
+				    struct aperfmperf *new)
+{
+	u64 aperf = new->aperf - old->aperf;
+	u64 mperf = new->mperf - old->mperf;
+	unsigned long ratio = aperf;
+
+	mperf >>= APERFMPERF_SHIFT;
+	if (mperf)
+		ratio = div64_u64(aperf, mperf);
+
+	return ratio;
+}
+
 #endif /* _ASM_X86_PROCESSOR_H */
diff --git a/arch/x86/include/asm/scatterlist.h b/arch/x86/include/asm/scatterlist.h
index 263d397..75af592 100644
--- a/arch/x86/include/asm/scatterlist.h
+++ b/arch/x86/include/asm/scatterlist.h
@@ -1,33 +1,8 @@
 #ifndef _ASM_X86_SCATTERLIST_H
 #define _ASM_X86_SCATTERLIST_H
 
-#include <asm/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;
-	unsigned int	dma_length;
-};
-
-#define ARCH_HAS_SG_CHAIN
 #define ISA_DMA_THRESHOLD (0x00ffffff)
 
-/*
- * These macros should be used after a pci_map_sg call has been done
- * to get bus addresses of each of the SG entries and their lengths.
- * You should only work with the number of sg entries pci_map_sg
- * returns.
- */
-#define sg_dma_address(sg)	((sg)->dma_address)
-#ifdef CONFIG_X86_32
-# define sg_dma_len(sg)		((sg)->length)
-#else
-# define sg_dma_len(sg)		((sg)->dma_length)
-#endif
+#include <asm-generic/scatterlist.h>
 
 #endif /* _ASM_X86_SCATTERLIST_H */
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index 4093d1e..18e496c 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -5,43 +5,6 @@
 
 #define COMMAND_LINE_SIZE 2048
 
-#ifndef __ASSEMBLY__
-
-/*
- * Any setup quirks to be performed?
- */
-struct mpc_cpu;
-struct mpc_bus;
-struct mpc_oemtable;
-
-struct x86_quirks {
-	int (*arch_pre_time_init)(void);
-	int (*arch_time_init)(void);
-	int (*arch_pre_intr_init)(void);
-	int (*arch_intr_init)(void);
-	int (*arch_trap_init)(void);
-	char * (*arch_memory_setup)(void);
-	int (*mach_get_smp_config)(unsigned int early);
-	int (*mach_find_smp_config)(unsigned int reserve);
-
-	int *mpc_record;
-	int (*mpc_apic_id)(struct mpc_cpu *m);
-	void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
-	void (*mpc_oem_pci_bus)(struct mpc_bus *m);
-	void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
-				unsigned short oemsize);
-	int (*setup_ioapic_ids)(void);
-};
-
-extern void x86_quirk_intr_init(void);
-
-extern void x86_quirk_trap_init(void);
-
-extern void x86_quirk_pre_time_init(void);
-extern void x86_quirk_time_init(void);
-
-#endif /* __ASSEMBLY__ */
-
 #ifdef __i386__
 
 #include <linux/pfn.h>
@@ -61,6 +24,7 @@ extern void x86_quirk_time_init(void);
 
 #ifndef __ASSEMBLY__
 #include <asm/bootparam.h>
+#include <asm/x86_init.h>
 
 /* Interrupt control for vSMPowered x86_64 systems */
 #ifdef CONFIG_X86_64
@@ -79,11 +43,16 @@ static inline void visws_early_detect(void) { }
 static inline int is_visws_box(void) { return 0; }
 #endif
 
-extern struct x86_quirks *x86_quirks;
 extern unsigned long saved_video_mode;
 
-#ifndef CONFIG_PARAVIRT
-#define paravirt_post_allocator_init()	do {} while (0)
+extern void reserve_standard_io_resources(void);
+extern void i386_reserve_resources(void);
+extern void setup_default_timer_irq(void);
+
+#ifdef CONFIG_X86_MRST
+extern void x86_mrst_early_setup(void);
+#else
+static inline void x86_mrst_early_setup(void) { }
 #endif
 
 #ifndef _SETUP
diff --git a/arch/x86/include/asm/shmbuf.h b/arch/x86/include/asm/shmbuf.h
index b51413b..83c05fc 100644
--- a/arch/x86/include/asm/shmbuf.h
+++ b/arch/x86/include/asm/shmbuf.h
@@ -1,51 +1 @@
-#ifndef _ASM_X86_SHMBUF_H
-#define _ASM_X86_SHMBUF_H
-
-/*
- * The shmid64_ds structure for x86 architecture.
- * Note extra padding because this structure is passed back and forth
- * between kernel and user space.
- *
- * Pad space on 32 bit is left for:
- * - 64-bit time_t to solve y2038 problem
- * - 2 miscellaneous 32-bit values
- *
- * Pad space on 64 bit is left for:
- * - 2 miscellaneous 64-bit values
- */
-
-struct shmid64_ds {
-	struct ipc64_perm	shm_perm;	/* operation perms */
-	size_t			shm_segsz;	/* size of segment (bytes) */
-	__kernel_time_t		shm_atime;	/* last attach time */
-#ifdef __i386__
-	unsigned long		__unused1;
-#endif
-	__kernel_time_t		shm_dtime;	/* last detach time */
-#ifdef __i386__
-	unsigned long		__unused2;
-#endif
-	__kernel_time_t		shm_ctime;	/* last change time */
-#ifdef __i386__
-	unsigned long		__unused3;
-#endif
-	__kernel_pid_t		shm_cpid;	/* pid of creator */
-	__kernel_pid_t		shm_lpid;	/* pid of last operator */
-	unsigned long		shm_nattch;	/* no. of current attaches */
-	unsigned long		__unused4;
-	unsigned long		__unused5;
-};
-
-struct shminfo64 {
-	unsigned long	shmmax;
-	unsigned long	shmmin;
-	unsigned long	shmmni;
-	unsigned long	shmseg;
-	unsigned long	shmall;
-	unsigned long	__unused1;
-	unsigned long	__unused2;
-	unsigned long	__unused3;
-	unsigned long	__unused4;
-};
-
-#endif /* _ASM_X86_SHMBUF_H */
+#include <asm-generic/shmbuf.h>
diff --git a/arch/x86/include/asm/socket.h b/arch/x86/include/asm/socket.h
index ca8bf2c..6b71384 100644
--- a/arch/x86/include/asm/socket.h
+++ b/arch/x86/include/asm/socket.h
@@ -1,60 +1 @@
-#ifndef _ASM_X86_SOCKET_H
-#define _ASM_X86_SOCKET_H
-
-#include <asm/sockios.h>
-
-/* For setsockopt(2) */
-#define SOL_SOCKET	1
-
-#define SO_DEBUG	1
-#define SO_REUSEADDR	2
-#define SO_TYPE		3
-#define SO_ERROR	4
-#define SO_DONTROUTE	5
-#define SO_BROADCAST	6
-#define SO_SNDBUF	7
-#define SO_RCVBUF	8
-#define SO_SNDBUFFORCE	32
-#define SO_RCVBUFFORCE	33
-#define SO_KEEPALIVE	9
-#define SO_OOBINLINE	10
-#define SO_NO_CHECK	11
-#define SO_PRIORITY	12
-#define SO_LINGER	13
-#define SO_BSDCOMPAT	14
-/* To add :#define SO_REUSEPORT 15 */
-#define SO_PASSCRED	16
-#define SO_PEERCRED	17
-#define SO_RCVLOWAT	18
-#define SO_SNDLOWAT	19
-#define SO_RCVTIMEO	20
-#define SO_SNDTIMEO	21
-
-/* Security levels - as per NRL IPv6 - don't actually do anything */
-#define SO_SECURITY_AUTHENTICATION		22
-#define SO_SECURITY_ENCRYPTION_TRANSPORT	23
-#define SO_SECURITY_ENCRYPTION_NETWORK		24
-
-#define SO_BINDTODEVICE	25
-
-/* Socket filtering */
-#define SO_ATTACH_FILTER        26
-#define SO_DETACH_FILTER        27
-
-#define SO_PEERNAME		28
-#define SO_TIMESTAMP		29
-#define SCM_TIMESTAMP		SO_TIMESTAMP
-
-#define SO_ACCEPTCONN		30
-
-#define SO_PEERSEC		31
-#define SO_PASSSEC		34
-#define SO_TIMESTAMPNS		35
-#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS
-
-#define SO_MARK			36
-
-#define SO_TIMESTAMPING		37
-#define SCM_TIMESTAMPING	SO_TIMESTAMPING
-
-#endif /* _ASM_X86_SOCKET_H */
+#include <asm-generic/socket.h>
diff --git a/arch/x86/include/asm/sockios.h b/arch/x86/include/asm/sockios.h
index 49cc72b..def6d47 100644
--- a/arch/x86/include/asm/sockios.h
+++ b/arch/x86/include/asm/sockios.h
@@ -1,13 +1 @@
-#ifndef _ASM_X86_SOCKIOS_H
-#define _ASM_X86_SOCKIOS_H
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN	0x8901
-#define SIOCSPGRP	0x8902
-#define FIOGETOWN	0x8903
-#define SIOCGPGRP	0x8904
-#define SIOCATMARK	0x8905
-#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */
-#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */
-
-#endif /* _ASM_X86_SOCKIOS_H */
+#include <asm-generic/sockios.h>
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index c2d742c..1575177 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -48,7 +48,7 @@
  * head_32 for boot CPU and setup_per_cpu_areas() for others.
  */
 #define GDT_STACK_CANARY_INIT						\
-	[GDT_ENTRY_STACK_CANARY] = { { { 0x00000018, 0x00409000 } } },
+	[GDT_ENTRY_STACK_CANARY] = GDT_ENTRY_INIT(0x4090, 0, 0x18),
 
 /*
  * Initialize the stackprotector canary value.
@@ -78,21 +78,19 @@ static __always_inline void boot_init_stack_canary(void)
 #ifdef CONFIG_X86_64
 	percpu_write(irq_stack_union.stack_canary, canary);
 #else
-	percpu_write(stack_canary, canary);
+	percpu_write(stack_canary.canary, canary);
 #endif
 }
 
 static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
-	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu) - 20;
+	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
 	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
 	struct desc_struct desc;
 
 	desc = gdt_table[GDT_ENTRY_STACK_CANARY];
-	desc.base0 = canary & 0xffff;
-	desc.base1 = (canary >> 16) & 0xff;
-	desc.base2 = (canary >> 24) & 0xff;
+	set_desc_base(&desc, canary);
 	write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S);
 #endif
 }
diff --git a/arch/x86/include/asm/string_32.h b/arch/x86/include/asm/string_32.h
index c86f452..ae907e6 100644
--- a/arch/x86/include/asm/string_32.h
+++ b/arch/x86/include/asm/string_32.h
@@ -65,7 +65,6 @@ static __always_inline void *__constant_memcpy(void *to, const void *from,
 	case 4:
 		*(int *)to = *(int *)from;
 		return to;
-
 	case 3:
 		*(short *)to = *(short *)from;
 		*((char *)to + 2) = *((char *)from + 2);
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 643c59b..f08f973 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -31,7 +31,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
 	"movl %P[task_canary](%[next]), %%ebx\n\t"			\
 	"movl %%ebx, "__percpu_arg([stack_canary])"\n\t"
 #define __switch_canary_oparam						\
-	, [stack_canary] "=m" (per_cpu_var(stack_canary))
+	, [stack_canary] "=m" (per_cpu_var(stack_canary.canary))
 #define __switch_canary_iparam						\
 	, [task_canary] "i" (offsetof(struct task_struct, stack_canary))
 #else	/* CC_STACKPROTECTOR */
@@ -150,33 +150,6 @@ do {									\
 #endif
 
 #ifdef __KERNEL__
-#define _set_base(addr, base) do { unsigned long __pr; \
-__asm__ __volatile__ ("movw %%dx,%1\n\t" \
-	"rorl $16,%%edx\n\t" \
-	"movb %%dl,%2\n\t" \
-	"movb %%dh,%3" \
-	:"=&d" (__pr) \
-	:"m" (*((addr)+2)), \
-	 "m" (*((addr)+4)), \
-	 "m" (*((addr)+7)), \
-	 "0" (base) \
-	); } while (0)
-
-#define _set_limit(addr, limit) do { unsigned long __lr; \
-__asm__ __volatile__ ("movw %%dx,%1\n\t" \
-	"rorl $16,%%edx\n\t" \
-	"movb %2,%%dh\n\t" \
-	"andb $0xf0,%%dh\n\t" \
-	"orb %%dh,%%dl\n\t" \
-	"movb %%dl,%2" \
-	:"=&d" (__lr) \
-	:"m" (*(addr)), \
-	 "m" (*((addr)+6)), \
-	 "0" (limit) \
-	); } while (0)
-
-#define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base))
-#define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1))
 
 extern void native_load_gs_index(unsigned);
 
diff --git a/arch/x86/include/asm/termbits.h b/arch/x86/include/asm/termbits.h
index af1b70e..3935b10 100644
--- a/arch/x86/include/asm/termbits.h
+++ b/arch/x86/include/asm/termbits.h
@@ -1,198 +1 @@
-#ifndef _ASM_X86_TERMBITS_H
-#define _ASM_X86_TERMBITS_H
-
-#include <linux/posix_types.h>
-
-typedef unsigned char	cc_t;
-typedef unsigned int	speed_t;
-typedef unsigned int	tcflag_t;
-
-#define NCCS 19
-struct termios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-};
-
-struct termios2 {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-struct ktermios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-/* c_iflag bits */
-#define IGNBRK	0000001
-#define BRKINT	0000002
-#define IGNPAR	0000004
-#define PARMRK	0000010
-#define INPCK	0000020
-#define ISTRIP	0000040
-#define INLCR	0000100
-#define IGNCR	0000200
-#define ICRNL	0000400
-#define IUCLC	0001000
-#define IXON	0002000
-#define IXANY	0004000
-#define IXOFF	0010000
-#define IMAXBEL	0020000
-#define IUTF8	0040000
-
-/* c_oflag bits */
-#define OPOST	0000001
-#define OLCUC	0000002
-#define ONLCR	0000004
-#define OCRNL	0000010
-#define ONOCR	0000020
-#define ONLRET	0000040
-#define OFILL	0000100
-#define OFDEL	0000200
-#define NLDLY	0000400
-#define   NL0	0000000
-#define   NL1	0000400
-#define CRDLY	0003000
-#define   CR0	0000000
-#define   CR1	0001000
-#define   CR2	0002000
-#define   CR3	0003000
-#define TABDLY	0014000
-#define   TAB0	0000000
-#define   TAB1	0004000
-#define   TAB2	0010000
-#define   TAB3	0014000
-#define   XTABS	0014000
-#define BSDLY	0020000
-#define   BS0	0000000
-#define   BS1	0020000
-#define VTDLY	0040000
-#define   VT0	0000000
-#define   VT1	0040000
-#define FFDLY	0100000
-#define   FF0	0000000
-#define   FF1	0100000
-
-/* c_cflag bit meaning */
-#define CBAUD	0010017
-#define  B0	0000000		/* hang up */
-#define  B50	0000001
-#define  B75	0000002
-#define  B110	0000003
-#define  B134	0000004
-#define  B150	0000005
-#define  B200	0000006
-#define  B300	0000007
-#define  B600	0000010
-#define  B1200	0000011
-#define  B1800	0000012
-#define  B2400	0000013
-#define  B4800	0000014
-#define  B9600	0000015
-#define  B19200	0000016
-#define  B38400	0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE	0000060
-#define   CS5	0000000
-#define   CS6	0000020
-#define   CS7	0000040
-#define   CS8	0000060
-#define CSTOPB	0000100
-#define CREAD	0000200
-#define PARENB	0000400
-#define PARODD	0001000
-#define HUPCL	0002000
-#define CLOCAL	0004000
-#define CBAUDEX 0010000
-#define	   BOTHER 0010000		/* non standard rate */
-#define    B57600 0010001
-#define   B115200 0010002
-#define   B230400 0010003
-#define   B460800 0010004
-#define   B500000 0010005
-#define   B576000 0010006
-#define   B921600 0010007
-#define  B1000000 0010010
-#define  B1152000 0010011
-#define  B1500000 0010012
-#define  B2000000 0010013
-#define  B2500000 0010014
-#define  B3000000 0010015
-#define  B3500000 0010016
-#define  B4000000 0010017
-#define CIBAUD	  002003600000	/* input baud rate */
-#define CMSPAR	  010000000000	/* mark or space (stick) parity */
-#define CRTSCTS	  020000000000	/* flow control */
-
-#define IBSHIFT	  16		/* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG	0000001
-#define ICANON	0000002
-#define XCASE	0000004
-#define ECHO	0000010
-#define ECHOE	0000020
-#define ECHOK	0000040
-#define ECHONL	0000100
-#define NOFLSH	0000200
-#define TOSTOP	0000400
-#define ECHOCTL	0001000
-#define ECHOPRT	0002000
-#define ECHOKE	0004000
-#define FLUSHO	0010000
-#define PENDIN	0040000
-#define IEXTEN	0100000
-
-/* tcflow() and TCXONC use these */
-#define	TCOOFF		0
-#define	TCOON		1
-#define	TCIOFF		2
-#define	TCION		3
-
-/* tcflush() and TCFLSH use these */
-#define	TCIFLUSH	0
-#define	TCOFLUSH	1
-#define	TCIOFLUSH	2
-
-/* tcsetattr uses these */
-#define	TCSANOW		0
-#define	TCSADRAIN	1
-#define	TCSAFLUSH	2
-
-#endif /* _ASM_X86_TERMBITS_H */
+#include <asm-generic/termbits.h>
diff --git a/arch/x86/include/asm/termios.h b/arch/x86/include/asm/termios.h
index c4ee805..280d78a 100644
--- a/arch/x86/include/asm/termios.h
+++ b/arch/x86/include/asm/termios.h
@@ -1,114 +1 @@
-#ifndef _ASM_X86_TERMIOS_H
-#define _ASM_X86_TERMIOS_H
-
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
-	unsigned short c_iflag;		/* input mode flags */
-	unsigned short c_oflag;		/* output mode flags */
-	unsigned short c_cflag;		/* control mode flags */
-	unsigned short c_lflag;		/* local mode flags */
-	unsigned char c_line;		/* line discipline */
-	unsigned char c_cc[NCC];	/* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE	0x001
-#define TIOCM_DTR	0x002
-#define TIOCM_RTS	0x004
-#define TIOCM_ST	0x008
-#define TIOCM_SR	0x010
-#define TIOCM_CTS	0x020
-#define TIOCM_CAR	0x040
-#define TIOCM_RNG	0x080
-#define TIOCM_DSR	0x100
-#define TIOCM_CD	TIOCM_CAR
-#define TIOCM_RI	TIOCM_RNG
-#define TIOCM_OUT1	0x2000
-#define TIOCM_OUT2	0x4000
-#define TIOCM_LOOP	0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
-
-#include <asm/uaccess.h>
-
-/*	intr=^C		quit=^\		erase=del	kill=^U
-	eof=^D		vtime=\0	vmin=\1		sxtc=\0
-	start=^Q	stop=^S		susp=^Z		eol=\0
-	reprint=^R	discard=^U	werase=^W	lnext=^V
-	eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-
-/*
- * Translate a "termio" structure into a "termios". Ugh.
- */
-#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
-	unsigned short __tmp; \
-	get_user(__tmp,&(termio)->x); \
-	*(unsigned short *) &(termios)->x = __tmp; \
-}
-
-static inline int user_termio_to_kernel_termios(struct ktermios *termios,
-						struct termio __user *termio)
-{
-	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag);
-	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag);
-	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag);
-	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag);
-	get_user(termios->c_line, &termio->c_line);
-	return copy_from_user(termios->c_cc, termio->c_cc, NCC);
-}
-
-/*
- * Translate a "termios" structure into a "termio". Ugh.
- */
-static inline int kernel_termios_to_user_termio(struct termio __user *termio,
-					    struct ktermios *termios)
-{
-	put_user((termios)->c_iflag, &(termio)->c_iflag);
-	put_user((termios)->c_oflag, &(termio)->c_oflag);
-	put_user((termios)->c_cflag, &(termio)->c_cflag);
-	put_user((termios)->c_lflag, &(termio)->c_lflag);
-	put_user((termios)->c_line,  &(termio)->c_line);
-	return copy_to_user((termio)->c_cc, (termios)->c_cc, NCC);
-}
-
-static inline int user_termios_to_kernel_termios(struct ktermios *k,
-						 struct termios2 __user *u)
-{
-	return copy_from_user(k, u, sizeof(struct termios2));
-}
-
-static inline int kernel_termios_to_user_termios(struct termios2 __user *u,
-						 struct ktermios *k)
-{
-	return copy_to_user(u, k, sizeof(struct termios2));
-}
-
-static inline int user_termios_to_kernel_termios_1(struct ktermios *k,
-						   struct termios __user *u)
-{
-	return copy_from_user(k, u, sizeof(struct termios));
-}
-
-static inline int kernel_termios_to_user_termios_1(struct termios __user *u,
-						   struct ktermios *k)
-{
-	return copy_to_user(u, k, sizeof(struct termios));
-}
-
-#endif	/* __KERNEL__ */
-
-#endif /* _ASM_X86_TERMIOS_H */
+#include <asm-generic/termios.h>
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 6f7786a..d27d0a2 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -214,7 +214,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack);
 static inline struct thread_info *current_thread_info(void)
 {
 	struct thread_info *ti;
-	ti = (void *)(percpu_read(kernel_stack) +
+	ti = (void *)(percpu_read_stable(kernel_stack) +
 		      KERNEL_STACK_OFFSET - THREAD_SIZE);
 	return ti;
 }
diff --git a/arch/x86/include/asm/time.h b/arch/x86/include/asm/time.h
index 50c733a..7bdec4e 100644
--- a/arch/x86/include/asm/time.h
+++ b/arch/x86/include/asm/time.h
@@ -4,60 +4,7 @@
 extern void hpet_time_init(void);
 
 #include <asm/mc146818rtc.h>
-#ifdef CONFIG_X86_32
-#include <linux/efi.h>
-
-static inline unsigned long native_get_wallclock(void)
-{
-	unsigned long retval;
-
-	if (efi_enabled)
-		retval = efi_get_time();
-	else
-		retval = mach_get_cmos_time();
-
-	return retval;
-}
-
-static inline int native_set_wallclock(unsigned long nowtime)
-{
-	int retval;
-
-	if (efi_enabled)
-		retval = efi_set_rtc_mmss(nowtime);
-	else
-		retval = mach_set_rtc_mmss(nowtime);
-
-	return retval;
-}
-
-#else
-extern void native_time_init_hook(void);
-
-static inline unsigned long native_get_wallclock(void)
-{
-	return mach_get_cmos_time();
-}
-
-static inline int native_set_wallclock(unsigned long nowtime)
-{
-	return mach_set_rtc_mmss(nowtime);
-}
-
-#endif
 
 extern void time_init(void);
 
-#ifdef CONFIG_PARAVIRT
-#include <asm/paravirt.h>
-#else /* !CONFIG_PARAVIRT */
-
-#define get_wallclock() native_get_wallclock()
-#define set_wallclock(x) native_set_wallclock(x)
-#define choose_time_init() hpet_time_init
-
-#endif /* CONFIG_PARAVIRT */
-
-extern unsigned long __init calibrate_cpu(void);
-
 #endif /* _ASM_X86_TIME_H */
diff --git a/arch/x86/include/asm/timer.h b/arch/x86/include/asm/timer.h
index 20ca9c4..5469630 100644
--- a/arch/x86/include/asm/timer.h
+++ b/arch/x86/include/asm/timer.h
@@ -8,20 +8,16 @@
 #define TICK_SIZE (tick_nsec / 1000)
 
 unsigned long long native_sched_clock(void);
-unsigned long native_calibrate_tsc(void);
+extern int recalibrate_cpu_khz(void);
 
-#ifdef CONFIG_X86_32
+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
 extern int timer_ack;
-extern irqreturn_t timer_interrupt(int irq, void *dev_id);
-#endif /* CONFIG_X86_32 */
-extern int recalibrate_cpu_khz(void);
+#else
+# define timer_ack (0)
+#endif
 
 extern int no_timer_check;
 
-#ifndef CONFIG_PARAVIRT
-#define calibrate_tsc() native_calibrate_tsc()
-#endif
-
 /* Accelerators for sched_clock()
  * convert from cycles(64bits) => nanoseconds (64bits)
  *  basic equation:
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 26d06e0..6f0695d 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -116,15 +116,11 @@ extern unsigned long node_remap_size[];
 
 # define SD_CACHE_NICE_TRIES	1
 # define SD_IDLE_IDX		1
-# define SD_NEWIDLE_IDX		2
-# define SD_FORKEXEC_IDX	0
 
 #else
 
 # define SD_CACHE_NICE_TRIES	2
 # define SD_IDLE_IDX		2
-# define SD_NEWIDLE_IDX		2
-# define SD_FORKEXEC_IDX	1
 
 #endif
 
@@ -137,22 +133,20 @@ extern unsigned long node_remap_size[];
 	.cache_nice_tries	= SD_CACHE_NICE_TRIES,			\
 	.busy_idx		= 3,					\
 	.idle_idx		= SD_IDLE_IDX,				\
-	.newidle_idx		= SD_NEWIDLE_IDX,			\
-	.wake_idx		= 1,					\
-	.forkexec_idx		= SD_FORKEXEC_IDX,			\
+	.newidle_idx		= 0,					\
+	.wake_idx		= 0,					\
+	.forkexec_idx		= 0,					\
 									\
 	.flags			= 1*SD_LOAD_BALANCE			\
 				| 1*SD_BALANCE_NEWIDLE			\
 				| 1*SD_BALANCE_EXEC			\
 				| 1*SD_BALANCE_FORK			\
-				| 0*SD_WAKE_IDLE			\
+				| 0*SD_BALANCE_WAKE			\
 				| 1*SD_WAKE_AFFINE			\
-				| 1*SD_WAKE_BALANCE			\
 				| 0*SD_SHARE_CPUPOWER			\
 				| 0*SD_POWERSAVINGS_BALANCE		\
 				| 0*SD_SHARE_PKG_RESOURCES		\
 				| 1*SD_SERIALIZE			\
-				| 1*SD_WAKE_IDLE_FAR			\
 				| 0*SD_PREFER_SIBLING			\
 				,					\
 	.last_balance		= jiffies,				\
diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index bfd74c0..4da91ad 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -81,9 +81,7 @@ extern int panic_on_unrecovered_nmi;
 
 void math_error(void __user *);
 void math_emulate(struct math_emu_info *);
-#ifdef CONFIG_X86_32
-unsigned long patch_espfix_desc(unsigned long, unsigned long);
-#else
+#ifndef CONFIG_X86_32
 asmlinkage void smp_thermal_interrupt(void);
 asmlinkage void mce_threshold_interrupt(void);
 #endif
diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h
index 38ae163..c042729 100644
--- a/arch/x86/include/asm/tsc.h
+++ b/arch/x86/include/asm/tsc.h
@@ -48,7 +48,8 @@ static __always_inline cycles_t vget_cycles(void)
 extern void tsc_init(void);
 extern void mark_tsc_unstable(char *reason);
 extern int unsynchronized_tsc(void);
-int check_tsc_unstable(void);
+extern int check_tsc_unstable(void);
+extern unsigned long native_calibrate_tsc(void);
 
 /*
  * Boot-time check whether the TSCs are synchronized across
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index 09b9774..df1da20 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -1,19 +1,11 @@
 #ifndef _ASM_X86_TYPES_H
 #define _ASM_X86_TYPES_H
 
-#include <asm-generic/int-ll64.h>
+#define dma_addr_t	dma_addr_t
 
-#ifndef __ASSEMBLY__
-
-typedef unsigned short umode_t;
+#include <asm-generic/types.h>
 
-#endif /* __ASSEMBLY__ */
-
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
 #ifdef __KERNEL__
-
 #ifndef __ASSEMBLY__
 
 typedef u64 dma64_addr_t;
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
index 5e06259..632fb44 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
@@ -33,7 +33,7 @@ unsigned long __must_check __copy_from_user_ll_nocache_nozero
  * Copy data from kernel space to user space.  Caller must check
  * the specified block with access_ok() before calling this function.
  * The caller should also make sure he pins the user space address
- * so that the we don't result in page fault and sleep.
+ * so that we don't result in page fault and sleep.
  *
  * Here we special-case 1, 2 and 4-byte copy_*_user invocations.  On a fault
  * we return the initial request size (1, 2 or 4), as copy_*_user should do.
diff --git a/arch/x86/include/asm/ucontext.h b/arch/x86/include/asm/ucontext.h
index 87324cf..b7c29c8 100644
--- a/arch/x86/include/asm/ucontext.h
+++ b/arch/x86/include/asm/ucontext.h
@@ -7,12 +7,6 @@
 				 * sigcontext struct (uc_mcontext).
 				 */
 
-struct ucontext {
-	unsigned long	  uc_flags;
-	struct ucontext  *uc_link;
-	stack_t		  uc_stack;
-	struct sigcontext uc_mcontext;
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
+#include <asm-generic/ucontext.h>
 
 #endif /* _ASM_X86_UCONTEXT_H */
diff --git a/arch/x86/include/asm/unistd_32.h b/arch/x86/include/asm/unistd_32.h
index 8deaada..6fb3c20 100644
--- a/arch/x86/include/asm/unistd_32.h
+++ b/arch/x86/include/asm/unistd_32.h
@@ -341,7 +341,7 @@
 #define __NR_preadv		333
 #define __NR_pwritev		334
 #define __NR_rt_tgsigqueueinfo	335
-#define __NR_perf_counter_open	336
+#define __NR_perf_event_open	336
 
 #ifdef __KERNEL__
 
diff --git a/arch/x86/include/asm/unistd_64.h b/arch/x86/include/asm/unistd_64.h
index b9f3c60..8d3ad0a 100644
--- a/arch/x86/include/asm/unistd_64.h
+++ b/arch/x86/include/asm/unistd_64.h
@@ -659,8 +659,8 @@ __SYSCALL(__NR_preadv, sys_preadv)
 __SYSCALL(__NR_pwritev, sys_pwritev)
 #define __NR_rt_tgsigqueueinfo			297
 __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
-#define __NR_perf_counter_open			298
-__SYSCALL(__NR_perf_counter_open, sys_perf_counter_open)
+#define __NR_perf_event_open			298
+__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
 
 #ifndef __NO_STUBS
 #define __ARCH_WANT_OLD_READDIR
diff --git a/arch/x86/include/asm/uv/uv_hub.h b/arch/x86/include/asm/uv/uv_hub.h
index 77a6850..04eb6c9 100644
--- a/arch/x86/include/asm/uv/uv_hub.h
+++ b/arch/x86/include/asm/uv/uv_hub.h
@@ -15,6 +15,7 @@
 #include <linux/numa.h>
 #include <linux/percpu.h>
 #include <linux/timer.h>
+#include <linux/io.h>
 #include <asm/types.h>
 #include <asm/percpu.h>
 #include <asm/uv/uv_mmrs.h>
@@ -258,13 +259,13 @@ static inline unsigned long *uv_global_mmr32_address(int pnode,
 static inline void uv_write_global_mmr32(int pnode, unsigned long offset,
 				 unsigned long val)
 {
-	*uv_global_mmr32_address(pnode, offset) = val;
+	writeq(val, uv_global_mmr32_address(pnode, offset));
 }
 
 static inline unsigned long uv_read_global_mmr32(int pnode,
 						 unsigned long offset)
 {
-	return *uv_global_mmr32_address(pnode, offset);
+	return readq(uv_global_mmr32_address(pnode, offset));
 }
 
 /*
@@ -281,13 +282,13 @@ static inline unsigned long *uv_global_mmr64_address(int pnode,
 static inline void uv_write_global_mmr64(int pnode, unsigned long offset,
 				unsigned long val)
 {
-	*uv_global_mmr64_address(pnode, offset) = val;
+	writeq(val, uv_global_mmr64_address(pnode, offset));
 }
 
 static inline unsigned long uv_read_global_mmr64(int pnode,
 						 unsigned long offset)
 {
-	return *uv_global_mmr64_address(pnode, offset);
+	return readq(uv_global_mmr64_address(pnode, offset));
 }
 
 /*
@@ -301,22 +302,22 @@ static inline unsigned long *uv_local_mmr_address(unsigned long offset)
 
 static inline unsigned long uv_read_local_mmr(unsigned long offset)
 {
-	return *uv_local_mmr_address(offset);
+	return readq(uv_local_mmr_address(offset));
 }
 
 static inline void uv_write_local_mmr(unsigned long offset, unsigned long val)
 {
-	*uv_local_mmr_address(offset) = val;
+	writeq(val, uv_local_mmr_address(offset));
 }
 
 static inline unsigned char uv_read_local_mmr8(unsigned long offset)
 {
-	return *((unsigned char *)uv_local_mmr_address(offset));
+	return readb(uv_local_mmr_address(offset));
 }
 
 static inline void uv_write_local_mmr8(unsigned long offset, unsigned char val)
 {
-	*((unsigned char *)uv_local_mmr_address(offset)) = val;
+	writeb(val, uv_local_mmr_address(offset));
 }
 
 /*
@@ -422,7 +423,7 @@ static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)
 	unsigned long val;
 
 	val = (1UL << UVH_IPI_INT_SEND_SHFT) |
-			((apicid & 0x3f) << UVH_IPI_INT_APIC_ID_SHFT) |
+			((apicid) << UVH_IPI_INT_APIC_ID_SHFT) |
 			(vector << UVH_IPI_INT_VECTOR_SHFT);
 	uv_write_global_mmr64(pnode, UVH_IPI_INT, val);
 }
diff --git a/arch/x86/include/asm/vgtod.h b/arch/x86/include/asm/vgtod.h
index dc27a69..3d61e20 100644
--- a/arch/x86/include/asm/vgtod.h
+++ b/arch/x86/include/asm/vgtod.h
@@ -21,6 +21,7 @@ struct vsyscall_gtod_data {
 		u32	shift;
 	} clock;
 	struct timespec wall_to_monotonic;
+	struct timespec wall_time_coarse;
 };
 extern struct vsyscall_gtod_data __vsyscall_gtod_data
 __section_vsyscall_gtod_data;
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index c11b7e1..e49ed6d 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -20,7 +20,7 @@
 #ifndef ASM_X86__VMWARE_H
 #define ASM_X86__VMWARE_H
 
-extern unsigned long vmware_get_tsc_khz(void);
+extern void vmware_platform_setup(void);
 extern int vmware_platform(void);
 extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
 
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h
index 11be5ad..272514c 100644
--- a/arch/x86/include/asm/vmx.h
+++ b/arch/x86/include/asm/vmx.h
@@ -55,6 +55,7 @@
 #define SECONDARY_EXEC_ENABLE_EPT               0x00000002
 #define SECONDARY_EXEC_ENABLE_VPID              0x00000020
 #define SECONDARY_EXEC_WBINVD_EXITING		0x00000040
+#define SECONDARY_EXEC_UNRESTRICTED_GUEST	0x00000080
 
 
 #define PIN_BASED_EXT_INTR_MASK                 0x00000001
@@ -351,9 +352,16 @@ enum vmcs_field {
 #define VMX_EPT_EXTENT_INDIVIDUAL_ADDR		0
 #define VMX_EPT_EXTENT_CONTEXT			1
 #define VMX_EPT_EXTENT_GLOBAL			2
+
+#define VMX_EPT_EXECUTE_ONLY_BIT		(1ull)
+#define VMX_EPT_PAGE_WALK_4_BIT			(1ull << 6)
+#define VMX_EPTP_UC_BIT				(1ull << 8)
+#define VMX_EPTP_WB_BIT				(1ull << 14)
+#define VMX_EPT_2MB_PAGE_BIT			(1ull << 16)
 #define VMX_EPT_EXTENT_INDIVIDUAL_BIT		(1ull << 24)
 #define VMX_EPT_EXTENT_CONTEXT_BIT		(1ull << 25)
 #define VMX_EPT_EXTENT_GLOBAL_BIT		(1ull << 26)
+
 #define VMX_EPT_DEFAULT_GAW			3
 #define VMX_EPT_MAX_GAW				0x4
 #define VMX_EPT_MT_EPTE_SHIFT			3
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
new file mode 100644
index 0000000..2c756fd
--- /dev/null
+++ b/arch/x86/include/asm/x86_init.h
@@ -0,0 +1,133 @@
+#ifndef _ASM_X86_PLATFORM_H
+#define _ASM_X86_PLATFORM_H
+
+#include <asm/pgtable_types.h>
+#include <asm/bootparam.h>
+
+struct mpc_bus;
+struct mpc_cpu;
+struct mpc_table;
+
+/**
+ * struct x86_init_mpparse - platform specific mpparse ops
+ * @mpc_record:			platform specific mpc record accounting
+ * @setup_ioapic_ids:		platform specific ioapic id override
+ * @mpc_apic_id:		platform specific mpc apic id assignment
+ * @smp_read_mpc_oem:		platform specific oem mpc table setup
+ * @mpc_oem_pci_bus:		platform specific pci bus setup (default NULL)
+ * @mpc_oem_bus_info:		platform specific mpc bus info
+ * @find_smp_config:		find the smp configuration
+ * @get_smp_config:		get the smp configuration
+ */
+struct x86_init_mpparse {
+	void (*mpc_record)(unsigned int mode);
+	void (*setup_ioapic_ids)(void);
+	int (*mpc_apic_id)(struct mpc_cpu *m);
+	void (*smp_read_mpc_oem)(struct mpc_table *mpc);
+	void (*mpc_oem_pci_bus)(struct mpc_bus *m);
+	void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
+	void (*find_smp_config)(unsigned int reserve);
+	void (*get_smp_config)(unsigned int early);
+};
+
+/**
+ * struct x86_init_resources - platform specific resource related ops
+ * @probe_roms:			probe BIOS roms
+ * @reserve_resources:		reserve the standard resources for the
+ *				platform
+ * @memory_setup:		platform specific memory setup
+ *
+ */
+struct x86_init_resources {
+	void (*probe_roms)(void);
+	void (*reserve_resources)(void);
+	char *(*memory_setup)(void);
+};
+
+/**
+ * struct x86_init_irqs - platform specific interrupt setup
+ * @pre_vector_init:		init code to run before interrupt vectors
+ *				are set up.
+ * @intr_init:			interrupt init code
+ * @trap_init:			platform specific trap setup
+ */
+struct x86_init_irqs {
+	void (*pre_vector_init)(void);
+	void (*intr_init)(void);
+	void (*trap_init)(void);
+};
+
+/**
+ * struct x86_init_oem - oem platform specific customizing functions
+ * @arch_setup:			platform specific architecure setup
+ * @banner:			print a platform specific banner
+ */
+struct x86_init_oem {
+	void (*arch_setup)(void);
+	void (*banner)(void);
+};
+
+/**
+ * struct x86_init_paging - platform specific paging functions
+ * @pagetable_setup_start:	platform specific pre paging_init() call
+ * @pagetable_setup_done:	platform specific post paging_init() call
+ */
+struct x86_init_paging {
+	void (*pagetable_setup_start)(pgd_t *base);
+	void (*pagetable_setup_done)(pgd_t *base);
+};
+
+/**
+ * struct x86_init_timers - platform specific timer setup
+ * @setup_perpcu_clockev:	set up the per cpu clock event device for the
+ *				boot cpu
+ * @tsc_pre_init:		platform function called before TSC init
+ * @timer_init:			initialize the platform timer (default PIT/HPET)
+ */
+struct x86_init_timers {
+	void (*setup_percpu_clockev)(void);
+	void (*tsc_pre_init)(void);
+	void (*timer_init)(void);
+};
+
+/**
+ * struct x86_init_ops - functions for platform specific setup
+ *
+ */
+struct x86_init_ops {
+	struct x86_init_resources	resources;
+	struct x86_init_mpparse		mpparse;
+	struct x86_init_irqs		irqs;
+	struct x86_init_oem		oem;
+	struct x86_init_paging		paging;
+	struct x86_init_timers		timers;
+};
+
+/**
+ * struct x86_cpuinit_ops - platform specific cpu hotplug setups
+ * @setup_percpu_clockev:	set up the per cpu clock event device
+ */
+struct x86_cpuinit_ops {
+	void (*setup_percpu_clockev)(void);
+};
+
+/**
+ * struct x86_platform_ops - platform specific runtime functions
+ * @calibrate_tsc:		calibrate TSC
+ * @get_wallclock:		get time from HW clock like RTC etc.
+ * @set_wallclock:		set time back to HW clock
+ */
+struct x86_platform_ops {
+	unsigned long (*calibrate_tsc)(void);
+	unsigned long (*get_wallclock)(void);
+	int (*set_wallclock)(unsigned long nowtime);
+};
+
+extern struct x86_init_ops x86_init;
+extern struct x86_cpuinit_ops x86_cpuinit;
+extern struct x86_platform_ops x86_platform;
+
+extern void x86_init_noop(void);
+extern void x86_init_uint_noop(unsigned int unused);
+
+#endif
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 430d5b2..4ba419b 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -31,8 +31,8 @@ GCOV_PROFILE_paravirt.o		:= n
 
 obj-y			:= process_$(BITS).o signal.o entry_$(BITS).o
 obj-y			+= traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
-obj-y			+= time_$(BITS).o ioport.o ldt.o dumpstack.o
-obj-y			+= setup.o i8259.o irqinit.o
+obj-y			+= time.o ioport.o ldt.o dumpstack.o
+obj-y			+= setup.o x86_init.o i8259.o irqinit.o
 obj-$(CONFIG_X86_VISWS)	+= visws_quirks.o
 obj-$(CONFIG_X86_32)	+= probe_roms_32.o
 obj-$(CONFIG_X86_32)	+= sys_i386_32.o i386_ksyms_32.o
@@ -52,6 +52,7 @@ obj-$(CONFIG_X86_DS_SELFTEST)		+= ds_selftest.o
 obj-$(CONFIG_X86_32)		+= tls.o
 obj-$(CONFIG_IA32_EMULATION)	+= tls.o
 obj-y				+= step.o
+obj-$(CONFIG_INTEL_TXT)		+= tboot.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
 obj-y				+= cpu/
 obj-y				+= acpi/
@@ -104,6 +105,7 @@ obj-$(CONFIG_SCx200)		+= scx200.o
 scx200-y			+= scx200_32.o
 
 obj-$(CONFIG_OLPC)		+= olpc.o
+obj-$(CONFIG_X86_MRST)		+= mrst.o
 
 microcode-y				:= microcode_core.o
 microcode-$(CONFIG_MICROCODE_INTEL)	+= microcode_intel.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 6b8ca3a..67e929b 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -833,106 +833,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
 extern int es7000_plat;
 #endif
 
-static struct {
-	int gsi_base;
-	int gsi_end;
-} mp_ioapic_routing[MAX_IO_APICS];
-
-int mp_find_ioapic(int gsi)
-{
-	int i = 0;
-
-	/* Find the IOAPIC that manages this GSI. */
-	for (i = 0; i < nr_ioapics; i++) {
-		if ((gsi >= mp_ioapic_routing[i].gsi_base)
-		    && (gsi <= mp_ioapic_routing[i].gsi_end))
-			return i;
-	}
-
-	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
-	return -1;
-}
-
-int mp_find_ioapic_pin(int ioapic, int gsi)
-{
-	if (WARN_ON(ioapic == -1))
-		return -1;
-	if (WARN_ON(gsi > mp_ioapic_routing[ioapic].gsi_end))
-		return -1;
-
-	return gsi - mp_ioapic_routing[ioapic].gsi_base;
-}
-
-static u8 __init uniq_ioapic_id(u8 id)
-{
-#ifdef CONFIG_X86_32
-	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
-	    !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
-		return io_apic_get_unique_id(nr_ioapics, id);
-	else
-		return id;
-#else
-	int i;
-	DECLARE_BITMAP(used, 256);
-	bitmap_zero(used, 256);
-	for (i = 0; i < nr_ioapics; i++) {
-		struct mpc_ioapic *ia = &mp_ioapics[i];
-		__set_bit(ia->apicid, used);
-	}
-	if (!test_bit(id, used))
-		return id;
-	return find_first_zero_bit(used, 256);
-#endif
-}
-
-static int bad_ioapic(unsigned long address)
-{
-	if (nr_ioapics >= MAX_IO_APICS) {
-		printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
-		       "(found %d)\n", MAX_IO_APICS, nr_ioapics);
-		panic("Recompile kernel with bigger MAX_IO_APICS!\n");
-	}
-	if (!address) {
-		printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
-		       " found in table, skipping!\n");
-		return 1;
-	}
-	return 0;
-}
-
-void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
-{
-	int idx = 0;
-
-	if (bad_ioapic(address))
-		return;
-
-	idx = nr_ioapics;
-
-	mp_ioapics[idx].type = MP_IOAPIC;
-	mp_ioapics[idx].flags = MPC_APIC_USABLE;
-	mp_ioapics[idx].apicaddr = address;
-
-	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-	mp_ioapics[idx].apicid = uniq_ioapic_id(id);
-	mp_ioapics[idx].apicver = io_apic_get_version(idx);
-
-	/*
-	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
-	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
-	 */
-	mp_ioapic_routing[idx].gsi_base = gsi_base;
-	mp_ioapic_routing[idx].gsi_end = gsi_base +
-	    io_apic_get_redir_entries(idx);
-
-	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
-	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
-	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
-	       mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end);
-
-	nr_ioapics++;
-}
-
 int __init acpi_probe_gsi(void)
 {
 	int idx;
@@ -947,7 +847,7 @@ int __init acpi_probe_gsi(void)
 
 	max_gsi = 0;
 	for (idx = 0; idx < nr_ioapics; idx++) {
-		gsi = mp_ioapic_routing[idx].gsi_end;
+		gsi = mp_gsi_routing[idx].gsi_end;
 
 		if (gsi > max_gsi)
 			max_gsi = gsi;
@@ -1179,9 +1079,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
 	 * If MPS is present, it will handle them,
 	 * otherwise the system will stay in PIC mode
 	 */
-	if (acpi_disabled || acpi_noirq) {
+	if (acpi_disabled || acpi_noirq)
 		return -ENODEV;
-	}
 
 	if (!cpu_has_apic)
 		return -ENODEV;
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index f576587..de7353c 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2,6 +2,7 @@
 #include <linux/sched.h>
 #include <linux/mutex.h>
 #include <linux/list.h>
+#include <linux/stringify.h>
 #include <linux/kprobes.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
@@ -32,7 +33,7 @@ __setup("smp-alt-boot", bootonly);
 #define smp_alt_once 1
 #endif
 
-static int debug_alternative;
+static int __initdata_or_module debug_alternative;
 
 static int __init debug_alt(char *str)
 {
@@ -51,7 +52,7 @@ static int __init setup_noreplace_smp(char *str)
 __setup("noreplace-smp", setup_noreplace_smp);
 
 #ifdef CONFIG_PARAVIRT
-static int noreplace_paravirt = 0;
+static int __initdata_or_module noreplace_paravirt = 0;
 
 static int __init setup_noreplace_paravirt(char *str)
 {
@@ -64,16 +65,17 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt);
 #define DPRINTK(fmt, args...) if (debug_alternative) \
 	printk(KERN_DEBUG fmt, args)
 
-#ifdef GENERIC_NOP1
+#if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64)
 /* Use inline assembly to define this because the nops are defined
    as inline assembly strings in the include files and we cannot
    get them easily into strings. */
-asm("\t.section .rodata, \"a\"\nintelnops: "
+asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nintelnops: "
 	GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
 	GENERIC_NOP7 GENERIC_NOP8
     "\t.previous");
 extern const unsigned char intelnops[];
-static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
+static const unsigned char *const __initconst_or_module
+intel_nops[ASM_NOP_MAX+1] = {
 	NULL,
 	intelnops,
 	intelnops + 1,
@@ -87,12 +89,13 @@ static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
 #endif
 
 #ifdef K8_NOP1
-asm("\t.section .rodata, \"a\"\nk8nops: "
+asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: "
 	K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
 	K8_NOP7 K8_NOP8
     "\t.previous");
 extern const unsigned char k8nops[];
-static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
+static const unsigned char *const __initconst_or_module
+k8_nops[ASM_NOP_MAX+1] = {
 	NULL,
 	k8nops,
 	k8nops + 1,
@@ -105,13 +108,14 @@ static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
 };
 #endif
 
-#ifdef K7_NOP1
-asm("\t.section .rodata, \"a\"\nk7nops: "
+#if defined(K7_NOP1) && !defined(CONFIG_X86_64)
+asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: "
 	K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
 	K7_NOP7 K7_NOP8
     "\t.previous");
 extern const unsigned char k7nops[];
-static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
+static const unsigned char *const __initconst_or_module
+k7_nops[ASM_NOP_MAX+1] = {
 	NULL,
 	k7nops,
 	k7nops + 1,
@@ -125,12 +129,13 @@ static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
 #endif
 
 #ifdef P6_NOP1
-asm("\t.section .rodata, \"a\"\np6nops: "
+asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: "
 	P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
 	P6_NOP7 P6_NOP8
     "\t.previous");
 extern const unsigned char p6nops[];
-static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
+static const unsigned char *const __initconst_or_module
+p6_nops[ASM_NOP_MAX+1] = {
 	NULL,
 	p6nops,
 	p6nops + 1,
@@ -146,7 +151,7 @@ static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
 #ifdef CONFIG_X86_64
 
 extern char __vsyscall_0;
-const unsigned char *const *find_nop_table(void)
+static const unsigned char *const *__init_or_module find_nop_table(void)
 {
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
 	    boot_cpu_has(X86_FEATURE_NOPL))
@@ -157,7 +162,7 @@ const unsigned char *const *find_nop_table(void)
 
 #else /* CONFIG_X86_64 */
 
-const unsigned char *const *find_nop_table(void)
+static const unsigned char *const *__init_or_module find_nop_table(void)
 {
 	if (boot_cpu_has(X86_FEATURE_K8))
 		return k8_nops;
@@ -172,7 +177,7 @@ const unsigned char *const *find_nop_table(void)
 #endif /* CONFIG_X86_64 */
 
 /* Use this to add nops to a buffer, then text_poke the whole buffer. */
-void add_nops(void *insns, unsigned int len)
+static void __init_or_module add_nops(void *insns, unsigned int len)
 {
 	const unsigned char *const *noptable = find_nop_table();
 
@@ -185,10 +190,10 @@ void add_nops(void *insns, unsigned int len)
 		len -= noplen;
 	}
 }
-EXPORT_SYMBOL_GPL(add_nops);
 
 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
 extern u8 *__smp_locks[], *__smp_locks_end[];
+static void *text_poke_early(void *addr, const void *opcode, size_t len);
 
 /* Replace instructions with better alternatives for this CPU type.
    This runs before SMP is initialized to avoid SMP problems with
@@ -196,7 +201,8 @@ extern u8 *__smp_locks[], *__smp_locks_end[];
    APs have less capabilities than the boot processor are not handled.
    Tough. Make sure you disable such features by hand. */
 
-void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
+void __init_or_module apply_alternatives(struct alt_instr *start,
+					 struct alt_instr *end)
 {
 	struct alt_instr *a;
 	char insnbuf[MAX_PATCH_LEN];
@@ -279,9 +285,10 @@ static LIST_HEAD(smp_alt_modules);
 static DEFINE_MUTEX(smp_alt);
 static int smp_mode = 1;	/* protected by smp_alt */
 
-void alternatives_smp_module_add(struct module *mod, char *name,
-				 void *locks, void *locks_end,
-				 void *text,  void *text_end)
+void __init_or_module alternatives_smp_module_add(struct module *mod,
+						  char *name,
+						  void *locks, void *locks_end,
+						  void *text,  void *text_end)
 {
 	struct smp_alt_module *smp;
 
@@ -317,7 +324,7 @@ void alternatives_smp_module_add(struct module *mod, char *name,
 	mutex_unlock(&smp_alt);
 }
 
-void alternatives_smp_module_del(struct module *mod)
+void __init_or_module alternatives_smp_module_del(struct module *mod)
 {
 	struct smp_alt_module *item;
 
@@ -386,8 +393,8 @@ void alternatives_smp_switch(int smp)
 #endif
 
 #ifdef CONFIG_PARAVIRT
-void apply_paravirt(struct paravirt_patch_site *start,
-		    struct paravirt_patch_site *end)
+void __init_or_module apply_paravirt(struct paravirt_patch_site *start,
+				     struct paravirt_patch_site *end)
 {
 	struct paravirt_patch_site *p;
 	char insnbuf[MAX_PATCH_LEN];
@@ -485,13 +492,14 @@ void __init alternative_instructions(void)
  * instructions. And on the local CPU you need to be protected again NMI or MCE
  * handlers seeing an inconsistent instruction while you patch.
  */
-void *text_poke_early(void *addr, const void *opcode, size_t len)
+static void *__init_or_module text_poke_early(void *addr, const void *opcode,
+					      size_t len)
 {
 	unsigned long flags;
 	local_irq_save(flags);
 	memcpy(addr, opcode, len);
-	local_irq_restore(flags);
 	sync_core();
+	local_irq_restore(flags);
 	/* Could also do a CLFLUSH here to speed up CPU recovery; but
 	   that causes hangs on some VIA CPUs. */
 	return addr;
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 0a1c283..894aa97 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -14,7 +14,7 @@
  *	Mikael Pettersson	:	PM converted to driver model.
  */
 
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/kernel_stat.h>
 #include <linux/mc146818rtc.h>
 #include <linux/acpi_pmtmr.h>
@@ -35,7 +35,8 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 
-#include <asm/perf_counter.h>
+#include <asm/perf_event.h>
+#include <asm/x86_init.h>
 #include <asm/pgalloc.h>
 #include <asm/atomic.h>
 #include <asm/mpspec.h>
@@ -49,6 +50,7 @@
 #include <asm/mtrr.h>
 #include <asm/smp.h>
 #include <asm/mce.h>
+#include <asm/kvm_para.h>
 
 unsigned int num_processors;
 
@@ -60,7 +62,7 @@ unsigned int boot_cpu_physical_apicid = -1U;
 /*
  * The highest APIC ID seen during enumeration.
  *
- * This determines the messaging protocol we can use: if all APIC IDs
+ * On AMD, this determines the messaging protocol we can use: if all APIC IDs
  * are in the 0 ... 7 range, then we can use logical addressing which
  * has some performance advantages (better broadcasting).
  *
@@ -977,7 +979,7 @@ void lapic_shutdown(void)
 {
 	unsigned long flags;
 
-	if (!cpu_has_apic)
+	if (!cpu_has_apic && !apic_from_smp_config())
 		return;
 
 	local_irq_save(flags);
@@ -1187,7 +1189,7 @@ void __cpuinit setup_local_APIC(void)
 		apic_write(APIC_ESR, 0);
 	}
 #endif
-	perf_counters_lapic_init();
+	perf_events_lapic_init();
 
 	preempt_disable();
 
@@ -1195,8 +1197,7 @@ void __cpuinit setup_local_APIC(void)
 	 * Double-check whether this APIC is really registered.
 	 * This is meaningless in clustered apic mode, so we skip it.
 	 */
-	if (!apic->apic_id_registered())
-		BUG();
+	BUG_ON(!apic->apic_id_registered());
 
 	/*
 	 * Intel recommends to set DFR, LDR and TPR before enabling
@@ -1361,52 +1362,80 @@ void enable_x2apic(void)
 }
 #endif /* CONFIG_X86_X2APIC */
 
-void __init enable_IR_x2apic(void)
+int __init enable_IR(void)
 {
 #ifdef CONFIG_INTR_REMAP
-	int ret;
-	unsigned long flags;
-	struct IO_APIC_route_entry **ioapic_entries = NULL;
-
-	ret = dmar_table_init();
-	if (ret) {
-		pr_debug("dmar_table_init() failed with %d:\n", ret);
-		goto ir_failed;
-	}
-
 	if (!intr_remapping_supported()) {
 		pr_debug("intr-remapping not supported\n");
-		goto ir_failed;
+		return 0;
 	}
 
-
 	if (!x2apic_preenabled && skip_ioapic_setup) {
 		pr_info("Skipped enabling intr-remap because of skipping "
 			"io-apic setup\n");
-		return;
+		return 0;
 	}
 
+	if (enable_intr_remapping(x2apic_supported()))
+		return 0;
+
+	pr_info("Enabled Interrupt-remapping\n");
+
+	return 1;
+
+#endif
+	return 0;
+}
+
+void __init enable_IR_x2apic(void)
+{
+	unsigned long flags;
+	struct IO_APIC_route_entry **ioapic_entries = NULL;
+	int ret, x2apic_enabled = 0;
+	int dmar_table_init_ret = 0;
+
+#ifdef CONFIG_INTR_REMAP
+	dmar_table_init_ret = dmar_table_init();
+	if (dmar_table_init_ret)
+		pr_debug("dmar_table_init() failed with %d:\n",
+				dmar_table_init_ret);
+#endif
+
 	ioapic_entries = alloc_ioapic_entries();
 	if (!ioapic_entries) {
-		pr_info("Allocate ioapic_entries failed: %d\n", ret);
-		goto end;
+		pr_err("Allocate ioapic_entries failed\n");
+		goto out;
 	}
 
 	ret = save_IO_APIC_setup(ioapic_entries);
 	if (ret) {
 		pr_info("Saving IO-APIC state failed: %d\n", ret);
-		goto end;
+		goto out;
 	}
 
 	local_irq_save(flags);
-	mask_IO_APIC_setup(ioapic_entries);
 	mask_8259A();
+	mask_IO_APIC_setup(ioapic_entries);
 
-	ret = enable_intr_remapping(x2apic_supported());
-	if (ret)
-		goto end_restore;
+	if (dmar_table_init_ret)
+		ret = 0;
+	else
+		ret = enable_IR();
 
-	pr_info("Enabled Interrupt-remapping\n");
+	if (!ret) {
+		/* IR is required if there is APIC ID > 255 even when running
+		 * under KVM
+		 */
+		if (max_physical_apicid > 255 || !kvm_para_available())
+			goto nox2apic;
+		/*
+		 * without IR all CPUs can be addressed by IOAPIC/MSI
+		 * only in physical mode
+		 */
+		x2apic_force_phys();
+	}
+
+	x2apic_enabled = 1;
 
 	if (x2apic_supported() && !x2apic_mode) {
 		x2apic_mode = 1;
@@ -1414,41 +1443,25 @@ void __init enable_IR_x2apic(void)
 		pr_info("Enabled x2apic\n");
 	}
 
-end_restore:
-	if (ret)
-		/*
-		 * IR enabling failed
-		 */
+nox2apic:
+	if (!ret) /* IR enabling failed */
 		restore_IO_APIC_setup(ioapic_entries);
-
 	unmask_8259A();
 	local_irq_restore(flags);
 
-end:
+out:
 	if (ioapic_entries)
 		free_ioapic_entries(ioapic_entries);
 
-	if (!ret)
+	if (x2apic_enabled)
 		return;
 
-ir_failed:
 	if (x2apic_preenabled)
-		panic("x2apic enabled by bios. But IR enabling failed");
+		panic("x2apic: enabled by BIOS but kernel init failed.");
 	else if (cpu_has_x2apic)
-		pr_info("Not enabling x2apic,Intr-remapping\n");
-#else
-	if (!cpu_has_x2apic)
-		return;
-
-	if (x2apic_preenabled)
-		panic("x2apic enabled prior OS handover,"
-		      " enable CONFIG_X86_X2APIC, CONFIG_INTR_REMAP");
-#endif
-
-	return;
+		pr_info("Not enabling x2apic, Intr-remapping init failed.\n");
 }
 
-
 #ifdef CONFIG_X86_64
 /*
  * Detect and enable local APICs on non-SMP boards.
@@ -1549,8 +1562,6 @@ no_apic:
 #ifdef CONFIG_X86_64
 void __init early_init_lapic_mapping(void)
 {
-	unsigned long phys_addr;
-
 	/*
 	 * If no local APIC can be found then go out
 	 * : it means there is no mpatable and MADT
@@ -1558,11 +1569,9 @@ void __init early_init_lapic_mapping(void)
 	if (!smp_found_config)
 		return;
 
-	phys_addr = mp_lapic_addr;
-
-	set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
+	set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
 	apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
-		    APIC_BASE, phys_addr);
+		    APIC_BASE, mp_lapic_addr);
 
 	/*
 	 * Fetch the APIC ID of the BSP in case we have a
@@ -1651,7 +1660,6 @@ int __init APIC_init_uniprocessor(void)
 	    APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
 		pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
 			boot_cpu_physical_apicid);
-		clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
 		return -1;
 	}
 #endif
@@ -1701,7 +1709,7 @@ int __init APIC_init_uniprocessor(void)
 	localise_nmi_watchdog();
 #endif
 
-	setup_boot_clock();
+	x86_init.timers.setup_percpu_clockev();
 #ifdef CONFIG_X86_64
 	check_nmi_watchdog();
 #endif
@@ -1908,24 +1916,14 @@ void __cpuinit generic_processor_info(int apicid, int version)
 		max_physical_apicid = apicid;
 
 #ifdef CONFIG_X86_32
-	/*
-	 * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y
-	 * but we need to work other dependencies like SMP_SUSPEND etc
-	 * before this can be done without some confusion.
-	 * if (CPU_HOTPLUG_ENABLED || num_processors > 8)
-	 *       - Ashok Raj <ashok.raj@intel.com>
-	 */
-	if (max_physical_apicid >= 8) {
-		switch (boot_cpu_data.x86_vendor) {
-		case X86_VENDOR_INTEL:
-			if (!APIC_XAPIC(version)) {
-				def_to_bigsmp = 0;
-				break;
-			}
-			/* If P4 and above fall through */
-		case X86_VENDOR_AMD:
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_INTEL:
+		if (num_processors > 8)
+			def_to_bigsmp = 1;
+		break;
+	case X86_VENDOR_AMD:
+		if (max_physical_apicid >= 8)
 			def_to_bigsmp = 1;
-		}
 	}
 #endif
 
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index 676cdac..77a0641 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -112,7 +112,7 @@ static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
 	return physids_promote(0xFFL);
 }
 
-static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
+static int bigsmp_check_phys_apicid_present(int phys_apicid)
 {
 	return 1;
 }
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index 8952a58..89174f8 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -167,7 +167,7 @@ static int es7000_apic_is_cluster(void)
 {
 	/* MPENTIUMIII */
 	if (boot_cpu_data.x86 == 6 &&
-	    (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11))
+	    (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11))
 		return 1;
 
 	return 0;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index d2ed6c5..64970b9 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -66,6 +66,8 @@
 #include <asm/apic.h>
 
 #define __apicdebuginit(type) static type __init
+#define for_each_irq_pin(entry, head) \
+	for (entry = head; entry; entry = entry->next)
 
 /*
  *      Is the SiS APIC rmw bug present ?
@@ -85,12 +87,20 @@ int nr_ioapic_registers[MAX_IO_APICS];
 struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
 int nr_ioapics;
 
+/* IO APIC gsi routing info */
+struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
+
 /* MP IRQ source entries */
 struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
 /* # of MP IRQ source entries */
 int mp_irq_entries;
 
+/* Number of legacy interrupts */
+static int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY;
+/* GSI interrupts */
+static int nr_irqs_gsi = NR_IRQS_LEGACY;
+
 #if defined (CONFIG_MCA) || defined (CONFIG_EISA)
 int mp_bus_id_to_type[MAX_MP_BUSSES];
 #endif
@@ -116,15 +126,6 @@ static int __init parse_noapic(char *str)
 }
 early_param("noapic", parse_noapic);
 
-struct irq_pin_list;
-
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * the indexing order of this array favors 1:1 mappings
- * between pins and IRQs.
- */
-
 struct irq_pin_list {
 	int apic, pin;
 	struct irq_pin_list *next;
@@ -139,6 +140,11 @@ static struct irq_pin_list *get_one_free_irq_2_pin(int node)
 	return pin;
 }
 
+/*
+ * This is performance-critical, we want to do it O(1)
+ *
+ * Most irqs are mapped 1:1 with pins.
+ */
 struct irq_cfg {
 	struct irq_pin_list *irq_2_pin;
 	cpumask_var_t domain;
@@ -172,6 +178,12 @@ static struct irq_cfg irq_cfgx[NR_IRQS] = {
 	[15] = { .vector = IRQ15_VECTOR, },
 };
 
+void __init io_apic_disable_legacy(void)
+{
+	nr_legacy_irqs = 0;
+	nr_irqs_gsi = 0;
+}
+
 int __init arch_early_irq_init(void)
 {
 	struct irq_cfg *cfg;
@@ -189,7 +201,7 @@ int __init arch_early_irq_init(void)
 		desc->chip_data = &cfg[i];
 		zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
 		zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
-		if (i < NR_IRQS_LEGACY)
+		if (i < nr_legacy_irqs)
 			cpumask_setall(cfg[i].domain);
 	}
 
@@ -414,13 +426,10 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
 	unsigned long flags;
 
 	spin_lock_irqsave(&ioapic_lock, flags);
-	entry = cfg->irq_2_pin;
-	for (;;) {
+	for_each_irq_pin(entry, cfg->irq_2_pin) {
 		unsigned int reg;
 		int pin;
 
-		if (!entry)
-			break;
 		pin = entry->pin;
 		reg = io_apic_read(entry->apic, 0x10 + pin*2);
 		/* Is the remote IRR bit set? */
@@ -428,9 +437,6 @@ static bool io_apic_level_ack_pending(struct irq_cfg *cfg)
 			spin_unlock_irqrestore(&ioapic_lock, flags);
 			return true;
 		}
-		if (!entry->next)
-			break;
-		entry = entry->next;
 	}
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -498,72 +504,68 @@ static void ioapic_mask_entry(int apic, int pin)
  * shared ISA-space IRQs, so we have to support them. We are super
  * fast in the common case, and fast for shared ISA-space IRQs.
  */
-static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
+static int
+add_pin_to_irq_node_nopanic(struct irq_cfg *cfg, int node, int apic, int pin)
 {
-	struct irq_pin_list *entry;
+	struct irq_pin_list **last, *entry;
 
-	entry = cfg->irq_2_pin;
-	if (!entry) {
-		entry = get_one_free_irq_2_pin(node);
-		if (!entry) {
-			printk(KERN_ERR "can not alloc irq_2_pin to add %d - %d\n",
-					apic, pin);
-			return;
-		}
-		cfg->irq_2_pin = entry;
-		entry->apic = apic;
-		entry->pin = pin;
-		return;
-	}
-
-	while (entry->next) {
-		/* not again, please */
+	/* don't allow duplicates */
+	last = &cfg->irq_2_pin;
+	for_each_irq_pin(entry, cfg->irq_2_pin) {
 		if (entry->apic == apic && entry->pin == pin)
-			return;
-
-		entry = entry->next;
+			return 0;
+		last = &entry->next;
 	}
 
-	entry->next = get_one_free_irq_2_pin(node);
-	entry = entry->next;
+	entry = get_one_free_irq_2_pin(node);
+	if (!entry) {
+		printk(KERN_ERR "can not alloc irq_pin_list (%d,%d,%d)\n",
+				node, apic, pin);
+		return -ENOMEM;
+	}
 	entry->apic = apic;
 	entry->pin = pin;
+
+	*last = entry;
+	return 0;
+}
+
+static void add_pin_to_irq_node(struct irq_cfg *cfg, int node, int apic, int pin)
+{
+	if (add_pin_to_irq_node_nopanic(cfg, node, apic, pin))
+		panic("IO-APIC: failed to add irq-pin. Can not proceed\n");
 }
 
 /*
  * Reroute an IRQ to a different pin.
  */
 static void __init replace_pin_at_irq_node(struct irq_cfg *cfg, int node,
-				      int oldapic, int oldpin,
-				      int newapic, int newpin)
+					   int oldapic, int oldpin,
+					   int newapic, int newpin)
 {
-	struct irq_pin_list *entry = cfg->irq_2_pin;
-	int replaced = 0;
+	struct irq_pin_list *entry;
 
-	while (entry) {
+	for_each_irq_pin(entry, cfg->irq_2_pin) {
 		if (entry->apic == oldapic && entry->pin == oldpin) {
 			entry->apic = newapic;
 			entry->pin = newpin;
-			replaced = 1;
 			/* every one is different, right? */
-			break;
+			return;
 		}
-		entry = entry->next;
 	}
 
-	/* why? call replace before add? */
-	if (!replaced)
-		add_pin_to_irq_node(cfg, node, newapic, newpin);
+	/* old apic/pin didn't exist, so just add new ones */
+	add_pin_to_irq_node(cfg, node, newapic, newpin);
 }
 
-static inline void io_apic_modify_irq(struct irq_cfg *cfg,
-				int mask_and, int mask_or,
-				void (*final)(struct irq_pin_list *entry))
+static void io_apic_modify_irq(struct irq_cfg *cfg,
+			       int mask_and, int mask_or,
+			       void (*final)(struct irq_pin_list *entry))
 {
 	int pin;
 	struct irq_pin_list *entry;
 
-	for (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) {
+	for_each_irq_pin(entry, cfg->irq_2_pin) {
 		unsigned int reg;
 		pin = entry->pin;
 		reg = io_apic_read(entry->apic, 0x10 + pin * 2);
@@ -580,7 +582,6 @@ static void __unmask_IO_APIC_irq(struct irq_cfg *cfg)
 	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED, 0, NULL);
 }
 
-#ifdef CONFIG_X86_64
 static void io_apic_sync(struct irq_pin_list *entry)
 {
 	/*
@@ -596,11 +597,6 @@ static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
 {
 	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
 }
-#else /* CONFIG_X86_32 */
-static void __mask_IO_APIC_irq(struct irq_cfg *cfg)
-{
-	io_apic_modify_irq(cfg, ~0, IO_APIC_REDIR_MASKED, NULL);
-}
 
 static void __mask_and_edge_IO_APIC_irq(struct irq_cfg *cfg)
 {
@@ -613,7 +609,6 @@ static void __unmask_and_level_IO_APIC_irq(struct irq_cfg *cfg)
 	io_apic_modify_irq(cfg, ~IO_APIC_REDIR_MASKED,
 			IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
 }
-#endif /* CONFIG_X86_32 */
 
 static void mask_IO_APIC_irq_desc(struct irq_desc *desc)
 {
@@ -883,7 +878,7 @@ static int __init find_isa_irq_apic(int irq, int type)
  */
 static int EISA_ELCR(unsigned int irq)
 {
-	if (irq < NR_IRQS_LEGACY) {
+	if (irq < nr_legacy_irqs) {
 		unsigned int port = 0x4d0 + (irq >> 3);
 		return (inb(port) >> (irq & 7)) & 1;
 	}
@@ -1480,7 +1475,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
 	}
 
 	ioapic_register_intr(irq, desc, trigger);
-	if (irq < NR_IRQS_LEGACY)
+	if (irq < nr_legacy_irqs)
 		disable_8259A_irq(irq);
 
 	ioapic_write_entry(apic_id, pin, entry);
@@ -1702,12 +1697,8 @@ __apicdebuginit(void) print_IO_APIC(void)
 		if (!entry)
 			continue;
 		printk(KERN_DEBUG "IRQ%d ", irq);
-		for (;;) {
+		for_each_irq_pin(entry, cfg->irq_2_pin)
 			printk("-> %d:%d", entry->apic, entry->pin);
-			if (!entry->next)
-				break;
-			entry = entry->next;
-		}
 		printk("\n");
 	}
 
@@ -1851,7 +1842,7 @@ __apicdebuginit(void) print_PIC(void)
 	unsigned int v;
 	unsigned long flags;
 
-	if (apic_verbosity == APIC_QUIET)
+	if (apic_verbosity == APIC_QUIET || !nr_legacy_irqs)
 		return;
 
 	printk(KERN_DEBUG "\nprinting PIC contents\n");
@@ -1883,7 +1874,7 @@ __apicdebuginit(int) print_all_ICs(void)
 	print_PIC();
 
 	/* don't print out if apic is not there */
-	if (!cpu_has_apic || disable_apic)
+	if (!cpu_has_apic && !apic_from_smp_config())
 		return 0;
 
 	print_all_local_APICs();
@@ -1914,6 +1905,10 @@ void __init enable_IO_APIC(void)
 		spin_unlock_irqrestore(&ioapic_lock, flags);
 		nr_ioapic_registers[apic] = reg_01.bits.entries+1;
 	}
+
+	if (!nr_legacy_irqs)
+		return;
+
 	for(apic = 0; apic < nr_ioapics; apic++) {
 		int pin;
 		/* See if any of the pins is in ExtINT mode */
@@ -1968,6 +1963,9 @@ void disable_IO_APIC(void)
 	 */
 	clear_IO_APIC();
 
+	if (!nr_legacy_irqs)
+		return;
+
 	/*
 	 * If the i8259 is routed through an IOAPIC
 	 * Put that IOAPIC in virtual wire mode
@@ -2001,7 +1999,7 @@ void disable_IO_APIC(void)
 	/*
 	 * Use virtual wire A mode when interrupt remapping is enabled.
 	 */
-	if (cpu_has_apic)
+	if (cpu_has_apic || apic_from_smp_config())
 		disconnect_bsp_APIC(!intr_remapping_enabled &&
 				ioapic_i8259.pin != -1);
 }
@@ -2014,7 +2012,7 @@ void disable_IO_APIC(void)
  * by Matt Domsch <Matt_Domsch@dell.com>  Tue Dec 21 12:25:05 CST 1999
  */
 
-static void __init setup_ioapic_ids_from_mpc(void)
+void __init setup_ioapic_ids_from_mpc(void)
 {
 	union IO_APIC_reg_00 reg_00;
 	physid_mask_t phys_id_present_map;
@@ -2023,9 +2021,8 @@ static void __init setup_ioapic_ids_from_mpc(void)
 	unsigned char old_id;
 	unsigned long flags;
 
-	if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
+	if (acpi_ioapic)
 		return;
-
 	/*
 	 * Don't check I/O APIC IDs for xAPIC systems.  They have
 	 * no meaning without the serial APIC bus.
@@ -2199,7 +2196,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
 	struct irq_cfg *cfg;
 
 	spin_lock_irqsave(&ioapic_lock, flags);
-	if (irq < NR_IRQS_LEGACY) {
+	if (irq < nr_legacy_irqs) {
 		disable_8259A_irq(irq);
 		if (i8259A_irq_pending(irq))
 			was_pending = 1;
@@ -2211,7 +2208,6 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
 	return was_pending;
 }
 
-#ifdef CONFIG_X86_64
 static int ioapic_retrigger_irq(unsigned int irq)
 {
 
@@ -2224,14 +2220,6 @@ static int ioapic_retrigger_irq(unsigned int irq)
 
 	return 1;
 }
-#else
-static int ioapic_retrigger_irq(unsigned int irq)
-{
-	apic->send_IPI_self(irq_cfg(irq)->vector);
-
-	return 1;
-}
-#endif
 
 /*
  * Level and edge triggered IO-APIC interrupts need different handling,
@@ -2269,13 +2257,9 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
 	struct irq_pin_list *entry;
 	u8 vector = cfg->vector;
 
-	entry = cfg->irq_2_pin;
-	for (;;) {
+	for_each_irq_pin(entry, cfg->irq_2_pin) {
 		unsigned int reg;
 
-		if (!entry)
-			break;
-
 		apic = entry->apic;
 		pin = entry->pin;
 		/*
@@ -2288,9 +2272,6 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, struct irq
 		reg &= ~IO_APIC_REDIR_VECTOR_MASK;
 		reg |= vector;
 		io_apic_modify(apic, 0x10 + pin*2, reg);
-		if (!entry->next)
-			break;
-		entry = entry->next;
 	}
 }
 
@@ -2515,11 +2496,8 @@ atomic_t irq_mis_count;
 static void ack_apic_level(unsigned int irq)
 {
 	struct irq_desc *desc = irq_to_desc(irq);
-
-#ifdef CONFIG_X86_32
 	unsigned long v;
 	int i;
-#endif
 	struct irq_cfg *cfg;
 	int do_unmask_irq = 0;
 
@@ -2532,31 +2510,28 @@ static void ack_apic_level(unsigned int irq)
 	}
 #endif
 
-#ifdef CONFIG_X86_32
 	/*
-	* It appears there is an erratum which affects at least version 0x11
-	* of I/O APIC (that's the 82093AA and cores integrated into various
-	* chipsets).  Under certain conditions a level-triggered interrupt is
-	* erroneously delivered as edge-triggered one but the respective IRR
-	* bit gets set nevertheless.  As a result the I/O unit expects an EOI
-	* message but it will never arrive and further interrupts are blocked
-	* from the source.  The exact reason is so far unknown, but the
-	* phenomenon was observed when two consecutive interrupt requests
-	* from a given source get delivered to the same CPU and the source is
-	* temporarily disabled in between.
-	*
-	* A workaround is to simulate an EOI message manually.  We achieve it
-	* by setting the trigger mode to edge and then to level when the edge
-	* trigger mode gets detected in the TMR of a local APIC for a
-	* level-triggered interrupt.  We mask the source for the time of the
-	* operation to prevent an edge-triggered interrupt escaping meanwhile.
-	* The idea is from Manfred Spraul.  --macro
-	*/
+	 * It appears there is an erratum which affects at least version 0x11
+	 * of I/O APIC (that's the 82093AA and cores integrated into various
+	 * chipsets).  Under certain conditions a level-triggered interrupt is
+	 * erroneously delivered as edge-triggered one but the respective IRR
+	 * bit gets set nevertheless.  As a result the I/O unit expects an EOI
+	 * message but it will never arrive and further interrupts are blocked
+	 * from the source.  The exact reason is so far unknown, but the
+	 * phenomenon was observed when two consecutive interrupt requests
+	 * from a given source get delivered to the same CPU and the source is
+	 * temporarily disabled in between.
+	 *
+	 * A workaround is to simulate an EOI message manually.  We achieve it
+	 * by setting the trigger mode to edge and then to level when the edge
+	 * trigger mode gets detected in the TMR of a local APIC for a
+	 * level-triggered interrupt.  We mask the source for the time of the
+	 * operation to prevent an edge-triggered interrupt escaping meanwhile.
+	 * The idea is from Manfred Spraul.  --macro
+	 */
 	cfg = desc->chip_data;
 	i = cfg->vector;
-
 	v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
-#endif
 
 	/*
 	 * We must acknowledge the irq before we move it or the acknowledge will
@@ -2598,7 +2573,7 @@ static void ack_apic_level(unsigned int irq)
 		unmask_IO_APIC_irq_desc(desc);
 	}
 
-#ifdef CONFIG_X86_32
+	/* Tail end of version 0x11 I/O APIC bug workaround */
 	if (!(v & (1 << (i & 0x1f)))) {
 		atomic_inc(&irq_mis_count);
 		spin_lock(&ioapic_lock);
@@ -2606,26 +2581,15 @@ static void ack_apic_level(unsigned int irq)
 		__unmask_and_level_IO_APIC_irq(cfg);
 		spin_unlock(&ioapic_lock);
 	}
-#endif
 }
 
 #ifdef CONFIG_INTR_REMAP
 static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
 {
-	int apic, pin;
 	struct irq_pin_list *entry;
 
-	entry = cfg->irq_2_pin;
-	for (;;) {
-
-		if (!entry)
-			break;
-
-		apic = entry->apic;
-		pin = entry->pin;
-		io_apic_eoi(apic, pin);
-		entry = entry->next;
-	}
+	for_each_irq_pin(entry, cfg->irq_2_pin)
+		io_apic_eoi(entry->apic, entry->pin);
 }
 
 static void
@@ -2710,7 +2674,7 @@ static inline void init_IO_APIC_traps(void)
 			 * so default to an old-fashioned 8259
 			 * interrupt if we can..
 			 */
-			if (irq < NR_IRQS_LEGACY)
+			if (irq < nr_legacy_irqs)
 				make_8259A_irq(irq);
 			else
 				/* Strange. Oh, well.. */
@@ -3046,7 +3010,7 @@ out:
  * the I/O APIC in all cases now.  No actual device should request
  * it anyway.  --macro
  */
-#define PIC_IRQS	(1 << PIC_CASCADE_IR)
+#define PIC_IRQS	(1UL << PIC_CASCADE_IR)
 
 void __init setup_IO_APIC(void)
 {
@@ -3054,21 +3018,19 @@ void __init setup_IO_APIC(void)
 	/*
 	 * calling enable_IO_APIC() is moved to setup_local_APIC for BP
 	 */
-
-	io_apic_irqs = ~PIC_IRQS;
+	io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
 
 	apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
 	/*
          * Set up IO-APIC IRQ routing.
          */
-#ifdef CONFIG_X86_32
-	if (!acpi_ioapic)
-		setup_ioapic_ids_from_mpc();
-#endif
+	x86_init.mpparse.setup_ioapic_ids();
+
 	sync_Arb_IDs();
 	setup_IO_APIC_irqs();
 	init_IO_APIC_traps();
-	check_timer();
+	if (nr_legacy_irqs)
+		check_timer();
 }
 
 /*
@@ -3169,7 +3131,6 @@ static int __init ioapic_init_sysfs(void)
 
 device_initcall(ioapic_init_sysfs);
 
-static int nr_irqs_gsi = NR_IRQS_LEGACY;
 /*
  * Dynamic irq allocate and deallocation
  */
@@ -3241,8 +3202,7 @@ void destroy_irq(unsigned int irq)
 	cfg = desc->chip_data;
 	dynamic_irq_cleanup(irq);
 	/* connect back irq_cfg */
-	if (desc)
-		desc->chip_data = cfg;
+	desc->chip_data = cfg;
 
 	free_irte(irq);
 	spin_lock_irqsave(&vector_lock, flags);
@@ -3910,9 +3870,13 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
 	/*
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
-	if (irq >= NR_IRQS_LEGACY) {
+	if (irq >= nr_legacy_irqs) {
 		cfg = desc->chip_data;
-		add_pin_to_irq_node(cfg, node, ioapic, pin);
+		if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
+			printk(KERN_INFO "can not add pin %d for irq %d\n",
+				pin, irq);
+			return 0;
+		}
 	}
 
 	setup_IO_APIC_irq(ioapic, pin, irq, desc, trigger, polarity);
@@ -3941,11 +3905,28 @@ int io_apic_set_pci_routing(struct device *dev, int irq,
 	return __io_apic_set_pci_routing(dev, irq, irq_attr);
 }
 
-/* --------------------------------------------------------------------------
-                          ACPI-based IOAPIC Configuration
-   -------------------------------------------------------------------------- */
+u8 __init io_apic_unique_id(u8 id)
+{
+#ifdef CONFIG_X86_32
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
+	    !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
+		return io_apic_get_unique_id(nr_ioapics, id);
+	else
+		return id;
+#else
+	int i;
+	DECLARE_BITMAP(used, 256);
 
-#ifdef CONFIG_ACPI
+	bitmap_zero(used, 256);
+	for (i = 0; i < nr_ioapics; i++) {
+		struct mpc_ioapic *ia = &mp_ioapics[i];
+		__set_bit(ia->apicid, used);
+	}
+	if (!test_bit(id, used))
+		return id;
+	return find_first_zero_bit(used, 256);
+#endif
+}
 
 #ifdef CONFIG_X86_32
 int __init io_apic_get_unique_id(int ioapic, int apic_id)
@@ -4054,8 +4035,6 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
 	return 0;
 }
 
-#endif /* CONFIG_ACPI */
-
 /*
  * This function currently is only a helper for the i386 smp boot process where
  * we need to reprogram the ioredtbls to cater for the cpus which have come online
@@ -4109,7 +4088,7 @@ void __init setup_ioapic_dest(void)
 
 static struct resource *ioapic_resources;
 
-static struct resource * __init ioapic_setup_resources(void)
+static struct resource * __init ioapic_setup_resources(int nr_ioapics)
 {
 	unsigned long n;
 	struct resource *res;
@@ -4125,15 +4104,13 @@ static struct resource * __init ioapic_setup_resources(void)
 	mem = alloc_bootmem(n);
 	res = (void *)mem;
 
-	if (mem != NULL) {
-		mem += sizeof(struct resource) * nr_ioapics;
+	mem += sizeof(struct resource) * nr_ioapics;
 
-		for (i = 0; i < nr_ioapics; i++) {
-			res[i].name = mem;
-			res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-			sprintf(mem,  "IOAPIC %u", i);
-			mem += IOAPIC_RESOURCE_NAME_SIZE;
-		}
+	for (i = 0; i < nr_ioapics; i++) {
+		res[i].name = mem;
+		res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		sprintf(mem,  "IOAPIC %u", i);
+		mem += IOAPIC_RESOURCE_NAME_SIZE;
 	}
 
 	ioapic_resources = res;
@@ -4147,7 +4124,7 @@ void __init ioapic_init_mappings(void)
 	struct resource *ioapic_res;
 	int i;
 
-	ioapic_res = ioapic_setup_resources();
+	ioapic_res = ioapic_setup_resources(nr_ioapics);
 	for (i = 0; i < nr_ioapics; i++) {
 		if (smp_found_config) {
 			ioapic_phys = mp_ioapics[i].apicaddr;
@@ -4176,11 +4153,9 @@ fake_ioapic_page:
 			    __fix_to_virt(idx), ioapic_phys);
 		idx++;
 
-		if (ioapic_res != NULL) {
-			ioapic_res->start = ioapic_phys;
-			ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
-			ioapic_res++;
-		}
+		ioapic_res->start = ioapic_phys;
+		ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
+		ioapic_res++;
 	}
 }
 
@@ -4201,3 +4176,76 @@ void __init ioapic_insert_resources(void)
 		r++;
 	}
 }
+
+int mp_find_ioapic(int gsi)
+{
+	int i = 0;
+
+	/* Find the IOAPIC that manages this GSI. */
+	for (i = 0; i < nr_ioapics; i++) {
+		if ((gsi >= mp_gsi_routing[i].gsi_base)
+		    && (gsi <= mp_gsi_routing[i].gsi_end))
+			return i;
+	}
+
+	printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
+	return -1;
+}
+
+int mp_find_ioapic_pin(int ioapic, int gsi)
+{
+	if (WARN_ON(ioapic == -1))
+		return -1;
+	if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end))
+		return -1;
+
+	return gsi - mp_gsi_routing[ioapic].gsi_base;
+}
+
+static int bad_ioapic(unsigned long address)
+{
+	if (nr_ioapics >= MAX_IO_APICS) {
+		printk(KERN_WARNING "WARING: Max # of I/O APICs (%d) exceeded "
+		       "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics);
+		return 1;
+	}
+	if (!address) {
+		printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address"
+		       " found in table, skipping!\n");
+		return 1;
+	}
+	return 0;
+}
+
+void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
+{
+	int idx = 0;
+
+	if (bad_ioapic(address))
+		return;
+
+	idx = nr_ioapics;
+
+	mp_ioapics[idx].type = MP_IOAPIC;
+	mp_ioapics[idx].flags = MPC_APIC_USABLE;
+	mp_ioapics[idx].apicaddr = address;
+
+	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
+	mp_ioapics[idx].apicid = io_apic_unique_id(id);
+	mp_ioapics[idx].apicver = io_apic_get_version(idx);
+
+	/*
+	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
+	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
+	 */
+	mp_gsi_routing[idx].gsi_base = gsi_base;
+	mp_gsi_routing[idx].gsi_end = gsi_base +
+	    io_apic_get_redir_entries(idx);
+
+	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
+	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
+	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
+	       mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end);
+
+	nr_ioapics++;
+}
diff --git a/arch/x86/kernel/apic/ipi.c b/arch/x86/kernel/apic/ipi.c
index 6ef00ba..08385e0 100644
--- a/arch/x86/kernel/apic/ipi.c
+++ b/arch/x86/kernel/apic/ipi.c
@@ -153,7 +153,7 @@ int safe_smp_processor_id(void)
 {
 	int apicid, cpuid;
 
-	if (!boot_cpu_has(X86_FEATURE_APIC))
+	if (!cpu_has_apic)
 		return 0;
 
 	apicid = hard_smp_processor_id();
diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c
index db72202..cb66a22 100644
--- a/arch/x86/kernel/apic/nmi.c
+++ b/arch/x86/kernel/apic/nmi.c
@@ -66,7 +66,7 @@ static inline unsigned int get_nmi_count(int cpu)
 
 static inline int mce_in_progress(void)
 {
-#if defined(CONFIG_X86_NEW_MCE)
+#if defined(CONFIG_X86_MCE)
 	return atomic_read(&mce_entry) > 0;
 #endif
 	return 0;
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c
index ca96e68..efa00e2 100644
--- a/arch/x86/kernel/apic/numaq_32.c
+++ b/arch/x86/kernel/apic/numaq_32.c
@@ -66,7 +66,6 @@ struct mpc_trans {
 	unsigned short			trans_reserved;
 };
 
-/* x86_quirks member */
 static int				mpc_record;
 
 static struct mpc_trans			*translation_table[MAX_MPC_ENTRY];
@@ -130,10 +129,9 @@ void __cpuinit numaq_tsc_disable(void)
 	}
 }
 
-static int __init numaq_pre_time_init(void)
+static void __init numaq_tsc_init(void)
 {
 	numaq_tsc_disable();
-	return 0;
 }
 
 static inline int generate_logical_apicid(int quad, int phys_apicid)
@@ -177,6 +175,19 @@ static void mpc_oem_pci_bus(struct mpc_bus *m)
 	quad_local_to_mp_bus_id[quad][local] = m->busid;
 }
 
+/*
+ * Called from mpparse code.
+ * mode = 0: prescan
+ * mode = 1: one mpc entry scanned
+ */
+static void numaq_mpc_record(unsigned int mode)
+{
+	if (!mode)
+		mpc_record = 0;
+	else
+		mpc_record++;
+}
+
 static void __init MP_translation_info(struct mpc_trans *m)
 {
 	printk(KERN_INFO
@@ -206,9 +217,9 @@ static int __init mpf_checksum(unsigned char *mp, int len)
 /*
  * Read/parse the MPC oem tables
  */
-static void __init
- smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize)
+static void __init smp_read_mpc_oem(struct mpc_table *mpc)
 {
+	struct mpc_oemtable *oemtable = (void *)(long)mpc->oemptr;
 	int count = sizeof(*oemtable);	/* the header size */
 	unsigned char *oemptr = ((unsigned char *)oemtable) + count;
 
@@ -250,29 +261,6 @@ static void __init
 	}
 }
 
-static int __init numaq_setup_ioapic_ids(void)
-{
-	/* so can skip it */
-	return 1;
-}
-
-static struct x86_quirks numaq_x86_quirks __initdata = {
-	.arch_pre_time_init		= numaq_pre_time_init,
-	.arch_time_init			= NULL,
-	.arch_pre_intr_init		= NULL,
-	.arch_memory_setup		= NULL,
-	.arch_intr_init			= NULL,
-	.arch_trap_init			= NULL,
-	.mach_get_smp_config		= NULL,
-	.mach_find_smp_config		= NULL,
-	.mpc_record			= &mpc_record,
-	.mpc_apic_id			= mpc_apic_id,
-	.mpc_oem_bus_info		= mpc_oem_bus_info,
-	.mpc_oem_pci_bus		= mpc_oem_pci_bus,
-	.smp_read_mpc_oem		= smp_read_mpc_oem,
-	.setup_ioapic_ids		= numaq_setup_ioapic_ids,
-};
-
 static __init void early_check_numaq(void)
 {
 	/*
@@ -286,8 +274,15 @@ static __init void early_check_numaq(void)
 	if (smp_found_config)
 		early_get_smp_config();
 
-	if (found_numaq)
-		x86_quirks = &numaq_x86_quirks;
+	if (found_numaq) {
+		x86_init.mpparse.mpc_record = numaq_mpc_record;
+		x86_init.mpparse.setup_ioapic_ids = x86_init_noop;
+		x86_init.mpparse.mpc_apic_id = mpc_apic_id;
+		x86_init.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
+		x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
+		x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
+		x86_init.timers.tsc_pre_init = numaq_tsc_init;
+	}
 }
 
 int __init get_memcfg_numaq(void)
@@ -418,7 +413,7 @@ static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid)
 /* Where the IO area was mapped on multiquad, always 0 otherwise */
 void *xquad_portio;
 
-static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid)
+static inline int numaq_check_phys_apicid_present(int phys_apicid)
 {
 	return 1;
 }
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index fcec2f1..c4cbd30 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -55,25 +55,32 @@ static int apicid_phys_pkg_id(int initial_apic_id, int index_msb)
 void __init default_setup_apic_routing(void)
 {
 #ifdef CONFIG_X86_X2APIC
-	if (x2apic_mode && (apic != &apic_x2apic_phys &&
+	if (x2apic_mode
 #ifdef CONFIG_X86_UV
-		       apic != &apic_x2apic_uv_x &&
+		       && apic != &apic_x2apic_uv_x
 #endif
-		       apic != &apic_x2apic_cluster)) {
+		       ) {
 		if (x2apic_phys)
 			apic = &apic_x2apic_phys;
 		else
 			apic = &apic_x2apic_cluster;
-		printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
 	}
 #endif
 
 	if (apic == &apic_flat) {
-		if (max_physical_apicid >= 8)
-			apic = &apic_physflat;
-		printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
+		switch (boot_cpu_data.x86_vendor) {
+		case X86_VENDOR_INTEL:
+			if (num_processors > 8)
+				apic = &apic_physflat;
+			break;
+		case X86_VENDOR_AMD:
+			if (max_physical_apicid >= 8)
+				apic = &apic_physflat;
+		}
 	}
 
+	printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
+
 	if (is_vsmp_box()) {
 		/* need to update phys_pkg_id */
 		apic->phys_pkg_id = apicid_phys_pkg_id;
diff --git a/arch/x86/kernel/apic/summit_32.c b/arch/x86/kernel/apic/summit_32.c
index eafdfbd..645ecc4 100644
--- a/arch/x86/kernel/apic/summit_32.c
+++ b/arch/x86/kernel/apic/summit_32.c
@@ -272,7 +272,7 @@ static physid_mask_t summit_apicid_to_cpu_present(int apicid)
 	return physid_mask_of_physid(0);
 }
 
-static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
+static int summit_check_phys_apicid_present(int physical_apicid)
 {
 	return 1;
 }
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c
index 6011593..f5f5886 100644
--- a/arch/x86/kernel/apic/x2apic_uv_x.c
+++ b/arch/x86/kernel/apic/x2apic_uv_x.c
@@ -389,6 +389,16 @@ static __init void map_gru_high(int max_pnode)
 		map_high("GRU", gru.s.base, shift, max_pnode, map_wb);
 }
 
+static __init void map_mmr_high(int max_pnode)
+{
+	union uvh_rh_gam_mmr_overlay_config_mmr_u mmr;
+	int shift = UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT;
+
+	mmr.v = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR);
+	if (mmr.s.enable)
+		map_high("MMR", mmr.s.base, shift, max_pnode, map_uc);
+}
+
 static __init void map_mmioh_high(int max_pnode)
 {
 	union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh;
@@ -643,6 +653,7 @@ void __init uv_system_init(void)
 	}
 
 	map_gru_high(max_pnode);
+	map_mmr_high(max_pnode);
 	map_mmioh_high(max_pnode);
 
 	uv_cpu_init();
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 442b550..151ace6 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -403,7 +403,15 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
 static struct apm_user *user_list;
 static DEFINE_SPINLOCK(user_list_lock);
-static const struct desc_struct	bad_bios_desc = { { { 0, 0x00409200 } } };
+
+/*
+ * Set up a segment that references the real mode segment 0x40
+ * that extends up to the end of page zero (that we have reserved).
+ * This is for buggy BIOS's that refer to (real mode) segment 0x40
+ * even though they are called in protected mode.
+ */
+static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
+			(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
 
 static const char driver_version[] = "1.16ac";	/* no spaces */
 
@@ -2332,15 +2340,6 @@ static int __init apm_init(void)
 	pm_flags |= PM_APM;
 
 	/*
-	 * Set up a segment that references the real mode segment 0x40
-	 * that extends up to the end of page zero (that we have reserved).
-	 * This is for buggy BIOS's that refer to (real mode) segment 0x40
-	 * even though they are called in protected mode.
-	 */
-	set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
-	_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
-
-	/*
 	 * Set up the long jump entry point to the APM BIOS, which is called
 	 * from inline assembly.
 	 */
@@ -2358,12 +2357,12 @@ static int __init apm_init(void)
 	 * code to that CPU.
 	 */
 	gdt = get_cpu_gdt_table(0);
-	set_base(gdt[APM_CS >> 3],
-		 __va((unsigned long)apm_info.bios.cseg << 4));
-	set_base(gdt[APM_CS_16 >> 3],
-		 __va((unsigned long)apm_info.bios.cseg_16 << 4));
-	set_base(gdt[APM_DS >> 3],
-		 __va((unsigned long)apm_info.bios.dseg << 4));
+	set_desc_base(&gdt[APM_CS >> 3],
+		 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
+	set_desc_base(&gdt[APM_CS_16 >> 3],
+		 (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
+	set_desc_base(&gdt[APM_DS >> 3],
+		 (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
 
 	proc_create("apm", 0, NULL, &apm_file_ops);
 
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index c1f253d..68537e9 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -13,7 +13,7 @@ CFLAGS_common.o		:= $(nostackp)
 
 obj-y			:= intel_cacheinfo.o addon_cpuid_features.o
 obj-y			+= proc.o capflags.o powerflags.o common.o
-obj-y			+= vmware.o hypervisor.o
+obj-y			+= vmware.o hypervisor.o sched.o
 
 obj-$(CONFIG_X86_32)	+= bugs.o cmpxchg.o
 obj-$(CONFIG_X86_64)	+= bugs_64.o
@@ -27,7 +27,7 @@ obj-$(CONFIG_CPU_SUP_CENTAUR)		+= centaur.o
 obj-$(CONFIG_CPU_SUP_TRANSMETA_32)	+= transmeta.o
 obj-$(CONFIG_CPU_SUP_UMC_32)		+= umc.o
 
-obj-$(CONFIG_PERF_COUNTERS)		+= perf_counter.o
+obj-$(CONFIG_PERF_EVENTS)		+= perf_event.o
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 63fddcd..f32fa71 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -2,7 +2,7 @@
 #include <linux/bitops.h>
 #include <linux/mm.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/processor.h>
 #include <asm/apic.h>
 #include <asm/cpu.h>
@@ -45,8 +45,8 @@ static void __cpuinit init_amd_k5(struct cpuinfo_x86 *c)
 #define CBAR_ENB	(0x80000000)
 #define CBAR_KEY	(0X000000CB)
 	if (c->x86_model == 9 || c->x86_model == 10) {
-		if (inl (CBAR) & CBAR_ENB)
-			outl (0 | CBAR_KEY, CBAR);
+		if (inl(CBAR) & CBAR_ENB)
+			outl(0 | CBAR_KEY, CBAR);
 	}
 }
 
@@ -87,9 +87,10 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c)
 		d = d2-d;
 
 		if (d > 20*K6_BUG_LOOP)
-			printk("system stability may be impaired when more than 32 MB are used.\n");
+			printk(KERN_CONT
+				"system stability may be impaired when more than 32 MB are used.\n");
 		else
-			printk("probably OK (after B9730xxxx).\n");
+			printk(KERN_CONT "probably OK (after B9730xxxx).\n");
 		printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n");
 	}
 
@@ -219,8 +220,9 @@ static void __cpuinit init_amd_k7(struct cpuinfo_x86 *c)
 	if ((c->x86_model == 8 && c->x86_mask >= 1) || (c->x86_model > 8)) {
 		rdmsr(MSR_K7_CLK_CTL, l, h);
 		if ((l & 0xfff00000) != 0x20000000) {
-			printk ("CPU: CLK_CTL MSR was %x. Reprogramming to %x\n", l,
-				((l & 0x000fffff)|0x20000000));
+			printk(KERN_INFO
+			    "CPU: CLK_CTL MSR was %x. Reprogramming to %x\n",
+					l, ((l & 0x000fffff)|0x20000000));
 			wrmsr(MSR_K7_CLK_CTL, (l & 0x000fffff)|0x20000000, h);
 		}
 	}
@@ -251,6 +253,64 @@ static int __cpuinit nearby_node(int apicid)
 #endif
 
 /*
+ * Fixup core topology information for AMD multi-node processors.
+ * Assumption 1: Number of cores in each internal node is the same.
+ * Assumption 2: Mixed systems with both single-node and dual-node
+ *               processors are not supported.
+ */
+#ifdef CONFIG_X86_HT
+static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_PCI
+	u32 t, cpn;
+	u8 n, n_id;
+	int cpu = smp_processor_id();
+
+	/* fixup topology information only once for a core */
+	if (cpu_has(c, X86_FEATURE_AMD_DCM))
+		return;
+
+	/* check for multi-node processor on boot cpu */
+	t = read_pci_config(0, 24, 3, 0xe8);
+	if (!(t & (1 << 29)))
+		return;
+
+	set_cpu_cap(c, X86_FEATURE_AMD_DCM);
+
+	/* cores per node: each internal node has half the number of cores */
+	cpn = c->x86_max_cores >> 1;
+
+	/* even-numbered NB_id of this dual-node processor */
+	n = c->phys_proc_id << 1;
+
+	/*
+	 * determine internal node id and assign cores fifty-fifty to
+	 * each node of the dual-node processor
+	 */
+	t = read_pci_config(0, 24 + n, 3, 0xe8);
+	n = (t>>30) & 0x3;
+	if (n == 0) {
+		if (c->cpu_core_id < cpn)
+			n_id = 0;
+		else
+			n_id = 1;
+	} else {
+		if (c->cpu_core_id < cpn)
+			n_id = 1;
+		else
+			n_id = 0;
+	}
+
+	/* compute entire NodeID, use llc_shared_map to store sibling info */
+	per_cpu(cpu_llc_id, cpu) = (c->phys_proc_id << 1) + n_id;
+
+	/* fixup core id to be in range from 0 to cpn */
+	c->cpu_core_id = c->cpu_core_id % cpn;
+#endif
+}
+#endif
+
+/*
  * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
  * Assumes number of cores is a power of two.
  */
@@ -267,17 +327,31 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c)
 	c->phys_proc_id = c->initial_apicid >> bits;
 	/* use socket ID also for last level cache */
 	per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
+	/* fixup topology information on multi-node processors */
+	if ((c->x86 == 0x10) && (c->x86_model == 9))
+		amd_fixup_dcm(c);
 #endif
 }
 
+int amd_get_nb_id(int cpu)
+{
+	int id = 0;
+#ifdef CONFIG_SMP
+	id = per_cpu(cpu_llc_id, cpu);
+#endif
+	return id;
+}
+EXPORT_SYMBOL_GPL(amd_get_nb_id);
+
 static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
 {
 #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
 	int cpu = smp_processor_id();
 	int node;
-	unsigned apicid = cpu_has_apic ? hard_smp_processor_id() : c->apicid;
+	unsigned apicid = c->apicid;
+
+	node = per_cpu(cpu_llc_id, cpu);
 
-	node = c->phys_proc_id;
 	if (apicid_to_node[apicid] != NUMA_NO_NODE)
 		node = apicid_to_node[apicid];
 	if (!node_online(node)) {
@@ -398,18 +472,30 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 		u32 level;
 
 		level = cpuid_eax(1);
-		if((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
+		if ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)
 			set_cpu_cap(c, X86_FEATURE_REP_GOOD);
 
 		/*
 		 * Some BIOSes incorrectly force this feature, but only K8
 		 * revision D (model = 0x14) and later actually support it.
+		 * (AMD Erratum #110, docId: 25759).
 		 */
-		if (c->x86_model < 0x14)
+		if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) {
+			u64 val;
+
 			clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
+			if (!rdmsrl_amd_safe(0xc001100d, &val)) {
+				val &= ~(1ULL << 32);
+				wrmsrl_amd_safe(0xc001100d, val);
+			}
+		}
+
 	}
 	if (c->x86 == 0x10 || c->x86 == 0x11)
 		set_cpu_cap(c, X86_FEATURE_REP_GOOD);
+
+	/* get apicid instead of initial apic id from cpuid */
+	c->apicid = hard_smp_processor_id();
 #else
 
 	/*
@@ -494,27 +580,30 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 		 * benefit in doing so.
 		 */
 		if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
-		    printk(KERN_DEBUG "tseg: %010llx\n", tseg);
-		    if ((tseg>>PMD_SHIFT) <
+			printk(KERN_DEBUG "tseg: %010llx\n", tseg);
+			if ((tseg>>PMD_SHIFT) <
 				(max_low_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) ||
-			((tseg>>PMD_SHIFT) <
+				((tseg>>PMD_SHIFT) <
 				(max_pfn_mapped>>(PMD_SHIFT-PAGE_SHIFT)) &&
-			 (tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT))))
-			set_memory_4k((unsigned long)__va(tseg), 1);
+				(tseg>>PMD_SHIFT) >= (1ULL<<(32 - PMD_SHIFT))))
+				set_memory_4k((unsigned long)__va(tseg), 1);
 		}
 	}
 #endif
 }
 
 #ifdef CONFIG_X86_32
-static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
+static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c,
+							unsigned int size)
 {
 	/* AMD errata T13 (order #21922) */
 	if ((c->x86 == 6)) {
-		if (c->x86_model == 3 && c->x86_mask == 0)	/* Duron Rev A0 */
+		/* Duron Rev A0 */
+		if (c->x86_model == 3 && c->x86_mask == 0)
 			size = 64;
+		/* Tbird rev A1/A2 */
 		if (c->x86_model == 4 &&
-		    (c->x86_mask == 0 || c->x86_mask == 1))	/* Tbird rev A1/A2 */
+			(c->x86_mask == 0 || c->x86_mask == 1))
 			size = 256;
 	}
 	return size;
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index c8e315f..01a2652 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -81,7 +81,7 @@ static void __init check_fpu(void)
 
 	boot_cpu_data.fdiv_bug = fdiv_bug;
 	if (boot_cpu_data.fdiv_bug)
-		printk("Hmm, FPU with FDIV bug.\n");
+		printk(KERN_WARNING "Hmm, FPU with FDIV bug.\n");
 }
 
 static void __init check_hlt(void)
@@ -98,7 +98,7 @@ static void __init check_hlt(void)
 	halt();
 	halt();
 	halt();
-	printk("OK.\n");
+	printk(KERN_CONT "OK.\n");
 }
 
 /*
@@ -122,9 +122,9 @@ static void __init check_popad(void)
 	 * CPU hard. Too bad.
 	 */
 	if (res != 12345678)
-		printk("Buggy.\n");
+		printk(KERN_CONT "Buggy.\n");
 	else
-		printk("OK.\n");
+		printk(KERN_CONT "OK.\n");
 #endif
 }
 
@@ -156,7 +156,7 @@ void __init check_bugs(void)
 {
 	identify_boot_cpu();
 #ifndef CONFIG_SMP
-	printk("CPU: ");
+	printk(KERN_INFO "CPU: ");
 	print_cpu_info(&boot_cpu_data);
 #endif
 	check_config();
diff --git a/arch/x86/kernel/cpu/bugs_64.c b/arch/x86/kernel/cpu/bugs_64.c
index 9a3ed06..04f0fe5 100644
--- a/arch/x86/kernel/cpu/bugs_64.c
+++ b/arch/x86/kernel/cpu/bugs_64.c
@@ -15,7 +15,7 @@ void __init check_bugs(void)
 {
 	identify_boot_cpu();
 #if !defined(CONFIG_SMP)
-	printk("CPU: ");
+	printk(KERN_INFO "CPU: ");
 	print_cpu_info(&boot_cpu_data);
 #endif
 	alternative_instructions();
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 5ce60a8..cc25c2b 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -13,13 +13,13 @@
 #include <linux/io.h>
 
 #include <asm/stackprotector.h>
-#include <asm/perf_counter.h>
+#include <asm/perf_event.h>
 #include <asm/mmu_context.h>
 #include <asm/hypervisor.h>
 #include <asm/processor.h>
 #include <asm/sections.h>
-#include <asm/topology.h>
-#include <asm/cpumask.h>
+#include <linux/topology.h>
+#include <linux/cpumask.h>
 #include <asm/pgtable.h>
 #include <asm/atomic.h>
 #include <asm/proto.h>
@@ -28,13 +28,12 @@
 #include <asm/desc.h>
 #include <asm/i387.h>
 #include <asm/mtrr.h>
-#include <asm/numa.h>
+#include <linux/numa.h>
 #include <asm/asm.h>
 #include <asm/cpu.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
 #include <asm/pat.h>
-#include <asm/smp.h>
 
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/uv/uv.h>
@@ -94,45 +93,45 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
 	 * TLS descriptors are currently at a different place compared to i386.
 	 * Hopefully nobody expects them at a fixed place (Wine?)
 	 */
-	[GDT_ENTRY_KERNEL32_CS]		= { { { 0x0000ffff, 0x00cf9b00 } } },
-	[GDT_ENTRY_KERNEL_CS]		= { { { 0x0000ffff, 0x00af9b00 } } },
-	[GDT_ENTRY_KERNEL_DS]		= { { { 0x0000ffff, 0x00cf9300 } } },
-	[GDT_ENTRY_DEFAULT_USER32_CS]	= { { { 0x0000ffff, 0x00cffb00 } } },
-	[GDT_ENTRY_DEFAULT_USER_DS]	= { { { 0x0000ffff, 0x00cff300 } } },
-	[GDT_ENTRY_DEFAULT_USER_CS]	= { { { 0x0000ffff, 0x00affb00 } } },
+	[GDT_ENTRY_KERNEL32_CS]		= GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
+	[GDT_ENTRY_KERNEL_CS]		= GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
+	[GDT_ENTRY_KERNEL_DS]		= GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
+	[GDT_ENTRY_DEFAULT_USER32_CS]	= GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
+	[GDT_ENTRY_DEFAULT_USER_DS]	= GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
+	[GDT_ENTRY_DEFAULT_USER_CS]	= GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
 #else
-	[GDT_ENTRY_KERNEL_CS]		= { { { 0x0000ffff, 0x00cf9a00 } } },
-	[GDT_ENTRY_KERNEL_DS]		= { { { 0x0000ffff, 0x00cf9200 } } },
-	[GDT_ENTRY_DEFAULT_USER_CS]	= { { { 0x0000ffff, 0x00cffa00 } } },
-	[GDT_ENTRY_DEFAULT_USER_DS]	= { { { 0x0000ffff, 0x00cff200 } } },
+	[GDT_ENTRY_KERNEL_CS]		= GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
+	[GDT_ENTRY_KERNEL_DS]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
+	[GDT_ENTRY_DEFAULT_USER_CS]	= GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
+	[GDT_ENTRY_DEFAULT_USER_DS]	= GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
 	/*
 	 * Segments used for calling PnP BIOS have byte granularity.
 	 * They code segments and data segments have fixed 64k limits,
 	 * the transfer segment sizes are set at run time.
 	 */
 	/* 32-bit code */
-	[GDT_ENTRY_PNPBIOS_CS32]	= { { { 0x0000ffff, 0x00409a00 } } },
+	[GDT_ENTRY_PNPBIOS_CS32]	= GDT_ENTRY_INIT(0x409a, 0, 0xffff),
 	/* 16-bit code */
-	[GDT_ENTRY_PNPBIOS_CS16]	= { { { 0x0000ffff, 0x00009a00 } } },
+	[GDT_ENTRY_PNPBIOS_CS16]	= GDT_ENTRY_INIT(0x009a, 0, 0xffff),
 	/* 16-bit data */
-	[GDT_ENTRY_PNPBIOS_DS]		= { { { 0x0000ffff, 0x00009200 } } },
+	[GDT_ENTRY_PNPBIOS_DS]		= GDT_ENTRY_INIT(0x0092, 0, 0xffff),
 	/* 16-bit data */
-	[GDT_ENTRY_PNPBIOS_TS1]		= { { { 0x00000000, 0x00009200 } } },
+	[GDT_ENTRY_PNPBIOS_TS1]		= GDT_ENTRY_INIT(0x0092, 0, 0),
 	/* 16-bit data */
-	[GDT_ENTRY_PNPBIOS_TS2]		= { { { 0x00000000, 0x00009200 } } },
+	[GDT_ENTRY_PNPBIOS_TS2]		= GDT_ENTRY_INIT(0x0092, 0, 0),
 	/*
 	 * The APM segments have byte granularity and their bases
 	 * are set at run time.  All have 64k limits.
 	 */
 	/* 32-bit code */
-	[GDT_ENTRY_APMBIOS_BASE]	= { { { 0x0000ffff, 0x00409a00 } } },
+	[GDT_ENTRY_APMBIOS_BASE]	= GDT_ENTRY_INIT(0x409a, 0, 0xffff),
 	/* 16-bit code */
-	[GDT_ENTRY_APMBIOS_BASE+1]	= { { { 0x0000ffff, 0x00009a00 } } },
+	[GDT_ENTRY_APMBIOS_BASE+1]	= GDT_ENTRY_INIT(0x009a, 0, 0xffff),
 	/* data */
-	[GDT_ENTRY_APMBIOS_BASE+2]	= { { { 0x0000ffff, 0x00409200 } } },
+	[GDT_ENTRY_APMBIOS_BASE+2]	= GDT_ENTRY_INIT(0x4092, 0, 0xffff),
 
-	[GDT_ENTRY_ESPFIX_SS]		= { { { 0x0000ffff, 0x00cf9200 } } },
-	[GDT_ENTRY_PERCPU]		= { { { 0x0000ffff, 0x00cf9200 } } },
+	[GDT_ENTRY_ESPFIX_SS]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
+	[GDT_ENTRY_PERCPU]		= GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
 	GDT_STACK_CANARY_INIT
 #endif
 } };
@@ -870,7 +869,7 @@ void __init identify_boot_cpu(void)
 #else
 	vgetcpu_set_mode();
 #endif
-	init_hw_perf_counters();
+	init_hw_perf_events();
 }
 
 void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c)
@@ -982,18 +981,26 @@ static __init int setup_disablecpuid(char *arg)
 __setup("clearcpuid=", setup_disablecpuid);
 
 #ifdef CONFIG_X86_64
-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
+struct desc_ptr idt_descr = { NR_VECTORS * 16 - 1, (unsigned long) idt_table };
 
 DEFINE_PER_CPU_FIRST(union irq_stack_union,
 		     irq_stack_union) __aligned(PAGE_SIZE);
 
-DEFINE_PER_CPU(char *, irq_stack_ptr) =
-	init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
+/*
+ * The following four percpu variables are hot.  Align current_task to
+ * cacheline size such that all four fall in the same cacheline.
+ */
+DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =
+	&init_task;
+EXPORT_PER_CPU_SYMBOL(current_task);
 
 DEFINE_PER_CPU(unsigned long, kernel_stack) =
 	(unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;
 EXPORT_PER_CPU_SYMBOL(kernel_stack);
 
+DEFINE_PER_CPU(char *, irq_stack_ptr) =
+	init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
+
 DEFINE_PER_CPU(unsigned int, irq_count) = -1;
 
 /*
@@ -1008,8 +1015,7 @@ static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = {
 };
 
 static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
-	[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ])
-	__aligned(PAGE_SIZE);
+	[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]);
 
 /* May not be marked __init: used by software suspend */
 void syscall_init(void)
@@ -1042,8 +1048,11 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist);
 
 #else	/* CONFIG_X86_64 */
 
+DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
+EXPORT_PER_CPU_SYMBOL(current_task);
+
 #ifdef CONFIG_CC_STACKPROTECTOR
-DEFINE_PER_CPU(unsigned long, stack_canary);
+DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
 #endif
 
 /* Make sure %fs and %gs are initialized properly in idle threads */
diff --git a/arch/x86/kernel/cpu/cpu_debug.c b/arch/x86/kernel/cpu/cpu_debug.c
index 6b2a52d..dca325c 100644
--- a/arch/x86/kernel/cpu/cpu_debug.c
+++ b/arch/x86/kernel/cpu/cpu_debug.c
@@ -30,8 +30,8 @@
 #include <asm/apic.h>
 #include <asm/desc.h>
 
-static DEFINE_PER_CPU(struct cpu_cpuX_base, cpu_arr[CPU_REG_ALL_BIT]);
-static DEFINE_PER_CPU(struct cpu_private *, priv_arr[MAX_CPU_FILES]);
+static DEFINE_PER_CPU(struct cpu_cpuX_base [CPU_REG_ALL_BIT], cpu_arr);
+static DEFINE_PER_CPU(struct cpu_private * [MAX_CPU_FILES], priv_arr);
 static DEFINE_PER_CPU(int, cpu_priv_count);
 
 static DEFINE_MUTEX(cpu_debug_lock);
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index ae9b503..7d5c3b0 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 <trace/power.h>
+#include <trace/events/power.h>
 
 #include <linux/acpi.h>
 #include <linux/io.h>
@@ -60,7 +60,6 @@ enum {
 };
 
 #define INTEL_MSR_RANGE		(0xffff)
-#define CPUID_6_ECX_APERFMPERF_CAPABILITY	(0x1)
 
 struct acpi_cpufreq_data {
 	struct acpi_processor_performance *acpi_data;
@@ -71,13 +70,7 @@ struct acpi_cpufreq_data {
 
 static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
 
-struct acpi_msr_data {
-	u64 saved_aperf, saved_mperf;
-};
-
-static DEFINE_PER_CPU(struct acpi_msr_data, msr_data);
-
-DEFINE_TRACE(power_mark);
+static DEFINE_PER_CPU(struct aperfmperf, old_perf);
 
 /* acpi_perf_data is a pointer to percpu data. */
 static struct acpi_processor_performance *acpi_perf_data;
@@ -244,23 +237,12 @@ static u32 get_cur_val(const struct cpumask *mask)
 	return cmd.val;
 }
 
-struct perf_pair {
-	union {
-		struct {
-			u32 lo;
-			u32 hi;
-		} split;
-		u64 whole;
-	} aperf, mperf;
-};
-
 /* Called via smp_call_function_single(), on the target CPU */
 static void read_measured_perf_ctrs(void *_cur)
 {
-	struct perf_pair *cur = _cur;
+	struct aperfmperf *am = _cur;
 
-	rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi);
-	rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi);
+	get_aperfmperf(am);
 }
 
 /*
@@ -279,63 +261,17 @@ static void read_measured_perf_ctrs(void *_cur)
 static unsigned int get_measured_perf(struct cpufreq_policy *policy,
 				      unsigned int cpu)
 {
-	struct perf_pair readin, cur;
-	unsigned int perf_percent;
+	struct aperfmperf perf;
+	unsigned long ratio;
 	unsigned int retval;
 
-	if (smp_call_function_single(cpu, read_measured_perf_ctrs, &readin, 1))
+	if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
 		return 0;
 
-	cur.aperf.whole = readin.aperf.whole -
-				per_cpu(msr_data, cpu).saved_aperf;
-	cur.mperf.whole = readin.mperf.whole -
-				per_cpu(msr_data, cpu).saved_mperf;
-	per_cpu(msr_data, cpu).saved_aperf = readin.aperf.whole;
-	per_cpu(msr_data, cpu).saved_mperf = readin.mperf.whole;
-
-#ifdef __i386__
-	/*
-	 * We dont want to do 64 bit divide with 32 bit kernel
-	 * Get an approximate value. Return failure in case we cannot get
-	 * an approximate value.
-	 */
-	if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) {
-		int shift_count;
-		u32 h;
-
-		h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi);
-		shift_count = fls(h);
-
-		cur.aperf.whole >>= shift_count;
-		cur.mperf.whole >>= shift_count;
-	}
-
-	if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) {
-		int shift_count = 7;
-		cur.aperf.split.lo >>= shift_count;
-		cur.mperf.split.lo >>= shift_count;
-	}
-
-	if (cur.aperf.split.lo && cur.mperf.split.lo)
-		perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo;
-	else
-		perf_percent = 0;
-
-#else
-	if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) {
-		int shift_count = 7;
-		cur.aperf.whole >>= shift_count;
-		cur.mperf.whole >>= shift_count;
-	}
-
-	if (cur.aperf.whole && cur.mperf.whole)
-		perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole;
-	else
-		perf_percent = 0;
-
-#endif
+	ratio = calc_aperfmperf_ratio(&per_cpu(old_perf, cpu), &perf);
+	per_cpu(old_perf, cpu) = perf;
 
-	retval = (policy->cpuinfo.max_freq * perf_percent) / 100;
+	retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
 
 	return retval;
 }
@@ -394,7 +330,6 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
 	unsigned int next_perf_state = 0; /* Index into perf table */
 	unsigned int i;
 	int result = 0;
-	struct power_trace it;
 
 	dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);
 
@@ -426,7 +361,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
 		}
 	}
 
-	trace_power_mark(&it, POWER_PSTATE, next_perf_state);
+	trace_power_frequency(POWER_PSTATE, data->freq_table[next_state].frequency);
 
 	switch (data->cpu_feature) {
 	case SYSTEM_INTEL_MSR_CAPABLE:
@@ -588,6 +523,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = {
 	},
 	{ }
 };
+
+static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
+{
+	/* http://www.intel.com/Assets/PDF/specupdate/314554.pdf
+	 * AL30: A Machine Check Exception (MCE) Occurring during an
+	 * Enhanced Intel SpeedStep Technology Ratio Change May Cause
+	 * Both Processor Cores to Lock Up when HT is enabled*/
+	if (c->x86_vendor == X86_VENDOR_INTEL) {
+		if ((c->x86 == 15) &&
+		    (c->x86_model == 6) &&
+		    (c->x86_mask == 8) && smt_capable())
+			return -ENODEV;
+		}
+	return 0;
+}
 #endif
 
 static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
@@ -602,6 +552,12 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
 	dprintk("acpi_cpufreq_cpu_init\n");
 
+#ifdef CONFIG_SMP
+	result = acpi_cpufreq_blacklist(c);
+	if (result)
+		return result;
+#endif
+
 	data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
@@ -731,12 +687,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	acpi_processor_notify_smm(THIS_MODULE);
 
 	/* Check for APERF/MPERF support in hardware */
-	if (c->x86_vendor == X86_VENDOR_INTEL && c->cpuid_level >= 6) {
-		unsigned int ecx;
-		ecx = cpuid_ecx(6);
-		if (ecx & CPUID_6_ECX_APERFMPERF_CAPABILITY)
-			acpi_cpufreq_driver.getavg = get_measured_perf;
-	}
+	if (cpu_has(c, X86_FEATURE_APERFMPERF))
+		acpi_cpufreq_driver.getavg = get_measured_perf;
 
 	dprintk("CPU%u - ACPI performance management activated.\n", cpu);
 	for (i = 0; i < perf->state_count; i++)
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 2a50ef8..6394aa5 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -605,9 +605,10 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
 	return 0;
 }
 
-static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
+static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
+		unsigned int entry)
 {
-	data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
 }
 
 static void print_basics(struct powernow_k8_data *data)
@@ -854,6 +855,10 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 		goto err_out;
 	}
 
+	/* fill in data */
+	data->numps = data->acpi_data.state_count;
+	powernow_k8_acpi_pst_values(data, 0);
+
 	if (cpu_family == CPU_HW_PSTATE)
 		ret_val = fill_powernow_table_pstate(data, powernow_table);
 	else
@@ -866,11 +871,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 	powernow_table[data->acpi_data.state_count].index = 0;
 	data->powernow_table = powernow_table;
 
-	/* fill in data */
-	data->numps = data->acpi_data.state_count;
 	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
 		print_basics(data);
-	powernow_k8_acpi_pst_values(data, 0);
 
 	/* notify BIOS that we exist */
 	acpi_processor_notify_smm(THIS_MODULE);
@@ -914,13 +916,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
 					"bad value %d.\n", i, index);
 			printk(KERN_ERR PFX "Please report to BIOS "
 					"manufacturer\n");
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 		rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
 		if (!(hi & HW_PSTATE_VALID_MASK)) {
 			dprintk("invalid pstate %d, ignoring\n", index);
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 
@@ -941,7 +943,6 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
 		struct cpufreq_frequency_table *powernow_table)
 {
 	int i;
-	int cntlofreq = 0;
 
 	for (i = 0; i < data->acpi_data.state_count; i++) {
 		u32 fid;
@@ -970,7 +971,7 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
 		/* verify frequency is OK */
 		if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
 			dprintk("invalid freq %u kHz, ignoring\n", freq);
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 
@@ -978,38 +979,17 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
 		 * BIOSs are using "off" to indicate invalid */
 		if (vid == VID_OFF) {
 			dprintk("invalid vid %u, ignoring\n", vid);
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 
-		/* verify only 1 entry from the lo frequency table */
-		if (fid < HI_FID_TABLE_BOTTOM) {
-			if (cntlofreq) {
-				/* if both entries are the same,
-				 * ignore this one ... */
-				if ((freq != powernow_table[cntlofreq].frequency) ||
-				    (index != powernow_table[cntlofreq].index)) {
-					printk(KERN_ERR PFX
-						"Too many lo freq table "
-						"entries\n");
-					return 1;
-				}
-
-				dprintk("double low frequency table entry, "
-						"ignoring it.\n");
-				invalidate_entry(data, i);
-				continue;
-			} else
-				cntlofreq = i;
-		}
-
 		if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
 			printk(KERN_INFO PFX "invalid freq entries "
 				"%u kHz vs. %u kHz\n", freq,
 				(unsigned int)
 				(data->acpi_data.states[i].core_frequency
 				 * 1000));
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 	}
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index 593171e..19807b8 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -3,10 +3,10 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <asm/dma.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/processor-cyrix.h>
 #include <asm/processor-flags.h>
-#include <asm/timer.h>
+#include <linux/timer.h>
 #include <asm/pci-direct.h>
 #include <asm/tsc.h>
 
@@ -282,7 +282,8 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
 		 *  The 5510/5520 companion chips have a funky PIT.
 		 */
 		if (vendor == PCI_VENDOR_ID_CYRIX &&
-	 (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520))
+			(device == PCI_DEVICE_ID_CYRIX_5510 ||
+					device == PCI_DEVICE_ID_CYRIX_5520))
 			mark_tsc_unstable("cyrix 5510/5520 detected");
 	}
 #endif
@@ -299,7 +300,8 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
 			 *  ?  : 0x7x
 			 * GX1 : 0x8x          GX1  datasheet 56
 			 */
-			if ((0x30 <= dir1 && dir1 <= 0x6f) || (0x80 <= dir1 && dir1 <= 0x8f))
+			if ((0x30 <= dir1 && dir1 <= 0x6f) ||
+					(0x80 <= dir1 && dir1 <= 0x8f))
 				geode_configure();
 			return;
 		} else { /* MediaGX */
@@ -427,9 +429,12 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 *c)
 			printk(KERN_INFO "Enabling CPUID on Cyrix processor.\n");
 			local_irq_save(flags);
 			ccr3 = getCx86(CX86_CCR3);
-			setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);       /* enable MAPEN  */
-			setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x80);  /* enable cpuid  */
-			setCx86(CX86_CCR3, ccr3);                       /* disable MAPEN */
+			/* enable MAPEN  */
+			setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
+			/* enable cpuid  */
+			setCx86_old(CX86_CCR4, getCx86_old(CX86_CCR4) | 0x80);
+			/* disable MAPEN */
+			setCx86(CX86_CCR3, ccr3);
 			local_irq_restore(flags);
 		}
 	}
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index fb5b86a..08be922 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -28,18 +28,10 @@
 static inline void __cpuinit
 detect_hypervisor_vendor(struct cpuinfo_x86 *c)
 {
-	if (vmware_platform()) {
+	if (vmware_platform())
 		c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE;
-	} else {
+	else
 		c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
-	}
-}
-
-unsigned long get_hypervisor_tsc_freq(void)
-{
-	if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
-		return vmware_get_tsc_khz();
-	return 0;
 }
 
 static inline void __cpuinit
@@ -56,3 +48,10 @@ void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
 	detect_hypervisor_vendor(c);
 	hypervisor_set_feature_bits(c);
 }
+
+void __init init_hypervisor_platform(void)
+{
+	init_hypervisor(&boot_cpu_data);
+	if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
+		vmware_platform_setup();
+}
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 3260ab0..40e1835 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -7,17 +7,17 @@
 #include <linux/sched.h>
 #include <linux/thread_info.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 
 #include <asm/processor.h>
 #include <asm/pgtable.h>
 #include <asm/msr.h>
-#include <asm/uaccess.h>
 #include <asm/ds.h>
 #include <asm/bugs.h>
 #include <asm/cpu.h>
 
 #ifdef CONFIG_X86_64
-#include <asm/topology.h>
+#include <linux/topology.h>
 #include <asm/numa_64.h>
 #endif
 
@@ -174,7 +174,8 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
 #ifdef CONFIG_X86_F00F_BUG
 	/*
 	 * All current models of Pentium and Pentium with MMX technology CPUs
-	 * have the F0 0F bug, which lets nonprivileged users lock up the system.
+	 * have the F0 0F bug, which lets nonprivileged users lock up the
+	 * system.
 	 * Note that the workaround only should be initialized once...
 	 */
 	c->f00f_bug = 0;
@@ -207,7 +208,7 @@ static void __cpuinit intel_workarounds(struct cpuinfo_x86 *c)
 			printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n");
 			printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n");
 			lo |= MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE;
-			wrmsr (MSR_IA32_MISC_ENABLE, lo, hi);
+			wrmsr(MSR_IA32_MISC_ENABLE, lo, hi);
 		}
 	}
 
@@ -283,7 +284,7 @@ static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
 	/* Intel has a non-standard dependency on %ecx for this CPUID level. */
 	cpuid_count(4, 0, &eax, &ebx, &ecx, &edx);
 	if (eax & 0x1f)
-		return ((eax >> 26) + 1);
+		return (eax >> 26) + 1;
 	else
 		return 1;
 }
@@ -349,6 +350,12 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
 			set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
 	}
 
+	if (c->cpuid_level > 6) {
+		unsigned ecx = cpuid_ecx(6);
+		if (ecx & 0x01)
+			set_cpu_cap(c, X86_FEATURE_APERFMPERF);
+	}
+
 	if (cpu_has_xmm2)
 		set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
 	if (cpu_has_ds) {
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 789efe2..804c40e 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -3,7 +3,7 @@
  *
  *	Changes:
  *	Venkatesh Pallipadi	: Adding cache identification through cpuid(4)
- *		Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
+ *	Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
  *	Andi Kleen / Andreas Herrmann	: CPUID4 emulation on AMD.
  */
 
@@ -16,7 +16,7 @@
 #include <linux/pci.h>
 
 #include <asm/processor.h>
-#include <asm/smp.h>
+#include <linux/smp.h>
 #include <asm/k8.h>
 
 #define LVL_1_INST	1
@@ -25,14 +25,15 @@
 #define LVL_3		4
 #define LVL_TRACE	5
 
-struct _cache_table
-{
+struct _cache_table {
 	unsigned char descriptor;
 	char cache_type;
 	short size;
 };
 
-/* all the cache descriptor types we care about (no TLB or trace cache entries) */
+/* All the cache descriptor types we care about (no TLB or
+   trace cache entries) */
+
 static const struct _cache_table __cpuinitconst cache_table[] =
 {
 	{ 0x06, LVL_1_INST, 8 },	/* 4-way set assoc, 32 byte line size */
@@ -105,8 +106,7 @@ static const struct _cache_table __cpuinitconst cache_table[] =
 };
 
 
-enum _cache_type
-{
+enum _cache_type {
 	CACHE_TYPE_NULL	= 0,
 	CACHE_TYPE_DATA = 1,
 	CACHE_TYPE_INST = 2,
@@ -170,31 +170,31 @@ unsigned short			num_cache_leaves;
    Maybe later */
 union l1_cache {
 	struct {
-		unsigned line_size : 8;
-		unsigned lines_per_tag : 8;
-		unsigned assoc : 8;
-		unsigned size_in_kb : 8;
+		unsigned line_size:8;
+		unsigned lines_per_tag:8;
+		unsigned assoc:8;
+		unsigned size_in_kb:8;
 	};
 	unsigned val;
 };
 
 union l2_cache {
 	struct {
-		unsigned line_size : 8;
-		unsigned lines_per_tag : 4;
-		unsigned assoc : 4;
-		unsigned size_in_kb : 16;
+		unsigned line_size:8;
+		unsigned lines_per_tag:4;
+		unsigned assoc:4;
+		unsigned size_in_kb:16;
 	};
 	unsigned val;
 };
 
 union l3_cache {
 	struct {
-		unsigned line_size : 8;
-		unsigned lines_per_tag : 4;
-		unsigned assoc : 4;
-		unsigned res : 2;
-		unsigned size_encoded : 14;
+		unsigned line_size:8;
+		unsigned lines_per_tag:4;
+		unsigned assoc:4;
+		unsigned res:2;
+		unsigned size_encoded:14;
 	};
 	unsigned val;
 };
@@ -241,7 +241,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	case 0:
 		if (!l1->val)
 			return;
-		assoc = l1->assoc;
+		assoc = assocs[l1->assoc];
 		line_size = l1->line_size;
 		lines_per_tag = l1->lines_per_tag;
 		size_in_kb = l1->size_in_kb;
@@ -249,7 +249,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	case 2:
 		if (!l2.val)
 			return;
-		assoc = l2.assoc;
+		assoc = assocs[l2.assoc];
 		line_size = l2.line_size;
 		lines_per_tag = l2.lines_per_tag;
 		/* cpu_data has errata corrections for K7 applied */
@@ -258,10 +258,14 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	case 3:
 		if (!l3.val)
 			return;
-		assoc = l3.assoc;
+		assoc = assocs[l3.assoc];
 		line_size = l3.line_size;
 		lines_per_tag = l3.lines_per_tag;
 		size_in_kb = l3.size_encoded * 512;
+		if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
+			size_in_kb = size_in_kb >> 1;
+			assoc = assoc >> 1;
+		}
 		break;
 	default:
 		return;
@@ -270,18 +274,14 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
 	eax->split.is_self_initializing = 1;
 	eax->split.type = types[leaf];
 	eax->split.level = levels[leaf];
-	if (leaf == 3)
-		eax->split.num_threads_sharing =
-			current_cpu_data.x86_max_cores - 1;
-	else
-		eax->split.num_threads_sharing = 0;
+	eax->split.num_threads_sharing = 0;
 	eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
 
 
-	if (assoc == 0xf)
+	if (assoc == 0xffff)
 		eax->split.is_fully_associative = 1;
 	ebx->split.coherency_line_size = line_size - 1;
-	ebx->split.ways_of_associativity = assocs[assoc] - 1;
+	ebx->split.ways_of_associativity = assoc - 1;
 	ebx->split.physical_line_partition = lines_per_tag - 1;
 	ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
 		(ebx->split.ways_of_associativity + 1) - 1;
@@ -350,7 +350,8 @@ static int __cpuinit find_num_cache_leaves(void)
 
 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 {
-	unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
+	/* Cache sizes */
+	unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
 	unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
 	unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
 	unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
@@ -377,8 +378,8 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 
 			retval = cpuid4_cache_lookup_regs(i, &this_leaf);
 			if (retval >= 0) {
-				switch(this_leaf.eax.split.level) {
-				    case 1:
+				switch (this_leaf.eax.split.level) {
+				case 1:
 					if (this_leaf.eax.split.type ==
 							CACHE_TYPE_DATA)
 						new_l1d = this_leaf.size/1024;
@@ -386,19 +387,20 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 							CACHE_TYPE_INST)
 						new_l1i = this_leaf.size/1024;
 					break;
-				    case 2:
+				case 2:
 					new_l2 = this_leaf.size/1024;
 					num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
 					index_msb = get_count_order(num_threads_sharing);
 					l2_id = c->apicid >> index_msb;
 					break;
-				    case 3:
+				case 3:
 					new_l3 = this_leaf.size/1024;
 					num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
-					index_msb = get_count_order(num_threads_sharing);
+					index_msb = get_count_order(
+							num_threads_sharing);
 					l3_id = c->apicid >> index_msb;
 					break;
-				    default:
+				default:
 					break;
 				}
 			}
@@ -421,22 +423,21 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 		/* Number of times to iterate */
 		n = cpuid_eax(2) & 0xFF;
 
-		for ( i = 0 ; i < n ; i++ ) {
+		for (i = 0 ; i < n ; i++) {
 			cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
 
 			/* If bit 31 is set, this is an unknown format */
-			for ( j = 0 ; j < 3 ; j++ ) {
-				if (regs[j] & (1 << 31)) regs[j] = 0;
-			}
+			for (j = 0 ; j < 3 ; j++)
+				if (regs[j] & (1 << 31))
+					regs[j] = 0;
 
 			/* Byte 0 is level count, not a descriptor */
-			for ( j = 1 ; j < 16 ; j++ ) {
+			for (j = 1 ; j < 16 ; j++) {
 				unsigned char des = dp[j];
 				unsigned char k = 0;
 
 				/* look up this descriptor in the table */
-				while (cache_table[k].descriptor != 0)
-				{
+				while (cache_table[k].descriptor != 0) {
 					if (cache_table[k].descriptor == des) {
 						if (only_trace && cache_table[k].cache_type != LVL_TRACE)
 							break;
@@ -488,14 +489,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
 	}
 
 	if (trace)
-		printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
-	else if ( l1i )
-		printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
+		printk(KERN_INFO "CPU: Trace cache: %dK uops", trace);
+	else if (l1i)
+		printk(KERN_INFO "CPU: L1 I cache: %dK", l1i);
 
 	if (l1d)
-		printk(", L1 D cache: %dK\n", l1d);
+		printk(KERN_CONT ", L1 D cache: %dK\n", l1d);
 	else
-		printk("\n");
+		printk(KERN_CONT "\n");
 
 	if (l2)
 		printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
@@ -522,6 +523,18 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 	int index_msb, i;
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 
+	if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
+		struct cpuinfo_x86 *d;
+		for_each_online_cpu(i) {
+			if (!per_cpu(cpuid4_info, i))
+				continue;
+			d = &cpu_data(i);
+			this_leaf = CPUID4_INFO_IDX(i, index);
+			cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
+				     d->llc_shared_map);
+		}
+		return;
+	}
 	this_leaf = CPUID4_INFO_IDX(cpu, index);
 	num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
 
@@ -558,8 +571,13 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
 	}
 }
 #else
-static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
-static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+{
+}
+
+static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
+{
+}
 #endif
 
 static void __cpuinit free_cache_attributes(unsigned int cpu)
@@ -645,7 +663,7 @@ static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
 static ssize_t show_##file_name						\
 			(struct _cpuid4_info *this_leaf, char *buf)	\
 {									\
-	return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
+	return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
 }
 
 show_one_plus(level, eax.split.level, 0);
@@ -656,7 +674,7 @@ show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
 
 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
 {
-	return sprintf (buf, "%luK\n", this_leaf->size / 1024);
+	return sprintf(buf, "%luK\n", this_leaf->size / 1024);
 }
 
 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
@@ -669,7 +687,7 @@ static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
 		const struct cpumask *mask;
 
 		mask = to_cpumask(this_leaf->shared_cpu_map);
-		n = type?
+		n = type ?
 			cpulist_scnprintf(buf, len-2, mask) :
 			cpumask_scnprintf(buf, len-2, mask);
 		buf[n++] = '\n';
@@ -800,7 +818,7 @@ static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
 static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
 		show_cache_disable_1, store_cache_disable_1);
 
-static struct attribute * default_attrs[] = {
+static struct attribute *default_attrs[] = {
 	&type.attr,
 	&level.attr,
 	&coherency_line_size.attr,
@@ -815,7 +833,7 @@ static struct attribute * default_attrs[] = {
 	NULL
 };
 
-static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
 {
 	struct _cache_attr *fattr = to_attr(attr);
 	struct _index_kobject *this_leaf = to_object(kobj);
@@ -828,8 +846,8 @@ static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
 	return ret;
 }
 
-static ssize_t store(struct kobject * kobj, struct attribute * attr,
-		     const char * buf, size_t count)
+static ssize_t store(struct kobject *kobj, struct attribute *attr,
+		     const char *buf, size_t count)
 {
 	struct _cache_attr *fattr = to_attr(attr);
 	struct _index_kobject *this_leaf = to_object(kobj);
@@ -883,7 +901,7 @@ static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
 		goto err_out;
 
 	per_cpu(index_kobject, cpu) = kzalloc(
-	    sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
+	    sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
 	if (unlikely(per_cpu(index_kobject, cpu) == NULL))
 		goto err_out;
 
@@ -917,7 +935,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 	}
 
 	for (i = 0; i < num_cache_leaves; i++) {
-		this_object = INDEX_KOBJECT_PTR(cpu,i);
+		this_object = INDEX_KOBJECT_PTR(cpu, i);
 		this_object->cpu = cpu;
 		this_object->index = i;
 		retval = kobject_init_and_add(&(this_object->kobj),
@@ -925,9 +943,8 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 					      per_cpu(cache_kobject, cpu),
 					      "index%1lu", i);
 		if (unlikely(retval)) {
-			for (j = 0; j < i; j++) {
-				kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
-			}
+			for (j = 0; j < i; j++)
+				kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
 			kobject_put(per_cpu(cache_kobject, cpu));
 			cpuid4_cache_sysfs_exit(cpu);
 			return retval;
@@ -952,7 +969,7 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
 	cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
 
 	for (i = 0; i < num_cache_leaves; i++)
-		kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
+		kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
 	kobject_put(per_cpu(cache_kobject, cpu));
 	cpuid4_cache_sysfs_exit(cpu);
 }
@@ -977,8 +994,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
-{
+static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
 	.notifier_call = cacheinfo_cpu_callback,
 };
 
diff --git a/arch/x86/kernel/cpu/mcheck/Makefile b/arch/x86/kernel/cpu/mcheck/Makefile
index 188a1ca..4ac6d48 100644
--- a/arch/x86/kernel/cpu/mcheck/Makefile
+++ b/arch/x86/kernel/cpu/mcheck/Makefile
@@ -1,11 +1,8 @@
-obj-y				=  mce.o
+obj-y				=  mce.o mce-severity.o
 
-obj-$(CONFIG_X86_NEW_MCE)	+= mce-severity.o
-obj-$(CONFIG_X86_OLD_MCE)	+= k7.o p4.o p6.o
 obj-$(CONFIG_X86_ANCIENT_MCE)	+= winchip.o p5.o
 obj-$(CONFIG_X86_MCE_INTEL)	+= mce_intel.o
 obj-$(CONFIG_X86_MCE_AMD)	+= mce_amd.o
-obj-$(CONFIG_X86_MCE_NONFATAL)	+= non-fatal.o
 obj-$(CONFIG_X86_MCE_THRESHOLD) += threshold.o
 obj-$(CONFIG_X86_MCE_INJECT)	+= mce-inject.o
 
diff --git a/arch/x86/kernel/cpu/mcheck/k7.c b/arch/x86/kernel/cpu/mcheck/k7.c
deleted file mode 100644
index b945d5d..0000000
--- a/arch/x86/kernel/cpu/mcheck/k7.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Athlon specific Machine Check Exception Reporting
- * (C) Copyright 2002 Dave Jones <davej@redhat.com>
- */
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-/* Machine Check Handler For AMD Athlon/Duron: */
-static void k7_machine_check(struct pt_regs *regs, long error_code)
-{
-	u32 alow, ahigh, high, low;
-	u32 mcgstl, mcgsth;
-	int recover = 1;
-	int i;
-
-	rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-	if (mcgstl & (1<<0))	/* Recoverable ? */
-		recover = 0;
-
-	printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
-		smp_processor_id(), mcgsth, mcgstl);
-
-	for (i = 1; i < nr_mce_banks; i++) {
-		rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-		if (high & (1<<31)) {
-			char misc[20];
-			char addr[24];
-
-			misc[0] = '\0';
-			addr[0] = '\0';
-
-			if (high & (1<<29))
-				recover |= 1;
-			if (high & (1<<25))
-				recover |= 2;
-			high &= ~(1<<31);
-
-			if (high & (1<<27)) {
-				rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
-				snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
-			}
-			if (high & (1<<26)) {
-				rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
-				snprintf(addr, 24, " at %08x%08x", ahigh, alow);
-			}
-
-			printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
-				smp_processor_id(), i, high, low, misc, addr);
-
-			/* Clear it: */
-			wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
-			/* Serialize: */
-			wmb();
-			add_taint(TAINT_MACHINE_CHECK);
-		}
-	}
-
-	if (recover & 2)
-		panic("CPU context corrupt");
-	if (recover & 1)
-		panic("Unable to continue");
-
-	printk(KERN_EMERG "Attempting to continue.\n");
-
-	mcgstl &= ~(1<<2);
-	wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-}
-
-
-/* AMD K7 machine check is Intel like: */
-void amd_mcheck_init(struct cpuinfo_x86 *c)
-{
-	u32 l, h;
-	int i;
-
-	if (!cpu_has(c, X86_FEATURE_MCE))
-		return;
-
-	machine_check_vector = k7_machine_check;
-	/* Make sure the vector pointer is visible before we enable MCEs: */
-	wmb();
-
-	printk(KERN_INFO "Intel machine check architecture supported.\n");
-
-	rdmsr(MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<8))	/* Control register present ? */
-		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-	nr_mce_banks = l & 0xff;
-
-	/*
-	 * Clear status for MC index 0 separately, we don't touch CTL,
-	 * as some K7 Athlons cause spurious MCEs when its enabled:
-	 */
-	if (boot_cpu_data.x86 == 6) {
-		wrmsr(MSR_IA32_MC0_STATUS, 0x0, 0x0);
-		i = 1;
-	} else
-		i = 0;
-
-	for (; i < nr_mce_banks; i++) {
-		wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-		wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-	}
-
-	set_in_cr4(X86_CR4_MCE);
-	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
-		smp_processor_id());
-}
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index a3a235a..7029f0e 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -18,7 +18,12 @@
 #include <linux/string.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
+#include <linux/notifier.h>
+#include <linux/kdebug.h>
+#include <linux/cpu.h>
+#include <linux/sched.h>
 #include <asm/mce.h>
+#include <asm/apic.h>
 
 /* Update fake mce registers on current CPU. */
 static void inject_mce(struct mce *m)
@@ -39,44 +44,141 @@ static void inject_mce(struct mce *m)
 	i->finished = 1;
 }
 
-struct delayed_mce {
-	struct timer_list timer;
-	struct mce m;
-};
+static void raise_poll(struct mce *m)
+{
+	unsigned long flags;
+	mce_banks_t b;
 
-/* Inject mce on current CPU */
-static void raise_mce(unsigned long data)
+	memset(&b, 0xff, sizeof(mce_banks_t));
+	local_irq_save(flags);
+	machine_check_poll(0, &b);
+	local_irq_restore(flags);
+	m->finished = 0;
+}
+
+static void raise_exception(struct mce *m, struct pt_regs *pregs)
 {
-	struct delayed_mce *dm = (struct delayed_mce *)data;
-	struct mce *m = &dm->m;
-	int cpu = m->extcpu;
+	struct pt_regs regs;
+	unsigned long flags;
 
-	inject_mce(m);
-	if (m->status & MCI_STATUS_UC) {
-		struct pt_regs regs;
+	if (!pregs) {
 		memset(&regs, 0, sizeof(struct pt_regs));
 		regs.ip = m->ip;
 		regs.cs = m->cs;
+		pregs = &regs;
+	}
+	/* in mcheck exeception handler, irq will be disabled */
+	local_irq_save(flags);
+	do_machine_check(pregs, 0);
+	local_irq_restore(flags);
+	m->finished = 0;
+}
+
+static cpumask_t mce_inject_cpumask;
+
+static int mce_raise_notify(struct notifier_block *self,
+			    unsigned long val, void *data)
+{
+	struct die_args *args = (struct die_args *)data;
+	int cpu = smp_processor_id();
+	struct mce *m = &__get_cpu_var(injectm);
+	if (val != DIE_NMI_IPI || !cpu_isset(cpu, mce_inject_cpumask))
+		return NOTIFY_DONE;
+	cpu_clear(cpu, mce_inject_cpumask);
+	if (m->inject_flags & MCJ_EXCEPTION)
+		raise_exception(m, args->regs);
+	else if (m->status)
+		raise_poll(m);
+	return NOTIFY_STOP;
+}
+
+static struct notifier_block mce_raise_nb = {
+	.notifier_call = mce_raise_notify,
+	.priority = 1000,
+};
+
+/* Inject mce on current CPU */
+static int raise_local(struct mce *m)
+{
+	int context = MCJ_CTX(m->inject_flags);
+	int ret = 0;
+	int cpu = m->extcpu;
+
+	if (m->inject_flags & MCJ_EXCEPTION) {
 		printk(KERN_INFO "Triggering MCE exception on CPU %d\n", cpu);
-		do_machine_check(&regs, 0);
+		switch (context) {
+		case MCJ_CTX_IRQ:
+			/*
+			 * Could do more to fake interrupts like
+			 * calling irq_enter, but the necessary
+			 * machinery isn't exported currently.
+			 */
+			/*FALL THROUGH*/
+		case MCJ_CTX_PROCESS:
+			raise_exception(m, NULL);
+			break;
+		default:
+			printk(KERN_INFO "Invalid MCE context\n");
+			ret = -EINVAL;
+		}
 		printk(KERN_INFO "MCE exception done on CPU %d\n", cpu);
-	} else {
-		mce_banks_t b;
-		memset(&b, 0xff, sizeof(mce_banks_t));
+	} else if (m->status) {
 		printk(KERN_INFO "Starting machine check poll CPU %d\n", cpu);
-		machine_check_poll(0, &b);
+		raise_poll(m);
 		mce_notify_irq();
-		printk(KERN_INFO "Finished machine check poll on CPU %d\n",
-		       cpu);
-	}
-	kfree(dm);
+		printk(KERN_INFO "Machine check poll done on CPU %d\n", cpu);
+	} else
+		m->finished = 0;
+
+	return ret;
+}
+
+static void raise_mce(struct mce *m)
+{
+	int context = MCJ_CTX(m->inject_flags);
+
+	inject_mce(m);
+
+	if (context == MCJ_CTX_RANDOM)
+		return;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	if (m->inject_flags & MCJ_NMI_BROADCAST) {
+		unsigned long start;
+		int cpu;
+		get_online_cpus();
+		mce_inject_cpumask = cpu_online_map;
+		cpu_clear(get_cpu(), mce_inject_cpumask);
+		for_each_online_cpu(cpu) {
+			struct mce *mcpu = &per_cpu(injectm, cpu);
+			if (!mcpu->finished ||
+			    MCJ_CTX(mcpu->inject_flags) != MCJ_CTX_RANDOM)
+				cpu_clear(cpu, mce_inject_cpumask);
+		}
+		if (!cpus_empty(mce_inject_cpumask))
+			apic->send_IPI_mask(&mce_inject_cpumask, NMI_VECTOR);
+		start = jiffies;
+		while (!cpus_empty(mce_inject_cpumask)) {
+			if (!time_before(jiffies, start + 2*HZ)) {
+				printk(KERN_ERR
+				"Timeout waiting for mce inject NMI %lx\n",
+					*cpus_addr(mce_inject_cpumask));
+				break;
+			}
+			cpu_relax();
+		}
+		raise_local(m);
+		put_cpu();
+		put_online_cpus();
+	} else
+#endif
+		raise_local(m);
 }
 
 /* Error injection interface */
 static ssize_t mce_write(struct file *filp, const char __user *ubuf,
 			 size_t usize, loff_t *off)
 {
-	struct delayed_mce *dm;
 	struct mce m;
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -96,19 +198,12 @@ static ssize_t mce_write(struct file *filp, const char __user *ubuf,
 	if (m.extcpu >= num_possible_cpus() || !cpu_online(m.extcpu))
 		return -EINVAL;
 
-	dm = kmalloc(sizeof(struct delayed_mce), GFP_KERNEL);
-	if (!dm)
-		return -ENOMEM;
-
 	/*
 	 * Need to give user space some time to set everything up,
 	 * so do it a jiffie or two later everywhere.
-	 * Should we use a hrtimer here for better synchronization?
 	 */
-	memcpy(&dm->m, &m, sizeof(struct mce));
-	setup_timer(&dm->timer, raise_mce, (unsigned long)dm);
-	dm->timer.expires = jiffies + 2;
-	add_timer_on(&dm->timer, m.extcpu);
+	schedule_timeout(2);
+	raise_mce(&m);
 	return usize;
 }
 
@@ -116,6 +211,7 @@ static int inject_init(void)
 {
 	printk(KERN_INFO "Machine check injector initialized\n");
 	mce_chrdev_ops.write = mce_write;
+	register_die_notifier(&mce_raise_nb);
 	return 0;
 }
 
diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h
index 54dcb8f..32996f9 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h
+++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h
@@ -1,3 +1,4 @@
+#include <linux/sysdev.h>
 #include <asm/mce.h>
 
 enum severity_level {
@@ -10,6 +11,20 @@ enum severity_level {
 	MCE_PANIC_SEVERITY,
 };
 
+#define ATTR_LEN		16
+
+/* One object for each MCE bank, shared by all CPUs */
+struct mce_bank {
+	u64			ctl;			/* subevents to enable */
+	unsigned char init;				/* initialise bank? */
+	struct sysdev_attribute attr;			/* sysdev attribute */
+	char			attrname[ATTR_LEN];	/* attribute name */
+};
+
 int mce_severity(struct mce *a, int tolerant, char **msg);
+struct dentry *mce_get_debugfs_dir(void);
 
 extern int mce_ser;
+
+extern struct mce_bank *mce_banks;
+
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index ff0807f..8a85dd1 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -139,6 +139,7 @@ int mce_severity(struct mce *a, int tolerant, char **msg)
 	}
 }
 
+#ifdef CONFIG_DEBUG_FS
 static void *s_start(struct seq_file *f, loff_t *pos)
 {
 	if (*pos >= ARRAY_SIZE(severities))
@@ -197,7 +198,7 @@ static int __init severities_debugfs_init(void)
 {
 	struct dentry *dmce = NULL, *fseverities_coverage = NULL;
 
-	dmce = debugfs_create_dir("mce", NULL);
+	dmce = mce_get_debugfs_dir();
 	if (dmce == NULL)
 		goto err_out;
 	fseverities_coverage = debugfs_create_file("severities-coverage",
@@ -209,10 +210,7 @@ static int __init severities_debugfs_init(void)
 	return 0;
 
 err_out:
-	if (fseverities_coverage)
-		debugfs_remove(fseverities_coverage);
-	if (dmce)
-		debugfs_remove(dmce);
 	return -ENOMEM;
 }
 late_initcall(severities_debugfs_init);
+#endif
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 0121304..2f5aab2 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -34,6 +34,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/debugfs.h>
 
 #include <asm/processor.h>
 #include <asm/hw_irq.h>
@@ -45,21 +46,8 @@
 
 #include "mce-internal.h"
 
-/* Handle unconfigured int18 (should never happen) */
-static void unexpected_machine_check(struct pt_regs *regs, long error_code)
-{
-	printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n",
-	       smp_processor_id());
-}
-
-/* Call the installed machine check handler for this CPU setup. */
-void (*machine_check_vector)(struct pt_regs *, long error_code) =
-						unexpected_machine_check;
-
 int mce_disabled __read_mostly;
 
-#ifdef CONFIG_X86_NEW_MCE
-
 #define MISC_MCELOG_MINOR	227
 
 #define SPINUNIT 100	/* 100ns */
@@ -77,7 +65,6 @@ DEFINE_PER_CPU(unsigned, mce_exception_count);
  */
 static int			tolerant		__read_mostly = 1;
 static int			banks			__read_mostly;
-static u64			*bank			__read_mostly;
 static int			rip_msr			__read_mostly;
 static int			mce_bootlog		__read_mostly = -1;
 static int			monarch_timeout		__read_mostly = -1;
@@ -87,13 +74,13 @@ int				mce_cmci_disabled	__read_mostly;
 int				mce_ignore_ce		__read_mostly;
 int				mce_ser			__read_mostly;
 
+struct mce_bank                *mce_banks		__read_mostly;
+
 /* User mode helper program triggered by machine check event */
 static unsigned long		mce_need_notify;
 static char			mce_helper[128];
 static char			*mce_helper_argv[2] = { mce_helper, NULL };
 
-static unsigned long		dont_init_banks;
-
 static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
 static DEFINE_PER_CPU(struct mce, mces_seen);
 static int			cpu_missing;
@@ -104,11 +91,6 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
 	[0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
 };
 
-static inline int skip_bank_init(int i)
-{
-	return i < BITS_PER_LONG && test_bit(i, &dont_init_banks);
-}
-
 static DEFINE_PER_CPU(struct work_struct, mce_work);
 
 /* Do initial initialization of a struct mce */
@@ -183,6 +165,11 @@ void mce_log(struct mce *mce)
 	set_bit(0, &mce_need_notify);
 }
 
+void __weak decode_mce(struct mce *m)
+{
+	return;
+}
+
 static void print_mce(struct mce *m)
 {
 	printk(KERN_EMERG
@@ -205,6 +192,8 @@ static void print_mce(struct mce *m)
 	printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
 			m->cpuvendor, m->cpuid, m->time, m->socketid,
 			m->apicid);
+
+	decode_mce(m);
 }
 
 static void print_mce_head(void)
@@ -215,13 +204,19 @@ static void print_mce_head(void)
 static void print_mce_tail(void)
 {
 	printk(KERN_EMERG "This is not a software problem!\n"
-	       "Run through mcelog --ascii to decode and contact your hardware vendor\n");
+#if (!defined(CONFIG_EDAC) || !defined(CONFIG_CPU_SUP_AMD))
+	       "Run through mcelog --ascii to decode and contact your hardware vendor\n"
+#endif
+	       );
 }
 
 #define PANIC_TIMEOUT 5 /* 5 seconds */
 
 static atomic_t mce_paniced;
 
+static int fake_panic;
+static atomic_t mce_fake_paniced;
+
 /* Panic in progress. Enable interrupts and wait for final IPI */
 static void wait_for_panic(void)
 {
@@ -239,15 +234,21 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
 {
 	int i;
 
-	/*
-	 * Make sure only one CPU runs in machine check panic
-	 */
-	if (atomic_add_return(1, &mce_paniced) > 1)
-		wait_for_panic();
-	barrier();
+	if (!fake_panic) {
+		/*
+		 * Make sure only one CPU runs in machine check panic
+		 */
+		if (atomic_inc_return(&mce_paniced) > 1)
+			wait_for_panic();
+		barrier();
 
-	bust_spinlocks(1);
-	console_verbose();
+		bust_spinlocks(1);
+		console_verbose();
+	} else {
+		/* Don't log too much for fake panic */
+		if (atomic_inc_return(&mce_fake_paniced) > 1)
+			return;
+	}
 	print_mce_head();
 	/* First print corrected ones that are still unlogged */
 	for (i = 0; i < MCE_LOG_LEN; i++) {
@@ -274,9 +275,12 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
 	print_mce_tail();
 	if (exp)
 		printk(KERN_EMERG "Machine check: %s\n", exp);
-	if (panic_timeout == 0)
-		panic_timeout = mce_panic_timeout;
-	panic(msg);
+	if (!fake_panic) {
+		if (panic_timeout == 0)
+			panic_timeout = mce_panic_timeout;
+		panic(msg);
+	} else
+		printk(KERN_EMERG "Fake kernel panic: %s\n", msg);
 }
 
 /* Support code for software error injection */
@@ -286,11 +290,11 @@ static int msr_to_offset(u32 msr)
 	unsigned bank = __get_cpu_var(injectm.bank);
 	if (msr == rip_msr)
 		return offsetof(struct mce, ip);
-	if (msr == MSR_IA32_MC0_STATUS + bank*4)
+	if (msr == MSR_IA32_MCx_STATUS(bank))
 		return offsetof(struct mce, status);
-	if (msr == MSR_IA32_MC0_ADDR + bank*4)
+	if (msr == MSR_IA32_MCx_ADDR(bank))
 		return offsetof(struct mce, addr);
-	if (msr == MSR_IA32_MC0_MISC + bank*4)
+	if (msr == MSR_IA32_MCx_MISC(bank))
 		return offsetof(struct mce, misc);
 	if (msr == MSR_IA32_MCG_STATUS)
 		return offsetof(struct mce, mcgstatus);
@@ -495,7 +499,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 
 	m.mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS);
 	for (i = 0; i < banks; i++) {
-		if (!bank[i] || !test_bit(i, *b))
+		if (!mce_banks[i].ctl || !test_bit(i, *b))
 			continue;
 
 		m.misc = 0;
@@ -504,7 +508,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 		m.tsc = 0;
 
 		barrier();
-		m.status = mce_rdmsrl(MSR_IA32_MC0_STATUS + i*4);
+		m.status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
 		if (!(m.status & MCI_STATUS_VAL))
 			continue;
 
@@ -519,9 +523,9 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 			continue;
 
 		if (m.status & MCI_STATUS_MISCV)
-			m.misc = mce_rdmsrl(MSR_IA32_MC0_MISC + i*4);
+			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
 		if (m.status & MCI_STATUS_ADDRV)
-			m.addr = mce_rdmsrl(MSR_IA32_MC0_ADDR + i*4);
+			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
 
 		if (!(flags & MCP_TIMESTAMP))
 			m.tsc = 0;
@@ -537,7 +541,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 		/*
 		 * Clear state for this bank.
 		 */
-		mce_wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+		mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
 	}
 
 	/*
@@ -558,7 +562,7 @@ static int mce_no_way_out(struct mce *m, char **msg)
 	int i;
 
 	for (i = 0; i < banks; i++) {
-		m->status = mce_rdmsrl(MSR_IA32_MC0_STATUS + i*4);
+		m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
 		if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
 			return 1;
 	}
@@ -618,7 +622,7 @@ out:
  * This way we prevent any potential data corruption in a unrecoverable case
  * and also makes sure always all CPU's errors are examined.
  *
- * Also this detects the case of an machine check event coming from outer
+ * Also this detects the case of a machine check event coming from outer
  * space (not detected by any CPUs) In this case some external agent wants
  * us to shut down, so panic too.
  *
@@ -671,7 +675,7 @@ static void mce_reign(void)
 	 * No machine check event found. Must be some external
 	 * source or one CPU is hung. Panic.
 	 */
-	if (!m && tolerant < 3)
+	if (global_worst <= MCE_KEEP_SEVERITY && tolerant < 3)
 		mce_panic("Machine check from unknown source", NULL, NULL);
 
 	/*
@@ -705,7 +709,7 @@ static int mce_start(int *no_way_out)
 	 * global_nwo should be updated before mce_callin
 	 */
 	smp_wmb();
-	order = atomic_add_return(1, &mce_callin);
+	order = atomic_inc_return(&mce_callin);
 
 	/*
 	 * Wait for everyone.
@@ -842,7 +846,7 @@ static void mce_clear_state(unsigned long *toclear)
 
 	for (i = 0; i < banks; i++) {
 		if (test_bit(i, toclear))
-			mce_wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+			mce_wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
 	}
 }
 
@@ -895,11 +899,11 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 	mce_setup(&m);
 
 	m.mcgstatus = mce_rdmsrl(MSR_IA32_MCG_STATUS);
-	no_way_out = mce_no_way_out(&m, &msg);
-
 	final = &__get_cpu_var(mces_seen);
 	*final = m;
 
+	no_way_out = mce_no_way_out(&m, &msg);
+
 	barrier();
 
 	/*
@@ -916,14 +920,14 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 	order = mce_start(&no_way_out);
 	for (i = 0; i < banks; i++) {
 		__clear_bit(i, toclear);
-		if (!bank[i])
+		if (!mce_banks[i].ctl)
 			continue;
 
 		m.misc = 0;
 		m.addr = 0;
 		m.bank = i;
 
-		m.status = mce_rdmsrl(MSR_IA32_MC0_STATUS + i*4);
+		m.status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
 		if ((m.status & MCI_STATUS_VAL) == 0)
 			continue;
 
@@ -964,9 +968,9 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			kill_it = 1;
 
 		if (m.status & MCI_STATUS_MISCV)
-			m.misc = mce_rdmsrl(MSR_IA32_MC0_MISC + i*4);
+			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
 		if (m.status & MCI_STATUS_ADDRV)
-			m.addr = mce_rdmsrl(MSR_IA32_MC0_ADDR + i*4);
+			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
 
 		/*
 		 * Action optional error. Queue address for later processing.
@@ -1091,7 +1095,7 @@ void mce_log_therm_throt_event(__u64 status)
  */
 static int check_interval = 5 * 60; /* 5 minutes */
 
-static DEFINE_PER_CPU(int, next_interval); /* in jiffies */
+static DEFINE_PER_CPU(int, mce_next_interval); /* in jiffies */
 static DEFINE_PER_CPU(struct timer_list, mce_timer);
 
 static void mcheck_timer(unsigned long data)
@@ -1110,7 +1114,7 @@ static void mcheck_timer(unsigned long data)
 	 * Alert userspace if needed.  If we logged an MCE, reduce the
 	 * polling interval, otherwise increase the polling interval.
 	 */
-	n = &__get_cpu_var(next_interval);
+	n = &__get_cpu_var(mce_next_interval);
 	if (mce_notify_irq())
 		*n = max(*n/2, HZ/100);
 	else
@@ -1159,10 +1163,25 @@ int mce_notify_irq(void)
 }
 EXPORT_SYMBOL_GPL(mce_notify_irq);
 
+static int mce_banks_init(void)
+{
+	int i;
+
+	mce_banks = kzalloc(banks * sizeof(struct mce_bank), GFP_KERNEL);
+	if (!mce_banks)
+		return -ENOMEM;
+	for (i = 0; i < banks; i++) {
+		struct mce_bank *b = &mce_banks[i];
+		b->ctl = -1ULL;
+		b->init = 1;
+	}
+	return 0;
+}
+
 /*
  * Initialize Machine Checks for a CPU.
  */
-static int mce_cap_init(void)
+static int __cpuinit mce_cap_init(void)
 {
 	unsigned b;
 	u64 cap;
@@ -1182,11 +1201,10 @@ static int mce_cap_init(void)
 	/* Don't support asymmetric configurations today */
 	WARN_ON(banks != 0 && b != banks);
 	banks = b;
-	if (!bank) {
-		bank = kmalloc(banks * sizeof(u64), GFP_KERNEL);
-		if (!bank)
-			return -ENOMEM;
-		memset(bank, 0xff, banks * sizeof(u64));
+	if (!mce_banks) {
+		int err = mce_banks_init();
+		if (err)
+			return err;
 	}
 
 	/* Use accurate RIP reporting if available. */
@@ -1218,15 +1236,16 @@ static void mce_init(void)
 		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
 
 	for (i = 0; i < banks; i++) {
-		if (skip_bank_init(i))
+		struct mce_bank *b = &mce_banks[i];
+		if (!b->init)
 			continue;
-		wrmsrl(MSR_IA32_MC0_CTL+4*i, bank[i]);
-		wrmsrl(MSR_IA32_MC0_STATUS+4*i, 0);
+		wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl);
+		wrmsrl(MSR_IA32_MCx_STATUS(i), 0);
 	}
 }
 
 /* Add per CPU specific workarounds here */
-static int mce_cpu_quirks(struct cpuinfo_x86 *c)
+static int __cpuinit mce_cpu_quirks(struct cpuinfo_x86 *c)
 {
 	if (c->x86_vendor == X86_VENDOR_UNKNOWN) {
 		pr_info("MCE: unknown CPU type - not enabling MCE support.\n");
@@ -1241,7 +1260,7 @@ static int mce_cpu_quirks(struct cpuinfo_x86 *c)
 			 * trips off incorrectly with the IOMMU & 3ware
 			 * & Cerberus:
 			 */
-			clear_bit(10, (unsigned long *)&bank[4]);
+			clear_bit(10, (unsigned long *)&mce_banks[4].ctl);
 		}
 		if (c->x86 <= 17 && mce_bootlog < 0) {
 			/*
@@ -1255,7 +1274,7 @@ static int mce_cpu_quirks(struct cpuinfo_x86 *c)
 		 * by default.
 		 */
 		 if (c->x86 == 6 && banks > 0)
-			bank[0] = 0;
+			mce_banks[0].ctl = 0;
 	}
 
 	if (c->x86_vendor == X86_VENDOR_INTEL) {
@@ -1268,8 +1287,8 @@ static int mce_cpu_quirks(struct cpuinfo_x86 *c)
 		 * valid event later, merely don't write CTL0.
 		 */
 
-		if (c->x86 == 6 && c->x86_model < 0x1A)
-			__set_bit(0, &dont_init_banks);
+		if (c->x86 == 6 && c->x86_model < 0x1A && banks > 0)
+			mce_banks[0].init = 0;
 
 		/*
 		 * All newer Intel systems support MCE broadcasting. Enable
@@ -1325,7 +1344,7 @@ static void mce_cpu_features(struct cpuinfo_x86 *c)
 static void mce_init_timer(void)
 {
 	struct timer_list *t = &__get_cpu_var(mce_timer);
-	int *n = &__get_cpu_var(next_interval);
+	int *n = &__get_cpu_var(mce_next_interval);
 
 	if (mce_ignore_ce)
 		return;
@@ -1338,6 +1357,17 @@ static void mce_init_timer(void)
 	add_timer_on(t, smp_processor_id());
 }
 
+/* Handle unconfigured int18 (should never happen) */
+static void unexpected_machine_check(struct pt_regs *regs, long error_code)
+{
+	printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n",
+	       smp_processor_id());
+}
+
+/* Call the installed machine check handler for this CPU setup. */
+void (*machine_check_vector)(struct pt_regs *, long error_code) =
+						unexpected_machine_check;
+
 /*
  * Called for each booted CPU to set up machine checks.
  * Must be called with preempt off:
@@ -1551,8 +1581,10 @@ static struct miscdevice mce_log_device = {
  */
 static int __init mcheck_enable(char *str)
 {
-	if (*str == 0)
+	if (*str == 0) {
 		enable_p5_mce();
+		return 1;
+	}
 	if (*str == '=')
 		str++;
 	if (!strcmp(str, "off"))
@@ -1593,8 +1625,9 @@ static int mce_disable(void)
 	int i;
 
 	for (i = 0; i < banks; i++) {
-		if (!skip_bank_init(i))
-			wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
+		struct mce_bank *b = &mce_banks[i];
+		if (b->init)
+			wrmsrl(MSR_IA32_MCx_CTL(i), 0);
 	}
 	return 0;
 }
@@ -1669,14 +1702,15 @@ DEFINE_PER_CPU(struct sys_device, mce_dev);
 __cpuinitdata
 void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
 
-static struct sysdev_attribute *bank_attrs;
+static inline struct mce_bank *attr_to_bank(struct sysdev_attribute *attr)
+{
+	return container_of(attr, struct mce_bank, attr);
+}
 
 static ssize_t show_bank(struct sys_device *s, struct sysdev_attribute *attr,
 			 char *buf)
 {
-	u64 b = bank[attr - bank_attrs];
-
-	return sprintf(buf, "%llx\n", b);
+	return sprintf(buf, "%llx\n", attr_to_bank(attr)->ctl);
 }
 
 static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr,
@@ -1687,7 +1721,7 @@ static ssize_t set_bank(struct sys_device *s, struct sysdev_attribute *attr,
 	if (strict_strtoull(buf, 0, &new) < 0)
 		return -EINVAL;
 
-	bank[attr - bank_attrs] = new;
+	attr_to_bank(attr)->ctl = new;
 	mce_restart();
 
 	return size;
@@ -1829,7 +1863,7 @@ static __cpuinit int mce_create_device(unsigned int cpu)
 	}
 	for (j = 0; j < banks; j++) {
 		err = sysdev_create_file(&per_cpu(mce_dev, cpu),
-					&bank_attrs[j]);
+					&mce_banks[j].attr);
 		if (err)
 			goto error2;
 	}
@@ -1838,10 +1872,10 @@ static __cpuinit int mce_create_device(unsigned int cpu)
 	return 0;
 error2:
 	while (--j >= 0)
-		sysdev_remove_file(&per_cpu(mce_dev, cpu), &bank_attrs[j]);
+		sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[j].attr);
 error:
 	while (--i >= 0)
-		sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]);
+		sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr);
 
 	sysdev_unregister(&per_cpu(mce_dev, cpu));
 
@@ -1859,7 +1893,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu)
 		sysdev_remove_file(&per_cpu(mce_dev, cpu), mce_attrs[i]);
 
 	for (i = 0; i < banks; i++)
-		sysdev_remove_file(&per_cpu(mce_dev, cpu), &bank_attrs[i]);
+		sysdev_remove_file(&per_cpu(mce_dev, cpu), &mce_banks[i].attr);
 
 	sysdev_unregister(&per_cpu(mce_dev, cpu));
 	cpumask_clear_cpu(cpu, mce_dev_initialized);
@@ -1876,8 +1910,9 @@ static void mce_disable_cpu(void *h)
 	if (!(action & CPU_TASKS_FROZEN))
 		cmci_clear();
 	for (i = 0; i < banks; i++) {
-		if (!skip_bank_init(i))
-			wrmsrl(MSR_IA32_MC0_CTL + i*4, 0);
+		struct mce_bank *b = &mce_banks[i];
+		if (b->init)
+			wrmsrl(MSR_IA32_MCx_CTL(i), 0);
 	}
 }
 
@@ -1892,8 +1927,9 @@ static void mce_reenable_cpu(void *h)
 	if (!(action & CPU_TASKS_FROZEN))
 		cmci_reenable();
 	for (i = 0; i < banks; i++) {
-		if (!skip_bank_init(i))
-			wrmsrl(MSR_IA32_MC0_CTL + i*4, bank[i]);
+		struct mce_bank *b = &mce_banks[i];
+		if (b->init)
+			wrmsrl(MSR_IA32_MCx_CTL(i), b->ctl);
 	}
 }
 
@@ -1925,7 +1961,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 	case CPU_DOWN_FAILED:
 	case CPU_DOWN_FAILED_FROZEN:
 		t->expires = round_jiffies(jiffies +
-						__get_cpu_var(next_interval));
+					   __get_cpu_var(mce_next_interval));
 		add_timer_on(t, cpu);
 		smp_call_function_single(cpu, mce_reenable_cpu, &action, 1);
 		break;
@@ -1941,35 +1977,21 @@ static struct notifier_block mce_cpu_notifier __cpuinitdata = {
 	.notifier_call = mce_cpu_callback,
 };
 
-static __init int mce_init_banks(void)
+static __init void mce_init_banks(void)
 {
 	int i;
 
-	bank_attrs = kzalloc(sizeof(struct sysdev_attribute) * banks,
-				GFP_KERNEL);
-	if (!bank_attrs)
-		return -ENOMEM;
-
 	for (i = 0; i < banks; i++) {
-		struct sysdev_attribute *a = &bank_attrs[i];
+		struct mce_bank *b = &mce_banks[i];
+		struct sysdev_attribute *a = &b->attr;
 
-		a->attr.name	= kasprintf(GFP_KERNEL, "bank%d", i);
-		if (!a->attr.name)
-			goto nomem;
+		a->attr.name	= b->attrname;
+		snprintf(b->attrname, ATTR_LEN, "bank%d", i);
 
 		a->attr.mode	= 0644;
 		a->show		= show_bank;
 		a->store	= set_bank;
 	}
-	return 0;
-
-nomem:
-	while (--i >= 0)
-		kfree(bank_attrs[i].attr.name);
-	kfree(bank_attrs);
-	bank_attrs = NULL;
-
-	return -ENOMEM;
 }
 
 static __init int mce_init_device(void)
@@ -1982,9 +2004,7 @@ static __init int mce_init_device(void)
 
 	zalloc_cpumask_var(&mce_dev_initialized, GFP_KERNEL);
 
-	err = mce_init_banks();
-	if (err)
-		return err;
+	mce_init_banks();
 
 	err = sysdev_class_register(&mce_sysclass);
 	if (err)
@@ -2004,57 +2024,65 @@ static __init int mce_init_device(void)
 
 device_initcall(mce_init_device);
 
-#else /* CONFIG_X86_OLD_MCE: */
-
-int nr_mce_banks;
-EXPORT_SYMBOL_GPL(nr_mce_banks);	/* non-fatal.o */
+/*
+ * Old style boot options parsing. Only for compatibility.
+ */
+static int __init mcheck_disable(char *str)
+{
+	mce_disabled = 1;
+	return 1;
+}
+__setup("nomce", mcheck_disable);
 
-/* This has to be run for each processor */
-void mcheck_init(struct cpuinfo_x86 *c)
+#ifdef CONFIG_DEBUG_FS
+struct dentry *mce_get_debugfs_dir(void)
 {
-	if (mce_disabled)
-		return;
+	static struct dentry *dmce;
 
-	switch (c->x86_vendor) {
-	case X86_VENDOR_AMD:
-		amd_mcheck_init(c);
-		break;
+	if (!dmce)
+		dmce = debugfs_create_dir("mce", NULL);
 
-	case X86_VENDOR_INTEL:
-		if (c->x86 == 5)
-			intel_p5_mcheck_init(c);
-		if (c->x86 == 6)
-			intel_p6_mcheck_init(c);
-		if (c->x86 == 15)
-			intel_p4_mcheck_init(c);
-		break;
+	return dmce;
+}
 
-	case X86_VENDOR_CENTAUR:
-		if (c->x86 == 5)
-			winchip_mcheck_init(c);
-		break;
+static void mce_reset(void)
+{
+	cpu_missing = 0;
+	atomic_set(&mce_fake_paniced, 0);
+	atomic_set(&mce_executing, 0);
+	atomic_set(&mce_callin, 0);
+	atomic_set(&global_nwo, 0);
+}
 
-	default:
-		break;
-	}
-	printk(KERN_INFO "mce: CPU supports %d MCE banks\n", nr_mce_banks);
+static int fake_panic_get(void *data, u64 *val)
+{
+	*val = fake_panic;
+	return 0;
 }
 
-static int __init mcheck_enable(char *str)
+static int fake_panic_set(void *data, u64 val)
 {
-	mce_p5_enabled = 1;
-	return 1;
+	mce_reset();
+	fake_panic = val;
+	return 0;
 }
-__setup("mce", mcheck_enable);
 
-#endif /* CONFIG_X86_OLD_MCE */
+DEFINE_SIMPLE_ATTRIBUTE(fake_panic_fops, fake_panic_get,
+			fake_panic_set, "%llu\n");
 
-/*
- * Old style boot options parsing. Only for compatibility.
- */
-static int __init mcheck_disable(char *str)
+static int __init mce_debugfs_init(void)
 {
-	mce_disabled = 1;
-	return 1;
+	struct dentry *dmce, *ffake_panic;
+
+	dmce = mce_get_debugfs_dir();
+	if (!dmce)
+		return -ENOMEM;
+	ffake_panic = debugfs_create_file("fake_panic", 0444, dmce, NULL,
+					  &fake_panic_fops);
+	if (!ffake_panic)
+		return -ENOMEM;
+
+	return 0;
 }
-__setup("nomce", mcheck_disable);
+late_initcall(mce_debugfs_init);
+#endif
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index ddae216..83a3d1f 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -69,7 +69,7 @@ struct threshold_bank {
 	struct threshold_block	*blocks;
 	cpumask_var_t		cpus;
 };
-static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]);
+static DEFINE_PER_CPU(struct threshold_bank * [NR_BANKS], threshold_banks);
 
 #ifdef CONFIG_SMP
 static unsigned char shared_bank[NR_BANKS] = {
@@ -489,12 +489,15 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
 	int i, err = 0;
 	struct threshold_bank *b = NULL;
 	char name[32];
+#ifdef CONFIG_SMP
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+#endif
 
 	sprintf(name, "threshold_bank%i", bank);
 
 #ifdef CONFIG_SMP
 	if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) {	/* symlink */
-		i = cpumask_first(cpu_core_mask(cpu));
+		i = cpumask_first(c->llc_shared_map);
 
 		/* first core not up yet */
 		if (cpu_data(i).cpu_core_id)
@@ -514,7 +517,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
 		if (err)
 			goto out;
 
-		cpumask_copy(b->cpus, cpu_core_mask(cpu));
+		cpumask_copy(b->cpus, c->llc_shared_map);
 		per_cpu(threshold_banks, cpu)[bank] = b;
 
 		goto out;
@@ -539,7 +542,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
 #ifndef CONFIG_SMP
 	cpumask_setall(b->cpus);
 #else
-	cpumask_copy(b->cpus, cpu_core_mask(cpu));
+	cpumask_copy(b->cpus, c->llc_shared_map);
 #endif
 
 	per_cpu(threshold_banks, cpu)[bank] = b;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
index e1acec0..889f665 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -90,7 +90,7 @@ static void cmci_discover(int banks, int boot)
 		if (test_bit(i, owned))
 			continue;
 
-		rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+		rdmsrl(MSR_IA32_MCx_CTL2(i), val);
 
 		/* Already owned by someone else? */
 		if (val & CMCI_EN) {
@@ -101,8 +101,8 @@ static void cmci_discover(int banks, int boot)
 		}
 
 		val |= CMCI_EN | CMCI_THRESHOLD;
-		wrmsrl(MSR_IA32_MC0_CTL2 + i, val);
-		rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+		wrmsrl(MSR_IA32_MCx_CTL2(i), val);
+		rdmsrl(MSR_IA32_MCx_CTL2(i), val);
 
 		/* Did the enable bit stick? -- the bank supports CMCI */
 		if (val & CMCI_EN) {
@@ -152,9 +152,9 @@ void cmci_clear(void)
 		if (!test_bit(i, __get_cpu_var(mce_banks_owned)))
 			continue;
 		/* Disable CMCI */
-		rdmsrl(MSR_IA32_MC0_CTL2 + i, val);
+		rdmsrl(MSR_IA32_MCx_CTL2(i), val);
 		val &= ~(CMCI_EN|CMCI_THRESHOLD_MASK);
-		wrmsrl(MSR_IA32_MC0_CTL2 + i, val);
+		wrmsrl(MSR_IA32_MCx_CTL2(i), val);
 		__clear_bit(i, __get_cpu_var(mce_banks_owned));
 	}
 	spin_unlock_irqrestore(&cmci_discover_lock, flags);
diff --git a/arch/x86/kernel/cpu/mcheck/non-fatal.c b/arch/x86/kernel/cpu/mcheck/non-fatal.c
deleted file mode 100644
index f5f2d6f..0000000
--- a/arch/x86/kernel/cpu/mcheck/non-fatal.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Non Fatal Machine Check Exception Reporting
- *
- * (C) Copyright 2002 Dave Jones. <davej@redhat.com>
- *
- * This file contains routines to check for non-fatal MCEs every 15s
- *
- */
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-static int		firstbank;
-
-#define MCE_RATE	(15*HZ)	/* timer rate is 15s */
-
-static void mce_checkregs(void *info)
-{
-	u32 low, high;
-	int i;
-
-	for (i = firstbank; i < nr_mce_banks; i++) {
-		rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-
-		if (!(high & (1<<31)))
-			continue;
-
-		printk(KERN_INFO "MCE: The hardware reports a non fatal, "
-			"correctable incident occurred on CPU %d.\n",
-				smp_processor_id());
-
-		printk(KERN_INFO "Bank %d: %08x%08x\n", i, high, low);
-
-		/*
-		 * Scrub the error so we don't pick it up in MCE_RATE
-		 * seconds time:
-		 */
-		wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
-
-		/* Serialize: */
-		wmb();
-		add_taint(TAINT_MACHINE_CHECK);
-	}
-}
-
-static void mce_work_fn(struct work_struct *work);
-static DECLARE_DELAYED_WORK(mce_work, mce_work_fn);
-
-static void mce_work_fn(struct work_struct *work)
-{
-	on_each_cpu(mce_checkregs, NULL, 1);
-	schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
-}
-
-static int __init init_nonfatal_mce_checker(void)
-{
-	struct cpuinfo_x86 *c = &boot_cpu_data;
-
-	/* Check for MCE support */
-	if (!cpu_has(c, X86_FEATURE_MCE))
-		return -ENODEV;
-
-	/* Check for PPro style MCA */
-	if (!cpu_has(c, X86_FEATURE_MCA))
-		return -ENODEV;
-
-	/* Some Athlons misbehave when we frob bank 0 */
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
-						boot_cpu_data.x86 == 6)
-		firstbank = 1;
-	else
-		firstbank = 0;
-
-	/*
-	 * Check for non-fatal errors every MCE_RATE s
-	 */
-	schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
-	printk(KERN_INFO "Machine check exception polling timer started.\n");
-
-	return 0;
-}
-module_init(init_nonfatal_mce_checker);
-
-MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c
deleted file mode 100644
index 4482aea..0000000
--- a/arch/x86/kernel/cpu/mcheck/p4.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * P4 specific Machine Check Exception Reporting
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-/* as supported by the P4/Xeon family */
-struct intel_mce_extended_msrs {
-	u32 eax;
-	u32 ebx;
-	u32 ecx;
-	u32 edx;
-	u32 esi;
-	u32 edi;
-	u32 ebp;
-	u32 esp;
-	u32 eflags;
-	u32 eip;
-	/* u32 *reserved[]; */
-};
-
-static int mce_num_extended_msrs;
-
-/* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */
-static void intel_get_extended_msrs(struct intel_mce_extended_msrs *r)
-{
-	u32 h;
-
-	rdmsr(MSR_IA32_MCG_EAX, r->eax, h);
-	rdmsr(MSR_IA32_MCG_EBX, r->ebx, h);
-	rdmsr(MSR_IA32_MCG_ECX, r->ecx, h);
-	rdmsr(MSR_IA32_MCG_EDX, r->edx, h);
-	rdmsr(MSR_IA32_MCG_ESI, r->esi, h);
-	rdmsr(MSR_IA32_MCG_EDI, r->edi, h);
-	rdmsr(MSR_IA32_MCG_EBP, r->ebp, h);
-	rdmsr(MSR_IA32_MCG_ESP, r->esp, h);
-	rdmsr(MSR_IA32_MCG_EFLAGS, r->eflags, h);
-	rdmsr(MSR_IA32_MCG_EIP, r->eip, h);
-}
-
-static void intel_machine_check(struct pt_regs *regs, long error_code)
-{
-	u32 alow, ahigh, high, low;
-	u32 mcgstl, mcgsth;
-	int recover = 1;
-	int i;
-
-	rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-	if (mcgstl & (1<<0))	/* Recoverable ? */
-		recover = 0;
-
-	printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
-		smp_processor_id(), mcgsth, mcgstl);
-
-	if (mce_num_extended_msrs > 0) {
-		struct intel_mce_extended_msrs dbg;
-
-		intel_get_extended_msrs(&dbg);
-
-		printk(KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n"
-			"\teax: %08x ebx: %08x ecx: %08x edx: %08x\n"
-			"\tesi: %08x edi: %08x ebp: %08x esp: %08x\n",
-			smp_processor_id(), dbg.eip, dbg.eflags,
-			dbg.eax, dbg.ebx, dbg.ecx, dbg.edx,
-			dbg.esi, dbg.edi, dbg.ebp, dbg.esp);
-	}
-
-	for (i = 0; i < nr_mce_banks; i++) {
-		rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-		if (high & (1<<31)) {
-			char misc[20];
-			char addr[24];
-
-			misc[0] = addr[0] = '\0';
-			if (high & (1<<29))
-				recover |= 1;
-			if (high & (1<<25))
-				recover |= 2;
-			high &= ~(1<<31);
-			if (high & (1<<27)) {
-				rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
-				snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
-			}
-			if (high & (1<<26)) {
-				rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
-				snprintf(addr, 24, " at %08x%08x", ahigh, alow);
-			}
-			printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
-				smp_processor_id(), i, high, low, misc, addr);
-		}
-	}
-
-	if (recover & 2)
-		panic("CPU context corrupt");
-	if (recover & 1)
-		panic("Unable to continue");
-
-	printk(KERN_EMERG "Attempting to continue.\n");
-
-	/*
-	 * Do not clear the MSR_IA32_MCi_STATUS if the error is not
-	 * recoverable/continuable.This will allow BIOS to look at the MSRs
-	 * for errors if the OS could not log the error.
-	 */
-	for (i = 0; i < nr_mce_banks; i++) {
-		u32 msr;
-		msr = MSR_IA32_MC0_STATUS+i*4;
-		rdmsr(msr, low, high);
-		if (high&(1<<31)) {
-			/* Clear it */
-			wrmsr(msr, 0UL, 0UL);
-			/* Serialize */
-			wmb();
-			add_taint(TAINT_MACHINE_CHECK);
-		}
-	}
-	mcgstl &= ~(1<<2);
-	wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-}
-
-void intel_p4_mcheck_init(struct cpuinfo_x86 *c)
-{
-	u32 l, h;
-	int i;
-
-	machine_check_vector = intel_machine_check;
-	wmb();
-
-	printk(KERN_INFO "Intel machine check architecture supported.\n");
-	rdmsr(MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<8))	/* Control register present ? */
-		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-	nr_mce_banks = l & 0xff;
-
-	for (i = 0; i < nr_mce_banks; i++) {
-		wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-		wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-	}
-
-	set_in_cr4(X86_CR4_MCE);
-	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
-		smp_processor_id());
-
-	/* Check for P4/Xeon extended MCE MSRs */
-	rdmsr(MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<9))	{/* MCG_EXT_P */
-		mce_num_extended_msrs = (l >> 16) & 0xff;
-		printk(KERN_INFO "CPU%d: Intel P4/Xeon Extended MCE MSRs (%d)"
-				" available\n",
-			smp_processor_id(), mce_num_extended_msrs);
-
-#ifdef CONFIG_X86_MCE_P4THERMAL
-		/* Check for P4/Xeon Thermal monitor */
-		intel_init_thermal(c);
-#endif
-	}
-}
diff --git a/arch/x86/kernel/cpu/mcheck/p6.c b/arch/x86/kernel/cpu/mcheck/p6.c
deleted file mode 100644
index 01e4f81..0000000
--- a/arch/x86/kernel/cpu/mcheck/p6.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * P6 specific Machine Check Exception Reporting
- * (C) Copyright 2002 Alan Cox <alan@lxorguk.ukuu.org.uk>
- */
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-
-#include <asm/processor.h>
-#include <asm/system.h>
-#include <asm/mce.h>
-#include <asm/msr.h>
-
-/* Machine Check Handler For PII/PIII */
-static void intel_machine_check(struct pt_regs *regs, long error_code)
-{
-	u32 alow, ahigh, high, low;
-	u32 mcgstl, mcgsth;
-	int recover = 1;
-	int i;
-
-	rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-	if (mcgstl & (1<<0))	/* Recoverable ? */
-		recover = 0;
-
-	printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n",
-		smp_processor_id(), mcgsth, mcgstl);
-
-	for (i = 0; i < nr_mce_banks; i++) {
-		rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
-		if (high & (1<<31)) {
-			char misc[20];
-			char addr[24];
-
-			misc[0] = '\0';
-			addr[0] = '\0';
-
-			if (high & (1<<29))
-				recover |= 1;
-			if (high & (1<<25))
-				recover |= 2;
-			high &= ~(1<<31);
-
-			if (high & (1<<27)) {
-				rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
-				snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
-			}
-			if (high & (1<<26)) {
-				rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
-				snprintf(addr, 24, " at %08x%08x", ahigh, alow);
-			}
-
-			printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
-				smp_processor_id(), i, high, low, misc, addr);
-		}
-	}
-
-	if (recover & 2)
-		panic("CPU context corrupt");
-	if (recover & 1)
-		panic("Unable to continue");
-
-	printk(KERN_EMERG "Attempting to continue.\n");
-	/*
-	 * Do not clear the MSR_IA32_MCi_STATUS if the error is not
-	 * recoverable/continuable.This will allow BIOS to look at the MSRs
-	 * for errors if the OS could not log the error:
-	 */
-	for (i = 0; i < nr_mce_banks; i++) {
-		unsigned int msr;
-
-		msr = MSR_IA32_MC0_STATUS+i*4;
-		rdmsr(msr, low, high);
-		if (high & (1<<31)) {
-			/* Clear it: */
-			wrmsr(msr, 0UL, 0UL);
-			/* Serialize: */
-			wmb();
-			add_taint(TAINT_MACHINE_CHECK);
-		}
-	}
-	mcgstl &= ~(1<<2);
-	wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
-}
-
-/* Set up machine check reporting for processors with Intel style MCE: */
-void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
-{
-	u32 l, h;
-	int i;
-
-	/* Check for MCE support */
-	if (!cpu_has(c, X86_FEATURE_MCE))
-		return;
-
-	/* Check for PPro style MCA */
-	if (!cpu_has(c, X86_FEATURE_MCA))
-		return;
-
-	/* Ok machine check is available */
-	machine_check_vector = intel_machine_check;
-	/* Make sure the vector pointer is visible before we enable MCEs: */
-	wmb();
-
-	printk(KERN_INFO "Intel machine check architecture supported.\n");
-	rdmsr(MSR_IA32_MCG_CAP, l, h);
-	if (l & (1<<8))	/* Control register present ? */
-		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);
-	nr_mce_banks = l & 0xff;
-
-	/*
-	 * Following the example in IA-32 SDM Vol 3:
-	 * - MC0_CTL should not be written
-	 * - Status registers on all banks should be cleared on reset
-	 */
-	for (i = 1; i < nr_mce_banks; i++)
-		wrmsr(MSR_IA32_MC0_CTL+4*i, 0xffffffff, 0xffffffff);
-
-	for (i = 0; i < nr_mce_banks; i++)
-		wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);
-
-	set_in_cr4(X86_CR4_MCE);
-	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
-		smp_processor_id());
-}
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index 5957a93..63a56d1 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -260,9 +260,6 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
 		return;
 	}
 
-	if (cpu_has(c, X86_FEATURE_TM2) && (l & MSR_IA32_MISC_ENABLE_TM2))
-		tm2 = 1;
-
 	/* Check whether a vector already exists */
 	if (h & APIC_VECTOR_MASK) {
 		printk(KERN_DEBUG
@@ -271,6 +268,16 @@ void intel_init_thermal(struct cpuinfo_x86 *c)
 		return;
 	}
 
+	/* early Pentium M models use different method for enabling TM2 */
+	if (cpu_has(c, X86_FEATURE_TM2)) {
+		if (c->x86 == 6 && (c->x86_model == 9 || c->x86_model == 13)) {
+			rdmsr(MSR_THERM2_CTL, l, h);
+			if (l & MSR_THERM2_CTL_TM_SELECT)
+				tm2 = 1;
+		} else if (l & MSR_IA32_MISC_ENABLE_TM2)
+			tm2 = 1;
+	}
+
 	/* We'll mask the thermal vector in the lapic till we're ready: */
 	h = THERMAL_APIC_VECTOR | APIC_DM_FIXED | APIC_LVT_MASKED;
 	apic_write(APIC_LVTTHMR, h);
diff --git a/arch/x86/kernel/cpu/mtrr/amd.c b/arch/x86/kernel/cpu/mtrr/amd.c
index ee2331b..33af141 100644
--- a/arch/x86/kernel/cpu/mtrr/amd.c
+++ b/arch/x86/kernel/cpu/mtrr/amd.c
@@ -7,15 +7,15 @@
 
 static void
 amd_get_mtrr(unsigned int reg, unsigned long *base,
-	     unsigned long *size, mtrr_type * type)
+	     unsigned long *size, mtrr_type *type)
 {
 	unsigned long low, high;
 
 	rdmsr(MSR_K6_UWCCR, low, high);
-	/*  Upper dword is region 1, lower is region 0  */
+	/* Upper dword is region 1, lower is region 0 */
 	if (reg == 1)
 		low = high;
-	/*  The base masks off on the right alignment  */
+	/* The base masks off on the right alignment */
 	*base = (low & 0xFFFE0000) >> PAGE_SHIFT;
 	*type = 0;
 	if (low & 1)
@@ -27,74 +27,81 @@ amd_get_mtrr(unsigned int reg, unsigned long *base,
 		return;
 	}
 	/*
-	 *  This needs a little explaining. The size is stored as an
-	 *  inverted mask of bits of 128K granularity 15 bits long offset
-	 *  2 bits
+	 * This needs a little explaining. The size is stored as an
+	 * inverted mask of bits of 128K granularity 15 bits long offset
+	 * 2 bits.
 	 *
-	 *  So to get a size we do invert the mask and add 1 to the lowest
-	 *  mask bit (4 as its 2 bits in). This gives us a size we then shift
-	 *  to turn into 128K blocks
+	 * So to get a size we do invert the mask and add 1 to the lowest
+	 * mask bit (4 as its 2 bits in). This gives us a size we then shift
+	 * to turn into 128K blocks.
 	 *
-	 *  eg              111 1111 1111 1100      is 512K
+	 * eg              111 1111 1111 1100      is 512K
 	 *
-	 *  invert          000 0000 0000 0011
-	 *  +1              000 0000 0000 0100
-	 *  *128K   ...
+	 * invert          000 0000 0000 0011
+	 * +1              000 0000 0000 0100
+	 * *128K   ...
 	 */
 	low = (~low) & 0x1FFFC;
 	*size = (low + 4) << (15 - PAGE_SHIFT);
-	return;
 }
 
-static void amd_set_mtrr(unsigned int reg, unsigned long base,
-			 unsigned long size, mtrr_type type)
-/*  [SUMMARY] Set variable MTRR register on the local CPU.
-    <reg> The register to set.
-    <base> The base address of the region.
-    <size> The size of the region. If this is 0 the region is disabled.
-    <type> The type of the region.
-    [RETURNS] Nothing.
-*/
+/**
+ * amd_set_mtrr - Set variable MTRR register on the local CPU.
+ *
+ * @reg The register to set.
+ * @base The base address of the region.
+ * @size The size of the region. If this is 0 the region is disabled.
+ * @type The type of the region.
+ *
+ * Returns nothing.
+ */
+static void
+amd_set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type)
 {
 	u32 regs[2];
 
 	/*
-	 *  Low is MTRR0 , High MTRR 1
+	 * Low is MTRR0, High MTRR 1
 	 */
 	rdmsr(MSR_K6_UWCCR, regs[0], regs[1]);
 	/*
-	 *  Blank to disable
+	 * Blank to disable
 	 */
-	if (size == 0)
+	if (size == 0) {
 		regs[reg] = 0;
-	else
-		/* Set the register to the base, the type (off by one) and an
-		   inverted bitmask of the size The size is the only odd
-		   bit. We are fed say 512K We invert this and we get 111 1111
-		   1111 1011 but if you subtract one and invert you get the   
-		   desired 111 1111 1111 1100 mask
-
-		   But ~(x - 1) == ~x + 1 == -x. Two's complement rocks!  */
+	} else {
+		/*
+		 * Set the register to the base, the type (off by one) and an
+		 * inverted bitmask of the size The size is the only odd
+		 * bit. We are fed say 512K We invert this and we get 111 1111
+		 * 1111 1011 but if you subtract one and invert you get the
+		 * desired 111 1111 1111 1100 mask
+		 *
+		 *  But ~(x - 1) == ~x + 1 == -x. Two's complement rocks!
+		 */
 		regs[reg] = (-size >> (15 - PAGE_SHIFT) & 0x0001FFFC)
 		    | (base << PAGE_SHIFT) | (type + 1);
+	}
 
 	/*
-	 *  The writeback rule is quite specific. See the manual. Its
-	 *  disable local interrupts, write back the cache, set the mtrr
+	 * The writeback rule is quite specific. See the manual. Its
+	 * disable local interrupts, write back the cache, set the mtrr
 	 */
 	wbinvd();
 	wrmsr(MSR_K6_UWCCR, regs[0], regs[1]);
 }
 
-static int amd_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
+static int
+amd_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
 {
-	/* Apply the K6 block alignment and size rules
-	   In order
-	   o Uncached or gathering only
-	   o 128K or bigger block
-	   o Power of 2 block
-	   o base suitably aligned to the power
-	*/
+	/*
+	 * Apply the K6 block alignment and size rules
+	 * In order
+	 * o Uncached or gathering only
+	 * o 128K or bigger block
+	 * o Power of 2 block
+	 * o base suitably aligned to the power
+	 */
 	if (type > MTRR_TYPE_WRCOMB || size < (1 << (17 - PAGE_SHIFT))
 	    || (size & ~(size - 1)) - size || (base & (size - 1)))
 		return -EINVAL;
@@ -115,5 +122,3 @@ int __init amd_init_mtrr(void)
 	set_mtrr_ops(&amd_mtrr_ops);
 	return 0;
 }
-
-//arch_initcall(amd_mtrr_init);
diff --git a/arch/x86/kernel/cpu/mtrr/centaur.c b/arch/x86/kernel/cpu/mtrr/centaur.c
index cb9aa3a..de89f14 100644
--- a/arch/x86/kernel/cpu/mtrr/centaur.c
+++ b/arch/x86/kernel/cpu/mtrr/centaur.c
@@ -1,7 +1,9 @@
 #include <linux/init.h>
 #include <linux/mm.h>
+
 #include <asm/mtrr.h>
 #include <asm/msr.h>
+
 #include "mtrr.h"
 
 static struct {
@@ -12,25 +14,25 @@ static struct {
 static u8 centaur_mcr_reserved;
 static u8 centaur_mcr_type;	/* 0 for winchip, 1 for winchip2 */
 
-/*
- *	Report boot time MCR setups 
+/**
+ * centaur_get_free_region - Get a free MTRR.
+ *
+ * @base: The starting (base) address of the region.
+ * @size: The size (in bytes) of the region.
+ *
+ * Returns: the index of the region on success, else -1 on error.
  */
-
 static int
 centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg)
-/*  [SUMMARY] Get a free MTRR.
-    <base> The starting (base) address of the region.
-    <size> The size (in bytes) of the region.
-    [RETURNS] The index of the region on success, else -1 on error.
-*/
 {
-	int i, max;
-	mtrr_type ltype;
 	unsigned long lbase, lsize;
+	mtrr_type ltype;
+	int i, max;
 
 	max = num_var_ranges;
 	if (replace_reg >= 0 && replace_reg < max)
 		return replace_reg;
+
 	for (i = 0; i < max; ++i) {
 		if (centaur_mcr_reserved & (1 << i))
 			continue;
@@ -38,11 +40,14 @@ centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg)
 		if (lsize == 0)
 			return i;
 	}
+
 	return -ENOSPC;
 }
 
-void
-mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
+/*
+ * Report boot time MCR setups
+ */
+void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
 {
 	centaur_mcr[mcr].low = lo;
 	centaur_mcr[mcr].high = hi;
@@ -54,33 +59,35 @@ centaur_get_mcr(unsigned int reg, unsigned long *base,
 {
 	*base = centaur_mcr[reg].high >> PAGE_SHIFT;
 	*size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
-	*type = MTRR_TYPE_WRCOMB;	/*  If it is there, it is write-combining  */
+	*type = MTRR_TYPE_WRCOMB;		/* write-combining  */
+
 	if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2))
 		*type = MTRR_TYPE_UNCACHABLE;
 	if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25)
 		*type = MTRR_TYPE_WRBACK;
 	if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31)
 		*type = MTRR_TYPE_WRBACK;
-
 }
 
-static void centaur_set_mcr(unsigned int reg, unsigned long base,
-			    unsigned long size, mtrr_type type)
+static void
+centaur_set_mcr(unsigned int reg, unsigned long base,
+		unsigned long size, mtrr_type type)
 {
 	unsigned long low, high;
 
 	if (size == 0) {
-		/*  Disable  */
+		/* Disable */
 		high = low = 0;
 	} else {
 		high = base << PAGE_SHIFT;
-		if (centaur_mcr_type == 0)
-			low = -size << PAGE_SHIFT | 0x1f;	/* only support write-combining... */
-		else {
+		if (centaur_mcr_type == 0) {
+			/* Only support write-combining... */
+			low = -size << PAGE_SHIFT | 0x1f;
+		} else {
 			if (type == MTRR_TYPE_UNCACHABLE)
-				low = -size << PAGE_SHIFT | 0x02;	/* NC */
+				low = -size << PAGE_SHIFT | 0x02; /* NC */
 			else
-				low = -size << PAGE_SHIFT | 0x09;	/* WWO,WC */
+				low = -size << PAGE_SHIFT | 0x09; /* WWO, WC */
 		}
 	}
 	centaur_mcr[reg].high = high;
@@ -88,118 +95,16 @@ static void centaur_set_mcr(unsigned int reg, unsigned long base,
 	wrmsr(MSR_IDT_MCR0 + reg, low, high);
 }
 
-#if 0
-/*
- *	Initialise the later (saner) Winchip MCR variant. In this version
- *	the BIOS can pass us the registers it has used (but not their values)
- *	and the control register is read/write
- */
-
-static void __init
-centaur_mcr1_init(void)
-{
-	unsigned i;
-	u32 lo, hi;
-
-	/* Unfortunately, MCR's are read-only, so there is no way to
-	 * find out what the bios might have done.
-	 */
-
-	rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
-	if (((lo >> 17) & 7) == 1) {	/* Type 1 Winchip2 MCR */
-		lo &= ~0x1C0;	/* clear key */
-		lo |= 0x040;	/* set key to 1 */
-		wrmsr(MSR_IDT_MCR_CTRL, lo, hi);	/* unlock MCR */
-	}
-
-	centaur_mcr_type = 1;
-
-	/*
-	 *  Clear any unconfigured MCR's.
-	 */
-
-	for (i = 0; i < 8; ++i) {
-		if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) {
-			if (!(lo & (1 << (9 + i))))
-				wrmsr(MSR_IDT_MCR0 + i, 0, 0);
-			else
-				/*
-				 *      If the BIOS set up an MCR we cannot see it
-				 *      but we don't wish to obliterate it
-				 */
-				centaur_mcr_reserved |= (1 << i);
-		}
-	}
-	/*  
-	 *  Throw the main write-combining switch... 
-	 *  However if OOSTORE is enabled then people have already done far
-	 *  cleverer things and we should behave. 
-	 */
-
-	lo |= 15;		/* Write combine enables */
-	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
-}
-
-/*
- *	Initialise the original winchip with read only MCR registers
- *	no used bitmask for the BIOS to pass on and write only control
- */
-
-static void __init
-centaur_mcr0_init(void)
-{
-	unsigned i;
-
-	/* Unfortunately, MCR's are read-only, so there is no way to
-	 * find out what the bios might have done.
-	 */
-
-	/* Clear any unconfigured MCR's.
-	 * This way we are sure that the centaur_mcr array contains the actual
-	 * values. The disadvantage is that any BIOS tweaks are thus undone.
-	 *
-	 */
-	for (i = 0; i < 8; ++i) {
-		if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0)
-			wrmsr(MSR_IDT_MCR0 + i, 0, 0);
-	}
-
-	wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);	/* Write only */
-}
-
-/*
- *	Initialise Winchip series MCR registers
- */
-
-static void __init
-centaur_mcr_init(void)
-{
-	struct set_mtrr_context ctxt;
-
-	set_mtrr_prepare_save(&ctxt);
-	set_mtrr_cache_disable(&ctxt);
-
-	if (boot_cpu_data.x86_model == 4)
-		centaur_mcr0_init();
-	else if (boot_cpu_data.x86_model == 8 || boot_cpu_data.x86_model == 9)
-		centaur_mcr1_init();
-
-	set_mtrr_done(&ctxt);
-}
-#endif
-
-static int centaur_validate_add_page(unsigned long base, 
-				     unsigned long size, unsigned int type)
+static int
+centaur_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
 {
 	/*
-	 *  FIXME: Winchip2 supports uncached
+	 * FIXME: Winchip2 supports uncached
 	 */
-	if (type != MTRR_TYPE_WRCOMB && 
+	if (type != MTRR_TYPE_WRCOMB &&
 	    (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) {
-		printk(KERN_WARNING
-		       "mtrr: only write-combining%s supported\n",
-		       centaur_mcr_type ? " and uncacheable are"
-		       : " is");
+		pr_warning("mtrr: only write-combining%s supported\n",
+			   centaur_mcr_type ? " and uncacheable are" : " is");
 		return -EINVAL;
 	}
 	return 0;
@@ -207,7 +112,6 @@ static int centaur_validate_add_page(unsigned long base,
 
 static struct mtrr_ops centaur_mtrr_ops = {
 	.vendor            = X86_VENDOR_CENTAUR,
-//	.init              = centaur_mcr_init,
 	.set               = centaur_set_mcr,
 	.get               = centaur_get_mcr,
 	.get_free_region   = centaur_get_free_region,
@@ -220,5 +124,3 @@ int __init centaur_init_mtrr(void)
 	set_mtrr_ops(&centaur_mtrr_ops);
 	return 0;
 }
-
-//arch_initcall(centaur_init_mtrr);
diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
index 1d584a1..315738c 100644
--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
+++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
@@ -1,51 +1,75 @@
-/*  MTRR (Memory Type Range Register) cleanup
-
-    Copyright (C) 2009 Yinghai Lu
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
+/*
+ * MTRR (Memory Type Range Register) cleanup
+ *
+ *  Copyright (C) 2009 Yinghai Lu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
 #include <linux/cpu.h>
-#include <linux/mutex.h>
 #include <linux/sort.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/kvm_para.h>
 
+#include <asm/processor.h>
 #include <asm/e820.h>
 #include <asm/mtrr.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
 #include <asm/msr.h>
-#include <asm/kvm_para.h>
-#include "mtrr.h"
 
-/* should be related to MTRR_VAR_RANGES nums */
-#define RANGE_NUM 256
+#include "mtrr.h"
 
 struct res_range {
-	unsigned long start;
-	unsigned long end;
+	unsigned long	start;
+	unsigned long	end;
+};
+
+struct var_mtrr_range_state {
+	unsigned long	base_pfn;
+	unsigned long	size_pfn;
+	mtrr_type	type;
+};
+
+struct var_mtrr_state {
+	unsigned long	range_startk;
+	unsigned long	range_sizek;
+	unsigned long	chunk_sizek;
+	unsigned long	gran_sizek;
+	unsigned int	reg;
 };
 
+/* Should be related to MTRR_VAR_RANGES nums */
+#define RANGE_NUM				256
+
+static struct res_range __initdata		range[RANGE_NUM];
+static int __initdata				nr_range;
+
+static struct var_mtrr_range_state __initdata	range_state[RANGE_NUM];
+
+static int __initdata debug_print;
+#define Dprintk(x...) do { if (debug_print) printk(KERN_DEBUG x); } while (0)
+
+
 static int __init
-add_range(struct res_range *range, int nr_range, unsigned long start,
-			      unsigned long end)
+add_range(struct res_range *range, int nr_range,
+	  unsigned long start, unsigned long end)
 {
-	/* out of slots */
+	/* Out of slots: */
 	if (nr_range >= RANGE_NUM)
 		return nr_range;
 
@@ -58,12 +82,12 @@ add_range(struct res_range *range, int nr_range, unsigned long start,
 }
 
 static int __init
-add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
-			      unsigned long end)
+add_range_with_merge(struct res_range *range, int nr_range,
+		     unsigned long start, unsigned long end)
 {
 	int i;
 
-	/* try to merge it with old one */
+	/* Try to merge it with old one: */
 	for (i = 0; i < nr_range; i++) {
 		unsigned long final_start, final_end;
 		unsigned long common_start, common_end;
@@ -84,7 +108,7 @@ add_range_with_merge(struct res_range *range, int nr_range, unsigned long start,
 		return nr_range;
 	}
 
-	/* need to add that */
+	/* Need to add it: */
 	return add_range(range, nr_range, start, end);
 }
 
@@ -117,7 +141,7 @@ subtract_range(struct res_range *range, unsigned long start, unsigned long end)
 		}
 
 		if (start > range[j].start && end < range[j].end) {
-			/* find the new spare */
+			/* Find the new spare: */
 			for (i = 0; i < RANGE_NUM; i++) {
 				if (range[i].end == 0)
 					break;
@@ -146,14 +170,8 @@ static int __init cmp_range(const void *x1, const void *x2)
 	return start1 - start2;
 }
 
-struct var_mtrr_range_state {
-	unsigned long base_pfn;
-	unsigned long size_pfn;
-	mtrr_type type;
-};
-
-static struct var_mtrr_range_state __initdata range_state[RANGE_NUM];
-static int __initdata debug_print;
+#define BIOS_BUG_MSG KERN_WARNING \
+	"WARNING: BIOS bug: VAR MTRR %d contains strange UC entry under 1M, check with your system vendor!\n"
 
 static int __init
 x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
@@ -180,7 +198,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
 				 range[i].start, range[i].end + 1);
 	}
 
-	/* take out UC ranges */
+	/* Take out UC ranges: */
 	for (i = 0; i < num_var_ranges; i++) {
 		type = range_state[i].type;
 		if (type != MTRR_TYPE_UNCACHABLE &&
@@ -193,9 +211,7 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
 		if (base < (1<<(20-PAGE_SHIFT)) && mtrr_state.have_fixed &&
 		    (mtrr_state.enabled & 1)) {
 			/* Var MTRR contains UC entry below 1M? Skip it: */
-			printk(KERN_WARNING "WARNING: BIOS bug: VAR MTRR %d "
-				"contains strange UC entry under 1M, check "
-				"with your system vendor!\n", i);
+			printk(BIOS_BUG_MSG, i);
 			if (base + size <= (1<<(20-PAGE_SHIFT)))
 				continue;
 			size -= (1<<(20-PAGE_SHIFT)) - base;
@@ -237,17 +253,13 @@ x86_get_mtrr_mem_range(struct res_range *range, int nr_range,
 	return nr_range;
 }
 
-static struct res_range __initdata range[RANGE_NUM];
-static int __initdata nr_range;
-
 #ifdef CONFIG_MTRR_SANITIZER
 
 static unsigned long __init sum_ranges(struct res_range *range, int nr_range)
 {
-	unsigned long sum;
+	unsigned long sum = 0;
 	int i;
 
-	sum = 0;
 	for (i = 0; i < nr_range; i++)
 		sum += range[i].end + 1 - range[i].start;
 
@@ -278,17 +290,9 @@ static int __init mtrr_cleanup_debug_setup(char *str)
 }
 early_param("mtrr_cleanup_debug", mtrr_cleanup_debug_setup);
 
-struct var_mtrr_state {
-	unsigned long	range_startk;
-	unsigned long	range_sizek;
-	unsigned long	chunk_sizek;
-	unsigned long	gran_sizek;
-	unsigned int	reg;
-};
-
 static void __init
 set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
-		unsigned char type, unsigned int address_bits)
+	     unsigned char type, unsigned int address_bits)
 {
 	u32 base_lo, base_hi, mask_lo, mask_hi;
 	u64 base, mask;
@@ -301,7 +305,7 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
 	mask = (1ULL << address_bits) - 1;
 	mask &= ~((((u64)sizek) << 10) - 1);
 
-	base  = ((u64)basek) << 10;
+	base = ((u64)basek) << 10;
 
 	base |= type;
 	mask |= 0x800;
@@ -317,15 +321,14 @@ set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
 
 static void __init
 save_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek,
-		unsigned char type)
+	      unsigned char type)
 {
 	range_state[reg].base_pfn = basek >> (PAGE_SHIFT - 10);
 	range_state[reg].size_pfn = sizek >> (PAGE_SHIFT - 10);
 	range_state[reg].type = type;
 }
 
-static void __init
-set_var_mtrr_all(unsigned int address_bits)
+static void __init set_var_mtrr_all(unsigned int address_bits)
 {
 	unsigned long basek, sizek;
 	unsigned char type;
@@ -342,11 +345,11 @@ set_var_mtrr_all(unsigned int address_bits)
 
 static unsigned long to_size_factor(unsigned long sizek, char *factorp)
 {
-	char factor;
 	unsigned long base = sizek;
+	char factor;
 
 	if (base & ((1<<10) - 1)) {
-		/* not MB alignment */
+		/* Not MB-aligned: */
 		factor = 'K';
 	} else if (base & ((1<<20) - 1)) {
 		factor = 'M';
@@ -372,11 +375,12 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk,
 		unsigned long max_align, align;
 		unsigned long sizek;
 
-		/* Compute the maximum size I can make a range */
+		/* Compute the maximum size with which we can make a range: */
 		if (range_startk)
 			max_align = ffs(range_startk) - 1;
 		else
 			max_align = 32;
+
 		align = fls(range_sizek) - 1;
 		if (align > max_align)
 			align = max_align;
@@ -386,11 +390,10 @@ range_to_mtrr(unsigned int reg, unsigned long range_startk,
 			char start_factor = 'K', size_factor = 'K';
 			unsigned long start_base, size_base;
 
-			start_base = to_size_factor(range_startk,
-							 &start_factor),
-			size_base = to_size_factor(sizek, &size_factor),
+			start_base = to_size_factor(range_startk, &start_factor);
+			size_base = to_size_factor(sizek, &size_factor);
 
-			printk(KERN_DEBUG "Setting variable MTRR %d, "
+			Dprintk("Setting variable MTRR %d, "
 				"base: %ld%cB, range: %ld%cB, type %s\n",
 				reg, start_base, start_factor,
 				size_base, size_factor,
@@ -425,10 +428,11 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
 	chunk_sizek = state->chunk_sizek;
 	gran_sizek = state->gran_sizek;
 
-	/* align with gran size, prevent small block used up MTRRs */
+	/* Align with gran size, prevent small block used up MTRRs: */
 	range_basek = ALIGN(state->range_startk, gran_sizek);
 	if ((range_basek > basek) && basek)
 		return second_sizek;
+
 	state->range_sizek -= (range_basek - state->range_startk);
 	range_sizek = ALIGN(state->range_sizek, gran_sizek);
 
@@ -439,22 +443,21 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
 	}
 	state->range_sizek = range_sizek;
 
-	/* try to append some small hole */
+	/* Try to append some small hole: */
 	range0_basek = state->range_startk;
 	range0_sizek = ALIGN(state->range_sizek, chunk_sizek);
 
-	/* no increase */
+	/* No increase: */
 	if (range0_sizek == state->range_sizek) {
-		if (debug_print)
-			printk(KERN_DEBUG "rangeX: %016lx - %016lx\n",
-				range0_basek<<10,
-				(range0_basek + state->range_sizek)<<10);
+		Dprintk("rangeX: %016lx - %016lx\n",
+			range0_basek<<10,
+			(range0_basek + state->range_sizek)<<10);
 		state->reg = range_to_mtrr(state->reg, range0_basek,
 				state->range_sizek, MTRR_TYPE_WRBACK);
 		return 0;
 	}
 
-	/* only cut back, when it is not the last */
+	/* Only cut back when it is not the last: */
 	if (sizek) {
 		while (range0_basek + range0_sizek > (basek + sizek)) {
 			if (range0_sizek >= chunk_sizek)
@@ -470,16 +473,16 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
 second_try:
 	range_basek = range0_basek + range0_sizek;
 
-	/* one hole in the middle */
+	/* One hole in the middle: */
 	if (range_basek > basek && range_basek <= (basek + sizek))
 		second_sizek = range_basek - basek;
 
 	if (range0_sizek > state->range_sizek) {
 
-		/* one hole in middle or at end */
+		/* One hole in middle or at the end: */
 		hole_sizek = range0_sizek - state->range_sizek - second_sizek;
 
-		/* hole size should be less than half of range0 size */
+		/* Hole size should be less than half of range0 size: */
 		if (hole_sizek >= (range0_sizek >> 1) &&
 		    range0_sizek >= chunk_sizek) {
 			range0_sizek -= chunk_sizek;
@@ -491,32 +494,30 @@ second_try:
 	}
 
 	if (range0_sizek) {
-		if (debug_print)
-			printk(KERN_DEBUG "range0: %016lx - %016lx\n",
-				range0_basek<<10,
-				(range0_basek + range0_sizek)<<10);
+		Dprintk("range0: %016lx - %016lx\n",
+			range0_basek<<10,
+			(range0_basek + range0_sizek)<<10);
 		state->reg = range_to_mtrr(state->reg, range0_basek,
 				range0_sizek, MTRR_TYPE_WRBACK);
 	}
 
 	if (range0_sizek < state->range_sizek) {
-		/* need to handle left over */
+		/* Need to handle left over range: */
 		range_sizek = state->range_sizek - range0_sizek;
 
-		if (debug_print)
-			printk(KERN_DEBUG "range: %016lx - %016lx\n",
-				 range_basek<<10,
-				 (range_basek + range_sizek)<<10);
+		Dprintk("range: %016lx - %016lx\n",
+			 range_basek<<10,
+			 (range_basek + range_sizek)<<10);
+
 		state->reg = range_to_mtrr(state->reg, range_basek,
 				 range_sizek, MTRR_TYPE_WRBACK);
 	}
 
 	if (hole_sizek) {
 		hole_basek = range_basek - hole_sizek - second_sizek;
-		if (debug_print)
-			printk(KERN_DEBUG "hole: %016lx - %016lx\n",
-				 hole_basek<<10,
-				 (hole_basek + hole_sizek)<<10);
+		Dprintk("hole: %016lx - %016lx\n",
+			 hole_basek<<10,
+			 (hole_basek + hole_sizek)<<10);
 		state->reg = range_to_mtrr(state->reg, hole_basek,
 				 hole_sizek, MTRR_TYPE_UNCACHABLE);
 	}
@@ -537,23 +538,23 @@ set_var_mtrr_range(struct var_mtrr_state *state, unsigned long base_pfn,
 	basek = base_pfn << (PAGE_SHIFT - 10);
 	sizek = size_pfn << (PAGE_SHIFT - 10);
 
-	/* See if I can merge with the last range */
+	/* See if I can merge with the last range: */
 	if ((basek <= 1024) ||
 	    (state->range_startk + state->range_sizek == basek)) {
 		unsigned long endk = basek + sizek;
 		state->range_sizek = endk - state->range_startk;
 		return;
 	}
-	/* Write the range mtrrs */
+	/* Write the range mtrrs: */
 	if (state->range_sizek != 0)
 		second_sizek = range_to_mtrr_with_hole(state, basek, sizek);
 
-	/* Allocate an msr */
+	/* Allocate an msr: */
 	state->range_startk = basek + second_sizek;
 	state->range_sizek  = sizek - second_sizek;
 }
 
-/* mininum size of mtrr block that can take hole */
+/* Mininum size of mtrr block that can take hole: */
 static u64 mtrr_chunk_size __initdata = (256ULL<<20);
 
 static int __init parse_mtrr_chunk_size_opt(char *p)
@@ -565,7 +566,7 @@ static int __init parse_mtrr_chunk_size_opt(char *p)
 }
 early_param("mtrr_chunk_size", parse_mtrr_chunk_size_opt);
 
-/* granity of mtrr of block */
+/* Granularity of mtrr of block: */
 static u64 mtrr_gran_size __initdata;
 
 static int __init parse_mtrr_gran_size_opt(char *p)
@@ -577,7 +578,7 @@ static int __init parse_mtrr_gran_size_opt(char *p)
 }
 early_param("mtrr_gran_size", parse_mtrr_gran_size_opt);
 
-static int nr_mtrr_spare_reg __initdata =
+static unsigned long nr_mtrr_spare_reg __initdata =
 				 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT;
 
 static int __init parse_mtrr_spare_reg(char *arg)
@@ -586,7 +587,6 @@ static int __init parse_mtrr_spare_reg(char *arg)
 		nr_mtrr_spare_reg = simple_strtoul(arg, NULL, 0);
 	return 0;
 }
-
 early_param("mtrr_spare_reg_nr", parse_mtrr_spare_reg);
 
 static int __init
@@ -594,8 +594,8 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range,
 		    u64 chunk_size, u64 gran_size)
 {
 	struct var_mtrr_state var_state;
-	int i;
 	int num_reg;
+	int i;
 
 	var_state.range_startk	= 0;
 	var_state.range_sizek	= 0;
@@ -605,17 +605,18 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range,
 
 	memset(range_state, 0, sizeof(range_state));
 
-	/* Write the range etc */
-	for (i = 0; i < nr_range; i++)
+	/* Write the range: */
+	for (i = 0; i < nr_range; i++) {
 		set_var_mtrr_range(&var_state, range[i].start,
 				   range[i].end - range[i].start + 1);
+	}
 
-	/* Write the last range */
+	/* Write the last range: */
 	if (var_state.range_sizek != 0)
 		range_to_mtrr_with_hole(&var_state, 0, 0);
 
 	num_reg = var_state.reg;
-	/* Clear out the extra MTRR's */
+	/* Clear out the extra MTRR's: */
 	while (var_state.reg < num_var_ranges) {
 		save_var_mtrr(var_state.reg, 0, 0, 0);
 		var_state.reg++;
@@ -625,11 +626,11 @@ x86_setup_var_mtrrs(struct res_range *range, int nr_range,
 }
 
 struct mtrr_cleanup_result {
-	unsigned long gran_sizek;
-	unsigned long chunk_sizek;
-	unsigned long lose_cover_sizek;
-	unsigned int num_reg;
-	int bad;
+	unsigned long	gran_sizek;
+	unsigned long	chunk_sizek;
+	unsigned long	lose_cover_sizek;
+	unsigned int	num_reg;
+	int		bad;
 };
 
 /*
@@ -645,10 +646,10 @@ static unsigned long __initdata min_loss_pfn[RANGE_NUM];
 
 static void __init print_out_mtrr_range_state(void)
 {
-	int i;
 	char start_factor = 'K', size_factor = 'K';
 	unsigned long start_base, size_base;
 	mtrr_type type;
+	int i;
 
 	for (i = 0; i < num_var_ranges; i++) {
 
@@ -676,10 +677,10 @@ static int __init mtrr_need_cleanup(void)
 	int i;
 	mtrr_type type;
 	unsigned long size;
-	/* extra one for all 0 */
+	/* Extra one for all 0: */
 	int num[MTRR_NUM_TYPES + 1];
 
-	/* check entries number */
+	/* Check entries number: */
 	memset(num, 0, sizeof(num));
 	for (i = 0; i < num_var_ranges; i++) {
 		type = range_state[i].type;
@@ -693,88 +694,86 @@ static int __init mtrr_need_cleanup(void)
 		num[type]++;
 	}
 
-	/* check if we got UC entries */
+	/* Check if we got UC entries: */
 	if (!num[MTRR_TYPE_UNCACHABLE])
 		return 0;
 
-	/* check if we only had WB and UC */
+	/* Check if we only had WB and UC */
 	if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
-		num_var_ranges - num[MTRR_NUM_TYPES])
+	    num_var_ranges - num[MTRR_NUM_TYPES])
 		return 0;
 
 	return 1;
 }
 
 static unsigned long __initdata range_sums;
-static void __init mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
-					 unsigned long extra_remove_base,
-					 unsigned long extra_remove_size,
-					 int i)
+
+static void __init
+mtrr_calc_range_state(u64 chunk_size, u64 gran_size,
+		      unsigned long x_remove_base,
+		      unsigned long x_remove_size, int i)
 {
-	int num_reg;
 	static struct res_range range_new[RANGE_NUM];
-	static int nr_range_new;
 	unsigned long range_sums_new;
+	static int nr_range_new;
+	int num_reg;
 
-	/* convert ranges to var ranges state */
-	num_reg = x86_setup_var_mtrrs(range, nr_range,
-						chunk_size, gran_size);
+	/* Convert ranges to var ranges state: */
+	num_reg = x86_setup_var_mtrrs(range, nr_range, chunk_size, gran_size);
 
-	/* we got new setting in range_state, check it */
+	/* We got new setting in range_state, check it: */
 	memset(range_new, 0, sizeof(range_new));
 	nr_range_new = x86_get_mtrr_mem_range(range_new, 0,
-				extra_remove_base, extra_remove_size);
+				x_remove_base, x_remove_size);
 	range_sums_new = sum_ranges(range_new, nr_range_new);
 
 	result[i].chunk_sizek = chunk_size >> 10;
 	result[i].gran_sizek = gran_size >> 10;
 	result[i].num_reg = num_reg;
+
 	if (range_sums < range_sums_new) {
-		result[i].lose_cover_sizek =
-			(range_sums_new - range_sums) << PSHIFT;
+		result[i].lose_cover_sizek = (range_sums_new - range_sums) << PSHIFT;
 		result[i].bad = 1;
-	} else
-		result[i].lose_cover_sizek =
-			(range_sums - range_sums_new) << PSHIFT;
+	} else {
+		result[i].lose_cover_sizek = (range_sums - range_sums_new) << PSHIFT;
+	}
 
-	/* double check it */
+	/* Double check it: */
 	if (!result[i].bad && !result[i].lose_cover_sizek) {
-		if (nr_range_new != nr_range ||
-			memcmp(range, range_new, sizeof(range)))
-				result[i].bad = 1;
+		if (nr_range_new != nr_range || memcmp(range, range_new, sizeof(range)))
+			result[i].bad = 1;
 	}
 
-	if (!result[i].bad && (range_sums - range_sums_new <
-				min_loss_pfn[num_reg])) {
-		min_loss_pfn[num_reg] =
-			range_sums - range_sums_new;
-	}
+	if (!result[i].bad && (range_sums - range_sums_new < min_loss_pfn[num_reg]))
+		min_loss_pfn[num_reg] = range_sums - range_sums_new;
 }
 
 static void __init mtrr_print_out_one_result(int i)
 {
-	char gran_factor, chunk_factor, lose_factor;
 	unsigned long gran_base, chunk_base, lose_base;
+	char gran_factor, chunk_factor, lose_factor;
 
 	gran_base = to_size_factor(result[i].gran_sizek, &gran_factor),
 	chunk_base = to_size_factor(result[i].chunk_sizek, &chunk_factor),
 	lose_base = to_size_factor(result[i].lose_cover_sizek, &lose_factor),
-	printk(KERN_INFO "%sgran_size: %ld%c \tchunk_size: %ld%c \t",
-			result[i].bad ? "*BAD*" : " ",
-			gran_base, gran_factor, chunk_base, chunk_factor);
-	printk(KERN_CONT "num_reg: %d  \tlose cover RAM: %s%ld%c\n",
-			result[i].num_reg, result[i].bad ? "-" : "",
-			lose_base, lose_factor);
+
+	pr_info("%sgran_size: %ld%c \tchunk_size: %ld%c \t",
+		result[i].bad ? "*BAD*" : " ",
+		gran_base, gran_factor, chunk_base, chunk_factor);
+	pr_cont("num_reg: %d  \tlose cover RAM: %s%ld%c\n",
+		result[i].num_reg, result[i].bad ? "-" : "",
+		lose_base, lose_factor);
 }
 
 static int __init mtrr_search_optimal_index(void)
 {
-	int i;
 	int num_reg_good;
 	int index_good;
+	int i;
 
 	if (nr_mtrr_spare_reg >= num_var_ranges)
 		nr_mtrr_spare_reg = num_var_ranges - 1;
+
 	num_reg_good = -1;
 	for (i = num_var_ranges - nr_mtrr_spare_reg; i > 0; i--) {
 		if (!min_loss_pfn[i])
@@ -796,24 +795,24 @@ static int __init mtrr_search_optimal_index(void)
 	return index_good;
 }
 
-
 int __init mtrr_cleanup(unsigned address_bits)
 {
-	unsigned long extra_remove_base, extra_remove_size;
+	unsigned long x_remove_base, x_remove_size;
 	unsigned long base, size, def, dummy;
-	mtrr_type type;
 	u64 chunk_size, gran_size;
+	mtrr_type type;
 	int index_good;
 	int i;
 
 	if (!is_cpu(INTEL) || enable_mtrr_cleanup < 1)
 		return 0;
+
 	rdmsr(MSR_MTRRdefType, def, dummy);
 	def &= 0xff;
 	if (def != MTRR_TYPE_UNCACHABLE)
 		return 0;
 
-	/* get it and store it aside */
+	/* Get it and store it aside: */
 	memset(range_state, 0, sizeof(range_state));
 	for (i = 0; i < num_var_ranges; i++) {
 		mtrr_if->get(i, &base, &size, &type);
@@ -822,29 +821,28 @@ int __init mtrr_cleanup(unsigned address_bits)
 		range_state[i].type = type;
 	}
 
-	/* check if we need handle it and can handle it */
+	/* Check if we need handle it and can handle it: */
 	if (!mtrr_need_cleanup())
 		return 0;
 
-	/* print original var MTRRs at first, for debugging: */
+	/* Print original var MTRRs at first, for debugging: */
 	printk(KERN_DEBUG "original variable MTRRs\n");
 	print_out_mtrr_range_state();
 
 	memset(range, 0, sizeof(range));
-	extra_remove_size = 0;
-	extra_remove_base = 1 << (32 - PAGE_SHIFT);
+	x_remove_size = 0;
+	x_remove_base = 1 << (32 - PAGE_SHIFT);
 	if (mtrr_tom2)
-		extra_remove_size =
-			(mtrr_tom2 >> PAGE_SHIFT) - extra_remove_base;
-	nr_range = x86_get_mtrr_mem_range(range, 0, extra_remove_base,
-					  extra_remove_size);
+		x_remove_size = (mtrr_tom2 >> PAGE_SHIFT) - x_remove_base;
+
+	nr_range = x86_get_mtrr_mem_range(range, 0, x_remove_base, x_remove_size);
 	/*
-	 * [0, 1M) should always be coverred by var mtrr with WB
-	 * and fixed mtrrs should take effective before var mtrr for it
+	 * [0, 1M) should always be covered by var mtrr with WB
+	 * and fixed mtrrs should take effect before var mtrr for it:
 	 */
 	nr_range = add_range_with_merge(range, nr_range, 0,
 					(1ULL<<(20 - PAGE_SHIFT)) - 1);
-	/* sort the ranges */
+	/* Sort the ranges: */
 	sort(range, nr_range, sizeof(struct res_range), cmp_range, NULL);
 
 	range_sums = sum_ranges(range, nr_range);
@@ -854,7 +852,7 @@ int __init mtrr_cleanup(unsigned address_bits)
 	if (mtrr_chunk_size && mtrr_gran_size) {
 		i = 0;
 		mtrr_calc_range_state(mtrr_chunk_size, mtrr_gran_size,
-				      extra_remove_base, extra_remove_size, i);
+				      x_remove_base, x_remove_size, i);
 
 		mtrr_print_out_one_result(i);
 
@@ -880,7 +878,7 @@ int __init mtrr_cleanup(unsigned address_bits)
 				continue;
 
 			mtrr_calc_range_state(chunk_size, gran_size,
-				      extra_remove_base, extra_remove_size, i);
+				      x_remove_base, x_remove_size, i);
 			if (debug_print) {
 				mtrr_print_out_one_result(i);
 				printk(KERN_INFO "\n");
@@ -890,7 +888,7 @@ int __init mtrr_cleanup(unsigned address_bits)
 		}
 	}
 
-	/* try to find the optimal index */
+	/* Try to find the optimal index: */
 	index_good = mtrr_search_optimal_index();
 
 	if (index_good != -1) {
@@ -898,7 +896,7 @@ int __init mtrr_cleanup(unsigned address_bits)
 		i = index_good;
 		mtrr_print_out_one_result(i);
 
-		/* convert ranges to var ranges state */
+		/* Convert ranges to var ranges state: */
 		chunk_size = result[i].chunk_sizek;
 		chunk_size <<= 10;
 		gran_size = result[i].gran_sizek;
@@ -941,8 +939,8 @@ early_param("disable_mtrr_trim", disable_mtrr_trim_setup);
  * Note this won't check if the MTRRs < 4GB where the magic bit doesn't
  * apply to are wrong, but so far we don't know of any such case in the wild.
  */
-#define Tom2Enabled (1U << 21)
-#define Tom2ForceMemTypeWB (1U << 22)
+#define Tom2Enabled		(1U << 21)
+#define Tom2ForceMemTypeWB	(1U << 22)
 
 int __init amd_special_default_mtrr(void)
 {
@@ -952,7 +950,7 @@ int __init amd_special_default_mtrr(void)
 		return 0;
 	if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11)
 		return 0;
-	/* In case some hypervisor doesn't pass SYSCFG through */
+	/* In case some hypervisor doesn't pass SYSCFG through: */
 	if (rdmsr_safe(MSR_K8_SYSCFG, &l, &h) < 0)
 		return 0;
 	/*
@@ -965,19 +963,21 @@ int __init amd_special_default_mtrr(void)
 	return 0;
 }
 
-static u64 __init real_trim_memory(unsigned long start_pfn,
-				   unsigned long limit_pfn)
+static u64 __init
+real_trim_memory(unsigned long start_pfn, unsigned long limit_pfn)
 {
 	u64 trim_start, trim_size;
+
 	trim_start = start_pfn;
 	trim_start <<= PAGE_SHIFT;
+
 	trim_size = limit_pfn;
 	trim_size <<= PAGE_SHIFT;
 	trim_size -= trim_start;
 
-	return e820_update_range(trim_start, trim_size, E820_RAM,
-				E820_RESERVED);
+	return e820_update_range(trim_start, trim_size, E820_RAM, E820_RESERVED);
 }
+
 /**
  * mtrr_trim_uncached_memory - trim RAM not covered by MTRRs
  * @end_pfn: ending page frame number
@@ -985,7 +985,7 @@ static u64 __init real_trim_memory(unsigned long start_pfn,
  * Some buggy BIOSes don't setup the MTRRs properly for systems with certain
  * memory configurations.  This routine checks that the highest MTRR matches
  * the end of memory, to make sure the MTRRs having a write back type cover
- * all of the memory the kernel is intending to use. If not, it'll trim any
+ * all of the memory the kernel is intending to use.  If not, it'll trim any
  * memory off the end by adjusting end_pfn, removing it from the kernel's
  * allocation pools, warning the user with an obnoxious message.
  */
@@ -994,21 +994,22 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 	unsigned long i, base, size, highest_pfn = 0, def, dummy;
 	mtrr_type type;
 	u64 total_trim_size;
-
 	/* extra one for all 0 */
 	int num[MTRR_NUM_TYPES + 1];
+
 	/*
 	 * Make sure we only trim uncachable memory on machines that
 	 * support the Intel MTRR architecture:
 	 */
 	if (!is_cpu(INTEL) || disable_mtrr_trim)
 		return 0;
+
 	rdmsr(MSR_MTRRdefType, def, dummy);
 	def &= 0xff;
 	if (def != MTRR_TYPE_UNCACHABLE)
 		return 0;
 
-	/* get it and store it aside */
+	/* Get it and store it aside: */
 	memset(range_state, 0, sizeof(range_state));
 	for (i = 0; i < num_var_ranges; i++) {
 		mtrr_if->get(i, &base, &size, &type);
@@ -1017,7 +1018,7 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 		range_state[i].type = type;
 	}
 
-	/* Find highest cached pfn */
+	/* Find highest cached pfn: */
 	for (i = 0; i < num_var_ranges; i++) {
 		type = range_state[i].type;
 		if (type != MTRR_TYPE_WRBACK)
@@ -1028,13 +1029,13 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 			highest_pfn = base + size;
 	}
 
-	/* kvm/qemu doesn't have mtrr set right, don't trim them all */
+	/* kvm/qemu doesn't have mtrr set right, don't trim them all: */
 	if (!highest_pfn) {
 		printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n");
 		return 0;
 	}
 
-	/* check entries number */
+	/* Check entries number: */
 	memset(num, 0, sizeof(num));
 	for (i = 0; i < num_var_ranges; i++) {
 		type = range_state[i].type;
@@ -1046,11 +1047,11 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 		num[type]++;
 	}
 
-	/* no entry for WB? */
+	/* No entry for WB? */
 	if (!num[MTRR_TYPE_WRBACK])
 		return 0;
 
-	/* check if we only had WB and UC */
+	/* Check if we only had WB and UC: */
 	if (num[MTRR_TYPE_WRBACK] + num[MTRR_TYPE_UNCACHABLE] !=
 		num_var_ranges - num[MTRR_NUM_TYPES])
 		return 0;
@@ -1066,31 +1067,31 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 	}
 	nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);
 
+	/* Check the head: */
 	total_trim_size = 0;
-	/* check the head */
 	if (range[0].start)
 		total_trim_size += real_trim_memory(0, range[0].start);
-	/* check the holes */
+
+	/* Check the holes: */
 	for (i = 0; i < nr_range - 1; i++) {
 		if (range[i].end + 1 < range[i+1].start)
 			total_trim_size += real_trim_memory(range[i].end + 1,
 							    range[i+1].start);
 	}
-	/* check the top */
+
+	/* Check the top: */
 	i = nr_range - 1;
 	if (range[i].end + 1 < end_pfn)
 		total_trim_size += real_trim_memory(range[i].end + 1,
 							 end_pfn);
 
 	if (total_trim_size) {
-		printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
-			" all of memory, losing %lluMB of RAM.\n",
-			total_trim_size >> 20);
+		pr_warning("WARNING: BIOS bug: CPU MTRRs don't cover all of memory, losing %lluMB of RAM.\n", total_trim_size >> 20);
 
 		if (!changed_by_mtrr_cleanup)
 			WARN_ON(1);
 
-		printk(KERN_INFO "update e820 for mtrr\n");
+		pr_info("update e820 for mtrr\n");
 		update_e820();
 
 		return 1;
@@ -1098,4 +1099,3 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 
 	return 0;
 }
-
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
index ff14c32..228d982 100644
--- a/arch/x86/kernel/cpu/mtrr/cyrix.c
+++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
@@ -1,38 +1,40 @@
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/mm.h>
-#include <asm/mtrr.h>
-#include <asm/msr.h>
-#include <asm/io.h>
+
 #include <asm/processor-cyrix.h>
 #include <asm/processor-flags.h>
+#include <asm/mtrr.h>
+#include <asm/msr.h>
+
 #include "mtrr.h"
 
 static void
 cyrix_get_arr(unsigned int reg, unsigned long *base,
 	      unsigned long *size, mtrr_type * type)
 {
-	unsigned long flags;
 	unsigned char arr, ccr3, rcr, shift;
+	unsigned long flags;
 
 	arr = CX86_ARR_BASE + (reg << 1) + reg;	/* avoid multiplication by 3 */
 
-	/* Save flags and disable interrupts */
 	local_irq_save(flags);
 
 	ccr3 = getCx86(CX86_CCR3);
 	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);	/* enable MAPEN */
-	((unsigned char *) base)[3] = getCx86(arr);
-	((unsigned char *) base)[2] = getCx86(arr + 1);
-	((unsigned char *) base)[1] = getCx86(arr + 2);
+	((unsigned char *)base)[3] = getCx86(arr);
+	((unsigned char *)base)[2] = getCx86(arr + 1);
+	((unsigned char *)base)[1] = getCx86(arr + 2);
 	rcr = getCx86(CX86_RCR_BASE + reg);
-	setCx86(CX86_CCR3, ccr3);	/* disable MAPEN */
+	setCx86(CX86_CCR3, ccr3);			/* disable MAPEN */
 
-	/* Enable interrupts if it was enabled previously */
 	local_irq_restore(flags);
+
 	shift = ((unsigned char *) base)[1] & 0x0f;
 	*base >>= PAGE_SHIFT;
 
-	/* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7
+	/*
+	 * Power of two, at least 4K on ARR0-ARR6, 256K on ARR7
 	 * Note: shift==0xf means 4G, this is unsupported.
 	 */
 	if (shift)
@@ -76,17 +78,20 @@ cyrix_get_arr(unsigned int reg, unsigned long *base,
 	}
 }
 
+/*
+ * cyrix_get_free_region - get a free ARR.
+ *
+ * @base: the starting (base) address of the region.
+ * @size: the size (in bytes) of the region.
+ *
+ * Returns: the index of the region on success, else -1 on error.
+*/
 static int
 cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg)
-/*  [SUMMARY] Get a free ARR.
-    <base> The starting (base) address of the region.
-    <size> The size (in bytes) of the region.
-    [RETURNS] The index of the region on success, else -1 on error.
-*/
 {
-	int i;
-	mtrr_type ltype;
 	unsigned long lbase, lsize;
+	mtrr_type ltype;
+	int i;
 
 	switch (replace_reg) {
 	case 7:
@@ -107,14 +112,17 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg)
 		cyrix_get_arr(7, &lbase, &lsize, &ltype);
 		if (lsize == 0)
 			return 7;
-		/*  Else try ARR0-ARR6 first  */
+		/* Else try ARR0-ARR6 first  */
 	} else {
 		for (i = 0; i < 7; i++) {
 			cyrix_get_arr(i, &lbase, &lsize, &ltype);
 			if (lsize == 0)
 				return i;
 		}
-		/* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */
+		/*
+		 * ARR0-ARR6 isn't free
+		 * try ARR7 but its size must be at least 256K
+		 */
 		cyrix_get_arr(i, &lbase, &lsize, &ltype);
 		if ((lsize == 0) && (size >= 0x40))
 			return i;
@@ -122,21 +130,22 @@ cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg)
 	return -ENOSPC;
 }
 
-static u32 cr4 = 0;
-static u32 ccr3;
+static u32 cr4, ccr3;
 
 static void prepare_set(void)
 {
 	u32 cr0;
 
 	/*  Save value of CR4 and clear Page Global Enable (bit 7)  */
-	if ( cpu_has_pge ) {
+	if (cpu_has_pge) {
 		cr4 = read_cr4();
 		write_cr4(cr4 & ~X86_CR4_PGE);
 	}
 
-	/*  Disable and flush caches. Note that wbinvd flushes the TLBs as
-	    a side-effect  */
+	/*
+	 * Disable and flush caches.
+	 * Note that wbinvd flushes the TLBs as a side-effect
+	 */
 	cr0 = read_cr0() | X86_CR0_CD;
 	wbinvd();
 	write_cr0(cr0);
@@ -147,22 +156,21 @@ static void prepare_set(void)
 
 	/* Cyrix ARRs - everything else was excluded at the top */
 	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
-
 }
 
 static void post_set(void)
 {
-	/*  Flush caches and TLBs  */
+	/* Flush caches and TLBs */
 	wbinvd();
 
 	/* Cyrix ARRs - everything else was excluded at the top */
 	setCx86(CX86_CCR3, ccr3);
-		
-	/*  Enable caches  */
+
+	/* Enable caches */
 	write_cr0(read_cr0() & 0xbfffffff);
 
-	/*  Restore value of CR4  */
-	if ( cpu_has_pge )
+	/* Restore value of CR4 */
+	if (cpu_has_pge)
 		write_cr4(cr4);
 }
 
@@ -178,7 +186,8 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base,
 		size >>= 6;
 
 	size &= 0x7fff;		/* make sure arr_size <= 14 */
-	for (arr_size = 0; size; arr_size++, size >>= 1) ;
+	for (arr_size = 0; size; arr_size++, size >>= 1)
+		;
 
 	if (reg < 7) {
 		switch (type) {
@@ -215,18 +224,18 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base,
 	prepare_set();
 
 	base <<= PAGE_SHIFT;
-	setCx86(arr, ((unsigned char *) &base)[3]);
-	setCx86(arr + 1, ((unsigned char *) &base)[2]);
-	setCx86(arr + 2, (((unsigned char *) &base)[1]) | arr_size);
+	setCx86(arr + 0,  ((unsigned char *)&base)[3]);
+	setCx86(arr + 1,  ((unsigned char *)&base)[2]);
+	setCx86(arr + 2, (((unsigned char *)&base)[1]) | arr_size);
 	setCx86(CX86_RCR_BASE + reg, arr_type);
 
 	post_set();
 }
 
 typedef struct {
-	unsigned long base;
-	unsigned long size;
-	mtrr_type type;
+	unsigned long	base;
+	unsigned long	size;
+	mtrr_type	type;
 } arr_state_t;
 
 static arr_state_t arr_state[8] = {
@@ -247,16 +256,17 @@ static void cyrix_set_all(void)
 		setCx86(CX86_CCR0 + i, ccr_state[i]);
 	for (; i < 7; i++)
 		setCx86(CX86_CCR4 + i, ccr_state[i]);
-	for (i = 0; i < 8; i++)
-		cyrix_set_arr(i, arr_state[i].base, 
+
+	for (i = 0; i < 8; i++) {
+		cyrix_set_arr(i, arr_state[i].base,
 			      arr_state[i].size, arr_state[i].type);
+	}
 
 	post_set();
 }
 
 static struct mtrr_ops cyrix_mtrr_ops = {
 	.vendor            = X86_VENDOR_CYRIX,
-//	.init              = cyrix_arr_init,
 	.set_all	   = cyrix_set_all,
 	.set               = cyrix_set_arr,
 	.get               = cyrix_get_arr,
@@ -270,5 +280,3 @@ int __init cyrix_init_mtrr(void)
 	set_mtrr_ops(&cyrix_mtrr_ops);
 	return 0;
 }
-
-//arch_initcall(cyrix_init_mtrr);
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 0543f69..55da0c5 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -1,28 +1,34 @@
-/* This only handles 32bit MTRR on 32bit hosts. This is strictly wrong
-   because MTRRs can span upto 40 bits (36bits on most modern x86) */ 
+/*
+ * This only handles 32bit MTRR on 32bit hosts. This is strictly wrong
+ * because MTRRs can span upto 40 bits (36bits on most modern x86)
+ */
+#define DEBUG
+
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 #include <linux/mm.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <asm/mtrr.h>
-#include <asm/msr.h>
-#include <asm/system.h>
-#include <asm/cpufeature.h>
+
 #include <asm/processor-flags.h>
+#include <asm/cpufeature.h>
 #include <asm/tlbflush.h>
+#include <asm/system.h>
+#include <asm/mtrr.h>
+#include <asm/msr.h>
 #include <asm/pat.h>
+
 #include "mtrr.h"
 
 struct fixed_range_block {
-	int base_msr; /* start address of an MTRR block */
-	int ranges;   /* number of MTRRs in this block  */
+	int base_msr;		/* start address of an MTRR block */
+	int ranges;		/* number of MTRRs in this block  */
 };
 
 static struct fixed_range_block fixed_range_blocks[] = {
-	{ MSR_MTRRfix64K_00000, 1 }, /* one  64k MTRR  */
-	{ MSR_MTRRfix16K_80000, 2 }, /* two  16k MTRRs */
-	{ MSR_MTRRfix4K_C0000,  8 }, /* eight 4k MTRRs */
+	{ MSR_MTRRfix64K_00000, 1 }, /* one   64k MTRR  */
+	{ MSR_MTRRfix16K_80000, 2 }, /* two   16k MTRRs */
+	{ MSR_MTRRfix4K_C0000,  8 }, /* eight  4k MTRRs */
 	{}
 };
 
@@ -30,10 +36,10 @@ static unsigned long smp_changes_mask;
 static int mtrr_state_set;
 u64 mtrr_tom2;
 
-struct mtrr_state_type mtrr_state = {};
+struct mtrr_state_type mtrr_state;
 EXPORT_SYMBOL_GPL(mtrr_state);
 
-/**
+/*
  * BIOS is expected to clear MtrrFixDramModEn bit, see for example
  * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
  * Opteron Processors" (26094 Rev. 3.30 February 2006), section
@@ -104,9 +110,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
 	 * Look of multiple ranges matching this address and pick type
 	 * as per MTRR precedence
 	 */
-	if (!(mtrr_state.enabled & 2)) {
+	if (!(mtrr_state.enabled & 2))
 		return mtrr_state.def_type;
-	}
 
 	prev_match = 0xFF;
 	for (i = 0; i < num_var_ranges; ++i) {
@@ -125,9 +130,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
 		if (start_state != end_state)
 			return 0xFE;
 
-		if ((start & mask) != (base & mask)) {
+		if ((start & mask) != (base & mask))
 			continue;
-		}
 
 		curr_match = mtrr_state.var_ranges[i].base_lo & 0xff;
 		if (prev_match == 0xFF) {
@@ -148,9 +152,8 @@ u8 mtrr_type_lookup(u64 start, u64 end)
 			curr_match = MTRR_TYPE_WRTHROUGH;
 		}
 
-		if (prev_match != curr_match) {
+		if (prev_match != curr_match)
 			return MTRR_TYPE_UNCACHABLE;
-		}
 	}
 
 	if (mtrr_tom2) {
@@ -164,7 +167,7 @@ u8 mtrr_type_lookup(u64 start, u64 end)
 	return mtrr_state.def_type;
 }
 
-/*  Get the MSR pair relating to a var range  */
+/* Get the MSR pair relating to a var range */
 static void
 get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
 {
@@ -172,7 +175,7 @@ get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr)
 	rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
 }
 
-/*  fill the MSR pair relating to a var range  */
+/* Fill the MSR pair relating to a var range */
 void fill_mtrr_var_range(unsigned int index,
 		u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi)
 {
@@ -186,10 +189,9 @@ void fill_mtrr_var_range(unsigned int index,
 	vr[index].mask_hi = mask_hi;
 }
 
-static void
-get_fixed_ranges(mtrr_type * frs)
+static void get_fixed_ranges(mtrr_type *frs)
 {
-	unsigned int *p = (unsigned int *) frs;
+	unsigned int *p = (unsigned int *)frs;
 	int i;
 
 	k8_check_syscfg_dram_mod_en();
@@ -217,22 +219,22 @@ static void __init print_fixed_last(void)
 	if (!last_fixed_end)
 		return;
 
-	printk(KERN_DEBUG "  %05X-%05X %s\n", last_fixed_start,
-		last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type));
+	pr_debug("  %05X-%05X %s\n", last_fixed_start,
+		 last_fixed_end - 1, mtrr_attrib_to_str(last_fixed_type));
 
 	last_fixed_end = 0;
 }
 
 static void __init update_fixed_last(unsigned base, unsigned end,
-				       mtrr_type type)
+				     mtrr_type type)
 {
 	last_fixed_start = base;
 	last_fixed_end = end;
 	last_fixed_type = type;
 }
 
-static void __init print_fixed(unsigned base, unsigned step,
-			       const mtrr_type *types)
+static void __init
+print_fixed(unsigned base, unsigned step, const mtrr_type *types)
 {
 	unsigned i;
 
@@ -259,54 +261,55 @@ static void __init print_mtrr_state(void)
 	unsigned int i;
 	int high_width;
 
-	printk(KERN_DEBUG "MTRR default type: %s\n",
-			 mtrr_attrib_to_str(mtrr_state.def_type));
+	pr_debug("MTRR default type: %s\n",
+		 mtrr_attrib_to_str(mtrr_state.def_type));
 	if (mtrr_state.have_fixed) {
-		printk(KERN_DEBUG "MTRR fixed ranges %sabled:\n",
-		       mtrr_state.enabled & 1 ? "en" : "dis");
+		pr_debug("MTRR fixed ranges %sabled:\n",
+			 mtrr_state.enabled & 1 ? "en" : "dis");
 		print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0);
 		for (i = 0; i < 2; ++i)
-			print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8);
+			print_fixed(0x80000 + i * 0x20000, 0x04000,
+				    mtrr_state.fixed_ranges + (i + 1) * 8);
 		for (i = 0; i < 8; ++i)
-			print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8);
+			print_fixed(0xC0000 + i * 0x08000, 0x01000,
+				    mtrr_state.fixed_ranges + (i + 3) * 8);
 
 		/* tail */
 		print_fixed_last();
 	}
-	printk(KERN_DEBUG "MTRR variable ranges %sabled:\n",
-	       mtrr_state.enabled & 2 ? "en" : "dis");
+	pr_debug("MTRR variable ranges %sabled:\n",
+		 mtrr_state.enabled & 2 ? "en" : "dis");
 	if (size_or_mask & 0xffffffffUL)
 		high_width = ffs(size_or_mask & 0xffffffffUL) - 1;
 	else
 		high_width = ffs(size_or_mask>>32) + 32 - 1;
 	high_width = (high_width - (32 - PAGE_SHIFT) + 3) / 4;
+
 	for (i = 0; i < num_var_ranges; ++i) {
 		if (mtrr_state.var_ranges[i].mask_lo & (1 << 11))
-			printk(KERN_DEBUG "  %u base %0*X%05X000 mask %0*X%05X000 %s\n",
-			       i,
-			       high_width,
-			       mtrr_state.var_ranges[i].base_hi,
-			       mtrr_state.var_ranges[i].base_lo >> 12,
-			       high_width,
-			       mtrr_state.var_ranges[i].mask_hi,
-			       mtrr_state.var_ranges[i].mask_lo >> 12,
-			       mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
+			pr_debug("  %u base %0*X%05X000 mask %0*X%05X000 %s\n",
+				 i,
+				 high_width,
+				 mtrr_state.var_ranges[i].base_hi,
+				 mtrr_state.var_ranges[i].base_lo >> 12,
+				 high_width,
+				 mtrr_state.var_ranges[i].mask_hi,
+				 mtrr_state.var_ranges[i].mask_lo >> 12,
+				 mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff));
 		else
-			printk(KERN_DEBUG "  %u disabled\n", i);
-	}
-	if (mtrr_tom2) {
-		printk(KERN_DEBUG "TOM2: %016llx aka %lldM\n",
-				  mtrr_tom2, mtrr_tom2>>20);
+			pr_debug("  %u disabled\n", i);
 	}
+	if (mtrr_tom2)
+		pr_debug("TOM2: %016llx aka %lldM\n", mtrr_tom2, mtrr_tom2>>20);
 }
 
-/*  Grab all of the MTRR state for this CPU into *state  */
+/* Grab all of the MTRR state for this CPU into *state */
 void __init get_mtrr_state(void)
 {
-	unsigned int i;
 	struct mtrr_var_range *vrs;
-	unsigned lo, dummy;
 	unsigned long flags;
+	unsigned lo, dummy;
+	unsigned int i;
 
 	vrs = mtrr_state.var_ranges;
 
@@ -324,6 +327,7 @@ void __init get_mtrr_state(void)
 
 	if (amd_special_default_mtrr()) {
 		unsigned low, high;
+
 		/* TOP_MEM2 */
 		rdmsr(MSR_K8_TOP_MEM2, low, high);
 		mtrr_tom2 = high;
@@ -344,10 +348,9 @@ void __init get_mtrr_state(void)
 
 	post_set();
 	local_irq_restore(flags);
-
 }
 
-/*  Some BIOS's are fucked and don't set all MTRRs the same!  */
+/* Some BIOS's are messed up and don't set all MTRRs the same! */
 void __init mtrr_state_warn(void)
 {
 	unsigned long mask = smp_changes_mask;
@@ -355,28 +358,33 @@ void __init mtrr_state_warn(void)
 	if (!mask)
 		return;
 	if (mask & MTRR_CHANGE_MASK_FIXED)
-		printk(KERN_WARNING "mtrr: your CPUs had inconsistent fixed MTRR settings\n");
+		pr_warning("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
 	if (mask & MTRR_CHANGE_MASK_VARIABLE)
-		printk(KERN_WARNING "mtrr: your CPUs had inconsistent variable MTRR settings\n");
+		pr_warning("mtrr: your CPUs had inconsistent variable MTRR settings\n");
 	if (mask & MTRR_CHANGE_MASK_DEFTYPE)
-		printk(KERN_WARNING "mtrr: your CPUs had inconsistent MTRRdefType settings\n");
+		pr_warning("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
+
 	printk(KERN_INFO "mtrr: probably your BIOS does not setup all CPUs.\n");
 	printk(KERN_INFO "mtrr: corrected configuration.\n");
 }
 
-/* Doesn't attempt to pass an error out to MTRR users
-   because it's quite complicated in some cases and probably not
-   worth it because the best error handling is to ignore it. */
+/*
+ * Doesn't attempt to pass an error out to MTRR users
+ * because it's quite complicated in some cases and probably not
+ * worth it because the best error handling is to ignore it.
+ */
 void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b)
 {
-	if (wrmsr_safe(msr, a, b) < 0)
+	if (wrmsr_safe(msr, a, b) < 0) {
 		printk(KERN_ERR
 			"MTRR: CPU %u: Writing MSR %x to %x:%x failed\n",
 			smp_processor_id(), msr, a, b);
+	}
 }
 
 /**
- * set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have
+ * set_fixed_range - checks & updates a fixed-range MTRR if it
+ *		     differs from the value it should have
  * @msr: MSR address of the MTTR which should be checked and updated
  * @changed: pointer which indicates whether the MTRR needed to be changed
  * @msrwords: pointer to the MSR values which the MSR should have
@@ -401,20 +409,23 @@ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
  *
  * Returns: The index of the region on success, else negative on error.
  */
-int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg)
+int
+generic_get_free_region(unsigned long base, unsigned long size, int replace_reg)
 {
-	int i, max;
-	mtrr_type ltype;
 	unsigned long lbase, lsize;
+	mtrr_type ltype;
+	int i, max;
 
 	max = num_var_ranges;
 	if (replace_reg >= 0 && replace_reg < max)
 		return replace_reg;
+
 	for (i = 0; i < max; ++i) {
 		mtrr_if->get(i, &lbase, &lsize, &ltype);
 		if (lsize == 0)
 			return i;
 	}
+
 	return -ENOSPC;
 }
 
@@ -434,7 +445,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
 	rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
 
 	if ((mask_lo & 0x800) == 0) {
-		/*  Invalid (i.e. free) range  */
+		/*  Invalid (i.e. free) range */
 		*base = 0;
 		*size = 0;
 		*type = 0;
@@ -471,27 +482,31 @@ out_put_cpu:
 }
 
 /**
- * set_fixed_ranges - checks & updates the fixed-range MTRRs if they differ from the saved set
+ * set_fixed_ranges - checks & updates the fixed-range MTRRs if they
+ *		      differ from the saved set
  * @frs: pointer to fixed-range MTRR values, saved by get_fixed_ranges()
  */
-static int set_fixed_ranges(mtrr_type * frs)
+static int set_fixed_ranges(mtrr_type *frs)
 {
-	unsigned long long *saved = (unsigned long long *) frs;
+	unsigned long long *saved = (unsigned long long *)frs;
 	bool changed = false;
-	int block=-1, range;
+	int block = -1, range;
 
 	k8_check_syscfg_dram_mod_en();
 
-	while (fixed_range_blocks[++block].ranges)
-	    for (range=0; range < fixed_range_blocks[block].ranges; range++)
-		set_fixed_range(fixed_range_blocks[block].base_msr + range,
-		    &changed, (unsigned int *) saved++);
+	while (fixed_range_blocks[++block].ranges) {
+		for (range = 0; range < fixed_range_blocks[block].ranges; range++)
+			set_fixed_range(fixed_range_blocks[block].base_msr + range,
+					&changed, (unsigned int *)saved++);
+	}
 
 	return changed;
 }
 
-/*  Set the MSR pair relating to a var range. Returns TRUE if
-    changes are made  */
+/*
+ * Set the MSR pair relating to a var range.
+ * Returns true if changes are made.
+ */
 static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
 {
 	unsigned int lo, hi;
@@ -501,6 +516,7 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
 	if ((vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
 	    || (vr->base_hi & (size_and_mask >> (32 - PAGE_SHIFT))) !=
 		(hi & (size_and_mask >> (32 - PAGE_SHIFT)))) {
+
 		mtrr_wrmsr(MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
 		changed = true;
 	}
@@ -526,21 +542,26 @@ static u32 deftype_lo, deftype_hi;
  */
 static unsigned long set_mtrr_state(void)
 {
-	unsigned int i;
 	unsigned long change_mask = 0;
+	unsigned int i;
 
-	for (i = 0; i < num_var_ranges; i++)
+	for (i = 0; i < num_var_ranges; i++) {
 		if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i]))
 			change_mask |= MTRR_CHANGE_MASK_VARIABLE;
+	}
 
 	if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges))
 		change_mask |= MTRR_CHANGE_MASK_FIXED;
 
-	/*  Set_mtrr_restore restores the old value of MTRRdefType,
-	   so to set it we fiddle with the saved value  */
+	/*
+	 * Set_mtrr_restore restores the old value of MTRRdefType,
+	 * so to set it we fiddle with the saved value:
+	 */
 	if ((deftype_lo & 0xff) != mtrr_state.def_type
 	    || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) {
-		deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | (mtrr_state.enabled << 10);
+
+		deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type |
+			     (mtrr_state.enabled << 10);
 		change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
 	}
 
@@ -548,33 +569,36 @@ static unsigned long set_mtrr_state(void)
 }
 
 
-static unsigned long cr4 = 0;
+static unsigned long cr4;
 static DEFINE_SPINLOCK(set_atomicity_lock);
 
 /*
- * Since we are disabling the cache don't allow any interrupts - they
- * would run extremely slow and would only increase the pain.  The caller must
- * ensure that local interrupts are disabled and are reenabled after post_set()
- * has been called.
+ * Since we are disabling the cache don't allow any interrupts,
+ * they would run extremely slow and would only increase the pain.
+ *
+ * The caller must ensure that local interrupts are disabled and
+ * are reenabled after post_set() has been called.
  */
-
 static void prepare_set(void) __acquires(set_atomicity_lock)
 {
 	unsigned long cr0;
 
-	/*  Note that this is not ideal, since the cache is only flushed/disabled
-	   for this CPU while the MTRRs are changed, but changing this requires
-	   more invasive changes to the way the kernel boots  */
+	/*
+	 * Note that this is not ideal
+	 * since the cache is only flushed/disabled for this CPU while the
+	 * MTRRs are changed, but changing this requires more invasive
+	 * changes to the way the kernel boots
+	 */
 
 	spin_lock(&set_atomicity_lock);
 
-	/*  Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
+	/* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */
 	cr0 = read_cr0() | X86_CR0_CD;
 	write_cr0(cr0);
 	wbinvd();
 
-	/*  Save value of CR4 and clear Page Global Enable (bit 7)  */
-	if ( cpu_has_pge ) {
+	/* Save value of CR4 and clear Page Global Enable (bit 7) */
+	if (cpu_has_pge) {
 		cr4 = read_cr4();
 		write_cr4(cr4 & ~X86_CR4_PGE);
 	}
@@ -582,26 +606,26 @@ static void prepare_set(void) __acquires(set_atomicity_lock)
 	/* Flush all TLBs via a mov %cr3, %reg; mov %reg, %cr3 */
 	__flush_tlb();
 
-	/*  Save MTRR state */
+	/* Save MTRR state */
 	rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
 
-	/*  Disable MTRRs, and set the default type to uncached  */
+	/* Disable MTRRs, and set the default type to uncached */
 	mtrr_wrmsr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi);
 }
 
 static void post_set(void) __releases(set_atomicity_lock)
 {
-	/*  Flush TLBs (no need to flush caches - they are disabled)  */
+	/* Flush TLBs (no need to flush caches - they are disabled) */
 	__flush_tlb();
 
 	/* Intel (P6) standard MTRRs */
 	mtrr_wrmsr(MSR_MTRRdefType, deftype_lo, deftype_hi);
-		
-	/*  Enable caches  */
+
+	/* Enable caches */
 	write_cr0(read_cr0() & 0xbfffffff);
 
-	/*  Restore value of CR4  */
-	if ( cpu_has_pge )
+	/* Restore value of CR4 */
+	if (cpu_has_pge)
 		write_cr4(cr4);
 	spin_unlock(&set_atomicity_lock);
 }
@@ -623,24 +647,27 @@ static void generic_set_all(void)
 	post_set();
 	local_irq_restore(flags);
 
-	/*  Use the atomic bitops to update the global mask  */
+	/* Use the atomic bitops to update the global mask */
 	for (count = 0; count < sizeof mask * 8; ++count) {
 		if (mask & 0x01)
 			set_bit(count, &smp_changes_mask);
 		mask >>= 1;
 	}
-	
+
 }
 
+/**
+ * generic_set_mtrr - set variable MTRR register on the local CPU.
+ *
+ * @reg: The register to set.
+ * @base: The base address of the region.
+ * @size: The size of the region. If this is 0 the region is disabled.
+ * @type: The type of the region.
+ *
+ * Returns nothing.
+ */
 static void generic_set_mtrr(unsigned int reg, unsigned long base,
 			     unsigned long size, mtrr_type type)
-/*  [SUMMARY] Set variable MTRR register on the local CPU.
-    <reg> The register to set.
-    <base> The base address of the region.
-    <size> The size of the region. If this is 0 the region is disabled.
-    <type> The type of the region.
-    [RETURNS] Nothing.
-*/
 {
 	unsigned long flags;
 	struct mtrr_var_range *vr;
@@ -651,8 +678,10 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
 	prepare_set();
 
 	if (size == 0) {
-		/* The invalid bit is kept in the mask, so we simply clear the
-		   relevant mask register to disable a range. */
+		/*
+		 * The invalid bit is kept in the mask, so we simply
+		 * clear the relevant mask register to disable a range.
+		 */
 		mtrr_wrmsr(MTRRphysMask_MSR(reg), 0, 0);
 		memset(vr, 0, sizeof(struct mtrr_var_range));
 	} else {
@@ -669,46 +698,50 @@ static void generic_set_mtrr(unsigned int reg, unsigned long base,
 	local_irq_restore(flags);
 }
 
-int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type)
+int generic_validate_add_page(unsigned long base, unsigned long size,
+			      unsigned int type)
 {
 	unsigned long lbase, last;
 
-	/*  For Intel PPro stepping <= 7, must be 4 MiB aligned 
-	    and not touch 0x70000000->0x7003FFFF */
+	/*
+	 * For Intel PPro stepping <= 7
+	 * must be 4 MiB aligned and not touch 0x70000000 -> 0x7003FFFF
+	 */
 	if (is_cpu(INTEL) && boot_cpu_data.x86 == 6 &&
 	    boot_cpu_data.x86_model == 1 &&
 	    boot_cpu_data.x86_mask <= 7) {
 		if (base & ((1 << (22 - PAGE_SHIFT)) - 1)) {
-			printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
+			pr_warning("mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
 			return -EINVAL;
 		}
 		if (!(base + size < 0x70000 || base > 0x7003F) &&
 		    (type == MTRR_TYPE_WRCOMB
 		     || type == MTRR_TYPE_WRBACK)) {
-			printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
+			pr_warning("mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
 			return -EINVAL;
 		}
 	}
 
-	/*  Check upper bits of base and last are equal and lower bits are 0
-	    for base and 1 for last  */
+	/*
+	 * Check upper bits of base and last are equal and lower bits are 0
+	 * for base and 1 for last
+	 */
 	last = base + size - 1;
 	for (lbase = base; !(lbase & 1) && (last & 1);
-	     lbase = lbase >> 1, last = last >> 1) ;
+	     lbase = lbase >> 1, last = last >> 1)
+		;
 	if (lbase != last) {
-		printk(KERN_WARNING "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
-		       base, size);
+		pr_warning("mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n", base, size);
 		return -EINVAL;
 	}
 	return 0;
 }
 
-
 static int generic_have_wrcomb(void)
 {
 	unsigned long config, dummy;
 	rdmsr(MSR_MTRRcap, config, dummy);
-	return (config & (1 << 10));
+	return config & (1 << 10);
 }
 
 int positive_have_wrcomb(void)
@@ -716,14 +749,15 @@ int positive_have_wrcomb(void)
 	return 1;
 }
 
-/* generic structure...
+/*
+ * Generic structure...
  */
 struct mtrr_ops generic_mtrr_ops = {
-	.use_intel_if      = 1,
-	.set_all	   = generic_set_all,
-	.get               = generic_get_mtrr,
-	.get_free_region   = generic_get_free_region,
-	.set               = generic_set_mtrr,
-	.validate_add_page = generic_validate_add_page,
-	.have_wrcomb       = generic_have_wrcomb,
+	.use_intel_if		= 1,
+	.set_all		= generic_set_all,
+	.get			= generic_get_mtrr,
+	.get_free_region	= generic_get_free_region,
+	.set			= generic_set_mtrr,
+	.validate_add_page	= generic_validate_add_page,
+	.have_wrcomb		= generic_have_wrcomb,
 };
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index fb73a52..f04e725 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -1,27 +1,28 @@
-#include <linux/init.h>
-#include <linux/proc_fs.h>
 #include <linux/capability.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
 #include <linux/seq_file.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
 
 #define LINE_SIZE 80
 
 #include <asm/mtrr.h>
+
 #include "mtrr.h"
 
 #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private)
 
 static const char *const mtrr_strings[MTRR_NUM_TYPES] =
 {
-    "uncachable",               /* 0 */
-    "write-combining",          /* 1 */
-    "?",                        /* 2 */
-    "?",                        /* 3 */
-    "write-through",            /* 4 */
-    "write-protect",            /* 5 */
-    "write-back",               /* 6 */
+	"uncachable",		/* 0 */
+	"write-combining",	/* 1 */
+	"?",			/* 2 */
+	"?",			/* 3 */
+	"write-through",	/* 4 */
+	"write-protect",	/* 5 */
+	"write-back",		/* 6 */
 };
 
 const char *mtrr_attrib_to_str(int x)
@@ -35,8 +36,8 @@ static int
 mtrr_file_add(unsigned long base, unsigned long size,
 	      unsigned int type, bool increment, struct file *file, int page)
 {
+	unsigned int *fcount = FILE_FCOUNT(file);
 	int reg, max;
-	unsigned int *fcount = FILE_FCOUNT(file); 
 
 	max = num_var_ranges;
 	if (fcount == NULL) {
@@ -61,8 +62,8 @@ static int
 mtrr_file_del(unsigned long base, unsigned long size,
 	      struct file *file, int page)
 {
-	int reg;
 	unsigned int *fcount = FILE_FCOUNT(file);
+	int reg;
 
 	if (!page) {
 		if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)))
@@ -81,13 +82,14 @@ mtrr_file_del(unsigned long base, unsigned long size,
 	return reg;
 }
 
-/* RED-PEN: seq_file can seek now. this is ignored. */
+/*
+ * seq_file can seek but we ignore it.
+ *
+ * Format of control line:
+ *    "base=%Lx size=%Lx type=%s" or "disable=%d"
+ */
 static ssize_t
 mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
-/*  Format of control line:
-    "base=%Lx size=%Lx type=%s"     OR:
-    "disable=%d"
-*/
 {
 	int i, err;
 	unsigned long reg;
@@ -100,15 +102,18 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
 		return -EPERM;
 	if (!len)
 		return -EINVAL;
+
 	memset(line, 0, LINE_SIZE);
 	if (len > LINE_SIZE)
 		len = LINE_SIZE;
 	if (copy_from_user(line, buf, len - 1))
 		return -EFAULT;
+
 	linelen = strlen(line);
 	ptr = line + linelen - 1;
 	if (linelen && *ptr == '\n')
 		*ptr = '\0';
+
 	if (!strncmp(line, "disable=", 8)) {
 		reg = simple_strtoul(line + 8, &ptr, 0);
 		err = mtrr_del_page(reg, 0, 0);
@@ -116,28 +121,35 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
 			return err;
 		return len;
 	}
+
 	if (strncmp(line, "base=", 5))
 		return -EINVAL;
+
 	base = simple_strtoull(line + 5, &ptr, 0);
-	for (; isspace(*ptr); ++ptr) ;
+	while (isspace(*ptr))
+		ptr++;
+
 	if (strncmp(ptr, "size=", 5))
 		return -EINVAL;
+
 	size = simple_strtoull(ptr + 5, &ptr, 0);
 	if ((base & 0xfff) || (size & 0xfff))
 		return -EINVAL;
-	for (; isspace(*ptr); ++ptr) ;
+	while (isspace(*ptr))
+		ptr++;
+
 	if (strncmp(ptr, "type=", 5))
 		return -EINVAL;
 	ptr += 5;
-	for (; isspace(*ptr); ++ptr) ;
+	while (isspace(*ptr))
+		ptr++;
+
 	for (i = 0; i < MTRR_NUM_TYPES; ++i) {
 		if (strcmp(ptr, mtrr_strings[i]))
 			continue;
 		base >>= PAGE_SHIFT;
 		size >>= PAGE_SHIFT;
-		err =
-		    mtrr_add_page((unsigned long) base, (unsigned long) size, i,
-				  true);
+		err = mtrr_add_page((unsigned long)base, (unsigned long)size, i, true);
 		if (err < 0)
 			return err;
 		return len;
@@ -181,7 +193,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
 	case MTRRIOC32_SET_PAGE_ENTRY:
 	case MTRRIOC32_DEL_PAGE_ENTRY:
 	case MTRRIOC32_KILL_PAGE_ENTRY: {
-		struct mtrr_sentry32 __user *s32 = (struct mtrr_sentry32 __user *)__arg;
+		struct mtrr_sentry32 __user *s32;
+
+		s32 = (struct mtrr_sentry32 __user *)__arg;
 		err = get_user(sentry.base, &s32->base);
 		err |= get_user(sentry.size, &s32->size);
 		err |= get_user(sentry.type, &s32->type);
@@ -191,7 +205,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
 	}
 	case MTRRIOC32_GET_ENTRY:
 	case MTRRIOC32_GET_PAGE_ENTRY: {
-		struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+		struct mtrr_gentry32 __user *g32;
+
+		g32 = (struct mtrr_gentry32 __user *)__arg;
 		err = get_user(gentry.regnum, &g32->regnum);
 		err |= get_user(gentry.base, &g32->base);
 		err |= get_user(gentry.size, &g32->size);
@@ -314,7 +330,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
 	if (err)
 		return err;
 
-	switch(cmd) {
+	switch (cmd) {
 	case MTRRIOC_GET_ENTRY:
 	case MTRRIOC_GET_PAGE_ENTRY:
 		if (copy_to_user(arg, &gentry, sizeof gentry))
@@ -323,7 +339,9 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
 #ifdef CONFIG_COMPAT
 	case MTRRIOC32_GET_ENTRY:
 	case MTRRIOC32_GET_PAGE_ENTRY: {
-		struct mtrr_gentry32 __user *g32 = (struct mtrr_gentry32 __user *)__arg;
+		struct mtrr_gentry32 __user *g32;
+
+		g32 = (struct mtrr_gentry32 __user *)__arg;
 		err = put_user(gentry.base, &g32->base);
 		err |= put_user(gentry.size, &g32->size);
 		err |= put_user(gentry.regnum, &g32->regnum);
@@ -335,11 +353,10 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg)
 	return err;
 }
 
-static int
-mtrr_close(struct inode *ino, struct file *file)
+static int mtrr_close(struct inode *ino, struct file *file)
 {
-	int i, max;
 	unsigned int *fcount = FILE_FCOUNT(file);
+	int i, max;
 
 	if (fcount != NULL) {
 		max = num_var_ranges;
@@ -359,22 +376,22 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset);
 
 static int mtrr_open(struct inode *inode, struct file *file)
 {
-	if (!mtrr_if) 
+	if (!mtrr_if)
 		return -EIO;
-	if (!mtrr_if->get) 
-		return -ENXIO; 
+	if (!mtrr_if->get)
+		return -ENXIO;
 	return single_open(file, mtrr_seq_show, NULL);
 }
 
 static const struct file_operations mtrr_fops = {
-	.owner   = THIS_MODULE,
-	.open	 = mtrr_open, 
-	.read    = seq_read,
-	.llseek  = seq_lseek,
-	.write   = mtrr_write,
-	.unlocked_ioctl = mtrr_ioctl,
-	.compat_ioctl = mtrr_ioctl,
-	.release = mtrr_close,
+	.owner			= THIS_MODULE,
+	.open			= mtrr_open,
+	.read			= seq_read,
+	.llseek			= seq_lseek,
+	.write			= mtrr_write,
+	.unlocked_ioctl		= mtrr_ioctl,
+	.compat_ioctl		= mtrr_ioctl,
+	.release		= mtrr_close,
 };
 
 static int mtrr_seq_show(struct seq_file *seq, void *offset)
@@ -388,23 +405,24 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset)
 	max = num_var_ranges;
 	for (i = 0; i < max; i++) {
 		mtrr_if->get(i, &base, &size, &type);
-		if (size == 0)
+		if (size == 0) {
 			mtrr_usage_table[i] = 0;
-		else {
-			if (size < (0x100000 >> PAGE_SHIFT)) {
-				/* less than 1MB */
-				factor = 'K';
-				size <<= PAGE_SHIFT - 10;
-			} else {
-				factor = 'M';
-				size >>= 20 - PAGE_SHIFT;
-			}
-			/* RED-PEN: base can be > 32bit */ 
-			len += seq_printf(seq, 
-				   "reg%02i: base=0x%06lx000 (%5luMB), size=%5lu%cB, count=%d: %s\n",
-			     i, base, base >> (20 - PAGE_SHIFT), size, factor,
-			     mtrr_usage_table[i], mtrr_attrib_to_str(type));
+			continue;
 		}
+		if (size < (0x100000 >> PAGE_SHIFT)) {
+			/* less than 1MB */
+			factor = 'K';
+			size <<= PAGE_SHIFT - 10;
+		} else {
+			factor = 'M';
+			size >>= 20 - PAGE_SHIFT;
+		}
+		/* Base can be > 32bit */
+		len += seq_printf(seq, "reg%02i: base=0x%06lx000 "
+			"(%5luMB), size=%5lu%cB, count=%d: %s\n",
+			i, base, base >> (20 - PAGE_SHIFT), size,
+			factor, mtrr_usage_table[i],
+			mtrr_attrib_to_str(type));
 	}
 	return 0;
 }
@@ -422,6 +440,5 @@ static int __init mtrr_if_init(void)
 	proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops);
 	return 0;
 }
-
 arch_initcall(mtrr_if_init);
 #endif			/*  CONFIG_PROC_FS  */
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 8fc248b..84e83de 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -25,43 +25,49 @@
     Operating System Writer's Guide" (Intel document number 242692),
     section 11.11.7
 
-    This was cleaned and made readable by Patrick Mochel <mochel@osdl.org> 
-    on 6-7 March 2002. 
-    Source: Intel Architecture Software Developers Manual, Volume 3: 
+    This was cleaned and made readable by Patrick Mochel <mochel@osdl.org>
+    on 6-7 March 2002.
+    Source: Intel Architecture Software Developers Manual, Volume 3:
     System Programming Guide; Section 9.11. (1997 edition - PPro).
 */
 
+#define DEBUG
+
+#include <linux/types.h> /* FIXME: kvm_para.h needs this */
+
+#include <linux/kvm_para.h>
+#include <linux/uaccess.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/init.h>
+#include <linux/sort.h>
+#include <linux/cpu.h>
 #include <linux/pci.h>
 #include <linux/smp.h>
-#include <linux/cpu.h>
-#include <linux/mutex.h>
-#include <linux/sort.h>
 
+#include <asm/processor.h>
 #include <asm/e820.h>
 #include <asm/mtrr.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
 #include <asm/msr.h>
-#include <asm/kvm_para.h>
+
 #include "mtrr.h"
 
-u32 num_var_ranges = 0;
+u32 num_var_ranges;
 
 unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
 static DEFINE_MUTEX(mtrr_mutex);
 
 u64 size_or_mask, size_and_mask;
+static bool mtrr_aps_delayed_init;
 
-static struct mtrr_ops * mtrr_ops[X86_VENDOR_NUM] = {};
+static struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM];
 
-struct mtrr_ops * mtrr_if = NULL;
+struct mtrr_ops *mtrr_if;
 
 static void set_mtrr(unsigned int reg, unsigned long base,
 		     unsigned long size, mtrr_type type);
 
-void set_mtrr_ops(struct mtrr_ops * ops)
+void set_mtrr_ops(struct mtrr_ops *ops)
 {
 	if (ops->vendor && ops->vendor < X86_VENDOR_NUM)
 		mtrr_ops[ops->vendor] = ops;
@@ -72,30 +78,36 @@ static int have_wrcomb(void)
 {
 	struct pci_dev *dev;
 	u8 rev;
-	
-	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
-		/* ServerWorks LE chipsets < rev 6 have problems with write-combining
-		   Don't allow it and leave room for other chipsets to be tagged */
+
+	dev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, NULL);
+	if (dev != NULL) {
+		/*
+		 * ServerWorks LE chipsets < rev 6 have problems with
+		 * write-combining. Don't allow it and leave room for other
+		 * chipsets to be tagged
+		 */
 		if (dev->vendor == PCI_VENDOR_ID_SERVERWORKS &&
 		    dev->device == PCI_DEVICE_ID_SERVERWORKS_LE) {
 			pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev);
 			if (rev <= 5) {
-				printk(KERN_INFO "mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
+				pr_info("mtrr: Serverworks LE rev < 6 detected. Write-combining disabled.\n");
 				pci_dev_put(dev);
 				return 0;
 			}
 		}
-		/* Intel 450NX errata # 23. Non ascending cacheline evictions to
-		   write combining memory may resulting in data corruption */
+		/*
+		 * Intel 450NX errata # 23. Non ascending cacheline evictions to
+		 * write combining memory may resulting in data corruption
+		 */
 		if (dev->vendor == PCI_VENDOR_ID_INTEL &&
 		    dev->device == PCI_DEVICE_ID_INTEL_82451NX) {
-			printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
+			pr_info("mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
 			pci_dev_put(dev);
 			return 0;
 		}
 		pci_dev_put(dev);
-	}		
-	return (mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0);
+	}
+	return mtrr_if->have_wrcomb ? mtrr_if->have_wrcomb() : 0;
 }
 
 /*  This function returns the number of variable MTRRs  */
@@ -103,12 +115,13 @@ static void __init set_num_var_ranges(void)
 {
 	unsigned long config = 0, dummy;
 
-	if (use_intel()) {
+	if (use_intel())
 		rdmsr(MSR_MTRRcap, config, dummy);
-	} else if (is_cpu(AMD))
+	else if (is_cpu(AMD))
 		config = 2;
 	else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
 		config = 8;
+
 	num_var_ranges = config & 0xff;
 }
 
@@ -130,10 +143,12 @@ struct set_mtrr_data {
 	mtrr_type	smp_type;
 };
 
+/**
+ * ipi_handler - Synchronisation handler. Executed by "other" CPUs.
+ *
+ * Returns nothing.
+ */
 static void ipi_handler(void *info)
-/*  [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
-    [RETURNS] Nothing.
-*/
 {
 #ifdef CONFIG_SMP
 	struct set_mtrr_data *data = info;
@@ -142,18 +157,22 @@ static void ipi_handler(void *info)
 	local_irq_save(flags);
 
 	atomic_dec(&data->count);
-	while(!atomic_read(&data->gate))
+	while (!atomic_read(&data->gate))
 		cpu_relax();
 
 	/*  The master has cleared me to execute  */
-	if (data->smp_reg != ~0U) 
-		mtrr_if->set(data->smp_reg, data->smp_base, 
+	if (data->smp_reg != ~0U) {
+		mtrr_if->set(data->smp_reg, data->smp_base,
 			     data->smp_size, data->smp_type);
-	else
+	} else if (mtrr_aps_delayed_init) {
+		/*
+		 * Initialize the MTRRs inaddition to the synchronisation.
+		 */
 		mtrr_if->set_all();
+	}
 
 	atomic_dec(&data->count);
-	while(atomic_read(&data->gate))
+	while (atomic_read(&data->gate))
 		cpu_relax();
 
 	atomic_dec(&data->count);
@@ -161,7 +180,8 @@ static void ipi_handler(void *info)
 #endif
 }
 
-static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
+static inline int types_compatible(mtrr_type type1, mtrr_type type2)
+{
 	return type1 == MTRR_TYPE_UNCACHABLE ||
 	       type2 == MTRR_TYPE_UNCACHABLE ||
 	       (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) ||
@@ -176,10 +196,10 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
  * @type:	mtrr type
  *
  * This is kinda tricky, but fortunately, Intel spelled it out for us cleanly:
- * 
+ *
  * 1. Send IPI to do the following:
  * 2. Disable Interrupts
- * 3. Wait for all procs to do so 
+ * 3. Wait for all procs to do so
  * 4. Enter no-fill cache mode
  * 5. Flush caches
  * 6. Clear PGE bit
@@ -189,26 +209,27 @@ static inline int types_compatible(mtrr_type type1, mtrr_type type2) {
  * 10. Enable all range registers
  * 11. Flush all TLBs and caches again
  * 12. Enter normal cache mode and reenable caching
- * 13. Set PGE 
+ * 13. Set PGE
  * 14. Wait for buddies to catch up
  * 15. Enable interrupts.
- * 
+ *
  * What does that mean for us? Well, first we set data.count to the number
  * of CPUs. As each CPU disables interrupts, it'll decrement it once. We wait
  * until it hits 0 and proceed. We set the data.gate flag and reset data.count.
- * Meanwhile, they are waiting for that flag to be set. Once it's set, each 
- * CPU goes through the transition of updating MTRRs. The CPU vendors may each do it 
- * differently, so we call mtrr_if->set() callback and let them take care of it.
- * When they're done, they again decrement data->count and wait for data.gate to 
- * be reset. 
- * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag.
+ * Meanwhile, they are waiting for that flag to be set. Once it's set, each
+ * CPU goes through the transition of updating MTRRs.
+ * The CPU vendors may each do it differently,
+ * so we call mtrr_if->set() callback and let them take care of it.
+ * When they're done, they again decrement data->count and wait for data.gate
+ * to be reset.
+ * When we finish, we wait for data.count to hit 0 and toggle the data.gate flag
  * Everyone then enables interrupts and we all continue on.
  *
  * Note that the mechanism is the same for UP systems, too; all the SMP stuff
  * becomes nops.
  */
-static void set_mtrr(unsigned int reg, unsigned long base,
-		     unsigned long size, mtrr_type type)
+static void
+set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type)
 {
 	struct set_mtrr_data data;
 	unsigned long flags;
@@ -218,121 +239,124 @@ static void set_mtrr(unsigned int reg, unsigned long base,
 	data.smp_size = size;
 	data.smp_type = type;
 	atomic_set(&data.count, num_booting_cpus() - 1);
-	/* make sure data.count is visible before unleashing other CPUs */
+
+	/* Make sure data.count is visible before unleashing other CPUs */
 	smp_wmb();
-	atomic_set(&data.gate,0);
+	atomic_set(&data.gate, 0);
 
-	/*  Start the ball rolling on other CPUs  */
+	/* Start the ball rolling on other CPUs */
 	if (smp_call_function(ipi_handler, &data, 0) != 0)
 		panic("mtrr: timed out waiting for other CPUs\n");
 
 	local_irq_save(flags);
 
-	while(atomic_read(&data.count))
+	while (atomic_read(&data.count))
 		cpu_relax();
 
-	/* ok, reset count and toggle gate */
+	/* Ok, reset count and toggle gate */
 	atomic_set(&data.count, num_booting_cpus() - 1);
 	smp_wmb();
-	atomic_set(&data.gate,1);
+	atomic_set(&data.gate, 1);
 
-	/* do our MTRR business */
+	/* Do our MTRR business */
 
-	/* HACK!
+	/*
+	 * HACK!
 	 * We use this same function to initialize the mtrrs on boot.
 	 * The state of the boot cpu's mtrrs has been saved, and we want
-	 * to replicate across all the APs. 
+	 * to replicate across all the APs.
 	 * If we're doing that @reg is set to something special...
 	 */
-	if (reg != ~0U) 
-		mtrr_if->set(reg,base,size,type);
+	if (reg != ~0U)
+		mtrr_if->set(reg, base, size, type);
+	else if (!mtrr_aps_delayed_init)
+		mtrr_if->set_all();
 
-	/* wait for the others */
-	while(atomic_read(&data.count))
+	/* Wait for the others */
+	while (atomic_read(&data.count))
 		cpu_relax();
 
 	atomic_set(&data.count, num_booting_cpus() - 1);
 	smp_wmb();
-	atomic_set(&data.gate,0);
+	atomic_set(&data.gate, 0);
 
 	/*
 	 * Wait here for everyone to have seen the gate change
 	 * So we're the last ones to touch 'data'
 	 */
-	while(atomic_read(&data.count))
+	while (atomic_read(&data.count))
 		cpu_relax();
 
 	local_irq_restore(flags);
 }
 
 /**
- *	mtrr_add_page - Add a memory type region
- *	@base: Physical base address of region in pages (in units of 4 kB!)
- *	@size: Physical size of region in pages (4 kB)
- *	@type: Type of MTRR desired
- *	@increment: If this is true do usage counting on the region
+ * mtrr_add_page - Add a memory type region
+ * @base: Physical base address of region in pages (in units of 4 kB!)
+ * @size: Physical size of region in pages (4 kB)
+ * @type: Type of MTRR desired
+ * @increment: If this is true do usage counting on the region
  *
- *	Memory type region registers control the caching on newer Intel and
- *	non Intel processors. This function allows drivers to request an
- *	MTRR is added. The details and hardware specifics of each processor's
- *	implementation are hidden from the caller, but nevertheless the 
- *	caller should expect to need to provide a power of two size on an
- *	equivalent power of two boundary.
+ * Memory type region registers control the caching on newer Intel and
+ * non Intel processors. This function allows drivers to request an
+ * MTRR is added. The details and hardware specifics of each processor's
+ * implementation are hidden from the caller, but nevertheless the
+ * caller should expect to need to provide a power of two size on an
+ * equivalent power of two boundary.
  *
- *	If the region cannot be added either because all regions are in use
- *	or the CPU cannot support it a negative value is returned. On success
- *	the register number for this entry is returned, but should be treated
- *	as a cookie only.
+ * If the region cannot be added either because all regions are in use
+ * or the CPU cannot support it a negative value is returned. On success
+ * the register number for this entry is returned, but should be treated
+ * as a cookie only.
  *
- *	On a multiprocessor machine the changes are made to all processors.
- *	This is required on x86 by the Intel processors.
+ * On a multiprocessor machine the changes are made to all processors.
+ * This is required on x86 by the Intel processors.
  *
- *	The available types are
+ * The available types are
  *
- *	%MTRR_TYPE_UNCACHABLE	-	No caching
+ * %MTRR_TYPE_UNCACHABLE - No caching
  *
- *	%MTRR_TYPE_WRBACK	-	Write data back in bursts whenever
+ * %MTRR_TYPE_WRBACK - Write data back in bursts whenever
  *
- *	%MTRR_TYPE_WRCOMB	-	Write data back soon but allow bursts
+ * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
  *
- *	%MTRR_TYPE_WRTHROUGH	-	Cache reads but not writes
+ * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
  *
- *	BUGS: Needs a quiet flag for the cases where drivers do not mind
- *	failures and do not wish system log messages to be sent.
+ * BUGS: Needs a quiet flag for the cases where drivers do not mind
+ * failures and do not wish system log messages to be sent.
  */
-
-int mtrr_add_page(unsigned long base, unsigned long size, 
+int mtrr_add_page(unsigned long base, unsigned long size,
 		  unsigned int type, bool increment)
 {
+	unsigned long lbase, lsize;
 	int i, replace, error;
 	mtrr_type ltype;
-	unsigned long lbase, lsize;
 
 	if (!mtrr_if)
 		return -ENXIO;
-		
-	if ((error = mtrr_if->validate_add_page(base,size,type)))
+
+	error = mtrr_if->validate_add_page(base, size, type);
+	if (error)
 		return error;
 
 	if (type >= MTRR_NUM_TYPES) {
-		printk(KERN_WARNING "mtrr: type: %u invalid\n", type);
+		pr_warning("mtrr: type: %u invalid\n", type);
 		return -EINVAL;
 	}
 
-	/*  If the type is WC, check that this processor supports it  */
+	/* If the type is WC, check that this processor supports it */
 	if ((type == MTRR_TYPE_WRCOMB) && !have_wrcomb()) {
-		printk(KERN_WARNING
-		       "mtrr: your processor doesn't support write-combining\n");
+		pr_warning("mtrr: your processor doesn't support write-combining\n");
 		return -ENOSYS;
 	}
 
 	if (!size) {
-		printk(KERN_WARNING "mtrr: zero sized request\n");
+		pr_warning("mtrr: zero sized request\n");
 		return -EINVAL;
 	}
 
 	if (base & size_or_mask || size & size_or_mask) {
-		printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n");
+		pr_warning("mtrr: base or size exceeds the MTRR width\n");
 		return -EINVAL;
 	}
 
@@ -341,36 +365,40 @@ int mtrr_add_page(unsigned long base, unsigned long size,
 
 	/* No CPU hotplug when we change MTRR entries */
 	get_online_cpus();
-	/*  Search for existing MTRR  */
+
+	/* Search for existing MTRR  */
 	mutex_lock(&mtrr_mutex);
 	for (i = 0; i < num_var_ranges; ++i) {
 		mtrr_if->get(i, &lbase, &lsize, &ltype);
-		if (!lsize || base > lbase + lsize - 1 || base + size - 1 < lbase)
+		if (!lsize || base > lbase + lsize - 1 ||
+		    base + size - 1 < lbase)
 			continue;
-		/*  At this point we know there is some kind of overlap/enclosure  */
+		/*
+		 * At this point we know there is some kind of
+		 * overlap/enclosure
+		 */
 		if (base < lbase || base + size - 1 > lbase + lsize - 1) {
-			if (base <= lbase && base + size - 1 >= lbase + lsize - 1) {
+			if (base <= lbase &&
+			    base + size - 1 >= lbase + lsize - 1) {
 				/*  New region encloses an existing region  */
 				if (type == ltype) {
 					replace = replace == -1 ? i : -2;
 					continue;
-				}
-				else if (types_compatible(type, ltype))
+				} else if (types_compatible(type, ltype))
 					continue;
 			}
-			printk(KERN_WARNING
-			       "mtrr: 0x%lx000,0x%lx000 overlaps existing"
-			       " 0x%lx000,0x%lx000\n", base, size, lbase,
-			       lsize);
+			pr_warning("mtrr: 0x%lx000,0x%lx000 overlaps existing"
+				" 0x%lx000,0x%lx000\n", base, size, lbase,
+				lsize);
 			goto out;
 		}
-		/*  New region is enclosed by an existing region  */
+		/* New region is enclosed by an existing region */
 		if (ltype != type) {
 			if (types_compatible(type, ltype))
 				continue;
-			printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
-			     base, size, mtrr_attrib_to_str(ltype),
-			     mtrr_attrib_to_str(type));
+			pr_warning("mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
+				base, size, mtrr_attrib_to_str(ltype),
+				mtrr_attrib_to_str(type));
 			goto out;
 		}
 		if (increment)
@@ -378,7 +406,7 @@ int mtrr_add_page(unsigned long base, unsigned long size,
 		error = i;
 		goto out;
 	}
-	/*  Search for an empty MTRR  */
+	/* Search for an empty MTRR */
 	i = mtrr_if->get_free_region(base, size, replace);
 	if (i >= 0) {
 		set_mtrr(i, base, size, type);
@@ -393,8 +421,9 @@ int mtrr_add_page(unsigned long base, unsigned long size,
 				mtrr_usage_table[replace] = 0;
 			}
 		}
-	} else
-		printk(KERN_INFO "mtrr: no more MTRRs available\n");
+	} else {
+		pr_info("mtrr: no more MTRRs available\n");
+	}
 	error = i;
  out:
 	mutex_unlock(&mtrr_mutex);
@@ -405,10 +434,8 @@ int mtrr_add_page(unsigned long base, unsigned long size,
 static int mtrr_check(unsigned long base, unsigned long size)
 {
 	if ((base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1))) {
-		printk(KERN_WARNING
-			"mtrr: size and base must be multiples of 4 kiB\n");
-		printk(KERN_DEBUG
-			"mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
+		pr_warning("mtrr: size and base must be multiples of 4 kiB\n");
+		pr_debug("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
 		dump_stack();
 		return -1;
 	}
@@ -416,66 +443,64 @@ static int mtrr_check(unsigned long base, unsigned long size)
 }
 
 /**
- *	mtrr_add - Add a memory type region
- *	@base: Physical base address of region
- *	@size: Physical size of region
- *	@type: Type of MTRR desired
- *	@increment: If this is true do usage counting on the region
+ * mtrr_add - Add a memory type region
+ * @base: Physical base address of region
+ * @size: Physical size of region
+ * @type: Type of MTRR desired
+ * @increment: If this is true do usage counting on the region
  *
- *	Memory type region registers control the caching on newer Intel and
- *	non Intel processors. This function allows drivers to request an
- *	MTRR is added. The details and hardware specifics of each processor's
- *	implementation are hidden from the caller, but nevertheless the 
- *	caller should expect to need to provide a power of two size on an
- *	equivalent power of two boundary.
+ * Memory type region registers control the caching on newer Intel and
+ * non Intel processors. This function allows drivers to request an
+ * MTRR is added. The details and hardware specifics of each processor's
+ * implementation are hidden from the caller, but nevertheless the
+ * caller should expect to need to provide a power of two size on an
+ * equivalent power of two boundary.
  *
- *	If the region cannot be added either because all regions are in use
- *	or the CPU cannot support it a negative value is returned. On success
- *	the register number for this entry is returned, but should be treated
- *	as a cookie only.
+ * If the region cannot be added either because all regions are in use
+ * or the CPU cannot support it a negative value is returned. On success
+ * the register number for this entry is returned, but should be treated
+ * as a cookie only.
  *
- *	On a multiprocessor machine the changes are made to all processors.
- *	This is required on x86 by the Intel processors.
+ * On a multiprocessor machine the changes are made to all processors.
+ * This is required on x86 by the Intel processors.
  *
- *	The available types are
+ * The available types are
  *
- *	%MTRR_TYPE_UNCACHABLE	-	No caching
+ * %MTRR_TYPE_UNCACHABLE - No caching
  *
- *	%MTRR_TYPE_WRBACK	-	Write data back in bursts whenever
+ * %MTRR_TYPE_WRBACK - Write data back in bursts whenever
  *
- *	%MTRR_TYPE_WRCOMB	-	Write data back soon but allow bursts
+ * %MTRR_TYPE_WRCOMB - Write data back soon but allow bursts
  *
- *	%MTRR_TYPE_WRTHROUGH	-	Cache reads but not writes
+ * %MTRR_TYPE_WRTHROUGH - Cache reads but not writes
  *
- *	BUGS: Needs a quiet flag for the cases where drivers do not mind
- *	failures and do not wish system log messages to be sent.
+ * BUGS: Needs a quiet flag for the cases where drivers do not mind
+ * failures and do not wish system log messages to be sent.
  */
-
-int
-mtrr_add(unsigned long base, unsigned long size, unsigned int type,
-	 bool increment)
+int mtrr_add(unsigned long base, unsigned long size, unsigned int type,
+	     bool increment)
 {
 	if (mtrr_check(base, size))
 		return -EINVAL;
 	return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type,
 			     increment);
 }
+EXPORT_SYMBOL(mtrr_add);
 
 /**
- *	mtrr_del_page - delete a memory type region
- *	@reg: Register returned by mtrr_add
- *	@base: Physical base address
- *	@size: Size of region
+ * mtrr_del_page - delete a memory type region
+ * @reg: Register returned by mtrr_add
+ * @base: Physical base address
+ * @size: Size of region
  *
- *	If register is supplied then base and size are ignored. This is
- *	how drivers should call it.
+ * If register is supplied then base and size are ignored. This is
+ * how drivers should call it.
  *
- *	Releases an MTRR region. If the usage count drops to zero the 
- *	register is freed and the region returns to default state.
- *	On success the register is returned, on failure a negative error
- *	code.
+ * Releases an MTRR region. If the usage count drops to zero the
+ * register is freed and the region returns to default state.
+ * On success the register is returned, on failure a negative error
+ * code.
  */
-
 int mtrr_del_page(int reg, unsigned long base, unsigned long size)
 {
 	int i, max;
@@ -500,22 +525,22 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
 			}
 		}
 		if (reg < 0) {
-			printk(KERN_DEBUG "mtrr: no MTRR for %lx000,%lx000 found\n", base,
-			       size);
+			pr_debug("mtrr: no MTRR for %lx000,%lx000 found\n",
+				 base, size);
 			goto out;
 		}
 	}
 	if (reg >= max) {
-		printk(KERN_WARNING "mtrr: register: %d too big\n", reg);
+		pr_warning("mtrr: register: %d too big\n", reg);
 		goto out;
 	}
 	mtrr_if->get(reg, &lbase, &lsize, &ltype);
 	if (lsize < 1) {
-		printk(KERN_WARNING "mtrr: MTRR %d not used\n", reg);
+		pr_warning("mtrr: MTRR %d not used\n", reg);
 		goto out;
 	}
 	if (mtrr_usage_table[reg] < 1) {
-		printk(KERN_WARNING "mtrr: reg: %d has count=0\n", reg);
+		pr_warning("mtrr: reg: %d has count=0\n", reg);
 		goto out;
 	}
 	if (--mtrr_usage_table[reg] < 1)
@@ -526,33 +551,31 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
 	put_online_cpus();
 	return error;
 }
+
 /**
- *	mtrr_del - delete a memory type region
- *	@reg: Register returned by mtrr_add
- *	@base: Physical base address
- *	@size: Size of region
+ * mtrr_del - delete a memory type region
+ * @reg: Register returned by mtrr_add
+ * @base: Physical base address
+ * @size: Size of region
  *
- *	If register is supplied then base and size are ignored. This is
- *	how drivers should call it.
+ * If register is supplied then base and size are ignored. This is
+ * how drivers should call it.
  *
- *	Releases an MTRR region. If the usage count drops to zero the 
- *	register is freed and the region returns to default state.
- *	On success the register is returned, on failure a negative error
- *	code.
+ * Releases an MTRR region. If the usage count drops to zero the
+ * register is freed and the region returns to default state.
+ * On success the register is returned, on failure a negative error
+ * code.
  */
-
-int
-mtrr_del(int reg, unsigned long base, unsigned long size)
+int mtrr_del(int reg, unsigned long base, unsigned long size)
 {
 	if (mtrr_check(base, size))
 		return -EINVAL;
 	return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
 }
-
-EXPORT_SYMBOL(mtrr_add);
 EXPORT_SYMBOL(mtrr_del);
 
-/* HACK ALERT!
+/*
+ * HACK ALERT!
  * These should be called implicitly, but we can't yet until all the initcall
  * stuff is done...
  */
@@ -576,29 +599,28 @@ struct mtrr_value {
 
 static struct mtrr_value mtrr_value[MTRR_MAX_VAR_RANGES];
 
-static int mtrr_save(struct sys_device * sysdev, pm_message_t state)
+static int mtrr_save(struct sys_device *sysdev, pm_message_t state)
 {
 	int i;
 
 	for (i = 0; i < num_var_ranges; i++) {
-		mtrr_if->get(i,
-			     &mtrr_value[i].lbase,
-			     &mtrr_value[i].lsize,
-			     &mtrr_value[i].ltype);
+		mtrr_if->get(i, &mtrr_value[i].lbase,
+				&mtrr_value[i].lsize,
+				&mtrr_value[i].ltype);
 	}
 	return 0;
 }
 
-static int mtrr_restore(struct sys_device * sysdev)
+static int mtrr_restore(struct sys_device *sysdev)
 {
 	int i;
 
 	for (i = 0; i < num_var_ranges; i++) {
-		if (mtrr_value[i].lsize)
-			set_mtrr(i,
-				 mtrr_value[i].lbase,
-				 mtrr_value[i].lsize,
-				 mtrr_value[i].ltype);
+		if (mtrr_value[i].lsize) {
+			set_mtrr(i, mtrr_value[i].lbase,
+				    mtrr_value[i].lsize,
+				    mtrr_value[i].ltype);
+		}
 	}
 	return 0;
 }
@@ -615,26 +637,29 @@ int __initdata changed_by_mtrr_cleanup;
 /**
  * mtrr_bp_init - initialize mtrrs on the boot CPU
  *
- * This needs to be called early; before any of the other CPUs are 
+ * This needs to be called early; before any of the other CPUs are
  * initialized (i.e. before smp_init()).
- * 
+ *
  */
 void __init mtrr_bp_init(void)
 {
 	u32 phys_addr;
+
 	init_ifs();
 
 	phys_addr = 32;
 
 	if (cpu_has_mtrr) {
 		mtrr_if = &generic_mtrr_ops;
-		size_or_mask = 0xff000000;	/* 36 bits */
+		size_or_mask = 0xff000000;			/* 36 bits */
 		size_and_mask = 0x00f00000;
 		phys_addr = 36;
 
-		/* This is an AMD specific MSR, but we assume(hope?) that
-		   Intel will implement it to when they extend the address
-		   bus of the Xeon. */
+		/*
+		 * This is an AMD specific MSR, but we assume(hope?) that
+		 * Intel will implement it to when they extend the address
+		 * bus of the Xeon.
+		 */
 		if (cpuid_eax(0x80000000) >= 0x80000008) {
 			phys_addr = cpuid_eax(0x80000008) & 0xff;
 			/* CPUID workaround for Intel 0F33/0F34 CPU */
@@ -649,9 +674,11 @@ void __init mtrr_bp_init(void)
 			size_and_mask = ~size_or_mask & 0xfffff00000ULL;
 		} else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
 			   boot_cpu_data.x86 == 6) {
-			/* VIA C* family have Intel style MTRRs, but
-			   don't support PAE */
-			size_or_mask = 0xfff00000;	/* 32 bits */
+			/*
+			 * VIA C* family have Intel style MTRRs,
+			 * but don't support PAE
+			 */
+			size_or_mask = 0xfff00000;		/* 32 bits */
 			size_and_mask = 0;
 			phys_addr = 32;
 		}
@@ -694,30 +721,28 @@ void __init mtrr_bp_init(void)
 				changed_by_mtrr_cleanup = 1;
 				mtrr_if->set_all();
 			}
-
 		}
 	}
 }
 
 void mtrr_ap_init(void)
 {
-	unsigned long flags;
-
-	if (!mtrr_if || !use_intel())
+	if (!use_intel() || mtrr_aps_delayed_init)
 		return;
 	/*
-	 * Ideally we should hold mtrr_mutex here to avoid mtrr entries changed,
-	 * but this routine will be called in cpu boot time, holding the lock
-	 * breaks it. This routine is called in two cases: 1.very earily time
-	 * of software resume, when there absolutely isn't mtrr entry changes;
-	 * 2.cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug lock to
-	 * prevent mtrr entry changes
+	 * Ideally we should hold mtrr_mutex here to avoid mtrr entries
+	 * changed, but this routine will be called in cpu boot time,
+	 * holding the lock breaks it.
+	 *
+	 * This routine is called in two cases:
+	 *
+	 *   1. very earily time of software resume, when there absolutely
+	 *      isn't mtrr entry changes;
+	 *
+	 *   2. cpu hotadd time. We let mtrr_add/del_page hold cpuhotplug
+	 *      lock to prevent mtrr entry changes
 	 */
-	local_irq_save(flags);
-
-	mtrr_if->set_all();
-
-	local_irq_restore(flags);
+	set_mtrr(~0U, 0, 0, 0);
 }
 
 /**
@@ -728,23 +753,55 @@ void mtrr_save_state(void)
 	smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1);
 }
 
+void set_mtrr_aps_delayed_init(void)
+{
+	if (!use_intel())
+		return;
+
+	mtrr_aps_delayed_init = true;
+}
+
+/*
+ * MTRR initialization for all AP's
+ */
+void mtrr_aps_init(void)
+{
+	if (!use_intel())
+		return;
+
+	set_mtrr(~0U, 0, 0, 0);
+	mtrr_aps_delayed_init = false;
+}
+
+void mtrr_bp_restore(void)
+{
+	if (!use_intel())
+		return;
+
+	mtrr_if->set_all();
+}
+
 static int __init mtrr_init_finialize(void)
 {
 	if (!mtrr_if)
 		return 0;
+
 	if (use_intel()) {
 		if (!changed_by_mtrr_cleanup)
 			mtrr_state_warn();
-	} else {
-		/* The CPUs haven't MTRR and seem to not support SMP. They have
-		 * specific drivers, we use a tricky method to support
-		 * suspend/resume for them.
-		 * TBD: is there any system with such CPU which supports
-		 * suspend/resume?  if no, we should remove the code.
-		 */
-		sysdev_driver_register(&cpu_sysdev_class,
-			&mtrr_sysdev_driver);
+		return 0;
 	}
+
+	/*
+	 * The CPU has no MTRR and seems to not support SMP. They have
+	 * specific drivers, we use a tricky method to support
+	 * suspend/resume for them.
+	 *
+	 * TBD: is there any system with such CPU which supports
+	 * suspend/resume? If no, we should remove the code.
+	 */
+	sysdev_driver_register(&cpu_sysdev_class, &mtrr_sysdev_driver);
+
 	return 0;
 }
 subsys_initcall(mtrr_init_finialize);
diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
index 7538b76..a501dee 100644
--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
+++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
@@ -1,5 +1,5 @@
 /*
- * local mtrr defines.
+ * local MTRR defines.
  */
 
 #include <linux/types.h>
@@ -14,13 +14,12 @@ extern unsigned int mtrr_usage_table[MTRR_MAX_VAR_RANGES];
 struct mtrr_ops {
 	u32	vendor;
 	u32	use_intel_if;
-//	void	(*init)(void);
 	void	(*set)(unsigned int reg, unsigned long base,
 		       unsigned long size, mtrr_type type);
 	void	(*set_all)(void);
 
 	void	(*get)(unsigned int reg, unsigned long *base,
-		       unsigned long *size, mtrr_type * type);
+		       unsigned long *size, mtrr_type *type);
 	int	(*get_free_region)(unsigned long base, unsigned long size,
 				   int replace_reg);
 	int	(*validate_add_page)(unsigned long base, unsigned long size,
@@ -39,11 +38,11 @@ extern int positive_have_wrcomb(void);
 
 /* library functions for processor-specific routines */
 struct set_mtrr_context {
-	unsigned long flags;
-	unsigned long cr4val;
-	u32 deftype_lo;
-	u32 deftype_hi;
-	u32 ccr3;
+	unsigned long	flags;
+	unsigned long	cr4val;
+	u32		deftype_lo;
+	u32		deftype_hi;
+	u32		ccr3;
 };
 
 void set_mtrr_done(struct set_mtrr_context *ctxt);
@@ -54,10 +53,10 @@ void fill_mtrr_var_range(unsigned int index,
 		u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi);
 void get_mtrr_state(void);
 
-extern void set_mtrr_ops(struct mtrr_ops * ops);
+extern void set_mtrr_ops(struct mtrr_ops *ops);
 
 extern u64 size_or_mask, size_and_mask;
-extern struct mtrr_ops * mtrr_if;
+extern struct mtrr_ops *mtrr_if;
 
 #define is_cpu(vnd)	(mtrr_if && mtrr_if->vendor == X86_VENDOR_##vnd)
 #define use_intel()	(mtrr_if && mtrr_if->use_intel_if == 1)
diff --git a/arch/x86/kernel/cpu/mtrr/state.c b/arch/x86/kernel/cpu/mtrr/state.c
index 1f5fb15..dfc80b4 100644
--- a/arch/x86/kernel/cpu/mtrr/state.c
+++ b/arch/x86/kernel/cpu/mtrr/state.c
@@ -1,24 +1,25 @@
-#include <linux/mm.h>
 #include <linux/init.h>
-#include <asm/io.h>
-#include <asm/mtrr.h>
-#include <asm/msr.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+
 #include <asm/processor-cyrix.h>
 #include <asm/processor-flags.h>
-#include "mtrr.h"
+#include <asm/mtrr.h>
+#include <asm/msr.h>
 
+#include "mtrr.h"
 
-/*  Put the processor into a state where MTRRs can be safely set  */
+/* Put the processor into a state where MTRRs can be safely set */
 void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
 {
 	unsigned int cr0;
 
-	/*  Disable interrupts locally  */
+	/* Disable interrupts locally */
 	local_irq_save(ctxt->flags);
 
 	if (use_intel() || is_cpu(CYRIX)) {
 
-		/*  Save value of CR4 and clear Page Global Enable (bit 7)  */
+		/* Save value of CR4 and clear Page Global Enable (bit 7) */
 		if (cpu_has_pge) {
 			ctxt->cr4val = read_cr4();
 			write_cr4(ctxt->cr4val & ~X86_CR4_PGE);
@@ -33,50 +34,61 @@ void set_mtrr_prepare_save(struct set_mtrr_context *ctxt)
 		write_cr0(cr0);
 		wbinvd();
 
-		if (use_intel())
-			/*  Save MTRR state */
+		if (use_intel()) {
+			/* Save MTRR state */
 			rdmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
-		else
-			/* Cyrix ARRs - everything else were excluded at the top */
+		} else {
+			/*
+			 * Cyrix ARRs -
+			 * everything else were excluded at the top
+			 */
 			ctxt->ccr3 = getCx86(CX86_CCR3);
+		}
 	}
 }
 
 void set_mtrr_cache_disable(struct set_mtrr_context *ctxt)
 {
-	if (use_intel())
-		/*  Disable MTRRs, and set the default type to uncached  */
+	if (use_intel()) {
+		/* Disable MTRRs, and set the default type to uncached */
 		mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo & 0xf300UL,
 		      ctxt->deftype_hi);
-	else if (is_cpu(CYRIX))
-		/* Cyrix ARRs - everything else were excluded at the top */
-		setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10);
+	} else {
+		if (is_cpu(CYRIX)) {
+			/* Cyrix ARRs - everything else were excluded at the top */
+			setCx86(CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10);
+		}
+	}
 }
 
-/*  Restore the processor after a set_mtrr_prepare  */
+/* Restore the processor after a set_mtrr_prepare */
 void set_mtrr_done(struct set_mtrr_context *ctxt)
 {
 	if (use_intel() || is_cpu(CYRIX)) {
 
-		/*  Flush caches and TLBs  */
+		/* Flush caches and TLBs */
 		wbinvd();
 
-		/*  Restore MTRRdefType  */
-		if (use_intel())
+		/* Restore MTRRdefType */
+		if (use_intel()) {
 			/* Intel (P6) standard MTRRs */
-			mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo, ctxt->deftype_hi);
-		else
-			/* Cyrix ARRs - everything else was excluded at the top */
+			mtrr_wrmsr(MSR_MTRRdefType, ctxt->deftype_lo,
+				   ctxt->deftype_hi);
+		} else {
+			/*
+			 * Cyrix ARRs -
+			 * everything else was excluded at the top
+			 */
 			setCx86(CX86_CCR3, ctxt->ccr3);
+		}
 
-		/*  Enable caches  */
+		/* Enable caches */
 		write_cr0(read_cr0() & 0xbfffffff);
 
-		/*  Restore value of CR4  */
+		/* Restore value of CR4 */
 		if (cpu_has_pge)
 			write_cr4(ctxt->cr4val);
 	}
-	/*  Re-enable interrupts locally (if enabled previously)  */
+	/* Re-enable interrupts locally (if enabled previously) */
 	local_irq_restore(ctxt->flags);
 }
-
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c
deleted file mode 100644
index f9cd084..0000000
--- a/arch/x86/kernel/cpu/perf_counter.c
+++ /dev/null
@@ -1,2281 +0,0 @@
-/*
- * Performance counter x86 architecture code
- *
- *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
- *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
- *  Copyright (C) 2009 Jaswinder Singh Rajput
- *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
- *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
- *
- *  For licencing details see kernel-base/COPYING
- */
-
-#include <linux/perf_counter.h>
-#include <linux/capability.h>
-#include <linux/notifier.h>
-#include <linux/hardirq.h>
-#include <linux/kprobes.h>
-#include <linux/module.h>
-#include <linux/kdebug.h>
-#include <linux/sched.h>
-#include <linux/uaccess.h>
-#include <linux/highmem.h>
-#include <linux/cpu.h>
-
-#include <asm/apic.h>
-#include <asm/stacktrace.h>
-#include <asm/nmi.h>
-
-static u64 perf_counter_mask __read_mostly;
-
-/* The maximal number of PEBS counters: */
-#define MAX_PEBS_COUNTERS	4
-
-/* The size of a BTS record in bytes: */
-#define BTS_RECORD_SIZE		24
-
-/* The size of a per-cpu BTS buffer in bytes: */
-#define BTS_BUFFER_SIZE		(BTS_RECORD_SIZE * 1024)
-
-/* The BTS overflow threshold in bytes from the end of the buffer: */
-#define BTS_OVFL_TH		(BTS_RECORD_SIZE * 64)
-
-
-/*
- * Bits in the debugctlmsr controlling branch tracing.
- */
-#define X86_DEBUGCTL_TR			(1 << 6)
-#define X86_DEBUGCTL_BTS		(1 << 7)
-#define X86_DEBUGCTL_BTINT		(1 << 8)
-#define X86_DEBUGCTL_BTS_OFF_OS		(1 << 9)
-#define X86_DEBUGCTL_BTS_OFF_USR	(1 << 10)
-
-/*
- * A debug store configuration.
- *
- * We only support architectures that use 64bit fields.
- */
-struct debug_store {
-	u64	bts_buffer_base;
-	u64	bts_index;
-	u64	bts_absolute_maximum;
-	u64	bts_interrupt_threshold;
-	u64	pebs_buffer_base;
-	u64	pebs_index;
-	u64	pebs_absolute_maximum;
-	u64	pebs_interrupt_threshold;
-	u64	pebs_counter_reset[MAX_PEBS_COUNTERS];
-};
-
-struct cpu_hw_counters {
-	struct perf_counter	*counters[X86_PMC_IDX_MAX];
-	unsigned long		used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-	unsigned long		active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
-	unsigned long		interrupts;
-	int			enabled;
-	struct debug_store	*ds;
-};
-
-/*
- * struct x86_pmu - generic x86 pmu
- */
-struct x86_pmu {
-	const char	*name;
-	int		version;
-	int		(*handle_irq)(struct pt_regs *);
-	void		(*disable_all)(void);
-	void		(*enable_all)(void);
-	void		(*enable)(struct hw_perf_counter *, int);
-	void		(*disable)(struct hw_perf_counter *, int);
-	unsigned	eventsel;
-	unsigned	perfctr;
-	u64		(*event_map)(int);
-	u64		(*raw_event)(u64);
-	int		max_events;
-	int		num_counters;
-	int		num_counters_fixed;
-	int		counter_bits;
-	u64		counter_mask;
-	int		apic;
-	u64		max_period;
-	u64		intel_ctrl;
-	void		(*enable_bts)(u64 config);
-	void		(*disable_bts)(void);
-};
-
-static struct x86_pmu x86_pmu __read_mostly;
-
-static DEFINE_PER_CPU(struct cpu_hw_counters, cpu_hw_counters) = {
-	.enabled = 1,
-};
-
-/*
- * Not sure about some of these
- */
-static const u64 p6_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,
-};
-
-static u64 p6_pmu_event_map(int event)
-{
-	return p6_perfmon_event_map[event];
-}
-
-/*
- * Counter setting that is specified not to count anything.
- * We use this to effectively disable a counter.
- *
- * L2_RQSTS with 0 MESI unit mask.
- */
-#define P6_NOP_COUNTER			0x0000002EULL
-
-static u64 p6_pmu_raw_event(u64 event)
-{
-#define P6_EVNTSEL_EVENT_MASK		0x000000FFULL
-#define P6_EVNTSEL_UNIT_MASK		0x0000FF00ULL
-#define P6_EVNTSEL_EDGE_MASK		0x00040000ULL
-#define P6_EVNTSEL_INV_MASK		0x00800000ULL
-#define P6_EVNTSEL_COUNTER_MASK		0xFF000000ULL
-
-#define P6_EVNTSEL_MASK			\
-	(P6_EVNTSEL_EVENT_MASK |	\
-	 P6_EVNTSEL_UNIT_MASK  |	\
-	 P6_EVNTSEL_EDGE_MASK  |	\
-	 P6_EVNTSEL_INV_MASK   |	\
-	 P6_EVNTSEL_COUNTER_MASK)
-
-	return event & P6_EVNTSEL_MASK;
-}
-
-
-/*
- * Intel PerfMon v3. Used on Core2 and later.
- */
-static const u64 intel_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x003c,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x4f2e,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x412e,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-  [PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
-};
-
-static u64 intel_pmu_event_map(int event)
-{
-	return intel_perfmon_event_map[event];
-}
-
-/*
- * Generalized hw caching related event table, filled
- * in on a per model basis. A value of 0 means
- * 'not supported', -1 means 'event makes no sense on
- * this CPU', any other value means the raw event
- * ID.
- */
-
-#define C(x) PERF_COUNT_HW_CACHE_##x
-
-static u64 __read_mostly hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX];
-
-static const u64 nehalem_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI            */
-		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE         */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI            */
-		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE         */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
-		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
-		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS               */
-		[ C(RESULT_MISS)   ] = 0x0224, /* L2_RQSTS.LD_MISS             */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS                */
-		[ C(RESULT_MISS)   ] = 0x0824, /* L2_RQSTS.RFO_MISS            */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference                */
-		[ C(RESULT_MISS)   ] = 0x412e, /* LLC Misses                   */
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI   (alias)  */
-		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI   (alias)  */
-		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0x0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
-		[ C(RESULT_MISS)   ] = 0x20c8, /* ITLB_MISS_RETIRED            */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
-		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static const u64 core2_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI          */
-		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE       */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI          */
-		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE       */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS      */
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS                  */
-		[ C(RESULT_MISS)   ] = 0x0081, /* L1I.MISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0208, /* DTLB_MISSES.MISS_LD        */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0808, /* DTLB_MISSES.MISS_ST        */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
-		[ C(RESULT_MISS)   ] = 0x1282, /* ITLBMISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static const u64 atom_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD               */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST               */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                  */
-		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                 */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
-		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0508, /* DTLB_MISSES.MISS_LD        */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI  (alias) */
-		[ C(RESULT_MISS)   ] = 0x0608, /* DTLB_MISSES.MISS_ST        */
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
-		[ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES                */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
-		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-static u64 intel_pmu_raw_event(u64 event)
-{
-#define CORE_EVNTSEL_EVENT_MASK		0x000000FFULL
-#define CORE_EVNTSEL_UNIT_MASK		0x0000FF00ULL
-#define CORE_EVNTSEL_EDGE_MASK		0x00040000ULL
-#define CORE_EVNTSEL_INV_MASK		0x00800000ULL
-#define CORE_EVNTSEL_COUNTER_MASK	0xFF000000ULL
-
-#define CORE_EVNTSEL_MASK		\
-	(CORE_EVNTSEL_EVENT_MASK |	\
-	 CORE_EVNTSEL_UNIT_MASK  |	\
-	 CORE_EVNTSEL_EDGE_MASK  |	\
-	 CORE_EVNTSEL_INV_MASK  |	\
-	 CORE_EVNTSEL_COUNTER_MASK)
-
-	return event & CORE_EVNTSEL_MASK;
-}
-
-static const u64 amd_hw_cache_event_ids
-				[PERF_COUNT_HW_CACHE_MAX]
-				[PERF_COUNT_HW_CACHE_OP_MAX]
-				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
-{
- [ C(L1D) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
-		[ C(RESULT_MISS)   ] = 0x0041, /* Data Cache Misses          */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts  */
-		[ C(RESULT_MISS)   ] = 0x0167, /* Data Prefetcher :cancelled */
-	},
- },
- [ C(L1I ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches  */
-		[ C(RESULT_MISS)   ] = 0x0081, /* Instruction cache misses   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(LL  ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
-		[ C(RESULT_MISS)   ] = 0x037E, /* L2 Cache Misses : IC+DC     */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback           */
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(DTLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
-		[ C(RESULT_MISS)   ] = 0x0046, /* L1 DTLB and L2 DLTB Miss   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = 0,
-		[ C(RESULT_MISS)   ] = 0,
-	},
- },
- [ C(ITLB) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes        */
-		[ C(RESULT_MISS)   ] = 0x0085, /* Instr. fetch ITLB misses   */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
- [ C(BPU ) ] = {
-	[ C(OP_READ) ] = {
-		[ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr.      */
-		[ C(RESULT_MISS)   ] = 0x00c3, /* Retired Mispredicted BI    */
-	},
-	[ C(OP_WRITE) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
-	[ C(OP_PREFETCH) ] = {
-		[ C(RESULT_ACCESS) ] = -1,
-		[ C(RESULT_MISS)   ] = -1,
-	},
- },
-};
-
-/*
- * AMD Performance Monitor K7 and later.
- */
-static const u64 amd_perfmon_event_map[] =
-{
-  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0076,
-  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
-  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0080,
-  [PERF_COUNT_HW_CACHE_MISSES]		= 0x0081,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
-};
-
-static u64 amd_pmu_event_map(int event)
-{
-	return amd_perfmon_event_map[event];
-}
-
-static u64 amd_pmu_raw_event(u64 event)
-{
-#define K7_EVNTSEL_EVENT_MASK	0x7000000FFULL
-#define K7_EVNTSEL_UNIT_MASK	0x00000FF00ULL
-#define K7_EVNTSEL_EDGE_MASK	0x000040000ULL
-#define K7_EVNTSEL_INV_MASK	0x000800000ULL
-#define K7_EVNTSEL_COUNTER_MASK	0x0FF000000ULL
-
-#define K7_EVNTSEL_MASK			\
-	(K7_EVNTSEL_EVENT_MASK |	\
-	 K7_EVNTSEL_UNIT_MASK  |	\
-	 K7_EVNTSEL_EDGE_MASK  |	\
-	 K7_EVNTSEL_INV_MASK   |	\
-	 K7_EVNTSEL_COUNTER_MASK)
-
-	return event & K7_EVNTSEL_MASK;
-}
-
-/*
- * Propagate counter elapsed time into the generic counter.
- * Can only be executed on the CPU where the counter is active.
- * Returns the delta events processed.
- */
-static u64
-x86_perf_counter_update(struct perf_counter *counter,
-			struct hw_perf_counter *hwc, int idx)
-{
-	int shift = 64 - x86_pmu.counter_bits;
-	u64 prev_raw_count, new_raw_count;
-	s64 delta;
-
-	if (idx == X86_PMC_IDX_FIXED_BTS)
-		return 0;
-
-	/*
-	 * Careful: an NMI might modify the previous counter value.
-	 *
-	 * Our tactic to handle this is to first atomically read and
-	 * exchange a new raw count - then add that new-prev delta
-	 * count to the generic counter atomically:
-	 */
-again:
-	prev_raw_count = atomic64_read(&hwc->prev_count);
-	rdmsrl(hwc->counter_base + idx, new_raw_count);
-
-	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
-					new_raw_count) != prev_raw_count)
-		goto again;
-
-	/*
-	 * Now we have the new raw value and have updated the prev
-	 * timestamp already. We can now calculate the elapsed delta
-	 * (counter-)time and add that to the generic counter.
-	 *
-	 * Careful, not all hw sign-extends above the physical width
-	 * of the count.
-	 */
-	delta = (new_raw_count << shift) - (prev_raw_count << shift);
-	delta >>= shift;
-
-	atomic64_add(delta, &counter->count);
-	atomic64_sub(delta, &hwc->period_left);
-
-	return new_raw_count;
-}
-
-static atomic_t active_counters;
-static DEFINE_MUTEX(pmc_reserve_mutex);
-
-static bool reserve_pmc_hardware(void)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
-	int i;
-
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		disable_lapic_nmi_watchdog();
-
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		if (!reserve_perfctr_nmi(x86_pmu.perfctr + i))
-			goto perfctr_fail;
-	}
-
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
-			goto eventsel_fail;
-	}
-#endif
-
-	return true;
-
-#ifdef CONFIG_X86_LOCAL_APIC
-eventsel_fail:
-	for (i--; i >= 0; i--)
-		release_evntsel_nmi(x86_pmu.eventsel + i);
-
-	i = x86_pmu.num_counters;
-
-perfctr_fail:
-	for (i--; i >= 0; i--)
-		release_perfctr_nmi(x86_pmu.perfctr + i);
-
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		enable_lapic_nmi_watchdog();
-
-	return false;
-#endif
-}
-
-static void release_pmc_hardware(void)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
-	int i;
-
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		release_perfctr_nmi(x86_pmu.perfctr + i);
-		release_evntsel_nmi(x86_pmu.eventsel + i);
-	}
-
-	if (nmi_watchdog == NMI_LOCAL_APIC)
-		enable_lapic_nmi_watchdog();
-#endif
-}
-
-static inline bool bts_available(void)
-{
-	return x86_pmu.enable_bts != NULL;
-}
-
-static inline void init_debug_store_on_cpu(int cpu)
-{
-	struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds;
-
-	if (!ds)
-		return;
-
-	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
-		     (u32)((u64)(unsigned long)ds),
-		     (u32)((u64)(unsigned long)ds >> 32));
-}
-
-static inline void fini_debug_store_on_cpu(int cpu)
-{
-	if (!per_cpu(cpu_hw_counters, cpu).ds)
-		return;
-
-	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
-}
-
-static void release_bts_hardware(void)
-{
-	int cpu;
-
-	if (!bts_available())
-		return;
-
-	get_online_cpus();
-
-	for_each_online_cpu(cpu)
-		fini_debug_store_on_cpu(cpu);
-
-	for_each_possible_cpu(cpu) {
-		struct debug_store *ds = per_cpu(cpu_hw_counters, cpu).ds;
-
-		if (!ds)
-			continue;
-
-		per_cpu(cpu_hw_counters, cpu).ds = NULL;
-
-		kfree((void *)(unsigned long)ds->bts_buffer_base);
-		kfree(ds);
-	}
-
-	put_online_cpus();
-}
-
-static int reserve_bts_hardware(void)
-{
-	int cpu, err = 0;
-
-	if (!bts_available())
-		return 0;
-
-	get_online_cpus();
-
-	for_each_possible_cpu(cpu) {
-		struct debug_store *ds;
-		void *buffer;
-
-		err = -ENOMEM;
-		buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
-		if (unlikely(!buffer))
-			break;
-
-		ds = kzalloc(sizeof(*ds), GFP_KERNEL);
-		if (unlikely(!ds)) {
-			kfree(buffer);
-			break;
-		}
-
-		ds->bts_buffer_base = (u64)(unsigned long)buffer;
-		ds->bts_index = ds->bts_buffer_base;
-		ds->bts_absolute_maximum =
-			ds->bts_buffer_base + BTS_BUFFER_SIZE;
-		ds->bts_interrupt_threshold =
-			ds->bts_absolute_maximum - BTS_OVFL_TH;
-
-		per_cpu(cpu_hw_counters, cpu).ds = ds;
-		err = 0;
-	}
-
-	if (err)
-		release_bts_hardware();
-	else {
-		for_each_online_cpu(cpu)
-			init_debug_store_on_cpu(cpu);
-	}
-
-	put_online_cpus();
-
-	return err;
-}
-
-static void hw_perf_counter_destroy(struct perf_counter *counter)
-{
-	if (atomic_dec_and_mutex_lock(&active_counters, &pmc_reserve_mutex)) {
-		release_pmc_hardware();
-		release_bts_hardware();
-		mutex_unlock(&pmc_reserve_mutex);
-	}
-}
-
-static inline int x86_pmu_initialized(void)
-{
-	return x86_pmu.handle_irq != NULL;
-}
-
-static inline int
-set_ext_hw_attr(struct hw_perf_counter *hwc, struct perf_counter_attr *attr)
-{
-	unsigned int cache_type, cache_op, cache_result;
-	u64 config, val;
-
-	config = attr->config;
-
-	cache_type = (config >>  0) & 0xff;
-	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
-		return -EINVAL;
-
-	cache_op = (config >>  8) & 0xff;
-	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
-		return -EINVAL;
-
-	cache_result = (config >> 16) & 0xff;
-	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
-		return -EINVAL;
-
-	val = hw_cache_event_ids[cache_type][cache_op][cache_result];
-
-	if (val == 0)
-		return -ENOENT;
-
-	if (val == -1)
-		return -EINVAL;
-
-	hwc->config |= val;
-
-	return 0;
-}
-
-static void intel_pmu_enable_bts(u64 config)
-{
-	unsigned long debugctlmsr;
-
-	debugctlmsr = get_debugctlmsr();
-
-	debugctlmsr |= X86_DEBUGCTL_TR;
-	debugctlmsr |= X86_DEBUGCTL_BTS;
-	debugctlmsr |= X86_DEBUGCTL_BTINT;
-
-	if (!(config & ARCH_PERFMON_EVENTSEL_OS))
-		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
-
-	if (!(config & ARCH_PERFMON_EVENTSEL_USR))
-		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
-
-	update_debugctlmsr(debugctlmsr);
-}
-
-static void intel_pmu_disable_bts(void)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	unsigned long debugctlmsr;
-
-	if (!cpuc->ds)
-		return;
-
-	debugctlmsr = get_debugctlmsr();
-
-	debugctlmsr &=
-		~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
-		  X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
-
-	update_debugctlmsr(debugctlmsr);
-}
-
-/*
- * Setup the hardware configuration for a given attr_type
- */
-static int __hw_perf_counter_init(struct perf_counter *counter)
-{
-	struct perf_counter_attr *attr = &counter->attr;
-	struct hw_perf_counter *hwc = &counter->hw;
-	u64 config;
-	int err;
-
-	if (!x86_pmu_initialized())
-		return -ENODEV;
-
-	err = 0;
-	if (!atomic_inc_not_zero(&active_counters)) {
-		mutex_lock(&pmc_reserve_mutex);
-		if (atomic_read(&active_counters) == 0) {
-			if (!reserve_pmc_hardware())
-				err = -EBUSY;
-			else
-				err = reserve_bts_hardware();
-		}
-		if (!err)
-			atomic_inc(&active_counters);
-		mutex_unlock(&pmc_reserve_mutex);
-	}
-	if (err)
-		return err;
-
-	/*
-	 * Generate PMC IRQs:
-	 * (keep 'enabled' bit clear for now)
-	 */
-	hwc->config = ARCH_PERFMON_EVENTSEL_INT;
-
-	/*
-	 * Count user and OS events unless requested not to.
-	 */
-	if (!attr->exclude_user)
-		hwc->config |= ARCH_PERFMON_EVENTSEL_USR;
-	if (!attr->exclude_kernel)
-		hwc->config |= ARCH_PERFMON_EVENTSEL_OS;
-
-	if (!hwc->sample_period) {
-		hwc->sample_period = x86_pmu.max_period;
-		hwc->last_period = hwc->sample_period;
-		atomic64_set(&hwc->period_left, hwc->sample_period);
-	} else {
-		/*
-		 * If we have a PMU initialized but no APIC
-		 * interrupts, we cannot sample hardware
-		 * counters (user-space has to fall back and
-		 * sample via a hrtimer based software counter):
-		 */
-		if (!x86_pmu.apic)
-			return -EOPNOTSUPP;
-	}
-
-	counter->destroy = hw_perf_counter_destroy;
-
-	/*
-	 * Raw event type provide the config in the event structure
-	 */
-	if (attr->type == PERF_TYPE_RAW) {
-		hwc->config |= x86_pmu.raw_event(attr->config);
-		return 0;
-	}
-
-	if (attr->type == PERF_TYPE_HW_CACHE)
-		return set_ext_hw_attr(hwc, attr);
-
-	if (attr->config >= x86_pmu.max_events)
-		return -EINVAL;
-
-	/*
-	 * The generic map:
-	 */
-	config = x86_pmu.event_map(attr->config);
-
-	if (config == 0)
-		return -ENOENT;
-
-	if (config == -1LL)
-		return -EINVAL;
-
-	/*
-	 * Branch tracing:
-	 */
-	if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
-	    (hwc->sample_period == 1)) {
-		/* BTS is not supported by this architecture. */
-		if (!bts_available())
-			return -EOPNOTSUPP;
-
-		/* BTS is currently only allowed for user-mode. */
-		if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
-			return -EOPNOTSUPP;
-	}
-
-	hwc->config |= config;
-
-	return 0;
-}
-
-static void p6_pmu_disable_all(void)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	u64 val;
-
-	if (!cpuc->enabled)
-		return;
-
-	cpuc->enabled = 0;
-	barrier();
-
-	/* p6 only has one enable register */
-	rdmsrl(MSR_P6_EVNTSEL0, val);
-	val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
-	wrmsrl(MSR_P6_EVNTSEL0, val);
-}
-
-static void intel_pmu_disable_all(void)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-
-	if (!cpuc->enabled)
-		return;
-
-	cpuc->enabled = 0;
-	barrier();
-
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-
-	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
-		intel_pmu_disable_bts();
-}
-
-static void amd_pmu_disable_all(void)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	int idx;
-
-	if (!cpuc->enabled)
-		return;
-
-	cpuc->enabled = 0;
-	/*
-	 * ensure we write the disable before we start disabling the
-	 * counters proper, so that amd_pmu_enable_counter() does the
-	 * right thing.
-	 */
-	barrier();
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		u64 val;
-
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-		rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
-		if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE))
-			continue;
-		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
-		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
-	}
-}
-
-void hw_perf_disable(void)
-{
-	if (!x86_pmu_initialized())
-		return;
-	return x86_pmu.disable_all();
-}
-
-static void p6_pmu_enable_all(void)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	unsigned long val;
-
-	if (cpuc->enabled)
-		return;
-
-	cpuc->enabled = 1;
-	barrier();
-
-	/* p6 only has one enable register */
-	rdmsrl(MSR_P6_EVNTSEL0, val);
-	val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-	wrmsrl(MSR_P6_EVNTSEL0, val);
-}
-
-static void intel_pmu_enable_all(void)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-
-	if (cpuc->enabled)
-		return;
-
-	cpuc->enabled = 1;
-	barrier();
-
-	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
-
-	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
-		struct perf_counter *counter =
-			cpuc->counters[X86_PMC_IDX_FIXED_BTS];
-
-		if (WARN_ON_ONCE(!counter))
-			return;
-
-		intel_pmu_enable_bts(counter->hw.config);
-	}
-}
-
-static void amd_pmu_enable_all(void)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	int idx;
-
-	if (cpuc->enabled)
-		return;
-
-	cpuc->enabled = 1;
-	barrier();
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		struct perf_counter *counter = cpuc->counters[idx];
-		u64 val;
-
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-
-		val = counter->hw.config;
-		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
-	}
-}
-
-void hw_perf_enable(void)
-{
-	if (!x86_pmu_initialized())
-		return;
-	x86_pmu.enable_all();
-}
-
-static inline u64 intel_pmu_get_status(void)
-{
-	u64 status;
-
-	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
-
-	return status;
-}
-
-static inline void intel_pmu_ack_status(u64 ack)
-{
-	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
-}
-
-static inline void x86_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	(void)checking_wrmsrl(hwc->config_base + idx,
-			      hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE);
-}
-
-static inline void x86_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	(void)checking_wrmsrl(hwc->config_base + idx, hwc->config);
-}
-
-static inline void
-intel_pmu_disable_fixed(struct hw_perf_counter *hwc, int __idx)
-{
-	int idx = __idx - X86_PMC_IDX_FIXED;
-	u64 ctrl_val, mask;
-
-	mask = 0xfULL << (idx * 4);
-
-	rdmsrl(hwc->config_base, ctrl_val);
-	ctrl_val &= ~mask;
-	(void)checking_wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static inline void
-p6_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	u64 val = P6_NOP_COUNTER;
-
-	if (cpuc->enabled)
-		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-
-	(void)checking_wrmsrl(hwc->config_base + idx, val);
-}
-
-static inline void
-intel_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
-		intel_pmu_disable_bts();
-		return;
-	}
-
-	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-		intel_pmu_disable_fixed(hwc, idx);
-		return;
-	}
-
-	x86_pmu_disable_counter(hwc, idx);
-}
-
-static inline void
-amd_pmu_disable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	x86_pmu_disable_counter(hwc, idx);
-}
-
-static DEFINE_PER_CPU(u64, prev_left[X86_PMC_IDX_MAX]);
-
-/*
- * Set the next IRQ period, based on the hwc->period_left value.
- * To be called with the counter disabled in hw:
- */
-static int
-x86_perf_counter_set_period(struct perf_counter *counter,
-			     struct hw_perf_counter *hwc, int idx)
-{
-	s64 left = atomic64_read(&hwc->period_left);
-	s64 period = hwc->sample_period;
-	int err, ret = 0;
-
-	if (idx == X86_PMC_IDX_FIXED_BTS)
-		return 0;
-
-	/*
-	 * If we are way outside a reasoable range then just skip forward:
-	 */
-	if (unlikely(left <= -period)) {
-		left = period;
-		atomic64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		ret = 1;
-	}
-
-	if (unlikely(left <= 0)) {
-		left += period;
-		atomic64_set(&hwc->period_left, left);
-		hwc->last_period = period;
-		ret = 1;
-	}
-	/*
-	 * Quirk: certain CPUs dont like it if just 1 event is left:
-	 */
-	if (unlikely(left < 2))
-		left = 2;
-
-	if (left > x86_pmu.max_period)
-		left = x86_pmu.max_period;
-
-	per_cpu(prev_left[idx], smp_processor_id()) = left;
-
-	/*
-	 * The hw counter starts counting from this counter offset,
-	 * mark it to be able to extra future deltas:
-	 */
-	atomic64_set(&hwc->prev_count, (u64)-left);
-
-	err = checking_wrmsrl(hwc->counter_base + idx,
-			     (u64)(-left) & x86_pmu.counter_mask);
-
-	perf_counter_update_userpage(counter);
-
-	return ret;
-}
-
-static inline void
-intel_pmu_enable_fixed(struct hw_perf_counter *hwc, int __idx)
-{
-	int idx = __idx - X86_PMC_IDX_FIXED;
-	u64 ctrl_val, bits, mask;
-	int err;
-
-	/*
-	 * Enable IRQ generation (0x8),
-	 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
-	 * if requested:
-	 */
-	bits = 0x8ULL;
-	if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
-		bits |= 0x2;
-	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
-		bits |= 0x1;
-	bits <<= (idx * 4);
-	mask = 0xfULL << (idx * 4);
-
-	rdmsrl(hwc->config_base, ctrl_val);
-	ctrl_val &= ~mask;
-	ctrl_val |= bits;
-	err = checking_wrmsrl(hwc->config_base, ctrl_val);
-}
-
-static void p6_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	u64 val;
-
-	val = hwc->config;
-	if (cpuc->enabled)
-		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-
-	(void)checking_wrmsrl(hwc->config_base + idx, val);
-}
-
-
-static void intel_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
-		if (!__get_cpu_var(cpu_hw_counters).enabled)
-			return;
-
-		intel_pmu_enable_bts(hwc->config);
-		return;
-	}
-
-	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
-		intel_pmu_enable_fixed(hwc, idx);
-		return;
-	}
-
-	x86_pmu_enable_counter(hwc, idx);
-}
-
-static void amd_pmu_enable_counter(struct hw_perf_counter *hwc, int idx)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-
-	if (cpuc->enabled)
-		x86_pmu_enable_counter(hwc, idx);
-}
-
-static int
-fixed_mode_idx(struct perf_counter *counter, struct hw_perf_counter *hwc)
-{
-	unsigned int event;
-
-	event = hwc->config & ARCH_PERFMON_EVENT_MASK;
-
-	if (unlikely((event ==
-		      x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
-		     (hwc->sample_period == 1)))
-		return X86_PMC_IDX_FIXED_BTS;
-
-	if (!x86_pmu.num_counters_fixed)
-		return -1;
-
-	if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS)))
-		return X86_PMC_IDX_FIXED_INSTRUCTIONS;
-	if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES)))
-		return X86_PMC_IDX_FIXED_CPU_CYCLES;
-	if (unlikely(event == x86_pmu.event_map(PERF_COUNT_HW_BUS_CYCLES)))
-		return X86_PMC_IDX_FIXED_BUS_CYCLES;
-
-	return -1;
-}
-
-/*
- * Find a PMC slot for the freshly enabled / scheduled in counter:
- */
-static int x86_pmu_enable(struct perf_counter *counter)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	struct hw_perf_counter *hwc = &counter->hw;
-	int idx;
-
-	idx = fixed_mode_idx(counter, hwc);
-	if (idx == X86_PMC_IDX_FIXED_BTS) {
-		/* BTS is already occupied. */
-		if (test_and_set_bit(idx, cpuc->used_mask))
-			return -EAGAIN;
-
-		hwc->config_base	= 0;
-		hwc->counter_base	= 0;
-		hwc->idx		= idx;
-	} else if (idx >= 0) {
-		/*
-		 * Try to get the fixed counter, if that is already taken
-		 * then try to get a generic counter:
-		 */
-		if (test_and_set_bit(idx, cpuc->used_mask))
-			goto try_generic;
-
-		hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
-		/*
-		 * We set it so that counter_base + idx in wrmsr/rdmsr maps to
-		 * MSR_ARCH_PERFMON_FIXED_CTR0 ... CTR2:
-		 */
-		hwc->counter_base =
-			MSR_ARCH_PERFMON_FIXED_CTR0 - X86_PMC_IDX_FIXED;
-		hwc->idx = idx;
-	} else {
-		idx = hwc->idx;
-		/* Try to get the previous generic counter again */
-		if (test_and_set_bit(idx, cpuc->used_mask)) {
-try_generic:
-			idx = find_first_zero_bit(cpuc->used_mask,
-						  x86_pmu.num_counters);
-			if (idx == x86_pmu.num_counters)
-				return -EAGAIN;
-
-			set_bit(idx, cpuc->used_mask);
-			hwc->idx = idx;
-		}
-		hwc->config_base  = x86_pmu.eventsel;
-		hwc->counter_base = x86_pmu.perfctr;
-	}
-
-	perf_counters_lapic_init();
-
-	x86_pmu.disable(hwc, idx);
-
-	cpuc->counters[idx] = counter;
-	set_bit(idx, cpuc->active_mask);
-
-	x86_perf_counter_set_period(counter, hwc, idx);
-	x86_pmu.enable(hwc, idx);
-
-	perf_counter_update_userpage(counter);
-
-	return 0;
-}
-
-static void x86_pmu_unthrottle(struct perf_counter *counter)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	struct hw_perf_counter *hwc = &counter->hw;
-
-	if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX ||
-				cpuc->counters[hwc->idx] != counter))
-		return;
-
-	x86_pmu.enable(hwc, hwc->idx);
-}
-
-void perf_counter_print_debug(void)
-{
-	u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
-	struct cpu_hw_counters *cpuc;
-	unsigned long flags;
-	int cpu, idx;
-
-	if (!x86_pmu.num_counters)
-		return;
-
-	local_irq_save(flags);
-
-	cpu = smp_processor_id();
-	cpuc = &per_cpu(cpu_hw_counters, cpu);
-
-	if (x86_pmu.version >= 2) {
-		rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
-		rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
-		rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
-		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
-
-		pr_info("\n");
-		pr_info("CPU#%d: ctrl:       %016llx\n", cpu, ctrl);
-		pr_info("CPU#%d: status:     %016llx\n", cpu, status);
-		pr_info("CPU#%d: overflow:   %016llx\n", cpu, overflow);
-		pr_info("CPU#%d: fixed:      %016llx\n", cpu, fixed);
-	}
-	pr_info("CPU#%d: used:       %016llx\n", cpu, *(u64 *)cpuc->used_mask);
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl);
-		rdmsrl(x86_pmu.perfctr  + idx, pmc_count);
-
-		prev_left = per_cpu(prev_left[idx], cpu);
-
-		pr_info("CPU#%d:   gen-PMC%d ctrl:  %016llx\n",
-			cpu, idx, pmc_ctrl);
-		pr_info("CPU#%d:   gen-PMC%d count: %016llx\n",
-			cpu, idx, pmc_count);
-		pr_info("CPU#%d:   gen-PMC%d left:  %016llx\n",
-			cpu, idx, prev_left);
-	}
-	for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
-		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
-
-		pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
-			cpu, idx, pmc_count);
-	}
-	local_irq_restore(flags);
-}
-
-static void intel_pmu_drain_bts_buffer(struct cpu_hw_counters *cpuc,
-				       struct perf_sample_data *data)
-{
-	struct debug_store *ds = cpuc->ds;
-	struct bts_record {
-		u64	from;
-		u64	to;
-		u64	flags;
-	};
-	struct perf_counter *counter = cpuc->counters[X86_PMC_IDX_FIXED_BTS];
-	unsigned long orig_ip = data->regs->ip;
-	struct bts_record *at, *top;
-
-	if (!counter)
-		return;
-
-	if (!ds)
-		return;
-
-	at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
-	top = (struct bts_record *)(unsigned long)ds->bts_index;
-
-	ds->bts_index = ds->bts_buffer_base;
-
-	for (; at < top; at++) {
-		data->regs->ip	= at->from;
-		data->addr	= at->to;
-
-		perf_counter_output(counter, 1, data);
-	}
-
-	data->regs->ip	= orig_ip;
-	data->addr	= 0;
-
-	/* There's new data available. */
-	counter->pending_kill = POLL_IN;
-}
-
-static void x86_pmu_disable(struct perf_counter *counter)
-{
-	struct cpu_hw_counters *cpuc = &__get_cpu_var(cpu_hw_counters);
-	struct hw_perf_counter *hwc = &counter->hw;
-	int idx = hwc->idx;
-
-	/*
-	 * Must be done before we disable, otherwise the nmi handler
-	 * could reenable again:
-	 */
-	clear_bit(idx, cpuc->active_mask);
-	x86_pmu.disable(hwc, idx);
-
-	/*
-	 * Make sure the cleared pointer becomes visible before we
-	 * (potentially) free the counter:
-	 */
-	barrier();
-
-	/*
-	 * Drain the remaining delta count out of a counter
-	 * that we are disabling:
-	 */
-	x86_perf_counter_update(counter, hwc, idx);
-
-	/* Drain the remaining BTS records. */
-	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
-		struct perf_sample_data data;
-		struct pt_regs regs;
-
-		data.regs = &regs;
-		intel_pmu_drain_bts_buffer(cpuc, &data);
-	}
-	cpuc->counters[idx] = NULL;
-	clear_bit(idx, cpuc->used_mask);
-
-	perf_counter_update_userpage(counter);
-}
-
-/*
- * Save and restart an expired counter. Called by NMI contexts,
- * so it has to be careful about preempting normal counter ops:
- */
-static int intel_pmu_save_and_restart(struct perf_counter *counter)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-	int idx = hwc->idx;
-	int ret;
-
-	x86_perf_counter_update(counter, hwc, idx);
-	ret = x86_perf_counter_set_period(counter, hwc, idx);
-
-	if (counter->state == PERF_COUNTER_STATE_ACTIVE)
-		intel_pmu_enable_counter(hwc, idx);
-
-	return ret;
-}
-
-static void intel_pmu_reset(void)
-{
-	struct debug_store *ds = __get_cpu_var(cpu_hw_counters).ds;
-	unsigned long flags;
-	int idx;
-
-	if (!x86_pmu.num_counters)
-		return;
-
-	local_irq_save(flags);
-
-	printk("clearing PMU state on CPU#%d\n", smp_processor_id());
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
-		checking_wrmsrl(x86_pmu.perfctr  + idx, 0ull);
-	}
-	for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) {
-		checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
-	}
-	if (ds)
-		ds->bts_index = ds->bts_buffer_base;
-
-	local_irq_restore(flags);
-}
-
-static int p6_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_counters *cpuc;
-	struct perf_counter *counter;
-	struct hw_perf_counter *hwc;
-	int idx, handled = 0;
-	u64 val;
-
-	data.regs = regs;
-	data.addr = 0;
-
-	cpuc = &__get_cpu_var(cpu_hw_counters);
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-
-		counter = cpuc->counters[idx];
-		hwc = &counter->hw;
-
-		val = x86_perf_counter_update(counter, hwc, idx);
-		if (val & (1ULL << (x86_pmu.counter_bits - 1)))
-			continue;
-
-		/*
-		 * counter overflow
-		 */
-		handled		= 1;
-		data.period	= counter->hw.last_period;
-
-		if (!x86_perf_counter_set_period(counter, hwc, idx))
-			continue;
-
-		if (perf_counter_overflow(counter, 1, &data))
-			p6_pmu_disable_counter(hwc, idx);
-	}
-
-	if (handled)
-		inc_irq_stat(apic_perf_irqs);
-
-	return handled;
-}
-
-/*
- * This handler is triggered by the local APIC, so the APIC IRQ handling
- * rules apply:
- */
-static int intel_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_counters *cpuc;
-	int bit, loops;
-	u64 ack, status;
-
-	data.regs = regs;
-	data.addr = 0;
-
-	cpuc = &__get_cpu_var(cpu_hw_counters);
-
-	perf_disable();
-	intel_pmu_drain_bts_buffer(cpuc, &data);
-	status = intel_pmu_get_status();
-	if (!status) {
-		perf_enable();
-		return 0;
-	}
-
-	loops = 0;
-again:
-	if (++loops > 100) {
-		WARN_ONCE(1, "perfcounters: irq loop stuck!\n");
-		perf_counter_print_debug();
-		intel_pmu_reset();
-		perf_enable();
-		return 1;
-	}
-
-	inc_irq_stat(apic_perf_irqs);
-	ack = status;
-	for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
-		struct perf_counter *counter = cpuc->counters[bit];
-
-		clear_bit(bit, (unsigned long *) &status);
-		if (!test_bit(bit, cpuc->active_mask))
-			continue;
-
-		if (!intel_pmu_save_and_restart(counter))
-			continue;
-
-		data.period = counter->hw.last_period;
-
-		if (perf_counter_overflow(counter, 1, &data))
-			intel_pmu_disable_counter(&counter->hw, bit);
-	}
-
-	intel_pmu_ack_status(ack);
-
-	/*
-	 * Repeat if there is more work to be done:
-	 */
-	status = intel_pmu_get_status();
-	if (status)
-		goto again;
-
-	perf_enable();
-
-	return 1;
-}
-
-static int amd_pmu_handle_irq(struct pt_regs *regs)
-{
-	struct perf_sample_data data;
-	struct cpu_hw_counters *cpuc;
-	struct perf_counter *counter;
-	struct hw_perf_counter *hwc;
-	int idx, handled = 0;
-	u64 val;
-
-	data.regs = regs;
-	data.addr = 0;
-
-	cpuc = &__get_cpu_var(cpu_hw_counters);
-
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
-		if (!test_bit(idx, cpuc->active_mask))
-			continue;
-
-		counter = cpuc->counters[idx];
-		hwc = &counter->hw;
-
-		val = x86_perf_counter_update(counter, hwc, idx);
-		if (val & (1ULL << (x86_pmu.counter_bits - 1)))
-			continue;
-
-		/*
-		 * counter overflow
-		 */
-		handled		= 1;
-		data.period	= counter->hw.last_period;
-
-		if (!x86_perf_counter_set_period(counter, hwc, idx))
-			continue;
-
-		if (perf_counter_overflow(counter, 1, &data))
-			amd_pmu_disable_counter(hwc, idx);
-	}
-
-	if (handled)
-		inc_irq_stat(apic_perf_irqs);
-
-	return handled;
-}
-
-void smp_perf_pending_interrupt(struct pt_regs *regs)
-{
-	irq_enter();
-	ack_APIC_irq();
-	inc_irq_stat(apic_pending_irqs);
-	perf_counter_do_pending();
-	irq_exit();
-}
-
-void set_perf_counter_pending(void)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
-	apic->send_IPI_self(LOCAL_PENDING_VECTOR);
-#endif
-}
-
-void perf_counters_lapic_init(void)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
-	if (!x86_pmu.apic || !x86_pmu_initialized())
-		return;
-
-	/*
-	 * Always use NMI for PMU
-	 */
-	apic_write(APIC_LVTPC, APIC_DM_NMI);
-#endif
-}
-
-static int __kprobes
-perf_counter_nmi_handler(struct notifier_block *self,
-			 unsigned long cmd, void *__args)
-{
-	struct die_args *args = __args;
-	struct pt_regs *regs;
-
-	if (!atomic_read(&active_counters))
-		return NOTIFY_DONE;
-
-	switch (cmd) {
-	case DIE_NMI:
-	case DIE_NMI_IPI:
-		break;
-
-	default:
-		return NOTIFY_DONE;
-	}
-
-	regs = args->regs;
-
-#ifdef CONFIG_X86_LOCAL_APIC
-	apic_write(APIC_LVTPC, APIC_DM_NMI);
-#endif
-	/*
-	 * Can't rely on the handled return value to say it was our NMI, two
-	 * counters could trigger 'simultaneously' raising two back-to-back NMIs.
-	 *
-	 * If the first NMI handles both, the latter will be empty and daze
-	 * the CPU.
-	 */
-	x86_pmu.handle_irq(regs);
-
-	return NOTIFY_STOP;
-}
-
-static __read_mostly struct notifier_block perf_counter_nmi_notifier = {
-	.notifier_call		= perf_counter_nmi_handler,
-	.next			= NULL,
-	.priority		= 1
-};
-
-static struct x86_pmu p6_pmu = {
-	.name			= "p6",
-	.handle_irq		= p6_pmu_handle_irq,
-	.disable_all		= p6_pmu_disable_all,
-	.enable_all		= p6_pmu_enable_all,
-	.enable			= p6_pmu_enable_counter,
-	.disable		= p6_pmu_disable_counter,
-	.eventsel		= MSR_P6_EVNTSEL0,
-	.perfctr		= MSR_P6_PERFCTR0,
-	.event_map		= p6_pmu_event_map,
-	.raw_event		= p6_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(p6_perfmon_event_map),
-	.apic			= 1,
-	.max_period		= (1ULL << 31) - 1,
-	.version		= 0,
-	.num_counters		= 2,
-	/*
-	 * Counters have 40 bits implemented. However they are designed such
-	 * that bits [32-39] are sign extensions of bit 31. As such the
-	 * effective width of a counter for P6-like PMU is 32 bits only.
-	 *
-	 * See IA-32 Intel Architecture Software developer manual Vol 3B
-	 */
-	.counter_bits		= 32,
-	.counter_mask		= (1ULL << 32) - 1,
-};
-
-static struct x86_pmu intel_pmu = {
-	.name			= "Intel",
-	.handle_irq		= intel_pmu_handle_irq,
-	.disable_all		= intel_pmu_disable_all,
-	.enable_all		= intel_pmu_enable_all,
-	.enable			= intel_pmu_enable_counter,
-	.disable		= intel_pmu_disable_counter,
-	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
-	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
-	.event_map		= intel_pmu_event_map,
-	.raw_event		= intel_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
-	.apic			= 1,
-	/*
-	 * Intel PMCs cannot be accessed sanely above 32 bit width,
-	 * so we install an artificial 1<<31 period regardless of
-	 * the generic counter period:
-	 */
-	.max_period		= (1ULL << 31) - 1,
-	.enable_bts		= intel_pmu_enable_bts,
-	.disable_bts		= intel_pmu_disable_bts,
-};
-
-static struct x86_pmu amd_pmu = {
-	.name			= "AMD",
-	.handle_irq		= amd_pmu_handle_irq,
-	.disable_all		= amd_pmu_disable_all,
-	.enable_all		= amd_pmu_enable_all,
-	.enable			= amd_pmu_enable_counter,
-	.disable		= amd_pmu_disable_counter,
-	.eventsel		= MSR_K7_EVNTSEL0,
-	.perfctr		= MSR_K7_PERFCTR0,
-	.event_map		= amd_pmu_event_map,
-	.raw_event		= amd_pmu_raw_event,
-	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
-	.num_counters		= 4,
-	.counter_bits		= 48,
-	.counter_mask		= (1ULL << 48) - 1,
-	.apic			= 1,
-	/* use highest bit to detect overflow */
-	.max_period		= (1ULL << 47) - 1,
-};
-
-static int p6_pmu_init(void)
-{
-	switch (boot_cpu_data.x86_model) {
-	case 1:
-	case 3:  /* Pentium Pro */
-	case 5:
-	case 6:  /* Pentium II */
-	case 7:
-	case 8:
-	case 11: /* Pentium III */
-		break;
-	case 9:
-	case 13:
-		/* Pentium M */
-		break;
-	default:
-		pr_cont("unsupported p6 CPU model %d ",
-			boot_cpu_data.x86_model);
-		return -ENODEV;
-	}
-
-	x86_pmu = p6_pmu;
-
-	if (!cpu_has_apic) {
-		pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
-		pr_info("no hardware sampling interrupt available.\n");
-		x86_pmu.apic = 0;
-	}
-
-	return 0;
-}
-
-static int intel_pmu_init(void)
-{
-	union cpuid10_edx edx;
-	union cpuid10_eax eax;
-	unsigned int unused;
-	unsigned int ebx;
-	int version;
-
-	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
-		/* check for P6 processor family */
-	   if (boot_cpu_data.x86 == 6) {
-		return p6_pmu_init();
-	   } else {
-		return -ENODEV;
-	   }
-	}
-
-	/*
-	 * Check whether the Architectural PerfMon supports
-	 * Branch Misses Retired Event or not.
-	 */
-	cpuid(10, &eax.full, &ebx, &unused, &edx.full);
-	if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED)
-		return -ENODEV;
-
-	version = eax.split.version_id;
-	if (version < 2)
-		return -ENODEV;
-
-	x86_pmu				= intel_pmu;
-	x86_pmu.version			= version;
-	x86_pmu.num_counters		= eax.split.num_counters;
-	x86_pmu.counter_bits		= eax.split.bit_width;
-	x86_pmu.counter_mask		= (1ULL << eax.split.bit_width) - 1;
-
-	/*
-	 * Quirk: v2 perfmon does not report fixed-purpose counters, so
-	 * assume at least 3 counters:
-	 */
-	x86_pmu.num_counters_fixed	= max((int)edx.split.num_counters_fixed, 3);
-
-	/*
-	 * Install the hw-cache-events table:
-	 */
-	switch (boot_cpu_data.x86_model) {
-	case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
-	case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
-	case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
-	case 29: /* six-core 45 nm xeon "Dunnington" */
-		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-
-		pr_cont("Core2 events, ");
-		break;
-	default:
-	case 26:
-		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-
-		pr_cont("Nehalem/Corei7 events, ");
-		break;
-	case 28:
-		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
-		       sizeof(hw_cache_event_ids));
-
-		pr_cont("Atom events, ");
-		break;
-	}
-	return 0;
-}
-
-static int amd_pmu_init(void)
-{
-	/* Performance-monitoring supported from K7 and later: */
-	if (boot_cpu_data.x86 < 6)
-		return -ENODEV;
-
-	x86_pmu = amd_pmu;
-
-	/* Events are common for all AMDs */
-	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
-	       sizeof(hw_cache_event_ids));
-
-	return 0;
-}
-
-void __init init_hw_perf_counters(void)
-{
-	int err;
-
-	pr_info("Performance Counters: ");
-
-	switch (boot_cpu_data.x86_vendor) {
-	case X86_VENDOR_INTEL:
-		err = intel_pmu_init();
-		break;
-	case X86_VENDOR_AMD:
-		err = amd_pmu_init();
-		break;
-	default:
-		return;
-	}
-	if (err != 0) {
-		pr_cont("no PMU driver, software counters only.\n");
-		return;
-	}
-
-	pr_cont("%s PMU driver.\n", x86_pmu.name);
-
-	if (x86_pmu.num_counters > X86_PMC_MAX_GENERIC) {
-		WARN(1, KERN_ERR "hw perf counters %d > max(%d), clipping!",
-		     x86_pmu.num_counters, X86_PMC_MAX_GENERIC);
-		x86_pmu.num_counters = X86_PMC_MAX_GENERIC;
-	}
-	perf_counter_mask = (1 << x86_pmu.num_counters) - 1;
-	perf_max_counters = x86_pmu.num_counters;
-
-	if (x86_pmu.num_counters_fixed > X86_PMC_MAX_FIXED) {
-		WARN(1, KERN_ERR "hw perf counters fixed %d > max(%d), clipping!",
-		     x86_pmu.num_counters_fixed, X86_PMC_MAX_FIXED);
-		x86_pmu.num_counters_fixed = X86_PMC_MAX_FIXED;
-	}
-
-	perf_counter_mask |=
-		((1LL << x86_pmu.num_counters_fixed)-1) << X86_PMC_IDX_FIXED;
-	x86_pmu.intel_ctrl = perf_counter_mask;
-
-	perf_counters_lapic_init();
-	register_die_notifier(&perf_counter_nmi_notifier);
-
-	pr_info("... version:                 %d\n",     x86_pmu.version);
-	pr_info("... bit width:               %d\n",     x86_pmu.counter_bits);
-	pr_info("... generic counters:        %d\n",     x86_pmu.num_counters);
-	pr_info("... value mask:              %016Lx\n", x86_pmu.counter_mask);
-	pr_info("... max period:              %016Lx\n", x86_pmu.max_period);
-	pr_info("... fixed-purpose counters:  %d\n",     x86_pmu.num_counters_fixed);
-	pr_info("... counter mask:            %016Lx\n", perf_counter_mask);
-}
-
-static inline void x86_pmu_read(struct perf_counter *counter)
-{
-	x86_perf_counter_update(counter, &counter->hw, counter->hw.idx);
-}
-
-static const struct pmu pmu = {
-	.enable		= x86_pmu_enable,
-	.disable	= x86_pmu_disable,
-	.read		= x86_pmu_read,
-	.unthrottle	= x86_pmu_unthrottle,
-};
-
-const struct pmu *hw_perf_counter_init(struct perf_counter *counter)
-{
-	int err;
-
-	err = __hw_perf_counter_init(counter);
-	if (err)
-		return ERR_PTR(err);
-
-	return &pmu;
-}
-
-/*
- * callchain support
- */
-
-static inline
-void callchain_store(struct perf_callchain_entry *entry, u64 ip)
-{
-	if (entry->nr < PERF_MAX_STACK_DEPTH)
-		entry->ip[entry->nr++] = ip;
-}
-
-static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry);
-static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry);
-static DEFINE_PER_CPU(int, in_nmi_frame);
-
-
-static void
-backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-	/* Ignore warnings */
-}
-
-static void backtrace_warning(void *data, char *msg)
-{
-	/* Ignore warnings */
-}
-
-static int backtrace_stack(void *data, char *name)
-{
-	per_cpu(in_nmi_frame, smp_processor_id()) =
-			x86_is_stack_id(NMI_STACK, name);
-
-	return 0;
-}
-
-static void backtrace_address(void *data, unsigned long addr, int reliable)
-{
-	struct perf_callchain_entry *entry = data;
-
-	if (per_cpu(in_nmi_frame, smp_processor_id()))
-		return;
-
-	if (reliable)
-		callchain_store(entry, addr);
-}
-
-static const struct stacktrace_ops backtrace_ops = {
-	.warning		= backtrace_warning,
-	.warning_symbol		= backtrace_warning_symbol,
-	.stack			= backtrace_stack,
-	.address		= backtrace_address,
-};
-
-#include "../dumpstack.h"
-
-static void
-perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
-	callchain_store(entry, PERF_CONTEXT_KERNEL);
-	callchain_store(entry, regs->ip);
-
-	dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry);
-}
-
-/*
- * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
- */
-static unsigned long
-copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
-{
-	unsigned long offset, addr = (unsigned long)from;
-	int type = in_nmi() ? KM_NMI : KM_IRQ0;
-	unsigned long size, len = 0;
-	struct page *page;
-	void *map;
-	int ret;
-
-	do {
-		ret = __get_user_pages_fast(addr, 1, 0, &page);
-		if (!ret)
-			break;
-
-		offset = addr & (PAGE_SIZE - 1);
-		size = min(PAGE_SIZE - offset, n - len);
-
-		map = kmap_atomic(page, type);
-		memcpy(to, map+offset, size);
-		kunmap_atomic(map, type);
-		put_page(page);
-
-		len  += size;
-		to   += size;
-		addr += size;
-
-	} while (len < n);
-
-	return len;
-}
-
-static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
-{
-	unsigned long bytes;
-
-	bytes = copy_from_user_nmi(frame, fp, sizeof(*frame));
-
-	return bytes == sizeof(*frame);
-}
-
-static void
-perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
-	struct stack_frame frame;
-	const void __user *fp;
-
-	if (!user_mode(regs))
-		regs = task_pt_regs(current);
-
-	fp = (void __user *)regs->bp;
-
-	callchain_store(entry, PERF_CONTEXT_USER);
-	callchain_store(entry, regs->ip);
-
-	while (entry->nr < PERF_MAX_STACK_DEPTH) {
-		frame.next_frame	     = NULL;
-		frame.return_address = 0;
-
-		if (!copy_stack_frame(fp, &frame))
-			break;
-
-		if ((unsigned long)fp < regs->sp)
-			break;
-
-		callchain_store(entry, frame.return_address);
-		fp = frame.next_frame;
-	}
-}
-
-static void
-perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
-{
-	int is_user;
-
-	if (!regs)
-		return;
-
-	is_user = user_mode(regs);
-
-	if (!current || current->pid == 0)
-		return;
-
-	if (is_user && current->state != TASK_RUNNING)
-		return;
-
-	if (!is_user)
-		perf_callchain_kernel(regs, entry);
-
-	if (current->mm)
-		perf_callchain_user(regs, entry);
-}
-
-struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
-{
-	struct perf_callchain_entry *entry;
-
-	if (in_nmi())
-		entry = &__get_cpu_var(nmi_entry);
-	else
-		entry = &__get_cpu_var(irq_entry);
-
-	entry->nr = 0;
-
-	perf_do_callchain(regs, entry);
-
-	return entry;
-}
-
-void hw_perf_counter_setup_online(int cpu)
-{
-	init_debug_store_on_cpu(cpu);
-}
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
new file mode 100644
index 0000000..a3c7adb
--- /dev/null
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -0,0 +1,2298 @@
+/*
+ * Performance events x86 architecture code
+ *
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+
+#include <linux/perf_event.h>
+#include <linux/capability.h>
+#include <linux/notifier.h>
+#include <linux/hardirq.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/kdebug.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/highmem.h>
+#include <linux/cpu.h>
+
+#include <asm/apic.h>
+#include <asm/stacktrace.h>
+#include <asm/nmi.h>
+
+static u64 perf_event_mask __read_mostly;
+
+/* The maximal number of PEBS events: */
+#define MAX_PEBS_EVENTS	4
+
+/* The size of a BTS record in bytes: */
+#define BTS_RECORD_SIZE		24
+
+/* The size of a per-cpu BTS buffer in bytes: */
+#define BTS_BUFFER_SIZE		(BTS_RECORD_SIZE * 2048)
+
+/* The BTS overflow threshold in bytes from the end of the buffer: */
+#define BTS_OVFL_TH		(BTS_RECORD_SIZE * 128)
+
+
+/*
+ * Bits in the debugctlmsr controlling branch tracing.
+ */
+#define X86_DEBUGCTL_TR			(1 << 6)
+#define X86_DEBUGCTL_BTS		(1 << 7)
+#define X86_DEBUGCTL_BTINT		(1 << 8)
+#define X86_DEBUGCTL_BTS_OFF_OS		(1 << 9)
+#define X86_DEBUGCTL_BTS_OFF_USR	(1 << 10)
+
+/*
+ * A debug store configuration.
+ *
+ * We only support architectures that use 64bit fields.
+ */
+struct debug_store {
+	u64	bts_buffer_base;
+	u64	bts_index;
+	u64	bts_absolute_maximum;
+	u64	bts_interrupt_threshold;
+	u64	pebs_buffer_base;
+	u64	pebs_index;
+	u64	pebs_absolute_maximum;
+	u64	pebs_interrupt_threshold;
+	u64	pebs_event_reset[MAX_PEBS_EVENTS];
+};
+
+struct cpu_hw_events {
+	struct perf_event	*events[X86_PMC_IDX_MAX];
+	unsigned long		used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	unsigned long		active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	unsigned long		interrupts;
+	int			enabled;
+	struct debug_store	*ds;
+};
+
+/*
+ * struct x86_pmu - generic x86 pmu
+ */
+struct x86_pmu {
+	const char	*name;
+	int		version;
+	int		(*handle_irq)(struct pt_regs *);
+	void		(*disable_all)(void);
+	void		(*enable_all)(void);
+	void		(*enable)(struct hw_perf_event *, int);
+	void		(*disable)(struct hw_perf_event *, int);
+	unsigned	eventsel;
+	unsigned	perfctr;
+	u64		(*event_map)(int);
+	u64		(*raw_event)(u64);
+	int		max_events;
+	int		num_events;
+	int		num_events_fixed;
+	int		event_bits;
+	u64		event_mask;
+	int		apic;
+	u64		max_period;
+	u64		intel_ctrl;
+	void		(*enable_bts)(u64 config);
+	void		(*disable_bts)(void);
+};
+
+static struct x86_pmu x86_pmu __read_mostly;
+
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
+	.enabled = 1,
+};
+
+/*
+ * Not sure about some of these
+ */
+static const u64 p6_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0079,
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0f2e,
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x012e,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+  [PERF_COUNT_HW_BUS_CYCLES]		= 0x0062,
+};
+
+static u64 p6_pmu_event_map(int hw_event)
+{
+	return p6_perfmon_event_map[hw_event];
+}
+
+/*
+ * Event setting that is specified not to count anything.
+ * We use this to effectively disable a counter.
+ *
+ * L2_RQSTS with 0 MESI unit mask.
+ */
+#define P6_NOP_EVENT			0x0000002EULL
+
+static u64 p6_pmu_raw_event(u64 hw_event)
+{
+#define P6_EVNTSEL_EVENT_MASK		0x000000FFULL
+#define P6_EVNTSEL_UNIT_MASK		0x0000FF00ULL
+#define P6_EVNTSEL_EDGE_MASK		0x00040000ULL
+#define P6_EVNTSEL_INV_MASK		0x00800000ULL
+#define P6_EVNTSEL_REG_MASK		0xFF000000ULL
+
+#define P6_EVNTSEL_MASK			\
+	(P6_EVNTSEL_EVENT_MASK |	\
+	 P6_EVNTSEL_UNIT_MASK  |	\
+	 P6_EVNTSEL_EDGE_MASK  |	\
+	 P6_EVNTSEL_INV_MASK   |	\
+	 P6_EVNTSEL_REG_MASK)
+
+	return hw_event & P6_EVNTSEL_MASK;
+}
+
+
+/*
+ * Intel PerfMon v3. Used on Core2 and later.
+ */
+static const u64 intel_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x003c,
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x4f2e,
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x412e,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+  [PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
+};
+
+static u64 intel_pmu_event_map(int hw_event)
+{
+	return intel_perfmon_event_map[hw_event];
+}
+
+/*
+ * Generalized hw caching related hw_event table, filled
+ * in on a per model basis. A value of 0 means
+ * 'not supported', -1 means 'hw_event makes no sense on
+ * this CPU', any other value means the raw hw_event
+ * ID.
+ */
+
+#define C(x) PERF_COUNT_HW_CACHE_##x
+
+static u64 __read_mostly hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX];
+
+static const u64 nehalem_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI            */
+		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE         */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI            */
+		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE         */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS        */
+		[ C(RESULT_MISS)   ] = 0x024e, /* L1D_PREFETCH.MISS            */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                    */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0324, /* L2_RQSTS.LOADS               */
+		[ C(RESULT_MISS)   ] = 0x0224, /* L2_RQSTS.LD_MISS             */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0c24, /* L2_RQSTS.RFOS                */
+		[ C(RESULT_MISS)   ] = 0x0824, /* L2_RQSTS.RFO_MISS            */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2e, /* LLC Reference                */
+		[ C(RESULT_MISS)   ] = 0x412e, /* LLC Misses                   */
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI   (alias)  */
+		[ C(RESULT_MISS)   ] = 0x0108, /* DTLB_LOAD_MISSES.ANY         */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI   (alias)  */
+		[ C(RESULT_MISS)   ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS  */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0x0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P           */
+		[ C(RESULT_MISS)   ] = 0x20c8, /* ITLB_MISS_RETIRED            */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
+		[ C(RESULT_MISS)   ] = 0x03e8, /* BPU_CLEARS.ANY               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static const u64 core2_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI          */
+		[ C(RESULT_MISS)   ] = 0x0140, /* L1D_CACHE_LD.I_STATE       */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI          */
+		[ C(RESULT_MISS)   ] = 0x0141, /* L1D_CACHE_ST.I_STATE       */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS      */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS                  */
+		[ C(RESULT_MISS)   ] = 0x0081, /* L1I.MISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0208, /* DTLB_MISSES.MISS_LD        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0808, /* DTLB_MISSES.MISS_ST        */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
+		[ C(RESULT_MISS)   ] = 0x1282, /* ITLBMISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static const u64 atom_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD               */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST               */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS                  */
+		[ C(RESULT_MISS)   ] = 0x0280, /* L1I.MISSES                 */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x4129, /* L2_LD.ISTATE               */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI                 */
+		[ C(RESULT_MISS)   ] = 0x412A, /* L2_ST.ISTATE               */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0508, /* DTLB_MISSES.MISS_LD        */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI  (alias) */
+		[ C(RESULT_MISS)   ] = 0x0608, /* DTLB_MISSES.MISS_ST        */
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P         */
+		[ C(RESULT_MISS)   ] = 0x0282, /* ITLB.MISSES                */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY        */
+		[ C(RESULT_MISS)   ] = 0x00c5, /* BP_INST_RETIRED.MISPRED    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+static u64 intel_pmu_raw_event(u64 hw_event)
+{
+#define CORE_EVNTSEL_EVENT_MASK		0x000000FFULL
+#define CORE_EVNTSEL_UNIT_MASK		0x0000FF00ULL
+#define CORE_EVNTSEL_EDGE_MASK		0x00040000ULL
+#define CORE_EVNTSEL_INV_MASK		0x00800000ULL
+#define CORE_EVNTSEL_REG_MASK	0xFF000000ULL
+
+#define CORE_EVNTSEL_MASK		\
+	(CORE_EVNTSEL_EVENT_MASK |	\
+	 CORE_EVNTSEL_UNIT_MASK  |	\
+	 CORE_EVNTSEL_EDGE_MASK  |	\
+	 CORE_EVNTSEL_INV_MASK  |	\
+	 CORE_EVNTSEL_REG_MASK)
+
+	return hw_event & CORE_EVNTSEL_MASK;
+}
+
+static const u64 amd_hw_cache_event_ids
+				[PERF_COUNT_HW_CACHE_MAX]
+				[PERF_COUNT_HW_CACHE_OP_MAX]
+				[PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(L1D) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
+		[ C(RESULT_MISS)   ] = 0x0041, /* Data Cache Misses          */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0267, /* Data Prefetcher :attempts  */
+		[ C(RESULT_MISS)   ] = 0x0167, /* Data Prefetcher :cancelled */
+	},
+ },
+ [ C(L1I ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction cache fetches  */
+		[ C(RESULT_MISS)   ] = 0x0081, /* Instruction cache misses   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0x014B, /* Prefetch Instructions :Load */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(LL  ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x037D, /* Requests to L2 Cache :IC+DC */
+		[ C(RESULT_MISS)   ] = 0x037E, /* L2 Cache Misses : IC+DC     */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0x017F, /* L2 Fill/Writeback           */
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(DTLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses        */
+		[ C(RESULT_MISS)   ] = 0x0046, /* L1 DTLB and L2 DLTB Miss   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = 0,
+		[ C(RESULT_MISS)   ] = 0,
+	},
+ },
+ [ C(ITLB) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x0080, /* Instruction fecthes        */
+		[ C(RESULT_MISS)   ] = 0x0085, /* Instr. fetch ITLB misses   */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+ [ C(BPU ) ] = {
+	[ C(OP_READ) ] = {
+		[ C(RESULT_ACCESS) ] = 0x00c2, /* Retired Branch Instr.      */
+		[ C(RESULT_MISS)   ] = 0x00c3, /* Retired Mispredicted BI    */
+	},
+	[ C(OP_WRITE) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+	[ C(OP_PREFETCH) ] = {
+		[ C(RESULT_ACCESS) ] = -1,
+		[ C(RESULT_MISS)   ] = -1,
+	},
+ },
+};
+
+/*
+ * AMD Performance Monitor K7 and later.
+ */
+static const u64 amd_perfmon_event_map[] =
+{
+  [PERF_COUNT_HW_CPU_CYCLES]		= 0x0076,
+  [PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+  [PERF_COUNT_HW_CACHE_REFERENCES]	= 0x0080,
+  [PERF_COUNT_HW_CACHE_MISSES]		= 0x0081,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c4,
+  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c5,
+};
+
+static u64 amd_pmu_event_map(int hw_event)
+{
+	return amd_perfmon_event_map[hw_event];
+}
+
+static u64 amd_pmu_raw_event(u64 hw_event)
+{
+#define K7_EVNTSEL_EVENT_MASK	0x7000000FFULL
+#define K7_EVNTSEL_UNIT_MASK	0x00000FF00ULL
+#define K7_EVNTSEL_EDGE_MASK	0x000040000ULL
+#define K7_EVNTSEL_INV_MASK	0x000800000ULL
+#define K7_EVNTSEL_REG_MASK	0x0FF000000ULL
+
+#define K7_EVNTSEL_MASK			\
+	(K7_EVNTSEL_EVENT_MASK |	\
+	 K7_EVNTSEL_UNIT_MASK  |	\
+	 K7_EVNTSEL_EDGE_MASK  |	\
+	 K7_EVNTSEL_INV_MASK   |	\
+	 K7_EVNTSEL_REG_MASK)
+
+	return hw_event & K7_EVNTSEL_MASK;
+}
+
+/*
+ * Propagate event elapsed time into the generic event.
+ * Can only be executed on the CPU where the event is active.
+ * Returns the delta events processed.
+ */
+static u64
+x86_perf_event_update(struct perf_event *event,
+			struct hw_perf_event *hwc, int idx)
+{
+	int shift = 64 - x86_pmu.event_bits;
+	u64 prev_raw_count, new_raw_count;
+	s64 delta;
+
+	if (idx == X86_PMC_IDX_FIXED_BTS)
+		return 0;
+
+	/*
+	 * Careful: an NMI might modify the previous event value.
+	 *
+	 * Our tactic to handle this is to first atomically read and
+	 * exchange a new raw count - then add that new-prev delta
+	 * count to the generic event atomically:
+	 */
+again:
+	prev_raw_count = atomic64_read(&hwc->prev_count);
+	rdmsrl(hwc->event_base + idx, new_raw_count);
+
+	if (atomic64_cmpxchg(&hwc->prev_count, prev_raw_count,
+					new_raw_count) != prev_raw_count)
+		goto again;
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (event-)time and add that to the generic event.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	atomic64_add(delta, &event->count);
+	atomic64_sub(delta, &hwc->period_left);
+
+	return new_raw_count;
+}
+
+static atomic_t active_events;
+static DEFINE_MUTEX(pmc_reserve_mutex);
+
+static bool reserve_pmc_hardware(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	int i;
+
+	if (nmi_watchdog == NMI_LOCAL_APIC)
+		disable_lapic_nmi_watchdog();
+
+	for (i = 0; i < x86_pmu.num_events; i++) {
+		if (!reserve_perfctr_nmi(x86_pmu.perfctr + i))
+			goto perfctr_fail;
+	}
+
+	for (i = 0; i < x86_pmu.num_events; i++) {
+		if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
+			goto eventsel_fail;
+	}
+#endif
+
+	return true;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+eventsel_fail:
+	for (i--; i >= 0; i--)
+		release_evntsel_nmi(x86_pmu.eventsel + i);
+
+	i = x86_pmu.num_events;
+
+perfctr_fail:
+	for (i--; i >= 0; i--)
+		release_perfctr_nmi(x86_pmu.perfctr + i);
+
+	if (nmi_watchdog == NMI_LOCAL_APIC)
+		enable_lapic_nmi_watchdog();
+
+	return false;
+#endif
+}
+
+static void release_pmc_hardware(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	int i;
+
+	for (i = 0; i < x86_pmu.num_events; i++) {
+		release_perfctr_nmi(x86_pmu.perfctr + i);
+		release_evntsel_nmi(x86_pmu.eventsel + i);
+	}
+
+	if (nmi_watchdog == NMI_LOCAL_APIC)
+		enable_lapic_nmi_watchdog();
+#endif
+}
+
+static inline bool bts_available(void)
+{
+	return x86_pmu.enable_bts != NULL;
+}
+
+static inline void init_debug_store_on_cpu(int cpu)
+{
+	struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+	if (!ds)
+		return;
+
+	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA,
+		     (u32)((u64)(unsigned long)ds),
+		     (u32)((u64)(unsigned long)ds >> 32));
+}
+
+static inline void fini_debug_store_on_cpu(int cpu)
+{
+	if (!per_cpu(cpu_hw_events, cpu).ds)
+		return;
+
+	wrmsr_on_cpu(cpu, MSR_IA32_DS_AREA, 0, 0);
+}
+
+static void release_bts_hardware(void)
+{
+	int cpu;
+
+	if (!bts_available())
+		return;
+
+	get_online_cpus();
+
+	for_each_online_cpu(cpu)
+		fini_debug_store_on_cpu(cpu);
+
+	for_each_possible_cpu(cpu) {
+		struct debug_store *ds = per_cpu(cpu_hw_events, cpu).ds;
+
+		if (!ds)
+			continue;
+
+		per_cpu(cpu_hw_events, cpu).ds = NULL;
+
+		kfree((void *)(unsigned long)ds->bts_buffer_base);
+		kfree(ds);
+	}
+
+	put_online_cpus();
+}
+
+static int reserve_bts_hardware(void)
+{
+	int cpu, err = 0;
+
+	if (!bts_available())
+		return 0;
+
+	get_online_cpus();
+
+	for_each_possible_cpu(cpu) {
+		struct debug_store *ds;
+		void *buffer;
+
+		err = -ENOMEM;
+		buffer = kzalloc(BTS_BUFFER_SIZE, GFP_KERNEL);
+		if (unlikely(!buffer))
+			break;
+
+		ds = kzalloc(sizeof(*ds), GFP_KERNEL);
+		if (unlikely(!ds)) {
+			kfree(buffer);
+			break;
+		}
+
+		ds->bts_buffer_base = (u64)(unsigned long)buffer;
+		ds->bts_index = ds->bts_buffer_base;
+		ds->bts_absolute_maximum =
+			ds->bts_buffer_base + BTS_BUFFER_SIZE;
+		ds->bts_interrupt_threshold =
+			ds->bts_absolute_maximum - BTS_OVFL_TH;
+
+		per_cpu(cpu_hw_events, cpu).ds = ds;
+		err = 0;
+	}
+
+	if (err)
+		release_bts_hardware();
+	else {
+		for_each_online_cpu(cpu)
+			init_debug_store_on_cpu(cpu);
+	}
+
+	put_online_cpus();
+
+	return err;
+}
+
+static void hw_perf_event_destroy(struct perf_event *event)
+{
+	if (atomic_dec_and_mutex_lock(&active_events, &pmc_reserve_mutex)) {
+		release_pmc_hardware();
+		release_bts_hardware();
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+}
+
+static inline int x86_pmu_initialized(void)
+{
+	return x86_pmu.handle_irq != NULL;
+}
+
+static inline int
+set_ext_hw_attr(struct hw_perf_event *hwc, struct perf_event_attr *attr)
+{
+	unsigned int cache_type, cache_op, cache_result;
+	u64 config, val;
+
+	config = attr->config;
+
+	cache_type = (config >>  0) & 0xff;
+	if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+		return -EINVAL;
+
+	cache_op = (config >>  8) & 0xff;
+	if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+		return -EINVAL;
+
+	cache_result = (config >> 16) & 0xff;
+	if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+		return -EINVAL;
+
+	val = hw_cache_event_ids[cache_type][cache_op][cache_result];
+
+	if (val == 0)
+		return -ENOENT;
+
+	if (val == -1)
+		return -EINVAL;
+
+	hwc->config |= val;
+
+	return 0;
+}
+
+static void intel_pmu_enable_bts(u64 config)
+{
+	unsigned long debugctlmsr;
+
+	debugctlmsr = get_debugctlmsr();
+
+	debugctlmsr |= X86_DEBUGCTL_TR;
+	debugctlmsr |= X86_DEBUGCTL_BTS;
+	debugctlmsr |= X86_DEBUGCTL_BTINT;
+
+	if (!(config & ARCH_PERFMON_EVENTSEL_OS))
+		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_OS;
+
+	if (!(config & ARCH_PERFMON_EVENTSEL_USR))
+		debugctlmsr |= X86_DEBUGCTL_BTS_OFF_USR;
+
+	update_debugctlmsr(debugctlmsr);
+}
+
+static void intel_pmu_disable_bts(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	unsigned long debugctlmsr;
+
+	if (!cpuc->ds)
+		return;
+
+	debugctlmsr = get_debugctlmsr();
+
+	debugctlmsr &=
+		~(X86_DEBUGCTL_TR | X86_DEBUGCTL_BTS | X86_DEBUGCTL_BTINT |
+		  X86_DEBUGCTL_BTS_OFF_OS | X86_DEBUGCTL_BTS_OFF_USR);
+
+	update_debugctlmsr(debugctlmsr);
+}
+
+/*
+ * Setup the hardware configuration for a given attr_type
+ */
+static int __hw_perf_event_init(struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	struct hw_perf_event *hwc = &event->hw;
+	u64 config;
+	int err;
+
+	if (!x86_pmu_initialized())
+		return -ENODEV;
+
+	err = 0;
+	if (!atomic_inc_not_zero(&active_events)) {
+		mutex_lock(&pmc_reserve_mutex);
+		if (atomic_read(&active_events) == 0) {
+			if (!reserve_pmc_hardware())
+				err = -EBUSY;
+			else
+				err = reserve_bts_hardware();
+		}
+		if (!err)
+			atomic_inc(&active_events);
+		mutex_unlock(&pmc_reserve_mutex);
+	}
+	if (err)
+		return err;
+
+	event->destroy = hw_perf_event_destroy;
+
+	/*
+	 * Generate PMC IRQs:
+	 * (keep 'enabled' bit clear for now)
+	 */
+	hwc->config = ARCH_PERFMON_EVENTSEL_INT;
+
+	/*
+	 * Count user and OS events unless requested not to.
+	 */
+	if (!attr->exclude_user)
+		hwc->config |= ARCH_PERFMON_EVENTSEL_USR;
+	if (!attr->exclude_kernel)
+		hwc->config |= ARCH_PERFMON_EVENTSEL_OS;
+
+	if (!hwc->sample_period) {
+		hwc->sample_period = x86_pmu.max_period;
+		hwc->last_period = hwc->sample_period;
+		atomic64_set(&hwc->period_left, hwc->sample_period);
+	} else {
+		/*
+		 * If we have a PMU initialized but no APIC
+		 * interrupts, we cannot sample hardware
+		 * events (user-space has to fall back and
+		 * sample via a hrtimer based software event):
+		 */
+		if (!x86_pmu.apic)
+			return -EOPNOTSUPP;
+	}
+
+	/*
+	 * Raw hw_event type provide the config in the hw_event structure
+	 */
+	if (attr->type == PERF_TYPE_RAW) {
+		hwc->config |= x86_pmu.raw_event(attr->config);
+		return 0;
+	}
+
+	if (attr->type == PERF_TYPE_HW_CACHE)
+		return set_ext_hw_attr(hwc, attr);
+
+	if (attr->config >= x86_pmu.max_events)
+		return -EINVAL;
+
+	/*
+	 * The generic map:
+	 */
+	config = x86_pmu.event_map(attr->config);
+
+	if (config == 0)
+		return -ENOENT;
+
+	if (config == -1LL)
+		return -EINVAL;
+
+	/*
+	 * Branch tracing:
+	 */
+	if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
+	    (hwc->sample_period == 1)) {
+		/* BTS is not supported by this architecture. */
+		if (!bts_available())
+			return -EOPNOTSUPP;
+
+		/* BTS is currently only allowed for user-mode. */
+		if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
+			return -EOPNOTSUPP;
+	}
+
+	hwc->config |= config;
+
+	return 0;
+}
+
+static void p6_pmu_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	u64 val;
+
+	if (!cpuc->enabled)
+		return;
+
+	cpuc->enabled = 0;
+	barrier();
+
+	/* p6 only has one enable register */
+	rdmsrl(MSR_P6_EVNTSEL0, val);
+	val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+	wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static void intel_pmu_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	if (!cpuc->enabled)
+		return;
+
+	cpuc->enabled = 0;
+	barrier();
+
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+
+	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
+		intel_pmu_disable_bts();
+}
+
+static void amd_pmu_disable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	int idx;
+
+	if (!cpuc->enabled)
+		return;
+
+	cpuc->enabled = 0;
+	/*
+	 * ensure we write the disable before we start disabling the
+	 * events proper, so that amd_pmu_enable_event() does the
+	 * right thing.
+	 */
+	barrier();
+
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		u64 val;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+		rdmsrl(MSR_K7_EVNTSEL0 + idx, val);
+		if (!(val & ARCH_PERFMON_EVENTSEL0_ENABLE))
+			continue;
+		val &= ~ARCH_PERFMON_EVENTSEL0_ENABLE;
+		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
+	}
+}
+
+void hw_perf_disable(void)
+{
+	if (!x86_pmu_initialized())
+		return;
+	return x86_pmu.disable_all();
+}
+
+static void p6_pmu_enable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	unsigned long val;
+
+	if (cpuc->enabled)
+		return;
+
+	cpuc->enabled = 1;
+	barrier();
+
+	/* p6 only has one enable register */
+	rdmsrl(MSR_P6_EVNTSEL0, val);
+	val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+	wrmsrl(MSR_P6_EVNTSEL0, val);
+}
+
+static void intel_pmu_enable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	if (cpuc->enabled)
+		return;
+
+	cpuc->enabled = 1;
+	barrier();
+
+	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
+
+	if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
+		struct perf_event *event =
+			cpuc->events[X86_PMC_IDX_FIXED_BTS];
+
+		if (WARN_ON_ONCE(!event))
+			return;
+
+		intel_pmu_enable_bts(event->hw.config);
+	}
+}
+
+static void amd_pmu_enable_all(void)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	int idx;
+
+	if (cpuc->enabled)
+		return;
+
+	cpuc->enabled = 1;
+	barrier();
+
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		struct perf_event *event = cpuc->events[idx];
+		u64 val;
+
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		val = event->hw.config;
+		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+		wrmsrl(MSR_K7_EVNTSEL0 + idx, val);
+	}
+}
+
+void hw_perf_enable(void)
+{
+	if (!x86_pmu_initialized())
+		return;
+	x86_pmu.enable_all();
+}
+
+static inline u64 intel_pmu_get_status(void)
+{
+	u64 status;
+
+	rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+
+	return status;
+}
+
+static inline void intel_pmu_ack_status(u64 ack)
+{
+	wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
+}
+
+static inline void x86_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+	(void)checking_wrmsrl(hwc->config_base + idx,
+			      hwc->config | ARCH_PERFMON_EVENTSEL0_ENABLE);
+}
+
+static inline void x86_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+	(void)checking_wrmsrl(hwc->config_base + idx, hwc->config);
+}
+
+static inline void
+intel_pmu_disable_fixed(struct hw_perf_event *hwc, int __idx)
+{
+	int idx = __idx - X86_PMC_IDX_FIXED;
+	u64 ctrl_val, mask;
+
+	mask = 0xfULL << (idx * 4);
+
+	rdmsrl(hwc->config_base, ctrl_val);
+	ctrl_val &= ~mask;
+	(void)checking_wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static inline void
+p6_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	u64 val = P6_NOP_EVENT;
+
+	if (cpuc->enabled)
+		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+
+	(void)checking_wrmsrl(hwc->config_base + idx, val);
+}
+
+static inline void
+intel_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
+		intel_pmu_disable_bts();
+		return;
+	}
+
+	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+		intel_pmu_disable_fixed(hwc, idx);
+		return;
+	}
+
+	x86_pmu_disable_event(hwc, idx);
+}
+
+static inline void
+amd_pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+	x86_pmu_disable_event(hwc, idx);
+}
+
+static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left);
+
+/*
+ * Set the next IRQ period, based on the hwc->period_left value.
+ * To be called with the event disabled in hw:
+ */
+static int
+x86_perf_event_set_period(struct perf_event *event,
+			     struct hw_perf_event *hwc, int idx)
+{
+	s64 left = atomic64_read(&hwc->period_left);
+	s64 period = hwc->sample_period;
+	int err, ret = 0;
+
+	if (idx == X86_PMC_IDX_FIXED_BTS)
+		return 0;
+
+	/*
+	 * If we are way outside a reasoable range then just skip forward:
+	 */
+	if (unlikely(left <= -period)) {
+		left = period;
+		atomic64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+
+	if (unlikely(left <= 0)) {
+		left += period;
+		atomic64_set(&hwc->period_left, left);
+		hwc->last_period = period;
+		ret = 1;
+	}
+	/*
+	 * Quirk: certain CPUs dont like it if just 1 hw_event is left:
+	 */
+	if (unlikely(left < 2))
+		left = 2;
+
+	if (left > x86_pmu.max_period)
+		left = x86_pmu.max_period;
+
+	per_cpu(pmc_prev_left[idx], smp_processor_id()) = left;
+
+	/*
+	 * The hw event starts counting from this event offset,
+	 * mark it to be able to extra future deltas:
+	 */
+	atomic64_set(&hwc->prev_count, (u64)-left);
+
+	err = checking_wrmsrl(hwc->event_base + idx,
+			     (u64)(-left) & x86_pmu.event_mask);
+
+	perf_event_update_userpage(event);
+
+	return ret;
+}
+
+static inline void
+intel_pmu_enable_fixed(struct hw_perf_event *hwc, int __idx)
+{
+	int idx = __idx - X86_PMC_IDX_FIXED;
+	u64 ctrl_val, bits, mask;
+	int err;
+
+	/*
+	 * Enable IRQ generation (0x8),
+	 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
+	 * if requested:
+	 */
+	bits = 0x8ULL;
+	if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
+		bits |= 0x2;
+	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
+		bits |= 0x1;
+	bits <<= (idx * 4);
+	mask = 0xfULL << (idx * 4);
+
+	rdmsrl(hwc->config_base, ctrl_val);
+	ctrl_val &= ~mask;
+	ctrl_val |= bits;
+	err = checking_wrmsrl(hwc->config_base, ctrl_val);
+}
+
+static void p6_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	u64 val;
+
+	val = hwc->config;
+	if (cpuc->enabled)
+		val |= ARCH_PERFMON_EVENTSEL0_ENABLE;
+
+	(void)checking_wrmsrl(hwc->config_base + idx, val);
+}
+
+
+static void intel_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS)) {
+		if (!__get_cpu_var(cpu_hw_events).enabled)
+			return;
+
+		intel_pmu_enable_bts(hwc->config);
+		return;
+	}
+
+	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
+		intel_pmu_enable_fixed(hwc, idx);
+		return;
+	}
+
+	x86_pmu_enable_event(hwc, idx);
+}
+
+static void amd_pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	if (cpuc->enabled)
+		x86_pmu_enable_event(hwc, idx);
+}
+
+static int
+fixed_mode_idx(struct perf_event *event, struct hw_perf_event *hwc)
+{
+	unsigned int hw_event;
+
+	hw_event = hwc->config & ARCH_PERFMON_EVENT_MASK;
+
+	if (unlikely((hw_event ==
+		      x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS)) &&
+		     (hwc->sample_period == 1)))
+		return X86_PMC_IDX_FIXED_BTS;
+
+	if (!x86_pmu.num_events_fixed)
+		return -1;
+
+	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_INSTRUCTIONS)))
+		return X86_PMC_IDX_FIXED_INSTRUCTIONS;
+	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_CPU_CYCLES)))
+		return X86_PMC_IDX_FIXED_CPU_CYCLES;
+	if (unlikely(hw_event == x86_pmu.event_map(PERF_COUNT_HW_BUS_CYCLES)))
+		return X86_PMC_IDX_FIXED_BUS_CYCLES;
+
+	return -1;
+}
+
+/*
+ * Find a PMC slot for the freshly enabled / scheduled in event:
+ */
+static int x86_pmu_enable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	idx = fixed_mode_idx(event, hwc);
+	if (idx == X86_PMC_IDX_FIXED_BTS) {
+		/* BTS is already occupied. */
+		if (test_and_set_bit(idx, cpuc->used_mask))
+			return -EAGAIN;
+
+		hwc->config_base	= 0;
+		hwc->event_base	= 0;
+		hwc->idx		= idx;
+	} else if (idx >= 0) {
+		/*
+		 * Try to get the fixed event, if that is already taken
+		 * then try to get a generic event:
+		 */
+		if (test_and_set_bit(idx, cpuc->used_mask))
+			goto try_generic;
+
+		hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
+		/*
+		 * We set it so that event_base + idx in wrmsr/rdmsr maps to
+		 * MSR_ARCH_PERFMON_FIXED_CTR0 ... CTR2:
+		 */
+		hwc->event_base =
+			MSR_ARCH_PERFMON_FIXED_CTR0 - X86_PMC_IDX_FIXED;
+		hwc->idx = idx;
+	} else {
+		idx = hwc->idx;
+		/* Try to get the previous generic event again */
+		if (test_and_set_bit(idx, cpuc->used_mask)) {
+try_generic:
+			idx = find_first_zero_bit(cpuc->used_mask,
+						  x86_pmu.num_events);
+			if (idx == x86_pmu.num_events)
+				return -EAGAIN;
+
+			set_bit(idx, cpuc->used_mask);
+			hwc->idx = idx;
+		}
+		hwc->config_base  = x86_pmu.eventsel;
+		hwc->event_base = x86_pmu.perfctr;
+	}
+
+	perf_events_lapic_init();
+
+	x86_pmu.disable(hwc, idx);
+
+	cpuc->events[idx] = event;
+	set_bit(idx, cpuc->active_mask);
+
+	x86_perf_event_set_period(event, hwc, idx);
+	x86_pmu.enable(hwc, idx);
+
+	perf_event_update_userpage(event);
+
+	return 0;
+}
+
+static void x86_pmu_unthrottle(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (WARN_ON_ONCE(hwc->idx >= X86_PMC_IDX_MAX ||
+				cpuc->events[hwc->idx] != event))
+		return;
+
+	x86_pmu.enable(hwc, hwc->idx);
+}
+
+void perf_event_print_debug(void)
+{
+	u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
+	struct cpu_hw_events *cpuc;
+	unsigned long flags;
+	int cpu, idx;
+
+	if (!x86_pmu.num_events)
+		return;
+
+	local_irq_save(flags);
+
+	cpu = smp_processor_id();
+	cpuc = &per_cpu(cpu_hw_events, cpu);
+
+	if (x86_pmu.version >= 2) {
+		rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
+		rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
+		rdmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, overflow);
+		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR_CTRL, fixed);
+
+		pr_info("\n");
+		pr_info("CPU#%d: ctrl:       %016llx\n", cpu, ctrl);
+		pr_info("CPU#%d: status:     %016llx\n", cpu, status);
+		pr_info("CPU#%d: overflow:   %016llx\n", cpu, overflow);
+		pr_info("CPU#%d: fixed:      %016llx\n", cpu, fixed);
+	}
+	pr_info("CPU#%d: used:       %016llx\n", cpu, *(u64 *)cpuc->used_mask);
+
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		rdmsrl(x86_pmu.eventsel + idx, pmc_ctrl);
+		rdmsrl(x86_pmu.perfctr  + idx, pmc_count);
+
+		prev_left = per_cpu(pmc_prev_left[idx], cpu);
+
+		pr_info("CPU#%d:   gen-PMC%d ctrl:  %016llx\n",
+			cpu, idx, pmc_ctrl);
+		pr_info("CPU#%d:   gen-PMC%d count: %016llx\n",
+			cpu, idx, pmc_count);
+		pr_info("CPU#%d:   gen-PMC%d left:  %016llx\n",
+			cpu, idx, prev_left);
+	}
+	for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
+		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
+
+		pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
+			cpu, idx, pmc_count);
+	}
+	local_irq_restore(flags);
+}
+
+static void intel_pmu_drain_bts_buffer(struct cpu_hw_events *cpuc)
+{
+	struct debug_store *ds = cpuc->ds;
+	struct bts_record {
+		u64	from;
+		u64	to;
+		u64	flags;
+	};
+	struct perf_event *event = cpuc->events[X86_PMC_IDX_FIXED_BTS];
+	struct bts_record *at, *top;
+	struct perf_output_handle handle;
+	struct perf_event_header header;
+	struct perf_sample_data data;
+	struct pt_regs regs;
+
+	if (!event)
+		return;
+
+	if (!ds)
+		return;
+
+	at  = (struct bts_record *)(unsigned long)ds->bts_buffer_base;
+	top = (struct bts_record *)(unsigned long)ds->bts_index;
+
+	if (top <= at)
+		return;
+
+	ds->bts_index = ds->bts_buffer_base;
+
+
+	data.period	= event->hw.last_period;
+	data.addr	= 0;
+	regs.ip		= 0;
+
+	/*
+	 * Prepare a generic sample, i.e. fill in the invariant fields.
+	 * We will overwrite the from and to address before we output
+	 * the sample.
+	 */
+	perf_prepare_sample(&header, &data, event, &regs);
+
+	if (perf_output_begin(&handle, event,
+			      header.size * (top - at), 1, 1))
+		return;
+
+	for (; at < top; at++) {
+		data.ip		= at->from;
+		data.addr	= at->to;
+
+		perf_output_sample(&handle, &header, &data, event);
+	}
+
+	perf_output_end(&handle);
+
+	/* There's new data available. */
+	event->hw.interrupts++;
+	event->pending_kill = POLL_IN;
+}
+
+static void x86_pmu_disable(struct perf_event *event)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	/*
+	 * Must be done before we disable, otherwise the nmi handler
+	 * could reenable again:
+	 */
+	clear_bit(idx, cpuc->active_mask);
+	x86_pmu.disable(hwc, idx);
+
+	/*
+	 * Make sure the cleared pointer becomes visible before we
+	 * (potentially) free the event:
+	 */
+	barrier();
+
+	/*
+	 * Drain the remaining delta count out of a event
+	 * that we are disabling:
+	 */
+	x86_perf_event_update(event, hwc, idx);
+
+	/* Drain the remaining BTS records. */
+	if (unlikely(idx == X86_PMC_IDX_FIXED_BTS))
+		intel_pmu_drain_bts_buffer(cpuc);
+
+	cpuc->events[idx] = NULL;
+	clear_bit(idx, cpuc->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+/*
+ * Save and restart an expired event. Called by NMI contexts,
+ * so it has to be careful about preempting normal event ops:
+ */
+static int intel_pmu_save_and_restart(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+	int ret;
+
+	x86_perf_event_update(event, hwc, idx);
+	ret = x86_perf_event_set_period(event, hwc, idx);
+
+	if (event->state == PERF_EVENT_STATE_ACTIVE)
+		intel_pmu_enable_event(hwc, idx);
+
+	return ret;
+}
+
+static void intel_pmu_reset(void)
+{
+	struct debug_store *ds = __get_cpu_var(cpu_hw_events).ds;
+	unsigned long flags;
+	int idx;
+
+	if (!x86_pmu.num_events)
+		return;
+
+	local_irq_save(flags);
+
+	printk("clearing PMU state on CPU#%d\n", smp_processor_id());
+
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		checking_wrmsrl(x86_pmu.eventsel + idx, 0ull);
+		checking_wrmsrl(x86_pmu.perfctr  + idx, 0ull);
+	}
+	for (idx = 0; idx < x86_pmu.num_events_fixed; idx++) {
+		checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
+	}
+	if (ds)
+		ds->bts_index = ds->bts_buffer_base;
+
+	local_irq_restore(flags);
+}
+
+static int p6_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	int idx, handled = 0;
+	u64 val;
+
+	data.addr = 0;
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		event = cpuc->events[idx];
+		hwc = &event->hw;
+
+		val = x86_perf_event_update(event, hwc, idx);
+		if (val & (1ULL << (x86_pmu.event_bits - 1)))
+			continue;
+
+		/*
+		 * event overflow
+		 */
+		handled		= 1;
+		data.period	= event->hw.last_period;
+
+		if (!x86_perf_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, 1, &data, regs))
+			p6_pmu_disable_event(hwc, idx);
+	}
+
+	if (handled)
+		inc_irq_stat(apic_perf_irqs);
+
+	return handled;
+}
+
+/*
+ * This handler is triggered by the local APIC, so the APIC IRQ handling
+ * rules apply:
+ */
+static int intel_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	int bit, loops;
+	u64 ack, status;
+
+	data.addr = 0;
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+
+	perf_disable();
+	intel_pmu_drain_bts_buffer(cpuc);
+	status = intel_pmu_get_status();
+	if (!status) {
+		perf_enable();
+		return 0;
+	}
+
+	loops = 0;
+again:
+	if (++loops > 100) {
+		WARN_ONCE(1, "perfevents: irq loop stuck!\n");
+		perf_event_print_debug();
+		intel_pmu_reset();
+		perf_enable();
+		return 1;
+	}
+
+	inc_irq_stat(apic_perf_irqs);
+	ack = status;
+	for_each_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
+		struct perf_event *event = cpuc->events[bit];
+
+		clear_bit(bit, (unsigned long *) &status);
+		if (!test_bit(bit, cpuc->active_mask))
+			continue;
+
+		if (!intel_pmu_save_and_restart(event))
+			continue;
+
+		data.period = event->hw.last_period;
+
+		if (perf_event_overflow(event, 1, &data, regs))
+			intel_pmu_disable_event(&event->hw, bit);
+	}
+
+	intel_pmu_ack_status(ack);
+
+	/*
+	 * Repeat if there is more work to be done:
+	 */
+	status = intel_pmu_get_status();
+	if (status)
+		goto again;
+
+	perf_enable();
+
+	return 1;
+}
+
+static int amd_pmu_handle_irq(struct pt_regs *regs)
+{
+	struct perf_sample_data data;
+	struct cpu_hw_events *cpuc;
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	int idx, handled = 0;
+	u64 val;
+
+	data.addr = 0;
+
+	cpuc = &__get_cpu_var(cpu_hw_events);
+
+	for (idx = 0; idx < x86_pmu.num_events; idx++) {
+		if (!test_bit(idx, cpuc->active_mask))
+			continue;
+
+		event = cpuc->events[idx];
+		hwc = &event->hw;
+
+		val = x86_perf_event_update(event, hwc, idx);
+		if (val & (1ULL << (x86_pmu.event_bits - 1)))
+			continue;
+
+		/*
+		 * event overflow
+		 */
+		handled		= 1;
+		data.period	= event->hw.last_period;
+
+		if (!x86_perf_event_set_period(event, hwc, idx))
+			continue;
+
+		if (perf_event_overflow(event, 1, &data, regs))
+			amd_pmu_disable_event(hwc, idx);
+	}
+
+	if (handled)
+		inc_irq_stat(apic_perf_irqs);
+
+	return handled;
+}
+
+void smp_perf_pending_interrupt(struct pt_regs *regs)
+{
+	irq_enter();
+	ack_APIC_irq();
+	inc_irq_stat(apic_pending_irqs);
+	perf_event_do_pending();
+	irq_exit();
+}
+
+void set_perf_event_pending(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	apic->send_IPI_self(LOCAL_PENDING_VECTOR);
+#endif
+}
+
+void perf_events_lapic_init(void)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	if (!x86_pmu.apic || !x86_pmu_initialized())
+		return;
+
+	/*
+	 * Always use NMI for PMU
+	 */
+	apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
+}
+
+static int __kprobes
+perf_event_nmi_handler(struct notifier_block *self,
+			 unsigned long cmd, void *__args)
+{
+	struct die_args *args = __args;
+	struct pt_regs *regs;
+
+	if (!atomic_read(&active_events))
+		return NOTIFY_DONE;
+
+	switch (cmd) {
+	case DIE_NMI:
+	case DIE_NMI_IPI:
+		break;
+
+	default:
+		return NOTIFY_DONE;
+	}
+
+	regs = args->regs;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	apic_write(APIC_LVTPC, APIC_DM_NMI);
+#endif
+	/*
+	 * Can't rely on the handled return value to say it was our NMI, two
+	 * events could trigger 'simultaneously' raising two back-to-back NMIs.
+	 *
+	 * If the first NMI handles both, the latter will be empty and daze
+	 * the CPU.
+	 */
+	x86_pmu.handle_irq(regs);
+
+	return NOTIFY_STOP;
+}
+
+static __read_mostly struct notifier_block perf_event_nmi_notifier = {
+	.notifier_call		= perf_event_nmi_handler,
+	.next			= NULL,
+	.priority		= 1
+};
+
+static struct x86_pmu p6_pmu = {
+	.name			= "p6",
+	.handle_irq		= p6_pmu_handle_irq,
+	.disable_all		= p6_pmu_disable_all,
+	.enable_all		= p6_pmu_enable_all,
+	.enable			= p6_pmu_enable_event,
+	.disable		= p6_pmu_disable_event,
+	.eventsel		= MSR_P6_EVNTSEL0,
+	.perfctr		= MSR_P6_PERFCTR0,
+	.event_map		= p6_pmu_event_map,
+	.raw_event		= p6_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(p6_perfmon_event_map),
+	.apic			= 1,
+	.max_period		= (1ULL << 31) - 1,
+	.version		= 0,
+	.num_events		= 2,
+	/*
+	 * Events have 40 bits implemented. However they are designed such
+	 * that bits [32-39] are sign extensions of bit 31. As such the
+	 * effective width of a event for P6-like PMU is 32 bits only.
+	 *
+	 * See IA-32 Intel Architecture Software developer manual Vol 3B
+	 */
+	.event_bits		= 32,
+	.event_mask		= (1ULL << 32) - 1,
+};
+
+static struct x86_pmu intel_pmu = {
+	.name			= "Intel",
+	.handle_irq		= intel_pmu_handle_irq,
+	.disable_all		= intel_pmu_disable_all,
+	.enable_all		= intel_pmu_enable_all,
+	.enable			= intel_pmu_enable_event,
+	.disable		= intel_pmu_disable_event,
+	.eventsel		= MSR_ARCH_PERFMON_EVENTSEL0,
+	.perfctr		= MSR_ARCH_PERFMON_PERFCTR0,
+	.event_map		= intel_pmu_event_map,
+	.raw_event		= intel_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(intel_perfmon_event_map),
+	.apic			= 1,
+	/*
+	 * Intel PMCs cannot be accessed sanely above 32 bit width,
+	 * so we install an artificial 1<<31 period regardless of
+	 * the generic event period:
+	 */
+	.max_period		= (1ULL << 31) - 1,
+	.enable_bts		= intel_pmu_enable_bts,
+	.disable_bts		= intel_pmu_disable_bts,
+};
+
+static struct x86_pmu amd_pmu = {
+	.name			= "AMD",
+	.handle_irq		= amd_pmu_handle_irq,
+	.disable_all		= amd_pmu_disable_all,
+	.enable_all		= amd_pmu_enable_all,
+	.enable			= amd_pmu_enable_event,
+	.disable		= amd_pmu_disable_event,
+	.eventsel		= MSR_K7_EVNTSEL0,
+	.perfctr		= MSR_K7_PERFCTR0,
+	.event_map		= amd_pmu_event_map,
+	.raw_event		= amd_pmu_raw_event,
+	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
+	.num_events		= 4,
+	.event_bits		= 48,
+	.event_mask		= (1ULL << 48) - 1,
+	.apic			= 1,
+	/* use highest bit to detect overflow */
+	.max_period		= (1ULL << 47) - 1,
+};
+
+static int p6_pmu_init(void)
+{
+	switch (boot_cpu_data.x86_model) {
+	case 1:
+	case 3:  /* Pentium Pro */
+	case 5:
+	case 6:  /* Pentium II */
+	case 7:
+	case 8:
+	case 11: /* Pentium III */
+		break;
+	case 9:
+	case 13:
+		/* Pentium M */
+		break;
+	default:
+		pr_cont("unsupported p6 CPU model %d ",
+			boot_cpu_data.x86_model);
+		return -ENODEV;
+	}
+
+	x86_pmu = p6_pmu;
+
+	if (!cpu_has_apic) {
+		pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
+		pr_info("no hardware sampling interrupt available.\n");
+		x86_pmu.apic = 0;
+	}
+
+	return 0;
+}
+
+static int intel_pmu_init(void)
+{
+	union cpuid10_edx edx;
+	union cpuid10_eax eax;
+	unsigned int unused;
+	unsigned int ebx;
+	int version;
+
+	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
+		/* check for P6 processor family */
+	   if (boot_cpu_data.x86 == 6) {
+		return p6_pmu_init();
+	   } else {
+		return -ENODEV;
+	   }
+	}
+
+	/*
+	 * Check whether the Architectural PerfMon supports
+	 * Branch Misses Retired hw_event or not.
+	 */
+	cpuid(10, &eax.full, &ebx, &unused, &edx.full);
+	if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED)
+		return -ENODEV;
+
+	version = eax.split.version_id;
+	if (version < 2)
+		return -ENODEV;
+
+	x86_pmu				= intel_pmu;
+	x86_pmu.version			= version;
+	x86_pmu.num_events		= eax.split.num_events;
+	x86_pmu.event_bits		= eax.split.bit_width;
+	x86_pmu.event_mask		= (1ULL << eax.split.bit_width) - 1;
+
+	/*
+	 * Quirk: v2 perfmon does not report fixed-purpose events, so
+	 * assume at least 3 events:
+	 */
+	x86_pmu.num_events_fixed	= max((int)edx.split.num_events_fixed, 3);
+
+	/*
+	 * Install the hw-cache-events table:
+	 */
+	switch (boot_cpu_data.x86_model) {
+	case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
+	case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
+	case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
+	case 29: /* six-core 45 nm xeon "Dunnington" */
+		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		pr_cont("Core2 events, ");
+		break;
+	default:
+	case 26:
+		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		pr_cont("Nehalem/Corei7 events, ");
+		break;
+	case 28:
+		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
+		       sizeof(hw_cache_event_ids));
+
+		pr_cont("Atom events, ");
+		break;
+	}
+	return 0;
+}
+
+static int amd_pmu_init(void)
+{
+	/* Performance-monitoring supported from K7 and later: */
+	if (boot_cpu_data.x86 < 6)
+		return -ENODEV;
+
+	x86_pmu = amd_pmu;
+
+	/* Events are common for all AMDs */
+	memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
+	       sizeof(hw_cache_event_ids));
+
+	return 0;
+}
+
+void __init init_hw_perf_events(void)
+{
+	int err;
+
+	pr_info("Performance Events: ");
+
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_INTEL:
+		err = intel_pmu_init();
+		break;
+	case X86_VENDOR_AMD:
+		err = amd_pmu_init();
+		break;
+	default:
+		return;
+	}
+	if (err != 0) {
+		pr_cont("no PMU driver, software events only.\n");
+		return;
+	}
+
+	pr_cont("%s PMU driver.\n", x86_pmu.name);
+
+	if (x86_pmu.num_events > X86_PMC_MAX_GENERIC) {
+		WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
+		     x86_pmu.num_events, X86_PMC_MAX_GENERIC);
+		x86_pmu.num_events = X86_PMC_MAX_GENERIC;
+	}
+	perf_event_mask = (1 << x86_pmu.num_events) - 1;
+	perf_max_events = x86_pmu.num_events;
+
+	if (x86_pmu.num_events_fixed > X86_PMC_MAX_FIXED) {
+		WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
+		     x86_pmu.num_events_fixed, X86_PMC_MAX_FIXED);
+		x86_pmu.num_events_fixed = X86_PMC_MAX_FIXED;
+	}
+
+	perf_event_mask |=
+		((1LL << x86_pmu.num_events_fixed)-1) << X86_PMC_IDX_FIXED;
+	x86_pmu.intel_ctrl = perf_event_mask;
+
+	perf_events_lapic_init();
+	register_die_notifier(&perf_event_nmi_notifier);
+
+	pr_info("... version:                %d\n",     x86_pmu.version);
+	pr_info("... bit width:              %d\n",     x86_pmu.event_bits);
+	pr_info("... generic registers:      %d\n",     x86_pmu.num_events);
+	pr_info("... value mask:             %016Lx\n", x86_pmu.event_mask);
+	pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
+	pr_info("... fixed-purpose events:   %d\n",     x86_pmu.num_events_fixed);
+	pr_info("... event mask:             %016Lx\n", perf_event_mask);
+}
+
+static inline void x86_pmu_read(struct perf_event *event)
+{
+	x86_perf_event_update(event, &event->hw, event->hw.idx);
+}
+
+static const struct pmu pmu = {
+	.enable		= x86_pmu_enable,
+	.disable	= x86_pmu_disable,
+	.read		= x86_pmu_read,
+	.unthrottle	= x86_pmu_unthrottle,
+};
+
+const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+	int err;
+
+	err = __hw_perf_event_init(event);
+	if (err) {
+		if (event->destroy)
+			event->destroy(event);
+		return ERR_PTR(err);
+	}
+
+	return &pmu;
+}
+
+/*
+ * callchain support
+ */
+
+static inline
+void callchain_store(struct perf_callchain_entry *entry, u64 ip)
+{
+	if (entry->nr < PERF_MAX_STACK_DEPTH)
+		entry->ip[entry->nr++] = ip;
+}
+
+static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
+static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_nmi_entry);
+static DEFINE_PER_CPU(int, in_nmi_frame);
+
+
+static void
+backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
+{
+	/* Ignore warnings */
+}
+
+static void backtrace_warning(void *data, char *msg)
+{
+	/* Ignore warnings */
+}
+
+static int backtrace_stack(void *data, char *name)
+{
+	per_cpu(in_nmi_frame, smp_processor_id()) =
+			x86_is_stack_id(NMI_STACK, name);
+
+	return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr, int reliable)
+{
+	struct perf_callchain_entry *entry = data;
+
+	if (per_cpu(in_nmi_frame, smp_processor_id()))
+		return;
+
+	if (reliable)
+		callchain_store(entry, addr);
+}
+
+static const struct stacktrace_ops backtrace_ops = {
+	.warning		= backtrace_warning,
+	.warning_symbol		= backtrace_warning_symbol,
+	.stack			= backtrace_stack,
+	.address		= backtrace_address,
+};
+
+#include "../dumpstack.h"
+
+static void
+perf_callchain_kernel(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	callchain_store(entry, PERF_CONTEXT_KERNEL);
+	callchain_store(entry, regs->ip);
+
+	dump_trace(NULL, regs, NULL, 0, &backtrace_ops, entry);
+}
+
+/*
+ * best effort, GUP based copy_from_user() that assumes IRQ or NMI context
+ */
+static unsigned long
+copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
+{
+	unsigned long offset, addr = (unsigned long)from;
+	int type = in_nmi() ? KM_NMI : KM_IRQ0;
+	unsigned long size, len = 0;
+	struct page *page;
+	void *map;
+	int ret;
+
+	do {
+		ret = __get_user_pages_fast(addr, 1, 0, &page);
+		if (!ret)
+			break;
+
+		offset = addr & (PAGE_SIZE - 1);
+		size = min(PAGE_SIZE - offset, n - len);
+
+		map = kmap_atomic(page, type);
+		memcpy(to, map+offset, size);
+		kunmap_atomic(map, type);
+		put_page(page);
+
+		len  += size;
+		to   += size;
+		addr += size;
+
+	} while (len < n);
+
+	return len;
+}
+
+static int copy_stack_frame(const void __user *fp, struct stack_frame *frame)
+{
+	unsigned long bytes;
+
+	bytes = copy_from_user_nmi(frame, fp, sizeof(*frame));
+
+	return bytes == sizeof(*frame);
+}
+
+static void
+perf_callchain_user(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	struct stack_frame frame;
+	const void __user *fp;
+
+	if (!user_mode(regs))
+		regs = task_pt_regs(current);
+
+	fp = (void __user *)regs->bp;
+
+	callchain_store(entry, PERF_CONTEXT_USER);
+	callchain_store(entry, regs->ip);
+
+	while (entry->nr < PERF_MAX_STACK_DEPTH) {
+		frame.next_frame	     = NULL;
+		frame.return_address = 0;
+
+		if (!copy_stack_frame(fp, &frame))
+			break;
+
+		if ((unsigned long)fp < regs->sp)
+			break;
+
+		callchain_store(entry, frame.return_address);
+		fp = frame.next_frame;
+	}
+}
+
+static void
+perf_do_callchain(struct pt_regs *regs, struct perf_callchain_entry *entry)
+{
+	int is_user;
+
+	if (!regs)
+		return;
+
+	is_user = user_mode(regs);
+
+	if (!current || current->pid == 0)
+		return;
+
+	if (is_user && current->state != TASK_RUNNING)
+		return;
+
+	if (!is_user)
+		perf_callchain_kernel(regs, entry);
+
+	if (current->mm)
+		perf_callchain_user(regs, entry);
+}
+
+struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+{
+	struct perf_callchain_entry *entry;
+
+	if (in_nmi())
+		entry = &__get_cpu_var(pmc_nmi_entry);
+	else
+		entry = &__get_cpu_var(pmc_irq_entry);
+
+	entry->nr = 0;
+
+	perf_do_callchain(regs, entry);
+
+	return entry;
+}
+
+void hw_perf_event_setup_online(int cpu)
+{
+	init_debug_store_on_cpu(cpu);
+}
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index e60ed74..fab786f 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -20,7 +20,7 @@
 #include <linux/kprobes.h>
 
 #include <asm/apic.h>
-#include <asm/perf_counter.h>
+#include <asm/perf_event.h>
 
 struct nmi_watchdog_ctlblk {
 	unsigned int cccr_msr;
@@ -68,16 +68,16 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
 	/* returns the bit offset of the performance counter register */
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
-		return (msr - MSR_K7_PERFCTR0);
+		return msr - MSR_K7_PERFCTR0;
 	case X86_VENDOR_INTEL:
 		if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
-			return (msr - MSR_ARCH_PERFMON_PERFCTR0);
+			return msr - MSR_ARCH_PERFMON_PERFCTR0;
 
 		switch (boot_cpu_data.x86) {
 		case 6:
-			return (msr - MSR_P6_PERFCTR0);
+			return msr - MSR_P6_PERFCTR0;
 		case 15:
-			return (msr - MSR_P4_BPU_PERFCTR0);
+			return msr - MSR_P4_BPU_PERFCTR0;
 		}
 	}
 	return 0;
@@ -92,16 +92,16 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
 	/* returns the bit offset of the event selection register */
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
-		return (msr - MSR_K7_EVNTSEL0);
+		return msr - MSR_K7_EVNTSEL0;
 	case X86_VENDOR_INTEL:
 		if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
-			return (msr - MSR_ARCH_PERFMON_EVENTSEL0);
+			return msr - MSR_ARCH_PERFMON_EVENTSEL0;
 
 		switch (boot_cpu_data.x86) {
 		case 6:
-			return (msr - MSR_P6_EVNTSEL0);
+			return msr - MSR_P6_EVNTSEL0;
 		case 15:
-			return (msr - MSR_P4_BSU_ESCR0);
+			return msr - MSR_P4_BSU_ESCR0;
 		}
 	}
 	return 0;
@@ -113,7 +113,7 @@ int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
 {
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	return (!test_bit(counter, perfctr_nmi_owner));
+	return !test_bit(counter, perfctr_nmi_owner);
 }
 
 /* checks the an msr for availability */
@@ -124,7 +124,7 @@ int avail_to_resrv_perfctr_nmi(unsigned int msr)
 	counter = nmi_perfctr_msr_to_bit(msr);
 	BUG_ON(counter > NMI_MAX_COUNTER_BITS);
 
-	return (!test_bit(counter, perfctr_nmi_owner));
+	return !test_bit(counter, perfctr_nmi_owner);
 }
 EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit);
 
@@ -237,7 +237,7 @@ static unsigned int adjust_for_32bit_ctr(unsigned int hz)
 	 */
 	counter_val = (u64)cpu_khz * 1000;
 	do_div(counter_val, retval);
- 	if (counter_val > 0x7fffffffULL) {
+	if (counter_val > 0x7fffffffULL) {
 		u64 count = (u64)cpu_khz * 1000;
 		do_div(count, 0x7fffffffUL);
 		retval = count + 1;
@@ -251,7 +251,7 @@ static void write_watchdog_counter(unsigned int perfctr_msr,
 	u64 count = (u64)cpu_khz * 1000;
 
 	do_div(count, nmi_hz);
-	if(descr)
+	if (descr)
 		pr_debug("setting %s to -0x%08Lx\n", descr, count);
 	wrmsrl(perfctr_msr, 0 - count);
 }
@@ -262,7 +262,7 @@ static void write_watchdog_counter32(unsigned int perfctr_msr,
 	u64 count = (u64)cpu_khz * 1000;
 
 	do_div(count, nmi_hz);
-	if(descr)
+	if (descr)
 		pr_debug("setting %s to -0x%08Lx\n", descr, count);
 	wrmsr(perfctr_msr, (u32)(-count), 0);
 }
@@ -296,7 +296,7 @@ static int setup_k7_watchdog(unsigned nmi_hz)
 
 	/* setup the timer */
 	wrmsr(evntsel_msr, evntsel, 0);
-	write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz);
+	write_watchdog_counter(perfctr_msr, "K7_PERFCTR0", nmi_hz);
 
 	/* initialize the wd struct before enabling */
 	wd->perfctr_msr = perfctr_msr;
@@ -387,7 +387,7 @@ static int setup_p6_watchdog(unsigned nmi_hz)
 	/* setup the timer */
 	wrmsr(evntsel_msr, evntsel, 0);
 	nmi_hz = adjust_for_32bit_ctr(nmi_hz);
-	write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz);
+	write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0", nmi_hz);
 
 	/* initialize the wd struct before enabling */
 	wd->perfctr_msr = perfctr_msr;
@@ -415,7 +415,7 @@ static void __kprobes p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 
 	/* P6/ARCH_PERFMON has 32 bit counter write */
-	write_watchdog_counter32(wd->perfctr_msr, NULL,nmi_hz);
+	write_watchdog_counter32(wd->perfctr_msr, NULL, nmi_hz);
 }
 
 static const struct wd_ops p6_wd_ops = {
@@ -490,9 +490,9 @@ static int setup_p4_watchdog(unsigned nmi_hz)
 	if (smp_num_siblings == 2) {
 		unsigned int ebx, apicid;
 
-        	ebx = cpuid_ebx(1);
-	        apicid = (ebx >> 24) & 0xff;
-        	ht_num = apicid & 1;
+		ebx = cpuid_ebx(1);
+		apicid = (ebx >> 24) & 0xff;
+		ht_num = apicid & 1;
 	} else
 #endif
 		ht_num = 0;
@@ -544,7 +544,7 @@ static int setup_p4_watchdog(unsigned nmi_hz)
 	}
 
 	evntsel = P4_ESCR_EVENT_SELECT(0x3F)
-	 	| P4_ESCR_OS
+		| P4_ESCR_OS
 		| P4_ESCR_USR;
 
 	cccr_val |= P4_CCCR_THRESHOLD(15)
@@ -612,7 +612,7 @@ static void __kprobes p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
 {
 	unsigned dummy;
 	/*
- 	 * P4 quirks:
+	 * P4 quirks:
 	 * - An overflown perfctr will assert its interrupt
 	 *   until the OVF flag in its CCCR is cleared.
 	 * - LVTPC is masked on interrupt and must be
@@ -662,7 +662,8 @@ static int setup_intel_arch_watchdog(unsigned nmi_hz)
 	 * NOTE: Corresponding bit = 0 in ebx indicates event present.
 	 */
 	cpuid(10, &(eax.full), &ebx, &unused, &unused);
-	if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
+	if ((eax.split.mask_length <
+			(ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
 	    (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
 		return 0;
 
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index d5e3039..62ac8cb 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -116,11 +116,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
 #endif
 	seq_printf(m, "clflush size\t: %u\n", c->x86_clflush_size);
-#ifdef CONFIG_X86_64
 	seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
 	seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n",
 		   c->x86_phys_bits, c->x86_virt_bits);
-#endif
 
 	seq_printf(m, "power management:");
 	for (i = 0; i < 32; i++) {
@@ -128,7 +126,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 			if (i < ARRAY_SIZE(x86_power_flags) &&
 			    x86_power_flags[i])
 				seq_printf(m, "%s%s",
-					   x86_power_flags[i][0]?" ":"",
+					   x86_power_flags[i][0] ? " " : "",
 					   x86_power_flags[i]);
 			else
 				seq_printf(m, " [%d]", i);
diff --git a/arch/x86/kernel/cpu/sched.c b/arch/x86/kernel/cpu/sched.c
new file mode 100644
index 0000000..a640ae5
--- /dev/null
+++ b/arch/x86/kernel/cpu/sched.c
@@ -0,0 +1,55 @@
+#include <linux/sched.h>
+#include <linux/math64.h>
+#include <linux/percpu.h>
+#include <linux/irqflags.h>
+
+#include <asm/cpufeature.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_SMP
+
+static DEFINE_PER_CPU(struct aperfmperf, old_perf_sched);
+
+static unsigned long scale_aperfmperf(void)
+{
+	struct aperfmperf val, *old = &__get_cpu_var(old_perf_sched);
+	unsigned long ratio, flags;
+
+	local_irq_save(flags);
+	get_aperfmperf(&val);
+	local_irq_restore(flags);
+
+	ratio = calc_aperfmperf_ratio(old, &val);
+	*old = val;
+
+	return ratio;
+}
+
+unsigned long arch_scale_freq_power(struct sched_domain *sd, int cpu)
+{
+	/*
+	 * do aperf/mperf on the cpu level because it includes things
+	 * like turbo mode, which are relevant to full cores.
+	 */
+	if (boot_cpu_has(X86_FEATURE_APERFMPERF))
+		return scale_aperfmperf();
+
+	/*
+	 * maybe have something cpufreq here
+	 */
+
+	return default_scale_freq_power(sd, cpu);
+}
+
+unsigned long arch_scale_smt_power(struct sched_domain *sd, int cpu)
+{
+	/*
+	 * aperf/mperf already includes the smt gain
+	 */
+	if (boot_cpu_has(X86_FEATURE_APERFMPERF))
+		return SCHED_LOAD_SCALE;
+
+	return default_scale_smt_power(sd, cpu);
+}
+
+#endif
diff --git a/arch/x86/kernel/cpu/vmware.c b/arch/x86/kernel/cpu/vmware.c
index 284c399..1cbed97 100644
--- a/arch/x86/kernel/cpu/vmware.c
+++ b/arch/x86/kernel/cpu/vmware.c
@@ -24,6 +24,7 @@
 #include <linux/dmi.h>
 #include <asm/div64.h>
 #include <asm/vmware.h>
+#include <asm/x86_init.h>
 
 #define CPUID_VMWARE_INFO_LEAF	0x40000000
 #define VMWARE_HYPERVISOR_MAGIC	0x564D5868
@@ -47,19 +48,33 @@ static inline int __vmware_platform(void)
 	return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
 }
 
-static unsigned long __vmware_get_tsc_khz(void)
+static unsigned long vmware_get_tsc_khz(void)
 {
-        uint64_t tsc_hz;
-        uint32_t eax, ebx, ecx, edx;
+	uint64_t tsc_hz;
+	uint32_t eax, ebx, ecx, edx;
+
+	VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+
+	tsc_hz = eax | (((uint64_t)ebx) << 32);
+	do_div(tsc_hz, 1000);
+	BUG_ON(tsc_hz >> 32);
+	printk(KERN_INFO "TSC freq read from hypervisor : %lu.%03lu MHz\n",
+			 (unsigned long) tsc_hz / 1000,
+			 (unsigned long) tsc_hz % 1000);
+	return tsc_hz;
+}
+
+void __init vmware_platform_setup(void)
+{
+	uint32_t eax, ebx, ecx, edx;
 
-        VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
+	VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
 
-        if (ebx == UINT_MAX)
-                return 0;
-        tsc_hz = eax | (((uint64_t)ebx) << 32);
-        do_div(tsc_hz, 1000);
-        BUG_ON(tsc_hz >> 32);
-        return tsc_hz;
+	if (ebx != UINT_MAX)
+		x86_platform.calibrate_tsc = vmware_get_tsc_khz;
+	else
+		printk(KERN_WARNING
+		       "Failed to get TSC freq from the hypervisor\n");
 }
 
 /*
@@ -87,12 +102,6 @@ int vmware_platform(void)
 	return 0;
 }
 
-unsigned long vmware_get_tsc_khz(void)
-{
-	BUG_ON(!vmware_platform());
-	return __vmware_get_tsc_khz();
-}
-
 /*
  * VMware hypervisor takes care of exporting a reliable TSC to the guest.
  * Still, due to timing difference when running on virtual cpus, the TSC can
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index b07af88..6a52d4b 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -182,7 +182,7 @@ static struct notifier_block __refdata cpuid_class_cpu_notifier =
 	.notifier_call = cpuid_class_cpu_callback,
 };
 
-static char *cpuid_nodename(struct device *dev)
+static char *cpuid_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt));
 }
@@ -203,7 +203,7 @@ static int __init cpuid_init(void)
 		err = PTR_ERR(cpuid_class);
 		goto out_chrdev;
 	}
-	cpuid_class->nodename = cpuid_nodename;
+	cpuid_class->devnode = cpuid_devnode;
 	for_each_online_cpu(i) {
 		err = cpuid_device_create(i);
 		if (err != 0)
diff --git a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
index b4f14c6..37250fe 100644
--- a/arch/x86/kernel/doublefault_32.c
+++ b/arch/x86/kernel/doublefault_32.c
@@ -27,9 +27,7 @@ static void doublefault_fn(void)
 
 	if (ptr_ok(gdt)) {
 		gdt += GDT_ENTRY_TSS << 3;
-		tss = *(u16 *)(gdt+2);
-		tss += *(u8 *)(gdt+4) << 16;
-		tss += *(u8 *)(gdt+7) << 24;
+		tss = get_desc_base((struct desc_struct *)gdt);
 		printk(KERN_EMERG "double fault, tss at %08lx\n", tss);
 
 		if (ptr_ok(tss)) {
diff --git a/arch/x86/kernel/ds.c b/arch/x86/kernel/ds.c
index 48bfe13..ef42a03 100644
--- a/arch/x86/kernel/ds.c
+++ b/arch/x86/kernel/ds.c
@@ -509,15 +509,15 @@ enum bts_field {
 	bts_escape		= ((unsigned long)-1 & ~bts_qual_mask)
 };
 
-static inline unsigned long bts_get(const char *base, enum bts_field field)
+static inline unsigned long bts_get(const char *base, unsigned long field)
 {
 	base += (ds_cfg.sizeof_ptr_field * field);
 	return *(unsigned long *)base;
 }
 
-static inline void bts_set(char *base, enum bts_field field, unsigned long val)
+static inline void bts_set(char *base, unsigned long field, unsigned long val)
 {
-	base += (ds_cfg.sizeof_ptr_field * field);;
+	base += (ds_cfg.sizeof_ptr_field * field);
 	(*(unsigned long *)base) = val;
 }
 
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index c840571..2d8a371 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -15,7 +15,6 @@
 #include <linux/bug.h>
 #include <linux/nmi.h>
 #include <linux/sysfs.h>
-#include <linux/ftrace.h>
 
 #include <asm/stacktrace.h>
 
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 5cb5725..a3210ce 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -115,7 +115,7 @@ static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
 {
 	int x = e820x->nr_map;
 
-	if (x == ARRAY_SIZE(e820x->map)) {
+	if (x >= ARRAY_SIZE(e820x->map)) {
 		printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
 		return;
 	}
@@ -1455,28 +1455,11 @@ char *__init default_machine_specific_memory_setup(void)
 	return who;
 }
 
-char *__init __attribute__((weak)) machine_specific_memory_setup(void)
-{
-	if (x86_quirks->arch_memory_setup) {
-		char *who = x86_quirks->arch_memory_setup();
-
-		if (who)
-			return who;
-	}
-	return default_machine_specific_memory_setup();
-}
-
-/* Overridden in paravirt.c if CONFIG_PARAVIRT */
-char * __init __attribute__((weak)) memory_setup(void)
-{
-	return machine_specific_memory_setup();
-}
-
 void __init setup_memory_map(void)
 {
 	char *who;
 
-	who = memory_setup();
+	who = x86_init.resources.memory_setup();
 	memcpy(&e820_saved, &e820, sizeof(struct e820map));
 	printk(KERN_INFO "BIOS-provided physical RAM map:\n");
 	e820_print_map(who);
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 335f049..b11cab3 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -624,7 +624,7 @@ try_next_port:
 		return -1;
 	}
 
-	loop = 10;
+	loop = 100000;
 	/* Reset the EHCI controller */
 	cmd = readl(&ehci_regs->command);
 	cmd |= CMD_RESET;
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
index fe26ba3..ad5bd98 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/kernel/efi.c
@@ -42,6 +42,7 @@
 #include <asm/time.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
+#include <asm/x86_init.h>
 
 #define EFI_DEBUG	1
 #define PFX 		"EFI: "
@@ -453,6 +454,9 @@ void __init efi_init(void)
 	if (add_efi_memmap)
 		do_add_efi_memmap();
 
+	x86_platform.get_wallclock = efi_get_time;
+	x86_platform.set_wallclock = efi_set_rtc_mmss;
+
 	/* Setup for EFI runtime service */
 	reboot_type = BOOT_EFI;
 
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index c251be7..681c3fd 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -146,7 +146,7 @@ ENTRY(ftrace_graph_caller)
 END(ftrace_graph_caller)
 
 GLOBAL(return_to_handler)
-	subq  $80, %rsp
+	subq  $24, %rsp
 
 	/* Save the return values */
 	movq %rax, (%rsp)
@@ -155,10 +155,10 @@ GLOBAL(return_to_handler)
 
 	call ftrace_return_to_handler
 
-	movq %rax, 72(%rsp)
+	movq %rax, 16(%rsp)
 	movq 8(%rsp), %rdx
 	movq (%rsp), %rax
-	addq $72, %rsp
+	addq $16, %rsp
 	retq
 #endif
 
@@ -1021,7 +1021,7 @@ apicinterrupt ERROR_APIC_VECTOR \
 apicinterrupt SPURIOUS_APIC_VECTOR \
 	spurious_interrupt smp_spurious_interrupt
 
-#ifdef CONFIG_PERF_COUNTERS
+#ifdef CONFIG_PERF_EVENTS
 apicinterrupt LOCAL_PENDING_VECTOR \
 	perf_pending_interrupt smp_perf_pending_interrupt
 #endif
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index 3f8579f..4f8e250 100644
--- a/arch/x86/kernel/head32.c
+++ b/arch/x86/kernel/head32.c
@@ -11,8 +11,21 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/e820.h>
-#include <asm/bios_ebda.h>
+#include <asm/page.h>
 #include <asm/trampoline.h>
+#include <asm/apic.h>
+#include <asm/io_apic.h>
+#include <asm/bios_ebda.h>
+
+static void __init i386_default_early_setup(void)
+{
+	/* Initilize 32bit specific setup functions */
+	x86_init.resources.probe_roms = probe_roms;
+	x86_init.resources.reserve_resources = i386_reserve_resources;
+	x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc;
+
+	reserve_ebda_region();
+}
 
 void __init i386_start_kernel(void)
 {
@@ -29,7 +42,16 @@ void __init i386_start_kernel(void)
 		reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
 	}
 #endif
-	reserve_ebda_region();
+
+	/* Call the subarch specific early setup function */
+	switch (boot_params.hdr.hardware_subarch) {
+	case X86_SUBARCH_MRST:
+		x86_mrst_early_setup();
+		break;
+	default:
+		i386_default_early_setup();
+		break;
+	}
 
 	/*
 	 * At this point everything still needed from the boot loader
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 70eaa85..0b06cd7 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -23,8 +23,8 @@
 #include <asm/sections.h>
 #include <asm/kdebug.h>
 #include <asm/e820.h>
-#include <asm/bios_ebda.h>
 #include <asm/trampoline.h>
+#include <asm/bios_ebda.h>
 
 static void __init zap_identity_mappings(void)
 {
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index cc827ac..b766e8c 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -157,6 +157,7 @@ subarch_entries:
 	.long default_entry		/* normal x86/PC */
 	.long lguest_entry		/* lguest hypervisor */
 	.long xen_entry			/* Xen hypervisor */
+	.long default_entry		/* Moorestown MID */
 num_subarch_entries = (. - subarch_entries) / 4
 .previous
 #endif /* CONFIG_PARAVIRT */
@@ -439,7 +440,6 @@ is386:	movl $2,%ecx		# set MP
 	jne 1f
 	movl $per_cpu__gdt_page,%eax
 	movl $per_cpu__stack_canary,%ecx
-	subl $20, %ecx
 	movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
 	shrl $16, %ecx
 	movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index 5cf36c0..23c1679 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -19,12 +19,6 @@
 DEFINE_SPINLOCK(i8253_lock);
 EXPORT_SYMBOL(i8253_lock);
 
-#ifdef CONFIG_X86_32
-static void pit_disable_clocksource(void);
-#else
-static inline void pit_disable_clocksource(void) { }
-#endif
-
 /*
  * HPET replaces the PIT, when enabled. So we need to know, which of
  * the two timers is used
@@ -57,12 +51,10 @@ static void init_pit_timer(enum clock_event_mode mode,
 			outb_pit(0, PIT_CH0);
 			outb_pit(0, PIT_CH0);
 		}
-		pit_disable_clocksource();
 		break;
 
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* One shot setup */
-		pit_disable_clocksource();
 		outb_pit(0x38, PIT_MODE);
 		break;
 
@@ -200,17 +192,6 @@ static struct clocksource pit_cs = {
 	.shift		= 20,
 };
 
-static void pit_disable_clocksource(void)
-{
-	/*
-	 * Use mult to check whether it is registered or not
-	 */
-	if (pit_cs.mult) {
-		clocksource_unregister(&pit_cs);
-		pit_cs.mult = 0;
-	}
-}
-
 static int __init init_pit_clocksource(void)
 {
 	 /*
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index b0cdde6..74656d1 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -104,7 +104,7 @@ static int show_other_interrupts(struct seq_file *p, int prec)
 	seq_printf(p, "  Threshold APIC interrupts\n");
 # endif
 #endif
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
 	seq_printf(p, "%*s: ", prec, "MCE");
 	for_each_online_cpu(j)
 		seq_printf(p, "%10u ", per_cpu(mce_exception_count, j));
@@ -200,7 +200,7 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
 	sum += irq_stats(cpu)->irq_threshold_count;
 # endif
 #endif
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
 	sum += per_cpu(mce_exception_count, cpu);
 	sum += per_cpu(mce_poll_count, cpu);
 #endif
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 3b09634..7d35d0f 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -218,7 +218,6 @@ bool handle_irq(unsigned irq, struct pt_regs *regs)
 void fixup_irqs(void)
 {
 	unsigned int irq;
-	static int warned;
 	struct irq_desc *desc;
 
 	for_each_irq_desc(irq, desc) {
@@ -236,8 +235,8 @@ void fixup_irqs(void)
 		}
 		if (desc->chip->set_affinity)
 			desc->chip->set_affinity(irq, affinity);
-		else if (desc->action && !(warned++))
-			printk("Cannot set affinity for irq %i\n", irq);
+		else if (desc->action)
+			printk_once("Cannot set affinity for irq %i\n", irq);
 	}
 
 #if 0
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 92b7703..40f3077 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -116,7 +116,7 @@ int vector_used_by_percpu_irq(unsigned int vector)
 	return 0;
 }
 
-static void __init init_ISA_irqs(void)
+void __init init_ISA_irqs(void)
 {
 	int i;
 
@@ -140,8 +140,10 @@ static void __init init_ISA_irqs(void)
 	}
 }
 
-/* Overridden in paravirt.c */
-void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
+void __init init_IRQ(void)
+{
+	x86_init.irqs.intr_init();
+}
 
 static void __init smp_intr_init(void)
 {
@@ -190,7 +192,7 @@ static void __init apic_intr_init(void)
 #ifdef CONFIG_X86_MCE_THRESHOLD
 	alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
 #endif
-#if defined(CONFIG_X86_NEW_MCE) && defined(CONFIG_X86_LOCAL_APIC)
+#if defined(CONFIG_X86_MCE) && defined(CONFIG_X86_LOCAL_APIC)
 	alloc_intr_gate(MCE_SELF_VECTOR, mce_self_interrupt);
 #endif
 
@@ -206,39 +208,19 @@ static void __init apic_intr_init(void)
 	alloc_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
 
 	/* Performance monitoring interrupts: */
-# ifdef CONFIG_PERF_COUNTERS
+# ifdef CONFIG_PERF_EVENTS
 	alloc_intr_gate(LOCAL_PENDING_VECTOR, perf_pending_interrupt);
 # endif
 
 #endif
 }
 
-/**
- * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
- *
- * Description:
- *	Perform any necessary interrupt initialisation prior to setting up
- *	the "ordinary" interrupt call gates.  For legacy reasons, the ISA
- *	interrupts should be initialised here if the machine emulates a PC
- *	in any way.
- **/
-static void __init x86_quirk_pre_intr_init(void)
-{
-#ifdef CONFIG_X86_32
-	if (x86_quirks->arch_pre_intr_init) {
-		if (x86_quirks->arch_pre_intr_init())
-			return;
-	}
-#endif
-	init_ISA_irqs();
-}
-
 void __init native_init_IRQ(void)
 {
 	int i;
 
 	/* Execute any quirks before the call gates are initialised: */
-	x86_quirk_pre_intr_init();
+	x86_init.irqs.pre_vector_init();
 
 	apic_intr_init();
 
@@ -258,12 +240,6 @@ void __init native_init_IRQ(void)
 
 #ifdef CONFIG_X86_32
 	/*
-	 * Call quirks after call gates are initialised (usually add in
-	 * the architecture specific gates):
-	 */
-	x86_quirk_intr_init();
-
-	/*
 	 * External FPU? Set up irq13 if so, for
 	 * original braindamaged IBM FERR coupling.
 	 */
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index c664d51..63b0ec8 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -34,7 +34,6 @@
 struct kvm_para_state {
 	u8 mmu_queue[MMU_QUEUE_SIZE];
 	int mmu_queue_len;
-	enum paravirt_lazy_mode mode;
 };
 
 static DEFINE_PER_CPU(struct kvm_para_state, para_state);
@@ -77,7 +76,7 @@ static void kvm_deferred_mmu_op(void *buffer, int len)
 {
 	struct kvm_para_state *state = kvm_para_state();
 
-	if (state->mode != PARAVIRT_LAZY_MMU) {
+	if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU) {
 		kvm_mmu_op(buffer, len);
 		return;
 	}
@@ -185,10 +184,7 @@ static void kvm_release_pt(unsigned long pfn)
 
 static void kvm_enter_lazy_mmu(void)
 {
-	struct kvm_para_state *state = kvm_para_state();
-
 	paravirt_enter_lazy_mmu();
-	state->mode = paravirt_get_lazy_mode();
 }
 
 static void kvm_leave_lazy_mmu(void)
@@ -197,7 +193,6 @@ static void kvm_leave_lazy_mmu(void)
 
 	mmu_queue_flush(state);
 	paravirt_leave_lazy_mmu();
-	state->mode = paravirt_get_lazy_mode();
 }
 
 static void __init paravirt_ops_setup(void)
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 223af43..feaeb0d 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -22,6 +22,8 @@
 #include <asm/msr.h>
 #include <asm/apic.h>
 #include <linux/percpu.h>
+
+#include <asm/x86_init.h>
 #include <asm/reboot.h>
 
 #define KVM_SCALE 22
@@ -50,8 +52,8 @@ static unsigned long kvm_get_wallclock(void)
 	struct timespec ts;
 	int low, high;
 
-	low = (int)__pa(&wall_clock);
-	high = ((u64)__pa(&wall_clock) >> 32);
+	low = (int)__pa_symbol(&wall_clock);
+	high = ((u64)__pa_symbol(&wall_clock) >> 32);
 	native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
 
 	vcpu_time = &get_cpu_var(hv_clock);
@@ -182,12 +184,13 @@ void __init kvmclock_init(void)
 	if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
 		if (kvm_register_clock("boot clock"))
 			return;
-		pv_time_ops.get_wallclock = kvm_get_wallclock;
-		pv_time_ops.set_wallclock = kvm_set_wallclock;
 		pv_time_ops.sched_clock = kvm_clock_read;
-		pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
+		x86_platform.calibrate_tsc = kvm_get_tsc_khz;
+		x86_platform.get_wallclock = kvm_get_wallclock;
+		x86_platform.set_wallclock = kvm_set_wallclock;
 #ifdef CONFIG_X86_LOCAL_APIC
-		pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
+		x86_cpuinit.setup_percpu_clockev =
+			kvm_setup_secondary_clock;
 #endif
 #ifdef CONFIG_SMP
 		smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index 9371448..0db7969 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -236,7 +236,7 @@ static const struct file_operations microcode_fops = {
 static struct miscdevice microcode_dev = {
 	.minor			= MICROCODE_MINOR,
 	.name			= "microcode",
-	.devnode		= "cpu/microcode",
+	.nodename		= "cpu/microcode",
 	.fops			= &microcode_fops,
 };
 
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 651c93b..5be95ef 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -45,6 +45,11 @@ static int __init mpf_checksum(unsigned char *mp, int len)
 	return sum & 0xFF;
 }
 
+int __init default_mpc_apic_id(struct mpc_cpu *m)
+{
+	return m->apicid;
+}
+
 static void __init MP_processor_info(struct mpc_cpu *m)
 {
 	int apicid;
@@ -55,10 +60,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
 		return;
 	}
 
-	if (x86_quirks->mpc_apic_id)
-		apicid = x86_quirks->mpc_apic_id(m);
-	else
-		apicid = m->apicid;
+	apicid = x86_init.mpparse.mpc_apic_id(m);
 
 	if (m->cpuflag & CPU_BOOTPROCESSOR) {
 		bootup_cpu = " (Bootup-CPU)";
@@ -70,16 +72,18 @@ static void __init MP_processor_info(struct mpc_cpu *m)
 }
 
 #ifdef CONFIG_X86_IO_APIC
-static void __init MP_bus_info(struct mpc_bus *m)
+void __init default_mpc_oem_bus_info(struct mpc_bus *m, char *str)
 {
-	char str[7];
 	memcpy(str, m->bustype, 6);
 	str[6] = 0;
+	apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
+}
 
-	if (x86_quirks->mpc_oem_bus_info)
-		x86_quirks->mpc_oem_bus_info(m, str);
-	else
-		apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
+static void __init MP_bus_info(struct mpc_bus *m)
+{
+	char str[7];
+
+	x86_init.mpparse.mpc_oem_bus_info(m, str);
 
 #if MAX_MP_BUSSES < 256
 	if (m->busid >= MAX_MP_BUSSES) {
@@ -96,8 +100,8 @@ static void __init MP_bus_info(struct mpc_bus *m)
 		mp_bus_id_to_type[m->busid] = MP_BUS_ISA;
 #endif
 	} else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
-		if (x86_quirks->mpc_oem_pci_bus)
-			x86_quirks->mpc_oem_pci_bus(m);
+		if (x86_init.mpparse.mpc_oem_pci_bus)
+			x86_init.mpparse.mpc_oem_pci_bus(m);
 
 		clear_bit(m->busid, mp_bus_not_pci);
 #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
@@ -291,6 +295,8 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
 			1, mpc, mpc->length, 1);
 }
 
+void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }
+
 static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
 {
 	char str[16];
@@ -312,16 +318,13 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
 	if (early)
 		return 1;
 
-	if (mpc->oemptr && x86_quirks->smp_read_mpc_oem) {
-		struct mpc_oemtable *oem_table = (void *)(long)mpc->oemptr;
-		x86_quirks->smp_read_mpc_oem(oem_table, mpc->oemsize);
-	}
+	if (mpc->oemptr)
+		x86_init.mpparse.smp_read_mpc_oem(mpc);
 
 	/*
 	 *      Now process the configuration blocks.
 	 */
-	if (x86_quirks->mpc_record)
-		*x86_quirks->mpc_record = 0;
+	x86_init.mpparse.mpc_record(0);
 
 	while (count < mpc->length) {
 		switch (*mpt) {
@@ -353,8 +356,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
 			count = mpc->length;
 			break;
 		}
-		if (x86_quirks->mpc_record)
-			(*x86_quirks->mpc_record)++;
+		x86_init.mpparse.mpc_record(1);
 	}
 
 #ifdef CONFIG_X86_BIGSMP
@@ -482,11 +484,11 @@ static void __init construct_ioapic_table(int mpc_default_type)
 		MP_bus_info(&bus);
 	}
 
-	ioapic.type = MP_IOAPIC;
-	ioapic.apicid = 2;
-	ioapic.apicver = mpc_default_type > 4 ? 0x10 : 0x01;
-	ioapic.flags = MPC_APIC_USABLE;
-	ioapic.apicaddr = 0xFEC00000;
+	ioapic.type	= MP_IOAPIC;
+	ioapic.apicid	= 2;
+	ioapic.apicver	= mpc_default_type > 4 ? 0x10 : 0x01;
+	ioapic.flags	= MPC_APIC_USABLE;
+	ioapic.apicaddr	= IO_APIC_DEFAULT_PHYS_BASE;
 	MP_ioapic_info(&ioapic);
 
 	/*
@@ -608,7 +610,7 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
 /*
  * Scan the memory blocks for an SMP configuration block.
  */
-static void __init __get_smp_config(unsigned int early)
+void __init default_get_smp_config(unsigned int early)
 {
 	struct mpf_intel *mpf = mpf_found;
 
@@ -625,11 +627,6 @@ static void __init __get_smp_config(unsigned int early)
 	if (acpi_lapic && acpi_ioapic)
 		return;
 
-	if (x86_quirks->mach_get_smp_config) {
-		if (x86_quirks->mach_get_smp_config(early))
-			return;
-	}
-
 	printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
 	       mpf->specification);
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
@@ -670,16 +667,6 @@ static void __init __get_smp_config(unsigned int early)
 	 */
 }
 
-void __init early_get_smp_config(void)
-{
-	__get_smp_config(1);
-}
-
-void __init get_smp_config(void)
-{
-	__get_smp_config(0);
-}
-
 static void __init smp_reserve_bootmem(struct mpf_intel *mpf)
 {
 	unsigned long size = get_mpc_size(mpf->physptr);
@@ -745,14 +732,10 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
 	return 0;
 }
 
-static void __init __find_smp_config(unsigned int reserve)
+void __init default_find_smp_config(unsigned int reserve)
 {
 	unsigned int address;
 
-	if (x86_quirks->mach_find_smp_config) {
-		if (x86_quirks->mach_find_smp_config(reserve))
-			return;
-	}
 	/*
 	 * FIXME: Linux assumes you have 640K of base ram..
 	 * this continues the error...
@@ -787,16 +770,6 @@ static void __init __find_smp_config(unsigned int reserve)
 		smp_scan_config(address, 0x400, reserve);
 }
 
-void __init early_find_smp_config(void)
-{
-	__find_smp_config(0);
-}
-
-void __init find_smp_config(void)
-{
-	__find_smp_config(1);
-}
-
 #ifdef CONFIG_X86_IO_APIC
 static u8 __initdata irq_used[MAX_IRQ_SOURCES];
 
diff --git a/arch/x86/kernel/mrst.c b/arch/x86/kernel/mrst.c
new file mode 100644
index 0000000..3b7078a
--- /dev/null
+++ b/arch/x86/kernel/mrst.c
@@ -0,0 +1,24 @@
+/*
+ * mrst.c: Intel Moorestown platform specific setup code
+ *
+ * (C) Copyright 2008 Intel Corporation
+ * Author: Jacob Pan (jacob.jun.pan@intel.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+#include <linux/init.h>
+
+#include <asm/setup.h>
+
+/*
+ * Moorestown specific x86_init function overrides and early setup
+ * calls.
+ */
+void __init x86_mrst_early_setup(void)
+{
+	x86_init.resources.probe_roms = x86_init_noop;
+	x86_init.resources.reserve_resources = x86_init_noop;
+}
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 98fd6cd..6a3cefc 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -1,6 +1,7 @@
 /* ----------------------------------------------------------------------- *
  *
  *   Copyright 2000-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -80,11 +81,8 @@ static ssize_t msr_read(struct file *file, char __user *buf,
 
 	for (; count; count -= 8) {
 		err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]);
-		if (err) {
-			if (err == -EFAULT) /* Fix idiotic error code */
-				err = -EIO;
+		if (err)
 			break;
-		}
 		if (copy_to_user(tmp, &data, 8)) {
 			err = -EFAULT;
 			break;
@@ -115,11 +113,8 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
 			break;
 		}
 		err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]);
-		if (err) {
-			if (err == -EFAULT) /* Fix idiotic error code */
-				err = -EIO;
+		if (err)
 			break;
-		}
 		tmp += 2;
 		bytes += 8;
 	}
@@ -127,6 +122,54 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
 	return bytes ? bytes : err;
 }
 
+static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
+{
+	u32 __user *uregs = (u32 __user *)arg;
+	u32 regs[8];
+	int cpu = iminor(file->f_path.dentry->d_inode);
+	int err;
+
+	switch (ioc) {
+	case X86_IOC_RDMSR_REGS:
+		if (!(file->f_mode & FMODE_READ)) {
+			err = -EBADF;
+			break;
+		}
+		if (copy_from_user(&regs, uregs, sizeof regs)) {
+			err = -EFAULT;
+			break;
+		}
+		err = rdmsr_safe_regs_on_cpu(cpu, regs);
+		if (err)
+			break;
+		if (copy_to_user(uregs, &regs, sizeof regs))
+			err = -EFAULT;
+		break;
+
+	case X86_IOC_WRMSR_REGS:
+		if (!(file->f_mode & FMODE_WRITE)) {
+			err = -EBADF;
+			break;
+		}
+		if (copy_from_user(&regs, uregs, sizeof regs)) {
+			err = -EFAULT;
+			break;
+		}
+		err = wrmsr_safe_regs_on_cpu(cpu, regs);
+		if (err)
+			break;
+		if (copy_to_user(uregs, &regs, sizeof regs))
+			err = -EFAULT;
+		break;
+
+	default:
+		err = -ENOTTY;
+		break;
+	}
+
+	return err;
+}
+
 static int msr_open(struct inode *inode, struct file *file)
 {
 	unsigned int cpu = iminor(file->f_path.dentry->d_inode);
@@ -157,6 +200,8 @@ static const struct file_operations msr_fops = {
 	.read = msr_read,
 	.write = msr_write,
 	.open = msr_open,
+	.unlocked_ioctl = msr_ioctl,
+	.compat_ioctl = msr_ioctl,
 };
 
 static int __cpuinit msr_device_create(int cpu)
@@ -196,7 +241,7 @@ static struct notifier_block __refdata msr_class_cpu_notifier = {
 	.notifier_call = msr_class_cpu_callback,
 };
 
-static char *msr_nodename(struct device *dev)
+static char *msr_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "cpu/%u/msr", MINOR(dev->devt));
 }
@@ -217,7 +262,7 @@ static int __init msr_init(void)
 		err = PTR_ERR(msr_class);
 		goto out_chrdev;
 	}
-	msr_class->nodename = msr_nodename;
+	msr_class->devnode = msr_devnode;
 	for_each_online_cpu(i) {
 		err = msr_device_create(i);
 		if (err != 0)
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 70ec9b9..1b1739d 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -54,17 +54,12 @@ u64 _paravirt_ident_64(u64 x)
 	return x;
 }
 
-static void __init default_banner(void)
+void __init default_banner(void)
 {
 	printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
 	       pv_info.name);
 }
 
-char *memory_setup(void)
-{
-	return pv_init_ops.memory_setup();
-}
-
 /* Simple instruction patching code. */
 #define DEF_NATIVE(ops, name, code)					\
 	extern const char start_##ops##_##name[], end_##ops##_##name[];	\
@@ -188,11 +183,6 @@ unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
 	return insn_len;
 }
 
-void init_IRQ(void)
-{
-	pv_irq_ops.init_IRQ();
-}
-
 static void native_flush_tlb(void)
 {
 	__native_flush_tlb();
@@ -218,13 +208,6 @@ extern void native_irq_enable_sysexit(void);
 extern void native_usergs_sysret32(void);
 extern void native_usergs_sysret64(void);
 
-static int __init print_banner(void)
-{
-	pv_init_ops.banner();
-	return 0;
-}
-core_initcall(print_banner);
-
 static struct resource reserve_ioports = {
 	.start = 0,
 	.end = IO_SPACE_LIMIT,
@@ -320,21 +303,13 @@ struct pv_info pv_info = {
 
 struct pv_init_ops pv_init_ops = {
 	.patch = native_patch,
-	.banner = default_banner,
-	.arch_setup = paravirt_nop,
-	.memory_setup = machine_specific_memory_setup,
 };
 
 struct pv_time_ops pv_time_ops = {
-	.time_init = hpet_time_init,
-	.get_wallclock = native_get_wallclock,
-	.set_wallclock = native_set_wallclock,
 	.sched_clock = native_sched_clock,
-	.get_tsc_khz = native_calibrate_tsc,
 };
 
 struct pv_irq_ops pv_irq_ops = {
-	.init_IRQ = native_init_IRQ,
 	.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
 	.restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
 	.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable),
@@ -362,8 +337,9 @@ struct pv_cpu_ops pv_cpu_ops = {
 #endif
 	.wbinvd = native_wbinvd,
 	.read_msr = native_read_msr_safe,
-	.read_msr_amd = native_read_msr_amd_safe,
+	.rdmsr_regs = native_rdmsr_safe_regs,
 	.write_msr = native_write_msr_safe,
+	.wrmsr_regs = native_wrmsr_safe_regs,
 	.read_tsc = native_read_tsc,
 	.read_pmc = native_read_pmc,
 	.read_tscp = native_read_tscp,
@@ -408,8 +384,6 @@ struct pv_cpu_ops pv_cpu_ops = {
 
 struct pv_apic_ops pv_apic_ops = {
 #ifdef CONFIG_X86_LOCAL_APIC
-	.setup_boot_clock = setup_boot_APIC_clock,
-	.setup_secondary_clock = setup_secondary_APIC_clock,
 	.startup_ipi_hook = paravirt_nop,
 #endif
 };
@@ -423,13 +397,6 @@ struct pv_apic_ops pv_apic_ops = {
 #endif
 
 struct pv_mmu_ops pv_mmu_ops = {
-#ifndef CONFIG_X86_64
-	.pagetable_setup_start = native_pagetable_setup_start,
-	.pagetable_setup_done = native_pagetable_setup_done,
-#else
-	.pagetable_setup_start = paravirt_nop,
-	.pagetable_setup_done = paravirt_nop,
-#endif
 
 	.read_cr2 = native_read_cr2,
 	.write_cr2 = native_write_cr2,
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index d71c865..64b838e 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -225,10 +225,8 @@ static __init int iommu_setup(char *p)
 		if (!strncmp(p, "soft", 4))
 			swiotlb = 1;
 #endif
-		if (!strncmp(p, "pt", 2)) {
+		if (!strncmp(p, "pt", 2))
 			iommu_pass_through = 1;
-			return 1;
-		}
 
 		gart_parse_options(p);
 
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 071166a..847ab41 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -9,7 +9,7 @@
 #include <linux/pm.h>
 #include <linux/clockchips.h>
 #include <linux/random.h>
-#include <trace/power.h>
+#include <trace/events/power.h>
 #include <asm/system.h>
 #include <asm/apic.h>
 #include <asm/syscalls.h>
@@ -25,9 +25,6 @@ EXPORT_SYMBOL(idle_nomwait);
 
 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;
@@ -299,9 +296,7 @@ static inline int hlt_use_halt(void)
 void default_idle(void)
 {
 	if (hlt_use_halt()) {
-		struct power_trace it;
-
-		trace_power_start(&it, POWER_CSTATE, 1);
+		trace_power_start(POWER_CSTATE, 1);
 		current_thread_info()->status &= ~TS_POLLING;
 		/*
 		 * TS_POLLING-cleared state must be visible before we
@@ -314,7 +309,6 @@ void default_idle(void)
 		else
 			local_irq_enable();
 		current_thread_info()->status |= TS_POLLING;
-		trace_power_end(&it);
 	} else {
 		local_irq_enable();
 		/* loop is done by the caller */
@@ -372,9 +366,7 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
  */
 void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
 {
-	struct power_trace it;
-
-	trace_power_start(&it, POWER_CSTATE, (ax>>4)+1);
+	trace_power_start(POWER_CSTATE, (ax>>4)+1);
 	if (!need_resched()) {
 		if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
 			clflush((void *)&current_thread_info()->flags);
@@ -384,15 +376,13 @@ void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
 		if (!need_resched())
 			__mwait(ax, cx);
 	}
-	trace_power_end(&it);
 }
 
 /* Default MONITOR/MWAIT with no hints, used for default C1 state */
 static void mwait_idle(void)
 {
-	struct power_trace it;
 	if (!need_resched()) {
-		trace_power_start(&it, POWER_CSTATE, 1);
+		trace_power_start(POWER_CSTATE, 1);
 		if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
 			clflush((void *)&current_thread_info()->flags);
 
@@ -402,7 +392,6 @@ static void mwait_idle(void)
 			__sti_mwait(0, 0);
 		else
 			local_irq_enable();
-		trace_power_end(&it);
 	} else
 		local_irq_enable();
 }
@@ -414,13 +403,11 @@ static void mwait_idle(void)
  */
 static void poll_idle(void)
 {
-	struct power_trace it;
-
-	trace_power_start(&it, POWER_CSTATE, 0);
+	trace_power_start(POWER_CSTATE, 0);
 	local_irq_enable();
 	while (!need_resched())
 		cpu_relax();
-	trace_power_end(&it);
+	trace_power_end(0);
 }
 
 /*
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 59f4524..4cf7956 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -61,9 +61,6 @@
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
-DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
-EXPORT_PER_CPU_SYMBOL(current_task);
-
 /*
  * Return saved PC of a blocked thread.
  */
@@ -350,14 +347,21 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 				 *next = &next_p->thread;
 	int cpu = smp_processor_id();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
+	bool preload_fpu;
 
 	/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
 
-	__unlazy_fpu(prev_p);
+	/*
+	 * If the task has used fpu the last 5 timeslices, just do a full
+	 * restore of the math state immediately to avoid the trap; the
+	 * chances of needing FPU soon are obviously high now
+	 */
+	preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
 
+	__unlazy_fpu(prev_p);
 
 	/* we're going to use this soon, after a few expensive things */
-	if (next_p->fpu_counter > 5)
+	if (preload_fpu)
 		prefetch(next->xstate);
 
 	/*
@@ -398,6 +402,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 		     task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))
 		__switch_to_xtra(prev_p, next_p, tss);
 
+	/* If we're going to preload the fpu context, make sure clts
+	   is run while we're batching the cpu state updates. */
+	if (preload_fpu)
+		clts();
+
 	/*
 	 * Leave lazy mode, flushing any hypercalls made here.
 	 * This must be done before restoring TLS segments so
@@ -407,15 +416,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	 */
 	arch_end_context_switch(next_p);
 
-	/* If the task has used fpu the last 5 timeslices, just do a full
-	 * restore of the math state immediately to avoid the trap; the
-	 * chances of needing FPU soon are obviously high now
-	 *
-	 * tsk_used_math() checks prevent calling math_state_restore(),
-	 * which can sleep in the case of !tsk_used_math()
-	 */
-	if (tsk_used_math(next_p) && next_p->fpu_counter > 5)
-		math_state_restore();
+	if (preload_fpu)
+		__math_state_restore();
 
 	/*
 	 * Restore %gs if needed (which is common)
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index ebefb54..ad535b6 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -55,9 +55,6 @@
 
 asmlinkage extern void ret_from_fork(void);
 
-DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
-EXPORT_PER_CPU_SYMBOL(current_task);
-
 DEFINE_PER_CPU(unsigned long, old_rsp);
 static DEFINE_PER_CPU(unsigned char, is_idle);
 
@@ -386,9 +383,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 	int cpu = smp_processor_id();
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
 	unsigned fsindex, gsindex;
+	bool preload_fpu;
+
+	/*
+	 * If the task has used fpu the last 5 timeslices, just do a full
+	 * restore of the math state immediately to avoid the trap; the
+	 * chances of needing FPU soon are obviously high now
+	 */
+	preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
 
 	/* we're going to use this soon, after a few expensive things */
-	if (next_p->fpu_counter > 5)
+	if (preload_fpu)
 		prefetch(next->xstate);
 
 	/*
@@ -419,6 +424,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 
 	load_TLS(next, cpu);
 
+	/* Must be after DS reload */
+	unlazy_fpu(prev_p);
+
+	/* Make sure cpu is ready for new context */
+	if (preload_fpu)
+		clts();
+
 	/*
 	 * Leave lazy mode, flushing any hypercalls made here.
 	 * This must be done before restoring TLS segments so
@@ -459,9 +471,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 		wrmsrl(MSR_KERNEL_GS_BASE, next->gs);
 	prev->gsindex = gsindex;
 
-	/* Must be after DS reload */
-	unlazy_fpu(prev_p);
-
 	/*
 	 * Switch the PDA and FPU contexts.
 	 */
@@ -480,15 +489,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 		     task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
 		__switch_to_xtra(prev_p, next_p, tss);
 
-	/* If the task has used fpu the last 5 timeslices, just do a full
-	 * restore of the math state immediately to avoid the trap; the
-	 * chances of needing FPU soon are obviously high now
-	 *
-	 * tsk_used_math() checks prevent calling math_state_restore(),
-	 * which can sleep in the case of !tsk_used_math()
+	/*
+	 * Preload the FPU context, now that we've determined that the
+	 * task is likely to be using it. 
 	 */
-	if (tsk_used_math(next_p) && next_p->fpu_counter > 5)
-		math_state_restore();
+	if (preload_fpu)
+		__math_state_restore();
 	return prev_p;
 }
 
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index af71d06..6c3b2c6 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -508,7 +508,7 @@ static void __init quirk_amd_nb_node(struct pci_dev *dev)
 
 	pci_read_config_dword(nb_ht, 0x60, &val);
 	set_dev_node(&dev->dev, val & 7);
-	pci_dev_put(dev);
+	pci_dev_put(nb_ht);
 }
 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB,
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index a06e8d1..27349f9 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -4,6 +4,7 @@
 #include <linux/pm.h>
 #include <linux/efi.h>
 #include <linux/dmi.h>
+#include <linux/tboot.h>
 #include <acpi/reboot.h>
 #include <asm/io.h>
 #include <asm/apic.h>
@@ -508,6 +509,8 @@ static void native_machine_emergency_restart(void)
 	if (reboot_emergency)
 		emergency_vmx_disable_all();
 
+	tboot_shutdown(TB_SHUTDOWN_REBOOT);
+
 	/* Tell the BIOS if we want cold or warm reboot */
 	*((unsigned short *)__va(0x472)) = reboot_mode;
 
@@ -634,6 +637,8 @@ static void native_machine_halt(void)
 	/* stop other cpus and apics */
 	machine_shutdown();
 
+	tboot_shutdown(TB_SHUTDOWN_HALT);
+
 	/* stop this cpu */
 	stop_this_cpu(NULL);
 }
@@ -645,6 +650,8 @@ static void native_machine_power_off(void)
 			machine_shutdown();
 		pm_power_off();
 	}
+	/* a fallback in case there is no PM info available */
+	tboot_shutdown(TB_SHUTDOWN_HALT);
 }
 
 struct machine_ops machine_ops = {
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 5d465b2..1cfbbfc 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -8,6 +8,7 @@
 #include <linux/pnp.h>
 
 #include <asm/vsyscall.h>
+#include <asm/x86_init.h>
 #include <asm/time.h>
 
 #ifdef CONFIG_X86_32
@@ -165,33 +166,29 @@ void rtc_cmos_write(unsigned char val, unsigned char addr)
 }
 EXPORT_SYMBOL(rtc_cmos_write);
 
-static int set_rtc_mmss(unsigned long nowtime)
+int update_persistent_clock(struct timespec now)
 {
 	unsigned long flags;
 	int retval;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	retval = set_wallclock(nowtime);
+	retval = x86_platform.set_wallclock(now.tv_sec);
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
 	return retval;
 }
 
 /* not static: needed by APM */
-unsigned long read_persistent_clock(void)
+void read_persistent_clock(struct timespec *ts)
 {
 	unsigned long retval, flags;
 
 	spin_lock_irqsave(&rtc_lock, flags);
-	retval = get_wallclock();
+	retval = x86_platform.get_wallclock();
 	spin_unlock_irqrestore(&rtc_lock, flags);
 
-	return retval;
-}
-
-int update_persistent_clock(struct timespec now)
-{
-	return set_rtc_mmss(now.tv_sec);
+	ts->tv_sec = retval;
+	ts->tv_nsec = 0;
 }
 
 unsigned long long native_read_tsc(void)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 63f32d2..f327bcc 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -66,6 +66,7 @@
 
 #include <linux/percpu.h>
 #include <linux/crash_dump.h>
+#include <linux/tboot.h>
 
 #include <video/edid.h>
 
@@ -108,10 +109,6 @@
 #include <asm/numa_64.h>
 #endif
 
-#ifndef ARCH_SETUP
-#define ARCH_SETUP
-#endif
-
 /*
  * end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
  * The direct mapping extends to max_pfn_mapped, so that we can directly access
@@ -133,9 +130,9 @@ int default_cpu_present_to_apicid(int mps_cpu)
 	return __default_cpu_present_to_apicid(mps_cpu);
 }
 
-int default_check_phys_apicid_present(int boot_cpu_physical_apicid)
+int default_check_phys_apicid_present(int phys_apicid)
 {
-	return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
+	return __default_check_phys_apicid_present(phys_apicid);
 }
 #endif
 
@@ -171,13 +168,6 @@ static struct resource bss_resource = {
 
 
 #ifdef CONFIG_X86_32
-static struct resource video_ram_resource = {
-	.name	= "Video RAM area",
-	.start	= 0xa0000,
-	.end	= 0xbffff,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
-};
-
 /* cpu data as detected by the assembly code in head.S */
 struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
 /* common cpu data for all cpus */
@@ -605,7 +595,7 @@ static struct resource standard_io_resources[] = {
 		.flags = IORESOURCE_BUSY | IORESOURCE_IO }
 };
 
-static void __init reserve_standard_io_resources(void)
+void __init reserve_standard_io_resources(void)
 {
 	int i;
 
@@ -637,10 +627,6 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
-static struct x86_quirks default_x86_quirks __initdata;
-
-struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
-
 #ifdef CONFIG_X86_RESERVE_LOW_64K
 static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
 {
@@ -757,7 +743,7 @@ void __init setup_arch(char **cmdline_p)
 	}
 #endif
 
-	ARCH_SETUP
+	x86_init.oem.arch_setup();
 
 	setup_memory_map();
 	parse_setup_data();
@@ -796,6 +782,16 @@ void __init setup_arch(char **cmdline_p)
 	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
 	*cmdline_p = command_line;
 
+#ifdef CONFIG_X86_64
+	/*
+	 * Must call this twice: Once just to detect whether hardware doesn't
+	 * support NX (so that the early EHCI debug console setup can safely
+	 * call set_fixmap(), and then again after parsing early parameters to
+	 * honor the respective command line option.
+	 */
+	check_efer();
+#endif
+
 	parse_early_param();
 
 #ifdef CONFIG_X86_64
@@ -833,11 +829,9 @@ void __init setup_arch(char **cmdline_p)
 	 * VMware detection requires dmi to be available, so this
 	 * needs to be done after dmi_scan_machine, for the BP.
 	 */
-	init_hypervisor(&boot_cpu_data);
+	init_hypervisor_platform();
 
-#ifdef CONFIG_X86_32
-	probe_roms();
-#endif
+	x86_init.resources.probe_roms();
 
 	/* after parse_early_param, so could debug it */
 	insert_resource(&iomem_resource, &code_resource);
@@ -972,10 +966,11 @@ void __init setup_arch(char **cmdline_p)
 	kvmclock_init();
 #endif
 
-	paravirt_pagetable_setup_start(swapper_pg_dir);
+	x86_init.paging.pagetable_setup_start(swapper_pg_dir);
 	paging_init();
-	paravirt_pagetable_setup_done(swapper_pg_dir);
-	paravirt_post_allocator_init();
+	x86_init.paging.pagetable_setup_done(swapper_pg_dir);
+
+	tboot_probe();
 
 #ifdef CONFIG_X86_64
 	map_vsyscall();
@@ -990,13 +985,11 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	acpi_boot_init();
 
-#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS)
 	/*
 	 * get boot-time SMP configuration:
 	 */
 	if (smp_found_config)
 		get_smp_config();
-#endif
 
 	prefill_possible_map();
 
@@ -1015,10 +1008,7 @@ void __init setup_arch(char **cmdline_p)
 	e820_reserve_resources();
 	e820_mark_nosave_regions(max_low_pfn);
 
-#ifdef CONFIG_X86_32
-	request_resource(&iomem_resource, &video_ram_resource);
-#endif
-	reserve_standard_io_resources();
+	x86_init.resources.reserve_resources();
 
 	e820_setup_gap();
 
@@ -1030,78 +1020,22 @@ void __init setup_arch(char **cmdline_p)
 	conswitchp = &dummy_con;
 #endif
 #endif
+	x86_init.oem.banner();
 }
 
 #ifdef CONFIG_X86_32
 
-/**
- * x86_quirk_intr_init - post gate setup interrupt initialisation
- *
- * Description:
- *	Fill in any interrupts that may have been left out by the general
- *	init_IRQ() routine.  interrupts having to do with the machine rather
- *	than the devices on the I/O bus (like APIC interrupts in intel MP
- *	systems) are started here.
- **/
-void __init x86_quirk_intr_init(void)
-{
-	if (x86_quirks->arch_intr_init) {
-		if (x86_quirks->arch_intr_init())
-			return;
-	}
-}
-
-/**
- * x86_quirk_trap_init - initialise system specific traps
- *
- * Description:
- *	Called as the final act of trap_init().  Used in VISWS to initialise
- *	the various board specific APIC traps.
- **/
-void __init x86_quirk_trap_init(void)
-{
-	if (x86_quirks->arch_trap_init) {
-		if (x86_quirks->arch_trap_init())
-			return;
-	}
-}
-
-static struct irqaction irq0  = {
-	.handler = timer_interrupt,
-	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
-	.name = "timer"
+static struct resource video_ram_resource = {
+	.name	= "Video RAM area",
+	.start	= 0xa0000,
+	.end	= 0xbffff,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM
 };
 
-/**
- * x86_quirk_pre_time_init - do any specific initialisations before.
- *
- **/
-void __init x86_quirk_pre_time_init(void)
+void __init i386_reserve_resources(void)
 {
-	if (x86_quirks->arch_pre_time_init)
-		x86_quirks->arch_pre_time_init();
+	request_resource(&iomem_resource, &video_ram_resource);
+	reserve_standard_io_resources();
 }
 
-/**
- * x86_quirk_time_init - do any specific initialisations for the system timer.
- *
- * Description:
- *	Must plug the system timer interrupt source at HZ into the IRQ listed
- *	in irq_vectors.h:TIMER_IRQ
- **/
-void __init x86_quirk_time_init(void)
-{
-	if (x86_quirks->arch_time_init) {
-		/*
-		 * A nonzero return code does not mean failure, it means
-		 * that the architecture quirk does not want any
-		 * generic (timer) setup to be performed after this:
-		 */
-		if (x86_quirks->arch_time_init())
-			return;
-	}
-
-	irq0.mask = cpumask_of_cpu(0);
-	setup_irq(0, &irq0);
-}
 #endif /* CONFIG_X86_32 */
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 07d8191..d559af9 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -55,6 +55,7 @@ EXPORT_SYMBOL(__per_cpu_offset);
 #define PERCPU_FIRST_CHUNK_RESERVE	0
 #endif
 
+#ifdef CONFIG_X86_32
 /**
  * pcpu_need_numa - determine percpu allocation needs to consider NUMA
  *
@@ -83,6 +84,7 @@ static bool __init pcpu_need_numa(void)
 #endif
 	return false;
 }
+#endif
 
 /**
  * pcpu_alloc_bootmem - NUMA friendly alloc_bootmem wrapper for percpu
@@ -124,308 +126,35 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size,
 }
 
 /*
- * Large page remap allocator
- *
- * This allocator uses PMD page as unit.  A PMD page is allocated for
- * each cpu and each is remapped into vmalloc area using PMD mapping.
- * As PMD page is quite large, only part of it is used for the first
- * chunk.  Unused part is returned to the bootmem allocator.
- *
- * So, the PMD pages are mapped twice - once to the physical mapping
- * and to the vmalloc area for the first percpu chunk.  The double
- * mapping does add one more PMD TLB entry pressure but still is much
- * better than only using 4k mappings while still being NUMA friendly.
+ * Helpers for first chunk memory allocation
  */
-#ifdef CONFIG_NEED_MULTIPLE_NODES
-struct pcpul_ent {
-	unsigned int	cpu;
-	void		*ptr;
-};
-
-static size_t pcpul_size;
-static struct pcpul_ent *pcpul_map;
-static struct vm_struct pcpul_vm;
-
-static struct page * __init pcpul_get_page(unsigned int cpu, int pageno)
+static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
 {
-	size_t off = (size_t)pageno << PAGE_SHIFT;
-
-	if (off >= pcpul_size)
-		return NULL;
-
-	return virt_to_page(pcpul_map[cpu].ptr + off);
+	return pcpu_alloc_bootmem(cpu, size, align);
 }
 
-static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
+static void __init pcpu_fc_free(void *ptr, size_t size)
 {
-	size_t map_size, dyn_size;
-	unsigned int cpu;
-	int i, j;
-	ssize_t ret;
-
-	if (!chosen) {
-		size_t vm_size = VMALLOC_END - VMALLOC_START;
-		size_t tot_size = nr_cpu_ids * PMD_SIZE;
-
-		/* on non-NUMA, embedding is better */
-		if (!pcpu_need_numa())
-			return -EINVAL;
-
-		/* don't consume more than 20% of vmalloc area */
-		if (tot_size > vm_size / 5) {
-			pr_info("PERCPU: too large chunk size %zuMB for "
-				"large page remap\n", tot_size >> 20);
-			return -EINVAL;
-		}
-	}
-
-	/* need PSE */
-	if (!cpu_has_pse) {
-		pr_warning("PERCPU: lpage allocator requires PSE\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * Currently supports only single page.  Supporting multiple
-	 * pages won't be too difficult if it ever becomes necessary.
-	 */
-	pcpul_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
-			       PERCPU_DYNAMIC_RESERVE);
-	if (pcpul_size > PMD_SIZE) {
-		pr_warning("PERCPU: static data is larger than large page, "
-			   "can't use large page\n");
-		return -EINVAL;
-	}
-	dyn_size = pcpul_size - static_size - PERCPU_FIRST_CHUNK_RESERVE;
-
-	/* allocate pointer array and alloc large pages */
-	map_size = PFN_ALIGN(nr_cpu_ids * sizeof(pcpul_map[0]));
-	pcpul_map = alloc_bootmem(map_size);
-
-	for_each_possible_cpu(cpu) {
-		pcpul_map[cpu].cpu = cpu;
-		pcpul_map[cpu].ptr = pcpu_alloc_bootmem(cpu, PMD_SIZE,
-							PMD_SIZE);
-		if (!pcpul_map[cpu].ptr) {
-			pr_warning("PERCPU: failed to allocate large page "
-				   "for cpu%u\n", cpu);
-			goto enomem;
-		}
-
-		/*
-		 * Only use pcpul_size bytes and give back the rest.
-		 *
-		 * Ingo: The 2MB up-rounding bootmem is needed to make
-		 * sure the partial 2MB page is still fully RAM - it's
-		 * not well-specified to have a PAT-incompatible area
-		 * (unmapped RAM, device memory, etc.) in that hole.
-		 */
-		free_bootmem(__pa(pcpul_map[cpu].ptr + pcpul_size),
-			     PMD_SIZE - pcpul_size);
-
-		memcpy(pcpul_map[cpu].ptr, __per_cpu_load, static_size);
-	}
-
-	/* allocate address and map */
-	pcpul_vm.flags = VM_ALLOC;
-	pcpul_vm.size = nr_cpu_ids * PMD_SIZE;
-	vm_area_register_early(&pcpul_vm, PMD_SIZE);
-
-	for_each_possible_cpu(cpu) {
-		pmd_t *pmd, pmd_v;
-
-		pmd = populate_extra_pmd((unsigned long)pcpul_vm.addr +
-					 cpu * PMD_SIZE);
-		pmd_v = pfn_pmd(page_to_pfn(virt_to_page(pcpul_map[cpu].ptr)),
-				PAGE_KERNEL_LARGE);
-		set_pmd(pmd, pmd_v);
-	}
-
-	/* we're ready, commit */
-	pr_info("PERCPU: Remapped at %p with large pages, static data "
-		"%zu bytes\n", pcpul_vm.addr, static_size);
-
-	ret = pcpu_setup_first_chunk(pcpul_get_page, static_size,
-				     PERCPU_FIRST_CHUNK_RESERVE, dyn_size,
-				     PMD_SIZE, pcpul_vm.addr, NULL);
-
-	/* sort pcpul_map array for pcpu_lpage_remapped() */
-	for (i = 0; i < nr_cpu_ids - 1; i++)
-		for (j = i + 1; j < nr_cpu_ids; j++)
-			if (pcpul_map[i].ptr > pcpul_map[j].ptr) {
-				struct pcpul_ent tmp = pcpul_map[i];
-				pcpul_map[i] = pcpul_map[j];
-				pcpul_map[j] = tmp;
-			}
-
-	return ret;
-
-enomem:
-	for_each_possible_cpu(cpu)
-		if (pcpul_map[cpu].ptr)
-			free_bootmem(__pa(pcpul_map[cpu].ptr), pcpul_size);
-	free_bootmem(__pa(pcpul_map), map_size);
-	return -ENOMEM;
+	free_bootmem(__pa(ptr), size);
 }
 
-/**
- * pcpu_lpage_remapped - determine whether a kaddr is in pcpul recycled area
- * @kaddr: the kernel address in question
- *
- * Determine whether @kaddr falls in the pcpul recycled area.  This is
- * used by pageattr to detect VM aliases and break up the pcpu PMD
- * mapping such that the same physical page is not mapped under
- * different attributes.
- *
- * The recycled area is always at the tail of a partially used PMD
- * page.
- *
- * RETURNS:
- * Address of corresponding remapped pcpu address if match is found;
- * otherwise, NULL.
- */
-void *pcpu_lpage_remapped(void *kaddr)
+static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
 {
-	void *pmd_addr = (void *)((unsigned long)kaddr & PMD_MASK);
-	unsigned long offset = (unsigned long)kaddr & ~PMD_MASK;
-	int left = 0, right = nr_cpu_ids - 1;
-	int pos;
-
-	/* pcpul in use at all? */
-	if (!pcpul_map)
-		return NULL;
-
-	/* okay, perform binary search */
-	while (left <= right) {
-		pos = (left + right) / 2;
-
-		if (pcpul_map[pos].ptr < pmd_addr)
-			left = pos + 1;
-		else if (pcpul_map[pos].ptr > pmd_addr)
-			right = pos - 1;
-		else {
-			/* it shouldn't be in the area for the first chunk */
-			WARN_ON(offset < pcpul_size);
-
-			return pcpul_vm.addr +
-				pcpul_map[pos].cpu * PMD_SIZE + offset;
-		}
-	}
-
-	return NULL;
-}
+#ifdef CONFIG_NEED_MULTIPLE_NODES
+	if (early_cpu_to_node(from) == early_cpu_to_node(to))
+		return LOCAL_DISTANCE;
+	else
+		return REMOTE_DISTANCE;
 #else
-static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
-{
-	return -EINVAL;
-}
+	return LOCAL_DISTANCE;
 #endif
-
-/*
- * Embedding allocator
- *
- * The first chunk is sized to just contain the static area plus
- * module and dynamic reserves and embedded into linear physical
- * mapping so that it can use PMD mapping without additional TLB
- * pressure.
- */
-static ssize_t __init setup_pcpu_embed(size_t static_size, bool chosen)
-{
-	size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
-
-	/*
-	 * If large page isn't supported, there's no benefit in doing
-	 * this.  Also, embedding allocation doesn't play well with
-	 * NUMA.
-	 */
-	if (!chosen && (!cpu_has_pse || pcpu_need_numa()))
-		return -EINVAL;
-
-	return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE,
-				      reserve - PERCPU_FIRST_CHUNK_RESERVE, -1);
 }
 
-/*
- * 4k page allocator
- *
- * This is the basic allocator.  Static percpu area is allocated
- * page-by-page and most of initialization is done by the generic
- * setup function.
- */
-static struct page **pcpu4k_pages __initdata;
-static int pcpu4k_nr_static_pages __initdata;
-
-static struct page * __init pcpu4k_get_page(unsigned int cpu, int pageno)
-{
-	if (pageno < pcpu4k_nr_static_pages)
-		return pcpu4k_pages[cpu * pcpu4k_nr_static_pages + pageno];
-	return NULL;
-}
-
-static void __init pcpu4k_populate_pte(unsigned long addr)
+static void __init pcpup_populate_pte(unsigned long addr)
 {
 	populate_extra_pte(addr);
 }
 
-static ssize_t __init setup_pcpu_4k(size_t static_size)
-{
-	size_t pages_size;
-	unsigned int cpu;
-	int i, j;
-	ssize_t ret;
-
-	pcpu4k_nr_static_pages = PFN_UP(static_size);
-
-	/* unaligned allocations can't be freed, round up to page size */
-	pages_size = PFN_ALIGN(pcpu4k_nr_static_pages * nr_cpu_ids
-			       * sizeof(pcpu4k_pages[0]));
-	pcpu4k_pages = alloc_bootmem(pages_size);
-
-	/* allocate and copy */
-	j = 0;
-	for_each_possible_cpu(cpu)
-		for (i = 0; i < pcpu4k_nr_static_pages; i++) {
-			void *ptr;
-
-			ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE);
-			if (!ptr) {
-				pr_warning("PERCPU: failed to allocate "
-					   "4k page for cpu%u\n", cpu);
-				goto enomem;
-			}
-
-			memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE);
-			pcpu4k_pages[j++] = virt_to_page(ptr);
-		}
-
-	/* we're ready, commit */
-	pr_info("PERCPU: Allocated %d 4k pages, static data %zu bytes\n",
-		pcpu4k_nr_static_pages, static_size);
-
-	ret = pcpu_setup_first_chunk(pcpu4k_get_page, static_size,
-				     PERCPU_FIRST_CHUNK_RESERVE, -1,
-				     -1, NULL, pcpu4k_populate_pte);
-	goto out_free_ar;
-
-enomem:
-	while (--j >= 0)
-		free_bootmem(__pa(page_address(pcpu4k_pages[j])), PAGE_SIZE);
-	ret = -ENOMEM;
-out_free_ar:
-	free_bootmem(__pa(pcpu4k_pages), pages_size);
-	return ret;
-}
-
-/* for explicit first chunk allocator selection */
-static char pcpu_chosen_alloc[16] __initdata;
-
-static int __init percpu_alloc_setup(char *str)
-{
-	strncpy(pcpu_chosen_alloc, str, sizeof(pcpu_chosen_alloc) - 1);
-	return 0;
-}
-early_param("percpu_alloc", percpu_alloc_setup);
-
 static inline void setup_percpu_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
@@ -441,52 +170,49 @@ static inline void setup_percpu_segment(int cpu)
 
 void __init setup_per_cpu_areas(void)
 {
-	size_t static_size = __per_cpu_end - __per_cpu_start;
 	unsigned int cpu;
 	unsigned long delta;
-	size_t pcpu_unit_size;
-	ssize_t ret;
+	int rc;
 
 	pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n",
 		NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids);
 
 	/*
-	 * Allocate percpu area.  If PSE is supported, try to make use
-	 * of large page mappings.  Please read comments on top of
-	 * each allocator for details.
+	 * Allocate percpu area.  Embedding allocator is our favorite;
+	 * however, on NUMA configurations, it can result in very
+	 * sparse unit mapping and vmalloc area isn't spacious enough
+	 * on 32bit.  Use page in that case.
 	 */
-	ret = -EINVAL;
-	if (strlen(pcpu_chosen_alloc)) {
-		if (strcmp(pcpu_chosen_alloc, "4k")) {
-			if (!strcmp(pcpu_chosen_alloc, "lpage"))
-				ret = setup_pcpu_lpage(static_size, true);
-			else if (!strcmp(pcpu_chosen_alloc, "embed"))
-				ret = setup_pcpu_embed(static_size, true);
-			else
-				pr_warning("PERCPU: unknown allocator %s "
-					   "specified\n", pcpu_chosen_alloc);
-			if (ret < 0)
-				pr_warning("PERCPU: %s allocator failed (%zd), "
-					   "falling back to 4k\n",
-					   pcpu_chosen_alloc, ret);
-		}
-	} else {
-		ret = setup_pcpu_lpage(static_size, false);
-		if (ret < 0)
-			ret = setup_pcpu_embed(static_size, false);
+#ifdef CONFIG_X86_32
+	if (pcpu_chosen_fc == PCPU_FC_AUTO && pcpu_need_numa())
+		pcpu_chosen_fc = PCPU_FC_PAGE;
+#endif
+	rc = -EINVAL;
+	if (pcpu_chosen_fc != PCPU_FC_PAGE) {
+		const size_t atom_size = cpu_has_pse ? PMD_SIZE : PAGE_SIZE;
+		const size_t dyn_size = PERCPU_MODULE_RESERVE +
+			PERCPU_DYNAMIC_RESERVE - PERCPU_FIRST_CHUNK_RESERVE;
+
+		rc = pcpu_embed_first_chunk(PERCPU_FIRST_CHUNK_RESERVE,
+					    dyn_size, atom_size,
+					    pcpu_cpu_distance,
+					    pcpu_fc_alloc, pcpu_fc_free);
+		if (rc < 0)
+			pr_warning("PERCPU: %s allocator failed (%d), "
+				   "falling back to page size\n",
+				   pcpu_fc_names[pcpu_chosen_fc], rc);
 	}
-	if (ret < 0)
-		ret = setup_pcpu_4k(static_size);
-	if (ret < 0)
-		panic("cannot allocate static percpu area (%zu bytes, err=%zd)",
-		      static_size, ret);
-
-	pcpu_unit_size = ret;
+	if (rc < 0)
+		rc = pcpu_page_first_chunk(PERCPU_FIRST_CHUNK_RESERVE,
+					   pcpu_fc_alloc, pcpu_fc_free,
+					   pcpup_populate_pte);
+	if (rc < 0)
+		panic("cannot initialize percpu area (err=%d)", rc);
 
 	/* alrighty, percpu areas up and running */
 	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
 	for_each_possible_cpu(cpu) {
-		per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size;
+		per_cpu_offset(cpu) = delta + pcpu_unit_offsets[cpu];
 		per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
 		per_cpu(cpu_number, cpu) = cpu;
 		setup_percpu_segment(cpu);
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 81e5823..6a44a76 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -856,7 +856,7 @@ static void do_signal(struct pt_regs *regs)
 void
 do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
 {
-#ifdef CONFIG_X86_NEW_MCE
+#ifdef CONFIG_X86_MCE
 	/* notify userspace of pending MCEs */
 	if (thread_info_flags & _TIF_MCE_NOTIFY)
 		mce_notify_process();
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 2fecda6..09c5e07 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -47,6 +47,7 @@
 #include <linux/bootmem.h>
 #include <linux/err.h>
 #include <linux/nmi.h>
+#include <linux/tboot.h>
 
 #include <asm/acpi.h>
 #include <asm/desc.h>
@@ -323,7 +324,7 @@ notrace static void __cpuinit start_secondary(void *unused)
 	/* enable local interrupts */
 	local_irq_enable();
 
-	setup_secondary_clock();
+	x86_cpuinit.setup_percpu_clockev();
 
 	wmb();
 	cpu_idle();
@@ -434,7 +435,8 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
 	 * For perf, we return last level cache shared map.
 	 * And for power savings, we return cpu_core_map
 	 */
-	if (sched_mc_power_savings || sched_smt_power_savings)
+	if ((sched_mc_power_savings || sched_smt_power_savings) &&
+	    !(cpu_has(c, X86_FEATURE_AMD_DCM)))
 		return cpu_core_mask(cpu);
 	else
 		return c->llc_shared_map;
@@ -1112,13 +1114,26 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 
 	printk(KERN_INFO "CPU%d: ", 0);
 	print_cpu_info(&cpu_data(0));
-	setup_boot_clock();
+	x86_init.timers.setup_percpu_clockev();
 
 	if (is_uv_system())
 		uv_system_init();
+
+	set_mtrr_aps_delayed_init();
 out:
 	preempt_enable();
 }
+
+void arch_enable_nonboot_cpus_begin(void)
+{
+	set_mtrr_aps_delayed_init();
+}
+
+void arch_enable_nonboot_cpus_end(void)
+{
+	mtrr_aps_init();
+}
+
 /*
  * Early setup to make printk work.
  */
@@ -1140,6 +1155,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
 	setup_ioapic_dest();
 #endif
 	check_nmi_watchdog();
+	mtrr_aps_init();
 }
 
 static int __initdata setup_possible_cpus = -1;
@@ -1317,6 +1333,7 @@ void play_dead_common(void)
 void native_play_dead(void)
 {
 	play_dead_common();
+	tboot_shutdown(TB_SHUTDOWN_WFS);
 	wbinvd_halt();
 }
 
diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
index e8b9863..3149032 100644
--- a/arch/x86/kernel/step.c
+++ b/arch/x86/kernel/step.c
@@ -4,6 +4,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/ptrace.h>
+#include <asm/desc.h>
 
 unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs)
 {
@@ -23,7 +24,7 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
 	 * and APM bios ones we just ignore here.
 	 */
 	if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
-		u32 *desc;
+		struct desc_struct *desc;
 		unsigned long base;
 
 		seg &= ~7UL;
@@ -33,12 +34,10 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re
 			addr = -1L; /* bogus selector, access would fault */
 		else {
 			desc = child->mm->context.ldt + seg;
-			base = ((desc[0] >> 16) |
-				((desc[1] & 0xff) << 16) |
-				(desc[1] & 0xff000000));
+			base = get_desc_base(desc);
 
 			/* 16-bit code segment? */
-			if (!((desc[1] >> 22) & 1))
+			if (!desc->d)
 				addr &= 0xffff;
 			addr += base;
 		}
diff --git a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
index d51321d..0157cd2 100644
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -335,4 +335,4 @@ ENTRY(sys_call_table)
 	.long sys_preadv
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo	/* 335 */
-	.long sys_perf_counter_open
+	.long sys_perf_event_open
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
new file mode 100644
index 0000000..86c9f91
--- /dev/null
+++ b/arch/x86/kernel/tboot.c
@@ -0,0 +1,447 @@
+/*
+ * tboot.c: main implementation of helper functions used by kernel for
+ *          runtime support of Intel(R) Trusted Execution Technology
+ *
+ * Copyright (c) 2006-2009, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/dma_remapping.h>
+#include <linux/init_task.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/dmar.h>
+#include <linux/cpu.h>
+#include <linux/pfn.h>
+#include <linux/mm.h>
+#include <linux/tboot.h>
+
+#include <asm/trampoline.h>
+#include <asm/processor.h>
+#include <asm/bootparam.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/fixmap.h>
+#include <asm/proto.h>
+#include <asm/setup.h>
+#include <asm/e820.h>
+#include <asm/io.h>
+
+#include "acpi/realmode/wakeup.h"
+
+/* Global pointer to shared data; NULL means no measured launch. */
+struct tboot *tboot __read_mostly;
+
+/* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */
+#define AP_WAIT_TIMEOUT		1
+
+#undef pr_fmt
+#define pr_fmt(fmt)	"tboot: " fmt
+
+static u8 tboot_uuid[16] __initdata = TBOOT_UUID;
+
+void __init tboot_probe(void)
+{
+	/* Look for valid page-aligned address for shared page. */
+	if (!boot_params.tboot_addr)
+		return;
+	/*
+	 * also verify that it is mapped as we expect it before calling
+	 * set_fixmap(), to reduce chance of garbage value causing crash
+	 */
+	if (!e820_any_mapped(boot_params.tboot_addr,
+			     boot_params.tboot_addr, E820_RESERVED)) {
+		pr_warning("non-0 tboot_addr but it is not of type E820_RESERVED\n");
+		return;
+	}
+
+	/* only a natively booted kernel should be using TXT */
+	if (paravirt_enabled()) {
+		pr_warning("non-0 tboot_addr but pv_ops is enabled\n");
+		return;
+	}
+
+	/* Map and check for tboot UUID. */
+	set_fixmap(FIX_TBOOT_BASE, boot_params.tboot_addr);
+	tboot = (struct tboot *)fix_to_virt(FIX_TBOOT_BASE);
+	if (memcmp(&tboot_uuid, &tboot->uuid, sizeof(tboot->uuid))) {
+		pr_warning("tboot at 0x%llx is invalid\n",
+			   boot_params.tboot_addr);
+		tboot = NULL;
+		return;
+	}
+	if (tboot->version < 5) {
+		pr_warning("tboot version is invalid: %u\n", tboot->version);
+		tboot = NULL;
+		return;
+	}
+
+	pr_info("found shared page at phys addr 0x%llx:\n",
+		boot_params.tboot_addr);
+	pr_debug("version: %d\n", tboot->version);
+	pr_debug("log_addr: 0x%08x\n", tboot->log_addr);
+	pr_debug("shutdown_entry: 0x%x\n", tboot->shutdown_entry);
+	pr_debug("tboot_base: 0x%08x\n", tboot->tboot_base);
+	pr_debug("tboot_size: 0x%x\n", tboot->tboot_size);
+}
+
+static pgd_t *tboot_pg_dir;
+static struct mm_struct tboot_mm = {
+	.mm_rb          = RB_ROOT,
+	.pgd            = swapper_pg_dir,
+	.mm_users       = ATOMIC_INIT(2),
+	.mm_count       = ATOMIC_INIT(1),
+	.mmap_sem       = __RWSEM_INITIALIZER(init_mm.mmap_sem),
+	.page_table_lock =  __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
+	.mmlist         = LIST_HEAD_INIT(init_mm.mmlist),
+	.cpu_vm_mask    = CPU_MASK_ALL,
+};
+
+static inline void switch_to_tboot_pt(void)
+{
+	write_cr3(virt_to_phys(tboot_pg_dir));
+}
+
+static int map_tboot_page(unsigned long vaddr, unsigned long pfn,
+			  pgprot_t prot)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	pgd = pgd_offset(&tboot_mm, vaddr);
+	pud = pud_alloc(&tboot_mm, pgd, vaddr);
+	if (!pud)
+		return -1;
+	pmd = pmd_alloc(&tboot_mm, pud, vaddr);
+	if (!pmd)
+		return -1;
+	pte = pte_alloc_map(&tboot_mm, pmd, vaddr);
+	if (!pte)
+		return -1;
+	set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot));
+	pte_unmap(pte);
+	return 0;
+}
+
+static int map_tboot_pages(unsigned long vaddr, unsigned long start_pfn,
+			   unsigned long nr)
+{
+	/* Reuse the original kernel mapping */
+	tboot_pg_dir = pgd_alloc(&tboot_mm);
+	if (!tboot_pg_dir)
+		return -1;
+
+	for (; nr > 0; nr--, vaddr += PAGE_SIZE, start_pfn++) {
+		if (map_tboot_page(vaddr, start_pfn, PAGE_KERNEL_EXEC))
+			return -1;
+	}
+
+	return 0;
+}
+
+static void tboot_create_trampoline(void)
+{
+	u32 map_base, map_size;
+
+	/* Create identity map for tboot shutdown code. */
+	map_base = PFN_DOWN(tboot->tboot_base);
+	map_size = PFN_UP(tboot->tboot_size);
+	if (map_tboot_pages(map_base << PAGE_SHIFT, map_base, map_size))
+		panic("tboot: Error mapping tboot pages (mfns) @ 0x%x, 0x%x\n",
+		      map_base, map_size);
+}
+
+#ifdef CONFIG_ACPI_SLEEP
+
+static void add_mac_region(phys_addr_t start, unsigned long size)
+{
+	struct tboot_mac_region *mr;
+	phys_addr_t end = start + size;
+
+	if (start && size) {
+		mr = &tboot->mac_regions[tboot->num_mac_regions++];
+		mr->start = round_down(start, PAGE_SIZE);
+		mr->size  = round_up(end, PAGE_SIZE) - mr->start;
+	}
+}
+
+static int tboot_setup_sleep(void)
+{
+	tboot->num_mac_regions = 0;
+
+	/* S3 resume code */
+	add_mac_region(acpi_wakeup_address, WAKEUP_SIZE);
+
+#ifdef CONFIG_X86_TRAMPOLINE
+	/* AP trampoline code */
+	add_mac_region(virt_to_phys(trampoline_base), TRAMPOLINE_SIZE);
+#endif
+
+	/* kernel code + data + bss */
+	add_mac_region(virt_to_phys(_text), _end - _text);
+
+	tboot->acpi_sinfo.kernel_s3_resume_vector = acpi_wakeup_address;
+
+	return 0;
+}
+
+#else /* no CONFIG_ACPI_SLEEP */
+
+static int tboot_setup_sleep(void)
+{
+	/* S3 shutdown requested, but S3 not supported by the kernel... */
+	BUG();
+	return -1;
+}
+
+#endif
+
+void tboot_shutdown(u32 shutdown_type)
+{
+	void (*shutdown)(void);
+
+	if (!tboot_enabled())
+		return;
+
+	/*
+	 * if we're being called before the 1:1 mapping is set up then just
+	 * return and let the normal shutdown happen; this should only be
+	 * due to very early panic()
+	 */
+	if (!tboot_pg_dir)
+		return;
+
+	/* if this is S3 then set regions to MAC */
+	if (shutdown_type == TB_SHUTDOWN_S3)
+		if (tboot_setup_sleep())
+			return;
+
+	tboot->shutdown_type = shutdown_type;
+
+	switch_to_tboot_pt();
+
+	shutdown = (void(*)(void))(unsigned long)tboot->shutdown_entry;
+	shutdown();
+
+	/* should not reach here */
+	while (1)
+		halt();
+}
+
+static void tboot_copy_fadt(const struct acpi_table_fadt *fadt)
+{
+#define TB_COPY_GAS(tbg, g)			\
+	tbg.space_id     = g.space_id;		\
+	tbg.bit_width    = g.bit_width;		\
+	tbg.bit_offset   = g.bit_offset;	\
+	tbg.access_width = g.access_width;	\
+	tbg.address      = g.address;
+
+	TB_COPY_GAS(tboot->acpi_sinfo.pm1a_cnt_blk, fadt->xpm1a_control_block);
+	TB_COPY_GAS(tboot->acpi_sinfo.pm1b_cnt_blk, fadt->xpm1b_control_block);
+	TB_COPY_GAS(tboot->acpi_sinfo.pm1a_evt_blk, fadt->xpm1a_event_block);
+	TB_COPY_GAS(tboot->acpi_sinfo.pm1b_evt_blk, fadt->xpm1b_event_block);
+
+	/*
+	 * We need phys addr of waking vector, but can't use virt_to_phys() on
+	 * &acpi_gbl_FACS because it is ioremap'ed, so calc from FACS phys
+	 * addr.
+	 */
+	tboot->acpi_sinfo.wakeup_vector = fadt->facs +
+		offsetof(struct acpi_table_facs, firmware_waking_vector);
+}
+
+void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
+{
+	static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = {
+		/* S0,1,2: */ -1, -1, -1,
+		/* S3: */ TB_SHUTDOWN_S3,
+		/* S4: */ TB_SHUTDOWN_S4,
+		/* S5: */ TB_SHUTDOWN_S5 };
+
+	if (!tboot_enabled())
+		return;
+
+	tboot_copy_fadt(&acpi_gbl_FADT);
+	tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control;
+	tboot->acpi_sinfo.pm1b_cnt_val = pm1b_control;
+	/* we always use the 32b wakeup vector */
+	tboot->acpi_sinfo.vector_width = 32;
+
+	if (sleep_state >= ACPI_S_STATE_COUNT ||
+	    acpi_shutdown_map[sleep_state] == -1) {
+		pr_warning("unsupported sleep state 0x%x\n", sleep_state);
+		return;
+	}
+
+	tboot_shutdown(acpi_shutdown_map[sleep_state]);
+}
+
+static atomic_t ap_wfs_count;
+
+static int tboot_wait_for_aps(int num_aps)
+{
+	unsigned long timeout;
+
+	timeout = AP_WAIT_TIMEOUT*HZ;
+	while (atomic_read((atomic_t *)&tboot->num_in_wfs) != num_aps &&
+	       timeout) {
+		mdelay(1);
+		timeout--;
+	}
+
+	if (timeout)
+		pr_warning("tboot wait for APs timeout\n");
+
+	return !(atomic_read((atomic_t *)&tboot->num_in_wfs) == num_aps);
+}
+
+static int __cpuinit tboot_cpu_callback(struct notifier_block *nfb,
+			unsigned long action, void *hcpu)
+{
+	switch (action) {
+	case CPU_DYING:
+		atomic_inc(&ap_wfs_count);
+		if (num_online_cpus() == 1)
+			if (tboot_wait_for_aps(atomic_read(&ap_wfs_count)))
+				return NOTIFY_BAD;
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block tboot_cpu_notifier __cpuinitdata =
+{
+	.notifier_call = tboot_cpu_callback,
+};
+
+static __init int tboot_late_init(void)
+{
+	if (!tboot_enabled())
+		return 0;
+
+	tboot_create_trampoline();
+
+	atomic_set(&ap_wfs_count, 0);
+	register_hotcpu_notifier(&tboot_cpu_notifier);
+	return 0;
+}
+
+late_initcall(tboot_late_init);
+
+/*
+ * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE)
+ */
+
+#define TXT_PUB_CONFIG_REGS_BASE       0xfed30000
+#define TXT_PRIV_CONFIG_REGS_BASE      0xfed20000
+
+/* # pages for each config regs space - used by fixmap */
+#define NR_TXT_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE -                \
+				  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
+
+/* offsets from pub/priv config space */
+#define TXTCR_HEAP_BASE             0x0300
+#define TXTCR_HEAP_SIZE             0x0308
+
+#define SHA1_SIZE      20
+
+struct sha1_hash {
+	u8 hash[SHA1_SIZE];
+};
+
+struct sinit_mle_data {
+	u32               version;             /* currently 6 */
+	struct sha1_hash  bios_acm_id;
+	u32               edx_senter_flags;
+	u64               mseg_valid;
+	struct sha1_hash  sinit_hash;
+	struct sha1_hash  mle_hash;
+	struct sha1_hash  stm_hash;
+	struct sha1_hash  lcp_policy_hash;
+	u32               lcp_policy_control;
+	u32               rlp_wakeup_addr;
+	u32               reserved;
+	u32               num_mdrs;
+	u32               mdrs_off;
+	u32               num_vtd_dmars;
+	u32               vtd_dmars_off;
+} __packed;
+
+struct acpi_table_header *tboot_get_dmar_table(struct acpi_table_header *dmar_tbl)
+{
+	void *heap_base, *heap_ptr, *config;
+
+	if (!tboot_enabled())
+		return dmar_tbl;
+
+	/*
+	 * ACPI tables may not be DMA protected by tboot, so use DMAR copy
+	 * SINIT saved in SinitMleData in TXT heap (which is DMA protected)
+	 */
+
+	/* map config space in order to get heap addr */
+	config = ioremap(TXT_PUB_CONFIG_REGS_BASE, NR_TXT_CONFIG_PAGES *
+			 PAGE_SIZE);
+	if (!config)
+		return NULL;
+
+	/* now map TXT heap */
+	heap_base = ioremap(*(u64 *)(config + TXTCR_HEAP_BASE),
+			    *(u64 *)(config + TXTCR_HEAP_SIZE));
+	iounmap(config);
+	if (!heap_base)
+		return NULL;
+
+	/* walk heap to SinitMleData */
+	/* skip BiosData */
+	heap_ptr = heap_base + *(u64 *)heap_base;
+	/* skip OsMleData */
+	heap_ptr += *(u64 *)heap_ptr;
+	/* skip OsSinitData */
+	heap_ptr += *(u64 *)heap_ptr;
+	/* now points to SinitMleDataSize; set to SinitMleData */
+	heap_ptr += sizeof(u64);
+	/* get addr of DMAR table */
+	dmar_tbl = (struct acpi_table_header *)(heap_ptr +
+		   ((struct sinit_mle_data *)heap_ptr)->vtd_dmars_off -
+		   sizeof(u64));
+
+	/* don't unmap heap because dmar.c needs access to this */
+
+	return dmar_tbl;
+}
+
+int tboot_force_iommu(void)
+{
+	if (!tboot_enabled())
+		return 0;
+
+	if (no_iommu || swiotlb || dmar_disabled)
+		pr_warning("Forcing Intel-IOMMU to enabled\n");
+
+	dmar_disabled = 0;
+#ifdef CONFIG_SWIOTLB
+	swiotlb = 0;
+#endif
+	no_iommu = 0;
+
+	return 1;
+}
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
new file mode 100644
index 0000000..e293ac5
--- /dev/null
+++ b/arch/x86/kernel/time.c
@@ -0,0 +1,121 @@
+/*
+ *  Copyright (c) 1991,1992,1995  Linus Torvalds
+ *  Copyright (c) 1994  Alan Modra
+ *  Copyright (c) 1995  Markus Kuhn
+ *  Copyright (c) 1996  Ingo Molnar
+ *  Copyright (c) 1998  Andrea Arcangeli
+ *  Copyright (c) 2002,2006  Vojtech Pavlik
+ *  Copyright (c) 2003  Andi Kleen
+ *
+ */
+
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/mca.h>
+
+#include <asm/vsyscall.h>
+#include <asm/x86_init.h>
+#include <asm/i8259.h>
+#include <asm/i8253.h>
+#include <asm/timer.h>
+#include <asm/hpet.h>
+#include <asm/time.h>
+
+#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
+int timer_ack;
+#endif
+
+#ifdef CONFIG_X86_64
+volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
+#endif
+
+unsigned long profile_pc(struct pt_regs *regs)
+{
+	unsigned long pc = instruction_pointer(regs);
+
+	if (!user_mode_vm(regs) && in_lock_functions(pc)) {
+#ifdef CONFIG_FRAME_POINTER
+		return *(unsigned long *)(regs->bp + sizeof(long));
+#else
+		unsigned long *sp = (unsigned long *)regs->sp;
+		/*
+		 * Return address is either directly at stack pointer
+		 * or above a saved flags. Eflags has bits 22-31 zero,
+		 * kernel addresses don't.
+		 */
+		if (sp[0] >> 22)
+			return sp[0];
+		if (sp[1] >> 22)
+			return sp[1];
+#endif
+	}
+	return pc;
+}
+EXPORT_SYMBOL(profile_pc);
+
+/*
+ * Default timer interrupt handler for PIT/HPET
+ */
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+	/* Keep nmi watchdog up to date */
+	inc_irq_stat(irq0_irqs);
+
+	/* Optimized out for !IO_APIC and x86_64 */
+	if (timer_ack) {
+		/*
+		 * Subtle, when I/O APICs are used we have to ack timer IRQ
+		 * manually to deassert NMI lines for the watchdog if run
+		 * on an 82489DX-based system.
+		 */
+		spin_lock(&i8259A_lock);
+		outb(0x0c, PIC_MASTER_OCW3);
+		/* Ack the IRQ; AEOI will end it automatically. */
+		inb(PIC_MASTER_POLL);
+		spin_unlock(&i8259A_lock);
+	}
+
+	global_clock_event->event_handler(global_clock_event);
+
+	/* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */
+	if (MCA_bus)
+		outb_p(inb_p(0x61)| 0x80, 0x61);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction irq0  = {
+	.handler = timer_interrupt,
+	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
+	.name = "timer"
+};
+
+void __init setup_default_timer_irq(void)
+{
+	irq0.mask = cpumask_of_cpu(0);
+	setup_irq(0, &irq0);
+}
+
+/* Default timer init function */
+void __init hpet_time_init(void)
+{
+	if (!hpet_enable())
+		setup_pit_timer();
+	setup_default_timer_irq();
+}
+
+static __init void x86_late_time_init(void)
+{
+	x86_init.timers.timer_init();
+	tsc_init();
+}
+
+/*
+ * Initialize TSC and delay the periodic timer init to
+ * late x86_late_time_init() so ioremap works.
+ */
+void __init time_init(void)
+{
+	late_time_init = x86_late_time_init;
+}
diff --git a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
deleted file mode 100644
index 5c5d87f..0000000
--- a/arch/x86/kernel/time_32.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
- *
- * This file contains the PC-specific time handling details:
- * reading the RTC at bootup, etc..
- * 1994-07-02    Alan Modra
- *	fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- * 1995-03-26    Markus Kuhn
- *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
- *      precision CMOS clock update
- * 1996-05-03    Ingo Molnar
- *      fixed time warps in do_[slow|fast]_gettimeoffset()
- * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
- *		"A Kernel Model for Precision Timekeeping" by Dave Mills
- * 1998-09-05    (Various)
- *	More robust do_fast_gettimeoffset() algorithm implemented
- *	(works with APM, Cyrix 6x86MX and Centaur C6),
- *	monotonic gettimeofday() with fast_get_timeoffset(),
- *	drift-proof precision TSC calibration on boot
- *	(C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
- *	Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
- *	ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
- * 1998-12-16    Andrea Arcangeli
- *	Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
- *	because was not accounting lost_ticks.
- * 1998-12-24 Copyright (C) 1998  Andrea Arcangeli
- *	Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
- *	serialize accesses to xtime/lost_ticks).
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/mca.h>
-
-#include <asm/setup.h>
-#include <asm/hpet.h>
-#include <asm/time.h>
-#include <asm/timer.h>
-
-#include <asm/do_timer.h>
-
-int timer_ack;
-
-unsigned long profile_pc(struct pt_regs *regs)
-{
-	unsigned long pc = instruction_pointer(regs);
-
-#ifdef CONFIG_SMP
-	if (!user_mode_vm(regs) && in_lock_functions(pc)) {
-#ifdef CONFIG_FRAME_POINTER
-		return *(unsigned long *)(regs->bp + sizeof(long));
-#else
-		unsigned long *sp = (unsigned long *)&regs->sp;
-
-		/* Return address is either directly at stack pointer
-		   or above a saved flags. Eflags has bits 22-31 zero,
-		   kernel addresses don't. */
-		if (sp[0] >> 22)
-			return sp[0];
-		if (sp[1] >> 22)
-			return sp[1];
-#endif
-	}
-#endif
-	return pc;
-}
-EXPORT_SYMBOL(profile_pc);
-
-/*
- * This is the same as the above, except we _also_ save the current
- * Time Stamp Counter value at the time of the timer interrupt, so that
- * we later on can estimate the time of day more exactly.
- */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-	/* Keep nmi watchdog up to date */
-	inc_irq_stat(irq0_irqs);
-
-#ifdef CONFIG_X86_IO_APIC
-	if (timer_ack) {
-		/*
-		 * Subtle, when I/O APICs are used we have to ack timer IRQ
-		 * manually to deassert NMI lines for the watchdog if run
-		 * on an 82489DX-based system.
-		 */
-		spin_lock(&i8259A_lock);
-		outb(0x0c, PIC_MASTER_OCW3);
-		/* Ack the IRQ; AEOI will end it automatically. */
-		inb(PIC_MASTER_POLL);
-		spin_unlock(&i8259A_lock);
-	}
-#endif
-
-	do_timer_interrupt_hook();
-
-#ifdef CONFIG_MCA
-	if (MCA_bus) {
-		/* The PS/2 uses level-triggered interrupts.  You can't
-		turn them off, nor would you want to (any attempt to
-		enable edge-triggered interrupts usually gets intercepted by a
-		special hardware circuit).  Hence we have to acknowledge
-		the timer interrupt.  Through some incredibly stupid
-		design idea, the reset for IRQ 0 is done by setting the
-		high bit of the PPI port B (0x61).  Note that some PS/2s,
-		notably the 55SX, work fine if this is removed.  */
-
-		u8 irq_v = inb_p(0x61);		/* read the current state */
-		outb_p(irq_v | 0x80, 0x61);	/* reset the IRQ */
-	}
-#endif
-
-	return IRQ_HANDLED;
-}
-
-/* Duplicate of time_init() below, with hpet_enable part added */
-void __init hpet_time_init(void)
-{
-	if (!hpet_enable())
-		setup_pit_timer();
-	x86_quirk_time_init();
-}
-
-/*
- * This is called directly from init code; we must delay timer setup in the
- * HPET case as we can't make the decision to turn on HPET this early in the
- * boot process.
- *
- * The chosen time_init function will usually be hpet_time_init, above, but
- * in the case of virtual hardware, an alternative function may be substituted.
- */
-void __init time_init(void)
-{
-	x86_quirk_pre_time_init();
-	tsc_init();
-	late_time_init = choose_time_init();
-}
diff --git a/arch/x86/kernel/time_64.c b/arch/x86/kernel/time_64.c
deleted file mode 100644
index 5ba343e..0000000
--- a/arch/x86/kernel/time_64.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *  "High Precision Event Timer" based timekeeping.
- *
- *  Copyright (c) 1991,1992,1995  Linus Torvalds
- *  Copyright (c) 1994  Alan Modra
- *  Copyright (c) 1995  Markus Kuhn
- *  Copyright (c) 1996  Ingo Molnar
- *  Copyright (c) 1998  Andrea Arcangeli
- *  Copyright (c) 2002,2006  Vojtech Pavlik
- *  Copyright (c) 2003  Andi Kleen
- *  RTC support code taken from arch/i386/kernel/timers/time_hpet.c
- */
-
-#include <linux/clockchips.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/mca.h>
-#include <linux/nmi.h>
-
-#include <asm/i8253.h>
-#include <asm/hpet.h>
-#include <asm/vgtod.h>
-#include <asm/time.h>
-#include <asm/timer.h>
-
-volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
-
-unsigned long profile_pc(struct pt_regs *regs)
-{
-	unsigned long pc = instruction_pointer(regs);
-
-	/* Assume the lock function has either no stack frame or a copy
-	   of flags from PUSHF
-	   Eflags always has bits 22 and up cleared unlike kernel addresses. */
-	if (!user_mode_vm(regs) && in_lock_functions(pc)) {
-#ifdef CONFIG_FRAME_POINTER
-		return *(unsigned long *)(regs->bp + sizeof(long));
-#else
-		unsigned long *sp = (unsigned long *)regs->sp;
-		if (sp[0] >> 22)
-			return sp[0];
-		if (sp[1] >> 22)
-			return sp[1];
-#endif
-	}
-	return pc;
-}
-EXPORT_SYMBOL(profile_pc);
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-	inc_irq_stat(irq0_irqs);
-
-	global_clock_event->event_handler(global_clock_event);
-
-#ifdef CONFIG_MCA
-	if (MCA_bus) {
-		u8 irq_v = inb_p(0x61);       /* read the current state */
-		outb_p(irq_v|0x80, 0x61);     /* reset the IRQ */
-	}
-#endif
-
-	return IRQ_HANDLED;
-}
-
-/* calibrate_cpu is used on systems with fixed rate TSCs to determine
- * processor frequency */
-#define TICK_COUNT 100000000
-unsigned long __init calibrate_cpu(void)
-{
-	int tsc_start, tsc_now;
-	int i, no_ctr_free;
-	unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
-	unsigned long flags;
-
-	for (i = 0; i < 4; i++)
-		if (avail_to_resrv_perfctr_nmi_bit(i))
-			break;
-	no_ctr_free = (i == 4);
-	if (no_ctr_free) {
-		WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... "
-		     "cpu_khz value may be incorrect.\n");
-		i = 3;
-		rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
-		wrmsrl(MSR_K7_EVNTSEL3, 0);
-		rdmsrl(MSR_K7_PERFCTR3, pmc3);
-	} else {
-		reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
-		reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
-	}
-	local_irq_save(flags);
-	/* start measuring cycles, incrementing from 0 */
-	wrmsrl(MSR_K7_PERFCTR0 + i, 0);
-	wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
-	rdtscl(tsc_start);
-	do {
-		rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
-		tsc_now = get_cycles();
-	} while ((tsc_now - tsc_start) < TICK_COUNT);
-
-	local_irq_restore(flags);
-	if (no_ctr_free) {
-		wrmsrl(MSR_K7_EVNTSEL3, 0);
-		wrmsrl(MSR_K7_PERFCTR3, pmc3);
-		wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
-	} else {
-		release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
-		release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
-	}
-
-	return pmc_now * tsc_khz / (tsc_now - tsc_start);
-}
-
-static struct irqaction irq0 = {
-	.handler	= timer_interrupt,
-	.flags		= IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER,
-	.name		= "timer"
-};
-
-void __init hpet_time_init(void)
-{
-	if (!hpet_enable())
-		setup_pit_timer();
-
-	setup_irq(0, &irq0);
-}
-
-void __init time_init(void)
-{
-	tsc_init();
-
-	late_time_init = choose_time_init();
-}
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 77b9689..503c1f2 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -640,13 +640,13 @@ static int __init uv_ptc_init(void)
 	if (!is_uv_system())
 		return 0;
 
-	proc_uv_ptc = create_proc_entry(UV_PTC_BASENAME, 0444, NULL);
+	proc_uv_ptc = proc_create(UV_PTC_BASENAME, 0444, NULL,
+				  &proc_uv_ptc_operations);
 	if (!proc_uv_ptc) {
 		printk(KERN_ERR "unable to create %s proc entry\n",
 		       UV_PTC_BASENAME);
 		return -EINVAL;
 	}
-	proc_uv_ptc->proc_fops = &proc_uv_ptc_operations;
 	return 0;
 }
 
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c
index 808031a..699f7ee 100644
--- a/arch/x86/kernel/trampoline.c
+++ b/arch/x86/kernel/trampoline.c
@@ -4,7 +4,7 @@
 #include <asm/e820.h>
 
 /* ready for x86_64 and x86 */
-unsigned char *trampoline_base = __va(TRAMPOLINE_BASE);
+unsigned char *__cpuinitdata trampoline_base = __va(TRAMPOLINE_BASE);
 
 void __init reserve_trampoline_memory(void)
 {
@@ -26,7 +26,7 @@ void __init reserve_trampoline_memory(void)
  * bootstrap into the page concerned. The caller
  * has made sure it's suitably aligned.
  */
-unsigned long setup_trampoline(void)
+unsigned long __cpuinit setup_trampoline(void)
 {
 	memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
 	return virt_to_phys(trampoline_base);
diff --git a/arch/x86/kernel/trampoline_32.S b/arch/x86/kernel/trampoline_32.S
index 66d874e..8508237 100644
--- a/arch/x86/kernel/trampoline_32.S
+++ b/arch/x86/kernel/trampoline_32.S
@@ -28,16 +28,12 @@
  */
 
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/segment.h>
 #include <asm/page_types.h>
 
 /* We can free up trampoline after bootup if cpu hotplug is not supported. */
-#ifndef CONFIG_HOTPLUG_CPU
-.section ".cpuinit.data","aw",@progbits
-#else
-.section .rodata,"a",@progbits
-#endif
-
+__CPUINITRODATA
 .code16
 
 ENTRY(trampoline_data)
diff --git a/arch/x86/kernel/trampoline_64.S b/arch/x86/kernel/trampoline_64.S
index cddfb8d..596d54c 100644
--- a/arch/x86/kernel/trampoline_64.S
+++ b/arch/x86/kernel/trampoline_64.S
@@ -25,14 +25,15 @@
  */
 
 #include <linux/linkage.h>
+#include <linux/init.h>
 #include <asm/pgtable_types.h>
 #include <asm/page_types.h>
 #include <asm/msr.h>
 #include <asm/segment.h>
 #include <asm/processor-flags.h>
 
-.section .rodata, "a", @progbits
-
+/* We can free up the trampoline after bootup if cpu hotplug is not supported. */
+__CPUINITRODATA
 .code16
 
 ENTRY(trampoline_data)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 5204332..9346e10 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -59,12 +59,12 @@
 #include <asm/mach_traps.h>
 
 #ifdef CONFIG_X86_64
+#include <asm/x86_init.h>
 #include <asm/pgalloc.h>
 #include <asm/proto.h>
 #else
 #include <asm/processor-flags.h>
 #include <asm/setup.h>
-#include <asm/traps.h>
 
 asmlinkage int system_call(void);
 
@@ -76,7 +76,7 @@ char ignore_fpu_irq;
  * F0 0F bug workaround.. We have a special link segment
  * for this.
  */
-gate_desc idt_table[256]
+gate_desc idt_table[NR_VECTORS]
 	__attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
 #endif
 
@@ -786,33 +786,34 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
 #endif
 }
 
-#ifdef CONFIG_X86_32
-unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
+asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
 {
-	struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
-	unsigned long base = (kesp - uesp) & -THREAD_SIZE;
-	unsigned long new_kesp = kesp - base;
-	unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
-	__u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
-
-	/* Set up base for espfix segment */
-	desc &= 0x00f0ff0000000000ULL;
-	desc |=	((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
-		((((__u64)base) << 32) & 0xff00000000000000ULL) |
-		((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
-		(lim_pages & 0xffff);
-	*(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
-
-	return new_kesp;
 }
-#endif
 
-asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
+asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
 {
 }
 
-asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
+/*
+ * __math_state_restore assumes that cr0.TS is already clear and the
+ * fpu state is all ready for use.  Used during context switch.
+ */
+void __math_state_restore(void)
 {
+	struct thread_info *thread = current_thread_info();
+	struct task_struct *tsk = thread->task;
+
+	/*
+	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
+	 */
+	if (unlikely(restore_fpu_checking(tsk))) {
+		stts();
+		force_sig(SIGSEGV, tsk);
+		return;
+	}
+
+	thread->status |= TS_USEDFPU;	/* So we fnsave on switch_to() */
+	tsk->fpu_counter++;
 }
 
 /*
@@ -846,17 +847,8 @@ asmlinkage void math_state_restore(void)
 	}
 
 	clts();				/* Allow maths ops (or we recurse) */
-	/*
-	 * Paranoid restore. send a SIGSEGV if we fail to restore the state.
-	 */
-	if (unlikely(restore_fpu_checking(tsk))) {
-		stts();
-		force_sig(SIGSEGV, tsk);
-		return;
-	}
 
-	thread->status |= TS_USEDFPU;	/* So we fnsave on switch_to() */
-	tsk->fpu_counter++;
+	__math_state_restore();
 }
 EXPORT_SYMBOL_GPL(math_state_restore);
 
@@ -980,7 +972,5 @@ void __init trap_init(void)
 	 */
 	cpu_init();
 
-#ifdef CONFIG_X86_32
-	x86_quirk_trap_init();
-#endif
+	x86_init.irqs.trap_init();
 }
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 71f4368..cd982f4 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -17,6 +17,8 @@
 #include <asm/time.h>
 #include <asm/delay.h>
 #include <asm/hypervisor.h>
+#include <asm/nmi.h>
+#include <asm/x86_init.h>
 
 unsigned int __read_mostly cpu_khz;	/* TSC clocks / usec, not used here */
 EXPORT_SYMBOL(cpu_khz);
@@ -400,15 +402,9 @@ unsigned long native_calibrate_tsc(void)
 {
 	u64 tsc1, tsc2, delta, ref1, ref2;
 	unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
-	unsigned long flags, latch, ms, fast_calibrate, hv_tsc_khz;
+	unsigned long flags, latch, ms, fast_calibrate;
 	int hpet = is_hpet_enabled(), i, loopmin;
 
-	hv_tsc_khz = get_hypervisor_tsc_freq();
-	if (hv_tsc_khz) {
-		printk(KERN_INFO "TSC: Frequency read from the hypervisor\n");
-		return hv_tsc_khz;
-	}
-
 	local_irq_save(flags);
 	fast_calibrate = quick_pit_calibrate();
 	local_irq_restore(flags);
@@ -566,7 +562,7 @@ int recalibrate_cpu_khz(void)
 	unsigned long cpu_khz_old = cpu_khz;
 
 	if (cpu_has_tsc) {
-		tsc_khz = calibrate_tsc();
+		tsc_khz = x86_platform.calibrate_tsc();
 		cpu_khz = tsc_khz;
 		cpu_data(0).loops_per_jiffy =
 			cpufreq_scale(cpu_data(0).loops_per_jiffy,
@@ -670,7 +666,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 	if ((val == CPUFREQ_PRECHANGE  && freq->old < freq->new) ||
 			(val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
 			(val == CPUFREQ_RESUMECHANGE)) {
-		*lpj = 	cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
+		*lpj = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new);
 
 		tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new);
 		if (!(freq->flags & CPUFREQ_CONST_LOOPS))
@@ -744,10 +740,16 @@ static cycle_t __vsyscall_fn vread_tsc(void)
 }
 #endif
 
+static void resume_tsc(void)
+{
+	clocksource_tsc.cycle_last = 0;
+}
+
 static struct clocksource clocksource_tsc = {
 	.name                   = "tsc",
 	.rating                 = 300,
 	.read                   = read_tsc,
+	.resume			= resume_tsc,
 	.mask                   = CLOCKSOURCE_MASK(64),
 	.shift                  = 22,
 	.flags                  = CLOCK_SOURCE_IS_CONTINUOUS |
@@ -761,12 +763,14 @@ void mark_tsc_unstable(char *reason)
 {
 	if (!tsc_unstable) {
 		tsc_unstable = 1;
-		printk("Marking TSC unstable due to %s\n", reason);
+		printk(KERN_INFO "Marking TSC unstable due to %s\n", reason);
 		/* Change only the rating, when not registered */
 		if (clocksource_tsc.mult)
-			clocksource_change_rating(&clocksource_tsc, 0);
-		else
+			clocksource_mark_unstable(&clocksource_tsc);
+		else {
+			clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE;
 			clocksource_tsc.rating = 0;
+		}
 	}
 }
 
@@ -852,15 +856,71 @@ static void __init init_tsc_clocksource(void)
 	clocksource_register(&clocksource_tsc);
 }
 
+#ifdef CONFIG_X86_64
+/*
+ * calibrate_cpu is used on systems with fixed rate TSCs to determine
+ * processor frequency
+ */
+#define TICK_COUNT 100000000
+static unsigned long __init calibrate_cpu(void)
+{
+	int tsc_start, tsc_now;
+	int i, no_ctr_free;
+	unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
+	unsigned long flags;
+
+	for (i = 0; i < 4; i++)
+		if (avail_to_resrv_perfctr_nmi_bit(i))
+			break;
+	no_ctr_free = (i == 4);
+	if (no_ctr_free) {
+		WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... "
+		     "cpu_khz value may be incorrect.\n");
+		i = 3;
+		rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
+		wrmsrl(MSR_K7_EVNTSEL3, 0);
+		rdmsrl(MSR_K7_PERFCTR3, pmc3);
+	} else {
+		reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+		reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+	}
+	local_irq_save(flags);
+	/* start measuring cycles, incrementing from 0 */
+	wrmsrl(MSR_K7_PERFCTR0 + i, 0);
+	wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
+	rdtscl(tsc_start);
+	do {
+		rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
+		tsc_now = get_cycles();
+	} while ((tsc_now - tsc_start) < TICK_COUNT);
+
+	local_irq_restore(flags);
+	if (no_ctr_free) {
+		wrmsrl(MSR_K7_EVNTSEL3, 0);
+		wrmsrl(MSR_K7_PERFCTR3, pmc3);
+		wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
+	} else {
+		release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
+		release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
+	}
+
+	return pmc_now * tsc_khz / (tsc_now - tsc_start);
+}
+#else
+static inline unsigned long calibrate_cpu(void) { return cpu_khz; }
+#endif
+
 void __init tsc_init(void)
 {
 	u64 lpj;
 	int cpu;
 
+	x86_init.timers.tsc_pre_init();
+
 	if (!cpu_has_tsc)
 		return;
 
-	tsc_khz = calibrate_tsc();
+	tsc_khz = x86_platform.calibrate_tsc();
 	cpu_khz = tsc_khz;
 
 	if (!tsc_khz) {
@@ -868,11 +928,9 @@ void __init tsc_init(void)
 		return;
 	}
 
-#ifdef CONFIG_X86_64
 	if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) &&
 			(boot_cpu_data.x86_vendor == X86_VENDOR_AMD))
 		cpu_khz = calibrate_cpu();
-#endif
 
 	printk("Detected %lu.%03lu MHz processor.\n",
 			(unsigned long)cpu_khz / 1000,
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index 31ffc24..f068553 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -30,6 +30,7 @@
 #include <asm/setup.h>
 #include <asm/apic.h>
 #include <asm/e820.h>
+#include <asm/time.h>
 #include <asm/io.h>
 
 #include <linux/kernel_stat.h>
@@ -53,7 +54,7 @@ int is_visws_box(void)
 	return visws_board_type >= 0;
 }
 
-static int __init visws_time_init(void)
+static void __init visws_time_init(void)
 {
 	printk(KERN_INFO "Starting Cobalt Timer system clock\n");
 
@@ -66,21 +67,13 @@ static int __init visws_time_init(void)
 	/* Enable (unmask) the timer interrupt */
 	co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
 
-	/*
-	 * Zero return means the generic timer setup code will set up
-	 * the standard vector:
-	 */
-	return 0;
+	setup_default_timer_irq();
 }
 
-static int __init visws_pre_intr_init(void)
+/* Replaces the default init_ISA_irqs in the generic setup */
+static void __init visws_pre_intr_init(void)
 {
 	init_VISWS_APIC_irqs();
-
-	/*
-	 * We dont want ISA irqs to be set up by the generic code:
-	 */
-	return 1;
 }
 
 /* Quirk for machine specific memory setup. */
@@ -156,12 +149,8 @@ static void visws_machine_power_off(void)
 	outl(PIIX_SPECIAL_STOP, 0xCFC);
 }
 
-static int __init visws_get_smp_config(unsigned int early)
+static void __init visws_get_smp_config(unsigned int early)
 {
-	/*
-	 * Prevent MP-table parsing by the generic code:
-	 */
-	return 1;
 }
 
 /*
@@ -208,7 +197,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
 	apic_version[m->apicid] = ver;
 }
 
-static int __init visws_find_smp_config(unsigned int reserve)
+static void __init visws_find_smp_config(unsigned int reserve)
 {
 	struct mpc_cpu *mp = phys_to_virt(CO_CPU_TAB_PHYS);
 	unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
@@ -230,21 +219,9 @@ static int __init visws_find_smp_config(unsigned int reserve)
 		MP_processor_info(mp++);
 
 	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-
-	return 1;
 }
 
-static int visws_trap_init(void);
-
-static struct x86_quirks visws_x86_quirks __initdata = {
-	.arch_time_init		= visws_time_init,
-	.arch_pre_intr_init	= visws_pre_intr_init,
-	.arch_memory_setup	= visws_memory_setup,
-	.arch_intr_init		= NULL,
-	.arch_trap_init		= visws_trap_init,
-	.mach_get_smp_config	= visws_get_smp_config,
-	.mach_find_smp_config	= visws_find_smp_config,
-};
+static void visws_trap_init(void);
 
 void __init visws_early_detect(void)
 {
@@ -257,11 +234,14 @@ void __init visws_early_detect(void)
 		return;
 
 	/*
-	 * Install special quirks for timer, interrupt and memory setup:
-	 * Fall back to generic behavior for traps:
-	 * Override generic MP-table parsing:
+	 * Override the default platform setup functions
 	 */
-	x86_quirks = &visws_x86_quirks;
+	x86_init.resources.memory_setup = visws_memory_setup;
+	x86_init.mpparse.get_smp_config = visws_get_smp_config;
+	x86_init.mpparse.find_smp_config = visws_find_smp_config;
+	x86_init.irqs.pre_vector_init = visws_pre_intr_init;
+	x86_init.irqs.trap_init = visws_trap_init;
+	x86_init.timers.timer_init = visws_time_init;
 
 	/*
 	 * Install reboot quirks:
@@ -400,12 +380,10 @@ static __init void cobalt_init(void)
 		co_apic_read(CO_APIC_ID));
 }
 
-static int __init visws_trap_init(void)
+static void __init visws_trap_init(void)
 {
 	lithium_init();
 	cobalt_init();
-
-	return 1;
 }
 
 /*
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 95a7289..31e6f6c 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -817,15 +817,15 @@ static inline int __init activate_vmi(void)
 		vmi_timer_ops.set_alarm = vmi_get_function(VMI_CALL_SetAlarm);
 		vmi_timer_ops.cancel_alarm =
 			 vmi_get_function(VMI_CALL_CancelAlarm);
-		pv_time_ops.time_init = vmi_time_init;
-		pv_time_ops.get_wallclock = vmi_get_wallclock;
-		pv_time_ops.set_wallclock = vmi_set_wallclock;
+		x86_init.timers.timer_init = vmi_time_init;
 #ifdef CONFIG_X86_LOCAL_APIC
-		pv_apic_ops.setup_boot_clock = vmi_time_bsp_init;
-		pv_apic_ops.setup_secondary_clock = vmi_time_ap_init;
+		x86_init.timers.setup_percpu_clockev = vmi_time_bsp_init;
+		x86_cpuinit.setup_percpu_clockev = vmi_time_ap_init;
 #endif
 		pv_time_ops.sched_clock = vmi_sched_clock;
-		pv_time_ops.get_tsc_khz = vmi_tsc_khz;
+		x86_platform.calibrate_tsc = vmi_tsc_khz;
+		x86_platform.get_wallclock = vmi_get_wallclock;
+		x86_platform.set_wallclock = vmi_set_wallclock;
 
 		/* We have true wallclock functions; disable CMOS clock sync */
 		no_sync_cmos_clock = 1;
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index 2b3eb82..611b9e2 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -68,7 +68,7 @@ unsigned long long vmi_sched_clock(void)
 	return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE));
 }
 
-/* paravirt_ops.get_tsc_khz = vmi_tsc_khz */
+/* x86_platform.calibrate_tsc = vmi_tsc_khz */
 unsigned long vmi_tsc_khz(void)
 {
 	unsigned long long khz;
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 9fc1782..a46accc 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -45,9 +45,9 @@ PHDRS {
 	text PT_LOAD FLAGS(5);          /* R_E */
 	data PT_LOAD FLAGS(7);          /* RWE */
 #ifdef CONFIG_X86_64
-	user PT_LOAD FLAGS(7);          /* RWE */
+	user PT_LOAD FLAGS(5);          /* R_E */
 #ifdef CONFIG_SMP
-	percpu PT_LOAD FLAGS(7);        /* RWE */
+	percpu PT_LOAD FLAGS(6);        /* RW_ */
 #endif
 	init PT_LOAD FLAGS(7);          /* RWE */
 #endif
@@ -348,15 +348,12 @@ SECTIONS
 		_end = .;
 	}
 
-	/* Sections to be discarded */
-	/DISCARD/ : {
-		*(.exitcall.exit)
-		*(.eh_frame)
-		*(.discard)
-	}
-
         STABS_DEBUG
         DWARF_DEBUG
+
+	/* Sections to be discarded */
+	DISCARDS
+	/DISCARD/ : { *(.eh_frame) }
 }
 
 
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 25ee06a..cf53a78 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -87,6 +87,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock)
 	vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec;
 	vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec;
 	vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic;
+	vsyscall_gtod_data.wall_time_coarse = __current_kernel_time();
 	write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags);
 }
 
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
new file mode 100644
index 0000000..4449a4a
--- /dev/null
+++ b/arch/x86/kernel/x86_init.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2009 Thomas Gleixner <tglx@linutronix.de>
+ *
+ *  For licencing details see kernel-base/COPYING
+ */
+#include <linux/init.h>
+
+#include <asm/bios_ebda.h>
+#include <asm/paravirt.h>
+#include <asm/mpspec.h>
+#include <asm/setup.h>
+#include <asm/apic.h>
+#include <asm/e820.h>
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/tsc.h>
+
+void __cpuinit x86_init_noop(void) { }
+void __init x86_init_uint_noop(unsigned int unused) { }
+void __init x86_init_pgd_noop(pgd_t *unused) { }
+
+/*
+ * The platform setup functions are preset with the default functions
+ * for standard PC hardware.
+ */
+struct x86_init_ops x86_init __initdata = {
+
+	.resources = {
+		.probe_roms		= x86_init_noop,
+		.reserve_resources	= reserve_standard_io_resources,
+		.memory_setup		= default_machine_specific_memory_setup,
+	},
+
+	.mpparse = {
+		.mpc_record		= x86_init_uint_noop,
+		.setup_ioapic_ids	= x86_init_noop,
+		.mpc_apic_id		= default_mpc_apic_id,
+		.smp_read_mpc_oem	= default_smp_read_mpc_oem,
+		.mpc_oem_bus_info	= default_mpc_oem_bus_info,
+		.find_smp_config	= default_find_smp_config,
+		.get_smp_config		= default_get_smp_config,
+	},
+
+	.irqs = {
+		.pre_vector_init	= init_ISA_irqs,
+		.intr_init		= native_init_IRQ,
+		.trap_init		= x86_init_noop,
+	},
+
+	.oem = {
+		.arch_setup		= x86_init_noop,
+		.banner			= default_banner,
+	},
+
+	.paging = {
+		.pagetable_setup_start	= native_pagetable_setup_start,
+		.pagetable_setup_done	= native_pagetable_setup_done,
+	},
+
+	.timers = {
+		.setup_percpu_clockev	= setup_boot_APIC_clock,
+		.tsc_pre_init		= x86_init_noop,
+		.timer_init		= hpet_time_init,
+	},
+};
+
+struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
+	.setup_percpu_clockev		= setup_secondary_APIC_clock,
+};
+
+struct x86_platform_ops x86_platform = {
+	.calibrate_tsc			= native_calibrate_tsc,
+	.get_wallclock			= mach_get_cmos_time,
+	.set_wallclock			= mach_set_rtc_mmss,
+};
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index 8600a09..b84e571 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -1,12 +1,8 @@
 #
 # KVM configuration
 #
-config HAVE_KVM
-       bool
 
-config HAVE_KVM_IRQCHIP
-       bool
-       default y
+source "virt/kvm/Kconfig"
 
 menuconfig VIRTUALIZATION
 	bool "Virtualization"
@@ -29,6 +25,9 @@ config KVM
 	select PREEMPT_NOTIFIERS
 	select MMU_NOTIFIER
 	select ANON_INODES
+	select HAVE_KVM_IRQCHIP
+	select HAVE_KVM_EVENTFD
+	select KVM_APIC_ARCHITECTURE
 	---help---
 	  Support hosting fully virtualized guest machines using hardware
 	  virtualization extensions.  You will need a fairly recent
@@ -63,18 +62,6 @@ config KVM_AMD
 	  To compile this as a module, choose M here: the module
 	  will be called kvm-amd.
 
-config KVM_TRACE
-	bool "KVM trace support"
-	depends on KVM && SYSFS
-	select MARKERS
-	select RELAY
-	select DEBUG_FS
-	default n
-	---help---
-	  This option allows reading a trace of kvm-related events through
-	  relayfs.  Note the ABI is not considered stable and will be
-	  modified in future updates.
-
 # OK, it's a little counter-intuitive to do this, but it puts it neatly under
 # the virtualization menu.
 source drivers/lguest/Kconfig
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index b43c4ef..0e7fe78 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -1,22 +1,19 @@
-#
-# Makefile for Kernel-based Virtual Machine module
-#
-
-common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
-                coalesced_mmio.o irq_comm.o)
-ifeq ($(CONFIG_KVM_TRACE),y)
-common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o)
-endif
-ifeq ($(CONFIG_IOMMU_API),y)
-common-objs += $(addprefix ../../../virt/kvm/, iommu.o)
-endif
 
 EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm
 
-kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o \
-	i8254.o timer.o
-obj-$(CONFIG_KVM) += kvm.o
-kvm-intel-objs = vmx.o
-obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
-kvm-amd-objs = svm.o
-obj-$(CONFIG_KVM_AMD) += kvm-amd.o
+CFLAGS_x86.o := -I.
+CFLAGS_svm.o := -I.
+CFLAGS_vmx.o := -I.
+
+kvm-y			+= $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
+				coalesced_mmio.o irq_comm.o eventfd.o)
+kvm-$(CONFIG_IOMMU_API)	+= $(addprefix ../../../virt/kvm/, iommu.o)
+
+kvm-y			+= x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
+			   i8254.o timer.o
+kvm-intel-y		+= vmx.o
+kvm-amd-y		+= svm.o
+
+obj-$(CONFIG_KVM)	+= kvm.o
+obj-$(CONFIG_KVM_INTEL)	+= kvm-intel.o
+obj-$(CONFIG_KVM_AMD)	+= kvm-amd.o
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
new file mode 100644
index 0000000..1be5cd6
--- /dev/null
+++ b/arch/x86/kvm/emulate.c
@@ -0,0 +1,2392 @@
+/******************************************************************************
+ * emulate.c
+ *
+ * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
+ *
+ * Copyright (c) 2005 Keir Fraser
+ *
+ * Linux coding style, mod r/m decoder, segment base fixes, real-mode
+ * privileged instructions:
+ *
+ * Copyright (C) 2006 Qumranet
+ *
+ *   Avi Kivity <avi@qumranet.com>
+ *   Yaniv Kamay <yaniv@qumranet.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
+ */
+
+#ifndef __KERNEL__
+#include <stdio.h>
+#include <stdint.h>
+#include <public/xen.h>
+#define DPRINTF(_f, _a ...) printf(_f , ## _a)
+#else
+#include <linux/kvm_host.h>
+#include "kvm_cache_regs.h"
+#define DPRINTF(x...) do {} while (0)
+#endif
+#include <linux/module.h>
+#include <asm/kvm_emulate.h>
+
+#include "mmu.h"		/* for is_long_mode() */
+
+/*
+ * Opcode effective-address decode tables.
+ * Note that we only emulate instructions that have at least one memory
+ * operand (excluding implicit stack references). We assume that stack
+ * references and instruction fetches will never occur in special memory
+ * areas that require emulation. So, for example, 'mov <imm>,<reg>' need
+ * not be handled.
+ */
+
+/* Operand sizes: 8-bit operands or specified/overridden size. */
+#define ByteOp      (1<<0)	/* 8-bit operands. */
+/* Destination operand type. */
+#define ImplicitOps (1<<1)	/* Implicit in opcode. No generic decode. */
+#define DstReg      (2<<1)	/* Register operand. */
+#define DstMem      (3<<1)	/* Memory operand. */
+#define DstAcc      (4<<1)      /* Destination Accumulator */
+#define DstMask     (7<<1)
+/* Source operand type. */
+#define SrcNone     (0<<4)	/* No source operand. */
+#define SrcImplicit (0<<4)	/* Source operand is implicit in the opcode. */
+#define SrcReg      (1<<4)	/* Register operand. */
+#define SrcMem      (2<<4)	/* Memory operand. */
+#define SrcMem16    (3<<4)	/* Memory operand (16-bit). */
+#define SrcMem32    (4<<4)	/* Memory operand (32-bit). */
+#define SrcImm      (5<<4)	/* Immediate operand. */
+#define SrcImmByte  (6<<4)	/* 8-bit sign-extended immediate operand. */
+#define SrcOne      (7<<4)	/* Implied '1' */
+#define SrcImmUByte (8<<4)      /* 8-bit unsigned immediate operand. */
+#define SrcImmU     (9<<4)      /* Immediate operand, unsigned */
+#define SrcMask     (0xf<<4)
+/* Generic ModRM decode. */
+#define ModRM       (1<<8)
+/* Destination is only written; never read. */
+#define Mov         (1<<9)
+#define BitOp       (1<<10)
+#define MemAbs      (1<<11)      /* Memory operand is absolute displacement */
+#define String      (1<<12)     /* String instruction (rep capable) */
+#define Stack       (1<<13)     /* Stack instruction (push/pop) */
+#define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
+#define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
+#define GroupMask   0xff        /* Group number stored in bits 0:7 */
+/* Source 2 operand type */
+#define Src2None    (0<<29)
+#define Src2CL      (1<<29)
+#define Src2ImmByte (2<<29)
+#define Src2One     (3<<29)
+#define Src2Imm16   (4<<29)
+#define Src2Mask    (7<<29)
+
+enum {
+	Group1_80, Group1_81, Group1_82, Group1_83,
+	Group1A, Group3_Byte, Group3, Group4, Group5, Group7,
+};
+
+static u32 opcode_table[256] = {
+	/* 0x00 - 0x07 */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
+	/* 0x08 - 0x0F */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	0, 0, 0, 0,
+	/* 0x10 - 0x17 */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
+	/* 0x18 - 0x1F */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
+	/* 0x20 - 0x27 */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
+	/* 0x28 - 0x2F */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	0, 0, 0, 0,
+	/* 0x30 - 0x37 */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	0, 0, 0, 0,
+	/* 0x38 - 0x3F */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
+	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
+	0, 0,
+	/* 0x40 - 0x47 */
+	DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
+	/* 0x48 - 0x4F */
+	DstReg, DstReg, DstReg, DstReg,	DstReg, DstReg, DstReg, DstReg,
+	/* 0x50 - 0x57 */
+	SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
+	SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
+	/* 0x58 - 0x5F */
+	DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
+	DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
+	/* 0x60 - 0x67 */
+	0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
+	0, 0, 0, 0,
+	/* 0x68 - 0x6F */
+	SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
+	SrcNone  | ByteOp  | ImplicitOps, SrcNone  | ImplicitOps, /* insb, insw/insd */
+	SrcNone  | ByteOp  | ImplicitOps, SrcNone  | ImplicitOps, /* outsb, outsw/outsd */
+	/* 0x70 - 0x77 */
+	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
+	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
+	/* 0x78 - 0x7F */
+	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
+	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
+	/* 0x80 - 0x87 */
+	Group | Group1_80, Group | Group1_81,
+	Group | Group1_82, Group | Group1_83,
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
+	/* 0x88 - 0x8F */
+	ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
+	ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	DstMem | SrcReg | ModRM | Mov, ModRM | DstReg,
+	DstReg | SrcMem | ModRM | Mov, Group | Group1A,
+	/* 0x90 - 0x97 */
+	DstReg, DstReg, DstReg, DstReg,	DstReg, DstReg, DstReg, DstReg,
+	/* 0x98 - 0x9F */
+	0, 0, SrcImm | Src2Imm16, 0,
+	ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
+	/* 0xA0 - 0xA7 */
+	ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
+	ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs,
+	ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
+	ByteOp | ImplicitOps | String, ImplicitOps | String,
+	/* 0xA8 - 0xAF */
+	0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
+	ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
+	ByteOp | ImplicitOps | String, ImplicitOps | String,
+	/* 0xB0 - 0xB7 */
+	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+	/* 0xB8 - 0xBF */
+	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+	/* 0xC0 - 0xC7 */
+	ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
+	0, ImplicitOps | Stack, 0, 0,
+	ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
+	/* 0xC8 - 0xCF */
+	0, 0, 0, ImplicitOps | Stack,
+	ImplicitOps, SrcImmByte, ImplicitOps, ImplicitOps,
+	/* 0xD0 - 0xD7 */
+	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
+	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
+	0, 0, 0, 0,
+	/* 0xD8 - 0xDF */
+	0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0xE0 - 0xE7 */
+	0, 0, 0, 0,
+	ByteOp | SrcImmUByte, SrcImmUByte,
+	ByteOp | SrcImmUByte, SrcImmUByte,
+	/* 0xE8 - 0xEF */
+	SrcImm | Stack, SrcImm | ImplicitOps,
+	SrcImmU | Src2Imm16, SrcImmByte | ImplicitOps,
+	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
+	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
+	/* 0xF0 - 0xF7 */
+	0, 0, 0, 0,
+	ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3,
+	/* 0xF8 - 0xFF */
+	ImplicitOps, 0, ImplicitOps, ImplicitOps,
+	ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
+};
+
+static u32 twobyte_table[256] = {
+	/* 0x00 - 0x0F */
+	0, Group | GroupDual | Group7, 0, 0, 0, ImplicitOps, ImplicitOps, 0,
+	ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
+	/* 0x10 - 0x1F */
+	0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
+	/* 0x20 - 0x2F */
+	ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0x30 - 0x3F */
+	ImplicitOps, 0, ImplicitOps, 0,
+	ImplicitOps, ImplicitOps, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0x40 - 0x47 */
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	/* 0x48 - 0x4F */
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
+	/* 0x50 - 0x5F */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0x60 - 0x6F */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0x70 - 0x7F */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0x80 - 0x8F */
+	SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
+	SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
+	/* 0x90 - 0x9F */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0xA0 - 0xA7 */
+	0, 0, 0, DstMem | SrcReg | ModRM | BitOp,
+	DstMem | SrcReg | Src2ImmByte | ModRM,
+	DstMem | SrcReg | Src2CL | ModRM, 0, 0,
+	/* 0xA8 - 0xAF */
+	0, 0, 0, DstMem | SrcReg | ModRM | BitOp,
+	DstMem | SrcReg | Src2ImmByte | ModRM,
+	DstMem | SrcReg | Src2CL | ModRM,
+	ModRM, 0,
+	/* 0xB0 - 0xB7 */
+	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0,
+	    DstMem | SrcReg | ModRM | BitOp,
+	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
+	    DstReg | SrcMem16 | ModRM | Mov,
+	/* 0xB8 - 0xBF */
+	0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp,
+	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
+	    DstReg | SrcMem16 | ModRM | Mov,
+	/* 0xC0 - 0xCF */
+	0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0xD0 - 0xDF */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0xE0 - 0xEF */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	/* 0xF0 - 0xFF */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static u32 group_table[] = {
+	[Group1_80*8] =
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	[Group1_81*8] =
+	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
+	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
+	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
+	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
+	[Group1_82*8] =
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
+	[Group1_83*8] =
+	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
+	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
+	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
+	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
+	[Group1A*8] =
+	DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0,
+	[Group3_Byte*8] =
+	ByteOp | SrcImm | DstMem | ModRM, 0,
+	ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
+	0, 0, 0, 0,
+	[Group3*8] =
+	DstMem | SrcImm | ModRM, 0,
+	DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
+	0, 0, 0, 0,
+	[Group4*8] =
+	ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
+	0, 0, 0, 0, 0, 0,
+	[Group5*8] =
+	DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
+	SrcMem | ModRM | Stack, 0,
+	SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0,
+	[Group7*8] =
+	0, 0, ModRM | SrcMem, ModRM | SrcMem,
+	SrcNone | ModRM | DstMem | Mov, 0,
+	SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp,
+};
+
+static u32 group2_table[] = {
+	[Group7*8] =
+	SrcNone | ModRM, 0, 0, SrcNone | ModRM,
+	SrcNone | ModRM | DstMem | Mov, 0,
+	SrcMem16 | ModRM | Mov, 0,
+};
+
+/* EFLAGS bit definitions. */
+#define EFLG_VM (1<<17)
+#define EFLG_RF (1<<16)
+#define EFLG_OF (1<<11)
+#define EFLG_DF (1<<10)
+#define EFLG_IF (1<<9)
+#define EFLG_SF (1<<7)
+#define EFLG_ZF (1<<6)
+#define EFLG_AF (1<<4)
+#define EFLG_PF (1<<2)
+#define EFLG_CF (1<<0)
+
+/*
+ * Instruction emulation:
+ * Most instructions are emulated directly via a fragment of inline assembly
+ * code. This allows us to save/restore EFLAGS and thus very easily pick up
+ * any modified flags.
+ */
+
+#if defined(CONFIG_X86_64)
+#define _LO32 "k"		/* force 32-bit operand */
+#define _STK  "%%rsp"		/* stack pointer */
+#elif defined(__i386__)
+#define _LO32 ""		/* force 32-bit operand */
+#define _STK  "%%esp"		/* stack pointer */
+#endif
+
+/*
+ * These EFLAGS bits are restored from saved value during emulation, and
+ * any changes are written back to the saved value after emulation.
+ */
+#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
+
+/* Before executing instruction: restore necessary bits in EFLAGS. */
+#define _PRE_EFLAGS(_sav, _msk, _tmp)					\
+	/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
+	"movl %"_sav",%"_LO32 _tmp"; "                                  \
+	"push %"_tmp"; "                                                \
+	"push %"_tmp"; "                                                \
+	"movl %"_msk",%"_LO32 _tmp"; "                                  \
+	"andl %"_LO32 _tmp",("_STK"); "                                 \
+	"pushf; "                                                       \
+	"notl %"_LO32 _tmp"; "                                          \
+	"andl %"_LO32 _tmp",("_STK"); "                                 \
+	"andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); "	\
+	"pop  %"_tmp"; "                                                \
+	"orl  %"_LO32 _tmp",("_STK"); "                                 \
+	"popf; "                                                        \
+	"pop  %"_sav"; "
+
+/* After executing instruction: write-back necessary bits in EFLAGS. */
+#define _POST_EFLAGS(_sav, _msk, _tmp) \
+	/* _sav |= EFLAGS & _msk; */		\
+	"pushf; "				\
+	"pop  %"_tmp"; "			\
+	"andl %"_msk",%"_LO32 _tmp"; "		\
+	"orl  %"_LO32 _tmp",%"_sav"; "
+
+#ifdef CONFIG_X86_64
+#define ON64(x) x
+#else
+#define ON64(x)
+#endif
+
+#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix)	\
+	do {								\
+		__asm__ __volatile__ (					\
+			_PRE_EFLAGS("0", "4", "2")			\
+			_op _suffix " %"_x"3,%1; "			\
+			_POST_EFLAGS("0", "4", "2")			\
+			: "=m" (_eflags), "=m" ((_dst).val),		\
+			  "=&r" (_tmp)					\
+			: _y ((_src).val), "i" (EFLAGS_MASK));		\
+	} while (0)
+
+
+/* Raw emulation: instruction has two explicit operands. */
+#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
+	do {								\
+		unsigned long _tmp;					\
+									\
+		switch ((_dst).bytes) {					\
+		case 2:							\
+			____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
+			break;						\
+		case 4:							\
+			____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \
+			break;						\
+		case 8:							\
+			ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \
+			break;						\
+		}							\
+	} while (0)
+
+#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
+	do {								     \
+		unsigned long _tmp;					     \
+		switch ((_dst).bytes) {				             \
+		case 1:							     \
+			____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b");  \
+			break;						     \
+		default:						     \
+			__emulate_2op_nobyte(_op, _src, _dst, _eflags,	     \
+					     _wx, _wy, _lx, _ly, _qx, _qy);  \
+			break;						     \
+		}							     \
+	} while (0)
+
+/* Source operand is byte-sized and may be restricted to just %cl. */
+#define emulate_2op_SrcB(_op, _src, _dst, _eflags)                      \
+	__emulate_2op(_op, _src, _dst, _eflags,				\
+		      "b", "c", "b", "c", "b", "c", "b", "c")
+
+/* Source operand is byte, word, long or quad sized. */
+#define emulate_2op_SrcV(_op, _src, _dst, _eflags)                      \
+	__emulate_2op(_op, _src, _dst, _eflags,				\
+		      "b", "q", "w", "r", _LO32, "r", "", "r")
+
+/* Source operand is word, long or quad sized. */
+#define emulate_2op_SrcV_nobyte(_op, _src, _dst, _eflags)               \
+	__emulate_2op_nobyte(_op, _src, _dst, _eflags,			\
+			     "w", "r", _LO32, "r", "", "r")
+
+/* Instruction has three operands and one operand is stored in ECX register */
+#define __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, _suffix, _type) 	\
+	do {									\
+		unsigned long _tmp;						\
+		_type _clv  = (_cl).val;  					\
+		_type _srcv = (_src).val;    					\
+		_type _dstv = (_dst).val;					\
+										\
+		__asm__ __volatile__ (						\
+			_PRE_EFLAGS("0", "5", "2")				\
+			_op _suffix " %4,%1 \n"					\
+			_POST_EFLAGS("0", "5", "2")				\
+			: "=m" (_eflags), "+r" (_dstv), "=&r" (_tmp)		\
+			: "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK)		\
+			); 							\
+										\
+		(_cl).val  = (unsigned long) _clv;				\
+		(_src).val = (unsigned long) _srcv;				\
+		(_dst).val = (unsigned long) _dstv;				\
+	} while (0)
+
+#define emulate_2op_cl(_op, _cl, _src, _dst, _eflags)				\
+	do {									\
+		switch ((_dst).bytes) {						\
+		case 2:								\
+			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,  	\
+						"w", unsigned short);         	\
+			break;							\
+		case 4: 							\
+			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,  	\
+						"l", unsigned int);           	\
+			break;							\
+		case 8:								\
+			ON64(__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,	\
+						"q", unsigned long));  		\
+			break;							\
+		}								\
+	} while (0)
+
+#define __emulate_1op(_op, _dst, _eflags, _suffix)			\
+	do {								\
+		unsigned long _tmp;					\
+									\
+		__asm__ __volatile__ (					\
+			_PRE_EFLAGS("0", "3", "2")			\
+			_op _suffix " %1; "				\
+			_POST_EFLAGS("0", "3", "2")			\
+			: "=m" (_eflags), "+m" ((_dst).val),		\
+			  "=&r" (_tmp)					\
+			: "i" (EFLAGS_MASK));				\
+	} while (0)
+
+/* Instruction has only one explicit operand (no source operand). */
+#define emulate_1op(_op, _dst, _eflags)                                    \
+	do {								\
+		switch ((_dst).bytes) {				        \
+		case 1:	__emulate_1op(_op, _dst, _eflags, "b"); break;	\
+		case 2:	__emulate_1op(_op, _dst, _eflags, "w"); break;	\
+		case 4:	__emulate_1op(_op, _dst, _eflags, "l"); break;	\
+		case 8:	ON64(__emulate_1op(_op, _dst, _eflags, "q")); break; \
+		}							\
+	} while (0)
+
+/* Fetch next part of the instruction being emulated. */
+#define insn_fetch(_type, _size, _eip)                                  \
+({	unsigned long _x;						\
+	rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size));		\
+	if (rc != 0)							\
+		goto done;						\
+	(_eip) += (_size);						\
+	(_type)_x;							\
+})
+
+static inline unsigned long ad_mask(struct decode_cache *c)
+{
+	return (1UL << (c->ad_bytes << 3)) - 1;
+}
+
+/* Access/update address held in a register, based on addressing mode. */
+static inline unsigned long
+address_mask(struct decode_cache *c, unsigned long reg)
+{
+	if (c->ad_bytes == sizeof(unsigned long))
+		return reg;
+	else
+		return reg & ad_mask(c);
+}
+
+static inline unsigned long
+register_address(struct decode_cache *c, unsigned long base, unsigned long reg)
+{
+	return base + address_mask(c, reg);
+}
+
+static inline void
+register_address_increment(struct decode_cache *c, unsigned long *reg, int inc)
+{
+	if (c->ad_bytes == sizeof(unsigned long))
+		*reg += inc;
+	else
+		*reg = (*reg & ~ad_mask(c)) | ((*reg + inc) & ad_mask(c));
+}
+
+static inline void jmp_rel(struct decode_cache *c, int rel)
+{
+	register_address_increment(c, &c->eip, rel);
+}
+
+static void set_seg_override(struct decode_cache *c, int seg)
+{
+	c->has_seg_override = true;
+	c->seg_override = seg;
+}
+
+static unsigned long seg_base(struct x86_emulate_ctxt *ctxt, int seg)
+{
+	if (ctxt->mode == X86EMUL_MODE_PROT64 && seg < VCPU_SREG_FS)
+		return 0;
+
+	return kvm_x86_ops->get_segment_base(ctxt->vcpu, seg);
+}
+
+static unsigned long seg_override_base(struct x86_emulate_ctxt *ctxt,
+				       struct decode_cache *c)
+{
+	if (!c->has_seg_override)
+		return 0;
+
+	return seg_base(ctxt, c->seg_override);
+}
+
+static unsigned long es_base(struct x86_emulate_ctxt *ctxt)
+{
+	return seg_base(ctxt, VCPU_SREG_ES);
+}
+
+static unsigned long ss_base(struct x86_emulate_ctxt *ctxt)
+{
+	return seg_base(ctxt, VCPU_SREG_SS);
+}
+
+static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
+			      struct x86_emulate_ops *ops,
+			      unsigned long linear, u8 *dest)
+{
+	struct fetch_cache *fc = &ctxt->decode.fetch;
+	int rc;
+	int size;
+
+	if (linear < fc->start || linear >= fc->end) {
+		size = min(15UL, PAGE_SIZE - offset_in_page(linear));
+		rc = ops->read_std(linear, fc->data, size, ctxt->vcpu);
+		if (rc)
+			return rc;
+		fc->start = linear;
+		fc->end = linear + size;
+	}
+	*dest = fc->data[linear - fc->start];
+	return 0;
+}
+
+static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
+			 struct x86_emulate_ops *ops,
+			 unsigned long eip, void *dest, unsigned size)
+{
+	int rc = 0;
+
+	eip += ctxt->cs_base;
+	while (size--) {
+		rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
+		if (rc)
+			return rc;
+	}
+	return 0;
+}
+
+/*
+ * Given the 'reg' portion of a ModRM byte, and a register block, return a
+ * pointer into the block that addresses the relevant register.
+ * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
+ */
+static void *decode_register(u8 modrm_reg, unsigned long *regs,
+			     int highbyte_regs)
+{
+	void *p;
+
+	p = &regs[modrm_reg];
+	if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8)
+		p = (unsigned char *)&regs[modrm_reg & 3] + 1;
+	return p;
+}
+
+static int read_descriptor(struct x86_emulate_ctxt *ctxt,
+			   struct x86_emulate_ops *ops,
+			   void *ptr,
+			   u16 *size, unsigned long *address, int op_bytes)
+{
+	int rc;
+
+	if (op_bytes == 2)
+		op_bytes = 3;
+	*address = 0;
+	rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
+			   ctxt->vcpu);
+	if (rc)
+		return rc;
+	rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
+			   ctxt->vcpu);
+	return rc;
+}
+
+static int test_cc(unsigned int condition, unsigned int flags)
+{
+	int rc = 0;
+
+	switch ((condition & 15) >> 1) {
+	case 0: /* o */
+		rc |= (flags & EFLG_OF);
+		break;
+	case 1: /* b/c/nae */
+		rc |= (flags & EFLG_CF);
+		break;
+	case 2: /* z/e */
+		rc |= (flags & EFLG_ZF);
+		break;
+	case 3: /* be/na */
+		rc |= (flags & (EFLG_CF|EFLG_ZF));
+		break;
+	case 4: /* s */
+		rc |= (flags & EFLG_SF);
+		break;
+	case 5: /* p/pe */
+		rc |= (flags & EFLG_PF);
+		break;
+	case 7: /* le/ng */
+		rc |= (flags & EFLG_ZF);
+		/* fall through */
+	case 6: /* l/nge */
+		rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF));
+		break;
+	}
+
+	/* Odd condition identifiers (lsb == 1) have inverted sense. */
+	return (!!rc ^ (condition & 1));
+}
+
+static void decode_register_operand(struct operand *op,
+				    struct decode_cache *c,
+				    int inhibit_bytereg)
+{
+	unsigned reg = c->modrm_reg;
+	int highbyte_regs = c->rex_prefix == 0;
+
+	if (!(c->d & ModRM))
+		reg = (c->b & 7) | ((c->rex_prefix & 1) << 3);
+	op->type = OP_REG;
+	if ((c->d & ByteOp) && !inhibit_bytereg) {
+		op->ptr = decode_register(reg, c->regs, highbyte_regs);
+		op->val = *(u8 *)op->ptr;
+		op->bytes = 1;
+	} else {
+		op->ptr = decode_register(reg, c->regs, 0);
+		op->bytes = c->op_bytes;
+		switch (op->bytes) {
+		case 2:
+			op->val = *(u16 *)op->ptr;
+			break;
+		case 4:
+			op->val = *(u32 *)op->ptr;
+			break;
+		case 8:
+			op->val = *(u64 *) op->ptr;
+			break;
+		}
+	}
+	op->orig_val = op->val;
+}
+
+static int decode_modrm(struct x86_emulate_ctxt *ctxt,
+			struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	u8 sib;
+	int index_reg = 0, base_reg = 0, scale;
+	int rc = 0;
+
+	if (c->rex_prefix) {
+		c->modrm_reg = (c->rex_prefix & 4) << 1;	/* REX.R */
+		index_reg = (c->rex_prefix & 2) << 2; /* REX.X */
+		c->modrm_rm = base_reg = (c->rex_prefix & 1) << 3; /* REG.B */
+	}
+
+	c->modrm = insn_fetch(u8, 1, c->eip);
+	c->modrm_mod |= (c->modrm & 0xc0) >> 6;
+	c->modrm_reg |= (c->modrm & 0x38) >> 3;
+	c->modrm_rm |= (c->modrm & 0x07);
+	c->modrm_ea = 0;
+	c->use_modrm_ea = 1;
+
+	if (c->modrm_mod == 3) {
+		c->modrm_ptr = decode_register(c->modrm_rm,
+					       c->regs, c->d & ByteOp);
+		c->modrm_val = *(unsigned long *)c->modrm_ptr;
+		return rc;
+	}
+
+	if (c->ad_bytes == 2) {
+		unsigned bx = c->regs[VCPU_REGS_RBX];
+		unsigned bp = c->regs[VCPU_REGS_RBP];
+		unsigned si = c->regs[VCPU_REGS_RSI];
+		unsigned di = c->regs[VCPU_REGS_RDI];
+
+		/* 16-bit ModR/M decode. */
+		switch (c->modrm_mod) {
+		case 0:
+			if (c->modrm_rm == 6)
+				c->modrm_ea += insn_fetch(u16, 2, c->eip);
+			break;
+		case 1:
+			c->modrm_ea += insn_fetch(s8, 1, c->eip);
+			break;
+		case 2:
+			c->modrm_ea += insn_fetch(u16, 2, c->eip);
+			break;
+		}
+		switch (c->modrm_rm) {
+		case 0:
+			c->modrm_ea += bx + si;
+			break;
+		case 1:
+			c->modrm_ea += bx + di;
+			break;
+		case 2:
+			c->modrm_ea += bp + si;
+			break;
+		case 3:
+			c->modrm_ea += bp + di;
+			break;
+		case 4:
+			c->modrm_ea += si;
+			break;
+		case 5:
+			c->modrm_ea += di;
+			break;
+		case 6:
+			if (c->modrm_mod != 0)
+				c->modrm_ea += bp;
+			break;
+		case 7:
+			c->modrm_ea += bx;
+			break;
+		}
+		if (c->modrm_rm == 2 || c->modrm_rm == 3 ||
+		    (c->modrm_rm == 6 && c->modrm_mod != 0))
+			if (!c->has_seg_override)
+				set_seg_override(c, VCPU_SREG_SS);
+		c->modrm_ea = (u16)c->modrm_ea;
+	} else {
+		/* 32/64-bit ModR/M decode. */
+		if ((c->modrm_rm & 7) == 4) {
+			sib = insn_fetch(u8, 1, c->eip);
+			index_reg |= (sib >> 3) & 7;
+			base_reg |= sib & 7;
+			scale = sib >> 6;
+
+			if ((base_reg & 7) == 5 && c->modrm_mod == 0)
+				c->modrm_ea += insn_fetch(s32, 4, c->eip);
+			else
+				c->modrm_ea += c->regs[base_reg];
+			if (index_reg != 4)
+				c->modrm_ea += c->regs[index_reg] << scale;
+		} else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) {
+			if (ctxt->mode == X86EMUL_MODE_PROT64)
+				c->rip_relative = 1;
+		} else
+			c->modrm_ea += c->regs[c->modrm_rm];
+		switch (c->modrm_mod) {
+		case 0:
+			if (c->modrm_rm == 5)
+				c->modrm_ea += insn_fetch(s32, 4, c->eip);
+			break;
+		case 1:
+			c->modrm_ea += insn_fetch(s8, 1, c->eip);
+			break;
+		case 2:
+			c->modrm_ea += insn_fetch(s32, 4, c->eip);
+			break;
+		}
+	}
+done:
+	return rc;
+}
+
+static int decode_abs(struct x86_emulate_ctxt *ctxt,
+		      struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc = 0;
+
+	switch (c->ad_bytes) {
+	case 2:
+		c->modrm_ea = insn_fetch(u16, 2, c->eip);
+		break;
+	case 4:
+		c->modrm_ea = insn_fetch(u32, 4, c->eip);
+		break;
+	case 8:
+		c->modrm_ea = insn_fetch(u64, 8, c->eip);
+		break;
+	}
+done:
+	return rc;
+}
+
+int
+x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc = 0;
+	int mode = ctxt->mode;
+	int def_op_bytes, def_ad_bytes, group;
+
+	/* Shadow copy of register state. Committed on successful emulation. */
+
+	memset(c, 0, sizeof(struct decode_cache));
+	c->eip = kvm_rip_read(ctxt->vcpu);
+	ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
+	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
+
+	switch (mode) {
+	case X86EMUL_MODE_REAL:
+	case X86EMUL_MODE_PROT16:
+		def_op_bytes = def_ad_bytes = 2;
+		break;
+	case X86EMUL_MODE_PROT32:
+		def_op_bytes = def_ad_bytes = 4;
+		break;
+#ifdef CONFIG_X86_64
+	case X86EMUL_MODE_PROT64:
+		def_op_bytes = 4;
+		def_ad_bytes = 8;
+		break;
+#endif
+	default:
+		return -1;
+	}
+
+	c->op_bytes = def_op_bytes;
+	c->ad_bytes = def_ad_bytes;
+
+	/* Legacy prefixes. */
+	for (;;) {
+		switch (c->b = insn_fetch(u8, 1, c->eip)) {
+		case 0x66:	/* operand-size override */
+			/* switch between 2/4 bytes */
+			c->op_bytes = def_op_bytes ^ 6;
+			break;
+		case 0x67:	/* address-size override */
+			if (mode == X86EMUL_MODE_PROT64)
+				/* switch between 4/8 bytes */
+				c->ad_bytes = def_ad_bytes ^ 12;
+			else
+				/* switch between 2/4 bytes */
+				c->ad_bytes = def_ad_bytes ^ 6;
+			break;
+		case 0x26:	/* ES override */
+		case 0x2e:	/* CS override */
+		case 0x36:	/* SS override */
+		case 0x3e:	/* DS override */
+			set_seg_override(c, (c->b >> 3) & 3);
+			break;
+		case 0x64:	/* FS override */
+		case 0x65:	/* GS override */
+			set_seg_override(c, c->b & 7);
+			break;
+		case 0x40 ... 0x4f: /* REX */
+			if (mode != X86EMUL_MODE_PROT64)
+				goto done_prefixes;
+			c->rex_prefix = c->b;
+			continue;
+		case 0xf0:	/* LOCK */
+			c->lock_prefix = 1;
+			break;
+		case 0xf2:	/* REPNE/REPNZ */
+			c->rep_prefix = REPNE_PREFIX;
+			break;
+		case 0xf3:	/* REP/REPE/REPZ */
+			c->rep_prefix = REPE_PREFIX;
+			break;
+		default:
+			goto done_prefixes;
+		}
+
+		/* Any legacy prefix after a REX prefix nullifies its effect. */
+
+		c->rex_prefix = 0;
+	}
+
+done_prefixes:
+
+	/* REX prefix. */
+	if (c->rex_prefix)
+		if (c->rex_prefix & 8)
+			c->op_bytes = 8;	/* REX.W */
+
+	/* Opcode byte(s). */
+	c->d = opcode_table[c->b];
+	if (c->d == 0) {
+		/* Two-byte opcode? */
+		if (c->b == 0x0f) {
+			c->twobyte = 1;
+			c->b = insn_fetch(u8, 1, c->eip);
+			c->d = twobyte_table[c->b];
+		}
+	}
+
+	if (c->d & Group) {
+		group = c->d & GroupMask;
+		c->modrm = insn_fetch(u8, 1, c->eip);
+		--c->eip;
+
+		group = (group << 3) + ((c->modrm >> 3) & 7);
+		if ((c->d & GroupDual) && (c->modrm >> 6) == 3)
+			c->d = group2_table[group];
+		else
+			c->d = group_table[group];
+	}
+
+	/* Unrecognised? */
+	if (c->d == 0) {
+		DPRINTF("Cannot emulate %02x\n", c->b);
+		return -1;
+	}
+
+	if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
+		c->op_bytes = 8;
+
+	/* ModRM and SIB bytes. */
+	if (c->d & ModRM)
+		rc = decode_modrm(ctxt, ops);
+	else if (c->d & MemAbs)
+		rc = decode_abs(ctxt, ops);
+	if (rc)
+		goto done;
+
+	if (!c->has_seg_override)
+		set_seg_override(c, VCPU_SREG_DS);
+
+	if (!(!c->twobyte && c->b == 0x8d))
+		c->modrm_ea += seg_override_base(ctxt, c);
+
+	if (c->ad_bytes != 8)
+		c->modrm_ea = (u32)c->modrm_ea;
+	/*
+	 * Decode and fetch the source operand: register, memory
+	 * or immediate.
+	 */
+	switch (c->d & SrcMask) {
+	case SrcNone:
+		break;
+	case SrcReg:
+		decode_register_operand(&c->src, c, 0);
+		break;
+	case SrcMem16:
+		c->src.bytes = 2;
+		goto srcmem_common;
+	case SrcMem32:
+		c->src.bytes = 4;
+		goto srcmem_common;
+	case SrcMem:
+		c->src.bytes = (c->d & ByteOp) ? 1 :
+							   c->op_bytes;
+		/* Don't fetch the address for invlpg: it could be unmapped. */
+		if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7)
+			break;
+	srcmem_common:
+		/*
+		 * For instructions with a ModR/M byte, switch to register
+		 * access if Mod = 3.
+		 */
+		if ((c->d & ModRM) && c->modrm_mod == 3) {
+			c->src.type = OP_REG;
+			c->src.val = c->modrm_val;
+			c->src.ptr = c->modrm_ptr;
+			break;
+		}
+		c->src.type = OP_MEM;
+		break;
+	case SrcImm:
+	case SrcImmU:
+		c->src.type = OP_IMM;
+		c->src.ptr = (unsigned long *)c->eip;
+		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		if (c->src.bytes == 8)
+			c->src.bytes = 4;
+		/* NB. Immediates are sign-extended as necessary. */
+		switch (c->src.bytes) {
+		case 1:
+			c->src.val = insn_fetch(s8, 1, c->eip);
+			break;
+		case 2:
+			c->src.val = insn_fetch(s16, 2, c->eip);
+			break;
+		case 4:
+			c->src.val = insn_fetch(s32, 4, c->eip);
+			break;
+		}
+		if ((c->d & SrcMask) == SrcImmU) {
+			switch (c->src.bytes) {
+			case 1:
+				c->src.val &= 0xff;
+				break;
+			case 2:
+				c->src.val &= 0xffff;
+				break;
+			case 4:
+				c->src.val &= 0xffffffff;
+				break;
+			}
+		}
+		break;
+	case SrcImmByte:
+	case SrcImmUByte:
+		c->src.type = OP_IMM;
+		c->src.ptr = (unsigned long *)c->eip;
+		c->src.bytes = 1;
+		if ((c->d & SrcMask) == SrcImmByte)
+			c->src.val = insn_fetch(s8, 1, c->eip);
+		else
+			c->src.val = insn_fetch(u8, 1, c->eip);
+		break;
+	case SrcOne:
+		c->src.bytes = 1;
+		c->src.val = 1;
+		break;
+	}
+
+	/*
+	 * Decode and fetch the second source operand: register, memory
+	 * or immediate.
+	 */
+	switch (c->d & Src2Mask) {
+	case Src2None:
+		break;
+	case Src2CL:
+		c->src2.bytes = 1;
+		c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8;
+		break;
+	case Src2ImmByte:
+		c->src2.type = OP_IMM;
+		c->src2.ptr = (unsigned long *)c->eip;
+		c->src2.bytes = 1;
+		c->src2.val = insn_fetch(u8, 1, c->eip);
+		break;
+	case Src2Imm16:
+		c->src2.type = OP_IMM;
+		c->src2.ptr = (unsigned long *)c->eip;
+		c->src2.bytes = 2;
+		c->src2.val = insn_fetch(u16, 2, c->eip);
+		break;
+	case Src2One:
+		c->src2.bytes = 1;
+		c->src2.val = 1;
+		break;
+	}
+
+	/* Decode and fetch the destination operand: register or memory. */
+	switch (c->d & DstMask) {
+	case ImplicitOps:
+		/* Special instructions do their own operand decoding. */
+		return 0;
+	case DstReg:
+		decode_register_operand(&c->dst, c,
+			 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
+		break;
+	case DstMem:
+		if ((c->d & ModRM) && c->modrm_mod == 3) {
+			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+			c->dst.type = OP_REG;
+			c->dst.val = c->dst.orig_val = c->modrm_val;
+			c->dst.ptr = c->modrm_ptr;
+			break;
+		}
+		c->dst.type = OP_MEM;
+		break;
+	case DstAcc:
+		c->dst.type = OP_REG;
+		c->dst.bytes = c->op_bytes;
+		c->dst.ptr = &c->regs[VCPU_REGS_RAX];
+		switch (c->op_bytes) {
+			case 1:
+				c->dst.val = *(u8 *)c->dst.ptr;
+				break;
+			case 2:
+				c->dst.val = *(u16 *)c->dst.ptr;
+				break;
+			case 4:
+				c->dst.val = *(u32 *)c->dst.ptr;
+				break;
+		}
+		c->dst.orig_val = c->dst.val;
+		break;
+	}
+
+	if (c->rip_relative)
+		c->modrm_ea += c->eip;
+
+done:
+	return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+}
+
+static inline void emulate_push(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->dst.type  = OP_MEM;
+	c->dst.bytes = c->op_bytes;
+	c->dst.val = c->src.val;
+	register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes);
+	c->dst.ptr = (void *) register_address(c, ss_base(ctxt),
+					       c->regs[VCPU_REGS_RSP]);
+}
+
+static int emulate_pop(struct x86_emulate_ctxt *ctxt,
+		       struct x86_emulate_ops *ops,
+		       void *dest, int len)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+
+	rc = ops->read_emulated(register_address(c, ss_base(ctxt),
+						 c->regs[VCPU_REGS_RSP]),
+				dest, len, ctxt->vcpu);
+	if (rc != 0)
+		return rc;
+
+	register_address_increment(c, &c->regs[VCPU_REGS_RSP], len);
+	return rc;
+}
+
+static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
+				struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+
+	rc = emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes);
+	if (rc != 0)
+		return rc;
+	return 0;
+}
+
+static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	switch (c->modrm_reg) {
+	case 0:	/* rol */
+		emulate_2op_SrcB("rol", c->src, c->dst, ctxt->eflags);
+		break;
+	case 1:	/* ror */
+		emulate_2op_SrcB("ror", c->src, c->dst, ctxt->eflags);
+		break;
+	case 2:	/* rcl */
+		emulate_2op_SrcB("rcl", c->src, c->dst, ctxt->eflags);
+		break;
+	case 3:	/* rcr */
+		emulate_2op_SrcB("rcr", c->src, c->dst, ctxt->eflags);
+		break;
+	case 4:	/* sal/shl */
+	case 6:	/* sal/shl */
+		emulate_2op_SrcB("sal", c->src, c->dst, ctxt->eflags);
+		break;
+	case 5:	/* shr */
+		emulate_2op_SrcB("shr", c->src, c->dst, ctxt->eflags);
+		break;
+	case 7:	/* sar */
+		emulate_2op_SrcB("sar", c->src, c->dst, ctxt->eflags);
+		break;
+	}
+}
+
+static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
+			       struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc = 0;
+
+	switch (c->modrm_reg) {
+	case 0 ... 1:	/* test */
+		emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
+		break;
+	case 2:	/* not */
+		c->dst.val = ~c->dst.val;
+		break;
+	case 3:	/* neg */
+		emulate_1op("neg", c->dst, ctxt->eflags);
+		break;
+	default:
+		DPRINTF("Cannot emulate %02x\n", c->b);
+		rc = X86EMUL_UNHANDLEABLE;
+		break;
+	}
+	return rc;
+}
+
+static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
+			       struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	switch (c->modrm_reg) {
+	case 0:	/* inc */
+		emulate_1op("inc", c->dst, ctxt->eflags);
+		break;
+	case 1:	/* dec */
+		emulate_1op("dec", c->dst, ctxt->eflags);
+		break;
+	case 2: /* call near abs */ {
+		long int old_eip;
+		old_eip = c->eip;
+		c->eip = c->src.val;
+		c->src.val = old_eip;
+		emulate_push(ctxt);
+		break;
+	}
+	case 4: /* jmp abs */
+		c->eip = c->src.val;
+		break;
+	case 6:	/* push */
+		emulate_push(ctxt);
+		break;
+	}
+	return 0;
+}
+
+static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
+			       struct x86_emulate_ops *ops,
+			       unsigned long memop)
+{
+	struct decode_cache *c = &ctxt->decode;
+	u64 old, new;
+	int rc;
+
+	rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu);
+	if (rc != 0)
+		return rc;
+
+	if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
+	    ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
+
+		c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
+		c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
+		ctxt->eflags &= ~EFLG_ZF;
+
+	} else {
+		new = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
+		       (u32) c->regs[VCPU_REGS_RBX];
+
+		rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu);
+		if (rc != 0)
+			return rc;
+		ctxt->eflags |= EFLG_ZF;
+	}
+	return 0;
+}
+
+static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
+			   struct x86_emulate_ops *ops)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+	unsigned long cs;
+
+	rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes);
+	if (rc)
+		return rc;
+	if (c->op_bytes == 4)
+		c->eip = (u32)c->eip;
+	rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
+	if (rc)
+		return rc;
+	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS);
+	return rc;
+}
+
+static inline int writeback(struct x86_emulate_ctxt *ctxt,
+			    struct x86_emulate_ops *ops)
+{
+	int rc;
+	struct decode_cache *c = &ctxt->decode;
+
+	switch (c->dst.type) {
+	case OP_REG:
+		/* The 4-byte case *is* correct:
+		 * in 64-bit mode we zero-extend.
+		 */
+		switch (c->dst.bytes) {
+		case 1:
+			*(u8 *)c->dst.ptr = (u8)c->dst.val;
+			break;
+		case 2:
+			*(u16 *)c->dst.ptr = (u16)c->dst.val;
+			break;
+		case 4:
+			*c->dst.ptr = (u32)c->dst.val;
+			break;	/* 64b: zero-ext */
+		case 8:
+			*c->dst.ptr = c->dst.val;
+			break;
+		}
+		break;
+	case OP_MEM:
+		if (c->lock_prefix)
+			rc = ops->cmpxchg_emulated(
+					(unsigned long)c->dst.ptr,
+					&c->dst.orig_val,
+					&c->dst.val,
+					c->dst.bytes,
+					ctxt->vcpu);
+		else
+			rc = ops->write_emulated(
+					(unsigned long)c->dst.ptr,
+					&c->dst.val,
+					c->dst.bytes,
+					ctxt->vcpu);
+		if (rc != 0)
+			return rc;
+		break;
+	case OP_NONE:
+		/* no writeback */
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask)
+{
+	u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask);
+	/*
+	 * an sti; sti; sequence only disable interrupts for the first
+	 * instruction. So, if the last instruction, be it emulated or
+	 * not, left the system with the INT_STI flag enabled, it
+	 * means that the last instruction is an sti. We should not
+	 * leave the flag on in this case. The same goes for mov ss
+	 */
+	if (!(int_shadow & mask))
+		ctxt->interruptibility = mask;
+}
+
+static inline void
+setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
+	struct kvm_segment *cs, struct kvm_segment *ss)
+{
+	memset(cs, 0, sizeof(struct kvm_segment));
+	kvm_x86_ops->get_segment(ctxt->vcpu, cs, VCPU_SREG_CS);
+	memset(ss, 0, sizeof(struct kvm_segment));
+
+	cs->l = 0;		/* will be adjusted later */
+	cs->base = 0;		/* flat segment */
+	cs->g = 1;		/* 4kb granularity */
+	cs->limit = 0xffffffff;	/* 4GB limit */
+	cs->type = 0x0b;	/* Read, Execute, Accessed */
+	cs->s = 1;
+	cs->dpl = 0;		/* will be adjusted later */
+	cs->present = 1;
+	cs->db = 1;
+
+	ss->unusable = 0;
+	ss->base = 0;		/* flat segment */
+	ss->limit = 0xffffffff;	/* 4GB limit */
+	ss->g = 1;		/* 4kb granularity */
+	ss->s = 1;
+	ss->type = 0x03;	/* Read/Write, Accessed */
+	ss->db = 1;		/* 32bit stack segment */
+	ss->dpl = 0;
+	ss->present = 1;
+}
+
+static int
+emulate_syscall(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct kvm_segment cs, ss;
+	u64 msr_data;
+
+	/* syscall is not available in real mode */
+	if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL
+		|| !(ctxt->vcpu->arch.cr0 & X86_CR0_PE))
+		return -1;
+
+	setup_syscalls_segments(ctxt, &cs, &ss);
+
+	kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
+	msr_data >>= 32;
+	cs.selector = (u16)(msr_data & 0xfffc);
+	ss.selector = (u16)(msr_data + 8);
+
+	if (is_long_mode(ctxt->vcpu)) {
+		cs.db = 0;
+		cs.l = 1;
+	}
+	kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS);
+	kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS);
+
+	c->regs[VCPU_REGS_RCX] = c->eip;
+	if (is_long_mode(ctxt->vcpu)) {
+#ifdef CONFIG_X86_64
+		c->regs[VCPU_REGS_R11] = ctxt->eflags & ~EFLG_RF;
+
+		kvm_x86_ops->get_msr(ctxt->vcpu,
+			ctxt->mode == X86EMUL_MODE_PROT64 ?
+			MSR_LSTAR : MSR_CSTAR, &msr_data);
+		c->eip = msr_data;
+
+		kvm_x86_ops->get_msr(ctxt->vcpu, MSR_SYSCALL_MASK, &msr_data);
+		ctxt->eflags &= ~(msr_data | EFLG_RF);
+#endif
+	} else {
+		/* legacy mode */
+		kvm_x86_ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
+		c->eip = (u32)msr_data;
+
+		ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
+	}
+
+	return 0;
+}
+
+static int
+emulate_sysenter(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct kvm_segment cs, ss;
+	u64 msr_data;
+
+	/* inject #UD if LOCK prefix is used */
+	if (c->lock_prefix)
+		return -1;
+
+	/* inject #GP if in real mode or paging is disabled */
+	if (ctxt->mode == X86EMUL_MODE_REAL ||
+		!(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
+		kvm_inject_gp(ctxt->vcpu, 0);
+		return -1;
+	}
+
+	/* XXX sysenter/sysexit have not been tested in 64bit mode.
+	* Therefore, we inject an #UD.
+	*/
+	if (ctxt->mode == X86EMUL_MODE_PROT64)
+		return -1;
+
+	setup_syscalls_segments(ctxt, &cs, &ss);
+
+	kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
+	switch (ctxt->mode) {
+	case X86EMUL_MODE_PROT32:
+		if ((msr_data & 0xfffc) == 0x0) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			return -1;
+		}
+		break;
+	case X86EMUL_MODE_PROT64:
+		if (msr_data == 0x0) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			return -1;
+		}
+		break;
+	}
+
+	ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
+	cs.selector = (u16)msr_data;
+	cs.selector &= ~SELECTOR_RPL_MASK;
+	ss.selector = cs.selector + 8;
+	ss.selector &= ~SELECTOR_RPL_MASK;
+	if (ctxt->mode == X86EMUL_MODE_PROT64
+		|| is_long_mode(ctxt->vcpu)) {
+		cs.db = 0;
+		cs.l = 1;
+	}
+
+	kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS);
+	kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS);
+
+	kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_EIP, &msr_data);
+	c->eip = msr_data;
+
+	kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data);
+	c->regs[VCPU_REGS_RSP] = msr_data;
+
+	return 0;
+}
+
+static int
+emulate_sysexit(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct kvm_segment cs, ss;
+	u64 msr_data;
+	int usermode;
+
+	/* inject #UD if LOCK prefix is used */
+	if (c->lock_prefix)
+		return -1;
+
+	/* inject #GP if in real mode or paging is disabled */
+	if (ctxt->mode == X86EMUL_MODE_REAL
+		|| !(ctxt->vcpu->arch.cr0 & X86_CR0_PE)) {
+		kvm_inject_gp(ctxt->vcpu, 0);
+		return -1;
+	}
+
+	/* sysexit must be called from CPL 0 */
+	if (kvm_x86_ops->get_cpl(ctxt->vcpu) != 0) {
+		kvm_inject_gp(ctxt->vcpu, 0);
+		return -1;
+	}
+
+	setup_syscalls_segments(ctxt, &cs, &ss);
+
+	if ((c->rex_prefix & 0x8) != 0x0)
+		usermode = X86EMUL_MODE_PROT64;
+	else
+		usermode = X86EMUL_MODE_PROT32;
+
+	cs.dpl = 3;
+	ss.dpl = 3;
+	kvm_x86_ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
+	switch (usermode) {
+	case X86EMUL_MODE_PROT32:
+		cs.selector = (u16)(msr_data + 16);
+		if ((msr_data & 0xfffc) == 0x0) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			return -1;
+		}
+		ss.selector = (u16)(msr_data + 24);
+		break;
+	case X86EMUL_MODE_PROT64:
+		cs.selector = (u16)(msr_data + 32);
+		if (msr_data == 0x0) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			return -1;
+		}
+		ss.selector = cs.selector + 8;
+		cs.db = 0;
+		cs.l = 1;
+		break;
+	}
+	cs.selector |= SELECTOR_RPL_MASK;
+	ss.selector |= SELECTOR_RPL_MASK;
+
+	kvm_x86_ops->set_segment(ctxt->vcpu, &cs, VCPU_SREG_CS);
+	kvm_x86_ops->set_segment(ctxt->vcpu, &ss, VCPU_SREG_SS);
+
+	c->eip = ctxt->vcpu->arch.regs[VCPU_REGS_RDX];
+	c->regs[VCPU_REGS_RSP] = ctxt->vcpu->arch.regs[VCPU_REGS_RCX];
+
+	return 0;
+}
+
+int
+x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
+{
+	unsigned long memop = 0;
+	u64 msr_data;
+	unsigned long saved_eip = 0;
+	struct decode_cache *c = &ctxt->decode;
+	unsigned int port;
+	int io_dir_in;
+	int rc = 0;
+
+	ctxt->interruptibility = 0;
+
+	/* Shadow copy of register state. Committed on successful emulation.
+	 * NOTE: we can copy them from vcpu as x86_decode_insn() doesn't
+	 * modify them.
+	 */
+
+	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
+	saved_eip = c->eip;
+
+	if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs))
+		memop = c->modrm_ea;
+
+	if (c->rep_prefix && (c->d & String)) {
+		/* All REP prefixes have the same first termination condition */
+		if (c->regs[VCPU_REGS_RCX] == 0) {
+			kvm_rip_write(ctxt->vcpu, c->eip);
+			goto done;
+		}
+		/* The second termination condition only applies for REPE
+		 * and REPNE. Test if the repeat string operation prefix is
+		 * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
+		 * corresponding termination condition according to:
+		 * 	- if REPE/REPZ and ZF = 0 then done
+		 * 	- if REPNE/REPNZ and ZF = 1 then done
+		 */
+		if ((c->b == 0xa6) || (c->b == 0xa7) ||
+				(c->b == 0xae) || (c->b == 0xaf)) {
+			if ((c->rep_prefix == REPE_PREFIX) &&
+				((ctxt->eflags & EFLG_ZF) == 0)) {
+					kvm_rip_write(ctxt->vcpu, c->eip);
+					goto done;
+			}
+			if ((c->rep_prefix == REPNE_PREFIX) &&
+				((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) {
+				kvm_rip_write(ctxt->vcpu, c->eip);
+				goto done;
+			}
+		}
+		c->regs[VCPU_REGS_RCX]--;
+		c->eip = kvm_rip_read(ctxt->vcpu);
+	}
+
+	if (c->src.type == OP_MEM) {
+		c->src.ptr = (unsigned long *)memop;
+		c->src.val = 0;
+		rc = ops->read_emulated((unsigned long)c->src.ptr,
+					&c->src.val,
+					c->src.bytes,
+					ctxt->vcpu);
+		if (rc != 0)
+			goto done;
+		c->src.orig_val = c->src.val;
+	}
+
+	if ((c->d & DstMask) == ImplicitOps)
+		goto special_insn;
+
+
+	if (c->dst.type == OP_MEM) {
+		c->dst.ptr = (unsigned long *)memop;
+		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.val = 0;
+		if (c->d & BitOp) {
+			unsigned long mask = ~(c->dst.bytes * 8 - 1);
+
+			c->dst.ptr = (void *)c->dst.ptr +
+						   (c->src.val & mask) / 8;
+		}
+		if (!(c->d & Mov) &&
+				   /* optimisation - avoid slow emulated read */
+		    ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
+					   &c->dst.val,
+					  c->dst.bytes, ctxt->vcpu)) != 0))
+			goto done;
+	}
+	c->dst.orig_val = c->dst.val;
+
+special_insn:
+
+	if (c->twobyte)
+		goto twobyte_insn;
+
+	switch (c->b) {
+	case 0x00 ... 0x05:
+	      add:		/* add */
+		emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x08 ... 0x0d:
+	      or:		/* or */
+		emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x10 ... 0x15:
+	      adc:		/* adc */
+		emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x18 ... 0x1d:
+	      sbb:		/* sbb */
+		emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x20 ... 0x25:
+	      and:		/* and */
+		emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x28 ... 0x2d:
+	      sub:		/* sub */
+		emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x30 ... 0x35:
+	      xor:		/* xor */
+		emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x38 ... 0x3d:
+	      cmp:		/* cmp */
+		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x40 ... 0x47: /* inc r16/r32 */
+		emulate_1op("inc", c->dst, ctxt->eflags);
+		break;
+	case 0x48 ... 0x4f: /* dec r16/r32 */
+		emulate_1op("dec", c->dst, ctxt->eflags);
+		break;
+	case 0x50 ... 0x57:  /* push reg */
+		emulate_push(ctxt);
+		break;
+	case 0x58 ... 0x5f: /* pop reg */
+	pop_instruction:
+		rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
+		if (rc != 0)
+			goto done;
+		break;
+	case 0x63:		/* movsxd */
+		if (ctxt->mode != X86EMUL_MODE_PROT64)
+			goto cannot_emulate;
+		c->dst.val = (s32) c->src.val;
+		break;
+	case 0x68: /* push imm */
+	case 0x6a: /* push imm8 */
+		emulate_push(ctxt);
+		break;
+	case 0x6c:		/* insb */
+	case 0x6d:		/* insw/insd */
+		 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
+				1,
+				(c->d & ByteOp) ? 1 : c->op_bytes,
+				c->rep_prefix ?
+				address_mask(c, c->regs[VCPU_REGS_RCX]) : 1,
+				(ctxt->eflags & EFLG_DF),
+				register_address(c, es_base(ctxt),
+						 c->regs[VCPU_REGS_RDI]),
+				c->rep_prefix,
+				c->regs[VCPU_REGS_RDX]) == 0) {
+			c->eip = saved_eip;
+			return -1;
+		}
+		return 0;
+	case 0x6e:		/* outsb */
+	case 0x6f:		/* outsw/outsd */
+		if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
+				0,
+				(c->d & ByteOp) ? 1 : c->op_bytes,
+				c->rep_prefix ?
+				address_mask(c, c->regs[VCPU_REGS_RCX]) : 1,
+				(ctxt->eflags & EFLG_DF),
+					 register_address(c,
+					  seg_override_base(ctxt, c),
+						 c->regs[VCPU_REGS_RSI]),
+				c->rep_prefix,
+				c->regs[VCPU_REGS_RDX]) == 0) {
+			c->eip = saved_eip;
+			return -1;
+		}
+		return 0;
+	case 0x70 ... 0x7f: /* jcc (short) */
+		if (test_cc(c->b, ctxt->eflags))
+			jmp_rel(c, c->src.val);
+		break;
+	case 0x80 ... 0x83:	/* Grp1 */
+		switch (c->modrm_reg) {
+		case 0:
+			goto add;
+		case 1:
+			goto or;
+		case 2:
+			goto adc;
+		case 3:
+			goto sbb;
+		case 4:
+			goto and;
+		case 5:
+			goto sub;
+		case 6:
+			goto xor;
+		case 7:
+			goto cmp;
+		}
+		break;
+	case 0x84 ... 0x85:
+		emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0x86 ... 0x87:	/* xchg */
+	xchg:
+		/* Write back the register source. */
+		switch (c->dst.bytes) {
+		case 1:
+			*(u8 *) c->src.ptr = (u8) c->dst.val;
+			break;
+		case 2:
+			*(u16 *) c->src.ptr = (u16) c->dst.val;
+			break;
+		case 4:
+			*c->src.ptr = (u32) c->dst.val;
+			break;	/* 64b reg: zero-extend */
+		case 8:
+			*c->src.ptr = c->dst.val;
+			break;
+		}
+		/*
+		 * Write back the memory destination with implicit LOCK
+		 * prefix.
+		 */
+		c->dst.val = c->src.val;
+		c->lock_prefix = 1;
+		break;
+	case 0x88 ... 0x8b:	/* mov */
+		goto mov;
+	case 0x8c: { /* mov r/m, sreg */
+		struct kvm_segment segreg;
+
+		if (c->modrm_reg <= 5)
+			kvm_get_segment(ctxt->vcpu, &segreg, c->modrm_reg);
+		else {
+			printk(KERN_INFO "0x8c: Invalid segreg in modrm byte 0x%02x\n",
+			       c->modrm);
+			goto cannot_emulate;
+		}
+		c->dst.val = segreg.selector;
+		break;
+	}
+	case 0x8d: /* lea r16/r32, m */
+		c->dst.val = c->modrm_ea;
+		break;
+	case 0x8e: { /* mov seg, r/m16 */
+		uint16_t sel;
+		int type_bits;
+		int err;
+
+		sel = c->src.val;
+		if (c->modrm_reg == VCPU_SREG_SS)
+			toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
+
+		if (c->modrm_reg <= 5) {
+			type_bits = (c->modrm_reg == 1) ? 9 : 1;
+			err = kvm_load_segment_descriptor(ctxt->vcpu, sel,
+							  type_bits, c->modrm_reg);
+		} else {
+			printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n",
+					c->modrm);
+			goto cannot_emulate;
+		}
+
+		if (err < 0)
+			goto cannot_emulate;
+
+		c->dst.type = OP_NONE;  /* Disable writeback. */
+		break;
+	}
+	case 0x8f:		/* pop (sole member of Grp1a) */
+		rc = emulate_grp1a(ctxt, ops);
+		if (rc != 0)
+			goto done;
+		break;
+	case 0x90: /* nop / xchg r8,rax */
+		if (!(c->rex_prefix & 1)) { /* nop */
+			c->dst.type = OP_NONE;
+			break;
+		}
+	case 0x91 ... 0x97: /* xchg reg,rax */
+		c->src.type = c->dst.type = OP_REG;
+		c->src.bytes = c->dst.bytes = c->op_bytes;
+		c->src.ptr = (unsigned long *) &c->regs[VCPU_REGS_RAX];
+		c->src.val = *(c->src.ptr);
+		goto xchg;
+	case 0x9c: /* pushf */
+		c->src.val =  (unsigned long) ctxt->eflags;
+		emulate_push(ctxt);
+		break;
+	case 0x9d: /* popf */
+		c->dst.type = OP_REG;
+		c->dst.ptr = (unsigned long *) &ctxt->eflags;
+		c->dst.bytes = c->op_bytes;
+		goto pop_instruction;
+	case 0xa0 ... 0xa1:	/* mov */
+		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
+		c->dst.val = c->src.val;
+		break;
+	case 0xa2 ... 0xa3:	/* mov */
+		c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX];
+		break;
+	case 0xa4 ... 0xa5:	/* movs */
+		c->dst.type = OP_MEM;
+		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.ptr = (unsigned long *)register_address(c,
+						   es_base(ctxt),
+						   c->regs[VCPU_REGS_RDI]);
+		if ((rc = ops->read_emulated(register_address(c,
+					   seg_override_base(ctxt, c),
+					c->regs[VCPU_REGS_RSI]),
+					&c->dst.val,
+					c->dst.bytes, ctxt->vcpu)) != 0)
+			goto done;
+		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
+							   : c->dst.bytes);
+		register_address_increment(c, &c->regs[VCPU_REGS_RDI],
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
+							   : c->dst.bytes);
+		break;
+	case 0xa6 ... 0xa7:	/* cmps */
+		c->src.type = OP_NONE; /* Disable writeback. */
+		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->src.ptr = (unsigned long *)register_address(c,
+				       seg_override_base(ctxt, c),
+						   c->regs[VCPU_REGS_RSI]);
+		if ((rc = ops->read_emulated((unsigned long)c->src.ptr,
+						&c->src.val,
+						c->src.bytes,
+						ctxt->vcpu)) != 0)
+			goto done;
+
+		c->dst.type = OP_NONE; /* Disable writeback. */
+		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.ptr = (unsigned long *)register_address(c,
+						   es_base(ctxt),
+						   c->regs[VCPU_REGS_RDI]);
+		if ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
+						&c->dst.val,
+						c->dst.bytes,
+						ctxt->vcpu)) != 0)
+			goto done;
+
+		DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr);
+
+		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
+
+		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
+				       (ctxt->eflags & EFLG_DF) ? -c->src.bytes
+								  : c->src.bytes);
+		register_address_increment(c, &c->regs[VCPU_REGS_RDI],
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
+								  : c->dst.bytes);
+
+		break;
+	case 0xaa ... 0xab:	/* stos */
+		c->dst.type = OP_MEM;
+		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.ptr = (unsigned long *)register_address(c,
+						   es_base(ctxt),
+						   c->regs[VCPU_REGS_RDI]);
+		c->dst.val = c->regs[VCPU_REGS_RAX];
+		register_address_increment(c, &c->regs[VCPU_REGS_RDI],
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
+							   : c->dst.bytes);
+		break;
+	case 0xac ... 0xad:	/* lods */
+		c->dst.type = OP_REG;
+		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
+		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
+		if ((rc = ops->read_emulated(register_address(c,
+						 seg_override_base(ctxt, c),
+						 c->regs[VCPU_REGS_RSI]),
+						 &c->dst.val,
+						 c->dst.bytes,
+						 ctxt->vcpu)) != 0)
+			goto done;
+		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
+				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
+							   : c->dst.bytes);
+		break;
+	case 0xae ... 0xaf:	/* scas */
+		DPRINTF("Urk! I don't handle SCAS.\n");
+		goto cannot_emulate;
+	case 0xb0 ... 0xbf: /* mov r, imm */
+		goto mov;
+	case 0xc0 ... 0xc1:
+		emulate_grp2(ctxt);
+		break;
+	case 0xc3: /* ret */
+		c->dst.type = OP_REG;
+		c->dst.ptr = &c->eip;
+		c->dst.bytes = c->op_bytes;
+		goto pop_instruction;
+	case 0xc6 ... 0xc7:	/* mov (sole member of Grp11) */
+	mov:
+		c->dst.val = c->src.val;
+		break;
+	case 0xcb:		/* ret far */
+		rc = emulate_ret_far(ctxt, ops);
+		if (rc)
+			goto done;
+		break;
+	case 0xd0 ... 0xd1:	/* Grp2 */
+		c->src.val = 1;
+		emulate_grp2(ctxt);
+		break;
+	case 0xd2 ... 0xd3:	/* Grp2 */
+		c->src.val = c->regs[VCPU_REGS_RCX];
+		emulate_grp2(ctxt);
+		break;
+	case 0xe4: 	/* inb */
+	case 0xe5: 	/* in */
+		port = c->src.val;
+		io_dir_in = 1;
+		goto do_io;
+	case 0xe6: /* outb */
+	case 0xe7: /* out */
+		port = c->src.val;
+		io_dir_in = 0;
+		goto do_io;
+	case 0xe8: /* call (near) */ {
+		long int rel = c->src.val;
+		c->src.val = (unsigned long) c->eip;
+		jmp_rel(c, rel);
+		emulate_push(ctxt);
+		break;
+	}
+	case 0xe9: /* jmp rel */
+		goto jmp;
+	case 0xea: /* jmp far */
+		if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9,
+					VCPU_SREG_CS) < 0) {
+			DPRINTF("jmp far: Failed to load CS descriptor\n");
+			goto cannot_emulate;
+		}
+
+		c->eip = c->src.val;
+		break;
+	case 0xeb:
+	      jmp:		/* jmp rel short */
+		jmp_rel(c, c->src.val);
+		c->dst.type = OP_NONE; /* Disable writeback. */
+		break;
+	case 0xec: /* in al,dx */
+	case 0xed: /* in (e/r)ax,dx */
+		port = c->regs[VCPU_REGS_RDX];
+		io_dir_in = 1;
+		goto do_io;
+	case 0xee: /* out al,dx */
+	case 0xef: /* out (e/r)ax,dx */
+		port = c->regs[VCPU_REGS_RDX];
+		io_dir_in = 0;
+	do_io:	if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in,
+				   (c->d & ByteOp) ? 1 : c->op_bytes,
+				   port) != 0) {
+			c->eip = saved_eip;
+			goto cannot_emulate;
+		}
+		break;
+	case 0xf4:              /* hlt */
+		ctxt->vcpu->arch.halt_request = 1;
+		break;
+	case 0xf5:	/* cmc */
+		/* complement carry flag from eflags reg */
+		ctxt->eflags ^= EFLG_CF;
+		c->dst.type = OP_NONE;	/* Disable writeback. */
+		break;
+	case 0xf6 ... 0xf7:	/* Grp3 */
+		rc = emulate_grp3(ctxt, ops);
+		if (rc != 0)
+			goto done;
+		break;
+	case 0xf8: /* clc */
+		ctxt->eflags &= ~EFLG_CF;
+		c->dst.type = OP_NONE;	/* Disable writeback. */
+		break;
+	case 0xfa: /* cli */
+		ctxt->eflags &= ~X86_EFLAGS_IF;
+		c->dst.type = OP_NONE;	/* Disable writeback. */
+		break;
+	case 0xfb: /* sti */
+		toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
+		ctxt->eflags |= X86_EFLAGS_IF;
+		c->dst.type = OP_NONE;	/* Disable writeback. */
+		break;
+	case 0xfc: /* cld */
+		ctxt->eflags &= ~EFLG_DF;
+		c->dst.type = OP_NONE;	/* Disable writeback. */
+		break;
+	case 0xfd: /* std */
+		ctxt->eflags |= EFLG_DF;
+		c->dst.type = OP_NONE;	/* Disable writeback. */
+		break;
+	case 0xfe ... 0xff:	/* Grp4/Grp5 */
+		rc = emulate_grp45(ctxt, ops);
+		if (rc != 0)
+			goto done;
+		break;
+	}
+
+writeback:
+	rc = writeback(ctxt, ops);
+	if (rc != 0)
+		goto done;
+
+	/* Commit shadow register state. */
+	memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);
+	kvm_rip_write(ctxt->vcpu, c->eip);
+
+done:
+	if (rc == X86EMUL_UNHANDLEABLE) {
+		c->eip = saved_eip;
+		return -1;
+	}
+	return 0;
+
+twobyte_insn:
+	switch (c->b) {
+	case 0x01: /* lgdt, lidt, lmsw */
+		switch (c->modrm_reg) {
+			u16 size;
+			unsigned long address;
+
+		case 0: /* vmcall */
+			if (c->modrm_mod != 3 || c->modrm_rm != 1)
+				goto cannot_emulate;
+
+			rc = kvm_fix_hypercall(ctxt->vcpu);
+			if (rc)
+				goto done;
+
+			/* Let the processor re-execute the fixed hypercall */
+			c->eip = kvm_rip_read(ctxt->vcpu);
+			/* Disable writeback. */
+			c->dst.type = OP_NONE;
+			break;
+		case 2: /* lgdt */
+			rc = read_descriptor(ctxt, ops, c->src.ptr,
+					     &size, &address, c->op_bytes);
+			if (rc)
+				goto done;
+			realmode_lgdt(ctxt->vcpu, size, address);
+			/* Disable writeback. */
+			c->dst.type = OP_NONE;
+			break;
+		case 3: /* lidt/vmmcall */
+			if (c->modrm_mod == 3) {
+				switch (c->modrm_rm) {
+				case 1:
+					rc = kvm_fix_hypercall(ctxt->vcpu);
+					if (rc)
+						goto done;
+					break;
+				default:
+					goto cannot_emulate;
+				}
+			} else {
+				rc = read_descriptor(ctxt, ops, c->src.ptr,
+						     &size, &address,
+						     c->op_bytes);
+				if (rc)
+					goto done;
+				realmode_lidt(ctxt->vcpu, size, address);
+			}
+			/* Disable writeback. */
+			c->dst.type = OP_NONE;
+			break;
+		case 4: /* smsw */
+			c->dst.bytes = 2;
+			c->dst.val = realmode_get_cr(ctxt->vcpu, 0);
+			break;
+		case 6: /* lmsw */
+			realmode_lmsw(ctxt->vcpu, (u16)c->src.val,
+				      &ctxt->eflags);
+			c->dst.type = OP_NONE;
+			break;
+		case 7: /* invlpg*/
+			emulate_invlpg(ctxt->vcpu, memop);
+			/* Disable writeback. */
+			c->dst.type = OP_NONE;
+			break;
+		default:
+			goto cannot_emulate;
+		}
+		break;
+	case 0x05: 		/* syscall */
+		if (emulate_syscall(ctxt) == -1)
+			goto cannot_emulate;
+		else
+			goto writeback;
+		break;
+	case 0x06:
+		emulate_clts(ctxt->vcpu);
+		c->dst.type = OP_NONE;
+		break;
+	case 0x08:		/* invd */
+	case 0x09:		/* wbinvd */
+	case 0x0d:		/* GrpP (prefetch) */
+	case 0x18:		/* Grp16 (prefetch/nop) */
+		c->dst.type = OP_NONE;
+		break;
+	case 0x20: /* mov cr, reg */
+		if (c->modrm_mod != 3)
+			goto cannot_emulate;
+		c->regs[c->modrm_rm] =
+				realmode_get_cr(ctxt->vcpu, c->modrm_reg);
+		c->dst.type = OP_NONE;	/* no writeback */
+		break;
+	case 0x21: /* mov from dr to reg */
+		if (c->modrm_mod != 3)
+			goto cannot_emulate;
+		rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
+		if (rc)
+			goto cannot_emulate;
+		c->dst.type = OP_NONE;	/* no writeback */
+		break;
+	case 0x22: /* mov reg, cr */
+		if (c->modrm_mod != 3)
+			goto cannot_emulate;
+		realmode_set_cr(ctxt->vcpu,
+				c->modrm_reg, c->modrm_val, &ctxt->eflags);
+		c->dst.type = OP_NONE;
+		break;
+	case 0x23: /* mov from reg to dr */
+		if (c->modrm_mod != 3)
+			goto cannot_emulate;
+		rc = emulator_set_dr(ctxt, c->modrm_reg,
+				     c->regs[c->modrm_rm]);
+		if (rc)
+			goto cannot_emulate;
+		c->dst.type = OP_NONE;	/* no writeback */
+		break;
+	case 0x30:
+		/* wrmsr */
+		msr_data = (u32)c->regs[VCPU_REGS_RAX]
+			| ((u64)c->regs[VCPU_REGS_RDX] << 32);
+		rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data);
+		if (rc) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			c->eip = kvm_rip_read(ctxt->vcpu);
+		}
+		rc = X86EMUL_CONTINUE;
+		c->dst.type = OP_NONE;
+		break;
+	case 0x32:
+		/* rdmsr */
+		rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
+		if (rc) {
+			kvm_inject_gp(ctxt->vcpu, 0);
+			c->eip = kvm_rip_read(ctxt->vcpu);
+		} else {
+			c->regs[VCPU_REGS_RAX] = (u32)msr_data;
+			c->regs[VCPU_REGS_RDX] = msr_data >> 32;
+		}
+		rc = X86EMUL_CONTINUE;
+		c->dst.type = OP_NONE;
+		break;
+	case 0x34:		/* sysenter */
+		if (emulate_sysenter(ctxt) == -1)
+			goto cannot_emulate;
+		else
+			goto writeback;
+		break;
+	case 0x35:		/* sysexit */
+		if (emulate_sysexit(ctxt) == -1)
+			goto cannot_emulate;
+		else
+			goto writeback;
+		break;
+	case 0x40 ... 0x4f:	/* cmov */
+		c->dst.val = c->dst.orig_val = c->src.val;
+		if (!test_cc(c->b, ctxt->eflags))
+			c->dst.type = OP_NONE; /* no writeback */
+		break;
+	case 0x80 ... 0x8f: /* jnz rel, etc*/
+		if (test_cc(c->b, ctxt->eflags))
+			jmp_rel(c, c->src.val);
+		c->dst.type = OP_NONE;
+		break;
+	case 0xa3:
+	      bt:		/* bt */
+		c->dst.type = OP_NONE;
+		/* only subword offset */
+		c->src.val &= (c->dst.bytes << 3) - 1;
+		emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0xa4: /* shld imm8, r, r/m */
+	case 0xa5: /* shld cl, r, r/m */
+		emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags);
+		break;
+	case 0xab:
+	      bts:		/* bts */
+		/* only subword offset */
+		c->src.val &= (c->dst.bytes << 3) - 1;
+		emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0xac: /* shrd imm8, r, r/m */
+	case 0xad: /* shrd cl, r, r/m */
+		emulate_2op_cl("shrd", c->src2, c->src, c->dst, ctxt->eflags);
+		break;
+	case 0xae:              /* clflush */
+		break;
+	case 0xb0 ... 0xb1:	/* cmpxchg */
+		/*
+		 * Save real source value, then compare EAX against
+		 * destination.
+		 */
+		c->src.orig_val = c->src.val;
+		c->src.val = c->regs[VCPU_REGS_RAX];
+		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
+		if (ctxt->eflags & EFLG_ZF) {
+			/* Success: write back to memory. */
+			c->dst.val = c->src.orig_val;
+		} else {
+			/* Failure: write the value we saw to EAX. */
+			c->dst.type = OP_REG;
+			c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
+		}
+		break;
+	case 0xb3:
+	      btr:		/* btr */
+		/* only subword offset */
+		c->src.val &= (c->dst.bytes << 3) - 1;
+		emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0xb6 ... 0xb7:	/* movzx */
+		c->dst.bytes = c->op_bytes;
+		c->dst.val = (c->d & ByteOp) ? (u8) c->src.val
+						       : (u16) c->src.val;
+		break;
+	case 0xba:		/* Grp8 */
+		switch (c->modrm_reg & 3) {
+		case 0:
+			goto bt;
+		case 1:
+			goto bts;
+		case 2:
+			goto btr;
+		case 3:
+			goto btc;
+		}
+		break;
+	case 0xbb:
+	      btc:		/* btc */
+		/* only subword offset */
+		c->src.val &= (c->dst.bytes << 3) - 1;
+		emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
+		break;
+	case 0xbe ... 0xbf:	/* movsx */
+		c->dst.bytes = c->op_bytes;
+		c->dst.val = (c->d & ByteOp) ? (s8) c->src.val :
+							(s16) c->src.val;
+		break;
+	case 0xc3:		/* movnti */
+		c->dst.bytes = c->op_bytes;
+		c->dst.val = (c->op_bytes == 4) ? (u32) c->src.val :
+							(u64) c->src.val;
+		break;
+	case 0xc7:		/* Grp9 (cmpxchg8b) */
+		rc = emulate_grp9(ctxt, ops, memop);
+		if (rc != 0)
+			goto done;
+		c->dst.type = OP_NONE;
+		break;
+	}
+	goto writeback;
+
+cannot_emulate:
+	DPRINTF("Cannot emulate %02x\n", c->b);
+	c->eip = saved_eip;
+	return -1;
+}
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 21f68e0..82ad523 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -231,7 +231,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pit *pit = vcpu->kvm->arch.vpit;
 
-	if (pit && vcpu->vcpu_id == 0 && pit->pit_state.irq_ack)
+	if (pit && kvm_vcpu_is_bsp(vcpu) && pit->pit_state.irq_ack)
 		return atomic_read(&pit->pit_state.pit_timer.pending);
 	return 0;
 }
@@ -252,7 +252,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
 	struct kvm_pit *pit = vcpu->kvm->arch.vpit;
 	struct hrtimer *timer;
 
-	if (vcpu->vcpu_id != 0 || !pit)
+	if (!kvm_vcpu_is_bsp(vcpu) || !pit)
 		return;
 
 	timer = &pit->pit_state.pit_timer.timer;
@@ -294,7 +294,7 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
 	pt->timer.function = kvm_timer_fn;
 	pt->t_ops = &kpit_ops;
 	pt->kvm = ps->pit->kvm;
-	pt->vcpu_id = 0;
+	pt->vcpu = pt->kvm->bsp_vcpu;
 
 	atomic_set(&pt->pending, 0);
 	ps->irq_ack = 1;
@@ -332,33 +332,62 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
 	case 1:
         /* FIXME: enhance mode 4 precision */
 	case 4:
-		create_pit_timer(ps, val, 0);
+		if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)) {
+			create_pit_timer(ps, val, 0);
+		}
 		break;
 	case 2:
 	case 3:
-		create_pit_timer(ps, val, 1);
+		if (!(ps->flags & KVM_PIT_FLAGS_HPET_LEGACY)){
+			create_pit_timer(ps, val, 1);
+		}
 		break;
 	default:
 		destroy_pit_timer(&ps->pit_timer);
 	}
 }
 
-void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val)
+void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start)
+{
+	u8 saved_mode;
+	if (hpet_legacy_start) {
+		/* save existing mode for later reenablement */
+		saved_mode = kvm->arch.vpit->pit_state.channels[0].mode;
+		kvm->arch.vpit->pit_state.channels[0].mode = 0xff; /* disable timer */
+		pit_load_count(kvm, channel, val);
+		kvm->arch.vpit->pit_state.channels[0].mode = saved_mode;
+	} else {
+		pit_load_count(kvm, channel, val);
+	}
+}
+
+static inline struct kvm_pit *dev_to_pit(struct kvm_io_device *dev)
+{
+	return container_of(dev, struct kvm_pit, dev);
+}
+
+static inline struct kvm_pit *speaker_to_pit(struct kvm_io_device *dev)
 {
-	mutex_lock(&kvm->arch.vpit->pit_state.lock);
-	pit_load_count(kvm, channel, val);
-	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
+	return container_of(dev, struct kvm_pit, speaker_dev);
 }
 
-static void pit_ioport_write(struct kvm_io_device *this,
-			     gpa_t addr, int len, const void *data)
+static inline int pit_in_range(gpa_t addr)
 {
-	struct kvm_pit *pit = (struct kvm_pit *)this->private;
+	return ((addr >= KVM_PIT_BASE_ADDRESS) &&
+		(addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
+}
+
+static int pit_ioport_write(struct kvm_io_device *this,
+			    gpa_t addr, int len, const void *data)
+{
+	struct kvm_pit *pit = dev_to_pit(this);
 	struct kvm_kpit_state *pit_state = &pit->pit_state;
 	struct kvm *kvm = pit->kvm;
 	int channel, access;
 	struct kvm_kpit_channel_state *s;
 	u32 val = *(u32 *) data;
+	if (!pit_in_range(addr))
+		return -EOPNOTSUPP;
 
 	val  &= 0xff;
 	addr &= KVM_PIT_CHANNEL_MASK;
@@ -421,16 +450,19 @@ static void pit_ioport_write(struct kvm_io_device *this,
 	}
 
 	mutex_unlock(&pit_state->lock);
+	return 0;
 }
 
-static void pit_ioport_read(struct kvm_io_device *this,
-			    gpa_t addr, int len, void *data)
+static int pit_ioport_read(struct kvm_io_device *this,
+			   gpa_t addr, int len, void *data)
 {
-	struct kvm_pit *pit = (struct kvm_pit *)this->private;
+	struct kvm_pit *pit = dev_to_pit(this);
 	struct kvm_kpit_state *pit_state = &pit->pit_state;
 	struct kvm *kvm = pit->kvm;
 	int ret, count;
 	struct kvm_kpit_channel_state *s;
+	if (!pit_in_range(addr))
+		return -EOPNOTSUPP;
 
 	addr &= KVM_PIT_CHANNEL_MASK;
 	s = &pit_state->channels[addr];
@@ -485,37 +517,36 @@ static void pit_ioport_read(struct kvm_io_device *this,
 	memcpy(data, (char *)&ret, len);
 
 	mutex_unlock(&pit_state->lock);
+	return 0;
 }
 
-static int pit_in_range(struct kvm_io_device *this, gpa_t addr,
-			int len, int is_write)
-{
-	return ((addr >= KVM_PIT_BASE_ADDRESS) &&
-		(addr < KVM_PIT_BASE_ADDRESS + KVM_PIT_MEM_LENGTH));
-}
-
-static void speaker_ioport_write(struct kvm_io_device *this,
-				 gpa_t addr, int len, const void *data)
+static int speaker_ioport_write(struct kvm_io_device *this,
+				gpa_t addr, int len, const void *data)
 {
-	struct kvm_pit *pit = (struct kvm_pit *)this->private;
+	struct kvm_pit *pit = speaker_to_pit(this);
 	struct kvm_kpit_state *pit_state = &pit->pit_state;
 	struct kvm *kvm = pit->kvm;
 	u32 val = *(u32 *) data;
+	if (addr != KVM_SPEAKER_BASE_ADDRESS)
+		return -EOPNOTSUPP;
 
 	mutex_lock(&pit_state->lock);
 	pit_state->speaker_data_on = (val >> 1) & 1;
 	pit_set_gate(kvm, 2, val & 1);
 	mutex_unlock(&pit_state->lock);
+	return 0;
 }
 
-static void speaker_ioport_read(struct kvm_io_device *this,
-				gpa_t addr, int len, void *data)
+static int speaker_ioport_read(struct kvm_io_device *this,
+			       gpa_t addr, int len, void *data)
 {
-	struct kvm_pit *pit = (struct kvm_pit *)this->private;
+	struct kvm_pit *pit = speaker_to_pit(this);
 	struct kvm_kpit_state *pit_state = &pit->pit_state;
 	struct kvm *kvm = pit->kvm;
 	unsigned int refresh_clock;
 	int ret;
+	if (addr != KVM_SPEAKER_BASE_ADDRESS)
+		return -EOPNOTSUPP;
 
 	/* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
 	refresh_clock = ((unsigned int)ktime_to_ns(ktime_get()) >> 14) & 1;
@@ -527,12 +558,7 @@ static void speaker_ioport_read(struct kvm_io_device *this,
 		len = sizeof(ret);
 	memcpy(data, (char *)&ret, len);
 	mutex_unlock(&pit_state->lock);
-}
-
-static int speaker_in_range(struct kvm_io_device *this, gpa_t addr,
-			    int len, int is_write)
-{
-	return (addr == KVM_SPEAKER_BASE_ADDRESS);
+	return 0;
 }
 
 void kvm_pit_reset(struct kvm_pit *pit)
@@ -541,6 +567,7 @@ void kvm_pit_reset(struct kvm_pit *pit)
 	struct kvm_kpit_channel_state *c;
 
 	mutex_lock(&pit->pit_state.lock);
+	pit->pit_state.flags = 0;
 	for (i = 0; i < 3; i++) {
 		c = &pit->pit_state.channels[i];
 		c->mode = 0xff;
@@ -563,10 +590,22 @@ static void pit_mask_notifer(struct kvm_irq_mask_notifier *kimn, bool mask)
 	}
 }
 
-struct kvm_pit *kvm_create_pit(struct kvm *kvm)
+static const struct kvm_io_device_ops pit_dev_ops = {
+	.read     = pit_ioport_read,
+	.write    = pit_ioport_write,
+};
+
+static const struct kvm_io_device_ops speaker_dev_ops = {
+	.read     = speaker_ioport_read,
+	.write    = speaker_ioport_write,
+};
+
+/* Caller must have writers lock on slots_lock */
+struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
 {
 	struct kvm_pit *pit;
 	struct kvm_kpit_state *pit_state;
+	int ret;
 
 	pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL);
 	if (!pit)
@@ -582,19 +621,6 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
 	mutex_lock(&pit->pit_state.lock);
 	spin_lock_init(&pit->pit_state.inject_lock);
 
-	/* Initialize PIO device */
-	pit->dev.read = pit_ioport_read;
-	pit->dev.write = pit_ioport_write;
-	pit->dev.in_range = pit_in_range;
-	pit->dev.private = pit;
-	kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
-
-	pit->speaker_dev.read = speaker_ioport_read;
-	pit->speaker_dev.write = speaker_ioport_write;
-	pit->speaker_dev.in_range = speaker_in_range;
-	pit->speaker_dev.private = pit;
-	kvm_io_bus_register_dev(&kvm->pio_bus, &pit->speaker_dev);
-
 	kvm->arch.vpit = pit;
 	pit->kvm = kvm;
 
@@ -613,7 +639,30 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
 	pit->mask_notifier.func = pit_mask_notifer;
 	kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
 
+	kvm_iodevice_init(&pit->dev, &pit_dev_ops);
+	ret = __kvm_io_bus_register_dev(&kvm->pio_bus, &pit->dev);
+	if (ret < 0)
+		goto fail;
+
+	if (flags & KVM_PIT_SPEAKER_DUMMY) {
+		kvm_iodevice_init(&pit->speaker_dev, &speaker_dev_ops);
+		ret = __kvm_io_bus_register_dev(&kvm->pio_bus,
+						&pit->speaker_dev);
+		if (ret < 0)
+			goto fail_unregister;
+	}
+
 	return pit;
+
+fail_unregister:
+	__kvm_io_bus_unregister_dev(&kvm->pio_bus, &pit->dev);
+
+fail:
+	if (pit->irq_source_id >= 0)
+		kvm_free_irq_source_id(kvm, pit->irq_source_id);
+
+	kfree(pit);
+	return NULL;
 }
 
 void kvm_free_pit(struct kvm *kvm)
@@ -623,6 +672,8 @@ void kvm_free_pit(struct kvm *kvm)
 	if (kvm->arch.vpit) {
 		kvm_unregister_irq_mask_notifier(kvm, 0,
 					       &kvm->arch.vpit->mask_notifier);
+		kvm_unregister_irq_ack_notifier(kvm,
+				&kvm->arch.vpit->pit_state.irq_ack_notifier);
 		mutex_lock(&kvm->arch.vpit->pit_state.lock);
 		timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
 		hrtimer_cancel(timer);
@@ -637,10 +688,10 @@ static void __inject_pit_timer_intr(struct kvm *kvm)
 	struct kvm_vcpu *vcpu;
 	int i;
 
-	mutex_lock(&kvm->lock);
+	mutex_lock(&kvm->irq_lock);
 	kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1);
 	kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0);
-	mutex_unlock(&kvm->lock);
+	mutex_unlock(&kvm->irq_lock);
 
 	/*
 	 * Provides NMI watchdog support via Virtual Wire mode.
@@ -652,11 +703,8 @@ static void __inject_pit_timer_intr(struct kvm *kvm)
 	 * VCPU0, and only if its LVT0 is in EXTINT mode.
 	 */
 	if (kvm->arch.vapics_in_nmi_mode > 0)
-		for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-			vcpu = kvm->vcpus[i];
-			if (vcpu)
-				kvm_apic_nmi_wd_deliver(vcpu);
-		}
+		kvm_for_each_vcpu(i, vcpu, kvm)
+			kvm_apic_nmi_wd_deliver(vcpu);
 }
 
 void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
@@ -665,7 +713,7 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_kpit_state *ps;
 
-	if (vcpu && pit) {
+	if (pit) {
 		int inject = 0;
 		ps = &pit->pit_state;
 
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index bbd863f..d4c1c7f 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -21,6 +21,7 @@ struct kvm_kpit_channel_state {
 
 struct kvm_kpit_state {
 	struct kvm_kpit_channel_state channels[3];
+	u32 flags;
 	struct kvm_timer pit_timer;
 	bool is_periodic;
 	u32    speaker_data_on;
@@ -49,8 +50,8 @@ struct kvm_pit {
 #define KVM_PIT_CHANNEL_MASK	    0x3
 
 void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu);
-void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val);
-struct kvm_pit *kvm_create_pit(struct kvm *kvm);
+void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start);
+struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags);
 void kvm_free_pit(struct kvm *kvm);
 void kvm_pit_reset(struct kvm_pit *pit);
 
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index 1ccb50c..01f1516 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -30,50 +30,24 @@
 #include "irq.h"
 
 #include <linux/kvm_host.h>
-
-static void pic_lock(struct kvm_pic *s)
-	__acquires(&s->lock)
-{
-	spin_lock(&s->lock);
-}
-
-static void pic_unlock(struct kvm_pic *s)
-	__releases(&s->lock)
-{
-	struct kvm *kvm = s->kvm;
-	unsigned acks = s->pending_acks;
-	bool wakeup = s->wakeup_needed;
-	struct kvm_vcpu *vcpu;
-
-	s->pending_acks = 0;
-	s->wakeup_needed = false;
-
-	spin_unlock(&s->lock);
-
-	while (acks) {
-		kvm_notify_acked_irq(kvm, SELECT_PIC(__ffs(acks)),
-				     __ffs(acks));
-		acks &= acks - 1;
-	}
-
-	if (wakeup) {
-		vcpu = s->kvm->vcpus[0];
-		if (vcpu)
-			kvm_vcpu_kick(vcpu);
-	}
-}
+#include "trace.h"
 
 static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
 {
 	s->isr &= ~(1 << irq);
 	s->isr_ack |= (1 << irq);
+	if (s != &s->pics_state->pics[0])
+		irq += 8;
+	kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq);
 }
 
 void kvm_pic_clear_isr_ack(struct kvm *kvm)
 {
 	struct kvm_pic *s = pic_irqchip(kvm);
+	spin_lock(&s->lock);
 	s->pics[0].isr_ack = 0xff;
 	s->pics[1].isr_ack = 0xff;
+	spin_unlock(&s->lock);
 }
 
 /*
@@ -174,9 +148,9 @@ static void pic_update_irq(struct kvm_pic *s)
 
 void kvm_pic_update_irq(struct kvm_pic *s)
 {
-	pic_lock(s);
+	spin_lock(&s->lock);
 	pic_update_irq(s);
-	pic_unlock(s);
+	spin_unlock(&s->lock);
 }
 
 int kvm_pic_set_irq(void *opaque, int irq, int level)
@@ -184,12 +158,14 @@ int kvm_pic_set_irq(void *opaque, int irq, int level)
 	struct kvm_pic *s = opaque;
 	int ret = -1;
 
-	pic_lock(s);
+	spin_lock(&s->lock);
 	if (irq >= 0 && irq < PIC_NUM_PINS) {
 		ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
 		pic_update_irq(s);
+		trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr,
+				      s->pics[irq >> 3].imr, ret == 0);
 	}
-	pic_unlock(s);
+	spin_unlock(&s->lock);
 
 	return ret;
 }
@@ -217,7 +193,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
 	int irq, irq2, intno;
 	struct kvm_pic *s = pic_irqchip(kvm);
 
-	pic_lock(s);
+	spin_lock(&s->lock);
 	irq = pic_get_irq(&s->pics[0]);
 	if (irq >= 0) {
 		pic_intack(&s->pics[0], irq);
@@ -242,8 +218,7 @@ int kvm_pic_read_irq(struct kvm *kvm)
 		intno = s->pics[0].irq_base + irq;
 	}
 	pic_update_irq(s);
-	pic_unlock(s);
-	kvm_notify_acked_irq(kvm, SELECT_PIC(irq), irq);
+	spin_unlock(&s->lock);
 
 	return intno;
 }
@@ -252,7 +227,7 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
 {
 	int irq, irqbase, n;
 	struct kvm *kvm = s->pics_state->irq_request_opaque;
-	struct kvm_vcpu *vcpu0 = kvm->vcpus[0];
+	struct kvm_vcpu *vcpu0 = kvm->bsp_vcpu;
 
 	if (s == &s->pics_state->pics[0])
 		irqbase = 0;
@@ -263,7 +238,7 @@ void kvm_pic_reset(struct kvm_kpic_state *s)
 		if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0))
 			if (s->irr & (1 << irq) || s->isr & (1 << irq)) {
 				n = irq + irqbase;
-				s->pics_state->pending_acks |= 1 << n;
+				kvm_notify_acked_irq(kvm, SELECT_PIC(n), n);
 			}
 	}
 	s->last_irr = 0;
@@ -428,8 +403,7 @@ static u32 elcr_ioport_read(void *opaque, u32 addr1)
 	return s->elcr;
 }
 
-static int picdev_in_range(struct kvm_io_device *this, gpa_t addr,
-			   int len, int is_write)
+static int picdev_in_range(gpa_t addr)
 {
 	switch (addr) {
 	case 0x20:
@@ -444,18 +418,25 @@ static int picdev_in_range(struct kvm_io_device *this, gpa_t addr,
 	}
 }
 
-static void picdev_write(struct kvm_io_device *this,
+static inline struct kvm_pic *to_pic(struct kvm_io_device *dev)
+{
+	return container_of(dev, struct kvm_pic, dev);
+}
+
+static int picdev_write(struct kvm_io_device *this,
 			 gpa_t addr, int len, const void *val)
 {
-	struct kvm_pic *s = this->private;
+	struct kvm_pic *s = to_pic(this);
 	unsigned char data = *(unsigned char *)val;
+	if (!picdev_in_range(addr))
+		return -EOPNOTSUPP;
 
 	if (len != 1) {
 		if (printk_ratelimit())
 			printk(KERN_ERR "PIC: non byte write\n");
-		return;
+		return 0;
 	}
-	pic_lock(s);
+	spin_lock(&s->lock);
 	switch (addr) {
 	case 0x20:
 	case 0x21:
@@ -468,21 +449,24 @@ static void picdev_write(struct kvm_io_device *this,
 		elcr_ioport_write(&s->pics[addr & 1], addr, data);
 		break;
 	}
-	pic_unlock(s);
+	spin_unlock(&s->lock);
+	return 0;
 }
 
-static void picdev_read(struct kvm_io_device *this,
-			gpa_t addr, int len, void *val)
+static int picdev_read(struct kvm_io_device *this,
+		       gpa_t addr, int len, void *val)
 {
-	struct kvm_pic *s = this->private;
+	struct kvm_pic *s = to_pic(this);
 	unsigned char data = 0;
+	if (!picdev_in_range(addr))
+		return -EOPNOTSUPP;
 
 	if (len != 1) {
 		if (printk_ratelimit())
 			printk(KERN_ERR "PIC: non byte read\n");
-		return;
+		return 0;
 	}
-	pic_lock(s);
+	spin_lock(&s->lock);
 	switch (addr) {
 	case 0x20:
 	case 0x21:
@@ -496,7 +480,8 @@ static void picdev_read(struct kvm_io_device *this,
 		break;
 	}
 	*(unsigned char *)val = data;
-	pic_unlock(s);
+	spin_unlock(&s->lock);
+	return 0;
 }
 
 /*
@@ -505,20 +490,27 @@ static void picdev_read(struct kvm_io_device *this,
 static void pic_irq_request(void *opaque, int level)
 {
 	struct kvm *kvm = opaque;
-	struct kvm_vcpu *vcpu = kvm->vcpus[0];
+	struct kvm_vcpu *vcpu = kvm->bsp_vcpu;
 	struct kvm_pic *s = pic_irqchip(kvm);
 	int irq = pic_get_irq(&s->pics[0]);
 
 	s->output = level;
 	if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) {
 		s->pics[0].isr_ack &= ~(1 << irq);
-		s->wakeup_needed = true;
+		kvm_vcpu_kick(vcpu);
 	}
 }
 
+static const struct kvm_io_device_ops picdev_ops = {
+	.read     = picdev_read,
+	.write    = picdev_write,
+};
+
 struct kvm_pic *kvm_create_pic(struct kvm *kvm)
 {
 	struct kvm_pic *s;
+	int ret;
+
 	s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL);
 	if (!s)
 		return NULL;
@@ -534,10 +526,12 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
 	/*
 	 * Initialize PIO device
 	 */
-	s->dev.read = picdev_read;
-	s->dev.write = picdev_write;
-	s->dev.in_range = picdev_in_range;
-	s->dev.private = s;
-	kvm_io_bus_register_dev(&kvm->pio_bus, &s->dev);
+	kvm_iodevice_init(&s->dev, &picdev_ops);
+	ret = kvm_io_bus_register_dev(kvm, &kvm->pio_bus, &s->dev);
+	if (ret < 0) {
+		kfree(s);
+		return NULL;
+	}
+
 	return s;
 }
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 9f59318..7d6058a 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -63,7 +63,6 @@ struct kvm_kpic_state {
 
 struct kvm_pic {
 	spinlock_t lock;
-	bool wakeup_needed;
 	unsigned pending_acks;
 	struct kvm *kvm;
 	struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h
index 1ff819d..7bcc5b6 100644
--- a/arch/x86/kvm/kvm_cache_regs.h
+++ b/arch/x86/kvm/kvm_cache_regs.h
@@ -29,4 +29,13 @@ static inline void kvm_rip_write(struct kvm_vcpu *vcpu, unsigned long val)
 	kvm_register_write(vcpu, VCPU_REGS_RIP, val);
 }
 
+static inline u64 kvm_pdptr_read(struct kvm_vcpu *vcpu, int index)
+{
+	if (!test_bit(VCPU_EXREG_PDPTR,
+		      (unsigned long *)&vcpu->arch.regs_avail))
+		kvm_x86_ops->cache_reg(vcpu, VCPU_EXREG_PDPTR);
+
+	return vcpu->arch.pdptrs[index];
+}
+
 #endif
diff --git a/arch/x86/kvm/kvm_svm.h b/arch/x86/kvm/kvm_svm.h
deleted file mode 100644
index ed66e4c..0000000
--- a/arch/x86/kvm/kvm_svm.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef __KVM_SVM_H
-#define __KVM_SVM_H
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/kvm_host.h>
-#include <asm/msr.h>
-
-#include <asm/svm.h>
-
-static const u32 host_save_user_msrs[] = {
-#ifdef CONFIG_X86_64
-	MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
-	MSR_FS_BASE,
-#endif
-	MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
-};
-
-#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
-
-struct kvm_vcpu;
-
-struct vcpu_svm {
-	struct kvm_vcpu vcpu;
-	struct vmcb *vmcb;
-	unsigned long vmcb_pa;
-	struct svm_cpu_data *svm_data;
-	uint64_t asid_generation;
-
-	u64 next_rip;
-
-	u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
-	u64 host_gs_base;
-	unsigned long host_cr2;
-
-	u32 *msrpm;
-	struct vmcb *hsave;
-	u64 hsave_msr;
-
-	u64 nested_vmcb;
-
-	/* These are the merged vectors */
-	u32 *nested_msrpm;
-
-	/* gpa pointers to the real vectors */
-	u64 nested_vmcb_msrpm;
-};
-
-#endif
-
diff --git a/arch/x86/kvm/kvm_timer.h b/arch/x86/kvm/kvm_timer.h
index 26bd6ba..55c7524 100644
--- a/arch/x86/kvm/kvm_timer.h
+++ b/arch/x86/kvm/kvm_timer.h
@@ -6,7 +6,7 @@ struct kvm_timer {
 	bool reinject;
 	struct kvm_timer_ops *t_ops;
 	struct kvm *kvm;
-	int vcpu_id;
+	struct kvm_vcpu *vcpu;
 };
 
 struct kvm_timer_ops {
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index ae99d83..1ae5ceb 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -32,8 +32,11 @@
 #include <asm/current.h>
 #include <asm/apicdef.h>
 #include <asm/atomic.h>
+#include <asm/apicdef.h>
 #include "kvm_cache_regs.h"
 #include "irq.h"
+#include "trace.h"
+#include "x86.h"
 
 #ifndef CONFIG_X86_64
 #define mod_64(x, y) ((x) - (y) * div64_u64(x, y))
@@ -141,6 +144,26 @@ static inline int apic_lvt_nmi_mode(u32 lvt_val)
 	return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI;
 }
 
+void kvm_apic_set_version(struct kvm_vcpu *vcpu)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+	struct kvm_cpuid_entry2 *feat;
+	u32 v = APIC_VERSION;
+
+	if (!irqchip_in_kernel(vcpu->kvm))
+		return;
+
+	feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0);
+	if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))))
+		v |= APIC_LVR_DIRECTED_EOI;
+	apic_set_reg(apic, APIC_LVR, v);
+}
+
+static inline int apic_x2apic_mode(struct kvm_lapic *apic)
+{
+	return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
+}
+
 static unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
 	LVT_MASK | APIC_LVT_TIMER_PERIODIC,	/* LVTT */
 	LVT_MASK | APIC_MODE_MASK,	/* LVTTHMR */
@@ -165,36 +188,52 @@ static int find_highest_vector(void *bitmap)
 
 static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic)
 {
+	apic->irr_pending = true;
 	return apic_test_and_set_vector(vec, apic->regs + APIC_IRR);
 }
 
-static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
+static inline int apic_search_irr(struct kvm_lapic *apic)
 {
-	apic_clear_vector(vec, apic->regs + APIC_IRR);
+	return find_highest_vector(apic->regs + APIC_IRR);
 }
 
 static inline int apic_find_highest_irr(struct kvm_lapic *apic)
 {
 	int result;
 
-	result = find_highest_vector(apic->regs + APIC_IRR);
+	if (!apic->irr_pending)
+		return -1;
+
+	result = apic_search_irr(apic);
 	ASSERT(result == -1 || result >= 16);
 
 	return result;
 }
 
+static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
+{
+	apic->irr_pending = false;
+	apic_clear_vector(vec, apic->regs + APIC_IRR);
+	if (apic_search_irr(apic) != -1)
+		apic->irr_pending = true;
+}
+
 int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
 {
 	struct kvm_lapic *apic = vcpu->arch.apic;
 	int highest_irr;
 
+	/* This may race with setting of irr in __apic_accept_irq() and
+	 * value returned may be wrong, but kvm_vcpu_kick() in __apic_accept_irq
+	 * will cause vmexit immediately and the value will be recalculated
+	 * on the next vmentry.
+	 */
 	if (!apic)
 		return 0;
 	highest_irr = apic_find_highest_irr(apic);
 
 	return highest_irr;
 }
-EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr);
 
 static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
 			     int vector, int level, int trig_mode);
@@ -251,7 +290,12 @@ int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest)
 int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
 {
 	int result = 0;
-	u8 logical_id;
+	u32 logical_id;
+
+	if (apic_x2apic_mode(apic)) {
+		logical_id = apic_get_reg(apic, APIC_LDR);
+		return logical_id & mda;
+	}
 
 	logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR));
 
@@ -331,6 +375,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
 			break;
 
 		result = !apic_test_and_set_irr(vector, apic);
+		trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode,
+					  trig_mode, vector, !result);
 		if (!result) {
 			if (trig_mode)
 				apic_debug("level trig mode repeatedly for "
@@ -425,7 +471,11 @@ static void apic_set_eoi(struct kvm_lapic *apic)
 		trigger_mode = IOAPIC_LEVEL_TRIG;
 	else
 		trigger_mode = IOAPIC_EDGE_TRIG;
-	kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
+	if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) {
+		mutex_lock(&apic->vcpu->kvm->irq_lock);
+		kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
+		mutex_unlock(&apic->vcpu->kvm->irq_lock);
+	}
 }
 
 static void apic_send_ipi(struct kvm_lapic *apic)
@@ -440,7 +490,12 @@ static void apic_send_ipi(struct kvm_lapic *apic)
 	irq.level = icr_low & APIC_INT_ASSERT;
 	irq.trig_mode = icr_low & APIC_INT_LEVELTRIG;
 	irq.shorthand = icr_low & APIC_SHORT_MASK;
-	irq.dest_id = GET_APIC_DEST_FIELD(icr_high);
+	if (apic_x2apic_mode(apic))
+		irq.dest_id = icr_high;
+	else
+		irq.dest_id = GET_APIC_DEST_FIELD(icr_high);
+
+	trace_kvm_apic_ipi(icr_low, irq.dest_id);
 
 	apic_debug("icr_high 0x%x, icr_low 0x%x, "
 		   "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
@@ -449,7 +504,9 @@ static void apic_send_ipi(struct kvm_lapic *apic)
 		   irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode,
 		   irq.vector);
 
+	mutex_lock(&apic->vcpu->kvm->irq_lock);
 	kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq);
+	mutex_unlock(&apic->vcpu->kvm->irq_lock);
 }
 
 static u32 apic_get_tmcct(struct kvm_lapic *apic)
@@ -495,12 +552,16 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
 {
 	u32 val = 0;
 
-	KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler);
-
 	if (offset >= LAPIC_MMIO_LENGTH)
 		return 0;
 
 	switch (offset) {
+	case APIC_ID:
+		if (apic_x2apic_mode(apic))
+			val = kvm_apic_id(apic);
+		else
+			val = kvm_apic_id(apic) << 24;
+		break;
 	case APIC_ARBPRI:
 		printk(KERN_WARNING "Access APIC ARBPRI register "
 		       "which is for P6\n");
@@ -522,21 +583,35 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
 	return val;
 }
 
-static void apic_mmio_read(struct kvm_io_device *this,
-			   gpa_t address, int len, void *data)
+static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev)
+{
+	return container_of(dev, struct kvm_lapic, dev);
+}
+
+static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len,
+		void *data)
 {
-	struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
-	unsigned int offset = address - apic->base_address;
 	unsigned char alignment = offset & 0xf;
 	u32 result;
+	/* this bitmask has a bit cleared for each reserver register */
+	static const u64 rmask = 0x43ff01ffffffe70cULL;
 
 	if ((alignment + len) > 4) {
-		printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d",
-		       (unsigned long)address, len);
-		return;
+		apic_debug("KVM_APIC_READ: alignment error %x %d\n",
+			   offset, len);
+		return 1;
 	}
+
+	if (offset > 0x3f0 || !(rmask & (1ULL << (offset >> 4)))) {
+		apic_debug("KVM_APIC_READ: read reserved register %x\n",
+			   offset);
+		return 1;
+	}
+
 	result = __apic_read(apic, offset & ~0xf);
 
+	trace_kvm_apic_read(offset, result);
+
 	switch (len) {
 	case 1:
 	case 2:
@@ -548,6 +623,28 @@ static void apic_mmio_read(struct kvm_io_device *this,
 		       "should be 1,2, or 4 instead\n", len);
 		break;
 	}
+	return 0;
+}
+
+static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
+{
+	return apic_hw_enabled(apic) &&
+	    addr >= apic->base_address &&
+	    addr < apic->base_address + LAPIC_MMIO_LENGTH;
+}
+
+static int apic_mmio_read(struct kvm_io_device *this,
+			   gpa_t address, int len, void *data)
+{
+	struct kvm_lapic *apic = to_lapic(this);
+	u32 offset = address - apic->base_address;
+
+	if (!apic_mmio_in_range(apic, address))
+		return -EOPNOTSUPP;
+
+	apic_reg_read(apic, offset, len, data);
+
+	return 0;
 }
 
 static void update_divide_count(struct kvm_lapic *apic)
@@ -573,6 +670,15 @@ static void start_apic_timer(struct kvm_lapic *apic)
 
 	if (!apic->lapic_timer.period)
 		return;
+	/*
+	 * Do not allow the guest to program periodic timers with small
+	 * interval, since the hrtimers are not throttled by the host
+	 * scheduler.
+	 */
+	if (apic_lvtt_period(apic)) {
+		if (apic->lapic_timer.period < NSEC_PER_MSEC/2)
+			apic->lapic_timer.period = NSEC_PER_MSEC/2;
+	}
 
 	hrtimer_start(&apic->lapic_timer.timer,
 		      ktime_add_ns(now, apic->lapic_timer.period),
@@ -603,40 +709,18 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
 		apic->vcpu->kvm->arch.vapics_in_nmi_mode--;
 }
 
-static void apic_mmio_write(struct kvm_io_device *this,
-			    gpa_t address, int len, const void *data)
+static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
 {
-	struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
-	unsigned int offset = address - apic->base_address;
-	unsigned char alignment = offset & 0xf;
-	u32 val;
-
-	/*
-	 * APIC register must be aligned on 128-bits boundary.
-	 * 32/64/128 bits registers must be accessed thru 32 bits.
-	 * Refer SDM 8.4.1
-	 */
-	if (len != 4 || alignment) {
-		/* Don't shout loud, $infamous_os would cause only noise. */
-		apic_debug("apic write: bad size=%d %lx\n",
-			   len, (long)address);
-		return;
-	}
-
-	val = *(u32 *) data;
-
-	/* too common printing */
-	if (offset != APIC_EOI)
-		apic_debug("%s: offset 0x%x with length 0x%x, and value is "
-			   "0x%x\n", __func__, offset, len, val);
-
-	offset &= 0xff0;
+	int ret = 0;
 
-	KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler);
+	trace_kvm_apic_write(reg, val);
 
-	switch (offset) {
+	switch (reg) {
 	case APIC_ID:		/* Local APIC ID */
-		apic_set_reg(apic, APIC_ID, val);
+		if (!apic_x2apic_mode(apic))
+			apic_set_reg(apic, APIC_ID, val);
+		else
+			ret = 1;
 		break;
 
 	case APIC_TASKPRI:
@@ -649,15 +733,24 @@ static void apic_mmio_write(struct kvm_io_device *this,
 		break;
 
 	case APIC_LDR:
-		apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK);
+		if (!apic_x2apic_mode(apic))
+			apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK);
+		else
+			ret = 1;
 		break;
 
 	case APIC_DFR:
-		apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
+		if (!apic_x2apic_mode(apic))
+			apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
+		else
+			ret = 1;
 		break;
 
-	case APIC_SPIV:
-		apic_set_reg(apic, APIC_SPIV, val & 0x3ff);
+	case APIC_SPIV: {
+		u32 mask = 0x3ff;
+		if (apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI)
+			mask |= APIC_SPIV_DIRECTED_EOI;
+		apic_set_reg(apic, APIC_SPIV, val & mask);
 		if (!(val & APIC_SPIV_APIC_ENABLED)) {
 			int i;
 			u32 lvt_val;
@@ -672,7 +765,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
 
 		}
 		break;
-
+	}
 	case APIC_ICR:
 		/* No delay here, so we always clear the pending bit */
 		apic_set_reg(apic, APIC_ICR, val & ~(1 << 12));
@@ -680,7 +773,9 @@ static void apic_mmio_write(struct kvm_io_device *this,
 		break;
 
 	case APIC_ICR2:
-		apic_set_reg(apic, APIC_ICR2, val & 0xff000000);
+		if (!apic_x2apic_mode(apic))
+			val &= 0xff000000;
+		apic_set_reg(apic, APIC_ICR2, val);
 		break;
 
 	case APIC_LVT0:
@@ -694,8 +789,8 @@ static void apic_mmio_write(struct kvm_io_device *this,
 		if (!apic_sw_enabled(apic))
 			val |= APIC_LVT_MASKED;
 
-		val &= apic_lvt_mask[(offset - APIC_LVTT) >> 4];
-		apic_set_reg(apic, offset, val);
+		val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4];
+		apic_set_reg(apic, reg, val);
 
 		break;
 
@@ -703,7 +798,7 @@ static void apic_mmio_write(struct kvm_io_device *this,
 		hrtimer_cancel(&apic->lapic_timer.timer);
 		apic_set_reg(apic, APIC_TMICT, val);
 		start_apic_timer(apic);
-		return;
+		break;
 
 	case APIC_TDCR:
 		if (val & 4)
@@ -712,27 +807,59 @@ static void apic_mmio_write(struct kvm_io_device *this,
 		update_divide_count(apic);
 		break;
 
+	case APIC_ESR:
+		if (apic_x2apic_mode(apic) && val != 0) {
+			printk(KERN_ERR "KVM_WRITE:ESR not zero %x\n", val);
+			ret = 1;
+		}
+		break;
+
+	case APIC_SELF_IPI:
+		if (apic_x2apic_mode(apic)) {
+			apic_reg_write(apic, APIC_ICR, 0x40000 | (val & 0xff));
+		} else
+			ret = 1;
+		break;
 	default:
-		apic_debug("Local APIC Write to read-only register %x\n",
-			   offset);
+		ret = 1;
 		break;
 	}
-
+	if (ret)
+		apic_debug("Local APIC Write to read-only register %x\n", reg);
+	return ret;
 }
 
-static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr,
-			   int len, int size)
+static int apic_mmio_write(struct kvm_io_device *this,
+			    gpa_t address, int len, const void *data)
 {
-	struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
-	int ret = 0;
+	struct kvm_lapic *apic = to_lapic(this);
+	unsigned int offset = address - apic->base_address;
+	u32 val;
 
+	if (!apic_mmio_in_range(apic, address))
+		return -EOPNOTSUPP;
 
-	if (apic_hw_enabled(apic) &&
-	    (addr >= apic->base_address) &&
-	    (addr < (apic->base_address + LAPIC_MMIO_LENGTH)))
-		ret = 1;
+	/*
+	 * APIC register must be aligned on 128-bits boundary.
+	 * 32/64/128 bits registers must be accessed thru 32 bits.
+	 * Refer SDM 8.4.1
+	 */
+	if (len != 4 || (offset & 0xf)) {
+		/* Don't shout loud, $infamous_os would cause only noise. */
+		apic_debug("apic write: bad size=%d %lx\n", len, (long)address);
+		return 0;
+	}
 
-	return ret;
+	val = *(u32*)data;
+
+	/* too common printing */
+	if (offset != APIC_EOI)
+		apic_debug("%s: offset 0x%x with length 0x%x, and value is "
+			   "0x%x\n", __func__, offset, len, val);
+
+	apic_reg_write(apic, offset & 0xff0, val);
+
+	return 0;
 }
 
 void kvm_free_lapic(struct kvm_vcpu *vcpu)
@@ -763,7 +890,6 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
 	apic_set_tpr(apic, ((cr8 & 0x0f) << 4)
 		     | (apic_get_reg(apic, APIC_TASKPRI) & 4));
 }
-EXPORT_SYMBOL_GPL(kvm_lapic_set_tpr);
 
 u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
 {
@@ -776,7 +902,6 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
 
 	return (tpr & 0xf0) >> 4;
 }
-EXPORT_SYMBOL_GPL(kvm_lapic_get_cr8);
 
 void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
 {
@@ -787,10 +912,16 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
 		vcpu->arch.apic_base = value;
 		return;
 	}
-	if (apic->vcpu->vcpu_id)
+
+	if (!kvm_vcpu_is_bsp(apic->vcpu))
 		value &= ~MSR_IA32_APICBASE_BSP;
 
 	vcpu->arch.apic_base = value;
+	if (apic_x2apic_mode(apic)) {
+		u32 id = kvm_apic_id(apic);
+		u32 ldr = ((id & ~0xf) << 16) | (1 << (id & 0xf));
+		apic_set_reg(apic, APIC_LDR, ldr);
+	}
 	apic->base_address = apic->vcpu->arch.apic_base &
 			     MSR_IA32_APICBASE_BASE;
 
@@ -800,12 +931,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
 
 }
 
-u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu)
-{
-	return vcpu->arch.apic_base;
-}
-EXPORT_SYMBOL_GPL(kvm_lapic_get_base);
-
 void kvm_lapic_reset(struct kvm_vcpu *vcpu)
 {
 	struct kvm_lapic *apic;
@@ -821,7 +946,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
 	hrtimer_cancel(&apic->lapic_timer.timer);
 
 	apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24);
-	apic_set_reg(apic, APIC_LVR, APIC_VERSION);
+	kvm_apic_set_version(apic->vcpu);
 
 	for (i = 0; i < APIC_LVT_NUM; i++)
 		apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
@@ -842,9 +967,10 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
 		apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
 		apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
 	}
+	apic->irr_pending = false;
 	update_divide_count(apic);
 	atomic_set(&apic->lapic_timer.pending, 0);
-	if (vcpu->vcpu_id == 0)
+	if (kvm_vcpu_is_bsp(vcpu))
 		vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP;
 	apic_update_ppr(apic);
 
@@ -855,7 +981,6 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
 		   vcpu, kvm_apic_id(apic),
 		   vcpu->arch.apic_base, apic->base_address);
 }
-EXPORT_SYMBOL_GPL(kvm_lapic_reset);
 
 bool kvm_apic_present(struct kvm_vcpu *vcpu)
 {
@@ -866,7 +991,6 @@ int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
 {
 	return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic);
 }
-EXPORT_SYMBOL_GPL(kvm_lapic_enabled);
 
 /*
  *----------------------------------------------------------------------
@@ -917,6 +1041,11 @@ static struct kvm_timer_ops lapic_timer_ops = {
 	.is_periodic = lapic_is_periodic,
 };
 
+static const struct kvm_io_device_ops apic_mmio_ops = {
+	.read     = apic_mmio_read,
+	.write    = apic_mmio_write,
+};
+
 int kvm_create_lapic(struct kvm_vcpu *vcpu)
 {
 	struct kvm_lapic *apic;
@@ -945,16 +1074,13 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu)
 	apic->lapic_timer.timer.function = kvm_timer_fn;
 	apic->lapic_timer.t_ops = &lapic_timer_ops;
 	apic->lapic_timer.kvm = vcpu->kvm;
-	apic->lapic_timer.vcpu_id = vcpu->vcpu_id;
+	apic->lapic_timer.vcpu = vcpu;
 
 	apic->base_address = APIC_DEFAULT_PHYS_BASE;
 	vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE;
 
 	kvm_lapic_reset(vcpu);
-	apic->dev.read = apic_mmio_read;
-	apic->dev.write = apic_mmio_write;
-	apic->dev.in_range = apic_mmio_range;
-	apic->dev.private = apic;
+	kvm_iodevice_init(&apic->dev, &apic_mmio_ops);
 
 	return 0;
 nomem_free_apic:
@@ -962,7 +1088,6 @@ nomem_free_apic:
 nomem:
 	return -ENOMEM;
 }
-EXPORT_SYMBOL_GPL(kvm_create_lapic);
 
 int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
 {
@@ -985,7 +1110,7 @@ int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu)
 	u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0);
 	int r = 0;
 
-	if (vcpu->vcpu_id == 0) {
+	if (kvm_vcpu_is_bsp(vcpu)) {
 		if (!apic_hw_enabled(vcpu->arch.apic))
 			r = 1;
 		if ((lvt0 & APIC_LVT_MASKED) == 0 &&
@@ -1025,7 +1150,8 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu)
 
 	apic->base_address = vcpu->arch.apic_base &
 			     MSR_IA32_APICBASE_BASE;
-	apic_set_reg(apic, APIC_LVR, APIC_VERSION);
+	kvm_apic_set_version(vcpu);
+
 	apic_update_ppr(apic);
 	hrtimer_cancel(&apic->lapic_timer.timer);
 	update_divide_count(apic);
@@ -1092,3 +1218,35 @@ void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr)
 
 	vcpu->arch.apic->vapic_addr = vapic_addr;
 }
+
+int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+	u32 reg = (msr - APIC_BASE_MSR) << 4;
+
+	if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
+		return 1;
+
+	/* if this is ICR write vector before command */
+	if (msr == 0x830)
+		apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32));
+	return apic_reg_write(apic, reg, (u32)data);
+}
+
+int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
+{
+	struct kvm_lapic *apic = vcpu->arch.apic;
+	u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0;
+
+	if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic))
+		return 1;
+
+	if (apic_reg_read(apic, reg, 4, &low))
+		return 1;
+	if (msr == 0x830)
+		apic_reg_read(apic, APIC_ICR2, 4, &high);
+
+	*data = (((u64)high) << 32) | low;
+
+	return 0;
+}
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index a587f83..40010b0 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -12,6 +12,7 @@ struct kvm_lapic {
 	struct kvm_timer lapic_timer;
 	u32 divide_count;
 	struct kvm_vcpu *vcpu;
+	bool irr_pending;
 	struct page *regs_page;
 	void *regs;
 	gpa_t vapic_addr;
@@ -28,6 +29,7 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
 void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value);
 u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
+void kvm_apic_set_version(struct kvm_vcpu *vcpu);
 
 int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
 int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
@@ -44,4 +46,6 @@ void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr);
 void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu);
 void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu);
 
+int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data);
+int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data);
 #endif
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 0ef5bb2..eca41ae 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -18,6 +18,7 @@
  */
 
 #include "mmu.h"
+#include "kvm_cache_regs.h"
 
 #include <linux/kvm_host.h>
 #include <linux/types.h>
@@ -107,6 +108,9 @@ module_param(oos_shadow, bool, 0644);
 
 #define PT32_LEVEL_MASK(level) \
 		(((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level))
+#define PT32_LVL_OFFSET_MASK(level) \
+	(PT32_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \
+						* PT32_LEVEL_BITS))) - 1))
 
 #define PT32_INDEX(address, level)\
 	(((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1))
@@ -115,10 +119,19 @@ module_param(oos_shadow, bool, 0644);
 #define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1))
 #define PT64_DIR_BASE_ADDR_MASK \
 	(PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1))
+#define PT64_LVL_ADDR_MASK(level) \
+	(PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \
+						* PT64_LEVEL_BITS))) - 1))
+#define PT64_LVL_OFFSET_MASK(level) \
+	(PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \
+						* PT64_LEVEL_BITS))) - 1))
 
 #define PT32_BASE_ADDR_MASK PAGE_MASK
 #define PT32_DIR_BASE_ADDR_MASK \
 	(PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1))
+#define PT32_LVL_ADDR_MASK(level) \
+	(PAGE_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \
+					    * PT32_LEVEL_BITS))) - 1))
 
 #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK \
 			| PT64_NX_MASK)
@@ -129,6 +142,7 @@ module_param(oos_shadow, bool, 0644);
 #define PFERR_RSVD_MASK (1U << 3)
 #define PFERR_FETCH_MASK (1U << 4)
 
+#define PT_PDPE_LEVEL 3
 #define PT_DIRECTORY_LEVEL 2
 #define PT_PAGE_TABLE_LEVEL 1
 
@@ -139,10 +153,13 @@ module_param(oos_shadow, bool, 0644);
 #define ACC_USER_MASK    PT_USER_MASK
 #define ACC_ALL          (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
 
+#define CREATE_TRACE_POINTS
+#include "mmutrace.h"
+
 #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
 
 struct kvm_rmap_desc {
-	u64 *shadow_ptes[RMAP_EXT];
+	u64 *sptes[RMAP_EXT];
 	struct kvm_rmap_desc *more;
 };
 
@@ -239,16 +256,25 @@ static int is_writeble_pte(unsigned long pte)
 	return pte & PT_WRITABLE_MASK;
 }
 
-static int is_dirty_pte(unsigned long pte)
+static int is_dirty_gpte(unsigned long pte)
 {
-	return pte & shadow_dirty_mask;
+	return pte & PT_DIRTY_MASK;
 }
 
-static int is_rmap_pte(u64 pte)
+static int is_rmap_spte(u64 pte)
 {
 	return is_shadow_present_pte(pte);
 }
 
+static int is_last_spte(u64 pte, int level)
+{
+	if (level == PT_PAGE_TABLE_LEVEL)
+		return 1;
+	if (is_large_pte(pte))
+		return 1;
+	return 0;
+}
+
 static pfn_t spte_to_pfn(u64 pte)
 {
 	return (pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
@@ -261,7 +287,7 @@ static gfn_t pse36_gfn_delta(u32 gpte)
 	return (gpte & PT32_DIR_PSE36_MASK) << shift;
 }
 
-static void set_shadow_pte(u64 *sptep, u64 spte)
+static void __set_spte(u64 *sptep, u64 spte)
 {
 #ifdef CONFIG_X86_64
 	set_64bit((unsigned long *)sptep, spte);
@@ -380,37 +406,52 @@ static void mmu_free_rmap_desc(struct kvm_rmap_desc *rd)
  * Return the pointer to the largepage write count for a given
  * gfn, handling slots that are not large page aligned.
  */
-static int *slot_largepage_idx(gfn_t gfn, struct kvm_memory_slot *slot)
+static int *slot_largepage_idx(gfn_t gfn,
+			       struct kvm_memory_slot *slot,
+			       int level)
 {
 	unsigned long idx;
 
-	idx = (gfn / KVM_PAGES_PER_HPAGE) -
-	      (slot->base_gfn / KVM_PAGES_PER_HPAGE);
-	return &slot->lpage_info[idx].write_count;
+	idx = (gfn / KVM_PAGES_PER_HPAGE(level)) -
+	      (slot->base_gfn / KVM_PAGES_PER_HPAGE(level));
+	return &slot->lpage_info[level - 2][idx].write_count;
 }
 
 static void account_shadowed(struct kvm *kvm, gfn_t gfn)
 {
+	struct kvm_memory_slot *slot;
 	int *write_count;
+	int i;
 
 	gfn = unalias_gfn(kvm, gfn);
-	write_count = slot_largepage_idx(gfn,
-					 gfn_to_memslot_unaliased(kvm, gfn));
-	*write_count += 1;
+
+	slot = gfn_to_memslot_unaliased(kvm, gfn);
+	for (i = PT_DIRECTORY_LEVEL;
+	     i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
+		write_count   = slot_largepage_idx(gfn, slot, i);
+		*write_count += 1;
+	}
 }
 
 static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn)
 {
+	struct kvm_memory_slot *slot;
 	int *write_count;
+	int i;
 
 	gfn = unalias_gfn(kvm, gfn);
-	write_count = slot_largepage_idx(gfn,
-					 gfn_to_memslot_unaliased(kvm, gfn));
-	*write_count -= 1;
-	WARN_ON(*write_count < 0);
+	for (i = PT_DIRECTORY_LEVEL;
+	     i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
+		slot          = gfn_to_memslot_unaliased(kvm, gfn);
+		write_count   = slot_largepage_idx(gfn, slot, i);
+		*write_count -= 1;
+		WARN_ON(*write_count < 0);
+	}
 }
 
-static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn)
+static int has_wrprotected_page(struct kvm *kvm,
+				gfn_t gfn,
+				int level)
 {
 	struct kvm_memory_slot *slot;
 	int *largepage_idx;
@@ -418,47 +459,67 @@ static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn)
 	gfn = unalias_gfn(kvm, gfn);
 	slot = gfn_to_memslot_unaliased(kvm, gfn);
 	if (slot) {
-		largepage_idx = slot_largepage_idx(gfn, slot);
+		largepage_idx = slot_largepage_idx(gfn, slot, level);
 		return *largepage_idx;
 	}
 
 	return 1;
 }
 
-static int host_largepage_backed(struct kvm *kvm, gfn_t gfn)
+static int host_mapping_level(struct kvm *kvm, gfn_t gfn)
 {
+	unsigned long page_size = PAGE_SIZE;
 	struct vm_area_struct *vma;
 	unsigned long addr;
-	int ret = 0;
+	int i, ret = 0;
 
 	addr = gfn_to_hva(kvm, gfn);
 	if (kvm_is_error_hva(addr))
-		return ret;
+		return page_size;
 
 	down_read(&current->mm->mmap_sem);
 	vma = find_vma(current->mm, addr);
-	if (vma && is_vm_hugetlb_page(vma))
-		ret = 1;
+	if (!vma)
+		goto out;
+
+	page_size = vma_kernel_pagesize(vma);
+
+out:
 	up_read(&current->mm->mmap_sem);
 
+	for (i = PT_PAGE_TABLE_LEVEL;
+	     i < (PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES); ++i) {
+		if (page_size >= KVM_HPAGE_SIZE(i))
+			ret = i;
+		else
+			break;
+	}
+
 	return ret;
 }
 
-static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn)
+static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
 {
 	struct kvm_memory_slot *slot;
-
-	if (has_wrprotected_page(vcpu->kvm, large_gfn))
-		return 0;
-
-	if (!host_largepage_backed(vcpu->kvm, large_gfn))
-		return 0;
+	int host_level;
+	int level = PT_PAGE_TABLE_LEVEL;
 
 	slot = gfn_to_memslot(vcpu->kvm, large_gfn);
 	if (slot && slot->dirty_bitmap)
-		return 0;
+		return PT_PAGE_TABLE_LEVEL;
 
-	return 1;
+	host_level = host_mapping_level(vcpu->kvm, large_gfn);
+
+	if (host_level == PT_PAGE_TABLE_LEVEL)
+		return host_level;
+
+	for (level = PT_DIRECTORY_LEVEL; level <= host_level; ++level) {
+
+		if (has_wrprotected_page(vcpu->kvm, large_gfn, level))
+			break;
+	}
+
+	return level - 1;
 }
 
 /*
@@ -466,19 +527,19 @@ static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn)
  * Note: gfn must be unaliased before this function get called
  */
 
-static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage)
+static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int level)
 {
 	struct kvm_memory_slot *slot;
 	unsigned long idx;
 
 	slot = gfn_to_memslot(kvm, gfn);
-	if (!lpage)
+	if (likely(level == PT_PAGE_TABLE_LEVEL))
 		return &slot->rmap[gfn - slot->base_gfn];
 
-	idx = (gfn / KVM_PAGES_PER_HPAGE) -
-	      (slot->base_gfn / KVM_PAGES_PER_HPAGE);
+	idx = (gfn / KVM_PAGES_PER_HPAGE(level)) -
+		(slot->base_gfn / KVM_PAGES_PER_HPAGE(level));
 
-	return &slot->lpage_info[idx].rmap_pde;
+	return &slot->lpage_info[level - 2][idx].rmap_pde;
 }
 
 /*
@@ -494,42 +555,42 @@ static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage)
  * the spte was not added.
  *
  */
-static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage)
+static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
 {
 	struct kvm_mmu_page *sp;
 	struct kvm_rmap_desc *desc;
 	unsigned long *rmapp;
 	int i, count = 0;
 
-	if (!is_rmap_pte(*spte))
+	if (!is_rmap_spte(*spte))
 		return count;
 	gfn = unalias_gfn(vcpu->kvm, gfn);
 	sp = page_header(__pa(spte));
 	sp->gfns[spte - sp->spt] = gfn;
-	rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage);
+	rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
 	if (!*rmapp) {
 		rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte);
 		*rmapp = (unsigned long)spte;
 	} else if (!(*rmapp & 1)) {
 		rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte);
 		desc = mmu_alloc_rmap_desc(vcpu);
-		desc->shadow_ptes[0] = (u64 *)*rmapp;
-		desc->shadow_ptes[1] = spte;
+		desc->sptes[0] = (u64 *)*rmapp;
+		desc->sptes[1] = spte;
 		*rmapp = (unsigned long)desc | 1;
 	} else {
 		rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte);
 		desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
-		while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) {
+		while (desc->sptes[RMAP_EXT-1] && desc->more) {
 			desc = desc->more;
 			count += RMAP_EXT;
 		}
-		if (desc->shadow_ptes[RMAP_EXT-1]) {
+		if (desc->sptes[RMAP_EXT-1]) {
 			desc->more = mmu_alloc_rmap_desc(vcpu);
 			desc = desc->more;
 		}
-		for (i = 0; desc->shadow_ptes[i]; ++i)
+		for (i = 0; desc->sptes[i]; ++i)
 			;
-		desc->shadow_ptes[i] = spte;
+		desc->sptes[i] = spte;
 	}
 	return count;
 }
@@ -541,14 +602,14 @@ static void rmap_desc_remove_entry(unsigned long *rmapp,
 {
 	int j;
 
-	for (j = RMAP_EXT - 1; !desc->shadow_ptes[j] && j > i; --j)
+	for (j = RMAP_EXT - 1; !desc->sptes[j] && j > i; --j)
 		;
-	desc->shadow_ptes[i] = desc->shadow_ptes[j];
-	desc->shadow_ptes[j] = NULL;
+	desc->sptes[i] = desc->sptes[j];
+	desc->sptes[j] = NULL;
 	if (j != 0)
 		return;
 	if (!prev_desc && !desc->more)
-		*rmapp = (unsigned long)desc->shadow_ptes[0];
+		*rmapp = (unsigned long)desc->sptes[0];
 	else
 		if (prev_desc)
 			prev_desc->more = desc->more;
@@ -566,7 +627,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
 	unsigned long *rmapp;
 	int i;
 
-	if (!is_rmap_pte(*spte))
+	if (!is_rmap_spte(*spte))
 		return;
 	sp = page_header(__pa(spte));
 	pfn = spte_to_pfn(*spte);
@@ -576,7 +637,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
 		kvm_release_pfn_dirty(pfn);
 	else
 		kvm_release_pfn_clean(pfn);
-	rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], is_large_pte(*spte));
+	rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level);
 	if (!*rmapp) {
 		printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
 		BUG();
@@ -593,8 +654,8 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
 		desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
 		prev_desc = NULL;
 		while (desc) {
-			for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i)
-				if (desc->shadow_ptes[i] == spte) {
+			for (i = 0; i < RMAP_EXT && desc->sptes[i]; ++i)
+				if (desc->sptes[i] == spte) {
 					rmap_desc_remove_entry(rmapp,
 							       desc, i,
 							       prev_desc);
@@ -625,10 +686,10 @@ static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte)
 	prev_desc = NULL;
 	prev_spte = NULL;
 	while (desc) {
-		for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) {
+		for (i = 0; i < RMAP_EXT && desc->sptes[i]; ++i) {
 			if (prev_spte == spte)
-				return desc->shadow_ptes[i];
-			prev_spte = desc->shadow_ptes[i];
+				return desc->sptes[i];
+			prev_spte = desc->sptes[i];
 		}
 		desc = desc->more;
 	}
@@ -639,10 +700,10 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
 {
 	unsigned long *rmapp;
 	u64 *spte;
-	int write_protected = 0;
+	int i, write_protected = 0;
 
 	gfn = unalias_gfn(kvm, gfn);
-	rmapp = gfn_to_rmap(kvm, gfn, 0);
+	rmapp = gfn_to_rmap(kvm, gfn, PT_PAGE_TABLE_LEVEL);
 
 	spte = rmap_next(kvm, rmapp, NULL);
 	while (spte) {
@@ -650,7 +711,7 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
 		BUG_ON(!(*spte & PT_PRESENT_MASK));
 		rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte);
 		if (is_writeble_pte(*spte)) {
-			set_shadow_pte(spte, *spte & ~PT_WRITABLE_MASK);
+			__set_spte(spte, *spte & ~PT_WRITABLE_MASK);
 			write_protected = 1;
 		}
 		spte = rmap_next(kvm, rmapp, spte);
@@ -664,21 +725,24 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
 	}
 
 	/* check for huge page mappings */
-	rmapp = gfn_to_rmap(kvm, gfn, 1);
-	spte = rmap_next(kvm, rmapp, NULL);
-	while (spte) {
-		BUG_ON(!spte);
-		BUG_ON(!(*spte & PT_PRESENT_MASK));
-		BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK));
-		pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn);
-		if (is_writeble_pte(*spte)) {
-			rmap_remove(kvm, spte);
-			--kvm->stat.lpages;
-			set_shadow_pte(spte, shadow_trap_nonpresent_pte);
-			spte = NULL;
-			write_protected = 1;
+	for (i = PT_DIRECTORY_LEVEL;
+	     i < PT_PAGE_TABLE_LEVEL + KVM_NR_PAGE_SIZES; ++i) {
+		rmapp = gfn_to_rmap(kvm, gfn, i);
+		spte = rmap_next(kvm, rmapp, NULL);
+		while (spte) {
+			BUG_ON(!spte);
+			BUG_ON(!(*spte & PT_PRESENT_MASK));
+			BUG_ON((*spte & (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK)) != (PT_PAGE_SIZE_MASK|PT_PRESENT_MASK));
+			pgprintk("rmap_write_protect(large): spte %p %llx %lld\n", spte, *spte, gfn);
+			if (is_writeble_pte(*spte)) {
+				rmap_remove(kvm, spte);
+				--kvm->stat.lpages;
+				__set_spte(spte, shadow_trap_nonpresent_pte);
+				spte = NULL;
+				write_protected = 1;
+			}
+			spte = rmap_next(kvm, rmapp, spte);
 		}
-		spte = rmap_next(kvm, rmapp, spte);
 	}
 
 	return write_protected;
@@ -693,7 +757,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
 		BUG_ON(!(*spte & PT_PRESENT_MASK));
 		rmap_printk("kvm_rmap_unmap_hva: spte %p %llx\n", spte, *spte);
 		rmap_remove(kvm, spte);
-		set_shadow_pte(spte, shadow_trap_nonpresent_pte);
+		__set_spte(spte, shadow_trap_nonpresent_pte);
 		need_tlb_flush = 1;
 	}
 	return need_tlb_flush;
@@ -702,7 +766,7 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
 static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
 			  int (*handler)(struct kvm *kvm, unsigned long *rmapp))
 {
-	int i;
+	int i, j;
 	int retval = 0;
 
 	/*
@@ -721,11 +785,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
 		end = start + (memslot->npages << PAGE_SHIFT);
 		if (hva >= start && hva < end) {
 			gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
+
 			retval |= handler(kvm, &memslot->rmap[gfn_offset]);
-			retval |= handler(kvm,
-					  &memslot->lpage_info[
-						  gfn_offset /
-						  KVM_PAGES_PER_HPAGE].rmap_pde);
+
+			for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
+				int idx = gfn_offset;
+				idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j);
+				retval |= handler(kvm,
+					&memslot->lpage_info[j][idx].rmap_pde);
+			}
 		}
 	}
 
@@ -763,12 +831,15 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp)
 
 #define RMAP_RECYCLE_THRESHOLD 1000
 
-static void rmap_recycle(struct kvm_vcpu *vcpu, gfn_t gfn, int lpage)
+static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
 {
 	unsigned long *rmapp;
+	struct kvm_mmu_page *sp;
+
+	sp = page_header(__pa(spte));
 
 	gfn = unalias_gfn(vcpu->kvm, gfn);
-	rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage);
+	rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
 
 	kvm_unmap_rmapp(vcpu->kvm, rmapp);
 	kvm_flush_remote_tlbs(vcpu->kvm);
@@ -1109,6 +1180,7 @@ static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
 		return 1;
 	}
 
+	trace_kvm_mmu_sync_page(sp);
 	if (rmap_write_protect(vcpu->kvm, sp->gfn))
 		kvm_flush_remote_tlbs(vcpu->kvm);
 	kvm_unlink_unsync_page(vcpu->kvm, sp);
@@ -1231,8 +1303,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
 		quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1;
 		role.quadrant = quadrant;
 	}
-	pgprintk("%s: looking gfn %lx role %x\n", __func__,
-		 gfn, role.word);
 	index = kvm_page_table_hashfn(gfn);
 	bucket = &vcpu->kvm->arch.mmu_page_hash[index];
 	hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link)
@@ -1249,14 +1319,13 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
 				set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests);
 				kvm_mmu_mark_parents_unsync(vcpu, sp);
 			}
-			pgprintk("%s: found\n", __func__);
+			trace_kvm_mmu_get_page(sp, false);
 			return sp;
 		}
 	++vcpu->kvm->stat.mmu_cache_miss;
 	sp = kvm_mmu_alloc_page(vcpu, parent_pte);
 	if (!sp)
 		return sp;
-	pgprintk("%s: adding gfn %lx role %x\n", __func__, gfn, role.word);
 	sp->gfn = gfn;
 	sp->role = role;
 	hlist_add_head(&sp->hash_link, bucket);
@@ -1269,6 +1338,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
 		vcpu->arch.mmu.prefetch_page(vcpu, sp);
 	else
 		nonpaging_prefetch_page(vcpu, sp);
+	trace_kvm_mmu_get_page(sp, true);
 	return sp;
 }
 
@@ -1292,6 +1362,11 @@ static bool shadow_walk_okay(struct kvm_shadow_walk_iterator *iterator)
 {
 	if (iterator->level < PT_PAGE_TABLE_LEVEL)
 		return false;
+
+	if (iterator->level == PT_PAGE_TABLE_LEVEL)
+		if (is_large_pte(*iterator->sptep))
+			return false;
+
 	iterator->index = SHADOW_PT_INDEX(iterator->addr, iterator->level);
 	iterator->sptep	= ((u64 *)__va(iterator->shadow_addr)) + iterator->index;
 	return true;
@@ -1312,25 +1387,17 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm,
 
 	pt = sp->spt;
 
-	if (sp->role.level == PT_PAGE_TABLE_LEVEL) {
-		for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
-			if (is_shadow_present_pte(pt[i]))
-				rmap_remove(kvm, &pt[i]);
-			pt[i] = shadow_trap_nonpresent_pte;
-		}
-		return;
-	}
-
 	for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
 		ent = pt[i];
 
 		if (is_shadow_present_pte(ent)) {
-			if (!is_large_pte(ent)) {
+			if (!is_last_spte(ent, sp->role.level)) {
 				ent &= PT64_BASE_ADDR_MASK;
 				mmu_page_remove_parent_pte(page_header(ent),
 							   &pt[i]);
 			} else {
-				--kvm->stat.lpages;
+				if (is_large_pte(ent))
+					--kvm->stat.lpages;
 				rmap_remove(kvm, &pt[i]);
 			}
 		}
@@ -1346,10 +1413,10 @@ static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte)
 static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm)
 {
 	int i;
+	struct kvm_vcpu *vcpu;
 
-	for (i = 0; i < KVM_MAX_VCPUS; ++i)
-		if (kvm->vcpus[i])
-			kvm->vcpus[i]->arch.last_pte_updated = NULL;
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		vcpu->arch.last_pte_updated = NULL;
 }
 
 static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
@@ -1368,7 +1435,7 @@ static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
 		}
 		BUG_ON(!parent_pte);
 		kvm_mmu_put_page(sp, parent_pte);
-		set_shadow_pte(parent_pte, shadow_trap_nonpresent_pte);
+		__set_spte(parent_pte, shadow_trap_nonpresent_pte);
 	}
 }
 
@@ -1400,6 +1467,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
 static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp)
 {
 	int ret;
+
+	trace_kvm_mmu_zap_page(sp);
 	++kvm->stat.mmu_shadow_zapped;
 	ret = mmu_zap_unsync_children(kvm, sp);
 	kvm_mmu_page_unlink_children(kvm, sp);
@@ -1516,7 +1585,7 @@ static void mmu_convert_notrap(struct kvm_mmu_page *sp)
 
 	for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
 		if (pt[i] == shadow_notrap_nonpresent_pte)
-			set_shadow_pte(&pt[i], shadow_trap_nonpresent_pte);
+			__set_spte(&pt[i], shadow_trap_nonpresent_pte);
 	}
 }
 
@@ -1646,6 +1715,7 @@ static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
 	struct kvm_mmu_page *s;
 	struct hlist_node *node, *n;
 
+	trace_kvm_mmu_unsync_page(sp);
 	index = kvm_page_table_hashfn(sp->gfn);
 	bucket = &vcpu->kvm->arch.mmu_page_hash[index];
 	/* don't unsync if pagetable is shadowed with multiple roles */
@@ -1682,9 +1752,9 @@ static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
 	return 0;
 }
 
-static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
+static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
 		    unsigned pte_access, int user_fault,
-		    int write_fault, int dirty, int largepage,
+		    int write_fault, int dirty, int level,
 		    gfn_t gfn, pfn_t pfn, bool speculative,
 		    bool can_unsync)
 {
@@ -1707,7 +1777,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
 		spte |= shadow_nx_mask;
 	if (pte_access & ACC_USER_MASK)
 		spte |= shadow_user_mask;
-	if (largepage)
+	if (level > PT_PAGE_TABLE_LEVEL)
 		spte |= PT_PAGE_SIZE_MASK;
 	if (tdp_enabled)
 		spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
@@ -1718,7 +1788,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
 	if ((pte_access & ACC_WRITE_MASK)
 	    || (write_fault && !is_write_protection(vcpu) && !user_fault)) {
 
-		if (largepage && has_wrprotected_page(vcpu->kvm, gfn)) {
+		if (level > PT_PAGE_TABLE_LEVEL &&
+		    has_wrprotected_page(vcpu->kvm, gfn, level)) {
 			ret = 1;
 			spte = shadow_trap_nonpresent_pte;
 			goto set_pte;
@@ -1732,7 +1803,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
 		 * is responsibility of mmu_get_page / kvm_sync_page.
 		 * Same reasoning can be applied to dirty page accounting.
 		 */
-		if (!can_unsync && is_writeble_pte(*shadow_pte))
+		if (!can_unsync && is_writeble_pte(*sptep))
 			goto set_pte;
 
 		if (mmu_need_write_protect(vcpu, gfn, can_unsync)) {
@@ -1749,65 +1820,67 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
 		mark_page_dirty(vcpu->kvm, gfn);
 
 set_pte:
-	set_shadow_pte(shadow_pte, spte);
+	__set_spte(sptep, spte);
 	return ret;
 }
 
-static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
+static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
 			 unsigned pt_access, unsigned pte_access,
 			 int user_fault, int write_fault, int dirty,
-			 int *ptwrite, int largepage, gfn_t gfn,
+			 int *ptwrite, int level, gfn_t gfn,
 			 pfn_t pfn, bool speculative)
 {
 	int was_rmapped = 0;
-	int was_writeble = is_writeble_pte(*shadow_pte);
+	int was_writeble = is_writeble_pte(*sptep);
 	int rmap_count;
 
 	pgprintk("%s: spte %llx access %x write_fault %d"
 		 " user_fault %d gfn %lx\n",
-		 __func__, *shadow_pte, pt_access,
+		 __func__, *sptep, pt_access,
 		 write_fault, user_fault, gfn);
 
-	if (is_rmap_pte(*shadow_pte)) {
+	if (is_rmap_spte(*sptep)) {
 		/*
 		 * If we overwrite a PTE page pointer with a 2MB PMD, unlink
 		 * the parent of the now unreachable PTE.
 		 */
-		if (largepage && !is_large_pte(*shadow_pte)) {
+		if (level > PT_PAGE_TABLE_LEVEL &&
+		    !is_large_pte(*sptep)) {
 			struct kvm_mmu_page *child;
-			u64 pte = *shadow_pte;
+			u64 pte = *sptep;
 
 			child = page_header(pte & PT64_BASE_ADDR_MASK);
-			mmu_page_remove_parent_pte(child, shadow_pte);
-		} else if (pfn != spte_to_pfn(*shadow_pte)) {
+			mmu_page_remove_parent_pte(child, sptep);
+		} else if (pfn != spte_to_pfn(*sptep)) {
 			pgprintk("hfn old %lx new %lx\n",
-				 spte_to_pfn(*shadow_pte), pfn);
-			rmap_remove(vcpu->kvm, shadow_pte);
+				 spte_to_pfn(*sptep), pfn);
+			rmap_remove(vcpu->kvm, sptep);
 		} else
 			was_rmapped = 1;
 	}
-	if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault,
-		      dirty, largepage, gfn, pfn, speculative, true)) {
+
+	if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault,
+		      dirty, level, gfn, pfn, speculative, true)) {
 		if (write_fault)
 			*ptwrite = 1;
 		kvm_x86_ops->tlb_flush(vcpu);
 	}
 
-	pgprintk("%s: setting spte %llx\n", __func__, *shadow_pte);
+	pgprintk("%s: setting spte %llx\n", __func__, *sptep);
 	pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n",
-		 is_large_pte(*shadow_pte)? "2MB" : "4kB",
-		 is_present_pte(*shadow_pte)?"RW":"R", gfn,
-		 *shadow_pte, shadow_pte);
-	if (!was_rmapped && is_large_pte(*shadow_pte))
+		 is_large_pte(*sptep)? "2MB" : "4kB",
+		 *sptep & PT_PRESENT_MASK ?"RW":"R", gfn,
+		 *sptep, sptep);
+	if (!was_rmapped && is_large_pte(*sptep))
 		++vcpu->kvm->stat.lpages;
 
-	page_header_update_slot(vcpu->kvm, shadow_pte, gfn);
+	page_header_update_slot(vcpu->kvm, sptep, gfn);
 	if (!was_rmapped) {
-		rmap_count = rmap_add(vcpu, shadow_pte, gfn, largepage);
-		if (!is_rmap_pte(*shadow_pte))
+		rmap_count = rmap_add(vcpu, sptep, gfn);
+		if (!is_rmap_spte(*sptep))
 			kvm_release_pfn_clean(pfn);
 		if (rmap_count > RMAP_RECYCLE_THRESHOLD)
-			rmap_recycle(vcpu, gfn, largepage);
+			rmap_recycle(vcpu, sptep, gfn);
 	} else {
 		if (was_writeble)
 			kvm_release_pfn_dirty(pfn);
@@ -1815,7 +1888,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
 			kvm_release_pfn_clean(pfn);
 	}
 	if (speculative) {
-		vcpu->arch.last_pte_updated = shadow_pte;
+		vcpu->arch.last_pte_updated = sptep;
 		vcpu->arch.last_pte_gfn = gfn;
 	}
 }
@@ -1825,7 +1898,7 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
 }
 
 static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
-			int largepage, gfn_t gfn, pfn_t pfn)
+			int level, gfn_t gfn, pfn_t pfn)
 {
 	struct kvm_shadow_walk_iterator iterator;
 	struct kvm_mmu_page *sp;
@@ -1833,11 +1906,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
 	gfn_t pseudo_gfn;
 
 	for_each_shadow_entry(vcpu, (u64)gfn << PAGE_SHIFT, iterator) {
-		if (iterator.level == PT_PAGE_TABLE_LEVEL
-		    || (largepage && iterator.level == PT_DIRECTORY_LEVEL)) {
+		if (iterator.level == level) {
 			mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
 				     0, write, 1, &pt_write,
-				     largepage, gfn, pfn, false);
+				     level, gfn, pfn, false);
 			++vcpu->stat.pf_fixed;
 			break;
 		}
@@ -1853,10 +1925,10 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
 				return -ENOMEM;
 			}
 
-			set_shadow_pte(iterator.sptep,
-				       __pa(sp->spt)
-				       | PT_PRESENT_MASK | PT_WRITABLE_MASK
-				       | shadow_user_mask | shadow_x_mask);
+			__set_spte(iterator.sptep,
+				   __pa(sp->spt)
+				   | PT_PRESENT_MASK | PT_WRITABLE_MASK
+				   | shadow_user_mask | shadow_x_mask);
 		}
 	}
 	return pt_write;
@@ -1865,14 +1937,20 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
 static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
 {
 	int r;
-	int largepage = 0;
+	int level;
 	pfn_t pfn;
 	unsigned long mmu_seq;
 
-	if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) {
-		gfn &= ~(KVM_PAGES_PER_HPAGE-1);
-		largepage = 1;
-	}
+	level = mapping_level(vcpu, gfn);
+
+	/*
+	 * This path builds a PAE pagetable - so we can map 2mb pages at
+	 * maximum. Therefore check if the level is larger than that.
+	 */
+	if (level > PT_DIRECTORY_LEVEL)
+		level = PT_DIRECTORY_LEVEL;
+
+	gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1);
 
 	mmu_seq = vcpu->kvm->mmu_notifier_seq;
 	smp_rmb();
@@ -1888,7 +1966,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
 	if (mmu_notifier_retry(vcpu, mmu_seq))
 		goto out_unlock;
 	kvm_mmu_free_some_pages(vcpu);
-	r = __direct_map(vcpu, v, write, largepage, gfn, pfn);
+	r = __direct_map(vcpu, v, write, level, gfn, pfn);
 	spin_unlock(&vcpu->kvm->mmu_lock);
 
 
@@ -1954,6 +2032,7 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
 	gfn_t root_gfn;
 	struct kvm_mmu_page *sp;
 	int direct = 0;
+	u64 pdptr;
 
 	root_gfn = vcpu->arch.cr3 >> PAGE_SHIFT;
 
@@ -1981,11 +2060,12 @@ static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
 
 		ASSERT(!VALID_PAGE(root));
 		if (vcpu->arch.mmu.root_level == PT32E_ROOT_LEVEL) {
-			if (!is_present_pte(vcpu->arch.pdptrs[i])) {
+			pdptr = kvm_pdptr_read(vcpu, i);
+			if (!is_present_gpte(pdptr)) {
 				vcpu->arch.mmu.pae_root[i] = 0;
 				continue;
 			}
-			root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT;
+			root_gfn = pdptr >> PAGE_SHIFT;
 		} else if (vcpu->arch.mmu.root_level == 0)
 			root_gfn = 0;
 		if (mmu_check_root(vcpu, root_gfn))
@@ -2062,7 +2142,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
 {
 	pfn_t pfn;
 	int r;
-	int largepage = 0;
+	int level;
 	gfn_t gfn = gpa >> PAGE_SHIFT;
 	unsigned long mmu_seq;
 
@@ -2073,10 +2153,10 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
 	if (r)
 		return r;
 
-	if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) {
-		gfn &= ~(KVM_PAGES_PER_HPAGE-1);
-		largepage = 1;
-	}
+	level = mapping_level(vcpu, gfn);
+
+	gfn &= ~(KVM_PAGES_PER_HPAGE(level) - 1);
+
 	mmu_seq = vcpu->kvm->mmu_notifier_seq;
 	smp_rmb();
 	pfn = gfn_to_pfn(vcpu->kvm, gfn);
@@ -2089,7 +2169,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
 		goto out_unlock;
 	kvm_mmu_free_some_pages(vcpu);
 	r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK,
-			 largepage, gfn, pfn);
+			 level, gfn, pfn);
 	spin_unlock(&vcpu->kvm->mmu_lock);
 
 	return r;
@@ -2206,7 +2286,9 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level)
 		context->rsvd_bits_mask[0][0] = exb_bit_rsvd |
 			rsvd_bits(maxphyaddr, 51);
 		context->rsvd_bits_mask[1][3] = context->rsvd_bits_mask[0][3];
-		context->rsvd_bits_mask[1][2] = context->rsvd_bits_mask[0][2];
+		context->rsvd_bits_mask[1][2] = exb_bit_rsvd |
+			rsvd_bits(maxphyaddr, 51) |
+			rsvd_bits(13, 29);
 		context->rsvd_bits_mask[1][1] = exb_bit_rsvd |
 			rsvd_bits(maxphyaddr, 51) |
 			rsvd_bits(13, 20);		/* large page */
@@ -2357,8 +2439,8 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
 	spin_unlock(&vcpu->kvm->mmu_lock);
 	if (r)
 		goto out;
+	/* set_cr3() should ensure TLB has been flushed */
 	kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
-	kvm_mmu_flush_tlb(vcpu);
 out:
 	return r;
 }
@@ -2378,15 +2460,14 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
 
 	pte = *spte;
 	if (is_shadow_present_pte(pte)) {
-		if (sp->role.level == PT_PAGE_TABLE_LEVEL ||
-		    is_large_pte(pte))
+		if (is_last_spte(pte, sp->role.level))
 			rmap_remove(vcpu->kvm, spte);
 		else {
 			child = page_header(pte & PT64_BASE_ADDR_MASK);
 			mmu_page_remove_parent_pte(child, spte);
 		}
 	}
-	set_shadow_pte(spte, shadow_trap_nonpresent_pte);
+	__set_spte(spte, shadow_trap_nonpresent_pte);
 	if (is_large_pte(pte))
 		--vcpu->kvm->stat.lpages;
 }
@@ -2397,11 +2478,8 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
 				  const void *new)
 {
 	if (sp->role.level != PT_PAGE_TABLE_LEVEL) {
-		if (!vcpu->arch.update_pte.largepage ||
-		    sp->role.glevels == PT32_ROOT_LEVEL) {
-			++vcpu->kvm->stat.mmu_pde_zapped;
-			return;
-		}
+		++vcpu->kvm->stat.mmu_pde_zapped;
+		return;
         }
 
 	++vcpu->kvm->stat.mmu_pte_updated;
@@ -2447,8 +2525,6 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 	u64 gpte = 0;
 	pfn_t pfn;
 
-	vcpu->arch.update_pte.largepage = 0;
-
 	if (bytes != 4 && bytes != 8)
 		return;
 
@@ -2472,14 +2548,10 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
 		if ((bytes == 4) && (gpa % 4 == 0))
 			memcpy((void *)&gpte, new, 4);
 	}
-	if (!is_present_pte(gpte))
+	if (!is_present_gpte(gpte))
 		return;
 	gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
 
-	if (is_large_pte(gpte) && is_largepage_backed(vcpu, gfn)) {
-		gfn &= ~(KVM_PAGES_PER_HPAGE-1);
-		vcpu->arch.update_pte.largepage = 1;
-	}
 	vcpu->arch.update_pte.mmu_seq = vcpu->kvm->mmu_notifier_seq;
 	smp_rmb();
 	pfn = gfn_to_pfn(vcpu->kvm, gfn);
@@ -2622,6 +2694,9 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva)
 	gpa_t gpa;
 	int r;
 
+	if (tdp_enabled)
+		return 0;
+
 	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, gva);
 
 	spin_lock(&vcpu->kvm->mmu_lock);
@@ -2633,7 +2708,8 @@ EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt);
 
 void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
 {
-	while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES) {
+	while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES &&
+	       !list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
 		struct kvm_mmu_page *sp;
 
 		sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev,
@@ -2670,8 +2746,9 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code)
 		++vcpu->stat.mmio_exits;
 		return 0;
 	case EMULATE_FAIL:
-		kvm_report_emulation_failure(vcpu, "pagetable");
-		return 1;
+		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
+		return 0;
 	default:
 		BUG();
 	}
@@ -2712,12 +2789,6 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
 
 	ASSERT(vcpu);
 
-	if (vcpu->kvm->arch.n_requested_mmu_pages)
-		vcpu->kvm->arch.n_free_mmu_pages =
-					vcpu->kvm->arch.n_requested_mmu_pages;
-	else
-		vcpu->kvm->arch.n_free_mmu_pages =
-					vcpu->kvm->arch.n_alloc_mmu_pages;
 	/*
 	 * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.
 	 * Therefore we need to allocate shadow page tables in the first
@@ -3029,6 +3100,24 @@ out:
 	return r;
 }
 
+int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4])
+{
+	struct kvm_shadow_walk_iterator iterator;
+	int nr_sptes = 0;
+
+	spin_lock(&vcpu->kvm->mmu_lock);
+	for_each_shadow_entry(vcpu, addr, iterator) {
+		sptes[iterator.level-1] = *iterator.sptep;
+		nr_sptes++;
+		if (!is_shadow_present_pte(*iterator.sptep))
+			break;
+	}
+	spin_unlock(&vcpu->kvm->mmu_lock);
+
+	return nr_sptes;
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy);
+
 #ifdef AUDIT
 
 static const char *audit_msg;
@@ -3041,6 +3130,54 @@ static gva_t canonicalize(gva_t gva)
 	return gva;
 }
 
+
+typedef void (*inspect_spte_fn) (struct kvm *kvm, struct kvm_mmu_page *sp,
+				 u64 *sptep);
+
+static void __mmu_spte_walk(struct kvm *kvm, struct kvm_mmu_page *sp,
+			    inspect_spte_fn fn)
+{
+	int i;
+
+	for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
+		u64 ent = sp->spt[i];
+
+		if (is_shadow_present_pte(ent)) {
+			if (!is_last_spte(ent, sp->role.level)) {
+				struct kvm_mmu_page *child;
+				child = page_header(ent & PT64_BASE_ADDR_MASK);
+				__mmu_spte_walk(kvm, child, fn);
+			} else
+				fn(kvm, sp, &sp->spt[i]);
+		}
+	}
+}
+
+static void mmu_spte_walk(struct kvm_vcpu *vcpu, inspect_spte_fn fn)
+{
+	int i;
+	struct kvm_mmu_page *sp;
+
+	if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+		return;
+	if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
+		hpa_t root = vcpu->arch.mmu.root_hpa;
+		sp = page_header(root);
+		__mmu_spte_walk(vcpu->kvm, sp, fn);
+		return;
+	}
+	for (i = 0; i < 4; ++i) {
+		hpa_t root = vcpu->arch.mmu.pae_root[i];
+
+		if (root && VALID_PAGE(root)) {
+			root &= PT64_BASE_ADDR_MASK;
+			sp = page_header(root);
+			__mmu_spte_walk(vcpu->kvm, sp, fn);
+		}
+	}
+	return;
+}
+
 static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
 				gva_t va, int level)
 {
@@ -3055,20 +3192,19 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte,
 			continue;
 
 		va = canonicalize(va);
-		if (level > 1) {
-			if (ent == shadow_notrap_nonpresent_pte)
-				printk(KERN_ERR "audit: (%s) nontrapping pte"
-				       " in nonleaf level: levels %d gva %lx"
-				       " level %d pte %llx\n", audit_msg,
-				       vcpu->arch.mmu.root_level, va, level, ent);
-			else
-				audit_mappings_page(vcpu, ent, va, level - 1);
-		} else {
+		if (is_shadow_present_pte(ent) && !is_last_spte(ent, level))
+			audit_mappings_page(vcpu, ent, va, level - 1);
+		else {
 			gpa_t gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, va);
 			gfn_t gfn = gpa >> PAGE_SHIFT;
 			pfn_t pfn = gfn_to_pfn(vcpu->kvm, gfn);
 			hpa_t hpa = (hpa_t)pfn << PAGE_SHIFT;
 
+			if (is_error_pfn(pfn)) {
+				kvm_release_pfn_clean(pfn);
+				continue;
+			}
+
 			if (is_shadow_present_pte(ent)
 			    && (ent & PT64_BASE_ADDR_MASK) != hpa)
 				printk(KERN_ERR "xx audit error: (%s) levels %d"
@@ -3122,7 +3258,7 @@ static int count_rmaps(struct kvm_vcpu *vcpu)
 			d = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
 			while (d) {
 				for (k = 0; k < RMAP_EXT; ++k)
-					if (d->shadow_ptes[k])
+					if (d->sptes[k])
 						++nmaps;
 					else
 						break;
@@ -3133,9 +3269,48 @@ static int count_rmaps(struct kvm_vcpu *vcpu)
 	return nmaps;
 }
 
-static int count_writable_mappings(struct kvm_vcpu *vcpu)
+void inspect_spte_has_rmap(struct kvm *kvm, struct kvm_mmu_page *sp, u64 *sptep)
+{
+	unsigned long *rmapp;
+	struct kvm_mmu_page *rev_sp;
+	gfn_t gfn;
+
+	if (*sptep & PT_WRITABLE_MASK) {
+		rev_sp = page_header(__pa(sptep));
+		gfn = rev_sp->gfns[sptep - rev_sp->spt];
+
+		if (!gfn_to_memslot(kvm, gfn)) {
+			if (!printk_ratelimit())
+				return;
+			printk(KERN_ERR "%s: no memslot for gfn %ld\n",
+					 audit_msg, gfn);
+			printk(KERN_ERR "%s: index %ld of sp (gfn=%lx)\n",
+					audit_msg, sptep - rev_sp->spt,
+					rev_sp->gfn);
+			dump_stack();
+			return;
+		}
+
+		rmapp = gfn_to_rmap(kvm, rev_sp->gfns[sptep - rev_sp->spt],
+				    is_large_pte(*sptep));
+		if (!*rmapp) {
+			if (!printk_ratelimit())
+				return;
+			printk(KERN_ERR "%s: no rmap for writable spte %llx\n",
+					 audit_msg, *sptep);
+			dump_stack();
+		}
+	}
+
+}
+
+void audit_writable_sptes_have_rmaps(struct kvm_vcpu *vcpu)
+{
+	mmu_spte_walk(vcpu, inspect_spte_has_rmap);
+}
+
+static void check_writable_mappings_rmap(struct kvm_vcpu *vcpu)
 {
-	int nmaps = 0;
 	struct kvm_mmu_page *sp;
 	int i;
 
@@ -3152,20 +3327,16 @@ static int count_writable_mappings(struct kvm_vcpu *vcpu)
 				continue;
 			if (!(ent & PT_WRITABLE_MASK))
 				continue;
-			++nmaps;
+			inspect_spte_has_rmap(vcpu->kvm, sp, &pt[i]);
 		}
 	}
-	return nmaps;
+	return;
 }
 
 static void audit_rmap(struct kvm_vcpu *vcpu)
 {
-	int n_rmap = count_rmaps(vcpu);
-	int n_actual = count_writable_mappings(vcpu);
-
-	if (n_rmap != n_actual)
-		printk(KERN_ERR "%s: (%s) rmap %d actual %d\n",
-		       __func__, audit_msg, n_rmap, n_actual);
+	check_writable_mappings_rmap(vcpu);
+	count_rmaps(vcpu);
 }
 
 static void audit_write_protection(struct kvm_vcpu *vcpu)
@@ -3173,20 +3344,28 @@ static void audit_write_protection(struct kvm_vcpu *vcpu)
 	struct kvm_mmu_page *sp;
 	struct kvm_memory_slot *slot;
 	unsigned long *rmapp;
+	u64 *spte;
 	gfn_t gfn;
 
 	list_for_each_entry(sp, &vcpu->kvm->arch.active_mmu_pages, link) {
 		if (sp->role.direct)
 			continue;
+		if (sp->unsync)
+			continue;
 
 		gfn = unalias_gfn(vcpu->kvm, sp->gfn);
 		slot = gfn_to_memslot_unaliased(vcpu->kvm, sp->gfn);
 		rmapp = &slot->rmap[gfn - slot->base_gfn];
-		if (*rmapp)
-			printk(KERN_ERR "%s: (%s) shadow page has writable"
-			       " mappings: gfn %lx role %x\n",
+
+		spte = rmap_next(vcpu->kvm, rmapp, NULL);
+		while (spte) {
+			if (*spte & PT_WRITABLE_MASK)
+				printk(KERN_ERR "%s: (%s) shadow page has "
+				"writable mappings: gfn %lx role %x\n",
 			       __func__, audit_msg, sp->gfn,
 			       sp->role.word);
+			spte = rmap_next(vcpu->kvm, rmapp, spte);
+		}
 	}
 }
 
@@ -3198,7 +3377,9 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg)
 	audit_msg = msg;
 	audit_rmap(vcpu);
 	audit_write_protection(vcpu);
-	audit_mappings(vcpu);
+	if (strcmp("pre pte write", audit_msg) != 0)
+		audit_mappings(vcpu);
+	audit_writable_sptes_have_rmaps(vcpu);
 	dbg = olddbg;
 }
 
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 3494a2f..61a1b38 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -37,6 +37,8 @@
 #define PT32_ROOT_LEVEL 2
 #define PT32E_ROOT_LEVEL 3
 
+int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]);
+
 static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
 {
 	if (unlikely(vcpu->kvm->arch.n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
@@ -75,7 +77,7 @@ static inline int is_paging(struct kvm_vcpu *vcpu)
 	return vcpu->arch.cr0 & X86_CR0_PG;
 }
 
-static inline int is_present_pte(unsigned long pte)
+static inline int is_present_gpte(unsigned long pte)
 {
 	return pte & PT_PRESENT_MASK;
 }
diff --git a/arch/x86/kvm/mmutrace.h b/arch/x86/kvm/mmutrace.h
new file mode 100644
index 0000000..3e4a5c6
--- /dev/null
+++ b/arch/x86/kvm/mmutrace.h
@@ -0,0 +1,220 @@
+#if !defined(_TRACE_KVMMMU_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVMMMU_H
+
+#include <linux/tracepoint.h>
+#include <linux/ftrace_event.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvmmmu
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE mmutrace
+
+#define KVM_MMU_PAGE_FIELDS \
+	__field(__u64, gfn) \
+	__field(__u32, role) \
+	__field(__u32, root_count) \
+	__field(__u32, unsync)
+
+#define KVM_MMU_PAGE_ASSIGN(sp)			     \
+	__entry->gfn = sp->gfn;			     \
+	__entry->role = sp->role.word;		     \
+	__entry->root_count = sp->root_count;        \
+	__entry->unsync = sp->unsync;
+
+#define KVM_MMU_PAGE_PRINTK() ({				        \
+	const char *ret = p->buffer + p->len;				\
+	static const char *access_str[] = {			        \
+		"---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux"  \
+	};							        \
+	union kvm_mmu_page_role role;				        \
+								        \
+	role.word = __entry->role;					\
+									\
+	trace_seq_printf(p, "sp gfn %llx %u/%u q%u%s %s%s %spge"	\
+			 " %snxe root %u %s%c",				\
+			 __entry->gfn, role.level, role.glevels,	\
+			 role.quadrant,					\
+			 role.direct ? " direct" : "",			\
+			 access_str[role.access],			\
+			 role.invalid ? " invalid" : "",		\
+			 role.cr4_pge ? "" : "!",			\
+			 role.nxe ? "" : "!",				\
+			 __entry->root_count,				\
+			 __entry->unsync ? "unsync" : "sync", 0);	\
+	ret;								\
+		})
+
+#define kvm_mmu_trace_pferr_flags       \
+	{ PFERR_PRESENT_MASK, "P" },	\
+	{ PFERR_WRITE_MASK, "W" },	\
+	{ PFERR_USER_MASK, "U" },	\
+	{ PFERR_RSVD_MASK, "RSVD" },	\
+	{ PFERR_FETCH_MASK, "F" }
+
+/*
+ * A pagetable walk has started
+ */
+TRACE_EVENT(
+	kvm_mmu_pagetable_walk,
+	TP_PROTO(u64 addr, int write_fault, int user_fault, int fetch_fault),
+	TP_ARGS(addr, write_fault, user_fault, fetch_fault),
+
+	TP_STRUCT__entry(
+		__field(__u64, addr)
+		__field(__u32, pferr)
+	),
+
+	TP_fast_assign(
+		__entry->addr = addr;
+		__entry->pferr = (!!write_fault << 1) | (!!user_fault << 2)
+		                 | (!!fetch_fault << 4);
+	),
+
+	TP_printk("addr %llx pferr %x %s", __entry->addr, __entry->pferr,
+		  __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags))
+);
+
+
+/* We just walked a paging element */
+TRACE_EVENT(
+	kvm_mmu_paging_element,
+	TP_PROTO(u64 pte, int level),
+	TP_ARGS(pte, level),
+
+	TP_STRUCT__entry(
+		__field(__u64, pte)
+		__field(__u32, level)
+		),
+
+	TP_fast_assign(
+		__entry->pte = pte;
+		__entry->level = level;
+		),
+
+	TP_printk("pte %llx level %u", __entry->pte, __entry->level)
+);
+
+/* We set a pte accessed bit */
+TRACE_EVENT(
+	kvm_mmu_set_accessed_bit,
+	TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size),
+	TP_ARGS(table_gfn, index, size),
+
+	TP_STRUCT__entry(
+		__field(__u64, gpa)
+		),
+
+	TP_fast_assign(
+		__entry->gpa = ((u64)table_gfn << PAGE_SHIFT)
+				+ index * size;
+		),
+
+	TP_printk("gpa %llx", __entry->gpa)
+);
+
+/* We set a pte dirty bit */
+TRACE_EVENT(
+	kvm_mmu_set_dirty_bit,
+	TP_PROTO(unsigned long table_gfn, unsigned index, unsigned size),
+	TP_ARGS(table_gfn, index, size),
+
+	TP_STRUCT__entry(
+		__field(__u64, gpa)
+		),
+
+	TP_fast_assign(
+		__entry->gpa = ((u64)table_gfn << PAGE_SHIFT)
+				+ index * size;
+		),
+
+	TP_printk("gpa %llx", __entry->gpa)
+);
+
+TRACE_EVENT(
+	kvm_mmu_walker_error,
+	TP_PROTO(u32 pferr),
+	TP_ARGS(pferr),
+
+	TP_STRUCT__entry(
+		__field(__u32, pferr)
+		),
+
+	TP_fast_assign(
+		__entry->pferr = pferr;
+		),
+
+	TP_printk("pferr %x %s", __entry->pferr,
+		  __print_flags(__entry->pferr, "|", kvm_mmu_trace_pferr_flags))
+);
+
+TRACE_EVENT(
+	kvm_mmu_get_page,
+	TP_PROTO(struct kvm_mmu_page *sp, bool created),
+	TP_ARGS(sp, created),
+
+	TP_STRUCT__entry(
+		KVM_MMU_PAGE_FIELDS
+		__field(bool, created)
+		),
+
+	TP_fast_assign(
+		KVM_MMU_PAGE_ASSIGN(sp)
+		__entry->created = created;
+		),
+
+	TP_printk("%s %s", KVM_MMU_PAGE_PRINTK(),
+		  __entry->created ? "new" : "existing")
+);
+
+TRACE_EVENT(
+	kvm_mmu_sync_page,
+	TP_PROTO(struct kvm_mmu_page *sp),
+	TP_ARGS(sp),
+
+	TP_STRUCT__entry(
+		KVM_MMU_PAGE_FIELDS
+		),
+
+	TP_fast_assign(
+		KVM_MMU_PAGE_ASSIGN(sp)
+		),
+
+	TP_printk("%s", KVM_MMU_PAGE_PRINTK())
+);
+
+TRACE_EVENT(
+	kvm_mmu_unsync_page,
+	TP_PROTO(struct kvm_mmu_page *sp),
+	TP_ARGS(sp),
+
+	TP_STRUCT__entry(
+		KVM_MMU_PAGE_FIELDS
+		),
+
+	TP_fast_assign(
+		KVM_MMU_PAGE_ASSIGN(sp)
+		),
+
+	TP_printk("%s", KVM_MMU_PAGE_PRINTK())
+);
+
+TRACE_EVENT(
+	kvm_mmu_zap_page,
+	TP_PROTO(struct kvm_mmu_page *sp),
+	TP_ARGS(sp),
+
+	TP_STRUCT__entry(
+		KVM_MMU_PAGE_FIELDS
+		),
+
+	TP_fast_assign(
+		KVM_MMU_PAGE_ASSIGN(sp)
+		),
+
+	TP_printk("%s", KVM_MMU_PAGE_PRINTK())
+);
+
+#endif /* _TRACE_KVMMMU_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 67785f6..d2fec9c 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -27,7 +27,8 @@
 	#define guest_walker guest_walker64
 	#define FNAME(name) paging##64_##name
 	#define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
-	#define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
+	#define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl)
+	#define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl)
 	#define PT_INDEX(addr, level) PT64_INDEX(addr, level)
 	#define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
 	#define PT_LEVEL_BITS PT64_LEVEL_BITS
@@ -43,7 +44,8 @@
 	#define guest_walker guest_walker32
 	#define FNAME(name) paging##32_##name
 	#define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
-	#define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
+	#define PT_LVL_ADDR_MASK(lvl) PT32_LVL_ADDR_MASK(lvl)
+	#define PT_LVL_OFFSET_MASK(lvl) PT32_LVL_OFFSET_MASK(lvl)
 	#define PT_INDEX(addr, level) PT32_INDEX(addr, level)
 	#define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
 	#define PT_LEVEL_BITS PT32_LEVEL_BITS
@@ -53,8 +55,8 @@
 	#error Invalid PTTYPE value
 #endif
 
-#define gpte_to_gfn FNAME(gpte_to_gfn)
-#define gpte_to_gfn_pde FNAME(gpte_to_gfn_pde)
+#define gpte_to_gfn_lvl FNAME(gpte_to_gfn_lvl)
+#define gpte_to_gfn(pte) gpte_to_gfn_lvl((pte), PT_PAGE_TABLE_LEVEL)
 
 /*
  * The guest_walker structure emulates the behavior of the hardware page
@@ -71,14 +73,9 @@ struct guest_walker {
 	u32 error_code;
 };
 
-static gfn_t gpte_to_gfn(pt_element_t gpte)
+static gfn_t gpte_to_gfn_lvl(pt_element_t gpte, int lvl)
 {
-	return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
-}
-
-static gfn_t gpte_to_gfn_pde(pt_element_t gpte)
-{
-	return (gpte & PT_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
+	return (gpte & PT_LVL_ADDR_MASK(lvl)) >> PAGE_SHIFT;
 }
 
 static bool FNAME(cmpxchg_gpte)(struct kvm *kvm,
@@ -125,14 +122,16 @@ static int FNAME(walk_addr)(struct guest_walker *walker,
 	gpa_t pte_gpa;
 	int rsvd_fault = 0;
 
-	pgprintk("%s: addr %lx\n", __func__, addr);
+	trace_kvm_mmu_pagetable_walk(addr, write_fault, user_fault,
+				     fetch_fault);
 walk:
 	walker->level = vcpu->arch.mmu.root_level;
 	pte = vcpu->arch.cr3;
 #if PTTYPE == 64
 	if (!is_long_mode(vcpu)) {
-		pte = vcpu->arch.pdptrs[(addr >> 30) & 3];
-		if (!is_present_pte(pte))
+		pte = kvm_pdptr_read(vcpu, (addr >> 30) & 3);
+		trace_kvm_mmu_paging_element(pte, walker->level);
+		if (!is_present_gpte(pte))
 			goto not_present;
 		--walker->level;
 	}
@@ -150,12 +149,11 @@ walk:
 		pte_gpa += index * sizeof(pt_element_t);
 		walker->table_gfn[walker->level - 1] = table_gfn;
 		walker->pte_gpa[walker->level - 1] = pte_gpa;
-		pgprintk("%s: table_gfn[%d] %lx\n", __func__,
-			 walker->level - 1, table_gfn);
 
 		kvm_read_guest(vcpu->kvm, pte_gpa, &pte, sizeof(pte));
+		trace_kvm_mmu_paging_element(pte, walker->level);
 
-		if (!is_present_pte(pte))
+		if (!is_present_gpte(pte))
 			goto not_present;
 
 		rsvd_fault = is_rsvd_bits_set(vcpu, pte, walker->level);
@@ -175,6 +173,8 @@ walk:
 #endif
 
 		if (!(pte & PT_ACCESSED_MASK)) {
+			trace_kvm_mmu_set_accessed_bit(table_gfn, index,
+						       sizeof(pte));
 			mark_page_dirty(vcpu->kvm, table_gfn);
 			if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn,
 			    index, pte, pte|PT_ACCESSED_MASK))
@@ -186,18 +186,24 @@ walk:
 
 		walker->ptes[walker->level - 1] = pte;
 
-		if (walker->level == PT_PAGE_TABLE_LEVEL) {
-			walker->gfn = gpte_to_gfn(pte);
-			break;
-		}
-
-		if (walker->level == PT_DIRECTORY_LEVEL
-		    && (pte & PT_PAGE_SIZE_MASK)
-		    && (PTTYPE == 64 || is_pse(vcpu))) {
-			walker->gfn = gpte_to_gfn_pde(pte);
-			walker->gfn += PT_INDEX(addr, PT_PAGE_TABLE_LEVEL);
-			if (PTTYPE == 32 && is_cpuid_PSE36())
+		if ((walker->level == PT_PAGE_TABLE_LEVEL) ||
+		    ((walker->level == PT_DIRECTORY_LEVEL) &&
+				(pte & PT_PAGE_SIZE_MASK)  &&
+				(PTTYPE == 64 || is_pse(vcpu))) ||
+		    ((walker->level == PT_PDPE_LEVEL) &&
+				(pte & PT_PAGE_SIZE_MASK)  &&
+				is_long_mode(vcpu))) {
+			int lvl = walker->level;
+
+			walker->gfn = gpte_to_gfn_lvl(pte, lvl);
+			walker->gfn += (addr & PT_LVL_OFFSET_MASK(lvl))
+					>> PAGE_SHIFT;
+
+			if (PTTYPE == 32 &&
+			    walker->level == PT_DIRECTORY_LEVEL &&
+			    is_cpuid_PSE36())
 				walker->gfn += pse36_gfn_delta(pte);
+
 			break;
 		}
 
@@ -205,9 +211,10 @@ walk:
 		--walker->level;
 	}
 
-	if (write_fault && !is_dirty_pte(pte)) {
+	if (write_fault && !is_dirty_gpte(pte)) {
 		bool ret;
 
+		trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte));
 		mark_page_dirty(vcpu->kvm, table_gfn);
 		ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte,
 			    pte|PT_DIRTY_MASK);
@@ -239,6 +246,7 @@ err:
 		walker->error_code |= PFERR_FETCH_MASK;
 	if (rsvd_fault)
 		walker->error_code |= PFERR_RSVD_MASK;
+	trace_kvm_mmu_walker_error(walker->error_code);
 	return 0;
 }
 
@@ -248,12 +256,11 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
 	pt_element_t gpte;
 	unsigned pte_access;
 	pfn_t pfn;
-	int largepage = vcpu->arch.update_pte.largepage;
 
 	gpte = *(const pt_element_t *)pte;
 	if (~gpte & (PT_PRESENT_MASK | PT_ACCESSED_MASK)) {
-		if (!is_present_pte(gpte))
-			set_shadow_pte(spte, shadow_notrap_nonpresent_pte);
+		if (!is_present_gpte(gpte))
+			__set_spte(spte, shadow_notrap_nonpresent_pte);
 		return;
 	}
 	pgprintk("%s: gpte %llx spte %p\n", __func__, (u64)gpte, spte);
@@ -267,7 +274,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
 		return;
 	kvm_get_pfn(pfn);
 	mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
-		     gpte & PT_DIRTY_MASK, NULL, largepage,
+		     gpte & PT_DIRTY_MASK, NULL, PT_PAGE_TABLE_LEVEL,
 		     gpte_to_gfn(gpte), pfn, true);
 }
 
@@ -276,7 +283,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
  */
 static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
 			 struct guest_walker *gw,
-			 int user_fault, int write_fault, int largepage,
+			 int user_fault, int write_fault, int hlevel,
 			 int *ptwrite, pfn_t pfn)
 {
 	unsigned access = gw->pt_access;
@@ -289,19 +296,18 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
 	pt_element_t curr_pte;
 	struct kvm_shadow_walk_iterator iterator;
 
-	if (!is_present_pte(gw->ptes[gw->level - 1]))
+	if (!is_present_gpte(gw->ptes[gw->level - 1]))
 		return NULL;
 
 	for_each_shadow_entry(vcpu, addr, iterator) {
 		level = iterator.level;
 		sptep = iterator.sptep;
-		if (level == PT_PAGE_TABLE_LEVEL
-		    || (largepage && level == PT_DIRECTORY_LEVEL)) {
+		if (iterator.level == hlevel) {
 			mmu_set_spte(vcpu, sptep, access,
 				     gw->pte_access & access,
 				     user_fault, write_fault,
 				     gw->ptes[gw->level-1] & PT_DIRTY_MASK,
-				     ptwrite, largepage,
+				     ptwrite, level,
 				     gw->gfn, pfn, false);
 			break;
 		}
@@ -311,16 +317,19 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
 
 		if (is_large_pte(*sptep)) {
 			rmap_remove(vcpu->kvm, sptep);
-			set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+			__set_spte(sptep, shadow_trap_nonpresent_pte);
 			kvm_flush_remote_tlbs(vcpu->kvm);
 		}
 
-		if (level == PT_DIRECTORY_LEVEL
-		    && gw->level == PT_DIRECTORY_LEVEL) {
+		if (level <= gw->level) {
+			int delta = level - gw->level + 1;
 			direct = 1;
-			if (!is_dirty_pte(gw->ptes[level - 1]))
+			if (!is_dirty_gpte(gw->ptes[level - delta]))
 				access &= ~ACC_WRITE_MASK;
-			table_gfn = gpte_to_gfn(gw->ptes[level - 1]);
+			table_gfn = gpte_to_gfn(gw->ptes[level - delta]);
+			/* advance table_gfn when emulating 1gb pages with 4k */
+			if (delta == 0)
+				table_gfn += PT_INDEX(addr, level);
 		} else {
 			direct = 0;
 			table_gfn = gw->table_gfn[level - 2];
@@ -369,11 +378,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
 	int user_fault = error_code & PFERR_USER_MASK;
 	int fetch_fault = error_code & PFERR_FETCH_MASK;
 	struct guest_walker walker;
-	u64 *shadow_pte;
+	u64 *sptep;
 	int write_pt = 0;
 	int r;
 	pfn_t pfn;
-	int largepage = 0;
+	int level = PT_PAGE_TABLE_LEVEL;
 	unsigned long mmu_seq;
 
 	pgprintk("%s: addr %lx err %x\n", __func__, addr, error_code);
@@ -399,14 +408,11 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
 		return 0;
 	}
 
-	if (walker.level == PT_DIRECTORY_LEVEL) {
-		gfn_t large_gfn;
-		large_gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE-1);
-		if (is_largepage_backed(vcpu, large_gfn)) {
-			walker.gfn = large_gfn;
-			largepage = 1;
-		}
+	if (walker.level >= PT_DIRECTORY_LEVEL) {
+		level = min(walker.level, mapping_level(vcpu, walker.gfn));
+		walker.gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE(level) - 1);
 	}
+
 	mmu_seq = vcpu->kvm->mmu_notifier_seq;
 	smp_rmb();
 	pfn = gfn_to_pfn(vcpu->kvm, walker.gfn);
@@ -422,11 +428,10 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
 	if (mmu_notifier_retry(vcpu, mmu_seq))
 		goto out_unlock;
 	kvm_mmu_free_some_pages(vcpu);
-	shadow_pte = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
-				  largepage, &write_pt, pfn);
-
+	sptep = FNAME(fetch)(vcpu, addr, &walker, user_fault, write_fault,
+			     level, &write_pt, pfn);
 	pgprintk("%s: shadow pte %p %llx ptwrite %d\n", __func__,
-		 shadow_pte, *shadow_pte, write_pt);
+		 sptep, *sptep, write_pt);
 
 	if (!write_pt)
 		vcpu->arch.last_pt_write_count = 0; /* reset fork detector */
@@ -459,8 +464,9 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
 		sptep = iterator.sptep;
 
 		/* FIXME: properly handle invlpg on large guest pages */
-		if (level == PT_PAGE_TABLE_LEVEL ||
-		    ((level == PT_DIRECTORY_LEVEL) && is_large_pte(*sptep))) {
+		if (level == PT_PAGE_TABLE_LEVEL  ||
+		    ((level == PT_DIRECTORY_LEVEL && is_large_pte(*sptep))) ||
+		    ((level == PT_PDPE_LEVEL && is_large_pte(*sptep)))) {
 			struct kvm_mmu_page *sp = page_header(__pa(sptep));
 
 			pte_gpa = (sp->gfn << PAGE_SHIFT);
@@ -472,7 +478,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
 					--vcpu->kvm->stat.lpages;
 				need_flush = 1;
 			}
-			set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+			__set_spte(sptep, shadow_trap_nonpresent_pte);
 			break;
 		}
 
@@ -489,7 +495,7 @@ static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
 	if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
 				  sizeof(pt_element_t)))
 		return;
-	if (is_present_pte(gpte) && (gpte & PT_ACCESSED_MASK)) {
+	if (is_present_gpte(gpte) && (gpte & PT_ACCESSED_MASK)) {
 		if (mmu_topup_memory_caches(vcpu))
 			return;
 		kvm_mmu_pte_write(vcpu, pte_gpa, (const u8 *)&gpte,
@@ -536,7 +542,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
 		r = kvm_read_guest_atomic(vcpu->kvm, pte_gpa, pt, sizeof pt);
 		pte_gpa += ARRAY_SIZE(pt) * sizeof(pt_element_t);
 		for (j = 0; j < ARRAY_SIZE(pt); ++j)
-			if (r || is_present_pte(pt[j]))
+			if (r || is_present_gpte(pt[j]))
 				sp->spt[i+j] = shadow_trap_nonpresent_pte;
 			else
 				sp->spt[i+j] = shadow_notrap_nonpresent_pte;
@@ -574,23 +580,23 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
 					  sizeof(pt_element_t)))
 			return -EINVAL;
 
-		if (gpte_to_gfn(gpte) != gfn || !is_present_pte(gpte) ||
+		if (gpte_to_gfn(gpte) != gfn || !is_present_gpte(gpte) ||
 		    !(gpte & PT_ACCESSED_MASK)) {
 			u64 nonpresent;
 
 			rmap_remove(vcpu->kvm, &sp->spt[i]);
-			if (is_present_pte(gpte))
+			if (is_present_gpte(gpte))
 				nonpresent = shadow_trap_nonpresent_pte;
 			else
 				nonpresent = shadow_notrap_nonpresent_pte;
-			set_shadow_pte(&sp->spt[i], nonpresent);
+			__set_spte(&sp->spt[i], nonpresent);
 			continue;
 		}
 
 		nr_present++;
 		pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
 		set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
-			 is_dirty_pte(gpte), 0, gfn,
+			 is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn,
 			 spte_to_pfn(sp->spt[i]), true, false);
 	}
 
@@ -603,9 +609,10 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
 #undef PT_BASE_ADDR_MASK
 #undef PT_INDEX
 #undef PT_LEVEL_MASK
-#undef PT_DIR_BASE_ADDR_MASK
+#undef PT_LVL_ADDR_MASK
+#undef PT_LVL_OFFSET_MASK
 #undef PT_LEVEL_BITS
 #undef PT_MAX_FULL_LEVELS
 #undef gpte_to_gfn
-#undef gpte_to_gfn_pde
+#undef gpte_to_gfn_lvl
 #undef CMPXCHG
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index b1f658a..944cc9c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -15,7 +15,6 @@
  */
 #include <linux/kvm_host.h>
 
-#include "kvm_svm.h"
 #include "irq.h"
 #include "mmu.h"
 #include "kvm_cache_regs.h"
@@ -26,10 +25,12 @@
 #include <linux/vmalloc.h>
 #include <linux/highmem.h>
 #include <linux/sched.h>
+#include <linux/ftrace_event.h>
 
 #include <asm/desc.h>
 
 #include <asm/virtext.h>
+#include "trace.h"
 
 #define __ex(x) __kvm_handle_fault_on_reboot(x)
 
@@ -46,6 +47,10 @@ MODULE_LICENSE("GPL");
 #define SVM_FEATURE_LBRV (1 << 1)
 #define SVM_FEATURE_SVML (1 << 2)
 
+#define NESTED_EXIT_HOST	0	/* Exit handled on host level */
+#define NESTED_EXIT_DONE	1	/* Exit caused nested vmexit  */
+#define NESTED_EXIT_CONTINUE	2	/* Further checks needed      */
+
 #define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
 
 /* Turn on to get debugging output*/
@@ -57,6 +62,58 @@ MODULE_LICENSE("GPL");
 #define nsvm_printk(fmt, args...) do {} while(0)
 #endif
 
+static const u32 host_save_user_msrs[] = {
+#ifdef CONFIG_X86_64
+	MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE,
+	MSR_FS_BASE,
+#endif
+	MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
+};
+
+#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
+
+struct kvm_vcpu;
+
+struct nested_state {
+	struct vmcb *hsave;
+	u64 hsave_msr;
+	u64 vmcb;
+
+	/* These are the merged vectors */
+	u32 *msrpm;
+
+	/* gpa pointers to the real vectors */
+	u64 vmcb_msrpm;
+
+	/* cache for intercepts of the guest */
+	u16 intercept_cr_read;
+	u16 intercept_cr_write;
+	u16 intercept_dr_read;
+	u16 intercept_dr_write;
+	u32 intercept_exceptions;
+	u64 intercept;
+
+};
+
+struct vcpu_svm {
+	struct kvm_vcpu vcpu;
+	struct vmcb *vmcb;
+	unsigned long vmcb_pa;
+	struct svm_cpu_data *svm_data;
+	uint64_t asid_generation;
+	uint64_t sysenter_esp;
+	uint64_t sysenter_eip;
+
+	u64 next_rip;
+
+	u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
+	u64 host_gs_base;
+
+	u32 *msrpm;
+
+	struct nested_state nested;
+};
+
 /* enable NPT for AMD64 and X86 with PAE */
 #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
 static bool npt_enabled = true;
@@ -67,15 +124,14 @@ static int npt = 1;
 
 module_param(npt, int, S_IRUGO);
 
-static int nested = 0;
+static int nested = 1;
 module_param(nested, int, S_IRUGO);
 
 static void svm_flush_tlb(struct kvm_vcpu *vcpu);
+static void svm_complete_interrupts(struct vcpu_svm *svm);
 
-static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override);
+static int nested_svm_exit_handled(struct vcpu_svm *svm);
 static int nested_svm_vmexit(struct vcpu_svm *svm);
-static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
-			     void *arg2, void *opaque);
 static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
 				      bool has_error_code, u32 error_code);
 
@@ -86,7 +142,22 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 
 static inline bool is_nested(struct vcpu_svm *svm)
 {
-	return svm->nested_vmcb;
+	return svm->nested.vmcb;
+}
+
+static inline void enable_gif(struct vcpu_svm *svm)
+{
+	svm->vcpu.arch.hflags |= HF_GIF_MASK;
+}
+
+static inline void disable_gif(struct vcpu_svm *svm)
+{
+	svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+}
+
+static inline bool gif_set(struct vcpu_svm *svm)
+{
+	return !!(svm->vcpu.arch.hflags & HF_GIF_MASK);
 }
 
 static unsigned long iopm_base;
@@ -147,19 +218,6 @@ static inline void invlpga(unsigned long addr, u32 asid)
 	asm volatile (__ex(SVM_INVLPGA) :: "a"(addr), "c"(asid));
 }
 
-static inline unsigned long kvm_read_cr2(void)
-{
-	unsigned long cr2;
-
-	asm volatile ("mov %%cr2, %0" : "=r" (cr2));
-	return cr2;
-}
-
-static inline void kvm_write_cr2(unsigned long val)
-{
-	asm volatile ("mov %0, %%cr2" :: "r" (val));
-}
-
 static inline void force_new_asid(struct kvm_vcpu *vcpu)
 {
 	to_svm(vcpu)->asid_generation--;
@@ -263,7 +321,7 @@ static void svm_hardware_enable(void *garbage)
 
 	struct svm_cpu_data *svm_data;
 	uint64_t efer;
-	struct desc_ptr gdt_descr;
+	struct descriptor_table gdt_descr;
 	struct desc_struct *gdt;
 	int me = raw_smp_processor_id();
 
@@ -283,8 +341,8 @@ static void svm_hardware_enable(void *garbage)
 	svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
 	svm_data->next_asid = svm_data->max_asid + 1;
 
-	asm volatile ("sgdt %0" : "=m"(gdt_descr));
-	gdt = (struct desc_struct *)gdt_descr.address;
+	kvm_get_gdt(&gdt_descr);
+	gdt = (struct desc_struct *)gdt_descr.base;
 	svm_data->tss_desc = (struct kvm_ldttss_desc *)(gdt + GDT_ENTRY_TSS);
 
 	rdmsrl(MSR_EFER, efer);
@@ -367,8 +425,6 @@ static void svm_vcpu_init_msrpm(u32 *msrpm)
 #endif
 	set_msr_interception(msrpm, MSR_K6_STAR, 1, 1);
 	set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1);
-	set_msr_interception(msrpm, MSR_IA32_SYSENTER_ESP, 1, 1);
-	set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1);
 }
 
 static void svm_enable_lbrv(struct vcpu_svm *svm)
@@ -595,8 +651,10 @@ static void init_vmcb(struct vcpu_svm *svm)
 	}
 	force_new_asid(&svm->vcpu);
 
-	svm->nested_vmcb = 0;
-	svm->vcpu.arch.hflags = HF_GIF_MASK;
+	svm->nested.vmcb = 0;
+	svm->vcpu.arch.hflags = 0;
+
+	enable_gif(svm);
 }
 
 static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
@@ -605,7 +663,7 @@ static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
 
 	init_vmcb(svm);
 
-	if (vcpu->vcpu_id != 0) {
+	if (!kvm_vcpu_is_bsp(vcpu)) {
 		kvm_rip_write(vcpu, 0);
 		svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12;
 		svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8;
@@ -656,9 +714,9 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
 	hsave_page = alloc_page(GFP_KERNEL);
 	if (!hsave_page)
 		goto uninit;
-	svm->hsave = page_address(hsave_page);
+	svm->nested.hsave = page_address(hsave_page);
 
-	svm->nested_msrpm = page_address(nested_msrpm_pages);
+	svm->nested.msrpm = page_address(nested_msrpm_pages);
 
 	svm->vmcb = page_address(page);
 	clear_page(svm->vmcb);
@@ -669,7 +727,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
 	fx_init(&svm->vcpu);
 	svm->vcpu.fpu_active = 1;
 	svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
-	if (svm->vcpu.vcpu_id == 0)
+	if (kvm_vcpu_is_bsp(&svm->vcpu))
 		svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP;
 
 	return &svm->vcpu;
@@ -688,8 +746,8 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
 
 	__free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
 	__free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
-	__free_page(virt_to_page(svm->hsave));
-	__free_pages(virt_to_page(svm->nested_msrpm), MSRPM_ALLOC_ORDER);
+	__free_page(virt_to_page(svm->nested.hsave));
+	__free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
 	kvm_vcpu_uninit(vcpu);
 	kmem_cache_free(kvm_vcpu_cache, svm);
 }
@@ -740,6 +798,18 @@ static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 	to_svm(vcpu)->vmcb->save.rflags = rflags;
 }
 
+static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
+{
+	switch (reg) {
+	case VCPU_EXREG_PDPTR:
+		BUG_ON(!npt_enabled);
+		load_pdptrs(vcpu, vcpu->arch.cr3);
+		break;
+	default:
+		BUG();
+	}
+}
+
 static void svm_set_vintr(struct vcpu_svm *svm)
 {
 	svm->vmcb->control.intercept |= 1ULL << INTERCEPT_VINTR;
@@ -1061,7 +1131,6 @@ static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
 		val = 0;
 	}
 
-	KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
 	return val;
 }
 
@@ -1070,8 +1139,6 @@ static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)value, handler);
-
 	*exception = 0;
 
 	switch (dr) {
@@ -1119,25 +1186,9 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 	fault_address  = svm->vmcb->control.exit_info_2;
 	error_code = svm->vmcb->control.exit_info_1;
 
-	if (!npt_enabled)
-		KVMTRACE_3D(PAGE_FAULT, &svm->vcpu, error_code,
-			    (u32)fault_address, (u32)(fault_address >> 32),
-			    handler);
-	else
-		KVMTRACE_3D(TDP_FAULT, &svm->vcpu, error_code,
-			    (u32)fault_address, (u32)(fault_address >> 32),
-			    handler);
-	/*
-	 * FIXME: Tis shouldn't be necessary here, but there is a flush
-	 * missing in the MMU code. Until we find this bug, flush the
-	 * complete TLB here on an NPF
-	 */
-	if (npt_enabled)
-		svm_flush_tlb(&svm->vcpu);
-	else {
-		if (kvm_event_needs_reinjection(&svm->vcpu))
-			kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
-	}
+	trace_kvm_page_fault(fault_address, error_code);
+	if (!npt_enabled && kvm_event_needs_reinjection(&svm->vcpu))
+		kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
 	return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
 }
 
@@ -1253,14 +1304,12 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 
 static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
-	KVMTRACE_0D(NMI, &svm->vcpu, handler);
 	return 1;
 }
 
 static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
 	++svm->vcpu.stat.irq_exits;
-	KVMTRACE_0D(INTR, &svm->vcpu, handler);
 	return 1;
 }
 
@@ -1303,44 +1352,39 @@ static int nested_svm_check_permissions(struct vcpu_svm *svm)
 static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
 				      bool has_error_code, u32 error_code)
 {
-	if (is_nested(svm)) {
-		svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
-		svm->vmcb->control.exit_code_hi = 0;
-		svm->vmcb->control.exit_info_1 = error_code;
-		svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
-		if (nested_svm_exit_handled(svm, false)) {
-			nsvm_printk("VMexit -> EXCP 0x%x\n", nr);
-
-			nested_svm_vmexit(svm);
-			return 1;
-		}
-	}
+	if (!is_nested(svm))
+		return 0;
 
-	return 0;
+	svm->vmcb->control.exit_code = SVM_EXIT_EXCP_BASE + nr;
+	svm->vmcb->control.exit_code_hi = 0;
+	svm->vmcb->control.exit_info_1 = error_code;
+	svm->vmcb->control.exit_info_2 = svm->vcpu.arch.cr2;
+
+	return nested_svm_exit_handled(svm);
 }
 
 static inline int nested_svm_intr(struct vcpu_svm *svm)
 {
-	if (is_nested(svm)) {
-		if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
-			return 0;
+	if (!is_nested(svm))
+		return 0;
 
-		if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
-			return 0;
+	if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
+		return 0;
 
-		svm->vmcb->control.exit_code = SVM_EXIT_INTR;
+	if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
+		return 0;
 
-		if (nested_svm_exit_handled(svm, false)) {
-			nsvm_printk("VMexit -> INTR\n");
-			nested_svm_vmexit(svm);
-			return 1;
-		}
+	svm->vmcb->control.exit_code = SVM_EXIT_INTR;
+
+	if (nested_svm_exit_handled(svm)) {
+		nsvm_printk("VMexit -> INTR\n");
+		return 1;
 	}
 
 	return 0;
 }
 
-static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa)
+static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, enum km_type idx)
 {
 	struct page *page;
 
@@ -1348,236 +1392,246 @@ static struct page *nested_svm_get_page(struct vcpu_svm *svm, u64 gpa)
 	page = gfn_to_page(svm->vcpu.kvm, gpa >> PAGE_SHIFT);
 	up_read(&current->mm->mmap_sem);
 
-	if (is_error_page(page)) {
-		printk(KERN_INFO "%s: could not find page at 0x%llx\n",
-		       __func__, gpa);
-		kvm_release_page_clean(page);
-		kvm_inject_gp(&svm->vcpu, 0);
-		return NULL;
-	}
-	return page;
+	if (is_error_page(page))
+		goto error;
+
+	return kmap_atomic(page, idx);
+
+error:
+	kvm_release_page_clean(page);
+	kvm_inject_gp(&svm->vcpu, 0);
+
+	return NULL;
 }
 
-static int nested_svm_do(struct vcpu_svm *svm,
-			 u64 arg1_gpa, u64 arg2_gpa, void *opaque,
-			 int (*handler)(struct vcpu_svm *svm,
-					void *arg1,
-					void *arg2,
-					void *opaque))
+static void nested_svm_unmap(void *addr, enum km_type idx)
 {
-	struct page *arg1_page;
-	struct page *arg2_page = NULL;
-	void *arg1;
-	void *arg2 = NULL;
-	int retval;
+	struct page *page;
 
-	arg1_page = nested_svm_get_page(svm, arg1_gpa);
-	if(arg1_page == NULL)
-		return 1;
+	if (!addr)
+		return;
 
-	if (arg2_gpa) {
-		arg2_page = nested_svm_get_page(svm, arg2_gpa);
-		if(arg2_page == NULL) {
-			kvm_release_page_clean(arg1_page);
-			return 1;
-		}
-	}
+	page = kmap_atomic_to_page(addr);
+
+	kunmap_atomic(addr, idx);
+	kvm_release_page_dirty(page);
+}
+
+static bool nested_svm_exit_handled_msr(struct vcpu_svm *svm)
+{
+	u32 param = svm->vmcb->control.exit_info_1 & 1;
+	u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
+	bool ret = false;
+	u32 t0, t1;
+	u8 *msrpm;
 
-	arg1 = kmap_atomic(arg1_page, KM_USER0);
-	if (arg2_gpa)
-		arg2 = kmap_atomic(arg2_page, KM_USER1);
+	if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT)))
+		return false;
 
-	retval = handler(svm, arg1, arg2, opaque);
+	msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
+
+	if (!msrpm)
+		goto out;
+
+	switch (msr) {
+	case 0 ... 0x1fff:
+		t0 = (msr * 2) % 8;
+		t1 = msr / 8;
+		break;
+	case 0xc0000000 ... 0xc0001fff:
+		t0 = (8192 + msr - 0xc0000000) * 2;
+		t1 = (t0 / 8);
+		t0 %= 8;
+		break;
+	case 0xc0010000 ... 0xc0011fff:
+		t0 = (16384 + msr - 0xc0010000) * 2;
+		t1 = (t0 / 8);
+		t0 %= 8;
+		break;
+	default:
+		ret = true;
+		goto out;
+	}
 
-	kunmap_atomic(arg1, KM_USER0);
-	if (arg2_gpa)
-		kunmap_atomic(arg2, KM_USER1);
+	ret = msrpm[t1] & ((1 << param) << t0);
 
-	kvm_release_page_dirty(arg1_page);
-	if (arg2_gpa)
-		kvm_release_page_dirty(arg2_page);
+out:
+	nested_svm_unmap(msrpm, KM_USER0);
 
-	return retval;
+	return ret;
 }
 
-static int nested_svm_exit_handled_real(struct vcpu_svm *svm,
-					void *arg1,
-					void *arg2,
-					void *opaque)
+static int nested_svm_exit_special(struct vcpu_svm *svm)
 {
-	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
-	bool kvm_overrides = *(bool *)opaque;
 	u32 exit_code = svm->vmcb->control.exit_code;
 
-	if (kvm_overrides) {
-		switch (exit_code) {
-		case SVM_EXIT_INTR:
-		case SVM_EXIT_NMI:
-			return 0;
+	switch (exit_code) {
+	case SVM_EXIT_INTR:
+	case SVM_EXIT_NMI:
+		return NESTED_EXIT_HOST;
 		/* For now we are always handling NPFs when using them */
-		case SVM_EXIT_NPF:
-			if (npt_enabled)
-				return 0;
-			break;
-		/* When we're shadowing, trap PFs */
-		case SVM_EXIT_EXCP_BASE + PF_VECTOR:
-			if (!npt_enabled)
-				return 0;
-			break;
-		default:
-			break;
-		}
+	case SVM_EXIT_NPF:
+		if (npt_enabled)
+			return NESTED_EXIT_HOST;
+		break;
+	/* When we're shadowing, trap PFs */
+	case SVM_EXIT_EXCP_BASE + PF_VECTOR:
+		if (!npt_enabled)
+			return NESTED_EXIT_HOST;
+		break;
+	default:
+		break;
 	}
 
+	return NESTED_EXIT_CONTINUE;
+}
+
+/*
+ * If this function returns true, this #vmexit was already handled
+ */
+static int nested_svm_exit_handled(struct vcpu_svm *svm)
+{
+	u32 exit_code = svm->vmcb->control.exit_code;
+	int vmexit = NESTED_EXIT_HOST;
+
 	switch (exit_code) {
+	case SVM_EXIT_MSR:
+		vmexit = nested_svm_exit_handled_msr(svm);
+		break;
 	case SVM_EXIT_READ_CR0 ... SVM_EXIT_READ_CR8: {
 		u32 cr_bits = 1 << (exit_code - SVM_EXIT_READ_CR0);
-		if (nested_vmcb->control.intercept_cr_read & cr_bits)
-			return 1;
+		if (svm->nested.intercept_cr_read & cr_bits)
+			vmexit = NESTED_EXIT_DONE;
 		break;
 	}
 	case SVM_EXIT_WRITE_CR0 ... SVM_EXIT_WRITE_CR8: {
 		u32 cr_bits = 1 << (exit_code - SVM_EXIT_WRITE_CR0);
-		if (nested_vmcb->control.intercept_cr_write & cr_bits)
-			return 1;
+		if (svm->nested.intercept_cr_write & cr_bits)
+			vmexit = NESTED_EXIT_DONE;
 		break;
 	}
 	case SVM_EXIT_READ_DR0 ... SVM_EXIT_READ_DR7: {
 		u32 dr_bits = 1 << (exit_code - SVM_EXIT_READ_DR0);
-		if (nested_vmcb->control.intercept_dr_read & dr_bits)
-			return 1;
+		if (svm->nested.intercept_dr_read & dr_bits)
+			vmexit = NESTED_EXIT_DONE;
 		break;
 	}
 	case SVM_EXIT_WRITE_DR0 ... SVM_EXIT_WRITE_DR7: {
 		u32 dr_bits = 1 << (exit_code - SVM_EXIT_WRITE_DR0);
-		if (nested_vmcb->control.intercept_dr_write & dr_bits)
-			return 1;
+		if (svm->nested.intercept_dr_write & dr_bits)
+			vmexit = NESTED_EXIT_DONE;
 		break;
 	}
 	case SVM_EXIT_EXCP_BASE ... SVM_EXIT_EXCP_BASE + 0x1f: {
 		u32 excp_bits = 1 << (exit_code - SVM_EXIT_EXCP_BASE);
-		if (nested_vmcb->control.intercept_exceptions & excp_bits)
-			return 1;
+		if (svm->nested.intercept_exceptions & excp_bits)
+			vmexit = NESTED_EXIT_DONE;
 		break;
 	}
 	default: {
 		u64 exit_bits = 1ULL << (exit_code - SVM_EXIT_INTR);
 		nsvm_printk("exit code: 0x%x\n", exit_code);
-		if (nested_vmcb->control.intercept & exit_bits)
-			return 1;
+		if (svm->nested.intercept & exit_bits)
+			vmexit = NESTED_EXIT_DONE;
 	}
 	}
 
-	return 0;
-}
-
-static int nested_svm_exit_handled_msr(struct vcpu_svm *svm,
-				       void *arg1, void *arg2,
-				       void *opaque)
-{
-	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
-	u8 *msrpm = (u8 *)arg2;
-        u32 t0, t1;
-	u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX];
-	u32 param = svm->vmcb->control.exit_info_1 & 1;
-
-	if (!(nested_vmcb->control.intercept & (1ULL << INTERCEPT_MSR_PROT)))
-		return 0;
-
-	switch(msr) {
-	case 0 ... 0x1fff:
-		t0 = (msr * 2) % 8;
-		t1 = msr / 8;
-		break;
-	case 0xc0000000 ... 0xc0001fff:
-		t0 = (8192 + msr - 0xc0000000) * 2;
-		t1 = (t0 / 8);
-		t0 %= 8;
-		break;
-	case 0xc0010000 ... 0xc0011fff:
-		t0 = (16384 + msr - 0xc0010000) * 2;
-		t1 = (t0 / 8);
-		t0 %= 8;
-		break;
-	default:
-		return 1;
-		break;
+	if (vmexit == NESTED_EXIT_DONE) {
+		nsvm_printk("#VMEXIT reason=%04x\n", exit_code);
+		nested_svm_vmexit(svm);
 	}
-	if (msrpm[t1] & ((1 << param) << t0))
-		return 1;
 
-	return 0;
+	return vmexit;
+}
+
+static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb)
+{
+	struct vmcb_control_area *dst  = &dst_vmcb->control;
+	struct vmcb_control_area *from = &from_vmcb->control;
+
+	dst->intercept_cr_read    = from->intercept_cr_read;
+	dst->intercept_cr_write   = from->intercept_cr_write;
+	dst->intercept_dr_read    = from->intercept_dr_read;
+	dst->intercept_dr_write   = from->intercept_dr_write;
+	dst->intercept_exceptions = from->intercept_exceptions;
+	dst->intercept            = from->intercept;
+	dst->iopm_base_pa         = from->iopm_base_pa;
+	dst->msrpm_base_pa        = from->msrpm_base_pa;
+	dst->tsc_offset           = from->tsc_offset;
+	dst->asid                 = from->asid;
+	dst->tlb_ctl              = from->tlb_ctl;
+	dst->int_ctl              = from->int_ctl;
+	dst->int_vector           = from->int_vector;
+	dst->int_state            = from->int_state;
+	dst->exit_code            = from->exit_code;
+	dst->exit_code_hi         = from->exit_code_hi;
+	dst->exit_info_1          = from->exit_info_1;
+	dst->exit_info_2          = from->exit_info_2;
+	dst->exit_int_info        = from->exit_int_info;
+	dst->exit_int_info_err    = from->exit_int_info_err;
+	dst->nested_ctl           = from->nested_ctl;
+	dst->event_inj            = from->event_inj;
+	dst->event_inj_err        = from->event_inj_err;
+	dst->nested_cr3           = from->nested_cr3;
+	dst->lbr_ctl              = from->lbr_ctl;
 }
 
-static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override)
+static int nested_svm_vmexit(struct vcpu_svm *svm)
 {
-	bool k = kvm_override;
-
-	switch (svm->vmcb->control.exit_code) {
-	case SVM_EXIT_MSR:
-		return nested_svm_do(svm, svm->nested_vmcb,
-				     svm->nested_vmcb_msrpm, NULL,
-				     nested_svm_exit_handled_msr);
-	default: break;
-	}
+	struct vmcb *nested_vmcb;
+	struct vmcb *hsave = svm->nested.hsave;
+	struct vmcb *vmcb = svm->vmcb;
 
-	return nested_svm_do(svm, svm->nested_vmcb, 0, &k,
-			     nested_svm_exit_handled_real);
-}
-
-static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1,
-				  void *arg2, void *opaque)
-{
-	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
-	struct vmcb *hsave = svm->hsave;
-	u64 nested_save[] = { nested_vmcb->save.cr0,
-			      nested_vmcb->save.cr3,
-			      nested_vmcb->save.cr4,
-			      nested_vmcb->save.efer,
-			      nested_vmcb->control.intercept_cr_read,
-			      nested_vmcb->control.intercept_cr_write,
-			      nested_vmcb->control.intercept_dr_read,
-			      nested_vmcb->control.intercept_dr_write,
-			      nested_vmcb->control.intercept_exceptions,
-			      nested_vmcb->control.intercept,
-			      nested_vmcb->control.msrpm_base_pa,
-			      nested_vmcb->control.iopm_base_pa,
-			      nested_vmcb->control.tsc_offset };
+	nested_vmcb = nested_svm_map(svm, svm->nested.vmcb, KM_USER0);
+	if (!nested_vmcb)
+		return 1;
 
 	/* Give the current vmcb to the guest */
-	memcpy(nested_vmcb, svm->vmcb, sizeof(struct vmcb));
-	nested_vmcb->save.cr0 = nested_save[0];
-	if (!npt_enabled)
-		nested_vmcb->save.cr3 = nested_save[1];
-	nested_vmcb->save.cr4 = nested_save[2];
-	nested_vmcb->save.efer = nested_save[3];
-	nested_vmcb->control.intercept_cr_read = nested_save[4];
-	nested_vmcb->control.intercept_cr_write = nested_save[5];
-	nested_vmcb->control.intercept_dr_read = nested_save[6];
-	nested_vmcb->control.intercept_dr_write = nested_save[7];
-	nested_vmcb->control.intercept_exceptions = nested_save[8];
-	nested_vmcb->control.intercept = nested_save[9];
-	nested_vmcb->control.msrpm_base_pa = nested_save[10];
-	nested_vmcb->control.iopm_base_pa = nested_save[11];
-	nested_vmcb->control.tsc_offset = nested_save[12];
+	disable_gif(svm);
+
+	nested_vmcb->save.es     = vmcb->save.es;
+	nested_vmcb->save.cs     = vmcb->save.cs;
+	nested_vmcb->save.ss     = vmcb->save.ss;
+	nested_vmcb->save.ds     = vmcb->save.ds;
+	nested_vmcb->save.gdtr   = vmcb->save.gdtr;
+	nested_vmcb->save.idtr   = vmcb->save.idtr;
+	if (npt_enabled)
+		nested_vmcb->save.cr3    = vmcb->save.cr3;
+	nested_vmcb->save.cr2    = vmcb->save.cr2;
+	nested_vmcb->save.rflags = vmcb->save.rflags;
+	nested_vmcb->save.rip    = vmcb->save.rip;
+	nested_vmcb->save.rsp    = vmcb->save.rsp;
+	nested_vmcb->save.rax    = vmcb->save.rax;
+	nested_vmcb->save.dr7    = vmcb->save.dr7;
+	nested_vmcb->save.dr6    = vmcb->save.dr6;
+	nested_vmcb->save.cpl    = vmcb->save.cpl;
+
+	nested_vmcb->control.int_ctl           = vmcb->control.int_ctl;
+	nested_vmcb->control.int_vector        = vmcb->control.int_vector;
+	nested_vmcb->control.int_state         = vmcb->control.int_state;
+	nested_vmcb->control.exit_code         = vmcb->control.exit_code;
+	nested_vmcb->control.exit_code_hi      = vmcb->control.exit_code_hi;
+	nested_vmcb->control.exit_info_1       = vmcb->control.exit_info_1;
+	nested_vmcb->control.exit_info_2       = vmcb->control.exit_info_2;
+	nested_vmcb->control.exit_int_info     = vmcb->control.exit_int_info;
+	nested_vmcb->control.exit_int_info_err = vmcb->control.exit_int_info_err;
+	nested_vmcb->control.tlb_ctl           = 0;
+	nested_vmcb->control.event_inj         = 0;
+	nested_vmcb->control.event_inj_err     = 0;
 
 	/* We always set V_INTR_MASKING and remember the old value in hflags */
 	if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
 		nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK;
 
-	if ((nested_vmcb->control.int_ctl & V_IRQ_MASK) &&
-	    (nested_vmcb->control.int_vector)) {
-		nsvm_printk("WARNING: IRQ 0x%x still enabled on #VMEXIT\n",
-				nested_vmcb->control.int_vector);
-	}
-
 	/* Restore the original control entries */
-	svm->vmcb->control = hsave->control;
+	copy_vmcb_control_area(vmcb, hsave);
 
 	/* Kill any pending exceptions */
 	if (svm->vcpu.arch.exception.pending == true)
 		nsvm_printk("WARNING: Pending Exception\n");
-	svm->vcpu.arch.exception.pending = false;
+
+	kvm_clear_exception_queue(&svm->vcpu);
+	kvm_clear_interrupt_queue(&svm->vcpu);
 
 	/* Restore selected save entries */
 	svm->vmcb->save.es = hsave->save.es;
@@ -1603,19 +1657,10 @@ static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1,
 	svm->vmcb->save.cpl = 0;
 	svm->vmcb->control.exit_int_info = 0;
 
-	svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
 	/* Exit nested SVM mode */
-	svm->nested_vmcb = 0;
+	svm->nested.vmcb = 0;
 
-	return 0;
-}
-
-static int nested_svm_vmexit(struct vcpu_svm *svm)
-{
-	nsvm_printk("VMexit\n");
-	if (nested_svm_do(svm, svm->nested_vmcb, 0,
-			  NULL, nested_svm_vmexit_real))
-		return 1;
+	nested_svm_unmap(nested_vmcb, KM_USER0);
 
 	kvm_mmu_reset_context(&svm->vcpu);
 	kvm_mmu_load(&svm->vcpu);
@@ -1623,38 +1668,63 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
 	return 0;
 }
 
-static int nested_svm_vmrun_msrpm(struct vcpu_svm *svm, void *arg1,
-				  void *arg2, void *opaque)
+static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
 {
+	u32 *nested_msrpm;
 	int i;
-	u32 *nested_msrpm = (u32*)arg1;
+
+	nested_msrpm = nested_svm_map(svm, svm->nested.vmcb_msrpm, KM_USER0);
+	if (!nested_msrpm)
+		return false;
+
 	for (i=0; i< PAGE_SIZE * (1 << MSRPM_ALLOC_ORDER) / 4; i++)
-		svm->nested_msrpm[i] = svm->msrpm[i] | nested_msrpm[i];
-	svm->vmcb->control.msrpm_base_pa = __pa(svm->nested_msrpm);
+		svm->nested.msrpm[i] = svm->msrpm[i] | nested_msrpm[i];
 
-	return 0;
+	svm->vmcb->control.msrpm_base_pa = __pa(svm->nested.msrpm);
+
+	nested_svm_unmap(nested_msrpm, KM_USER0);
+
+	return true;
 }
 
-static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
-			    void *arg2, void *opaque)
+static bool nested_svm_vmrun(struct vcpu_svm *svm)
 {
-	struct vmcb *nested_vmcb = (struct vmcb *)arg1;
-	struct vmcb *hsave = svm->hsave;
+	struct vmcb *nested_vmcb;
+	struct vmcb *hsave = svm->nested.hsave;
+	struct vmcb *vmcb = svm->vmcb;
+
+	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+	if (!nested_vmcb)
+		return false;
 
 	/* nested_vmcb is our indicator if nested SVM is activated */
-	svm->nested_vmcb = svm->vmcb->save.rax;
+	svm->nested.vmcb = svm->vmcb->save.rax;
 
 	/* Clear internal status */
-	svm->vcpu.arch.exception.pending = false;
+	kvm_clear_exception_queue(&svm->vcpu);
+	kvm_clear_interrupt_queue(&svm->vcpu);
 
 	/* Save the old vmcb, so we don't need to pick what we save, but
 	   can restore everything when a VMEXIT occurs */
-	memcpy(hsave, svm->vmcb, sizeof(struct vmcb));
-	/* We need to remember the original CR3 in the SPT case */
-	if (!npt_enabled)
-		hsave->save.cr3 = svm->vcpu.arch.cr3;
-	hsave->save.cr4 = svm->vcpu.arch.cr4;
-	hsave->save.rip = svm->next_rip;
+	hsave->save.es     = vmcb->save.es;
+	hsave->save.cs     = vmcb->save.cs;
+	hsave->save.ss     = vmcb->save.ss;
+	hsave->save.ds     = vmcb->save.ds;
+	hsave->save.gdtr   = vmcb->save.gdtr;
+	hsave->save.idtr   = vmcb->save.idtr;
+	hsave->save.efer   = svm->vcpu.arch.shadow_efer;
+	hsave->save.cr0    = svm->vcpu.arch.cr0;
+	hsave->save.cr4    = svm->vcpu.arch.cr4;
+	hsave->save.rflags = vmcb->save.rflags;
+	hsave->save.rip    = svm->next_rip;
+	hsave->save.rsp    = vmcb->save.rsp;
+	hsave->save.rax    = vmcb->save.rax;
+	if (npt_enabled)
+		hsave->save.cr3    = vmcb->save.cr3;
+	else
+		hsave->save.cr3    = svm->vcpu.arch.cr3;
+
+	copy_vmcb_control_area(hsave, vmcb);
 
 	if (svm->vmcb->save.rflags & X86_EFLAGS_IF)
 		svm->vcpu.arch.hflags |= HF_HIF_MASK;
@@ -1679,7 +1749,7 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
 		kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3);
 		kvm_mmu_reset_context(&svm->vcpu);
 	}
-	svm->vmcb->save.cr2 = nested_vmcb->save.cr2;
+	svm->vmcb->save.cr2 = svm->vcpu.arch.cr2 = nested_vmcb->save.cr2;
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, nested_vmcb->save.rax);
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, nested_vmcb->save.rsp);
 	kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, nested_vmcb->save.rip);
@@ -1706,7 +1776,15 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
 
 	svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
 
-	svm->nested_vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;
+	svm->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;
+
+	/* cache intercepts */
+	svm->nested.intercept_cr_read    = nested_vmcb->control.intercept_cr_read;
+	svm->nested.intercept_cr_write   = nested_vmcb->control.intercept_cr_write;
+	svm->nested.intercept_dr_read    = nested_vmcb->control.intercept_dr_read;
+	svm->nested.intercept_dr_write   = nested_vmcb->control.intercept_dr_write;
+	svm->nested.intercept_exceptions = nested_vmcb->control.intercept_exceptions;
+	svm->nested.intercept            = nested_vmcb->control.intercept;
 
 	force_new_asid(&svm->vcpu);
 	svm->vmcb->control.exit_int_info = nested_vmcb->control.exit_int_info;
@@ -1734,12 +1812,14 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1,
 	svm->vmcb->control.event_inj = nested_vmcb->control.event_inj;
 	svm->vmcb->control.event_inj_err = nested_vmcb->control.event_inj_err;
 
-	svm->vcpu.arch.hflags |= HF_GIF_MASK;
+	nested_svm_unmap(nested_vmcb, KM_USER0);
 
-	return 0;
+	enable_gif(svm);
+
+	return true;
 }
 
-static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
+static void nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
 {
 	to_vmcb->save.fs = from_vmcb->save.fs;
 	to_vmcb->save.gs = from_vmcb->save.gs;
@@ -1753,44 +1833,44 @@ static int nested_svm_vmloadsave(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
 	to_vmcb->save.sysenter_cs = from_vmcb->save.sysenter_cs;
 	to_vmcb->save.sysenter_esp = from_vmcb->save.sysenter_esp;
 	to_vmcb->save.sysenter_eip = from_vmcb->save.sysenter_eip;
-
-	return 1;
-}
-
-static int nested_svm_vmload(struct vcpu_svm *svm, void *nested_vmcb,
-			     void *arg2, void *opaque)
-{
-	return nested_svm_vmloadsave((struct vmcb *)nested_vmcb, svm->vmcb);
-}
-
-static int nested_svm_vmsave(struct vcpu_svm *svm, void *nested_vmcb,
-			     void *arg2, void *opaque)
-{
-	return nested_svm_vmloadsave(svm->vmcb, (struct vmcb *)nested_vmcb);
 }
 
 static int vmload_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
+	struct vmcb *nested_vmcb;
+
 	if (nested_svm_check_permissions(svm))
 		return 1;
 
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
 
-	nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmload);
+	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+	if (!nested_vmcb)
+		return 1;
+
+	nested_svm_vmloadsave(nested_vmcb, svm->vmcb);
+	nested_svm_unmap(nested_vmcb, KM_USER0);
 
 	return 1;
 }
 
 static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
+	struct vmcb *nested_vmcb;
+
 	if (nested_svm_check_permissions(svm))
 		return 1;
 
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
 
-	nested_svm_do(svm, svm->vmcb->save.rax, 0, NULL, nested_svm_vmsave);
+	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, KM_USER0);
+	if (!nested_vmcb)
+		return 1;
+
+	nested_svm_vmloadsave(svm->vmcb, nested_vmcb);
+	nested_svm_unmap(nested_vmcb, KM_USER0);
 
 	return 1;
 }
@@ -1798,19 +1878,29 @@ static int vmsave_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 static int vmrun_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 {
 	nsvm_printk("VMrun\n");
+
 	if (nested_svm_check_permissions(svm))
 		return 1;
 
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
 
-	if (nested_svm_do(svm, svm->vmcb->save.rax, 0,
-			  NULL, nested_svm_vmrun))
+	if (!nested_svm_vmrun(svm))
 		return 1;
 
-	if (nested_svm_do(svm, svm->nested_vmcb_msrpm, 0,
-		      NULL, nested_svm_vmrun_msrpm))
-		return 1;
+	if (!nested_svm_vmrun_msrpm(svm))
+		goto failed;
+
+	return 1;
+
+failed:
+
+	svm->vmcb->control.exit_code    = SVM_EXIT_ERR;
+	svm->vmcb->control.exit_code_hi = 0;
+	svm->vmcb->control.exit_info_1  = 0;
+	svm->vmcb->control.exit_info_2  = 0;
+
+	nested_svm_vmexit(svm);
 
 	return 1;
 }
@@ -1823,7 +1913,7 @@ static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
 
-	svm->vcpu.arch.hflags |= HF_GIF_MASK;
+	enable_gif(svm);
 
 	return 1;
 }
@@ -1836,7 +1926,7 @@ static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
 	skip_emulated_instruction(&svm->vcpu);
 
-	svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+	disable_gif(svm);
 
 	/* After a CLGI no interrupts should come */
 	svm_clear_vintr(svm);
@@ -1845,6 +1935,19 @@ static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 	return 1;
 }
 
+static int invlpga_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+	struct kvm_vcpu *vcpu = &svm->vcpu;
+	nsvm_printk("INVLPGA\n");
+
+	/* Let's treat INVLPGA the same as INVLPG (can be optimized!) */
+	kvm_mmu_invlpg(vcpu, vcpu->arch.regs[VCPU_REGS_RAX]);
+
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+	return 1;
+}
+
 static int invalid_op_interception(struct vcpu_svm *svm,
 				   struct kvm_run *kvm_run)
 {
@@ -1953,7 +2056,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	switch (ecx) {
-	case MSR_IA32_TIME_STAMP_COUNTER: {
+	case MSR_IA32_TSC: {
 		u64 tsc;
 
 		rdtscll(tsc);
@@ -1981,10 +2084,10 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
 		*data = svm->vmcb->save.sysenter_cs;
 		break;
 	case MSR_IA32_SYSENTER_EIP:
-		*data = svm->vmcb->save.sysenter_eip;
+		*data = svm->sysenter_eip;
 		break;
 	case MSR_IA32_SYSENTER_ESP:
-		*data = svm->vmcb->save.sysenter_esp;
+		*data = svm->sysenter_esp;
 		break;
 	/* Nobody will change the following 5 values in the VMCB so
 	   we can safely return them on rdmsr. They will always be 0
@@ -2005,7 +2108,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
 		*data = svm->vmcb->save.last_excp_to;
 		break;
 	case MSR_VM_HSAVE_PA:
-		*data = svm->hsave_msr;
+		*data = svm->nested.hsave_msr;
 		break;
 	case MSR_VM_CR:
 		*data = 0;
@@ -2027,8 +2130,7 @@ static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 	if (svm_get_msr(&svm->vcpu, ecx, &data))
 		kvm_inject_gp(&svm->vcpu, 0);
 	else {
-		KVMTRACE_3D(MSR_READ, &svm->vcpu, ecx, (u32)data,
-			    (u32)(data >> 32), handler);
+		trace_kvm_msr_read(ecx, data);
 
 		svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff;
 		svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32;
@@ -2043,7 +2145,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	switch (ecx) {
-	case MSR_IA32_TIME_STAMP_COUNTER: {
+	case MSR_IA32_TSC: {
 		u64 tsc;
 
 		rdtscll(tsc);
@@ -2071,9 +2173,11 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 		svm->vmcb->save.sysenter_cs = data;
 		break;
 	case MSR_IA32_SYSENTER_EIP:
+		svm->sysenter_eip = data;
 		svm->vmcb->save.sysenter_eip = data;
 		break;
 	case MSR_IA32_SYSENTER_ESP:
+		svm->sysenter_esp = data;
 		svm->vmcb->save.sysenter_esp = data;
 		break;
 	case MSR_IA32_DEBUGCTLMSR:
@@ -2091,24 +2195,12 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
 		else
 			svm_disable_lbrv(svm);
 		break;
-	case MSR_K7_EVNTSEL0:
-	case MSR_K7_EVNTSEL1:
-	case MSR_K7_EVNTSEL2:
-	case MSR_K7_EVNTSEL3:
-	case MSR_K7_PERFCTR0:
-	case MSR_K7_PERFCTR1:
-	case MSR_K7_PERFCTR2:
-	case MSR_K7_PERFCTR3:
-		/*
-		 * Just discard all writes to the performance counters; this
-		 * should keep both older linux and windows 64-bit guests
-		 * happy
-		 */
-		pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", ecx, data);
-
-		break;
 	case MSR_VM_HSAVE_PA:
-		svm->hsave_msr = data;
+		svm->nested.hsave_msr = data;
+		break;
+	case MSR_VM_CR:
+	case MSR_VM_IGNNE:
+		pr_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
 		break;
 	default:
 		return kvm_set_msr_common(vcpu, ecx, data);
@@ -2122,8 +2214,7 @@ static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 	u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
 		| ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
 
-	KVMTRACE_3D(MSR_WRITE, &svm->vcpu, ecx, (u32)data, (u32)(data >> 32),
-		    handler);
+	trace_kvm_msr_write(ecx, data);
 
 	svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
 	if (svm_set_msr(&svm->vcpu, ecx, data))
@@ -2144,8 +2235,6 @@ static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
 static int interrupt_window_interception(struct vcpu_svm *svm,
 				   struct kvm_run *kvm_run)
 {
-	KVMTRACE_0D(PEND_INTR, &svm->vcpu, handler);
-
 	svm_clear_vintr(svm);
 	svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
 	/*
@@ -2201,7 +2290,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
 	[SVM_EXIT_INVD]                         = emulate_on_interception,
 	[SVM_EXIT_HLT]				= halt_interception,
 	[SVM_EXIT_INVLPG]			= invlpg_interception,
-	[SVM_EXIT_INVLPGA]			= invalid_op_interception,
+	[SVM_EXIT_INVLPGA]			= invlpga_interception,
 	[SVM_EXIT_IOIO] 		  	= io_interception,
 	[SVM_EXIT_MSR]				= msr_interception,
 	[SVM_EXIT_TASK_SWITCH]			= task_switch_interception,
@@ -2224,20 +2313,26 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 	struct vcpu_svm *svm = to_svm(vcpu);
 	u32 exit_code = svm->vmcb->control.exit_code;
 
-	KVMTRACE_3D(VMEXIT, vcpu, exit_code, (u32)svm->vmcb->save.rip,
-		    (u32)((u64)svm->vmcb->save.rip >> 32), entryexit);
+	trace_kvm_exit(exit_code, svm->vmcb->save.rip);
 
 	if (is_nested(svm)) {
+		int vmexit;
+
 		nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n",
 			    exit_code, svm->vmcb->control.exit_info_1,
 			    svm->vmcb->control.exit_info_2, svm->vmcb->save.rip);
-		if (nested_svm_exit_handled(svm, true)) {
-			nested_svm_vmexit(svm);
-			nsvm_printk("-> #VMEXIT\n");
+
+		vmexit = nested_svm_exit_special(svm);
+
+		if (vmexit == NESTED_EXIT_CONTINUE)
+			vmexit = nested_svm_exit_handled(svm);
+
+		if (vmexit == NESTED_EXIT_DONE)
 			return 1;
-		}
 	}
 
+	svm_complete_interrupts(svm);
+
 	if (npt_enabled) {
 		int mmu_reload = 0;
 		if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) {
@@ -2246,12 +2341,6 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 		}
 		vcpu->arch.cr0 = svm->vmcb->save.cr0;
 		vcpu->arch.cr3 = svm->vmcb->save.cr3;
-		if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
-			if (!load_pdptrs(vcpu, vcpu->arch.cr3)) {
-				kvm_inject_gp(vcpu, 0);
-				return 1;
-			}
-		}
 		if (mmu_reload) {
 			kvm_mmu_reset_context(vcpu);
 			kvm_mmu_load(vcpu);
@@ -2319,7 +2408,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
 {
 	struct vmcb_control_area *control;
 
-	KVMTRACE_1D(INJ_VIRQ, &svm->vcpu, (u32)irq, handler);
+	trace_kvm_inj_virq(irq);
 
 	++svm->vcpu.stat.irq_injections;
 	control = &svm->vmcb->control;
@@ -2329,21 +2418,14 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
 		((/*control->int_vector >> 4*/ 0xf) << V_INTR_PRIO_SHIFT);
 }
 
-static void svm_queue_irq(struct kvm_vcpu *vcpu, unsigned nr)
-{
-	struct vcpu_svm *svm = to_svm(vcpu);
-
-	svm->vmcb->control.event_inj = nr |
-		SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR;
-}
-
 static void svm_set_irq(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	nested_svm_intr(svm);
+	BUG_ON(!(gif_set(svm)));
 
-	svm_queue_irq(vcpu, vcpu->arch.interrupt.nr);
+	svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr |
+		SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR;
 }
 
 static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
@@ -2371,13 +2453,25 @@ static int svm_interrupt_allowed(struct kvm_vcpu *vcpu)
 	struct vmcb *vmcb = svm->vmcb;
 	return (vmcb->save.rflags & X86_EFLAGS_IF) &&
 		!(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) &&
-		(svm->vcpu.arch.hflags & HF_GIF_MASK);
+		gif_set(svm) &&
+		!(is_nested(svm) && (svm->vcpu.arch.hflags & HF_VINTR_MASK));
 }
 
 static void enable_irq_window(struct kvm_vcpu *vcpu)
 {
-	svm_set_vintr(to_svm(vcpu));
-	svm_inject_irq(to_svm(vcpu), 0x0);
+	struct vcpu_svm *svm = to_svm(vcpu);
+	nsvm_printk("Trying to open IRQ window\n");
+
+	nested_svm_intr(svm);
+
+	/* In case GIF=0 we can't rely on the CPU to tell us when
+	 * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
+	 * The next time we get that intercept, this function will be
+	 * called again though and we'll get the vintr intercept. */
+	if (gif_set(svm)) {
+		svm_set_vintr(svm);
+		svm_inject_irq(svm, 0x0);
+	}
 }
 
 static void enable_nmi_window(struct kvm_vcpu *vcpu)
@@ -2456,6 +2550,8 @@ static void svm_complete_interrupts(struct vcpu_svm *svm)
 	case SVM_EXITINTINFO_TYPE_EXEPT:
 		/* In case of software exception do not reinject an exception
 		   vector, but re-execute and instruction instead */
+		if (is_nested(svm))
+			break;
 		if (kvm_exception_is_soft(vector))
 			break;
 		if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) {
@@ -2498,9 +2594,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	fs_selector = kvm_read_fs();
 	gs_selector = kvm_read_gs();
 	ldt_selector = kvm_read_ldt();
-	svm->host_cr2 = kvm_read_cr2();
-	if (!is_nested(svm))
-		svm->vmcb->save.cr2 = vcpu->arch.cr2;
+	svm->vmcb->save.cr2 = vcpu->arch.cr2;
 	/* required for live migration with NPT */
 	if (npt_enabled)
 		svm->vmcb->save.cr3 = vcpu->arch.cr3;
@@ -2585,8 +2679,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
 	vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
 
-	kvm_write_cr2(svm->host_cr2);
-
 	kvm_load_fs(fs_selector);
 	kvm_load_gs(gs_selector);
 	kvm_load_ldt(ldt_selector);
@@ -2602,7 +2694,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
 	svm->next_rip = 0;
 
-	svm_complete_interrupts(svm);
+	if (npt_enabled) {
+		vcpu->arch.regs_avail &= ~(1 << VCPU_EXREG_PDPTR);
+		vcpu->arch.regs_dirty &= ~(1 << VCPU_EXREG_PDPTR);
+	}
 }
 
 #undef R
@@ -2673,6 +2768,64 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
 	return 0;
 }
 
+static const struct trace_print_flags svm_exit_reasons_str[] = {
+	{ SVM_EXIT_READ_CR0,           		"read_cr0" },
+	{ SVM_EXIT_READ_CR3,	      		"read_cr3" },
+	{ SVM_EXIT_READ_CR4,	      		"read_cr4" },
+	{ SVM_EXIT_READ_CR8,  	      		"read_cr8" },
+	{ SVM_EXIT_WRITE_CR0,          		"write_cr0" },
+	{ SVM_EXIT_WRITE_CR3,	      		"write_cr3" },
+	{ SVM_EXIT_WRITE_CR4,          		"write_cr4" },
+	{ SVM_EXIT_WRITE_CR8, 	      		"write_cr8" },
+	{ SVM_EXIT_READ_DR0, 	      		"read_dr0" },
+	{ SVM_EXIT_READ_DR1,	      		"read_dr1" },
+	{ SVM_EXIT_READ_DR2,	      		"read_dr2" },
+	{ SVM_EXIT_READ_DR3,	      		"read_dr3" },
+	{ SVM_EXIT_WRITE_DR0,	      		"write_dr0" },
+	{ SVM_EXIT_WRITE_DR1,	      		"write_dr1" },
+	{ SVM_EXIT_WRITE_DR2,	      		"write_dr2" },
+	{ SVM_EXIT_WRITE_DR3,	      		"write_dr3" },
+	{ SVM_EXIT_WRITE_DR5,	      		"write_dr5" },
+	{ SVM_EXIT_WRITE_DR7,	      		"write_dr7" },
+	{ SVM_EXIT_EXCP_BASE + DB_VECTOR,	"DB excp" },
+	{ SVM_EXIT_EXCP_BASE + BP_VECTOR,	"BP excp" },
+	{ SVM_EXIT_EXCP_BASE + UD_VECTOR,	"UD excp" },
+	{ SVM_EXIT_EXCP_BASE + PF_VECTOR,	"PF excp" },
+	{ SVM_EXIT_EXCP_BASE + NM_VECTOR,	"NM excp" },
+	{ SVM_EXIT_EXCP_BASE + MC_VECTOR,	"MC excp" },
+	{ SVM_EXIT_INTR,			"interrupt" },
+	{ SVM_EXIT_NMI,				"nmi" },
+	{ SVM_EXIT_SMI,				"smi" },
+	{ SVM_EXIT_INIT,			"init" },
+	{ SVM_EXIT_VINTR,			"vintr" },
+	{ SVM_EXIT_CPUID,			"cpuid" },
+	{ SVM_EXIT_INVD,			"invd" },
+	{ SVM_EXIT_HLT,				"hlt" },
+	{ SVM_EXIT_INVLPG,			"invlpg" },
+	{ SVM_EXIT_INVLPGA,			"invlpga" },
+	{ SVM_EXIT_IOIO,			"io" },
+	{ SVM_EXIT_MSR,				"msr" },
+	{ SVM_EXIT_TASK_SWITCH,			"task_switch" },
+	{ SVM_EXIT_SHUTDOWN,			"shutdown" },
+	{ SVM_EXIT_VMRUN,			"vmrun" },
+	{ SVM_EXIT_VMMCALL,			"hypercall" },
+	{ SVM_EXIT_VMLOAD,			"vmload" },
+	{ SVM_EXIT_VMSAVE,			"vmsave" },
+	{ SVM_EXIT_STGI,			"stgi" },
+	{ SVM_EXIT_CLGI,			"clgi" },
+	{ SVM_EXIT_SKINIT,			"skinit" },
+	{ SVM_EXIT_WBINVD,			"wbinvd" },
+	{ SVM_EXIT_MONITOR,			"monitor" },
+	{ SVM_EXIT_MWAIT,			"mwait" },
+	{ SVM_EXIT_NPF,				"npf" },
+	{ -1, NULL }
+};
+
+static bool svm_gb_page_enable(void)
+{
+	return true;
+}
+
 static struct kvm_x86_ops svm_x86_ops = {
 	.cpu_has_kvm_support = has_svm,
 	.disabled_by_bios = is_disabled,
@@ -2710,6 +2863,7 @@ static struct kvm_x86_ops svm_x86_ops = {
 	.set_gdt = svm_set_gdt,
 	.get_dr = svm_get_dr,
 	.set_dr = svm_set_dr,
+	.cache_reg = svm_cache_reg,
 	.get_rflags = svm_get_rflags,
 	.set_rflags = svm_set_rflags,
 
@@ -2733,6 +2887,9 @@ static struct kvm_x86_ops svm_x86_ops = {
 	.set_tss_addr = svm_set_tss_addr,
 	.get_tdp_level = get_npt_level,
 	.get_mt_mask = svm_get_mt_mask,
+
+	.exit_reasons_str = svm_exit_reasons_str,
+	.gb_page_enable = svm_gb_page_enable,
 };
 
 static int __init svm_init(void)
diff --git a/arch/x86/kvm/timer.c b/arch/x86/kvm/timer.c
index 86dbac0..eea4043 100644
--- a/arch/x86/kvm/timer.c
+++ b/arch/x86/kvm/timer.c
@@ -9,12 +9,16 @@ static int __kvm_timer_fn(struct kvm_vcpu *vcpu, struct kvm_timer *ktimer)
 	int restart_timer = 0;
 	wait_queue_head_t *q = &vcpu->wq;
 
-	/* FIXME: this code should not know anything about vcpus */
-	if (!atomic_inc_and_test(&ktimer->pending))
+	/*
+	 * There is a race window between reading and incrementing, but we do
+	 * not care about potentially loosing timer events in the !reinject
+	 * case anyway.
+	 */
+	if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
+		atomic_inc(&ktimer->pending);
+		/* FIXME: this code should not know anything about vcpus */
 		set_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
-
-	if (!ktimer->reinject)
-		atomic_set(&ktimer->pending, 1);
+	}
 
 	if (waitqueue_active(q))
 		wake_up_interruptible(q);
@@ -33,7 +37,7 @@ enum hrtimer_restart kvm_timer_fn(struct hrtimer *data)
 	struct kvm_vcpu *vcpu;
 	struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer);
 
-	vcpu = ktimer->kvm->vcpus[ktimer->vcpu_id];
+	vcpu = ktimer->vcpu;
 	if (!vcpu)
 		return HRTIMER_NORESTART;
 
diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h
new file mode 100644
index 0000000..0d480e7
--- /dev/null
+++ b/arch/x86/kvm/trace.h
@@ -0,0 +1,355 @@
+#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+#define TRACE_INCLUDE_PATH arch/x86/kvm
+#define TRACE_INCLUDE_FILE trace
+
+/*
+ * Tracepoint for guest mode entry.
+ */
+TRACE_EVENT(kvm_entry,
+	TP_PROTO(unsigned int vcpu_id),
+	TP_ARGS(vcpu_id),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	vcpu_id		)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_id	= vcpu_id;
+	),
+
+	TP_printk("vcpu %u", __entry->vcpu_id)
+);
+
+/*
+ * Tracepoint for hypercall.
+ */
+TRACE_EVENT(kvm_hypercall,
+	TP_PROTO(unsigned long nr, unsigned long a0, unsigned long a1,
+		 unsigned long a2, unsigned long a3),
+	TP_ARGS(nr, a0, a1, a2, a3),
+
+	TP_STRUCT__entry(
+		__field(	unsigned long, 	nr		)
+		__field(	unsigned long,	a0		)
+		__field(	unsigned long,	a1		)
+		__field(	unsigned long,	a2		)
+		__field(	unsigned long,	a3		)
+	),
+
+	TP_fast_assign(
+		__entry->nr		= nr;
+		__entry->a0		= a0;
+		__entry->a1		= a1;
+		__entry->a2		= a2;
+		__entry->a3		= a3;
+	),
+
+	TP_printk("nr 0x%lx a0 0x%lx a1 0x%lx a2 0x%lx a3 0x%lx",
+		 __entry->nr, __entry->a0, __entry->a1,  __entry->a2,
+		 __entry->a3)
+);
+
+/*
+ * Tracepoint for PIO.
+ */
+TRACE_EVENT(kvm_pio,
+	TP_PROTO(unsigned int rw, unsigned int port, unsigned int size,
+		 unsigned int count),
+	TP_ARGS(rw, port, size, count),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int, 	rw		)
+		__field(	unsigned int, 	port		)
+		__field(	unsigned int, 	size		)
+		__field(	unsigned int,	count		)
+	),
+
+	TP_fast_assign(
+		__entry->rw		= rw;
+		__entry->port		= port;
+		__entry->size		= size;
+		__entry->count		= count;
+	),
+
+	TP_printk("pio_%s at 0x%x size %d count %d",
+		  __entry->rw ? "write" : "read",
+		  __entry->port, __entry->size, __entry->count)
+);
+
+/*
+ * Tracepoint for cpuid.
+ */
+TRACE_EVENT(kvm_cpuid,
+	TP_PROTO(unsigned int function, unsigned long rax, unsigned long rbx,
+		 unsigned long rcx, unsigned long rdx),
+	TP_ARGS(function, rax, rbx, rcx, rdx),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	function	)
+		__field(	unsigned long,	rax		)
+		__field(	unsigned long,	rbx		)
+		__field(	unsigned long,	rcx		)
+		__field(	unsigned long,	rdx		)
+	),
+
+	TP_fast_assign(
+		__entry->function	= function;
+		__entry->rax		= rax;
+		__entry->rbx		= rbx;
+		__entry->rcx		= rcx;
+		__entry->rdx		= rdx;
+	),
+
+	TP_printk("func %x rax %lx rbx %lx rcx %lx rdx %lx",
+		  __entry->function, __entry->rax,
+		  __entry->rbx, __entry->rcx, __entry->rdx)
+);
+
+#define AREG(x) { APIC_##x, "APIC_" #x }
+
+#define kvm_trace_symbol_apic						    \
+	AREG(ID), AREG(LVR), AREG(TASKPRI), AREG(ARBPRI), AREG(PROCPRI),    \
+	AREG(EOI), AREG(RRR), AREG(LDR), AREG(DFR), AREG(SPIV), AREG(ISR),  \
+	AREG(TMR), AREG(IRR), AREG(ESR), AREG(ICR), AREG(ICR2), AREG(LVTT), \
+	AREG(LVTTHMR), AREG(LVTPC), AREG(LVT0), AREG(LVT1), AREG(LVTERR),   \
+	AREG(TMICT), AREG(TMCCT), AREG(TDCR), AREG(SELF_IPI), AREG(EFEAT),  \
+	AREG(ECTRL)
+/*
+ * Tracepoint for apic access.
+ */
+TRACE_EVENT(kvm_apic,
+	TP_PROTO(unsigned int rw, unsigned int reg, unsigned int val),
+	TP_ARGS(rw, reg, val),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	rw		)
+		__field(	unsigned int,	reg		)
+		__field(	unsigned int,	val		)
+	),
+
+	TP_fast_assign(
+		__entry->rw		= rw;
+		__entry->reg		= reg;
+		__entry->val		= val;
+	),
+
+	TP_printk("apic_%s %s = 0x%x",
+		  __entry->rw ? "write" : "read",
+		  __print_symbolic(__entry->reg, kvm_trace_symbol_apic),
+		  __entry->val)
+);
+
+#define trace_kvm_apic_read(reg, val)		trace_kvm_apic(0, reg, val)
+#define trace_kvm_apic_write(reg, val)		trace_kvm_apic(1, reg, val)
+
+/*
+ * Tracepoint for kvm guest exit:
+ */
+TRACE_EVENT(kvm_exit,
+	TP_PROTO(unsigned int exit_reason, unsigned long guest_rip),
+	TP_ARGS(exit_reason, guest_rip),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	exit_reason	)
+		__field(	unsigned long,	guest_rip	)
+	),
+
+	TP_fast_assign(
+		__entry->exit_reason	= exit_reason;
+		__entry->guest_rip	= guest_rip;
+	),
+
+	TP_printk("reason %s rip 0x%lx",
+		 ftrace_print_symbols_seq(p, __entry->exit_reason,
+					  kvm_x86_ops->exit_reasons_str),
+		 __entry->guest_rip)
+);
+
+/*
+ * Tracepoint for kvm interrupt injection:
+ */
+TRACE_EVENT(kvm_inj_virq,
+	TP_PROTO(unsigned int irq),
+	TP_ARGS(irq),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	irq		)
+	),
+
+	TP_fast_assign(
+		__entry->irq		= irq;
+	),
+
+	TP_printk("irq %u", __entry->irq)
+);
+
+/*
+ * Tracepoint for page fault.
+ */
+TRACE_EVENT(kvm_page_fault,
+	TP_PROTO(unsigned long fault_address, unsigned int error_code),
+	TP_ARGS(fault_address, error_code),
+
+	TP_STRUCT__entry(
+		__field(	unsigned long,	fault_address	)
+		__field(	unsigned int,	error_code	)
+	),
+
+	TP_fast_assign(
+		__entry->fault_address	= fault_address;
+		__entry->error_code	= error_code;
+	),
+
+	TP_printk("address %lx error_code %x",
+		  __entry->fault_address, __entry->error_code)
+);
+
+/*
+ * Tracepoint for guest MSR access.
+ */
+TRACE_EVENT(kvm_msr,
+	TP_PROTO(unsigned int rw, unsigned int ecx, unsigned long data),
+	TP_ARGS(rw, ecx, data),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	rw		)
+		__field(	unsigned int,	ecx		)
+		__field(	unsigned long,	data		)
+	),
+
+	TP_fast_assign(
+		__entry->rw		= rw;
+		__entry->ecx		= ecx;
+		__entry->data		= data;
+	),
+
+	TP_printk("msr_%s %x = 0x%lx",
+		  __entry->rw ? "write" : "read",
+		  __entry->ecx, __entry->data)
+);
+
+#define trace_kvm_msr_read(ecx, data)		trace_kvm_msr(0, ecx, data)
+#define trace_kvm_msr_write(ecx, data)		trace_kvm_msr(1, ecx, data)
+
+/*
+ * Tracepoint for guest CR access.
+ */
+TRACE_EVENT(kvm_cr,
+	TP_PROTO(unsigned int rw, unsigned int cr, unsigned long val),
+	TP_ARGS(rw, cr, val),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	rw		)
+		__field(	unsigned int,	cr		)
+		__field(	unsigned long,	val		)
+	),
+
+	TP_fast_assign(
+		__entry->rw		= rw;
+		__entry->cr		= cr;
+		__entry->val		= val;
+	),
+
+	TP_printk("cr_%s %x = 0x%lx",
+		  __entry->rw ? "write" : "read",
+		  __entry->cr, __entry->val)
+);
+
+#define trace_kvm_cr_read(cr, val)		trace_kvm_cr(0, cr, val)
+#define trace_kvm_cr_write(cr, val)		trace_kvm_cr(1, cr, val)
+
+TRACE_EVENT(kvm_pic_set_irq,
+	    TP_PROTO(__u8 chip, __u8 pin, __u8 elcr, __u8 imr, bool coalesced),
+	    TP_ARGS(chip, pin, elcr, imr, coalesced),
+
+	TP_STRUCT__entry(
+		__field(	__u8,		chip		)
+		__field(	__u8,		pin		)
+		__field(	__u8,		elcr		)
+		__field(	__u8,		imr		)
+		__field(	bool,		coalesced	)
+	),
+
+	TP_fast_assign(
+		__entry->chip		= chip;
+		__entry->pin		= pin;
+		__entry->elcr		= elcr;
+		__entry->imr		= imr;
+		__entry->coalesced	= coalesced;
+	),
+
+	TP_printk("chip %u pin %u (%s%s)%s",
+		  __entry->chip, __entry->pin,
+		  (__entry->elcr & (1 << __entry->pin)) ? "level":"edge",
+		  (__entry->imr & (1 << __entry->pin)) ? "|masked":"",
+		  __entry->coalesced ? " (coalesced)" : "")
+);
+
+#define kvm_apic_dst_shorthand		\
+	{0x0, "dst"},			\
+	{0x1, "self"},			\
+	{0x2, "all"},			\
+	{0x3, "all-but-self"}
+
+TRACE_EVENT(kvm_apic_ipi,
+	    TP_PROTO(__u32 icr_low, __u32 dest_id),
+	    TP_ARGS(icr_low, dest_id),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		icr_low		)
+		__field(	__u32,		dest_id		)
+	),
+
+	TP_fast_assign(
+		__entry->icr_low	= icr_low;
+		__entry->dest_id	= dest_id;
+	),
+
+	TP_printk("dst %x vec %u (%s|%s|%s|%s|%s)",
+		  __entry->dest_id, (u8)__entry->icr_low,
+		  __print_symbolic((__entry->icr_low >> 8 & 0x7),
+				   kvm_deliver_mode),
+		  (__entry->icr_low & (1<<11)) ? "logical" : "physical",
+		  (__entry->icr_low & (1<<14)) ? "assert" : "de-assert",
+		  (__entry->icr_low & (1<<15)) ? "level" : "edge",
+		  __print_symbolic((__entry->icr_low >> 18 & 0x3),
+				   kvm_apic_dst_shorthand))
+);
+
+TRACE_EVENT(kvm_apic_accept_irq,
+	    TP_PROTO(__u32 apicid, __u16 dm, __u8 tm, __u8 vec, bool coalesced),
+	    TP_ARGS(apicid, dm, tm, vec, coalesced),
+
+	TP_STRUCT__entry(
+		__field(	__u32,		apicid		)
+		__field(	__u16,		dm		)
+		__field(	__u8,		tm		)
+		__field(	__u8,		vec		)
+		__field(	bool,		coalesced	)
+	),
+
+	TP_fast_assign(
+		__entry->apicid		= apicid;
+		__entry->dm		= dm;
+		__entry->tm		= tm;
+		__entry->vec		= vec;
+		__entry->coalesced	= coalesced;
+	),
+
+	TP_printk("apicid %x vec %u (%s|%s)%s",
+		  __entry->apicid, __entry->vec,
+		  __print_symbolic((__entry->dm >> 8 & 0x7), kvm_deliver_mode),
+		  __entry->tm ? "level" : "edge",
+		  __entry->coalesced ? " (coalesced)" : "")
+);
+
+#endif /* _TRACE_KVM_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 29f9129..f381201 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -25,6 +25,7 @@
 #include <linux/highmem.h>
 #include <linux/sched.h>
 #include <linux/moduleparam.h>
+#include <linux/ftrace_event.h>
 #include "kvm_cache_regs.h"
 #include "x86.h"
 
@@ -34,6 +35,8 @@
 #include <asm/virtext.h>
 #include <asm/mce.h>
 
+#include "trace.h"
+
 #define __ex(x) __kvm_handle_fault_on_reboot(x)
 
 MODULE_AUTHOR("Qumranet");
@@ -51,6 +54,10 @@ module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO);
 static int __read_mostly enable_ept = 1;
 module_param_named(ept, enable_ept, bool, S_IRUGO);
 
+static int __read_mostly enable_unrestricted_guest = 1;
+module_param_named(unrestricted_guest,
+			enable_unrestricted_guest, bool, S_IRUGO);
+
 static int __read_mostly emulate_invalid_guest_state = 0;
 module_param(emulate_invalid_guest_state, bool, S_IRUGO);
 
@@ -84,6 +91,14 @@ struct vcpu_vmx {
 		int           guest_efer_loaded;
 	} host_state;
 	struct {
+		int vm86_active;
+		u8 save_iopl;
+		struct kvm_save_segment {
+			u16 selector;
+			unsigned long base;
+			u32 limit;
+			u32 ar;
+		} tr, es, ds, fs, gs;
 		struct {
 			bool pending;
 			u8 vector;
@@ -161,6 +176,8 @@ static struct kvm_vmx_segment_field {
 	VMX_SEGMENT_FIELD(LDTR),
 };
 
+static void ept_save_pdptrs(struct kvm_vcpu *vcpu);
+
 /*
  * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it
  * away by decrementing the array size.
@@ -256,6 +273,26 @@ static inline bool cpu_has_vmx_flexpriority(void)
 		cpu_has_vmx_virtualize_apic_accesses();
 }
 
+static inline bool cpu_has_vmx_ept_execute_only(void)
+{
+	return !!(vmx_capability.ept & VMX_EPT_EXECUTE_ONLY_BIT);
+}
+
+static inline bool cpu_has_vmx_eptp_uncacheable(void)
+{
+	return !!(vmx_capability.ept & VMX_EPTP_UC_BIT);
+}
+
+static inline bool cpu_has_vmx_eptp_writeback(void)
+{
+	return !!(vmx_capability.ept & VMX_EPTP_WB_BIT);
+}
+
+static inline bool cpu_has_vmx_ept_2m_page(void)
+{
+	return !!(vmx_capability.ept & VMX_EPT_2MB_PAGE_BIT);
+}
+
 static inline int cpu_has_vmx_invept_individual_addr(void)
 {
 	return !!(vmx_capability.ept & VMX_EPT_EXTENT_INDIVIDUAL_BIT);
@@ -277,6 +314,12 @@ static inline int cpu_has_vmx_ept(void)
 		SECONDARY_EXEC_ENABLE_EPT;
 }
 
+static inline int cpu_has_vmx_unrestricted_guest(void)
+{
+	return vmcs_config.cpu_based_2nd_exec_ctrl &
+		SECONDARY_EXEC_UNRESTRICTED_GUEST;
+}
+
 static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm)
 {
 	return flexpriority_enabled &&
@@ -497,14 +540,16 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
 	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR);
 	if (!vcpu->fpu_active)
 		eb |= 1u << NM_VECTOR;
+	/*
+	 * Unconditionally intercept #DB so we can maintain dr6 without
+	 * reading it every exit.
+	 */
+	eb |= 1u << DB_VECTOR;
 	if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
-		if (vcpu->guest_debug &
-		    (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
-			eb |= 1u << DB_VECTOR;
 		if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
 			eb |= 1u << BP_VECTOR;
 	}
-	if (vcpu->arch.rmode.vm86_active)
+	if (to_vmx(vcpu)->rmode.vm86_active)
 		eb = ~0;
 	if (enable_ept)
 		eb &= ~(1u << PF_VECTOR); /* bypass_guest_pf = 0 */
@@ -528,12 +573,15 @@ static void reload_tss(void)
 static void load_transition_efer(struct vcpu_vmx *vmx)
 {
 	int efer_offset = vmx->msr_offset_efer;
-	u64 host_efer = vmx->host_msrs[efer_offset].data;
-	u64 guest_efer = vmx->guest_msrs[efer_offset].data;
+	u64 host_efer;
+	u64 guest_efer;
 	u64 ignore_bits;
 
 	if (efer_offset < 0)
 		return;
+	host_efer = vmx->host_msrs[efer_offset].data;
+	guest_efer = vmx->guest_msrs[efer_offset].data;
+
 	/*
 	 * NX is emulated; LMA and LME handled by hardware; SCE meaninless
 	 * outside long mode
@@ -735,12 +783,17 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
 
 static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
-	return vmcs_readl(GUEST_RFLAGS);
+	unsigned long rflags;
+
+	rflags = vmcs_readl(GUEST_RFLAGS);
+	if (to_vmx(vcpu)->rmode.vm86_active)
+		rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
+	return rflags;
 }
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
-	if (vcpu->arch.rmode.vm86_active)
+	if (to_vmx(vcpu)->rmode.vm86_active)
 		rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
 	vmcs_writel(GUEST_RFLAGS, rflags);
 }
@@ -797,12 +850,13 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
 		intr_info |= INTR_INFO_DELIVER_CODE_MASK;
 	}
 
-	if (vcpu->arch.rmode.vm86_active) {
+	if (vmx->rmode.vm86_active) {
 		vmx->rmode.irq.pending = true;
 		vmx->rmode.irq.vector = nr;
 		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
-		if (nr == BP_VECTOR || nr == OF_VECTOR)
-			vmx->rmode.irq.rip++;
+		if (kvm_exception_is_soft(nr))
+			vmx->rmode.irq.rip +=
+				vmx->vcpu.arch.event_exit_inst_len;
 		intr_info |= INTR_TYPE_SOFT_INTR;
 		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info);
 		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
@@ -940,7 +994,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
 	case MSR_EFER:
 		return kvm_get_msr_common(vcpu, msr_index, pdata);
 #endif
-	case MSR_IA32_TIME_STAMP_COUNTER:
+	case MSR_IA32_TSC:
 		data = guest_read_tsc();
 		break;
 	case MSR_IA32_SYSENTER_CS:
@@ -953,9 +1007,9 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
 		data = vmcs_readl(GUEST_SYSENTER_ESP);
 		break;
 	default:
-		vmx_load_host_state(to_vmx(vcpu));
 		msr = find_msr_entry(to_vmx(vcpu), msr_index);
 		if (msr) {
+			vmx_load_host_state(to_vmx(vcpu));
 			data = msr->data;
 			break;
 		}
@@ -1000,22 +1054,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
 	case MSR_IA32_SYSENTER_ESP:
 		vmcs_writel(GUEST_SYSENTER_ESP, data);
 		break;
-	case MSR_IA32_TIME_STAMP_COUNTER:
+	case MSR_IA32_TSC:
 		rdtscll(host_tsc);
 		guest_write_tsc(data, host_tsc);
 		break;
-	case MSR_P6_PERFCTR0:
-	case MSR_P6_PERFCTR1:
-	case MSR_P6_EVNTSEL0:
-	case MSR_P6_EVNTSEL1:
-		/*
-		 * Just discard all writes to the performance counters; this
-		 * should keep both older linux and windows 64-bit guests
-		 * happy
-		 */
-		pr_unimpl(vcpu, "unimplemented perfctr wrmsr: 0x%x data 0x%llx\n", msr_index, data);
-
-		break;
 	case MSR_IA32_CR_PAT:
 		if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
 			vmcs_write64(GUEST_IA32_PAT, data);
@@ -1024,9 +1066,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
 		}
 		/* Otherwise falls through to kvm_set_msr_common */
 	default:
-		vmx_load_host_state(vmx);
 		msr = find_msr_entry(vmx, msr_index);
 		if (msr) {
+			vmx_load_host_state(vmx);
 			msr->data = data;
 			break;
 		}
@@ -1046,6 +1088,10 @@ static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
 	case VCPU_REGS_RIP:
 		vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP);
 		break;
+	case VCPU_EXREG_PDPTR:
+		if (enable_ept)
+			ept_save_pdptrs(vcpu);
+		break;
 	default:
 		break;
 	}
@@ -1203,7 +1249,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
 		opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
 			SECONDARY_EXEC_WBINVD_EXITING |
 			SECONDARY_EXEC_ENABLE_VPID |
-			SECONDARY_EXEC_ENABLE_EPT;
+			SECONDARY_EXEC_ENABLE_EPT |
+			SECONDARY_EXEC_UNRESTRICTED_GUEST;
 		if (adjust_vmx_controls(min2, opt2,
 					MSR_IA32_VMX_PROCBASED_CTLS2,
 					&_cpu_based_2nd_exec_control) < 0)
@@ -1217,12 +1264,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
 	if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) {
 		/* CR3 accesses and invlpg don't need to cause VM Exits when EPT
 		   enabled */
-		min &= ~(CPU_BASED_CR3_LOAD_EXITING |
-			 CPU_BASED_CR3_STORE_EXITING |
-			 CPU_BASED_INVLPG_EXITING);
-		if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
-					&_cpu_based_exec_control) < 0)
-			return -EIO;
+		_cpu_based_exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING |
+					     CPU_BASED_CR3_STORE_EXITING |
+					     CPU_BASED_INVLPG_EXITING);
 		rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
 		      vmx_capability.ept, vmx_capability.vpid);
 	}
@@ -1333,8 +1377,13 @@ static __init int hardware_setup(void)
 	if (!cpu_has_vmx_vpid())
 		enable_vpid = 0;
 
-	if (!cpu_has_vmx_ept())
+	if (!cpu_has_vmx_ept()) {
 		enable_ept = 0;
+		enable_unrestricted_guest = 0;
+	}
+
+	if (!cpu_has_vmx_unrestricted_guest())
+		enable_unrestricted_guest = 0;
 
 	if (!cpu_has_vmx_flexpriority())
 		flexpriority_enabled = 0;
@@ -1342,6 +1391,9 @@ static __init int hardware_setup(void)
 	if (!cpu_has_vmx_tpr_shadow())
 		kvm_x86_ops->update_cr8_intercept = NULL;
 
+	if (enable_ept && !cpu_has_vmx_ept_2m_page())
+		kvm_disable_largepages();
+
 	return alloc_kvm_area();
 }
 
@@ -1372,15 +1424,15 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 
 	vmx->emulation_required = 1;
-	vcpu->arch.rmode.vm86_active = 0;
+	vmx->rmode.vm86_active = 0;
 
-	vmcs_writel(GUEST_TR_BASE, vcpu->arch.rmode.tr.base);
-	vmcs_write32(GUEST_TR_LIMIT, vcpu->arch.rmode.tr.limit);
-	vmcs_write32(GUEST_TR_AR_BYTES, vcpu->arch.rmode.tr.ar);
+	vmcs_writel(GUEST_TR_BASE, vmx->rmode.tr.base);
+	vmcs_write32(GUEST_TR_LIMIT, vmx->rmode.tr.limit);
+	vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
 
 	flags = vmcs_readl(GUEST_RFLAGS);
 	flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
-	flags |= (vcpu->arch.rmode.save_iopl << IOPL_SHIFT);
+	flags |= (vmx->rmode.save_iopl << IOPL_SHIFT);
 	vmcs_writel(GUEST_RFLAGS, flags);
 
 	vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
@@ -1391,10 +1443,10 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
 	if (emulate_invalid_guest_state)
 		return;
 
-	fix_pmode_dataseg(VCPU_SREG_ES, &vcpu->arch.rmode.es);
-	fix_pmode_dataseg(VCPU_SREG_DS, &vcpu->arch.rmode.ds);
-	fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
-	fix_pmode_dataseg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
+	fix_pmode_dataseg(VCPU_SREG_ES, &vmx->rmode.es);
+	fix_pmode_dataseg(VCPU_SREG_DS, &vmx->rmode.ds);
+	fix_pmode_dataseg(VCPU_SREG_GS, &vmx->rmode.gs);
+	fix_pmode_dataseg(VCPU_SREG_FS, &vmx->rmode.fs);
 
 	vmcs_write16(GUEST_SS_SELECTOR, 0);
 	vmcs_write32(GUEST_SS_AR_BYTES, 0x93);
@@ -1433,20 +1485,23 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
 	unsigned long flags;
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 
+	if (enable_unrestricted_guest)
+		return;
+
 	vmx->emulation_required = 1;
-	vcpu->arch.rmode.vm86_active = 1;
+	vmx->rmode.vm86_active = 1;
 
-	vcpu->arch.rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
+	vmx->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
 	vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
 
-	vcpu->arch.rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
+	vmx->rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
 	vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
 
-	vcpu->arch.rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES);
+	vmx->rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES);
 	vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
 
 	flags = vmcs_readl(GUEST_RFLAGS);
-	vcpu->arch.rmode.save_iopl
+	vmx->rmode.save_iopl
 		= (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
 
 	flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
@@ -1468,10 +1523,10 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
 		vmcs_writel(GUEST_CS_BASE, 0xf0000);
 	vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
 
-	fix_rmode_seg(VCPU_SREG_ES, &vcpu->arch.rmode.es);
-	fix_rmode_seg(VCPU_SREG_DS, &vcpu->arch.rmode.ds);
-	fix_rmode_seg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
-	fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
+	fix_rmode_seg(VCPU_SREG_ES, &vmx->rmode.es);
+	fix_rmode_seg(VCPU_SREG_DS, &vmx->rmode.ds);
+	fix_rmode_seg(VCPU_SREG_GS, &vmx->rmode.gs);
+	fix_rmode_seg(VCPU_SREG_FS, &vmx->rmode.fs);
 
 continue_rmode:
 	kvm_mmu_reset_context(vcpu);
@@ -1545,11 +1600,11 @@ static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
 
 static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
 {
+	if (!test_bit(VCPU_EXREG_PDPTR,
+		      (unsigned long *)&vcpu->arch.regs_dirty))
+		return;
+
 	if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
-		if (!load_pdptrs(vcpu, vcpu->arch.cr3)) {
-			printk(KERN_ERR "EPT: Fail to load pdptrs!\n");
-			return;
-		}
 		vmcs_write64(GUEST_PDPTR0, vcpu->arch.pdptrs[0]);
 		vmcs_write64(GUEST_PDPTR1, vcpu->arch.pdptrs[1]);
 		vmcs_write64(GUEST_PDPTR2, vcpu->arch.pdptrs[2]);
@@ -1557,6 +1612,21 @@ static void ept_load_pdptrs(struct kvm_vcpu *vcpu)
 	}
 }
 
+static void ept_save_pdptrs(struct kvm_vcpu *vcpu)
+{
+	if (is_paging(vcpu) && is_pae(vcpu) && !is_long_mode(vcpu)) {
+		vcpu->arch.pdptrs[0] = vmcs_read64(GUEST_PDPTR0);
+		vcpu->arch.pdptrs[1] = vmcs_read64(GUEST_PDPTR1);
+		vcpu->arch.pdptrs[2] = vmcs_read64(GUEST_PDPTR2);
+		vcpu->arch.pdptrs[3] = vmcs_read64(GUEST_PDPTR3);
+	}
+
+	__set_bit(VCPU_EXREG_PDPTR,
+		  (unsigned long *)&vcpu->arch.regs_avail);
+	__set_bit(VCPU_EXREG_PDPTR,
+		  (unsigned long *)&vcpu->arch.regs_dirty);
+}
+
 static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
 
 static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
@@ -1571,8 +1641,6 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
 			      CPU_BASED_CR3_STORE_EXITING));
 		vcpu->arch.cr0 = cr0;
 		vmx_set_cr4(vcpu, vcpu->arch.cr4);
-		*hw_cr0 |= X86_CR0_PE | X86_CR0_PG;
-		*hw_cr0 &= ~X86_CR0_WP;
 	} else if (!is_paging(vcpu)) {
 		/* From nonpaging to paging */
 		vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
@@ -1581,9 +1649,10 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
 			       CPU_BASED_CR3_STORE_EXITING));
 		vcpu->arch.cr0 = cr0;
 		vmx_set_cr4(vcpu, vcpu->arch.cr4);
-		if (!(vcpu->arch.cr0 & X86_CR0_WP))
-			*hw_cr0 &= ~X86_CR0_WP;
 	}
+
+	if (!(cr0 & X86_CR0_WP))
+		*hw_cr0 &= ~X86_CR0_WP;
 }
 
 static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
@@ -1598,15 +1667,21 @@ static void ept_update_paging_mode_cr4(unsigned long *hw_cr4,
 
 static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 {
-	unsigned long hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) |
-				KVM_VM_CR0_ALWAYS_ON;
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	unsigned long hw_cr0;
+
+	if (enable_unrestricted_guest)
+		hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST)
+			| KVM_VM_CR0_ALWAYS_ON_UNRESTRICTED_GUEST;
+	else
+		hw_cr0 = (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON;
 
 	vmx_fpu_deactivate(vcpu);
 
-	if (vcpu->arch.rmode.vm86_active && (cr0 & X86_CR0_PE))
+	if (vmx->rmode.vm86_active && (cr0 & X86_CR0_PE))
 		enter_pmode(vcpu);
 
-	if (!vcpu->arch.rmode.vm86_active && !(cr0 & X86_CR0_PE))
+	if (!vmx->rmode.vm86_active && !(cr0 & X86_CR0_PE))
 		enter_rmode(vcpu);
 
 #ifdef CONFIG_X86_64
@@ -1650,10 +1725,8 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 	if (enable_ept) {
 		eptp = construct_eptp(cr3);
 		vmcs_write64(EPT_POINTER, eptp);
-		ept_sync_context(eptp);
-		ept_load_pdptrs(vcpu);
 		guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
-			VMX_EPT_IDENTITY_PAGETABLE_ADDR;
+			vcpu->kvm->arch.ept_identity_map_addr;
 	}
 
 	vmx_flush_tlb(vcpu);
@@ -1664,7 +1737,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 
 static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
-	unsigned long hw_cr4 = cr4 | (vcpu->arch.rmode.vm86_active ?
+	unsigned long hw_cr4 = cr4 | (to_vmx(vcpu)->rmode.vm86_active ?
 		    KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON);
 
 	vcpu->arch.cr4 = cr4;
@@ -1707,16 +1780,13 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu,
 
 static int vmx_get_cpl(struct kvm_vcpu *vcpu)
 {
-	struct kvm_segment kvm_seg;
-
 	if (!(vcpu->arch.cr0 & X86_CR0_PE)) /* if real mode */
 		return 0;
 
 	if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */
 		return 3;
 
-	vmx_get_segment(vcpu, &kvm_seg, VCPU_SREG_CS);
-	return kvm_seg.selector & 3;
+	return vmcs_read16(GUEST_CS_SELECTOR) & 3;
 }
 
 static u32 vmx_segment_access_rights(struct kvm_segment *var)
@@ -1744,20 +1814,21 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var)
 static void vmx_set_segment(struct kvm_vcpu *vcpu,
 			    struct kvm_segment *var, int seg)
 {
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
 	u32 ar;
 
-	if (vcpu->arch.rmode.vm86_active && seg == VCPU_SREG_TR) {
-		vcpu->arch.rmode.tr.selector = var->selector;
-		vcpu->arch.rmode.tr.base = var->base;
-		vcpu->arch.rmode.tr.limit = var->limit;
-		vcpu->arch.rmode.tr.ar = vmx_segment_access_rights(var);
+	if (vmx->rmode.vm86_active && seg == VCPU_SREG_TR) {
+		vmx->rmode.tr.selector = var->selector;
+		vmx->rmode.tr.base = var->base;
+		vmx->rmode.tr.limit = var->limit;
+		vmx->rmode.tr.ar = vmx_segment_access_rights(var);
 		return;
 	}
 	vmcs_writel(sf->base, var->base);
 	vmcs_write32(sf->limit, var->limit);
 	vmcs_write16(sf->selector, var->selector);
-	if (vcpu->arch.rmode.vm86_active && var->s) {
+	if (vmx->rmode.vm86_active && var->s) {
 		/*
 		 * Hack real-mode segments into vm86 compatibility.
 		 */
@@ -1766,6 +1837,21 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu,
 		ar = 0xf3;
 	} else
 		ar = vmx_segment_access_rights(var);
+
+	/*
+	 *   Fix the "Accessed" bit in AR field of segment registers for older
+	 * qemu binaries.
+	 *   IA32 arch specifies that at the time of processor reset the
+	 * "Accessed" bit in the AR field of segment registers is 1. And qemu
+	 * is setting it to 0 in the usedland code. This causes invalid guest
+	 * state vmexit when "unrestricted guest" mode is turned on.
+	 *    Fix for this setup issue in cpu_reset is being pushed in the qemu
+	 * tree. Newer qemu binaries with that qemu fix would not need this
+	 * kvm hack.
+	 */
+	if (enable_unrestricted_guest && (seg != VCPU_SREG_LDTR))
+		ar |= 0x1; /* Accessed */
+
 	vmcs_write32(sf->ar_bytes, ar);
 }
 
@@ -2040,7 +2126,7 @@ static int init_rmode_identity_map(struct kvm *kvm)
 	if (likely(kvm->arch.ept_identity_pagetable_done))
 		return 1;
 	ret = 0;
-	identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT;
+	identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT;
 	r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
 	if (r < 0)
 		goto out;
@@ -2062,11 +2148,19 @@ out:
 static void seg_setup(int seg)
 {
 	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
+	unsigned int ar;
 
 	vmcs_write16(sf->selector, 0);
 	vmcs_writel(sf->base, 0);
 	vmcs_write32(sf->limit, 0xffff);
-	vmcs_write32(sf->ar_bytes, 0xf3);
+	if (enable_unrestricted_guest) {
+		ar = 0x93;
+		if (seg == VCPU_SREG_CS)
+			ar |= 0x08; /* code segment */
+	} else
+		ar = 0xf3;
+
+	vmcs_write32(sf->ar_bytes, ar);
 }
 
 static int alloc_apic_access_page(struct kvm *kvm)
@@ -2101,14 +2195,15 @@ static int alloc_identity_pagetable(struct kvm *kvm)
 		goto out;
 	kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
 	kvm_userspace_mem.flags = 0;
-	kvm_userspace_mem.guest_phys_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR;
+	kvm_userspace_mem.guest_phys_addr =
+		kvm->arch.ept_identity_map_addr;
 	kvm_userspace_mem.memory_size = PAGE_SIZE;
 	r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
 	if (r)
 		goto out;
 
 	kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
-			VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT);
+			kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
 out:
 	up_write(&kvm->slots_lock);
 	return r;
@@ -2209,6 +2304,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
 			exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
 		if (!enable_ept)
 			exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
+		if (!enable_unrestricted_guest)
+			exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
 		vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control);
 	}
 
@@ -2326,14 +2423,14 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
 		goto out;
 	}
 
-	vmx->vcpu.arch.rmode.vm86_active = 0;
+	vmx->rmode.vm86_active = 0;
 
 	vmx->soft_vnmi_blocked = 0;
 
 	vmx->vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val();
 	kvm_set_cr8(&vmx->vcpu, 0);
 	msr = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
-	if (vmx->vcpu.vcpu_id == 0)
+	if (kvm_vcpu_is_bsp(&vmx->vcpu))
 		msr |= MSR_IA32_APICBASE_BSP;
 	kvm_set_apic_base(&vmx->vcpu, msr);
 
@@ -2344,7 +2441,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
 	 * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
 	 * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4.  Sigh.
 	 */
-	if (vmx->vcpu.vcpu_id == 0) {
+	if (kvm_vcpu_is_bsp(&vmx->vcpu)) {
 		vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
 		vmcs_writel(GUEST_CS_BASE, 0x000f0000);
 	} else {
@@ -2373,7 +2470,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
 	vmcs_writel(GUEST_SYSENTER_EIP, 0);
 
 	vmcs_writel(GUEST_RFLAGS, 0x02);
-	if (vmx->vcpu.vcpu_id == 0)
+	if (kvm_vcpu_is_bsp(&vmx->vcpu))
 		kvm_rip_write(vcpu, 0xfff0);
 	else
 		kvm_rip_write(vcpu, 0);
@@ -2461,13 +2558,16 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu)
 	uint32_t intr;
 	int irq = vcpu->arch.interrupt.nr;
 
-	KVMTRACE_1D(INJ_VIRQ, vcpu, (u32)irq, handler);
+	trace_kvm_inj_virq(irq);
 
 	++vcpu->stat.irq_injections;
-	if (vcpu->arch.rmode.vm86_active) {
+	if (vmx->rmode.vm86_active) {
 		vmx->rmode.irq.pending = true;
 		vmx->rmode.irq.vector = irq;
 		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
+		if (vcpu->arch.interrupt.soft)
+			vmx->rmode.irq.rip +=
+				vmx->vcpu.arch.event_exit_inst_len;
 		vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
 			     irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
 		vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
@@ -2502,7 +2602,7 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
 	}
 
 	++vcpu->stat.nmi_injections;
-	if (vcpu->arch.rmode.vm86_active) {
+	if (vmx->rmode.vm86_active) {
 		vmx->rmode.irq.pending = true;
 		vmx->rmode.irq.vector = NMI_VECTOR;
 		vmx->rmode.irq.rip = kvm_rip_read(vcpu);
@@ -2659,14 +2759,14 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		if (enable_ept)
 			BUG();
 		cr2 = vmcs_readl(EXIT_QUALIFICATION);
-		KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
-			    (u32)((u64)cr2 >> 32), handler);
+		trace_kvm_page_fault(cr2, error_code);
+
 		if (kvm_event_needs_reinjection(vcpu))
 			kvm_mmu_unprotect_page_virt(vcpu, cr2);
 		return kvm_mmu_page_fault(vcpu, cr2, error_code);
 	}
 
-	if (vcpu->arch.rmode.vm86_active &&
+	if (vmx->rmode.vm86_active &&
 	    handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK,
 								error_code)) {
 		if (vcpu->arch.halt_request) {
@@ -2707,7 +2807,6 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu,
 				     struct kvm_run *kvm_run)
 {
 	++vcpu->stat.irq_exits;
-	KVMTRACE_1D(INTR, vcpu, vmcs_read32(VM_EXIT_INTR_INFO), handler);
 	return 1;
 }
 
@@ -2755,7 +2854,7 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall)
 
 static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	unsigned long exit_qualification;
+	unsigned long exit_qualification, val;
 	int cr;
 	int reg;
 
@@ -2764,21 +2863,19 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	reg = (exit_qualification >> 8) & 15;
 	switch ((exit_qualification >> 4) & 3) {
 	case 0: /* mov to cr */
-		KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr,
-			    (u32)kvm_register_read(vcpu, reg),
-			    (u32)((u64)kvm_register_read(vcpu, reg) >> 32),
-			    handler);
+		val = kvm_register_read(vcpu, reg);
+		trace_kvm_cr_write(cr, val);
 		switch (cr) {
 		case 0:
-			kvm_set_cr0(vcpu, kvm_register_read(vcpu, reg));
+			kvm_set_cr0(vcpu, val);
 			skip_emulated_instruction(vcpu);
 			return 1;
 		case 3:
-			kvm_set_cr3(vcpu, kvm_register_read(vcpu, reg));
+			kvm_set_cr3(vcpu, val);
 			skip_emulated_instruction(vcpu);
 			return 1;
 		case 4:
-			kvm_set_cr4(vcpu, kvm_register_read(vcpu, reg));
+			kvm_set_cr4(vcpu, val);
 			skip_emulated_instruction(vcpu);
 			return 1;
 		case 8: {
@@ -2800,23 +2897,19 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		vcpu->arch.cr0 &= ~X86_CR0_TS;
 		vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
 		vmx_fpu_activate(vcpu);
-		KVMTRACE_0D(CLTS, vcpu, handler);
 		skip_emulated_instruction(vcpu);
 		return 1;
 	case 1: /*mov from cr*/
 		switch (cr) {
 		case 3:
 			kvm_register_write(vcpu, reg, vcpu->arch.cr3);
-			KVMTRACE_3D(CR_READ, vcpu, (u32)cr,
-				    (u32)kvm_register_read(vcpu, reg),
-				    (u32)((u64)kvm_register_read(vcpu, reg) >> 32),
-				    handler);
+			trace_kvm_cr_read(cr, vcpu->arch.cr3);
 			skip_emulated_instruction(vcpu);
 			return 1;
 		case 8:
-			kvm_register_write(vcpu, reg, kvm_get_cr8(vcpu));
-			KVMTRACE_2D(CR_READ, vcpu, (u32)cr,
-				    (u32)kvm_register_read(vcpu, reg), handler);
+			val = kvm_get_cr8(vcpu);
+			kvm_register_write(vcpu, reg, val);
+			trace_kvm_cr_read(cr, val);
 			skip_emulated_instruction(vcpu);
 			return 1;
 		}
@@ -2841,6 +2934,8 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	unsigned long val;
 	int dr, reg;
 
+	if (!kvm_require_cpl(vcpu, 0))
+		return 1;
 	dr = vmcs_readl(GUEST_DR7);
 	if (dr & DR7_GD) {
 		/*
@@ -2884,7 +2979,6 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 			val = 0;
 		}
 		kvm_register_write(vcpu, reg, val);
-		KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
 	} else {
 		val = vcpu->arch.regs[reg];
 		switch (dr) {
@@ -2917,7 +3011,6 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 			}
 			break;
 		}
-		KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)val, handler);
 	}
 	skip_emulated_instruction(vcpu);
 	return 1;
@@ -2939,8 +3032,7 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		return 1;
 	}
 
-	KVMTRACE_3D(MSR_READ, vcpu, ecx, (u32)data, (u32)(data >> 32),
-		    handler);
+	trace_kvm_msr_read(ecx, data);
 
 	/* FIXME: handling of bits 32:63 of rax, rdx */
 	vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u;
@@ -2955,8 +3047,7 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
 		| ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
 
-	KVMTRACE_3D(MSR_WRITE, vcpu, ecx, (u32)data, (u32)(data >> 32),
-		    handler);
+	trace_kvm_msr_write(ecx, data);
 
 	if (vmx_set_msr(vcpu, ecx, data) != 0) {
 		kvm_inject_gp(vcpu, 0);
@@ -2983,7 +3074,6 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu,
 	cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
 	vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
 
-	KVMTRACE_0D(PEND_INTR, vcpu, handler);
 	++vcpu->stat.irq_window_exits;
 
 	/*
@@ -3049,7 +3139,7 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		printk(KERN_ERR
 		       "Fail to handle apic access vmexit! Offset is 0x%lx\n",
 		       offset);
-		return -ENOTSUPP;
+		return -ENOEXEC;
 	}
 	return 1;
 }
@@ -3118,7 +3208,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
 	if (exit_qualification & (1 << 6)) {
 		printk(KERN_ERR "EPT: GPA exceeds GAW!\n");
-		return -ENOTSUPP;
+		return -EINVAL;
 	}
 
 	gla_validity = (exit_qualification >> 7) & 0x3;
@@ -3130,14 +3220,98 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		printk(KERN_ERR "EPT: Exit qualification is 0x%lx\n",
 			(long unsigned int)exit_qualification);
 		kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
-		kvm_run->hw.hardware_exit_reason = 0;
-		return -ENOTSUPP;
+		kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_VIOLATION;
+		return 0;
 	}
 
 	gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
+	trace_kvm_page_fault(gpa, exit_qualification);
 	return kvm_mmu_page_fault(vcpu, gpa & PAGE_MASK, 0);
 }
 
+static u64 ept_rsvd_mask(u64 spte, int level)
+{
+	int i;
+	u64 mask = 0;
+
+	for (i = 51; i > boot_cpu_data.x86_phys_bits; i--)
+		mask |= (1ULL << i);
+
+	if (level > 2)
+		/* bits 7:3 reserved */
+		mask |= 0xf8;
+	else if (level == 2) {
+		if (spte & (1ULL << 7))
+			/* 2MB ref, bits 20:12 reserved */
+			mask |= 0x1ff000;
+		else
+			/* bits 6:3 reserved */
+			mask |= 0x78;
+	}
+
+	return mask;
+}
+
+static void ept_misconfig_inspect_spte(struct kvm_vcpu *vcpu, u64 spte,
+				       int level)
+{
+	printk(KERN_ERR "%s: spte 0x%llx level %d\n", __func__, spte, level);
+
+	/* 010b (write-only) */
+	WARN_ON((spte & 0x7) == 0x2);
+
+	/* 110b (write/execute) */
+	WARN_ON((spte & 0x7) == 0x6);
+
+	/* 100b (execute-only) and value not supported by logical processor */
+	if (!cpu_has_vmx_ept_execute_only())
+		WARN_ON((spte & 0x7) == 0x4);
+
+	/* not 000b */
+	if ((spte & 0x7)) {
+		u64 rsvd_bits = spte & ept_rsvd_mask(spte, level);
+
+		if (rsvd_bits != 0) {
+			printk(KERN_ERR "%s: rsvd_bits = 0x%llx\n",
+					 __func__, rsvd_bits);
+			WARN_ON(1);
+		}
+
+		if (level == 1 || (level == 2 && (spte & (1ULL << 7)))) {
+			u64 ept_mem_type = (spte & 0x38) >> 3;
+
+			if (ept_mem_type == 2 || ept_mem_type == 3 ||
+			    ept_mem_type == 7) {
+				printk(KERN_ERR "%s: ept_mem_type=0x%llx\n",
+						__func__, ept_mem_type);
+				WARN_ON(1);
+			}
+		}
+	}
+}
+
+static int handle_ept_misconfig(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+	u64 sptes[4];
+	int nr_sptes, i;
+	gpa_t gpa;
+
+	gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS);
+
+	printk(KERN_ERR "EPT: Misconfiguration.\n");
+	printk(KERN_ERR "EPT: GPA: 0x%llx\n", gpa);
+
+	nr_sptes = kvm_mmu_get_spte_hierarchy(vcpu, gpa, sptes);
+
+	for (i = PT64_ROOT_LEVEL; i > PT64_ROOT_LEVEL - nr_sptes; --i)
+		ept_misconfig_inspect_spte(vcpu, sptes[i-1], i);
+
+	kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
+	kvm_run->hw.hardware_exit_reason = EXIT_REASON_EPT_MISCONFIG;
+
+	return 0;
+}
+
 static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	u32 cpu_based_vm_exec_control;
@@ -3217,8 +3391,9 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
 	[EXIT_REASON_APIC_ACCESS]             = handle_apic_access,
 	[EXIT_REASON_WBINVD]                  = handle_wbinvd,
 	[EXIT_REASON_TASK_SWITCH]             = handle_task_switch,
-	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
 	[EXIT_REASON_MCE_DURING_VMENTRY]      = handle_machine_check,
+	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
+	[EXIT_REASON_EPT_MISCONFIG]           = handle_ept_misconfig,
 };
 
 static const int kvm_vmx_max_exit_handlers =
@@ -3234,8 +3409,7 @@ static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 	u32 exit_reason = vmx->exit_reason;
 	u32 vectoring_info = vmx->idt_vectoring_info;
 
-	KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu),
-		    (u32)((u64)kvm_rip_read(vcpu) >> 32), entryexit);
+	trace_kvm_exit(exit_reason, kvm_rip_read(vcpu));
 
 	/* If we need to emulate an MMIO from handle_invalid_guest_state
 	 * we just return 0 */
@@ -3247,10 +3421,8 @@ static int vmx_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 
 	/* Access CR3 don't cause VMExit in paging mode, so we need
 	 * to sync with guest real CR3. */
-	if (enable_ept && is_paging(vcpu)) {
+	if (enable_ept && is_paging(vcpu))
 		vcpu->arch.cr3 = vmcs_readl(GUEST_CR3);
-		ept_load_pdptrs(vcpu);
-	}
 
 	if (unlikely(vmx->fail)) {
 		kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
@@ -3326,10 +3498,8 @@ static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
 
 	/* We need to handle NMIs before interrupts are enabled */
 	if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
-	    (exit_intr_info & INTR_INFO_VALID_MASK)) {
-		KVMTRACE_0D(NMI, &vmx->vcpu, handler);
+	    (exit_intr_info & INTR_INFO_VALID_MASK))
 		asm("int $2");
-	}
 
 	idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
 
@@ -3434,6 +3604,10 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 
+	if (enable_ept && is_paging(vcpu)) {
+		vmcs_writel(GUEST_CR3, vcpu->arch.cr3);
+		ept_load_pdptrs(vcpu);
+	}
 	/* Record the guest's net vcpu time for enforced NMI injections. */
 	if (unlikely(!cpu_has_virtual_nmis() && vmx->soft_vnmi_blocked))
 		vmx->entry_time = ktime_get();
@@ -3449,12 +3623,21 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
 		vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
 
+	/* When single-stepping over STI and MOV SS, we must clear the
+	 * corresponding interruptibility bits in the guest state. Otherwise
+	 * vmentry fails as it then expects bit 14 (BS) in pending debug
+	 * exceptions being set, but that's not correct for the guest debugging
+	 * case. */
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+		vmx_set_interrupt_shadow(vcpu, 0);
+
 	/*
 	 * Loading guest fpu may have cleared host cr0.ts
 	 */
 	vmcs_writel(HOST_CR0, read_cr0());
 
-	set_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		set_debugreg(vcpu->arch.dr6, 6);
 
 	asm(
 		/* Store host registers */
@@ -3465,11 +3648,16 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		"mov %%"R"sp, %c[host_rsp](%0) \n\t"
 		__ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
 		"1: \n\t"
+		/* Reload cr2 if changed */
+		"mov %c[cr2](%0), %%"R"ax \n\t"
+		"mov %%cr2, %%"R"dx \n\t"
+		"cmp %%"R"ax, %%"R"dx \n\t"
+		"je 2f \n\t"
+		"mov %%"R"ax, %%cr2 \n\t"
+		"2: \n\t"
 		/* Check if vmlaunch of vmresume is needed */
 		"cmpl $0, %c[launched](%0) \n\t"
 		/* Load guest registers.  Don't clobber flags. */
-		"mov %c[cr2](%0), %%"R"ax \n\t"
-		"mov %%"R"ax, %%cr2 \n\t"
 		"mov %c[rax](%0), %%"R"ax \n\t"
 		"mov %c[rbx](%0), %%"R"bx \n\t"
 		"mov %c[rdx](%0), %%"R"dx \n\t"
@@ -3547,10 +3735,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 #endif
 	      );
 
-	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
+	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
+				  | (1 << VCPU_EXREG_PDPTR));
 	vcpu->arch.regs_dirty = 0;
 
-	get_debugreg(vcpu->arch.dr6, 6);
+	if (vcpu->arch.switch_db_regs)
+		get_debugreg(vcpu->arch.dr6, 6);
 
 	vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
 	if (vmx->rmode.irq.pending)
@@ -3633,9 +3823,13 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
 		if (alloc_apic_access_page(kvm) != 0)
 			goto free_vmcs;
 
-	if (enable_ept)
+	if (enable_ept) {
+		if (!kvm->arch.ept_identity_map_addr)
+			kvm->arch.ept_identity_map_addr =
+				VMX_EPT_IDENTITY_PAGETABLE_ADDR;
 		if (alloc_identity_pagetable(kvm) != 0)
 			goto free_vmcs;
+	}
 
 	return &vmx->vcpu;
 
@@ -3699,6 +3893,34 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
 	return ret;
 }
 
+static const struct trace_print_flags vmx_exit_reasons_str[] = {
+	{ EXIT_REASON_EXCEPTION_NMI,           "exception" },
+	{ EXIT_REASON_EXTERNAL_INTERRUPT,      "ext_irq" },
+	{ EXIT_REASON_TRIPLE_FAULT,            "triple_fault" },
+	{ EXIT_REASON_NMI_WINDOW,              "nmi_window" },
+	{ EXIT_REASON_IO_INSTRUCTION,          "io_instruction" },
+	{ EXIT_REASON_CR_ACCESS,               "cr_access" },
+	{ EXIT_REASON_DR_ACCESS,               "dr_access" },
+	{ EXIT_REASON_CPUID,                   "cpuid" },
+	{ EXIT_REASON_MSR_READ,                "rdmsr" },
+	{ EXIT_REASON_MSR_WRITE,               "wrmsr" },
+	{ EXIT_REASON_PENDING_INTERRUPT,       "interrupt_window" },
+	{ EXIT_REASON_HLT,                     "halt" },
+	{ EXIT_REASON_INVLPG,                  "invlpg" },
+	{ EXIT_REASON_VMCALL,                  "hypercall" },
+	{ EXIT_REASON_TPR_BELOW_THRESHOLD,     "tpr_below_thres" },
+	{ EXIT_REASON_APIC_ACCESS,             "apic_access" },
+	{ EXIT_REASON_WBINVD,                  "wbinvd" },
+	{ EXIT_REASON_TASK_SWITCH,             "task_switch" },
+	{ EXIT_REASON_EPT_VIOLATION,           "ept_violation" },
+	{ -1, NULL }
+};
+
+static bool vmx_gb_page_enable(void)
+{
+	return false;
+}
+
 static struct kvm_x86_ops vmx_x86_ops = {
 	.cpu_has_kvm_support = cpu_has_kvm_support,
 	.disabled_by_bios = vmx_disabled_by_bios,
@@ -3758,6 +3980,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
 	.set_tss_addr = vmx_set_tss_addr,
 	.get_tdp_level = get_ept_level,
 	.get_mt_mask = vmx_get_mt_mask,
+
+	.exit_reasons_str = vmx_exit_reasons_str,
+	.gb_page_enable = vmx_gb_page_enable,
 };
 
 static int __init vmx_init(void)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3d45290..be451ee 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -37,11 +37,16 @@
 #include <linux/iommu.h>
 #include <linux/intel-iommu.h>
 #include <linux/cpufreq.h>
+#include <trace/events/kvm.h>
+#undef TRACE_INCLUDE_FILE
+#define CREATE_TRACE_POINTS
+#include "trace.h"
 
 #include <asm/uaccess.h>
 #include <asm/msr.h>
 #include <asm/desc.h>
 #include <asm/mtrr.h>
+#include <asm/mce.h>
 
 #define MAX_IO_MSRS 256
 #define CR0_RESERVED_BITS						\
@@ -55,6 +60,10 @@
 			  | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
 
 #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
+
+#define KVM_MAX_MCE_BANKS 32
+#define KVM_MCE_CAP_SUPPORTED MCG_CTL_P
+
 /* EFER defaults:
  * - enable syscall per default because its emulated by KVM
  * - enable LME and LMA per default on 64 bit KVM
@@ -68,14 +77,16 @@ static u64 __read_mostly efer_reserved_bits = 0xfffffffffffffffeULL;
 #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
 #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
 
+static void update_cr8_intercept(struct kvm_vcpu *vcpu);
 static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
 				    struct kvm_cpuid_entry2 __user *entries);
-struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
-					      u32 function, u32 index);
 
 struct kvm_x86_ops *kvm_x86_ops;
 EXPORT_SYMBOL_GPL(kvm_x86_ops);
 
+int ignore_msrs = 0;
+module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
+
 struct kvm_stats_debugfs_item debugfs_entries[] = {
 	{ "pf_fixed", VCPU_STAT(pf_fixed) },
 	{ "pf_guest", VCPU_STAT(pf_guest) },
@@ -122,18 +133,16 @@ unsigned long segment_base(u16 selector)
 	if (selector == 0)
 		return 0;
 
-	asm("sgdt %0" : "=m"(gdt));
+	kvm_get_gdt(&gdt);
 	table_base = gdt.base;
 
 	if (selector & 4) {           /* from ldt */
-		u16 ldt_selector;
+		u16 ldt_selector = kvm_read_ldt();
 
-		asm("sldt %0" : "=g"(ldt_selector));
 		table_base = segment_base(ldt_selector);
 	}
 	d = (struct desc_struct *)(table_base + (selector & ~7));
-	v = d->base0 | ((unsigned long)d->base1 << 16) |
-		((unsigned long)d->base2 << 24);
+	v = get_desc_base(d);
 #ifdef CONFIG_X86_64
 	if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
 		v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32;
@@ -176,16 +185,22 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr,
 	++vcpu->stat.pf_guest;
 
 	if (vcpu->arch.exception.pending) {
-		if (vcpu->arch.exception.nr == PF_VECTOR) {
-			printk(KERN_DEBUG "kvm: inject_page_fault:"
-					" double fault 0x%lx\n", addr);
-			vcpu->arch.exception.nr = DF_VECTOR;
-			vcpu->arch.exception.error_code = 0;
-		} else if (vcpu->arch.exception.nr == DF_VECTOR) {
+		switch(vcpu->arch.exception.nr) {
+		case DF_VECTOR:
 			/* triple fault -> shutdown */
 			set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
+			return;
+		case PF_VECTOR:
+			vcpu->arch.exception.nr = DF_VECTOR;
+			vcpu->arch.exception.error_code = 0;
+			return;
+		default:
+			/* replace previous exception with a new one in a hope
+			   that instruction re-execution will regenerate lost
+			   exception */
+			vcpu->arch.exception.pending = false;
+			break;
 		}
-		return;
 	}
 	vcpu->arch.cr2 = addr;
 	kvm_queue_exception_e(vcpu, PF_VECTOR, error_code);
@@ -207,12 +222,18 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
 }
 EXPORT_SYMBOL_GPL(kvm_queue_exception_e);
 
-static void __queue_exception(struct kvm_vcpu *vcpu)
+/*
+ * Checks if cpl <= required_cpl; if true, return true.  Otherwise queue
+ * a #GP and return false.
+ */
+bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl)
 {
-	kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr,
-				     vcpu->arch.exception.has_error_code,
-				     vcpu->arch.exception.error_code);
+	if (kvm_x86_ops->get_cpl(vcpu) <= required_cpl)
+		return true;
+	kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
+	return false;
 }
+EXPORT_SYMBOL_GPL(kvm_require_cpl);
 
 /*
  * Load the pae pdptrs.  Return true is they are all valid.
@@ -232,7 +253,7 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
 		goto out;
 	}
 	for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
-		if (is_present_pte(pdpte[i]) &&
+		if (is_present_gpte(pdpte[i]) &&
 		    (pdpte[i] & vcpu->arch.mmu.rsvd_bits_mask[0][2])) {
 			ret = 0;
 			goto out;
@@ -241,6 +262,10 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
 	ret = 1;
 
 	memcpy(vcpu->arch.pdptrs, pdpte, sizeof(vcpu->arch.pdptrs));
+	__set_bit(VCPU_EXREG_PDPTR,
+		  (unsigned long *)&vcpu->arch.regs_avail);
+	__set_bit(VCPU_EXREG_PDPTR,
+		  (unsigned long *)&vcpu->arch.regs_dirty);
 out:
 
 	return ret;
@@ -256,6 +281,10 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu)
 	if (is_long_mode(vcpu) || !is_pae(vcpu))
 		return false;
 
+	if (!test_bit(VCPU_EXREG_PDPTR,
+		      (unsigned long *)&vcpu->arch.regs_avail))
+		return true;
+
 	r = kvm_read_guest(vcpu->kvm, vcpu->arch.cr3 & ~31u, pdpte, sizeof(pdpte));
 	if (r < 0)
 		goto out;
@@ -328,9 +357,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0);
 void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
 {
 	kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f));
-	KVMTRACE_1D(LMSW, vcpu,
-		    (u32)((vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)),
-		    handler);
 }
 EXPORT_SYMBOL_GPL(kvm_lmsw);
 
@@ -466,7 +492,7 @@ static u32 msrs_to_save[] = {
 #ifdef CONFIG_X86_64
 	MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
 #endif
-	MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
+	MSR_IA32_TSC, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK,
 	MSR_IA32_PERF_STATUS, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA
 };
 
@@ -644,8 +670,7 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
 
 	/* Keep irq disabled to prevent changes to the clock */
 	local_irq_save(flags);
-	kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER,
-			  &vcpu->hv_clock.tsc_timestamp);
+	kvm_get_msr(v, MSR_IA32_TSC, &vcpu->hv_clock.tsc_timestamp);
 	ktime_get_ts(&ts);
 	local_irq_restore(flags);
 
@@ -778,23 +803,60 @@ static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 	return 0;
 }
 
+static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+	u64 mcg_cap = vcpu->arch.mcg_cap;
+	unsigned bank_num = mcg_cap & 0xff;
+
+	switch (msr) {
+	case MSR_IA32_MCG_STATUS:
+		vcpu->arch.mcg_status = data;
+		break;
+	case MSR_IA32_MCG_CTL:
+		if (!(mcg_cap & MCG_CTL_P))
+			return 1;
+		if (data != 0 && data != ~(u64)0)
+			return -1;
+		vcpu->arch.mcg_ctl = data;
+		break;
+	default:
+		if (msr >= MSR_IA32_MC0_CTL &&
+		    msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
+			u32 offset = msr - MSR_IA32_MC0_CTL;
+			/* only 0 or all 1s can be written to IA32_MCi_CTL */
+			if ((offset & 0x3) == 0 &&
+			    data != 0 && data != ~(u64)0)
+				return -1;
+			vcpu->arch.mce_banks[offset] = data;
+			break;
+		}
+		return 1;
+	}
+	return 0;
+}
+
 int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 {
 	switch (msr) {
 	case MSR_EFER:
 		set_efer(vcpu, data);
 		break;
-	case MSR_IA32_MC0_STATUS:
-		pr_unimpl(vcpu, "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n",
-		       __func__, data);
+	case MSR_K7_HWCR:
+		data &= ~(u64)0x40;	/* ignore flush filter disable */
+		if (data != 0) {
+			pr_unimpl(vcpu, "unimplemented HWCR wrmsr: 0x%llx\n",
+				data);
+			return 1;
+		}
 		break;
-	case MSR_IA32_MCG_STATUS:
-		pr_unimpl(vcpu, "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n",
-			__func__, data);
+	case MSR_FAM10H_MMIO_CONF_BASE:
+		if (data != 0) {
+			pr_unimpl(vcpu, "unimplemented MMIO_CONF_BASE wrmsr: "
+				"0x%llx\n", data);
+			return 1;
+		}
 		break;
-	case MSR_IA32_MCG_CTL:
-		pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n",
-			__func__, data);
+	case MSR_AMD64_NB_CFG:
 		break;
 	case MSR_IA32_DEBUGCTLMSR:
 		if (!data) {
@@ -811,12 +873,15 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 	case MSR_IA32_UCODE_REV:
 	case MSR_IA32_UCODE_WRITE:
 	case MSR_VM_HSAVE_PA:
+	case MSR_AMD64_PATCH_LOADER:
 		break;
 	case 0x200 ... 0x2ff:
 		return set_msr_mtrr(vcpu, msr, data);
 	case MSR_IA32_APICBASE:
 		kvm_set_apic_base(vcpu, data);
 		break;
+	case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff:
+		return kvm_x2apic_msr_write(vcpu, msr, data);
 	case MSR_IA32_MISC_ENABLE:
 		vcpu->arch.ia32_misc_enable_msr = data;
 		break;
@@ -850,9 +915,50 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 		kvm_request_guest_time_update(vcpu);
 		break;
 	}
+	case MSR_IA32_MCG_CTL:
+	case MSR_IA32_MCG_STATUS:
+	case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
+		return set_msr_mce(vcpu, msr, data);
+
+	/* Performance counters are not protected by a CPUID bit,
+	 * so we should check all of them in the generic path for the sake of
+	 * cross vendor migration.
+	 * Writing a zero into the event select MSRs disables them,
+	 * which we perfectly emulate ;-). Any other value should be at least
+	 * reported, some guests depend on them.
+	 */
+	case MSR_P6_EVNTSEL0:
+	case MSR_P6_EVNTSEL1:
+	case MSR_K7_EVNTSEL0:
+	case MSR_K7_EVNTSEL1:
+	case MSR_K7_EVNTSEL2:
+	case MSR_K7_EVNTSEL3:
+		if (data != 0)
+			pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
+				"0x%x data 0x%llx\n", msr, data);
+		break;
+	/* at least RHEL 4 unconditionally writes to the perfctr registers,
+	 * so we ignore writes to make it happy.
+	 */
+	case MSR_P6_PERFCTR0:
+	case MSR_P6_PERFCTR1:
+	case MSR_K7_PERFCTR0:
+	case MSR_K7_PERFCTR1:
+	case MSR_K7_PERFCTR2:
+	case MSR_K7_PERFCTR3:
+		pr_unimpl(vcpu, "unimplemented perfctr wrmsr: "
+			"0x%x data 0x%llx\n", msr, data);
+		break;
 	default:
-		pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data);
-		return 1;
+		if (!ignore_msrs) {
+			pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n",
+				msr, data);
+			return 1;
+		} else {
+			pr_unimpl(vcpu, "ignored wrmsr: 0x%x data %llx\n",
+				msr, data);
+			break;
+		}
 	}
 	return 0;
 }
@@ -905,26 +1011,47 @@ static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	return 0;
 }
 
-int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 {
 	u64 data;
+	u64 mcg_cap = vcpu->arch.mcg_cap;
+	unsigned bank_num = mcg_cap & 0xff;
 
 	switch (msr) {
-	case 0xc0010010: /* SYSCFG */
-	case 0xc0010015: /* HWCR */
-	case MSR_IA32_PLATFORM_ID:
 	case MSR_IA32_P5_MC_ADDR:
 	case MSR_IA32_P5_MC_TYPE:
-	case MSR_IA32_MC0_CTL:
-	case MSR_IA32_MCG_STATUS:
+		data = 0;
+		break;
 	case MSR_IA32_MCG_CAP:
+		data = vcpu->arch.mcg_cap;
+		break;
 	case MSR_IA32_MCG_CTL:
-	case MSR_IA32_MC0_MISC:
-	case MSR_IA32_MC0_MISC+4:
-	case MSR_IA32_MC0_MISC+8:
-	case MSR_IA32_MC0_MISC+12:
-	case MSR_IA32_MC0_MISC+16:
-	case MSR_IA32_MC0_MISC+20:
+		if (!(mcg_cap & MCG_CTL_P))
+			return 1;
+		data = vcpu->arch.mcg_ctl;
+		break;
+	case MSR_IA32_MCG_STATUS:
+		data = vcpu->arch.mcg_status;
+		break;
+	default:
+		if (msr >= MSR_IA32_MC0_CTL &&
+		    msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
+			u32 offset = msr - MSR_IA32_MC0_CTL;
+			data = vcpu->arch.mce_banks[offset];
+			break;
+		}
+		return 1;
+	}
+	*pdata = data;
+	return 0;
+}
+
+int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
+{
+	u64 data;
+
+	switch (msr) {
+	case MSR_IA32_PLATFORM_ID:
 	case MSR_IA32_UCODE_REV:
 	case MSR_IA32_EBL_CR_POWERON:
 	case MSR_IA32_DEBUGCTLMSR:
@@ -932,10 +1059,18 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case MSR_IA32_LASTBRANCHTOIP:
 	case MSR_IA32_LASTINTFROMIP:
 	case MSR_IA32_LASTINTTOIP:
+	case MSR_K8_SYSCFG:
+	case MSR_K7_HWCR:
 	case MSR_VM_HSAVE_PA:
+	case MSR_P6_PERFCTR0:
+	case MSR_P6_PERFCTR1:
 	case MSR_P6_EVNTSEL0:
 	case MSR_P6_EVNTSEL1:
 	case MSR_K7_EVNTSEL0:
+	case MSR_K7_PERFCTR0:
+	case MSR_K8_INT_PENDING_MSG:
+	case MSR_AMD64_NB_CFG:
+	case MSR_FAM10H_MMIO_CONF_BASE:
 		data = 0;
 		break;
 	case MSR_MTRRcap:
@@ -949,6 +1084,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case MSR_IA32_APICBASE:
 		data = kvm_get_apic_base(vcpu);
 		break;
+	case APIC_BASE_MSR ... APIC_BASE_MSR + 0x3ff:
+		return kvm_x2apic_msr_read(vcpu, msr, pdata);
+		break;
 	case MSR_IA32_MISC_ENABLE:
 		data = vcpu->arch.ia32_misc_enable_msr;
 		break;
@@ -967,9 +1105,22 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 	case MSR_KVM_SYSTEM_TIME:
 		data = vcpu->arch.time;
 		break;
+	case MSR_IA32_P5_MC_ADDR:
+	case MSR_IA32_P5_MC_TYPE:
+	case MSR_IA32_MCG_CAP:
+	case MSR_IA32_MCG_CTL:
+	case MSR_IA32_MCG_STATUS:
+	case MSR_IA32_MC0_CTL ... MSR_IA32_MC0_CTL + 4 * KVM_MAX_MCE_BANKS - 1:
+		return get_msr_mce(vcpu, msr, pdata);
 	default:
-		pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
-		return 1;
+		if (!ignore_msrs) {
+			pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
+			return 1;
+		} else {
+			pr_unimpl(vcpu, "ignored rdmsr: 0x%x\n", msr);
+			data = 0;
+		}
+		break;
 	}
 	*pdata = data;
 	return 0;
@@ -1068,6 +1219,11 @@ int kvm_dev_ioctl_check_extension(long ext)
 	case KVM_CAP_REINJECT_CONTROL:
 	case KVM_CAP_IRQ_INJECT_STATUS:
 	case KVM_CAP_ASSIGN_DEV_IRQ:
+	case KVM_CAP_IRQFD:
+	case KVM_CAP_IOEVENTFD:
+	case KVM_CAP_PIT2:
+	case KVM_CAP_PIT_STATE2:
+	case KVM_CAP_SET_IDENTITY_MAP_ADDR:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -1088,6 +1244,9 @@ int kvm_dev_ioctl_check_extension(long ext)
 	case KVM_CAP_IOMMU:
 		r = iommu_found();
 		break;
+	case KVM_CAP_MCE:
+		r = KVM_MAX_MCE_BANKS;
+		break;
 	default:
 		r = 0;
 		break;
@@ -1147,6 +1306,16 @@ long kvm_arch_dev_ioctl(struct file *filp,
 		r = 0;
 		break;
 	}
+	case KVM_X86_GET_MCE_CAP_SUPPORTED: {
+		u64 mce_cap;
+
+		mce_cap = KVM_MCE_CAP_SUPPORTED;
+		r = -EFAULT;
+		if (copy_to_user(argp, &mce_cap, sizeof mce_cap))
+			goto out;
+		r = 0;
+		break;
+	}
 	default:
 		r = -EINVAL;
 	}
@@ -1227,6 +1396,7 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
 	vcpu->arch.cpuid_nent = cpuid->nent;
 	cpuid_fix_nx_cap(vcpu);
 	r = 0;
+	kvm_apic_set_version(vcpu);
 
 out_free:
 	vfree(cpuid_entries);
@@ -1248,6 +1418,7 @@ static int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
 			   cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
 		goto out;
 	vcpu->arch.cpuid_nent = cpuid->nent;
+	kvm_apic_set_version(vcpu);
 	return 0;
 
 out:
@@ -1290,6 +1461,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 			 u32 index, int *nent, int maxnent)
 {
 	unsigned f_nx = is_efer_nx() ? F(NX) : 0;
+	unsigned f_gbpages = kvm_x86_ops->gb_page_enable() ? F(GBPAGES) : 0;
 #ifdef CONFIG_X86_64
 	unsigned f_lm = F(LM);
 #else
@@ -1314,7 +1486,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 		F(MTRR) | F(PGE) | F(MCA) | F(CMOV) |
 		F(PAT) | F(PSE36) | 0 /* Reserved */ |
 		f_nx | 0 /* Reserved */ | F(MMXEXT) | F(MMX) |
-		F(FXSR) | F(FXSR_OPT) | 0 /* GBPAGES */ | 0 /* RDTSCP */ |
+		F(FXSR) | F(FXSR_OPT) | f_gbpages | 0 /* RDTSCP */ |
 		0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
 	/* cpuid 1.ecx */
 	const u32 kvm_supported_word4_x86_features =
@@ -1323,7 +1495,7 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 		0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
 		0 /* Reserved */ | F(CX16) | 0 /* xTPR Update, PDCM */ |
 		0 /* Reserved, DCA */ | F(XMM4_1) |
-		F(XMM4_2) | 0 /* x2APIC */ | F(MOVBE) | F(POPCNT) |
+		F(XMM4_2) | F(X2APIC) | F(MOVBE) | F(POPCNT) |
 		0 /* Reserved, XSAVE, OSXSAVE */;
 	/* cpuid 0x80000001.ecx */
 	const u32 kvm_supported_word6_x86_features =
@@ -1344,6 +1516,9 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 	case 1:
 		entry->edx &= kvm_supported_word0_x86_features;
 		entry->ecx &= kvm_supported_word4_x86_features;
+		/* we support x2apic emulation even if host does not support
+		 * it since we emulate x2apic in software */
+		entry->ecx |= F(X2APIC);
 		break;
 	/* function 2 entries are STATEFUL. That is, repeated cpuid commands
 	 * may return different values. This forces us to get_cpu() before
@@ -1435,6 +1610,10 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
 	for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
 		do_cpuid_ent(&cpuid_entries[nent], func, 0,
 			     &nent, cpuid->nent);
+	r = -E2BIG;
+	if (nent >= cpuid->nent)
+		goto out_free;
+
 	r = -EFAULT;
 	if (copy_to_user(entries, cpuid_entries,
 			 nent * sizeof(struct kvm_cpuid_entry2)))
@@ -1464,6 +1643,7 @@ static int kvm_vcpu_ioctl_set_lapic(struct kvm_vcpu *vcpu,
 	vcpu_load(vcpu);
 	memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s);
 	kvm_apic_post_state_restore(vcpu);
+	update_cr8_intercept(vcpu);
 	vcpu_put(vcpu);
 
 	return 0;
@@ -1503,6 +1683,80 @@ static int vcpu_ioctl_tpr_access_reporting(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
+					u64 mcg_cap)
+{
+	int r;
+	unsigned bank_num = mcg_cap & 0xff, bank;
+
+	r = -EINVAL;
+	if (!bank_num)
+		goto out;
+	if (mcg_cap & ~(KVM_MCE_CAP_SUPPORTED | 0xff | 0xff0000))
+		goto out;
+	r = 0;
+	vcpu->arch.mcg_cap = mcg_cap;
+	/* Init IA32_MCG_CTL to all 1s */
+	if (mcg_cap & MCG_CTL_P)
+		vcpu->arch.mcg_ctl = ~(u64)0;
+	/* Init IA32_MCi_CTL to all 1s */
+	for (bank = 0; bank < bank_num; bank++)
+		vcpu->arch.mce_banks[bank*4] = ~(u64)0;
+out:
+	return r;
+}
+
+static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
+				      struct kvm_x86_mce *mce)
+{
+	u64 mcg_cap = vcpu->arch.mcg_cap;
+	unsigned bank_num = mcg_cap & 0xff;
+	u64 *banks = vcpu->arch.mce_banks;
+
+	if (mce->bank >= bank_num || !(mce->status & MCI_STATUS_VAL))
+		return -EINVAL;
+	/*
+	 * if IA32_MCG_CTL is not all 1s, the uncorrected error
+	 * reporting is disabled
+	 */
+	if ((mce->status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
+	    vcpu->arch.mcg_ctl != ~(u64)0)
+		return 0;
+	banks += 4 * mce->bank;
+	/*
+	 * if IA32_MCi_CTL is not all 1s, the uncorrected error
+	 * reporting is disabled for the bank
+	 */
+	if ((mce->status & MCI_STATUS_UC) && banks[0] != ~(u64)0)
+		return 0;
+	if (mce->status & MCI_STATUS_UC) {
+		if ((vcpu->arch.mcg_status & MCG_STATUS_MCIP) ||
+		    !(vcpu->arch.cr4 & X86_CR4_MCE)) {
+			printk(KERN_DEBUG "kvm: set_mce: "
+			       "injects mce exception while "
+			       "previous one is in progress!\n");
+			set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
+			return 0;
+		}
+		if (banks[1] & MCI_STATUS_VAL)
+			mce->status |= MCI_STATUS_OVER;
+		banks[2] = mce->addr;
+		banks[3] = mce->misc;
+		vcpu->arch.mcg_status = mce->mcg_status;
+		banks[1] = mce->status;
+		kvm_queue_exception(vcpu, MC_VECTOR);
+	} else if (!(banks[1] & MCI_STATUS_VAL)
+		   || !(banks[1] & MCI_STATUS_UC)) {
+		if (banks[1] & MCI_STATUS_VAL)
+			mce->status |= MCI_STATUS_OVER;
+		banks[2] = mce->addr;
+		banks[3] = mce->misc;
+		banks[1] = mce->status;
+	} else
+		banks[1] |= MCI_STATUS_OVER;
+	return 0;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg)
 {
@@ -1636,6 +1890,24 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 		kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
 		break;
 	}
+	case KVM_X86_SETUP_MCE: {
+		u64 mcg_cap;
+
+		r = -EFAULT;
+		if (copy_from_user(&mcg_cap, argp, sizeof mcg_cap))
+			goto out;
+		r = kvm_vcpu_ioctl_x86_setup_mce(vcpu, mcg_cap);
+		break;
+	}
+	case KVM_X86_SET_MCE: {
+		struct kvm_x86_mce mce;
+
+		r = -EFAULT;
+		if (copy_from_user(&mce, argp, sizeof mce))
+			goto out;
+		r = kvm_vcpu_ioctl_x86_set_mce(vcpu, &mce);
+		break;
+	}
 	default:
 		r = -EINVAL;
 	}
@@ -1654,6 +1926,13 @@ static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
 	return ret;
 }
 
+static int kvm_vm_ioctl_set_identity_map_addr(struct kvm *kvm,
+					      u64 ident_addr)
+{
+	kvm->arch.ept_identity_map_addr = ident_addr;
+	return 0;
+}
+
 static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
 					  u32 kvm_nr_mmu_pages)
 {
@@ -1775,19 +2054,25 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip)
 	r = 0;
 	switch (chip->chip_id) {
 	case KVM_IRQCHIP_PIC_MASTER:
+		spin_lock(&pic_irqchip(kvm)->lock);
 		memcpy(&pic_irqchip(kvm)->pics[0],
 			&chip->chip.pic,
 			sizeof(struct kvm_pic_state));
+		spin_unlock(&pic_irqchip(kvm)->lock);
 		break;
 	case KVM_IRQCHIP_PIC_SLAVE:
+		spin_lock(&pic_irqchip(kvm)->lock);
 		memcpy(&pic_irqchip(kvm)->pics[1],
 			&chip->chip.pic,
 			sizeof(struct kvm_pic_state));
+		spin_unlock(&pic_irqchip(kvm)->lock);
 		break;
 	case KVM_IRQCHIP_IOAPIC:
+		mutex_lock(&kvm->irq_lock);
 		memcpy(ioapic_irqchip(kvm),
 			&chip->chip.ioapic,
 			sizeof(struct kvm_ioapic_state));
+		mutex_unlock(&kvm->irq_lock);
 		break;
 	default:
 		r = -EINVAL;
@@ -1801,7 +2086,9 @@ static int kvm_vm_ioctl_get_pit(struct kvm *kvm, struct kvm_pit_state *ps)
 {
 	int r = 0;
 
+	mutex_lock(&kvm->arch.vpit->pit_state.lock);
 	memcpy(ps, &kvm->arch.vpit->pit_state, sizeof(struct kvm_pit_state));
+	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
 	return r;
 }
 
@@ -1809,8 +2096,39 @@ static int kvm_vm_ioctl_set_pit(struct kvm *kvm, struct kvm_pit_state *ps)
 {
 	int r = 0;
 
+	mutex_lock(&kvm->arch.vpit->pit_state.lock);
 	memcpy(&kvm->arch.vpit->pit_state, ps, sizeof(struct kvm_pit_state));
-	kvm_pit_load_count(kvm, 0, ps->channels[0].count);
+	kvm_pit_load_count(kvm, 0, ps->channels[0].count, 0);
+	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
+	return r;
+}
+
+static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
+{
+	int r = 0;
+
+	mutex_lock(&kvm->arch.vpit->pit_state.lock);
+	memcpy(ps->channels, &kvm->arch.vpit->pit_state.channels,
+		sizeof(ps->channels));
+	ps->flags = kvm->arch.vpit->pit_state.flags;
+	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
+	return r;
+}
+
+static int kvm_vm_ioctl_set_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps)
+{
+	int r = 0, start = 0;
+	u32 prev_legacy, cur_legacy;
+	mutex_lock(&kvm->arch.vpit->pit_state.lock);
+	prev_legacy = kvm->arch.vpit->pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY;
+	cur_legacy = ps->flags & KVM_PIT_FLAGS_HPET_LEGACY;
+	if (!prev_legacy && cur_legacy)
+		start = 1;
+	memcpy(&kvm->arch.vpit->pit_state.channels, &ps->channels,
+	       sizeof(kvm->arch.vpit->pit_state.channels));
+	kvm->arch.vpit->pit_state.flags = ps->flags;
+	kvm_pit_load_count(kvm, 0, kvm->arch.vpit->pit_state.channels[0].count, start);
+	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
 	return r;
 }
 
@@ -1819,7 +2137,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 {
 	if (!kvm->arch.vpit)
 		return -ENXIO;
+	mutex_lock(&kvm->arch.vpit->pit_state.lock);
 	kvm->arch.vpit->pit_state.pit_timer.reinject = control->pit_reinject;
+	mutex_unlock(&kvm->arch.vpit->pit_state.lock);
 	return 0;
 }
 
@@ -1845,7 +2165,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		spin_lock(&kvm->mmu_lock);
 		kvm_mmu_slot_remove_write_access(kvm, log->slot);
 		spin_unlock(&kvm->mmu_lock);
-		kvm_flush_remote_tlbs(kvm);
 		memslot = &kvm->memslots[log->slot];
 		n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
 		memset(memslot->dirty_bitmap, 0, n);
@@ -1869,7 +2188,9 @@ long kvm_arch_vm_ioctl(struct file *filp,
 	 */
 	union {
 		struct kvm_pit_state ps;
+		struct kvm_pit_state2 ps2;
 		struct kvm_memory_alias alias;
+		struct kvm_pit_config pit_config;
 	} u;
 
 	switch (ioctl) {
@@ -1878,6 +2199,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		if (r < 0)
 			goto out;
 		break;
+	case KVM_SET_IDENTITY_MAP_ADDR: {
+		u64 ident_addr;
+
+		r = -EFAULT;
+		if (copy_from_user(&ident_addr, argp, sizeof ident_addr))
+			goto out;
+		r = kvm_vm_ioctl_set_identity_map_addr(kvm, ident_addr);
+		if (r < 0)
+			goto out;
+		break;
+	}
 	case KVM_SET_MEMORY_REGION: {
 		struct kvm_memory_region kvm_mem;
 		struct kvm_userspace_memory_region kvm_userspace_mem;
@@ -1930,16 +2262,24 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		}
 		break;
 	case KVM_CREATE_PIT:
-		mutex_lock(&kvm->lock);
+		u.pit_config.flags = KVM_PIT_SPEAKER_DUMMY;
+		goto create_pit;
+	case KVM_CREATE_PIT2:
+		r = -EFAULT;
+		if (copy_from_user(&u.pit_config, argp,
+				   sizeof(struct kvm_pit_config)))
+			goto out;
+	create_pit:
+		down_write(&kvm->slots_lock);
 		r = -EEXIST;
 		if (kvm->arch.vpit)
 			goto create_pit_unlock;
 		r = -ENOMEM;
-		kvm->arch.vpit = kvm_create_pit(kvm);
+		kvm->arch.vpit = kvm_create_pit(kvm, u.pit_config.flags);
 		if (kvm->arch.vpit)
 			r = 0;
 	create_pit_unlock:
-		mutex_unlock(&kvm->lock);
+		up_write(&kvm->slots_lock);
 		break;
 	case KVM_IRQ_LINE_STATUS:
 	case KVM_IRQ_LINE: {
@@ -1950,10 +2290,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
 			goto out;
 		if (irqchip_in_kernel(kvm)) {
 			__s32 status;
-			mutex_lock(&kvm->lock);
+			mutex_lock(&kvm->irq_lock);
 			status = kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID,
 					irq_event.irq, irq_event.level);
-			mutex_unlock(&kvm->lock);
+			mutex_unlock(&kvm->irq_lock);
 			if (ioctl == KVM_IRQ_LINE_STATUS) {
 				irq_event.status = status;
 				if (copy_to_user(argp, &irq_event,
@@ -2042,6 +2382,32 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		r = 0;
 		break;
 	}
+	case KVM_GET_PIT2: {
+		r = -ENXIO;
+		if (!kvm->arch.vpit)
+			goto out;
+		r = kvm_vm_ioctl_get_pit2(kvm, &u.ps2);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &u.ps2, sizeof(u.ps2)))
+			goto out;
+		r = 0;
+		break;
+	}
+	case KVM_SET_PIT2: {
+		r = -EFAULT;
+		if (copy_from_user(&u.ps2, argp, sizeof(u.ps2)))
+			goto out;
+		r = -ENXIO;
+		if (!kvm->arch.vpit)
+			goto out;
+		r = kvm_vm_ioctl_set_pit2(kvm, &u.ps2);
+		if (r)
+			goto out;
+		r = 0;
+		break;
+	}
 	case KVM_REINJECT_CONTROL: {
 		struct kvm_reinject_control control;
 		r =  -EFAULT;
@@ -2075,35 +2441,23 @@ static void kvm_init_msr_list(void)
 	num_msrs_to_save = j;
 }
 
-/*
- * Only apic need an MMIO device hook, so shortcut now..
- */
-static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu,
-						gpa_t addr, int len,
-						int is_write)
+static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
+			   const void *v)
 {
-	struct kvm_io_device *dev;
+	if (vcpu->arch.apic &&
+	    !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, len, v))
+		return 0;
 
-	if (vcpu->arch.apic) {
-		dev = &vcpu->arch.apic->dev;
-		if (dev->in_range(dev, addr, len, is_write))
-			return dev;
-	}
-	return NULL;
+	return kvm_io_bus_write(&vcpu->kvm->mmio_bus, addr, len, v);
 }
 
-
-static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
-						gpa_t addr, int len,
-						int is_write)
+static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
 {
-	struct kvm_io_device *dev;
+	if (vcpu->arch.apic &&
+	    !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, len, v))
+		return 0;
 
-	dev = vcpu_find_pervcpu_dev(vcpu, addr, len, is_write);
-	if (dev == NULL)
-		dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len,
-					  is_write);
-	return dev;
+	return kvm_io_bus_read(&vcpu->kvm->mmio_bus, addr, len, v);
 }
 
 static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
@@ -2172,11 +2526,12 @@ static int emulator_read_emulated(unsigned long addr,
 				  unsigned int bytes,
 				  struct kvm_vcpu *vcpu)
 {
-	struct kvm_io_device *mmio_dev;
 	gpa_t                 gpa;
 
 	if (vcpu->mmio_read_completed) {
 		memcpy(val, vcpu->mmio_data, bytes);
+		trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes,
+			       vcpu->mmio_phys_addr, *(u64 *)val);
 		vcpu->mmio_read_completed = 0;
 		return X86EMUL_CONTINUE;
 	}
@@ -2197,14 +2552,12 @@ mmio:
 	/*
 	 * Is this MMIO handled locally?
 	 */
-	mutex_lock(&vcpu->kvm->lock);
-	mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 0);
-	if (mmio_dev) {
-		kvm_iodevice_read(mmio_dev, gpa, bytes, val);
-		mutex_unlock(&vcpu->kvm->lock);
+	if (!vcpu_mmio_read(vcpu, gpa, bytes, val)) {
+		trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, gpa, *(u64 *)val);
 		return X86EMUL_CONTINUE;
 	}
-	mutex_unlock(&vcpu->kvm->lock);
+
+	trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0);
 
 	vcpu->mmio_needed = 1;
 	vcpu->mmio_phys_addr = gpa;
@@ -2231,7 +2584,6 @@ static int emulator_write_emulated_onepage(unsigned long addr,
 					   unsigned int bytes,
 					   struct kvm_vcpu *vcpu)
 {
-	struct kvm_io_device *mmio_dev;
 	gpa_t                 gpa;
 
 	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, addr);
@@ -2249,17 +2601,12 @@ static int emulator_write_emulated_onepage(unsigned long addr,
 		return X86EMUL_CONTINUE;
 
 mmio:
+	trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
 	/*
 	 * Is this MMIO handled locally?
 	 */
-	mutex_lock(&vcpu->kvm->lock);
-	mmio_dev = vcpu_find_mmio_dev(vcpu, gpa, bytes, 1);
-	if (mmio_dev) {
-		kvm_iodevice_write(mmio_dev, gpa, bytes, val);
-		mutex_unlock(&vcpu->kvm->lock);
+	if (!vcpu_mmio_write(vcpu, gpa, bytes, val))
 		return X86EMUL_CONTINUE;
-	}
-	mutex_unlock(&vcpu->kvm->lock);
 
 	vcpu->mmio_needed = 1;
 	vcpu->mmio_phys_addr = gpa;
@@ -2297,12 +2644,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
 				     unsigned int bytes,
 				     struct kvm_vcpu *vcpu)
 {
-	static int reported;
-
-	if (!reported) {
-		reported = 1;
-		printk(KERN_WARNING "kvm: emulating exchange as write\n");
-	}
+	printk_once(KERN_WARNING "kvm: emulating exchange as write\n");
 #ifndef CONFIG_X86_64
 	/* guests cmpxchg8b have to be emulated atomically */
 	if (bytes == 8) {
@@ -2348,7 +2690,6 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
 
 int emulate_clts(struct kvm_vcpu *vcpu)
 {
-	KVMTRACE_0D(CLTS, vcpu, handler);
 	kvm_x86_ops->set_cr0(vcpu, vcpu->arch.cr0 & ~X86_CR0_TS);
 	return X86EMUL_CONTINUE;
 }
@@ -2425,7 +2766,7 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 	kvm_clear_exception_queue(vcpu);
 	vcpu->arch.mmio_fault_cr2 = cr2;
 	/*
-	 * TODO: fix x86_emulate.c to use guest_read/write_register
+	 * TODO: fix emulate.c to use guest_read/write_register
 	 * instead of direct ->regs accesses, can save hundred cycles
 	 * on Intel for instructions that don't read/change RSP, for
 	 * for example.
@@ -2449,14 +2790,33 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
 
 		r = x86_decode_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
 
-		/* Reject the instructions other than VMCALL/VMMCALL when
-		 * try to emulate invalid opcode */
+		/* Only allow emulation of specific instructions on #UD
+		 * (namely VMMCALL, sysenter, sysexit, syscall)*/
 		c = &vcpu->arch.emulate_ctxt.decode;
-		if ((emulation_type & EMULTYPE_TRAP_UD) &&
-		    (!(c->twobyte && c->b == 0x01 &&
-		      (c->modrm_reg == 0 || c->modrm_reg == 3) &&
-		       c->modrm_mod == 3 && c->modrm_rm == 1)))
-			return EMULATE_FAIL;
+		if (emulation_type & EMULTYPE_TRAP_UD) {
+			if (!c->twobyte)
+				return EMULATE_FAIL;
+			switch (c->b) {
+			case 0x01: /* VMMCALL */
+				if (c->modrm_mod != 3 || c->modrm_rm != 1)
+					return EMULATE_FAIL;
+				break;
+			case 0x34: /* sysenter */
+			case 0x35: /* sysexit */
+				if (c->modrm_mod != 0 || c->modrm_rm != 0)
+					return EMULATE_FAIL;
+				break;
+			case 0x05: /* syscall */
+				if (c->modrm_mod != 0 || c->modrm_rm != 0)
+					return EMULATE_FAIL;
+				break;
+			default:
+				return EMULATE_FAIL;
+			}
+
+			if (!(c->modrm_reg == 0 || c->modrm_reg == 3))
+				return EMULATE_FAIL;
+		}
 
 		++vcpu->stat.insn_emulation;
 		if (r)  {
@@ -2576,52 +2936,40 @@ int complete_pio(struct kvm_vcpu *vcpu)
 	return 0;
 }
 
-static void kernel_pio(struct kvm_io_device *pio_dev,
-		       struct kvm_vcpu *vcpu,
-		       void *pd)
+static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
 {
 	/* TODO: String I/O for in kernel device */
+	int r;
 
-	mutex_lock(&vcpu->kvm->lock);
 	if (vcpu->arch.pio.in)
-		kvm_iodevice_read(pio_dev, vcpu->arch.pio.port,
-				  vcpu->arch.pio.size,
-				  pd);
+		r = kvm_io_bus_read(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
+				    vcpu->arch.pio.size, pd);
 	else
-		kvm_iodevice_write(pio_dev, vcpu->arch.pio.port,
-				   vcpu->arch.pio.size,
-				   pd);
-	mutex_unlock(&vcpu->kvm->lock);
+		r = kvm_io_bus_write(&vcpu->kvm->pio_bus, vcpu->arch.pio.port,
+				     vcpu->arch.pio.size, pd);
+	return r;
 }
 
-static void pio_string_write(struct kvm_io_device *pio_dev,
-			     struct kvm_vcpu *vcpu)
+static int pio_string_write(struct kvm_vcpu *vcpu)
 {
 	struct kvm_pio_request *io = &vcpu->arch.pio;
 	void *pd = vcpu->arch.pio_data;
-	int i;
+	int i, r = 0;
 
-	mutex_lock(&vcpu->kvm->lock);
 	for (i = 0; i < io->cur_count; i++) {
-		kvm_iodevice_write(pio_dev, io->port,
-				   io->size,
-				   pd);
+		if (kvm_io_bus_write(&vcpu->kvm->pio_bus,
+				     io->port, io->size, pd)) {
+			r = -EOPNOTSUPP;
+			break;
+		}
 		pd += io->size;
 	}
-	mutex_unlock(&vcpu->kvm->lock);
-}
-
-static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu,
-					       gpa_t addr, int len,
-					       int is_write)
-{
-	return kvm_io_bus_find_dev(&vcpu->kvm->pio_bus, addr, len, is_write);
+	return r;
 }
 
 int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
 		  int size, unsigned port)
 {
-	struct kvm_io_device *pio_dev;
 	unsigned long val;
 
 	vcpu->run->exit_reason = KVM_EXIT_IO;
@@ -2635,19 +2983,13 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
 	vcpu->arch.pio.down = 0;
 	vcpu->arch.pio.rep = 0;
 
-	if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
-		KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size,
-			    handler);
-	else
-		KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size,
-			    handler);
+	trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
+		      size, 1);
 
 	val = kvm_register_read(vcpu, VCPU_REGS_RAX);
 	memcpy(vcpu->arch.pio_data, &val, 4);
 
-	pio_dev = vcpu_find_pio_dev(vcpu, port, size, !in);
-	if (pio_dev) {
-		kernel_pio(pio_dev, vcpu, vcpu->arch.pio_data);
+	if (!kernel_pio(vcpu, vcpu->arch.pio_data)) {
 		complete_pio(vcpu);
 		return 1;
 	}
@@ -2661,7 +3003,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
 {
 	unsigned now, in_page;
 	int ret = 0;
-	struct kvm_io_device *pio_dev;
 
 	vcpu->run->exit_reason = KVM_EXIT_IO;
 	vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
@@ -2674,12 +3015,8 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
 	vcpu->arch.pio.down = down;
 	vcpu->arch.pio.rep = rep;
 
-	if (vcpu->run->io.direction == KVM_EXIT_IO_IN)
-		KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size,
-			    handler);
-	else
-		KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size,
-			    handler);
+	trace_kvm_pio(vcpu->run->io.direction == KVM_EXIT_IO_OUT, port,
+		      size, count);
 
 	if (!count) {
 		kvm_x86_ops->skip_emulated_instruction(vcpu);
@@ -2709,9 +3046,6 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
 
 	vcpu->arch.pio.guest_gva = address;
 
-	pio_dev = vcpu_find_pio_dev(vcpu, port,
-				    vcpu->arch.pio.cur_count,
-				    !vcpu->arch.pio.in);
 	if (!vcpu->arch.pio.in) {
 		/* string PIO write */
 		ret = pio_copy_data(vcpu);
@@ -2719,16 +3053,13 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
 			kvm_inject_gp(vcpu, 0);
 			return 1;
 		}
-		if (ret == 0 && pio_dev) {
-			pio_string_write(pio_dev, vcpu);
+		if (ret == 0 && !pio_string_write(vcpu)) {
 			complete_pio(vcpu);
 			if (vcpu->arch.pio.count == 0)
 				ret = 1;
 		}
-	} else if (pio_dev)
-		pr_unimpl(vcpu, "no string pio read support yet, "
-		       "port %x size %d count %ld\n",
-			port, size, count);
+	}
+	/* no string PIO read support yet */
 
 	return ret;
 }
@@ -2761,10 +3092,7 @@ static int kvmclock_cpufreq_notifier(struct notifier_block *nb, unsigned long va
 
 	spin_lock(&kvm_lock);
 	list_for_each_entry(kvm, &vm_list, vm_list) {
-		for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-			vcpu = kvm->vcpus[i];
-			if (!vcpu)
-				continue;
+		kvm_for_each_vcpu(i, vcpu, kvm) {
 			if (vcpu->cpu != freq->cpu)
 				continue;
 			if (!kvm_request_guest_time_update(vcpu))
@@ -2857,7 +3185,6 @@ void kvm_arch_exit(void)
 int kvm_emulate_halt(struct kvm_vcpu *vcpu)
 {
 	++vcpu->stat.halt_exits;
-	KVMTRACE_0D(HLT, vcpu, handler);
 	if (irqchip_in_kernel(vcpu->kvm)) {
 		vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
 		return 1;
@@ -2888,7 +3215,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 	a2 = kvm_register_read(vcpu, VCPU_REGS_RDX);
 	a3 = kvm_register_read(vcpu, VCPU_REGS_RSI);
 
-	KVMTRACE_1D(VMMCALL, vcpu, (u32)nr, handler);
+	trace_kvm_hypercall(nr, a0, a1, a2, a3);
 
 	if (!is_long_mode(vcpu)) {
 		nr &= 0xFFFFFFFF;
@@ -2898,6 +3225,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 		a3 &= 0xFFFFFFFF;
 	}
 
+	if (kvm_x86_ops->get_cpl(vcpu) != 0) {
+		ret = -KVM_EPERM;
+		goto out;
+	}
+
 	switch (nr) {
 	case KVM_HC_VAPIC_POLL_IRQ:
 		ret = 0;
@@ -2909,6 +3241,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
 		ret = -KVM_ENOSYS;
 		break;
 	}
+out:
 	kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
 	++vcpu->stat.hypercalls;
 	return r;
@@ -2988,8 +3321,6 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
 		vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr);
 		return 0;
 	}
-	KVMTRACE_3D(CR_READ, vcpu, (u32)cr, (u32)value,
-		    (u32)((u64)value >> 32), handler);
 
 	return value;
 }
@@ -2997,9 +3328,6 @@ unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
 void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
 		     unsigned long *rflags)
 {
-	KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, (u32)val,
-		    (u32)((u64)val >> 32), handler);
-
 	switch (cr) {
 	case 0:
 		kvm_set_cr0(vcpu, mk_cr_64(vcpu->arch.cr0, val));
@@ -3109,11 +3437,11 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
 		kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx);
 	}
 	kvm_x86_ops->skip_emulated_instruction(vcpu);
-	KVMTRACE_5D(CPUID, vcpu, function,
-		    (u32)kvm_register_read(vcpu, VCPU_REGS_RAX),
-		    (u32)kvm_register_read(vcpu, VCPU_REGS_RBX),
-		    (u32)kvm_register_read(vcpu, VCPU_REGS_RCX),
-		    (u32)kvm_register_read(vcpu, VCPU_REGS_RDX), handler);
+	trace_kvm_cpuid(function,
+			kvm_register_read(vcpu, VCPU_REGS_RAX),
+			kvm_register_read(vcpu, VCPU_REGS_RBX),
+			kvm_register_read(vcpu, VCPU_REGS_RCX),
+			kvm_register_read(vcpu, VCPU_REGS_RDX));
 }
 EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
 
@@ -3179,6 +3507,9 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
 	if (!kvm_x86_ops->update_cr8_intercept)
 		return;
 
+	if (!vcpu->arch.apic)
+		return;
+
 	if (!vcpu->arch.apic->vapic_addr)
 		max_irr = kvm_lapic_find_highest_irr(vcpu);
 	else
@@ -3192,12 +3523,16 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu)
 	kvm_x86_ops->update_cr8_intercept(vcpu, tpr, max_irr);
 }
 
-static void inject_pending_irq(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static void inject_pending_event(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-		kvm_x86_ops->set_interrupt_shadow(vcpu, 0);
-
 	/* try to reinject previous events if any */
+	if (vcpu->arch.exception.pending) {
+		kvm_x86_ops->queue_exception(vcpu, vcpu->arch.exception.nr,
+					  vcpu->arch.exception.has_error_code,
+					  vcpu->arch.exception.error_code);
+		return;
+	}
+
 	if (vcpu->arch.nmi_injected) {
 		kvm_x86_ops->set_nmi(vcpu);
 		return;
@@ -3271,16 +3606,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 	smp_mb__after_clear_bit();
 
 	if (vcpu->requests || need_resched() || signal_pending(current)) {
+		set_bit(KVM_REQ_KICK, &vcpu->requests);
 		local_irq_enable();
 		preempt_enable();
 		r = 1;
 		goto out;
 	}
 
-	if (vcpu->arch.exception.pending)
-		__queue_exception(vcpu);
-	else
-		inject_pending_irq(vcpu, kvm_run);
+	inject_pending_event(vcpu, kvm_run);
 
 	/* enable NMI/IRQ window open exits if needed */
 	if (vcpu->arch.nmi_pending)
@@ -3297,14 +3630,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 
 	kvm_guest_enter();
 
-	get_debugreg(vcpu->arch.host_dr6, 6);
-	get_debugreg(vcpu->arch.host_dr7, 7);
 	if (unlikely(vcpu->arch.switch_db_regs)) {
-		get_debugreg(vcpu->arch.host_db[0], 0);
-		get_debugreg(vcpu->arch.host_db[1], 1);
-		get_debugreg(vcpu->arch.host_db[2], 2);
-		get_debugreg(vcpu->arch.host_db[3], 3);
-
 		set_debugreg(0, 7);
 		set_debugreg(vcpu->arch.eff_db[0], 0);
 		set_debugreg(vcpu->arch.eff_db[1], 1);
@@ -3312,18 +3638,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 		set_debugreg(vcpu->arch.eff_db[3], 3);
 	}
 
-	KVMTRACE_0D(VMENTRY, vcpu, entryexit);
+	trace_kvm_entry(vcpu->vcpu_id);
 	kvm_x86_ops->run(vcpu, kvm_run);
 
-	if (unlikely(vcpu->arch.switch_db_regs)) {
-		set_debugreg(0, 7);
-		set_debugreg(vcpu->arch.host_db[0], 0);
-		set_debugreg(vcpu->arch.host_db[1], 1);
-		set_debugreg(vcpu->arch.host_db[2], 2);
-		set_debugreg(vcpu->arch.host_db[3], 3);
+	if (unlikely(vcpu->arch.switch_db_regs || test_thread_flag(TIF_DEBUG))) {
+		set_debugreg(current->thread.debugreg0, 0);
+		set_debugreg(current->thread.debugreg1, 1);
+		set_debugreg(current->thread.debugreg2, 2);
+		set_debugreg(current->thread.debugreg3, 3);
+		set_debugreg(current->thread.debugreg6, 6);
+		set_debugreg(current->thread.debugreg7, 7);
 	}
-	set_debugreg(vcpu->arch.host_dr6, 6);
-	set_debugreg(vcpu->arch.host_dr7, 7);
 
 	set_bit(KVM_REQ_KICK, &vcpu->requests);
 	local_irq_enable();
@@ -3653,11 +3978,8 @@ static void kvm_set_segment(struct kvm_vcpu *vcpu,
 static void seg_desct_to_kvm_desct(struct desc_struct *seg_desc, u16 selector,
 				   struct kvm_segment *kvm_desct)
 {
-	kvm_desct->base = seg_desc->base0;
-	kvm_desct->base |= seg_desc->base1 << 16;
-	kvm_desct->base |= seg_desc->base2 << 24;
-	kvm_desct->limit = seg_desc->limit0;
-	kvm_desct->limit |= seg_desc->limit << 16;
+	kvm_desct->base = get_desc_base(seg_desc);
+	kvm_desct->limit = get_desc_limit(seg_desc);
 	if (seg_desc->g) {
 		kvm_desct->limit <<= 12;
 		kvm_desct->limit |= 0xfff;
@@ -3701,7 +4023,6 @@ static void get_segment_descriptor_dtable(struct kvm_vcpu *vcpu,
 static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 					 struct desc_struct *seg_desc)
 {
-	gpa_t gpa;
 	struct descriptor_table dtable;
 	u16 index = selector >> 3;
 
@@ -3711,16 +4032,13 @@ static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 		kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
 		return 1;
 	}
-	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
-	gpa += index * 8;
-	return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8);
+	return kvm_read_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
 }
 
 /* allowed just for 8 bytes segments */
 static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 					 struct desc_struct *seg_desc)
 {
-	gpa_t gpa;
 	struct descriptor_table dtable;
 	u16 index = selector >> 3;
 
@@ -3728,19 +4046,13 @@ static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 
 	if (dtable.limit < index * 8 + 7)
 		return 1;
-	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
-	gpa += index * 8;
-	return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8);
+	return kvm_write_guest_virt(dtable.base + index*8, seg_desc, sizeof(*seg_desc), vcpu);
 }
 
 static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
 			     struct desc_struct *seg_desc)
 {
-	u32 base_addr;
-
-	base_addr = seg_desc->base0;
-	base_addr |= (seg_desc->base1 << 16);
-	base_addr |= (seg_desc->base2 << 24);
+	u32 base_addr = get_desc_base(seg_desc);
 
 	return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
 }
@@ -3785,12 +4097,19 @@ static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int se
 	return 0;
 }
 
+static int is_vm86_segment(struct kvm_vcpu *vcpu, int seg)
+{
+	return (seg != VCPU_SREG_LDTR) &&
+		(seg != VCPU_SREG_TR) &&
+		(kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_VM);
+}
+
 int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 				int type_bits, int seg)
 {
 	struct kvm_segment kvm_seg;
 
-	if (!(vcpu->arch.cr0 & X86_CR0_PE))
+	if (is_vm86_segment(vcpu, seg) || !(vcpu->arch.cr0 & X86_CR0_PE))
 		return kvm_load_realmode_segment(vcpu, selector, seg);
 	if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
 		return 1;
@@ -4029,7 +4348,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
 		}
 	}
 
-	if (!nseg_desc.p || (nseg_desc.limit0 | nseg_desc.limit << 16) < 0x67) {
+	if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) {
 		kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc);
 		return 1;
 	}
@@ -4099,13 +4418,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 
 	vcpu->arch.cr2 = sregs->cr2;
 	mmu_reset_needed |= vcpu->arch.cr3 != sregs->cr3;
-
-	down_read(&vcpu->kvm->slots_lock);
-	if (gfn_to_memslot(vcpu->kvm, sregs->cr3 >> PAGE_SHIFT))
-		vcpu->arch.cr3 = sregs->cr3;
-	else
-		set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
-	up_read(&vcpu->kvm->slots_lock);
+	vcpu->arch.cr3 = sregs->cr3;
 
 	kvm_set_cr8(vcpu, sregs->cr8);
 
@@ -4147,8 +4460,10 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
 	kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
 	kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
 
+	update_cr8_intercept(vcpu);
+
 	/* Older userspace won't unhalt the vcpu on reset. */
-	if (vcpu->vcpu_id == 0 && kvm_rip_read(vcpu) == 0xfff0 &&
+	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
 	    sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
 	    !(vcpu->arch.cr0 & X86_CR0_PE))
 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
@@ -4419,7 +4734,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 	kvm = vcpu->kvm;
 
 	vcpu->arch.mmu.root_hpa = INVALID_PAGE;
-	if (!irqchip_in_kernel(kvm) || vcpu->vcpu_id == 0)
+	if (!irqchip_in_kernel(kvm) || kvm_vcpu_is_bsp(vcpu))
 		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 	else
 		vcpu->arch.mp_state = KVM_MP_STATE_UNINITIALIZED;
@@ -4441,6 +4756,14 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
 			goto fail_mmu_destroy;
 	}
 
+	vcpu->arch.mce_banks = kzalloc(KVM_MAX_MCE_BANKS * sizeof(u64) * 4,
+				       GFP_KERNEL);
+	if (!vcpu->arch.mce_banks) {
+		r = -ENOMEM;
+		goto fail_mmu_destroy;
+	}
+	vcpu->arch.mcg_cap = KVM_MAX_MCE_BANKS;
+
 	return 0;
 
 fail_mmu_destroy:
@@ -4488,20 +4811,22 @@ static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
 static void kvm_free_vcpus(struct kvm *kvm)
 {
 	unsigned int i;
+	struct kvm_vcpu *vcpu;
 
 	/*
 	 * Unpin any mmu pages first.
 	 */
-	for (i = 0; i < KVM_MAX_VCPUS; ++i)
-		if (kvm->vcpus[i])
-			kvm_unload_vcpu_mmu(kvm->vcpus[i]);
-	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		if (kvm->vcpus[i]) {
-			kvm_arch_vcpu_free(kvm->vcpus[i]);
-			kvm->vcpus[i] = NULL;
-		}
-	}
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		kvm_unload_vcpu_mmu(vcpu);
+	kvm_for_each_vcpu(i, vcpu, kvm)
+		kvm_arch_vcpu_free(vcpu);
+
+	mutex_lock(&kvm->lock);
+	for (i = 0; i < atomic_read(&kvm->online_vcpus); i++)
+		kvm->vcpus[i] = NULL;
 
+	atomic_set(&kvm->online_vcpus, 0);
+	mutex_unlock(&kvm->lock);
 }
 
 void kvm_arch_sync_events(struct kvm *kvm)
@@ -4578,7 +4903,6 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
 
 	kvm_mmu_slot_remove_write_access(kvm, mem->slot);
 	spin_unlock(&kvm->mmu_lock);
-	kvm_flush_remote_tlbs(kvm);
 
 	return 0;
 }
@@ -4592,8 +4916,10 @@ void kvm_arch_flush_shadow(struct kvm *kvm)
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
 {
 	return vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE
-	       || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED
-	       || vcpu->arch.nmi_pending;
+		|| vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED
+		|| vcpu->arch.nmi_pending ||
+		(kvm_arch_interrupt_allowed(vcpu) &&
+		 kvm_cpu_has_interrupt(vcpu));
 }
 
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
@@ -4617,3 +4943,9 @@ int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
 {
 	return kvm_x86_ops->interrupt_allowed(vcpu);
 }
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_msr);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_cr);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 4c8e10a..5eadea5 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -31,4 +31,8 @@ static inline bool kvm_exception_is_soft(unsigned int nr)
 {
 	return (nr == BP_VECTOR) || (nr == OF_VECTOR);
 }
+
+struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
+                                             u32 function, u32 index);
+
 #endif
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
deleted file mode 100644
index 616de46..0000000
--- a/arch/x86/kvm/x86_emulate.c
+++ /dev/null
@@ -1,2141 +0,0 @@
-/******************************************************************************
- * x86_emulate.c
- *
- * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
- *
- * Copyright (c) 2005 Keir Fraser
- *
- * Linux coding style, mod r/m decoder, segment base fixes, real-mode
- * privileged instructions:
- *
- * Copyright (C) 2006 Qumranet
- *
- *   Avi Kivity <avi@qumranet.com>
- *   Yaniv Kamay <yaniv@qumranet.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
- */
-
-#ifndef __KERNEL__
-#include <stdio.h>
-#include <stdint.h>
-#include <public/xen.h>
-#define DPRINTF(_f, _a ...) printf(_f , ## _a)
-#else
-#include <linux/kvm_host.h>
-#include "kvm_cache_regs.h"
-#define DPRINTF(x...) do {} while (0)
-#endif
-#include <linux/module.h>
-#include <asm/kvm_x86_emulate.h>
-
-/*
- * Opcode effective-address decode tables.
- * Note that we only emulate instructions that have at least one memory
- * operand (excluding implicit stack references). We assume that stack
- * references and instruction fetches will never occur in special memory
- * areas that require emulation. So, for example, 'mov <imm>,<reg>' need
- * not be handled.
- */
-
-/* Operand sizes: 8-bit operands or specified/overridden size. */
-#define ByteOp      (1<<0)	/* 8-bit operands. */
-/* Destination operand type. */
-#define ImplicitOps (1<<1)	/* Implicit in opcode. No generic decode. */
-#define DstReg      (2<<1)	/* Register operand. */
-#define DstMem      (3<<1)	/* Memory operand. */
-#define DstAcc      (4<<1)      /* Destination Accumulator */
-#define DstMask     (7<<1)
-/* Source operand type. */
-#define SrcNone     (0<<4)	/* No source operand. */
-#define SrcImplicit (0<<4)	/* Source operand is implicit in the opcode. */
-#define SrcReg      (1<<4)	/* Register operand. */
-#define SrcMem      (2<<4)	/* Memory operand. */
-#define SrcMem16    (3<<4)	/* Memory operand (16-bit). */
-#define SrcMem32    (4<<4)	/* Memory operand (32-bit). */
-#define SrcImm      (5<<4)	/* Immediate operand. */
-#define SrcImmByte  (6<<4)	/* 8-bit sign-extended immediate operand. */
-#define SrcOne      (7<<4)	/* Implied '1' */
-#define SrcImmUByte (8<<4)      /* 8-bit unsigned immediate operand. */
-#define SrcMask     (0xf<<4)
-/* Generic ModRM decode. */
-#define ModRM       (1<<8)
-/* Destination is only written; never read. */
-#define Mov         (1<<9)
-#define BitOp       (1<<10)
-#define MemAbs      (1<<11)      /* Memory operand is absolute displacement */
-#define String      (1<<12)     /* String instruction (rep capable) */
-#define Stack       (1<<13)     /* Stack instruction (push/pop) */
-#define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
-#define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
-#define GroupMask   0xff        /* Group number stored in bits 0:7 */
-/* Source 2 operand type */
-#define Src2None    (0<<29)
-#define Src2CL      (1<<29)
-#define Src2ImmByte (2<<29)
-#define Src2One     (3<<29)
-#define Src2Imm16   (4<<29)
-#define Src2Mask    (7<<29)
-
-enum {
-	Group1_80, Group1_81, Group1_82, Group1_83,
-	Group1A, Group3_Byte, Group3, Group4, Group5, Group7,
-};
-
-static u32 opcode_table[256] = {
-	/* 0x00 - 0x07 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm, 0, 0,
-	/* 0x08 - 0x0F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	0, 0, 0, 0,
-	/* 0x10 - 0x17 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	0, 0, 0, 0,
-	/* 0x18 - 0x1F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	0, 0, 0, 0,
-	/* 0x20 - 0x27 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
-	/* 0x28 - 0x2F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	0, 0, 0, 0,
-	/* 0x30 - 0x37 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	0, 0, 0, 0,
-	/* 0x38 - 0x3F */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
-	ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
-	0, 0,
-	/* 0x40 - 0x47 */
-	DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
-	/* 0x48 - 0x4F */
-	DstReg, DstReg, DstReg, DstReg,	DstReg, DstReg, DstReg, DstReg,
-	/* 0x50 - 0x57 */
-	SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
-	SrcReg | Stack, SrcReg | Stack, SrcReg | Stack, SrcReg | Stack,
-	/* 0x58 - 0x5F */
-	DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
-	DstReg | Stack, DstReg | Stack, DstReg | Stack, DstReg | Stack,
-	/* 0x60 - 0x67 */
-	0, 0, 0, DstReg | SrcMem32 | ModRM | Mov /* movsxd (x86/64) */ ,
-	0, 0, 0, 0,
-	/* 0x68 - 0x6F */
-	SrcImm | Mov | Stack, 0, SrcImmByte | Mov | Stack, 0,
-	SrcNone  | ByteOp  | ImplicitOps, SrcNone  | ImplicitOps, /* insb, insw/insd */
-	SrcNone  | ByteOp  | ImplicitOps, SrcNone  | ImplicitOps, /* outsb, outsw/outsd */
-	/* 0x70 - 0x77 */
-	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
-	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
-	/* 0x78 - 0x7F */
-	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
-	SrcImmByte, SrcImmByte, SrcImmByte, SrcImmByte,
-	/* 0x80 - 0x87 */
-	Group | Group1_80, Group | Group1_81,
-	Group | Group1_82, Group | Group1_83,
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
-	/* 0x88 - 0x8F */
-	ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov,
-	ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstMem | SrcReg | ModRM | Mov, ModRM | DstReg,
-	DstReg | SrcMem | ModRM | Mov, Group | Group1A,
-	/* 0x90 - 0x97 */
-	DstReg, DstReg, DstReg, DstReg,	DstReg, DstReg, DstReg, DstReg,
-	/* 0x98 - 0x9F */
-	0, 0, SrcImm | Src2Imm16, 0,
-	ImplicitOps | Stack, ImplicitOps | Stack, 0, 0,
-	/* 0xA0 - 0xA7 */
-	ByteOp | DstReg | SrcMem | Mov | MemAbs, DstReg | SrcMem | Mov | MemAbs,
-	ByteOp | DstMem | SrcReg | Mov | MemAbs, DstMem | SrcReg | Mov | MemAbs,
-	ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
-	ByteOp | ImplicitOps | String, ImplicitOps | String,
-	/* 0xA8 - 0xAF */
-	0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
-	ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
-	ByteOp | ImplicitOps | String, ImplicitOps | String,
-	/* 0xB0 - 0xB7 */
-	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
-	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
-	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
-	ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
-	/* 0xB8 - 0xBF */
-	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
-	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
-	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
-	DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
-	/* 0xC0 - 0xC7 */
-	ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
-	0, ImplicitOps | Stack, 0, 0,
-	ByteOp | DstMem | SrcImm | ModRM | Mov, DstMem | SrcImm | ModRM | Mov,
-	/* 0xC8 - 0xCF */
-	0, 0, 0, ImplicitOps | Stack,
-	ImplicitOps, SrcImmByte, ImplicitOps, ImplicitOps,
-	/* 0xD0 - 0xD7 */
-	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
-	ByteOp | DstMem | SrcImplicit | ModRM, DstMem | SrcImplicit | ModRM,
-	0, 0, 0, 0,
-	/* 0xD8 - 0xDF */
-	0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0xE0 - 0xE7 */
-	0, 0, 0, 0,
-	ByteOp | SrcImmUByte, SrcImmUByte,
-	ByteOp | SrcImmUByte, SrcImmUByte,
-	/* 0xE8 - 0xEF */
-	SrcImm | Stack, SrcImm | ImplicitOps,
-	SrcImm | Src2Imm16, SrcImmByte | ImplicitOps,
-	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
-	SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
-	/* 0xF0 - 0xF7 */
-	0, 0, 0, 0,
-	ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3,
-	/* 0xF8 - 0xFF */
-	ImplicitOps, 0, ImplicitOps, ImplicitOps,
-	ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
-};
-
-static u32 twobyte_table[256] = {
-	/* 0x00 - 0x0F */
-	0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0,
-	ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0,
-	/* 0x10 - 0x1F */
-	0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0,
-	/* 0x20 - 0x2F */
-	ModRM | ImplicitOps, ModRM, ModRM | ImplicitOps, ModRM, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0x30 - 0x3F */
-	ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0x40 - 0x47 */
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	/* 0x48 - 0x4F */
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov,
-	/* 0x50 - 0x5F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0x60 - 0x6F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0x70 - 0x7F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0x80 - 0x8F */
-	SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
-	SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm, SrcImm,
-	/* 0x90 - 0x9F */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0xA0 - 0xA7 */
-	0, 0, 0, DstMem | SrcReg | ModRM | BitOp,
-	DstMem | SrcReg | Src2ImmByte | ModRM,
-	DstMem | SrcReg | Src2CL | ModRM, 0, 0,
-	/* 0xA8 - 0xAF */
-	0, 0, 0, DstMem | SrcReg | ModRM | BitOp,
-	DstMem | SrcReg | Src2ImmByte | ModRM,
-	DstMem | SrcReg | Src2CL | ModRM,
-	ModRM, 0,
-	/* 0xB0 - 0xB7 */
-	ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0,
-	    DstMem | SrcReg | ModRM | BitOp,
-	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
-	    DstReg | SrcMem16 | ModRM | Mov,
-	/* 0xB8 - 0xBF */
-	0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp,
-	0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
-	    DstReg | SrcMem16 | ModRM | Mov,
-	/* 0xC0 - 0xCF */
-	0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0xD0 - 0xDF */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0xE0 - 0xEF */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	/* 0xF0 - 0xFF */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static u32 group_table[] = {
-	[Group1_80*8] =
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	[Group1_81*8] =
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	DstMem | SrcImm | ModRM, DstMem | SrcImm | ModRM,
-	[Group1_82*8] =
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	ByteOp | DstMem | SrcImm | ModRM, ByteOp | DstMem | SrcImm | ModRM,
-	[Group1_83*8] =
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
-	DstMem | SrcImmByte | ModRM, DstMem | SrcImmByte | ModRM,
-	[Group1A*8] =
-	DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0,
-	[Group3_Byte*8] =
-	ByteOp | SrcImm | DstMem | ModRM, 0,
-	ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
-	0, 0, 0, 0,
-	[Group3*8] =
-	DstMem | SrcImm | ModRM, 0,
-	DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
-	0, 0, 0, 0,
-	[Group4*8] =
-	ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
-	0, 0, 0, 0, 0, 0,
-	[Group5*8] =
-	DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
-	SrcMem | ModRM | Stack, 0,
-	SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0,
-	[Group7*8] =
-	0, 0, ModRM | SrcMem, ModRM | SrcMem,
-	SrcNone | ModRM | DstMem | Mov, 0,
-	SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp,
-};
-
-static u32 group2_table[] = {
-	[Group7*8] =
-	SrcNone | ModRM, 0, 0, SrcNone | ModRM,
-	SrcNone | ModRM | DstMem | Mov, 0,
-	SrcMem16 | ModRM | Mov, 0,
-};
-
-/* EFLAGS bit definitions. */
-#define EFLG_OF (1<<11)
-#define EFLG_DF (1<<10)
-#define EFLG_SF (1<<7)
-#define EFLG_ZF (1<<6)
-#define EFLG_AF (1<<4)
-#define EFLG_PF (1<<2)
-#define EFLG_CF (1<<0)
-
-/*
- * Instruction emulation:
- * Most instructions are emulated directly via a fragment of inline assembly
- * code. This allows us to save/restore EFLAGS and thus very easily pick up
- * any modified flags.
- */
-
-#if defined(CONFIG_X86_64)
-#define _LO32 "k"		/* force 32-bit operand */
-#define _STK  "%%rsp"		/* stack pointer */
-#elif defined(__i386__)
-#define _LO32 ""		/* force 32-bit operand */
-#define _STK  "%%esp"		/* stack pointer */
-#endif
-
-/*
- * These EFLAGS bits are restored from saved value during emulation, and
- * any changes are written back to the saved value after emulation.
- */
-#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
-
-/* Before executing instruction: restore necessary bits in EFLAGS. */
-#define _PRE_EFLAGS(_sav, _msk, _tmp)					\
-	/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
-	"movl %"_sav",%"_LO32 _tmp"; "                                  \
-	"push %"_tmp"; "                                                \
-	"push %"_tmp"; "                                                \
-	"movl %"_msk",%"_LO32 _tmp"; "                                  \
-	"andl %"_LO32 _tmp",("_STK"); "                                 \
-	"pushf; "                                                       \
-	"notl %"_LO32 _tmp"; "                                          \
-	"andl %"_LO32 _tmp",("_STK"); "                                 \
-	"andl %"_LO32 _tmp","__stringify(BITS_PER_LONG/4)"("_STK"); "	\
-	"pop  %"_tmp"; "                                                \
-	"orl  %"_LO32 _tmp",("_STK"); "                                 \
-	"popf; "                                                        \
-	"pop  %"_sav"; "
-
-/* After executing instruction: write-back necessary bits in EFLAGS. */
-#define _POST_EFLAGS(_sav, _msk, _tmp) \
-	/* _sav |= EFLAGS & _msk; */		\
-	"pushf; "				\
-	"pop  %"_tmp"; "			\
-	"andl %"_msk",%"_LO32 _tmp"; "		\
-	"orl  %"_LO32 _tmp",%"_sav"; "
-
-#ifdef CONFIG_X86_64
-#define ON64(x) x
-#else
-#define ON64(x)
-#endif
-
-#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix)	\
-	do {								\
-		__asm__ __volatile__ (					\
-			_PRE_EFLAGS("0", "4", "2")			\
-			_op _suffix " %"_x"3,%1; "			\
-			_POST_EFLAGS("0", "4", "2")			\
-			: "=m" (_eflags), "=m" ((_dst).val),		\
-			  "=&r" (_tmp)					\
-			: _y ((_src).val), "i" (EFLAGS_MASK));		\
-	} while (0)
-
-
-/* Raw emulation: instruction has two explicit operands. */
-#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
-	do {								\
-		unsigned long _tmp;					\
-									\
-		switch ((_dst).bytes) {					\
-		case 2:							\
-			____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
-			break;						\
-		case 4:							\
-			____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \
-			break;						\
-		case 8:							\
-			ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \
-			break;						\
-		}							\
-	} while (0)
-
-#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
-	do {								     \
-		unsigned long _tmp;					     \
-		switch ((_dst).bytes) {				             \
-		case 1:							     \
-			____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b");  \
-			break;						     \
-		default:						     \
-			__emulate_2op_nobyte(_op, _src, _dst, _eflags,	     \
-					     _wx, _wy, _lx, _ly, _qx, _qy);  \
-			break;						     \
-		}							     \
-	} while (0)
-
-/* Source operand is byte-sized and may be restricted to just %cl. */
-#define emulate_2op_SrcB(_op, _src, _dst, _eflags)                      \
-	__emulate_2op(_op, _src, _dst, _eflags,				\
-		      "b", "c", "b", "c", "b", "c", "b", "c")
-
-/* Source operand is byte, word, long or quad sized. */
-#define emulate_2op_SrcV(_op, _src, _dst, _eflags)                      \
-	__emulate_2op(_op, _src, _dst, _eflags,				\
-		      "b", "q", "w", "r", _LO32, "r", "", "r")
-
-/* Source operand is word, long or quad sized. */
-#define emulate_2op_SrcV_nobyte(_op, _src, _dst, _eflags)               \
-	__emulate_2op_nobyte(_op, _src, _dst, _eflags,			\
-			     "w", "r", _LO32, "r", "", "r")
-
-/* Instruction has three operands and one operand is stored in ECX register */
-#define __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, _suffix, _type) 	\
-	do {									\
-		unsigned long _tmp;						\
-		_type _clv  = (_cl).val;  					\
-		_type _srcv = (_src).val;    					\
-		_type _dstv = (_dst).val;					\
-										\
-		__asm__ __volatile__ (						\
-			_PRE_EFLAGS("0", "5", "2")				\
-			_op _suffix " %4,%1 \n"					\
-			_POST_EFLAGS("0", "5", "2")				\
-			: "=m" (_eflags), "+r" (_dstv), "=&r" (_tmp)		\
-			: "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK)		\
-			); 							\
-										\
-		(_cl).val  = (unsigned long) _clv;				\
-		(_src).val = (unsigned long) _srcv;				\
-		(_dst).val = (unsigned long) _dstv;				\
-	} while (0)
-
-#define emulate_2op_cl(_op, _cl, _src, _dst, _eflags)				\
-	do {									\
-		switch ((_dst).bytes) {						\
-		case 2:								\
-			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,  	\
-						"w", unsigned short);         	\
-			break;							\
-		case 4: 							\
-			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,  	\
-						"l", unsigned int);           	\
-			break;							\
-		case 8:								\
-			ON64(__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,	\
-						"q", unsigned long));  		\
-			break;							\
-		}								\
-	} while (0)
-
-#define __emulate_1op(_op, _dst, _eflags, _suffix)			\
-	do {								\
-		unsigned long _tmp;					\
-									\
-		__asm__ __volatile__ (					\
-			_PRE_EFLAGS("0", "3", "2")			\
-			_op _suffix " %1; "				\
-			_POST_EFLAGS("0", "3", "2")			\
-			: "=m" (_eflags), "+m" ((_dst).val),		\
-			  "=&r" (_tmp)					\
-			: "i" (EFLAGS_MASK));				\
-	} while (0)
-
-/* Instruction has only one explicit operand (no source operand). */
-#define emulate_1op(_op, _dst, _eflags)                                    \
-	do {								\
-		switch ((_dst).bytes) {				        \
-		case 1:	__emulate_1op(_op, _dst, _eflags, "b"); break;	\
-		case 2:	__emulate_1op(_op, _dst, _eflags, "w"); break;	\
-		case 4:	__emulate_1op(_op, _dst, _eflags, "l"); break;	\
-		case 8:	ON64(__emulate_1op(_op, _dst, _eflags, "q")); break; \
-		}							\
-	} while (0)
-
-/* Fetch next part of the instruction being emulated. */
-#define insn_fetch(_type, _size, _eip)                                  \
-({	unsigned long _x;						\
-	rc = do_insn_fetch(ctxt, ops, (_eip), &_x, (_size));		\
-	if (rc != 0)							\
-		goto done;						\
-	(_eip) += (_size);						\
-	(_type)_x;							\
-})
-
-static inline unsigned long ad_mask(struct decode_cache *c)
-{
-	return (1UL << (c->ad_bytes << 3)) - 1;
-}
-
-/* Access/update address held in a register, based on addressing mode. */
-static inline unsigned long
-address_mask(struct decode_cache *c, unsigned long reg)
-{
-	if (c->ad_bytes == sizeof(unsigned long))
-		return reg;
-	else
-		return reg & ad_mask(c);
-}
-
-static inline unsigned long
-register_address(struct decode_cache *c, unsigned long base, unsigned long reg)
-{
-	return base + address_mask(c, reg);
-}
-
-static inline void
-register_address_increment(struct decode_cache *c, unsigned long *reg, int inc)
-{
-	if (c->ad_bytes == sizeof(unsigned long))
-		*reg += inc;
-	else
-		*reg = (*reg & ~ad_mask(c)) | ((*reg + inc) & ad_mask(c));
-}
-
-static inline void jmp_rel(struct decode_cache *c, int rel)
-{
-	register_address_increment(c, &c->eip, rel);
-}
-
-static void set_seg_override(struct decode_cache *c, int seg)
-{
-	c->has_seg_override = true;
-	c->seg_override = seg;
-}
-
-static unsigned long seg_base(struct x86_emulate_ctxt *ctxt, int seg)
-{
-	if (ctxt->mode == X86EMUL_MODE_PROT64 && seg < VCPU_SREG_FS)
-		return 0;
-
-	return kvm_x86_ops->get_segment_base(ctxt->vcpu, seg);
-}
-
-static unsigned long seg_override_base(struct x86_emulate_ctxt *ctxt,
-				       struct decode_cache *c)
-{
-	if (!c->has_seg_override)
-		return 0;
-
-	return seg_base(ctxt, c->seg_override);
-}
-
-static unsigned long es_base(struct x86_emulate_ctxt *ctxt)
-{
-	return seg_base(ctxt, VCPU_SREG_ES);
-}
-
-static unsigned long ss_base(struct x86_emulate_ctxt *ctxt)
-{
-	return seg_base(ctxt, VCPU_SREG_SS);
-}
-
-static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
-			      struct x86_emulate_ops *ops,
-			      unsigned long linear, u8 *dest)
-{
-	struct fetch_cache *fc = &ctxt->decode.fetch;
-	int rc;
-	int size;
-
-	if (linear < fc->start || linear >= fc->end) {
-		size = min(15UL, PAGE_SIZE - offset_in_page(linear));
-		rc = ops->read_std(linear, fc->data, size, ctxt->vcpu);
-		if (rc)
-			return rc;
-		fc->start = linear;
-		fc->end = linear + size;
-	}
-	*dest = fc->data[linear - fc->start];
-	return 0;
-}
-
-static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
-			 struct x86_emulate_ops *ops,
-			 unsigned long eip, void *dest, unsigned size)
-{
-	int rc = 0;
-
-	eip += ctxt->cs_base;
-	while (size--) {
-		rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
-		if (rc)
-			return rc;
-	}
-	return 0;
-}
-
-/*
- * Given the 'reg' portion of a ModRM byte, and a register block, return a
- * pointer into the block that addresses the relevant register.
- * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
- */
-static void *decode_register(u8 modrm_reg, unsigned long *regs,
-			     int highbyte_regs)
-{
-	void *p;
-
-	p = &regs[modrm_reg];
-	if (highbyte_regs && modrm_reg >= 4 && modrm_reg < 8)
-		p = (unsigned char *)&regs[modrm_reg & 3] + 1;
-	return p;
-}
-
-static int read_descriptor(struct x86_emulate_ctxt *ctxt,
-			   struct x86_emulate_ops *ops,
-			   void *ptr,
-			   u16 *size, unsigned long *address, int op_bytes)
-{
-	int rc;
-
-	if (op_bytes == 2)
-		op_bytes = 3;
-	*address = 0;
-	rc = ops->read_std((unsigned long)ptr, (unsigned long *)size, 2,
-			   ctxt->vcpu);
-	if (rc)
-		return rc;
-	rc = ops->read_std((unsigned long)ptr + 2, address, op_bytes,
-			   ctxt->vcpu);
-	return rc;
-}
-
-static int test_cc(unsigned int condition, unsigned int flags)
-{
-	int rc = 0;
-
-	switch ((condition & 15) >> 1) {
-	case 0: /* o */
-		rc |= (flags & EFLG_OF);
-		break;
-	case 1: /* b/c/nae */
-		rc |= (flags & EFLG_CF);
-		break;
-	case 2: /* z/e */
-		rc |= (flags & EFLG_ZF);
-		break;
-	case 3: /* be/na */
-		rc |= (flags & (EFLG_CF|EFLG_ZF));
-		break;
-	case 4: /* s */
-		rc |= (flags & EFLG_SF);
-		break;
-	case 5: /* p/pe */
-		rc |= (flags & EFLG_PF);
-		break;
-	case 7: /* le/ng */
-		rc |= (flags & EFLG_ZF);
-		/* fall through */
-	case 6: /* l/nge */
-		rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF));
-		break;
-	}
-
-	/* Odd condition identifiers (lsb == 1) have inverted sense. */
-	return (!!rc ^ (condition & 1));
-}
-
-static void decode_register_operand(struct operand *op,
-				    struct decode_cache *c,
-				    int inhibit_bytereg)
-{
-	unsigned reg = c->modrm_reg;
-	int highbyte_regs = c->rex_prefix == 0;
-
-	if (!(c->d & ModRM))
-		reg = (c->b & 7) | ((c->rex_prefix & 1) << 3);
-	op->type = OP_REG;
-	if ((c->d & ByteOp) && !inhibit_bytereg) {
-		op->ptr = decode_register(reg, c->regs, highbyte_regs);
-		op->val = *(u8 *)op->ptr;
-		op->bytes = 1;
-	} else {
-		op->ptr = decode_register(reg, c->regs, 0);
-		op->bytes = c->op_bytes;
-		switch (op->bytes) {
-		case 2:
-			op->val = *(u16 *)op->ptr;
-			break;
-		case 4:
-			op->val = *(u32 *)op->ptr;
-			break;
-		case 8:
-			op->val = *(u64 *) op->ptr;
-			break;
-		}
-	}
-	op->orig_val = op->val;
-}
-
-static int decode_modrm(struct x86_emulate_ctxt *ctxt,
-			struct x86_emulate_ops *ops)
-{
-	struct decode_cache *c = &ctxt->decode;
-	u8 sib;
-	int index_reg = 0, base_reg = 0, scale;
-	int rc = 0;
-
-	if (c->rex_prefix) {
-		c->modrm_reg = (c->rex_prefix & 4) << 1;	/* REX.R */
-		index_reg = (c->rex_prefix & 2) << 2; /* REX.X */
-		c->modrm_rm = base_reg = (c->rex_prefix & 1) << 3; /* REG.B */
-	}
-
-	c->modrm = insn_fetch(u8, 1, c->eip);
-	c->modrm_mod |= (c->modrm & 0xc0) >> 6;
-	c->modrm_reg |= (c->modrm & 0x38) >> 3;
-	c->modrm_rm |= (c->modrm & 0x07);
-	c->modrm_ea = 0;
-	c->use_modrm_ea = 1;
-
-	if (c->modrm_mod == 3) {
-		c->modrm_ptr = decode_register(c->modrm_rm,
-					       c->regs, c->d & ByteOp);
-		c->modrm_val = *(unsigned long *)c->modrm_ptr;
-		return rc;
-	}
-
-	if (c->ad_bytes == 2) {
-		unsigned bx = c->regs[VCPU_REGS_RBX];
-		unsigned bp = c->regs[VCPU_REGS_RBP];
-		unsigned si = c->regs[VCPU_REGS_RSI];
-		unsigned di = c->regs[VCPU_REGS_RDI];
-
-		/* 16-bit ModR/M decode. */
-		switch (c->modrm_mod) {
-		case 0:
-			if (c->modrm_rm == 6)
-				c->modrm_ea += insn_fetch(u16, 2, c->eip);
-			break;
-		case 1:
-			c->modrm_ea += insn_fetch(s8, 1, c->eip);
-			break;
-		case 2:
-			c->modrm_ea += insn_fetch(u16, 2, c->eip);
-			break;
-		}
-		switch (c->modrm_rm) {
-		case 0:
-			c->modrm_ea += bx + si;
-			break;
-		case 1:
-			c->modrm_ea += bx + di;
-			break;
-		case 2:
-			c->modrm_ea += bp + si;
-			break;
-		case 3:
-			c->modrm_ea += bp + di;
-			break;
-		case 4:
-			c->modrm_ea += si;
-			break;
-		case 5:
-			c->modrm_ea += di;
-			break;
-		case 6:
-			if (c->modrm_mod != 0)
-				c->modrm_ea += bp;
-			break;
-		case 7:
-			c->modrm_ea += bx;
-			break;
-		}
-		if (c->modrm_rm == 2 || c->modrm_rm == 3 ||
-		    (c->modrm_rm == 6 && c->modrm_mod != 0))
-			if (!c->has_seg_override)
-				set_seg_override(c, VCPU_SREG_SS);
-		c->modrm_ea = (u16)c->modrm_ea;
-	} else {
-		/* 32/64-bit ModR/M decode. */
-		if ((c->modrm_rm & 7) == 4) {
-			sib = insn_fetch(u8, 1, c->eip);
-			index_reg |= (sib >> 3) & 7;
-			base_reg |= sib & 7;
-			scale = sib >> 6;
-
-			if ((base_reg & 7) == 5 && c->modrm_mod == 0)
-				c->modrm_ea += insn_fetch(s32, 4, c->eip);
-			else
-				c->modrm_ea += c->regs[base_reg];
-			if (index_reg != 4)
-				c->modrm_ea += c->regs[index_reg] << scale;
-		} else if ((c->modrm_rm & 7) == 5 && c->modrm_mod == 0) {
-			if (ctxt->mode == X86EMUL_MODE_PROT64)
-				c->rip_relative = 1;
-		} else
-			c->modrm_ea += c->regs[c->modrm_rm];
-		switch (c->modrm_mod) {
-		case 0:
-			if (c->modrm_rm == 5)
-				c->modrm_ea += insn_fetch(s32, 4, c->eip);
-			break;
-		case 1:
-			c->modrm_ea += insn_fetch(s8, 1, c->eip);
-			break;
-		case 2:
-			c->modrm_ea += insn_fetch(s32, 4, c->eip);
-			break;
-		}
-	}
-done:
-	return rc;
-}
-
-static int decode_abs(struct x86_emulate_ctxt *ctxt,
-		      struct x86_emulate_ops *ops)
-{
-	struct decode_cache *c = &ctxt->decode;
-	int rc = 0;
-
-	switch (c->ad_bytes) {
-	case 2:
-		c->modrm_ea = insn_fetch(u16, 2, c->eip);
-		break;
-	case 4:
-		c->modrm_ea = insn_fetch(u32, 4, c->eip);
-		break;
-	case 8:
-		c->modrm_ea = insn_fetch(u64, 8, c->eip);
-		break;
-	}
-done:
-	return rc;
-}
-
-int
-x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
-{
-	struct decode_cache *c = &ctxt->decode;
-	int rc = 0;
-	int mode = ctxt->mode;
-	int def_op_bytes, def_ad_bytes, group;
-
-	/* Shadow copy of register state. Committed on successful emulation. */
-
-	memset(c, 0, sizeof(struct decode_cache));
-	c->eip = kvm_rip_read(ctxt->vcpu);
-	ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
-	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
-
-	switch (mode) {
-	case X86EMUL_MODE_REAL:
-	case X86EMUL_MODE_PROT16:
-		def_op_bytes = def_ad_bytes = 2;
-		break;
-	case X86EMUL_MODE_PROT32:
-		def_op_bytes = def_ad_bytes = 4;
-		break;
-#ifdef CONFIG_X86_64
-	case X86EMUL_MODE_PROT64:
-		def_op_bytes = 4;
-		def_ad_bytes = 8;
-		break;
-#endif
-	default:
-		return -1;
-	}
-
-	c->op_bytes = def_op_bytes;
-	c->ad_bytes = def_ad_bytes;
-
-	/* Legacy prefixes. */
-	for (;;) {
-		switch (c->b = insn_fetch(u8, 1, c->eip)) {
-		case 0x66:	/* operand-size override */
-			/* switch between 2/4 bytes */
-			c->op_bytes = def_op_bytes ^ 6;
-			break;
-		case 0x67:	/* address-size override */
-			if (mode == X86EMUL_MODE_PROT64)
-				/* switch between 4/8 bytes */
-				c->ad_bytes = def_ad_bytes ^ 12;
-			else
-				/* switch between 2/4 bytes */
-				c->ad_bytes = def_ad_bytes ^ 6;
-			break;
-		case 0x26:	/* ES override */
-		case 0x2e:	/* CS override */
-		case 0x36:	/* SS override */
-		case 0x3e:	/* DS override */
-			set_seg_override(c, (c->b >> 3) & 3);
-			break;
-		case 0x64:	/* FS override */
-		case 0x65:	/* GS override */
-			set_seg_override(c, c->b & 7);
-			break;
-		case 0x40 ... 0x4f: /* REX */
-			if (mode != X86EMUL_MODE_PROT64)
-				goto done_prefixes;
-			c->rex_prefix = c->b;
-			continue;
-		case 0xf0:	/* LOCK */
-			c->lock_prefix = 1;
-			break;
-		case 0xf2:	/* REPNE/REPNZ */
-			c->rep_prefix = REPNE_PREFIX;
-			break;
-		case 0xf3:	/* REP/REPE/REPZ */
-			c->rep_prefix = REPE_PREFIX;
-			break;
-		default:
-			goto done_prefixes;
-		}
-
-		/* Any legacy prefix after a REX prefix nullifies its effect. */
-
-		c->rex_prefix = 0;
-	}
-
-done_prefixes:
-
-	/* REX prefix. */
-	if (c->rex_prefix)
-		if (c->rex_prefix & 8)
-			c->op_bytes = 8;	/* REX.W */
-
-	/* Opcode byte(s). */
-	c->d = opcode_table[c->b];
-	if (c->d == 0) {
-		/* Two-byte opcode? */
-		if (c->b == 0x0f) {
-			c->twobyte = 1;
-			c->b = insn_fetch(u8, 1, c->eip);
-			c->d = twobyte_table[c->b];
-		}
-	}
-
-	if (c->d & Group) {
-		group = c->d & GroupMask;
-		c->modrm = insn_fetch(u8, 1, c->eip);
-		--c->eip;
-
-		group = (group << 3) + ((c->modrm >> 3) & 7);
-		if ((c->d & GroupDual) && (c->modrm >> 6) == 3)
-			c->d = group2_table[group];
-		else
-			c->d = group_table[group];
-	}
-
-	/* Unrecognised? */
-	if (c->d == 0) {
-		DPRINTF("Cannot emulate %02x\n", c->b);
-		return -1;
-	}
-
-	if (mode == X86EMUL_MODE_PROT64 && (c->d & Stack))
-		c->op_bytes = 8;
-
-	/* ModRM and SIB bytes. */
-	if (c->d & ModRM)
-		rc = decode_modrm(ctxt, ops);
-	else if (c->d & MemAbs)
-		rc = decode_abs(ctxt, ops);
-	if (rc)
-		goto done;
-
-	if (!c->has_seg_override)
-		set_seg_override(c, VCPU_SREG_DS);
-
-	if (!(!c->twobyte && c->b == 0x8d))
-		c->modrm_ea += seg_override_base(ctxt, c);
-
-	if (c->ad_bytes != 8)
-		c->modrm_ea = (u32)c->modrm_ea;
-	/*
-	 * Decode and fetch the source operand: register, memory
-	 * or immediate.
-	 */
-	switch (c->d & SrcMask) {
-	case SrcNone:
-		break;
-	case SrcReg:
-		decode_register_operand(&c->src, c, 0);
-		break;
-	case SrcMem16:
-		c->src.bytes = 2;
-		goto srcmem_common;
-	case SrcMem32:
-		c->src.bytes = 4;
-		goto srcmem_common;
-	case SrcMem:
-		c->src.bytes = (c->d & ByteOp) ? 1 :
-							   c->op_bytes;
-		/* Don't fetch the address for invlpg: it could be unmapped. */
-		if (c->twobyte && c->b == 0x01 && c->modrm_reg == 7)
-			break;
-	srcmem_common:
-		/*
-		 * For instructions with a ModR/M byte, switch to register
-		 * access if Mod = 3.
-		 */
-		if ((c->d & ModRM) && c->modrm_mod == 3) {
-			c->src.type = OP_REG;
-			c->src.val = c->modrm_val;
-			c->src.ptr = c->modrm_ptr;
-			break;
-		}
-		c->src.type = OP_MEM;
-		break;
-	case SrcImm:
-		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
-		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		if (c->src.bytes == 8)
-			c->src.bytes = 4;
-		/* NB. Immediates are sign-extended as necessary. */
-		switch (c->src.bytes) {
-		case 1:
-			c->src.val = insn_fetch(s8, 1, c->eip);
-			break;
-		case 2:
-			c->src.val = insn_fetch(s16, 2, c->eip);
-			break;
-		case 4:
-			c->src.val = insn_fetch(s32, 4, c->eip);
-			break;
-		}
-		break;
-	case SrcImmByte:
-	case SrcImmUByte:
-		c->src.type = OP_IMM;
-		c->src.ptr = (unsigned long *)c->eip;
-		c->src.bytes = 1;
-		if ((c->d & SrcMask) == SrcImmByte)
-			c->src.val = insn_fetch(s8, 1, c->eip);
-		else
-			c->src.val = insn_fetch(u8, 1, c->eip);
-		break;
-	case SrcOne:
-		c->src.bytes = 1;
-		c->src.val = 1;
-		break;
-	}
-
-	/*
-	 * Decode and fetch the second source operand: register, memory
-	 * or immediate.
-	 */
-	switch (c->d & Src2Mask) {
-	case Src2None:
-		break;
-	case Src2CL:
-		c->src2.bytes = 1;
-		c->src2.val = c->regs[VCPU_REGS_RCX] & 0x8;
-		break;
-	case Src2ImmByte:
-		c->src2.type = OP_IMM;
-		c->src2.ptr = (unsigned long *)c->eip;
-		c->src2.bytes = 1;
-		c->src2.val = insn_fetch(u8, 1, c->eip);
-		break;
-	case Src2Imm16:
-		c->src2.type = OP_IMM;
-		c->src2.ptr = (unsigned long *)c->eip;
-		c->src2.bytes = 2;
-		c->src2.val = insn_fetch(u16, 2, c->eip);
-		break;
-	case Src2One:
-		c->src2.bytes = 1;
-		c->src2.val = 1;
-		break;
-	}
-
-	/* Decode and fetch the destination operand: register or memory. */
-	switch (c->d & DstMask) {
-	case ImplicitOps:
-		/* Special instructions do their own operand decoding. */
-		return 0;
-	case DstReg:
-		decode_register_operand(&c->dst, c,
-			 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
-		break;
-	case DstMem:
-		if ((c->d & ModRM) && c->modrm_mod == 3) {
-			c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-			c->dst.type = OP_REG;
-			c->dst.val = c->dst.orig_val = c->modrm_val;
-			c->dst.ptr = c->modrm_ptr;
-			break;
-		}
-		c->dst.type = OP_MEM;
-		break;
-	case DstAcc:
-		c->dst.type = OP_REG;
-		c->dst.bytes = c->op_bytes;
-		c->dst.ptr = &c->regs[VCPU_REGS_RAX];
-		switch (c->op_bytes) {
-			case 1:
-				c->dst.val = *(u8 *)c->dst.ptr;
-				break;
-			case 2:
-				c->dst.val = *(u16 *)c->dst.ptr;
-				break;
-			case 4:
-				c->dst.val = *(u32 *)c->dst.ptr;
-				break;
-		}
-		c->dst.orig_val = c->dst.val;
-		break;
-	}
-
-	if (c->rip_relative)
-		c->modrm_ea += c->eip;
-
-done:
-	return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
-}
-
-static inline void emulate_push(struct x86_emulate_ctxt *ctxt)
-{
-	struct decode_cache *c = &ctxt->decode;
-
-	c->dst.type  = OP_MEM;
-	c->dst.bytes = c->op_bytes;
-	c->dst.val = c->src.val;
-	register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes);
-	c->dst.ptr = (void *) register_address(c, ss_base(ctxt),
-					       c->regs[VCPU_REGS_RSP]);
-}
-
-static int emulate_pop(struct x86_emulate_ctxt *ctxt,
-		       struct x86_emulate_ops *ops,
-		       void *dest, int len)
-{
-	struct decode_cache *c = &ctxt->decode;
-	int rc;
-
-	rc = ops->read_emulated(register_address(c, ss_base(ctxt),
-						 c->regs[VCPU_REGS_RSP]),
-				dest, len, ctxt->vcpu);
-	if (rc != 0)
-		return rc;
-
-	register_address_increment(c, &c->regs[VCPU_REGS_RSP], len);
-	return rc;
-}
-
-static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
-				struct x86_emulate_ops *ops)
-{
-	struct decode_cache *c = &ctxt->decode;
-	int rc;
-
-	rc = emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes);
-	if (rc != 0)
-		return rc;
-	return 0;
-}
-
-static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt)
-{
-	struct decode_cache *c = &ctxt->decode;
-	switch (c->modrm_reg) {
-	case 0:	/* rol */
-		emulate_2op_SrcB("rol", c->src, c->dst, ctxt->eflags);
-		break;
-	case 1:	/* ror */
-		emulate_2op_SrcB("ror", c->src, c->dst, ctxt->eflags);
-		break;
-	case 2:	/* rcl */
-		emulate_2op_SrcB("rcl", c->src, c->dst, ctxt->eflags);
-		break;
-	case 3:	/* rcr */
-		emulate_2op_SrcB("rcr", c->src, c->dst, ctxt->eflags);
-		break;
-	case 4:	/* sal/shl */
-	case 6:	/* sal/shl */
-		emulate_2op_SrcB("sal", c->src, c->dst, ctxt->eflags);
-		break;
-	case 5:	/* shr */
-		emulate_2op_SrcB("shr", c->src, c->dst, ctxt->eflags);
-		break;
-	case 7:	/* sar */
-		emulate_2op_SrcB("sar", c->src, c->dst, ctxt->eflags);
-		break;
-	}
-}
-
-static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops)
-{
-	struct decode_cache *c = &ctxt->decode;
-	int rc = 0;
-
-	switch (c->modrm_reg) {
-	case 0 ... 1:	/* test */
-		emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
-		break;
-	case 2:	/* not */
-		c->dst.val = ~c->dst.val;
-		break;
-	case 3:	/* neg */
-		emulate_1op("neg", c->dst, ctxt->eflags);
-		break;
-	default:
-		DPRINTF("Cannot emulate %02x\n", c->b);
-		rc = X86EMUL_UNHANDLEABLE;
-		break;
-	}
-	return rc;
-}
-
-static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops)
-{
-	struct decode_cache *c = &ctxt->decode;
-
-	switch (c->modrm_reg) {
-	case 0:	/* inc */
-		emulate_1op("inc", c->dst, ctxt->eflags);
-		break;
-	case 1:	/* dec */
-		emulate_1op("dec", c->dst, ctxt->eflags);
-		break;
-	case 2: /* call near abs */ {
-		long int old_eip;
-		old_eip = c->eip;
-		c->eip = c->src.val;
-		c->src.val = old_eip;
-		emulate_push(ctxt);
-		break;
-	}
-	case 4: /* jmp abs */
-		c->eip = c->src.val;
-		break;
-	case 6:	/* push */
-		emulate_push(ctxt);
-		break;
-	}
-	return 0;
-}
-
-static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops,
-			       unsigned long memop)
-{
-	struct decode_cache *c = &ctxt->decode;
-	u64 old, new;
-	int rc;
-
-	rc = ops->read_emulated(memop, &old, 8, ctxt->vcpu);
-	if (rc != 0)
-		return rc;
-
-	if (((u32) (old >> 0) != (u32) c->regs[VCPU_REGS_RAX]) ||
-	    ((u32) (old >> 32) != (u32) c->regs[VCPU_REGS_RDX])) {
-
-		c->regs[VCPU_REGS_RAX] = (u32) (old >> 0);
-		c->regs[VCPU_REGS_RDX] = (u32) (old >> 32);
-		ctxt->eflags &= ~EFLG_ZF;
-
-	} else {
-		new = ((u64)c->regs[VCPU_REGS_RCX] << 32) |
-		       (u32) c->regs[VCPU_REGS_RBX];
-
-		rc = ops->cmpxchg_emulated(memop, &old, &new, 8, ctxt->vcpu);
-		if (rc != 0)
-			return rc;
-		ctxt->eflags |= EFLG_ZF;
-	}
-	return 0;
-}
-
-static int emulate_ret_far(struct x86_emulate_ctxt *ctxt,
-			   struct x86_emulate_ops *ops)
-{
-	struct decode_cache *c = &ctxt->decode;
-	int rc;
-	unsigned long cs;
-
-	rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes);
-	if (rc)
-		return rc;
-	if (c->op_bytes == 4)
-		c->eip = (u32)c->eip;
-	rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
-	if (rc)
-		return rc;
-	rc = kvm_load_segment_descriptor(ctxt->vcpu, (u16)cs, 1, VCPU_SREG_CS);
-	return rc;
-}
-
-static inline int writeback(struct x86_emulate_ctxt *ctxt,
-			    struct x86_emulate_ops *ops)
-{
-	int rc;
-	struct decode_cache *c = &ctxt->decode;
-
-	switch (c->dst.type) {
-	case OP_REG:
-		/* The 4-byte case *is* correct:
-		 * in 64-bit mode we zero-extend.
-		 */
-		switch (c->dst.bytes) {
-		case 1:
-			*(u8 *)c->dst.ptr = (u8)c->dst.val;
-			break;
-		case 2:
-			*(u16 *)c->dst.ptr = (u16)c->dst.val;
-			break;
-		case 4:
-			*c->dst.ptr = (u32)c->dst.val;
-			break;	/* 64b: zero-ext */
-		case 8:
-			*c->dst.ptr = c->dst.val;
-			break;
-		}
-		break;
-	case OP_MEM:
-		if (c->lock_prefix)
-			rc = ops->cmpxchg_emulated(
-					(unsigned long)c->dst.ptr,
-					&c->dst.orig_val,
-					&c->dst.val,
-					c->dst.bytes,
-					ctxt->vcpu);
-		else
-			rc = ops->write_emulated(
-					(unsigned long)c->dst.ptr,
-					&c->dst.val,
-					c->dst.bytes,
-					ctxt->vcpu);
-		if (rc != 0)
-			return rc;
-		break;
-	case OP_NONE:
-		/* no writeback */
-		break;
-	default:
-		break;
-	}
-	return 0;
-}
-
-static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask)
-{
-	u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask);
-	/*
-	 * an sti; sti; sequence only disable interrupts for the first
-	 * instruction. So, if the last instruction, be it emulated or
-	 * not, left the system with the INT_STI flag enabled, it
-	 * means that the last instruction is an sti. We should not
-	 * leave the flag on in this case. The same goes for mov ss
-	 */
-	if (!(int_shadow & mask))
-		ctxt->interruptibility = mask;
-}
-
-int
-x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
-{
-	unsigned long memop = 0;
-	u64 msr_data;
-	unsigned long saved_eip = 0;
-	struct decode_cache *c = &ctxt->decode;
-	unsigned int port;
-	int io_dir_in;
-	int rc = 0;
-
-	ctxt->interruptibility = 0;
-
-	/* Shadow copy of register state. Committed on successful emulation.
-	 * NOTE: we can copy them from vcpu as x86_decode_insn() doesn't
-	 * modify them.
-	 */
-
-	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
-	saved_eip = c->eip;
-
-	if (((c->d & ModRM) && (c->modrm_mod != 3)) || (c->d & MemAbs))
-		memop = c->modrm_ea;
-
-	if (c->rep_prefix && (c->d & String)) {
-		/* All REP prefixes have the same first termination condition */
-		if (c->regs[VCPU_REGS_RCX] == 0) {
-			kvm_rip_write(ctxt->vcpu, c->eip);
-			goto done;
-		}
-		/* The second termination condition only applies for REPE
-		 * and REPNE. Test if the repeat string operation prefix is
-		 * REPE/REPZ or REPNE/REPNZ and if it's the case it tests the
-		 * corresponding termination condition according to:
-		 * 	- if REPE/REPZ and ZF = 0 then done
-		 * 	- if REPNE/REPNZ and ZF = 1 then done
-		 */
-		if ((c->b == 0xa6) || (c->b == 0xa7) ||
-				(c->b == 0xae) || (c->b == 0xaf)) {
-			if ((c->rep_prefix == REPE_PREFIX) &&
-				((ctxt->eflags & EFLG_ZF) == 0)) {
-					kvm_rip_write(ctxt->vcpu, c->eip);
-					goto done;
-			}
-			if ((c->rep_prefix == REPNE_PREFIX) &&
-				((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) {
-				kvm_rip_write(ctxt->vcpu, c->eip);
-				goto done;
-			}
-		}
-		c->regs[VCPU_REGS_RCX]--;
-		c->eip = kvm_rip_read(ctxt->vcpu);
-	}
-
-	if (c->src.type == OP_MEM) {
-		c->src.ptr = (unsigned long *)memop;
-		c->src.val = 0;
-		rc = ops->read_emulated((unsigned long)c->src.ptr,
-					&c->src.val,
-					c->src.bytes,
-					ctxt->vcpu);
-		if (rc != 0)
-			goto done;
-		c->src.orig_val = c->src.val;
-	}
-
-	if ((c->d & DstMask) == ImplicitOps)
-		goto special_insn;
-
-
-	if (c->dst.type == OP_MEM) {
-		c->dst.ptr = (unsigned long *)memop;
-		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.val = 0;
-		if (c->d & BitOp) {
-			unsigned long mask = ~(c->dst.bytes * 8 - 1);
-
-			c->dst.ptr = (void *)c->dst.ptr +
-						   (c->src.val & mask) / 8;
-		}
-		if (!(c->d & Mov) &&
-				   /* optimisation - avoid slow emulated read */
-		    ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
-					   &c->dst.val,
-					  c->dst.bytes, ctxt->vcpu)) != 0))
-			goto done;
-	}
-	c->dst.orig_val = c->dst.val;
-
-special_insn:
-
-	if (c->twobyte)
-		goto twobyte_insn;
-
-	switch (c->b) {
-	case 0x00 ... 0x05:
-	      add:		/* add */
-		emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x08 ... 0x0d:
-	      or:		/* or */
-		emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x10 ... 0x15:
-	      adc:		/* adc */
-		emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x18 ... 0x1d:
-	      sbb:		/* sbb */
-		emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x20 ... 0x25:
-	      and:		/* and */
-		emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x28 ... 0x2d:
-	      sub:		/* sub */
-		emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x30 ... 0x35:
-	      xor:		/* xor */
-		emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x38 ... 0x3d:
-	      cmp:		/* cmp */
-		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x40 ... 0x47: /* inc r16/r32 */
-		emulate_1op("inc", c->dst, ctxt->eflags);
-		break;
-	case 0x48 ... 0x4f: /* dec r16/r32 */
-		emulate_1op("dec", c->dst, ctxt->eflags);
-		break;
-	case 0x50 ... 0x57:  /* push reg */
-		emulate_push(ctxt);
-		break;
-	case 0x58 ... 0x5f: /* pop reg */
-	pop_instruction:
-		rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
-		if (rc != 0)
-			goto done;
-		break;
-	case 0x63:		/* movsxd */
-		if (ctxt->mode != X86EMUL_MODE_PROT64)
-			goto cannot_emulate;
-		c->dst.val = (s32) c->src.val;
-		break;
-	case 0x68: /* push imm */
-	case 0x6a: /* push imm8 */
-		emulate_push(ctxt);
-		break;
-	case 0x6c:		/* insb */
-	case 0x6d:		/* insw/insd */
-		 if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
-				1,
-				(c->d & ByteOp) ? 1 : c->op_bytes,
-				c->rep_prefix ?
-				address_mask(c, c->regs[VCPU_REGS_RCX]) : 1,
-				(ctxt->eflags & EFLG_DF),
-				register_address(c, es_base(ctxt),
-						 c->regs[VCPU_REGS_RDI]),
-				c->rep_prefix,
-				c->regs[VCPU_REGS_RDX]) == 0) {
-			c->eip = saved_eip;
-			return -1;
-		}
-		return 0;
-	case 0x6e:		/* outsb */
-	case 0x6f:		/* outsw/outsd */
-		if (kvm_emulate_pio_string(ctxt->vcpu, NULL,
-				0,
-				(c->d & ByteOp) ? 1 : c->op_bytes,
-				c->rep_prefix ?
-				address_mask(c, c->regs[VCPU_REGS_RCX]) : 1,
-				(ctxt->eflags & EFLG_DF),
-					 register_address(c,
-					  seg_override_base(ctxt, c),
-						 c->regs[VCPU_REGS_RSI]),
-				c->rep_prefix,
-				c->regs[VCPU_REGS_RDX]) == 0) {
-			c->eip = saved_eip;
-			return -1;
-		}
-		return 0;
-	case 0x70 ... 0x7f: /* jcc (short) */
-		if (test_cc(c->b, ctxt->eflags))
-			jmp_rel(c, c->src.val);
-		break;
-	case 0x80 ... 0x83:	/* Grp1 */
-		switch (c->modrm_reg) {
-		case 0:
-			goto add;
-		case 1:
-			goto or;
-		case 2:
-			goto adc;
-		case 3:
-			goto sbb;
-		case 4:
-			goto and;
-		case 5:
-			goto sub;
-		case 6:
-			goto xor;
-		case 7:
-			goto cmp;
-		}
-		break;
-	case 0x84 ... 0x85:
-		emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x86 ... 0x87:	/* xchg */
-	xchg:
-		/* Write back the register source. */
-		switch (c->dst.bytes) {
-		case 1:
-			*(u8 *) c->src.ptr = (u8) c->dst.val;
-			break;
-		case 2:
-			*(u16 *) c->src.ptr = (u16) c->dst.val;
-			break;
-		case 4:
-			*c->src.ptr = (u32) c->dst.val;
-			break;	/* 64b reg: zero-extend */
-		case 8:
-			*c->src.ptr = c->dst.val;
-			break;
-		}
-		/*
-		 * Write back the memory destination with implicit LOCK
-		 * prefix.
-		 */
-		c->dst.val = c->src.val;
-		c->lock_prefix = 1;
-		break;
-	case 0x88 ... 0x8b:	/* mov */
-		goto mov;
-	case 0x8c: { /* mov r/m, sreg */
-		struct kvm_segment segreg;
-
-		if (c->modrm_reg <= 5)
-			kvm_get_segment(ctxt->vcpu, &segreg, c->modrm_reg);
-		else {
-			printk(KERN_INFO "0x8c: Invalid segreg in modrm byte 0x%02x\n",
-			       c->modrm);
-			goto cannot_emulate;
-		}
-		c->dst.val = segreg.selector;
-		break;
-	}
-	case 0x8d: /* lea r16/r32, m */
-		c->dst.val = c->modrm_ea;
-		break;
-	case 0x8e: { /* mov seg, r/m16 */
-		uint16_t sel;
-		int type_bits;
-		int err;
-
-		sel = c->src.val;
-		if (c->modrm_reg == VCPU_SREG_SS)
-			toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
-
-		if (c->modrm_reg <= 5) {
-			type_bits = (c->modrm_reg == 1) ? 9 : 1;
-			err = kvm_load_segment_descriptor(ctxt->vcpu, sel,
-							  type_bits, c->modrm_reg);
-		} else {
-			printk(KERN_INFO "Invalid segreg in modrm byte 0x%02x\n",
-					c->modrm);
-			goto cannot_emulate;
-		}
-
-		if (err < 0)
-			goto cannot_emulate;
-
-		c->dst.type = OP_NONE;  /* Disable writeback. */
-		break;
-	}
-	case 0x8f:		/* pop (sole member of Grp1a) */
-		rc = emulate_grp1a(ctxt, ops);
-		if (rc != 0)
-			goto done;
-		break;
-	case 0x90: /* nop / xchg r8,rax */
-		if (!(c->rex_prefix & 1)) { /* nop */
-			c->dst.type = OP_NONE;
-			break;
-		}
-	case 0x91 ... 0x97: /* xchg reg,rax */
-		c->src.type = c->dst.type = OP_REG;
-		c->src.bytes = c->dst.bytes = c->op_bytes;
-		c->src.ptr = (unsigned long *) &c->regs[VCPU_REGS_RAX];
-		c->src.val = *(c->src.ptr);
-		goto xchg;
-	case 0x9c: /* pushf */
-		c->src.val =  (unsigned long) ctxt->eflags;
-		emulate_push(ctxt);
-		break;
-	case 0x9d: /* popf */
-		c->dst.type = OP_REG;
-		c->dst.ptr = (unsigned long *) &ctxt->eflags;
-		c->dst.bytes = c->op_bytes;
-		goto pop_instruction;
-	case 0xa0 ... 0xa1:	/* mov */
-		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
-		c->dst.val = c->src.val;
-		break;
-	case 0xa2 ... 0xa3:	/* mov */
-		c->dst.val = (unsigned long)c->regs[VCPU_REGS_RAX];
-		break;
-	case 0xa4 ... 0xa5:	/* movs */
-		c->dst.type = OP_MEM;
-		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = (unsigned long *)register_address(c,
-						   es_base(ctxt),
-						   c->regs[VCPU_REGS_RDI]);
-		if ((rc = ops->read_emulated(register_address(c,
-					   seg_override_base(ctxt, c),
-					c->regs[VCPU_REGS_RSI]),
-					&c->dst.val,
-					c->dst.bytes, ctxt->vcpu)) != 0)
-			goto done;
-		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
-				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
-							   : c->dst.bytes);
-		register_address_increment(c, &c->regs[VCPU_REGS_RDI],
-				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
-							   : c->dst.bytes);
-		break;
-	case 0xa6 ... 0xa7:	/* cmps */
-		c->src.type = OP_NONE; /* Disable writeback. */
-		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->src.ptr = (unsigned long *)register_address(c,
-				       seg_override_base(ctxt, c),
-						   c->regs[VCPU_REGS_RSI]);
-		if ((rc = ops->read_emulated((unsigned long)c->src.ptr,
-						&c->src.val,
-						c->src.bytes,
-						ctxt->vcpu)) != 0)
-			goto done;
-
-		c->dst.type = OP_NONE; /* Disable writeback. */
-		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = (unsigned long *)register_address(c,
-						   es_base(ctxt),
-						   c->regs[VCPU_REGS_RDI]);
-		if ((rc = ops->read_emulated((unsigned long)c->dst.ptr,
-						&c->dst.val,
-						c->dst.bytes,
-						ctxt->vcpu)) != 0)
-			goto done;
-
-		DPRINTF("cmps: mem1=0x%p mem2=0x%p\n", c->src.ptr, c->dst.ptr);
-
-		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
-
-		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
-				       (ctxt->eflags & EFLG_DF) ? -c->src.bytes
-								  : c->src.bytes);
-		register_address_increment(c, &c->regs[VCPU_REGS_RDI],
-				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
-								  : c->dst.bytes);
-
-		break;
-	case 0xaa ... 0xab:	/* stos */
-		c->dst.type = OP_MEM;
-		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = (unsigned long *)register_address(c,
-						   es_base(ctxt),
-						   c->regs[VCPU_REGS_RDI]);
-		c->dst.val = c->regs[VCPU_REGS_RAX];
-		register_address_increment(c, &c->regs[VCPU_REGS_RDI],
-				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
-							   : c->dst.bytes);
-		break;
-	case 0xac ... 0xad:	/* lods */
-		c->dst.type = OP_REG;
-		c->dst.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
-		c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
-		if ((rc = ops->read_emulated(register_address(c,
-						 seg_override_base(ctxt, c),
-						 c->regs[VCPU_REGS_RSI]),
-						 &c->dst.val,
-						 c->dst.bytes,
-						 ctxt->vcpu)) != 0)
-			goto done;
-		register_address_increment(c, &c->regs[VCPU_REGS_RSI],
-				       (ctxt->eflags & EFLG_DF) ? -c->dst.bytes
-							   : c->dst.bytes);
-		break;
-	case 0xae ... 0xaf:	/* scas */
-		DPRINTF("Urk! I don't handle SCAS.\n");
-		goto cannot_emulate;
-	case 0xb0 ... 0xbf: /* mov r, imm */
-		goto mov;
-	case 0xc0 ... 0xc1:
-		emulate_grp2(ctxt);
-		break;
-	case 0xc3: /* ret */
-		c->dst.type = OP_REG;
-		c->dst.ptr = &c->eip;
-		c->dst.bytes = c->op_bytes;
-		goto pop_instruction;
-	case 0xc6 ... 0xc7:	/* mov (sole member of Grp11) */
-	mov:
-		c->dst.val = c->src.val;
-		break;
-	case 0xcb:		/* ret far */
-		rc = emulate_ret_far(ctxt, ops);
-		if (rc)
-			goto done;
-		break;
-	case 0xd0 ... 0xd1:	/* Grp2 */
-		c->src.val = 1;
-		emulate_grp2(ctxt);
-		break;
-	case 0xd2 ... 0xd3:	/* Grp2 */
-		c->src.val = c->regs[VCPU_REGS_RCX];
-		emulate_grp2(ctxt);
-		break;
-	case 0xe4: 	/* inb */
-	case 0xe5: 	/* in */
-		port = c->src.val;
-		io_dir_in = 1;
-		goto do_io;
-	case 0xe6: /* outb */
-	case 0xe7: /* out */
-		port = c->src.val;
-		io_dir_in = 0;
-		goto do_io;
-	case 0xe8: /* call (near) */ {
-		long int rel = c->src.val;
-		c->src.val = (unsigned long) c->eip;
-		jmp_rel(c, rel);
-		emulate_push(ctxt);
-		break;
-	}
-	case 0xe9: /* jmp rel */
-		goto jmp;
-	case 0xea: /* jmp far */
-		if (kvm_load_segment_descriptor(ctxt->vcpu, c->src2.val, 9,
-					VCPU_SREG_CS) < 0) {
-			DPRINTF("jmp far: Failed to load CS descriptor\n");
-			goto cannot_emulate;
-		}
-
-		c->eip = c->src.val;
-		break;
-	case 0xeb:
-	      jmp:		/* jmp rel short */
-		jmp_rel(c, c->src.val);
-		c->dst.type = OP_NONE; /* Disable writeback. */
-		break;
-	case 0xec: /* in al,dx */
-	case 0xed: /* in (e/r)ax,dx */
-		port = c->regs[VCPU_REGS_RDX];
-		io_dir_in = 1;
-		goto do_io;
-	case 0xee: /* out al,dx */
-	case 0xef: /* out (e/r)ax,dx */
-		port = c->regs[VCPU_REGS_RDX];
-		io_dir_in = 0;
-	do_io:	if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in,
-				   (c->d & ByteOp) ? 1 : c->op_bytes,
-				   port) != 0) {
-			c->eip = saved_eip;
-			goto cannot_emulate;
-		}
-		break;
-	case 0xf4:              /* hlt */
-		ctxt->vcpu->arch.halt_request = 1;
-		break;
-	case 0xf5:	/* cmc */
-		/* complement carry flag from eflags reg */
-		ctxt->eflags ^= EFLG_CF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
-		break;
-	case 0xf6 ... 0xf7:	/* Grp3 */
-		rc = emulate_grp3(ctxt, ops);
-		if (rc != 0)
-			goto done;
-		break;
-	case 0xf8: /* clc */
-		ctxt->eflags &= ~EFLG_CF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
-		break;
-	case 0xfa: /* cli */
-		ctxt->eflags &= ~X86_EFLAGS_IF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
-		break;
-	case 0xfb: /* sti */
-		toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
-		ctxt->eflags |= X86_EFLAGS_IF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
-		break;
-	case 0xfc: /* cld */
-		ctxt->eflags &= ~EFLG_DF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
-		break;
-	case 0xfd: /* std */
-		ctxt->eflags |= EFLG_DF;
-		c->dst.type = OP_NONE;	/* Disable writeback. */
-		break;
-	case 0xfe ... 0xff:	/* Grp4/Grp5 */
-		rc = emulate_grp45(ctxt, ops);
-		if (rc != 0)
-			goto done;
-		break;
-	}
-
-writeback:
-	rc = writeback(ctxt, ops);
-	if (rc != 0)
-		goto done;
-
-	/* Commit shadow register state. */
-	memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);
-	kvm_rip_write(ctxt->vcpu, c->eip);
-
-done:
-	if (rc == X86EMUL_UNHANDLEABLE) {
-		c->eip = saved_eip;
-		return -1;
-	}
-	return 0;
-
-twobyte_insn:
-	switch (c->b) {
-	case 0x01: /* lgdt, lidt, lmsw */
-		switch (c->modrm_reg) {
-			u16 size;
-			unsigned long address;
-
-		case 0: /* vmcall */
-			if (c->modrm_mod != 3 || c->modrm_rm != 1)
-				goto cannot_emulate;
-
-			rc = kvm_fix_hypercall(ctxt->vcpu);
-			if (rc)
-				goto done;
-
-			/* Let the processor re-execute the fixed hypercall */
-			c->eip = kvm_rip_read(ctxt->vcpu);
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		case 2: /* lgdt */
-			rc = read_descriptor(ctxt, ops, c->src.ptr,
-					     &size, &address, c->op_bytes);
-			if (rc)
-				goto done;
-			realmode_lgdt(ctxt->vcpu, size, address);
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		case 3: /* lidt/vmmcall */
-			if (c->modrm_mod == 3) {
-				switch (c->modrm_rm) {
-				case 1:
-					rc = kvm_fix_hypercall(ctxt->vcpu);
-					if (rc)
-						goto done;
-					break;
-				default:
-					goto cannot_emulate;
-				}
-			} else {
-				rc = read_descriptor(ctxt, ops, c->src.ptr,
-						     &size, &address,
-						     c->op_bytes);
-				if (rc)
-					goto done;
-				realmode_lidt(ctxt->vcpu, size, address);
-			}
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		case 4: /* smsw */
-			c->dst.bytes = 2;
-			c->dst.val = realmode_get_cr(ctxt->vcpu, 0);
-			break;
-		case 6: /* lmsw */
-			realmode_lmsw(ctxt->vcpu, (u16)c->src.val,
-				      &ctxt->eflags);
-			c->dst.type = OP_NONE;
-			break;
-		case 7: /* invlpg*/
-			emulate_invlpg(ctxt->vcpu, memop);
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		default:
-			goto cannot_emulate;
-		}
-		break;
-	case 0x06:
-		emulate_clts(ctxt->vcpu);
-		c->dst.type = OP_NONE;
-		break;
-	case 0x08:		/* invd */
-	case 0x09:		/* wbinvd */
-	case 0x0d:		/* GrpP (prefetch) */
-	case 0x18:		/* Grp16 (prefetch/nop) */
-		c->dst.type = OP_NONE;
-		break;
-	case 0x20: /* mov cr, reg */
-		if (c->modrm_mod != 3)
-			goto cannot_emulate;
-		c->regs[c->modrm_rm] =
-				realmode_get_cr(ctxt->vcpu, c->modrm_reg);
-		c->dst.type = OP_NONE;	/* no writeback */
-		break;
-	case 0x21: /* mov from dr to reg */
-		if (c->modrm_mod != 3)
-			goto cannot_emulate;
-		rc = emulator_get_dr(ctxt, c->modrm_reg, &c->regs[c->modrm_rm]);
-		if (rc)
-			goto cannot_emulate;
-		c->dst.type = OP_NONE;	/* no writeback */
-		break;
-	case 0x22: /* mov reg, cr */
-		if (c->modrm_mod != 3)
-			goto cannot_emulate;
-		realmode_set_cr(ctxt->vcpu,
-				c->modrm_reg, c->modrm_val, &ctxt->eflags);
-		c->dst.type = OP_NONE;
-		break;
-	case 0x23: /* mov from reg to dr */
-		if (c->modrm_mod != 3)
-			goto cannot_emulate;
-		rc = emulator_set_dr(ctxt, c->modrm_reg,
-				     c->regs[c->modrm_rm]);
-		if (rc)
-			goto cannot_emulate;
-		c->dst.type = OP_NONE;	/* no writeback */
-		break;
-	case 0x30:
-		/* wrmsr */
-		msr_data = (u32)c->regs[VCPU_REGS_RAX]
-			| ((u64)c->regs[VCPU_REGS_RDX] << 32);
-		rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data);
-		if (rc) {
-			kvm_inject_gp(ctxt->vcpu, 0);
-			c->eip = kvm_rip_read(ctxt->vcpu);
-		}
-		rc = X86EMUL_CONTINUE;
-		c->dst.type = OP_NONE;
-		break;
-	case 0x32:
-		/* rdmsr */
-		rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
-		if (rc) {
-			kvm_inject_gp(ctxt->vcpu, 0);
-			c->eip = kvm_rip_read(ctxt->vcpu);
-		} else {
-			c->regs[VCPU_REGS_RAX] = (u32)msr_data;
-			c->regs[VCPU_REGS_RDX] = msr_data >> 32;
-		}
-		rc = X86EMUL_CONTINUE;
-		c->dst.type = OP_NONE;
-		break;
-	case 0x40 ... 0x4f:	/* cmov */
-		c->dst.val = c->dst.orig_val = c->src.val;
-		if (!test_cc(c->b, ctxt->eflags))
-			c->dst.type = OP_NONE; /* no writeback */
-		break;
-	case 0x80 ... 0x8f: /* jnz rel, etc*/
-		if (test_cc(c->b, ctxt->eflags))
-			jmp_rel(c, c->src.val);
-		c->dst.type = OP_NONE;
-		break;
-	case 0xa3:
-	      bt:		/* bt */
-		c->dst.type = OP_NONE;
-		/* only subword offset */
-		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("bt", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0xa4: /* shld imm8, r, r/m */
-	case 0xa5: /* shld cl, r, r/m */
-		emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags);
-		break;
-	case 0xab:
-	      bts:		/* bts */
-		/* only subword offset */
-		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("bts", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0xac: /* shrd imm8, r, r/m */
-	case 0xad: /* shrd cl, r, r/m */
-		emulate_2op_cl("shrd", c->src2, c->src, c->dst, ctxt->eflags);
-		break;
-	case 0xae:              /* clflush */
-		break;
-	case 0xb0 ... 0xb1:	/* cmpxchg */
-		/*
-		 * Save real source value, then compare EAX against
-		 * destination.
-		 */
-		c->src.orig_val = c->src.val;
-		c->src.val = c->regs[VCPU_REGS_RAX];
-		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
-		if (ctxt->eflags & EFLG_ZF) {
-			/* Success: write back to memory. */
-			c->dst.val = c->src.orig_val;
-		} else {
-			/* Failure: write the value we saw to EAX. */
-			c->dst.type = OP_REG;
-			c->dst.ptr = (unsigned long *)&c->regs[VCPU_REGS_RAX];
-		}
-		break;
-	case 0xb3:
-	      btr:		/* btr */
-		/* only subword offset */
-		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("btr", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0xb6 ... 0xb7:	/* movzx */
-		c->dst.bytes = c->op_bytes;
-		c->dst.val = (c->d & ByteOp) ? (u8) c->src.val
-						       : (u16) c->src.val;
-		break;
-	case 0xba:		/* Grp8 */
-		switch (c->modrm_reg & 3) {
-		case 0:
-			goto bt;
-		case 1:
-			goto bts;
-		case 2:
-			goto btr;
-		case 3:
-			goto btc;
-		}
-		break;
-	case 0xbb:
-	      btc:		/* btc */
-		/* only subword offset */
-		c->src.val &= (c->dst.bytes << 3) - 1;
-		emulate_2op_SrcV_nobyte("btc", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0xbe ... 0xbf:	/* movsx */
-		c->dst.bytes = c->op_bytes;
-		c->dst.val = (c->d & ByteOp) ? (s8) c->src.val :
-							(s16) c->src.val;
-		break;
-	case 0xc3:		/* movnti */
-		c->dst.bytes = c->op_bytes;
-		c->dst.val = (c->op_bytes == 4) ? (u32) c->src.val :
-							(u64) c->src.val;
-		break;
-	case 0xc7:		/* Grp9 (cmpxchg8b) */
-		rc = emulate_grp9(ctxt, ops, memop);
-		if (rc != 0)
-			goto done;
-		c->dst.type = OP_NONE;
-		break;
-	}
-	goto writeback;
-
-cannot_emulate:
-	DPRINTF("Cannot emulate %02x\n", c->b);
-	c->eip = saved_eip;
-	return -1;
-}
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index d677fa9..4cb7d5d 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -1262,7 +1262,6 @@ __init void lguest_init(void)
 	 */
 
 	/* Interrupt-related operations */
-	pv_irq_ops.init_IRQ = lguest_init_IRQ;
 	pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl);
 	pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(lg_restore_fl);
 	pv_irq_ops.irq_disable = PV_CALLEE_SAVE(irq_disable);
@@ -1270,7 +1269,6 @@ __init void lguest_init(void)
 	pv_irq_ops.safe_halt = lguest_safe_halt;
 
 	/* Setup operations */
-	pv_init_ops.memory_setup = lguest_memory_setup;
 	pv_init_ops.patch = lguest_patch;
 
 	/* Intercepts of various CPU instructions */
@@ -1320,10 +1318,11 @@ __init void lguest_init(void)
 	set_lguest_basic_apic_ops();
 #endif
 
-	/* Time operations */
-	pv_time_ops.get_wallclock = lguest_get_wallclock;
-	pv_time_ops.time_init = lguest_time_init;
-	pv_time_ops.get_tsc_khz = lguest_tsc_khz;
+	x86_init.resources.memory_setup = lguest_memory_setup;
+	x86_init.irqs.intr_init = lguest_init_IRQ;
+	x86_init.timers.timer_init = lguest_time_init;
+	x86_platform.calibrate_tsc = lguest_tsc_khz;
+	x86_platform.get_wallclock =  lguest_get_wallclock;
 
 	/*
 	 * Now is a good time to look at the implementations of these functions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 07c3189..9e60920 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -9,6 +9,8 @@ lib-y += thunk_$(BITS).o
 lib-y += usercopy_$(BITS).o getuser.o putuser.o
 lib-y += memcpy_$(BITS).o
 
+obj-y += msr-reg.o msr-reg-export.o
+
 ifeq ($(CONFIG_X86_32),y)
         obj-y += atomic64_32.o
         lib-y += checksum_32.o
diff --git a/arch/x86/lib/msr-reg-export.c b/arch/x86/lib/msr-reg-export.c
new file mode 100644
index 0000000..a311cc5
--- /dev/null
+++ b/arch/x86/lib/msr-reg-export.c
@@ -0,0 +1,5 @@
+#include <linux/module.h>
+#include <asm/msr.h>
+
+EXPORT_SYMBOL(native_rdmsr_safe_regs);
+EXPORT_SYMBOL(native_wrmsr_safe_regs);
diff --git a/arch/x86/lib/msr-reg.S b/arch/x86/lib/msr-reg.S
new file mode 100644
index 0000000..69fa106
--- /dev/null
+++ b/arch/x86/lib/msr-reg.S
@@ -0,0 +1,102 @@
+#include <linux/linkage.h>
+#include <linux/errno.h>
+#include <asm/dwarf2.h>
+#include <asm/asm.h>
+#include <asm/msr.h>
+
+#ifdef CONFIG_X86_64
+/*
+ * int native_{rdmsr,wrmsr}_safe_regs(u32 gprs[8]);
+ *
+ * reg layout: u32 gprs[eax, ecx, edx, ebx, esp, ebp, esi, edi]
+ *
+ */
+.macro op_safe_regs op
+ENTRY(native_\op\()_safe_regs)
+	CFI_STARTPROC
+	pushq_cfi %rbx
+	pushq_cfi %rbp
+	movq	%rdi, %r10	/* Save pointer */
+	xorl	%r11d, %r11d	/* Return value */
+	movl    (%rdi), %eax
+	movl    4(%rdi), %ecx
+	movl    8(%rdi), %edx
+	movl    12(%rdi), %ebx
+	movl    20(%rdi), %ebp
+	movl    24(%rdi), %esi
+	movl    28(%rdi), %edi
+	CFI_REMEMBER_STATE
+1:	\op
+2:	movl    %eax, (%r10)
+	movl	%r11d, %eax	/* Return value */
+	movl    %ecx, 4(%r10)
+	movl    %edx, 8(%r10)
+	movl    %ebx, 12(%r10)
+	movl    %ebp, 20(%r10)
+	movl    %esi, 24(%r10)
+	movl    %edi, 28(%r10)
+	popq_cfi %rbp
+	popq_cfi %rbx
+	ret
+3:
+	CFI_RESTORE_STATE
+	movl    $-EIO, %r11d
+	jmp     2b
+
+	_ASM_EXTABLE(1b, 3b)
+	CFI_ENDPROC
+ENDPROC(native_\op\()_safe_regs)
+.endm
+
+#else /* X86_32 */
+
+.macro op_safe_regs op
+ENTRY(native_\op\()_safe_regs)
+	CFI_STARTPROC
+	pushl_cfi %ebx
+	pushl_cfi %ebp
+	pushl_cfi %esi
+	pushl_cfi %edi
+	pushl_cfi $0              /* Return value */
+	pushl_cfi %eax
+	movl    4(%eax), %ecx
+	movl    8(%eax), %edx
+	movl    12(%eax), %ebx
+	movl    20(%eax), %ebp
+	movl    24(%eax), %esi
+	movl    28(%eax), %edi
+	movl    (%eax), %eax
+	CFI_REMEMBER_STATE
+1:	\op
+2:	pushl_cfi %eax
+	movl    4(%esp), %eax
+	popl_cfi (%eax)
+	addl    $4, %esp
+	CFI_ADJUST_CFA_OFFSET -4
+	movl    %ecx, 4(%eax)
+	movl    %edx, 8(%eax)
+	movl    %ebx, 12(%eax)
+	movl    %ebp, 20(%eax)
+	movl    %esi, 24(%eax)
+	movl    %edi, 28(%eax)
+	popl_cfi %eax
+	popl_cfi %edi
+	popl_cfi %esi
+	popl_cfi %ebp
+	popl_cfi %ebx
+	ret
+3:
+	CFI_RESTORE_STATE
+	movl    $-EIO, 4(%esp)
+	jmp     2b
+
+	_ASM_EXTABLE(1b, 3b)
+	CFI_ENDPROC
+ENDPROC(native_\op\()_safe_regs)
+.endm
+
+#endif
+
+op_safe_regs rdmsr
+op_safe_regs wrmsr
+
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c
index caa24ac..33a1e3c 100644
--- a/arch/x86/lib/msr.c
+++ b/arch/x86/lib/msr.c
@@ -175,3 +175,52 @@ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h)
 	return err ? err : rv.err;
 }
 EXPORT_SYMBOL(wrmsr_safe_on_cpu);
+
+/*
+ * These variants are significantly slower, but allows control over
+ * the entire 32-bit GPR set.
+ */
+struct msr_regs_info {
+	u32 *regs;
+	int err;
+};
+
+static void __rdmsr_safe_regs_on_cpu(void *info)
+{
+	struct msr_regs_info *rv = info;
+
+	rv->err = rdmsr_safe_regs(rv->regs);
+}
+
+static void __wrmsr_safe_regs_on_cpu(void *info)
+{
+	struct msr_regs_info *rv = info;
+
+	rv->err = wrmsr_safe_regs(rv->regs);
+}
+
+int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+	int err;
+	struct msr_regs_info rv;
+
+	rv.regs   = regs;
+	rv.err    = -EIO;
+	err = smp_call_function_single(cpu, __rdmsr_safe_regs_on_cpu, &rv, 1);
+
+	return err ? err : rv.err;
+}
+EXPORT_SYMBOL(rdmsr_safe_regs_on_cpu);
+
+int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 *regs)
+{
+	int err;
+	struct msr_regs_info rv;
+
+	rv.regs = regs;
+	rv.err  = -EIO;
+	err = smp_call_function_single(cpu, __wrmsr_safe_regs_on_cpu, &rv, 1);
+
+	return err ? err : rv.err;
+}
+EXPORT_SYMBOL(wrmsr_safe_regs_on_cpu);
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index eefdeee..9b5a9f5 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -1,5 +1,9 @@
 obj-y	:=  init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \
-	    pat.o pgtable.o gup.o
+	    pat.o pgtable.o physaddr.o gup.o
+
+# Make sure __phys_addr has no stackprotector
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_physaddr.o		:= $(nostackp)
 
 obj-$(CONFIG_SMP)		+= tlb.o
 
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index bfae139..82728f2 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -10,7 +10,7 @@
 #include <linux/bootmem.h>		/* max_low_pfn			*/
 #include <linux/kprobes.h>		/* __kprobes, ...		*/
 #include <linux/mmiotrace.h>		/* kmmio_handler, ...		*/
-#include <linux/perf_counter.h>		/* perf_swcounter_event		*/
+#include <linux/perf_event.h>		/* perf_sw_event		*/
 
 #include <asm/traps.h>			/* dotraplinkage, ...		*/
 #include <asm/pgalloc.h>		/* pgd_*(), ...			*/
@@ -285,26 +285,25 @@ check_v8086_mode(struct pt_regs *regs, unsigned long address,
 		tsk->thread.screen_bitmap |= 1 << bit;
 }
 
-static void dump_pagetable(unsigned long address)
+static bool low_pfn(unsigned long pfn)
 {
-	__typeof__(pte_val(__pte(0))) page;
+	return pfn < max_low_pfn;
+}
 
-	page = read_cr3();
-	page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
+static void dump_pagetable(unsigned long address)
+{
+	pgd_t *base = __va(read_cr3());
+	pgd_t *pgd = &base[pgd_index(address)];
+	pmd_t *pmd;
+	pte_t *pte;
 
 #ifdef CONFIG_X86_PAE
-	printk("*pdpt = %016Lx ", page);
-	if ((page >> PAGE_SHIFT) < max_low_pfn
-	    && page & _PAGE_PRESENT) {
-		page &= PAGE_MASK;
-		page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
-							& (PTRS_PER_PMD - 1)];
-		printk(KERN_CONT "*pde = %016Lx ", page);
-		page &= ~_PAGE_NX;
-	}
-#else
-	printk("*pde = %08lx ", page);
+	printk("*pdpt = %016Lx ", pgd_val(*pgd));
+	if (!low_pfn(pgd_val(*pgd) >> PAGE_SHIFT) || !pgd_present(*pgd))
+		goto out;
 #endif
+	pmd = pmd_offset(pud_offset(pgd, address), address);
+	printk(KERN_CONT "*pde = %0*Lx ", sizeof(*pmd) * 2, (u64)pmd_val(*pmd));
 
 	/*
 	 * We must not directly access the pte in the highpte
@@ -312,16 +311,12 @@ static void dump_pagetable(unsigned long address)
 	 * And let's rather not kmap-atomic the pte, just in case
 	 * it's allocated already:
 	 */
-	if ((page >> PAGE_SHIFT) < max_low_pfn
-	    && (page & _PAGE_PRESENT)
-	    && !(page & _PAGE_PSE)) {
-
-		page &= PAGE_MASK;
-		page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
-							& (PTRS_PER_PTE - 1)];
-		printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
-	}
+	if (!low_pfn(pmd_pfn(*pmd)) || !pmd_present(*pmd) || pmd_large(*pmd))
+		goto out;
 
+	pte = pte_offset_kernel(pmd, address);
+	printk("*pte = %0*Lx ", sizeof(*pte) * 2, (u64)pte_val(*pte));
+out:
 	printk("\n");
 }
 
@@ -450,16 +445,12 @@ static int bad_address(void *p)
 
 static void dump_pagetable(unsigned long address)
 {
-	pgd_t *pgd;
+	pgd_t *base = __va(read_cr3() & PHYSICAL_PAGE_MASK);
+	pgd_t *pgd = base + pgd_index(address);
 	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte;
 
-	pgd = (pgd_t *)read_cr3();
-
-	pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK);
-
-	pgd += pgd_index(address);
 	if (bad_address(pgd))
 		goto bad;
 
@@ -1026,7 +1017,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code)
 	if (unlikely(error_code & PF_RSVD))
 		pgtable_bad(regs, error_code, address);
 
-	perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
 
 	/*
 	 * If we're in an interrupt, have no user context or are running
@@ -1123,11 +1114,11 @@ good_area:
 
 	if (fault & VM_FAULT_MAJOR) {
 		tsk->maj_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
 				     regs, address);
 	} else {
 		tsk->min_flt++;
-		perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
 				     regs, address);
 	}
 
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 2112ed5..63a6ba6 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -24,7 +24,7 @@ void kunmap(struct page *page)
  * no global lock is needed and because the kmap code must perform a global TLB
  * invalidation when the kmap pool wraps.
  *
- * However when holding an atomic kmap is is not legal to sleep, so atomic
+ * However when holding an atomic kmap it is not legal to sleep, so atomic
  * kmaps are appropriate for short, tight code paths only.
  */
 void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
@@ -104,6 +104,7 @@ EXPORT_SYMBOL(kunmap);
 EXPORT_SYMBOL(kmap_atomic);
 EXPORT_SYMBOL(kunmap_atomic);
 EXPORT_SYMBOL(kmap_atomic_prot);
+EXPORT_SYMBOL(kmap_atomic_to_page);
 
 void __init set_highmem_pages_init(void)
 {
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index fe6f84c..84e236c 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -21,7 +21,7 @@
 #include <linux/module.h>
 #include <linux/highmem.h>
 
-int is_io_mapping_possible(resource_size_t base, unsigned long size)
+static int is_io_mapping_possible(resource_size_t base, unsigned long size)
 {
 #if !defined(CONFIG_X86_PAE) && defined(CONFIG_PHYS_ADDR_T_64BIT)
 	/* There is no way to map greater than 1 << 32 address without PAE */
@@ -30,7 +30,30 @@ int is_io_mapping_possible(resource_size_t base, unsigned long size)
 #endif
 	return 1;
 }
-EXPORT_SYMBOL_GPL(is_io_mapping_possible);
+
+int iomap_create_wc(resource_size_t base, unsigned long size, pgprot_t *prot)
+{
+	unsigned long flag = _PAGE_CACHE_WC;
+	int ret;
+
+	if (!is_io_mapping_possible(base, size))
+		return -EINVAL;
+
+	ret = io_reserve_memtype(base, base + size, &flag);
+	if (ret)
+		return ret;
+
+	*prot = __pgprot(__PAGE_KERNEL | flag);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(iomap_create_wc);
+
+void
+iomap_free(resource_size_t base, unsigned long size)
+{
+	io_free_memtype(base, base + size);
+}
+EXPORT_SYMBOL_GPL(iomap_free);
 
 void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
 {
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 8a45093..334e63c 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -22,77 +22,7 @@
 #include <asm/pgalloc.h>
 #include <asm/pat.h>
 
-static inline int phys_addr_valid(resource_size_t addr)
-{
-#ifdef CONFIG_PHYS_ADDR_T_64BIT
-	return !(addr >> boot_cpu_data.x86_phys_bits);
-#else
-	return 1;
-#endif
-}
-
-#ifdef CONFIG_X86_64
-
-unsigned long __phys_addr(unsigned long x)
-{
-	if (x >= __START_KERNEL_map) {
-		x -= __START_KERNEL_map;
-		VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
-		x += phys_base;
-	} else {
-		VIRTUAL_BUG_ON(x < PAGE_OFFSET);
-		x -= PAGE_OFFSET;
-		VIRTUAL_BUG_ON(!phys_addr_valid(x));
-	}
-	return x;
-}
-EXPORT_SYMBOL(__phys_addr);
-
-bool __virt_addr_valid(unsigned long x)
-{
-	if (x >= __START_KERNEL_map) {
-		x -= __START_KERNEL_map;
-		if (x >= KERNEL_IMAGE_SIZE)
-			return false;
-		x += phys_base;
-	} else {
-		if (x < PAGE_OFFSET)
-			return false;
-		x -= PAGE_OFFSET;
-		if (!phys_addr_valid(x))
-			return false;
-	}
-
-	return pfn_valid(x >> PAGE_SHIFT);
-}
-EXPORT_SYMBOL(__virt_addr_valid);
-
-#else
-
-#ifdef CONFIG_DEBUG_VIRTUAL
-unsigned long __phys_addr(unsigned long x)
-{
-	/* VMALLOC_* aren't constants  */
-	VIRTUAL_BUG_ON(x < PAGE_OFFSET);
-	VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
-	return x - PAGE_OFFSET;
-}
-EXPORT_SYMBOL(__phys_addr);
-#endif
-
-bool __virt_addr_valid(unsigned long x)
-{
-	if (x < PAGE_OFFSET)
-		return false;
-	if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
-		return false;
-	if (x >= FIXADDR_START)
-		return false;
-	return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
-}
-EXPORT_SYMBOL(__virt_addr_valid);
-
-#endif
+#include "physaddr.h"
 
 int page_is_ram(unsigned long pagenr)
 {
@@ -228,24 +158,14 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 	retval = reserve_memtype(phys_addr, (u64)phys_addr + size,
 						prot_val, &new_prot_val);
 	if (retval) {
-		pr_debug("Warning: reserve_memtype returned %d\n", retval);
+		printk(KERN_ERR "ioremap reserve_memtype failed %d\n", retval);
 		return NULL;
 	}
 
 	if (prot_val != new_prot_val) {
-		/*
-		 * Do not fallback to certain memory types with certain
-		 * requested type:
-		 * - request is uc-, return cannot be write-back
-		 * - request is uc-, return cannot be write-combine
-		 * - request is write-combine, return cannot be write-back
-		 */
-		if ((prot_val == _PAGE_CACHE_UC_MINUS &&
-		     (new_prot_val == _PAGE_CACHE_WB ||
-		      new_prot_val == _PAGE_CACHE_WC)) ||
-		    (prot_val == _PAGE_CACHE_WC &&
-		     new_prot_val == _PAGE_CACHE_WB)) {
-			pr_debug(
+		if (!is_new_memtype_allowed(phys_addr, size,
+					    prot_val, new_prot_val)) {
+			printk(KERN_ERR
 		"ioremap error for 0x%llx-0x%llx, requested 0x%lx, got 0x%lx\n",
 				(unsigned long long)phys_addr,
 				(unsigned long long)(phys_addr + size),
diff --git a/arch/x86/mm/kmemcheck/shadow.c b/arch/x86/mm/kmemcheck/shadow.c
index e773b6b..3f66b82 100644
--- a/arch/x86/mm/kmemcheck/shadow.c
+++ b/arch/x86/mm/kmemcheck/shadow.c
@@ -1,7 +1,6 @@
 #include <linux/kmemcheck.h>
 #include <linux/module.h>
 #include <linux/mm.h>
-#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 1658296..c8191de 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -29,13 +29,26 @@
 #include <linux/random.h>
 #include <linux/limits.h>
 #include <linux/sched.h>
+#include <asm/elf.h>
+
+static unsigned int stack_maxrandom_size(void)
+{
+	unsigned int max = 0;
+	if ((current->flags & PF_RANDOMIZE) &&
+		!(current->personality & ADDR_NO_RANDOMIZE)) {
+		max = ((-1U) & STACK_RND_MASK) << PAGE_SHIFT;
+	}
+
+	return max;
+}
+
 
 /*
  * Top of mmap area (just below the process stack).
  *
- * Leave an at least ~128 MB hole.
+ * Leave an at least ~128 MB hole with possible stack randomization.
  */
-#define MIN_GAP (128*1024*1024)
+#define MIN_GAP (128*1024*1024UL + stack_maxrandom_size())
 #define MAX_GAP (TASK_SIZE/6*5)
 
 /*
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 7e600c1..24952fd 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -12,6 +12,7 @@
 #include <linux/seq_file.h>
 #include <linux/debugfs.h>
 #include <linux/pfn.h>
+#include <linux/percpu.h>
 
 #include <asm/e820.h>
 #include <asm/processor.h>
@@ -686,7 +687,7 @@ static int cpa_process_alias(struct cpa_data *cpa)
 {
 	struct cpa_data alias_cpa;
 	unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT);
-	unsigned long vaddr, remapped;
+	unsigned long vaddr;
 	int ret;
 
 	if (cpa->pfn >= max_pfn_mapped)
@@ -744,24 +745,6 @@ static int cpa_process_alias(struct cpa_data *cpa)
 	}
 #endif
 
-	/*
-	 * If the PMD page was partially used for per-cpu remapping,
-	 * the recycled area needs to be split and modified.  Because
-	 * the area is always proper subset of a PMD page
-	 * cpa->numpages is guaranteed to be 1 for these areas, so
-	 * there's no need to loop over and check for further remaps.
-	 */
-	remapped = (unsigned long)pcpu_lpage_remapped((void *)laddr);
-	if (remapped) {
-		WARN_ON(cpa->numpages > 1);
-		alias_cpa = *cpa;
-		alias_cpa.vaddr = &remapped;
-		alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY);
-		ret = __change_page_attr_set_clr(&alias_cpa, 0);
-		if (ret)
-			return ret;
-	}
-
 	return 0;
 }
 
@@ -822,6 +805,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
 {
 	struct cpa_data cpa;
 	int ret, cache, checkalias;
+	unsigned long baddr = 0;
 
 	/*
 	 * Check, if we are requested to change a not supported
@@ -853,6 +837,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
 			 */
 			WARN_ON_ONCE(1);
 		}
+		/*
+		 * Save address for cache flush. *addr is modified in the call
+		 * to __change_page_attr_set_clr() below.
+		 */
+		baddr = *addr;
 	}
 
 	/* Must avoid aliasing mappings in the highmem code */
@@ -900,7 +889,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
 			cpa_flush_array(addr, numpages, cache,
 					cpa.flags, pages);
 		} else
-			cpa_flush_range(*addr, numpages, cache);
+			cpa_flush_range(baddr, numpages, cache);
 	} else
 		cpa_flush_all(cache);
 
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 352aa9e..7257cf3 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -15,6 +15,7 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 #include <linux/fs.h>
+#include <linux/rbtree.h>
 
 #include <asm/cacheflush.h>
 #include <asm/processor.h>
@@ -148,11 +149,10 @@ static char *cattr_name(unsigned long flags)
  * areas). All the aliases have the same cache attributes of course.
  * Zero attributes are represented as holes.
  *
- * Currently the data structure is a list because the number of mappings
- * are expected to be relatively small. If this should be a problem
- * it could be changed to a rbtree or similar.
+ * The data structure is a list that is also organized as an rbtree
+ * sorted on the start address of memtype range.
  *
- * memtype_lock protects the whole list.
+ * memtype_lock protects both the linear list and rbtree.
  */
 
 struct memtype {
@@ -160,11 +160,53 @@ struct memtype {
 	u64			end;
 	unsigned long		type;
 	struct list_head	nd;
+	struct rb_node		rb;
 };
 
+static struct rb_root memtype_rbroot = RB_ROOT;
 static LIST_HEAD(memtype_list);
 static DEFINE_SPINLOCK(memtype_lock);	/* protects memtype list */
 
+static struct memtype *memtype_rb_search(struct rb_root *root, u64 start)
+{
+	struct rb_node *node = root->rb_node;
+	struct memtype *last_lower = NULL;
+
+	while (node) {
+		struct memtype *data = container_of(node, struct memtype, rb);
+
+		if (data->start < start) {
+			last_lower = data;
+			node = node->rb_right;
+		} else if (data->start > start) {
+			node = node->rb_left;
+		} else
+			return data;
+	}
+
+	/* Will return NULL if there is no entry with its start <= start */
+	return last_lower;
+}
+
+static void memtype_rb_insert(struct rb_root *root, struct memtype *data)
+{
+	struct rb_node **new = &(root->rb_node);
+	struct rb_node *parent = NULL;
+
+	while (*new) {
+		struct memtype *this = container_of(*new, struct memtype, rb);
+
+		parent = *new;
+		if (data->start <= this->start)
+			new = &((*new)->rb_left);
+		else if (data->start > this->start)
+			new = &((*new)->rb_right);
+	}
+
+	rb_link_node(&data->rb, parent, new);
+	rb_insert_color(&data->rb, root);
+}
+
 /*
  * Does intersection of PAT memory type and MTRR memory type and returns
  * the resulting memory type as PAT understands it.
@@ -218,9 +260,6 @@ chk_conflict(struct memtype *new, struct memtype *entry, unsigned long *type)
 	return -EBUSY;
 }
 
-static struct memtype *cached_entry;
-static u64 cached_start;
-
 static int pat_pagerange_is_ram(unsigned long start, unsigned long end)
 {
 	int ram_page = 0, not_rampage = 0;
@@ -249,63 +288,61 @@ static int pat_pagerange_is_ram(unsigned long start, unsigned long end)
 }
 
 /*
- * For RAM pages, mark the pages as non WB memory type using
- * PageNonWB (PG_arch_1). We allow only one set_memory_uc() or
- * set_memory_wc() on a RAM page at a time before marking it as WB again.
- * This is ok, because only one driver will be owning the page and
- * doing set_memory_*() calls.
+ * For RAM pages, we use page flags to mark the pages with appropriate type.
+ * Here we do two pass:
+ * - Find the memtype of all the pages in the range, look for any conflicts
+ * - In case of no conflicts, set the new memtype for pages in the range
  *
- * For now, we use PageNonWB to track that the RAM page is being mapped
- * as non WB. In future, we will have to use one more flag
- * (or some other mechanism in page_struct) to distinguish between
- * UC and WC mapping.
+ * Caller must hold memtype_lock for atomicity.
  */
 static int reserve_ram_pages_type(u64 start, u64 end, unsigned long req_type,
 				  unsigned long *new_type)
 {
 	struct page *page;
-	u64 pfn, end_pfn;
+	u64 pfn;
+
+	if (req_type == _PAGE_CACHE_UC) {
+		/* We do not support strong UC */
+		WARN_ON_ONCE(1);
+		req_type = _PAGE_CACHE_UC_MINUS;
+	}
 
 	for (pfn = (start >> PAGE_SHIFT); pfn < (end >> PAGE_SHIFT); ++pfn) {
-		page = pfn_to_page(pfn);
-		if (page_mapped(page) || PageNonWB(page))
-			goto out;
+		unsigned long type;
 
-		SetPageNonWB(page);
+		page = pfn_to_page(pfn);
+		type = get_page_memtype(page);
+		if (type != -1) {
+			printk(KERN_INFO "reserve_ram_pages_type failed "
+				"0x%Lx-0x%Lx, track 0x%lx, req 0x%lx\n",
+				start, end, type, req_type);
+			if (new_type)
+				*new_type = type;
+
+			return -EBUSY;
+		}
 	}
-	return 0;
 
-out:
-	end_pfn = pfn;
-	for (pfn = (start >> PAGE_SHIFT); pfn < end_pfn; ++pfn) {
+	if (new_type)
+		*new_type = req_type;
+
+	for (pfn = (start >> PAGE_SHIFT); pfn < (end >> PAGE_SHIFT); ++pfn) {
 		page = pfn_to_page(pfn);
-		ClearPageNonWB(page);
+		set_page_memtype(page, req_type);
 	}
-
-	return -EINVAL;
+	return 0;
 }
 
 static int free_ram_pages_type(u64 start, u64 end)
 {
 	struct page *page;
-	u64 pfn, end_pfn;
+	u64 pfn;
 
 	for (pfn = (start >> PAGE_SHIFT); pfn < (end >> PAGE_SHIFT); ++pfn) {
 		page = pfn_to_page(pfn);
-		if (page_mapped(page) || !PageNonWB(page))
-			goto out;
-
-		ClearPageNonWB(page);
+		set_page_memtype(page, -1);
 	}
 	return 0;
-
-out:
-	end_pfn = pfn;
-	for (pfn = (start >> PAGE_SHIFT); pfn < end_pfn; ++pfn) {
-		page = pfn_to_page(pfn);
-		SetPageNonWB(page);
-	}
-	return -EINVAL;
 }
 
 /*
@@ -339,6 +376,8 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 		if (new_type) {
 			if (req_type == -1)
 				*new_type = _PAGE_CACHE_WB;
+			else if (req_type == _PAGE_CACHE_WC)
+				*new_type = _PAGE_CACHE_UC_MINUS;
 			else
 				*new_type = req_type & _PAGE_CACHE_MASK;
 		}
@@ -364,11 +403,16 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 		*new_type = actual_type;
 
 	is_range_ram = pat_pagerange_is_ram(start, end);
-	if (is_range_ram == 1)
-		return reserve_ram_pages_type(start, end, req_type,
-					      new_type);
-	else if (is_range_ram < 0)
+	if (is_range_ram == 1) {
+
+		spin_lock(&memtype_lock);
+		err = reserve_ram_pages_type(start, end, req_type, new_type);
+		spin_unlock(&memtype_lock);
+
+		return err;
+	} else if (is_range_ram < 0) {
 		return -EINVAL;
+	}
 
 	new  = kmalloc(sizeof(struct memtype), GFP_KERNEL);
 	if (!new)
@@ -380,17 +424,11 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
 	spin_lock(&memtype_lock);
 
-	if (cached_entry && start >= cached_start)
-		entry = cached_entry;
-	else
-		entry = list_entry(&memtype_list, struct memtype, nd);
-
 	/* Search for existing mapping that overlaps the current range */
 	where = NULL;
-	list_for_each_entry_continue(entry, &memtype_list, nd) {
+	list_for_each_entry(entry, &memtype_list, nd) {
 		if (end <= entry->start) {
 			where = entry->nd.prev;
-			cached_entry = list_entry(where, struct memtype, nd);
 			break;
 		} else if (start <= entry->start) { /* end > entry->start */
 			err = chk_conflict(new, entry, new_type);
@@ -398,8 +436,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 				dprintk("Overlap at 0x%Lx-0x%Lx\n",
 					entry->start, entry->end);
 				where = entry->nd.prev;
-				cached_entry = list_entry(where,
-							struct memtype, nd);
 			}
 			break;
 		} else if (start < entry->end) { /* start > entry->start */
@@ -407,8 +443,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 			if (!err) {
 				dprintk("Overlap at 0x%Lx-0x%Lx\n",
 					entry->start, entry->end);
-				cached_entry = list_entry(entry->nd.prev,
-							struct memtype, nd);
 
 				/*
 				 * Move to right position in the linked
@@ -436,13 +470,13 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 		return err;
 	}
 
-	cached_start = start;
-
 	if (where)
 		list_add(&new->nd, where);
 	else
 		list_add_tail(&new->nd, &memtype_list);
 
+	memtype_rb_insert(&memtype_rbroot, new);
+
 	spin_unlock(&memtype_lock);
 
 	dprintk("reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n",
@@ -454,7 +488,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
 int free_memtype(u64 start, u64 end)
 {
-	struct memtype *entry;
+	struct memtype *entry, *saved_entry;
 	int err = -EINVAL;
 	int is_range_ram;
 
@@ -466,23 +500,58 @@ int free_memtype(u64 start, u64 end)
 		return 0;
 
 	is_range_ram = pat_pagerange_is_ram(start, end);
-	if (is_range_ram == 1)
-		return free_ram_pages_type(start, end);
-	else if (is_range_ram < 0)
+	if (is_range_ram == 1) {
+
+		spin_lock(&memtype_lock);
+		err = free_ram_pages_type(start, end);
+		spin_unlock(&memtype_lock);
+
+		return err;
+	} else if (is_range_ram < 0) {
 		return -EINVAL;
+	}
 
 	spin_lock(&memtype_lock);
-	list_for_each_entry(entry, &memtype_list, nd) {
+
+	entry = memtype_rb_search(&memtype_rbroot, start);
+	if (unlikely(entry == NULL))
+		goto unlock_ret;
+
+	/*
+	 * Saved entry points to an entry with start same or less than what
+	 * we searched for. Now go through the list in both directions to look
+	 * for the entry that matches with both start and end, with list stored
+	 * in sorted start address
+	 */
+	saved_entry = entry;
+	list_for_each_entry_from(entry, &memtype_list, nd) {
 		if (entry->start == start && entry->end == end) {
-			if (cached_entry == entry || cached_start == start)
-				cached_entry = NULL;
+			rb_erase(&entry->rb, &memtype_rbroot);
+			list_del(&entry->nd);
+			kfree(entry);
+			err = 0;
+			break;
+		} else if (entry->start > start) {
+			break;
+		}
+	}
+
+	if (!err)
+		goto unlock_ret;
 
+	entry = saved_entry;
+	list_for_each_entry_reverse(entry, &memtype_list, nd) {
+		if (entry->start == start && entry->end == end) {
+			rb_erase(&entry->rb, &memtype_rbroot);
 			list_del(&entry->nd);
 			kfree(entry);
 			err = 0;
 			break;
+		} else if (entry->start < start) {
+			break;
 		}
 	}
+unlock_ret:
 	spin_unlock(&memtype_lock);
 
 	if (err) {
@@ -496,6 +565,101 @@ int free_memtype(u64 start, u64 end)
 }
 
 
+/**
+ * lookup_memtype - Looksup the memory type for a physical address
+ * @paddr: physical address of which memory type needs to be looked up
+ *
+ * Only to be called when PAT is enabled
+ *
+ * Returns _PAGE_CACHE_WB, _PAGE_CACHE_WC, _PAGE_CACHE_UC_MINUS or
+ * _PAGE_CACHE_UC
+ */
+static unsigned long lookup_memtype(u64 paddr)
+{
+	int rettype = _PAGE_CACHE_WB;
+	struct memtype *entry;
+
+	if (is_ISA_range(paddr, paddr + PAGE_SIZE - 1))
+		return rettype;
+
+	if (pat_pagerange_is_ram(paddr, paddr + PAGE_SIZE)) {
+		struct page *page;
+		spin_lock(&memtype_lock);
+		page = pfn_to_page(paddr >> PAGE_SHIFT);
+		rettype = get_page_memtype(page);
+		spin_unlock(&memtype_lock);
+		/*
+		 * -1 from get_page_memtype() implies RAM page is in its
+		 * default state and not reserved, and hence of type WB
+		 */
+		if (rettype == -1)
+			rettype = _PAGE_CACHE_WB;
+
+		return rettype;
+	}
+
+	spin_lock(&memtype_lock);
+
+	entry = memtype_rb_search(&memtype_rbroot, paddr);
+	if (entry != NULL)
+		rettype = entry->type;
+	else
+		rettype = _PAGE_CACHE_UC_MINUS;
+
+	spin_unlock(&memtype_lock);
+	return rettype;
+}
+
+/**
+ * io_reserve_memtype - Request a memory type mapping for a region of memory
+ * @start: start (physical address) of the region
+ * @end: end (physical address) of the region
+ * @type: A pointer to memtype, with requested type. On success, requested
+ * or any other compatible type that was available for the region is returned
+ *
+ * On success, returns 0
+ * On failure, returns non-zero
+ */
+int io_reserve_memtype(resource_size_t start, resource_size_t end,
+			unsigned long *type)
+{
+	resource_size_t size = end - start;
+	unsigned long req_type = *type;
+	unsigned long new_type;
+	int ret;
+
+	WARN_ON_ONCE(iomem_map_sanity_check(start, size));
+
+	ret = reserve_memtype(start, end, req_type, &new_type);
+	if (ret)
+		goto out_err;
+
+	if (!is_new_memtype_allowed(start, size, req_type, new_type))
+		goto out_free;
+
+	if (kernel_map_sync_memtype(start, size, new_type) < 0)
+		goto out_free;
+
+	*type = new_type;
+	return 0;
+
+out_free:
+	free_memtype(start, end);
+	ret = -EBUSY;
+out_err:
+	return ret;
+}
+
+/**
+ * io_free_memtype - Release a memory type mapping for a region of memory
+ * @start: start (physical address) of the region
+ * @end: end (physical address) of the region
+ */
+void io_free_memtype(resource_size_t start, resource_size_t end)
+{
+	free_memtype(start, end);
+}
+
 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 				unsigned long size, pgprot_t vma_prot)
 {
@@ -577,7 +741,7 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
 {
 	unsigned long id_sz;
 
-	if (!pat_enabled || base >= __pa(high_memory))
+	if (base >= __pa(high_memory))
 		return 0;
 
 	id_sz = (__pa(high_memory) < base + size) ?
@@ -612,11 +776,29 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
 	is_ram = pat_pagerange_is_ram(paddr, paddr + size);
 
 	/*
-	 * reserve_pfn_range() doesn't support RAM pages. Maintain the current
-	 * behavior with RAM pages by returning success.
+	 * reserve_pfn_range() for RAM pages. We do not refcount to keep
+	 * track of number of mappings of RAM pages. We can assert that
+	 * the type requested matches the type of first page in the range.
 	 */
-	if (is_ram != 0)
+	if (is_ram) {
+		if (!pat_enabled)
+			return 0;
+
+		flags = lookup_memtype(paddr);
+		if (want_flags != flags) {
+			printk(KERN_WARNING
+			"%s:%d map pfn RAM range req %s for %Lx-%Lx, got %s\n",
+				current->comm, current->pid,
+				cattr_name(want_flags),
+				(unsigned long long)paddr,
+				(unsigned long long)(paddr + size),
+				cattr_name(flags));
+			*vma_prot = __pgprot((pgprot_val(*vma_prot) &
+					      (~_PAGE_CACHE_MASK)) |
+					     flags);
+		}
 		return 0;
+	}
 
 	ret = reserve_memtype(paddr, paddr + size, want_flags, &flags);
 	if (ret)
@@ -678,14 +860,6 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
 	unsigned long vma_size = vma->vm_end - vma->vm_start;
 	pgprot_t pgprot;
 
-	if (!pat_enabled)
-		return 0;
-
-	/*
-	 * For now, only handle remap_pfn_range() vmas where
-	 * is_linear_pfn_mapping() == TRUE. Handling of
-	 * vm_insert_pfn() is TBD.
-	 */
 	if (is_linear_pfn_mapping(vma)) {
 		/*
 		 * reserve the whole chunk covered by vma. We need the
@@ -713,23 +887,24 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
 int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
 			unsigned long pfn, unsigned long size)
 {
+	unsigned long flags;
 	resource_size_t paddr;
 	unsigned long vma_size = vma->vm_end - vma->vm_start;
 
-	if (!pat_enabled)
-		return 0;
-
-	/*
-	 * For now, only handle remap_pfn_range() vmas where
-	 * is_linear_pfn_mapping() == TRUE. Handling of
-	 * vm_insert_pfn() is TBD.
-	 */
 	if (is_linear_pfn_mapping(vma)) {
 		/* reserve the whole chunk starting from vm_pgoff */
 		paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
 		return reserve_pfn_range(paddr, vma_size, prot, 0);
 	}
 
+	if (!pat_enabled)
+		return 0;
+
+	/* for vm_insert_pfn and friends, we set prot based on lookup */
+	flags = lookup_memtype(pfn << PAGE_SHIFT);
+	*prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) |
+			 flags);
+
 	return 0;
 }
 
@@ -744,14 +919,6 @@ void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
 	resource_size_t paddr;
 	unsigned long vma_size = vma->vm_end - vma->vm_start;
 
-	if (!pat_enabled)
-		return;
-
-	/*
-	 * For now, only handle remap_pfn_range() vmas where
-	 * is_linear_pfn_mapping() == TRUE. Handling of
-	 * vm_insert_pfn() is TBD.
-	 */
 	if (is_linear_pfn_mapping(vma)) {
 		/* free the whole chunk starting from vm_pgoff */
 		paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
@@ -827,7 +994,7 @@ static int memtype_seq_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
-static struct seq_operations memtype_seq_ops = {
+static const struct seq_operations memtype_seq_ops = {
 	.start = memtype_seq_start,
 	.next  = memtype_seq_next,
 	.stop  = memtype_seq_stop,
diff --git a/arch/x86/mm/physaddr.c b/arch/x86/mm/physaddr.c
new file mode 100644
index 0000000..d2e2735
--- /dev/null
+++ b/arch/x86/mm/physaddr.c
@@ -0,0 +1,70 @@
+#include <linux/mmdebug.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+
+#include "physaddr.h"
+
+#ifdef CONFIG_X86_64
+
+unsigned long __phys_addr(unsigned long x)
+{
+	if (x >= __START_KERNEL_map) {
+		x -= __START_KERNEL_map;
+		VIRTUAL_BUG_ON(x >= KERNEL_IMAGE_SIZE);
+		x += phys_base;
+	} else {
+		VIRTUAL_BUG_ON(x < PAGE_OFFSET);
+		x -= PAGE_OFFSET;
+		VIRTUAL_BUG_ON(!phys_addr_valid(x));
+	}
+	return x;
+}
+EXPORT_SYMBOL(__phys_addr);
+
+bool __virt_addr_valid(unsigned long x)
+{
+	if (x >= __START_KERNEL_map) {
+		x -= __START_KERNEL_map;
+		if (x >= KERNEL_IMAGE_SIZE)
+			return false;
+		x += phys_base;
+	} else {
+		if (x < PAGE_OFFSET)
+			return false;
+		x -= PAGE_OFFSET;
+		if (!phys_addr_valid(x))
+			return false;
+	}
+
+	return pfn_valid(x >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(__virt_addr_valid);
+
+#else
+
+#ifdef CONFIG_DEBUG_VIRTUAL
+unsigned long __phys_addr(unsigned long x)
+{
+	/* VMALLOC_* aren't constants  */
+	VIRTUAL_BUG_ON(x < PAGE_OFFSET);
+	VIRTUAL_BUG_ON(__vmalloc_start_set && is_vmalloc_addr((void *) x));
+	return x - PAGE_OFFSET;
+}
+EXPORT_SYMBOL(__phys_addr);
+#endif
+
+bool __virt_addr_valid(unsigned long x)
+{
+	if (x < PAGE_OFFSET)
+		return false;
+	if (__vmalloc_start_set && is_vmalloc_addr((void *) x))
+		return false;
+	if (x >= FIXADDR_START)
+		return false;
+	return pfn_valid((x - PAGE_OFFSET) >> PAGE_SHIFT);
+}
+EXPORT_SYMBOL(__virt_addr_valid);
+
+#endif	/* CONFIG_X86_64 */
diff --git a/arch/x86/mm/physaddr.h b/arch/x86/mm/physaddr.h
new file mode 100644
index 0000000..a3cd5a0
--- /dev/null
+++ b/arch/x86/mm/physaddr.h
@@ -0,0 +1,10 @@
+#include <asm/processor.h>
+
+static inline int phys_addr_valid(resource_size_t addr)
+{
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+	return !(addr >> boot_cpu_data.x86_phys_bits);
+#else
+	return 1;
+#endif
+}
diff --git a/arch/x86/mm/srat_32.c b/arch/x86/mm/srat_32.c
index 29a0e37..6f8aa33 100644
--- a/arch/x86/mm/srat_32.c
+++ b/arch/x86/mm/srat_32.c
@@ -215,7 +215,7 @@ int __init get_memcfg_from_srat(void)
 		goto out_fail;
 
 	if (num_memory_chunks == 0) {
-		printk(KERN_WARNING
+		printk(KERN_DEBUG
 			 "could not find any ACPI SRAT memory areas.\n");
 		goto out_fail;
 	}
@@ -277,7 +277,7 @@ int __init get_memcfg_from_srat(void)
 	}
 	return 1;
 out_fail:
-	printk(KERN_ERR "failed to get NUMA memory information from SRAT"
+	printk(KERN_DEBUG "failed to get NUMA memory information from SRAT"
 			" table\n");
 	return 0;
 }
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
index 4899215..8eb0587 100644
--- a/arch/x86/oprofile/op_model_ppro.c
+++ b/arch/x86/oprofile/op_model_ppro.c
@@ -234,11 +234,11 @@ static void arch_perfmon_setup_counters(void)
 	if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 &&
 		current_cpu_data.x86_model == 15) {
 		eax.split.version_id = 2;
-		eax.split.num_counters = 2;
+		eax.split.num_events = 2;
 		eax.split.bit_width = 40;
 	}
 
-	num_counters = eax.split.num_counters;
+	num_counters = eax.split.num_events;
 
 	op_arch_perfmon_spec.num_counters = num_counters;
 	op_arch_perfmon_spec.num_controls = num_counters;
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
index b837761..7b8e75d 100644
--- a/arch/x86/oprofile/op_x86_model.h
+++ b/arch/x86/oprofile/op_x86_model.h
@@ -13,7 +13,7 @@
 #define OP_X86_MODEL_H
 
 #include <asm/types.h>
-#include <asm/perf_counter.h>
+#include <asm/perf_event.h>
 
 struct op_msr {
 	unsigned long	addr;
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 3ffa10d..572ee97 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -15,63 +15,6 @@
  * also get peer root bus resource for io,mmio
  */
 
-#ifdef CONFIG_NUMA
-
-#define BUS_NR 256
-
-#ifdef CONFIG_X86_64
-
-static int mp_bus_to_node[BUS_NR];
-
-void set_mp_bus_to_node(int busnum, int node)
-{
-	if (busnum >= 0 &&  busnum < BUS_NR)
-		mp_bus_to_node[busnum] = node;
-}
-
-int get_mp_bus_to_node(int busnum)
-{
-	int node = -1;
-
-	if (busnum < 0 || busnum > (BUS_NR - 1))
-		return node;
-
-	node = mp_bus_to_node[busnum];
-
-	/*
-	 * let numa_node_id to decide it later in dma_alloc_pages
-	 * if there is no ram on that node
-	 */
-	if (node != -1 && !node_online(node))
-		node = -1;
-
-	return node;
-}
-
-#else /* CONFIG_X86_32 */
-
-static unsigned char mp_bus_to_node[BUS_NR];
-
-void set_mp_bus_to_node(int busnum, int node)
-{
-	if (busnum >= 0 &&  busnum < BUS_NR)
-	mp_bus_to_node[busnum] = (unsigned char) node;
-}
-
-int get_mp_bus_to_node(int busnum)
-{
-	int node;
-
-	if (busnum < 0 || busnum > (BUS_NR - 1))
-		return 0;
-	node = mp_bus_to_node[busnum];
-	return node;
-}
-
-#endif /* CONFIG_X86_32 */
-
-#endif /* CONFIG_NUMA */
-
 #ifdef CONFIG_X86_64
 
 /*
@@ -301,11 +244,6 @@ static int __init early_fill_mp_bus_info(void)
 	u64 val;
 	u32 address;
 
-#ifdef CONFIG_NUMA
-	for (i = 0; i < BUS_NR; i++)
-		mp_bus_to_node[i] = -1;
-#endif
-
 	if (!early_pci_allowed())
 		return -1;
 
@@ -346,7 +284,7 @@ static int __init early_fill_mp_bus_info(void)
 		node = (reg >> 4) & 0x07;
 #ifdef CONFIG_NUMA
 		for (j = min_bus; j <= max_bus; j++)
-			mp_bus_to_node[j] = (unsigned char) node;
+			set_mp_bus_to_node(j, node);
 #endif
 		link = (reg >> 8) & 0x03;
 
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 2202b62..5db96d4 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -600,3 +600,72 @@ struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno)
 {
 	return pci_scan_bus_on_node(busno, &pci_root_ops, -1);
 }
+
+/*
+ * NUMA info for PCI busses
+ *
+ * Early arch code is responsible for filling in reasonable values here.
+ * A node id of "-1" means "use current node".  In other words, if a bus
+ * has a -1 node id, it's not tightly coupled to any particular chunk
+ * of memory (as is the case on some Nehalem systems).
+ */
+#ifdef CONFIG_NUMA
+
+#define BUS_NR 256
+
+#ifdef CONFIG_X86_64
+
+static int mp_bus_to_node[BUS_NR] = {
+	[0 ... BUS_NR - 1] = -1
+};
+
+void set_mp_bus_to_node(int busnum, int node)
+{
+	if (busnum >= 0 &&  busnum < BUS_NR)
+		mp_bus_to_node[busnum] = node;
+}
+
+int get_mp_bus_to_node(int busnum)
+{
+	int node = -1;
+
+	if (busnum < 0 || busnum > (BUS_NR - 1))
+		return node;
+
+	node = mp_bus_to_node[busnum];
+
+	/*
+	 * let numa_node_id to decide it later in dma_alloc_pages
+	 * if there is no ram on that node
+	 */
+	if (node != -1 && !node_online(node))
+		node = -1;
+
+	return node;
+}
+
+#else /* CONFIG_X86_32 */
+
+static unsigned char mp_bus_to_node[BUS_NR] = {
+	[0 ... BUS_NR - 1] = -1
+};
+
+void set_mp_bus_to_node(int busnum, int node)
+{
+	if (busnum >= 0 &&  busnum < BUS_NR)
+	mp_bus_to_node[busnum] = (unsigned char) node;
+}
+
+int get_mp_bus_to_node(int busnum)
+{
+	int node;
+
+	if (busnum < 0 || busnum > (BUS_NR - 1))
+		return 0;
+	node = mp_bus_to_node[busnum];
+	return node;
+}
+
+#endif /* CONFIG_X86_32 */
+
+#endif /* CONFIG_NUMA */
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index b3d20b9..8aa85f1 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -242,11 +242,7 @@ static void __restore_processor_state(struct saved_context *ctxt)
 	fix_processor_context();
 
 	do_fpu_end();
-	mtrr_ap_init();
-
-#ifdef CONFIG_X86_OLD_MCE
-	mcheck_init(&boot_cpu_data);
-#endif
+	mtrr_bp_restore();
 }
 
 /* Needed by apm.c */
diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_gettime.c
index 6a40b78..ee55754 100644
--- a/arch/x86/vdso/vclock_gettime.c
+++ b/arch/x86/vdso/vclock_gettime.c
@@ -86,14 +86,47 @@ notrace static noinline int do_monotonic(struct timespec *ts)
 	return 0;
 }
 
+notrace static noinline int do_realtime_coarse(struct timespec *ts)
+{
+	unsigned long seq;
+	do {
+		seq = read_seqbegin(&gtod->lock);
+		ts->tv_sec = gtod->wall_time_coarse.tv_sec;
+		ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;
+	} while (unlikely(read_seqretry(&gtod->lock, seq)));
+	return 0;
+}
+
+notrace static noinline int do_monotonic_coarse(struct timespec *ts)
+{
+	unsigned long seq, ns, secs;
+	do {
+		seq = read_seqbegin(&gtod->lock);
+		secs = gtod->wall_time_coarse.tv_sec;
+		ns = gtod->wall_time_coarse.tv_nsec;
+		secs += gtod->wall_to_monotonic.tv_sec;
+		ns += gtod->wall_to_monotonic.tv_nsec;
+	} while (unlikely(read_seqretry(&gtod->lock, seq)));
+	vset_normalized_timespec(ts, secs, ns);
+	return 0;
+}
+
 notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
 {
-	if (likely(gtod->sysctl_enabled && gtod->clock.vread))
+	if (likely(gtod->sysctl_enabled))
 		switch (clock) {
 		case CLOCK_REALTIME:
-			return do_realtime(ts);
+			if (likely(gtod->clock.vread))
+				return do_realtime(ts);
+			break;
 		case CLOCK_MONOTONIC:
-			return do_monotonic(ts);
+			if (likely(gtod->clock.vread))
+				return do_monotonic(ts);
+			break;
+		case CLOCK_REALTIME_COARSE:
+			return do_realtime_coarse(ts);
+		case CLOCK_MONOTONIC_COARSE:
+			return do_monotonic_coarse(ts);
 		}
 	return vdso_fallback_gettime(clock, ts);
 }
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
index 7410640..3bb4fc2 100644
--- a/arch/x86/xen/Makefile
+++ b/arch/x86/xen/Makefile
@@ -8,6 +8,7 @@ endif
 # Make sure early boot has no stackprotector
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_enlighten.o		:= $(nostackp)
+CFLAGS_mmu.o			:= $(nostackp)
 
 obj-y		:= enlighten.o setup.o multicalls.o mmu.o irq.o \
 			time.o xen-asm.o xen-asm_$(BITS).o \
@@ -16,3 +17,4 @@ obj-y		:= enlighten.o setup.o multicalls.o mmu.o irq.o \
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
 obj-$(CONFIG_XEN_DEBUG_FS)	+= debugfs.o
+
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index eb33aaa..544eb74 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -51,6 +51,7 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 #include <asm/reboot.h>
+#include <asm/stackprotector.h>
 
 #include "xen-ops.h"
 #include "mmu.h"
@@ -330,18 +331,28 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
 	unsigned long frames[pages];
 	int f;
 
-	/* A GDT can be up to 64k in size, which corresponds to 8192
-	   8-byte entries, or 16 4k pages.. */
+	/*
+	 * A GDT can be up to 64k in size, which corresponds to 8192
+	 * 8-byte entries, or 16 4k pages..
+	 */
 
 	BUG_ON(size > 65536);
 	BUG_ON(va & ~PAGE_MASK);
 
 	for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
 		int level;
-		pte_t *ptep = lookup_address(va, &level);
+		pte_t *ptep;
 		unsigned long pfn, mfn;
 		void *virt;
 
+		/*
+		 * The GDT is per-cpu and is in the percpu data area.
+		 * That can be virtually mapped, so we need to do a
+		 * page-walk to get the underlying MFN for the
+		 * hypercall.  The page can also be in the kernel's
+		 * linear range, so we need to RO that mapping too.
+		 */
+		ptep = lookup_address(va, &level);
 		BUG_ON(ptep == NULL);
 
 		pfn = pte_pfn(*ptep);
@@ -358,6 +369,44 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
 		BUG();
 }
 
+/*
+ * load_gdt for early boot, when the gdt is only mapped once
+ */
+static __init void xen_load_gdt_boot(const struct desc_ptr *dtr)
+{
+	unsigned long va = dtr->address;
+	unsigned int size = dtr->size + 1;
+	unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+	unsigned long frames[pages];
+	int f;
+
+	/*
+	 * A GDT can be up to 64k in size, which corresponds to 8192
+	 * 8-byte entries, or 16 4k pages..
+	 */
+
+	BUG_ON(size > 65536);
+	BUG_ON(va & ~PAGE_MASK);
+
+	for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
+		pte_t pte;
+		unsigned long pfn, mfn;
+
+		pfn = virt_to_pfn(va);
+		mfn = pfn_to_mfn(pfn);
+
+		pte = pfn_pte(pfn, PAGE_KERNEL_RO);
+
+		if (HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0))
+			BUG();
+
+		frames[f] = mfn;
+	}
+
+	if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct)))
+		BUG();
+}
+
 static void load_TLS_descriptor(struct thread_struct *t,
 				unsigned int cpu, unsigned int i)
 {
@@ -581,6 +630,29 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry,
 	preempt_enable();
 }
 
+/*
+ * Version of write_gdt_entry for use at early boot-time needed to
+ * update an entry as simply as possible.
+ */
+static __init void xen_write_gdt_entry_boot(struct desc_struct *dt, int entry,
+					    const void *desc, int type)
+{
+	switch (type) {
+	case DESC_LDT:
+	case DESC_TSS:
+		/* ignore */
+		break;
+
+	default: {
+		xmaddr_t maddr = virt_to_machine(&dt[entry]);
+
+		if (HYPERVISOR_update_descriptor(maddr.maddr, *(u64 *)desc))
+			dt[entry] = *(struct desc_struct *)desc;
+	}
+
+	}
+}
+
 static void xen_load_sp0(struct tss_struct *tss,
 			 struct thread_struct *thread)
 {
@@ -714,7 +786,7 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
 	set:
 		base = ((u64)high << 32) | low;
 		if (HYPERVISOR_set_segment_base(which, base) != 0)
-			ret = -EFAULT;
+			ret = -EIO;
 		break;
 #endif
 
@@ -840,19 +912,9 @@ static const struct pv_info xen_info __initdata = {
 
 static const struct pv_init_ops xen_init_ops __initdata = {
 	.patch = xen_patch,
-
-	.banner = xen_banner,
-	.memory_setup = xen_memory_setup,
-	.arch_setup = xen_arch_setup,
-	.post_allocator_init = xen_post_allocator_init,
 };
 
 static const struct pv_time_ops xen_time_ops __initdata = {
-	.time_init = xen_time_init,
-
-	.set_wallclock = xen_set_wallclock,
-	.get_wallclock = xen_get_wallclock,
-	.get_tsc_khz = xen_tsc_khz,
 	.sched_clock = xen_sched_clock,
 };
 
@@ -918,8 +980,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
 
 static const struct pv_apic_ops xen_apic_ops __initdata = {
 #ifdef CONFIG_X86_LOCAL_APIC
-	.setup_boot_clock = paravirt_nop,
-	.setup_secondary_clock = paravirt_nop,
 	.startup_ipi_hook = paravirt_nop,
 #endif
 };
@@ -965,6 +1025,23 @@ static const struct machine_ops __initdata xen_machine_ops = {
 	.emergency_restart = xen_emergency_restart,
 };
 
+/*
+ * Set up the GDT and segment registers for -fstack-protector.  Until
+ * we do this, we have to be careful not to call any stack-protected
+ * function, which is most of the kernel.
+ */
+static void __init xen_setup_stackprotector(void)
+{
+	pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry_boot;
+	pv_cpu_ops.load_gdt = xen_load_gdt_boot;
+
+	setup_stack_canary_segment(0);
+	switch_to_new_gdt(0);
+
+	pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry;
+	pv_cpu_ops.load_gdt = xen_load_gdt;
+}
+
 /* First C function to be called on Xen boot */
 asmlinkage void __init xen_start_kernel(void)
 {
@@ -981,16 +1058,43 @@ asmlinkage void __init xen_start_kernel(void)
 	pv_time_ops = xen_time_ops;
 	pv_cpu_ops = xen_cpu_ops;
 	pv_apic_ops = xen_apic_ops;
-	pv_mmu_ops = xen_mmu_ops;
 
-#ifdef CONFIG_X86_64
+	x86_init.resources.memory_setup = xen_memory_setup;
+	x86_init.oem.arch_setup = xen_arch_setup;
+	x86_init.oem.banner = xen_banner;
+
+	x86_init.timers.timer_init = xen_time_init;
+	x86_init.timers.setup_percpu_clockev = x86_init_noop;
+	x86_cpuinit.setup_percpu_clockev = x86_init_noop;
+
+	x86_platform.calibrate_tsc = xen_tsc_khz;
+	x86_platform.get_wallclock = xen_get_wallclock;
+	x86_platform.set_wallclock = xen_set_wallclock;
+
 	/*
-	 * Setup percpu state.  We only need to do this for 64-bit
-	 * because 32-bit already has %fs set properly.
+	 * Set up some pagetable state before starting to set any ptes.
 	 */
-	load_percpu_segment(0);
-#endif
 
+	/* Prevent unwanted bits from being set in PTEs. */
+	__supported_pte_mask &= ~_PAGE_GLOBAL;
+	if (!xen_initial_domain())
+		__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
+
+	__supported_pte_mask |= _PAGE_IOMAP;
+
+	xen_setup_features();
+
+	/* Get mfn list */
+	if (!xen_feature(XENFEAT_auto_translated_physmap))
+		xen_build_dynamic_phys_to_machine();
+
+	/*
+	 * Set up kernel GDT and segment registers, mainly so that
+	 * -fstack-protector code can be executed.
+	 */
+	xen_setup_stackprotector();
+
+	xen_init_mmu_ops();
 	xen_init_irq_ops();
 	xen_init_cpuid_mask();
 
@@ -1001,8 +1105,6 @@ asmlinkage void __init xen_start_kernel(void)
 	set_xen_basic_apic_ops();
 #endif
 
-	xen_setup_features();
-
 	if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
 		pv_mmu_ops.ptep_modify_prot_start = xen_ptep_modify_prot_start;
 		pv_mmu_ops.ptep_modify_prot_commit = xen_ptep_modify_prot_commit;
@@ -1019,17 +1121,8 @@ asmlinkage void __init xen_start_kernel(void)
 
 	xen_smp_init();
 
-	/* Get mfn list */
-	if (!xen_feature(XENFEAT_auto_translated_physmap))
-		xen_build_dynamic_phys_to_machine();
-
 	pgd = (pgd_t *)xen_start_info->pt_base;
 
-	/* Prevent unwanted bits from being set in PTEs. */
-	__supported_pte_mask &= ~_PAGE_GLOBAL;
-	if (!xen_initial_domain())
-		__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
-
 #ifdef CONFIG_X86_64
 	/* Work out if we support NX */
 	check_efer();
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index cfd1779..9d30105 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -1,5 +1,7 @@
 #include <linux/hardirq.h>
 
+#include <asm/x86_init.h>
+
 #include <xen/interface/xen.h>
 #include <xen/interface/sched.h>
 #include <xen/interface/vcpu.h>
@@ -112,8 +114,6 @@ static void xen_halt(void)
 }
 
 static const struct pv_irq_ops xen_irq_ops __initdata = {
-	.init_IRQ = xen_init_IRQ,
-
 	.save_fl = PV_CALLEE_SAVE(xen_save_fl),
 	.restore_fl = PV_CALLEE_SAVE(xen_restore_fl),
 	.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
@@ -129,4 +129,5 @@ static const struct pv_irq_ops xen_irq_ops __initdata = {
 void __init xen_init_irq_ops()
 {
 	pv_irq_ops = xen_irq_ops;
+	x86_init.irqs.intr_init = xen_init_IRQ;
 }
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 4ceb285..093dd59 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1229,9 +1229,12 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
 {
 }
 
+static void xen_post_allocator_init(void);
+
 static __init void xen_pagetable_setup_done(pgd_t *base)
 {
 	xen_setup_shared_info();
+	xen_post_allocator_init();
 }
 
 static void xen_write_cr2(unsigned long cr2)
@@ -1841,7 +1844,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
 #endif
 }
 
-__init void xen_post_allocator_init(void)
+static __init void xen_post_allocator_init(void)
 {
 	pv_mmu_ops.set_pte = xen_set_pte;
 	pv_mmu_ops.set_pmd = xen_set_pmd;
@@ -1875,10 +1878,7 @@ static void xen_leave_lazy_mmu(void)
 	preempt_enable();
 }
 
-const struct pv_mmu_ops xen_mmu_ops __initdata = {
-	.pagetable_setup_start = xen_pagetable_setup_start,
-	.pagetable_setup_done = xen_pagetable_setup_done,
-
+static const struct pv_mmu_ops xen_mmu_ops __initdata = {
 	.read_cr2 = xen_read_cr2,
 	.write_cr2 = xen_write_cr2,
 
@@ -1954,6 +1954,12 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = {
 	.set_fixmap = xen_set_fixmap,
 };
 
+void __init xen_init_mmu_ops(void)
+{
+	x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start;
+	x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
+	pv_mmu_ops = xen_mmu_ops;
+}
 
 #ifdef CONFIG_XEN_DEBUG_FS
 
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
index da73026..5fe6bc7 100644
--- a/arch/x86/xen/mmu.h
+++ b/arch/x86/xen/mmu.h
@@ -59,5 +59,5 @@ void  xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
 
 unsigned long xen_read_cr2_direct(void);
 
-extern const struct pv_mmu_ops xen_mmu_ops;
+extern void xen_init_mmu_ops(void);
 #endif	/* _XEN_MMU_H */
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 429834e..fe03eee 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -236,6 +236,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 	ctxt->user_regs.ss = __KERNEL_DS;
 #ifdef CONFIG_X86_32
 	ctxt->user_regs.fs = __KERNEL_PERCPU;
+	ctxt->user_regs.gs = __KERNEL_STACK_CANARY;
 #else
 	ctxt->gs_base_kernel = per_cpu_offset(cpu);
 #endif
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 5601506..36a5141 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -187,7 +187,6 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 	struct xen_spinlock *prev;
 	int irq = __get_cpu_var(lock_kicker_irq);
 	int ret;
-	unsigned long flags;
 	u64 start;
 
 	/* If kicker interrupts not initialized yet, just spin */
@@ -199,16 +198,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 	/* announce we're spinning */
 	prev = spinning_lock(xl);
 
-	flags = __raw_local_save_flags();
-	if (irq_enable) {
-		ADD_STATS(taken_slow_irqenable, 1);
-		raw_local_irq_enable();
-	}
-
 	ADD_STATS(taken_slow, 1);
 	ADD_STATS(taken_slow_nested, prev != NULL);
 
 	do {
+		unsigned long flags;
+
 		/* clear pending */
 		xen_clear_irq_pending(irq);
 
@@ -228,6 +223,12 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 			goto out;
 		}
 
+		flags = __raw_local_save_flags();
+		if (irq_enable) {
+			ADD_STATS(taken_slow_irqenable, 1);
+			raw_local_irq_enable();
+		}
+
 		/*
 		 * Block until irq becomes pending.  If we're
 		 * interrupted at this point (after the trylock but
@@ -238,13 +239,15 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
 		 * pending.
 		 */
 		xen_poll_irq(irq);
+
+		raw_local_irq_restore(flags);
+
 		ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq));
 	} while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */
 
 	kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
 
 out:
-	raw_local_irq_restore(flags);
 	unspinning_lock(xl, prev);
 	spin_time_accum_blocked(start);
 
@@ -323,8 +326,13 @@ static void xen_spin_unlock(struct raw_spinlock *lock)
 	smp_wmb();		/* make sure no writes get moved after unlock */
 	xl->lock = 0;		/* release lock */
 
-	/* make sure unlock happens before kick */
-	barrier();
+	/*
+	 * Make sure unlock happens before checking for waiting
+	 * spinners.  We need a strong barrier to enforce the
+	 * write-read ordering to different memory locations, as the
+	 * CPU makes no implied guarantees about their ordering.
+	 */
+	mb();
 
 	if (unlikely(xl->spinners))
 		xen_spin_unlock_slow(xl);
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 22494fd..355fa6b 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -30,8 +30,6 @@ pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
 void xen_ident_map_ISA(void);
 void xen_reserve_top(void);
 
-void xen_post_allocator_init(void);
-
 char * __init xen_memory_setup(void);
 void __init xen_arch_setup(void);
 void __init xen_init_IRQ(void);
diff --git a/arch/xtensa/include/asm/socket.h b/arch/xtensa/include/asm/socket.h
index dd1a7a4..beb3a6b 100644
--- a/arch/xtensa/include/asm/socket.h
+++ b/arch/xtensa/include/asm/socket.h
@@ -68,4 +68,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif	/* _XTENSA_SOCKET_H */
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 8848120..19085ff 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -59,9 +59,8 @@ static struct irqaction timer_irqaction = {
 
 void __init time_init(void)
 {
-	xtime.tv_nsec = 0;
-	xtime.tv_sec = read_persistent_clock();
-
+	/* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */
+	read_persistent_clock(&xtime);
 	set_normalized_timespec(&wall_to_monotonic,
 		-xtime.tv_sec, -xtime.tv_nsec);
 
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index 41c159c..921b6ff 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -280,15 +280,6 @@ SECTIONS
     *(.ResetVector.text)
   }
 
-  /* Sections to be discarded */
-  /DISCARD/ :
-  {
-	*(.exit.literal)
-	EXIT_TEXT
-	EXIT_DATA
-        *(.exitcall.exit)
-  }
-
   .xt.lit : { *(.xt.lit) }
   .xt.prop : { *(.xt.prop) }
 
@@ -321,4 +312,8 @@ SECTIONS
     *(.xt.lit)
     *(.gnu.linkonce.p*)
   }
+
+  /* Sections to be discarded */
+  DISCARDS
+  /DISCARD/ : { *(.exit.literal) }
 }
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
index edad415..2f0b86b 100644
--- a/arch/xtensa/platforms/iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -545,7 +545,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irqrestore(&lp->lock, flags);
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/block/Makefile b/block/Makefile
index 6c54ed0..ba74ca6 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -5,7 +5,7 @@
 obj-$(CONFIG_BLOCK) := elevator.o blk-core.o blk-tag.o blk-sysfs.o \
 			blk-barrier.o blk-settings.o blk-ioc.o blk-map.o \
 			blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
-			ioctl.o genhd.o scsi_ioctl.o
+			blk-iopoll.o ioctl.o genhd.o scsi_ioctl.o
 
 obj-$(CONFIG_BLK_DEV_BSG)	+= bsg.o
 obj-$(CONFIG_IOSCHED_NOOP)	+= noop-iosched.o
diff --git a/block/as-iosched.c b/block/as-iosched.c
index 7a12cf6..ce8ba57 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -146,7 +146,7 @@ enum arq_state {
 #define RQ_STATE(rq)	((enum arq_state)(rq)->elevator_private2)
 #define RQ_SET_STATE(rq, state)	((rq)->elevator_private2 = (void *) state)
 
-static DEFINE_PER_CPU(unsigned long, ioc_count);
+static DEFINE_PER_CPU(unsigned long, as_ioc_count);
 static struct completion *ioc_gone;
 static DEFINE_SPINLOCK(ioc_gone_lock);
 
@@ -161,7 +161,7 @@ static void as_antic_stop(struct as_data *ad);
 static void free_as_io_context(struct as_io_context *aic)
 {
 	kfree(aic);
-	elv_ioc_count_dec(ioc_count);
+	elv_ioc_count_dec(as_ioc_count);
 	if (ioc_gone) {
 		/*
 		 * AS scheduler is exiting, grab exit lock and check
@@ -169,7 +169,7 @@ static void free_as_io_context(struct as_io_context *aic)
 		 * complete ioc_gone and set it back to NULL.
 		 */
 		spin_lock(&ioc_gone_lock);
-		if (ioc_gone && !elv_ioc_count_read(ioc_count)) {
+		if (ioc_gone && !elv_ioc_count_read(as_ioc_count)) {
 			complete(ioc_gone);
 			ioc_gone = NULL;
 		}
@@ -211,7 +211,7 @@ static struct as_io_context *alloc_as_io_context(void)
 		ret->seek_total = 0;
 		ret->seek_samples = 0;
 		ret->seek_mean = 0;
-		elv_ioc_count_inc(ioc_count);
+		elv_ioc_count_inc(as_ioc_count);
 	}
 
 	return ret;
@@ -1507,7 +1507,7 @@ static void __exit as_exit(void)
 	ioc_gone = &all_gone;
 	/* ioc_gone's update must be visible before reading ioc_count */
 	smp_wmb();
-	if (elv_ioc_count_read(ioc_count))
+	if (elv_ioc_count_read(as_ioc_count))
 		wait_for_completion(&all_gone);
 	synchronize_rcu();
 }
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 30022b4..6593ab3 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -348,6 +348,9 @@ static void blkdev_discard_end_io(struct bio *bio, int err)
 		clear_bit(BIO_UPTODATE, &bio->bi_flags);
 	}
 
+	if (bio->bi_private)
+		complete(bio->bi_private);
+
 	bio_put(bio);
 }
 
@@ -357,21 +360,20 @@ static void blkdev_discard_end_io(struct bio *bio, int err)
  * @sector:	start sector
  * @nr_sects:	number of sectors to discard
  * @gfp_mask:	memory allocation flags (for bio_alloc)
+ * @flags:	DISCARD_FL_* flags to control behaviour
  *
  * Description:
- *    Issue a discard request for the sectors in question. Does not wait.
+ *    Issue a discard request for the sectors in question.
  */
-int blkdev_issue_discard(struct block_device *bdev,
-			 sector_t sector, sector_t nr_sects, gfp_t gfp_mask)
+int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
+		sector_t nr_sects, gfp_t gfp_mask, int flags)
 {
-	struct request_queue *q;
-	struct bio *bio;
+	DECLARE_COMPLETION_ONSTACK(wait);
+	struct request_queue *q = bdev_get_queue(bdev);
+	int type = flags & DISCARD_FL_BARRIER ?
+		DISCARD_BARRIER : DISCARD_NOBARRIER;
 	int ret = 0;
 
-	if (bdev->bd_disk == NULL)
-		return -ENXIO;
-
-	q = bdev_get_queue(bdev);
 	if (!q)
 		return -ENXIO;
 
@@ -379,12 +381,14 @@ int blkdev_issue_discard(struct block_device *bdev,
 		return -EOPNOTSUPP;
 
 	while (nr_sects && !ret) {
-		bio = bio_alloc(gfp_mask, 0);
+		struct bio *bio = bio_alloc(gfp_mask, 0);
 		if (!bio)
 			return -ENOMEM;
 
 		bio->bi_end_io = blkdev_discard_end_io;
 		bio->bi_bdev = bdev;
+		if (flags & DISCARD_FL_WAIT)
+			bio->bi_private = &wait;
 
 		bio->bi_sector = sector;
 
@@ -396,10 +400,13 @@ int blkdev_issue_discard(struct block_device *bdev,
 			bio->bi_size = nr_sects << 9;
 			nr_sects = 0;
 		}
+
 		bio_get(bio);
-		submit_bio(DISCARD_BARRIER, bio);
+		submit_bio(type, bio);
+
+		if (flags & DISCARD_FL_WAIT)
+			wait_for_completion(&wait);
 
-		/* Check if it failed immediately */
 		if (bio_flagged(bio, BIO_EOPNOTSUPP))
 			ret = -EOPNOTSUPP;
 		else if (!bio_flagged(bio, BIO_UPTODATE))
diff --git a/block/blk-core.c b/block/blk-core.c
index e695634..8135228 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -69,7 +69,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
 		part_stat_inc(cpu, part, merges[rw]);
 	else {
 		part_round_stats(cpu, part);
-		part_inc_in_flight(part);
+		part_inc_in_flight(part, rw);
 	}
 
 	part_stat_unlock();
@@ -1031,7 +1031,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
 
 	if (part->in_flight) {
 		__part_stat_add(cpu, part, time_in_queue,
-				part->in_flight * (now - part->stamp));
+				part_in_flight(part) * (now - part->stamp));
 		__part_stat_add(cpu, part, io_ticks, (now - part->stamp));
 	}
 	part->stamp = now;
@@ -1112,31 +1112,27 @@ void init_request_from_bio(struct request *req, struct bio *bio)
 	req->cmd_type = REQ_TYPE_FS;
 
 	/*
-	 * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
+	 * Inherit FAILFAST from bio (for read-ahead, and explicit
+	 * FAILFAST).  FAILFAST flags are identical for req and bio.
 	 */
-	if (bio_rw_ahead(bio))
-		req->cmd_flags |= (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
-				   REQ_FAILFAST_DRIVER);
-	if (bio_failfast_dev(bio))
-		req->cmd_flags |= REQ_FAILFAST_DEV;
-	if (bio_failfast_transport(bio))
-		req->cmd_flags |= REQ_FAILFAST_TRANSPORT;
-	if (bio_failfast_driver(bio))
-		req->cmd_flags |= REQ_FAILFAST_DRIVER;
-
-	if (unlikely(bio_discard(bio))) {
+	if (bio_rw_flagged(bio, BIO_RW_AHEAD))
+		req->cmd_flags |= REQ_FAILFAST_MASK;
+	else
+		req->cmd_flags |= bio->bi_rw & REQ_FAILFAST_MASK;
+
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_DISCARD))) {
 		req->cmd_flags |= REQ_DISCARD;
-		if (bio_barrier(bio))
+		if (bio_rw_flagged(bio, BIO_RW_BARRIER))
 			req->cmd_flags |= REQ_SOFTBARRIER;
 		req->q->prepare_discard_fn(req->q, req);
-	} else if (unlikely(bio_barrier(bio)))
+	} else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER)))
 		req->cmd_flags |= REQ_HARDBARRIER;
 
-	if (bio_sync(bio))
+	if (bio_rw_flagged(bio, BIO_RW_SYNCIO))
 		req->cmd_flags |= REQ_RW_SYNC;
-	if (bio_rw_meta(bio))
+	if (bio_rw_flagged(bio, BIO_RW_META))
 		req->cmd_flags |= REQ_RW_META;
-	if (bio_noidle(bio))
+	if (bio_rw_flagged(bio, BIO_RW_NOIDLE))
 		req->cmd_flags |= REQ_NOIDLE;
 
 	req->errors = 0;
@@ -1151,7 +1147,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
  */
 static inline bool queue_should_plug(struct request_queue *q)
 {
-	return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
+	return !(blk_queue_nonrot(q) && blk_queue_queuing(q));
 }
 
 static int __make_request(struct request_queue *q, struct bio *bio)
@@ -1160,11 +1156,12 @@ static int __make_request(struct request_queue *q, struct bio *bio)
 	int el_ret;
 	unsigned int bytes = bio->bi_size;
 	const unsigned short prio = bio_prio(bio);
-	const int sync = bio_sync(bio);
-	const int unplug = bio_unplug(bio);
+	const bool sync = bio_rw_flagged(bio, BIO_RW_SYNCIO);
+	const bool unplug = bio_rw_flagged(bio, BIO_RW_UNPLUG);
+	const unsigned int ff = bio->bi_rw & REQ_FAILFAST_MASK;
 	int rw_flags;
 
-	if (bio_barrier(bio) && bio_has_data(bio) &&
+	if (bio_rw_flagged(bio, BIO_RW_BARRIER) && bio_has_data(bio) &&
 	    (q->next_ordered == QUEUE_ORDERED_NONE)) {
 		bio_endio(bio, -EOPNOTSUPP);
 		return 0;
@@ -1178,7 +1175,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
 
 	spin_lock_irq(q->queue_lock);
 
-	if (unlikely(bio_barrier(bio)) || elv_queue_empty(q))
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER)) || elv_queue_empty(q))
 		goto get_rq;
 
 	el_ret = elv_merge(q, &req, bio);
@@ -1191,6 +1188,9 @@ static int __make_request(struct request_queue *q, struct bio *bio)
 
 		trace_block_bio_backmerge(q, bio);
 
+		if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
+			blk_rq_set_mixed_merge(req);
+
 		req->biotail->bi_next = bio;
 		req->biotail = bio;
 		req->__data_len += bytes;
@@ -1210,6 +1210,12 @@ static int __make_request(struct request_queue *q, struct bio *bio)
 
 		trace_block_bio_frontmerge(q, bio);
 
+		if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff) {
+			blk_rq_set_mixed_merge(req);
+			req->cmd_flags &= ~REQ_FAILFAST_MASK;
+			req->cmd_flags |= ff;
+		}
+
 		bio->bi_next = req->bio;
 		req->bio = bio;
 
@@ -1457,19 +1463,20 @@ static inline void __generic_make_request(struct bio *bio)
 		if (old_sector != -1)
 			trace_block_remap(q, bio, old_dev, old_sector);
 
-		trace_block_bio_queue(q, bio);
-
 		old_sector = bio->bi_sector;
 		old_dev = bio->bi_bdev->bd_dev;
 
 		if (bio_check_eod(bio, nr_sectors))
 			goto end_io;
 
-		if (bio_discard(bio) && !q->prepare_discard_fn) {
+		if (bio_rw_flagged(bio, BIO_RW_DISCARD) &&
+		    !q->prepare_discard_fn) {
 			err = -EOPNOTSUPP;
 			goto end_io;
 		}
 
+		trace_block_bio_queue(q, bio);
+
 		ret = q->make_request_fn(q, bio);
 	} while (ret);
 
@@ -1654,6 +1661,50 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
 }
 EXPORT_SYMBOL_GPL(blk_insert_cloned_request);
 
+/**
+ * blk_rq_err_bytes - determine number of bytes till the next failure boundary
+ * @rq: request to examine
+ *
+ * Description:
+ *     A request could be merge of IOs which require different failure
+ *     handling.  This function determines the number of bytes which
+ *     can be failed from the beginning of the request without
+ *     crossing into area which need to be retried further.
+ *
+ * Return:
+ *     The number of bytes to fail.
+ *
+ * Context:
+ *     queue_lock must be held.
+ */
+unsigned int blk_rq_err_bytes(const struct request *rq)
+{
+	unsigned int ff = rq->cmd_flags & REQ_FAILFAST_MASK;
+	unsigned int bytes = 0;
+	struct bio *bio;
+
+	if (!(rq->cmd_flags & REQ_MIXED_MERGE))
+		return blk_rq_bytes(rq);
+
+	/*
+	 * Currently the only 'mixing' which can happen is between
+	 * different fastfail types.  We can safely fail portions
+	 * which have all the failfast bits that the first one has -
+	 * the ones which are at least as eager to fail as the first
+	 * one.
+	 */
+	for (bio = rq->bio; bio; bio = bio->bi_next) {
+		if ((bio->bi_rw & ff) != ff)
+			break;
+		bytes += bio->bi_size;
+	}
+
+	/* this could lead to infinite loop */
+	BUG_ON(blk_rq_bytes(rq) && !bytes);
+	return bytes;
+}
+EXPORT_SYMBOL_GPL(blk_rq_err_bytes);
+
 static void blk_account_io_completion(struct request *req, unsigned int bytes)
 {
 	if (blk_do_io_stat(req)) {
@@ -1687,7 +1738,7 @@ static void blk_account_io_done(struct request *req)
 		part_stat_inc(cpu, part, ios[rw]);
 		part_stat_add(cpu, part, ticks[rw], duration);
 		part_round_stats(cpu, part);
-		part_dec_in_flight(part);
+		part_dec_in_flight(part, rw);
 
 		part_stat_unlock();
 	}
@@ -1807,8 +1858,15 @@ void blk_dequeue_request(struct request *rq)
 	 * and to it is freed is accounted as io that is in progress at
 	 * the driver side.
 	 */
-	if (blk_account_rq(rq))
+	if (blk_account_rq(rq)) {
 		q->in_flight[rq_is_sync(rq)]++;
+		/*
+		 * Mark this device as supporting hardware queuing, if
+		 * we have more IOs in flight than 4.
+		 */
+		if (!blk_queue_queuing(q) && queue_in_flight(q) > 4)
+			set_bit(QUEUE_FLAG_CQ, &q->queue_flags);
+	}
 }
 
 /**
@@ -2000,6 +2058,12 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes)
 	if (blk_fs_request(req) || blk_discard_rq(req))
 		req->__sector += total_bytes >> 9;
 
+	/* mixed attributes always follow the first bio */
+	if (req->cmd_flags & REQ_MIXED_MERGE) {
+		req->cmd_flags &= ~REQ_FAILFAST_MASK;
+		req->cmd_flags |= req->bio->bi_rw & REQ_FAILFAST_MASK;
+	}
+
 	/*
 	 * If total number of sectors is less than the first segment
 	 * size, something has gone terribly wrong.
@@ -2179,6 +2243,25 @@ bool blk_end_request_cur(struct request *rq, int error)
 EXPORT_SYMBOL(blk_end_request_cur);
 
 /**
+ * blk_end_request_err - Finish a request till the next failure boundary.
+ * @rq: the request to finish till the next failure boundary for
+ * @error: must be negative errno
+ *
+ * Description:
+ *     Complete @rq till the next failure boundary.
+ *
+ * Return:
+ *     %false - we are done with this request
+ *     %true  - still buffers pending for this request
+ */
+bool blk_end_request_err(struct request *rq, int error)
+{
+	WARN_ON(error >= 0);
+	return blk_end_request(rq, error, blk_rq_err_bytes(rq));
+}
+EXPORT_SYMBOL_GPL(blk_end_request_err);
+
+/**
  * __blk_end_request - Helper function for drivers to complete the request.
  * @rq:       the request being processed
  * @error:    %0 for success, < %0 for error
@@ -2237,12 +2320,31 @@ bool __blk_end_request_cur(struct request *rq, int error)
 }
 EXPORT_SYMBOL(__blk_end_request_cur);
 
+/**
+ * __blk_end_request_err - Finish a request till the next failure boundary.
+ * @rq: the request to finish till the next failure boundary for
+ * @error: must be negative errno
+ *
+ * Description:
+ *     Complete @rq till the next failure boundary.  Must be called
+ *     with queue lock held.
+ *
+ * Return:
+ *     %false - we are done with this request
+ *     %true  - still buffers pending for this request
+ */
+bool __blk_end_request_err(struct request *rq, int error)
+{
+	WARN_ON(error >= 0);
+	return __blk_end_request(rq, error, blk_rq_err_bytes(rq));
+}
+EXPORT_SYMBOL_GPL(__blk_end_request_err);
+
 void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 		     struct bio *bio)
 {
-	/* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw, and
-	   we want BIO_RW_AHEAD (bit 1) to imply REQ_FAILFAST (bit 1). */
-	rq->cmd_flags |= (bio->bi_rw & 3);
+	/* Bit 0 (R/W) is identical in rq->cmd_flags and bio->bi_rw */
+	rq->cmd_flags |= bio->bi_rw & REQ_RW;
 
 	if (bio_has_data(bio)) {
 		rq->nr_phys_segments = bio_phys_segments(q, bio);
diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c
new file mode 100644
index 0000000..ca56420
--- /dev/null
+++ b/block/blk-iopoll.c
@@ -0,0 +1,227 @@
+/*
+ * Functions related to interrupt-poll handling in the block layer. This
+ * is similar to NAPI for network devices.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+#include <linux/interrupt.h>
+#include <linux/cpu.h>
+#include <linux/blk-iopoll.h>
+#include <linux/delay.h>
+
+#include "blk.h"
+
+int blk_iopoll_enabled = 1;
+EXPORT_SYMBOL(blk_iopoll_enabled);
+
+static unsigned int blk_iopoll_budget __read_mostly = 256;
+
+static DEFINE_PER_CPU(struct list_head, blk_cpu_iopoll);
+
+/**
+ * blk_iopoll_sched - Schedule a run of the iopoll handler
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     Add this blk_iopoll structure to the pending poll list and trigger the
+ *     raise of the blk iopoll softirq. The driver must already have gotten a
+ *     succesful return from blk_iopoll_sched_prep() before calling this.
+ **/
+void blk_iopoll_sched(struct blk_iopoll *iop)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	list_add_tail(&iop->list, &__get_cpu_var(blk_cpu_iopoll));
+	__raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(blk_iopoll_sched);
+
+/**
+ * __blk_iopoll_complete - Mark this @iop as un-polled again
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     See blk_iopoll_complete(). This function must be called with interrupts
+ *     disabled.
+ **/
+void __blk_iopoll_complete(struct blk_iopoll *iop)
+{
+	list_del(&iop->list);
+	smp_mb__before_clear_bit();
+	clear_bit_unlock(IOPOLL_F_SCHED, &iop->state);
+}
+EXPORT_SYMBOL(__blk_iopoll_complete);
+
+/**
+ * blk_iopoll_complete - Mark this @iop as un-polled again
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     If a driver consumes less than the assigned budget in its run of the
+ *     iopoll handler, it'll end the polled mode by calling this function. The
+ *     iopoll handler will not be invoked again before blk_iopoll_sched_prep()
+ *     is called.
+ **/
+void blk_iopoll_complete(struct blk_iopoll *iopoll)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	__blk_iopoll_complete(iopoll);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(blk_iopoll_complete);
+
+static void blk_iopoll_softirq(struct softirq_action *h)
+{
+	struct list_head *list = &__get_cpu_var(blk_cpu_iopoll);
+	int rearm = 0, budget = blk_iopoll_budget;
+	unsigned long start_time = jiffies;
+
+	local_irq_disable();
+
+	while (!list_empty(list)) {
+		struct blk_iopoll *iop;
+		int work, weight;
+
+		/*
+		 * If softirq window is exhausted then punt.
+		 */
+		if (budget <= 0 || time_after(jiffies, start_time)) {
+			rearm = 1;
+			break;
+		}
+
+		local_irq_enable();
+
+		/* Even though interrupts have been re-enabled, this
+		 * access is safe because interrupts can only add new
+		 * entries to the tail of this list, and only ->poll()
+		 * calls can remove this head entry from the list.
+		 */
+		iop = list_entry(list->next, struct blk_iopoll, list);
+
+		weight = iop->weight;
+		work = 0;
+		if (test_bit(IOPOLL_F_SCHED, &iop->state))
+			work = iop->poll(iop, weight);
+
+		budget -= work;
+
+		local_irq_disable();
+
+		/*
+		 * Drivers must not modify the iopoll state, if they
+		 * consume their assigned weight (or more, some drivers can't
+		 * easily just stop processing, they have to complete an
+		 * entire mask of commands).In such cases this code
+		 * still "owns" the iopoll instance and therefore can
+		 * move the instance around on the list at-will.
+		 */
+		if (work >= weight) {
+			if (blk_iopoll_disable_pending(iop))
+				__blk_iopoll_complete(iop);
+			else
+				list_move_tail(&iop->list, list);
+		}
+	}
+
+	if (rearm)
+		__raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ);
+
+	local_irq_enable();
+}
+
+/**
+ * blk_iopoll_disable - Disable iopoll on this @iop
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     Disable io polling and wait for any pending callbacks to have completed.
+ **/
+void blk_iopoll_disable(struct blk_iopoll *iop)
+{
+	set_bit(IOPOLL_F_DISABLE, &iop->state);
+	while (test_and_set_bit(IOPOLL_F_SCHED, &iop->state))
+		msleep(1);
+	clear_bit(IOPOLL_F_DISABLE, &iop->state);
+}
+EXPORT_SYMBOL(blk_iopoll_disable);
+
+/**
+ * blk_iopoll_enable - Enable iopoll on this @iop
+ * @iop:      The parent iopoll structure
+ *
+ * Description:
+ *     Enable iopoll on this @iop. Note that the handler run will not be
+ *     scheduled, it will only mark it as active.
+ **/
+void blk_iopoll_enable(struct blk_iopoll *iop)
+{
+	BUG_ON(!test_bit(IOPOLL_F_SCHED, &iop->state));
+	smp_mb__before_clear_bit();
+	clear_bit_unlock(IOPOLL_F_SCHED, &iop->state);
+}
+EXPORT_SYMBOL(blk_iopoll_enable);
+
+/**
+ * blk_iopoll_init - Initialize this @iop
+ * @iop:      The parent iopoll structure
+ * @weight:   The default weight (or command completion budget)
+ * @poll_fn:  The handler to invoke
+ *
+ * Description:
+ *     Initialize this blk_iopoll structure. Before being actively used, the
+ *     driver must call blk_iopoll_enable().
+ **/
+void blk_iopoll_init(struct blk_iopoll *iop, int weight, blk_iopoll_fn *poll_fn)
+{
+	memset(iop, 0, sizeof(*iop));
+	INIT_LIST_HEAD(&iop->list);
+	iop->weight = weight;
+	iop->poll = poll_fn;
+	set_bit(IOPOLL_F_SCHED, &iop->state);
+}
+EXPORT_SYMBOL(blk_iopoll_init);
+
+static int __cpuinit blk_iopoll_cpu_notify(struct notifier_block *self,
+					  unsigned long action, void *hcpu)
+{
+	/*
+	 * If a CPU goes away, splice its entries to the current CPU
+	 * and trigger a run of the softirq
+	 */
+	if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
+		int cpu = (unsigned long) hcpu;
+
+		local_irq_disable();
+		list_splice_init(&per_cpu(blk_cpu_iopoll, cpu),
+				 &__get_cpu_var(blk_cpu_iopoll));
+		__raise_softirq_irqoff(BLOCK_IOPOLL_SOFTIRQ);
+		local_irq_enable();
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata blk_iopoll_cpu_notifier = {
+	.notifier_call	= blk_iopoll_cpu_notify,
+};
+
+static __init int blk_iopoll_setup(void)
+{
+	int i;
+
+	for_each_possible_cpu(i)
+		INIT_LIST_HEAD(&per_cpu(blk_cpu_iopoll, i));
+
+	open_softirq(BLOCK_IOPOLL_SOFTIRQ, blk_iopoll_softirq);
+	register_hotcpu_notifier(&blk_iopoll_cpu_notifier);
+	return 0;
+}
+subsys_initcall(blk_iopoll_setup);
diff --git a/block/blk-merge.c b/block/blk-merge.c
index e199967..99cb5cf 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -311,6 +311,36 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
 	return 1;
 }
 
+/**
+ * blk_rq_set_mixed_merge - mark a request as mixed merge
+ * @rq: request to mark as mixed merge
+ *
+ * Description:
+ *     @rq is about to be mixed merged.  Make sure the attributes
+ *     which can be mixed are set in each bio and mark @rq as mixed
+ *     merged.
+ */
+void blk_rq_set_mixed_merge(struct request *rq)
+{
+	unsigned int ff = rq->cmd_flags & REQ_FAILFAST_MASK;
+	struct bio *bio;
+
+	if (rq->cmd_flags & REQ_MIXED_MERGE)
+		return;
+
+	/*
+	 * @rq will no longer represent mixable attributes for all the
+	 * contained bios.  It will just track those of the first one.
+	 * Distributes the attributs to each bio.
+	 */
+	for (bio = rq->bio; bio; bio = bio->bi_next) {
+		WARN_ON_ONCE((bio->bi_rw & REQ_FAILFAST_MASK) &&
+			     (bio->bi_rw & REQ_FAILFAST_MASK) != ff);
+		bio->bi_rw |= ff;
+	}
+	rq->cmd_flags |= REQ_MIXED_MERGE;
+}
+
 static void blk_account_io_merge(struct request *req)
 {
 	if (blk_do_io_stat(req)) {
@@ -321,7 +351,7 @@ static void blk_account_io_merge(struct request *req)
 		part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
 
 		part_round_stats(cpu, part);
-		part_dec_in_flight(part);
+		part_dec_in_flight(part, rq_data_dir(req));
 
 		part_stat_unlock();
 	}
@@ -350,12 +380,6 @@ static int attempt_merge(struct request_queue *q, struct request *req,
 	if (blk_integrity_rq(req) != blk_integrity_rq(next))
 		return 0;
 
-	/* don't merge requests of different failfast settings */
-	if (blk_failfast_dev(req)	!= blk_failfast_dev(next)	||
-	    blk_failfast_transport(req)	!= blk_failfast_transport(next)	||
-	    blk_failfast_driver(req)	!= blk_failfast_driver(next))
-		return 0;
-
 	/*
 	 * If we are allowed to merge, then append bio list
 	 * from next to rq and release next. merge_requests_fn
@@ -366,6 +390,19 @@ static int attempt_merge(struct request_queue *q, struct request *req,
 		return 0;
 
 	/*
+	 * If failfast settings disagree or any of the two is already
+	 * a mixed merge, mark both as mixed before proceeding.  This
+	 * makes sure that all involved bios have mixable attributes
+	 * set properly.
+	 */
+	if ((req->cmd_flags | next->cmd_flags) & REQ_MIXED_MERGE ||
+	    (req->cmd_flags & REQ_FAILFAST_MASK) !=
+	    (next->cmd_flags & REQ_FAILFAST_MASK)) {
+		blk_rq_set_mixed_merge(req);
+		blk_rq_set_mixed_merge(next);
+	}
+
+	/*
 	 * At this point we have either done a back merge
 	 * or front merge. We need the smaller start_time of
 	 * the merged requests to be the current request
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 476d870..83413ff 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -428,6 +428,25 @@ void blk_queue_io_min(struct request_queue *q, unsigned int min)
 EXPORT_SYMBOL(blk_queue_io_min);
 
 /**
+ * blk_limits_io_opt - set optimal request size for a device
+ * @limits: the queue limits
+ * @opt:  smallest I/O size in bytes
+ *
+ * Description:
+ *   Storage devices may report an optimal I/O size, which is the
+ *   device's preferred unit for sustained I/O.  This is rarely reported
+ *   for disk drives.  For RAID arrays it is usually the stripe width or
+ *   the internal track size.  A properly aligned multiple of
+ *   optimal_io_size is the preferred request size for workloads where
+ *   sustained throughput is desired.
+ */
+void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt)
+{
+	limits->io_opt = opt;
+}
+EXPORT_SYMBOL(blk_limits_io_opt);
+
+/**
  * blk_queue_io_opt - set optimal request size for the queue
  * @q:	the request queue for the device
  * @opt:  optimal request size in bytes
@@ -442,7 +461,7 @@ EXPORT_SYMBOL(blk_queue_io_min);
  */
 void blk_queue_io_opt(struct request_queue *q, unsigned int opt)
 {
-	q->limits.io_opt = opt;
+	blk_limits_io_opt(&q->limits, opt);
 }
 EXPORT_SYMBOL(blk_queue_io_opt);
 
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index d3aa2aa..b78c9c3 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -40,7 +40,12 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count)
 {
 	struct request_list *rl = &q->rq;
 	unsigned long nr;
-	int ret = queue_var_store(&nr, page, count);
+	int ret;
+
+	if (!q->request_fn)
+		return -EINVAL;
+
+	ret = queue_var_store(&nr, page, count);
 	if (nr < BLKDEV_MIN_RQ)
 		nr = BLKDEV_MIN_RQ;
 
diff --git a/block/blk.h b/block/blk.h
index 3fae6ad..5ee3d7e 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -104,6 +104,7 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req,
 int attempt_back_merge(struct request_queue *q, struct request *rq);
 int attempt_front_merge(struct request_queue *q, struct request *rq);
 void blk_recalc_rq_segments(struct request *rq);
+void blk_rq_set_mixed_merge(struct request *rq);
 
 void blk_queue_congestion_threshold(struct request_queue *q);
 
diff --git a/block/bsg.c b/block/bsg.c
index 5f184bb..0676301 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -1062,7 +1062,7 @@ EXPORT_SYMBOL_GPL(bsg_register_queue);
 
 static struct cdev bsg_cdev;
 
-static char *bsg_nodename(struct device *dev)
+static char *bsg_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "bsg/%s", dev_name(dev));
 }
@@ -1087,7 +1087,7 @@ static int __init bsg_init(void)
 		ret = PTR_ERR(bsg_class);
 		goto destroy_kmemcache;
 	}
-	bsg_class->nodename = bsg_nodename;
+	bsg_class->devnode = bsg_devnode;
 
 	ret = alloc_chrdev_region(&devid, 0, BSG_MAX_DEVS, "bsg");
 	if (ret)
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index fd7080e..1ca813b 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -48,7 +48,7 @@ static int cfq_slice_idle = HZ / 125;
 static struct kmem_cache *cfq_pool;
 static struct kmem_cache *cfq_ioc_pool;
 
-static DEFINE_PER_CPU(unsigned long, ioc_count);
+static DEFINE_PER_CPU(unsigned long, cfq_ioc_count);
 static struct completion *ioc_gone;
 static DEFINE_SPINLOCK(ioc_gone_lock);
 
@@ -134,13 +134,8 @@ struct cfq_data {
 	struct rb_root prio_trees[CFQ_PRIO_LISTS];
 
 	unsigned int busy_queues;
-	/*
-	 * Used to track any pending rt requests so we can pre-empt current
-	 * non-RT cfqq in service when this value is non-zero.
-	 */
-	unsigned int busy_rt_queues;
 
-	int rq_in_driver;
+	int rq_in_driver[2];
 	int sync_flight;
 
 	/*
@@ -191,7 +186,6 @@ enum cfqq_state_flags {
 	CFQ_CFQQ_FLAG_on_rr = 0,	/* on round-robin busy list */
 	CFQ_CFQQ_FLAG_wait_request,	/* waiting for a request */
 	CFQ_CFQQ_FLAG_must_dispatch,	/* must be allowed a dispatch */
-	CFQ_CFQQ_FLAG_must_alloc,	/* must be allowed rq alloc */
 	CFQ_CFQQ_FLAG_must_alloc_slice,	/* per-slice must_alloc flag */
 	CFQ_CFQQ_FLAG_fifo_expire,	/* FIFO checked in this slice */
 	CFQ_CFQQ_FLAG_idle_window,	/* slice idling enabled */
@@ -218,7 +212,6 @@ static inline int cfq_cfqq_##name(const struct cfq_queue *cfqq)		\
 CFQ_CFQQ_FNS(on_rr);
 CFQ_CFQQ_FNS(wait_request);
 CFQ_CFQQ_FNS(must_dispatch);
-CFQ_CFQQ_FNS(must_alloc);
 CFQ_CFQQ_FNS(must_alloc_slice);
 CFQ_CFQQ_FNS(fifo_expire);
 CFQ_CFQQ_FNS(idle_window);
@@ -239,6 +232,11 @@ static struct cfq_queue *cfq_get_queue(struct cfq_data *, int,
 static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *,
 						struct io_context *);
 
+static inline int rq_in_driver(struct cfq_data *cfqd)
+{
+	return cfqd->rq_in_driver[0] + cfqd->rq_in_driver[1];
+}
+
 static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic,
 					    int is_sync)
 {
@@ -257,7 +255,7 @@ static inline void cic_set_cfqq(struct cfq_io_context *cic,
  */
 static inline int cfq_bio_sync(struct bio *bio)
 {
-	if (bio_data_dir(bio) == READ || bio_sync(bio))
+	if (bio_data_dir(bio) == READ || bio_rw_flagged(bio, BIO_RW_SYNCIO))
 		return 1;
 
 	return 0;
@@ -648,8 +646,6 @@ static void cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 	BUG_ON(cfq_cfqq_on_rr(cfqq));
 	cfq_mark_cfqq_on_rr(cfqq);
 	cfqd->busy_queues++;
-	if (cfq_class_rt(cfqq))
-		cfqd->busy_rt_queues++;
 
 	cfq_resort_rr_list(cfqd, cfqq);
 }
@@ -673,8 +669,6 @@ static void cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 
 	BUG_ON(!cfqd->busy_queues);
 	cfqd->busy_queues--;
-	if (cfq_class_rt(cfqq))
-		cfqd->busy_rt_queues--;
 }
 
 /*
@@ -760,9 +754,9 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
 
-	cfqd->rq_in_driver++;
+	cfqd->rq_in_driver[rq_is_sync(rq)]++;
 	cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "activate rq, drv=%d",
-						cfqd->rq_in_driver);
+						rq_in_driver(cfqd));
 
 	cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
 }
@@ -770,11 +764,12 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq)
 static void cfq_deactivate_request(struct request_queue *q, struct request *rq)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
+	const int sync = rq_is_sync(rq);
 
-	WARN_ON(!cfqd->rq_in_driver);
-	cfqd->rq_in_driver--;
+	WARN_ON(!cfqd->rq_in_driver[sync]);
+	cfqd->rq_in_driver[sync]--;
 	cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d",
-						cfqd->rq_in_driver);
+						rq_in_driver(cfqd));
 }
 
 static void cfq_remove_request(struct request *rq)
@@ -1080,7 +1075,7 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
 	/*
 	 * still requests with the driver, don't idle
 	 */
-	if (cfqd->rq_in_driver)
+	if (rq_in_driver(cfqd))
 		return;
 
 	/*
@@ -1115,6 +1110,7 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq)
 
 	cfq_log_cfqq(cfqd, cfqq, "dispatch_insert");
 
+	cfqq->next_rq = cfq_find_next_rq(cfqd, cfqq, rq);
 	cfq_remove_request(rq);
 	cfqq->dispatched++;
 	elv_dispatch_sort(q, rq);
@@ -1179,20 +1175,6 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
 		goto expire;
 
 	/*
-	 * If we have a RT cfqq waiting, then we pre-empt the current non-rt
-	 * cfqq.
-	 */
-	if (!cfq_class_rt(cfqq) && cfqd->busy_rt_queues) {
-		/*
-		 * We simulate this as cfqq timed out so that it gets to bank
-		 * the remaining of its time slice.
-		 */
-		cfq_log_cfqq(cfqd, cfqq, "preempt");
-		cfq_slice_expired(cfqd, 1);
-		goto new_queue;
-	}
-
-	/*
 	 * The active queue has requests and isn't expired, allow it to
 	 * dispatch.
 	 */
@@ -1312,6 +1294,12 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
 		return 0;
 
 	/*
+	 * Drain async requests before we start sync IO
+	 */
+	if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
+		return 0;
+
+	/*
 	 * If this is an async queue and we have sync IO in flight, let it wait
 	 */
 	if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
@@ -1362,7 +1350,7 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
 		cfq_slice_expired(cfqd, 0);
 	}
 
-	cfq_log(cfqd, "dispatched a request");
+	cfq_log_cfqq(cfqd, cfqq, "dispatched a request");
 	return 1;
 }
 
@@ -1427,7 +1415,7 @@ static void cfq_cic_free_rcu(struct rcu_head *head)
 	cic = container_of(head, struct cfq_io_context, rcu_head);
 
 	kmem_cache_free(cfq_ioc_pool, cic);
-	elv_ioc_count_dec(ioc_count);
+	elv_ioc_count_dec(cfq_ioc_count);
 
 	if (ioc_gone) {
 		/*
@@ -1436,7 +1424,7 @@ static void cfq_cic_free_rcu(struct rcu_head *head)
 		 * complete ioc_gone and set it back to NULL
 		 */
 		spin_lock(&ioc_gone_lock);
-		if (ioc_gone && !elv_ioc_count_read(ioc_count)) {
+		if (ioc_gone && !elv_ioc_count_read(cfq_ioc_count)) {
 			complete(ioc_gone);
 			ioc_gone = NULL;
 		}
@@ -1562,7 +1550,7 @@ cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
 		INIT_HLIST_NODE(&cic->cic_list);
 		cic->dtor = cfq_free_io_context;
 		cic->exit = cfq_exit_io_context;
-		elv_ioc_count_inc(ioc_count);
+		elv_ioc_count_inc(cfq_ioc_count);
 	}
 
 	return cic;
@@ -2130,11 +2118,11 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
  */
 static void cfq_update_hw_tag(struct cfq_data *cfqd)
 {
-	if (cfqd->rq_in_driver > cfqd->rq_in_driver_peak)
-		cfqd->rq_in_driver_peak = cfqd->rq_in_driver;
+	if (rq_in_driver(cfqd) > cfqd->rq_in_driver_peak)
+		cfqd->rq_in_driver_peak = rq_in_driver(cfqd);
 
 	if (cfqd->rq_queued <= CFQ_HW_QUEUE_MIN &&
-	    cfqd->rq_in_driver <= CFQ_HW_QUEUE_MIN)
+	    rq_in_driver(cfqd) <= CFQ_HW_QUEUE_MIN)
 		return;
 
 	if (cfqd->hw_tag_samples++ < 50)
@@ -2161,9 +2149,9 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
 
 	cfq_update_hw_tag(cfqd);
 
-	WARN_ON(!cfqd->rq_in_driver);
+	WARN_ON(!cfqd->rq_in_driver[sync]);
 	WARN_ON(!cfqq->dispatched);
-	cfqd->rq_in_driver--;
+	cfqd->rq_in_driver[sync]--;
 	cfqq->dispatched--;
 
 	if (cfq_cfqq_sync(cfqq))
@@ -2197,7 +2185,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
 			cfq_arm_slice_timer(cfqd);
 	}
 
-	if (!cfqd->rq_in_driver)
+	if (!rq_in_driver(cfqd))
 		cfq_schedule_dispatch(cfqd);
 }
 
@@ -2229,8 +2217,7 @@ static void cfq_prio_boost(struct cfq_queue *cfqq)
 
 static inline int __cfq_may_queue(struct cfq_queue *cfqq)
 {
-	if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) &&
-	    !cfq_cfqq_must_alloc_slice(cfqq)) {
+	if (cfq_cfqq_wait_request(cfqq) && !cfq_cfqq_must_alloc_slice(cfqq)) {
 		cfq_mark_cfqq_must_alloc_slice(cfqq);
 		return ELV_MQUEUE_MUST;
 	}
@@ -2317,7 +2304,6 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
 	}
 
 	cfqq->allocated[rw]++;
-	cfq_clear_cfqq_must_alloc(cfqq);
 	atomic_inc(&cfqq->ref);
 
 	spin_unlock_irqrestore(q->queue_lock, flags);
@@ -2668,7 +2654,7 @@ static void __exit cfq_exit(void)
 	 * this also protects us from entering cfq_slab_kill() with
 	 * pending RCU callbacks
 	 */
-	if (elv_ioc_count_read(ioc_count))
+	if (elv_ioc_count_read(cfq_ioc_count))
 		wait_for_completion(&all_gone);
 	cfq_slab_kill();
 }
diff --git a/block/elevator.c b/block/elevator.c
index 2d511f9..1975b61 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -79,7 +79,8 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio)
 	/*
 	 * Don't merge file system requests and discard requests
 	 */
-	if (bio_discard(bio) != bio_discard(rq->bio))
+	if (bio_rw_flagged(bio, BIO_RW_DISCARD) !=
+	    bio_rw_flagged(rq->bio, BIO_RW_DISCARD))
 		return 0;
 
 	/*
@@ -100,19 +101,6 @@ int elv_rq_merge_ok(struct request *rq, struct bio *bio)
 	if (bio_integrity(bio) != blk_integrity_rq(rq))
 		return 0;
 
-	/*
-	 * Don't merge if failfast settings don't match.
-	 *
-	 * FIXME: The negation in front of each condition is necessary
-	 * because bio and request flags use different bit positions
-	 * and the accessors return those bits directly.  This
-	 * ugliness will soon go away.
-	 */
-	if (!bio_failfast_dev(bio)	 != !blk_failfast_dev(rq)	||
-	    !bio_failfast_transport(bio) != !blk_failfast_transport(rq)	||
-	    !bio_failfast_driver(bio)	 != !blk_failfast_driver(rq))
-		return 0;
-
 	if (!elv_iosched_allow_merge(rq, bio))
 		return 0;
 
diff --git a/block/genhd.c b/block/genhd.c
index f4c64c2..517e433 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -869,6 +869,7 @@ static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
 static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
 static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
+static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 static struct device_attribute dev_attr_fail =
 	__ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -888,6 +889,7 @@ static struct attribute *disk_attrs[] = {
 	&dev_attr_alignment_offset.attr,
 	&dev_attr_capability.attr,
 	&dev_attr_stat.attr,
+	&dev_attr_inflight.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 	&dev_attr_fail.attr,
 #endif
@@ -901,7 +903,7 @@ static struct attribute_group disk_attr_group = {
 	.attrs = disk_attrs,
 };
 
-static struct attribute_group *disk_attr_groups[] = {
+static const struct attribute_group *disk_attr_groups[] = {
 	&disk_attr_group,
 	NULL
 };
@@ -996,12 +998,12 @@ struct class block_class = {
 	.name		= "block",
 };
 
-static char *block_nodename(struct device *dev)
+static char *block_devnode(struct device *dev, mode_t *mode)
 {
 	struct gendisk *disk = dev_to_disk(dev);
 
-	if (disk->nodename)
-		return disk->nodename(disk);
+	if (disk->devnode)
+		return disk->devnode(disk, mode);
 	return NULL;
 }
 
@@ -1009,7 +1011,7 @@ static struct device_type disk_type = {
 	.name		= "disk",
 	.groups		= disk_attr_groups,
 	.release	= disk_release,
-	.nodename	= block_nodename,
+	.devnode	= block_devnode,
 };
 
 #ifdef CONFIG_PROC_FS
@@ -1053,7 +1055,7 @@ static int diskstats_show(struct seq_file *seqf, void *v)
 			   part_stat_read(hd, merges[1]),
 			   (unsigned long long)part_stat_read(hd, sectors[1]),
 			   jiffies_to_msecs(part_stat_read(hd, ticks[1])),
-			   hd->in_flight,
+			   part_in_flight(hd),
 			   jiffies_to_msecs(part_stat_read(hd, io_ticks)),
 			   jiffies_to_msecs(part_stat_read(hd, time_in_queue))
 			);
@@ -1215,6 +1217,16 @@ void put_disk(struct gendisk *disk)
 
 EXPORT_SYMBOL(put_disk);
 
+static void set_disk_ro_uevent(struct gendisk *gd, int ro)
+{
+	char event[] = "DISK_RO=1";
+	char *envp[] = { event, NULL };
+
+	if (!ro)
+		event[8] = '0';
+	kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp);
+}
+
 void set_device_ro(struct block_device *bdev, int flag)
 {
 	bdev->bd_part->policy = flag;
@@ -1227,8 +1239,12 @@ void set_disk_ro(struct gendisk *disk, int flag)
 	struct disk_part_iter piter;
 	struct hd_struct *part;
 
-	disk_part_iter_init(&piter, disk,
-			    DISK_PITER_INCL_EMPTY | DISK_PITER_INCL_PART0);
+	if (disk->part0.policy != flag) {
+		set_disk_ro_uevent(disk, flag);
+		disk->part0.policy = flag;
+	}
+
+	disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
 	while ((part = disk_part_iter_next(&piter)))
 		part->policy = flag;
 	disk_part_iter_exit(&piter);
diff --git a/block/ioctl.c b/block/ioctl.c
index 500e4c7..d3e6b58 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -112,22 +112,9 @@ static int blkdev_reread_part(struct block_device *bdev)
 	return res;
 }
 
-static void blk_ioc_discard_endio(struct bio *bio, int err)
-{
-	if (err) {
-		if (err == -EOPNOTSUPP)
-			set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
-		clear_bit(BIO_UPTODATE, &bio->bi_flags);
-	}
-	complete(bio->bi_private);
-}
-
 static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
 			     uint64_t len)
 {
-	struct request_queue *q = bdev_get_queue(bdev);
-	int ret = 0;
-
 	if (start & 511)
 		return -EINVAL;
 	if (len & 511)
@@ -137,40 +124,8 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
 
 	if (start + len > (bdev->bd_inode->i_size >> 9))
 		return -EINVAL;
-
-	if (!q->prepare_discard_fn)
-		return -EOPNOTSUPP;
-
-	while (len && !ret) {
-		DECLARE_COMPLETION_ONSTACK(wait);
-		struct bio *bio;
-
-		bio = bio_alloc(GFP_KERNEL, 0);
-
-		bio->bi_end_io = blk_ioc_discard_endio;
-		bio->bi_bdev = bdev;
-		bio->bi_private = &wait;
-		bio->bi_sector = start;
-
-		if (len > queue_max_hw_sectors(q)) {
-			bio->bi_size = queue_max_hw_sectors(q) << 9;
-			len -= queue_max_hw_sectors(q);
-			start += queue_max_hw_sectors(q);
-		} else {
-			bio->bi_size = len << 9;
-			len = 0;
-		}
-		submit_bio(DISCARD_NOBARRIER, bio);
-
-		wait_for_completion(&wait);
-
-		if (bio_flagged(bio, BIO_EOPNOTSUPP))
-			ret = -EOPNOTSUPP;
-		else if (!bio_flagged(bio, BIO_UPTODATE))
-			ret = -EIO;
-		bio_put(bio);
-	}
-	return ret;
+	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL,
+				    DISCARD_FL_WAIT);
 }
 
 static int put_ushort(unsigned long arg, unsigned short val)
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index db307a3..cc22f9a 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -45,6 +45,7 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "actables.h"
+#include <linux/tboot.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwsleep")
@@ -342,6 +343,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 
 	ACPI_FLUSH_CPU_CACHE();
 
+	tboot_sleep(sleep_state, pm1a_control, pm1b_control);
+
 	/* Write #2: Write both SLP_TYP + SLP_EN */
 
 	status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 82b02dc..c016335 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -275,7 +275,6 @@ void acpi_tb_parse_fadt(u32 table_index)
 
 void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
 {
-
 	/*
 	 * Check if the FADT is larger than the largest table that we expect
 	 * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 55b5b90..31b961c 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -61,20 +61,6 @@ static struct acpi_driver acpi_pci_root_driver = {
 		},
 };
 
-struct acpi_pci_root {
-	struct list_head node;
-	struct acpi_device *device;
-	struct pci_bus *bus;
-	u16 segment;
-	u8 bus_nr;
-
-	u32 osc_support_set;	/* _OSC state of support bits */
-	u32 osc_control_set;	/* _OSC state of control bits */
-	u32 osc_control_qry;	/* the latest _OSC query result */
-
-	u32 osc_queried:1;	/* has _OSC control been queried? */
-};
-
 static LIST_HEAD(acpi_pci_roots);
 
 static struct acpi_pci_driver *sub_driver;
@@ -317,7 +303,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
 	return status;
 }
 
-static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
+struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
 {
 	struct acpi_pci_root *root;
 
@@ -327,6 +313,7 @@ static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(acpi_pci_find_root);
 
 struct acpi_handle_node {
 	struct list_head node;
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index d74365d..5a09bf3 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -44,6 +44,8 @@
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
+#include "sleep.h"
+
 #define _COMPONENT			ACPI_POWER_COMPONENT
 ACPI_MODULE_NAME("power");
 #define ACPI_POWER_CLASS		"power_resource"
@@ -361,17 +363,15 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
  */
 int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
 {
-	int i, err;
+	int i, err = 0;
 
 	if (!dev || !dev->wakeup.flags.valid)
 		return -EINVAL;
 
-	/*
-	 * Do not execute the code below twice in a row without calling
-	 * acpi_disable_wakeup_device_power() in between for the same device
-	 */
-	if (dev->wakeup.flags.prepared)
-		return 0;
+	mutex_lock(&acpi_device_lock);
+
+	if (dev->wakeup.prepare_count++)
+		goto out;
 
 	/* Open power resource */
 	for (i = 0; i < dev->wakeup.resources.count; i++) {
@@ -379,7 +379,8 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
 		if (ret) {
 			printk(KERN_ERR PREFIX "Transition power state\n");
 			dev->wakeup.flags.valid = 0;
-			return -ENODEV;
+			err = -ENODEV;
+			goto err_out;
 		}
 	}
 
@@ -388,9 +389,13 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
 	 * in arbitrary power state afterwards.
 	 */
 	err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
-	if (!err)
-		dev->wakeup.flags.prepared = 1;
 
+ err_out:
+	if (err)
+		dev->wakeup.prepare_count = 0;
+
+ out:
+	mutex_unlock(&acpi_device_lock);
 	return err;
 }
 
@@ -402,35 +407,42 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
  */
 int acpi_disable_wakeup_device_power(struct acpi_device *dev)
 {
-	int i, ret;
+	int i, err = 0;
 
 	if (!dev || !dev->wakeup.flags.valid)
 		return -EINVAL;
 
+	mutex_lock(&acpi_device_lock);
+
+	if (--dev->wakeup.prepare_count > 0)
+		goto out;
+
 	/*
-	 * Do not execute the code below twice in a row without calling
-	 * acpi_enable_wakeup_device_power() in between for the same device
+	 * Executing the code below even if prepare_count is already zero when
+	 * the function is called may be useful, for example for initialisation.
 	 */
-	if (!dev->wakeup.flags.prepared)
-		return 0;
+	if (dev->wakeup.prepare_count < 0)
+		dev->wakeup.prepare_count = 0;
 
-	dev->wakeup.flags.prepared = 0;
-
-	ret = acpi_device_sleep_wake(dev, 0, 0, 0);
-	if (ret)
-		return ret;
+	err = acpi_device_sleep_wake(dev, 0, 0, 0);
+	if (err)
+		goto out;
 
 	/* Close power resource */
 	for (i = 0; i < dev->wakeup.resources.count; i++) {
-		ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev);
+		int ret = acpi_power_off_device(
+				dev->wakeup.resources.handles[i], dev);
 		if (ret) {
 			printk(KERN_ERR PREFIX "Transition power state\n");
 			dev->wakeup.flags.valid = 0;
-			return -ENODEV;
+			err = -ENODEV;
+			goto out;
 		}
 	}
 
-	return ret;
+ out:
+	mutex_unlock(&acpi_device_lock);
+	return err;
 }
 
 /* --------------------------------------------------------------------------
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 781435d..318b1ea 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -781,6 +781,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
 	kfree(buffer.pointer);
 
 	device->wakeup.flags.valid = 1;
+	device->wakeup.prepare_count = 0;
 	/* Call _PSW/_DSW object to disable its ability to wake the sleeping
 	 * system for the ACPI device with the _PRW object.
 	 * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 42159a2..feece69 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -689,19 +689,25 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
 {
 	acpi_handle handle;
 	struct acpi_device *adev;
+	int error;
 
-	if (!device_may_wakeup(dev))
+	if (!device_can_wakeup(dev))
 		return -EINVAL;
 
 	handle = DEVICE_ACPI_HANDLE(dev);
 	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
-		printk(KERN_DEBUG "ACPI handle has no context!\n");
+		dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__);
 		return -ENODEV;
 	}
 
-	return enable ?
+	error = enable ?
 		acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) :
 		acpi_disable_wakeup_device_power(adev);
+	if (!error)
+		dev_info(dev, "wake-up capability %s by ACPI\n",
+				enable ? "enabled" : "disabled");
+
+	return error;
 }
 #endif
 
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 88725dc..e0ee0c0 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -68,7 +68,7 @@ void acpi_enable_wakeup_device(u8 sleep_state)
 		/* If users want to disable run-wake GPE,
 		 * we only disable it for wake and leave it for runtime
 		 */
-		if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
+		if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count)
 		    || sleep_state > (u32) dev->wakeup.sleep_state) {
 			if (dev->wakeup.flags.run_wake) {
 				/* set_gpe_type will disable GPE, leave it like that */
@@ -100,7 +100,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
 		if (!dev->wakeup.flags.valid)
 			continue;
 
-		if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
+		if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count)
 		    || sleep_state > (u32) dev->wakeup.sleep_state) {
 			if (dev->wakeup.flags.run_wake) {
 				acpi_set_gpe_type(dev->wakeup.gpe_device,
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 2466506..f60b2b6 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -204,6 +204,7 @@ static void amba_device_release(struct device *dev)
 int amba_device_register(struct amba_device *dev, struct resource *parent)
 {
 	u32 pid, cid;
+	u32 size;
 	void __iomem *tmp;
 	int i, ret;
 
@@ -229,16 +230,25 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
 	if (ret)
 		goto err_out;
 
-	tmp = ioremap(dev->res.start, SZ_4K);
+	/*
+	 * Dynamically calculate the size of the resource
+	 * and use this for iomap
+	 */
+	size = resource_size(&dev->res);
+	tmp = ioremap(dev->res.start, size);
 	if (!tmp) {
 		ret = -ENOMEM;
 		goto err_release;
 	}
 
+	/*
+	 * Read pid and cid based on size of resource
+	 * they are located at end of region
+	 */
 	for (pid = 0, i = 0; i < 4; i++)
-		pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8);
+		pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8);
 	for (cid = 0, i = 0; i < 4; i++)
-		cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8);
+		cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8);
 
 	iounmap(tmp);
 
@@ -353,11 +363,14 @@ amba_find_device(const char *busid, struct device *parent, unsigned int id,
 int amba_request_regions(struct amba_device *dev, const char *name)
 {
 	int ret = 0;
+	u32 size;
 
 	if (!name)
 		name = dev->dev.driver->name;
 
-	if (!request_mem_region(dev->res.start, SZ_4K, name))
+	size = resource_size(&dev->res);
+
+	if (!request_mem_region(dev->res.start, size, name))
 		ret = -EBUSY;
 
 	return ret;
@@ -371,7 +384,10 @@ int amba_request_regions(struct amba_device *dev, const char *name)
  */
 void amba_release_regions(struct amba_device *dev)
 {
-	release_mem_region(dev->res.start, SZ_4K);
+	u32 size;
+
+	size = resource_size(&dev->res);
+	release_mem_region(dev->res.start, size);
 }
 
 EXPORT_SYMBOL(amba_driver_register);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index ab2fa4e..f2df6e2 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -255,6 +255,15 @@ config PATA_ARTOP
 
 	  If unsure, say N.
 
+config PATA_ATP867X
+	tristate "ARTOP/Acard ATP867X PATA support"
+	depends on PCI
+	help
+	  This option enables support for ARTOP/Acard ATP867X PATA
+	  controllers.
+
+	  If unsure, say N.
+
 config PATA_AT32
 	tristate "Atmel AVR32 PATA support (Experimental)"
 	depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 463eb52..01e126f 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SATA_FSL)		+= sata_fsl.o
 obj-$(CONFIG_PATA_ALI)		+= pata_ali.o
 obj-$(CONFIG_PATA_AMD)		+= pata_amd.o
 obj-$(CONFIG_PATA_ARTOP)	+= pata_artop.o
+obj-$(CONFIG_PATA_ATP867X)	+= pata_atp867x.o
 obj-$(CONFIG_PATA_AT32)		+= pata_at32.o
 obj-$(CONFIG_PATA_ATIIXP)	+= pata_atiixp.o
 obj-$(CONFIG_PATA_CMD640_PCI)	+= pata_cmd640.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index d4cd9c2..acd1162 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -2930,8 +2930,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (ahci_sb600_32bit_only(pdev))
 		hpriv->flags |= AHCI_HFLAG_32BIT_ONLY;
 
-	if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
-		pci_enable_msi(pdev);
+	if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
+		pci_intx(pdev, 1);
 
 	/* save initial config */
 	ahci_save_initial_config(pdev, hpriv);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index df31dea..0ddaf43 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5024,8 +5024,6 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
 		struct ata_device *dev = qc->dev;
 		struct ata_eh_info *ehi = &dev->link->eh_info;
 
-		WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN);
-
 		if (unlikely(qc->err_mask))
 			qc->flags |= ATA_QCFLAG_FAILED;
 
@@ -5038,6 +5036,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
 			}
 		}
 
+		WARN_ON_ONCE(ap->pflags & ATA_PFLAG_FROZEN);
+
 		/* read result TF if requested */
 		if (qc->flags & ATA_QCFLAG_RESULT_TF)
 			fill_result_tf(qc);
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 33a74f1..567f3f7 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -307,6 +307,9 @@ static unsigned long nv_mode_filter(struct ata_device *dev,
 		limit |= ATA_MASK_PIO;
 	if (!(limit & (ATA_MASK_MWDMA | ATA_MASK_UDMA)))
 		limit |= ATA_MASK_MWDMA | ATA_MASK_UDMA;
+	/* PIO4, MWDMA2, UDMA2 should always be supported regardless of
+	   cable detection result */
+	limit |= ata_pack_xfermask(ATA_PIO4, ATA_MWDMA2, ATA_UDMA2);
 
 	ata_port_printk(ap, KERN_DEBUG, "nv_mode_filter: 0x%lx&0x%lx->0x%lx, "
 			"BIOS=0x%lx (0x%x) ACPI=0x%lx%s\n",
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c
new file mode 100644
index 0000000..7990de9
--- /dev/null
+++ b/drivers/ata/pata_atp867x.c
@@ -0,0 +1,548 @@
+/*
+ * pata_atp867x.c - ARTOP 867X 64bit 4-channel UDMA133 ATA controller driver
+ *
+ *	(C) 2009 Google Inc. John(Jung-Ik) Lee <jilee@google.com>
+ *
+ * Per Atp867 data sheet rev 1.2, Acard.
+ * Based in part on early ide code from
+ *	2003-2004 by Eric Uhrhane, Google, 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
+ *
+ *
+ * TODO:
+ *   1. RAID features [comparison, XOR, striping, mirroring, etc.]
+ */
+
+#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>
+
+#define	DRV_NAME	"pata_atp867x"
+#define	DRV_VERSION	"0.7.5"
+
+/*
+ * IO Registers
+ * Note that all runtime hot priv ports are cached in ap private_data
+ */
+
+enum {
+	ATP867X_IO_CHANNEL_OFFSET	= 0x10,
+
+	/*
+	 * IO Register Bitfields
+	 */
+
+	ATP867X_IO_PIOSPD_ACTIVE_SHIFT	= 4,
+	ATP867X_IO_PIOSPD_RECOVER_SHIFT	= 0,
+
+	ATP867X_IO_DMAMODE_MSTR_SHIFT	= 0,
+	ATP867X_IO_DMAMODE_MSTR_MASK	= 0x07,
+	ATP867X_IO_DMAMODE_SLAVE_SHIFT	= 4,
+	ATP867X_IO_DMAMODE_SLAVE_MASK	= 0x70,
+
+	ATP867X_IO_DMAMODE_UDMA_6	= 0x07,
+	ATP867X_IO_DMAMODE_UDMA_5	= 0x06,
+	ATP867X_IO_DMAMODE_UDMA_4	= 0x05,
+	ATP867X_IO_DMAMODE_UDMA_3	= 0x04,
+	ATP867X_IO_DMAMODE_UDMA_2	= 0x03,
+	ATP867X_IO_DMAMODE_UDMA_1	= 0x02,
+	ATP867X_IO_DMAMODE_UDMA_0	= 0x01,
+	ATP867X_IO_DMAMODE_DISABLE	= 0x00,
+
+	ATP867X_IO_SYS_INFO_66MHZ	= 0x04,
+	ATP867X_IO_SYS_INFO_SLOW_UDMA5	= 0x02,
+	ATP867X_IO_SYS_MASK_RESERVED	= (~0xf1),
+
+	ATP867X_IO_PORTSPD_VAL		= 0x1143,
+	ATP867X_PREREAD_VAL		= 0x0200,
+
+	ATP867X_NUM_PORTS		= 4,
+	ATP867X_BAR_IOBASE		= 0,
+	ATP867X_BAR_ROMBASE		= 6,
+};
+
+#define ATP867X_IOBASE(ap)		((ap)->host->iomap[0])
+#define ATP867X_SYS_INFO(ap)		(0x3F + ATP867X_IOBASE(ap))
+
+#define ATP867X_IO_PORTBASE(ap, port)	(0x00 + ATP867X_IOBASE(ap) + \
+					(port) * ATP867X_IO_CHANNEL_OFFSET)
+#define ATP867X_IO_DMABASE(ap, port)	(0x40 + \
+					ATP867X_IO_PORTBASE((ap), (port)))
+
+#define ATP867X_IO_STATUS(ap, port)	(0x07 + \
+					ATP867X_IO_PORTBASE((ap), (port)))
+#define ATP867X_IO_ALTSTATUS(ap, port)	(0x0E + \
+					ATP867X_IO_PORTBASE((ap), (port)))
+
+/*
+ * hot priv ports
+ */
+#define ATP867X_IO_MSTRPIOSPD(ap, port)	(0x08 + \
+					ATP867X_IO_DMABASE((ap), (port)))
+#define ATP867X_IO_SLAVPIOSPD(ap, port)	(0x09 + \
+					ATP867X_IO_DMABASE((ap), (port)))
+#define ATP867X_IO_8BPIOSPD(ap, port)	(0x0A + \
+					ATP867X_IO_DMABASE((ap), (port)))
+#define ATP867X_IO_DMAMODE(ap, port)	(0x0B + \
+					ATP867X_IO_DMABASE((ap), (port)))
+
+#define ATP867X_IO_PORTSPD(ap, port)	(0x4A + \
+					ATP867X_IO_PORTBASE((ap), (port)))
+#define ATP867X_IO_PREREAD(ap, port)	(0x4C + \
+					ATP867X_IO_PORTBASE((ap), (port)))
+
+struct atp867x_priv {
+	void __iomem *dma_mode;
+	void __iomem *mstr_piospd;
+	void __iomem *slave_piospd;
+	void __iomem *eightb_piospd;
+	int		pci66mhz;
+};
+
+static inline u8 atp867x_speed_to_mode(u8 speed)
+{
+	return speed - XFER_UDMA_0 + 1;
+}
+
+static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
+	struct atp867x_priv *dp = ap->private_data;
+	u8 speed = adev->dma_mode;
+	u8 b;
+	u8 mode;
+
+	mode = atp867x_speed_to_mode(speed);
+
+	/*
+	 * Doc 6.6.9: decrease the udma mode value by 1 for safer UDMA speed
+	 * on 66MHz bus
+	 *   rev-A: UDMA_1~4 (5, 6 no change)
+	 *   rev-B: all UDMA modes
+	 *   UDMA_0 stays not to disable UDMA
+	 */
+	if (dp->pci66mhz && mode > ATP867X_IO_DMAMODE_UDMA_0  &&
+	   (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B ||
+	    mode < ATP867X_IO_DMAMODE_UDMA_5))
+		mode--;
+
+	b = ioread8(dp->dma_mode);
+	if (adev->devno & 1) {
+		b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK) |
+			(mode << ATP867X_IO_DMAMODE_SLAVE_SHIFT);
+	} else {
+		b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK) |
+			(mode << ATP867X_IO_DMAMODE_MSTR_SHIFT);
+	}
+	iowrite8(b, dp->dma_mode);
+}
+
+static int atp867x_get_active_clocks_shifted(unsigned int clk)
+{
+	unsigned char clocks = clk;
+
+	switch (clocks) {
+	case 0:
+		clocks = 1;
+		break;
+	case 1 ... 7:
+		break;
+	case 8 ... 12:
+		clocks = 7;
+		break;
+	default:
+		printk(KERN_WARNING "ATP867X: active %dclk is invalid. "
+			"Using default 8clk.\n", clk);
+		clocks = 0;	/* 8 clk */
+		break;
+	}
+	return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT;
+}
+
+static int atp867x_get_recover_clocks_shifted(unsigned int clk)
+{
+	unsigned char clocks = clk;
+
+	switch (clocks) {
+	case 0:
+		clocks = 1;
+		break;
+	case 1 ... 11:
+		break;
+	case 12:
+		clocks = 0;
+		break;
+	case 13: case 14:
+		--clocks;
+		break;
+	case 15:
+		break;
+	default:
+		printk(KERN_WARNING "ATP867X: recover %dclk is invalid. "
+			"Using default 15clk.\n", clk);
+		clocks = 0;	/* 12 clk */
+		break;
+	}
+	return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT;
+}
+
+static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+	struct ata_device *peer = ata_dev_pair(adev);
+	struct atp867x_priv *dp = ap->private_data;
+	u8 speed = adev->pio_mode;
+	struct ata_timing t, p;
+	int T, UT;
+	u8 b;
+
+	T = 1000000000 / 33333;
+	UT = T / 4;
+
+	ata_timing_compute(adev, speed, &t, T, UT);
+	if (peer && peer->pio_mode) {
+		ata_timing_compute(peer, peer->pio_mode, &p, T, UT);
+		ata_timing_merge(&p, &t, &t, ATA_TIMING_8BIT);
+	}
+
+	b = ioread8(dp->dma_mode);
+	if (adev->devno & 1)
+		b = (b & ~ATP867X_IO_DMAMODE_SLAVE_MASK);
+	else
+		b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK);
+	iowrite8(b, dp->dma_mode);
+
+	b = atp867x_get_active_clocks_shifted(t.active) |
+		atp867x_get_recover_clocks_shifted(t.recover);
+	if (dp->pci66mhz)
+		b += 0x10;
+
+	if (adev->devno & 1)
+		iowrite8(b, dp->slave_piospd);
+	else
+		iowrite8(b, dp->mstr_piospd);
+
+	/*
+	 * use the same value for comand timing as for PIO timimg
+	 */
+	iowrite8(b, dp->eightb_piospd);
+}
+
+static int atp867x_cable_detect(struct ata_port *ap)
+{
+	return ATA_CBL_PATA40_SHORT;
+}
+
+static struct scsi_host_template atp867x_sht = {
+	ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations atp867x_ops = {
+	.inherits		= &ata_bmdma_port_ops,
+	.cable_detect		= atp867x_cable_detect,
+	.set_piomode		= atp867x_set_piomode,
+	.set_dmamode		= atp867x_set_dmamode,
+};
+
+
+#ifdef	ATP867X_DEBUG
+static void atp867x_check_res(struct pci_dev *pdev)
+{
+	int i;
+	unsigned long start, len;
+
+	/* Check the PCI resources for this channel are enabled */
+	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+		start = pci_resource_start(pdev, i);
+		len   = pci_resource_len(pdev, i);
+		printk(KERN_DEBUG "ATP867X: resource start:len=%lx:%lx\n",
+			start, len);
+	}
+}
+
+static void atp867x_check_ports(struct ata_port *ap, int port)
+{
+	struct ata_ioports *ioaddr = &ap->ioaddr;
+	struct atp867x_priv *dp = ap->private_data;
+
+	printk(KERN_DEBUG "ATP867X: port[%d] addresses\n"
+		"  cmd_addr	=0x%llx, 0x%llx\n"
+		"  ctl_addr	=0x%llx, 0x%llx\n"
+		"  bmdma_addr	=0x%llx, 0x%llx\n"
+		"  data_addr	=0x%llx\n"
+		"  error_addr	=0x%llx\n"
+		"  feature_addr	=0x%llx\n"
+		"  nsect_addr	=0x%llx\n"
+		"  lbal_addr	=0x%llx\n"
+		"  lbam_addr	=0x%llx\n"
+		"  lbah_addr	=0x%llx\n"
+		"  device_addr	=0x%llx\n"
+		"  status_addr	=0x%llx\n"
+		"  command_addr	=0x%llx\n"
+		"  dp->dma_mode	=0x%llx\n"
+		"  dp->mstr_piospd	=0x%llx\n"
+		"  dp->slave_piospd	=0x%llx\n"
+		"  dp->eightb_piospd	=0x%llx\n"
+		"  dp->pci66mhz		=0x%lx\n",
+		port,
+		(unsigned long long)ioaddr->cmd_addr,
+		(unsigned long long)ATP867X_IO_PORTBASE(ap, port),
+		(unsigned long long)ioaddr->ctl_addr,
+		(unsigned long long)ATP867X_IO_ALTSTATUS(ap, port),
+		(unsigned long long)ioaddr->bmdma_addr,
+		(unsigned long long)ATP867X_IO_DMABASE(ap, port),
+		(unsigned long long)ioaddr->data_addr,
+		(unsigned long long)ioaddr->error_addr,
+		(unsigned long long)ioaddr->feature_addr,
+		(unsigned long long)ioaddr->nsect_addr,
+		(unsigned long long)ioaddr->lbal_addr,
+		(unsigned long long)ioaddr->lbam_addr,
+		(unsigned long long)ioaddr->lbah_addr,
+		(unsigned long long)ioaddr->device_addr,
+		(unsigned long long)ioaddr->status_addr,
+		(unsigned long long)ioaddr->command_addr,
+		(unsigned long long)dp->dma_mode,
+		(unsigned long long)dp->mstr_piospd,
+		(unsigned long long)dp->slave_piospd,
+		(unsigned long long)dp->eightb_piospd,
+		(unsigned long)dp->pci66mhz);
+}
+#endif
+
+static int atp867x_set_priv(struct ata_port *ap)
+{
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+	struct atp867x_priv *dp;
+	int port = ap->port_no;
+
+	dp = ap->private_data =
+		devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);
+	if (dp == NULL)
+		return -ENOMEM;
+
+	dp->dma_mode	 = ATP867X_IO_DMAMODE(ap, port);
+	dp->mstr_piospd	 = ATP867X_IO_MSTRPIOSPD(ap, port);
+	dp->slave_piospd = ATP867X_IO_SLAVPIOSPD(ap, port);
+	dp->eightb_piospd = ATP867X_IO_8BPIOSPD(ap, port);
+
+	dp->pci66mhz =
+		ioread8(ATP867X_SYS_INFO(ap)) & ATP867X_IO_SYS_INFO_66MHZ;
+
+	return 0;
+}
+
+static void atp867x_fixup(struct ata_host *host)
+{
+	struct pci_dev *pdev = to_pci_dev(host->dev);
+	struct ata_port *ap = host->ports[0];
+	int i;
+	u8 v;
+
+	/*
+	 * Broken BIOS might not set latency high enough
+	 */
+	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &v);
+	if (v < 0x80) {
+		v = 0x80;
+		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, v);
+		printk(KERN_DEBUG "ATP867X: set latency timer of device %s"
+			" to %d\n", pci_name(pdev), v);
+	}
+
+	/*
+	 * init 8bit io ports speed(0aaarrrr) to 43h and
+	 * init udma modes of master/slave to 0/0(11h)
+	 */
+	for (i = 0; i < ATP867X_NUM_PORTS; i++)
+		iowrite16(ATP867X_IO_PORTSPD_VAL, ATP867X_IO_PORTSPD(ap, i));
+
+	/*
+	 * init PreREAD counts
+	 */
+	for (i = 0; i < ATP867X_NUM_PORTS; i++)
+		iowrite16(ATP867X_PREREAD_VAL, ATP867X_IO_PREREAD(ap, i));
+
+	v = ioread8(ATP867X_IOBASE(ap) + 0x28);
+	v &= 0xcf;	/* Enable INTA#: bit4=0 means enable */
+	v |= 0xc0;	/* Enable PCI burst, MRM & not immediate interrupts */
+	iowrite8(v, ATP867X_IOBASE(ap) + 0x28);
+
+	/*
+	 * Turn off the over clocked udma5 mode, only for Rev-B
+	 */
+	v = ioread8(ATP867X_SYS_INFO(ap));
+	v &= ATP867X_IO_SYS_MASK_RESERVED;
+	if (pdev->device == PCI_DEVICE_ID_ARTOP_ATP867B)
+		v |= ATP867X_IO_SYS_INFO_SLOW_UDMA5;
+	iowrite8(v, ATP867X_SYS_INFO(ap));
+}
+
+static int atp867x_ata_pci_sff_init_host(struct ata_host *host)
+{
+	struct device *gdev = host->dev;
+	struct pci_dev *pdev = to_pci_dev(gdev);
+	unsigned int mask = 0;
+	int i, rc;
+
+	/*
+	 * do not map rombase
+	 */
+	rc = pcim_iomap_regions(pdev, 1 << ATP867X_BAR_IOBASE, DRV_NAME);
+	if (rc == -EBUSY)
+		pcim_pin_device(pdev);
+	if (rc)
+		return rc;
+	host->iomap = pcim_iomap_table(pdev);
+
+#ifdef	ATP867X_DEBUG
+	atp867x_check_res(pdev);
+
+	for (i = 0; i < PCI_ROM_RESOURCE; i++)
+		printk(KERN_DEBUG "ATP867X: iomap[%d]=0x%llx\n", i,
+			(unsigned long long)(host->iomap[i]));
+#endif
+
+	/*
+	 * request, iomap BARs and init port addresses accordingly
+	 */
+	for (i = 0; i < host->n_ports; i++) {
+		struct ata_port *ap = host->ports[i];
+		struct ata_ioports *ioaddr = &ap->ioaddr;
+
+		ioaddr->cmd_addr = ATP867X_IO_PORTBASE(ap, i);
+		ioaddr->ctl_addr = ioaddr->altstatus_addr
+				 = ATP867X_IO_ALTSTATUS(ap, i);
+		ioaddr->bmdma_addr = ATP867X_IO_DMABASE(ap, i);
+
+		ata_sff_std_ports(ioaddr);
+		rc = atp867x_set_priv(ap);
+		if (rc)
+			return rc;
+
+#ifdef	ATP867X_DEBUG
+		atp867x_check_ports(ap, i);
+#endif
+		ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
+			(unsigned long)ioaddr->cmd_addr,
+			(unsigned long)ioaddr->ctl_addr);
+		ata_port_desc(ap, "bmdma 0x%lx",
+			(unsigned long)ioaddr->bmdma_addr);
+
+		mask |= 1 << i;
+	}
+
+	if (!mask) {
+		dev_printk(KERN_ERR, gdev, "no available native port\n");
+		return -ENODEV;
+	}
+
+	atp867x_fixup(host);
+
+	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+	if (rc)
+		return rc;
+
+	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+	return rc;
+}
+
+static int atp867x_init_one(struct pci_dev *pdev,
+	const struct pci_device_id *id)
+{
+	static int printed_version;
+	static const struct ata_port_info info_867x = {
+		.flags		= ATA_FLAG_SLAVE_POSS,
+		.pio_mask	= ATA_PIO4,
+		.mwdma_mask	= ATA_MWDMA2,
+		.udma_mask 	= ATA_UDMA6,
+		.port_ops	= &atp867x_ops,
+	};
+
+	struct ata_host *host;
+	const struct ata_port_info *ppi[] = { &info_867x, NULL };
+	int rc;
+
+	if (!printed_version++)
+		dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
+
+	rc = pcim_enable_device(pdev);
+	if (rc)
+		return rc;
+
+	printk(KERN_INFO "ATP867X: ATP867 ATA UDMA133 controller (rev %02X)",
+		pdev->device);
+
+	host = ata_host_alloc_pinfo(&pdev->dev, ppi, ATP867X_NUM_PORTS);
+	if (!host) {
+		dev_printk(KERN_ERR, &pdev->dev,
+			"failed to allocate ATA host\n");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+
+	rc = atp867x_ata_pci_sff_init_host(host);
+	if (rc) {
+		dev_printk(KERN_ERR, &pdev->dev, "failed to init host\n");
+		goto err_out;
+	}
+
+	pci_set_master(pdev);
+
+	rc = ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+				IRQF_SHARED, &atp867x_sht);
+	if (rc)
+		dev_printk(KERN_ERR, &pdev->dev, "failed to activate host\n");
+
+err_out:
+	return rc;
+}
+
+static struct pci_device_id atp867x_pci_tbl[] = {
+	{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867A),	0 },
+	{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867B),	0 },
+	{ },
+};
+
+static struct pci_driver atp867x_driver = {
+	.name 		= DRV_NAME,
+	.id_table 	= atp867x_pci_tbl,
+	.probe 		= atp867x_init_one,
+	.remove		= ata_pci_remove_one,
+};
+
+static int __init atp867x_init(void)
+{
+	return pci_register_driver(&atp867x_driver);
+}
+
+static void __exit atp867x_exit(void)
+{
+	pci_unregister_driver(&atp867x_driver);
+}
+
+MODULE_AUTHOR("John(Jung-Ik) Lee, Google Inc.");
+MODULE_DESCRIPTION("low level driver for Artop/Acard 867x ATA controller");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, atp867x_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(atp867x_init);
+module_exit(atp867x_exit);
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index b1fd7d6..07d8d00 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -56,6 +56,7 @@ enum {
 	/* host register offsets (from host->iomap[PDC_MMIO_BAR]) */
 	PDC_INT_SEQMASK		= 0x40,	/* Mask of asserted SEQ INTs */
 	PDC_FLASH_CTL		= 0x44, /* Flash control register */
+	PDC_PCI_CTL		= 0x48, /* PCI control/status reg */
 	PDC_SATA_PLUG_CSR	= 0x6C, /* SATA Plug control/status reg */
 	PDC2_SATA_PLUG_CSR	= 0x60, /* SATAII Plug control/status reg */
 	PDC_TBG_MODE		= 0x41C, /* TBG mode (not SATAII) */
@@ -75,7 +76,17 @@ enum {
 	PDC_CTLSTAT		= 0x60,	/* IDE control and status (per port) */
 
 	/* per-port SATA register offsets (from ap->ioaddr.scr_addr) */
+	PDC_SATA_ERROR		= 0x04,
 	PDC_PHYMODE4		= 0x14,
+	PDC_LINK_LAYER_ERRORS	= 0x6C,
+	PDC_FPDMA_CTLSTAT	= 0xD8,
+	PDC_INTERNAL_DEBUG_1	= 0xF8,	/* also used for PATA */
+	PDC_INTERNAL_DEBUG_2	= 0xFC,	/* also used for PATA */
+
+	/* PDC_FPDMA_CTLSTAT bit definitions */
+	PDC_FPDMA_CTLSTAT_RESET			= 1 << 3,
+	PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG	= 1 << 10,
+	PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG	= 1 << 11,
 
 	/* PDC_GLOBAL_CTL bit definitions */
 	PDC_PH_ERR		= (1 <<  8), /* PCI error while loading packet */
@@ -195,9 +206,12 @@ static struct ata_port_operations pdc_sata_ops = {
 	.hardreset		= pdc_sata_hardreset,
 };
 
-/* First-generation chips need a more restrictive ->check_atapi_dma op */
+/* First-generation chips need a more restrictive ->check_atapi_dma op,
+   and ->freeze/thaw that ignore the hotplug controls. */
 static struct ata_port_operations pdc_old_sata_ops = {
 	.inherits		= &pdc_sata_ops,
+	.freeze			= pdc_freeze,
+	.thaw			= pdc_thaw,
 	.check_atapi_dma	= pdc_old_sata_check_atapi_dma,
 };
 
@@ -356,12 +370,76 @@ static int pdc_sata_port_start(struct ata_port *ap)
 	return 0;
 }
 
+static void pdc_fpdma_clear_interrupt_flag(struct ata_port *ap)
+{
+	void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+	u32 tmp;
+
+	tmp = readl(sata_mmio + PDC_FPDMA_CTLSTAT);
+	tmp |= PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG;
+	tmp |= PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG;
+
+	/* It's not allowed to write to the entire FPDMA_CTLSTAT register
+	   when NCQ is running. So do a byte-sized write to bits 10 and 11. */
+	writeb(tmp >> 8, sata_mmio + PDC_FPDMA_CTLSTAT + 1);
+	readb(sata_mmio + PDC_FPDMA_CTLSTAT + 1); /* flush */
+}
+
+static void pdc_fpdma_reset(struct ata_port *ap)
+{
+	void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+	u8 tmp;
+
+	tmp = (u8)readl(sata_mmio + PDC_FPDMA_CTLSTAT);
+	tmp &= 0x7F;
+	tmp |= PDC_FPDMA_CTLSTAT_RESET;
+	writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
+	readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
+	udelay(100);
+	tmp &= ~PDC_FPDMA_CTLSTAT_RESET;
+	writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
+	readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
+
+	pdc_fpdma_clear_interrupt_flag(ap);
+}
+
+static void pdc_not_at_command_packet_phase(struct ata_port *ap)
+{
+	void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+	unsigned int i;
+	u32 tmp;
+
+	/* check not at ASIC packet command phase */
+	for (i = 0; i < 100; ++i) {
+		writel(0, sata_mmio + PDC_INTERNAL_DEBUG_1);
+		tmp = readl(sata_mmio + PDC_INTERNAL_DEBUG_2);
+		if ((tmp & 0xF) != 1)
+			break;
+		udelay(100);
+	}
+}
+
+static void pdc_clear_internal_debug_record_error_register(struct ata_port *ap)
+{
+	void __iomem *sata_mmio = ap->ioaddr.scr_addr;
+
+	writel(0xffffffff, sata_mmio + PDC_SATA_ERROR);
+	writel(0xffff0000, sata_mmio + PDC_LINK_LAYER_ERRORS);
+}
+
 static void pdc_reset_port(struct ata_port *ap)
 {
 	void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
 	unsigned int i;
 	u32 tmp;
 
+	if (ap->flags & PDC_FLAG_GEN_II)
+		pdc_not_at_command_packet_phase(ap);
+
+	tmp = readl(ata_ctlstat_mmio);
+	tmp |= PDC_RESET;
+	writel(tmp, ata_ctlstat_mmio);
+
 	for (i = 11; i > 0; i--) {
 		tmp = readl(ata_ctlstat_mmio);
 		if (tmp & PDC_RESET)
@@ -376,6 +454,11 @@ static void pdc_reset_port(struct ata_port *ap)
 	tmp &= ~PDC_RESET;
 	writel(tmp, ata_ctlstat_mmio);
 	readl(ata_ctlstat_mmio);	/* flush */
+
+	if (sata_scr_valid(&ap->link) && (ap->flags & PDC_FLAG_GEN_II)) {
+		pdc_fpdma_reset(ap);
+		pdc_clear_internal_debug_record_error_register(ap);
+	}
 }
 
 static int pdc_pata_cable_detect(struct ata_port *ap)
@@ -626,11 +709,6 @@ static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap)
 	return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags));
 }
 
-static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap)
-{
-	return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR;
-}
-
 static void pdc_freeze(struct ata_port *ap)
 {
 	void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
@@ -647,7 +725,7 @@ static void pdc_sata_freeze(struct ata_port *ap)
 {
 	struct ata_host *host = ap->host;
 	void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
-	unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+	unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
 	unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
 	u32 hotplug_status;
 
@@ -685,7 +763,7 @@ static void pdc_sata_thaw(struct ata_port *ap)
 {
 	struct ata_host *host = ap->host;
 	void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
-	unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+	unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR;
 	unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
 	u32 hotplug_status;
 
@@ -708,11 +786,50 @@ static int pdc_pata_softreset(struct ata_link *link, unsigned int *class,
 	return ata_sff_softreset(link, class, deadline);
 }
 
+static unsigned int pdc_ata_port_to_ata_no(const struct ata_port *ap)
+{
+	void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
+	void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
+
+	/* ata_mmio == host_mmio + 0x200 + ata_no * 0x80 */
+	return (ata_mmio - host_mmio - 0x200) / 0x80;
+}
+
+static void pdc_hard_reset_port(struct ata_port *ap)
+{
+	void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
+	void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1;
+	unsigned int ata_no = pdc_ata_port_to_ata_no(ap);
+	u8 tmp;
+
+	spin_lock(&ap->host->lock);
+
+	tmp = readb(pcictl_b1_mmio);
+	tmp &= ~(0x10 << ata_no);
+	writeb(tmp, pcictl_b1_mmio);
+	readb(pcictl_b1_mmio); /* flush */
+	udelay(100);
+	tmp |= (0x10 << ata_no);
+	writeb(tmp, pcictl_b1_mmio);
+	readb(pcictl_b1_mmio); /* flush */
+
+	spin_unlock(&ap->host->lock);
+}
+
 static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
 			      unsigned long deadline)
 {
+	if (link->ap->flags & PDC_FLAG_GEN_II)
+		pdc_not_at_command_packet_phase(link->ap);
+	/* hotplug IRQs should have been masked by pdc_sata_freeze() */
+	pdc_hard_reset_port(link->ap);
 	pdc_reset_port(link->ap);
-	return sata_sff_hardreset(link, class, deadline);
+
+	/* sata_promise can't reliably acquire the first D2H Reg FIS
+	 * after hardreset.  Do non-waiting hardreset and request
+	 * follow-up SRST.
+	 */
+	return sata_std_hardreset(link, class, deadline);
 }
 
 static void pdc_error_handler(struct ata_port *ap)
@@ -832,14 +949,14 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
 	spin_lock(&host->lock);
 
 	/* read and clear hotplug flags for all ports */
-	if (host->ports[0]->flags & PDC_FLAG_GEN_II)
+	if (host->ports[0]->flags & PDC_FLAG_GEN_II) {
 		hotplug_offset = PDC2_SATA_PLUG_CSR;
-	else
-		hotplug_offset = PDC_SATA_PLUG_CSR;
-	hotplug_status = readl(host_mmio + hotplug_offset);
-	if (hotplug_status & 0xff)
-		writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
-	hotplug_status &= 0xff;	/* clear uninteresting bits */
+		hotplug_status = readl(host_mmio + hotplug_offset);
+		if (hotplug_status & 0xff)
+			writel(hotplug_status | 0xff, host_mmio + hotplug_offset);
+		hotplug_status &= 0xff;	/* clear uninteresting bits */
+	} else
+		hotplug_status = 0;
 
 	/* reading should also clear interrupts */
 	mask = readl(host_mmio + PDC_INT_SEQMASK);
@@ -1034,9 +1151,11 @@ static void pdc_host_init(struct ata_host *host)
 	tmp = readl(host_mmio + hotplug_offset);
 	writel(tmp | 0xff, host_mmio + hotplug_offset);
 
-	/* unmask plug/unplug ints */
 	tmp = readl(host_mmio + hotplug_offset);
-	writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
+	if (is_gen2)	/* unmask plug/unplug ints */
+		writel(tmp & ~0xff0000, host_mmio + hotplug_offset);
+	else		/* mask plug/unplug ints */
+		writel(tmp | 0xff0000, host_mmio + hotplug_offset);
 
 	/* don't initialise TBG or SLEW on 2nd generation chips */
 	if (is_gen2)
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 6b969f8..01ce241 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -641,7 +641,7 @@ static int make_rate (const hrz_dev * dev, u32 c, rounding r,
 					pre = 1;
 				break;
 			case round_nearest:
-				pre = (br+(c<<div)/2)/(c<<div);
+				pre = DIV_ROUND_CLOSEST(br, c<<div);
 				// but p must be non-zero
 				if (!pre)
 					pre = 1;
@@ -671,7 +671,7 @@ static int make_rate (const hrz_dev * dev, u32 c, rounding r,
 					pre = DIV_ROUND_UP(br, c<<div);
 					break;
 				case round_nearest:
-					pre = (br+(c<<div)/2)/(c<<div);
+					pre = DIV_ROUND_CLOSEST(br, c<<div);
 					break;
 				default: /* round_up */
 					pre = br/(c<<div);
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 9359613..307321b 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -372,7 +372,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb
 	}
 
 	snr = next_string(skb);
-	if (!str)
+	if (!snr)
 		return -EIO;
 	attn = next_string(skb);
 	if (!attn)
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 8f006f9..ee37727 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -8,6 +8,31 @@ config UEVENT_HELPER_PATH
 	  Path to uevent helper program forked by the kernel for
 	  every uevent.
 
+config DEVTMPFS
+	bool "Create a kernel maintained /dev tmpfs (EXPERIMENTAL)"
+	depends on HOTPLUG && SHMEM && TMPFS
+	help
+	  This creates a tmpfs filesystem, and mounts it at bootup
+	  and mounts it at /dev. The kernel driver core creates device
+	  nodes for all registered devices in that filesystem. All device
+	  nodes are owned by root and have the default mode of 0600.
+	  Userspace can add and delete the nodes as needed. This is
+	  intended to simplify bootup, and make it possible to delay
+	  the initial coldplug at bootup done by udev in userspace.
+	  It should also provide a simpler way for rescue systems
+	  to bring up a kernel with dynamic major/minor numbers.
+	  Meaningful symlinks, permissions and device ownership must
+	  still be handled by userspace.
+	  If unsure, say N here.
+
+config DEVTMPFS_MOUNT
+	bool "Automount devtmpfs at /dev"
+	depends on DEVTMPFS
+	help
+	  This will mount devtmpfs at /dev if the kernel mounts the root
+	  filesystem. It will not affect initramfs based mounting.
+	  If unsure, say N here.
+
 config STANDALONE
 	bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
 	default y
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index b5b8ba5..c12c7f2 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -4,8 +4,10 @@ obj-y			:= core.o sys.o bus.o dd.o \
 			   driver.o class.o platform.o \
 			   cpu.o firmware.o init.o map.o devres.o \
 			   attribute_container.o transport_class.o
+obj-$(CONFIG_DEVTMPFS)	+= devtmpfs.o
 obj-y			+= power/
 obj-$(CONFIG_HAS_DMA)	+= dma-mapping.o
+obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
 obj-$(CONFIG_ISA)	+= isa.o
 obj-$(CONFIG_FW_LOADER)	+= firmware_class.o
 obj-$(CONFIG_NUMA)	+= node.o
diff --git a/drivers/base/base.h b/drivers/base/base.h
index b528145..2ca7f5b 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -70,6 +70,8 @@ struct class_private {
  * @knode_parent - node in sibling list
  * @knode_driver - node in driver list
  * @knode_bus - node in bus list
+ * @driver_data - private pointer for driver specific info.  Will turn into a
+ * list soon.
  * @device - pointer back to the struct class that this structure is
  * associated with.
  *
@@ -80,6 +82,7 @@ struct device_private {
 	struct klist_node knode_parent;
 	struct klist_node knode_driver;
 	struct klist_node knode_bus;
+	void *driver_data;
 	struct device *device;
 };
 #define to_device_private_parent(obj)	\
@@ -89,6 +92,8 @@ struct device_private {
 #define to_device_private_bus(obj)	\
 	container_of(obj, struct device_private, knode_bus)
 
+extern int device_private_init(struct device *dev);
+
 /* initialisation functions */
 extern int devices_init(void);
 extern int buses_init(void);
@@ -104,7 +109,7 @@ extern int system_bus_init(void);
 extern int cpu_dev_init(void);
 
 extern int bus_add_device(struct device *dev);
-extern void bus_attach_device(struct device *dev);
+extern void bus_probe_device(struct device *dev);
 extern void bus_remove_device(struct device *dev);
 
 extern int bus_add_driver(struct device_driver *drv);
@@ -134,3 +139,9 @@ static inline void module_add_driver(struct module *mod,
 				     struct device_driver *drv) { }
 static inline void module_remove_driver(struct device_driver *drv) { }
 #endif
+
+#ifdef CONFIG_DEVTMPFS
+extern int devtmpfs_init(void);
+#else
+static inline int devtmpfs_init(void) { return 0; }
+#endif
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 4b04a15..973bf2a 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -459,8 +459,9 @@ static inline void remove_deprecated_bus_links(struct device *dev) { }
  * bus_add_device - add device to bus
  * @dev: device being added
  *
+ * - Add device's bus attributes.
+ * - Create links to device's bus.
  * - Add the device to its bus's list of devices.
- * - Create link to device's bus.
  */
 int bus_add_device(struct device *dev)
 {
@@ -483,6 +484,7 @@ int bus_add_device(struct device *dev)
 		error = make_deprecated_bus_links(dev);
 		if (error)
 			goto out_deprecated;
+		klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
 	}
 	return 0;
 
@@ -498,24 +500,19 @@ out_put:
 }
 
 /**
- * bus_attach_device - add device to bus
- * @dev: device tried to attach to a driver
+ * bus_probe_device - probe drivers for a new device
+ * @dev: device to probe
  *
- * - Add device to bus's list of devices.
- * - Try to attach to driver.
+ * - Automatically probe for a driver if the bus allows it.
  */
-void bus_attach_device(struct device *dev)
+void bus_probe_device(struct device *dev)
 {
 	struct bus_type *bus = dev->bus;
-	int ret = 0;
+	int ret;
 
-	if (bus) {
-		if (bus->p->drivers_autoprobe)
-			ret = device_attach(dev);
+	if (bus && bus->p->drivers_autoprobe) {
+		ret = device_attach(dev);
 		WARN_ON(ret < 0);
-		if (ret >= 0)
-			klist_add_tail(&dev->p->knode_bus,
-				       &bus->p->klist_devices);
 	}
 }
 
diff --git a/drivers/base/class.c b/drivers/base/class.c
index eb85e43..161746d 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -488,6 +488,93 @@ void class_interface_unregister(struct class_interface *class_intf)
 	class_put(parent);
 }
 
+struct class_compat {
+	struct kobject *kobj;
+};
+
+/**
+ * class_compat_register - register a compatibility class
+ * @name: the name of the class
+ *
+ * Compatibility class are meant as a temporary user-space compatibility
+ * workaround when converting a family of class devices to a bus devices.
+ */
+struct class_compat *class_compat_register(const char *name)
+{
+	struct class_compat *cls;
+
+	cls = kmalloc(sizeof(struct class_compat), GFP_KERNEL);
+	if (!cls)
+		return NULL;
+	cls->kobj = kobject_create_and_add(name, &class_kset->kobj);
+	if (!cls->kobj) {
+		kfree(cls);
+		return NULL;
+	}
+	return cls;
+}
+EXPORT_SYMBOL_GPL(class_compat_register);
+
+/**
+ * class_compat_unregister - unregister a compatibility class
+ * @cls: the class to unregister
+ */
+void class_compat_unregister(struct class_compat *cls)
+{
+	kobject_put(cls->kobj);
+	kfree(cls);
+}
+EXPORT_SYMBOL_GPL(class_compat_unregister);
+
+/**
+ * class_compat_create_link - create a compatibility class device link to
+ *			      a bus device
+ * @cls: the compatibility class
+ * @dev: the target bus device
+ * @device_link: an optional device to which a "device" link should be created
+ */
+int class_compat_create_link(struct class_compat *cls, struct device *dev,
+			     struct device *device_link)
+{
+	int error;
+
+	error = sysfs_create_link(cls->kobj, &dev->kobj, dev_name(dev));
+	if (error)
+		return error;
+
+	/*
+	 * Optionally add a "device" link (typically to the parent), as a
+	 * class device would have one and we want to provide as much
+	 * backwards compatibility as possible.
+	 */
+	if (device_link) {
+		error = sysfs_create_link(&dev->kobj, &device_link->kobj,
+					  "device");
+		if (error)
+			sysfs_remove_link(cls->kobj, dev_name(dev));
+	}
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(class_compat_create_link);
+
+/**
+ * class_compat_remove_link - remove a compatibility class device link to
+ *			      a bus device
+ * @cls: the compatibility class
+ * @dev: the target bus device
+ * @device_link: an optional device to which a "device" link was previously
+ * 		 created
+ */
+void class_compat_remove_link(struct class_compat *cls, struct device *dev,
+			      struct device *device_link)
+{
+	if (device_link)
+		sysfs_remove_link(&dev->kobj, "device");
+	sysfs_remove_link(cls->kobj, dev_name(dev));
+}
+EXPORT_SYMBOL_GPL(class_compat_remove_link);
+
 int __init classes_init(void)
 {
 	class_kset = kset_create_and_add("class", NULL, NULL);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 7ecb193..6bee6af 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -166,13 +166,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj,
 	if (MAJOR(dev->devt)) {
 		const char *tmp;
 		const char *name;
+		mode_t mode = 0;
 
 		add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
 		add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
-		name = device_get_nodename(dev, &tmp);
+		name = device_get_devnode(dev, &mode, &tmp);
 		if (name) {
 			add_uevent_var(env, "DEVNAME=%s", name);
 			kfree(tmp);
+			if (mode)
+				add_uevent_var(env, "DEVMODE=%#o", mode & 0777);
 		}
 	}
 
@@ -341,7 +344,7 @@ static void device_remove_attributes(struct device *dev,
 }
 
 static int device_add_groups(struct device *dev,
-			     struct attribute_group **groups)
+			     const struct attribute_group **groups)
 {
 	int error = 0;
 	int i;
@@ -361,7 +364,7 @@ static int device_add_groups(struct device *dev,
 }
 
 static void device_remove_groups(struct device *dev,
-				 struct attribute_group **groups)
+				 const struct attribute_group **groups)
 {
 	int i;
 
@@ -843,6 +846,17 @@ static void device_remove_sys_dev_entry(struct device *dev)
 	}
 }
 
+int device_private_init(struct device *dev)
+{
+	dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
+	if (!dev->p)
+		return -ENOMEM;
+	dev->p->device = dev;
+	klist_init(&dev->p->klist_children, klist_children_get,
+		   klist_children_put);
+	return 0;
+}
+
 /**
  * device_add - add device to device hierarchy.
  * @dev: device.
@@ -868,14 +882,11 @@ int device_add(struct device *dev)
 	if (!dev)
 		goto done;
 
-	dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
 	if (!dev->p) {
-		error = -ENOMEM;
-		goto done;
+		error = device_private_init(dev);
+		if (error)
+			goto done;
 	}
-	dev->p->device = dev;
-	klist_init(&dev->p->klist_children, klist_children_get,
-		   klist_children_put);
 
 	/*
 	 * for statically allocated devices, which should all be converted
@@ -921,6 +932,8 @@ int device_add(struct device *dev)
 		error = device_create_sys_dev_entry(dev);
 		if (error)
 			goto devtattrError;
+
+		devtmpfs_create_node(dev);
 	}
 
 	error = device_add_class_symlinks(dev);
@@ -945,7 +958,7 @@ int device_add(struct device *dev)
 					     BUS_NOTIFY_ADD_DEVICE, dev);
 
 	kobject_uevent(&dev->kobj, KOBJ_ADD);
-	bus_attach_device(dev);
+	bus_probe_device(dev);
 	if (parent)
 		klist_add_tail(&dev->p->knode_parent,
 			       &parent->p->klist_children);
@@ -1067,6 +1080,7 @@ void device_del(struct device *dev)
 	if (parent)
 		klist_del(&dev->p->knode_parent);
 	if (MAJOR(dev->devt)) {
+		devtmpfs_delete_node(dev);
 		device_remove_sys_dev_entry(dev);
 		device_remove_file(dev, &devt_attr);
 	}
@@ -1137,8 +1151,9 @@ static struct device *next_device(struct klist_iter *i)
 }
 
 /**
- * device_get_nodename - path of device node file
+ * device_get_devnode - path of device node file
  * @dev: device
+ * @mode: returned file access mode
  * @tmp: possibly allocated string
  *
  * Return the relative path of a possible device node.
@@ -1146,21 +1161,22 @@ static struct device *next_device(struct klist_iter *i)
  * a name. This memory is returned in tmp and needs to be
  * freed by the caller.
  */
-const char *device_get_nodename(struct device *dev, const char **tmp)
+const char *device_get_devnode(struct device *dev,
+			       mode_t *mode, const char **tmp)
 {
 	char *s;
 
 	*tmp = NULL;
 
 	/* the device type may provide a specific name */
-	if (dev->type && dev->type->nodename)
-		*tmp = dev->type->nodename(dev);
+	if (dev->type && dev->type->devnode)
+		*tmp = dev->type->devnode(dev, mode);
 	if (*tmp)
 		return *tmp;
 
 	/* the class may provide a specific name */
-	if (dev->class && dev->class->nodename)
-		*tmp = dev->class->nodename(dev);
+	if (dev->class && dev->class->devnode)
+		*tmp = dev->class->devnode(dev, mode);
 	if (*tmp)
 		return *tmp;
 
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index f010687..979d159 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -11,8 +11,8 @@
  *
  * Copyright (c) 2002-5 Patrick Mochel
  * Copyright (c) 2002-3 Open Source Development Labs
- * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de>
- * Copyright (c) 2007 Novell Inc.
+ * Copyright (c) 2007-2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (c) 2007-2009 Novell Inc.
  *
  * This file is released under the GPLv2
  */
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/wait.h>
 #include <linux/async.h>
+#include <linux/pm_runtime.h>
 
 #include "base.h"
 #include "power/power.h"
@@ -202,7 +203,10 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
 	pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
 		 drv->bus->name, __func__, dev_name(dev), drv->name);
 
+	pm_runtime_get_noresume(dev);
+	pm_runtime_barrier(dev);
 	ret = really_probe(dev, drv);
+	pm_runtime_put_sync(dev);
 
 	return ret;
 }
@@ -245,7 +249,9 @@ int device_attach(struct device *dev)
 			ret = 0;
 		}
 	} else {
+		pm_runtime_get_noresume(dev);
 		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
+		pm_runtime_put_sync(dev);
 	}
 	up(&dev->sem);
 	return ret;
@@ -306,6 +312,9 @@ static void __device_release_driver(struct device *dev)
 
 	drv = dev->driver;
 	if (drv) {
+		pm_runtime_get_noresume(dev);
+		pm_runtime_barrier(dev);
+
 		driver_sysfs_remove(dev);
 
 		if (dev->bus)
@@ -324,6 +333,8 @@ static void __device_release_driver(struct device *dev)
 			blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
 						     BUS_NOTIFY_UNBOUND_DRIVER,
 						     dev);
+
+		pm_runtime_put_sync(dev);
 	}
 }
 
@@ -380,3 +391,30 @@ void driver_detach(struct device_driver *drv)
 		put_device(dev);
 	}
 }
+
+/*
+ * These exports can't be _GPL due to .h files using this within them, and it
+ * might break something that was previously working...
+ */
+void *dev_get_drvdata(const struct device *dev)
+{
+	if (dev && dev->p)
+		return dev->p->driver_data;
+	return NULL;
+}
+EXPORT_SYMBOL(dev_get_drvdata);
+
+void dev_set_drvdata(struct device *dev, void *data)
+{
+	int error;
+
+	if (!dev)
+		return;
+	if (!dev->p) {
+		error = device_private_init(dev);
+		if (error)
+			return;
+	}
+	dev->p->driver_data = data;
+}
+EXPORT_SYMBOL(dev_set_drvdata);
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
new file mode 100644
index 0000000..a1cb5af
--- /dev/null
+++ b/drivers/base/devtmpfs.c
@@ -0,0 +1,375 @@
+/*
+ * devtmpfs - kernel-maintained tmpfs-based /dev
+ *
+ * Copyright (C) 2009, Kay Sievers <kay.sievers@vrfy.org>
+ *
+ * During bootup, before any driver core device is registered,
+ * devtmpfs, a tmpfs-based filesystem is created. Every driver-core
+ * device which requests a device node, will add a node in this
+ * filesystem.
+ * By default, all devices are named after the the name of the
+ * device, owned by root and have a default mode of 0600. Subsystems
+ * can overwrite the default setting if needed.
+ */
+
+#include <linux/kernel.h>
+#include <linux/syscalls.h>
+#include <linux/mount.h>
+#include <linux/device.h>
+#include <linux/genhd.h>
+#include <linux/namei.h>
+#include <linux/fs.h>
+#include <linux/shmem_fs.h>
+#include <linux/cred.h>
+#include <linux/sched.h>
+#include <linux/init_task.h>
+
+static struct vfsmount *dev_mnt;
+
+#if defined CONFIG_DEVTMPFS_MOUNT
+static int dev_mount = 1;
+#else
+static int dev_mount;
+#endif
+
+static int __init mount_param(char *str)
+{
+	dev_mount = simple_strtoul(str, NULL, 0);
+	return 1;
+}
+__setup("devtmpfs.mount=", mount_param);
+
+static int dev_get_sb(struct file_system_type *fs_type, int flags,
+		      const char *dev_name, void *data, struct vfsmount *mnt)
+{
+	return get_sb_single(fs_type, flags, data, shmem_fill_super, mnt);
+}
+
+static struct file_system_type dev_fs_type = {
+	.name = "devtmpfs",
+	.get_sb = dev_get_sb,
+	.kill_sb = kill_litter_super,
+};
+
+#ifdef CONFIG_BLOCK
+static inline int is_blockdev(struct device *dev)
+{
+	return dev->class == &block_class;
+}
+#else
+static inline int is_blockdev(struct device *dev) { return 0; }
+#endif
+
+static int dev_mkdir(const char *name, mode_t mode)
+{
+	struct nameidata nd;
+	struct dentry *dentry;
+	int err;
+
+	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+			      name, LOOKUP_PARENT, &nd);
+	if (err)
+		return err;
+
+	dentry = lookup_create(&nd, 1);
+	if (!IS_ERR(dentry)) {
+		err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
+		dput(dentry);
+	} else {
+		err = PTR_ERR(dentry);
+	}
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+	path_put(&nd.path);
+	return err;
+}
+
+static int create_path(const char *nodepath)
+{
+	char *path;
+	struct nameidata nd;
+	int err = 0;
+
+	path = kstrdup(nodepath, GFP_KERNEL);
+	if (!path)
+		return -ENOMEM;
+
+	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+			      path, LOOKUP_PARENT, &nd);
+	if (err == 0) {
+		struct dentry *dentry;
+
+		/* create directory right away */
+		dentry = lookup_create(&nd, 1);
+		if (!IS_ERR(dentry)) {
+			err = vfs_mkdir(nd.path.dentry->d_inode,
+					dentry, 0755);
+			dput(dentry);
+		}
+		mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+		path_put(&nd.path);
+	} else if (err == -ENOENT) {
+		char *s;
+
+		/* parent directories do not exist, create them */
+		s = path;
+		while (1) {
+			s = strchr(s, '/');
+			if (!s)
+				break;
+			s[0] = '\0';
+			err = dev_mkdir(path, 0755);
+			if (err && err != -EEXIST)
+				break;
+			s[0] = '/';
+			s++;
+		}
+	}
+
+	kfree(path);
+	return err;
+}
+
+int devtmpfs_create_node(struct device *dev)
+{
+	const char *tmp = NULL;
+	const char *nodename;
+	const struct cred *curr_cred;
+	mode_t mode = 0;
+	struct nameidata nd;
+	struct dentry *dentry;
+	int err;
+
+	if (!dev_mnt)
+		return 0;
+
+	nodename = device_get_devnode(dev, &mode, &tmp);
+	if (!nodename)
+		return -ENOMEM;
+
+	if (mode == 0)
+		mode = 0600;
+	if (is_blockdev(dev))
+		mode |= S_IFBLK;
+	else
+		mode |= S_IFCHR;
+
+	curr_cred = override_creds(&init_cred);
+	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+			      nodename, LOOKUP_PARENT, &nd);
+	if (err == -ENOENT) {
+		/* create missing parent directories */
+		create_path(nodename);
+		err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+				      nodename, LOOKUP_PARENT, &nd);
+		if (err)
+			goto out;
+	}
+
+	dentry = lookup_create(&nd, 0);
+	if (!IS_ERR(dentry)) {
+		int umask;
+
+		umask = sys_umask(0000);
+		err = vfs_mknod(nd.path.dentry->d_inode,
+				dentry, mode, dev->devt);
+		sys_umask(umask);
+		/* mark as kernel created inode */
+		if (!err)
+			dentry->d_inode->i_private = &dev_mnt;
+		dput(dentry);
+	} else {
+		err = PTR_ERR(dentry);
+	}
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+	path_put(&nd.path);
+out:
+	kfree(tmp);
+	revert_creds(curr_cred);
+	return err;
+}
+
+static int dev_rmdir(const char *name)
+{
+	struct nameidata nd;
+	struct dentry *dentry;
+	int err;
+
+	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+			      name, LOOKUP_PARENT, &nd);
+	if (err)
+		return err;
+
+	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+	dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
+	if (!IS_ERR(dentry)) {
+		if (dentry->d_inode)
+			err = vfs_rmdir(nd.path.dentry->d_inode, dentry);
+		else
+			err = -ENOENT;
+		dput(dentry);
+	} else {
+		err = PTR_ERR(dentry);
+	}
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+	path_put(&nd.path);
+	return err;
+}
+
+static int delete_path(const char *nodepath)
+{
+	const char *path;
+	int err = 0;
+
+	path = kstrdup(nodepath, GFP_KERNEL);
+	if (!path)
+		return -ENOMEM;
+
+	while (1) {
+		char *base;
+
+		base = strrchr(path, '/');
+		if (!base)
+			break;
+		base[0] = '\0';
+		err = dev_rmdir(path);
+		if (err)
+			break;
+	}
+
+	kfree(path);
+	return err;
+}
+
+static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *stat)
+{
+	/* did we create it */
+	if (inode->i_private != &dev_mnt)
+		return 0;
+
+	/* does the dev_t match */
+	if (is_blockdev(dev)) {
+		if (!S_ISBLK(stat->mode))
+			return 0;
+	} else {
+		if (!S_ISCHR(stat->mode))
+			return 0;
+	}
+	if (stat->rdev != dev->devt)
+		return 0;
+
+	/* ours */
+	return 1;
+}
+
+int devtmpfs_delete_node(struct device *dev)
+{
+	const char *tmp = NULL;
+	const char *nodename;
+	const struct cred *curr_cred;
+	struct nameidata nd;
+	struct dentry *dentry;
+	struct kstat stat;
+	int deleted = 1;
+	int err;
+
+	if (!dev_mnt)
+		return 0;
+
+	nodename = device_get_devnode(dev, NULL, &tmp);
+	if (!nodename)
+		return -ENOMEM;
+
+	curr_cred = override_creds(&init_cred);
+	err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+			      nodename, LOOKUP_PARENT, &nd);
+	if (err)
+		goto out;
+
+	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+	dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
+	if (!IS_ERR(dentry)) {
+		if (dentry->d_inode) {
+			err = vfs_getattr(nd.path.mnt, dentry, &stat);
+			if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
+				err = vfs_unlink(nd.path.dentry->d_inode,
+						 dentry);
+				if (!err || err == -ENOENT)
+					deleted = 1;
+			}
+		} else {
+			err = -ENOENT;
+		}
+		dput(dentry);
+	} else {
+		err = PTR_ERR(dentry);
+	}
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+	path_put(&nd.path);
+	if (deleted && strchr(nodename, '/'))
+		delete_path(nodename);
+out:
+	kfree(tmp);
+	revert_creds(curr_cred);
+	return err;
+}
+
+/*
+ * If configured, or requested by the commandline, devtmpfs will be
+ * auto-mounted after the kernel mounted the root filesystem.
+ */
+int devtmpfs_mount(const char *mountpoint)
+{
+	struct path path;
+	int err;
+
+	if (!dev_mount)
+		return 0;
+
+	if (!dev_mnt)
+		return 0;
+
+	err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
+	if (err)
+		return err;
+	err = do_add_mount(dev_mnt, &path, 0, NULL);
+	if (err)
+		printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
+	else
+		printk(KERN_INFO "devtmpfs: mounted\n");
+	path_put(&path);
+	return err;
+}
+
+/*
+ * Create devtmpfs instance, driver-core devices will add their device
+ * nodes here.
+ */
+int __init devtmpfs_init(void)
+{
+	int err;
+	struct vfsmount *mnt;
+
+	err = register_filesystem(&dev_fs_type);
+	if (err) {
+		printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
+		       "type %i\n", err);
+		return err;
+	}
+
+	mnt = kern_mount(&dev_fs_type);
+	if (IS_ERR(mnt)) {
+		err = PTR_ERR(mnt);
+		printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
+		unregister_filesystem(&dev_fs_type);
+		return err;
+	}
+	dev_mnt = mnt;
+
+	printk(KERN_INFO "devtmpfs: initialized\n");
+	return 0;
+}
diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c
new file mode 100644
index 0000000..962a3b5
--- /dev/null
+++ b/drivers/base/dma-coherent.c
@@ -0,0 +1,176 @@
+/*
+ * Coherent per-device memory handling.
+ * Borrowed from i386
+ */
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+
+struct dma_coherent_mem {
+	void		*virt_base;
+	u32		device_base;
+	int		size;
+	int		flags;
+	unsigned long	*bitmap;
+};
+
+int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
+				dma_addr_t device_addr, size_t size, int flags)
+{
+	void __iomem *mem_base = NULL;
+	int pages = size >> PAGE_SHIFT;
+	int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
+
+	if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
+		goto out;
+	if (!size)
+		goto out;
+	if (dev->dma_mem)
+		goto out;
+
+	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
+
+	mem_base = ioremap(bus_addr, size);
+	if (!mem_base)
+		goto out;
+
+	dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
+	if (!dev->dma_mem)
+		goto out;
+	dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+	if (!dev->dma_mem->bitmap)
+		goto free1_out;
+
+	dev->dma_mem->virt_base = mem_base;
+	dev->dma_mem->device_base = device_addr;
+	dev->dma_mem->size = pages;
+	dev->dma_mem->flags = flags;
+
+	if (flags & DMA_MEMORY_MAP)
+		return DMA_MEMORY_MAP;
+
+	return DMA_MEMORY_IO;
+
+ free1_out:
+	kfree(dev->dma_mem);
+ out:
+	if (mem_base)
+		iounmap(mem_base);
+	return 0;
+}
+EXPORT_SYMBOL(dma_declare_coherent_memory);
+
+void dma_release_declared_memory(struct device *dev)
+{
+	struct dma_coherent_mem *mem = dev->dma_mem;
+
+	if (!mem)
+		return;
+	dev->dma_mem = NULL;
+	iounmap(mem->virt_base);
+	kfree(mem->bitmap);
+	kfree(mem);
+}
+EXPORT_SYMBOL(dma_release_declared_memory);
+
+void *dma_mark_declared_memory_occupied(struct device *dev,
+					dma_addr_t device_addr, size_t size)
+{
+	struct dma_coherent_mem *mem = dev->dma_mem;
+	int pos, err;
+
+	size += device_addr & ~PAGE_MASK;
+
+	if (!mem)
+		return ERR_PTR(-EINVAL);
+
+	pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
+	err = bitmap_allocate_region(mem->bitmap, pos, get_order(size));
+	if (err != 0)
+		return ERR_PTR(err);
+	return mem->virt_base + (pos << PAGE_SHIFT);
+}
+EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
+
+/**
+ * dma_alloc_from_coherent() - try to allocate memory from the per-device coherent area
+ *
+ * @dev:	device from which we allocate memory
+ * @size:	size of requested memory area
+ * @dma_handle:	This will be filled with the correct dma handle
+ * @ret:	This pointer will be filled with the virtual address
+ *		to allocated area.
+ *
+ * This function should be only called from per-arch dma_alloc_coherent()
+ * to support allocation from per-device coherent memory pools.
+ *
+ * Returns 0 if dma_alloc_coherent should continue with allocating from
+ * generic memory areas, or !0 if dma_alloc_coherent should return @ret.
+ */
+int dma_alloc_from_coherent(struct device *dev, ssize_t size,
+				       dma_addr_t *dma_handle, void **ret)
+{
+	struct dma_coherent_mem *mem;
+	int order = get_order(size);
+	int pageno;
+
+	if (!dev)
+		return 0;
+	mem = dev->dma_mem;
+	if (!mem)
+		return 0;
+
+	*ret = NULL;
+
+	if (unlikely(size > (mem->size << PAGE_SHIFT)))
+		goto err;
+
+	pageno = bitmap_find_free_region(mem->bitmap, mem->size, order);
+	if (unlikely(pageno < 0))
+		goto err;
+
+	/*
+	 * Memory was found in the per-device area.
+	 */
+	*dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
+	*ret = mem->virt_base + (pageno << PAGE_SHIFT);
+	memset(*ret, 0, size);
+
+	return 1;
+
+err:
+	/*
+	 * In the case where the allocation can not be satisfied from the
+	 * per-device area, try to fall back to generic memory if the
+	 * constraints allow it.
+	 */
+	return mem->flags & DMA_MEMORY_EXCLUSIVE;
+}
+EXPORT_SYMBOL(dma_alloc_from_coherent);
+
+/**
+ * dma_release_from_coherent() - try to free the memory allocated from per-device coherent memory pool
+ * @dev:	device from which the memory was allocated
+ * @order:	the order of pages allocated
+ * @vaddr:	virtual address of allocated pages
+ *
+ * This checks whether the memory was allocated from the per-device
+ * coherent memory pool and if so, releases that memory.
+ *
+ * Returns 1 if we correctly released the memory, or 0 if
+ * dma_release_coherent() should proceed with releasing memory from
+ * generic pools.
+ */
+int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
+{
+	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+
+	if (mem && vaddr >= mem->virt_base && vaddr <
+		   (mem->virt_base + (mem->size << PAGE_SHIFT))) {
+		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
+
+		bitmap_release_region(mem->bitmap, page, order);
+		return 1;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(dma_release_from_coherent);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 8ae0f63..ed2ebd3 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -181,7 +181,7 @@ void put_driver(struct device_driver *drv)
 EXPORT_SYMBOL_GPL(put_driver);
 
 static int driver_add_groups(struct device_driver *drv,
-			     struct attribute_group **groups)
+			     const struct attribute_group **groups)
 {
 	int error = 0;
 	int i;
@@ -201,7 +201,7 @@ static int driver_add_groups(struct device_driver *drv,
 }
 
 static void driver_remove_groups(struct device_driver *drv,
-				 struct attribute_group **groups)
+				 const struct attribute_group **groups)
 {
 	int i;
 
diff --git a/drivers/base/init.c b/drivers/base/init.c
index 7bd9b6a..c8a934e 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -20,6 +20,7 @@
 void __init driver_init(void)
 {
 	/* These are the core pieces */
+	devtmpfs_init();
 	devices_init();
 	buses_init();
 	classes_init();
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 456594b..ed156a1 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -10,6 +10,7 @@
  * information.
  */
 
+#include <linux/string.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -17,6 +18,7 @@
 #include <linux/bootmem.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 
 #include "base.h"
 
@@ -212,14 +214,13 @@ EXPORT_SYMBOL_GPL(platform_device_add_resources);
 int platform_device_add_data(struct platform_device *pdev, const void *data,
 			     size_t size)
 {
-	void *d;
+	void *d = kmemdup(data, size, GFP_KERNEL);
 
-	d = kmalloc(size, GFP_KERNEL);
 	if (d) {
-		memcpy(d, data, size);
 		pdev->dev.platform_data = d;
+		return 0;
 	}
-	return d ? 0 : -ENOMEM;
+	return -ENOMEM;
 }
 EXPORT_SYMBOL_GPL(platform_device_add_data);
 
@@ -625,30 +626,6 @@ static int platform_legacy_suspend(struct device *dev, pm_message_t mesg)
 	return ret;
 }
 
-static int platform_legacy_suspend_late(struct device *dev, pm_message_t mesg)
-{
-	struct platform_driver *pdrv = to_platform_driver(dev->driver);
-	struct platform_device *pdev = to_platform_device(dev);
-	int ret = 0;
-
-	if (dev->driver && pdrv->suspend_late)
-		ret = pdrv->suspend_late(pdev, mesg);
-
-	return ret;
-}
-
-static int platform_legacy_resume_early(struct device *dev)
-{
-	struct platform_driver *pdrv = to_platform_driver(dev->driver);
-	struct platform_device *pdev = to_platform_device(dev);
-	int ret = 0;
-
-	if (dev->driver && pdrv->resume_early)
-		ret = pdrv->resume_early(pdev);
-
-	return ret;
-}
-
 static int platform_legacy_resume(struct device *dev)
 {
 	struct platform_driver *pdrv = to_platform_driver(dev->driver);
@@ -680,6 +657,13 @@ static void platform_pm_complete(struct device *dev)
 		drv->pm->complete(dev);
 }
 
+#else /* !CONFIG_PM_SLEEP */
+
+#define platform_pm_prepare		NULL
+#define platform_pm_complete		NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
 #ifdef CONFIG_SUSPEND
 
 static int platform_pm_suspend(struct device *dev)
@@ -711,8 +695,6 @@ static int platform_pm_suspend_noirq(struct device *dev)
 	if (drv->pm) {
 		if (drv->pm->suspend_noirq)
 			ret = drv->pm->suspend_noirq(dev);
-	} else {
-		ret = platform_legacy_suspend_late(dev, PMSG_SUSPEND);
 	}
 
 	return ret;
@@ -747,8 +729,6 @@ static int platform_pm_resume_noirq(struct device *dev)
 	if (drv->pm) {
 		if (drv->pm->resume_noirq)
 			ret = drv->pm->resume_noirq(dev);
-	} else {
-		ret = platform_legacy_resume_early(dev);
 	}
 
 	return ret;
@@ -794,8 +774,6 @@ static int platform_pm_freeze_noirq(struct device *dev)
 	if (drv->pm) {
 		if (drv->pm->freeze_noirq)
 			ret = drv->pm->freeze_noirq(dev);
-	} else {
-		ret = platform_legacy_suspend_late(dev, PMSG_FREEZE);
 	}
 
 	return ret;
@@ -830,8 +808,6 @@ static int platform_pm_thaw_noirq(struct device *dev)
 	if (drv->pm) {
 		if (drv->pm->thaw_noirq)
 			ret = drv->pm->thaw_noirq(dev);
-	} else {
-		ret = platform_legacy_resume_early(dev);
 	}
 
 	return ret;
@@ -866,8 +842,6 @@ static int platform_pm_poweroff_noirq(struct device *dev)
 	if (drv->pm) {
 		if (drv->pm->poweroff_noirq)
 			ret = drv->pm->poweroff_noirq(dev);
-	} else {
-		ret = platform_legacy_suspend_late(dev, PMSG_HIBERNATE);
 	}
 
 	return ret;
@@ -902,8 +876,6 @@ static int platform_pm_restore_noirq(struct device *dev)
 	if (drv->pm) {
 		if (drv->pm->restore_noirq)
 			ret = drv->pm->restore_noirq(dev);
-	} else {
-		ret = platform_legacy_resume_early(dev);
 	}
 
 	return ret;
@@ -922,7 +894,32 @@ static int platform_pm_restore_noirq(struct device *dev)
 
 #endif /* !CONFIG_HIBERNATION */
 
-static struct dev_pm_ops platform_dev_pm_ops = {
+#ifdef CONFIG_PM_RUNTIME
+
+int __weak platform_pm_runtime_suspend(struct device *dev)
+{
+	return -ENOSYS;
+};
+
+int __weak platform_pm_runtime_resume(struct device *dev)
+{
+	return -ENOSYS;
+};
+
+int __weak platform_pm_runtime_idle(struct device *dev)
+{
+	return -ENOSYS;
+};
+
+#else /* !CONFIG_PM_RUNTIME */
+
+#define platform_pm_runtime_suspend NULL
+#define platform_pm_runtime_resume NULL
+#define platform_pm_runtime_idle NULL
+
+#endif /* !CONFIG_PM_RUNTIME */
+
+static const struct dev_pm_ops platform_dev_pm_ops = {
 	.prepare = platform_pm_prepare,
 	.complete = platform_pm_complete,
 	.suspend = platform_pm_suspend,
@@ -937,22 +934,17 @@ static struct dev_pm_ops platform_dev_pm_ops = {
 	.thaw_noirq = platform_pm_thaw_noirq,
 	.poweroff_noirq = platform_pm_poweroff_noirq,
 	.restore_noirq = platform_pm_restore_noirq,
+	.runtime_suspend = platform_pm_runtime_suspend,
+	.runtime_resume = platform_pm_runtime_resume,
+	.runtime_idle = platform_pm_runtime_idle,
 };
 
-#define PLATFORM_PM_OPS_PTR	(&platform_dev_pm_ops)
-
-#else /* !CONFIG_PM_SLEEP */
-
-#define PLATFORM_PM_OPS_PTR	NULL
-
-#endif /* !CONFIG_PM_SLEEP */
-
 struct bus_type platform_bus_type = {
 	.name		= "platform",
 	.dev_attrs	= platform_dev_attrs,
 	.match		= platform_match,
 	.uevent		= platform_uevent,
-	.pm		= PLATFORM_PM_OPS_PTR,
+	.pm		= &platform_dev_pm_ops,
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
 
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 911208b..3ce3519 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_PM)	+= sysfs.o
 obj-$(CONFIG_PM_SLEEP)	+= main.o
+obj-$(CONFIG_PM_RUNTIME)	+= runtime.o
 obj-$(CONFIG_PM_TRACE_RTC)	+= trace.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 58a3e57..e0dc407 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -21,6 +21,7 @@
 #include <linux/kallsyms.h>
 #include <linux/mutex.h>
 #include <linux/pm.h>
+#include <linux/pm_runtime.h>
 #include <linux/resume-trace.h>
 #include <linux/rwsem.h>
 #include <linux/interrupt.h>
@@ -49,7 +50,17 @@ static DEFINE_MUTEX(dpm_list_mtx);
 static bool transition_started;
 
 /**
- *	device_pm_lock - lock the list of active devices used by the PM core
+ * device_pm_init - Initialize the PM-related part of a device object.
+ * @dev: Device object being initialized.
+ */
+void device_pm_init(struct device *dev)
+{
+	dev->power.status = DPM_ON;
+	pm_runtime_init(dev);
+}
+
+/**
+ * device_pm_lock - Lock the list of active devices used by the PM core.
  */
 void device_pm_lock(void)
 {
@@ -57,7 +68,7 @@ void device_pm_lock(void)
 }
 
 /**
- *	device_pm_unlock - unlock the list of active devices used by the PM core
+ * device_pm_unlock - Unlock the list of active devices used by the PM core.
  */
 void device_pm_unlock(void)
 {
@@ -65,8 +76,8 @@ void device_pm_unlock(void)
 }
 
 /**
- *	device_pm_add - add a device to the list of active devices
- *	@dev:	Device to be added to the list
+ * device_pm_add - Add a device to the PM core's list of active devices.
+ * @dev: Device to add to the list.
  */
 void device_pm_add(struct device *dev)
 {
@@ -92,10 +103,8 @@ void device_pm_add(struct device *dev)
 }
 
 /**
- *	device_pm_remove - remove a device from the list of active devices
- *	@dev:	Device to be removed from the list
- *
- *	This function also removes the device's PM-related sysfs attributes.
+ * device_pm_remove - Remove a device from the PM core's list of active devices.
+ * @dev: Device to be removed from the list.
  */
 void device_pm_remove(struct device *dev)
 {
@@ -105,12 +114,13 @@ void device_pm_remove(struct device *dev)
 	mutex_lock(&dpm_list_mtx);
 	list_del_init(&dev->power.entry);
 	mutex_unlock(&dpm_list_mtx);
+	pm_runtime_remove(dev);
 }
 
 /**
- *	device_pm_move_before - move device in dpm_list
- *	@deva:  Device to move in dpm_list
- *	@devb:  Device @deva should come before
+ * device_pm_move_before - Move device in the PM core's list of active devices.
+ * @deva: Device to move in dpm_list.
+ * @devb: Device @deva should come before.
  */
 void device_pm_move_before(struct device *deva, struct device *devb)
 {
@@ -124,9 +134,9 @@ void device_pm_move_before(struct device *deva, struct device *devb)
 }
 
 /**
- *	device_pm_move_after - move device in dpm_list
- *	@deva:  Device to move in dpm_list
- *	@devb:  Device @deva should come after
+ * device_pm_move_after - Move device in the PM core's list of active devices.
+ * @deva: Device to move in dpm_list.
+ * @devb: Device @deva should come after.
  */
 void device_pm_move_after(struct device *deva, struct device *devb)
 {
@@ -140,8 +150,8 @@ void device_pm_move_after(struct device *deva, struct device *devb)
 }
 
 /**
- * 	device_pm_move_last - move device to end of dpm_list
- * 	@dev:   Device to move in dpm_list
+ * device_pm_move_last - Move device to end of the PM core's list of devices.
+ * @dev: Device to move in dpm_list.
  */
 void device_pm_move_last(struct device *dev)
 {
@@ -152,13 +162,14 @@ void device_pm_move_last(struct device *dev)
 }
 
 /**
- *	pm_op - execute the PM operation appropiate for given PM event
- *	@dev:	Device.
- *	@ops:	PM operations to choose from.
- *	@state:	PM transition of the system being carried out.
+ * pm_op - Execute the PM operation appropriate for given PM event.
+ * @dev: Device to handle.
+ * @ops: PM operations to choose from.
+ * @state: PM transition of the system being carried out.
  */
-static int pm_op(struct device *dev, struct dev_pm_ops *ops,
-			pm_message_t state)
+static int pm_op(struct device *dev,
+		 const struct dev_pm_ops *ops,
+		 pm_message_t state)
 {
 	int error = 0;
 
@@ -212,15 +223,16 @@ static int pm_op(struct device *dev, struct dev_pm_ops *ops,
 }
 
 /**
- *	pm_noirq_op - execute the PM operation appropiate for given PM event
- *	@dev:	Device.
- *	@ops:	PM operations to choose from.
- *	@state: PM transition of the system being carried out.
+ * pm_noirq_op - Execute the PM operation appropriate for given PM event.
+ * @dev: Device to handle.
+ * @ops: PM operations to choose from.
+ * @state: PM transition of the system being carried out.
  *
- *	The operation is executed with interrupts disabled by the only remaining
- *	functional CPU in the system.
+ * The driver of @dev will not receive interrupts while this function is being
+ * executed.
  */
-static int pm_noirq_op(struct device *dev, struct dev_pm_ops *ops,
+static int pm_noirq_op(struct device *dev,
+			const struct dev_pm_ops *ops,
 			pm_message_t state)
 {
 	int error = 0;
@@ -315,11 +327,12 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info,
 /*------------------------- Resume routines -------------------------*/
 
 /**
- *	device_resume_noirq - Power on one device (early resume).
- *	@dev:	Device.
- *	@state: PM transition of the system being carried out.
+ * device_resume_noirq - Execute an "early resume" callback for given device.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
  *
- *	Must be called with interrupts disabled.
+ * The driver of @dev will not receive interrupts while this function is being
+ * executed.
  */
 static int device_resume_noirq(struct device *dev, pm_message_t state)
 {
@@ -341,20 +354,18 @@ static int device_resume_noirq(struct device *dev, pm_message_t state)
 }
 
 /**
- *	dpm_resume_noirq - Power on all regular (non-sysdev) devices.
- *	@state: PM transition of the system being carried out.
- *
- *	Call the "noirq" resume handlers for all devices marked as
- *	DPM_OFF_IRQ and enable device drivers to receive interrupts.
+ * dpm_resume_noirq - Execute "early resume" callbacks for non-sysdev devices.
+ * @state: PM transition of the system being carried out.
  *
- *	Must be called under dpm_list_mtx.  Device drivers should not receive
- *	interrupts while it's being executed.
+ * Call the "noirq" resume handlers for all devices marked as DPM_OFF_IRQ and
+ * enable device drivers to receive interrupts.
  */
 void dpm_resume_noirq(pm_message_t state)
 {
 	struct device *dev;
 
 	mutex_lock(&dpm_list_mtx);
+	transition_started = false;
 	list_for_each_entry(dev, &dpm_list, power.entry)
 		if (dev->power.status > DPM_OFF) {
 			int error;
@@ -370,9 +381,9 @@ void dpm_resume_noirq(pm_message_t state)
 EXPORT_SYMBOL_GPL(dpm_resume_noirq);
 
 /**
- *	device_resume - Restore state for one device.
- *	@dev:	Device.
- *	@state: PM transition of the system being carried out.
+ * device_resume - Execute "resume" callbacks for given device.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
  */
 static int device_resume(struct device *dev, pm_message_t state)
 {
@@ -421,11 +432,11 @@ static int device_resume(struct device *dev, pm_message_t state)
 }
 
 /**
- *	dpm_resume - Resume every device.
- *	@state: PM transition of the system being carried out.
+ * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
+ * @state: PM transition of the system being carried out.
  *
- *	Execute the appropriate "resume" callback for all devices the status of
- *	which indicates that they are inactive.
+ * Execute the appropriate "resume" callback for all devices whose status
+ * indicates that they are suspended.
  */
 static void dpm_resume(pm_message_t state)
 {
@@ -433,7 +444,6 @@ static void dpm_resume(pm_message_t state)
 
 	INIT_LIST_HEAD(&list);
 	mutex_lock(&dpm_list_mtx);
-	transition_started = false;
 	while (!list_empty(&dpm_list)) {
 		struct device *dev = to_device(dpm_list.next);
 
@@ -462,9 +472,9 @@ static void dpm_resume(pm_message_t state)
 }
 
 /**
- *	device_complete - Complete a PM transition for given device
- *	@dev:	Device.
- *	@state: PM transition of the system being carried out.
+ * device_complete - Complete a PM transition for given device.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
  */
 static void device_complete(struct device *dev, pm_message_t state)
 {
@@ -489,11 +499,11 @@ static void device_complete(struct device *dev, pm_message_t state)
 }
 
 /**
- *	dpm_complete - Complete a PM transition for all devices.
- *	@state: PM transition of the system being carried out.
+ * dpm_complete - Complete a PM transition for all non-sysdev devices.
+ * @state: PM transition of the system being carried out.
  *
- *	Execute the ->complete() callbacks for all devices that are not marked
- *	as DPM_ON.
+ * Execute the ->complete() callbacks for all devices whose PM status is not
+ * DPM_ON (this allows new devices to be registered).
  */
 static void dpm_complete(pm_message_t state)
 {
@@ -510,6 +520,7 @@ static void dpm_complete(pm_message_t state)
 			mutex_unlock(&dpm_list_mtx);
 
 			device_complete(dev, state);
+			pm_runtime_put_noidle(dev);
 
 			mutex_lock(&dpm_list_mtx);
 		}
@@ -522,11 +533,11 @@ static void dpm_complete(pm_message_t state)
 }
 
 /**
- *	dpm_resume_end - Restore state of each device in system.
- *	@state: PM transition of the system being carried out.
+ * dpm_resume_end - Execute "resume" callbacks and complete system transition.
+ * @state: PM transition of the system being carried out.
  *
- *	Resume all the devices, unlock them all, and allow new
- *	devices to be registered once again.
+ * Execute "resume" callbacks for all devices and complete the PM transition of
+ * the system.
  */
 void dpm_resume_end(pm_message_t state)
 {
@@ -540,9 +551,11 @@ EXPORT_SYMBOL_GPL(dpm_resume_end);
 /*------------------------- Suspend routines -------------------------*/
 
 /**
- *	resume_event - return a PM message representing the resume event
- *	               corresponding to given sleep state.
- *	@sleep_state: PM message representing a sleep state.
+ * resume_event - Return a "resume" message for given "suspend" sleep state.
+ * @sleep_state: PM message representing a sleep state.
+ *
+ * Return a PM message representing the resume event corresponding to given
+ * sleep state.
  */
 static pm_message_t resume_event(pm_message_t sleep_state)
 {
@@ -559,11 +572,12 @@ static pm_message_t resume_event(pm_message_t sleep_state)
 }
 
 /**
- *	device_suspend_noirq - Shut down one device (late suspend).
- *	@dev:	Device.
- *	@state: PM transition of the system being carried out.
+ * device_suspend_noirq - Execute a "late suspend" callback for given device.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
  *
- *	This is called with interrupts off and only a single CPU running.
+ * The driver of @dev will not receive interrupts while this function is being
+ * executed.
  */
 static int device_suspend_noirq(struct device *dev, pm_message_t state)
 {
@@ -580,13 +594,11 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
 }
 
 /**
- *	dpm_suspend_noirq - Power down all regular (non-sysdev) devices.
- *	@state: PM transition of the system being carried out.
- *
- *	Prevent device drivers from receiving interrupts and call the "noirq"
- *	suspend handlers.
+ * dpm_suspend_noirq - Execute "late suspend" callbacks for non-sysdev devices.
+ * @state: PM transition of the system being carried out.
  *
- *	Must be called under dpm_list_mtx.
+ * Prevent device drivers from receiving interrupts and call the "noirq" suspend
+ * handlers for all non-sysdev devices.
  */
 int dpm_suspend_noirq(pm_message_t state)
 {
@@ -611,9 +623,9 @@ int dpm_suspend_noirq(pm_message_t state)
 EXPORT_SYMBOL_GPL(dpm_suspend_noirq);
 
 /**
- *	device_suspend - Save state of one device.
- *	@dev:	Device.
- *	@state: PM transition of the system being carried out.
+ * device_suspend - Execute "suspend" callbacks for given device.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
  */
 static int device_suspend(struct device *dev, pm_message_t state)
 {
@@ -660,10 +672,8 @@ static int device_suspend(struct device *dev, pm_message_t state)
 }
 
 /**
- *	dpm_suspend - Suspend every device.
- *	@state: PM transition of the system being carried out.
- *
- *	Execute the appropriate "suspend" callbacks for all devices.
+ * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
+ * @state: PM transition of the system being carried out.
  */
 static int dpm_suspend(pm_message_t state)
 {
@@ -697,9 +707,12 @@ static int dpm_suspend(pm_message_t state)
 }
 
 /**
- *	device_prepare - Execute the ->prepare() callback(s) for given device.
- *	@dev:	Device.
- *	@state: PM transition of the system being carried out.
+ * device_prepare - Prepare a device for system power transition.
+ * @dev: Device to handle.
+ * @state: PM transition of the system being carried out.
+ *
+ * Execute the ->prepare() callback(s) for given device.  No new children of the
+ * device may be registered after this function has returned.
  */
 static int device_prepare(struct device *dev, pm_message_t state)
 {
@@ -735,10 +748,10 @@ static int device_prepare(struct device *dev, pm_message_t state)
 }
 
 /**
- *	dpm_prepare - Prepare all devices for a PM transition.
- *	@state: PM transition of the system being carried out.
+ * dpm_prepare - Prepare all non-sysdev devices for a system PM transition.
+ * @state: PM transition of the system being carried out.
  *
- *	Execute the ->prepare() callback for all devices.
+ * Execute the ->prepare() callback(s) for all devices.
  */
 static int dpm_prepare(pm_message_t state)
 {
@@ -755,7 +768,14 @@ static int dpm_prepare(pm_message_t state)
 		dev->power.status = DPM_PREPARING;
 		mutex_unlock(&dpm_list_mtx);
 
-		error = device_prepare(dev, state);
+		pm_runtime_get_noresume(dev);
+		if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) {
+			/* Wake-up requested during system sleep transition. */
+			pm_runtime_put_noidle(dev);
+			error = -EBUSY;
+		} else {
+			error = device_prepare(dev, state);
+		}
 
 		mutex_lock(&dpm_list_mtx);
 		if (error) {
@@ -782,10 +802,11 @@ static int dpm_prepare(pm_message_t state)
 }
 
 /**
- *	dpm_suspend_start - Save state and stop all devices in system.
- *	@state: PM transition of the system being carried out.
+ * dpm_suspend_start - Prepare devices for PM transition and suspend them.
+ * @state: PM transition of the system being carried out.
  *
- *	Prepare and suspend all devices.
+ * Prepare all non-sysdev devices for system PM transition and execute "suspend"
+ * callbacks for them.
  */
 int dpm_suspend_start(pm_message_t state)
 {
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index c7cb4fc..b8fa1aa 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -1,7 +1,14 @@
-static inline void device_pm_init(struct device *dev)
-{
-	dev->power.status = DPM_ON;
-}
+#ifdef CONFIG_PM_RUNTIME
+
+extern void pm_runtime_init(struct device *dev);
+extern void pm_runtime_remove(struct device *dev);
+
+#else /* !CONFIG_PM_RUNTIME */
+
+static inline void pm_runtime_init(struct device *dev) {}
+static inline void pm_runtime_remove(struct device *dev) {}
+
+#endif /* !CONFIG_PM_RUNTIME */
 
 #ifdef CONFIG_PM_SLEEP
 
@@ -16,23 +23,33 @@ static inline struct device *to_device(struct list_head *entry)
 	return container_of(entry, struct device, power.entry);
 }
 
+extern void device_pm_init(struct device *dev);
 extern void device_pm_add(struct device *);
 extern void device_pm_remove(struct device *);
 extern void device_pm_move_before(struct device *, struct device *);
 extern void device_pm_move_after(struct device *, struct device *);
 extern void device_pm_move_last(struct device *);
 
-#else /* CONFIG_PM_SLEEP */
+#else /* !CONFIG_PM_SLEEP */
+
+static inline void device_pm_init(struct device *dev)
+{
+	pm_runtime_init(dev);
+}
+
+static inline void device_pm_remove(struct device *dev)
+{
+	pm_runtime_remove(dev);
+}
 
 static inline void device_pm_add(struct device *dev) {}
-static inline void device_pm_remove(struct device *dev) {}
 static inline void device_pm_move_before(struct device *deva,
 					 struct device *devb) {}
 static inline void device_pm_move_after(struct device *deva,
 					struct device *devb) {}
 static inline void device_pm_move_last(struct device *dev) {}
 
-#endif
+#endif /* !CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_PM
 
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
new file mode 100644
index 0000000..38556f6
--- /dev/null
+++ b/drivers/base/power/runtime.c
@@ -0,0 +1,1011 @@
+/*
+ * drivers/base/power/runtime.c - Helper functions for device run-time PM
+ *
+ * Copyright (c) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/sched.h>
+#include <linux/pm_runtime.h>
+#include <linux/jiffies.h>
+
+static int __pm_runtime_resume(struct device *dev, bool from_wq);
+static int __pm_request_idle(struct device *dev);
+static int __pm_request_resume(struct device *dev);
+
+/**
+ * pm_runtime_deactivate_timer - Deactivate given device's suspend timer.
+ * @dev: Device to handle.
+ */
+static void pm_runtime_deactivate_timer(struct device *dev)
+{
+	if (dev->power.timer_expires > 0) {
+		del_timer(&dev->power.suspend_timer);
+		dev->power.timer_expires = 0;
+	}
+}
+
+/**
+ * pm_runtime_cancel_pending - Deactivate suspend timer and cancel requests.
+ * @dev: Device to handle.
+ */
+static void pm_runtime_cancel_pending(struct device *dev)
+{
+	pm_runtime_deactivate_timer(dev);
+	/*
+	 * In case there's a request pending, make sure its work function will
+	 * return without doing anything.
+	 */
+	dev->power.request = RPM_REQ_NONE;
+}
+
+/**
+ * __pm_runtime_idle - Notify device bus type if the device can be suspended.
+ * @dev: Device to notify the bus type about.
+ *
+ * This function must be called under dev->power.lock with interrupts disabled.
+ */
+static int __pm_runtime_idle(struct device *dev)
+	__releases(&dev->power.lock) __acquires(&dev->power.lock)
+{
+	int retval = 0;
+
+	dev_dbg(dev, "__pm_runtime_idle()!\n");
+
+	if (dev->power.runtime_error)
+		retval = -EINVAL;
+	else if (dev->power.idle_notification)
+		retval = -EINPROGRESS;
+	else if (atomic_read(&dev->power.usage_count) > 0
+	    || dev->power.disable_depth > 0
+	    || dev->power.runtime_status != RPM_ACTIVE)
+		retval = -EAGAIN;
+	else if (!pm_children_suspended(dev))
+		retval = -EBUSY;
+	if (retval)
+		goto out;
+
+	if (dev->power.request_pending) {
+		/*
+		 * If an idle notification request is pending, cancel it.  Any
+		 * other pending request takes precedence over us.
+		 */
+		if (dev->power.request == RPM_REQ_IDLE) {
+			dev->power.request = RPM_REQ_NONE;
+		} else if (dev->power.request != RPM_REQ_NONE) {
+			retval = -EAGAIN;
+			goto out;
+		}
+	}
+
+	dev->power.idle_notification = true;
+
+	if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_idle) {
+		spin_unlock_irq(&dev->power.lock);
+
+		dev->bus->pm->runtime_idle(dev);
+
+		spin_lock_irq(&dev->power.lock);
+	}
+
+	dev->power.idle_notification = false;
+	wake_up_all(&dev->power.wait_queue);
+
+ out:
+	dev_dbg(dev, "__pm_runtime_idle() returns %d!\n", retval);
+
+	return retval;
+}
+
+/**
+ * pm_runtime_idle - Notify device bus type if the device can be suspended.
+ * @dev: Device to notify the bus type about.
+ */
+int pm_runtime_idle(struct device *dev)
+{
+	int retval;
+
+	spin_lock_irq(&dev->power.lock);
+	retval = __pm_runtime_idle(dev);
+	spin_unlock_irq(&dev->power.lock);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_idle);
+
+/**
+ * __pm_runtime_suspend - Carry out run-time suspend of given device.
+ * @dev: Device to suspend.
+ * @from_wq: If set, the function has been called via pm_wq.
+ *
+ * Check if the device can be suspended and run the ->runtime_suspend() callback
+ * provided by its bus type.  If another suspend has been started earlier, wait
+ * for it to finish.  If an idle notification or suspend request is pending or
+ * scheduled, cancel it.
+ *
+ * This function must be called under dev->power.lock with interrupts disabled.
+ */
+int __pm_runtime_suspend(struct device *dev, bool from_wq)
+	__releases(&dev->power.lock) __acquires(&dev->power.lock)
+{
+	struct device *parent = NULL;
+	bool notify = false;
+	int retval = 0;
+
+	dev_dbg(dev, "__pm_runtime_suspend()%s!\n",
+		from_wq ? " from workqueue" : "");
+
+ repeat:
+	if (dev->power.runtime_error) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	/* Pending resume requests take precedence over us. */
+	if (dev->power.request_pending
+	    && dev->power.request == RPM_REQ_RESUME) {
+		retval = -EAGAIN;
+		goto out;
+	}
+
+	/* Other scheduled or pending requests need to be canceled. */
+	pm_runtime_cancel_pending(dev);
+
+	if (dev->power.runtime_status == RPM_SUSPENDED)
+		retval = 1;
+	else if (dev->power.runtime_status == RPM_RESUMING
+	    || dev->power.disable_depth > 0
+	    || atomic_read(&dev->power.usage_count) > 0)
+		retval = -EAGAIN;
+	else if (!pm_children_suspended(dev))
+		retval = -EBUSY;
+	if (retval)
+		goto out;
+
+	if (dev->power.runtime_status == RPM_SUSPENDING) {
+		DEFINE_WAIT(wait);
+
+		if (from_wq) {
+			retval = -EINPROGRESS;
+			goto out;
+		}
+
+		/* Wait for the other suspend running in parallel with us. */
+		for (;;) {
+			prepare_to_wait(&dev->power.wait_queue, &wait,
+					TASK_UNINTERRUPTIBLE);
+			if (dev->power.runtime_status != RPM_SUSPENDING)
+				break;
+
+			spin_unlock_irq(&dev->power.lock);
+
+			schedule();
+
+			spin_lock_irq(&dev->power.lock);
+		}
+		finish_wait(&dev->power.wait_queue, &wait);
+		goto repeat;
+	}
+
+	dev->power.runtime_status = RPM_SUSPENDING;
+
+	if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) {
+		spin_unlock_irq(&dev->power.lock);
+
+		retval = dev->bus->pm->runtime_suspend(dev);
+
+		spin_lock_irq(&dev->power.lock);
+		dev->power.runtime_error = retval;
+	} else {
+		retval = -ENOSYS;
+	}
+
+	if (retval) {
+		dev->power.runtime_status = RPM_ACTIVE;
+		pm_runtime_cancel_pending(dev);
+		dev->power.deferred_resume = false;
+
+		if (retval == -EAGAIN || retval == -EBUSY) {
+			notify = true;
+			dev->power.runtime_error = 0;
+		}
+	} else {
+		dev->power.runtime_status = RPM_SUSPENDED;
+
+		if (dev->parent) {
+			parent = dev->parent;
+			atomic_add_unless(&parent->power.child_count, -1, 0);
+		}
+	}
+	wake_up_all(&dev->power.wait_queue);
+
+	if (dev->power.deferred_resume) {
+		dev->power.deferred_resume = false;
+		__pm_runtime_resume(dev, false);
+		retval = -EAGAIN;
+		goto out;
+	}
+
+	if (notify)
+		__pm_runtime_idle(dev);
+
+	if (parent && !parent->power.ignore_children) {
+		spin_unlock_irq(&dev->power.lock);
+
+		pm_request_idle(parent);
+
+		spin_lock_irq(&dev->power.lock);
+	}
+
+ out:
+	dev_dbg(dev, "__pm_runtime_suspend() returns %d!\n", retval);
+
+	return retval;
+}
+
+/**
+ * pm_runtime_suspend - Carry out run-time suspend of given device.
+ * @dev: Device to suspend.
+ */
+int pm_runtime_suspend(struct device *dev)
+{
+	int retval;
+
+	spin_lock_irq(&dev->power.lock);
+	retval = __pm_runtime_suspend(dev, false);
+	spin_unlock_irq(&dev->power.lock);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_suspend);
+
+/**
+ * __pm_runtime_resume - Carry out run-time resume of given device.
+ * @dev: Device to resume.
+ * @from_wq: If set, the function has been called via pm_wq.
+ *
+ * Check if the device can be woken up and run the ->runtime_resume() callback
+ * provided by its bus type.  If another resume has been started earlier, wait
+ * for it to finish.  If there's a suspend running in parallel with this
+ * function, wait for it to finish and resume the device.  Cancel any scheduled
+ * or pending requests.
+ *
+ * This function must be called under dev->power.lock with interrupts disabled.
+ */
+int __pm_runtime_resume(struct device *dev, bool from_wq)
+	__releases(&dev->power.lock) __acquires(&dev->power.lock)
+{
+	struct device *parent = NULL;
+	int retval = 0;
+
+	dev_dbg(dev, "__pm_runtime_resume()%s!\n",
+		from_wq ? " from workqueue" : "");
+
+ repeat:
+	if (dev->power.runtime_error) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	pm_runtime_cancel_pending(dev);
+
+	if (dev->power.runtime_status == RPM_ACTIVE)
+		retval = 1;
+	else if (dev->power.disable_depth > 0)
+		retval = -EAGAIN;
+	if (retval)
+		goto out;
+
+	if (dev->power.runtime_status == RPM_RESUMING
+	    || dev->power.runtime_status == RPM_SUSPENDING) {
+		DEFINE_WAIT(wait);
+
+		if (from_wq) {
+			if (dev->power.runtime_status == RPM_SUSPENDING)
+				dev->power.deferred_resume = true;
+			retval = -EINPROGRESS;
+			goto out;
+		}
+
+		/* Wait for the operation carried out in parallel with us. */
+		for (;;) {
+			prepare_to_wait(&dev->power.wait_queue, &wait,
+					TASK_UNINTERRUPTIBLE);
+			if (dev->power.runtime_status != RPM_RESUMING
+			    && dev->power.runtime_status != RPM_SUSPENDING)
+				break;
+
+			spin_unlock_irq(&dev->power.lock);
+
+			schedule();
+
+			spin_lock_irq(&dev->power.lock);
+		}
+		finish_wait(&dev->power.wait_queue, &wait);
+		goto repeat;
+	}
+
+	if (!parent && dev->parent) {
+		/*
+		 * Increment the parent's resume counter and resume it if
+		 * necessary.
+		 */
+		parent = dev->parent;
+		spin_unlock_irq(&dev->power.lock);
+
+		pm_runtime_get_noresume(parent);
+
+		spin_lock_irq(&parent->power.lock);
+		/*
+		 * We can resume if the parent's run-time PM is disabled or it
+		 * is set to ignore children.
+		 */
+		if (!parent->power.disable_depth
+		    && !parent->power.ignore_children) {
+			__pm_runtime_resume(parent, false);
+			if (parent->power.runtime_status != RPM_ACTIVE)
+				retval = -EBUSY;
+		}
+		spin_unlock_irq(&parent->power.lock);
+
+		spin_lock_irq(&dev->power.lock);
+		if (retval)
+			goto out;
+		goto repeat;
+	}
+
+	dev->power.runtime_status = RPM_RESUMING;
+
+	if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) {
+		spin_unlock_irq(&dev->power.lock);
+
+		retval = dev->bus->pm->runtime_resume(dev);
+
+		spin_lock_irq(&dev->power.lock);
+		dev->power.runtime_error = retval;
+	} else {
+		retval = -ENOSYS;
+	}
+
+	if (retval) {
+		dev->power.runtime_status = RPM_SUSPENDED;
+		pm_runtime_cancel_pending(dev);
+	} else {
+		dev->power.runtime_status = RPM_ACTIVE;
+		if (parent)
+			atomic_inc(&parent->power.child_count);
+	}
+	wake_up_all(&dev->power.wait_queue);
+
+	if (!retval)
+		__pm_request_idle(dev);
+
+ out:
+	if (parent) {
+		spin_unlock_irq(&dev->power.lock);
+
+		pm_runtime_put(parent);
+
+		spin_lock_irq(&dev->power.lock);
+	}
+
+	dev_dbg(dev, "__pm_runtime_resume() returns %d!\n", retval);
+
+	return retval;
+}
+
+/**
+ * pm_runtime_resume - Carry out run-time resume of given device.
+ * @dev: Device to suspend.
+ */
+int pm_runtime_resume(struct device *dev)
+{
+	int retval;
+
+	spin_lock_irq(&dev->power.lock);
+	retval = __pm_runtime_resume(dev, false);
+	spin_unlock_irq(&dev->power.lock);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_resume);
+
+/**
+ * pm_runtime_work - Universal run-time PM work function.
+ * @work: Work structure used for scheduling the execution of this function.
+ *
+ * Use @work to get the device object the work is to be done for, determine what
+ * is to be done and execute the appropriate run-time PM function.
+ */
+static void pm_runtime_work(struct work_struct *work)
+{
+	struct device *dev = container_of(work, struct device, power.work);
+	enum rpm_request req;
+
+	spin_lock_irq(&dev->power.lock);
+
+	if (!dev->power.request_pending)
+		goto out;
+
+	req = dev->power.request;
+	dev->power.request = RPM_REQ_NONE;
+	dev->power.request_pending = false;
+
+	switch (req) {
+	case RPM_REQ_NONE:
+		break;
+	case RPM_REQ_IDLE:
+		__pm_runtime_idle(dev);
+		break;
+	case RPM_REQ_SUSPEND:
+		__pm_runtime_suspend(dev, true);
+		break;
+	case RPM_REQ_RESUME:
+		__pm_runtime_resume(dev, true);
+		break;
+	}
+
+ out:
+	spin_unlock_irq(&dev->power.lock);
+}
+
+/**
+ * __pm_request_idle - Submit an idle notification request for given device.
+ * @dev: Device to handle.
+ *
+ * Check if the device's run-time PM status is correct for suspending the device
+ * and queue up a request to run __pm_runtime_idle() for it.
+ *
+ * This function must be called under dev->power.lock with interrupts disabled.
+ */
+static int __pm_request_idle(struct device *dev)
+{
+	int retval = 0;
+
+	if (dev->power.runtime_error)
+		retval = -EINVAL;
+	else if (atomic_read(&dev->power.usage_count) > 0
+	    || dev->power.disable_depth > 0
+	    || dev->power.runtime_status == RPM_SUSPENDED
+	    || dev->power.runtime_status == RPM_SUSPENDING)
+		retval = -EAGAIN;
+	else if (!pm_children_suspended(dev))
+		retval = -EBUSY;
+	if (retval)
+		return retval;
+
+	if (dev->power.request_pending) {
+		/* Any requests other then RPM_REQ_IDLE take precedence. */
+		if (dev->power.request == RPM_REQ_NONE)
+			dev->power.request = RPM_REQ_IDLE;
+		else if (dev->power.request != RPM_REQ_IDLE)
+			retval = -EAGAIN;
+		return retval;
+	}
+
+	dev->power.request = RPM_REQ_IDLE;
+	dev->power.request_pending = true;
+	queue_work(pm_wq, &dev->power.work);
+
+	return retval;
+}
+
+/**
+ * pm_request_idle - Submit an idle notification request for given device.
+ * @dev: Device to handle.
+ */
+int pm_request_idle(struct device *dev)
+{
+	unsigned long flags;
+	int retval;
+
+	spin_lock_irqsave(&dev->power.lock, flags);
+	retval = __pm_request_idle(dev);
+	spin_unlock_irqrestore(&dev->power.lock, flags);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_request_idle);
+
+/**
+ * __pm_request_suspend - Submit a suspend request for given device.
+ * @dev: Device to suspend.
+ *
+ * This function must be called under dev->power.lock with interrupts disabled.
+ */
+static int __pm_request_suspend(struct device *dev)
+{
+	int retval = 0;
+
+	if (dev->power.runtime_error)
+		return -EINVAL;
+
+	if (dev->power.runtime_status == RPM_SUSPENDED)
+		retval = 1;
+	else if (atomic_read(&dev->power.usage_count) > 0
+	    || dev->power.disable_depth > 0)
+		retval = -EAGAIN;
+	else if (dev->power.runtime_status == RPM_SUSPENDING)
+		retval = -EINPROGRESS;
+	else if (!pm_children_suspended(dev))
+		retval = -EBUSY;
+	if (retval < 0)
+		return retval;
+
+	pm_runtime_deactivate_timer(dev);
+
+	if (dev->power.request_pending) {
+		/*
+		 * Pending resume requests take precedence over us, but we can
+		 * overtake any other pending request.
+		 */
+		if (dev->power.request == RPM_REQ_RESUME)
+			retval = -EAGAIN;
+		else if (dev->power.request != RPM_REQ_SUSPEND)
+			dev->power.request = retval ?
+						RPM_REQ_NONE : RPM_REQ_SUSPEND;
+		return retval;
+	} else if (retval) {
+		return retval;
+	}
+
+	dev->power.request = RPM_REQ_SUSPEND;
+	dev->power.request_pending = true;
+	queue_work(pm_wq, &dev->power.work);
+
+	return 0;
+}
+
+/**
+ * pm_suspend_timer_fn - Timer function for pm_schedule_suspend().
+ * @data: Device pointer passed by pm_schedule_suspend().
+ *
+ * Check if the time is right and execute __pm_request_suspend() in that case.
+ */
+static void pm_suspend_timer_fn(unsigned long data)
+{
+	struct device *dev = (struct device *)data;
+	unsigned long flags;
+	unsigned long expires;
+
+	spin_lock_irqsave(&dev->power.lock, flags);
+
+	expires = dev->power.timer_expires;
+	/* If 'expire' is after 'jiffies' we've been called too early. */
+	if (expires > 0 && !time_after(expires, jiffies)) {
+		dev->power.timer_expires = 0;
+		__pm_request_suspend(dev);
+	}
+
+	spin_unlock_irqrestore(&dev->power.lock, flags);
+}
+
+/**
+ * pm_schedule_suspend - Set up a timer to submit a suspend request in future.
+ * @dev: Device to suspend.
+ * @delay: Time to wait before submitting a suspend request, in milliseconds.
+ */
+int pm_schedule_suspend(struct device *dev, unsigned int delay)
+{
+	unsigned long flags;
+	int retval = 0;
+
+	spin_lock_irqsave(&dev->power.lock, flags);
+
+	if (dev->power.runtime_error) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	if (!delay) {
+		retval = __pm_request_suspend(dev);
+		goto out;
+	}
+
+	pm_runtime_deactivate_timer(dev);
+
+	if (dev->power.request_pending) {
+		/*
+		 * Pending resume requests take precedence over us, but any
+		 * other pending requests have to be canceled.
+		 */
+		if (dev->power.request == RPM_REQ_RESUME) {
+			retval = -EAGAIN;
+			goto out;
+		}
+		dev->power.request = RPM_REQ_NONE;
+	}
+
+	if (dev->power.runtime_status == RPM_SUSPENDED)
+		retval = 1;
+	else if (dev->power.runtime_status == RPM_SUSPENDING)
+		retval = -EINPROGRESS;
+	else if (atomic_read(&dev->power.usage_count) > 0
+	    || dev->power.disable_depth > 0)
+		retval = -EAGAIN;
+	else if (!pm_children_suspended(dev))
+		retval = -EBUSY;
+	if (retval)
+		goto out;
+
+	dev->power.timer_expires = jiffies + msecs_to_jiffies(delay);
+	mod_timer(&dev->power.suspend_timer, dev->power.timer_expires);
+
+ out:
+	spin_unlock_irqrestore(&dev->power.lock, flags);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_schedule_suspend);
+
+/**
+ * pm_request_resume - Submit a resume request for given device.
+ * @dev: Device to resume.
+ *
+ * This function must be called under dev->power.lock with interrupts disabled.
+ */
+static int __pm_request_resume(struct device *dev)
+{
+	int retval = 0;
+
+	if (dev->power.runtime_error)
+		return -EINVAL;
+
+	if (dev->power.runtime_status == RPM_ACTIVE)
+		retval = 1;
+	else if (dev->power.runtime_status == RPM_RESUMING)
+		retval = -EINPROGRESS;
+	else if (dev->power.disable_depth > 0)
+		retval = -EAGAIN;
+	if (retval < 0)
+		return retval;
+
+	pm_runtime_deactivate_timer(dev);
+
+	if (dev->power.request_pending) {
+		/* If non-resume request is pending, we can overtake it. */
+		dev->power.request = retval ? RPM_REQ_NONE : RPM_REQ_RESUME;
+		return retval;
+	} else if (retval) {
+		return retval;
+	}
+
+	dev->power.request = RPM_REQ_RESUME;
+	dev->power.request_pending = true;
+	queue_work(pm_wq, &dev->power.work);
+
+	return retval;
+}
+
+/**
+ * pm_request_resume - Submit a resume request for given device.
+ * @dev: Device to resume.
+ */
+int pm_request_resume(struct device *dev)
+{
+	unsigned long flags;
+	int retval;
+
+	spin_lock_irqsave(&dev->power.lock, flags);
+	retval = __pm_request_resume(dev);
+	spin_unlock_irqrestore(&dev->power.lock, flags);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_request_resume);
+
+/**
+ * __pm_runtime_get - Reference count a device and wake it up, if necessary.
+ * @dev: Device to handle.
+ * @sync: If set and the device is suspended, resume it synchronously.
+ *
+ * Increment the usage count of the device and if it was zero previously,
+ * resume it or submit a resume request for it, depending on the value of @sync.
+ */
+int __pm_runtime_get(struct device *dev, bool sync)
+{
+	int retval = 1;
+
+	if (atomic_add_return(1, &dev->power.usage_count) == 1)
+		retval = sync ? pm_runtime_resume(dev) : pm_request_resume(dev);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(__pm_runtime_get);
+
+/**
+ * __pm_runtime_put - Decrement the device's usage counter and notify its bus.
+ * @dev: Device to handle.
+ * @sync: If the device's bus type is to be notified, do that synchronously.
+ *
+ * Decrement the usage count of the device and if it reaches zero, carry out a
+ * synchronous idle notification or submit an idle notification request for it,
+ * depending on the value of @sync.
+ */
+int __pm_runtime_put(struct device *dev, bool sync)
+{
+	int retval = 0;
+
+	if (atomic_dec_and_test(&dev->power.usage_count))
+		retval = sync ? pm_runtime_idle(dev) : pm_request_idle(dev);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(__pm_runtime_put);
+
+/**
+ * __pm_runtime_set_status - Set run-time PM status of a device.
+ * @dev: Device to handle.
+ * @status: New run-time PM status of the device.
+ *
+ * If run-time PM of the device is disabled or its power.runtime_error field is
+ * different from zero, the status may be changed either to RPM_ACTIVE, or to
+ * RPM_SUSPENDED, as long as that reflects the actual state of the device.
+ * However, if the device has a parent and the parent is not active, and the
+ * parent's power.ignore_children flag is unset, the device's status cannot be
+ * set to RPM_ACTIVE, so -EBUSY is returned in that case.
+ *
+ * If successful, __pm_runtime_set_status() clears the power.runtime_error field
+ * and the device parent's counter of unsuspended children is modified to
+ * reflect the new status.  If the new status is RPM_SUSPENDED, an idle
+ * notification request for the parent is submitted.
+ */
+int __pm_runtime_set_status(struct device *dev, unsigned int status)
+{
+	struct device *parent = dev->parent;
+	unsigned long flags;
+	bool notify_parent = false;
+	int error = 0;
+
+	if (status != RPM_ACTIVE && status != RPM_SUSPENDED)
+		return -EINVAL;
+
+	spin_lock_irqsave(&dev->power.lock, flags);
+
+	if (!dev->power.runtime_error && !dev->power.disable_depth) {
+		error = -EAGAIN;
+		goto out;
+	}
+
+	if (dev->power.runtime_status == status)
+		goto out_set;
+
+	if (status == RPM_SUSPENDED) {
+		/* It always is possible to set the status to 'suspended'. */
+		if (parent) {
+			atomic_add_unless(&parent->power.child_count, -1, 0);
+			notify_parent = !parent->power.ignore_children;
+		}
+		goto out_set;
+	}
+
+	if (parent) {
+		spin_lock_irq(&parent->power.lock);
+
+		/*
+		 * It is invalid to put an active child under a parent that is
+		 * not active, has run-time PM enabled and the
+		 * 'power.ignore_children' flag unset.
+		 */
+		if (!parent->power.disable_depth
+		    && !parent->power.ignore_children
+		    && parent->power.runtime_status != RPM_ACTIVE) {
+			error = -EBUSY;
+		} else {
+			if (dev->power.runtime_status == RPM_SUSPENDED)
+				atomic_inc(&parent->power.child_count);
+		}
+
+		spin_unlock_irq(&parent->power.lock);
+
+		if (error)
+			goto out;
+	}
+
+ out_set:
+	dev->power.runtime_status = status;
+	dev->power.runtime_error = 0;
+ out:
+	spin_unlock_irqrestore(&dev->power.lock, flags);
+
+	if (notify_parent)
+		pm_request_idle(parent);
+
+	return error;
+}
+EXPORT_SYMBOL_GPL(__pm_runtime_set_status);
+
+/**
+ * __pm_runtime_barrier - Cancel pending requests and wait for completions.
+ * @dev: Device to handle.
+ *
+ * Flush all pending requests for the device from pm_wq and wait for all
+ * run-time PM operations involving the device in progress to complete.
+ *
+ * Should be called under dev->power.lock with interrupts disabled.
+ */
+static void __pm_runtime_barrier(struct device *dev)
+{
+	pm_runtime_deactivate_timer(dev);
+
+	if (dev->power.request_pending) {
+		dev->power.request = RPM_REQ_NONE;
+		spin_unlock_irq(&dev->power.lock);
+
+		cancel_work_sync(&dev->power.work);
+
+		spin_lock_irq(&dev->power.lock);
+		dev->power.request_pending = false;
+	}
+
+	if (dev->power.runtime_status == RPM_SUSPENDING
+	    || dev->power.runtime_status == RPM_RESUMING
+	    || dev->power.idle_notification) {
+		DEFINE_WAIT(wait);
+
+		/* Suspend, wake-up or idle notification in progress. */
+		for (;;) {
+			prepare_to_wait(&dev->power.wait_queue, &wait,
+					TASK_UNINTERRUPTIBLE);
+			if (dev->power.runtime_status != RPM_SUSPENDING
+			    && dev->power.runtime_status != RPM_RESUMING
+			    && !dev->power.idle_notification)
+				break;
+			spin_unlock_irq(&dev->power.lock);
+
+			schedule();
+
+			spin_lock_irq(&dev->power.lock);
+		}
+		finish_wait(&dev->power.wait_queue, &wait);
+	}
+}
+
+/**
+ * pm_runtime_barrier - Flush pending requests and wait for completions.
+ * @dev: Device to handle.
+ *
+ * Prevent the device from being suspended by incrementing its usage counter and
+ * if there's a pending resume request for the device, wake the device up.
+ * Next, make sure that all pending requests for the device have been flushed
+ * from pm_wq and wait for all run-time PM operations involving the device in
+ * progress to complete.
+ *
+ * Return value:
+ * 1, if there was a resume request pending and the device had to be woken up,
+ * 0, otherwise
+ */
+int pm_runtime_barrier(struct device *dev)
+{
+	int retval = 0;
+
+	pm_runtime_get_noresume(dev);
+	spin_lock_irq(&dev->power.lock);
+
+	if (dev->power.request_pending
+	    && dev->power.request == RPM_REQ_RESUME) {
+		__pm_runtime_resume(dev, false);
+		retval = 1;
+	}
+
+	__pm_runtime_barrier(dev);
+
+	spin_unlock_irq(&dev->power.lock);
+	pm_runtime_put_noidle(dev);
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(pm_runtime_barrier);
+
+/**
+ * __pm_runtime_disable - Disable run-time PM of a device.
+ * @dev: Device to handle.
+ * @check_resume: If set, check if there's a resume request for the device.
+ *
+ * Increment power.disable_depth for the device and if was zero previously,
+ * cancel all pending run-time PM requests for the device and wait for all
+ * operations in progress to complete.  The device can be either active or
+ * suspended after its run-time PM has been disabled.
+ *
+ * If @check_resume is set and there's a resume request pending when
+ * __pm_runtime_disable() is called and power.disable_depth is zero, the
+ * function will wake up the device before disabling its run-time PM.
+ */
+void __pm_runtime_disable(struct device *dev, bool check_resume)
+{
+	spin_lock_irq(&dev->power.lock);
+
+	if (dev->power.disable_depth > 0) {
+		dev->power.disable_depth++;
+		goto out;
+	}
+
+	/*
+	 * Wake up the device if there's a resume request pending, because that
+	 * means there probably is some I/O to process and disabling run-time PM
+	 * shouldn't prevent the device from processing the I/O.
+	 */
+	if (check_resume && dev->power.request_pending
+	    && dev->power.request == RPM_REQ_RESUME) {
+		/*
+		 * Prevent suspends and idle notifications from being carried
+		 * out after we have woken up the device.
+		 */
+		pm_runtime_get_noresume(dev);
+
+		__pm_runtime_resume(dev, false);
+
+		pm_runtime_put_noidle(dev);
+	}
+
+	if (!dev->power.disable_depth++)
+		__pm_runtime_barrier(dev);
+
+ out:
+	spin_unlock_irq(&dev->power.lock);
+}
+EXPORT_SYMBOL_GPL(__pm_runtime_disable);
+
+/**
+ * pm_runtime_enable - Enable run-time PM of a device.
+ * @dev: Device to handle.
+ */
+void pm_runtime_enable(struct device *dev)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->power.lock, flags);
+
+	if (dev->power.disable_depth > 0)
+		dev->power.disable_depth--;
+	else
+		dev_warn(dev, "Unbalanced %s!\n", __func__);
+
+	spin_unlock_irqrestore(&dev->power.lock, flags);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_enable);
+
+/**
+ * pm_runtime_init - Initialize run-time PM fields in given device object.
+ * @dev: Device object to initialize.
+ */
+void pm_runtime_init(struct device *dev)
+{
+	spin_lock_init(&dev->power.lock);
+
+	dev->power.runtime_status = RPM_SUSPENDED;
+	dev->power.idle_notification = false;
+
+	dev->power.disable_depth = 1;
+	atomic_set(&dev->power.usage_count, 0);
+
+	dev->power.runtime_error = 0;
+
+	atomic_set(&dev->power.child_count, 0);
+	pm_suspend_ignore_children(dev, false);
+
+	dev->power.request_pending = false;
+	dev->power.request = RPM_REQ_NONE;
+	dev->power.deferred_resume = false;
+	INIT_WORK(&dev->power.work, pm_runtime_work);
+
+	dev->power.timer_expires = 0;
+	setup_timer(&dev->power.suspend_timer, pm_suspend_timer_fn,
+			(unsigned long)dev);
+
+	init_waitqueue_head(&dev->power.wait_queue);
+}
+
+/**
+ * pm_runtime_remove - Prepare for removing a device from device hierarchy.
+ * @dev: Device object being removed from device hierarchy.
+ */
+void pm_runtime_remove(struct device *dev)
+{
+	__pm_runtime_disable(dev, false);
+
+	/* Change the status back to 'suspended' to match the initial status. */
+	if (dev->power.runtime_status == RPM_ACTIVE)
+		pm_runtime_set_suspended(dev);
+}
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 95d3449..b6cd571 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -172,6 +172,9 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
 		BUG();
 		bio_endio(bio, -ENXIO);
 		return 0;
+	} else if (bio_rw_flagged(bio, BIO_RW_BARRIER)) {
+		bio_endio(bio, -EOPNOTSUPP);
+		return 0;
 	} else if (bio->bi_io_vec == NULL) {
 		printk(KERN_ERR "aoe: bi_io_vec is NULL\n");
 		BUG();
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 1988835..62141ec 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -266,7 +266,7 @@ static const struct file_operations aoe_fops = {
 	.owner = THIS_MODULE,
 };
 
-static char *aoe_nodename(struct device *dev)
+static char *aoe_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "etherd/%s", dev_name(dev));
 }
@@ -288,7 +288,7 @@ aoechr_init(void)
 		unregister_chrdev(AOE_MAJOR, "aoechr");
 		return PTR_ERR(aoe_class);
 	}
-	aoe_class->nodename = aoe_nodename;
+	aoe_class->devnode = aoe_devnode;
 
 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
 		device_create(aoe_class, NULL,
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index a52cc7f..d8372b4 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -572,7 +572,7 @@ static struct attribute_group cciss_dev_attr_group = {
 	.attrs = cciss_dev_attrs,
 };
 
-static struct attribute_group *cciss_dev_attr_groups[] = {
+static const struct attribute_group *cciss_dev_attr_groups[] = {
 	&cciss_dev_attr_group,
 	NULL
 };
@@ -3889,7 +3889,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 	int j = 0;
 	int rc;
 	int dac, return_code;
-	InquiryData_struct *inq_buff = NULL;
+	InquiryData_struct *inq_buff;
 
 	if (reset_devices) {
 		/* Reset the controller with a PCI power-cycle */
@@ -4029,6 +4029,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 		printk(KERN_WARNING "cciss: unable to determine firmware"
 			" version of controller\n");
 	}
+	kfree(inq_buff);
 
 	cciss_procinit(i);
 
@@ -4045,7 +4046,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 	return 1;
 
 clean4:
-	kfree(inq_buff);
 	kfree(hba[i]->cmd_pool_bits);
 	if (hba[i]->cmd_pool)
 		pci_free_consistent(hba[i]->pdev,
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 91b7530..2b387c2 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4151,7 +4151,7 @@ static void floppy_device_release(struct device *dev)
 {
 }
 
-static int floppy_resume(struct platform_device *dev)
+static int floppy_resume(struct device *dev)
 {
 	int fdc;
 
@@ -4162,10 +4162,15 @@ static int floppy_resume(struct platform_device *dev)
 	return 0;
 }
 
-static struct platform_driver floppy_driver = {
+static struct dev_pm_ops floppy_pm_ops = {
 	.resume = floppy_resume,
+	.restore = floppy_resume,
+};
+
+static struct platform_driver floppy_driver = {
 	.driver = {
 		.name = "floppy",
+		.pm = &floppy_pm_ops,
 	},
 };
 
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 5757188..bbb7944 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -475,7 +475,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
 	pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset;
 
 	if (bio_rw(bio) == WRITE) {
-		int barrier = bio_barrier(bio);
+		bool barrier = bio_rw_flagged(bio, BIO_RW_BARRIER);
 		struct file *file = lo->lo_backing_file;
 
 		if (barrier) {
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 911dfd9..9f3518c 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -219,8 +219,6 @@ static int pcd_sector;		/* address of next requested sector */
 static int pcd_count;		/* number of blocks still to do */
 static char *pcd_buf;		/* buffer for request in progress */
 
-static int pcd_warned;		/* Have we logged a phase warning ? */
-
 /* kernel glue structures */
 
 static int pcd_block_open(struct block_device *bdev, fmode_t mode)
@@ -417,12 +415,10 @@ static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
 					printk
 					    ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
 					     cd->name, fun, p, d, k);
-				if ((verbose < 2) && !pcd_warned) {
-					pcd_warned = 1;
-					printk
-					    ("%s: WARNING: ATAPI phase errors\n",
-					     cd->name);
-				}
+				if (verbose < 2)
+					printk_once(
+					    "%s: WARNING: ATAPI phase errors\n",
+					    cd->name);
 				mdelay(1);
 			}
 			if (k++ > PCD_TMO) {
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 99a506f..fd5bb8a 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -92,7 +92,7 @@ static struct mutex ctl_mutex;	/* Serialize open/close/setup/teardown */
 static mempool_t *psd_pool;
 
 static struct class	*class_pktcdvd = NULL;    /* /sys/class/pktcdvd */
-static struct dentry	*pkt_debugfs_root = NULL; /* /debug/pktcdvd */
+static struct dentry	*pkt_debugfs_root = NULL; /* /sys/kernel/debug/pktcdvd */
 
 /* forward declaration */
 static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev);
@@ -2857,7 +2857,7 @@ static struct block_device_operations pktcdvd_ops = {
 	.media_changed =	pkt_media_changed,
 };
 
-static char *pktcdvd_nodename(struct gendisk *gd)
+static char *pktcdvd_devnode(struct gendisk *gd, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "pktcdvd/%s", gd->disk_name);
 }
@@ -2914,7 +2914,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
 	disk->fops = &pktcdvd_ops;
 	disk->flags = GENHD_FL_REMOVABLE;
 	strcpy(disk->disk_name, pd->name);
-	disk->nodename = pktcdvd_nodename;
+	disk->devnode = pktcdvd_devnode;
 	disk->private_data = pd;
 	disk->queue = blk_alloc_queue(GFP_KERNEL);
 	if (!disk->queue)
@@ -3070,7 +3070,7 @@ static const struct file_operations pkt_ctl_fops = {
 static struct miscdevice pkt_misc = {
 	.minor 		= MISC_DYNAMIC_MINOR,
 	.name  		= DRIVER_NAME,
-	.name  		= "pktcdvd/control",
+	.nodename	= "pktcdvd/control",
 	.fops  		= &pkt_ctl_fops
 };
 
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 095f97e..c8753a9 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -13,8 +13,8 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
+#include <asm/cell-regs.h>
 #include <asm/firmware.h>
-#include <asm/iommu.h>
 #include <asm/lv1call.h>
 #include <asm/ps3.h>
 #include <asm/ps3gpu.h>
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index da403b6..f5cd2e8 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -1564,15 +1564,13 @@ static int carm_init_shm(struct carm_host *host)
 
 static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	static unsigned int printed_version;
 	struct carm_host *host;
 	unsigned int pci_dac;
 	int rc;
 	struct request_queue *q;
 	unsigned int i;
 
-	if (!printed_version++)
-		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+	printk_once(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
 
 	rc = pci_enable_device(pdev);
 	if (rc)
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 390d69b..b441ce3 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -416,15 +416,9 @@ retry:
 		goto retry;
 	}
 	if (we.max_disk > (MAX_DISKNO - 1)) {
-		static int warned;
-
-		if (warned == 0) {
-			warned++;
-			printk(VIOD_KERN_INFO
-				"Only examining the first %d "
-				"of %d disks connected\n",
-				MAX_DISKNO, we.max_disk + 1);
-		}
+		printk_once(VIOD_KERN_INFO
+			"Only examining the first %d of %d disks connected\n",
+			MAX_DISKNO, we.max_disk + 1);
 	}
 
 	/* Send the close event to OS/400.  We DON'T expect a response */
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 1164837..652367a 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -170,5 +170,30 @@ config BT_HCIVHCI
 	  Say Y here to compile support for virtual HCI devices into the
 	  kernel or say M to compile it as module (hci_vhci).
 
+config BT_MRVL
+	tristate "Marvell Bluetooth driver support"
+	help
+	  The core driver to support Marvell Bluetooth devices.
+
+	  This driver is required if you want to support
+	  Marvell Bluetooth devices, such as 8688.
+
+	  Say Y here to compile Marvell Bluetooth driver
+	  into the kernel or say M to compile it as module.
+
+config BT_MRVL_SDIO
+	tristate "Marvell BT-over-SDIO driver"
+	depends on BT_MRVL && MMC
+	select FW_LOADER
+	help
+	  The driver for Marvell Bluetooth chipsets with SDIO interface.
+
+	  This driver is required if you want to use Marvell Bluetooth
+	  devices with SDIO interface. Currently only SD8688 chipset is
+	  supported.
+
+	  Say Y here to compile support for Marvell BT-over-SDIO driver
+	  into the kernel or say M to compile it as module.
+
 endmenu
 
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 16930f9..b3f57d2 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -15,6 +15,12 @@ obj-$(CONFIG_BT_HCIBTUART)	+= btuart_cs.o
 obj-$(CONFIG_BT_HCIBTUSB)	+= btusb.o
 obj-$(CONFIG_BT_HCIBTSDIO)	+= btsdio.o
 
+obj-$(CONFIG_BT_MRVL)		+= btmrvl.o
+obj-$(CONFIG_BT_MRVL_SDIO)	+= btmrvl_sdio.o
+
+btmrvl-y			:= btmrvl_main.o
+btmrvl-$(CONFIG_DEBUG_FS)	+= btmrvl_debugfs.o
+
 hci_uart-y				:= hci_ldisc.o
 hci_uart-$(CONFIG_BT_HCIUART_H4)	+= hci_h4.o
 hci_uart-$(CONFIG_BT_HCIUART_BCSP)	+= hci_bcsp.o
diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c
new file mode 100644
index 0000000..4617bd1
--- /dev/null
+++ b/drivers/bluetooth/btmrvl_debugfs.c
@@ -0,0 +1,432 @@
+/**
+ * Marvell Bluetooth driver: debugfs related functions
+ *
+ * Copyright (C) 2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ **/
+
+#include <linux/debugfs.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "btmrvl_drv.h"
+
+struct btmrvl_debugfs_data {
+	struct dentry *root_dir, *config_dir, *status_dir;
+
+	/* config */
+	struct dentry *drvdbg;
+	struct dentry *psmode;
+	struct dentry *pscmd;
+	struct dentry *hsmode;
+	struct dentry *hscmd;
+	struct dentry *gpiogap;
+	struct dentry *hscfgcmd;
+
+	/* status */
+	struct dentry *curpsmode;
+	struct dentry *hsstate;
+	struct dentry *psstate;
+	struct dentry *txdnldready;
+};
+
+static int btmrvl_open_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t btmrvl_hscfgcmd_write(struct file *file,
+			const char __user *ubuf, size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	long result, ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	ret = strict_strtol(buf, 10, &result);
+
+	priv->btmrvl_dev.hscfgcmd = result;
+
+	if (priv->btmrvl_dev.hscfgcmd) {
+		btmrvl_prepare_command(priv);
+		wake_up_interruptible(&priv->main_thread.wait_q);
+	}
+
+	return count;
+}
+
+static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
+						priv->btmrvl_dev.hscfgcmd);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_hscfgcmd_fops = {
+	.read	= btmrvl_hscfgcmd_read,
+	.write	= btmrvl_hscfgcmd_write,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	long result, ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	ret = strict_strtol(buf, 10, &result);
+
+	priv->btmrvl_dev.psmode = result;
+
+	return count;
+}
+
+static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
+						priv->btmrvl_dev.psmode);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_psmode_fops = {
+	.read	= btmrvl_psmode_read,
+	.write	= btmrvl_psmode_write,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	long result, ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	ret = strict_strtol(buf, 10, &result);
+
+	priv->btmrvl_dev.pscmd = result;
+
+	if (priv->btmrvl_dev.pscmd) {
+		btmrvl_prepare_command(priv);
+		wake_up_interruptible(&priv->main_thread.wait_q);
+	}
+
+	return count;
+
+}
+
+static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.pscmd);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_pscmd_fops = {
+	.read = btmrvl_pscmd_read,
+	.write = btmrvl_pscmd_write,
+	.open = btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	long result, ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	ret = strict_strtol(buf, 16, &result);
+
+	priv->btmrvl_dev.gpio_gap = result;
+
+	return count;
+}
+
+static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "0x%x\n",
+						priv->btmrvl_dev.gpio_gap);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_gpiogap_fops = {
+	.read	= btmrvl_gpiogap_read,
+	.write	= btmrvl_gpiogap_write,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data;
+	char buf[16];
+	long result, ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	ret = strict_strtol(buf, 10, &result);
+
+	priv->btmrvl_dev.hscmd = result;
+	if (priv->btmrvl_dev.hscmd) {
+		btmrvl_prepare_command(priv);
+		wake_up_interruptible(&priv->main_thread.wait_q);
+	}
+
+	return count;
+}
+
+static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hscmd);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_hscmd_fops = {
+	.read	= btmrvl_hscmd_read,
+	.write	= btmrvl_hscmd_write,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	long result, ret;
+
+	memset(buf, 0, sizeof(buf));
+
+	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
+		return -EFAULT;
+
+	ret = strict_strtol(buf, 10, &result);
+
+	priv->btmrvl_dev.hsmode = result;
+
+	return count;
+}
+
+static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->btmrvl_dev.hsmode);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_hsmode_fops = {
+	.read	= btmrvl_hsmode_read,
+	.write	= btmrvl_hsmode_write,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->psmode);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_curpsmode_fops = {
+	.read	= btmrvl_curpsmode_read,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->ps_state);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_psstate_fops = {
+	.read	= btmrvl_psstate_read,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n", priv->adapter->hs_state);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_hsstate_fops = {
+	.read	= btmrvl_hsstate_read,
+	.open	= btmrvl_open_generic,
+};
+
+static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf,
+						size_t count, loff_t *ppos)
+{
+	struct btmrvl_private *priv = file->private_data;
+	char buf[16];
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf) - 1, "%d\n",
+					priv->btmrvl_dev.tx_dnld_rdy);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, ret);
+}
+
+static const struct file_operations btmrvl_txdnldready_fops = {
+	.read	= btmrvl_txdnldready_read,
+	.open	= btmrvl_open_generic,
+};
+
+void btmrvl_debugfs_init(struct hci_dev *hdev)
+{
+	struct btmrvl_private *priv = hdev->driver_data;
+	struct btmrvl_debugfs_data *dbg;
+
+	dbg = kzalloc(sizeof(*dbg), GFP_KERNEL);
+	priv->debugfs_data = dbg;
+
+	if (!dbg) {
+		BT_ERR("Can not allocate memory for btmrvl_debugfs_data.");
+		return;
+	}
+
+	dbg->root_dir = debugfs_create_dir("btmrvl", NULL);
+
+	dbg->config_dir = debugfs_create_dir("config", dbg->root_dir);
+
+	dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir,
+				hdev->driver_data, &btmrvl_psmode_fops);
+	dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir,
+				hdev->driver_data, &btmrvl_pscmd_fops);
+	dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir,
+				hdev->driver_data, &btmrvl_gpiogap_fops);
+	dbg->hsmode =  debugfs_create_file("hsmode", 0644, dbg->config_dir,
+				hdev->driver_data, &btmrvl_hsmode_fops);
+	dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir,
+				hdev->driver_data, &btmrvl_hscmd_fops);
+	dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
+				hdev->driver_data, &btmrvl_hscfgcmd_fops);
+
+	dbg->status_dir = debugfs_create_dir("status", dbg->root_dir);
+	dbg->curpsmode = debugfs_create_file("curpsmode", 0444,
+						dbg->status_dir,
+						hdev->driver_data,
+						&btmrvl_curpsmode_fops);
+	dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir,
+				hdev->driver_data, &btmrvl_psstate_fops);
+	dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir,
+				hdev->driver_data, &btmrvl_hsstate_fops);
+	dbg->txdnldready = debugfs_create_file("txdnldready", 0444,
+						dbg->status_dir,
+						hdev->driver_data,
+						&btmrvl_txdnldready_fops);
+}
+
+void btmrvl_debugfs_remove(struct hci_dev *hdev)
+{
+	struct btmrvl_private *priv = hdev->driver_data;
+	struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
+
+	if (!dbg)
+		return;
+
+	debugfs_remove(dbg->psmode);
+	debugfs_remove(dbg->pscmd);
+	debugfs_remove(dbg->gpiogap);
+	debugfs_remove(dbg->hsmode);
+	debugfs_remove(dbg->hscmd);
+	debugfs_remove(dbg->hscfgcmd);
+	debugfs_remove(dbg->config_dir);
+
+	debugfs_remove(dbg->curpsmode);
+	debugfs_remove(dbg->psstate);
+	debugfs_remove(dbg->hsstate);
+	debugfs_remove(dbg->txdnldready);
+	debugfs_remove(dbg->status_dir);
+
+	debugfs_remove(dbg->root_dir);
+
+	kfree(dbg);
+}
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
new file mode 100644
index 0000000..411c7a7
--- /dev/null
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -0,0 +1,139 @@
+/*
+ * Marvell Bluetooth driver: global definitions & declarations
+ *
+ * Copyright (C) 2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ *
+ */
+
+#include <linux/kthread.h>
+#include <linux/bitops.h>
+#include <net/bluetooth/bluetooth.h>
+
+#define BTM_HEADER_LEN			4
+#define BTM_UPLD_SIZE			2312
+
+/* Time to wait until Host Sleep state change in millisecond */
+#define WAIT_UNTIL_HS_STATE_CHANGED	5000
+/* Time to wait for command response in millisecond */
+#define WAIT_UNTIL_CMD_RESP		5000
+
+struct btmrvl_thread {
+	struct task_struct *task;
+	wait_queue_head_t wait_q;
+	void *priv;
+};
+
+struct btmrvl_device {
+	void *card;
+	struct hci_dev *hcidev;
+
+	u8 tx_dnld_rdy;
+
+	u8 psmode;
+	u8 pscmd;
+	u8 hsmode;
+	u8 hscmd;
+
+	/* Low byte is gap, high byte is GPIO */
+	u16 gpio_gap;
+
+	u8 hscfgcmd;
+	u8 sendcmdflag;
+};
+
+struct btmrvl_adapter {
+	u32 int_count;
+	struct sk_buff_head tx_queue;
+	u8 psmode;
+	u8 ps_state;
+	u8 hs_state;
+	u8 wakeup_tries;
+	wait_queue_head_t cmd_wait_q;
+	u8 cmd_complete;
+};
+
+struct btmrvl_private {
+	struct btmrvl_device btmrvl_dev;
+	struct btmrvl_adapter *adapter;
+	struct btmrvl_thread main_thread;
+	int (*hw_host_to_card) (struct btmrvl_private *priv,
+				u8 *payload, u16 nb);
+	int (*hw_wakeup_firmware) (struct btmrvl_private *priv);
+	spinlock_t driver_lock;		/* spinlock used by driver */
+#ifdef CONFIG_DEBUG_FS
+	void *debugfs_data;
+#endif
+};
+
+#define MRVL_VENDOR_PKT			0xFE
+
+/* Bluetooth commands  */
+#define BT_CMD_AUTO_SLEEP_MODE		0x23
+#define BT_CMD_HOST_SLEEP_CONFIG	0x59
+#define BT_CMD_HOST_SLEEP_ENABLE	0x5A
+#define BT_CMD_MODULE_CFG_REQ		0x5B
+
+/* Sub-commands: Module Bringup/Shutdown Request */
+#define MODULE_BRINGUP_REQ		0xF1
+#define MODULE_SHUTDOWN_REQ		0xF2
+
+#define BT_EVENT_POWER_STATE		0x20
+
+/* Bluetooth Power States */
+#define BT_PS_ENABLE			0x02
+#define BT_PS_DISABLE			0x03
+#define BT_PS_SLEEP			0x01
+
+#define OGF				0x3F
+
+/* Host Sleep states */
+#define HS_ACTIVATED			0x01
+#define HS_DEACTIVATED			0x00
+
+/* Power Save modes */
+#define PS_SLEEP			0x01
+#define PS_AWAKE			0x00
+
+struct btmrvl_cmd {
+	__le16 ocf_ogf;
+	u8 length;
+	u8 data[4];
+} __attribute__ ((packed));
+
+struct btmrvl_event {
+	u8 ec;		/* event counter */
+	u8 length;
+	u8 data[4];
+} __attribute__ ((packed));
+
+/* Prototype of global function */
+
+struct btmrvl_private *btmrvl_add_card(void *card);
+int btmrvl_remove_card(struct btmrvl_private *priv);
+
+void btmrvl_interrupt(struct btmrvl_private *priv);
+
+void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb);
+int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb);
+
+int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd);
+int btmrvl_prepare_command(struct btmrvl_private *priv);
+
+#ifdef CONFIG_DEBUG_FS
+void btmrvl_debugfs_init(struct hci_dev *hdev);
+void btmrvl_debugfs_remove(struct hci_dev *hdev);
+#endif
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
new file mode 100644
index 0000000..e605563
--- /dev/null
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -0,0 +1,624 @@
+/**
+ * Marvell Bluetooth driver
+ *
+ * Copyright (C) 2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ **/
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "btmrvl_drv.h"
+
+#define VERSION "1.0"
+
+/*
+ * This function is called by interface specific interrupt handler.
+ * It updates Power Save & Host Sleep states, and wakes up the main
+ * thread.
+ */
+void btmrvl_interrupt(struct btmrvl_private *priv)
+{
+	priv->adapter->ps_state = PS_AWAKE;
+
+	priv->adapter->wakeup_tries = 0;
+
+	priv->adapter->int_count++;
+
+	wake_up_interruptible(&priv->main_thread.wait_q);
+}
+EXPORT_SYMBOL_GPL(btmrvl_interrupt);
+
+void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
+{
+	struct hci_event_hdr *hdr = (void *) skb->data;
+	struct hci_ev_cmd_complete *ec;
+	u16 opcode, ocf;
+
+	if (hdr->evt == HCI_EV_CMD_COMPLETE) {
+		ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
+		opcode = __le16_to_cpu(ec->opcode);
+		ocf = hci_opcode_ocf(opcode);
+		if (ocf == BT_CMD_MODULE_CFG_REQ &&
+					priv->btmrvl_dev.sendcmdflag) {
+			priv->btmrvl_dev.sendcmdflag = false;
+			priv->adapter->cmd_complete = true;
+			wake_up_interruptible(&priv->adapter->cmd_wait_q);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt);
+
+int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
+{
+	struct btmrvl_adapter *adapter = priv->adapter;
+	struct btmrvl_event *event;
+	u8 ret = 0;
+
+	event = (struct btmrvl_event *) skb->data;
+	if (event->ec != 0xff) {
+		BT_DBG("Not Marvell Event=%x", event->ec);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	switch (event->data[0]) {
+	case BT_CMD_AUTO_SLEEP_MODE:
+		if (!event->data[2]) {
+			if (event->data[1] == BT_PS_ENABLE)
+				adapter->psmode = 1;
+			else
+				adapter->psmode = 0;
+			BT_DBG("PS Mode:%s",
+				(adapter->psmode) ? "Enable" : "Disable");
+		} else {
+			BT_DBG("PS Mode command failed");
+		}
+		break;
+
+	case BT_CMD_HOST_SLEEP_CONFIG:
+		if (!event->data[3])
+			BT_DBG("gpio=%x, gap=%x", event->data[1],
+							event->data[2]);
+		else
+			BT_DBG("HSCFG command failed");
+		break;
+
+	case BT_CMD_HOST_SLEEP_ENABLE:
+		if (!event->data[1]) {
+			adapter->hs_state = HS_ACTIVATED;
+			if (adapter->psmode)
+				adapter->ps_state = PS_SLEEP;
+			wake_up_interruptible(&adapter->cmd_wait_q);
+			BT_DBG("HS ACTIVATED!");
+		} else {
+			BT_DBG("HS Enable failed");
+		}
+		break;
+
+	case BT_CMD_MODULE_CFG_REQ:
+		if (priv->btmrvl_dev.sendcmdflag &&
+				event->data[1] == MODULE_BRINGUP_REQ) {
+			BT_DBG("EVENT:%s", (event->data[2]) ?
+				"Bring-up failed" : "Bring-up succeed");
+		} else if (priv->btmrvl_dev.sendcmdflag &&
+				event->data[1] == MODULE_SHUTDOWN_REQ) {
+			BT_DBG("EVENT:%s", (event->data[2]) ?
+				"Shutdown failed" : "Shutdown succeed");
+		} else {
+			BT_DBG("BT_CMD_MODULE_CFG_REQ resp for APP");
+			ret = -EINVAL;
+		}
+		break;
+
+	case BT_EVENT_POWER_STATE:
+		if (event->data[1] == BT_PS_SLEEP)
+			adapter->ps_state = PS_SLEEP;
+		BT_DBG("EVENT:%s",
+			(adapter->ps_state) ? "PS_SLEEP" : "PS_AWAKE");
+		break;
+
+	default:
+		BT_DBG("Unknown Event=%d", event->data[0]);
+		ret = -EINVAL;
+		break;
+	}
+
+exit:
+	if (!ret)
+		kfree_skb(skb);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(btmrvl_process_event);
+
+int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
+{
+	struct sk_buff *skb;
+	struct btmrvl_cmd *cmd;
+	int ret = 0;
+
+	skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+	if (skb == NULL) {
+		BT_ERR("No free skb");
+		return -ENOMEM;
+	}
+
+	cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+	cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_MODULE_CFG_REQ));
+	cmd->length = 1;
+	cmd->data[0] = subcmd;
+
+	bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+
+	skb->dev = (void *) priv->btmrvl_dev.hcidev;
+	skb_queue_head(&priv->adapter->tx_queue, skb);
+
+	priv->btmrvl_dev.sendcmdflag = true;
+
+	priv->adapter->cmd_complete = false;
+
+	BT_DBG("Queue module cfg Command");
+
+	wake_up_interruptible(&priv->main_thread.wait_q);
+
+	if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
+				priv->adapter->cmd_complete,
+				msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) {
+		ret = -ETIMEDOUT;
+		BT_ERR("module_cfg_cmd(%x): timeout: %d",
+					subcmd, priv->btmrvl_dev.sendcmdflag);
+	}
+
+	BT_DBG("module cfg Command done");
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
+
+static int btmrvl_enable_hs(struct btmrvl_private *priv)
+{
+	struct sk_buff *skb;
+	struct btmrvl_cmd *cmd;
+	int ret = 0;
+
+	skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+	if (skb == NULL) {
+		BT_ERR("No free skb");
+		return -ENOMEM;
+	}
+
+	cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+	cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_ENABLE));
+	cmd->length = 0;
+
+	bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+
+	skb->dev = (void *) priv->btmrvl_dev.hcidev;
+	skb_queue_head(&priv->adapter->tx_queue, skb);
+
+	BT_DBG("Queue hs enable Command");
+
+	wake_up_interruptible(&priv->main_thread.wait_q);
+
+	if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
+			priv->adapter->hs_state,
+			msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED))) {
+		ret = -ETIMEDOUT;
+		BT_ERR("timeout: %d, %d,%d", priv->adapter->hs_state,
+						priv->adapter->ps_state,
+						priv->adapter->wakeup_tries);
+	}
+
+	return ret;
+}
+
+int btmrvl_prepare_command(struct btmrvl_private *priv)
+{
+	struct sk_buff *skb = NULL;
+	struct btmrvl_cmd *cmd;
+	int ret = 0;
+
+	if (priv->btmrvl_dev.hscfgcmd) {
+		priv->btmrvl_dev.hscfgcmd = 0;
+
+		skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+		if (skb == NULL) {
+			BT_ERR("No free skb");
+			return -ENOMEM;
+		}
+
+		cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+		cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_CONFIG));
+		cmd->length = 2;
+		cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
+		cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
+
+		bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+
+		skb->dev = (void *) priv->btmrvl_dev.hcidev;
+		skb_queue_head(&priv->adapter->tx_queue, skb);
+
+		BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x",
+						cmd->data[0], cmd->data[1]);
+	}
+
+	if (priv->btmrvl_dev.pscmd) {
+		priv->btmrvl_dev.pscmd = 0;
+
+		skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+		if (skb == NULL) {
+			BT_ERR("No free skb");
+			return -ENOMEM;
+		}
+
+		cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+		cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_AUTO_SLEEP_MODE));
+		cmd->length = 1;
+
+		if (priv->btmrvl_dev.psmode)
+			cmd->data[0] = BT_PS_ENABLE;
+		else
+			cmd->data[0] = BT_PS_DISABLE;
+
+		bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+
+		skb->dev = (void *) priv->btmrvl_dev.hcidev;
+		skb_queue_head(&priv->adapter->tx_queue, skb);
+
+		BT_DBG("Queue PSMODE Command:%d", cmd->data[0]);
+	}
+
+	if (priv->btmrvl_dev.hscmd) {
+		priv->btmrvl_dev.hscmd = 0;
+
+		if (priv->btmrvl_dev.hsmode) {
+			ret = btmrvl_enable_hs(priv);
+		} else {
+			ret = priv->hw_wakeup_firmware(priv);
+			priv->adapter->hs_state = HS_DEACTIVATED;
+		}
+	}
+
+	return ret;
+}
+
+static int btmrvl_tx_pkt(struct btmrvl_private *priv, struct sk_buff *skb)
+{
+	int ret = 0;
+
+	if (!skb || !skb->data)
+		return -EINVAL;
+
+	if (!skb->len || ((skb->len + BTM_HEADER_LEN) > BTM_UPLD_SIZE)) {
+		BT_ERR("Tx Error: Bad skb length %d : %d",
+						skb->len, BTM_UPLD_SIZE);
+		return -EINVAL;
+	}
+
+	if (skb_headroom(skb) < BTM_HEADER_LEN) {
+		struct sk_buff *tmp = skb;
+
+		skb = skb_realloc_headroom(skb, BTM_HEADER_LEN);
+		if (!skb) {
+			BT_ERR("Tx Error: realloc_headroom failed %d",
+				BTM_HEADER_LEN);
+			skb = tmp;
+			return -EINVAL;
+		}
+
+		kfree_skb(tmp);
+	}
+
+	skb_push(skb, BTM_HEADER_LEN);
+
+	/* header type: byte[3]
+	 * HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor
+	 * header length: byte[2][1][0]
+	 */
+
+	skb->data[0] = (skb->len & 0x0000ff);
+	skb->data[1] = (skb->len & 0x00ff00) >> 8;
+	skb->data[2] = (skb->len & 0xff0000) >> 16;
+	skb->data[3] = bt_cb(skb)->pkt_type;
+
+	if (priv->hw_host_to_card)
+		ret = priv->hw_host_to_card(priv, skb->data, skb->len);
+
+	return ret;
+}
+
+static void btmrvl_init_adapter(struct btmrvl_private *priv)
+{
+	skb_queue_head_init(&priv->adapter->tx_queue);
+
+	priv->adapter->ps_state = PS_AWAKE;
+
+	init_waitqueue_head(&priv->adapter->cmd_wait_q);
+}
+
+static void btmrvl_free_adapter(struct btmrvl_private *priv)
+{
+	skb_queue_purge(&priv->adapter->tx_queue);
+
+	kfree(priv->adapter);
+
+	priv->adapter = NULL;
+}
+
+static int btmrvl_ioctl(struct hci_dev *hdev,
+				unsigned int cmd, unsigned long arg)
+{
+	return -ENOIOCTLCMD;
+}
+
+static void btmrvl_destruct(struct hci_dev *hdev)
+{
+}
+
+static int btmrvl_send_frame(struct sk_buff *skb)
+{
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct btmrvl_private *priv = NULL;
+
+	BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
+
+	if (!hdev || !hdev->driver_data) {
+		BT_ERR("Frame for unknown HCI device");
+		return -ENODEV;
+	}
+
+	priv = (struct btmrvl_private *) hdev->driver_data;
+	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
+		BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
+		print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
+							skb->data, skb->len);
+		return -EBUSY;
+	}
+
+	switch (bt_cb(skb)->pkt_type) {
+	case HCI_COMMAND_PKT:
+		hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		hdev->stat.acl_tx++;
+		break;
+
+	case HCI_SCODATA_PKT:
+		hdev->stat.sco_tx++;
+		break;
+	}
+
+	skb_queue_tail(&priv->adapter->tx_queue, skb);
+
+	wake_up_interruptible(&priv->main_thread.wait_q);
+
+	return 0;
+}
+
+static int btmrvl_flush(struct hci_dev *hdev)
+{
+	struct btmrvl_private *priv = hdev->driver_data;
+
+	skb_queue_purge(&priv->adapter->tx_queue);
+
+	return 0;
+}
+
+static int btmrvl_close(struct hci_dev *hdev)
+{
+	struct btmrvl_private *priv = hdev->driver_data;
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	skb_queue_purge(&priv->adapter->tx_queue);
+
+	return 0;
+}
+
+static int btmrvl_open(struct hci_dev *hdev)
+{
+	set_bit(HCI_RUNNING, &hdev->flags);
+
+	return 0;
+}
+
+/*
+ * This function handles the event generated by firmware, rx data
+ * received from firmware, and tx data sent from kernel.
+ */
+static int btmrvl_service_main_thread(void *data)
+{
+	struct btmrvl_thread *thread = data;
+	struct btmrvl_private *priv = thread->priv;
+	struct btmrvl_adapter *adapter = priv->adapter;
+	wait_queue_t wait;
+	struct sk_buff *skb;
+	ulong flags;
+
+	init_waitqueue_entry(&wait, current);
+
+	current->flags |= PF_NOFREEZE;
+
+	for (;;) {
+		add_wait_queue(&thread->wait_q, &wait);
+
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (adapter->wakeup_tries ||
+				((!adapter->int_count) &&
+				(!priv->btmrvl_dev.tx_dnld_rdy ||
+				skb_queue_empty(&adapter->tx_queue)))) {
+			BT_DBG("main_thread is sleeping...");
+			schedule();
+		}
+
+		set_current_state(TASK_RUNNING);
+
+		remove_wait_queue(&thread->wait_q, &wait);
+
+		BT_DBG("main_thread woke up");
+
+		if (kthread_should_stop()) {
+			BT_DBG("main_thread: break from main thread");
+			break;
+		}
+
+		spin_lock_irqsave(&priv->driver_lock, flags);
+		if (adapter->int_count) {
+			adapter->int_count = 0;
+		} else if (adapter->ps_state == PS_SLEEP &&
+					!skb_queue_empty(&adapter->tx_queue)) {
+			spin_unlock_irqrestore(&priv->driver_lock, flags);
+			adapter->wakeup_tries++;
+			priv->hw_wakeup_firmware(priv);
+			continue;
+		}
+		spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+		if (adapter->ps_state == PS_SLEEP)
+			continue;
+
+		if (!priv->btmrvl_dev.tx_dnld_rdy)
+			continue;
+
+		skb = skb_dequeue(&adapter->tx_queue);
+		if (skb) {
+			if (btmrvl_tx_pkt(priv, skb))
+				priv->btmrvl_dev.hcidev->stat.err_tx++;
+			else
+				priv->btmrvl_dev.hcidev->stat.byte_tx += skb->len;
+
+			kfree_skb(skb);
+		}
+	}
+
+	return 0;
+}
+
+struct btmrvl_private *btmrvl_add_card(void *card)
+{
+	struct hci_dev *hdev = NULL;
+	struct btmrvl_private *priv;
+	int ret;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		BT_ERR("Can not allocate priv");
+		goto err_priv;
+	}
+
+	priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL);
+	if (!priv->adapter) {
+		BT_ERR("Allocate buffer for btmrvl_adapter failed!");
+		goto err_adapter;
+	}
+
+	btmrvl_init_adapter(priv);
+
+	hdev = hci_alloc_dev();
+	if (!hdev) {
+		BT_ERR("Can not allocate HCI device");
+		goto err_hdev;
+	}
+
+	BT_DBG("Starting kthread...");
+	priv->main_thread.priv = priv;
+	spin_lock_init(&priv->driver_lock);
+
+	init_waitqueue_head(&priv->main_thread.wait_q);
+	priv->main_thread.task = kthread_run(btmrvl_service_main_thread,
+				&priv->main_thread, "btmrvl_main_service");
+
+	priv->btmrvl_dev.hcidev = hdev;
+	priv->btmrvl_dev.card = card;
+
+	hdev->driver_data = priv;
+
+	priv->btmrvl_dev.tx_dnld_rdy = true;
+
+	hdev->type = HCI_SDIO;
+	hdev->open = btmrvl_open;
+	hdev->close = btmrvl_close;
+	hdev->flush = btmrvl_flush;
+	hdev->send = btmrvl_send_frame;
+	hdev->destruct = btmrvl_destruct;
+	hdev->ioctl = btmrvl_ioctl;
+	hdev->owner = THIS_MODULE;
+
+	ret = hci_register_dev(hdev);
+	if (ret < 0) {
+		BT_ERR("Can not register HCI device");
+		goto err_hci_register_dev;
+	}
+
+#ifdef CONFIG_DEBUG_FS
+	btmrvl_debugfs_init(hdev);
+#endif
+
+	return priv;
+
+err_hci_register_dev:
+	/* Stop the thread servicing the interrupts */
+	kthread_stop(priv->main_thread.task);
+
+	hci_free_dev(hdev);
+
+err_hdev:
+	btmrvl_free_adapter(priv);
+
+err_adapter:
+	kfree(priv);
+
+err_priv:
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(btmrvl_add_card);
+
+int btmrvl_remove_card(struct btmrvl_private *priv)
+{
+	struct hci_dev *hdev;
+
+	hdev = priv->btmrvl_dev.hcidev;
+
+	wake_up_interruptible(&priv->adapter->cmd_wait_q);
+
+	kthread_stop(priv->main_thread.task);
+
+#ifdef CONFIG_DEBUG_FS
+	btmrvl_debugfs_remove(hdev);
+#endif
+
+	hci_unregister_dev(hdev);
+
+	hci_free_dev(hdev);
+
+	priv->btmrvl_dev.hcidev = NULL;
+
+	btmrvl_free_adapter(priv);
+
+	kfree(priv);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btmrvl_remove_card);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell Bluetooth driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
new file mode 100644
index 0000000..5b33b85
--- /dev/null
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -0,0 +1,1003 @@
+/**
+ * Marvell BT-over-SDIO driver: SDIO interface related functions.
+ *
+ * Copyright (C) 2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ **/
+
+#include <linux/firmware.h>
+
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "btmrvl_drv.h"
+#include "btmrvl_sdio.h"
+
+#define VERSION "1.0"
+
+/* The btmrvl_sdio_remove() callback function is called
+ * when user removes this module from kernel space or ejects
+ * the card from the slot. The driver handles these 2 cases
+ * differently.
+ * If the user is removing the module, a MODULE_SHUTDOWN_REQ
+ * command is sent to firmware and interrupt will be disabled.
+ * If the card is removed, there is no need to send command
+ * or disable interrupt.
+ *
+ * The variable 'user_rmmod' is used to distinguish these two
+ * scenarios. This flag is initialized as FALSE in case the card
+ * is removed, and will be set to TRUE for module removal when
+ * module_exit function is called.
+ */
+static u8 user_rmmod;
+
+static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
+	.helper		= "sd8688_helper.bin",
+	.firmware	= "sd8688.bin",
+};
+
+static const struct sdio_device_id btmrvl_sdio_ids[] = {
+	/* Marvell SD8688 Bluetooth device */
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
+			.driver_data = (unsigned long) &btmrvl_sdio_sd6888 },
+
+	{ }	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(sdio, btmrvl_sdio_ids);
+
+static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card)
+{
+	u8 reg;
+	int ret;
+
+	reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret);
+	if (!ret)
+		card->rx_unit = reg;
+
+	return ret;
+}
+
+static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
+{
+	u8 fws0, fws1;
+	int ret;
+
+	*dat = 0;
+
+	fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret);
+
+	if (!ret)
+		fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
+
+	if (ret)
+		return -EIO;
+
+	*dat = (((u16) fws1) << 8) | fws0;
+
+	return 0;
+}
+
+static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
+{
+	u8 reg;
+	int ret;
+
+	reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret);
+	if (!ret)
+		*dat = (u16) reg << card->rx_unit;
+
+	return ret;
+}
+
+static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card,
+								u8 mask)
+{
+	int ret;
+
+	sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret);
+	if (ret) {
+		BT_ERR("Unable to enable the host interrupt!");
+		ret = -EIO;
+	}
+
+	return ret;
+}
+
+static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
+								u8 mask)
+{
+	u8 host_int_mask;
+	int ret;
+
+	host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret);
+	if (ret)
+		return -EIO;
+
+	host_int_mask &= ~mask;
+
+	sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret);
+	if (ret < 0) {
+		BT_ERR("Unable to disable the host interrupt!");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
+{
+	unsigned int tries;
+	u8 status;
+	int ret;
+
+	for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
+		status = sdio_readb(card->func, CARD_STATUS_REG, &ret);
+		if (ret)
+			goto failed;
+		if ((status & bits) == bits)
+			return ret;
+
+		udelay(1);
+	}
+
+	ret = -ETIMEDOUT;
+
+failed:
+	BT_ERR("FAILED! ret=%d", ret);
+
+	return ret;
+}
+
+static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card,
+								int pollnum)
+{
+	int ret = -ETIMEDOUT;
+	u16 firmwarestat;
+	unsigned int tries;
+
+	 /* Wait for firmware to become ready */
+	for (tries = 0; tries < pollnum; tries++) {
+		if (btmrvl_sdio_read_fw_status(card, &firmwarestat) < 0)
+			continue;
+
+		if (firmwarestat == FIRMWARE_READY) {
+			ret = 0;
+			break;
+		} else {
+			msleep(10);
+		}
+	}
+
+	return ret;
+}
+
+static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
+{
+	const struct firmware *fw_helper = NULL;
+	const u8 *helper = NULL;
+	int ret;
+	void *tmphlprbuf = NULL;
+	int tmphlprbufsz, hlprblknow, helperlen;
+	u8 *helperbuf;
+	u32 tx_len;
+
+	ret = request_firmware(&fw_helper, card->helper,
+						&card->func->dev);
+	if ((ret < 0) || !fw_helper) {
+		BT_ERR("request_firmware(helper) failed, error code = %d",
+									ret);
+		ret = -ENOENT;
+		goto done;
+	}
+
+	helper = fw_helper->data;
+	helperlen = fw_helper->size;
+
+	BT_DBG("Downloading helper image (%d bytes), block size %d bytes",
+						helperlen, SDIO_BLOCK_SIZE);
+
+	tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
+
+	tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL);
+	if (!tmphlprbuf) {
+		BT_ERR("Unable to allocate buffer for helper."
+			" Terminating download");
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	memset(tmphlprbuf, 0, tmphlprbufsz);
+
+	helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN);
+
+	/* Perform helper data transfer */
+	tx_len = (FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE)
+			- SDIO_HEADER_LEN;
+	hlprblknow = 0;
+
+	do {
+		ret = btmrvl_sdio_poll_card_status(card,
+					    CARD_IO_READY | DN_LD_CARD_RDY);
+		if (ret < 0) {
+			BT_ERR("Helper download poll status timeout @ %d",
+				hlprblknow);
+			goto done;
+		}
+
+		/* Check if there is more data? */
+		if (hlprblknow >= helperlen)
+			break;
+
+		if (helperlen - hlprblknow < tx_len)
+			tx_len = helperlen - hlprblknow;
+
+		/* Little-endian */
+		helperbuf[0] = ((tx_len & 0x000000ff) >> 0);
+		helperbuf[1] = ((tx_len & 0x0000ff00) >> 8);
+		helperbuf[2] = ((tx_len & 0x00ff0000) >> 16);
+		helperbuf[3] = ((tx_len & 0xff000000) >> 24);
+
+		memcpy(&helperbuf[SDIO_HEADER_LEN], &helper[hlprblknow],
+				tx_len);
+
+		/* Now send the data */
+		ret = sdio_writesb(card->func, card->ioport, helperbuf,
+				FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE);
+		if (ret < 0) {
+			BT_ERR("IO error during helper download @ %d",
+				hlprblknow);
+			goto done;
+		}
+
+		hlprblknow += tx_len;
+	} while (true);
+
+	BT_DBG("Transferring helper image EOF block");
+
+	memset(helperbuf, 0x0, SDIO_BLOCK_SIZE);
+
+	ret = sdio_writesb(card->func, card->ioport, helperbuf,
+							SDIO_BLOCK_SIZE);
+	if (ret < 0) {
+		BT_ERR("IO error in writing helper image EOF block");
+		goto done;
+	}
+
+	ret = 0;
+
+done:
+	kfree(tmphlprbuf);
+	if (fw_helper)
+		release_firmware(fw_helper);
+
+	return ret;
+}
+
+static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
+{
+	const struct firmware *fw_firmware = NULL;
+	const u8 *firmware = NULL;
+	int firmwarelen, tmpfwbufsz, ret;
+	unsigned int tries, offset;
+	u8 base0, base1;
+	void *tmpfwbuf = NULL;
+	u8 *fwbuf;
+	u16 len;
+	int txlen = 0, tx_blocks = 0, count = 0;
+
+	ret = request_firmware(&fw_firmware, card->firmware,
+							&card->func->dev);
+	if ((ret < 0) || !fw_firmware) {
+		BT_ERR("request_firmware(firmware) failed, error code = %d",
+									ret);
+		ret = -ENOENT;
+		goto done;
+	}
+
+	firmware = fw_firmware->data;
+	firmwarelen = fw_firmware->size;
+
+	BT_DBG("Downloading FW image (%d bytes)", firmwarelen);
+
+	tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
+	tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL);
+	if (!tmpfwbuf) {
+		BT_ERR("Unable to allocate buffer for firmware."
+		       " Terminating download");
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	memset(tmpfwbuf, 0, tmpfwbufsz);
+
+	/* Ensure aligned firmware buffer */
+	fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN);
+
+	/* Perform firmware data transfer */
+	offset = 0;
+	do {
+		ret = btmrvl_sdio_poll_card_status(card,
+					CARD_IO_READY | DN_LD_CARD_RDY);
+		if (ret < 0) {
+			BT_ERR("FW download with helper poll status"
+						" timeout @ %d", offset);
+			goto done;
+		}
+
+		/* Check if there is more data ? */
+		if (offset >= firmwarelen)
+			break;
+
+		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+			base0 = sdio_readb(card->func,
+					SQ_READ_BASE_ADDRESS_A0_REG, &ret);
+			if (ret) {
+				BT_ERR("BASE0 register read failed:"
+					" base0 = 0x%04X(%d)."
+					" Terminating download",
+					base0, base0);
+				ret = -EIO;
+				goto done;
+			}
+			base1 = sdio_readb(card->func,
+					SQ_READ_BASE_ADDRESS_A1_REG, &ret);
+			if (ret) {
+				BT_ERR("BASE1 register read failed:"
+					" base1 = 0x%04X(%d)."
+					" Terminating download",
+					base1, base1);
+				ret = -EIO;
+				goto done;
+			}
+
+			len = (((u16) base1) << 8) | base0;
+			if (len)
+				break;
+
+			udelay(10);
+		}
+
+		if (!len)
+			break;
+		else if (len > BTM_UPLD_SIZE) {
+			BT_ERR("FW download failure @%d, invalid length %d",
+								offset, len);
+			ret = -EINVAL;
+			goto done;
+		}
+
+		txlen = len;
+
+		if (len & BIT(0)) {
+			count++;
+			if (count > MAX_WRITE_IOMEM_RETRY) {
+				BT_ERR("FW download failure @%d, "
+					"over max retry count", offset);
+				ret = -EIO;
+				goto done;
+			}
+			BT_ERR("FW CRC error indicated by the helper: "
+				"len = 0x%04X, txlen = %d", len, txlen);
+			len &= ~BIT(0);
+			/* Set txlen to 0 so as to resend from same offset */
+			txlen = 0;
+		} else {
+			count = 0;
+
+			/* Last block ? */
+			if (firmwarelen - offset < txlen)
+				txlen = firmwarelen - offset;
+
+			tx_blocks =
+			    (txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE;
+
+			memcpy(fwbuf, &firmware[offset], txlen);
+		}
+
+		ret = sdio_writesb(card->func, card->ioport, fwbuf,
+					tx_blocks * SDIO_BLOCK_SIZE);
+
+		if (ret < 0) {
+			BT_ERR("FW download, writesb(%d) failed @%d",
+							count, offset);
+			sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG,
+									&ret);
+			if (ret)
+				BT_ERR("writeb failed (CFG)");
+		}
+
+		offset += txlen;
+	} while (true);
+
+	BT_DBG("FW download over, size %d bytes", offset);
+
+	ret = 0;
+
+done:
+	kfree(tmpfwbuf);
+
+	if (fw_firmware)
+		release_firmware(fw_firmware);
+
+	return ret;
+}
+
+static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
+{
+	u16 buf_len = 0;
+	int ret, buf_block_len, blksz;
+	struct sk_buff *skb = NULL;
+	u32 type;
+	u8 *payload = NULL;
+	struct hci_dev *hdev = priv->btmrvl_dev.hcidev;
+	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
+
+	if (!card || !card->func) {
+		BT_ERR("card or function is NULL!");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Read the length of data to be transferred */
+	ret = btmrvl_sdio_read_rx_len(card, &buf_len);
+	if (ret < 0) {
+		BT_ERR("read rx_len failed");
+		ret = -EIO;
+		goto exit;
+	}
+
+	blksz = SDIO_BLOCK_SIZE;
+	buf_block_len = (buf_len + blksz - 1) / blksz;
+
+	if (buf_len <= SDIO_HEADER_LEN
+			|| (buf_block_len * blksz) > ALLOC_BUF_SIZE) {
+		BT_ERR("invalid packet length: %d", buf_len);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Allocate buffer */
+	skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN,
+								GFP_ATOMIC);
+	if (skb == NULL) {
+		BT_ERR("No free skb");
+		goto exit;
+	}
+
+	if ((unsigned long) skb->data & (BTSDIO_DMA_ALIGN - 1)) {
+		skb_put(skb, (unsigned long) skb->data &
+					(BTSDIO_DMA_ALIGN - 1));
+		skb_pull(skb, (unsigned long) skb->data &
+					(BTSDIO_DMA_ALIGN - 1));
+	}
+
+	payload = skb->data;
+
+	ret = sdio_readsb(card->func, payload, card->ioport,
+			  buf_block_len * blksz);
+	if (ret < 0) {
+		BT_ERR("readsb failed: %d", ret);
+		ret = -EIO;
+		goto exit;
+	}
+
+	/* This is SDIO specific header length: byte[2][1][0], type: byte[3]
+	 * (HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor)
+	 */
+
+	buf_len = payload[0];
+	buf_len |= (u16) payload[1] << 8;
+	type = payload[3];
+
+	switch (type) {
+	case HCI_ACLDATA_PKT:
+	case HCI_SCODATA_PKT:
+	case HCI_EVENT_PKT:
+		bt_cb(skb)->pkt_type = type;
+		skb->dev = (void *)hdev;
+		skb_put(skb, buf_len);
+		skb_pull(skb, SDIO_HEADER_LEN);
+
+		if (type == HCI_EVENT_PKT)
+			btmrvl_check_evtpkt(priv, skb);
+
+		hci_recv_frame(skb);
+		hdev->stat.byte_rx += buf_len;
+		break;
+
+	case MRVL_VENDOR_PKT:
+		bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
+		skb->dev = (void *)hdev;
+		skb_put(skb, buf_len);
+		skb_pull(skb, SDIO_HEADER_LEN);
+
+		if (btmrvl_process_event(priv, skb))
+			hci_recv_frame(skb);
+
+		hdev->stat.byte_rx += buf_len;
+		break;
+
+	default:
+		BT_ERR("Unknow packet type:%d", type);
+		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload,
+						blksz * buf_block_len);
+
+		kfree_skb(skb);
+		skb = NULL;
+		break;
+	}
+
+exit:
+	if (ret) {
+		hdev->stat.err_rx++;
+		if (skb)
+			kfree_skb(skb);
+	}
+
+	return ret;
+}
+
+static int btmrvl_sdio_get_int_status(struct btmrvl_private *priv, u8 * ireg)
+{
+	int ret;
+	u8 sdio_ireg = 0;
+	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
+
+	*ireg = 0;
+
+	sdio_ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
+	if (ret) {
+		BT_ERR("sdio_readb: read int status register failed");
+		ret = -EIO;
+		goto done;
+	}
+
+	if (sdio_ireg != 0) {
+		/*
+		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+		 * Clear the interrupt status register and re-enable the
+		 * interrupt.
+		 */
+		BT_DBG("sdio_ireg = 0x%x", sdio_ireg);
+
+		sdio_writeb(card->func, ~(sdio_ireg) & (DN_LD_HOST_INT_STATUS |
+							UP_LD_HOST_INT_STATUS),
+			    HOST_INTSTATUS_REG, &ret);
+		if (ret) {
+			BT_ERR("sdio_writeb: clear int status register "
+				"failed");
+			ret = -EIO;
+			goto done;
+		}
+	}
+
+	if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
+		if (priv->btmrvl_dev.tx_dnld_rdy)
+			BT_DBG("tx_done already received: "
+				" int_status=0x%x", sdio_ireg);
+		else
+			priv->btmrvl_dev.tx_dnld_rdy = true;
+	}
+
+	if (sdio_ireg & UP_LD_HOST_INT_STATUS)
+		btmrvl_sdio_card_to_host(priv);
+
+	*ireg = sdio_ireg;
+
+	ret = 0;
+
+done:
+	return ret;
+}
+
+static void btmrvl_sdio_interrupt(struct sdio_func *func)
+{
+	struct btmrvl_private *priv;
+	struct hci_dev *hcidev;
+	struct btmrvl_sdio_card *card;
+	u8 ireg = 0;
+
+	card = sdio_get_drvdata(func);
+	if (card && card->priv) {
+		priv = card->priv;
+		hcidev = priv->btmrvl_dev.hcidev;
+
+		if (btmrvl_sdio_get_int_status(priv, &ireg))
+			BT_ERR("reading HOST_INT_STATUS_REG failed");
+		else
+			BT_DBG("HOST_INT_STATUS_REG %#x", ireg);
+
+		btmrvl_interrupt(priv);
+	}
+}
+
+static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
+{
+	struct sdio_func *func;
+	u8 reg;
+	int ret = 0;
+
+	if (!card || !card->func) {
+		BT_ERR("Error: card or function is NULL!");
+		ret = -EINVAL;
+		goto failed;
+	}
+
+	func = card->func;
+
+	sdio_claim_host(func);
+
+	ret = sdio_enable_func(func);
+	if (ret) {
+		BT_ERR("sdio_enable_func() failed: ret=%d", ret);
+		ret = -EIO;
+		goto release_host;
+	}
+
+	ret = sdio_claim_irq(func, btmrvl_sdio_interrupt);
+	if (ret) {
+		BT_ERR("sdio_claim_irq failed: ret=%d", ret);
+		ret = -EIO;
+		goto disable_func;
+	}
+
+	ret = sdio_set_block_size(card->func, SDIO_BLOCK_SIZE);
+	if (ret) {
+		BT_ERR("cannot set SDIO block size");
+		ret = -EIO;
+		goto release_irq;
+	}
+
+	reg = sdio_readb(func, IO_PORT_0_REG, &ret);
+	if (ret < 0) {
+		ret = -EIO;
+		goto release_irq;
+	}
+
+	card->ioport = reg;
+
+	reg = sdio_readb(func, IO_PORT_1_REG, &ret);
+	if (ret < 0) {
+		ret = -EIO;
+		goto release_irq;
+	}
+
+	card->ioport |= (reg << 8);
+
+	reg = sdio_readb(func, IO_PORT_2_REG, &ret);
+	if (ret < 0) {
+		ret = -EIO;
+		goto release_irq;
+	}
+
+	card->ioport |= (reg << 16);
+
+	BT_DBG("SDIO FUNC%d IO port: 0x%x", func->num, card->ioport);
+
+	sdio_set_drvdata(func, card);
+
+	sdio_release_host(func);
+
+	return 0;
+
+release_irq:
+	sdio_release_irq(func);
+
+disable_func:
+	sdio_disable_func(func);
+
+release_host:
+	sdio_release_host(func);
+
+failed:
+	return ret;
+}
+
+static int btmrvl_sdio_unregister_dev(struct btmrvl_sdio_card *card)
+{
+	if (card && card->func) {
+		sdio_claim_host(card->func);
+		sdio_release_irq(card->func);
+		sdio_disable_func(card->func);
+		sdio_release_host(card->func);
+		sdio_set_drvdata(card->func, NULL);
+	}
+
+	return 0;
+}
+
+static int btmrvl_sdio_enable_host_int(struct btmrvl_sdio_card *card)
+{
+	int ret;
+
+	if (!card || !card->func)
+		return -EINVAL;
+
+	sdio_claim_host(card->func);
+
+	ret = btmrvl_sdio_enable_host_int_mask(card, HIM_ENABLE);
+
+	btmrvl_sdio_get_rx_unit(card);
+
+	sdio_release_host(card->func);
+
+	return ret;
+}
+
+static int btmrvl_sdio_disable_host_int(struct btmrvl_sdio_card *card)
+{
+	int ret;
+
+	if (!card || !card->func)
+		return -EINVAL;
+
+	sdio_claim_host(card->func);
+
+	ret = btmrvl_sdio_disable_host_int_mask(card, HIM_DISABLE);
+
+	sdio_release_host(card->func);
+
+	return ret;
+}
+
+static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
+				u8 *payload, u16 nb)
+{
+	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
+	int ret = 0;
+	int buf_block_len;
+	int blksz;
+	int i = 0;
+	u8 *buf = NULL;
+	void *tmpbuf = NULL;
+	int tmpbufsz;
+
+	if (!card || !card->func) {
+		BT_ERR("card or function is NULL!");
+		return -EINVAL;
+	}
+
+	buf = payload;
+	if ((unsigned long) payload & (BTSDIO_DMA_ALIGN - 1)) {
+		tmpbufsz = ALIGN_SZ(nb, BTSDIO_DMA_ALIGN);
+		tmpbuf = kzalloc(tmpbufsz, GFP_KERNEL);
+		if (!tmpbuf)
+			return -ENOMEM;
+		buf = (u8 *) ALIGN_ADDR(tmpbuf, BTSDIO_DMA_ALIGN);
+		memcpy(buf, payload, nb);
+	}
+
+	blksz = SDIO_BLOCK_SIZE;
+	buf_block_len = (nb + blksz - 1) / blksz;
+
+	sdio_claim_host(card->func);
+
+	do {
+		/* Transfer data to card */
+		ret = sdio_writesb(card->func, card->ioport, buf,
+				   buf_block_len * blksz);
+		if (ret < 0) {
+			i++;
+			BT_ERR("i=%d writesb failed: %d", i, ret);
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+						payload, nb);
+			ret = -EIO;
+			if (i > MAX_WRITE_IOMEM_RETRY)
+				goto exit;
+		}
+	} while (ret);
+
+	priv->btmrvl_dev.tx_dnld_rdy = false;
+
+exit:
+	sdio_release_host(card->func);
+
+	return ret;
+}
+
+static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
+{
+	int ret = 0;
+
+	if (!card || !card->func) {
+		BT_ERR("card or function is NULL!");
+		return -EINVAL;
+	}
+	sdio_claim_host(card->func);
+
+	if (!btmrvl_sdio_verify_fw_download(card, 1)) {
+		BT_DBG("Firmware already downloaded!");
+		goto done;
+	}
+
+	ret = btmrvl_sdio_download_helper(card);
+	if (ret) {
+		BT_ERR("Failed to download helper!");
+		ret = -EIO;
+		goto done;
+	}
+
+	if (btmrvl_sdio_download_fw_w_helper(card)) {
+		BT_ERR("Failed to download firmware!");
+		ret = -EIO;
+		goto done;
+	}
+
+	if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) {
+		BT_ERR("FW failed to be active in time!");
+		ret = -ETIMEDOUT;
+		goto done;
+	}
+
+done:
+	sdio_release_host(card->func);
+
+	return ret;
+}
+
+static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
+{
+	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
+	int ret = 0;
+
+	if (!card || !card->func) {
+		BT_ERR("card or function is NULL!");
+		return -EINVAL;
+	}
+
+	sdio_claim_host(card->func);
+
+	sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret);
+
+	sdio_release_host(card->func);
+
+	BT_DBG("wake up firmware");
+
+	return ret;
+}
+
+static int btmrvl_sdio_probe(struct sdio_func *func,
+					const struct sdio_device_id *id)
+{
+	int ret = 0;
+	struct btmrvl_private *priv = NULL;
+	struct btmrvl_sdio_card *card = NULL;
+
+	BT_INFO("vendor=0x%x, device=0x%x, class=%d, fn=%d",
+			id->vendor, id->device, id->class, func->num);
+
+	card = kzalloc(sizeof(*card), GFP_KERNEL);
+	if (!card) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	card->func = func;
+
+	if (id->driver_data) {
+		struct btmrvl_sdio_device *data = (void *) id->driver_data;
+		card->helper   = data->helper;
+		card->firmware = data->firmware;
+	}
+
+	if (btmrvl_sdio_register_dev(card) < 0) {
+		BT_ERR("Failed to register BT device!");
+		ret = -ENODEV;
+		goto free_card;
+	}
+
+	/* Disable the interrupts on the card */
+	btmrvl_sdio_disable_host_int(card);
+
+	if (btmrvl_sdio_download_fw(card)) {
+		BT_ERR("Downloading firmware failed!");
+		ret = -ENODEV;
+		goto unreg_dev;
+	}
+
+	msleep(100);
+
+	btmrvl_sdio_enable_host_int(card);
+
+	priv = btmrvl_add_card(card);
+	if (!priv) {
+		BT_ERR("Initializing card failed!");
+		ret = -ENODEV;
+		goto disable_host_int;
+	}
+
+	card->priv = priv;
+
+	/* Initialize the interface specific function pointers */
+	priv->hw_host_to_card = btmrvl_sdio_host_to_card;
+	priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
+
+	btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
+
+	return 0;
+
+disable_host_int:
+	btmrvl_sdio_disable_host_int(card);
+unreg_dev:
+	btmrvl_sdio_unregister_dev(card);
+free_card:
+	kfree(card);
+done:
+	return ret;
+}
+
+static void btmrvl_sdio_remove(struct sdio_func *func)
+{
+	struct btmrvl_sdio_card *card;
+
+	if (func) {
+		card = sdio_get_drvdata(func);
+		if (card) {
+			/* Send SHUTDOWN command & disable interrupt
+			 * if user removes the module.
+			 */
+			if (user_rmmod) {
+				btmrvl_send_module_cfg_cmd(card->priv,
+							MODULE_SHUTDOWN_REQ);
+				btmrvl_sdio_disable_host_int(card);
+			}
+			BT_DBG("unregester dev");
+			btmrvl_sdio_unregister_dev(card);
+			btmrvl_remove_card(card->priv);
+			kfree(card);
+		}
+	}
+}
+
+static struct sdio_driver bt_mrvl_sdio = {
+	.name		= "btmrvl_sdio",
+	.id_table	= btmrvl_sdio_ids,
+	.probe		= btmrvl_sdio_probe,
+	.remove		= btmrvl_sdio_remove,
+};
+
+static int btmrvl_sdio_init_module(void)
+{
+	if (sdio_register_driver(&bt_mrvl_sdio) != 0) {
+		BT_ERR("SDIO Driver Registration Failed");
+		return -ENODEV;
+	}
+
+	/* Clear the flag in case user removes the card. */
+	user_rmmod = 0;
+
+	return 0;
+}
+
+static void btmrvl_sdio_exit_module(void)
+{
+	/* Set the flag as user is removing this module. */
+	user_rmmod = 1;
+
+	sdio_unregister_driver(&bt_mrvl_sdio);
+}
+
+module_init(btmrvl_sdio_init_module);
+module_exit(btmrvl_sdio_exit_module);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
new file mode 100644
index 0000000..27329f1
--- /dev/null
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -0,0 +1,108 @@
+/**
+ * Marvell BT-over-SDIO driver: SDIO interface related definitions
+ *
+ * Copyright (C) 2009, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ *
+ **/
+
+#define SDIO_HEADER_LEN			4
+
+/* SD block size can not bigger than 64 due to buf size limit in firmware */
+/* define SD block size for data Tx/Rx */
+#define SDIO_BLOCK_SIZE			64
+
+/* Number of blocks for firmware transfer */
+#define FIRMWARE_TRANSFER_NBLOCK	2
+
+/* This is for firmware specific length */
+#define FW_EXTRA_LEN			36
+
+#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
+
+#define MRVDRV_BT_RX_PACKET_BUFFER_SIZE \
+	(HCI_MAX_FRAME_SIZE + FW_EXTRA_LEN)
+
+#define ALLOC_BUF_SIZE	(((max_t (int, MRVDRV_BT_RX_PACKET_BUFFER_SIZE, \
+			MRVDRV_SIZE_OF_CMD_BUFFER) + SDIO_HEADER_LEN \
+			+ SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE) \
+			* SDIO_BLOCK_SIZE)
+
+/* The number of times to try when polling for status */
+#define MAX_POLL_TRIES			100
+
+/* Max retry number of CMD53 write */
+#define MAX_WRITE_IOMEM_RETRY		2
+
+/* Host Control Registers */
+#define IO_PORT_0_REG			0x00
+#define IO_PORT_1_REG			0x01
+#define IO_PORT_2_REG			0x02
+
+#define CONFIG_REG			0x03
+#define HOST_POWER_UP			BIT(1)
+#define HOST_CMD53_FIN			BIT(2)
+
+#define HOST_INT_MASK_REG		0x04
+#define HIM_DISABLE			0xff
+#define HIM_ENABLE			(BIT(0) | BIT(1))
+
+#define HOST_INTSTATUS_REG		0x05
+#define UP_LD_HOST_INT_STATUS		BIT(0)
+#define DN_LD_HOST_INT_STATUS		BIT(1)
+
+/* Card Control Registers */
+#define SQ_READ_BASE_ADDRESS_A0_REG  	0x10
+#define SQ_READ_BASE_ADDRESS_A1_REG  	0x11
+
+#define CARD_STATUS_REG              	0x20
+#define DN_LD_CARD_RDY               	BIT(0)
+#define CARD_IO_READY              	BIT(3)
+
+#define CARD_FW_STATUS0_REG		0x40
+#define CARD_FW_STATUS1_REG		0x41
+#define FIRMWARE_READY			0xfedc
+
+#define CARD_RX_LEN_REG			0x42
+#define CARD_RX_UNIT_REG		0x43
+
+
+struct btmrvl_sdio_card {
+	struct sdio_func *func;
+	u32 ioport;
+	const char *helper;
+	const char *firmware;
+	u8 rx_unit;
+	struct btmrvl_private *priv;
+};
+
+struct btmrvl_sdio_device {
+	const char *helper;
+	const char *firmware;
+};
+
+
+/* Platform specific DMA alignment */
+#define BTSDIO_DMA_ALIGN		8
+
+/* Macros for Data Alignment : size */
+#define ALIGN_SZ(p, a)	\
+	(((p) + ((a) - 1)) & ~((a) - 1))
+
+/* Macros for Data Alignment : address */
+#define ALIGN_ADDR(p, a)	\
+	((((unsigned long)(p)) + (((unsigned long)(a)) - 1)) & \
+					~(((unsigned long)(a)) - 1))
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index e70c57e..7ba91aa 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -35,7 +35,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-#define VERSION "0.5"
+#define VERSION "0.6"
 
 static int ignore_dga;
 static int ignore_csr;
@@ -145,6 +145,7 @@ static struct usb_device_id blacklist_table[] = {
 #define BTUSB_INTR_RUNNING	0
 #define BTUSB_BULK_RUNNING	1
 #define BTUSB_ISOC_RUNNING	2
+#define BTUSB_SUSPENDING	3
 
 struct btusb_data {
 	struct hci_dev       *hdev;
@@ -157,11 +158,15 @@ struct btusb_data {
 	unsigned long flags;
 
 	struct work_struct work;
+	struct work_struct waker;
 
 	struct usb_anchor tx_anchor;
 	struct usb_anchor intr_anchor;
 	struct usb_anchor bulk_anchor;
 	struct usb_anchor isoc_anchor;
+	struct usb_anchor deferred;
+	int tx_in_flight;
+	spinlock_t txlock;
 
 	struct usb_endpoint_descriptor *intr_ep;
 	struct usb_endpoint_descriptor *bulk_tx_ep;
@@ -174,8 +179,23 @@ struct btusb_data {
 	unsigned int sco_num;
 	int isoc_altsetting;
 	int suspend_count;
+	int did_iso_resume:1;
 };
 
+static int inc_tx(struct btusb_data *data)
+{
+	unsigned long flags;
+	int rv;
+
+	spin_lock_irqsave(&data->txlock, flags);
+	rv = test_bit(BTUSB_SUSPENDING, &data->flags);
+	if (!rv)
+		data->tx_in_flight++;
+	spin_unlock_irqrestore(&data->txlock, flags);
+
+	return rv;
+}
+
 static void btusb_intr_complete(struct urb *urb)
 {
 	struct hci_dev *hdev = urb->context;
@@ -202,6 +222,7 @@ static void btusb_intr_complete(struct urb *urb)
 	if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
 		return;
 
+	usb_mark_last_busy(data->udev);
 	usb_anchor_urb(urb, &data->intr_anchor);
 
 	err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -301,7 +322,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
 	struct urb *urb;
 	unsigned char *buf;
 	unsigned int pipe;
-	int err, size;
+	int err, size = HCI_MAX_FRAME_SIZE;
 
 	BT_DBG("%s", hdev->name);
 
@@ -312,8 +333,6 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
 	if (!urb)
 		return -ENOMEM;
 
-	size = le16_to_cpu(data->bulk_rx_ep->wMaxPacketSize);
-
 	buf = kmalloc(size, mem_flags);
 	if (!buf) {
 		usb_free_urb(urb);
@@ -327,6 +346,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
 
 	urb->transfer_flags |= URB_FREE_BUFFER;
 
+	usb_mark_last_busy(data->udev);
 	usb_anchor_urb(urb, &data->bulk_anchor);
 
 	err = usb_submit_urb(urb, mem_flags);
@@ -465,6 +485,33 @@ static void btusb_tx_complete(struct urb *urb)
 {
 	struct sk_buff *skb = urb->context;
 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+	struct btusb_data *data = hdev->driver_data;
+
+	BT_DBG("%s urb %p status %d count %d", hdev->name,
+					urb, urb->status, urb->actual_length);
+
+	if (!test_bit(HCI_RUNNING, &hdev->flags))
+		goto done;
+
+	if (!urb->status)
+		hdev->stat.byte_tx += urb->transfer_buffer_length;
+	else
+		hdev->stat.err_tx++;
+
+done:
+	spin_lock(&data->txlock);
+	data->tx_in_flight--;
+	spin_unlock(&data->txlock);
+
+	kfree(urb->setup_packet);
+
+	kfree_skb(skb);
+}
+
+static void btusb_isoc_tx_complete(struct urb *urb)
+{
+	struct sk_buff *skb = urb->context;
+	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 
 	BT_DBG("%s urb %p status %d count %d", hdev->name,
 					urb, urb->status, urb->actual_length);
@@ -490,11 +537,17 @@ static int btusb_open(struct hci_dev *hdev)
 
 	BT_DBG("%s", hdev->name);
 
+	err = usb_autopm_get_interface(data->intf);
+	if (err < 0)
+		return err;
+
+	data->intf->needs_remote_wakeup = 1;
+
 	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-		return 0;
+		goto done;
 
 	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
-		return 0;
+		goto done;
 
 	err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
 	if (err < 0)
@@ -509,17 +562,28 @@ static int btusb_open(struct hci_dev *hdev)
 	set_bit(BTUSB_BULK_RUNNING, &data->flags);
 	btusb_submit_bulk_urb(hdev, GFP_KERNEL);
 
+done:
+	usb_autopm_put_interface(data->intf);
 	return 0;
 
 failed:
 	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
 	clear_bit(HCI_RUNNING, &hdev->flags);
+	usb_autopm_put_interface(data->intf);
 	return err;
 }
 
+static void btusb_stop_traffic(struct btusb_data *data)
+{
+	usb_kill_anchored_urbs(&data->intr_anchor);
+	usb_kill_anchored_urbs(&data->bulk_anchor);
+	usb_kill_anchored_urbs(&data->isoc_anchor);
+}
+
 static int btusb_close(struct hci_dev *hdev)
 {
 	struct btusb_data *data = hdev->driver_data;
+	int err;
 
 	BT_DBG("%s", hdev->name);
 
@@ -529,13 +593,16 @@ static int btusb_close(struct hci_dev *hdev)
 	cancel_work_sync(&data->work);
 
 	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
-	usb_kill_anchored_urbs(&data->isoc_anchor);
-
 	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-	usb_kill_anchored_urbs(&data->bulk_anchor);
-
 	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
-	usb_kill_anchored_urbs(&data->intr_anchor);
+
+	btusb_stop_traffic(data);
+	err = usb_autopm_get_interface(data->intf);
+	if (err < 0)
+		return 0;
+
+	data->intf->needs_remote_wakeup = 0;
+	usb_autopm_put_interface(data->intf);
 
 	return 0;
 }
@@ -622,7 +689,7 @@ static int btusb_send_frame(struct sk_buff *skb)
 		urb->dev      = data->udev;
 		urb->pipe     = pipe;
 		urb->context  = skb;
-		urb->complete = btusb_tx_complete;
+		urb->complete = btusb_isoc_tx_complete;
 		urb->interval = data->isoc_tx_ep->bInterval;
 
 		urb->transfer_flags  = URB_ISO_ASAP;
@@ -633,12 +700,21 @@ static int btusb_send_frame(struct sk_buff *skb)
 				le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
 
 		hdev->stat.sco_tx++;
-		break;
+		goto skip_waking;
 
 	default:
 		return -EILSEQ;
 	}
 
+	err = inc_tx(data);
+	if (err) {
+		usb_anchor_urb(urb, &data->deferred);
+		schedule_work(&data->waker);
+		err = 0;
+		goto done;
+	}
+
+skip_waking:
 	usb_anchor_urb(urb, &data->tx_anchor);
 
 	err = usb_submit_urb(urb, GFP_ATOMIC);
@@ -646,10 +722,13 @@ static int btusb_send_frame(struct sk_buff *skb)
 		BT_ERR("%s urb %p submission failed", hdev->name, urb);
 		kfree(urb->setup_packet);
 		usb_unanchor_urb(urb);
+	} else {
+		usb_mark_last_busy(data->udev);
 	}
 
 	usb_free_urb(urb);
 
+done:
 	return err;
 }
 
@@ -721,8 +800,19 @@ static void btusb_work(struct work_struct *work)
 {
 	struct btusb_data *data = container_of(work, struct btusb_data, work);
 	struct hci_dev *hdev = data->hdev;
+	int err;
 
 	if (hdev->conn_hash.sco_num > 0) {
+		if (!data->did_iso_resume) {
+			err = usb_autopm_get_interface(data->isoc);
+			if (err < 0) {
+				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+				usb_kill_anchored_urbs(&data->isoc_anchor);
+				return;
+			}
+
+			data->did_iso_resume = 1;
+		}
 		if (data->isoc_altsetting != 2) {
 			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
 			usb_kill_anchored_urbs(&data->isoc_anchor);
@@ -742,9 +832,25 @@ static void btusb_work(struct work_struct *work)
 		usb_kill_anchored_urbs(&data->isoc_anchor);
 
 		__set_isoc_interface(hdev, 0);
+		if (data->did_iso_resume) {
+			data->did_iso_resume = 0;
+			usb_autopm_put_interface(data->isoc);
+		}
 	}
 }
 
+static void btusb_waker(struct work_struct *work)
+{
+	struct btusb_data *data = container_of(work, struct btusb_data, waker);
+	int err;
+
+	err = usb_autopm_get_interface(data->intf);
+	if (err < 0)
+		return;
+
+	usb_autopm_put_interface(data->intf);
+}
+
 static int btusb_probe(struct usb_interface *intf,
 				const struct usb_device_id *id)
 {
@@ -814,11 +920,14 @@ static int btusb_probe(struct usb_interface *intf,
 	spin_lock_init(&data->lock);
 
 	INIT_WORK(&data->work, btusb_work);
+	INIT_WORK(&data->waker, btusb_waker);
+	spin_lock_init(&data->txlock);
 
 	init_usb_anchor(&data->tx_anchor);
 	init_usb_anchor(&data->intr_anchor);
 	init_usb_anchor(&data->bulk_anchor);
 	init_usb_anchor(&data->isoc_anchor);
+	init_usb_anchor(&data->deferred);
 
 	hdev = hci_alloc_dev();
 	if (!hdev) {
@@ -943,6 +1052,7 @@ static void btusb_disconnect(struct usb_interface *intf)
 	hci_free_dev(hdev);
 }
 
+#ifdef CONFIG_PM
 static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct btusb_data *data = usb_get_intfdata(intf);
@@ -952,22 +1062,44 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
 	if (data->suspend_count++)
 		return 0;
 
+	spin_lock_irq(&data->txlock);
+	if (!(interface_to_usbdev(intf)->auto_pm && data->tx_in_flight)) {
+		set_bit(BTUSB_SUSPENDING, &data->flags);
+		spin_unlock_irq(&data->txlock);
+	} else {
+		spin_unlock_irq(&data->txlock);
+		data->suspend_count--;
+		return -EBUSY;
+	}
+
 	cancel_work_sync(&data->work);
 
+	btusb_stop_traffic(data);
 	usb_kill_anchored_urbs(&data->tx_anchor);
 
-	usb_kill_anchored_urbs(&data->isoc_anchor);
-	usb_kill_anchored_urbs(&data->bulk_anchor);
-	usb_kill_anchored_urbs(&data->intr_anchor);
-
 	return 0;
 }
 
+static void play_deferred(struct btusb_data *data)
+{
+	struct urb *urb;
+	int err;
+
+	while ((urb = usb_get_from_anchor(&data->deferred))) {
+		err = usb_submit_urb(urb, GFP_ATOMIC);
+		if (err < 0)
+			break;
+
+		data->tx_in_flight++;
+	}
+	usb_scuttle_anchored_urbs(&data->deferred);
+}
+
 static int btusb_resume(struct usb_interface *intf)
 {
 	struct btusb_data *data = usb_get_intfdata(intf);
 	struct hci_dev *hdev = data->hdev;
-	int err;
+	int err = 0;
 
 	BT_DBG("intf %p", intf);
 
@@ -975,13 +1107,13 @@ static int btusb_resume(struct usb_interface *intf)
 		return 0;
 
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
-		return 0;
+		goto done;
 
 	if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
 		err = btusb_submit_intr_urb(hdev, GFP_NOIO);
 		if (err < 0) {
 			clear_bit(BTUSB_INTR_RUNNING, &data->flags);
-			return err;
+			goto failed;
 		}
 	}
 
@@ -989,9 +1121,10 @@ static int btusb_resume(struct usb_interface *intf)
 		err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
 		if (err < 0) {
 			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-			return err;
-		} else
-			btusb_submit_bulk_urb(hdev, GFP_NOIO);
+			goto failed;
+		}
+
+		btusb_submit_bulk_urb(hdev, GFP_NOIO);
 	}
 
 	if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
@@ -1001,16 +1134,35 @@ static int btusb_resume(struct usb_interface *intf)
 			btusb_submit_isoc_urb(hdev, GFP_NOIO);
 	}
 
+	spin_lock_irq(&data->txlock);
+	play_deferred(data);
+	clear_bit(BTUSB_SUSPENDING, &data->flags);
+	spin_unlock_irq(&data->txlock);
+	schedule_work(&data->work);
+
 	return 0;
+
+failed:
+	usb_scuttle_anchored_urbs(&data->deferred);
+done:
+	spin_lock_irq(&data->txlock);
+	clear_bit(BTUSB_SUSPENDING, &data->flags);
+	spin_unlock_irq(&data->txlock);
+
+	return err;
 }
+#endif
 
 static struct usb_driver btusb_driver = {
 	.name		= "btusb",
 	.probe		= btusb_probe,
 	.disconnect	= btusb_disconnect,
+#ifdef CONFIG_PM
 	.suspend	= btusb_suspend,
 	.resume		= btusb_resume,
+#endif
 	.id_table	= btusb_table,
+	.supports_autosuspend = 1,
 };
 
 static int __init btusb_init(void)
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 2cc7b32..b881a9c 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -618,7 +618,7 @@ static int dtl1_config(struct pcmcia_device *link)
 
 	/* Look for a generic full-sized window */
 	link->io.NumPorts1 = 8;
-	if (!pcmcia_loop_config(link, dtl1_confcheck, NULL))
+	if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0)
 		goto failed;
 
 	i = pcmcia_request_irq(link, &link->irq);
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 894b2cb..40aec0f 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -373,8 +373,9 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
 
 	i = 0;
 	skb_queue_walk_safe(&bcsp->unack, skb, tmp) {
-		if (i++ >= pkts_to_be_removed)
+		if (i >= pkts_to_be_removed)
 			break;
+		i++;
 
 		__skb_unlink(skb, &bcsp->unack);
 		kfree_skb(skb);
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 178e2e9..d6f36c0 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -107,7 +107,7 @@ struct agp_bridge_driver {
 	void (*agp_enable)(struct agp_bridge_data *, u32);
 	void (*cleanup)(void);
 	void (*tlb_flush)(struct agp_memory *);
-	unsigned long (*mask_memory)(struct agp_bridge_data *, struct page *, int);
+	unsigned long (*mask_memory)(struct agp_bridge_data *, dma_addr_t, int);
 	void (*cache_flush)(void);
 	int (*create_gatt_table)(struct agp_bridge_data *);
 	int (*free_gatt_table)(struct agp_bridge_data *);
@@ -121,6 +121,11 @@ struct agp_bridge_driver {
 	void (*agp_destroy_pages)(struct agp_memory *);
 	int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
 	void (*chipset_flush)(struct agp_bridge_data *);
+
+	int (*agp_map_page)(struct page *page, dma_addr_t *ret);
+	void (*agp_unmap_page)(struct page *page, dma_addr_t dma);
+	int (*agp_map_memory)(struct agp_memory *mem);
+	void (*agp_unmap_memory)(struct agp_memory *mem);
 };
 
 struct agp_bridge_data {
@@ -134,7 +139,8 @@ struct agp_bridge_data {
 	u32 __iomem *gatt_table;
 	u32 *gatt_table_real;
 	unsigned long scratch_page;
-	unsigned long scratch_page_real;
+	struct page *scratch_page_page;
+	dma_addr_t scratch_page_dma;
 	unsigned long gart_bus_addr;
 	unsigned long gatt_bus_addr;
 	u32 mode;
@@ -291,7 +297,7 @@ int agp_3_5_enable(struct agp_bridge_data *bridge);
 void global_cache_flush(void);
 void get_agp_version(struct agp_bridge_data *bridge);
 unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge,
-				      struct page *page, int type);
+				      dma_addr_t phys, int type);
 int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge,
 				  int type);
 struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev);
@@ -312,9 +318,6 @@ void agp3_generic_cleanup(void);
 #define AGP_GENERIC_SIZES_ENTRIES 11
 extern const struct aper_size_info_16 agp3_generic_sizes[];
 
-#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x)))
-#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x)))
-
 extern int agp_off;
 extern int agp_try_unsupported_boot;
 
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 201ef3f..d2ce68f 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -152,7 +152,7 @@ static struct page *m1541_alloc_page(struct agp_bridge_data *bridge)
 	pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
 	pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 			(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-			  phys_to_gart(page_to_phys(page))) | ALI_CACHE_FLUSH_EN ));
+			  page_to_phys(page)) | ALI_CACHE_FLUSH_EN ));
 	return page;
 }
 
@@ -180,7 +180,7 @@ static void m1541_destroy_page(struct page *page, int flags)
 		pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
 		pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
 				       (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
-					 phys_to_gart(page_to_phys(page))) | ALI_CACHE_FLUSH_EN));
+					 page_to_phys(page)) | ALI_CACHE_FLUSH_EN));
 	}
 	agp_generic_destroy_page(page, flags);
 }
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index ba9bde7..73dbf40 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -44,7 +44,7 @@ static int amd_create_page_map(struct amd_page_map *page_map)
 #ifndef CONFIG_X86
 	SetPageReserved(virt_to_page(page_map->real));
 	global_cache_flush();
-	page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
+	page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
 					    PAGE_SIZE);
 	if (page_map->remapped == NULL) {
 		ClearPageReserved(virt_to_page(page_map->real));
@@ -160,7 +160,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge)
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -173,7 +173,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge)
 
 	/* Calculate the agp offset */
 	for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-		writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1,
+		writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
@@ -325,7 +325,9 @@ static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		writel(agp_generic_mask_memory(agp_bridge,
-			mem->pages[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
+					       page_to_phys(mem->pages[i]),
+					       mem->type),
+		       cur_gatt+GET_GATT_OFF(addr));
 		readl(cur_gatt+GET_GATT_OFF(addr));	/* PCI Posting. */
 	}
 	amd_irongate_tlbflush(mem);
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 3bf5dda..2fb2e6c 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -79,7 +79,8 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		tmp = agp_bridge->driver->mask_memory(agp_bridge,
-			mem->pages[i], mask_type);
+						      page_to_phys(mem->pages[i]),
+						      mask_type);
 
 		BUG_ON(tmp & 0xffffff0000000ffcULL);
 		pte = (tmp & 0x000000ff00000000ULL) >> 28;
@@ -177,7 +178,7 @@ static const struct aper_size_info_32 amd_8151_sizes[7] =
 
 static int amd_8151_configure(void)
 {
-	unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real);
+	unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
 	int i;
 
 	/* Configure AGP regs in each x86-64 host bridge. */
@@ -557,7 +558,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev)
 {
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 
-	release_mem_region(virt_to_gart(bridge->gatt_table_real),
+	release_mem_region(virt_to_phys(bridge->gatt_table_real),
 			   amd64_aperture_sizes[bridge->aperture_size_idx].size);
 	agp_remove_bridge(bridge);
 	agp_put_bridge(bridge);
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 33656e1..3b2ecbe 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -302,7 +302,8 @@ static int ati_insert_memory(struct agp_memory * mem,
 		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = GET_GATT(addr);
 		writel(agp_bridge->driver->mask_memory(agp_bridge,	
-						       mem->pages[i], mem->type),
+						       page_to_phys(mem->pages[i]),
+						       mem->type),
 		       cur_gatt+GET_GATT_OFF(addr));
 	}
 	readl(GET_GATT(agp_bridge->gart_bus_addr)); /* PCI posting */
@@ -359,7 +360,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Write out the size register */
 	current_size = A_SIZE_LVL2(agp_bridge->current_size);
@@ -389,7 +390,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge)
 
 	/* Calculate the agp offset */
 	for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
-		writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1,
+		writel(virt_to_phys(ati_generic_private.gatt_pages[i]->real) | 1,
 			page_dir.remapped+GET_PAGE_DIR_OFF(addr));
 		readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));	/* PCI Posting. */
 	}
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index cfa5a64..ad87753 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -149,9 +149,21 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 			return -ENOMEM;
 		}
 
-		bridge->scratch_page_real = phys_to_gart(page_to_phys(page));
-		bridge->scratch_page =
-		    bridge->driver->mask_memory(bridge, page, 0);
+		bridge->scratch_page_page = page;
+		if (bridge->driver->agp_map_page) {
+			if (bridge->driver->agp_map_page(page,
+							 &bridge->scratch_page_dma)) {
+				dev_err(&bridge->dev->dev,
+					"unable to dma-map scratch page\n");
+				rc = -ENOMEM;
+				goto err_out_nounmap;
+			}
+		} else {
+			bridge->scratch_page_dma = page_to_phys(page);
+		}
+
+		bridge->scratch_page = bridge->driver->mask_memory(bridge,
+						   bridge->scratch_page_dma, 0);
 	}
 
 	size_value = bridge->driver->fetch_size();
@@ -191,8 +203,14 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 	return 0;
 
 err_out:
+	if (bridge->driver->needs_scratch_page &&
+	    bridge->driver->agp_unmap_page) {
+		bridge->driver->agp_unmap_page(bridge->scratch_page_page,
+					       bridge->scratch_page_dma);
+	}
+err_out_nounmap:
 	if (bridge->driver->needs_scratch_page) {
-		void *va = gart_to_virt(bridge->scratch_page_real);
+		void *va = page_address(bridge->scratch_page_page);
 
 		bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
 		bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
@@ -219,7 +237,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
 
 	if (bridge->driver->agp_destroy_page &&
 	    bridge->driver->needs_scratch_page) {
-		void *va = gart_to_virt(bridge->scratch_page_real);
+		void *va = page_address(bridge->scratch_page_page);
+
+		if (bridge->driver->agp_unmap_page)
+			bridge->driver->agp_unmap_page(bridge->scratch_page_page,
+						       bridge->scratch_page_dma);
 
 		bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
 		bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index 35d50f2..793f39e 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -67,7 +67,7 @@ static const struct gatt_mask efficeon_generic_masks[] =
 /* This function does the same thing as mask_memory() for this chipset... */
 static inline unsigned long efficeon_mask_memory(struct page *page)
 {
-	unsigned long addr = phys_to_gart(page_to_phys(page));
+	unsigned long addr = page_to_phys(page);
 	return addr | 0x00000001;
 }
 
@@ -226,7 +226,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
 
 		efficeon_private.l1_table[index] = page;
 
-		value = virt_to_gart((unsigned long *)page) | pati | present | index;
+		value = virt_to_phys((unsigned long *)page) | pati | present | index;
 
 		pci_write_config_dword(agp_bridge->dev,
 			EFFICEON_ATTPAGE, value);
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 1e8b461..c505439 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -437,6 +437,12 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
 		curr->bridge->driver->cache_flush();
 		curr->is_flushed = true;
 	}
+
+	if (curr->bridge->driver->agp_map_memory) {
+		ret_val = curr->bridge->driver->agp_map_memory(curr);
+		if (ret_val)
+			return ret_val;
+	}
 	ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type);
 
 	if (ret_val != 0)
@@ -478,6 +484,9 @@ int agp_unbind_memory(struct agp_memory *curr)
 	if (ret_val != 0)
 		return ret_val;
 
+	if (curr->bridge->driver->agp_unmap_memory)
+		curr->bridge->driver->agp_unmap_memory(curr);
+
 	curr->is_bound = false;
 	curr->pg_start = 0;
 	spin_lock(&curr->bridge->mapped_lock);
@@ -979,7 +988,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 	set_memory_uc((unsigned long)table, 1 << page_order);
 	bridge->gatt_table = (void *)table;
 #else
-	bridge->gatt_table = ioremap_nocache(virt_to_gart(table),
+	bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
 					(PAGE_SIZE * (1 << page_order)));
 	bridge->driver->cache_flush();
 #endif
@@ -992,7 +1001,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge)
 
 		return -ENOMEM;
 	}
-	bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real);
+	bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real);
 
 	/* AK: bogus, should encode addresses > 4GB */
 	for (i = 0; i < num_entries; i++) {
@@ -1132,7 +1141,9 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
 	}
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		writel(bridge->driver->mask_memory(bridge, mem->pages[i], mask_type),
+		writel(bridge->driver->mask_memory(bridge,
+						   page_to_phys(mem->pages[i]),
+						   mask_type),
 		       bridge->gatt_table+j);
 	}
 	readl(bridge->gatt_table+j-1);	/* PCI Posting. */
@@ -1347,9 +1358,8 @@ void global_cache_flush(void)
 EXPORT_SYMBOL(global_cache_flush);
 
 unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge,
-				      struct page *page, int type)
+				      dma_addr_t addr, int type)
 {
-	unsigned long addr = phys_to_gart(page_to_phys(page));
 	/* memory type is ignored in the generic routine */
 	if (bridge->driver->masks)
 		return addr | bridge->driver->masks[0].mask;
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index 8f3d4c1..501e293 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -107,7 +107,7 @@ static int __init hp_zx1_ioc_shared(void)
 	hp->gart_size = HP_ZX1_GART_SIZE;
 	hp->gatt_entries = hp->gart_size / hp->io_page_size;
 
-	hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
+	hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE));
 	hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
 	if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
@@ -246,7 +246,7 @@ hp_zx1_configure (void)
 	agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS);
 
 	if (hp->io_pdir_owner) {
-		writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
+		writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE);
 		readl(hp->ioc_regs+HP_ZX1_PDIR_BASE);
 		writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG);
 		readl(hp->ioc_regs+HP_ZX1_TCNFG);
@@ -394,10 +394,8 @@ hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type)
 }
 
 static unsigned long
-hp_zx1_mask_memory (struct agp_bridge_data *bridge,
-		    struct page *page, int type)
+hp_zx1_mask_memory (struct agp_bridge_data *bridge, dma_addr_t addr, int type)
 {
-	unsigned long addr = phys_to_gart(page_to_phys(page));
 	return HP_ZX1_PDIR_VALID_BIT | addr;
 }
 
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 60cc35b..e763d33 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -61,7 +61,7 @@
 #define WR_FLUSH_GATT(index)	RD_GATT(index)
 
 static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
-				       unsigned long addr, int type);
+				       dma_addr_t addr, int type);
 
 static struct {
 	void *gatt;				/* ioremap'd GATT area */
@@ -325,7 +325,7 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem,
 
 	io_page_size = 1UL << I460_IO_PAGE_SHIFT;
 	for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
-		paddr = phys_to_gart(page_to_phys(mem->pages[i]));
+		paddr = page_to_phys(mem->pages[i]);
 		for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size)
 			WR_GATT(j, i460_mask_memory(agp_bridge, paddr, mem->type));
 	}
@@ -382,7 +382,7 @@ static int i460_alloc_large_page (struct lp_desc *lp)
 		return -ENOMEM;
 	}
 
-	lp->paddr = phys_to_gart(page_to_phys(lp->page));
+	lp->paddr = page_to_phys(lp->page);
 	lp->refcount = 0;
 	atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 	return 0;
@@ -546,20 +546,13 @@ static void i460_destroy_page (struct page *page, int flags)
 #endif /* I460_LARGE_IO_PAGES */
 
 static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
-				       unsigned long addr, int type)
+				       dma_addr_t addr, int type)
 {
 	/* Make sure the returned address is a valid GATT entry */
 	return bridge->driver->masks[0].mask
 		| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
 }
 
-static unsigned long i460_page_mask_memory(struct agp_bridge_data *bridge,
-					   struct page *page, int type)
-{
-	unsigned long addr = phys_to_gart(page_to_phys(page));
-	return i460_mask_memory(bridge, addr, type);
-}
-
 const struct agp_bridge_driver intel_i460_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= i460_sizes,
@@ -569,7 +562,7 @@ const struct agp_bridge_driver intel_i460_driver = {
 	.fetch_size		= i460_fetch_size,
 	.cleanup		= i460_cleanup,
 	.tlb_flush		= i460_tlb_flush,
-	.mask_memory		= i460_page_mask_memory,
+	.mask_memory		= i460_mask_memory,
 	.masks			= i460_masks,
 	.agp_enable		= agp_generic_enable,
 	.cache_flush		= global_cache_flush,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index c585577..1540e69 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -10,6 +10,16 @@
 #include <linux/agp_backend.h>
 #include "agp.h"
 
+/*
+ * If we have Intel graphics, we're not going to have anything other than
+ * an Intel IOMMU. So make the correct use of the PCI DMA API contingent
+ * on the Intel IOMMU support (CONFIG_DMAR).
+ * Only newer chipsets need to bother with this, of course.
+ */
+#ifdef CONFIG_DMAR
+#define USE_PCI_DMA_API 1
+#endif
+
 #define PCI_DEVICE_ID_INTEL_E7221_HB	0x2588
 #define PCI_DEVICE_ID_INTEL_E7221_IG	0x258a
 #define PCI_DEVICE_ID_INTEL_82946GZ_HB      0x2970
@@ -172,6 +182,123 @@ static struct _intel_private {
 	int resource_valid;
 } intel_private;
 
+#ifdef USE_PCI_DMA_API
+static int intel_agp_map_page(struct page *page, dma_addr_t *ret)
+{
+	*ret = pci_map_page(intel_private.pcidev, page, 0,
+			    PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+	if (pci_dma_mapping_error(intel_private.pcidev, *ret))
+		return -EINVAL;
+	return 0;
+}
+
+static void intel_agp_unmap_page(struct page *page, dma_addr_t dma)
+{
+	pci_unmap_page(intel_private.pcidev, dma,
+		       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+}
+
+static void intel_agp_free_sglist(struct agp_memory *mem)
+{
+	struct sg_table st;
+
+	st.sgl = mem->sg_list;
+	st.orig_nents = st.nents = mem->page_count;
+
+	sg_free_table(&st);
+
+	mem->sg_list = NULL;
+	mem->num_sg = 0;
+}
+
+static int intel_agp_map_memory(struct agp_memory *mem)
+{
+	struct sg_table st;
+	struct scatterlist *sg;
+	int i;
+
+	DBG("try mapping %lu pages\n", (unsigned long)mem->page_count);
+
+	if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL))
+		return -ENOMEM;
+
+	mem->sg_list = sg = st.sgl;
+
+	for (i = 0 ; i < mem->page_count; i++, sg = sg_next(sg))
+		sg_set_page(sg, mem->pages[i], PAGE_SIZE, 0);
+
+	mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list,
+				 mem->page_count, PCI_DMA_BIDIRECTIONAL);
+	if (unlikely(!mem->num_sg)) {
+		intel_agp_free_sglist(mem);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void intel_agp_unmap_memory(struct agp_memory *mem)
+{
+	DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count);
+
+	pci_unmap_sg(intel_private.pcidev, mem->sg_list,
+		     mem->page_count, PCI_DMA_BIDIRECTIONAL);
+	intel_agp_free_sglist(mem);
+}
+
+static void intel_agp_insert_sg_entries(struct agp_memory *mem,
+					off_t pg_start, int mask_type)
+{
+	struct scatterlist *sg;
+	int i, j;
+
+	j = pg_start;
+
+	WARN_ON(!mem->num_sg);
+
+	if (mem->num_sg == mem->page_count) {
+		for_each_sg(mem->sg_list, sg, mem->page_count, i) {
+			writel(agp_bridge->driver->mask_memory(agp_bridge,
+					sg_dma_address(sg), mask_type),
+					intel_private.gtt+j);
+			j++;
+		}
+	} else {
+		/* sg may merge pages, but we have to seperate
+		 * per-page addr for GTT */
+		unsigned int len, m;
+
+		for_each_sg(mem->sg_list, sg, mem->num_sg, i) {
+			len = sg_dma_len(sg) / PAGE_SIZE;
+			for (m = 0; m < len; m++) {
+				writel(agp_bridge->driver->mask_memory(agp_bridge,
+								       sg_dma_address(sg) + m * PAGE_SIZE,
+								       mask_type),
+				       intel_private.gtt+j);
+				j++;
+			}
+		}
+	}
+	readl(intel_private.gtt+j-1);
+}
+
+#else
+
+static void intel_agp_insert_sg_entries(struct agp_memory *mem,
+					off_t pg_start, int mask_type)
+{
+	int i, j;
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+		writel(agp_bridge->driver->mask_memory(agp_bridge,
+				page_to_phys(mem->pages[i]), mask_type),
+		       intel_private.gtt+j);
+	}
+
+	readl(intel_private.gtt+j-1);
+}
+
+#endif
+
 static int intel_i810_fetch_size(void)
 {
 	u32 smram_miscc;
@@ -345,8 +472,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
 			global_cache_flush();
 		for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 			writel(agp_bridge->driver->mask_memory(agp_bridge,
-							       mem->pages[i],
-							       mask_type),
+					page_to_phys(mem->pages[i]), mask_type),
 			       intel_private.registers+I810_PTE_BASE+(j*4));
 		}
 		readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
@@ -463,9 +589,8 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
 }
 
 static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge,
-					    struct page *page, int type)
+					    dma_addr_t addr, int type)
 {
-	unsigned long addr = phys_to_gart(page_to_phys(page));
 	/* Type checking must be done elsewhere */
 	return addr | bridge->driver->masks[type].mask;
 }
@@ -853,7 +978,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start,
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
-						       mem->pages[i], mask_type),
+				page_to_phys(mem->pages[i]), mask_type),
 		       intel_private.registers+I810_PTE_BASE+(j*4));
 	}
 	readl(intel_private.registers+I810_PTE_BASE+((j-1)*4));
@@ -1017,6 +1142,12 @@ static int intel_i915_configure(void)
 
 	intel_i9xx_setup_flush();
 
+#ifdef USE_PCI_DMA_API 
+	if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
+		dev_err(&intel_private.pcidev->dev,
+			"set gfx device dma mask 36bit failed!\n");
+#endif
+
 	return 0;
 }
 
@@ -1041,7 +1172,7 @@ static void intel_i915_chipset_flush(struct agp_bridge_data *bridge)
 static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
 				     int type)
 {
-	int i, j, num_entries;
+	int num_entries;
 	void *temp;
 	int ret = -EINVAL;
 	int mask_type;
@@ -1065,7 +1196,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
 	if ((pg_start + mem->page_count) > num_entries)
 		goto out_err;
 
-	/* The i915 can't check the GTT for entries since its read only,
+	/* The i915 can't check the GTT for entries since it's read only;
 	 * depend on the caller to make the correct offset decisions.
 	 */
 
@@ -1081,12 +1212,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
 	if (!mem->is_flushed)
 		global_cache_flush();
 
-	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-		writel(agp_bridge->driver->mask_memory(agp_bridge,
-						       mem->pages[i], mask_type), intel_private.gtt+j);
-	}
-
-	readl(intel_private.gtt+j-1);
+	intel_agp_insert_sg_entries(mem, pg_start, mask_type);
 	agp_bridge->driver->tlb_flush(mem);
 
  out:
@@ -1198,9 +1324,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
  * this conditional.
  */
 static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
-					    struct page *page, int type)
+					    dma_addr_t addr, int type)
 {
-	dma_addr_t addr = phys_to_gart(page_to_phys(page));
 	/* Shift high bits down */
 	addr |= (addr >> 28) & 0xf0;
 
@@ -2006,6 +2131,12 @@ static const struct agp_bridge_driver intel_915_driver = {
 	.agp_destroy_pages      = agp_generic_destroy_pages,
 	.agp_type_to_mask_type  = intel_i830_type_to_mask_type,
 	.chipset_flush		= intel_i915_chipset_flush,
+#ifdef USE_PCI_DMA_API
+	.agp_map_page		= intel_agp_map_page,
+	.agp_unmap_page		= intel_agp_unmap_page,
+	.agp_map_memory		= intel_agp_map_memory,
+	.agp_unmap_memory	= intel_agp_unmap_memory,
+#endif
 };
 
 static const struct agp_bridge_driver intel_i965_driver = {
@@ -2034,6 +2165,12 @@ static const struct agp_bridge_driver intel_i965_driver = {
 	.agp_destroy_pages      = agp_generic_destroy_pages,
 	.agp_type_to_mask_type	= intel_i830_type_to_mask_type,
 	.chipset_flush		= intel_i915_chipset_flush,
+#ifdef USE_PCI_DMA_API
+	.agp_map_page		= intel_agp_map_page,
+	.agp_unmap_page		= intel_agp_unmap_page,
+	.agp_map_memory		= intel_agp_map_memory,
+	.agp_unmap_memory	= intel_agp_unmap_memory,
+#endif
 };
 
 static const struct agp_bridge_driver intel_7505_driver = {
@@ -2088,6 +2225,12 @@ static const struct agp_bridge_driver intel_g33_driver = {
 	.agp_destroy_pages      = agp_generic_destroy_pages,
 	.agp_type_to_mask_type	= intel_i830_type_to_mask_type,
 	.chipset_flush		= intel_i915_chipset_flush,
+#ifdef USE_PCI_DMA_API
+	.agp_map_page		= intel_agp_map_page,
+	.agp_unmap_page		= intel_agp_unmap_page,
+	.agp_map_memory		= intel_agp_map_memory,
+	.agp_unmap_memory	= intel_agp_unmap_memory,
+#endif
 };
 
 static int find_gmch(u16 device)
@@ -2313,15 +2456,6 @@ static int agp_intel_resume(struct pci_dev *pdev)
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 	int ret_val;
 
-	pci_restore_state(pdev);
-
-	/* We should restore our graphics device's config space,
-	 * as host bridge (00:00) resumes before graphics device (02:00),
-	 * then our access to its pci space can work right.
-	 */
-	if (intel_private.pcidev)
-		pci_restore_state(intel_private.pcidev);
-
 	if (bridge->driver == &intel_generic_driver)
 		intel_configure();
 	else if (bridge->driver == &intel_850_driver)
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 263d71d..7e36d2b 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -225,7 +225,7 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type
 	}
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		writel(agp_bridge->driver->mask_memory(agp_bridge,
-			mem->pages[i], mask_type),
+			       page_to_phys(mem->pages[i]), mask_type),
 			agp_bridge->gatt_table+nvidia_private.pg_offset+j);
 	}
 
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index e077701..60ab751 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -32,7 +32,7 @@
 #define AGP8X_MODE		(1 << AGP8X_MODE_BIT)
 
 static unsigned long
-parisc_agp_mask_memory(struct agp_bridge_data *bridge, unsigned long addr,
+parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
 		       int type);
 
 static struct _parisc_agp_info {
@@ -189,20 +189,12 @@ parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
 }
 
 static unsigned long
-parisc_agp_mask_memory(struct agp_bridge_data *bridge, unsigned long addr,
+parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
 		       int type)
 {
 	return SBA_PDIR_VALID_BIT | addr;
 }
 
-static unsigned long
-parisc_agp_page_mask_memory(struct agp_bridge_data *bridge, struct page *page,
-			    int type)
-{
-	unsigned long addr = phys_to_gart(page_to_phys(page));
-	return SBA_PDIR_VALID_BIT | addr;
-}
-
 static void
 parisc_agp_enable(struct agp_bridge_data *bridge, u32 mode)
 {
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index d3ea2e4..0d426ae 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -70,10 +70,9 @@ static void sgi_tioca_tlbflush(struct agp_memory *mem)
  * entry.
  */
 static unsigned long
-sgi_tioca_mask_memory(struct agp_bridge_data *bridge,
-		      struct page *page, int type)
+sgi_tioca_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
+		      int type)
 {
-	unsigned long addr = phys_to_gart(page_to_phys(page));
 	return tioca_physpage_to_gart(addr);
 }
 
@@ -190,7 +189,8 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
 
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		table[j] =
-		    bridge->driver->mask_memory(bridge, mem->pages[i],
+		    bridge->driver->mask_memory(bridge,
+						page_to_phys(mem->pages[i]),
 						mem->type);
 	}
 
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index b964a21..13acaaf 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -155,7 +155,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
 	/* Create a fake scratch directory */
 	for (i = 0; i < 1024; i++) {
 		writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i);
-		writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
+		writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
 	}
 
 	retval = serverworks_create_gatt_pages(value->num_entries / 1024);
@@ -167,7 +167,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
 
 	agp_bridge->gatt_table_real = (u32 *)page_dir.real;
 	agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
-	agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
+	agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
 
 	/* Get the address for the gart region.
 	 * This is a bus address even on the alpha, b/c its
@@ -179,7 +179,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge)
 
 	/* Calculate the agp offset */
 	for (i = 0; i < value->num_entries / 1024; i++)
-		writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
+		writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
 
 	return 0;
 }
@@ -349,7 +349,9 @@ static int serverworks_insert_memory(struct agp_memory *mem,
 	for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
 		addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
 		cur_gatt = SVRWRKS_GET_GATT(addr);
-		writel(agp_bridge->driver->mask_memory(agp_bridge, mem->pages[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
+		writel(agp_bridge->driver->mask_memory(agp_bridge, 
+				page_to_phys(mem->pages[i]), mem->type),
+		       cur_gatt+GET_GATT_OFF(addr));
 	}
 	serverworks_tlbflush(mem);
 	return 0;
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index f192c3b..20ef1bf 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -7,6 +7,7 @@
 #include <linux/pagemap.h>
 #include <linux/agp_backend.h>
 #include <linux/delay.h>
+#include <linux/vmalloc.h>
 #include <asm/uninorth.h>
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
@@ -27,6 +28,8 @@
 static int uninorth_rev;
 static int is_u3;
 
+#define DEFAULT_APERTURE_SIZE 256
+#define DEFAULT_APERTURE_STRING "256"
 static char *aperture = NULL;
 
 static int uninorth_fetch_size(void)
@@ -55,7 +58,7 @@ static int uninorth_fetch_size(void)
 
 	if (!size) {
 		for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++)
-			if (values[i].size == 32)
+			if (values[i].size == DEFAULT_APERTURE_SIZE)
 				break;
 	}
 
@@ -135,7 +138,7 @@ static int uninorth_configure(void)
 	if (is_u3) {
 		pci_write_config_dword(agp_bridge->dev,
 				       UNI_N_CFG_GART_DUMMY_PAGE,
-				       agp_bridge->scratch_page_real >> 12);
+				       page_to_phys(agp_bridge->scratch_page_page) >> 12);
 	}
 
 	return 0;
@@ -179,8 +182,6 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start,
 	}
 	(void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
 	mb();
-	flush_dcache_range((unsigned long)&agp_bridge->gatt_table[pg_start],
-		(unsigned long)&agp_bridge->gatt_table[pg_start + mem->page_count]);
 
 	uninorth_tlbflush(mem);
 	return 0;
@@ -224,7 +225,6 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 				   (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000);
 	}
 	mb();
-	flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]);
 	uninorth_tlbflush(mem);
 
 	return 0;
@@ -243,7 +243,6 @@ int u3_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
 	for (i = 0; i < mem->page_count; ++i)
 		gp[i] = 0;
 	mb();
-	flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]);
 	uninorth_tlbflush(mem);
 
 	return 0;
@@ -396,6 +395,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 	int i;
 	void *temp;
 	struct page *page;
+	struct page **pages;
 
 	/* We can't handle 2 level gatt's */
 	if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -424,21 +424,39 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
 	if (table == NULL)
 		return -ENOMEM;
 
+	pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
+	if (pages == NULL)
+		goto enomem;
+
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
-	for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
+	for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
+	     page++, i++) {
 		SetPageReserved(page);
+		pages[i] = page;
+	}
 
 	bridge->gatt_table_real = (u32 *) table;
-	bridge->gatt_table = (u32 *)table;
-	bridge->gatt_bus_addr = virt_to_gart(table);
+	/* Need to clear out any dirty data still sitting in caches */
+	flush_dcache_range((unsigned long)table,
+			   (unsigned long)(table_end + PAGE_SIZE));
+	bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG);
+
+	if (bridge->gatt_table == NULL)
+		goto enomem;
+
+	bridge->gatt_bus_addr = virt_to_phys(table);
 
 	for (i = 0; i < num_entries; i++)
 		bridge->gatt_table[i] = 0;
 
-	flush_dcache_range((unsigned long)table, (unsigned long)table_end);
-
 	return 0;
+
+enomem:
+	kfree(pages);
+	if (table)
+		free_pages((unsigned long)table, page_order);
+	return -ENOMEM;
 }
 
 static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
@@ -456,6 +474,7 @@ static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
 	 * from the table.
 	 */
 
+	vunmap(bridge->gatt_table);
 	table = (char *) bridge->gatt_table_real;
 	table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
 
@@ -474,13 +493,11 @@ void null_cache_flush(void)
 
 /* Setup function */
 
-static const struct aper_size_info_32 uninorth_sizes[7] =
+static const struct aper_size_info_32 uninorth_sizes[] =
 {
-#if 0 /* Not sure uninorth supports that high aperture sizes */
 	{256, 65536, 6, 64},
 	{128, 32768, 5, 32},
 	{64, 16384, 4, 16},
-#endif
 	{32, 8192, 3, 8},
 	{16, 4096, 2, 4},
 	{8, 2048, 1, 2},
@@ -491,7 +508,7 @@ static const struct aper_size_info_32 uninorth_sizes[7] =
  * Not sure that u3 supports that high aperture sizes but it
  * would strange if it did not :)
  */
-static const struct aper_size_info_32 u3_sizes[8] =
+static const struct aper_size_info_32 u3_sizes[] =
 {
 	{512, 131072, 7, 128},
 	{256, 65536, 6, 64},
@@ -507,7 +524,7 @@ const struct agp_bridge_driver uninorth_agp_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= (void *)uninorth_sizes,
 	.size_type		= U32_APER_SIZE,
-	.num_aperture_sizes	= 4,
+	.num_aperture_sizes	= ARRAY_SIZE(uninorth_sizes),
 	.configure		= uninorth_configure,
 	.fetch_size		= uninorth_fetch_size,
 	.cleanup		= uninorth_cleanup,
@@ -534,7 +551,7 @@ const struct agp_bridge_driver u3_agp_driver = {
 	.owner			= THIS_MODULE,
 	.aperture_sizes		= (void *)u3_sizes,
 	.size_type		= U32_APER_SIZE,
-	.num_aperture_sizes	= 8,
+	.num_aperture_sizes	= ARRAY_SIZE(u3_sizes),
 	.configure		= uninorth_configure,
 	.fetch_size		= uninorth_fetch_size,
 	.cleanup		= uninorth_cleanup,
@@ -717,7 +734,7 @@ module_param(aperture, charp, 0);
 MODULE_PARM_DESC(aperture,
 		 "Aperture size, must be power of two between 4MB and an\n"
 		 "\t\tupper limit specific to the UniNorth revision.\n"
-		 "\t\tDefault: 32M");
+		 "\t\tDefault: " DEFAULT_APERTURE_STRING "M");
 
 MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
 MODULE_LICENSE("GPL");
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 2dafc2d..df5038b 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -11,7 +11,7 @@
  * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
  * Modified and maintained by Marcio Saito <marcio@cyclades.com>.
  *
- * Copyright (C) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (C) 2007-2009 Jiri Slaby <jirislaby@gmail.com>
  *
  * Much of the design and some of the code came from serial.c
  * which was copyright (C) 1991, 1992  Linus Torvalds.  It was
@@ -19,577 +19,9 @@
  * and then fixed as suggested by Michael K. Johnson 12/12/92.
  * Converted to pci probing and cleaned up by Jiri Slaby.
  *
- * This version supports shared IRQ's (only for PCI boards).
- *
- * Prevent users from opening non-existing Z ports.
- *
- * Revision 2.3.2.8   2000/07/06 18:14:16 ivan
- * Fixed the PCI detection function to work properly on Alpha systems.
- * Implemented support for TIOCSERGETLSR ioctl.
- * Implemented full support for non-standard baud rates.
- *
- * Revision 2.3.2.7   2000/06/01 18:26:34 ivan
- * Request PLX I/O region, although driver doesn't use it, to avoid
- * problems with other drivers accessing it.
- * Removed count for on-board buffer characters in cy_chars_in_buffer
- * (Cyclades-Z only).
- *
- * Revision 2.3.2.6   2000/05/05 13:56:05 ivan
- * Driver now reports physical instead of virtual memory addresses.
- * Masks were added to some Cyclades-Z read accesses.
- * Implemented workaround for PLX9050 bug that would cause a system lockup
- * in certain systems, depending on the MMIO addresses allocated to the
- * board.
- * Changed the Tx interrupt programming in the CD1400 chips to boost up
- * performance (Cyclom-Y only).
- * Code is now compliant with the new module interface (module_[init|exit]).
- * Make use of the PCI helper functions to access PCI resources.
- * Did some code "housekeeping".
- *
- * Revision 2.3.2.5   2000/01/19 14:35:33 ivan
- * Fixed bug in cy_set_termios on CRTSCTS flag turnoff.
- *
- * Revision 2.3.2.4   2000/01/17 09:19:40 ivan
- * Fixed SMP locking in Cyclom-Y interrupt handler.
- *
- * Revision 2.3.2.3   1999/12/28 12:11:39 ivan
- * Added a new cyclades_card field called nports to allow the driver to
- * know the exact number of ports found by the Z firmware after its load;
- * RX buffer contention prevention logic on interrupt op mode revisited
- * (Cyclades-Z only);
- * Revisited printk's for Z debug;
- * Driver now makes sure that the constant SERIAL_XMIT_SIZE is defined;
- *
- * Revision 2.3.2.2   1999/10/01 11:27:43 ivan
- * Fixed bug in cyz_poll that would make all ports but port 0
- * unable to transmit/receive data (Cyclades-Z only);
- * Implemented logic to prevent the RX buffer from being stuck with data
- * due to a driver / firmware race condition in interrupt op mode
- * (Cyclades-Z only);
- * Fixed bug in block_til_ready logic that would lead to a system crash;
- * Revisited cy_close spinlock usage;
- *
- * Revision 2.3.2.1   1999/09/28 11:01:22 ivan
- * Revisited CONFIG_PCI conditional compilation for PCI board support;
- * Implemented TIOCGICOUNT and TIOCMIWAIT ioctl support;
- * _Major_ cleanup on the Cyclades-Z interrupt support code / logic;
- * Removed CTS handling from the driver -- this is now completely handled
- * by the firmware (Cyclades-Z only);
- * Flush RX on-board buffers on a port open (Cyclades-Z only);
- * Fixed handling of ASYNC_SPD_* TTY flags;
- * Module unload now unmaps all memory area allocated by ioremap;
- *
- * Revision 2.3.1.1   1999/07/15 16:45:53 ivan
- * Removed CY_PROC conditional compilation;
- * Implemented SMP-awareness for the driver;
- * Implemented a new ISA IRQ autoprobe that uses the irq_probe_[on|off]
- * functions;
- * The driver now accepts memory addresses (maddr=0xMMMMM) and IRQs
- * (irq=NN) as parameters (only for ISA boards);
- * Fixed bug in set_line_char that would prevent the Cyclades-Z
- * ports from being configured at speeds above 115.2Kbps;
- * Fixed bug in cy_set_termios that would prevent XON/XOFF flow control
- * switching from working properly;
- * The driver now only prints IRQ info for the Cyclades-Z if it's
- * configured to work in interrupt mode;
- *
- * Revision 2.2.2.3   1999/06/28 11:13:29 ivan
- * Added support for interrupt mode operation for the Z cards;
- * Removed the driver inactivity control for the Z;
- * Added a missing MOD_DEC_USE_COUNT in the cy_open function for when
- * the Z firmware is not loaded yet;
- * Replaced the "manual" Z Tx flush buffer by a call to a FW command of
- * same functionality;
- * Implemented workaround for IRQ setting loss on the PCI configuration
- * registers after a PCI bridge EEPROM reload (affects PLX9060 only);
- *
- * Revision 2.2.2.2  1999/05/14 17:18:15 ivan
- * /proc entry location changed to /proc/tty/driver/cyclades;
- * Added support to shared IRQ's (only for PCI boards);
- * Added support for Cobalt Qube2 systems;
- * IRQ [de]allocation scheme revisited;
- * BREAK implementation changed in order to make use of the 'break_ctl'
- * TTY facility;
- * Fixed typo in TTY structure field 'driver_name';
- * Included a PCI bridge reset and EEPROM reload in the board
- * initialization code (for both Y and Z series).
- *
- * Revision 2.2.2.1  1999/04/08 16:17:43 ivan
- * Fixed a bug in cy_wait_until_sent that was preventing the port to be
- * closed properly after a SIGINT;
- * Module usage counter scheme revisited;
- * Added support to the upcoming Y PCI boards (i.e., support to additional
- * PCI Device ID's).
- *
- * Revision 2.2.1.10 1999/01/20 16:14:29 ivan
- * Removed all unnecessary page-alignement operations in ioremap calls
- * (ioremap is currently safe for these operations).
- *
- * Revision 2.2.1.9  1998/12/30 18:18:30 ivan
- * Changed access to PLX PCI bridge registers from I/O to MMIO, in
- * order to make PLX9050-based boards work with certain motherboards.
- *
- * Revision 2.2.1.8  1998/11/13 12:46:20 ivan
- * cy_close function now resets (correctly) the tty->closing flag;
- * JIFFIES_DIFF macro fixed.
- *
- * Revision 2.2.1.7  1998/09/03 12:07:28 ivan
- * Fixed bug in cy_close function, which was not informing HW of
- * which port should have the reception disabled before doing so;
- * fixed Cyclom-8YoP hardware detection bug.
- *
- * Revision 2.2.1.6  1998/08/20 17:15:39 ivan
- * Fixed bug in cy_close function, which causes malfunction
- * of one of the first 4 ports when a higher port is closed
- * (Cyclom-Y only).
- *
- * Revision 2.2.1.5  1998/08/10 18:10:28 ivan
- * Fixed Cyclom-4Yo hardware detection bug.
- *
- * Revision 2.2.1.4  1998/08/04 11:02:50 ivan
- * /proc/cyclades implementation with great collaboration of
- * Marc Lewis <marc@blarg.net>;
- * cyy_interrupt was changed to avoid occurrence of kernel oopses
- * during PPP operation.
- *
- * Revision 2.2.1.3  1998/06/01 12:09:10 ivan
- * General code review in order to comply with 2.1 kernel standards;
- * data loss prevention for slow devices revisited (cy_wait_until_sent
- * was created);
- * removed conditional compilation for new/old PCI structure support
- * (now the driver only supports the new PCI structure).
- *
- * Revision 2.2.1.1  1998/03/19 16:43:12 ivan
- * added conditional compilation for new/old PCI structure support;
- * removed kernel series (2.0.x / 2.1.x) conditional compilation.
- *
- * Revision 2.1.1.3  1998/03/16 18:01:12 ivan
- * cleaned up the data loss fix;
- * fixed XON/XOFF handling once more (Cyclades-Z);
- * general review of the driver routines;
- * introduction of a mechanism to prevent data loss with slow
- * printers, by forcing a delay before closing the port.
- *
- * Revision 2.1.1.2  1998/02/17 16:50:00 ivan
- * fixed detection/handling of new CD1400 in Ye boards;
- * fixed XON/XOFF handling (Cyclades-Z);
- * fixed data loss caused by a premature port close;
- * introduction of a flag that holds the CD1400 version ID per port
- * (used by the CYGETCD1400VER new ioctl).
- *
- * Revision 2.1.1.1  1997/12/03 17:31:19 ivan
- * Code review for the module cleanup routine;
- * fixed RTS and DTR status report for new CD1400's in get_modem_info;
- * includes anonymous changes regarding signal_pending.
- *
- * Revision 2.1  1997/11/01 17:42:41 ivan
- * Changes in the driver to support Alpha systems (except 8Zo V_1);
- * BREAK fix for the Cyclades-Z boards;
- * driver inactivity control by FW implemented;
- * introduction of flag that allows driver to take advantage of
- * a special CD1400 feature related to HW flow control;
- * added support for the CD1400  rev. J (Cyclom-Y boards);
- * introduction of ioctls to:
- *  - control the rtsdtr_inv flag (Cyclom-Y);
- *  - control the rflow flag (Cyclom-Y);
- *  - adjust the polling interval (Cyclades-Z);
- *
- * Revision 1.36.4.33  1997/06/27 19:00:00  ivan
- * Fixes related to kernel version conditional
- * compilation.
- *
- * Revision 1.36.4.32  1997/06/14 19:30:00  ivan
- * Compatibility issues between kernels 2.0.x and
- * 2.1.x (mainly related to clear_bit function).
- *
- * Revision 1.36.4.31  1997/06/03 15:30:00  ivan
- * Changes to define the memory window according to the
- * board type.
- *
- * Revision 1.36.4.30  1997/05/16 15:30:00  daniel
- * Changes to support new cycladesZ boards.
- *
- * Revision 1.36.4.29  1997/05/12 11:30:00  daniel
- * Merge of Bentson's and Daniel's version 1.36.4.28.
- * Corrects bug in cy_detect_pci: check if there are more
- * ports than the number of static structs allocated.
- * Warning message during initialization if this driver is
- * used with the new generation of cycladesZ boards.  Those
- * will be supported only in next release of the driver.
- * Corrects bug in cy_detect_pci and cy_detect_isa that
- * returned wrong number of VALID boards, when a cyclomY
- * was found with no serial modules connected.
- * Changes to use current (2.1.x) kernel subroutine names
- * and created macros for compilation with 2.0.x kernel,
- * instead of the other way around.
- *
- * Revision 1.36.4.28  1997/05/?? ??:00:00  bentson
- * Change queue_task_irq_off to queue_task_irq.
- * The inline function queue_task_irq_off (tqueue.h)
- * was removed from latest releases of 2.1.x kernel.
- * Use of macro __init to mark the initialization
- * routines, so memory can be reused.
- * Also incorporate implementation of critical region
- * in function cleanup_module() created by anonymous
- * linuxer.
- *
- * Revision 1.36.4.28  1997/04/25 16:00:00  daniel
- * Change to support new firmware that solves DCD problem:
- * application could fail to receive SIGHUP signal when DCD
- * varying too fast.
- *
- * Revision 1.36.4.27  1997/03/26 10:30:00  daniel
- * Changed for support linux versions 2.1.X.
- * Backward compatible with linux versions 2.0.X.
- * Corrected illegal use of filler field in
- * CH_CTRL struct.
- * Deleted some debug messages.
- *
- * Revision 1.36.4.26  1997/02/27 12:00:00  daniel
- * Included check for NULL tty pointer in cyz_poll.
- *
- * Revision 1.36.4.25  1997/02/26 16:28:30  bentson
- * Bill Foster at Blarg! Online services noticed that
- * some of the switch elements of -Z modem control
- * lacked a closing "break;"
- *
- * Revision 1.36.4.24  1997/02/24 11:00:00  daniel
- * Changed low water threshold for buffer xmit_buf
- *
- * Revision 1.36.4.23  1996/12/02 21:50:16  bentson
- * Marcio provided fix to modem status fetch for -Z
- *
- * Revision 1.36.4.22  1996/10/28 22:41:17  bentson
- * improve mapping of -Z control page (thanks to Steve
- * Price <stevep@fa.tdktca.com> for help on this)
- *
- * Revision 1.36.4.21  1996/09/10 17:00:10  bentson
- * shift from CPU-bound to memcopy in cyz_polling operation
- *
- * Revision 1.36.4.20  1996/09/09 18:30:32  Bentson
- * Added support to set and report higher speeds.
- *
- * Revision 1.36.4.19c  1996/08/09 10:00:00  Marcio Saito
- * Some fixes in the HW flow control for the BETA release.
- * Don't try to register the IRQ.
- *
- * Revision 1.36.4.19  1996/08/08 16:23:18  Bentson
- * make sure "cyc" appears in all kernel messages; all soft interrupts
- * handled by same routine; recognize out-of-band reception; comment
- * out some diagnostic messages; leave RTS/CTS flow control to hardware;
- * fix race condition in -Z buffer management; only -Y needs to explicitly
- * flush chars; tidy up some startup messages;
- *
- * Revision 1.36.4.18  1996/07/25 18:57:31  bentson
- * shift MOD_INC_USE_COUNT location to match
- * serial.c; purge some diagnostic messages;
- *
- * Revision 1.36.4.17  1996/07/25 18:01:08  bentson
- * enable modem status messages and fetch & process them; note
- * time of last activity type for each port; set_line_char now
- * supports more than line 0 and treats 0 baud correctly;
- * get_modem_info senses rs_status;
- *
- * Revision 1.36.4.16  1996/07/20 08:43:15  bentson
- * barely works--now's time to turn on
- * more features 'til it breaks
- *
- * Revision 1.36.4.15  1996/07/19 22:30:06  bentson
- * check more -Z board status; shorten boot message
- *
- * Revision 1.36.4.14  1996/07/19 22:20:37  bentson
- * fix reference to ch_ctrl in startup; verify return
- * values from cyz_issue_cmd and cyz_update_channel;
- * more stuff to get modem control correct;
- *
- * Revision 1.36.4.13  1996/07/11 19:53:33  bentson
- * more -Z stuff folded in; re-order changes to put -Z stuff
- * after -Y stuff (to make changes clearer)
- *
- * Revision 1.36.4.12  1996/07/11 15:40:55  bentson
- * Add code to poll Cyclades-Z.  Add code to get & set RS-232 control.
- * Add code to send break.  Clear firmware ID word at startup (so
- * that other code won't talk to inactive board).
- *
- * Revision 1.36.4.11  1996/07/09 05:28:29  bentson
- * add code for -Z in set_line_char
- *
- * Revision 1.36.4.10  1996/07/08 19:28:37  bentson
- * fold more -Z stuff (or in some cases, error messages)
- * into driver; add text to "don't know what to do" messages.
- *
- * Revision 1.36.4.9  1996/07/08 18:38:38  bentson
- * moved compile-time flags near top of file; cosmetic changes
- * to narrow text (to allow 2-up printing); changed many declarations
- * to "static" to limit external symbols; shuffled code order to
- * coalesce -Y and -Z specific code, also to put internal functions
- * in order of tty_driver structure; added code to recognize -Z
- * ports (and for moment, do nothing or report error); add cy_startup
- * to parse boot command line for extra base addresses for ISA probes;
- *
- * Revision 1.36.4.8  1996/06/25 17:40:19  bentson
- * reorder some code, fix types of some vars (int vs. long),
- * add cy_setup to support user declared ISA addresses
- *
- * Revision 1.36.4.7  1996/06/21 23:06:18  bentson
- * dump ioctl based firmware load (it's now a user level
- * program); ensure uninitialzed ports cannot be used
- *
- * Revision 1.36.4.6  1996/06/20 23:17:19  bentson
- * rename vars and restructure some code
- *
- * Revision 1.36.4.5  1996/06/14 15:09:44  bentson
- * get right status back after boot load
- *
- * Revision 1.36.4.4  1996/06/13 19:51:44  bentson
- * successfully loads firmware
- *
- * Revision 1.36.4.3  1996/06/13 06:08:33  bentson
- * add more of the code for the boot/load ioctls
- *
- * Revision 1.36.4.2  1996/06/11 21:00:51  bentson
- * start to add Z functionality--starting with ioctl
- * for loading firmware
- *
- * Revision 1.36.4.1  1996/06/10 18:03:02  bentson
- * added code to recognize Z/PCI card at initialization; report
- * presence, but card is not initialized (because firmware needs
- * to be loaded)
- *
- * Revision 1.36.3.8  1996/06/07 16:29:00  bentson
- * starting minor number at zero; added missing verify_area
- * as noted by Heiko EiÃŸfeldt <heiko@colossus.escape.de>
- *
- * Revision 1.36.3.7  1996/04/19 21:06:18  bentson
- * remove unneeded boot message & fix CLOCAL hardware flow
- * control (Miquel van Smoorenburg <miquels@Q.cistron.nl>);
- * remove unused diagnostic statements; minor 0 is first;
- *
- * Revision 1.36.3.6  1996/03/13 13:21:17  marcio
- * The kernel function vremap (available only in later 1.3.xx kernels)
- * allows the access to memory addresses above the RAM. This revision
- * of the driver supports PCI boards below 1Mb (device id 0x100) and
- * above 1Mb (device id 0x101).
- *
- * Revision 1.36.3.5  1996/03/07 15:20:17  bentson
- * Some global changes to interrupt handling spilled into
- * this driver--mostly unused arguments in system function
- * calls.  Also added change by Marcio Saito which should
- * reduce lost interrupts at startup by fast processors.
- *
- * Revision 1.36.3.4  1995/11/13  20:45:10  bentson
- * Changes by Corey Minyard <minyard@wf-rch.cirr.com> distributed
- * in 1.3.41 kernel to remove a possible race condition, extend
- * some error messages, and let the driver run as a loadable module
- * Change by Alan Wendt <alan@ez0.ezlink.com> to remove a
- * possible race condition.
- * Change by Marcio Saito <marcio@cyclades.com> to fix PCI addressing.
- *
- * Revision 1.36.3.3  1995/11/13  19:44:48  bentson
- * Changes by Linus Torvalds in 1.3.33 kernel distribution
- * required due to reordering of driver initialization.
- * Drivers are now initialized *after* memory management.
- *
- * Revision 1.36.3.2  1995/09/08  22:07:14  bentson
- * remove printk from ISR; fix typo
- *
- * Revision 1.36.3.1  1995/09/01  12:00:42  marcio
- * Minor fixes in the PCI board support. PCI function calls in
- * conditional compilation (CONFIG_PCI). Thanks to Jim Duncan
- * <duncan@okay.com>. "bad serial count" message removed.
- *
- * Revision 1.36.3  1995/08/22  09:19:42  marcio
- * Cyclom-Y/PCI support added. Changes in the cy_init routine and
- * board initialization. Changes in the boot messages. The driver
- * supports up to 4 boards and 64 ports by default.
- *
- * Revision 1.36.1.4  1995/03/29  06:14:14  bentson
- * disambiguate between Cyclom-16Y and Cyclom-32Ye;
- *
- * Revision 1.36.1.3  1995/03/23  22:15:35  bentson
- * add missing break in modem control block in ioctl switch statement
- * (discovered by Michael Edward Chastain <mec@jobe.shell.portal.com>);
- *
- * Revision 1.36.1.2  1995/03/22  19:16:22  bentson
- * make sure CTS flow control is set as soon as possible (thanks
- * to note from David Lambert <lambert@chesapeake.rps.slb.com>);
- *
- * Revision 1.36.1.1  1995/03/13  15:44:43  bentson
- * initialize defaults for receive threshold and stale data timeout;
- * cosmetic changes;
- *
- * Revision 1.36  1995/03/10  23:33:53  bentson
- * added support of chips 4-7 in 32 port Cyclom-Ye;
- * fix cy_interrupt pointer dereference problem
- * (Joe Portman <baron@aa.net>);
- * give better error response if open is attempted on non-existent port
- * (Zachariah Vaum <jchryslr@netcom.com>);
- * correct command timeout (Kenneth Lerman <lerman@@seltd.newnet.com>);
- * conditional compilation for -16Y on systems with fast, noisy bus;
- * comment out diagnostic print function;
- * cleaned up table of base addresses;
- * set receiver time-out period register to correct value,
- * set receive threshold to better default values,
- * set chip timer to more accurate 200 Hz ticking,
- * add code to monitor and modify receive parameters
- * (Rik Faith <faith@cs.unc.edu> Nick Simicich
- * <njs@scifi.emi.net>);
- *
- * Revision 1.35  1994/12/16  13:54:18  steffen
- * additional patch by Marcio Saito for board detection
- * Accidently left out in 1.34
- *
- * Revision 1.34  1994/12/10  12:37:12  steffen
- * This is the corrected version as suggested by Marcio Saito
- *
- * Revision 1.33  1994/12/01  22:41:18  bentson
- * add hooks to support more high speeds directly; add tytso
- * patch regarding CLOCAL wakeups
- *
- * Revision 1.32  1994/11/23  19:50:04  bentson
- * allow direct kernel control of higher signalling rates;
- * look for cards at additional locations
- *
- * Revision 1.31  1994/11/16  04:33:28  bentson
- * ANOTHER fix from Corey Minyard, minyard@wf-rch.cirr.com--
- * a problem in chars_in_buffer has been resolved by some
- * small changes;  this should yield smoother output
- *
- * Revision 1.30  1994/11/16  04:28:05  bentson
- * Fix from Corey Minyard, Internet: minyard@metronet.com,
- * UUCP: minyard@wf-rch.cirr.com, WORK: minyardbnr.ca, to
- * cy_hangup that appears to clear up much (all?) of the
- * DTR glitches; also he's added/cleaned-up diagnostic messages
- *
- * Revision 1.29  1994/11/16  04:16:07  bentson
- * add change proposed by Ralph Sims, ralphs@halcyon.com, to
- * operate higher speeds in same way as other serial ports;
- * add more serial ports (for up to two 16-port muxes).
- *
- * Revision 1.28  1994/11/04  00:13:16  root
- * turn off diagnostic messages
- *
- * Revision 1.27  1994/11/03  23:46:37  root
- * bunch of changes to bring driver into greater conformance
- * with the serial.c driver (looking for missed fixes)
- *
- * Revision 1.26  1994/11/03  22:40:36  root
- * automatic interrupt probing fixed.
- *
- * Revision 1.25  1994/11/03  20:17:02  root
- * start to implement auto-irq
- *
- * Revision 1.24  1994/11/03  18:01:55  root
- * still working on modem signals--trying not to drop DTR
- * during the getty/login processes
- *
- * Revision 1.23  1994/11/03  17:51:36  root
- * extend baud rate support; set receive threshold as function
- * of baud rate; fix some problems with RTS/CTS;
- *
- * Revision 1.22  1994/11/02  18:05:35  root
- * changed arguments to udelay to type long to get
- * delays to be of correct duration
- *
- * Revision 1.21  1994/11/02  17:37:30  root
- * employ udelay (after calibrating loops_per_second earlier
- * in init/main.c) instead of using home-grown delay routines
- *
- * Revision 1.20  1994/11/02  03:11:38  root
- * cy_chars_in_buffer forces a return value of 0 to let
- * login work (don't know why it does); some functions
- * that were returning EFAULT, now executes the code;
- * more work on deciding when to disable xmit interrupts;
- *
- * Revision 1.19  1994/11/01  20:10:14  root
- * define routine to start transmission interrupts (by enabling
- * transmit interrupts); directly enable/disable modem interrupts;
- *
- * Revision 1.18  1994/11/01  18:40:45  bentson
- * Don't always enable transmit interrupts in startup; interrupt on
- * TxMpty instead of TxRdy to help characters get out before shutdown;
- * restructure xmit interrupt to check for chars first and quit if
- * none are ready to go; modem status (MXVRx) is upright, _not_ inverted
- * (to my view);
- *
- * Revision 1.17  1994/10/30  04:39:45  bentson
- * rename serial_driver and callout_driver to cy_serial_driver and
- * cy_callout_driver to avoid linkage interference; initialize
- * info->type to PORT_CIRRUS; ruggedize paranoia test; elide ->port
- * from cyclades_port structure; add paranoia check to cy_close;
- *
- * Revision 1.16  1994/10/30  01:14:33  bentson
- * change major numbers; add some _early_ return statements;
- *
- * Revision 1.15  1994/10/29  06:43:15  bentson
- * final tidying up for clean compile;  enable some error reporting
- *
- * Revision 1.14  1994/10/28  20:30:22  Bentson
- * lots of changes to drag the driver towards the new tty_io
- * structures and operation.  not expected to work, but may
- * compile cleanly.
- *
- * Revision 1.13  1994/07/21  23:08:57  Bentson
- * add some diagnostic cruft; support 24 lines (for testing
- * both -8Y and -16Y cards; be more thorough in servicing all
- * chips during interrupt; add "volatile" a few places to
- * circumvent compiler optimizations; fix base & offset
- * computations in block_til_ready (was causing chip 0 to
- * stop operation)
- *
- * Revision 1.12  1994/07/19  16:42:11  Bentson
- * add some hackery for kernel version 1.1.8; expand
- * error messages; refine timing for delay loops and
- * declare loop params volatile
- *
- * Revision 1.11  1994/06/11  21:53:10  bentson
- * get use of save_car right in transmit interrupt service
- *
- * Revision 1.10.1.1  1994/06/11  21:31:18  bentson
- * add some diagnostic printing; try to fix save_car stuff
- *
- * Revision 1.10  1994/06/11  20:36:08  bentson
- * clean up compiler warnings
- *
- * Revision 1.9  1994/06/11  19:42:46  bentson
- * added a bunch of code to support modem signalling
- *
- * Revision 1.8  1994/06/11  17:57:07  bentson
- * recognize break & parity error
- *
- * Revision 1.7  1994/06/05  05:51:34  bentson
- * Reorder baud table to be monotonic; add cli to CP; discard
- * incoming characters and status if the line isn't open; start to
- * fold code into cy_throttle; start to port get_serial_info,
- * set_serial_info, get_modem_info, set_modem_info, and send_break
- * from serial.c; expand cy_ioctl; relocate and expand config_setup;
- * get flow control characters from tty struct; invalidate ports w/o
- * hardware;
- *
- * Revision 1.6  1994/05/31  18:42:21  bentson
- * add a loop-breaker in the interrupt service routine;
- * note when port is initialized so that it can be shut
- * down under the right conditions; receive works without
- * any obvious errors
- *
- * Revision 1.5  1994/05/30  00:55:02  bentson
- * transmit works without obvious errors
- *
- * Revision 1.4  1994/05/27  18:46:27  bentson
- * incorporated more code from lib_y.c; can now print short
- * strings under interrupt control to port zero; seems to
- * select ports/channels/lines correctly
- *
- * Revision 1.3  1994/05/25  22:12:44  bentson
- * shifting from multi-port on a card to proper multiplexor
- * data structures;  added skeletons of most routines
- *
- * Revision 1.2  1994/05/19  13:21:43  bentson
- * start to crib from other sources
- *
  */
 
-#define CY_VERSION	"2.5"
+#define CY_VERSION	"2.6"
 
 /* If you need to install more boards than NR_CARDS, change the constant
    in the definition below. No other change is necessary to support up to
@@ -648,9 +80,7 @@
 #include <linux/firmware.h>
 #include <linux/device.h>
 
-#include <asm/system.h>
 #include <linux/io.h>
-#include <asm/irq.h>
 #include <linux/uaccess.h>
 
 #include <linux/kernel.h>
@@ -660,13 +90,11 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
-static void cy_throttle(struct tty_struct *tty);
 static void cy_send_xchar(struct tty_struct *tty, char ch);
 
 #ifndef SERIAL_XMIT_SIZE
 #define	SERIAL_XMIT_SIZE	(min(PAGE_SIZE, 4096))
 #endif
-#define WAKEUP_CHARS		256
 
 #define STD_COM_FLAGS (0)
 
@@ -756,25 +184,25 @@ static int cy_next_channel;	/* next minor available */
  *                                               HI            VHI
  *     20
  */
-static int baud_table[] = {
+static const int baud_table[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
 	1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
 	230400, 0
 };
 
-static char baud_co_25[] = {	/* 25 MHz clock option table */
+static const char baud_co_25[] = {	/* 25 MHz clock option table */
 	/* value =>    00    01   02    03    04 */
 	/* divide by    8    32   128   512  2048 */
 	0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
 	0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-static char baud_bpr_25[] = {	/* 25 MHz baud rate period table */
+static const char baud_bpr_25[] = {	/* 25 MHz baud rate period table */
 	0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
 	0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
 };
 
-static char baud_co_60[] = {	/* 60 MHz clock option table (CD1400 J) */
+static const char baud_co_60[] = {	/* 60 MHz clock option table (CD1400 J) */
 	/* value =>    00    01   02    03    04 */
 	/* divide by    8    32   128   512  2048 */
 	0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03,
@@ -782,13 +210,13 @@ static char baud_co_60[] = {	/* 60 MHz clock option table (CD1400 J) */
 	0x00
 };
 
-static char baud_bpr_60[] = {	/* 60 MHz baud rate period table (CD1400 J) */
+static const char baud_bpr_60[] = {	/* 60 MHz baud rate period table (CD1400 J) */
 	0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62,
 	0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32,
 	0x21
 };
 
-static char baud_cor3[] = {	/* receive threshold */
+static const char baud_cor3[] = {	/* receive threshold */
 	0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 	0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07,
 	0x07
@@ -805,7 +233,7 @@ static char baud_cor3[] = {	/* receive threshold */
  * cables.
  */
 
-static char rflow_thr[] = {	/* rflow threshold */
+static const char rflow_thr[] = {	/* rflow threshold */
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 	0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
 	0x0a
@@ -814,7 +242,7 @@ static char rflow_thr[] = {	/* rflow threshold */
 /*  The Cyclom-Ye has placed the sequential chips in non-sequential
  *  address order.  This look-up table overcomes that problem.
  */
-static int cy_chip_offset[] = { 0x0000,
+static const unsigned int cy_chip_offset[] = { 0x0000,
 	0x0400,
 	0x0800,
 	0x0C00,
@@ -827,7 +255,7 @@ static int cy_chip_offset[] = { 0x0000,
 /* PCI related definitions */
 
 #ifdef CONFIG_PCI
-static struct pci_device_id cy_pci_dev_id[] __devinitdata = {
+static const struct pci_device_id cy_pci_dev_id[] = {
 	/* PCI < 1Mb */
 	{ PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) },
 	/* PCI > 1Mb */
@@ -850,7 +278,7 @@ MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
 #endif
 
 static void cy_start(struct tty_struct *);
-static void set_line_char(struct cyclades_port *);
+static void cy_set_line_char(struct cyclades_port *, struct tty_struct *);
 static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
 #ifdef CONFIG_ISA
 static unsigned detect_isa_irq(void __iomem *);
@@ -869,6 +297,20 @@ static void cyz_rx_restart(unsigned long);
 static struct timer_list cyz_rx_full_timer[NR_PORTS];
 #endif				/* CONFIG_CYZ_INTR */
 
+static inline void cyy_writeb(struct cyclades_port *port, u32 reg, u8 val)
+{
+	struct cyclades_card *card = port->card;
+
+	cy_writeb(port->u.cyy.base_addr + (reg << card->bus_index), val);
+}
+
+static inline u8 cyy_readb(struct cyclades_port *port, u32 reg)
+{
+	struct cyclades_card *card = port->card;
+
+	return readb(port->u.cyy.base_addr + (reg << card->bus_index));
+}
+
 static inline bool cy_is_Z(struct cyclades_card *card)
 {
 	return card->num_chips == (unsigned int)-1;
@@ -893,7 +335,7 @@ static inline bool cyz_is_loaded(struct cyclades_card *card)
 }
 
 static inline int serial_paranoia_check(struct cyclades_port *info,
-		char *name, const char *routine)
+		const char *name, const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
 	if (!info) {
@@ -909,7 +351,7 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
 	}
 #endif
 	return 0;
-}				/* serial_paranoia_check */
+}
 
 /***********************************************************/
 /********* Start of block of Cyclom-Y specific code ********/
@@ -921,13 +363,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
 
    This function is only called from inside spinlock-protected code.
  */
-static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index)
+static int __cyy_issue_cmd(void __iomem *base_addr, u8 cmd, int index)
 {
+	void __iomem *ccr = base_addr + (CyCCR << index);
 	unsigned int i;
 
 	/* Check to see that the previous command has completed */
 	for (i = 0; i < 100; i++) {
-		if (readb(base_addr + (CyCCR << index)) == 0)
+		if (readb(ccr) == 0)
 			break;
 		udelay(10L);
 	}
@@ -937,10 +380,16 @@ static int cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index)
 		return -1;
 
 	/* Issue the new command */
-	cy_writeb(base_addr + (CyCCR << index), cmd);
+	cy_writeb(ccr, cmd);
 
 	return 0;
-}				/* cyy_issue_cmd */
+}
+
+static inline int cyy_issue_cmd(struct cyclades_port *port, u8 cmd)
+{
+	return __cyy_issue_cmd(port->u.cyy.base_addr, cmd,
+			port->card->bus_index);
+}
 
 #ifdef CONFIG_ISA
 /* ISA interrupt detection code */
@@ -960,12 +409,12 @@ static unsigned detect_isa_irq(void __iomem *address)
 
 	irqs = probe_irq_on();
 	/* Wait ... */
-	udelay(5000L);
+	msleep(5);
 
 	/* Enable the Tx interrupts on the CD1400 */
 	local_irq_save(flags);
 	cy_writeb(address + (CyCAR << index), 0);
-	cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index);
+	__cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index);
 
 	cy_writeb(address + (CyCAR << index), 0);
 	cy_writeb(address + (CySRER << index),
@@ -973,7 +422,7 @@ static unsigned detect_isa_irq(void __iomem *address)
 	local_irq_restore(flags);
 
 	/* Wait ... */
-	udelay(5000L);
+	msleep(5);
 
 	/* Check which interrupt is in use */
 	irq = probe_irq_off(irqs);
@@ -999,7 +448,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
 	struct cyclades_port *info;
 	struct tty_struct *tty;
 	int len, index = cinfo->bus_index;
-	u8 save_xir, channel, save_car, data, char_count;
+	u8 ivr, save_xir, channel, save_car, data, char_count;
 
 #ifdef CY_DEBUG_INTERRUPTS
 	printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
@@ -1008,26 +457,25 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
 	save_xir = readb(base_addr + (CyRIR << index));
 	channel = save_xir & CyIRChannel;
 	info = &cinfo->ports[channel + chip * 4];
-	save_car = readb(base_addr + (CyCAR << index));
-	cy_writeb(base_addr + (CyCAR << index), save_xir);
+	save_car = cyy_readb(info, CyCAR);
+	cyy_writeb(info, CyCAR, save_xir);
+	ivr = cyy_readb(info, CyRIVR) & CyIVRMask;
 
+	tty = tty_port_tty_get(&info->port);
 	/* if there is nowhere to put the data, discard it */
-	if (info->port.tty == NULL) {
-		if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
-				CyIVRRxEx) {	/* exception */
-			data = readb(base_addr + (CyRDSR << index));
+	if (tty == NULL) {
+		if (ivr == CyIVRRxEx) {	/* exception */
+			data = cyy_readb(info, CyRDSR);
 		} else {	/* normal character reception */
-			char_count = readb(base_addr + (CyRDCR << index));
+			char_count = cyy_readb(info, CyRDCR);
 			while (char_count--)
-				data = readb(base_addr + (CyRDSR << index));
+				data = cyy_readb(info, CyRDSR);
 		}
 		goto end;
 	}
 	/* there is an open port for this data */
-	tty = info->port.tty;
-	if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
-			CyIVRRxEx) {	/* exception */
-		data = readb(base_addr + (CyRDSR << index));
+	if (ivr == CyIVRRxEx) {	/* exception */
+		data = cyy_readb(info, CyRDSR);
 
 		/* For statistics only */
 		if (data & CyBREAK)
@@ -1041,28 +489,29 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
 
 		if (data & info->ignore_status_mask) {
 			info->icount.rx++;
+			tty_kref_put(tty);
 			return;
 		}
 		if (tty_buffer_request_room(tty, 1)) {
 			if (data & info->read_status_mask) {
 				if (data & CyBREAK) {
 					tty_insert_flip_char(tty,
-						readb(base_addr + (CyRDSR <<
-							index)), TTY_BREAK);
+						cyy_readb(info, CyRDSR),
+						TTY_BREAK);
 					info->icount.rx++;
 					if (info->port.flags & ASYNC_SAK)
 						do_SAK(tty);
 				} else if (data & CyFRAME) {
 					tty_insert_flip_char(tty,
-						readb(base_addr + (CyRDSR <<
-							index)), TTY_FRAME);
+						cyy_readb(info, CyRDSR),
+						TTY_FRAME);
 					info->icount.rx++;
 					info->idle_stats.frame_errs++;
 				} else if (data & CyPARITY) {
 					/* Pieces of seven... */
 					tty_insert_flip_char(tty,
-						readb(base_addr + (CyRDSR <<
-							index)), TTY_PARITY);
+						cyy_readb(info, CyRDSR),
+						TTY_PARITY);
 					info->icount.rx++;
 					info->idle_stats.parity_errs++;
 				} else if (data & CyOVERRUN) {
@@ -1074,8 +523,8 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
 					   the next incoming character.
 					 */
 					tty_insert_flip_char(tty,
-						readb(base_addr + (CyRDSR <<
-							index)), TTY_FRAME);
+						cyy_readb(info, CyRDSR),
+						TTY_FRAME);
 					info->icount.rx++;
 					info->idle_stats.overruns++;
 				/* These two conditions may imply */
@@ -1099,7 +548,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
 		}
 	} else {	/* normal character reception */
 		/* load # chars available from the chip */
-		char_count = readb(base_addr + (CyRDCR << index));
+		char_count = cyy_readb(info, CyRDCR);
 
 #ifdef CY_ENABLE_MONITORING
 		++info->mon.int_count;
@@ -1110,7 +559,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
 #endif
 		len = tty_buffer_request_room(tty, char_count);
 		while (len--) {
-			data = readb(base_addr + (CyRDSR << index));
+			data = cyy_readb(info, CyRDSR);
 			tty_insert_flip_char(tty, data, TTY_NORMAL);
 			info->idle_stats.recv_bytes++;
 			info->icount.rx++;
@@ -1121,16 +570,18 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
 		info->idle_stats.recv_idle = jiffies;
 	}
 	tty_schedule_flip(tty);
+	tty_kref_put(tty);
 end:
 	/* end of service */
-	cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f);
-	cy_writeb(base_addr + (CyCAR << index), save_car);
+	cyy_writeb(info, CyRIR, save_xir & 0x3f);
+	cyy_writeb(info, CyCAR, save_car);
 }
 
 static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
 		void __iomem *base_addr)
 {
 	struct cyclades_port *info;
+	struct tty_struct *tty;
 	int char_count, index = cinfo->bus_index;
 	u8 save_xir, channel, save_car, outch;
 
@@ -1154,9 +605,9 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
 		goto end;
 	}
 	info = &cinfo->ports[channel + chip * 4];
-	if (info->port.tty == NULL) {
-		cy_writeb(base_addr + (CySRER << index),
-			  readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+	tty = tty_port_tty_get(&info->port);
+	if (tty == NULL) {
+		cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy);
 		goto end;
 	}
 
@@ -1165,7 +616,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
 
 	if (info->x_char) {	/* send special char */
 		outch = info->x_char;
-		cy_writeb(base_addr + (CyTDR << index), outch);
+		cyy_writeb(info, CyTDR, outch);
 		char_count--;
 		info->icount.tx++;
 		info->x_char = 0;
@@ -1173,14 +624,14 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
 
 	if (info->breakon || info->breakoff) {
 		if (info->breakon) {
-			cy_writeb(base_addr + (CyTDR << index), 0);
-			cy_writeb(base_addr + (CyTDR << index), 0x81);
+			cyy_writeb(info, CyTDR, 0);
+			cyy_writeb(info, CyTDR, 0x81);
 			info->breakon = 0;
 			char_count -= 2;
 		}
 		if (info->breakoff) {
-			cy_writeb(base_addr + (CyTDR << index), 0);
-			cy_writeb(base_addr + (CyTDR << index), 0x83);
+			cyy_writeb(info, CyTDR, 0);
+			cyy_writeb(info, CyTDR, 0x83);
 			info->breakoff = 0;
 			char_count -= 2;
 		}
@@ -1188,27 +639,23 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
 
 	while (char_count-- > 0) {
 		if (!info->xmit_cnt) {
-			if (readb(base_addr + (CySRER << index)) & CyTxMpty) {
-				cy_writeb(base_addr + (CySRER << index),
-					readb(base_addr + (CySRER << index)) &
-						~CyTxMpty);
+			if (cyy_readb(info, CySRER) & CyTxMpty) {
+				cyy_writeb(info, CySRER,
+					cyy_readb(info, CySRER) & ~CyTxMpty);
 			} else {
-				cy_writeb(base_addr + (CySRER << index),
-					(readb(base_addr + (CySRER << index)) &
-						~CyTxRdy) | CyTxMpty);
+				cyy_writeb(info, CySRER, CyTxMpty |
+					(cyy_readb(info, CySRER) & ~CyTxRdy));
 			}
 			goto done;
 		}
 		if (info->port.xmit_buf == NULL) {
-			cy_writeb(base_addr + (CySRER << index),
-				readb(base_addr + (CySRER << index)) &
-					~CyTxRdy);
+			cyy_writeb(info, CySRER,
+				cyy_readb(info, CySRER) & ~CyTxRdy);
 			goto done;
 		}
-		if (info->port.tty->stopped || info->port.tty->hw_stopped) {
-			cy_writeb(base_addr + (CySRER << index),
-				readb(base_addr + (CySRER << index)) &
-					~CyTxRdy);
+		if (tty->stopped || tty->hw_stopped) {
+			cyy_writeb(info, CySRER,
+				cyy_readb(info, CySRER) & ~CyTxRdy);
 			goto done;
 		}
 		/* Because the Embedded Transmit Commands have been enabled,
@@ -1225,15 +672,15 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
 			info->xmit_cnt--;
 			info->xmit_tail = (info->xmit_tail + 1) &
 					(SERIAL_XMIT_SIZE - 1);
-			cy_writeb(base_addr + (CyTDR << index), outch);
+			cyy_writeb(info, CyTDR, outch);
 			info->icount.tx++;
 		} else {
 			if (char_count > 1) {
 				info->xmit_cnt--;
 				info->xmit_tail = (info->xmit_tail + 1) &
 					(SERIAL_XMIT_SIZE - 1);
-				cy_writeb(base_addr + (CyTDR << index), outch);
-				cy_writeb(base_addr + (CyTDR << index), 0);
+				cyy_writeb(info, CyTDR, outch);
+				cyy_writeb(info, CyTDR, 0);
 				info->icount.tx++;
 				char_count--;
 			}
@@ -1241,17 +688,19 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
 	}
 
 done:
-	tty_wakeup(info->port.tty);
+	tty_wakeup(tty);
+	tty_kref_put(tty);
 end:
 	/* end of service */
-	cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
-	cy_writeb(base_addr + (CyCAR << index), save_car);
+	cyy_writeb(info, CyTIR, save_xir & 0x3f);
+	cyy_writeb(info, CyCAR, save_car);
 }
 
 static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
 		void __iomem *base_addr)
 {
 	struct cyclades_port *info;
+	struct tty_struct *tty;
 	int index = cinfo->bus_index;
 	u8 save_xir, channel, save_car, mdm_change, mdm_status;
 
@@ -1259,13 +708,14 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
 	save_xir = readb(base_addr + (CyMIR << index));
 	channel = save_xir & CyIRChannel;
 	info = &cinfo->ports[channel + chip * 4];
-	save_car = readb(base_addr + (CyCAR << index));
-	cy_writeb(base_addr + (CyCAR << index), save_xir);
+	save_car = cyy_readb(info, CyCAR);
+	cyy_writeb(info, CyCAR, save_xir);
 
-	mdm_change = readb(base_addr + (CyMISR << index));
-	mdm_status = readb(base_addr + (CyMSVR1 << index));
+	mdm_change = cyy_readb(info, CyMISR);
+	mdm_status = cyy_readb(info, CyMSVR1);
 
-	if (!info->port.tty)
+	tty = tty_port_tty_get(&info->port);
+	if (!tty)
 		goto end;
 
 	if (mdm_change & CyANY_DELTA) {
@@ -1279,35 +729,32 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
 		if (mdm_change & CyRI)
 			info->icount.rng++;
 
-		wake_up_interruptible(&info->delta_msr_wait);
+		wake_up_interruptible(&info->port.delta_msr_wait);
 	}
 
 	if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
-		if (!(mdm_status & CyDCD)) {
-			tty_hangup(info->port.tty);
-			info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-		}
-		wake_up_interruptible(&info->port.open_wait);
+		if (mdm_status & CyDCD)
+			wake_up_interruptible(&info->port.open_wait);
+		else
+			tty_hangup(tty);
 	}
 	if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) {
-		if (info->port.tty->hw_stopped) {
+		if (tty->hw_stopped) {
 			if (mdm_status & CyCTS) {
 				/* cy_start isn't used
 				   because... !!! */
-				info->port.tty->hw_stopped = 0;
-				cy_writeb(base_addr + (CySRER << index),
-					readb(base_addr + (CySRER << index)) |
-						CyTxRdy);
-				tty_wakeup(info->port.tty);
+				tty->hw_stopped = 0;
+				cyy_writeb(info, CySRER,
+					cyy_readb(info, CySRER) | CyTxRdy);
+				tty_wakeup(tty);
 			}
 		} else {
 			if (!(mdm_status & CyCTS)) {
 				/* cy_stop isn't used
 				   because ... !!! */
-				info->port.tty->hw_stopped = 1;
-				cy_writeb(base_addr + (CySRER << index),
-					readb(base_addr + (CySRER << index)) &
-						~CyTxRdy);
+				tty->hw_stopped = 1;
+				cyy_writeb(info, CySRER,
+					cyy_readb(info, CySRER) & ~CyTxRdy);
 			}
 		}
 	}
@@ -1315,10 +762,11 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
 	}
 	if (mdm_change & CyRI) {
 	}*/
+	tty_kref_put(tty);
 end:
 	/* end of service */
-	cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f);
-	cy_writeb(base_addr + (CyCAR << index), save_car);
+	cyy_writeb(info, CyMIR, save_xir & 0x3f);
+	cyy_writeb(info, CyCAR, save_car);
 }
 
 /* The real interrupt service routine is called
@@ -1389,6 +837,56 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }				/* cyy_interrupt */
 
+static void cyy_change_rts_dtr(struct cyclades_port *info, unsigned int set,
+		unsigned int clear)
+{
+	struct cyclades_card *card = info->card;
+	int channel = info->line - card->first_line;
+	u32 rts, dtr, msvrr, msvrd;
+
+	channel &= 0x03;
+
+	if (info->rtsdtr_inv) {
+		msvrr = CyMSVR2;
+		msvrd = CyMSVR1;
+		rts = CyDTR;
+		dtr = CyRTS;
+	} else {
+		msvrr = CyMSVR1;
+		msvrd = CyMSVR2;
+		rts = CyRTS;
+		dtr = CyDTR;
+	}
+	if (set & TIOCM_RTS) {
+		cyy_writeb(info, CyCAR, channel);
+		cyy_writeb(info, msvrr, rts);
+	}
+	if (clear & TIOCM_RTS) {
+		cyy_writeb(info, CyCAR, channel);
+		cyy_writeb(info, msvrr, ~rts);
+	}
+	if (set & TIOCM_DTR) {
+		cyy_writeb(info, CyCAR, channel);
+		cyy_writeb(info, msvrd, dtr);
+#ifdef CY_DEBUG_DTR
+		printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
+		printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
+			cyy_readb(info, CyMSVR1),
+			cyy_readb(info, CyMSVR2));
+#endif
+	}
+	if (clear & TIOCM_DTR) {
+		cyy_writeb(info, CyCAR, channel);
+		cyy_writeb(info, msvrd, ~dtr);
+#ifdef CY_DEBUG_DTR
+		printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
+		printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
+			cyy_readb(info, CyMSVR1),
+			cyy_readb(info, CyMSVR2));
+#endif
+	}
+}
+
 /***********************************************************/
 /********* End of block of Cyclom-Y specific code **********/
 /******** Start of block of Cyclades-Z specific code *******/
@@ -1398,15 +896,9 @@ static int
 cyz_fetch_msg(struct cyclades_card *cinfo,
 		__u32 *channel, __u8 *cmd, __u32 *param)
 {
-	struct FIRM_ID __iomem *firm_id;
-	struct ZFW_CTRL __iomem *zfw_ctrl;
-	struct BOARD_CTRL __iomem *board_ctrl;
+	struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
 	unsigned long loc_doorbell;
 
-	firm_id = cinfo->base_addr + ID_ADDRESS;
-	zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &zfw_ctrl->board_ctrl;
-
 	loc_doorbell = readl(&cinfo->ctl_addr.p9060->loc_doorbell);
 	if (loc_doorbell) {
 		*cmd = (char)(0xff & loc_doorbell);
@@ -1422,19 +914,13 @@ static int
 cyz_issue_cmd(struct cyclades_card *cinfo,
 		__u32 channel, __u8 cmd, __u32 param)
 {
-	struct FIRM_ID __iomem *firm_id;
-	struct ZFW_CTRL __iomem *zfw_ctrl;
-	struct BOARD_CTRL __iomem *board_ctrl;
+	struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
 	__u32 __iomem *pci_doorbell;
 	unsigned int index;
 
-	firm_id = cinfo->base_addr + ID_ADDRESS;
 	if (!cyz_is_loaded(cinfo))
 		return -1;
 
-	zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &zfw_ctrl->board_ctrl;
-
 	index = 0;
 	pci_doorbell = &cinfo->ctl_addr.p9060->pci_doorbell;
 	while ((readl(pci_doorbell) & 0xff) != 0) {
@@ -1449,11 +935,10 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
 	return 0;
 }				/* cyz_issue_cmd */
 
-static void cyz_handle_rx(struct cyclades_port *info,
-		struct BUF_CTRL __iomem *buf_ctrl)
+static void cyz_handle_rx(struct cyclades_port *info, struct tty_struct *tty)
 {
+	struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
 	struct cyclades_card *cinfo = info->card;
-	struct tty_struct *tty = info->port.tty;
 	unsigned int char_count;
 	int len;
 #ifdef BLOCKMOVE
@@ -1542,11 +1027,10 @@ static void cyz_handle_rx(struct cyclades_port *info,
 	}
 }
 
-static void cyz_handle_tx(struct cyclades_port *info,
-		struct BUF_CTRL __iomem *buf_ctrl)
+static void cyz_handle_tx(struct cyclades_port *info, struct tty_struct *tty)
 {
+	struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
 	struct cyclades_card *cinfo = info->card;
-	struct tty_struct *tty = info->port.tty;
 	u8 data;
 	unsigned int char_count;
 #ifdef BLOCKMOVE
@@ -1621,34 +1105,24 @@ ztxdone:
 
 static void cyz_handle_cmd(struct cyclades_card *cinfo)
 {
+	struct BOARD_CTRL __iomem *board_ctrl = cinfo->board_ctrl;
 	struct tty_struct *tty;
 	struct cyclades_port *info;
-	static struct FIRM_ID __iomem *firm_id;
-	static struct ZFW_CTRL __iomem *zfw_ctrl;
-	static struct BOARD_CTRL __iomem *board_ctrl;
-	static struct CH_CTRL __iomem *ch_ctrl;
-	static struct BUF_CTRL __iomem *buf_ctrl;
 	__u32 channel, param, fw_ver;
 	__u8 cmd;
 	int special_count;
 	int delta_count;
 
-	firm_id = cinfo->base_addr + ID_ADDRESS;
-	zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
-	board_ctrl = &zfw_ctrl->board_ctrl;
 	fw_ver = readl(&board_ctrl->fw_version);
 
 	while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
 		special_count = 0;
 		delta_count = 0;
 		info = &cinfo->ports[channel];
-		tty = info->port.tty;
+		tty = tty_port_tty_get(&info->port);
 		if (tty == NULL)
 			continue;
 
-		ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-		buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-
 		switch (cmd) {
 		case C_CM_PR_ERROR:
 			tty_insert_flip_char(tty, 0, TTY_PARITY);
@@ -1669,15 +1143,12 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
 			info->icount.dcd++;
 			delta_count++;
 			if (info->port.flags & ASYNC_CHECK_CD) {
-				if ((fw_ver > 241 ? ((u_long) param) :
-						readl(&ch_ctrl->rs_status)) &
-						C_RS_DCD) {
+				u32 dcd = fw_ver > 241 ? param :
+					readl(&info->u.cyz.ch_ctrl->rs_status);
+				if (dcd & C_RS_DCD)
 					wake_up_interruptible(&info->port.open_wait);
-				} else {
-					tty_hangup(info->port.tty);
-					wake_up_interruptible(&info->port.open_wait);
-					info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-				}
+				else
+					tty_hangup(tty);
 			}
 			break;
 		case C_CM_MCTS:
@@ -1706,7 +1177,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
 			printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
 					"port %ld\n", info->card, channel);
 #endif
-			cyz_handle_rx(info, buf_ctrl);
+			cyz_handle_rx(info, tty);
 			break;
 		case C_CM_TXBEMPTY:
 		case C_CM_TXLOWWM:
@@ -1716,7 +1187,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
 			printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
 					"port %ld\n", info->card, channel);
 #endif
-			cyz_handle_tx(info, buf_ctrl);
+			cyz_handle_tx(info, tty);
 			break;
 #endif				/* CONFIG_CYZ_INTR */
 		case C_CM_FATAL:
@@ -1726,9 +1197,10 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
 			break;
 		}
 		if (delta_count)
-			wake_up_interruptible(&info->delta_msr_wait);
+			wake_up_interruptible(&info->port.delta_msr_wait);
 		if (special_count)
 			tty_schedule_flip(tty);
+		tty_kref_put(tty);
 	}
 }
 
@@ -1774,10 +1246,6 @@ static void cyz_poll(unsigned long arg)
 {
 	struct cyclades_card *cinfo;
 	struct cyclades_port *info;
-	struct tty_struct *tty;
-	struct FIRM_ID __iomem *firm_id;
-	struct ZFW_CTRL __iomem *zfw_ctrl;
-	struct BUF_CTRL __iomem *buf_ctrl;
 	unsigned long expires = jiffies + HZ;
 	unsigned int port, card;
 
@@ -1789,10 +1257,6 @@ static void cyz_poll(unsigned long arg)
 		if (!cyz_is_loaded(cinfo))
 			continue;
 
-		firm_id = cinfo->base_addr + ID_ADDRESS;
-		zfw_ctrl = cinfo->base_addr +
-				(readl(&firm_id->zfwctrl_addr) & 0xfffff);
-
 	/* Skip first polling cycle to avoid racing conditions with the FW */
 		if (!cinfo->intr_enabled) {
 			cinfo->intr_enabled = 1;
@@ -1802,13 +1266,17 @@ static void cyz_poll(unsigned long arg)
 		cyz_handle_cmd(cinfo);
 
 		for (port = 0; port < cinfo->nports; port++) {
+			struct tty_struct *tty;
+
 			info = &cinfo->ports[port];
-			tty = info->port.tty;
-			buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
+			tty = tty_port_tty_get(&info->port);
+			/* OK to pass NULL to the handle functions below.
+			   They need to drop the data in that case. */
 
 			if (!info->throttle)
-				cyz_handle_rx(info, buf_ctrl);
-			cyz_handle_tx(info, buf_ctrl);
+				cyz_handle_rx(info, tty);
+			cyz_handle_tx(info, tty);
+			tty_kref_put(tty);
 		}
 		/* poll every 'cyz_polling_cycle' period */
 		expires = jiffies + cyz_polling_cycle;
@@ -1824,13 +1292,12 @@ static void cyz_poll(unsigned long arg)
 /* This is called whenever a port becomes active;
    interrupts are enabled and DTR & RTS are turned on.
  */
-static int startup(struct cyclades_port *info)
+static int cy_startup(struct cyclades_port *info, struct tty_struct *tty)
 {
 	struct cyclades_card *card;
 	unsigned long flags;
 	int retval = 0;
-	void __iomem *base_addr;
-	int chip, channel, index;
+	int channel;
 	unsigned long page;
 
 	card = info->card;
@@ -1842,15 +1309,11 @@ static int startup(struct cyclades_port *info)
 
 	spin_lock_irqsave(&card->card_lock, flags);
 
-	if (info->port.flags & ASYNC_INITIALIZED) {
-		free_page(page);
+	if (info->port.flags & ASYNC_INITIALIZED)
 		goto errout;
-	}
 
 	if (!info->type) {
-		if (info->port.tty)
-			set_bit(TTY_IO_ERROR, &info->port.tty->flags);
-		free_page(page);
+		set_bit(TTY_IO_ERROR, &tty->flags);
 		goto errout;
 	}
 
@@ -1861,96 +1324,53 @@ static int startup(struct cyclades_port *info)
 
 	spin_unlock_irqrestore(&card->card_lock, flags);
 
-	set_line_char(info);
+	cy_set_line_char(info, tty);
 
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
 		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
 
-#ifdef CY_DEBUG_OPEN
-		printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, "
-				"base_addr %p\n",
-				card, chip, channel, base_addr);
-#endif
 		spin_lock_irqsave(&card->card_lock, flags);
 
-		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
+		cyy_writeb(info, CyCAR, channel);
 
-		cy_writeb(base_addr + (CyRTPR << index),
+		cyy_writeb(info, CyRTPR,
 			(info->default_timeout ? info->default_timeout : 0x02));
 		/* 10ms rx timeout */
 
-		cyy_issue_cmd(base_addr, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR,
-				index);
-
-		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
-		cy_writeb(base_addr + (CyMSVR1 << index), CyRTS);
-		cy_writeb(base_addr + (CyMSVR2 << index), CyDTR);
-
-#ifdef CY_DEBUG_DTR
-		printk(KERN_DEBUG "cyc:startup raising DTR\n");
-		printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
-			readb(base_addr + (CyMSVR1 << index)),
-			readb(base_addr + (CyMSVR2 << index)));
-#endif
-
-		cy_writeb(base_addr + (CySRER << index),
-			readb(base_addr + (CySRER << index)) | CyRxData);
-		info->port.flags |= ASYNC_INITIALIZED;
-
-		if (info->port.tty)
-			clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
-		info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-		info->breakon = info->breakoff = 0;
-		memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
-		info->idle_stats.in_use =
-		info->idle_stats.recv_idle =
-		info->idle_stats.xmit_idle = jiffies;
+		cyy_issue_cmd(info, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR);
 
-		spin_unlock_irqrestore(&card->card_lock, flags);
+		cyy_change_rts_dtr(info, TIOCM_RTS | TIOCM_DTR, 0);
 
+		cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyRxData);
 	} else {
-		struct FIRM_ID __iomem *firm_id;
-		struct ZFW_CTRL __iomem *zfw_ctrl;
-		struct BOARD_CTRL __iomem *board_ctrl;
-		struct CH_CTRL __iomem *ch_ctrl;
+		struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
 
-		base_addr = card->base_addr;
-
-		firm_id = base_addr + ID_ADDRESS;
 		if (!cyz_is_loaded(card))
 			return -ENODEV;
 
-		zfw_ctrl = card->base_addr +
-				(readl(&firm_id->zfwctrl_addr) & 0xfffff);
-		board_ctrl = &zfw_ctrl->board_ctrl;
-		ch_ctrl = zfw_ctrl->ch_ctrl;
-
 #ifdef CY_DEBUG_OPEN
 		printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
-			"base_addr %p\n", card, channel, base_addr);
+			"base_addr %p\n", card, channel, card->base_addr);
 #endif
 		spin_lock_irqsave(&card->card_lock, flags);
 
-		cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
+		cy_writel(&ch_ctrl->op_mode, C_CH_ENABLE);
 #ifdef Z_WAKE
 #ifdef CONFIG_CYZ_INTR
-		cy_writel(&ch_ctrl[channel].intr_enable,
+		cy_writel(&ch_ctrl->intr_enable,
 			  C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
 			  C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD);
 #else
-		cy_writel(&ch_ctrl[channel].intr_enable,
+		cy_writel(&ch_ctrl->intr_enable,
 			  C_IN_IOCTLW | C_IN_MDCD);
 #endif				/* CONFIG_CYZ_INTR */
 #else
 #ifdef CONFIG_CYZ_INTR
-		cy_writel(&ch_ctrl[channel].intr_enable,
+		cy_writel(&ch_ctrl->intr_enable,
 			  C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM |
 			  C_IN_RXNNDT | C_IN_MDCD);
 #else
-		cy_writel(&ch_ctrl[channel].intr_enable, C_IN_MDCD);
+		cy_writel(&ch_ctrl->intr_enable, C_IN_MDCD);
 #endif				/* CONFIG_CYZ_INTR */
 #endif				/* Z_WAKE */
 
@@ -1969,32 +1389,22 @@ static int startup(struct cyclades_port *info)
 
 		/* set timeout !!! */
 		/* set RTS and DTR !!! */
-		cy_writel(&ch_ctrl[channel].rs_control,
-			readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
-			C_RS_DTR);
-		retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
-		if (retval != 0) {
-			printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was "
-				"%x\n", info->line, retval);
-		}
-#ifdef CY_DEBUG_DTR
-		printk(KERN_DEBUG "cyc:startup raising Z DTR\n");
-#endif
+		tty_port_raise_dtr_rts(&info->port);
 
 		/* enable send, recv, modem !!! */
+	}
 
-		info->port.flags |= ASYNC_INITIALIZED;
-		if (info->port.tty)
-			clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
-		info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-		info->breakon = info->breakoff = 0;
-		memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
-		info->idle_stats.in_use =
-		info->idle_stats.recv_idle =
-		info->idle_stats.xmit_idle = jiffies;
+	info->port.flags |= ASYNC_INITIALIZED;
 
-		spin_unlock_irqrestore(&card->card_lock, flags);
-	}
+	clear_bit(TTY_IO_ERROR, &tty->flags);
+	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+	info->breakon = info->breakoff = 0;
+	memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
+	info->idle_stats.in_use =
+	info->idle_stats.recv_idle =
+	info->idle_stats.xmit_idle = jiffies;
+
+	spin_unlock_irqrestore(&card->card_lock, flags);
 
 #ifdef CY_DEBUG_OPEN
 	printk(KERN_DEBUG "cyc startup done\n");
@@ -2003,28 +1413,20 @@ static int startup(struct cyclades_port *info)
 
 errout:
 	spin_unlock_irqrestore(&card->card_lock, flags);
+	free_page(page);
 	return retval;
 }				/* startup */
 
 static void start_xmit(struct cyclades_port *info)
 {
-	struct cyclades_card *card;
+	struct cyclades_card *card = info->card;
 	unsigned long flags;
-	void __iomem *base_addr;
-	int chip, channel, index;
+	int channel = info->line - card->first_line;
 
-	card = info->card;
-	channel = info->line - card->first_line;
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
-
 		spin_lock_irqsave(&card->card_lock, flags);
-		cy_writeb(base_addr + (CyCAR << index), channel);
-		cy_writeb(base_addr + (CySRER << index),
-			readb(base_addr + (CySRER << index)) | CyTxRdy);
+		cyy_writeb(info, CyCAR, channel & 0x03);
+		cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy);
 		spin_unlock_irqrestore(&card->card_lock, flags);
 	} else {
 #ifdef CONFIG_CYZ_INTR
@@ -2047,12 +1449,11 @@ static void start_xmit(struct cyclades_port *info)
  * This routine shuts down a serial port; interrupts are disabled,
  * and DTR is dropped if the hangup on close termio flag is on.
  */
-static void shutdown(struct cyclades_port *info)
+static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
 {
 	struct cyclades_card *card;
 	unsigned long flags;
-	void __iomem *base_addr;
-	int chip, channel, index;
+	int channel;
 
 	if (!(info->port.flags & ASYNC_INITIALIZED))
 		return;
@@ -2060,21 +1461,10 @@ static void shutdown(struct cyclades_port *info)
 	card = info->card;
 	channel = info->line - card->first_line;
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
-
-#ifdef CY_DEBUG_OPEN
-		printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, "
-				"channel %d, base_addr %p\n",
-				card, chip, channel, base_addr);
-#endif
-
 		spin_lock_irqsave(&card->card_lock, flags);
 
 		/* Clear delta_msr_wait queue to avoid mem leaks. */
-		wake_up_interruptible(&info->delta_msr_wait);
+		wake_up_interruptible(&info->port.delta_msr_wait);
 
 		if (info->port.xmit_buf) {
 			unsigned char *temp;
@@ -2082,47 +1472,25 @@ static void shutdown(struct cyclades_port *info)
 			info->port.xmit_buf = NULL;
 			free_page((unsigned long)temp);
 		}
-		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
-		if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
-			cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS);
-			cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR);
-#ifdef CY_DEBUG_DTR
-			printk(KERN_DEBUG "cyc shutdown dropping DTR\n");
-			printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
-				readb(base_addr + (CyMSVR1 << index)),
-				readb(base_addr + (CyMSVR2 << index)));
-#endif
-		}
-		cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index);
+		if (tty->termios->c_cflag & HUPCL)
+			cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR);
+
+		cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR);
 		/* it may be appropriate to clear _XMIT at
 		   some later date (after testing)!!! */
 
-		if (info->port.tty)
-			set_bit(TTY_IO_ERROR, &info->port.tty->flags);
+		set_bit(TTY_IO_ERROR, &tty->flags);
 		info->port.flags &= ~ASYNC_INITIALIZED;
 		spin_unlock_irqrestore(&card->card_lock, flags);
 	} else {
-		struct FIRM_ID __iomem *firm_id;
-		struct ZFW_CTRL __iomem *zfw_ctrl;
-		struct BOARD_CTRL __iomem *board_ctrl;
-		struct CH_CTRL __iomem *ch_ctrl;
-		int retval;
-
-		base_addr = card->base_addr;
 #ifdef CY_DEBUG_OPEN
 		printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
-			"base_addr %p\n", card, channel, base_addr);
+			"base_addr %p\n", card, channel, card->base_addr);
 #endif
 
-		firm_id = base_addr + ID_ADDRESS;
 		if (!cyz_is_loaded(card))
 			return;
 
-		zfw_ctrl = card->base_addr +
-				(readl(&firm_id->zfwctrl_addr) & 0xfffff);
-		board_ctrl = &zfw_ctrl->board_ctrl;
-		ch_ctrl = zfw_ctrl->ch_ctrl;
-
 		spin_lock_irqsave(&card->card_lock, flags);
 
 		if (info->port.xmit_buf) {
@@ -2132,23 +1500,10 @@ static void shutdown(struct cyclades_port *info)
 			free_page((unsigned long)temp);
 		}
 
-		if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
-			cy_writel(&ch_ctrl[channel].rs_control,
-				(__u32)(readl(&ch_ctrl[channel].rs_control) &
-					~(C_RS_RTS | C_RS_DTR)));
-			retval = cyz_issue_cmd(info->card, channel,
-					C_CM_IOCTLM, 0L);
-			if (retval != 0) {
-				printk(KERN_ERR"cyc:shutdown retval on ttyC%d "
-					"was %x\n", info->line, retval);
-			}
-#ifdef CY_DEBUG_DTR
-			printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n");
-#endif
-		}
+		if (tty->termios->c_cflag & HUPCL)
+			tty_port_lower_dtr_rts(&info->port);
 
-		if (info->port.tty)
-			set_bit(TTY_IO_ERROR, &info->port.tty->flags);
+		set_bit(TTY_IO_ERROR, &tty->flags);
 		info->port.flags &= ~ASYNC_INITIALIZED;
 
 		spin_unlock_irqrestore(&card->card_lock, flags);
@@ -2165,199 +1520,6 @@ static void shutdown(struct cyclades_port *info)
  * ------------------------------------------------------------
  */
 
-static int
-block_til_ready(struct tty_struct *tty, struct file *filp,
-		struct cyclades_port *info)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	struct cyclades_card *cinfo;
-	unsigned long flags;
-	int chip, channel, index;
-	int retval;
-	void __iomem *base_addr;
-
-	cinfo = info->card;
-	channel = info->line - cinfo->first_line;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
-		wait_event_interruptible(info->port.close_wait,
-				!(info->port.flags & ASYNC_CLOSING));
-		return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
-	}
-
-	/*
-	 * If non-blocking mode is set, then make the check up front
-	 * and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-					(tty->flags & (1 << TTY_IO_ERROR))) {
-		info->port.flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, info->port.count is dropped by one, so that
-	 * cy_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&info->port.open_wait, &wait);
-#ifdef CY_DEBUG_OPEN
-	printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, "
-		"count = %d\n", info->line, info->port.count);
-#endif
-	spin_lock_irqsave(&cinfo->card_lock, flags);
-	if (!tty_hung_up_p(filp))
-		info->port.count--;
-	spin_unlock_irqrestore(&cinfo->card_lock, flags);
-#ifdef CY_DEBUG_COUNT
-	printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to "
-		"%d\n", current->pid, info->port.count);
-#endif
-	info->port.blocked_open++;
-
-	if (!cy_is_Z(cinfo)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = cinfo->bus_index;
-		base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
-
-		while (1) {
-			spin_lock_irqsave(&cinfo->card_lock, flags);
-			if ((tty->termios->c_cflag & CBAUD)) {
-				cy_writeb(base_addr + (CyCAR << index),
-					  (u_char) channel);
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  CyRTS);
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  CyDTR);
-#ifdef CY_DEBUG_DTR
-				printk(KERN_DEBUG "cyc:block_til_ready raising "
-					"DTR\n");
-				printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
-					readb(base_addr + (CyMSVR1 << index)),
-					readb(base_addr + (CyMSVR2 << index)));
-#endif
-			}
-			spin_unlock_irqrestore(&cinfo->card_lock, flags);
-
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (tty_hung_up_p(filp) ||
-					!(info->port.flags & ASYNC_INITIALIZED)) {
-				retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
-					  -EAGAIN : -ERESTARTSYS);
-				break;
-			}
-
-			spin_lock_irqsave(&cinfo->card_lock, flags);
-			cy_writeb(base_addr + (CyCAR << index),
-				  (u_char) channel);
-			if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
-					(readb(base_addr +
-						(CyMSVR1 << index)) & CyDCD))) {
-				spin_unlock_irqrestore(&cinfo->card_lock, flags);
-				break;
-			}
-			spin_unlock_irqrestore(&cinfo->card_lock, flags);
-
-			if (signal_pending(current)) {
-				retval = -ERESTARTSYS;
-				break;
-			}
-#ifdef CY_DEBUG_OPEN
-			printk(KERN_DEBUG "cyc block_til_ready blocking: "
-				"ttyC%d, count = %d\n",
-				info->line, info->port.count);
-#endif
-			schedule();
-		}
-	} else {
-		struct FIRM_ID __iomem *firm_id;
-		struct ZFW_CTRL __iomem *zfw_ctrl;
-		struct BOARD_CTRL __iomem *board_ctrl;
-		struct CH_CTRL __iomem *ch_ctrl;
-
-		base_addr = cinfo->base_addr;
-		firm_id = base_addr + ID_ADDRESS;
-		if (!cyz_is_loaded(cinfo)) {
-			__set_current_state(TASK_RUNNING);
-			remove_wait_queue(&info->port.open_wait, &wait);
-			return -EINVAL;
-		}
-
-		zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)
-								& 0xfffff);
-		board_ctrl = &zfw_ctrl->board_ctrl;
-		ch_ctrl = zfw_ctrl->ch_ctrl;
-
-		while (1) {
-			if ((tty->termios->c_cflag & CBAUD)) {
-				cy_writel(&ch_ctrl[channel].rs_control,
-					readl(&ch_ctrl[channel].rs_control) |
-					C_RS_RTS | C_RS_DTR);
-				retval = cyz_issue_cmd(cinfo,
-					channel, C_CM_IOCTLM, 0L);
-				if (retval != 0) {
-					printk(KERN_ERR "cyc:block_til_ready "
-						"retval on ttyC%d was %x\n",
-						info->line, retval);
-				}
-#ifdef CY_DEBUG_DTR
-				printk(KERN_DEBUG "cyc:block_til_ready raising "
-					"Z DTR\n");
-#endif
-			}
-
-			set_current_state(TASK_INTERRUPTIBLE);
-			if (tty_hung_up_p(filp) ||
-					!(info->port.flags & ASYNC_INITIALIZED)) {
-				retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
-					  -EAGAIN : -ERESTARTSYS);
-				break;
-			}
-			if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
-					(readl(&ch_ctrl[channel].rs_status) &
-						C_RS_DCD))) {
-				break;
-			}
-			if (signal_pending(current)) {
-				retval = -ERESTARTSYS;
-				break;
-			}
-#ifdef CY_DEBUG_OPEN
-			printk(KERN_DEBUG "cyc block_til_ready blocking: "
-				"ttyC%d, count = %d\n",
-				info->line, info->port.count);
-#endif
-			schedule();
-		}
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&info->port.open_wait, &wait);
-	if (!tty_hung_up_p(filp)) {
-		info->port.count++;
-#ifdef CY_DEBUG_COUNT
-		printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing "
-			"count to %d\n", current->pid, info->port.count);
-#endif
-	}
-	info->port.blocked_open--;
-#ifdef CY_DEBUG_OPEN
-	printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, "
-		"count = %d\n", info->line, info->port.count);
-#endif
-	if (retval)
-		return retval;
-	info->port.flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}				/* block_til_ready */
-
 /*
  * This routine is called whenever a serial port is opened.  It
  * performs the serial-specific initialization for the tty structure.
@@ -2436,7 +1598,6 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
 	printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
 #endif
 	tty->driver_data = info;
-	info->port.tty = tty;
 	if (serial_paranoia_check(info, tty->name, "cy_open"))
 		return -ENODEV;
 
@@ -2462,11 +1623,11 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
 	/*
 	 * Start up serial port
 	 */
-	retval = startup(info);
+	retval = cy_startup(info, tty);
 	if (retval)
 		return retval;
 
-	retval = block_til_ready(tty, filp, info);
+	retval = tty_port_block_til_ready(&info->port, tty, filp);
 	if (retval) {
 #ifdef CY_DEBUG_OPEN
 		printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready "
@@ -2476,6 +1637,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
 	}
 
 	info->throttle = 0;
+	tty_port_tty_set(&info->port, tty);
 
 #ifdef CY_DEBUG_OPEN
 	printk(KERN_DEBUG "cyc:cy_open done\n");
@@ -2490,8 +1652,6 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
 {
 	struct cyclades_card *card;
 	struct cyclades_port *info = tty->driver_data;
-	void __iomem *base_addr;
-	int chip, channel, index;
 	unsigned long orig_jiffies;
 	int char_time;
 
@@ -2535,13 +1695,8 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
 		timeout, char_time, jiffies);
 #endif
 	card = info->card;
-	channel = (info->line) - (card->first_line);
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
-		while (readb(base_addr + (CySRER << index)) & CyTxRdy) {
+		while (cyy_readb(info, CySRER) & CyTxRdy) {
 #ifdef CY_DEBUG_WAIT_UNTIL_SENT
 			printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
 #endif
@@ -2595,103 +1750,37 @@ static void cy_flush_buffer(struct tty_struct *tty)
 }				/* cy_flush_buffer */
 
 
-/*
- * This routine is called when a particular tty device is closed.
- */
-static void cy_close(struct tty_struct *tty, struct file *filp)
+static void cy_do_close(struct tty_port *port)
 {
-	struct cyclades_port *info = tty->driver_data;
+	struct cyclades_port *info = container_of(port, struct cyclades_port,
+								port);
 	struct cyclades_card *card;
 	unsigned long flags;
-
-#ifdef CY_DEBUG_OTHER
-	printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line);
-#endif
-
-	if (!info || serial_paranoia_check(info, tty->name, "cy_close"))
-		return;
+	int channel;
 
 	card = info->card;
-
-	spin_lock_irqsave(&card->card_lock, flags);
-	/* If the TTY is being hung up, nothing to do */
-	if (tty_hung_up_p(filp)) {
-		spin_unlock_irqrestore(&card->card_lock, flags);
-		return;
-	}
-#ifdef CY_DEBUG_OPEN
-	printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line,
-		info->port.count);
-#endif
-	if ((tty->count == 1) && (info->port.count != 1)) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  Info->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk(KERN_ERR "cyc:cy_close: bad serial port count; "
-			"tty->count is 1, info->port.count is %d\n", info->port.count);
-		info->port.count = 1;
-	}
-#ifdef CY_DEBUG_COUNT
-	printk(KERN_DEBUG  "cyc:cy_close at (%d): decrementing count to %d\n",
-		current->pid, info->port.count - 1);
-#endif
-	if (--info->port.count < 0) {
-#ifdef CY_DEBUG_COUNT
-		printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n");
-#endif
-		info->port.count = 0;
-	}
-	if (info->port.count) {
-		spin_unlock_irqrestore(&card->card_lock, flags);
-		return;
-	}
-	info->port.flags |= ASYNC_CLOSING;
-
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	spin_unlock_irqrestore(&card->card_lock, flags);
-	if (info->port.closing_wait != CY_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->port.closing_wait);
-
+	channel = info->line - card->first_line;
 	spin_lock_irqsave(&card->card_lock, flags);
 
 	if (!cy_is_Z(card)) {
-		int channel = info->line - card->first_line;
-		int index = card->bus_index;
-		void __iomem *base_addr = card->base_addr +
-			(cy_chip_offset[channel >> 2] << index);
 		/* Stop accepting input */
-		channel &= 0x03;
-		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
-		cy_writeb(base_addr + (CySRER << index),
-			  readb(base_addr + (CySRER << index)) & ~CyRxData);
+		cyy_writeb(info, CyCAR, channel & 0x03);
+		cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyRxData);
 		if (info->port.flags & ASYNC_INITIALIZED) {
 			/* Waiting for on-board buffers to be empty before
 			   closing the port */
 			spin_unlock_irqrestore(&card->card_lock, flags);
-			cy_wait_until_sent(tty, info->timeout);
+			cy_wait_until_sent(port->tty, info->timeout);
 			spin_lock_irqsave(&card->card_lock, flags);
 		}
 	} else {
 #ifdef Z_WAKE
 		/* Waiting for on-board buffers to be empty before closing
 		   the port */
-		void __iomem *base_addr = card->base_addr;
-		struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
-		struct ZFW_CTRL __iomem *zfw_ctrl =
-		    base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
-		struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
-		int channel = info->line - card->first_line;
+		struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
 		int retval;
 
-		if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
+		if (readl(&ch_ctrl->flow_status) != C_FS_TXIDLE) {
 			retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
 			if (retval != 0) {
 				printk(KERN_DEBUG "cyc:cy_close retval on "
@@ -2703,32 +1792,19 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
 		}
 #endif
 	}
-
 	spin_unlock_irqrestore(&card->card_lock, flags);
-	shutdown(info);
-	cy_flush_buffer(tty);
-	tty_ldisc_flush(tty);
-	spin_lock_irqsave(&card->card_lock, flags);
-
-	tty->closing = 0;
-	info->port.tty = NULL;
-	if (info->port.blocked_open) {
-		spin_unlock_irqrestore(&card->card_lock, flags);
-		if (info->port.close_delay) {
-			msleep_interruptible(jiffies_to_msecs
-						(info->port.close_delay));
-		}
-		wake_up_interruptible(&info->port.open_wait);
-		spin_lock_irqsave(&card->card_lock, flags);
-	}
-	info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
-	wake_up_interruptible(&info->port.close_wait);
-
-#ifdef CY_DEBUG_OTHER
-	printk(KERN_DEBUG "cyc:cy_close done\n");
-#endif
+	cy_shutdown(info, port->tty);
+}
 
-	spin_unlock_irqrestore(&card->card_lock, flags);
+/*
+ * This routine is called when a particular tty device is closed.
+ */
+static void cy_close(struct tty_struct *tty, struct file *filp)
+{
+	struct cyclades_port *info = tty->driver_data;
+	if (!info || serial_paranoia_check(info, tty->name, "cy_close"))
+		return;
+	tty_port_close(&info->port, tty, filp);
 }				/* cy_close */
 
 /* This routine gets called when tty_write has put something into
@@ -2871,18 +1947,13 @@ static int cy_write_room(struct tty_struct *tty)
 
 static int cy_chars_in_buffer(struct tty_struct *tty)
 {
-	struct cyclades_card *card;
 	struct cyclades_port *info = tty->driver_data;
-	int channel;
 
 	if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
 		return 0;
 
-	card = info->card;
-	channel = (info->line) - (card->first_line);
-
 #ifdef Z_EXT_CHARS_IN_BUFFER
-	if (!cy_is_Z(card)) {
+	if (!cy_is_Z(info->card)) {
 #endif				/* Z_EXT_CHARS_IN_BUFFER */
 #ifdef CY_DEBUG_IO
 		printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
@@ -2891,20 +1962,11 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
 		return info->xmit_cnt;
 #ifdef Z_EXT_CHARS_IN_BUFFER
 	} else {
-		static struct FIRM_ID *firm_id;
-		static struct ZFW_CTRL *zfw_ctrl;
-		static struct CH_CTRL *ch_ctrl;
-		static struct BUF_CTRL *buf_ctrl;
+		struct BUF_CTRL __iomem *buf_ctrl = info->u.cyz.buf_ctrl;
 		int char_count;
 		__u32 tx_put, tx_get, tx_bufsize;
 
 		lock_kernel();
-		firm_id = card->base_addr + ID_ADDRESS;
-		zfw_ctrl = card->base_addr +
-			(readl(&firm_id->zfwctrl_addr) & 0xfffff);
-		ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-		buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
-
 		tx_get = readl(&buf_ctrl->tx_get);
 		tx_put = readl(&buf_ctrl->tx_put);
 		tx_bufsize = readl(&buf_ctrl->tx_bufsize);
@@ -2957,48 +2019,44 @@ static void cyy_baud_calc(struct cyclades_port *info, __u32 baud)
  * This routine finds or computes the various line characteristics.
  * It used to be called config_setup
  */
-static void set_line_char(struct cyclades_port *info)
+static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
 {
 	struct cyclades_card *card;
 	unsigned long flags;
-	void __iomem *base_addr;
-	int chip, channel, index;
+	int channel;
 	unsigned cflag, iflag;
 	int baud, baud_rate = 0;
 	int i;
 
-	if (!info->port.tty || !info->port.tty->termios)
+	if (!tty->termios) /* XXX can this happen at all? */
 		return;
 
 	if (info->line == -1)
 		return;
 
-	cflag = info->port.tty->termios->c_cflag;
-	iflag = info->port.tty->termios->c_iflag;
+	cflag = tty->termios->c_cflag;
+	iflag = tty->termios->c_iflag;
 
 	/*
 	 * Set up the tty->alt_speed kludge
 	 */
-	if (info->port.tty) {
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-			info->port.tty->alt_speed = 57600;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-			info->port.tty->alt_speed = 115200;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-			info->port.tty->alt_speed = 230400;
-		if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-			info->port.tty->alt_speed = 460800;
-	}
+	if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+		tty->alt_speed = 57600;
+	if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+		tty->alt_speed = 115200;
+	if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+		tty->alt_speed = 230400;
+	if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+		tty->alt_speed = 460800;
 
 	card = info->card;
 	channel = info->line - card->first_line;
 
 	if (!cy_is_Z(card)) {
-
-		index = card->bus_index;
+		u32 cflags;
 
 		/* baud rate */
-		baud = tty_get_baud_rate(info->port.tty);
+		baud = tty_get_baud_rate(tty);
 		if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
 				ASYNC_SPD_CUST) {
 			if (info->custom_divisor)
@@ -3107,124 +2165,68 @@ static void set_line_char(struct cyclades_port *info)
 	    cable.  Contact Marcio Saito for details.
 	 ***********************************************/
 
-		chip = channel >> 2;
 		channel &= 0x03;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
 
 		spin_lock_irqsave(&card->card_lock, flags);
-		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
+		cyy_writeb(info, CyCAR, channel);
 
 		/* tx and rx baud rate */
 
-		cy_writeb(base_addr + (CyTCOR << index), info->tco);
-		cy_writeb(base_addr + (CyTBPR << index), info->tbpr);
-		cy_writeb(base_addr + (CyRCOR << index), info->rco);
-		cy_writeb(base_addr + (CyRBPR << index), info->rbpr);
+		cyy_writeb(info, CyTCOR, info->tco);
+		cyy_writeb(info, CyTBPR, info->tbpr);
+		cyy_writeb(info, CyRCOR, info->rco);
+		cyy_writeb(info, CyRBPR, info->rbpr);
 
 		/* set line characteristics  according configuration */
 
-		cy_writeb(base_addr + (CySCHR1 << index),
-			  START_CHAR(info->port.tty));
-		cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->port.tty));
-		cy_writeb(base_addr + (CyCOR1 << index), info->cor1);
-		cy_writeb(base_addr + (CyCOR2 << index), info->cor2);
-		cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
-		cy_writeb(base_addr + (CyCOR4 << index), info->cor4);
-		cy_writeb(base_addr + (CyCOR5 << index), info->cor5);
+		cyy_writeb(info, CySCHR1, START_CHAR(tty));
+		cyy_writeb(info, CySCHR2, STOP_CHAR(tty));
+		cyy_writeb(info, CyCOR1, info->cor1);
+		cyy_writeb(info, CyCOR2, info->cor2);
+		cyy_writeb(info, CyCOR3, info->cor3);
+		cyy_writeb(info, CyCOR4, info->cor4);
+		cyy_writeb(info, CyCOR5, info->cor5);
 
-		cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch |
-				CyCOR3ch, index);
+		cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch |
+				CyCOR3ch);
 
 		/* !!! Is this needed? */
-		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
-		cy_writeb(base_addr + (CyRTPR << index),
+		cyy_writeb(info, CyCAR, channel);
+		cyy_writeb(info, CyRTPR,
 			(info->default_timeout ? info->default_timeout : 0x02));
 		/* 10ms rx timeout */
 
-		if (C_CLOCAL(info->port.tty)) {
-			/* without modem intr */
-			cy_writeb(base_addr + (CySRER << index),
-				readb(base_addr + (CySRER << index)) | CyMdmCh);
-			/* act on 1->0 modem transitions */
-			if ((cflag & CRTSCTS) && info->rflow) {
-				cy_writeb(base_addr + (CyMCOR1 << index),
-					  (CyCTS | rflow_thr[i]));
-			} else {
-				cy_writeb(base_addr + (CyMCOR1 << index),
-					  CyCTS);
-			}
-			/* act on 0->1 modem transitions */
-			cy_writeb(base_addr + (CyMCOR2 << index), CyCTS);
-		} else {
-			/* without modem intr */
-			cy_writeb(base_addr + (CySRER << index),
-				  readb(base_addr +
-					   (CySRER << index)) | CyMdmCh);
-			/* act on 1->0 modem transitions */
-			if ((cflag & CRTSCTS) && info->rflow) {
-				cy_writeb(base_addr + (CyMCOR1 << index),
-					  (CyDSR | CyCTS | CyRI | CyDCD |
-					   rflow_thr[i]));
-			} else {
-				cy_writeb(base_addr + (CyMCOR1 << index),
-					  CyDSR | CyCTS | CyRI | CyDCD);
-			}
-			/* act on 0->1 modem transitions */
-			cy_writeb(base_addr + (CyMCOR2 << index),
-				  CyDSR | CyCTS | CyRI | CyDCD);
-		}
+		cflags = CyCTS;
+		if (!C_CLOCAL(tty))
+			cflags |= CyDSR | CyRI | CyDCD;
+		/* without modem intr */
+		cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyMdmCh);
+		/* act on 1->0 modem transitions */
+		if ((cflag & CRTSCTS) && info->rflow)
+			cyy_writeb(info, CyMCOR1, cflags | rflow_thr[i]);
+		else
+			cyy_writeb(info, CyMCOR1, cflags);
+		/* act on 0->1 modem transitions */
+		cyy_writeb(info, CyMCOR2, cflags);
 
-		if (i == 0) {	/* baud rate is zero, turn off line */
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  ~CyRTS);
-			} else {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  ~CyDTR);
-			}
-#ifdef CY_DEBUG_DTR
-			printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n");
-			printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
-				readb(base_addr + (CyMSVR1 << index)),
-				readb(base_addr + (CyMSVR2 << index)));
-#endif
-		} else {
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  CyRTS);
-			} else {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  CyDTR);
-			}
-#ifdef CY_DEBUG_DTR
-			printk(KERN_DEBUG "cyc:set_line_char raising DTR\n");
-			printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
-				readb(base_addr + (CyMSVR1 << index)),
-				readb(base_addr + (CyMSVR2 << index)));
-#endif
-		}
+		if (i == 0)	/* baud rate is zero, turn off line */
+			cyy_change_rts_dtr(info, 0, TIOCM_DTR);
+		else
+			cyy_change_rts_dtr(info, TIOCM_DTR, 0);
 
-		if (info->port.tty)
-			clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
+		clear_bit(TTY_IO_ERROR, &tty->flags);
 		spin_unlock_irqrestore(&card->card_lock, flags);
 
 	} else {
-		struct FIRM_ID __iomem *firm_id;
-		struct ZFW_CTRL __iomem *zfw_ctrl;
-		struct CH_CTRL __iomem *ch_ctrl;
+		struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
 		__u32 sw_flow;
 		int retval;
 
-		firm_id = card->base_addr + ID_ADDRESS;
 		if (!cyz_is_loaded(card))
 			return;
 
-		zfw_ctrl = card->base_addr +
-			(readl(&firm_id->zfwctrl_addr) & 0xfffff);
-		ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
-
 		/* baud rate */
-		baud = tty_get_baud_rate(info->port.tty);
+		baud = tty_get_baud_rate(tty);
 		if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
 				ASYNC_SPD_CUST) {
 			if (info->custom_divisor)
@@ -3335,45 +2337,38 @@ static void set_line_char(struct cyclades_port *info)
 				"was %x\n", info->line, retval);
 		}
 
-		if (info->port.tty)
-			clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
+		clear_bit(TTY_IO_ERROR, &tty->flags);
 	}
 }				/* set_line_char */
 
-static int
-get_serial_info(struct cyclades_port *info,
+static int cy_get_serial_info(struct cyclades_port *info,
 		struct serial_struct __user *retinfo)
 {
-	struct serial_struct tmp;
 	struct cyclades_card *cinfo = info->card;
-
-	if (!retinfo)
-		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = info->type;
-	tmp.line = info->line;
-	tmp.port = (info->card - cy_card) * 0x100 + info->line -
-		cinfo->first_line;
-	tmp.irq = cinfo->irq;
-	tmp.flags = info->port.flags;
-	tmp.close_delay = info->port.close_delay;
-	tmp.closing_wait = info->port.closing_wait;
-	tmp.baud_base = info->baud;
-	tmp.custom_divisor = info->custom_divisor;
-	tmp.hub6 = 0;		/*!!! */
+	struct serial_struct tmp = {
+		.type = info->type,
+		.line = info->line,
+		.port = (info->card - cy_card) * 0x100 + info->line -
+			cinfo->first_line,
+		.irq = cinfo->irq,
+		.flags = info->port.flags,
+		.close_delay = info->port.close_delay,
+		.closing_wait = info->port.closing_wait,
+		.baud_base = info->baud,
+		.custom_divisor = info->custom_divisor,
+		.hub6 = 0,		/*!!! */
+	};
 	return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
-}				/* get_serial_info */
+}
 
 static int
-set_serial_info(struct cyclades_port *info,
+cy_set_serial_info(struct cyclades_port *info, struct tty_struct *tty,
 		struct serial_struct __user *new_info)
 {
 	struct serial_struct new_serial;
-	struct cyclades_port old_info;
 
 	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
 		return -EFAULT;
-	old_info = *info;
 
 	if (!capable(CAP_SYS_ADMIN)) {
 		if (new_serial.close_delay != info->port.close_delay ||
@@ -3403,10 +2398,10 @@ set_serial_info(struct cyclades_port *info,
 
 check_and_exit:
 	if (info->port.flags & ASYNC_INITIALIZED) {
-		set_line_char(info);
+		cy_set_line_char(info, tty);
 		return 0;
 	} else {
-		return startup(info);
+		return cy_startup(info, tty);
 	}
 }				/* set_serial_info */
 
@@ -3422,24 +2417,14 @@ check_and_exit:
  */
 static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value)
 {
-	struct cyclades_card *card;
-	int chip, channel, index;
-	unsigned char status;
+	struct cyclades_card *card = info->card;
 	unsigned int result;
 	unsigned long flags;
-	void __iomem *base_addr;
+	u8 status;
 
-	card = info->card;
-	channel = (info->line) - (card->first_line);
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
-
 		spin_lock_irqsave(&card->card_lock, flags);
-		status = readb(base_addr + (CySRER << index)) &
-				(CyTxRdy | CyTxMpty);
+		status = cyy_readb(info, CySRER) & (CyTxRdy | CyTxMpty);
 		spin_unlock_irqrestore(&card->card_lock, flags);
 		result = (status ? 0 : TIOCSER_TEMT);
 	} else {
@@ -3453,34 +2438,23 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
 {
 	struct cyclades_port *info = tty->driver_data;
 	struct cyclades_card *card;
-	int chip, channel, index;
-	void __iomem *base_addr;
-	unsigned long flags;
-	unsigned char status;
-	unsigned long lstatus;
-	unsigned int result;
-	struct FIRM_ID __iomem *firm_id;
-	struct ZFW_CTRL __iomem *zfw_ctrl;
-	struct BOARD_CTRL __iomem *board_ctrl;
-	struct CH_CTRL __iomem *ch_ctrl;
+	int result;
 
 	if (serial_paranoia_check(info, tty->name, __func__))
 		return -ENODEV;
 
-	lock_kernel();
-
 	card = info->card;
-	channel = info->line - card->first_line;
+
+	lock_kernel();
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
+		unsigned long flags;
+		int channel = info->line - card->first_line;
+		u8 status;
 
 		spin_lock_irqsave(&card->card_lock, flags);
-		cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
-		status = readb(base_addr + (CyMSVR1 << index));
-		status |= readb(base_addr + (CyMSVR2 << index));
+		cyy_writeb(info, CyCAR, channel & 0x03);
+		status = cyy_readb(info, CyMSVR1);
+		status |= cyy_readb(info, CyMSVR2);
 		spin_unlock_irqrestore(&card->card_lock, flags);
 
 		if (info->rtsdtr_inv) {
@@ -3495,27 +2469,22 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
 			((status & CyDSR) ? TIOCM_DSR : 0) |
 			((status & CyCTS) ? TIOCM_CTS : 0);
 	} else {
-		base_addr = card->base_addr;
-		firm_id = card->base_addr + ID_ADDRESS;
-		if (cyz_is_loaded(card)) {
-			zfw_ctrl = card->base_addr +
-				(readl(&firm_id->zfwctrl_addr) & 0xfffff);
-			board_ctrl = &zfw_ctrl->board_ctrl;
-			ch_ctrl = zfw_ctrl->ch_ctrl;
-			lstatus = readl(&ch_ctrl[channel].rs_status);
-			result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
-				((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
-				((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
-				((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
-				((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
-				((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
-		} else {
-			result = 0;
-			unlock_kernel();
-			return -ENODEV;
+		u32 lstatus;
+
+		if (!cyz_is_loaded(card)) {
+			result = -ENODEV;
+			goto end;
 		}
 
+		lstatus = readl(&info->u.cyz.ch_ctrl->rs_status);
+		result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
+			((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
+			((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
+			((lstatus & C_RS_RI) ? TIOCM_RNG : 0) |
+			((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) |
+			((lstatus & C_RS_CTS) ? TIOCM_CTS : 0);
 	}
+end:
 	unlock_kernel();
 	return result;
 }				/* cy_tiomget */
@@ -3526,150 +2495,53 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
 {
 	struct cyclades_port *info = tty->driver_data;
 	struct cyclades_card *card;
-	int chip, channel, index;
-	void __iomem *base_addr;
 	unsigned long flags;
-	struct FIRM_ID __iomem *firm_id;
-	struct ZFW_CTRL __iomem *zfw_ctrl;
-	struct BOARD_CTRL __iomem *board_ctrl;
-	struct CH_CTRL __iomem *ch_ctrl;
-	int retval;
 
 	if (serial_paranoia_check(info, tty->name, __func__))
 		return -ENODEV;
 
 	card = info->card;
-	channel = (info->line) - (card->first_line);
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
+		spin_lock_irqsave(&card->card_lock, flags);
+		cyy_change_rts_dtr(info, set, clear);
+		spin_unlock_irqrestore(&card->card_lock, flags);
+	} else {
+		struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
+		int retval, channel = info->line - card->first_line;
+		u32 rs;
 
-		if (set & TIOCM_RTS) {
-			spin_lock_irqsave(&card->card_lock, flags);
-			cy_writeb(base_addr + (CyCAR << index),
-				  (u_char) channel);
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  CyDTR);
-			} else {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  CyRTS);
-			}
-			spin_unlock_irqrestore(&card->card_lock, flags);
-		}
-		if (clear & TIOCM_RTS) {
-			spin_lock_irqsave(&card->card_lock, flags);
-			cy_writeb(base_addr + (CyCAR << index),
-				  (u_char) channel);
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  ~CyDTR);
-			} else {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  ~CyRTS);
-			}
-			spin_unlock_irqrestore(&card->card_lock, flags);
-		}
+		if (!cyz_is_loaded(card))
+			return -ENODEV;
+
+		spin_lock_irqsave(&card->card_lock, flags);
+		rs = readl(&ch_ctrl->rs_control);
+		if (set & TIOCM_RTS)
+			rs |= C_RS_RTS;
+		if (clear & TIOCM_RTS)
+			rs &= ~C_RS_RTS;
 		if (set & TIOCM_DTR) {
-			spin_lock_irqsave(&card->card_lock, flags);
-			cy_writeb(base_addr + (CyCAR << index),
-				  (u_char) channel);
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  CyRTS);
-			} else {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  CyDTR);
-			}
+			rs |= C_RS_DTR;
 #ifdef CY_DEBUG_DTR
-			printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
-			printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
-				readb(base_addr + (CyMSVR1 << index)),
-				readb(base_addr + (CyMSVR2 << index)));
+			printk(KERN_DEBUG "cyc:set_modem_info raising Z DTR\n");
 #endif
-			spin_unlock_irqrestore(&card->card_lock, flags);
 		}
 		if (clear & TIOCM_DTR) {
-			spin_lock_irqsave(&card->card_lock, flags);
-			cy_writeb(base_addr + (CyCAR << index),
-				  (u_char) channel);
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  ~CyRTS);
-			} else {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  ~CyDTR);
-			}
-
+			rs &= ~C_RS_DTR;
 #ifdef CY_DEBUG_DTR
-			printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
-			printk(KERN_DEBUG "     status: 0x%x, 0x%x\n",
-				readb(base_addr + (CyMSVR1 << index)),
-				readb(base_addr + (CyMSVR2 << index)));
+			printk(KERN_DEBUG "cyc:set_modem_info clearing "
+				"Z DTR\n");
 #endif
-			spin_unlock_irqrestore(&card->card_lock, flags);
 		}
-	} else {
-		base_addr = card->base_addr;
-
-		firm_id = card->base_addr + ID_ADDRESS;
-		if (cyz_is_loaded(card)) {
-			zfw_ctrl = card->base_addr +
-				(readl(&firm_id->zfwctrl_addr) & 0xfffff);
-			board_ctrl = &zfw_ctrl->board_ctrl;
-			ch_ctrl = zfw_ctrl->ch_ctrl;
-
-			if (set & TIOCM_RTS) {
-				spin_lock_irqsave(&card->card_lock, flags);
-				cy_writel(&ch_ctrl[channel].rs_control,
-					readl(&ch_ctrl[channel].rs_control) |
-					C_RS_RTS);
-				spin_unlock_irqrestore(&card->card_lock, flags);
-			}
-			if (clear & TIOCM_RTS) {
-				spin_lock_irqsave(&card->card_lock, flags);
-				cy_writel(&ch_ctrl[channel].rs_control,
-					readl(&ch_ctrl[channel].rs_control) &
-					~C_RS_RTS);
-				spin_unlock_irqrestore(&card->card_lock, flags);
-			}
-			if (set & TIOCM_DTR) {
-				spin_lock_irqsave(&card->card_lock, flags);
-				cy_writel(&ch_ctrl[channel].rs_control,
-					readl(&ch_ctrl[channel].rs_control) |
-					C_RS_DTR);
-#ifdef CY_DEBUG_DTR
-				printk(KERN_DEBUG "cyc:set_modem_info raising "
-					"Z DTR\n");
-#endif
-				spin_unlock_irqrestore(&card->card_lock, flags);
-			}
-			if (clear & TIOCM_DTR) {
-				spin_lock_irqsave(&card->card_lock, flags);
-				cy_writel(&ch_ctrl[channel].rs_control,
-					readl(&ch_ctrl[channel].rs_control) &
-					~C_RS_DTR);
-#ifdef CY_DEBUG_DTR
-				printk(KERN_DEBUG "cyc:set_modem_info clearing "
-					"Z DTR\n");
-#endif
-				spin_unlock_irqrestore(&card->card_lock, flags);
-			}
-		} else {
-			return -ENODEV;
-		}
-		spin_lock_irqsave(&card->card_lock, flags);
+		cy_writel(&ch_ctrl->rs_control, rs);
 		retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
+		spin_unlock_irqrestore(&card->card_lock, flags);
 		if (retval != 0) {
 			printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
 				"was %x\n", info->line, retval);
 		}
-		spin_unlock_irqrestore(&card->card_lock, flags);
 	}
 	return 0;
-}				/* cy_tiocmset */
+}
 
 /*
  * cy_break() --- routine which turns the break handling on or off
@@ -3734,41 +2606,18 @@ static int cy_break(struct tty_struct *tty, int break_state)
 	return retval;
 }				/* cy_break */
 
-static int get_mon_info(struct cyclades_port *info,
-				struct cyclades_monitor __user *mon)
-{
-
-	if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
-		return -EFAULT;
-	info->mon.int_count = 0;
-	info->mon.char_count = 0;
-	info->mon.char_max = 0;
-	info->mon.char_last = 0;
-	return 0;
-}				/* get_mon_info */
-
 static int set_threshold(struct cyclades_port *info, unsigned long value)
 {
-	struct cyclades_card *card;
-	void __iomem *base_addr;
-	int channel, chip, index;
+	struct cyclades_card *card = info->card;
 	unsigned long flags;
 
-	card = info->card;
-	channel = info->line - card->first_line;
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr =
-		    card->base_addr + (cy_chip_offset[chip] << index);
-
 		info->cor3 &= ~CyREC_FIFO;
 		info->cor3 |= value & CyREC_FIFO;
 
 		spin_lock_irqsave(&card->card_lock, flags);
-		cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
-		cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index);
+		cyy_writeb(info, CyCOR3, info->cor3);
+		cyy_issue_cmd(info, CyCOR_CHANGE | CyCOR3ch);
 		spin_unlock_irqrestore(&card->card_lock, flags);
 	}
 	return 0;
@@ -3777,55 +2626,23 @@ static int set_threshold(struct cyclades_port *info, unsigned long value)
 static int get_threshold(struct cyclades_port *info,
 						unsigned long __user *value)
 {
-	struct cyclades_card *card;
-	void __iomem *base_addr;
-	int channel, chip, index;
-	unsigned long tmp;
+	struct cyclades_card *card = info->card;
 
-	card = info->card;
-	channel = info->line - card->first_line;
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
-
-		tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
+		u8 tmp = cyy_readb(info, CyCOR3) & CyREC_FIFO;
 		return put_user(tmp, value);
 	}
 	return 0;
 }				/* get_threshold */
 
-static int set_default_threshold(struct cyclades_port *info,
-							unsigned long value)
-{
-	info->default_threshold = value & 0x0f;
-	return 0;
-}				/* set_default_threshold */
-
-static int get_default_threshold(struct cyclades_port *info,
-						unsigned long __user *value)
-{
-	return put_user(info->default_threshold, value);
-}				/* get_default_threshold */
-
 static int set_timeout(struct cyclades_port *info, unsigned long value)
 {
-	struct cyclades_card *card;
-	void __iomem *base_addr;
-	int channel, chip, index;
+	struct cyclades_card *card = info->card;
 	unsigned long flags;
 
-	card = info->card;
-	channel = info->line - card->first_line;
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
-
 		spin_lock_irqsave(&card->card_lock, flags);
-		cy_writeb(base_addr + (CyRTPR << index), value & 0xff);
+		cyy_writeb(info, CyRTPR, value & 0xff);
 		spin_unlock_irqrestore(&card->card_lock, flags);
 	}
 	return 0;
@@ -3834,36 +2651,35 @@ static int set_timeout(struct cyclades_port *info, unsigned long value)
 static int get_timeout(struct cyclades_port *info,
 						unsigned long __user *value)
 {
-	struct cyclades_card *card;
-	void __iomem *base_addr;
-	int channel, chip, index;
-	unsigned long tmp;
+	struct cyclades_card *card = info->card;
 
-	card = info->card;
-	channel = info->line - card->first_line;
 	if (!cy_is_Z(card)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		index = card->bus_index;
-		base_addr = card->base_addr + (cy_chip_offset[chip] << index);
-
-		tmp = readb(base_addr + (CyRTPR << index));
+		u8 tmp = cyy_readb(info, CyRTPR);
 		return put_user(tmp, value);
 	}
 	return 0;
 }				/* get_timeout */
 
-static int set_default_timeout(struct cyclades_port *info, unsigned long value)
+static int cy_cflags_changed(struct cyclades_port *info, unsigned long arg,
+		struct cyclades_icount *cprev)
 {
-	info->default_timeout = value & 0xff;
-	return 0;
-}				/* set_default_timeout */
+	struct cyclades_icount cnow;
+	unsigned long flags;
+	int ret;
 
-static int get_default_timeout(struct cyclades_port *info,
-					unsigned long __user *value)
-{
-	return put_user(info->default_timeout, value);
-}				/* get_default_timeout */
+	spin_lock_irqsave(&info->card->card_lock, flags);
+	cnow = info->icount;	/* atomic copy */
+	spin_unlock_irqrestore(&info->card->card_lock, flags);
+
+	ret =	((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));
+
+	*cprev = cnow;
+
+	return ret;
+}
 
 /*
  * This routine allows the tty driver to implement device-
@@ -3875,8 +2691,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 	 unsigned int cmd, unsigned long arg)
 {
 	struct cyclades_port *info = tty->driver_data;
-	struct cyclades_icount cprev, cnow;	/* kernel counter temps */
-	struct serial_icounter_struct __user *p_cuser;	/* user space */
+	struct cyclades_icount cnow;	/* kernel counter temps */
 	int ret_val = 0;
 	unsigned long flags;
 	void __user *argp = (void __user *)arg;
@@ -3892,7 +2707,11 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 
 	switch (cmd) {
 	case CYGETMON:
-		ret_val = get_mon_info(info, argp);
+		if (copy_to_user(argp, &info->mon, sizeof(info->mon))) {
+			ret_val = -EFAULT;
+			break;
+		}
+		memset(&info->mon, 0, sizeof(info->mon));
 		break;
 	case CYGETTHRESH:
 		ret_val = get_threshold(info, argp);
@@ -3901,10 +2720,11 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 		ret_val = set_threshold(info, arg);
 		break;
 	case CYGETDEFTHRESH:
-		ret_val = get_default_threshold(info, argp);
+		ret_val = put_user(info->default_threshold,
+				(unsigned long __user *)argp);
 		break;
 	case CYSETDEFTHRESH:
-		ret_val = set_default_threshold(info, arg);
+		info->default_threshold = arg & 0x0f;
 		break;
 	case CYGETTIMEOUT:
 		ret_val = get_timeout(info, argp);
@@ -3913,21 +2733,20 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 		ret_val = set_timeout(info, arg);
 		break;
 	case CYGETDEFTIMEOUT:
-		ret_val = get_default_timeout(info, argp);
+		ret_val = put_user(info->default_timeout,
+				(unsigned long __user *)argp);
 		break;
 	case CYSETDEFTIMEOUT:
-		ret_val = set_default_timeout(info, arg);
+		info->default_timeout = arg & 0xff;
 		break;
 	case CYSETRFLOW:
 		info->rflow = (int)arg;
-		ret_val = 0;
 		break;
 	case CYGETRFLOW:
 		ret_val = info->rflow;
 		break;
 	case CYSETRTSDTR_INV:
 		info->rtsdtr_inv = (int)arg;
-		ret_val = 0;
 		break;
 	case CYGETRTSDTR_INV:
 		ret_val = info->rtsdtr_inv;
@@ -3938,7 +2757,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 #ifndef CONFIG_CYZ_INTR
 	case CYZSETPOLLCYCLE:
 		cyz_polling_cycle = (arg * HZ) / 1000;
-		ret_val = 0;
 		break;
 	case CYZGETPOLLCYCLE:
 		ret_val = (cyz_polling_cycle * 1000) / HZ;
@@ -3946,16 +2764,15 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 #endif				/* CONFIG_CYZ_INTR */
 	case CYSETWAIT:
 		info->port.closing_wait = (unsigned short)arg * HZ / 100;
-		ret_val = 0;
 		break;
 	case CYGETWAIT:
 		ret_val = info->port.closing_wait / (HZ / 100);
 		break;
 	case TIOCGSERIAL:
-		ret_val = get_serial_info(info, argp);
+		ret_val = cy_get_serial_info(info, argp);
 		break;
 	case TIOCSSERIAL:
-		ret_val = set_serial_info(info, argp);
+		ret_val = cy_set_serial_info(info, tty, argp);
 		break;
 	case TIOCSERGETLSR:	/* Get line status register */
 		ret_val = get_lsr_info(info, argp);
@@ -3971,17 +2788,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 		/* note the counters on entry */
 		cnow = info->icount;
 		spin_unlock_irqrestore(&info->card->card_lock, flags);
-		ret_val = wait_event_interruptible(info->delta_msr_wait, ({
-			cprev = cnow;
-			spin_lock_irqsave(&info->card->card_lock, flags);
-			cnow = info->icount;	/* atomic copy */
-			spin_unlock_irqrestore(&info->card->card_lock, flags);
-
-			((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));
-		}));
+		ret_val = wait_event_interruptible(info->port.delta_msr_wait,
+				cy_cflags_changed(info, arg, &cnow));
 		break;
 
 		/*
@@ -3990,46 +2798,29 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
 		 * NB: both 1->0 and 0->1 transitions are counted except for
 		 *     RI where only 0->1 is counted.
 		 */
-	case TIOCGICOUNT:
+	case TIOCGICOUNT: {
+		struct serial_icounter_struct sic = { };
+
 		spin_lock_irqsave(&info->card->card_lock, flags);
 		cnow = info->icount;
 		spin_unlock_irqrestore(&info->card->card_lock, flags);
-		p_cuser = argp;
-		ret_val = put_user(cnow.cts, &p_cuser->cts);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.dsr, &p_cuser->dsr);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.rng, &p_cuser->rng);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.dcd, &p_cuser->dcd);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.rx, &p_cuser->rx);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.tx, &p_cuser->tx);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.frame, &p_cuser->frame);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.overrun, &p_cuser->overrun);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.parity, &p_cuser->parity);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.brk, &p_cuser->brk);
-		if (ret_val)
-			break;
-		ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
-		if (ret_val)
-			break;
-		ret_val = 0;
+
+		sic.cts = cnow.cts;
+		sic.dsr = cnow.dsr;
+		sic.rng = cnow.rng;
+		sic.dcd = cnow.dcd;
+		sic.rx = cnow.rx;
+		sic.tx = cnow.tx;
+		sic.frame = cnow.frame;
+		sic.overrun = cnow.overrun;
+		sic.parity = cnow.parity;
+		sic.brk = cnow.brk;
+		sic.buf_overrun = cnow.buf_overrun;
+
+		if (copy_to_user(argp, &sic, sizeof(sic)))
+			ret_val = -EFAULT;
 		break;
+	}
 	default:
 		ret_val = -ENOIOCTLCMD;
 	}
@@ -4055,7 +2846,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 	printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
 #endif
 
-	set_line_char(info);
+	cy_set_line_char(info, tty);
 
 	if ((old_termios->c_cflag & CRTSCTS) &&
 			!(tty->termios->c_cflag & CRTSCTS)) {
@@ -4112,8 +2903,6 @@ static void cy_throttle(struct tty_struct *tty)
 	struct cyclades_port *info = tty->driver_data;
 	struct cyclades_card *card;
 	unsigned long flags;
-	void __iomem *base_addr;
-	int chip, channel, index;
 
 #ifdef CY_DEBUG_THROTTLE
 	char buf[64];
@@ -4135,24 +2924,9 @@ static void cy_throttle(struct tty_struct *tty)
 	}
 
 	if (tty->termios->c_cflag & CRTSCTS) {
-		channel = info->line - card->first_line;
 		if (!cy_is_Z(card)) {
-			chip = channel >> 2;
-			channel &= 0x03;
-			index = card->bus_index;
-			base_addr = card->base_addr +
-				(cy_chip_offset[chip] << index);
-
 			spin_lock_irqsave(&card->card_lock, flags);
-			cy_writeb(base_addr + (CyCAR << index),
-				  (u_char) channel);
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  ~CyDTR);
-			} else {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  ~CyRTS);
-			}
+			cyy_change_rts_dtr(info, 0, TIOCM_RTS);
 			spin_unlock_irqrestore(&card->card_lock, flags);
 		} else {
 			info->throttle = 1;
@@ -4170,8 +2944,6 @@ static void cy_unthrottle(struct tty_struct *tty)
 	struct cyclades_port *info = tty->driver_data;
 	struct cyclades_card *card;
 	unsigned long flags;
-	void __iomem *base_addr;
-	int chip, channel, index;
 
 #ifdef CY_DEBUG_THROTTLE
 	char buf[64];
@@ -4192,24 +2964,9 @@ static void cy_unthrottle(struct tty_struct *tty)
 
 	if (tty->termios->c_cflag & CRTSCTS) {
 		card = info->card;
-		channel = info->line - card->first_line;
 		if (!cy_is_Z(card)) {
-			chip = channel >> 2;
-			channel &= 0x03;
-			index = card->bus_index;
-			base_addr = card->base_addr +
-				(cy_chip_offset[chip] << index);
-
 			spin_lock_irqsave(&card->card_lock, flags);
-			cy_writeb(base_addr + (CyCAR << index),
-				  (u_char) channel);
-			if (info->rtsdtr_inv) {
-				cy_writeb(base_addr + (CyMSVR2 << index),
-					  CyDTR);
-			} else {
-				cy_writeb(base_addr + (CyMSVR1 << index),
-					  CyRTS);
-			}
+			cyy_change_rts_dtr(info, TIOCM_RTS, 0);
 			spin_unlock_irqrestore(&card->card_lock, flags);
 		} else {
 			info->throttle = 0;
@@ -4224,8 +2981,7 @@ static void cy_stop(struct tty_struct *tty)
 {
 	struct cyclades_card *cinfo;
 	struct cyclades_port *info = tty->driver_data;
-	void __iomem *base_addr;
-	int chip, channel, index;
+	int channel;
 	unsigned long flags;
 
 #ifdef CY_DEBUG_OTHER
@@ -4238,16 +2994,9 @@ static void cy_stop(struct tty_struct *tty)
 	cinfo = info->card;
 	channel = info->line - cinfo->first_line;
 	if (!cy_is_Z(cinfo)) {
-		index = cinfo->bus_index;
-		chip = channel >> 2;
-		channel &= 0x03;
-		base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
-
 		spin_lock_irqsave(&cinfo->card_lock, flags);
-		cy_writeb(base_addr + (CyCAR << index),
-			(u_char)(channel & 0x0003)); /* index channel */
-		cy_writeb(base_addr + (CySRER << index),
-			  readb(base_addr + (CySRER << index)) & ~CyTxRdy);
+		cyy_writeb(info, CyCAR, channel & 0x03);
+		cyy_writeb(info, CySRER, cyy_readb(info, CySRER) & ~CyTxRdy);
 		spin_unlock_irqrestore(&cinfo->card_lock, flags);
 	}
 }				/* cy_stop */
@@ -4256,8 +3005,7 @@ static void cy_start(struct tty_struct *tty)
 {
 	struct cyclades_card *cinfo;
 	struct cyclades_port *info = tty->driver_data;
-	void __iomem *base_addr;
-	int chip, channel, index;
+	int channel;
 	unsigned long flags;
 
 #ifdef CY_DEBUG_OTHER
@@ -4269,17 +3017,10 @@ static void cy_start(struct tty_struct *tty)
 
 	cinfo = info->card;
 	channel = info->line - cinfo->first_line;
-	index = cinfo->bus_index;
 	if (!cy_is_Z(cinfo)) {
-		chip = channel >> 2;
-		channel &= 0x03;
-		base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
-
 		spin_lock_irqsave(&cinfo->card_lock, flags);
-		cy_writeb(base_addr + (CyCAR << index),
-			(u_char) (channel & 0x0003));	/* index channel */
-		cy_writeb(base_addr + (CySRER << index),
-			  readb(base_addr + (CySRER << index)) | CyTxRdy);
+		cyy_writeb(info, CyCAR, channel & 0x03);
+		cyy_writeb(info, CySRER, cyy_readb(info, CySRER) | CyTxRdy);
 		spin_unlock_irqrestore(&cinfo->card_lock, flags);
 	}
 }				/* cy_start */
@@ -4299,17 +3040,84 @@ static void cy_hangup(struct tty_struct *tty)
 		return;
 
 	cy_flush_buffer(tty);
-	shutdown(info);
-	info->port.count = 0;
-#ifdef CY_DEBUG_COUNT
-	printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
-		current->pid);
-#endif
-	info->port.tty = NULL;
-	info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	wake_up_interruptible(&info->port.open_wait);
+	cy_shutdown(info, tty);
+	tty_port_hangup(&info->port);
 }				/* cy_hangup */
 
+static int cyy_carrier_raised(struct tty_port *port)
+{
+	struct cyclades_port *info = container_of(port, struct cyclades_port,
+			port);
+	struct cyclades_card *cinfo = info->card;
+	unsigned long flags;
+	int channel = info->line - cinfo->first_line;
+	u32 cd;
+
+	spin_lock_irqsave(&cinfo->card_lock, flags);
+	cyy_writeb(info, CyCAR, channel & 0x03);
+	cd = cyy_readb(info, CyMSVR1) & CyDCD;
+	spin_unlock_irqrestore(&cinfo->card_lock, flags);
+
+	return cd;
+}
+
+static void cyy_dtr_rts(struct tty_port *port, int raise)
+{
+	struct cyclades_port *info = container_of(port, struct cyclades_port,
+			port);
+	struct cyclades_card *cinfo = info->card;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cinfo->card_lock, flags);
+	cyy_change_rts_dtr(info, raise ? TIOCM_RTS | TIOCM_DTR : 0,
+			raise ? 0 : TIOCM_RTS | TIOCM_DTR);
+	spin_unlock_irqrestore(&cinfo->card_lock, flags);
+}
+
+static int cyz_carrier_raised(struct tty_port *port)
+{
+	struct cyclades_port *info = container_of(port, struct cyclades_port,
+			port);
+
+	return readl(&info->u.cyz.ch_ctrl->rs_status) & C_RS_DCD;
+}
+
+static void cyz_dtr_rts(struct tty_port *port, int raise)
+{
+	struct cyclades_port *info = container_of(port, struct cyclades_port,
+			port);
+	struct cyclades_card *cinfo = info->card;
+	struct CH_CTRL __iomem *ch_ctrl = info->u.cyz.ch_ctrl;
+	int ret, channel = info->line - cinfo->first_line;
+	u32 rs;
+
+	rs = readl(&ch_ctrl->rs_control);
+	if (raise)
+		rs |= C_RS_RTS | C_RS_DTR;
+	else
+		rs &= ~(C_RS_RTS | C_RS_DTR);
+	cy_writel(&ch_ctrl->rs_control, rs);
+	ret = cyz_issue_cmd(cinfo, channel, C_CM_IOCTLM, 0L);
+	if (ret != 0)
+		printk(KERN_ERR "%s: retval on ttyC%d was %x\n",
+				__func__, info->line, ret);
+#ifdef CY_DEBUG_DTR
+	printk(KERN_DEBUG "%s: raising Z DTR\n", __func__);
+#endif
+}
+
+static const struct tty_port_operations cyy_port_ops = {
+	.carrier_raised = cyy_carrier_raised,
+	.dtr_rts = cyy_dtr_rts,
+	.shutdown = cy_do_close,
+};
+
+static const struct tty_port_operations cyz_port_ops = {
+	.carrier_raised = cyz_carrier_raised,
+	.dtr_rts = cyz_dtr_rts,
+	.shutdown = cy_do_close,
+};
+
 /*
  * ---------------------------------------------------------------------
  * cy_init() and friends
@@ -4321,8 +3129,7 @@ static void cy_hangup(struct tty_struct *tty)
 static int __devinit cy_init_card(struct cyclades_card *cinfo)
 {
 	struct cyclades_port *info;
-	unsigned int port;
-	unsigned short chip_number;
+	unsigned int channel, port;
 
 	spin_lock_init(&cinfo->card_lock);
 	cinfo->intr_enabled = 0;
@@ -4334,9 +3141,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
 		return -ENOMEM;
 	}
 
-	for (port = cinfo->first_line; port < cinfo->first_line + cinfo->nports;
-			port++) {
-		info = &cinfo->ports[port - cinfo->first_line];
+	for (channel = 0, port = cinfo->first_line; channel < cinfo->nports;
+			channel++, port++) {
+		info = &cinfo->ports[channel];
 		tty_port_init(&info->port);
 		info->magic = CYCLADES_MAGIC;
 		info->card = cinfo;
@@ -4346,10 +3153,19 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
 		info->port.close_delay = 5 * HZ / 10;
 		info->port.flags = STD_COM_FLAGS;
 		init_completion(&info->shutdown_wait);
-		init_waitqueue_head(&info->delta_msr_wait);
 
 		if (cy_is_Z(cinfo)) {
+			struct FIRM_ID *firm_id = cinfo->base_addr + ID_ADDRESS;
+			struct ZFW_CTRL *zfw_ctrl;
+
+			info->port.ops = &cyz_port_ops;
 			info->type = PORT_STARTECH;
+
+			zfw_ctrl = cinfo->base_addr +
+				(readl(&firm_id->zfwctrl_addr) & 0xfffff);
+			info->u.cyz.ch_ctrl = &zfw_ctrl->ch_ctrl[channel];
+			info->u.cyz.buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
+
 			if (cinfo->hw_ver == ZO_V1)
 				info->xmit_fifo_size = CYZ_FIFO_SIZE;
 			else
@@ -4359,17 +3175,20 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
 				cyz_rx_restart, (unsigned long)info);
 #endif
 		} else {
+			unsigned short chip_number;
 			int index = cinfo->bus_index;
+
+			info->port.ops = &cyy_port_ops;
 			info->type = PORT_CIRRUS;
 			info->xmit_fifo_size = CyMAX_CHAR_FIFO;
 			info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
 			info->cor2 = CyETC;
 			info->cor3 = 0x08;	/* _very_ small rcv threshold */
 
-			chip_number = (port - cinfo->first_line) / 4;
-			info->chip_rev = readb(cinfo->base_addr +
-				      (cy_chip_offset[chip_number] << index) +
-				      (CyGFRCR << index));
+			chip_number = channel / CyPORTS_PER_CHIP;
+			info->u.cyy.base_addr = cinfo->base_addr +
+				(cy_chip_offset[chip_number] << index);
+			info->chip_rev = cyy_readb(info, CyGFRCR);
 
 			if (info->chip_rev >= CD1400_REV_J) {
 				/* It is a CD1400 rev. J or later */
@@ -5060,8 +3879,14 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
 		}
 		cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
 	} else {
+		struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS;
+		struct ZFW_CTRL __iomem *zfw_ctrl;
+
+		zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
+
 		cy_card[card_no].hw_ver = mailbox;
 		cy_card[card_no].num_chips = (unsigned int)-1;
+		cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl;
 #ifdef CONFIG_CYZ_INTR
 		/* allocate IRQ only if board has an IRQ */
 		if (irq != 0 && irq != 255) {
@@ -5191,18 +4016,30 @@ static int cyclades_proc_show(struct seq_file *m, void *v)
 		for (j = 0; j < cy_card[i].nports; j++) {
 			info = &cy_card[i].ports[j];
 
-			if (info->port.count)
+			if (info->port.count) {
+				/* XXX is the ldisc num worth this? */
+				struct tty_struct *tty;
+				struct tty_ldisc *ld;
+				int num = 0;
+				tty = tty_port_tty_get(&info->port);
+				if (tty) {
+					ld = tty_ldisc_ref(tty);
+					if (ld) {
+						num = ld->ops->num;
+						tty_ldisc_deref(ld);
+					}
+					tty_kref_put(tty);
+				}
 				seq_printf(m, "%3d %8lu %10lu %8lu "
-					"%10lu %8lu %9lu %6ld\n", info->line,
+					"%10lu %8lu %9lu %6d\n", info->line,
 					(cur_jifs - info->idle_stats.in_use) /
 					HZ, info->idle_stats.xmit_bytes,
 					(cur_jifs - info->idle_stats.xmit_idle)/
 					HZ, info->idle_stats.recv_bytes,
 					(cur_jifs - info->idle_stats.recv_idle)/
 					HZ, info->idle_stats.overruns,
-					/* FIXME: double check locking */
-					(long)info->port.tty->ldisc->ops->num);
-			else
+					num);
+			} else
 				seq_printf(m, "%3d %8lu %10lu %8lu "
 					"%10lu %8lu %9lu %6ld\n",
 					info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index a5c59fc..b19d43c 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -572,7 +572,7 @@ static void check_modem_status(struct esp_struct *info)
 			info->icount.dcd++;
 		if (status & UART_MSR_DCTS)
 			info->icount.cts++;
-		wake_up_interruptible(&info->delta_msr_wait);
+		wake_up_interruptible(&info->port.delta_msr_wait);
 	}
 
 	if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
@@ -927,7 +927,7 @@ static void shutdown(struct esp_struct *info)
 	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
 	 * here so the queue might never be waken up
 	 */
-	wake_up_interruptible(&info->delta_msr_wait);
+	wake_up_interruptible(&info->port.delta_msr_wait);
 	wake_up_interruptible(&info->break_wait);
 
 	/* stop a DMA transfer on the port being closed */
@@ -1800,7 +1800,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file *file,
 		spin_unlock_irqrestore(&info->lock, flags);
 		while (1) {
 			/* FIXME: convert to new style wakeup */
-			interruptible_sleep_on(&info->delta_msr_wait);
+			interruptible_sleep_on(&info->port.delta_msr_wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
@@ -2452,7 +2452,6 @@ static int __init espserial_init(void)
 		info->config.flow_off = flow_off;
 		info->config.pio_threshold = pio_threshold;
 		info->next_port = ports;
-		init_waitqueue_head(&info->delta_msr_wait);
 		init_waitqueue_head(&info->break_wait);
 		ports = info;
 		printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ",
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index a00869c..ef31738 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -2,7 +2,7 @@
  * Generic /dev/nvram driver for architectures providing some
  * "generic" hooks, that is :
  *
- * nvram_read_byte, nvram_write_byte, nvram_sync
+ * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size
  *
  * Note that an additional hook is supported for PowerMac only
  * for getting the nvram "partition" informations
@@ -28,6 +28,8 @@
 
 #define NVRAM_SIZE	8192
 
+static ssize_t nvram_len;
+
 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
 	lock_kernel();
@@ -36,7 +38,7 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 		offset += file->f_pos;
 		break;
 	case 2:
-		offset += NVRAM_SIZE;
+		offset += nvram_len;
 		break;
 	}
 	if (offset < 0) {
@@ -56,9 +58,9 @@ static ssize_t read_nvram(struct file *file, char __user *buf,
 
 	if (!access_ok(VERIFY_WRITE, buf, count))
 		return -EFAULT;
-	if (*ppos >= NVRAM_SIZE)
+	if (*ppos >= nvram_len)
 		return 0;
-	for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count)
+	for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count)
 		if (__put_user(nvram_read_byte(i), p))
 			return -EFAULT;
 	*ppos = i;
@@ -74,9 +76,9 @@ static ssize_t write_nvram(struct file *file, const char __user *buf,
 
 	if (!access_ok(VERIFY_READ, buf, count))
 		return -EFAULT;
-	if (*ppos >= NVRAM_SIZE)
+	if (*ppos >= nvram_len)
 		return 0;
-	for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) {
+	for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) {
 		if (__get_user(c, p))
 			return -EFAULT;
 		nvram_write_byte(c, i);
@@ -133,9 +135,20 @@ static struct miscdevice nvram_dev = {
 
 int __init nvram_init(void)
 {
+	int ret = 0;
+
 	printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
 		NVRAM_VERSION);
-	return misc_register(&nvram_dev);
+	ret = misc_register(&nvram_dev);
+	if (ret != 0)
+		goto out;
+
+	nvram_len = nvram_get_size();
+	if (nvram_len < 0)
+		nvram_len = NVRAM_SIZE;
+
+out:
+	return ret;
 }
 
 void __exit nvram_cleanup(void)
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index d97779e..25ce15b 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -516,8 +516,6 @@ static void hvc_set_winsz(struct work_struct *work)
 	struct winsize ws;
 
 	hp = container_of(work, struct hvc_struct, tty_resize);
-	if (!hp)
-		return;
 
 	spin_lock_irqsave(&hp->lock, hvc_flags);
 	if (!hp->tty) {
diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c
index c72b994..10be343 100644
--- a/drivers/char/hvc_vio.c
+++ b/drivers/char/hvc_vio.c
@@ -120,7 +120,7 @@ static struct vio_driver hvc_vio_driver = {
 	}
 };
 
-static int hvc_vio_init(void)
+static int __init hvc_vio_init(void)
 {
 	int rc;
 
@@ -134,7 +134,7 @@ static int hvc_vio_init(void)
 }
 module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
 
-static void hvc_vio_exit(void)
+static void __exit hvc_vio_exit(void)
 {
 	vio_unregister_driver(&hvc_vio_driver);
 }
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index 2989056..793b236 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1230,11 +1230,12 @@ static struct tty_driver *hvsi_console_device(struct console *console,
 
 static int __init hvsi_console_setup(struct console *console, char *options)
 {
-	struct hvsi_struct *hp = &hvsi_ports[console->index];
+	struct hvsi_struct *hp;
 	int ret;
 
 	if (console->index < 0 || console->index >= hvsi_count)
 		return -1;
+	hp = &hvsi_ports[console->index];
 
 	/* give the FSP a chance to change the baud rate when we re-open */
 	hvsi_close_protocol(hp);
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index ce66a70..8706026 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -126,6 +126,19 @@ config HW_RANDOM_OMAP
 
  	  If unsure, say Y.
 
+config HW_RANDOM_OCTEON
+	tristate "Octeon Random Number Generator support"
+	depends on HW_RANDOM && CPU_CAVIUM_OCTEON
+	default HW_RANDOM
+	---help---
+	  This driver provides kernel-side support for the Random Number
+	  Generator hardware found on Octeon processors.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called octeon-rng.
+
+	  If unsure, say Y.
+
 config HW_RANDOM_PASEMI
 	tristate "PA Semi HW Random Number Generator support"
 	depends on HW_RANDOM && PPC_PASEMI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 676828b..5eeb130 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
 obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
 obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
 obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
+obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index fc93e2f..1573aeb 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -153,7 +153,7 @@ static const struct file_operations rng_chrdev_ops = {
 static struct miscdevice rng_miscdev = {
 	.minor		= RNG_MISCDEV_MINOR,
 	.name		= RNG_MODULE_NAME,
-	.devnode	= "hwrng",
+	.nodename	= "hwrng",
 	.fops		= &rng_chrdev_ops,
 };
 
diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c
new file mode 100644
index 0000000..54b0d9b
--- /dev/null
+++ b/drivers/char/hw_random/octeon-rng.c
@@ -0,0 +1,147 @@
+/*
+ * Hardware Random Number Generator support for Cavium Networks
+ * Octeon processor family.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009 Cavium Networks
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-rnm-defs.h>
+
+struct octeon_rng {
+	struct hwrng ops;
+	void __iomem *control_status;
+	void __iomem *result;
+};
+
+static int octeon_rng_init(struct hwrng *rng)
+{
+	union cvmx_rnm_ctl_status ctl;
+	struct octeon_rng *p = container_of(rng, struct octeon_rng, ops);
+
+	ctl.u64 = 0;
+	ctl.s.ent_en = 1; /* Enable the entropy source.  */
+	ctl.s.rng_en = 1; /* Enable the RNG hardware.  */
+	cvmx_write_csr((u64)p->control_status, ctl.u64);
+	return 0;
+}
+
+static void octeon_rng_cleanup(struct hwrng *rng)
+{
+	union cvmx_rnm_ctl_status ctl;
+	struct octeon_rng *p = container_of(rng, struct octeon_rng, ops);
+
+	ctl.u64 = 0;
+	/* Disable everything.  */
+	cvmx_write_csr((u64)p->control_status, ctl.u64);
+}
+
+static int octeon_rng_data_read(struct hwrng *rng, u32 *data)
+{
+	struct octeon_rng *p = container_of(rng, struct octeon_rng, ops);
+
+	*data = cvmx_read64_uint32((u64)p->result);
+	return sizeof(u32);
+}
+
+static int __devinit octeon_rng_probe(struct platform_device *pdev)
+{
+	struct resource *res_ports;
+	struct resource *res_result;
+	struct octeon_rng *rng;
+	int ret;
+	struct hwrng ops = {
+		.name = "octeon",
+		.init = octeon_rng_init,
+		.cleanup = octeon_rng_cleanup,
+		.data_read = octeon_rng_data_read
+	};
+
+	rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+	if (!rng)
+		return -ENOMEM;
+
+	res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res_ports)
+		goto err_ports;
+
+	res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res_result)
+		goto err_ports;
+
+
+	rng->control_status = devm_ioremap_nocache(&pdev->dev,
+						   res_ports->start,
+						   sizeof(u64));
+	if (!rng->control_status)
+		goto err_ports;
+
+	rng->result = devm_ioremap_nocache(&pdev->dev,
+					   res_result->start,
+					   sizeof(u64));
+	if (!rng->result)
+		goto err_r;
+
+	rng->ops = ops;
+
+	dev_set_drvdata(&pdev->dev, &rng->ops);
+	ret = hwrng_register(&rng->ops);
+	if (ret)
+		goto err;
+
+	dev_info(&pdev->dev, "Octeon Random Number Generator\n");
+
+	return 0;
+err:
+	devm_iounmap(&pdev->dev, rng->control_status);
+err_r:
+	devm_iounmap(&pdev->dev, rng->result);
+err_ports:
+	devm_kfree(&pdev->dev, rng);
+	return -ENOENT;
+}
+
+static int __exit octeon_rng_remove(struct platform_device *pdev)
+{
+	struct hwrng *rng = dev_get_drvdata(&pdev->dev);
+
+	hwrng_unregister(rng);
+
+	return 0;
+}
+
+static struct platform_driver octeon_rng_driver = {
+	.driver = {
+		.name		= "octeon_rng",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= octeon_rng_probe,
+	.remove		= __exit_p(octeon_rng_remove),
+};
+
+static int __init octeon_rng_mod_init(void)
+{
+	return platform_driver_register(&octeon_rng_driver);
+}
+
+static void __exit octeon_rng_mod_exit(void)
+{
+	platform_driver_unregister(&octeon_rng_driver);
+}
+
+module_init(octeon_rng_mod_init);
+module_exit(octeon_rng_mod_exit);
+
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 4f1f4cd..426bfdd 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -846,37 +846,53 @@ static int isicom_carrier_raised(struct tty_port *port)
 	return (ip->status & ISI_DCD)?1 : 0;
 }
 
-static int isicom_open(struct tty_struct *tty, struct file *filp)
+static struct tty_port *isicom_find_port(struct tty_struct *tty)
 {
 	struct isi_port *port;
 	struct isi_board *card;
 	unsigned int board;
-	int error, line;
+	int line = tty->index;
 
-	line = tty->index;
 	if (line < 0 || line > PORT_COUNT-1)
-		return -ENODEV;
+		return NULL;
 	board = BOARD(line);
 	card = &isi_card[board];
 
 	if (!(card->status & FIRMWARE_LOADED))
-		return -ENODEV;
+		return NULL;
 
 	/*  open on a port greater than the port count for the card !!! */
 	if (line > ((board * 16) + card->port_count - 1))
-		return -ENODEV;
+		return NULL;
 
 	port = &isi_ports[line];
 	if (isicom_paranoia_check(port, tty->name, "isicom_open"))
-		return -ENODEV;
+		return NULL;
 
+	return &port->port;
+}
+	
+static int isicom_open(struct tty_struct *tty, struct file *filp)
+{
+	struct isi_port *port;
+	struct isi_board *card;
+	struct tty_port *tport;
+	int error = 0;
+
+	tport = isicom_find_port(tty);
+	if (tport == NULL)
+		return -ENODEV;
+	port = container_of(tport, struct isi_port, port);
+	card = &isi_card[BOARD(tty->index)];
 	isicom_setup_board(card);
 
 	/* FIXME: locking on port.count etc */
 	port->port.count++;
 	tty->driver_data = port;
 	tty_port_tty_set(&port->port, tty);
-	error = isicom_setup_port(tty);
+	/* FIXME: Locking on Initialized flag */
+	if (!test_bit(ASYNCB_INITIALIZED, &tport->flags))
+		error = isicom_setup_port(tty);
 	if (error == 0)
 		error = tty_port_block_til_ready(&port->port, tty, filp);
 	return error;
@@ -952,19 +968,12 @@ static void isicom_flush_buffer(struct tty_struct *tty)
 	tty_wakeup(tty);
 }
 
-static void isicom_close(struct tty_struct *tty, struct file *filp)
+static void isicom_close_port(struct tty_port *port)
 {
-	struct isi_port *ip = tty->driver_data;
-	struct tty_port *port = &ip->port;
-	struct isi_board *card;
+	struct isi_port *ip = container_of(port, struct isi_port, port);
+	struct isi_board *card = ip->card;
 	unsigned long flags;
 
-	BUG_ON(!ip);
-
-	card = ip->card;
-	if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
-		return;
-
 	/* indicate to the card that no more data can be received
 	   on this port */
 	spin_lock_irqsave(&card->card_lock, flags);
@@ -974,9 +983,19 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
 	}
 	isicom_shutdown_port(ip);
 	spin_unlock_irqrestore(&card->card_lock, flags);
+}
+
+static void isicom_close(struct tty_struct *tty, struct file *filp)
+{
+	struct isi_port *ip = tty->driver_data;
+	struct tty_port *port = &ip->port;
+	if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
+		return;
 
+	if (tty_port_close_start(port, tty, filp) == 0)
+		return;
+	isicom_close_port(port);
 	isicom_flush_buffer(tty);
-	
 	tty_port_close_end(port, tty);
 }
 
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index acd8e9e..87c67b4 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -15,6 +15,7 @@
 #include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/ioport.h>
+#include <linux/kernel.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
@@ -715,8 +716,8 @@ static ssize_t show_algo(struct device *dev, struct device_attribute *attr, char
 	 */
 	debug0 = *(uint64_t *) soft->debug_addr;
 
-	return sprintf(buf, "0x%lx 0x%lx\n",
-		       (debug0 >> 32), (debug0 & 0xffffffff));
+	return sprintf(buf, "0x%x 0x%x\n",
+		       upper_32_bits(debug0), lower_32_bits(debug0));
 }
 
 static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 645237b..0aede1d 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -864,71 +864,75 @@ static const struct file_operations kmsg_fops = {
 	.write =	kmsg_write,
 };
 
-static const struct {
-	unsigned int		minor;
-	char			*name;
-	umode_t			mode;
-	const struct file_operations	*fops;
-	struct backing_dev_info	*dev_info;
-} devlist[] = { /* list of minor devices */
-	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops,
-		&directly_mappable_cdev_bdi},
+static const struct memdev {
+	const char *name;
+	mode_t mode;
+	const struct file_operations *fops;
+	struct backing_dev_info *dev_info;
+} devlist[] = {
+	 [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
 #ifdef CONFIG_DEVKMEM
-	{2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops,
-		&directly_mappable_cdev_bdi},
+	 [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
 #endif
-	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops, NULL},
+	 [3] = { "null", 0666, &null_fops, NULL },
 #ifdef CONFIG_DEVPORT
-	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops, NULL},
+	 [4] = { "port", 0, &port_fops, NULL },
 #endif
-	{5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops, &zero_bdi},
-	{7, "full",    S_IRUGO | S_IWUGO,           &full_fops, NULL},
-	{8, "random",  S_IRUGO | S_IWUSR,           &random_fops, NULL},
-	{9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops, NULL},
-	{11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops, NULL},
+	 [5] = { "zero", 0666, &zero_fops, &zero_bdi },
+	 [7] = { "full", 0666, &full_fops, NULL },
+	 [8] = { "random", 0666, &random_fops, NULL },
+	 [9] = { "urandom", 0666, &urandom_fops, NULL },
+	[11] = { "kmsg", 0, &kmsg_fops, NULL },
 #ifdef CONFIG_CRASH_DUMP
-	{12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops, NULL},
+	[12] = { "oldmem", 0, &oldmem_fops, NULL },
 #endif
 };
 
 static int memory_open(struct inode *inode, struct file *filp)
 {
-	int ret = 0;
-	int i;
+	int minor;
+	const struct memdev *dev;
+	int ret = -ENXIO;
 
 	lock_kernel();
 
-	for (i = 0; i < ARRAY_SIZE(devlist); i++) {
-		if (devlist[i].minor == iminor(inode)) {
-			filp->f_op = devlist[i].fops;
-			if (devlist[i].dev_info) {
-				filp->f_mapping->backing_dev_info =
-					devlist[i].dev_info;
-			}
+	minor = iminor(inode);
+	if (minor >= ARRAY_SIZE(devlist))
+		goto out;
 
-			break;
-		}
-	}
+	dev = &devlist[minor];
+	if (!dev->fops)
+		goto out;
 
-	if (i == ARRAY_SIZE(devlist))
-		ret = -ENXIO;
-	else
-		if (filp->f_op && filp->f_op->open)
-			ret = filp->f_op->open(inode, filp);
+	filp->f_op = dev->fops;
+	if (dev->dev_info)
+		filp->f_mapping->backing_dev_info = dev->dev_info;
 
+	if (dev->fops->open)
+		ret = dev->fops->open(inode, filp);
+	else
+		ret = 0;
+out:
 	unlock_kernel();
 	return ret;
 }
 
 static const struct file_operations memory_fops = {
-	.open		= memory_open,	/* just a selector for the real open */
+	.open		= memory_open,
 };
 
+static char *mem_devnode(struct device *dev, mode_t *mode)
+{
+	if (mode && devlist[MINOR(dev->devt)].mode)
+		*mode = devlist[MINOR(dev->devt)].mode;
+	return NULL;
+}
+
 static struct class *mem_class;
 
 static int __init chr_dev_init(void)
 {
-	int i;
+	int minor;
 	int err;
 
 	err = bdi_init(&zero_bdi);
@@ -939,10 +943,13 @@ static int __init chr_dev_init(void)
 		printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 
 	mem_class = class_create(THIS_MODULE, "mem");
-	for (i = 0; i < ARRAY_SIZE(devlist); i++)
-		device_create(mem_class, NULL,
-			      MKDEV(MEM_MAJOR, devlist[i].minor), NULL,
-			      devlist[i].name);
+	mem_class->devnode = mem_devnode;
+	for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
+		if (!devlist[minor].name)
+			continue;
+		device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+			      NULL, devlist[minor].name);
+	}
 
 	return 0;
 }
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 62c99fa..1ee27cc 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -263,12 +263,14 @@ int misc_deregister(struct miscdevice *misc)
 EXPORT_SYMBOL(misc_register);
 EXPORT_SYMBOL(misc_deregister);
 
-static char *misc_nodename(struct device *dev)
+static char *misc_devnode(struct device *dev, mode_t *mode)
 {
 	struct miscdevice *c = dev_get_drvdata(dev);
 
-	if (c->devnode)
-		return kstrdup(c->devnode, GFP_KERNEL);
+	if (mode && c->mode)
+		*mode = c->mode;
+	if (c->nodename)
+		return kstrdup(c->nodename, GFP_KERNEL);
 	return NULL;
 }
 
@@ -287,7 +289,7 @@ static int __init misc_init(void)
 	err = -EIO;
 	if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))
 		goto fail_printk;
-	misc_class->nodename = misc_nodename;
+	misc_class->devnode = misc_devnode;
 	return 0;
 
 fail_printk:
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index dbf8d52..5e28d39 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -48,7 +48,7 @@
 
 #include "mxser.h"
 
-#define	MXSER_VERSION	"2.0.4"		/* 1.12 */
+#define	MXSER_VERSION	"2.0.5"		/* 1.14 */
 #define	MXSERMAJOR	 174
 
 #define MXSER_BOARDS		4	/* Max. boards */
@@ -69,6 +69,7 @@
 #define PCI_DEVICE_ID_POS104UL	0x1044
 #define PCI_DEVICE_ID_CB108	0x1080
 #define PCI_DEVICE_ID_CP102UF	0x1023
+#define PCI_DEVICE_ID_CP112UL	0x1120
 #define PCI_DEVICE_ID_CB114	0x1142
 #define PCI_DEVICE_ID_CP114UL	0x1143
 #define PCI_DEVICE_ID_CB134I	0x1341
@@ -139,7 +140,8 @@ static const struct mxser_cardinfo mxser_cards[] = {
 	{ "CP-138U series",	8, },
 	{ "POS-104UL series",	4, },
 	{ "CP-114UL series",	4, },
-/*30*/	{ "CP-102UF series",	2, }
+/*30*/	{ "CP-102UF series",	2, },
+	{ "CP-112UL series",	2, },
 };
 
 /* driver_data correspond to the lines in the structure above
@@ -170,6 +172,7 @@ static struct pci_device_id mxser_pcibrds[] = {
 	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL),	.driver_data = 28 },
 	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP114UL),	.driver_data = 29 },
 	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP102UF),	.driver_data = 30 },
+	{ PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP112UL),	.driver_data = 31 },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
@@ -258,7 +261,6 @@ struct mxser_port {
 	struct mxser_mon mon_data;
 
 	spinlock_t slock;
-	wait_queue_head_t delta_msr_wait;
 };
 
 struct mxser_board {
@@ -818,7 +820,7 @@ static void mxser_check_modem_status(struct tty_struct *tty,
 	if (status & UART_MSR_DCTS)
 		port->icount.cts++;
 	port->mon_data.modem_status = status;
-	wake_up_interruptible(&port->delta_msr_wait);
+	wake_up_interruptible(&port->port.delta_msr_wait);
 
 	if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
 		if (status & UART_MSR_DCD)
@@ -973,7 +975,7 @@ static void mxser_shutdown(struct tty_struct *tty)
 	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
 	 * here so the queue might never be waken up
 	 */
-	wake_up_interruptible(&info->delta_msr_wait);
+	wake_up_interruptible(&info->port.delta_msr_wait);
 
 	/*
 	 * Free the IRQ, if necessary
@@ -1073,34 +1075,17 @@ static void mxser_flush_buffer(struct tty_struct *tty)
 }
 
 
-/*
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- */
-static void mxser_close(struct tty_struct *tty, struct file *filp)
+static void mxser_close_port(struct tty_struct *tty, struct tty_port *port)
 {
-	struct mxser_port *info = tty->driver_data;
-	struct tty_port *port = &info->port;
-
+	struct mxser_port *info = container_of(port, struct mxser_port, port);
 	unsigned long timeout;
-
-	if (tty->index == MXSER_PORTS)
-		return;
-	if (!info)
-		return;
-
-	if (tty_port_close_start(port, tty, filp) == 0)
-		return;
-
 	/*
 	 * Save the termios structure, since this port may have
 	 * separate termios for callout and dialin.
 	 *
 	 * FIXME: Can this go ?
 	 */
-	if (info->port.flags & ASYNC_NORMAL_ACTIVE)
+	if (port->flags & ASYNC_NORMAL_ACTIVE)
 		info->normal_termios = *tty->termios;
 	/*
 	 * At this point we stop accepting input.  To do this, we
@@ -1112,7 +1097,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
 	if (info->board->chip_flag)
 		info->IER &= ~MOXA_MUST_RECV_ISR;
 
-	if (info->port.flags & ASYNC_INITIALIZED) {
+	if (port->flags & ASYNC_INITIALIZED) {
 		outb(info->IER, info->ioaddr + UART_IER);
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
@@ -1127,8 +1112,26 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
 		}
 	}
 	mxser_shutdown(tty);
-	mxser_flush_buffer(tty);
 
+}
+
+/*
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ */
+static void mxser_close(struct tty_struct *tty, struct file *filp)
+{
+	struct mxser_port *info = tty->driver_data;
+	struct tty_port *port = &info->port;
+
+	if (tty->index == MXSER_PORTS)
+		return;
+	if (tty_port_close_start(port, tty, filp) == 0)
+		return;
+	mxser_close_port(tty, port);
+	mxser_flush_buffer(tty);
 	/* Right now the tty_port set is done outside of the close_end helper
 	   as we don't yet have everyone using refcounts */	
 	tty_port_close_end(port, tty);
@@ -1761,7 +1764,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
 		cnow = info->icount;	/* note the counters on entry */
 		spin_unlock_irqrestore(&info->slock, flags);
 
-		return wait_event_interruptible(info->delta_msr_wait,
+		return wait_event_interruptible(info->port.delta_msr_wait,
 				mxser_cflags_changed(info, arg, &cnow));
 	/*
 	 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -1803,7 +1806,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
 
 		lock_kernel();
 		len = mxser_chars_in_buffer(tty);
-		lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT;
+		lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_THRE;
 		len += (lsr ? 0 : 1);
 		unlock_kernel();
 
@@ -2413,7 +2416,6 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
 		info->port.close_delay = 5 * HZ / 10;
 		info->port.closing_wait = 30 * HZ;
 		info->normal_termios = mxvar_sdriver->init_termios;
-		init_waitqueue_head(&info->delta_msr_wait);
 		memset(&info->mon_data, 0, sizeof(struct mxser_mon));
 		info->err_shadow = 0;
 		spin_lock_init(&info->slock);
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 4e28b35..2e50f4d 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -272,7 +272,8 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty)
  *
  *	This is a helper function that handles one output character
  *	(including special characters like TAB, CR, LF, etc.),
- *	putting the results in the tty driver's write buffer.
+ *	doing OPOST processing and putting the results in the
+ *	tty driver's write buffer.
  *
  *	Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
  *	and NLDLY.  They simply aren't relevant in the world today.
@@ -350,8 +351,9 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
  *	@c: character (or partial unicode symbol)
  *	@tty: terminal device
  *
- *	Perform OPOST processing.  Returns -1 when the output device is
- *	full and the character must be retried.
+ *	Output one character with OPOST processing.
+ *	Returns -1 when the output device is full and the character
+ *	must be retried.
  *
  *	Locking: output_lock to protect column state and space left
  *		 (also, this is called from n_tty_write under the
@@ -377,8 +379,11 @@ static int process_output(unsigned char c, struct tty_struct *tty)
 /**
  *	process_output_block		-	block post processor
  *	@tty: terminal device
- *	@inbuf: user buffer
- *	@nr: number of bytes
+ *	@buf: character buffer
+ *	@nr: number of bytes to output
+ *
+ *	Output a block of characters with OPOST processing.
+ *	Returns the number of characters output.
  *
  *	This path is used to speed up block console writes, among other
  *	things when processing blocks of output data. It handles only
@@ -571,33 +576,23 @@ static void process_echoes(struct tty_struct *tty)
 				break;
 
 			default:
-				if (iscntrl(op)) {
-					if (L_ECHOCTL(tty)) {
-						/*
-						 * Ensure there is enough space
-						 * for the whole ctrl pair.
-						 */
-						if (space < 2) {
-							no_space_left = 1;
-							break;
-						}
-						tty_put_char(tty, '^');
-						tty_put_char(tty, op ^ 0100);
-						tty->column += 2;
-						space -= 2;
-					} else {
-						if (!space) {
-							no_space_left = 1;
-							break;
-						}
-						tty_put_char(tty, op);
-						space--;
-					}
-				}
 				/*
-				 * If above falls through, this was an
-				 * undefined op.
+				 * If the op is not a special byte code,
+				 * it is a ctrl char tagged to be echoed
+				 * as "^X" (where X is the letter
+				 * representing the control char).
+				 * Note that we must ensure there is
+				 * enough space for the whole ctrl pair.
+				 *
 				 */
+				if (space < 2) {
+					no_space_left = 1;
+					break;
+				}
+				tty_put_char(tty, '^');
+				tty_put_char(tty, op ^ 0100);
+				tty->column += 2;
+				space -= 2;
 				cp += 2;
 				nr -= 2;
 			}
@@ -605,12 +600,18 @@ static void process_echoes(struct tty_struct *tty)
 			if (no_space_left)
 				break;
 		} else {
-			int retval;
-
-			retval = do_output_char(c, tty, space);
-			if (retval < 0)
-				break;
-			space -= retval;
+			if (O_OPOST(tty) &&
+			    !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
+				int retval = do_output_char(c, tty, space);
+				if (retval < 0)
+					break;
+				space -= retval;
+			} else {
+				if (!space)
+					break;
+				tty_put_char(tty, c);
+				space -= 1;
+			}
 			cp += 1;
 			nr -= 1;
 		}
@@ -798,8 +799,8 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty)
  *	Echo user input back onto the screen. This must be called only when
  *	L_ECHO(tty) is true. Called from the driver receive_buf path.
  *
- *	This variant tags control characters to be possibly echoed as
- *	as "^X" (where X is the letter representing the control char).
+ *	This variant tags control characters to be echoed as "^X"
+ *	(where X is the letter representing the control char).
  *
  *	Locking: echo_lock to protect the echo buffer
  */
@@ -812,7 +813,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty)
 		add_echo_byte(ECHO_OP_START, tty);
 		add_echo_byte(ECHO_OP_START, tty);
 	} else {
-		if (iscntrl(c) && c != '\t')
+		if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
 			add_echo_byte(ECHO_OP_START, tty);
 		add_echo_byte(c, tty);
 	}
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 77b3648..caf6e4d 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -4005,10 +4005,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
  *
  * skb  socket buffer containing HDLC frame
  * dev  pointer to network device structure
- *
- * returns 0 if success, otherwise error code
  */
-static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	MGSLPC_INFO *info = dev_to_port(dev);
 	unsigned long flags;
@@ -4043,7 +4042,7 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	spin_unlock_irqrestore(&info->lock,flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index b33d668..53761ce 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -120,8 +120,10 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
 		/* Stuff the data into the input queue of the other end */
 		c = tty_insert_flip_string(to, buf, c);
 		/* And shovel */
-		tty_flip_buffer_push(to);
-		tty_wakeup(tty);
+		if (c) {
+			tty_flip_buffer_push(to);
+			tty_wakeup(tty);
+		}
 	}
 	return c;
 }
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 05f9d18..64acd05 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -246,7 +246,7 @@ static const struct file_operations raw_fops = {
 	.read	=	do_sync_read,
 	.aio_read = 	generic_file_aio_read,
 	.write	=	do_sync_write,
-	.aio_write = 	generic_file_aio_write_nolock,
+	.aio_write =	blkdev_aio_write,
 	.open	=	raw_open,
 	.release=	raw_release,
 	.ioctl	=	raw_ioctl,
@@ -261,7 +261,7 @@ static const struct file_operations raw_ctl_fops = {
 
 static struct cdev raw_cdev;
 
-static char *raw_nodename(struct device *dev)
+static char *raw_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "raw/%s", dev_name(dev));
 }
@@ -289,7 +289,7 @@ static int __init raw_init(void)
 		ret = PTR_ERR(raw_class);
 		goto error_region;
 	}
-	raw_class->nodename = raw_nodename;
+	raw_class->devnode = raw_devnode;
 	device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 
 	return 0;
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 171711a..3cfa22d 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -343,7 +343,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
 	if (port == NULL)
 		return;
 
-	tty = port->port.tty;
+	tty = tty_port_tty_get(&port->port);
 
 #ifdef RC_REPORT_OVERRUN
 	status = rc_in(bp, CD180_RCSR);
@@ -355,18 +355,18 @@ static void rc_receive_exc(struct riscom_board const *bp)
 #endif
 	ch = rc_in(bp, CD180_RDR);
 	if (!status)
-		return;
+		goto out;
 	if (status & RCSR_TOUT)  {
 		printk(KERN_WARNING "rc%d: port %d: Receiver timeout. "
 				    "Hardware problems ?\n",
 		       board_No(bp), port_No(port));
-		return;
+		goto out;
 
 	} else if (status & RCSR_BREAK)  {
 		printk(KERN_INFO "rc%d: port %d: Handling break...\n",
 		       board_No(bp), port_No(port));
 		flag = TTY_BREAK;
-		if (port->port.flags & ASYNC_SAK)
+		if (tty && (port->port.flags & ASYNC_SAK))
 			do_SAK(tty);
 
 	} else if (status & RCSR_PE)
@@ -380,8 +380,12 @@ static void rc_receive_exc(struct riscom_board const *bp)
 	else
 		flag = TTY_NORMAL;
 
-	tty_insert_flip_char(tty, ch, flag);
-	tty_flip_buffer_push(tty);
+	if (tty) {
+		tty_insert_flip_char(tty, ch, flag);
+		tty_flip_buffer_push(tty);
+	}
+out:
+	tty_kref_put(tty);
 }
 
 static void rc_receive(struct riscom_board const *bp)
@@ -394,7 +398,7 @@ static void rc_receive(struct riscom_board const *bp)
 	if (port == NULL)
 		return;
 
-	tty = port->port.tty;
+	tty = tty_port_tty_get(&port->port);
 
 	count = rc_in(bp, CD180_RDCR);
 
@@ -403,15 +407,14 @@ static void rc_receive(struct riscom_board const *bp)
 #endif
 
 	while (count--)  {
-		if (tty_buffer_request_room(tty, 1) == 0)  {
-			printk(KERN_WARNING "rc%d: port %d: Working around "
-					    "flip buffer overflow.\n",
-			       board_No(bp), port_No(port));
-			break;
-		}
-		tty_insert_flip_char(tty, rc_in(bp, CD180_RDR), TTY_NORMAL);
+		u8 ch = rc_in(bp, CD180_RDR);
+		if (tty)
+			tty_insert_flip_char(tty, ch, TTY_NORMAL);
+	}
+	if (tty) {
+		tty_flip_buffer_push(tty);
+		tty_kref_put(tty);
 	}
-	tty_flip_buffer_push(tty);
 }
 
 static void rc_transmit(struct riscom_board const *bp)
@@ -424,22 +427,22 @@ static void rc_transmit(struct riscom_board const *bp)
 	if (port == NULL)
 		return;
 
-	tty = port->port.tty;
+	tty = tty_port_tty_get(&port->port);
 
 	if (port->IER & IER_TXEMPTY) {
 		/* FIFO drained */
 		rc_out(bp, CD180_CAR, port_No(port));
 		port->IER &= ~IER_TXEMPTY;
 		rc_out(bp, CD180_IER, port->IER);
-		return;
+		goto out;
 	}
 
 	if ((port->xmit_cnt <= 0 && !port->break_length)
-	    || tty->stopped || tty->hw_stopped)  {
+	    || (tty && (tty->stopped || tty->hw_stopped)))  {
 		rc_out(bp, CD180_CAR, port_No(port));
 		port->IER &= ~IER_TXRDY;
 		rc_out(bp, CD180_IER, port->IER);
-		return;
+		goto out;
 	}
 
 	if (port->break_length)  {
@@ -464,7 +467,7 @@ static void rc_transmit(struct riscom_board const *bp)
 			rc_out(bp, CD180_CCR, CCR_CORCHG2);
 			port->break_length = 0;
 		}
-		return;
+		goto out;
 	}
 
 	count = CD180_NFIFO;
@@ -480,8 +483,10 @@ static void rc_transmit(struct riscom_board const *bp)
 		port->IER &= ~IER_TXRDY;
 		rc_out(bp, CD180_IER, port->IER);
 	}
-	if (port->xmit_cnt <= port->wakeup_chars)
+	if (tty && port->xmit_cnt <= port->wakeup_chars)
 		tty_wakeup(tty);
+out:
+	tty_kref_put(tty);
 }
 
 static void rc_check_modem(struct riscom_board const *bp)
@@ -494,37 +499,43 @@ static void rc_check_modem(struct riscom_board const *bp)
 	if (port == NULL)
 		return;
 
-	tty = port->port.tty;
+	tty = tty_port_tty_get(&port->port);
 
 	mcr = rc_in(bp, CD180_MCR);
 	if (mcr & MCR_CDCHG) {
 		if (rc_in(bp, CD180_MSVR) & MSVR_CD)
 			wake_up_interruptible(&port->port.open_wait);
-		else
+		else if (tty)
 			tty_hangup(tty);
 	}
 
 #ifdef RISCOM_BRAIN_DAMAGED_CTS
 	if (mcr & MCR_CTSCHG)  {
 		if (rc_in(bp, CD180_MSVR) & MSVR_CTS)  {
-			tty->hw_stopped = 0;
 			port->IER |= IER_TXRDY;
-			if (port->xmit_cnt <= port->wakeup_chars)
-				tty_wakeup(tty);
+			if (tty) {
+				tty->hw_stopped = 0;
+				if (port->xmit_cnt <= port->wakeup_chars)
+					tty_wakeup(tty);
+			}
 		} else  {
-			tty->hw_stopped = 1;
+			if (tty)
+				tty->hw_stopped = 1;
 			port->IER &= ~IER_TXRDY;
 		}
 		rc_out(bp, CD180_IER, port->IER);
 	}
 	if (mcr & MCR_DSRCHG)  {
 		if (rc_in(bp, CD180_MSVR) & MSVR_DSR)  {
-			tty->hw_stopped = 0;
 			port->IER |= IER_TXRDY;
-			if (port->xmit_cnt <= port->wakeup_chars)
-				tty_wakeup(tty);
+			if (tty) {
+				tty->hw_stopped = 0;
+				if (port->xmit_cnt <= port->wakeup_chars)
+					tty_wakeup(tty);
+			}
 		} else  {
-			tty->hw_stopped = 1;
+			if (tty)
+				tty->hw_stopped = 1;
 			port->IER &= ~IER_TXRDY;
 		}
 		rc_out(bp, CD180_IER, port->IER);
@@ -533,6 +544,7 @@ static void rc_check_modem(struct riscom_board const *bp)
 
 	/* Clear change bits */
 	rc_out(bp, CD180_MCR, 0);
+	tty_kref_put(tty);
 }
 
 /* The main interrupt processing routine */
@@ -632,9 +644,9 @@ static void rc_shutdown_board(struct riscom_board *bp)
  * Setting up port characteristics.
  * Must be called with disabled interrupts
  */
-static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
+static void rc_change_speed(struct tty_struct *tty, struct riscom_board *bp,
+						struct riscom_port *port)
 {
-	struct tty_struct *tty = port->port.tty;
 	unsigned long baud;
 	long tmp;
 	unsigned char cor1 = 0, cor3 = 0;
@@ -781,7 +793,8 @@ static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
 }
 
 /* Must be called with interrupts enabled */
-static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
+static int rc_setup_port(struct tty_struct *tty, struct riscom_board *bp,
+						struct riscom_port *port)
 {
 	unsigned long flags;
 
@@ -793,11 +806,11 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
 
 	spin_lock_irqsave(&riscom_lock, flags);
 
-	clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
+	clear_bit(TTY_IO_ERROR, &tty->flags);
 	if (port->port.count == 1)
 		bp->count++;
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
-	rc_change_speed(bp, port);
+	rc_change_speed(tty, bp, port);
 	port->port.flags |= ASYNC_INITIALIZED;
 
 	spin_unlock_irqrestore(&riscom_lock, flags);
@@ -898,9 +911,9 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
 
 	port->port.count++;
 	tty->driver_data = port;
-	port->port.tty = tty;
+	tty_port_tty_set(&port->port, tty);
 
-	error = rc_setup_port(bp, port);
+	error = rc_setup_port(tty, bp, port);
 	if (error == 0)
 		error = tty_port_block_til_ready(&port->port, tty, filp);
 	return error;
@@ -921,20 +934,12 @@ static void rc_flush_buffer(struct tty_struct *tty)
 	tty_wakeup(tty);
 }
 
-static void rc_close(struct tty_struct *tty, struct file *filp)
+static void rc_close_port(struct tty_port *port)
 {
-	struct riscom_port *port = tty->driver_data;
-	struct riscom_board *bp;
 	unsigned long flags;
+	struct riscom_port *rp = container_of(port, struct riscom_port, port);
+	struct riscom_board *bp = port_Board(rp);
 	unsigned long timeout;
-
-	if (!port || rc_paranoia_check(port, tty->name, "close"))
-		return;
-
-	bp = port_Board(port);
-	
-	if (tty_port_close_start(&port->port, tty, filp) == 0)
-		return;
 	
 	/*
 	 * At this point we stop accepting input.  To do this, we
@@ -944,31 +949,37 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
 	 */
 
 	spin_lock_irqsave(&riscom_lock, flags);
-	port->IER &= ~IER_RXD;
-	if (port->port.flags & ASYNC_INITIALIZED) {
-		port->IER &= ~IER_TXRDY;
-		port->IER |= IER_TXEMPTY;
-		rc_out(bp, CD180_CAR, port_No(port));
-		rc_out(bp, CD180_IER, port->IER);
+	rp->IER &= ~IER_RXD;
+	if (port->flags & ASYNC_INITIALIZED) {
+		rp->IER &= ~IER_TXRDY;
+		rp->IER |= IER_TXEMPTY;
+		rc_out(bp, CD180_CAR, port_No(rp));
+		rc_out(bp, CD180_IER, rp->IER);
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
 		 * has completely drained; this is especially
 		 * important if there is a transmit FIFO!
 		 */
 		timeout = jiffies + HZ;
-		while (port->IER & IER_TXEMPTY) {
+		while (rp->IER & IER_TXEMPTY) {
 			spin_unlock_irqrestore(&riscom_lock, flags);
-			msleep_interruptible(jiffies_to_msecs(port->timeout));
+			msleep_interruptible(jiffies_to_msecs(rp->timeout));
 			spin_lock_irqsave(&riscom_lock, flags);
 			if (time_after(jiffies, timeout))
 				break;
 		}
 	}
-	rc_shutdown_port(tty, bp, port);
-	rc_flush_buffer(tty);
+	rc_shutdown_port(port->tty, bp, rp);
 	spin_unlock_irqrestore(&riscom_lock, flags);
+}
+
+static void rc_close(struct tty_struct *tty, struct file *filp)
+{
+	struct riscom_port *port = tty->driver_data;
 
-	tty_port_close_end(&port->port, tty);
+	if (!port || rc_paranoia_check(port, tty->name, "close"))
+		return;
+	tty_port_close(&port->port, tty, filp);
 }
 
 static int rc_write(struct tty_struct *tty,
@@ -1170,7 +1181,7 @@ static int rc_send_break(struct tty_struct *tty, int length)
 	return 0;
 }
 
-static int rc_set_serial_info(struct riscom_port *port,
+static int rc_set_serial_info(struct tty_struct *tty, struct riscom_port *port,
 				     struct serial_struct __user *newinfo)
 {
 	struct serial_struct tmp;
@@ -1180,17 +1191,6 @@ static int rc_set_serial_info(struct riscom_port *port,
 	if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
 		return -EFAULT;
 
-#if 0
-	if ((tmp.irq != bp->irq) ||
-	    (tmp.port != bp->base) ||
-	    (tmp.type != PORT_CIRRUS) ||
-	    (tmp.baud_base != (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC) ||
-	    (tmp.custom_divisor != 0) ||
-	    (tmp.xmit_fifo_size != CD180_NFIFO) ||
-	    (tmp.flags & ~RISCOM_LEGAL_FLAGS))
-		return -EINVAL;
-#endif
-
 	change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
 			(tmp.flags & ASYNC_SPD_MASK));
 
@@ -1212,7 +1212,7 @@ static int rc_set_serial_info(struct riscom_port *port,
 		unsigned long flags;
 
 		spin_lock_irqsave(&riscom_lock, flags);
-		rc_change_speed(bp, port);
+		rc_change_speed(tty, bp, port);
 		spin_unlock_irqrestore(&riscom_lock, flags);
 	}
 	return 0;
@@ -1255,7 +1255,7 @@ static int rc_ioctl(struct tty_struct *tty, struct file *filp,
 		break;
 	case TIOCSSERIAL:
 		lock_kernel();
-		retval = rc_set_serial_info(port, argp);
+		retval = rc_set_serial_info(tty, port, argp);
 		unlock_kernel();
 		break;
 	default:
@@ -1350,21 +1350,12 @@ static void rc_start(struct tty_struct *tty)
 static void rc_hangup(struct tty_struct *tty)
 {
 	struct riscom_port *port = tty->driver_data;
-	struct riscom_board *bp;
-	unsigned long flags;
 
 	if (rc_paranoia_check(port, tty->name, "rc_hangup"))
 		return;
 
-	bp = port_Board(port);
-
-	rc_shutdown_port(tty, bp, port);
-	spin_lock_irqsave(&port->port.lock, flags);
-	port->port.count = 0;
-	port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
-	port->port.tty = NULL;
-	wake_up_interruptible(&port->port.open_wait);
-	spin_unlock_irqrestore(&port->port.lock, flags);
+	rc_shutdown_port(tty, port_Board(port), port);
+	tty_port_hangup(&port->port);
 }
 
 static void rc_set_termios(struct tty_struct *tty,
@@ -1377,7 +1368,7 @@ static void rc_set_termios(struct tty_struct *tty,
 		return;
 
 	spin_lock_irqsave(&riscom_lock, flags);
-	rc_change_speed(port_Board(port), port);
+	rc_change_speed(tty, port_Board(port), port);
 	spin_unlock_irqrestore(&riscom_lock, flags);
 
 	if ((old_termios->c_cflag & CRTSCTS) &&
@@ -1410,6 +1401,7 @@ static const struct tty_operations riscom_ops = {
 
 static const struct tty_port_operations riscom_port_ops = {
 	.carrier_raised = carrier_raised,
+	.shutdown = rc_close_port,
 };
 
 
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 51e7a46..5942a9d 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -171,7 +171,6 @@ static int startup(struct cyclades_port *);
 static void cy_throttle(struct tty_struct *);
 static void cy_unthrottle(struct tty_struct *);
 static void config_setup(struct cyclades_port *);
-extern void console_print(const char *);
 #ifdef CYCLOM_SHOW_STATUS
 static void show_status(int);
 #endif
@@ -245,7 +244,7 @@ void SP(char *data)
 {
 	unsigned long flags;
 	local_irq_save(flags);
-	console_print(data);
+	printk(KERN_EMERG "%s", data);
 	local_irq_restore(flags);
 }
 
@@ -255,7 +254,7 @@ void CP(char data)
 	unsigned long flags;
 	local_irq_save(flags);
 	scrn[0] = data;
-	console_print(scrn);
+	printk(KERN_EMERG "%c", scrn);
 	local_irq_restore(flags);
 }				/* CP */
 
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 813552f..4846b73 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -7697,10 +7697,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
  *
  * skb  socket buffer containing HDLC frame
  * dev  pointer to network device structure
- *
- * returns 0 if success, otherwise error code
  */
-static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct mgsl_struct *info = dev_to_port(dev);
 	unsigned long flags;
@@ -7731,7 +7730,7 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
 	 	usc_start_transmitter(info);
 	spin_unlock_irqrestore(&info->irq_spinlock,flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 91f20a9..8678f0c 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1497,10 +1497,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
  *
  * skb  socket buffer containing HDLC frame
  * dev  pointer to network device structure
- *
- * returns 0 if success, otherwise error code
  */
-static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct slgt_info *info = dev_to_port(dev);
 	unsigned long flags;
@@ -1529,7 +1528,7 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
 	update_tx_timer(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 8d4a2a8..2b18adc 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1608,10 +1608,9 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
  *
  * skb  socket buffer containing HDLC frame
  * dev  pointer to network device structure
- *
- * returns 0 if success, otherwise error code
  */
-static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	SLMP_INFO *info = dev_to_port(dev);
 	unsigned long flags;
@@ -1642,7 +1641,7 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
 	 	tx_start(info);
 	spin_unlock_irqrestore(&info->lock,flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 50eecfe..44203ff 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -26,7 +26,7 @@
 #include <linux/proc_fs.h>
 #include <linux/nmi.h>
 #include <linux/quotaops.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/suspend.h>
@@ -252,7 +252,7 @@ static void sysrq_handle_showregs(int key, struct tty_struct *tty)
 	struct pt_regs *regs = get_irq_regs();
 	if (regs)
 		show_regs(regs);
-	perf_counter_print_debug();
+	perf_event_print_debug();
 }
 static struct sysrq_key_op sysrq_showregs_op = {
 	.handler	= sysrq_handle_showregs,
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index a3afa0c..ea18a12 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1184,6 +1184,7 @@ int tty_init_termios(struct tty_struct *tty)
 	tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(tty_init_termios);
 
 /**
  *	tty_driver_install_tty() - install a tty entry in the driver
@@ -1386,10 +1387,14 @@ EXPORT_SYMBOL(tty_shutdown);
  *		tty_mutex - sometimes only
  *		takes the file list lock internally when working on the list
  *	of ttys that the driver keeps.
+ *
+ *	This method gets called from a work queue so that the driver private
+ *	shutdown ops can sleep (needed for USB at least)
  */
-static void release_one_tty(struct kref *kref)
+static void release_one_tty(struct work_struct *work)
 {
-	struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
+	struct tty_struct *tty =
+		container_of(work, struct tty_struct, hangup_work);
 	struct tty_driver *driver = tty->driver;
 
 	if (tty->ops->shutdown)
@@ -1407,6 +1412,15 @@ static void release_one_tty(struct kref *kref)
 	free_tty_struct(tty);
 }
 
+static void queue_release_one_tty(struct kref *kref)
+{
+	struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
+	/* The hangup queue is now free so we can reuse it rather than
+	   waste a chunk of memory for each port */
+	INIT_WORK(&tty->hangup_work, release_one_tty);
+	schedule_work(&tty->hangup_work);
+}
+
 /**
  *	tty_kref_put		-	release a tty kref
  *	@tty: tty device
@@ -1418,7 +1432,7 @@ static void release_one_tty(struct kref *kref)
 void tty_kref_put(struct tty_struct *tty)
 {
 	if (tty)
-		kref_put(&tty->kref, release_one_tty);
+		kref_put(&tty->kref, queue_release_one_tty);
 }
 EXPORT_SYMBOL(tty_kref_put);
 
@@ -2085,7 +2099,7 @@ static int tioccons(struct file *file)
  *	the generic functionality existed. This piece of history is preserved
  *	in the expected tty API of posix OS's.
  *
- *	Locking: none, the open fle handle ensures it won't go away.
+ *	Locking: none, the open file handle ensures it won't go away.
  */
 
 static int fionbio(struct file *file, int __user *p)
@@ -3056,11 +3070,22 @@ void __init console_init(void)
 	}
 }
 
+static char *tty_devnode(struct device *dev, mode_t *mode)
+{
+	if (!mode)
+		return NULL;
+	if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
+	    dev->devt == MKDEV(TTYAUX_MAJOR, 2))
+		*mode = 0666;
+	return NULL;
+}
+
 static int __init tty_class_init(void)
 {
 	tty_class = class_create(THIS_MODULE, "tty");
 	if (IS_ERR(tty_class))
 		return PTR_ERR(tty_class);
+	tty_class->devnode = tty_devnode;
 	return 0;
 }
 
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index ad6ba4e..8e67d5c 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -393,9 +393,7 @@ void tty_termios_encode_baud_rate(struct ktermios *termios,
 		termios->c_cflag |= (BOTHER << IBSHIFT);
 #else
 	if (ifound == -1 || ofound == -1) {
-		static int warned;
-		if (!warned++)
-			printk(KERN_WARNING "tty: Unable to return correct "
+		printk_once(KERN_WARNING "tty: Unable to return correct "
 			  "speed data as your architecture needs updating.\n");
 	}
 #endif
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index e48af9f..aafdbae 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -145,48 +145,33 @@ int tty_unregister_ldisc(int disc)
 }
 EXPORT_SYMBOL(tty_unregister_ldisc);
 
-
-/**
- *	tty_ldisc_try_get	-	try and reference an ldisc
- *	@disc: ldisc number
- *
- *	Attempt to open and lock a line discipline into place. Return
- *	the line discipline refcounted or an error.
- */
-
-static struct tty_ldisc *tty_ldisc_try_get(int disc)
+static struct tty_ldisc_ops *get_ldops(int disc)
 {
 	unsigned long flags;
-	struct tty_ldisc *ld;
-	struct tty_ldisc_ops *ldops;
-	int err = -EINVAL;
-
-	ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
-	if (ld == NULL)
-		return ERR_PTR(-ENOMEM);
+	struct tty_ldisc_ops *ldops, *ret;
 
 	spin_lock_irqsave(&tty_ldisc_lock, flags);
-	ld->ops = NULL;
+	ret = ERR_PTR(-EINVAL);
 	ldops = tty_ldiscs[disc];
-	/* Check the entry is defined */
 	if (ldops) {
-		/* If the module is being unloaded we can't use it */
-		if (!try_module_get(ldops->owner))
-			err = -EAGAIN;
-		else {
-			/* lock it */
+		ret = ERR_PTR(-EAGAIN);
+		if (try_module_get(ldops->owner)) {
 			ldops->refcount++;
-			ld->ops = ldops;
-			atomic_set(&ld->users, 1);
-			err = 0;
+			ret = ldops;
 		}
 	}
 	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-	if (err) {
-		kfree(ld);
-		return ERR_PTR(err);
-	}
-	return ld;
+	return ret;
+}
+
+static void put_ldops(struct tty_ldisc_ops *ldops)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+	ldops->refcount--;
+	module_put(ldops->owner);
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
 }
 
 /**
@@ -205,14 +190,31 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
 static struct tty_ldisc *tty_ldisc_get(int disc)
 {
 	struct tty_ldisc *ld;
+	struct tty_ldisc_ops *ldops;
 
 	if (disc < N_TTY || disc >= NR_LDISCS)
 		return ERR_PTR(-EINVAL);
-	ld = tty_ldisc_try_get(disc);
-	if (IS_ERR(ld)) {
+
+	/*
+	 * Get the ldisc ops - we may need to request them to be loaded
+	 * dynamically and try again.
+	 */
+	ldops = get_ldops(disc);
+	if (IS_ERR(ldops)) {
 		request_module("tty-ldisc-%d", disc);
-		ld = tty_ldisc_try_get(disc);
+		ldops = get_ldops(disc);
+		if (IS_ERR(ldops))
+			return ERR_CAST(ldops);
 	}
+
+	ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
+	if (ld == NULL) {
+		put_ldops(ldops);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ld->ops = ldops;
+	atomic_set(&ld->users, 1);
 	return ld;
 }
 
@@ -234,13 +236,13 @@ static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
 static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
 {
 	int i = *(loff_t *)v;
-	struct tty_ldisc *ld;
+	struct tty_ldisc_ops *ldops;
 
-	ld = tty_ldisc_try_get(i);
-	if (IS_ERR(ld))
+	ldops = get_ldops(i);
+	if (IS_ERR(ldops))
 		return 0;
-	seq_printf(m, "%-10s %2d\n", ld->ops->name ? ld->ops->name : "???", i);
-	put_ldisc(ld);
+	seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
+	put_ldops(ldops);
 	return 0;
 }
 
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index 9769b11..a4bbb28 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -23,6 +23,7 @@ void tty_port_init(struct tty_port *port)
 	memset(port, 0, sizeof(*port));
 	init_waitqueue_head(&port->open_wait);
 	init_waitqueue_head(&port->close_wait);
+	init_waitqueue_head(&port->delta_msr_wait);
 	mutex_init(&port->mutex);
 	spin_lock_init(&port->lock);
 	port->close_delay = (50 * HZ) / 100;
@@ -96,6 +97,14 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
 }
 EXPORT_SYMBOL(tty_port_tty_set);
 
+static void tty_port_shutdown(struct tty_port *port)
+{
+	if (port->ops->shutdown &&
+		test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
+			port->ops->shutdown(port);
+
+}
+
 /**
  *	tty_port_hangup		-	hangup helper
  *	@port: tty port
@@ -116,6 +125,8 @@ void tty_port_hangup(struct tty_port *port)
 	port->tty = NULL;
 	spin_unlock_irqrestore(&port->lock, flags);
 	wake_up_interruptible(&port->open_wait);
+	wake_up_interruptible(&port->delta_msr_wait);
+	tty_port_shutdown(port);
 }
 EXPORT_SYMBOL(tty_port_hangup);
 
@@ -296,15 +307,17 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
 
 	if (port->count) {
 		spin_unlock_irqrestore(&port->lock, flags);
+		if (port->ops->drop)
+			port->ops->drop(port);
 		return 0;
 	}
-	port->flags |= ASYNC_CLOSING;
+	set_bit(ASYNCB_CLOSING, &port->flags);
 	tty->closing = 1;
 	spin_unlock_irqrestore(&port->lock, flags);
 	/* Don't block on a stalled port, just pull the chain */
 	if (tty->flow_stopped)
 		tty_driver_flush_buffer(tty);
-	if (port->flags & ASYNC_INITIALIZED &&
+	if (test_bit(ASYNCB_INITIALIZED, &port->flags) &&
 			port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
 		tty_wait_until_sent(tty, port->closing_wait);
 	if (port->drain_delay) {
@@ -318,6 +331,9 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
 			timeout = 2 * HZ;
 		schedule_timeout_interruptible(timeout);
 	}
+	/* Don't call port->drop for the last reference. Callers will want
+	   to drop the last active reference in ->shutdown() or the tty
+	   shutdown path */
 	return 1;
 }
 EXPORT_SYMBOL(tty_port_close_start);
@@ -348,3 +364,14 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty)
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 EXPORT_SYMBOL(tty_port_close_end);
+
+void tty_port_close(struct tty_port *port, struct tty_struct *tty,
+							struct file *filp)
+{
+	if (tty_port_close_start(port, tty, filp) == 0)
+		return;
+	tty_port_shutdown(port);
+	tty_port_close_end(port, tty);
+	tty_port_tty_set(port, NULL);
+}
+EXPORT_SYMBOL(tty_port_close);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 404f4c1..0c80c68 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -252,7 +252,6 @@ static void notify_update(struct vc_data *vc)
 	struct vt_notifier_param param = { .vc = vc };
 	atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
 }
-
 /*
  *	Low-Level Functions
  */
@@ -935,6 +934,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
 
 	if (CON_IS_VISIBLE(vc))
 		update_screen(vc);
+	vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
 	return err;
 }
 
@@ -2129,11 +2129,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 	currcons = vc->vc_num;
 	if (!vc_cons_allocated(currcons)) {
 	    /* could this happen? */
-	    static int error = 0;
-	    if (!error) {
-		error = 1;
-		printk("con_write: tty %d not allocated\n", currcons+1);
-	    }
+		printk_once("con_write: tty %d not allocated\n", currcons+1);
 	    release_console_sem();
 	    return 0;
 	}
@@ -2910,6 +2906,9 @@ static const struct tty_operations con_ops = {
 	.flush_chars = con_flush_chars,
 	.chars_in_buffer = con_chars_in_buffer,
 	.ioctl = vt_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = vt_compat_ioctl,
+#endif
 	.stop = con_stop,
 	.start = con_start,
 	.throttle = con_throttle,
@@ -2948,9 +2947,6 @@ int __init vty_init(const struct file_operations *console_fops)
 		panic("Couldn't register console driver\n");
 	kbd_init();
 	console_map_init();
-#ifdef CONFIG_PROM_CONSOLE
-	prom_con_init();
-#endif
 #ifdef CONFIG_MDA_CONSOLE
 	mda_console_init();
 #endif
@@ -2958,7 +2954,6 @@ int __init vty_init(const struct file_operations *console_fops)
 }
 
 #ifndef VT_SINGLE_DRIVER
-#include <linux/device.h>
 
 static struct class *vtconsole_class;
 
@@ -3641,6 +3636,7 @@ void do_blank_screen(int entering_gfx)
 		blank_state = blank_vesa_wait;
 		mod_timer(&console_timer, jiffies + vesa_off_interval);
 	}
+	vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
 }
 EXPORT_SYMBOL(do_blank_screen);
 
@@ -3685,6 +3681,7 @@ void do_unblank_screen(int leaving_gfx)
 		console_blank_hook(0);
 	set_palette(vc);
 	set_cursor(vc);
+	vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
 }
 EXPORT_SYMBOL(do_unblank_screen);
 
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 95189f2..29c651a 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -16,6 +16,8 @@
 #include <linux/tty.h>
 #include <linux/timer.h>
 #include <linux/kernel.h>
+#include <linux/compat.h>
+#include <linux/module.h>
 #include <linux/kd.h>
 #include <linux/vt.h>
 #include <linux/string.h>
@@ -62,6 +64,133 @@ extern struct tty_driver *console_driver;
 static void complete_change_console(struct vc_data *vc);
 
 /*
+ *	User space VT_EVENT handlers
+ */
+
+struct vt_event_wait {
+	struct list_head list;
+	struct vt_event event;
+	int done;
+};
+
+static LIST_HEAD(vt_events);
+static DEFINE_SPINLOCK(vt_event_lock);
+static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
+
+/**
+ *	vt_event_post
+ *	@event: the event that occurred
+ *	@old: old console
+ *	@new: new console
+ *
+ *	Post an VT event to interested VT handlers
+ */
+
+void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
+{
+	struct list_head *pos, *head;
+	unsigned long flags;
+	int wake = 0;
+
+	spin_lock_irqsave(&vt_event_lock, flags);
+	head = &vt_events;
+
+	list_for_each(pos, head) {
+		struct vt_event_wait *ve = list_entry(pos,
+						struct vt_event_wait, list);
+		if (!(ve->event.event & event))
+			continue;
+		ve->event.event = event;
+		/* kernel view is consoles 0..n-1, user space view is
+		   console 1..n with 0 meaning current, so we must bias */
+		ve->event.old = old + 1;
+		ve->event.new = new + 1;
+		wake = 1;
+		ve->done = 1;
+	}
+	spin_unlock_irqrestore(&vt_event_lock, flags);
+	if (wake)
+		wake_up_interruptible(&vt_event_waitqueue);
+}
+
+/**
+ *	vt_event_wait		-	wait for an event
+ *	@vw: our event
+ *
+ *	Waits for an event to occur which completes our vt_event_wait
+ *	structure. On return the structure has wv->done set to 1 for success
+ *	or 0 if some event such as a signal ended the wait.
+ */
+
+static void vt_event_wait(struct vt_event_wait *vw)
+{
+	unsigned long flags;
+	/* Prepare the event */
+	INIT_LIST_HEAD(&vw->list);
+	vw->done = 0;
+	/* Queue our event */
+	spin_lock_irqsave(&vt_event_lock, flags);
+	list_add(&vw->list, &vt_events);
+	spin_unlock_irqrestore(&vt_event_lock, flags);
+	/* Wait for it to pass */
+	wait_event_interruptible(vt_event_waitqueue, vw->done);
+	/* Dequeue it */
+	spin_lock_irqsave(&vt_event_lock, flags);
+	list_del(&vw->list);
+	spin_unlock_irqrestore(&vt_event_lock, flags);
+}
+
+/**
+ *	vt_event_wait_ioctl	-	event ioctl handler
+ *	@arg: argument to ioctl
+ *
+ *	Implement the VT_WAITEVENT ioctl using the VT event interface
+ */
+
+static int vt_event_wait_ioctl(struct vt_event __user *event)
+{
+	struct vt_event_wait vw;
+
+	if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
+		return -EFAULT;
+	/* Highest supported event for now */
+	if (vw.event.event & ~VT_MAX_EVENT)
+		return -EINVAL;
+
+	vt_event_wait(&vw);
+	/* If it occurred report it */
+	if (vw.done) {
+		if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINTR;
+}
+
+/**
+ *	vt_waitactive	-	active console wait
+ *	@event: event code
+ *	@n: new console
+ *
+ *	Helper for event waits. Used to implement the legacy
+ *	event waiting ioctls in terms of events
+ */
+
+int vt_waitactive(int n)
+{
+	struct vt_event_wait vw;
+	do {
+		if (n == fg_console + 1)
+			break;
+		vw.event.event = VT_EVENT_SWITCH;
+		vt_event_wait(&vw);
+		if (vw.done == 0)
+			return -EINTR;
+	} while (vw.event.new != n);
+	return 0;
+}
+
+/*
  * these are the valid i/o ports we're allowed to change. they map all the
  * video ports
  */
@@ -360,6 +489,8 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_
 	return 0;
 }
 
+
+
 /*
  * We handle the console-specific ioctl's here.  We allow the
  * capability to modify any console, not just the fg_console. 
@@ -842,6 +973,41 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		}
 		break;
 
+	case VT_SETACTIVATE:
+	{
+		struct vt_setactivate vsa;
+
+		if (!perm)
+			goto eperm;
+
+		if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
+						sizeof(struct vt_setactivate)))
+			return -EFAULT;
+		if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
+			ret = -ENXIO;
+		else {
+			vsa.console--;
+			acquire_console_sem();
+			ret = vc_allocate(vsa.console);
+			if (ret == 0) {
+				struct vc_data *nvc;
+				/* This is safe providing we don't drop the
+				   console sem between vc_allocate and
+				   finishing referencing nvc */
+				nvc = vc_cons[vsa.console].d;
+				nvc->vt_mode = vsa.mode;
+				nvc->vt_mode.frsig = 0;
+				put_pid(nvc->vt_pid);
+				nvc->vt_pid = get_pid(task_pid(current));
+			}
+			release_console_sem();
+			if (ret)
+				break;
+			/* Commence switch and lock */
+			set_console(arg);
+		}
+	}
+
 	/*
 	 * wait until the specified VT has been activated
 	 */
@@ -851,7 +1017,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		if (arg == 0 || arg > MAX_NR_CONSOLES)
 			ret = -ENXIO;
 		else
-			ret = vt_waitactive(arg - 1);
+			ret = vt_waitactive(arg);
 		break;
 
 	/*
@@ -1159,6 +1325,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
 		ret = put_user(vc->vc_hi_font_mask,
 					(unsigned short __user *)arg);
 		break;
+	case VT_WAITEVENT:
+		ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
+		break;
 	default:
 		ret = -ENOIOCTLCMD;
 	}
@@ -1170,54 +1339,6 @@ eperm:
 	goto out;
 }
 
-/*
- * Sometimes we want to wait until a particular VT has been activated. We
- * do it in a very simple manner. Everybody waits on a single queue and
- * get woken up at once. Those that are satisfied go on with their business,
- * while those not ready go back to sleep. Seems overkill to add a wait
- * to each vt just for this - usually this does nothing!
- */
-static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
-
-/*
- * Sleeps until a vt is activated, or the task is interrupted. Returns
- * 0 if activation, -EINTR if interrupted by a signal handler.
- */
-int vt_waitactive(int vt)
-{
-	int retval;
-	DECLARE_WAITQUEUE(wait, current);
-
-	add_wait_queue(&vt_activate_queue, &wait);
-	for (;;) {
-		retval = 0;
-
-		/*
-		 * Synchronize with redraw_screen(). By acquiring the console
-		 * semaphore we make sure that the console switch is completed
-		 * before we return. If we didn't wait for the semaphore, we
-		 * could return at a point where fg_console has already been
-		 * updated, but the console switch hasn't been completed.
-		 */
-		acquire_console_sem();
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (vt == fg_console) {
-			release_console_sem();
-			break;
-		}
-		release_console_sem();
-		retval = -ERESTARTNOHAND;
-		if (signal_pending(current))
-			break;
-		schedule();
-	}
-	remove_wait_queue(&vt_activate_queue, &wait);
-	__set_current_state(TASK_RUNNING);
-	return retval;
-}
-
-#define vt_wake_waitactive() wake_up(&vt_activate_queue)
-
 void reset_vc(struct vc_data *vc)
 {
 	vc->vc_mode = KD_TEXT;
@@ -1256,12 +1377,216 @@ void vc_SAK(struct work_struct *work)
 	release_console_sem();
 }
 
+#ifdef CONFIG_COMPAT
+
+struct compat_consolefontdesc {
+	unsigned short charcount;       /* characters in font (256 or 512) */
+	unsigned short charheight;      /* scan lines per character (1-32) */
+	compat_caddr_t chardata;	/* font data in expanded form */
+};
+
+static inline int
+compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
+			 int perm, struct console_font_op *op)
+{
+	struct compat_consolefontdesc cfdarg;
+	int i;
+
+	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case PIO_FONTX:
+		if (!perm)
+			return -EPERM;
+		op->op = KD_FONT_OP_SET;
+		op->flags = KD_FONT_FLAG_OLD;
+		op->width = 8;
+		op->height = cfdarg.charheight;
+		op->charcount = cfdarg.charcount;
+		op->data = compat_ptr(cfdarg.chardata);
+		return con_font_op(vc_cons[fg_console].d, op);
+	case GIO_FONTX:
+		op->op = KD_FONT_OP_GET;
+		op->flags = KD_FONT_FLAG_OLD;
+		op->width = 8;
+		op->height = cfdarg.charheight;
+		op->charcount = cfdarg.charcount;
+		op->data = compat_ptr(cfdarg.chardata);
+		i = con_font_op(vc_cons[fg_console].d, op);
+		if (i)
+			return i;
+		cfdarg.charheight = op->height;
+		cfdarg.charcount = op->charcount;
+		if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
+			return -EFAULT;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+struct compat_console_font_op {
+	compat_uint_t op;        /* operation code KD_FONT_OP_* */
+	compat_uint_t flags;     /* KD_FONT_FLAG_* */
+	compat_uint_t width, height;     /* font size */
+	compat_uint_t charcount;
+	compat_caddr_t data;    /* font data with height fixed to 32 */
+};
+
+static inline int
+compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
+			 int perm, struct console_font_op *op, struct vc_data *vc)
+{
+	int i;
+
+	if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
+		return -EFAULT;
+	if (!perm && op->op != KD_FONT_OP_GET)
+		return -EPERM;
+	op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
+	op->flags |= KD_FONT_FLAG_OLD;
+	i = con_font_op(vc, op);
+	if (i)
+		return i;
+	((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
+	if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
+		return -EFAULT;
+	return 0;
+}
+
+struct compat_unimapdesc {
+	unsigned short entry_ct;
+	compat_caddr_t entries;
+};
+
+static inline int
+compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
+			 int perm, struct vc_data *vc)
+{
+	struct compat_unimapdesc tmp;
+	struct unipair __user *tmp_entries;
+
+	if (copy_from_user(&tmp, user_ud, sizeof tmp))
+		return -EFAULT;
+	tmp_entries = compat_ptr(tmp.entries);
+	if (tmp_entries)
+		if (!access_ok(VERIFY_WRITE, tmp_entries,
+				tmp.entry_ct*sizeof(struct unipair)))
+			return -EFAULT;
+	switch (cmd) {
+	case PIO_UNIMAP:
+		if (!perm)
+			return -EPERM;
+		return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
+	case GIO_UNIMAP:
+		if (!perm && fg_console != vc->vc_num)
+			return -EPERM;
+		return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
+	}
+	return 0;
+}
+
+long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
+	     unsigned int cmd, unsigned long arg)
+{
+	struct vc_data *vc = tty->driver_data;
+	struct console_font_op op;	/* used in multiple places here */
+	struct kbd_struct *kbd;
+	unsigned int console;
+	void __user *up = (void __user *)arg;
+	int perm;
+	int ret = 0;
+
+	console = vc->vc_num;
+
+	lock_kernel();
+
+	if (!vc_cons_allocated(console)) { 	/* impossible? */
+		ret = -ENOIOCTLCMD;
+		goto out;
+	}
+
+	/*
+	 * To have permissions to do most of the vt ioctls, we either have
+	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
+	 */
+	perm = 0;
+	if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+		perm = 1;
+
+	kbd = kbd_table + console;
+	switch (cmd) {
+	/*
+	 * these need special handlers for incompatible data structures
+	 */
+	case PIO_FONTX:
+	case GIO_FONTX:
+		ret = compat_fontx_ioctl(cmd, up, perm, &op);
+		break;
+
+	case KDFONTOP:
+		ret = compat_kdfontop_ioctl(up, perm, &op, vc);
+		break;
+
+	case PIO_UNIMAP:
+	case GIO_UNIMAP:
+		ret = do_unimap_ioctl(cmd, up, perm, vc);
+		break;
+
+	/*
+	 * all these treat 'arg' as an integer
+	 */
+	case KIOCSOUND:
+	case KDMKTONE:
+#ifdef CONFIG_X86
+	case KDADDIO:
+	case KDDELIO:
+#endif
+	case KDSETMODE:
+	case KDMAPDISP:
+	case KDUNMAPDISP:
+	case KDSKBMODE:
+	case KDSKBMETA:
+	case KDSKBLED:
+	case KDSETLED:
+	case KDSIGACCEPT:
+	case VT_ACTIVATE:
+	case VT_WAITACTIVE:
+	case VT_RELDISP:
+	case VT_DISALLOCATE:
+	case VT_RESIZE:
+	case VT_RESIZEX:
+		goto fallback;
+
+	/*
+	 * the rest has a compatible data structure behind arg,
+	 * but we have to convert it to a proper 64 bit pointer.
+	 */
+	default:
+		arg = (unsigned long)compat_ptr(arg);
+		goto fallback;
+	}
+out:
+	unlock_kernel();
+	return ret;
+
+fallback:
+	unlock_kernel();
+	return vt_ioctl(tty, file, cmd, arg);
+}
+
+
+#endif /* CONFIG_COMPAT */
+
+
 /*
- * Performs the back end of a vt switch
+ * Performs the back end of a vt switch. Called under the console
+ * semaphore.
  */
 static void complete_change_console(struct vc_data *vc)
 {
 	unsigned char old_vc_mode;
+	int old = fg_console;
 
 	last_console = fg_console;
 
@@ -1325,7 +1650,7 @@ static void complete_change_console(struct vc_data *vc)
 	/*
 	 * Wake anyone waiting for their VT to activate
 	 */
-	vt_wake_waitactive();
+	vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
 	return;
 }
 
@@ -1398,3 +1723,58 @@ void change_console(struct vc_data *new_vc)
 
 	complete_change_console(new_vc);
 }
+
+/* Perform a kernel triggered VT switch for suspend/resume */
+
+static int disable_vt_switch;
+
+int vt_move_to_console(unsigned int vt, int alloc)
+{
+	int prev;
+
+	acquire_console_sem();
+	/* Graphics mode - up to X */
+	if (disable_vt_switch) {
+		release_console_sem();
+		return 0;
+	}
+	prev = fg_console;
+
+	if (alloc && vc_allocate(vt)) {
+		/* we can't have a free VC for now. Too bad,
+		 * we don't want to mess the screen for now. */
+		release_console_sem();
+		return -ENOSPC;
+	}
+
+	if (set_console(vt)) {
+		/*
+		 * We're unable to switch to the SUSPEND_CONSOLE.
+		 * Let the calling function know so it can decide
+		 * what to do.
+		 */
+		release_console_sem();
+		return -EIO;
+	}
+	release_console_sem();
+	if (vt_waitactive(vt + 1)) {
+		pr_debug("Suspend: Can't switch VCs.");
+		return -EINTR;
+	}
+	return prev;
+}
+
+/*
+ * Normally during a suspend, we allocate a new console and switch to it.
+ * When we resume, we switch back to the original console.  This switch
+ * can be slow, so on systems where the framebuffer can handle restoration
+ * of video registers anyways, there's little point in doing the console
+ * switch.  This function allows you to disable it by passing it '0'.
+ */
+void pm_set_vt_switch(int do_switch)
+{
+	acquire_console_sem();
+	disable_vt_switch = !do_switch;
+	release_console_sem();
+}
+EXPORT_SYMBOL(pm_set_vt_switch);
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index c5afc98..85e5dc0 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -202,9 +202,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
  * cn_proc_mcast_ctl
  * @data: message sent from userspace via the connector
  */
-static void cn_proc_mcast_ctl(void *data)
+static void cn_proc_mcast_ctl(struct cn_msg *msg)
 {
-	struct cn_msg *msg = data;
 	enum proc_cn_mcast_op *mc_op = NULL;
 	int err = 0;
 
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index 408c2af..4a1dfe1 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -87,7 +87,9 @@ void cn_queue_wrapper(struct work_struct *work)
 	kfree(d->free);
 }
 
-static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struct cb_id *id, void (*callback)(void *))
+static struct cn_callback_entry *
+cn_queue_alloc_callback_entry(char *name, struct cb_id *id,
+			      void (*callback)(struct cn_msg *))
 {
 	struct cn_callback_entry *cbq;
 
@@ -120,7 +122,8 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
 	return ((i1->idx == i2->idx) && (i1->val == i2->val));
 }
 
-int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *))
+int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id,
+			  void (*callback)(struct cn_msg *))
 {
 	struct cn_callback_entry *cbq, *__cbq;
 	int found = 0;
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 08b2500..74f52af 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -269,7 +269,8 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
  *
  * May sleep.
  */
-int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *))
+int cn_add_callback(struct cb_id *id, char *name,
+		    void (*callback)(struct cn_msg *))
 {
 	int err;
 	struct cn_dev *dev = &cdev;
@@ -351,9 +352,8 @@ static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
  *
  * Used for notification of a request's processing.
  */
-static void cn_callback(void *data)
+static void cn_callback(struct cn_msg *msg)
 {
-	struct cn_msg *msg = data;
 	struct cn_ctl_msg *ctl;
 	struct cn_ctl_entry *ent;
 	u32 size;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 2968ed6..3938c78 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -61,6 +61,8 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock);
  *   are concerned with are online after they get the lock.
  * - Governor routines that can be called in cpufreq hotplug path should not
  *   take this sem as top level hotplug notifier handler takes this.
+ * - Lock should not be held across
+ *     __cpufreq_governor(data, CPUFREQ_GOV_STOP);
  */
 static DEFINE_PER_CPU(int, policy_cpu);
 static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem);
@@ -686,6 +688,9 @@ static struct attribute *default_attrs[] = {
 	NULL
 };
 
+struct kobject *cpufreq_global_kobject;
+EXPORT_SYMBOL(cpufreq_global_kobject);
+
 #define to_policy(k) container_of(k, struct cpufreq_policy, kobj)
 #define to_attr(a) container_of(a, struct freq_attr, attr)
 
@@ -756,92 +761,20 @@ static struct kobj_type ktype_cpufreq = {
 	.release	= cpufreq_sysfs_release,
 };
 
-
-/**
- * cpufreq_add_dev - add a CPU device
- *
- * Adds the cpufreq interface for a CPU device.
- *
- * The Oracle says: try running cpufreq registration/unregistration concurrently
- * with with cpu hotplugging and all hell will break loose. Tried to clean this
- * mess up, but more thorough testing is needed. - Mathieu
+/*
+ * Returns:
+ *   Negative: Failure
+ *   0:        Success
+ *   Positive: When we have a managed CPU and the sysfs got symlinked
  */
-static int cpufreq_add_dev(struct sys_device *sys_dev)
+int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
+		struct sys_device *sys_dev)
 {
-	unsigned int cpu = sys_dev->id;
 	int ret = 0;
-	struct cpufreq_policy new_policy;
-	struct cpufreq_policy *policy;
-	struct freq_attr **drv_attr;
-	struct sys_device *cpu_sys_dev;
+#ifdef CONFIG_SMP
 	unsigned long flags;
 	unsigned int j;
 
-	if (cpu_is_offline(cpu))
-		return 0;
-
-	cpufreq_debug_disable_ratelimit();
-	dprintk("adding CPU %u\n", cpu);
-
-#ifdef CONFIG_SMP
-	/* check whether a different CPU already registered this
-	 * CPU because it is in the same boat. */
-	policy = cpufreq_cpu_get(cpu);
-	if (unlikely(policy)) {
-		cpufreq_cpu_put(policy);
-		cpufreq_debug_enable_ratelimit();
-		return 0;
-	}
-#endif
-
-	if (!try_module_get(cpufreq_driver->owner)) {
-		ret = -EINVAL;
-		goto module_out;
-	}
-
-	policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
-	if (!policy) {
-		ret = -ENOMEM;
-		goto nomem_out;
-	}
-	if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) {
-		ret = -ENOMEM;
-		goto err_free_policy;
-	}
-	if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) {
-		ret = -ENOMEM;
-		goto err_free_cpumask;
-	}
-
-	policy->cpu = cpu;
-	cpumask_copy(policy->cpus, cpumask_of(cpu));
-
-	/* Initially set CPU itself as the policy_cpu */
-	per_cpu(policy_cpu, cpu) = cpu;
-	ret = (lock_policy_rwsem_write(cpu) < 0);
-	WARN_ON(ret);
-
-	init_completion(&policy->kobj_unregister);
-	INIT_WORK(&policy->update, handle_update);
-
-	/* Set governor before ->init, so that driver could check it */
-	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-	/* call driver. From then on the cpufreq must be able
-	 * to accept all calls to ->verify and ->setpolicy for this CPU
-	 */
-	ret = cpufreq_driver->init(policy);
-	if (ret) {
-		dprintk("initialization failed\n");
-		goto err_unlock_policy;
-	}
-	policy->user_policy.min = policy->min;
-	policy->user_policy.max = policy->max;
-
-	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
-				     CPUFREQ_START, policy);
-
-#ifdef CONFIG_SMP
-
 #ifdef CONFIG_HOTPLUG_CPU
 	if (per_cpu(cpufreq_cpu_governor, cpu)) {
 		policy->governor = per_cpu(cpufreq_cpu_governor, cpu);
@@ -872,9 +805,8 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 				/* Should not go through policy unlock path */
 				if (cpufreq_driver->exit)
 					cpufreq_driver->exit(policy);
-				ret = -EBUSY;
 				cpufreq_cpu_put(managed_policy);
-				goto err_free_cpumask;
+				return -EBUSY;
 			}
 
 			spin_lock_irqsave(&cpufreq_driver_lock, flags);
@@ -893,17 +825,62 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 			 * Call driver->exit() because only the cpu parent of
 			 * the kobj needed to call init().
 			 */
-			goto out_driver_exit; /* call driver->exit() */
+			if (cpufreq_driver->exit)
+				cpufreq_driver->exit(policy);
+
+			if (!ret)
+				return 1;
+			else
+				return ret;
 		}
 	}
 #endif
-	memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+	return ret;
+}
+
+
+/* symlink affected CPUs */
+int cpufreq_add_dev_symlink(unsigned int cpu, struct cpufreq_policy *policy)
+{
+	unsigned int j;
+	int ret = 0;
+
+	for_each_cpu(j, policy->cpus) {
+		struct cpufreq_policy *managed_policy;
+		struct sys_device *cpu_sys_dev;
+
+		if (j == cpu)
+			continue;
+		if (!cpu_online(j))
+			continue;
+
+		dprintk("CPU %u already managed, adding link\n", j);
+		managed_policy = cpufreq_cpu_get(cpu);
+		cpu_sys_dev = get_cpu_sysdev(j);
+		ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
+					"cpufreq");
+		if (ret) {
+			cpufreq_cpu_put(managed_policy);
+			return ret;
+		}
+	}
+	return ret;
+}
+
+int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy,
+		struct sys_device *sys_dev)
+{
+	struct cpufreq_policy new_policy;
+	struct freq_attr **drv_attr;
+	unsigned long flags;
+	int ret = 0;
+	unsigned int j;
 
 	/* prepare interface data */
-	ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj,
-				   "cpufreq");
+	ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
+				   &sys_dev->kobj, "cpufreq");
 	if (ret)
-		goto out_driver_exit;
+		return ret;
 
 	/* set up files for this cpu device */
 	drv_attr = cpufreq_driver->attr;
@@ -926,35 +903,20 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 
 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
 	for_each_cpu(j, policy->cpus) {
-		if (!cpu_online(j))
-			continue;
+	if (!cpu_online(j))
+		continue;
 		per_cpu(cpufreq_cpu_data, j) = policy;
 		per_cpu(policy_cpu, j) = policy->cpu;
 	}
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-	/* symlink affected CPUs */
-	for_each_cpu(j, policy->cpus) {
-		struct cpufreq_policy *managed_policy;
-
-		if (j == cpu)
-			continue;
-		if (!cpu_online(j))
-			continue;
-
-		dprintk("CPU %u already managed, adding link\n", j);
-		managed_policy = cpufreq_cpu_get(cpu);
-		cpu_sys_dev = get_cpu_sysdev(j);
-		ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
-					"cpufreq");
-		if (ret) {
-			cpufreq_cpu_put(managed_policy);
-			goto err_out_unregister;
-		}
-	}
+	ret = cpufreq_add_dev_symlink(cpu, policy);
+	if (ret)
+		goto err_out_kobj_put;
 
-	policy->governor = NULL; /* to assure that the starting sequence is
-				  * run in cpufreq_set_policy */
+	memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+	/* assure that the starting sequence is run in __cpufreq_set_policy */
+	policy->governor = NULL;
 
 	/* set default policy */
 	ret = __cpufreq_set_policy(policy, &new_policy);
@@ -963,8 +925,107 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 
 	if (ret) {
 		dprintk("setting policy failed\n");
-		goto err_out_unregister;
+		if (cpufreq_driver->exit)
+			cpufreq_driver->exit(policy);
+	}
+	return ret;
+
+err_out_kobj_put:
+	kobject_put(&policy->kobj);
+	wait_for_completion(&policy->kobj_unregister);
+	return ret;
+}
+
+
+/**
+ * cpufreq_add_dev - add a CPU device
+ *
+ * Adds the cpufreq interface for a CPU device.
+ *
+ * The Oracle says: try running cpufreq registration/unregistration concurrently
+ * with with cpu hotplugging and all hell will break loose. Tried to clean this
+ * mess up, but more thorough testing is needed. - Mathieu
+ */
+static int cpufreq_add_dev(struct sys_device *sys_dev)
+{
+	unsigned int cpu = sys_dev->id;
+	int ret = 0;
+	struct cpufreq_policy *policy;
+	unsigned long flags;
+	unsigned int j;
+
+	if (cpu_is_offline(cpu))
+		return 0;
+
+	cpufreq_debug_disable_ratelimit();
+	dprintk("adding CPU %u\n", cpu);
+
+#ifdef CONFIG_SMP
+	/* check whether a different CPU already registered this
+	 * CPU because it is in the same boat. */
+	policy = cpufreq_cpu_get(cpu);
+	if (unlikely(policy)) {
+		cpufreq_cpu_put(policy);
+		cpufreq_debug_enable_ratelimit();
+		return 0;
+	}
+#endif
+
+	if (!try_module_get(cpufreq_driver->owner)) {
+		ret = -EINVAL;
+		goto module_out;
+	}
+
+	ret = -ENOMEM;
+	policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
+	if (!policy)
+		goto nomem_out;
+
+	if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
+		goto err_free_policy;
+
+	if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
+		goto err_free_cpumask;
+
+	policy->cpu = cpu;
+	cpumask_copy(policy->cpus, cpumask_of(cpu));
+
+	/* Initially set CPU itself as the policy_cpu */
+	per_cpu(policy_cpu, cpu) = cpu;
+	ret = (lock_policy_rwsem_write(cpu) < 0);
+	WARN_ON(ret);
+
+	init_completion(&policy->kobj_unregister);
+	INIT_WORK(&policy->update, handle_update);
+
+	/* Set governor before ->init, so that driver could check it */
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+	/* call driver. From then on the cpufreq must be able
+	 * to accept all calls to ->verify and ->setpolicy for this CPU
+	 */
+	ret = cpufreq_driver->init(policy);
+	if (ret) {
+		dprintk("initialization failed\n");
+		goto err_unlock_policy;
 	}
+	policy->user_policy.min = policy->min;
+	policy->user_policy.max = policy->max;
+
+	blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
+				     CPUFREQ_START, policy);
+
+	ret = cpufreq_add_dev_policy(cpu, policy, sys_dev);
+	if (ret) {
+		if (ret > 0)
+			/* This is a managed cpu, symlink created,
+			   exit with 0 */
+			ret = 0;
+		goto err_unlock_policy;
+	}
+
+	ret = cpufreq_add_dev_interface(cpu, policy, sys_dev);
+	if (ret)
+		goto err_out_unregister;
 
 	unlock_policy_rwsem_write(cpu);
 
@@ -982,14 +1043,9 @@ err_out_unregister:
 		per_cpu(cpufreq_cpu_data, j) = NULL;
 	spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-err_out_kobj_put:
 	kobject_put(&policy->kobj);
 	wait_for_completion(&policy->kobj_unregister);
 
-out_driver_exit:
-	if (cpufreq_driver->exit)
-		cpufreq_driver->exit(policy);
-
 err_unlock_policy:
 	unlock_policy_rwsem_write(cpu);
 err_free_cpumask:
@@ -1653,8 +1709,17 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data,
 			dprintk("governor switch\n");
 
 			/* end old governor */
-			if (data->governor)
+			if (data->governor) {
+				/*
+				 * Need to release the rwsem around governor
+				 * stop due to lock dependency between
+				 * cancel_delayed_work_sync and the read lock
+				 * taken in the delayed work handler.
+				 */
+				unlock_policy_rwsem_write(data->cpu);
 				__cpufreq_governor(data, CPUFREQ_GOV_STOP);
+				lock_policy_rwsem_write(data->cpu);
+			}
 
 			/* start new governor */
 			data->governor = policy->governor;
@@ -1884,7 +1949,11 @@ static int __init cpufreq_core_init(void)
 		per_cpu(policy_cpu, cpu) = -1;
 		init_rwsem(&per_cpu(cpu_policy_rwsem, cpu));
 	}
+
+	cpufreq_global_kobject = kobject_create_and_add("cpufreq",
+						&cpu_sysdev_class.kset.kobj);
+	BUG_ON(!cpufreq_global_kobject);
+
 	return 0;
 }
-
 core_initcall(cpufreq_core_init);
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index bdea7e2..bc33ddc 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -71,7 +71,7 @@ struct cpu_dbs_info_s {
 	 */
 	struct mutex timer_mutex;
 };
-static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
+static DEFINE_PER_CPU(struct cpu_dbs_info_s, cs_cpu_dbs_info);
 
 static unsigned int dbs_enable;	/* number of CPUs using this policy */
 
@@ -137,7 +137,7 @@ dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
 		     void *data)
 {
 	struct cpufreq_freqs *freq = data;
-	struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cpu_dbs_info,
+	struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cs_cpu_dbs_info,
 							freq->cpu);
 
 	struct cpufreq_policy *policy;
@@ -297,7 +297,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
 	/* we need to re-evaluate prev_cpu_idle */
 	for_each_online_cpu(j) {
 		struct cpu_dbs_info_s *dbs_info;
-		dbs_info = &per_cpu(cpu_dbs_info, j);
+		dbs_info = &per_cpu(cs_cpu_dbs_info, j);
 		dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
 						&dbs_info->prev_cpu_wall);
 		if (dbs_tuners_ins.ignore_nice)
@@ -387,7 +387,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 		cputime64_t cur_wall_time, cur_idle_time;
 		unsigned int idle_time, wall_time;
 
-		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		j_dbs_info = &per_cpu(cs_cpu_dbs_info, j);
 
 		cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
 
@@ -521,7 +521,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 	unsigned int j;
 	int rc;
 
-	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
+	this_dbs_info = &per_cpu(cs_cpu_dbs_info, cpu);
 
 	switch (event) {
 	case CPUFREQ_GOV_START:
@@ -538,7 +538,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 
 		for_each_cpu(j, policy->cpus) {
 			struct cpu_dbs_info_s *j_dbs_info;
-			j_dbs_info = &per_cpu(cpu_dbs_info, j);
+			j_dbs_info = &per_cpu(cs_cpu_dbs_info, j);
 			j_dbs_info->cur_policy = policy;
 
 			j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index d6ba142..071699d 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -55,6 +55,18 @@ static unsigned int min_sampling_rate;
 #define TRANSITION_LATENCY_LIMIT		(10 * 1000 * 1000)
 
 static void do_dbs_timer(struct work_struct *work);
+static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
+				unsigned int event);
+
+#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
+static
+#endif
+struct cpufreq_governor cpufreq_gov_ondemand = {
+       .name                   = "ondemand",
+       .governor               = cpufreq_governor_dbs,
+       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+       .owner                  = THIS_MODULE,
+};
 
 /* Sampling types */
 enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE};
@@ -78,7 +90,7 @@ struct cpu_dbs_info_s {
 	 */
 	struct mutex timer_mutex;
 };
-static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info);
+static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info);
 
 static unsigned int dbs_enable;	/* number of CPUs using this policy */
 
@@ -149,7 +161,8 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
 	unsigned int freq_hi, freq_lo;
 	unsigned int index = 0;
 	unsigned int jiffies_total, jiffies_hi, jiffies_lo;
-	struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, policy->cpu);
+	struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info,
+						   policy->cpu);
 
 	if (!dbs_info->freq_table) {
 		dbs_info->freq_lo = 0;
@@ -192,7 +205,7 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy,
 
 static void ondemand_powersave_bias_init_cpu(int cpu)
 {
-	struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu);
+	struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
 	dbs_info->freq_table = cpufreq_frequency_get_table(cpu);
 	dbs_info->freq_lo = 0;
 }
@@ -206,20 +219,23 @@ static void ondemand_powersave_bias_init(void)
 }
 
 /************************** sysfs interface ************************/
-static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf)
+
+static ssize_t show_sampling_rate_max(struct kobject *kobj,
+				      struct attribute *attr, char *buf)
 {
 	printk_once(KERN_INFO "CPUFREQ: ondemand sampling_rate_max "
 	       "sysfs file is deprecated - used by: %s\n", current->comm);
 	return sprintf(buf, "%u\n", -1U);
 }
 
-static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf)
+static ssize_t show_sampling_rate_min(struct kobject *kobj,
+				      struct attribute *attr, char *buf)
 {
 	return sprintf(buf, "%u\n", min_sampling_rate);
 }
 
 #define define_one_ro(_name)		\
-static struct freq_attr _name =		\
+static struct global_attr _name =	\
 __ATTR(_name, 0444, show_##_name, NULL)
 
 define_one_ro(sampling_rate_max);
@@ -228,7 +244,7 @@ define_one_ro(sampling_rate_min);
 /* cpufreq_ondemand Governor Tunables */
 #define show_one(file_name, object)					\
 static ssize_t show_##file_name						\
-(struct cpufreq_policy *unused, char *buf)				\
+(struct kobject *kobj, struct attribute *attr, char *buf)              \
 {									\
 	return sprintf(buf, "%u\n", dbs_tuners_ins.object);		\
 }
@@ -237,8 +253,38 @@ show_one(up_threshold, up_threshold);
 show_one(ignore_nice_load, ignore_nice);
 show_one(powersave_bias, powersave_bias);
 
-static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+/*** delete after deprecation time ***/
+
+#define DEPRECATION_MSG(file_name)					\
+	printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs "	\
+		    "interface is deprecated - " #file_name "\n");
+
+#define show_one_old(file_name)						\
+static ssize_t show_##file_name##_old					\
+(struct cpufreq_policy *unused, char *buf)				\
+{									\
+	printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs "	\
+		    "interface is deprecated - " #file_name "\n");	\
+	return show_##file_name(NULL, NULL, buf);			\
+}
+show_one_old(sampling_rate);
+show_one_old(up_threshold);
+show_one_old(ignore_nice_load);
+show_one_old(powersave_bias);
+show_one_old(sampling_rate_min);
+show_one_old(sampling_rate_max);
+
+#define define_one_ro_old(object, _name)       \
+static struct freq_attr object =               \
+__ATTR(_name, 0444, show_##_name##_old, NULL)
+
+define_one_ro_old(sampling_rate_min_old, sampling_rate_min);
+define_one_ro_old(sampling_rate_max_old, sampling_rate_max);
+
+/*** delete after deprecation time ***/
+
+static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
+				   const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -253,8 +299,8 @@ static ssize_t store_sampling_rate(struct cpufreq_policy *unused,
 	return count;
 }
 
-static ssize_t store_up_threshold(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
+				  const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -272,8 +318,8 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused,
 	return count;
 }
 
-static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
-		const char *buf, size_t count)
+static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b,
+				      const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -297,7 +343,7 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
 	/* we need to re-evaluate prev_cpu_idle */
 	for_each_online_cpu(j) {
 		struct cpu_dbs_info_s *dbs_info;
-		dbs_info = &per_cpu(cpu_dbs_info, j);
+		dbs_info = &per_cpu(od_cpu_dbs_info, j);
 		dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
 						&dbs_info->prev_cpu_wall);
 		if (dbs_tuners_ins.ignore_nice)
@@ -309,8 +355,8 @@ static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
 	return count;
 }
 
-static ssize_t store_powersave_bias(struct cpufreq_policy *unused,
-		const char *buf, size_t count)
+static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b,
+				    const char *buf, size_t count)
 {
 	unsigned int input;
 	int ret;
@@ -331,7 +377,7 @@ static ssize_t store_powersave_bias(struct cpufreq_policy *unused,
 }
 
 #define define_one_rw(_name) \
-static struct freq_attr _name = \
+static struct global_attr _name = \
 __ATTR(_name, 0644, show_##_name, store_##_name)
 
 define_one_rw(sampling_rate);
@@ -354,6 +400,47 @@ static struct attribute_group dbs_attr_group = {
 	.name = "ondemand",
 };
 
+/*** delete after deprecation time ***/
+
+#define write_one_old(file_name)					\
+static ssize_t store_##file_name##_old					\
+(struct cpufreq_policy *unused, const char *buf, size_t count)		\
+{									\
+       printk_once(KERN_INFO "CPUFREQ: Per core ondemand sysfs "	\
+		   "interface is deprecated - " #file_name "\n");	\
+       return store_##file_name(NULL, NULL, buf, count);		\
+}
+write_one_old(sampling_rate);
+write_one_old(up_threshold);
+write_one_old(ignore_nice_load);
+write_one_old(powersave_bias);
+
+#define define_one_rw_old(object, _name)       \
+static struct freq_attr object =               \
+__ATTR(_name, 0644, show_##_name##_old, store_##_name##_old)
+
+define_one_rw_old(sampling_rate_old, sampling_rate);
+define_one_rw_old(up_threshold_old, up_threshold);
+define_one_rw_old(ignore_nice_load_old, ignore_nice_load);
+define_one_rw_old(powersave_bias_old, powersave_bias);
+
+static struct attribute *dbs_attributes_old[] = {
+       &sampling_rate_max_old.attr,
+       &sampling_rate_min_old.attr,
+       &sampling_rate_old.attr,
+       &up_threshold_old.attr,
+       &ignore_nice_load_old.attr,
+       &powersave_bias_old.attr,
+       NULL
+};
+
+static struct attribute_group dbs_attr_group_old = {
+       .attrs = dbs_attributes_old,
+       .name = "ondemand",
+};
+
+/*** delete after deprecation time ***/
+
 /************************** sysfs end ************************/
 
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
@@ -388,7 +475,7 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 		unsigned int load, load_freq;
 		int freq_avg;
 
-		j_dbs_info = &per_cpu(cpu_dbs_info, j);
+		j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
 
 		cur_idle_time = get_cpu_idle_time(j, &cur_wall_time);
 
@@ -535,7 +622,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 	unsigned int j;
 	int rc;
 
-	this_dbs_info = &per_cpu(cpu_dbs_info, cpu);
+	this_dbs_info = &per_cpu(od_cpu_dbs_info, cpu);
 
 	switch (event) {
 	case CPUFREQ_GOV_START:
@@ -544,7 +631,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 
 		mutex_lock(&dbs_mutex);
 
-		rc = sysfs_create_group(&policy->kobj, &dbs_attr_group);
+		rc = sysfs_create_group(&policy->kobj, &dbs_attr_group_old);
 		if (rc) {
 			mutex_unlock(&dbs_mutex);
 			return rc;
@@ -553,7 +640,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 		dbs_enable++;
 		for_each_cpu(j, policy->cpus) {
 			struct cpu_dbs_info_s *j_dbs_info;
-			j_dbs_info = &per_cpu(cpu_dbs_info, j);
+			j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
 			j_dbs_info->cur_policy = policy;
 
 			j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j,
@@ -565,13 +652,20 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 		}
 		this_dbs_info->cpu = cpu;
 		ondemand_powersave_bias_init_cpu(cpu);
-		mutex_init(&this_dbs_info->timer_mutex);
 		/*
 		 * Start the timerschedule work, when this governor
 		 * is used for first time
 		 */
 		if (dbs_enable == 1) {
 			unsigned int latency;
+
+			rc = sysfs_create_group(cpufreq_global_kobject,
+						&dbs_attr_group);
+			if (rc) {
+				mutex_unlock(&dbs_mutex);
+				return rc;
+			}
+
 			/* policy latency is in nS. Convert it to uS first */
 			latency = policy->cpuinfo.transition_latency / 1000;
 			if (latency == 0)
@@ -585,6 +679,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 		}
 		mutex_unlock(&dbs_mutex);
 
+		mutex_init(&this_dbs_info->timer_mutex);
 		dbs_timer_init(this_dbs_info);
 		break;
 
@@ -592,10 +687,13 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 		dbs_timer_exit(this_dbs_info);
 
 		mutex_lock(&dbs_mutex);
-		sysfs_remove_group(&policy->kobj, &dbs_attr_group);
+		sysfs_remove_group(&policy->kobj, &dbs_attr_group_old);
 		mutex_destroy(&this_dbs_info->timer_mutex);
 		dbs_enable--;
 		mutex_unlock(&dbs_mutex);
+		if (!dbs_enable)
+			sysfs_remove_group(cpufreq_global_kobject,
+					   &dbs_attr_group);
 
 		break;
 
@@ -613,16 +711,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
 	return 0;
 }
 
-#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND
-static
-#endif
-struct cpufreq_governor cpufreq_gov_ondemand = {
-	.name			= "ondemand",
-	.governor		= cpufreq_governor_dbs,
-	.max_transition_latency = TRANSITION_LATENCY_LIMIT,
-	.owner			= THIS_MODULE,
-};
-
 static int __init cpufreq_gov_dbs_init(void)
 {
 	int err;
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 8504a21..ad41f19 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -17,6 +17,7 @@
 #include <linux/cpuidle.h>
 #include <linux/ktime.h>
 #include <linux/hrtimer.h>
+#include <trace/events/power.h>
 
 #include "cpuidle.h"
 
@@ -91,6 +92,7 @@ static void cpuidle_idle_call(void)
 	/* give the governor an opportunity to reflect on the outcome */
 	if (cpuidle_curr_governor->reflect)
 		cpuidle_curr_governor->reflect(dev);
+	trace_power_end(0);
 }
 
 /**
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 9a1e5fb..c8522e6 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -1166,32 +1166,37 @@ static void at_dma_shutdown(struct platform_device *pdev)
 	clk_disable(atdma->clk);
 }
 
-static int at_dma_suspend_late(struct platform_device *pdev, pm_message_t mesg)
+static int at_dma_suspend_noirq(struct device *dev)
 {
-	struct at_dma	*atdma = platform_get_drvdata(pdev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct at_dma *atdma = platform_get_drvdata(pdev);
 
 	at_dma_off(platform_get_drvdata(pdev));
 	clk_disable(atdma->clk);
 	return 0;
 }
 
-static int at_dma_resume_early(struct platform_device *pdev)
+static int at_dma_resume_noirq(struct device *dev)
 {
-	struct at_dma	*atdma = platform_get_drvdata(pdev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct at_dma *atdma = platform_get_drvdata(pdev);
 
 	clk_enable(atdma->clk);
 	dma_writel(atdma, EN, AT_DMA_ENABLE);
 	return 0;
-
 }
 
+static struct dev_pm_ops at_dma_dev_pm_ops = {
+	.suspend_noirq = at_dma_suspend_noirq,
+	.resume_noirq = at_dma_resume_noirq,
+};
+
 static struct platform_driver at_dma_driver = {
 	.remove		= __exit_p(at_dma_remove),
 	.shutdown	= at_dma_shutdown,
-	.suspend_late	= at_dma_suspend_late,
-	.resume_early	= at_dma_resume_early,
 	.driver = {
 		.name	= "at_hdmac",
+		.pm	= &at_dma_dev_pm_ops,
 	},
 };
 
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 98c9a84..933c143 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -1399,8 +1399,9 @@ static void dw_shutdown(struct platform_device *pdev)
 	clk_disable(dw->clk);
 }
 
-static int dw_suspend_late(struct platform_device *pdev, pm_message_t mesg)
+static int dw_suspend_noirq(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct dw_dma	*dw = platform_get_drvdata(pdev);
 
 	dw_dma_off(platform_get_drvdata(pdev));
@@ -1408,23 +1409,27 @@ static int dw_suspend_late(struct platform_device *pdev, pm_message_t mesg)
 	return 0;
 }
 
-static int dw_resume_early(struct platform_device *pdev)
+static int dw_resume_noirq(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct dw_dma	*dw = platform_get_drvdata(pdev);
 
 	clk_enable(dw->clk);
 	dma_writel(dw, CFG, DW_CFG_DMA_EN);
 	return 0;
-
 }
 
+static struct dev_pm_ops dw_dev_pm_ops = {
+	.suspend_noirq = dw_suspend_noirq,
+	.resume_noirq = dw_resume_noirq,
+};
+
 static struct platform_driver dw_driver = {
 	.remove		= __exit_p(dw_remove),
 	.shutdown	= dw_shutdown,
-	.suspend_late	= dw_suspend_late,
-	.resume_early	= dw_resume_early,
 	.driver = {
 		.name	= "dw_dmac",
+		.pm	= &dw_dev_pm_ops,
 	},
 };
 
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c
index 88dab52..7837930 100644
--- a/drivers/dma/txx9dmac.c
+++ b/drivers/dma/txx9dmac.c
@@ -1291,17 +1291,18 @@ static void txx9dmac_shutdown(struct platform_device *pdev)
 	txx9dmac_off(ddev);
 }
 
-static int txx9dmac_suspend_late(struct platform_device *pdev,
-				 pm_message_t mesg)
+static int txx9dmac_suspend_noirq(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
 
 	txx9dmac_off(ddev);
 	return 0;
 }
 
-static int txx9dmac_resume_early(struct platform_device *pdev)
+static int txx9dmac_resume_noirq(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct txx9dmac_dev *ddev = platform_get_drvdata(pdev);
 	struct txx9dmac_platform_data *pdata = pdev->dev.platform_data;
 	u32 mcr;
@@ -1314,6 +1315,11 @@ static int txx9dmac_resume_early(struct platform_device *pdev)
 
 }
 
+static struct dev_pm_ops txx9dmac_dev_pm_ops = {
+	.suspend_noirq = txx9dmac_suspend_noirq,
+	.resume_noirq = txx9dmac_resume_noirq,
+};
+
 static struct platform_driver txx9dmac_chan_driver = {
 	.remove		= __exit_p(txx9dmac_chan_remove),
 	.driver = {
@@ -1324,10 +1330,9 @@ static struct platform_driver txx9dmac_chan_driver = {
 static struct platform_driver txx9dmac_driver = {
 	.remove		= __exit_p(txx9dmac_remove),
 	.shutdown	= txx9dmac_shutdown,
-	.suspend_late	= txx9dmac_suspend_late,
-	.resume_early	= txx9dmac_resume_early,
 	.driver = {
 		.name	= "txx9dmac",
+		.pm	= &txx9dmac_dev_pm_ops,
 	},
 };
 
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 4339b1a..a3ca18e 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -59,7 +59,7 @@ config EDAC_MM_EDAC
 
 config EDAC_AMD64
 	tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
-	depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI
+	depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && CPU_SUP_AMD
 	help
 	  Support for error detection and correction on the AMD 64
 	  Families of Memory Controllers (K8, F10h and F11h)
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 98aa4a7..cfa033c 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -17,6 +17,10 @@ ifdef CONFIG_PCI
 edac_core-objs	+= edac_pci.o edac_pci_sysfs.o
 endif
 
+ifdef CONFIG_CPU_SUP_AMD
+edac_core-objs  += edac_mce_amd.o
+endif
+
 obj-$(CONFIG_EDAC_AMD76X)		+= amd76x_edac.o
 obj-$(CONFIG_EDAC_CPC925)		+= cpc925_edac.o
 obj-$(CONFIG_EDAC_I5000)		+= i5000_edac.o
@@ -32,7 +36,7 @@ obj-$(CONFIG_EDAC_X38)			+= x38_edac.o
 obj-$(CONFIG_EDAC_I82860)		+= i82860_edac.o
 obj-$(CONFIG_EDAC_R82600)		+= r82600_edac.o
 
-amd64_edac_mod-y :=  amd64_edac_err_types.o amd64_edac.o
+amd64_edac_mod-y := amd64_edac.o
 amd64_edac_mod-$(CONFIG_EDAC_DEBUG) += amd64_edac_dbg.o
 amd64_edac_mod-$(CONFIG_EDAC_AMD64_ERROR_INJECTION) += amd64_edac_inj.o
 
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index e2a10bc..4e551e6 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -19,6 +19,63 @@ static struct mem_ctl_info *mci_lookup[MAX_NUMNODES];
 static struct amd64_pvt *pvt_lookup[MAX_NUMNODES];
 
 /*
+ * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
+ * for DDR2 DRAM mapping.
+ */
+u32 revf_quad_ddr2_shift[] = {
+	0,	/* 0000b NULL DIMM (128mb) */
+	28,	/* 0001b 256mb */
+	29,	/* 0010b 512mb */
+	29,	/* 0011b 512mb */
+	29,	/* 0100b 512mb */
+	30,	/* 0101b 1gb */
+	30,	/* 0110b 1gb */
+	31,	/* 0111b 2gb */
+	31,	/* 1000b 2gb */
+	32,	/* 1001b 4gb */
+	32,	/* 1010b 4gb */
+	33,	/* 1011b 8gb */
+	0,	/* 1100b future */
+	0,	/* 1101b future */
+	0,	/* 1110b future */
+	0	/* 1111b future */
+};
+
+/*
+ * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing
+ * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
+ * or higher value'.
+ *
+ *FIXME: Produce a better mapping/linearisation.
+ */
+
+struct scrubrate scrubrates[] = {
+	{ 0x01, 1600000000UL},
+	{ 0x02, 800000000UL},
+	{ 0x03, 400000000UL},
+	{ 0x04, 200000000UL},
+	{ 0x05, 100000000UL},
+	{ 0x06, 50000000UL},
+	{ 0x07, 25000000UL},
+	{ 0x08, 12284069UL},
+	{ 0x09, 6274509UL},
+	{ 0x0A, 3121951UL},
+	{ 0x0B, 1560975UL},
+	{ 0x0C, 781440UL},
+	{ 0x0D, 390720UL},
+	{ 0x0E, 195300UL},
+	{ 0x0F, 97650UL},
+	{ 0x10, 48854UL},
+	{ 0x11, 24427UL},
+	{ 0x12, 12213UL},
+	{ 0x13, 6101UL},
+	{ 0x14, 3051UL},
+	{ 0x15, 1523UL},
+	{ 0x16, 761UL},
+	{ 0x00, 0UL},        /* scrubbing off */
+};
+
+/*
  * Memory scrubber control interface. For K8, memory scrubbing is handled by
  * hardware and can involve L2 cache, dcache as well as the main memory. With
  * F10, this is extended to L3 cache scrubbing on CPU models sporting that
@@ -693,7 +750,7 @@ static void find_csrow_limits(struct mem_ctl_info *mci, int csrow,
  * specific.
  */
 static u64 extract_error_address(struct mem_ctl_info *mci,
-				 struct amd64_error_info_regs *info)
+				 struct err_regs *info)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
 
@@ -1049,7 +1106,7 @@ static int k8_early_channel_count(struct amd64_pvt *pvt)
 
 /* extract the ERROR ADDRESS for the K8 CPUs */
 static u64 k8_get_error_address(struct mem_ctl_info *mci,
-				struct amd64_error_info_regs *info)
+				struct err_regs *info)
 {
 	return (((u64) (info->nbeah & 0xff)) << 32) +
 			(info->nbeal & ~0x03);
@@ -1092,7 +1149,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
 }
 
 static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
-					struct amd64_error_info_regs *info,
+					struct err_regs *info,
 					u64 SystemAddress)
 {
 	struct mem_ctl_info *src_mci;
@@ -1101,8 +1158,8 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 	u32 page, offset;
 
 	/* Extract the syndrome parts and form a 16-bit syndrome */
-	syndrome = EXTRACT_HIGH_SYNDROME(info->nbsl) << 8;
-	syndrome |= EXTRACT_LOW_SYNDROME(info->nbsh);
+	syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
+	syndrome |= LOW_SYNDROME(info->nbsh);
 
 	/* CHIPKILL enabled */
 	if (info->nbcfg & K8_NBCFG_CHIPKILL) {
@@ -1198,7 +1255,9 @@ static int k8_dbam_map_to_pages(struct amd64_pvt *pvt, int dram_map)
  */
 static int f10_early_channel_count(struct amd64_pvt *pvt)
 {
+	int dbams[] = { DBAM0, DBAM1 };
 	int err = 0, channels = 0;
+	int i, j;
 	u32 dbam;
 
 	err = pci_read_config_dword(pvt->dram_f2_ctl, F10_DCLR_0, &pvt->dclr0);
@@ -1231,46 +1290,19 @@ static int f10_early_channel_count(struct amd64_pvt *pvt)
 	 * is more than just one DIMM present in unganged mode. Need to check
 	 * both controllers since DIMMs can be placed in either one.
 	 */
-	channels = 0;
-	err = pci_read_config_dword(pvt->dram_f2_ctl, DBAM0, &dbam);
-	if (err)
-		goto err_reg;
-
-	if (DBAM_DIMM(0, dbam) > 0)
-		channels++;
-	if (DBAM_DIMM(1, dbam) > 0)
-		channels++;
-	if (DBAM_DIMM(2, dbam) > 0)
-		channels++;
-	if (DBAM_DIMM(3, dbam) > 0)
-		channels++;
-
-	/* If more than 2 DIMMs are present, then we have 2 channels */
-	if (channels > 2)
-		channels = 2;
-	else if (channels == 0) {
-		/* No DIMMs on DCT0, so look at DCT1 */
-		err = pci_read_config_dword(pvt->dram_f2_ctl, DBAM1, &dbam);
+	for (i = 0; i < ARRAY_SIZE(dbams); i++) {
+		err = pci_read_config_dword(pvt->dram_f2_ctl, dbams[i], &dbam);
 		if (err)
 			goto err_reg;
 
-		if (DBAM_DIMM(0, dbam) > 0)
-			channels++;
-		if (DBAM_DIMM(1, dbam) > 0)
-			channels++;
-		if (DBAM_DIMM(2, dbam) > 0)
-			channels++;
-		if (DBAM_DIMM(3, dbam) > 0)
-			channels++;
-
-		if (channels > 2)
-			channels = 2;
+		for (j = 0; j < 4; j++) {
+			if (DBAM_DIMM(j, dbam) > 0) {
+				channels++;
+				break;
+			}
+		}
 	}
 
-	/* If we found ALL 0 values, then assume just ONE DIMM-ONE Channel */
-	if (channels == 0)
-		channels = 1;
-
 	debugf0("MCT channel count: %d\n", channels);
 
 	return channels;
@@ -1311,7 +1343,7 @@ static void amd64_teardown(struct amd64_pvt *pvt)
 }
 
 static u64 f10_get_error_address(struct mem_ctl_info *mci,
-			struct amd64_error_info_regs *info)
+			struct err_regs *info)
 {
 	return (((u64) (info->nbeah & 0xffff)) << 32) +
 			(info->nbeal & ~0x01);
@@ -1688,7 +1720,7 @@ static int f10_translate_sysaddr_to_cs(struct amd64_pvt *pvt, u64 sys_addr,
  * The @sys_addr is usually an error address received from the hardware.
  */
 static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
-				     struct amd64_error_info_regs *info,
+				     struct err_regs *info,
 				     u64 sys_addr)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
@@ -1701,8 +1733,8 @@ static void f10_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
 	if (csrow >= 0) {
 		error_address_to_page_and_offset(sys_addr, &page, &offset);
 
-		syndrome = EXTRACT_HIGH_SYNDROME(info->nbsl) << 8;
-		syndrome |= EXTRACT_LOW_SYNDROME(info->nbsh);
+		syndrome  = HIGH_SYNDROME(info->nbsl) << 8;
+		syndrome |= LOW_SYNDROME(info->nbsh);
 
 		/*
 		 * Is CHIPKILL on? If so, then we can attempt to use the
@@ -2045,7 +2077,7 @@ static int get_channel_from_ecc_syndrome(unsigned short syndrome)
  *	- 0: if no valid error is indicated
  */
 static int amd64_get_error_info_regs(struct mem_ctl_info *mci,
-				     struct amd64_error_info_regs *regs)
+				     struct err_regs *regs)
 {
 	struct amd64_pvt *pvt;
 	struct pci_dev *misc_f3_ctl;
@@ -2094,10 +2126,10 @@ err_reg:
  *	- 0: if no error is found
  */
 static int amd64_get_error_info(struct mem_ctl_info *mci,
-				struct amd64_error_info_regs *info)
+				struct err_regs *info)
 {
 	struct amd64_pvt *pvt;
-	struct amd64_error_info_regs regs;
+	struct err_regs regs;
 
 	pvt = mci->pvt_info;
 
@@ -2152,48 +2184,12 @@ static int amd64_get_error_info(struct mem_ctl_info *mci,
 	return 1;
 }
 
-static inline void amd64_decode_gart_tlb_error(struct mem_ctl_info *mci,
-					 struct amd64_error_info_regs *info)
-{
-	u32 err_code;
-	u32 ec_tt;		/* error code transaction type (2b) */
-	u32 ec_ll;		/* error code cache level (2b) */
-
-	err_code = EXTRACT_ERROR_CODE(info->nbsl);
-	ec_ll = EXTRACT_LL_CODE(err_code);
-	ec_tt = EXTRACT_TT_CODE(err_code);
-
-	amd64_mc_printk(mci, KERN_ERR,
-		     "GART TLB event: transaction type(%s), "
-		     "cache level(%s)\n", tt_msgs[ec_tt], ll_msgs[ec_ll]);
-}
-
-static inline void amd64_decode_mem_cache_error(struct mem_ctl_info *mci,
-				      struct amd64_error_info_regs *info)
-{
-	u32 err_code;
-	u32 ec_rrrr;		/* error code memory transaction (4b) */
-	u32 ec_tt;		/* error code transaction type (2b) */
-	u32 ec_ll;		/* error code cache level (2b) */
-
-	err_code = EXTRACT_ERROR_CODE(info->nbsl);
-	ec_ll = EXTRACT_LL_CODE(err_code);
-	ec_tt = EXTRACT_TT_CODE(err_code);
-	ec_rrrr = EXTRACT_RRRR_CODE(err_code);
-
-	amd64_mc_printk(mci, KERN_ERR,
-		     "cache hierarchy error: memory transaction type(%s), "
-		     "transaction type(%s), cache level(%s)\n",
-		     rrrr_msgs[ec_rrrr], tt_msgs[ec_tt], ll_msgs[ec_ll]);
-}
-
-
 /*
  * Handle any Correctable Errors (CEs) that have occurred. Check for valid ERROR
  * ADDRESS and process.
  */
 static void amd64_handle_ce(struct mem_ctl_info *mci,
-			    struct amd64_error_info_regs *info)
+			    struct err_regs *info)
 {
 	struct amd64_pvt *pvt = mci->pvt_info;
 	u64 SystemAddress;
@@ -2216,7 +2212,7 @@ static void amd64_handle_ce(struct mem_ctl_info *mci,
 
 /* Handle any Un-correctable Errors (UEs) */
 static void amd64_handle_ue(struct mem_ctl_info *mci,
-			    struct amd64_error_info_regs *info)
+			    struct err_regs *info)
 {
 	int csrow;
 	u64 SystemAddress;
@@ -2261,59 +2257,24 @@ static void amd64_handle_ue(struct mem_ctl_info *mci,
 	}
 }
 
-static void amd64_decode_bus_error(struct mem_ctl_info *mci,
-				   struct amd64_error_info_regs *info)
+static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
+					    struct err_regs *info)
 {
-	u32 err_code, ext_ec;
-	u32 ec_pp;		/* error code participating processor (2p) */
-	u32 ec_to;		/* error code timed out (1b) */
-	u32 ec_rrrr;		/* error code memory transaction (4b) */
-	u32 ec_ii;		/* error code memory or I/O (2b) */
-	u32 ec_ll;		/* error code cache level (2b) */
-
-	ext_ec = EXTRACT_EXT_ERROR_CODE(info->nbsl);
-	err_code = EXTRACT_ERROR_CODE(info->nbsl);
+	u32 ec  = ERROR_CODE(info->nbsl);
+	u32 xec = EXT_ERROR_CODE(info->nbsl);
+	int ecc_type = info->nbsh & (0x3 << 13);
 
-	ec_ll = EXTRACT_LL_CODE(err_code);
-	ec_ii = EXTRACT_II_CODE(err_code);
-	ec_rrrr = EXTRACT_RRRR_CODE(err_code);
-	ec_to = EXTRACT_TO_CODE(err_code);
-	ec_pp = EXTRACT_PP_CODE(err_code);
-
-	amd64_mc_printk(mci, KERN_ERR,
-		"BUS ERROR:\n"
-		"  time-out(%s) mem or i/o(%s)\n"
-		"  participating processor(%s)\n"
-		"  memory transaction type(%s)\n"
-		"  cache level(%s) Error Found by: %s\n",
-		to_msgs[ec_to],
-		ii_msgs[ec_ii],
-		pp_msgs[ec_pp],
-		rrrr_msgs[ec_rrrr],
-		ll_msgs[ec_ll],
-		(info->nbsh & K8_NBSH_ERR_SCRUBER) ?
-			"Scrubber" : "Normal Operation");
-
-	/* If this was an 'observed' error, early out */
-	if (ec_pp == K8_NBSL_PP_OBS)
-		return;		/* We aren't the node involved */
-
-	/* Parse out the extended error code for ECC events */
-	switch (ext_ec) {
-	/* F10 changed to one Extended ECC error code */
-	case F10_NBSL_EXT_ERR_RES:		/* Reserved field */
-	case F10_NBSL_EXT_ERR_ECC:		/* F10 ECC ext err code */
-		break;
+	/* Bail early out if this was an 'observed' error */
+	if (PP(ec) == K8_NBSL_PP_OBS)
+		return;
 
-	default:
-		amd64_mc_printk(mci, KERN_ERR, "NOT ECC: no special error "
-					       "handling for this error\n");
+	/* Do only ECC errors */
+	if (xec && xec != F10_NBSL_EXT_ERR_ECC)
 		return;
-	}
 
-	if (info->nbsh & K8_NBSH_CECC)
+	if (ecc_type == 2)
 		amd64_handle_ce(mci, info);
-	else if (info->nbsh & K8_NBSH_UECC)
+	else if (ecc_type == 1)
 		amd64_handle_ue(mci, info);
 
 	/*
@@ -2324,139 +2285,26 @@ static void amd64_decode_bus_error(struct mem_ctl_info *mci,
 	 * catastrophic.
 	 */
 	if (info->nbsh & K8_NBSH_OVERFLOW)
-		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR
-					  "Error Overflow set");
+		edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR "Error Overflow");
 }
 
-int amd64_process_error_info(struct mem_ctl_info *mci,
-			     struct amd64_error_info_regs *info,
-			     int handle_errors)
+void amd64_decode_bus_error(int node_id, struct err_regs *regs)
 {
-	struct amd64_pvt *pvt;
-	struct amd64_error_info_regs *regs;
-	u32 err_code, ext_ec;
-	int gart_tlb_error = 0;
-
-	pvt = mci->pvt_info;
-
-	/* If caller doesn't want us to process the error, return */
-	if (!handle_errors)
-		return 1;
-
-	regs = info;
-
-	debugf1("NorthBridge ERROR: mci(0x%p)\n", mci);
-	debugf1("  MC node(%d) Error-Address(0x%.8x-%.8x)\n",
-		pvt->mc_node_id, regs->nbeah, regs->nbeal);
-	debugf1("  nbsh(0x%.8x) nbsl(0x%.8x)\n",
-		regs->nbsh, regs->nbsl);
-	debugf1("  Valid Error=%s Overflow=%s\n",
-		(regs->nbsh & K8_NBSH_VALID_BIT) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_OVERFLOW) ? "True" : "False");
-	debugf1("  Err Uncorrected=%s MCA Error Reporting=%s\n",
-		(regs->nbsh & K8_NBSH_UNCORRECTED_ERR) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_ERR_ENABLE) ?
-			"True" : "False");
-	debugf1("  MiscErr Valid=%s ErrAddr Valid=%s PCC=%s\n",
-		(regs->nbsh & K8_NBSH_MISC_ERR_VALID) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_VALID_ERROR_ADDR) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_PCC) ?
-			"True" : "False");
-	debugf1("  CECC=%s UECC=%s Found by Scruber=%s\n",
-		(regs->nbsh & K8_NBSH_CECC) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_UECC) ?
-			"True" : "False",
-		(regs->nbsh & K8_NBSH_ERR_SCRUBER) ?
-			"True" : "False");
-	debugf1("  CORE0=%s CORE1=%s CORE2=%s CORE3=%s\n",
-		(regs->nbsh & K8_NBSH_CORE0) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_CORE1) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_CORE2) ? "True" : "False",
-		(regs->nbsh & K8_NBSH_CORE3) ? "True" : "False");
-
+	struct mem_ctl_info *mci = mci_lookup[node_id];
 
-	err_code = EXTRACT_ERROR_CODE(regs->nbsl);
-
-	/* Determine which error type:
-	 *	1) GART errors - non-fatal, developmental events
-	 *	2) MEMORY errors
-	 *	3) BUS errors
-	 *	4) Unknown error
-	 */
-	if (TEST_TLB_ERROR(err_code)) {
-		/*
-		 * GART errors are intended to help graphics driver developers
-		 * to detect bad GART PTEs. It is recommended by AMD to disable
-		 * GART table walk error reporting by default[1] (currently
-		 * being disabled in mce_cpu_quirks()) and according to the
-		 * comment in mce_cpu_quirks(), such GART errors can be
-		 * incorrectly triggered. We may see these errors anyway and
-		 * unless requested by the user, they won't be reported.
-		 *
-		 * [1] section 13.10.1 on BIOS and Kernel Developers Guide for
-		 *     AMD NPT family 0Fh processors
-		 */
-		if (report_gart_errors == 0)
-			return 1;
-
-		/*
-		 * Only if GART error reporting is requested should we generate
-		 * any logs.
-		 */
-		gart_tlb_error = 1;
-
-		debugf1("GART TLB error\n");
-		amd64_decode_gart_tlb_error(mci, info);
-	} else if (TEST_MEM_ERROR(err_code)) {
-		debugf1("Memory/Cache error\n");
-		amd64_decode_mem_cache_error(mci, info);
-	} else if (TEST_BUS_ERROR(err_code)) {
-		debugf1("Bus (Link/DRAM) error\n");
-		amd64_decode_bus_error(mci, info);
-	} else {
-		/* shouldn't reach here! */
-		amd64_mc_printk(mci, KERN_WARNING,
-			     "%s(): unknown MCE error 0x%x\n", __func__,
-			     err_code);
-	}
-
-	ext_ec = EXTRACT_EXT_ERROR_CODE(regs->nbsl);
-	amd64_mc_printk(mci, KERN_ERR,
-		"ExtErr=(0x%x) %s\n", ext_ec, ext_msgs[ext_ec]);
-
-	if (((ext_ec >= F10_NBSL_EXT_ERR_CRC &&
-			ext_ec <= F10_NBSL_EXT_ERR_TGT) ||
-			(ext_ec == F10_NBSL_EXT_ERR_RMW)) &&
-			EXTRACT_LDT_LINK(info->nbsh)) {
-
-		amd64_mc_printk(mci, KERN_ERR,
-			"Error on hypertransport link: %s\n",
-			htlink_msgs[
-			EXTRACT_LDT_LINK(info->nbsh)]);
-	}
+	__amd64_decode_bus_error(mci, regs);
 
 	/*
 	 * Check the UE bit of the NB status high register, if set generate some
 	 * logs. If NOT a GART error, then process the event as a NO-INFO event.
 	 * If it was a GART error, skip that process.
+	 *
+	 * FIXME: this should go somewhere else, if at all.
 	 */
-	if (regs->nbsh & K8_NBSH_UNCORRECTED_ERR) {
-		amd64_mc_printk(mci, KERN_CRIT, "uncorrected error\n");
-		if (!gart_tlb_error)
-			edac_mc_handle_ue_no_info(mci, "UE bit is set\n");
-	}
-
-	if (regs->nbsh & K8_NBSH_PCC)
-		amd64_mc_printk(mci, KERN_CRIT,
-			"PCC (processor context corrupt) set\n");
+	if (regs->nbsh & K8_NBSH_UC_ERR && !report_gart_errors)
+		edac_mc_handle_ue_no_info(mci, "UE bit is set");
 
-	return 1;
 }
-EXPORT_SYMBOL_GPL(amd64_process_error_info);
 
 /*
  * The main polling 'check' function, called FROM the edac core to perform the
@@ -2464,10 +2312,12 @@ EXPORT_SYMBOL_GPL(amd64_process_error_info);
  */
 static void amd64_check(struct mem_ctl_info *mci)
 {
-	struct amd64_error_info_regs info;
+	struct err_regs regs;
 
-	if (amd64_get_error_info(mci, &info))
-		amd64_process_error_info(mci, &info, 1);
+	if (amd64_get_error_info(mci, &regs)) {
+		struct amd64_pvt *pvt = mci->pvt_info;
+		amd_decode_nb_mce(pvt->mc_node_id, &regs, 1);
+	}
 }
 
 /*
@@ -2891,30 +2741,53 @@ static void amd64_restore_ecc_error_reporting(struct amd64_pvt *pvt)
 	wrmsr_on_cpus(cpumask, K8_MSR_MCGCTL, msrs);
 }
 
-static void check_mcg_ctl(void *ret)
+/* get all cores on this DCT */
+static void get_cpus_on_this_dct_cpumask(cpumask_t *mask, int nid)
 {
-	u64 msr_val = 0;
-	u8 nbe;
-
-	rdmsrl(MSR_IA32_MCG_CTL, msr_val);
-	nbe = msr_val & K8_MSR_MCGCTL_NBE;
+	int cpu;
 
-	debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
-		raw_smp_processor_id(), msr_val,
-		(nbe ? "enabled" : "disabled"));
-
-	if (!nbe)
-		*(int *)ret = 0;
+	for_each_online_cpu(cpu)
+		if (amd_get_nb_id(cpu) == nid)
+			cpumask_set_cpu(cpu, mask);
 }
 
 /* check MCG_CTL on all the cpus on this node */
-static int amd64_mcg_ctl_enabled_on_cpus(const cpumask_t *mask)
+static bool amd64_nb_mce_bank_enabled_on_node(int nid)
 {
-	int ret = 1;
-	preempt_disable();
-	smp_call_function_many(mask, check_mcg_ctl, &ret, 1);
-	preempt_enable();
+	cpumask_t mask;
+	struct msr *msrs;
+	int cpu, nbe, idx = 0;
+	bool ret = false;
+
+	cpumask_clear(&mask);
+
+	get_cpus_on_this_dct_cpumask(&mask, nid);
+
+	msrs = kzalloc(sizeof(struct msr) * cpumask_weight(&mask), GFP_KERNEL);
+	if (!msrs) {
+		amd64_printk(KERN_WARNING, "%s: error allocating msrs\n",
+			      __func__);
+		 return false;
+	}
+
+	rdmsr_on_cpus(&mask, MSR_IA32_MCG_CTL, msrs);
+
+	for_each_cpu(cpu, &mask) {
+		nbe = msrs[idx].l & K8_MSR_MCGCTL_NBE;
 
+		debugf0("core: %u, MCG_CTL: 0x%llx, NB MSR is %s\n",
+			cpu, msrs[idx].q,
+			(nbe ? "enabled" : "disabled"));
+
+		if (!nbe)
+			goto out;
+
+		idx++;
+	}
+	ret = true;
+
+out:
+	kfree(msrs);
 	return ret;
 }
 
@@ -2924,71 +2797,46 @@ static int amd64_mcg_ctl_enabled_on_cpus(const cpumask_t *mask)
  * the memory system completely. A command line option allows to force-enable
  * hardware ECC later in amd64_enable_ecc_error_reporting().
  */
+static const char *ecc_warning =
+	"WARNING: ECC is disabled by BIOS. Module will NOT be loaded.\n"
+	" Either Enable ECC in the BIOS, or set 'ecc_enable_override'.\n"
+	" Also, use of the override can cause unknown side effects.\n";
+
 static int amd64_check_ecc_enabled(struct amd64_pvt *pvt)
 {
 	u32 value;
-	int err = 0, ret = 0;
+	int err = 0;
 	u8 ecc_enabled = 0;
+	bool nb_mce_en = false;
 
 	err = pci_read_config_dword(pvt->misc_f3_ctl, K8_NBCFG, &value);
 	if (err)
 		debugf0("Reading K8_NBCTL failed\n");
 
 	ecc_enabled = !!(value & K8_NBCFG_ECC_ENABLE);
+	if (!ecc_enabled)
+		amd64_printk(KERN_WARNING, "This node reports that Memory ECC "
+			     "is currently disabled, set F3x%x[22] (%s).\n",
+			     K8_NBCFG, pci_name(pvt->misc_f3_ctl));
+	else
+		amd64_printk(KERN_INFO, "ECC is enabled by BIOS.\n");
 
-	ret = amd64_mcg_ctl_enabled_on_cpus(cpumask_of_node(pvt->mc_node_id));
-
-	debugf0("K8_NBCFG=0x%x,  DRAM ECC is %s\n", value,
-			(value & K8_NBCFG_ECC_ENABLE ? "enabled" : "disabled"));
-
-	if (!ecc_enabled || !ret) {
-		if (!ecc_enabled) {
-			amd64_printk(KERN_WARNING, "This node reports that "
-						   "Memory ECC is currently "
-						   "disabled.\n");
+	nb_mce_en = amd64_nb_mce_bank_enabled_on_node(pvt->mc_node_id);
+	if (!nb_mce_en)
+		amd64_printk(KERN_WARNING, "NB MCE bank disabled, set MSR "
+			     "0x%08x[4] on node %d to enable.\n",
+			     MSR_IA32_MCG_CTL, pvt->mc_node_id);
 
-			amd64_printk(KERN_WARNING, "bit 0x%lx in register "
-				"F3x%x of the MISC_CONTROL device (%s) "
-				"should be enabled\n", K8_NBCFG_ECC_ENABLE,
-				K8_NBCFG, pci_name(pvt->misc_f3_ctl));
-		}
-		if (!ret) {
-			amd64_printk(KERN_WARNING, "bit 0x%016lx in MSR 0x%08x "
-					"of node %d should be enabled\n",
-					K8_MSR_MCGCTL_NBE, MSR_IA32_MCG_CTL,
-					pvt->mc_node_id);
-		}
+	if (!ecc_enabled || !nb_mce_en) {
 		if (!ecc_enable_override) {
-			amd64_printk(KERN_WARNING, "WARNING: ECC is NOT "
-				"currently enabled by the BIOS. Module "
-				"will NOT be loaded.\n"
-				"    Either Enable ECC in the BIOS, "
-				"or use the 'ecc_enable_override' "
-				"parameter.\n"
-				"    Might be a BIOS bug, if BIOS says "
-				"ECC is enabled\n"
-				"    Use of the override can cause "
-				"unknown side effects.\n");
-			ret = -ENODEV;
-		} else
-			/*
-			 * enable further driver loading if ECC enable is
-			 * overridden.
-			 */
-			ret = 0;
-	} else {
-		amd64_printk(KERN_INFO,
-			"ECC is enabled by BIOS, Proceeding "
-			"with EDAC module initialization\n");
-
-		/* Signal good ECC status */
-		ret = 0;
-
+			amd64_printk(KERN_WARNING, "%s", ecc_warning);
+			return -ENODEV;
+		}
+	} else
 		/* CLEAR the override, since BIOS controlled it */
 		ecc_enable_override = 0;
-	}
 
-	return ret;
+	return 0;
 }
 
 struct mcidev_sysfs_attribute sysfs_attrs[ARRAY_SIZE(amd64_dbg_attrs) +
@@ -3163,6 +3011,13 @@ static int amd64_init_2nd_stage(struct amd64_pvt *pvt)
 
 	mci_lookup[node_id] = mci;
 	pvt_lookup[node_id] = NULL;
+
+	/* register stuff with EDAC MCE */
+	if (report_gart_errors)
+		amd_report_gart_errors(true);
+
+	amd_register_ecc_decoder(amd64_decode_bus_error);
+
 	return 0;
 
 err_add_mc:
@@ -3229,6 +3084,10 @@ static void __devexit amd64_remove_one_instance(struct pci_dev *pdev)
 
 	mci_lookup[pvt->mc_node_id] = NULL;
 
+	/* unregister from EDAC MCE */
+	amd_report_gart_errors(false);
+	amd_unregister_ecc_decoder(amd64_decode_bus_error);
+
 	/* Free the EDAC CORE resources */
 	edac_mc_free(mci);
 }
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index ba73015..8ea07e2 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -72,6 +72,7 @@
 #include <linux/edac.h>
 #include <asm/msr.h>
 #include "edac_core.h"
+#include "edac_mce_amd.h"
 
 #define amd64_printk(level, fmt, arg...) \
 	edac_printk(level, "amd64", fmt, ##arg)
@@ -303,21 +304,9 @@ enum {
 #define K8_NBSL				0x48
 
 
-#define EXTRACT_HIGH_SYNDROME(x)	(((x) >> 24) & 0xff)
-#define EXTRACT_EXT_ERROR_CODE(x)	(((x) >> 16) & 0x1f)
-
 /* Family F10h: Normalized Extended Error Codes */
 #define F10_NBSL_EXT_ERR_RES		0x0
-#define F10_NBSL_EXT_ERR_CRC		0x1
-#define F10_NBSL_EXT_ERR_SYNC		0x2
-#define F10_NBSL_EXT_ERR_MST		0x3
-#define F10_NBSL_EXT_ERR_TGT		0x4
-#define F10_NBSL_EXT_ERR_GART		0x5
-#define F10_NBSL_EXT_ERR_RMW		0x6
-#define F10_NBSL_EXT_ERR_WDT		0x7
 #define F10_NBSL_EXT_ERR_ECC		0x8
-#define F10_NBSL_EXT_ERR_DEV		0x9
-#define F10_NBSL_EXT_ERR_LINK_DATA	0xA
 
 /* Next two are overloaded values */
 #define F10_NBSL_EXT_ERR_LINK_PROTO	0xB
@@ -348,17 +337,6 @@ enum {
 #define K8_NBSL_EXT_ERR_CHIPKILL_ECC	0x8
 #define K8_NBSL_EXT_ERR_DRAM_PARITY	0xD
 
-#define EXTRACT_ERROR_CODE(x)		((x) & 0xffff)
-#define	TEST_TLB_ERROR(x)		(((x) & 0xFFF0) == 0x0010)
-#define	TEST_MEM_ERROR(x)		(((x) & 0xFF00) == 0x0100)
-#define	TEST_BUS_ERROR(x)		(((x) & 0xF800) == 0x0800)
-#define	EXTRACT_TT_CODE(x)		(((x) >> 2) & 0x3)
-#define	EXTRACT_II_CODE(x)		(((x) >> 2) & 0x3)
-#define	EXTRACT_LL_CODE(x)		(((x) >> 0) & 0x3)
-#define	EXTRACT_RRRR_CODE(x)		(((x) >> 4) & 0xf)
-#define	EXTRACT_TO_CODE(x)		(((x) >> 8) & 0x1)
-#define	EXTRACT_PP_CODE(x)		(((x) >> 9) & 0x3)
-
 /*
  * The following are for BUS type errors AFTER values have been normalized by
  * shifting right
@@ -368,28 +346,7 @@ enum {
 #define K8_NBSL_PP_OBS			0x2
 #define K8_NBSL_PP_GENERIC		0x3
 
-
-#define K8_NBSH				0x4C
-
-#define K8_NBSH_VALID_BIT		BIT(31)
-#define K8_NBSH_OVERFLOW		BIT(30)
-#define K8_NBSH_UNCORRECTED_ERR		BIT(29)
-#define K8_NBSH_ERR_ENABLE		BIT(28)
-#define K8_NBSH_MISC_ERR_VALID		BIT(27)
-#define K8_NBSH_VALID_ERROR_ADDR	BIT(26)
-#define K8_NBSH_PCC			BIT(25)
-#define K8_NBSH_CECC			BIT(14)
-#define K8_NBSH_UECC			BIT(13)
-#define K8_NBSH_ERR_SCRUBER		BIT(8)
-#define K8_NBSH_CORE3			BIT(3)
-#define K8_NBSH_CORE2			BIT(2)
-#define K8_NBSH_CORE1			BIT(1)
-#define K8_NBSH_CORE0			BIT(0)
-
-#define EXTRACT_LDT_LINK(x)		(((x) >> 4) & 0x7)
 #define EXTRACT_ERR_CPU_MAP(x)		((x) & 0xF)
-#define EXTRACT_LOW_SYNDROME(x)		(((x) >> 15) & 0xff)
-
 
 #define K8_NBEAL			0x50
 #define K8_NBEAH			0x54
@@ -455,23 +412,6 @@ enum amd64_chipset_families {
 	F11_CPUS,
 };
 
-/*
- * Structure to hold:
- *
- * 1) dynamically read status and error address HW registers
- * 2) sysfs entered values
- * 3) MCE values
- *
- * Depends on entry into the modules
- */
-struct amd64_error_info_regs {
-	u32 nbcfg;
-	u32 nbsh;
-	u32 nbsl;
-	u32 nbeah;
-	u32 nbeal;
-};
-
 /* Error injection control structure */
 struct error_injection {
 	u32	section;
@@ -542,7 +482,7 @@ struct amd64_pvt {
 	u32 online_spare;               /* On-Line spare Reg */
 
 	/* temp storage for when input is received from sysfs */
-	struct amd64_error_info_regs ctl_error_info;
+	struct err_regs ctl_error_info;
 
 	/* place to store error injection parameters prior to issue */
 	struct error_injection injection;
@@ -601,11 +541,11 @@ struct low_ops {
 	int (*early_channel_count)(struct amd64_pvt *pvt);
 
 	u64 (*get_error_address)(struct mem_ctl_info *mci,
-			struct amd64_error_info_regs *info);
+			struct err_regs *info);
 	void (*read_dram_base_limit)(struct amd64_pvt *pvt, int dram);
 	void (*read_dram_ctl_register)(struct amd64_pvt *pvt);
 	void (*map_sysaddr_to_csrow)(struct mem_ctl_info *mci,
-					struct amd64_error_info_regs *info,
+					struct err_regs *info,
 					u64 SystemAddr);
 	int (*dbam_map_to_pages)(struct amd64_pvt *pvt, int dram_map);
 };
@@ -637,8 +577,5 @@ static inline struct low_ops *family_ops(int index)
 #define F10_MIN_SCRUB_RATE_BITS	0x5
 #define F11_MIN_SCRUB_RATE_BITS	0x6
 
-int amd64_process_error_info(struct mem_ctl_info *mci,
-			     struct amd64_error_info_regs *info,
-			     int handle_errors);
 int amd64_get_dram_hole_info(struct mem_ctl_info *mci, u64 *hole_base,
 			     u64 *hole_offset, u64 *hole_size);
diff --git a/drivers/edac/amd64_edac_dbg.c b/drivers/edac/amd64_edac_dbg.c
index 0a41b24..59cf2cf 100644
--- a/drivers/edac/amd64_edac_dbg.c
+++ b/drivers/edac/amd64_edac_dbg.c
@@ -24,7 +24,7 @@ static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data,
 
 		/* Process the Mapping request */
 		/* TODO: Add race prevention */
-		amd64_process_error_info(mci, &pvt->ctl_error_info, 1);
+		amd_decode_nb_mce(pvt->mc_node_id, &pvt->ctl_error_info, 1);
 
 		return count;
 	}
diff --git a/drivers/edac/amd64_edac_err_types.c b/drivers/edac/amd64_edac_err_types.c
deleted file mode 100644
index f212ff1..0000000
--- a/drivers/edac/amd64_edac_err_types.c
+++ /dev/null
@@ -1,161 +0,0 @@
-#include "amd64_edac.h"
-
-/*
- * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
- * for DDR2 DRAM mapping.
- */
-u32 revf_quad_ddr2_shift[] = {
-	0,	/* 0000b NULL DIMM (128mb) */
-	28,	/* 0001b 256mb */
-	29,	/* 0010b 512mb */
-	29,	/* 0011b 512mb */
-	29,	/* 0100b 512mb */
-	30,	/* 0101b 1gb */
-	30,	/* 0110b 1gb */
-	31,	/* 0111b 2gb */
-	31,	/* 1000b 2gb */
-	32,	/* 1001b 4gb */
-	32,	/* 1010b 4gb */
-	33,	/* 1011b 8gb */
-	0,	/* 1100b future */
-	0,	/* 1101b future */
-	0,	/* 1110b future */
-	0	/* 1111b future */
-};
-
-/*
- * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing
- * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching-
- * or higher value'.
- *
- *FIXME: Produce a better mapping/linearisation.
- */
-
-struct scrubrate scrubrates[] = {
-	{ 0x01, 1600000000UL},
-	{ 0x02, 800000000UL},
-	{ 0x03, 400000000UL},
-	{ 0x04, 200000000UL},
-	{ 0x05, 100000000UL},
-	{ 0x06, 50000000UL},
-	{ 0x07, 25000000UL},
-	{ 0x08, 12284069UL},
-	{ 0x09, 6274509UL},
-	{ 0x0A, 3121951UL},
-	{ 0x0B, 1560975UL},
-	{ 0x0C, 781440UL},
-	{ 0x0D, 390720UL},
-	{ 0x0E, 195300UL},
-	{ 0x0F, 97650UL},
-	{ 0x10, 48854UL},
-	{ 0x11, 24427UL},
-	{ 0x12, 12213UL},
-	{ 0x13, 6101UL},
-	{ 0x14, 3051UL},
-	{ 0x15, 1523UL},
-	{ 0x16, 761UL},
-	{ 0x00, 0UL},        /* scrubbing off */
-};
-
-/*
- * string representation for the different MCA reported error types, see F3x48
- * or MSR0000_0411.
- */
-const char *tt_msgs[] = {        /* transaction type */
-	"instruction",
-	"data",
-	"generic",
-	"reserved"
-};
-
-const char *ll_msgs[] = {	/* cache level */
-	"L0",
-	"L1",
-	"L2",
-	"L3/generic"
-};
-
-const char *rrrr_msgs[] = {
-	"generic",
-	"generic read",
-	"generic write",
-	"data read",
-	"data write",
-	"inst fetch",
-	"prefetch",
-	"evict",
-	"snoop",
-	"reserved RRRR= 9",
-	"reserved RRRR= 10",
-	"reserved RRRR= 11",
-	"reserved RRRR= 12",
-	"reserved RRRR= 13",
-	"reserved RRRR= 14",
-	"reserved RRRR= 15"
-};
-
-const char *pp_msgs[] = {	/* participating processor */
-	"local node originated (SRC)",
-	"local node responded to request (RES)",
-	"local node observed as 3rd party (OBS)",
-	"generic"
-};
-
-const char *to_msgs[] = {
-	"no timeout",
-	"timed out"
-};
-
-const char *ii_msgs[] = {	/* memory or i/o */
-	"mem access",
-	"reserved",
-	"i/o access",
-	"generic"
-};
-
-/* Map the 5 bits of Extended Error code to the string table. */
-const char *ext_msgs[] = {	/* extended error */
-	"K8 ECC error/F10 reserved",	/* 0_0000b */
-	"CRC error",			/* 0_0001b */
-	"sync error",			/* 0_0010b */
-	"mst abort",			/* 0_0011b */
-	"tgt abort",			/* 0_0100b */
-	"GART error",			/* 0_0101b */
-	"RMW error",			/* 0_0110b */
-	"Wdog timer error",		/* 0_0111b */
-	"F10-ECC/K8-Chipkill error",	/* 0_1000b */
-	"DEV Error",			/* 0_1001b */
-	"Link Data error",		/* 0_1010b */
-	"Link or L3 Protocol error",	/* 0_1011b */
-	"NB Array error",		/* 0_1100b */
-	"DRAM Parity error",		/* 0_1101b */
-	"Link Retry/GART Table Walk/DEV Table Walk error", /* 0_1110b */
-	"Res 0x0ff error",		/* 0_1111b */
-	"Res 0x100 error",		/* 1_0000b */
-	"Res 0x101 error",		/* 1_0001b */
-	"Res 0x102 error",		/* 1_0010b */
-	"Res 0x103 error",		/* 1_0011b */
-	"Res 0x104 error",		/* 1_0100b */
-	"Res 0x105 error",		/* 1_0101b */
-	"Res 0x106 error",		/* 1_0110b */
-	"Res 0x107 error",		/* 1_0111b */
-	"Res 0x108 error",		/* 1_1000b */
-	"Res 0x109 error",		/* 1_1001b */
-	"Res 0x10A error",		/* 1_1010b */
-	"Res 0x10B error",		/* 1_1011b */
-	"L3 Cache Data error",		/* 1_1100b */
-	"L3 CacheTag error",		/* 1_1101b */
-	"L3 Cache LRU error",		/* 1_1110b */
-	"Res 0x1FF error"		/* 1_1111b */
-};
-
-const char *htlink_msgs[] = {
-	"none",
-	"1",
-	"2",
-	"1 2",
-	"3",
-	"1 3",
-	"2 3",
-	"1 2 3"
-};
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
new file mode 100644
index 0000000..0c21c37
--- /dev/null
+++ b/drivers/edac/edac_mce_amd.c
@@ -0,0 +1,422 @@
+#include <linux/module.h>
+#include "edac_mce_amd.h"
+
+static bool report_gart_errors;
+static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
+
+void amd_report_gart_errors(bool v)
+{
+	report_gart_errors = v;
+}
+EXPORT_SYMBOL_GPL(amd_report_gart_errors);
+
+void amd_register_ecc_decoder(void (*f)(int, struct err_regs *))
+{
+	nb_bus_decoder = f;
+}
+EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
+
+void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *))
+{
+	if (nb_bus_decoder) {
+		WARN_ON(nb_bus_decoder != f);
+
+		nb_bus_decoder = NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(amd_unregister_ecc_decoder);
+
+/*
+ * string representation for the different MCA reported error types, see F3x48
+ * or MSR0000_0411.
+ */
+const char *tt_msgs[] = {        /* transaction type */
+	"instruction",
+	"data",
+	"generic",
+	"reserved"
+};
+EXPORT_SYMBOL_GPL(tt_msgs);
+
+const char *ll_msgs[] = {	/* cache level */
+	"L0",
+	"L1",
+	"L2",
+	"L3/generic"
+};
+EXPORT_SYMBOL_GPL(ll_msgs);
+
+const char *rrrr_msgs[] = {
+	"generic",
+	"generic read",
+	"generic write",
+	"data read",
+	"data write",
+	"inst fetch",
+	"prefetch",
+	"evict",
+	"snoop",
+	"reserved RRRR= 9",
+	"reserved RRRR= 10",
+	"reserved RRRR= 11",
+	"reserved RRRR= 12",
+	"reserved RRRR= 13",
+	"reserved RRRR= 14",
+	"reserved RRRR= 15"
+};
+EXPORT_SYMBOL_GPL(rrrr_msgs);
+
+const char *pp_msgs[] = {	/* participating processor */
+	"local node originated (SRC)",
+	"local node responded to request (RES)",
+	"local node observed as 3rd party (OBS)",
+	"generic"
+};
+EXPORT_SYMBOL_GPL(pp_msgs);
+
+const char *to_msgs[] = {
+	"no timeout",
+	"timed out"
+};
+EXPORT_SYMBOL_GPL(to_msgs);
+
+const char *ii_msgs[] = {	/* memory or i/o */
+	"mem access",
+	"reserved",
+	"i/o access",
+	"generic"
+};
+EXPORT_SYMBOL_GPL(ii_msgs);
+
+/*
+ * Map the 4 or 5 (family-specific) bits of Extended Error code to the
+ * string table.
+ */
+const char *ext_msgs[] = {
+	"K8 ECC error",					/* 0_0000b */
+	"CRC error on link",				/* 0_0001b */
+	"Sync error packets on link",			/* 0_0010b */
+	"Master Abort during link operation",		/* 0_0011b */
+	"Target Abort during link operation",		/* 0_0100b */
+	"Invalid GART PTE entry during table walk",	/* 0_0101b */
+	"Unsupported atomic RMW command received",	/* 0_0110b */
+	"WDT error: NB transaction timeout",		/* 0_0111b */
+	"ECC/ChipKill ECC error",			/* 0_1000b */
+	"SVM DEV Error",				/* 0_1001b */
+	"Link Data error",				/* 0_1010b */
+	"Link/L3/Probe Filter Protocol error",		/* 0_1011b */
+	"NB Internal Arrays Parity error",		/* 0_1100b */
+	"DRAM Address/Control Parity error",		/* 0_1101b */
+	"Link Transmission error",			/* 0_1110b */
+	"GART/DEV Table Walk Data error"		/* 0_1111b */
+	"Res 0x100 error",				/* 1_0000b */
+	"Res 0x101 error",				/* 1_0001b */
+	"Res 0x102 error",				/* 1_0010b */
+	"Res 0x103 error",				/* 1_0011b */
+	"Res 0x104 error",				/* 1_0100b */
+	"Res 0x105 error",				/* 1_0101b */
+	"Res 0x106 error",				/* 1_0110b */
+	"Res 0x107 error",				/* 1_0111b */
+	"Res 0x108 error",				/* 1_1000b */
+	"Res 0x109 error",				/* 1_1001b */
+	"Res 0x10A error",				/* 1_1010b */
+	"Res 0x10B error",				/* 1_1011b */
+	"ECC error in L3 Cache Data",			/* 1_1100b */
+	"L3 Cache Tag error",				/* 1_1101b */
+	"L3 Cache LRU Parity error",			/* 1_1110b */
+	"Probe Filter error"				/* 1_1111b */
+};
+EXPORT_SYMBOL_GPL(ext_msgs);
+
+static void amd_decode_dc_mce(u64 mc0_status)
+{
+	u32 ec  = mc0_status & 0xffff;
+	u32 xec = (mc0_status >> 16) & 0xf;
+
+	pr_emerg(" Data Cache Error");
+
+	if (xec == 1 && TLB_ERROR(ec))
+		pr_cont(": %s TLB multimatch.\n", LL_MSG(ec));
+	else if (xec == 0) {
+		if (mc0_status & (1ULL << 40))
+			pr_cont(" during Data Scrub.\n");
+		else if (TLB_ERROR(ec))
+			pr_cont(": %s TLB parity error.\n", LL_MSG(ec));
+		else if (MEM_ERROR(ec)) {
+			u8 ll   = ec & 0x3;
+			u8 tt   = (ec >> 2) & 0x3;
+			u8 rrrr = (ec >> 4) & 0xf;
+
+			/* see F10h BKDG (31116), Table 92. */
+			if (ll == 0x1) {
+				if (tt != 0x1)
+					goto wrong_dc_mce;
+
+				pr_cont(": Data/Tag %s error.\n", RRRR_MSG(ec));
+
+			} else if (ll == 0x2 && rrrr == 0x3)
+				pr_cont(" during L1 linefill from L2.\n");
+			else
+				goto wrong_dc_mce;
+		} else if (BUS_ERROR(ec) && boot_cpu_data.x86 == 0xf)
+			pr_cont(" during system linefill.\n");
+		else
+			goto wrong_dc_mce;
+	} else
+		goto wrong_dc_mce;
+
+	return;
+
+wrong_dc_mce:
+	pr_warning("Corrupted DC MCE info?\n");
+}
+
+static void amd_decode_ic_mce(u64 mc1_status)
+{
+	u32 ec  = mc1_status & 0xffff;
+	u32 xec = (mc1_status >> 16) & 0xf;
+
+	pr_emerg(" Instruction Cache Error");
+
+	if (xec == 1 && TLB_ERROR(ec))
+		pr_cont(": %s TLB multimatch.\n", LL_MSG(ec));
+	else if (xec == 0) {
+		if (TLB_ERROR(ec))
+			pr_cont(": %s TLB Parity error.\n", LL_MSG(ec));
+		else if (BUS_ERROR(ec)) {
+			if (boot_cpu_data.x86 == 0xf &&
+			    (mc1_status & (1ULL << 58)))
+				pr_cont(" during system linefill.\n");
+			else
+				pr_cont(" during attempted NB data read.\n");
+		} else if (MEM_ERROR(ec)) {
+			u8 ll   = ec & 0x3;
+			u8 rrrr = (ec >> 4) & 0xf;
+
+			if (ll == 0x2)
+				pr_cont(" during a linefill from L2.\n");
+			else if (ll == 0x1) {
+
+				switch (rrrr) {
+				case 0x5:
+					pr_cont(": Parity error during "
+					       "data load.\n");
+					break;
+
+				case 0x7:
+					pr_cont(": Copyback Parity/Victim"
+						" error.\n");
+					break;
+
+				case 0x8:
+					pr_cont(": Tag Snoop error.\n");
+					break;
+
+				default:
+					goto wrong_ic_mce;
+					break;
+				}
+			}
+		} else
+			goto wrong_ic_mce;
+	} else
+		goto wrong_ic_mce;
+
+	return;
+
+wrong_ic_mce:
+	pr_warning("Corrupted IC MCE info?\n");
+}
+
+static void amd_decode_bu_mce(u64 mc2_status)
+{
+	u32 ec = mc2_status & 0xffff;
+	u32 xec = (mc2_status >> 16) & 0xf;
+
+	pr_emerg(" Bus Unit Error");
+
+	if (xec == 0x1)
+		pr_cont(" in the write data buffers.\n");
+	else if (xec == 0x3)
+		pr_cont(" in the victim data buffers.\n");
+	else if (xec == 0x2 && MEM_ERROR(ec))
+		pr_cont(": %s error in the L2 cache tags.\n", RRRR_MSG(ec));
+	else if (xec == 0x0) {
+		if (TLB_ERROR(ec))
+			pr_cont(": %s error in a Page Descriptor Cache or "
+				"Guest TLB.\n", TT_MSG(ec));
+		else if (BUS_ERROR(ec))
+			pr_cont(": %s/ECC error in data read from NB: %s.\n",
+				RRRR_MSG(ec), PP_MSG(ec));
+		else if (MEM_ERROR(ec)) {
+			u8 rrrr = (ec >> 4) & 0xf;
+
+			if (rrrr >= 0x7)
+				pr_cont(": %s error during data copyback.\n",
+					RRRR_MSG(ec));
+			else if (rrrr <= 0x1)
+				pr_cont(": %s parity/ECC error during data "
+					"access from L2.\n", RRRR_MSG(ec));
+			else
+				goto wrong_bu_mce;
+		} else
+			goto wrong_bu_mce;
+	} else
+		goto wrong_bu_mce;
+
+	return;
+
+wrong_bu_mce:
+	pr_warning("Corrupted BU MCE info?\n");
+}
+
+static void amd_decode_ls_mce(u64 mc3_status)
+{
+	u32 ec  = mc3_status & 0xffff;
+	u32 xec = (mc3_status >> 16) & 0xf;
+
+	pr_emerg(" Load Store Error");
+
+	if (xec == 0x0) {
+		u8 rrrr = (ec >> 4) & 0xf;
+
+		if (!BUS_ERROR(ec) || (rrrr != 0x3 && rrrr != 0x4))
+			goto wrong_ls_mce;
+
+		pr_cont(" during %s.\n", RRRR_MSG(ec));
+	}
+	return;
+
+wrong_ls_mce:
+	pr_warning("Corrupted LS MCE info?\n");
+}
+
+void amd_decode_nb_mce(int node_id, struct err_regs *regs, int handle_errors)
+{
+	u32 ec  = ERROR_CODE(regs->nbsl);
+	u32 xec = EXT_ERROR_CODE(regs->nbsl);
+
+	if (!handle_errors)
+		return;
+
+	pr_emerg(" Northbridge Error, node %d", node_id);
+
+	/*
+	 * F10h, revD can disable ErrCpu[3:0] so check that first and also the
+	 * value encoding has changed so interpret those differently
+	 */
+	if ((boot_cpu_data.x86 == 0x10) &&
+	    (boot_cpu_data.x86_model > 8)) {
+		if (regs->nbsh & K8_NBSH_ERR_CPU_VAL)
+			pr_cont(", core: %u\n", (u8)(regs->nbsh & 0xf));
+	} else {
+		pr_cont(", core: %d\n", ilog2((regs->nbsh & 0xf)));
+	}
+
+
+	pr_emerg("%s.\n", EXT_ERR_MSG(xec));
+
+	if (BUS_ERROR(ec) && nb_bus_decoder)
+		nb_bus_decoder(node_id, regs);
+}
+EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
+
+static void amd_decode_fr_mce(u64 mc5_status)
+{
+	/* we have only one error signature so match all fields at once. */
+	if ((mc5_status & 0xffff) == 0x0f0f)
+		pr_emerg(" FR Error: CPU Watchdog timer expire.\n");
+	else
+		pr_warning("Corrupted FR MCE info?\n");
+}
+
+static inline void amd_decode_err_code(unsigned int ec)
+{
+	if (TLB_ERROR(ec)) {
+		/*
+		 * GART errors are intended to help graphics driver developers
+		 * to detect bad GART PTEs. It is recommended by AMD to disable
+		 * GART table walk error reporting by default[1] (currently
+		 * being disabled in mce_cpu_quirks()) and according to the
+		 * comment in mce_cpu_quirks(), such GART errors can be
+		 * incorrectly triggered. We may see these errors anyway and
+		 * unless requested by the user, they won't be reported.
+		 *
+		 * [1] section 13.10.1 on BIOS and Kernel Developers Guide for
+		 *     AMD NPT family 0Fh processors
+		 */
+		if (!report_gart_errors)
+			return;
+
+		pr_emerg(" Transaction: %s, Cache Level %s\n",
+			 TT_MSG(ec), LL_MSG(ec));
+	} else if (MEM_ERROR(ec)) {
+		pr_emerg(" Transaction: %s, Type: %s, Cache Level: %s",
+			 RRRR_MSG(ec), TT_MSG(ec), LL_MSG(ec));
+	} else if (BUS_ERROR(ec)) {
+		pr_emerg(" Transaction type: %s(%s), %s, Cache Level: %s, "
+			 "Participating Processor: %s\n",
+			  RRRR_MSG(ec), II_MSG(ec), TO_MSG(ec), LL_MSG(ec),
+			  PP_MSG(ec));
+	} else
+		pr_warning("Huh? Unknown MCE error 0x%x\n", ec);
+}
+
+void decode_mce(struct mce *m)
+{
+	struct err_regs regs;
+	int node, ecc;
+
+	pr_emerg("MC%d_STATUS: ", m->bank);
+
+	pr_cont("%sorrected error, report: %s, MiscV: %svalid, "
+		 "CPU context corrupt: %s",
+		 ((m->status & MCI_STATUS_UC) ? "Unc"  : "C"),
+		 ((m->status & MCI_STATUS_EN) ? "yes"  : "no"),
+		 ((m->status & MCI_STATUS_MISCV) ? ""  : "in"),
+		 ((m->status & MCI_STATUS_PCC) ? "yes" : "no"));
+
+	/* do the two bits[14:13] together */
+	ecc = m->status & (3ULL << 45);
+	if (ecc)
+		pr_cont(", %sECC Error", ((ecc == 2) ? "C" : "U"));
+
+	pr_cont("\n");
+
+	switch (m->bank) {
+	case 0:
+		amd_decode_dc_mce(m->status);
+		break;
+
+	case 1:
+		amd_decode_ic_mce(m->status);
+		break;
+
+	case 2:
+		amd_decode_bu_mce(m->status);
+		break;
+
+	case 3:
+		amd_decode_ls_mce(m->status);
+		break;
+
+	case 4:
+		regs.nbsl  = (u32) m->status;
+		regs.nbsh  = (u32)(m->status >> 32);
+		regs.nbeal = (u32) m->addr;
+		regs.nbeah = (u32)(m->addr >> 32);
+		node       = amd_get_nb_id(m->extcpu);
+
+		amd_decode_nb_mce(node, &regs, 1);
+		break;
+
+	case 5:
+		amd_decode_fr_mce(m->status);
+		break;
+
+	default:
+		break;
+	}
+
+	amd_decode_err_code(m->status & 0xffff);
+}
diff --git a/drivers/edac/edac_mce_amd.h b/drivers/edac/edac_mce_amd.h
new file mode 100644
index 0000000..df23ee0
--- /dev/null
+++ b/drivers/edac/edac_mce_amd.h
@@ -0,0 +1,69 @@
+#ifndef _EDAC_MCE_AMD_H
+#define _EDAC_MCE_AMD_H
+
+#include <asm/mce.h>
+
+#define ERROR_CODE(x)			((x) & 0xffff)
+#define EXT_ERROR_CODE(x)		(((x) >> 16) & 0x1f)
+#define EXT_ERR_MSG(x)			ext_msgs[EXT_ERROR_CODE(x)]
+
+#define LOW_SYNDROME(x)			(((x) >> 15) & 0xff)
+#define HIGH_SYNDROME(x)		(((x) >> 24) & 0xff)
+
+#define TLB_ERROR(x)			(((x) & 0xFFF0) == 0x0010)
+#define MEM_ERROR(x)			(((x) & 0xFF00) == 0x0100)
+#define BUS_ERROR(x)			(((x) & 0xF800) == 0x0800)
+
+#define TT(x)				(((x) >> 2) & 0x3)
+#define TT_MSG(x)			tt_msgs[TT(x)]
+#define II(x)				(((x) >> 2) & 0x3)
+#define II_MSG(x)			ii_msgs[II(x)]
+#define LL(x)				(((x) >> 0) & 0x3)
+#define LL_MSG(x)			ll_msgs[LL(x)]
+#define RRRR(x)				(((x) >> 4) & 0xf)
+#define RRRR_MSG(x)			rrrr_msgs[RRRR(x)]
+#define TO(x)				(((x) >> 8) & 0x1)
+#define TO_MSG(x)			to_msgs[TO(x)]
+#define PP(x)				(((x) >> 9) & 0x3)
+#define PP_MSG(x)			pp_msgs[PP(x)]
+
+#define K8_NBSH				0x4C
+
+#define K8_NBSH_VALID_BIT		BIT(31)
+#define K8_NBSH_OVERFLOW		BIT(30)
+#define K8_NBSH_UC_ERR			BIT(29)
+#define K8_NBSH_ERR_EN			BIT(28)
+#define K8_NBSH_MISCV			BIT(27)
+#define K8_NBSH_VALID_ERROR_ADDR	BIT(26)
+#define K8_NBSH_PCC			BIT(25)
+#define K8_NBSH_ERR_CPU_VAL		BIT(24)
+#define K8_NBSH_CECC			BIT(14)
+#define K8_NBSH_UECC			BIT(13)
+#define K8_NBSH_ERR_SCRUBER		BIT(8)
+
+extern const char *tt_msgs[];
+extern const char *ll_msgs[];
+extern const char *rrrr_msgs[];
+extern const char *pp_msgs[];
+extern const char *to_msgs[];
+extern const char *ii_msgs[];
+extern const char *ext_msgs[];
+
+/*
+ * relevant NB regs
+ */
+struct err_regs {
+	u32 nbcfg;
+	u32 nbsh;
+	u32 nbsl;
+	u32 nbeah;
+	u32 nbeal;
+};
+
+
+void amd_report_gart_errors(bool);
+void amd_register_ecc_decoder(void (*f)(int, struct err_regs *));
+void amd_unregister_ecc_decoder(void (*f)(int, struct err_regs *));
+void amd_decode_nb_mce(int, struct err_regs *, int);
+
+#endif /* _EDAC_MCE_AMD_H */
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index 97e656a..9d0dfcb 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -312,7 +312,7 @@ static void init_fw_attribute_group(struct device *dev,
 	group->groups[0] = &group->group;
 	group->groups[1] = NULL;
 	group->group.attrs = group->attrs;
-	dev->groups = group->groups;
+	dev->groups = (const struct attribute_group **) group->groups;
 }
 
 static ssize_t modalias_show(struct device *dev,
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index a42209a..cbaf420 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -663,8 +663,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
 	if (netif_queue_stopped(net))
 		netif_wake_queue(net);
 
-	net->last_rx = jiffies;
-
 	return 0;
 }
 
@@ -1188,7 +1186,7 @@ static int fwnet_stop(struct net_device *net)
 	return 0;
 }
 
-static int fwnet_tx(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
 {
 	struct fwnet_header hdr_buf;
 	struct fwnet_device *dev = netdev_priv(net);
@@ -1342,7 +1340,7 @@ static void fwnet_get_drvinfo(struct net_device *net,
 	strcpy(info->bus_info, "ieee1394");
 }
 
-static struct ethtool_ops fwnet_ethtool_ops = {
+static const struct ethtool_ops fwnet_ethtool_ops = {
 	.get_drvinfo = fwnet_get_drvinfo,
 };
 
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
index 5a76d05..dbdf6fa 100644
--- a/drivers/firmware/dmi-id.c
+++ b/drivers/firmware/dmi-id.c
@@ -139,7 +139,7 @@ static struct attribute_group sys_dmi_attribute_group = {
 	.attrs = sys_dmi_attributes,
 };
 
-static struct attribute_group* sys_dmi_attribute_groups[] = {
+static const struct attribute_group* sys_dmi_attribute_groups[] = {
 	&sys_dmi_attribute_group,
 	NULL
 };
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 96dda81..6b4c484 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -155,6 +155,13 @@ config GPIO_TWL4030
 	  Say yes here to access the GPIO signals of various multi-function
 	  power management chips from Texas Instruments.
 
+config GPIO_WM831X
+	tristate "WM831x GPIOs"
+	depends on MFD_WM831X
+	help
+	  Say yes here to access the GPIO signals of WM831x power management
+	  chips from Wolfson Microelectronics.
+
 comment "PCI GPIO expanders:"
 
 config GPIO_BT8XX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9244c6f..ea7c745 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_GPIO_TWL4030)	+= twl4030-gpio.o
 obj-$(CONFIG_GPIO_XILINX)	+= xilinx_gpio.o
 obj-$(CONFIG_GPIO_BT8XX)	+= bt8xxgpio.o
 obj-$(CONFIG_GPIO_VR41XX)	+= vr41xx_giu.o
+obj-$(CONFIG_GPIO_WM831X)	+= wm831x-gpio.o
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c
new file mode 100644
index 0000000..f9c09a5
--- /dev/null
+++ b/drivers/gpio/wm831x-gpio.c
@@ -0,0 +1,252 @@
+/*
+ * wm831x-gpio.c  --  gpiolib support for Wolfson WM831x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/gpio.h>
+
+#define WM831X_GPIO_MAX 16
+
+struct wm831x_gpio {
+	struct wm831x *wm831x;
+	struct gpio_chip gpio_chip;
+};
+
+static inline struct wm831x_gpio *to_wm831x_gpio(struct gpio_chip *chip)
+{
+	return container_of(chip, struct wm831x_gpio, gpio_chip);
+}
+
+static int wm831x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+	struct wm831x *wm831x = wm831x_gpio->wm831x;
+
+	return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
+			       WM831X_GPN_DIR | WM831X_GPN_TRI,
+			       WM831X_GPN_DIR);
+}
+
+static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+	struct wm831x *wm831x = wm831x_gpio->wm831x;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);
+	if (ret < 0)
+		return ret;
+
+	if (ret & 1 << offset)
+		return 1;
+	else
+		return 0;
+}
+
+static int wm831x_gpio_direction_out(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+	struct wm831x *wm831x = wm831x_gpio->wm831x;
+
+	return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
+			       WM831X_GPN_DIR | WM831X_GPN_TRI, 0);
+}
+
+static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+	struct wm831x *wm831x = wm831x_gpio->wm831x;
+
+	wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
+			value << offset);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
+	struct wm831x *wm831x = wm831x_gpio->wm831x;
+	int i;
+
+	for (i = 0; i < chip->ngpio; i++) {
+		int gpio = i + chip->base;
+		int reg;
+		const char *label, *pull, *powerdomain;
+
+		/* We report the GPIO even if it's not requested since
+		 * we're also reporting things like alternate
+		 * functions which apply even when the GPIO is not in
+		 * use as a GPIO.
+		 */
+		label = gpiochip_is_requested(chip, i);
+		if (!label)
+			label = "Unrequested";
+
+		seq_printf(s, " gpio-%-3d (%-20.20s) ", gpio, label);
+
+		reg = wm831x_reg_read(wm831x, WM831X_GPIO1_CONTROL + i);
+		if (reg < 0) {
+			dev_err(wm831x->dev,
+				"GPIO control %d read failed: %d\n",
+				gpio, reg);
+			seq_printf(s, "\n");
+			continue;
+		}
+
+		switch (reg & WM831X_GPN_PULL_MASK) {
+		case WM831X_GPIO_PULL_NONE:
+			pull = "nopull";
+			break;
+		case WM831X_GPIO_PULL_DOWN:
+			pull = "pulldown";
+			break;
+		case WM831X_GPIO_PULL_UP:
+			pull = "pullup";
+		default:
+			pull = "INVALID PULL";
+			break;
+		}
+
+		switch (i + 1) {
+		case 1 ... 3:
+		case 7 ... 9:
+			if (reg & WM831X_GPN_PWR_DOM)
+				powerdomain = "VPMIC";
+			else
+				powerdomain = "DBVDD";
+			break;
+
+		case 4 ... 6:
+		case 10 ... 12:
+			if (reg & WM831X_GPN_PWR_DOM)
+				powerdomain = "SYSVDD";
+			else
+				powerdomain = "DBVDD";
+			break;
+
+		case 13 ... 16:
+			powerdomain = "TPVDD";
+			break;
+
+		default:
+			BUG();
+			break;
+		}
+
+		seq_printf(s, " %s %s %s %s%s\n"
+			   "                                  %s%s (0x%4x)\n",
+			   reg & WM831X_GPN_DIR ? "in" : "out",
+			   wm831x_gpio_get(chip, i) ? "high" : "low",
+			   pull,
+			   powerdomain,
+			   reg & WM831X_GPN_POL ? " inverted" : "",
+			   reg & WM831X_GPN_OD ? "open-drain" : "CMOS",
+			   reg & WM831X_GPN_TRI ? " tristated" : "",
+			   reg);
+	}
+}
+#else
+#define wm831x_gpio_dbg_show NULL
+#endif
+
+static struct gpio_chip template_chip = {
+	.label			= "wm831x",
+	.owner			= THIS_MODULE,
+	.direction_input	= wm831x_gpio_direction_in,
+	.get			= wm831x_gpio_get,
+	.direction_output	= wm831x_gpio_direction_out,
+	.set			= wm831x_gpio_set,
+	.dbg_show		= wm831x_gpio_dbg_show,
+	.can_sleep		= 1,
+};
+
+static int __devinit wm831x_gpio_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	struct wm831x_gpio *wm831x_gpio;
+	int ret;
+
+	wm831x_gpio = kzalloc(sizeof(*wm831x_gpio), GFP_KERNEL);
+	if (wm831x_gpio == NULL)
+		return -ENOMEM;
+
+	wm831x_gpio->wm831x = wm831x;
+	wm831x_gpio->gpio_chip = template_chip;
+	wm831x_gpio->gpio_chip.ngpio = WM831X_GPIO_MAX;
+	wm831x_gpio->gpio_chip.dev = &pdev->dev;
+	if (pdata && pdata->gpio_base)
+		wm831x_gpio->gpio_chip.base = pdata->gpio_base;
+	else
+		wm831x_gpio->gpio_chip.base = -1;
+
+	ret = gpiochip_add(&wm831x_gpio->gpio_chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
+			ret);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, wm831x_gpio);
+
+	return ret;
+
+err:
+	kfree(wm831x_gpio);
+	return ret;
+}
+
+static int __devexit wm831x_gpio_remove(struct platform_device *pdev)
+{
+	struct wm831x_gpio *wm831x_gpio = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = gpiochip_remove(&wm831x_gpio->gpio_chip);
+	if (ret == 0)
+		kfree(wm831x_gpio);
+
+	return ret;
+}
+
+static struct platform_driver wm831x_gpio_driver = {
+	.driver.name	= "wm831x-gpio",
+	.driver.owner	= THIS_MODULE,
+	.probe		= wm831x_gpio_probe,
+	.remove		= __devexit_p(wm831x_gpio_remove),
+};
+
+static int __init wm831x_gpio_init(void)
+{
+	return platform_driver_register(&wm831x_gpio_driver);
+}
+subsys_initcall(wm831x_gpio_init);
+
+static void __exit wm831x_gpio_exit(void)
+{
+	platform_driver_unregister(&wm831x_gpio_driver);
+}
+module_exit(wm831x_gpio_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("GPIO interface for WM831x PMICs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-gpio");
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index de566cf..30879df 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1 @@
-obj-y			+= drm/
+obj-y			+= drm/ vga/
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 39b393d..e4d971c 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -18,6 +18,14 @@ menuconfig DRM
 	  details.  You should also select and configure AGP
 	  (/dev/agpgart) support.
 
+config DRM_KMS_HELPER
+	tristate
+	depends on DRM
+	select FB
+	select FRAMEBUFFER_CONSOLE if !EMBEDDED
+	help
+	  FB and CRTC helpers for KMS drivers.
+
 config DRM_TTM
 	tristate
 	depends on DRM
@@ -36,6 +44,7 @@ config DRM_TDFX
 config DRM_R128
 	tristate "ATI Rage 128"
 	depends on DRM && PCI
+	select FW_LOADER
 	help
 	  Choose this option if you have an ATI Rage 128 graphics card.  If M
 	  is selected, the module will be called r128.  AGP support for
@@ -47,8 +56,9 @@ config DRM_RADEON
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB
-	select FRAMEBUFFER_CONSOLE if !EMBEDDED
+	select FW_LOADER
+        select DRM_KMS_HELPER
+        select DRM_TTM
 	help
 	  Choose this option if you have an ATI Radeon graphics card.  There
 	  are both PCI and AGP versions.  You don't need to choose this to
@@ -82,11 +92,10 @@ config DRM_I830
 config DRM_I915
 	tristate "i915 driver"
 	depends on AGP_INTEL
+	select DRM_KMS_HELPER
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select FB
-	select FRAMEBUFFER_CONSOLE if !EMBEDDED
 	# i915 depends on ACPI_VIDEO when ACPI is enabled
 	# but for select to work, need to select ACPI_VIDEO's dependencies, ick
 	select VIDEO_OUTPUT_CONTROL if ACPI
@@ -116,6 +125,7 @@ endchoice
 config DRM_MGA
 	tristate "Matrox g200/g400"
 	depends on DRM
+	select FW_LOADER
 	help
 	  Choose this option if you have a Matrox G200, G400 or G450 graphics
 	  card.  If M is selected, the module will be called mga.  AGP
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index fe23f29..3c8827a 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -10,11 +10,15 @@ drm-y       :=	drm_auth.o drm_bufs.o drm_cache.o \
 		drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
 		drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
 		drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
-		drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \
-		drm_info.o drm_debugfs.o
+		drm_crtc.o drm_modes.o drm_edid.o \
+		drm_info.o drm_debugfs.o drm_encoder_slave.o
 
 drm-$(CONFIG_COMPAT) += drm_ioc32.o
 
+drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o
+
+obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
+
 obj-$(CONFIG_DRM)	+= drm.o
 obj-$(CONFIG_DRM_TTM)	+= ttm/
 obj-$(CONFIG_DRM_TDFX)	+= tdfx/
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 6246e3f..3d09e30 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -310,10 +310,10 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
 			  (unsigned long long)map->offset, map->size);
 
 		break;
+	}
 	case _DRM_GEM:
-		DRM_ERROR("tried to rmmap GEM object\n");
+		DRM_ERROR("tried to addmap GEM object\n");
 		break;
-	}
 	case _DRM_SCATTER_GATHER:
 		if (!dev->sg) {
 			kfree(map);
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 0e994a0..0e3bd5b 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -45,6 +45,23 @@ drm_clflush_page(struct page *page)
 		clflush(page_virtual + i);
 	kunmap_atomic(page_virtual, KM_USER0);
 }
+
+static void drm_cache_flush_clflush(struct page *pages[],
+				    unsigned long num_pages)
+{
+	unsigned long i;
+
+	mb();
+	for (i = 0; i < num_pages; i++)
+		drm_clflush_page(*pages++);
+	mb();
+}
+
+static void
+drm_clflush_ipi_handler(void *null)
+{
+	wbinvd();
+}
 #endif
 
 void
@@ -53,17 +70,30 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages)
 
 #if defined(CONFIG_X86)
 	if (cpu_has_clflush) {
-		unsigned long i;
-
-		mb();
-		for (i = 0; i < num_pages; ++i)
-			drm_clflush_page(*pages++);
-		mb();
-
+		drm_cache_flush_clflush(pages, num_pages);
 		return;
 	}
 
-	wbinvd();
+	if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
+		printk(KERN_ERR "Timed out waiting for cache flush.\n");
+
+#elif defined(__powerpc__)
+	unsigned long i;
+	for (i = 0; i < num_pages; i++) {
+		struct page *page = pages[i];
+		void *page_virtual;
+
+		if (unlikely(page == NULL))
+			continue;
+
+		page_virtual = kmap_atomic(page, KM_USER0);
+		flush_dcache_range((unsigned long)page_virtual,
+				   (unsigned long)page_virtual + PAGE_SIZE);
+		kunmap_atomic(page_virtual, KM_USER0);
+	}
+#else
+	printk(KERN_ERR "Architecture has no drm_cache.c support\n");
+	WARN_ON_ONCE(1);
 #endif
 }
 EXPORT_SYMBOL(drm_clflush_pages);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 2f631c7..ba728ad 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -68,10 +68,10 @@ DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
  */
 static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
 {
-	{ DRM_MODE_SCALE_NON_GPU, "Non-GPU" },
-	{ DRM_MODE_SCALE_FULLSCREEN, "Fullscreen" },
-	{ DRM_MODE_SCALE_NO_SCALE, "No scale" },
-	{ DRM_MODE_SCALE_ASPECT, "Aspect" },
+	{ DRM_MODE_SCALE_NONE, "None" },
+	{ DRM_MODE_SCALE_FULLSCREEN, "Full" },
+	{ DRM_MODE_SCALE_CENTER, "Center" },
+	{ DRM_MODE_SCALE_ASPECT, "Full aspect" },
 };
 
 static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
@@ -108,6 +108,7 @@ static struct drm_prop_enum_list drm_tv_select_enum_list[] =
 	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
 	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
 	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
+	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
 };
 
 DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
@@ -118,6 +119,7 @@ static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
 	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
 	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
 	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
+	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
 };
 
 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
@@ -146,6 +148,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
 	{ DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
 	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
 	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
+	{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
 };
 
 static struct drm_prop_enum_list drm_encoder_enum_list[] =
@@ -165,6 +168,7 @@ char *drm_get_encoder_name(struct drm_encoder *encoder)
 		 encoder->base.id);
 	return buf;
 }
+EXPORT_SYMBOL(drm_get_encoder_name);
 
 char *drm_get_connector_name(struct drm_connector *connector)
 {
@@ -699,6 +703,42 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
 		drm_property_add_enum(dev->mode_config.tv_mode_property, i,
 				      i, modes[i]);
 
+	dev->mode_config.tv_brightness_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "brightness", 2);
+	dev->mode_config.tv_brightness_property->values[0] = 0;
+	dev->mode_config.tv_brightness_property->values[1] = 100;
+
+	dev->mode_config.tv_contrast_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "contrast", 2);
+	dev->mode_config.tv_contrast_property->values[0] = 0;
+	dev->mode_config.tv_contrast_property->values[1] = 100;
+
+	dev->mode_config.tv_flicker_reduction_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "flicker reduction", 2);
+	dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
+	dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
+
+	dev->mode_config.tv_overscan_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "overscan", 2);
+	dev->mode_config.tv_overscan_property->values[0] = 0;
+	dev->mode_config.tv_overscan_property->values[1] = 100;
+
+	dev->mode_config.tv_saturation_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "saturation", 2);
+	dev->mode_config.tv_saturation_property->values[0] = 0;
+	dev->mode_config.tv_saturation_property->values[1] = 100;
+
+	dev->mode_config.tv_hue_property =
+		drm_property_create(dev, DRM_MODE_PROP_RANGE,
+				    "hue", 2);
+	dev->mode_config.tv_hue_property->values[0] = 0;
+	dev->mode_config.tv_hue_property->values[1] = 100;
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_mode_create_tv_properties);
@@ -1044,7 +1084,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 		if (file_priv->master->minor->type == DRM_MINOR_CONTROL) {
 			list_for_each_entry(crtc, &dev->mode_config.crtc_list,
 					    head) {
-				DRM_DEBUG("CRTC ID is %d\n", crtc->base.id);
+				DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id);
 				if (put_user(crtc->base.id, crtc_id + copied)) {
 					ret = -EFAULT;
 					goto out;
@@ -1072,7 +1112,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 			list_for_each_entry(encoder,
 					    &dev->mode_config.encoder_list,
 					    head) {
-				DRM_DEBUG("ENCODER ID is %d\n",
+				DRM_DEBUG_KMS("ENCODER ID is %d\n",
 					  encoder->base.id);
 				if (put_user(encoder->base.id, encoder_id +
 					     copied)) {
@@ -1103,7 +1143,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 			list_for_each_entry(connector,
 					    &dev->mode_config.connector_list,
 					    head) {
-				DRM_DEBUG("CONNECTOR ID is %d\n",
+				DRM_DEBUG_KMS("CONNECTOR ID is %d\n",
 					  connector->base.id);
 				if (put_user(connector->base.id,
 					     connector_id + copied)) {
@@ -1127,7 +1167,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
 	}
 	card_res->count_connectors = connector_count;
 
-	DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs,
+	DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs,
 		  card_res->count_connectors, card_res->count_encoders);
 
 out:
@@ -1230,7 +1270,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 
 	memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
 
-	DRM_DEBUG("connector id %d:\n", out_resp->connector_id);
+	DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id);
 
 	mutex_lock(&dev->mode_config.mutex);
 
@@ -1406,7 +1446,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 	obj = drm_mode_object_find(dev, crtc_req->crtc_id,
 				   DRM_MODE_OBJECT_CRTC);
 	if (!obj) {
-		DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id);
+		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -1419,7 +1459,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			list_for_each_entry(crtcfb,
 					    &dev->mode_config.crtc_list, head) {
 				if (crtcfb == crtc) {
-					DRM_DEBUG("Using current fb for setmode\n");
+					DRM_DEBUG_KMS("Using current fb for "
+							"setmode\n");
 					fb = crtc->fb;
 				}
 			}
@@ -1427,7 +1468,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			obj = drm_mode_object_find(dev, crtc_req->fb_id,
 						   DRM_MODE_OBJECT_FB);
 			if (!obj) {
-				DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id);
+				DRM_DEBUG_KMS("Unknown FB ID%d\n",
+						crtc_req->fb_id);
 				ret = -EINVAL;
 				goto out;
 			}
@@ -1440,13 +1482,13 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 	}
 
 	if (crtc_req->count_connectors == 0 && mode) {
-		DRM_DEBUG("Count connectors is 0 but mode set\n");
+		DRM_DEBUG_KMS("Count connectors is 0 but mode set\n");
 		ret = -EINVAL;
 		goto out;
 	}
 
 	if (crtc_req->count_connectors > 0 && (!mode || !fb)) {
-		DRM_DEBUG("Count connectors is %d but no mode or fb set\n",
+		DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n",
 			  crtc_req->count_connectors);
 		ret = -EINVAL;
 		goto out;
@@ -1479,7 +1521,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 			obj = drm_mode_object_find(dev, out_id,
 						   DRM_MODE_OBJECT_CONNECTOR);
 			if (!obj) {
-				DRM_DEBUG("Connector id %d unknown\n", out_id);
+				DRM_DEBUG_KMS("Connector id %d unknown\n",
+						out_id);
 				ret = -EINVAL;
 				goto out;
 			}
@@ -1512,7 +1555,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
 	struct drm_crtc *crtc;
 	int ret = 0;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	if (!req->flags) {
 		DRM_ERROR("no operation set\n");
@@ -1522,7 +1565,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
 	mutex_lock(&dev->mode_config.mutex);
 	obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
 	if (!obj) {
-		DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc_id);
+		DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
 		ret = -EINVAL;
 		goto out;
 	}
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 6aaa2cb..fe86974 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -33,15 +33,6 @@
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
 
-/*
- * Detailed mode info for 800x600@60Hz
- */
-static struct drm_display_mode std_modes[] = {
-	{ DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840,
-		   968, 1056, 0, 600, 601, 605, 628, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-};
-
 static void drm_mode_validate_flag(struct drm_connector *connector,
 				   int flags)
 {
@@ -94,7 +85,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 	int count = 0;
 	int mode_flags = 0;
 
-	DRM_DEBUG("%s\n", drm_get_connector_name(connector));
+	DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector));
 	/* set all modes to the unverified state */
 	list_for_each_entry_safe(mode, t, &connector->modes, head)
 		mode->status = MODE_UNVERIFIED;
@@ -102,15 +93,17 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 	connector->status = connector->funcs->detect(connector);
 
 	if (connector->status == connector_status_disconnected) {
-		DRM_DEBUG("%s is disconnected\n",
+		DRM_DEBUG_KMS("%s is disconnected\n",
 			  drm_get_connector_name(connector));
-		/* TODO set EDID to NULL */
-		return 0;
+		goto prune;
 	}
 
 	count = (*connector_funcs->get_modes)(connector);
-	if (!count)
-		return 0;
+	if (!count) {
+		count = drm_add_modes_noedid(connector, 800, 600);
+		if (!count)
+			return 0;
+	}
 
 	drm_mode_connector_list_update(connector);
 
@@ -130,7 +123,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 								   mode);
 	}
 
-
+prune:
 	drm_mode_prune_invalid(dev, &connector->modes, true);
 
 	if (list_empty(&connector->modes))
@@ -138,7 +131,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
 
 	drm_mode_sort(&connector->modes);
 
-	DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector));
+	DRM_DEBUG_KMS("Probed modes for %s\n",
+				drm_get_connector_name(connector));
 	list_for_each_entry_safe(mode, t, &connector->modes, head) {
 		mode->vrefresh = drm_mode_vrefresh(mode);
 
@@ -165,39 +159,6 @@ int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
 }
 EXPORT_SYMBOL(drm_helper_probe_connector_modes);
 
-static void drm_helper_add_std_modes(struct drm_device *dev,
-				     struct drm_connector *connector)
-{
-	struct drm_display_mode *mode, *t;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(std_modes); i++) {
-		struct drm_display_mode *stdmode;
-
-		/*
-		 * When no valid EDID modes are available we end up
-		 * here and bailed in the past, now we add some standard
-		 * modes and move on.
-		 */
-		stdmode = drm_mode_duplicate(dev, &std_modes[i]);
-		drm_mode_probed_add(connector, stdmode);
-		drm_mode_list_concat(&connector->probed_modes,
-				     &connector->modes);
-
-		DRM_DEBUG("Adding mode %s to %s\n", stdmode->name,
-			  drm_get_connector_name(connector));
-	}
-	drm_mode_sort(&connector->modes);
-
-	DRM_DEBUG("Added std modes on %s\n", drm_get_connector_name(connector));
-	list_for_each_entry_safe(mode, t, &connector->modes, head) {
-		mode->vrefresh = drm_mode_vrefresh(mode);
-
-		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
-		drm_mode_debug_printmodeline(mode);
-	}
-}
-
 /**
  * drm_helper_encoder_in_use - check if a given encoder is in use
  * @encoder: encoder to check
@@ -258,13 +219,27 @@ EXPORT_SYMBOL(drm_helper_crtc_in_use);
 void drm_helper_disable_unused_functions(struct drm_device *dev)
 {
 	struct drm_encoder *encoder;
+	struct drm_connector *connector;
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct drm_crtc *crtc;
 
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (!connector->encoder)
+			continue;
+		if (connector->status == connector_status_disconnected)
+			connector->encoder = NULL;
+	}
+
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		encoder_funcs = encoder->helper_private;
-		if (!drm_helper_encoder_in_use(encoder))
-			(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+		if (!drm_helper_encoder_in_use(encoder)) {
+			if (encoder_funcs->disable)
+				(*encoder_funcs->disable)(encoder);
+			else
+				(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
+			/* disconnector encoder from any connector */
+			encoder->crtc = NULL;
+		}
 	}
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -312,7 +287,7 @@ static void drm_enable_connectors(struct drm_device *dev, bool *enabled)
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		enabled[i] = drm_connector_enabled(connector, true);
-		DRM_DEBUG("connector %d enabled? %s\n", connector->base.id,
+		DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
 			  enabled[i] ? "yes" : "no");
 		any_enabled |= enabled[i];
 		i++;
@@ -342,7 +317,7 @@ static bool drm_target_preferred(struct drm_device *dev,
 			continue;
 		}
 
-		DRM_DEBUG("looking for preferred mode on connector %d\n",
+		DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
 			  connector->base.id);
 
 		modes[i] = drm_has_preferred_mode(connector, width, height);
@@ -351,7 +326,7 @@ static bool drm_target_preferred(struct drm_device *dev,
 			list_for_each_entry(modes[i], &connector->modes, head)
 				break;
 		}
-		DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name :
+		DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
 			  "none");
 		i++;
 	}
@@ -409,7 +384,7 @@ static int drm_pick_crtcs(struct drm_device *dev,
 	c = 0;
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 
-		if ((connector->encoder->possible_crtcs & (1 << c)) == 0) {
+		if ((encoder->possible_crtcs & (1 << c)) == 0) {
 			c++;
 			continue;
 		}
@@ -452,7 +427,7 @@ static void drm_setup_crtcs(struct drm_device *dev)
 	int width, height;
 	int i, ret;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	width = dev->mode_config.max_width;
 	height = dev->mode_config.max_height;
@@ -475,7 +450,7 @@ static void drm_setup_crtcs(struct drm_device *dev)
 	if (!ret)
 		DRM_ERROR("Unable to find initial modes\n");
 
-	DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height);
+	DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height);
 
 	drm_pick_crtcs(dev, crtcs, modes, 0, width, height);
 
@@ -490,12 +465,14 @@ static void drm_setup_crtcs(struct drm_device *dev)
 		}
 
 		if (mode && crtc) {
-			DRM_DEBUG("desired mode %s set on crtc %d\n",
+			DRM_DEBUG_KMS("desired mode %s set on crtc %d\n",
 				  mode->name, crtc->base.id);
 			crtc->desired_mode = mode;
 			connector->encoder->crtc = crtc;
-		} else
+		} else {
 			connector->encoder->crtc = NULL;
+			connector->encoder = NULL;
+		}
 		i++;
 	}
 
@@ -702,18 +679,17 @@ EXPORT_SYMBOL(drm_crtc_helper_set_mode);
 int drm_crtc_helper_set_config(struct drm_mode_set *set)
 {
 	struct drm_device *dev;
-	struct drm_crtc **save_crtcs, *new_crtc;
-	struct drm_encoder **save_encoders, *new_encoder;
+	struct drm_crtc *save_crtcs, *new_crtc, *crtc;
+	struct drm_encoder *save_encoders, *new_encoder, *encoder;
 	struct drm_framebuffer *old_fb = NULL;
-	bool save_enabled;
 	bool mode_changed = false; /* if true do a full mode set */
 	bool fb_changed = false; /* if true and !mode_changed just do a flip */
-	struct drm_connector *connector;
+	struct drm_connector *save_connectors, *connector;
 	int count = 0, ro, fail = 0;
 	struct drm_crtc_helper_funcs *crtc_funcs;
 	int ret = 0;
 
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	if (!set)
 		return -EINVAL;
@@ -726,37 +702,60 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 
 	crtc_funcs = set->crtc->helper_private;
 
-	DRM_DEBUG("crtc: %p %d fb: %p connectors: %p num_connectors: %d (x, y) (%i, %i)\n",
+	DRM_DEBUG_KMS("crtc: %p %d fb: %p connectors: %p num_connectors:"
+			" %d (x, y) (%i, %i)\n",
 		  set->crtc, set->crtc->base.id, set->fb, set->connectors,
 		  (int)set->num_connectors, set->x, set->y);
 
 	dev = set->crtc->dev;
 
-	/* save previous config */
-	save_enabled = set->crtc->enabled;
-
-	/*
-	 * We do mode_config.num_connectors here since we'll look at the
-	 * CRTC and encoder associated with each connector later.
-	 */
-	save_crtcs = kzalloc(dev->mode_config.num_connector *
-			     sizeof(struct drm_crtc *), GFP_KERNEL);
+	/* Allocate space for the backup of all (non-pointer) crtc, encoder and
+	 * connector data. */
+	save_crtcs = kzalloc(dev->mode_config.num_crtc *
+			     sizeof(struct drm_crtc), GFP_KERNEL);
 	if (!save_crtcs)
 		return -ENOMEM;
 
-	save_encoders = kzalloc(dev->mode_config.num_connector *
-				sizeof(struct drm_encoders *), GFP_KERNEL);
+	save_encoders = kzalloc(dev->mode_config.num_encoder *
+				sizeof(struct drm_encoder), GFP_KERNEL);
 	if (!save_encoders) {
 		kfree(save_crtcs);
 		return -ENOMEM;
 	}
 
+	save_connectors = kzalloc(dev->mode_config.num_connector *
+				sizeof(struct drm_connector), GFP_KERNEL);
+	if (!save_connectors) {
+		kfree(save_crtcs);
+		kfree(save_encoders);
+		return -ENOMEM;
+	}
+
+	/* Copy data. Note that driver private data is not affected.
+	 * Should anything bad happen only the expected state is
+	 * restored, not the drivers personal bookkeeping.
+	 */
+	count = 0;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		save_crtcs[count++] = *crtc;
+	}
+
+	count = 0;
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		save_encoders[count++] = *encoder;
+	}
+
+	count = 0;
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		save_connectors[count++] = *connector;
+	}
+
 	/* We should be able to check here if the fb has the same properties
 	 * and then just flip_or_move it */
 	if (set->crtc->fb != set->fb) {
 		/* If we have no fb then treat it as a full mode set */
 		if (set->crtc->fb == NULL) {
-			DRM_DEBUG("crtc has no fb, full mode set\n");
+			DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
 			mode_changed = true;
 		} else if (set->fb == NULL) {
 			mode_changed = true;
@@ -772,7 +771,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		fb_changed = true;
 
 	if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) {
-		DRM_DEBUG("modes are different, full mode set\n");
+		DRM_DEBUG_KMS("modes are different, full mode set\n");
 		drm_mode_debug_printmodeline(&set->crtc->mode);
 		drm_mode_debug_printmodeline(set->mode);
 		mode_changed = true;
@@ -783,7 +782,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 		struct drm_connector_helper_funcs *connector_funcs =
 			connector->helper_private;
-		save_encoders[count++] = connector->encoder;
 		new_encoder = connector->encoder;
 		for (ro = 0; ro < set->num_connectors; ro++) {
 			if (set->connectors[ro] == connector) {
@@ -798,15 +796,20 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		}
 
 		if (new_encoder != connector->encoder) {
-			DRM_DEBUG("encoder changed, full mode switch\n");
+			DRM_DEBUG_KMS("encoder changed, full mode switch\n");
 			mode_changed = true;
+			/* If the encoder is reused for another connector, then
+			 * the appropriate crtc will be set later.
+			 */
+			if (connector->encoder)
+				connector->encoder->crtc = NULL;
 			connector->encoder = new_encoder;
 		}
 	}
 
 	if (fail) {
 		ret = -EINVAL;
-		goto fail_no_encoder;
+		goto fail;
 	}
 
 	count = 0;
@@ -814,8 +817,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		if (!connector->encoder)
 			continue;
 
-		save_crtcs[count++] = connector->encoder->crtc;
-
 		if (connector->encoder->crtc == set->crtc)
 			new_crtc = NULL;
 		else
@@ -830,14 +831,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		if (new_crtc &&
 		    !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
 			ret = -EINVAL;
-			goto fail_set_mode;
+			goto fail;
 		}
 		if (new_crtc != connector->encoder->crtc) {
-			DRM_DEBUG("crtc changed, full mode switch\n");
+			DRM_DEBUG_KMS("crtc changed, full mode switch\n");
 			mode_changed = true;
 			connector->encoder->crtc = new_crtc;
 		}
-		DRM_DEBUG("setting connector %d crtc to %p\n",
+		DRM_DEBUG_KMS("setting connector %d crtc to %p\n",
 			  connector->base.id, new_crtc);
 	}
 
@@ -850,7 +851,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		set->crtc->fb = set->fb;
 		set->crtc->enabled = (set->mode != NULL);
 		if (set->mode != NULL) {
-			DRM_DEBUG("attempting to set mode from userspace\n");
+			DRM_DEBUG_KMS("attempting to set mode from"
+					" userspace\n");
 			drm_mode_debug_printmodeline(set->mode);
 			if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
 						      set->x, set->y,
@@ -858,7 +860,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 				DRM_ERROR("failed to set mode on crtc %p\n",
 					  set->crtc);
 				ret = -EINVAL;
-				goto fail_set_mode;
+				goto fail;
 			}
 			/* TODO are these needed? */
 			set->crtc->desired_x = set->x;
@@ -867,43 +869,50 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		}
 		drm_helper_disable_unused_functions(dev);
 	} else if (fb_changed) {
+		set->crtc->x = set->x;
+		set->crtc->y = set->y;
+
 		old_fb = set->crtc->fb;
 		if (set->crtc->fb != set->fb)
 			set->crtc->fb = set->fb;
 		ret = crtc_funcs->mode_set_base(set->crtc,
 						set->x, set->y, old_fb);
 		if (ret != 0)
-		    goto fail_set_mode;
+			goto fail;
 	}
 
+	kfree(save_connectors);
 	kfree(save_encoders);
 	kfree(save_crtcs);
 	return 0;
 
-fail_set_mode:
-	set->crtc->enabled = save_enabled;
-	set->crtc->fb = old_fb;
+fail:
+	/* Restore all previous data. */
 	count = 0;
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (!connector->encoder)
-			continue;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		*crtc = save_crtcs[count++];
+	}
 
-		connector->encoder->crtc = save_crtcs[count++];
+	count = 0;
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		*encoder = save_encoders[count++];
 	}
-fail_no_encoder:
-	kfree(save_crtcs);
+
 	count = 0;
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		connector->encoder = save_encoders[count++];
+		*connector = save_connectors[count++];
 	}
+
+	kfree(save_connectors);
 	kfree(save_encoders);
+	kfree(save_crtcs);
 	return ret;
 }
 EXPORT_SYMBOL(drm_crtc_helper_set_config);
 
 bool drm_helper_plugged_event(struct drm_device *dev)
 {
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	drm_helper_probe_connector_modes(dev, dev->mode_config.max_width,
 					 dev->mode_config.max_height);
@@ -932,7 +941,6 @@ bool drm_helper_plugged_event(struct drm_device *dev)
  */
 bool drm_helper_initial_config(struct drm_device *dev)
 {
-	struct drm_connector *connector;
 	int count = 0;
 
 	count = drm_helper_probe_connector_modes(dev,
@@ -940,16 +948,9 @@ bool drm_helper_initial_config(struct drm_device *dev)
 						 dev->mode_config.max_height);
 
 	/*
-	 * None of the available connectors had any modes, so add some
-	 * and try to light them up anyway
+	 * we shouldn't end up with no modes here.
 	 */
-	if (!count) {
-		DRM_ERROR("connectors have no modes, using standard modes\n");
-		list_for_each_entry(connector,
-				    &dev->mode_config.connector_list,
-				    head)
-			drm_helper_add_std_modes(dev, connector);
-	}
+	WARN(!count, "Connected connector with 0 modes\n");
 
 	drm_setup_crtcs(dev);
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index b39d7bf..a75ca63 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -63,12 +63,12 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
 	DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
 	DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
-	DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
 
 	DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+	DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
 
 	DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 7f2728b..90d76ba 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -60,6 +60,12 @@
 #define EDID_QUIRK_FIRST_DETAILED_PREFERRED	(1 << 5)
 /* use +hsync +vsync for detailed mode */
 #define EDID_QUIRK_DETAILED_SYNC_PP		(1 << 6)
+/* define the number of Extension EDID block */
+#define MAX_EDID_EXT_NUM 4
+
+#define LEVEL_DMT	0
+#define LEVEL_GTF	1
+#define LEVEL_CVT	2
 
 static struct edid_quirk {
 	char *vendor;
@@ -237,28 +243,291 @@ static void edid_fixup_preferred(struct drm_connector *connector,
 	preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
 }
 
+/*
+ * Add the Autogenerated from the DMT spec.
+ * This table is copied from xfree86/modes/xf86EdidModes.c.
+ * But the mode with Reduced blank feature is deleted.
+ */
+static struct drm_display_mode drm_dmt_modes[] = {
+	/* 640x350@85Hz */
+	{ DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
+		   736, 832, 0, 350, 382, 385, 445, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 640x400@85Hz */
+	{ DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672,
+		   736, 832, 0, 400, 401, 404, 445, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 720x400@85Hz */
+	{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756,
+		   828, 936, 0, 400, 401, 404, 446, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 640x480@60Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
+		   752, 800, 0, 480, 489, 492, 525, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 640x480@72Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
+		   704, 832, 0, 480, 489, 492, 520, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 640x480@75Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656,
+		   720, 840, 0, 480, 481, 484, 500, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 640x480@85Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696,
+		   752, 832, 0, 480, 481, 484, 509, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 800x600@56Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824,
+		   896, 1024, 0, 600, 601, 603, 625, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 800x600@60Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
+		   968, 1056, 0, 600, 601, 605, 628, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 800x600@72Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856,
+		   976, 1040, 0, 600, 637, 643, 666, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 800x600@75Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816,
+		   896, 1056, 0, 600, 601, 604, 625, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 800x600@85Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832,
+		   896, 1048, 0, 600, 601, 604, 631, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 848x480@60Hz */
+	{ DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864,
+		   976, 1088, 0, 480, 486, 494, 517, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1024x768@43Hz, interlace */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
+		   1208, 1264, 0, 768, 768, 772, 817, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
+			DRM_MODE_FLAG_INTERLACE) },
+	/* 1024x768@60Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
+		   1184, 1344, 0, 768, 771, 777, 806, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1024x768@70Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
+		   1184, 1328, 0, 768, 771, 777, 806, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1024x768@75Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
+		   1136, 1312, 0, 768, 769, 772, 800, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1024x768@85Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072,
+		   1072, 1376, 0, 768, 769, 772, 808, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1152x864@75Hz */
+	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
+		   1344, 1600, 0, 864, 865, 868, 900, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x768@60Hz */
+	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
+		   1472, 1664, 0, 768, 771, 778, 798, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x768@75Hz */
+	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360,
+		   1488, 1696, 0, 768, 771, 778, 805, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x768@85Hz */
+	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360,
+		   1496, 1712, 0, 768, 771, 778, 809, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x800@60Hz */
+	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
+		   1480, 1680, 0, 800, 803, 809, 831, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x800@75Hz */
+	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360,
+		   1488, 1696, 0, 800, 803, 809, 838, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x800@85Hz */
+	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360,
+		   1496, 1712, 0, 800, 803, 809, 843, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x960@60Hz */
+	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
+		   1488, 1800, 0, 960, 961, 964, 1000, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x960@85Hz */
+	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344,
+		   1504, 1728, 0, 960, 961, 964, 1011, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x1024@60Hz */
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
+		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x1024@75Hz */
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
+		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1280x1024@85Hz */
+	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344,
+		   1504, 1728, 0, 1024, 1025, 1028, 1072, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1360x768@60Hz */
+	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
+		   1536, 1792, 0, 768, 771, 777, 795, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x1050@60Hz */
+	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
+		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x1050@75Hz */
+	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504,
+		   1648, 1896, 0, 1050, 1053, 1057, 1099, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x1050@85Hz */
+	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504,
+		   1656, 1912, 0, 1050, 1053, 1057, 1105, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x900@60Hz */
+	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
+		   1672, 1904, 0, 900, 903, 909, 934, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x900@75Hz */
+	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536,
+		   1688, 1936, 0, 900, 903, 909, 942, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1440x900@85Hz */
+	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544,
+		   1696, 1952, 0, 900, 903, 909, 948, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1600x1200@60Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
+		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1600x1200@65Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664,
+		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1600x1200@70Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664,
+		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1600x1200@75Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 2025000, 1600, 1664,
+		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1600x1200@85Hz */
+	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664,
+		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1680x1050@60Hz */
+	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
+		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1680x1050@75Hz */
+	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800,
+		   1976, 2272, 0, 1050, 1053, 1059, 1099, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1680x1050@85Hz */
+	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808,
+		   1984, 2288, 0, 1050, 1053, 1059, 1105, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1792x1344@60Hz */
+	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
+		   2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1729x1344@75Hz */
+	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888,
+		   2104, 2456, 0, 1344, 1345, 1348, 1417, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1853x1392@60Hz */
+	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
+		   2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1856x1392@75Hz */
+	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984,
+		   2208, 2560, 0, 1392, 1395, 1399, 1500, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1200@60Hz */
+	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
+		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1200@75Hz */
+	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056,
+		   2264, 2608, 0, 1200, 1203, 1209, 1255, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1200@85Hz */
+	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064,
+		   2272, 2624, 0, 1200, 1203, 1209, 1262, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1440@60Hz */
+	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
+		   2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1920x1440@75Hz */
+	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064,
+		   2288, 2640, 0, 1440, 1441, 1444, 1500, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1600@60Hz */
+	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
+		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1600@75HZ */
+	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768,
+		   3048, 3536, 0, 1600, 1603, 1609, 1672, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 2560x1600@85HZ */
+	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768,
+		   3048, 3536, 0, 1600, 1603, 1609, 1682, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+};
+
+static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
+			int hsize, int vsize, int fresh)
+{
+	int i, count;
+	struct drm_display_mode *ptr, *mode;
+
+	count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
+	mode = NULL;
+	for (i = 0; i < count; i++) {
+		ptr = &drm_dmt_modes[i];
+		if (hsize == ptr->hdisplay &&
+			vsize == ptr->vdisplay &&
+			fresh == drm_mode_vrefresh(ptr)) {
+			/* get the expected default mode */
+			mode = drm_mode_duplicate(dev, ptr);
+			break;
+		}
+	}
+	return mode;
+}
 /**
  * drm_mode_std - convert standard mode info (width, height, refresh) into mode
  * @t: standard timing params
+ * @timing_level: standard timing level
  *
  * Take the standard timing params (in this case width, aspect, and refresh)
- * and convert them into a real mode using CVT.
+ * and convert them into a real mode using CVT/GTF/DMT.
  *
  * Punts for now, but should eventually use the FB layer's CVT based mode
  * generation code.
  */
 struct drm_display_mode *drm_mode_std(struct drm_device *dev,
-				      struct std_timing *t)
+				      struct std_timing *t,
+				      int timing_level)
 {
 	struct drm_display_mode *mode;
-	int hsize = t->hsize * 8 + 248, vsize;
+	int hsize, vsize;
+	int vrefresh_rate;
 	unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
 		>> EDID_TIMING_ASPECT_SHIFT;
-
-	mode = drm_mode_create(dev);
-	if (!mode)
-		return NULL;
-
+	unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
+		>> EDID_TIMING_VFREQ_SHIFT;
+
+	/* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
+	hsize = t->hsize * 8 + 248;
+	/* vrefresh_rate = vfreq + 60 */
+	vrefresh_rate = vfreq + 60;
+	/* the vdisplay is calculated based on the aspect ratio */
 	if (aspect_ratio == 0)
 		vsize = (hsize * 10) / 16;
 	else if (aspect_ratio == 1)
@@ -267,9 +536,30 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
 		vsize = (hsize * 4) / 5;
 	else
 		vsize = (hsize * 9) / 16;
-
-	drm_mode_set_name(mode);
-
+	/* HDTV hack */
+	if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) {
+		mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
+		mode->hdisplay = 1366;
+		mode->vsync_start = mode->vsync_start - 1;
+		mode->vsync_end = mode->vsync_end - 1;
+		return mode;
+	}
+	mode = NULL;
+	/* check whether it can be found in default mode table */
+	mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate);
+	if (mode)
+		return mode;
+
+	switch (timing_level) {
+	case LEVEL_DMT:
+		break;
+	case LEVEL_GTF:
+		mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
+		break;
+	case LEVEL_CVT:
+		mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
+		break;
+	}
 	return mode;
 }
 
@@ -451,6 +741,19 @@ static int add_established_modes(struct drm_connector *connector, struct edid *e
 
 	return modes;
 }
+/**
+ * stanard_timing_level - get std. timing level(CVT/GTF/DMT)
+ * @edid: EDID block to scan
+ */
+static int standard_timing_level(struct edid *edid)
+{
+	if (edid->revision >= 2) {
+		if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF))
+			return LEVEL_CVT;
+		return LEVEL_GTF;
+	}
+	return LEVEL_DMT;
+}
 
 /**
  * add_standard_modes - get std. modes from EDID and add them
@@ -463,6 +766,9 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
 {
 	struct drm_device *dev = connector->dev;
 	int i, modes = 0;
+	int timing_level;
+
+	timing_level = standard_timing_level(edid);
 
 	for (i = 0; i < EDID_STD_TIMINGS; i++) {
 		struct std_timing *t = &edid->standard_timings[i];
@@ -472,7 +778,8 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
 		if (t->hsize == 1 && t->vfreq_aspect == 1)
 			continue;
 
-		newmode = drm_mode_std(dev, &edid->standard_timings[i]);
+		newmode = drm_mode_std(dev, &edid->standard_timings[i],
+					timing_level);
 		if (newmode) {
 			drm_mode_probed_add(connector, newmode);
 			modes++;
@@ -496,6 +803,9 @@ static int add_detailed_info(struct drm_connector *connector,
 {
 	struct drm_device *dev = connector->dev;
 	int i, j, modes = 0;
+	int timing_level;
+
+	timing_level = standard_timing_level(edid);
 
 	for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
 		struct detailed_timing *timing = &edid->detailed_timings[i];
@@ -525,7 +835,8 @@ static int add_detailed_info(struct drm_connector *connector,
 					struct drm_display_mode *newmode;
 
 					std = &data->data.timings[j];
-					newmode = drm_mode_std(dev, std);
+					newmode = drm_mode_std(dev, std,
+							       timing_level);
 					if (newmode) {
 						drm_mode_probed_add(connector, newmode);
 						modes++;
@@ -551,6 +862,122 @@ static int add_detailed_info(struct drm_connector *connector,
 
 	return modes;
 }
+/**
+ * add_detailed_mode_eedid - get detailed mode info from addtional timing
+ * 			EDID block
+ * @connector: attached connector
+ * @edid: EDID block to scan(It is only to get addtional timing EDID block)
+ * @quirks: quirks to apply
+ *
+ * Some of the detailed timing sections may contain mode information.  Grab
+ * it and add it to the list.
+ */
+static int add_detailed_info_eedid(struct drm_connector *connector,
+			     struct edid *edid, u32 quirks)
+{
+	struct drm_device *dev = connector->dev;
+	int i, j, modes = 0;
+	char *edid_ext = NULL;
+	struct detailed_timing *timing;
+	struct detailed_non_pixel *data;
+	struct drm_display_mode *newmode;
+	int edid_ext_num;
+	int start_offset, end_offset;
+	int timing_level;
+
+	if (edid->version == 1 && edid->revision < 3) {
+		/* If the EDID version is less than 1.3, there is no
+		 * extension EDID.
+		 */
+		return 0;
+	}
+	if (!edid->extensions) {
+		/* if there is no extension EDID, it is unnecessary to
+		 * parse the E-EDID to get detailed info
+		 */
+		return 0;
+	}
+
+	/* Chose real EDID extension number */
+	edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
+		       MAX_EDID_EXT_NUM : edid->extensions;
+
+	/* Find CEA extension */
+	for (i = 0; i < edid_ext_num; i++) {
+		edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
+		/* This block is CEA extension */
+		if (edid_ext[0] == 0x02)
+			break;
+	}
+
+	if (i == edid_ext_num) {
+		/* if there is no additional timing EDID block, return */
+		return 0;
+	}
+
+	/* Get the start offset of detailed timing block */
+	start_offset = edid_ext[2];
+	if (start_offset == 0) {
+		/* If the start_offset is zero, it means that neither detailed
+		 * info nor data block exist. In such case it is also
+		 * unnecessary to parse the detailed timing info.
+		 */
+		return 0;
+	}
+
+	timing_level = standard_timing_level(edid);
+	end_offset = EDID_LENGTH;
+	end_offset -= sizeof(struct detailed_timing);
+	for (i = start_offset; i < end_offset;
+			i += sizeof(struct detailed_timing)) {
+		timing = (struct detailed_timing *)(edid_ext + i);
+		data = &timing->data.other_data;
+		/* Detailed mode timing */
+		if (timing->pixel_clock) {
+			newmode = drm_mode_detailed(dev, edid, timing, quirks);
+			if (!newmode)
+				continue;
+
+			drm_mode_probed_add(connector, newmode);
+
+			modes++;
+			continue;
+		}
+
+		/* Other timing or info */
+		switch (data->type) {
+		case EDID_DETAIL_MONITOR_SERIAL:
+			break;
+		case EDID_DETAIL_MONITOR_STRING:
+			break;
+		case EDID_DETAIL_MONITOR_RANGE:
+			/* Get monitor range data */
+			break;
+		case EDID_DETAIL_MONITOR_NAME:
+			break;
+		case EDID_DETAIL_MONITOR_CPDATA:
+			break;
+		case EDID_DETAIL_STD_MODES:
+			/* Five modes per detailed section */
+			for (j = 0; j < 5; i++) {
+				struct std_timing *std;
+				struct drm_display_mode *newmode;
+
+				std = &data->data.timings[j];
+				newmode = drm_mode_std(dev, std, timing_level);
+				if (newmode) {
+					drm_mode_probed_add(connector, newmode);
+					modes++;
+				}
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	return modes;
+}
 
 #define DDC_ADDR 0x50
 /**
@@ -584,7 +1011,6 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
 	if (i2c_transfer(adapter, msgs, 2) == 2)
 		return 0;
 
-	dev_info(&adapter->dev, "unable to read EDID block.\n");
 	return -1;
 }
 EXPORT_SYMBOL(drm_do_probe_ddc_edid);
@@ -597,8 +1023,6 @@ static int drm_ddc_read_edid(struct drm_connector *connector,
 
 	ret = drm_do_probe_ddc_edid(adapter, buf, len);
 	if (ret != 0) {
-		dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
-			 drm_get_connector_name(connector));
 		goto end;
 	}
 	if (!edid_is_valid((struct edid *)buf)) {
@@ -610,7 +1034,6 @@ end:
 	return ret;
 }
 
-#define MAX_EDID_EXT_NUM 4
 /**
  * drm_get_edid - get EDID data, if available
  * @connector: connector we're probing
@@ -763,6 +1186,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
 	num_modes += add_established_modes(connector, edid);
 	num_modes += add_standard_modes(connector, edid);
 	num_modes += add_detailed_info(connector, edid, quirks);
+	num_modes += add_detailed_info_eedid(connector, edid, quirks);
 
 	if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
 		edid_fixup_preferred(connector, quirks);
@@ -788,3 +1212,49 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
 	return num_modes;
 }
 EXPORT_SYMBOL(drm_add_edid_modes);
+
+/**
+ * drm_add_modes_noedid - add modes for the connectors without EDID
+ * @connector: connector we're probing
+ * @hdisplay: the horizontal display limit
+ * @vdisplay: the vertical display limit
+ *
+ * Add the specified modes to the connector's mode list. Only when the
+ * hdisplay/vdisplay is not beyond the given limit, it will be added.
+ *
+ * Return number of modes added or 0 if we couldn't find any.
+ */
+int drm_add_modes_noedid(struct drm_connector *connector,
+			int hdisplay, int vdisplay)
+{
+	int i, count, num_modes = 0;
+	struct drm_display_mode *mode, *ptr;
+	struct drm_device *dev = connector->dev;
+
+	count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode);
+	if (hdisplay < 0)
+		hdisplay = 0;
+	if (vdisplay < 0)
+		vdisplay = 0;
+
+	for (i = 0; i < count; i++) {
+		ptr = &drm_dmt_modes[i];
+		if (hdisplay && vdisplay) {
+			/*
+			 * Only when two are valid, they will be used to check
+			 * whether the mode should be added to the mode list of
+			 * the connector.
+			 */
+			if (ptr->hdisplay > hdisplay ||
+					ptr->vdisplay > vdisplay)
+				continue;
+		}
+		mode = drm_mode_duplicate(dev, ptr);
+		if (mode) {
+			drm_mode_probed_add(connector, mode);
+			num_modes++;
+		}
+	}
+	return num_modes;
+}
+EXPORT_SYMBOL(drm_add_modes_noedid);
diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c
new file mode 100644
index 0000000..f018469
--- /dev/null
+++ b/drivers/gpu/drm/drm_encoder_slave.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "drm_encoder_slave.h"
+
+/**
+ * drm_i2c_encoder_init - Initialize an I2C slave encoder
+ * @dev:	DRM device.
+ * @encoder:    Encoder to be attached to the I2C device. You aren't
+ *		required to have called drm_encoder_init() before.
+ * @adap:	I2C adapter that will be used to communicate with
+ *		the device.
+ * @info:	Information that will be used to create the I2C device.
+ *		Required fields are @addr and @type.
+ *
+ * Create an I2C device on the specified bus (the module containing its
+ * driver is transparently loaded) and attach it to the specified
+ * &drm_encoder_slave. The @slave_funcs field will be initialized with
+ * the hooks provided by the slave driver.
+ *
+ * Returns 0 on success or a negative errno on failure, in particular,
+ * -ENODEV is returned when no matching driver is found.
+ */
+int drm_i2c_encoder_init(struct drm_device *dev,
+			 struct drm_encoder_slave *encoder,
+			 struct i2c_adapter *adap,
+			 const struct i2c_board_info *info)
+{
+	char modalias[sizeof(I2C_MODULE_PREFIX)
+		      + I2C_NAME_SIZE];
+	struct module *module = NULL;
+	struct i2c_client *client;
+	struct drm_i2c_encoder_driver *encoder_drv;
+	int err = 0;
+
+	snprintf(modalias, sizeof(modalias),
+		 "%s%s", I2C_MODULE_PREFIX, info->type);
+	request_module(modalias);
+
+	client = i2c_new_device(adap, info);
+	if (!client) {
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	if (!client->driver) {
+		err = -ENODEV;
+		goto fail_unregister;
+	}
+
+	module = client->driver->driver.owner;
+	if (!try_module_get(module)) {
+		err = -ENODEV;
+		goto fail_unregister;
+	}
+
+	encoder->bus_priv = client;
+
+	encoder_drv = to_drm_i2c_encoder_driver(client->driver);
+
+	err = encoder_drv->encoder_init(client, dev, encoder);
+	if (err)
+		goto fail_unregister;
+
+	return 0;
+
+fail_unregister:
+	i2c_unregister_device(client);
+	module_put(module);
+fail:
+	return err;
+}
+EXPORT_SYMBOL(drm_i2c_encoder_init);
+
+/**
+ * drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder
+ * @drm_encoder:	Encoder to be unregistered.
+ *
+ * This should be called from the @destroy method of an I2C slave
+ * encoder driver once I2C access is no longer needed.
+ */
+void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder)
+{
+	struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder);
+	struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder);
+	struct module *module = client->driver->driver.owner;
+
+	i2c_unregister_device(client);
+	encoder->bus_priv = NULL;
+
+	module_put(module);
+}
+EXPORT_SYMBOL(drm_i2c_encoder_destroy);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
new file mode 100644
index 0000000..2c46713
--- /dev/null
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) 2006-2009 Red Hat Inc.
+ * Copyright (c) 2006-2008 Intel Corporation
+ * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
+ *
+ * DRM framebuffer helper functions
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Authors:
+ *      Dave Airlie <airlied@linux.ie>
+ *      Jesse Barnes <jesse.barnes@intel.com>
+ */
+#include <linux/sysrq.h>
+#include <linux/fb.h>
+#include "drmP.h"
+#include "drm_crtc.h"
+#include "drm_fb_helper.h"
+#include "drm_crtc_helper.h"
+
+MODULE_AUTHOR("David Airlie, Jesse Barnes");
+MODULE_DESCRIPTION("DRM KMS helper");
+MODULE_LICENSE("GPL and additional rights");
+
+static LIST_HEAD(kernel_fb_helper_list);
+
+bool drm_fb_helper_force_kernel_mode(void)
+{
+	int i = 0;
+	bool ret, error = false;
+	struct drm_fb_helper *helper;
+
+	if (list_empty(&kernel_fb_helper_list))
+		return false;
+
+	list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
+		for (i = 0; i < helper->crtc_count; i++) {
+			struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
+			ret = drm_crtc_helper_set_config(mode_set);
+			if (ret)
+				error = true;
+		}
+	}
+	return error;
+}
+
+int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed,
+			void *panic_str)
+{
+	DRM_ERROR("panic occurred, switching back to text console\n");
+	return drm_fb_helper_force_kernel_mode();
+	return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_panic);
+
+static struct notifier_block paniced = {
+	.notifier_call = drm_fb_helper_panic,
+};
+
+/**
+ * drm_fb_helper_restore - restore the framebuffer console (kernel) config
+ *
+ * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
+ */
+void drm_fb_helper_restore(void)
+{
+	bool ret;
+	ret = drm_fb_helper_force_kernel_mode();
+	if (ret == true)
+		DRM_ERROR("Failed to restore crtc configuration\n");
+}
+EXPORT_SYMBOL(drm_fb_helper_restore);
+
+static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
+{
+	drm_fb_helper_restore();
+}
+static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn);
+
+static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3)
+{
+	schedule_work(&drm_fb_helper_restore_work);
+}
+
+static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
+	.handler = drm_fb_helper_sysrq,
+	.help_msg = "force-fb(V)",
+	.action_msg = "Restore framebuffer console",
+};
+
+static void drm_fb_helper_on(struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_device *dev = fb_helper->dev;
+	struct drm_crtc *crtc;
+	struct drm_encoder *encoder;
+	int i;
+
+	/*
+	 * For each CRTC in this fb, turn the crtc on then,
+	 * find all associated encoders and turn them on.
+	 */
+	for (i = 0; i < fb_helper->crtc_count; i++) {
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+			struct drm_crtc_helper_funcs *crtc_funcs =
+				crtc->helper_private;
+
+			/* Only mess with CRTCs in this fb */
+			if (crtc->base.id != fb_helper->crtc_info[i].crtc_id ||
+			    !crtc->enabled)
+				continue;
+
+			mutex_lock(&dev->mode_config.mutex);
+			crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+			mutex_unlock(&dev->mode_config.mutex);
+
+			/* Found a CRTC on this fb, now find encoders */
+			list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+				if (encoder->crtc == crtc) {
+					struct drm_encoder_helper_funcs *encoder_funcs;
+
+					encoder_funcs = encoder->helper_private;
+					mutex_lock(&dev->mode_config.mutex);
+					encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
+					mutex_unlock(&dev->mode_config.mutex);
+				}
+			}
+		}
+	}
+}
+
+static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_device *dev = fb_helper->dev;
+	struct drm_crtc *crtc;
+	struct drm_encoder *encoder;
+	int i;
+
+	/*
+	 * For each CRTC in this fb, find all associated encoders
+	 * and turn them off, then turn off the CRTC.
+	 */
+	for (i = 0; i < fb_helper->crtc_count; i++) {
+		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+			struct drm_crtc_helper_funcs *crtc_funcs =
+				crtc->helper_private;
+
+			/* Only mess with CRTCs in this fb */
+			if (crtc->base.id != fb_helper->crtc_info[i].crtc_id ||
+			    !crtc->enabled)
+				continue;
+
+			/* Found a CRTC on this fb, now find encoders */
+			list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+				if (encoder->crtc == crtc) {
+					struct drm_encoder_helper_funcs *encoder_funcs;
+
+					encoder_funcs = encoder->helper_private;
+					mutex_lock(&dev->mode_config.mutex);
+					encoder_funcs->dpms(encoder, dpms_mode);
+					mutex_unlock(&dev->mode_config.mutex);
+				}
+			}
+			if (dpms_mode == DRM_MODE_DPMS_OFF) {
+				mutex_lock(&dev->mode_config.mutex);
+				crtc_funcs->dpms(crtc, dpms_mode);
+				mutex_unlock(&dev->mode_config.mutex);
+			}
+		}
+	}
+}
+
+int drm_fb_helper_blank(int blank, struct fb_info *info)
+{
+	switch (blank) {
+	case FB_BLANK_UNBLANK:
+		drm_fb_helper_on(info);
+		break;
+	case FB_BLANK_NORMAL:
+		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
+		break;
+	case FB_BLANK_HSYNC_SUSPEND:
+		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
+		break;
+	case FB_BLANK_VSYNC_SUSPEND:
+		drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
+		break;
+	case FB_BLANK_POWERDOWN:
+		drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
+		break;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_blank);
+
+static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
+{
+	int i;
+
+	for (i = 0; i < helper->crtc_count; i++)
+		kfree(helper->crtc_info[i].mode_set.connectors);
+	kfree(helper->crtc_info);
+}
+
+int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, int max_conn_count)
+{
+	struct drm_device *dev = helper->dev;
+	struct drm_crtc *crtc;
+	int ret = 0;
+	int i;
+
+	helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL);
+	if (!helper->crtc_info)
+		return -ENOMEM;
+
+	helper->crtc_count = crtc_count;
+
+	for (i = 0; i < crtc_count; i++) {
+		helper->crtc_info[i].mode_set.connectors =
+			kcalloc(max_conn_count,
+				sizeof(struct drm_connector *),
+				GFP_KERNEL);
+
+		if (!helper->crtc_info[i].mode_set.connectors) {
+			ret = -ENOMEM;
+			goto out_free;
+		}
+		helper->crtc_info[i].mode_set.num_connectors = 0;
+	}
+
+	i = 0;
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		helper->crtc_info[i].crtc_id = crtc->base.id;
+		helper->crtc_info[i].mode_set.crtc = crtc;
+		i++;
+	}
+	helper->conn_limit = max_conn_count;
+	return 0;
+out_free:
+	drm_fb_helper_crtc_free(helper);
+	return -ENOMEM;
+}
+EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
+
+int drm_fb_helper_setcolreg(unsigned regno,
+			    unsigned red,
+			    unsigned green,
+			    unsigned blue,
+			    unsigned transp,
+			    struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_device *dev = fb_helper->dev;
+	struct drm_crtc *crtc;
+	int i;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		struct drm_framebuffer *fb = fb_helper->fb;
+
+		for (i = 0; i < fb_helper->crtc_count; i++) {
+			if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
+				break;
+		}
+		if (i == fb_helper->crtc_count)
+			continue;
+
+		if (regno > 255)
+			return 1;
+
+		if (fb->depth == 8) {
+			fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
+			return 0;
+		}
+
+		if (regno < 16) {
+			switch (fb->depth) {
+			case 15:
+				fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
+					((green & 0xf800) >>  6) |
+					((blue & 0xf800) >> 11);
+				break;
+			case 16:
+				fb->pseudo_palette[regno] = (red & 0xf800) |
+					((green & 0xfc00) >>  5) |
+					((blue  & 0xf800) >> 11);
+				break;
+			case 24:
+			case 32:
+				fb->pseudo_palette[regno] =
+					(((red >> 8) & 0xff) << info->var.red.offset) |
+					(((green >> 8) & 0xff) << info->var.green.offset) |
+					(((blue >> 8) & 0xff) << info->var.blue.offset);
+				break;
+			}
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_setcolreg);
+
+int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
+			    struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_framebuffer *fb = fb_helper->fb;
+	int depth;
+
+	if (var->pixclock == -1 || !var->pixclock)
+		return -EINVAL;
+
+	/* Need to resize the fb object !!! */
+	if (var->xres > fb->width || var->yres > fb->height) {
+		DRM_ERROR("Requested width/height is greater than current fb "
+			   "object %dx%d > %dx%d\n", var->xres, var->yres,
+			   fb->width, fb->height);
+		DRM_ERROR("Need resizing code.\n");
+		return -EINVAL;
+	}
+
+	switch (var->bits_per_pixel) {
+	case 16:
+		depth = (var->green.length == 6) ? 16 : 15;
+		break;
+	case 32:
+		depth = (var->transp.length > 0) ? 32 : 24;
+		break;
+	default:
+		depth = var->bits_per_pixel;
+		break;
+	}
+
+	switch (depth) {
+	case 8:
+		var->red.offset = 0;
+		var->green.offset = 0;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		break;
+	case 15:
+		var->red.offset = 10;
+		var->green.offset = 5;
+		var->blue.offset = 0;
+		var->red.length = 5;
+		var->green.length = 5;
+		var->blue.length = 5;
+		var->transp.length = 1;
+		var->transp.offset = 15;
+		break;
+	case 16:
+		var->red.offset = 11;
+		var->green.offset = 5;
+		var->blue.offset = 0;
+		var->red.length = 5;
+		var->green.length = 6;
+		var->blue.length = 5;
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		break;
+	case 24:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->transp.length = 0;
+		var->transp.offset = 0;
+		break;
+	case 32:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->transp.length = 8;
+		var->transp.offset = 24;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_check_var);
+
+/* this will let fbcon do the mode init */
+int drm_fb_helper_set_par(struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_device *dev = fb_helper->dev;
+	struct fb_var_screeninfo *var = &info->var;
+	struct drm_crtc *crtc;
+	int ret;
+	int i;
+
+	if (var->pixclock != -1) {
+		DRM_ERROR("PIXEL CLCOK SET\n");
+		return -EINVAL;
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+
+		for (i = 0; i < fb_helper->crtc_count; i++) {
+			if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
+				break;
+		}
+		if (i == fb_helper->crtc_count)
+			continue;
+
+		if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) {
+			mutex_lock(&dev->mode_config.mutex);
+			ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set);
+			mutex_unlock(&dev->mode_config.mutex);
+			if (ret)
+				return ret;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_set_par);
+
+int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
+			      struct fb_info *info)
+{
+	struct drm_fb_helper *fb_helper = info->par;
+	struct drm_device *dev = fb_helper->dev;
+	struct drm_mode_set *modeset;
+	struct drm_crtc *crtc;
+	int ret = 0;
+	int i;
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		for (i = 0; i < fb_helper->crtc_count; i++) {
+			if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
+				break;
+		}
+
+		if (i == fb_helper->crtc_count)
+			continue;
+
+		modeset = &fb_helper->crtc_info[i].mode_set;
+
+		modeset->x = var->xoffset;
+		modeset->y = var->yoffset;
+
+		if (modeset->num_connectors) {
+			mutex_lock(&dev->mode_config.mutex);
+			ret = crtc->funcs->set_config(modeset);
+			mutex_unlock(&dev->mode_config.mutex);
+			if (!ret) {
+				info->var.xoffset = var->xoffset;
+				info->var.yoffset = var->yoffset;
+			}
+		}
+	}
+	return ret;
+}
+EXPORT_SYMBOL(drm_fb_helper_pan_display);
+
+int drm_fb_helper_single_fb_probe(struct drm_device *dev,
+				  int (*fb_create)(struct drm_device *dev,
+						   uint32_t fb_width,
+						   uint32_t fb_height,
+						   uint32_t surface_width,
+						   uint32_t surface_height,
+						   struct drm_framebuffer **fb_ptr))
+{
+	struct drm_crtc *crtc;
+	struct drm_connector *connector;
+	unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
+	unsigned int surface_width = 0, surface_height = 0;
+	int new_fb = 0;
+	int crtc_count = 0;
+	int ret, i, conn_count = 0;
+	struct fb_info *info;
+	struct drm_framebuffer *fb;
+	struct drm_mode_set *modeset = NULL;
+	struct drm_fb_helper *fb_helper;
+
+	/* first up get a count of crtcs now in use and new min/maxes width/heights */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (drm_helper_crtc_in_use(crtc)) {
+			if (crtc->desired_mode) {
+				if (crtc->desired_mode->hdisplay < fb_width)
+					fb_width = crtc->desired_mode->hdisplay;
+
+				if (crtc->desired_mode->vdisplay < fb_height)
+					fb_height = crtc->desired_mode->vdisplay;
+
+				if (crtc->desired_mode->hdisplay > surface_width)
+					surface_width = crtc->desired_mode->hdisplay;
+
+				if (crtc->desired_mode->vdisplay > surface_height)
+					surface_height = crtc->desired_mode->vdisplay;
+			}
+			crtc_count++;
+		}
+	}
+
+	if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
+		/* hmm everyone went away - assume VGA cable just fell out
+		   and will come back later. */
+		return 0;
+	}
+
+	/* do we have an fb already? */
+	if (list_empty(&dev->mode_config.fb_kernel_list)) {
+		ret = (*fb_create)(dev, fb_width, fb_height, surface_width,
+				   surface_height, &fb);
+		if (ret)
+			return -EINVAL;
+		new_fb = 1;
+	} else {
+		fb = list_first_entry(&dev->mode_config.fb_kernel_list,
+				      struct drm_framebuffer, filp_head);
+
+		/* if someone hotplugs something bigger than we have already allocated, we are pwned.
+		   As really we can't resize an fbdev that is in the wild currently due to fbdev
+		   not really being designed for the lower layers moving stuff around under it.
+		   - so in the grand style of things - punt. */
+		if ((fb->width < surface_width) ||
+		    (fb->height < surface_height)) {
+			DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
+			return -EINVAL;
+		}
+	}
+
+	info = fb->fbdev;
+	fb_helper = info->par;
+
+	crtc_count = 0;
+	/* okay we need to setup new connector sets in the crtcs */
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		modeset = &fb_helper->crtc_info[crtc_count].mode_set;
+		modeset->fb = fb;
+		conn_count = 0;
+		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+			if (connector->encoder)
+				if (connector->encoder->crtc == modeset->crtc) {
+					modeset->connectors[conn_count] = connector;
+					conn_count++;
+					if (conn_count > fb_helper->conn_limit)
+						BUG();
+				}
+		}
+
+		for (i = conn_count; i < fb_helper->conn_limit; i++)
+			modeset->connectors[i] = NULL;
+
+		modeset->crtc = crtc;
+		crtc_count++;
+
+		modeset->num_connectors = conn_count;
+		if (modeset->crtc->desired_mode) {
+			if (modeset->mode)
+				drm_mode_destroy(dev, modeset->mode);
+			modeset->mode = drm_mode_duplicate(dev,
+							   modeset->crtc->desired_mode);
+		}
+	}
+	fb_helper->crtc_count = crtc_count;
+	fb_helper->fb = fb;
+
+	if (new_fb) {
+		info->var.pixclock = -1;
+		if (register_framebuffer(info) < 0)
+			return -EINVAL;
+	} else {
+		drm_fb_helper_set_par(info);
+	}
+	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+	       info->fix.id);
+
+	/* Switch back to kernel console on panic */
+	/* multi card linked list maybe */
+	if (list_empty(&kernel_fb_helper_list)) {
+		printk(KERN_INFO "registered panic notifier\n");
+		atomic_notifier_chain_register(&panic_notifier_list,
+					       &paniced);
+		register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
+	}
+	list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
+	return 0;
+}
+EXPORT_SYMBOL(drm_fb_helper_single_fb_probe);
+
+void drm_fb_helper_free(struct drm_fb_helper *helper)
+{
+	list_del(&helper->kernel_fb_list);
+	if (list_empty(&kernel_fb_helper_list)) {
+		printk(KERN_INFO "unregistered panic notifier\n");
+		atomic_notifier_chain_unregister(&panic_notifier_list,
+						 &paniced);
+		unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op);
+	}
+	drm_fb_helper_crtc_free(helper);
+}
+EXPORT_SYMBOL(drm_fb_helper_free);
+
+void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch)
+{
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.visual = FB_VISUAL_TRUECOLOR;
+	info->fix.type_aux = 0;
+	info->fix.xpanstep = 1; /* doing it in hw */
+	info->fix.ypanstep = 1; /* doing it in hw */
+	info->fix.ywrapstep = 0;
+	info->fix.accel = FB_ACCEL_NONE;
+	info->fix.type_aux = 0;
+
+	info->fix.line_length = pitch;
+	return;
+}
+EXPORT_SYMBOL(drm_fb_helper_fill_fix);
+
+void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
+			    uint32_t fb_width, uint32_t fb_height)
+{
+	info->pseudo_palette = fb->pseudo_palette;
+	info->var.xres_virtual = fb->width;
+	info->var.yres_virtual = fb->height;
+	info->var.bits_per_pixel = fb->bits_per_pixel;
+	info->var.xoffset = 0;
+	info->var.yoffset = 0;
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->var.height = -1;
+	info->var.width = -1;
+
+	switch (fb->depth) {
+	case 8:
+		info->var.red.offset = 0;
+		info->var.green.offset = 0;
+		info->var.blue.offset = 0;
+		info->var.red.length = 8; /* 8bit DAC */
+		info->var.green.length = 8;
+		info->var.blue.length = 8;
+		info->var.transp.offset = 0;
+		info->var.transp.length = 0;
+		break;
+	case 15:
+		info->var.red.offset = 10;
+		info->var.green.offset = 5;
+		info->var.blue.offset = 0;
+		info->var.red.length = 5;
+		info->var.green.length = 5;
+		info->var.blue.length = 5;
+		info->var.transp.offset = 15;
+		info->var.transp.length = 1;
+		break;
+	case 16:
+		info->var.red.offset = 11;
+		info->var.green.offset = 5;
+		info->var.blue.offset = 0;
+		info->var.red.length = 5;
+		info->var.green.length = 6;
+		info->var.blue.length = 5;
+		info->var.transp.offset = 0;
+		break;
+	case 24:
+		info->var.red.offset = 16;
+		info->var.green.offset = 8;
+		info->var.blue.offset = 0;
+		info->var.red.length = 8;
+		info->var.green.length = 8;
+		info->var.blue.length = 8;
+		info->var.transp.offset = 0;
+		info->var.transp.length = 0;
+		break;
+	case 32:
+		info->var.red.offset = 16;
+		info->var.green.offset = 8;
+		info->var.blue.offset = 0;
+		info->var.red.length = 8;
+		info->var.green.length = 8;
+		info->var.blue.length = 8;
+		info->var.transp.offset = 24;
+		info->var.transp.length = 8;
+		break;
+	default:
+		break;
+	}
+
+	info->var.xres = fb_width;
+	info->var.yres = fb_height;
+}
+EXPORT_SYMBOL(drm_fb_helper_fill_var);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index ffe8f43..230c9ff 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -164,7 +164,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc);
  * Removes the mapping from handle to filp for this object.
  */
 static int
-drm_gem_handle_delete(struct drm_file *filp, int handle)
+drm_gem_handle_delete(struct drm_file *filp, u32 handle)
 {
 	struct drm_device *dev;
 	struct drm_gem_object *obj;
@@ -207,7 +207,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle)
 int
 drm_gem_handle_create(struct drm_file *file_priv,
 		       struct drm_gem_object *obj,
-		       int *handlep)
+		       u32 *handlep)
 {
 	int	ret;
 
@@ -221,7 +221,7 @@ again:
 
 	/* do the allocation under our spinlock */
 	spin_lock(&file_priv->table_lock);
-	ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
+	ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep);
 	spin_unlock(&file_priv->table_lock);
 	if (ret == -EAGAIN)
 		goto again;
@@ -237,7 +237,7 @@ EXPORT_SYMBOL(drm_gem_handle_create);
 /** Returns a reference to the object named by the handle. */
 struct drm_gem_object *
 drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
-		      int handle)
+		      u32 handle)
 {
 	struct drm_gem_object *obj;
 
@@ -344,7 +344,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
 	struct drm_gem_open *args = data;
 	struct drm_gem_object *obj;
 	int ret;
-	int handle;
+	u32 handle;
 
 	if (!(dev->driver->driver_features & DRIVER_GEM))
 		return -ENODEV;
@@ -539,7 +539,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 	vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
 	vma->vm_ops = obj->dev->driver->gem_vm_ops;
 	vma->vm_private_data = map->handle;
-	/* FIXME: use pgprot_writecombine when available */
 	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 
 	/* Take a ref for this mapping of the object, so that the fault
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index f85aaf2..0a6f0b3 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -37,6 +37,7 @@
 
 #include <linux/interrupt.h>	/* For task queue support */
 
+#include <linux/vgaarb.h>
 /**
  * Get interrupt from bus id.
  *
@@ -171,6 +172,26 @@ err:
 }
 EXPORT_SYMBOL(drm_vblank_init);
 
+static void drm_irq_vgaarb_nokms(void *cookie, bool state)
+{
+	struct drm_device *dev = cookie;
+
+	if (dev->driver->vgaarb_irq) {
+		dev->driver->vgaarb_irq(dev, state);
+		return;
+	}
+
+	if (!dev->irq_enabled)
+		return;
+
+	if (state)
+		dev->driver->irq_uninstall(dev);
+	else {
+		dev->driver->irq_preinstall(dev);
+		dev->driver->irq_postinstall(dev);
+	}
+}
+
 /**
  * Install IRQ handler.
  *
@@ -231,6 +252,9 @@ int drm_irq_install(struct drm_device *dev)
 		return ret;
 	}
 
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
+
 	/* After installing handler */
 	ret = dev->driver->irq_postinstall(dev);
 	if (ret < 0) {
@@ -279,6 +303,9 @@ int drm_irq_uninstall(struct drm_device * dev)
 
 	DRM_DEBUG("irq=%d\n", dev->pdev->irq);
 
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		vga_client_register(dev->pdev, NULL, NULL, NULL);
+
 	dev->driver->irq_uninstall(dev);
 
 	free_irq(dev->pdev->irq, dev);
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 3e47869..c861d80 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -44,6 +44,7 @@
 #include "drmP.h"
 #include "drm_mm.h"
 #include <linux/slab.h>
+#include <linux/seq_file.h>
 
 #define MM_UNUSED_TARGET 4
 
@@ -370,3 +371,23 @@ void drm_mm_takedown(struct drm_mm * mm)
 	BUG_ON(mm->num_unused != 0);
 }
 EXPORT_SYMBOL(drm_mm_takedown);
+
+#if defined(CONFIG_DEBUG_FS)
+int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
+{
+	struct drm_mm_node *entry;
+	int total_used = 0, total_free = 0, total = 0;
+
+	list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
+		seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used");
+		total += entry->size;
+		if (entry->free)
+			total_free += entry->size;
+		else
+			total_used += entry->size;
+	}
+	seq_printf(m, "total: %d, used %d free %d\n", total, total_free, total_used);
+	return 0;
+}
+EXPORT_SYMBOL(drm_mm_dump_table);
+#endif
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 7914097..49404ce 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -8,6 +8,8 @@
  * Copyright Â© 2007 Dave Airlie
  * Copyright Â© 2007-2008 Intel Corporation
  *   Jesse Barnes <jesse.barnes@intel.com>
+ * Copyright 2005-2006 Luc Verhaegen
+ * Copyright (c) 2001, Andy Ritger  aritger@nvidia.com
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -38,7 +40,6 @@
 #include "drm.h"
 #include "drm_crtc.h"
 
-#define DRM_MODESET_DEBUG	"drm_mode"
 /**
  * drm_mode_debug_printmodeline - debug print a mode
  * @dev: DRM device
@@ -51,8 +52,8 @@
  */
 void drm_mode_debug_printmodeline(struct drm_display_mode *mode)
 {
-	DRM_DEBUG_MODE(DRM_MODESET_DEBUG,
-		"Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
+	DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d "
+			"0x%x 0x%x\n",
 		mode->base.id, mode->name, mode->vrefresh, mode->clock,
 		mode->hdisplay, mode->hsync_start,
 		mode->hsync_end, mode->htotal,
@@ -62,6 +63,420 @@ void drm_mode_debug_printmodeline(struct drm_display_mode *mode)
 EXPORT_SYMBOL(drm_mode_debug_printmodeline);
 
 /**
+ * drm_cvt_mode -create a modeline based on CVT algorithm
+ * @dev: DRM device
+ * @hdisplay: hdisplay size
+ * @vdisplay: vdisplay size
+ * @vrefresh  : vrefresh rate
+ * @reduced : Whether the GTF calculation is simplified
+ * @interlaced:Whether the interlace is supported
+ *
+ * LOCKING:
+ * none.
+ *
+ * return the modeline based on CVT algorithm
+ *
+ * This function is called to generate the modeline based on CVT algorithm
+ * according to the hdisplay, vdisplay, vrefresh.
+ * It is based from the VESA(TM) Coordinated Video Timing Generator by
+ * Graham Loveridge April 9, 2003 available at
+ * http://www.vesa.org/public/CVT/CVTd6r1.xls
+ *
+ * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c.
+ * What I have done is to translate it by using integer calculation.
+ */
+#define HV_FACTOR			1000
+struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
+				      int vdisplay, int vrefresh,
+				      bool reduced, bool interlaced)
+{
+	/* 1) top/bottom margin size (% of height) - default: 1.8, */
+#define	CVT_MARGIN_PERCENTAGE		18
+	/* 2) character cell horizontal granularity (pixels) - default 8 */
+#define	CVT_H_GRANULARITY		8
+	/* 3) Minimum vertical porch (lines) - default 3 */
+#define	CVT_MIN_V_PORCH			3
+	/* 4) Minimum number of vertical back porch lines - default 6 */
+#define	CVT_MIN_V_BPORCH		6
+	/* Pixel Clock step (kHz) */
+#define CVT_CLOCK_STEP			250
+	struct drm_display_mode *drm_mode;
+	bool margins = false;
+	unsigned int vfieldrate, hperiod;
+	int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync;
+	int interlace;
+
+	/* allocate the drm_display_mode structure. If failure, we will
+	 * return directly
+	 */
+	drm_mode = drm_mode_create(dev);
+	if (!drm_mode)
+		return NULL;
+
+	/* the CVT default refresh rate is 60Hz */
+	if (!vrefresh)
+		vrefresh = 60;
+
+	/* the required field fresh rate */
+	if (interlaced)
+		vfieldrate = vrefresh * 2;
+	else
+		vfieldrate = vrefresh;
+
+	/* horizontal pixels */
+	hdisplay_rnd = hdisplay - (hdisplay % CVT_H_GRANULARITY);
+
+	/* determine the left&right borders */
+	hmargin = 0;
+	if (margins) {
+		hmargin = hdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000;
+		hmargin -= hmargin % CVT_H_GRANULARITY;
+	}
+	/* find the total active pixels */
+	drm_mode->hdisplay = hdisplay_rnd + 2 * hmargin;
+
+	/* find the number of lines per field */
+	if (interlaced)
+		vdisplay_rnd = vdisplay / 2;
+	else
+		vdisplay_rnd = vdisplay;
+
+	/* find the top & bottom borders */
+	vmargin = 0;
+	if (margins)
+		vmargin = vdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000;
+
+	drm_mode->vdisplay = vdisplay + 2 * vmargin;
+
+	/* Interlaced */
+	if (interlaced)
+		interlace = 1;
+	else
+		interlace = 0;
+
+	/* Determine VSync Width from aspect ratio */
+	if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay))
+		vsync = 4;
+	else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay))
+		vsync = 5;
+	else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay))
+		vsync = 6;
+	else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay))
+		vsync = 7;
+	else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay))
+		vsync = 7;
+	else /* custom */
+		vsync = 10;
+
+	if (!reduced) {
+		/* simplify the GTF calculation */
+		/* 4) Minimum time of vertical sync + back porch interval (Âµs)
+		 * default 550.0
+		 */
+		int tmp1, tmp2;
+#define CVT_MIN_VSYNC_BP	550
+		/* 3) Nominal HSync width (% of line period) - default 8 */
+#define CVT_HSYNC_PERCENTAGE	8
+		unsigned int hblank_percentage;
+		int vsyncandback_porch, vback_porch, hblank;
+
+		/* estimated the horizontal period */
+		tmp1 = HV_FACTOR * 1000000  -
+				CVT_MIN_VSYNC_BP * HV_FACTOR * vfieldrate;
+		tmp2 = (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH) * 2 +
+				interlace;
+		hperiod = tmp1 * 2 / (tmp2 * vfieldrate);
+
+		tmp1 = CVT_MIN_VSYNC_BP * HV_FACTOR / hperiod + 1;
+		/* 9. Find number of lines in sync + backporch */
+		if (tmp1 < (vsync + CVT_MIN_V_PORCH))
+			vsyncandback_porch = vsync + CVT_MIN_V_PORCH;
+		else
+			vsyncandback_porch = tmp1;
+		/* 10. Find number of lines in back porch */
+		vback_porch = vsyncandback_porch - vsync;
+		drm_mode->vtotal = vdisplay_rnd + 2 * vmargin +
+				vsyncandback_porch + CVT_MIN_V_PORCH;
+		/* 5) Definition of Horizontal blanking time limitation */
+		/* Gradient (%/kHz) - default 600 */
+#define CVT_M_FACTOR	600
+		/* Offset (%) - default 40 */
+#define CVT_C_FACTOR	40
+		/* Blanking time scaling factor - default 128 */
+#define CVT_K_FACTOR	128
+		/* Scaling factor weighting - default 20 */
+#define CVT_J_FACTOR	20
+#define CVT_M_PRIME	(CVT_M_FACTOR * CVT_K_FACTOR / 256)
+#define CVT_C_PRIME	((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
+			 CVT_J_FACTOR)
+		/* 12. Find ideal blanking duty cycle from formula */
+		hblank_percentage = CVT_C_PRIME * HV_FACTOR - CVT_M_PRIME *
+					hperiod / 1000;
+		/* 13. Blanking time */
+		if (hblank_percentage < 20 * HV_FACTOR)
+			hblank_percentage = 20 * HV_FACTOR;
+		hblank = drm_mode->hdisplay * hblank_percentage /
+			 (100 * HV_FACTOR - hblank_percentage);
+		hblank -= hblank % (2 * CVT_H_GRANULARITY);
+		/* 14. find the total pixes per line */
+		drm_mode->htotal = drm_mode->hdisplay + hblank;
+		drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2;
+		drm_mode->hsync_start = drm_mode->hsync_end -
+			(drm_mode->htotal * CVT_HSYNC_PERCENTAGE) / 100;
+		drm_mode->hsync_start += CVT_H_GRANULARITY -
+			drm_mode->hsync_start % CVT_H_GRANULARITY;
+		/* fill the Vsync values */
+		drm_mode->vsync_start = drm_mode->vdisplay + CVT_MIN_V_PORCH;
+		drm_mode->vsync_end = drm_mode->vsync_start + vsync;
+	} else {
+		/* Reduced blanking */
+		/* Minimum vertical blanking interval time (Âµs)- default 460 */
+#define CVT_RB_MIN_VBLANK	460
+		/* Fixed number of clocks for horizontal sync */
+#define CVT_RB_H_SYNC		32
+		/* Fixed number of clocks for horizontal blanking */
+#define CVT_RB_H_BLANK		160
+		/* Fixed number of lines for vertical front porch - default 3*/
+#define CVT_RB_VFPORCH		3
+		int vbilines;
+		int tmp1, tmp2;
+		/* 8. Estimate Horizontal period. */
+		tmp1 = HV_FACTOR * 1000000 -
+			CVT_RB_MIN_VBLANK * HV_FACTOR * vfieldrate;
+		tmp2 = vdisplay_rnd + 2 * vmargin;
+		hperiod = tmp1 / (tmp2 * vfieldrate);
+		/* 9. Find number of lines in vertical blanking */
+		vbilines = CVT_RB_MIN_VBLANK * HV_FACTOR / hperiod + 1;
+		/* 10. Check if vertical blanking is sufficient */
+		if (vbilines < (CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH))
+			vbilines = CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH;
+		/* 11. Find total number of lines in vertical field */
+		drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines;
+		/* 12. Find total number of pixels in a line */
+		drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK;
+		/* Fill in HSync values */
+		drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2;
+		drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC;
+	}
+	/* 15/13. Find pixel clock frequency (kHz for xf86) */
+	drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod;
+	drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP;
+	/* 18/16. Find actual vertical frame frequency */
+	/* ignore - just set the mode flag for interlaced */
+	if (interlaced)
+		drm_mode->vtotal *= 2;
+	/* Fill the mode line name */
+	drm_mode_set_name(drm_mode);
+	if (reduced)
+		drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC |
+					DRM_MODE_FLAG_NVSYNC);
+	else
+		drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC |
+					DRM_MODE_FLAG_NHSYNC);
+	if (interlaced)
+		drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
+
+    return drm_mode;
+}
+EXPORT_SYMBOL(drm_cvt_mode);
+
+/**
+ * drm_gtf_mode - create the modeline based on GTF algorithm
+ *
+ * @dev		:drm device
+ * @hdisplay	:hdisplay size
+ * @vdisplay	:vdisplay size
+ * @vrefresh	:vrefresh rate.
+ * @interlaced	:whether the interlace is supported
+ * @margins	:whether the margin is supported
+ *
+ * LOCKING.
+ * none.
+ *
+ * return the modeline based on GTF algorithm
+ *
+ * This function is to create the modeline based on the GTF algorithm.
+ * Generalized Timing Formula is derived from:
+ *	GTF Spreadsheet by Andy Morrish (1/5/97)
+ *	available at http://www.vesa.org
+ *
+ * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c.
+ * What I have done is to translate it by using integer calculation.
+ * I also refer to the function of fb_get_mode in the file of
+ * drivers/video/fbmon.c
+ */
+struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay,
+				      int vdisplay, int vrefresh,
+				      bool interlaced, int margins)
+{
+	/* 1) top/bottom margin size (% of height) - default: 1.8, */
+#define	GTF_MARGIN_PERCENTAGE		18
+	/* 2) character cell horizontal granularity (pixels) - default 8 */
+#define	GTF_CELL_GRAN			8
+	/* 3) Minimum vertical porch (lines) - default 3 */
+#define	GTF_MIN_V_PORCH			1
+	/* width of vsync in lines */
+#define V_SYNC_RQD			3
+	/* width of hsync as % of total line */
+#define H_SYNC_PERCENT			8
+	/* min time of vsync + back porch (microsec) */
+#define MIN_VSYNC_PLUS_BP		550
+	/* blanking formula gradient */
+#define GTF_M				600
+	/* blanking formula offset */
+#define GTF_C				40
+	/* blanking formula scaling factor */
+#define GTF_K				128
+	/* blanking formula scaling factor */
+#define GTF_J				20
+	/* C' and M' are part of the Blanking Duty Cycle computation */
+#define GTF_C_PRIME		(((GTF_C - GTF_J) * GTF_K / 256) + GTF_J)
+#define GTF_M_PRIME		(GTF_K * GTF_M / 256)
+	struct drm_display_mode *drm_mode;
+	unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd;
+	int top_margin, bottom_margin;
+	int interlace;
+	unsigned int hfreq_est;
+	int vsync_plus_bp, vback_porch;
+	unsigned int vtotal_lines, vfieldrate_est, hperiod;
+	unsigned int vfield_rate, vframe_rate;
+	int left_margin, right_margin;
+	unsigned int total_active_pixels, ideal_duty_cycle;
+	unsigned int hblank, total_pixels, pixel_freq;
+	int hsync, hfront_porch, vodd_front_porch_lines;
+	unsigned int tmp1, tmp2;
+
+	drm_mode = drm_mode_create(dev);
+	if (!drm_mode)
+		return NULL;
+
+	/* 1. In order to give correct results, the number of horizontal
+	 * pixels requested is first processed to ensure that it is divisible
+	 * by the character size, by rounding it to the nearest character
+	 * cell boundary:
+	 */
+	hdisplay_rnd = (hdisplay + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN;
+	hdisplay_rnd = hdisplay_rnd * GTF_CELL_GRAN;
+
+	/* 2. If interlace is requested, the number of vertical lines assumed
+	 * by the calculation must be halved, as the computation calculates
+	 * the number of vertical lines per field.
+	 */
+	if (interlaced)
+		vdisplay_rnd = vdisplay / 2;
+	else
+		vdisplay_rnd = vdisplay;
+
+	/* 3. Find the frame rate required: */
+	if (interlaced)
+		vfieldrate_rqd = vrefresh * 2;
+	else
+		vfieldrate_rqd = vrefresh;
+
+	/* 4. Find number of lines in Top margin: */
+	top_margin = 0;
+	if (margins)
+		top_margin = (vdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) /
+				1000;
+	/* 5. Find number of lines in bottom margin: */
+	bottom_margin = top_margin;
+
+	/* 6. If interlace is required, then set variable interlace: */
+	if (interlaced)
+		interlace = 1;
+	else
+		interlace = 0;
+
+	/* 7. Estimate the Horizontal frequency */
+	{
+		tmp1 = (1000000  - MIN_VSYNC_PLUS_BP * vfieldrate_rqd) / 500;
+		tmp2 = (vdisplay_rnd + 2 * top_margin + GTF_MIN_V_PORCH) *
+				2 + interlace;
+		hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1;
+	}
+
+	/* 8. Find the number of lines in V sync + back porch */
+	/* [V SYNC+BP] = RINT(([MIN VSYNC+BP] * hfreq_est / 1000000)) */
+	vsync_plus_bp = MIN_VSYNC_PLUS_BP * hfreq_est / 1000;
+	vsync_plus_bp = (vsync_plus_bp + 500) / 1000;
+	/*  9. Find the number of lines in V back porch alone: */
+	vback_porch = vsync_plus_bp - V_SYNC_RQD;
+	/*  10. Find the total number of lines in Vertical field period: */
+	vtotal_lines = vdisplay_rnd + top_margin + bottom_margin +
+			vsync_plus_bp + GTF_MIN_V_PORCH;
+	/*  11. Estimate the Vertical field frequency: */
+	vfieldrate_est = hfreq_est / vtotal_lines;
+	/*  12. Find the actual horizontal period: */
+	hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines);
+
+	/*  13. Find the actual Vertical field frequency: */
+	vfield_rate = hfreq_est / vtotal_lines;
+	/*  14. Find the Vertical frame frequency: */
+	if (interlaced)
+		vframe_rate = vfield_rate / 2;
+	else
+		vframe_rate = vfield_rate;
+	/*  15. Find number of pixels in left margin: */
+	if (margins)
+		left_margin = (hdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) /
+				1000;
+	else
+		left_margin = 0;
+
+	/* 16.Find number of pixels in right margin: */
+	right_margin = left_margin;
+	/* 17.Find total number of active pixels in image and left and right */
+	total_active_pixels = hdisplay_rnd + left_margin + right_margin;
+	/* 18.Find the ideal blanking duty cycle from blanking duty cycle */
+	ideal_duty_cycle = GTF_C_PRIME * 1000 -
+				(GTF_M_PRIME * 1000000 / hfreq_est);
+	/* 19.Find the number of pixels in the blanking time to the nearest
+	 * double character cell: */
+	hblank = total_active_pixels * ideal_duty_cycle /
+			(100000 - ideal_duty_cycle);
+	hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN);
+	hblank = hblank * 2 * GTF_CELL_GRAN;
+	/* 20.Find total number of pixels: */
+	total_pixels = total_active_pixels + hblank;
+	/* 21.Find pixel clock frequency: */
+	pixel_freq = total_pixels * hfreq_est / 1000;
+	/* Stage 1 computations are now complete; I should really pass
+	 * the results to another function and do the Stage 2 computations,
+	 * but I only need a few more values so I'll just append the
+	 * computations here for now */
+	/* 17. Find the number of pixels in the horizontal sync period: */
+	hsync = H_SYNC_PERCENT * total_pixels / 100;
+	hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN;
+	hsync = hsync * GTF_CELL_GRAN;
+	/* 18. Find the number of pixels in horizontal front porch period */
+	hfront_porch = hblank / 2 - hsync;
+	/*  36. Find the number of lines in the odd front porch period: */
+	vodd_front_porch_lines = GTF_MIN_V_PORCH ;
+
+	/* finally, pack the results in the mode struct */
+	drm_mode->hdisplay = hdisplay_rnd;
+	drm_mode->hsync_start = hdisplay_rnd + hfront_porch;
+	drm_mode->hsync_end = drm_mode->hsync_start + hsync;
+	drm_mode->htotal = total_pixels;
+	drm_mode->vdisplay = vdisplay_rnd;
+	drm_mode->vsync_start = vdisplay_rnd + vodd_front_porch_lines;
+	drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD;
+	drm_mode->vtotal = vtotal_lines;
+
+	drm_mode->clock = pixel_freq;
+
+	drm_mode_set_name(drm_mode);
+	drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC;
+
+	if (interlaced) {
+		drm_mode->vtotal *= 2;
+		drm_mode->flags |= DRM_MODE_FLAG_INTERLACE;
+	}
+
+	return drm_mode;
+}
+EXPORT_SYMBOL(drm_gtf_mode);
+/**
  * drm_mode_set_name - set the name on a mode
  * @mode: name will be set in this mode
  *
@@ -151,7 +566,9 @@ EXPORT_SYMBOL(drm_mode_height);
  * FIXME: why is this needed?  shouldn't vrefresh be set already?
  *
  * RETURNS:
- * Vertical refresh rate of @mode x 1000. For precision reasons.
+ * Vertical refresh rate. It will be the result of actual value plus 0.5.
+ * If it is 70.288, it will return 70Hz.
+ * If it is 59.6, it will return 60Hz.
  */
 int drm_mode_vrefresh(struct drm_display_mode *mode)
 {
@@ -161,14 +578,13 @@ int drm_mode_vrefresh(struct drm_display_mode *mode)
 	if (mode->vrefresh > 0)
 		refresh = mode->vrefresh;
 	else if (mode->htotal > 0 && mode->vtotal > 0) {
+		int vtotal;
+		vtotal = mode->vtotal;
 		/* work out vrefresh the value will be x1000 */
 		calc_val = (mode->clock * 1000);
-
 		calc_val /= mode->htotal;
-		calc_val *= 1000;
-		calc_val /= mode->vtotal;
+		refresh = (calc_val + vtotal / 2) / vtotal;
 
-		refresh = calc_val;
 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 			refresh *= 2;
 		if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -403,8 +819,7 @@ void drm_mode_prune_invalid(struct drm_device *dev,
 			list_del(&mode->head);
 			if (verbose) {
 				drm_mode_debug_printmodeline(mode);
-				DRM_DEBUG_MODE(DRM_MODESET_DEBUG,
-					"Not using %s mode %d\n",
+				DRM_DEBUG_KMS("Not using %s mode %d\n",
 					mode->name, mode->status);
 			}
 			drm_mode_destroy(dev, mode);
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index bbd4b3d..d379c4f 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -106,20 +106,25 @@ int drm_proc_create_files(struct drm_info_list *files, int count,
 			continue;
 
 		tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL);
-		ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root);
+		if (tmp == NULL) {
+			ret = -1;
+			goto fail;
+		}
+		tmp->minor = minor;
+		tmp->info_ent = &files[i];
+		list_add(&tmp->list, &minor->proc_nodes.list);
+
+		ent = proc_create_data(files[i].name, S_IRUGO, root,
+				       &drm_proc_fops, tmp);
 		if (!ent) {
 			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
 				  name, files[i].name);
+			list_del(&tmp->list);
 			kfree(tmp);
 			ret = -1;
 			goto fail;
 		}
 
-		ent->proc_fops = &drm_proc_fops;
-		ent->data = tmp;
-		tmp->minor = minor;
-		tmp->info_ent = &files[i];
-		list_add(&(tmp->list), &(minor->proc_nodes.list));
 	}
 	return 0;
 
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index f7a615b..7e42b7e 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/err.h>
 
+#include "drm_sysfs.h"
 #include "drm_core.h"
 #include "drmP.h"
 
@@ -76,7 +77,7 @@ static ssize_t version_show(struct class *dev, char *buf)
 		       CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
 }
 
-static char *drm_nodename(struct device *dev)
+static char *drm_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev));
 }
@@ -112,7 +113,7 @@ struct class *drm_sysfs_create(struct module *owner, char *name)
 	if (err)
 		goto err_out_class;
 
-	class->nodename = drm_nodename;
+	class->devnode = drm_devnode;
 
 	return class;
 
@@ -253,6 +254,7 @@ static ssize_t subconnector_show(struct device *device,
 		case DRM_MODE_CONNECTOR_Composite:
 		case DRM_MODE_CONNECTOR_SVIDEO:
 		case DRM_MODE_CONNECTOR_Component:
+		case DRM_MODE_CONNECTOR_TV:
 			prop = dev->mode_config.tv_subconnector_property;
 			is_tv = 1;
 			break;
@@ -293,6 +295,7 @@ static ssize_t select_subconnector_show(struct device *device,
 		case DRM_MODE_CONNECTOR_Composite:
 		case DRM_MODE_CONNECTOR_SVIDEO:
 		case DRM_MODE_CONNECTOR_Component:
+		case DRM_MODE_CONNECTOR_TV:
 			prop = dev->mode_config.tv_select_subconnector_property;
 			is_tv = 1;
 			break;
@@ -391,6 +394,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
 		case DRM_MODE_CONNECTOR_Composite:
 		case DRM_MODE_CONNECTOR_SVIDEO:
 		case DRM_MODE_CONNECTOR_Component:
+		case DRM_MODE_CONNECTOR_TV:
 			for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
 				ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
 				if (ret)
@@ -519,3 +523,27 @@ void drm_sysfs_device_remove(struct drm_minor *minor)
 {
 	device_unregister(&minor->kdev);
 }
+
+
+/**
+ * drm_class_device_register - Register a struct device in the drm class.
+ *
+ * @dev: pointer to struct device to register.
+ *
+ * @dev should have all relevant members pre-filled with the exception
+ * of the class member. In particular, the device_type member must
+ * be set.
+ */
+
+int drm_class_device_register(struct device *dev)
+{
+	dev->class = drm_class;
+	return device_register(dev);
+}
+EXPORT_SYMBOL_GPL(drm_class_device_register);
+
+void drm_class_device_unregister(struct device *dev)
+{
+	return device_unregister(dev);
+}
+EXPORT_SYMBOL_GPL(drm_class_device_unregister);
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 30d6b99..5269dfa 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -4,10 +4,10 @@
 
 ccflags-y := -Iinclude/drm
 i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
+	  i915_debugfs.o \
           i915_suspend.o \
 	  i915_gem.o \
 	  i915_gem_debug.o \
-	  i915_gem_debugfs.o \
 	  i915_gem_tiling.o \
 	  intel_display.o \
 	  intel_crt.o \
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
new file mode 100644
index 0000000..1e3bdce
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *    Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include <linux/seq_file.h>
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+#define DRM_I915_RING_DEBUG 1
+
+
+#if defined(CONFIG_DEBUG_FS)
+
+#define ACTIVE_LIST	1
+#define FLUSHING_LIST	2
+#define INACTIVE_LIST	3
+
+static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv)
+{
+	if (obj_priv->user_pin_count > 0)
+		return "P";
+	else if (obj_priv->pin_count > 0)
+		return "p";
+	else
+		return " ";
+}
+
+static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv)
+{
+    switch (obj_priv->tiling_mode) {
+    default:
+    case I915_TILING_NONE: return " ";
+    case I915_TILING_X: return "X";
+    case I915_TILING_Y: return "Y";
+    }
+}
+
+static int i915_gem_object_list_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	uintptr_t list = (uintptr_t) node->info_ent->data;
+	struct list_head *head;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj_priv;
+	spinlock_t *lock = NULL;
+
+	switch (list) {
+	case ACTIVE_LIST:
+		seq_printf(m, "Active:\n");
+		lock = &dev_priv->mm.active_list_lock;
+		head = &dev_priv->mm.active_list;
+		break;
+	case INACTIVE_LIST:
+		seq_printf(m, "Inactive:\n");
+		head = &dev_priv->mm.inactive_list;
+		break;
+	case FLUSHING_LIST:
+		seq_printf(m, "Flushing:\n");
+		head = &dev_priv->mm.flushing_list;
+		break;
+	default:
+		DRM_INFO("Ooops, unexpected list\n");
+		return 0;
+	}
+
+	if (lock)
+		spin_lock(lock);
+	list_for_each_entry(obj_priv, head, list)
+	{
+		struct drm_gem_object *obj = obj_priv->obj;
+
+		seq_printf(m, "    %p: %s %08x %08x %d",
+			   obj,
+			   get_pin_flag(obj_priv),
+			   obj->read_domains, obj->write_domain,
+			   obj_priv->last_rendering_seqno);
+
+		if (obj->name)
+			seq_printf(m, " (name: %d)", obj->name);
+		if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
+			seq_printf(m, " (fence: %d)", obj_priv->fence_reg);
+		if (obj_priv->gtt_space != NULL)
+			seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset);
+
+		seq_printf(m, "\n");
+	}
+
+	if (lock)
+	    spin_unlock(lock);
+	return 0;
+}
+
+static int i915_gem_request_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_gem_request *gem_request;
+
+	seq_printf(m, "Request:\n");
+	list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
+		seq_printf(m, "    %d @ %d\n",
+			   gem_request->seqno,
+			   (int) (jiffies - gem_request->emitted_jiffies));
+	}
+	return 0;
+}
+
+static int i915_gem_seqno_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (dev_priv->hw_status_page != NULL) {
+		seq_printf(m, "Current sequence: %d\n",
+			   i915_get_gem_seqno(dev));
+	} else {
+		seq_printf(m, "Current sequence: hws uninitialized\n");
+	}
+	seq_printf(m, "Waiter sequence:  %d\n",
+			dev_priv->mm.waiting_gem_seqno);
+	seq_printf(m, "IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
+	return 0;
+}
+
+
+static int i915_interrupt_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (!IS_IGDNG(dev)) {
+		seq_printf(m, "Interrupt enable:    %08x\n",
+			   I915_READ(IER));
+		seq_printf(m, "Interrupt identity:  %08x\n",
+			   I915_READ(IIR));
+		seq_printf(m, "Interrupt mask:      %08x\n",
+			   I915_READ(IMR));
+		seq_printf(m, "Pipe A stat:         %08x\n",
+			   I915_READ(PIPEASTAT));
+		seq_printf(m, "Pipe B stat:         %08x\n",
+			   I915_READ(PIPEBSTAT));
+	} else {
+		seq_printf(m, "North Display Interrupt enable:		%08x\n",
+			   I915_READ(DEIER));
+		seq_printf(m, "North Display Interrupt identity:	%08x\n",
+			   I915_READ(DEIIR));
+		seq_printf(m, "North Display Interrupt mask:		%08x\n",
+			   I915_READ(DEIMR));
+		seq_printf(m, "South Display Interrupt enable:		%08x\n",
+			   I915_READ(SDEIER));
+		seq_printf(m, "South Display Interrupt identity:	%08x\n",
+			   I915_READ(SDEIIR));
+		seq_printf(m, "South Display Interrupt mask:		%08x\n",
+			   I915_READ(SDEIMR));
+		seq_printf(m, "Graphics Interrupt enable:		%08x\n",
+			   I915_READ(GTIER));
+		seq_printf(m, "Graphics Interrupt identity:		%08x\n",
+			   I915_READ(GTIIR));
+		seq_printf(m, "Graphics Interrupt mask:		%08x\n",
+			   I915_READ(GTIMR));
+	}
+	seq_printf(m, "Interrupts received: %d\n",
+		   atomic_read(&dev_priv->irq_received));
+	if (dev_priv->hw_status_page != NULL) {
+		seq_printf(m, "Current sequence:    %d\n",
+			   i915_get_gem_seqno(dev));
+	} else {
+		seq_printf(m, "Current sequence:    hws uninitialized\n");
+	}
+	seq_printf(m, "Waiter sequence:     %d\n",
+		   dev_priv->mm.waiting_gem_seqno);
+	seq_printf(m, "IRQ sequence:        %d\n",
+		   dev_priv->mm.irq_gem_seqno);
+	return 0;
+}
+
+static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int i;
+
+	seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start);
+	seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
+	for (i = 0; i < dev_priv->num_fence_regs; i++) {
+		struct drm_gem_object *obj = dev_priv->fence_regs[i].obj;
+
+		if (obj == NULL) {
+			seq_printf(m, "Fenced object[%2d] = unused\n", i);
+		} else {
+			struct drm_i915_gem_object *obj_priv;
+
+			obj_priv = obj->driver_private;
+			seq_printf(m, "Fenced object[%2d] = %p: %s "
+				   "%08x %08zx %08x %s %08x %08x %d",
+				   i, obj, get_pin_flag(obj_priv),
+				   obj_priv->gtt_offset,
+				   obj->size, obj_priv->stride,
+				   get_tiling_flag(obj_priv),
+				   obj->read_domains, obj->write_domain,
+				   obj_priv->last_rendering_seqno);
+			if (obj->name)
+				seq_printf(m, " (name: %d)", obj->name);
+			seq_printf(m, "\n");
+		}
+	}
+
+	return 0;
+}
+
+static int i915_hws_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	int i;
+	volatile u32 *hws;
+
+	hws = (volatile u32 *)dev_priv->hw_status_page;
+	if (hws == NULL)
+		return 0;
+
+	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
+		seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			   i * 4,
+			   hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
+	}
+	return 0;
+}
+
+static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count)
+{
+	int page, i;
+	uint32_t *mem;
+
+	for (page = 0; page < page_count; page++) {
+		mem = kmap(pages[page]);
+		for (i = 0; i < PAGE_SIZE; i += 4)
+			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
+		kunmap(pages[page]);
+	}
+}
+
+static int i915_batchbuffer_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_gem_object *obj;
+	struct drm_i915_gem_object *obj_priv;
+	int ret;
+
+	spin_lock(&dev_priv->mm.active_list_lock);
+
+	list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
+		obj = obj_priv->obj;
+		if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
+		    ret = i915_gem_object_get_pages(obj);
+		    if (ret) {
+			    DRM_ERROR("Failed to get pages: %d\n", ret);
+			    spin_unlock(&dev_priv->mm.active_list_lock);
+			    return ret;
+		    }
+
+		    seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset);
+		    i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE);
+
+		    i915_gem_object_put_pages(obj);
+		}
+	}
+
+	spin_unlock(&dev_priv->mm.active_list_lock);
+
+	return 0;
+}
+
+static int i915_ringbuffer_data(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	u8 *virt;
+	uint32_t *ptr, off;
+
+	if (!dev_priv->ring.ring_obj) {
+		seq_printf(m, "No ringbuffer setup\n");
+		return 0;
+	}
+
+	virt = dev_priv->ring.virtual_start;
+
+	for (off = 0; off < dev_priv->ring.Size; off += 4) {
+		ptr = (uint32_t *)(virt + off);
+		seq_printf(m, "%08x :  %08x\n", off, *ptr);
+	}
+
+	return 0;
+}
+
+static int i915_ringbuffer_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	unsigned int head, tail;
+
+	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+	tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
+
+	seq_printf(m, "RingHead :  %08x\n", head);
+	seq_printf(m, "RingTail :  %08x\n", tail);
+	seq_printf(m, "RingSize :  %08lx\n", dev_priv->ring.Size);
+	seq_printf(m, "Acthd :     %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
+
+	return 0;
+}
+
+static int i915_error_state(struct seq_file *m, void *unused)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_i915_error_state *error;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->error_lock, flags);
+	if (!dev_priv->first_error) {
+		seq_printf(m, "no error state collected\n");
+		goto out;
+	}
+
+	error = dev_priv->first_error;
+
+	seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
+		   error->time.tv_usec);
+	seq_printf(m, "EIR: 0x%08x\n", error->eir);
+	seq_printf(m, "  PGTBL_ER: 0x%08x\n", error->pgtbl_er);
+	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
+	seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir);
+	seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr);
+	seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone);
+	seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd);
+	if (IS_I965G(dev)) {
+		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps);
+		seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
+	}
+
+out:
+	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
+
+	return 0;
+}
+
+static int i915_registers_info(struct seq_file *m, void *data) {
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	uint32_t reg;
+
+#define DUMP_RANGE(start, end) \
+	for (reg=start; reg < end; reg += 4) \
+	seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg));
+
+	DUMP_RANGE(0x00000, 0x00fff);   /* VGA registers */
+	DUMP_RANGE(0x02000, 0x02fff);   /* instruction, memory, interrupt control registers */
+	DUMP_RANGE(0x03000, 0x031ff);   /* FENCE and PPGTT control registers */
+	DUMP_RANGE(0x03200, 0x03fff);   /* frame buffer compression registers */
+	DUMP_RANGE(0x05000, 0x05fff);   /* I/O control registers */
+	DUMP_RANGE(0x06000, 0x06fff);   /* clock control registers */
+	DUMP_RANGE(0x07000, 0x07fff);   /* 3D internal debug registers */
+	DUMP_RANGE(0x07400, 0x088ff);   /* GPE debug registers */
+	DUMP_RANGE(0x0a000, 0x0afff);   /* display palette registers */
+	DUMP_RANGE(0x10000, 0x13fff);   /* MMIO MCHBAR */
+	DUMP_RANGE(0x30000, 0x3ffff);   /* overlay registers */
+	DUMP_RANGE(0x60000, 0x6ffff);   /* display engine pipeline registers */
+	DUMP_RANGE(0x70000, 0x72fff);   /* display and cursor registers */
+	DUMP_RANGE(0x73000, 0x73fff);   /* performance counters */
+
+	return 0;
+}
+
+
+static struct drm_info_list i915_debugfs_list[] = {
+	{"i915_regs", i915_registers_info, 0},
+	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
+	{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
+	{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
+	{"i915_gem_request", i915_gem_request_info, 0},
+	{"i915_gem_seqno", i915_gem_seqno_info, 0},
+	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
+	{"i915_gem_interrupt", i915_interrupt_info, 0},
+	{"i915_gem_hws", i915_hws_info, 0},
+	{"i915_ringbuffer_data", i915_ringbuffer_data, 0},
+	{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
+	{"i915_batchbuffers", i915_batchbuffer_info, 0},
+	{"i915_error_state", i915_error_state, 0},
+};
+#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
+
+int i915_debugfs_init(struct drm_minor *minor)
+{
+	return drm_debugfs_create_files(i915_debugfs_list,
+					I915_DEBUGFS_ENTRIES,
+					minor->debugfs_root, minor);
+}
+
+void i915_debugfs_cleanup(struct drm_minor *minor)
+{
+	drm_debugfs_remove_files(i915_debugfs_list,
+				 I915_DEBUGFS_ENTRIES, minor);
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 50d1f78..5a49a18 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -29,11 +29,11 @@
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc_helper.h"
+#include "drm_fb_helper.h"
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
-
-#define I915_DRV	"i915_drv"
+#include <linux/vgaarb.h>
 
 /* Really want an OS-independent resettable timer.  Would like to have
  * this loop run for (eg) 3 sec, but have the timer reset every time
@@ -80,6 +80,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
 	return -EBUSY;
 }
 
+/* As a ringbuffer is only allowed to wrap between instructions, fill
+ * the tail with NOOPs.
+ */
+int i915_wrap_ring(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	volatile unsigned int *virt;
+	int rem;
+
+	rem = dev_priv->ring.Size - dev_priv->ring.tail;
+	if (dev_priv->ring.space < rem) {
+		int ret = i915_wait_ring(dev, rem, __func__);
+		if (ret)
+			return ret;
+	}
+	dev_priv->ring.space -= rem;
+
+	virt = (unsigned int *)
+		(dev_priv->ring.virtual_start + dev_priv->ring.tail);
+	rem /= 4;
+	while (rem--)
+		*virt++ = MI_NOOP;
+
+	dev_priv->ring.tail = 0;
+
+	return 0;
+}
+
 /**
  * Sets up the hardware status page for devices that need a physical address
  * in the register.
@@ -101,7 +129,7 @@ static int i915_init_phys_hws(struct drm_device *dev)
 	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 
 	I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
-	DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n");
+	DRM_DEBUG_DRIVER("Enabled hardware status page\n");
 	return 0;
 }
 
@@ -187,8 +215,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
 		master_priv->sarea_priv = (drm_i915_sarea_t *)
 			((u8 *)master_priv->sarea->handle + init->sarea_priv_offset);
 	} else {
-		DRM_DEBUG_DRIVER(I915_DRV,
-				"sarea not found assuming DRI2 userspace\n");
+		DRM_DEBUG_DRIVER("sarea not found assuming DRI2 userspace\n");
 	}
 
 	if (init->ring_size != 0) {
@@ -200,7 +227,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
 		}
 
 		dev_priv->ring.Size = init->ring_size;
-		dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
 
 		dev_priv->ring.map.offset = init->ring_start;
 		dev_priv->ring.map.size = init->ring_size;
@@ -238,7 +264,7 @@ static int i915_dma_resume(struct drm_device * dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
-	DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__);
+	DRM_DEBUG_DRIVER("%s\n", __func__);
 
 	if (dev_priv->ring.map.handle == NULL) {
 		DRM_ERROR("can not ioremap virtual address for"
@@ -251,14 +277,14 @@ static int i915_dma_resume(struct drm_device * dev)
 		DRM_ERROR("Can not find hardware status page\n");
 		return -EINVAL;
 	}
-	DRM_DEBUG_DRIVER(I915_DRV, "hw status page @ %p\n",
+	DRM_DEBUG_DRIVER("hw status page @ %p\n",
 				dev_priv->hw_status_page);
 
 	if (dev_priv->status_gfx_addr != 0)
 		I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
 	else
 		I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
-	DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n");
+	DRM_DEBUG_DRIVER("Enabled hardware status page\n");
 
 	return 0;
 }
@@ -552,7 +578,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
 	if (!master_priv->sarea_priv)
 		return -EINVAL;
 
-	DRM_DEBUG_DRIVER(I915_DRV, "%s: page=%d pfCurrentPage=%d\n",
+	DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n",
 			  __func__,
 			 dev_priv->current_page,
 			 master_priv->sarea_priv->pf_current_page);
@@ -633,8 +659,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
 		return -EINVAL;
 	}
 
-	DRM_DEBUG_DRIVER(I915_DRV,
-			"i915 batchbuffer, start %x used %d cliprects %d\n",
+	DRM_DEBUG_DRIVER("i915 batchbuffer, start %x used %d cliprects %d\n",
 			batch->start, batch->used, batch->num_cliprects);
 
 	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -681,8 +706,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
 	void *batch_data;
 	int ret;
 
-	DRM_DEBUG_DRIVER(I915_DRV,
-			"i915 cmdbuffer, buf %p sz %d cliprects %d\n",
+	DRM_DEBUG_DRIVER("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
 			cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
 
 	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -735,7 +759,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data,
 {
 	int ret;
 
-	DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__);
+	DRM_DEBUG_DRIVER("%s\n", __func__);
 
 	RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
 
@@ -778,7 +802,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
 		value = dev_priv->num_fence_regs - dev_priv->fence_reg_start;
 		break;
 	default:
-		DRM_DEBUG_DRIVER(I915_DRV, "Unknown parameter %d\n",
+		DRM_DEBUG_DRIVER("Unknown parameter %d\n",
 					param->param);
 		return -EINVAL;
 	}
@@ -819,7 +843,7 @@ static int i915_setparam(struct drm_device *dev, void *data,
 		dev_priv->fence_reg_start = param->value;
 		break;
 	default:
-		DRM_DEBUG_DRIVER(I915_DRV, "unknown parameter %d\n",
+		DRM_DEBUG_DRIVER("unknown parameter %d\n",
 					param->param);
 		return -EINVAL;
 	}
@@ -846,7 +870,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 		return 0;
 	}
 
-	DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
+	DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr);
 
 	dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
 
@@ -868,13 +892,25 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 
 	memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
 	I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
-	DRM_DEBUG_DRIVER(I915_DRV, "load hws HWS_PGA with gfx mem 0x%x\n",
+	DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n",
 				dev_priv->status_gfx_addr);
-	DRM_DEBUG_DRIVER(I915_DRV, "load hws at %p\n",
+	DRM_DEBUG_DRIVER("load hws at %p\n",
 				dev_priv->hw_status_page);
 	return 0;
 }
 
+static int i915_get_bridge_dev(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+	if (!dev_priv->bridge_dev) {
+		DRM_ERROR("bridge device not found\n");
+		return -1;
+	}
+	return 0;
+}
+
 /**
  * i915_probe_agp - get AGP bootup configuration
  * @pdev: PCI device
@@ -888,20 +924,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
 			  uint32_t *preallocated_size)
 {
-	struct pci_dev *bridge_dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	u16 tmp = 0;
 	unsigned long overhead;
 	unsigned long stolen;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_ERROR("bridge device not found\n");
-		return -1;
-	}
-
 	/* Get the fb aperture size and "stolen" memory amount. */
-	pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
-	pci_dev_put(bridge_dev);
+	pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp);
 
 	*aperture_size = 1024 * 1024;
 	*preallocated_size = 1024 * 1024;
@@ -984,6 +1013,19 @@ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
 	return 0;
 }
 
+/* true = enable decode, false = disable decoder */
+static unsigned int i915_vga_set_decode(void *cookie, bool state)
+{
+	struct drm_device *dev = cookie;
+
+	intel_modeset_vga_set_state(dev, state);
+	if (state)
+		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+	else
+		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
+
 static int i915_load_modeset_init(struct drm_device *dev,
 				  unsigned long prealloc_size,
 				  unsigned long agp_size)
@@ -1029,6 +1071,11 @@ static int i915_load_modeset_init(struct drm_device *dev,
 	if (ret)
 		DRM_INFO("failed to find VBIOS tables\n");
 
+	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
+	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
+	if (ret)
+		goto destroy_ringbuffer;
+
 	ret = drm_irq_install(dev);
 	if (ret)
 		goto destroy_ringbuffer;
@@ -1153,11 +1200,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 	base = drm_get_resource_start(dev, mmio_bar);
 	size = drm_get_resource_len(dev, mmio_bar);
 
+	if (i915_get_bridge_dev(dev)) {
+		ret = -EIO;
+		goto free_priv;
+	}
+
 	dev_priv->regs = ioremap(base, size);
 	if (!dev_priv->regs) {
 		DRM_ERROR("failed to map registers\n");
 		ret = -EIO;
-		goto free_priv;
+		goto put_bridge;
 	}
 
         dev_priv->mm.gtt_mapping =
@@ -1269,6 +1321,8 @@ out_iomapfree:
 	io_mapping_free(dev_priv->mm.gtt_mapping);
 out_rmmap:
 	iounmap(dev_priv->regs);
+put_bridge:
+	pci_dev_put(dev_priv->bridge_dev);
 free_priv:
 	kfree(dev_priv);
 	return ret;
@@ -1289,6 +1343,7 @@ int i915_driver_unload(struct drm_device *dev)
 
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		drm_irq_uninstall(dev);
+		vga_client_register(dev->pdev, NULL, NULL, NULL);
 	}
 
 	if (dev->pdev->msi_enabled)
@@ -1312,6 +1367,7 @@ int i915_driver_unload(struct drm_device *dev)
 		i915_gem_lastclose(dev);
 	}
 
+	pci_dev_put(dev_priv->bridge_dev);
 	kfree(dev->dev_private);
 
 	return 0;
@@ -1321,7 +1377,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
 {
 	struct drm_i915_file_private *i915_file_priv;
 
-	DRM_DEBUG_DRIVER(I915_DRV, "\n");
+	DRM_DEBUG_DRIVER("\n");
 	i915_file_priv = (struct drm_i915_file_private *)
 	    kmalloc(sizeof(*i915_file_priv), GFP_KERNEL);
 
@@ -1352,7 +1408,7 @@ void i915_driver_lastclose(struct drm_device * dev)
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
 	if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
-		intelfb_restore();
+		drm_fb_helper_restore();
 		return;
 	}
 
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index fc4b68a..dbe568c 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -37,12 +37,15 @@
 #include <linux/console.h>
 #include "drm_crtc_helper.h"
 
-static unsigned int i915_modeset = -1;
+static int i915_modeset = -1;
 module_param_named(modeset, i915_modeset, int, 0400);
 
 unsigned int i915_fbpercrtc = 0;
 module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
 
+unsigned int i915_powersave = 1;
+module_param_named(powersave, i915_powersave, int, 0400);
+
 static struct drm_driver driver;
 
 static struct pci_device_id pciidlist[] = {
@@ -188,8 +191,8 @@ static struct drm_driver driver = {
 	.master_create = i915_master_create,
 	.master_destroy = i915_master_destroy,
 #if defined(CONFIG_DEBUG_FS)
-	.debugfs_init = i915_gem_debugfs_init,
-	.debugfs_cleanup = i915_gem_debugfs_cleanup,
+	.debugfs_init = i915_debugfs_init,
+	.debugfs_cleanup = i915_debugfs_cleanup,
 #endif
 	.gem_init_object = i915_gem_init_object,
 	.gem_free_object = i915_gem_free_object,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5b4f87e..a0632f8 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object {
 };
 
 typedef struct _drm_i915_ring_buffer {
-	int tail_mask;
 	unsigned long Size;
 	u8 *virtual_start;
 	int head;
@@ -156,6 +155,7 @@ typedef struct drm_i915_private {
 
 	void __iomem *regs;
 
+	struct pci_dev *bridge_dev;
 	drm_i915_ring_buffer_t ring;
 
 	drm_dma_handle_t *status_page_dmah;
@@ -311,7 +311,7 @@ typedef struct drm_i915_private {
 	u32 saveIMR;
 	u32 saveCACHE_MODE_0;
 	u32 saveD_STATE;
-	u32 saveCG_2D_DIS;
+	u32 saveDSPCLK_GATE_D;
 	u32 saveMI_ARB_STATE;
 	u32 saveSWF0[16];
 	u32 saveSWF1[16];
@@ -443,6 +443,14 @@ typedef struct drm_i915_private {
 		struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT];
 	} mm;
 	struct sdvo_device_mapping sdvo_mappings[2];
+
+	/* Reclocking support */
+	bool render_reclock_avail;
+	bool lvds_downclock_avail;
+	struct work_struct idle_work;
+	struct timer_list idle_timer;
+	bool busy;
+	u16 orig_clock;
 } drm_i915_private_t;
 
 /** driver private structure attached to each drm_gem_object */
@@ -575,6 +583,7 @@ enum intel_chip_family {
 extern struct drm_ioctl_desc i915_ioctls[];
 extern int i915_max_ioctl;
 extern unsigned int i915_fbpercrtc;
+extern unsigned int i915_powersave;
 
 extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
 extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
@@ -730,8 +739,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len,
 void i915_dump_lru(struct drm_device *dev, const char *where);
 
 /* i915_debugfs.c */
-int i915_gem_debugfs_init(struct drm_minor *minor);
-void i915_gem_debugfs_cleanup(struct drm_minor *minor);
+int i915_debugfs_init(struct drm_minor *minor);
+void i915_debugfs_cleanup(struct drm_minor *minor);
 
 /* i915_suspend.c */
 extern int i915_save_state(struct drm_device *dev);
@@ -757,6 +766,7 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; }
 /* modesetting */
 extern void intel_modeset_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
+extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
 
 /**
  * Lock test for when it's just for synchronization of ring access.
@@ -781,33 +791,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
 
 #define I915_VERBOSE 0
 
-#define RING_LOCALS	unsigned int outring, ringmask, outcount; \
-                        volatile char *virt;
-
-#define BEGIN_LP_RING(n) do {				\
-	if (I915_VERBOSE)				\
-		DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n));	\
-	if (dev_priv->ring.space < (n)*4)		\
-		i915_wait_ring(dev, (n)*4, __func__);		\
-	outcount = 0;					\
-	outring = dev_priv->ring.tail;			\
-	ringmask = dev_priv->ring.tail_mask;		\
-	virt = dev_priv->ring.virtual_start;		\
+#define RING_LOCALS	volatile unsigned int *ring_virt__;
+
+#define BEGIN_LP_RING(n) do {						\
+	int bytes__ = 4*(n);						\
+	if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n));	\
+	/* a wrap must occur between instructions so pad beforehand */	\
+	if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \
+		i915_wrap_ring(dev);					\
+	if (unlikely (dev_priv->ring.space < bytes__))			\
+		i915_wait_ring(dev, bytes__, __func__);			\
+	ring_virt__ = (unsigned int *)					\
+	        (dev_priv->ring.virtual_start + dev_priv->ring.tail);	\
+	dev_priv->ring.tail += bytes__;					\
+	dev_priv->ring.tail &= dev_priv->ring.Size - 1;			\
+	dev_priv->ring.space -= bytes__;				\
 } while (0)
 
-#define OUT_RING(n) do {					\
+#define OUT_RING(n) do {						\
 	if (I915_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));	\
-	*(volatile unsigned int *)(virt + outring) = (n);	\
-        outcount++;						\
-	outring += 4;						\
-	outring &= ringmask;					\
+	*ring_virt__++ = (n);						\
 } while (0)
 
 #define ADVANCE_LP_RING() do {						\
-	if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring);	\
-	dev_priv->ring.tail = outring;					\
-	dev_priv->ring.space -= outcount * 4;				\
-	I915_WRITE(PRB0_TAIL, outring);			\
+	if (I915_VERBOSE)						\
+		DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail);	\
+	I915_WRITE(PRB0_TAIL, dev_priv->ring.tail);			\
 } while(0)
 
 /**
@@ -830,6 +839,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
 #define I915_GEM_HWS_INDEX		0x20
 #define I915_BREADCRUMB_INDEX		0x21
 
+extern int i915_wrap_ring(struct drm_device * dev);
 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 
 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
@@ -903,6 +913,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 /* dsparb controlled by hw only */
 #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev))
 
+#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev))
+#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev))
+
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
 #endif
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 80e5ba4..c673171 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -29,6 +29,7 @@
 #include "drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
+#include "intel_drv.h"
 #include <linux/swap.h>
 #include <linux/pci.h>
 
@@ -111,7 +112,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 {
 	struct drm_i915_gem_create *args = data;
 	struct drm_gem_object *obj;
-	int handle, ret;
+	int ret;
+	u32 handle;
 
 	args->size = roundup(args->size, PAGE_SIZE);
 
@@ -981,6 +983,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_gem_set_domain *args = data;
 	struct drm_gem_object *obj;
+	struct drm_i915_gem_object *obj_priv;
 	uint32_t read_domains = args->read_domains;
 	uint32_t write_domain = args->write_domain;
 	int ret;
@@ -1004,15 +1007,17 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (obj == NULL)
 		return -EBADF;
+	obj_priv = obj->driver_private;
 
 	mutex_lock(&dev->struct_mutex);
+
+	intel_mark_busy(dev, obj);
+
 #if WATCH_BUF
 	DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n",
 		 obj, obj->size, read_domains, write_domain);
 #endif
 	if (read_domains & I915_GEM_DOMAIN_GTT) {
-		struct drm_i915_gem_object *obj_priv = obj->driver_private;
-
 		ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
 
 		/* Update the LRU on the fence for the CPU access that's
@@ -2776,6 +2781,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 	BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
 	BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
 
+	intel_mark_busy(dev, obj);
+
 #if WATCH_BUF
 	DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
 		 __func__, obj,
@@ -4093,7 +4100,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
 
 	/* Set up the kernel mapping for the ring. */
 	ring->Size = obj->size;
-	ring->tail_mask = obj->size - 1;
 
 	ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
 	ring->map.size = obj->size;
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c
deleted file mode 100644
index cb3b974..0000000
--- a/drivers/gpu/drm/i915/i915_gem_debugfs.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright Â© 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *    Keith Packard <keithp@keithp.com>
- *
- */
-
-#include <linux/seq_file.h>
-#include "drmP.h"
-#include "drm.h"
-#include "i915_drm.h"
-#include "i915_drv.h"
-
-#define DRM_I915_RING_DEBUG 1
-
-
-#if defined(CONFIG_DEBUG_FS)
-
-#define ACTIVE_LIST	1
-#define FLUSHING_LIST	2
-#define INACTIVE_LIST	3
-
-static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv)
-{
-	if (obj_priv->user_pin_count > 0)
-		return "P";
-	else if (obj_priv->pin_count > 0)
-		return "p";
-	else
-		return " ";
-}
-
-static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv)
-{
-    switch (obj_priv->tiling_mode) {
-    default:
-    case I915_TILING_NONE: return " ";
-    case I915_TILING_X: return "X";
-    case I915_TILING_Y: return "Y";
-    }
-}
-
-static int i915_gem_object_list_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	uintptr_t list = (uintptr_t) node->info_ent->data;
-	struct list_head *head;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_object *obj_priv;
-	spinlock_t *lock = NULL;
-
-	switch (list) {
-	case ACTIVE_LIST:
-		seq_printf(m, "Active:\n");
-		lock = &dev_priv->mm.active_list_lock;
-		head = &dev_priv->mm.active_list;
-		break;
-	case INACTIVE_LIST:
-		seq_printf(m, "Inactive:\n");
-		head = &dev_priv->mm.inactive_list;
-		break;
-	case FLUSHING_LIST:
-		seq_printf(m, "Flushing:\n");
-		head = &dev_priv->mm.flushing_list;
-		break;
-	default:
-		DRM_INFO("Ooops, unexpected list\n");
-		return 0;
-	}
-
-	if (lock)
-		spin_lock(lock);
-	list_for_each_entry(obj_priv, head, list)
-	{
-		struct drm_gem_object *obj = obj_priv->obj;
-
-		seq_printf(m, "    %p: %s %08x %08x %d",
-			   obj,
-			   get_pin_flag(obj_priv),
-			   obj->read_domains, obj->write_domain,
-			   obj_priv->last_rendering_seqno);
-
-		if (obj->name)
-			seq_printf(m, " (name: %d)", obj->name);
-		if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
-			seq_printf(m, " (fence: %d)", obj_priv->fence_reg);
-		if (obj_priv->gtt_space != NULL)
-			seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset);
-
-		seq_printf(m, "\n");
-	}
-
-	if (lock)
-	    spin_unlock(lock);
-	return 0;
-}
-
-static int i915_gem_request_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_gem_request *gem_request;
-
-	seq_printf(m, "Request:\n");
-	list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) {
-		seq_printf(m, "    %d @ %d\n",
-			   gem_request->seqno,
-			   (int) (jiffies - gem_request->emitted_jiffies));
-	}
-	return 0;
-}
-
-static int i915_gem_seqno_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-
-	if (dev_priv->hw_status_page != NULL) {
-		seq_printf(m, "Current sequence: %d\n",
-			   i915_get_gem_seqno(dev));
-	} else {
-		seq_printf(m, "Current sequence: hws uninitialized\n");
-	}
-	seq_printf(m, "Waiter sequence:  %d\n",
-			dev_priv->mm.waiting_gem_seqno);
-	seq_printf(m, "IRQ sequence:     %d\n", dev_priv->mm.irq_gem_seqno);
-	return 0;
-}
-
-
-static int i915_interrupt_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-
-	seq_printf(m, "Interrupt enable:    %08x\n",
-		   I915_READ(IER));
-	seq_printf(m, "Interrupt identity:  %08x\n",
-		   I915_READ(IIR));
-	seq_printf(m, "Interrupt mask:      %08x\n",
-		   I915_READ(IMR));
-	seq_printf(m, "Pipe A stat:         %08x\n",
-		   I915_READ(PIPEASTAT));
-	seq_printf(m, "Pipe B stat:         %08x\n",
-		   I915_READ(PIPEBSTAT));
-	seq_printf(m, "Interrupts received: %d\n",
-		   atomic_read(&dev_priv->irq_received));
-	if (dev_priv->hw_status_page != NULL) {
-		seq_printf(m, "Current sequence:    %d\n",
-			   i915_get_gem_seqno(dev));
-	} else {
-		seq_printf(m, "Current sequence:    hws uninitialized\n");
-	}
-	seq_printf(m, "Waiter sequence:     %d\n",
-		   dev_priv->mm.waiting_gem_seqno);
-	seq_printf(m, "IRQ sequence:        %d\n",
-		   dev_priv->mm.irq_gem_seqno);
-	return 0;
-}
-
-static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int i;
-
-	seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start);
-	seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs);
-	for (i = 0; i < dev_priv->num_fence_regs; i++) {
-		struct drm_gem_object *obj = dev_priv->fence_regs[i].obj;
-
-		if (obj == NULL) {
-			seq_printf(m, "Fenced object[%2d] = unused\n", i);
-		} else {
-			struct drm_i915_gem_object *obj_priv;
-
-			obj_priv = obj->driver_private;
-			seq_printf(m, "Fenced object[%2d] = %p: %s "
-				   "%08x %08zx %08x %s %08x %08x %d",
-				   i, obj, get_pin_flag(obj_priv),
-				   obj_priv->gtt_offset,
-				   obj->size, obj_priv->stride,
-				   get_tiling_flag(obj_priv),
-				   obj->read_domains, obj->write_domain,
-				   obj_priv->last_rendering_seqno);
-			if (obj->name)
-				seq_printf(m, " (name: %d)", obj->name);
-			seq_printf(m, "\n");
-		}
-	}
-
-	return 0;
-}
-
-static int i915_hws_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	int i;
-	volatile u32 *hws;
-
-	hws = (volatile u32 *)dev_priv->hw_status_page;
-	if (hws == NULL)
-		return 0;
-
-	for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) {
-		seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
-			   i * 4,
-			   hws[i], hws[i + 1], hws[i + 2], hws[i + 3]);
-	}
-	return 0;
-}
-
-static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count)
-{
-	int page, i;
-	uint32_t *mem;
-
-	for (page = 0; page < page_count; page++) {
-		mem = kmap(pages[page]);
-		for (i = 0; i < PAGE_SIZE; i += 4)
-			seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
-		kunmap(pages[page]);
-	}
-}
-
-static int i915_batchbuffer_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_gem_object *obj;
-	struct drm_i915_gem_object *obj_priv;
-	int ret;
-
-	spin_lock(&dev_priv->mm.active_list_lock);
-
-	list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
-		obj = obj_priv->obj;
-		if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) {
-		    ret = i915_gem_object_get_pages(obj);
-		    if (ret) {
-			    DRM_ERROR("Failed to get pages: %d\n", ret);
-			    spin_unlock(&dev_priv->mm.active_list_lock);
-			    return ret;
-		    }
-
-		    seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset);
-		    i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE);
-
-		    i915_gem_object_put_pages(obj);
-		}
-	}
-
-	spin_unlock(&dev_priv->mm.active_list_lock);
-
-	return 0;
-}
-
-static int i915_ringbuffer_data(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	u8 *virt;
-	uint32_t *ptr, off;
-
-	if (!dev_priv->ring.ring_obj) {
-		seq_printf(m, "No ringbuffer setup\n");
-		return 0;
-	}
-
-	virt = dev_priv->ring.virtual_start;
-
-	for (off = 0; off < dev_priv->ring.Size; off += 4) {
-		ptr = (uint32_t *)(virt + off);
-		seq_printf(m, "%08x :  %08x\n", off, *ptr);
-	}
-
-	return 0;
-}
-
-static int i915_ringbuffer_info(struct seq_file *m, void *data)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	unsigned int head, tail, mask;
-
-	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
-	tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
-	mask = dev_priv->ring.tail_mask;
-
-	seq_printf(m, "RingHead :  %08x\n", head);
-	seq_printf(m, "RingTail :  %08x\n", tail);
-	seq_printf(m, "RingMask :  %08x\n", mask);
-	seq_printf(m, "RingSize :  %08lx\n", dev_priv->ring.Size);
-	seq_printf(m, "Acthd :     %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD));
-
-	return 0;
-}
-
-static int i915_error_state(struct seq_file *m, void *unused)
-{
-	struct drm_info_node *node = (struct drm_info_node *) m->private;
-	struct drm_device *dev = node->minor->dev;
-	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct drm_i915_error_state *error;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev_priv->error_lock, flags);
-	if (!dev_priv->first_error) {
-		seq_printf(m, "no error state collected\n");
-		goto out;
-	}
-
-	error = dev_priv->first_error;
-
-	seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec,
-		   error->time.tv_usec);
-	seq_printf(m, "EIR: 0x%08x\n", error->eir);
-	seq_printf(m, "  PGTBL_ER: 0x%08x\n", error->pgtbl_er);
-	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
-	seq_printf(m, "  IPEIR: 0x%08x\n", error->ipeir);
-	seq_printf(m, "  IPEHR: 0x%08x\n", error->ipehr);
-	seq_printf(m, "  INSTDONE: 0x%08x\n", error->instdone);
-	seq_printf(m, "  ACTHD: 0x%08x\n", error->acthd);
-	if (IS_I965G(dev)) {
-		seq_printf(m, "  INSTPS: 0x%08x\n", error->instps);
-		seq_printf(m, "  INSTDONE1: 0x%08x\n", error->instdone1);
-	}
-
-out:
-	spin_unlock_irqrestore(&dev_priv->error_lock, flags);
-
-	return 0;
-}
-
-static struct drm_info_list i915_gem_debugfs_list[] = {
-	{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
-	{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
-	{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
-	{"i915_gem_request", i915_gem_request_info, 0},
-	{"i915_gem_seqno", i915_gem_seqno_info, 0},
-	{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
-	{"i915_gem_interrupt", i915_interrupt_info, 0},
-	{"i915_gem_hws", i915_hws_info, 0},
-	{"i915_ringbuffer_data", i915_ringbuffer_data, 0},
-	{"i915_ringbuffer_info", i915_ringbuffer_info, 0},
-	{"i915_batchbuffers", i915_batchbuffer_info, 0},
-	{"i915_error_state", i915_error_state, 0},
-};
-#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list)
-
-int i915_gem_debugfs_init(struct drm_minor *minor)
-{
-	return drm_debugfs_create_files(i915_gem_debugfs_list,
-					I915_GEM_DEBUGFS_ENTRIES,
-					minor->debugfs_root, minor);
-}
-
-void i915_gem_debugfs_cleanup(struct drm_minor *minor)
-{
-	drm_debugfs_remove_files(i915_gem_debugfs_list,
-				 I915_GEM_DEBUGFS_ENTRIES, minor);
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index a2d527b..200e398 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -94,23 +94,15 @@
 static int
 intel_alloc_mchbar_resource(struct drm_device *dev)
 {
-	struct pci_dev *bridge_dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
 	u32 temp_lo, temp_hi = 0;
 	u64 mchbar_addr;
 	int ret = 0;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_DEBUG("no bridge dev?!\n");
-		ret = -ENODEV;
-		goto out;
-	}
-
 	if (IS_I965G(dev))
-		pci_read_config_dword(bridge_dev, reg + 4, &temp_hi);
-	pci_read_config_dword(bridge_dev, reg, &temp_lo);
+		pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
+	pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
 	mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
 
 	/* If ACPI doesn't have it, assume we need to allocate it ourselves */
@@ -118,30 +110,28 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
 	if (mchbar_addr &&
 	    pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
 		ret = 0;
-		goto out_put;
+		goto out;
 	}
 #endif
 
 	/* Get some space for it */
-	ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res,
+	ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
 				     MCHBAR_SIZE, MCHBAR_SIZE,
 				     PCIBIOS_MIN_MEM,
 				     0,   pcibios_align_resource,
-				     bridge_dev);
+				     dev_priv->bridge_dev);
 	if (ret) {
 		DRM_DEBUG("failed bus alloc: %d\n", ret);
 		dev_priv->mch_res.start = 0;
-		goto out_put;
+		goto out;
 	}
 
 	if (IS_I965G(dev))
-		pci_write_config_dword(bridge_dev, reg + 4,
+		pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
 				       upper_32_bits(dev_priv->mch_res.start));
 
-	pci_write_config_dword(bridge_dev, reg,
+	pci_write_config_dword(dev_priv->bridge_dev, reg,
 			       lower_32_bits(dev_priv->mch_res.start));
-out_put:
-	pci_dev_put(bridge_dev);
 out:
 	return ret;
 }
@@ -150,44 +140,36 @@ out:
 static bool
 intel_setup_mchbar(struct drm_device *dev)
 {
-	struct pci_dev *bridge_dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
 	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
 	u32 temp;
 	bool need_disable = false, enabled;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_DEBUG("no bridge dev?!\n");
-		goto out;
-	}
-
 	if (IS_I915G(dev) || IS_I915GM(dev)) {
-		pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
+		pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
 		enabled = !!(temp & DEVEN_MCHBAR_EN);
 	} else {
-		pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
 		enabled = temp & 1;
 	}
 
 	/* If it's already enabled, don't have to do anything */
 	if (enabled)
-		goto out_put;
+		goto out;
 
 	if (intel_alloc_mchbar_resource(dev))
-		goto out_put;
+		goto out;
 
 	need_disable = true;
 
 	/* Space is allocated or reserved, so enable it. */
 	if (IS_I915G(dev) || IS_I915GM(dev)) {
-		pci_write_config_dword(bridge_dev, DEVEN_REG,
+		pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
 				       temp | DEVEN_MCHBAR_EN);
 	} else {
-		pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
-		pci_write_config_dword(bridge_dev, mchbar_reg, temp | 1);
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
+		pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
 	}
-out_put:
-	pci_dev_put(bridge_dev);
 out:
 	return need_disable;
 }
@@ -196,25 +178,18 @@ static void
 intel_teardown_mchbar(struct drm_device *dev, bool disable)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct pci_dev *bridge_dev;
 	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
 	u32 temp;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_DEBUG("no bridge dev?!\n");
-		return;
-	}
-
 	if (disable) {
 		if (IS_I915G(dev) || IS_I915GM(dev)) {
-			pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
+			pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
 			temp &= ~DEVEN_MCHBAR_EN;
-			pci_write_config_dword(bridge_dev, DEVEN_REG, temp);
+			pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
 		} else {
-			pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
+			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
 			temp &= ~1;
-			pci_write_config_dword(bridge_dev, mchbar_reg, temp);
+			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
 		}
 	}
 
@@ -234,7 +209,13 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
 	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 	bool need_disable;
 
-	if (!IS_I9XX(dev)) {
+	if (IS_IGDNG(dev)) {
+		/* On IGDNG whatever DRAM config, GPU always do
+		 * same swizzling setup.
+		 */
+		swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+		swizzle_y = I915_BIT_6_SWIZZLE_9;
+	} else if (!IS_I9XX(dev)) {
 		/* As far as we know, the 865 doesn't have these bit 6
 		 * swizzling issues.
 		 */
@@ -317,13 +298,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
 		}
 	}
 
-	/* FIXME: check with memory config on IGDNG */
-	if (IS_IGDNG(dev)) {
-		DRM_ERROR("disable tiling on IGDNG...\n");
-		swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
-		swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
-	}
-
 	dev_priv->mm.bit_6_swizzle_x = swizzle_x;
 	dev_priv->mm.bit_6_swizzle_y = swizzle_y;
 }
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7ebc84c..6c89f2f 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 
 			I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
 			I915_READ(PORT_HOTPLUG_STAT);
+
+			/* EOS interrupts occurs */
+			if (IS_IGD(dev) &&
+				(hotplug_status & CRT_EOS_INT_STATUS)) {
+				u32 temp;
+
+				DRM_DEBUG("EOS interrupt occurs\n");
+				/* status is already cleared */
+				temp = I915_READ(ADPA);
+				temp &= ~ADPA_DAC_ENABLE;
+				I915_WRITE(ADPA, temp);
+
+				temp = I915_READ(PORT_HOTPLUG_EN);
+				temp &= ~CRT_EOS_INT_EN;
+				I915_WRITE(PORT_HOTPLUG_EN, temp);
+
+				temp = I915_READ(PORT_HOTPLUG_STAT);
+				if (temp & CRT_EOS_INT_STATUS)
+					I915_WRITE(PORT_HOTPLUG_STAT,
+						CRT_EOS_INT_STATUS);
+			}
 		}
 
 		I915_WRITE(IIR, iir);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2955083..3f79635 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -30,6 +30,7 @@
  * fb aperture size and the amount of pre-reserved memory.
  */
 #define INTEL_GMCH_CTRL		0x52
+#define INTEL_GMCH_VGA_DISABLE  (1 << 1)
 #define INTEL_GMCH_ENABLED	0x4
 #define INTEL_GMCH_MEM_MASK	0x1
 #define INTEL_GMCH_MEM_64M	0x1
@@ -55,7 +56,7 @@
 /* PCI config space */
 
 #define HPLLCC	0xc0 /* 855 only */
-#define   GC_CLOCK_CONTROL_MASK		(3 << 0)
+#define   GC_CLOCK_CONTROL_MASK		(0xf << 0)
 #define   GC_CLOCK_133_200		(0 << 0)
 #define   GC_CLOCK_100_200		(1 << 0)
 #define   GC_CLOCK_100_133		(2 << 0)
@@ -65,6 +66,25 @@
 #define   GC_DISPLAY_CLOCK_190_200_MHZ	(0 << 4)
 #define   GC_DISPLAY_CLOCK_333_MHZ	(4 << 4)
 #define   GC_DISPLAY_CLOCK_MASK		(7 << 4)
+#define   GM45_GC_RENDER_CLOCK_MASK	(0xf << 0)
+#define   GM45_GC_RENDER_CLOCK_266_MHZ	(8 << 0)
+#define   GM45_GC_RENDER_CLOCK_320_MHZ	(9 << 0)
+#define   GM45_GC_RENDER_CLOCK_400_MHZ	(0xb << 0)
+#define   GM45_GC_RENDER_CLOCK_533_MHZ	(0xc << 0)
+#define   I965_GC_RENDER_CLOCK_MASK	(0xf << 0)
+#define   I965_GC_RENDER_CLOCK_267_MHZ	(2 << 0)
+#define   I965_GC_RENDER_CLOCK_333_MHZ	(3 << 0)
+#define   I965_GC_RENDER_CLOCK_444_MHZ	(4 << 0)
+#define   I965_GC_RENDER_CLOCK_533_MHZ	(5 << 0)
+#define   I945_GC_RENDER_CLOCK_MASK	(7 << 0)
+#define   I945_GC_RENDER_CLOCK_166_MHZ	(0 << 0)
+#define   I945_GC_RENDER_CLOCK_200_MHZ	(1 << 0)
+#define   I945_GC_RENDER_CLOCK_250_MHZ	(3 << 0)
+#define   I945_GC_RENDER_CLOCK_400_MHZ	(5 << 0)
+#define   I915_GC_RENDER_CLOCK_MASK	(7 << 0)
+#define   I915_GC_RENDER_CLOCK_166_MHZ	(0 << 0)
+#define   I915_GC_RENDER_CLOCK_200_MHZ	(1 << 0)
+#define   I915_GC_RENDER_CLOCK_333_MHZ	(4 << 0)
 #define LBB	0xf4
 
 /* VGA stuff */
@@ -553,9 +573,118 @@
 #define   DPLLA_TEST_M_BYPASS		(1 << 2)
 #define   DPLLA_INPUT_BUFFER_ENABLE	(1 << 0)
 #define D_STATE		0x6104
-#define CG_2D_DIS	0x6200
-#define DPCUNIT_CLOCK_GATE_DISABLE	(1 << 24)
-#define CG_3D_DIS	0x6204
+#define  DSTATE_PLL_D3_OFF			(1<<3)
+#define  DSTATE_GFX_CLOCK_GATING		(1<<1)
+#define  DSTATE_DOT_CLOCK_GATING		(1<<0)
+#define DSPCLK_GATE_D		0x6200
+# define DPUNIT_B_CLOCK_GATE_DISABLE		(1 << 30) /* 965 */
+# define VSUNIT_CLOCK_GATE_DISABLE		(1 << 29) /* 965 */
+# define VRHUNIT_CLOCK_GATE_DISABLE		(1 << 28) /* 965 */
+# define VRDUNIT_CLOCK_GATE_DISABLE		(1 << 27) /* 965 */
+# define AUDUNIT_CLOCK_GATE_DISABLE		(1 << 26) /* 965 */
+# define DPUNIT_A_CLOCK_GATE_DISABLE		(1 << 25) /* 965 */
+# define DPCUNIT_CLOCK_GATE_DISABLE		(1 << 24) /* 965 */
+# define TVRUNIT_CLOCK_GATE_DISABLE		(1 << 23) /* 915-945 */
+# define TVCUNIT_CLOCK_GATE_DISABLE		(1 << 22) /* 915-945 */
+# define TVFUNIT_CLOCK_GATE_DISABLE		(1 << 21) /* 915-945 */
+# define TVEUNIT_CLOCK_GATE_DISABLE		(1 << 20) /* 915-945 */
+# define DVSUNIT_CLOCK_GATE_DISABLE		(1 << 19) /* 915-945 */
+# define DSSUNIT_CLOCK_GATE_DISABLE		(1 << 18) /* 915-945 */
+# define DDBUNIT_CLOCK_GATE_DISABLE		(1 << 17) /* 915-945 */
+# define DPRUNIT_CLOCK_GATE_DISABLE		(1 << 16) /* 915-945 */
+# define DPFUNIT_CLOCK_GATE_DISABLE		(1 << 15) /* 915-945 */
+# define DPBMUNIT_CLOCK_GATE_DISABLE		(1 << 14) /* 915-945 */
+# define DPLSUNIT_CLOCK_GATE_DISABLE		(1 << 13) /* 915-945 */
+# define DPLUNIT_CLOCK_GATE_DISABLE		(1 << 12) /* 915-945 */
+# define DPOUNIT_CLOCK_GATE_DISABLE		(1 << 11)
+# define DPBUNIT_CLOCK_GATE_DISABLE		(1 << 10)
+# define DCUNIT_CLOCK_GATE_DISABLE		(1 << 9)
+# define DPUNIT_CLOCK_GATE_DISABLE		(1 << 8)
+# define VRUNIT_CLOCK_GATE_DISABLE		(1 << 7) /* 915+: reserved */
+# define OVHUNIT_CLOCK_GATE_DISABLE		(1 << 6) /* 830-865 */
+# define DPIOUNIT_CLOCK_GATE_DISABLE		(1 << 6) /* 915-945 */
+# define OVFUNIT_CLOCK_GATE_DISABLE		(1 << 5)
+# define OVBUNIT_CLOCK_GATE_DISABLE		(1 << 4)
+/**
+ * This bit must be set on the 830 to prevent hangs when turning off the
+ * overlay scaler.
+ */
+# define OVRUNIT_CLOCK_GATE_DISABLE		(1 << 3)
+# define OVCUNIT_CLOCK_GATE_DISABLE		(1 << 2)
+# define OVUUNIT_CLOCK_GATE_DISABLE		(1 << 1)
+# define ZVUNIT_CLOCK_GATE_DISABLE		(1 << 0) /* 830 */
+# define OVLUNIT_CLOCK_GATE_DISABLE		(1 << 0) /* 845,865 */
+
+#define RENCLK_GATE_D1		0x6204
+# define BLITTER_CLOCK_GATE_DISABLE		(1 << 13) /* 945GM only */
+# define MPEG_CLOCK_GATE_DISABLE		(1 << 12) /* 945GM only */
+# define PC_FE_CLOCK_GATE_DISABLE		(1 << 11)
+# define PC_BE_CLOCK_GATE_DISABLE		(1 << 10)
+# define WINDOWER_CLOCK_GATE_DISABLE		(1 << 9)
+# define INTERPOLATOR_CLOCK_GATE_DISABLE	(1 << 8)
+# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE	(1 << 7)
+# define MOTION_COMP_CLOCK_GATE_DISABLE		(1 << 6)
+# define MAG_CLOCK_GATE_DISABLE			(1 << 5)
+/** This bit must be unset on 855,865 */
+# define MECI_CLOCK_GATE_DISABLE		(1 << 4)
+# define DCMP_CLOCK_GATE_DISABLE		(1 << 3)
+# define MEC_CLOCK_GATE_DISABLE			(1 << 2)
+# define MECO_CLOCK_GATE_DISABLE		(1 << 1)
+/** This bit must be set on 855,865. */
+# define SV_CLOCK_GATE_DISABLE			(1 << 0)
+# define I915_MPEG_CLOCK_GATE_DISABLE		(1 << 16)
+# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE	(1 << 15)
+# define I915_MOTION_COMP_CLOCK_GATE_DISABLE	(1 << 14)
+# define I915_BD_BF_CLOCK_GATE_DISABLE		(1 << 13)
+# define I915_SF_SE_CLOCK_GATE_DISABLE		(1 << 12)
+# define I915_WM_CLOCK_GATE_DISABLE		(1 << 11)
+# define I915_IZ_CLOCK_GATE_DISABLE		(1 << 10)
+# define I915_PI_CLOCK_GATE_DISABLE		(1 << 9)
+# define I915_DI_CLOCK_GATE_DISABLE		(1 << 8)
+# define I915_SH_SV_CLOCK_GATE_DISABLE		(1 << 7)
+# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE	(1 << 6)
+# define I915_SC_CLOCK_GATE_DISABLE		(1 << 5)
+# define I915_FL_CLOCK_GATE_DISABLE		(1 << 4)
+# define I915_DM_CLOCK_GATE_DISABLE		(1 << 3)
+# define I915_PS_CLOCK_GATE_DISABLE		(1 << 2)
+# define I915_CC_CLOCK_GATE_DISABLE		(1 << 1)
+# define I915_BY_CLOCK_GATE_DISABLE		(1 << 0)
+
+# define I965_RCZ_CLOCK_GATE_DISABLE		(1 << 30)
+/** This bit must always be set on 965G/965GM */
+# define I965_RCC_CLOCK_GATE_DISABLE		(1 << 29)
+# define I965_RCPB_CLOCK_GATE_DISABLE		(1 << 28)
+# define I965_DAP_CLOCK_GATE_DISABLE		(1 << 27)
+# define I965_ROC_CLOCK_GATE_DISABLE		(1 << 26)
+# define I965_GW_CLOCK_GATE_DISABLE		(1 << 25)
+# define I965_TD_CLOCK_GATE_DISABLE		(1 << 24)
+/** This bit must always be set on 965G */
+# define I965_ISC_CLOCK_GATE_DISABLE		(1 << 23)
+# define I965_IC_CLOCK_GATE_DISABLE		(1 << 22)
+# define I965_EU_CLOCK_GATE_DISABLE		(1 << 21)
+# define I965_IF_CLOCK_GATE_DISABLE		(1 << 20)
+# define I965_TC_CLOCK_GATE_DISABLE		(1 << 19)
+# define I965_SO_CLOCK_GATE_DISABLE		(1 << 17)
+# define I965_FBC_CLOCK_GATE_DISABLE		(1 << 16)
+# define I965_MARI_CLOCK_GATE_DISABLE		(1 << 15)
+# define I965_MASF_CLOCK_GATE_DISABLE		(1 << 14)
+# define I965_MAWB_CLOCK_GATE_DISABLE		(1 << 13)
+# define I965_EM_CLOCK_GATE_DISABLE		(1 << 12)
+# define I965_UC_CLOCK_GATE_DISABLE		(1 << 11)
+# define I965_SI_CLOCK_GATE_DISABLE		(1 << 6)
+# define I965_MT_CLOCK_GATE_DISABLE		(1 << 5)
+# define I965_PL_CLOCK_GATE_DISABLE		(1 << 4)
+# define I965_DG_CLOCK_GATE_DISABLE		(1 << 3)
+# define I965_QC_CLOCK_GATE_DISABLE		(1 << 2)
+# define I965_FT_CLOCK_GATE_DISABLE		(1 << 1)
+# define I965_DM_CLOCK_GATE_DISABLE		(1 << 0)
+
+#define RENCLK_GATE_D2		0x6208
+#define VF_UNIT_CLOCK_GATE_DISABLE		(1 << 9)
+#define GS_UNIT_CLOCK_GATE_DISABLE		(1 << 7)
+#define CL_UNIT_CLOCK_GATE_DISABLE		(1 << 6)
+#define RAMCLK_GATE_D		0x6210		/* CRL only */
+#define DEUC			0x6214          /* CRL only */
 
 /*
  * Palette regs
@@ -683,6 +812,7 @@
 #define   SDVOB_HOTPLUG_INT_EN			(1 << 26)
 #define   SDVOC_HOTPLUG_INT_EN			(1 << 25)
 #define   TV_HOTPLUG_INT_EN			(1 << 18)
+#define   CRT_EOS_INT_EN			(1 << 10)
 #define   CRT_HOTPLUG_INT_EN			(1 << 9)
 #define   CRT_HOTPLUG_FORCE_DETECT		(1 << 3)
 #define CRT_HOTPLUG_ACTIVATION_PERIOD_32	(0 << 8)
@@ -717,6 +847,7 @@
 #define   DPC_HOTPLUG_INT_STATUS		(1 << 28)
 #define   HDMID_HOTPLUG_INT_STATUS		(1 << 27)
 #define   DPD_HOTPLUG_INT_STATUS		(1 << 27)
+#define   CRT_EOS_INT_STATUS			(1 << 12)
 #define   CRT_HOTPLUG_INT_STATUS		(1 << 11)
 #define   TV_HOTPLUG_INT_STATUS			(1 << 10)
 #define   CRT_HOTPLUG_MONITOR_MASK		(3 << 8)
@@ -1586,6 +1717,7 @@
 #define   PIPECONF_PROGRESSIVE	(0 << 21)
 #define   PIPECONF_INTERLACE_W_FIELD_INDICATION	(6 << 21)
 #define   PIPECONF_INTERLACE_FIELD_0_ONLY		(7 << 21)
+#define   PIPECONF_CXSR_DOWNCLOCK	(1<<16)
 #define PIPEASTAT		0x70024
 #define   PIPE_FIFO_UNDERRUN_STATUS		(1UL<<31)
 #define   PIPE_CRC_ERROR_ENABLE			(1UL<<29)
@@ -1733,6 +1865,7 @@
 #define   DISPPLANE_NO_LINE_DOUBLE		0
 #define   DISPPLANE_STEREO_POLARITY_FIRST	0
 #define   DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
+#define   DISPPLANE_TRICKLE_FEED_DISABLE	(1<<14) /* IGDNG */
 #define   DISPPLANE_TILED			(1<<10)
 #define DSPAADDR		0x70184
 #define DSPASTRIDE		0x70188
@@ -1913,6 +2046,9 @@
 #define GTIIR   0x44018
 #define GTIER   0x4401c
 
+#define DISP_ARB_CTL	0x45000
+#define  DISP_TILE_SURFACE_SWIZZLING	(1<<13)
+
 /* PCH */
 
 /* south display engine interrupt */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 1d04e19..20d4d19 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev)
 
 	/* Clock gating state */
 	dev_priv->saveD_STATE = I915_READ(D_STATE);
-	dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
+	dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
 
 	/* Cache mode state */
 	dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
@@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev)
 
 	/* Clock gating state */
 	I915_WRITE (D_STATE, dev_priv->saveD_STATE);
-	I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
+	I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
 
 	/* Cache mode state */
 	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index f806fcc..1e28c16 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -355,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv,
 	}
 
 	driver = find_section(bdb, BDB_DRIVER_FEATURES);
-	if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
+	if (!driver)
+		return;
+
+	if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)
 		dev_priv->edp_support = 1;
+
+	if (driver->dual_frequency)
+		dev_priv->render_reclock_avail = true;
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 590f81c..88814fa 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
 	}
 
 	I915_WRITE(reg, temp);
+
+	if (IS_IGD(dev)) {
+		if (mode == DRM_MODE_DPMS_OFF) {
+			/* turn off DAC */
+			temp = I915_READ(PORT_HOTPLUG_EN);
+			temp &= ~CRT_EOS_INT_EN;
+			I915_WRITE(PORT_HOTPLUG_EN, temp);
+
+			temp = I915_READ(PORT_HOTPLUG_STAT);
+			if (temp & CRT_EOS_INT_STATUS)
+				I915_WRITE(PORT_HOTPLUG_STAT,
+					CRT_EOS_INT_STATUS);
+		} else {
+			/* turn on DAC. EOS interrupt must be enabled after DAC
+			 * is enabled, so it sounds not good to enable it in
+			 * i915_driver_irq_postinstall()
+			 * wait 12.5ms after DAC is enabled
+			 */
+			msleep(13);
+			temp = I915_READ(PORT_HOTPLUG_STAT);
+			if (temp & CRT_EOS_INT_STATUS)
+				I915_WRITE(PORT_HOTPLUG_STAT,
+					CRT_EOS_INT_STATUS);
+			temp = I915_READ(PORT_HOTPLUG_EN);
+			temp |= CRT_EOS_INT_EN;
+			I915_WRITE(PORT_HOTPLUG_EN, temp);
+		}
+	}
 }
 
 static int intel_crt_mode_valid(struct drm_connector *connector,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 748ed50..0227b16 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -38,6 +38,7 @@
 
 bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
 static void intel_update_watermarks(struct drm_device *dev);
+static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule);
 
 typedef struct {
     /* given values */
@@ -67,6 +68,8 @@ struct intel_limit {
     intel_p2_t	    p2;
     bool (* find_pll)(const intel_limit_t *, struct drm_crtc *,
 		      int, int, intel_clock_t *);
+    bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *,
+			      int, int, intel_clock_t *);
 };
 
 #define I8XX_DOT_MIN		  25000
@@ -261,6 +264,9 @@ static bool
 intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 		    int target, int refclk, intel_clock_t *best_clock);
 static bool
+intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+			    int target, int refclk, intel_clock_t *best_clock);
+static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 			int target, int refclk, intel_clock_t *best_clock);
 static bool
@@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = {
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_SLOW,	.p2_fast = I8XX_P2_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_i8xx_lvds = {
@@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = {
 	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
 		 .p2_slow = I8XX_P2_LVDS_SLOW,	.p2_fast = I8XX_P2_LVDS_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 	
 static const intel_limit_t intel_limits_i9xx_sdvo = {
@@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = {
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_i9xx_lvds = {
@@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = {
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
     /* below parameter and function is for G4X Chipset Family*/
@@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = {
 		 .p2_fast = G4X_P2_SDVO_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_hdmi = {
@@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = {
 		 .p2_fast = G4X_P2_HDMI_DAC_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
@@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
 		 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
@@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
 		 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
 	},
 	.find_pll = intel_g4x_find_best_PLL,
+	.find_reduced_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_display_port = {
@@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_igd_sdvo = {
 	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_igd_lvds = {
@@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_igd_lvds = {
 	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_SLOW },
 	.find_pll = intel_find_best_PLL,
+	.find_reduced_pll = intel_find_best_reduced_PLL,
 };
 
 static const intel_limit_t intel_limits_igdng_sdvo = {
@@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 
 	memset (best_clock, 0, sizeof (*best_clock));
 
-	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
-		for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
-			/* m1 is always 0 in IGD */
-			if (clock.m2 >= clock.m1 && !IS_IGD(dev))
-				break;
-			for (clock.n = limit->n.min; clock.n <= limit->n.max;
-			     clock.n++) {
-				for (clock.p1 = limit->p1.min;
-				     clock.p1 <= limit->p1.max; clock.p1++) {
+	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
+		for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
+		     clock.m1++) {
+			for (clock.m2 = limit->m2.min;
+			     clock.m2 <= limit->m2.max; clock.m2++) {
+				/* m1 is always 0 in IGD */
+				if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+					break;
+				for (clock.n = limit->n.min;
+				     clock.n <= limit->n.max; clock.n++) {
 					int this_err;
 
 					intel_clock(dev, refclk, &clock);
@@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 	return (err != target);
 }
 
+
+static bool
+intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
+			    int target, int refclk, intel_clock_t *best_clock)
+
+{
+	struct drm_device *dev = crtc->dev;
+	intel_clock_t clock;
+	int err = target;
+	bool found = false;
+
+	memcpy(&clock, best_clock, sizeof(intel_clock_t));
+
+	for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
+		for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) {
+			/* m1 is always 0 in IGD */
+			if (clock.m2 >= clock.m1 && !IS_IGD(dev))
+				break;
+			for (clock.n = limit->n.min; clock.n <= limit->n.max;
+			     clock.n++) {
+				int this_err;
+
+				intel_clock(dev, refclk, &clock);
+
+				if (!intel_PLL_is_valid(crtc, &clock))
+					continue;
+
+				this_err = abs(clock.dot - target);
+				if (this_err < err) {
+					*best_clock = clock;
+					err = this_err;
+					found = true;
+				}
+			}
+		}
+	}
+
+	return found;
+}
+
 static bool
 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 			int target, int refclk, intel_clock_t *best_clock)
@@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 	max_n = limit->n.max;
 	/* based on hardware requriment prefer smaller n to precision */
 	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
-		/* based on hardware requirment prefere larger m1,m2, p1 */
+		/* based on hardware requirment prefere larger m1,m2 */
 		for (clock.m1 = limit->m1.max;
 		     clock.m1 >= limit->m1.min; clock.m1--) {
 			for (clock.m2 = limit->m2.max;
@@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
 
 	memset(best_clock, 0, sizeof(*best_clock));
 	max_n = limit->n.max;
-	/* based on hardware requriment prefer smaller n to precision */
-	for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
-		/* based on hardware requirment prefere larger m1,m2, p1 */
-		for (clock.m1 = limit->m1.max;
-		     clock.m1 >= limit->m1.min; clock.m1--) {
-			for (clock.m2 = limit->m2.max;
-			     clock.m2 >= limit->m2.min; clock.m2--) {
-				for (clock.p1 = limit->p1.max;
-				     clock.p1 >= limit->p1.min; clock.p1--) {
+	for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
+		/* based on hardware requriment prefer smaller n to precision */
+		for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+			/* based on hardware requirment prefere larger m1,m2 */
+			for (clock.m1 = limit->m1.max;
+			     clock.m1 >= limit->m1.min; clock.m1--) {
+				for (clock.m2 = limit->m2.max;
+				     clock.m2 >= limit->m2.min; clock.m2--) {
 					int this_err;
 
 					intel_clock(dev, refclk, &clock);
@@ -1008,6 +1064,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 			dspcntr &= ~DISPPLANE_TILED;
 	}
 
+	if (IS_IGDNG(dev))
+		/* must disable */
+		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
+
 	I915_WRITE(dspcntr_reg, dspcntr);
 
 	Start = obj_priv->gtt_offset;
@@ -1030,8 +1090,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
 	if (old_fb) {
 		intel_fb = to_intel_framebuffer(old_fb);
+		obj_priv = intel_fb->obj->driver_private;
 		i915_gem_object_unpin(intel_fb->obj);
 	}
+	intel_increase_pllclock(crtc, true);
+
 	mutex_unlock(&dev->struct_mutex);
 
 	if (!dev->primary->master)
@@ -1581,6 +1644,8 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
 	else
 		i9xx_crtc_dpms(crtc, mode);
 
+	intel_crtc->dpms_mode = mode;
+
 	if (!dev->primary->master)
 		return;
 
@@ -1603,8 +1668,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
 		DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
 		break;
 	}
-
-	intel_crtc->dpms_mode = mode;
 }
 
 static void intel_crtc_prepare (struct drm_crtc *crtc)
@@ -2054,6 +2117,18 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane)
 	return size;
 }
 
+static void g4x_update_wm(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 fw_blc_self = I915_READ(FW_BLC_SELF);
+
+	if (i915_powersave)
+		fw_blc_self |= FW_BLC_SELF_EN;
+	else
+		fw_blc_self &= ~FW_BLC_SELF_EN;
+	I915_WRITE(FW_BLC_SELF, fw_blc_self);
+}
+
 static void i965_update_wm(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2105,7 +2180,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
 	cwm = 2;
 
 	/* Calc sr entries for one plane configs */
-	if (sr_hdisplay && (!planea_clock || !planeb_clock)) {
+	if (HAS_FW_BLC(dev) && sr_hdisplay &&
+	    (!planea_clock || !planeb_clock)) {
 		/* self-refresh has much higher latency */
 		const static int sr_latency_ns = 6000;
 
@@ -2120,8 +2196,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock,
 		srwm = total_size - sr_entries;
 		if (srwm < 0)
 			srwm = 1;
-		if (IS_I9XX(dev))
-			I915_WRITE(FW_BLC_SELF, (srwm & 0x3f));
+		I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f));
 	}
 
 	DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n",
@@ -2195,9 +2270,6 @@ static void intel_update_watermarks(struct drm_device *dev)
 	unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
 	int enabled = 0, pixel_size = 0;
 
-	if (DSPARB_HWCONTROL(dev))
-		return;
-
 	/* Get the clock config from both planes */
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		intel_crtc = to_intel_crtc(crtc);
@@ -2230,7 +2302,9 @@ static void intel_update_watermarks(struct drm_device *dev)
 	else if (IS_IGD(dev))
 		igd_disable_cxsr(dev);
 
-	if (IS_I965G(dev))
+	if (IS_G4X(dev))
+		g4x_update_wm(dev);
+	else if (IS_I965G(dev))
 		i965_update_wm(dev);
 	else if (IS_I9XX(dev) || IS_MOBILE(dev))
 		i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay,
@@ -2264,9 +2338,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
 	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
 	int refclk, num_outputs = 0;
-	intel_clock_t clock;
-	u32 dpll = 0, fp = 0, dspcntr, pipeconf;
-	bool ok, is_sdvo = false, is_dvo = false;
+	intel_clock_t clock, reduced_clock;
+	u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
+	bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
 	bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
 	bool is_edp = false;
 	struct drm_mode_config *mode_config = &dev->mode_config;
@@ -2349,6 +2423,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
+	if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) {
+		memcpy(&reduced_clock, &clock, sizeof(intel_clock_t));
+		has_reduced_clock = limit->find_reduced_pll(limit, crtc,
+							    (adjusted_mode->clock*3/4),
+							    refclk,
+							    &reduced_clock);
+	}
+
 	/* SDVO TV has fixed PLL values depend on its clock range,
 	   this mirrors vbios setting. */
 	if (is_sdvo && is_tv) {
@@ -2394,10 +2476,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 				  link_bw, &m_n);
 	}
 
-	if (IS_IGD(dev))
+	if (IS_IGD(dev)) {
 		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
-	else
+		if (has_reduced_clock)
+			fp2 = (1 << reduced_clock.n) << 16 |
+				reduced_clock.m1 << 8 | reduced_clock.m2;
+	} else {
 		fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
+		if (has_reduced_clock)
+			fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
+				reduced_clock.m2;
+	}
 
 	if (!IS_IGDNG(dev))
 		dpll = DPLL_VGA_MODE_DIS;
@@ -2426,6 +2515,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 			/* also FPA1 */
 			if (IS_IGDNG(dev))
 				dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+			if (IS_G4X(dev) && has_reduced_clock)
+				dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
 		}
 		switch (clock.p2) {
 		case 5:
@@ -2573,6 +2664,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 		udelay(150);
 	}
 
+	if (is_lvds && has_reduced_clock && i915_powersave) {
+		I915_WRITE(fp_reg + 4, fp2);
+		intel_crtc->lowfreq_avail = true;
+		if (HAS_PIPE_CXSR(dev)) {
+			DRM_DEBUG("enabling CxSR downclocking\n");
+			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
+		}
+	} else {
+		I915_WRITE(fp_reg + 4, fp);
+		intel_crtc->lowfreq_avail = false;
+		if (HAS_PIPE_CXSR(dev)) {
+			DRM_DEBUG("disabling CxSR downclocking\n");
+			pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
+		}
+	}
+
 	I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
 		   ((adjusted_mode->crtc_htotal - 1) << 16));
 	I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
@@ -2616,6 +2723,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
 
 	intel_wait_for_vblank(dev);
 
+	if (IS_IGDNG(dev)) {
+		/* enable address swizzle for tiling buffer */
+		temp = I915_READ(DISP_ARB_CTL);
+		I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING);
+	}
+
 	I915_WRITE(dspcntr_reg, dspcntr);
 
 	/* Flush the plane changes */
@@ -2769,10 +2882,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_framebuffer *intel_fb;
 	int pipe = intel_crtc->pipe;
 	uint32_t temp = 0;
 	uint32_t adder;
 
+	if (crtc->fb) {
+		intel_fb = to_intel_framebuffer(crtc->fb);
+		intel_mark_busy(dev, intel_fb->obj);
+	}
+
 	if (x < 0) {
 		temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
 		x = -x;
@@ -3070,12 +3189,319 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
 	return mode;
 }
 
+#define GPU_IDLE_TIMEOUT 500 /* ms */
+
+/* When this timer fires, we've been idle for awhile */
+static void intel_gpu_idle_timer(unsigned long arg)
+{
+	struct drm_device *dev = (struct drm_device *)arg;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	DRM_DEBUG("idle timer fired, downclocking\n");
+
+	dev_priv->busy = false;
+
+	queue_work(dev_priv->wq, &dev_priv->idle_work);
+}
+
+void intel_increase_renderclock(struct drm_device *dev, bool schedule)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (IS_IGDNG(dev))
+		return;
+
+	if (!dev_priv->render_reclock_avail) {
+		DRM_DEBUG("not reclocking render clock\n");
+		return;
+	}
+
+	/* Restore render clock frequency to original value */
+	if (IS_G4X(dev) || IS_I9XX(dev))
+		pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock);
+	else if (IS_I85X(dev))
+		pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock);
+	DRM_DEBUG("increasing render clock frequency\n");
+
+	/* Schedule downclock */
+	if (schedule)
+		mod_timer(&dev_priv->idle_timer, jiffies +
+			  msecs_to_jiffies(GPU_IDLE_TIMEOUT));
+}
+
+void intel_decrease_renderclock(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+
+	if (IS_IGDNG(dev))
+		return;
+
+	if (!dev_priv->render_reclock_avail) {
+		DRM_DEBUG("not reclocking render clock\n");
+		return;
+	}
+
+	if (IS_G4X(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK;
+		gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I965G(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~I965_GC_RENDER_CLOCK_MASK;
+		gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I945G(dev) || IS_I945GM(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~I945_GC_RENDER_CLOCK_MASK;
+		gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I915G(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~I915_GC_RENDER_CLOCK_MASK;
+		gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	} else if (IS_I85X(dev)) {
+		u16 hpllcc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, HPLLCC, &hpllcc);
+
+		/* Up to maximum... */
+		hpllcc &= ~GC_CLOCK_CONTROL_MASK;
+		hpllcc |= GC_CLOCK_133_200;
+
+		pci_write_config_word(dev->pdev, HPLLCC, hpllcc);
+	}
+	DRM_DEBUG("decreasing render clock frequency\n");
+}
+
+/* Note that no increase function is needed for this - increase_renderclock()
+ *  will also rewrite these bits
+ */
+void intel_decrease_displayclock(struct drm_device *dev)
+{
+	if (IS_IGDNG(dev))
+		return;
+
+	if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) ||
+	    IS_I915GM(dev)) {
+		u16 gcfgc;
+
+		/* Adjust render clock... */
+		pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
+
+		/* Down to minimum... */
+		gcfgc &= ~0xf0;
+		gcfgc |= 0x80;
+
+		pci_write_config_word(dev->pdev, GCFGC, gcfgc);
+	}
+}
+
+#define CRTC_IDLE_TIMEOUT 1000 /* ms */
+
+static void intel_crtc_idle_timer(unsigned long arg)
+{
+	struct intel_crtc *intel_crtc = (struct intel_crtc *)arg;
+	struct drm_crtc *crtc = &intel_crtc->base;
+	drm_i915_private_t *dev_priv = crtc->dev->dev_private;
+
+	DRM_DEBUG("idle timer fired, downclocking\n");
+
+	intel_crtc->busy = false;
+
+	queue_work(dev_priv->wq, &dev_priv->idle_work);
+}
+
+static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule)
+{
+	struct drm_device *dev = crtc->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+	int dpll = I915_READ(dpll_reg);
+
+	if (IS_IGDNG(dev))
+		return;
+
+	if (!dev_priv->lvds_downclock_avail)
+		return;
+
+	if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) {
+		DRM_DEBUG("upclocking LVDS\n");
+
+		/* Unlock panel regs */
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
+
+		dpll &= ~DISPLAY_RATE_SELECT_FPA1;
+		I915_WRITE(dpll_reg, dpll);
+		dpll = I915_READ(dpll_reg);
+		intel_wait_for_vblank(dev);
+		dpll = I915_READ(dpll_reg);
+		if (dpll & DISPLAY_RATE_SELECT_FPA1)
+			DRM_DEBUG("failed to upclock LVDS!\n");
+
+		/* ...and lock them again */
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
+	}
+
+	/* Schedule downclock */
+	if (schedule)
+		mod_timer(&intel_crtc->idle_timer, jiffies +
+			  msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
+}
+
+static void intel_decrease_pllclock(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+	int dpll = I915_READ(dpll_reg);
+
+	if (IS_IGDNG(dev))
+		return;
+
+	if (!dev_priv->lvds_downclock_avail)
+		return;
+
+	/*
+	 * Since this is called by a timer, we should never get here in
+	 * the manual case.
+	 */
+	if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) {
+		DRM_DEBUG("downclocking LVDS\n");
+
+		/* Unlock panel regs */
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16));
+
+		dpll |= DISPLAY_RATE_SELECT_FPA1;
+		I915_WRITE(dpll_reg, dpll);
+		dpll = I915_READ(dpll_reg);
+		intel_wait_for_vblank(dev);
+		dpll = I915_READ(dpll_reg);
+		if (!(dpll & DISPLAY_RATE_SELECT_FPA1))
+			DRM_DEBUG("failed to downclock LVDS!\n");
+
+		/* ...and lock them again */
+		I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3);
+	}
+
+}
+
+/**
+ * intel_idle_update - adjust clocks for idleness
+ * @work: work struct
+ *
+ * Either the GPU or display (or both) went idle.  Check the busy status
+ * here and adjust the CRTC and GPU clocks as necessary.
+ */
+static void intel_idle_update(struct work_struct *work)
+{
+	drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+						    idle_work);
+	struct drm_device *dev = dev_priv->dev;
+	struct drm_crtc *crtc;
+	struct intel_crtc *intel_crtc;
+
+	if (!i915_powersave)
+		return;
+
+	mutex_lock(&dev->struct_mutex);
+
+	/* GPU isn't processing, downclock it. */
+	if (!dev_priv->busy) {
+		intel_decrease_renderclock(dev);
+		intel_decrease_displayclock(dev);
+	}
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		/* Skip inactive CRTCs */
+		if (!crtc->fb)
+			continue;
+
+		intel_crtc = to_intel_crtc(crtc);
+		if (!intel_crtc->busy)
+			intel_decrease_pllclock(crtc);
+	}
+
+	mutex_unlock(&dev->struct_mutex);
+}
+
+/**
+ * intel_mark_busy - mark the GPU and possibly the display busy
+ * @dev: drm device
+ * @obj: object we're operating on
+ *
+ * Callers can use this function to indicate that the GPU is busy processing
+ * commands.  If @obj matches one of the CRTC objects (i.e. it's a scanout
+ * buffer), we'll also mark the display as busy, so we know to increase its
+ * clock frequency.
+ */
+void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj)
+{
+	drm_i915_private_t *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc = NULL;
+	struct intel_framebuffer *intel_fb;
+	struct intel_crtc *intel_crtc;
+
+	if (!drm_core_check_feature(dev, DRIVER_MODESET))
+		return;
+
+	dev_priv->busy = true;
+	intel_increase_renderclock(dev, true);
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		if (!crtc->fb)
+			continue;
+
+		intel_crtc = to_intel_crtc(crtc);
+		intel_fb = to_intel_framebuffer(crtc->fb);
+		if (intel_fb->obj == obj) {
+			if (!intel_crtc->busy) {
+				/* Non-busy -> busy, upclock */
+				intel_increase_pllclock(crtc, true);
+				intel_crtc->busy = true;
+			} else {
+				/* Busy -> busy, put off timer */
+				mod_timer(&intel_crtc->idle_timer, jiffies +
+					  msecs_to_jiffies(CRTC_IDLE_TIMEOUT));
+			}
+		}
+	}
+}
+
 static void intel_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
-	if (intel_crtc->mode_set.mode)
-		drm_mode_destroy(crtc->dev, intel_crtc->mode_set.mode);
 	drm_crtc_cleanup(crtc);
 	kfree(intel_crtc);
 }
@@ -3122,15 +3548,10 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 	intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
 	drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
 
-	intel_crtc->mode_set.crtc = &intel_crtc->base;
-	intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1);
-	intel_crtc->mode_set.num_connectors = 0;
-
-	if (i915_fbpercrtc) {
+	intel_crtc->busy = false;
 
-
-
-	}
+	setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer,
+		    (unsigned long)intel_crtc);
 }
 
 int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
@@ -3138,30 +3559,26 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data;
-	struct drm_crtc *crtc = NULL;
-	int pipe = -1;
+	struct drm_mode_object *drmmode_obj;
+	struct intel_crtc *crtc;
 
 	if (!dev_priv) {
 		DRM_ERROR("called with no initialization\n");
 		return -EINVAL;
 	}
 
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-		if (crtc->base.id == pipe_from_crtc_id->crtc_id) {
-			pipe = intel_crtc->pipe;
-			break;
-		}
-	}
+	drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
+			DRM_MODE_OBJECT_CRTC);
 
-	if (pipe == -1) {
+	if (!drmmode_obj) {
 		DRM_ERROR("no such CRTC id\n");
 		return -EINVAL;
 	}
 
-	pipe_from_crtc_id->pipe = pipe;
+	crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
+	pipe_from_crtc_id->pipe = crtc->pipe;
 
-       return 0;
+	return 0;
 }
 
 struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
@@ -3362,8 +3779,56 @@ static const struct drm_mode_config_funcs intel_mode_funcs = {
 	.fb_changed = intelfb_probe,
 };
 
+void intel_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * Disable clock gating reported to work incorrectly according to the
+	 * specs, but enable as much else as we can.
+	 */
+	if (IS_G4X(dev)) {
+		uint32_t dspclk_gate;
+		I915_WRITE(RENCLK_GATE_D1, 0);
+		I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
+		       GS_UNIT_CLOCK_GATE_DISABLE |
+		       CL_UNIT_CLOCK_GATE_DISABLE);
+		I915_WRITE(RAMCLK_GATE_D, 0);
+		dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
+			OVRUNIT_CLOCK_GATE_DISABLE |
+			OVCUNIT_CLOCK_GATE_DISABLE;
+		if (IS_GM45(dev))
+			dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
+		I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
+	} else if (IS_I965GM(dev)) {
+		I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
+		I915_WRITE(RENCLK_GATE_D2, 0);
+		I915_WRITE(DSPCLK_GATE_D, 0);
+		I915_WRITE(RAMCLK_GATE_D, 0);
+		I915_WRITE16(DEUC, 0);
+	} else if (IS_I965G(dev)) {
+		I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
+		       I965_RCC_CLOCK_GATE_DISABLE |
+		       I965_RCPB_CLOCK_GATE_DISABLE |
+		       I965_ISC_CLOCK_GATE_DISABLE |
+		       I965_FBC_CLOCK_GATE_DISABLE);
+		I915_WRITE(RENCLK_GATE_D2, 0);
+	} else if (IS_I9XX(dev)) {
+		u32 dstate = I915_READ(D_STATE);
+
+		dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
+			DSTATE_DOT_CLOCK_GATING;
+		I915_WRITE(D_STATE, dstate);
+	} else if (IS_I855(dev) || IS_I865G(dev)) {
+		I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
+	} else if (IS_I830(dev)) {
+		I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
+	}
+}
+
 void intel_modeset_init(struct drm_device *dev)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	int num_pipe;
 	int i;
 
@@ -3398,15 +3863,47 @@ void intel_modeset_init(struct drm_device *dev)
 	DRM_DEBUG("%d display pipe%s available.\n",
 		  num_pipe, num_pipe > 1 ? "s" : "");
 
+	if (IS_I85X(dev))
+		pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock);
+	else if (IS_I9XX(dev) || IS_G4X(dev))
+		pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock);
+
 	for (i = 0; i < num_pipe; i++) {
 		intel_crtc_init(dev, i);
 	}
 
 	intel_setup_outputs(dev);
+
+	intel_init_clock_gating(dev);
+
+	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
+	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
+		    (unsigned long)dev);
 }
 
 void intel_modeset_cleanup(struct drm_device *dev)
 {
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_crtc *crtc;
+	struct intel_crtc *intel_crtc;
+
+	mutex_lock(&dev->struct_mutex);
+
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+		/* Skip inactive CRTCs */
+		if (!crtc->fb)
+			continue;
+
+		intel_crtc = to_intel_crtc(crtc);
+		intel_increase_pllclock(crtc, false);
+		del_timer_sync(&intel_crtc->idle_timer);
+	}
+
+	intel_increase_renderclock(dev, false);
+	del_timer_sync(&dev_priv->idle_timer);
+
+	mutex_unlock(&dev->struct_mutex);
+
 	drm_mode_config_cleanup(dev);
 }
 
@@ -3420,3 +3917,20 @@ struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
 
 	return &intel_output->enc;
 }
+
+/*
+ * set vga decode state - true == enable VGA decode
+ */
+int intel_modeset_vga_set_state(struct drm_device *dev, bool state)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u16 gmch_ctrl;
+
+	pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl);
+	if (state)
+		gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE;
+	else
+		gmch_ctrl |= INTEL_GMCH_VGA_DISABLE;
+	pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl);
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 26a6227..3ebbbab 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -117,9 +117,9 @@ struct intel_crtc {
 	uint32_t cursor_addr;
 	u8 lut_r[256], lut_g[256], lut_b[256];
 	int dpms_mode;
-	struct intel_framebuffer *fbdev_fb;
-	/* a mode_set for fbdev users on this crtc */
-	struct drm_mode_set mode_set;
+	bool busy; /* is scanout buffer being updated frequently? */
+	struct timer_list idle_timer;
+	bool lowfreq_avail;
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
@@ -138,6 +138,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg);
 extern bool intel_sdvo_init(struct drm_device *dev, int output_device);
 extern void intel_dvo_init(struct drm_device *dev);
 extern void intel_tv_init(struct drm_device *dev);
+extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj);
 extern void intel_lvds_init(struct drm_device *dev);
 extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
@@ -178,4 +179,5 @@ extern int intel_framebuffer_create(struct drm_device *dev,
 				    struct drm_mode_fb_cmd *mode_cmd,
 				    struct drm_framebuffer **fb,
 				    struct drm_gem_object *obj);
+
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index 1d30802..7ba4a23 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -39,339 +39,34 @@
 #include "drmP.h"
 #include "drm.h"
 #include "drm_crtc.h"
+#include "drm_fb_helper.h"
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 
 struct intelfb_par {
-	struct drm_device *dev;
-	struct drm_display_mode *our_mode;
+	struct drm_fb_helper helper;
 	struct intel_framebuffer *intel_fb;
-	int crtc_count;
-	/* crtc currently bound to this */
-	uint32_t crtc_ids[2];
+	struct drm_display_mode *our_mode;
 };
 
-static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			unsigned blue, unsigned transp,
-			struct fb_info *info)
-{
-	struct intelfb_par *par = info->par;
-	struct drm_device *dev = par->dev;
-	struct drm_crtc *crtc;
-	int i;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-		struct drm_mode_set *modeset = &intel_crtc->mode_set;
-		struct drm_framebuffer *fb = modeset->fb;
-
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
-
-		if (i == par->crtc_count)
-			continue;
-
-
-		if (regno > 255)
-			return 1;
-
-		if (fb->depth == 8) {
-			intel_crtc_fb_gamma_set(crtc, red, green, blue, regno);
-			return 0;
-		}
-
-		if (regno < 16) {
-			switch (fb->depth) {
-			case 15:
-				fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
-					((green & 0xf800) >>  6) |
-					((blue & 0xf800) >> 11);
-				break;
-			case 16:
-				fb->pseudo_palette[regno] = (red & 0xf800) |
-					((green & 0xfc00) >>  5) |
-					((blue  & 0xf800) >> 11);
-				break;
-			case 24:
-			case 32:
-				fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
-					(green & 0xff00) |
-					((blue  & 0xff00) >> 8);
-				break;
-			}
-		}
-	}
-	return 0;
-}
-
-static int intelfb_check_var(struct fb_var_screeninfo *var,
-			struct fb_info *info)
-{
-	struct intelfb_par *par = info->par;
-	struct intel_framebuffer *intel_fb = par->intel_fb;
-	struct drm_framebuffer *fb = &intel_fb->base;
-	int depth;
-
-	if (var->pixclock == -1 || !var->pixclock)
-		return -EINVAL;
-
-	/* Need to resize the fb object !!! */
-	if (var->xres > fb->width || var->yres > fb->height) {
-		DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height);
-		DRM_ERROR("Need resizing code.\n");
-		return -EINVAL;
-	}
-
-	switch (var->bits_per_pixel) {
-	case 16:
-		depth = (var->green.length == 6) ? 16 : 15;
-		break;
-	case 32:
-		depth = (var->transp.length > 0) ? 32 : 24;
-		break;
-	default:
-		depth = var->bits_per_pixel;
-		break;
-	}
-
-	switch (depth) {
-	case 8:
-		var->red.offset = 0;
-		var->green.offset = 0;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 0;
-		var->transp.offset = 0;
-		break;
-	case 15:
-		var->red.offset = 10;
-		var->green.offset = 5;
-		var->blue.offset = 0;
-		var->red.length = 5;
-		var->green.length = 5;
-		var->blue.length = 5;
-		var->transp.length = 1;
-		var->transp.offset = 15;
-		break;
-	case 16:
-		var->red.offset = 11;
-		var->green.offset = 5;
-		var->blue.offset = 0;
-		var->red.length = 5;
-		var->green.length = 6;
-		var->blue.length = 5;
-		var->transp.length = 0;
-		var->transp.offset = 0;
-		break;
-	case 24:
-		var->red.offset = 16;
-		var->green.offset = 8;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 0;
-		var->transp.offset = 0;
-		break;
-	case 32:
-		var->red.offset = 16;
-		var->green.offset = 8;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 8;
-		var->transp.offset = 24;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/* this will let fbcon do the mode init */
-/* FIXME: take mode config lock? */
-static int intelfb_set_par(struct fb_info *info)
-{
-	struct intelfb_par *par = info->par;
-	struct drm_device *dev = par->dev;
-	struct fb_var_screeninfo *var = &info->var;
-	int i;
-
-	DRM_DEBUG("%d %d\n", var->xres, var->pixclock);
-
-	if (var->pixclock != -1) {
-
-		DRM_ERROR("PIXEL CLOCK SET\n");
-		return -EINVAL;
-	} else {
-		struct drm_crtc *crtc;
-		int ret;
-
-		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-			struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-			for (i = 0; i < par->crtc_count; i++)
-				if (crtc->base.id == par->crtc_ids[i])
-					break;
-
-			if (i == par->crtc_count)
-				continue;
-
-			if (crtc->fb == intel_crtc->mode_set.fb) {
-				mutex_lock(&dev->mode_config.mutex);
-				ret = crtc->funcs->set_config(&intel_crtc->mode_set);
-				mutex_unlock(&dev->mode_config.mutex);
-				if (ret)
-					return ret;
-			}
-		}
-		return 0;
-	}
-}
-
-static int intelfb_pan_display(struct fb_var_screeninfo *var,
-				struct fb_info *info)
-{
-	struct intelfb_par *par = info->par;
-	struct drm_device *dev = par->dev;
-	struct drm_mode_set *modeset;
-	struct drm_crtc *crtc;
-	struct intel_crtc *intel_crtc;
-	int ret = 0;
-	int i;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
-
-		if (i == par->crtc_count)
-			continue;
-
-		intel_crtc = to_intel_crtc(crtc);
-		modeset = &intel_crtc->mode_set;
-
-		modeset->x = var->xoffset;
-		modeset->y = var->yoffset;
-
-		if (modeset->num_connectors) {
-			mutex_lock(&dev->mode_config.mutex);
-			ret = crtc->funcs->set_config(modeset);
-			mutex_unlock(&dev->mode_config.mutex);
-			if (!ret) {
-				info->var.xoffset = var->xoffset;
-				info->var.yoffset = var->yoffset;
-			}
-		}
-	}
-
-	return ret;
-}
-
-static void intelfb_on(struct fb_info *info)
-{
-	struct intelfb_par *par = info->par;
-	struct drm_device *dev = par->dev;
-	struct drm_crtc *crtc;
-	struct drm_encoder *encoder;
-	int i;
-
-	/*
-	 * For each CRTC in this fb, find all associated encoders
-	 * and turn them off, then turn off the CRTC.
-	 */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
-
-		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-
-		/* Found a CRTC on this fb, now find encoders */
-		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-			if (encoder->crtc == crtc) {
-				struct drm_encoder_helper_funcs *encoder_funcs;
-				encoder_funcs = encoder->helper_private;
-				encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-			}
-		}
-	}
-}
-
-static void intelfb_off(struct fb_info *info, int dpms_mode)
-{
-	struct intelfb_par *par = info->par;
-	struct drm_device *dev = par->dev;
-	struct drm_crtc *crtc;
-	struct drm_encoder *encoder;
-	int i;
-
-	/*
-	 * For each CRTC in this fb, find all associated encoders
-	 * and turn them off, then turn off the CRTC.
-	 */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-
-		for (i = 0; i < par->crtc_count; i++)
-			if (crtc->base.id == par->crtc_ids[i])
-				break;
-
-		/* Found a CRTC on this fb, now find encoders */
-		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-			if (encoder->crtc == crtc) {
-				struct drm_encoder_helper_funcs *encoder_funcs;
-				encoder_funcs = encoder->helper_private;
-				encoder_funcs->dpms(encoder, dpms_mode);
-			}
-		}
-		if (dpms_mode == DRM_MODE_DPMS_OFF)
-			crtc_funcs->dpms(crtc, dpms_mode);
-	}
-}
-
-static int intelfb_blank(int blank, struct fb_info *info)
-{
-	switch (blank) {
-	case FB_BLANK_UNBLANK:
-		intelfb_on(info);
-		break;
-	case FB_BLANK_NORMAL:
-		intelfb_off(info, DRM_MODE_DPMS_STANDBY);
-		break;
-	case FB_BLANK_HSYNC_SUSPEND:
-		intelfb_off(info, DRM_MODE_DPMS_STANDBY);
-		break;
-	case FB_BLANK_VSYNC_SUSPEND:
-		intelfb_off(info, DRM_MODE_DPMS_SUSPEND);
-		break;
-	case FB_BLANK_POWERDOWN:
-		intelfb_off(info, DRM_MODE_DPMS_OFF);
-		break;
-	}
-	return 0;
-}
-
 static struct fb_ops intelfb_ops = {
 	.owner = THIS_MODULE,
-	.fb_check_var = intelfb_check_var,
-	.fb_set_par = intelfb_set_par,
-	.fb_setcolreg = intelfb_setcolreg,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_setcolreg = drm_fb_helper_setcolreg,
 	.fb_fillrect = cfb_fillrect,
 	.fb_copyarea = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_pan_display = intelfb_pan_display,
-	.fb_blank = intelfb_blank,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
 };
 
+static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
+	.gamma_set = intel_crtc_fb_gamma_set,
+};
+
+
 /**
  * Curretly it is assumed that the old framebuffer is reused.
  *
@@ -412,25 +107,10 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(intelfb_resize);
 
-static struct drm_mode_set kernelfb_mode;
-
-static int intelfb_panic(struct notifier_block *n, unsigned long ununsed,
-			 void *panic_str)
-{
-	DRM_ERROR("panic occurred, switching back to text console\n");
-
-	intelfb_restore();
-	return 0;
-}
-
-static struct notifier_block paniced = {
-	.notifier_call = intelfb_panic,
-};
-
 static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
 			  uint32_t fb_height, uint32_t surface_width,
 			  uint32_t surface_height,
-			  struct intel_framebuffer **intel_fb_p)
+			  struct drm_framebuffer **fb_p)
 {
 	struct fb_info *info;
 	struct intelfb_par *par;
@@ -479,7 +159,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
 	list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
 
 	intel_fb = to_intel_framebuffer(fb);
-	*intel_fb_p = intel_fb;
+	*fb_p = fb;
 
 	info = framebuffer_alloc(sizeof(struct intelfb_par), device);
 	if (!info) {
@@ -489,21 +169,19 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
 
 	par = info->par;
 
+	par->helper.funcs = &intel_fb_helper_funcs;
+	par->helper.dev = dev;
+	ret = drm_fb_helper_init_crtc_count(&par->helper, 2,
+					    INTELFB_CONN_LIMIT);
+	if (ret)
+		goto out_unref;
+
 	strcpy(info->fix.id, "inteldrmfb");
-	info->fix.type = FB_TYPE_PACKED_PIXELS;
-	info->fix.visual = FB_VISUAL_TRUECOLOR;
-	info->fix.type_aux = 0;
-	info->fix.xpanstep = 1; /* doing it in hw */
-	info->fix.ypanstep = 1; /* doing it in hw */
-	info->fix.ywrapstep = 0;
-	info->fix.accel = FB_ACCEL_I830;
-	info->fix.type_aux = 0;
 
 	info->flags = FBINFO_DEFAULT;
 
 	info->fbops = &intelfb_ops;
 
-	info->fix.line_length = fb->pitch;
 
 	/* setup aperture base/size for vesafb takeover */
 	info->aperture_base = dev->mode_config.fb_base;
@@ -527,18 +205,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
 
 //	memset(info->screen_base, 0, size);
 
-	info->pseudo_palette = fb->pseudo_palette;
-	info->var.xres_virtual = fb->width;
-	info->var.yres_virtual = fb->height;
-	info->var.bits_per_pixel = fb->bits_per_pixel;
-	info->var.xoffset = 0;
-	info->var.yoffset = 0;
-	info->var.activate = FB_ACTIVATE_NOW;
-	info->var.height = -1;
-	info->var.width = -1;
-
-	info->var.xres = fb_width;
-	info->var.yres = fb_height;
+	drm_fb_helper_fill_fix(info, fb->pitch);
+	drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
 
 	/* FIXME: we really shouldn't expose mmio space at all */
 	info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar);
@@ -550,64 +218,9 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
 	info->pixmap.scan_align = 1;
 
-	switch(fb->depth) {
-	case 8:
-		info->var.red.offset = 0;
-		info->var.green.offset = 0;
-		info->var.blue.offset = 0;
-		info->var.red.length = 8; /* 8bit DAC */
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 0;
-		info->var.transp.length = 0;
-		break;
-	case 15:
-		info->var.red.offset = 10;
-		info->var.green.offset = 5;
-		info->var.blue.offset = 0;
-		info->var.red.length = 5;
-		info->var.green.length = 5;
-		info->var.blue.length = 5;
-		info->var.transp.offset = 15;
-		info->var.transp.length = 1;
-		break;
-	case 16:
-		info->var.red.offset = 11;
-		info->var.green.offset = 5;
-		info->var.blue.offset = 0;
-		info->var.red.length = 5;
-		info->var.green.length = 6;
-		info->var.blue.length = 5;
-		info->var.transp.offset = 0;
-		break;
-	case 24:
-		info->var.red.offset = 16;
-		info->var.green.offset = 8;
-		info->var.blue.offset = 0;
-		info->var.red.length = 8;
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 0;
-		info->var.transp.length = 0;
-		break;
-	case 32:
-		info->var.red.offset = 16;
-		info->var.green.offset = 8;
-		info->var.blue.offset = 0;
-		info->var.red.length = 8;
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 24;
-		info->var.transp.length = 8;
-		break;
-	default:
-		break;
-	}
-
 	fb->fbdev = info;
 
 	par->intel_fb = intel_fb;
-	par->dev = dev;
 
 	/* To allow resizeing without swapping buffers */
 	DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width,
@@ -625,307 +238,12 @@ out:
 	return ret;
 }
 
-static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *crtc)
-{
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	struct intel_framebuffer *intel_fb;
-	struct drm_framebuffer *fb;
-	struct drm_connector *connector;
-	struct fb_info *info;
-	struct intelfb_par *par;
-	struct drm_mode_set *modeset;
-	unsigned int width, height;
-	int new_fb = 0;
-	int ret, i, conn_count;
-
-	if (!drm_helper_crtc_in_use(crtc))
-		return 0;
-
-	if (!crtc->desired_mode)
-		return 0;
-
-	width = crtc->desired_mode->hdisplay;
-	height = crtc->desired_mode->vdisplay;
-
-	/* is there an fb bound to this crtc already */
-	if (!intel_crtc->mode_set.fb) {
-		ret = intelfb_create(dev, width, height, width, height, &intel_fb);
-		if (ret)
-			return -EINVAL;
-		new_fb = 1;
-	} else {
-		fb = intel_crtc->mode_set.fb;
-		intel_fb = to_intel_framebuffer(fb);
-		if ((intel_fb->base.width < width) || (intel_fb->base.height < height))
-			return -EINVAL;
-	}
-
-	info = intel_fb->base.fbdev;
-	par = info->par;
-
-	modeset = &intel_crtc->mode_set;
-	modeset->fb = &intel_fb->base;
-	conn_count = 0;
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (connector->encoder)
-			if (connector->encoder->crtc == modeset->crtc) {
-				modeset->connectors[conn_count] = connector;
-				conn_count++;
-				if (conn_count > INTELFB_CONN_LIMIT)
-					BUG();
-			}
-	}
-
-	for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
-		modeset->connectors[i] = NULL;
-
-	par->crtc_ids[0] = crtc->base.id;
-
-	modeset->num_connectors = conn_count;
-	if (modeset->crtc->desired_mode) {
-		if (modeset->mode)
-			drm_mode_destroy(dev, modeset->mode);
-		modeset->mode = drm_mode_duplicate(dev,
-						   modeset->crtc->desired_mode);
-	}
-
-	par->crtc_count = 1;
-
-	if (new_fb) {
-		info->var.pixclock = -1;
-		if (register_framebuffer(info) < 0)
-			return -EINVAL;
-	} else
-		intelfb_set_par(info);
-
-	DRM_INFO("fb%d: %s frame buffer device\n", info->node,
-	       info->fix.id);
-
-	/* Switch back to kernel console on panic */
-	kernelfb_mode = *modeset;
-	atomic_notifier_chain_register(&panic_notifier_list, &paniced);
-	DRM_DEBUG("registered panic notifier\n");
-
-	return 0;
-}
-
-static int intelfb_multi_fb_probe(struct drm_device *dev)
-{
-
-	struct drm_crtc *crtc;
-	int ret = 0;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		ret = intelfb_multi_fb_probe_crtc(dev, crtc);
-		if (ret)
-			return ret;
-	}
-	return ret;
-}
-
-static int intelfb_single_fb_probe(struct drm_device *dev)
-{
-	struct drm_crtc *crtc;
-	struct drm_connector *connector;
-	unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
-	unsigned int surface_width = 0, surface_height = 0;
-	int new_fb = 0;
-	int crtc_count = 0;
-	int ret, i, conn_count = 0;
-	struct intel_framebuffer *intel_fb;
-	struct fb_info *info;
-	struct intelfb_par *par;
-	struct drm_mode_set *modeset = NULL;
-
-	DRM_DEBUG("\n");
-
-	/* Get a count of crtcs now in use and new min/maxes width/heights */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		if (!drm_helper_crtc_in_use(crtc))
-			continue;
-
-		crtc_count++;
-		if (!crtc->desired_mode)
-			continue;
-
-		/* Smallest mode determines console size... */
-		if (crtc->desired_mode->hdisplay < fb_width)
-			fb_width = crtc->desired_mode->hdisplay;
-
-		if (crtc->desired_mode->vdisplay < fb_height)
-			fb_height = crtc->desired_mode->vdisplay;
-
-		/* ... but largest for memory allocation dimensions */
-		if (crtc->desired_mode->hdisplay > surface_width)
-			surface_width = crtc->desired_mode->hdisplay;
-
-		if (crtc->desired_mode->vdisplay > surface_height)
-			surface_height = crtc->desired_mode->vdisplay;
-	}
-
-	if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
-		/* hmm everyone went away - assume VGA cable just fell out
-		   and will come back later. */
-		DRM_DEBUG("no CRTCs available?\n");
-		return 0;
-	}
-
-//fail
-	/* Find the fb for our new config */
-	if (list_empty(&dev->mode_config.fb_kernel_list)) {
-		DRM_DEBUG("creating new fb (console size %dx%d, "
-			  "buffer size %dx%d)\n", fb_width, fb_height,
-			  surface_width, surface_height);
-		ret = intelfb_create(dev, fb_width, fb_height, surface_width,
-				     surface_height, &intel_fb);
-		if (ret)
-			return -EINVAL;
-		new_fb = 1;
-	} else {
-		struct drm_framebuffer *fb;
-
-		fb = list_first_entry(&dev->mode_config.fb_kernel_list,
-				      struct drm_framebuffer, filp_head);
-		intel_fb = to_intel_framebuffer(fb);
-
-		/* if someone hotplugs something bigger than we have already
-		 * allocated, we are pwned.  As really we can't resize an
-		 * fbdev that is in the wild currently due to fbdev not really
-		 * being designed for the lower layers moving stuff around
-		 * under it.
-		 * - so in the grand style of things - punt.
-		 */
-		if ((fb->width < surface_width) ||
-		    (fb->height < surface_height)) {
-			DRM_ERROR("fb not large enough for console\n");
-			return -EINVAL;
-		}
-	}
-// fail
-
-	info = intel_fb->base.fbdev;
-	par = info->par;
-
-	crtc_count = 0;
-	/*
-	 * For each CRTC, set up the connector list for the CRTC's mode
-	 * set configuration.
-	 */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-
-		modeset = &intel_crtc->mode_set;
-		modeset->fb = &intel_fb->base;
-		conn_count = 0;
-		list_for_each_entry(connector, &dev->mode_config.connector_list,
-				    head) {
-			if (!connector->encoder)
-				continue;
-
-			if(connector->encoder->crtc == modeset->crtc) {
-				modeset->connectors[conn_count++] = connector;
-				if (conn_count > INTELFB_CONN_LIMIT)
-					BUG();
-			}
-		}
-
-		/* Zero out remaining connector pointers */
-		for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
-			modeset->connectors[i] = NULL;
-
-		par->crtc_ids[crtc_count++] = crtc->base.id;
-
-		modeset->num_connectors = conn_count;
-		if (modeset->crtc->desired_mode) {
-			if (modeset->mode)
-				drm_mode_destroy(dev, modeset->mode);
-			modeset->mode = drm_mode_duplicate(dev,
-							   modeset->crtc->desired_mode);
-		}
-	}
-	par->crtc_count = crtc_count;
-
-	if (new_fb) {
-		info->var.pixclock = -1;
-		if (register_framebuffer(info) < 0)
-			return -EINVAL;
-	} else
-		intelfb_set_par(info);
-
-	DRM_INFO("fb%d: %s frame buffer device\n", info->node,
-	       info->fix.id);
-
-	/* Switch back to kernel console on panic */
-	kernelfb_mode = *modeset;
-	atomic_notifier_chain_register(&panic_notifier_list, &paniced);
-	DRM_DEBUG("registered panic notifier\n");
-
-	return 0;
-}
-
-/**
- * intelfb_restore - restore the framebuffer console (kernel) config
- *
- * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
- */
-void intelfb_restore(void)
-{
-	int ret;
-	if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) {
-		DRM_ERROR("Failed to restore crtc configuration: %d\n",
-			  ret);
-	}
-}
-
-static void intelfb_restore_work_fn(struct work_struct *ignored)
-{
-	intelfb_restore();
-}
-static DECLARE_WORK(intelfb_restore_work, intelfb_restore_work_fn);
-
-static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3)
-{
-        schedule_work(&intelfb_restore_work);
-}
-
-static struct sysrq_key_op sysrq_intelfb_restore_op = {
-        .handler = intelfb_sysrq,
-        .help_msg = "force-fb(V)",
-        .action_msg = "Restore framebuffer console",
-};
-
 int intelfb_probe(struct drm_device *dev)
 {
 	int ret;
 
 	DRM_DEBUG("\n");
-
-	/* something has changed in the lower levels of hell - deal with it
-	   here */
-
-	/* two modes : a) 1 fb to rule all crtcs.
-	               b) one fb per crtc.
-	   two actions 1) new connected device
-	               2) device removed.
-	   case a/1 : if the fb surface isn't big enough - resize the surface fb.
-	              if the fb size isn't big enough - resize fb into surface.
-		      if everything big enough configure the new crtc/etc.
-	   case a/2 : undo the configuration
-	              possibly resize down the fb to fit the new configuration.
-           case b/1 : see if it is on a new crtc - setup a new fb and add it.
-	   case b/2 : teardown the new fb.
-	*/
-
-	/* mode a first */
-	/* search for an fb */
-	if (i915_fbpercrtc == 1) {
-		ret = intelfb_multi_fb_probe(dev);
-	} else {
-		ret = intelfb_single_fb_probe(dev);
-	}
-
-	register_sysrq_key('v', &sysrq_intelfb_restore_op);
-
+	ret = drm_fb_helper_single_fb_probe(dev, intelfb_create);
 	return ret;
 }
 EXPORT_SYMBOL(intelfb_probe);
@@ -940,13 +258,14 @@ int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
 	info = fb->fbdev;
 
 	if (info) {
+		struct intelfb_par *par = info->par;
 		unregister_framebuffer(info);
 		iounmap(info->screen_base);
+		if (info->par)
+			drm_fb_helper_free(&par->helper);
 		framebuffer_release(info);
 	}
 
-	atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
-	memset(&kernelfb_mode, 0, sizeof(struct drm_mode_set));
 	return 0;
 }
 EXPORT_SYMBOL(intelfb_remove);
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
index 62b8bea..c7eab72 100644
--- a/drivers/gpu/drm/i915/intel_i2c.c
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -42,11 +42,11 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable)
 	if (!IS_IGD(dev))
 		return;
 	if (enable)
-		I915_WRITE(CG_2D_DIS,
-			I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE);
+		I915_WRITE(DSPCLK_GATE_D,
+			I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE);
 	else
-		I915_WRITE(CG_2D_DIS,
-			I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE));
+		I915_WRITE(DSPCLK_GATE_D,
+			I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE));
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 8df02ef..dafc0da 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -38,16 +38,6 @@
 #include "i915_drv.h"
 #include <linux/acpi.h>
 
-#define I915_LVDS "i915_lvds"
-
-/*
- * the following four scaling options are defined.
- * #define DRM_MODE_SCALE_NON_GPU	0
- * #define DRM_MODE_SCALE_FULLSCREEN	1
- * #define DRM_MODE_SCALE_NO_SCALE	2
- * #define DRM_MODE_SCALE_ASPECT	3
- */
-
 /* Private structure for the integrated LVDS support */
 struct intel_lvds_priv {
 	int fitting_mode;
@@ -336,7 +326,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
 	I915_WRITE(BCLRPAT_B, 0);
 
 	switch (lvds_priv->fitting_mode) {
-	case DRM_MODE_SCALE_NO_SCALE:
+	case DRM_MODE_SCALE_CENTER:
 		/*
 		 * For centered modes, we have to calculate border widths &
 		 * heights and modify the values programmed into the CRTC.
@@ -672,9 +662,8 @@ static int intel_lvds_set_property(struct drm_connector *connector,
 				connector->encoder) {
 		struct drm_crtc *crtc = connector->encoder->crtc;
 		struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
-		if (value == DRM_MODE_SCALE_NON_GPU) {
-			DRM_DEBUG_KMS(I915_LVDS,
-					"non_GPU property is unsupported\n");
+		if (value == DRM_MODE_SCALE_NONE) {
+			DRM_DEBUG_KMS("no scaling not supported\n");
 			return 0;
 		}
 		if (lvds_priv->fitting_mode == value) {
@@ -731,8 +720,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
 
 static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
 {
-	DRM_DEBUG_KMS(I915_LVDS,
-		      "Skipping LVDS initialization for %s\n", id->ident);
+	DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident);
 	return 1;
 }
 
@@ -1027,7 +1015,7 @@ out:
 	return;
 
 failed:
-	DRM_DEBUG_KMS(I915_LVDS, "No LVDS modes found, disabling.\n");
+	DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
 	if (intel_output->ddc_bus)
 		intel_i2c_destroy(intel_output->ddc_bus);
 	drm_connector_cleanup(connector);
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index d3b74ba..0bf28ef 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -37,7 +37,19 @@
 #include "intel_sdvo_regs.h"
 
 #undef SDVO_DEBUG
-#define I915_SDVO	"i915_sdvo"
+
+static char *tv_format_names[] = {
+	"NTSC_M"   , "NTSC_J"  , "NTSC_443",
+	"PAL_B"    , "PAL_D"   , "PAL_G"   ,
+	"PAL_H"    , "PAL_I"   , "PAL_M"   ,
+	"PAL_N"    , "PAL_NC"  , "PAL_60"  ,
+	"SECAM_B"  , "SECAM_D" , "SECAM_G" ,
+	"SECAM_K"  , "SECAM_K1", "SECAM_L" ,
+	"SECAM_60"
+};
+
+#define TV_FORMAT_NUM  (sizeof(tv_format_names) / sizeof(*tv_format_names))
+
 struct intel_sdvo_priv {
 	u8 slave_addr;
 
@@ -71,6 +83,15 @@ struct intel_sdvo_priv {
 	 */
 	bool is_tv;
 
+	/* This is for current tv format name */
+	char *tv_format_name;
+
+	/* This contains all current supported TV format */
+	char *tv_format_supported[TV_FORMAT_NUM];
+	int   format_supported_num;
+	struct drm_property *tv_format_property;
+	struct drm_property *tv_format_name_property[TV_FORMAT_NUM];
+
 	/**
 	 * This is set if we treat the device as HDMI, instead of DVI.
 	 */
@@ -97,14 +118,6 @@ struct intel_sdvo_priv {
 	 */
 	struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions;
 
-	/**
-	 * Current selected TV format.
-	 *
-	 * This is stored in the same structure that's passed to the device, for
-	 * convenience.
-	 */
-	struct intel_sdvo_tv_format tv_format;
-
 	/*
 	 * supported encoding mode, used to determine whether HDMI is
 	 * supported
@@ -114,6 +127,9 @@ struct intel_sdvo_priv {
 	/* DDC bus used by this SDVO output */
 	uint8_t ddc_bus;
 
+	/* Mac mini hack -- use the same DDC as the analog connector */
+	struct i2c_adapter *analog_ddc_bus;
+
 	int save_sdvo_mult;
 	u16 save_active_outputs;
 	struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
@@ -188,7 +204,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
 		return true;
 	}
 
-	DRM_DEBUG("i2c transfer returned %d\n", ret);
+	DRM_DEBUG_KMS("i2c transfer returned %d\n", ret);
 	return false;
 }
 
@@ -298,7 +314,7 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
 	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 	int i;
 
-	DRM_DEBUG_KMS(I915_SDVO, "%s: W: %02X ",
+	DRM_DEBUG_KMS("%s: W: %02X ",
 				SDVO_NAME(sdvo_priv), cmd);
 	for (i = 0; i < args_len; i++)
 		DRM_LOG_KMS("%02X ", ((u8 *)args)[i]);
@@ -351,7 +367,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
 	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 	int i;
 
-	DRM_DEBUG_KMS(I915_SDVO, "%s: R: ", SDVO_NAME(sdvo_priv));
+	DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
 	for (i = 0; i < response_len; i++)
 		DRM_LOG_KMS("%02X ", ((u8 *)response)[i]);
 	for (; i < 8; i++)
@@ -668,10 +684,10 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
 	status = intel_sdvo_read_response(intel_output, &response, 1);
 
 	if (status != SDVO_CMD_STATUS_SUCCESS) {
-		DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
+		DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
 		return SDVO_CLOCK_RATE_MULT_1X;
 	} else {
-		DRM_DEBUG("Current clock rate multiplier: %d\n", response);
+		DRM_DEBUG_KMS("Current clock rate multiplier: %d\n", response);
 	}
 
 	return response;
@@ -945,23 +961,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
 
 static void intel_sdvo_set_tv_format(struct intel_output *output)
 {
+
+	struct intel_sdvo_tv_format format;
 	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
-	struct intel_sdvo_tv_format *format, unset;
-	u8 status;
+	uint32_t format_map, i;
+	uint8_t status;
 
-	format = &sdvo_priv->tv_format;
-	memset(&unset, 0, sizeof(unset));
-	if (memcmp(format, &unset, sizeof(*format))) {
-		DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
-				SDVO_NAME(sdvo_priv));
-		format->ntsc_m = 1;
-		intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format,
-				sizeof(*format));
-		status = intel_sdvo_read_response(output, NULL, 0);
-		if (status != SDVO_CMD_STATUS_SUCCESS)
-			DRM_DEBUG("%s: Failed to set TV format\n",
-					SDVO_NAME(sdvo_priv));
-	}
+	for (i = 0; i < TV_FORMAT_NUM; i++)
+		if (tv_format_names[i] == sdvo_priv->tv_format_name)
+			break;
+
+	format_map = 1 << i;
+	memset(&format, 0, sizeof(format));
+	memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
+			sizeof(format) : sizeof(format_map));
+
+	intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
+			     sizeof(format));
+
+	status = intel_sdvo_read_response(output, NULL, 0);
+	if (status != SDVO_CMD_STATUS_SUCCESS)
+		DRM_DEBUG("%s: Failed to set TV format\n",
+			  SDVO_NAME(sdvo_priv));
 }
 
 static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
@@ -1230,8 +1251,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
 		 * a given it the status is a success, we succeeded.
 		 */
 		if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
-			DRM_DEBUG("First %s output reported failure to sync\n",
-				   SDVO_NAME(sdvo_priv));
+			DRM_DEBUG_KMS("First %s output reported failure to "
+					"sync\n", SDVO_NAME(sdvo_priv));
 		}
 
 		if (0)
@@ -1326,8 +1347,8 @@ static void intel_sdvo_restore(struct drm_connector *connector)
 			intel_wait_for_vblank(dev);
 		status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
 		if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
-			DRM_DEBUG("First %s output reported failure to sync\n",
-				   SDVO_NAME(sdvo_priv));
+			DRM_DEBUG_KMS("First %s output reported failure to "
+					"sync\n", SDVO_NAME(sdvo_priv));
 	}
 
 	intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
@@ -1405,7 +1426,7 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
 	u8 response[2];
 	u8 status;
 	struct intel_output *intel_output;
-	DRM_DEBUG("\n");
+	DRM_DEBUG_KMS("\n");
 
 	if (!connector)
 		return 0;
@@ -1478,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
 	return (caps > 1);
 }
 
+static struct drm_connector *
+intel_find_analog_connector(struct drm_device *dev)
+{
+	struct drm_connector *connector;
+	struct intel_output *intel_output;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		intel_output = to_intel_output(connector);
+		if (intel_output->type == INTEL_OUTPUT_ANALOG)
+			return connector;
+	}
+	return NULL;
+}
+
+static int
+intel_analog_is_connected(struct drm_device *dev)
+{
+	struct drm_connector *analog_connector;
+	analog_connector = intel_find_analog_connector(dev);
+
+	if (!analog_connector)
+		return false;
+
+	if (analog_connector->funcs->detect(analog_connector) ==
+			connector_status_disconnected)
+		return false;
+
+	return true;
+}
+
 enum drm_connector_status
 intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 {
@@ -1488,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 
 	edid = drm_get_edid(&intel_output->base,
 			    intel_output->ddc_bus);
+
+	/* when there is no edid and no monitor is connected with VGA
+	 * port, try to use the CRT ddc to read the EDID for DVI-connector
+	 */
+	if (edid == NULL &&
+	    sdvo_priv->analog_ddc_bus &&
+	    !intel_analog_is_connected(intel_output->base.dev))
+		edid = drm_get_edid(&intel_output->base,
+				    sdvo_priv->analog_ddc_bus);
 	if (edid != NULL) {
 		/* Don't report the output as connected if it's a DVI-I
 		 * connector with a non-digital EDID coming out.
@@ -1516,10 +1576,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 	struct intel_output *intel_output = to_intel_output(connector);
 	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 
-	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
+	intel_sdvo_write_cmd(intel_output,
+			     SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
 	status = intel_sdvo_read_response(intel_output, &response, 2);
 
-	DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8);
+	DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
 
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return connector_status_unknown;
@@ -1540,50 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
 {
 	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	int num_modes;
 
 	/* set the bus switch and get the modes */
-	intel_ddc_get_modes(intel_output);
+	num_modes = intel_ddc_get_modes(intel_output);
 
-#if 0
-	struct drm_device *dev = encoder->dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-	/* Mac mini hack.  On this device, I get DDC through the analog, which
-	 * load-detects as disconnected.  I fail to DDC through the SDVO DDC,
-	 * but it does load-detect as connected.  So, just steal the DDC bits
-	 * from analog when we fail at finding it the right way.
+	/*
+	 * Mac mini hack.  On this device, the DVI-I connector shares one DDC
+	 * link between analog and digital outputs. So, if the regular SDVO
+	 * DDC fails, check to see if the analog output is disconnected, in
+	 * which case we'll look there for the digital DDC data.
 	 */
-	crt = xf86_config->output[0];
-	intel_output = crt->driver_private;
-	if (intel_output->type == I830_OUTPUT_ANALOG &&
-	    crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
-		I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A");
-		edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus);
-		xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true);
-	}
-	if (edid_mon) {
-		xf86OutputSetEDID(output, edid_mon);
-		modes = xf86OutputGetEDIDModes(output);
-	}
-#endif
-}
+	if (num_modes == 0 &&
+	    sdvo_priv->analog_ddc_bus &&
+	    !intel_analog_is_connected(intel_output->base.dev)) {
+		struct i2c_adapter *digital_ddc_bus;
 
-/**
- * This function checks the current TV format, and chooses a default if
- * it hasn't been set.
- */
-static void
-intel_sdvo_check_tv_format(struct intel_output *output)
-{
-	struct intel_sdvo_priv *dev_priv = output->dev_priv;
-	struct intel_sdvo_tv_format format;
-	uint8_t status;
+		/* Switch to the analog ddc bus and try that
+		 */
+		digital_ddc_bus = intel_output->ddc_bus;
+		intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
 
-	intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
-	status = intel_sdvo_read_response(output, &format, sizeof(format));
-	if (status != SDVO_CMD_STATUS_SUCCESS)
-		return;
+		(void) intel_ddc_get_modes(intel_output);
 
-	memcpy(&dev_priv->tv_format, &format, sizeof(format));
+		intel_output->ddc_bus = digital_ddc_bus;
+	}
 }
 
 /*
@@ -1656,17 +1699,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 	struct intel_output *output = to_intel_output(connector);
 	struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
 	struct intel_sdvo_sdtv_resolution_request tv_res;
-	uint32_t reply = 0;
+	uint32_t reply = 0, format_map = 0;
+	int i;
 	uint8_t status;
-	int i = 0;
 
-	intel_sdvo_check_tv_format(output);
 
 	/* Read the list of supported input resolutions for the selected TV
 	 * format.
 	 */
-	memset(&tv_res, 0, sizeof(tv_res));
-	memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res));
+	for (i = 0; i < TV_FORMAT_NUM; i++)
+		if (tv_format_names[i] ==  sdvo_priv->tv_format_name)
+			break;
+
+	format_map = (1 << i);
+	memcpy(&tv_res, &format_map,
+	       sizeof(struct intel_sdvo_sdtv_resolution_request) >
+	       sizeof(format_map) ? sizeof(format_map) :
+	       sizeof(struct intel_sdvo_sdtv_resolution_request));
+
+	intel_sdvo_set_target_output(output, sdvo_priv->controlled_output);
+
 	intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
 			     &tv_res, sizeof(tv_res));
 	status = intel_sdvo_read_response(output, &reply, 3);
@@ -1681,6 +1733,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 			if (nmode)
 				drm_mode_probed_add(connector, nmode);
 		}
+
 }
 
 static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
@@ -1748,17 +1801,62 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
 		intel_i2c_destroy(intel_output->i2c_bus);
 	if (intel_output->ddc_bus)
 		intel_i2c_destroy(intel_output->ddc_bus);
+	if (sdvo_priv->analog_ddc_bus)
+		intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
 
 	if (sdvo_priv->sdvo_lvds_fixed_mode != NULL)
 		drm_mode_destroy(connector->dev,
 				 sdvo_priv->sdvo_lvds_fixed_mode);
 
+	if (sdvo_priv->tv_format_property)
+		drm_property_destroy(connector->dev,
+				     sdvo_priv->tv_format_property);
+
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
 
 	kfree(intel_output);
 }
 
+static int
+intel_sdvo_set_property(struct drm_connector *connector,
+			struct drm_property *property,
+			uint64_t val)
+{
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct drm_encoder *encoder = &intel_output->enc;
+	struct drm_crtc *crtc = encoder->crtc;
+	int ret = 0;
+	bool changed = false;
+
+	ret = drm_connector_property_set_value(connector, property, val);
+	if (ret < 0)
+		goto out;
+
+	if (property == sdvo_priv->tv_format_property) {
+		if (val >= TV_FORMAT_NUM) {
+			ret = -EINVAL;
+			goto out;
+		}
+		if (sdvo_priv->tv_format_name ==
+		    sdvo_priv->tv_format_supported[val])
+			goto out;
+
+		sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val];
+		changed = true;
+	} else {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (changed && crtc)
+		drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
+				crtc->y, crtc->fb);
+out:
+	return ret;
+}
+
 static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
 	.dpms = intel_sdvo_dpms,
 	.mode_fixup = intel_sdvo_mode_fixup,
@@ -1773,6 +1871,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
 	.restore = intel_sdvo_restore,
 	.detect = intel_sdvo_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
+	.set_property = intel_sdvo_set_property,
 	.destroy = intel_sdvo_destroy,
 };
 
@@ -2013,10 +2112,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
 
 		sdvo_priv->controlled_output = 0;
 		memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
-		DRM_DEBUG_KMS(I915_SDVO,
-				"%s: Unknown SDVO output type (0x%02x%02x)\n",
-				  SDVO_NAME(sdvo_priv),
-				  bytes[0], bytes[1]);
+		DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
+			      SDVO_NAME(sdvo_priv),
+			      bytes[0], bytes[1]);
 		ret = false;
 	}
 	intel_output->crtc_mask = (1 << 0) | (1 << 1);
@@ -2029,6 +2127,55 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
 
 }
 
+static void intel_sdvo_tv_create_property(struct drm_connector *connector)
+{
+      struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	struct intel_sdvo_tv_format format;
+	uint32_t format_map, i;
+	uint8_t status;
+
+	intel_sdvo_set_target_output(intel_output,
+				     sdvo_priv->controlled_output);
+
+	intel_sdvo_write_cmd(intel_output,
+			     SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
+	status = intel_sdvo_read_response(intel_output,
+					  &format, sizeof(format));
+	if (status != SDVO_CMD_STATUS_SUCCESS)
+		return;
+
+	memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ?
+	       sizeof(format_map) : sizeof(format));
+
+	if (format_map == 0)
+		return;
+
+	sdvo_priv->format_supported_num = 0;
+	for (i = 0 ; i < TV_FORMAT_NUM; i++)
+		if (format_map & (1 << i)) {
+			sdvo_priv->tv_format_supported
+			[sdvo_priv->format_supported_num++] =
+			tv_format_names[i];
+		}
+
+
+	sdvo_priv->tv_format_property =
+			drm_property_create(
+				connector->dev, DRM_MODE_PROP_ENUM,
+				"mode", sdvo_priv->format_supported_num);
+
+	for (i = 0; i < sdvo_priv->format_supported_num; i++)
+		drm_property_add_enum(
+				sdvo_priv->tv_format_property, i,
+				i, sdvo_priv->tv_format_supported[i]);
+
+	sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0];
+	drm_connector_attach_property(
+			connector, sdvo_priv->tv_format_property, 0);
+
+}
+
 bool intel_sdvo_init(struct drm_device *dev, int output_device)
 {
 	struct drm_connector *connector;
@@ -2066,18 +2213,22 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	/* Read the regs to test if we can talk to the device */
 	for (i = 0; i < 0x40; i++) {
 		if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
-			DRM_DEBUG_KMS(I915_SDVO,
-					"No SDVO device found on SDVO%c\n",
+			DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
 					output_device == SDVOB ? 'B' : 'C');
 			goto err_i2c;
 		}
 	}
 
 	/* setup the DDC bus. */
-	if (output_device == SDVOB)
+	if (output_device == SDVOB) {
 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
-	else
+		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
+						"SDVOB/VGA DDC BUS");
+	} else {
 		intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+		sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
+						"SDVOC/VGA DDC BUS");
+	}
 
 	if (intel_output->ddc_bus == NULL)
 		goto err_i2c;
@@ -2090,7 +2241,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 
 	if (intel_sdvo_output_setup(intel_output,
 				    sdvo_priv->caps.output_flags) != true) {
-		DRM_DEBUG("SDVO output failed to setup on SDVO%c\n",
+		DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
 			  output_device == SDVOB ? 'B' : 'C');
 		goto err_i2c;
 	}
@@ -2111,6 +2262,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
 
 	drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+	if (sdvo_priv->is_tv)
+		intel_sdvo_tv_create_property(connector);
 	drm_sysfs_connector_add(connector);
 
 	intel_sdvo_select_ddc_bus(sdvo_priv);
@@ -2123,7 +2276,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 					       &sdvo_priv->pixel_clock_max);
 
 
-	DRM_DEBUG_KMS(I915_SDVO, "%s device VID/DID: %02X:%02X.%02X, "
+	DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, "
 			"clock range %dMHz - %dMHz, "
 			"input 1: %c, input 2: %c, "
 			"output 1: %c, output 2: %c\n",
@@ -2143,6 +2296,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	return true;
 
 err_i2c:
+	if (sdvo_priv->analog_ddc_bus != NULL)
+		intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
 	if (intel_output->ddc_bus != NULL)
 		intel_i2c_destroy(intel_output->ddc_bus);
 	if (intel_output->i2c_bus != NULL)
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 5b1c9e9..c64eab4 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1437,6 +1437,35 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
 	return type;
 }
 
+/*
+ * Here we set accurate tv format according to connector type
+ * i.e Component TV should not be assigned by NTSC or PAL
+ */
+static void intel_tv_find_better_format(struct drm_connector *connector)
+{
+	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+	const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+	int i;
+
+	if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
+		tv_mode->component_only)
+		return;
+
+
+	for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) {
+		tv_mode = tv_modes + i;
+
+		if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
+			tv_mode->component_only)
+			break;
+	}
+
+	tv_priv->tv_format = tv_mode->name;
+	drm_connector_property_set_value(connector,
+		connector->dev->mode_config.tv_mode_property, i);
+}
+
 /**
  * Detect the TV connection.
  *
@@ -1473,6 +1502,7 @@ intel_tv_detect(struct drm_connector *connector)
 	if (type < 0)
 		return connector_status_disconnected;
 
+	intel_tv_find_better_format(connector);
 	return connector_status_connected;
 }
 
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index 6c67a02..3c917fb 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -444,7 +444,7 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
 {
 	drm_mga_private_t *const dev_priv =
 	    (drm_mga_private_t *) dev->dev_private;
-	unsigned int warp_size = mga_warp_microcode_size(dev_priv);
+	unsigned int warp_size = MGA_WARP_UCODE_SIZE;
 	int err;
 	unsigned offset;
 	const unsigned secondary_size = dma_bs->secondary_bin_count
@@ -619,7 +619,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
 {
 	drm_mga_private_t *const dev_priv =
 	    (drm_mga_private_t *) dev->dev_private;
-	unsigned int warp_size = mga_warp_microcode_size(dev_priv);
+	unsigned int warp_size = MGA_WARP_UCODE_SIZE;
 	unsigned int primary_size;
 	unsigned int bin_count;
 	int err;
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
index 3d264f2..be6c6b9 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -177,7 +177,6 @@ extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
 extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf);
 
 				/* mga_warp.c */
-extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv);
 extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
 extern int mga_warp_init(drm_mga_private_t * dev_priv);
 
diff --git a/drivers/gpu/drm/mga/mga_ucode.h b/drivers/gpu/drm/mga/mga_ucode.h
deleted file mode 100644
index b611e27..0000000
--- a/drivers/gpu/drm/mga/mga_ucode.h
+++ /dev/null
@@ -1,11645 +0,0 @@
-/* mga_ucode.h -- Matrox G200/G400 WARP engine microcode -*- linux-c -*-
- * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com
- *
- * Copyright 1999 Matrox Graphics Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Kernel-based WARP engine management:
- *    Gareth Hughes <gareth@valinux.com>
- */
-
-/*
- * WARP pipes are named according to the functions they perform, where:
- *
- *   - T stands for computation of texture stage 0
- *   - T2 stands for computation of both texture stage 0 and texture stage 1
- *   - G stands for computation of triangle intensity (Gouraud interpolation)
- *   - Z stands for computation of Z buffer interpolation
- *   - S stands for computation of specular highlight
- *   - A stands for computation of the alpha channel
- *   - F stands for computation of vertex fog interpolation
- */
-
-static unsigned char warp_g200_tgz[] = {
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x72, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x60, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x03, 0x80, 0x0A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x57, 0x39, 0x20, 0xE9,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0x2B, 0x32, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0xB3, 0x05,
-	0x00, 0xE0,
-	0x16, 0x28, 0x20, 0xE9,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x1E, 0x2B, 0x20, 0xE9,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x85, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x84, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x82, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x7F, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g200_tgza[] = {
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x7D, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x6B, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2D, 0x44, 0x4C, 0xB6,
-	0x25, 0x44, 0x54, 0xB6,
-
-	0x03, 0x80, 0x2A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x2D, 0x20,
-	0x25, 0x20,
-	0x07, 0xC0, 0x44, 0xC6,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x1F, 0x62, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x3F, 0x3D, 0x5D, 0x9F,
-	0x00, 0xE0,
-	0x07, 0x20,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0xB3, 0x05,
-	0x00, 0xE0,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0x26, 0x1F, 0xDF,
-	0x9D, 0x1F, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x9E, 0x3F, 0x4F, 0xE9,
-
-	0x07, 0x07, 0x1F, 0xAF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x9C, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x57, 0x39, 0x20, 0xE9,
-
-	0x16, 0x28, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0x1E, 0x2B, 0x20, 0xE9,
-	0x2B, 0x32, 0x20, 0xE9,
-
-	0x1C, 0x23, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x7A, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x79, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x77, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x74, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g200_tgzaf[] = {
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x83, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x21, 0x45, 0x80, 0xE8,
-	0x1A, 0x4D, 0x80, 0xE8,
-
-	0x31, 0x55, 0x80, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x6F, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0D, 0x21, 0x1A, 0xB6,
-	0x05, 0x21, 0x31, 0xB6,
-
-	0x2D, 0x44, 0x4C, 0xB6,
-	0x25, 0x44, 0x54, 0xB6,
-
-	0x03, 0x80, 0x2A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x0D, 0x20,
-	0x05, 0x20,
-	0x2F, 0xC0, 0x21, 0xC6,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x07, 0xC0, 0x44, 0xC6,
-
-	0x17, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x2D, 0x20,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0xE0,
-	0x2F, 0x20,
-
-	0x1F, 0x62, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x07, 0x20,
-
-	0x3F, 0x3D, 0x5D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0xB3, 0x05,
-	0x00, 0xE0,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x35, 0x17, 0x4F, 0xE9,
-
-	0x1F, 0x26, 0x1F, 0xDF,
-	0x9D, 0x1F, 0x4F, 0xE9,
-
-	0x9E, 0x3F, 0x4F, 0xE9,
-	0x39, 0x37, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x17, 0xAF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x07, 0x07, 0x1F, 0xAF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x31, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x9C, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x57, 0x39, 0x20, 0xE9,
-
-	0x16, 0x28, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0x1E, 0x2B, 0x20, 0xE9,
-	0x2B, 0x32, 0x20, 0xE9,
-
-	0x1C, 0x23, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x74, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x73, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x71, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6E, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g200_tgzf[] = {
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x7F, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x21, 0x45, 0x80, 0xE8,
-	0x1A, 0x4D, 0x80, 0xE8,
-
-	0x31, 0x55, 0x80, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x6B, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0D, 0x21, 0x1A, 0xB6,
-	0x05, 0x21, 0x31, 0xB6,
-
-	0x03, 0x80, 0x2A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x0D, 0x20,
-	0x05, 0x20,
-	0x2F, 0xC0, 0x21, 0xC6,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x17, 0x50, 0x56, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0xE0,
-	0x2F, 0x20,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0xB3, 0x05,
-	0x00, 0xE0,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x17, 0x26, 0x17, 0xDF,
-	0x35, 0x17, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x39, 0x37, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x17, 0xAF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x31, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x57, 0x39, 0x20, 0xE9,
-
-	0x16, 0x28, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0x1E, 0x2B, 0x20, 0xE9,
-	0x2B, 0x32, 0x20, 0xE9,
-
-	0x1C, 0x23, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x78, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x77, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x75, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x72, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g200_tgzs[] = {
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x8B, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x21, 0x45, 0x80, 0xE8,
-	0x1A, 0x4D, 0x80, 0xE8,
-
-	0x31, 0x55, 0x80, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x77, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2D, 0x21, 0x1A, 0xB0,
-	0x25, 0x21, 0x31, 0xB0,
-
-	0x0D, 0x21, 0x1A, 0xB2,
-	0x05, 0x21, 0x31, 0xB2,
-
-	0x03, 0x80, 0x2A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x2D, 0x20,
-	0x25, 0x20,
-	0x05, 0x20,
-	0x0D, 0x20,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x2F, 0xC0, 0x21, 0xC0,
-
-	0x16, 0x42, 0x56, 0x9F,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x1E, 0x62, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x21, 0x31, 0xB4,
-	0x2D, 0x21, 0x1A, 0xB4,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0x05,
-	0x00, 0xE0,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0xE0,
-	0x2F, 0x20,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x1E, 0x26, 0x1E, 0xDF,
-
-	0xA7, 0x1E, 0x4F, 0xE9,
-	0x17, 0x26, 0x16, 0xDF,
-
-	0x2D, 0x20,
-	0x00, 0xE0,
-	0xA8, 0x3F, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x1E, 0xAF,
-	0x25, 0x20,
-	0x00, 0xE0,
-
-	0xA4, 0x16, 0x4F, 0xE9,
-	0x0F, 0xC0, 0x21, 0xC2,
-
-	0xA6, 0x80, 0x4F, 0xE9,
-	0x1F, 0x62, 0x57, 0x9F,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0xE0,
-	0x8F, 0x20,
-
-	0xA5, 0x37, 0x4F, 0xE9,
-	0x0F, 0x17, 0x0F, 0xAF,
-
-	0x06, 0xC0, 0x21, 0xC4,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0xA3, 0x80, 0x4F, 0xE9,
-
-	0x06, 0x20,
-	0x00, 0xE0,
-	0x1F, 0x26, 0x1F, 0xDF,
-
-	0xA1, 0x1F, 0x4F, 0xE9,
-	0xA2, 0x3F, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x06, 0x06, 0x1F, 0xAF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x57, 0x39, 0x20, 0xE9,
-
-	0x16, 0x28, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0x1E, 0x2B, 0x20, 0xE9,
-	0x2B, 0x32, 0x20, 0xE9,
-
-	0x1C, 0x23, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x6C, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6B, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x69, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g200_tgzsa[] = {
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x8F, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x21, 0x45, 0x80, 0xE8,
-	0x1A, 0x4D, 0x80, 0xE8,
-
-	0x31, 0x55, 0x80, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x7B, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2D, 0x21, 0x1A, 0xB0,
-	0x25, 0x21, 0x31, 0xB0,
-
-	0x0D, 0x21, 0x1A, 0xB2,
-	0x05, 0x21, 0x31, 0xB2,
-
-	0x03, 0x80, 0x2A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x2D, 0x20,
-	0x25, 0x20,
-	0x05, 0x20,
-	0x0D, 0x20,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x2F, 0xC0, 0x21, 0xC0,
-
-	0x16, 0x42, 0x56, 0x9F,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x1E, 0x62, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x21, 0x31, 0xB4,
-	0x2D, 0x21, 0x1A, 0xB4,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0x05,
-	0x00, 0xE0,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0x0D, 0x44, 0x4C, 0xB6,
-	0x05, 0x44, 0x54, 0xB6,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0xE0,
-	0x2F, 0x20,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x1E, 0x26, 0x1E, 0xDF,
-
-	0xA7, 0x1E, 0x4F, 0xE9,
-	0x17, 0x26, 0x16, 0xDF,
-
-	0x2D, 0x20,
-	0x00, 0xE0,
-	0xA8, 0x3F, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x1E, 0xAF,
-	0x25, 0x20,
-	0x00, 0xE0,
-
-	0xA4, 0x16, 0x4F, 0xE9,
-	0x0F, 0xC0, 0x21, 0xC2,
-
-	0xA6, 0x80, 0x4F, 0xE9,
-	0x1F, 0x62, 0x57, 0x9F,
-
-	0x0D, 0x20,
-	0x05, 0x20,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0xE0,
-	0x0F, 0x20,
-
-	0x17, 0x50, 0x56, 0x9F,
-	0xA5, 0x37, 0x4F, 0xE9,
-
-	0x06, 0xC0, 0x21, 0xC4,
-	0x0F, 0x17, 0x0F, 0xAF,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2F, 0xC0, 0x44, 0xC6,
-	0xA3, 0x80, 0x4F, 0xE9,
-
-	0x06, 0x20,
-	0x00, 0xE0,
-	0x1F, 0x26, 0x1F, 0xDF,
-
-	0x17, 0x26, 0x17, 0xDF,
-	0x9D, 0x17, 0x4F, 0xE9,
-
-	0xA1, 0x1F, 0x4F, 0xE9,
-	0xA2, 0x3F, 0x4F, 0xE9,
-
-	0x06, 0x06, 0x1F, 0xAF,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x9E, 0x37, 0x4F, 0xE9,
-	0x2F, 0x17, 0x2F, 0xAF,
-
-	0xA0, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x9C, 0x80, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x57, 0x39, 0x20, 0xE9,
-
-	0x16, 0x28, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0x1E, 0x2B, 0x20, 0xE9,
-	0x2B, 0x32, 0x20, 0xE9,
-
-	0x1C, 0x23, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x68, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x67, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x65, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x62, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g200_tgzsaf[] = {
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x94, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x21, 0x45, 0x80, 0xE8,
-	0x1A, 0x4D, 0x80, 0xE8,
-
-	0x31, 0x55, 0x80, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x80, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2D, 0x21, 0x1A, 0xB0,
-	0x25, 0x21, 0x31, 0xB0,
-
-	0x0D, 0x21, 0x1A, 0xB2,
-	0x05, 0x21, 0x31, 0xB2,
-
-	0x03, 0x80, 0x2A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x2D, 0x20,
-	0x25, 0x20,
-	0x05, 0x20,
-	0x0D, 0x20,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x2F, 0xC0, 0x21, 0xC0,
-
-	0x16, 0x42, 0x56, 0x9F,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x1E, 0x62, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x21, 0x31, 0xB4,
-	0x2D, 0x21, 0x1A, 0xB4,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0x05,
-	0x00, 0xE0,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0x0D, 0x21, 0x1A, 0xB6,
-	0x05, 0x21, 0x31, 0xB6,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0xE0,
-	0x2F, 0x20,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x1E, 0x26, 0x1E, 0xDF,
-
-	0xA7, 0x1E, 0x4F, 0xE9,
-	0x17, 0x26, 0x16, 0xDF,
-
-	0x2D, 0x20,
-	0x00, 0xE0,
-	0xA8, 0x3F, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x1E, 0xAF,
-	0x25, 0x20,
-	0x00, 0xE0,
-
-	0xA4, 0x16, 0x4F, 0xE9,
-	0x0F, 0xC0, 0x21, 0xC2,
-
-	0xA6, 0x80, 0x4F, 0xE9,
-	0x1F, 0x62, 0x57, 0x9F,
-
-	0x0D, 0x20,
-	0x05, 0x20,
-	0x2F, 0xC0, 0x21, 0xC6,
-
-	0x2D, 0x44, 0x4C, 0xB6,
-	0x25, 0x44, 0x54, 0xB6,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0xE0,
-	0x0F, 0x20,
-
-	0x2D, 0x20,
-	0x25, 0x20,
-	0x07, 0xC0, 0x44, 0xC6,
-
-	0x17, 0x50, 0x56, 0x9F,
-	0xA5, 0x37, 0x4F, 0xE9,
-
-	0x06, 0xC0, 0x21, 0xC4,
-	0x0F, 0x17, 0x0F, 0xAF,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1E, 0x62, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x3E, 0x3D, 0x5D, 0x9F,
-	0x00, 0xE0,
-	0x07, 0x20,
-
-	0x2F, 0x20,
-	0x00, 0xE0,
-	0xA3, 0x0F, 0x4F, 0xE9,
-
-	0x06, 0x20,
-	0x00, 0xE0,
-	0x1F, 0x26, 0x1F, 0xDF,
-
-	0x17, 0x26, 0x17, 0xDF,
-	0xA1, 0x1F, 0x4F, 0xE9,
-
-	0x1E, 0x26, 0x1E, 0xDF,
-	0x9D, 0x1E, 0x4F, 0xE9,
-
-	0x35, 0x17, 0x4F, 0xE9,
-	0xA2, 0x3F, 0x4F, 0xE9,
-
-	0x06, 0x06, 0x1F, 0xAF,
-	0x39, 0x37, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x17, 0xAF,
-	0x07, 0x07, 0x1E, 0xAF,
-
-	0xA0, 0x80, 0x4F, 0xE9,
-	0x9E, 0x3E, 0x4F, 0xE9,
-
-	0x31, 0x80, 0x4F, 0xE9,
-	0x9C, 0x80, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x57, 0x39, 0x20, 0xE9,
-
-	0x16, 0x28, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0x1E, 0x2B, 0x20, 0xE9,
-	0x2B, 0x32, 0x20, 0xE9,
-
-	0x1C, 0x23, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x63, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x62, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x60, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x5D, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g200_tgzsf[] = {
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x98, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x81, 0x04,
-	0x89, 0x04,
-	0x01, 0x04,
-	0x09, 0x04,
-
-	0xC9, 0x41, 0xC0, 0xEC,
-	0x11, 0x04,
-	0x00, 0xE0,
-
-	0x41, 0xCC, 0x41, 0xCD,
-	0x49, 0xCC, 0x49, 0xCD,
-
-	0xD1, 0x41, 0xC0, 0xEC,
-	0x51, 0xCC, 0x51, 0xCD,
-
-	0x80, 0x04,
-	0x10, 0x04,
-	0x08, 0x04,
-	0x00, 0xE0,
-
-	0x00, 0xCC, 0xC0, 0xCD,
-	0xD1, 0x49, 0xC0, 0xEC,
-
-	0x8A, 0x1F, 0x20, 0xE9,
-	0x8B, 0x3F, 0x20, 0xE9,
-
-	0x41, 0x3C, 0x41, 0xAD,
-	0x49, 0x3C, 0x49, 0xAD,
-
-	0x10, 0xCC, 0x10, 0xCD,
-	0x08, 0xCC, 0x08, 0xCD,
-
-	0xB9, 0x41, 0x49, 0xBB,
-	0x1F, 0xF0, 0x41, 0xCD,
-
-	0x51, 0x3C, 0x51, 0xAD,
-	0x00, 0x98, 0x80, 0xE9,
-
-	0x8F, 0x80, 0x07, 0xEA,
-	0x24, 0x1F, 0x20, 0xE9,
-
-	0x21, 0x45, 0x80, 0xE8,
-	0x1A, 0x4D, 0x80, 0xE8,
-
-	0x31, 0x55, 0x80, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0x41, 0x49, 0xBD,
-	0x1D, 0x41, 0x51, 0xBD,
-
-	0x2E, 0x41, 0x2A, 0xB8,
-	0x34, 0x53, 0xA0, 0xE8,
-
-	0x15, 0x30,
-	0x1D, 0x30,
-	0x58, 0xE3,
-	0x00, 0xE0,
-
-	0xB5, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x24, 0x43, 0xA0, 0xE8,
-	0x2C, 0x4B, 0xA0, 0xE8,
-
-	0x15, 0x72,
-	0x09, 0xE3,
-	0x00, 0xE0,
-	0x1D, 0x72,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0x97, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x6C, 0x64, 0xC8, 0xEC,
-	0x98, 0xE1,
-	0xB5, 0x05,
-
-	0xBD, 0x05,
-	0x2E, 0x30,
-	0x32, 0xC0, 0xA0, 0xE8,
-
-	0x33, 0xC0, 0xA0, 0xE8,
-	0x74, 0x64, 0xC8, 0xEC,
-
-	0x40, 0x3C, 0x40, 0xAD,
-	0x32, 0x6A,
-	0x2A, 0x30,
-
-	0x20, 0x73,
-	0x33, 0x6A,
-	0x00, 0xE0,
-	0x28, 0x73,
-
-	0x1C, 0x72,
-	0x83, 0xE2,
-	0x7B, 0x80, 0x15, 0xEA,
-
-	0xB8, 0x3D, 0x28, 0xDF,
-	0x30, 0x35, 0x20, 0xDF,
-
-	0x40, 0x30,
-	0x00, 0xE0,
-	0xCC, 0xE2,
-	0x64, 0x72,
-
-	0x25, 0x42, 0x52, 0xBF,
-	0x2D, 0x42, 0x4A, 0xBF,
-
-	0x30, 0x2E, 0x30, 0xDF,
-	0x38, 0x2E, 0x38, 0xDF,
-
-	0x18, 0x1D, 0x45, 0xE9,
-	0x1E, 0x15, 0x45, 0xE9,
-
-	0x2B, 0x49, 0x51, 0xBD,
-	0x00, 0xE0,
-	0x1F, 0x73,
-
-	0x38, 0x38, 0x40, 0xAF,
-	0x30, 0x30, 0x40, 0xAF,
-
-	0x24, 0x1F, 0x24, 0xDF,
-	0x1D, 0x32, 0x20, 0xE9,
-
-	0x2C, 0x1F, 0x2C, 0xDF,
-	0x1A, 0x33, 0x20, 0xE9,
-
-	0xB0, 0x10,
-	0x08, 0xE3,
-	0x40, 0x10,
-	0xB8, 0x10,
-
-	0x26, 0xF0, 0x30, 0xCD,
-	0x2F, 0xF0, 0x38, 0xCD,
-
-	0x2B, 0x80, 0x20, 0xE9,
-	0x2A, 0x80, 0x20, 0xE9,
-
-	0xA6, 0x20,
-	0x88, 0xE2,
-	0x00, 0xE0,
-	0xAF, 0x20,
-
-	0x28, 0x2A, 0x26, 0xAF,
-	0x20, 0x2A, 0xC0, 0xAF,
-
-	0x34, 0x1F, 0x34, 0xDF,
-	0x46, 0x24, 0x46, 0xDF,
-
-	0x28, 0x30, 0x80, 0xBF,
-	0x20, 0x38, 0x80, 0xBF,
-
-	0x47, 0x24, 0x47, 0xDF,
-	0x4E, 0x2C, 0x4E, 0xDF,
-
-	0x4F, 0x2C, 0x4F, 0xDF,
-	0x56, 0x34, 0x56, 0xDF,
-
-	0x28, 0x15, 0x28, 0xDF,
-	0x20, 0x1D, 0x20, 0xDF,
-
-	0x57, 0x34, 0x57, 0xDF,
-	0x00, 0xE0,
-	0x1D, 0x05,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x89, 0xE2,
-	0x2B, 0x30,
-
-	0x3F, 0xC1, 0x1D, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x68,
-	0xBF, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x20, 0xC0, 0x20, 0xAF,
-	0x28, 0x05,
-	0x97, 0x74,
-
-	0x00, 0xE0,
-	0x2A, 0x10,
-	0x16, 0xC0, 0x20, 0xE9,
-
-	0x04, 0x80, 0x10, 0xEA,
-	0x8C, 0xE2,
-	0x95, 0x05,
-
-	0x28, 0xC1, 0x28, 0xAD,
-	0x1F, 0xC1, 0x15, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA8, 0x67,
-	0x9F, 0x6B,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x28, 0xC0, 0x28, 0xAD,
-	0x1D, 0x25,
-	0x20, 0x05,
-
-	0x28, 0x32, 0x80, 0xAD,
-	0x40, 0x2A, 0x40, 0xBD,
-
-	0x1C, 0x80, 0x20, 0xE9,
-	0x20, 0x33, 0x20, 0xAD,
-
-	0x20, 0x73,
-	0x00, 0xE0,
-	0xB6, 0x49, 0x51, 0xBB,
-
-	0x26, 0x2F, 0xB0, 0xE8,
-	0x19, 0x20, 0x20, 0xE9,
-
-	0x35, 0x20, 0x35, 0xDF,
-	0x3D, 0x20, 0x3D, 0xDF,
-
-	0x15, 0x20, 0x15, 0xDF,
-	0x1D, 0x20, 0x1D, 0xDF,
-
-	0x26, 0xD0, 0x26, 0xCD,
-	0x29, 0x49, 0x2A, 0xB8,
-
-	0x26, 0x40, 0x80, 0xBD,
-	0x3B, 0x48, 0x50, 0xBD,
-
-	0x3E, 0x54, 0x57, 0x9F,
-	0x00, 0xE0,
-	0x82, 0xE1,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x26, 0x30,
-	0x29, 0x30,
-	0x48, 0x3C, 0x48, 0xAD,
-
-	0x2B, 0x72,
-	0xC2, 0xE1,
-	0x2C, 0xC0, 0x44, 0xC2,
-
-	0x05, 0x24, 0x34, 0xBF,
-	0x0D, 0x24, 0x2C, 0xBF,
-
-	0x2D, 0x46, 0x4E, 0xBF,
-	0x25, 0x46, 0x56, 0xBF,
-
-	0x20, 0x1D, 0x6F, 0x8F,
-	0x32, 0x3E, 0x5F, 0xE9,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x30,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x33, 0x1E, 0x5F, 0xE9,
-
-	0x05, 0x44, 0x54, 0xB2,
-	0x0D, 0x44, 0x4C, 0xB2,
-
-	0x19, 0xC0, 0xB0, 0xE8,
-	0x34, 0xC0, 0x44, 0xC4,
-
-	0x33, 0x73,
-	0x00, 0xE0,
-	0x3E, 0x62, 0x57, 0x9F,
-
-	0x1E, 0xAF, 0x59, 0x9F,
-	0x00, 0xE0,
-	0x0D, 0x20,
-
-	0x84, 0x3E, 0x58, 0xE9,
-	0x28, 0x1D, 0x6F, 0x8F,
-
-	0x05, 0x20,
-	0x00, 0xE0,
-	0x85, 0x1E, 0x58, 0xE9,
-
-	0x9B, 0x3B, 0x33, 0xDF,
-	0x20, 0x20, 0x42, 0xAF,
-
-	0x30, 0x42, 0x56, 0x9F,
-	0x80, 0x3E, 0x57, 0xE9,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x30, 0x80, 0x5F, 0xE9,
-
-	0x28, 0x28, 0x24, 0xAF,
-	0x81, 0x1E, 0x57, 0xE9,
-
-	0x05, 0x47, 0x57, 0xBF,
-	0x0D, 0x47, 0x4F, 0xBF,
-
-	0x88, 0x80, 0x58, 0xE9,
-	0x1B, 0x29, 0x1B, 0xDF,
-
-	0x30, 0x1D, 0x6F, 0x8F,
-	0x3A, 0x30, 0x4F, 0xE9,
-
-	0x1C, 0x30, 0x26, 0xDF,
-	0x09, 0xE3,
-	0x3B, 0x05,
-
-	0x3E, 0x50, 0x56, 0x9F,
-	0x3B, 0x3F, 0x4F, 0xE9,
-
-	0x1E, 0x8F, 0x51, 0x9F,
-	0x00, 0xE0,
-	0xAC, 0x20,
-
-	0x2D, 0x44, 0x4C, 0xB4,
-	0x2C, 0x1C, 0xC0, 0xAF,
-
-	0x25, 0x44, 0x54, 0xB4,
-	0x00, 0xE0,
-	0xC8, 0x30,
-
-	0x30, 0x46, 0x30, 0xAF,
-	0x1B, 0x1B, 0x48, 0xAF,
-
-	0x00, 0xE0,
-	0x25, 0x20,
-	0x38, 0x2C, 0x4F, 0xE9,
-
-	0x86, 0x80, 0x57, 0xE9,
-	0x38, 0x1D, 0x6F, 0x8F,
-
-	0x28, 0x74,
-	0x00, 0xE0,
-	0x0D, 0x44, 0x4C, 0xB0,
-
-	0x05, 0x44, 0x54, 0xB0,
-	0x2D, 0x20,
-	0x9B, 0x10,
-
-	0x82, 0x3E, 0x57, 0xE9,
-	0x32, 0xF0, 0x1B, 0xCD,
-
-	0x1E, 0xBD, 0x59, 0x9F,
-	0x83, 0x1E, 0x57, 0xE9,
-
-	0x38, 0x47, 0x38, 0xAF,
-	0x34, 0x20,
-	0x2A, 0x30,
-
-	0x00, 0xE0,
-	0x0D, 0x20,
-	0x32, 0x20,
-	0x05, 0x20,
-
-	0x87, 0x80, 0x57, 0xE9,
-	0x1F, 0x54, 0x57, 0x9F,
-
-	0x17, 0x42, 0x56, 0x9F,
-	0x00, 0xE0,
-	0x3B, 0x6A,
-
-	0x3F, 0x8F, 0x51, 0x9F,
-	0x37, 0x1E, 0x4F, 0xE9,
-
-	0x37, 0x32, 0x2A, 0xAF,
-	0x00, 0xE0,
-	0x32, 0x00,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x27, 0xC0, 0x44, 0xC0,
-
-	0x36, 0x1F, 0x4F, 0xE9,
-	0x1F, 0x1F, 0x26, 0xDF,
-
-	0x37, 0x1B, 0x37, 0xBF,
-	0x17, 0x26, 0x17, 0xDF,
-
-	0x3E, 0x17, 0x4F, 0xE9,
-	0x3F, 0x3F, 0x4F, 0xE9,
-
-	0x34, 0x1F, 0x34, 0xAF,
-	0x2B, 0x05,
-	0xA7, 0x20,
-
-	0x33, 0x2B, 0x37, 0xDF,
-	0x27, 0x17, 0xC0, 0xAF,
-
-	0x34, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2D, 0x21, 0x1A, 0xB0,
-	0x25, 0x21, 0x31, 0xB0,
-
-	0x0D, 0x21, 0x1A, 0xB2,
-	0x05, 0x21, 0x31, 0xB2,
-
-	0x03, 0x80, 0x2A, 0xEA,
-	0x17, 0xC1, 0x2B, 0xBD,
-
-	0x2D, 0x20,
-	0x25, 0x20,
-	0x05, 0x20,
-	0x0D, 0x20,
-
-	0xB3, 0x68,
-	0x97, 0x25,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0xC0, 0x33, 0xAF,
-	0x2F, 0xC0, 0x21, 0xC0,
-
-	0x16, 0x42, 0x56, 0x9F,
-	0x3C, 0x27, 0x4F, 0xE9,
-
-	0x1E, 0x62, 0x57, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x21, 0x31, 0xB4,
-	0x2D, 0x21, 0x1A, 0xB4,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x33, 0x05,
-	0x00, 0xE0,
-	0x28, 0x19, 0x60, 0xEC,
-
-	0x0D, 0x21, 0x1A, 0xB6,
-	0x05, 0x21, 0x31, 0xB6,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0xE0,
-	0x2F, 0x20,
-
-	0x23, 0x3B, 0x33, 0xAD,
-	0x1E, 0x26, 0x1E, 0xDF,
-
-	0xA7, 0x1E, 0x4F, 0xE9,
-	0x17, 0x26, 0x16, 0xDF,
-
-	0x2D, 0x20,
-	0x00, 0xE0,
-	0xA8, 0x3F, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x1E, 0xAF,
-	0x25, 0x20,
-	0x00, 0xE0,
-
-	0xA4, 0x16, 0x4F, 0xE9,
-	0x0F, 0xC0, 0x21, 0xC2,
-
-	0xA6, 0x80, 0x4F, 0xE9,
-	0x1F, 0x62, 0x57, 0x9F,
-
-	0x0D, 0x20,
-	0x05, 0x20,
-	0x2F, 0xC0, 0x21, 0xC6,
-
-	0x3F, 0x2F, 0x5D, 0x9F,
-	0x00, 0xE0,
-	0x0F, 0x20,
-
-	0x17, 0x50, 0x56, 0x9F,
-	0xA5, 0x37, 0x4F, 0xE9,
-
-	0x06, 0xC0, 0x21, 0xC4,
-	0x0F, 0x17, 0x0F, 0xAF,
-
-	0x37, 0x0F, 0x5C, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2F, 0x20,
-	0x00, 0xE0,
-	0xA3, 0x80, 0x4F, 0xE9,
-
-	0x06, 0x20,
-	0x00, 0xE0,
-	0x1F, 0x26, 0x1F, 0xDF,
-
-	0x17, 0x26, 0x17, 0xDF,
-	0x35, 0x17, 0x4F, 0xE9,
-
-	0xA1, 0x1F, 0x4F, 0xE9,
-	0xA2, 0x3F, 0x4F, 0xE9,
-
-	0x06, 0x06, 0x1F, 0xAF,
-	0x39, 0x37, 0x4F, 0xE9,
-
-	0x2F, 0x2F, 0x17, 0xAF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xA0, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x31, 0x80, 0x4F, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x57, 0x39, 0x20, 0xE9,
-
-	0x16, 0x28, 0x20, 0xE9,
-	0x1D, 0x3B, 0x20, 0xE9,
-
-	0x1E, 0x2B, 0x20, 0xE9,
-	0x2B, 0x32, 0x20, 0xE9,
-
-	0x1C, 0x23, 0x20, 0xE9,
-	0x57, 0x36, 0x20, 0xE9,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x40, 0x40, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x90, 0xE2,
-	0x00, 0xE0,
-
-	0x68, 0xFF, 0x20, 0xEA,
-	0x19, 0xC8, 0xC1, 0xCD,
-
-	0x1F, 0xD7, 0x18, 0xBD,
-	0x3F, 0xD7, 0x22, 0xBD,
-
-	0x9F, 0x41, 0x49, 0xBD,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x25, 0x41, 0x49, 0xBD,
-	0x2D, 0x41, 0x51, 0xBD,
-
-	0x0D, 0x80, 0x07, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x35, 0x40, 0x48, 0xBD,
-	0x3D, 0x40, 0x50, 0xBD,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x25, 0x30,
-	0x2D, 0x30,
-
-	0x35, 0x30,
-	0xB5, 0x30,
-	0xBD, 0x30,
-	0x3D, 0x30,
-
-	0x9C, 0xA7, 0x5B, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x67, 0xFF, 0x0A, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC9, 0x41, 0xC8, 0xEC,
-	0x42, 0xE1,
-	0x00, 0xE0,
-
-	0x65, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xC8, 0x40, 0xC0, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x62, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-};
-
-static unsigned char warp_g400_t2gz[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x78, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x69, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x34, 0x80, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x25, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x3D, 0xCF, 0x74, 0xC2,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2A, 0x44, 0x54, 0xB4,
-	0x1A, 0x44, 0x64, 0xB4,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x9F, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xBE, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x7D, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_t2gza[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x7C, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x6D, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x34, 0x80, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x29, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x0F, 0xCF, 0x74, 0xC6,
-	0x3D, 0xCF, 0x74, 0xC2,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x0F, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x54, 0xB4,
-	0x02, 0x44, 0x64, 0xB4,
-
-	0x2A, 0x44, 0x54, 0xB6,
-	0x1A, 0x44, 0x64, 0xB6,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x20,
-	0x02, 0x20,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x36, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x37, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x9B, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xBA, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x79, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_t2gzaf[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x81, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x72, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x2E, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x3D, 0xCF, 0x74, 0xC2,
-	0x0F, 0xCF, 0x74, 0xC6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x0F, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x54, 0xB4,
-	0x02, 0x44, 0x64, 0xB4,
-
-	0x2A, 0x44, 0x54, 0xB6,
-	0x1A, 0x44, 0x64, 0xB6,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x20,
-	0x02, 0x20,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x3D, 0xCF, 0x75, 0xC6,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x45, 0x55, 0xB6,
-	0x02, 0x45, 0x65, 0xB6,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x3D, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x38, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x96, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xB5, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x74, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_t2gzf[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x7D, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x6E, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x34, 0x80, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0F, 0xCF, 0x75, 0xC6,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x28, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x3D, 0xCF, 0x74, 0xC2,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x31, 0x0F, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x54, 0xB4,
-	0x02, 0x44, 0x64, 0xB4,
-
-	0x2A, 0x45, 0x55, 0xB6,
-	0x1A, 0x45, 0x65, 0xB6,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x20,
-	0x02, 0x20,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x36, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x37, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x9A, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xBB, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x78, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_t2gzs[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x85, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x76, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x0F, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x31, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x0F, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB4,
-	0x1A, 0x44, 0x64, 0xB4,
-
-	0x0A, 0x45, 0x55, 0xB0,
-	0x02, 0x45, 0x65, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x55, 0xB2,
-	0x1A, 0x45, 0x65, 0xB2,
-
-	0x0A, 0x45, 0x55, 0xB4,
-	0x02, 0x45, 0x65, 0xB4,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x20,
-	0x1A, 0x20,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0xA7, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x92, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xB2, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x70, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_t2gzsa[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x8A, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x7B, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x0F, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x36, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x0F, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB4,
-	0x1A, 0x44, 0x64, 0xB4,
-
-	0x0A, 0x45, 0x55, 0xB0,
-	0x02, 0x45, 0x65, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x55, 0xB2,
-	0x1A, 0x45, 0x65, 0xB2,
-
-	0x0A, 0x45, 0x55, 0xB4,
-	0x02, 0x45, 0x65, 0xB4,
-
-	0x0F, 0xCF, 0x74, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA7, 0x30, 0x4F, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB6,
-	0x1A, 0x44, 0x64, 0xB6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x8D, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xAD, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x6B, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_t2gzsaf[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x8E, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x7F, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x0F, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x3A, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x0F, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB4,
-	0x1A, 0x44, 0x64, 0xB4,
-
-	0x0A, 0x45, 0x55, 0xB0,
-	0x02, 0x45, 0x65, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x55, 0xB2,
-	0x1A, 0x45, 0x65, 0xB2,
-
-	0x0A, 0x45, 0x55, 0xB4,
-	0x02, 0x45, 0x65, 0xB4,
-
-	0x0F, 0xCF, 0x74, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA7, 0x30, 0x4F, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB6,
-	0x1A, 0x44, 0x64, 0xB6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x45, 0x55, 0xB6,
-	0x02, 0x45, 0x65, 0xB6,
-
-	0x3D, 0xCF, 0x75, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x3D, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x89, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xA9, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x67, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_t2gzsf[] = {
-
-	0x00, 0x8A, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x0A, 0x40, 0x50, 0xBF,
-	0x2A, 0x40, 0x60, 0xBF,
-
-	0x32, 0x41, 0x51, 0xBF,
-	0x3A, 0x41, 0x61, 0xBF,
-
-	0xC3, 0x6B,
-	0xD3, 0x6B,
-	0x00, 0x8A, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x23, 0x9F,
-	0x00, 0xE0,
-	0x51, 0x04,
-
-	0x90, 0xE2,
-	0x61, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x51, 0x41, 0xE0, 0xEC,
-	0x39, 0x67, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x63, 0xA0, 0xE8,
-
-	0x61, 0x41, 0xE0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x8A, 0x80, 0x15, 0xEA,
-	0x10, 0x04,
-	0x20, 0x04,
-
-	0x61, 0x51, 0xE0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x52, 0xBF,
-	0x0F, 0x52, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x62, 0xBF,
-	0x1E, 0x51, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x0E, 0x61, 0x60, 0xEA,
-
-	0x32, 0x40, 0x50, 0xBD,
-	0x22, 0x40, 0x60, 0xBD,
-
-	0x12, 0x41, 0x51, 0xBD,
-	0x3A, 0x41, 0x61, 0xBD,
-
-	0xBF, 0x2F, 0x0E, 0xBD,
-	0x97, 0xE2,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x35, 0x48, 0xB1, 0xE8,
-	0x3D, 0x59, 0xB1, 0xE8,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x56, 0x31, 0x56, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x66, 0x31, 0x66, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x57, 0x39, 0x57, 0xBF,
-	0x67, 0x39, 0x67, 0xBF,
-
-	0x7B, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x35, 0x00,
-	0x3D, 0x00,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0x8D, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x75, 0xF8, 0xEC,
-	0x35, 0x20,
-	0x3D, 0x20,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x53, 0x53, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x0E, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x48, 0x35, 0x48, 0xBF,
-	0x58, 0x35, 0x58, 0xBF,
-
-	0x68, 0x35, 0x68, 0xBF,
-	0x49, 0x3D, 0x49, 0xBF,
-
-	0x59, 0x3D, 0x59, 0xBF,
-	0x69, 0x3D, 0x69, 0xBF,
-
-	0x63, 0x63, 0x2D, 0xDF,
-	0x4D, 0x7D, 0xF8, 0xEC,
-
-	0x59, 0xE3,
-	0x00, 0xE0,
-	0xB8, 0x38, 0x33, 0xBF,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x18, 0x3A, 0x41, 0xE9,
-
-	0x3F, 0x53, 0xA0, 0xE8,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x63, 0xA0, 0xE8,
-
-	0x50, 0x70, 0xF8, 0xEC,
-	0x2B, 0x50, 0x3C, 0xE9,
-
-	0x1F, 0x0F, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x59, 0x78, 0xF8, 0xEC,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x56, 0x3F, 0x56, 0xDF,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x66, 0x3D, 0x66, 0xDF,
-
-	0x1D, 0x32, 0x41, 0xE9,
-	0x67, 0x3D, 0x67, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3F, 0x57, 0xDF,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x59, 0x3F, 0x59, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x69, 0x3D, 0x69, 0xDF,
-
-	0x48, 0x37, 0x48, 0xDF,
-	0x58, 0x3F, 0x58, 0xDF,
-
-	0x68, 0x3D, 0x68, 0xDF,
-	0x49, 0x37, 0x49, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x0F, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x54, 0xB0,
-	0x02, 0x44, 0x64, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB2,
-	0x1A, 0x44, 0x64, 0xB2,
-
-	0x36, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x0F, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x54, 0xB4,
-	0x1A, 0x44, 0x64, 0xB4,
-
-	0x0A, 0x45, 0x55, 0xB0,
-	0x02, 0x45, 0x65, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x55, 0xB2,
-	0x1A, 0x45, 0x65, 0xB2,
-
-	0x0A, 0x45, 0x55, 0xB4,
-	0x02, 0x45, 0x65, 0xB4,
-
-	0x0F, 0xCF, 0x75, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA7, 0x30, 0x4F, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x31, 0x0F, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x55, 0xB6,
-	0x1A, 0x45, 0x65, 0xB6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x56, 0xBF,
-	0x1A, 0x46, 0x66, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x57, 0xBF,
-	0x02, 0x47, 0x67, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x53, 0xBF,
-	0x1A, 0x43, 0x63, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x48, 0x58, 0xBF,
-	0x02, 0x48, 0x68, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x2A, 0x49, 0x59, 0xBF,
-	0x1A, 0x49, 0x69, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x82, 0x30, 0x57, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x83, 0x38, 0x57, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x84, 0x31, 0x5E, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x85, 0x39, 0x5E, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x87, 0x77, 0x57, 0xE9,
-	0x8B, 0x3E, 0xBF, 0xEA,
-
-	0x80, 0x30, 0x57, 0xE9,
-	0x81, 0x38, 0x57, 0xE9,
-
-	0x82, 0x31, 0x57, 0xE9,
-	0x86, 0x78, 0x57, 0xE9,
-
-	0x83, 0x39, 0x57, 0xE9,
-	0x87, 0x79, 0x57, 0xE9,
-
-	0x30, 0x1F, 0x5F, 0xE9,
-	0x8A, 0x34, 0x20, 0xE9,
-
-	0x8B, 0x3C, 0x20, 0xE9,
-	0x37, 0x50, 0x60, 0xBD,
-
-	0x57, 0x0D, 0x20, 0xE9,
-	0x35, 0x51, 0x61, 0xBD,
-
-	0x2B, 0x50, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x0E, 0x77,
-
-	0x24, 0x51, 0x20, 0xE9,
-	0x8D, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x0E, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x0B, 0x46, 0xA0, 0xE8,
-	0x1B, 0x56, 0xA0, 0xE8,
-
-	0x2B, 0x66, 0xA0, 0xE8,
-	0x0C, 0x47, 0xA0, 0xE8,
-
-	0x1C, 0x57, 0xA0, 0xE8,
-	0x2C, 0x67, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x57, 0x80, 0x57, 0xCF,
-
-	0x66, 0x33, 0x66, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x67, 0x3B, 0x67, 0xCF,
-
-	0x0B, 0x48, 0xA0, 0xE8,
-	0x1B, 0x58, 0xA0, 0xE8,
-
-	0x2B, 0x68, 0xA0, 0xE8,
-	0x0C, 0x49, 0xA0, 0xE8,
-
-	0x1C, 0x59, 0xA0, 0xE8,
-	0x2C, 0x69, 0xA0, 0xE8,
-
-	0x0B, 0x00,
-	0x1B, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x0C, 0x00,
-	0x1C, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x0B, 0x65,
-	0x1B, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x0C, 0x65,
-	0x1C, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x0B, 0x1B, 0x60, 0xEC,
-	0x34, 0xD7, 0x34, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x0C, 0x1C, 0x60, 0xEC,
-
-	0x3C, 0xD7, 0x3C, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x0B, 0x2B, 0xDE, 0xE8,
-	0x1B, 0x80, 0xDE, 0xE8,
-
-	0x34, 0x80, 0x34, 0xBD,
-	0x3C, 0x80, 0x3C, 0xBD,
-
-	0x33, 0xD7, 0x0B, 0xBD,
-	0x3B, 0xD7, 0x1B, 0xBD,
-
-	0x48, 0x80, 0x48, 0xCF,
-	0x59, 0x80, 0x59, 0xCF,
-
-	0x68, 0x33, 0x68, 0xCF,
-	0x49, 0x3B, 0x49, 0xCF,
-
-	0xAD, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x58, 0x33, 0x58, 0xCF,
-	0x69, 0x3B, 0x69, 0xCF,
-
-	0x6B, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgz[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x58, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x4A, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x34, 0x80, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x1D, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x3D, 0xCF, 0x74, 0xC2,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x2A, 0x44, 0x4C, 0xB4,
-	0x1A, 0x44, 0x54, 0xB4,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0xAF, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xD6, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x9D, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgza[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x5C, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x4E, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x34, 0x80, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x27, 0xCF, 0x74, 0xC6,
-	0x3D, 0xCF, 0x74, 0xC2,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x20, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x27, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x4C, 0xB4,
-	0x02, 0x44, 0x54, 0xB4,
-
-	0x2A, 0x44, 0x4C, 0xB6,
-	0x1A, 0x44, 0x54, 0xB6,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x20,
-	0x02, 0x20,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x36, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x37, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0xAB, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xD3, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x99, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgzaf[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x61, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x53, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x26, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x3D, 0xCF, 0x74, 0xC2,
-	0x27, 0xCF, 0x74, 0xC6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x27, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x4C, 0xB4,
-	0x02, 0x44, 0x54, 0xB4,
-
-	0x2A, 0x44, 0x4C, 0xB6,
-	0x1A, 0x44, 0x54, 0xB6,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x20,
-	0x02, 0x20,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x3D, 0xCF, 0x75, 0xC6,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x45, 0x4D, 0xB6,
-	0x02, 0x45, 0x55, 0xB6,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x3D, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x38, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x38, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0xA6, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xCD, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x94, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgzf[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x5D, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x4F, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x34, 0x80, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x27, 0xCF, 0x75, 0xC6,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x20, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x3D, 0xCF, 0x74, 0xC2,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x31, 0x27, 0x20, 0xE9,
-
-	0x0A, 0x44, 0x4C, 0xB4,
-	0x02, 0x44, 0x54, 0xB4,
-
-	0x2A, 0x45, 0x4D, 0xB6,
-	0x1A, 0x45, 0x55, 0xB6,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x38, 0x3D, 0x20, 0xE9,
-
-	0x0A, 0x20,
-	0x02, 0x20,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x36, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x37, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0xAA, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xD3, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x98, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgzs[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x65, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x57, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x27, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x29, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x27, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB4,
-	0x1A, 0x44, 0x54, 0xB4,
-
-	0x0A, 0x45, 0x4D, 0xB0,
-	0x02, 0x45, 0x55, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x4D, 0xB2,
-	0x1A, 0x45, 0x55, 0xB2,
-
-	0x0A, 0x45, 0x4D, 0xB4,
-	0x02, 0x45, 0x55, 0xB4,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x20,
-	0x02, 0x20,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0xA7, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0xA2, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xCA, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x90, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgzsa[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x6A, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x5C, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x27, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x2E, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x27, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB4,
-	0x1A, 0x44, 0x54, 0xB4,
-
-	0x0A, 0x45, 0x4D, 0xB0,
-	0x02, 0x45, 0x55, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x4D, 0xB2,
-	0x1A, 0x45, 0x55, 0xB2,
-
-	0x0A, 0x45, 0x4D, 0xB4,
-	0x02, 0x45, 0x55, 0xB4,
-
-	0x27, 0xCF, 0x74, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA7, 0x30, 0x4F, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB6,
-	0x1A, 0x44, 0x54, 0xB6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0x9D, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xC5, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x8B, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgzsaf[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x6E, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x60, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x27, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x32, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x27, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB4,
-	0x1A, 0x44, 0x54, 0xB4,
-
-	0x0A, 0x45, 0x4D, 0xB0,
-	0x02, 0x45, 0x55, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x4D, 0xB2,
-	0x1A, 0x45, 0x55, 0xB2,
-
-	0x0A, 0x45, 0x4D, 0xB4,
-	0x02, 0x45, 0x55, 0xB4,
-
-	0x27, 0xCF, 0x74, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA7, 0x30, 0x4F, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9C, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB6,
-	0x1A, 0x44, 0x54, 0xB6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x45, 0x4D, 0xB6,
-	0x02, 0x45, 0x55, 0xB6,
-
-	0x3D, 0xCF, 0x75, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x3D, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x9D, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x9E, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x30, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x38, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0x99, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xC1, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x87, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
-
-static unsigned char warp_g400_tgzsf[] = {
-
-	0x00, 0x88, 0x98, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-	0xFF, 0x80, 0xC0, 0xE9,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x22, 0x40, 0x48, 0xBF,
-	0x2A, 0x40, 0x50, 0xBF,
-
-	0x32, 0x41, 0x49, 0xBF,
-	0x3A, 0x41, 0x51, 0xBF,
-
-	0xC3, 0x6B,
-	0xCB, 0x6B,
-	0x00, 0x88, 0x98, 0xE9,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x96, 0xE2,
-	0x41, 0x04,
-
-	0x7B, 0x43, 0xA0, 0xE8,
-	0x73, 0x4B, 0xA0, 0xE8,
-
-	0xAD, 0xEE, 0x29, 0x9F,
-	0x00, 0xE0,
-	0x49, 0x04,
-
-	0x90, 0xE2,
-	0x51, 0x04,
-	0x31, 0x46, 0xB1, 0xE8,
-
-	0x49, 0x41, 0xC0, 0xEC,
-	0x39, 0x57, 0xB1, 0xE8,
-
-	0x00, 0x04,
-	0x46, 0xE2,
-	0x73, 0x53, 0xA0, 0xE8,
-
-	0x51, 0x41, 0xC0, 0xEC,
-	0x31, 0x00,
-	0x39, 0x00,
-
-	0x6A, 0x80, 0x15, 0xEA,
-	0x08, 0x04,
-	0x10, 0x04,
-
-	0x51, 0x49, 0xC0, 0xEC,
-	0x2F, 0x41, 0x60, 0xEA,
-
-	0x31, 0x20,
-	0x39, 0x20,
-	0x1F, 0x42, 0xA0, 0xE8,
-
-	0x2A, 0x42, 0x4A, 0xBF,
-	0x27, 0x4A, 0xA0, 0xE8,
-
-	0x1A, 0x42, 0x52, 0xBF,
-	0x1E, 0x49, 0x60, 0xEA,
-
-	0x73, 0x7B, 0xC8, 0xEC,
-	0x26, 0x51, 0x60, 0xEA,
-
-	0x32, 0x40, 0x48, 0xBD,
-	0x22, 0x40, 0x50, 0xBD,
-
-	0x12, 0x41, 0x49, 0xBD,
-	0x3A, 0x41, 0x51, 0xBD,
-
-	0xBF, 0x2F, 0x26, 0xBD,
-	0x00, 0xE0,
-	0x7B, 0x72,
-
-	0x32, 0x20,
-	0x22, 0x20,
-	0x12, 0x20,
-	0x3A, 0x20,
-
-	0x46, 0x31, 0x46, 0xBF,
-	0x4E, 0x31, 0x4E, 0xBF,
-
-	0xB3, 0xE2, 0x2D, 0x9F,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x56, 0x31, 0x56, 0xBF,
-	0x47, 0x39, 0x47, 0xBF,
-
-	0x4F, 0x39, 0x4F, 0xBF,
-	0x57, 0x39, 0x57, 0xBF,
-
-	0x5C, 0x80, 0x07, 0xEA,
-	0x24, 0x41, 0x20, 0xE9,
-
-	0x42, 0x73, 0xF8, 0xEC,
-	0x00, 0xE0,
-	0x2D, 0x73,
-
-	0x33, 0x72,
-	0x0C, 0xE3,
-	0xA5, 0x2F, 0x1E, 0xBD,
-
-	0x43, 0x43, 0x2D, 0xDF,
-	0x4B, 0x4B, 0x2D, 0xDF,
-
-	0xAE, 0x1E, 0x26, 0xBD,
-	0x58, 0xE3,
-	0x33, 0x66,
-
-	0x53, 0x53, 0x2D, 0xDF,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0xB8, 0x38, 0x33, 0xBF,
-	0x00, 0xE0,
-	0x59, 0xE3,
-
-	0x1E, 0x12, 0x41, 0xE9,
-	0x1A, 0x22, 0x41, 0xE9,
-
-	0x2B, 0x40, 0x3D, 0xE9,
-	0x3F, 0x4B, 0xA0, 0xE8,
-
-	0x2D, 0x73,
-	0x30, 0x76,
-	0x05, 0x80, 0x3D, 0xEA,
-
-	0x37, 0x43, 0xA0, 0xE8,
-	0x3D, 0x53, 0xA0, 0xE8,
-
-	0x48, 0x70, 0xF8, 0xEC,
-	0x2B, 0x48, 0x3C, 0xE9,
-
-	0x1F, 0x27, 0xBC, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x15, 0xC0, 0x20, 0xE9,
-	0x15, 0xC0, 0x20, 0xE9,
-
-	0x18, 0x3A, 0x41, 0xE9,
-	0x1D, 0x32, 0x41, 0xE9,
-
-	0x2A, 0x40, 0x20, 0xE9,
-	0x56, 0x3D, 0x56, 0xDF,
-
-	0x46, 0x37, 0x46, 0xDF,
-	0x4E, 0x3F, 0x4E, 0xDF,
-
-	0x16, 0x30, 0x20, 0xE9,
-	0x4F, 0x3F, 0x4F, 0xDF,
-
-	0x47, 0x37, 0x47, 0xDF,
-	0x57, 0x3D, 0x57, 0xDF,
-
-	0x32, 0x32, 0x2D, 0xDF,
-	0x22, 0x22, 0x2D, 0xDF,
-
-	0x12, 0x12, 0x2D, 0xDF,
-	0x3A, 0x3A, 0x2D, 0xDF,
-
-	0x27, 0xCF, 0x74, 0xC2,
-	0x37, 0xCF, 0x74, 0xC4,
-
-	0x0A, 0x44, 0x4C, 0xB0,
-	0x02, 0x44, 0x54, 0xB0,
-
-	0x3D, 0xCF, 0x74, 0xC0,
-	0x34, 0x37, 0x20, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x38, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3C, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB2,
-	0x1A, 0x44, 0x54, 0xB2,
-
-	0x2E, 0x80, 0x3A, 0xEA,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x27, 0xCF, 0x75, 0xC0,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x32, 0x31, 0x5F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x33, 0x39, 0x5F, 0xE9,
-
-	0x3D, 0xCF, 0x75, 0xC2,
-	0x37, 0xCF, 0x75, 0xC4,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA6, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA3, 0x3D, 0x20, 0xE9,
-
-	0x2A, 0x44, 0x4C, 0xB4,
-	0x1A, 0x44, 0x54, 0xB4,
-
-	0x0A, 0x45, 0x4D, 0xB0,
-	0x02, 0x45, 0x55, 0xB0,
-
-	0x88, 0x73, 0x5E, 0xE9,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA0, 0x37, 0x20, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x3E, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x3F, 0x38, 0x4F, 0xE9,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x3A, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x3B, 0x39, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x4D, 0xB2,
-	0x1A, 0x45, 0x55, 0xB2,
-
-	0x0A, 0x45, 0x4D, 0xB4,
-	0x02, 0x45, 0x55, 0xB4,
-
-	0x27, 0xCF, 0x75, 0xC6,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0xA7, 0x30, 0x4F, 0xE9,
-	0x0A, 0x20,
-	0x02, 0x20,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x31, 0x27, 0x20, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA8, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x45, 0x4D, 0xB6,
-	0x1A, 0x45, 0x55, 0xB6,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x36, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x37, 0x39, 0x4F, 0xE9,
-
-	0x00, 0x80, 0x00, 0xE8,
-	0x2A, 0x20,
-	0x1A, 0x20,
-
-	0x2A, 0x46, 0x4E, 0xBF,
-	0x1A, 0x46, 0x56, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA4, 0x31, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA5, 0x39, 0x4F, 0xE9,
-
-	0x0A, 0x47, 0x4F, 0xBF,
-	0x02, 0x47, 0x57, 0xBF,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0xA1, 0x30, 0x4F, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0xA2, 0x38, 0x4F, 0xE9,
-
-	0x2A, 0x43, 0x4B, 0xBF,
-	0x1A, 0x43, 0x53, 0xBF,
-
-	0x30, 0x50, 0x2E, 0x9F,
-	0x35, 0x31, 0x4F, 0xE9,
-
-	0x38, 0x21, 0x2C, 0x9F,
-	0x39, 0x39, 0x4F, 0xE9,
-
-	0x31, 0x53, 0x2F, 0x9F,
-	0x80, 0x31, 0x57, 0xE9,
-
-	0x39, 0xE5, 0x2C, 0x9F,
-	0x81, 0x39, 0x57, 0xE9,
-
-	0x37, 0x48, 0x50, 0xBD,
-	0x8A, 0x36, 0x20, 0xE9,
-
-	0x86, 0x76, 0x57, 0xE9,
-	0x8B, 0x3E, 0x20, 0xE9,
-
-	0x82, 0x30, 0x57, 0xE9,
-	0x87, 0x77, 0x57, 0xE9,
-
-	0x83, 0x38, 0x57, 0xE9,
-	0x35, 0x49, 0x51, 0xBD,
-
-	0x84, 0x31, 0x5E, 0xE9,
-	0x30, 0x1F, 0x5F, 0xE9,
-
-	0x85, 0x39, 0x5E, 0xE9,
-	0x57, 0x25, 0x20, 0xE9,
-
-	0x2B, 0x48, 0x20, 0xE9,
-	0x1D, 0x37, 0xE1, 0xEA,
-
-	0x1E, 0x35, 0xE1, 0xEA,
-	0x00, 0xE0,
-	0x26, 0x77,
-
-	0x24, 0x49, 0x20, 0xE9,
-	0x9D, 0xFF, 0x20, 0xEA,
-
-	0x16, 0x26, 0x20, 0xE9,
-	0x57, 0x2E, 0xBF, 0xEA,
-
-	0x1C, 0x46, 0xA0, 0xE8,
-	0x23, 0x4E, 0xA0, 0xE8,
-
-	0x2B, 0x56, 0xA0, 0xE8,
-	0x1D, 0x47, 0xA0, 0xE8,
-
-	0x24, 0x4F, 0xA0, 0xE8,
-	0x2C, 0x57, 0xA0, 0xE8,
-
-	0x1C, 0x00,
-	0x23, 0x00,
-	0x2B, 0x00,
-	0x00, 0xE0,
-
-	0x1D, 0x00,
-	0x24, 0x00,
-	0x2C, 0x00,
-	0x00, 0xE0,
-
-	0x1C, 0x65,
-	0x23, 0x65,
-	0x2B, 0x65,
-	0x00, 0xE0,
-
-	0x1D, 0x65,
-	0x24, 0x65,
-	0x2C, 0x65,
-	0x00, 0xE0,
-
-	0x1C, 0x23, 0x60, 0xEC,
-	0x36, 0xD7, 0x36, 0xAD,
-
-	0x2B, 0x80, 0x60, 0xEC,
-	0x1D, 0x24, 0x60, 0xEC,
-
-	0x3E, 0xD7, 0x3E, 0xAD,
-	0x2C, 0x80, 0x60, 0xEC,
-
-	0x1C, 0x2B, 0xDE, 0xE8,
-	0x23, 0x80, 0xDE, 0xE8,
-
-	0x36, 0x80, 0x36, 0xBD,
-	0x3E, 0x80, 0x3E, 0xBD,
-
-	0x33, 0xD7, 0x1C, 0xBD,
-	0x3B, 0xD7, 0x23, 0xBD,
-
-	0x46, 0x80, 0x46, 0xCF,
-	0x4F, 0x80, 0x4F, 0xCF,
-
-	0x56, 0x33, 0x56, 0xCF,
-	0x47, 0x3B, 0x47, 0xCF,
-
-	0xC5, 0xFF, 0x20, 0xEA,
-	0x00, 0x80, 0x00, 0xE8,
-
-	0x4E, 0x33, 0x4E, 0xCF,
-	0x57, 0x3B, 0x57, 0xCF,
-
-	0x8B, 0xFF, 0x20, 0xEA,
-	0x57, 0xC0, 0xBF, 0xEA,
-
-	0x00, 0x80, 0xA0, 0xE9,
-	0x00, 0x00, 0xD8, 0xEC,
-
-};
diff --git a/drivers/gpu/drm/mga/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c
index 651b93c..9aad484 100644
--- a/drivers/gpu/drm/mga/mga_warp.c
+++ b/drivers/gpu/drm/mga/mga_warp.c
@@ -27,132 +27,108 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
+#include <linux/firmware.h>
+#include <linux/ihex.h>
+#include <linux/platform_device.h>
+
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
 #include "mga_drv.h"
-#include "mga_ucode.h"
+
+#define FIRMWARE_G200 "matrox/g200_warp.fw"
+#define FIRMWARE_G400 "matrox/g400_warp.fw"
+
+MODULE_FIRMWARE(FIRMWARE_G200);
+MODULE_FIRMWARE(FIRMWARE_G400);
 
 #define MGA_WARP_CODE_ALIGN		256	/* in bytes */
 
-#define WARP_UCODE_SIZE( which )					\
-	((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)
-
-#define WARP_UCODE_INSTALL( which, where )				\
-do {									\
-	DRM_DEBUG( " pcbase = 0x%08lx  vcbase = %p\n", pcbase, vcbase );\
-	dev_priv->warp_pipe_phys[where] = pcbase;			\
-	memcpy( vcbase, which, sizeof(which) );				\
-	pcbase += WARP_UCODE_SIZE( which );				\
-	vcbase += WARP_UCODE_SIZE( which );				\
-} while (0)
-
-static const unsigned int mga_warp_g400_microcode_size =
-    (WARP_UCODE_SIZE(warp_g400_tgz) +
-     WARP_UCODE_SIZE(warp_g400_tgza) +
-     WARP_UCODE_SIZE(warp_g400_tgzaf) +
-     WARP_UCODE_SIZE(warp_g400_tgzf) +
-     WARP_UCODE_SIZE(warp_g400_tgzs) +
-     WARP_UCODE_SIZE(warp_g400_tgzsa) +
-     WARP_UCODE_SIZE(warp_g400_tgzsaf) +
-     WARP_UCODE_SIZE(warp_g400_tgzsf) +
-     WARP_UCODE_SIZE(warp_g400_t2gz) +
-     WARP_UCODE_SIZE(warp_g400_t2gza) +
-     WARP_UCODE_SIZE(warp_g400_t2gzaf) +
-     WARP_UCODE_SIZE(warp_g400_t2gzf) +
-     WARP_UCODE_SIZE(warp_g400_t2gzs) +
-     WARP_UCODE_SIZE(warp_g400_t2gzsa) +
-     WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf));
-
-static const unsigned int mga_warp_g200_microcode_size =
-    (WARP_UCODE_SIZE(warp_g200_tgz) +
-     WARP_UCODE_SIZE(warp_g200_tgza) +
-     WARP_UCODE_SIZE(warp_g200_tgzaf) +
-     WARP_UCODE_SIZE(warp_g200_tgzf) +
-     WARP_UCODE_SIZE(warp_g200_tgzs) +
-     WARP_UCODE_SIZE(warp_g200_tgzsa) +
-     WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf));
-
-unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
+#define WARP_UCODE_SIZE(size)		ALIGN(size, MGA_WARP_CODE_ALIGN)
+
+int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
 {
+	unsigned char *vcbase = dev_priv->warp->handle;
+	unsigned long pcbase = dev_priv->warp->offset;
+	const char *firmware_name;
+	struct platform_device *pdev;
+	const struct firmware *fw = NULL;
+	const struct ihex_binrec *rec;
+	unsigned int size;
+	int n_pipes, where;
+	int rc = 0;
+
 	switch (dev_priv->chipset) {
 	case MGA_CARD_TYPE_G400:
 	case MGA_CARD_TYPE_G550:
-		return PAGE_ALIGN(mga_warp_g400_microcode_size);
+		firmware_name = FIRMWARE_G400;
+		n_pipes = MGA_MAX_G400_PIPES;
+		break;
 	case MGA_CARD_TYPE_G200:
-		return PAGE_ALIGN(mga_warp_g200_microcode_size);
+		firmware_name = FIRMWARE_G200;
+		n_pipes = MGA_MAX_G200_PIPES;
+		break;
 	default:
-		return 0;
+		return -EINVAL;
 	}
-}
-
-static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
-{
-	unsigned char *vcbase = dev_priv->warp->handle;
-	unsigned long pcbase = dev_priv->warp->offset;
-
-	memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
-
-	WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ);
-	WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF);
-	WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA);
-	WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF);
-	WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS);
-	WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF);
-	WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA);
-	WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF);
-
-	WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ);
-	WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF);
-	WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA);
-	WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF);
-	WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS);
-	WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF);
-	WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA);
-	WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF);
-
-	return 0;
-}
-
-static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv)
-{
-	unsigned char *vcbase = dev_priv->warp->handle;
-	unsigned long pcbase = dev_priv->warp->offset;
-
-	memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
-
-	WARP_UCODE_INSTALL(warp_g200_tgz, MGA_WARP_TGZ);
-	WARP_UCODE_INSTALL(warp_g200_tgzf, MGA_WARP_TGZF);
-	WARP_UCODE_INSTALL(warp_g200_tgza, MGA_WARP_TGZA);
-	WARP_UCODE_INSTALL(warp_g200_tgzaf, MGA_WARP_TGZAF);
-	WARP_UCODE_INSTALL(warp_g200_tgzs, MGA_WARP_TGZS);
-	WARP_UCODE_INSTALL(warp_g200_tgzsf, MGA_WARP_TGZSF);
-	WARP_UCODE_INSTALL(warp_g200_tgzsa, MGA_WARP_TGZSA);
-	WARP_UCODE_INSTALL(warp_g200_tgzsaf, MGA_WARP_TGZSAF);
 
-	return 0;
-}
+	pdev = platform_device_register_simple("mga_warp", 0, NULL, 0);
+	if (IS_ERR(pdev)) {
+		DRM_ERROR("mga: Failed to register microcode\n");
+		return PTR_ERR(pdev);
+	}
+	rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev);
+	platform_device_unregister(pdev);
+	if (rc) {
+		DRM_ERROR("mga: Failed to load microcode \"%s\"\n",
+			  firmware_name);
+		return rc;
+	}
 
-int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
-{
-	const unsigned int size = mga_warp_microcode_size(dev_priv);
+	size = 0;
+	where = 0;
+	for (rec = (const struct ihex_binrec *)fw->data;
+	     rec;
+	     rec = ihex_next_binrec(rec)) {
+		size += WARP_UCODE_SIZE(be16_to_cpu(rec->len));
+		where++;
+	}
 
+	if (where != n_pipes) {
+		DRM_ERROR("mga: Invalid microcode \"%s\"\n", firmware_name);
+		rc = -EINVAL;
+		goto out;
+	}
+	size = PAGE_ALIGN(size);
 	DRM_DEBUG("MGA ucode size = %d bytes\n", size);
 	if (size > dev_priv->warp->size) {
 		DRM_ERROR("microcode too large! (%u > %lu)\n",
 			  size, dev_priv->warp->size);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 
-	switch (dev_priv->chipset) {
-	case MGA_CARD_TYPE_G400:
-	case MGA_CARD_TYPE_G550:
-		return mga_warp_install_g400_microcode(dev_priv);
-	case MGA_CARD_TYPE_G200:
-		return mga_warp_install_g200_microcode(dev_priv);
-	default:
-		return -EINVAL;
+	memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
+
+	where = 0;
+	for (rec = (const struct ihex_binrec *)fw->data;
+	     rec;
+	     rec = ihex_next_binrec(rec)) {
+		unsigned int src_size, dst_size;
+
+		DRM_DEBUG(" pcbase = 0x%08lx  vcbase = %p\n", pcbase, vcbase);
+		dev_priv->warp_pipe_phys[where] = pcbase;
+		src_size = be16_to_cpu(rec->len);
+		dst_size = WARP_UCODE_SIZE(src_size);
+		memcpy(vcbase, rec->data, src_size);
+		pcbase += dst_size;
+		vcbase += dst_size;
+		where++;
 	}
+
+out:
+	release_firmware(fw);
+	return rc;
 }
 
 #define WMISC_EXPECTED		(MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index c75fd35..4c39a40 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -29,6 +29,9 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
@@ -36,50 +39,9 @@
 
 #define R128_FIFO_DEBUG		0
 
-/* CCE microcode (from ATI) */
-static u32 r128_cce_microcode[] = {
-	0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0,
-	1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0,
-	599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1,
-	11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11,
-	262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28,
-	1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9,
-	30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656,
-	1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1,
-	15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071,
-	12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2,
-	46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1,
-	459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
-	18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1,
-	15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2,
-	268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1,
-	15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82,
-	1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729,
-	3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008,
-	1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
-	15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1,
-	180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1,
-	114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0,
-	33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370,
-	1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1,
-	14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793,
-	1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
-	198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1,
-	114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1,
-	1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1,
-	1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894,
-	16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14,
-	174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1,
-	33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1,
-	33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1,
-	409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
+#define FIRMWARE_NAME		"r128/r128_cce.bin"
+
+MODULE_FIRMWARE(FIRMWARE_NAME);
 
 static int R128_READ_PLL(struct drm_device * dev, int addr)
 {
@@ -176,20 +138,50 @@ static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv)
  */
 
 /* Load the microcode for the CCE */
-static void r128_cce_load_microcode(drm_r128_private_t * dev_priv)
+static int r128_cce_load_microcode(drm_r128_private_t *dev_priv)
 {
-	int i;
+	struct platform_device *pdev;
+	const struct firmware *fw;
+	const __be32 *fw_data;
+	int rc, i;
 
 	DRM_DEBUG("\n");
 
+	pdev = platform_device_register_simple("r128_cce", 0, NULL, 0);
+	if (IS_ERR(pdev)) {
+		printk(KERN_ERR "r128_cce: Failed to register firmware\n");
+		return PTR_ERR(pdev);
+	}
+	rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev);
+	platform_device_unregister(pdev);
+	if (rc) {
+		printk(KERN_ERR "r128_cce: Failed to load firmware \"%s\"\n",
+		       FIRMWARE_NAME);
+		return rc;
+	}
+
+	if (fw->size != 256 * 8) {
+		printk(KERN_ERR
+		       "r128_cce: Bogus length %zu in firmware \"%s\"\n",
+		       fw->size, FIRMWARE_NAME);
+		rc = -EINVAL;
+		goto out_release;
+	}
+
 	r128_do_wait_for_idle(dev_priv);
 
+	fw_data = (const __be32 *)fw->data;
 	R128_WRITE(R128_PM4_MICROCODE_ADDR, 0);
 	for (i = 0; i < 256; i++) {
-		R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]);
+		R128_WRITE(R128_PM4_MICROCODE_DATAH,
+			   be32_to_cpup(&fw_data[i * 2]));
 		R128_WRITE(R128_PM4_MICROCODE_DATAL,
-			   r128_cce_microcode[i * 2 + 1]);
+			   be32_to_cpup(&fw_data[i * 2 + 1]));
 	}
+
+out_release:
+	release_firmware(fw);
+	return rc;
 }
 
 /* Flush any pending commands to the CCE.  This should only be used just
@@ -350,9 +342,15 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev,
 static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
 {
 	drm_r128_private_t *dev_priv;
+	int rc;
 
 	DRM_DEBUG("\n");
 
+	if (dev->dev_private) {
+		DRM_DEBUG("called when already initialized\n");
+		return -EINVAL;
+	}
+
 	dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL);
 	if (dev_priv == NULL)
 		return -ENOMEM;
@@ -575,13 +573,18 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
 #endif
 
 	r128_cce_init_ring_buffer(dev, dev_priv);
-	r128_cce_load_microcode(dev_priv);
+	rc = r128_cce_load_microcode(dev_priv);
 
 	dev->dev_private = (void *)dev_priv;
 
 	r128_do_engine_reset(dev);
 
-	return 0;
+	if (rc) {
+		DRM_ERROR("Failed to load firmware!\n");
+		r128_do_cleanup_cce(dev);
+	}
+
+	return rc;
 }
 
 int r128_do_cleanup_cce(struct drm_device * dev)
@@ -649,6 +652,8 @@ int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_pri
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
 		DRM_DEBUG("while CCE running\n");
 		return 0;
@@ -671,6 +676,8 @@ int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	/* Flush any pending CCE commands.  This ensures any outstanding
 	 * commands are exectuted by the engine before we turn it off.
 	 */
@@ -708,10 +715,7 @@ int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_pri
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	if (!dev_priv) {
-		DRM_DEBUG("called before init done\n");
-		return -EINVAL;
-	}
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
 
 	r128_do_cce_reset(dev_priv);
 
@@ -728,6 +732,8 @@ int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	if (dev_priv->cce_running) {
 		r128_do_cce_flush(dev_priv);
 	}
@@ -741,6 +747,8 @@ int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev->dev_private);
+
 	return r128_do_engine_reset(dev);
 }
 
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h
index 797a26c..3c60829 100644
--- a/drivers/gpu/drm/r128/r128_drv.h
+++ b/drivers/gpu/drm/r128/r128_drv.h
@@ -422,6 +422,14 @@ static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv)
  * Misc helper macros
  */
 
+#define DEV_INIT_TEST_WITH_RETURN(_dev_priv)				\
+do {									\
+	if (!_dev_priv) {						\
+		DRM_ERROR("called with no initialization\n");		\
+		return -EINVAL;						\
+	}								\
+} while (0)
+
 #define RING_SPACE_TEST_WITH_RETURN( dev_priv )				\
 do {									\
 	drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i;		\
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c
index 026a48c..af2665c 100644
--- a/drivers/gpu/drm/r128/r128_state.c
+++ b/drivers/gpu/drm/r128/r128_state.c
@@ -1244,14 +1244,18 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple)
 static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
-	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	drm_r128_sarea_t *sarea_priv;
 	drm_r128_clear_t *clear = data;
 	DRM_DEBUG("\n");
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
 
+	sarea_priv = dev_priv->sarea_priv;
+
 	if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
 		sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
 
@@ -1312,6 +1316,8 @@ static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *fi
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
 
 	if (!dev_priv->page_flipping)
@@ -1331,6 +1337,8 @@ static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *fi
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
 
 	if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
@@ -1354,10 +1362,7 @@ static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
 
 	DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
 		  DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
@@ -1410,10 +1415,7 @@ static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
 
 	DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
 		  elts->idx, elts->start, elts->end, elts->discard);
@@ -1476,6 +1478,8 @@ static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *fi
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx);
 
 	if (blit->idx < 0 || blit->idx >= dma->buf_count) {
@@ -1501,6 +1505,8 @@ static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *f
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
 
 	ret = -EINVAL;
@@ -1531,6 +1537,8 @@ static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
+
 	if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
 		return -EFAULT;
 
@@ -1555,10 +1563,7 @@ static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file
 
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
 
 	DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
 		  indirect->idx, indirect->start, indirect->end,
@@ -1620,10 +1625,7 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi
 	drm_r128_getparam_t *param = data;
 	int value;
 
-	if (!dev_priv) {
-		DRM_ERROR("called with no initialization\n");
-		return -EINVAL;
-	}
+	DEV_INIT_TEST_WITH_RETURN(dev_priv);
 
 	DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
 
diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index 2168d67..5982321 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -1,7 +1,6 @@
 config DRM_RADEON_KMS
 	bool "Enable modesetting on radeon by default"
 	depends on DRM_RADEON
-	select DRM_TTM
 	help
 	  Choose this option if you want kernel modesetting enabled by default,
 	  and you have a new enough userspace to support this. Running old
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 013d380..09a2892 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -3,18 +3,53 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 ccflags-y := -Iinclude/drm
+
+hostprogs-y := mkregtable
+
+quiet_cmd_mkregtable = MKREGTABLE $@
+      cmd_mkregtable = $(obj)/mkregtable $< > $@
+
+$(obj)/rn50_reg_safe.h: $(src)/reg_srcs/rn50 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
+$(obj)/r100_reg_safe.h: $(src)/reg_srcs/r100 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
+$(obj)/r200_reg_safe.h: $(src)/reg_srcs/r200 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
+$(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
+$(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
+$(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable
+	$(call if_changed,mkregtable)
+
+$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h
+
+$(obj)/r200.o: $(obj)/r200_reg_safe.h
+
+$(obj)/rv515.o: $(obj)/rv515_reg_safe.h
+
+$(obj)/r300.o: $(obj)/r300_reg_safe.h
+
+$(obj)/rs600.o: $(obj)/rs600_reg_safe.h
+
 radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
 	radeon_irq.o r300_cmdbuf.o r600_cp.o
-
-radeon-$(CONFIG_DRM_RADEON_KMS) += radeon_device.o radeon_kms.o \
+# add KMS driver
+radeon-y += radeon_device.o radeon_kms.o \
 	radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \
 	atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \
 	radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \
 	radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \
 	radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \
 	radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
-	rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \
-	radeon_test.o
+	rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
+	r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
+	r600_blit_kms.o
 
 radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
 
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h
index cf67928..5d40208 100644
--- a/drivers/gpu/drm/radeon/atombios.h
+++ b/drivers/gpu/drm/radeon/atombios.h
@@ -2374,6 +2374,17 @@ typedef struct _ATOM_ANALOG_TV_INFO {
 	ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING];
 } ATOM_ANALOG_TV_INFO;
 
+#define MAX_SUPPORTED_TV_TIMING_V1_2    3
+
+typedef struct _ATOM_ANALOG_TV_INFO_V1_2 {
+	ATOM_COMMON_TABLE_HEADER sHeader;
+	UCHAR                    ucTV_SupportedStandard;
+	UCHAR                    ucTV_BootUpDefaultStandard;
+	UCHAR                    ucExt_TV_ASIC_ID;
+	UCHAR                    ucExt_TV_ASIC_SlaveAddr;
+	ATOM_DTD_FORMAT          aModeTimings[MAX_SUPPORTED_TV_TIMING];
+} ATOM_ANALOG_TV_INFO_V1_2;
+
 /**************************************************************************/
 /*  VRAM usage and their defintions */
 
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 74d034f..6a01592 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -31,6 +31,10 @@
 #include "atom.h"
 #include "atom-bits.h"
 
+/* evil but including atombios.h is much worse */
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+				SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
+				int32_t *pixel_clock);
 static void atombios_overscan_setup(struct drm_crtc *crtc,
 				    struct drm_display_mode *mode,
 				    struct drm_display_mode *adjusted_mode)
@@ -89,17 +93,32 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 	ENABLE_SCALER_PS_ALLOCATION args;
 	int index = GetIndexIntoMasterTable(COMMAND, EnableScaler);
+
 	/* fixme - fill in enc_priv for atom dac */
 	enum radeon_tv_std tv_std = TV_STD_NTSC;
+	bool is_tv = false, is_cv = false;
+	struct drm_encoder *encoder;
 
 	if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id)
 		return;
 
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		/* find tv std */
+		if (encoder->crtc == crtc) {
+			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+			if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
+				struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+				tv_std = tv_dac->tv_std;
+				is_tv = true;
+			}
+		}
+	}
+
 	memset(&args, 0, sizeof(args));
 
 	args.ucScaler = radeon_crtc->crtc_id;
 
-	if (radeon_crtc->devices & (ATOM_DEVICE_TV_SUPPORT)) {
+	if (is_tv) {
 		switch (tv_std) {
 		case TV_STD_NTSC:
 		default:
@@ -128,7 +147,7 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
 			break;
 		}
 		args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
-	} else if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT)) {
+	} else if (is_cv) {
 		args.ucTVStandard = ATOM_TV_CV;
 		args.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
 	} else {
@@ -151,9 +170,9 @@ static void atombios_scaler_setup(struct drm_crtc *crtc)
 		}
 	}
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
-	if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)
-	    && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_RV570) {
-		atom_rv515_force_tv_scaler(rdev);
+	if ((is_tv || is_cv)
+	    && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) {
+		atom_rv515_force_tv_scaler(rdev, radeon_crtc);
 	}
 }
 
@@ -370,6 +389,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 					pll_flags |= RADEON_PLL_USE_REF_DIV;
 			}
 			radeon_encoder = to_radeon_encoder(encoder);
+			break;
 		}
 	}
 
@@ -468,6 +488,11 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 	}
 
 	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		fb_format =
+		    AVIVO_D1GRPH_CONTROL_DEPTH_8BPP |
+		    AVIVO_D1GRPH_CONTROL_8BPP_INDEXED;
+		break;
 	case 15:
 		fb_format =
 		    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
@@ -551,42 +576,68 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_encoder *encoder;
 	SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
+	int need_tv_timings = 0;
+	bool ret;
 
 	/* TODO color tiling */
 	memset(&crtc_timing, 0, sizeof(crtc_timing));
 
-	/* TODO tv */
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-
+		/* find tv std */
+		if (encoder->crtc == crtc) {
+			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+			if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
+				struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv;
+				if (tv_dac) {
+					if (tv_dac->tv_std == TV_STD_NTSC ||
+					    tv_dac->tv_std == TV_STD_NTSC_J ||
+					    tv_dac->tv_std == TV_STD_PAL_M)
+						need_tv_timings = 1;
+					else
+						need_tv_timings = 2;
+					break;
+				}
+			}
+		}
 	}
 
 	crtc_timing.ucCRTC = radeon_crtc->crtc_id;
-	crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
-	crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
-	crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
-	crtc_timing.usH_SyncWidth =
-	    adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
+	if (need_tv_timings) {
+		ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1,
+						 &crtc_timing, &adjusted_mode->clock);
+		if (ret == false)
+			need_tv_timings = 0;
+	}
 
-	crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
-	crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
-	crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
-	crtc_timing.usV_SyncWidth =
-	    adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
+	if (!need_tv_timings) {
+		crtc_timing.usH_Total = adjusted_mode->crtc_htotal;
+		crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay;
+		crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start;
+		crtc_timing.usH_SyncWidth =
+			adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start;
 
-	if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
-		crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
+		crtc_timing.usV_Total = adjusted_mode->crtc_vtotal;
+		crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay;
+		crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start;
+		crtc_timing.usV_SyncWidth =
+			adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start;
 
-	if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
-		crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+			crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
 
-	if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
-		crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+			crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
 
-	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
-		crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC)
+			crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
 
-	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
-		crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
+			crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
+
+		if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
+			crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
+	}
 
 	atombios_crtc_set_pll(crtc, adjusted_mode);
 	atombios_crtc_set_timing(crtc, &crtc_timing);
diff --git a/drivers/gpu/drm/radeon/avivod.h b/drivers/gpu/drm/radeon/avivod.h
new file mode 100644
index 0000000..e2b92c4
--- /dev/null
+++ b/drivers/gpu/drm/radeon/avivod.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef AVIVOD_H
+#define AVIVOD_H
+
+
+#define	D1CRTC_CONTROL					0x6080
+#define		CRTC_EN						(1 << 0)
+#define	D1CRTC_UPDATE_LOCK				0x60E8
+#define	D1GRPH_PRIMARY_SURFACE_ADDRESS			0x6110
+#define	D1GRPH_SECONDARY_SURFACE_ADDRESS		0x6118
+
+#define	D2CRTC_CONTROL					0x6880
+#define	D2CRTC_UPDATE_LOCK				0x68E8
+#define	D2GRPH_PRIMARY_SURFACE_ADDRESS			0x6910
+#define	D2GRPH_SECONDARY_SURFACE_ADDRESS		0x6918
+
+#define	D1VGA_CONTROL					0x0330
+#define		DVGA_CONTROL_MODE_ENABLE			(1 << 0)
+#define		DVGA_CONTROL_TIMING_SELECT			(1 << 8)
+#define		DVGA_CONTROL_SYNC_POLARITY_SELECT		(1 << 9)
+#define		DVGA_CONTROL_OVERSCAN_TIMING_SELECT		(1 << 10)
+#define		DVGA_CONTROL_OVERSCAN_COLOR_EN			(1 << 16)
+#define		DVGA_CONTROL_ROTATE				(1 << 24)
+#define D2VGA_CONTROL					0x0338
+
+#define	VGA_HDP_CONTROL					0x328
+#define		VGA_MEM_PAGE_SELECT_EN				(1 << 0)
+#define		VGA_MEMORY_DISABLE				(1 << 4)
+#define		VGA_RBBM_LOCK_DISABLE				(1 << 8)
+#define		VGA_SOFT_RESET					(1 << 16)
+#define	VGA_MEMORY_BASE_ADDRESS				0x0310
+#define	VGA_RENDER_CONTROL				0x0300
+#define		VGA_VSTATUS_CNTL_MASK				0x00030000
+
+/* AVIVO disable VGA rendering */
+static inline void radeon_avivo_vga_render_disable(struct radeon_device *rdev)
+{
+	u32 vga_render;
+	vga_render = RREG32(VGA_RENDER_CONTROL);
+	vga_render &= ~VGA_VSTATUS_CNTL_MASK;
+	WREG32(VGA_RENDER_CONTROL, vga_render);
+}
+
+#endif
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c
new file mode 100644
index 0000000..fb211e5
--- /dev/null
+++ b/drivers/gpu/drm/radeon/mkregtable.c
@@ -0,0 +1,720 @@
+/* utility to create the register check tables
+ * this includes inlined list.h safe for userspace.
+ *
+ * Copyright 2009 Jerome Glisse
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Authors:
+ * 	Jerome Glisse
+ * 	Dave Airlie
+ */
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <regex.h>
+#include <libgen.h>
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:    the pointer to the member.
+ * @type:   the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({          \
+	const typeof(((type *)0)->member)*__mptr = (ptr);    \
+		     (type *)((char *)__mptr - offsetof(type, member)); })
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+	struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+	list->next = list;
+	list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void __list_add(struct list_head *new,
+			      struct list_head *prev, struct list_head *next)
+{
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
+}
+#else
+extern void __list_add(struct list_head *new,
+		       struct list_head *prev, struct list_head *next);
+#endif
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head *prev, struct list_head *next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+#ifndef CONFIG_DEBUG_LIST
+static inline void list_del(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	entry->next = (void *)0xDEADBEEF;
+	entry->prev = (void *)0xBEEFDEAD;
+}
+#else
+extern void list_del(struct list_head *entry);
+#endif
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old, struct list_head *new)
+{
+	new->next = old->next;
+	new->next->prev = new;
+	new->prev = old->prev;
+	new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+				     struct list_head *new)
+{
+	list_replace(old, new);
+	INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+				  struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+			       const struct list_head *head)
+{
+	return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+	struct list_head *next = head->next;
+	return (next == head) && (next == head->prev);
+}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+	return !list_empty(head) && (head->next == head->prev);
+}
+
+static inline void __list_cut_position(struct list_head *list,
+				       struct list_head *head,
+				       struct list_head *entry)
+{
+	struct list_head *new_first = entry->next;
+	list->next = head->next;
+	list->next->prev = list;
+	list->prev = entry;
+	entry->next = list;
+	head->next = new_first;
+	new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ *	and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ *
+ */
+static inline void list_cut_position(struct list_head *list,
+				     struct list_head *head,
+				     struct list_head *entry)
+{
+	if (list_empty(head))
+		return;
+	if (list_is_singular(head) && (head->next != entry && head != entry))
+		return;
+	if (entry == head)
+		INIT_LIST_HEAD(list);
+	else
+		__list_cut_position(list, head, entry);
+}
+
+static inline void __list_splice(const struct list_head *list,
+				 struct list_head *prev, struct list_head *next)
+{
+	struct list_head *first = list->next;
+	struct list_head *last = list->prev;
+
+	first->prev = prev;
+	prev->next = first;
+
+	last->next = next;
+	next->prev = last;
+}
+
+/**
+ * list_splice - join two lists, this is designed for stacks
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(const struct list_head *list,
+			       struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head, head->next);
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice_tail(struct list_head *list,
+				    struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head->prev, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+				    struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head, head->next);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_tail_init(struct list_head *list,
+					 struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head->prev, head);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:	the &struct list_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:	the list head to take the element from.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+		pos = pos->next)
+
+/**
+ * __list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev	-	iterate over a list backwards
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+	for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+		pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+	for (pos = (head)->next, n = pos->next; pos != (head); \
+		pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+	for (pos = (head)->prev, n = pos->prev; \
+	     prefetch(pos->prev), pos != (head); \
+	     pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry	-	iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &pos->member != (head); 	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)			\
+	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
+	     prefetch(pos->member.prev), &pos->member != (head); 	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos:	the type * to use as a start point
+ * @head:	the head of the list
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+	((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
+	     prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member)		\
+	for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     prefetch(pos->member.prev), &pos->member != (head);	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member) 			\
+	for (; prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+		n = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member) 		\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member), 		\
+		n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) 			\
+	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
+	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
+		n = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     &pos->member != (head); 					\
+	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+struct offset {
+	struct list_head list;
+	unsigned offset;
+};
+
+struct table {
+	struct list_head offsets;
+	unsigned offset_max;
+	unsigned nentry;
+	unsigned *table;
+	char *gpu_prefix;
+};
+
+struct offset *offset_new(unsigned o)
+{
+	struct offset *offset;
+
+	offset = (struct offset *)malloc(sizeof(struct offset));
+	if (offset) {
+		INIT_LIST_HEAD(&offset->list);
+		offset->offset = o;
+	}
+	return offset;
+}
+
+void table_offset_add(struct table *t, struct offset *offset)
+{
+	list_add_tail(&offset->list, &t->offsets);
+}
+
+void table_init(struct table *t)
+{
+	INIT_LIST_HEAD(&t->offsets);
+	t->offset_max = 0;
+	t->nentry = 0;
+	t->table = NULL;
+}
+
+void table_print(struct table *t)
+{
+	unsigned nlloop, i, j, n, c, id;
+
+	nlloop = (t->nentry + 3) / 4;
+	c = t->nentry;
+	printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix,
+	       t->nentry);
+	for (i = 0, id = 0; i < nlloop; i++) {
+		n = 4;
+		if (n > c)
+			n = c;
+		c -= n;
+		for (j = 0; j < n; j++) {
+			if (j == 0)
+				printf("\t");
+			else
+				printf(" ");
+			printf("0x%08X,", t->table[id++]);
+		}
+		printf("\n");
+	}
+	printf("};\n");
+}
+
+int table_build(struct table *t)
+{
+	struct offset *offset;
+	unsigned i, m;
+
+	t->nentry = ((t->offset_max >> 2) + 31) / 32;
+	t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry);
+	if (t->table == NULL)
+		return -1;
+	memset(t->table, 0xff, sizeof(unsigned) * t->nentry);
+	list_for_each_entry(offset, &t->offsets, list) {
+		i = (offset->offset >> 2) / 32;
+		m = (offset->offset >> 2) & 31;
+		m = 1 << m;
+		t->table[i] ^= m;
+	}
+	return 0;
+}
+
+static char gpu_name[10];
+int parser_auth(struct table *t, const char *filename)
+{
+	FILE *file;
+	regex_t mask_rex;
+	regmatch_t match[4];
+	char buf[1024];
+	size_t end;
+	int len;
+	int done = 0;
+	int r;
+	unsigned o;
+	struct offset *offset;
+	char last_reg_s[10];
+	int last_reg;
+
+	if (regcomp
+	    (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) {
+		fprintf(stderr, "Failed to compile regular expression\n");
+		return -1;
+	}
+	file = fopen(filename, "r");
+	if (file == NULL) {
+		fprintf(stderr, "Failed to open: %s\n", filename);
+		return -1;
+	}
+	fseek(file, 0, SEEK_END);
+	end = ftell(file);
+	fseek(file, 0, SEEK_SET);
+
+	/* get header */
+	if (fgets(buf, 1024, file) == NULL)
+		return -1;
+
+	/* first line will contain the last register
+	 * and gpu name */
+	sscanf(buf, "%s %s", gpu_name, last_reg_s);
+	t->gpu_prefix = gpu_name;
+	last_reg = strtol(last_reg_s, NULL, 16);
+
+	do {
+		if (fgets(buf, 1024, file) == NULL)
+			return -1;
+		len = strlen(buf);
+		if (ftell(file) == end)
+			done = 1;
+		if (len) {
+			r = regexec(&mask_rex, buf, 4, match, 0);
+			if (r == REG_NOMATCH) {
+			} else if (r) {
+				fprintf(stderr,
+					"Error matching regular expression %d in %s\n",
+					r, filename);
+				return -1;
+			} else {
+				buf[match[0].rm_eo] = 0;
+				buf[match[1].rm_eo] = 0;
+				buf[match[2].rm_eo] = 0;
+				o = strtol(&buf[match[1].rm_so], NULL, 16);
+				offset = offset_new(o);
+				table_offset_add(t, offset);
+				if (o > t->offset_max)
+					t->offset_max = o;
+			}
+		}
+	} while (!done);
+	fclose(file);
+	if (t->offset_max < last_reg)
+		t->offset_max = last_reg;
+	return table_build(t);
+}
+
+int main(int argc, char *argv[])
+{
+	struct table t;
+
+	if (argc != 2) {
+		fprintf(stderr, "Usage: %s <authfile>\n", argv[0]);
+		exit(1);
+	}
+	table_init(&t);
+	if (parser_auth(&t, argv[1])) {
+		fprintf(stderr, "Failed to parse file %s\n", argv[1]);
+		return -1;
+	}
+	table_print(&t);
+	return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 68e728e..be51c5f 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -29,15 +29,41 @@
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
-#include "radeon_microcode.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "r100d.h"
+
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+
+#include "r100_reg_safe.h"
+#include "rn50_reg_safe.h"
+
+/* Firmware Names */
+#define FIRMWARE_R100		"radeon/R100_cp.bin"
+#define FIRMWARE_R200		"radeon/R200_cp.bin"
+#define FIRMWARE_R300		"radeon/R300_cp.bin"
+#define FIRMWARE_R420		"radeon/R420_cp.bin"
+#define FIRMWARE_RS690		"radeon/RS690_cp.bin"
+#define FIRMWARE_RS600		"radeon/RS600_cp.bin"
+#define FIRMWARE_R520		"radeon/R520_cp.bin"
+
+MODULE_FIRMWARE(FIRMWARE_R100);
+MODULE_FIRMWARE(FIRMWARE_R200);
+MODULE_FIRMWARE(FIRMWARE_R300);
+MODULE_FIRMWARE(FIRMWARE_R420);
+MODULE_FIRMWARE(FIRMWARE_RS690);
+MODULE_FIRMWARE(FIRMWARE_RS600);
+MODULE_FIRMWARE(FIRMWARE_R520);
+
+#include "r100_track.h"
 
 /* This files gather functions specifics to:
  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
  *
  * Some of these functions might be used by newer ASICs.
  */
+int r200_init(struct radeon_device *rdev);
 void r100_hdp_reset(struct radeon_device *rdev);
 void r100_gpu_init(struct radeon_device *rdev);
 int r100_gui_wait_for_idle(struct radeon_device *rdev);
@@ -58,23 +84,28 @@ void r100_pci_gart_tlb_flush(struct radeon_device *rdev)
 	 * could end up in wrong address. */
 }
 
-int r100_pci_gart_enable(struct radeon_device *rdev)
+int r100_pci_gart_init(struct radeon_device *rdev)
 {
-	uint32_t tmp;
 	int r;
 
+	if (rdev->gart.table.ram.ptr) {
+		WARN(1, "R100 PCI GART already initialized.\n");
+		return 0;
+	}
 	/* Initialize common gart structure */
 	r = radeon_gart_init(rdev);
-	if (r) {
+	if (r)
 		return r;
-	}
-	if (rdev->gart.table.ram.ptr == NULL) {
-		rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
-		r = radeon_gart_table_ram_alloc(rdev);
-		if (r) {
-			return r;
-		}
-	}
+	rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
+	rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+	rdev->asic->gart_set_page = &r100_pci_gart_set_page;
+	return radeon_gart_table_ram_alloc(rdev);
+}
+
+int r100_pci_gart_enable(struct radeon_device *rdev)
+{
+	uint32_t tmp;
+
 	/* discard memory request outside of configured range */
 	tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
 	WREG32(RADEON_AIC_CNTL, tmp);
@@ -114,13 +145,11 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 	return 0;
 }
 
-int r100_gart_enable(struct radeon_device *rdev)
+void r100_pci_gart_fini(struct radeon_device *rdev)
 {
-	if (rdev->flags & RADEON_IS_AGP) {
-		r100_pci_gart_disable(rdev);
-		return 0;
-	}
-	return r100_pci_gart_enable(rdev);
+	r100_pci_gart_disable(rdev);
+	radeon_gart_table_ram_free(rdev);
+	radeon_gart_fini(rdev);
 }
 
 
@@ -247,9 +276,6 @@ int r100_mc_init(struct radeon_device *rdev)
 
 void r100_mc_fini(struct radeon_device *rdev)
 {
-	r100_pci_gart_disable(rdev);
-	radeon_gart_table_ram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 
@@ -273,6 +299,17 @@ int r100_irq_set(struct radeon_device *rdev)
 	return 0;
 }
 
+void r100_irq_disable(struct radeon_device *rdev)
+{
+	u32 tmp;
+
+	WREG32(R_000040_GEN_INT_CNTL, 0);
+	/* Wait and acknowledge irq */
+	mdelay(1);
+	tmp = RREG32(R_000044_GEN_INT_STATUS);
+	WREG32(R_000044_GEN_INT_STATUS, tmp);
+}
+
 static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
 {
 	uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
@@ -293,6 +330,9 @@ int r100_irq_process(struct radeon_device *rdev)
 	if (!status) {
 		return IRQ_NONE;
 	}
+	if (rdev->shutdown) {
+		return IRQ_NONE;
+	}
 	while (status) {
 		/* SW interrupt */
 		if (status & RADEON_SW_INT_TEST) {
@@ -367,14 +407,21 @@ int r100_wb_init(struct radeon_device *rdev)
 			return r;
 		}
 	}
-	WREG32(0x774, rdev->wb.gpu_addr);
-	WREG32(0x70C, rdev->wb.gpu_addr + 1024);
-	WREG32(0x770, 0xff);
+	WREG32(R_000774_SCRATCH_ADDR, rdev->wb.gpu_addr);
+	WREG32(R_00070C_CP_RB_RPTR_ADDR,
+		S_00070C_RB_RPTR_ADDR((rdev->wb.gpu_addr + 1024) >> 2));
+	WREG32(R_000770_SCRATCH_UMSK, 0xff);
 	return 0;
 }
 
+void r100_wb_disable(struct radeon_device *rdev)
+{
+	WREG32(R_000770_SCRATCH_UMSK, 0);
+}
+
 void r100_wb_fini(struct radeon_device *rdev)
 {
+	r100_wb_disable(rdev);
 	if (rdev->wb.wb_obj) {
 		radeon_object_kunmap(rdev->wb.wb_obj);
 		radeon_object_unpin(rdev->wb.wb_obj);
@@ -461,6 +508,21 @@ int r100_copy_blit(struct radeon_device *rdev,
 /*
  * CP
  */
+static int r100_cp_wait_for_idle(struct radeon_device *rdev)
+{
+	unsigned i;
+	u32 tmp;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(R_000E40_RBBM_STATUS);
+		if (!G_000E40_CP_CMDSTRM_BUSY(tmp)) {
+			return 0;
+		}
+		udelay(1);
+	}
+	return -1;
+}
+
 void r100_ring_start(struct radeon_device *rdev)
 {
 	int r;
@@ -478,33 +540,33 @@ void r100_ring_start(struct radeon_device *rdev)
 	radeon_ring_unlock_commit(rdev);
 }
 
-static void r100_cp_load_microcode(struct radeon_device *rdev)
+
+/* Load the microcode for the CP */
+static int r100_cp_init_microcode(struct radeon_device *rdev)
 {
-	int i;
+	struct platform_device *pdev;
+	const char *fw_name = NULL;
+	int err;
 
-	if (r100_gui_wait_for_idle(rdev)) {
-		printk(KERN_WARNING "Failed to wait GUI idle while "
-		       "programming pipes. Bad things might happen.\n");
-	}
+	DRM_DEBUG("\n");
 
-	WREG32(RADEON_CP_ME_RAM_ADDR, 0);
+	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
+	err = IS_ERR(pdev);
+	if (err) {
+		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
+		return -EINVAL;
+	}
 	if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
 	    (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
 	    (rdev->family == CHIP_RS200)) {
 		DRM_INFO("Loading R100 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			WREG32(RADEON_CP_ME_RAM_DATAH, R100_cp_microcode[i][1]);
-			WREG32(RADEON_CP_ME_RAM_DATAL, R100_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R100;
 	} else if ((rdev->family == CHIP_R200) ||
 		   (rdev->family == CHIP_RV250) ||
 		   (rdev->family == CHIP_RV280) ||
 		   (rdev->family == CHIP_RS300)) {
 		DRM_INFO("Loading R200 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			WREG32(RADEON_CP_ME_RAM_DATAH, R200_cp_microcode[i][1]);
-			WREG32(RADEON_CP_ME_RAM_DATAL, R200_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R200;
 	} else if ((rdev->family == CHIP_R300) ||
 		   (rdev->family == CHIP_R350) ||
 		   (rdev->family == CHIP_RV350) ||
@@ -512,31 +574,19 @@ static void r100_cp_load_microcode(struct radeon_device *rdev)
 		   (rdev->family == CHIP_RS400) ||
 		   (rdev->family == CHIP_RS480)) {
 		DRM_INFO("Loading R300 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			WREG32(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]);
-			WREG32(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R300;
 	} else if ((rdev->family == CHIP_R420) ||
 		   (rdev->family == CHIP_R423) ||
 		   (rdev->family == CHIP_RV410)) {
 		DRM_INFO("Loading R400 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			WREG32(RADEON_CP_ME_RAM_DATAH, R420_cp_microcode[i][1]);
-			WREG32(RADEON_CP_ME_RAM_DATAL, R420_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R420;
 	} else if ((rdev->family == CHIP_RS690) ||
 		   (rdev->family == CHIP_RS740)) {
 		DRM_INFO("Loading RS690/RS740 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			WREG32(RADEON_CP_ME_RAM_DATAH, RS690_cp_microcode[i][1]);
-			WREG32(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_RS690;
 	} else if (rdev->family == CHIP_RS600) {
 		DRM_INFO("Loading RS600 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			WREG32(RADEON_CP_ME_RAM_DATAH, RS600_cp_microcode[i][1]);
-			WREG32(RADEON_CP_ME_RAM_DATAL, RS600_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_RS600;
 	} else if ((rdev->family == CHIP_RV515) ||
 		   (rdev->family == CHIP_R520) ||
 		   (rdev->family == CHIP_RV530) ||
@@ -544,9 +594,43 @@ static void r100_cp_load_microcode(struct radeon_device *rdev)
 		   (rdev->family == CHIP_RV560) ||
 		   (rdev->family == CHIP_RV570)) {
 		DRM_INFO("Loading R500 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			WREG32(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]);
-			WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]);
+		fw_name = FIRMWARE_R520;
+	}
+
+	err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
+	platform_device_unregister(pdev);
+	if (err) {
+		printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
+		       fw_name);
+	} else if (rdev->me_fw->size % 8) {
+		printk(KERN_ERR
+		       "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->me_fw->size, fw_name);
+		err = -EINVAL;
+		release_firmware(rdev->me_fw);
+		rdev->me_fw = NULL;
+	}
+	return err;
+}
+static void r100_cp_load_microcode(struct radeon_device *rdev)
+{
+	const __be32 *fw_data;
+	int i, size;
+
+	if (r100_gui_wait_for_idle(rdev)) {
+		printk(KERN_WARNING "Failed to wait GUI idle while "
+		       "programming pipes. Bad things might happen.\n");
+	}
+
+	if (rdev->me_fw) {
+		size = rdev->me_fw->size / 4;
+		fw_data = (const __be32 *)&rdev->me_fw->data[0];
+		WREG32(RADEON_CP_ME_RAM_ADDR, 0);
+		for (i = 0; i < size; i += 2) {
+			WREG32(RADEON_CP_ME_RAM_DATAH,
+			       be32_to_cpup(&fw_data[i]));
+			WREG32(RADEON_CP_ME_RAM_DATAL,
+			       be32_to_cpup(&fw_data[i + 1]));
 		}
 	}
 }
@@ -585,6 +669,15 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
 	} else {
 		DRM_INFO("radeon: cp idle (0x%08X)\n", tmp);
 	}
+
+	if (!rdev->me_fw) {
+		r = r100_cp_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
 	/* Align ring size */
 	rb_bufsz = drm_order(ring_size / 8);
 	ring_size = (1 << (rb_bufsz + 1)) * 4;
@@ -658,9 +751,11 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
 
 void r100_cp_fini(struct radeon_device *rdev)
 {
+	if (r100_cp_wait_for_idle(rdev)) {
+		DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n");
+	}
 	/* Disable ring */
-	rdev->cp.ready = false;
-	WREG32(RADEON_CP_CSQ_CNTL, 0);
+	r100_cp_disable(rdev);
 	radeon_ring_fini(rdev);
 	DRM_INFO("radeon: cp finalized\n");
 }
@@ -710,6 +805,12 @@ int r100_cp_reset(struct radeon_device *rdev)
 	return -1;
 }
 
+void r100_cp_commit(struct radeon_device *rdev)
+{
+	WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
+	(void)RREG32(RADEON_CP_RB_WPTR);
+}
+
 
 /*
  * CS functions
@@ -968,147 +1069,356 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
 	return 0;
 }
 
+static int r100_get_vtx_size(uint32_t vtx_fmt)
+{
+	int vtx_size;
+	vtx_size = 2;
+	/* ordered according to bits in spec */
+	if (vtx_fmt & RADEON_SE_VTX_FMT_W0)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_FPCOLOR)
+		vtx_size += 3;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_FPALPHA)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_PKCOLOR)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_FPSPEC)
+		vtx_size += 3;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_FPFOG)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_PKSPEC)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_ST0)
+		vtx_size += 2;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_ST1)
+		vtx_size += 2;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_Q1)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_ST2)
+		vtx_size += 2;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_Q2)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_ST3)
+		vtx_size += 2;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_Q3)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_Q0)
+		vtx_size++;
+	/* blend weight */
+	if (vtx_fmt & (0x7 << 15))
+		vtx_size += (vtx_fmt >> 15) & 0x7;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_N0)
+		vtx_size += 3;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_XY1)
+		vtx_size += 2;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_Z1)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_W1)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_N1)
+		vtx_size++;
+	if (vtx_fmt & RADEON_SE_VTX_FMT_Z)
+		vtx_size++;
+	return vtx_size;
+}
+
 static int r100_packet0_check(struct radeon_cs_parser *p,
-			      struct radeon_cs_packet *pkt)
+			      struct radeon_cs_packet *pkt,
+			      unsigned idx, unsigned reg)
 {
 	struct radeon_cs_chunk *ib_chunk;
 	struct radeon_cs_reloc *reloc;
+	struct r100_cs_track *track;
 	volatile uint32_t *ib;
 	uint32_t tmp;
-	unsigned reg;
-	unsigned i;
-	unsigned idx;
-	bool onereg;
 	int r;
+	int i, face;
 	u32 tile_flags = 0;
 
 	ib = p->ib->ptr;
 	ib_chunk = &p->chunks[p->chunk_ib_idx];
-	idx = pkt->idx + 1;
-	reg = pkt->reg;
-	onereg = false;
-	if (CP_PACKET0_GET_ONE_REG_WR(ib_chunk->kdata[pkt->idx])) {
-		onereg = true;
-	}
-	for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
-		switch (reg) {
-		case RADEON_CRTC_GUI_TRIG_VLINE:
-			r = r100_cs_packet_parse_vline(p);
-			if (r) {
-				DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-						idx, reg);
-				r100_cs_dump_packet(p, pkt);
-				return r;
-			}
-			break;
+	track = (struct r100_cs_track *)p->track;
+
+	switch (reg) {
+	case RADEON_CRTC_GUI_TRIG_VLINE:
+		r = r100_cs_packet_parse_vline(p);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		break;
 		/* FIXME: only allow PACKET3 blit? easier to check for out of
 		 * range access */
-		case RADEON_DST_PITCH_OFFSET:
-		case RADEON_SRC_PITCH_OFFSET:
-			r = r100_cs_packet_next_reloc(p, &reloc);
-			if (r) {
-				DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-					  idx, reg);
-				r100_cs_dump_packet(p, pkt);
-				return r;
-			}
-			tmp = ib_chunk->kdata[idx] & 0x003fffff;
-			tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
-
-			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-				tile_flags |= RADEON_DST_TILE_MACRO;
-			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-				if (reg == RADEON_SRC_PITCH_OFFSET) {
-					DRM_ERROR("Cannot src blit from microtiled surface\n");
-					r100_cs_dump_packet(p, pkt);
-					return -EINVAL;
-				}
-				tile_flags |= RADEON_DST_TILE_MICRO;
-			}
+	case RADEON_DST_PITCH_OFFSET:
+	case RADEON_SRC_PITCH_OFFSET:
+		r = r100_reloc_pitch_offset(p, pkt, idx, reg);
+		if (r)
+			return r;
+		break;
+	case RADEON_RB3D_DEPTHOFFSET:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->zb.robj = reloc->robj;
+		track->zb.offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		break;
+	case RADEON_RB3D_COLOROFFSET:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->cb[0].robj = reloc->robj;
+		track->cb[0].offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		break;
+	case RADEON_PP_TXOFFSET_0:
+	case RADEON_PP_TXOFFSET_1:
+	case RADEON_PP_TXOFFSET_2:
+		i = (reg - RADEON_PP_TXOFFSET_0) / 24;
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		track->textures[i].robj = reloc->robj;
+		break;
+	case RADEON_PP_CUBIC_OFFSET_T0_0:
+	case RADEON_PP_CUBIC_OFFSET_T0_1:
+	case RADEON_PP_CUBIC_OFFSET_T0_2:
+	case RADEON_PP_CUBIC_OFFSET_T0_3:
+	case RADEON_PP_CUBIC_OFFSET_T0_4:
+		i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4;
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->textures[0].cube_info[i].offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		track->textures[0].cube_info[i].robj = reloc->robj;
+		break;
+	case RADEON_PP_CUBIC_OFFSET_T1_0:
+	case RADEON_PP_CUBIC_OFFSET_T1_1:
+	case RADEON_PP_CUBIC_OFFSET_T1_2:
+	case RADEON_PP_CUBIC_OFFSET_T1_3:
+	case RADEON_PP_CUBIC_OFFSET_T1_4:
+		i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4;
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->textures[1].cube_info[i].offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		track->textures[1].cube_info[i].robj = reloc->robj;
+		break;
+	case RADEON_PP_CUBIC_OFFSET_T2_0:
+	case RADEON_PP_CUBIC_OFFSET_T2_1:
+	case RADEON_PP_CUBIC_OFFSET_T2_2:
+	case RADEON_PP_CUBIC_OFFSET_T2_3:
+	case RADEON_PP_CUBIC_OFFSET_T2_4:
+		i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4;
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->textures[2].cube_info[i].offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		track->textures[2].cube_info[i].robj = reloc->robj;
+		break;
+	case RADEON_RE_WIDTH_HEIGHT:
+		track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
+		break;
+	case RADEON_RB3D_COLORPITCH:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
 
-			tmp |= tile_flags;
-			ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
-			break;
-		case RADEON_RB3D_DEPTHOFFSET:
-		case RADEON_RB3D_COLOROFFSET:
-		case R300_RB3D_COLOROFFSET0:
-		case R300_ZB_DEPTHOFFSET:
-		case R200_PP_TXOFFSET_0:
-		case R200_PP_TXOFFSET_1:
-		case R200_PP_TXOFFSET_2:
-		case R200_PP_TXOFFSET_3:
-		case R200_PP_TXOFFSET_4:
-		case R200_PP_TXOFFSET_5:
-		case RADEON_PP_TXOFFSET_0:
-		case RADEON_PP_TXOFFSET_1:
-		case RADEON_PP_TXOFFSET_2:
-		case R300_TX_OFFSET_0:
-		case R300_TX_OFFSET_0+4:
-		case R300_TX_OFFSET_0+8:
-		case R300_TX_OFFSET_0+12:
-		case R300_TX_OFFSET_0+16:
-		case R300_TX_OFFSET_0+20:
-		case R300_TX_OFFSET_0+24:
-		case R300_TX_OFFSET_0+28:
-		case R300_TX_OFFSET_0+32:
-		case R300_TX_OFFSET_0+36:
-		case R300_TX_OFFSET_0+40:
-		case R300_TX_OFFSET_0+44:
-		case R300_TX_OFFSET_0+48:
-		case R300_TX_OFFSET_0+52:
-		case R300_TX_OFFSET_0+56:
-		case R300_TX_OFFSET_0+60:
-			/* rn50 has no 3D engine so fail on any 3d setup */
-			if (ASIC_IS_RN50(p->rdev)) {
-				DRM_ERROR("attempt to use RN50 3D engine failed\n");
-				return -EINVAL;
-			}
-			r = r100_cs_packet_next_reloc(p, &reloc);
-			if (r) {
-				DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-					  idx, reg);
-				r100_cs_dump_packet(p, pkt);
-				return r;
-			}
-			ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
-			break;
-		case R300_RB3D_COLORPITCH0:
-		case RADEON_RB3D_COLORPITCH:
-			r = r100_cs_packet_next_reloc(p, &reloc);
-			if (r) {
-				DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-					  idx, reg);
-				r100_cs_dump_packet(p, pkt);
-				return r;
-			}
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+			tile_flags |= RADEON_COLOR_TILE_ENABLE;
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+			tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
 
-			if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-				tile_flags |= RADEON_COLOR_TILE_ENABLE;
-			if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
-				tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
+		tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
+		tmp |= tile_flags;
+		ib[idx] = tmp;
 
-			tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
-			tmp |= tile_flags;
-			ib[idx] = tmp;
+		track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
+		break;
+	case RADEON_RB3D_DEPTHPITCH:
+		track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
+		break;
+	case RADEON_RB3D_CNTL:
+		switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
+		case 7:
+		case 8:
+		case 9:
+		case 11:
+		case 12:
+			track->cb[0].cpp = 1;
 			break;
-		case RADEON_RB3D_ZPASS_ADDR:
-			r = r100_cs_packet_next_reloc(p, &reloc);
-			if (r) {
-				DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-					  idx, reg);
-				r100_cs_dump_packet(p, pkt);
-				return r;
-			}
-			ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		case 3:
+		case 4:
+		case 15:
+			track->cb[0].cpp = 2;
+			break;
+		case 6:
+			track->cb[0].cpp = 4;
 			break;
 		default:
-			/* FIXME: we don't want to allow anyothers packet */
+			DRM_ERROR("Invalid color buffer format (%d) !\n",
+				  ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
+			return -EINVAL;
+		}
+		track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
+		break;
+	case RADEON_RB3D_ZSTENCILCNTL:
+		switch (ib_chunk->kdata[idx] & 0xf) {
+		case 0:
+			track->zb.cpp = 2;
+			break;
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 9:
+		case 11:
+			track->zb.cpp = 4;
 			break;
+		default:
+			break;
+		}
+		break;
+	case RADEON_RB3D_ZPASS_ADDR:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		break;
+	case RADEON_PP_CNTL:
+		{
+			uint32_t temp = ib_chunk->kdata[idx] >> 4;
+			for (i = 0; i < track->num_texture; i++)
+				track->textures[i].enabled = !!(temp & (1 << i));
 		}
-		if (onereg) {
-			/* FIXME: forbid onereg write to register on relocate */
+		break;
+	case RADEON_SE_VF_CNTL:
+		track->vap_vf_cntl = ib_chunk->kdata[idx];
+		break;
+	case RADEON_SE_VTX_FMT:
+		track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]);
+		break;
+	case RADEON_PP_TEX_SIZE_0:
+	case RADEON_PP_TEX_SIZE_1:
+	case RADEON_PP_TEX_SIZE_2:
+		i = (reg - RADEON_PP_TEX_SIZE_0) / 8;
+		track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
+		track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
+		break;
+	case RADEON_PP_TEX_PITCH_0:
+	case RADEON_PP_TEX_PITCH_1:
+	case RADEON_PP_TEX_PITCH_2:
+		i = (reg - RADEON_PP_TEX_PITCH_0) / 8;
+		track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
+		break;
+	case RADEON_PP_TXFILTER_0:
+	case RADEON_PP_TXFILTER_1:
+	case RADEON_PP_TXFILTER_2:
+		i = (reg - RADEON_PP_TXFILTER_0) / 24;
+		track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK)
+						 >> RADEON_MAX_MIP_LEVEL_SHIFT);
+		tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
+		if (tmp == 2 || tmp == 6)
+			track->textures[i].roundup_w = false;
+		tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
+		if (tmp == 2 || tmp == 6)
+			track->textures[i].roundup_h = false;
+		break;
+	case RADEON_PP_TXFORMAT_0:
+	case RADEON_PP_TXFORMAT_1:
+	case RADEON_PP_TXFORMAT_2:
+		i = (reg - RADEON_PP_TXFORMAT_0) / 24;
+		if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) {
+			track->textures[i].use_pitch = 1;
+		} else {
+			track->textures[i].use_pitch = 0;
+			track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
+			track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+		}
+		if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
+			track->textures[i].tex_coord_type = 2;
+		switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
+		case RADEON_TXFORMAT_I8:
+		case RADEON_TXFORMAT_RGB332:
+		case RADEON_TXFORMAT_Y8:
+			track->textures[i].cpp = 1;
 			break;
+		case RADEON_TXFORMAT_AI88:
+		case RADEON_TXFORMAT_ARGB1555:
+		case RADEON_TXFORMAT_RGB565:
+		case RADEON_TXFORMAT_ARGB4444:
+		case RADEON_TXFORMAT_VYUY422:
+		case RADEON_TXFORMAT_YVYU422:
+		case RADEON_TXFORMAT_DXT1:
+		case RADEON_TXFORMAT_SHADOW16:
+		case RADEON_TXFORMAT_LDUDV655:
+		case RADEON_TXFORMAT_DUDV88:
+			track->textures[i].cpp = 2;
+			break;
+		case RADEON_TXFORMAT_ARGB8888:
+		case RADEON_TXFORMAT_RGBA8888:
+		case RADEON_TXFORMAT_DXT23:
+		case RADEON_TXFORMAT_DXT45:
+		case RADEON_TXFORMAT_SHADOW32:
+		case RADEON_TXFORMAT_LDUDUV8888:
+			track->textures[i].cpp = 4;
+			break;
+		}
+		track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
+		track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
+		break;
+	case RADEON_PP_CUBIC_FACES_0:
+	case RADEON_PP_CUBIC_FACES_1:
+	case RADEON_PP_CUBIC_FACES_2:
+		tmp = ib_chunk->kdata[idx];
+		i = (reg - RADEON_PP_CUBIC_FACES_0) / 4;
+		for (face = 0; face < 4; face++) {
+			track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
+			track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
 		}
+		break;
+	default:
+		printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+		       reg, idx);
+		return -EINVAL;
 	}
 	return 0;
 }
@@ -1137,6 +1447,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 {
 	struct radeon_cs_chunk *ib_chunk;
 	struct radeon_cs_reloc *reloc;
+	struct r100_cs_track *track;
 	unsigned idx;
 	unsigned i, c;
 	volatile uint32_t *ib;
@@ -1145,9 +1456,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 	ib = p->ib->ptr;
 	ib_chunk = &p->chunks[p->chunk_ib_idx];
 	idx = pkt->idx + 1;
+	track = (struct r100_cs_track *)p->track;
 	switch (pkt->opcode) {
 	case PACKET3_3D_LOAD_VBPNTR:
 		c = ib_chunk->kdata[idx++];
+		track->num_arrays = c;
 		for (i = 0; i < (c - 1); i += 2, idx += 3) {
 			r = r100_cs_packet_next_reloc(p, &reloc);
 			if (r) {
@@ -1157,6 +1470,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 				return r;
 			}
 			ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
+			track->arrays[i + 0].robj = reloc->robj;
+			track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
+			track->arrays[i + 0].esize &= 0x7F;
 			r = r100_cs_packet_next_reloc(p, &reloc);
 			if (r) {
 				DRM_ERROR("No reloc for packet3 %d\n",
@@ -1165,6 +1481,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 				return r;
 			}
 			ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset);
+			track->arrays[i + 1].robj = reloc->robj;
+			track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24;
+			track->arrays[i + 1].esize &= 0x7F;
 		}
 		if (c & 1) {
 			r = r100_cs_packet_next_reloc(p, &reloc);
@@ -1175,6 +1494,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 				return r;
 			}
 			ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
+			track->arrays[i + 0].robj = reloc->robj;
+			track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
+			track->arrays[i + 0].esize &= 0x7F;
 		}
 		break;
 	case PACKET3_INDX_BUFFER:
@@ -1191,7 +1513,6 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 		}
 		break;
 	case 0x23:
-		/* FIXME: cleanup */
 		/* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */
 		r = r100_cs_packet_next_reloc(p, &reloc);
 		if (r) {
@@ -1200,18 +1521,71 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 			return r;
 		}
 		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		track->num_arrays = 1;
+		track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]);
+
+		track->arrays[0].robj = reloc->robj;
+		track->arrays[0].esize = track->vtx_size;
+
+		track->max_indx = ib_chunk->kdata[idx+1];
+
+		track->vap_vf_cntl = ib_chunk->kdata[idx+3];
+		track->immd_dwords = pkt->count - 1;
+		r = r100_cs_track_check(p->rdev, track);
+		if (r)
+			return r;
 		break;
 	case PACKET3_3D_DRAW_IMMD:
+		if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) {
+			DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
+			return -EINVAL;
+		}
+		track->vap_vf_cntl = ib_chunk->kdata[idx+1];
+		track->immd_dwords = pkt->count - 1;
+		r = r100_cs_track_check(p->rdev, track);
+		if (r)
+			return r;
+		break;
 		/* triggers drawing using in-packet vertex data */
 	case PACKET3_3D_DRAW_IMMD_2:
+		if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) {
+			DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
+			return -EINVAL;
+		}
+		track->vap_vf_cntl = ib_chunk->kdata[idx];
+		track->immd_dwords = pkt->count;
+		r = r100_cs_track_check(p->rdev, track);
+		if (r)
+			return r;
+		break;
 		/* triggers drawing using in-packet vertex data */
 	case PACKET3_3D_DRAW_VBUF_2:
+		track->vap_vf_cntl = ib_chunk->kdata[idx];
+		r = r100_cs_track_check(p->rdev, track);
+		if (r)
+			return r;
+		break;
 		/* triggers drawing of vertex buffers setup elsewhere */
 	case PACKET3_3D_DRAW_INDX_2:
+		track->vap_vf_cntl = ib_chunk->kdata[idx];
+		r = r100_cs_track_check(p->rdev, track);
+		if (r)
+			return r;
+		break;
 		/* triggers drawing using indices to vertex buffer */
 	case PACKET3_3D_DRAW_VBUF:
+		track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
+		r = r100_cs_track_check(p->rdev, track);
+		if (r)
+			return r;
+		break;
 		/* triggers drawing of vertex buffers setup elsewhere */
 	case PACKET3_3D_DRAW_INDX:
+		track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
+		r = r100_cs_track_check(p->rdev, track);
+		if (r)
+			return r;
+		break;
 		/* triggers drawing using indices to vertex buffer */
 	case PACKET3_NOP:
 		break;
@@ -1225,8 +1599,12 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
 int r100_cs_parse(struct radeon_cs_parser *p)
 {
 	struct radeon_cs_packet pkt;
+	struct r100_cs_track *track;
 	int r;
 
+	track = kzalloc(sizeof(*track), GFP_KERNEL);
+	r100_cs_track_clear(p->rdev, track);
+	p->track = track;
 	do {
 		r = r100_cs_packet_parse(p, &pkt, p->idx);
 		if (r) {
@@ -1235,7 +1613,16 @@ int r100_cs_parse(struct radeon_cs_parser *p)
 		p->idx += pkt.count + 2;
 		switch (pkt.type) {
 			case PACKET_TYPE0:
-				r = r100_packet0_check(p, &pkt);
+				if (p->rdev->family >= CHIP_R200)
+					r = r100_cs_parse_packet0(p, &pkt,
+								  p->rdev->config.r100.reg_safe_bm,
+								  p->rdev->config.r100.reg_safe_bm_size,
+								  &r200_packet0_check);
+				else
+					r = r100_cs_parse_packet0(p, &pkt,
+								  p->rdev->config.r100.reg_safe_bm,
+								  p->rdev->config.r100.reg_safe_bm_size,
+								  &r100_packet0_check);
 				break;
 			case PACKET_TYPE2:
 				break;
@@ -1568,6 +1955,20 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
 		rdev->mc.real_vram_size = rdev->mc.aper_size;
 }
 
+void r100_vga_set_state(struct radeon_device *rdev, bool state)
+{
+	uint32_t temp;
+
+	temp = RREG32(RADEON_CONFIG_CNTL);
+	if (state == false) {
+		temp &= ~(1<<8);
+		temp |= (1<<9);
+	} else {
+		temp &= ~(1<<9);
+	}
+	WREG32(RADEON_CONFIG_CNTL, temp);
+}
+
 void r100_vram_info(struct radeon_device *rdev)
 {
 	r100_vram_get_type(rdev);
@@ -1634,6 +2035,15 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
 
 int r100_init(struct radeon_device *rdev)
 {
+	if (ASIC_IS_RN50(rdev)) {
+		rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
+		rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm);
+	} else if (rdev->family < CHIP_R200) {
+		rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
+		rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
+	} else {
+		return r200_init(rdev);
+	}
 	return 0;
 }
 
@@ -1839,6 +2249,11 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
 			flags |= R300_SURF_TILE_MICRO;
 	}
 
+	if (tiling_flags & RADEON_TILING_SWAP_16BIT)
+		flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP;
+	if (tiling_flags & RADEON_TILING_SWAP_32BIT)
+		flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
+
 	DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
 	WREG32(RADEON_SURFACE0_INFO + surf_index, flags);
 	WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);
@@ -2334,3 +2749,460 @@ void r100_bandwidth_update(struct radeon_device *rdev)
 			  (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL));
 	}
 }
+
+static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
+{
+	DRM_ERROR("pitch                      %d\n", t->pitch);
+	DRM_ERROR("width                      %d\n", t->width);
+	DRM_ERROR("height                     %d\n", t->height);
+	DRM_ERROR("num levels                 %d\n", t->num_levels);
+	DRM_ERROR("depth                      %d\n", t->txdepth);
+	DRM_ERROR("bpp                        %d\n", t->cpp);
+	DRM_ERROR("coordinate type            %d\n", t->tex_coord_type);
+	DRM_ERROR("width round to power of 2  %d\n", t->roundup_w);
+	DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
+}
+
+static int r100_cs_track_cube(struct radeon_device *rdev,
+			      struct r100_cs_track *track, unsigned idx)
+{
+	unsigned face, w, h;
+	struct radeon_object *cube_robj;
+	unsigned long size;
+
+	for (face = 0; face < 5; face++) {
+		cube_robj = track->textures[idx].cube_info[face].robj;
+		w = track->textures[idx].cube_info[face].width;
+		h = track->textures[idx].cube_info[face].height;
+
+		size = w * h;
+		size *= track->textures[idx].cpp;
+
+		size += track->textures[idx].cube_info[face].offset;
+
+		if (size > radeon_object_size(cube_robj)) {
+			DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
+				  size, radeon_object_size(cube_robj));
+			r100_cs_track_texture_print(&track->textures[idx]);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int r100_cs_track_texture_check(struct radeon_device *rdev,
+				       struct r100_cs_track *track)
+{
+	struct radeon_object *robj;
+	unsigned long size;
+	unsigned u, i, w, h;
+	int ret;
+
+	for (u = 0; u < track->num_texture; u++) {
+		if (!track->textures[u].enabled)
+			continue;
+		robj = track->textures[u].robj;
+		if (robj == NULL) {
+			DRM_ERROR("No texture bound to unit %u\n", u);
+			return -EINVAL;
+		}
+		size = 0;
+		for (i = 0; i <= track->textures[u].num_levels; i++) {
+			if (track->textures[u].use_pitch) {
+				if (rdev->family < CHIP_R300)
+					w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i);
+				else
+					w = track->textures[u].pitch / (1 << i);
+			} else {
+				w = track->textures[u].width / (1 << i);
+				if (rdev->family >= CHIP_RV515)
+					w |= track->textures[u].width_11;
+				if (track->textures[u].roundup_w)
+					w = roundup_pow_of_two(w);
+			}
+			h = track->textures[u].height / (1 << i);
+			if (rdev->family >= CHIP_RV515)
+				h |= track->textures[u].height_11;
+			if (track->textures[u].roundup_h)
+				h = roundup_pow_of_two(h);
+			size += w * h;
+		}
+		size *= track->textures[u].cpp;
+		switch (track->textures[u].tex_coord_type) {
+		case 0:
+			break;
+		case 1:
+			size *= (1 << track->textures[u].txdepth);
+			break;
+		case 2:
+			if (track->separate_cube) {
+				ret = r100_cs_track_cube(rdev, track, u);
+				if (ret)
+					return ret;
+			} else
+				size *= 6;
+			break;
+		default:
+			DRM_ERROR("Invalid texture coordinate type %u for unit "
+				  "%u\n", track->textures[u].tex_coord_type, u);
+			return -EINVAL;
+		}
+		if (size > radeon_object_size(robj)) {
+			DRM_ERROR("Texture of unit %u needs %lu bytes but is "
+				  "%lu\n", u, size, radeon_object_size(robj));
+			r100_cs_track_texture_print(&track->textures[u]);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
+{
+	unsigned i;
+	unsigned long size;
+	unsigned prim_walk;
+	unsigned nverts;
+
+	for (i = 0; i < track->num_cb; i++) {
+		if (track->cb[i].robj == NULL) {
+			DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
+			return -EINVAL;
+		}
+		size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
+		size += track->cb[i].offset;
+		if (size > radeon_object_size(track->cb[i].robj)) {
+			DRM_ERROR("[drm] Buffer too small for color buffer %d "
+				  "(need %lu have %lu) !\n", i, size,
+				  radeon_object_size(track->cb[i].robj));
+			DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
+				  i, track->cb[i].pitch, track->cb[i].cpp,
+				  track->cb[i].offset, track->maxy);
+			return -EINVAL;
+		}
+	}
+	if (track->z_enabled) {
+		if (track->zb.robj == NULL) {
+			DRM_ERROR("[drm] No buffer for z buffer !\n");
+			return -EINVAL;
+		}
+		size = track->zb.pitch * track->zb.cpp * track->maxy;
+		size += track->zb.offset;
+		if (size > radeon_object_size(track->zb.robj)) {
+			DRM_ERROR("[drm] Buffer too small for z buffer "
+				  "(need %lu have %lu) !\n", size,
+				  radeon_object_size(track->zb.robj));
+			DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
+				  track->zb.pitch, track->zb.cpp,
+				  track->zb.offset, track->maxy);
+			return -EINVAL;
+		}
+	}
+	prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
+	nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+	switch (prim_walk) {
+	case 1:
+		for (i = 0; i < track->num_arrays; i++) {
+			size = track->arrays[i].esize * track->max_indx * 4;
+			if (track->arrays[i].robj == NULL) {
+				DRM_ERROR("(PW %u) Vertex array %u no buffer "
+					  "bound\n", prim_walk, i);
+				return -EINVAL;
+			}
+			if (size > radeon_object_size(track->arrays[i].robj)) {
+				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
+					   "have %lu dwords\n", prim_walk, i,
+					   size >> 2,
+					   radeon_object_size(track->arrays[i].robj) >> 2);
+				DRM_ERROR("Max indices %u\n", track->max_indx);
+				return -EINVAL;
+			}
+		}
+		break;
+	case 2:
+		for (i = 0; i < track->num_arrays; i++) {
+			size = track->arrays[i].esize * (nverts - 1) * 4;
+			if (track->arrays[i].robj == NULL) {
+				DRM_ERROR("(PW %u) Vertex array %u no buffer "
+					  "bound\n", prim_walk, i);
+				return -EINVAL;
+			}
+			if (size > radeon_object_size(track->arrays[i].robj)) {
+				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
+					   "have %lu dwords\n", prim_walk, i, size >> 2,
+					   radeon_object_size(track->arrays[i].robj) >> 2);
+				return -EINVAL;
+			}
+		}
+		break;
+	case 3:
+		size = track->vtx_size * nverts;
+		if (size != track->immd_dwords) {
+			DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n",
+				  track->immd_dwords, size);
+			DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n",
+				  nverts, track->vtx_size);
+			return -EINVAL;
+		}
+		break;
+	default:
+		DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n",
+			  prim_walk);
+		return -EINVAL;
+	}
+	return r100_cs_track_texture_check(rdev, track);
+}
+
+void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track)
+{
+	unsigned i, face;
+
+	if (rdev->family < CHIP_R300) {
+		track->num_cb = 1;
+		if (rdev->family <= CHIP_RS200)
+			track->num_texture = 3;
+		else
+			track->num_texture = 6;
+		track->maxy = 2048;
+		track->separate_cube = 1;
+	} else {
+		track->num_cb = 4;
+		track->num_texture = 16;
+		track->maxy = 4096;
+		track->separate_cube = 0;
+	}
+
+	for (i = 0; i < track->num_cb; i++) {
+		track->cb[i].robj = NULL;
+		track->cb[i].pitch = 8192;
+		track->cb[i].cpp = 16;
+		track->cb[i].offset = 0;
+	}
+	track->z_enabled = true;
+	track->zb.robj = NULL;
+	track->zb.pitch = 8192;
+	track->zb.cpp = 4;
+	track->zb.offset = 0;
+	track->vtx_size = 0x7F;
+	track->immd_dwords = 0xFFFFFFFFUL;
+	track->num_arrays = 11;
+	track->max_indx = 0x00FFFFFFUL;
+	for (i = 0; i < track->num_arrays; i++) {
+		track->arrays[i].robj = NULL;
+		track->arrays[i].esize = 0x7F;
+	}
+	for (i = 0; i < track->num_texture; i++) {
+		track->textures[i].pitch = 16536;
+		track->textures[i].width = 16536;
+		track->textures[i].height = 16536;
+		track->textures[i].width_11 = 1 << 11;
+		track->textures[i].height_11 = 1 << 11;
+		track->textures[i].num_levels = 12;
+		if (rdev->family <= CHIP_RS200) {
+			track->textures[i].tex_coord_type = 0;
+			track->textures[i].txdepth = 0;
+		} else {
+			track->textures[i].txdepth = 16;
+			track->textures[i].tex_coord_type = 1;
+		}
+		track->textures[i].cpp = 64;
+		track->textures[i].robj = NULL;
+		/* CS IB emission code makes sure texture unit are disabled */
+		track->textures[i].enabled = false;
+		track->textures[i].roundup_w = true;
+		track->textures[i].roundup_h = true;
+		if (track->separate_cube)
+			for (face = 0; face < 5; face++) {
+				track->textures[i].cube_info[face].robj = NULL;
+				track->textures[i].cube_info[face].width = 16536;
+				track->textures[i].cube_info[face].height = 16536;
+				track->textures[i].cube_info[face].offset = 0;
+			}
+	}
+}
+
+int r100_ring_test(struct radeon_device *rdev)
+{
+	uint32_t scratch;
+	uint32_t tmp = 0;
+	unsigned i;
+	int r;
+
+	r = radeon_scratch_get(rdev, &scratch);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
+		return r;
+	}
+	WREG32(scratch, 0xCAFEDEAD);
+	r = radeon_ring_lock(rdev, 2);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
+		radeon_scratch_free(rdev, scratch);
+		return r;
+	}
+	radeon_ring_write(rdev, PACKET0(scratch, 0));
+	radeon_ring_write(rdev, 0xDEADBEEF);
+	radeon_ring_unlock_commit(rdev);
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(scratch);
+		if (tmp == 0xDEADBEEF) {
+			break;
+		}
+		DRM_UDELAY(1);
+	}
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ring test succeeded in %d usecs\n", i);
+	} else {
+		DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n",
+			  scratch, tmp);
+		r = -EINVAL;
+	}
+	radeon_scratch_free(rdev, scratch);
+	return r;
+}
+
+void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+	radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1));
+	radeon_ring_write(rdev, ib->gpu_addr);
+	radeon_ring_write(rdev, ib->length_dw);
+}
+
+int r100_ib_test(struct radeon_device *rdev)
+{
+	struct radeon_ib *ib;
+	uint32_t scratch;
+	uint32_t tmp = 0;
+	unsigned i;
+	int r;
+
+	r = radeon_scratch_get(rdev, &scratch);
+	if (r) {
+		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
+		return r;
+	}
+	WREG32(scratch, 0xCAFEDEAD);
+	r = radeon_ib_get(rdev, &ib);
+	if (r) {
+		return r;
+	}
+	ib->ptr[0] = PACKET0(scratch, 0);
+	ib->ptr[1] = 0xDEADBEEF;
+	ib->ptr[2] = PACKET2(0);
+	ib->ptr[3] = PACKET2(0);
+	ib->ptr[4] = PACKET2(0);
+	ib->ptr[5] = PACKET2(0);
+	ib->ptr[6] = PACKET2(0);
+	ib->ptr[7] = PACKET2(0);
+	ib->length_dw = 8;
+	r = radeon_ib_schedule(rdev, ib);
+	if (r) {
+		radeon_scratch_free(rdev, scratch);
+		radeon_ib_free(rdev, &ib);
+		return r;
+	}
+	r = radeon_fence_wait(ib->fence, false);
+	if (r) {
+		return r;
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(scratch);
+		if (tmp == 0xDEADBEEF) {
+			break;
+		}
+		DRM_UDELAY(1);
+	}
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ib test succeeded in %u usecs\n", i);
+	} else {
+		DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
+			  scratch, tmp);
+		r = -EINVAL;
+	}
+	radeon_scratch_free(rdev, scratch);
+	radeon_ib_free(rdev, &ib);
+	return r;
+}
+
+void r100_ib_fini(struct radeon_device *rdev)
+{
+	radeon_ib_pool_fini(rdev);
+}
+
+int r100_ib_init(struct radeon_device *rdev)
+{
+	int r;
+
+	r = radeon_ib_pool_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "failled initializing IB pool (%d).\n", r);
+		r100_ib_fini(rdev);
+		return r;
+	}
+	r = r100_ib_test(rdev);
+	if (r) {
+		dev_err(rdev->dev, "failled testing IB (%d).\n", r);
+		r100_ib_fini(rdev);
+		return r;
+	}
+	return 0;
+}
+
+void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
+{
+	/* Shutdown CP we shouldn't need to do that but better be safe than
+	 * sorry
+	 */
+	rdev->cp.ready = false;
+	WREG32(R_000740_CP_CSQ_CNTL, 0);
+
+	/* Save few CRTC registers */
+	save->GENMO_WT = RREG32(R_0003C0_GENMO_WT);
+	save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL);
+	save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL);
+	save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET);
+	if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
+		save->CRTC2_GEN_CNTL = RREG32(R_0003F8_CRTC2_GEN_CNTL);
+		save->CUR2_OFFSET = RREG32(R_000360_CUR2_OFFSET);
+	}
+
+	/* Disable VGA aperture access */
+	WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT);
+	/* Disable cursor, overlay, crtc */
+	WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1));
+	WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL |
+					S_000054_CRTC_DISPLAY_DIS(1));
+	WREG32(R_000050_CRTC_GEN_CNTL,
+			(C_000050_CRTC_CUR_EN & save->CRTC_GEN_CNTL) |
+			S_000050_CRTC_DISP_REQ_EN_B(1));
+	WREG32(R_000420_OV0_SCALE_CNTL,
+		C_000420_OV0_OVERLAY_EN & RREG32(R_000420_OV0_SCALE_CNTL));
+	WREG32(R_000260_CUR_OFFSET, C_000260_CUR_LOCK & save->CUR_OFFSET);
+	if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
+		WREG32(R_000360_CUR2_OFFSET, save->CUR2_OFFSET |
+						S_000360_CUR2_LOCK(1));
+		WREG32(R_0003F8_CRTC2_GEN_CNTL,
+			(C_0003F8_CRTC2_CUR_EN & save->CRTC2_GEN_CNTL) |
+			S_0003F8_CRTC2_DISPLAY_DIS(1) |
+			S_0003F8_CRTC2_DISP_REQ_EN_B(1));
+		WREG32(R_000360_CUR2_OFFSET,
+			C_000360_CUR2_LOCK & save->CUR2_OFFSET);
+	}
+}
+
+void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
+{
+	/* Update base address for crtc */
+	WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_location);
+	if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
+		WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR,
+				rdev->mc.vram_location);
+	}
+	/* Restore CRTC registers */
+	WREG32(R_0003C0_GENMO_WT, save->GENMO_WT);
+	WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL);
+	WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL);
+	if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
+		WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL);
+	}
+}
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
new file mode 100644
index 0000000..70a82ed
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r100_track.h
@@ -0,0 +1,124 @@
+
+#define R100_TRACK_MAX_TEXTURE 3
+#define R200_TRACK_MAX_TEXTURE 6
+#define R300_TRACK_MAX_TEXTURE 16
+
+#define R100_MAX_CB 1
+#define R300_MAX_CB 4
+
+/*
+ * CS functions
+ */
+struct r100_cs_track_cb {
+	struct radeon_object	*robj;
+	unsigned		pitch;
+	unsigned		cpp;
+	unsigned		offset;
+};
+
+struct r100_cs_track_array {
+	struct radeon_object	*robj;
+	unsigned		esize;
+};
+
+struct r100_cs_cube_info {
+	struct radeon_object	*robj;
+	unsigned                offset;
+	unsigned		width;
+	unsigned		height;
+};
+
+struct r100_cs_track_texture {
+	struct radeon_object	*robj;
+	struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
+	unsigned		pitch;
+	unsigned		width;
+	unsigned		height;
+	unsigned		num_levels;
+	unsigned		cpp;
+	unsigned		tex_coord_type;
+	unsigned		txdepth;
+	unsigned		width_11;
+	unsigned		height_11;
+	bool			use_pitch;
+	bool			enabled;
+	bool			roundup_w;
+	bool			roundup_h;
+};
+
+struct r100_cs_track_limits {
+	unsigned num_cb;
+	unsigned num_texture;
+	unsigned max_levels;
+};
+
+struct r100_cs_track {
+	struct radeon_device *rdev;
+	unsigned			num_cb;
+	unsigned                        num_texture;
+	unsigned			maxy;
+	unsigned			vtx_size;
+	unsigned			vap_vf_cntl;
+	unsigned			immd_dwords;
+	unsigned			num_arrays;
+	unsigned			max_indx;
+	struct r100_cs_track_array	arrays[11];
+	struct r100_cs_track_cb 	cb[R300_MAX_CB];
+	struct r100_cs_track_cb 	zb;
+	struct r100_cs_track_texture	textures[R300_TRACK_MAX_TEXTURE];
+	bool				z_enabled;
+	bool                            separate_cube;
+
+};
+
+int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
+void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track);
+int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
+			      struct radeon_cs_reloc **cs_reloc);
+void r100_cs_dump_packet(struct radeon_cs_parser *p,
+			 struct radeon_cs_packet *pkt);
+
+int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
+
+int r200_packet0_check(struct radeon_cs_parser *p,
+		       struct radeon_cs_packet *pkt,
+		       unsigned idx, unsigned reg);
+
+static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
+					  struct radeon_cs_packet *pkt,
+					  unsigned idx,
+					  unsigned reg)
+{
+	int r;
+	u32 tile_flags = 0;
+	u32 tmp;
+	struct radeon_cs_reloc *reloc;
+	struct radeon_cs_chunk *ib_chunk;
+
+	ib_chunk = &p->chunks[p->chunk_ib_idx];
+
+	r = r100_cs_packet_next_reloc(p, &reloc);
+	if (r) {
+		DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+			  idx, reg);
+		r100_cs_dump_packet(p, pkt);
+		return r;
+	}
+	tmp = ib_chunk->kdata[idx] & 0x003fffff;
+	tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
+
+	if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+		tile_flags |= RADEON_DST_TILE_MACRO;
+	if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
+		if (reg == RADEON_SRC_PITCH_OFFSET) {
+			DRM_ERROR("Cannot src blit from microtiled surface\n");
+			r100_cs_dump_packet(p, pkt);
+			return -EINVAL;
+		}
+		tile_flags |= RADEON_DST_TILE_MICRO;
+	}
+
+	tmp |= tile_flags;
+	p->ib->ptr[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
+	return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h
new file mode 100644
index 0000000..c4b257e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r100d.h
@@ -0,0 +1,607 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef __R100D_H__
+#define __R100D_H__
+
+#define CP_PACKET0			0x00000000
+#define		PACKET0_BASE_INDEX_SHIFT	0
+#define		PACKET0_BASE_INDEX_MASK		(0x1ffff << 0)
+#define		PACKET0_COUNT_SHIFT		16
+#define		PACKET0_COUNT_MASK		(0x3fff << 16)
+#define CP_PACKET1			0x40000000
+#define CP_PACKET2			0x80000000
+#define		PACKET2_PAD_SHIFT		0
+#define		PACKET2_PAD_MASK		(0x3fffffff << 0)
+#define CP_PACKET3			0xC0000000
+#define		PACKET3_IT_OPCODE_SHIFT		8
+#define		PACKET3_IT_OPCODE_MASK		(0xff << 8)
+#define		PACKET3_COUNT_SHIFT		16
+#define		PACKET3_COUNT_MASK		(0x3fff << 16)
+/* PACKET3 op code */
+#define		PACKET3_NOP			0x10
+#define		PACKET3_3D_DRAW_VBUF		0x28
+#define		PACKET3_3D_DRAW_IMMD		0x29
+#define		PACKET3_3D_DRAW_INDX		0x2A
+#define		PACKET3_3D_LOAD_VBPNTR		0x2F
+#define		PACKET3_INDX_BUFFER		0x33
+#define		PACKET3_3D_DRAW_VBUF_2		0x34
+#define		PACKET3_3D_DRAW_IMMD_2		0x35
+#define		PACKET3_3D_DRAW_INDX_2		0x36
+#define		PACKET3_BITBLT_MULTI		0x9B
+
+#define PACKET0(reg, n)	(CP_PACKET0 |					\
+			 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) |	\
+			 REG_SET(PACKET0_COUNT, (n)))
+#define PACKET2(v)	(CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+#define PACKET3(op, n)	(CP_PACKET3 |					\
+			 REG_SET(PACKET3_IT_OPCODE, (op)) |		\
+			 REG_SET(PACKET3_COUNT, (n)))
+
+#define	PACKET_TYPE0	0
+#define	PACKET_TYPE1	1
+#define	PACKET_TYPE2	2
+#define	PACKET_TYPE3	3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
+#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+
+/* Registers */
+#define R_000040_GEN_INT_CNTL                        0x000040
+#define   S_000040_CRTC_VBLANK(x)                      (((x) & 0x1) << 0)
+#define   G_000040_CRTC_VBLANK(x)                      (((x) >> 0) & 0x1)
+#define   C_000040_CRTC_VBLANK                         0xFFFFFFFE
+#define   S_000040_CRTC_VLINE(x)                       (((x) & 0x1) << 1)
+#define   G_000040_CRTC_VLINE(x)                       (((x) >> 1) & 0x1)
+#define   C_000040_CRTC_VLINE                          0xFFFFFFFD
+#define   S_000040_CRTC_VSYNC(x)                       (((x) & 0x1) << 2)
+#define   G_000040_CRTC_VSYNC(x)                       (((x) >> 2) & 0x1)
+#define   C_000040_CRTC_VSYNC                          0xFFFFFFFB
+#define   S_000040_SNAPSHOT(x)                         (((x) & 0x1) << 3)
+#define   G_000040_SNAPSHOT(x)                         (((x) >> 3) & 0x1)
+#define   C_000040_SNAPSHOT                            0xFFFFFFF7
+#define   S_000040_FP_DETECT(x)                        (((x) & 0x1) << 4)
+#define   G_000040_FP_DETECT(x)                        (((x) >> 4) & 0x1)
+#define   C_000040_FP_DETECT                           0xFFFFFFEF
+#define   S_000040_CRTC2_VLINE(x)                      (((x) & 0x1) << 5)
+#define   G_000040_CRTC2_VLINE(x)                      (((x) >> 5) & 0x1)
+#define   C_000040_CRTC2_VLINE                         0xFFFFFFDF
+#define   S_000040_DMA_VIPH0_INT_EN(x)                 (((x) & 0x1) << 12)
+#define   G_000040_DMA_VIPH0_INT_EN(x)                 (((x) >> 12) & 0x1)
+#define   C_000040_DMA_VIPH0_INT_EN                    0xFFFFEFFF
+#define   S_000040_CRTC2_VSYNC(x)                      (((x) & 0x1) << 6)
+#define   G_000040_CRTC2_VSYNC(x)                      (((x) >> 6) & 0x1)
+#define   C_000040_CRTC2_VSYNC                         0xFFFFFFBF
+#define   S_000040_SNAPSHOT2(x)                        (((x) & 0x1) << 7)
+#define   G_000040_SNAPSHOT2(x)                        (((x) >> 7) & 0x1)
+#define   C_000040_SNAPSHOT2                           0xFFFFFF7F
+#define   S_000040_CRTC2_VBLANK(x)                     (((x) & 0x1) << 9)
+#define   G_000040_CRTC2_VBLANK(x)                     (((x) >> 9) & 0x1)
+#define   C_000040_CRTC2_VBLANK                        0xFFFFFDFF
+#define   S_000040_FP2_DETECT(x)                       (((x) & 0x1) << 10)
+#define   G_000040_FP2_DETECT(x)                       (((x) >> 10) & 0x1)
+#define   C_000040_FP2_DETECT                          0xFFFFFBFF
+#define   S_000040_VSYNC_DIFF_OVER_LIMIT(x)            (((x) & 0x1) << 11)
+#define   G_000040_VSYNC_DIFF_OVER_LIMIT(x)            (((x) >> 11) & 0x1)
+#define   C_000040_VSYNC_DIFF_OVER_LIMIT               0xFFFFF7FF
+#define   S_000040_DMA_VIPH1_INT_EN(x)                 (((x) & 0x1) << 13)
+#define   G_000040_DMA_VIPH1_INT_EN(x)                 (((x) >> 13) & 0x1)
+#define   C_000040_DMA_VIPH1_INT_EN                    0xFFFFDFFF
+#define   S_000040_DMA_VIPH2_INT_EN(x)                 (((x) & 0x1) << 14)
+#define   G_000040_DMA_VIPH2_INT_EN(x)                 (((x) >> 14) & 0x1)
+#define   C_000040_DMA_VIPH2_INT_EN                    0xFFFFBFFF
+#define   S_000040_DMA_VIPH3_INT_EN(x)                 (((x) & 0x1) << 15)
+#define   G_000040_DMA_VIPH3_INT_EN(x)                 (((x) >> 15) & 0x1)
+#define   C_000040_DMA_VIPH3_INT_EN                    0xFFFF7FFF
+#define   S_000040_I2C_INT_EN(x)                       (((x) & 0x1) << 17)
+#define   G_000040_I2C_INT_EN(x)                       (((x) >> 17) & 0x1)
+#define   C_000040_I2C_INT_EN                          0xFFFDFFFF
+#define   S_000040_GUI_IDLE(x)                         (((x) & 0x1) << 19)
+#define   G_000040_GUI_IDLE(x)                         (((x) >> 19) & 0x1)
+#define   C_000040_GUI_IDLE                            0xFFF7FFFF
+#define   S_000040_VIPH_INT_EN(x)                      (((x) & 0x1) << 24)
+#define   G_000040_VIPH_INT_EN(x)                      (((x) >> 24) & 0x1)
+#define   C_000040_VIPH_INT_EN                         0xFEFFFFFF
+#define   S_000040_SW_INT_EN(x)                        (((x) & 0x1) << 25)
+#define   G_000040_SW_INT_EN(x)                        (((x) >> 25) & 0x1)
+#define   C_000040_SW_INT_EN                           0xFDFFFFFF
+#define   S_000040_GEYSERVILLE(x)                      (((x) & 0x1) << 27)
+#define   G_000040_GEYSERVILLE(x)                      (((x) >> 27) & 0x1)
+#define   C_000040_GEYSERVILLE                         0xF7FFFFFF
+#define   S_000040_HDCP_AUTHORIZED_INT(x)              (((x) & 0x1) << 28)
+#define   G_000040_HDCP_AUTHORIZED_INT(x)              (((x) >> 28) & 0x1)
+#define   C_000040_HDCP_AUTHORIZED_INT                 0xEFFFFFFF
+#define   S_000040_DVI_I2C_INT(x)                      (((x) & 0x1) << 29)
+#define   G_000040_DVI_I2C_INT(x)                      (((x) >> 29) & 0x1)
+#define   C_000040_DVI_I2C_INT                         0xDFFFFFFF
+#define   S_000040_GUIDMA(x)                           (((x) & 0x1) << 30)
+#define   G_000040_GUIDMA(x)                           (((x) >> 30) & 0x1)
+#define   C_000040_GUIDMA                              0xBFFFFFFF
+#define   S_000040_VIDDMA(x)                           (((x) & 0x1) << 31)
+#define   G_000040_VIDDMA(x)                           (((x) >> 31) & 0x1)
+#define   C_000040_VIDDMA                              0x7FFFFFFF
+#define R_000044_GEN_INT_STATUS                      0x000044
+#define   S_000044_CRTC_VBLANK_STAT(x)                 (((x) & 0x1) << 0)
+#define   G_000044_CRTC_VBLANK_STAT(x)                 (((x) >> 0) & 0x1)
+#define   C_000044_CRTC_VBLANK_STAT                    0xFFFFFFFE
+#define   S_000044_CRTC_VBLANK_STAT_AK(x)              (((x) & 0x1) << 0)
+#define   G_000044_CRTC_VBLANK_STAT_AK(x)              (((x) >> 0) & 0x1)
+#define   C_000044_CRTC_VBLANK_STAT_AK                 0xFFFFFFFE
+#define   S_000044_CRTC_VLINE_STAT(x)                  (((x) & 0x1) << 1)
+#define   G_000044_CRTC_VLINE_STAT(x)                  (((x) >> 1) & 0x1)
+#define   C_000044_CRTC_VLINE_STAT                     0xFFFFFFFD
+#define   S_000044_CRTC_VLINE_STAT_AK(x)               (((x) & 0x1) << 1)
+#define   G_000044_CRTC_VLINE_STAT_AK(x)               (((x) >> 1) & 0x1)
+#define   C_000044_CRTC_VLINE_STAT_AK                  0xFFFFFFFD
+#define   S_000044_CRTC_VSYNC_STAT(x)                  (((x) & 0x1) << 2)
+#define   G_000044_CRTC_VSYNC_STAT(x)                  (((x) >> 2) & 0x1)
+#define   C_000044_CRTC_VSYNC_STAT                     0xFFFFFFFB
+#define   S_000044_CRTC_VSYNC_STAT_AK(x)               (((x) & 0x1) << 2)
+#define   G_000044_CRTC_VSYNC_STAT_AK(x)               (((x) >> 2) & 0x1)
+#define   C_000044_CRTC_VSYNC_STAT_AK                  0xFFFFFFFB
+#define   S_000044_SNAPSHOT_STAT(x)                    (((x) & 0x1) << 3)
+#define   G_000044_SNAPSHOT_STAT(x)                    (((x) >> 3) & 0x1)
+#define   C_000044_SNAPSHOT_STAT                       0xFFFFFFF7
+#define   S_000044_SNAPSHOT_STAT_AK(x)                 (((x) & 0x1) << 3)
+#define   G_000044_SNAPSHOT_STAT_AK(x)                 (((x) >> 3) & 0x1)
+#define   C_000044_SNAPSHOT_STAT_AK                    0xFFFFFFF7
+#define   S_000044_FP_DETECT_STAT(x)                   (((x) & 0x1) << 4)
+#define   G_000044_FP_DETECT_STAT(x)                   (((x) >> 4) & 0x1)
+#define   C_000044_FP_DETECT_STAT                      0xFFFFFFEF
+#define   S_000044_FP_DETECT_STAT_AK(x)                (((x) & 0x1) << 4)
+#define   G_000044_FP_DETECT_STAT_AK(x)                (((x) >> 4) & 0x1)
+#define   C_000044_FP_DETECT_STAT_AK                   0xFFFFFFEF
+#define   S_000044_CRTC2_VLINE_STAT(x)                 (((x) & 0x1) << 5)
+#define   G_000044_CRTC2_VLINE_STAT(x)                 (((x) >> 5) & 0x1)
+#define   C_000044_CRTC2_VLINE_STAT                    0xFFFFFFDF
+#define   S_000044_CRTC2_VLINE_STAT_AK(x)              (((x) & 0x1) << 5)
+#define   G_000044_CRTC2_VLINE_STAT_AK(x)              (((x) >> 5) & 0x1)
+#define   C_000044_CRTC2_VLINE_STAT_AK                 0xFFFFFFDF
+#define   S_000044_CRTC2_VSYNC_STAT(x)                 (((x) & 0x1) << 6)
+#define   G_000044_CRTC2_VSYNC_STAT(x)                 (((x) >> 6) & 0x1)
+#define   C_000044_CRTC2_VSYNC_STAT                    0xFFFFFFBF
+#define   S_000044_CRTC2_VSYNC_STAT_AK(x)              (((x) & 0x1) << 6)
+#define   G_000044_CRTC2_VSYNC_STAT_AK(x)              (((x) >> 6) & 0x1)
+#define   C_000044_CRTC2_VSYNC_STAT_AK                 0xFFFFFFBF
+#define   S_000044_SNAPSHOT2_STAT(x)                   (((x) & 0x1) << 7)
+#define   G_000044_SNAPSHOT2_STAT(x)                   (((x) >> 7) & 0x1)
+#define   C_000044_SNAPSHOT2_STAT                      0xFFFFFF7F
+#define   S_000044_SNAPSHOT2_STAT_AK(x)                (((x) & 0x1) << 7)
+#define   G_000044_SNAPSHOT2_STAT_AK(x)                (((x) >> 7) & 0x1)
+#define   C_000044_SNAPSHOT2_STAT_AK                   0xFFFFFF7F
+#define   S_000044_CAP0_INT_ACTIVE(x)                  (((x) & 0x1) << 8)
+#define   G_000044_CAP0_INT_ACTIVE(x)                  (((x) >> 8) & 0x1)
+#define   C_000044_CAP0_INT_ACTIVE                     0xFFFFFEFF
+#define   S_000044_CRTC2_VBLANK_STAT(x)                (((x) & 0x1) << 9)
+#define   G_000044_CRTC2_VBLANK_STAT(x)                (((x) >> 9) & 0x1)
+#define   C_000044_CRTC2_VBLANK_STAT                   0xFFFFFDFF
+#define   S_000044_CRTC2_VBLANK_STAT_AK(x)             (((x) & 0x1) << 9)
+#define   G_000044_CRTC2_VBLANK_STAT_AK(x)             (((x) >> 9) & 0x1)
+#define   C_000044_CRTC2_VBLANK_STAT_AK                0xFFFFFDFF
+#define   S_000044_FP2_DETECT_STAT(x)                  (((x) & 0x1) << 10)
+#define   G_000044_FP2_DETECT_STAT(x)                  (((x) >> 10) & 0x1)
+#define   C_000044_FP2_DETECT_STAT                     0xFFFFFBFF
+#define   S_000044_FP2_DETECT_STAT_AK(x)               (((x) & 0x1) << 10)
+#define   G_000044_FP2_DETECT_STAT_AK(x)               (((x) >> 10) & 0x1)
+#define   C_000044_FP2_DETECT_STAT_AK                  0xFFFFFBFF
+#define   S_000044_VSYNC_DIFF_OVER_LIMIT_STAT(x)       (((x) & 0x1) << 11)
+#define   G_000044_VSYNC_DIFF_OVER_LIMIT_STAT(x)       (((x) >> 11) & 0x1)
+#define   C_000044_VSYNC_DIFF_OVER_LIMIT_STAT          0xFFFFF7FF
+#define   S_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK(x)    (((x) & 0x1) << 11)
+#define   G_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK(x)    (((x) >> 11) & 0x1)
+#define   C_000044_VSYNC_DIFF_OVER_LIMIT_STAT_AK       0xFFFFF7FF
+#define   S_000044_DMA_VIPH0_INT(x)                    (((x) & 0x1) << 12)
+#define   G_000044_DMA_VIPH0_INT(x)                    (((x) >> 12) & 0x1)
+#define   C_000044_DMA_VIPH0_INT                       0xFFFFEFFF
+#define   S_000044_DMA_VIPH0_INT_AK(x)                 (((x) & 0x1) << 12)
+#define   G_000044_DMA_VIPH0_INT_AK(x)                 (((x) >> 12) & 0x1)
+#define   C_000044_DMA_VIPH0_INT_AK                    0xFFFFEFFF
+#define   S_000044_DMA_VIPH1_INT(x)                    (((x) & 0x1) << 13)
+#define   G_000044_DMA_VIPH1_INT(x)                    (((x) >> 13) & 0x1)
+#define   C_000044_DMA_VIPH1_INT                       0xFFFFDFFF
+#define   S_000044_DMA_VIPH1_INT_AK(x)                 (((x) & 0x1) << 13)
+#define   G_000044_DMA_VIPH1_INT_AK(x)                 (((x) >> 13) & 0x1)
+#define   C_000044_DMA_VIPH1_INT_AK                    0xFFFFDFFF
+#define   S_000044_DMA_VIPH2_INT(x)                    (((x) & 0x1) << 14)
+#define   G_000044_DMA_VIPH2_INT(x)                    (((x) >> 14) & 0x1)
+#define   C_000044_DMA_VIPH2_INT                       0xFFFFBFFF
+#define   S_000044_DMA_VIPH2_INT_AK(x)                 (((x) & 0x1) << 14)
+#define   G_000044_DMA_VIPH2_INT_AK(x)                 (((x) >> 14) & 0x1)
+#define   C_000044_DMA_VIPH2_INT_AK                    0xFFFFBFFF
+#define   S_000044_DMA_VIPH3_INT(x)                    (((x) & 0x1) << 15)
+#define   G_000044_DMA_VIPH3_INT(x)                    (((x) >> 15) & 0x1)
+#define   C_000044_DMA_VIPH3_INT                       0xFFFF7FFF
+#define   S_000044_DMA_VIPH3_INT_AK(x)                 (((x) & 0x1) << 15)
+#define   G_000044_DMA_VIPH3_INT_AK(x)                 (((x) >> 15) & 0x1)
+#define   C_000044_DMA_VIPH3_INT_AK                    0xFFFF7FFF
+#define   S_000044_I2C_INT(x)                          (((x) & 0x1) << 17)
+#define   G_000044_I2C_INT(x)                          (((x) >> 17) & 0x1)
+#define   C_000044_I2C_INT                             0xFFFDFFFF
+#define   S_000044_I2C_INT_AK(x)                       (((x) & 0x1) << 17)
+#define   G_000044_I2C_INT_AK(x)                       (((x) >> 17) & 0x1)
+#define   C_000044_I2C_INT_AK                          0xFFFDFFFF
+#define   S_000044_GUI_IDLE_STAT(x)                    (((x) & 0x1) << 19)
+#define   G_000044_GUI_IDLE_STAT(x)                    (((x) >> 19) & 0x1)
+#define   C_000044_GUI_IDLE_STAT                       0xFFF7FFFF
+#define   S_000044_GUI_IDLE_STAT_AK(x)                 (((x) & 0x1) << 19)
+#define   G_000044_GUI_IDLE_STAT_AK(x)                 (((x) >> 19) & 0x1)
+#define   C_000044_GUI_IDLE_STAT_AK                    0xFFF7FFFF
+#define   S_000044_VIPH_INT(x)                         (((x) & 0x1) << 24)
+#define   G_000044_VIPH_INT(x)                         (((x) >> 24) & 0x1)
+#define   C_000044_VIPH_INT                            0xFEFFFFFF
+#define   S_000044_SW_INT(x)                           (((x) & 0x1) << 25)
+#define   G_000044_SW_INT(x)                           (((x) >> 25) & 0x1)
+#define   C_000044_SW_INT                              0xFDFFFFFF
+#define   S_000044_SW_INT_AK(x)                        (((x) & 0x1) << 25)
+#define   G_000044_SW_INT_AK(x)                        (((x) >> 25) & 0x1)
+#define   C_000044_SW_INT_AK                           0xFDFFFFFF
+#define   S_000044_SW_INT_SET(x)                       (((x) & 0x1) << 26)
+#define   G_000044_SW_INT_SET(x)                       (((x) >> 26) & 0x1)
+#define   C_000044_SW_INT_SET                          0xFBFFFFFF
+#define   S_000044_GEYSERVILLE_STAT(x)                 (((x) & 0x1) << 27)
+#define   G_000044_GEYSERVILLE_STAT(x)                 (((x) >> 27) & 0x1)
+#define   C_000044_GEYSERVILLE_STAT                    0xF7FFFFFF
+#define   S_000044_GEYSERVILLE_STAT_AK(x)              (((x) & 0x1) << 27)
+#define   G_000044_GEYSERVILLE_STAT_AK(x)              (((x) >> 27) & 0x1)
+#define   C_000044_GEYSERVILLE_STAT_AK                 0xF7FFFFFF
+#define   S_000044_HDCP_AUTHORIZED_INT_STAT(x)         (((x) & 0x1) << 28)
+#define   G_000044_HDCP_AUTHORIZED_INT_STAT(x)         (((x) >> 28) & 0x1)
+#define   C_000044_HDCP_AUTHORIZED_INT_STAT            0xEFFFFFFF
+#define   S_000044_HDCP_AUTHORIZED_INT_AK(x)           (((x) & 0x1) << 28)
+#define   G_000044_HDCP_AUTHORIZED_INT_AK(x)           (((x) >> 28) & 0x1)
+#define   C_000044_HDCP_AUTHORIZED_INT_AK              0xEFFFFFFF
+#define   S_000044_DVI_I2C_INT_STAT(x)                 (((x) & 0x1) << 29)
+#define   G_000044_DVI_I2C_INT_STAT(x)                 (((x) >> 29) & 0x1)
+#define   C_000044_DVI_I2C_INT_STAT                    0xDFFFFFFF
+#define   S_000044_DVI_I2C_INT_AK(x)                   (((x) & 0x1) << 29)
+#define   G_000044_DVI_I2C_INT_AK(x)                   (((x) >> 29) & 0x1)
+#define   C_000044_DVI_I2C_INT_AK                      0xDFFFFFFF
+#define   S_000044_GUIDMA_STAT(x)                      (((x) & 0x1) << 30)
+#define   G_000044_GUIDMA_STAT(x)                      (((x) >> 30) & 0x1)
+#define   C_000044_GUIDMA_STAT                         0xBFFFFFFF
+#define   S_000044_GUIDMA_AK(x)                        (((x) & 0x1) << 30)
+#define   G_000044_GUIDMA_AK(x)                        (((x) >> 30) & 0x1)
+#define   C_000044_GUIDMA_AK                           0xBFFFFFFF
+#define   S_000044_VIDDMA_STAT(x)                      (((x) & 0x1) << 31)
+#define   G_000044_VIDDMA_STAT(x)                      (((x) >> 31) & 0x1)
+#define   C_000044_VIDDMA_STAT                         0x7FFFFFFF
+#define   S_000044_VIDDMA_AK(x)                        (((x) & 0x1) << 31)
+#define   G_000044_VIDDMA_AK(x)                        (((x) >> 31) & 0x1)
+#define   C_000044_VIDDMA_AK                           0x7FFFFFFF
+#define R_000050_CRTC_GEN_CNTL                       0x000050
+#define   S_000050_CRTC_DBL_SCAN_EN(x)                 (((x) & 0x1) << 0)
+#define   G_000050_CRTC_DBL_SCAN_EN(x)                 (((x) >> 0) & 0x1)
+#define   C_000050_CRTC_DBL_SCAN_EN                    0xFFFFFFFE
+#define   S_000050_CRTC_INTERLACE_EN(x)                (((x) & 0x1) << 1)
+#define   G_000050_CRTC_INTERLACE_EN(x)                (((x) >> 1) & 0x1)
+#define   C_000050_CRTC_INTERLACE_EN                   0xFFFFFFFD
+#define   S_000050_CRTC_C_SYNC_EN(x)                   (((x) & 0x1) << 4)
+#define   G_000050_CRTC_C_SYNC_EN(x)                   (((x) >> 4) & 0x1)
+#define   C_000050_CRTC_C_SYNC_EN                      0xFFFFFFEF
+#define   S_000050_CRTC_PIX_WIDTH(x)                   (((x) & 0xF) << 8)
+#define   G_000050_CRTC_PIX_WIDTH(x)                   (((x) >> 8) & 0xF)
+#define   C_000050_CRTC_PIX_WIDTH                      0xFFFFF0FF
+#define   S_000050_CRTC_ICON_EN(x)                     (((x) & 0x1) << 15)
+#define   G_000050_CRTC_ICON_EN(x)                     (((x) >> 15) & 0x1)
+#define   C_000050_CRTC_ICON_EN                        0xFFFF7FFF
+#define   S_000050_CRTC_CUR_EN(x)                      (((x) & 0x1) << 16)
+#define   G_000050_CRTC_CUR_EN(x)                      (((x) >> 16) & 0x1)
+#define   C_000050_CRTC_CUR_EN                         0xFFFEFFFF
+#define   S_000050_CRTC_VSTAT_MODE(x)                  (((x) & 0x3) << 17)
+#define   G_000050_CRTC_VSTAT_MODE(x)                  (((x) >> 17) & 0x3)
+#define   C_000050_CRTC_VSTAT_MODE                     0xFFF9FFFF
+#define   S_000050_CRTC_CUR_MODE(x)                    (((x) & 0x7) << 20)
+#define   G_000050_CRTC_CUR_MODE(x)                    (((x) >> 20) & 0x7)
+#define   C_000050_CRTC_CUR_MODE                       0xFF8FFFFF
+#define   S_000050_CRTC_EXT_DISP_EN(x)                 (((x) & 0x1) << 24)
+#define   G_000050_CRTC_EXT_DISP_EN(x)                 (((x) >> 24) & 0x1)
+#define   C_000050_CRTC_EXT_DISP_EN                    0xFEFFFFFF
+#define   S_000050_CRTC_EN(x)                          (((x) & 0x1) << 25)
+#define   G_000050_CRTC_EN(x)                          (((x) >> 25) & 0x1)
+#define   C_000050_CRTC_EN                             0xFDFFFFFF
+#define   S_000050_CRTC_DISP_REQ_EN_B(x)               (((x) & 0x1) << 26)
+#define   G_000050_CRTC_DISP_REQ_EN_B(x)               (((x) >> 26) & 0x1)
+#define   C_000050_CRTC_DISP_REQ_EN_B                  0xFBFFFFFF
+#define R_000054_CRTC_EXT_CNTL                       0x000054
+#define   S_000054_CRTC_VGA_XOVERSCAN(x)               (((x) & 0x1) << 0)
+#define   G_000054_CRTC_VGA_XOVERSCAN(x)               (((x) >> 0) & 0x1)
+#define   C_000054_CRTC_VGA_XOVERSCAN                  0xFFFFFFFE
+#define   S_000054_VGA_BLINK_RATE(x)                   (((x) & 0x3) << 1)
+#define   G_000054_VGA_BLINK_RATE(x)                   (((x) >> 1) & 0x3)
+#define   C_000054_VGA_BLINK_RATE                      0xFFFFFFF9
+#define   S_000054_VGA_ATI_LINEAR(x)                   (((x) & 0x1) << 3)
+#define   G_000054_VGA_ATI_LINEAR(x)                   (((x) >> 3) & 0x1)
+#define   C_000054_VGA_ATI_LINEAR                      0xFFFFFFF7
+#define   S_000054_VGA_128KAP_PAGING(x)                (((x) & 0x1) << 4)
+#define   G_000054_VGA_128KAP_PAGING(x)                (((x) >> 4) & 0x1)
+#define   C_000054_VGA_128KAP_PAGING                   0xFFFFFFEF
+#define   S_000054_VGA_TEXT_132(x)                     (((x) & 0x1) << 5)
+#define   G_000054_VGA_TEXT_132(x)                     (((x) >> 5) & 0x1)
+#define   C_000054_VGA_TEXT_132                        0xFFFFFFDF
+#define   S_000054_VGA_XCRT_CNT_EN(x)                  (((x) & 0x1) << 6)
+#define   G_000054_VGA_XCRT_CNT_EN(x)                  (((x) >> 6) & 0x1)
+#define   C_000054_VGA_XCRT_CNT_EN                     0xFFFFFFBF
+#define   S_000054_CRTC_HSYNC_DIS(x)                   (((x) & 0x1) << 8)
+#define   G_000054_CRTC_HSYNC_DIS(x)                   (((x) >> 8) & 0x1)
+#define   C_000054_CRTC_HSYNC_DIS                      0xFFFFFEFF
+#define   S_000054_CRTC_VSYNC_DIS(x)                   (((x) & 0x1) << 9)
+#define   G_000054_CRTC_VSYNC_DIS(x)                   (((x) >> 9) & 0x1)
+#define   C_000054_CRTC_VSYNC_DIS                      0xFFFFFDFF
+#define   S_000054_CRTC_DISPLAY_DIS(x)                 (((x) & 0x1) << 10)
+#define   G_000054_CRTC_DISPLAY_DIS(x)                 (((x) >> 10) & 0x1)
+#define   C_000054_CRTC_DISPLAY_DIS                    0xFFFFFBFF
+#define   S_000054_CRTC_SYNC_TRISTATE(x)               (((x) & 0x1) << 11)
+#define   G_000054_CRTC_SYNC_TRISTATE(x)               (((x) >> 11) & 0x1)
+#define   C_000054_CRTC_SYNC_TRISTATE                  0xFFFFF7FF
+#define   S_000054_CRTC_HSYNC_TRISTATE(x)              (((x) & 0x1) << 12)
+#define   G_000054_CRTC_HSYNC_TRISTATE(x)              (((x) >> 12) & 0x1)
+#define   C_000054_CRTC_HSYNC_TRISTATE                 0xFFFFEFFF
+#define   S_000054_CRTC_VSYNC_TRISTATE(x)              (((x) & 0x1) << 13)
+#define   G_000054_CRTC_VSYNC_TRISTATE(x)              (((x) >> 13) & 0x1)
+#define   C_000054_CRTC_VSYNC_TRISTATE                 0xFFFFDFFF
+#define   S_000054_CRT_ON(x)                           (((x) & 0x1) << 15)
+#define   G_000054_CRT_ON(x)                           (((x) >> 15) & 0x1)
+#define   C_000054_CRT_ON                              0xFFFF7FFF
+#define   S_000054_VGA_CUR_B_TEST(x)                   (((x) & 0x1) << 17)
+#define   G_000054_VGA_CUR_B_TEST(x)                   (((x) >> 17) & 0x1)
+#define   C_000054_VGA_CUR_B_TEST                      0xFFFDFFFF
+#define   S_000054_VGA_PACK_DIS(x)                     (((x) & 0x1) << 18)
+#define   G_000054_VGA_PACK_DIS(x)                     (((x) >> 18) & 0x1)
+#define   C_000054_VGA_PACK_DIS                        0xFFFBFFFF
+#define   S_000054_VGA_MEM_PS_EN(x)                    (((x) & 0x1) << 19)
+#define   G_000054_VGA_MEM_PS_EN(x)                    (((x) >> 19) & 0x1)
+#define   C_000054_VGA_MEM_PS_EN                       0xFFF7FFFF
+#define   S_000054_VCRTC_IDX_MASTER(x)                 (((x) & 0x7F) << 24)
+#define   G_000054_VCRTC_IDX_MASTER(x)                 (((x) >> 24) & 0x7F)
+#define   C_000054_VCRTC_IDX_MASTER                    0x80FFFFFF
+#define R_00023C_DISPLAY_BASE_ADDR                   0x00023C
+#define   S_00023C_DISPLAY_BASE_ADDR(x)                (((x) & 0xFFFFFFFF) << 0)
+#define   G_00023C_DISPLAY_BASE_ADDR(x)                (((x) >> 0) & 0xFFFFFFFF)
+#define   C_00023C_DISPLAY_BASE_ADDR                   0x00000000
+#define R_000260_CUR_OFFSET                          0x000260
+#define   S_000260_CUR_OFFSET(x)                       (((x) & 0x7FFFFFF) << 0)
+#define   G_000260_CUR_OFFSET(x)                       (((x) >> 0) & 0x7FFFFFF)
+#define   C_000260_CUR_OFFSET                          0xF8000000
+#define   S_000260_CUR_LOCK(x)                         (((x) & 0x1) << 31)
+#define   G_000260_CUR_LOCK(x)                         (((x) >> 31) & 0x1)
+#define   C_000260_CUR_LOCK                            0x7FFFFFFF
+#define R_00033C_CRTC2_DISPLAY_BASE_ADDR             0x00033C
+#define   S_00033C_CRTC2_DISPLAY_BASE_ADDR(x)          (((x) & 0xFFFFFFFF) << 0)
+#define   G_00033C_CRTC2_DISPLAY_BASE_ADDR(x)          (((x) >> 0) & 0xFFFFFFFF)
+#define   C_00033C_CRTC2_DISPLAY_BASE_ADDR             0x00000000
+#define R_000360_CUR2_OFFSET                         0x000360
+#define   S_000360_CUR2_OFFSET(x)                      (((x) & 0x7FFFFFF) << 0)
+#define   G_000360_CUR2_OFFSET(x)                      (((x) >> 0) & 0x7FFFFFF)
+#define   C_000360_CUR2_OFFSET                         0xF8000000
+#define   S_000360_CUR2_LOCK(x)                        (((x) & 0x1) << 31)
+#define   G_000360_CUR2_LOCK(x)                        (((x) >> 31) & 0x1)
+#define   C_000360_CUR2_LOCK                           0x7FFFFFFF
+#define R_0003C0_GENMO_WT                            0x0003C0
+#define   S_0003C0_GENMO_MONO_ADDRESS_B(x)             (((x) & 0x1) << 0)
+#define   G_0003C0_GENMO_MONO_ADDRESS_B(x)             (((x) >> 0) & 0x1)
+#define   C_0003C0_GENMO_MONO_ADDRESS_B                0xFFFFFFFE
+#define   S_0003C0_VGA_RAM_EN(x)                       (((x) & 0x1) << 1)
+#define   G_0003C0_VGA_RAM_EN(x)                       (((x) >> 1) & 0x1)
+#define   C_0003C0_VGA_RAM_EN                          0xFFFFFFFD
+#define   S_0003C0_VGA_CKSEL(x)                        (((x) & 0x3) << 2)
+#define   G_0003C0_VGA_CKSEL(x)                        (((x) >> 2) & 0x3)
+#define   C_0003C0_VGA_CKSEL                           0xFFFFFFF3
+#define   S_0003C0_ODD_EVEN_MD_PGSEL(x)                (((x) & 0x1) << 5)
+#define   G_0003C0_ODD_EVEN_MD_PGSEL(x)                (((x) >> 5) & 0x1)
+#define   C_0003C0_ODD_EVEN_MD_PGSEL                   0xFFFFFFDF
+#define   S_0003C0_VGA_HSYNC_POL(x)                    (((x) & 0x1) << 6)
+#define   G_0003C0_VGA_HSYNC_POL(x)                    (((x) >> 6) & 0x1)
+#define   C_0003C0_VGA_HSYNC_POL                       0xFFFFFFBF
+#define   S_0003C0_VGA_VSYNC_POL(x)                    (((x) & 0x1) << 7)
+#define   G_0003C0_VGA_VSYNC_POL(x)                    (((x) >> 7) & 0x1)
+#define   C_0003C0_VGA_VSYNC_POL                       0xFFFFFF7F
+#define R_0003F8_CRTC2_GEN_CNTL                      0x0003F8
+#define   S_0003F8_CRTC2_DBL_SCAN_EN(x)                (((x) & 0x1) << 0)
+#define   G_0003F8_CRTC2_DBL_SCAN_EN(x)                (((x) >> 0) & 0x1)
+#define   C_0003F8_CRTC2_DBL_SCAN_EN                   0xFFFFFFFE
+#define   S_0003F8_CRTC2_INTERLACE_EN(x)               (((x) & 0x1) << 1)
+#define   G_0003F8_CRTC2_INTERLACE_EN(x)               (((x) >> 1) & 0x1)
+#define   C_0003F8_CRTC2_INTERLACE_EN                  0xFFFFFFFD
+#define   S_0003F8_CRTC2_SYNC_TRISTATE(x)              (((x) & 0x1) << 4)
+#define   G_0003F8_CRTC2_SYNC_TRISTATE(x)              (((x) >> 4) & 0x1)
+#define   C_0003F8_CRTC2_SYNC_TRISTATE                 0xFFFFFFEF
+#define   S_0003F8_CRTC2_HSYNC_TRISTATE(x)             (((x) & 0x1) << 5)
+#define   G_0003F8_CRTC2_HSYNC_TRISTATE(x)             (((x) >> 5) & 0x1)
+#define   C_0003F8_CRTC2_HSYNC_TRISTATE                0xFFFFFFDF
+#define   S_0003F8_CRTC2_VSYNC_TRISTATE(x)             (((x) & 0x1) << 6)
+#define   G_0003F8_CRTC2_VSYNC_TRISTATE(x)             (((x) >> 6) & 0x1)
+#define   C_0003F8_CRTC2_VSYNC_TRISTATE                0xFFFFFFBF
+#define   S_0003F8_CRT2_ON(x)                          (((x) & 0x1) << 7)
+#define   G_0003F8_CRT2_ON(x)                          (((x) >> 7) & 0x1)
+#define   C_0003F8_CRT2_ON                             0xFFFFFF7F
+#define   S_0003F8_CRTC2_PIX_WIDTH(x)                  (((x) & 0xF) << 8)
+#define   G_0003F8_CRTC2_PIX_WIDTH(x)                  (((x) >> 8) & 0xF)
+#define   C_0003F8_CRTC2_PIX_WIDTH                     0xFFFFF0FF
+#define   S_0003F8_CRTC2_ICON_EN(x)                    (((x) & 0x1) << 15)
+#define   G_0003F8_CRTC2_ICON_EN(x)                    (((x) >> 15) & 0x1)
+#define   C_0003F8_CRTC2_ICON_EN                       0xFFFF7FFF
+#define   S_0003F8_CRTC2_CUR_EN(x)                     (((x) & 0x1) << 16)
+#define   G_0003F8_CRTC2_CUR_EN(x)                     (((x) >> 16) & 0x1)
+#define   C_0003F8_CRTC2_CUR_EN                        0xFFFEFFFF
+#define   S_0003F8_CRTC2_CUR_MODE(x)                   (((x) & 0x7) << 20)
+#define   G_0003F8_CRTC2_CUR_MODE(x)                   (((x) >> 20) & 0x7)
+#define   C_0003F8_CRTC2_CUR_MODE                      0xFF8FFFFF
+#define   S_0003F8_CRTC2_DISPLAY_DIS(x)                (((x) & 0x1) << 23)
+#define   G_0003F8_CRTC2_DISPLAY_DIS(x)                (((x) >> 23) & 0x1)
+#define   C_0003F8_CRTC2_DISPLAY_DIS                   0xFF7FFFFF
+#define   S_0003F8_CRTC2_EN(x)                         (((x) & 0x1) << 25)
+#define   G_0003F8_CRTC2_EN(x)                         (((x) >> 25) & 0x1)
+#define   C_0003F8_CRTC2_EN                            0xFDFFFFFF
+#define   S_0003F8_CRTC2_DISP_REQ_EN_B(x)              (((x) & 0x1) << 26)
+#define   G_0003F8_CRTC2_DISP_REQ_EN_B(x)              (((x) >> 26) & 0x1)
+#define   C_0003F8_CRTC2_DISP_REQ_EN_B                 0xFBFFFFFF
+#define   S_0003F8_CRTC2_C_SYNC_EN(x)                  (((x) & 0x1) << 27)
+#define   G_0003F8_CRTC2_C_SYNC_EN(x)                  (((x) >> 27) & 0x1)
+#define   C_0003F8_CRTC2_C_SYNC_EN                     0xF7FFFFFF
+#define   S_0003F8_CRTC2_HSYNC_DIS(x)                  (((x) & 0x1) << 28)
+#define   G_0003F8_CRTC2_HSYNC_DIS(x)                  (((x) >> 28) & 0x1)
+#define   C_0003F8_CRTC2_HSYNC_DIS                     0xEFFFFFFF
+#define   S_0003F8_CRTC2_VSYNC_DIS(x)                  (((x) & 0x1) << 29)
+#define   G_0003F8_CRTC2_VSYNC_DIS(x)                  (((x) >> 29) & 0x1)
+#define   C_0003F8_CRTC2_VSYNC_DIS                     0xDFFFFFFF
+#define R_000420_OV0_SCALE_CNTL                      0x000420
+#define   S_000420_OV0_NO_READ_BEHIND_SCAN(x)          (((x) & 0x1) << 1)
+#define   G_000420_OV0_NO_READ_BEHIND_SCAN(x)          (((x) >> 1) & 0x1)
+#define   C_000420_OV0_NO_READ_BEHIND_SCAN             0xFFFFFFFD
+#define   S_000420_OV0_HORZ_PICK_NEAREST(x)            (((x) & 0x1) << 2)
+#define   G_000420_OV0_HORZ_PICK_NEAREST(x)            (((x) >> 2) & 0x1)
+#define   C_000420_OV0_HORZ_PICK_NEAREST               0xFFFFFFFB
+#define   S_000420_OV0_VERT_PICK_NEAREST(x)            (((x) & 0x1) << 3)
+#define   G_000420_OV0_VERT_PICK_NEAREST(x)            (((x) >> 3) & 0x1)
+#define   C_000420_OV0_VERT_PICK_NEAREST               0xFFFFFFF7
+#define   S_000420_OV0_SIGNED_UV(x)                    (((x) & 0x1) << 4)
+#define   G_000420_OV0_SIGNED_UV(x)                    (((x) >> 4) & 0x1)
+#define   C_000420_OV0_SIGNED_UV                       0xFFFFFFEF
+#define   S_000420_OV0_GAMMA_SEL(x)                    (((x) & 0x7) << 5)
+#define   G_000420_OV0_GAMMA_SEL(x)                    (((x) >> 5) & 0x7)
+#define   C_000420_OV0_GAMMA_SEL                       0xFFFFFF1F
+#define   S_000420_OV0_SURFACE_FORMAT(x)               (((x) & 0xF) << 8)
+#define   G_000420_OV0_SURFACE_FORMAT(x)               (((x) >> 8) & 0xF)
+#define   C_000420_OV0_SURFACE_FORMAT                  0xFFFFF0FF
+#define   S_000420_OV0_ADAPTIVE_DEINT(x)               (((x) & 0x1) << 12)
+#define   G_000420_OV0_ADAPTIVE_DEINT(x)               (((x) >> 12) & 0x1)
+#define   C_000420_OV0_ADAPTIVE_DEINT                  0xFFFFEFFF
+#define   S_000420_OV0_CRTC_SEL(x)                     (((x) & 0x1) << 14)
+#define   G_000420_OV0_CRTC_SEL(x)                     (((x) >> 14) & 0x1)
+#define   C_000420_OV0_CRTC_SEL                        0xFFFFBFFF
+#define   S_000420_OV0_BURST_PER_PLANE(x)              (((x) & 0x7F) << 16)
+#define   G_000420_OV0_BURST_PER_PLANE(x)              (((x) >> 16) & 0x7F)
+#define   C_000420_OV0_BURST_PER_PLANE                 0xFF80FFFF
+#define   S_000420_OV0_DOUBLE_BUFFER_REGS(x)           (((x) & 0x1) << 24)
+#define   G_000420_OV0_DOUBLE_BUFFER_REGS(x)           (((x) >> 24) & 0x1)
+#define   C_000420_OV0_DOUBLE_BUFFER_REGS              0xFEFFFFFF
+#define   S_000420_OV0_BANDWIDTH(x)                    (((x) & 0x1) << 26)
+#define   G_000420_OV0_BANDWIDTH(x)                    (((x) >> 26) & 0x1)
+#define   C_000420_OV0_BANDWIDTH                       0xFBFFFFFF
+#define   S_000420_OV0_LIN_TRANS_BYPASS(x)             (((x) & 0x1) << 28)
+#define   G_000420_OV0_LIN_TRANS_BYPASS(x)             (((x) >> 28) & 0x1)
+#define   C_000420_OV0_LIN_TRANS_BYPASS                0xEFFFFFFF
+#define   S_000420_OV0_INT_EMU(x)                      (((x) & 0x1) << 29)
+#define   G_000420_OV0_INT_EMU(x)                      (((x) >> 29) & 0x1)
+#define   C_000420_OV0_INT_EMU                         0xDFFFFFFF
+#define   S_000420_OV0_OVERLAY_EN(x)                   (((x) & 0x1) << 30)
+#define   G_000420_OV0_OVERLAY_EN(x)                   (((x) >> 30) & 0x1)
+#define   C_000420_OV0_OVERLAY_EN                      0xBFFFFFFF
+#define   S_000420_OV0_SOFT_RESET(x)                   (((x) & 0x1) << 31)
+#define   G_000420_OV0_SOFT_RESET(x)                   (((x) >> 31) & 0x1)
+#define   C_000420_OV0_SOFT_RESET                      0x7FFFFFFF
+#define R_00070C_CP_RB_RPTR_ADDR                     0x00070C
+#define   S_00070C_RB_RPTR_SWAP(x)                     (((x) & 0x3) << 0)
+#define   G_00070C_RB_RPTR_SWAP(x)                     (((x) >> 0) & 0x3)
+#define   C_00070C_RB_RPTR_SWAP                        0xFFFFFFFC
+#define   S_00070C_RB_RPTR_ADDR(x)                     (((x) & 0x3FFFFFFF) << 2)
+#define   G_00070C_RB_RPTR_ADDR(x)                     (((x) >> 2) & 0x3FFFFFFF)
+#define   C_00070C_RB_RPTR_ADDR                        0x00000003
+#define R_000740_CP_CSQ_CNTL                         0x000740
+#define   S_000740_CSQ_CNT_PRIMARY(x)                  (((x) & 0xFF) << 0)
+#define   G_000740_CSQ_CNT_PRIMARY(x)                  (((x) >> 0) & 0xFF)
+#define   C_000740_CSQ_CNT_PRIMARY                     0xFFFFFF00
+#define   S_000740_CSQ_CNT_INDIRECT(x)                 (((x) & 0xFF) << 8)
+#define   G_000740_CSQ_CNT_INDIRECT(x)                 (((x) >> 8) & 0xFF)
+#define   C_000740_CSQ_CNT_INDIRECT                    0xFFFF00FF
+#define   S_000740_CSQ_MODE(x)                         (((x) & 0xF) << 28)
+#define   G_000740_CSQ_MODE(x)                         (((x) >> 28) & 0xF)
+#define   C_000740_CSQ_MODE                            0x0FFFFFFF
+#define R_000770_SCRATCH_UMSK                        0x000770
+#define   S_000770_SCRATCH_UMSK(x)                     (((x) & 0x3F) << 0)
+#define   G_000770_SCRATCH_UMSK(x)                     (((x) >> 0) & 0x3F)
+#define   C_000770_SCRATCH_UMSK                        0xFFFFFFC0
+#define   S_000770_SCRATCH_SWAP(x)                     (((x) & 0x3) << 16)
+#define   G_000770_SCRATCH_SWAP(x)                     (((x) >> 16) & 0x3)
+#define   C_000770_SCRATCH_SWAP                        0xFFFCFFFF
+#define R_000774_SCRATCH_ADDR                        0x000774
+#define   S_000774_SCRATCH_ADDR(x)                     (((x) & 0x7FFFFFF) << 5)
+#define   G_000774_SCRATCH_ADDR(x)                     (((x) >> 5) & 0x7FFFFFF)
+#define   C_000774_SCRATCH_ADDR                        0x0000001F
+#define R_000E40_RBBM_STATUS                         0x000E40
+#define   S_000E40_CMDFIFO_AVAIL(x)                    (((x) & 0x7F) << 0)
+#define   G_000E40_CMDFIFO_AVAIL(x)                    (((x) >> 0) & 0x7F)
+#define   C_000E40_CMDFIFO_AVAIL                       0xFFFFFF80
+#define   S_000E40_HIRQ_ON_RBB(x)                      (((x) & 0x1) << 8)
+#define   G_000E40_HIRQ_ON_RBB(x)                      (((x) >> 8) & 0x1)
+#define   C_000E40_HIRQ_ON_RBB                         0xFFFFFEFF
+#define   S_000E40_CPRQ_ON_RBB(x)                      (((x) & 0x1) << 9)
+#define   G_000E40_CPRQ_ON_RBB(x)                      (((x) >> 9) & 0x1)
+#define   C_000E40_CPRQ_ON_RBB                         0xFFFFFDFF
+#define   S_000E40_CFRQ_ON_RBB(x)                      (((x) & 0x1) << 10)
+#define   G_000E40_CFRQ_ON_RBB(x)                      (((x) >> 10) & 0x1)
+#define   C_000E40_CFRQ_ON_RBB                         0xFFFFFBFF
+#define   S_000E40_HIRQ_IN_RTBUF(x)                    (((x) & 0x1) << 11)
+#define   G_000E40_HIRQ_IN_RTBUF(x)                    (((x) >> 11) & 0x1)
+#define   C_000E40_HIRQ_IN_RTBUF                       0xFFFFF7FF
+#define   S_000E40_CPRQ_IN_RTBUF(x)                    (((x) & 0x1) << 12)
+#define   G_000E40_CPRQ_IN_RTBUF(x)                    (((x) >> 12) & 0x1)
+#define   C_000E40_CPRQ_IN_RTBUF                       0xFFFFEFFF
+#define   S_000E40_CFRQ_IN_RTBUF(x)                    (((x) & 0x1) << 13)
+#define   G_000E40_CFRQ_IN_RTBUF(x)                    (((x) >> 13) & 0x1)
+#define   C_000E40_CFRQ_IN_RTBUF                       0xFFFFDFFF
+#define   S_000E40_CF_PIPE_BUSY(x)                     (((x) & 0x1) << 14)
+#define   G_000E40_CF_PIPE_BUSY(x)                     (((x) >> 14) & 0x1)
+#define   C_000E40_CF_PIPE_BUSY                        0xFFFFBFFF
+#define   S_000E40_ENG_EV_BUSY(x)                      (((x) & 0x1) << 15)
+#define   G_000E40_ENG_EV_BUSY(x)                      (((x) >> 15) & 0x1)
+#define   C_000E40_ENG_EV_BUSY                         0xFFFF7FFF
+#define   S_000E40_CP_CMDSTRM_BUSY(x)                  (((x) & 0x1) << 16)
+#define   G_000E40_CP_CMDSTRM_BUSY(x)                  (((x) >> 16) & 0x1)
+#define   C_000E40_CP_CMDSTRM_BUSY                     0xFFFEFFFF
+#define   S_000E40_E2_BUSY(x)                          (((x) & 0x1) << 17)
+#define   G_000E40_E2_BUSY(x)                          (((x) >> 17) & 0x1)
+#define   C_000E40_E2_BUSY                             0xFFFDFFFF
+#define   S_000E40_RB2D_BUSY(x)                        (((x) & 0x1) << 18)
+#define   G_000E40_RB2D_BUSY(x)                        (((x) >> 18) & 0x1)
+#define   C_000E40_RB2D_BUSY                           0xFFFBFFFF
+#define   S_000E40_RB3D_BUSY(x)                        (((x) & 0x1) << 19)
+#define   G_000E40_RB3D_BUSY(x)                        (((x) >> 19) & 0x1)
+#define   C_000E40_RB3D_BUSY                           0xFFF7FFFF
+#define   S_000E40_SE_BUSY(x)                          (((x) & 0x1) << 20)
+#define   G_000E40_SE_BUSY(x)                          (((x) >> 20) & 0x1)
+#define   C_000E40_SE_BUSY                             0xFFEFFFFF
+#define   S_000E40_RE_BUSY(x)                          (((x) & 0x1) << 21)
+#define   G_000E40_RE_BUSY(x)                          (((x) >> 21) & 0x1)
+#define   C_000E40_RE_BUSY                             0xFFDFFFFF
+#define   S_000E40_TAM_BUSY(x)                         (((x) & 0x1) << 22)
+#define   G_000E40_TAM_BUSY(x)                         (((x) >> 22) & 0x1)
+#define   C_000E40_TAM_BUSY                            0xFFBFFFFF
+#define   S_000E40_TDM_BUSY(x)                         (((x) & 0x1) << 23)
+#define   G_000E40_TDM_BUSY(x)                         (((x) >> 23) & 0x1)
+#define   C_000E40_TDM_BUSY                            0xFF7FFFFF
+#define   S_000E40_PB_BUSY(x)                          (((x) & 0x1) << 24)
+#define   G_000E40_PB_BUSY(x)                          (((x) >> 24) & 0x1)
+#define   C_000E40_PB_BUSY                             0xFEFFFFFF
+#define   S_000E40_GUI_ACTIVE(x)                       (((x) & 0x1) << 31)
+#define   G_000E40_GUI_ACTIVE(x)                       (((x) >> 31) & 0x1)
+#define   C_000E40_GUI_ACTIVE                          0x7FFFFFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
new file mode 100644
index 0000000..568c74b
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_reg.h"
+#include "radeon.h"
+
+#include "r200_reg_safe.h"
+
+#include "r100_track.h"
+
+static int r200_get_vtx_size_0(uint32_t vtx_fmt_0)
+{
+	int vtx_size, i;
+	vtx_size = 2;
+
+	if (vtx_fmt_0 & R200_VTX_Z0)
+		vtx_size++;
+	if (vtx_fmt_0 & R200_VTX_W0)
+		vtx_size++;
+	/* blend weight */
+	if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT))
+		vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7;
+	if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL)
+		vtx_size++;
+	if (vtx_fmt_0 & R200_VTX_N0)
+		vtx_size += 3;
+	if (vtx_fmt_0 & R200_VTX_POINT_SIZE)
+		vtx_size++;
+	if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG)
+		vtx_size++;
+	if (vtx_fmt_0 & R200_VTX_SHININESS_0)
+		vtx_size++;
+	if (vtx_fmt_0 & R200_VTX_SHININESS_1)
+		vtx_size++;
+	for (i = 0; i < 8; i++) {
+		int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3;
+		switch (color_size) {
+		case 0: break;
+		case 1: vtx_size++; break;
+		case 2: vtx_size += 3; break;
+		case 3: vtx_size += 4; break;
+		}
+	}
+	if (vtx_fmt_0 & R200_VTX_XY1)
+		vtx_size += 2;
+	if (vtx_fmt_0 & R200_VTX_Z1)
+		vtx_size++;
+	if (vtx_fmt_0 & R200_VTX_W1)
+		vtx_size++;
+	if (vtx_fmt_0 & R200_VTX_N1)
+		vtx_size += 3;
+	return vtx_size;
+}
+
+static int r200_get_vtx_size_1(uint32_t vtx_fmt_1)
+{
+	int vtx_size, i, tex_size;
+	vtx_size = 0;
+	for (i = 0; i < 6; i++) {
+		tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7;
+		if (tex_size > 4)
+			continue;
+		vtx_size += tex_size;
+	}
+	return vtx_size;
+}
+
+int r200_packet0_check(struct radeon_cs_parser *p,
+		       struct radeon_cs_packet *pkt,
+		       unsigned idx, unsigned reg)
+{
+	struct radeon_cs_chunk *ib_chunk;
+	struct radeon_cs_reloc *reloc;
+	struct r100_cs_track *track;
+	volatile uint32_t *ib;
+	uint32_t tmp;
+	int r;
+	int i;
+	int face;
+	u32 tile_flags = 0;
+
+	ib = p->ib->ptr;
+	ib_chunk = &p->chunks[p->chunk_ib_idx];
+	track = (struct r100_cs_track *)p->track;
+
+	switch (reg) {
+	case RADEON_CRTC_GUI_TRIG_VLINE:
+		r = r100_cs_packet_parse_vline(p);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		break;
+		/* FIXME: only allow PACKET3 blit? easier to check for out of
+		 * range access */
+	case RADEON_DST_PITCH_OFFSET:
+	case RADEON_SRC_PITCH_OFFSET:
+		r = r100_reloc_pitch_offset(p, pkt, idx, reg);
+		if (r)
+			return r;
+		break;
+	case RADEON_RB3D_DEPTHOFFSET:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->zb.robj = reloc->robj;
+		track->zb.offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		break;
+	case RADEON_RB3D_COLOROFFSET:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->cb[0].robj = reloc->robj;
+		track->cb[0].offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		break;
+	case R200_PP_TXOFFSET_0:
+	case R200_PP_TXOFFSET_1:
+	case R200_PP_TXOFFSET_2:
+	case R200_PP_TXOFFSET_3:
+	case R200_PP_TXOFFSET_4:
+	case R200_PP_TXOFFSET_5:
+		i = (reg - R200_PP_TXOFFSET_0) / 24;
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		track->textures[i].robj = reloc->robj;
+		break;
+	case R200_PP_CUBIC_OFFSET_F1_0:
+	case R200_PP_CUBIC_OFFSET_F2_0:
+	case R200_PP_CUBIC_OFFSET_F3_0:
+	case R200_PP_CUBIC_OFFSET_F4_0:
+	case R200_PP_CUBIC_OFFSET_F5_0:
+	case R200_PP_CUBIC_OFFSET_F1_1:
+	case R200_PP_CUBIC_OFFSET_F2_1:
+	case R200_PP_CUBIC_OFFSET_F3_1:
+	case R200_PP_CUBIC_OFFSET_F4_1:
+	case R200_PP_CUBIC_OFFSET_F5_1:
+	case R200_PP_CUBIC_OFFSET_F1_2:
+	case R200_PP_CUBIC_OFFSET_F2_2:
+	case R200_PP_CUBIC_OFFSET_F3_2:
+	case R200_PP_CUBIC_OFFSET_F4_2:
+	case R200_PP_CUBIC_OFFSET_F5_2:
+	case R200_PP_CUBIC_OFFSET_F1_3:
+	case R200_PP_CUBIC_OFFSET_F2_3:
+	case R200_PP_CUBIC_OFFSET_F3_3:
+	case R200_PP_CUBIC_OFFSET_F4_3:
+	case R200_PP_CUBIC_OFFSET_F5_3:
+	case R200_PP_CUBIC_OFFSET_F1_4:
+	case R200_PP_CUBIC_OFFSET_F2_4:
+	case R200_PP_CUBIC_OFFSET_F3_4:
+	case R200_PP_CUBIC_OFFSET_F4_4:
+	case R200_PP_CUBIC_OFFSET_F5_4:
+	case R200_PP_CUBIC_OFFSET_F1_5:
+	case R200_PP_CUBIC_OFFSET_F2_5:
+	case R200_PP_CUBIC_OFFSET_F3_5:
+	case R200_PP_CUBIC_OFFSET_F4_5:
+	case R200_PP_CUBIC_OFFSET_F5_5:
+		i = (reg - R200_PP_TXOFFSET_0) / 24;
+		face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4;
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		track->textures[i].cube_info[face - 1].offset = ib_chunk->kdata[idx];
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		track->textures[i].cube_info[face - 1].robj = reloc->robj;
+		break;
+	case RADEON_RE_WIDTH_HEIGHT:
+		track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
+		break;
+	case RADEON_RB3D_COLORPITCH:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
+			tile_flags |= RADEON_COLOR_TILE_ENABLE;
+		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
+			tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
+
+		tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
+		tmp |= tile_flags;
+		ib[idx] = tmp;
+
+		track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
+		break;
+	case RADEON_RB3D_DEPTHPITCH:
+		track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
+		break;
+	case RADEON_RB3D_CNTL:
+		switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
+		case 7:
+		case 8:
+		case 9:
+		case 11:
+		case 12:
+			track->cb[0].cpp = 1;
+			break;
+		case 3:
+		case 4:
+		case 15:
+			track->cb[0].cpp = 2;
+			break;
+		case 6:
+			track->cb[0].cpp = 4;
+			break;
+		default:
+			DRM_ERROR("Invalid color buffer format (%d) !\n",
+				  ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
+			return -EINVAL;
+		}
+		if (ib_chunk->kdata[idx] & RADEON_DEPTHXY_OFFSET_ENABLE) {
+			DRM_ERROR("No support for depth xy offset in kms\n");
+			return -EINVAL;
+		}
+
+		track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
+		break;
+	case RADEON_RB3D_ZSTENCILCNTL:
+		switch (ib_chunk->kdata[idx] & 0xf) {
+		case 0:
+			track->zb.cpp = 2;
+			break;
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 9:
+		case 11:
+			track->zb.cpp = 4;
+			break;
+		default:
+			break;
+		}
+		break;
+	case RADEON_RB3D_ZPASS_ADDR:
+		r = r100_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
+				  idx, reg);
+			r100_cs_dump_packet(p, pkt);
+			return r;
+		}
+		ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
+		break;
+	case RADEON_PP_CNTL:
+		{
+			uint32_t temp = ib_chunk->kdata[idx] >> 4;
+			for (i = 0; i < track->num_texture; i++)
+				track->textures[i].enabled = !!(temp & (1 << i));
+		}
+		break;
+	case RADEON_SE_VF_CNTL:
+		track->vap_vf_cntl = ib_chunk->kdata[idx];
+		break;
+	case 0x210c:
+		/* VAP_VF_MAX_VTX_INDX */
+		track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL;
+		break;
+	case R200_SE_VTX_FMT_0:
+		track->vtx_size = r200_get_vtx_size_0(ib_chunk->kdata[idx]);
+		break;
+	case R200_SE_VTX_FMT_1:
+		track->vtx_size += r200_get_vtx_size_1(ib_chunk->kdata[idx]);
+		break;
+	case R200_PP_TXSIZE_0:
+	case R200_PP_TXSIZE_1:
+	case R200_PP_TXSIZE_2:
+	case R200_PP_TXSIZE_3:
+	case R200_PP_TXSIZE_4:
+	case R200_PP_TXSIZE_5:
+		i = (reg - R200_PP_TXSIZE_0) / 32;
+		track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
+		track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
+		break;
+	case R200_PP_TXPITCH_0:
+	case R200_PP_TXPITCH_1:
+	case R200_PP_TXPITCH_2:
+	case R200_PP_TXPITCH_3:
+	case R200_PP_TXPITCH_4:
+	case R200_PP_TXPITCH_5:
+		i = (reg - R200_PP_TXPITCH_0) / 32;
+		track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
+		break;
+	case R200_PP_TXFILTER_0:
+	case R200_PP_TXFILTER_1:
+	case R200_PP_TXFILTER_2:
+	case R200_PP_TXFILTER_3:
+	case R200_PP_TXFILTER_4:
+	case R200_PP_TXFILTER_5:
+		i = (reg - R200_PP_TXFILTER_0) / 32;
+		track->textures[i].num_levels = ((ib_chunk->kdata[idx] & R200_MAX_MIP_LEVEL_MASK)
+						 >> R200_MAX_MIP_LEVEL_SHIFT);
+		tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
+		if (tmp == 2 || tmp == 6)
+			track->textures[i].roundup_w = false;
+		tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
+		if (tmp == 2 || tmp == 6)
+			track->textures[i].roundup_h = false;
+		break;
+	case R200_PP_TXMULTI_CTL_0:
+	case R200_PP_TXMULTI_CTL_1:
+	case R200_PP_TXMULTI_CTL_2:
+	case R200_PP_TXMULTI_CTL_3:
+	case R200_PP_TXMULTI_CTL_4:
+	case R200_PP_TXMULTI_CTL_5:
+		i = (reg - R200_PP_TXMULTI_CTL_0) / 32;
+		break;
+	case R200_PP_TXFORMAT_X_0:
+	case R200_PP_TXFORMAT_X_1:
+	case R200_PP_TXFORMAT_X_2:
+	case R200_PP_TXFORMAT_X_3:
+	case R200_PP_TXFORMAT_X_4:
+	case R200_PP_TXFORMAT_X_5:
+		i = (reg - R200_PP_TXFORMAT_X_0) / 32;
+		track->textures[i].txdepth = ib_chunk->kdata[idx] & 0x7;
+		tmp = (ib_chunk->kdata[idx] >> 16) & 0x3;
+		/* 2D, 3D, CUBE */
+		switch (tmp) {
+		case 0:
+		case 5:
+		case 6:
+		case 7:
+			track->textures[i].tex_coord_type = 0;
+			break;
+		case 1:
+			track->textures[i].tex_coord_type = 1;
+			break;
+		case 2:
+			track->textures[i].tex_coord_type = 2;
+			break;
+		}
+		break;
+	case R200_PP_TXFORMAT_0:
+	case R200_PP_TXFORMAT_1:
+	case R200_PP_TXFORMAT_2:
+	case R200_PP_TXFORMAT_3:
+	case R200_PP_TXFORMAT_4:
+	case R200_PP_TXFORMAT_5:
+		i = (reg - R200_PP_TXFORMAT_0) / 32;
+		if (ib_chunk->kdata[idx] & R200_TXFORMAT_NON_POWER2) {
+			track->textures[i].use_pitch = 1;
+		} else {
+			track->textures[i].use_pitch = 0;
+			track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
+			track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
+		}
+		switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
+		case R200_TXFORMAT_I8:
+		case R200_TXFORMAT_RGB332:
+		case R200_TXFORMAT_Y8:
+			track->textures[i].cpp = 1;
+			break;
+		case R200_TXFORMAT_DXT1:
+		case R200_TXFORMAT_AI88:
+		case R200_TXFORMAT_ARGB1555:
+		case R200_TXFORMAT_RGB565:
+		case R200_TXFORMAT_ARGB4444:
+		case R200_TXFORMAT_VYUY422:
+		case R200_TXFORMAT_YVYU422:
+		case R200_TXFORMAT_LDVDU655:
+		case R200_TXFORMAT_DVDU88:
+		case R200_TXFORMAT_AVYU4444:
+			track->textures[i].cpp = 2;
+			break;
+		case R200_TXFORMAT_ARGB8888:
+		case R200_TXFORMAT_RGBA8888:
+		case R200_TXFORMAT_ABGR8888:
+		case R200_TXFORMAT_BGR111110:
+		case R200_TXFORMAT_LDVDU8888:
+		case R200_TXFORMAT_DXT23:
+		case R200_TXFORMAT_DXT45:
+			track->textures[i].cpp = 4;
+			break;
+		}
+		track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
+		track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
+		break;
+	case R200_PP_CUBIC_FACES_0:
+	case R200_PP_CUBIC_FACES_1:
+	case R200_PP_CUBIC_FACES_2:
+	case R200_PP_CUBIC_FACES_3:
+	case R200_PP_CUBIC_FACES_4:
+	case R200_PP_CUBIC_FACES_5:
+		tmp = ib_chunk->kdata[idx];
+		i = (reg - R200_PP_CUBIC_FACES_0) / 32;
+		for (face = 0; face < 4; face++) {
+			track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
+			track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
+		}
+		break;
+	default:
+		printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+		       reg, idx);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int r200_init(struct radeon_device *rdev)
+{
+	rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
+	rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
+	return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 051bca6..bb151ec 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -31,7 +31,10 @@
 #include "radeon_reg.h"
 #include "radeon.h"
 #include "radeon_drm.h"
-#include "radeon_share.h"
+#include "r100_track.h"
+#include "r300d.h"
+
+#include "r300_reg_safe.h"
 
 /* r300,r350,rv350,rv370,rv380 depends on : */
 void r100_hdp_reset(struct radeon_device *rdev);
@@ -39,7 +42,6 @@ int r100_cp_reset(struct radeon_device *rdev);
 int r100_rb2d_reset(struct radeon_device *rdev);
 int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
 int r100_pci_gart_enable(struct radeon_device *rdev);
-void r100_pci_gart_disable(struct radeon_device *rdev);
 void r100_mc_setup(struct radeon_device *rdev);
 void r100_mc_disable_clients(struct radeon_device *rdev);
 int r100_gui_wait_for_idle(struct radeon_device *rdev);
@@ -47,14 +49,10 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
 			 struct radeon_cs_packet *pkt,
 			 unsigned idx);
 int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
-int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
-			      struct radeon_cs_reloc **cs_reloc);
 int r100_cs_parse_packet0(struct radeon_cs_parser *p,
 			  struct radeon_cs_packet *pkt,
 			  const unsigned *auth, unsigned n,
 			  radeon_packet0_check_t check);
-void r100_cs_dump_packet(struct radeon_cs_parser *p,
-			 struct radeon_cs_packet *pkt);
 int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
 					 struct radeon_cs_packet *pkt,
 					 struct radeon_object *robj);
@@ -87,26 +85,57 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
 	mb();
 }
 
-int rv370_pcie_gart_enable(struct radeon_device *rdev)
+int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
+{
+	void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+
+	if (i < 0 || i > rdev->gart.num_gpu_pages) {
+		return -EINVAL;
+	}
+	addr = (lower_32_bits(addr) >> 8) |
+	       ((upper_32_bits(addr) & 0xff) << 24) |
+	       0xc;
+	/* on x86 we want this to be CPU endian, on powerpc
+	 * on powerpc without HW swappers, it'll get swapped on way
+	 * into VRAM - so no need for cpu_to_le32 on VRAM tables */
+	writel(addr, ((void __iomem *)ptr) + (i * 4));
+	return 0;
+}
+
+int rv370_pcie_gart_init(struct radeon_device *rdev)
 {
-	uint32_t table_addr;
-	uint32_t tmp;
 	int r;
 
+	if (rdev->gart.table.vram.robj) {
+		WARN(1, "RV370 PCIE GART already initialized.\n");
+		return 0;
+	}
 	/* Initialize common gart structure */
 	r = radeon_gart_init(rdev);
-	if (r) {
+	if (r)
 		return r;
-	}
 	r = rv370_debugfs_pcie_gart_info_init(rdev);
-	if (r) {
+	if (r)
 		DRM_ERROR("Failed to register debugfs file for PCIE gart !\n");
-	}
 	rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
-	r = radeon_gart_table_vram_alloc(rdev);
-	if (r) {
-		return r;
+	rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+	rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+	return radeon_gart_table_vram_alloc(rdev);
+}
+
+int rv370_pcie_gart_enable(struct radeon_device *rdev)
+{
+	uint32_t table_addr;
+	uint32_t tmp;
+	int r;
+
+	if (rdev->gart.table.vram.robj == NULL) {
+		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
+		return -EINVAL;
 	}
+	r = radeon_gart_table_vram_pin(rdev);
+	if (r)
+		return r;
 	/* discard memory request outside of configured range */
 	tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
 	WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
@@ -128,7 +157,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
 	WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp);
 	rv370_pcie_gart_tlb_flush(rdev);
 	DRM_INFO("PCIE GART of %uM enabled (table at 0x%08X).\n",
-		 rdev->mc.gtt_size >> 20, table_addr);
+		 (unsigned)(rdev->mc.gtt_size >> 20), table_addr);
 	rdev->gart.ready = true;
 	return 0;
 }
@@ -146,45 +175,13 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
 	}
 }
 
-int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
+void rv370_pcie_gart_fini(struct radeon_device *rdev)
 {
-	void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
-
-	if (i < 0 || i > rdev->gart.num_gpu_pages) {
-		return -EINVAL;
-	}
-	addr = (lower_32_bits(addr) >> 8) |
-	       ((upper_32_bits(addr) & 0xff) << 24) |
-	       0xc;
-	/* on x86 we want this to be CPU endian, on powerpc
-	 * on powerpc without HW swappers, it'll get swapped on way
-	 * into VRAM - so no need for cpu_to_le32 on VRAM tables */
-	writel(addr, ((void __iomem *)ptr) + (i * 4));
-	return 0;
-}
-
-int r300_gart_enable(struct radeon_device *rdev)
-{
-#if __OS_HAS_AGP
-	if (rdev->flags & RADEON_IS_AGP) {
-		if (rdev->family > CHIP_RV350) {
-			rv370_pcie_gart_disable(rdev);
-		} else {
-			r100_pci_gart_disable(rdev);
-		}
-		return 0;
-	}
-#endif
-	if (rdev->flags & RADEON_IS_PCIE) {
-		rdev->asic->gart_disable = &rv370_pcie_gart_disable;
-		rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
-		rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
-		return rv370_pcie_gart_enable(rdev);
-	}
-	return r100_pci_gart_enable(rdev);
+	rv370_pcie_gart_disable(rdev);
+	radeon_gart_table_vram_free(rdev);
+	radeon_gart_fini(rdev);
 }
 
-
 /*
  * MC
  */
@@ -232,14 +229,6 @@ int r300_mc_init(struct radeon_device *rdev)
 
 void r300_mc_fini(struct radeon_device *rdev)
 {
-	if (rdev->flags & RADEON_IS_PCIE) {
-		rv370_pcie_gart_disable(rdev);
-		radeon_gart_table_vram_free(rdev);
-	} else {
-		r100_pci_gart_disable(rdev);
-		radeon_gart_table_ram_free(rdev);
-	}
-	radeon_gart_fini(rdev);
 }
 
 
@@ -704,307 +693,13 @@ int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
 /*
  * CS functions
  */
-struct r300_cs_track_cb {
-	struct radeon_object	*robj;
-	unsigned		pitch;
-	unsigned		cpp;
-	unsigned		offset;
-};
-
-struct r300_cs_track_array {
-	struct radeon_object	*robj;
-	unsigned		esize;
-};
-
-struct r300_cs_track_texture {
-	struct radeon_object	*robj;
-	unsigned		pitch;
-	unsigned		width;
-	unsigned		height;
-	unsigned		num_levels;
-	unsigned		cpp;
-	unsigned		tex_coord_type;
-	unsigned		txdepth;
-	unsigned		width_11;
-	unsigned		height_11;
-	bool			use_pitch;
-	bool			enabled;
-	bool			roundup_w;
-	bool			roundup_h;
-};
-
-struct r300_cs_track {
-	unsigned			num_cb;
-	unsigned			maxy;
-	unsigned			vtx_size;
-	unsigned			vap_vf_cntl;
-	unsigned			immd_dwords;
-	unsigned			num_arrays;
-	unsigned			max_indx;
-	struct r300_cs_track_array	arrays[11];
-	struct r300_cs_track_cb 	cb[4];
-	struct r300_cs_track_cb 	zb;
-	struct r300_cs_track_texture	textures[16];
-	bool				z_enabled;
-};
-
-static inline void r300_cs_track_texture_print(struct r300_cs_track_texture *t)
-{
-	DRM_ERROR("pitch                      %d\n", t->pitch);
-	DRM_ERROR("width                      %d\n", t->width);
-	DRM_ERROR("height                     %d\n", t->height);
-	DRM_ERROR("num levels                 %d\n", t->num_levels);
-	DRM_ERROR("depth                      %d\n", t->txdepth);
-	DRM_ERROR("bpp                        %d\n", t->cpp);
-	DRM_ERROR("coordinate type            %d\n", t->tex_coord_type);
-	DRM_ERROR("width round to power of 2  %d\n", t->roundup_w);
-	DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
-}
-
-static inline int r300_cs_track_texture_check(struct radeon_device *rdev,
-					      struct r300_cs_track *track)
-{
-	struct radeon_object *robj;
-	unsigned long size;
-	unsigned u, i, w, h;
-
-	for (u = 0; u < 16; u++) {
-		if (!track->textures[u].enabled)
-			continue;
-		robj = track->textures[u].robj;
-		if (robj == NULL) {
-			DRM_ERROR("No texture bound to unit %u\n", u);
-			return -EINVAL;
-		}
-		size = 0;
-		for (i = 0; i <= track->textures[u].num_levels; i++) {
-			if (track->textures[u].use_pitch) {
-				w = track->textures[u].pitch / (1 << i);
-			} else {
-				w = track->textures[u].width / (1 << i);
-				if (rdev->family >= CHIP_RV515)
-					w |= track->textures[u].width_11;
-				if (track->textures[u].roundup_w)
-					w = roundup_pow_of_two(w);
-			}
-			h = track->textures[u].height / (1 << i);
-			if (rdev->family >= CHIP_RV515)
-				h |= track->textures[u].height_11;
-			if (track->textures[u].roundup_h)
-				h = roundup_pow_of_two(h);
-			size += w * h;
-		}
-		size *= track->textures[u].cpp;
-		switch (track->textures[u].tex_coord_type) {
-		case 0:
-			break;
-		case 1:
-			size *= (1 << track->textures[u].txdepth);
-			break;
-		case 2:
-			size *= 6;
-			break;
-		default:
-			DRM_ERROR("Invalid texture coordinate type %u for unit "
-				  "%u\n", track->textures[u].tex_coord_type, u);
-			return -EINVAL;
-		}
-		if (size > radeon_object_size(robj)) {
-			DRM_ERROR("Texture of unit %u needs %lu bytes but is "
-				  "%lu\n", u, size, radeon_object_size(robj));
-			r300_cs_track_texture_print(&track->textures[u]);
-			return -EINVAL;
-		}
-	}
-	return 0;
-}
-
-int r300_cs_track_check(struct radeon_device *rdev, struct r300_cs_track *track)
-{
-	unsigned i;
-	unsigned long size;
-	unsigned prim_walk;
-	unsigned nverts;
-
-	for (i = 0; i < track->num_cb; i++) {
-		if (track->cb[i].robj == NULL) {
-			DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
-			return -EINVAL;
-		}
-		size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
-		size += track->cb[i].offset;
-		if (size > radeon_object_size(track->cb[i].robj)) {
-			DRM_ERROR("[drm] Buffer too small for color buffer %d "
-				  "(need %lu have %lu) !\n", i, size,
-				  radeon_object_size(track->cb[i].robj));
-			DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
-				  i, track->cb[i].pitch, track->cb[i].cpp,
-				  track->cb[i].offset, track->maxy);
-			return -EINVAL;
-		}
-	}
-	if (track->z_enabled) {
-		if (track->zb.robj == NULL) {
-			DRM_ERROR("[drm] No buffer for z buffer !\n");
-			return -EINVAL;
-		}
-		size = track->zb.pitch * track->zb.cpp * track->maxy;
-		size += track->zb.offset;
-		if (size > radeon_object_size(track->zb.robj)) {
-			DRM_ERROR("[drm] Buffer too small for z buffer "
-				  "(need %lu have %lu) !\n", size,
-				  radeon_object_size(track->zb.robj));
-			return -EINVAL;
-		}
-	}
-	prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
-	nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
-	switch (prim_walk) {
-	case 1:
-		for (i = 0; i < track->num_arrays; i++) {
-			size = track->arrays[i].esize * track->max_indx * 4;
-			if (track->arrays[i].robj == NULL) {
-				DRM_ERROR("(PW %u) Vertex array %u no buffer "
-					  "bound\n", prim_walk, i);
-				return -EINVAL;
-			}
-			if (size > radeon_object_size(track->arrays[i].robj)) {
-				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
-					   "have %lu dwords\n", prim_walk, i,
-					   size >> 2,
-					   radeon_object_size(track->arrays[i].robj) >> 2);
-				DRM_ERROR("Max indices %u\n", track->max_indx);
-				return -EINVAL;
-			}
-		}
-		break;
-	case 2:
-		for (i = 0; i < track->num_arrays; i++) {
-			size = track->arrays[i].esize * (nverts - 1) * 4;
-			if (track->arrays[i].robj == NULL) {
-				DRM_ERROR("(PW %u) Vertex array %u no buffer "
-					  "bound\n", prim_walk, i);
-				return -EINVAL;
-			}
-			if (size > radeon_object_size(track->arrays[i].robj)) {
-				DRM_ERROR("(PW %u) Vertex array %u need %lu dwords "
-					   "have %lu dwords\n", prim_walk, i, size >> 2,
-					   radeon_object_size(track->arrays[i].robj) >> 2);
-				return -EINVAL;
-			}
-		}
-		break;
-	case 3:
-		size = track->vtx_size * nverts;
-		if (size != track->immd_dwords) {
-			DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n",
-				  track->immd_dwords, size);
-			DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n",
-				  nverts, track->vtx_size);
-			return -EINVAL;
-		}
-		break;
-	default:
-		DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n",
-			  prim_walk);
-		return -EINVAL;
-	}
-	return r300_cs_track_texture_check(rdev, track);
-}
-
-static inline void r300_cs_track_clear(struct r300_cs_track *track)
-{
-	unsigned i;
-
-	track->num_cb = 4;
-	track->maxy = 4096;
-	for (i = 0; i < track->num_cb; i++) {
-		track->cb[i].robj = NULL;
-		track->cb[i].pitch = 8192;
-		track->cb[i].cpp = 16;
-		track->cb[i].offset = 0;
-	}
-	track->z_enabled = true;
-	track->zb.robj = NULL;
-	track->zb.pitch = 8192;
-	track->zb.cpp = 4;
-	track->zb.offset = 0;
-	track->vtx_size = 0x7F;
-	track->immd_dwords = 0xFFFFFFFFUL;
-	track->num_arrays = 11;
-	track->max_indx = 0x00FFFFFFUL;
-	for (i = 0; i < track->num_arrays; i++) {
-		track->arrays[i].robj = NULL;
-		track->arrays[i].esize = 0x7F;
-	}
-	for (i = 0; i < 16; i++) {
-		track->textures[i].pitch = 16536;
-		track->textures[i].width = 16536;
-		track->textures[i].height = 16536;
-		track->textures[i].width_11 = 1 << 11;
-		track->textures[i].height_11 = 1 << 11;
-		track->textures[i].num_levels = 12;
-		track->textures[i].txdepth = 16;
-		track->textures[i].cpp = 64;
-		track->textures[i].tex_coord_type = 1;
-		track->textures[i].robj = NULL;
-		/* CS IB emission code makes sure texture unit are disabled */
-		track->textures[i].enabled = false;
-		track->textures[i].roundup_w = true;
-		track->textures[i].roundup_h = true;
-	}
-}
-
-static const unsigned r300_reg_safe_bm[159] = {
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
-	0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
-	0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
-	0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF,
-	0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
-	0x00000000, 0x0000C100, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x0003FC01, 0xFFFFFCF8, 0xFF800B19,
-};
-
 static int r300_packet0_check(struct radeon_cs_parser *p,
 		struct radeon_cs_packet *pkt,
 		unsigned idx, unsigned reg)
 {
 	struct radeon_cs_chunk *ib_chunk;
 	struct radeon_cs_reloc *reloc;
-	struct r300_cs_track *track;
+	struct r100_cs_track *track;
 	volatile uint32_t *ib;
 	uint32_t tmp, tile_flags = 0;
 	unsigned i;
@@ -1012,7 +707,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
 
 	ib = p->ib->ptr;
 	ib_chunk = &p->chunks[p->chunk_ib_idx];
-	track = (struct r300_cs_track*)p->track;
+	track = (struct r100_cs_track *)p->track;
 	switch(reg) {
 	case AVIVO_D1MODE_VLINE_START_END:
 	case RADEON_CRTC_GUI_TRIG_VLINE:
@@ -1026,28 +721,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
 		break;
 	case RADEON_DST_PITCH_OFFSET:
 	case RADEON_SRC_PITCH_OFFSET:
-		r = r100_cs_packet_next_reloc(p, &reloc);
-		if (r) {
-			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
-					idx, reg);
-			r100_cs_dump_packet(p, pkt);
+		r = r100_reloc_pitch_offset(p, pkt, idx, reg);
+		if (r)
 			return r;
-		}
-		tmp = ib_chunk->kdata[idx] & 0x003fffff;
-		tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
-
-		if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
-			tile_flags |= RADEON_DST_TILE_MACRO;
-		if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
-			if (reg == RADEON_SRC_PITCH_OFFSET) {
-				DRM_ERROR("Cannot src blit from microtiled surface\n");
-				r100_cs_dump_packet(p, pkt);
-				return -EINVAL;
-			}
-			tile_flags |= RADEON_DST_TILE_MICRO;
-		}
-		tmp |= tile_flags;
-		ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
 		break;
 	case R300_RB3D_COLOROFFSET0:
 	case R300_RB3D_COLOROFFSET1:
@@ -1256,42 +932,41 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
 		tmp = (ib_chunk->kdata[idx] >> 25) & 0x3;
 		track->textures[i].tex_coord_type = tmp;
 		switch ((ib_chunk->kdata[idx] & 0x1F)) {
-		case 0:
-		case 2:
-		case 5:
-		case 18:
-		case 20:
-		case 21:
+		case R300_TX_FORMAT_X8:
+		case R300_TX_FORMAT_Y4X4:
+		case R300_TX_FORMAT_Z3Y3X2:
 			track->textures[i].cpp = 1;
 			break;
-		case 1:
-		case 3:
-		case 6:
-		case 7:
-		case 10:
-		case 11:
-		case 19:
-		case 22:
-		case 24:
+		case R300_TX_FORMAT_X16:
+		case R300_TX_FORMAT_Y8X8:
+		case R300_TX_FORMAT_Z5Y6X5:
+		case R300_TX_FORMAT_Z6Y5X5:
+		case R300_TX_FORMAT_W4Z4Y4X4:
+		case R300_TX_FORMAT_W1Z5Y5X5:
+		case R300_TX_FORMAT_DXT1:
+		case R300_TX_FORMAT_D3DMFT_CxV8U8:
+		case R300_TX_FORMAT_B8G8_B8G8:
+		case R300_TX_FORMAT_G8R8_G8B8:
 			track->textures[i].cpp = 2;
 			break;
-		case 4:
-		case 8:
-		case 9:
-		case 12:
-		case 13:
-		case 23:
-		case 25:
-		case 27:
-		case 30:
+		case R300_TX_FORMAT_Y16X16:
+		case R300_TX_FORMAT_Z11Y11X10:
+		case R300_TX_FORMAT_Z10Y11X11:
+		case R300_TX_FORMAT_W8Z8Y8X8:
+		case R300_TX_FORMAT_W2Z10Y10X10:
+		case 0x17:
+		case R300_TX_FORMAT_FL_I32:
+		case 0x1e:
+		case R300_TX_FORMAT_DXT3:
+		case R300_TX_FORMAT_DXT5:
 			track->textures[i].cpp = 4;
 			break;
-		case 14:
-		case 26:
-		case 28:
+		case R300_TX_FORMAT_W16Z16Y16X16:
+		case R300_TX_FORMAT_FL_R16G16B16A16:
+		case R300_TX_FORMAT_FL_I32A32:
 			track->textures[i].cpp = 8;
 			break;
-		case 29:
+		case R300_TX_FORMAT_FL_R32G32B32A32:
 			track->textures[i].cpp = 16;
 			break;
 		default:
@@ -1319,11 +994,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
 	case 0x443C:
 		/* TX_FILTER0_[0-15] */
 		i = (reg - 0x4400) >> 2;
-		tmp = ib_chunk->kdata[idx] & 0x7;;
+		tmp = ib_chunk->kdata[idx] & 0x7;
 		if (tmp == 2 || tmp == 4 || tmp == 6) {
 			track->textures[i].roundup_w = false;
 		}
-		tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;;
+		tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;
 		if (tmp == 2 || tmp == 4 || tmp == 6) {
 			track->textures[i].roundup_h = false;
 		}
@@ -1411,8 +1086,9 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
 			      struct radeon_cs_packet *pkt)
 {
 	struct radeon_cs_chunk *ib_chunk;
+
 	struct radeon_cs_reloc *reloc;
-	struct r300_cs_track *track;
+	struct r100_cs_track *track;
 	volatile uint32_t *ib;
 	unsigned idx;
 	unsigned i, c;
@@ -1421,7 +1097,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
 	ib = p->ib->ptr;
 	ib_chunk = &p->chunks[p->chunk_ib_idx];
 	idx = pkt->idx + 1;
-	track = (struct r300_cs_track*)p->track;
+	track = (struct r100_cs_track *)p->track;
 	switch(pkt->opcode) {
 	case PACKET3_3D_LOAD_VBPNTR:
 		c = ib_chunk->kdata[idx++] & 0x1F;
@@ -1488,7 +1164,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
 		}
 		track->vap_vf_cntl = ib_chunk->kdata[idx+1];
 		track->immd_dwords = pkt->count - 1;
-		r = r300_cs_track_check(p->rdev, track);
+		r = r100_cs_track_check(p->rdev, track);
 		if (r) {
 			return r;
 		}
@@ -1503,35 +1179,35 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
 		}
 		track->vap_vf_cntl = ib_chunk->kdata[idx];
 		track->immd_dwords = pkt->count;
-		r = r300_cs_track_check(p->rdev, track);
+		r = r100_cs_track_check(p->rdev, track);
 		if (r) {
 			return r;
 		}
 		break;
 	case PACKET3_3D_DRAW_VBUF:
 		track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
-		r = r300_cs_track_check(p->rdev, track);
+		r = r100_cs_track_check(p->rdev, track);
 		if (r) {
 			return r;
 		}
 		break;
 	case PACKET3_3D_DRAW_VBUF_2:
 		track->vap_vf_cntl = ib_chunk->kdata[idx];
-		r = r300_cs_track_check(p->rdev, track);
+		r = r100_cs_track_check(p->rdev, track);
 		if (r) {
 			return r;
 		}
 		break;
 	case PACKET3_3D_DRAW_INDX:
 		track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
-		r = r300_cs_track_check(p->rdev, track);
+		r = r100_cs_track_check(p->rdev, track);
 		if (r) {
 			return r;
 		}
 		break;
 	case PACKET3_3D_DRAW_INDX_2:
 		track->vap_vf_cntl = ib_chunk->kdata[idx];
-		r = r300_cs_track_check(p->rdev, track);
+		r = r100_cs_track_check(p->rdev, track);
 		if (r) {
 			return r;
 		}
@@ -1548,11 +1224,12 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
 int r300_cs_parse(struct radeon_cs_parser *p)
 {
 	struct radeon_cs_packet pkt;
-	struct r300_cs_track track;
+	struct r100_cs_track *track;
 	int r;
 
-	r300_cs_track_clear(&track);
-	p->track = &track;
+	track = kzalloc(sizeof(*track), GFP_KERNEL);
+	r100_cs_track_clear(p->rdev, track);
+	p->track = track;
 	do {
 		r = r100_cs_packet_parse(p, &pkt, p->idx);
 		if (r) {
@@ -1582,9 +1259,48 @@ int r300_cs_parse(struct radeon_cs_parser *p)
 	return 0;
 }
 
-int r300_init(struct radeon_device *rdev)
+void r300_set_reg_safe(struct radeon_device *rdev)
 {
 	rdev->config.r300.reg_safe_bm = r300_reg_safe_bm;
 	rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm);
+}
+
+int r300_init(struct radeon_device *rdev)
+{
+	r300_set_reg_safe(rdev);
 	return 0;
 }
+
+void r300_mc_program(struct radeon_device *rdev)
+{
+	struct r100_mc_save save;
+	int r;
+
+	r = r100_debugfs_mc_info_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "Failed to create r100_mc debugfs file.\n");
+	}
+
+	/* Stops all mc clients */
+	r100_mc_stop(rdev, &save);
+	if (rdev->flags & RADEON_IS_AGP) {
+		WREG32(R_00014C_MC_AGP_LOCATION,
+			S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
+			S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
+		WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
+		WREG32(R_00015C_AGP_BASE_2,
+			upper_32_bits(rdev->mc.agp_base) & 0xff);
+	} else {
+		WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF);
+		WREG32(R_000170_AGP_BASE, 0);
+		WREG32(R_00015C_AGP_BASE_2, 0);
+	}
+	/* Wait for mc idle */
+	if (r300_mc_wait_for_idle(rdev))
+		DRM_INFO("Failed to wait MC idle before programming MC.\n");
+	/* Program MC, should be a 32bits limited address space */
+	WREG32(R_000148_MC_FB_LOCATION,
+		S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
+		S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
+	r100_mc_resume(rdev, &save);
+}
diff --git a/drivers/gpu/drm/radeon/r300.h b/drivers/gpu/drm/radeon/r300.h
deleted file mode 100644
index 8486b4d..0000000
--- a/drivers/gpu/drm/radeon/r300.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2008 Advanced Micro Devices, Inc.
- * Copyright 2008 Red Hat Inc.
- * Copyright 2009 Jerome Glisse.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Dave Airlie
- *          Alex Deucher
- *          Jerome Glisse
- */
-#ifndef R300_H
-#define R300_H
-
-struct r300_asic {
-	const unsigned	*reg_safe_bm;
-	unsigned	reg_safe_bm_size;
-};
-
-#endif
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h
new file mode 100644
index 0000000..d4fa3eb
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r300d.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef __R300D_H__
+#define __R300D_H__
+
+#define CP_PACKET0			0x00000000
+#define		PACKET0_BASE_INDEX_SHIFT	0
+#define		PACKET0_BASE_INDEX_MASK		(0x1ffff << 0)
+#define		PACKET0_COUNT_SHIFT		16
+#define		PACKET0_COUNT_MASK		(0x3fff << 16)
+#define CP_PACKET1			0x40000000
+#define CP_PACKET2			0x80000000
+#define		PACKET2_PAD_SHIFT		0
+#define		PACKET2_PAD_MASK		(0x3fffffff << 0)
+#define CP_PACKET3			0xC0000000
+#define		PACKET3_IT_OPCODE_SHIFT		8
+#define		PACKET3_IT_OPCODE_MASK		(0xff << 8)
+#define		PACKET3_COUNT_SHIFT		16
+#define		PACKET3_COUNT_MASK		(0x3fff << 16)
+/* PACKET3 op code */
+#define		PACKET3_NOP			0x10
+#define		PACKET3_3D_DRAW_VBUF		0x28
+#define		PACKET3_3D_DRAW_IMMD		0x29
+#define		PACKET3_3D_DRAW_INDX		0x2A
+#define		PACKET3_3D_LOAD_VBPNTR		0x2F
+#define		PACKET3_INDX_BUFFER		0x33
+#define		PACKET3_3D_DRAW_VBUF_2		0x34
+#define		PACKET3_3D_DRAW_IMMD_2		0x35
+#define		PACKET3_3D_DRAW_INDX_2		0x36
+#define		PACKET3_BITBLT_MULTI		0x9B
+
+#define PACKET0(reg, n)	(CP_PACKET0 |					\
+			 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) |	\
+			 REG_SET(PACKET0_COUNT, (n)))
+#define PACKET2(v)	(CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+#define PACKET3(op, n)	(CP_PACKET3 |					\
+			 REG_SET(PACKET3_IT_OPCODE, (op)) |		\
+			 REG_SET(PACKET3_COUNT, (n)))
+
+#define	PACKET_TYPE0	0
+#define	PACKET_TYPE1	1
+#define	PACKET_TYPE2	2
+#define	PACKET_TYPE3	3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
+#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+
+/* Registers */
+#define R_000148_MC_FB_LOCATION                      0x000148
+#define   S_000148_MC_FB_START(x)                      (((x) & 0xFFFF) << 0)
+#define   G_000148_MC_FB_START(x)                      (((x) >> 0) & 0xFFFF)
+#define   C_000148_MC_FB_START                         0xFFFF0000
+#define   S_000148_MC_FB_TOP(x)                        (((x) & 0xFFFF) << 16)
+#define   G_000148_MC_FB_TOP(x)                        (((x) >> 16) & 0xFFFF)
+#define   C_000148_MC_FB_TOP                           0x0000FFFF
+#define R_00014C_MC_AGP_LOCATION                     0x00014C
+#define   S_00014C_MC_AGP_START(x)                     (((x) & 0xFFFF) << 0)
+#define   G_00014C_MC_AGP_START(x)                     (((x) >> 0) & 0xFFFF)
+#define   C_00014C_MC_AGP_START                        0xFFFF0000
+#define   S_00014C_MC_AGP_TOP(x)                       (((x) & 0xFFFF) << 16)
+#define   G_00014C_MC_AGP_TOP(x)                       (((x) >> 16) & 0xFFFF)
+#define   C_00014C_MC_AGP_TOP                          0x0000FFFF
+#define R_00015C_AGP_BASE_2                          0x00015C
+#define   S_00015C_AGP_BASE_ADDR_2(x)                  (((x) & 0xF) << 0)
+#define   G_00015C_AGP_BASE_ADDR_2(x)                  (((x) >> 0) & 0xF)
+#define   C_00015C_AGP_BASE_ADDR_2                     0xFFFFFFF0
+#define R_000170_AGP_BASE                            0x000170
+#define   S_000170_AGP_BASE_ADDR(x)                    (((x) & 0xFFFFFFFF) << 0)
+#define   G_000170_AGP_BASE_ADDR(x)                    (((x) >> 0) & 0xFFFFFFFF)
+#define   C_000170_AGP_BASE_ADDR                       0x00000000
+
+
+#endif
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 97426a6..49a2fdc 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -29,47 +29,13 @@
 #include "drmP.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "atom.h"
+#include "r420d.h"
 
-/* r420,r423,rv410 depends on : */
-void r100_pci_gart_disable(struct radeon_device *rdev);
-void r100_hdp_reset(struct radeon_device *rdev);
-void r100_mc_setup(struct radeon_device *rdev);
-int r100_gui_wait_for_idle(struct radeon_device *rdev);
-void r100_mc_disable_clients(struct radeon_device *rdev);
-void r300_vram_info(struct radeon_device *rdev);
-int r300_mc_wait_for_idle(struct radeon_device *rdev);
-int rv370_pcie_gart_enable(struct radeon_device *rdev);
-void rv370_pcie_gart_disable(struct radeon_device *rdev);
-
-/* This files gather functions specifics to :
- * r420,r423,rv410
- *
- * Some of these functions might be used by newer ASICs.
- */
-void r420_gpu_init(struct radeon_device *rdev);
-int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
-
-
-/*
- * MC
- */
 int r420_mc_init(struct radeon_device *rdev)
 {
 	int r;
 
-	if (r100_debugfs_rbbm_init(rdev)) {
-		DRM_ERROR("Failed to register debugfs file for RBBM !\n");
-	}
-	if (r420_debugfs_pipes_info_init(rdev)) {
-		DRM_ERROR("Failed to register debugfs file for pipes !\n");
-	}
-
-	r420_gpu_init(rdev);
-	r100_pci_gart_disable(rdev);
-	if (rdev->flags & RADEON_IS_PCIE) {
-		rv370_pcie_gart_disable(rdev);
-	}
-
 	/* Setup GPU memory space */
 	rdev->mc.vram_location = 0xFFFFFFFFUL;
 	rdev->mc.gtt_location = 0xFFFFFFFFUL;
@@ -87,33 +53,9 @@ int r420_mc_init(struct radeon_device *rdev)
 	if (r) {
 		return r;
 	}
-
-	/* Program GPU memory space */
-	r100_mc_disable_clients(rdev);
-	if (r300_mc_wait_for_idle(rdev)) {
-		printk(KERN_WARNING "Failed to wait MC idle while "
-		       "programming pipes. Bad things might happen.\n");
-	}
-	r100_mc_setup(rdev);
 	return 0;
 }
 
-void r420_mc_fini(struct radeon_device *rdev)
-{
-	rv370_pcie_gart_disable(rdev);
-	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
-}
-
-
-/*
- * Global GPU functions
- */
-void r420_errata(struct radeon_device *rdev)
-{
-	rdev->pll_errata = 0;
-}
-
 void r420_pipes_init(struct radeon_device *rdev)
 {
 	unsigned tmp;
@@ -122,6 +64,11 @@ void r420_pipes_init(struct radeon_device *rdev)
 
 	/* GA_ENHANCE workaround TCL deadlock issue */
 	WREG32(0x4274, (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3));
+	/* add idle wait as per freedesktop.org bug 24041 */
+	if (r100_gui_wait_for_idle(rdev)) {
+		printk(KERN_WARNING "Failed to wait GUI idle while "
+		       "programming pipes. Bad things might happen.\n");
+	}
 	/* get max number of pipes */
 	gb_pipe_select = RREG32(0x402C);
 	num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
@@ -179,25 +126,239 @@ void r420_pipes_init(struct radeon_device *rdev)
 		 rdev->num_gb_pipes, rdev->num_z_pipes);
 }
 
-void r420_gpu_init(struct radeon_device *rdev)
+u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg)
+{
+	u32 r;
+
+	WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg));
+	r = RREG32(R_0001FC_MC_IND_DATA);
+	return r;
+}
+
+void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+	WREG32(R_0001F8_MC_IND_INDEX, S_0001F8_MC_IND_ADDR(reg) |
+		S_0001F8_MC_IND_WR_EN(1));
+	WREG32(R_0001FC_MC_IND_DATA, v);
+}
+
+static void r420_debugfs(struct radeon_device *rdev)
+{
+	if (r100_debugfs_rbbm_init(rdev)) {
+		DRM_ERROR("Failed to register debugfs file for RBBM !\n");
+	}
+	if (r420_debugfs_pipes_info_init(rdev)) {
+		DRM_ERROR("Failed to register debugfs file for pipes !\n");
+	}
+}
+
+static void r420_clock_resume(struct radeon_device *rdev)
+{
+	u32 sclk_cntl;
+	sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL);
+	sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
+	if (rdev->family == CHIP_R420)
+		sclk_cntl |= S_00000D_FORCE_PX(1) | S_00000D_FORCE_TX(1);
+	WREG32_PLL(R_00000D_SCLK_CNTL, sclk_cntl);
+}
+
+static int r420_startup(struct radeon_device *rdev)
 {
-	r100_hdp_reset(rdev);
+	int r;
+
+	r300_mc_program(rdev);
+	/* Initialize GART (initialize after TTM so we can allocate
+	 * memory through TTM but finalize after TTM) */
+	if (rdev->flags & RADEON_IS_PCIE) {
+		r = rv370_pcie_gart_enable(rdev);
+		if (r)
+			return r;
+	}
+	if (rdev->flags & RADEON_IS_PCI) {
+		r = r100_pci_gart_enable(rdev);
+		if (r)
+			return r;
+	}
 	r420_pipes_init(rdev);
-	if (r300_mc_wait_for_idle(rdev)) {
-		printk(KERN_WARNING "Failed to wait MC idle while "
-		       "programming pipes. Bad things might happen.\n");
+	/* Enable IRQ */
+	rdev->irq.sw_int = true;
+	r100_irq_set(rdev);
+	/* 1M ring buffer */
+	r = r100_cp_init(rdev, 1024 * 1024);
+	if (r) {
+		dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
+		return r;
+	}
+	r = r100_wb_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
+	}
+	r = r100_ib_init(rdev);
+	if (r) {
+		dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
+		return r;
 	}
+	return 0;
 }
 
+int r420_resume(struct radeon_device *rdev)
+{
+	/* Make sur GART are not working */
+	if (rdev->flags & RADEON_IS_PCIE)
+		rv370_pcie_gart_disable(rdev);
+	if (rdev->flags & RADEON_IS_PCI)
+		r100_pci_gart_disable(rdev);
+	/* Resume clock before doing reset */
+	r420_clock_resume(rdev);
+	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
+	if (radeon_gpu_reset(rdev)) {
+		dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+			RREG32(R_000E40_RBBM_STATUS),
+			RREG32(R_0007C0_CP_STAT));
+	}
+	/* check if cards are posted or not */
+	if (rdev->is_atom_bios) {
+		atom_asic_init(rdev->mode_info.atom_context);
+	} else {
+		radeon_combios_asic_init(rdev->ddev);
+	}
+	/* Resume clock after posting */
+	r420_clock_resume(rdev);
 
-/*
- * r420,r423,rv410 VRAM info
- */
-void r420_vram_info(struct radeon_device *rdev)
+	return r420_startup(rdev);
+}
+
+int r420_suspend(struct radeon_device *rdev)
 {
-	r300_vram_info(rdev);
+	r100_cp_disable(rdev);
+	r100_wb_disable(rdev);
+	r100_irq_disable(rdev);
+	if (rdev->flags & RADEON_IS_PCIE)
+		rv370_pcie_gart_disable(rdev);
+	if (rdev->flags & RADEON_IS_PCI)
+		r100_pci_gart_disable(rdev);
+	return 0;
+}
+
+void r420_fini(struct radeon_device *rdev)
+{
+	r100_cp_fini(rdev);
+	r100_wb_fini(rdev);
+	r100_ib_fini(rdev);
+	radeon_gem_fini(rdev);
+	if (rdev->flags & RADEON_IS_PCIE)
+		rv370_pcie_gart_fini(rdev);
+	if (rdev->flags & RADEON_IS_PCI)
+		r100_pci_gart_fini(rdev);
+	radeon_agp_fini(rdev);
+	radeon_irq_kms_fini(rdev);
+	radeon_fence_driver_fini(rdev);
+	radeon_object_fini(rdev);
+	if (rdev->is_atom_bios) {
+		radeon_atombios_fini(rdev);
+	} else {
+		radeon_combios_fini(rdev);
+	}
+	kfree(rdev->bios);
+	rdev->bios = NULL;
 }
 
+int r420_init(struct radeon_device *rdev)
+{
+	int r;
+
+	rdev->new_init_path = true;
+	/* Initialize scratch registers */
+	radeon_scratch_init(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
+	/* TODO: disable VGA need to use VGA request */
+	/* BIOS*/
+	if (!radeon_get_bios(rdev)) {
+		if (ASIC_IS_AVIVO(rdev))
+			return -EINVAL;
+	}
+	if (rdev->is_atom_bios) {
+		r = radeon_atombios_init(rdev);
+		if (r) {
+			return r;
+		}
+	} else {
+		r = radeon_combios_init(rdev);
+		if (r) {
+			return r;
+		}
+	}
+	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
+	if (radeon_gpu_reset(rdev)) {
+		dev_warn(rdev->dev,
+			"GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
+			RREG32(R_000E40_RBBM_STATUS),
+			RREG32(R_0007C0_CP_STAT));
+	}
+	/* check if cards are posted or not */
+	if (!radeon_card_posted(rdev) && rdev->bios) {
+		DRM_INFO("GPU not posted. posting now...\n");
+		if (rdev->is_atom_bios) {
+			atom_asic_init(rdev->mode_info.atom_context);
+		} else {
+			radeon_combios_asic_init(rdev->ddev);
+		}
+	}
+	/* Initialize clocks */
+	radeon_get_clock_info(rdev->ddev);
+	/* Get vram informations */
+	r300_vram_info(rdev);
+	/* Initialize memory controller (also test AGP) */
+	r = r420_mc_init(rdev);
+	if (r) {
+		return r;
+	}
+	r420_debugfs(rdev);
+	/* Fence driver */
+	r = radeon_fence_driver_init(rdev);
+	if (r) {
+		return r;
+	}
+	r = radeon_irq_kms_init(rdev);
+	if (r) {
+		return r;
+	}
+	/* Memory manager */
+	r = radeon_object_init(rdev);
+	if (r) {
+		return r;
+	}
+	if (rdev->flags & RADEON_IS_PCIE) {
+		r = rv370_pcie_gart_init(rdev);
+		if (r)
+			return r;
+	}
+	if (rdev->flags & RADEON_IS_PCI) {
+		r = r100_pci_gart_init(rdev);
+		if (r)
+			return r;
+	}
+	r300_set_reg_safe(rdev);
+	rdev->accel_working = true;
+	r = r420_startup(rdev);
+	if (r) {
+		/* Somethings want wront with the accel init stop accel */
+		dev_err(rdev->dev, "Disabling GPU acceleration\n");
+		r420_suspend(rdev);
+		r100_cp_fini(rdev);
+		r100_wb_fini(rdev);
+		r100_ib_fini(rdev);
+		if (rdev->flags & RADEON_IS_PCIE)
+			rv370_pcie_gart_fini(rdev);
+		if (rdev->flags & RADEON_IS_PCI)
+			r100_pci_gart_fini(rdev);
+		radeon_agp_fini(rdev);
+		radeon_irq_kms_fini(rdev);
+		rdev->accel_working = false;
+	}
+	return 0;
+}
 
 /*
  * Debugfs info
diff --git a/drivers/gpu/drm/radeon/r420d.h b/drivers/gpu/drm/radeon/r420d.h
new file mode 100644
index 0000000..a48a7db
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r420d.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef R420D_H
+#define R420D_H
+
+#define R_0001F8_MC_IND_INDEX                        0x0001F8
+#define   S_0001F8_MC_IND_ADDR(x)                      (((x) & 0x7F) << 0)
+#define   G_0001F8_MC_IND_ADDR(x)                      (((x) >> 0) & 0x7F)
+#define   C_0001F8_MC_IND_ADDR                         0xFFFFFF80
+#define   S_0001F8_MC_IND_WR_EN(x)                     (((x) & 0x1) << 8)
+#define   G_0001F8_MC_IND_WR_EN(x)                     (((x) >> 8) & 0x1)
+#define   C_0001F8_MC_IND_WR_EN                        0xFFFFFEFF
+#define R_0001FC_MC_IND_DATA                         0x0001FC
+#define   S_0001FC_MC_IND_DATA(x)                      (((x) & 0xFFFFFFFF) << 0)
+#define   G_0001FC_MC_IND_DATA(x)                      (((x) >> 0) & 0xFFFFFFFF)
+#define   C_0001FC_MC_IND_DATA                         0x00000000
+#define R_0007C0_CP_STAT                             0x0007C0
+#define   S_0007C0_MRU_BUSY(x)                         (((x) & 0x1) << 0)
+#define   G_0007C0_MRU_BUSY(x)                         (((x) >> 0) & 0x1)
+#define   C_0007C0_MRU_BUSY                            0xFFFFFFFE
+#define   S_0007C0_MWU_BUSY(x)                         (((x) & 0x1) << 1)
+#define   G_0007C0_MWU_BUSY(x)                         (((x) >> 1) & 0x1)
+#define   C_0007C0_MWU_BUSY                            0xFFFFFFFD
+#define   S_0007C0_RSIU_BUSY(x)                        (((x) & 0x1) << 2)
+#define   G_0007C0_RSIU_BUSY(x)                        (((x) >> 2) & 0x1)
+#define   C_0007C0_RSIU_BUSY                           0xFFFFFFFB
+#define   S_0007C0_RCIU_BUSY(x)                        (((x) & 0x1) << 3)
+#define   G_0007C0_RCIU_BUSY(x)                        (((x) >> 3) & 0x1)
+#define   C_0007C0_RCIU_BUSY                           0xFFFFFFF7
+#define   S_0007C0_CSF_PRIMARY_BUSY(x)                 (((x) & 0x1) << 9)
+#define   G_0007C0_CSF_PRIMARY_BUSY(x)                 (((x) >> 9) & 0x1)
+#define   C_0007C0_CSF_PRIMARY_BUSY                    0xFFFFFDFF
+#define   S_0007C0_CSF_INDIRECT_BUSY(x)                (((x) & 0x1) << 10)
+#define   G_0007C0_CSF_INDIRECT_BUSY(x)                (((x) >> 10) & 0x1)
+#define   C_0007C0_CSF_INDIRECT_BUSY                   0xFFFFFBFF
+#define   S_0007C0_CSQ_PRIMARY_BUSY(x)                 (((x) & 0x1) << 11)
+#define   G_0007C0_CSQ_PRIMARY_BUSY(x)                 (((x) >> 11) & 0x1)
+#define   C_0007C0_CSQ_PRIMARY_BUSY                    0xFFFFF7FF
+#define   S_0007C0_CSQ_INDIRECT_BUSY(x)                (((x) & 0x1) << 12)
+#define   G_0007C0_CSQ_INDIRECT_BUSY(x)                (((x) >> 12) & 0x1)
+#define   C_0007C0_CSQ_INDIRECT_BUSY                   0xFFFFEFFF
+#define   S_0007C0_CSI_BUSY(x)                         (((x) & 0x1) << 13)
+#define   G_0007C0_CSI_BUSY(x)                         (((x) >> 13) & 0x1)
+#define   C_0007C0_CSI_BUSY                            0xFFFFDFFF
+#define   S_0007C0_CSF_INDIRECT2_BUSY(x)               (((x) & 0x1) << 14)
+#define   G_0007C0_CSF_INDIRECT2_BUSY(x)               (((x) >> 14) & 0x1)
+#define   C_0007C0_CSF_INDIRECT2_BUSY                  0xFFFFBFFF
+#define   S_0007C0_CSQ_INDIRECT2_BUSY(x)               (((x) & 0x1) << 15)
+#define   G_0007C0_CSQ_INDIRECT2_BUSY(x)               (((x) >> 15) & 0x1)
+#define   C_0007C0_CSQ_INDIRECT2_BUSY                  0xFFFF7FFF
+#define   S_0007C0_GUIDMA_BUSY(x)                      (((x) & 0x1) << 28)
+#define   G_0007C0_GUIDMA_BUSY(x)                      (((x) >> 28) & 0x1)
+#define   C_0007C0_GUIDMA_BUSY                         0xEFFFFFFF
+#define   S_0007C0_VIDDMA_BUSY(x)                      (((x) & 0x1) << 29)
+#define   G_0007C0_VIDDMA_BUSY(x)                      (((x) >> 29) & 0x1)
+#define   C_0007C0_VIDDMA_BUSY                         0xDFFFFFFF
+#define   S_0007C0_CMDSTRM_BUSY(x)                     (((x) & 0x1) << 30)
+#define   G_0007C0_CMDSTRM_BUSY(x)                     (((x) >> 30) & 0x1)
+#define   C_0007C0_CMDSTRM_BUSY                        0xBFFFFFFF
+#define   S_0007C0_CP_BUSY(x)                          (((x) & 0x1) << 31)
+#define   G_0007C0_CP_BUSY(x)                          (((x) >> 31) & 0x1)
+#define   C_0007C0_CP_BUSY                             0x7FFFFFFF
+#define R_000E40_RBBM_STATUS                         0x000E40
+#define   S_000E40_CMDFIFO_AVAIL(x)                    (((x) & 0x7F) << 0)
+#define   G_000E40_CMDFIFO_AVAIL(x)                    (((x) >> 0) & 0x7F)
+#define   C_000E40_CMDFIFO_AVAIL                       0xFFFFFF80
+#define   S_000E40_HIRQ_ON_RBB(x)                      (((x) & 0x1) << 8)
+#define   G_000E40_HIRQ_ON_RBB(x)                      (((x) >> 8) & 0x1)
+#define   C_000E40_HIRQ_ON_RBB                         0xFFFFFEFF
+#define   S_000E40_CPRQ_ON_RBB(x)                      (((x) & 0x1) << 9)
+#define   G_000E40_CPRQ_ON_RBB(x)                      (((x) >> 9) & 0x1)
+#define   C_000E40_CPRQ_ON_RBB                         0xFFFFFDFF
+#define   S_000E40_CFRQ_ON_RBB(x)                      (((x) & 0x1) << 10)
+#define   G_000E40_CFRQ_ON_RBB(x)                      (((x) >> 10) & 0x1)
+#define   C_000E40_CFRQ_ON_RBB                         0xFFFFFBFF
+#define   S_000E40_HIRQ_IN_RTBUF(x)                    (((x) & 0x1) << 11)
+#define   G_000E40_HIRQ_IN_RTBUF(x)                    (((x) >> 11) & 0x1)
+#define   C_000E40_HIRQ_IN_RTBUF                       0xFFFFF7FF
+#define   S_000E40_CPRQ_IN_RTBUF(x)                    (((x) & 0x1) << 12)
+#define   G_000E40_CPRQ_IN_RTBUF(x)                    (((x) >> 12) & 0x1)
+#define   C_000E40_CPRQ_IN_RTBUF                       0xFFFFEFFF
+#define   S_000E40_CFRQ_IN_RTBUF(x)                    (((x) & 0x1) << 13)
+#define   G_000E40_CFRQ_IN_RTBUF(x)                    (((x) >> 13) & 0x1)
+#define   C_000E40_CFRQ_IN_RTBUF                       0xFFFFDFFF
+#define   S_000E40_CF_PIPE_BUSY(x)                     (((x) & 0x1) << 14)
+#define   G_000E40_CF_PIPE_BUSY(x)                     (((x) >> 14) & 0x1)
+#define   C_000E40_CF_PIPE_BUSY                        0xFFFFBFFF
+#define   S_000E40_ENG_EV_BUSY(x)                      (((x) & 0x1) << 15)
+#define   G_000E40_ENG_EV_BUSY(x)                      (((x) >> 15) & 0x1)
+#define   C_000E40_ENG_EV_BUSY                         0xFFFF7FFF
+#define   S_000E40_CP_CMDSTRM_BUSY(x)                  (((x) & 0x1) << 16)
+#define   G_000E40_CP_CMDSTRM_BUSY(x)                  (((x) >> 16) & 0x1)
+#define   C_000E40_CP_CMDSTRM_BUSY                     0xFFFEFFFF
+#define   S_000E40_E2_BUSY(x)                          (((x) & 0x1) << 17)
+#define   G_000E40_E2_BUSY(x)                          (((x) >> 17) & 0x1)
+#define   C_000E40_E2_BUSY                             0xFFFDFFFF
+#define   S_000E40_RB2D_BUSY(x)                        (((x) & 0x1) << 18)
+#define   G_000E40_RB2D_BUSY(x)                        (((x) >> 18) & 0x1)
+#define   C_000E40_RB2D_BUSY                           0xFFFBFFFF
+#define   S_000E40_RB3D_BUSY(x)                        (((x) & 0x1) << 19)
+#define   G_000E40_RB3D_BUSY(x)                        (((x) >> 19) & 0x1)
+#define   C_000E40_RB3D_BUSY                           0xFFF7FFFF
+#define   S_000E40_VAP_BUSY(x)                         (((x) & 0x1) << 20)
+#define   G_000E40_VAP_BUSY(x)                         (((x) >> 20) & 0x1)
+#define   C_000E40_VAP_BUSY                            0xFFEFFFFF
+#define   S_000E40_RE_BUSY(x)                          (((x) & 0x1) << 21)
+#define   G_000E40_RE_BUSY(x)                          (((x) >> 21) & 0x1)
+#define   C_000E40_RE_BUSY                             0xFFDFFFFF
+#define   S_000E40_TAM_BUSY(x)                         (((x) & 0x1) << 22)
+#define   G_000E40_TAM_BUSY(x)                         (((x) >> 22) & 0x1)
+#define   C_000E40_TAM_BUSY                            0xFFBFFFFF
+#define   S_000E40_TDM_BUSY(x)                         (((x) & 0x1) << 23)
+#define   G_000E40_TDM_BUSY(x)                         (((x) >> 23) & 0x1)
+#define   C_000E40_TDM_BUSY                            0xFF7FFFFF
+#define   S_000E40_PB_BUSY(x)                          (((x) & 0x1) << 24)
+#define   G_000E40_PB_BUSY(x)                          (((x) >> 24) & 0x1)
+#define   C_000E40_PB_BUSY                             0xFEFFFFFF
+#define   S_000E40_TIM_BUSY(x)                         (((x) & 0x1) << 25)
+#define   G_000E40_TIM_BUSY(x)                         (((x) >> 25) & 0x1)
+#define   C_000E40_TIM_BUSY                            0xFDFFFFFF
+#define   S_000E40_GA_BUSY(x)                          (((x) & 0x1) << 26)
+#define   G_000E40_GA_BUSY(x)                          (((x) >> 26) & 0x1)
+#define   C_000E40_GA_BUSY                             0xFBFFFFFF
+#define   S_000E40_CBA2D_BUSY(x)                       (((x) & 0x1) << 27)
+#define   G_000E40_CBA2D_BUSY(x)                       (((x) >> 27) & 0x1)
+#define   C_000E40_CBA2D_BUSY                          0xF7FFFFFF
+#define   S_000E40_GUI_ACTIVE(x)                       (((x) & 0x1) << 31)
+#define   G_000E40_GUI_ACTIVE(x)                       (((x) >> 31) & 0x1)
+#define   C_000E40_GUI_ACTIVE                          0x7FFFFFFF
+
+/* CLK registers */
+#define R_00000D_SCLK_CNTL                           0x00000D
+#define   S_00000D_SCLK_SRC_SEL(x)                     (((x) & 0x7) << 0)
+#define   G_00000D_SCLK_SRC_SEL(x)                     (((x) >> 0) & 0x7)
+#define   C_00000D_SCLK_SRC_SEL                        0xFFFFFFF8
+#define   S_00000D_CP_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 3)
+#define   G_00000D_CP_MAX_DYN_STOP_LAT(x)              (((x) >> 3) & 0x1)
+#define   C_00000D_CP_MAX_DYN_STOP_LAT                 0xFFFFFFF7
+#define   S_00000D_HDP_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 4)
+#define   G_00000D_HDP_MAX_DYN_STOP_LAT(x)             (((x) >> 4) & 0x1)
+#define   C_00000D_HDP_MAX_DYN_STOP_LAT                0xFFFFFFEF
+#define   S_00000D_TV_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 5)
+#define   G_00000D_TV_MAX_DYN_STOP_LAT(x)              (((x) >> 5) & 0x1)
+#define   C_00000D_TV_MAX_DYN_STOP_LAT                 0xFFFFFFDF
+#define   S_00000D_E2_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 6)
+#define   G_00000D_E2_MAX_DYN_STOP_LAT(x)              (((x) >> 6) & 0x1)
+#define   C_00000D_E2_MAX_DYN_STOP_LAT                 0xFFFFFFBF
+#define   S_00000D_SE_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 7)
+#define   G_00000D_SE_MAX_DYN_STOP_LAT(x)              (((x) >> 7) & 0x1)
+#define   C_00000D_SE_MAX_DYN_STOP_LAT                 0xFFFFFF7F
+#define   S_00000D_IDCT_MAX_DYN_STOP_LAT(x)            (((x) & 0x1) << 8)
+#define   G_00000D_IDCT_MAX_DYN_STOP_LAT(x)            (((x) >> 8) & 0x1)
+#define   C_00000D_IDCT_MAX_DYN_STOP_LAT               0xFFFFFEFF
+#define   S_00000D_VIP_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 9)
+#define   G_00000D_VIP_MAX_DYN_STOP_LAT(x)             (((x) >> 9) & 0x1)
+#define   C_00000D_VIP_MAX_DYN_STOP_LAT                0xFFFFFDFF
+#define   S_00000D_RE_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 10)
+#define   G_00000D_RE_MAX_DYN_STOP_LAT(x)              (((x) >> 10) & 0x1)
+#define   C_00000D_RE_MAX_DYN_STOP_LAT                 0xFFFFFBFF
+#define   S_00000D_PB_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 11)
+#define   G_00000D_PB_MAX_DYN_STOP_LAT(x)              (((x) >> 11) & 0x1)
+#define   C_00000D_PB_MAX_DYN_STOP_LAT                 0xFFFFF7FF
+#define   S_00000D_TAM_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 12)
+#define   G_00000D_TAM_MAX_DYN_STOP_LAT(x)             (((x) >> 12) & 0x1)
+#define   C_00000D_TAM_MAX_DYN_STOP_LAT                0xFFFFEFFF
+#define   S_00000D_TDM_MAX_DYN_STOP_LAT(x)             (((x) & 0x1) << 13)
+#define   G_00000D_TDM_MAX_DYN_STOP_LAT(x)             (((x) >> 13) & 0x1)
+#define   C_00000D_TDM_MAX_DYN_STOP_LAT                0xFFFFDFFF
+#define   S_00000D_RB_MAX_DYN_STOP_LAT(x)              (((x) & 0x1) << 14)
+#define   G_00000D_RB_MAX_DYN_STOP_LAT(x)              (((x) >> 14) & 0x1)
+#define   C_00000D_RB_MAX_DYN_STOP_LAT                 0xFFFFBFFF
+#define   S_00000D_FORCE_DISP2(x)                      (((x) & 0x1) << 15)
+#define   G_00000D_FORCE_DISP2(x)                      (((x) >> 15) & 0x1)
+#define   C_00000D_FORCE_DISP2                         0xFFFF7FFF
+#define   S_00000D_FORCE_CP(x)                         (((x) & 0x1) << 16)
+#define   G_00000D_FORCE_CP(x)                         (((x) >> 16) & 0x1)
+#define   C_00000D_FORCE_CP                            0xFFFEFFFF
+#define   S_00000D_FORCE_HDP(x)                        (((x) & 0x1) << 17)
+#define   G_00000D_FORCE_HDP(x)                        (((x) >> 17) & 0x1)
+#define   C_00000D_FORCE_HDP                           0xFFFDFFFF
+#define   S_00000D_FORCE_DISP1(x)                      (((x) & 0x1) << 18)
+#define   G_00000D_FORCE_DISP1(x)                      (((x) >> 18) & 0x1)
+#define   C_00000D_FORCE_DISP1                         0xFFFBFFFF
+#define   S_00000D_FORCE_TOP(x)                        (((x) & 0x1) << 19)
+#define   G_00000D_FORCE_TOP(x)                        (((x) >> 19) & 0x1)
+#define   C_00000D_FORCE_TOP                           0xFFF7FFFF
+#define   S_00000D_FORCE_E2(x)                         (((x) & 0x1) << 20)
+#define   G_00000D_FORCE_E2(x)                         (((x) >> 20) & 0x1)
+#define   C_00000D_FORCE_E2                            0xFFEFFFFF
+#define   S_00000D_FORCE_SE(x)                         (((x) & 0x1) << 21)
+#define   G_00000D_FORCE_SE(x)                         (((x) >> 21) & 0x1)
+#define   C_00000D_FORCE_SE                            0xFFDFFFFF
+#define   S_00000D_FORCE_IDCT(x)                       (((x) & 0x1) << 22)
+#define   G_00000D_FORCE_IDCT(x)                       (((x) >> 22) & 0x1)
+#define   C_00000D_FORCE_IDCT                          0xFFBFFFFF
+#define   S_00000D_FORCE_VIP(x)                        (((x) & 0x1) << 23)
+#define   G_00000D_FORCE_VIP(x)                        (((x) >> 23) & 0x1)
+#define   C_00000D_FORCE_VIP                           0xFF7FFFFF
+#define   S_00000D_FORCE_RE(x)                         (((x) & 0x1) << 24)
+#define   G_00000D_FORCE_RE(x)                         (((x) >> 24) & 0x1)
+#define   C_00000D_FORCE_RE                            0xFEFFFFFF
+#define   S_00000D_FORCE_PB(x)                         (((x) & 0x1) << 25)
+#define   G_00000D_FORCE_PB(x)                         (((x) >> 25) & 0x1)
+#define   C_00000D_FORCE_PB                            0xFDFFFFFF
+#define   S_00000D_FORCE_PX(x)                         (((x) & 0x1) << 26)
+#define   G_00000D_FORCE_PX(x)                         (((x) >> 26) & 0x1)
+#define   C_00000D_FORCE_PX                            0xFBFFFFFF
+#define   S_00000D_FORCE_TX(x)                         (((x) & 0x1) << 27)
+#define   G_00000D_FORCE_TX(x)                         (((x) >> 27) & 0x1)
+#define   C_00000D_FORCE_TX                            0xF7FFFFFF
+#define   S_00000D_FORCE_RB(x)                         (((x) & 0x1) << 28)
+#define   G_00000D_FORCE_RB(x)                         (((x) >> 28) & 0x1)
+#define   C_00000D_FORCE_RB                            0xEFFFFFFF
+#define   S_00000D_FORCE_TV_SCLK(x)                    (((x) & 0x1) << 29)
+#define   G_00000D_FORCE_TV_SCLK(x)                    (((x) >> 29) & 0x1)
+#define   C_00000D_FORCE_TV_SCLK                       0xDFFFFFFF
+#define   S_00000D_FORCE_SUBPIC(x)                     (((x) & 0x1) << 30)
+#define   G_00000D_FORCE_SUBPIC(x)                     (((x) >> 30) & 0x1)
+#define   C_00000D_FORCE_SUBPIC                        0xBFFFFFFF
+#define   S_00000D_FORCE_OV0(x)                        (((x) & 0x1) << 31)
+#define   G_00000D_FORCE_OV0(x)                        (((x) >> 31) & 0x1)
+#define   C_00000D_FORCE_OV0                           0x7FFFFFFF
+
+#endif
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index ebd6b0f..d4b0b9d 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -28,12 +28,9 @@
 #include "drmP.h"
 #include "radeon_reg.h"
 #include "radeon.h"
-#include "radeon_share.h"
 
 /* r520,rv530,rv560,rv570,r580 depends on : */
 void r100_hdp_reset(struct radeon_device *rdev);
-int rv370_pcie_gart_enable(struct radeon_device *rdev);
-void rv370_pcie_gart_disable(struct radeon_device *rdev);
 void r420_pipes_init(struct radeon_device *rdev);
 void rs600_mc_disable_clients(struct radeon_device *rdev);
 void rs600_disable_vga(struct radeon_device *rdev);
@@ -119,9 +116,6 @@ int r520_mc_init(struct radeon_device *rdev)
 
 void r520_mc_fini(struct radeon_device *rdev)
 {
-	rv370_pcie_gart_disable(rdev);
-	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 538cd90..eab31c1 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -25,12 +25,45 @@
  *          Alex Deucher
  *          Jerome Glisse
  */
+#include <linux/seq_file.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
 #include "drmP.h"
-#include "radeon_reg.h"
+#include "radeon_drm.h"
 #include "radeon.h"
+#include "radeon_mode.h"
+#include "r600d.h"
+#include "avivod.h"
+#include "atom.h"
 
-/* r600,rv610,rv630,rv620,rv635,rv670 depends on : */
-void rs600_mc_disable_clients(struct radeon_device *rdev);
+#define PFP_UCODE_SIZE 576
+#define PM4_UCODE_SIZE 1792
+#define R700_PFP_UCODE_SIZE 848
+#define R700_PM4_UCODE_SIZE 1360
+
+/* Firmware Names */
+MODULE_FIRMWARE("radeon/R600_pfp.bin");
+MODULE_FIRMWARE("radeon/R600_me.bin");
+MODULE_FIRMWARE("radeon/RV610_pfp.bin");
+MODULE_FIRMWARE("radeon/RV610_me.bin");
+MODULE_FIRMWARE("radeon/RV630_pfp.bin");
+MODULE_FIRMWARE("radeon/RV630_me.bin");
+MODULE_FIRMWARE("radeon/RV620_pfp.bin");
+MODULE_FIRMWARE("radeon/RV620_me.bin");
+MODULE_FIRMWARE("radeon/RV635_pfp.bin");
+MODULE_FIRMWARE("radeon/RV635_me.bin");
+MODULE_FIRMWARE("radeon/RV670_pfp.bin");
+MODULE_FIRMWARE("radeon/RV670_me.bin");
+MODULE_FIRMWARE("radeon/RS780_pfp.bin");
+MODULE_FIRMWARE("radeon/RS780_me.bin");
+MODULE_FIRMWARE("radeon/RV770_pfp.bin");
+MODULE_FIRMWARE("radeon/RV770_me.bin");
+MODULE_FIRMWARE("radeon/RV730_pfp.bin");
+MODULE_FIRMWARE("radeon/RV730_me.bin");
+MODULE_FIRMWARE("radeon/RV710_pfp.bin");
+MODULE_FIRMWARE("radeon/RV710_me.bin");
+
+int r600_debugfs_mc_info_init(struct radeon_device *rdev);
 
 /* This files gather functions specifics to:
  * r600,rv610,rv630,rv620,rv635,rv670
@@ -39,87 +72,293 @@ void rs600_mc_disable_clients(struct radeon_device *rdev);
  */
 int r600_mc_wait_for_idle(struct radeon_device *rdev);
 void r600_gpu_init(struct radeon_device *rdev);
+void r600_fini(struct radeon_device *rdev);
 
 
 /*
- * MC
+ * R600 PCIE GART
  */
-int r600_mc_init(struct radeon_device *rdev)
+int r600_gart_clear_page(struct radeon_device *rdev, int i)
 {
-	uint32_t tmp;
+	void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
+	u64 pte;
 
-	r600_gpu_init(rdev);
+	if (i < 0 || i > rdev->gart.num_gpu_pages)
+		return -EINVAL;
+	pte = 0;
+	writeq(pte, ((void __iomem *)ptr) + (i * 8));
+	return 0;
+}
 
-	/* setup the gart before changing location so we can ask to
-	 * discard unmapped mc request
-	 */
-	/* FIXME: disable out of gart access */
-	tmp = rdev->mc.gtt_location / 4096;
-	tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp);
-	WREG32(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp);
-	tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096;
-	tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp);
-	WREG32(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp);
-
-	rs600_mc_disable_clients(rdev);
-	if (r600_mc_wait_for_idle(rdev)) {
-		printk(KERN_WARNING "Failed to wait MC idle while "
-		       "programming pipes. Bad things might happen.\n");
+void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
+{
+	unsigned i;
+	u32 tmp;
+
+	WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12);
+	WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12);
+	WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		/* read MC_STATUS */
+		tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE);
+		tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT;
+		if (tmp == 2) {
+			printk(KERN_WARNING "[drm] r600 flush TLB failed\n");
+			return;
+		}
+		if (tmp) {
+			return;
+		}
+		udelay(1);
 	}
+}
 
-	tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-	tmp = REG_SET(R600_MC_FB_TOP, tmp >> 24);
-	tmp |= REG_SET(R600_MC_FB_BASE, rdev->mc.vram_location >> 24);
-	WREG32(R600_MC_VM_FB_LOCATION, tmp);
-	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-	tmp = REG_SET(R600_MC_AGP_TOP, tmp >> 22);
-	WREG32(R600_MC_VM_AGP_TOP, tmp);
-	tmp = REG_SET(R600_MC_AGP_BOT, rdev->mc.gtt_location >> 22);
-	WREG32(R600_MC_VM_AGP_BOT, tmp);
-	return 0;
+int r600_pcie_gart_init(struct radeon_device *rdev)
+{
+	int r;
+
+	if (rdev->gart.table.vram.robj) {
+		WARN(1, "R600 PCIE GART already initialized.\n");
+		return 0;
+	}
+	/* Initialize common gart structure */
+	r = radeon_gart_init(rdev);
+	if (r)
+		return r;
+	rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
+	return radeon_gart_table_vram_alloc(rdev);
 }
 
-void r600_mc_fini(struct radeon_device *rdev)
+int r600_pcie_gart_enable(struct radeon_device *rdev)
 {
-	/* FIXME: implement */
+	u32 tmp;
+	int r, i;
+
+	if (rdev->gart.table.vram.robj == NULL) {
+		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
+		return -EINVAL;
+	}
+	r = radeon_gart_table_vram_pin(rdev);
+	if (r)
+		return r;
+
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+				EFFECTIVE_L2_QUEUE_SIZE(7));
+	WREG32(VM_L2_CNTL2, 0);
+	WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
+	/* Setup TLB control */
+	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
+		ENABLE_WAIT_L2_QUERY;
+	WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
+	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+	WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
+	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
+				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
+	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
+			(u32)(rdev->dummy_page.addr >> 12));
+	for (i = 1; i < 7; i++)
+		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+
+	r600_pcie_gart_tlb_flush(rdev);
+	rdev->gart.ready = true;
+	return 0;
 }
 
+void r600_pcie_gart_disable(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int i;
 
-/*
- * Global GPU functions
- */
-void r600_errata(struct radeon_device *rdev)
+	/* Disable all tables */
+	for (i = 0; i < 7; i++)
+		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+
+	/* Disable L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
+				EFFECTIVE_L2_QUEUE_SIZE(7));
+	WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
+	/* Setup L1 TLB control */
+	tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
+		ENABLE_WAIT_L2_QUERY;
+	WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
+	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
+	if (rdev->gart.table.vram.robj) {
+		radeon_object_kunmap(rdev->gart.table.vram.robj);
+		radeon_object_unpin(rdev->gart.table.vram.robj);
+	}
+}
+
+void r600_pcie_gart_fini(struct radeon_device *rdev)
 {
-	rdev->pll_errata = 0;
+	r600_pcie_gart_disable(rdev);
+	radeon_gart_table_vram_free(rdev);
+	radeon_gart_fini(rdev);
 }
 
 int r600_mc_wait_for_idle(struct radeon_device *rdev)
 {
-	/* FIXME: implement */
-	return 0;
+	unsigned i;
+	u32 tmp;
+
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		/* read MC_STATUS */
+		tmp = RREG32(R_000E50_SRBM_STATUS) & 0x3F00;
+		if (!tmp)
+			return 0;
+		udelay(1);
+	}
+	return -1;
 }
 
-void r600_gpu_init(struct radeon_device *rdev)
+static void r600_mc_resume(struct radeon_device *rdev)
 {
-	/* FIXME: implement */
-}
+	u32 d1vga_control, d2vga_control;
+	u32 vga_render_control, vga_hdp_control;
+	u32 d1crtc_control, d2crtc_control;
+	u32 new_d1grph_primary, new_d1grph_secondary;
+	u32 new_d2grph_primary, new_d2grph_secondary;
+	u64 old_vram_start;
+	u32 tmp;
+	int i, j;
 
+	/* Initialize HDP */
+	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
+		WREG32((0x2c14 + j), 0x00000000);
+		WREG32((0x2c18 + j), 0x00000000);
+		WREG32((0x2c1c + j), 0x00000000);
+		WREG32((0x2c20 + j), 0x00000000);
+		WREG32((0x2c24 + j), 0x00000000);
+	}
+	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
 
-/*
- * VRAM info
- */
-void r600_vram_get_type(struct radeon_device *rdev)
+	d1vga_control = RREG32(D1VGA_CONTROL);
+	d2vga_control = RREG32(D2VGA_CONTROL);
+	vga_render_control = RREG32(VGA_RENDER_CONTROL);
+	vga_hdp_control = RREG32(VGA_HDP_CONTROL);
+	d1crtc_control = RREG32(D1CRTC_CONTROL);
+	d2crtc_control = RREG32(D2CRTC_CONTROL);
+	old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
+	new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
+	new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
+	new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
+	new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
+	new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
+	new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
+	new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
+	new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
+
+	/* Stop all video */
+	WREG32(D1VGA_CONTROL, 0);
+	WREG32(D2VGA_CONTROL, 0);
+	WREG32(VGA_RENDER_CONTROL, 0);
+	WREG32(D1CRTC_UPDATE_LOCK, 1);
+	WREG32(D2CRTC_UPDATE_LOCK, 1);
+	WREG32(D1CRTC_CONTROL, 0);
+	WREG32(D2CRTC_CONTROL, 0);
+	WREG32(D1CRTC_UPDATE_LOCK, 0);
+	WREG32(D2CRTC_UPDATE_LOCK, 0);
+
+	mdelay(1);
+	if (r600_mc_wait_for_idle(rdev)) {
+		printk(KERN_WARNING "[drm] MC not idle !\n");
+	}
+
+	/* Lockout access through VGA aperture*/
+	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
+
+	/* Update configuration */
+	WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
+	WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
+	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+	tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
+	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
+	WREG32(MC_VM_FB_LOCATION, tmp);
+	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
+	WREG32(HDP_NONSURFACE_INFO, (2 << 7));
+	WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
+	if (rdev->flags & RADEON_IS_AGP) {
+		WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
+		WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
+		WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
+	} else {
+		WREG32(MC_VM_AGP_BASE, 0);
+		WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
+		WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
+	}
+	WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
+	WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
+	WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
+	WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
+	WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
+
+	/* Unlock host access */
+	WREG32(VGA_HDP_CONTROL, vga_hdp_control);
+
+	mdelay(1);
+	if (r600_mc_wait_for_idle(rdev)) {
+		printk(KERN_WARNING "[drm] MC not idle !\n");
+	}
+
+	/* Restore video state */
+	WREG32(D1CRTC_UPDATE_LOCK, 1);
+	WREG32(D2CRTC_UPDATE_LOCK, 1);
+	WREG32(D1CRTC_CONTROL, d1crtc_control);
+	WREG32(D2CRTC_CONTROL, d2crtc_control);
+	WREG32(D1CRTC_UPDATE_LOCK, 0);
+	WREG32(D2CRTC_UPDATE_LOCK, 0);
+	WREG32(D1VGA_CONTROL, d1vga_control);
+	WREG32(D2VGA_CONTROL, d2vga_control);
+	WREG32(VGA_RENDER_CONTROL, vga_render_control);
+
+	/* we need to own VRAM, so turn off the VGA renderer here
+	 * to stop it overwriting our objects */
+	radeon_avivo_vga_render_disable(rdev);
+}
+
+int r600_mc_init(struct radeon_device *rdev)
 {
-	uint32_t tmp;
+	fixed20_12 a;
+	u32 tmp;
 	int chansize;
+	int r;
 
+	/* Get VRAM informations */
 	rdev->mc.vram_width = 128;
 	rdev->mc.vram_is_ddr = true;
-
-	tmp = RREG32(R600_RAMCFG);
-	if (tmp & R600_CHANSIZE_OVERRIDE) {
+	tmp = RREG32(RAMCFG);
+	if (tmp & CHANSIZE_OVERRIDE) {
 		chansize = 16;
-	} else if (tmp & R600_CHANSIZE) {
+	} else if (tmp & CHANSIZE_MASK) {
 		chansize = 64;
 	} else {
 		chansize = 32;
@@ -135,36 +374,1459 @@ void r600_vram_get_type(struct radeon_device *rdev)
 			(rdev->family == CHIP_RV635)) {
 		rdev->mc.vram_width = 2 * chansize;
 	}
+	/* Could aper size report 0 ? */
+	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
+	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+	/* Setup GPU memory space */
+	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
+	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r)
+			return r;
+		/* gtt_size is setup by radeon_agp_init */
+		rdev->mc.gtt_location = rdev->mc.agp_base;
+		tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
+		/* Try to put vram before or after AGP because we
+		 * we want SYSTEM_APERTURE to cover both VRAM and
+		 * AGP so that GPU can catch out of VRAM/AGP access
+		 */
+		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
+			/* Enought place before */
+			rdev->mc.vram_location = rdev->mc.gtt_location -
+							rdev->mc.mc_vram_size;
+		} else if (tmp > rdev->mc.mc_vram_size) {
+			/* Enought place after */
+			rdev->mc.vram_location = rdev->mc.gtt_location +
+							rdev->mc.gtt_size;
+		} else {
+			/* Try to setup VRAM then AGP might not
+			 * not work on some card
+			 */
+			rdev->mc.vram_location = 0x00000000UL;
+			rdev->mc.gtt_location = rdev->mc.mc_vram_size;
+		}
+	} else {
+		if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
+			rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
+								0xFFFF) << 24;
+			rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+			tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+			if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
+				/* Enough place after vram */
+				rdev->mc.gtt_location = tmp;
+			} else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
+				/* Enough place before vram */
+				rdev->mc.gtt_location = 0;
+			} else {
+				/* Not enough place after or before shrink
+				 * gart size
+				 */
+				if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
+					rdev->mc.gtt_location = 0;
+					rdev->mc.gtt_size = rdev->mc.vram_location;
+				} else {
+					rdev->mc.gtt_location = tmp;
+					rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
+				}
+			}
+			rdev->mc.gtt_location = rdev->mc.mc_vram_size;
+		} else {
+			rdev->mc.vram_location = 0x00000000UL;
+			rdev->mc.gtt_location = rdev->mc.mc_vram_size;
+			rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+		}
+	}
+	rdev->mc.vram_start = rdev->mc.vram_location;
+	rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+	rdev->mc.gtt_start = rdev->mc.gtt_location;
+	rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
+	/* FIXME: we should enforce default clock in case GPU is not in
+	 * default setup
+	 */
+	a.full = rfixed_const(100);
+	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
+	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+	return 0;
 }
 
-void r600_vram_info(struct radeon_device *rdev)
+/* We doesn't check that the GPU really needs a reset we simply do the
+ * reset, it's up to the caller to determine if the GPU needs one. We
+ * might add an helper function to check that.
+ */
+int r600_gpu_soft_reset(struct radeon_device *rdev)
 {
-	r600_vram_get_type(rdev);
-	rdev->mc.real_vram_size = RREG32(R600_CONFIG_MEMSIZE);
-	rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
+	u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
+				S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
+				S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
+				S_008010_SH_BUSY(1) | S_008010_SPI03_BUSY(1) |
+				S_008010_SMX_BUSY(1) | S_008010_SC_BUSY(1) |
+				S_008010_PA_BUSY(1) | S_008010_DB03_BUSY(1) |
+				S_008010_CR_BUSY(1) | S_008010_CB03_BUSY(1) |
+				S_008010_GUI_ACTIVE(1);
+	u32 grbm2_busy_mask = S_008014_SPI0_BUSY(1) | S_008014_SPI1_BUSY(1) |
+			S_008014_SPI2_BUSY(1) | S_008014_SPI3_BUSY(1) |
+			S_008014_TA0_BUSY(1) | S_008014_TA1_BUSY(1) |
+			S_008014_TA2_BUSY(1) | S_008014_TA3_BUSY(1) |
+			S_008014_DB0_BUSY(1) | S_008014_DB1_BUSY(1) |
+			S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) |
+			S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
+			S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
+	u32 srbm_reset = 0;
 
-	/* Could aper size report 0 ? */
-	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+	/* Disable CP parsing/prefetching */
+	WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
+	/* Check if any of the rendering block is busy and reset it */
+	if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
+	    (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
+		WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) |
+			S_008020_SOFT_RESET_DB(1) |
+			S_008020_SOFT_RESET_CB(1) |
+			S_008020_SOFT_RESET_PA(1) |
+			S_008020_SOFT_RESET_SC(1) |
+			S_008020_SOFT_RESET_SMX(1) |
+			S_008020_SOFT_RESET_SPI(1) |
+			S_008020_SOFT_RESET_SX(1) |
+			S_008020_SOFT_RESET_SH(1) |
+			S_008020_SOFT_RESET_TC(1) |
+			S_008020_SOFT_RESET_TA(1) |
+			S_008020_SOFT_RESET_VC(1) |
+			S_008020_SOFT_RESET_VGT(1));
+		(void)RREG32(R_008020_GRBM_SOFT_RESET);
+		udelay(50);
+		WREG32(R_008020_GRBM_SOFT_RESET, 0);
+		(void)RREG32(R_008020_GRBM_SOFT_RESET);
+	}
+	/* Reset CP (we always reset CP) */
+	WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1));
+	(void)RREG32(R_008020_GRBM_SOFT_RESET);
+	udelay(50);
+	WREG32(R_008020_GRBM_SOFT_RESET, 0);
+	(void)RREG32(R_008020_GRBM_SOFT_RESET);
+	/* Reset others GPU block if necessary */
+	if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
+	if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_GRBM(1);
+	if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_IH(1);
+	if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_VMC(1);
+	if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_MC(1);
+	if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_MC(1);
+	if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_MC(1);
+	if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_MC(1);
+	if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_MC(1);
+	if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
+	if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
+		srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
+	WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
+	(void)RREG32(R_000E60_SRBM_SOFT_RESET);
+	udelay(50);
+	WREG32(R_000E60_SRBM_SOFT_RESET, 0);
+	(void)RREG32(R_000E60_SRBM_SOFT_RESET);
+	/* Wait a little for things to settle down */
+	udelay(50);
+	return 0;
 }
 
+int r600_gpu_reset(struct radeon_device *rdev)
+{
+	return r600_gpu_soft_reset(rdev);
+}
+
+static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+					     u32 num_backends,
+					     u32 backend_disable_mask)
+{
+	u32 backend_map = 0;
+	u32 enabled_backends_mask;
+	u32 enabled_backends_count;
+	u32 cur_pipe;
+	u32 swizzle_pipe[R6XX_MAX_PIPES];
+	u32 cur_backend;
+	u32 i;
+
+	if (num_tile_pipes > R6XX_MAX_PIPES)
+		num_tile_pipes = R6XX_MAX_PIPES;
+	if (num_tile_pipes < 1)
+		num_tile_pipes = 1;
+	if (num_backends > R6XX_MAX_BACKENDS)
+		num_backends = R6XX_MAX_BACKENDS;
+	if (num_backends < 1)
+		num_backends = 1;
+
+	enabled_backends_mask = 0;
+	enabled_backends_count = 0;
+	for (i = 0; i < R6XX_MAX_BACKENDS; ++i) {
+		if (((backend_disable_mask >> i) & 1) == 0) {
+			enabled_backends_mask |= (1 << i);
+			++enabled_backends_count;
+		}
+		if (enabled_backends_count == num_backends)
+			break;
+	}
+
+	if (enabled_backends_count == 0) {
+		enabled_backends_mask = 1;
+		enabled_backends_count = 1;
+	}
+
+	if (enabled_backends_count != num_backends)
+		num_backends = enabled_backends_count;
+
+	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES);
+	switch (num_tile_pipes) {
+	case 1:
+		swizzle_pipe[0] = 0;
+		break;
+	case 2:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		break;
+	case 3:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		break;
+	case 4:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		swizzle_pipe[3] = 3;
+		break;
+	case 5:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		swizzle_pipe[2] = 2;
+		swizzle_pipe[3] = 3;
+		swizzle_pipe[4] = 4;
+		break;
+	case 6:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 5;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		break;
+	case 7:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		swizzle_pipe[6] = 5;
+		break;
+	case 8:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 1;
+		swizzle_pipe[5] = 3;
+		swizzle_pipe[6] = 5;
+		swizzle_pipe[7] = 7;
+		break;
+	}
+
+	cur_backend = 0;
+	for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+		while (((1 << cur_backend) & enabled_backends_mask) == 0)
+			cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+
+		backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+		cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+	}
+
+	return backend_map;
+}
+
+int r600_count_pipe_bits(uint32_t val)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < 32; i++) {
+		ret += val & 1;
+		val >>= 1;
+	}
+	return ret;
+}
+
+void r600_gpu_init(struct radeon_device *rdev)
+{
+	u32 tiling_config;
+	u32 ramcfg;
+	u32 tmp;
+	int i, j;
+	u32 sq_config;
+	u32 sq_gpr_resource_mgmt_1 = 0;
+	u32 sq_gpr_resource_mgmt_2 = 0;
+	u32 sq_thread_resource_mgmt = 0;
+	u32 sq_stack_resource_mgmt_1 = 0;
+	u32 sq_stack_resource_mgmt_2 = 0;
+
+	/* FIXME: implement */
+	switch (rdev->family) {
+	case CHIP_R600:
+		rdev->config.r600.max_pipes = 4;
+		rdev->config.r600.max_tile_pipes = 8;
+		rdev->config.r600.max_simds = 4;
+		rdev->config.r600.max_backends = 4;
+		rdev->config.r600.max_gprs = 256;
+		rdev->config.r600.max_threads = 192;
+		rdev->config.r600.max_stack_entries = 256;
+		rdev->config.r600.max_hw_contexts = 8;
+		rdev->config.r600.max_gs_threads = 16;
+		rdev->config.r600.sx_max_export_size = 128;
+		rdev->config.r600.sx_max_export_pos_size = 16;
+		rdev->config.r600.sx_max_export_smx_size = 128;
+		rdev->config.r600.sq_num_cf_insts = 2;
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		rdev->config.r600.max_pipes = 2;
+		rdev->config.r600.max_tile_pipes = 2;
+		rdev->config.r600.max_simds = 3;
+		rdev->config.r600.max_backends = 1;
+		rdev->config.r600.max_gprs = 128;
+		rdev->config.r600.max_threads = 192;
+		rdev->config.r600.max_stack_entries = 128;
+		rdev->config.r600.max_hw_contexts = 8;
+		rdev->config.r600.max_gs_threads = 4;
+		rdev->config.r600.sx_max_export_size = 128;
+		rdev->config.r600.sx_max_export_pos_size = 16;
+		rdev->config.r600.sx_max_export_smx_size = 128;
+		rdev->config.r600.sq_num_cf_insts = 2;
+		break;
+	case CHIP_RV610:
+	case CHIP_RV620:
+	case CHIP_RS780:
+	case CHIP_RS880:
+		rdev->config.r600.max_pipes = 1;
+		rdev->config.r600.max_tile_pipes = 1;
+		rdev->config.r600.max_simds = 2;
+		rdev->config.r600.max_backends = 1;
+		rdev->config.r600.max_gprs = 128;
+		rdev->config.r600.max_threads = 192;
+		rdev->config.r600.max_stack_entries = 128;
+		rdev->config.r600.max_hw_contexts = 4;
+		rdev->config.r600.max_gs_threads = 4;
+		rdev->config.r600.sx_max_export_size = 128;
+		rdev->config.r600.sx_max_export_pos_size = 16;
+		rdev->config.r600.sx_max_export_smx_size = 128;
+		rdev->config.r600.sq_num_cf_insts = 1;
+		break;
+	case CHIP_RV670:
+		rdev->config.r600.max_pipes = 4;
+		rdev->config.r600.max_tile_pipes = 4;
+		rdev->config.r600.max_simds = 4;
+		rdev->config.r600.max_backends = 4;
+		rdev->config.r600.max_gprs = 192;
+		rdev->config.r600.max_threads = 192;
+		rdev->config.r600.max_stack_entries = 256;
+		rdev->config.r600.max_hw_contexts = 8;
+		rdev->config.r600.max_gs_threads = 16;
+		rdev->config.r600.sx_max_export_size = 128;
+		rdev->config.r600.sx_max_export_pos_size = 16;
+		rdev->config.r600.sx_max_export_smx_size = 128;
+		rdev->config.r600.sq_num_cf_insts = 2;
+		break;
+	default:
+		break;
+	}
+
+	/* Initialize HDP */
+	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
+		WREG32((0x2c14 + j), 0x00000000);
+		WREG32((0x2c18 + j), 0x00000000);
+		WREG32((0x2c1c + j), 0x00000000);
+		WREG32((0x2c20 + j), 0x00000000);
+		WREG32((0x2c24 + j), 0x00000000);
+	}
+
+	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+
+	/* Setup tiling */
+	tiling_config = 0;
+	ramcfg = RREG32(RAMCFG);
+	switch (rdev->config.r600.max_tile_pipes) {
+	case 1:
+		tiling_config |= PIPE_TILING(0);
+		break;
+	case 2:
+		tiling_config |= PIPE_TILING(1);
+		break;
+	case 4:
+		tiling_config |= PIPE_TILING(2);
+		break;
+	case 8:
+		tiling_config |= PIPE_TILING(3);
+		break;
+	default:
+		break;
+	}
+	tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
+	tiling_config |= GROUP_SIZE(0);
+	tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
+	if (tmp > 3) {
+		tiling_config |= ROW_TILING(3);
+		tiling_config |= SAMPLE_SPLIT(3);
+	} else {
+		tiling_config |= ROW_TILING(tmp);
+		tiling_config |= SAMPLE_SPLIT(tmp);
+	}
+	tiling_config |= BANK_SWAPS(1);
+	tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes,
+						rdev->config.r600.max_backends,
+						(0xff << rdev->config.r600.max_backends) & 0xff);
+	tiling_config |= BACKEND_MAP(tmp);
+	WREG32(GB_TILING_CONFIG, tiling_config);
+	WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
+	WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff);
+
+	tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK);
+	WREG32(CC_RB_BACKEND_DISABLE, tmp);
+
+	/* Setup pipes */
+	tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK);
+	tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK);
+	WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp);
+	WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp);
+
+	tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK);
+	WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
+	WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK);
+
+	/* Setup some CP states */
+	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | ROQ_IB2_START(0x2b)));
+	WREG32(CP_MEQ_THRESHOLDS, (MEQ_END(0x40) | ROQ_END(0x40)));
+
+	WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | SYNC_GRADIENT |
+			     SYNC_WALKER | SYNC_ALIGNER));
+	/* Setup various GPU states */
+	if (rdev->family == CHIP_RV670)
+		WREG32(ARB_GDEC_RD_CNTL, 0x00000021);
+
+	tmp = RREG32(SX_DEBUG_1);
+	tmp |= SMX_EVENT_RELEASE;
+	if ((rdev->family > CHIP_R600))
+		tmp |= ENABLE_NEW_SMX_ADDRESS;
+	WREG32(SX_DEBUG_1, tmp);
+
+	if (((rdev->family) == CHIP_R600) ||
+	    ((rdev->family) == CHIP_RV630) ||
+	    ((rdev->family) == CHIP_RV610) ||
+	    ((rdev->family) == CHIP_RV620) ||
+	    ((rdev->family) == CHIP_RS780)) {
+		WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE);
+	} else {
+		WREG32(DB_DEBUG, 0);
+	}
+	WREG32(DB_WATERMARKS, (DEPTH_FREE(4) | DEPTH_CACHELINE_FREE(16) |
+			       DEPTH_FLUSH(16) | DEPTH_PENDING_FREE(4)));
+
+	WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
+	WREG32(VGT_NUM_INSTANCES, 0);
+
+	WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0));
+	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(0));
+
+	tmp = RREG32(SQ_MS_FIFO_SIZES);
+	if (((rdev->family) == CHIP_RV610) ||
+	    ((rdev->family) == CHIP_RV620) ||
+	    ((rdev->family) == CHIP_RS780)) {
+		tmp = (CACHE_FIFO_SIZE(0xa) |
+		       FETCH_FIFO_HIWATER(0xa) |
+		       DONE_FIFO_HIWATER(0xe0) |
+		       ALU_UPDATE_FIFO_HIWATER(0x8));
+	} else if (((rdev->family) == CHIP_R600) ||
+		   ((rdev->family) == CHIP_RV630)) {
+		tmp &= ~DONE_FIFO_HIWATER(0xff);
+		tmp |= DONE_FIFO_HIWATER(0x4);
+	}
+	WREG32(SQ_MS_FIFO_SIZES, tmp);
+
+	/* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+	 * should be adjusted as needed by the 2D/3D drivers.  This just sets default values
+	 */
+	sq_config = RREG32(SQ_CONFIG);
+	sq_config &= ~(PS_PRIO(3) |
+		       VS_PRIO(3) |
+		       GS_PRIO(3) |
+		       ES_PRIO(3));
+	sq_config |= (DX9_CONSTS |
+		      VC_ENABLE |
+		      PS_PRIO(0) |
+		      VS_PRIO(1) |
+		      GS_PRIO(2) |
+		      ES_PRIO(3));
+
+	if ((rdev->family) == CHIP_R600) {
+		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(124) |
+					  NUM_VS_GPRS(124) |
+					  NUM_CLAUSE_TEMP_GPRS(4));
+		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(0) |
+					  NUM_ES_GPRS(0));
+		sq_thread_resource_mgmt = (NUM_PS_THREADS(136) |
+					   NUM_VS_THREADS(48) |
+					   NUM_GS_THREADS(4) |
+					   NUM_ES_THREADS(4));
+		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(128) |
+					    NUM_VS_STACK_ENTRIES(128));
+		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(0) |
+					    NUM_ES_STACK_ENTRIES(0));
+	} else if (((rdev->family) == CHIP_RV610) ||
+		   ((rdev->family) == CHIP_RV620) ||
+		   ((rdev->family) == CHIP_RS780)) {
+		/* no vertex cache */
+		sq_config &= ~VC_ENABLE;
+
+		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
+					  NUM_VS_GPRS(44) |
+					  NUM_CLAUSE_TEMP_GPRS(2));
+		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
+					  NUM_ES_GPRS(17));
+		sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
+					   NUM_VS_THREADS(78) |
+					   NUM_GS_THREADS(4) |
+					   NUM_ES_THREADS(31));
+		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
+					    NUM_VS_STACK_ENTRIES(40));
+		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
+					    NUM_ES_STACK_ENTRIES(16));
+	} else if (((rdev->family) == CHIP_RV630) ||
+		   ((rdev->family) == CHIP_RV635)) {
+		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
+					  NUM_VS_GPRS(44) |
+					  NUM_CLAUSE_TEMP_GPRS(2));
+		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(18) |
+					  NUM_ES_GPRS(18));
+		sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
+					   NUM_VS_THREADS(78) |
+					   NUM_GS_THREADS(4) |
+					   NUM_ES_THREADS(31));
+		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
+					    NUM_VS_STACK_ENTRIES(40));
+		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
+					    NUM_ES_STACK_ENTRIES(16));
+	} else if ((rdev->family) == CHIP_RV670) {
+		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
+					  NUM_VS_GPRS(44) |
+					  NUM_CLAUSE_TEMP_GPRS(2));
+		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
+					  NUM_ES_GPRS(17));
+		sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
+					   NUM_VS_THREADS(78) |
+					   NUM_GS_THREADS(4) |
+					   NUM_ES_THREADS(31));
+		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(64) |
+					    NUM_VS_STACK_ENTRIES(64));
+		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(64) |
+					    NUM_ES_STACK_ENTRIES(64));
+	}
+
+	WREG32(SQ_CONFIG, sq_config);
+	WREG32(SQ_GPR_RESOURCE_MGMT_1,  sq_gpr_resource_mgmt_1);
+	WREG32(SQ_GPR_RESOURCE_MGMT_2,  sq_gpr_resource_mgmt_2);
+	WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+	WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
+	WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
+
+	if (((rdev->family) == CHIP_RV610) ||
+	    ((rdev->family) == CHIP_RV620) ||
+	    ((rdev->family) == CHIP_RS780)) {
+		WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY));
+	} else {
+		WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC));
+	}
+
+	/* More default values. 2D/3D driver should adjust as needed */
+	WREG32(PA_SC_AA_SAMPLE_LOCS_2S, (S0_X(0xc) | S0_Y(0x4) |
+					 S1_X(0x4) | S1_Y(0xc)));
+	WREG32(PA_SC_AA_SAMPLE_LOCS_4S, (S0_X(0xe) | S0_Y(0xe) |
+					 S1_X(0x2) | S1_Y(0x2) |
+					 S2_X(0xa) | S2_Y(0x6) |
+					 S3_X(0x6) | S3_Y(0xa)));
+	WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD0, (S0_X(0xe) | S0_Y(0xb) |
+					     S1_X(0x4) | S1_Y(0xc) |
+					     S2_X(0x1) | S2_Y(0x6) |
+					     S3_X(0xa) | S3_Y(0xe)));
+	WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD1, (S4_X(0x6) | S4_Y(0x1) |
+					     S5_X(0x0) | S5_Y(0x0) |
+					     S6_X(0xb) | S6_Y(0x4) |
+					     S7_X(0x7) | S7_Y(0x8)));
+
+	WREG32(VGT_STRMOUT_EN, 0);
+	tmp = rdev->config.r600.max_pipes * 16;
+	switch (rdev->family) {
+	case CHIP_RV610:
+	case CHIP_RS780:
+	case CHIP_RV620:
+		tmp += 32;
+		break;
+	case CHIP_RV670:
+		tmp += 128;
+		break;
+	default:
+		break;
+	}
+	if (tmp > 256) {
+		tmp = 256;
+	}
+	WREG32(VGT_ES_PER_GS, 128);
+	WREG32(VGT_GS_PER_ES, tmp);
+	WREG32(VGT_GS_PER_VS, 2);
+	WREG32(VGT_GS_VERTEX_REUSE, 16);
+
+	/* more default values. 2D/3D driver should adjust as needed */
+	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
+	WREG32(VGT_STRMOUT_EN, 0);
+	WREG32(SX_MISC, 0);
+	WREG32(PA_SC_MODE_CNTL, 0);
+	WREG32(PA_SC_AA_CONFIG, 0);
+	WREG32(PA_SC_LINE_STIPPLE, 0);
+	WREG32(SPI_INPUT_Z, 0);
+	WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
+	WREG32(CB_COLOR7_FRAG, 0);
+
+	/* Clear render buffer base addresses */
+	WREG32(CB_COLOR0_BASE, 0);
+	WREG32(CB_COLOR1_BASE, 0);
+	WREG32(CB_COLOR2_BASE, 0);
+	WREG32(CB_COLOR3_BASE, 0);
+	WREG32(CB_COLOR4_BASE, 0);
+	WREG32(CB_COLOR5_BASE, 0);
+	WREG32(CB_COLOR6_BASE, 0);
+	WREG32(CB_COLOR7_BASE, 0);
+	WREG32(CB_COLOR7_FRAG, 0);
+
+	switch (rdev->family) {
+	case CHIP_RV610:
+	case CHIP_RS780:
+	case CHIP_RV620:
+		tmp = TC_L2_SIZE(8);
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		tmp = TC_L2_SIZE(4);
+		break;
+	case CHIP_R600:
+		tmp = TC_L2_SIZE(0) | L2_DISABLE_LATE_HIT;
+		break;
+	default:
+		tmp = TC_L2_SIZE(0);
+		break;
+	}
+	WREG32(TC_CNTL, tmp);
+
+	tmp = RREG32(HDP_HOST_PATH_CNTL);
+	WREG32(HDP_HOST_PATH_CNTL, tmp);
+
+	tmp = RREG32(ARB_POP);
+	tmp |= ENABLE_TC128;
+	WREG32(ARB_POP, tmp);
+
+	WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
+	WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
+			       NUM_CLIP_SEQ(3)));
+	WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095));
+}
+
+
 /*
  * Indirect registers accessor
  */
-uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg)
+u32 r600_pciep_rreg(struct radeon_device *rdev, u32 reg)
 {
-	uint32_t r;
+	u32 r;
 
-	WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff));
-	(void)RREG32(R600_PCIE_PORT_INDEX);
-	r = RREG32(R600_PCIE_PORT_DATA);
+	WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
+	(void)RREG32(PCIE_PORT_INDEX);
+	r = RREG32(PCIE_PORT_DATA);
 	return r;
 }
 
-void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
+void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
 {
-	WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff));
-	(void)RREG32(R600_PCIE_PORT_INDEX);
-	WREG32(R600_PCIE_PORT_DATA, (v));
-	(void)RREG32(R600_PCIE_PORT_DATA);
+	WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
+	(void)RREG32(PCIE_PORT_INDEX);
+	WREG32(PCIE_PORT_DATA, (v));
+	(void)RREG32(PCIE_PORT_DATA);
+}
+
+
+/*
+ * CP & Ring
+ */
+void r600_cp_stop(struct radeon_device *rdev)
+{
+	WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
+}
+
+int r600_cp_init_microcode(struct radeon_device *rdev)
+{
+	struct platform_device *pdev;
+	const char *chip_name;
+	size_t pfp_req_size, me_req_size;
+	char fw_name[30];
+	int err;
+
+	DRM_DEBUG("\n");
+
+	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
+	err = IS_ERR(pdev);
+	if (err) {
+		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
+		return -EINVAL;
+	}
+
+	switch (rdev->family) {
+	case CHIP_R600: chip_name = "R600"; break;
+	case CHIP_RV610: chip_name = "RV610"; break;
+	case CHIP_RV630: chip_name = "RV630"; break;
+	case CHIP_RV620: chip_name = "RV620"; break;
+	case CHIP_RV635: chip_name = "RV635"; break;
+	case CHIP_RV670: chip_name = "RV670"; break;
+	case CHIP_RS780:
+	case CHIP_RS880: chip_name = "RS780"; break;
+	case CHIP_RV770: chip_name = "RV770"; break;
+	case CHIP_RV730:
+	case CHIP_RV740: chip_name = "RV730"; break;
+	case CHIP_RV710: chip_name = "RV710"; break;
+	default: BUG();
+	}
+
+	if (rdev->family >= CHIP_RV770) {
+		pfp_req_size = R700_PFP_UCODE_SIZE * 4;
+		me_req_size = R700_PM4_UCODE_SIZE * 4;
+	} else {
+		pfp_req_size = PFP_UCODE_SIZE * 4;
+		me_req_size = PM4_UCODE_SIZE * 12;
+	}
+
+	DRM_INFO("Loading %s CP Microcode\n", chip_name);
+
+	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+	err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
+	if (err)
+		goto out;
+	if (rdev->pfp_fw->size != pfp_req_size) {
+		printk(KERN_ERR
+		       "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->pfp_fw->size, fw_name);
+		err = -EINVAL;
+		goto out;
+	}
+
+	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+	err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
+	if (err)
+		goto out;
+	if (rdev->me_fw->size != me_req_size) {
+		printk(KERN_ERR
+		       "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+		       rdev->me_fw->size, fw_name);
+		err = -EINVAL;
+	}
+out:
+	platform_device_unregister(pdev);
+
+	if (err) {
+		if (err != -EINVAL)
+			printk(KERN_ERR
+			       "r600_cp: Failed to load firmware \"%s\"\n",
+			       fw_name);
+		release_firmware(rdev->pfp_fw);
+		rdev->pfp_fw = NULL;
+		release_firmware(rdev->me_fw);
+		rdev->me_fw = NULL;
+	}
+	return err;
+}
+
+static int r600_cp_load_microcode(struct radeon_device *rdev)
+{
+	const __be32 *fw_data;
+	int i;
+
+	if (!rdev->me_fw || !rdev->pfp_fw)
+		return -EINVAL;
+
+	r600_cp_stop(rdev);
+
+	WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
+
+	/* Reset cp */
+	WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
+	RREG32(GRBM_SOFT_RESET);
+	mdelay(15);
+	WREG32(GRBM_SOFT_RESET, 0);
+
+	WREG32(CP_ME_RAM_WADDR, 0);
+
+	fw_data = (const __be32 *)rdev->me_fw->data;
+	WREG32(CP_ME_RAM_WADDR, 0);
+	for (i = 0; i < PM4_UCODE_SIZE * 3; i++)
+		WREG32(CP_ME_RAM_DATA,
+		       be32_to_cpup(fw_data++));
+
+	fw_data = (const __be32 *)rdev->pfp_fw->data;
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+	for (i = 0; i < PFP_UCODE_SIZE; i++)
+		WREG32(CP_PFP_UCODE_DATA,
+		       be32_to_cpup(fw_data++));
+
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+	WREG32(CP_ME_RAM_WADDR, 0);
+	WREG32(CP_ME_RAM_RADDR, 0);
+	return 0;
+}
+
+int r600_cp_start(struct radeon_device *rdev)
+{
+	int r;
+	uint32_t cp_me;
+
+	r = radeon_ring_lock(rdev, 7);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
+		return r;
+	}
+	radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
+	radeon_ring_write(rdev, 0x1);
+	if (rdev->family < CHIP_RV770) {
+		radeon_ring_write(rdev, 0x3);
+		radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1);
+	} else {
+		radeon_ring_write(rdev, 0x0);
+		radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1);
+	}
+	radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
+	radeon_ring_write(rdev, 0);
+	radeon_ring_write(rdev, 0);
+	radeon_ring_unlock_commit(rdev);
+
+	cp_me = 0xff;
+	WREG32(R_0086D8_CP_ME_CNTL, cp_me);
+	return 0;
+}
+
+int r600_cp_resume(struct radeon_device *rdev)
+{
+	u32 tmp;
+	u32 rb_bufsz;
+	int r;
+
+	/* Reset cp */
+	WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
+	RREG32(GRBM_SOFT_RESET);
+	mdelay(15);
+	WREG32(GRBM_SOFT_RESET, 0);
+
+	/* Set ring buffer size */
+	rb_bufsz = drm_order(rdev->cp.ring_size / 8);
+#ifdef __BIG_ENDIAN
+	WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE |
+		(drm_order(4096/8) << 8) | rb_bufsz);
+#else
+	WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz);
+#endif
+	WREG32(CP_SEM_WAIT_TIMER, 0x4);
+
+	/* Set the write pointer delay */
+	WREG32(CP_RB_WPTR_DELAY, 0);
+
+	/* Initialize the ring buffer's read and write pointers */
+	tmp = RREG32(CP_RB_CNTL);
+	WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
+	WREG32(CP_RB_RPTR_WR, 0);
+	WREG32(CP_RB_WPTR, 0);
+	WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF);
+	WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr));
+	mdelay(1);
+	WREG32(CP_RB_CNTL, tmp);
+
+	WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8);
+	WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
+
+	rdev->cp.rptr = RREG32(CP_RB_RPTR);
+	rdev->cp.wptr = RREG32(CP_RB_WPTR);
+
+	r600_cp_start(rdev);
+	rdev->cp.ready = true;
+	r = radeon_ring_test(rdev);
+	if (r) {
+		rdev->cp.ready = false;
+		return r;
+	}
+	return 0;
+}
+
+void r600_cp_commit(struct radeon_device *rdev)
+{
+	WREG32(CP_RB_WPTR, rdev->cp.wptr);
+	(void)RREG32(CP_RB_WPTR);
+}
+
+void r600_ring_init(struct radeon_device *rdev, unsigned ring_size)
+{
+	u32 rb_bufsz;
+
+	/* Align ring size */
+	rb_bufsz = drm_order(ring_size / 8);
+	ring_size = (1 << (rb_bufsz + 1)) * 4;
+	rdev->cp.ring_size = ring_size;
+	rdev->cp.align_mask = 16 - 1;
+}
+
+
+/*
+ * GPU scratch registers helpers function.
+ */
+void r600_scratch_init(struct radeon_device *rdev)
+{
+	int i;
+
+	rdev->scratch.num_reg = 7;
+	for (i = 0; i < rdev->scratch.num_reg; i++) {
+		rdev->scratch.free[i] = true;
+		rdev->scratch.reg[i] = SCRATCH_REG0 + (i * 4);
+	}
+}
+
+int r600_ring_test(struct radeon_device *rdev)
+{
+	uint32_t scratch;
+	uint32_t tmp = 0;
+	unsigned i;
+	int r;
+
+	r = radeon_scratch_get(rdev, &scratch);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
+		return r;
+	}
+	WREG32(scratch, 0xCAFEDEAD);
+	r = radeon_ring_lock(rdev, 3);
+	if (r) {
+		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
+		radeon_scratch_free(rdev, scratch);
+		return r;
+	}
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+	radeon_ring_write(rdev, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
+	radeon_ring_write(rdev, 0xDEADBEEF);
+	radeon_ring_unlock_commit(rdev);
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(scratch);
+		if (tmp == 0xDEADBEEF)
+			break;
+		DRM_UDELAY(1);
+	}
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ring test succeeded in %d usecs\n", i);
+	} else {
+		DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n",
+			  scratch, tmp);
+		r = -EINVAL;
+	}
+	radeon_scratch_free(rdev, scratch);
+	return r;
+}
+
+/*
+ * Writeback
+ */
+int r600_wb_init(struct radeon_device *rdev)
+{
+	int r;
+
+	if (rdev->wb.wb_obj == NULL) {
+		r = radeon_object_create(rdev, NULL, 4096,
+					 true,
+					 RADEON_GEM_DOMAIN_GTT,
+					 false, &rdev->wb.wb_obj);
+		if (r) {
+			DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r);
+			return r;
+		}
+		r = radeon_object_pin(rdev->wb.wb_obj,
+				      RADEON_GEM_DOMAIN_GTT,
+				      &rdev->wb.gpu_addr);
+		if (r) {
+			DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r);
+			return r;
+		}
+		r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
+		if (r) {
+			DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r);
+			return r;
+		}
+	}
+	WREG32(SCRATCH_ADDR, (rdev->wb.gpu_addr >> 8) & 0xFFFFFFFF);
+	WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + 1024) & 0xFFFFFFFC);
+	WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 1024) & 0xFF);
+	WREG32(SCRATCH_UMSK, 0xff);
+	return 0;
+}
+
+void r600_wb_fini(struct radeon_device *rdev)
+{
+	if (rdev->wb.wb_obj) {
+		radeon_object_kunmap(rdev->wb.wb_obj);
+		radeon_object_unpin(rdev->wb.wb_obj);
+		radeon_object_unref(&rdev->wb.wb_obj);
+		rdev->wb.wb = NULL;
+		rdev->wb.wb_obj = NULL;
+	}
+}
+
+
+/*
+ * CS
+ */
+void r600_fence_ring_emit(struct radeon_device *rdev,
+			  struct radeon_fence *fence)
+{
+	/* Emit fence sequence & fire IRQ */
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+	radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
+	radeon_ring_write(rdev, fence->seq);
+}
+
+int r600_copy_dma(struct radeon_device *rdev,
+		  uint64_t src_offset,
+		  uint64_t dst_offset,
+		  unsigned num_pages,
+		  struct radeon_fence *fence)
+{
+	/* FIXME: implement */
+	return 0;
+}
+
+int r600_copy_blit(struct radeon_device *rdev,
+		   uint64_t src_offset, uint64_t dst_offset,
+		   unsigned num_pages, struct radeon_fence *fence)
+{
+	r600_blit_prepare_copy(rdev, num_pages * 4096);
+	r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096);
+	r600_blit_done_copy(rdev, fence);
+	return 0;
+}
+
+int r600_irq_process(struct radeon_device *rdev)
+{
+	/* FIXME: implement */
+	return 0;
+}
+
+int r600_irq_set(struct radeon_device *rdev)
+{
+	/* FIXME: implement */
+	return 0;
+}
+
+int r600_set_surface_reg(struct radeon_device *rdev, int reg,
+			 uint32_t tiling_flags, uint32_t pitch,
+			 uint32_t offset, uint32_t obj_size)
+{
+	/* FIXME: implement */
+	return 0;
+}
+
+void r600_clear_surface_reg(struct radeon_device *rdev, int reg)
+{
+	/* FIXME: implement */
+}
+
+
+bool r600_card_posted(struct radeon_device *rdev)
+{
+	uint32_t reg;
+
+	/* first check CRTCs */
+	reg = RREG32(D1CRTC_CONTROL) |
+		RREG32(D2CRTC_CONTROL);
+	if (reg & CRTC_EN)
+		return true;
+
+	/* then check MEM_SIZE, in case the crtcs are off */
+	if (RREG32(CONFIG_MEMSIZE))
+		return true;
+
+	return false;
+}
+
+int r600_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	r600_gpu_reset(rdev);
+	r600_mc_resume(rdev);
+	r = r600_pcie_gart_enable(rdev);
+	if (r)
+		return r;
+	r600_gpu_init(rdev);
+
+	r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
+			      &rdev->r600_blit.shader_gpu_addr);
+	if (r) {
+		DRM_ERROR("failed to pin blit object %d\n", r);
+		return r;
+	}
+
+	r = radeon_ring_init(rdev, rdev->cp.ring_size);
+	if (r)
+		return r;
+	r = r600_cp_load_microcode(rdev);
+	if (r)
+		return r;
+	r = r600_cp_resume(rdev);
+	if (r)
+		return r;
+	r = r600_wb_init(rdev);
+	if (r)
+		return r;
+	return 0;
+}
+
+void r600_vga_set_state(struct radeon_device *rdev, bool state)
+{
+	uint32_t temp;
+
+	temp = RREG32(CONFIG_CNTL);
+	if (state == false) {
+		temp &= ~(1<<0);
+		temp |= (1<<1);
+	} else {
+		temp &= ~(1<<1);
+	}
+	WREG32(CONFIG_CNTL, temp);
+}
+
+int r600_resume(struct radeon_device *rdev)
+{
+	int r;
+
+	if (radeon_gpu_reset(rdev)) {
+		/* FIXME: what do we want to do here ? */
+	}
+	/* post card */
+	if (rdev->is_atom_bios) {
+		atom_asic_init(rdev->mode_info.atom_context);
+	} else {
+		radeon_combios_asic_init(rdev->ddev);
+	}
+	/* Initialize clocks */
+	r = radeon_clocks_init(rdev);
+	if (r) {
+		return r;
+	}
+
+	r = r600_startup(rdev);
+	if (r) {
+		DRM_ERROR("r600 startup failed on resume\n");
+		return r;
+	}
+
+	r = radeon_ib_test(rdev);
+	if (r) {
+		DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+		return r;
+	}
+	return r;
+}
+
+
+int r600_suspend(struct radeon_device *rdev)
+{
+	/* FIXME: we should wait for ring to be empty */
+	r600_cp_stop(rdev);
+	rdev->cp.ready = false;
+
+	r600_pcie_gart_disable(rdev);
+	/* unpin shaders bo */
+	radeon_object_unpin(rdev->r600_blit.shader_obj);
+	return 0;
+}
+
+/* Plan is to move initialization in that function and use
+ * helper function so that radeon_device_init pretty much
+ * do nothing more than calling asic specific function. This
+ * should also allow to remove a bunch of callback function
+ * like vram_info.
+ */
+int r600_init(struct radeon_device *rdev)
+{
+	int r;
+
+	rdev->new_init_path = true;
+	r = radeon_dummy_page_init(rdev);
+	if (r)
+		return r;
+	if (r600_debugfs_mc_info_init(rdev)) {
+		DRM_ERROR("Failed to register debugfs file for mc !\n");
+	}
+	/* This don't do much */
+	r = radeon_gem_init(rdev);
+	if (r)
+		return r;
+	/* Read BIOS */
+	if (!radeon_get_bios(rdev)) {
+		if (ASIC_IS_AVIVO(rdev))
+			return -EINVAL;
+	}
+	/* Must be an ATOMBIOS */
+	if (!rdev->is_atom_bios)
+		return -EINVAL;
+	r = radeon_atombios_init(rdev);
+	if (r)
+		return r;
+	/* Post card if necessary */
+	if (!r600_card_posted(rdev) && rdev->bios) {
+		DRM_INFO("GPU not posted. posting now...\n");
+		atom_asic_init(rdev->mode_info.atom_context);
+	}
+	/* Initialize scratch registers */
+	r600_scratch_init(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
+	radeon_get_clock_info(rdev->ddev);
+	r = radeon_clocks_init(rdev);
+	if (r)
+		return r;
+	/* Fence driver */
+	r = radeon_fence_driver_init(rdev);
+	if (r)
+		return r;
+	r = r600_mc_init(rdev);
+	if (r) {
+		if (rdev->flags & RADEON_IS_AGP) {
+			/* Retry with disabling AGP */
+			r600_fini(rdev);
+			rdev->flags &= ~RADEON_IS_AGP;
+			return r600_init(rdev);
+		}
+		return r;
+	}
+	/* Memory manager */
+	r = radeon_object_init(rdev);
+	if (r)
+		return r;
+	rdev->cp.ring_obj = NULL;
+	r600_ring_init(rdev, 1024 * 1024);
+
+	if (!rdev->me_fw || !rdev->pfp_fw) {
+		r = r600_cp_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
+	r = r600_pcie_gart_init(rdev);
+	if (r)
+		return r;
+
+	rdev->accel_working = true;
+	r = r600_blit_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: failled blitter (%d).\n", r);
+		return r;
+	}
+
+	r = r600_startup(rdev);
+	if (r) {
+		if (rdev->flags & RADEON_IS_AGP) {
+			/* Retry with disabling AGP */
+			r600_fini(rdev);
+			rdev->flags &= ~RADEON_IS_AGP;
+			return r600_init(rdev);
+		}
+		rdev->accel_working = false;
+	}
+	if (rdev->accel_working) {
+		r = radeon_ib_pool_init(rdev);
+		if (r) {
+			DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
+			rdev->accel_working = false;
+		}
+		r = radeon_ib_test(rdev);
+		if (r) {
+			DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+			rdev->accel_working = false;
+		}
+	}
+	return 0;
+}
+
+void r600_fini(struct radeon_device *rdev)
+{
+	/* Suspend operations */
+	r600_suspend(rdev);
+
+	r600_blit_fini(rdev);
+	radeon_ring_fini(rdev);
+	r600_pcie_gart_fini(rdev);
+	radeon_gem_fini(rdev);
+	radeon_fence_driver_fini(rdev);
+	radeon_clocks_fini(rdev);
+#if __OS_HAS_AGP
+	if (rdev->flags & RADEON_IS_AGP)
+		radeon_agp_fini(rdev);
+#endif
+	radeon_object_fini(rdev);
+	if (rdev->is_atom_bios)
+		radeon_atombios_fini(rdev);
+	else
+		radeon_combios_fini(rdev);
+	kfree(rdev->bios);
+	rdev->bios = NULL;
+	radeon_dummy_page_fini(rdev);
+}
+
+
+/*
+ * CS stuff
+ */
+void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
+{
+	/* FIXME: implement */
+	radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
+	radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC);
+	radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF);
+	radeon_ring_write(rdev, ib->length_dw);
+}
+
+int r600_ib_test(struct radeon_device *rdev)
+{
+	struct radeon_ib *ib;
+	uint32_t scratch;
+	uint32_t tmp = 0;
+	unsigned i;
+	int r;
+
+	r = radeon_scratch_get(rdev, &scratch);
+	if (r) {
+		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
+		return r;
+	}
+	WREG32(scratch, 0xCAFEDEAD);
+	r = radeon_ib_get(rdev, &ib);
+	if (r) {
+		DRM_ERROR("radeon: failed to get ib (%d).\n", r);
+		return r;
+	}
+	ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1);
+	ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+	ib->ptr[2] = 0xDEADBEEF;
+	ib->ptr[3] = PACKET2(0);
+	ib->ptr[4] = PACKET2(0);
+	ib->ptr[5] = PACKET2(0);
+	ib->ptr[6] = PACKET2(0);
+	ib->ptr[7] = PACKET2(0);
+	ib->ptr[8] = PACKET2(0);
+	ib->ptr[9] = PACKET2(0);
+	ib->ptr[10] = PACKET2(0);
+	ib->ptr[11] = PACKET2(0);
+	ib->ptr[12] = PACKET2(0);
+	ib->ptr[13] = PACKET2(0);
+	ib->ptr[14] = PACKET2(0);
+	ib->ptr[15] = PACKET2(0);
+	ib->length_dw = 16;
+	r = radeon_ib_schedule(rdev, ib);
+	if (r) {
+		radeon_scratch_free(rdev, scratch);
+		radeon_ib_free(rdev, &ib);
+		DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
+		return r;
+	}
+	r = radeon_fence_wait(ib->fence, false);
+	if (r) {
+		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
+		return r;
+	}
+	for (i = 0; i < rdev->usec_timeout; i++) {
+		tmp = RREG32(scratch);
+		if (tmp == 0xDEADBEEF)
+			break;
+		DRM_UDELAY(1);
+	}
+	if (i < rdev->usec_timeout) {
+		DRM_INFO("ib test succeeded in %u usecs\n", i);
+	} else {
+		DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
+			  scratch, tmp);
+		r = -EINVAL;
+	}
+	radeon_scratch_free(rdev, scratch);
+	radeon_ib_free(rdev, &ib);
+	return r;
+}
+
+
+
+
+/*
+ * Debugfs info
+ */
+#if defined(CONFIG_DEBUG_FS)
+
+static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t rdp, wdp;
+	unsigned count, i, j;
+
+	radeon_ring_free_size(rdev);
+	rdp = RREG32(CP_RB_RPTR);
+	wdp = RREG32(CP_RB_WPTR);
+	count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
+	seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT));
+	seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
+	seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
+	seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
+	seq_printf(m, "%u dwords in ring\n", count);
+	for (j = 0; j <= count; j++) {
+		i = (rdp + j) & rdev->cp.ptr_mask;
+		seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
+	}
+	return 0;
+}
+
+static int r600_debugfs_mc_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct radeon_device *rdev = dev->dev_private;
+
+	DREG32_SYS(m, rdev, R_000E50_SRBM_STATUS);
+	DREG32_SYS(m, rdev, VM_L2_STATUS);
+	return 0;
+}
+
+static struct drm_info_list r600_mc_info_list[] = {
+	{"r600_mc_info", r600_debugfs_mc_info, 0, NULL},
+	{"r600_ring_info", r600_debugfs_cp_ring_info, 0, NULL},
+};
+#endif
+
+int r600_debugfs_mc_info_init(struct radeon_device *rdev)
+{
+#if defined(CONFIG_DEBUG_FS)
+	return radeon_debugfs_add_files(rdev, r600_mc_info_list, ARRAY_SIZE(r600_mc_info_list));
+#else
+	return 0;
+#endif
 }
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
new file mode 100644
index 0000000..dde2ccb
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -0,0 +1,850 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *     Alex Deucher <alexander.deucher@amd.com>
+ */
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+#include "r600_blit_shaders.h"
+
+#define DI_PT_RECTLIST        0x11
+#define DI_INDEX_SIZE_16_BIT  0x0
+#define DI_SRC_SEL_AUTO_INDEX 0x2
+
+#define FMT_8                 0x1
+#define FMT_5_6_5             0x8
+#define FMT_8_8_8_8           0x1a
+#define COLOR_8               0x1
+#define COLOR_5_6_5           0x8
+#define COLOR_8_8_8_8         0x1a
+
+static inline void
+set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr)
+{
+	u32 cb_color_info;
+	int pitch, slice;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	h = (h + 7) & ~7;
+	if (h < 8)
+		h = 8;
+
+	cb_color_info = ((format << 2) | (1 << 27));
+	pitch = (w / 8) - 1;
+	slice = ((w * h) / 64) - 1;
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) &&
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) {
+		BEGIN_RING(21 + 2);
+		OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+		OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+		OUT_RING(gpu_addr >> 8);
+		OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0));
+		OUT_RING(2 << 0);
+	} else {
+		BEGIN_RING(21);
+		OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+		OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+		OUT_RING(gpu_addr >> 8);
+	}
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((pitch << 0) | (slice << 10));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(cb_color_info);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	ADVANCE_RING();
+}
+
+static inline void
+cp_set_surface_sync(drm_radeon_private_t *dev_priv,
+		    u32 sync_type, u32 size, u64 mc_addr)
+{
+	u32 cp_coher_size;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	if (size == 0xffffffff)
+		cp_coher_size = 0xffffffff;
+	else
+		cp_coher_size = ((size + 255) >> 8);
+
+	BEGIN_RING(5);
+	OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
+	OUT_RING(sync_type);
+	OUT_RING(cp_coher_size);
+	OUT_RING((mc_addr >> 8));
+	OUT_RING(10); /* poll interval */
+	ADVANCE_RING();
+}
+
+static inline void
+set_shaders(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	u64 gpu_addr;
+	int i;
+	u32 *vs, *ps;
+	uint32_t sq_pgm_resources;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	/* load shaders */
+	vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset);
+	ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256);
+
+	for (i = 0; i < r6xx_vs_size; i++)
+		vs[i] = r6xx_vs[i];
+	for (i = 0; i < r6xx_ps_size; i++)
+		ps[i] = r6xx_ps[i];
+
+	dev_priv->blit_vb->used = 512;
+
+	gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset;
+
+	/* setup shader regs */
+	sq_pgm_resources = (1 << 0);
+
+	BEGIN_RING(9 + 12);
+	/* VS */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(gpu_addr >> 8);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(sq_pgm_resources);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+
+	/* PS */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((gpu_addr + 256) >> 8);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(sq_pgm_resources | (1 << 28));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(2);
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1));
+	OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING(0);
+	ADVANCE_RING();
+
+	cp_set_surface_sync(dev_priv,
+			    R600_SH_ACTION_ENA, 512, gpu_addr);
+}
+
+static inline void
+set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr)
+{
+	uint32_t sq_vtx_constant_word2;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8));
+
+	BEGIN_RING(9);
+	OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
+	OUT_RING(0x460);
+	OUT_RING(gpu_addr & 0xffffffff);
+	OUT_RING(48 - 1);
+	OUT_RING(sq_vtx_constant_word2);
+	OUT_RING(1 << 0);
+	OUT_RING(0);
+	OUT_RING(0);
+	OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30);
+	ADVANCE_RING();
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
+		cp_set_surface_sync(dev_priv,
+				    R600_TC_ACTION_ENA, 48, gpu_addr);
+	else
+		cp_set_surface_sync(dev_priv,
+				    R600_VC_ACTION_ENA, 48, gpu_addr);
+}
+
+static inline void
+set_tex_resource(drm_radeon_private_t *dev_priv,
+		 int format, int w, int h, int pitch, u64 gpu_addr)
+{
+	uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	if (h < 1)
+		h = 1;
+
+	sq_tex_resource_word0 = (1 << 0);
+	sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
+				  ((w - 1) << 19));
+
+	sq_tex_resource_word1 = (format << 26);
+	sq_tex_resource_word1 |= ((h - 1) << 0);
+
+	sq_tex_resource_word4 = ((1 << 14) |
+				 (0 << 16) |
+				 (1 << 19) |
+				 (2 << 22) |
+				 (3 << 25));
+
+	BEGIN_RING(9);
+	OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
+	OUT_RING(0);
+	OUT_RING(sq_tex_resource_word0);
+	OUT_RING(sq_tex_resource_word1);
+	OUT_RING(gpu_addr >> 8);
+	OUT_RING(gpu_addr >> 8);
+	OUT_RING(sq_tex_resource_word4);
+	OUT_RING(0);
+	OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30);
+	ADVANCE_RING();
+
+}
+
+static inline void
+set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2)
+{
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(12);
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
+	OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((x1 << 0) | (y1 << 16));
+	OUT_RING((x2 << 0) | (y2 << 16));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
+	OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31));
+	OUT_RING((x2 << 0) | (y2 << 16));
+
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2));
+	OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2);
+	OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31));
+	OUT_RING((x2 << 0) | (y2 << 16));
+	ADVANCE_RING();
+}
+
+static inline void
+draw_auto(drm_radeon_private_t *dev_priv)
+{
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(10);
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+	OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2);
+	OUT_RING(DI_PT_RECTLIST);
+
+	OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
+	OUT_RING(DI_INDEX_SIZE_16_BIT);
+
+	OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
+	OUT_RING(1);
+
+	OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
+	OUT_RING(3);
+	OUT_RING(DI_SRC_SEL_AUTO_INDEX);
+
+	ADVANCE_RING();
+	COMMIT_RING();
+}
+
+static inline void
+set_default_state(drm_radeon_private_t *dev_priv)
+{
+	int i;
+	u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;
+	u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;
+	int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;
+	int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads;
+	int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
+	RING_LOCALS;
+
+	switch ((dev_priv->flags & RADEON_FAMILY_MASK)) {
+	case CHIP_R600:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 144;
+		num_vs_threads = 40;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV610:
+	case CHIP_RV620:
+	case CHIP_RS780:
+	case CHIP_RS880:
+	default:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV670:
+		num_ps_gprs = 144;
+		num_vs_gprs = 40;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV770:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 188;
+		num_vs_threads = 60;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 256;
+		num_vs_stack_entries = 256;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV730:
+	case CHIP_RV740:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 188;
+		num_vs_threads = 60;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV710:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 144;
+		num_vs_threads = 48;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	}
+
+	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) ||
+	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710))
+		sq_config = 0;
+	else
+		sq_config = R600_VC_ENABLE;
+
+	sq_config |= (R600_DX9_CONSTS |
+		      R600_ALU_INST_PREFER_VECTOR |
+		      R600_PS_PRIO(0) |
+		      R600_VS_PRIO(1) |
+		      R600_GS_PRIO(2) |
+		      R600_ES_PRIO(3));
+
+	sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) |
+				  R600_NUM_VS_GPRS(num_vs_gprs) |
+				  R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
+	sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) |
+				  R600_NUM_ES_GPRS(num_es_gprs));
+	sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) |
+				   R600_NUM_VS_THREADS(num_vs_threads) |
+				   R600_NUM_GS_THREADS(num_gs_threads) |
+				   R600_NUM_ES_THREADS(num_es_threads));
+	sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
+				    R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
+	sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
+				    R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries));
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
+		BEGIN_RING(r7xx_default_size + 10);
+		for (i = 0; i < r7xx_default_size; i++)
+			OUT_RING(r7xx_default_state[i]);
+	} else {
+		BEGIN_RING(r6xx_default_size + 10);
+		for (i = 0; i < r6xx_default_size; i++)
+			OUT_RING(r6xx_default_state[i]);
+	}
+	OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
+	OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
+	/* SQ config */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6));
+	OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2);
+	OUT_RING(sq_config);
+	OUT_RING(sq_gpr_resource_mgmt_1);
+	OUT_RING(sq_gpr_resource_mgmt_2);
+	OUT_RING(sq_thread_resource_mgmt);
+	OUT_RING(sq_stack_resource_mgmt_1);
+	OUT_RING(sq_stack_resource_mgmt_2);
+	ADVANCE_RING();
+}
+
+static inline uint32_t i2f(uint32_t input)
+{
+	u32 result, i, exponent, fraction;
+
+	if ((input & 0x3fff) == 0)
+		result = 0; /* 0 is a special case */
+	else {
+		exponent = 140; /* exponent biased by 127; */
+		fraction = (input & 0x3fff) << 10; /* cheat and only
+						      handle numbers below 2^^15 */
+		for (i = 0; i < 14; i++) {
+			if (fraction & 0x800000)
+				break;
+			else {
+				fraction = fraction << 1; /* keep
+							     shifting left until top bit = 1 */
+				exponent = exponent - 1;
+			}
+		}
+		result = exponent << 23 | (fraction & 0x7fffff); /* mask
+								    off top bit; assumed 1 */
+	}
+	return result;
+}
+
+
+static inline int r600_nomm_get_vb(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	dev_priv->blit_vb = radeon_freelist_get(dev);
+	if (!dev_priv->blit_vb) {
+		DRM_ERROR("Unable to allocate vertex buffer for blit\n");
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static inline void r600_nomm_put_vb(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+
+	dev_priv->blit_vb->used = 0;
+	radeon_cp_discard_buffer(dev, dev_priv->blit_vb->file_priv->master, dev_priv->blit_vb);
+}
+
+static inline void *r600_nomm_get_vb_ptr(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	return (((char *)dev->agp_buffer_map->handle +
+		 dev_priv->blit_vb->offset + dev_priv->blit_vb->used));
+}
+
+int
+r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	DRM_DEBUG("\n");
+
+	r600_nomm_get_vb(dev);
+
+	dev_priv->blit_vb->file_priv = file_priv;
+
+	set_default_state(dev_priv);
+	set_shaders(dev);
+
+	return 0;
+}
+
+
+void
+r600_done_blit_copy(struct drm_device *dev)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	BEGIN_RING(5);
+	OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
+	OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
+	/* wait for 3D idle clean */
+	OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+	OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2);
+	OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN);
+
+	ADVANCE_RING();
+	COMMIT_RING();
+
+	r600_nomm_put_vb(dev);
+}
+
+void
+r600_blit_copy(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int size_bytes)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	int max_bytes;
+	u64 vb_addr;
+	u32 *vb;
+
+	vb = r600_nomm_get_vb_ptr(dev);
+
+	if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
+		max_bytes = 8192;
+
+		while (size_bytes) {
+			int cur_size = size_bytes;
+			int src_x = src_gpu_addr & 255;
+			int dst_x = dst_gpu_addr & 255;
+			int h = 1;
+			src_gpu_addr = src_gpu_addr & ~255;
+			dst_gpu_addr = dst_gpu_addr & ~255;
+
+			if (!src_x && !dst_x) {
+				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
+				if (h == 0)
+					h = 1;
+				else
+					cur_size = max_bytes;
+			} else {
+				if (cur_size > max_bytes)
+					cur_size = max_bytes;
+				if (cur_size > (max_bytes - dst_x))
+					cur_size = (max_bytes - dst_x);
+				if (cur_size > (max_bytes - src_x))
+					cur_size = (max_bytes - src_x);
+			}
+
+			if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
+
+				r600_nomm_put_vb(dev);
+				r600_nomm_get_vb(dev);
+				if (!dev_priv->blit_vb)
+					return;
+				set_shaders(dev);
+				vb = r600_nomm_get_vb_ptr(dev);
+			}
+
+			vb[0] = i2f(dst_x);
+			vb[1] = 0;
+			vb[2] = i2f(src_x);
+			vb[3] = 0;
+
+			vb[4] = i2f(dst_x);
+			vb[5] = i2f(h);
+			vb[6] = i2f(src_x);
+			vb[7] = i2f(h);
+
+			vb[8] = i2f(dst_x + cur_size);
+			vb[9] = i2f(h);
+			vb[10] = i2f(src_x + cur_size);
+			vb[11] = i2f(h);
+
+			/* src */
+			set_tex_resource(dev_priv, FMT_8,
+					 src_x + cur_size, h, src_x + cur_size,
+					 src_gpu_addr);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
+
+			/* dst */
+			set_render_target(dev_priv, COLOR_8,
+					  dst_x + cur_size, h,
+					  dst_gpu_addr);
+
+			/* scissors */
+			set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h);
+
+			/* Vertex buffer setup */
+			vb_addr = dev_priv->gart_buffers_offset +
+				dev_priv->blit_vb->offset +
+				dev_priv->blit_vb->used;
+			set_vtx_resource(dev_priv, vb_addr);
+
+			/* draw */
+			draw_auto(dev_priv);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
+					    cur_size * h, dst_gpu_addr);
+
+			vb += 12;
+			dev_priv->blit_vb->used += 12 * 4;
+
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
+			size_bytes -= cur_size * h;
+		}
+	} else {
+		max_bytes = 8192 * 4;
+
+		while (size_bytes) {
+			int cur_size = size_bytes;
+			int src_x = (src_gpu_addr & 255);
+			int dst_x = (dst_gpu_addr & 255);
+			int h = 1;
+			src_gpu_addr = src_gpu_addr & ~255;
+			dst_gpu_addr = dst_gpu_addr & ~255;
+
+			if (!src_x && !dst_x) {
+				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
+				if (h == 0)
+					h = 1;
+				else
+					cur_size = max_bytes;
+			} else {
+				if (cur_size > max_bytes)
+					cur_size = max_bytes;
+				if (cur_size > (max_bytes - dst_x))
+					cur_size = (max_bytes - dst_x);
+				if (cur_size > (max_bytes - src_x))
+					cur_size = (max_bytes - src_x);
+			}
+
+			if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
+				r600_nomm_put_vb(dev);
+				r600_nomm_get_vb(dev);
+				if (!dev_priv->blit_vb)
+					return;
+
+				set_shaders(dev);
+				vb = r600_nomm_get_vb_ptr(dev);
+			}
+
+			vb[0] = i2f(dst_x / 4);
+			vb[1] = 0;
+			vb[2] = i2f(src_x / 4);
+			vb[3] = 0;
+
+			vb[4] = i2f(dst_x / 4);
+			vb[5] = i2f(h);
+			vb[6] = i2f(src_x / 4);
+			vb[7] = i2f(h);
+
+			vb[8] = i2f((dst_x + cur_size) / 4);
+			vb[9] = i2f(h);
+			vb[10] = i2f((src_x + cur_size) / 4);
+			vb[11] = i2f(h);
+
+			/* src */
+			set_tex_resource(dev_priv, FMT_8_8_8_8,
+					 (src_x + cur_size) / 4,
+					 h, (src_x + cur_size) / 4,
+					 src_gpu_addr);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
+
+			/* dst */
+			set_render_target(dev_priv, COLOR_8_8_8_8,
+					  dst_x + cur_size, h,
+					  dst_gpu_addr);
+
+			/* scissors */
+			set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h);
+
+			/* Vertex buffer setup */
+			vb_addr = dev_priv->gart_buffers_offset +
+				dev_priv->blit_vb->offset +
+				dev_priv->blit_vb->used;
+			set_vtx_resource(dev_priv, vb_addr);
+
+			/* draw */
+			draw_auto(dev_priv);
+
+			cp_set_surface_sync(dev_priv,
+					    R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
+					    cur_size * h, dst_gpu_addr);
+
+			vb += 12;
+			dev_priv->blit_vb->used += 12 * 4;
+
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
+			size_bytes -= cur_size * h;
+		}
+	}
+}
+
+void
+r600_blit_swap(struct drm_device *dev,
+	       uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+	       int sx, int sy, int dx, int dy,
+	       int w, int h, int src_pitch, int dst_pitch, int cpp)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	int cb_format, tex_format;
+	u64 vb_addr;
+	u32 *vb;
+
+	vb = r600_nomm_get_vb_ptr(dev);
+
+	if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
+
+		r600_nomm_put_vb(dev);
+		r600_nomm_get_vb(dev);
+		if (!dev_priv->blit_vb)
+			return;
+
+		set_shaders(dev);
+		vb = r600_nomm_get_vb_ptr(dev);
+	}
+
+	if (cpp == 4) {
+		cb_format = COLOR_8_8_8_8;
+		tex_format = FMT_8_8_8_8;
+	} else if (cpp == 2) {
+		cb_format = COLOR_5_6_5;
+		tex_format = FMT_5_6_5;
+	} else {
+		cb_format = COLOR_8;
+		tex_format = FMT_8;
+	}
+
+	vb[0] = i2f(dx);
+	vb[1] = i2f(dy);
+	vb[2] = i2f(sx);
+	vb[3] = i2f(sy);
+
+	vb[4] = i2f(dx);
+	vb[5] = i2f(dy + h);
+	vb[6] = i2f(sx);
+	vb[7] = i2f(sy + h);
+
+	vb[8] = i2f(dx + w);
+	vb[9] = i2f(dy + h);
+	vb[10] = i2f(sx + w);
+	vb[11] = i2f(sy + h);
+
+	/* src */
+	set_tex_resource(dev_priv, tex_format,
+			 src_pitch / cpp,
+			 sy + h, src_pitch / cpp,
+			 src_gpu_addr);
+
+	cp_set_surface_sync(dev_priv,
+			    R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr);
+
+	/* dst */
+	set_render_target(dev_priv, cb_format,
+			  dst_pitch / cpp, dy + h,
+			  dst_gpu_addr);
+
+	/* scissors */
+	set_scissors(dev_priv, dx, dy, dx + w, dy + h);
+
+	/* Vertex buffer setup */
+	vb_addr = dev_priv->gart_buffers_offset +
+		dev_priv->blit_vb->offset +
+		dev_priv->blit_vb->used;
+	set_vtx_resource(dev_priv, vb_addr);
+
+	/* draw */
+	draw_auto(dev_priv);
+
+	cp_set_surface_sync(dev_priv,
+			    R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA,
+			    dst_pitch * (dy + h), dst_gpu_addr);
+
+	dev_priv->blit_vb->used += 12 * 4;
+}
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
new file mode 100644
index 0000000..0a6f468
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -0,0 +1,805 @@
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon.h"
+
+#include "r600d.h"
+#include "r600_blit_shaders.h"
+
+#define DI_PT_RECTLIST        0x11
+#define DI_INDEX_SIZE_16_BIT  0x0
+#define DI_SRC_SEL_AUTO_INDEX 0x2
+
+#define FMT_8                 0x1
+#define FMT_5_6_5             0x8
+#define FMT_8_8_8_8           0x1a
+#define COLOR_8               0x1
+#define COLOR_5_6_5           0x8
+#define COLOR_8_8_8_8         0x1a
+
+/* emits 21 on rv770+, 23 on r600 */
+static void
+set_render_target(struct radeon_device *rdev, int format,
+		  int w, int h, u64 gpu_addr)
+{
+	u32 cb_color_info;
+	int pitch, slice;
+
+	h = (h + 7) & ~7;
+	if (h < 8)
+		h = 8;
+
+	cb_color_info = ((format << 2) | (1 << 27));
+	pitch = (w / 8) - 1;
+	slice = ((w * h) / 64) - 1;
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, gpu_addr >> 8);
+
+	if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) {
+		radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0));
+		radeon_ring_write(rdev, 2 << 0);
+	}
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, (pitch << 0) | (slice << 10));
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, 0);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, cb_color_info);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, 0);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, 0);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, 0);
+}
+
+/* emits 5dw */
+static void
+cp_set_surface_sync(struct radeon_device *rdev,
+		    u32 sync_type, u32 size,
+		    u64 mc_addr)
+{
+	u32 cp_coher_size;
+
+	if (size == 0xffffffff)
+		cp_coher_size = 0xffffffff;
+	else
+		cp_coher_size = ((size + 255) >> 8);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3));
+	radeon_ring_write(rdev, sync_type);
+	radeon_ring_write(rdev, cp_coher_size);
+	radeon_ring_write(rdev, mc_addr >> 8);
+	radeon_ring_write(rdev, 10); /* poll interval */
+}
+
+/* emits 21dw + 1 surface sync = 26dw */
+static void
+set_shaders(struct radeon_device *rdev)
+{
+	u64 gpu_addr;
+	u32 sq_pgm_resources;
+
+	/* setup shader regs */
+	sq_pgm_resources = (1 << 0);
+
+	/* VS */
+	gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, gpu_addr >> 8);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, sq_pgm_resources);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, 0);
+
+	/* PS */
+	gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset;
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, gpu_addr >> 8);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, sq_pgm_resources | (1 << 28));
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, 2);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1));
+	radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, 0);
+
+	gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset;
+	cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr);
+}
+
+/* emits 9 + 1 sync (5) = 14*/
+static void
+set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr)
+{
+	u32 sq_vtx_constant_word2;
+
+	sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8));
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
+	radeon_ring_write(rdev, 0x460);
+	radeon_ring_write(rdev, gpu_addr & 0xffffffff);
+	radeon_ring_write(rdev, 48 - 1);
+	radeon_ring_write(rdev, sq_vtx_constant_word2);
+	radeon_ring_write(rdev, 1 << 0);
+	radeon_ring_write(rdev, 0);
+	radeon_ring_write(rdev, 0);
+	radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30);
+
+	if ((rdev->family == CHIP_RV610) ||
+	    (rdev->family == CHIP_RV620) ||
+	    (rdev->family == CHIP_RS780) ||
+	    (rdev->family == CHIP_RS880) ||
+	    (rdev->family == CHIP_RV710))
+		cp_set_surface_sync(rdev,
+				    PACKET3_TC_ACTION_ENA, 48, gpu_addr);
+	else
+		cp_set_surface_sync(rdev,
+				    PACKET3_VC_ACTION_ENA, 48, gpu_addr);
+}
+
+/* emits 9 */
+static void
+set_tex_resource(struct radeon_device *rdev,
+		 int format, int w, int h, int pitch,
+		 u64 gpu_addr)
+{
+	uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4;
+
+	if (h < 1)
+		h = 1;
+
+	sq_tex_resource_word0 = (1 << 0);
+	sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) |
+				  ((w - 1) << 19));
+
+	sq_tex_resource_word1 = (format << 26);
+	sq_tex_resource_word1 |= ((h - 1) << 0);
+
+	sq_tex_resource_word4 = ((1 << 14) |
+				 (0 << 16) |
+				 (1 << 19) |
+				 (2 << 22) |
+				 (3 << 25));
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7));
+	radeon_ring_write(rdev, 0);
+	radeon_ring_write(rdev, sq_tex_resource_word0);
+	radeon_ring_write(rdev, sq_tex_resource_word1);
+	radeon_ring_write(rdev, gpu_addr >> 8);
+	radeon_ring_write(rdev, gpu_addr >> 8);
+	radeon_ring_write(rdev, sq_tex_resource_word4);
+	radeon_ring_write(rdev, 0);
+	radeon_ring_write(rdev, SQ_TEX_VTX_VALID_TEXTURE << 30);
+}
+
+/* emits 12 */
+static void
+set_scissors(struct radeon_device *rdev, int x1, int y1,
+	     int x2, int y2)
+{
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+	radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, (x1 << 0) | (y1 << 16));
+	radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+	radeon_ring_write(rdev, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31));
+	radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
+	radeon_ring_write(rdev, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31));
+	radeon_ring_write(rdev, (x2 << 0) | (y2 << 16));
+}
+
+/* emits 10 */
+static void
+draw_auto(struct radeon_device *rdev)
+{
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+	radeon_ring_write(rdev, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, DI_PT_RECTLIST);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0));
+	radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0));
+	radeon_ring_write(rdev, 1);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1));
+	radeon_ring_write(rdev, 3);
+	radeon_ring_write(rdev, DI_SRC_SEL_AUTO_INDEX);
+
+}
+
+/* emits 14 */
+static void
+set_default_state(struct radeon_device *rdev)
+{
+	u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2;
+	u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2;
+	int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs;
+	int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads;
+	int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
+	u64 gpu_addr;
+	int dwords;
+
+	switch (rdev->family) {
+	case CHIP_R600:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV630:
+	case CHIP_RV635:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 144;
+		num_vs_threads = 40;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV610:
+	case CHIP_RV620:
+	case CHIP_RS780:
+	case CHIP_RS880:
+	default:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV670:
+		num_ps_gprs = 144;
+		num_vs_gprs = 40;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 136;
+		num_vs_threads = 48;
+		num_gs_threads = 4;
+		num_es_threads = 4;
+		num_ps_stack_entries = 40;
+		num_vs_stack_entries = 40;
+		num_gs_stack_entries = 32;
+		num_es_stack_entries = 16;
+		break;
+	case CHIP_RV770:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 188;
+		num_vs_threads = 60;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 256;
+		num_vs_stack_entries = 256;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV730:
+	case CHIP_RV740:
+		num_ps_gprs = 84;
+		num_vs_gprs = 36;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 188;
+		num_vs_threads = 60;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	case CHIP_RV710:
+		num_ps_gprs = 192;
+		num_vs_gprs = 56;
+		num_temp_gprs = 4;
+		num_gs_gprs = 0;
+		num_es_gprs = 0;
+		num_ps_threads = 144;
+		num_vs_threads = 48;
+		num_gs_threads = 0;
+		num_es_threads = 0;
+		num_ps_stack_entries = 128;
+		num_vs_stack_entries = 128;
+		num_gs_stack_entries = 0;
+		num_es_stack_entries = 0;
+		break;
+	}
+
+	if ((rdev->family == CHIP_RV610) ||
+	    (rdev->family == CHIP_RV620) ||
+	    (rdev->family == CHIP_RS780) ||
+	    (rdev->family == CHIP_RS780) ||
+	    (rdev->family == CHIP_RV710))
+		sq_config = 0;
+	else
+		sq_config = VC_ENABLE;
+
+	sq_config |= (DX9_CONSTS |
+		      ALU_INST_PREFER_VECTOR |
+		      PS_PRIO(0) |
+		      VS_PRIO(1) |
+		      GS_PRIO(2) |
+		      ES_PRIO(3));
+
+	sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) |
+				  NUM_VS_GPRS(num_vs_gprs) |
+				  NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
+	sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) |
+				  NUM_ES_GPRS(num_es_gprs));
+	sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) |
+				   NUM_VS_THREADS(num_vs_threads) |
+				   NUM_GS_THREADS(num_gs_threads) |
+				   NUM_ES_THREADS(num_es_threads));
+	sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
+				    NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
+	sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
+				    NUM_ES_STACK_ENTRIES(num_es_stack_entries));
+
+	/* emit an IB pointing at default state */
+	dwords = (rdev->r600_blit.state_len + 0xf) & ~0xf;
+	gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
+	radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
+	radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC);
+	radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
+	radeon_ring_write(rdev, dwords);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
+	radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
+	/* SQ config */
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 6));
+	radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, sq_config);
+	radeon_ring_write(rdev, sq_gpr_resource_mgmt_1);
+	radeon_ring_write(rdev, sq_gpr_resource_mgmt_2);
+	radeon_ring_write(rdev, sq_thread_resource_mgmt);
+	radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
+	radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
+}
+
+static inline uint32_t i2f(uint32_t input)
+{
+	u32 result, i, exponent, fraction;
+
+	if ((input & 0x3fff) == 0)
+		result = 0; /* 0 is a special case */
+	else {
+		exponent = 140; /* exponent biased by 127; */
+		fraction = (input & 0x3fff) << 10; /* cheat and only
+						      handle numbers below 2^^15 */
+		for (i = 0; i < 14; i++) {
+			if (fraction & 0x800000)
+				break;
+			else {
+				fraction = fraction << 1; /* keep
+							     shifting left until top bit = 1 */
+				exponent = exponent - 1;
+			}
+		}
+		result = exponent << 23 | (fraction & 0x7fffff); /* mask
+								    off top bit; assumed 1 */
+	}
+	return result;
+}
+
+int r600_blit_init(struct radeon_device *rdev)
+{
+	u32 obj_size;
+	int r, dwords;
+	void *ptr;
+	u32 packet2s[16];
+	int num_packet2s = 0;
+
+	rdev->r600_blit.state_offset = 0;
+
+	if (rdev->family >= CHIP_RV770)
+		rdev->r600_blit.state_len = r7xx_default_size;
+	else
+		rdev->r600_blit.state_len = r6xx_default_size;
+
+	dwords = rdev->r600_blit.state_len;
+	while (dwords & 0xf) {
+		packet2s[num_packet2s++] = PACKET2(0);
+		dwords++;
+	}
+
+	obj_size = dwords * 4;
+	obj_size = ALIGN(obj_size, 256);
+
+	rdev->r600_blit.vs_offset = obj_size;
+	obj_size += r6xx_vs_size * 4;
+	obj_size = ALIGN(obj_size, 256);
+
+	rdev->r600_blit.ps_offset = obj_size;
+	obj_size += r6xx_ps_size * 4;
+	obj_size = ALIGN(obj_size, 256);
+
+	r = radeon_object_create(rdev, NULL, obj_size,
+				 true, RADEON_GEM_DOMAIN_VRAM,
+				 false, &rdev->r600_blit.shader_obj);
+	if (r) {
+		DRM_ERROR("r600 failed to allocate shader\n");
+		return r;
+	}
+
+	DRM_DEBUG("r6xx blit allocated bo %08x vs %08x ps %08x\n",
+		  obj_size,
+		  rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset);
+
+	r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr);
+	if (r) {
+		DRM_ERROR("failed to map blit object %d\n", r);
+		return r;
+	}
+
+	if (rdev->family >= CHIP_RV770)
+		memcpy_toio(ptr + rdev->r600_blit.state_offset,
+			    r7xx_default_state, rdev->r600_blit.state_len * 4);
+	else
+		memcpy_toio(ptr + rdev->r600_blit.state_offset,
+			    r6xx_default_state, rdev->r600_blit.state_len * 4);
+	if (num_packet2s)
+		memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
+			    packet2s, num_packet2s * 4);
+
+
+	memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4);
+	memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4);
+
+	radeon_object_kunmap(rdev->r600_blit.shader_obj);
+	return 0;
+}
+
+void r600_blit_fini(struct radeon_device *rdev)
+{
+	radeon_object_unpin(rdev->r600_blit.shader_obj);
+	radeon_object_unref(&rdev->r600_blit.shader_obj);
+}
+
+int r600_vb_ib_get(struct radeon_device *rdev)
+{
+	int r;
+	r = radeon_ib_get(rdev, &rdev->r600_blit.vb_ib);
+	if (r) {
+		DRM_ERROR("failed to get IB for vertex buffer\n");
+		return r;
+	}
+
+	rdev->r600_blit.vb_total = 64*1024;
+	rdev->r600_blit.vb_used = 0;
+	return 0;
+}
+
+void r600_vb_ib_put(struct radeon_device *rdev)
+{
+	radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
+	mutex_lock(&rdev->ib_pool.mutex);
+	list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs);
+	mutex_unlock(&rdev->ib_pool.mutex);
+	radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
+}
+
+int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
+{
+	int r;
+	int ring_size, line_size;
+	int max_size;
+	/* loops of emits 64 + fence emit possible */
+	int dwords_per_loop = 76, num_loops;
+
+	r = r600_vb_ib_get(rdev);
+	WARN_ON(r);
+
+	/* set_render_target emits 2 extra dwords on rv6xx */
+	if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
+		dwords_per_loop += 2;
+
+	/* 8 bpp vs 32 bpp for xfer unit */
+	if (size_bytes & 3)
+		line_size = 8192;
+	else
+		line_size = 8192*4;
+
+	max_size = 8192 * line_size;
+
+	/* major loops cover the max size transfer */
+	num_loops = ((size_bytes + max_size) / max_size);
+	/* minor loops cover the extra non aligned bits */
+	num_loops += ((size_bytes % line_size) ? 1 : 0);
+	/* calculate number of loops correctly */
+	ring_size = num_loops * dwords_per_loop;
+	/* set default  + shaders */
+	ring_size += 40; /* shaders + def state */
+	ring_size += 3; /* fence emit for VB IB */
+	ring_size += 5; /* done copy */
+	ring_size += 3; /* fence emit for done copy */
+	r = radeon_ring_lock(rdev, ring_size);
+	WARN_ON(r);
+
+	set_default_state(rdev); /* 14 */
+	set_shaders(rdev); /* 26 */
+	return 0;
+}
+
+void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence)
+{
+	int r;
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
+	radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
+	/* wait for 3D idle clean */
+	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+	radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
+	radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
+
+	if (rdev->r600_blit.vb_ib)
+		r600_vb_ib_put(rdev);
+
+	if (fence)
+		r = radeon_fence_emit(rdev, fence);
+
+	radeon_ring_unlock_commit(rdev);
+}
+
+void r600_kms_blit_copy(struct radeon_device *rdev,
+			u64 src_gpu_addr, u64 dst_gpu_addr,
+			int size_bytes)
+{
+	int max_bytes;
+	u64 vb_gpu_addr;
+	u32 *vb;
+
+	DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
+		  size_bytes, rdev->r600_blit.vb_used);
+	vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
+	if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
+		max_bytes = 8192;
+
+		while (size_bytes) {
+			int cur_size = size_bytes;
+			int src_x = src_gpu_addr & 255;
+			int dst_x = dst_gpu_addr & 255;
+			int h = 1;
+			src_gpu_addr = src_gpu_addr & ~255;
+			dst_gpu_addr = dst_gpu_addr & ~255;
+
+			if (!src_x && !dst_x) {
+				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
+				if (h == 0)
+					h = 1;
+				else
+					cur_size = max_bytes;
+			} else {
+				if (cur_size > max_bytes)
+					cur_size = max_bytes;
+				if (cur_size > (max_bytes - dst_x))
+					cur_size = (max_bytes - dst_x);
+				if (cur_size > (max_bytes - src_x))
+					cur_size = (max_bytes - src_x);
+			}
+
+			if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) {
+				WARN_ON(1);
+
+#if 0
+				r600_vb_ib_put(rdev);
+
+				r600_nomm_put_vb(dev);
+				r600_nomm_get_vb(dev);
+				if (!dev_priv->blit_vb)
+					return;
+				set_shaders(dev);
+				vb = r600_nomm_get_vb_ptr(dev);
+#endif
+			}
+
+			vb[0] = i2f(dst_x);
+			vb[1] = 0;
+			vb[2] = i2f(src_x);
+			vb[3] = 0;
+
+			vb[4] = i2f(dst_x);
+			vb[5] = i2f(h);
+			vb[6] = i2f(src_x);
+			vb[7] = i2f(h);
+
+			vb[8] = i2f(dst_x + cur_size);
+			vb[9] = i2f(h);
+			vb[10] = i2f(src_x + cur_size);
+			vb[11] = i2f(h);
+
+			/* src 9 */
+			set_tex_resource(rdev, FMT_8,
+					 src_x + cur_size, h, src_x + cur_size,
+					 src_gpu_addr);
+
+			/* 5 */
+			cp_set_surface_sync(rdev,
+					    PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
+
+			/* dst 23 */
+			set_render_target(rdev, COLOR_8,
+					  dst_x + cur_size, h,
+					  dst_gpu_addr);
+
+			/* scissors 12 */
+			set_scissors(rdev, dst_x, 0, dst_x + cur_size, h);
+
+			/* 14 */
+			vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
+			set_vtx_resource(rdev, vb_gpu_addr);
+
+			/* draw 10 */
+			draw_auto(rdev);
+
+			/* 5 */
+			cp_set_surface_sync(rdev,
+					    PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
+					    cur_size * h, dst_gpu_addr);
+
+			vb += 12;
+			rdev->r600_blit.vb_used += 12 * 4;
+
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
+			size_bytes -= cur_size * h;
+		}
+	} else {
+		max_bytes = 8192 * 4;
+
+		while (size_bytes) {
+			int cur_size = size_bytes;
+			int src_x = (src_gpu_addr & 255);
+			int dst_x = (dst_gpu_addr & 255);
+			int h = 1;
+			src_gpu_addr = src_gpu_addr & ~255;
+			dst_gpu_addr = dst_gpu_addr & ~255;
+
+			if (!src_x && !dst_x) {
+				h = (cur_size / max_bytes);
+				if (h > 8192)
+					h = 8192;
+				if (h == 0)
+					h = 1;
+				else
+					cur_size = max_bytes;
+			} else {
+				if (cur_size > max_bytes)
+					cur_size = max_bytes;
+				if (cur_size > (max_bytes - dst_x))
+					cur_size = (max_bytes - dst_x);
+				if (cur_size > (max_bytes - src_x))
+					cur_size = (max_bytes - src_x);
+			}
+
+			if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) {
+				WARN_ON(1);
+			}
+#if 0
+			if ((rdev->blit_vb->used + 48) > rdev->blit_vb->total) {
+				r600_nomm_put_vb(dev);
+				r600_nomm_get_vb(dev);
+				if (!rdev->blit_vb)
+					return;
+
+				set_shaders(dev);
+				vb = r600_nomm_get_vb_ptr(dev);
+			}
+#endif
+
+			vb[0] = i2f(dst_x / 4);
+			vb[1] = 0;
+			vb[2] = i2f(src_x / 4);
+			vb[3] = 0;
+
+			vb[4] = i2f(dst_x / 4);
+			vb[5] = i2f(h);
+			vb[6] = i2f(src_x / 4);
+			vb[7] = i2f(h);
+
+			vb[8] = i2f((dst_x + cur_size) / 4);
+			vb[9] = i2f(h);
+			vb[10] = i2f((src_x + cur_size) / 4);
+			vb[11] = i2f(h);
+
+			/* src 9 */
+			set_tex_resource(rdev, FMT_8_8_8_8,
+					 (src_x + cur_size) / 4,
+					 h, (src_x + cur_size) / 4,
+					 src_gpu_addr);
+			/* 5 */
+			cp_set_surface_sync(rdev,
+					    PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr);
+
+			/* dst 23 */
+			set_render_target(rdev, COLOR_8_8_8_8,
+					  dst_x + cur_size, h,
+					  dst_gpu_addr);
+
+			/* scissors 12  */
+			set_scissors(rdev, (dst_x / 4), 0, (dst_x + cur_size / 4), h);
+
+			/* Vertex buffer setup 14 */
+			vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
+			set_vtx_resource(rdev, vb_gpu_addr);
+
+			/* draw 10 */
+			draw_auto(rdev);
+
+			/* 5 */
+			cp_set_surface_sync(rdev,
+					    PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
+					    cur_size * h, dst_gpu_addr);
+
+			/* 78 ring dwords per loop */
+			vb += 12;
+			rdev->r600_blit.vb_used += 12 * 4;
+
+			src_gpu_addr += cur_size * h;
+			dst_gpu_addr += cur_size * h;
+			size_bytes -= cur_size * h;
+		}
+	}
+}
+
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c
new file mode 100644
index 0000000..d745e81
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c
@@ -0,0 +1,1072 @@
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+const u32 r6xx_default_state[] =
+{
+	0xc0002400,
+	0x00000000,
+	0xc0012800,
+	0x80000000,
+	0x80000000,
+	0xc0004600,
+	0x00000016,
+	0xc0016800,
+	0x00000010,
+	0x00028000,
+	0xc0016800,
+	0x00000010,
+	0x00008000,
+	0xc0016800,
+	0x00000542,
+	0x07000003,
+	0xc0016800,
+	0x000005c5,
+	0x00000000,
+	0xc0016800,
+	0x00000363,
+	0x00000000,
+	0xc0016800,
+	0x0000060c,
+	0x82000000,
+	0xc0016800,
+	0x0000060e,
+	0x01020204,
+	0xc0016f00,
+	0x00000000,
+	0x00000000,
+	0xc0016f00,
+	0x00000001,
+	0x00000000,
+	0xc0096900,
+	0x0000022a,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000004,
+	0x00000000,
+	0xc0016900,
+	0x0000000a,
+	0x00000000,
+	0xc0016900,
+	0x0000000b,
+	0x00000000,
+	0xc0016900,
+	0x0000010c,
+	0x00000000,
+	0xc0016900,
+	0x0000010d,
+	0x00000000,
+	0xc0016900,
+	0x00000200,
+	0x00000000,
+	0xc0016900,
+	0x00000343,
+	0x00000060,
+	0xc0016900,
+	0x00000344,
+	0x00000040,
+	0xc0016900,
+	0x00000351,
+	0x0000aa00,
+	0xc0016900,
+	0x00000104,
+	0x00000000,
+	0xc0016900,
+	0x0000010e,
+	0x00000000,
+	0xc0046900,
+	0x00000105,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0036900,
+	0x00000109,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0046900,
+	0x0000030c,
+	0x01000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0046900,
+	0x00000048,
+	0x3f800000,
+	0x00000000,
+	0x3f800000,
+	0x3f800000,
+	0xc0016900,
+	0x0000008e,
+	0x0000000f,
+	0xc0016900,
+	0x00000080,
+	0x00000000,
+	0xc0016900,
+	0x00000083,
+	0x0000ffff,
+	0xc0016900,
+	0x00000084,
+	0x00000000,
+	0xc0016900,
+	0x00000085,
+	0x20002000,
+	0xc0016900,
+	0x00000086,
+	0x00000000,
+	0xc0016900,
+	0x00000087,
+	0x20002000,
+	0xc0016900,
+	0x00000088,
+	0x00000000,
+	0xc0016900,
+	0x00000089,
+	0x20002000,
+	0xc0016900,
+	0x0000008a,
+	0x00000000,
+	0xc0016900,
+	0x0000008b,
+	0x20002000,
+	0xc0016900,
+	0x0000008c,
+	0x00000000,
+	0xc0016900,
+	0x00000094,
+	0x80000000,
+	0xc0016900,
+	0x00000095,
+	0x20002000,
+	0xc0026900,
+	0x000000b4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000096,
+	0x80000000,
+	0xc0016900,
+	0x00000097,
+	0x20002000,
+	0xc0026900,
+	0x000000b6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000098,
+	0x80000000,
+	0xc0016900,
+	0x00000099,
+	0x20002000,
+	0xc0026900,
+	0x000000b8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009a,
+	0x80000000,
+	0xc0016900,
+	0x0000009b,
+	0x20002000,
+	0xc0026900,
+	0x000000ba,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009c,
+	0x80000000,
+	0xc0016900,
+	0x0000009d,
+	0x20002000,
+	0xc0026900,
+	0x000000bc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009e,
+	0x80000000,
+	0xc0016900,
+	0x0000009f,
+	0x20002000,
+	0xc0026900,
+	0x000000be,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a0,
+	0x80000000,
+	0xc0016900,
+	0x000000a1,
+	0x20002000,
+	0xc0026900,
+	0x000000c0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a2,
+	0x80000000,
+	0xc0016900,
+	0x000000a3,
+	0x20002000,
+	0xc0026900,
+	0x000000c2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a4,
+	0x80000000,
+	0xc0016900,
+	0x000000a5,
+	0x20002000,
+	0xc0026900,
+	0x000000c4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a6,
+	0x80000000,
+	0xc0016900,
+	0x000000a7,
+	0x20002000,
+	0xc0026900,
+	0x000000c6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a8,
+	0x80000000,
+	0xc0016900,
+	0x000000a9,
+	0x20002000,
+	0xc0026900,
+	0x000000c8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000aa,
+	0x80000000,
+	0xc0016900,
+	0x000000ab,
+	0x20002000,
+	0xc0026900,
+	0x000000ca,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ac,
+	0x80000000,
+	0xc0016900,
+	0x000000ad,
+	0x20002000,
+	0xc0026900,
+	0x000000cc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ae,
+	0x80000000,
+	0xc0016900,
+	0x000000af,
+	0x20002000,
+	0xc0026900,
+	0x000000ce,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b0,
+	0x80000000,
+	0xc0016900,
+	0x000000b1,
+	0x20002000,
+	0xc0026900,
+	0x000000d0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b2,
+	0x80000000,
+	0xc0016900,
+	0x000000b3,
+	0x20002000,
+	0xc0026900,
+	0x000000d2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000293,
+	0x00004010,
+	0xc0016900,
+	0x00000300,
+	0x00000000,
+	0xc0016900,
+	0x00000301,
+	0x00000000,
+	0xc0016900,
+	0x00000312,
+	0xffffffff,
+	0xc0016900,
+	0x00000307,
+	0x00000000,
+	0xc0016900,
+	0x00000308,
+	0x00000000,
+	0xc0016900,
+	0x00000283,
+	0x00000000,
+	0xc0016900,
+	0x00000292,
+	0x00000000,
+	0xc0066900,
+	0x0000010f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000000,
+	0xc0016900,
+	0x00000207,
+	0x00000000,
+	0xc0016900,
+	0x00000208,
+	0x00000000,
+	0xc0046900,
+	0x00000303,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0xc0016900,
+	0x00000205,
+	0x00000004,
+	0xc0016900,
+	0x00000280,
+	0x00000000,
+	0xc0016900,
+	0x00000281,
+	0x00000000,
+	0xc0016900,
+	0x0000037e,
+	0x00000000,
+	0xc0016900,
+	0x00000382,
+	0x00000000,
+	0xc0016900,
+	0x00000380,
+	0x00000000,
+	0xc0016900,
+	0x00000383,
+	0x00000000,
+	0xc0016900,
+	0x00000381,
+	0x00000000,
+	0xc0016900,
+	0x00000282,
+	0x00000008,
+	0xc0016900,
+	0x00000302,
+	0x0000002d,
+	0xc0016900,
+	0x0000037f,
+	0x00000000,
+	0xc0016900,
+	0x000001b2,
+	0x00000000,
+	0xc0016900,
+	0x000001b6,
+	0x00000000,
+	0xc0016900,
+	0x000001b7,
+	0x00000000,
+	0xc0016900,
+	0x000001b8,
+	0x00000000,
+	0xc0016900,
+	0x000001b9,
+	0x00000000,
+	0xc0016900,
+	0x00000225,
+	0x00000000,
+	0xc0016900,
+	0x00000229,
+	0x00000000,
+	0xc0016900,
+	0x00000237,
+	0x00000000,
+	0xc0016900,
+	0x00000100,
+	0x00000800,
+	0xc0016900,
+	0x00000101,
+	0x00000000,
+	0xc0016900,
+	0x00000102,
+	0x00000000,
+	0xc0016900,
+	0x000002a8,
+	0x00000000,
+	0xc0016900,
+	0x000002a9,
+	0x00000000,
+	0xc0016900,
+	0x00000103,
+	0x00000000,
+	0xc0016900,
+	0x00000284,
+	0x00000000,
+	0xc0016900,
+	0x00000290,
+	0x00000000,
+	0xc0016900,
+	0x00000285,
+	0x00000000,
+	0xc0016900,
+	0x00000286,
+	0x00000000,
+	0xc0016900,
+	0x00000287,
+	0x00000000,
+	0xc0016900,
+	0x00000288,
+	0x00000000,
+	0xc0016900,
+	0x00000289,
+	0x00000000,
+	0xc0016900,
+	0x0000028a,
+	0x00000000,
+	0xc0016900,
+	0x0000028b,
+	0x00000000,
+	0xc0016900,
+	0x0000028c,
+	0x00000000,
+	0xc0016900,
+	0x0000028d,
+	0x00000000,
+	0xc0016900,
+	0x0000028e,
+	0x00000000,
+	0xc0016900,
+	0x0000028f,
+	0x00000000,
+	0xc0016900,
+	0x000002a1,
+	0x00000000,
+	0xc0016900,
+	0x000002a5,
+	0x00000000,
+	0xc0016900,
+	0x000002ac,
+	0x00000000,
+	0xc0016900,
+	0x000002ad,
+	0x00000000,
+	0xc0016900,
+	0x000002ae,
+	0x00000000,
+	0xc0016900,
+	0x000002c8,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000100,
+	0xc0016900,
+	0x00000204,
+	0x00010000,
+	0xc0036e00,
+	0x00000000,
+	0x00000012,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x0000008f,
+	0x0000000f,
+	0xc0016900,
+	0x000001e8,
+	0x00000001,
+	0xc0016900,
+	0x00000202,
+	0x00cc0000,
+	0xc0016900,
+	0x00000205,
+	0x00000244,
+	0xc0016900,
+	0x00000203,
+	0x00000210,
+	0xc0016900,
+	0x000001b1,
+	0x00000000,
+	0xc0016900,
+	0x00000185,
+	0x00000000,
+	0xc0016900,
+	0x000001b3,
+	0x00000001,
+	0xc0016900,
+	0x000001b4,
+	0x00000000,
+	0xc0016900,
+	0x00000191,
+	0x00000b00,
+	0xc0016900,
+	0x000001b5,
+	0x00000000,
+};
+
+const u32 r7xx_default_state[] =
+{
+	0xc0012800,
+	0x80000000,
+	0x80000000,
+	0xc0004600,
+	0x00000016,
+	0xc0016800,
+	0x00000010,
+	0x00028000,
+	0xc0016800,
+	0x00000010,
+	0x00008000,
+	0xc0016800,
+	0x00000542,
+	0x07000002,
+	0xc0016800,
+	0x000005c5,
+	0x00000000,
+	0xc0016800,
+	0x00000363,
+	0x00004000,
+	0xc0016800,
+	0x0000060c,
+	0x00000000,
+	0xc0016800,
+	0x0000060e,
+	0x00420204,
+	0xc0016f00,
+	0x00000000,
+	0x00000000,
+	0xc0016f00,
+	0x00000001,
+	0x00000000,
+	0xc0096900,
+	0x0000022a,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000004,
+	0x00000000,
+	0xc0016900,
+	0x0000000a,
+	0x00000000,
+	0xc0016900,
+	0x0000000b,
+	0x00000000,
+	0xc0016900,
+	0x0000010c,
+	0x00000000,
+	0xc0016900,
+	0x0000010d,
+	0x00000000,
+	0xc0016900,
+	0x00000200,
+	0x00000000,
+	0xc0016900,
+	0x00000343,
+	0x00000060,
+	0xc0016900,
+	0x00000344,
+	0x00000000,
+	0xc0016900,
+	0x00000351,
+	0x0000aa00,
+	0xc0016900,
+	0x00000104,
+	0x00000000,
+	0xc0016900,
+	0x0000010e,
+	0x00000000,
+	0xc0046900,
+	0x00000105,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0046900,
+	0x0000030c,
+	0x01000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x0000008e,
+	0x0000000f,
+	0xc0016900,
+	0x00000080,
+	0x00000000,
+	0xc0016900,
+	0x00000083,
+	0x0000ffff,
+	0xc0016900,
+	0x00000084,
+	0x00000000,
+	0xc0016900,
+	0x00000085,
+	0x20002000,
+	0xc0016900,
+	0x00000086,
+	0x00000000,
+	0xc0016900,
+	0x00000087,
+	0x20002000,
+	0xc0016900,
+	0x00000088,
+	0x00000000,
+	0xc0016900,
+	0x00000089,
+	0x20002000,
+	0xc0016900,
+	0x0000008a,
+	0x00000000,
+	0xc0016900,
+	0x0000008b,
+	0x20002000,
+	0xc0016900,
+	0x0000008c,
+	0xaaaaaaaa,
+	0xc0016900,
+	0x00000094,
+	0x80000000,
+	0xc0016900,
+	0x00000095,
+	0x20002000,
+	0xc0026900,
+	0x000000b4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000096,
+	0x80000000,
+	0xc0016900,
+	0x00000097,
+	0x20002000,
+	0xc0026900,
+	0x000000b6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000098,
+	0x80000000,
+	0xc0016900,
+	0x00000099,
+	0x20002000,
+	0xc0026900,
+	0x000000b8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009a,
+	0x80000000,
+	0xc0016900,
+	0x0000009b,
+	0x20002000,
+	0xc0026900,
+	0x000000ba,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009c,
+	0x80000000,
+	0xc0016900,
+	0x0000009d,
+	0x20002000,
+	0xc0026900,
+	0x000000bc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x0000009e,
+	0x80000000,
+	0xc0016900,
+	0x0000009f,
+	0x20002000,
+	0xc0026900,
+	0x000000be,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a0,
+	0x80000000,
+	0xc0016900,
+	0x000000a1,
+	0x20002000,
+	0xc0026900,
+	0x000000c0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a2,
+	0x80000000,
+	0xc0016900,
+	0x000000a3,
+	0x20002000,
+	0xc0026900,
+	0x000000c2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a4,
+	0x80000000,
+	0xc0016900,
+	0x000000a5,
+	0x20002000,
+	0xc0026900,
+	0x000000c4,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a6,
+	0x80000000,
+	0xc0016900,
+	0x000000a7,
+	0x20002000,
+	0xc0026900,
+	0x000000c6,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000a8,
+	0x80000000,
+	0xc0016900,
+	0x000000a9,
+	0x20002000,
+	0xc0026900,
+	0x000000c8,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000aa,
+	0x80000000,
+	0xc0016900,
+	0x000000ab,
+	0x20002000,
+	0xc0026900,
+	0x000000ca,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ac,
+	0x80000000,
+	0xc0016900,
+	0x000000ad,
+	0x20002000,
+	0xc0026900,
+	0x000000cc,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000ae,
+	0x80000000,
+	0xc0016900,
+	0x000000af,
+	0x20002000,
+	0xc0026900,
+	0x000000ce,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b0,
+	0x80000000,
+	0xc0016900,
+	0x000000b1,
+	0x20002000,
+	0xc0026900,
+	0x000000d0,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x000000b2,
+	0x80000000,
+	0xc0016900,
+	0x000000b3,
+	0x20002000,
+	0xc0026900,
+	0x000000d2,
+	0x00000000,
+	0x3f800000,
+	0xc0016900,
+	0x00000293,
+	0x00514000,
+	0xc0016900,
+	0x00000300,
+	0x00000000,
+	0xc0016900,
+	0x00000301,
+	0x00000000,
+	0xc0016900,
+	0x00000312,
+	0xffffffff,
+	0xc0016900,
+	0x00000307,
+	0x00000000,
+	0xc0016900,
+	0x00000308,
+	0x00000000,
+	0xc0016900,
+	0x00000283,
+	0x00000000,
+	0xc0016900,
+	0x00000292,
+	0x00000000,
+	0xc0066900,
+	0x0000010f,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000000,
+	0xc0016900,
+	0x00000207,
+	0x00000000,
+	0xc0016900,
+	0x00000208,
+	0x00000000,
+	0xc0046900,
+	0x00000303,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0x3f800000,
+	0xc0016900,
+	0x00000205,
+	0x00000004,
+	0xc0016900,
+	0x00000280,
+	0x00000000,
+	0xc0016900,
+	0x00000281,
+	0x00000000,
+	0xc0016900,
+	0x0000037e,
+	0x00000000,
+	0xc0016900,
+	0x00000382,
+	0x00000000,
+	0xc0016900,
+	0x00000380,
+	0x00000000,
+	0xc0016900,
+	0x00000383,
+	0x00000000,
+	0xc0016900,
+	0x00000381,
+	0x00000000,
+	0xc0016900,
+	0x00000282,
+	0x00000008,
+	0xc0016900,
+	0x00000302,
+	0x0000002d,
+	0xc0016900,
+	0x0000037f,
+	0x00000000,
+	0xc0016900,
+	0x000001b2,
+	0x00000001,
+	0xc0016900,
+	0x000001b6,
+	0x00000000,
+	0xc0016900,
+	0x000001b7,
+	0x00000000,
+	0xc0016900,
+	0x000001b8,
+	0x00000000,
+	0xc0016900,
+	0x000001b9,
+	0x00000000,
+	0xc0016900,
+	0x00000225,
+	0x00000000,
+	0xc0016900,
+	0x00000229,
+	0x00000000,
+	0xc0016900,
+	0x00000237,
+	0x00000000,
+	0xc0016900,
+	0x00000100,
+	0x00000800,
+	0xc0016900,
+	0x00000101,
+	0x00000000,
+	0xc0016900,
+	0x00000102,
+	0x00000000,
+	0xc0016900,
+	0x000002a8,
+	0x00000000,
+	0xc0016900,
+	0x000002a9,
+	0x00000000,
+	0xc0016900,
+	0x00000103,
+	0x00000000,
+	0xc0016900,
+	0x00000284,
+	0x00000000,
+	0xc0016900,
+	0x00000290,
+	0x00000000,
+	0xc0016900,
+	0x00000285,
+	0x00000000,
+	0xc0016900,
+	0x00000286,
+	0x00000000,
+	0xc0016900,
+	0x00000287,
+	0x00000000,
+	0xc0016900,
+	0x00000288,
+	0x00000000,
+	0xc0016900,
+	0x00000289,
+	0x00000000,
+	0xc0016900,
+	0x0000028a,
+	0x00000000,
+	0xc0016900,
+	0x0000028b,
+	0x00000000,
+	0xc0016900,
+	0x0000028c,
+	0x00000000,
+	0xc0016900,
+	0x0000028d,
+	0x00000000,
+	0xc0016900,
+	0x0000028e,
+	0x00000000,
+	0xc0016900,
+	0x0000028f,
+	0x00000000,
+	0xc0016900,
+	0x000002a1,
+	0x00000000,
+	0xc0016900,
+	0x000002a5,
+	0x00000000,
+	0xc0016900,
+	0x000002ac,
+	0x00000000,
+	0xc0016900,
+	0x000002ad,
+	0x00000000,
+	0xc0016900,
+	0x000002ae,
+	0x00000000,
+	0xc0016900,
+	0x000002c8,
+	0x00000000,
+	0xc0016900,
+	0x00000206,
+	0x00000100,
+	0xc0016900,
+	0x00000204,
+	0x00010000,
+	0xc0036e00,
+	0x00000000,
+	0x00000012,
+	0x00000000,
+	0x00000000,
+	0xc0016900,
+	0x0000008f,
+	0x0000000f,
+	0xc0016900,
+	0x000001e8,
+	0x00000001,
+	0xc0016900,
+	0x00000202,
+	0x00cc0000,
+	0xc0016900,
+	0x00000205,
+	0x00000244,
+	0xc0016900,
+	0x00000203,
+	0x00000210,
+	0xc0016900,
+	0x000001b1,
+	0x00000000,
+	0xc0016900,
+	0x00000185,
+	0x00000000,
+	0xc0016900,
+	0x000001b3,
+	0x00000001,
+	0xc0016900,
+	0x000001b4,
+	0x00000000,
+	0xc0016900,
+	0x00000191,
+	0x00000b00,
+	0xc0016900,
+	0x000001b5,
+	0x00000000,
+};
+
+/* same for r6xx/r7xx */
+const u32 r6xx_vs[] =
+{
+	0x00000004,
+	0x81000000,
+	0x0000203c,
+	0x94000b08,
+	0x00004000,
+	0x14200b1a,
+	0x00000000,
+	0x00000000,
+	0x3c000000,
+	0x68cd1000,
+	0x00080000,
+	0x00000000,
+};
+
+const u32 r6xx_ps[] =
+{
+	0x00000002,
+	0x80800000,
+	0x00000000,
+	0x94200688,
+	0x00000010,
+	0x000d1000,
+	0xb0800000,
+	0x00000000,
+};
+
+const u32 r6xx_ps_size = ARRAY_SIZE(r6xx_ps);
+const u32 r6xx_vs_size = ARRAY_SIZE(r6xx_vs);
+const u32 r6xx_default_size = ARRAY_SIZE(r6xx_default_state);
+const u32 r7xx_default_size = ARRAY_SIZE(r7xx_default_state);
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h
new file mode 100644
index 0000000..fdc3b37
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h
@@ -0,0 +1,14 @@
+
+#ifndef R600_BLIT_SHADERS_H
+#define R600_BLIT_SHADERS_H
+
+extern const u32 r6xx_ps[];
+extern const u32 r6xx_vs[];
+extern const u32 r7xx_default_state[];
+extern const u32 r6xx_default_state[];
+
+
+extern const u32 r6xx_ps_size, r6xx_vs_size;
+extern const u32 r6xx_default_size, r7xx_default_size;
+
+#endif
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
index 20f1790..6d5a711 100644
--- a/drivers/gpu/drm/radeon/r600_cp.c
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -31,7 +31,38 @@
 #include "radeon_drm.h"
 #include "radeon_drv.h"
 
-#include "r600_microcode.h"
+#define PFP_UCODE_SIZE 576
+#define PM4_UCODE_SIZE 1792
+#define R700_PFP_UCODE_SIZE 848
+#define R700_PM4_UCODE_SIZE 1360
+
+/* Firmware Names */
+MODULE_FIRMWARE("radeon/R600_pfp.bin");
+MODULE_FIRMWARE("radeon/R600_me.bin");
+MODULE_FIRMWARE("radeon/RV610_pfp.bin");
+MODULE_FIRMWARE("radeon/RV610_me.bin");
+MODULE_FIRMWARE("radeon/RV630_pfp.bin");
+MODULE_FIRMWARE("radeon/RV630_me.bin");
+MODULE_FIRMWARE("radeon/RV620_pfp.bin");
+MODULE_FIRMWARE("radeon/RV620_me.bin");
+MODULE_FIRMWARE("radeon/RV635_pfp.bin");
+MODULE_FIRMWARE("radeon/RV635_me.bin");
+MODULE_FIRMWARE("radeon/RV670_pfp.bin");
+MODULE_FIRMWARE("radeon/RV670_me.bin");
+MODULE_FIRMWARE("radeon/RS780_pfp.bin");
+MODULE_FIRMWARE("radeon/RS780_me.bin");
+MODULE_FIRMWARE("radeon/RV770_pfp.bin");
+MODULE_FIRMWARE("radeon/RV770_me.bin");
+MODULE_FIRMWARE("radeon/RV730_pfp.bin");
+MODULE_FIRMWARE("radeon/RV730_me.bin");
+MODULE_FIRMWARE("radeon/RV710_pfp.bin");
+MODULE_FIRMWARE("radeon/RV710_me.bin");
+
+
+int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
+			unsigned family, u32 *ib, int *l);
+void r600_cs_legacy_init(void);
+
 
 # define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */
 # define ATI_PCIGART_PAGE_MASK		(~(ATI_PCIGART_PAGE_SIZE-1))
@@ -275,11 +306,93 @@ static void r600_vm_init(struct drm_device *dev)
 	r600_vm_flush_gart_range(dev);
 }
 
-/* load r600 microcode */
+static int r600_cp_init_microcode(drm_radeon_private_t *dev_priv)
+{
+	struct platform_device *pdev;
+	const char *chip_name;
+	size_t pfp_req_size, me_req_size;
+	char fw_name[30];
+	int err;
+
+	pdev = platform_device_register_simple("r600_cp", 0, NULL, 0);
+	err = IS_ERR(pdev);
+	if (err) {
+		printk(KERN_ERR "r600_cp: Failed to register firmware\n");
+		return -EINVAL;
+	}
+
+	switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+	case CHIP_R600:  chip_name = "R600";  break;
+	case CHIP_RV610: chip_name = "RV610"; break;
+	case CHIP_RV630: chip_name = "RV630"; break;
+	case CHIP_RV620: chip_name = "RV620"; break;
+	case CHIP_RV635: chip_name = "RV635"; break;
+	case CHIP_RV670: chip_name = "RV670"; break;
+	case CHIP_RS780:
+	case CHIP_RS880: chip_name = "RS780"; break;
+	case CHIP_RV770: chip_name = "RV770"; break;
+	case CHIP_RV730:
+	case CHIP_RV740: chip_name = "RV730"; break;
+	case CHIP_RV710: chip_name = "RV710"; break;
+	default:         BUG();
+	}
+
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
+		pfp_req_size = R700_PFP_UCODE_SIZE * 4;
+		me_req_size = R700_PM4_UCODE_SIZE * 4;
+	} else {
+		pfp_req_size = PFP_UCODE_SIZE * 4;
+		me_req_size = PM4_UCODE_SIZE * 12;
+	}
+
+	DRM_INFO("Loading %s CP Microcode\n", chip_name);
+
+	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
+	err = request_firmware(&dev_priv->pfp_fw, fw_name, &pdev->dev);
+	if (err)
+		goto out;
+	if (dev_priv->pfp_fw->size != pfp_req_size) {
+		printk(KERN_ERR
+		       "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+		       dev_priv->pfp_fw->size, fw_name);
+		err = -EINVAL;
+		goto out;
+	}
+
+	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
+	err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev);
+	if (err)
+		goto out;
+	if (dev_priv->me_fw->size != me_req_size) {
+		printk(KERN_ERR
+		       "r600_cp: Bogus length %zu in firmware \"%s\"\n",
+		       dev_priv->me_fw->size, fw_name);
+		err = -EINVAL;
+	}
+out:
+	platform_device_unregister(pdev);
+
+	if (err) {
+		if (err != -EINVAL)
+			printk(KERN_ERR
+			       "r600_cp: Failed to load firmware \"%s\"\n",
+			       fw_name);
+		release_firmware(dev_priv->pfp_fw);
+		dev_priv->pfp_fw = NULL;
+		release_firmware(dev_priv->me_fw);
+		dev_priv->me_fw = NULL;
+	}
+	return err;
+}
+
 static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
 {
+	const __be32 *fw_data;
 	int i;
 
+	if (!dev_priv->me_fw || !dev_priv->pfp_fw)
+		return;
+
 	r600_do_cp_stop(dev_priv);
 
 	RADEON_WRITE(R600_CP_RB_CNTL,
@@ -292,115 +405,18 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
 	DRM_UDELAY(15000);
 	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
+	fw_data = (const __be32 *)dev_priv->me_fw->data;
 	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+	for (i = 0; i < PM4_UCODE_SIZE * 3; i++)
+		RADEON_WRITE(R600_CP_ME_RAM_DATA,
+			     be32_to_cpup(fw_data++));
 
-	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) {
-		DRM_INFO("Loading R600 CP Microcode\n");
-		for (i = 0; i < PM4_UCODE_SIZE; i++) {
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     R600_cp_microcode[i][0]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     R600_cp_microcode[i][1]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     R600_cp_microcode[i][2]);
-		}
-
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading R600 PFP Microcode\n");
-		for (i = 0; i < PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]);
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) {
-		DRM_INFO("Loading RV610 CP Microcode\n");
-		for (i = 0; i < PM4_UCODE_SIZE; i++) {
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV610_cp_microcode[i][0]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV610_cp_microcode[i][1]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV610_cp_microcode[i][2]);
-		}
-
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV610 PFP Microcode\n");
-		for (i = 0; i < PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]);
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
-		DRM_INFO("Loading RV630 CP Microcode\n");
-		for (i = 0; i < PM4_UCODE_SIZE; i++) {
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV630_cp_microcode[i][0]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV630_cp_microcode[i][1]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV630_cp_microcode[i][2]);
-		}
-
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV630 PFP Microcode\n");
-		for (i = 0; i < PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]);
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) {
-		DRM_INFO("Loading RV620 CP Microcode\n");
-		for (i = 0; i < PM4_UCODE_SIZE; i++) {
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV620_cp_microcode[i][0]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV620_cp_microcode[i][1]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV620_cp_microcode[i][2]);
-		}
-
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV620 PFP Microcode\n");
-		for (i = 0; i < PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]);
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
-		DRM_INFO("Loading RV635 CP Microcode\n");
-		for (i = 0; i < PM4_UCODE_SIZE; i++) {
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV635_cp_microcode[i][0]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV635_cp_microcode[i][1]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV635_cp_microcode[i][2]);
-		}
-
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV635 PFP Microcode\n");
-		for (i = 0; i < PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]);
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) {
-		DRM_INFO("Loading RV670 CP Microcode\n");
-		for (i = 0; i < PM4_UCODE_SIZE; i++) {
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV670_cp_microcode[i][0]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV670_cp_microcode[i][1]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RV670_cp_microcode[i][2]);
-		}
-
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV670 PFP Microcode\n");
-		for (i = 0; i < PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]);
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) ||
-		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) {
-		DRM_INFO("Loading RS780/RS880 CP Microcode\n");
-		for (i = 0; i < PM4_UCODE_SIZE; i++) {
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RS780_cp_microcode[i][0]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RS780_cp_microcode[i][1]);
-			RADEON_WRITE(R600_CP_ME_RAM_DATA,
-				     RS780_cp_microcode[i][2]);
-		}
+	fw_data = (const __be32 *)dev_priv->pfp_fw->data;
+	RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+	for (i = 0; i < PFP_UCODE_SIZE; i++)
+		RADEON_WRITE(R600_CP_PFP_UCODE_DATA,
+			     be32_to_cpup(fw_data++));
 
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RS780/RS880 PFP Microcode\n");
-		for (i = 0; i < PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]);
-	}
 	RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
 	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
 	RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
@@ -459,11 +475,14 @@ static void r700_vm_init(struct drm_device *dev)
 	r600_vm_flush_gart_range(dev);
 }
 
-/* load r600 microcode */
 static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
 {
+	const __be32 *fw_data;
 	int i;
 
+	if (!dev_priv->me_fw || !dev_priv->pfp_fw)
+		return;
+
 	r600_do_cp_stop(dev_priv);
 
 	RADEON_WRITE(R600_CP_RB_CNTL,
@@ -476,48 +495,18 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
 	DRM_UDELAY(15000);
 	RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
 
+	fw_data = (const __be32 *)dev_priv->pfp_fw->data;
+	RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+	for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+		RADEON_WRITE(R600_CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
+	RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
 
-	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) {
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV770/RV790 PFP Microcode\n");
-		for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]);
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-
-		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
-		DRM_INFO("Loading RV770/RV790 CP Microcode\n");
-		for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]);
-		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
-
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730) ||
-		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740)) {
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV730/RV740 PFP Microcode\n");
-		for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]);
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-
-		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
-		DRM_INFO("Loading RV730/RV740 CP Microcode\n");
-		for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]);
-		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
-
-	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) {
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-		DRM_INFO("Loading RV710 PFP Microcode\n");
-		for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]);
-		RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
-
-		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
-		DRM_INFO("Loading RV710 CP Microcode\n");
-		for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
-			RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]);
-		RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+	fw_data = (const __be32 *)dev_priv->me_fw->data;
+	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+	for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+		RADEON_WRITE(R600_CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
+	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
 
-	}
 	RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
 	RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
 	RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
@@ -1874,6 +1863,8 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 
 	DRM_DEBUG("\n");
 
+	mutex_init(&dev_priv->cs_mutex);
+	r600_cs_legacy_init();
 	/* if we require new memory map but we don't have it fail */
 	if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
 		DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
@@ -1905,7 +1896,7 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 	/* Enable vblank on CRTC1 for older X servers
 	 */
 	dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
-
+	dev_priv->do_boxes = 0;
 	dev_priv->cp_mode = init->cp_mode;
 
 	/* We don't support anything other than bus-mastering ring mode,
@@ -1991,11 +1982,11 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 	} else
 #endif
 	{
-		dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+		dev_priv->cp_ring->handle = (void *)(unsigned long)dev_priv->cp_ring->offset;
 		dev_priv->ring_rptr->handle =
-		    (void *)dev_priv->ring_rptr->offset;
+			(void *)(unsigned long)dev_priv->ring_rptr->offset;
 		dev->agp_buffer_map->handle =
-		    (void *)dev->agp_buffer_map->offset;
+			(void *)(unsigned long)dev->agp_buffer_map->offset;
 
 		DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
 			  dev_priv->cp_ring->handle);
@@ -2147,6 +2138,14 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 			r600_vm_init(dev);
 	}
 
+	if (!dev_priv->me_fw || !dev_priv->pfp_fw) {
+		int err = r600_cp_init_microcode(dev_priv);
+		if (err) {
+			DRM_ERROR("Failed to load firmware!\n");
+			r600_do_cleanup_cp(dev);
+			return err;
+		}
+	}
 	if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
 		r700_cp_load_microcode(dev_priv);
 	else
@@ -2291,3 +2290,239 @@ int r600_cp_dispatch_indirect(struct drm_device *dev,
 
 	return 0;
 }
+
+void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_master *master = file_priv->master;
+	struct drm_radeon_master_private *master_priv = master->driver_priv;
+	drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv;
+	int nbox = sarea_priv->nbox;
+	struct drm_clip_rect *pbox = sarea_priv->boxes;
+	int i, cpp, src_pitch, dst_pitch;
+	uint64_t src, dst;
+	RING_LOCALS;
+	DRM_DEBUG("\n");
+
+	if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888)
+		cpp = 4;
+	else
+		cpp = 2;
+
+	if (sarea_priv->pfCurrentPage == 0) {
+		src_pitch = dev_priv->back_pitch;
+		dst_pitch = dev_priv->front_pitch;
+		src = dev_priv->back_offset + dev_priv->fb_location;
+		dst = dev_priv->front_offset + dev_priv->fb_location;
+	} else {
+		src_pitch = dev_priv->front_pitch;
+		dst_pitch = dev_priv->back_pitch;
+		src = dev_priv->front_offset + dev_priv->fb_location;
+		dst = dev_priv->back_offset + dev_priv->fb_location;
+	}
+
+	if (r600_prepare_blit_copy(dev, file_priv)) {
+		DRM_ERROR("unable to allocate vertex buffer for swap buffer\n");
+		return;
+	}
+	for (i = 0; i < nbox; i++) {
+		int x = pbox[i].x1;
+		int y = pbox[i].y1;
+		int w = pbox[i].x2 - x;
+		int h = pbox[i].y2 - y;
+
+		DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
+
+		r600_blit_swap(dev,
+			       src, dst,
+			       x, y, x, y, w, h,
+			       src_pitch, dst_pitch, cpp);
+	}
+	r600_done_blit_copy(dev);
+
+	/* Increment the frame counter.  The client-side 3D driver must
+	 * throttle the framerate by waiting for this value before
+	 * performing the swapbuffer ioctl.
+	 */
+	sarea_priv->last_frame++;
+
+	BEGIN_RING(3);
+	R600_FRAME_AGE(sarea_priv->last_frame);
+	ADVANCE_RING();
+}
+
+int r600_cp_dispatch_texture(struct drm_device *dev,
+			     struct drm_file *file_priv,
+			     drm_radeon_texture_t *tex,
+			     drm_radeon_tex_image_t *image)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	struct drm_buf *buf;
+	u32 *buffer;
+	const u8 __user *data;
+	int size, pass_size;
+	u64 src_offset, dst_offset;
+
+	if (!radeon_check_offset(dev_priv, tex->offset)) {
+		DRM_ERROR("Invalid destination offset\n");
+		return -EINVAL;
+	}
+
+	/* this might fail for zero-sized uploads - are those illegal? */
+	if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) {
+		DRM_ERROR("Invalid final destination offset\n");
+		return -EINVAL;
+	}
+
+	size = tex->height * tex->pitch;
+
+	if (size == 0)
+		return 0;
+
+	dst_offset = tex->offset;
+
+	if (r600_prepare_blit_copy(dev, file_priv)) {
+		DRM_ERROR("unable to allocate vertex buffer for swap buffer\n");
+		return -EAGAIN;
+	}
+	do {
+		data = (const u8 __user *)image->data;
+		pass_size = size;
+
+		buf = radeon_freelist_get(dev);
+		if (!buf) {
+			DRM_DEBUG("EAGAIN\n");
+			if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
+				return -EFAULT;
+			return -EAGAIN;
+		}
+
+		if (pass_size > buf->total)
+			pass_size = buf->total;
+
+		/* Dispatch the indirect buffer.
+		 */
+		buffer =
+		    (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
+
+		if (DRM_COPY_FROM_USER(buffer, data, pass_size)) {
+			DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size);
+			return -EFAULT;
+		}
+
+		buf->file_priv = file_priv;
+		buf->used = pass_size;
+		src_offset = dev_priv->gart_buffers_offset + buf->offset;
+
+		r600_blit_copy(dev, src_offset, dst_offset, pass_size);
+
+		radeon_cp_discard_buffer(dev, file_priv->master, buf);
+
+		/* Update the input parameters for next time */
+		image->data = (const u8 __user *)image->data + pass_size;
+		dst_offset += pass_size;
+		size -= pass_size;
+	} while (size > 0);
+	r600_done_blit_copy(dev);
+
+	return 0;
+}
+
+/*
+ * Legacy cs ioctl
+ */
+static u32 radeon_cs_id_get(struct drm_radeon_private *radeon)
+{
+	/* FIXME: check if wrap affect last reported wrap & sequence */
+	radeon->cs_id_scnt = (radeon->cs_id_scnt + 1) & 0x00FFFFFF;
+	if (!radeon->cs_id_scnt) {
+		/* increment wrap counter */
+		radeon->cs_id_wcnt += 0x01000000;
+		/* valid sequence counter start at 1 */
+		radeon->cs_id_scnt = 1;
+	}
+	return (radeon->cs_id_scnt | radeon->cs_id_wcnt);
+}
+
+static void r600_cs_id_emit(drm_radeon_private_t *dev_priv, u32 *id)
+{
+	RING_LOCALS;
+
+	*id = radeon_cs_id_get(dev_priv);
+
+	/* SCRATCH 2 */
+	BEGIN_RING(3);
+	R600_CLEAR_AGE(*id);
+	ADVANCE_RING();
+	COMMIT_RING();
+}
+
+static int r600_ib_get(struct drm_device *dev,
+			struct drm_file *fpriv,
+			struct drm_buf **buffer)
+{
+	struct drm_buf *buf;
+
+	*buffer = NULL;
+	buf = radeon_freelist_get(dev);
+	if (!buf) {
+		return -EBUSY;
+	}
+	buf->file_priv = fpriv;
+	*buffer = buf;
+	return 0;
+}
+
+static void r600_ib_free(struct drm_device *dev, struct drm_buf *buf,
+			struct drm_file *fpriv, int l, int r)
+{
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+
+	if (buf) {
+		if (!r)
+			r600_cp_dispatch_indirect(dev, buf, 0, l * 4);
+		radeon_cp_discard_buffer(dev, fpriv->master, buf);
+		COMMIT_RING();
+	}
+}
+
+int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv)
+{
+	struct drm_radeon_private *dev_priv = dev->dev_private;
+	struct drm_radeon_cs *cs = data;
+	struct drm_buf *buf;
+	unsigned family;
+	int l, r = 0;
+	u32 *ib, cs_id = 0;
+
+	if (dev_priv == NULL) {
+		DRM_ERROR("called with no initialization\n");
+		return -EINVAL;
+	}
+	family = dev_priv->flags & RADEON_FAMILY_MASK;
+	if (family < CHIP_R600) {
+		DRM_ERROR("cs ioctl valid only for R6XX & R7XX in legacy mode\n");
+		return -EINVAL;
+	}
+	mutex_lock(&dev_priv->cs_mutex);
+	/* get ib */
+	r = r600_ib_get(dev, fpriv, &buf);
+	if (r) {
+		DRM_ERROR("ib_get failed\n");
+		goto out;
+	}
+	ib = dev->agp_buffer_map->handle + buf->offset;
+	/* now parse command stream */
+	r = r600_cs_legacy(dev, data,  fpriv, family, ib, &l);
+	if (r) {
+		goto out;
+	}
+
+out:
+	r600_ib_free(dev, buf, fpriv, l, r);
+	/* emit cs id sequence */
+	r600_cs_id_emit(dev_priv, &cs_id);
+	cs->cs_id = cs_id;
+	mutex_unlock(&dev_priv->cs_mutex);
+	return r;
+}
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
new file mode 100644
index 0000000..33b89cd
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#include "drmP.h"
+#include "radeon.h"
+#include "r600d.h"
+#include "avivod.h"
+
+static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
+					struct radeon_cs_reloc **cs_reloc);
+static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
+					struct radeon_cs_reloc **cs_reloc);
+typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**);
+static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm;
+
+/**
+ * r600_cs_packet_parse() - parse cp packet and point ib index to next packet
+ * @parser:	parser structure holding parsing context.
+ * @pkt:	where to store packet informations
+ *
+ * Assume that chunk_ib_index is properly set. Will return -EINVAL
+ * if packet is bigger than remaining ib size. or if packets is unknown.
+ **/
+int r600_cs_packet_parse(struct radeon_cs_parser *p,
+			struct radeon_cs_packet *pkt,
+			unsigned idx)
+{
+	struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
+	uint32_t header;
+
+	if (idx >= ib_chunk->length_dw) {
+		DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
+			  idx, ib_chunk->length_dw);
+		return -EINVAL;
+	}
+	header = ib_chunk->kdata[idx];
+	pkt->idx = idx;
+	pkt->type = CP_PACKET_GET_TYPE(header);
+	pkt->count = CP_PACKET_GET_COUNT(header);
+	pkt->one_reg_wr = 0;
+	switch (pkt->type) {
+	case PACKET_TYPE0:
+		pkt->reg = CP_PACKET0_GET_REG(header);
+		break;
+	case PACKET_TYPE3:
+		pkt->opcode = CP_PACKET3_GET_OPCODE(header);
+		break;
+	case PACKET_TYPE2:
+		pkt->count = -1;
+		break;
+	default:
+		DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
+		return -EINVAL;
+	}
+	if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
+		DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
+			  pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/**
+ * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3
+ * @parser:		parser structure holding parsing context.
+ * @data:		pointer to relocation data
+ * @offset_start:	starting offset
+ * @offset_mask:	offset mask (to align start offset on)
+ * @reloc:		reloc informations
+ *
+ * Check next packet is relocation packet3, do bo validation and compute
+ * GPU offset using the provided start.
+ **/
+static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
+					struct radeon_cs_reloc **cs_reloc)
+{
+	struct radeon_cs_chunk *ib_chunk;
+	struct radeon_cs_chunk *relocs_chunk;
+	struct radeon_cs_packet p3reloc;
+	unsigned idx;
+	int r;
+
+	if (p->chunk_relocs_idx == -1) {
+		DRM_ERROR("No relocation chunk !\n");
+		return -EINVAL;
+	}
+	*cs_reloc = NULL;
+	ib_chunk = &p->chunks[p->chunk_ib_idx];
+	relocs_chunk = &p->chunks[p->chunk_relocs_idx];
+	r = r600_cs_packet_parse(p, &p3reloc, p->idx);
+	if (r) {
+		return r;
+	}
+	p->idx += p3reloc.count + 2;
+	if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+		DRM_ERROR("No packet3 for relocation for packet at %d.\n",
+			  p3reloc.idx);
+		return -EINVAL;
+	}
+	idx = ib_chunk->kdata[p3reloc.idx + 1];
+	if (idx >= relocs_chunk->length_dw) {
+		DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
+			  idx, relocs_chunk->length_dw);
+		return -EINVAL;
+	}
+	/* FIXME: we assume reloc size is 4 dwords */
+	*cs_reloc = p->relocs_ptr[(idx / 4)];
+	return 0;
+}
+
+/**
+ * r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3
+ * @parser:		parser structure holding parsing context.
+ * @data:		pointer to relocation data
+ * @offset_start:	starting offset
+ * @offset_mask:	offset mask (to align start offset on)
+ * @reloc:		reloc informations
+ *
+ * Check next packet is relocation packet3, do bo validation and compute
+ * GPU offset using the provided start.
+ **/
+static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
+					struct radeon_cs_reloc **cs_reloc)
+{
+	struct radeon_cs_chunk *ib_chunk;
+	struct radeon_cs_chunk *relocs_chunk;
+	struct radeon_cs_packet p3reloc;
+	unsigned idx;
+	int r;
+
+	if (p->chunk_relocs_idx == -1) {
+		DRM_ERROR("No relocation chunk !\n");
+		return -EINVAL;
+	}
+	*cs_reloc = NULL;
+	ib_chunk = &p->chunks[p->chunk_ib_idx];
+	relocs_chunk = &p->chunks[p->chunk_relocs_idx];
+	r = r600_cs_packet_parse(p, &p3reloc, p->idx);
+	if (r) {
+		return r;
+	}
+	p->idx += p3reloc.count + 2;
+	if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
+		DRM_ERROR("No packet3 for relocation for packet at %d.\n",
+			  p3reloc.idx);
+		return -EINVAL;
+	}
+	idx = ib_chunk->kdata[p3reloc.idx + 1];
+	if (idx >= relocs_chunk->length_dw) {
+		DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
+			  idx, relocs_chunk->length_dw);
+		return -EINVAL;
+	}
+	*cs_reloc = &p->relocs[0];
+	(*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32;
+	(*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0];
+	return 0;
+}
+
+static int r600_packet0_check(struct radeon_cs_parser *p,
+				struct radeon_cs_packet *pkt,
+				unsigned idx, unsigned reg)
+{
+	switch (reg) {
+	case AVIVO_D1MODE_VLINE_START_END:
+	case AVIVO_D2MODE_VLINE_START_END:
+		break;
+	default:
+		printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+		       reg, idx);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int r600_cs_parse_packet0(struct radeon_cs_parser *p,
+				struct radeon_cs_packet *pkt)
+{
+	unsigned reg, i;
+	unsigned idx;
+	int r;
+
+	idx = pkt->idx + 1;
+	reg = pkt->reg;
+	for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
+		r = r600_packet0_check(p, pkt, idx, reg);
+		if (r) {
+			return r;
+		}
+	}
+	return 0;
+}
+
+static int r600_packet3_check(struct radeon_cs_parser *p,
+				struct radeon_cs_packet *pkt)
+{
+	struct radeon_cs_chunk *ib_chunk;
+	struct radeon_cs_reloc *reloc;
+	volatile u32 *ib;
+	unsigned idx;
+	unsigned i;
+	unsigned start_reg, end_reg, reg;
+	int r;
+
+	ib = p->ib->ptr;
+	ib_chunk = &p->chunks[p->chunk_ib_idx];
+	idx = pkt->idx + 1;
+	switch (pkt->opcode) {
+	case PACKET3_START_3D_CMDBUF:
+		if (p->family >= CHIP_RV770 || pkt->count) {
+			DRM_ERROR("bad START_3D\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_CONTEXT_CONTROL:
+		if (pkt->count != 1) {
+			DRM_ERROR("bad CONTEXT_CONTROL\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_INDEX_TYPE:
+	case PACKET3_NUM_INSTANCES:
+		if (pkt->count) {
+			DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_DRAW_INDEX:
+		if (pkt->count != 3) {
+			DRM_ERROR("bad DRAW_INDEX\n");
+			return -EINVAL;
+		}
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("bad DRAW_INDEX\n");
+			return -EINVAL;
+		}
+		ib[idx+0] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+		ib[idx+1] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		break;
+	case PACKET3_DRAW_INDEX_AUTO:
+		if (pkt->count != 1) {
+			DRM_ERROR("bad DRAW_INDEX_AUTO\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_DRAW_INDEX_IMMD_BE:
+	case PACKET3_DRAW_INDEX_IMMD:
+		if (pkt->count < 2) {
+			DRM_ERROR("bad DRAW_INDEX_IMMD\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_WAIT_REG_MEM:
+		if (pkt->count != 5) {
+			DRM_ERROR("bad WAIT_REG_MEM\n");
+			return -EINVAL;
+		}
+		/* bit 4 is reg (0) or mem (1) */
+		if (ib_chunk->kdata[idx+0] & 0x10) {
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad WAIT_REG_MEM\n");
+				return -EINVAL;
+			}
+			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+2] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		}
+		break;
+	case PACKET3_SURFACE_SYNC:
+		if (pkt->count != 3) {
+			DRM_ERROR("bad SURFACE_SYNC\n");
+			return -EINVAL;
+		}
+		/* 0xffffffff/0x0 is flush all cache flag */
+		if (ib_chunk->kdata[idx+1] != 0xffffffff ||
+		    ib_chunk->kdata[idx+2] != 0) {
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad SURFACE_SYNC\n");
+				return -EINVAL;
+			}
+			ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+		}
+		break;
+	case PACKET3_EVENT_WRITE:
+		if (pkt->count != 2 && pkt->count != 0) {
+			DRM_ERROR("bad EVENT_WRITE\n");
+			return -EINVAL;
+		}
+		if (pkt->count) {
+			r = r600_cs_packet_next_reloc(p, &reloc);
+			if (r) {
+				DRM_ERROR("bad EVENT_WRITE\n");
+				return -EINVAL;
+			}
+			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+			ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		}
+		break;
+	case PACKET3_EVENT_WRITE_EOP:
+		if (pkt->count != 4) {
+			DRM_ERROR("bad EVENT_WRITE_EOP\n");
+			return -EINVAL;
+		}
+		r = r600_cs_packet_next_reloc(p, &reloc);
+		if (r) {
+			DRM_ERROR("bad EVENT_WRITE\n");
+			return -EINVAL;
+		}
+		ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
+		ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+		break;
+	case PACKET3_SET_CONFIG_REG:
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONFIG_REG_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) ||
+		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
+		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
+			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
+			return -EINVAL;
+		}
+		for (i = 0; i < pkt->count; i++) {
+			reg = start_reg + (4 * i);
+			switch (reg) {
+			case CP_COHER_BASE:
+				/* use PACKET3_SURFACE_SYNC */
+				return -EINVAL;
+			default:
+				break;
+			}
+		}
+		break;
+	case PACKET3_SET_CONTEXT_REG:
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONTEXT_REG_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) ||
+		    (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
+		    (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
+			DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
+			return -EINVAL;
+		}
+		for (i = 0; i < pkt->count; i++) {
+			reg = start_reg + (4 * i);
+			switch (reg) {
+			case DB_DEPTH_BASE:
+			case CB_COLOR0_BASE:
+			case CB_COLOR1_BASE:
+			case CB_COLOR2_BASE:
+			case CB_COLOR3_BASE:
+			case CB_COLOR4_BASE:
+			case CB_COLOR5_BASE:
+			case CB_COLOR6_BASE:
+			case CB_COLOR7_BASE:
+			case SQ_PGM_START_FS:
+			case SQ_PGM_START_ES:
+			case SQ_PGM_START_VS:
+			case SQ_PGM_START_GS:
+			case SQ_PGM_START_PS:
+				r = r600_cs_packet_next_reloc(p, &reloc);
+				if (r) {
+					DRM_ERROR("bad SET_CONTEXT_REG "
+							"0x%04X\n", reg);
+					return -EINVAL;
+				}
+				ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				break;
+			case VGT_DMA_BASE:
+			case VGT_DMA_BASE_HI:
+				/* These should be handled by DRAW_INDEX packet 3 */
+			case VGT_STRMOUT_BASE_OFFSET_0:
+			case VGT_STRMOUT_BASE_OFFSET_1:
+			case VGT_STRMOUT_BASE_OFFSET_2:
+			case VGT_STRMOUT_BASE_OFFSET_3:
+			case VGT_STRMOUT_BASE_OFFSET_HI_0:
+			case VGT_STRMOUT_BASE_OFFSET_HI_1:
+			case VGT_STRMOUT_BASE_OFFSET_HI_2:
+			case VGT_STRMOUT_BASE_OFFSET_HI_3:
+			case VGT_STRMOUT_BUFFER_BASE_0:
+			case VGT_STRMOUT_BUFFER_BASE_1:
+			case VGT_STRMOUT_BUFFER_BASE_2:
+			case VGT_STRMOUT_BUFFER_BASE_3:
+			case VGT_STRMOUT_BUFFER_OFFSET_0:
+			case VGT_STRMOUT_BUFFER_OFFSET_1:
+			case VGT_STRMOUT_BUFFER_OFFSET_2:
+			case VGT_STRMOUT_BUFFER_OFFSET_3:
+				/* These should be handled by STRMOUT_BUFFER packet 3 */
+				DRM_ERROR("bad context reg: 0x%08x\n", reg);
+				return -EINVAL;
+			default:
+				break;
+			}
+		}
+		break;
+	case PACKET3_SET_RESOURCE:
+		if (pkt->count % 7) {
+			DRM_ERROR("bad SET_RESOURCE\n");
+			return -EINVAL;
+		}
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_RESOURCE_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) ||
+		    (start_reg >= PACKET3_SET_RESOURCE_END) ||
+		    (end_reg >= PACKET3_SET_RESOURCE_END)) {
+			DRM_ERROR("bad SET_RESOURCE\n");
+			return -EINVAL;
+		}
+		for (i = 0; i < (pkt->count / 7); i++) {
+			switch (G__SQ_VTX_CONSTANT_TYPE(ib[idx+(i*7)+6+1])) {
+			case SQ_TEX_VTX_VALID_TEXTURE:
+				/* tex base */
+				r = r600_cs_packet_next_reloc(p, &reloc);
+				if (r) {
+					DRM_ERROR("bad SET_RESOURCE\n");
+					return -EINVAL;
+				}
+				ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				/* tex mip base */
+				r = r600_cs_packet_next_reloc(p, &reloc);
+				if (r) {
+					DRM_ERROR("bad SET_RESOURCE\n");
+					return -EINVAL;
+				}
+				ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
+				break;
+			case SQ_TEX_VTX_VALID_BUFFER:
+				/* vtx base */
+				r = r600_cs_packet_next_reloc(p, &reloc);
+				if (r) {
+					DRM_ERROR("bad SET_RESOURCE\n");
+					return -EINVAL;
+				}
+				ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
+				ib[idx+1+(i*7)+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
+				break;
+			case SQ_TEX_VTX_INVALID_TEXTURE:
+			case SQ_TEX_VTX_INVALID_BUFFER:
+			default:
+				DRM_ERROR("bad SET_RESOURCE\n");
+				return -EINVAL;
+			}
+		}
+		break;
+	case PACKET3_SET_ALU_CONST:
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_ALU_CONST_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
+		    (start_reg >= PACKET3_SET_ALU_CONST_END) ||
+		    (end_reg >= PACKET3_SET_ALU_CONST_END)) {
+			DRM_ERROR("bad SET_ALU_CONST\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_SET_BOOL_CONST:
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_BOOL_CONST_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) ||
+		    (start_reg >= PACKET3_SET_BOOL_CONST_END) ||
+		    (end_reg >= PACKET3_SET_BOOL_CONST_END)) {
+			DRM_ERROR("bad SET_BOOL_CONST\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_SET_LOOP_CONST:
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_LOOP_CONST_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) ||
+		    (start_reg >= PACKET3_SET_LOOP_CONST_END) ||
+		    (end_reg >= PACKET3_SET_LOOP_CONST_END)) {
+			DRM_ERROR("bad SET_LOOP_CONST\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_SET_CTL_CONST:
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_CTL_CONST_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) ||
+		    (start_reg >= PACKET3_SET_CTL_CONST_END) ||
+		    (end_reg >= PACKET3_SET_CTL_CONST_END)) {
+			DRM_ERROR("bad SET_CTL_CONST\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_SET_SAMPLER:
+		if (pkt->count % 3) {
+			DRM_ERROR("bad SET_SAMPLER\n");
+			return -EINVAL;
+		}
+		start_reg = (ib[idx+0] << 2) + PACKET3_SET_SAMPLER_OFFSET;
+		end_reg = 4 * pkt->count + start_reg - 4;
+		if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) ||
+		    (start_reg >= PACKET3_SET_SAMPLER_END) ||
+		    (end_reg >= PACKET3_SET_SAMPLER_END)) {
+			DRM_ERROR("bad SET_SAMPLER\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_SURFACE_BASE_UPDATE:
+		if (p->family >= CHIP_RV770 || p->family == CHIP_R600) {
+			DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
+			return -EINVAL;
+		}
+		if (pkt->count) {
+			DRM_ERROR("bad SURFACE_BASE_UPDATE\n");
+			return -EINVAL;
+		}
+		break;
+	case PACKET3_NOP:
+		break;
+	default:
+		DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int r600_cs_parse(struct radeon_cs_parser *p)
+{
+	struct radeon_cs_packet pkt;
+	int r;
+
+	do {
+		r = r600_cs_packet_parse(p, &pkt, p->idx);
+		if (r) {
+			return r;
+		}
+		p->idx += pkt.count + 2;
+		switch (pkt.type) {
+		case PACKET_TYPE0:
+			r = r600_cs_parse_packet0(p, &pkt);
+			break;
+		case PACKET_TYPE2:
+			break;
+		case PACKET_TYPE3:
+			r = r600_packet3_check(p, &pkt);
+			break;
+		default:
+			DRM_ERROR("Unknown packet type %d !\n", pkt.type);
+			return -EINVAL;
+		}
+		if (r) {
+			return r;
+		}
+	} while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
+#if 0
+	for (r = 0; r < p->ib->length_dw; r++) {
+		printk(KERN_INFO "%05d  0x%08X\n", r, p->ib->ptr[r]);
+		mdelay(1);
+	}
+#endif
+	return 0;
+}
+
+static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p)
+{
+	if (p->chunk_relocs_idx == -1) {
+		return 0;
+	}
+	p->relocs = kcalloc(1, sizeof(struct radeon_cs_reloc), GFP_KERNEL);
+	if (p->relocs == NULL) {
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+/**
+ * cs_parser_fini() - clean parser states
+ * @parser:	parser structure holding parsing context.
+ * @error:	error number
+ *
+ * If error is set than unvalidate buffer, otherwise just free memory
+ * used by parsing context.
+ **/
+static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error)
+{
+	unsigned i;
+
+	kfree(parser->relocs);
+	for (i = 0; i < parser->nchunks; i++) {
+		kfree(parser->chunks[i].kdata);
+	}
+	kfree(parser->chunks);
+	kfree(parser->chunks_array);
+}
+
+int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
+			unsigned family, u32 *ib, int *l)
+{
+	struct radeon_cs_parser parser;
+	struct radeon_cs_chunk *ib_chunk;
+	struct radeon_ib	fake_ib;
+	int r;
+
+	/* initialize parser */
+	memset(&parser, 0, sizeof(struct radeon_cs_parser));
+	parser.filp = filp;
+	parser.rdev = NULL;
+	parser.family = family;
+	parser.ib = &fake_ib;
+	fake_ib.ptr = ib;
+	r = radeon_cs_parser_init(&parser, data);
+	if (r) {
+		DRM_ERROR("Failed to initialize parser !\n");
+		r600_cs_parser_fini(&parser, r);
+		return r;
+	}
+	r = r600_cs_parser_relocs_legacy(&parser);
+	if (r) {
+		DRM_ERROR("Failed to parse relocation !\n");
+		r600_cs_parser_fini(&parser, r);
+		return r;
+	}
+	/* Copy the packet into the IB, the parser will read from the
+	 * input memory (cached) and write to the IB (which can be
+	 * uncached). */
+	ib_chunk = &parser.chunks[parser.chunk_ib_idx];
+	parser.ib->length_dw = ib_chunk->length_dw;
+	memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4);
+	*l = parser.ib->length_dw;
+	r = r600_cs_parse(&parser);
+	if (r) {
+		DRM_ERROR("Invalid command stream !\n");
+		r600_cs_parser_fini(&parser, r);
+		return r;
+	}
+	r600_cs_parser_fini(&parser, r);
+	return r;
+}
+
+void r600_cs_legacy_init(void)
+{
+	r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm;
+}
diff --git a/drivers/gpu/drm/radeon/r600_microcode.h b/drivers/gpu/drm/radeon/r600_microcode.h
deleted file mode 100644
index 778c8b4..0000000
--- a/drivers/gpu/drm/radeon/r600_microcode.h
+++ /dev/null
@@ -1,23297 +0,0 @@
-/*
- * Copyright 2008-2009 Advanced Micro Devices, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef R600_MICROCODE_H
-#define R600_MICROCODE_H
-
-static const int ME_JUMP_TABLE_START = 1764;
-static const int ME_JUMP_TABLE_END   = 1792;
-
-#define PFP_UCODE_SIZE 576
-#define PM4_UCODE_SIZE 1792
-#define R700_PFP_UCODE_SIZE 848
-#define R700_PM4_UCODE_SIZE 1360
-
-static const u32 R600_cp_microcode[][3] = {
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0000ffff, 0x00284621, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000000, 0x00e00000, 0x000 },
-    { 0x00010000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x614 },
-    { 0x00000000, 0x00600000, 0x5b2 },
-    { 0x00000000, 0x00600000, 0x5c5 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000f00, 0x00281622, 0x000 },
-    { 0x00000008, 0x00211625, 0x000 },
-    { 0x00000020, 0x00203625, 0x000 },
-    { 0x8d000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x002f0225, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x018 },
-    { 0x00412000, 0x00404811, 0x019 },
-    { 0x00422000, 0x00204811, 0x000 },
-    { 0x8e000000, 0x00204411, 0x000 },
-    { 0x00000031, 0x00204a2d, 0x000 },
-    { 0x90000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x0000000c, 0x00211622, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000019, 0x00211a22, 0x000 },
-    { 0x00000004, 0x00281a26, 0x000 },
-    { 0x00000000, 0x002914c5, 0x000 },
-    { 0x00000021, 0x00203625, 0x000 },
-    { 0x00000000, 0x003a1402, 0x000 },
-    { 0x00000016, 0x00211625, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x0000001d, 0x00200e2d, 0x000 },
-    { 0xfffffffc, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002914a3, 0x000 },
-    { 0x0000001d, 0x00203625, 0x000 },
-    { 0x00008000, 0x00280e22, 0x000 },
-    { 0x00000007, 0x00220e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x20000000, 0x00280e22, 0x000 },
-    { 0x00000006, 0x00210e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x00000000, 0x00220222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x038 },
-    { 0x00000000, 0x2ee00000, 0x035 },
-    { 0x00000000, 0x2ce00000, 0x037 },
-    { 0x00000000, 0x00400e2d, 0x039 },
-    { 0x00000008, 0x00200e2d, 0x000 },
-    { 0x00000009, 0x0040122d, 0x046 },
-    { 0x00000001, 0x00400e2d, 0x039 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x03e },
-    { 0x00000008, 0x00401c11, 0x041 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x0000000f, 0x00281e27, 0x000 },
-    { 0x00000003, 0x00221e27, 0x000 },
-    { 0x7fc00000, 0x00281a23, 0x000 },
-    { 0x00000014, 0x00211a26, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000008, 0x00221a26, 0x000 },
-    { 0x00000000, 0x00290cc7, 0x000 },
-    { 0x00000030, 0x00203624, 0x000 },
-    { 0x00007f00, 0x00281221, 0x000 },
-    { 0x00001400, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x04b },
-    { 0x00000001, 0x00290e23, 0x000 },
-    { 0x00000010, 0x00203623, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfff80000, 0x00294a23, 0x000 },
-    { 0x00000000, 0x003a2c02, 0x000 },
-    { 0x00000002, 0x00220e2b, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x00000011, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00294a23, 0x000 },
-    { 0x00000030, 0x00204a2d, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000032, 0x00200e2d, 0x000 },
-    { 0x060a0200, 0x00294a23, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x061 },
-    { 0x00000000, 0x2ee00000, 0x05f },
-    { 0x00000000, 0x2ce00000, 0x05e },
-    { 0x00000000, 0x00400e2d, 0x062 },
-    { 0x00000001, 0x00400e2d, 0x062 },
-    { 0x0000000a, 0x00200e2d, 0x000 },
-    { 0x0000000b, 0x0040122d, 0x06a },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x7fc00000, 0x00281623, 0x000 },
-    { 0x00000014, 0x00211625, 0x000 },
-    { 0x00000001, 0x00331625, 0x000 },
-    { 0x80000000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00290ca3, 0x000 },
-    { 0x3ffffc00, 0x00290e23, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x06d },
-    { 0x00000100, 0x00401c11, 0x070 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x000000f0, 0x00281e27, 0x000 },
-    { 0x00000004, 0x00221e27, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0xfffff0ff, 0x00281a30, 0x000 },
-    { 0x0000a028, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948e6, 0x000 },
-    { 0x0000a018, 0x00204411, 0x000 },
-    { 0x3fffffff, 0x00284a23, 0x000 },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x0000002d, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a3, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x080 },
-    { 0x0000002e, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a4, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x081 },
-    { 0x00000000, 0x00400000, 0x087 },
-    { 0x0000002d, 0x00203623, 0x000 },
-    { 0x0000002e, 0x00203624, 0x000 },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x087 },
-    { 0x00000000, 0x00600000, 0x5ed },
-    { 0x00000000, 0x00600000, 0x5e1 },
-    { 0x00000002, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x08a },
-    { 0x00000018, 0xc0403620, 0x090 },
-    { 0x00000000, 0x2ee00000, 0x08e },
-    { 0x00000000, 0x2ce00000, 0x08d },
-    { 0x00000002, 0x00400e2d, 0x08f },
-    { 0x00000003, 0x00400e2d, 0x08f },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000018, 0x00203623, 0x000 },
-    { 0x00000003, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x095 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x09d },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x2ee00000, 0x09b },
-    { 0x00000000, 0x2ce00000, 0x09a },
-    { 0x00000002, 0x00400e2d, 0x09c },
-    { 0x00000003, 0x00400e2d, 0x09c },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x003f0000, 0x00280e23, 0x000 },
-    { 0x00000010, 0x00210e23, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x0000001e, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a4 },
-    { 0x0000001c, 0xc0203620, 0x000 },
-    { 0x0000001f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a7 },
-    { 0x0000001b, 0xc0203620, 0x000 },
-    { 0x00000008, 0x00210e2b, 0x000 },
-    { 0x0000007f, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0db },
-    { 0x00000000, 0x27000000, 0x000 },
-    { 0x00000000, 0x00600000, 0x28c },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000000c, 0x00221e30, 0x000 },
-    { 0x99800000, 0x00204411, 0x000 },
-    { 0x00000004, 0x0020122d, 0x000 },
-    { 0x00000008, 0x00221224, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00291ce4, 0x000 },
-    { 0x00000000, 0x00604807, 0x128 },
-    { 0x9b000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x9c000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x0033146f, 0x000 },
-    { 0x00000001, 0x00333e23, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0x00203c05, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e007, 0x00204411, 0x000 },
-    { 0x0000000f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0c5 },
-    { 0x00f8ff08, 0x00204811, 0x000 },
-    { 0x98000000, 0x00404811, 0x0d6 },
-    { 0x000000f0, 0x00280e22, 0x000 },
-    { 0x000000a0, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0d4 },
-    { 0x00000013, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0cf },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0ce },
-    { 0x00003f00, 0x00400c11, 0x0d0 },
-    { 0x00001f00, 0x00400c11, 0x0d0 },
-    { 0x00000f00, 0x00200c11, 0x000 },
-    { 0x00380009, 0x00294a23, 0x000 },
-    { 0x3f000000, 0x00280e2b, 0x000 },
-    { 0x00000002, 0x00220e23, 0x000 },
-    { 0x00000007, 0x00494a23, 0x0d6 },
-    { 0x00380f09, 0x00204811, 0x000 },
-    { 0x68000007, 0x00204811, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000a202, 0x00204411, 0x000 },
-    { 0x00ff0000, 0x00284a22, 0x000 },
-    { 0x00000030, 0x00200e2d, 0x000 },
-    { 0x0000002e, 0x0020122d, 0x000 },
-    { 0x00000000, 0x002f0083, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0e3 },
-    { 0x00000000, 0x00600000, 0x5e7 },
-    { 0x00000000, 0x00400000, 0x0e4 },
-    { 0x00000000, 0x00600000, 0x5ea },
-    { 0x00000007, 0x0020222d, 0x000 },
-    { 0x00000005, 0x00220e22, 0x000 },
-    { 0x00100000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x000000ef, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x0000001d, 0x00200e2d, 0x000 },
-    { 0x00000003, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x0f1 },
-    { 0x0000000b, 0x00210228, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f1 },
-    { 0x00000400, 0x00292228, 0x000 },
-    { 0x0000001a, 0x00203628, 0x000 },
-    { 0x0000001c, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f6 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000001e, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x104 },
-    { 0x0000a30f, 0x00204411, 0x000 },
-    { 0x00000013, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0fd },
-    { 0xffffffff, 0x00404811, 0x104 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x100 },
-    { 0x0000ffff, 0x00404811, 0x104 },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x103 },
-    { 0x000000ff, 0x00404811, 0x104 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0002c400, 0x00204411, 0x000 },
-    { 0x0000001f, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x10b },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000019, 0x00203623, 0x000 },
-    { 0x00000018, 0x40224a20, 0x000 },
-    { 0x00000010, 0xc0424a20, 0x10d },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000019, 0x00203623, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000000a, 0x00201011, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x114 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00531224, 0x110 },
-    { 0xffbfffff, 0x00283a2e, 0x000 },
-    { 0x0000001b, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x127 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x00000018, 0x00220e30, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e00e, 0x00204411, 0x000 },
-    { 0x07f8ff08, 0x00204811, 0x000 },
-    { 0x00000000, 0x00294a23, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00800000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204806, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x614 },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x613 },
-    { 0x00000004, 0x00404c11, 0x12e },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x2fe },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x19f },
-    { 0x00000000, 0x00600000, 0x151 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40280620, 0x000 },
-    { 0x00000010, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x00341461, 0x000 },
-    { 0x00000000, 0x00741882, 0x2a4 },
-    { 0x0001a1fd, 0x00604411, 0x2c9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x138 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x2fe },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x19f },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x151 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0681a20, 0x2a4 },
-    { 0x0001a1fd, 0x00604411, 0x2c9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x149 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000001, 0x00300a2f, 0x000 },
-    { 0x00000001, 0x00210a22, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600000, 0x17c },
-    { 0x00000000, 0x00600000, 0x18d },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00202c08, 0x000 },
-    { 0x00000000, 0x00202411, 0x000 },
-    { 0x00000000, 0x00202811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00221e29, 0x000 },
-    { 0x00000000, 0x007048eb, 0x189 },
-    { 0x00000000, 0x00600000, 0x2a4 },
-    { 0x00000001, 0x40330620, 0x000 },
-    { 0x00000000, 0xc0302409, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x28c },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x173 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000001, 0x00530621, 0x16f },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0604800, 0x184 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000013, 0x0020062d, 0x000 },
-    { 0x00000000, 0x0078042a, 0x2e4 },
-    { 0x00000000, 0x00202809, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x165 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000210, 0x00600411, 0x2fe },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x181 },
-    { 0x0000001b, 0xc0203620, 0x000 },
-    { 0x0000001c, 0xc0203620, 0x000 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x46000000, 0x00600811, 0x19f },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x188 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00804811, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40281620, 0x000 },
-    { 0x00000010, 0xc0811a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000008, 0x00221e30, 0x000 },
-    { 0x00000032, 0x00201a2d, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfffbff09, 0x00204811, 0x000 },
-    { 0x00000011, 0x0020222d, 0x000 },
-    { 0x00001fff, 0x00294a28, 0x000 },
-    { 0x00000006, 0x0020222d, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000100, 0x00201811, 0x000 },
-    { 0x00000008, 0x00621e28, 0x128 },
-    { 0x00000008, 0x00822228, 0x000 },
-    { 0x0002c000, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00600e2d, 0x1aa },
-    { 0x0000001c, 0x00600e2d, 0x1aa },
-    { 0x0000c008, 0x00204411, 0x000 },
-    { 0x0000001d, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x1a6 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x39000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00804802, 0x000 },
-    { 0x00000020, 0x00202e2d, 0x000 },
-    { 0x00000000, 0x003b0d63, 0x000 },
-    { 0x00000008, 0x00224a23, 0x000 },
-    { 0x00000010, 0x00224a23, 0x000 },
-    { 0x00000018, 0x00224a23, 0x000 },
-    { 0x00000000, 0x00804803, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x2fe },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x19f },
-    { 0x00000007, 0x0021062f, 0x000 },
-    { 0x00000019, 0x00200a2d, 0x000 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000ffff, 0x40282220, 0x000 },
-    { 0x0000000f, 0x00262228, 0x000 },
-    { 0x00000010, 0x40212620, 0x000 },
-    { 0x0000000f, 0x00262629, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1cd },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000081, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000080, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1c9 },
-    { 0x00000000, 0x00600000, 0x1d6 },
-    { 0x00000001, 0x00531e27, 0x1c5 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000001f, 0x00280a22, 0x000 },
-    { 0x0000001f, 0x00282a2a, 0x000 },
-    { 0x00000001, 0x00530621, 0x1be },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000002, 0x00304a2f, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000001, 0x00301e2f, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x1d6 },
-    { 0x00000001, 0x00531e27, 0x1d2 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x0000000f, 0x00260e23, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000000f, 0x00261224, 0x000 },
-    { 0x00000000, 0x00201411, 0x000 },
-    { 0x00000000, 0x00601811, 0x2a4 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022b, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1e5 },
-    { 0x00000010, 0x00221628, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a29, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x0020480a, 0x000 },
-    { 0x00000000, 0x00202c11, 0x000 },
-    { 0x00000010, 0x00221623, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a24, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x00731503, 0x1f2 },
-    { 0x00000000, 0x00201805, 0x000 },
-    { 0x00000000, 0x00731524, 0x1f2 },
-    { 0x00000000, 0x002d14c5, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00000000, 0x00202003, 0x000 },
-    { 0x00000000, 0x00802404, 0x000 },
-    { 0x0000000f, 0x00210225, 0x000 },
-    { 0x00000000, 0x14c00000, 0x613 },
-    { 0x00000000, 0x002b1405, 0x000 },
-    { 0x00000001, 0x00901625, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x2fe },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x19f },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00294a22, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a21, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000ffff, 0x40281220, 0x000 },
-    { 0x00000010, 0xc0211a20, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211620, 0x000 },
-    { 0x00000000, 0x00741465, 0x2a4 },
-    { 0x0001a1fd, 0x00604411, 0x2c9 },
-    { 0x00000001, 0x00330621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x206 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x1ff },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x5c5 },
-    { 0x00000000, 0x0040040f, 0x200 },
-    { 0x00000000, 0x00600000, 0x5b2 },
-    { 0x00000000, 0x00600000, 0x5c5 },
-    { 0x00000210, 0x00600411, 0x2fe },
-    { 0x00000000, 0x00600000, 0x18d },
-    { 0x00000000, 0x00600000, 0x189 },
-    { 0x00000000, 0x00600000, 0x2a4 },
-    { 0x00000000, 0x00600000, 0x28c },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x21f },
-    { 0x00000000, 0xc0404800, 0x21c },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x00600411, 0x2e4 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x5b2 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000018, 0x40210a20, 0x000 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x235 },
-    { 0x0000001a, 0x0020222d, 0x000 },
-    { 0x00080101, 0x00292228, 0x000 },
-    { 0x0000001a, 0x00203628, 0x000 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x23a },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000010, 0x00600411, 0x2fe },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x19f },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00000000, 0x00600000, 0x265 },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0x00000001, 0x00211e27, 0x000 },
-    { 0x00000000, 0x14e00000, 0x253 },
-    { 0x00000018, 0x00201e2d, 0x000 },
-    { 0x0000ffff, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00341c27, 0x000 },
-    { 0x00000000, 0x12c00000, 0x248 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e5, 0x000 },
-    { 0x00000000, 0x08c00000, 0x24b },
-    { 0x00000000, 0x00201407, 0x000 },
-    { 0x00000018, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00211e27, 0x000 },
-    { 0x00000000, 0x00341c47, 0x000 },
-    { 0x00000000, 0x12c00000, 0x250 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x08c00000, 0x253 },
-    { 0x00000000, 0x00201807, 0x000 },
-    { 0x00000000, 0x00600000, 0x2aa },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000000, 0x00342023, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25b },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25a },
-    { 0x00000016, 0x00404811, 0x25f },
-    { 0x00000018, 0x00404811, 0x25f },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25e },
-    { 0x00000017, 0x00404811, 0x25f },
-    { 0x00000019, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00604411, 0x2d2 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x23f },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000010, 0x40210620, 0x000 },
-    { 0x0000ffff, 0xc0280a20, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0881a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x614 },
-    { 0x00000000, 0x00600000, 0x5b2 },
-    { 0x00000000, 0xc0600000, 0x28c },
-    { 0x00000005, 0x00200a2d, 0x000 },
-    { 0x00000008, 0x00220a22, 0x000 },
-    { 0x00000034, 0x00201a2d, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00007000, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00311ce6, 0x000 },
-    { 0x00000033, 0x00201a2d, 0x000 },
-    { 0x0000000c, 0x00221a26, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x06e00000, 0x27b },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000034, 0x00203623, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00691ce2, 0x128 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x286 },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000024, 0x00403627, 0x000 },
-    { 0x0000000c, 0xc0220a20, 0x000 },
-    { 0x00000032, 0x00203622, 0x000 },
-    { 0x00000031, 0xc0403620, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000009, 0x00204811, 0x000 },
-    { 0xa1000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000029, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce3, 0x000 },
-    { 0x00000029, 0x00203627, 0x000 },
-    { 0x0000002a, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce4, 0x000 },
-    { 0x0000002a, 0x00203627, 0x000 },
-    { 0x0000002b, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a3, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x0000002b, 0x00203627, 0x000 },
-    { 0x0000002c, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x0000002c, 0x00803627, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x0000002a, 0x00203624, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x0000002b, 0x00203627, 0x000 },
-    { 0x00000000, 0x00311cc4, 0x000 },
-    { 0x0000002c, 0x00803627, 0x000 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00203628, 0x000 },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14c00000, 0x2c5 },
-    { 0x00000000, 0x00400000, 0x2c2 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00203628, 0x000 },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2c2 },
-    { 0x00000003, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2c5 },
-    { 0x0000002b, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e1, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2c5 },
-    { 0x00000029, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a1, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2c5 },
-    { 0x0000002c, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e2, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2c5 },
-    { 0x0000002a, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2c5 },
-    { 0x00000000, 0x00600000, 0x5ed },
-    { 0x00000000, 0x00600000, 0x29e },
-    { 0x00000000, 0x00400000, 0x2c7 },
-    { 0x00000000, 0x00600000, 0x29e },
-    { 0x00000000, 0x00600000, 0x5e4 },
-    { 0x00000000, 0x00400000, 0x2c7 },
-    { 0x00000000, 0x00600000, 0x290 },
-    { 0x00000000, 0x00400000, 0x2c7 },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000023, 0x0080222d, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca1, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x003808c5, 0x000 },
-    { 0x00000000, 0x00300841, 0x000 },
-    { 0x00000001, 0x00220a22, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x0000001d, 0x0020222d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x301 },
-    { 0xffffffef, 0x00280621, 0x000 },
-    { 0x0000001a, 0x0020222d, 0x000 },
-    { 0x0000f8e0, 0x00204411, 0x000 },
-    { 0x00000000, 0x00294901, 0x000 },
-    { 0x00000000, 0x00894901, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00002257, 0x00204411, 0x000 },
-    { 0x00000003, 0xc0484a20, 0x000 },
-    { 0x0000225d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x5c5 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x00000001, 0x40304a20, 0x000 },
-    { 0x00000002, 0xc0304a20, 0x000 },
-    { 0x00000001, 0x00530a22, 0x334 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x614 },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x33d },
-    { 0x00000014, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x351 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000016, 0x00604811, 0x35e },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x355 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00404811, 0x349 },
-    { 0x00000028, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x349 },
-    { 0x00002104, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x00000035, 0x00203626, 0x000 },
-    { 0x00000049, 0x00201811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000000, 0x002f0226, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x360 },
-    { 0x00000035, 0x00801a2d, 0x000 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x00000015, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x376 },
-    { 0x0000001e, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x380 },
-    { 0x00000020, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x38c },
-    { 0x0000000f, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x398 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x398 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x39a },
-    { 0x00000016, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x39f },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x08000000, 0x00290a22, 0x000 },
-    { 0x00000003, 0x40210e20, 0x000 },
-    { 0x0000000c, 0xc0211220, 0x000 },
-    { 0x00080000, 0x00281224, 0x000 },
-    { 0x00000014, 0xc0221620, 0x000 },
-    { 0x00000000, 0x002914a4, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948a2, 0x000 },
-    { 0x0000a1fe, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000015, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x614 },
-    { 0x00000015, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x382 },
-    { 0x0000210e, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x614 },
-    { 0x00000003, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x38e },
-    { 0x00002108, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00404811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000006, 0x00404811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000016, 0x00604811, 0x35e },
-    { 0x00000016, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x0000001d, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3b9 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x614 },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3ab },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0xbabecafe, 0x00204811, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000004, 0x00404811, 0x000 },
-    { 0x00002170, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000a, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3be },
-    { 0x8c000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00003fff, 0x40280a20, 0x000 },
-    { 0x80000000, 0x40280e20, 0x000 },
-    { 0x40000000, 0xc0281220, 0x000 },
-    { 0x00040000, 0x00694622, 0x614 },
-    { 0x00000000, 0x00201410, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3cc },
-    { 0x00000000, 0xc0401800, 0x3cf },
-    { 0x00003fff, 0xc0281a20, 0x000 },
-    { 0x00040000, 0x00694626, 0x614 },
-    { 0x00000000, 0x00201810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3d2 },
-    { 0x00000000, 0xc0401c00, 0x3d5 },
-    { 0x00003fff, 0xc0281e20, 0x000 },
-    { 0x00040000, 0x00694627, 0x614 },
-    { 0x00000000, 0x00201c10, 0x000 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0x002820c5, 0x000 },
-    { 0x00000000, 0x004948e8, 0x000 },
-    { 0xa5800000, 0x00200811, 0x000 },
-    { 0x00002000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x3fd },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x0000001f, 0xc0210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3e2 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000ffff, 0xc0481220, 0x3ea },
-    { 0xa7800000, 0x00200811, 0x000 },
-    { 0x0000a000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x3fd },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00304883, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x83000000, 0x00604411, 0x3fd },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xa9800000, 0x00200811, 0x000 },
-    { 0x0000c000, 0x00400c11, 0x3e5 },
-    { 0xab800000, 0x00200811, 0x000 },
-    { 0x0000f8e0, 0x00400c11, 0x3e5 },
-    { 0xad800000, 0x00200811, 0x000 },
-    { 0x0000f880, 0x00400c11, 0x3e5 },
-    { 0xb3800000, 0x00200811, 0x000 },
-    { 0x0000f3fc, 0x00400c11, 0x3e5 },
-    { 0xaf800000, 0x00200811, 0x000 },
-    { 0x0000e000, 0x00400c11, 0x3e5 },
-    { 0xb1800000, 0x00200811, 0x000 },
-    { 0x0000f000, 0x00400c11, 0x3e5 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00002148, 0x00204811, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00182000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0018a000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0018c000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0018f8e0, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0018f880, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0018e000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0018f000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0018f3fc, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x86000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x614 },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00404c02, 0x42e },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x00000000, 0xc0201400, 0x000 },
-    { 0x00000000, 0xc0201800, 0x000 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x43c },
-    { 0x00000000, 0xc0202000, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x00000010, 0x00280a23, 0x000 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x444 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0x00694624, 0x614 },
-    { 0x00000000, 0x00400000, 0x44d },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x449 },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x44c },
-    { 0x00000000, 0x002824f0, 0x000 },
-    { 0x00000007, 0x00280a23, 0x000 },
-    { 0x00000001, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x454 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x04e00000, 0x46d },
-    { 0x00000000, 0x00400000, 0x47a },
-    { 0x00000002, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x459 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x02e00000, 0x46d },
-    { 0x00000000, 0x00400000, 0x47a },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x45e },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x46d },
-    { 0x00000000, 0x00400000, 0x47a },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x463 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46d },
-    { 0x00000000, 0x00400000, 0x47a },
-    { 0x00000005, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x468 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x06e00000, 0x46d },
-    { 0x00000000, 0x00400000, 0x47a },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46d },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x08e00000, 0x46d },
-    { 0x00000000, 0x00400000, 0x47a },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x000 },
-    { 0x00000008, 0x00210a23, 0x000 },
-    { 0x00000000, 0x14c00000, 0x477 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x480 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x00404c08, 0x43c },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000011, 0x40211220, 0x000 },
-    { 0x00000012, 0x40211620, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00210225, 0x000 },
-    { 0x00000000, 0x14e00000, 0x48a },
-    { 0x00040000, 0xc0494a20, 0x48b },
-    { 0xfffbffff, 0xc0284a20, 0x000 },
-    { 0x00000000, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x497 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000c, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x493 },
-    { 0xa0000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x00204811, 0x000 },
-    { 0x0000216b, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000216c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x491 },
-    { 0x00000000, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4ae },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x4a9 },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x4ac },
-    { 0x00000000, 0x00400000, 0x4b2 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xc0600000, 0x614 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4b9 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0404810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x614 },
-    { 0x00000000, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4bb },
-    { 0x00002180, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000003, 0x00333e2f, 0x000 },
-    { 0x00000001, 0x00210221, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4eb },
-    { 0x00000035, 0x00200a2d, 0x000 },
-    { 0x00040000, 0x18e00c11, 0x4da },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xd8c04800, 0x4ce },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000036, 0x0020122d, 0x000 },
-    { 0x00000000, 0x00290c83, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000011, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x491 },
-    { 0x00000035, 0xc0203620, 0x000 },
-    { 0x00000036, 0xc0403620, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0xe0000000, 0xc0484a20, 0x000 },
-    { 0x0000000f, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4f2 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0xd9000000, 0x000 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00204811, 0x000 },
-    { 0x000000ff, 0x00280e30, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x4f6 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x14c00000, 0x50b },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000024, 0x00203623, 0x000 },
-    { 0x00000034, 0x00203623, 0x000 },
-    { 0x00000032, 0x00203623, 0x000 },
-    { 0x00000031, 0x00203623, 0x000 },
-    { 0x0000001d, 0x00203623, 0x000 },
-    { 0x0000002d, 0x00203623, 0x000 },
-    { 0x0000002e, 0x00203623, 0x000 },
-    { 0x0000001b, 0x00203623, 0x000 },
-    { 0x0000001c, 0x00203623, 0x000 },
-    { 0xffffe000, 0x00200c11, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x0000002a, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00200c11, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x0000002c, 0x00203623, 0x000 },
-    { 0xf1ffffff, 0x00283a2e, 0x000 },
-    { 0x0000001a, 0xc0220e20, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000033, 0x40203620, 0x000 },
-    { 0x87000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x9d000000, 0x00204411, 0x000 },
-    { 0x0000001f, 0x40214a20, 0x000 },
-    { 0x96000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x0000001f, 0x00211624, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000003, 0x00281e23, 0x000 },
-    { 0x00000008, 0x00222223, 0x000 },
-    { 0xfffff000, 0x00282228, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000027, 0x00203628, 0x000 },
-    { 0x00000018, 0x00211e23, 0x000 },
-    { 0x00000028, 0x00203627, 0x000 },
-    { 0x00000002, 0x00221624, 0x000 },
-    { 0x00000000, 0x003014a8, 0x000 },
-    { 0x00000026, 0x00203625, 0x000 },
-    { 0x00000003, 0x00211a24, 0x000 },
-    { 0x10000000, 0x00281a26, 0x000 },
-    { 0xefffffff, 0x00283a2e, 0x000 },
-    { 0x00000000, 0x004938ce, 0x602 },
-    { 0x00000001, 0x40280a20, 0x000 },
-    { 0x00000006, 0x40280e20, 0x000 },
-    { 0x00000300, 0xc0281220, 0x000 },
-    { 0x00000008, 0x00211224, 0x000 },
-    { 0x00000000, 0xc0201620, 0x000 },
-    { 0x00000000, 0xc0201a20, 0x000 },
-    { 0x00000000, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x541 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x614 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00020000, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x549 },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x55b },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x549 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x614 },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x55b },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x54d },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00000000, 0xc0400000, 0x55b },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x559 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x554 },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x557 },
-    { 0x00000000, 0x00401c10, 0x55b },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x55d },
-    { 0x00000000, 0x00600000, 0x5a4 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56d },
-    { 0x0000a2b7, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x614 },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x0000a2c4, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x56b },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000001, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x57d },
-    { 0x0000a2bb, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x614 },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x0000a2c5, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x57b },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000002, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x58d },
-    { 0x0000a2bf, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x614 },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x0000a2c6, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x58b },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x0000a2c3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x614 },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x0000a2c7, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x599 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0x01000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00400000, 0x59f },
-    { 0xa4000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5a4 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x88000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x5b7 },
-    { 0x00001000, 0x00200811, 0x000 },
-    { 0x00000034, 0x00203622, 0x000 },
-    { 0x00000000, 0x00600000, 0x5bb },
-    { 0x00000000, 0x00600000, 0x5a4 },
-    { 0x98000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5bb },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000022, 0x00204811, 0x000 },
-    { 0x89000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x0000217a, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x5e1 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000016, 0x00604811, 0x35e },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x09800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x614 },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000004, 0x00404c11, 0x5dc },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0x00000004, 0x00291e27, 0x000 },
-    { 0x0000001d, 0x00803627, 0x000 },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0xfffffffb, 0x00281e27, 0x000 },
-    { 0x0000001d, 0x00803627, 0x000 },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00291e27, 0x000 },
-    { 0x0000001d, 0x00803627, 0x000 },
-    { 0x0000001d, 0x00201e2d, 0x000 },
-    { 0xfffffff7, 0x00281e27, 0x000 },
-    { 0x0000001d, 0x00803627, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000016, 0x00604811, 0x35e },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x01800000, 0x00204811, 0x000 },
-    { 0x00ffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004217f, 0x00604411, 0x614 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x613 },
-    { 0x00000010, 0x00404c11, 0x5f9 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x38c00000, 0x000 },
-    { 0x00000025, 0x00200a2d, 0x000 },
-    { 0x00000026, 0x00200e2d, 0x000 },
-    { 0x00000027, 0x0020122d, 0x000 },
-    { 0x00000028, 0x0020162d, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000004, 0x00301224, 0x000 },
-    { 0x00000000, 0x002f0064, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x612 },
-    { 0x00000003, 0x00281a22, 0x000 },
-    { 0x00000008, 0x00221222, 0x000 },
-    { 0xfffff000, 0x00281224, 0x000 },
-    { 0x00000000, 0x002910c4, 0x000 },
-    { 0x00000027, 0x00403624, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x614 },
-    { 0x9f000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x617 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x2fe },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x19f },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0xc0204411, 0x000 },
-    { 0x00000029, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x0000002c, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000002a, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000002b, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x013304ef, 0x059b0239, 0x000 },
-    { 0x01b00159, 0x0425059b, 0x000 },
-    { 0x021201f6, 0x02390142, 0x000 },
-    { 0x0210022e, 0x0289022a, 0x000 },
-    { 0x03c2059b, 0x059b059b, 0x000 },
-    { 0x05cd05ce, 0x0308059b, 0x000 },
-    { 0x059b05a0, 0x03090329, 0x000 },
-    { 0x0313026b, 0x032b031d, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x059b052c, 0x059b059b, 0x000 },
-    { 0x03a5059b, 0x04a2032d, 0x000 },
-    { 0x04810433, 0x0423059b, 0x000 },
-    { 0x04bb04ed, 0x042704c8, 0x000 },
-    { 0x043304f4, 0x033a0365, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x059b059b, 0x05b905a2, 0x000 },
-    { 0x059b059b, 0x0007059b, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x03e303d8, 0x03f303f1, 0x000 },
-    { 0x03f903f5, 0x03f703fb, 0x000 },
-    { 0x04070403, 0x040f040b, 0x000 },
-    { 0x04170413, 0x041f041b, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x059b059b, 0x059b059b, 0x000 },
-    { 0x00020600, 0x06190006, 0x000 },
-};
-
-static const u32 R600_pfp_microcode[] = {
-0xd40071,
-0xd40072,
-0xca0400,
-0xa00000,
-0x7e828b,
-0x800003,
-0xca0400,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xc41838,
-0xca2400,
-0xca2800,
-0x9581a8,
-0xc41c3a,
-0xc3c000,
-0xca0800,
-0xca0c00,
-0x7c744b,
-0xc20005,
-0x99c000,
-0xc41c3a,
-0x7c744c,
-0xc0fff0,
-0x042c04,
-0x309002,
-0x7d2500,
-0x351402,
-0x7d350b,
-0x255403,
-0x7cd580,
-0x259c03,
-0x95c004,
-0xd5001b,
-0x7eddc1,
-0x7d9d80,
-0xd6801b,
-0xd5801b,
-0xd4401e,
-0xd5401e,
-0xd6401e,
-0xd6801e,
-0xd4801e,
-0xd4c01e,
-0x9783d4,
-0xd5c01e,
-0xca0800,
-0x80001b,
-0xca0c00,
-0xe4011e,
-0xd4001e,
-0x80000d,
-0xc41838,
-0xe4013e,
-0xd4001e,
-0x80000d,
-0xc41838,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca1800,
-0xd4401e,
-0xd5801e,
-0x800054,
-0xd40073,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xe2001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0xd48060,
-0xd4401e,
-0x800002,
-0xd4801e,
-0xca0800,
-0xd48061,
-0xd4401e,
-0x800002,
-0xd4801e,
-0xca0800,
-0xca0c00,
-0xd4401e,
-0xd48016,
-0xd4c016,
-0xd4801e,
-0x8001b9,
-0xd4c01e,
-0xc6083e,
-0xca0c00,
-0xca1000,
-0x948004,
-0xca1400,
-0xe420f3,
-0xd42013,
-0xd56065,
-0xd4e01c,
-0xd5201c,
-0xd5601c,
-0x800002,
-0x062001,
-0xc6083e,
-0xca0c00,
-0xca1000,
-0x9483f7,
-0xca1400,
-0xe420f3,
-0x80007a,
-0xd42013,
-0xc6083e,
-0xca0c00,
-0xca1000,
-0x9883ef,
-0xca1400,
-0xd40064,
-0x80008e,
-0x000000,
-0xc41432,
-0xc6183e,
-0xc4082f,
-0x954005,
-0xc40c30,
-0xd4401e,
-0x800002,
-0xee001e,
-0x9583f5,
-0xc41031,
-0xd44033,
-0xd52065,
-0xd4a01c,
-0xd4e01c,
-0xd5201c,
-0xd40073,
-0xe4015e,
-0xd4001e,
-0x8001b9,
-0x062001,
-0x0a2001,
-0xd60074,
-0xc40836,
-0xc61040,
-0x988007,
-0xcc3835,
-0x95010f,
-0xd4001f,
-0xd46062,
-0x800002,
-0xd42062,
-0xcc1433,
-0x8401bc,
-0xd40070,
-0xd5401e,
-0x800002,
-0xee001e,
-0xca0c00,
-0xca1000,
-0xd4c01a,
-0x8401bc,
-0xd5001a,
-0xcc0443,
-0x35101f,
-0x2c9401,
-0x7d098b,
-0x984005,
-0x7d15cb,
-0xd4001a,
-0x8001b9,
-0xd4006d,
-0x344401,
-0xcc0c44,
-0x98403a,
-0xcc2c46,
-0x958004,
-0xcc0445,
-0x8001b9,
-0xd4001a,
-0xd4c01a,
-0x282801,
-0x8400f3,
-0xcc1003,
-0x98801b,
-0x04380c,
-0x8400f3,
-0xcc1003,
-0x988017,
-0x043808,
-0x8400f3,
-0xcc1003,
-0x988013,
-0x043804,
-0x8400f3,
-0xcc1003,
-0x988014,
-0xcc1047,
-0x9a8009,
-0xcc1448,
-0x9840da,
-0xd4006d,
-0xcc1844,
-0xd5001a,
-0xd5401a,
-0x8000cc,
-0xd5801a,
-0x96c0d3,
-0xd4006d,
-0x8001b9,
-0xd4006e,
-0x9ac003,
-0xd4006d,
-0xd4006e,
-0x800002,
-0xec007f,
-0x9ac0ca,
-0xd4006d,
-0x8001b9,
-0xd4006e,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0x7d9103,
-0x7dd583,
-0x7d190c,
-0x35cc1f,
-0x35701f,
-0x7cf0cb,
-0x7cd08b,
-0x880000,
-0x7e8e8b,
-0x95c004,
-0xd4006e,
-0x8001b9,
-0xd4001a,
-0xd4c01a,
-0xcc0803,
-0xcc0c03,
-0xcc1003,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0xcc2403,
-0xcc2803,
-0x35c41f,
-0x36b01f,
-0x7c704b,
-0x34f01f,
-0x7c704b,
-0x35701f,
-0x7c704b,
-0x7d8881,
-0x7dccc1,
-0x7e5101,
-0x7e9541,
-0x7c9082,
-0x7cd4c2,
-0x7c848b,
-0x9ac003,
-0x7c8c8b,
-0x2c8801,
-0x98809c,
-0xd4006d,
-0x98409a,
-0xd4006e,
-0xcc0847,
-0xcc0c48,
-0xcc1044,
-0xd4801a,
-0xd4c01a,
-0x800104,
-0xd5001a,
-0xcc0832,
-0xd40032,
-0x9482d8,
-0xca0c00,
-0xd4401e,
-0x800002,
-0xd4001e,
-0xe4011e,
-0xd4001e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd4401e,
-0xca1400,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xd5401e,
-0xd54034,
-0x800002,
-0xee001e,
-0x280404,
-0xe2001a,
-0xe2001a,
-0xd4401a,
-0xca3800,
-0xcc0803,
-0xcc0c03,
-0xcc0c03,
-0xcc0c03,
-0x9882bc,
-0x000000,
-0x8401bc,
-0xd7806f,
-0x800002,
-0xee001f,
-0xca0400,
-0xc2ff00,
-0xcc0834,
-0xc13fff,
-0x7c74cb,
-0x7cc90b,
-0x7d010f,
-0x9902af,
-0x7c738b,
-0x8401bc,
-0xd7806f,
-0x800002,
-0xee001f,
-0xca0800,
-0x281900,
-0x7d898b,
-0x958014,
-0x281404,
-0xca0c00,
-0xca1000,
-0xca1c00,
-0xca2400,
-0xe2001f,
-0xd4c01a,
-0xd5001a,
-0xd5401a,
-0xcc1803,
-0xcc2c03,
-0xcc2c03,
-0xcc2c03,
-0x7da58b,
-0x7d9c47,
-0x984296,
-0x000000,
-0x800164,
-0xd4c01a,
-0xd4401e,
-0xd4801e,
-0x800002,
-0xee001e,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c06,
-0x0ccc06,
-0x98c006,
-0xcc1049,
-0x990004,
-0xd40071,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xd4801e,
-0x800002,
-0xee001e,
-0xca0800,
-0xca0c00,
-0x34d018,
-0x251001,
-0x95001f,
-0xc17fff,
-0xca1000,
-0xca1400,
-0xca1800,
-0xd4801d,
-0xd4c01d,
-0x7db18b,
-0xc14202,
-0xc2c001,
-0xd5801d,
-0x34dc0e,
-0x7d5d4c,
-0x7f734c,
-0xd7401e,
-0xd5001e,
-0xd5401e,
-0xc14200,
-0xc2c000,
-0x099c01,
-0x31dc10,
-0x7f5f4c,
-0x7f734c,
-0x7d8380,
-0xd5806f,
-0xd58066,
-0xd7401e,
-0xec005e,
-0xc82402,
-0x8001b9,
-0xd60074,
-0xd4401e,
-0xd4801e,
-0xd4c01e,
-0x800002,
-0xee001e,
-0x800002,
-0xee001f,
-0xd4001f,
-0x800002,
-0xd4001f,
-0xd4001f,
-0x880000,
-0xd4001f,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x010174,
-0x02017b,
-0x030090,
-0x040080,
-0x050005,
-0x060040,
-0x070033,
-0x08012f,
-0x090047,
-0x0a0037,
-0x1001b7,
-0x1700a4,
-0x22013d,
-0x23014c,
-0x2000b5,
-0x240128,
-0x27004e,
-0x28006b,
-0x2a0061,
-0x2b0053,
-0x2f0066,
-0x320088,
-0x340182,
-0x3c0159,
-0x3f0073,
-0x41018f,
-0x440131,
-0x550176,
-0x56017d,
-0x60000c,
-0x610035,
-0x620039,
-0x630039,
-0x640039,
-0x650039,
-0x660039,
-0x670039,
-0x68003b,
-0x690042,
-0x6a0049,
-0x6b0049,
-0x6c0049,
-0x6d0049,
-0x6e0049,
-0x6f0049,
-0x7301b7,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-0x000007,
-};
-
-static const u32 RV610_cp_microcode[][3] = {
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0000ffff, 0x00284621, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000000, 0x00e00000, 0x000 },
-    { 0x00010000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000f00, 0x00281622, 0x000 },
-    { 0x00000008, 0x00211625, 0x000 },
-    { 0x00000018, 0x00203625, 0x000 },
-    { 0x8d000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x002f0225, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x018 },
-    { 0x00412000, 0x00404811, 0x019 },
-    { 0x00422000, 0x00204811, 0x000 },
-    { 0x8e000000, 0x00204411, 0x000 },
-    { 0x00000028, 0x00204a2d, 0x000 },
-    { 0x90000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x0000000c, 0x00211622, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000019, 0x00211a22, 0x000 },
-    { 0x00000004, 0x00281a26, 0x000 },
-    { 0x00000000, 0x002914c5, 0x000 },
-    { 0x00000019, 0x00203625, 0x000 },
-    { 0x00000000, 0x003a1402, 0x000 },
-    { 0x00000016, 0x00211625, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0xfffffffc, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002914a3, 0x000 },
-    { 0x00000017, 0x00203625, 0x000 },
-    { 0x00008000, 0x00280e22, 0x000 },
-    { 0x00000007, 0x00220e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x20000000, 0x00280e22, 0x000 },
-    { 0x00000006, 0x00210e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x00000000, 0x00220222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x038 },
-    { 0x00000000, 0x2ee00000, 0x035 },
-    { 0x00000000, 0x2ce00000, 0x037 },
-    { 0x00000000, 0x00400e2d, 0x039 },
-    { 0x00000008, 0x00200e2d, 0x000 },
-    { 0x00000009, 0x0040122d, 0x046 },
-    { 0x00000001, 0x00400e2d, 0x039 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x03e },
-    { 0x00000008, 0x00401c11, 0x041 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x0000000f, 0x00281e27, 0x000 },
-    { 0x00000003, 0x00221e27, 0x000 },
-    { 0x7fc00000, 0x00281a23, 0x000 },
-    { 0x00000014, 0x00211a26, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000008, 0x00221a26, 0x000 },
-    { 0x00000000, 0x00290cc7, 0x000 },
-    { 0x00000027, 0x00203624, 0x000 },
-    { 0x00007f00, 0x00281221, 0x000 },
-    { 0x00001400, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x04b },
-    { 0x00000001, 0x00290e23, 0x000 },
-    { 0x0000000e, 0x00203623, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfff80000, 0x00294a23, 0x000 },
-    { 0x00000000, 0x003a2c02, 0x000 },
-    { 0x00000002, 0x00220e2b, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x0000000f, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00204a2d, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000029, 0x00200e2d, 0x000 },
-    { 0x060a0200, 0x00294a23, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x061 },
-    { 0x00000000, 0x2ee00000, 0x05f },
-    { 0x00000000, 0x2ce00000, 0x05e },
-    { 0x00000000, 0x00400e2d, 0x062 },
-    { 0x00000001, 0x00400e2d, 0x062 },
-    { 0x0000000a, 0x00200e2d, 0x000 },
-    { 0x0000000b, 0x0040122d, 0x06a },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x7fc00000, 0x00281623, 0x000 },
-    { 0x00000014, 0x00211625, 0x000 },
-    { 0x00000001, 0x00331625, 0x000 },
-    { 0x80000000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00290ca3, 0x000 },
-    { 0x3ffffc00, 0x00290e23, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x06d },
-    { 0x00000100, 0x00401c11, 0x070 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x000000f0, 0x00281e27, 0x000 },
-    { 0x00000004, 0x00221e27, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0xfffff0ff, 0x00281a30, 0x000 },
-    { 0x0000a028, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948e6, 0x000 },
-    { 0x0000a018, 0x00204411, 0x000 },
-    { 0x3fffffff, 0x00284a23, 0x000 },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000030, 0x0020162d, 0x000 },
-    { 0x00000002, 0x00291625, 0x000 },
-    { 0x00000030, 0x00203625, 0x000 },
-    { 0x00000025, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a3, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x083 },
-    { 0x00000026, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a4, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x084 },
-    { 0x00000000, 0x00400000, 0x08a },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203624, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x08a },
-    { 0x00000000, 0x00600000, 0x668 },
-    { 0x00000000, 0x00600000, 0x65c },
-    { 0x00000002, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x08d },
-    { 0x00000012, 0xc0403620, 0x093 },
-    { 0x00000000, 0x2ee00000, 0x091 },
-    { 0x00000000, 0x2ce00000, 0x090 },
-    { 0x00000002, 0x00400e2d, 0x092 },
-    { 0x00000003, 0x00400e2d, 0x092 },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000012, 0x00203623, 0x000 },
-    { 0x00000003, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x098 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x0a0 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x2ee00000, 0x09e },
-    { 0x00000000, 0x2ce00000, 0x09d },
-    { 0x00000002, 0x00400e2d, 0x09f },
-    { 0x00000003, 0x00400e2d, 0x09f },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x003f0000, 0x00280e23, 0x000 },
-    { 0x00000010, 0x00210e23, 0x000 },
-    { 0x00000011, 0x00203623, 0x000 },
-    { 0x0000001e, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a7 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x0000001f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0aa },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000008, 0x00210e2b, 0x000 },
-    { 0x0000007f, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0e1 },
-    { 0x00000000, 0x27000000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x0b3 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000000c, 0x00221e30, 0x000 },
-    { 0x99800000, 0x00204411, 0x000 },
-    { 0x00000004, 0x0020122d, 0x000 },
-    { 0x00000008, 0x00221224, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00291ce4, 0x000 },
-    { 0x00000000, 0x00604807, 0x12f },
-    { 0x9b000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x9c000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x0033146f, 0x000 },
-    { 0x00000001, 0x00333e23, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0x00203c05, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e007, 0x00204411, 0x000 },
-    { 0x0000000f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0cb },
-    { 0x00f8ff08, 0x00204811, 0x000 },
-    { 0x98000000, 0x00404811, 0x0dc },
-    { 0x000000f0, 0x00280e22, 0x000 },
-    { 0x000000a0, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0da },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d5 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d4 },
-    { 0x00003f00, 0x00400c11, 0x0d6 },
-    { 0x00001f00, 0x00400c11, 0x0d6 },
-    { 0x00000f00, 0x00200c11, 0x000 },
-    { 0x00380009, 0x00294a23, 0x000 },
-    { 0x3f000000, 0x00280e2b, 0x000 },
-    { 0x00000002, 0x00220e23, 0x000 },
-    { 0x00000007, 0x00494a23, 0x0dc },
-    { 0x00380f09, 0x00204811, 0x000 },
-    { 0x68000007, 0x00204811, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000a202, 0x00204411, 0x000 },
-    { 0x00ff0000, 0x00280e22, 0x000 },
-    { 0x00000080, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00200e2d, 0x000 },
-    { 0x00000026, 0x0020122d, 0x000 },
-    { 0x00000000, 0x002f0083, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0ea },
-    { 0x00000000, 0x00600000, 0x662 },
-    { 0x00000000, 0x00400000, 0x0eb },
-    { 0x00000000, 0x00600000, 0x665 },
-    { 0x00000007, 0x0020222d, 0x000 },
-    { 0x00000005, 0x00220e22, 0x000 },
-    { 0x00100000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x000000ef, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000003, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x0f8 },
-    { 0x0000000b, 0x00210228, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f8 },
-    { 0x00000400, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000001c, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0fd },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000001e, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x10b },
-    { 0x0000a30f, 0x00204411, 0x000 },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x104 },
-    { 0xffffffff, 0x00404811, 0x10b },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x107 },
-    { 0x0000ffff, 0x00404811, 0x10b },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x10a },
-    { 0x000000ff, 0x00404811, 0x10b },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0002c400, 0x00204411, 0x000 },
-    { 0x0000001f, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x112 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000018, 0x40224a20, 0x000 },
-    { 0x00000010, 0xc0424a20, 0x114 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000000a, 0x00201011, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x11b },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00531224, 0x117 },
-    { 0xffbfffff, 0x00283a2e, 0x000 },
-    { 0x0000001b, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x12e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x00000018, 0x00220e30, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e00e, 0x00204411, 0x000 },
-    { 0x07f8ff08, 0x00204811, 0x000 },
-    { 0x00000000, 0x00294a23, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00800000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204806, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x68c },
-    { 0x00000004, 0x00404c11, 0x135 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000001c, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x13c },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40280620, 0x000 },
-    { 0x00000010, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x00341461, 0x000 },
-    { 0x00000000, 0x00741882, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x147 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0681a20, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x158 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000001, 0x00300a2f, 0x000 },
-    { 0x00000001, 0x00210a22, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600000, 0x18f },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00202c08, 0x000 },
-    { 0x00000000, 0x00202411, 0x000 },
-    { 0x00000000, 0x00202811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00221e29, 0x000 },
-    { 0x00000000, 0x007048eb, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000001, 0x40330620, 0x000 },
-    { 0x00000000, 0xc0302409, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x181 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x186 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x186 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000001, 0x00530621, 0x182 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0604800, 0x197 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000011, 0x0020062d, 0x000 },
-    { 0x00000000, 0x0078042a, 0x2fb },
-    { 0x00000000, 0x00202809, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x174 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x194 },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x46000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x19b },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00804811, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40281620, 0x000 },
-    { 0x00000010, 0xc0811a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000008, 0x00221e30, 0x000 },
-    { 0x00000029, 0x00201a2d, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfffbff09, 0x00204811, 0x000 },
-    { 0x0000000f, 0x0020222d, 0x000 },
-    { 0x00001fff, 0x00294a28, 0x000 },
-    { 0x00000006, 0x0020222d, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000100, 0x00201811, 0x000 },
-    { 0x00000008, 0x00621e28, 0x12f },
-    { 0x00000008, 0x00822228, 0x000 },
-    { 0x0002c000, 0x00204411, 0x000 },
-    { 0x00000015, 0x00600e2d, 0x1bd },
-    { 0x00000016, 0x00600e2d, 0x1bd },
-    { 0x0000c008, 0x00204411, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x1b9 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x39000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00804802, 0x000 },
-    { 0x00000018, 0x00202e2d, 0x000 },
-    { 0x00000000, 0x003b0d63, 0x000 },
-    { 0x00000008, 0x00224a23, 0x000 },
-    { 0x00000010, 0x00224a23, 0x000 },
-    { 0x00000018, 0x00224a23, 0x000 },
-    { 0x00000000, 0x00804803, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000007, 0x0021062f, 0x000 },
-    { 0x00000013, 0x00200a2d, 0x000 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000ffff, 0x40282220, 0x000 },
-    { 0x0000000f, 0x00262228, 0x000 },
-    { 0x00000010, 0x40212620, 0x000 },
-    { 0x0000000f, 0x00262629, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1e0 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000081, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000080, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1dc },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1d8 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000001f, 0x00280a22, 0x000 },
-    { 0x0000001f, 0x00282a2a, 0x000 },
-    { 0x00000001, 0x00530621, 0x1d1 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000002, 0x00304a2f, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000001, 0x00301e2f, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1e5 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x0000000f, 0x00260e23, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000000f, 0x00261224, 0x000 },
-    { 0x00000000, 0x00201411, 0x000 },
-    { 0x00000000, 0x00601811, 0x2bb },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022b, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1f8 },
-    { 0x00000010, 0x00221628, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a29, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x0020480a, 0x000 },
-    { 0x00000000, 0x00202c11, 0x000 },
-    { 0x00000010, 0x00221623, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a24, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x00731503, 0x205 },
-    { 0x00000000, 0x00201805, 0x000 },
-    { 0x00000000, 0x00731524, 0x205 },
-    { 0x00000000, 0x002d14c5, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00000000, 0x00202003, 0x000 },
-    { 0x00000000, 0x00802404, 0x000 },
-    { 0x0000000f, 0x00210225, 0x000 },
-    { 0x00000000, 0x14c00000, 0x68c },
-    { 0x00000000, 0x002b1405, 0x000 },
-    { 0x00000001, 0x00901625, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00294a22, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a21, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000ffff, 0x40281220, 0x000 },
-    { 0x00000010, 0xc0211a20, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211620, 0x000 },
-    { 0x00000000, 0x00741465, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00000001, 0x00330621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x219 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x212 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000000, 0x0040040f, 0x213 },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00000000, 0x00600000, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x232 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x236 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x236 },
-    { 0x00000000, 0xc0404800, 0x233 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x00600411, 0x2fb },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000018, 0x40210a20, 0x000 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x24c },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x00080101, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x251 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000010, 0x00600411, 0x315 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00000000, 0x00600000, 0x27c },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000001, 0x00211e27, 0x000 },
-    { 0x00000000, 0x14e00000, 0x26a },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x0000ffff, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00341c27, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25f },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e5, 0x000 },
-    { 0x00000000, 0x08c00000, 0x262 },
-    { 0x00000000, 0x00201407, 0x000 },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00211e27, 0x000 },
-    { 0x00000000, 0x00341c47, 0x000 },
-    { 0x00000000, 0x12c00000, 0x267 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x08c00000, 0x26a },
-    { 0x00000000, 0x00201807, 0x000 },
-    { 0x00000000, 0x00600000, 0x2c1 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000000, 0x00342023, 0x000 },
-    { 0x00000000, 0x12c00000, 0x272 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x271 },
-    { 0x00000016, 0x00404811, 0x276 },
-    { 0x00000018, 0x00404811, 0x276 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x275 },
-    { 0x00000017, 0x00404811, 0x276 },
-    { 0x00000019, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00604411, 0x2e9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x256 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000010, 0x40210620, 0x000 },
-    { 0x0000ffff, 0xc0280a20, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0881a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x00000000, 0xc0600000, 0x2a3 },
-    { 0x00000005, 0x00200a2d, 0x000 },
-    { 0x00000008, 0x00220a22, 0x000 },
-    { 0x0000002b, 0x00201a2d, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00007000, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00311ce6, 0x000 },
-    { 0x0000002a, 0x00201a2d, 0x000 },
-    { 0x0000000c, 0x00221a26, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x06e00000, 0x292 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00691ce2, 0x12f },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x29d },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000001c, 0x00403627, 0x000 },
-    { 0x0000000c, 0xc0220a20, 0x000 },
-    { 0x00000029, 0x00203622, 0x000 },
-    { 0x00000028, 0xc0403620, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000009, 0x00204811, 0x000 },
-    { 0xa1000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce3, 0x000 },
-    { 0x00000021, 0x00203627, 0x000 },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce4, 0x000 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a3, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203624, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000000, 0x00311cc4, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14c00000, 0x2dc },
-    { 0x00000000, 0x00400000, 0x2d9 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2d9 },
-    { 0x00000003, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2dc },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e1, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a1, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e2, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000000, 0x00600000, 0x668 },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00600000, 0x65f },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2a7 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x0000001a, 0x00201e2d, 0x000 },
-    { 0x0000001b, 0x0080222d, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca1, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x003808c5, 0x000 },
-    { 0x00000000, 0x00300841, 0x000 },
-    { 0x00000001, 0x00220a22, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000017, 0x0020222d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x318 },
-    { 0xffffffef, 0x00280621, 0x000 },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x0000f8e0, 0x00204411, 0x000 },
-    { 0x00000000, 0x00294901, 0x000 },
-    { 0x00000000, 0x00894901, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00002257, 0x00204411, 0x000 },
-    { 0x00000003, 0xc0484a20, 0x000 },
-    { 0x0000225d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x00000001, 0x40304a20, 0x000 },
-    { 0x00000002, 0xc0304a20, 0x000 },
-    { 0x00000001, 0x00530a22, 0x34b },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x354 },
-    { 0x00000014, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x364 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00604802, 0x36e },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x36a },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x00000028, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5c0 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x0000002c, 0x00203626, 0x000 },
-    { 0x00000049, 0x00201811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000000, 0x002f0226, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x370 },
-    { 0x0000002c, 0x00801a2d, 0x000 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x00000015, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x386 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b1 },
-    { 0x00000016, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b5 },
-    { 0x00000020, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x39c },
-    { 0x0000000f, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x0000001e, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x390 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x08000000, 0x00290a22, 0x000 },
-    { 0x00000003, 0x40210e20, 0x000 },
-    { 0x0000000c, 0xc0211220, 0x000 },
-    { 0x00080000, 0x00281224, 0x000 },
-    { 0x00000014, 0xc0221620, 0x000 },
-    { 0x00000000, 0x002914a4, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948a2, 0x000 },
-    { 0x0000a1fe, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000015, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x392 },
-    { 0x0000210e, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000003, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x39e },
-    { 0x00002108, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x80000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000010, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3ae },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000006, 0x00404811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x0000001d, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3ce },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3c0 },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0xbabecafe, 0x00204811, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000004, 0x00404811, 0x000 },
-    { 0x00002170, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000a, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3d3 },
-    { 0x8c000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00003fff, 0x40280a20, 0x000 },
-    { 0x80000000, 0x40280e20, 0x000 },
-    { 0x40000000, 0xc0281220, 0x000 },
-    { 0x00040000, 0x00694622, 0x68d },
-    { 0x00000000, 0x00201410, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e1 },
-    { 0x00000000, 0xc0401800, 0x3e4 },
-    { 0x00003fff, 0xc0281a20, 0x000 },
-    { 0x00040000, 0x00694626, 0x68d },
-    { 0x00000000, 0x00201810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e7 },
-    { 0x00000000, 0xc0401c00, 0x3ea },
-    { 0x00003fff, 0xc0281e20, 0x000 },
-    { 0x00040000, 0x00694627, 0x68d },
-    { 0x00000000, 0x00201c10, 0x000 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0x002820c5, 0x000 },
-    { 0x00000000, 0x004948e8, 0x000 },
-    { 0xa5800000, 0x00200811, 0x000 },
-    { 0x00002000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x0000001f, 0xc0210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3f7 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000ffff, 0xc0481220, 0x3ff },
-    { 0xa7800000, 0x00200811, 0x000 },
-    { 0x0000a000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00304883, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xa9800000, 0x00200811, 0x000 },
-    { 0x0000c000, 0x00400c11, 0x3fa },
-    { 0xab800000, 0x00200811, 0x000 },
-    { 0x0000f8e0, 0x00400c11, 0x3fa },
-    { 0xad800000, 0x00200811, 0x000 },
-    { 0x0000f880, 0x00400c11, 0x3fa },
-    { 0xb3800000, 0x00200811, 0x000 },
-    { 0x0000f3fc, 0x00400c11, 0x3fa },
-    { 0xaf800000, 0x00200811, 0x000 },
-    { 0x0000e000, 0x00400c11, 0x3fa },
-    { 0xb1800000, 0x00200811, 0x000 },
-    { 0x0000f000, 0x00400c11, 0x3fa },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00002148, 0x00204811, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x01182000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0218a000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0318c000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0418f8e0, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0518f880, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0618e000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0718f000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0818f3fc, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000030, 0x00200a2d, 0x000 },
-    { 0x00000000, 0xc0290c40, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x86000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x85000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00000018, 0x40210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x445 },
-    { 0x00800000, 0xc0494a20, 0x446 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00404c02, 0x44b },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x00000000, 0xc0201400, 0x000 },
-    { 0x00000000, 0xc0201800, 0x000 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x459 },
-    { 0x00000000, 0xc0202000, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x00000010, 0x00280a23, 0x000 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x461 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0x00694624, 0x68d },
-    { 0x00000000, 0x00400000, 0x466 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00604805, 0x692 },
-    { 0x00000000, 0x002824f0, 0x000 },
-    { 0x00000007, 0x00280a23, 0x000 },
-    { 0x00000001, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46d },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x04e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000002, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x472 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x02e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x477 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x47c },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000005, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x481 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x06e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x486 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x08e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x000 },
-    { 0x00000008, 0x00210a23, 0x000 },
-    { 0x00000000, 0x14c00000, 0x490 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x499 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x00404c08, 0x459 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000011, 0x40211220, 0x000 },
-    { 0x00000012, 0x40211620, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00210225, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4a3 },
-    { 0x00040000, 0xc0494a20, 0x4a4 },
-    { 0xfffbffff, 0xc0284a20, 0x000 },
-    { 0x00000000, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4b0 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000c, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4ac },
-    { 0xa0000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x00204811, 0x000 },
-    { 0x0000216b, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000216c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4aa },
-    { 0x00000000, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4c3 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x692 },
-    { 0x00000000, 0x00400000, 0x4c7 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xc0600000, 0x68d },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4ce },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0404810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000000, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4d0 },
-    { 0x00002180, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000003, 0x00333e2f, 0x000 },
-    { 0x00000001, 0x00210221, 0x000 },
-    { 0x00000000, 0x14e00000, 0x500 },
-    { 0x0000002c, 0x00200a2d, 0x000 },
-    { 0x00040000, 0x18e00c11, 0x4ef },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xd8c04800, 0x4e3 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000002d, 0x0020122d, 0x000 },
-    { 0x00000000, 0x00290c83, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000011, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4aa },
-    { 0x0000002c, 0xc0203620, 0x000 },
-    { 0x0000002d, 0xc0403620, 0x000 },
-    { 0x0000000f, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x505 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0xd9000000, 0x000 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xb5000000, 0x00204411, 0x000 },
-    { 0x00002000, 0x00204811, 0x000 },
-    { 0xb6000000, 0x00204411, 0x000 },
-    { 0x0000a000, 0x00204811, 0x000 },
-    { 0xb7000000, 0x00204411, 0x000 },
-    { 0x0000c000, 0x00204811, 0x000 },
-    { 0xb8000000, 0x00204411, 0x000 },
-    { 0x0000f8e0, 0x00204811, 0x000 },
-    { 0xb9000000, 0x00204411, 0x000 },
-    { 0x0000f880, 0x00204811, 0x000 },
-    { 0xba000000, 0x00204411, 0x000 },
-    { 0x0000e000, 0x00204811, 0x000 },
-    { 0xbb000000, 0x00204411, 0x000 },
-    { 0x0000f000, 0x00204811, 0x000 },
-    { 0xbc000000, 0x00204411, 0x000 },
-    { 0x0000f3fc, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00204811, 0x000 },
-    { 0x000000ff, 0x00280e30, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x519 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x14c00000, 0x52e },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000001c, 0x00203623, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x00000028, 0x00203623, 0x000 },
-    { 0x00000017, 0x00203623, 0x000 },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203623, 0x000 },
-    { 0x00000015, 0x00203623, 0x000 },
-    { 0x00000016, 0x00203623, 0x000 },
-    { 0xffffe000, 0x00200c11, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00200c11, 0x000 },
-    { 0x00000023, 0x00203623, 0x000 },
-    { 0x00000024, 0x00203623, 0x000 },
-    { 0xf1ffffff, 0x00283a2e, 0x000 },
-    { 0x0000001a, 0xc0220e20, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000002a, 0x40203620, 0x000 },
-    { 0x87000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x9d000000, 0x00204411, 0x000 },
-    { 0x0000001f, 0x40214a20, 0x000 },
-    { 0x96000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x0000001f, 0x00211624, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x0000001d, 0x00203623, 0x000 },
-    { 0x00000003, 0x00281e23, 0x000 },
-    { 0x00000008, 0x00222223, 0x000 },
-    { 0xfffff000, 0x00282228, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x0000001f, 0x00203628, 0x000 },
-    { 0x00000018, 0x00211e23, 0x000 },
-    { 0x00000020, 0x00203627, 0x000 },
-    { 0x00000002, 0x00221624, 0x000 },
-    { 0x00000000, 0x003014a8, 0x000 },
-    { 0x0000001e, 0x00203625, 0x000 },
-    { 0x00000003, 0x00211a24, 0x000 },
-    { 0x10000000, 0x00281a26, 0x000 },
-    { 0xefffffff, 0x00283a2e, 0x000 },
-    { 0x00000000, 0x004938ce, 0x67b },
-    { 0x00000001, 0x40280a20, 0x000 },
-    { 0x00000006, 0x40280e20, 0x000 },
-    { 0x00000300, 0xc0281220, 0x000 },
-    { 0x00000008, 0x00211224, 0x000 },
-    { 0x00000000, 0xc0201620, 0x000 },
-    { 0x00000000, 0xc0201a20, 0x000 },
-    { 0x00000000, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x566 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68d },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00020000, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56e },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x57c },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68d },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x57c },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x572 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00000000, 0xc0400000, 0x57c },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x57a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x692 },
-    { 0x00000000, 0x00401c10, 0x57c },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x57e },
-    { 0x00000000, 0x00600000, 0x5c9 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x58f },
-    { 0x0000a2b7, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c4, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x58d },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000001, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5a0 },
-    { 0x0000a2bb, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c5, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x59e },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000002, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5b1 },
-    { 0x0000a2bf, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c6, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5af },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x0000a2c3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c7, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5be },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0x01000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00400000, 0x5c4 },
-    { 0xa4000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5c9 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000002c, 0x00203621, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5d0 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000030, 0x00403621, 0x5e3 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x5e3 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a092, 0x00604411, 0x68d },
-    { 0x00000031, 0x00203630, 0x000 },
-    { 0x0004a093, 0x00604411, 0x68d },
-    { 0x00000032, 0x00203630, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68d },
-    { 0x00000033, 0x00203630, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68d },
-    { 0x00000034, 0x00203630, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68d },
-    { 0x00000035, 0x00203630, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68d },
-    { 0x00000036, 0x00203630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x88000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000001, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62c },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62c },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x605 },
-    { 0x0000a092, 0x00204411, 0x000 },
-    { 0x00000031, 0x00204a2d, 0x000 },
-    { 0x0000a093, 0x00204411, 0x000 },
-    { 0x00000032, 0x00204a2d, 0x000 },
-    { 0x0000a2b6, 0x00204411, 0x000 },
-    { 0x00000033, 0x00204a2d, 0x000 },
-    { 0x0000a2ba, 0x00204411, 0x000 },
-    { 0x00000034, 0x00204a2d, 0x000 },
-    { 0x0000a2be, 0x00204411, 0x000 },
-    { 0x00000035, 0x00204a2d, 0x000 },
-    { 0x0000a2c2, 0x00204411, 0x000 },
-    { 0x00000036, 0x00204a2d, 0x000 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x000001ff, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62b },
-    { 0x00000000, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x60e },
-    { 0x0004a003, 0x00604411, 0x68d },
-    { 0x0000a003, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x14c00000, 0x613 },
-    { 0x0004a010, 0x00604411, 0x68d },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62b },
-    { 0x0004a011, 0x00604411, 0x68d },
-    { 0x0000a011, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a012, 0x00604411, 0x68d },
-    { 0x0000a012, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a013, 0x00604411, 0x68d },
-    { 0x0000a013, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a014, 0x00604411, 0x68d },
-    { 0x0000a014, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a015, 0x00604411, 0x68d },
-    { 0x0000a015, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a016, 0x00604411, 0x68d },
-    { 0x0000a016, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a017, 0x00604411, 0x68d },
-    { 0x0000a017, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000002c, 0x0080062d, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x63d },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000002, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x63b },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x00001000, 0x00200811, 0x000 },
-    { 0x0000002b, 0x00203622, 0x000 },
-    { 0x00000000, 0x00600000, 0x641 },
-    { 0x00000000, 0x00600000, 0x5c9 },
-    { 0x98000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0600000, 0x641 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000022, 0x00204811, 0x000 },
-    { 0x89000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00404811, 0x62d },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404811, 0x62d },
-    { 0x00000000, 0x00600000, 0x65c },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0xc0204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x09800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000004, 0x00404c11, 0x656 },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000004, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffffb, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffff7, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x01800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x68c },
-    { 0x00000010, 0x00404c11, 0x672 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x38c00000, 0x000 },
-    { 0x0000001d, 0x00200a2d, 0x000 },
-    { 0x0000001e, 0x00200e2d, 0x000 },
-    { 0x0000001f, 0x0020122d, 0x000 },
-    { 0x00000020, 0x0020162d, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000004, 0x00301224, 0x000 },
-    { 0x00000000, 0x002f0064, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x68b },
-    { 0x00000003, 0x00281a22, 0x000 },
-    { 0x00000008, 0x00221222, 0x000 },
-    { 0xfffff000, 0x00281224, 0x000 },
-    { 0x00000000, 0x002910c4, 0x000 },
-    { 0x0000001f, 0x00403624, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x68d },
-    { 0x9f000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x690 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x692 },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x695 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0xc0204411, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000024, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000022, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x01420502, 0x05c00250, 0x000 },
-    { 0x01c30168, 0x043f05c0, 0x000 },
-    { 0x02250209, 0x02500151, 0x000 },
-    { 0x02230245, 0x02a00241, 0x000 },
-    { 0x03d705c0, 0x05c005c0, 0x000 },
-    { 0x0649064a, 0x031f05c0, 0x000 },
-    { 0x05c005c5, 0x03200340, 0x000 },
-    { 0x032a0282, 0x03420334, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c00551, 0x05c005c0, 0x000 },
-    { 0x03ba05c0, 0x04bb0344, 0x000 },
-    { 0x049a0450, 0x043d05c0, 0x000 },
-    { 0x04d005c0, 0x044104dd, 0x000 },
-    { 0x04500507, 0x03510375, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x063f05c7, 0x000 },
-    { 0x05c005c0, 0x000705c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x03f803ed, 0x04080406, 0x000 },
-    { 0x040e040a, 0x040c0410, 0x000 },
-    { 0x041c0418, 0x04240420, 0x000 },
-    { 0x042c0428, 0x04340430, 0x000 },
-    { 0x05c005c0, 0x043805c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x00020679, 0x06970006, 0x000 },
-};
-
-static const u32 RV610_pfp_microcode[] = {
-0xca0400,
-0xa00000,
-0x7e828b,
-0x7c038b,
-0x8001b8,
-0x7c038b,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xc41838,
-0xca2400,
-0xca2800,
-0x9581a8,
-0xc41c3a,
-0xc3c000,
-0xca0800,
-0xca0c00,
-0x7c744b,
-0xc20005,
-0x99c000,
-0xc41c3a,
-0x7c744c,
-0xc0fff0,
-0x042c04,
-0x309002,
-0x7d2500,
-0x351402,
-0x7d350b,
-0x255403,
-0x7cd580,
-0x259c03,
-0x95c004,
-0xd5001b,
-0x7eddc1,
-0x7d9d80,
-0xd6801b,
-0xd5801b,
-0xd4401e,
-0xd5401e,
-0xd6401e,
-0xd6801e,
-0xd4801e,
-0xd4c01e,
-0x9783d3,
-0xd5c01e,
-0xca0800,
-0x80001a,
-0xca0c00,
-0xe4011e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xe4013e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca1800,
-0xd4401e,
-0xd5801e,
-0x800053,
-0xd40075,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xe2001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0xd48060,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xd48061,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xca0c00,
-0xd4401e,
-0xd48016,
-0xd4c016,
-0xd4801e,
-0x8001b8,
-0xd4c01e,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x948004,
-0xca1400,
-0xe420f3,
-0xd42013,
-0xd56065,
-0xd4e01c,
-0xd5201c,
-0xd5601c,
-0x800000,
-0x062001,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9483f7,
-0xca1400,
-0xe420f3,
-0x800079,
-0xd42013,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9883ef,
-0xca1400,
-0xd40064,
-0x80008d,
-0x000000,
-0xc41432,
-0xc61843,
-0xc4082f,
-0x954005,
-0xc40c30,
-0xd4401e,
-0x800000,
-0xee001e,
-0x9583f5,
-0xc41031,
-0xd44033,
-0xd52065,
-0xd4a01c,
-0xd4e01c,
-0xd5201c,
-0xe4015e,
-0xd4001e,
-0x800000,
-0x062001,
-0xca1800,
-0x0a2001,
-0xd60076,
-0xc40836,
-0x988007,
-0xc61045,
-0x950110,
-0xd4001f,
-0xd46062,
-0x800000,
-0xd42062,
-0xcc3835,
-0xcc1433,
-0x8401bb,
-0xd40072,
-0xd5401e,
-0x800000,
-0xee001e,
-0xe2001a,
-0x8401bb,
-0xe2001a,
-0xcc104b,
-0xcc0447,
-0x2c9401,
-0x7d098b,
-0x984005,
-0x7d15cb,
-0xd4001a,
-0x8001b8,
-0xd4006d,
-0x344401,
-0xcc0c48,
-0x98403a,
-0xcc2c4a,
-0x958004,
-0xcc0449,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0x282801,
-0x8400f0,
-0xcc1003,
-0x98801b,
-0x04380c,
-0x8400f0,
-0xcc1003,
-0x988017,
-0x043808,
-0x8400f0,
-0xcc1003,
-0x988013,
-0x043804,
-0x8400f0,
-0xcc1003,
-0x988014,
-0xcc104c,
-0x9a8009,
-0xcc144d,
-0x9840dc,
-0xd4006d,
-0xcc1848,
-0xd5001a,
-0xd5401a,
-0x8000c9,
-0xd5801a,
-0x96c0d5,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0x9ac003,
-0xd4006d,
-0xd4006e,
-0x800000,
-0xec007f,
-0x9ac0cc,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0x7d9103,
-0x7dd583,
-0x7d190c,
-0x35cc1f,
-0x35701f,
-0x7cf0cb,
-0x7cd08b,
-0x880000,
-0x7e8e8b,
-0x95c004,
-0xd4006e,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0xcc0803,
-0xcc0c03,
-0xcc1003,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0xcc2403,
-0xcc2803,
-0x35c41f,
-0x36b01f,
-0x7c704b,
-0x34f01f,
-0x7c704b,
-0x35701f,
-0x7c704b,
-0x7d8881,
-0x7dccc1,
-0x7e5101,
-0x7e9541,
-0x7c9082,
-0x7cd4c2,
-0x7c848b,
-0x9ac003,
-0x7c8c8b,
-0x2c8801,
-0x98809e,
-0xd4006d,
-0x98409c,
-0xd4006e,
-0xcc084c,
-0xcc0c4d,
-0xcc1048,
-0xd4801a,
-0xd4c01a,
-0x800101,
-0xd5001a,
-0xcc0832,
-0xd40032,
-0x9482d9,
-0xca0c00,
-0xd4401e,
-0x800000,
-0xd4001e,
-0xe4011e,
-0xd4001e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd4401e,
-0xca1400,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xd5401e,
-0xd54034,
-0x800000,
-0xee001e,
-0x280404,
-0xe2001a,
-0xe2001a,
-0xd4401a,
-0xca3800,
-0xcc0803,
-0xcc0c03,
-0xcc0c03,
-0xcc0c03,
-0x9882bd,
-0x000000,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0400,
-0xc2ff00,
-0xcc0834,
-0xc13fff,
-0x7c74cb,
-0x7cc90b,
-0x7d010f,
-0x9902b0,
-0x7c738b,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0800,
-0x281900,
-0x7d898b,
-0x958014,
-0x281404,
-0xca0c00,
-0xca1000,
-0xca1c00,
-0xca2400,
-0xe2001f,
-0xd4c01a,
-0xd5001a,
-0xd5401a,
-0xcc1803,
-0xcc2c03,
-0xcc2c03,
-0xcc2c03,
-0x7da58b,
-0x7d9c47,
-0x984297,
-0x000000,
-0x800161,
-0xd4c01a,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c06,
-0x0ccc06,
-0x98c006,
-0xcc104e,
-0x990004,
-0xd40073,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xca0800,
-0xca0c00,
-0x34d018,
-0x251001,
-0x950021,
-0xc17fff,
-0xca1000,
-0xca1400,
-0xca1800,
-0xd4801d,
-0xd4c01d,
-0x7db18b,
-0xc14202,
-0xc2c001,
-0xd5801d,
-0x34dc0e,
-0x7d5d4c,
-0x7f734c,
-0xd7401e,
-0xd5001e,
-0xd5401e,
-0xc14200,
-0xc2c000,
-0x099c01,
-0x31dc10,
-0x7f5f4c,
-0x7f734c,
-0x042802,
-0x7d8380,
-0xd5a86f,
-0xd58066,
-0xd7401e,
-0xec005e,
-0xc82402,
-0xc82402,
-0x8001b8,
-0xd60076,
-0xd4401e,
-0xd4801e,
-0xd4c01e,
-0x800000,
-0xee001e,
-0x800000,
-0xee001f,
-0xd4001f,
-0x800000,
-0xd4001f,
-0xd4001f,
-0x880000,
-0xd4001f,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x010171,
-0x020178,
-0x03008f,
-0x04007f,
-0x050003,
-0x06003f,
-0x070032,
-0x08012c,
-0x090046,
-0x0a0036,
-0x1001b6,
-0x1700a2,
-0x22013a,
-0x230149,
-0x2000b4,
-0x240125,
-0x27004d,
-0x28006a,
-0x2a0060,
-0x2b0052,
-0x2f0065,
-0x320087,
-0x34017f,
-0x3c0156,
-0x3f0072,
-0x41018c,
-0x44012e,
-0x550173,
-0x56017a,
-0x60000b,
-0x610034,
-0x620038,
-0x630038,
-0x640038,
-0x650038,
-0x660038,
-0x670038,
-0x68003a,
-0x690041,
-0x6a0048,
-0x6b0048,
-0x6c0048,
-0x6d0048,
-0x6e0048,
-0x6f0048,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-};
-
-static const u32 RV620_cp_microcode[][3] = {
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0000ffff, 0x00284621, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000000, 0x00e00000, 0x000 },
-    { 0x00010000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000f00, 0x00281622, 0x000 },
-    { 0x00000008, 0x00211625, 0x000 },
-    { 0x00000018, 0x00203625, 0x000 },
-    { 0x8d000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x002f0225, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x018 },
-    { 0x00412000, 0x00404811, 0x019 },
-    { 0x00422000, 0x00204811, 0x000 },
-    { 0x8e000000, 0x00204411, 0x000 },
-    { 0x00000028, 0x00204a2d, 0x000 },
-    { 0x90000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x0000000c, 0x00211622, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000019, 0x00211a22, 0x000 },
-    { 0x00000004, 0x00281a26, 0x000 },
-    { 0x00000000, 0x002914c5, 0x000 },
-    { 0x00000019, 0x00203625, 0x000 },
-    { 0x00000000, 0x003a1402, 0x000 },
-    { 0x00000016, 0x00211625, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0xfffffffc, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002914a3, 0x000 },
-    { 0x00000017, 0x00203625, 0x000 },
-    { 0x00008000, 0x00280e22, 0x000 },
-    { 0x00000007, 0x00220e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x20000000, 0x00280e22, 0x000 },
-    { 0x00000006, 0x00210e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x00000000, 0x00220222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x038 },
-    { 0x00000000, 0x2ee00000, 0x035 },
-    { 0x00000000, 0x2ce00000, 0x037 },
-    { 0x00000000, 0x00400e2d, 0x039 },
-    { 0x00000008, 0x00200e2d, 0x000 },
-    { 0x00000009, 0x0040122d, 0x046 },
-    { 0x00000001, 0x00400e2d, 0x039 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x03e },
-    { 0x00000008, 0x00401c11, 0x041 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x0000000f, 0x00281e27, 0x000 },
-    { 0x00000003, 0x00221e27, 0x000 },
-    { 0x7fc00000, 0x00281a23, 0x000 },
-    { 0x00000014, 0x00211a26, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000008, 0x00221a26, 0x000 },
-    { 0x00000000, 0x00290cc7, 0x000 },
-    { 0x00000027, 0x00203624, 0x000 },
-    { 0x00007f00, 0x00281221, 0x000 },
-    { 0x00001400, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x04b },
-    { 0x00000001, 0x00290e23, 0x000 },
-    { 0x0000000e, 0x00203623, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfff80000, 0x00294a23, 0x000 },
-    { 0x00000000, 0x003a2c02, 0x000 },
-    { 0x00000002, 0x00220e2b, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x0000000f, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00204a2d, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000029, 0x00200e2d, 0x000 },
-    { 0x060a0200, 0x00294a23, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x061 },
-    { 0x00000000, 0x2ee00000, 0x05f },
-    { 0x00000000, 0x2ce00000, 0x05e },
-    { 0x00000000, 0x00400e2d, 0x062 },
-    { 0x00000001, 0x00400e2d, 0x062 },
-    { 0x0000000a, 0x00200e2d, 0x000 },
-    { 0x0000000b, 0x0040122d, 0x06a },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x7fc00000, 0x00281623, 0x000 },
-    { 0x00000014, 0x00211625, 0x000 },
-    { 0x00000001, 0x00331625, 0x000 },
-    { 0x80000000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00290ca3, 0x000 },
-    { 0x3ffffc00, 0x00290e23, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x06d },
-    { 0x00000100, 0x00401c11, 0x070 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x000000f0, 0x00281e27, 0x000 },
-    { 0x00000004, 0x00221e27, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0xfffff0ff, 0x00281a30, 0x000 },
-    { 0x0000a028, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948e6, 0x000 },
-    { 0x0000a018, 0x00204411, 0x000 },
-    { 0x3fffffff, 0x00284a23, 0x000 },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000030, 0x0020162d, 0x000 },
-    { 0x00000002, 0x00291625, 0x000 },
-    { 0x00000030, 0x00203625, 0x000 },
-    { 0x00000025, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a3, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x083 },
-    { 0x00000026, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a4, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x084 },
-    { 0x00000000, 0x00400000, 0x08a },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203624, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x08a },
-    { 0x00000000, 0x00600000, 0x668 },
-    { 0x00000000, 0x00600000, 0x65c },
-    { 0x00000002, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x08d },
-    { 0x00000012, 0xc0403620, 0x093 },
-    { 0x00000000, 0x2ee00000, 0x091 },
-    { 0x00000000, 0x2ce00000, 0x090 },
-    { 0x00000002, 0x00400e2d, 0x092 },
-    { 0x00000003, 0x00400e2d, 0x092 },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000012, 0x00203623, 0x000 },
-    { 0x00000003, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x098 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x0a0 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x2ee00000, 0x09e },
-    { 0x00000000, 0x2ce00000, 0x09d },
-    { 0x00000002, 0x00400e2d, 0x09f },
-    { 0x00000003, 0x00400e2d, 0x09f },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x003f0000, 0x00280e23, 0x000 },
-    { 0x00000010, 0x00210e23, 0x000 },
-    { 0x00000011, 0x00203623, 0x000 },
-    { 0x0000001e, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a7 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x0000001f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0aa },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000008, 0x00210e2b, 0x000 },
-    { 0x0000007f, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0e1 },
-    { 0x00000000, 0x27000000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x0b3 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000000c, 0x00221e30, 0x000 },
-    { 0x99800000, 0x00204411, 0x000 },
-    { 0x00000004, 0x0020122d, 0x000 },
-    { 0x00000008, 0x00221224, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00291ce4, 0x000 },
-    { 0x00000000, 0x00604807, 0x12f },
-    { 0x9b000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x9c000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x0033146f, 0x000 },
-    { 0x00000001, 0x00333e23, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0x00203c05, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e007, 0x00204411, 0x000 },
-    { 0x0000000f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0cb },
-    { 0x00f8ff08, 0x00204811, 0x000 },
-    { 0x98000000, 0x00404811, 0x0dc },
-    { 0x000000f0, 0x00280e22, 0x000 },
-    { 0x000000a0, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0da },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d5 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d4 },
-    { 0x00003f00, 0x00400c11, 0x0d6 },
-    { 0x00001f00, 0x00400c11, 0x0d6 },
-    { 0x00000f00, 0x00200c11, 0x000 },
-    { 0x00380009, 0x00294a23, 0x000 },
-    { 0x3f000000, 0x00280e2b, 0x000 },
-    { 0x00000002, 0x00220e23, 0x000 },
-    { 0x00000007, 0x00494a23, 0x0dc },
-    { 0x00380f09, 0x00204811, 0x000 },
-    { 0x68000007, 0x00204811, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000a202, 0x00204411, 0x000 },
-    { 0x00ff0000, 0x00280e22, 0x000 },
-    { 0x00000080, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00200e2d, 0x000 },
-    { 0x00000026, 0x0020122d, 0x000 },
-    { 0x00000000, 0x002f0083, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0ea },
-    { 0x00000000, 0x00600000, 0x662 },
-    { 0x00000000, 0x00400000, 0x0eb },
-    { 0x00000000, 0x00600000, 0x665 },
-    { 0x00000007, 0x0020222d, 0x000 },
-    { 0x00000005, 0x00220e22, 0x000 },
-    { 0x00100000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x000000ef, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000003, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x0f8 },
-    { 0x0000000b, 0x00210228, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f8 },
-    { 0x00000400, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000001c, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0fd },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000001e, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x10b },
-    { 0x0000a30f, 0x00204411, 0x000 },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x104 },
-    { 0xffffffff, 0x00404811, 0x10b },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x107 },
-    { 0x0000ffff, 0x00404811, 0x10b },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x10a },
-    { 0x000000ff, 0x00404811, 0x10b },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0002c400, 0x00204411, 0x000 },
-    { 0x0000001f, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x112 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000018, 0x40224a20, 0x000 },
-    { 0x00000010, 0xc0424a20, 0x114 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000000a, 0x00201011, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x11b },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00531224, 0x117 },
-    { 0xffbfffff, 0x00283a2e, 0x000 },
-    { 0x0000001b, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x12e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x00000018, 0x00220e30, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e00e, 0x00204411, 0x000 },
-    { 0x07f8ff08, 0x00204811, 0x000 },
-    { 0x00000000, 0x00294a23, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00800000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204806, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x68c },
-    { 0x00000004, 0x00404c11, 0x135 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000001c, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x13c },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40280620, 0x000 },
-    { 0x00000010, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x00341461, 0x000 },
-    { 0x00000000, 0x00741882, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x147 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0681a20, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x158 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000001, 0x00300a2f, 0x000 },
-    { 0x00000001, 0x00210a22, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600000, 0x18f },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00202c08, 0x000 },
-    { 0x00000000, 0x00202411, 0x000 },
-    { 0x00000000, 0x00202811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00221e29, 0x000 },
-    { 0x00000000, 0x007048eb, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000001, 0x40330620, 0x000 },
-    { 0x00000000, 0xc0302409, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x181 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x186 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x186 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000001, 0x00530621, 0x182 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0604800, 0x197 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000011, 0x0020062d, 0x000 },
-    { 0x00000000, 0x0078042a, 0x2fb },
-    { 0x00000000, 0x00202809, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x174 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x194 },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x46000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x19b },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00804811, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40281620, 0x000 },
-    { 0x00000010, 0xc0811a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000008, 0x00221e30, 0x000 },
-    { 0x00000029, 0x00201a2d, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfffbff09, 0x00204811, 0x000 },
-    { 0x0000000f, 0x0020222d, 0x000 },
-    { 0x00001fff, 0x00294a28, 0x000 },
-    { 0x00000006, 0x0020222d, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000100, 0x00201811, 0x000 },
-    { 0x00000008, 0x00621e28, 0x12f },
-    { 0x00000008, 0x00822228, 0x000 },
-    { 0x0002c000, 0x00204411, 0x000 },
-    { 0x00000015, 0x00600e2d, 0x1bd },
-    { 0x00000016, 0x00600e2d, 0x1bd },
-    { 0x0000c008, 0x00204411, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x1b9 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x39000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00804802, 0x000 },
-    { 0x00000018, 0x00202e2d, 0x000 },
-    { 0x00000000, 0x003b0d63, 0x000 },
-    { 0x00000008, 0x00224a23, 0x000 },
-    { 0x00000010, 0x00224a23, 0x000 },
-    { 0x00000018, 0x00224a23, 0x000 },
-    { 0x00000000, 0x00804803, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000007, 0x0021062f, 0x000 },
-    { 0x00000013, 0x00200a2d, 0x000 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000ffff, 0x40282220, 0x000 },
-    { 0x0000000f, 0x00262228, 0x000 },
-    { 0x00000010, 0x40212620, 0x000 },
-    { 0x0000000f, 0x00262629, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1e0 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000081, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000080, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1dc },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1d8 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000001f, 0x00280a22, 0x000 },
-    { 0x0000001f, 0x00282a2a, 0x000 },
-    { 0x00000001, 0x00530621, 0x1d1 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000002, 0x00304a2f, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000001, 0x00301e2f, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1e5 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x0000000f, 0x00260e23, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000000f, 0x00261224, 0x000 },
-    { 0x00000000, 0x00201411, 0x000 },
-    { 0x00000000, 0x00601811, 0x2bb },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022b, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1f8 },
-    { 0x00000010, 0x00221628, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a29, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x0020480a, 0x000 },
-    { 0x00000000, 0x00202c11, 0x000 },
-    { 0x00000010, 0x00221623, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a24, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x00731503, 0x205 },
-    { 0x00000000, 0x00201805, 0x000 },
-    { 0x00000000, 0x00731524, 0x205 },
-    { 0x00000000, 0x002d14c5, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00000000, 0x00202003, 0x000 },
-    { 0x00000000, 0x00802404, 0x000 },
-    { 0x0000000f, 0x00210225, 0x000 },
-    { 0x00000000, 0x14c00000, 0x68c },
-    { 0x00000000, 0x002b1405, 0x000 },
-    { 0x00000001, 0x00901625, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00294a22, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a21, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000ffff, 0x40281220, 0x000 },
-    { 0x00000010, 0xc0211a20, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211620, 0x000 },
-    { 0x00000000, 0x00741465, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00000001, 0x00330621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x219 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x212 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000000, 0x0040040f, 0x213 },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00000000, 0x00600000, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x232 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x236 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x236 },
-    { 0x00000000, 0xc0404800, 0x233 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x00600411, 0x2fb },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000018, 0x40210a20, 0x000 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x24c },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x00080101, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x251 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000010, 0x00600411, 0x315 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00000000, 0x00600000, 0x27c },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000001, 0x00211e27, 0x000 },
-    { 0x00000000, 0x14e00000, 0x26a },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x0000ffff, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00341c27, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25f },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e5, 0x000 },
-    { 0x00000000, 0x08c00000, 0x262 },
-    { 0x00000000, 0x00201407, 0x000 },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00211e27, 0x000 },
-    { 0x00000000, 0x00341c47, 0x000 },
-    { 0x00000000, 0x12c00000, 0x267 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x08c00000, 0x26a },
-    { 0x00000000, 0x00201807, 0x000 },
-    { 0x00000000, 0x00600000, 0x2c1 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000000, 0x00342023, 0x000 },
-    { 0x00000000, 0x12c00000, 0x272 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x271 },
-    { 0x00000016, 0x00404811, 0x276 },
-    { 0x00000018, 0x00404811, 0x276 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x275 },
-    { 0x00000017, 0x00404811, 0x276 },
-    { 0x00000019, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00604411, 0x2e9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x256 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000010, 0x40210620, 0x000 },
-    { 0x0000ffff, 0xc0280a20, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0881a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x00000000, 0x00600000, 0x631 },
-    { 0x00000000, 0xc0600000, 0x2a3 },
-    { 0x00000005, 0x00200a2d, 0x000 },
-    { 0x00000008, 0x00220a22, 0x000 },
-    { 0x0000002b, 0x00201a2d, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00007000, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00311ce6, 0x000 },
-    { 0x0000002a, 0x00201a2d, 0x000 },
-    { 0x0000000c, 0x00221a26, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x06e00000, 0x292 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00691ce2, 0x12f },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x29d },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000001c, 0x00403627, 0x000 },
-    { 0x0000000c, 0xc0220a20, 0x000 },
-    { 0x00000029, 0x00203622, 0x000 },
-    { 0x00000028, 0xc0403620, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000009, 0x00204811, 0x000 },
-    { 0xa1000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce3, 0x000 },
-    { 0x00000021, 0x00203627, 0x000 },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce4, 0x000 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a3, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203624, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000000, 0x00311cc4, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14c00000, 0x2dc },
-    { 0x00000000, 0x00400000, 0x2d9 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2d9 },
-    { 0x00000003, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2dc },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e1, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a1, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e2, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000000, 0x00600000, 0x668 },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00600000, 0x65f },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2a7 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x0000001a, 0x00201e2d, 0x000 },
-    { 0x0000001b, 0x0080222d, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca1, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x003808c5, 0x000 },
-    { 0x00000000, 0x00300841, 0x000 },
-    { 0x00000001, 0x00220a22, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000017, 0x0020222d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x318 },
-    { 0xffffffef, 0x00280621, 0x000 },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x0000f8e0, 0x00204411, 0x000 },
-    { 0x00000000, 0x00294901, 0x000 },
-    { 0x00000000, 0x00894901, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00002257, 0x00204411, 0x000 },
-    { 0x00000003, 0xc0484a20, 0x000 },
-    { 0x0000225d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x645 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x00000001, 0x40304a20, 0x000 },
-    { 0x00000002, 0xc0304a20, 0x000 },
-    { 0x00000001, 0x00530a22, 0x34b },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x354 },
-    { 0x00000014, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x364 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00604802, 0x36e },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x36a },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x00000028, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5c0 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x0000002c, 0x00203626, 0x000 },
-    { 0x00000049, 0x00201811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000000, 0x002f0226, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x370 },
-    { 0x0000002c, 0x00801a2d, 0x000 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x00000015, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x386 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b1 },
-    { 0x00000016, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b5 },
-    { 0x00000020, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x39c },
-    { 0x0000000f, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x0000001e, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x390 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x08000000, 0x00290a22, 0x000 },
-    { 0x00000003, 0x40210e20, 0x000 },
-    { 0x0000000c, 0xc0211220, 0x000 },
-    { 0x00080000, 0x00281224, 0x000 },
-    { 0x00000014, 0xc0221620, 0x000 },
-    { 0x00000000, 0x002914a4, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948a2, 0x000 },
-    { 0x0000a1fe, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000015, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x392 },
-    { 0x0000210e, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000003, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x39e },
-    { 0x00002108, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x80000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000010, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3ae },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000006, 0x00404811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x0000001d, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3ce },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3c0 },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0xbabecafe, 0x00204811, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000004, 0x00404811, 0x000 },
-    { 0x00002170, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000a, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3d3 },
-    { 0x8c000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00003fff, 0x40280a20, 0x000 },
-    { 0x80000000, 0x40280e20, 0x000 },
-    { 0x40000000, 0xc0281220, 0x000 },
-    { 0x00040000, 0x00694622, 0x68d },
-    { 0x00000000, 0x00201410, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e1 },
-    { 0x00000000, 0xc0401800, 0x3e4 },
-    { 0x00003fff, 0xc0281a20, 0x000 },
-    { 0x00040000, 0x00694626, 0x68d },
-    { 0x00000000, 0x00201810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e7 },
-    { 0x00000000, 0xc0401c00, 0x3ea },
-    { 0x00003fff, 0xc0281e20, 0x000 },
-    { 0x00040000, 0x00694627, 0x68d },
-    { 0x00000000, 0x00201c10, 0x000 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0x002820c5, 0x000 },
-    { 0x00000000, 0x004948e8, 0x000 },
-    { 0xa5800000, 0x00200811, 0x000 },
-    { 0x00002000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x0000001f, 0xc0210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3f7 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000ffff, 0xc0481220, 0x3ff },
-    { 0xa7800000, 0x00200811, 0x000 },
-    { 0x0000a000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00304883, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xa9800000, 0x00200811, 0x000 },
-    { 0x0000c000, 0x00400c11, 0x3fa },
-    { 0xab800000, 0x00200811, 0x000 },
-    { 0x0000f8e0, 0x00400c11, 0x3fa },
-    { 0xad800000, 0x00200811, 0x000 },
-    { 0x0000f880, 0x00400c11, 0x3fa },
-    { 0xb3800000, 0x00200811, 0x000 },
-    { 0x0000f3fc, 0x00400c11, 0x3fa },
-    { 0xaf800000, 0x00200811, 0x000 },
-    { 0x0000e000, 0x00400c11, 0x3fa },
-    { 0xb1800000, 0x00200811, 0x000 },
-    { 0x0000f000, 0x00400c11, 0x3fa },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00002148, 0x00204811, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x01182000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0218a000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0318c000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0418f8e0, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0518f880, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0618e000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0718f000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0818f3fc, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000030, 0x00200a2d, 0x000 },
-    { 0x00000000, 0xc0290c40, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x86000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x85000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00000018, 0x40210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x445 },
-    { 0x00800000, 0xc0494a20, 0x446 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00404c02, 0x44b },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x00000000, 0xc0201400, 0x000 },
-    { 0x00000000, 0xc0201800, 0x000 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x459 },
-    { 0x00000000, 0xc0202000, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x00000010, 0x00280a23, 0x000 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x461 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0x00694624, 0x68d },
-    { 0x00000000, 0x00400000, 0x466 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00604805, 0x692 },
-    { 0x00000000, 0x002824f0, 0x000 },
-    { 0x00000007, 0x00280a23, 0x000 },
-    { 0x00000001, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46d },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x04e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000002, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x472 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x02e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x477 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x47c },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000005, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x481 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x06e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x486 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x08e00000, 0x486 },
-    { 0x00000000, 0x00400000, 0x493 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x000 },
-    { 0x00000008, 0x00210a23, 0x000 },
-    { 0x00000000, 0x14c00000, 0x490 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x499 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x00404c08, 0x459 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000011, 0x40211220, 0x000 },
-    { 0x00000012, 0x40211620, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00210225, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4a3 },
-    { 0x00040000, 0xc0494a20, 0x4a4 },
-    { 0xfffbffff, 0xc0284a20, 0x000 },
-    { 0x00000000, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4b0 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000c, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4ac },
-    { 0xa0000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x00204811, 0x000 },
-    { 0x0000216b, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000216c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4aa },
-    { 0x00000000, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4c3 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x692 },
-    { 0x00000000, 0x00400000, 0x4c7 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xc0600000, 0x68d },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4ce },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0404810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68d },
-    { 0x00000000, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4d0 },
-    { 0x00002180, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000003, 0x00333e2f, 0x000 },
-    { 0x00000001, 0x00210221, 0x000 },
-    { 0x00000000, 0x14e00000, 0x500 },
-    { 0x0000002c, 0x00200a2d, 0x000 },
-    { 0x00040000, 0x18e00c11, 0x4ef },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xd8c04800, 0x4e3 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000002d, 0x0020122d, 0x000 },
-    { 0x00000000, 0x00290c83, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000011, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4aa },
-    { 0x0000002c, 0xc0203620, 0x000 },
-    { 0x0000002d, 0xc0403620, 0x000 },
-    { 0x0000000f, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x505 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0xd9000000, 0x000 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xb5000000, 0x00204411, 0x000 },
-    { 0x00002000, 0x00204811, 0x000 },
-    { 0xb6000000, 0x00204411, 0x000 },
-    { 0x0000a000, 0x00204811, 0x000 },
-    { 0xb7000000, 0x00204411, 0x000 },
-    { 0x0000c000, 0x00204811, 0x000 },
-    { 0xb8000000, 0x00204411, 0x000 },
-    { 0x0000f8e0, 0x00204811, 0x000 },
-    { 0xb9000000, 0x00204411, 0x000 },
-    { 0x0000f880, 0x00204811, 0x000 },
-    { 0xba000000, 0x00204411, 0x000 },
-    { 0x0000e000, 0x00204811, 0x000 },
-    { 0xbb000000, 0x00204411, 0x000 },
-    { 0x0000f000, 0x00204811, 0x000 },
-    { 0xbc000000, 0x00204411, 0x000 },
-    { 0x0000f3fc, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00204811, 0x000 },
-    { 0x000000ff, 0x00280e30, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x519 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x14c00000, 0x52e },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000001c, 0x00203623, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x00000028, 0x00203623, 0x000 },
-    { 0x00000017, 0x00203623, 0x000 },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203623, 0x000 },
-    { 0x00000015, 0x00203623, 0x000 },
-    { 0x00000016, 0x00203623, 0x000 },
-    { 0xffffe000, 0x00200c11, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00200c11, 0x000 },
-    { 0x00000023, 0x00203623, 0x000 },
-    { 0x00000024, 0x00203623, 0x000 },
-    { 0xf1ffffff, 0x00283a2e, 0x000 },
-    { 0x0000001a, 0xc0220e20, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000002a, 0x40203620, 0x000 },
-    { 0x87000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x9d000000, 0x00204411, 0x000 },
-    { 0x0000001f, 0x40214a20, 0x000 },
-    { 0x96000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x0000001f, 0x00211624, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x0000001d, 0x00203623, 0x000 },
-    { 0x00000003, 0x00281e23, 0x000 },
-    { 0x00000008, 0x00222223, 0x000 },
-    { 0xfffff000, 0x00282228, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x0000001f, 0x00203628, 0x000 },
-    { 0x00000018, 0x00211e23, 0x000 },
-    { 0x00000020, 0x00203627, 0x000 },
-    { 0x00000002, 0x00221624, 0x000 },
-    { 0x00000000, 0x003014a8, 0x000 },
-    { 0x0000001e, 0x00203625, 0x000 },
-    { 0x00000003, 0x00211a24, 0x000 },
-    { 0x10000000, 0x00281a26, 0x000 },
-    { 0xefffffff, 0x00283a2e, 0x000 },
-    { 0x00000000, 0x004938ce, 0x67b },
-    { 0x00000001, 0x40280a20, 0x000 },
-    { 0x00000006, 0x40280e20, 0x000 },
-    { 0x00000300, 0xc0281220, 0x000 },
-    { 0x00000008, 0x00211224, 0x000 },
-    { 0x00000000, 0xc0201620, 0x000 },
-    { 0x00000000, 0xc0201a20, 0x000 },
-    { 0x00000000, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x566 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68d },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00020000, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56e },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x57c },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68d },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x57c },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x572 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00000000, 0xc0400000, 0x57c },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x57a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x692 },
-    { 0x00000000, 0x00401c10, 0x57c },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x57e },
-    { 0x00000000, 0x00600000, 0x5c9 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x58f },
-    { 0x0000a2b7, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c4, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x58d },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000001, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5a0 },
-    { 0x0000a2bb, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c5, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x59e },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000002, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5b1 },
-    { 0x0000a2bf, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c6, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5af },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x0000a2c3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68d },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000a2c7, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5be },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0x01000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00400000, 0x5c4 },
-    { 0xa4000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5c9 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000002c, 0x00203621, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5d0 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000030, 0x00403621, 0x5e3 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x5e3 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a092, 0x00604411, 0x68d },
-    { 0x00000031, 0x00203630, 0x000 },
-    { 0x0004a093, 0x00604411, 0x68d },
-    { 0x00000032, 0x00203630, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68d },
-    { 0x00000033, 0x00203630, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68d },
-    { 0x00000034, 0x00203630, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68d },
-    { 0x00000035, 0x00203630, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68d },
-    { 0x00000036, 0x00203630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x88000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000001, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62c },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62c },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x605 },
-    { 0x0000a092, 0x00204411, 0x000 },
-    { 0x00000031, 0x00204a2d, 0x000 },
-    { 0x0000a093, 0x00204411, 0x000 },
-    { 0x00000032, 0x00204a2d, 0x000 },
-    { 0x0000a2b6, 0x00204411, 0x000 },
-    { 0x00000033, 0x00204a2d, 0x000 },
-    { 0x0000a2ba, 0x00204411, 0x000 },
-    { 0x00000034, 0x00204a2d, 0x000 },
-    { 0x0000a2be, 0x00204411, 0x000 },
-    { 0x00000035, 0x00204a2d, 0x000 },
-    { 0x0000a2c2, 0x00204411, 0x000 },
-    { 0x00000036, 0x00204a2d, 0x000 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x000001ff, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62b },
-    { 0x00000000, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x60e },
-    { 0x0004a003, 0x00604411, 0x68d },
-    { 0x0000a003, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x14c00000, 0x613 },
-    { 0x0004a010, 0x00604411, 0x68d },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62b },
-    { 0x0004a011, 0x00604411, 0x68d },
-    { 0x0000a011, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a012, 0x00604411, 0x68d },
-    { 0x0000a012, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a013, 0x00604411, 0x68d },
-    { 0x0000a013, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a014, 0x00604411, 0x68d },
-    { 0x0000a014, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a015, 0x00604411, 0x68d },
-    { 0x0000a015, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a016, 0x00604411, 0x68d },
-    { 0x0000a016, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a017, 0x00604411, 0x68d },
-    { 0x0000a017, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x0000002c, 0x0080062d, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x63d },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000002, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x63b },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68d },
-    { 0x00001000, 0x00200811, 0x000 },
-    { 0x0000002b, 0x00203622, 0x000 },
-    { 0x00000000, 0x00600000, 0x641 },
-    { 0x00000000, 0x00600000, 0x5c9 },
-    { 0x98000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0600000, 0x641 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000022, 0x00204811, 0x000 },
-    { 0x89000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00404811, 0x62d },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404811, 0x62d },
-    { 0x00000000, 0x00600000, 0x65c },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0xc0204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x09800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000004, 0x00404c11, 0x656 },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000004, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffffb, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffff7, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x01800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68d },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x68c },
-    { 0x00000010, 0x00404c11, 0x672 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x38c00000, 0x000 },
-    { 0x0000001d, 0x00200a2d, 0x000 },
-    { 0x0000001e, 0x00200e2d, 0x000 },
-    { 0x0000001f, 0x0020122d, 0x000 },
-    { 0x00000020, 0x0020162d, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000004, 0x00301224, 0x000 },
-    { 0x00000000, 0x002f0064, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x68b },
-    { 0x00000003, 0x00281a22, 0x000 },
-    { 0x00000008, 0x00221222, 0x000 },
-    { 0xfffff000, 0x00281224, 0x000 },
-    { 0x00000000, 0x002910c4, 0x000 },
-    { 0x0000001f, 0x00403624, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x68d },
-    { 0x9f000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x690 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x692 },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x695 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0xc0204411, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000024, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000022, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x01420502, 0x05c00250, 0x000 },
-    { 0x01c30168, 0x043f05c0, 0x000 },
-    { 0x02250209, 0x02500151, 0x000 },
-    { 0x02230245, 0x02a00241, 0x000 },
-    { 0x03d705c0, 0x05c005c0, 0x000 },
-    { 0x0649064a, 0x031f05c0, 0x000 },
-    { 0x05c005c5, 0x03200340, 0x000 },
-    { 0x032a0282, 0x03420334, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c00551, 0x05c005c0, 0x000 },
-    { 0x03ba05c0, 0x04bb0344, 0x000 },
-    { 0x049a0450, 0x043d05c0, 0x000 },
-    { 0x04d005c0, 0x044104dd, 0x000 },
-    { 0x04500507, 0x03510375, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x063f05c7, 0x000 },
-    { 0x05c005c0, 0x000705c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x03f803ed, 0x04080406, 0x000 },
-    { 0x040e040a, 0x040c0410, 0x000 },
-    { 0x041c0418, 0x04240420, 0x000 },
-    { 0x042c0428, 0x04340430, 0x000 },
-    { 0x05c005c0, 0x043805c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x05c005c0, 0x05c005c0, 0x000 },
-    { 0x00020679, 0x06970006, 0x000 },
-};
-
-static const u32 RV620_pfp_microcode[] = {
-0xca0400,
-0xa00000,
-0x7e828b,
-0x7c038b,
-0x8001b8,
-0x7c038b,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xc41838,
-0xca2400,
-0xca2800,
-0x9581a8,
-0xc41c3a,
-0xc3c000,
-0xca0800,
-0xca0c00,
-0x7c744b,
-0xc20005,
-0x99c000,
-0xc41c3a,
-0x7c744c,
-0xc0fff0,
-0x042c04,
-0x309002,
-0x7d2500,
-0x351402,
-0x7d350b,
-0x255403,
-0x7cd580,
-0x259c03,
-0x95c004,
-0xd5001b,
-0x7eddc1,
-0x7d9d80,
-0xd6801b,
-0xd5801b,
-0xd4401e,
-0xd5401e,
-0xd6401e,
-0xd6801e,
-0xd4801e,
-0xd4c01e,
-0x9783d3,
-0xd5c01e,
-0xca0800,
-0x80001a,
-0xca0c00,
-0xe4011e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xe4013e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca1800,
-0xd4401e,
-0xd5801e,
-0x800053,
-0xd40075,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xe2001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0xd48060,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xd48061,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xca0c00,
-0xd4401e,
-0xd48016,
-0xd4c016,
-0xd4801e,
-0x8001b8,
-0xd4c01e,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x948004,
-0xca1400,
-0xe420f3,
-0xd42013,
-0xd56065,
-0xd4e01c,
-0xd5201c,
-0xd5601c,
-0x800000,
-0x062001,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9483f7,
-0xca1400,
-0xe420f3,
-0x800079,
-0xd42013,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9883ef,
-0xca1400,
-0xd40064,
-0x80008d,
-0x000000,
-0xc41432,
-0xc61843,
-0xc4082f,
-0x954005,
-0xc40c30,
-0xd4401e,
-0x800000,
-0xee001e,
-0x9583f5,
-0xc41031,
-0xd44033,
-0xd52065,
-0xd4a01c,
-0xd4e01c,
-0xd5201c,
-0xe4015e,
-0xd4001e,
-0x800000,
-0x062001,
-0xca1800,
-0x0a2001,
-0xd60076,
-0xc40836,
-0x988007,
-0xc61045,
-0x950110,
-0xd4001f,
-0xd46062,
-0x800000,
-0xd42062,
-0xcc3835,
-0xcc1433,
-0x8401bb,
-0xd40072,
-0xd5401e,
-0x800000,
-0xee001e,
-0xe2001a,
-0x8401bb,
-0xe2001a,
-0xcc104b,
-0xcc0447,
-0x2c9401,
-0x7d098b,
-0x984005,
-0x7d15cb,
-0xd4001a,
-0x8001b8,
-0xd4006d,
-0x344401,
-0xcc0c48,
-0x98403a,
-0xcc2c4a,
-0x958004,
-0xcc0449,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0x282801,
-0x8400f0,
-0xcc1003,
-0x98801b,
-0x04380c,
-0x8400f0,
-0xcc1003,
-0x988017,
-0x043808,
-0x8400f0,
-0xcc1003,
-0x988013,
-0x043804,
-0x8400f0,
-0xcc1003,
-0x988014,
-0xcc104c,
-0x9a8009,
-0xcc144d,
-0x9840dc,
-0xd4006d,
-0xcc1848,
-0xd5001a,
-0xd5401a,
-0x8000c9,
-0xd5801a,
-0x96c0d5,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0x9ac003,
-0xd4006d,
-0xd4006e,
-0x800000,
-0xec007f,
-0x9ac0cc,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0x7d9103,
-0x7dd583,
-0x7d190c,
-0x35cc1f,
-0x35701f,
-0x7cf0cb,
-0x7cd08b,
-0x880000,
-0x7e8e8b,
-0x95c004,
-0xd4006e,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0xcc0803,
-0xcc0c03,
-0xcc1003,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0xcc2403,
-0xcc2803,
-0x35c41f,
-0x36b01f,
-0x7c704b,
-0x34f01f,
-0x7c704b,
-0x35701f,
-0x7c704b,
-0x7d8881,
-0x7dccc1,
-0x7e5101,
-0x7e9541,
-0x7c9082,
-0x7cd4c2,
-0x7c848b,
-0x9ac003,
-0x7c8c8b,
-0x2c8801,
-0x98809e,
-0xd4006d,
-0x98409c,
-0xd4006e,
-0xcc084c,
-0xcc0c4d,
-0xcc1048,
-0xd4801a,
-0xd4c01a,
-0x800101,
-0xd5001a,
-0xcc0832,
-0xd40032,
-0x9482d9,
-0xca0c00,
-0xd4401e,
-0x800000,
-0xd4001e,
-0xe4011e,
-0xd4001e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd4401e,
-0xca1400,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xd5401e,
-0xd54034,
-0x800000,
-0xee001e,
-0x280404,
-0xe2001a,
-0xe2001a,
-0xd4401a,
-0xca3800,
-0xcc0803,
-0xcc0c03,
-0xcc0c03,
-0xcc0c03,
-0x9882bd,
-0x000000,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0400,
-0xc2ff00,
-0xcc0834,
-0xc13fff,
-0x7c74cb,
-0x7cc90b,
-0x7d010f,
-0x9902b0,
-0x7c738b,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0800,
-0x281900,
-0x7d898b,
-0x958014,
-0x281404,
-0xca0c00,
-0xca1000,
-0xca1c00,
-0xca2400,
-0xe2001f,
-0xd4c01a,
-0xd5001a,
-0xd5401a,
-0xcc1803,
-0xcc2c03,
-0xcc2c03,
-0xcc2c03,
-0x7da58b,
-0x7d9c47,
-0x984297,
-0x000000,
-0x800161,
-0xd4c01a,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c06,
-0x0ccc06,
-0x98c006,
-0xcc104e,
-0x990004,
-0xd40073,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xca0800,
-0xca0c00,
-0x34d018,
-0x251001,
-0x950021,
-0xc17fff,
-0xca1000,
-0xca1400,
-0xca1800,
-0xd4801d,
-0xd4c01d,
-0x7db18b,
-0xc14202,
-0xc2c001,
-0xd5801d,
-0x34dc0e,
-0x7d5d4c,
-0x7f734c,
-0xd7401e,
-0xd5001e,
-0xd5401e,
-0xc14200,
-0xc2c000,
-0x099c01,
-0x31dc10,
-0x7f5f4c,
-0x7f734c,
-0x042802,
-0x7d8380,
-0xd5a86f,
-0xd58066,
-0xd7401e,
-0xec005e,
-0xc82402,
-0xc82402,
-0x8001b8,
-0xd60076,
-0xd4401e,
-0xd4801e,
-0xd4c01e,
-0x800000,
-0xee001e,
-0x800000,
-0xee001f,
-0xd4001f,
-0x800000,
-0xd4001f,
-0xd4001f,
-0x880000,
-0xd4001f,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x010171,
-0x020178,
-0x03008f,
-0x04007f,
-0x050003,
-0x06003f,
-0x070032,
-0x08012c,
-0x090046,
-0x0a0036,
-0x1001b6,
-0x1700a2,
-0x22013a,
-0x230149,
-0x2000b4,
-0x240125,
-0x27004d,
-0x28006a,
-0x2a0060,
-0x2b0052,
-0x2f0065,
-0x320087,
-0x34017f,
-0x3c0156,
-0x3f0072,
-0x41018c,
-0x44012e,
-0x550173,
-0x56017a,
-0x60000b,
-0x610034,
-0x620038,
-0x630038,
-0x640038,
-0x650038,
-0x660038,
-0x670038,
-0x68003a,
-0x690041,
-0x6a0048,
-0x6b0048,
-0x6c0048,
-0x6d0048,
-0x6e0048,
-0x6f0048,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-};
-
-static const u32 RV630_cp_microcode[][3] = {
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0000ffff, 0x00284621, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000000, 0x00e00000, 0x000 },
-    { 0x00010000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000f00, 0x00281622, 0x000 },
-    { 0x00000008, 0x00211625, 0x000 },
-    { 0x00000018, 0x00203625, 0x000 },
-    { 0x8d000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x002f0225, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x018 },
-    { 0x00412000, 0x00404811, 0x019 },
-    { 0x00422000, 0x00204811, 0x000 },
-    { 0x8e000000, 0x00204411, 0x000 },
-    { 0x00000028, 0x00204a2d, 0x000 },
-    { 0x90000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x0000000c, 0x00211622, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000019, 0x00211a22, 0x000 },
-    { 0x00000004, 0x00281a26, 0x000 },
-    { 0x00000000, 0x002914c5, 0x000 },
-    { 0x00000019, 0x00203625, 0x000 },
-    { 0x00000000, 0x003a1402, 0x000 },
-    { 0x00000016, 0x00211625, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0xfffffffc, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002914a3, 0x000 },
-    { 0x00000017, 0x00203625, 0x000 },
-    { 0x00008000, 0x00280e22, 0x000 },
-    { 0x00000007, 0x00220e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x20000000, 0x00280e22, 0x000 },
-    { 0x00000006, 0x00210e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x00000000, 0x00220222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x038 },
-    { 0x00000000, 0x2ee00000, 0x035 },
-    { 0x00000000, 0x2ce00000, 0x037 },
-    { 0x00000000, 0x00400e2d, 0x039 },
-    { 0x00000008, 0x00200e2d, 0x000 },
-    { 0x00000009, 0x0040122d, 0x046 },
-    { 0x00000001, 0x00400e2d, 0x039 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x03e },
-    { 0x00000008, 0x00401c11, 0x041 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x0000000f, 0x00281e27, 0x000 },
-    { 0x00000003, 0x00221e27, 0x000 },
-    { 0x7fc00000, 0x00281a23, 0x000 },
-    { 0x00000014, 0x00211a26, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000008, 0x00221a26, 0x000 },
-    { 0x00000000, 0x00290cc7, 0x000 },
-    { 0x00000027, 0x00203624, 0x000 },
-    { 0x00007f00, 0x00281221, 0x000 },
-    { 0x00001400, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x04b },
-    { 0x00000001, 0x00290e23, 0x000 },
-    { 0x0000000e, 0x00203623, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfff80000, 0x00294a23, 0x000 },
-    { 0x00000000, 0x003a2c02, 0x000 },
-    { 0x00000002, 0x00220e2b, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x0000000f, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00204a2d, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000029, 0x00200e2d, 0x000 },
-    { 0x060a0200, 0x00294a23, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x061 },
-    { 0x00000000, 0x2ee00000, 0x05f },
-    { 0x00000000, 0x2ce00000, 0x05e },
-    { 0x00000000, 0x00400e2d, 0x062 },
-    { 0x00000001, 0x00400e2d, 0x062 },
-    { 0x0000000a, 0x00200e2d, 0x000 },
-    { 0x0000000b, 0x0040122d, 0x06a },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x7fc00000, 0x00281623, 0x000 },
-    { 0x00000014, 0x00211625, 0x000 },
-    { 0x00000001, 0x00331625, 0x000 },
-    { 0x80000000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00290ca3, 0x000 },
-    { 0x3ffffc00, 0x00290e23, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x06d },
-    { 0x00000100, 0x00401c11, 0x070 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x000000f0, 0x00281e27, 0x000 },
-    { 0x00000004, 0x00221e27, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0xfffff0ff, 0x00281a30, 0x000 },
-    { 0x0000a028, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948e6, 0x000 },
-    { 0x0000a018, 0x00204411, 0x000 },
-    { 0x3fffffff, 0x00284a23, 0x000 },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000030, 0x0020162d, 0x000 },
-    { 0x00000002, 0x00291625, 0x000 },
-    { 0x00000030, 0x00203625, 0x000 },
-    { 0x00000025, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a3, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x083 },
-    { 0x00000026, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a4, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x084 },
-    { 0x00000000, 0x00400000, 0x08a },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203624, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x08a },
-    { 0x00000000, 0x00600000, 0x665 },
-    { 0x00000000, 0x00600000, 0x659 },
-    { 0x00000002, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x08d },
-    { 0x00000012, 0xc0403620, 0x093 },
-    { 0x00000000, 0x2ee00000, 0x091 },
-    { 0x00000000, 0x2ce00000, 0x090 },
-    { 0x00000002, 0x00400e2d, 0x092 },
-    { 0x00000003, 0x00400e2d, 0x092 },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000012, 0x00203623, 0x000 },
-    { 0x00000003, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x098 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x0a0 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x2ee00000, 0x09e },
-    { 0x00000000, 0x2ce00000, 0x09d },
-    { 0x00000002, 0x00400e2d, 0x09f },
-    { 0x00000003, 0x00400e2d, 0x09f },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x003f0000, 0x00280e23, 0x000 },
-    { 0x00000010, 0x00210e23, 0x000 },
-    { 0x00000011, 0x00203623, 0x000 },
-    { 0x0000001e, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a7 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x0000001f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0aa },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000008, 0x00210e2b, 0x000 },
-    { 0x0000007f, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0e1 },
-    { 0x00000000, 0x27000000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x0b3 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000000c, 0x00221e30, 0x000 },
-    { 0x99800000, 0x00204411, 0x000 },
-    { 0x00000004, 0x0020122d, 0x000 },
-    { 0x00000008, 0x00221224, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00291ce4, 0x000 },
-    { 0x00000000, 0x00604807, 0x12f },
-    { 0x9b000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x9c000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x0033146f, 0x000 },
-    { 0x00000001, 0x00333e23, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0x00203c05, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e007, 0x00204411, 0x000 },
-    { 0x0000000f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0cb },
-    { 0x00f8ff08, 0x00204811, 0x000 },
-    { 0x98000000, 0x00404811, 0x0dc },
-    { 0x000000f0, 0x00280e22, 0x000 },
-    { 0x000000a0, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0da },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d5 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d4 },
-    { 0x00003f00, 0x00400c11, 0x0d6 },
-    { 0x00001f00, 0x00400c11, 0x0d6 },
-    { 0x00000f00, 0x00200c11, 0x000 },
-    { 0x00380009, 0x00294a23, 0x000 },
-    { 0x3f000000, 0x00280e2b, 0x000 },
-    { 0x00000002, 0x00220e23, 0x000 },
-    { 0x00000007, 0x00494a23, 0x0dc },
-    { 0x00380f09, 0x00204811, 0x000 },
-    { 0x68000007, 0x00204811, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000a202, 0x00204411, 0x000 },
-    { 0x00ff0000, 0x00280e22, 0x000 },
-    { 0x00000080, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00200e2d, 0x000 },
-    { 0x00000026, 0x0020122d, 0x000 },
-    { 0x00000000, 0x002f0083, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0ea },
-    { 0x00000000, 0x00600000, 0x65f },
-    { 0x00000000, 0x00400000, 0x0eb },
-    { 0x00000000, 0x00600000, 0x662 },
-    { 0x00000007, 0x0020222d, 0x000 },
-    { 0x00000005, 0x00220e22, 0x000 },
-    { 0x00100000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x000000ef, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000003, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x0f8 },
-    { 0x0000000b, 0x00210228, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f8 },
-    { 0x00000400, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000001c, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0fd },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000001e, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x10b },
-    { 0x0000a30f, 0x00204411, 0x000 },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x104 },
-    { 0xffffffff, 0x00404811, 0x10b },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x107 },
-    { 0x0000ffff, 0x00404811, 0x10b },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x10a },
-    { 0x000000ff, 0x00404811, 0x10b },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0002c400, 0x00204411, 0x000 },
-    { 0x0000001f, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x112 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000018, 0x40224a20, 0x000 },
-    { 0x00000010, 0xc0424a20, 0x114 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000000a, 0x00201011, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x11b },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00531224, 0x117 },
-    { 0xffbfffff, 0x00283a2e, 0x000 },
-    { 0x0000001b, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x12e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x00000018, 0x00220e30, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e00e, 0x00204411, 0x000 },
-    { 0x07f8ff08, 0x00204811, 0x000 },
-    { 0x00000000, 0x00294a23, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00800000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204806, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x689 },
-    { 0x00000004, 0x00404c11, 0x135 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000001c, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x13c },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40280620, 0x000 },
-    { 0x00000010, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x00341461, 0x000 },
-    { 0x00000000, 0x00741882, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x147 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0681a20, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x158 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000001, 0x00300a2f, 0x000 },
-    { 0x00000001, 0x00210a22, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600000, 0x18f },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00202c08, 0x000 },
-    { 0x00000000, 0x00202411, 0x000 },
-    { 0x00000000, 0x00202811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00221e29, 0x000 },
-    { 0x00000000, 0x007048eb, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000001, 0x40330620, 0x000 },
-    { 0x00000000, 0xc0302409, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x181 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x186 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x186 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000001, 0x00530621, 0x182 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0604800, 0x197 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000011, 0x0020062d, 0x000 },
-    { 0x00000000, 0x0078042a, 0x2fb },
-    { 0x00000000, 0x00202809, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x174 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x194 },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x46000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x19b },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00804811, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40281620, 0x000 },
-    { 0x00000010, 0xc0811a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000008, 0x00221e30, 0x000 },
-    { 0x00000029, 0x00201a2d, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfffbff09, 0x00204811, 0x000 },
-    { 0x0000000f, 0x0020222d, 0x000 },
-    { 0x00001fff, 0x00294a28, 0x000 },
-    { 0x00000006, 0x0020222d, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000100, 0x00201811, 0x000 },
-    { 0x00000008, 0x00621e28, 0x12f },
-    { 0x00000008, 0x00822228, 0x000 },
-    { 0x0002c000, 0x00204411, 0x000 },
-    { 0x00000015, 0x00600e2d, 0x1bd },
-    { 0x00000016, 0x00600e2d, 0x1bd },
-    { 0x0000c008, 0x00204411, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x1b9 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x39000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00804802, 0x000 },
-    { 0x00000018, 0x00202e2d, 0x000 },
-    { 0x00000000, 0x003b0d63, 0x000 },
-    { 0x00000008, 0x00224a23, 0x000 },
-    { 0x00000010, 0x00224a23, 0x000 },
-    { 0x00000018, 0x00224a23, 0x000 },
-    { 0x00000000, 0x00804803, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000007, 0x0021062f, 0x000 },
-    { 0x00000013, 0x00200a2d, 0x000 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000ffff, 0x40282220, 0x000 },
-    { 0x0000000f, 0x00262228, 0x000 },
-    { 0x00000010, 0x40212620, 0x000 },
-    { 0x0000000f, 0x00262629, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1e0 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000081, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000080, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1dc },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1d8 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000001f, 0x00280a22, 0x000 },
-    { 0x0000001f, 0x00282a2a, 0x000 },
-    { 0x00000001, 0x00530621, 0x1d1 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000002, 0x00304a2f, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000001, 0x00301e2f, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1e5 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x0000000f, 0x00260e23, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000000f, 0x00261224, 0x000 },
-    { 0x00000000, 0x00201411, 0x000 },
-    { 0x00000000, 0x00601811, 0x2bb },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022b, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1f8 },
-    { 0x00000010, 0x00221628, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a29, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x0020480a, 0x000 },
-    { 0x00000000, 0x00202c11, 0x000 },
-    { 0x00000010, 0x00221623, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a24, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x00731503, 0x205 },
-    { 0x00000000, 0x00201805, 0x000 },
-    { 0x00000000, 0x00731524, 0x205 },
-    { 0x00000000, 0x002d14c5, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00000000, 0x00202003, 0x000 },
-    { 0x00000000, 0x00802404, 0x000 },
-    { 0x0000000f, 0x00210225, 0x000 },
-    { 0x00000000, 0x14c00000, 0x689 },
-    { 0x00000000, 0x002b1405, 0x000 },
-    { 0x00000001, 0x00901625, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00294a22, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a21, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000ffff, 0x40281220, 0x000 },
-    { 0x00000010, 0xc0211a20, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211620, 0x000 },
-    { 0x00000000, 0x00741465, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00000001, 0x00330621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x219 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x212 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000000, 0x0040040f, 0x213 },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00000000, 0x00600000, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x232 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x236 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x236 },
-    { 0x00000000, 0xc0404800, 0x233 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x00600411, 0x2fb },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000018, 0x40210a20, 0x000 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x24c },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x00080101, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x251 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000010, 0x00600411, 0x315 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00000000, 0x00600000, 0x27c },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000001, 0x00211e27, 0x000 },
-    { 0x00000000, 0x14e00000, 0x26a },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x0000ffff, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00341c27, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25f },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e5, 0x000 },
-    { 0x00000000, 0x08c00000, 0x262 },
-    { 0x00000000, 0x00201407, 0x000 },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00211e27, 0x000 },
-    { 0x00000000, 0x00341c47, 0x000 },
-    { 0x00000000, 0x12c00000, 0x267 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x08c00000, 0x26a },
-    { 0x00000000, 0x00201807, 0x000 },
-    { 0x00000000, 0x00600000, 0x2c1 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000000, 0x00342023, 0x000 },
-    { 0x00000000, 0x12c00000, 0x272 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x271 },
-    { 0x00000016, 0x00404811, 0x276 },
-    { 0x00000018, 0x00404811, 0x276 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x275 },
-    { 0x00000017, 0x00404811, 0x276 },
-    { 0x00000019, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00604411, 0x2e9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x256 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000010, 0x40210620, 0x000 },
-    { 0x0000ffff, 0xc0280a20, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0881a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x00000000, 0xc0600000, 0x2a3 },
-    { 0x00000005, 0x00200a2d, 0x000 },
-    { 0x00000008, 0x00220a22, 0x000 },
-    { 0x0000002b, 0x00201a2d, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00007000, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00311ce6, 0x000 },
-    { 0x0000002a, 0x00201a2d, 0x000 },
-    { 0x0000000c, 0x00221a26, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x06e00000, 0x292 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00691ce2, 0x12f },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x29d },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000001c, 0x00403627, 0x000 },
-    { 0x0000000c, 0xc0220a20, 0x000 },
-    { 0x00000029, 0x00203622, 0x000 },
-    { 0x00000028, 0xc0403620, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000009, 0x00204811, 0x000 },
-    { 0xa1000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce3, 0x000 },
-    { 0x00000021, 0x00203627, 0x000 },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce4, 0x000 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a3, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203624, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000000, 0x00311cc4, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14c00000, 0x2dc },
-    { 0x00000000, 0x00400000, 0x2d9 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2d9 },
-    { 0x00000003, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2dc },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e1, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a1, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e2, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000000, 0x00600000, 0x665 },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00600000, 0x65c },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2a7 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x0000001a, 0x00201e2d, 0x000 },
-    { 0x0000001b, 0x0080222d, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca1, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x003808c5, 0x000 },
-    { 0x00000000, 0x00300841, 0x000 },
-    { 0x00000001, 0x00220a22, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000017, 0x0020222d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x318 },
-    { 0xffffffef, 0x00280621, 0x000 },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x0000f8e0, 0x00204411, 0x000 },
-    { 0x00000000, 0x00294901, 0x000 },
-    { 0x00000000, 0x00894901, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00002257, 0x00204411, 0x000 },
-    { 0x00000003, 0xc0484a20, 0x000 },
-    { 0x0000225d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x00000001, 0x40304a20, 0x000 },
-    { 0x00000002, 0xc0304a20, 0x000 },
-    { 0x00000001, 0x00530a22, 0x34b },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x354 },
-    { 0x00000014, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x364 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00604802, 0x36e },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x36a },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x00000028, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5bd },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x0000002c, 0x00203626, 0x000 },
-    { 0x00000049, 0x00201811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000000, 0x002f0226, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x370 },
-    { 0x0000002c, 0x00801a2d, 0x000 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x00000015, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x386 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b1 },
-    { 0x00000016, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b5 },
-    { 0x00000020, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x39c },
-    { 0x0000000f, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x0000001e, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x390 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x08000000, 0x00290a22, 0x000 },
-    { 0x00000003, 0x40210e20, 0x000 },
-    { 0x0000000c, 0xc0211220, 0x000 },
-    { 0x00080000, 0x00281224, 0x000 },
-    { 0x00000014, 0xc0221620, 0x000 },
-    { 0x00000000, 0x002914a4, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948a2, 0x000 },
-    { 0x0000a1fe, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000015, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x392 },
-    { 0x0000210e, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000003, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x39e },
-    { 0x00002108, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x80000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000010, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3ae },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000006, 0x00404811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x0000001d, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3ce },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3c0 },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0xbabecafe, 0x00204811, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000004, 0x00404811, 0x000 },
-    { 0x00002170, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000a, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3d3 },
-    { 0x8c000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00003fff, 0x40280a20, 0x000 },
-    { 0x80000000, 0x40280e20, 0x000 },
-    { 0x40000000, 0xc0281220, 0x000 },
-    { 0x00040000, 0x00694622, 0x68a },
-    { 0x00000000, 0x00201410, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e1 },
-    { 0x00000000, 0xc0401800, 0x3e4 },
-    { 0x00003fff, 0xc0281a20, 0x000 },
-    { 0x00040000, 0x00694626, 0x68a },
-    { 0x00000000, 0x00201810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e7 },
-    { 0x00000000, 0xc0401c00, 0x3ea },
-    { 0x00003fff, 0xc0281e20, 0x000 },
-    { 0x00040000, 0x00694627, 0x68a },
-    { 0x00000000, 0x00201c10, 0x000 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0x002820c5, 0x000 },
-    { 0x00000000, 0x004948e8, 0x000 },
-    { 0xa5800000, 0x00200811, 0x000 },
-    { 0x00002000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x0000001f, 0xc0210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3f7 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000ffff, 0xc0481220, 0x3ff },
-    { 0xa7800000, 0x00200811, 0x000 },
-    { 0x0000a000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00304883, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xa9800000, 0x00200811, 0x000 },
-    { 0x0000c000, 0x00400c11, 0x3fa },
-    { 0xab800000, 0x00200811, 0x000 },
-    { 0x0000f8e0, 0x00400c11, 0x3fa },
-    { 0xad800000, 0x00200811, 0x000 },
-    { 0x0000f880, 0x00400c11, 0x3fa },
-    { 0xb3800000, 0x00200811, 0x000 },
-    { 0x0000f3fc, 0x00400c11, 0x3fa },
-    { 0xaf800000, 0x00200811, 0x000 },
-    { 0x0000e000, 0x00400c11, 0x3fa },
-    { 0xb1800000, 0x00200811, 0x000 },
-    { 0x0000f000, 0x00400c11, 0x3fa },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00002148, 0x00204811, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x01182000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0218a000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0318c000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0418f8e0, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0518f880, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0618e000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0718f000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0818f3fc, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000030, 0x00200a2d, 0x000 },
-    { 0x00000000, 0xc0290c40, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x86000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x85000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00404c02, 0x448 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x00000000, 0xc0201400, 0x000 },
-    { 0x00000000, 0xc0201800, 0x000 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x456 },
-    { 0x00000000, 0xc0202000, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x00000010, 0x00280a23, 0x000 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x45e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0x00694624, 0x68a },
-    { 0x00000000, 0x00400000, 0x463 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00604805, 0x68f },
-    { 0x00000000, 0x002824f0, 0x000 },
-    { 0x00000007, 0x00280a23, 0x000 },
-    { 0x00000001, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46a },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x04e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000002, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46f },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x02e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x474 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x479 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000005, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x47e },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x06e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x483 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x08e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x000 },
-    { 0x00000008, 0x00210a23, 0x000 },
-    { 0x00000000, 0x14c00000, 0x48d },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x496 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x00404c08, 0x456 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000011, 0x40211220, 0x000 },
-    { 0x00000012, 0x40211620, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00210225, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4a0 },
-    { 0x00040000, 0xc0494a20, 0x4a1 },
-    { 0xfffbffff, 0xc0284a20, 0x000 },
-    { 0x00000000, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4ad },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000c, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4a9 },
-    { 0xa0000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x00204811, 0x000 },
-    { 0x0000216b, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000216c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4a7 },
-    { 0x00000000, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4c0 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x68f },
-    { 0x00000000, 0x00400000, 0x4c4 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xc0600000, 0x68a },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4cb },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0404810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000000, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4cd },
-    { 0x00002180, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000003, 0x00333e2f, 0x000 },
-    { 0x00000001, 0x00210221, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4fd },
-    { 0x0000002c, 0x00200a2d, 0x000 },
-    { 0x00040000, 0x18e00c11, 0x4ec },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xd8c04800, 0x4e0 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000002d, 0x0020122d, 0x000 },
-    { 0x00000000, 0x00290c83, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000011, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4a7 },
-    { 0x0000002c, 0xc0203620, 0x000 },
-    { 0x0000002d, 0xc0403620, 0x000 },
-    { 0x0000000f, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x502 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0xd9000000, 0x000 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xb5000000, 0x00204411, 0x000 },
-    { 0x00002000, 0x00204811, 0x000 },
-    { 0xb6000000, 0x00204411, 0x000 },
-    { 0x0000a000, 0x00204811, 0x000 },
-    { 0xb7000000, 0x00204411, 0x000 },
-    { 0x0000c000, 0x00204811, 0x000 },
-    { 0xb8000000, 0x00204411, 0x000 },
-    { 0x0000f8e0, 0x00204811, 0x000 },
-    { 0xb9000000, 0x00204411, 0x000 },
-    { 0x0000f880, 0x00204811, 0x000 },
-    { 0xba000000, 0x00204411, 0x000 },
-    { 0x0000e000, 0x00204811, 0x000 },
-    { 0xbb000000, 0x00204411, 0x000 },
-    { 0x0000f000, 0x00204811, 0x000 },
-    { 0xbc000000, 0x00204411, 0x000 },
-    { 0x0000f3fc, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00204811, 0x000 },
-    { 0x000000ff, 0x00280e30, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x516 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x14c00000, 0x52b },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000001c, 0x00203623, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x00000028, 0x00203623, 0x000 },
-    { 0x00000017, 0x00203623, 0x000 },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203623, 0x000 },
-    { 0x00000015, 0x00203623, 0x000 },
-    { 0x00000016, 0x00203623, 0x000 },
-    { 0xffffe000, 0x00200c11, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00200c11, 0x000 },
-    { 0x00000023, 0x00203623, 0x000 },
-    { 0x00000024, 0x00203623, 0x000 },
-    { 0xf1ffffff, 0x00283a2e, 0x000 },
-    { 0x0000001a, 0xc0220e20, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000002a, 0x40203620, 0x000 },
-    { 0x87000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x9d000000, 0x00204411, 0x000 },
-    { 0x0000001f, 0x40214a20, 0x000 },
-    { 0x96000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x0000001f, 0x00211624, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x0000001d, 0x00203623, 0x000 },
-    { 0x00000003, 0x00281e23, 0x000 },
-    { 0x00000008, 0x00222223, 0x000 },
-    { 0xfffff000, 0x00282228, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x0000001f, 0x00203628, 0x000 },
-    { 0x00000018, 0x00211e23, 0x000 },
-    { 0x00000020, 0x00203627, 0x000 },
-    { 0x00000002, 0x00221624, 0x000 },
-    { 0x00000000, 0x003014a8, 0x000 },
-    { 0x0000001e, 0x00203625, 0x000 },
-    { 0x00000003, 0x00211a24, 0x000 },
-    { 0x10000000, 0x00281a26, 0x000 },
-    { 0xefffffff, 0x00283a2e, 0x000 },
-    { 0x00000000, 0x004938ce, 0x678 },
-    { 0x00000001, 0x40280a20, 0x000 },
-    { 0x00000006, 0x40280e20, 0x000 },
-    { 0x00000300, 0xc0281220, 0x000 },
-    { 0x00000008, 0x00211224, 0x000 },
-    { 0x00000000, 0xc0201620, 0x000 },
-    { 0x00000000, 0xc0201a20, 0x000 },
-    { 0x00000000, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x563 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68a },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00020000, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56b },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x579 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56b },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68a },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x579 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56f },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00000000, 0xc0400000, 0x579 },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x577 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x68f },
-    { 0x00000000, 0x00401c10, 0x579 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x57b },
-    { 0x00000000, 0x00600000, 0x5c6 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x58c },
-    { 0x0000a2b7, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c4, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x58a },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000001, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x59d },
-    { 0x0000a2bb, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c5, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x59b },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000002, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5ae },
-    { 0x0000a2bf, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c6, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5ac },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x0000a2c3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c7, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5bb },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0x01000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00400000, 0x5c1 },
-    { 0xa4000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5c6 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000002c, 0x00203621, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5cd },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000030, 0x00403621, 0x5e0 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x5e0 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a092, 0x00604411, 0x68a },
-    { 0x00000031, 0x00203630, 0x000 },
-    { 0x0004a093, 0x00604411, 0x68a },
-    { 0x00000032, 0x00203630, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68a },
-    { 0x00000033, 0x00203630, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68a },
-    { 0x00000034, 0x00203630, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68a },
-    { 0x00000035, 0x00203630, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68a },
-    { 0x00000036, 0x00203630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x88000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000001, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x629 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x629 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x602 },
-    { 0x0000a092, 0x00204411, 0x000 },
-    { 0x00000031, 0x00204a2d, 0x000 },
-    { 0x0000a093, 0x00204411, 0x000 },
-    { 0x00000032, 0x00204a2d, 0x000 },
-    { 0x0000a2b6, 0x00204411, 0x000 },
-    { 0x00000033, 0x00204a2d, 0x000 },
-    { 0x0000a2ba, 0x00204411, 0x000 },
-    { 0x00000034, 0x00204a2d, 0x000 },
-    { 0x0000a2be, 0x00204411, 0x000 },
-    { 0x00000035, 0x00204a2d, 0x000 },
-    { 0x0000a2c2, 0x00204411, 0x000 },
-    { 0x00000036, 0x00204a2d, 0x000 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x000001ff, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x628 },
-    { 0x00000000, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x60b },
-    { 0x0004a003, 0x00604411, 0x68a },
-    { 0x0000a003, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x14c00000, 0x610 },
-    { 0x0004a010, 0x00604411, 0x68a },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x628 },
-    { 0x0004a011, 0x00604411, 0x68a },
-    { 0x0000a011, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a012, 0x00604411, 0x68a },
-    { 0x0000a012, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a013, 0x00604411, 0x68a },
-    { 0x0000a013, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a014, 0x00604411, 0x68a },
-    { 0x0000a014, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a015, 0x00604411, 0x68a },
-    { 0x0000a015, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a016, 0x00604411, 0x68a },
-    { 0x0000a016, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a017, 0x00604411, 0x68a },
-    { 0x0000a017, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000002c, 0x0080062d, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x63a },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000002, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x638 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x00001000, 0x00200811, 0x000 },
-    { 0x0000002b, 0x00203622, 0x000 },
-    { 0x00000000, 0x00600000, 0x63e },
-    { 0x00000000, 0x00600000, 0x5c6 },
-    { 0x98000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0600000, 0x63e },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000022, 0x00204811, 0x000 },
-    { 0x89000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00404811, 0x62a },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404811, 0x62a },
-    { 0x00000000, 0x00600000, 0x659 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0xc0204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x09800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000004, 0x00404c11, 0x653 },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000004, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffffb, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffff7, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x01800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x689 },
-    { 0x00000010, 0x00404c11, 0x66f },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x38c00000, 0x000 },
-    { 0x0000001d, 0x00200a2d, 0x000 },
-    { 0x0000001e, 0x00200e2d, 0x000 },
-    { 0x0000001f, 0x0020122d, 0x000 },
-    { 0x00000020, 0x0020162d, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000004, 0x00301224, 0x000 },
-    { 0x00000000, 0x002f0064, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x688 },
-    { 0x00000003, 0x00281a22, 0x000 },
-    { 0x00000008, 0x00221222, 0x000 },
-    { 0xfffff000, 0x00281224, 0x000 },
-    { 0x00000000, 0x002910c4, 0x000 },
-    { 0x0000001f, 0x00403624, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x68a },
-    { 0x9f000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x68d },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x68f },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x692 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0xc0204411, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000024, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000022, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x014204ff, 0x05bd0250, 0x000 },
-    { 0x01c30168, 0x043f05bd, 0x000 },
-    { 0x02250209, 0x02500151, 0x000 },
-    { 0x02230245, 0x02a00241, 0x000 },
-    { 0x03d705bd, 0x05bd05bd, 0x000 },
-    { 0x06460647, 0x031f05bd, 0x000 },
-    { 0x05bd05c2, 0x03200340, 0x000 },
-    { 0x032a0282, 0x03420334, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd054e, 0x05bd05bd, 0x000 },
-    { 0x03ba05bd, 0x04b80344, 0x000 },
-    { 0x0497044d, 0x043d05bd, 0x000 },
-    { 0x04cd05bd, 0x044104da, 0x000 },
-    { 0x044d0504, 0x03510375, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x063c05c4, 0x000 },
-    { 0x05bd05bd, 0x000705bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x03f803ed, 0x04080406, 0x000 },
-    { 0x040e040a, 0x040c0410, 0x000 },
-    { 0x041c0418, 0x04240420, 0x000 },
-    { 0x042c0428, 0x04340430, 0x000 },
-    { 0x05bd05bd, 0x043805bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x00020676, 0x06940006, 0x000 },
-};
-
-static const u32 RV630_pfp_microcode[] = {
-0xca0400,
-0xa00000,
-0x7e828b,
-0x7c038b,
-0x8001b8,
-0x7c038b,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xc41838,
-0xca2400,
-0xca2800,
-0x9581a8,
-0xc41c3a,
-0xc3c000,
-0xca0800,
-0xca0c00,
-0x7c744b,
-0xc20005,
-0x99c000,
-0xc41c3a,
-0x7c744c,
-0xc0fff0,
-0x042c04,
-0x309002,
-0x7d2500,
-0x351402,
-0x7d350b,
-0x255403,
-0x7cd580,
-0x259c03,
-0x95c004,
-0xd5001b,
-0x7eddc1,
-0x7d9d80,
-0xd6801b,
-0xd5801b,
-0xd4401e,
-0xd5401e,
-0xd6401e,
-0xd6801e,
-0xd4801e,
-0xd4c01e,
-0x9783d3,
-0xd5c01e,
-0xca0800,
-0x80001a,
-0xca0c00,
-0xe4011e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xe4013e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca1800,
-0xd4401e,
-0xd5801e,
-0x800053,
-0xd40075,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xe2001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0xd48060,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xd48061,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xca0c00,
-0xd4401e,
-0xd48016,
-0xd4c016,
-0xd4801e,
-0x8001b8,
-0xd4c01e,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x948004,
-0xca1400,
-0xe420f3,
-0xd42013,
-0xd56065,
-0xd4e01c,
-0xd5201c,
-0xd5601c,
-0x800000,
-0x062001,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9483f7,
-0xca1400,
-0xe420f3,
-0x800079,
-0xd42013,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9883ef,
-0xca1400,
-0xd40064,
-0x80008d,
-0x000000,
-0xc41432,
-0xc61843,
-0xc4082f,
-0x954005,
-0xc40c30,
-0xd4401e,
-0x800000,
-0xee001e,
-0x9583f5,
-0xc41031,
-0xd44033,
-0xd52065,
-0xd4a01c,
-0xd4e01c,
-0xd5201c,
-0xe4015e,
-0xd4001e,
-0x800000,
-0x062001,
-0xca1800,
-0x0a2001,
-0xd60076,
-0xc40836,
-0x988007,
-0xc61045,
-0x950110,
-0xd4001f,
-0xd46062,
-0x800000,
-0xd42062,
-0xcc3835,
-0xcc1433,
-0x8401bb,
-0xd40072,
-0xd5401e,
-0x800000,
-0xee001e,
-0xe2001a,
-0x8401bb,
-0xe2001a,
-0xcc104b,
-0xcc0447,
-0x2c9401,
-0x7d098b,
-0x984005,
-0x7d15cb,
-0xd4001a,
-0x8001b8,
-0xd4006d,
-0x344401,
-0xcc0c48,
-0x98403a,
-0xcc2c4a,
-0x958004,
-0xcc0449,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0x282801,
-0x8400f0,
-0xcc1003,
-0x98801b,
-0x04380c,
-0x8400f0,
-0xcc1003,
-0x988017,
-0x043808,
-0x8400f0,
-0xcc1003,
-0x988013,
-0x043804,
-0x8400f0,
-0xcc1003,
-0x988014,
-0xcc104c,
-0x9a8009,
-0xcc144d,
-0x9840dc,
-0xd4006d,
-0xcc1848,
-0xd5001a,
-0xd5401a,
-0x8000c9,
-0xd5801a,
-0x96c0d5,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0x9ac003,
-0xd4006d,
-0xd4006e,
-0x800000,
-0xec007f,
-0x9ac0cc,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0x7d9103,
-0x7dd583,
-0x7d190c,
-0x35cc1f,
-0x35701f,
-0x7cf0cb,
-0x7cd08b,
-0x880000,
-0x7e8e8b,
-0x95c004,
-0xd4006e,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0xcc0803,
-0xcc0c03,
-0xcc1003,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0xcc2403,
-0xcc2803,
-0x35c41f,
-0x36b01f,
-0x7c704b,
-0x34f01f,
-0x7c704b,
-0x35701f,
-0x7c704b,
-0x7d8881,
-0x7dccc1,
-0x7e5101,
-0x7e9541,
-0x7c9082,
-0x7cd4c2,
-0x7c848b,
-0x9ac003,
-0x7c8c8b,
-0x2c8801,
-0x98809e,
-0xd4006d,
-0x98409c,
-0xd4006e,
-0xcc084c,
-0xcc0c4d,
-0xcc1048,
-0xd4801a,
-0xd4c01a,
-0x800101,
-0xd5001a,
-0xcc0832,
-0xd40032,
-0x9482d9,
-0xca0c00,
-0xd4401e,
-0x800000,
-0xd4001e,
-0xe4011e,
-0xd4001e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd4401e,
-0xca1400,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xd5401e,
-0xd54034,
-0x800000,
-0xee001e,
-0x280404,
-0xe2001a,
-0xe2001a,
-0xd4401a,
-0xca3800,
-0xcc0803,
-0xcc0c03,
-0xcc0c03,
-0xcc0c03,
-0x9882bd,
-0x000000,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0400,
-0xc2ff00,
-0xcc0834,
-0xc13fff,
-0x7c74cb,
-0x7cc90b,
-0x7d010f,
-0x9902b0,
-0x7c738b,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0800,
-0x281900,
-0x7d898b,
-0x958014,
-0x281404,
-0xca0c00,
-0xca1000,
-0xca1c00,
-0xca2400,
-0xe2001f,
-0xd4c01a,
-0xd5001a,
-0xd5401a,
-0xcc1803,
-0xcc2c03,
-0xcc2c03,
-0xcc2c03,
-0x7da58b,
-0x7d9c47,
-0x984297,
-0x000000,
-0x800161,
-0xd4c01a,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c06,
-0x0ccc06,
-0x98c006,
-0xcc104e,
-0x990004,
-0xd40073,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xca0800,
-0xca0c00,
-0x34d018,
-0x251001,
-0x950021,
-0xc17fff,
-0xca1000,
-0xca1400,
-0xca1800,
-0xd4801d,
-0xd4c01d,
-0x7db18b,
-0xc14202,
-0xc2c001,
-0xd5801d,
-0x34dc0e,
-0x7d5d4c,
-0x7f734c,
-0xd7401e,
-0xd5001e,
-0xd5401e,
-0xc14200,
-0xc2c000,
-0x099c01,
-0x31dc10,
-0x7f5f4c,
-0x7f734c,
-0x042802,
-0x7d8380,
-0xd5a86f,
-0xd58066,
-0xd7401e,
-0xec005e,
-0xc82402,
-0xc82402,
-0x8001b8,
-0xd60076,
-0xd4401e,
-0xd4801e,
-0xd4c01e,
-0x800000,
-0xee001e,
-0x800000,
-0xee001f,
-0xd4001f,
-0x800000,
-0xd4001f,
-0xd4001f,
-0x880000,
-0xd4001f,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x010171,
-0x020178,
-0x03008f,
-0x04007f,
-0x050003,
-0x06003f,
-0x070032,
-0x08012c,
-0x090046,
-0x0a0036,
-0x1001b6,
-0x1700a2,
-0x22013a,
-0x230149,
-0x2000b4,
-0x240125,
-0x27004d,
-0x28006a,
-0x2a0060,
-0x2b0052,
-0x2f0065,
-0x320087,
-0x34017f,
-0x3c0156,
-0x3f0072,
-0x41018c,
-0x44012e,
-0x550173,
-0x56017a,
-0x60000b,
-0x610034,
-0x620038,
-0x630038,
-0x640038,
-0x650038,
-0x660038,
-0x670038,
-0x68003a,
-0x690041,
-0x6a0048,
-0x6b0048,
-0x6c0048,
-0x6d0048,
-0x6e0048,
-0x6f0048,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-};
-
-static const u32 RV635_cp_microcode[][3] = {
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0000ffff, 0x00284621, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000000, 0x00e00000, 0x000 },
-    { 0x00010000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000f00, 0x00281622, 0x000 },
-    { 0x00000008, 0x00211625, 0x000 },
-    { 0x00000018, 0x00203625, 0x000 },
-    { 0x8d000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x002f0225, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x018 },
-    { 0x00412000, 0x00404811, 0x019 },
-    { 0x00422000, 0x00204811, 0x000 },
-    { 0x8e000000, 0x00204411, 0x000 },
-    { 0x00000028, 0x00204a2d, 0x000 },
-    { 0x90000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x0000000c, 0x00211622, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000019, 0x00211a22, 0x000 },
-    { 0x00000004, 0x00281a26, 0x000 },
-    { 0x00000000, 0x002914c5, 0x000 },
-    { 0x00000019, 0x00203625, 0x000 },
-    { 0x00000000, 0x003a1402, 0x000 },
-    { 0x00000016, 0x00211625, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0xfffffffc, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002914a3, 0x000 },
-    { 0x00000017, 0x00203625, 0x000 },
-    { 0x00008000, 0x00280e22, 0x000 },
-    { 0x00000007, 0x00220e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x20000000, 0x00280e22, 0x000 },
-    { 0x00000006, 0x00210e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x00000000, 0x00220222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x038 },
-    { 0x00000000, 0x2ee00000, 0x035 },
-    { 0x00000000, 0x2ce00000, 0x037 },
-    { 0x00000000, 0x00400e2d, 0x039 },
-    { 0x00000008, 0x00200e2d, 0x000 },
-    { 0x00000009, 0x0040122d, 0x046 },
-    { 0x00000001, 0x00400e2d, 0x039 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x03e },
-    { 0x00000008, 0x00401c11, 0x041 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x0000000f, 0x00281e27, 0x000 },
-    { 0x00000003, 0x00221e27, 0x000 },
-    { 0x7fc00000, 0x00281a23, 0x000 },
-    { 0x00000014, 0x00211a26, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000008, 0x00221a26, 0x000 },
-    { 0x00000000, 0x00290cc7, 0x000 },
-    { 0x00000027, 0x00203624, 0x000 },
-    { 0x00007f00, 0x00281221, 0x000 },
-    { 0x00001400, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x04b },
-    { 0x00000001, 0x00290e23, 0x000 },
-    { 0x0000000e, 0x00203623, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfff80000, 0x00294a23, 0x000 },
-    { 0x00000000, 0x003a2c02, 0x000 },
-    { 0x00000002, 0x00220e2b, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x0000000f, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00204a2d, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000029, 0x00200e2d, 0x000 },
-    { 0x060a0200, 0x00294a23, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x061 },
-    { 0x00000000, 0x2ee00000, 0x05f },
-    { 0x00000000, 0x2ce00000, 0x05e },
-    { 0x00000000, 0x00400e2d, 0x062 },
-    { 0x00000001, 0x00400e2d, 0x062 },
-    { 0x0000000a, 0x00200e2d, 0x000 },
-    { 0x0000000b, 0x0040122d, 0x06a },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x7fc00000, 0x00281623, 0x000 },
-    { 0x00000014, 0x00211625, 0x000 },
-    { 0x00000001, 0x00331625, 0x000 },
-    { 0x80000000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00290ca3, 0x000 },
-    { 0x3ffffc00, 0x00290e23, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x06d },
-    { 0x00000100, 0x00401c11, 0x070 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x000000f0, 0x00281e27, 0x000 },
-    { 0x00000004, 0x00221e27, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0xfffff0ff, 0x00281a30, 0x000 },
-    { 0x0000a028, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948e6, 0x000 },
-    { 0x0000a018, 0x00204411, 0x000 },
-    { 0x3fffffff, 0x00284a23, 0x000 },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000030, 0x0020162d, 0x000 },
-    { 0x00000002, 0x00291625, 0x000 },
-    { 0x00000030, 0x00203625, 0x000 },
-    { 0x00000025, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a3, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x083 },
-    { 0x00000026, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a4, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x084 },
-    { 0x00000000, 0x00400000, 0x08a },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203624, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x08a },
-    { 0x00000000, 0x00600000, 0x665 },
-    { 0x00000000, 0x00600000, 0x659 },
-    { 0x00000002, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x08d },
-    { 0x00000012, 0xc0403620, 0x093 },
-    { 0x00000000, 0x2ee00000, 0x091 },
-    { 0x00000000, 0x2ce00000, 0x090 },
-    { 0x00000002, 0x00400e2d, 0x092 },
-    { 0x00000003, 0x00400e2d, 0x092 },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000012, 0x00203623, 0x000 },
-    { 0x00000003, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x098 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x0a0 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x2ee00000, 0x09e },
-    { 0x00000000, 0x2ce00000, 0x09d },
-    { 0x00000002, 0x00400e2d, 0x09f },
-    { 0x00000003, 0x00400e2d, 0x09f },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x003f0000, 0x00280e23, 0x000 },
-    { 0x00000010, 0x00210e23, 0x000 },
-    { 0x00000011, 0x00203623, 0x000 },
-    { 0x0000001e, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a7 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x0000001f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0aa },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000008, 0x00210e2b, 0x000 },
-    { 0x0000007f, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0e1 },
-    { 0x00000000, 0x27000000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x0b3 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000000c, 0x00221e30, 0x000 },
-    { 0x99800000, 0x00204411, 0x000 },
-    { 0x00000004, 0x0020122d, 0x000 },
-    { 0x00000008, 0x00221224, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00291ce4, 0x000 },
-    { 0x00000000, 0x00604807, 0x12f },
-    { 0x9b000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x9c000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x0033146f, 0x000 },
-    { 0x00000001, 0x00333e23, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0x00203c05, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e007, 0x00204411, 0x000 },
-    { 0x0000000f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0cb },
-    { 0x00f8ff08, 0x00204811, 0x000 },
-    { 0x98000000, 0x00404811, 0x0dc },
-    { 0x000000f0, 0x00280e22, 0x000 },
-    { 0x000000a0, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0da },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d5 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d4 },
-    { 0x00003f00, 0x00400c11, 0x0d6 },
-    { 0x00001f00, 0x00400c11, 0x0d6 },
-    { 0x00000f00, 0x00200c11, 0x000 },
-    { 0x00380009, 0x00294a23, 0x000 },
-    { 0x3f000000, 0x00280e2b, 0x000 },
-    { 0x00000002, 0x00220e23, 0x000 },
-    { 0x00000007, 0x00494a23, 0x0dc },
-    { 0x00380f09, 0x00204811, 0x000 },
-    { 0x68000007, 0x00204811, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000a202, 0x00204411, 0x000 },
-    { 0x00ff0000, 0x00280e22, 0x000 },
-    { 0x00000080, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00200e2d, 0x000 },
-    { 0x00000026, 0x0020122d, 0x000 },
-    { 0x00000000, 0x002f0083, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0ea },
-    { 0x00000000, 0x00600000, 0x65f },
-    { 0x00000000, 0x00400000, 0x0eb },
-    { 0x00000000, 0x00600000, 0x662 },
-    { 0x00000007, 0x0020222d, 0x000 },
-    { 0x00000005, 0x00220e22, 0x000 },
-    { 0x00100000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x000000ef, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000003, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x0f8 },
-    { 0x0000000b, 0x00210228, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f8 },
-    { 0x00000400, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000001c, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0fd },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000001e, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x10b },
-    { 0x0000a30f, 0x00204411, 0x000 },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x104 },
-    { 0xffffffff, 0x00404811, 0x10b },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x107 },
-    { 0x0000ffff, 0x00404811, 0x10b },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x10a },
-    { 0x000000ff, 0x00404811, 0x10b },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0002c400, 0x00204411, 0x000 },
-    { 0x0000001f, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x112 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000018, 0x40224a20, 0x000 },
-    { 0x00000010, 0xc0424a20, 0x114 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000000a, 0x00201011, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x11b },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00531224, 0x117 },
-    { 0xffbfffff, 0x00283a2e, 0x000 },
-    { 0x0000001b, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x12e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x00000018, 0x00220e30, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e00e, 0x00204411, 0x000 },
-    { 0x07f8ff08, 0x00204811, 0x000 },
-    { 0x00000000, 0x00294a23, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00800000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204806, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x689 },
-    { 0x00000004, 0x00404c11, 0x135 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000001c, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x13c },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40280620, 0x000 },
-    { 0x00000010, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x00341461, 0x000 },
-    { 0x00000000, 0x00741882, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x147 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0681a20, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x158 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000001, 0x00300a2f, 0x000 },
-    { 0x00000001, 0x00210a22, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600000, 0x18f },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00202c08, 0x000 },
-    { 0x00000000, 0x00202411, 0x000 },
-    { 0x00000000, 0x00202811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00221e29, 0x000 },
-    { 0x00000000, 0x007048eb, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000001, 0x40330620, 0x000 },
-    { 0x00000000, 0xc0302409, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x181 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x186 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x186 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000001, 0x00530621, 0x182 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0604800, 0x197 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000011, 0x0020062d, 0x000 },
-    { 0x00000000, 0x0078042a, 0x2fb },
-    { 0x00000000, 0x00202809, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x174 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x194 },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x46000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x19b },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00804811, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40281620, 0x000 },
-    { 0x00000010, 0xc0811a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000008, 0x00221e30, 0x000 },
-    { 0x00000029, 0x00201a2d, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfffbff09, 0x00204811, 0x000 },
-    { 0x0000000f, 0x0020222d, 0x000 },
-    { 0x00001fff, 0x00294a28, 0x000 },
-    { 0x00000006, 0x0020222d, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000100, 0x00201811, 0x000 },
-    { 0x00000008, 0x00621e28, 0x12f },
-    { 0x00000008, 0x00822228, 0x000 },
-    { 0x0002c000, 0x00204411, 0x000 },
-    { 0x00000015, 0x00600e2d, 0x1bd },
-    { 0x00000016, 0x00600e2d, 0x1bd },
-    { 0x0000c008, 0x00204411, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x1b9 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x39000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00804802, 0x000 },
-    { 0x00000018, 0x00202e2d, 0x000 },
-    { 0x00000000, 0x003b0d63, 0x000 },
-    { 0x00000008, 0x00224a23, 0x000 },
-    { 0x00000010, 0x00224a23, 0x000 },
-    { 0x00000018, 0x00224a23, 0x000 },
-    { 0x00000000, 0x00804803, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000007, 0x0021062f, 0x000 },
-    { 0x00000013, 0x00200a2d, 0x000 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000ffff, 0x40282220, 0x000 },
-    { 0x0000000f, 0x00262228, 0x000 },
-    { 0x00000010, 0x40212620, 0x000 },
-    { 0x0000000f, 0x00262629, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1e0 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000081, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000080, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1dc },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1d8 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000001f, 0x00280a22, 0x000 },
-    { 0x0000001f, 0x00282a2a, 0x000 },
-    { 0x00000001, 0x00530621, 0x1d1 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000002, 0x00304a2f, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000001, 0x00301e2f, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1e5 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x0000000f, 0x00260e23, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000000f, 0x00261224, 0x000 },
-    { 0x00000000, 0x00201411, 0x000 },
-    { 0x00000000, 0x00601811, 0x2bb },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022b, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1f8 },
-    { 0x00000010, 0x00221628, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a29, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x0020480a, 0x000 },
-    { 0x00000000, 0x00202c11, 0x000 },
-    { 0x00000010, 0x00221623, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a24, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x00731503, 0x205 },
-    { 0x00000000, 0x00201805, 0x000 },
-    { 0x00000000, 0x00731524, 0x205 },
-    { 0x00000000, 0x002d14c5, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00000000, 0x00202003, 0x000 },
-    { 0x00000000, 0x00802404, 0x000 },
-    { 0x0000000f, 0x00210225, 0x000 },
-    { 0x00000000, 0x14c00000, 0x689 },
-    { 0x00000000, 0x002b1405, 0x000 },
-    { 0x00000001, 0x00901625, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00294a22, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a21, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000ffff, 0x40281220, 0x000 },
-    { 0x00000010, 0xc0211a20, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211620, 0x000 },
-    { 0x00000000, 0x00741465, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00000001, 0x00330621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x219 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x212 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000000, 0x0040040f, 0x213 },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00000000, 0x00600000, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x232 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x236 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x236 },
-    { 0x00000000, 0xc0404800, 0x233 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x00600411, 0x2fb },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000018, 0x40210a20, 0x000 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x24c },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x00080101, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x251 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000010, 0x00600411, 0x315 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00000000, 0x00600000, 0x27c },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000001, 0x00211e27, 0x000 },
-    { 0x00000000, 0x14e00000, 0x26a },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x0000ffff, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00341c27, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25f },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e5, 0x000 },
-    { 0x00000000, 0x08c00000, 0x262 },
-    { 0x00000000, 0x00201407, 0x000 },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00211e27, 0x000 },
-    { 0x00000000, 0x00341c47, 0x000 },
-    { 0x00000000, 0x12c00000, 0x267 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x08c00000, 0x26a },
-    { 0x00000000, 0x00201807, 0x000 },
-    { 0x00000000, 0x00600000, 0x2c1 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000000, 0x00342023, 0x000 },
-    { 0x00000000, 0x12c00000, 0x272 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x271 },
-    { 0x00000016, 0x00404811, 0x276 },
-    { 0x00000018, 0x00404811, 0x276 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x275 },
-    { 0x00000017, 0x00404811, 0x276 },
-    { 0x00000019, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00604411, 0x2e9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x256 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000010, 0x40210620, 0x000 },
-    { 0x0000ffff, 0xc0280a20, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0881a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x00000000, 0x00600000, 0x62e },
-    { 0x00000000, 0xc0600000, 0x2a3 },
-    { 0x00000005, 0x00200a2d, 0x000 },
-    { 0x00000008, 0x00220a22, 0x000 },
-    { 0x0000002b, 0x00201a2d, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00007000, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00311ce6, 0x000 },
-    { 0x0000002a, 0x00201a2d, 0x000 },
-    { 0x0000000c, 0x00221a26, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x06e00000, 0x292 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00691ce2, 0x12f },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x29d },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000001c, 0x00403627, 0x000 },
-    { 0x0000000c, 0xc0220a20, 0x000 },
-    { 0x00000029, 0x00203622, 0x000 },
-    { 0x00000028, 0xc0403620, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000009, 0x00204811, 0x000 },
-    { 0xa1000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce3, 0x000 },
-    { 0x00000021, 0x00203627, 0x000 },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce4, 0x000 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a3, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203624, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000000, 0x00311cc4, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14c00000, 0x2dc },
-    { 0x00000000, 0x00400000, 0x2d9 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2d9 },
-    { 0x00000003, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2dc },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e1, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a1, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e2, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000000, 0x00600000, 0x665 },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00600000, 0x65c },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2a7 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x0000001a, 0x00201e2d, 0x000 },
-    { 0x0000001b, 0x0080222d, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca1, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x003808c5, 0x000 },
-    { 0x00000000, 0x00300841, 0x000 },
-    { 0x00000001, 0x00220a22, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000017, 0x0020222d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x318 },
-    { 0xffffffef, 0x00280621, 0x000 },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x0000f8e0, 0x00204411, 0x000 },
-    { 0x00000000, 0x00294901, 0x000 },
-    { 0x00000000, 0x00894901, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00002257, 0x00204411, 0x000 },
-    { 0x00000003, 0xc0484a20, 0x000 },
-    { 0x0000225d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x642 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x00000001, 0x40304a20, 0x000 },
-    { 0x00000002, 0xc0304a20, 0x000 },
-    { 0x00000001, 0x00530a22, 0x34b },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x354 },
-    { 0x00000014, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x364 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00604802, 0x36e },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x36a },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x00000028, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5bd },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35f },
-    { 0x0000002c, 0x00203626, 0x000 },
-    { 0x00000049, 0x00201811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000000, 0x002f0226, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x370 },
-    { 0x0000002c, 0x00801a2d, 0x000 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x00000015, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x386 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b1 },
-    { 0x00000016, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b5 },
-    { 0x00000020, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x39c },
-    { 0x0000000f, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a8 },
-    { 0x0000001e, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x390 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x08000000, 0x00290a22, 0x000 },
-    { 0x00000003, 0x40210e20, 0x000 },
-    { 0x0000000c, 0xc0211220, 0x000 },
-    { 0x00080000, 0x00281224, 0x000 },
-    { 0x00000014, 0xc0221620, 0x000 },
-    { 0x00000000, 0x002914a4, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948a2, 0x000 },
-    { 0x0000a1fe, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000015, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x392 },
-    { 0x0000210e, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000003, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x39e },
-    { 0x00002108, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x80000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000010, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3ae },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000006, 0x00404811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x0000001d, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3ce },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3c0 },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0xbabecafe, 0x00204811, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000004, 0x00404811, 0x000 },
-    { 0x00002170, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000a, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3d3 },
-    { 0x8c000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00003fff, 0x40280a20, 0x000 },
-    { 0x80000000, 0x40280e20, 0x000 },
-    { 0x40000000, 0xc0281220, 0x000 },
-    { 0x00040000, 0x00694622, 0x68a },
-    { 0x00000000, 0x00201410, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e1 },
-    { 0x00000000, 0xc0401800, 0x3e4 },
-    { 0x00003fff, 0xc0281a20, 0x000 },
-    { 0x00040000, 0x00694626, 0x68a },
-    { 0x00000000, 0x00201810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e7 },
-    { 0x00000000, 0xc0401c00, 0x3ea },
-    { 0x00003fff, 0xc0281e20, 0x000 },
-    { 0x00040000, 0x00694627, 0x68a },
-    { 0x00000000, 0x00201c10, 0x000 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0x002820c5, 0x000 },
-    { 0x00000000, 0x004948e8, 0x000 },
-    { 0xa5800000, 0x00200811, 0x000 },
-    { 0x00002000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x0000001f, 0xc0210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3f7 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000ffff, 0xc0481220, 0x3ff },
-    { 0xa7800000, 0x00200811, 0x000 },
-    { 0x0000a000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00304883, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xa9800000, 0x00200811, 0x000 },
-    { 0x0000c000, 0x00400c11, 0x3fa },
-    { 0xab800000, 0x00200811, 0x000 },
-    { 0x0000f8e0, 0x00400c11, 0x3fa },
-    { 0xad800000, 0x00200811, 0x000 },
-    { 0x0000f880, 0x00400c11, 0x3fa },
-    { 0xb3800000, 0x00200811, 0x000 },
-    { 0x0000f3fc, 0x00400c11, 0x3fa },
-    { 0xaf800000, 0x00200811, 0x000 },
-    { 0x0000e000, 0x00400c11, 0x3fa },
-    { 0xb1800000, 0x00200811, 0x000 },
-    { 0x0000f000, 0x00400c11, 0x3fa },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00002148, 0x00204811, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x01182000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0218a000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0318c000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0418f8e0, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0518f880, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0618e000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0718f000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0818f3fc, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000030, 0x00200a2d, 0x000 },
-    { 0x00000000, 0xc0290c40, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x86000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x85000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00404c02, 0x448 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x00000000, 0xc0201400, 0x000 },
-    { 0x00000000, 0xc0201800, 0x000 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x456 },
-    { 0x00000000, 0xc0202000, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x00000010, 0x00280a23, 0x000 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x45e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0x00694624, 0x68a },
-    { 0x00000000, 0x00400000, 0x463 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00604805, 0x68f },
-    { 0x00000000, 0x002824f0, 0x000 },
-    { 0x00000007, 0x00280a23, 0x000 },
-    { 0x00000001, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46a },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x04e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000002, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46f },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x02e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x474 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x479 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000005, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x47e },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x06e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x483 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x08e00000, 0x483 },
-    { 0x00000000, 0x00400000, 0x490 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x000 },
-    { 0x00000008, 0x00210a23, 0x000 },
-    { 0x00000000, 0x14c00000, 0x48d },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x496 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x00404c08, 0x456 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000011, 0x40211220, 0x000 },
-    { 0x00000012, 0x40211620, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00210225, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4a0 },
-    { 0x00040000, 0xc0494a20, 0x4a1 },
-    { 0xfffbffff, 0xc0284a20, 0x000 },
-    { 0x00000000, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4ad },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000c, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4a9 },
-    { 0xa0000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x00204811, 0x000 },
-    { 0x0000216b, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000216c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4a7 },
-    { 0x00000000, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4c0 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x68f },
-    { 0x00000000, 0x00400000, 0x4c4 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xc0600000, 0x68a },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4cb },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0404810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x68a },
-    { 0x00000000, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4cd },
-    { 0x00002180, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000003, 0x00333e2f, 0x000 },
-    { 0x00000001, 0x00210221, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4fd },
-    { 0x0000002c, 0x00200a2d, 0x000 },
-    { 0x00040000, 0x18e00c11, 0x4ec },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xd8c04800, 0x4e0 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000002d, 0x0020122d, 0x000 },
-    { 0x00000000, 0x00290c83, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000011, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4a7 },
-    { 0x0000002c, 0xc0203620, 0x000 },
-    { 0x0000002d, 0xc0403620, 0x000 },
-    { 0x0000000f, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x502 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0xd9000000, 0x000 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xb5000000, 0x00204411, 0x000 },
-    { 0x00002000, 0x00204811, 0x000 },
-    { 0xb6000000, 0x00204411, 0x000 },
-    { 0x0000a000, 0x00204811, 0x000 },
-    { 0xb7000000, 0x00204411, 0x000 },
-    { 0x0000c000, 0x00204811, 0x000 },
-    { 0xb8000000, 0x00204411, 0x000 },
-    { 0x0000f8e0, 0x00204811, 0x000 },
-    { 0xb9000000, 0x00204411, 0x000 },
-    { 0x0000f880, 0x00204811, 0x000 },
-    { 0xba000000, 0x00204411, 0x000 },
-    { 0x0000e000, 0x00204811, 0x000 },
-    { 0xbb000000, 0x00204411, 0x000 },
-    { 0x0000f000, 0x00204811, 0x000 },
-    { 0xbc000000, 0x00204411, 0x000 },
-    { 0x0000f3fc, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00204811, 0x000 },
-    { 0x000000ff, 0x00280e30, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x516 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x14c00000, 0x52b },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000001c, 0x00203623, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x00000028, 0x00203623, 0x000 },
-    { 0x00000017, 0x00203623, 0x000 },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203623, 0x000 },
-    { 0x00000015, 0x00203623, 0x000 },
-    { 0x00000016, 0x00203623, 0x000 },
-    { 0xffffe000, 0x00200c11, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00200c11, 0x000 },
-    { 0x00000023, 0x00203623, 0x000 },
-    { 0x00000024, 0x00203623, 0x000 },
-    { 0xf1ffffff, 0x00283a2e, 0x000 },
-    { 0x0000001a, 0xc0220e20, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000002a, 0x40203620, 0x000 },
-    { 0x87000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x9d000000, 0x00204411, 0x000 },
-    { 0x0000001f, 0x40214a20, 0x000 },
-    { 0x96000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x0000001f, 0x00211624, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x0000001d, 0x00203623, 0x000 },
-    { 0x00000003, 0x00281e23, 0x000 },
-    { 0x00000008, 0x00222223, 0x000 },
-    { 0xfffff000, 0x00282228, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x0000001f, 0x00203628, 0x000 },
-    { 0x00000018, 0x00211e23, 0x000 },
-    { 0x00000020, 0x00203627, 0x000 },
-    { 0x00000002, 0x00221624, 0x000 },
-    { 0x00000000, 0x003014a8, 0x000 },
-    { 0x0000001e, 0x00203625, 0x000 },
-    { 0x00000003, 0x00211a24, 0x000 },
-    { 0x10000000, 0x00281a26, 0x000 },
-    { 0xefffffff, 0x00283a2e, 0x000 },
-    { 0x00000000, 0x004938ce, 0x678 },
-    { 0x00000001, 0x40280a20, 0x000 },
-    { 0x00000006, 0x40280e20, 0x000 },
-    { 0x00000300, 0xc0281220, 0x000 },
-    { 0x00000008, 0x00211224, 0x000 },
-    { 0x00000000, 0xc0201620, 0x000 },
-    { 0x00000000, 0xc0201a20, 0x000 },
-    { 0x00000000, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x563 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68a },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00020000, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56b },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x579 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56b },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x68a },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x579 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56f },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00000000, 0xc0400000, 0x579 },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x577 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x68f },
-    { 0x00000000, 0x00401c10, 0x579 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x57b },
-    { 0x00000000, 0x00600000, 0x5c6 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x58c },
-    { 0x0000a2b7, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c4, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x58a },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000001, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x59d },
-    { 0x0000a2bb, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c5, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x59b },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000002, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5ae },
-    { 0x0000a2bf, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c6, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5ac },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x0000a2c3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68a },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000a2c7, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5bb },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0x01000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00400000, 0x5c1 },
-    { 0xa4000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5c6 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000002c, 0x00203621, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5cd },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000030, 0x00403621, 0x5e0 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x5e0 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a092, 0x00604411, 0x68a },
-    { 0x00000031, 0x00203630, 0x000 },
-    { 0x0004a093, 0x00604411, 0x68a },
-    { 0x00000032, 0x00203630, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x68a },
-    { 0x00000033, 0x00203630, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x68a },
-    { 0x00000034, 0x00203630, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x68a },
-    { 0x00000035, 0x00203630, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x68a },
-    { 0x00000036, 0x00203630, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x88000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000001, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x629 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x629 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x602 },
-    { 0x0000a092, 0x00204411, 0x000 },
-    { 0x00000031, 0x00204a2d, 0x000 },
-    { 0x0000a093, 0x00204411, 0x000 },
-    { 0x00000032, 0x00204a2d, 0x000 },
-    { 0x0000a2b6, 0x00204411, 0x000 },
-    { 0x00000033, 0x00204a2d, 0x000 },
-    { 0x0000a2ba, 0x00204411, 0x000 },
-    { 0x00000034, 0x00204a2d, 0x000 },
-    { 0x0000a2be, 0x00204411, 0x000 },
-    { 0x00000035, 0x00204a2d, 0x000 },
-    { 0x0000a2c2, 0x00204411, 0x000 },
-    { 0x00000036, 0x00204a2d, 0x000 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x000001ff, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x628 },
-    { 0x00000000, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x60b },
-    { 0x0004a003, 0x00604411, 0x68a },
-    { 0x0000a003, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x14c00000, 0x610 },
-    { 0x0004a010, 0x00604411, 0x68a },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x628 },
-    { 0x0004a011, 0x00604411, 0x68a },
-    { 0x0000a011, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a012, 0x00604411, 0x68a },
-    { 0x0000a012, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a013, 0x00604411, 0x68a },
-    { 0x0000a013, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a014, 0x00604411, 0x68a },
-    { 0x0000a014, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a015, 0x00604411, 0x68a },
-    { 0x0000a015, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a016, 0x00604411, 0x68a },
-    { 0x0000a016, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a017, 0x00604411, 0x68a },
-    { 0x0000a017, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x0000002c, 0x0080062d, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x63a },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000002, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x638 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x68a },
-    { 0x00001000, 0x00200811, 0x000 },
-    { 0x0000002b, 0x00203622, 0x000 },
-    { 0x00000000, 0x00600000, 0x63e },
-    { 0x00000000, 0x00600000, 0x5c6 },
-    { 0x98000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0600000, 0x63e },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000022, 0x00204811, 0x000 },
-    { 0x89000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00404811, 0x62a },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404811, 0x62a },
-    { 0x00000000, 0x00600000, 0x659 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0xc0204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x09800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000004, 0x00404c11, 0x653 },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000004, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffffb, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffff7, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36e },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x01800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004217f, 0x00604411, 0x68a },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x689 },
-    { 0x00000010, 0x00404c11, 0x66f },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x38c00000, 0x000 },
-    { 0x0000001d, 0x00200a2d, 0x000 },
-    { 0x0000001e, 0x00200e2d, 0x000 },
-    { 0x0000001f, 0x0020122d, 0x000 },
-    { 0x00000020, 0x0020162d, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000004, 0x00301224, 0x000 },
-    { 0x00000000, 0x002f0064, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x688 },
-    { 0x00000003, 0x00281a22, 0x000 },
-    { 0x00000008, 0x00221222, 0x000 },
-    { 0xfffff000, 0x00281224, 0x000 },
-    { 0x00000000, 0x002910c4, 0x000 },
-    { 0x0000001f, 0x00403624, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x68a },
-    { 0x9f000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x68d },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x68f },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x692 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0xc0204411, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000024, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000022, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x014204ff, 0x05bd0250, 0x000 },
-    { 0x01c30168, 0x043f05bd, 0x000 },
-    { 0x02250209, 0x02500151, 0x000 },
-    { 0x02230245, 0x02a00241, 0x000 },
-    { 0x03d705bd, 0x05bd05bd, 0x000 },
-    { 0x06460647, 0x031f05bd, 0x000 },
-    { 0x05bd05c2, 0x03200340, 0x000 },
-    { 0x032a0282, 0x03420334, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd054e, 0x05bd05bd, 0x000 },
-    { 0x03ba05bd, 0x04b80344, 0x000 },
-    { 0x0497044d, 0x043d05bd, 0x000 },
-    { 0x04cd05bd, 0x044104da, 0x000 },
-    { 0x044d0504, 0x03510375, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x063c05c4, 0x000 },
-    { 0x05bd05bd, 0x000705bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x03f803ed, 0x04080406, 0x000 },
-    { 0x040e040a, 0x040c0410, 0x000 },
-    { 0x041c0418, 0x04240420, 0x000 },
-    { 0x042c0428, 0x04340430, 0x000 },
-    { 0x05bd05bd, 0x043805bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x05bd05bd, 0x05bd05bd, 0x000 },
-    { 0x00020676, 0x06940006, 0x000 },
-};
-
-static const u32 RV635_pfp_microcode[] = {
-0xca0400,
-0xa00000,
-0x7e828b,
-0x7c038b,
-0x8001b8,
-0x7c038b,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xc41838,
-0xca2400,
-0xca2800,
-0x9581a8,
-0xc41c3a,
-0xc3c000,
-0xca0800,
-0xca0c00,
-0x7c744b,
-0xc20005,
-0x99c000,
-0xc41c3a,
-0x7c744c,
-0xc0fff0,
-0x042c04,
-0x309002,
-0x7d2500,
-0x351402,
-0x7d350b,
-0x255403,
-0x7cd580,
-0x259c03,
-0x95c004,
-0xd5001b,
-0x7eddc1,
-0x7d9d80,
-0xd6801b,
-0xd5801b,
-0xd4401e,
-0xd5401e,
-0xd6401e,
-0xd6801e,
-0xd4801e,
-0xd4c01e,
-0x9783d3,
-0xd5c01e,
-0xca0800,
-0x80001a,
-0xca0c00,
-0xe4011e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xe4013e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca1800,
-0xd4401e,
-0xd5801e,
-0x800053,
-0xd40075,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xe2001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0xd48060,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xd48061,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xca0c00,
-0xd4401e,
-0xd48016,
-0xd4c016,
-0xd4801e,
-0x8001b8,
-0xd4c01e,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x948004,
-0xca1400,
-0xe420f3,
-0xd42013,
-0xd56065,
-0xd4e01c,
-0xd5201c,
-0xd5601c,
-0x800000,
-0x062001,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9483f7,
-0xca1400,
-0xe420f3,
-0x800079,
-0xd42013,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9883ef,
-0xca1400,
-0xd40064,
-0x80008d,
-0x000000,
-0xc41432,
-0xc61843,
-0xc4082f,
-0x954005,
-0xc40c30,
-0xd4401e,
-0x800000,
-0xee001e,
-0x9583f5,
-0xc41031,
-0xd44033,
-0xd52065,
-0xd4a01c,
-0xd4e01c,
-0xd5201c,
-0xe4015e,
-0xd4001e,
-0x800000,
-0x062001,
-0xca1800,
-0x0a2001,
-0xd60076,
-0xc40836,
-0x988007,
-0xc61045,
-0x950110,
-0xd4001f,
-0xd46062,
-0x800000,
-0xd42062,
-0xcc3835,
-0xcc1433,
-0x8401bb,
-0xd40072,
-0xd5401e,
-0x800000,
-0xee001e,
-0xe2001a,
-0x8401bb,
-0xe2001a,
-0xcc104b,
-0xcc0447,
-0x2c9401,
-0x7d098b,
-0x984005,
-0x7d15cb,
-0xd4001a,
-0x8001b8,
-0xd4006d,
-0x344401,
-0xcc0c48,
-0x98403a,
-0xcc2c4a,
-0x958004,
-0xcc0449,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0x282801,
-0x8400f0,
-0xcc1003,
-0x98801b,
-0x04380c,
-0x8400f0,
-0xcc1003,
-0x988017,
-0x043808,
-0x8400f0,
-0xcc1003,
-0x988013,
-0x043804,
-0x8400f0,
-0xcc1003,
-0x988014,
-0xcc104c,
-0x9a8009,
-0xcc144d,
-0x9840dc,
-0xd4006d,
-0xcc1848,
-0xd5001a,
-0xd5401a,
-0x8000c9,
-0xd5801a,
-0x96c0d5,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0x9ac003,
-0xd4006d,
-0xd4006e,
-0x800000,
-0xec007f,
-0x9ac0cc,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0x7d9103,
-0x7dd583,
-0x7d190c,
-0x35cc1f,
-0x35701f,
-0x7cf0cb,
-0x7cd08b,
-0x880000,
-0x7e8e8b,
-0x95c004,
-0xd4006e,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0xcc0803,
-0xcc0c03,
-0xcc1003,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0xcc2403,
-0xcc2803,
-0x35c41f,
-0x36b01f,
-0x7c704b,
-0x34f01f,
-0x7c704b,
-0x35701f,
-0x7c704b,
-0x7d8881,
-0x7dccc1,
-0x7e5101,
-0x7e9541,
-0x7c9082,
-0x7cd4c2,
-0x7c848b,
-0x9ac003,
-0x7c8c8b,
-0x2c8801,
-0x98809e,
-0xd4006d,
-0x98409c,
-0xd4006e,
-0xcc084c,
-0xcc0c4d,
-0xcc1048,
-0xd4801a,
-0xd4c01a,
-0x800101,
-0xd5001a,
-0xcc0832,
-0xd40032,
-0x9482d9,
-0xca0c00,
-0xd4401e,
-0x800000,
-0xd4001e,
-0xe4011e,
-0xd4001e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd4401e,
-0xca1400,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xd5401e,
-0xd54034,
-0x800000,
-0xee001e,
-0x280404,
-0xe2001a,
-0xe2001a,
-0xd4401a,
-0xca3800,
-0xcc0803,
-0xcc0c03,
-0xcc0c03,
-0xcc0c03,
-0x9882bd,
-0x000000,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0400,
-0xc2ff00,
-0xcc0834,
-0xc13fff,
-0x7c74cb,
-0x7cc90b,
-0x7d010f,
-0x9902b0,
-0x7c738b,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0800,
-0x281900,
-0x7d898b,
-0x958014,
-0x281404,
-0xca0c00,
-0xca1000,
-0xca1c00,
-0xca2400,
-0xe2001f,
-0xd4c01a,
-0xd5001a,
-0xd5401a,
-0xcc1803,
-0xcc2c03,
-0xcc2c03,
-0xcc2c03,
-0x7da58b,
-0x7d9c47,
-0x984297,
-0x000000,
-0x800161,
-0xd4c01a,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c06,
-0x0ccc06,
-0x98c006,
-0xcc104e,
-0x990004,
-0xd40073,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xca0800,
-0xca0c00,
-0x34d018,
-0x251001,
-0x950021,
-0xc17fff,
-0xca1000,
-0xca1400,
-0xca1800,
-0xd4801d,
-0xd4c01d,
-0x7db18b,
-0xc14202,
-0xc2c001,
-0xd5801d,
-0x34dc0e,
-0x7d5d4c,
-0x7f734c,
-0xd7401e,
-0xd5001e,
-0xd5401e,
-0xc14200,
-0xc2c000,
-0x099c01,
-0x31dc10,
-0x7f5f4c,
-0x7f734c,
-0x042802,
-0x7d8380,
-0xd5a86f,
-0xd58066,
-0xd7401e,
-0xec005e,
-0xc82402,
-0xc82402,
-0x8001b8,
-0xd60076,
-0xd4401e,
-0xd4801e,
-0xd4c01e,
-0x800000,
-0xee001e,
-0x800000,
-0xee001f,
-0xd4001f,
-0x800000,
-0xd4001f,
-0xd4001f,
-0x880000,
-0xd4001f,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x010171,
-0x020178,
-0x03008f,
-0x04007f,
-0x050003,
-0x06003f,
-0x070032,
-0x08012c,
-0x090046,
-0x0a0036,
-0x1001b6,
-0x1700a2,
-0x22013a,
-0x230149,
-0x2000b4,
-0x240125,
-0x27004d,
-0x28006a,
-0x2a0060,
-0x2b0052,
-0x2f0065,
-0x320087,
-0x34017f,
-0x3c0156,
-0x3f0072,
-0x41018c,
-0x44012e,
-0x550173,
-0x56017a,
-0x60000b,
-0x610034,
-0x620038,
-0x630038,
-0x640038,
-0x650038,
-0x660038,
-0x670038,
-0x68003a,
-0x690041,
-0x6a0048,
-0x6b0048,
-0x6c0048,
-0x6d0048,
-0x6e0048,
-0x6f0048,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-};
-
-static const u32 RV670_cp_microcode[][3] = {
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0000ffff, 0x00284621, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000000, 0x00e00000, 0x000 },
-    { 0x00010000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x00000000, 0x00600000, 0x624 },
-    { 0x00000000, 0x00600000, 0x638 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000f00, 0x00281622, 0x000 },
-    { 0x00000008, 0x00211625, 0x000 },
-    { 0x00000018, 0x00203625, 0x000 },
-    { 0x8d000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x002f0225, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x018 },
-    { 0x00412000, 0x00404811, 0x019 },
-    { 0x00422000, 0x00204811, 0x000 },
-    { 0x8e000000, 0x00204411, 0x000 },
-    { 0x00000028, 0x00204a2d, 0x000 },
-    { 0x90000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x0000000c, 0x00211622, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000019, 0x00211a22, 0x000 },
-    { 0x00000004, 0x00281a26, 0x000 },
-    { 0x00000000, 0x002914c5, 0x000 },
-    { 0x00000019, 0x00203625, 0x000 },
-    { 0x00000000, 0x003a1402, 0x000 },
-    { 0x00000016, 0x00211625, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0xfffffffc, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002914a3, 0x000 },
-    { 0x00000017, 0x00203625, 0x000 },
-    { 0x00008000, 0x00280e22, 0x000 },
-    { 0x00000007, 0x00220e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x20000000, 0x00280e22, 0x000 },
-    { 0x00000006, 0x00210e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x00000000, 0x00220222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x038 },
-    { 0x00000000, 0x2ee00000, 0x035 },
-    { 0x00000000, 0x2ce00000, 0x037 },
-    { 0x00000000, 0x00400e2d, 0x039 },
-    { 0x00000008, 0x00200e2d, 0x000 },
-    { 0x00000009, 0x0040122d, 0x046 },
-    { 0x00000001, 0x00400e2d, 0x039 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x03e },
-    { 0x00000008, 0x00401c11, 0x041 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x0000000f, 0x00281e27, 0x000 },
-    { 0x00000003, 0x00221e27, 0x000 },
-    { 0x7fc00000, 0x00281a23, 0x000 },
-    { 0x00000014, 0x00211a26, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000008, 0x00221a26, 0x000 },
-    { 0x00000000, 0x00290cc7, 0x000 },
-    { 0x00000027, 0x00203624, 0x000 },
-    { 0x00007f00, 0x00281221, 0x000 },
-    { 0x00001400, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x04b },
-    { 0x00000001, 0x00290e23, 0x000 },
-    { 0x0000000e, 0x00203623, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfff80000, 0x00294a23, 0x000 },
-    { 0x00000000, 0x003a2c02, 0x000 },
-    { 0x00000002, 0x00220e2b, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x0000000f, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00204a2d, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000029, 0x00200e2d, 0x000 },
-    { 0x060a0200, 0x00294a23, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x061 },
-    { 0x00000000, 0x2ee00000, 0x05f },
-    { 0x00000000, 0x2ce00000, 0x05e },
-    { 0x00000000, 0x00400e2d, 0x062 },
-    { 0x00000001, 0x00400e2d, 0x062 },
-    { 0x0000000a, 0x00200e2d, 0x000 },
-    { 0x0000000b, 0x0040122d, 0x06a },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x7fc00000, 0x00281623, 0x000 },
-    { 0x00000014, 0x00211625, 0x000 },
-    { 0x00000001, 0x00331625, 0x000 },
-    { 0x80000000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00290ca3, 0x000 },
-    { 0x3ffffc00, 0x00290e23, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x06d },
-    { 0x00000100, 0x00401c11, 0x070 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x000000f0, 0x00281e27, 0x000 },
-    { 0x00000004, 0x00221e27, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0xfffff0ff, 0x00281a30, 0x000 },
-    { 0x0000a028, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948e6, 0x000 },
-    { 0x0000a018, 0x00204411, 0x000 },
-    { 0x3fffffff, 0x00284a23, 0x000 },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000030, 0x0020162d, 0x000 },
-    { 0x00000002, 0x00291625, 0x000 },
-    { 0x00000030, 0x00203625, 0x000 },
-    { 0x00000025, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a3, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x083 },
-    { 0x00000026, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a4, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x084 },
-    { 0x00000000, 0x00400000, 0x08a },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203624, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x08a },
-    { 0x00000000, 0x00600000, 0x659 },
-    { 0x00000000, 0x00600000, 0x64d },
-    { 0x00000002, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x08d },
-    { 0x00000012, 0xc0403620, 0x093 },
-    { 0x00000000, 0x2ee00000, 0x091 },
-    { 0x00000000, 0x2ce00000, 0x090 },
-    { 0x00000002, 0x00400e2d, 0x092 },
-    { 0x00000003, 0x00400e2d, 0x092 },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000012, 0x00203623, 0x000 },
-    { 0x00000003, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x098 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x0a0 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x2ee00000, 0x09e },
-    { 0x00000000, 0x2ce00000, 0x09d },
-    { 0x00000002, 0x00400e2d, 0x09f },
-    { 0x00000003, 0x00400e2d, 0x09f },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x003f0000, 0x00280e23, 0x000 },
-    { 0x00000010, 0x00210e23, 0x000 },
-    { 0x00000011, 0x00203623, 0x000 },
-    { 0x0000001e, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a7 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x0000001f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0aa },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000008, 0x00210e2b, 0x000 },
-    { 0x0000007f, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0e1 },
-    { 0x00000000, 0x27000000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x0b3 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000000c, 0x00221e30, 0x000 },
-    { 0x99800000, 0x00204411, 0x000 },
-    { 0x00000004, 0x0020122d, 0x000 },
-    { 0x00000008, 0x00221224, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00291ce4, 0x000 },
-    { 0x00000000, 0x00604807, 0x12f },
-    { 0x9b000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x9c000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x0033146f, 0x000 },
-    { 0x00000001, 0x00333e23, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0x00203c05, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e007, 0x00204411, 0x000 },
-    { 0x0000000f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0cb },
-    { 0x00f8ff08, 0x00204811, 0x000 },
-    { 0x98000000, 0x00404811, 0x0dc },
-    { 0x000000f0, 0x00280e22, 0x000 },
-    { 0x000000a0, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0da },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d5 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d4 },
-    { 0x00003f00, 0x00400c11, 0x0d6 },
-    { 0x00001f00, 0x00400c11, 0x0d6 },
-    { 0x00000f00, 0x00200c11, 0x000 },
-    { 0x00380009, 0x00294a23, 0x000 },
-    { 0x3f000000, 0x00280e2b, 0x000 },
-    { 0x00000002, 0x00220e23, 0x000 },
-    { 0x00000007, 0x00494a23, 0x0dc },
-    { 0x00380f09, 0x00204811, 0x000 },
-    { 0x68000007, 0x00204811, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000a202, 0x00204411, 0x000 },
-    { 0x00ff0000, 0x00280e22, 0x000 },
-    { 0x00000080, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00200e2d, 0x000 },
-    { 0x00000026, 0x0020122d, 0x000 },
-    { 0x00000000, 0x002f0083, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0ea },
-    { 0x00000000, 0x00600000, 0x653 },
-    { 0x00000000, 0x00400000, 0x0eb },
-    { 0x00000000, 0x00600000, 0x656 },
-    { 0x00000007, 0x0020222d, 0x000 },
-    { 0x00000005, 0x00220e22, 0x000 },
-    { 0x00100000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x000000ef, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000003, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x0f8 },
-    { 0x0000000b, 0x00210228, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f8 },
-    { 0x00000400, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000001c, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0fd },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000001e, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x10b },
-    { 0x0000a30f, 0x00204411, 0x000 },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x104 },
-    { 0xffffffff, 0x00404811, 0x10b },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x107 },
-    { 0x0000ffff, 0x00404811, 0x10b },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x10a },
-    { 0x000000ff, 0x00404811, 0x10b },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0002c400, 0x00204411, 0x000 },
-    { 0x0000001f, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x112 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000018, 0x40224a20, 0x000 },
-    { 0x00000010, 0xc0424a20, 0x114 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000000a, 0x00201011, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x11b },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00531224, 0x117 },
-    { 0xffbfffff, 0x00283a2e, 0x000 },
-    { 0x0000001b, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x12e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x00000018, 0x00220e30, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e00e, 0x00204411, 0x000 },
-    { 0x07f8ff08, 0x00204811, 0x000 },
-    { 0x00000000, 0x00294a23, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00800000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204806, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x67c },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x67b },
-    { 0x00000004, 0x00404c11, 0x135 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000001c, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x67c },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x13c },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40280620, 0x000 },
-    { 0x00000010, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x00341461, 0x000 },
-    { 0x00000000, 0x00741882, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x147 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0681a20, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x158 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000001, 0x00300a2f, 0x000 },
-    { 0x00000001, 0x00210a22, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600000, 0x18f },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00202c08, 0x000 },
-    { 0x00000000, 0x00202411, 0x000 },
-    { 0x00000000, 0x00202811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00221e29, 0x000 },
-    { 0x00000000, 0x007048eb, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000001, 0x40330620, 0x000 },
-    { 0x00000000, 0xc0302409, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x181 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x186 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x186 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000001, 0x00530621, 0x182 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0604800, 0x197 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000011, 0x0020062d, 0x000 },
-    { 0x00000000, 0x0078042a, 0x2fb },
-    { 0x00000000, 0x00202809, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x174 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x194 },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x46000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x19b },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00804811, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40281620, 0x000 },
-    { 0x00000010, 0xc0811a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000008, 0x00221e30, 0x000 },
-    { 0x00000029, 0x00201a2d, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfffbff09, 0x00204811, 0x000 },
-    { 0x0000000f, 0x0020222d, 0x000 },
-    { 0x00001fff, 0x00294a28, 0x000 },
-    { 0x00000006, 0x0020222d, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000100, 0x00201811, 0x000 },
-    { 0x00000008, 0x00621e28, 0x12f },
-    { 0x00000008, 0x00822228, 0x000 },
-    { 0x0002c000, 0x00204411, 0x000 },
-    { 0x00000015, 0x00600e2d, 0x1bd },
-    { 0x00000016, 0x00600e2d, 0x1bd },
-    { 0x0000c008, 0x00204411, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x1b9 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x39000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00804802, 0x000 },
-    { 0x00000018, 0x00202e2d, 0x000 },
-    { 0x00000000, 0x003b0d63, 0x000 },
-    { 0x00000008, 0x00224a23, 0x000 },
-    { 0x00000010, 0x00224a23, 0x000 },
-    { 0x00000018, 0x00224a23, 0x000 },
-    { 0x00000000, 0x00804803, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000007, 0x0021062f, 0x000 },
-    { 0x00000013, 0x00200a2d, 0x000 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000ffff, 0x40282220, 0x000 },
-    { 0x0000000f, 0x00262228, 0x000 },
-    { 0x00000010, 0x40212620, 0x000 },
-    { 0x0000000f, 0x00262629, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1e0 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000081, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000080, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1dc },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1d8 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000001f, 0x00280a22, 0x000 },
-    { 0x0000001f, 0x00282a2a, 0x000 },
-    { 0x00000001, 0x00530621, 0x1d1 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000002, 0x00304a2f, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000001, 0x00301e2f, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1e5 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x0000000f, 0x00260e23, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000000f, 0x00261224, 0x000 },
-    { 0x00000000, 0x00201411, 0x000 },
-    { 0x00000000, 0x00601811, 0x2bb },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022b, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1f8 },
-    { 0x00000010, 0x00221628, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a29, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x0020480a, 0x000 },
-    { 0x00000000, 0x00202c11, 0x000 },
-    { 0x00000010, 0x00221623, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a24, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x00731503, 0x205 },
-    { 0x00000000, 0x00201805, 0x000 },
-    { 0x00000000, 0x00731524, 0x205 },
-    { 0x00000000, 0x002d14c5, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00000000, 0x00202003, 0x000 },
-    { 0x00000000, 0x00802404, 0x000 },
-    { 0x0000000f, 0x00210225, 0x000 },
-    { 0x00000000, 0x14c00000, 0x67b },
-    { 0x00000000, 0x002b1405, 0x000 },
-    { 0x00000001, 0x00901625, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00294a22, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a21, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000ffff, 0x40281220, 0x000 },
-    { 0x00000010, 0xc0211a20, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211620, 0x000 },
-    { 0x00000000, 0x00741465, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00000001, 0x00330621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x219 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x212 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x638 },
-    { 0x00000000, 0x0040040f, 0x213 },
-    { 0x00000000, 0x00600000, 0x624 },
-    { 0x00000000, 0x00600000, 0x638 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00000000, 0x00600000, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x232 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x236 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x236 },
-    { 0x00000000, 0xc0404800, 0x233 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x00600411, 0x2fb },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x624 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000018, 0x40210a20, 0x000 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x24c },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x00080101, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x251 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000010, 0x00600411, 0x315 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00000000, 0x00600000, 0x27c },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000001, 0x00211e27, 0x000 },
-    { 0x00000000, 0x14e00000, 0x26a },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x0000ffff, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00341c27, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25f },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e5, 0x000 },
-    { 0x00000000, 0x08c00000, 0x262 },
-    { 0x00000000, 0x00201407, 0x000 },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00211e27, 0x000 },
-    { 0x00000000, 0x00341c47, 0x000 },
-    { 0x00000000, 0x12c00000, 0x267 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x08c00000, 0x26a },
-    { 0x00000000, 0x00201807, 0x000 },
-    { 0x00000000, 0x00600000, 0x2c1 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000000, 0x00342023, 0x000 },
-    { 0x00000000, 0x12c00000, 0x272 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x271 },
-    { 0x00000016, 0x00404811, 0x276 },
-    { 0x00000018, 0x00404811, 0x276 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x275 },
-    { 0x00000017, 0x00404811, 0x276 },
-    { 0x00000019, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00604411, 0x2e9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x256 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000010, 0x40210620, 0x000 },
-    { 0x0000ffff, 0xc0280a20, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0881a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x00000000, 0x00600000, 0x624 },
-    { 0x00000000, 0xc0600000, 0x2a3 },
-    { 0x00000005, 0x00200a2d, 0x000 },
-    { 0x00000008, 0x00220a22, 0x000 },
-    { 0x0000002b, 0x00201a2d, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00007000, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00311ce6, 0x000 },
-    { 0x0000002a, 0x00201a2d, 0x000 },
-    { 0x0000000c, 0x00221a26, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x06e00000, 0x292 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00691ce2, 0x12f },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x29d },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000001c, 0x00403627, 0x000 },
-    { 0x0000000c, 0xc0220a20, 0x000 },
-    { 0x00000029, 0x00203622, 0x000 },
-    { 0x00000028, 0xc0403620, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000009, 0x00204811, 0x000 },
-    { 0xa1000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce3, 0x000 },
-    { 0x00000021, 0x00203627, 0x000 },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce4, 0x000 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a3, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203624, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000000, 0x00311cc4, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14c00000, 0x2dc },
-    { 0x00000000, 0x00400000, 0x2d9 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2d9 },
-    { 0x00000003, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2dc },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e1, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a1, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e2, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000000, 0x00600000, 0x659 },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00600000, 0x650 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2a7 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x0000001a, 0x00201e2d, 0x000 },
-    { 0x0000001b, 0x0080222d, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca1, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x003808c5, 0x000 },
-    { 0x00000000, 0x00300841, 0x000 },
-    { 0x00000001, 0x00220a22, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000017, 0x0020222d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x318 },
-    { 0xffffffef, 0x00280621, 0x000 },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x0000f8e0, 0x00204411, 0x000 },
-    { 0x00000000, 0x00294901, 0x000 },
-    { 0x00000000, 0x00894901, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00002257, 0x00204411, 0x000 },
-    { 0x00000003, 0xc0484a20, 0x000 },
-    { 0x0000225d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x638 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x00000001, 0x40304a20, 0x000 },
-    { 0x00000002, 0xc0304a20, 0x000 },
-    { 0x00000001, 0x00530a22, 0x34b },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x67c },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x354 },
-    { 0x00000014, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x362 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00604802, 0x36a },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x366 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35d },
-    { 0x00000028, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5b3 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x35d },
-    { 0x0000002c, 0x00203626, 0x000 },
-    { 0x00000049, 0x00201811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000000, 0x002f0226, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x36c },
-    { 0x0000002c, 0x00801a2d, 0x000 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x00000015, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x382 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3ad },
-    { 0x00000016, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3af },
-    { 0x00000020, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x398 },
-    { 0x0000000f, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a4 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a4 },
-    { 0x0000001e, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x38c },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x08000000, 0x00290a22, 0x000 },
-    { 0x00000003, 0x40210e20, 0x000 },
-    { 0x0000000c, 0xc0211220, 0x000 },
-    { 0x00080000, 0x00281224, 0x000 },
-    { 0x00000014, 0xc0221620, 0x000 },
-    { 0x00000000, 0x002914a4, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948a2, 0x000 },
-    { 0x0000a1fe, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x67c },
-    { 0x00000015, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x38e },
-    { 0x0000210e, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x67c },
-    { 0x00000003, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x39a },
-    { 0x00002108, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x80000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000010, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3aa },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000006, 0x00404811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36a },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x0000001d, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3c4 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x67c },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3b8 },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0xbabecafe, 0x00204811, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000004, 0x00404811, 0x000 },
-    { 0x00002170, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000a, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3c9 },
-    { 0x8c000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00003fff, 0x40280a20, 0x000 },
-    { 0x80000000, 0x40280e20, 0x000 },
-    { 0x40000000, 0xc0281220, 0x000 },
-    { 0x00040000, 0x00694622, 0x67c },
-    { 0x00000000, 0x00201410, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3d7 },
-    { 0x00000000, 0xc0401800, 0x3da },
-    { 0x00003fff, 0xc0281a20, 0x000 },
-    { 0x00040000, 0x00694626, 0x67c },
-    { 0x00000000, 0x00201810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3dd },
-    { 0x00000000, 0xc0401c00, 0x3e0 },
-    { 0x00003fff, 0xc0281e20, 0x000 },
-    { 0x00040000, 0x00694627, 0x67c },
-    { 0x00000000, 0x00201c10, 0x000 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0x002820c5, 0x000 },
-    { 0x00000000, 0x004948e8, 0x000 },
-    { 0xa5800000, 0x00200811, 0x000 },
-    { 0x00002000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x408 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x0000001f, 0xc0210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3ed },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000ffff, 0xc0481220, 0x3f5 },
-    { 0xa7800000, 0x00200811, 0x000 },
-    { 0x0000a000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x408 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00304883, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x83000000, 0x00604411, 0x408 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xa9800000, 0x00200811, 0x000 },
-    { 0x0000c000, 0x00400c11, 0x3f0 },
-    { 0xab800000, 0x00200811, 0x000 },
-    { 0x0000f8e0, 0x00400c11, 0x3f0 },
-    { 0xad800000, 0x00200811, 0x000 },
-    { 0x0000f880, 0x00400c11, 0x3f0 },
-    { 0xb3800000, 0x00200811, 0x000 },
-    { 0x0000f3fc, 0x00400c11, 0x3f0 },
-    { 0xaf800000, 0x00200811, 0x000 },
-    { 0x0000e000, 0x00400c11, 0x3f0 },
-    { 0xb1800000, 0x00200811, 0x000 },
-    { 0x0000f000, 0x00400c11, 0x3f0 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00002148, 0x00204811, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x01182000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0218a000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0318c000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0418f8e0, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0518f880, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0618e000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0718f000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0818f3fc, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000030, 0x00200a2d, 0x000 },
-    { 0x00000000, 0xc0290c40, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x86000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x85000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x67c },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00404c02, 0x43e },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x00000000, 0xc0201400, 0x000 },
-    { 0x00000000, 0xc0201800, 0x000 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x44c },
-    { 0x00000000, 0xc0202000, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x00000010, 0x00280a23, 0x000 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x454 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0x00694624, 0x67c },
-    { 0x00000000, 0x00400000, 0x459 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00604805, 0x681 },
-    { 0x00000000, 0x002824f0, 0x000 },
-    { 0x00000007, 0x00280a23, 0x000 },
-    { 0x00000001, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x460 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x04e00000, 0x479 },
-    { 0x00000000, 0x00400000, 0x486 },
-    { 0x00000002, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x465 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x02e00000, 0x479 },
-    { 0x00000000, 0x00400000, 0x486 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46a },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x479 },
-    { 0x00000000, 0x00400000, 0x486 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x46f },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x479 },
-    { 0x00000000, 0x00400000, 0x486 },
-    { 0x00000005, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x474 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x06e00000, 0x479 },
-    { 0x00000000, 0x00400000, 0x486 },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x479 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x08e00000, 0x479 },
-    { 0x00000000, 0x00400000, 0x486 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x000 },
-    { 0x00000008, 0x00210a23, 0x000 },
-    { 0x00000000, 0x14c00000, 0x483 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x48c },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x00404c08, 0x44c },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000011, 0x40211220, 0x000 },
-    { 0x00000012, 0x40211620, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00210225, 0x000 },
-    { 0x00000000, 0x14e00000, 0x496 },
-    { 0x00040000, 0xc0494a20, 0x497 },
-    { 0xfffbffff, 0xc0284a20, 0x000 },
-    { 0x00000000, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4a3 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000c, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x49f },
-    { 0xa0000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x00204811, 0x000 },
-    { 0x0000216b, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000216c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x49d },
-    { 0x00000000, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4b6 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x681 },
-    { 0x00000000, 0x00400000, 0x4ba },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xc0600000, 0x67c },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4c1 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0404810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x67c },
-    { 0x00000000, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4c3 },
-    { 0x00002180, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000003, 0x00333e2f, 0x000 },
-    { 0x00000001, 0x00210221, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4f3 },
-    { 0x0000002c, 0x00200a2d, 0x000 },
-    { 0x00040000, 0x18e00c11, 0x4e2 },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xd8c04800, 0x4d6 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000002d, 0x0020122d, 0x000 },
-    { 0x00000000, 0x00290c83, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000011, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x49d },
-    { 0x0000002c, 0xc0203620, 0x000 },
-    { 0x0000002d, 0xc0403620, 0x000 },
-    { 0x0000000f, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4f8 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0xd9000000, 0x000 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xb5000000, 0x00204411, 0x000 },
-    { 0x00002000, 0x00204811, 0x000 },
-    { 0xb6000000, 0x00204411, 0x000 },
-    { 0x0000a000, 0x00204811, 0x000 },
-    { 0xb7000000, 0x00204411, 0x000 },
-    { 0x0000c000, 0x00204811, 0x000 },
-    { 0xb8000000, 0x00204411, 0x000 },
-    { 0x0000f8e0, 0x00204811, 0x000 },
-    { 0xb9000000, 0x00204411, 0x000 },
-    { 0x0000f880, 0x00204811, 0x000 },
-    { 0xba000000, 0x00204411, 0x000 },
-    { 0x0000e000, 0x00204811, 0x000 },
-    { 0xbb000000, 0x00204411, 0x000 },
-    { 0x0000f000, 0x00204811, 0x000 },
-    { 0xbc000000, 0x00204411, 0x000 },
-    { 0x0000f3fc, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00204811, 0x000 },
-    { 0x000000ff, 0x00280e30, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x50c },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x14c00000, 0x521 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000001c, 0x00203623, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x00000028, 0x00203623, 0x000 },
-    { 0x00000017, 0x00203623, 0x000 },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203623, 0x000 },
-    { 0x00000015, 0x00203623, 0x000 },
-    { 0x00000016, 0x00203623, 0x000 },
-    { 0xffffe000, 0x00200c11, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00200c11, 0x000 },
-    { 0x00000023, 0x00203623, 0x000 },
-    { 0x00000024, 0x00203623, 0x000 },
-    { 0xf1ffffff, 0x00283a2e, 0x000 },
-    { 0x0000001a, 0xc0220e20, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000002a, 0x40203620, 0x000 },
-    { 0x87000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x9d000000, 0x00204411, 0x000 },
-    { 0x0000001f, 0x40214a20, 0x000 },
-    { 0x96000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x0000001f, 0x00211624, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x0000001d, 0x00203623, 0x000 },
-    { 0x00000003, 0x00281e23, 0x000 },
-    { 0x00000008, 0x00222223, 0x000 },
-    { 0xfffff000, 0x00282228, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x0000001f, 0x00203628, 0x000 },
-    { 0x00000018, 0x00211e23, 0x000 },
-    { 0x00000020, 0x00203627, 0x000 },
-    { 0x00000002, 0x00221624, 0x000 },
-    { 0x00000000, 0x003014a8, 0x000 },
-    { 0x0000001e, 0x00203625, 0x000 },
-    { 0x00000003, 0x00211a24, 0x000 },
-    { 0x10000000, 0x00281a26, 0x000 },
-    { 0xefffffff, 0x00283a2e, 0x000 },
-    { 0x00000000, 0x004938ce, 0x66a },
-    { 0x00000001, 0x40280a20, 0x000 },
-    { 0x00000006, 0x40280e20, 0x000 },
-    { 0x00000300, 0xc0281220, 0x000 },
-    { 0x00000008, 0x00211224, 0x000 },
-    { 0x00000000, 0xc0201620, 0x000 },
-    { 0x00000000, 0xc0201a20, 0x000 },
-    { 0x00000000, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x559 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x67c },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00020000, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x561 },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x56f },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x561 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x67c },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x56f },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x565 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00000000, 0xc0400000, 0x56f },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x56d },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x681 },
-    { 0x00000000, 0x00401c10, 0x56f },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x571 },
-    { 0x00000000, 0x00600000, 0x5bc },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x582 },
-    { 0x0000a2b7, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x67c },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x0000a2c4, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x580 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000001, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x593 },
-    { 0x0000a2bb, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x67c },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x0000a2c5, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x591 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000002, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5a4 },
-    { 0x0000a2bf, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x67c },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x0000a2c6, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5a2 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x0000a2c3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x67c },
-    { 0x0000001a, 0x00212230, 0x000 },
-    { 0x00000006, 0x00222630, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x0000a2c7, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5b1 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0x01000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00400000, 0x5b7 },
-    { 0xa4000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5bc },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000002c, 0x00203621, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5c3 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000030, 0x00403621, 0x5d6 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x5d6 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004a092, 0x00604411, 0x67c },
-    { 0x00000031, 0x00203630, 0x000 },
-    { 0x0004a093, 0x00604411, 0x67c },
-    { 0x00000032, 0x00203630, 0x000 },
-    { 0x0004a2b6, 0x00604411, 0x67c },
-    { 0x00000033, 0x00203630, 0x000 },
-    { 0x0004a2ba, 0x00604411, 0x67c },
-    { 0x00000034, 0x00203630, 0x000 },
-    { 0x0004a2be, 0x00604411, 0x67c },
-    { 0x00000035, 0x00203630, 0x000 },
-    { 0x0004a2c2, 0x00604411, 0x67c },
-    { 0x00000036, 0x00203630, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x88000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000001, 0x002f0230, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x61f },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x61f },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00007e00, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x5f8 },
-    { 0x0000a092, 0x00204411, 0x000 },
-    { 0x00000031, 0x00204a2d, 0x000 },
-    { 0x0000a093, 0x00204411, 0x000 },
-    { 0x00000032, 0x00204a2d, 0x000 },
-    { 0x0000a2b6, 0x00204411, 0x000 },
-    { 0x00000033, 0x00204a2d, 0x000 },
-    { 0x0000a2ba, 0x00204411, 0x000 },
-    { 0x00000034, 0x00204a2d, 0x000 },
-    { 0x0000a2be, 0x00204411, 0x000 },
-    { 0x00000035, 0x00204a2d, 0x000 },
-    { 0x0000a2c2, 0x00204411, 0x000 },
-    { 0x00000036, 0x00204a2d, 0x000 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x000001ff, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x61e },
-    { 0x00000000, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x601 },
-    { 0x0004a003, 0x00604411, 0x67c },
-    { 0x0000a003, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x14c00000, 0x606 },
-    { 0x0004a010, 0x00604411, 0x67c },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00000001, 0x00210621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x61e },
-    { 0x0004a011, 0x00604411, 0x67c },
-    { 0x0000a011, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a012, 0x00604411, 0x67c },
-    { 0x0000a012, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a013, 0x00604411, 0x67c },
-    { 0x0000a013, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a014, 0x00604411, 0x67c },
-    { 0x0000a014, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a015, 0x00604411, 0x67c },
-    { 0x0000a015, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a016, 0x00604411, 0x67c },
-    { 0x0000a016, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x0004a017, 0x00604411, 0x67c },
-    { 0x0000a017, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x0000002c, 0x0080062d, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x630 },
-    { 0x00000030, 0x0020062d, 0x000 },
-    { 0x00000002, 0x00280621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x62e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x67c },
-    { 0x00001000, 0x00200811, 0x000 },
-    { 0x0000002b, 0x00203622, 0x000 },
-    { 0x00000000, 0x00600000, 0x634 },
-    { 0x00000000, 0x00600000, 0x5bc },
-    { 0x98000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0600000, 0x634 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000022, 0x00204811, 0x000 },
-    { 0x89000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00404811, 0x620 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404811, 0x620 },
-    { 0x00000000, 0x00600000, 0x64d },
-    { 0x0001a2a4, 0xc0204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36a },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x09800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x67c },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000004, 0x00404c11, 0x647 },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000004, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffffb, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffff7, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x36a },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x01800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004217f, 0x00604411, 0x67c },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x67b },
-    { 0x00000010, 0x00404c11, 0x661 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x38c00000, 0x000 },
-    { 0x0000001d, 0x00200a2d, 0x000 },
-    { 0x0000001e, 0x00200e2d, 0x000 },
-    { 0x0000001f, 0x0020122d, 0x000 },
-    { 0x00000020, 0x0020162d, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000004, 0x00301224, 0x000 },
-    { 0x00000000, 0x002f0064, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x67a },
-    { 0x00000003, 0x00281a22, 0x000 },
-    { 0x00000008, 0x00221222, 0x000 },
-    { 0xfffff000, 0x00281224, 0x000 },
-    { 0x00000000, 0x002910c4, 0x000 },
-    { 0x0000001f, 0x00403624, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x67c },
-    { 0x9f000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x67f },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x681 },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x684 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0xc0204411, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000024, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000022, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x014204f5, 0x05b30250, 0x000 },
-    { 0x01c30168, 0x043505b3, 0x000 },
-    { 0x02250209, 0x02500151, 0x000 },
-    { 0x02230245, 0x02a00241, 0x000 },
-    { 0x03cd05b3, 0x05b305b3, 0x000 },
-    { 0x063c063d, 0x031f05b3, 0x000 },
-    { 0x05b305b8, 0x03200340, 0x000 },
-    { 0x032a0282, 0x03420334, 0x000 },
-    { 0x05b305b3, 0x05b305b3, 0x000 },
-    { 0x05b30544, 0x05b305b3, 0x000 },
-    { 0x03b205b3, 0x04ae0344, 0x000 },
-    { 0x048d0443, 0x043305b3, 0x000 },
-    { 0x04c305b3, 0x043704d0, 0x000 },
-    { 0x044304fa, 0x03510371, 0x000 },
-    { 0x05b305b3, 0x05b305b3, 0x000 },
-    { 0x05b305b3, 0x05b305b3, 0x000 },
-    { 0x05b305b3, 0x063205ba, 0x000 },
-    { 0x05b305b3, 0x000705b3, 0x000 },
-    { 0x05b305b3, 0x05b305b3, 0x000 },
-    { 0x05b305b3, 0x05b305b3, 0x000 },
-    { 0x03ee03e3, 0x03fe03fc, 0x000 },
-    { 0x04040400, 0x04020406, 0x000 },
-    { 0x0412040e, 0x041a0416, 0x000 },
-    { 0x0422041e, 0x042a0426, 0x000 },
-    { 0x05b305b3, 0x042e05b3, 0x000 },
-    { 0x05b305b3, 0x05b305b3, 0x000 },
-    { 0x05b305b3, 0x05b305b3, 0x000 },
-    { 0x00020668, 0x06860006, 0x000 },
-};
-
-static const u32 RV670_pfp_microcode[] = {
-0xca0400,
-0xa00000,
-0x7e828b,
-0x7c038b,
-0x8001b8,
-0x7c038b,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xc41838,
-0xca2400,
-0xca2800,
-0x9581a8,
-0xc41c3a,
-0xc3c000,
-0xca0800,
-0xca0c00,
-0x7c744b,
-0xc20005,
-0x99c000,
-0xc41c3a,
-0x7c744c,
-0xc0fff0,
-0x042c04,
-0x309002,
-0x7d2500,
-0x351402,
-0x7d350b,
-0x255403,
-0x7cd580,
-0x259c03,
-0x95c004,
-0xd5001b,
-0x7eddc1,
-0x7d9d80,
-0xd6801b,
-0xd5801b,
-0xd4401e,
-0xd5401e,
-0xd6401e,
-0xd6801e,
-0xd4801e,
-0xd4c01e,
-0x9783d3,
-0xd5c01e,
-0xca0800,
-0x80001a,
-0xca0c00,
-0xe4011e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xe4013e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca1800,
-0xd4401e,
-0xd5801e,
-0x800053,
-0xd40075,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xe2001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0xd48060,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xd48061,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xca0c00,
-0xd4401e,
-0xd48016,
-0xd4c016,
-0xd4801e,
-0x8001b8,
-0xd4c01e,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x948004,
-0xca1400,
-0xe420f3,
-0xd42013,
-0xd56065,
-0xd4e01c,
-0xd5201c,
-0xd5601c,
-0x800000,
-0x062001,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9483f7,
-0xca1400,
-0xe420f3,
-0x800079,
-0xd42013,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9883ef,
-0xca1400,
-0xd40064,
-0x80008d,
-0x000000,
-0xc41432,
-0xc61843,
-0xc4082f,
-0x954005,
-0xc40c30,
-0xd4401e,
-0x800000,
-0xee001e,
-0x9583f5,
-0xc41031,
-0xd44033,
-0xd52065,
-0xd4a01c,
-0xd4e01c,
-0xd5201c,
-0xe4015e,
-0xd4001e,
-0x800000,
-0x062001,
-0xca1800,
-0x0a2001,
-0xd60076,
-0xc40836,
-0x988007,
-0xc61045,
-0x950110,
-0xd4001f,
-0xd46062,
-0x800000,
-0xd42062,
-0xcc3835,
-0xcc1433,
-0x8401bb,
-0xd40072,
-0xd5401e,
-0x800000,
-0xee001e,
-0xe2001a,
-0x8401bb,
-0xe2001a,
-0xcc104b,
-0xcc0447,
-0x2c9401,
-0x7d098b,
-0x984005,
-0x7d15cb,
-0xd4001a,
-0x8001b8,
-0xd4006d,
-0x344401,
-0xcc0c48,
-0x98403a,
-0xcc2c4a,
-0x958004,
-0xcc0449,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0x282801,
-0x8400f0,
-0xcc1003,
-0x98801b,
-0x04380c,
-0x8400f0,
-0xcc1003,
-0x988017,
-0x043808,
-0x8400f0,
-0xcc1003,
-0x988013,
-0x043804,
-0x8400f0,
-0xcc1003,
-0x988014,
-0xcc104c,
-0x9a8009,
-0xcc144d,
-0x9840dc,
-0xd4006d,
-0xcc1848,
-0xd5001a,
-0xd5401a,
-0x8000c9,
-0xd5801a,
-0x96c0d5,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0x9ac003,
-0xd4006d,
-0xd4006e,
-0x800000,
-0xec007f,
-0x9ac0cc,
-0xd4006d,
-0x8001b8,
-0xd4006e,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0x7d9103,
-0x7dd583,
-0x7d190c,
-0x35cc1f,
-0x35701f,
-0x7cf0cb,
-0x7cd08b,
-0x880000,
-0x7e8e8b,
-0x95c004,
-0xd4006e,
-0x8001b8,
-0xd4001a,
-0xd4c01a,
-0xcc0803,
-0xcc0c03,
-0xcc1003,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0xcc2403,
-0xcc2803,
-0x35c41f,
-0x36b01f,
-0x7c704b,
-0x34f01f,
-0x7c704b,
-0x35701f,
-0x7c704b,
-0x7d8881,
-0x7dccc1,
-0x7e5101,
-0x7e9541,
-0x7c9082,
-0x7cd4c2,
-0x7c848b,
-0x9ac003,
-0x7c8c8b,
-0x2c8801,
-0x98809e,
-0xd4006d,
-0x98409c,
-0xd4006e,
-0xcc084c,
-0xcc0c4d,
-0xcc1048,
-0xd4801a,
-0xd4c01a,
-0x800101,
-0xd5001a,
-0xcc0832,
-0xd40032,
-0x9482d9,
-0xca0c00,
-0xd4401e,
-0x800000,
-0xd4001e,
-0xe4011e,
-0xd4001e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd4401e,
-0xca1400,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xd5401e,
-0xd54034,
-0x800000,
-0xee001e,
-0x280404,
-0xe2001a,
-0xe2001a,
-0xd4401a,
-0xca3800,
-0xcc0803,
-0xcc0c03,
-0xcc0c03,
-0xcc0c03,
-0x9882bd,
-0x000000,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0400,
-0xc2ff00,
-0xcc0834,
-0xc13fff,
-0x7c74cb,
-0x7cc90b,
-0x7d010f,
-0x9902b0,
-0x7c738b,
-0x8401bb,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0800,
-0x281900,
-0x7d898b,
-0x958014,
-0x281404,
-0xca0c00,
-0xca1000,
-0xca1c00,
-0xca2400,
-0xe2001f,
-0xd4c01a,
-0xd5001a,
-0xd5401a,
-0xcc1803,
-0xcc2c03,
-0xcc2c03,
-0xcc2c03,
-0x7da58b,
-0x7d9c47,
-0x984297,
-0x000000,
-0x800161,
-0xd4c01a,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c06,
-0x0ccc06,
-0x98c006,
-0xcc104e,
-0x990004,
-0xd40073,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xca0800,
-0xca0c00,
-0x34d018,
-0x251001,
-0x950021,
-0xc17fff,
-0xca1000,
-0xca1400,
-0xca1800,
-0xd4801d,
-0xd4c01d,
-0x7db18b,
-0xc14202,
-0xc2c001,
-0xd5801d,
-0x34dc0e,
-0x7d5d4c,
-0x7f734c,
-0xd7401e,
-0xd5001e,
-0xd5401e,
-0xc14200,
-0xc2c000,
-0x099c01,
-0x31dc10,
-0x7f5f4c,
-0x7f734c,
-0x042802,
-0x7d8380,
-0xd5a86f,
-0xd58066,
-0xd7401e,
-0xec005e,
-0xc82402,
-0xc82402,
-0x8001b8,
-0xd60076,
-0xd4401e,
-0xd4801e,
-0xd4c01e,
-0x800000,
-0xee001e,
-0x800000,
-0xee001f,
-0xd4001f,
-0x800000,
-0xd4001f,
-0xd4001f,
-0x880000,
-0xd4001f,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x010171,
-0x020178,
-0x03008f,
-0x04007f,
-0x050003,
-0x06003f,
-0x070032,
-0x08012c,
-0x090046,
-0x0a0036,
-0x1001b6,
-0x1700a2,
-0x22013a,
-0x230149,
-0x2000b4,
-0x240125,
-0x27004d,
-0x28006a,
-0x2a0060,
-0x2b0052,
-0x2f0065,
-0x320087,
-0x34017f,
-0x3c0156,
-0x3f0072,
-0x41018c,
-0x44012e,
-0x550173,
-0x56017a,
-0x60000b,
-0x610034,
-0x620038,
-0x630038,
-0x640038,
-0x650038,
-0x660038,
-0x670038,
-0x68003a,
-0x690041,
-0x6a0048,
-0x6b0048,
-0x6c0048,
-0x6d0048,
-0x6e0048,
-0x6f0048,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-};
-
-static const u32 RS780_cp_microcode[][3] = {
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0000ffff, 0x00284621, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000000, 0x00e00000, 0x000 },
-    { 0x00010000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x622 },
-    { 0x00000000, 0x00600000, 0x5d1 },
-    { 0x00000000, 0x00600000, 0x5de },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000f00, 0x00281622, 0x000 },
-    { 0x00000008, 0x00211625, 0x000 },
-    { 0x00000018, 0x00203625, 0x000 },
-    { 0x8d000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x002f0225, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x018 },
-    { 0x00412000, 0x00404811, 0x019 },
-    { 0x00422000, 0x00204811, 0x000 },
-    { 0x8e000000, 0x00204411, 0x000 },
-    { 0x00000028, 0x00204a2d, 0x000 },
-    { 0x90000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x0000000c, 0x00211622, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000019, 0x00211a22, 0x000 },
-    { 0x00000004, 0x00281a26, 0x000 },
-    { 0x00000000, 0x002914c5, 0x000 },
-    { 0x00000019, 0x00203625, 0x000 },
-    { 0x00000000, 0x003a1402, 0x000 },
-    { 0x00000016, 0x00211625, 0x000 },
-    { 0x00000003, 0x00281625, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0xfffffffc, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002914a3, 0x000 },
-    { 0x00000017, 0x00203625, 0x000 },
-    { 0x00008000, 0x00280e22, 0x000 },
-    { 0x00000007, 0x00220e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x20000000, 0x00280e22, 0x000 },
-    { 0x00000006, 0x00210e23, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x00000000, 0x00220222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x038 },
-    { 0x00000000, 0x2ee00000, 0x035 },
-    { 0x00000000, 0x2ce00000, 0x037 },
-    { 0x00000000, 0x00400e2d, 0x039 },
-    { 0x00000008, 0x00200e2d, 0x000 },
-    { 0x00000009, 0x0040122d, 0x046 },
-    { 0x00000001, 0x00400e2d, 0x039 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x03e },
-    { 0x00000008, 0x00401c11, 0x041 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x0000000f, 0x00281e27, 0x000 },
-    { 0x00000003, 0x00221e27, 0x000 },
-    { 0x7fc00000, 0x00281a23, 0x000 },
-    { 0x00000014, 0x00211a26, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000008, 0x00221a26, 0x000 },
-    { 0x00000000, 0x00290cc7, 0x000 },
-    { 0x00000027, 0x00203624, 0x000 },
-    { 0x00007f00, 0x00281221, 0x000 },
-    { 0x00001400, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x04b },
-    { 0x00000001, 0x00290e23, 0x000 },
-    { 0x0000000e, 0x00203623, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfff80000, 0x00294a23, 0x000 },
-    { 0x00000000, 0x003a2c02, 0x000 },
-    { 0x00000002, 0x00220e2b, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x0000000f, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00204a2d, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000029, 0x00200e2d, 0x000 },
-    { 0x060a0200, 0x00294a23, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14e00000, 0x061 },
-    { 0x00000000, 0x2ee00000, 0x05f },
-    { 0x00000000, 0x2ce00000, 0x05e },
-    { 0x00000000, 0x00400e2d, 0x062 },
-    { 0x00000001, 0x00400e2d, 0x062 },
-    { 0x0000000a, 0x00200e2d, 0x000 },
-    { 0x0000000b, 0x0040122d, 0x06a },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x003ffffc, 0x00281223, 0x000 },
-    { 0x00000002, 0x00221224, 0x000 },
-    { 0x7fc00000, 0x00281623, 0x000 },
-    { 0x00000014, 0x00211625, 0x000 },
-    { 0x00000001, 0x00331625, 0x000 },
-    { 0x80000000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00290ca3, 0x000 },
-    { 0x3ffffc00, 0x00290e23, 0x000 },
-    { 0x0000001f, 0x00211e23, 0x000 },
-    { 0x00000000, 0x14e00000, 0x06d },
-    { 0x00000100, 0x00401c11, 0x070 },
-    { 0x0000000d, 0x00201e2d, 0x000 },
-    { 0x000000f0, 0x00281e27, 0x000 },
-    { 0x00000004, 0x00221e27, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0xfffff0ff, 0x00281a30, 0x000 },
-    { 0x0000a028, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948e6, 0x000 },
-    { 0x0000a018, 0x00204411, 0x000 },
-    { 0x3fffffff, 0x00284a23, 0x000 },
-    { 0x0000a010, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000030, 0x0020162d, 0x000 },
-    { 0x00000002, 0x00291625, 0x000 },
-    { 0x00000030, 0x00203625, 0x000 },
-    { 0x00000025, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a3, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x083 },
-    { 0x00000026, 0x0020162d, 0x000 },
-    { 0x00000000, 0x002f00a4, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x084 },
-    { 0x00000000, 0x00400000, 0x08a },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203624, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x08a },
-    { 0x00000000, 0x00600000, 0x5ff },
-    { 0x00000000, 0x00600000, 0x5f3 },
-    { 0x00000002, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x08d },
-    { 0x00000012, 0xc0403620, 0x093 },
-    { 0x00000000, 0x2ee00000, 0x091 },
-    { 0x00000000, 0x2ce00000, 0x090 },
-    { 0x00000002, 0x00400e2d, 0x092 },
-    { 0x00000003, 0x00400e2d, 0x092 },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000012, 0x00203623, 0x000 },
-    { 0x00000003, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x098 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x0a0 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x2ee00000, 0x09e },
-    { 0x00000000, 0x2ce00000, 0x09d },
-    { 0x00000002, 0x00400e2d, 0x09f },
-    { 0x00000003, 0x00400e2d, 0x09f },
-    { 0x0000000c, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x003f0000, 0x00280e23, 0x000 },
-    { 0x00000010, 0x00210e23, 0x000 },
-    { 0x00000011, 0x00203623, 0x000 },
-    { 0x0000001e, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0a7 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x0000001f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0aa },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000008, 0x00210e2b, 0x000 },
-    { 0x0000007f, 0x00280e23, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0e1 },
-    { 0x00000000, 0x27000000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x0b3 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000000c, 0x00221e30, 0x000 },
-    { 0x99800000, 0x00204411, 0x000 },
-    { 0x00000004, 0x0020122d, 0x000 },
-    { 0x00000008, 0x00221224, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00291ce4, 0x000 },
-    { 0x00000000, 0x00604807, 0x12f },
-    { 0x9b000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x9c000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x0033146f, 0x000 },
-    { 0x00000001, 0x00333e23, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0x00203c05, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e007, 0x00204411, 0x000 },
-    { 0x0000000f, 0x0021022b, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0cb },
-    { 0x00f8ff08, 0x00204811, 0x000 },
-    { 0x98000000, 0x00404811, 0x0dc },
-    { 0x000000f0, 0x00280e22, 0x000 },
-    { 0x000000a0, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x0da },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d5 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0d4 },
-    { 0x00003f00, 0x00400c11, 0x0d6 },
-    { 0x00001f00, 0x00400c11, 0x0d6 },
-    { 0x00000f00, 0x00200c11, 0x000 },
-    { 0x00380009, 0x00294a23, 0x000 },
-    { 0x3f000000, 0x00280e2b, 0x000 },
-    { 0x00000002, 0x00220e23, 0x000 },
-    { 0x00000007, 0x00494a23, 0x0dc },
-    { 0x00380f09, 0x00204811, 0x000 },
-    { 0x68000007, 0x00204811, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000a202, 0x00204411, 0x000 },
-    { 0x00ff0000, 0x00280e22, 0x000 },
-    { 0x00000080, 0x00294a23, 0x000 },
-    { 0x00000027, 0x00200e2d, 0x000 },
-    { 0x00000026, 0x0020122d, 0x000 },
-    { 0x00000000, 0x002f0083, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x0ea },
-    { 0x00000000, 0x00600000, 0x5f9 },
-    { 0x00000000, 0x00400000, 0x0eb },
-    { 0x00000000, 0x00600000, 0x5fc },
-    { 0x00000007, 0x0020222d, 0x000 },
-    { 0x00000005, 0x00220e22, 0x000 },
-    { 0x00100000, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000000, 0x003a0c02, 0x000 },
-    { 0x000000ef, 0x00280e23, 0x000 },
-    { 0x00000000, 0x00292068, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000003, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x0f8 },
-    { 0x0000000b, 0x00210228, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0f8 },
-    { 0x00000400, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000001c, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x0fd },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000001e, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x10b },
-    { 0x0000a30f, 0x00204411, 0x000 },
-    { 0x00000011, 0x00200e2d, 0x000 },
-    { 0x00000001, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x104 },
-    { 0xffffffff, 0x00404811, 0x10b },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x107 },
-    { 0x0000ffff, 0x00404811, 0x10b },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x10a },
-    { 0x000000ff, 0x00404811, 0x10b },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0002c400, 0x00204411, 0x000 },
-    { 0x0000001f, 0x00210e22, 0x000 },
-    { 0x00000000, 0x14c00000, 0x112 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000018, 0x40224a20, 0x000 },
-    { 0x00000010, 0xc0424a20, 0x114 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x00000013, 0x00203623, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000000a, 0x00201011, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x11b },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00531224, 0x117 },
-    { 0xffbfffff, 0x00283a2e, 0x000 },
-    { 0x0000001b, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x12e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000d, 0x00204811, 0x000 },
-    { 0x00000018, 0x00220e30, 0x000 },
-    { 0xfc000000, 0x00280e23, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x00000000, 0x00201010, 0x000 },
-    { 0x0000e00e, 0x00204411, 0x000 },
-    { 0x07f8ff08, 0x00204811, 0x000 },
-    { 0x00000000, 0x00294a23, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a24, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00800000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204806, 0x000 },
-    { 0x00000008, 0x00214a27, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x622 },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x621 },
-    { 0x00000004, 0x00404c11, 0x135 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000001c, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x622 },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x13c },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40280620, 0x000 },
-    { 0x00000010, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x00341461, 0x000 },
-    { 0x00000000, 0x00741882, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x147 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x160 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0681a20, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x158 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000001, 0x00300a2f, 0x000 },
-    { 0x00000001, 0x00210a22, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600000, 0x18f },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00202c08, 0x000 },
-    { 0x00000000, 0x00202411, 0x000 },
-    { 0x00000000, 0x00202811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00221e29, 0x000 },
-    { 0x00000000, 0x007048eb, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000001, 0x40330620, 0x000 },
-    { 0x00000000, 0xc0302409, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x181 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x186 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x186 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000001, 0x00530621, 0x182 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0604800, 0x197 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000011, 0x0020062d, 0x000 },
-    { 0x00000000, 0x0078042a, 0x2fb },
-    { 0x00000000, 0x00202809, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x174 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x194 },
-    { 0x00000015, 0xc0203620, 0x000 },
-    { 0x00000016, 0xc0203620, 0x000 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x46000000, 0x00600811, 0x1b2 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x19b },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00804811, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000ffff, 0x40281620, 0x000 },
-    { 0x00000010, 0xc0811a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x00000008, 0x00221e30, 0x000 },
-    { 0x00000029, 0x00201a2d, 0x000 },
-    { 0x0000e000, 0x00204411, 0x000 },
-    { 0xfffbff09, 0x00204811, 0x000 },
-    { 0x0000000f, 0x0020222d, 0x000 },
-    { 0x00001fff, 0x00294a28, 0x000 },
-    { 0x00000006, 0x0020222d, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000100, 0x00201811, 0x000 },
-    { 0x00000008, 0x00621e28, 0x12f },
-    { 0x00000008, 0x00822228, 0x000 },
-    { 0x0002c000, 0x00204411, 0x000 },
-    { 0x00000015, 0x00600e2d, 0x1bd },
-    { 0x00000016, 0x00600e2d, 0x1bd },
-    { 0x0000c008, 0x00204411, 0x000 },
-    { 0x00000017, 0x00200e2d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x1b9 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x39000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00804802, 0x000 },
-    { 0x00000018, 0x00202e2d, 0x000 },
-    { 0x00000000, 0x003b0d63, 0x000 },
-    { 0x00000008, 0x00224a23, 0x000 },
-    { 0x00000010, 0x00224a23, 0x000 },
-    { 0x00000018, 0x00224a23, 0x000 },
-    { 0x00000000, 0x00804803, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00000007, 0x0021062f, 0x000 },
-    { 0x00000013, 0x00200a2d, 0x000 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000ffff, 0x40282220, 0x000 },
-    { 0x0000000f, 0x00262228, 0x000 },
-    { 0x00000010, 0x40212620, 0x000 },
-    { 0x0000000f, 0x00262629, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1e0 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000081, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000080, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1dc },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1d8 },
-    { 0x00000001, 0x00202c11, 0x000 },
-    { 0x0000001f, 0x00280a22, 0x000 },
-    { 0x0000001f, 0x00282a2a, 0x000 },
-    { 0x00000001, 0x00530621, 0x1d1 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000002, 0x00304a2f, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000001, 0x00301e2f, 0x000 },
-    { 0x00000000, 0x002f0227, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00600000, 0x1e9 },
-    { 0x00000001, 0x00531e27, 0x1e5 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x0000000f, 0x00260e23, 0x000 },
-    { 0x00000010, 0xc0211220, 0x000 },
-    { 0x0000000f, 0x00261224, 0x000 },
-    { 0x00000000, 0x00201411, 0x000 },
-    { 0x00000000, 0x00601811, 0x2bb },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022b, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x1f8 },
-    { 0x00000010, 0x00221628, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a29, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x0020480a, 0x000 },
-    { 0x00000000, 0x00202c11, 0x000 },
-    { 0x00000010, 0x00221623, 0x000 },
-    { 0xffff0000, 0x00281625, 0x000 },
-    { 0x0000ffff, 0x00281a24, 0x000 },
-    { 0x00000000, 0x002948c5, 0x000 },
-    { 0x00000000, 0x00731503, 0x205 },
-    { 0x00000000, 0x00201805, 0x000 },
-    { 0x00000000, 0x00731524, 0x205 },
-    { 0x00000000, 0x002d14c5, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00202802, 0x000 },
-    { 0x00000000, 0x00202003, 0x000 },
-    { 0x00000000, 0x00802404, 0x000 },
-    { 0x0000000f, 0x00210225, 0x000 },
-    { 0x00000000, 0x14c00000, 0x621 },
-    { 0x00000000, 0x002b1405, 0x000 },
-    { 0x00000001, 0x00901625, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001a, 0x00294a22, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a21, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000ffff, 0x40281220, 0x000 },
-    { 0x00000010, 0xc0211a20, 0x000 },
-    { 0x0000ffff, 0x40280e20, 0x000 },
-    { 0x00000010, 0xc0211620, 0x000 },
-    { 0x00000000, 0x00741465, 0x2bb },
-    { 0x0001a1fd, 0x00604411, 0x2e0 },
-    { 0x00000001, 0x00330621, 0x000 },
-    { 0x00000000, 0x002f0221, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x219 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x212 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x5de },
-    { 0x00000000, 0x0040040f, 0x213 },
-    { 0x00000000, 0x00600000, 0x5d1 },
-    { 0x00000000, 0x00600000, 0x5de },
-    { 0x00000210, 0x00600411, 0x315 },
-    { 0x00000000, 0x00600000, 0x1a0 },
-    { 0x00000000, 0x00600000, 0x19c },
-    { 0x00000000, 0x00600000, 0x2bb },
-    { 0x00000000, 0x00600000, 0x2a3 },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204808, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x232 },
-    { 0x00000000, 0x00600000, 0x13a },
-    { 0x00000000, 0x00400000, 0x236 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x236 },
-    { 0x00000000, 0xc0404800, 0x233 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x00600411, 0x2fb },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000000, 0x00600000, 0x5d1 },
-    { 0x0000a00c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000018, 0x40210a20, 0x000 },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x24c },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x00080101, 0x00292228, 0x000 },
-    { 0x00000014, 0x00203628, 0x000 },
-    { 0x0000a30c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x251 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000010, 0x00600411, 0x315 },
-    { 0x3f800000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00000000, 0x00600000, 0x27c },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000001, 0x00211e27, 0x000 },
-    { 0x00000000, 0x14e00000, 0x26a },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x0000ffff, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00341c27, 0x000 },
-    { 0x00000000, 0x12c00000, 0x25f },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e5, 0x000 },
-    { 0x00000000, 0x08c00000, 0x262 },
-    { 0x00000000, 0x00201407, 0x000 },
-    { 0x00000012, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00211e27, 0x000 },
-    { 0x00000000, 0x00341c47, 0x000 },
-    { 0x00000000, 0x12c00000, 0x267 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x08c00000, 0x26a },
-    { 0x00000000, 0x00201807, 0x000 },
-    { 0x00000000, 0x00600000, 0x2c1 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x00000000, 0x00342023, 0x000 },
-    { 0x00000000, 0x12c00000, 0x272 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x271 },
-    { 0x00000016, 0x00404811, 0x276 },
-    { 0x00000018, 0x00404811, 0x276 },
-    { 0x00000000, 0x00342044, 0x000 },
-    { 0x00000000, 0x12c00000, 0x275 },
-    { 0x00000017, 0x00404811, 0x276 },
-    { 0x00000019, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0x00604411, 0x2e9 },
-    { 0x00003fff, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x256 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x00000010, 0x40210620, 0x000 },
-    { 0x0000ffff, 0xc0280a20, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x00000010, 0x40211620, 0x000 },
-    { 0x0000ffff, 0xc0881a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00042004, 0x00604411, 0x622 },
-    { 0x00000000, 0x00600000, 0x5d1 },
-    { 0x00000000, 0xc0600000, 0x2a3 },
-    { 0x00000005, 0x00200a2d, 0x000 },
-    { 0x00000008, 0x00220a22, 0x000 },
-    { 0x0000002b, 0x00201a2d, 0x000 },
-    { 0x0000001c, 0x00201e2d, 0x000 },
-    { 0x00007000, 0x00281e27, 0x000 },
-    { 0x00000000, 0x00311ce6, 0x000 },
-    { 0x0000002a, 0x00201a2d, 0x000 },
-    { 0x0000000c, 0x00221a26, 0x000 },
-    { 0x00000000, 0x002f00e6, 0x000 },
-    { 0x00000000, 0x06e00000, 0x292 },
-    { 0x00000000, 0x00201c11, 0x000 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000010, 0x00201811, 0x000 },
-    { 0x00000000, 0x00691ce2, 0x12f },
-    { 0x93800000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x95000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f022f, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x29d },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x92000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000001c, 0x00403627, 0x000 },
-    { 0x0000000c, 0xc0220a20, 0x000 },
-    { 0x00000029, 0x00203622, 0x000 },
-    { 0x00000028, 0xc0403620, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000009, 0x00204811, 0x000 },
-    { 0xa1000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00804811, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce3, 0x000 },
-    { 0x00000021, 0x00203627, 0x000 },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002c1ce4, 0x000 },
-    { 0x00000022, 0x00203627, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a3, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x00000000, 0x002d1d07, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203624, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000023, 0x00203627, 0x000 },
-    { 0x00000000, 0x00311cc4, 0x000 },
-    { 0x00000024, 0x00803627, 0x000 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14c00000, 0x2dc },
-    { 0x00000000, 0x00400000, 0x2d9 },
-    { 0x0000001a, 0x00203627, 0x000 },
-    { 0x0000001b, 0x00203628, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000002, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2d9 },
-    { 0x00000003, 0x00210227, 0x000 },
-    { 0x00000000, 0x14e00000, 0x2dc },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e1, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120a1, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000024, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x002e00e2, 0x000 },
-    { 0x00000000, 0x02c00000, 0x2dc },
-    { 0x00000022, 0x00201e2d, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x00000000, 0x002e00e8, 0x000 },
-    { 0x00000000, 0x06c00000, 0x2dc },
-    { 0x00000000, 0x00600000, 0x5ff },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2b5 },
-    { 0x00000000, 0x00600000, 0x5f6 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x00000000, 0x00600000, 0x2a7 },
-    { 0x00000000, 0x00400000, 0x2de },
-    { 0x0000001a, 0x00201e2d, 0x000 },
-    { 0x0000001b, 0x0080222d, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000000, 0x00311ca1, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294847, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e21, 0x000 },
-    { 0x00000000, 0x003120c2, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00311ca3, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294887, 0x000 },
-    { 0x00000001, 0x00220a21, 0x000 },
-    { 0x00000000, 0x003008a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000010, 0x00221e23, 0x000 },
-    { 0x00000000, 0x003120c4, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x003808c5, 0x000 },
-    { 0x00000000, 0x00300841, 0x000 },
-    { 0x00000001, 0x00220a22, 0x000 },
-    { 0x00000000, 0x003308a2, 0x000 },
-    { 0x00000010, 0x00221e22, 0x000 },
-    { 0x00000010, 0x00212222, 0x000 },
-    { 0x00000000, 0x00894907, 0x000 },
-    { 0x00000017, 0x0020222d, 0x000 },
-    { 0x00000000, 0x14c00000, 0x318 },
-    { 0xffffffef, 0x00280621, 0x000 },
-    { 0x00000014, 0x0020222d, 0x000 },
-    { 0x0000f8e0, 0x00204411, 0x000 },
-    { 0x00000000, 0x00294901, 0x000 },
-    { 0x00000000, 0x00894901, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x060a0200, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0204811, 0x000 },
-    { 0x8a000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00002257, 0x00204411, 0x000 },
-    { 0x00000003, 0xc0484a20, 0x000 },
-    { 0x0000225d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0x00600000, 0x5de },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00384a22, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0001a1fd, 0x00204411, 0x000 },
-    { 0x00000000, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x00000001, 0x40304a20, 0x000 },
-    { 0x00000002, 0xc0304a20, 0x000 },
-    { 0x00000001, 0x00530a22, 0x355 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x622 },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x35e },
-    { 0x00000014, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x36c },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00604802, 0x374 },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x370 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x367 },
-    { 0x00000028, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5ba },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x367 },
-    { 0x0000002c, 0x00203626, 0x000 },
-    { 0x00000049, 0x00201811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000001, 0x00331a26, 0x000 },
-    { 0x00000000, 0x002f0226, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x376 },
-    { 0x0000002c, 0x00801a2d, 0x000 },
-    { 0x0000003f, 0xc0280a20, 0x000 },
-    { 0x00000015, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x38c },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b7 },
-    { 0x00000016, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3b9 },
-    { 0x00000020, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3a2 },
-    { 0x0000000f, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3ae },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x3ae },
-    { 0x0000001e, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x396 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x08000000, 0x00290a22, 0x000 },
-    { 0x00000003, 0x40210e20, 0x000 },
-    { 0x0000000c, 0xc0211220, 0x000 },
-    { 0x00080000, 0x00281224, 0x000 },
-    { 0x00000014, 0xc0221620, 0x000 },
-    { 0x00000000, 0x002914a4, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x002948a2, 0x000 },
-    { 0x0000a1fe, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000016, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x622 },
-    { 0x00000015, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x398 },
-    { 0x0000210e, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000017, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x622 },
-    { 0x00000003, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3a4 },
-    { 0x00002108, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404802, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x80000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000010, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3b4 },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000006, 0x00404811, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x374 },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x0000001d, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3ce },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x00000018, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x622 },
-    { 0x00000011, 0x00210230, 0x000 },
-    { 0x00000000, 0x14e00000, 0x3c2 },
-    { 0x00002100, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0xbabecafe, 0x00204811, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000004, 0x00404811, 0x000 },
-    { 0x00002170, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000a, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3d3 },
-    { 0x8c000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00003fff, 0x40280a20, 0x000 },
-    { 0x80000000, 0x40280e20, 0x000 },
-    { 0x40000000, 0xc0281220, 0x000 },
-    { 0x00040000, 0x00694622, 0x622 },
-    { 0x00000000, 0x00201410, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e1 },
-    { 0x00000000, 0xc0401800, 0x3e4 },
-    { 0x00003fff, 0xc0281a20, 0x000 },
-    { 0x00040000, 0x00694626, 0x622 },
-    { 0x00000000, 0x00201810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x3e7 },
-    { 0x00000000, 0xc0401c00, 0x3ea },
-    { 0x00003fff, 0xc0281e20, 0x000 },
-    { 0x00040000, 0x00694627, 0x622 },
-    { 0x00000000, 0x00201c10, 0x000 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0x002820c5, 0x000 },
-    { 0x00000000, 0x004948e8, 0x000 },
-    { 0xa5800000, 0x00200811, 0x000 },
-    { 0x00002000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x40204800, 0x000 },
-    { 0x0000001f, 0xc0210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x3f7 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00008000, 0x00204811, 0x000 },
-    { 0x0000ffff, 0xc0481220, 0x3ff },
-    { 0xa7800000, 0x00200811, 0x000 },
-    { 0x0000a000, 0x00200c11, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0x00204402, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000ffff, 0xc0281220, 0x000 },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00304883, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x83000000, 0x00604411, 0x412 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xa9800000, 0x00200811, 0x000 },
-    { 0x0000c000, 0x00400c11, 0x3fa },
-    { 0xab800000, 0x00200811, 0x000 },
-    { 0x0000f8e0, 0x00400c11, 0x3fa },
-    { 0xad800000, 0x00200811, 0x000 },
-    { 0x0000f880, 0x00400c11, 0x3fa },
-    { 0xb3800000, 0x00200811, 0x000 },
-    { 0x0000f3fc, 0x00400c11, 0x3fa },
-    { 0xaf800000, 0x00200811, 0x000 },
-    { 0x0000e000, 0x00400c11, 0x3fa },
-    { 0xb1800000, 0x00200811, 0x000 },
-    { 0x0000f000, 0x00400c11, 0x3fa },
-    { 0x83000000, 0x00204411, 0x000 },
-    { 0x00002148, 0x00204811, 0x000 },
-    { 0x84000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x1d000000, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x01182000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0218a000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0318c000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0418f8e0, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0518f880, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0618e000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0718f000, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x0818f3fc, 0xc0304620, 0x000 },
-    { 0x00000000, 0xd9004800, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x00000033, 0xc0300a20, 0x000 },
-    { 0x00000000, 0xc0403440, 0x000 },
-    { 0x00000030, 0x00200a2d, 0x000 },
-    { 0x00000000, 0xc0290c40, 0x000 },
-    { 0x00000030, 0x00203623, 0x000 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x00a0000a, 0x000 },
-    { 0x86000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x85000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0x00404801, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x00000018, 0x40210220, 0x000 },
-    { 0x00000000, 0x14c00000, 0x447 },
-    { 0x00800000, 0xc0494a20, 0x448 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x06e00000, 0x450 },
-    { 0x00000004, 0x00200811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x622 },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00404c02, 0x450 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x00000000, 0xc0201400, 0x000 },
-    { 0x00000000, 0xc0201800, 0x000 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x461 },
-    { 0x00000000, 0xc0202000, 0x000 },
-    { 0x00000004, 0x002f0228, 0x000 },
-    { 0x00000000, 0x06e00000, 0x461 },
-    { 0x00000004, 0x00202011, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x00000010, 0x00280a23, 0x000 },
-    { 0x00000010, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x469 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0x00694624, 0x622 },
-    { 0x00000000, 0x00400000, 0x46e },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00604805, 0x627 },
-    { 0x00000000, 0x002824f0, 0x000 },
-    { 0x00000007, 0x00280a23, 0x000 },
-    { 0x00000001, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x475 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x04e00000, 0x48e },
-    { 0x00000000, 0x00400000, 0x49b },
-    { 0x00000002, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x47a },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x02e00000, 0x48e },
-    { 0x00000000, 0x00400000, 0x49b },
-    { 0x00000003, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x47f },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x48e },
-    { 0x00000000, 0x00400000, 0x49b },
-    { 0x00000004, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x484 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x48e },
-    { 0x00000000, 0x00400000, 0x49b },
-    { 0x00000005, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x489 },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x06e00000, 0x48e },
-    { 0x00000000, 0x00400000, 0x49b },
-    { 0x00000006, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x48e },
-    { 0x00000000, 0x002f00c9, 0x000 },
-    { 0x00000000, 0x08e00000, 0x48e },
-    { 0x00000000, 0x00400000, 0x49b },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x000 },
-    { 0x00000008, 0x00210a23, 0x000 },
-    { 0x00000000, 0x14c00000, 0x498 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00007f00, 0x00280a21, 0x000 },
-    { 0x00004500, 0x002f0222, 0x000 },
-    { 0x00000000, 0x0ae00000, 0x4a1 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x00404c08, 0x461 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000010, 0x40210e20, 0x000 },
-    { 0x00000011, 0x40211220, 0x000 },
-    { 0x00000012, 0x40211620, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00210225, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4ab },
-    { 0x00040000, 0xc0494a20, 0x4ac },
-    { 0xfffbffff, 0xc0284a20, 0x000 },
-    { 0x00000000, 0x00210223, 0x000 },
-    { 0x00000000, 0x14e00000, 0x4b8 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x0000000c, 0x00204811, 0x000 },
-    { 0x00000000, 0x00200010, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4b4 },
-    { 0xa0000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000004, 0x00204811, 0x000 },
-    { 0x0000216b, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000216c, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204810, 0x000 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0ce00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4b2 },
-    { 0x00000000, 0xc0210a20, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4cb },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x627 },
-    { 0x00000000, 0x00400000, 0x4cf },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00040000, 0xc0294620, 0x000 },
-    { 0x00000000, 0xc0600000, 0x622 },
-    { 0x00000001, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4d6 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00404811, 0x000 },
-    { 0x00000000, 0xc0204400, 0x000 },
-    { 0x00000000, 0xc0404810, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x000021f8, 0x00204411, 0x000 },
-    { 0x0000000e, 0x00204811, 0x000 },
-    { 0x000421f9, 0x00604411, 0x622 },
-    { 0x00000000, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x4d8 },
-    { 0x00002180, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000003, 0x00333e2f, 0x000 },
-    { 0x00000001, 0x00210221, 0x000 },
-    { 0x00000000, 0x14e00000, 0x508 },
-    { 0x0000002c, 0x00200a2d, 0x000 },
-    { 0x00040000, 0x18e00c11, 0x4f7 },
-    { 0x00000001, 0x00333e2f, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xd8c04800, 0x4eb },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000002d, 0x0020122d, 0x000 },
-    { 0x00000000, 0x00290c83, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204802, 0x000 },
-    { 0x00000000, 0x00204803, 0x000 },
-    { 0x00000008, 0x00300a22, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000011, 0x00210224, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000000, 0x00400000, 0x4b2 },
-    { 0x0000002c, 0xc0203620, 0x000 },
-    { 0x0000002d, 0xc0403620, 0x000 },
-    { 0x0000000f, 0x00210221, 0x000 },
-    { 0x00000000, 0x14c00000, 0x50d },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00000000, 0xd9000000, 0x000 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0xb5000000, 0x00204411, 0x000 },
-    { 0x00002000, 0x00204811, 0x000 },
-    { 0xb6000000, 0x00204411, 0x000 },
-    { 0x0000a000, 0x00204811, 0x000 },
-    { 0xb7000000, 0x00204411, 0x000 },
-    { 0x0000c000, 0x00204811, 0x000 },
-    { 0xb8000000, 0x00204411, 0x000 },
-    { 0x0000f8e0, 0x00204811, 0x000 },
-    { 0xb9000000, 0x00204411, 0x000 },
-    { 0x0000f880, 0x00204811, 0x000 },
-    { 0xba000000, 0x00204411, 0x000 },
-    { 0x0000e000, 0x00204811, 0x000 },
-    { 0xbb000000, 0x00204411, 0x000 },
-    { 0x0000f000, 0x00204811, 0x000 },
-    { 0xbc000000, 0x00204411, 0x000 },
-    { 0x0000f3fc, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000002, 0x00204811, 0x000 },
-    { 0x000000ff, 0x00280e30, 0x000 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x521 },
-    { 0x00000000, 0xc0200800, 0x000 },
-    { 0x00000000, 0x14c00000, 0x536 },
-    { 0x00000000, 0x00200c11, 0x000 },
-    { 0x0000001c, 0x00203623, 0x000 },
-    { 0x0000002b, 0x00203623, 0x000 },
-    { 0x00000029, 0x00203623, 0x000 },
-    { 0x00000028, 0x00203623, 0x000 },
-    { 0x00000017, 0x00203623, 0x000 },
-    { 0x00000025, 0x00203623, 0x000 },
-    { 0x00000026, 0x00203623, 0x000 },
-    { 0x00000015, 0x00203623, 0x000 },
-    { 0x00000016, 0x00203623, 0x000 },
-    { 0xffffe000, 0x00200c11, 0x000 },
-    { 0x00000021, 0x00203623, 0x000 },
-    { 0x00000022, 0x00203623, 0x000 },
-    { 0x00001fff, 0x00200c11, 0x000 },
-    { 0x00000023, 0x00203623, 0x000 },
-    { 0x00000024, 0x00203623, 0x000 },
-    { 0xf1ffffff, 0x00283a2e, 0x000 },
-    { 0x0000001a, 0xc0220e20, 0x000 },
-    { 0x00000000, 0x0029386e, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000006, 0x00204811, 0x000 },
-    { 0x0000002a, 0x40203620, 0x000 },
-    { 0x87000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0x9d000000, 0x00204411, 0x000 },
-    { 0x0000001f, 0x40214a20, 0x000 },
-    { 0x96000000, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0200c00, 0x000 },
-    { 0x00000000, 0xc0201000, 0x000 },
-    { 0x0000001f, 0x00211624, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x0000001d, 0x00203623, 0x000 },
-    { 0x00000003, 0x00281e23, 0x000 },
-    { 0x00000008, 0x00222223, 0x000 },
-    { 0xfffff000, 0x00282228, 0x000 },
-    { 0x00000000, 0x002920e8, 0x000 },
-    { 0x0000001f, 0x00203628, 0x000 },
-    { 0x00000018, 0x00211e23, 0x000 },
-    { 0x00000020, 0x00203627, 0x000 },
-    { 0x00000002, 0x00221624, 0x000 },
-    { 0x00000000, 0x003014a8, 0x000 },
-    { 0x0000001e, 0x00203625, 0x000 },
-    { 0x00000003, 0x00211a24, 0x000 },
-    { 0x10000000, 0x00281a26, 0x000 },
-    { 0xefffffff, 0x00283a2e, 0x000 },
-    { 0x00000000, 0x004938ce, 0x610 },
-    { 0x00000001, 0x40280a20, 0x000 },
-    { 0x00000006, 0x40280e20, 0x000 },
-    { 0x00000300, 0xc0281220, 0x000 },
-    { 0x00000008, 0x00211224, 0x000 },
-    { 0x00000000, 0xc0201620, 0x000 },
-    { 0x00000000, 0xc0201a20, 0x000 },
-    { 0x00000000, 0x00210222, 0x000 },
-    { 0x00000000, 0x14c00000, 0x56c },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x622 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00020000, 0x00294a26, 0x000 },
-    { 0x00000000, 0x00204810, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x574 },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x582 },
-    { 0x00000002, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x574 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00002258, 0x00300a24, 0x000 },
-    { 0x00040000, 0x00694622, 0x622 },
-    { 0x00000000, 0xc0201c10, 0x000 },
-    { 0x00000000, 0xc0400000, 0x582 },
-    { 0x00000000, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x578 },
-    { 0x00000000, 0xc0201c00, 0x000 },
-    { 0x00000000, 0xc0400000, 0x582 },
-    { 0x00000004, 0x002f0223, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x580 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x0000216d, 0x00204411, 0x000 },
-    { 0x00000000, 0xc0204800, 0x000 },
-    { 0x00000000, 0xc0604800, 0x627 },
-    { 0x00000000, 0x00401c10, 0x582 },
-    { 0x00000000, 0xc0200000, 0x000 },
-    { 0x00000000, 0xc0400000, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x584 },
-    { 0x00000000, 0x00600000, 0x5c3 },
-    { 0x00000000, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x592 },
-    { 0x0000a2b7, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x00000033, 0x0020262d, 0x000 },
-    { 0x0000001a, 0x00212229, 0x000 },
-    { 0x00000006, 0x00222629, 0x000 },
-    { 0x0000a2c4, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x590 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d1, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000001, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5a0 },
-    { 0x0000a2bb, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x00000034, 0x0020262d, 0x000 },
-    { 0x0000001a, 0x00212229, 0x000 },
-    { 0x00000006, 0x00222629, 0x000 },
-    { 0x0000a2c5, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x59e },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d2, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x00000002, 0x002f0224, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x5ae },
-    { 0x0000a2bf, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x00000035, 0x0020262d, 0x000 },
-    { 0x0000001a, 0x00212229, 0x000 },
-    { 0x00000006, 0x00222629, 0x000 },
-    { 0x0000a2c6, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5ac },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d3, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x0000a2c3, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204807, 0x000 },
-    { 0x00000036, 0x0020262d, 0x000 },
-    { 0x0000001a, 0x00212229, 0x000 },
-    { 0x00000006, 0x00222629, 0x000 },
-    { 0x0000a2c7, 0x00204411, 0x000 },
-    { 0x00000000, 0x003048e9, 0x000 },
-    { 0x00000000, 0x00e00000, 0x5b8 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404808, 0x000 },
-    { 0x0000a2d4, 0x00204411, 0x000 },
-    { 0x00000001, 0x00504a28, 0x000 },
-    { 0x85000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0x0000304a, 0x00204411, 0x000 },
-    { 0x01000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x00400000, 0x5be },
-    { 0xa4000000, 0xc0204411, 0x000 },
-    { 0x00000000, 0xc0404800, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5c3 },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x0000003f, 0x00204811, 0x000 },
-    { 0x00000005, 0x00204811, 0x000 },
-    { 0x0000a1f4, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x88000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0xff000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x00000002, 0x00804811, 0x000 },
-    { 0x00000000, 0x0ee00000, 0x5d6 },
-    { 0x00001000, 0x00200811, 0x000 },
-    { 0x0000002b, 0x00203622, 0x000 },
-    { 0x00000000, 0x00600000, 0x5da },
-    { 0x00000000, 0x00600000, 0x5c3 },
-    { 0x98000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00804811, 0x000 },
-    { 0x00000000, 0xc0600000, 0x5da },
-    { 0x00000000, 0xc0400400, 0x001 },
-    { 0x0000a2a4, 0x00204411, 0x000 },
-    { 0x00000022, 0x00204811, 0x000 },
-    { 0x89000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00404811, 0x5cd },
-    { 0x97000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x8a000000, 0x00204411, 0x000 },
-    { 0x00000000, 0x00404811, 0x5cd },
-    { 0x00000000, 0x00600000, 0x5f3 },
-    { 0x0001a2a4, 0xc0204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x374 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x09800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x0004217f, 0x00604411, 0x622 },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x000 },
-    { 0x00000004, 0x00404c11, 0x5ed },
-    { 0x00000000, 0x00400000, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000004, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffffb, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0x00000008, 0x00291e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x00000017, 0x00201e2d, 0x000 },
-    { 0xfffffff7, 0x00281e27, 0x000 },
-    { 0x00000017, 0x00803627, 0x000 },
-    { 0x0001a2a4, 0x00204411, 0x000 },
-    { 0x00000016, 0x00604811, 0x374 },
-    { 0x00002010, 0x00204411, 0x000 },
-    { 0x00010000, 0x00204811, 0x000 },
-    { 0x0000217c, 0x00204411, 0x000 },
-    { 0x01800000, 0x00204811, 0x000 },
-    { 0xffffffff, 0x00204811, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000000, 0x17000000, 0x000 },
-    { 0x81000000, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0004217f, 0x00604411, 0x622 },
-    { 0x0000001f, 0x00210230, 0x000 },
-    { 0x00000000, 0x14c00000, 0x621 },
-    { 0x00000010, 0x00404c11, 0x607 },
-    { 0x00000000, 0xc0200400, 0x000 },
-    { 0x00000000, 0x38c00000, 0x000 },
-    { 0x0000001d, 0x00200a2d, 0x000 },
-    { 0x0000001e, 0x00200e2d, 0x000 },
-    { 0x0000001f, 0x0020122d, 0x000 },
-    { 0x00000020, 0x0020162d, 0x000 },
-    { 0x00002169, 0x00204411, 0x000 },
-    { 0x00000000, 0x00204804, 0x000 },
-    { 0x00000000, 0x00204805, 0x000 },
-    { 0x00000000, 0x00204801, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000004, 0x00301224, 0x000 },
-    { 0x00000000, 0x002f0064, 0x000 },
-    { 0x00000000, 0x0cc00000, 0x620 },
-    { 0x00000003, 0x00281a22, 0x000 },
-    { 0x00000008, 0x00221222, 0x000 },
-    { 0xfffff000, 0x00281224, 0x000 },
-    { 0x00000000, 0x002910c4, 0x000 },
-    { 0x0000001f, 0x00403624, 0x000 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x622 },
-    { 0x9f000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x625 },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x1ac00000, 0x627 },
-    { 0x9e000000, 0x00204411, 0x000 },
-    { 0xcafebabe, 0x00204811, 0x000 },
-    { 0x00000000, 0x1ae00000, 0x62a },
-    { 0x00000000, 0x00800000, 0x000 },
-    { 0x00000000, 0x00600000, 0x00b },
-    { 0x00001000, 0x00600411, 0x315 },
-    { 0x00000000, 0x00200411, 0x000 },
-    { 0x00000000, 0x00600811, 0x1b2 },
-    { 0x0000225c, 0x00204411, 0x000 },
-    { 0x00000003, 0x00204811, 0x000 },
-    { 0x00002256, 0x00204411, 0x000 },
-    { 0x0000001b, 0x00204811, 0x000 },
-    { 0x0000a1fc, 0x00204411, 0x000 },
-    { 0x00000001, 0x00204811, 0x000 },
-    { 0x0001a1fd, 0xc0204411, 0x000 },
-    { 0x00000021, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000024, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000022, 0x0020222d, 0x000 },
-    { 0x0000ffff, 0x00282228, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00204811, 0x000 },
-    { 0x00000023, 0x00201e2d, 0x000 },
-    { 0x00000010, 0x00221e27, 0x000 },
-    { 0x00000000, 0x00294907, 0x000 },
-    { 0x00000000, 0x00404811, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x00000000, 0x00000000, 0x000 },
-    { 0x0142050a, 0x05ba0250, 0x000 },
-    { 0x01c30168, 0x044105ba, 0x000 },
-    { 0x02250209, 0x02500151, 0x000 },
-    { 0x02230245, 0x02a00241, 0x000 },
-    { 0x03d705ba, 0x05ba05ba, 0x000 },
-    { 0x05e205e3, 0x031f05ba, 0x000 },
-    { 0x032005bf, 0x0320034a, 0x000 },
-    { 0x03340282, 0x034c033e, 0x000 },
-    { 0x05ba05ba, 0x05ba05ba, 0x000 },
-    { 0x05ba0557, 0x05ba032a, 0x000 },
-    { 0x03bc05ba, 0x04c3034e, 0x000 },
-    { 0x04a20455, 0x043f05ba, 0x000 },
-    { 0x04d805ba, 0x044304e5, 0x000 },
-    { 0x0455050f, 0x035b037b, 0x000 },
-    { 0x05ba05ba, 0x05ba05ba, 0x000 },
-    { 0x05ba05ba, 0x05ba05ba, 0x000 },
-    { 0x05ba05ba, 0x05d805c1, 0x000 },
-    { 0x05ba05ba, 0x000705ba, 0x000 },
-    { 0x05ba05ba, 0x05ba05ba, 0x000 },
-    { 0x05ba05ba, 0x05ba05ba, 0x000 },
-    { 0x03f803ed, 0x04080406, 0x000 },
-    { 0x040e040a, 0x040c0410, 0x000 },
-    { 0x041c0418, 0x04240420, 0x000 },
-    { 0x042c0428, 0x04340430, 0x000 },
-    { 0x05ba05ba, 0x043a0438, 0x000 },
-    { 0x05ba05ba, 0x05ba05ba, 0x000 },
-    { 0x05ba05ba, 0x05ba05ba, 0x000 },
-    { 0x0002060e, 0x062c0006, 0x000 },
-};
-
-static const u32 RS780_pfp_microcode[] = {
-0xca0400,
-0xa00000,
-0x7e828b,
-0x7c038b,
-0x8001db,
-0x7c038b,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xc41838,
-0xca2400,
-0xca2800,
-0x9581cb,
-0xc41c3a,
-0xc3c000,
-0xca0800,
-0xca0c00,
-0x7c744b,
-0xc20005,
-0x99c000,
-0xc41c3a,
-0x7c744c,
-0xc0ffe0,
-0x042c08,
-0x309002,
-0x7d2500,
-0x351402,
-0x7d350b,
-0x255407,
-0x7cd580,
-0x259c07,
-0x95c004,
-0xd5001b,
-0x7eddc1,
-0x7d9d80,
-0xd6801b,
-0xd5801b,
-0xd4401e,
-0xd5401e,
-0xd6401e,
-0xd6801e,
-0xd4801e,
-0xd4c01e,
-0x9783d3,
-0xd5c01e,
-0xca0800,
-0x80001a,
-0xca0c00,
-0xe4011e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xe4013e,
-0xd4001e,
-0x80000c,
-0xc41838,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0xca0c00,
-0x8001db,
-0xd48024,
-0xca0800,
-0x7c00c0,
-0xc81425,
-0xc81824,
-0x7c9488,
-0x7c9880,
-0xc20003,
-0xd40075,
-0x7c744c,
-0x800064,
-0xd4401e,
-0xca1800,
-0xd4401e,
-0xd5801e,
-0x800062,
-0xd40075,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xe2001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xd40075,
-0xd4401e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd48019,
-0xd4c018,
-0xd50017,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c01,
-0xd48060,
-0x94c003,
-0x041001,
-0x041002,
-0xd50025,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xd48061,
-0xd4401e,
-0x800000,
-0xd4801e,
-0xca0800,
-0xca0c00,
-0xd4401e,
-0xd48016,
-0xd4c016,
-0xd4801e,
-0x8001db,
-0xd4c01e,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x948004,
-0xca1400,
-0xe420f3,
-0xd42013,
-0xd56065,
-0xd4e01c,
-0xd5201c,
-0xd5601c,
-0x800000,
-0x062001,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9483f7,
-0xca1400,
-0xe420f3,
-0x80009c,
-0xd42013,
-0xc60843,
-0xca0c00,
-0xca1000,
-0x9883ef,
-0xca1400,
-0xd40064,
-0x8000b0,
-0x000000,
-0xc41432,
-0xc61843,
-0xc4082f,
-0x954005,
-0xc40c30,
-0xd4401e,
-0x800000,
-0xee001e,
-0x9583f5,
-0xc41031,
-0xd44033,
-0xd52065,
-0xd4a01c,
-0xd4e01c,
-0xd5201c,
-0xe4015e,
-0xd4001e,
-0x800000,
-0x062001,
-0xca1800,
-0x0a2001,
-0xd60076,
-0xc40836,
-0x988007,
-0xc61045,
-0x950110,
-0xd4001f,
-0xd46062,
-0x800000,
-0xd42062,
-0xcc3835,
-0xcc1433,
-0x8401de,
-0xd40072,
-0xd5401e,
-0x800000,
-0xee001e,
-0xe2001a,
-0x8401de,
-0xe2001a,
-0xcc104b,
-0xcc0447,
-0x2c9401,
-0x7d098b,
-0x984005,
-0x7d15cb,
-0xd4001a,
-0x8001db,
-0xd4006d,
-0x344401,
-0xcc0c48,
-0x98403a,
-0xcc2c4a,
-0x958004,
-0xcc0449,
-0x8001db,
-0xd4001a,
-0xd4c01a,
-0x282801,
-0x840113,
-0xcc1003,
-0x98801b,
-0x04380c,
-0x840113,
-0xcc1003,
-0x988017,
-0x043808,
-0x840113,
-0xcc1003,
-0x988013,
-0x043804,
-0x840113,
-0xcc1003,
-0x988014,
-0xcc104c,
-0x9a8009,
-0xcc144d,
-0x9840dc,
-0xd4006d,
-0xcc1848,
-0xd5001a,
-0xd5401a,
-0x8000ec,
-0xd5801a,
-0x96c0d5,
-0xd4006d,
-0x8001db,
-0xd4006e,
-0x9ac003,
-0xd4006d,
-0xd4006e,
-0x800000,
-0xec007f,
-0x9ac0cc,
-0xd4006d,
-0x8001db,
-0xd4006e,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0x7d9103,
-0x7dd583,
-0x7d190c,
-0x35cc1f,
-0x35701f,
-0x7cf0cb,
-0x7cd08b,
-0x880000,
-0x7e8e8b,
-0x95c004,
-0xd4006e,
-0x8001db,
-0xd4001a,
-0xd4c01a,
-0xcc0803,
-0xcc0c03,
-0xcc1003,
-0xcc1403,
-0xcc1803,
-0xcc1c03,
-0xcc2403,
-0xcc2803,
-0x35c41f,
-0x36b01f,
-0x7c704b,
-0x34f01f,
-0x7c704b,
-0x35701f,
-0x7c704b,
-0x7d8881,
-0x7dccc1,
-0x7e5101,
-0x7e9541,
-0x7c9082,
-0x7cd4c2,
-0x7c848b,
-0x9ac003,
-0x7c8c8b,
-0x2c8801,
-0x98809e,
-0xd4006d,
-0x98409c,
-0xd4006e,
-0xcc084c,
-0xcc0c4d,
-0xcc1048,
-0xd4801a,
-0xd4c01a,
-0x800124,
-0xd5001a,
-0xcc0832,
-0xd40032,
-0x9482b6,
-0xca0c00,
-0xd4401e,
-0x800000,
-0xd4001e,
-0xe4011e,
-0xd4001e,
-0xca0800,
-0xca0c00,
-0xca1000,
-0xd4401e,
-0xca1400,
-0xd4801e,
-0xd4c01e,
-0xd5001e,
-0xd5401e,
-0xd54034,
-0x800000,
-0xee001e,
-0x280404,
-0xe2001a,
-0xe2001a,
-0xd4401a,
-0xca3800,
-0xcc0803,
-0xcc0c03,
-0xcc0c03,
-0xcc0c03,
-0x98829a,
-0x000000,
-0x8401de,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0400,
-0xc2ff00,
-0xcc0834,
-0xc13fff,
-0x7c74cb,
-0x7cc90b,
-0x7d010f,
-0x99028d,
-0x7c738b,
-0x8401de,
-0xd7a06f,
-0x800000,
-0xee001f,
-0xca0800,
-0x281900,
-0x7d898b,
-0x958014,
-0x281404,
-0xca0c00,
-0xca1000,
-0xca1c00,
-0xca2400,
-0xe2001f,
-0xd4c01a,
-0xd5001a,
-0xd5401a,
-0xcc1803,
-0xcc2c03,
-0xcc2c03,
-0xcc2c03,
-0x7da58b,
-0x7d9c47,
-0x984274,
-0x000000,
-0x800184,
-0xd4c01a,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xe4013e,
-0xd4001e,
-0xd4401e,
-0xee001e,
-0xca0400,
-0xa00000,
-0x7e828b,
-0xca0800,
-0x248c06,
-0x0ccc06,
-0x98c006,
-0xcc104e,
-0x990004,
-0xd40073,
-0xe4011e,
-0xd4001e,
-0xd4401e,
-0xd4801e,
-0x800000,
-0xee001e,
-0xca0800,
-0xca0c00,
-0x34d018,
-0x251001,
-0x950021,
-0xc17fff,
-0xca1000,
-0xca1400,
-0xca1800,
-0xd4801d,
-0xd4c01d,
-0x7db18b,
-0xc14202,
-0xc2c001,
-0xd5801d,
-0x34dc0e,
-0x7d5d4c,
-0x7f734c,
-0xd7401e,
-0xd5001e,
-0xd5401e,
-0xc14200,
-0xc2c000,
-0x099c01,
-0x31dc10,
-0x7f5f4c,
-0x7f734c,
-0x042802,
-0x7d8380,
-0xd5a86f,
-0xd58066,
-0xd7401e,
-0xec005e,
-0xc82402,
-0xc82402,
-0x8001db,
-0xd60076,
-0xd4401e,
-0xd4801e,
-0xd4c01e,
-0x800000,
-0xee001e,
-0x800000,
-0xee001f,
-0xd4001f,
-0x800000,
-0xd4001f,
-0xd4001f,
-0x880000,
-0xd4001f,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x000000,
-0x010194,
-0x02019b,
-0x0300b2,
-0x0400a2,
-0x050003,
-0x06003f,
-0x070032,
-0x08014f,
-0x090046,
-0x0a0036,
-0x1001d9,
-0x1700c5,
-0x22015d,
-0x23016c,
-0x2000d7,
-0x240148,
-0x26004d,
-0x27005c,
-0x28008d,
-0x290051,
-0x2a007e,
-0x2b0061,
-0x2f0088,
-0x3200aa,
-0x3401a2,
-0x36006f,
-0x3c0179,
-0x3f0095,
-0x4101af,
-0x440151,
-0x550196,
-0x56019d,
-0x60000b,
-0x610034,
-0x620038,
-0x630038,
-0x640038,
-0x650038,
-0x660038,
-0x670038,
-0x68003a,
-0x690041,
-0x6a0048,
-0x6b0048,
-0x6c0048,
-0x6d0048,
-0x6e0048,
-0x6f0048,
-0x7301d9,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-0x000006,
-};
-
-static const u32 RV770_cp_microcode[] = {
-0xcc0003ea,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x80000001,
-0xd040007f,
-0x80000001,
-0xcc400041,
-0x7c40c000,
-0xc0160004,
-0x30d03fff,
-0x7d15000c,
-0xcc110000,
-0x28d8001e,
-0x31980001,
-0x28dc001f,
-0xc8200004,
-0x95c00006,
-0x7c424000,
-0xcc000062,
-0x7e56800c,
-0xcc290000,
-0xc8240004,
-0x7e26000b,
-0x95800006,
-0x7c42c000,
-0xcc000062,
-0x7ed7000c,
-0xcc310000,
-0xc82c0004,
-0x7e2e000c,
-0xcc000062,
-0x31103fff,
-0x80000001,
-0xce110000,
-0x7c40c000,
-0x80000001,
-0xcc400040,
-0x80000001,
-0xcc412257,
-0x7c418000,
-0xcc400045,
-0xcc400048,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xcc400045,
-0xcc400048,
-0x7c40c000,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xcc000045,
-0xcc000048,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x040ca1fd,
-0xc0120001,
-0xcc000045,
-0xcc000048,
-0x7cd0c00c,
-0xcc41225c,
-0xcc41a1fc,
-0xd04d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x80000001,
-0xcc41225d,
-0x7c408000,
-0x7c40c000,
-0xc02a0002,
-0x7c410000,
-0x7d29000c,
-0x30940001,
-0x30980006,
-0x309c0300,
-0x29dc0008,
-0x7c420000,
-0x7c424000,
-0x9540000f,
-0xc02e0004,
-0x05f02258,
-0x7f2f000c,
-0xcc310000,
-0xc8280004,
-0xccc12169,
-0xcd01216a,
-0xce81216b,
-0x0db40002,
-0xcc01216c,
-0x9740000e,
-0x0db40000,
-0x8000007b,
-0xc834000a,
-0x0db40002,
-0x97400009,
-0x0db40000,
-0xc02e0004,
-0x05f02258,
-0x7f2f000c,
-0xcc310000,
-0xc8280004,
-0x8000007b,
-0xc834000a,
-0x97400004,
-0x7e028000,
-0x8000007b,
-0xc834000a,
-0x0db40004,
-0x9740ff8c,
-0x00000000,
-0xce01216d,
-0xce41216e,
-0xc8280003,
-0xc834000a,
-0x9b400004,
-0x043c0005,
-0x8400026d,
-0xcc000062,
-0x0df40000,
-0x9740000b,
-0xc82c03e6,
-0xce81a2b7,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c4,
-0x80000001,
-0xcfc1a2d1,
-0x0df40001,
-0x9740000b,
-0xc82c03e7,
-0xce81a2bb,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c5,
-0x80000001,
-0xcfc1a2d2,
-0x0df40002,
-0x9740000b,
-0xc82c03e8,
-0xce81a2bf,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c6,
-0x80000001,
-0xcfc1a2d3,
-0xc82c03e9,
-0xce81a2c3,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c7,
-0x80000001,
-0xcfc1a2d4,
-0x80000001,
-0xcc400042,
-0x7c40c000,
-0x7c410000,
-0x2914001d,
-0x31540001,
-0x9940000d,
-0x31181000,
-0xc81c0011,
-0x09dc0001,
-0x95c0ffff,
-0xc81c0011,
-0xccc12100,
-0xcd012101,
-0xccc12102,
-0xcd012103,
-0x04180004,
-0x8000039f,
-0xcd81a2a4,
-0xc02a0004,
-0x95800008,
-0x36a821a3,
-0xcc290000,
-0xc8280004,
-0xc81c0011,
-0x0de40040,
-0x9640ffff,
-0xc81c0011,
-0xccc12170,
-0xcd012171,
-0xc8200012,
-0x96000000,
-0xc8200012,
-0x8000039f,
-0xcc000064,
-0x7c40c000,
-0x7c410000,
-0xcc000045,
-0xcc000048,
-0x40d40003,
-0xcd41225c,
-0xcd01a1fc,
-0xc01a0001,
-0x041ca1fd,
-0x7dd9c00c,
-0x7c420000,
-0x08cc0001,
-0x06240001,
-0x06280002,
-0xce1d0000,
-0xce5d0000,
-0x98c0fffa,
-0xce9d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x7c40c000,
-0x30d00001,
-0x28cc0001,
-0x7c414000,
-0x95000006,
-0x7c418000,
-0xcd41216d,
-0xcd81216e,
-0x800000f3,
-0xc81c0003,
-0xc0220004,
-0x7e16000c,
-0xcc210000,
-0xc81c0004,
-0x7c424000,
-0x98c00004,
-0x7c428000,
-0x80000001,
-0xcde50000,
-0xce412169,
-0xce81216a,
-0xcdc1216b,
-0x80000001,
-0xcc01216c,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0x7c41c000,
-0x28a40008,
-0x326400ff,
-0x0e68003c,
-0x9680000a,
-0x7c020000,
-0x7c420000,
-0x1e300003,
-0xcc00006a,
-0x9b000003,
-0x42200005,
-0x04200040,
-0x80000110,
-0x7c024000,
-0x7e024000,
-0x9a400000,
-0x0a640001,
-0x30ec0010,
-0x9ac0000a,
-0xcc000062,
-0xc02a0004,
-0xc82c0021,
-0x7e92800c,
-0xcc000041,
-0xcc290000,
-0xcec00021,
-0x80000120,
-0xc8300004,
-0xcd01216d,
-0xcd41216e,
-0xc8300003,
-0x7f1f000b,
-0x30f40007,
-0x27780001,
-0x9740002a,
-0x07b80125,
-0x9f800000,
-0x00000000,
-0x80000135,
-0x7f1b8004,
-0x80000139,
-0x7f1b8005,
-0x8000013d,
-0x7f1b8002,
-0x80000141,
-0x7f1b8003,
-0x80000145,
-0x7f1b8007,
-0x80000149,
-0x7f1b8006,
-0x8000014e,
-0x28a40008,
-0x9b800019,
-0x28a40008,
-0x8000015e,
-0x326400ff,
-0x9b800015,
-0x28a40008,
-0x8000015e,
-0x326400ff,
-0x9b800011,
-0x28a40008,
-0x8000015e,
-0x326400ff,
-0x9b80000d,
-0x28a40008,
-0x8000015e,
-0x326400ff,
-0x9b800009,
-0x28a40008,
-0x8000015e,
-0x326400ff,
-0x9b800005,
-0x28a40008,
-0x8000015e,
-0x326400ff,
-0x28a40008,
-0x326400ff,
-0x0e68003c,
-0x9a80feb1,
-0x28ec0008,
-0x7c434000,
-0x7c438000,
-0x7c43c000,
-0x96c00007,
-0xcc000062,
-0xcf412169,
-0xcf81216a,
-0xcfc1216b,
-0x80000001,
-0xcc01216c,
-0x80000001,
-0xcff50000,
-0xcc00006b,
-0x840003a2,
-0x0e68003c,
-0x9a800004,
-0xc8280015,
-0x80000001,
-0xd040007f,
-0x9680ffab,
-0x7e024000,
-0x8400023b,
-0xc00e0002,
-0xcc000041,
-0x80000239,
-0xccc1304a,
-0x7c40c000,
-0x7c410000,
-0xc01e0001,
-0x29240012,
-0xc0220002,
-0x96400005,
-0xc0260004,
-0xc027fffb,
-0x7d25000b,
-0xc0260000,
-0x7dd2800b,
-0x7e12c00b,
-0x7d25000c,
-0x7c414000,
-0x7c418000,
-0xccc12169,
-0x9a80000a,
-0xcd01216a,
-0xcd41216b,
-0x96c0fe82,
-0xcd81216c,
-0xc8300018,
-0x97000000,
-0xc8300018,
-0x80000001,
-0xcc000018,
-0x840003a2,
-0xcc00007f,
-0xc8140013,
-0xc8180014,
-0xcd41216b,
-0x96c0fe76,
-0xcd81216c,
-0x80000182,
-0xc8300018,
-0xc80c0008,
-0x98c00000,
-0xc80c0008,
-0x7c410000,
-0x95000002,
-0x00000000,
-0x7c414000,
-0xc8200009,
-0xcc400043,
-0xce01a1f4,
-0xcc400044,
-0xc00e8000,
-0x7c424000,
-0x7c428000,
-0x2aac001f,
-0x96c0fe63,
-0xc035f000,
-0xce4003e2,
-0x32780003,
-0x267c0008,
-0x7ff7c00b,
-0x7ffbc00c,
-0x2a780018,
-0xcfc003e3,
-0xcf8003e4,
-0x26b00002,
-0x7f3f0000,
-0xcf0003e5,
-0x8000031f,
-0x7c80c000,
-0x7c40c000,
-0x28d00008,
-0x3110000f,
-0x9500000f,
-0x25280001,
-0x06a801b3,
-0x9e800000,
-0x00000000,
-0x800001d4,
-0xc0120800,
-0x800001e2,
-0xc814000f,
-0x800001e9,
-0xc8140010,
-0x800001f0,
-0xccc1a2a4,
-0x800001f9,
-0xc8140011,
-0x30d0003f,
-0x0d280015,
-0x9a800012,
-0x0d28001e,
-0x9a80001e,
-0x0d280020,
-0x9a800023,
-0x0d24000f,
-0x0d280010,
-0x7e6a800c,
-0x9a800026,
-0x0d200004,
-0x0d240014,
-0x0d280028,
-0x7e62400c,
-0x7ea6800c,
-0x9a80002a,
-0xc8140011,
-0x80000001,
-0xccc1a2a4,
-0xc0120800,
-0x7c414000,
-0x7d0cc00c,
-0xc0120008,
-0x29580003,
-0x295c000c,
-0x7c420000,
-0x7dd1c00b,
-0x26200014,
-0x7e1e400c,
-0x7e4e800c,
-0xce81a2a4,
-0x80000001,
-0xcd81a1fe,
-0xc814000f,
-0x0410210e,
-0x95400000,
-0xc814000f,
-0xd0510000,
-0x80000001,
-0xccc1a2a4,
-0xc8140010,
-0x04102108,
-0x95400000,
-0xc8140010,
-0xd0510000,
-0x80000001,
-0xccc1a2a4,
-0xccc1a2a4,
-0x04100001,
-0xcd000019,
-0x840003a2,
-0xcc00007f,
-0xc8100019,
-0x99000000,
-0xc8100019,
-0x80000002,
-0x7c408000,
-0x04102100,
-0x09540001,
-0x9540ffff,
-0xc8140011,
-0xd0510000,
-0x8000039f,
-0xccc1a2a4,
-0x7c40c000,
-0xcc40000d,
-0x94c0fdff,
-0xcc40000e,
-0x7c410000,
-0x95000005,
-0x08cc0001,
-0xc8140005,
-0x99400014,
-0x00000000,
-0x98c0fffb,
-0x7c410000,
-0x80000002,
-0x7d008000,
-0xc8140005,
-0x7c40c000,
-0x9940000c,
-0xc818000c,
-0x7c410000,
-0x9580fdee,
-0xc820000e,
-0xc81c000d,
-0x66200020,
-0x7e1e002c,
-0x25240002,
-0x7e624020,
-0x80000001,
-0xcce60000,
-0x7c410000,
-0xcc00006c,
-0xcc00006d,
-0xc818001f,
-0xc81c001e,
-0x65980020,
-0x7dd9c02c,
-0x7cd4c00c,
-0xccde0000,
-0x45dc0004,
-0xc8280017,
-0x9680000f,
-0xc00e0001,
-0x28680008,
-0x2aac0016,
-0x32a800ff,
-0x0eb00049,
-0x7f2f000b,
-0x97000006,
-0x00000000,
-0xc8140005,
-0x7c40c000,
-0x80000223,
-0x7c410000,
-0x80000226,
-0xd040007f,
-0x8400023b,
-0xcc000041,
-0xccc1304a,
-0x94000000,
-0xc83c001a,
-0x043c0005,
-0xcfc1a2a4,
-0xc0361f90,
-0xc0387fff,
-0x7c03c010,
-0x7f7b400c,
-0xcf41217c,
-0xcfc1217d,
-0xcc01217e,
-0xc03a0004,
-0x0434217f,
-0x7f7b400c,
-0xcc350000,
-0xc83c0004,
-0x2bfc001f,
-0x04380020,
-0x97c00005,
-0xcc000062,
-0x9b800000,
-0x0bb80001,
-0x80000247,
-0xcc000071,
-0xcc01a1f4,
-0x04380016,
-0xc0360002,
-0xcf81a2a4,
-0x88000000,
-0xcf412010,
-0x7c40c000,
-0x28d0001c,
-0x95000005,
-0x04d40001,
-0xcd400065,
-0x80000001,
-0xcd400068,
-0x09540002,
-0x80000001,
-0xcd400066,
-0x8400026c,
-0xc81803ea,
-0x7c40c000,
-0x9980fd9d,
-0xc8140016,
-0x08d00001,
-0x9940002b,
-0xcd000068,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x043c0005,
-0xcfc1a2a4,
-0xcc01a1f4,
-0x840003a2,
-0xcc000046,
-0x88000000,
-0xcc00007f,
-0x8400027e,
-0xc81803ea,
-0x7c40c000,
-0x9980fd8b,
-0xc8140016,
-0x08d00001,
-0x99400019,
-0xcd000068,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x043c0022,
-0xcfc1a2a4,
-0x840003a2,
-0xcc000047,
-0x88000000,
-0xcc00007f,
-0xc8100016,
-0x9900000d,
-0xcc400067,
-0x80000002,
-0x7c408000,
-0xc81803ea,
-0x9980fd77,
-0x7c40c000,
-0x94c00003,
-0xc8100016,
-0x99000004,
-0xccc00068,
-0x80000002,
-0x7c408000,
-0x8400023b,
-0xc0148000,
-0xcc000041,
-0xcd41304a,
-0xc0148000,
-0x99000000,
-0xc8100016,
-0x80000002,
-0x7c408000,
-0xc0120001,
-0x7c51400c,
-0x80000001,
-0xd0550000,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0x291c001f,
-0xccc0004a,
-0xcd00004b,
-0x95c00003,
-0xc01c8000,
-0xcdc12010,
-0xdd830000,
-0x055c2000,
-0xcc000062,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc0004c,
-0xcd00004d,
-0xdd830000,
-0x055ca000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc0004e,
-0xcd00004f,
-0xdd830000,
-0x055cc000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00050,
-0xcd000051,
-0xdd830000,
-0x055cf8e0,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00052,
-0xcd000053,
-0xdd830000,
-0x055cf880,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00054,
-0xcd000055,
-0xdd830000,
-0x055ce000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00056,
-0xcd000057,
-0xdd830000,
-0x055cf000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00058,
-0xcd000059,
-0xdd830000,
-0x055cf3fc,
-0x80000001,
-0xd81f4100,
-0xd0432000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043a000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043c000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f8e0,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f880,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043e000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f3fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xc81403e0,
-0xcc430000,
-0xcc430000,
-0xcc430000,
-0x7d45c000,
-0xcdc30000,
-0xd0430000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x7c40c000,
-0xc81003e2,
-0xc81403e5,
-0xc81803e3,
-0xc81c03e4,
-0xcd812169,
-0xcdc1216a,
-0xccc1216b,
-0xcc01216c,
-0x04200004,
-0x7da18000,
-0x7d964002,
-0x9640fcd7,
-0xcd8003e3,
-0x31280003,
-0xc02df000,
-0x25180008,
-0x7dad800b,
-0x7da9800c,
-0x80000001,
-0xcd8003e3,
-0x308cffff,
-0xd04d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x7c40c000,
-0x7c410000,
-0x29240018,
-0x32640001,
-0x9a400013,
-0xc8140020,
-0x15580002,
-0x9580ffff,
-0xc8140020,
-0xcc00006e,
-0xccc12180,
-0xcd01218d,
-0xcc412181,
-0x2914001f,
-0x34588000,
-0xcd81218c,
-0x9540fcb9,
-0xcc412182,
-0xc8140020,
-0x9940ffff,
-0xc8140020,
-0x80000002,
-0x7c408000,
-0x7c414000,
-0x7c418000,
-0x7c41c000,
-0x65b40020,
-0x7f57402c,
-0xd4378100,
-0x47740004,
-0xd4378100,
-0x47740004,
-0xd4378100,
-0x47740004,
-0x09dc0004,
-0xd4378100,
-0x99c0fff8,
-0x47740004,
-0x2924001f,
-0xc0380019,
-0x9640fca1,
-0xc03e0004,
-0xcf8121f8,
-0x37e021f9,
-0xcc210000,
-0xc8200004,
-0x2a200018,
-0x32200001,
-0x9a00fffb,
-0xcf8121f8,
-0x80000002,
-0x7c408000,
-0x7c40c000,
-0x28d00018,
-0x31100001,
-0xc0160080,
-0x95000003,
-0xc02a0004,
-0x7cd4c00c,
-0xccc1217c,
-0xcc41217d,
-0xcc41217e,
-0x7c418000,
-0x1db00003,
-0x36a0217f,
-0x9b000003,
-0x419c0005,
-0x041c0040,
-0x99c00000,
-0x09dc0001,
-0xcc210000,
-0xc8240004,
-0x2a6c001f,
-0x419c0005,
-0x9ac0fffa,
-0xcc800062,
-0x80000002,
-0x7c408000,
-0x7c40c000,
-0x04d403e6,
-0x80000001,
-0xcc540000,
-0x8000039f,
-0xcc4003ea,
-0xc01c8000,
-0x044ca000,
-0xcdc12010,
-0x7c410000,
-0xc8140009,
-0x04180000,
-0x041c0008,
-0xcd800071,
-0x09dc0001,
-0x05980001,
-0xcd0d0000,
-0x99c0fffc,
-0xcc800062,
-0x8000039f,
-0xcd400071,
-0xc00e0100,
-0xcc000041,
-0xccc1304a,
-0xc83c007f,
-0xcc00007f,
-0x80000001,
-0xcc00007f,
-0xcc00007f,
-0x88000000,
-0xcc00007f,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00010333,
-0x00100004,
-0x00170006,
-0x00210008,
-0x00270028,
-0x00280023,
-0x00290029,
-0x002a0026,
-0x002b0029,
-0x002d0038,
-0x002e003f,
-0x002f004a,
-0x0034004c,
-0x00360030,
-0x003900af,
-0x003a00d0,
-0x003b00e5,
-0x003c00fd,
-0x003d016c,
-0x003f00ad,
-0x00410338,
-0x0043036c,
-0x0044018f,
-0x004500fd,
-0x004601ad,
-0x004701ad,
-0x00480200,
-0x0049020e,
-0x004a0257,
-0x004b0284,
-0x00520261,
-0x00530273,
-0x00540289,
-0x0057029b,
-0x0060029f,
-0x006102ae,
-0x006202b8,
-0x006302c2,
-0x006402cc,
-0x006502d6,
-0x006602e0,
-0x006702ea,
-0x006802f4,
-0x006902f8,
-0x006a02fc,
-0x006b0300,
-0x006c0304,
-0x006d0308,
-0x006e030c,
-0x006f0310,
-0x00700314,
-0x00720386,
-0x0074038c,
-0x0079038a,
-0x007c031e,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-0x000f039b,
-};
-
-static const u32 RV770_pfp_microcode[] = {
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x80000000,
-0xdc030000,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xc818000e,
-0x31980001,
-0x7c424000,
-0x95800252,
-0x7c428000,
-0xc81c001c,
-0xc037c000,
-0x7c40c000,
-0x7c410000,
-0x7cb4800b,
-0xc0360003,
-0x99c00000,
-0xc81c001c,
-0x7cb4800c,
-0x24d40002,
-0x7d654000,
-0xcd400043,
-0xce800043,
-0xcd000043,
-0xcc800040,
-0xce400040,
-0xce800040,
-0xccc00040,
-0xdc3a0000,
-0x9780ffde,
-0xcd000040,
-0x7c40c000,
-0x80000018,
-0x7c410000,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xc818000e,
-0x8000000c,
-0x31980002,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xc818000e,
-0x288c0008,
-0x30cc000f,
-0x34100001,
-0x7d0d0008,
-0x8000000c,
-0x7d91800b,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xcc4003f9,
-0x80000261,
-0xcc4003f8,
-0xc82003f8,
-0xc81c03f9,
-0xc81803fb,
-0xc037ffff,
-0x7c414000,
-0xcf41a29e,
-0x66200020,
-0x7de1c02c,
-0x7d58c008,
-0x7cdcc020,
-0x68d00020,
-0xc0360003,
-0xcc000054,
-0x7cb4800c,
-0x8000006a,
-0xcc800040,
-0x7c418000,
-0xcd81a29e,
-0xcc800040,
-0xcd800040,
-0x80000068,
-0xcc000054,
-0xc019ffff,
-0xcc800040,
-0xcd81a29e,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0xccc1a1fa,
-0xcd01a1f9,
-0xcd41a29d,
-0xccc00040,
-0xcd000040,
-0xcd400040,
-0xcc400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xcc000054,
-0xcc800040,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0xccc1a1fa,
-0xcd01a1f9,
-0xcd41a29d,
-0xccc00040,
-0xcd000040,
-0xcd400040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x7c40c000,
-0x30d00001,
-0xccc1a29f,
-0x95000003,
-0x04140001,
-0x04140002,
-0xcd4003fb,
-0xcc800040,
-0x80000000,
-0xccc00040,
-0x7c40c000,
-0xcc800040,
-0xccc1a2a2,
-0x80000000,
-0xccc00040,
-0x7c40c000,
-0x28d4001f,
-0xcc800040,
-0x95400003,
-0x7c410000,
-0xccc00057,
-0x2918001f,
-0xccc00040,
-0x95800003,
-0xcd000040,
-0xcd000058,
-0x80000261,
-0xcc00007f,
-0xc8200017,
-0xc8300022,
-0x9a000006,
-0x0e280001,
-0xc824001e,
-0x0a640001,
-0xd4001240,
-0xce400040,
-0xc036c000,
-0x96800007,
-0x37747900,
-0x041c0001,
-0xcf400040,
-0xcdc00040,
-0xcf0003fa,
-0x7c030000,
-0xca0c0010,
-0x7c410000,
-0x94c00004,
-0x7c414000,
-0xd42002c4,
-0xcde00044,
-0x9b00000b,
-0x7c418000,
-0xcc00004b,
-0xcda00049,
-0xcd200041,
-0xcd600041,
-0xcda00041,
-0x06200001,
-0xce000056,
-0x80000261,
-0xcc00007f,
-0xc8280020,
-0xc82c0021,
-0xcc000063,
-0x7eea4001,
-0x65740020,
-0x7f53402c,
-0x269c0002,
-0x7df5c020,
-0x69f80020,
-0xce80004b,
-0xce600049,
-0xcde00041,
-0xcfa00041,
-0xce600041,
-0x271c0002,
-0x7df5c020,
-0x69f80020,
-0x7db24001,
-0xcf00004b,
-0xce600049,
-0xcde00041,
-0xcfa00041,
-0x800000bd,
-0xce600041,
-0xc8200017,
-0xc8300022,
-0x9a000006,
-0x0e280001,
-0xc824001e,
-0x0a640001,
-0xd4001240,
-0xce400040,
-0xca0c0010,
-0x7c410000,
-0x94c0000b,
-0xc036c000,
-0x96800007,
-0x37747900,
-0x041c0001,
-0xcf400040,
-0xcdc00040,
-0xcf0003fa,
-0x7c030000,
-0x800000b6,
-0x7c414000,
-0xcc000048,
-0x800000ef,
-0x00000000,
-0xc8200017,
-0xc81c0023,
-0x0e240002,
-0x99c00015,
-0x7c418000,
-0x0a200001,
-0xce000056,
-0xd4000440,
-0xcc000040,
-0xc036c000,
-0xca140013,
-0x96400007,
-0x37747900,
-0xcf400040,
-0xcc000040,
-0xc83003fa,
-0x80000104,
-0xcf000022,
-0xcc000022,
-0x9540015d,
-0xcc00007f,
-0xcca00046,
-0x80000000,
-0xcc200046,
-0x80000261,
-0xcc000064,
-0xc8200017,
-0xc810001f,
-0x96000005,
-0x09100001,
-0xd4000440,
-0xcd000040,
-0xcd000022,
-0xcc800040,
-0xd0400040,
-0xc80c0025,
-0x94c0feeb,
-0xc8100008,
-0xcd000040,
-0xd4000fc0,
-0x80000000,
-0xd4000fa2,
-0x7c40c000,
-0x7c410000,
-0xccc003fd,
-0xcd0003fc,
-0xccc00042,
-0xcd000042,
-0x2914001f,
-0x29180010,
-0x31980007,
-0x3b5c0001,
-0x7d76000b,
-0x99800005,
-0x7d5e400b,
-0xcc000042,
-0x80000261,
-0xcc00004d,
-0x29980001,
-0x292c0008,
-0x9980003d,
-0x32ec0001,
-0x96000004,
-0x2930000c,
-0x80000261,
-0xcc000042,
-0x04140010,
-0xcd400042,
-0x33300001,
-0x34280001,
-0x8400015e,
-0xc8140003,
-0x9b40001b,
-0x0438000c,
-0x8400015e,
-0xc8140003,
-0x9b400017,
-0x04380008,
-0x8400015e,
-0xc8140003,
-0x9b400013,
-0x04380004,
-0x8400015e,
-0xc8140003,
-0x9b400015,
-0xc80c03fd,
-0x9a800009,
-0xc81003fc,
-0x9b000118,
-0xcc00004d,
-0x04140010,
-0xccc00042,
-0xcd000042,
-0x80000136,
-0xcd400042,
-0x96c00111,
-0xcc00004d,
-0x80000261,
-0xcc00004e,
-0x9ac00003,
-0xcc00004d,
-0xcc00004e,
-0xdf830000,
-0x80000000,
-0xd80301ff,
-0x9ac00107,
-0xcc00004d,
-0x80000261,
-0xcc00004e,
-0xc8180003,
-0xc81c0003,
-0xc8200003,
-0x7d5d4003,
-0x7da1c003,
-0x7d5d400c,
-0x2a10001f,
-0x299c001f,
-0x7d1d000b,
-0x7d17400b,
-0x88000000,
-0x7e92800b,
-0x96400004,
-0xcc00004e,
-0x80000261,
-0xcc000042,
-0x04380008,
-0xcf800042,
-0xc8080003,
-0xc80c0003,
-0xc8100003,
-0xc8140003,
-0xc8180003,
-0xc81c0003,
-0xc8240003,
-0xc8280003,
-0x29fc001f,
-0x2ab0001f,
-0x7ff3c00b,
-0x28f0001f,
-0x7ff3c00b,
-0x2970001f,
-0x7ff3c00b,
-0x7d888001,
-0x7dccc001,
-0x7e510001,
-0x7e954001,
-0x7c908002,
-0x7cd4c002,
-0x7cbc800b,
-0x9ac00003,
-0x7c8f400b,
-0x38b40001,
-0x9b4000d8,
-0xcc00004d,
-0x9bc000d6,
-0xcc00004e,
-0xc80c03fd,
-0xc81003fc,
-0xccc00042,
-0x8000016f,
-0xcd000042,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xcc400040,
-0xcc400040,
-0xcc400040,
-0x7c40c000,
-0xccc00040,
-0xccc0000d,
-0x80000000,
-0xd0400040,
-0x7c40c000,
-0x7c410000,
-0x65140020,
-0x7d4d402c,
-0x24580002,
-0x7d598020,
-0x7c41c000,
-0xcd800042,
-0x69980020,
-0xcd800042,
-0xcdc00042,
-0xc023c000,
-0x05e40002,
-0x7ca0800b,
-0x26640010,
-0x7ca4800c,
-0xcc800040,
-0xcdc00040,
-0xccc00040,
-0x95c0000e,
-0xcd000040,
-0x09dc0001,
-0xc8280003,
-0x96800008,
-0xce800040,
-0xc834001d,
-0x97400000,
-0xc834001d,
-0x26a80008,
-0x84000264,
-0xcc2b0000,
-0x99c0fff7,
-0x09dc0001,
-0xdc3a0000,
-0x97800004,
-0x7c418000,
-0x800001a3,
-0x25980002,
-0xa0000000,
-0x7d808000,
-0xc818001d,
-0x7c40c000,
-0x64d00008,
-0x95800000,
-0xc818001d,
-0xcc130000,
-0xcc800040,
-0xccc00040,
-0x80000000,
-0xcc400040,
-0xc810001f,
-0x7c40c000,
-0xcc800040,
-0x7cd1400c,
-0xcd400040,
-0x05180001,
-0x80000000,
-0xcd800022,
-0x7c40c000,
-0x64500020,
-0x84000264,
-0xcc000061,
-0x7cd0c02c,
-0xc8200017,
-0xc8d60000,
-0x99400008,
-0x7c438000,
-0xdf830000,
-0xcfa0004f,
-0x84000264,
-0xcc000062,
-0x80000000,
-0xd040007f,
-0x80000261,
-0xcc000062,
-0x84000264,
-0xcc000061,
-0xc8200017,
-0x7c40c000,
-0xc036ff00,
-0xc810000d,
-0xc0303fff,
-0x7cf5400b,
-0x7d51800b,
-0x7d81800f,
-0x99800008,
-0x7cf3800b,
-0xdf830000,
-0xcfa0004f,
-0x84000264,
-0xcc000062,
-0x80000000,
-0xd040007f,
-0x80000261,
-0xcc000062,
-0x84000264,
-0x7c40c000,
-0x28dc0008,
-0x95c00019,
-0x30dc0010,
-0x7c410000,
-0x99c00004,
-0x64540020,
-0x80000209,
-0xc91d0000,
-0x7d15002c,
-0xc91e0000,
-0x7c420000,
-0x7c424000,
-0x7c418000,
-0x7de5c00b,
-0x7de28007,
-0x9a80000e,
-0x41ac0005,
-0x9ac00000,
-0x0aec0001,
-0x30dc0010,
-0x99c00004,
-0x00000000,
-0x8000020c,
-0xc91d0000,
-0x8000020c,
-0xc91e0000,
-0xcc800040,
-0xccc00040,
-0xd0400040,
-0xc80c0025,
-0x94c0fde3,
-0xc8100008,
-0xcd000040,
-0xd4000fc0,
-0x80000000,
-0xd4000fa2,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x7c40c000,
-0x30d00006,
-0x0d100006,
-0x99000007,
-0xc8140015,
-0x99400005,
-0xcc000052,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xccc00040,
-0x80000000,
-0xd0400040,
-0x7c40c000,
-0xcc4d0000,
-0xdc3a0000,
-0x9780fdbc,
-0x04cc0001,
-0x80000243,
-0xcc4d0000,
-0x7c40c000,
-0x7c410000,
-0x29240018,
-0x32640001,
-0x9640000f,
-0xcc800040,
-0x7c414000,
-0x7c418000,
-0x7c41c000,
-0xccc00043,
-0xcd000043,
-0x31dc7fff,
-0xcdc00043,
-0xccc00040,
-0xcd000040,
-0xcd400040,
-0xcd800040,
-0x80000000,
-0xcdc00040,
-0xccc00040,
-0xcd000040,
-0x80000000,
-0xd0400040,
-0x80000000,
-0xd040007f,
-0xcc00007f,
-0x80000000,
-0xcc00007f,
-0xcc00007f,
-0x88000000,
-0xcc00007f,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00030223,
-0x0004022b,
-0x000500a0,
-0x00020003,
-0x0006003c,
-0x00070027,
-0x00080192,
-0x00090044,
-0x000a002d,
-0x0010025f,
-0x001700f1,
-0x002201d8,
-0x002301e9,
-0x0026004c,
-0x0027005f,
-0x0020011b,
-0x00280093,
-0x0029004f,
-0x002a0084,
-0x002b0065,
-0x002f008e,
-0x003200d9,
-0x00340233,
-0x00360075,
-0x0039010b,
-0x003c01fd,
-0x003f00a0,
-0x00410248,
-0x00440195,
-0x0048019e,
-0x004901c6,
-0x004a01d0,
-0x00550226,
-0x0056022e,
-0x0060000a,
-0x0061002a,
-0x00620030,
-0x00630030,
-0x00640030,
-0x00650030,
-0x00660030,
-0x00670030,
-0x00680037,
-0x0069003f,
-0x006a0047,
-0x006b0047,
-0x006c0047,
-0x006d0047,
-0x006e0047,
-0x006f0047,
-0x00700047,
-0x0073025f,
-0x007b0241,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-};
-
-static const u32 RV730_pfp_microcode[] = {
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x80000000,
-0xdc030000,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xc818000e,
-0x31980001,
-0x7c424000,
-0x9580023a,
-0x7c428000,
-0xc81c001c,
-0xc037c000,
-0x7c40c000,
-0x7c410000,
-0x7cb4800b,
-0xc0360003,
-0x99c00000,
-0xc81c001c,
-0x7cb4800c,
-0x24d40002,
-0x7d654000,
-0xcd400043,
-0xce800043,
-0xcd000043,
-0xcc800040,
-0xce400040,
-0xce800040,
-0xccc00040,
-0xdc3a0000,
-0x9780ffde,
-0xcd000040,
-0x7c40c000,
-0x80000018,
-0x7c410000,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xc818000e,
-0x8000000c,
-0x31980002,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xc818000e,
-0x288c0008,
-0x30cc000f,
-0x34100001,
-0x7d0d0008,
-0x8000000c,
-0x7d91800b,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xcc4003f9,
-0x80000249,
-0xcc4003f8,
-0xc037ffff,
-0x7c414000,
-0xcf41a29e,
-0xc82003f8,
-0xc81c03f9,
-0x66200020,
-0xc81803fb,
-0x7de1c02c,
-0x7d58c008,
-0x7cdcc020,
-0x69100020,
-0xc0360003,
-0xcc000054,
-0x7cb4800c,
-0x80000069,
-0xcc800040,
-0x7c418000,
-0xcd81a29e,
-0xcc800040,
-0x80000067,
-0xcd800040,
-0xc019ffff,
-0xcc800040,
-0xcd81a29e,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0xccc1a1fa,
-0xcd01a1f9,
-0xcd41a29d,
-0xccc00040,
-0xcd000040,
-0xcd400040,
-0xcc400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xcc000054,
-0xcc800040,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0xccc1a1fa,
-0xcd01a1f9,
-0xcd41a29d,
-0xccc00040,
-0xcd000040,
-0xcd400040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x7c40c000,
-0x30d00001,
-0xccc1a29f,
-0x95000003,
-0x04140001,
-0x04140002,
-0xcd4003fb,
-0xcc800040,
-0x80000000,
-0xccc00040,
-0x7c40c000,
-0xcc800040,
-0xccc1a2a2,
-0x80000000,
-0xccc00040,
-0x7c40c000,
-0x28d4001f,
-0xcc800040,
-0x95400003,
-0x7c410000,
-0xccc00057,
-0x2918001f,
-0xccc00040,
-0x95800003,
-0xcd000040,
-0xcd000058,
-0x80000249,
-0xcc00007f,
-0xc8200017,
-0xc8300022,
-0x9a000006,
-0x0e280001,
-0xc824001e,
-0x0a640001,
-0xd4001240,
-0xce400040,
-0xc036c000,
-0x96800007,
-0x37747900,
-0x041c0001,
-0xcf400040,
-0xcdc00040,
-0xcf0003fa,
-0x7c030000,
-0xca0c0010,
-0x7c410000,
-0x94c00004,
-0x7c414000,
-0xd42002c4,
-0xcde00044,
-0x9b00000b,
-0x7c418000,
-0xcc00004b,
-0xcda00049,
-0xcd200041,
-0xcd600041,
-0xcda00041,
-0x06200001,
-0xce000056,
-0x80000249,
-0xcc00007f,
-0xc8280020,
-0xc82c0021,
-0xcc000063,
-0x7eea4001,
-0x65740020,
-0x7f53402c,
-0x269c0002,
-0x7df5c020,
-0x69f80020,
-0xce80004b,
-0xce600049,
-0xcde00041,
-0xcfa00041,
-0xce600041,
-0x271c0002,
-0x7df5c020,
-0x69f80020,
-0x7db24001,
-0xcf00004b,
-0xce600049,
-0xcde00041,
-0xcfa00041,
-0x800000bc,
-0xce600041,
-0xc8200017,
-0xc8300022,
-0x9a000006,
-0x0e280001,
-0xc824001e,
-0x0a640001,
-0xd4001240,
-0xce400040,
-0xca0c0010,
-0x7c410000,
-0x94c0000b,
-0xc036c000,
-0x96800007,
-0x37747900,
-0x041c0001,
-0xcf400040,
-0xcdc00040,
-0xcf0003fa,
-0x7c030000,
-0x800000b5,
-0x7c414000,
-0xcc000048,
-0x800000ee,
-0x00000000,
-0xc8200017,
-0xc81c0023,
-0x0e240002,
-0x99c00015,
-0x7c418000,
-0x0a200001,
-0xce000056,
-0xd4000440,
-0xcc000040,
-0xc036c000,
-0xca140013,
-0x96400007,
-0x37747900,
-0xcf400040,
-0xcc000040,
-0xc83003fa,
-0x80000103,
-0xcf000022,
-0xcc000022,
-0x95400146,
-0xcc00007f,
-0xcca00046,
-0x80000000,
-0xcc200046,
-0x80000249,
-0xcc000064,
-0xc8200017,
-0xc810001f,
-0x96000005,
-0x09100001,
-0xd4000440,
-0xcd000040,
-0xcd000022,
-0xcc800040,
-0xd0400040,
-0xc80c0025,
-0x94c0feec,
-0xc8100008,
-0xcd000040,
-0xd4000fc0,
-0x80000000,
-0xd4000fa2,
-0x7c40c000,
-0x7c410000,
-0xccc003fd,
-0xcd0003fc,
-0xccc00042,
-0xcd000042,
-0x2914001f,
-0x29180010,
-0x31980007,
-0x3b5c0001,
-0x7d76000b,
-0x99800005,
-0x7d5e400b,
-0xcc000042,
-0x80000249,
-0xcc00004d,
-0x29980001,
-0x292c0008,
-0x9980003d,
-0x32ec0001,
-0x96000004,
-0x2930000c,
-0x80000249,
-0xcc000042,
-0x04140010,
-0xcd400042,
-0x33300001,
-0x34280001,
-0x8400015d,
-0xc8140003,
-0x9b40001b,
-0x0438000c,
-0x8400015d,
-0xc8140003,
-0x9b400017,
-0x04380008,
-0x8400015d,
-0xc8140003,
-0x9b400013,
-0x04380004,
-0x8400015d,
-0xc8140003,
-0x9b400015,
-0xc80c03fd,
-0x9a800009,
-0xc81003fc,
-0x9b000101,
-0xcc00004d,
-0x04140010,
-0xccc00042,
-0xcd000042,
-0x80000135,
-0xcd400042,
-0x96c000fa,
-0xcc00004d,
-0x80000249,
-0xcc00004e,
-0x9ac00003,
-0xcc00004d,
-0xcc00004e,
-0xdf830000,
-0x80000000,
-0xd80301ff,
-0x9ac000f0,
-0xcc00004d,
-0x80000249,
-0xcc00004e,
-0xc8180003,
-0xc81c0003,
-0xc8200003,
-0x7d5d4003,
-0x7da1c003,
-0x7d5d400c,
-0x2a10001f,
-0x299c001f,
-0x7d1d000b,
-0x7d17400b,
-0x88000000,
-0x7e92800b,
-0x96400004,
-0xcc00004e,
-0x80000249,
-0xcc000042,
-0x04380008,
-0xcf800042,
-0xc8080003,
-0xc80c0003,
-0xc8100003,
-0xc8140003,
-0xc8180003,
-0xc81c0003,
-0xc8240003,
-0xc8280003,
-0x29fc001f,
-0x2ab0001f,
-0x7ff3c00b,
-0x28f0001f,
-0x7ff3c00b,
-0x2970001f,
-0x7ff3c00b,
-0x7d888001,
-0x7dccc001,
-0x7e510001,
-0x7e954001,
-0x7c908002,
-0x7cd4c002,
-0x7cbc800b,
-0x9ac00003,
-0x7c8f400b,
-0x38b40001,
-0x9b4000c1,
-0xcc00004d,
-0x9bc000bf,
-0xcc00004e,
-0xc80c03fd,
-0xc81003fc,
-0xccc00042,
-0x8000016e,
-0xcd000042,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xcc400040,
-0xcc400040,
-0xcc400040,
-0x7c40c000,
-0xccc00040,
-0xccc0000d,
-0x80000000,
-0xd0400040,
-0x7c40c000,
-0x7c410000,
-0x65140020,
-0x7d4d402c,
-0x24580002,
-0x7d598020,
-0x7c41c000,
-0xcd800042,
-0x69980020,
-0xcd800042,
-0xcdc00042,
-0xc023c000,
-0x05e40002,
-0x7ca0800b,
-0x26640010,
-0x7ca4800c,
-0xcc800040,
-0xcdc00040,
-0xccc00040,
-0x95c0000e,
-0xcd000040,
-0x09dc0001,
-0xc8280003,
-0x96800008,
-0xce800040,
-0xc834001d,
-0x97400000,
-0xc834001d,
-0x26a80008,
-0x8400024c,
-0xcc2b0000,
-0x99c0fff7,
-0x09dc0001,
-0xdc3a0000,
-0x97800004,
-0x7c418000,
-0x800001a2,
-0x25980002,
-0xa0000000,
-0x7d808000,
-0xc818001d,
-0x7c40c000,
-0x64d00008,
-0x95800000,
-0xc818001d,
-0xcc130000,
-0xcc800040,
-0xccc00040,
-0x80000000,
-0xcc400040,
-0xc810001f,
-0x7c40c000,
-0xcc800040,
-0x7cd1400c,
-0xcd400040,
-0x05180001,
-0x80000000,
-0xcd800022,
-0x7c40c000,
-0x64500020,
-0x8400024c,
-0xcc000061,
-0x7cd0c02c,
-0xc8200017,
-0xc8d60000,
-0x99400008,
-0x7c438000,
-0xdf830000,
-0xcfa0004f,
-0x8400024c,
-0xcc000062,
-0x80000000,
-0xd040007f,
-0x80000249,
-0xcc000062,
-0x8400024c,
-0xcc000061,
-0xc8200017,
-0x7c40c000,
-0xc036ff00,
-0xc810000d,
-0xc0303fff,
-0x7cf5400b,
-0x7d51800b,
-0x7d81800f,
-0x99800008,
-0x7cf3800b,
-0xdf830000,
-0xcfa0004f,
-0x8400024c,
-0xcc000062,
-0x80000000,
-0xd040007f,
-0x80000249,
-0xcc000062,
-0x8400024c,
-0x7c40c000,
-0x28dc0008,
-0x95c00019,
-0x30dc0010,
-0x7c410000,
-0x99c00004,
-0x64540020,
-0x80000208,
-0xc91d0000,
-0x7d15002c,
-0xc91e0000,
-0x7c420000,
-0x7c424000,
-0x7c418000,
-0x7de5c00b,
-0x7de28007,
-0x9a80000e,
-0x41ac0005,
-0x9ac00000,
-0x0aec0001,
-0x30dc0010,
-0x99c00004,
-0x00000000,
-0x8000020b,
-0xc91d0000,
-0x8000020b,
-0xc91e0000,
-0xcc800040,
-0xccc00040,
-0xd0400040,
-0xc80c0025,
-0x94c0fde4,
-0xc8100008,
-0xcd000040,
-0xd4000fc0,
-0x80000000,
-0xd4000fa2,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x7c40c000,
-0x30d00006,
-0x0d100006,
-0x99000007,
-0xc8140015,
-0x99400005,
-0xcc000052,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xccc00040,
-0x80000000,
-0xd0400040,
-0x7c40c000,
-0xcc4d0000,
-0xdc3a0000,
-0x9780fdbd,
-0x04cc0001,
-0x80000242,
-0xcc4d0000,
-0x80000000,
-0xd040007f,
-0xcc00007f,
-0x80000000,
-0xcc00007f,
-0xcc00007f,
-0x88000000,
-0xcc00007f,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00030222,
-0x0004022a,
-0x0005009f,
-0x00020003,
-0x0006003c,
-0x00070027,
-0x00080191,
-0x00090044,
-0x000a002d,
-0x00100247,
-0x001700f0,
-0x002201d7,
-0x002301e8,
-0x0026004c,
-0x0027005f,
-0x0020011a,
-0x00280092,
-0x0029004f,
-0x002a0083,
-0x002b0064,
-0x002f008d,
-0x003200d8,
-0x00340232,
-0x00360074,
-0x0039010a,
-0x003c01fc,
-0x003f009f,
-0x00410005,
-0x00440194,
-0x0048019d,
-0x004901c5,
-0x004a01cf,
-0x00550225,
-0x0056022d,
-0x0060000a,
-0x0061002a,
-0x00620030,
-0x00630030,
-0x00640030,
-0x00650030,
-0x00660030,
-0x00670030,
-0x00680037,
-0x0069003f,
-0x006a0047,
-0x006b0047,
-0x006c0047,
-0x006d0047,
-0x006e0047,
-0x006f0047,
-0x00700047,
-0x00730247,
-0x007b0240,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-};
-
-static const u32 RV730_cp_microcode[] = {
-0xcc0003ea,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x80000001,
-0xd040007f,
-0x80000001,
-0xcc400041,
-0x7c40c000,
-0xc0160004,
-0x30d03fff,
-0x7d15000c,
-0xcc110000,
-0x28d8001e,
-0x31980001,
-0x28dc001f,
-0xc8200004,
-0x95c00006,
-0x7c424000,
-0xcc000062,
-0x7e56800c,
-0xcc290000,
-0xc8240004,
-0x7e26000b,
-0x95800006,
-0x7c42c000,
-0xcc000062,
-0x7ed7000c,
-0xcc310000,
-0xc82c0004,
-0x7e2e000c,
-0xcc000062,
-0x31103fff,
-0x80000001,
-0xce110000,
-0x7c40c000,
-0x80000001,
-0xcc400040,
-0x80000001,
-0xcc412257,
-0x7c418000,
-0xcc400045,
-0xcc400048,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xcc400045,
-0xcc400048,
-0x7c40c000,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xcc000045,
-0xcc000048,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x040ca1fd,
-0xc0120001,
-0xcc000045,
-0xcc000048,
-0x7cd0c00c,
-0xcc41225c,
-0xcc41a1fc,
-0xd04d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x80000001,
-0xcc41225d,
-0x7c408000,
-0x7c40c000,
-0xc02a0002,
-0x7c410000,
-0x7d29000c,
-0x30940001,
-0x30980006,
-0x309c0300,
-0x29dc0008,
-0x7c420000,
-0x7c424000,
-0x9540000f,
-0xc02e0004,
-0x05f02258,
-0x7f2f000c,
-0xcc310000,
-0xc8280004,
-0xccc12169,
-0xcd01216a,
-0xce81216b,
-0x0db40002,
-0xcc01216c,
-0x9740000e,
-0x0db40000,
-0x8000007b,
-0xc834000a,
-0x0db40002,
-0x97400009,
-0x0db40000,
-0xc02e0004,
-0x05f02258,
-0x7f2f000c,
-0xcc310000,
-0xc8280004,
-0x8000007b,
-0xc834000a,
-0x97400004,
-0x7e028000,
-0x8000007b,
-0xc834000a,
-0x0db40004,
-0x9740ff8c,
-0x00000000,
-0xce01216d,
-0xce41216e,
-0xc8280003,
-0xc834000a,
-0x9b400004,
-0x043c0005,
-0x8400026b,
-0xcc000062,
-0x0df40000,
-0x9740000b,
-0xc82c03e6,
-0xce81a2b7,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c4,
-0x80000001,
-0xcfc1a2d1,
-0x0df40001,
-0x9740000b,
-0xc82c03e7,
-0xce81a2bb,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c5,
-0x80000001,
-0xcfc1a2d2,
-0x0df40002,
-0x9740000b,
-0xc82c03e8,
-0xce81a2bf,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c6,
-0x80000001,
-0xcfc1a2d3,
-0xc82c03e9,
-0xce81a2c3,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c7,
-0x80000001,
-0xcfc1a2d4,
-0x80000001,
-0xcc400042,
-0x7c40c000,
-0x7c410000,
-0x2914001d,
-0x31540001,
-0x9940000c,
-0x31181000,
-0xc81c0011,
-0x95c00000,
-0xc81c0011,
-0xccc12100,
-0xcd012101,
-0xccc12102,
-0xcd012103,
-0x04180004,
-0x8000037c,
-0xcd81a2a4,
-0xc02a0004,
-0x95800008,
-0x36a821a3,
-0xcc290000,
-0xc8280004,
-0xc81c0011,
-0x0de40040,
-0x9640ffff,
-0xc81c0011,
-0xccc12170,
-0xcd012171,
-0xc8200012,
-0x96000000,
-0xc8200012,
-0x8000037c,
-0xcc000064,
-0x7c40c000,
-0x7c410000,
-0xcc000045,
-0xcc000048,
-0x40d40003,
-0xcd41225c,
-0xcd01a1fc,
-0xc01a0001,
-0x041ca1fd,
-0x7dd9c00c,
-0x7c420000,
-0x08cc0001,
-0x06240001,
-0x06280002,
-0xce1d0000,
-0xce5d0000,
-0x98c0fffa,
-0xce9d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x7c40c000,
-0x30d00001,
-0x28cc0001,
-0x7c414000,
-0x95000006,
-0x7c418000,
-0xcd41216d,
-0xcd81216e,
-0x800000f2,
-0xc81c0003,
-0xc0220004,
-0x7e16000c,
-0xcc210000,
-0xc81c0004,
-0x7c424000,
-0x98c00004,
-0x7c428000,
-0x80000001,
-0xcde50000,
-0xce412169,
-0xce81216a,
-0xcdc1216b,
-0x80000001,
-0xcc01216c,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0x7c41c000,
-0x28a40008,
-0x326400ff,
-0x0e68003c,
-0x9680000a,
-0x7c020000,
-0x7c420000,
-0x1e300003,
-0xcc00006a,
-0x9b000003,
-0x42200005,
-0x04200040,
-0x8000010f,
-0x7c024000,
-0x7e024000,
-0x9a400000,
-0x0a640001,
-0x30ec0010,
-0x9ac0000a,
-0xcc000062,
-0xc02a0004,
-0xc82c0021,
-0x7e92800c,
-0xcc000041,
-0xcc290000,
-0xcec00021,
-0x8000011f,
-0xc8300004,
-0xcd01216d,
-0xcd41216e,
-0xc8300003,
-0x7f1f000b,
-0x30f40007,
-0x27780001,
-0x9740002a,
-0x07b80124,
-0x9f800000,
-0x00000000,
-0x80000134,
-0x7f1b8004,
-0x80000138,
-0x7f1b8005,
-0x8000013c,
-0x7f1b8002,
-0x80000140,
-0x7f1b8003,
-0x80000144,
-0x7f1b8007,
-0x80000148,
-0x7f1b8006,
-0x8000014d,
-0x28a40008,
-0x9b800019,
-0x28a40008,
-0x8000015d,
-0x326400ff,
-0x9b800015,
-0x28a40008,
-0x8000015d,
-0x326400ff,
-0x9b800011,
-0x28a40008,
-0x8000015d,
-0x326400ff,
-0x9b80000d,
-0x28a40008,
-0x8000015d,
-0x326400ff,
-0x9b800009,
-0x28a40008,
-0x8000015d,
-0x326400ff,
-0x9b800005,
-0x28a40008,
-0x8000015d,
-0x326400ff,
-0x28a40008,
-0x326400ff,
-0x0e68003c,
-0x9a80feb2,
-0x28ec0008,
-0x7c434000,
-0x7c438000,
-0x7c43c000,
-0x96c00007,
-0xcc000062,
-0xcf412169,
-0xcf81216a,
-0xcfc1216b,
-0x80000001,
-0xcc01216c,
-0x80000001,
-0xcff50000,
-0xcc00006b,
-0x8400037f,
-0x0e68003c,
-0x9a800004,
-0xc8280015,
-0x80000001,
-0xd040007f,
-0x9680ffab,
-0x7e024000,
-0x84000239,
-0xc00e0002,
-0xcc000041,
-0x80000237,
-0xccc1304a,
-0x7c40c000,
-0x7c410000,
-0xc01e0001,
-0x29240012,
-0xc0220002,
-0x96400005,
-0xc0260004,
-0xc027fffb,
-0x7d25000b,
-0xc0260000,
-0x7dd2800b,
-0x7e12c00b,
-0x7d25000c,
-0x7c414000,
-0x7c418000,
-0xccc12169,
-0x9a80000a,
-0xcd01216a,
-0xcd41216b,
-0x96c0fe83,
-0xcd81216c,
-0xc8300018,
-0x97000000,
-0xc8300018,
-0x80000001,
-0xcc000018,
-0x8400037f,
-0xcc00007f,
-0xc8140013,
-0xc8180014,
-0xcd41216b,
-0x96c0fe77,
-0xcd81216c,
-0x80000181,
-0xc8300018,
-0xc80c0008,
-0x98c00000,
-0xc80c0008,
-0x7c410000,
-0x95000002,
-0x00000000,
-0x7c414000,
-0xc8200009,
-0xcc400043,
-0xce01a1f4,
-0xcc400044,
-0xc00e8000,
-0x7c424000,
-0x7c428000,
-0x2aac001f,
-0x96c0fe64,
-0xc035f000,
-0xce4003e2,
-0x32780003,
-0x267c0008,
-0x7ff7c00b,
-0x7ffbc00c,
-0x2a780018,
-0xcfc003e3,
-0xcf8003e4,
-0x26b00002,
-0x7f3f0000,
-0xcf0003e5,
-0x8000031d,
-0x7c80c000,
-0x7c40c000,
-0x28d00008,
-0x3110000f,
-0x9500000f,
-0x25280001,
-0x06a801b2,
-0x9e800000,
-0x00000000,
-0x800001d3,
-0xc0120800,
-0x800001e1,
-0xc814000f,
-0x800001e8,
-0xc8140010,
-0x800001ef,
-0xccc1a2a4,
-0x800001f8,
-0xc8140011,
-0x30d0003f,
-0x0d280015,
-0x9a800012,
-0x0d28001e,
-0x9a80001e,
-0x0d280020,
-0x9a800023,
-0x0d24000f,
-0x0d280010,
-0x7e6a800c,
-0x9a800026,
-0x0d200004,
-0x0d240014,
-0x0d280028,
-0x7e62400c,
-0x7ea6800c,
-0x9a80002a,
-0xc8140011,
-0x80000001,
-0xccc1a2a4,
-0xc0120800,
-0x7c414000,
-0x7d0cc00c,
-0xc0120008,
-0x29580003,
-0x295c000c,
-0x7c420000,
-0x7dd1c00b,
-0x26200014,
-0x7e1e400c,
-0x7e4e800c,
-0xce81a2a4,
-0x80000001,
-0xcd81a1fe,
-0xc814000f,
-0x0410210e,
-0x95400000,
-0xc814000f,
-0xd0510000,
-0x80000001,
-0xccc1a2a4,
-0xc8140010,
-0x04102108,
-0x95400000,
-0xc8140010,
-0xd0510000,
-0x80000001,
-0xccc1a2a4,
-0xccc1a2a4,
-0x04100001,
-0xcd000019,
-0x8400037f,
-0xcc00007f,
-0xc8100019,
-0x99000000,
-0xc8100019,
-0x80000002,
-0x7c408000,
-0x04102100,
-0x95400000,
-0xc8140011,
-0xd0510000,
-0x8000037c,
-0xccc1a2a4,
-0x7c40c000,
-0xcc40000d,
-0x94c0fe01,
-0xcc40000e,
-0x7c410000,
-0x95000005,
-0x08cc0001,
-0xc8140005,
-0x99400014,
-0x00000000,
-0x98c0fffb,
-0x7c410000,
-0x80000002,
-0x7d008000,
-0xc8140005,
-0x7c40c000,
-0x9940000c,
-0xc818000c,
-0x7c410000,
-0x9580fdf0,
-0xc820000e,
-0xc81c000d,
-0x66200020,
-0x7e1e002c,
-0x25240002,
-0x7e624020,
-0x80000001,
-0xcce60000,
-0x7c410000,
-0xcc00006c,
-0xcc00006d,
-0xc818001f,
-0xc81c001e,
-0x65980020,
-0x7dd9c02c,
-0x7cd4c00c,
-0xccde0000,
-0x45dc0004,
-0xc8280017,
-0x9680000f,
-0xc00e0001,
-0x28680008,
-0x2aac0016,
-0x32a800ff,
-0x0eb00049,
-0x7f2f000b,
-0x97000006,
-0x00000000,
-0xc8140005,
-0x7c40c000,
-0x80000221,
-0x7c410000,
-0x80000224,
-0xd040007f,
-0x84000239,
-0xcc000041,
-0xccc1304a,
-0x94000000,
-0xc83c001a,
-0x043c0005,
-0xcfc1a2a4,
-0xc0361f90,
-0xc0387fff,
-0x7c03c010,
-0x7f7b400c,
-0xcf41217c,
-0xcfc1217d,
-0xcc01217e,
-0xc03a0004,
-0x0434217f,
-0x7f7b400c,
-0xcc350000,
-0xc83c0004,
-0x2bfc001f,
-0x04380020,
-0x97c00005,
-0xcc000062,
-0x9b800000,
-0x0bb80001,
-0x80000245,
-0xcc000071,
-0xcc01a1f4,
-0x04380016,
-0xc0360002,
-0xcf81a2a4,
-0x88000000,
-0xcf412010,
-0x7c40c000,
-0x28d0001c,
-0x95000005,
-0x04d40001,
-0xcd400065,
-0x80000001,
-0xcd400068,
-0x09540002,
-0x80000001,
-0xcd400066,
-0x8400026a,
-0xc81803ea,
-0x7c40c000,
-0x9980fd9f,
-0xc8140016,
-0x08d00001,
-0x9940002b,
-0xcd000068,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x043c0005,
-0xcfc1a2a4,
-0xcc01a1f4,
-0x8400037f,
-0xcc000046,
-0x88000000,
-0xcc00007f,
-0x8400027c,
-0xc81803ea,
-0x7c40c000,
-0x9980fd8d,
-0xc8140016,
-0x08d00001,
-0x99400019,
-0xcd000068,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x043c0022,
-0xcfc1a2a4,
-0x8400037f,
-0xcc000047,
-0x88000000,
-0xcc00007f,
-0xc8100016,
-0x9900000d,
-0xcc400067,
-0x80000002,
-0x7c408000,
-0xc81803ea,
-0x9980fd79,
-0x7c40c000,
-0x94c00003,
-0xc8100016,
-0x99000004,
-0xccc00068,
-0x80000002,
-0x7c408000,
-0x84000239,
-0xc0148000,
-0xcc000041,
-0xcd41304a,
-0xc0148000,
-0x99000000,
-0xc8100016,
-0x80000002,
-0x7c408000,
-0xc0120001,
-0x7c51400c,
-0x80000001,
-0xd0550000,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0x291c001f,
-0xccc0004a,
-0xcd00004b,
-0x95c00003,
-0xc01c8000,
-0xcdc12010,
-0xdd830000,
-0x055c2000,
-0xcc000062,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc0004c,
-0xcd00004d,
-0xdd830000,
-0x055ca000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc0004e,
-0xcd00004f,
-0xdd830000,
-0x055cc000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00050,
-0xcd000051,
-0xdd830000,
-0x055cf8e0,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00052,
-0xcd000053,
-0xdd830000,
-0x055cf880,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00054,
-0xcd000055,
-0xdd830000,
-0x055ce000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00056,
-0xcd000057,
-0xdd830000,
-0x055cf000,
-0x80000001,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00058,
-0xcd000059,
-0xdd830000,
-0x055cf3fc,
-0x80000001,
-0xd81f4100,
-0xd0432000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043a000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043c000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f8e0,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f880,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043e000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f3fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xc81403e0,
-0xcc430000,
-0xcc430000,
-0xcc430000,
-0x7d45c000,
-0xcdc30000,
-0xd0430000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x7c40c000,
-0xc81003e2,
-0xc81403e5,
-0xc81803e3,
-0xc81c03e4,
-0xcd812169,
-0xcdc1216a,
-0xccc1216b,
-0xcc01216c,
-0x04200004,
-0x7da18000,
-0x7d964002,
-0x9640fcd9,
-0xcd8003e3,
-0x31280003,
-0xc02df000,
-0x25180008,
-0x7dad800b,
-0x7da9800c,
-0x80000001,
-0xcd8003e3,
-0x308cffff,
-0xd04d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xc8140020,
-0x15580002,
-0x9580ffff,
-0xc8140020,
-0xcc00006e,
-0xcc412180,
-0x7c40c000,
-0xccc1218d,
-0xcc412181,
-0x28d0001f,
-0x34588000,
-0xcd81218c,
-0x9500fcbf,
-0xcc412182,
-0xc8140020,
-0x9940ffff,
-0xc8140020,
-0x80000002,
-0x7c408000,
-0x7c40c000,
-0x28d00018,
-0x31100001,
-0xc0160080,
-0x95000003,
-0xc02a0004,
-0x7cd4c00c,
-0xccc1217c,
-0xcc41217d,
-0xcc41217e,
-0x7c418000,
-0x1db00003,
-0x36a0217f,
-0x9b000003,
-0x419c0005,
-0x041c0040,
-0x99c00000,
-0x09dc0001,
-0xcc210000,
-0xc8240004,
-0x2a6c001f,
-0x419c0005,
-0x9ac0fffa,
-0xcc800062,
-0x80000002,
-0x7c408000,
-0x7c40c000,
-0x04d403e6,
-0x80000001,
-0xcc540000,
-0x8000037c,
-0xcc4003ea,
-0xc01c8000,
-0x044ca000,
-0xcdc12010,
-0x7c410000,
-0xc8140009,
-0x04180000,
-0x041c0008,
-0xcd800071,
-0x09dc0001,
-0x05980001,
-0xcd0d0000,
-0x99c0fffc,
-0xcc800062,
-0x8000037c,
-0xcd400071,
-0xc00e0100,
-0xcc000041,
-0xccc1304a,
-0xc83c007f,
-0xcc00007f,
-0x80000001,
-0xcc00007f,
-0xcc00007f,
-0x88000000,
-0xcc00007f,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00010331,
-0x00100004,
-0x00170006,
-0x00210008,
-0x00270028,
-0x00280023,
-0x00290029,
-0x002a0026,
-0x002b0029,
-0x002d0038,
-0x002e003f,
-0x002f004a,
-0x0034004c,
-0x00360030,
-0x003900af,
-0x003a00cf,
-0x003b00e4,
-0x003c00fc,
-0x003d016b,
-0x003f00ad,
-0x00410336,
-0x00430349,
-0x0044018e,
-0x004500fc,
-0x004601ac,
-0x004701ac,
-0x004801fe,
-0x0049020c,
-0x004a0255,
-0x004b0282,
-0x0052025f,
-0x00530271,
-0x00540287,
-0x00570299,
-0x0060029d,
-0x006102ac,
-0x006202b6,
-0x006302c0,
-0x006402ca,
-0x006502d4,
-0x006602de,
-0x006702e8,
-0x006802f2,
-0x006902f6,
-0x006a02fa,
-0x006b02fe,
-0x006c0302,
-0x006d0306,
-0x006e030a,
-0x006f030e,
-0x00700312,
-0x00720363,
-0x00740369,
-0x00790367,
-0x007c031c,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-0x000f0378,
-};
-
-static const u32 RV710_pfp_microcode[] = {
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x80000000,
-0xdc030000,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xc818000e,
-0x31980001,
-0x7c424000,
-0x9580023a,
-0x7c428000,
-0xc81c001c,
-0xc037c000,
-0x7c40c000,
-0x7c410000,
-0x7cb4800b,
-0xc0360003,
-0x99c00000,
-0xc81c001c,
-0x7cb4800c,
-0x24d40002,
-0x7d654000,
-0xcd400043,
-0xce800043,
-0xcd000043,
-0xcc800040,
-0xce400040,
-0xce800040,
-0xccc00040,
-0xdc3a0000,
-0x9780ffde,
-0xcd000040,
-0x7c40c000,
-0x80000018,
-0x7c410000,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xc818000e,
-0x8000000c,
-0x31980002,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xc818000e,
-0x288c0008,
-0x30cc000f,
-0x34100001,
-0x7d0d0008,
-0x8000000c,
-0x7d91800b,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xcc4003f9,
-0x80000249,
-0xcc4003f8,
-0xc037ffff,
-0x7c414000,
-0xcf41a29e,
-0xc82003f8,
-0xc81c03f9,
-0x66200020,
-0xc81803fb,
-0x7de1c02c,
-0x7d58c008,
-0x7cdcc020,
-0x69100020,
-0xc0360003,
-0xcc000054,
-0x7cb4800c,
-0x80000069,
-0xcc800040,
-0x7c418000,
-0xcd81a29e,
-0xcc800040,
-0x80000067,
-0xcd800040,
-0xc019ffff,
-0xcc800040,
-0xcd81a29e,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0xccc1a1fa,
-0xcd01a1f9,
-0xcd41a29d,
-0xccc00040,
-0xcd000040,
-0xcd400040,
-0xcc400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xcc000054,
-0xcc800040,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0xccc1a1fa,
-0xcd01a1f9,
-0xcd41a29d,
-0xccc00040,
-0xcd000040,
-0xcd400040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x7c40c000,
-0x30d00001,
-0xccc1a29f,
-0x95000003,
-0x04140001,
-0x04140002,
-0xcd4003fb,
-0xcc800040,
-0x80000000,
-0xccc00040,
-0x7c40c000,
-0xcc800040,
-0xccc1a2a2,
-0x80000000,
-0xccc00040,
-0x7c40c000,
-0x28d4001f,
-0xcc800040,
-0x95400003,
-0x7c410000,
-0xccc00057,
-0x2918001f,
-0xccc00040,
-0x95800003,
-0xcd000040,
-0xcd000058,
-0x80000249,
-0xcc00007f,
-0xc8200017,
-0xc8300022,
-0x9a000006,
-0x0e280001,
-0xc824001e,
-0x0a640001,
-0xd4001240,
-0xce400040,
-0xc036c000,
-0x96800007,
-0x37747900,
-0x041c0001,
-0xcf400040,
-0xcdc00040,
-0xcf0003fa,
-0x7c030000,
-0xca0c0010,
-0x7c410000,
-0x94c00004,
-0x7c414000,
-0xd42002c4,
-0xcde00044,
-0x9b00000b,
-0x7c418000,
-0xcc00004b,
-0xcda00049,
-0xcd200041,
-0xcd600041,
-0xcda00041,
-0x06200001,
-0xce000056,
-0x80000249,
-0xcc00007f,
-0xc8280020,
-0xc82c0021,
-0xcc000063,
-0x7eea4001,
-0x65740020,
-0x7f53402c,
-0x269c0002,
-0x7df5c020,
-0x69f80020,
-0xce80004b,
-0xce600049,
-0xcde00041,
-0xcfa00041,
-0xce600041,
-0x271c0002,
-0x7df5c020,
-0x69f80020,
-0x7db24001,
-0xcf00004b,
-0xce600049,
-0xcde00041,
-0xcfa00041,
-0x800000bc,
-0xce600041,
-0xc8200017,
-0xc8300022,
-0x9a000006,
-0x0e280001,
-0xc824001e,
-0x0a640001,
-0xd4001240,
-0xce400040,
-0xca0c0010,
-0x7c410000,
-0x94c0000b,
-0xc036c000,
-0x96800007,
-0x37747900,
-0x041c0001,
-0xcf400040,
-0xcdc00040,
-0xcf0003fa,
-0x7c030000,
-0x800000b5,
-0x7c414000,
-0xcc000048,
-0x800000ee,
-0x00000000,
-0xc8200017,
-0xc81c0023,
-0x0e240002,
-0x99c00015,
-0x7c418000,
-0x0a200001,
-0xce000056,
-0xd4000440,
-0xcc000040,
-0xc036c000,
-0xca140013,
-0x96400007,
-0x37747900,
-0xcf400040,
-0xcc000040,
-0xc83003fa,
-0x80000103,
-0xcf000022,
-0xcc000022,
-0x95400146,
-0xcc00007f,
-0xcca00046,
-0x80000000,
-0xcc200046,
-0x80000249,
-0xcc000064,
-0xc8200017,
-0xc810001f,
-0x96000005,
-0x09100001,
-0xd4000440,
-0xcd000040,
-0xcd000022,
-0xcc800040,
-0xd0400040,
-0xc80c0025,
-0x94c0feec,
-0xc8100008,
-0xcd000040,
-0xd4000fc0,
-0x80000000,
-0xd4000fa2,
-0x7c40c000,
-0x7c410000,
-0xccc003fd,
-0xcd0003fc,
-0xccc00042,
-0xcd000042,
-0x2914001f,
-0x29180010,
-0x31980007,
-0x3b5c0001,
-0x7d76000b,
-0x99800005,
-0x7d5e400b,
-0xcc000042,
-0x80000249,
-0xcc00004d,
-0x29980001,
-0x292c0008,
-0x9980003d,
-0x32ec0001,
-0x96000004,
-0x2930000c,
-0x80000249,
-0xcc000042,
-0x04140010,
-0xcd400042,
-0x33300001,
-0x34280001,
-0x8400015d,
-0xc8140003,
-0x9b40001b,
-0x0438000c,
-0x8400015d,
-0xc8140003,
-0x9b400017,
-0x04380008,
-0x8400015d,
-0xc8140003,
-0x9b400013,
-0x04380004,
-0x8400015d,
-0xc8140003,
-0x9b400015,
-0xc80c03fd,
-0x9a800009,
-0xc81003fc,
-0x9b000101,
-0xcc00004d,
-0x04140010,
-0xccc00042,
-0xcd000042,
-0x80000135,
-0xcd400042,
-0x96c000fa,
-0xcc00004d,
-0x80000249,
-0xcc00004e,
-0x9ac00003,
-0xcc00004d,
-0xcc00004e,
-0xdf830000,
-0x80000000,
-0xd80301ff,
-0x9ac000f0,
-0xcc00004d,
-0x80000249,
-0xcc00004e,
-0xc8180003,
-0xc81c0003,
-0xc8200003,
-0x7d5d4003,
-0x7da1c003,
-0x7d5d400c,
-0x2a10001f,
-0x299c001f,
-0x7d1d000b,
-0x7d17400b,
-0x88000000,
-0x7e92800b,
-0x96400004,
-0xcc00004e,
-0x80000249,
-0xcc000042,
-0x04380008,
-0xcf800042,
-0xc8080003,
-0xc80c0003,
-0xc8100003,
-0xc8140003,
-0xc8180003,
-0xc81c0003,
-0xc8240003,
-0xc8280003,
-0x29fc001f,
-0x2ab0001f,
-0x7ff3c00b,
-0x28f0001f,
-0x7ff3c00b,
-0x2970001f,
-0x7ff3c00b,
-0x7d888001,
-0x7dccc001,
-0x7e510001,
-0x7e954001,
-0x7c908002,
-0x7cd4c002,
-0x7cbc800b,
-0x9ac00003,
-0x7c8f400b,
-0x38b40001,
-0x9b4000c1,
-0xcc00004d,
-0x9bc000bf,
-0xcc00004e,
-0xc80c03fd,
-0xc81003fc,
-0xccc00042,
-0x8000016e,
-0xcd000042,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xcc400040,
-0xcc400040,
-0xcc400040,
-0x7c40c000,
-0xccc00040,
-0xccc0000d,
-0x80000000,
-0xd0400040,
-0x7c40c000,
-0x7c410000,
-0x65140020,
-0x7d4d402c,
-0x24580002,
-0x7d598020,
-0x7c41c000,
-0xcd800042,
-0x69980020,
-0xcd800042,
-0xcdc00042,
-0xc023c000,
-0x05e40002,
-0x7ca0800b,
-0x26640010,
-0x7ca4800c,
-0xcc800040,
-0xcdc00040,
-0xccc00040,
-0x95c0000e,
-0xcd000040,
-0x09dc0001,
-0xc8280003,
-0x96800008,
-0xce800040,
-0xc834001d,
-0x97400000,
-0xc834001d,
-0x26a80008,
-0x8400024c,
-0xcc2b0000,
-0x99c0fff7,
-0x09dc0001,
-0xdc3a0000,
-0x97800004,
-0x7c418000,
-0x800001a2,
-0x25980002,
-0xa0000000,
-0x7d808000,
-0xc818001d,
-0x7c40c000,
-0x64d00008,
-0x95800000,
-0xc818001d,
-0xcc130000,
-0xcc800040,
-0xccc00040,
-0x80000000,
-0xcc400040,
-0xc810001f,
-0x7c40c000,
-0xcc800040,
-0x7cd1400c,
-0xcd400040,
-0x05180001,
-0x80000000,
-0xcd800022,
-0x7c40c000,
-0x64500020,
-0x8400024c,
-0xcc000061,
-0x7cd0c02c,
-0xc8200017,
-0xc8d60000,
-0x99400008,
-0x7c438000,
-0xdf830000,
-0xcfa0004f,
-0x8400024c,
-0xcc000062,
-0x80000000,
-0xd040007f,
-0x80000249,
-0xcc000062,
-0x8400024c,
-0xcc000061,
-0xc8200017,
-0x7c40c000,
-0xc036ff00,
-0xc810000d,
-0xc0303fff,
-0x7cf5400b,
-0x7d51800b,
-0x7d81800f,
-0x99800008,
-0x7cf3800b,
-0xdf830000,
-0xcfa0004f,
-0x8400024c,
-0xcc000062,
-0x80000000,
-0xd040007f,
-0x80000249,
-0xcc000062,
-0x8400024c,
-0x7c40c000,
-0x28dc0008,
-0x95c00019,
-0x30dc0010,
-0x7c410000,
-0x99c00004,
-0x64540020,
-0x80000208,
-0xc91d0000,
-0x7d15002c,
-0xc91e0000,
-0x7c420000,
-0x7c424000,
-0x7c418000,
-0x7de5c00b,
-0x7de28007,
-0x9a80000e,
-0x41ac0005,
-0x9ac00000,
-0x0aec0001,
-0x30dc0010,
-0x99c00004,
-0x00000000,
-0x8000020b,
-0xc91d0000,
-0x8000020b,
-0xc91e0000,
-0xcc800040,
-0xccc00040,
-0xd0400040,
-0xc80c0025,
-0x94c0fde4,
-0xc8100008,
-0xcd000040,
-0xd4000fc0,
-0x80000000,
-0xd4000fa2,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0xd40003c0,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xd0400040,
-0x7c408000,
-0xa0000000,
-0x7e82800b,
-0x7c40c000,
-0x30d00006,
-0x0d100006,
-0x99000007,
-0xc8140015,
-0x99400005,
-0xcc000052,
-0xd4000340,
-0xd4000fc0,
-0xd4000fa2,
-0xcc800040,
-0xccc00040,
-0x80000000,
-0xd0400040,
-0x7c40c000,
-0xcc4d0000,
-0xdc3a0000,
-0x9780fdbd,
-0x04cc0001,
-0x80000242,
-0xcc4d0000,
-0x80000000,
-0xd040007f,
-0xcc00007f,
-0x80000000,
-0xcc00007f,
-0xcc00007f,
-0x88000000,
-0xcc00007f,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00030222,
-0x0004022a,
-0x0005009f,
-0x00020003,
-0x0006003c,
-0x00070027,
-0x00080191,
-0x00090044,
-0x000a002d,
-0x00100247,
-0x001700f0,
-0x002201d7,
-0x002301e8,
-0x0026004c,
-0x0027005f,
-0x0020011a,
-0x00280092,
-0x0029004f,
-0x002a0083,
-0x002b0064,
-0x002f008d,
-0x003200d8,
-0x00340232,
-0x00360074,
-0x0039010a,
-0x003c01fc,
-0x003f009f,
-0x00410005,
-0x00440194,
-0x0048019d,
-0x004901c5,
-0x004a01cf,
-0x00550225,
-0x0056022d,
-0x0060000a,
-0x0061002a,
-0x00620030,
-0x00630030,
-0x00640030,
-0x00650030,
-0x00660030,
-0x00670030,
-0x00680037,
-0x0069003f,
-0x006a0047,
-0x006b0047,
-0x006c0047,
-0x006d0047,
-0x006e0047,
-0x006f0047,
-0x00700047,
-0x00730247,
-0x007b0240,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-0x00000005,
-};
-
-static const u32 RV710_cp_microcode[] = {
-0xcc0003ea,
-0x04080003,
-0xcc800043,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x80000003,
-0xd040007f,
-0x80000003,
-0xcc400041,
-0x7c40c000,
-0xc0160004,
-0x30d03fff,
-0x7d15000c,
-0xcc110000,
-0x28d8001e,
-0x31980001,
-0x28dc001f,
-0xc8200004,
-0x95c00006,
-0x7c424000,
-0xcc000062,
-0x7e56800c,
-0xcc290000,
-0xc8240004,
-0x7e26000b,
-0x95800006,
-0x7c42c000,
-0xcc000062,
-0x7ed7000c,
-0xcc310000,
-0xc82c0004,
-0x7e2e000c,
-0xcc000062,
-0x31103fff,
-0x80000003,
-0xce110000,
-0x7c40c000,
-0x80000003,
-0xcc400040,
-0x80000003,
-0xcc412257,
-0x7c418000,
-0xcc400045,
-0xcc400048,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xcc400045,
-0xcc400048,
-0x7c40c000,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xcc000045,
-0xcc000048,
-0xcc41225c,
-0xcc41a1fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x040ca1fd,
-0xc0120001,
-0xcc000045,
-0xcc000048,
-0x7cd0c00c,
-0xcc41225c,
-0xcc41a1fc,
-0xd04d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x80000003,
-0xcc41225d,
-0x7c408000,
-0x7c40c000,
-0xc02a0002,
-0x7c410000,
-0x7d29000c,
-0x30940001,
-0x30980006,
-0x309c0300,
-0x29dc0008,
-0x7c420000,
-0x7c424000,
-0x9540000f,
-0xc02e0004,
-0x05f02258,
-0x7f2f000c,
-0xcc310000,
-0xc8280004,
-0xccc12169,
-0xcd01216a,
-0xce81216b,
-0x0db40002,
-0xcc01216c,
-0x9740000e,
-0x0db40000,
-0x8000007d,
-0xc834000a,
-0x0db40002,
-0x97400009,
-0x0db40000,
-0xc02e0004,
-0x05f02258,
-0x7f2f000c,
-0xcc310000,
-0xc8280004,
-0x8000007d,
-0xc834000a,
-0x97400004,
-0x7e028000,
-0x8000007d,
-0xc834000a,
-0x0db40004,
-0x9740ff8c,
-0x00000000,
-0xce01216d,
-0xce41216e,
-0xc8280003,
-0xc834000a,
-0x9b400004,
-0x043c0005,
-0x8400026d,
-0xcc000062,
-0x0df40000,
-0x9740000b,
-0xc82c03e6,
-0xce81a2b7,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c4,
-0x80000003,
-0xcfc1a2d1,
-0x0df40001,
-0x9740000b,
-0xc82c03e7,
-0xce81a2bb,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c5,
-0x80000003,
-0xcfc1a2d2,
-0x0df40002,
-0x9740000b,
-0xc82c03e8,
-0xce81a2bf,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c6,
-0x80000003,
-0xcfc1a2d3,
-0xc82c03e9,
-0xce81a2c3,
-0xc0300006,
-0x7ef34028,
-0xc0300020,
-0x7f6b8020,
-0x7fb3c029,
-0xcf81a2c7,
-0x80000003,
-0xcfc1a2d4,
-0x80000003,
-0xcc400042,
-0x7c40c000,
-0x7c410000,
-0x2914001d,
-0x31540001,
-0x9940000c,
-0x31181000,
-0xc81c0011,
-0x95c00000,
-0xc81c0011,
-0xccc12100,
-0xcd012101,
-0xccc12102,
-0xcd012103,
-0x04180004,
-0x8000037e,
-0xcd81a2a4,
-0xc02a0004,
-0x95800008,
-0x36a821a3,
-0xcc290000,
-0xc8280004,
-0xc81c0011,
-0x0de40040,
-0x9640ffff,
-0xc81c0011,
-0xccc12170,
-0xcd012171,
-0xc8200012,
-0x96000000,
-0xc8200012,
-0x8000037e,
-0xcc000064,
-0x7c40c000,
-0x7c410000,
-0xcc000045,
-0xcc000048,
-0x40d40003,
-0xcd41225c,
-0xcd01a1fc,
-0xc01a0001,
-0x041ca1fd,
-0x7dd9c00c,
-0x7c420000,
-0x08cc0001,
-0x06240001,
-0x06280002,
-0xce1d0000,
-0xce5d0000,
-0x98c0fffa,
-0xce9d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x7c40c000,
-0x30d00001,
-0x28cc0001,
-0x7c414000,
-0x95000006,
-0x7c418000,
-0xcd41216d,
-0xcd81216e,
-0x800000f4,
-0xc81c0003,
-0xc0220004,
-0x7e16000c,
-0xcc210000,
-0xc81c0004,
-0x7c424000,
-0x98c00004,
-0x7c428000,
-0x80000003,
-0xcde50000,
-0xce412169,
-0xce81216a,
-0xcdc1216b,
-0x80000003,
-0xcc01216c,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0x7c41c000,
-0x28a40008,
-0x326400ff,
-0x0e68003c,
-0x9680000a,
-0x7c020000,
-0x7c420000,
-0x1e300003,
-0xcc00006a,
-0x9b000003,
-0x42200005,
-0x04200040,
-0x80000111,
-0x7c024000,
-0x7e024000,
-0x9a400000,
-0x0a640001,
-0x30ec0010,
-0x9ac0000a,
-0xcc000062,
-0xc02a0004,
-0xc82c0021,
-0x7e92800c,
-0xcc000041,
-0xcc290000,
-0xcec00021,
-0x80000121,
-0xc8300004,
-0xcd01216d,
-0xcd41216e,
-0xc8300003,
-0x7f1f000b,
-0x30f40007,
-0x27780001,
-0x9740002a,
-0x07b80126,
-0x9f800000,
-0x00000000,
-0x80000136,
-0x7f1b8004,
-0x8000013a,
-0x7f1b8005,
-0x8000013e,
-0x7f1b8002,
-0x80000142,
-0x7f1b8003,
-0x80000146,
-0x7f1b8007,
-0x8000014a,
-0x7f1b8006,
-0x8000014f,
-0x28a40008,
-0x9b800019,
-0x28a40008,
-0x8000015f,
-0x326400ff,
-0x9b800015,
-0x28a40008,
-0x8000015f,
-0x326400ff,
-0x9b800011,
-0x28a40008,
-0x8000015f,
-0x326400ff,
-0x9b80000d,
-0x28a40008,
-0x8000015f,
-0x326400ff,
-0x9b800009,
-0x28a40008,
-0x8000015f,
-0x326400ff,
-0x9b800005,
-0x28a40008,
-0x8000015f,
-0x326400ff,
-0x28a40008,
-0x326400ff,
-0x0e68003c,
-0x9a80feb2,
-0x28ec0008,
-0x7c434000,
-0x7c438000,
-0x7c43c000,
-0x96c00007,
-0xcc000062,
-0xcf412169,
-0xcf81216a,
-0xcfc1216b,
-0x80000003,
-0xcc01216c,
-0x80000003,
-0xcff50000,
-0xcc00006b,
-0x84000381,
-0x0e68003c,
-0x9a800004,
-0xc8280015,
-0x80000003,
-0xd040007f,
-0x9680ffab,
-0x7e024000,
-0x8400023b,
-0xc00e0002,
-0xcc000041,
-0x80000239,
-0xccc1304a,
-0x7c40c000,
-0x7c410000,
-0xc01e0001,
-0x29240012,
-0xc0220002,
-0x96400005,
-0xc0260004,
-0xc027fffb,
-0x7d25000b,
-0xc0260000,
-0x7dd2800b,
-0x7e12c00b,
-0x7d25000c,
-0x7c414000,
-0x7c418000,
-0xccc12169,
-0x9a80000a,
-0xcd01216a,
-0xcd41216b,
-0x96c0fe83,
-0xcd81216c,
-0xc8300018,
-0x97000000,
-0xc8300018,
-0x80000003,
-0xcc000018,
-0x84000381,
-0xcc00007f,
-0xc8140013,
-0xc8180014,
-0xcd41216b,
-0x96c0fe77,
-0xcd81216c,
-0x80000183,
-0xc8300018,
-0xc80c0008,
-0x98c00000,
-0xc80c0008,
-0x7c410000,
-0x95000002,
-0x00000000,
-0x7c414000,
-0xc8200009,
-0xcc400043,
-0xce01a1f4,
-0xcc400044,
-0xc00e8000,
-0x7c424000,
-0x7c428000,
-0x2aac001f,
-0x96c0fe64,
-0xc035f000,
-0xce4003e2,
-0x32780003,
-0x267c0008,
-0x7ff7c00b,
-0x7ffbc00c,
-0x2a780018,
-0xcfc003e3,
-0xcf8003e4,
-0x26b00002,
-0x7f3f0000,
-0xcf0003e5,
-0x8000031f,
-0x7c80c000,
-0x7c40c000,
-0x28d00008,
-0x3110000f,
-0x9500000f,
-0x25280001,
-0x06a801b4,
-0x9e800000,
-0x00000000,
-0x800001d5,
-0xc0120800,
-0x800001e3,
-0xc814000f,
-0x800001ea,
-0xc8140010,
-0x800001f1,
-0xccc1a2a4,
-0x800001fa,
-0xc8140011,
-0x30d0003f,
-0x0d280015,
-0x9a800012,
-0x0d28001e,
-0x9a80001e,
-0x0d280020,
-0x9a800023,
-0x0d24000f,
-0x0d280010,
-0x7e6a800c,
-0x9a800026,
-0x0d200004,
-0x0d240014,
-0x0d280028,
-0x7e62400c,
-0x7ea6800c,
-0x9a80002a,
-0xc8140011,
-0x80000003,
-0xccc1a2a4,
-0xc0120800,
-0x7c414000,
-0x7d0cc00c,
-0xc0120008,
-0x29580003,
-0x295c000c,
-0x7c420000,
-0x7dd1c00b,
-0x26200014,
-0x7e1e400c,
-0x7e4e800c,
-0xce81a2a4,
-0x80000003,
-0xcd81a1fe,
-0xc814000f,
-0x0410210e,
-0x95400000,
-0xc814000f,
-0xd0510000,
-0x80000003,
-0xccc1a2a4,
-0xc8140010,
-0x04102108,
-0x95400000,
-0xc8140010,
-0xd0510000,
-0x80000003,
-0xccc1a2a4,
-0xccc1a2a4,
-0x04100001,
-0xcd000019,
-0x84000381,
-0xcc00007f,
-0xc8100019,
-0x99000000,
-0xc8100019,
-0x80000004,
-0x7c408000,
-0x04102100,
-0x95400000,
-0xc8140011,
-0xd0510000,
-0x8000037e,
-0xccc1a2a4,
-0x7c40c000,
-0xcc40000d,
-0x94c0fe01,
-0xcc40000e,
-0x7c410000,
-0x95000005,
-0x08cc0001,
-0xc8140005,
-0x99400014,
-0x00000000,
-0x98c0fffb,
-0x7c410000,
-0x80000004,
-0x7d008000,
-0xc8140005,
-0x7c40c000,
-0x9940000c,
-0xc818000c,
-0x7c410000,
-0x9580fdf0,
-0xc820000e,
-0xc81c000d,
-0x66200020,
-0x7e1e002c,
-0x25240002,
-0x7e624020,
-0x80000003,
-0xcce60000,
-0x7c410000,
-0xcc00006c,
-0xcc00006d,
-0xc818001f,
-0xc81c001e,
-0x65980020,
-0x7dd9c02c,
-0x7cd4c00c,
-0xccde0000,
-0x45dc0004,
-0xc8280017,
-0x9680000f,
-0xc00e0001,
-0x28680008,
-0x2aac0016,
-0x32a800ff,
-0x0eb00049,
-0x7f2f000b,
-0x97000006,
-0x00000000,
-0xc8140005,
-0x7c40c000,
-0x80000223,
-0x7c410000,
-0x80000226,
-0xd040007f,
-0x8400023b,
-0xcc000041,
-0xccc1304a,
-0x94000000,
-0xc83c001a,
-0x043c0005,
-0xcfc1a2a4,
-0xc0361f90,
-0xc0387fff,
-0x7c03c010,
-0x7f7b400c,
-0xcf41217c,
-0xcfc1217d,
-0xcc01217e,
-0xc03a0004,
-0x0434217f,
-0x7f7b400c,
-0xcc350000,
-0xc83c0004,
-0x2bfc001f,
-0x04380020,
-0x97c00005,
-0xcc000062,
-0x9b800000,
-0x0bb80001,
-0x80000247,
-0xcc000071,
-0xcc01a1f4,
-0x04380016,
-0xc0360002,
-0xcf81a2a4,
-0x88000000,
-0xcf412010,
-0x7c40c000,
-0x28d0001c,
-0x95000005,
-0x04d40001,
-0xcd400065,
-0x80000003,
-0xcd400068,
-0x09540002,
-0x80000003,
-0xcd400066,
-0x8400026c,
-0xc81803ea,
-0x7c40c000,
-0x9980fd9f,
-0xc8140016,
-0x08d00001,
-0x9940002b,
-0xcd000068,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x043c0005,
-0xcfc1a2a4,
-0xcc01a1f4,
-0x84000381,
-0xcc000046,
-0x88000000,
-0xcc00007f,
-0x8400027e,
-0xc81803ea,
-0x7c40c000,
-0x9980fd8d,
-0xc8140016,
-0x08d00001,
-0x99400019,
-0xcd000068,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x043c0022,
-0xcfc1a2a4,
-0x84000381,
-0xcc000047,
-0x88000000,
-0xcc00007f,
-0xc8100016,
-0x9900000d,
-0xcc400067,
-0x80000004,
-0x7c408000,
-0xc81803ea,
-0x9980fd79,
-0x7c40c000,
-0x94c00003,
-0xc8100016,
-0x99000004,
-0xccc00068,
-0x80000004,
-0x7c408000,
-0x8400023b,
-0xc0148000,
-0xcc000041,
-0xcd41304a,
-0xc0148000,
-0x99000000,
-0xc8100016,
-0x80000004,
-0x7c408000,
-0xc0120001,
-0x7c51400c,
-0x80000003,
-0xd0550000,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0x291c001f,
-0xccc0004a,
-0xcd00004b,
-0x95c00003,
-0xc01c8000,
-0xcdc12010,
-0xdd830000,
-0x055c2000,
-0xcc000062,
-0x80000003,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc0004c,
-0xcd00004d,
-0xdd830000,
-0x055ca000,
-0x80000003,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc0004e,
-0xcd00004f,
-0xdd830000,
-0x055cc000,
-0x80000003,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00050,
-0xcd000051,
-0xdd830000,
-0x055cf8e0,
-0x80000003,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00052,
-0xcd000053,
-0xdd830000,
-0x055cf880,
-0x80000003,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00054,
-0xcd000055,
-0xdd830000,
-0x055ce000,
-0x80000003,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00056,
-0xcd000057,
-0xdd830000,
-0x055cf000,
-0x80000003,
-0xd81f4100,
-0x7c40c000,
-0x7c410000,
-0x7c414000,
-0x7c418000,
-0xccc00058,
-0xcd000059,
-0xdd830000,
-0x055cf3fc,
-0x80000003,
-0xd81f4100,
-0xd0432000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043a000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043c000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f8e0,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f880,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043e000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xd043f3fc,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xc81403e0,
-0xcc430000,
-0xcc430000,
-0xcc430000,
-0x7d45c000,
-0xcdc30000,
-0xd0430000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0x7c40c000,
-0xc81003e2,
-0xc81403e5,
-0xc81803e3,
-0xc81c03e4,
-0xcd812169,
-0xcdc1216a,
-0xccc1216b,
-0xcc01216c,
-0x04200004,
-0x7da18000,
-0x7d964002,
-0x9640fcd9,
-0xcd8003e3,
-0x31280003,
-0xc02df000,
-0x25180008,
-0x7dad800b,
-0x7da9800c,
-0x80000003,
-0xcd8003e3,
-0x308cffff,
-0xd04d0000,
-0x7c408000,
-0xa0000000,
-0xcc800062,
-0xc8140020,
-0x15580002,
-0x9580ffff,
-0xc8140020,
-0xcc00006e,
-0xcc412180,
-0x7c40c000,
-0xccc1218d,
-0xcc412181,
-0x28d0001f,
-0x34588000,
-0xcd81218c,
-0x9500fcbf,
-0xcc412182,
-0xc8140020,
-0x9940ffff,
-0xc8140020,
-0x80000004,
-0x7c408000,
-0x7c40c000,
-0x28d00018,
-0x31100001,
-0xc0160080,
-0x95000003,
-0xc02a0004,
-0x7cd4c00c,
-0xccc1217c,
-0xcc41217d,
-0xcc41217e,
-0x7c418000,
-0x1db00003,
-0x36a0217f,
-0x9b000003,
-0x419c0005,
-0x041c0040,
-0x99c00000,
-0x09dc0001,
-0xcc210000,
-0xc8240004,
-0x2a6c001f,
-0x419c0005,
-0x9ac0fffa,
-0xcc800062,
-0x80000004,
-0x7c408000,
-0x7c40c000,
-0x04d403e6,
-0x80000003,
-0xcc540000,
-0x8000037e,
-0xcc4003ea,
-0xc01c8000,
-0x044ca000,
-0xcdc12010,
-0x7c410000,
-0xc8140009,
-0x04180000,
-0x041c0008,
-0xcd800071,
-0x09dc0001,
-0x05980001,
-0xcd0d0000,
-0x99c0fffc,
-0xcc800062,
-0x8000037e,
-0xcd400071,
-0xc00e0100,
-0xcc000041,
-0xccc1304a,
-0xc83c007f,
-0xcc00007f,
-0x80000003,
-0xcc00007f,
-0xcc00007f,
-0x88000000,
-0xcc00007f,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00000000,
-0x00010333,
-0x00100006,
-0x00170008,
-0x0021000a,
-0x0027002a,
-0x00280025,
-0x0029002b,
-0x002a0028,
-0x002b002b,
-0x002d003a,
-0x002e0041,
-0x002f004c,
-0x0034004e,
-0x00360032,
-0x003900b1,
-0x003a00d1,
-0x003b00e6,
-0x003c00fe,
-0x003d016d,
-0x003f00af,
-0x00410338,
-0x0043034b,
-0x00440190,
-0x004500fe,
-0x004601ae,
-0x004701ae,
-0x00480200,
-0x0049020e,
-0x004a0257,
-0x004b0284,
-0x00520261,
-0x00530273,
-0x00540289,
-0x0057029b,
-0x0060029f,
-0x006102ae,
-0x006202b8,
-0x006302c2,
-0x006402cc,
-0x006502d6,
-0x006602e0,
-0x006702ea,
-0x006802f4,
-0x006902f8,
-0x006a02fc,
-0x006b0300,
-0x006c0304,
-0x006d0308,
-0x006e030c,
-0x006f0310,
-0x00700314,
-0x00720365,
-0x0074036b,
-0x00790369,
-0x007c031e,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-0x000f037a,
-};
-
-#endif
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
new file mode 100644
index 0000000..4a9028a
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -0,0 +1,662 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef R600D_H
+#define R600D_H
+
+#define CP_PACKET2			0x80000000
+#define		PACKET2_PAD_SHIFT		0
+#define		PACKET2_PAD_MASK		(0x3fffffff << 0)
+
+#define PACKET2(v)	(CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+
+#define R6XX_MAX_SH_GPRS			256
+#define R6XX_MAX_TEMP_GPRS			16
+#define R6XX_MAX_SH_THREADS			256
+#define R6XX_MAX_SH_STACK_ENTRIES		4096
+#define R6XX_MAX_BACKENDS			8
+#define R6XX_MAX_BACKENDS_MASK			0xff
+#define R6XX_MAX_SIMDS				8
+#define R6XX_MAX_SIMDS_MASK			0xff
+#define R6XX_MAX_PIPES				8
+#define R6XX_MAX_PIPES_MASK			0xff
+
+/* PTE flags */
+#define PTE_VALID				(1 << 0)
+#define PTE_SYSTEM				(1 << 1)
+#define PTE_SNOOPED				(1 << 2)
+#define PTE_READABLE				(1 << 5)
+#define PTE_WRITEABLE				(1 << 6)
+
+/* Registers */
+#define	ARB_POP						0x2418
+#define 	ENABLE_TC128					(1 << 30)
+#define	ARB_GDEC_RD_CNTL				0x246C
+
+#define	CC_GC_SHADER_PIPE_CONFIG			0x8950
+#define	CC_RB_BACKEND_DISABLE				0x98F4
+#define		BACKEND_DISABLE(x)				((x) << 16)
+
+#define	CB_COLOR0_BASE					0x28040
+#define	CB_COLOR1_BASE					0x28044
+#define	CB_COLOR2_BASE					0x28048
+#define	CB_COLOR3_BASE					0x2804C
+#define	CB_COLOR4_BASE					0x28050
+#define	CB_COLOR5_BASE					0x28054
+#define	CB_COLOR6_BASE					0x28058
+#define	CB_COLOR7_BASE					0x2805C
+#define	CB_COLOR7_FRAG					0x280FC
+
+#define CB_COLOR0_SIZE                                  0x28060
+#define CB_COLOR0_VIEW                                  0x28080
+#define CB_COLOR0_INFO                                  0x280a0
+#define CB_COLOR0_TILE                                  0x280c0
+#define CB_COLOR0_FRAG                                  0x280e0
+#define CB_COLOR0_MASK                                  0x28100
+
+#define	CONFIG_MEMSIZE					0x5428
+#define CONFIG_CNTL					0x5424
+#define	CP_STAT						0x8680
+#define	CP_COHER_BASE					0x85F8
+#define	CP_DEBUG					0xC1FC
+#define	R_0086D8_CP_ME_CNTL			0x86D8
+#define		S_0086D8_CP_ME_HALT(x)			(((x) & 1)<<28)
+#define		C_0086D8_CP_ME_HALT(x)			((x) & 0xEFFFFFFF)
+#define	CP_ME_RAM_DATA					0xC160
+#define	CP_ME_RAM_RADDR					0xC158
+#define	CP_ME_RAM_WADDR					0xC15C
+#define CP_MEQ_THRESHOLDS				0x8764
+#define		MEQ_END(x)					((x) << 16)
+#define		ROQ_END(x)					((x) << 24)
+#define	CP_PERFMON_CNTL					0x87FC
+#define	CP_PFP_UCODE_ADDR				0xC150
+#define	CP_PFP_UCODE_DATA				0xC154
+#define	CP_QUEUE_THRESHOLDS				0x8760
+#define		ROQ_IB1_START(x)				((x) << 0)
+#define		ROQ_IB2_START(x)				((x) << 8)
+#define	CP_RB_BASE					0xC100
+#define	CP_RB_CNTL					0xC104
+#define		RB_BUFSZ(x)					((x)<<0)
+#define		RB_BLKSZ(x)					((x)<<8)
+#define		RB_NO_UPDATE					(1<<27)
+#define		RB_RPTR_WR_ENA					(1<<31)
+#define		BUF_SWAP_32BIT					(2 << 16)
+#define	CP_RB_RPTR					0x8700
+#define	CP_RB_RPTR_ADDR					0xC10C
+#define	CP_RB_RPTR_ADDR_HI				0xC110
+#define	CP_RB_RPTR_WR					0xC108
+#define	CP_RB_WPTR					0xC114
+#define	CP_RB_WPTR_ADDR					0xC118
+#define	CP_RB_WPTR_ADDR_HI				0xC11C
+#define	CP_RB_WPTR_DELAY				0x8704
+#define	CP_ROQ_IB1_STAT					0x8784
+#define	CP_ROQ_IB2_STAT					0x8788
+#define	CP_SEM_WAIT_TIMER				0x85BC
+
+#define	DB_DEBUG					0x9830
+#define		PREZ_MUST_WAIT_FOR_POSTZ_DONE			(1 << 31)
+#define	DB_DEPTH_BASE					0x2800C
+#define	DB_WATERMARKS					0x9838
+#define		DEPTH_FREE(x)					((x) << 0)
+#define		DEPTH_FLUSH(x)					((x) << 5)
+#define		DEPTH_PENDING_FREE(x)				((x) << 15)
+#define		DEPTH_CACHELINE_FREE(x)				((x) << 20)
+
+#define	DCP_TILING_CONFIG				0x6CA0
+#define		PIPE_TILING(x)					((x) << 1)
+#define 	BANK_TILING(x)					((x) << 4)
+#define		GROUP_SIZE(x)					((x) << 6)
+#define		ROW_TILING(x)					((x) << 8)
+#define		BANK_SWAPS(x)					((x) << 11)
+#define		SAMPLE_SPLIT(x)					((x) << 14)
+#define		BACKEND_MAP(x)					((x) << 16)
+
+#define GB_TILING_CONFIG				0x98F0
+
+#define	GC_USER_SHADER_PIPE_CONFIG			0x8954
+#define		INACTIVE_QD_PIPES(x)				((x) << 8)
+#define		INACTIVE_QD_PIPES_MASK				0x0000FF00
+#define		INACTIVE_SIMDS(x)				((x) << 16)
+#define		INACTIVE_SIMDS_MASK				0x00FF0000
+
+#define SQ_CONFIG                                         0x8c00
+#       define VC_ENABLE                                  (1 << 0)
+#       define EXPORT_SRC_C                               (1 << 1)
+#       define DX9_CONSTS                                 (1 << 2)
+#       define ALU_INST_PREFER_VECTOR                     (1 << 3)
+#       define DX10_CLAMP                                 (1 << 4)
+#       define CLAUSE_SEQ_PRIO(x)                         ((x) << 8)
+#       define PS_PRIO(x)                                 ((x) << 24)
+#       define VS_PRIO(x)                                 ((x) << 26)
+#       define GS_PRIO(x)                                 ((x) << 28)
+#       define ES_PRIO(x)                                 ((x) << 30)
+#define SQ_GPR_RESOURCE_MGMT_1                            0x8c04
+#       define NUM_PS_GPRS(x)                             ((x) << 0)
+#       define NUM_VS_GPRS(x)                             ((x) << 16)
+#       define NUM_CLAUSE_TEMP_GPRS(x)                    ((x) << 28)
+#define SQ_GPR_RESOURCE_MGMT_2                            0x8c08
+#       define NUM_GS_GPRS(x)                             ((x) << 0)
+#       define NUM_ES_GPRS(x)                             ((x) << 16)
+#define SQ_THREAD_RESOURCE_MGMT                           0x8c0c
+#       define NUM_PS_THREADS(x)                          ((x) << 0)
+#       define NUM_VS_THREADS(x)                          ((x) << 8)
+#       define NUM_GS_THREADS(x)                          ((x) << 16)
+#       define NUM_ES_THREADS(x)                          ((x) << 24)
+#define SQ_STACK_RESOURCE_MGMT_1                          0x8c10
+#       define NUM_PS_STACK_ENTRIES(x)                    ((x) << 0)
+#       define NUM_VS_STACK_ENTRIES(x)                    ((x) << 16)
+#define SQ_STACK_RESOURCE_MGMT_2                          0x8c14
+#       define NUM_GS_STACK_ENTRIES(x)                    ((x) << 0)
+#       define NUM_ES_STACK_ENTRIES(x)                    ((x) << 16)
+
+#define GRBM_CNTL                                       0x8000
+#       define GRBM_READ_TIMEOUT(x)                     ((x) << 0)
+#define	GRBM_STATUS					0x8010
+#define		CMDFIFO_AVAIL_MASK				0x0000001F
+#define		GUI_ACTIVE					(1<<31)
+#define	GRBM_STATUS2					0x8014
+#define	GRBM_SOFT_RESET					0x8020
+#define		SOFT_RESET_CP					(1<<0)
+
+#define	HDP_HOST_PATH_CNTL				0x2C00
+#define	HDP_NONSURFACE_BASE				0x2C04
+#define	HDP_NONSURFACE_INFO				0x2C08
+#define	HDP_NONSURFACE_SIZE				0x2C0C
+#define HDP_REG_COHERENCY_FLUSH_CNTL			0x54A0
+#define	HDP_TILING_CONFIG				0x2F3C
+
+#define MC_VM_AGP_TOP					0x2184
+#define MC_VM_AGP_BOT					0x2188
+#define	MC_VM_AGP_BASE					0x218C
+#define MC_VM_FB_LOCATION				0x2180
+#define MC_VM_L1_TLB_MCD_RD_A_CNTL			0x219C
+#define 	ENABLE_L1_TLB					(1 << 0)
+#define		ENABLE_L1_FRAGMENT_PROCESSING			(1 << 1)
+#define		ENABLE_L1_STRICT_ORDERING			(1 << 2)
+#define		SYSTEM_ACCESS_MODE_MASK				0x000000C0
+#define		SYSTEM_ACCESS_MODE_SHIFT			6
+#define		SYSTEM_ACCESS_MODE_PA_ONLY			(0 << 6)
+#define		SYSTEM_ACCESS_MODE_USE_SYS_MAP			(1 << 6)
+#define		SYSTEM_ACCESS_MODE_IN_SYS			(2 << 6)
+#define		SYSTEM_ACCESS_MODE_NOT_IN_SYS			(3 << 6)
+#define		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU	(0 << 8)
+#define		SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE	(1 << 8)
+#define		ENABLE_SEMAPHORE_MODE				(1 << 10)
+#define		ENABLE_WAIT_L2_QUERY				(1 << 11)
+#define		EFFECTIVE_L1_TLB_SIZE(x)			(((x) & 7) << 12)
+#define		EFFECTIVE_L1_TLB_SIZE_MASK			0x00007000
+#define		EFFECTIVE_L1_TLB_SIZE_SHIFT			12
+#define		EFFECTIVE_L1_QUEUE_SIZE(x)			(((x) & 7) << 15)
+#define		EFFECTIVE_L1_QUEUE_SIZE_MASK			0x00038000
+#define		EFFECTIVE_L1_QUEUE_SIZE_SHIFT			15
+#define MC_VM_L1_TLB_MCD_RD_B_CNTL			0x21A0
+#define MC_VM_L1_TLB_MCB_RD_GFX_CNTL			0x21FC
+#define MC_VM_L1_TLB_MCB_RD_HDP_CNTL			0x2204
+#define MC_VM_L1_TLB_MCB_RD_PDMA_CNTL			0x2208
+#define MC_VM_L1_TLB_MCB_RD_SEM_CNTL			0x220C
+#define	MC_VM_L1_TLB_MCB_RD_SYS_CNTL			0x2200
+#define MC_VM_L1_TLB_MCD_WR_A_CNTL			0x21A4
+#define MC_VM_L1_TLB_MCD_WR_B_CNTL			0x21A8
+#define MC_VM_L1_TLB_MCB_WR_GFX_CNTL			0x2210
+#define MC_VM_L1_TLB_MCB_WR_HDP_CNTL			0x2218
+#define MC_VM_L1_TLB_MCB_WR_PDMA_CNTL			0x221C
+#define MC_VM_L1_TLB_MCB_WR_SEM_CNTL			0x2220
+#define MC_VM_L1_TLB_MCB_WR_SYS_CNTL			0x2214
+#define MC_VM_SYSTEM_APERTURE_LOW_ADDR			0x2190
+#define		LOGICAL_PAGE_NUMBER_MASK			0x000FFFFF
+#define		LOGICAL_PAGE_NUMBER_SHIFT			0
+#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR			0x2194
+#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR		0x2198
+
+#define	PA_CL_ENHANCE					0x8A14
+#define		CLIP_VTX_REORDER_ENA				(1 << 0)
+#define		NUM_CLIP_SEQ(x)					((x) << 1)
+#define PA_SC_AA_CONFIG					0x28C04
+#define	PA_SC_AA_SAMPLE_LOCS_2S				0x8B40
+#define	PA_SC_AA_SAMPLE_LOCS_4S				0x8B44
+#define	PA_SC_AA_SAMPLE_LOCS_8S_WD0			0x8B48
+#define	PA_SC_AA_SAMPLE_LOCS_8S_WD1			0x8B4C
+#define		S0_X(x)						((x) << 0)
+#define		S0_Y(x)						((x) << 4)
+#define		S1_X(x)						((x) << 8)
+#define		S1_Y(x)						((x) << 12)
+#define		S2_X(x)						((x) << 16)
+#define		S2_Y(x)						((x) << 20)
+#define		S3_X(x)						((x) << 24)
+#define		S3_Y(x)						((x) << 28)
+#define		S4_X(x)						((x) << 0)
+#define		S4_Y(x)						((x) << 4)
+#define		S5_X(x)						((x) << 8)
+#define		S5_Y(x)						((x) << 12)
+#define		S6_X(x)						((x) << 16)
+#define		S6_Y(x)						((x) << 20)
+#define		S7_X(x)						((x) << 24)
+#define		S7_Y(x)						((x) << 28)
+#define PA_SC_CLIPRECT_RULE				0x2820c
+#define	PA_SC_ENHANCE					0x8BF0
+#define		FORCE_EOV_MAX_CLK_CNT(x)			((x) << 0)
+#define		FORCE_EOV_MAX_TILE_CNT(x)			((x) << 12)
+#define PA_SC_LINE_STIPPLE				0x28A0C
+#define	PA_SC_LINE_STIPPLE_STATE			0x8B10
+#define PA_SC_MODE_CNTL					0x28A4C
+#define	PA_SC_MULTI_CHIP_CNTL				0x8B20
+
+#define PA_SC_SCREEN_SCISSOR_TL                         0x28030
+#define PA_SC_GENERIC_SCISSOR_TL                        0x28240
+#define PA_SC_WINDOW_SCISSOR_TL                         0x28204
+
+#define	PCIE_PORT_INDEX					0x0038
+#define	PCIE_PORT_DATA					0x003C
+
+#define RAMCFG						0x2408
+#define		NOOFBANK_SHIFT					0
+#define		NOOFBANK_MASK					0x00000001
+#define		NOOFRANK_SHIFT					1
+#define		NOOFRANK_MASK					0x00000002
+#define		NOOFROWS_SHIFT					2
+#define		NOOFROWS_MASK					0x0000001C
+#define		NOOFCOLS_SHIFT					5
+#define		NOOFCOLS_MASK					0x00000060
+#define		CHANSIZE_SHIFT					7
+#define		CHANSIZE_MASK					0x00000080
+#define		BURSTLENGTH_SHIFT				8
+#define		BURSTLENGTH_MASK				0x00000100
+#define		CHANSIZE_OVERRIDE				(1 << 10)
+
+#define	SCRATCH_REG0					0x8500
+#define	SCRATCH_REG1					0x8504
+#define	SCRATCH_REG2					0x8508
+#define	SCRATCH_REG3					0x850C
+#define	SCRATCH_REG4					0x8510
+#define	SCRATCH_REG5					0x8514
+#define	SCRATCH_REG6					0x8518
+#define	SCRATCH_REG7					0x851C
+#define	SCRATCH_UMSK					0x8540
+#define	SCRATCH_ADDR					0x8544
+
+#define	SPI_CONFIG_CNTL					0x9100
+#define		GPR_WRITE_PRIORITY(x)				((x) << 0)
+#define		DISABLE_INTERP_1				(1 << 5)
+#define	SPI_CONFIG_CNTL_1				0x913C
+#define		VTX_DONE_DELAY(x)				((x) << 0)
+#define		INTERP_ONE_PRIM_PER_ROW				(1 << 4)
+#define	SPI_INPUT_Z					0x286D8
+#define	SPI_PS_IN_CONTROL_0				0x286CC
+#define		NUM_INTERP(x)					((x)<<0)
+#define		POSITION_ENA					(1<<8)
+#define		POSITION_CENTROID				(1<<9)
+#define		POSITION_ADDR(x)				((x)<<10)
+#define		PARAM_GEN(x)					((x)<<15)
+#define		PARAM_GEN_ADDR(x)				((x)<<19)
+#define		BARYC_SAMPLE_CNTL(x)				((x)<<26)
+#define		PERSP_GRADIENT_ENA				(1<<28)
+#define		LINEAR_GRADIENT_ENA				(1<<29)
+#define		POSITION_SAMPLE					(1<<30)
+#define		BARYC_AT_SAMPLE_ENA				(1<<31)
+#define	SPI_PS_IN_CONTROL_1				0x286D0
+#define		GEN_INDEX_PIX					(1<<0)
+#define		GEN_INDEX_PIX_ADDR(x)				((x)<<1)
+#define		FRONT_FACE_ENA					(1<<8)
+#define		FRONT_FACE_CHAN(x)				((x)<<9)
+#define		FRONT_FACE_ALL_BITS				(1<<11)
+#define		FRONT_FACE_ADDR(x)				((x)<<12)
+#define		FOG_ADDR(x)					((x)<<17)
+#define		FIXED_PT_POSITION_ENA				(1<<24)
+#define		FIXED_PT_POSITION_ADDR(x)			((x)<<25)
+
+#define	SQ_MS_FIFO_SIZES				0x8CF0
+#define		CACHE_FIFO_SIZE(x)				((x) << 0)
+#define		FETCH_FIFO_HIWATER(x)				((x) << 8)
+#define		DONE_FIFO_HIWATER(x)				((x) << 16)
+#define		ALU_UPDATE_FIFO_HIWATER(x)			((x) << 24)
+#define	SQ_PGM_START_ES					0x28880
+#define	SQ_PGM_START_FS					0x28894
+#define	SQ_PGM_START_GS					0x2886C
+#define	SQ_PGM_START_PS					0x28840
+#define SQ_PGM_RESOURCES_PS                             0x28850
+#define SQ_PGM_EXPORTS_PS                               0x28854
+#define SQ_PGM_CF_OFFSET_PS                             0x288cc
+#define	SQ_PGM_START_VS					0x28858
+#define SQ_PGM_RESOURCES_VS                             0x28868
+#define SQ_PGM_CF_OFFSET_VS                             0x288d0
+#define	SQ_VTX_CONSTANT_WORD6_0				0x38018
+#define		S__SQ_VTX_CONSTANT_TYPE(x)			(((x) & 3) << 30)
+#define		G__SQ_VTX_CONSTANT_TYPE(x)			(((x) >> 30) & 3)
+#define			SQ_TEX_VTX_INVALID_TEXTURE			0x0
+#define			SQ_TEX_VTX_INVALID_BUFFER			0x1
+#define			SQ_TEX_VTX_VALID_TEXTURE			0x2
+#define			SQ_TEX_VTX_VALID_BUFFER				0x3
+
+
+#define	SX_MISC						0x28350
+#define	SX_DEBUG_1					0x9054
+#define		SMX_EVENT_RELEASE				(1 << 0)
+#define		ENABLE_NEW_SMX_ADDRESS				(1 << 16)
+
+#define	TA_CNTL_AUX					0x9508
+#define		DISABLE_CUBE_WRAP				(1 << 0)
+#define		DISABLE_CUBE_ANISO				(1 << 1)
+#define		SYNC_GRADIENT					(1 << 24)
+#define		SYNC_WALKER					(1 << 25)
+#define		SYNC_ALIGNER					(1 << 26)
+#define		BILINEAR_PRECISION_6_BIT			(0 << 31)
+#define		BILINEAR_PRECISION_8_BIT			(1 << 31)
+
+#define	TC_CNTL						0x9608
+#define		TC_L2_SIZE(x)					((x)<<5)
+#define		L2_DISABLE_LATE_HIT				(1<<9)
+
+
+#define	VGT_CACHE_INVALIDATION				0x88C4
+#define		CACHE_INVALIDATION(x)				((x)<<0)
+#define			VC_ONLY						0
+#define			TC_ONLY						1
+#define			VC_AND_TC					2
+#define	VGT_DMA_BASE					0x287E8
+#define	VGT_DMA_BASE_HI					0x287E4
+#define	VGT_ES_PER_GS					0x88CC
+#define	VGT_GS_PER_ES					0x88C8
+#define	VGT_GS_PER_VS					0x88E8
+#define	VGT_GS_VERTEX_REUSE				0x88D4
+#define VGT_PRIMITIVE_TYPE                              0x8958
+#define	VGT_NUM_INSTANCES				0x8974
+#define	VGT_OUT_DEALLOC_CNTL				0x28C5C
+#define		DEALLOC_DIST_MASK				0x0000007F
+#define	VGT_STRMOUT_BASE_OFFSET_0			0x28B10
+#define	VGT_STRMOUT_BASE_OFFSET_1			0x28B14
+#define	VGT_STRMOUT_BASE_OFFSET_2			0x28B18
+#define	VGT_STRMOUT_BASE_OFFSET_3			0x28B1c
+#define	VGT_STRMOUT_BASE_OFFSET_HI_0			0x28B44
+#define	VGT_STRMOUT_BASE_OFFSET_HI_1			0x28B48
+#define	VGT_STRMOUT_BASE_OFFSET_HI_2			0x28B4c
+#define	VGT_STRMOUT_BASE_OFFSET_HI_3			0x28B50
+#define	VGT_STRMOUT_BUFFER_BASE_0			0x28AD8
+#define	VGT_STRMOUT_BUFFER_BASE_1			0x28AE8
+#define	VGT_STRMOUT_BUFFER_BASE_2			0x28AF8
+#define	VGT_STRMOUT_BUFFER_BASE_3			0x28B08
+#define	VGT_STRMOUT_BUFFER_OFFSET_0			0x28ADC
+#define	VGT_STRMOUT_BUFFER_OFFSET_1			0x28AEC
+#define	VGT_STRMOUT_BUFFER_OFFSET_2			0x28AFC
+#define	VGT_STRMOUT_BUFFER_OFFSET_3			0x28B0C
+#define	VGT_STRMOUT_EN					0x28AB0
+#define	VGT_VERTEX_REUSE_BLOCK_CNTL			0x28C58
+#define		VTX_REUSE_DEPTH_MASK				0x000000FF
+#define VGT_EVENT_INITIATOR                             0x28a90
+#       define CACHE_FLUSH_AND_INV_EVENT                        (0x16 << 0)
+
+#define VM_CONTEXT0_CNTL				0x1410
+#define		ENABLE_CONTEXT					(1 << 0)
+#define		PAGE_TABLE_DEPTH(x)				(((x) & 3) << 1)
+#define		RANGE_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 4)
+#define VM_CONTEXT0_INVALIDATION_LOW_ADDR		0x1490
+#define VM_CONTEXT0_INVALIDATION_HIGH_ADDR		0x14B0
+#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR		0x1574
+#define VM_CONTEXT0_PAGE_TABLE_START_ADDR		0x1594
+#define VM_CONTEXT0_PAGE_TABLE_END_ADDR			0x15B4
+#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR	0x1554
+#define VM_CONTEXT0_REQUEST_RESPONSE			0x1470
+#define		REQUEST_TYPE(x)					(((x) & 0xf) << 0)
+#define		RESPONSE_TYPE_MASK				0x000000F0
+#define		RESPONSE_TYPE_SHIFT				4
+#define VM_L2_CNTL					0x1400
+#define		ENABLE_L2_CACHE					(1 << 0)
+#define		ENABLE_L2_FRAGMENT_PROCESSING			(1 << 1)
+#define		ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE		(1 << 9)
+#define		EFFECTIVE_L2_QUEUE_SIZE(x)			(((x) & 7) << 13)
+#define VM_L2_CNTL2					0x1404
+#define		INVALIDATE_ALL_L1_TLBS				(1 << 0)
+#define		INVALIDATE_L2_CACHE				(1 << 1)
+#define VM_L2_CNTL3					0x1408
+#define		BANK_SELECT_0(x)				(((x) & 0x1f) << 0)
+#define		BANK_SELECT_1(x)				(((x) & 0x1f) << 5)
+#define		L2_CACHE_UPDATE_MODE(x)				(((x) & 3) << 10)
+#define	VM_L2_STATUS					0x140C
+#define		L2_BUSY						(1 << 0)
+
+#define	WAIT_UNTIL					0x8040
+#define         WAIT_2D_IDLE_bit                                (1 << 14)
+#define         WAIT_3D_IDLE_bit                                (1 << 15)
+#define         WAIT_2D_IDLECLEAN_bit                           (1 << 16)
+#define         WAIT_3D_IDLECLEAN_bit                           (1 << 17)
+
+
+
+/*
+ * PM4
+ */
+#define	PACKET_TYPE0	0
+#define	PACKET_TYPE1	1
+#define	PACKET_TYPE2	2
+#define	PACKET_TYPE3	3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+#define PACKET0(reg, n)	((PACKET_TYPE0 << 30) |				\
+			 (((reg) >> 2) & 0xFFFF) |			\
+			 ((n) & 0x3FFF) << 16)
+#define PACKET3(op, n)	((PACKET_TYPE3 << 30) |				\
+			 (((op) & 0xFF) << 8) |				\
+			 ((n) & 0x3FFF) << 16)
+
+/* Packet 3 types */
+#define	PACKET3_NOP					0x10
+#define	PACKET3_INDIRECT_BUFFER_END			0x17
+#define	PACKET3_SET_PREDICATION				0x20
+#define	PACKET3_REG_RMW					0x21
+#define	PACKET3_COND_EXEC				0x22
+#define	PACKET3_PRED_EXEC				0x23
+#define	PACKET3_START_3D_CMDBUF				0x24
+#define	PACKET3_DRAW_INDEX_2				0x27
+#define	PACKET3_CONTEXT_CONTROL				0x28
+#define	PACKET3_DRAW_INDEX_IMMD_BE			0x29
+#define	PACKET3_INDEX_TYPE				0x2A
+#define	PACKET3_DRAW_INDEX				0x2B
+#define	PACKET3_DRAW_INDEX_AUTO				0x2D
+#define	PACKET3_DRAW_INDEX_IMMD				0x2E
+#define	PACKET3_NUM_INSTANCES				0x2F
+#define	PACKET3_STRMOUT_BUFFER_UPDATE			0x34
+#define	PACKET3_INDIRECT_BUFFER_MP			0x38
+#define	PACKET3_MEM_SEMAPHORE				0x39
+#define	PACKET3_MPEG_INDEX				0x3A
+#define	PACKET3_WAIT_REG_MEM				0x3C
+#define	PACKET3_MEM_WRITE				0x3D
+#define	PACKET3_INDIRECT_BUFFER				0x32
+#define	PACKET3_CP_INTERRUPT				0x40
+#define	PACKET3_SURFACE_SYNC				0x43
+#              define PACKET3_CB0_DEST_BASE_ENA    (1 << 6)
+#              define PACKET3_TC_ACTION_ENA        (1 << 23)
+#              define PACKET3_VC_ACTION_ENA        (1 << 24)
+#              define PACKET3_CB_ACTION_ENA        (1 << 25)
+#              define PACKET3_DB_ACTION_ENA        (1 << 26)
+#              define PACKET3_SH_ACTION_ENA        (1 << 27)
+#              define PACKET3_SMX_ACTION_ENA       (1 << 28)
+#define	PACKET3_ME_INITIALIZE				0x44
+#define		PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
+#define	PACKET3_COND_WRITE				0x45
+#define	PACKET3_EVENT_WRITE				0x46
+#define	PACKET3_EVENT_WRITE_EOP				0x47
+#define	PACKET3_ONE_REG_WRITE				0x57
+#define	PACKET3_SET_CONFIG_REG				0x68
+#define		PACKET3_SET_CONFIG_REG_OFFSET			0x00008000
+#define		PACKET3_SET_CONFIG_REG_END			0x0000ac00
+#define	PACKET3_SET_CONTEXT_REG				0x69
+#define		PACKET3_SET_CONTEXT_REG_OFFSET			0x00028000
+#define		PACKET3_SET_CONTEXT_REG_END			0x00029000
+#define	PACKET3_SET_ALU_CONST				0x6A
+#define		PACKET3_SET_ALU_CONST_OFFSET			0x00030000
+#define		PACKET3_SET_ALU_CONST_END			0x00032000
+#define	PACKET3_SET_BOOL_CONST				0x6B
+#define		PACKET3_SET_BOOL_CONST_OFFSET			0x0003e380
+#define		PACKET3_SET_BOOL_CONST_END			0x00040000
+#define	PACKET3_SET_LOOP_CONST				0x6C
+#define		PACKET3_SET_LOOP_CONST_OFFSET			0x0003e200
+#define		PACKET3_SET_LOOP_CONST_END			0x0003e380
+#define	PACKET3_SET_RESOURCE				0x6D
+#define		PACKET3_SET_RESOURCE_OFFSET			0x00038000
+#define		PACKET3_SET_RESOURCE_END			0x0003c000
+#define	PACKET3_SET_SAMPLER				0x6E
+#define		PACKET3_SET_SAMPLER_OFFSET			0x0003c000
+#define		PACKET3_SET_SAMPLER_END				0x0003cff0
+#define	PACKET3_SET_CTL_CONST				0x6F
+#define		PACKET3_SET_CTL_CONST_OFFSET			0x0003cff0
+#define		PACKET3_SET_CTL_CONST_END			0x0003e200
+#define	PACKET3_SURFACE_BASE_UPDATE			0x73
+
+
+#define	R_008020_GRBM_SOFT_RESET		0x8020
+#define		S_008020_SOFT_RESET_CP(x)		(((x) & 1) << 0)
+#define		S_008020_SOFT_RESET_CB(x)		(((x) & 1) << 1)
+#define		S_008020_SOFT_RESET_CR(x)		(((x) & 1) << 2)
+#define		S_008020_SOFT_RESET_DB(x)		(((x) & 1) << 3)
+#define		S_008020_SOFT_RESET_PA(x)		(((x) & 1) << 5)
+#define		S_008020_SOFT_RESET_SC(x)		(((x) & 1) << 6)
+#define		S_008020_SOFT_RESET_SMX(x)		(((x) & 1) << 7)
+#define		S_008020_SOFT_RESET_SPI(x)		(((x) & 1) << 8)
+#define		S_008020_SOFT_RESET_SH(x)		(((x) & 1) << 9)
+#define		S_008020_SOFT_RESET_SX(x)		(((x) & 1) << 10)
+#define		S_008020_SOFT_RESET_TC(x)		(((x) & 1) << 11)
+#define		S_008020_SOFT_RESET_TA(x)		(((x) & 1) << 12)
+#define		S_008020_SOFT_RESET_VC(x)		(((x) & 1) << 13)
+#define		S_008020_SOFT_RESET_VGT(x)		(((x) & 1) << 14)
+#define	R_008010_GRBM_STATUS			0x8010
+#define		S_008010_CMDFIFO_AVAIL(x)		(((x) & 0x1F) << 0)
+#define		S_008010_CP_RQ_PENDING(x)		(((x) & 1) << 6)
+#define		S_008010_CF_RQ_PENDING(x)		(((x) & 1) << 7)
+#define		S_008010_PF_RQ_PENDING(x)		(((x) & 1) << 8)
+#define		S_008010_GRBM_EE_BUSY(x)		(((x) & 1) << 10)
+#define		S_008010_VC_BUSY(x)			(((x) & 1) << 11)
+#define		S_008010_DB03_CLEAN(x)			(((x) & 1) << 12)
+#define		S_008010_CB03_CLEAN(x)			(((x) & 1) << 13)
+#define		S_008010_VGT_BUSY_NO_DMA(x)		(((x) & 1) << 16)
+#define		S_008010_VGT_BUSY(x)			(((x) & 1) << 17)
+#define		S_008010_TA03_BUSY(x)			(((x) & 1) << 18)
+#define		S_008010_TC_BUSY(x)			(((x) & 1) << 19)
+#define		S_008010_SX_BUSY(x)			(((x) & 1) << 20)
+#define		S_008010_SH_BUSY(x)			(((x) & 1) << 21)
+#define		S_008010_SPI03_BUSY(x)			(((x) & 1) << 22)
+#define		S_008010_SMX_BUSY(x)			(((x) & 1) << 23)
+#define		S_008010_SC_BUSY(x)			(((x) & 1) << 24)
+#define		S_008010_PA_BUSY(x)			(((x) & 1) << 25)
+#define		S_008010_DB03_BUSY(x)			(((x) & 1) << 26)
+#define		S_008010_CR_BUSY(x)			(((x) & 1) << 27)
+#define		S_008010_CP_COHERENCY_BUSY(x)		(((x) & 1) << 28)
+#define		S_008010_CP_BUSY(x)			(((x) & 1) << 29)
+#define		S_008010_CB03_BUSY(x)			(((x) & 1) << 30)
+#define		S_008010_GUI_ACTIVE(x)			(((x) & 1) << 31)
+#define		G_008010_CMDFIFO_AVAIL(x)		(((x) >> 0) & 0x1F)
+#define		G_008010_CP_RQ_PENDING(x)		(((x) >> 6) & 1)
+#define		G_008010_CF_RQ_PENDING(x)		(((x) >> 7) & 1)
+#define		G_008010_PF_RQ_PENDING(x)		(((x) >> 8) & 1)
+#define		G_008010_GRBM_EE_BUSY(x)		(((x) >> 10) & 1)
+#define		G_008010_VC_BUSY(x)			(((x) >> 11) & 1)
+#define		G_008010_DB03_CLEAN(x)			(((x) >> 12) & 1)
+#define		G_008010_CB03_CLEAN(x)			(((x) >> 13) & 1)
+#define		G_008010_VGT_BUSY_NO_DMA(x)		(((x) >> 16) & 1)
+#define		G_008010_VGT_BUSY(x)			(((x) >> 17) & 1)
+#define		G_008010_TA03_BUSY(x)			(((x) >> 18) & 1)
+#define		G_008010_TC_BUSY(x)			(((x) >> 19) & 1)
+#define		G_008010_SX_BUSY(x)			(((x) >> 20) & 1)
+#define		G_008010_SH_BUSY(x)			(((x) >> 21) & 1)
+#define		G_008010_SPI03_BUSY(x)			(((x) >> 22) & 1)
+#define		G_008010_SMX_BUSY(x)			(((x) >> 23) & 1)
+#define		G_008010_SC_BUSY(x)			(((x) >> 24) & 1)
+#define		G_008010_PA_BUSY(x)			(((x) >> 25) & 1)
+#define		G_008010_DB03_BUSY(x)			(((x) >> 26) & 1)
+#define		G_008010_CR_BUSY(x)			(((x) >> 27) & 1)
+#define		G_008010_CP_COHERENCY_BUSY(x)		(((x) >> 28) & 1)
+#define		G_008010_CP_BUSY(x)			(((x) >> 29) & 1)
+#define		G_008010_CB03_BUSY(x)			(((x) >> 30) & 1)
+#define		G_008010_GUI_ACTIVE(x)			(((x) >> 31) & 1)
+#define	R_008014_GRBM_STATUS2			0x8014
+#define		S_008014_CR_CLEAN(x)			(((x) & 1) << 0)
+#define		S_008014_SMX_CLEAN(x)			(((x) & 1) << 1)
+#define		S_008014_SPI0_BUSY(x)			(((x) & 1) << 8)
+#define		S_008014_SPI1_BUSY(x)			(((x) & 1) << 9)
+#define		S_008014_SPI2_BUSY(x)			(((x) & 1) << 10)
+#define		S_008014_SPI3_BUSY(x)			(((x) & 1) << 11)
+#define		S_008014_TA0_BUSY(x)			(((x) & 1) << 12)
+#define		S_008014_TA1_BUSY(x)			(((x) & 1) << 13)
+#define		S_008014_TA2_BUSY(x)			(((x) & 1) << 14)
+#define		S_008014_TA3_BUSY(x)			(((x) & 1) << 15)
+#define		S_008014_DB0_BUSY(x)			(((x) & 1) << 16)
+#define		S_008014_DB1_BUSY(x)			(((x) & 1) << 17)
+#define		S_008014_DB2_BUSY(x)			(((x) & 1) << 18)
+#define		S_008014_DB3_BUSY(x)			(((x) & 1) << 19)
+#define		S_008014_CB0_BUSY(x)			(((x) & 1) << 20)
+#define		S_008014_CB1_BUSY(x)			(((x) & 1) << 21)
+#define		S_008014_CB2_BUSY(x)			(((x) & 1) << 22)
+#define		S_008014_CB3_BUSY(x)			(((x) & 1) << 23)
+#define		G_008014_CR_CLEAN(x)			(((x) >> 0) & 1)
+#define		G_008014_SMX_CLEAN(x)			(((x) >> 1) & 1)
+#define		G_008014_SPI0_BUSY(x)			(((x) >> 8) & 1)
+#define		G_008014_SPI1_BUSY(x)			(((x) >> 9) & 1)
+#define		G_008014_SPI2_BUSY(x)			(((x) >> 10) & 1)
+#define		G_008014_SPI3_BUSY(x)			(((x) >> 11) & 1)
+#define		G_008014_TA0_BUSY(x)			(((x) >> 12) & 1)
+#define		G_008014_TA1_BUSY(x)			(((x) >> 13) & 1)
+#define		G_008014_TA2_BUSY(x)			(((x) >> 14) & 1)
+#define		G_008014_TA3_BUSY(x)			(((x) >> 15) & 1)
+#define		G_008014_DB0_BUSY(x)			(((x) >> 16) & 1)
+#define		G_008014_DB1_BUSY(x)			(((x) >> 17) & 1)
+#define		G_008014_DB2_BUSY(x)			(((x) >> 18) & 1)
+#define		G_008014_DB3_BUSY(x)			(((x) >> 19) & 1)
+#define		G_008014_CB0_BUSY(x)			(((x) >> 20) & 1)
+#define		G_008014_CB1_BUSY(x)			(((x) >> 21) & 1)
+#define		G_008014_CB2_BUSY(x)			(((x) >> 22) & 1)
+#define		G_008014_CB3_BUSY(x)			(((x) >> 23) & 1)
+#define	R_000E50_SRBM_STATUS				0x0E50
+#define		G_000E50_RLC_RQ_PENDING(x)		(((x) >> 3) & 1)
+#define		G_000E50_RCU_RQ_PENDING(x)		(((x) >> 4) & 1)
+#define		G_000E50_GRBM_RQ_PENDING(x)		(((x) >> 5) & 1)
+#define		G_000E50_HI_RQ_PENDING(x)		(((x) >> 6) & 1)
+#define		G_000E50_IO_EXTERN_SIGNAL(x)		(((x) >> 7) & 1)
+#define		G_000E50_VMC_BUSY(x)			(((x) >> 8) & 1)
+#define		G_000E50_MCB_BUSY(x)			(((x) >> 9) & 1)
+#define		G_000E50_MCDZ_BUSY(x)			(((x) >> 10) & 1)
+#define		G_000E50_MCDY_BUSY(x)			(((x) >> 11) & 1)
+#define		G_000E50_MCDX_BUSY(x)			(((x) >> 12) & 1)
+#define		G_000E50_MCDW_BUSY(x)			(((x) >> 13) & 1)
+#define		G_000E50_SEM_BUSY(x)			(((x) >> 14) & 1)
+#define		G_000E50_RLC_BUSY(x)			(((x) >> 15) & 1)
+#define	R_000E60_SRBM_SOFT_RESET			0x0E60
+#define		S_000E60_SOFT_RESET_BIF(x)		(((x) & 1) << 1)
+#define		S_000E60_SOFT_RESET_CG(x)		(((x) & 1) << 2)
+#define		S_000E60_SOFT_RESET_CMC(x)		(((x) & 1) << 3)
+#define		S_000E60_SOFT_RESET_CSC(x)		(((x) & 1) << 4)
+#define		S_000E60_SOFT_RESET_DC(x)		(((x) & 1) << 5)
+#define		S_000E60_SOFT_RESET_GRBM(x)		(((x) & 1) << 8)
+#define		S_000E60_SOFT_RESET_HDP(x)		(((x) & 1) << 9)
+#define		S_000E60_SOFT_RESET_IH(x)		(((x) & 1) << 10)
+#define		S_000E60_SOFT_RESET_MC(x)		(((x) & 1) << 11)
+#define		S_000E60_SOFT_RESET_RLC(x)		(((x) & 1) << 13)
+#define		S_000E60_SOFT_RESET_ROM(x)		(((x) & 1) << 14)
+#define		S_000E60_SOFT_RESET_SEM(x)		(((x) & 1) << 15)
+#define		S_000E60_SOFT_RESET_TSC(x)		(((x) & 1) << 16)
+#define		S_000E60_SOFT_RESET_VMC(x)		(((x) & 1) << 17)
+
+#endif
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b519fb2..c839b60 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -51,7 +51,6 @@
 
 #include "radeon_mode.h"
 #include "radeon_reg.h"
-#include "r300.h"
 
 /*
  * Modules parameters.
@@ -66,6 +65,7 @@ extern int radeon_gart_size;
 extern int radeon_benchmarking;
 extern int radeon_testing;
 extern int radeon_connector_table;
+extern int radeon_tv;
 
 /*
  * Copy from radeon_drv.h so we don't have to include both and have conflicting
@@ -75,6 +75,7 @@ extern int radeon_connector_table;
 #define RADEON_IB_POOL_SIZE		16
 #define RADEON_DEBUGFS_MAX_NUM_FILES	32
 #define RADEONFB_CONN_LIMIT		4
+#define RADEON_BIOS_NUM_SCRATCH		8
 
 enum radeon_family {
 	CHIP_R100,
@@ -107,14 +108,15 @@ enum radeon_family {
 	CHIP_R600,
 	CHIP_RV610,
 	CHIP_RV630,
+	CHIP_RV670,
 	CHIP_RV620,
 	CHIP_RV635,
-	CHIP_RV670,
 	CHIP_RS780,
+	CHIP_RS880,
 	CHIP_RV770,
 	CHIP_RV730,
 	CHIP_RV710,
-	CHIP_RS880,
+	CHIP_RV740,
 	CHIP_LAST,
 };
 
@@ -151,10 +153,21 @@ struct radeon_device;
  */
 bool radeon_get_bios(struct radeon_device *rdev);
 
+
 /*
- * Clocks
+ * Dummy page
  */
+struct radeon_dummy_page {
+	struct page	*page;
+	dma_addr_t	addr;
+};
+int radeon_dummy_page_init(struct radeon_device *rdev);
+void radeon_dummy_page_fini(struct radeon_device *rdev);
+
 
+/*
+ * Clocks
+ */
 struct radeon_clock {
 	struct radeon_pll p1pll;
 	struct radeon_pll p2pll;
@@ -165,6 +178,7 @@ struct radeon_clock {
 	uint32_t default_sclk;
 };
 
+
 /*
  * Fences.
  */
@@ -331,14 +345,18 @@ struct radeon_mc {
 	resource_size_t		aper_size;
 	resource_size_t		aper_base;
 	resource_size_t		agp_base;
-	unsigned		gtt_location;
-	unsigned		gtt_size;
-	unsigned		vram_location;
 	/* for some chips with <= 32MB we need to lie
 	 * about vram size near mc fb location */
-	unsigned		mc_vram_size;
+	u64			mc_vram_size;
+	u64			gtt_location;
+	u64			gtt_size;
+	u64			gtt_start;
+	u64			gtt_end;
+	u64			vram_location;
+	u64			vram_start;
+	u64			vram_end;
 	unsigned		vram_width;
-	unsigned		real_vram_size;
+	u64			real_vram_size;
 	int			vram_mtrr;
 	bool			vram_is_ddr;
 };
@@ -385,6 +403,10 @@ struct radeon_ib {
 	uint32_t		length_dw;
 };
 
+/*
+ * locking -
+ * mutex protects scheduled_ibs, ready, alloc_bm
+ */
 struct radeon_ib_pool {
 	struct mutex		mutex;
 	struct radeon_object	*robj;
@@ -410,6 +432,16 @@ struct radeon_cp {
 	bool			ready;
 };
 
+struct r600_blit {
+	struct radeon_object	*shader_obj;
+	u64 shader_gpu_addr;
+	u32 vs_offset, ps_offset;
+	u32 state_offset;
+	u32 state_len;
+	u32 vb_used, vb_total;
+	struct radeon_ib *vb_ib;
+};
+
 int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib);
 void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib);
 int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib);
@@ -462,6 +494,7 @@ struct radeon_cs_parser {
 	int			chunk_relocs_idx;
 	struct radeon_ib	*ib;
 	void			*track;
+	unsigned		family;
 };
 
 struct radeon_cs_packet {
@@ -558,13 +591,19 @@ int r100_debugfs_cp_init(struct radeon_device *rdev);
  */
 struct radeon_asic {
 	int (*init)(struct radeon_device *rdev);
+	void (*fini)(struct radeon_device *rdev);
+	int (*resume)(struct radeon_device *rdev);
+	int (*suspend)(struct radeon_device *rdev);
 	void (*errata)(struct radeon_device *rdev);
 	void (*vram_info)(struct radeon_device *rdev);
+	void (*vga_set_state)(struct radeon_device *rdev, bool state);
 	int (*gpu_reset)(struct radeon_device *rdev);
 	int (*mc_init)(struct radeon_device *rdev);
 	void (*mc_fini)(struct radeon_device *rdev);
 	int (*wb_init)(struct radeon_device *rdev);
 	void (*wb_fini)(struct radeon_device *rdev);
+	int (*gart_init)(struct radeon_device *rdev);
+	void (*gart_fini)(struct radeon_device *rdev);
 	int (*gart_enable)(struct radeon_device *rdev);
 	void (*gart_disable)(struct radeon_device *rdev);
 	void (*gart_tlb_flush)(struct radeon_device *rdev);
@@ -572,7 +611,11 @@ struct radeon_asic {
 	int (*cp_init)(struct radeon_device *rdev, unsigned ring_size);
 	void (*cp_fini)(struct radeon_device *rdev);
 	void (*cp_disable)(struct radeon_device *rdev);
+	void (*cp_commit)(struct radeon_device *rdev);
 	void (*ring_start)(struct radeon_device *rdev);
+	int (*ring_test)(struct radeon_device *rdev);
+	void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
+	int (*ib_test)(struct radeon_device *rdev);
 	int (*irq_set)(struct radeon_device *rdev);
 	int (*irq_process)(struct radeon_device *rdev);
 	u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
@@ -604,8 +647,60 @@ struct radeon_asic {
 	void (*bandwidth_update)(struct radeon_device *rdev);
 };
 
+/*
+ * Asic structures
+ */
+struct r100_asic {
+	const unsigned	*reg_safe_bm;
+	unsigned	reg_safe_bm_size;
+};
+
+struct r300_asic {
+	const unsigned	*reg_safe_bm;
+	unsigned	reg_safe_bm_size;
+};
+
+struct r600_asic {
+	unsigned max_pipes;
+	unsigned max_tile_pipes;
+	unsigned max_simds;
+	unsigned max_backends;
+	unsigned max_gprs;
+	unsigned max_threads;
+	unsigned max_stack_entries;
+	unsigned max_hw_contexts;
+	unsigned max_gs_threads;
+	unsigned sx_max_export_size;
+	unsigned sx_max_export_pos_size;
+	unsigned sx_max_export_smx_size;
+	unsigned sq_num_cf_insts;
+};
+
+struct rv770_asic {
+	unsigned max_pipes;
+	unsigned max_tile_pipes;
+	unsigned max_simds;
+	unsigned max_backends;
+	unsigned max_gprs;
+	unsigned max_threads;
+	unsigned max_stack_entries;
+	unsigned max_hw_contexts;
+	unsigned max_gs_threads;
+	unsigned sx_max_export_size;
+	unsigned sx_max_export_pos_size;
+	unsigned sx_max_export_smx_size;
+	unsigned sq_num_cf_insts;
+	unsigned sx_num_of_sets;
+	unsigned sc_prim_fifo_size;
+	unsigned sc_hiz_tile_fifo_size;
+	unsigned sc_earlyz_tile_fifo_fize;
+};
+
 union radeon_asic_config {
 	struct r300_asic	r300;
+	struct r100_asic	r100;
+	struct r600_asic	r600;
+	struct rv770_asic	rv770;
 };
 
 
@@ -646,6 +741,7 @@ typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t);
 typedef void (*radeon_wreg_t)(struct radeon_device*, uint32_t, uint32_t);
 
 struct radeon_device {
+	struct device			*dev;
 	struct drm_device		*ddev;
 	struct pci_dev			*pdev;
 	/* ASIC */
@@ -689,13 +785,20 @@ struct radeon_device {
 	struct radeon_asic		*asic;
 	struct radeon_gem		gem;
 	struct radeon_pm		pm;
+	uint32_t			bios_scratch[RADEON_BIOS_NUM_SCRATCH];
 	struct mutex			cs_mutex;
 	struct radeon_wb		wb;
+	struct radeon_dummy_page	dummy_page;
 	bool				gpu_lockup;
 	bool				shutdown;
 	bool				suspend;
 	bool				need_dma32;
+	bool				new_init_path;
+	bool				accel_working;
 	struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
+	const struct firmware *me_fw;	/* all family ME firmware */
+	const struct firmware *pfp_fw;	/* r6/700 PFP firmware */
+	struct r600_blit r600_blit;
 };
 
 int radeon_device_init(struct radeon_device *rdev,
@@ -705,6 +808,13 @@ int radeon_device_init(struct radeon_device *rdev,
 void radeon_device_fini(struct radeon_device *rdev);
 int radeon_gpu_wait_for_idle(struct radeon_device *rdev);
 
+/* r600 blit */
+int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes);
+void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence);
+void r600_kms_blit_copy(struct radeon_device *rdev,
+			u64 src_gpu_addr, u64 dst_gpu_addr,
+			int size_bytes);
+
 static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg)
 {
 	if (reg < 0x10000)
@@ -732,6 +842,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
 #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg))
 #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg))
 #define RREG32(reg) r100_mm_rreg(rdev, (reg))
+#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg)))
 #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v))
 #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
 #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK)
@@ -755,6 +866,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32
 		tmp_ |= ((val) & ~(mask));			\
 		WREG32_PLL(reg, tmp_);				\
 	} while (0)
+#define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg)))
 
 /*
  * Indirect registers accessor
@@ -819,51 +931,6 @@ void radeon_atombios_fini(struct radeon_device *rdev);
 /*
  * RING helpers.
  */
-#define CP_PACKET0			0x00000000
-#define		PACKET0_BASE_INDEX_SHIFT	0
-#define		PACKET0_BASE_INDEX_MASK		(0x1ffff << 0)
-#define		PACKET0_COUNT_SHIFT		16
-#define		PACKET0_COUNT_MASK		(0x3fff << 16)
-#define CP_PACKET1			0x40000000
-#define CP_PACKET2			0x80000000
-#define		PACKET2_PAD_SHIFT		0
-#define		PACKET2_PAD_MASK		(0x3fffffff << 0)
-#define CP_PACKET3			0xC0000000
-#define		PACKET3_IT_OPCODE_SHIFT		8
-#define		PACKET3_IT_OPCODE_MASK		(0xff << 8)
-#define		PACKET3_COUNT_SHIFT		16
-#define		PACKET3_COUNT_MASK		(0x3fff << 16)
-/* PACKET3 op code */
-#define		PACKET3_NOP			0x10
-#define		PACKET3_3D_DRAW_VBUF		0x28
-#define		PACKET3_3D_DRAW_IMMD		0x29
-#define		PACKET3_3D_DRAW_INDX		0x2A
-#define		PACKET3_3D_LOAD_VBPNTR		0x2F
-#define		PACKET3_INDX_BUFFER		0x33
-#define		PACKET3_3D_DRAW_VBUF_2		0x34
-#define		PACKET3_3D_DRAW_IMMD_2		0x35
-#define		PACKET3_3D_DRAW_INDX_2		0x36
-#define		PACKET3_BITBLT_MULTI		0x9B
-
-#define PACKET0(reg, n)	(CP_PACKET0 |					\
-			 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) |	\
-			 REG_SET(PACKET0_COUNT, (n)))
-#define PACKET2(v)	(CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
-#define PACKET3(op, n)	(CP_PACKET3 |					\
-			 REG_SET(PACKET3_IT_OPCODE, (op)) |		\
-			 REG_SET(PACKET3_COUNT, (n)))
-
-#define	PACKET_TYPE0	0
-#define	PACKET_TYPE1	1
-#define	PACKET_TYPE2	2
-#define	PACKET_TYPE3	3
-
-#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
-#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
-#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
-#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
-#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
-
 static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
 {
 #if DRM_DEBUG_CODE
@@ -882,14 +949,20 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
  * ASICs macro.
  */
 #define radeon_init(rdev) (rdev)->asic->init((rdev))
+#define radeon_fini(rdev) (rdev)->asic->fini((rdev))
+#define radeon_resume(rdev) (rdev)->asic->resume((rdev))
+#define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
 #define radeon_cs_parse(p) rdev->asic->cs_parse((p))
 #define radeon_errata(rdev) (rdev)->asic->errata((rdev))
 #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
+#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
 #define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
 #define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
 #define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
 #define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev))
 #define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev))
+#define radeon_gpu_gart_init(rdev) (rdev)->asic->gart_init((rdev))
+#define radeon_gpu_gart_fini(rdev) (rdev)->asic->gart_fini((rdev))
 #define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev))
 #define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev))
 #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev))
@@ -897,7 +970,11 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
 #define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize))
 #define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev))
 #define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev))
+#define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev))
 #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev))
+#define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev))
+#define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib))
+#define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev))
 #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev))
 #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
 #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
@@ -913,4 +990,88 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
 #define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
 #define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev))
 
+/* Common functions */
+extern int radeon_gart_table_vram_pin(struct radeon_device *rdev);
+extern int radeon_modeset_init(struct radeon_device *rdev);
+extern void radeon_modeset_fini(struct radeon_device *rdev);
+extern bool radeon_card_posted(struct radeon_device *rdev);
+extern int radeon_clocks_init(struct radeon_device *rdev);
+extern void radeon_clocks_fini(struct radeon_device *rdev);
+extern void radeon_scratch_init(struct radeon_device *rdev);
+extern void radeon_surface_init(struct radeon_device *rdev);
+extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
+
+/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
+struct r100_mc_save {
+	u32	GENMO_WT;
+	u32	CRTC_EXT_CNTL;
+	u32	CRTC_GEN_CNTL;
+	u32	CRTC2_GEN_CNTL;
+	u32	CUR_OFFSET;
+	u32	CUR2_OFFSET;
+};
+extern void r100_cp_disable(struct radeon_device *rdev);
+extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
+extern void r100_cp_fini(struct radeon_device *rdev);
+extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
+extern int r100_pci_gart_init(struct radeon_device *rdev);
+extern void r100_pci_gart_fini(struct radeon_device *rdev);
+extern int r100_pci_gart_enable(struct radeon_device *rdev);
+extern void r100_pci_gart_disable(struct radeon_device *rdev);
+extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
+extern int r100_debugfs_mc_info_init(struct radeon_device *rdev);
+extern int r100_gui_wait_for_idle(struct radeon_device *rdev);
+extern void r100_ib_fini(struct radeon_device *rdev);
+extern int r100_ib_init(struct radeon_device *rdev);
+extern void r100_irq_disable(struct radeon_device *rdev);
+extern int r100_irq_set(struct radeon_device *rdev);
+extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
+extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
+extern void r100_vram_init_sizes(struct radeon_device *rdev);
+extern void r100_wb_disable(struct radeon_device *rdev);
+extern void r100_wb_fini(struct radeon_device *rdev);
+extern int r100_wb_init(struct radeon_device *rdev);
+
+/* r300,r350,rv350,rv370,rv380 */
+extern void r300_set_reg_safe(struct radeon_device *rdev);
+extern void r300_mc_program(struct radeon_device *rdev);
+extern void r300_vram_info(struct radeon_device *rdev);
+extern int rv370_pcie_gart_init(struct radeon_device *rdev);
+extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
+extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
+extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
+
+/* r420,r423,rv410 */
+extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg);
+extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v);
+extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
+
+/* rv515 */
+extern void rv515_bandwidth_avivo_update(struct radeon_device *rdev);
+
+/* rs690, rs740 */
+extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
+					struct drm_display_mode *mode1,
+					struct drm_display_mode *mode2);
+
+/* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */
+extern bool r600_card_posted(struct radeon_device *rdev);
+extern void r600_cp_stop(struct radeon_device *rdev);
+extern void r600_ring_init(struct radeon_device *rdev, unsigned ring_size);
+extern int r600_cp_resume(struct radeon_device *rdev);
+extern int r600_count_pipe_bits(uint32_t val);
+extern int r600_gart_clear_page(struct radeon_device *rdev, int i);
+extern int r600_mc_wait_for_idle(struct radeon_device *rdev);
+extern int r600_pcie_gart_init(struct radeon_device *rdev);
+extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
+extern int r600_ib_test(struct radeon_device *rdev);
+extern int r600_ring_test(struct radeon_device *rdev);
+extern int r600_wb_init(struct radeon_device *rdev);
+extern void r600_wb_fini(struct radeon_device *rdev);
+extern void r600_scratch_init(struct radeon_device *rdev);
+extern int r600_blit_init(struct radeon_device *rdev);
+extern void r600_blit_fini(struct radeon_device *rdev);
+extern int r600_cp_init_microcode(struct radeon_device *rdev);
+extern int r600_gpu_reset(struct radeon_device *rdev);
+
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 93d8f88..8968f78 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -42,23 +42,28 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
  * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
  */
 int r100_init(struct radeon_device *rdev);
+int r200_init(struct radeon_device *rdev);
 uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
 void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
 void r100_errata(struct radeon_device *rdev);
 void r100_vram_info(struct radeon_device *rdev);
+void r100_vga_set_state(struct radeon_device *rdev, bool state);
 int r100_gpu_reset(struct radeon_device *rdev);
 int r100_mc_init(struct radeon_device *rdev);
 void r100_mc_fini(struct radeon_device *rdev);
 u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
 int r100_wb_init(struct radeon_device *rdev);
 void r100_wb_fini(struct radeon_device *rdev);
-int r100_gart_enable(struct radeon_device *rdev);
+int r100_pci_gart_init(struct radeon_device *rdev);
+void r100_pci_gart_fini(struct radeon_device *rdev);
+int r100_pci_gart_enable(struct radeon_device *rdev);
 void r100_pci_gart_disable(struct radeon_device *rdev);
 void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
 int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
 int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
 void r100_cp_fini(struct radeon_device *rdev);
 void r100_cp_disable(struct radeon_device *rdev);
+void r100_cp_commit(struct radeon_device *rdev);
 void r100_ring_start(struct radeon_device *rdev);
 int r100_irq_set(struct radeon_device *rdev);
 int r100_irq_process(struct radeon_device *rdev);
@@ -77,24 +82,34 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
 			 uint32_t offset, uint32_t obj_size);
 int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
 void r100_bandwidth_update(struct radeon_device *rdev);
+void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
+int r100_ib_test(struct radeon_device *rdev);
+int r100_ring_test(struct radeon_device *rdev);
 
 static struct radeon_asic r100_asic = {
 	.init = &r100_init,
 	.errata = &r100_errata,
 	.vram_info = &r100_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r100_gpu_reset,
 	.mc_init = &r100_mc_init,
 	.mc_fini = &r100_mc_fini,
 	.wb_init = &r100_wb_init,
 	.wb_fini = &r100_wb_fini,
-	.gart_enable = &r100_gart_enable,
+	.gart_init = &r100_pci_gart_init,
+	.gart_fini = &r100_pci_gart_fini,
+	.gart_enable = &r100_pci_gart_enable,
 	.gart_disable = &r100_pci_gart_disable,
 	.gart_tlb_flush = &r100_pci_gart_tlb_flush,
 	.gart_set_page = &r100_pci_gart_set_page,
 	.cp_init = &r100_cp_init,
 	.cp_fini = &r100_cp_fini,
 	.cp_disable = &r100_cp_disable,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &r100_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = &r100_ib_test,
 	.irq_set = &r100_irq_set,
 	.irq_process = &r100_irq_process,
 	.get_vblank_counter = &r100_get_vblank_counter,
@@ -126,7 +141,9 @@ void r300_ring_start(struct radeon_device *rdev);
 void r300_fence_ring_emit(struct radeon_device *rdev,
 			  struct radeon_fence *fence);
 int r300_cs_parse(struct radeon_cs_parser *p);
-int r300_gart_enable(struct radeon_device *rdev);
+int rv370_pcie_gart_init(struct radeon_device *rdev);
+void rv370_pcie_gart_fini(struct radeon_device *rdev);
+int rv370_pcie_gart_enable(struct radeon_device *rdev);
 void rv370_pcie_gart_disable(struct radeon_device *rdev);
 void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
 int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
@@ -143,19 +160,26 @@ static struct radeon_asic r300_asic = {
 	.init = &r300_init,
 	.errata = &r300_errata,
 	.vram_info = &r300_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &r300_mc_init,
 	.mc_fini = &r300_mc_fini,
 	.wb_init = &r100_wb_init,
 	.wb_fini = &r100_wb_fini,
-	.gart_enable = &r300_gart_enable,
+	.gart_init = &r100_pci_gart_init,
+	.gart_fini = &r100_pci_gart_fini,
+	.gart_enable = &r100_pci_gart_enable,
 	.gart_disable = &r100_pci_gart_disable,
 	.gart_tlb_flush = &r100_pci_gart_tlb_flush,
 	.gart_set_page = &r100_pci_gart_set_page,
 	.cp_init = &r100_cp_init,
 	.cp_fini = &r100_cp_fini,
 	.cp_disable = &r100_cp_disable,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = &r100_ib_test,
 	.irq_set = &r100_irq_set,
 	.irq_process = &r100_irq_process,
 	.get_vblank_counter = &r100_get_vblank_counter,
@@ -176,27 +200,35 @@ static struct radeon_asic r300_asic = {
 /*
  * r420,r423,rv410
  */
-void r420_errata(struct radeon_device *rdev);
-void r420_vram_info(struct radeon_device *rdev);
-int r420_mc_init(struct radeon_device *rdev);
-void r420_mc_fini(struct radeon_device *rdev);
+extern int r420_init(struct radeon_device *rdev);
+extern void r420_fini(struct radeon_device *rdev);
+extern int r420_suspend(struct radeon_device *rdev);
+extern int r420_resume(struct radeon_device *rdev);
 static struct radeon_asic r420_asic = {
-	.init = &r300_init,
-	.errata = &r420_errata,
-	.vram_info = &r420_vram_info,
+	.init = &r420_init,
+	.fini = &r420_fini,
+	.suspend = &r420_suspend,
+	.resume = &r420_resume,
+	.errata = NULL,
+	.vram_info = NULL,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
-	.mc_init = &r420_mc_init,
-	.mc_fini = &r420_mc_fini,
-	.wb_init = &r100_wb_init,
-	.wb_fini = &r100_wb_fini,
-	.gart_enable = &r300_gart_enable,
-	.gart_disable = &rv370_pcie_gart_disable,
+	.mc_init = NULL,
+	.mc_fini = NULL,
+	.wb_init = NULL,
+	.wb_fini = NULL,
+	.gart_enable = NULL,
+	.gart_disable = NULL,
 	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
 	.gart_set_page = &rv370_pcie_gart_set_page,
-	.cp_init = &r100_cp_init,
-	.cp_fini = &r100_cp_fini,
-	.cp_disable = &r100_cp_disable,
+	.cp_init = NULL,
+	.cp_fini = NULL,
+	.cp_disable = NULL,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = NULL,
 	.irq_set = &r100_irq_set,
 	.irq_process = &r100_irq_process,
 	.get_vblank_counter = &r100_get_vblank_counter,
@@ -222,6 +254,8 @@ void rs400_errata(struct radeon_device *rdev);
 void rs400_vram_info(struct radeon_device *rdev);
 int rs400_mc_init(struct radeon_device *rdev);
 void rs400_mc_fini(struct radeon_device *rdev);
+int rs400_gart_init(struct radeon_device *rdev);
+void rs400_gart_fini(struct radeon_device *rdev);
 int rs400_gart_enable(struct radeon_device *rdev);
 void rs400_gart_disable(struct radeon_device *rdev);
 void rs400_gart_tlb_flush(struct radeon_device *rdev);
@@ -232,11 +266,14 @@ static struct radeon_asic rs400_asic = {
 	.init = &r300_init,
 	.errata = &rs400_errata,
 	.vram_info = &rs400_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &rs400_mc_init,
 	.mc_fini = &rs400_mc_fini,
 	.wb_init = &r100_wb_init,
 	.wb_fini = &r100_wb_fini,
+	.gart_init = &rs400_gart_init,
+	.gart_fini = &rs400_gart_fini,
 	.gart_enable = &rs400_gart_enable,
 	.gart_disable = &rs400_gart_disable,
 	.gart_tlb_flush = &rs400_gart_tlb_flush,
@@ -244,7 +281,11 @@ static struct radeon_asic rs400_asic = {
 	.cp_init = &r100_cp_init,
 	.cp_fini = &r100_cp_fini,
 	.cp_disable = &r100_cp_disable,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = &r100_ib_test,
 	.irq_set = &r100_irq_set,
 	.irq_process = &r100_irq_process,
 	.get_vblank_counter = &r100_get_vblank_counter,
@@ -266,7 +307,7 @@ static struct radeon_asic rs400_asic = {
 /*
  * rs600.
  */
-int rs600_init(struct radeon_device *dev);
+int rs600_init(struct radeon_device *rdev);
 void rs600_errata(struct radeon_device *rdev);
 void rs600_vram_info(struct radeon_device *rdev);
 int rs600_mc_init(struct radeon_device *rdev);
@@ -274,6 +315,8 @@ void rs600_mc_fini(struct radeon_device *rdev);
 int rs600_irq_set(struct radeon_device *rdev);
 int rs600_irq_process(struct radeon_device *rdev);
 u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
+int rs600_gart_init(struct radeon_device *rdev);
+void rs600_gart_fini(struct radeon_device *rdev);
 int rs600_gart_enable(struct radeon_device *rdev);
 void rs600_gart_disable(struct radeon_device *rdev);
 void rs600_gart_tlb_flush(struct radeon_device *rdev);
@@ -285,11 +328,14 @@ static struct radeon_asic rs600_asic = {
 	.init = &rs600_init,
 	.errata = &rs600_errata,
 	.vram_info = &rs600_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &rs600_mc_init,
 	.mc_fini = &rs600_mc_fini,
 	.wb_init = &r100_wb_init,
 	.wb_fini = &r100_wb_fini,
+	.gart_init = &rs600_gart_init,
+	.gart_fini = &rs600_gart_fini,
 	.gart_enable = &rs600_gart_enable,
 	.gart_disable = &rs600_gart_disable,
 	.gart_tlb_flush = &rs600_gart_tlb_flush,
@@ -297,7 +343,11 @@ static struct radeon_asic rs600_asic = {
 	.cp_init = &r100_cp_init,
 	.cp_fini = &r100_cp_fini,
 	.cp_disable = &r100_cp_disable,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = &r100_ib_test,
 	.irq_set = &rs600_irq_set,
 	.irq_process = &rs600_irq_process,
 	.get_vblank_counter = &rs600_get_vblank_counter,
@@ -328,11 +378,14 @@ static struct radeon_asic rs690_asic = {
 	.init = &rs600_init,
 	.errata = &rs690_errata,
 	.vram_info = &rs690_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &r300_gpu_reset,
 	.mc_init = &rs690_mc_init,
 	.mc_fini = &rs690_mc_fini,
 	.wb_init = &r100_wb_init,
 	.wb_fini = &r100_wb_fini,
+	.gart_init = &rs400_gart_init,
+	.gart_fini = &rs400_gart_fini,
 	.gart_enable = &rs400_gart_enable,
 	.gart_disable = &rs400_gart_disable,
 	.gart_tlb_flush = &rs400_gart_tlb_flush,
@@ -340,7 +393,11 @@ static struct radeon_asic rs690_asic = {
 	.cp_init = &r100_cp_init,
 	.cp_fini = &r100_cp_fini,
 	.cp_disable = &r100_cp_disable,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &r300_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = &r100_ib_test,
 	.irq_set = &rs600_irq_set,
 	.irq_process = &rs600_irq_process,
 	.get_vblank_counter = &rs600_get_vblank_counter,
@@ -378,19 +435,26 @@ static struct radeon_asic rv515_asic = {
 	.init = &rv515_init,
 	.errata = &rv515_errata,
 	.vram_info = &rv515_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &rv515_gpu_reset,
 	.mc_init = &rv515_mc_init,
 	.mc_fini = &rv515_mc_fini,
 	.wb_init = &r100_wb_init,
 	.wb_fini = &r100_wb_fini,
-	.gart_enable = &r300_gart_enable,
+	.gart_init = &rv370_pcie_gart_init,
+	.gart_fini = &rv370_pcie_gart_fini,
+	.gart_enable = &rv370_pcie_gart_enable,
 	.gart_disable = &rv370_pcie_gart_disable,
 	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
 	.gart_set_page = &rv370_pcie_gart_set_page,
 	.cp_init = &r100_cp_init,
 	.cp_fini = &r100_cp_fini,
 	.cp_disable = &r100_cp_disable,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &rv515_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = &r100_ib_test,
 	.irq_set = &rs600_irq_set,
 	.irq_process = &rs600_irq_process,
 	.get_vblank_counter = &rs600_get_vblank_counter,
@@ -421,19 +485,26 @@ static struct radeon_asic r520_asic = {
 	.init = &rv515_init,
 	.errata = &r520_errata,
 	.vram_info = &r520_vram_info,
+	.vga_set_state = &r100_vga_set_state,
 	.gpu_reset = &rv515_gpu_reset,
 	.mc_init = &r520_mc_init,
 	.mc_fini = &r520_mc_fini,
 	.wb_init = &r100_wb_init,
 	.wb_fini = &r100_wb_fini,
-	.gart_enable = &r300_gart_enable,
+	.gart_init = &rv370_pcie_gart_init,
+	.gart_fini = &rv370_pcie_gart_fini,
+	.gart_enable = &rv370_pcie_gart_enable,
 	.gart_disable = &rv370_pcie_gart_disable,
 	.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
 	.gart_set_page = &rv370_pcie_gart_set_page,
 	.cp_init = &r100_cp_init,
 	.cp_fini = &r100_cp_fini,
 	.cp_disable = &r100_cp_disable,
+	.cp_commit = &r100_cp_commit,
 	.ring_start = &rv515_ring_start,
+	.ring_test = &r100_ring_test,
+	.ring_ib_execute = &r100_ring_ib_execute,
+	.ib_test = &r100_ib_test,
 	.irq_set = &rs600_irq_set,
 	.irq_process = &rs600_irq_process,
 	.get_vblank_counter = &rs600_get_vblank_counter,
@@ -452,9 +523,130 @@ static struct radeon_asic r520_asic = {
 };
 
 /*
- * r600,rv610,rv630,rv620,rv635,rv670,rs780,rv770,rv730,rv710
+ * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880
  */
+int r600_init(struct radeon_device *rdev);
+void r600_fini(struct radeon_device *rdev);
+int r600_suspend(struct radeon_device *rdev);
+int r600_resume(struct radeon_device *rdev);
+void r600_vga_set_state(struct radeon_device *rdev, bool state);
+int r600_wb_init(struct radeon_device *rdev);
+void r600_wb_fini(struct radeon_device *rdev);
+void r600_cp_commit(struct radeon_device *rdev);
+void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
 uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg);
 void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
+int r600_cs_parse(struct radeon_cs_parser *p);
+void r600_fence_ring_emit(struct radeon_device *rdev,
+			  struct radeon_fence *fence);
+int r600_copy_dma(struct radeon_device *rdev,
+		  uint64_t src_offset,
+		  uint64_t dst_offset,
+		  unsigned num_pages,
+		  struct radeon_fence *fence);
+int r600_irq_process(struct radeon_device *rdev);
+int r600_irq_set(struct radeon_device *rdev);
+int r600_gpu_reset(struct radeon_device *rdev);
+int r600_set_surface_reg(struct radeon_device *rdev, int reg,
+			 uint32_t tiling_flags, uint32_t pitch,
+			 uint32_t offset, uint32_t obj_size);
+int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
+void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
+int r600_ib_test(struct radeon_device *rdev);
+int r600_ring_test(struct radeon_device *rdev);
+int r600_copy_blit(struct radeon_device *rdev,
+		   uint64_t src_offset, uint64_t dst_offset,
+		   unsigned num_pages, struct radeon_fence *fence);
+
+static struct radeon_asic r600_asic = {
+	.errata = NULL,
+	.init = &r600_init,
+	.fini = &r600_fini,
+	.suspend = &r600_suspend,
+	.resume = &r600_resume,
+	.cp_commit = &r600_cp_commit,
+	.vram_info = NULL,
+	.vga_set_state = &r600_vga_set_state,
+	.gpu_reset = &r600_gpu_reset,
+	.mc_init = NULL,
+	.mc_fini = NULL,
+	.wb_init = &r600_wb_init,
+	.wb_fini = &r600_wb_fini,
+	.gart_enable = NULL,
+	.gart_disable = NULL,
+	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+	.gart_set_page = &rs600_gart_set_page,
+	.cp_init = NULL,
+	.cp_fini = NULL,
+	.cp_disable = NULL,
+	.ring_start = NULL,
+	.ring_test = &r600_ring_test,
+	.ring_ib_execute = &r600_ring_ib_execute,
+	.ib_test = &r600_ib_test,
+	.irq_set = &r600_irq_set,
+	.irq_process = &r600_irq_process,
+	.fence_ring_emit = &r600_fence_ring_emit,
+	.cs_parse = &r600_cs_parse,
+	.copy_blit = &r600_copy_blit,
+	.copy_dma = &r600_copy_blit,
+	.copy = &r600_copy_blit,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r600_set_surface_reg,
+	.clear_surface_reg = r600_clear_surface_reg,
+	.bandwidth_update = &r520_bandwidth_update,
+};
+
+/*
+ * rv770,rv730,rv710,rv740
+ */
+int rv770_init(struct radeon_device *rdev);
+void rv770_fini(struct radeon_device *rdev);
+int rv770_suspend(struct radeon_device *rdev);
+int rv770_resume(struct radeon_device *rdev);
+int rv770_gpu_reset(struct radeon_device *rdev);
+
+static struct radeon_asic rv770_asic = {
+	.errata = NULL,
+	.init = &rv770_init,
+	.fini = &rv770_fini,
+	.suspend = &rv770_suspend,
+	.resume = &rv770_resume,
+	.cp_commit = &r600_cp_commit,
+	.vram_info = NULL,
+	.gpu_reset = &rv770_gpu_reset,
+	.vga_set_state = &r600_vga_set_state,
+	.mc_init = NULL,
+	.mc_fini = NULL,
+	.wb_init = &r600_wb_init,
+	.wb_fini = &r600_wb_fini,
+	.gart_enable = NULL,
+	.gart_disable = NULL,
+	.gart_tlb_flush = &r600_pcie_gart_tlb_flush,
+	.gart_set_page = &rs600_gart_set_page,
+	.cp_init = NULL,
+	.cp_fini = NULL,
+	.cp_disable = NULL,
+	.ring_start = NULL,
+	.ring_test = &r600_ring_test,
+	.ring_ib_execute = &r600_ring_ib_execute,
+	.ib_test = &r600_ib_test,
+	.irq_set = &r600_irq_set,
+	.irq_process = &r600_irq_process,
+	.fence_ring_emit = &r600_fence_ring_emit,
+	.cs_parse = &r600_cs_parse,
+	.copy_blit = &r600_copy_blit,
+	.copy_dma = &r600_copy_blit,
+	.copy = &r600_copy_blit,
+	.set_engine_clock = &radeon_atom_set_engine_clock,
+	.set_memory_clock = &radeon_atom_set_memory_clock,
+	.set_pcie_lanes = NULL,
+	.set_clock_gating = &radeon_atom_set_clock_gating,
+	.set_surface_reg = r600_set_surface_reg,
+	.clear_surface_reg = r600_clear_surface_reg,
+	.bandwidth_update = &r520_bandwidth_update,
+};
 
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index fcfe5c0..7437421 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -104,7 +104,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
 				     uint32_t supported_device,
 				     int *connector_type,
 				     struct radeon_i2c_bus_rec *i2c_bus,
-				     uint8_t *line_mux)
+				     uint16_t *line_mux)
 {
 
 	/* Asus M2A-VM HDMI board lists the DVI port as HDMI */
@@ -143,20 +143,31 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
 			return false;
 	}
 
-	/* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */
-	if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) ||
-	    (*connector_type == DRM_MODE_CONNECTOR_HDMIB)) {
-		if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) {
-			return false;
-		}
-	}
-
 	/* ASUS HD 3600 XT board lists the DVI port as HDMI */
 	if ((dev->pdev->device == 0x9598) &&
 	    (dev->pdev->subsystem_vendor == 0x1043) &&
 	    (dev->pdev->subsystem_device == 0x01da)) {
-		if (*connector_type == DRM_MODE_CONNECTOR_HDMIB) {
-			*connector_type = DRM_MODE_CONNECTOR_DVID;
+		if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+			*connector_type = DRM_MODE_CONNECTOR_DVII;
+		}
+	}
+
+	/* ASUS HD 3450 board lists the DVI port as HDMI */
+	if ((dev->pdev->device == 0x95C5) &&
+	    (dev->pdev->subsystem_vendor == 0x1043) &&
+	    (dev->pdev->subsystem_device == 0x01e2)) {
+		if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+			*connector_type = DRM_MODE_CONNECTOR_DVII;
+		}
+	}
+
+	/* some BIOSes seem to report DAC on HDMI - usually this is a board with
+	 * HDMI + VGA reporting as HDMI
+	 */
+	if (*connector_type == DRM_MODE_CONNECTOR_HDMIA) {
+		if (supported_device & (ATOM_DEVICE_CRT_SUPPORT)) {
+			*connector_type = DRM_MODE_CONNECTOR_VGA;
+			*line_mux = 0;
 		}
 	}
 
@@ -192,11 +203,11 @@ const int object_connector_convert[] = {
 	DRM_MODE_CONNECTOR_Composite,
 	DRM_MODE_CONNECTOR_SVIDEO,
 	DRM_MODE_CONNECTOR_Unknown,
+	DRM_MODE_CONNECTOR_Unknown,
 	DRM_MODE_CONNECTOR_9PinDIN,
 	DRM_MODE_CONNECTOR_Unknown,
 	DRM_MODE_CONNECTOR_HDMIA,
 	DRM_MODE_CONNECTOR_HDMIB,
-	DRM_MODE_CONNECTOR_HDMIB,
 	DRM_MODE_CONNECTOR_LVDS,
 	DRM_MODE_CONNECTOR_9PinDIN,
 	DRM_MODE_CONNECTOR_Unknown,
@@ -218,7 +229,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
 	ATOM_OBJECT_HEADER *obj_header;
 	int i, j, path_size, device_support;
 	int connector_type;
-	uint16_t igp_lane_info;
+	uint16_t igp_lane_info, conn_id;
 	bool linkb;
 	struct radeon_i2c_bus_rec ddc_bus;
 
@@ -370,10 +381,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
 						       && record->
 						       ucRecordType <=
 						       ATOM_MAX_OBJECT_RECORD_NUMBER) {
-							DRM_ERROR
-							    ("record type %d\n",
-							     record->
-							     ucRecordType);
 							switch (record->
 								ucRecordType) {
 							case ATOM_I2C_RECORD_TYPE:
@@ -409,9 +416,15 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
 			else
 				ddc_bus = radeon_lookup_gpio(dev, line_mux);
 
+			conn_id = le16_to_cpu(path->usConnObjectId);
+
+			if (!radeon_atom_apply_quirks
+			    (dev, le16_to_cpu(path->usDeviceTag), &connector_type,
+			     &ddc_bus, &conn_id))
+				continue;
+
 			radeon_add_atom_connector(dev,
-						  le16_to_cpu(path->
-							      usConnObjectId),
+						  conn_id,
 						  le16_to_cpu(path->
 							      usDeviceTag),
 						  connector_type, &ddc_bus,
@@ -427,7 +440,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
 
 struct bios_connector {
 	bool valid;
-	uint8_t line_mux;
+	uint16_t line_mux;
 	uint16_t devices;
 	int connector_type;
 	struct radeon_i2c_bus_rec ddc_bus;
@@ -471,11 +484,6 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
 			continue;
 		}
 
-		if (i == ATOM_DEVICE_TV1_INDEX) {
-			DRM_DEBUG("Skipping TV Out\n");
-			continue;
-		}
-
 		bios_connectors[i].connector_type =
 		    supported_devices_connector_convert[ci.sucConnectorInfo.
 							sbfAccess.
@@ -711,9 +719,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
 	return false;
 }
 
-struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
-							      radeon_encoder
-							      *encoder)
+bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
+				   struct radeon_encoder_int_tmds *tmds)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct radeon_device *rdev = dev->dev_private;
@@ -724,7 +731,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
 	uint8_t frev, crev;
 	uint16_t maxfreq;
 	int i;
-	struct radeon_encoder_int_tmds *tmds = NULL;
 
 	atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
 			       &crev, &data_offset);
@@ -734,12 +740,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
 				       data_offset);
 
 	if (tmds_info) {
-		tmds =
-		    kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
-
-		if (!tmds)
-			return NULL;
-
 		maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
 		for (i = 0; i < 4; i++) {
 			tmds->tmds_pll[i].freq =
@@ -765,8 +765,9 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
 				break;
 			}
 		}
+		return true;
 	}
-	return tmds;
+	return false;
 }
 
 union lvds_info {
@@ -858,6 +859,72 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
 	return p_dac;
 }
 
+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
+				SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
+				int32_t *pixel_clock)
+{
+	struct radeon_mode_info *mode_info = &rdev->mode_info;
+	ATOM_ANALOG_TV_INFO *tv_info;
+	ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2;
+	ATOM_DTD_FORMAT *dtd_timings;
+	int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
+	u8 frev, crev;
+	uint16_t data_offset;
+
+	atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
+
+	switch (crev) {
+	case 1:
+		tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
+		if (index > MAX_SUPPORTED_TV_TIMING)
+			return false;
+
+		crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
+		crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
+		crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
+		crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
+
+		crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
+		crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
+		crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
+		crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
+
+		crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo;
+
+		crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight);
+		crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft);
+		crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom);
+		crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop);
+		*pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
+
+		if (index == 1) {
+			/* PAL timings appear to have wrong values for totals */
+			crtc_timing->usH_Total -= 1;
+			crtc_timing->usV_Total -= 1;
+		}
+		break;
+	case 2:
+		tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
+		if (index > MAX_SUPPORTED_TV_TIMING_V1_2)
+			return false;
+
+		dtd_timings = &tv_info_v1_2->aModeTimings[index];
+		crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
+		crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive);
+		crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
+		crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth);
+		crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
+		crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive);
+		crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
+		crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth);
+
+		crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
+		*pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
+		break;
+	}
+	return true;
+}
+
 struct radeon_encoder_tv_dac *
 radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
 {
@@ -948,10 +1015,10 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
 	uint32_t bios_2_scratch, bios_6_scratch;
 
 	if (rdev->family >= CHIP_R600) {
-		bios_2_scratch = RREG32(R600_BIOS_0_SCRATCH);
+		bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
 		bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
 	} else {
-		bios_2_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
+		bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
 		bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
 	}
 
@@ -971,6 +1038,34 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
 
 }
 
+void radeon_save_bios_scratch_regs(struct radeon_device *rdev)
+{
+	uint32_t scratch_reg;
+	int i;
+
+	if (rdev->family >= CHIP_R600)
+		scratch_reg = R600_BIOS_0_SCRATCH;
+	else
+		scratch_reg = RADEON_BIOS_0_SCRATCH;
+
+	for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
+		rdev->bios_scratch[i] = RREG32(scratch_reg + (i * 4));
+}
+
+void radeon_restore_bios_scratch_regs(struct radeon_device *rdev)
+{
+	uint32_t scratch_reg;
+	int i;
+
+	if (rdev->family >= CHIP_R600)
+		scratch_reg = R600_BIOS_0_SCRATCH;
+	else
+		scratch_reg = RADEON_BIOS_0_SCRATCH;
+
+	for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++)
+		WREG32(scratch_reg + (i * 4), rdev->bios_scratch[i]);
+}
+
 void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock)
 {
 	struct drm_device *dev = encoder->dev;
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index a37cbce..152eef1 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -102,10 +102,12 @@ void radeon_get_clock_info(struct drm_device *dev)
 			p1pll->reference_div = 12;
 		if (p2pll->reference_div < 2)
 			p2pll->reference_div = 12;
-		if (spll->reference_div < 2)
-			spll->reference_div =
-			    RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
-			    RADEON_M_SPLL_REF_DIV_MASK;
+		if (rdev->family < CHIP_RS600) {
+			if (spll->reference_div < 2)
+				spll->reference_div =
+					RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
+					RADEON_M_SPLL_REF_DIV_MASK;
+		}
 		if (mpll->reference_div < 2)
 			mpll->reference_div = spll->reference_div;
 	} else {
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index 2a027e0..748265a 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -863,8 +863,10 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
 	int tmp, i;
 	struct radeon_encoder_lvds *lvds = NULL;
 
-	if (rdev->bios == NULL)
-		return radeon_legacy_get_lvds_info_from_regs(rdev);
+	if (rdev->bios == NULL) {
+		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
+		goto out;
+	}
 
 	lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
 
@@ -965,11 +967,13 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder
 				lvds->native_mode.flags = 0;
 			}
 		}
-		encoder->native_mode = lvds->native_mode;
 	} else {
 		DRM_INFO("No panel info found in BIOS\n");
-		return radeon_legacy_get_lvds_info_from_regs(rdev);
+		lvds = radeon_legacy_get_lvds_info_from_regs(rdev);
 	}
+out:
+	if (lvds)
+		encoder->native_mode = lvds->native_mode;
 	return lvds;
 }
 
@@ -994,48 +998,37 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
 	{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/* CHIP_RS480 */
 };
 
-static struct radeon_encoder_int_tmds
-    *radeon_legacy_get_tmds_info_from_table(struct radeon_device *rdev)
+bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
+					    struct radeon_encoder_int_tmds *tmds)
 {
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
 	int i;
-	struct radeon_encoder_int_tmds *tmds = NULL;
-
-	tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
-
-	if (!tmds)
-		return NULL;
 
 	for (i = 0; i < 4; i++) {
 		tmds->tmds_pll[i].value =
-		    default_tmds_pll[rdev->family][i].value;
+			default_tmds_pll[rdev->family][i].value;
 		tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
 	}
 
-	return tmds;
+	return true;
 }
 
-struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct
-							     radeon_encoder
-							     *encoder)
+bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
+					      struct radeon_encoder_int_tmds *tmds)
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct radeon_device *rdev = dev->dev_private;
 	uint16_t tmds_info;
 	int i, n;
 	uint8_t ver;
-	struct radeon_encoder_int_tmds *tmds = NULL;
 
 	if (rdev->bios == NULL)
-		return radeon_legacy_get_tmds_info_from_table(rdev);
+		return false;
 
 	tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
 
 	if (tmds_info) {
-		tmds =
-		    kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
-
-		if (!tmds)
-			return NULL;
 
 		ver = RBIOS8(tmds_info);
 		DRM_INFO("DFP table revision: %d\n", ver);
@@ -1073,6 +1066,23 @@ struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct
 		}
 	} else
 		DRM_INFO("No TMDS info found in BIOS\n");
+	return true;
+}
+
+struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
+{
+	struct radeon_encoder_int_tmds *tmds = NULL;
+	bool ret;
+
+	tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
+
+	if (!tmds)
+		return NULL;
+
+	ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
+	if (ret == false)
+		radeon_legacy_get_tmds_info_from_table(encoder, tmds);
+
 	return tmds;
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 70ede6a..af1d551 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -28,6 +28,7 @@
 #include "drm_crtc_helper.h"
 #include "radeon_drm.h"
 #include "radeon.h"
+#include "atom.h"
 
 extern void
 radeon_combios_connected_scratch_regs(struct drm_connector *connector,
@@ -38,6 +39,15 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
 				       struct drm_encoder *encoder,
 				       bool connected);
 
+static void radeon_property_change_mode(struct drm_encoder *encoder)
+{
+	struct drm_crtc *crtc = encoder->crtc;
+
+	if (crtc && crtc->enabled) {
+		drm_crtc_helper_set_mode(crtc, &crtc->mode,
+					 crtc->x, crtc->y, crtc->fb);
+	}
+}
 static void
 radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status)
 {
@@ -77,6 +87,27 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
 	}
 }
 
+struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
+{
+	struct drm_mode_object *obj;
+	struct drm_encoder *encoder;
+	int i;
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		if (connector->encoder_ids[i] == 0)
+			break;
+
+		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+
+		encoder = obj_to_encoder(obj);
+		if (encoder->encoder_type == encoder_type)
+			return encoder;
+	}
+	return NULL;
+}
+
 struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
 {
 	int enc_id = connector->encoder_ids[0];
@@ -94,6 +125,53 @@ struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
 	return NULL;
 }
 
+/*
+ * radeon_connector_analog_encoder_conflict_solve
+ * - search for other connectors sharing this encoder
+ *   if priority is true, then set them disconnected if this is connected
+ *   if priority is false, set us disconnected if they are connected
+ */
+static enum drm_connector_status
+radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
+					       struct drm_encoder *encoder,
+					       enum drm_connector_status current_status,
+					       bool priority)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_connector *conflict;
+	int i;
+
+	list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
+		if (conflict == connector)
+			continue;
+
+		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+			if (conflict->encoder_ids[i] == 0)
+				break;
+
+			/* if the IDs match */
+			if (conflict->encoder_ids[i] == encoder->base.id) {
+				if (conflict->status != connector_status_connected)
+					continue;
+
+				if (priority == true) {
+					DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
+					DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
+					conflict->status = connector_status_disconnected;
+					radeon_connector_update_scratch_regs(conflict, connector_status_disconnected);
+				} else {
+					DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector));
+					DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict));
+					current_status = connector_status_disconnected;
+				}
+				break;
+			}
+		}
+	}
+	return current_status;
+
+}
+
 static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
@@ -126,12 +204,171 @@ static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encode
 	return mode;
 }
 
+static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_display_mode *mode = NULL;
+	struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
+	int i;
+	struct mode_size {
+		int w;
+		int h;
+	} common_modes[17] = {
+		{ 640,  480},
+		{ 720,  480},
+		{ 800,  600},
+		{ 848,  480},
+		{1024,  768},
+		{1152,  768},
+		{1280,  720},
+		{1280,  800},
+		{1280,  854},
+		{1280,  960},
+		{1280, 1024},
+		{1440,  900},
+		{1400, 1050},
+		{1680, 1050},
+		{1600, 1200},
+		{1920, 1080},
+		{1920, 1200}
+	};
+
+	for (i = 0; i < 17; i++) {
+		if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+			if (common_modes[i].w > native_mode->panel_xres ||
+			    common_modes[i].h > native_mode->panel_yres ||
+			    (common_modes[i].w == native_mode->panel_xres &&
+			     common_modes[i].h == native_mode->panel_yres))
+				continue;
+		}
+		if (common_modes[i].w < 320 || common_modes[i].h < 200)
+			continue;
+
+		mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false);
+		drm_mode_probed_add(connector, mode);
+	}
+}
+
 int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
 				  uint64_t val)
 {
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct radeon_encoder *radeon_encoder;
+
+	if (property == rdev->mode_info.coherent_mode_property) {
+		struct radeon_encoder_atom_dig *dig;
+
+		/* need to find digital encoder on connector */
+		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
+		if (!encoder)
+			return 0;
+
+		radeon_encoder = to_radeon_encoder(encoder);
+
+		if (!radeon_encoder->enc_priv)
+			return 0;
+
+		dig = radeon_encoder->enc_priv;
+		dig->coherent_mode = val ? true : false;
+		radeon_property_change_mode(&radeon_encoder->base);
+	}
+
+	if (property == rdev->mode_info.tv_std_property) {
+		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC);
+		if (!encoder) {
+			encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_DAC);
+		}
+
+		if (!encoder)
+			return 0;
+
+		radeon_encoder = to_radeon_encoder(encoder);
+		if (!radeon_encoder->enc_priv)
+			return 0;
+		if (rdev->is_atom_bios) {
+			struct radeon_encoder_atom_dac *dac_int;
+			dac_int = radeon_encoder->enc_priv;
+			dac_int->tv_std = val;
+		} else {
+			struct radeon_encoder_tv_dac *dac_int;
+			dac_int = radeon_encoder->enc_priv;
+			dac_int->tv_std = val;
+		}
+		radeon_property_change_mode(&radeon_encoder->base);
+	}
+
+	if (property == rdev->mode_info.load_detect_property) {
+		struct radeon_connector *radeon_connector =
+			to_radeon_connector(connector);
+
+		if (val == 0)
+			radeon_connector->dac_load_detect = false;
+		else
+			radeon_connector->dac_load_detect = true;
+	}
+
+	if (property == rdev->mode_info.tmds_pll_property) {
+		struct radeon_encoder_int_tmds *tmds = NULL;
+		bool ret = false;
+		/* need to find digital encoder on connector */
+		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
+		if (!encoder)
+			return 0;
+
+		radeon_encoder = to_radeon_encoder(encoder);
+
+		tmds = radeon_encoder->enc_priv;
+		if (!tmds)
+			return 0;
+
+		if (val == 0) {
+			if (rdev->is_atom_bios)
+				ret = radeon_atombios_get_tmds_info(radeon_encoder, tmds);
+			else
+				ret = radeon_legacy_get_tmds_info_from_combios(radeon_encoder, tmds);
+		}
+		if (val == 1 || ret == false) {
+			radeon_legacy_get_tmds_info_from_table(radeon_encoder, tmds);
+		}
+		radeon_property_change_mode(&radeon_encoder->base);
+	}
+
 	return 0;
 }
 
+static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
+					  struct drm_connector *connector)
+{
+	struct radeon_encoder *radeon_encoder =	to_radeon_encoder(encoder);
+	struct radeon_native_mode *native_mode = &radeon_encoder->native_mode;
+
+	/* Try to get native mode details from EDID if necessary */
+	if (!native_mode->dotclock) {
+		struct drm_display_mode *t, *mode;
+
+		list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
+			if (mode->hdisplay == native_mode->panel_xres &&
+			    mode->vdisplay == native_mode->panel_yres) {
+				native_mode->hblank = mode->htotal - mode->hdisplay;
+				native_mode->hoverplus = mode->hsync_start - mode->hdisplay;
+				native_mode->hsync_width = mode->hsync_end - mode->hsync_start;
+				native_mode->vblank = mode->vtotal - mode->vdisplay;
+				native_mode->voverplus = mode->vsync_start - mode->vdisplay;
+				native_mode->vsync_width = mode->vsync_end - mode->vsync_start;
+				native_mode->dotclock = mode->clock;
+				DRM_INFO("Determined LVDS native mode details from EDID\n");
+				break;
+			}
+		}
+	}
+	if (!native_mode->dotclock) {
+		DRM_INFO("No LVDS native mode details, disabling RMX\n");
+		radeon_encoder->rmx_type = RMX_OFF;
+	}
+}
 
 static int radeon_lvds_get_modes(struct drm_connector *connector)
 {
@@ -143,6 +380,12 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
 	if (radeon_connector->ddc_bus) {
 		ret = radeon_ddc_get_modes(radeon_connector);
 		if (ret > 0) {
+			encoder = radeon_best_single_encoder(connector);
+			if (encoder) {
+				radeon_fixup_lvds_native_mode(encoder, connector);
+				/* add scaled modes */
+				radeon_add_common_modes(encoder, connector);
+			}
 			return ret;
 		}
 	}
@@ -156,7 +399,10 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
 	if (mode) {
 		ret = 1;
 		drm_mode_probed_add(connector, mode);
+		/* add scaled modes */
+		radeon_add_common_modes(encoder, connector);
 	}
+
 	return ret;
 }
 
@@ -186,6 +432,42 @@ static void radeon_connector_destroy(struct drm_connector *connector)
 	kfree(connector);
 }
 
+static int radeon_lvds_set_property(struct drm_connector *connector,
+				    struct drm_property *property,
+				    uint64_t value)
+{
+	struct drm_device *dev = connector->dev;
+	struct radeon_encoder *radeon_encoder;
+	enum radeon_rmx_type rmx_type;
+
+	DRM_DEBUG("\n");
+	if (property != dev->mode_config.scaling_mode_property)
+		return 0;
+
+	if (connector->encoder)
+		radeon_encoder = to_radeon_encoder(connector->encoder);
+	else {
+		struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
+		radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
+	}
+
+	switch (value) {
+	case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
+	case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
+	case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
+	default:
+	case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
+	}
+	if (radeon_encoder->rmx_type == rmx_type)
+		return 0;
+
+	radeon_encoder->rmx_type = rmx_type;
+
+	radeon_property_change_mode(&radeon_encoder->base);
+	return 0;
+}
+
+
 struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
 	.get_modes = radeon_lvds_get_modes,
 	.mode_valid = radeon_lvds_mode_valid,
@@ -197,7 +479,7 @@ struct drm_connector_funcs radeon_lvds_connector_funcs = {
 	.detect = radeon_lvds_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = radeon_connector_destroy,
-	.set_property = radeon_connector_set_property,
+	.set_property = radeon_lvds_set_property,
 };
 
 static int radeon_vga_get_modes(struct drm_connector *connector)
@@ -213,7 +495,6 @@ static int radeon_vga_get_modes(struct drm_connector *connector)
 static int radeon_vga_mode_valid(struct drm_connector *connector,
 				  struct drm_display_mode *mode)
 {
-
 	return MODE_OK;
 }
 
@@ -225,22 +506,24 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
 	bool dret;
 	enum drm_connector_status ret = connector_status_disconnected;
 
+	encoder = radeon_best_single_encoder(connector);
+	if (!encoder)
+		ret = connector_status_disconnected;
+
 	radeon_i2c_do_lock(radeon_connector, 1);
 	dret = radeon_ddc_probe(radeon_connector);
 	radeon_i2c_do_lock(radeon_connector, 0);
 	if (dret)
 		ret = connector_status_connected;
 	else {
-		/* if EDID fails to a load detect */
-		encoder = radeon_best_single_encoder(connector);
-		if (!encoder)
-			ret = connector_status_disconnected;
-		else {
+		if (radeon_connector->dac_load_detect) {
 			encoder_funcs = encoder->helper_private;
 			ret = encoder_funcs->detect(encoder, connector);
 		}
 	}
 
+	if (ret == connector_status_connected)
+		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
 	radeon_connector_update_scratch_regs(connector, ret);
 	return ret;
 }
@@ -259,21 +542,97 @@ struct drm_connector_funcs radeon_vga_connector_funcs = {
 	.set_property = radeon_connector_set_property,
 };
 
+static int radeon_tv_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct drm_display_mode *tv_mode;
+	struct drm_encoder *encoder;
+
+	encoder = radeon_best_single_encoder(connector);
+	if (!encoder)
+		return 0;
+
+	/* avivo chips can scale any mode */
+	if (rdev->family >= CHIP_RS600)
+		/* add scaled modes */
+		radeon_add_common_modes(encoder, connector);
+	else {
+		/* only 800x600 is supported right now on pre-avivo chips */
+		tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false);
+		tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+		drm_mode_probed_add(connector, tv_mode);
+	}
+	return 1;
+}
+
+static int radeon_tv_mode_valid(struct drm_connector *connector,
+				struct drm_display_mode *mode)
+{
+	return MODE_OK;
+}
+
+static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
+{
+	struct drm_encoder *encoder;
+	struct drm_encoder_helper_funcs *encoder_funcs;
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	enum drm_connector_status ret = connector_status_disconnected;
+
+	if (!radeon_connector->dac_load_detect)
+		return ret;
+
+	encoder = radeon_best_single_encoder(connector);
+	if (!encoder)
+		ret = connector_status_disconnected;
+	else {
+		encoder_funcs = encoder->helper_private;
+		ret = encoder_funcs->detect(encoder, connector);
+	}
+	if (ret == connector_status_connected)
+		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
+	radeon_connector_update_scratch_regs(connector, ret);
+	return ret;
+}
+
+struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
+	.get_modes = radeon_tv_get_modes,
+	.mode_valid = radeon_tv_mode_valid,
+	.best_encoder = radeon_best_single_encoder,
+};
+
+struct drm_connector_funcs radeon_tv_connector_funcs = {
+	.dpms = drm_helper_connector_dpms,
+	.detect = radeon_tv_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = radeon_connector_destroy,
+	.set_property = radeon_connector_set_property,
+};
+
 static int radeon_dvi_get_modes(struct drm_connector *connector)
 {
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	int ret;
 
 	ret = radeon_ddc_get_modes(radeon_connector);
-	/* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */
-	radeon_connector_update_scratch_regs(connector, connector_status_connected);
 	return ret;
 }
 
+/*
+ * DVI is complicated
+ * Do a DDC probe, if DDC probe passes, get the full EDID so
+ * we can do analog/digital monitor detection at this point.
+ * If the monitor is an analog monitor or we got no DDC,
+ * we need to find the DAC encoder object for this connector.
+ * If we got no DDC, we do load detection on the DAC encoder object.
+ * If we got analog DDC or load detection passes on the DAC encoder
+ * we have to check if this analog encoder is shared with anyone else (TV)
+ * if its shared we have to set the other connector to disconnected.
+ */
 static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
 {
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
-	struct drm_encoder *encoder;
+	struct drm_encoder *encoder = NULL;
 	struct drm_encoder_helper_funcs *encoder_funcs;
 	struct drm_mode_object *obj;
 	int i;
@@ -283,9 +642,29 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
 	radeon_i2c_do_lock(radeon_connector, 1);
 	dret = radeon_ddc_probe(radeon_connector);
 	radeon_i2c_do_lock(radeon_connector, 0);
-	if (dret)
-		ret = connector_status_connected;
-	else {
+	if (dret) {
+		radeon_i2c_do_lock(radeon_connector, 1);
+		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+		radeon_i2c_do_lock(radeon_connector, 0);
+
+		if (!radeon_connector->edid) {
+			DRM_ERROR("DDC responded but not EDID found for %s\n",
+				  drm_get_connector_name(connector));
+		} else {
+			radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
+
+			/* if this isn't a digital monitor
+			   then we need to make sure we don't have any
+			   TV conflicts */
+			ret = connector_status_connected;
+		}
+	}
+
+	if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
+		goto out;
+
+	/* find analog encoder */
+	if (radeon_connector->dac_load_detect) {
 		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
 			if (connector->encoder_ids[i] == 0)
 				break;
@@ -300,15 +679,23 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
 
 			encoder_funcs = encoder->helper_private;
 			if (encoder_funcs->detect) {
-				ret = encoder_funcs->detect(encoder, connector);
-				if (ret == connector_status_connected) {
-					radeon_connector->use_digital = 0;
-					break;
+				if (ret != connector_status_connected) {
+					ret = encoder_funcs->detect(encoder, connector);
+					if (ret == connector_status_connected) {
+						radeon_connector->use_digital = false;
+					}
 				}
+				break;
 			}
 		}
 	}
 
+	if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) &&
+	    encoder) {
+		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
+	}
+
+out:
 	/* updated in get modes as well since we need to know if it's analog or digital */
 	radeon_connector_update_scratch_regs(connector, ret);
 	return ret;
@@ -332,7 +719,7 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
 
 		encoder = obj_to_encoder(obj);
 
-		if (radeon_connector->use_digital) {
+		if (radeon_connector->use_digital == true) {
 			if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
 				return encoder;
 		} else {
@@ -379,16 +766,14 @@ radeon_add_atom_connector(struct drm_device *dev,
 			  bool linkb,
 			  uint32_t igp_lane_info)
 {
+	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector_atom_dig *radeon_dig_connector;
 	uint32_t subpixel_order = SubPixelNone;
 
 	/* fixme - tv/cv/din */
-	if ((connector_type == DRM_MODE_CONNECTOR_Unknown) ||
-	    (connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
-	    (connector_type == DRM_MODE_CONNECTOR_Composite) ||
-	    (connector_type == DRM_MODE_CONNECTOR_9PinDIN))
+	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
 		return;
 
 	/* see if we already added it */
@@ -417,6 +802,9 @@ radeon_add_atom_connector(struct drm_device *dev,
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.load_detect_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_DVIA:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -426,6 +814,9 @@ radeon_add_atom_connector(struct drm_device *dev,
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.load_detect_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_DVII:
 	case DRM_MODE_CONNECTOR_DVID:
@@ -443,6 +834,12 @@ radeon_add_atom_connector(struct drm_device *dev,
 				goto failed;
 		}
 		subpixel_order = SubPixelHorizontalRGB;
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.coherent_mode_property,
+					      1);
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.load_detect_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_HDMIA:
 	case DRM_MODE_CONNECTOR_HDMIB:
@@ -459,6 +856,9 @@ radeon_add_atom_connector(struct drm_device *dev,
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.coherent_mode_property,
+					      1);
 		subpixel_order = SubPixelHorizontalRGB;
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
@@ -480,6 +880,13 @@ radeon_add_atom_connector(struct drm_device *dev,
 	case DRM_MODE_CONNECTOR_SVIDEO:
 	case DRM_MODE_CONNECTOR_Composite:
 	case DRM_MODE_CONNECTOR_9PinDIN:
+		if (radeon_tv == 1) {
+			drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
+		}
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.load_detect_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_LVDS:
 		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -495,6 +902,10 @@ radeon_add_atom_connector(struct drm_device *dev,
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
+		drm_mode_create_scaling_mode_property(dev);
+		drm_connector_attach_property(&radeon_connector->base,
+					      dev->mode_config.scaling_mode_property,
+					      DRM_MODE_SCALE_FULLSCREEN);
 		subpixel_order = SubPixelHorizontalRGB;
 		break;
 	}
@@ -517,15 +928,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
 			    int connector_type,
 			    struct radeon_i2c_bus_rec *i2c_bus)
 {
+	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
 	uint32_t subpixel_order = SubPixelNone;
 
 	/* fixme - tv/cv/din */
-	if ((connector_type == DRM_MODE_CONNECTOR_Unknown) ||
-	    (connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
-	    (connector_type == DRM_MODE_CONNECTOR_Composite) ||
-	    (connector_type == DRM_MODE_CONNECTOR_9PinDIN))
+	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
 		return;
 
 	/* see if we already added it */
@@ -554,6 +963,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.load_detect_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_DVIA:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -563,6 +975,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
+		drm_connector_attach_property(&radeon_connector->base,
+					      rdev->mode_info.load_detect_property,
+					      1);
 		break;
 	case DRM_MODE_CONNECTOR_DVII:
 	case DRM_MODE_CONNECTOR_DVID:
@@ -572,12 +987,22 @@ radeon_add_legacy_connector(struct drm_device *dev,
 			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
 			if (!radeon_connector->ddc_bus)
 				goto failed;
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.load_detect_property,
+						      1);
 		}
 		subpixel_order = SubPixelHorizontalRGB;
 		break;
 	case DRM_MODE_CONNECTOR_SVIDEO:
 	case DRM_MODE_CONNECTOR_Composite:
 	case DRM_MODE_CONNECTOR_9PinDIN:
+		if (radeon_tv == 1) {
+			drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.load_detect_property,
+						      1);
+		}
 		break;
 	case DRM_MODE_CONNECTOR_LVDS:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
@@ -587,6 +1012,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
 			if (!radeon_connector->ddc_bus)
 				goto failed;
 		}
+		drm_connector_attach_property(&radeon_connector->base,
+					      dev->mode_config.scaling_mode_property,
+					      DRM_MODE_SCALE_FULLSCREEN);
 		subpixel_order = SubPixelHorizontalRGB;
 		break;
 	}
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 7a52c46..4f7afc7 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -36,10 +36,25 @@
 #include "radeon_drv.h"
 #include "r300_reg.h"
 
-#include "radeon_microcode.h"
-
 #define RADEON_FIFO_DEBUG	0
 
+/* Firmware Names */
+#define FIRMWARE_R100		"radeon/R100_cp.bin"
+#define FIRMWARE_R200		"radeon/R200_cp.bin"
+#define FIRMWARE_R300		"radeon/R300_cp.bin"
+#define FIRMWARE_R420		"radeon/R420_cp.bin"
+#define FIRMWARE_RS690		"radeon/RS690_cp.bin"
+#define FIRMWARE_RS600		"radeon/RS600_cp.bin"
+#define FIRMWARE_R520		"radeon/R520_cp.bin"
+
+MODULE_FIRMWARE(FIRMWARE_R100);
+MODULE_FIRMWARE(FIRMWARE_R200);
+MODULE_FIRMWARE(FIRMWARE_R300);
+MODULE_FIRMWARE(FIRMWARE_R420);
+MODULE_FIRMWARE(FIRMWARE_RS690);
+MODULE_FIRMWARE(FIRMWARE_RS600);
+MODULE_FIRMWARE(FIRMWARE_R520);
+
 static int radeon_do_cleanup_cp(struct drm_device * dev);
 static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
 
@@ -460,37 +475,34 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
  */
 
 /* Load the microcode for the CP */
-static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
+static int radeon_cp_init_microcode(drm_radeon_private_t *dev_priv)
 {
-	int i;
+	struct platform_device *pdev;
+	const char *fw_name = NULL;
+	int err;
+
 	DRM_DEBUG("\n");
 
-	radeon_do_wait_for_idle(dev_priv);
+	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
+	err = IS_ERR(pdev);
+	if (err) {
+		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
+		return -EINVAL;
+	}
 
-	RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
 	if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) ||
 	    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) {
 		DRM_INFO("Loading R100 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-				     R100_cp_microcode[i][1]);
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-				     R100_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R100;
 	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) {
 		DRM_INFO("Loading R200 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-				     R200_cp_microcode[i][1]);
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-				     R200_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R200;
 	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
@@ -498,39 +510,19 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
 		DRM_INFO("Loading R300 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-				     R300_cp_microcode[i][1]);
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-				     R300_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R300;
 	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) {
 		DRM_INFO("Loading R400 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-				     R420_cp_microcode[i][1]);
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-				     R420_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_R420;
 	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
 		DRM_INFO("Loading RS690/RS740 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-				     RS690_cp_microcode[i][1]);
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-				     RS690_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_RS690;
 	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
 		DRM_INFO("Loading RS600 Microcode\n");
-		for (i = 0; i < 256; i++) {
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-				     RS600_cp_microcode[i][1]);
-			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-				     RS600_cp_microcode[i][0]);
-		}
+		fw_name = FIRMWARE_RS600;
 	} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
@@ -538,11 +530,41 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) ||
 		   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) {
 		DRM_INFO("Loading R500 Microcode\n");
-		for (i = 0; i < 256; i++) {
+		fw_name = FIRMWARE_R520;
+	}
+
+	err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev);
+	platform_device_unregister(pdev);
+	if (err) {
+		printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
+		       fw_name);
+	} else if (dev_priv->me_fw->size % 8) {
+		printk(KERN_ERR
+		       "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
+		       dev_priv->me_fw->size, fw_name);
+		err = -EINVAL;
+		release_firmware(dev_priv->me_fw);
+		dev_priv->me_fw = NULL;
+	}
+	return err;
+}
+
+static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+	const __be32 *fw_data;
+	int i, size;
+
+	radeon_do_wait_for_idle(dev_priv);
+
+	if (dev_priv->me_fw) {
+		size = dev_priv->me_fw->size / 4;
+		fw_data = (const __be32 *)&dev_priv->me_fw->data[0];
+		RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
+		for (i = 0; i < size; i += 2) {
 			RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-				     R520_cp_microcode[i][1]);
+				     be32_to_cpup(&fw_data[i]));
 			RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-				     R520_cp_microcode[i][0]);
+				     be32_to_cpup(&fw_data[i + 1]));
 		}
 	}
 }
@@ -594,6 +616,18 @@ static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
 
 	dev_priv->cp_running = 1;
 
+	/* on r420, any DMA from CP to system memory while 2D is active
+	 * can cause a hang.  workaround is to queue a CP RESYNC token
+	 */
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
+		BEGIN_RING(3);
+		OUT_RING(CP_PACKET0(R300_CP_RESYNC_ADDR, 1));
+		OUT_RING(5); /* scratch reg 5 */
+		OUT_RING(0xdeadbeef);
+		ADVANCE_RING();
+		COMMIT_RING();
+	}
+
 	BEGIN_RING(8);
 	/* isync can only be written through cp on r5xx write it here */
 	OUT_RING(CP_PACKET0(RADEON_ISYNC_CNTL, 0));
@@ -631,8 +665,19 @@ static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
  */
 static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
 {
+	RING_LOCALS;
 	DRM_DEBUG("\n");
 
+	/* finish the pending CP_RESYNC token */
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) {
+		BEGIN_RING(2);
+		OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
+		OUT_RING(R300_RB3D_DC_FINISH);
+		ADVANCE_RING();
+		COMMIT_RING();
+		radeon_do_wait_for_idle(dev_priv);
+	}
+
 	RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
 
 	dev_priv->cp_running = 0;
@@ -1495,6 +1540,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
 		radeon_set_pcigart(dev_priv, 1);
 	}
 
+	if (!dev_priv->me_fw) {
+		int err = radeon_cp_init_microcode(dev_priv);
+		if (err) {
+			DRM_ERROR("Failed to load firmware!\n");
+			radeon_do_cleanup_cp(dev);
+			return err;
+		}
+	}
 	radeon_cp_load_microcode(dev_priv);
 	radeon_cp_init_ring_buffer(dev, dev_priv, file_priv);
 
@@ -1764,6 +1817,14 @@ void radeon_do_release(struct drm_device * dev)
 			r600_do_cleanup_cp(dev);
 		else
 			radeon_do_cleanup_cp(dev);
+		if (dev_priv->me_fw) {
+			release_firmware(dev_priv->me_fw);
+			dev_priv->me_fw = NULL;
+		}
+		if (dev_priv->pfp_fw) {
+			release_firmware(dev_priv->pfp_fw);
+			dev_priv->pfp_fw = NULL;
+		}
 	}
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index a169067..12f5990 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -145,7 +145,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
 		cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data;
 
 		size = p->chunks[i].length_dw * sizeof(uint32_t);
-		p->chunks[i].kdata = kzalloc(size, GFP_KERNEL);
+		p->chunks[i].kdata = kmalloc(size, GFP_KERNEL);
 		if (p->chunks[i].kdata == NULL) {
 			return -ENOMEM;
 		}
@@ -185,6 +185,7 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
 			mutex_unlock(&parser->rdev->ddev->struct_mutex);
 		}
 	}
+	kfree(parser->track);
 	kfree(parser->relocs);
 	kfree(parser->relocs_ptr);
 	for (i = 0; i < parser->nchunks; i++) {
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 7693f7c..daf5db7 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -29,6 +29,7 @@
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/radeon_drm.h>
+#include <linux/vgaarb.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 #include "radeon_asic.h"
@@ -37,7 +38,7 @@
 /*
  * Clear GPU surface registers.
  */
-static void radeon_surface_init(struct radeon_device *rdev)
+void radeon_surface_init(struct radeon_device *rdev)
 {
 	/* FIXME: check this out */
 	if (rdev->family < CHIP_R600) {
@@ -56,7 +57,7 @@ static void radeon_surface_init(struct radeon_device *rdev)
 /*
  * GPU scratch registers helpers function.
  */
-static void radeon_scratch_init(struct radeon_device *rdev)
+void radeon_scratch_init(struct radeon_device *rdev)
 {
 	int i;
 
@@ -156,16 +157,18 @@ int radeon_mc_setup(struct radeon_device *rdev)
 		tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
 		rdev->mc.gtt_location = tmp;
 	}
-	DRM_INFO("radeon: VRAM %uM\n", rdev->mc.real_vram_size >> 20);
+	rdev->mc.vram_start = rdev->mc.vram_location;
+	rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
+	rdev->mc.gtt_start = rdev->mc.gtt_location;
+	rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
+	DRM_INFO("radeon: VRAM %uM\n", (unsigned)(rdev->mc.mc_vram_size >> 20));
 	DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
-		 rdev->mc.vram_location,
-		 rdev->mc.vram_location + rdev->mc.mc_vram_size - 1);
-	if (rdev->mc.real_vram_size != rdev->mc.mc_vram_size)
-		DRM_INFO("radeon: VRAM less than aperture workaround enabled\n");
-	DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20);
+		 (unsigned)rdev->mc.vram_location,
+		 (unsigned)(rdev->mc.vram_location + rdev->mc.mc_vram_size - 1));
+	DRM_INFO("radeon: GTT %uM\n", (unsigned)(rdev->mc.gtt_size >> 20));
 	DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
-		 rdev->mc.gtt_location,
-		 rdev->mc.gtt_location + rdev->mc.gtt_size - 1);
+		 (unsigned)rdev->mc.gtt_location,
+		 (unsigned)(rdev->mc.gtt_location + rdev->mc.gtt_size - 1));
 	return 0;
 }
 
@@ -173,7 +176,7 @@ int radeon_mc_setup(struct radeon_device *rdev)
 /*
  * GPU helpers function.
  */
-static bool radeon_card_posted(struct radeon_device *rdev)
+bool radeon_card_posted(struct radeon_device *rdev)
 {
 	uint32_t reg;
 
@@ -205,6 +208,31 @@ static bool radeon_card_posted(struct radeon_device *rdev)
 
 }
 
+int radeon_dummy_page_init(struct radeon_device *rdev)
+{
+	rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO);
+	if (rdev->dummy_page.page == NULL)
+		return -ENOMEM;
+	rdev->dummy_page.addr = pci_map_page(rdev->pdev, rdev->dummy_page.page,
+					0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+	if (!rdev->dummy_page.addr) {
+		__free_page(rdev->dummy_page.page);
+		rdev->dummy_page.page = NULL;
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+void radeon_dummy_page_fini(struct radeon_device *rdev)
+{
+	if (rdev->dummy_page.page == NULL)
+		return;
+	pci_unmap_page(rdev->pdev, rdev->dummy_page.addr,
+			PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+	__free_page(rdev->dummy_page.page);
+	rdev->dummy_page.page = NULL;
+}
+
 
 /*
  * Registers accessors functions.
@@ -243,6 +271,10 @@ void radeon_register_accessor_init(struct radeon_device *rdev)
 		rdev->pll_rreg = &r100_pll_rreg;
 		rdev->pll_wreg = &r100_pll_wreg;
 	}
+	if (rdev->family >= CHIP_R420) {
+		rdev->mc_rreg = &r420_mc_rreg;
+		rdev->mc_wreg = &r420_mc_wreg;
+	}
 	if (rdev->family >= CHIP_RV515) {
 		rdev->mc_rreg = &rv515_mc_rreg;
 		rdev->mc_wreg = &rv515_mc_wreg;
@@ -289,6 +321,14 @@ int radeon_asic_init(struct radeon_device *rdev)
 	case CHIP_RV350:
 	case CHIP_RV380:
 		rdev->asic = &r300_asic;
+		if (rdev->flags & RADEON_IS_PCIE) {
+			rdev->asic->gart_init = &rv370_pcie_gart_init;
+			rdev->asic->gart_fini = &rv370_pcie_gart_fini;
+			rdev->asic->gart_enable = &rv370_pcie_gart_enable;
+			rdev->asic->gart_disable = &rv370_pcie_gart_disable;
+			rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+			rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
+		}
 		break;
 	case CHIP_R420:
 	case CHIP_R423:
@@ -323,9 +363,15 @@ int radeon_asic_init(struct radeon_device *rdev)
 	case CHIP_RV635:
 	case CHIP_RV670:
 	case CHIP_RS780:
+	case CHIP_RS880:
+		rdev->asic = &r600_asic;
+		break;
 	case CHIP_RV770:
 	case CHIP_RV730:
 	case CHIP_RV710:
+	case CHIP_RV740:
+		rdev->asic = &rv770_asic;
+		break;
 	default:
 		/* FIXME: not supported yet */
 		return -EINVAL;
@@ -341,7 +387,6 @@ int radeon_clocks_init(struct radeon_device *rdev)
 {
 	int r;
 
-	radeon_get_clock_info(rdev->ddev);
 	r = radeon_static_clocks_init(rdev->ddev);
 	if (r) {
 		return r;
@@ -436,10 +481,18 @@ void radeon_combios_fini(struct radeon_device *rdev)
 {
 }
 
-int radeon_modeset_init(struct radeon_device *rdev);
-void radeon_modeset_fini(struct radeon_device *rdev);
-
+/* if we get transitioned to only one device, tak VGA back */
+static unsigned int radeon_vga_set_decode(void *cookie, bool state)
+{
+	struct radeon_device *rdev = cookie;
 
+	radeon_vga_set_state(rdev, state);
+	if (state)
+		return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+		       VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+	else
+		return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+}
 /*
  * Radeon device.
  */
@@ -448,11 +501,12 @@ int radeon_device_init(struct radeon_device *rdev,
 		       struct pci_dev *pdev,
 		       uint32_t flags)
 {
-	int r, ret;
+	int r;
 	int dma_bits;
 
 	DRM_INFO("radeon: Initializing kernel modesetting.\n");
 	rdev->shutdown = false;
+	rdev->dev = &pdev->dev;
 	rdev->ddev = ddev;
 	rdev->pdev = pdev;
 	rdev->flags = flags;
@@ -461,37 +515,47 @@ int radeon_device_init(struct radeon_device *rdev,
 	rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT;
 	rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
 	rdev->gpu_lockup = false;
+	rdev->accel_working = false;
 	/* mutex initialization are all done here so we
 	 * can recall function without having locking issues */
 	mutex_init(&rdev->cs_mutex);
 	mutex_init(&rdev->ib_pool.mutex);
 	mutex_init(&rdev->cp.mutex);
 	rwlock_init(&rdev->fence_drv.lock);
+	INIT_LIST_HEAD(&rdev->gem.objects);
+
+	/* Set asic functions */
+	r = radeon_asic_init(rdev);
+	if (r) {
+		return r;
+	}
 
 	if (radeon_agpmode == -1) {
 		rdev->flags &= ~RADEON_IS_AGP;
-		if (rdev->family > CHIP_RV515 ||
+		if (rdev->family >= CHIP_RV515 ||
 		    rdev->family == CHIP_RV380 ||
 		    rdev->family == CHIP_RV410 ||
 		    rdev->family == CHIP_R423) {
 			DRM_INFO("Forcing AGP to PCIE mode\n");
 			rdev->flags |= RADEON_IS_PCIE;
+			rdev->asic->gart_init = &rv370_pcie_gart_init;
+			rdev->asic->gart_fini = &rv370_pcie_gart_fini;
+			rdev->asic->gart_enable = &rv370_pcie_gart_enable;
+			rdev->asic->gart_disable = &rv370_pcie_gart_disable;
+			rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
+			rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
 		} else {
 			DRM_INFO("Forcing AGP to PCI mode\n");
 			rdev->flags |= RADEON_IS_PCI;
+			rdev->asic->gart_init = &r100_pci_gart_init;
+			rdev->asic->gart_fini = &r100_pci_gart_fini;
+			rdev->asic->gart_enable = &r100_pci_gart_enable;
+			rdev->asic->gart_disable = &r100_pci_gart_disable;
+			rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
+			rdev->asic->gart_set_page = &r100_pci_gart_set_page;
 		}
 	}
 
-	/* Set asic functions */
-	r = radeon_asic_init(rdev);
-	if (r) {
-		return r;
-	}
-	r = radeon_init(rdev);
-	if (r) {
-		return r;
-	}
-
 	/* set DMA mask + need_dma32 flags.
 	 * PCIE - can handle 40-bits.
 	 * IGP - can handle 40-bits (in theory)
@@ -521,156 +585,150 @@ int radeon_device_init(struct radeon_device *rdev,
 	DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
 	DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
 
-	/* Setup errata flags */
-	radeon_errata(rdev);
-	/* Initialize scratch registers */
-	radeon_scratch_init(rdev);
-	/* Initialize surface registers */
-	radeon_surface_init(rdev);
-
-	/* TODO: disable VGA need to use VGA request */
-	/* BIOS*/
-	if (!radeon_get_bios(rdev)) {
-		if (ASIC_IS_AVIVO(rdev))
-			return -EINVAL;
-	}
-	if (rdev->is_atom_bios) {
-		r = radeon_atombios_init(rdev);
-		if (r) {
-			return r;
-		}
-	} else {
-		r = radeon_combios_init(rdev);
-		if (r) {
-			return r;
-		}
-	}
-	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
-	if (radeon_gpu_reset(rdev)) {
-		/* FIXME: what do we want to do here ? */
-	}
-	/* check if cards are posted or not */
-	if (!radeon_card_posted(rdev) && rdev->bios) {
-		DRM_INFO("GPU not posted. posting now...\n");
-		if (rdev->is_atom_bios) {
-			atom_asic_init(rdev->mode_info.atom_context);
-		} else {
-			radeon_combios_asic_init(rdev->ddev);
-		}
-	}
-	/* Initialize clocks */
-	r = radeon_clocks_init(rdev);
-	if (r) {
-		return r;
-	}
-	/* Get vram informations */
-	radeon_vram_info(rdev);
-
-	/* Add an MTRR for the VRAM */
-	rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
-				      MTRR_TYPE_WRCOMB, 1);
-	DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n",
-		 rdev->mc.real_vram_size >> 20,
-		 (unsigned)rdev->mc.aper_size >> 20);
-	DRM_INFO("RAM width %dbits %cDR\n",
-		 rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S');
-	/* Initialize memory controller (also test AGP) */
-	r = radeon_mc_init(rdev);
-	if (r) {
-		return r;
-	}
-	/* Fence driver */
-	r = radeon_fence_driver_init(rdev);
-	if (r) {
-		return r;
-	}
-	r = radeon_irq_kms_init(rdev);
+	rdev->new_init_path = false;
+	r = radeon_init(rdev);
 	if (r) {
 		return r;
 	}
-	/* Memory manager */
-	r = radeon_object_init(rdev);
+
+	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
+	r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
 	if (r) {
-		return r;
-	}
-	/* Initialize GART (initialize after TTM so we can allocate
-	 * memory through TTM but finalize after TTM) */
-	r = radeon_gart_enable(rdev);
-	if (!r) {
-		r = radeon_gem_init(rdev);
+		return -EINVAL;
 	}
 
-	/* 1M ring buffer */
-	if (!r) {
-		r = radeon_cp_init(rdev, 1024 * 1024);
-	}
-	if (!r) {
-		r = radeon_wb_init(rdev);
+	if (!rdev->new_init_path) {
+		/* Setup errata flags */
+		radeon_errata(rdev);
+		/* Initialize scratch registers */
+		radeon_scratch_init(rdev);
+		/* Initialize surface registers */
+		radeon_surface_init(rdev);
+
+		/* BIOS*/
+		if (!radeon_get_bios(rdev)) {
+			if (ASIC_IS_AVIVO(rdev))
+				return -EINVAL;
+		}
+		if (rdev->is_atom_bios) {
+			r = radeon_atombios_init(rdev);
+			if (r) {
+				return r;
+			}
+		} else {
+			r = radeon_combios_init(rdev);
+			if (r) {
+				return r;
+			}
+		}
+		/* Reset gpu before posting otherwise ATOM will enter infinite loop */
+		if (radeon_gpu_reset(rdev)) {
+			/* FIXME: what do we want to do here ? */
+		}
+		/* check if cards are posted or not */
+		if (!radeon_card_posted(rdev) && rdev->bios) {
+			DRM_INFO("GPU not posted. posting now...\n");
+			if (rdev->is_atom_bios) {
+				atom_asic_init(rdev->mode_info.atom_context);
+			} else {
+				radeon_combios_asic_init(rdev->ddev);
+			}
+		}
+		/* Get clock & vram information */
+		radeon_get_clock_info(rdev->ddev);
+		radeon_vram_info(rdev);
+		/* Initialize clocks */
+		r = radeon_clocks_init(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
 			return r;
 		}
-	}
-	if (!r) {
-		r = radeon_ib_pool_init(rdev);
+
+		/* Initialize memory controller (also test AGP) */
+		r = radeon_mc_init(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
 			return r;
 		}
-	}
-	if (!r) {
-		r = radeon_ib_test(rdev);
+		/* Fence driver */
+		r = radeon_fence_driver_init(rdev);
 		if (r) {
-			DRM_ERROR("radeon: failled testing IB (%d).\n", r);
 			return r;
 		}
+		r = radeon_irq_kms_init(rdev);
+		if (r) {
+			return r;
+		}
+		/* Memory manager */
+		r = radeon_object_init(rdev);
+		if (r) {
+			return r;
+		}
+		r = radeon_gpu_gart_init(rdev);
+		if (r)
+			return r;
+		/* Initialize GART (initialize after TTM so we can allocate
+		 * memory through TTM but finalize after TTM) */
+		r = radeon_gart_enable(rdev);
+		if (r)
+			return 0;
+			r = radeon_gem_init(rdev);
+		if (r)
+			return 0;
+
+		/* 1M ring buffer */
+		r = radeon_cp_init(rdev, 1024 * 1024);
+		if (r)
+			return 0;
+		r = radeon_wb_init(rdev);
+		if (r)
+			DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
+		r = radeon_ib_pool_init(rdev);
+		if (r)
+			return 0;
+		r = radeon_ib_test(rdev);
+		if (r)
+			return 0;
+		rdev->accel_working = true;
 	}
-	ret = r;
-	r = radeon_modeset_init(rdev);
-	if (r) {
-		return r;
-	}
-	if (!ret) {
-		DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
-	}
+	DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
 	if (radeon_testing) {
 		radeon_test_moves(rdev);
 	}
 	if (radeon_benchmarking) {
 		radeon_benchmark(rdev);
 	}
-	return ret;
+	return 0;
 }
 
 void radeon_device_fini(struct radeon_device *rdev)
 {
-	if (rdev == NULL || rdev->rmmio == NULL) {
-		return;
-	}
 	DRM_INFO("radeon: finishing device.\n");
 	rdev->shutdown = true;
 	/* Order matter so becarefull if you rearrange anythings */
-	radeon_modeset_fini(rdev);
-	radeon_ib_pool_fini(rdev);
-	radeon_cp_fini(rdev);
-	radeon_wb_fini(rdev);
-	radeon_gem_fini(rdev);
-	radeon_object_fini(rdev);
-	/* mc_fini must be after object_fini */
-	radeon_mc_fini(rdev);
+	if (!rdev->new_init_path) {
+		radeon_ib_pool_fini(rdev);
+		radeon_cp_fini(rdev);
+		radeon_wb_fini(rdev);
+		radeon_gpu_gart_fini(rdev);
+		radeon_gem_fini(rdev);
+		radeon_mc_fini(rdev);
 #if __OS_HAS_AGP
-	radeon_agp_fini(rdev);
+		radeon_agp_fini(rdev);
 #endif
-	radeon_irq_kms_fini(rdev);
-	radeon_fence_driver_fini(rdev);
-	radeon_clocks_fini(rdev);
-	if (rdev->is_atom_bios) {
-		radeon_atombios_fini(rdev);
+		radeon_irq_kms_fini(rdev);
+		vga_client_register(rdev->pdev, NULL, NULL, NULL);
+		radeon_fence_driver_fini(rdev);
+		radeon_clocks_fini(rdev);
+		radeon_object_fini(rdev);
+		if (rdev->is_atom_bios) {
+			radeon_atombios_fini(rdev);
+		} else {
+			radeon_combios_fini(rdev);
+		}
+		kfree(rdev->bios);
+		rdev->bios = NULL;
 	} else {
-		radeon_combios_fini(rdev);
+		radeon_fini(rdev);
 	}
-	kfree(rdev->bios);
-	rdev->bios = NULL;
 	iounmap(rdev->rmmio);
 	rdev->rmmio = NULL;
 }
@@ -708,15 +766,19 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
 	/* wait for gpu to finish processing current batch */
 	radeon_fence_wait_last(rdev);
 
-	radeon_cp_disable(rdev);
-	radeon_gart_disable(rdev);
+	radeon_save_bios_scratch_regs(rdev);
 
+	if (!rdev->new_init_path) {
+		radeon_cp_disable(rdev);
+		radeon_gart_disable(rdev);
+		rdev->irq.sw_int = false;
+		radeon_irq_set(rdev);
+	} else {
+		radeon_suspend(rdev);
+	}
 	/* evict remaining vram memory */
 	radeon_object_evict_vram(rdev);
 
-	rdev->irq.sw_int = false;
-	radeon_irq_set(rdev);
-
 	pci_save_state(dev->pdev);
 	if (state.event == PM_EVENT_SUSPEND) {
 		/* Shut down the device */
@@ -743,38 +805,43 @@ int radeon_resume_kms(struct drm_device *dev)
 	}
 	pci_set_master(dev->pdev);
 	/* Reset gpu before posting otherwise ATOM will enter infinite loop */
-	if (radeon_gpu_reset(rdev)) {
-		/* FIXME: what do we want to do here ? */
-	}
-	/* post card */
-	if (rdev->is_atom_bios) {
-		atom_asic_init(rdev->mode_info.atom_context);
+	if (!rdev->new_init_path) {
+		if (radeon_gpu_reset(rdev)) {
+			/* FIXME: what do we want to do here ? */
+		}
+		/* post card */
+		if (rdev->is_atom_bios) {
+			atom_asic_init(rdev->mode_info.atom_context);
+		} else {
+			radeon_combios_asic_init(rdev->ddev);
+		}
+		/* Initialize clocks */
+		r = radeon_clocks_init(rdev);
+		if (r) {
+			release_console_sem();
+			return r;
+		}
+		/* Enable IRQ */
+		rdev->irq.sw_int = true;
+		radeon_irq_set(rdev);
+		/* Initialize GPU Memory Controller */
+		r = radeon_mc_init(rdev);
+		if (r) {
+			goto out;
+		}
+		r = radeon_gart_enable(rdev);
+		if (r) {
+			goto out;
+		}
+		r = radeon_cp_init(rdev, rdev->cp.ring_size);
+		if (r) {
+			goto out;
+		}
 	} else {
-		radeon_combios_asic_init(rdev->ddev);
-	}
-	/* Initialize clocks */
-	r = radeon_clocks_init(rdev);
-	if (r) {
-		release_console_sem();
-		return r;
-	}
-	/* Enable IRQ */
-	rdev->irq.sw_int = true;
-	radeon_irq_set(rdev);
-	/* Initialize GPU Memory Controller */
-	r = radeon_mc_init(rdev);
-	if (r) {
-		goto out;
-	}
-	r = radeon_gart_enable(rdev);
-	if (r) {
-		goto out;
-	}
-	r = radeon_cp_init(rdev, rdev->cp.ring_size);
-	if (r) {
-		goto out;
+		radeon_resume(rdev);
 	}
 out:
+	radeon_restore_bios_scratch_regs(rdev);
 	fb_set_suspend(rdev->fbdev_info, 0);
 	release_console_sem();
 
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index a8fa1bb..5d8141b 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -158,9 +158,6 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
 
-	if (radeon_crtc->mode_set.mode) {
-		drm_mode_destroy(crtc->dev, radeon_crtc->mode_set.mode);
-	}
 	drm_crtc_cleanup(crtc);
 	kfree(radeon_crtc);
 }
@@ -189,9 +186,11 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
 	radeon_crtc->crtc_id = index;
 	rdev->mode_info.crtcs[index] = radeon_crtc;
 
+#if 0
 	radeon_crtc->mode_set.crtc = &radeon_crtc->base;
 	radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
 	radeon_crtc->mode_set.num_connectors = 0;
+#endif
 
 	for (i = 0; i < 256; i++) {
 		radeon_crtc->lut_r[i] = i << 2;
@@ -313,7 +312,7 @@ static void radeon_print_display_setup(struct drm_device *dev)
 	}
 }
 
-bool radeon_setup_enc_conn(struct drm_device *dev)
+static bool radeon_setup_enc_conn(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_connector *drm_connector;
@@ -347,9 +346,13 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
 
 	if (!radeon_connector->ddc_bus)
 		return -1;
-	radeon_i2c_do_lock(radeon_connector, 1);
-	edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
-	radeon_i2c_do_lock(radeon_connector, 0);
+	if (!radeon_connector->edid) {
+		radeon_i2c_do_lock(radeon_connector, 1);
+		edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
+		radeon_i2c_do_lock(radeon_connector, 0);
+	} else
+		edid = radeon_connector->edid;
+
 	if (edid) {
 		/* update digital bits here */
 		if (edid->input & DRM_EDID_INPUT_DIGITAL)
@@ -362,7 +365,7 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
 		return ret;
 	}
 	drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
-	return -1;
+	return 0;
 }
 
 static int radeon_ddc_dump(struct drm_connector *connector)
@@ -620,6 +623,83 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
 	.fb_changed = radeonfb_probe,
 };
 
+struct drm_prop_enum_list {
+	int type;
+	char *name;
+};
+
+static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
+{	{ 0, "driver" },
+	{ 1, "bios" },
+};
+
+static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
+{	{ TV_STD_NTSC, "ntsc" },
+	{ TV_STD_PAL, "pal" },
+	{ TV_STD_PAL_M, "pal-m" },
+	{ TV_STD_PAL_60, "pal-60" },
+	{ TV_STD_NTSC_J, "ntsc-j" },
+	{ TV_STD_SCART_PAL, "scart-pal" },
+	{ TV_STD_PAL_CN, "pal-cn" },
+	{ TV_STD_SECAM, "secam" },
+};
+
+int radeon_modeset_create_props(struct radeon_device *rdev)
+{
+	int i, sz;
+
+	if (rdev->is_atom_bios) {
+		rdev->mode_info.coherent_mode_property =
+			drm_property_create(rdev->ddev,
+					    DRM_MODE_PROP_RANGE,
+					    "coherent", 2);
+		if (!rdev->mode_info.coherent_mode_property)
+			return -ENOMEM;
+
+		rdev->mode_info.coherent_mode_property->values[0] = 0;
+		rdev->mode_info.coherent_mode_property->values[0] = 1;
+	}
+
+	if (!ASIC_IS_AVIVO(rdev)) {
+		sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
+		rdev->mode_info.tmds_pll_property =
+			drm_property_create(rdev->ddev,
+					    DRM_MODE_PROP_ENUM,
+					    "tmds_pll", sz);
+		for (i = 0; i < sz; i++) {
+			drm_property_add_enum(rdev->mode_info.tmds_pll_property,
+					      i,
+					      radeon_tmds_pll_enum_list[i].type,
+					      radeon_tmds_pll_enum_list[i].name);
+		}
+	}
+
+	rdev->mode_info.load_detect_property =
+		drm_property_create(rdev->ddev,
+				    DRM_MODE_PROP_RANGE,
+				    "load detection", 2);
+	if (!rdev->mode_info.load_detect_property)
+		return -ENOMEM;
+	rdev->mode_info.load_detect_property->values[0] = 0;
+	rdev->mode_info.load_detect_property->values[0] = 1;
+
+	drm_mode_create_scaling_mode_property(rdev->ddev);
+
+	sz = ARRAY_SIZE(radeon_tv_std_enum_list);
+	rdev->mode_info.tv_std_property =
+		drm_property_create(rdev->ddev,
+				    DRM_MODE_PROP_ENUM,
+				    "tv standard", sz);
+	for (i = 0; i < sz; i++) {
+		drm_property_add_enum(rdev->mode_info.tv_std_property,
+				      i,
+				      radeon_tv_std_enum_list[i].type,
+				      radeon_tv_std_enum_list[i].name);
+	}
+
+	return 0;
+}
+
 int radeon_modeset_init(struct radeon_device *rdev)
 {
 	int num_crtc = 2, i;
@@ -640,6 +720,10 @@ int radeon_modeset_init(struct radeon_device *rdev)
 
 	rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
 
+	ret = radeon_modeset_create_props(rdev);
+	if (ret) {
+		return ret;
+	}
 	/* allocate crtcs - TODO single crtc */
 	for (i = 0; i < num_crtc; i++) {
 		radeon_crtc_init(rdev->ddev, i);
@@ -678,7 +762,6 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
 			continue;
 		if (first) {
 			radeon_crtc->rmx_type = radeon_encoder->rmx_type;
-			radeon_crtc->devices = radeon_encoder->devices;
 			memcpy(&radeon_crtc->native_mode,
 				&radeon_encoder->native_mode,
 				sizeof(struct radeon_native_mode));
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 0bd5879..50fce49 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -38,7 +38,6 @@
 #include <linux/console.h>
 
 
-#if defined(CONFIG_DRM_RADEON_KMS)
 /*
  * KMS wrapper.
  */
@@ -77,11 +76,9 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
 int radeon_debugfs_init(struct drm_minor *minor);
 void radeon_debugfs_cleanup(struct drm_minor *minor);
 #endif
-#endif
 
 
 int radeon_no_wb;
-#if defined(CONFIG_DRM_RADEON_KMS)
 int radeon_modeset = -1;
 int radeon_dynclks = -1;
 int radeon_r4xx_atom = 0;
@@ -91,12 +88,11 @@ int radeon_gart_size = 512; /* default gart size */
 int radeon_benchmarking = 0;
 int radeon_testing = 0;
 int radeon_connector_table = 0;
-#endif
+int radeon_tv = 1;
 
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
 
-#if defined(CONFIG_DRM_RADEON_KMS)
 MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
 module_param_named(modeset, radeon_modeset, int, 0400);
 
@@ -123,7 +119,9 @@ module_param_named(test, radeon_testing, int, 0444);
 
 MODULE_PARM_DESC(connector_table, "Force connector table");
 module_param_named(connector_table, radeon_connector_table, int, 0444);
-#endif
+
+MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
+module_param_named(tv, radeon_tv, int, 0444);
 
 static int radeon_suspend(struct drm_device *dev, pm_message_t state)
 {
@@ -215,7 +213,6 @@ static struct drm_driver driver_old = {
 	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
-#if defined(CONFIG_DRM_RADEON_KMS)
 static struct drm_driver kms_driver;
 
 static int __devinit
@@ -289,7 +286,7 @@ static struct drm_driver kms_driver = {
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
 #ifdef CONFIG_COMPAT
-		 .compat_ioctl = NULL,
+		 .compat_ioctl = radeon_kms_compat_ioctl,
 #endif
 	},
 
@@ -309,7 +306,6 @@ static struct drm_driver kms_driver = {
 	.minor = KMS_DRIVER_MINOR,
 	.patchlevel = KMS_DRIVER_PATCHLEVEL,
 };
-#endif
 
 static struct drm_driver *driver;
 
@@ -317,7 +313,6 @@ static int __init radeon_init(void)
 {
 	driver = &driver_old;
 	driver->num_ioctls = radeon_max_ioctl;
-#if defined(CONFIG_DRM_RADEON_KMS)
 #ifdef CONFIG_VGA_CONSOLE
 	if (vgacon_text_force() && radeon_modeset == -1) {
 		DRM_INFO("VGACON disable radeon kernel modesetting.\n");
@@ -328,8 +323,13 @@ static int __init radeon_init(void)
 #endif
 	/* if enabled by default */
 	if (radeon_modeset == -1) {
-		DRM_INFO("radeon default to kernel modesetting.\n");
+#ifdef CONFIG_DRM_RADEON_KMS
+		DRM_INFO("radeon defaulting to kernel modesetting.\n");
 		radeon_modeset = 1;
+#else
+		DRM_INFO("radeon defaulting to userspace modesetting.\n");
+		radeon_modeset = 0;
+#endif
 	}
 	if (radeon_modeset == 1) {
 		DRM_INFO("radeon kernel modesetting enabled.\n");
@@ -339,7 +339,6 @@ static int __init radeon_init(void)
 	}
 	/* if the vga console setting is enabled still
 	 * let modprobe override it */
-#endif
 	return drm_init(driver);
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 6fa32da..cb0cfe4 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -31,6 +31,9 @@
 #ifndef __RADEON_DRV_H__
 #define __RADEON_DRV_H__
 
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+
 /* General customization:
  */
 
@@ -353,6 +356,14 @@ typedef struct drm_radeon_private {
 	int r700_sc_hiz_tile_fifo_size;
 	int r700_sc_earlyz_tile_fifo_fize;
 
+	struct mutex cs_mutex;
+	u32 cs_id_scnt;
+	u32 cs_id_wcnt;
+	/* r6xx/r7xx drm blit vertex buffer */
+	struct drm_buf *blit_vb;
+
+	/* firmware */
+	const struct firmware *me_fw, *pfp_fw;
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
@@ -391,6 +402,9 @@ static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
 		(off >= gart_start && off <= gart_end));
 }
 
+/* radeon_state.c */
+extern void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf);
+
 				/* radeon_cp.c */
 extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
 extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv);
@@ -457,6 +471,8 @@ extern int radeon_driver_open(struct drm_device *dev,
 			      struct drm_file *file_priv);
 extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
 				unsigned long arg);
+extern long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd,
+				    unsigned long arg);
 
 extern int radeon_master_create(struct drm_device *dev, struct drm_master *master);
 extern void radeon_master_destroy(struct drm_device *dev, struct drm_master *master);
@@ -482,6 +498,22 @@ extern int r600_cp_dispatch_indirect(struct drm_device *dev,
 				     struct drm_buf *buf, int start, int end);
 extern int r600_page_table_init(struct drm_device *dev);
 extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
+extern int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv);
+extern void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv);
+extern int r600_cp_dispatch_texture(struct drm_device *dev,
+				    struct drm_file *file_priv,
+				    drm_radeon_texture_t *tex,
+				    drm_radeon_tex_image_t *image);
+/* r600_blit.c */
+extern int r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv);
+extern void r600_done_blit_copy(struct drm_device *dev);
+extern void r600_blit_copy(struct drm_device *dev,
+			   uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+			   int size_bytes);
+extern void r600_blit_swap(struct drm_device *dev,
+			   uint64_t src_gpu_addr, uint64_t dst_gpu_addr,
+			   int sx, int sy, int dx, int dy,
+			   int w, int h, int src_pitch, int dst_pitch, int cpp);
 
 /* Flags for stats.boxes
  */
@@ -1067,6 +1099,9 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
 #	define RADEON_CSQ_PRIBM_INDBM		(4 << 28)
 #	define RADEON_CSQ_PRIPIO_INDPIO		(15 << 28)
 
+#define R300_CP_RESYNC_ADDR		0x0778
+#define R300_CP_RESYNC_DATA		0x077c
+
 #define RADEON_AIC_CNTL			0x01d0
 #	define RADEON_PCIGART_TRANSLATE_EN	(1 << 0)
 #	define RS400_MSI_REARM	                (1 << 3)
@@ -1109,13 +1144,71 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
 #	define RADEON_CNTL_BITBLT_MULTI		0x00009B00
 #	define RADEON_CNTL_SET_SCISSORS		0xC0001E00
 
-#	define R600_IT_INDIRECT_BUFFER		0x00003200
-#	define R600_IT_ME_INITIALIZE		0x00004400
+#       define R600_IT_INDIRECT_BUFFER_END      0x00001700
+#       define R600_IT_SET_PREDICATION          0x00002000
+#       define R600_IT_REG_RMW                  0x00002100
+#       define R600_IT_COND_EXEC                0x00002200
+#       define R600_IT_PRED_EXEC                0x00002300
+#       define R600_IT_START_3D_CMDBUF          0x00002400
+#       define R600_IT_DRAW_INDEX_2             0x00002700
+#       define R600_IT_CONTEXT_CONTROL          0x00002800
+#       define R600_IT_DRAW_INDEX_IMMD_BE       0x00002900
+#       define R600_IT_INDEX_TYPE               0x00002A00
+#       define R600_IT_DRAW_INDEX               0x00002B00
+#       define R600_IT_DRAW_INDEX_AUTO          0x00002D00
+#       define R600_IT_DRAW_INDEX_IMMD          0x00002E00
+#       define R600_IT_NUM_INSTANCES            0x00002F00
+#       define R600_IT_STRMOUT_BUFFER_UPDATE    0x00003400
+#       define R600_IT_INDIRECT_BUFFER_MP       0x00003800
+#       define R600_IT_MEM_SEMAPHORE            0x00003900
+#       define R600_IT_MPEG_INDEX               0x00003A00
+#       define R600_IT_WAIT_REG_MEM             0x00003C00
+#       define R600_IT_MEM_WRITE                0x00003D00
+#       define R600_IT_INDIRECT_BUFFER          0x00003200
+#       define R600_IT_CP_INTERRUPT             0x00004000
+#       define R600_IT_SURFACE_SYNC             0x00004300
+#              define R600_CB0_DEST_BASE_ENA    (1 << 6)
+#              define R600_TC_ACTION_ENA        (1 << 23)
+#              define R600_VC_ACTION_ENA        (1 << 24)
+#              define R600_CB_ACTION_ENA        (1 << 25)
+#              define R600_DB_ACTION_ENA        (1 << 26)
+#              define R600_SH_ACTION_ENA        (1 << 27)
+#              define R600_SMX_ACTION_ENA       (1 << 28)
+#       define R600_IT_ME_INITIALIZE            0x00004400
 #	       define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
-#	define R600_IT_EVENT_WRITE		0x00004600
-#	define R600_IT_SET_CONFIG_REG		0x00006800
-#	define R600_SET_CONFIG_REG_OFFSET       0x00008000
-#	define R600_SET_CONFIG_REG_END          0x0000ac00
+#       define R600_IT_COND_WRITE               0x00004500
+#       define R600_IT_EVENT_WRITE              0x00004600
+#       define R600_IT_EVENT_WRITE_EOP          0x00004700
+#       define R600_IT_ONE_REG_WRITE            0x00005700
+#       define R600_IT_SET_CONFIG_REG           0x00006800
+#              define R600_SET_CONFIG_REG_OFFSET 0x00008000
+#              define R600_SET_CONFIG_REG_END   0x0000ac00
+#       define R600_IT_SET_CONTEXT_REG          0x00006900
+#              define R600_SET_CONTEXT_REG_OFFSET 0x00028000
+#              define R600_SET_CONTEXT_REG_END  0x00029000
+#       define R600_IT_SET_ALU_CONST            0x00006A00
+#              define R600_SET_ALU_CONST_OFFSET 0x00030000
+#              define R600_SET_ALU_CONST_END    0x00032000
+#       define R600_IT_SET_BOOL_CONST           0x00006B00
+#              define R600_SET_BOOL_CONST_OFFSET 0x0003e380
+#              define R600_SET_BOOL_CONST_END   0x00040000
+#       define R600_IT_SET_LOOP_CONST           0x00006C00
+#              define R600_SET_LOOP_CONST_OFFSET 0x0003e200
+#              define R600_SET_LOOP_CONST_END   0x0003e380
+#       define R600_IT_SET_RESOURCE             0x00006D00
+#              define R600_SET_RESOURCE_OFFSET  0x00038000
+#              define R600_SET_RESOURCE_END     0x0003c000
+#              define R600_SQ_TEX_VTX_INVALID_TEXTURE  0x0
+#              define R600_SQ_TEX_VTX_INVALID_BUFFER   0x1
+#              define R600_SQ_TEX_VTX_VALID_TEXTURE    0x2
+#              define R600_SQ_TEX_VTX_VALID_BUFFER     0x3
+#       define R600_IT_SET_SAMPLER              0x00006E00
+#              define R600_SET_SAMPLER_OFFSET   0x0003c000
+#              define R600_SET_SAMPLER_END      0x0003cff0
+#       define R600_IT_SET_CTL_CONST            0x00006F00
+#              define R600_SET_CTL_CONST_OFFSET 0x0003cff0
+#              define R600_SET_CTL_CONST_END    0x0003e200
+#       define R600_IT_SURFACE_BASE_UPDATE      0x00007300
 
 #define RADEON_CP_PACKET_MASK		0xC0000000
 #define RADEON_CP_PACKET_COUNT_MASK	0x3fff0000
@@ -1593,6 +1686,52 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
 #define R600_CB_COLOR7_BASE                                    0x2805c
 #define R600_CB_COLOR7_FRAG                                    0x280fc
 
+#define R600_CB_COLOR0_SIZE                                    0x28060
+#define R600_CB_COLOR0_VIEW                                    0x28080
+#define R600_CB_COLOR0_INFO                                    0x280a0
+#define R600_CB_COLOR0_TILE                                    0x280c0
+#define R600_CB_COLOR0_FRAG                                    0x280e0
+#define R600_CB_COLOR0_MASK                                    0x28100
+
+#define AVIVO_D1MODE_VLINE_START_END                           0x6538
+#define AVIVO_D2MODE_VLINE_START_END                           0x6d38
+#define R600_CP_COHER_BASE                                     0x85f8
+#define R600_DB_DEPTH_BASE                                     0x2800c
+#define R600_SQ_PGM_START_FS                                   0x28894
+#define R600_SQ_PGM_START_ES                                   0x28880
+#define R600_SQ_PGM_START_VS                                   0x28858
+#define R600_SQ_PGM_RESOURCES_VS                               0x28868
+#define R600_SQ_PGM_CF_OFFSET_VS                               0x288d0
+#define R600_SQ_PGM_START_GS                                   0x2886c
+#define R600_SQ_PGM_START_PS                                   0x28840
+#define R600_SQ_PGM_RESOURCES_PS                               0x28850
+#define R600_SQ_PGM_EXPORTS_PS                                 0x28854
+#define R600_SQ_PGM_CF_OFFSET_PS                               0x288cc
+#define R600_VGT_DMA_BASE                                      0x287e8
+#define R600_VGT_DMA_BASE_HI                                   0x287e4
+#define R600_VGT_STRMOUT_BASE_OFFSET_0                         0x28b10
+#define R600_VGT_STRMOUT_BASE_OFFSET_1                         0x28b14
+#define R600_VGT_STRMOUT_BASE_OFFSET_2                         0x28b18
+#define R600_VGT_STRMOUT_BASE_OFFSET_3                         0x28b1c
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_0                      0x28b44
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_1                      0x28b48
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_2                      0x28b4c
+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_3                      0x28b50
+#define R600_VGT_STRMOUT_BUFFER_BASE_0                         0x28ad8
+#define R600_VGT_STRMOUT_BUFFER_BASE_1                         0x28ae8
+#define R600_VGT_STRMOUT_BUFFER_BASE_2                         0x28af8
+#define R600_VGT_STRMOUT_BUFFER_BASE_3                         0x28b08
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_0                       0x28adc
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_1                       0x28aec
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_2                       0x28afc
+#define R600_VGT_STRMOUT_BUFFER_OFFSET_3                       0x28b0c
+
+#define R600_VGT_PRIMITIVE_TYPE                                0x8958
+
+#define R600_PA_SC_SCREEN_SCISSOR_TL                           0x28030
+#define R600_PA_SC_GENERIC_SCISSOR_TL                          0x28240
+#define R600_PA_SC_WINDOW_SCISSOR_TL                           0x28204
+
 #define R600_TC_CNTL                                           0x9608
 #       define R600_TC_L2_SIZE(x)                              ((x) << 5)
 #       define R600_L2_DISABLE_LATE_HIT                        (1 << 9)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 0a92706..6216467 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -126,6 +126,23 @@ radeon_link_encoder_connector(struct drm_device *dev)
 	}
 }
 
+void radeon_encoder_set_active_device(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder == encoder) {
+			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+			radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
+			DRM_DEBUG("setting active device to %08x from %08x %08x for encoder %d\n",
+				  radeon_encoder->active_device, radeon_encoder->devices,
+				  radeon_connector->devices, encoder->encoder_type);
+		}
+	}
+}
+
 static struct drm_connector *
 radeon_get_connector_for_encoder(struct drm_encoder *encoder)
 {
@@ -224,9 +241,12 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	DAC_ENCODER_CONTROL_PS_ALLOCATION args;
 	int index = 0, num = 0;
-	/* fixme - fill in enc_priv for atom dac */
+	struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
 	enum radeon_tv_std tv_std = TV_STD_NTSC;
 
+	if (dac_info->tv_std)
+		tv_std = dac_info->tv_std;
+
 	memset(&args, 0, sizeof(args));
 
 	switch (radeon_encoder->encoder_id) {
@@ -244,9 +264,9 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
 
 	args.ucAction = action;
 
-	if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT))
+	if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT))
 		args.ucDacStandard = ATOM_DAC1_PS2;
-	else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+	else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 		args.ucDacStandard = ATOM_DAC1_CV;
 	else {
 		switch (tv_std) {
@@ -279,16 +299,19 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	TV_ENCODER_CONTROL_PS_ALLOCATION args;
 	int index = 0;
-	/* fixme - fill in enc_priv for atom dac */
+	struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
 	enum radeon_tv_std tv_std = TV_STD_NTSC;
 
+	if (dac_info->tv_std)
+		tv_std = dac_info->tv_std;
+
 	memset(&args, 0, sizeof(args));
 
 	index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
 
 	args.sTVEncoder.ucAction = action;
 
-	if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+	if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 		args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
 	else {
 		switch (tv_std) {
@@ -520,6 +543,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
 
 	switch (connector->connector_type) {
 	case DRM_MODE_CONNECTOR_DVII:
+	case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
 		if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
 			return ATOM_ENCODER_MODE_HDMI;
 		else if (radeon_connector->use_digital)
@@ -529,7 +553,6 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
 		break;
 	case DRM_MODE_CONNECTOR_DVID:
 	case DRM_MODE_CONNECTOR_HDMIA:
-	case DRM_MODE_CONNECTOR_HDMIB:
 	default:
 		if (drm_detect_hdmi_monitor((struct edid *)connector->edid_blob_ptr))
 			return ATOM_ENCODER_MODE_HDMI;
@@ -825,10 +848,10 @@ atombios_yuv_setup(struct drm_encoder *encoder, bool enable)
 
 	/* XXX: fix up scratch reg handling */
 	temp = RREG32(reg);
-	if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
+	if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 		WREG32(reg, (ATOM_S3_TV1_ACTIVE |
 			     (radeon_crtc->crtc_id << 18)));
-	else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+	else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 		WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24)));
 	else
 		WREG32(reg, 0);
@@ -851,9 +874,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
 	DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args;
 	int index = 0;
 	bool is_dig = false;
+	int devices;
 
 	memset(&args, 0, sizeof(args));
 
+	/* on DPMS off we have no idea if active device is meaningful */
+	if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device)
+		devices = radeon_encoder->devices;
+	else
+		devices = radeon_encoder->active_device;
+
+	DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n",
+		  radeon_encoder->encoder_id, mode, radeon_encoder->devices,
+		  radeon_encoder->active_device);
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -881,18 +914,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-		if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
+		if (devices & (ATOM_DEVICE_TV_SUPPORT))
 			index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-		else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+		else if (devices & (ATOM_DEVICE_CV_SUPPORT))
 			index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
 		else
 			index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-		if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
+		if (devices & (ATOM_DEVICE_TV_SUPPORT))
 			index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-		else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+		else if (devices & (ATOM_DEVICE_CV_SUPPORT))
 			index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
 		else
 			index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
@@ -979,18 +1012,18 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-				if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
+				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 					args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
-				else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+				else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 					args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
 				else
 					args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-				if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
+				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 					args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX;
-				else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+				else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 					args.v1.ucDevice = ATOM_DEVICE_CV_INDEX;
 				else
 					args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX;
@@ -1019,17 +1052,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
 				args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-				if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
+				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-				else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+				else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
 				else
 					args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
 				break;
 			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-				if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT))
+				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-				else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT))
+				else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
 					args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
 				else
 					args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
@@ -1097,7 +1130,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 	atombios_set_encoder_crtc_source(encoder);
 
 	if (ASIC_IS_AVIVO(rdev)) {
-		if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
+		if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
 			atombios_yuv_setup(encoder, true);
 		else
 			atombios_yuv_setup(encoder, false);
@@ -1135,7 +1168,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
 		atombios_dac_setup(encoder, ATOM_ENABLE);
-		if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+		if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
 			atombios_tv_setup(encoder, ATOM_ENABLE);
 		break;
 	}
@@ -1143,11 +1176,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 }
 
 static bool
-atombios_dac_load_detect(struct drm_encoder *encoder)
+atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 
 	if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT |
 				       ATOM_DEVICE_CV_SUPPORT |
@@ -1168,15 +1202,15 @@ atombios_dac_load_detect(struct drm_encoder *encoder)
 		else
 			args.sDacload.ucDacType = ATOM_DAC_B;
 
-		if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT)
+		if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT)
 			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
-		else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT)
+		else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT)
 			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
-		else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
+		else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
 			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
 			if (crev >= 3)
 				args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
-		} else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
+		} else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
 			args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
 			if (crev >= 3)
 				args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
@@ -1195,9 +1229,10 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	uint32_t bios_0_scratch;
 
-	if (!atombios_dac_load_detect(encoder)) {
+	if (!atombios_dac_load_detect(encoder, connector)) {
 		DRM_DEBUG("detect returned false \n");
 		return connector_status_unknown;
 	}
@@ -1207,17 +1242,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
 	else
 		bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH);
 
-	DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch);
-	if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) {
+	DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
+	if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
 		if (bios_0_scratch & ATOM_S0_CRT1_MASK)
 			return connector_status_connected;
-	} else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) {
+	}
+	if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
 		if (bios_0_scratch & ATOM_S0_CRT2_MASK)
 			return connector_status_connected;
-	} else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) {
+	}
+	if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
 		if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
 			return connector_status_connected;
-	} else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) {
+	}
+	if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
 		if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
 			return connector_status_connected; /* CTV */
 		else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
@@ -1230,6 +1268,8 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 {
 	radeon_atom_output_lock(encoder, true);
 	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
@@ -1238,12 +1278,20 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder)
 	radeon_atom_output_lock(encoder, false);
 }
 
+static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+	radeon_encoder->active_device = 0;
+}
+
 static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
 	.dpms = radeon_atom_encoder_dpms,
 	.mode_fixup = radeon_atom_mode_fixup,
 	.prepare = radeon_atom_encoder_prepare,
 	.mode_set = radeon_atom_encoder_mode_set,
 	.commit = radeon_atom_encoder_commit,
+	.disable = radeon_atom_encoder_disable,
 	/* no detect for TMDS/LVDS yet */
 };
 
@@ -1268,6 +1316,18 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
 	.destroy = radeon_enc_destroy,
 };
 
+struct radeon_encoder_atom_dac *
+radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
+{
+	struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
+
+	if (!dac)
+		return NULL;
+
+	dac->tv_std = TV_STD_NTSC;
+	return dac;
+}
+
 struct radeon_encoder_atom_dig *
 radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
 {
@@ -1336,6 +1396,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
 		drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC);
+		radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
 		drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
@@ -1345,8 +1406,14 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-		drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
-		radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
+		if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+			radeon_encoder->rmx_type = RMX_FULL;
+			drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
+			radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder);
+		} else {
+			drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
+			radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
+		}
 		drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
 		break;
 	}
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index ec383ed..944e4fa 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -28,15 +28,7 @@
      */
 
 #include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/fb.h>
-#include <linux/init.h>
 
 #include "drmP.h"
 #include "drm.h"
@@ -45,375 +37,24 @@
 #include "radeon_drm.h"
 #include "radeon.h"
 
+#include "drm_fb_helper.h"
+
 struct radeon_fb_device {
-	struct radeon_device		*rdev;
-	struct drm_display_mode		*mode;
+	struct drm_fb_helper helper;
 	struct radeon_framebuffer	*rfb;
-	int				crtc_count;
-	/* crtc currently bound to this */
-	uint32_t			crtc_ids[2];
+	struct radeon_device		*rdev;
 };
 
-static int radeonfb_setcolreg(unsigned regno,
-			      unsigned red,
-			      unsigned green,
-			      unsigned blue,
-			      unsigned transp,
-			      struct fb_info *info)
-{
-	struct radeon_fb_device *rfbdev = info->par;
-	struct drm_device *dev = rfbdev->rdev->ddev;
-	struct drm_crtc *crtc;
-	int i;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-		struct drm_mode_set *modeset = &radeon_crtc->mode_set;
-		struct drm_framebuffer *fb = modeset->fb;
-
-		for (i = 0; i < rfbdev->crtc_count; i++) {
-			if (crtc->base.id == rfbdev->crtc_ids[i]) {
-				break;
-			}
-		}
-		if (i == rfbdev->crtc_count) {
-			continue;
-		}
-		if (regno > 255) {
-			return 1;
-		}
-		if (fb->depth == 8) {
-			radeon_crtc_fb_gamma_set(crtc, red, green, blue, regno);
-			return 0;
-		}
-
-		if (regno < 16) {
-			switch (fb->depth) {
-			case 15:
-				fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
-					((green & 0xf800) >>  6) |
-					((blue & 0xf800) >> 11);
-				break;
-			case 16:
-				fb->pseudo_palette[regno] = (red & 0xf800) |
-					((green & 0xfc00) >>  5) |
-					((blue  & 0xf800) >> 11);
-				break;
-			case 24:
-			case 32:
-				fb->pseudo_palette[regno] =
-					(((red >> 8) & 0xff) << info->var.red.offset) |
-					(((green >> 8) & 0xff) << info->var.green.offset) |
-					(((blue >> 8) & 0xff) << info->var.blue.offset);
-				break;
-			}
-		}
-	}
-	return 0;
-}
-
-static int radeonfb_check_var(struct fb_var_screeninfo *var,
-			      struct fb_info *info)
-{
-	struct radeon_fb_device *rfbdev = info->par;
-	struct radeon_framebuffer *rfb = rfbdev->rfb;
-	struct drm_framebuffer *fb = &rfb->base;
-	int depth;
-
-	if (var->pixclock == -1 || !var->pixclock) {
-		return -EINVAL;
-	}
-	/* Need to resize the fb object !!! */
-	if (var->xres > fb->width || var->yres > fb->height) {
-		DRM_ERROR("Requested width/height is greater than current fb "
-			   "object %dx%d > %dx%d\n", var->xres, var->yres,
-			   fb->width, fb->height);
-		DRM_ERROR("Need resizing code.\n");
-		return -EINVAL;
-	}
-
-	switch (var->bits_per_pixel) {
-	case 16:
-		depth = (var->green.length == 6) ? 16 : 15;
-		break;
-	case 32:
-		depth = (var->transp.length > 0) ? 32 : 24;
-		break;
-	default:
-		depth = var->bits_per_pixel;
-		break;
-	}
-
-	switch (depth) {
-	case 8:
-		var->red.offset = 0;
-		var->green.offset = 0;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 0;
-		var->transp.offset = 0;
-		break;
-#ifdef __LITTLE_ENDIAN
-	case 15:
-		var->red.offset = 10;
-		var->green.offset = 5;
-		var->blue.offset = 0;
-		var->red.length = 5;
-		var->green.length = 5;
-		var->blue.length = 5;
-		var->transp.length = 1;
-		var->transp.offset = 15;
-		break;
-	case 16:
-		var->red.offset = 11;
-		var->green.offset = 5;
-		var->blue.offset = 0;
-		var->red.length = 5;
-		var->green.length = 6;
-		var->blue.length = 5;
-		var->transp.length = 0;
-		var->transp.offset = 0;
-		break;
-	case 24:
-		var->red.offset = 16;
-		var->green.offset = 8;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 0;
-		var->transp.offset = 0;
-		break;
-	case 32:
-		var->red.offset = 16;
-		var->green.offset = 8;
-		var->blue.offset = 0;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 8;
-		var->transp.offset = 24;
-		break;
-#else
-	case 24:
-		var->red.offset = 8;
-		var->green.offset = 16;
-		var->blue.offset = 24;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 0;
-		var->transp.offset = 0;
-		break;
-	case 32:
-		var->red.offset = 8;
-		var->green.offset = 16;
-		var->blue.offset = 24;
-		var->red.length = 8;
-		var->green.length = 8;
-		var->blue.length = 8;
-		var->transp.length = 8;
-		var->transp.offset = 0;
-		break;
-#endif
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/* this will let fbcon do the mode init */
-static int radeonfb_set_par(struct fb_info *info)
-{
-	struct radeon_fb_device *rfbdev = info->par;
-	struct drm_device *dev = rfbdev->rdev->ddev;
-	struct fb_var_screeninfo *var = &info->var;
-	struct drm_crtc *crtc;
-	int ret;
-	int i;
-
-	if (var->pixclock != -1) {
-		DRM_ERROR("PIXEL CLCOK SET\n");
-		return -EINVAL;
-	}
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
-		for (i = 0; i < rfbdev->crtc_count; i++) {
-			if (crtc->base.id == rfbdev->crtc_ids[i]) {
-				break;
-			}
-		}
-		if (i == rfbdev->crtc_count) {
-			continue;
-		}
-		if (crtc->fb == radeon_crtc->mode_set.fb) {
-			mutex_lock(&dev->mode_config.mutex);
-			ret = crtc->funcs->set_config(&radeon_crtc->mode_set);
-			mutex_unlock(&dev->mode_config.mutex);
-			if (ret) {
-				return ret;
-			}
-		}
-	}
-	return 0;
-}
-
-static int radeonfb_pan_display(struct fb_var_screeninfo *var,
-				struct fb_info *info)
-{
-	struct radeon_fb_device *rfbdev = info->par;
-	struct drm_device *dev = rfbdev->rdev->ddev;
-	struct drm_mode_set *modeset;
-	struct drm_crtc *crtc;
-	struct radeon_crtc *radeon_crtc;
-	int ret = 0;
-	int i;
-
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		for (i = 0; i < rfbdev->crtc_count; i++) {
-			if (crtc->base.id == rfbdev->crtc_ids[i]) {
-				break;
-			}
-		}
-
-		if (i == rfbdev->crtc_count) {
-			continue;
-		}
-
-		radeon_crtc = to_radeon_crtc(crtc);
-		modeset = &radeon_crtc->mode_set;
-
-		modeset->x = var->xoffset;
-		modeset->y = var->yoffset;
-
-		if (modeset->num_connectors) {
-			mutex_lock(&dev->mode_config.mutex);
-			ret = crtc->funcs->set_config(modeset);
-			mutex_unlock(&dev->mode_config.mutex);
-			if (!ret) {
-				info->var.xoffset = var->xoffset;
-				info->var.yoffset = var->yoffset;
-			}
-		}
-	}
-	return ret;
-}
-
-static void radeonfb_on(struct fb_info *info)
-{
-	struct radeon_fb_device *rfbdev = info->par;
-	struct drm_device *dev = rfbdev->rdev->ddev;
-	struct drm_crtc *crtc;
-	struct drm_encoder *encoder;
-	int i;
-
-	/*
-	 * For each CRTC in this fb, find all associated encoders
-	 * and turn them off, then turn off the CRTC.
-	 */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-
-		for (i = 0; i < rfbdev->crtc_count; i++) {
-			if (crtc->base.id == rfbdev->crtc_ids[i]) {
-				break;
-			}
-		}
-
-		mutex_lock(&dev->mode_config.mutex);
-		crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-		mutex_unlock(&dev->mode_config.mutex);
-
-		/* Found a CRTC on this fb, now find encoders */
-		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-			if (encoder->crtc == crtc) {
-				struct drm_encoder_helper_funcs *encoder_funcs;
-
-				encoder_funcs = encoder->helper_private;
-				mutex_lock(&dev->mode_config.mutex);
-				encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-				mutex_unlock(&dev->mode_config.mutex);
-			}
-		}
-	}
-}
-
-static void radeonfb_off(struct fb_info *info, int dpms_mode)
-{
-	struct radeon_fb_device *rfbdev = info->par;
-	struct drm_device *dev = rfbdev->rdev->ddev;
-	struct drm_crtc *crtc;
-	struct drm_encoder *encoder;
-	int i;
-
-	/*
-	 * For each CRTC in this fb, find all associated encoders
-	 * and turn them off, then turn off the CRTC.
-	 */
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
-
-		for (i = 0; i < rfbdev->crtc_count; i++) {
-			if (crtc->base.id == rfbdev->crtc_ids[i]) {
-				break;
-			}
-		}
-
-		/* Found a CRTC on this fb, now find encoders */
-		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-			if (encoder->crtc == crtc) {
-				struct drm_encoder_helper_funcs *encoder_funcs;
-
-				encoder_funcs = encoder->helper_private;
-				mutex_lock(&dev->mode_config.mutex);
-				encoder_funcs->dpms(encoder, dpms_mode);
-				mutex_unlock(&dev->mode_config.mutex);
-			}
-		}
-		if (dpms_mode == DRM_MODE_DPMS_OFF) {
-			mutex_lock(&dev->mode_config.mutex);
-			crtc_funcs->dpms(crtc, dpms_mode);
-			mutex_unlock(&dev->mode_config.mutex);
-		}
-	}
-}
-
-int radeonfb_blank(int blank, struct fb_info *info)
-{
-	switch (blank) {
-	case FB_BLANK_UNBLANK:
-		radeonfb_on(info);
-		break;
-	case FB_BLANK_NORMAL:
-		radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
-		break;
-	case FB_BLANK_HSYNC_SUSPEND:
-		radeonfb_off(info, DRM_MODE_DPMS_STANDBY);
-		break;
-	case FB_BLANK_VSYNC_SUSPEND:
-		radeonfb_off(info, DRM_MODE_DPMS_SUSPEND);
-		break;
-	case FB_BLANK_POWERDOWN:
-		radeonfb_off(info, DRM_MODE_DPMS_OFF);
-		break;
-	}
-	return 0;
-}
-
 static struct fb_ops radeonfb_ops = {
 	.owner = THIS_MODULE,
-	.fb_check_var = radeonfb_check_var,
-	.fb_set_par = radeonfb_set_par,
-	.fb_setcolreg = radeonfb_setcolreg,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_setcolreg = drm_fb_helper_setcolreg,
 	.fb_fillrect = cfb_fillrect,
 	.fb_copyarea = cfb_copyarea,
 	.fb_imageblit = cfb_imageblit,
-	.fb_pan_display = radeonfb_pan_display,
-	.fb_blank = radeonfb_blank,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
 };
 
 /**
@@ -456,21 +97,6 @@ int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(radeonfb_resize);
 
-static struct drm_mode_set panic_mode;
-
-int radeonfb_panic(struct notifier_block *n, unsigned long ununsed,
-		  void *panic_str)
-{
-	DRM_ERROR("panic occurred, switching back to text console\n");
-	drm_crtc_helper_set_config(&panic_mode);
-	return 0;
-}
-EXPORT_SYMBOL(radeonfb_panic);
-
-static struct notifier_block paniced = {
-	.notifier_call = radeonfb_panic,
-};
-
 static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
 {
 	int aligned = width;
@@ -495,11 +121,16 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo
 	return aligned;
 }
 
-int radeonfb_create(struct radeon_device *rdev,
+static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
+	.gamma_set = radeon_crtc_fb_gamma_set,
+};
+
+int radeonfb_create(struct drm_device *dev,
 		    uint32_t fb_width, uint32_t fb_height,
 		    uint32_t surface_width, uint32_t surface_height,
-		    struct radeon_framebuffer **rfb_p)
+		    struct drm_framebuffer **fb_p)
 {
+	struct radeon_device *rdev = dev->dev_private;
 	struct fb_info *info;
 	struct radeon_fb_device *rfbdev;
 	struct drm_framebuffer *fb = NULL;
@@ -513,6 +144,7 @@ int radeonfb_create(struct radeon_device *rdev,
 	void *fbptr = NULL;
 	unsigned long tmp;
 	bool fb_tiled = false; /* useful for testing */
+	u32 tiling_flags = 0;
 
 	mode_cmd.width = surface_width;
 	mode_cmd.height = surface_height;
@@ -537,7 +169,22 @@ int radeonfb_create(struct radeon_device *rdev,
 	robj = gobj->driver_private;
 
 	if (fb_tiled)
-		radeon_object_set_tiling_flags(robj, RADEON_TILING_MACRO|RADEON_TILING_SURFACE, mode_cmd.pitch);
+		tiling_flags = RADEON_TILING_MACRO;
+
+#ifdef __BIG_ENDIAN
+	switch (mode_cmd.bpp) {
+	case 32:
+		tiling_flags |= RADEON_TILING_SWAP_32BIT;
+		break;
+	case 16:
+		tiling_flags |= RADEON_TILING_SWAP_16BIT;
+	default:
+		break;
+	}
+#endif
+
+	if (tiling_flags)
+		radeon_object_set_tiling_flags(robj, tiling_flags | RADEON_TILING_SURFACE, mode_cmd.pitch);
 	mutex_lock(&rdev->ddev->struct_mutex);
 	fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
 	if (fb == NULL) {
@@ -554,8 +201,8 @@ int radeonfb_create(struct radeon_device *rdev,
 
 	list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list);
 
+	*fb_p = fb;
 	rfb = to_radeon_framebuffer(fb);
-	*rfb_p = rfb;
 	rdev->fbdev_rfb = rfb;
 	rdev->fbdev_robj = robj;
 
@@ -564,7 +211,15 @@ int radeonfb_create(struct radeon_device *rdev,
 		ret = -ENOMEM;
 		goto out_unref;
 	}
+
+	rdev->fbdev_info = info;
 	rfbdev = info->par;
+	rfbdev->helper.funcs = &radeon_fb_helper_funcs;
+	rfbdev->helper.dev = dev;
+	ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, 2,
+					    RADEONFB_CONN_LIMIT);
+	if (ret)
+		goto out_unref;
 
 	if (fb_tiled)
 		radeon_object_check_tiling(robj, 0, 0);
@@ -577,33 +232,19 @@ int radeonfb_create(struct radeon_device *rdev,
 	memset_io(fbptr, 0, aligned_size);
 
 	strcpy(info->fix.id, "radeondrmfb");
-	info->fix.type = FB_TYPE_PACKED_PIXELS;
-	info->fix.visual = FB_VISUAL_TRUECOLOR;
-	info->fix.type_aux = 0;
-	info->fix.xpanstep = 1; /* doing it in hw */
-	info->fix.ypanstep = 1; /* doing it in hw */
-	info->fix.ywrapstep = 0;
-	info->fix.accel = FB_ACCEL_NONE;
-	info->fix.type_aux = 0;
+
+	drm_fb_helper_fill_fix(info, fb->pitch);
+
 	info->flags = FBINFO_DEFAULT;
 	info->fbops = &radeonfb_ops;
-	info->fix.line_length = fb->pitch;
+
 	tmp = fb_gpuaddr - rdev->mc.vram_location;
 	info->fix.smem_start = rdev->mc.aper_base + tmp;
 	info->fix.smem_len = size;
 	info->screen_base = fbptr;
 	info->screen_size = size;
-	info->pseudo_palette = fb->pseudo_palette;
-	info->var.xres_virtual = fb->width;
-	info->var.yres_virtual = fb->height;
-	info->var.bits_per_pixel = fb->bits_per_pixel;
-	info->var.xoffset = 0;
-	info->var.yoffset = 0;
-	info->var.activate = FB_ACTIVATE_NOW;
-	info->var.height = -1;
-	info->var.width = -1;
-	info->var.xres = fb_width;
-	info->var.yres = fb_height;
+
+	drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
 
 	/* setup aperture base/size for vesafb takeover */
 	info->aperture_base = rdev->ddev->mode_config.fb_base;
@@ -626,83 +267,6 @@ int radeonfb_create(struct radeon_device *rdev,
 	DRM_INFO("fb depth is %d\n", fb->depth);
 	DRM_INFO("   pitch is %d\n", fb->pitch);
 
-	switch (fb->depth) {
-	case 8:
-		info->var.red.offset = 0;
-		info->var.green.offset = 0;
-		info->var.blue.offset = 0;
-		info->var.red.length = 8; /* 8bit DAC */
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 0;
-		info->var.transp.length = 0;
-		break;
-#ifdef __LITTLE_ENDIAN
-	case 15:
-		info->var.red.offset = 10;
-		info->var.green.offset = 5;
-		info->var.blue.offset = 0;
-		info->var.red.length = 5;
-		info->var.green.length = 5;
-		info->var.blue.length = 5;
-		info->var.transp.offset = 15;
-		info->var.transp.length = 1;
-		break;
-	case 16:
-		info->var.red.offset = 11;
-		info->var.green.offset = 5;
-		info->var.blue.offset = 0;
-		info->var.red.length = 5;
-		info->var.green.length = 6;
-		info->var.blue.length = 5;
-		info->var.transp.offset = 0;
-		break;
-	case 24:
-		info->var.red.offset = 16;
-		info->var.green.offset = 8;
-		info->var.blue.offset = 0;
-		info->var.red.length = 8;
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 0;
-		info->var.transp.length = 0;
-		break;
-	case 32:
-		info->var.red.offset = 16;
-		info->var.green.offset = 8;
-		info->var.blue.offset = 0;
-		info->var.red.length = 8;
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 24;
-		info->var.transp.length = 8;
-		break;
-#else
-	case 24:
-		info->var.red.offset = 8;
-		info->var.green.offset = 16;
-		info->var.blue.offset = 24;
-		info->var.red.length = 8;
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 0;
-		info->var.transp.length = 0;
-		break;
-	case 32:
-		info->var.red.offset = 8;
-		info->var.green.offset = 16;
-		info->var.blue.offset = 24;
-		info->var.red.length = 8;
-		info->var.green.length = 8;
-		info->var.blue.length = 8;
-		info->var.transp.offset = 0;
-		info->var.transp.length = 8;
-		break;
-	default:
-#endif
-		break;
-	}
-
 	fb->fbdev = info;
 	rfbdev->rfb = rfb;
 	rfbdev->rdev = rdev;
@@ -726,145 +290,10 @@ out:
 	return ret;
 }
 
-static int radeonfb_single_fb_probe(struct radeon_device *rdev)
-{
-	struct drm_crtc *crtc;
-	struct drm_connector *connector;
-	unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
-	unsigned int surface_width = 0, surface_height = 0;
-	int new_fb = 0;
-	int crtc_count = 0;
-	int ret, i, conn_count = 0;
-	struct radeon_framebuffer *rfb;
-	struct fb_info *info;
-	struct radeon_fb_device *rfbdev;
-	struct drm_mode_set *modeset = NULL;
-
-	/* first up get a count of crtcs now in use and new min/maxes width/heights */
-	list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
-		if (drm_helper_crtc_in_use(crtc)) {
-			if (crtc->desired_mode) {
-				if (crtc->desired_mode->hdisplay < fb_width)
-					fb_width = crtc->desired_mode->hdisplay;
-
-				if (crtc->desired_mode->vdisplay < fb_height)
-					fb_height = crtc->desired_mode->vdisplay;
-
-				if (crtc->desired_mode->hdisplay > surface_width)
-					surface_width = crtc->desired_mode->hdisplay;
-
-				if (crtc->desired_mode->vdisplay > surface_height)
-					surface_height = crtc->desired_mode->vdisplay;
-			}
-			crtc_count++;
-		}
-	}
-
-	if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
-		/* hmm everyone went away - assume VGA cable just fell out
-		   and will come back later. */
-		return 0;
-	}
-
-	/* do we have an fb already? */
-	if (list_empty(&rdev->ddev->mode_config.fb_kernel_list)) {
-		/* create an fb if we don't have one */
-		ret = radeonfb_create(rdev, fb_width, fb_height, surface_width, surface_height, &rfb);
-		if (ret) {
-			return -EINVAL;
-		}
-		new_fb = 1;
-	} else {
-		struct drm_framebuffer *fb;
-		fb = list_first_entry(&rdev->ddev->mode_config.fb_kernel_list, struct drm_framebuffer, filp_head);
-		rfb = to_radeon_framebuffer(fb);
-
-		/* if someone hotplugs something bigger than we have already allocated, we are pwned.
-		   As really we can't resize an fbdev that is in the wild currently due to fbdev
-		   not really being designed for the lower layers moving stuff around under it.
-		   - so in the grand style of things - punt. */
-		if ((fb->width < surface_width) || (fb->height < surface_height)) {
-			DRM_ERROR("Framebuffer not large enough to scale console onto.\n");
-			return -EINVAL;
-		}
-	}
-
-	info = rfb->base.fbdev;
-	rdev->fbdev_info = info;
-	rfbdev = info->par;
-
-	crtc_count = 0;
-	/* okay we need to setup new connector sets in the crtcs */
-	list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) {
-		struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-		modeset = &radeon_crtc->mode_set;
-		modeset->fb = &rfb->base;
-		conn_count = 0;
-		list_for_each_entry(connector, &rdev->ddev->mode_config.connector_list, head) {
-			if (connector->encoder)
-				if (connector->encoder->crtc == modeset->crtc) {
-					modeset->connectors[conn_count] = connector;
-					conn_count++;
-					if (conn_count > RADEONFB_CONN_LIMIT)
-						BUG();
-				}
-		}
-
-		for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++)
-			modeset->connectors[i] = NULL;
-
-
-		rfbdev->crtc_ids[crtc_count++] = crtc->base.id;
-
-		modeset->num_connectors = conn_count;
-		if (modeset->crtc->desired_mode) {
-			if (modeset->mode) {
-				drm_mode_destroy(rdev->ddev, modeset->mode);
-			}
-			modeset->mode = drm_mode_duplicate(rdev->ddev,
-							   modeset->crtc->desired_mode);
-		}
-	}
-	rfbdev->crtc_count = crtc_count;
-
-	if (new_fb) {
-		info->var.pixclock = -1;
-		if (register_framebuffer(info) < 0)
-			return -EINVAL;
-	} else {
-		radeonfb_set_par(info);
-	}
-	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
-	       info->fix.id);
-
-	/* Switch back to kernel console on panic */
-	panic_mode = *modeset;
-	atomic_notifier_chain_register(&panic_notifier_list, &paniced);
-	printk(KERN_INFO "registered panic notifier\n");
-
-	return 0;
-}
-
 int radeonfb_probe(struct drm_device *dev)
 {
 	int ret;
-
-	/* something has changed in the lower levels of hell - deal with it
-	   here */
-
-	/* two modes : a) 1 fb to rule all crtcs.
-	               b) one fb per crtc.
-	   two actions 1) new connected device
-	               2) device removed.
-	   case a/1 : if the fb surface isn't big enough - resize the surface fb.
-	              if the fb size isn't big enough - resize fb into surface.
-		      if everything big enough configure the new crtc/etc.
-	   case a/2 : undo the configuration
-	              possibly resize down the fb to fit the new configuration.
-           case b/1 : see if it is on a new crtc - setup a new fb and add it.
-	   case b/2 : teardown the new fb.
-	*/
-	ret = radeonfb_single_fb_probe(dev->dev_private);
+	ret = drm_fb_helper_single_fb_probe(dev, &radeonfb_create);
 	return ret;
 }
 EXPORT_SYMBOL(radeonfb_probe);
@@ -880,16 +309,17 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
 	}
 	info = fb->fbdev;
 	if (info) {
+		struct radeon_fb_device *rfbdev = info->par;
 		robj = rfb->obj->driver_private;
 		unregister_framebuffer(info);
 		radeon_object_kunmap(robj);
 		radeon_object_unpin(robj);
+		drm_fb_helper_free(&rfbdev->helper);
 		framebuffer_release(info);
 	}
 
 	printk(KERN_INFO "unregistered panic notifier\n");
-	atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
-	memset(&panic_mode, 0, sizeof(struct drm_mode_set));
+
 	return 0;
 }
 EXPORT_SYMBOL(radeonfb_remove);
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c
index b4e48dd..3beb26d 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -53,9 +53,9 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
 		 * away
 		 */
 		WREG32(rdev->fence_drv.scratch_reg, fence->seq);
-	} else {
+	} else
 		radeon_fence_ring_emit(rdev, fence);
-	}
+
 	fence->emited = true;
 	fence->timeout = jiffies + ((2000 * HZ) / 1000);
 	list_del(&fence->list);
@@ -168,7 +168,38 @@ bool radeon_fence_signaled(struct radeon_fence *fence)
 	return signaled;
 }
 
-int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
+int r600_fence_wait(struct radeon_fence *fence,  bool intr, bool lazy)
+{
+	struct radeon_device *rdev;
+	int ret = 0;
+
+	rdev = fence->rdev;
+
+	__set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
+
+	while (1) {
+		if (radeon_fence_signaled(fence))
+			break;
+
+		if (time_after_eq(jiffies, fence->timeout)) {
+			ret = -EBUSY;
+			break;
+		}
+
+		if (lazy)
+			schedule_timeout(1);
+
+		if (intr && signal_pending(current)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+	}
+	__set_current_state(TASK_RUNNING);
+	return ret;
+}
+
+
+int radeon_fence_wait(struct radeon_fence *fence, bool intr)
 {
 	struct radeon_device *rdev;
 	unsigned long cur_jiffies;
@@ -176,7 +207,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
 	bool expired = false;
 	int r;
 
-
 	if (fence == NULL) {
 		WARN(1, "Querying an invalid fence : %p !\n", fence);
 		return 0;
@@ -185,13 +215,22 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible)
 	if (radeon_fence_signaled(fence)) {
 		return 0;
 	}
+
+	if (rdev->family >= CHIP_R600) {
+		r = r600_fence_wait(fence, intr, 0);
+		if (r == -ERESTARTSYS)
+			return -EBUSY;
+		return r;
+	}
+
 retry:
 	cur_jiffies = jiffies;
 	timeout = HZ / 100;
 	if (time_after(fence->timeout, cur_jiffies)) {
 		timeout = fence->timeout - cur_jiffies;
 	}
-	if (interruptible) {
+
+	if (intr) {
 		r = wait_event_interruptible_timeout(rdev->fence_drv.queue,
 				radeon_fence_signaled(fence), timeout);
 		if (unlikely(r == -ERESTARTSYS)) {
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 2977539..a931af0 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -75,7 +75,6 @@ void radeon_gart_table_ram_free(struct radeon_device *rdev)
 
 int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
 {
-	uint64_t gpu_addr;
 	int r;
 
 	if (rdev->gart.table.vram.robj == NULL) {
@@ -88,6 +87,14 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev)
 			return r;
 		}
 	}
+	return 0;
+}
+
+int radeon_gart_table_vram_pin(struct radeon_device *rdev)
+{
+	uint64_t gpu_addr;
+	int r;
+
 	r = radeon_object_pin(rdev->gart.table.vram.robj,
 			      RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
 	if (r) {
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c
index 56decda..a1bf11d 100644
--- a/drivers/gpu/drm/radeon/radeon_ioc32.c
+++ b/drivers/gpu/drm/radeon/radeon_ioc32.c
@@ -422,3 +422,18 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
 	return ret;
 }
+
+long radeon_kms_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	unsigned int nr = DRM_IOCTL_NR(cmd);
+	int ret;
+
+	if (nr < DRM_COMMAND_BASE)
+		return drm_compat_ioctl(filp, cmd, arg);
+
+	lock_kernel();		/* XXX for now */
+	ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
+	unlock_kernel();
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index 9836c70..b79ecc4 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -188,6 +188,9 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
 	u32 stat;
 	u32 r500_disp_int;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return IRQ_NONE;
+
 	/* Only consider the bits we're interested in - others could be used
 	 * outside the DRM
 	 */
@@ -286,6 +289,9 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr
 	drm_radeon_irq_emit_t *emit = data;
 	int result;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return -EINVAL;
+
 	LOCK_TEST_WITH_RETURN(dev, file_priv);
 
 	if (!dev_priv) {
@@ -315,6 +321,9 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
 		return -EINVAL;
 	}
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return -EINVAL;
+
 	return radeon_wait_irq(dev, irqwait->irq_seq);
 }
 
@@ -326,6 +335,9 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
 	    (drm_radeon_private_t *) dev->dev_private;
 	u32 dummy;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return;
+
 	/* Disable *all* interrupts */
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
@@ -345,6 +357,9 @@ int radeon_driver_irq_postinstall(struct drm_device *dev)
 
 	dev->max_vblank_count = 0x001fffff;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return 0;
+
 	radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
 
 	return 0;
@@ -357,6 +372,9 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
 	if (!dev_priv)
 		return;
 
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		return;
+
 	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
 		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
 	/* Disable *all* interrupts */
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 9805e4b..1841145 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -28,7 +28,6 @@
 #include "drmP.h"
 #include "radeon_drm.h"
 #include "radeon_reg.h"
-#include "radeon_microcode.h"
 #include "radeon.h"
 #include "atom.h"
 
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index dce09ad..709bd89 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -54,12 +54,23 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 		flags |= RADEON_IS_PCI;
 	}
 
+	/* radeon_device_init should report only fatal error
+	 * like memory allocation failure or iomapping failure,
+	 * or memory manager initialization failure, it must
+	 * properly initialize the GPU MC controller and permit
+	 * VRAM allocation
+	 */
 	r = radeon_device_init(rdev, dev, dev->pdev, flags);
 	if (r) {
-		DRM_ERROR("Failed to initialize radeon, disabling IOCTL\n");
-		radeon_device_fini(rdev);
-		kfree(rdev);
-		dev->dev_private = NULL;
+		DRM_ERROR("Fatal error while trying to initialize radeon.\n");
+		return r;
+	}
+	/* Again modeset_init should fail only on fatal error
+	 * otherwise it should provide enough functionalities
+	 * for shadowfb to run
+	 */
+	r = radeon_modeset_init(rdev);
+	if (r) {
 		return r;
 	}
 	return 0;
@@ -69,6 +80,9 @@ int radeon_driver_unload_kms(struct drm_device *dev)
 {
 	struct radeon_device *rdev = dev->dev_private;
 
+	if (rdev == NULL)
+		return 0;
+	radeon_modeset_fini(rdev);
 	radeon_device_fini(rdev);
 	kfree(rdev);
 	dev->dev_private = NULL;
@@ -98,6 +112,9 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 	case RADEON_INFO_NUM_Z_PIPES:
 		value = rdev->num_z_pipes;
 		break;
+	case RADEON_INFO_ACCEL_WORKING:
+		value = rdev->accel_working;
+		break;
 	default:
 		DRM_DEBUG("Invalid request %d\n", info->request);
 		return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 0da72f1..2b997a1 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -28,6 +28,7 @@
 #include <drm/radeon_drm.h>
 #include "radeon_fixed.h"
 #include "radeon.h"
+#include "atom.h"
 
 static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc,
 				       struct drm_display_mode *mode,
@@ -340,6 +341,9 @@ void radeon_legacy_atom_set_surface(struct drm_crtc *crtc)
 	uint32_t crtc_pitch;
 
 	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		format = 2;
+		break;
 	case 15:      /*  555 */
 		format = 3;
 		break;
@@ -400,11 +404,33 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 	uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
 	uint32_t crtc_pitch, pitch_pixels;
 	uint32_t tiling_flags;
+	int format;
+	uint32_t gen_cntl_reg, gen_cntl_val;
 
 	DRM_DEBUG("\n");
 
 	radeon_fb = to_radeon_framebuffer(crtc->fb);
 
+	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		format = 2;
+		break;
+	case 15:      /*  555 */
+		format = 3;
+		break;
+	case 16:      /*  565 */
+		format = 4;
+		break;
+	case 24:      /*  RGB */
+		format = 5;
+		break;
+	case 32:      /* xRGB */
+		format = 6;
+		break;
+	default:
+		return false;
+	}
+
 	obj = radeon_fb->obj;
 	if (radeon_gem_object_pin(obj, RADEON_GEM_DOMAIN_VRAM, &base)) {
 		return -EINVAL;
@@ -457,6 +483,9 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 	} else {
 		int offset = y * pitch_pixels + x;
 		switch (crtc->fb->bits_per_pixel) {
+		case 8:
+			offset *= 1;
+			break;
 		case 15:
 		case 16:
 			offset *= 2;
@@ -475,6 +504,16 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
 
 	base &= ~7;
 
+	if (radeon_crtc->crtc_id == 1)
+		gen_cntl_reg = RADEON_CRTC2_GEN_CNTL;
+	else
+		gen_cntl_reg = RADEON_CRTC_GEN_CNTL;
+
+	gen_cntl_val = RREG32(gen_cntl_reg);
+	gen_cntl_val &= ~(0xf << 8);
+	gen_cntl_val |= (format << 8);
+	WREG32(gen_cntl_reg, gen_cntl_val);
+
 	crtc_offset = (u32)base;
 
 	WREG32(RADEON_DISPLAY_BASE_ADDR + radeon_crtc->crtc_offset, radeon_crtc->legacy_display_base_addr);
@@ -501,6 +540,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct drm_encoder *encoder;
 	int format;
 	int hsync_start;
 	int hsync_wid;
@@ -509,10 +549,24 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
 	uint32_t crtc_h_sync_strt_wid;
 	uint32_t crtc_v_total_disp;
 	uint32_t crtc_v_sync_strt_wid;
+	bool is_tv = false;
 
 	DRM_DEBUG("\n");
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		if (encoder->crtc == crtc) {
+			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+			if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
+				is_tv = true;
+				DRM_INFO("crtc %d is connected to a TV\n", radeon_crtc->crtc_id);
+				break;
+			}
+		}
+	}
 
 	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		format = 2;
+		break;
 	case 15:      /*  555 */
 		format = 3;
 		break;
@@ -642,6 +696,11 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod
 		WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
 	}
 
+	if (is_tv)
+		radeon_legacy_tv_adjust_crtc_reg(encoder, &crtc_h_total_disp,
+						 &crtc_h_sync_strt_wid, &crtc_v_total_disp,
+						 &crtc_v_sync_strt_wid);
+
 	WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp);
 	WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid);
 	WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp);
@@ -668,7 +727,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 	uint32_t pll_ref_div = 0;
 	uint32_t pll_fb_post_div = 0;
 	uint32_t htotal_cntl = 0;
-
+	bool is_tv = false;
 	struct radeon_pll *pll;
 
 	struct {
@@ -703,6 +762,13 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
+			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+
+			if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) {
+				is_tv = true;
+				break;
+			}
+
 			if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
 				pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
 			if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
@@ -766,6 +832,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 					  ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
 					 RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
 
+		if (is_tv) {
+			radeon_legacy_tv_adjust_pll2(encoder, &htotal_cntl,
+						     &pll_ref_div, &pll_fb_post_div,
+						     &pixclks_cntl);
+		}
+
 		WREG32_PLL_P(RADEON_PIXCLKS_CNTL,
 			     RADEON_PIX2CLK_SRC_SEL_CPUCLK,
 			     ~(RADEON_PIX2CLK_SRC_SEL_MASK));
@@ -820,6 +892,15 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 
 		WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
 	} else {
+		uint32_t pixclks_cntl;
+
+
+		if (is_tv) {
+			pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
+			radeon_legacy_tv_adjust_pll1(encoder, &htotal_cntl, &pll_ref_div,
+						     &pll_fb_post_div, &pixclks_cntl);
+		}
+
 		if (rdev->flags & RADEON_IS_MOBILITY) {
 			/* A temporal workaround for the occational blanking on certain laptop panels.
 			   This appears to related to the PLL divider registers (fail to lock?).
@@ -914,6 +995,8 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
 			     RADEON_VCLK_SRC_SEL_PPLLCLK,
 			     ~(RADEON_VCLK_SRC_SEL_MASK));
 
+		if (is_tv)
+			WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
 	}
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 9322675..b1547f7 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -29,6 +29,15 @@
 #include "radeon.h"
 #include "atom.h"
 
+static void radeon_legacy_encoder_disable(struct drm_encoder *encoder)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_encoder_helper_funcs *encoder_funcs;
+
+	encoder_funcs = encoder->helper_private;
+	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
+	radeon_encoder->active_device = 0;
+}
 
 static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
 {
@@ -98,6 +107,8 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder)
 	else
 		radeon_combios_output_lock(encoder, true);
 	radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_lvds_commit(struct drm_encoder *encoder)
@@ -195,6 +206,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
 	.prepare = radeon_legacy_lvds_prepare,
 	.mode_set = radeon_legacy_lvds_mode_set,
 	.commit = radeon_legacy_lvds_commit,
+	.disable = radeon_legacy_encoder_disable,
 };
 
 
@@ -260,6 +272,7 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder)
 	else
 		radeon_combios_output_lock(encoder, true);
 	radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
+	radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder)
@@ -402,6 +415,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_fu
 	.mode_set = radeon_legacy_primary_dac_mode_set,
 	.commit = radeon_legacy_primary_dac_commit,
 	.detect = radeon_legacy_primary_dac_detect,
+	.disable = radeon_legacy_encoder_disable,
 };
 
 
@@ -454,6 +468,7 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder)
 	else
 		radeon_combios_output_lock(encoder, true);
 	radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF);
+	radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder)
@@ -566,6 +581,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs
 	.prepare = radeon_legacy_tmds_int_prepare,
 	.mode_set = radeon_legacy_tmds_int_mode_set,
 	.commit = radeon_legacy_tmds_int_commit,
+	.disable = radeon_legacy_encoder_disable,
 };
 
 
@@ -620,6 +636,7 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder)
 	else
 		radeon_combios_output_lock(encoder, true);
 	radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF);
+	radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder)
@@ -706,6 +723,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs
 	.prepare = radeon_legacy_tmds_ext_prepare,
 	.mode_set = radeon_legacy_tmds_ext_mode_set,
 	.commit = radeon_legacy_tmds_ext_commit,
+	.disable = radeon_legacy_encoder_disable,
 };
 
 
@@ -727,17 +745,21 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0;
-	/* uint32_t tv_master_cntl = 0; */
-
+	uint32_t tv_master_cntl = 0;
+	bool is_tv;
 	DRM_DEBUG("\n");
 
+	is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false;
+
 	if (rdev->family == CHIP_R200)
 		fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
 	else {
-		crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
-		/*  FIXME TV */
-		/* tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); */
+		if (is_tv)
+			tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL);
+		else
+			crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
 		tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
 	}
 
@@ -746,20 +768,23 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
 		if (rdev->family == CHIP_R200) {
 			fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
 		} else {
-			crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
-			/* tv_master_cntl |= RADEON_TV_ON; */
+			if (is_tv)
+				tv_master_cntl |= RADEON_TV_ON;
+			else
+				crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
+
 			if (rdev->family == CHIP_R420 ||
-					rdev->family == CHIP_R423 ||
-					rdev->family == CHIP_RV410)
+			    rdev->family == CHIP_R423 ||
+			    rdev->family == CHIP_RV410)
 				tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
-						R420_TV_DAC_GDACPD |
-						R420_TV_DAC_BDACPD |
-						RADEON_TV_DAC_BGSLEEP);
+						 R420_TV_DAC_GDACPD |
+						 R420_TV_DAC_BDACPD |
+						 RADEON_TV_DAC_BGSLEEP);
 			else
 				tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
-						RADEON_TV_DAC_GDACPD |
-						RADEON_TV_DAC_BDACPD |
-						RADEON_TV_DAC_BGSLEEP);
+						 RADEON_TV_DAC_GDACPD |
+						 RADEON_TV_DAC_BDACPD |
+						 RADEON_TV_DAC_BGSLEEP);
 		}
 		break;
 	case DRM_MODE_DPMS_STANDBY:
@@ -768,8 +793,11 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
 		if (rdev->family == CHIP_R200)
 			fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
 		else {
-			crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
-			/* tv_master_cntl &= ~RADEON_TV_ON; */
+			if (is_tv)
+				tv_master_cntl &= ~RADEON_TV_ON;
+			else
+				crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
+
 			if (rdev->family == CHIP_R420 ||
 					rdev->family == CHIP_R423 ||
 					rdev->family == CHIP_RV410)
@@ -789,8 +817,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
 	if (rdev->family == CHIP_R200) {
 		WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
 	} else {
-		WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
-		/* WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); */
+		if (is_tv)
+			WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
+		else
+			WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
 		WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
 	}
 
@@ -809,6 +839,7 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder)
 	else
 		radeon_combios_output_lock(encoder, true);
 	radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF);
+	radeon_encoder_set_active_device(encoder);
 }
 
 static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder)
@@ -831,11 +862,15 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
 	uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0;
-	uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0;
+	uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0;
+	bool is_tv = false;
 
 	DRM_DEBUG("\n");
 
+	is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false;
+
 	if (rdev->family != CHIP_R200) {
 		tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
 		if (rdev->family == CHIP_R420 ||
@@ -858,7 +893,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
 		}
 
 		/*  FIXME TV */
-		if (radeon_encoder->enc_priv) {
+		if (tv_dac) {
 			struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
 			tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
 					RADEON_TV_DAC_NHOLD |
@@ -875,44 +910,93 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
 	if (ASIC_IS_R300(rdev)) {
 		gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1;
 		disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
-	} else if (rdev->family == CHIP_R200)
-		fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
+	}
+
+	if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev))
+		disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL);
 	else
 		disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
 
-	dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL;
+	if (rdev->family == CHIP_R200)
+		fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
 
-	if (radeon_crtc->crtc_id == 0) {
-		if (ASIC_IS_R300(rdev)) {
-			disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
-			disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
-		} else if (rdev->family == CHIP_R200) {
-			fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
-					  RADEON_FP2_DVO_RATE_SEL_SDR);
-		} else
-			disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+	if (is_tv) {
+		uint32_t dac_cntl;
+
+		dac_cntl = RREG32(RADEON_DAC_CNTL);
+		dac_cntl &= ~RADEON_DAC_TVO_EN;
+		WREG32(RADEON_DAC_CNTL, dac_cntl);
+
+		if (ASIC_IS_R300(rdev))
+			gpiopad_a = RREG32(RADEON_GPIOPAD_A) & ~1;
+
+		dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~RADEON_DAC2_DAC2_CLK_SEL;
+		if (radeon_crtc->crtc_id == 0) {
+			if (ASIC_IS_R300(rdev)) {
+				disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+				disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC |
+						     RADEON_DISP_TV_SOURCE_CRTC);
+			}
+			if (rdev->family >= CHIP_R200) {
+				disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2;
+			} else {
+				disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+			}
+		} else {
+			if (ASIC_IS_R300(rdev)) {
+				disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+				disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC;
+			}
+			if (rdev->family >= CHIP_R200) {
+				disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2;
+			} else {
+				disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
+			}
+		}
+		WREG32(RADEON_DAC_CNTL2, dac2_cntl);
 	} else {
-		if (ASIC_IS_R300(rdev)) {
-			disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
-			disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
-		} else if (rdev->family == CHIP_R200) {
-			fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
-					  RADEON_FP2_DVO_RATE_SEL_SDR);
-			fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
-		} else
-			disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
-	}
 
-	WREG32(RADEON_DAC_CNTL2, dac2_cntl);
+		dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL;
+
+		if (radeon_crtc->crtc_id == 0) {
+			if (ASIC_IS_R300(rdev)) {
+				disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+				disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
+			} else if (rdev->family == CHIP_R200) {
+				fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
+						  RADEON_FP2_DVO_RATE_SEL_SDR);
+			} else
+				disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+		} else {
+			if (ASIC_IS_R300(rdev)) {
+				disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+				disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+			} else if (rdev->family == CHIP_R200) {
+				fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
+						  RADEON_FP2_DVO_RATE_SEL_SDR);
+				fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+			} else
+				disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
+		}
+		WREG32(RADEON_DAC_CNTL2, dac2_cntl);
+	}
 
 	if (ASIC_IS_R300(rdev)) {
 		WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
-		WREG32(RADEON_DISP_TV_OUT_CNTL, disp_output_cntl);
-	} else if (rdev->family == CHIP_R200)
-		WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+		WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+	}
+
+	if (rdev->family >= CHIP_R200)
+		WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl);
 	else
 		WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
 
+	if (rdev->family == CHIP_R200)
+		WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+
+	if (is_tv)
+		radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode);
+
 	if (rdev->is_atom_bios)
 		radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id);
 	else
@@ -920,6 +1004,141 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
 
 }
 
+static bool r300_legacy_tv_detect(struct drm_encoder *encoder,
+				  struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
+	uint32_t disp_output_cntl, gpiopad_a, tmp;
+	bool found = false;
+
+	/* save regs needed */
+	gpiopad_a = RREG32(RADEON_GPIOPAD_A);
+	dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
+	crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
+	dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
+	tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
+	disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
+
+	WREG32_P(RADEON_GPIOPAD_A, 0, ~1);
+
+	WREG32(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL);
+
+	WREG32(RADEON_CRTC2_GEN_CNTL,
+	       RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT);
+
+	tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+	tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+	WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
+
+	WREG32(RADEON_DAC_EXT_CNTL,
+	       RADEON_DAC2_FORCE_BLANK_OFF_EN |
+	       RADEON_DAC2_FORCE_DATA_EN |
+	       RADEON_DAC_FORCE_DATA_SEL_RGB |
+	       (0xec << RADEON_DAC_FORCE_DATA_SHIFT));
+
+	WREG32(RADEON_TV_DAC_CNTL,
+	       RADEON_TV_DAC_STD_NTSC |
+	       (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+	       (6 << RADEON_TV_DAC_DACADJ_SHIFT));
+
+	RREG32(RADEON_TV_DAC_CNTL);
+	mdelay(4);
+
+	WREG32(RADEON_TV_DAC_CNTL,
+	       RADEON_TV_DAC_NBLANK |
+	       RADEON_TV_DAC_NHOLD |
+	       RADEON_TV_MONITOR_DETECT_EN |
+	       RADEON_TV_DAC_STD_NTSC |
+	       (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+	       (6 << RADEON_TV_DAC_DACADJ_SHIFT));
+
+	RREG32(RADEON_TV_DAC_CNTL);
+	mdelay(6);
+
+	tmp = RREG32(RADEON_TV_DAC_CNTL);
+	if ((tmp & RADEON_TV_DAC_GDACDET) != 0) {
+		found = true;
+		DRM_DEBUG("S-video TV connection detected\n");
+	} else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) {
+		found = true;
+		DRM_DEBUG("Composite TV connection detected\n");
+	}
+
+	WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+	WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+	WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+	WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+	WREG32(RADEON_DAC_CNTL2, dac_cntl2);
+	WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+	return found;
+}
+
+static bool radeon_legacy_tv_detect(struct drm_encoder *encoder,
+				    struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t tv_dac_cntl, dac_cntl2;
+	uint32_t config_cntl, tv_pre_dac_mux_cntl, tv_master_cntl, tmp;
+	bool found = false;
+
+	if (ASIC_IS_R300(rdev))
+		return r300_legacy_tv_detect(encoder, connector);
+
+	dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
+	tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL);
+	tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
+	config_cntl = RREG32(RADEON_CONFIG_CNTL);
+	tv_pre_dac_mux_cntl = RREG32(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+	tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
+	WREG32(RADEON_DAC_CNTL2, tmp);
+
+	tmp = tv_master_cntl | RADEON_TV_ON;
+	tmp &= ~(RADEON_TV_ASYNC_RST |
+		 RADEON_RESTART_PHASE_FIX |
+		 RADEON_CRT_FIFO_CE_EN |
+		 RADEON_TV_FIFO_CE_EN |
+		 RADEON_RE_SYNC_NOW_SEL_MASK);
+	tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
+	WREG32(RADEON_TV_MASTER_CNTL, tmp);
+
+	tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
+		RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
+		(8 << RADEON_TV_DAC_BGADJ_SHIFT);
+
+	if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
+		tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
+	else
+		tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
+	WREG32(RADEON_TV_DAC_CNTL, tmp);
+
+	tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
+		RADEON_RED_MX_FORCE_DAC_DATA |
+		RADEON_GRN_MX_FORCE_DAC_DATA |
+		RADEON_BLU_MX_FORCE_DAC_DATA |
+		(0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
+	WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
+
+	mdelay(3);
+	tmp = RREG32(RADEON_TV_DAC_CNTL);
+	if (tmp & RADEON_TV_DAC_GDACDET) {
+		found = true;
+		DRM_DEBUG("S-video TV connection detected\n");
+	} else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) {
+		found = true;
+		DRM_DEBUG("Composite TV connection detected\n");
+	}
+
+	WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
+	WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+	WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
+	WREG32(RADEON_DAC_CNTL2, dac_cntl2);
+	return found;
+}
+
 static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
 							     struct drm_connector *connector)
 {
@@ -928,9 +1147,29 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
 	uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
 	uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
 	enum drm_connector_status found = connector_status_disconnected;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
 	bool color = true;
 
-	/*  FIXME tv */
+	if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO ||
+	    connector->connector_type == DRM_MODE_CONNECTOR_Composite ||
+	    connector->connector_type == DRM_MODE_CONNECTOR_9PinDIN) {
+		bool tv_detect;
+
+		if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT))
+			return connector_status_disconnected;
+
+		tv_detect = radeon_legacy_tv_detect(encoder, connector);
+		if (tv_detect && tv_dac)
+			found = connector_status_connected;
+		return found;
+	}
+
+	/* don't probe if the encoder is being used for something else not CRT related */
+	if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT)) {
+		DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device);
+		return connector_status_disconnected;
+	}
 
 	/* save the regs we need */
 	pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
@@ -1013,8 +1252,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
 	}
 	WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
 
-	/* return found; */
-	return connector_status_disconnected;
+	return found;
 
 }
 
@@ -1025,6 +1263,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs =
 	.mode_set = radeon_legacy_tv_dac_mode_set,
 	.commit = radeon_legacy_tv_dac_commit,
 	.detect = radeon_legacy_tv_dac_detect,
+	.disable = radeon_legacy_encoder_disable,
 };
 
 
@@ -1032,6 +1271,30 @@ static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = {
 	.destroy = radeon_enc_destroy,
 };
 
+
+static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon_encoder *encoder)
+{
+	struct drm_device *dev = encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder_int_tmds *tmds = NULL;
+	bool ret;
+
+	tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
+
+	if (!tmds)
+		return NULL;
+
+	if (rdev->is_atom_bios)
+		ret = radeon_atombios_get_tmds_info(encoder, tmds);
+	else
+		ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
+
+	if (ret == false)
+		radeon_legacy_get_tmds_info_from_table(encoder, tmds);
+
+	return tmds;
+}
+
 void
 radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
 {
@@ -1078,10 +1341,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 		drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS);
 		drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
-		if (rdev->is_atom_bios)
-			radeon_encoder->enc_priv = radeon_atombios_get_tmds_info(radeon_encoder);
-		else
-			radeon_encoder->enc_priv = radeon_combios_get_tmds_info(radeon_encoder);
+		radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder);
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 		drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
new file mode 100644
index 0000000..3a12bb0
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c
@@ -0,0 +1,904 @@
+#include "drmP.h"
+#include "drm_crtc_helper.h"
+#include "radeon.h"
+
+/*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi@lycos.com>
+ */
+
+
+/*
+ * Limits of h/v positions (hPos & vPos)
+ */
+#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */
+#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */
+
+/*
+ * Unit for hPos (in TV clock periods)
+ */
+#define H_POS_UNIT 10
+
+/*
+ * Indexes in h. code timing table for horizontal line position adjustment
+ */
+#define H_TABLE_POS1 6
+#define H_TABLE_POS2 8
+
+/*
+ * Limits of hor. size (hSize)
+ */
+#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */
+
+/* tv standard constants */
+#define NTSC_TV_CLOCK_T 233
+#define NTSC_TV_VFTOTAL 1
+#define NTSC_TV_LINES_PER_FRAME 525
+#define NTSC_TV_ZERO_H_SIZE 479166
+#define NTSC_TV_H_SIZE_UNIT 9478
+
+#define PAL_TV_CLOCK_T 188
+#define PAL_TV_VFTOTAL 3
+#define PAL_TV_LINES_PER_FRAME 625
+#define PAL_TV_ZERO_H_SIZE 473200
+#define PAL_TV_H_SIZE_UNIT 9360
+
+/* tv pll setting for 27 mhz ref clk */
+#define NTSC_TV_PLL_M_27 22
+#define NTSC_TV_PLL_N_27 175
+#define NTSC_TV_PLL_P_27 5
+
+#define PAL_TV_PLL_M_27 113
+#define PAL_TV_PLL_N_27 668
+#define PAL_TV_PLL_P_27 3
+
+/* tv pll setting for 14 mhz ref clk */
+#define NTSC_TV_PLL_M_14 33
+#define NTSC_TV_PLL_N_14 693
+#define NTSC_TV_PLL_P_14 7
+
+#define VERT_LEAD_IN_LINES 2
+#define FRAC_BITS 0xe
+#define FRAC_MASK 0x3fff
+
+struct radeon_tv_mode_constants {
+	uint16_t hor_resolution;
+	uint16_t ver_resolution;
+	enum radeon_tv_std standard;
+	uint16_t hor_total;
+	uint16_t ver_total;
+	uint16_t hor_start;
+	uint16_t hor_syncstart;
+	uint16_t ver_syncstart;
+	unsigned def_restart;
+	uint16_t crtcPLL_N;
+	uint8_t  crtcPLL_M;
+	uint8_t  crtcPLL_post_div;
+	unsigned pix_to_tv;
+};
+
+static const uint16_t hor_timing_NTSC[] = {
+	0x0007,
+	0x003f,
+	0x0263,
+	0x0a24,
+	0x2a6b,
+	0x0a36,
+	0x126d, /* H_TABLE_POS1 */
+	0x1bfe,
+	0x1a8f, /* H_TABLE_POS2 */
+	0x1ec7,
+	0x3863,
+	0x1bfe,
+	0x1bfe,
+	0x1a2a,
+	0x1e95,
+	0x0e31,
+	0x201b,
+	0
+};
+
+static const uint16_t vert_timing_NTSC[] = {
+	0x2001,
+	0x200d,
+	0x1006,
+	0x0c06,
+	0x1006,
+	0x1818,
+	0x21e3,
+	0x1006,
+	0x0c06,
+	0x1006,
+	0x1817,
+	0x21d4,
+	0x0002,
+	0
+};
+
+static const uint16_t hor_timing_PAL[] = {
+	0x0007,
+	0x0058,
+	0x027c,
+	0x0a31,
+	0x2a77,
+	0x0a95,
+	0x124f, /* H_TABLE_POS1 */
+	0x1bfe,
+	0x1b22, /* H_TABLE_POS2 */
+	0x1ef9,
+	0x387c,
+	0x1bfe,
+	0x1bfe,
+	0x1b31,
+	0x1eb5,
+	0x0e43,
+	0x201b,
+	0
+};
+
+static const uint16_t vert_timing_PAL[] = 	{
+	0x2001,
+	0x200c,
+	0x1005,
+	0x0c05,
+	0x1005,
+	0x1401,
+	0x1821,
+	0x2240,
+	0x1005,
+	0x0c05,
+	0x1005,
+	0x1401,
+	0x1822,
+	0x2230,
+	0x0002,
+	0
+};
+
+/**********************************************************************
+ *
+ * availableModes
+ *
+ * Table of all allowed modes for tv output
+ *
+ **********************************************************************/
+static const struct radeon_tv_mode_constants available_tv_modes[] = {
+	{   /* NTSC timing for 27 Mhz ref clk */
+		800,                /* horResolution */
+		600,                /* verResolution */
+		TV_STD_NTSC,        /* standard */
+		990,                /* horTotal */
+		740,                /* verTotal */
+		813,                /* horStart */
+		824,                /* horSyncStart */
+		632,                /* verSyncStart */
+		625592,             /* defRestart */
+		592,                /* crtcPLL_N */
+		91,                 /* crtcPLL_M */
+		4,                  /* crtcPLL_postDiv */
+		1022,               /* pixToTV */
+	},
+	{   /* PAL timing for 27 Mhz ref clk */
+		800,               /* horResolution */
+		600,               /* verResolution */
+		TV_STD_PAL,        /* standard */
+		1144,              /* horTotal */
+		706,               /* verTotal */
+		812,               /* horStart */
+		824,               /* horSyncStart */
+		669,               /* verSyncStart */
+		696700,            /* defRestart */
+		1382,              /* crtcPLL_N */
+		231,               /* crtcPLL_M */
+		4,                 /* crtcPLL_postDiv */
+		759,               /* pixToTV */
+	},
+	{   /* NTSC timing for 14 Mhz ref clk */
+		800,                /* horResolution */
+		600,                /* verResolution */
+		TV_STD_NTSC,        /* standard */
+		1018,               /* horTotal */
+		727,                /* verTotal */
+		813,                /* horStart */
+		840,                /* horSyncStart */
+		633,                /* verSyncStart */
+		630627,             /* defRestart */
+		347,                /* crtcPLL_N */
+		14,                 /* crtcPLL_M */
+			8,                  /* crtcPLL_postDiv */
+		1022,               /* pixToTV */
+	},
+};
+
+#define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes)
+
+static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder,
+									    uint16_t *pll_ref_freq)
+{
+	struct drm_device *dev = radeon_encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_crtc *radeon_crtc;
+	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
+	const struct radeon_tv_mode_constants *const_ptr;
+	struct radeon_pll *pll;
+
+	radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
+	if (radeon_crtc->crtc_id == 1)
+		pll = &rdev->clock.p2pll;
+	else
+		pll = &rdev->clock.p1pll;
+
+	if (pll_ref_freq)
+		*pll_ref_freq = pll->reference_freq;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M) {
+		if (pll->reference_freq == 2700)
+			const_ptr = &available_tv_modes[0];
+		else
+			const_ptr = &available_tv_modes[2];
+	} else {
+		if (pll->reference_freq == 2700)
+			const_ptr = &available_tv_modes[1];
+		else
+			const_ptr = &available_tv_modes[1]; /* FIX ME */
+	}
+	return const_ptr;
+}
+
+static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
+static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
+static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
+static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
+
+static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests,
+				 unsigned n_wait_loops, unsigned cnt_threshold)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t save_pll_test;
+	unsigned int i, j;
+
+	WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
+	save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL);
+	WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B);
+
+	WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
+	for (i = 0; i < n_tests; i++) {
+		WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
+		for (j = 0; j < n_wait_loops; j++)
+			if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold)
+				break;
+	}
+	WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test);
+	WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
+}
+
+
+static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder,
+					uint16_t addr, uint32_t value)
+{
+	struct drm_device *dev = radeon_encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t tmp;
+	int i = 0;
+
+	WREG32(RADEON_TV_HOST_WRITE_DATA, value);
+
+	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
+	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
+
+	do {
+		tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
+		if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
+			break;
+		i++;
+	} while (i < 10000);
+	WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
+}
+
+#if 0 /* included for completeness */
+static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr)
+{
+	struct drm_device *dev = radeon_encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	uint32_t tmp;
+	int i = 0;
+
+	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr);
+	WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
+
+	do {
+		tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL);
+		if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
+			break;
+		i++;
+	} while (i < 10000);
+	WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0);
+	return RREG32(RADEON_TV_HOST_READ_DATA);
+}
+#endif
+
+static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr)
+{
+	uint16_t h_table;
+
+	switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
+	case 0:
+		h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
+		break;
+	case 1:
+		h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
+		break;
+	case 2:
+		h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
+		break;
+	default:
+		h_table = 0;
+		break;
+	}
+	return h_table;
+}
+
+static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr)
+{
+	uint16_t v_table;
+
+	switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
+	case 0:
+		v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
+		break;
+	case 1:
+		v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
+		break;
+	case 2:
+		v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
+		break;
+	default:
+		v_table = 0;
+		break;
+	}
+	return v_table;
+}
+
+static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder)
+{
+	struct drm_device *dev = radeon_encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
+	uint16_t h_table, v_table;
+	uint32_t tmp;
+	int i;
+
+	WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr);
+	h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr);
+	v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr);
+
+	for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) {
+		tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]);
+		radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp);
+		if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0)
+			break;
+	}
+	for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) {
+		tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]);
+		radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp);
+		if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0)
+			break;
+	}
+}
+
+static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder)
+{
+	struct drm_device *dev = radeon_encoder->base.dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
+	WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart);
+	WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart);
+	WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart);
+}
+
+static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
+	struct radeon_crtc *radeon_crtc;
+	int restart;
+	unsigned int h_total, v_total, f_total;
+	int v_offset, h_offset;
+	u16 p1, p2, h_inc;
+	bool h_changed;
+	const struct radeon_tv_mode_constants *const_ptr;
+	struct radeon_pll *pll;
+
+	radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc);
+	if (radeon_crtc->crtc_id == 1)
+		pll = &rdev->clock.p2pll;
+	else
+		pll = &rdev->clock.p1pll;
+
+	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
+	if (!const_ptr)
+		return false;
+
+	h_total = const_ptr->hor_total;
+	v_total = const_ptr->ver_total;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M ||
+	    tv_dac->tv_std == TV_STD_PAL_60)
+		f_total = NTSC_TV_VFTOTAL + 1;
+	else
+		f_total = PAL_TV_VFTOTAL + 1;
+
+	/* adjust positions 1&2 in hor. cod timing table */
+	h_offset = tv_dac->h_pos * H_POS_UNIT;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M) {
+		h_offset -= 50;
+		p1 = hor_timing_NTSC[H_TABLE_POS1];
+		p2 = hor_timing_NTSC[H_TABLE_POS2];
+	} else {
+		p1 = hor_timing_PAL[H_TABLE_POS1];
+		p2 = hor_timing_PAL[H_TABLE_POS2];
+	}
+
+	p1 = (u16)((int)p1 + h_offset);
+	p2 = (u16)((int)p2 - h_offset);
+
+	h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] ||
+		     p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]);
+
+	tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1;
+	tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2;
+
+	/* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */
+	h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000;
+
+	/* adjust restart */
+	restart = const_ptr->def_restart;
+
+	/*
+	 * convert v_pos TV lines to n. of CRTC pixels
+	 */
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M ||
+	    tv_dac->tv_std == TV_STD_PAL_60)
+		v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME);
+	else
+		v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME);
+
+	restart -= v_offset + h_offset;
+
+	DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n",
+		  const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart);
+
+	tv_dac->tv.hrestart = restart % h_total;
+	restart /= h_total;
+	tv_dac->tv.vrestart = restart % v_total;
+	restart /= v_total;
+	tv_dac->tv.frestart = restart % f_total;
+
+	DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n",
+		  (unsigned)tv_dac->tv.frestart,
+		  (unsigned)tv_dac->tv.vrestart,
+		  (unsigned)tv_dac->tv.hrestart);
+
+	/* compute h_inc from hsize */
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M)
+		h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) /
+			      (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
+	else
+		h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) /
+			      (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
+
+	tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) |
+		((u32)h_inc << RADEON_H_INC_SHIFT);
+
+	DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc);
+
+	return h_changed;
+}
+
+void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
+	const struct radeon_tv_mode_constants *const_ptr;
+	struct radeon_crtc *radeon_crtc;
+	int i;
+	uint16_t pll_ref_freq;
+	uint32_t vert_space, flicker_removal, tmp;
+	uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl;
+	uint32_t tv_modulator_cntl1, tv_modulator_cntl2;
+	uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2;
+	uint32_t tv_pll_cntl, tv_pll_cntl1, tv_ftotal;
+	uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl;
+	uint32_t m, n, p;
+	const uint16_t *hor_timing;
+	const uint16_t *vert_timing;
+
+	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq);
+	if (!const_ptr)
+		return;
+
+	radeon_crtc = to_radeon_crtc(encoder->crtc);
+
+	tv_master_cntl = (RADEON_VIN_ASYNC_RST |
+			  RADEON_CRT_FIFO_CE_EN |
+			  RADEON_TV_FIFO_CE_EN |
+			  RADEON_TV_ON);
+
+	if (!ASIC_IS_R300(rdev))
+		tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J)
+		tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
+
+	tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT |
+			      RADEON_SYNC_TIP_LEVEL |
+			      RADEON_YFLT_EN |
+			      RADEON_UVFLT_EN |
+			      (6 << RADEON_CY_FILT_BLEND_SHIFT));
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J) {
+		tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) |
+			(0x3b << RADEON_BLANK_LEVEL_SHIFT);
+		tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |
+			((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
+	} else if (tv_dac->tv_std == TV_STD_SCART_PAL) {
+		tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;
+		tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |
+			((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
+	} else {
+		tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN |
+			(0x3b << RADEON_SET_UP_LEVEL_SHIFT) |
+			(0x3b << RADEON_BLANK_LEVEL_SHIFT);
+		tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) |
+			((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
+	}
+
+
+	tv_rgb_cntl = (RADEON_RGB_DITHER_EN
+		       | RADEON_TVOUT_SCALE_EN
+		       | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT)
+		       | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT)
+		       | RADEON_RGB_ATTEN_SEL(0x3)
+		       | RADEON_RGB_ATTEN_VAL(0xc));
+
+	if (radeon_crtc->crtc_id == 1)
+		tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;
+	else {
+		if (radeon_crtc->rmx_type != RMX_OFF)
+			tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;
+		else
+			tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;
+	}
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M ||
+	    tv_dac->tv_std == TV_STD_PAL_60)
+		vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
+	else
+		vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
+
+	tmp = RREG32(RADEON_TV_VSCALER_CNTL1);
+	tmp &= 0xe3ff0000;
+	tmp |= (vert_space * (1 << FRAC_BITS) / 10000);
+	tv_vscaler_cntl1 = tmp;
+
+	if (pll_ref_freq == 2700)
+		tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
+
+	if (const_ptr->hor_resolution == 1024)
+		tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
+	else
+		tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
+
+	/* scale up for int divide */
+	tmp = const_ptr->ver_total * 2 * 1000;
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M ||
+	    tv_dac->tv_std == TV_STD_PAL_60) {
+		tmp /= NTSC_TV_LINES_PER_FRAME;
+	} else {
+		tmp /= PAL_TV_LINES_PER_FRAME;
+	}
+	flicker_removal = (tmp + 500) / 1000;
+
+	if (flicker_removal < 3)
+		flicker_removal = 3;
+	for (i = 0; i < 6; ++i) {
+		if (flicker_removal == SLOPE_limit[i])
+			break;
+	}
+
+	tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) +
+				5001) / 10000 / 8 | ((SLOPE_value[i] *
+				(1 << (FRAC_BITS - 1)) / 8) << 16);
+	tv_y_fall_cntl =
+		(YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |
+		RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /
+		1024;
+	tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG|
+		(flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;
+
+	tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0;
+	tv_vscaler_cntl2 |= (0x10 << 24) |
+		RADEON_DITHER_MODE |
+		RADEON_Y_OUTPUT_DITHER_EN |
+		RADEON_UV_OUTPUT_DITHER_EN |
+		RADEON_UV_TO_BUF_DITHER_EN;
+
+	tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
+	tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
+	tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
+	tv_dac->tv.timing_cntl = tmp;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M ||
+	    tv_dac->tv_std == TV_STD_PAL_60)
+		tv_dac_cntl = tv_dac->ntsc_tvdac_adj;
+	else
+		tv_dac_cntl = tv_dac->pal_tvdac_adj;
+
+	tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J)
+		tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+	else
+		tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J) {
+		if (pll_ref_freq == 2700) {
+			m = NTSC_TV_PLL_M_27;
+			n = NTSC_TV_PLL_N_27;
+			p = NTSC_TV_PLL_P_27;
+		} else {
+			m = NTSC_TV_PLL_M_14;
+			n = NTSC_TV_PLL_N_14;
+			p = NTSC_TV_PLL_P_14;
+		}
+	} else {
+		if (pll_ref_freq == 2700) {
+			m = PAL_TV_PLL_M_27;
+			n = PAL_TV_PLL_N_27;
+			p = PAL_TV_PLL_P_27;
+		} else {
+			m = PAL_TV_PLL_M_27;
+			n = PAL_TV_PLL_N_27;
+			p = PAL_TV_PLL_P_27;
+		}
+	}
+
+	tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) |
+		(((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
+		((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
+		(((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+		((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
+
+	tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK) << RADEON_TVPCP_SHIFT) |
+			((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) |
+			((1 & RADEON_TVPDC_MASK) << RADEON_TVPDC_SHIFT) |
+			RADEON_TVCLK_SRC_SEL_TVPLL |
+			RADEON_TVPLL_TEST_DIS);
+
+	tv_dac->tv.tv_uv_adr = 0xc8;
+
+	if (tv_dac->tv_std == TV_STD_NTSC ||
+	    tv_dac->tv_std == TV_STD_NTSC_J ||
+	    tv_dac->tv_std == TV_STD_PAL_M ||
+	    tv_dac->tv_std == TV_STD_PAL_60) {
+		tv_ftotal = NTSC_TV_VFTOTAL;
+		hor_timing = hor_timing_NTSC;
+		vert_timing = vert_timing_NTSC;
+	} else {
+		hor_timing = hor_timing_PAL;
+		vert_timing = vert_timing_PAL;
+		tv_ftotal = PAL_TV_VFTOTAL;
+	}
+
+	for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
+		if ((tv_dac->tv.h_code_timing[i] = hor_timing[i]) == 0)
+			break;
+	}
+
+	for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
+		if ((tv_dac->tv.v_code_timing[i] = vert_timing[i]) == 0)
+			break;
+	}
+
+	radeon_legacy_tv_init_restarts(encoder);
+
+	/* play with DAC_CNTL */
+	/* play with GPIOPAD_A */
+	/* DISP_OUTPUT_CNTL */
+	/* use reference freq */
+
+	/* program the TV registers */
+	WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
+				       RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST));
+
+	tmp = RREG32(RADEON_TV_DAC_CNTL);
+	tmp &= ~RADEON_TV_DAC_NBLANK;
+	tmp |= RADEON_TV_DAC_BGSLEEP |
+		RADEON_TV_DAC_RDACPD |
+		RADEON_TV_DAC_GDACPD |
+		RADEON_TV_DAC_BDACPD;
+	WREG32(RADEON_TV_DAC_CNTL, tmp);
+
+	/* TV PLL */
+	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+	WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl);
+	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
+
+	radeon_wait_pll_lock(encoder, 200, 800, 135);
+
+	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
+
+	radeon_wait_pll_lock(encoder, 300, 160, 27);
+	radeon_wait_pll_lock(encoder, 200, 800, 135);
+
+	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf);
+	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+
+	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
+	WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
+
+	/* TV HV */
+	WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl);
+	WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1);
+	WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1);
+	WREG32(RADEON_TV_HSTART, const_ptr->hor_start);
+
+	WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1);
+	WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1);
+	WREG32(RADEON_TV_FTOTAL, tv_ftotal);
+	WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1);
+	WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2);
+
+	WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl);
+	WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl);
+	WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl);
+
+	WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST |
+				       RADEON_CRT_ASYNC_RST));
+
+	/* TV restarts */
+	radeon_legacy_write_tv_restarts(radeon_encoder);
+
+	/* tv timings */
+	radeon_restore_tv_timing_tables(radeon_encoder);
+
+	WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST));
+
+	/* tv std */
+	WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE));
+	WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl);
+	WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1);
+	WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2);
+	WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN |
+					    RADEON_C_GRN_EN |
+					    RADEON_CMP_BLU_EN |
+					    RADEON_DAC_DITHER_EN));
+
+	WREG32(RADEON_TV_CRC_CNTL, 0);
+
+	WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
+
+	WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) |
+					       (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT)));
+	WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) |
+						(0x100 << RADEON_Y_GAIN_SHIFT)));
+
+	WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+
+}
+
+void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
+				      uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,
+				      uint32_t *v_total_disp, uint32_t *v_sync_strt_wid)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	const struct radeon_tv_mode_constants *const_ptr;
+	uint32_t tmp;
+
+	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
+	if (!const_ptr)
+		return;
+
+	*h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
+		(((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
+
+	tmp = *h_sync_strt_wid;
+	tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR);
+	tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
+		(const_ptr->hor_syncstart & 7);
+	*h_sync_strt_wid = tmp;
+
+	*v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
+		((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
+
+	tmp = *v_sync_strt_wid;
+	tmp &= ~RADEON_CRTC_V_SYNC_STRT;
+	tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
+	*v_sync_strt_wid = tmp;
+}
+
+static inline int get_post_div(int value)
+{
+	int post_div;
+	switch (value) {
+	case 1: post_div = 0; break;
+	case 2: post_div = 1; break;
+	case 3: post_div = 4; break;
+	case 4: post_div = 2; break;
+	case 6: post_div = 6; break;
+	case 8: post_div = 3; break;
+	case 12: post_div = 7; break;
+	case 16:
+	default: post_div = 5; break;
+	}
+	return post_div;
+}
+
+void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder,
+				  uint32_t *htotal_cntl, uint32_t *ppll_ref_div,
+				  uint32_t *ppll_div_3, uint32_t *pixclks_cntl)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	const struct radeon_tv_mode_constants *const_ptr;
+
+	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
+	if (!const_ptr)
+		return;
+
+	*htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN;
+
+	*ppll_ref_div = const_ptr->crtcPLL_M;
+
+	*ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
+	*pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);
+	*pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
+}
+
+void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
+				  uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div,
+				  uint32_t *p2pll_div_0, uint32_t *pixclks_cntl)
+{
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	const struct radeon_tv_mode_constants *const_ptr;
+
+	const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL);
+	if (!const_ptr)
+		return;
+
+	*htotal2_cntl = (const_ptr->hor_total & 0x7);
+
+	*p2pll_ref_div = const_ptr->crtcPLL_M;
+
+	*p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16);
+	*pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;
+	*pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL;
+}
+
diff --git a/drivers/gpu/drm/radeon/radeon_microcode.h b/drivers/gpu/drm/radeon/radeon_microcode.h
deleted file mode 100644
index a348c9e..0000000
--- a/drivers/gpu/drm/radeon/radeon_microcode.h
+++ /dev/null
@@ -1,1844 +0,0 @@
-/*
- * Copyright 2007 Advanced Micro Devices, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#ifndef RADEON_MICROCODE_H
-#define RADEON_MICROCODE_H
-
-/* production radeon ucode r1xx-r6xx */
-static const u32 R100_cp_microcode[][2] = {
-    { 0x21007000, 0000000000 },
-    { 0x20007000, 0000000000 },
-    { 0x000000b4, 0x00000004 },
-    { 0x000000b8, 0x00000004 },
-    { 0x6f5b4d4c, 0000000000 },
-    { 0x4c4c427f, 0000000000 },
-    { 0x5b568a92, 0000000000 },
-    { 0x4ca09c6d, 0000000000 },
-    { 0xad4c4c4c, 0000000000 },
-    { 0x4ce1af3d, 0000000000 },
-    { 0xd8afafaf, 0000000000 },
-    { 0xd64c4cdc, 0000000000 },
-    { 0x4cd10d10, 0000000000 },
-    { 0x000f0000, 0x00000016 },
-    { 0x362f242d, 0000000000 },
-    { 0x00000012, 0x00000004 },
-    { 0x000f0000, 0x00000016 },
-    { 0x362f282d, 0000000000 },
-    { 0x000380e7, 0x00000002 },
-    { 0x04002c97, 0x00000002 },
-    { 0x000f0001, 0x00000016 },
-    { 0x333a3730, 0000000000 },
-    { 0x000077ef, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x00000021, 0x0000001a },
-    { 0x00004000, 0x0000001e },
-    { 0x00061000, 0x00000002 },
-    { 0x00000021, 0x0000001a },
-    { 0x00004000, 0x0000001e },
-    { 0x00061000, 0x00000002 },
-    { 0x00000021, 0x0000001a },
-    { 0x00004000, 0x0000001e },
-    { 0x00000017, 0x00000004 },
-    { 0x0003802b, 0x00000002 },
-    { 0x040067e0, 0x00000002 },
-    { 0x00000017, 0x00000004 },
-    { 0x000077e0, 0x00000002 },
-    { 0x00065000, 0x00000002 },
-    { 0x000037e1, 0x00000002 },
-    { 0x040067e1, 0x00000006 },
-    { 0x000077e0, 0x00000002 },
-    { 0x000077e1, 0x00000002 },
-    { 0x000077e1, 0x00000006 },
-    { 0xffffffff, 0000000000 },
-    { 0x10000000, 0000000000 },
-    { 0x0003802b, 0x00000002 },
-    { 0x040067e0, 0x00000006 },
-    { 0x00007675, 0x00000002 },
-    { 0x00007676, 0x00000002 },
-    { 0x00007677, 0x00000002 },
-    { 0x00007678, 0x00000006 },
-    { 0x0003802c, 0x00000002 },
-    { 0x04002676, 0x00000002 },
-    { 0x00007677, 0x00000002 },
-    { 0x00007678, 0x00000006 },
-    { 0x0000002f, 0x00000018 },
-    { 0x0000002f, 0x00000018 },
-    { 0000000000, 0x00000006 },
-    { 0x00000030, 0x00000018 },
-    { 0x00000030, 0x00000018 },
-    { 0000000000, 0x00000006 },
-    { 0x01605000, 0x00000002 },
-    { 0x00065000, 0x00000002 },
-    { 0x00098000, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x64c0603e, 0x00000004 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x00080000, 0x00000016 },
-    { 0000000000, 0000000000 },
-    { 0x0400251d, 0x00000002 },
-    { 0x00007580, 0x00000002 },
-    { 0x00067581, 0x00000002 },
-    { 0x04002580, 0x00000002 },
-    { 0x00067581, 0x00000002 },
-    { 0x00000049, 0x00000004 },
-    { 0x00005000, 0000000000 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x0000750e, 0x00000002 },
-    { 0x00019000, 0x00000002 },
-    { 0x00011055, 0x00000014 },
-    { 0x00000055, 0x00000012 },
-    { 0x0400250f, 0x00000002 },
-    { 0x0000504f, 0x00000004 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x00007565, 0x00000002 },
-    { 0x00007566, 0x00000002 },
-    { 0x00000058, 0x00000004 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x01e655b4, 0x00000002 },
-    { 0x4401b0e4, 0x00000002 },
-    { 0x01c110e4, 0x00000002 },
-    { 0x26667066, 0x00000018 },
-    { 0x040c2565, 0x00000002 },
-    { 0x00000066, 0x00000018 },
-    { 0x04002564, 0x00000002 },
-    { 0x00007566, 0x00000002 },
-    { 0x0000005d, 0x00000004 },
-    { 0x00401069, 0x00000008 },
-    { 0x00101000, 0x00000002 },
-    { 0x000d80ff, 0x00000002 },
-    { 0x0080006c, 0x00000008 },
-    { 0x000f9000, 0x00000002 },
-    { 0x000e00ff, 0x00000002 },
-    { 0000000000, 0x00000006 },
-    { 0x0000008f, 0x00000018 },
-    { 0x0000005b, 0x00000004 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x00007576, 0x00000002 },
-    { 0x00065000, 0x00000002 },
-    { 0x00009000, 0x00000002 },
-    { 0x00041000, 0x00000002 },
-    { 0x0c00350e, 0x00000002 },
-    { 0x00049000, 0x00000002 },
-    { 0x00051000, 0x00000002 },
-    { 0x01e785f8, 0x00000002 },
-    { 0x00200000, 0x00000002 },
-    { 0x0060007e, 0x0000000c },
-    { 0x00007563, 0x00000002 },
-    { 0x006075f0, 0x00000021 },
-    { 0x20007073, 0x00000004 },
-    { 0x00005073, 0x00000004 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x00007576, 0x00000002 },
-    { 0x00007577, 0x00000002 },
-    { 0x0000750e, 0x00000002 },
-    { 0x0000750f, 0x00000002 },
-    { 0x00a05000, 0x00000002 },
-    { 0x00600083, 0x0000000c },
-    { 0x006075f0, 0x00000021 },
-    { 0x000075f8, 0x00000002 },
-    { 0x00000083, 0x00000004 },
-    { 0x000a750e, 0x00000002 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x0020750f, 0x00000002 },
-    { 0x00600086, 0x00000004 },
-    { 0x00007570, 0x00000002 },
-    { 0x00007571, 0x00000002 },
-    { 0x00007572, 0x00000006 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x00005000, 0x00000002 },
-    { 0x00a05000, 0x00000002 },
-    { 0x00007568, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x00000095, 0x0000000c },
-    { 0x00058000, 0x00000002 },
-    { 0x0c607562, 0x00000002 },
-    { 0x00000097, 0x00000004 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x00600096, 0x00000004 },
-    { 0x400070e5, 0000000000 },
-    { 0x000380e6, 0x00000002 },
-    { 0x040025c5, 0x00000002 },
-    { 0x000380e5, 0x00000002 },
-    { 0x000000a8, 0x0000001c },
-    { 0x000650aa, 0x00000018 },
-    { 0x040025bb, 0x00000002 },
-    { 0x000610ab, 0x00000018 },
-    { 0x040075bc, 0000000000 },
-    { 0x000075bb, 0x00000002 },
-    { 0x000075bc, 0000000000 },
-    { 0x00090000, 0x00000006 },
-    { 0x00090000, 0x00000002 },
-    { 0x000d8002, 0x00000006 },
-    { 0x00007832, 0x00000002 },
-    { 0x00005000, 0x00000002 },
-    { 0x000380e7, 0x00000002 },
-    { 0x04002c97, 0x00000002 },
-    { 0x00007820, 0x00000002 },
-    { 0x00007821, 0x00000002 },
-    { 0x00007800, 0000000000 },
-    { 0x01200000, 0x00000002 },
-    { 0x20077000, 0x00000002 },
-    { 0x01200000, 0x00000002 },
-    { 0x20007000, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x0120751b, 0x00000002 },
-    { 0x8040750a, 0x00000002 },
-    { 0x8040750b, 0x00000002 },
-    { 0x00110000, 0x00000002 },
-    { 0x000380e5, 0x00000002 },
-    { 0x000000c6, 0x0000001c },
-    { 0x000610ab, 0x00000018 },
-    { 0x844075bd, 0x00000002 },
-    { 0x000610aa, 0x00000018 },
-    { 0x840075bb, 0x00000002 },
-    { 0x000610ab, 0x00000018 },
-    { 0x844075bc, 0x00000002 },
-    { 0x000000c9, 0x00000004 },
-    { 0x804075bd, 0x00000002 },
-    { 0x800075bb, 0x00000002 },
-    { 0x804075bc, 0x00000002 },
-    { 0x00108000, 0x00000002 },
-    { 0x01400000, 0x00000002 },
-    { 0x006000cd, 0x0000000c },
-    { 0x20c07000, 0x00000020 },
-    { 0x000000cf, 0x00000012 },
-    { 0x00800000, 0x00000006 },
-    { 0x0080751d, 0x00000006 },
-    { 0000000000, 0000000000 },
-    { 0x0000775c, 0x00000002 },
-    { 0x00a05000, 0x00000002 },
-    { 0x00661000, 0x00000002 },
-    { 0x0460275d, 0x00000020 },
-    { 0x00004000, 0000000000 },
-    { 0x01e00830, 0x00000002 },
-    { 0x21007000, 0000000000 },
-    { 0x6464614d, 0000000000 },
-    { 0x69687420, 0000000000 },
-    { 0x00000073, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x00005000, 0x00000002 },
-    { 0x000380d0, 0x00000002 },
-    { 0x040025e0, 0x00000002 },
-    { 0x000075e1, 0000000000 },
-    { 0x00000001, 0000000000 },
-    { 0x000380e0, 0x00000002 },
-    { 0x04002394, 0x00000002 },
-    { 0x00005000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x00000008, 0000000000 },
-    { 0x00000004, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-};
-
-static const u32 R200_cp_microcode[][2] = {
-    { 0x21007000, 0000000000 },
-    { 0x20007000, 0000000000 },
-    { 0x000000bf, 0x00000004 },
-    { 0x000000c3, 0x00000004 },
-    { 0x7a685e5d, 0000000000 },
-    { 0x5d5d5588, 0000000000 },
-    { 0x68659197, 0000000000 },
-    { 0x5da19f78, 0000000000 },
-    { 0x5d5d5d5d, 0000000000 },
-    { 0x5dee5d50, 0000000000 },
-    { 0xf2acacac, 0000000000 },
-    { 0xe75df9e9, 0000000000 },
-    { 0xb1dd0e11, 0000000000 },
-    { 0xe2afafaf, 0000000000 },
-    { 0x000f0000, 0x00000016 },
-    { 0x452f232d, 0000000000 },
-    { 0x00000013, 0x00000004 },
-    { 0x000f0000, 0x00000016 },
-    { 0x452f272d, 0000000000 },
-    { 0x000f0001, 0x00000016 },
-    { 0x3e4d4a37, 0000000000 },
-    { 0x000077ef, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x00000020, 0x0000001a },
-    { 0x00004000, 0x0000001e },
-    { 0x00061000, 0x00000002 },
-    { 0x00000020, 0x0000001a },
-    { 0x00004000, 0x0000001e },
-    { 0x00061000, 0x00000002 },
-    { 0x00000020, 0x0000001a },
-    { 0x00004000, 0x0000001e },
-    { 0x00000016, 0x00000004 },
-    { 0x0003802a, 0x00000002 },
-    { 0x040067e0, 0x00000002 },
-    { 0x00000016, 0x00000004 },
-    { 0x000077e0, 0x00000002 },
-    { 0x00065000, 0x00000002 },
-    { 0x000037e1, 0x00000002 },
-    { 0x040067e1, 0x00000006 },
-    { 0x000077e0, 0x00000002 },
-    { 0x000077e1, 0x00000002 },
-    { 0x000077e1, 0x00000006 },
-    { 0xffffffff, 0000000000 },
-    { 0x10000000, 0000000000 },
-    { 0x07f007f0, 0000000000 },
-    { 0x0003802a, 0x00000002 },
-    { 0x040067e0, 0x00000006 },
-    { 0x0003802c, 0x00000002 },
-    { 0x04002741, 0x00000002 },
-    { 0x04002741, 0x00000002 },
-    { 0x04002743, 0x00000002 },
-    { 0x00007675, 0x00000002 },
-    { 0x00007676, 0x00000002 },
-    { 0x00007677, 0x00000002 },
-    { 0x00007678, 0x00000006 },
-    { 0x0003802c, 0x00000002 },
-    { 0x04002741, 0x00000002 },
-    { 0x04002741, 0x00000002 },
-    { 0x04002743, 0x00000002 },
-    { 0x00007676, 0x00000002 },
-    { 0x00007677, 0x00000002 },
-    { 0x00007678, 0x00000006 },
-    { 0x0003802b, 0x00000002 },
-    { 0x04002676, 0x00000002 },
-    { 0x00007677, 0x00000002 },
-    { 0x0003802c, 0x00000002 },
-    { 0x04002741, 0x00000002 },
-    { 0x04002743, 0x00000002 },
-    { 0x00007678, 0x00000006 },
-    { 0x0003802c, 0x00000002 },
-    { 0x04002741, 0x00000002 },
-    { 0x04002741, 0x00000002 },
-    { 0x04002743, 0x00000002 },
-    { 0x00007678, 0x00000006 },
-    { 0x0000002f, 0x00000018 },
-    { 0x0000002f, 0x00000018 },
-    { 0000000000, 0x00000006 },
-    { 0x00000037, 0x00000018 },
-    { 0x00000037, 0x00000018 },
-    { 0000000000, 0x00000006 },
-    { 0x01605000, 0x00000002 },
-    { 0x00065000, 0x00000002 },
-    { 0x00098000, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x64c06051, 0x00000004 },
-    { 0x00080000, 0x00000016 },
-    { 0000000000, 0000000000 },
-    { 0x0400251d, 0x00000002 },
-    { 0x00007580, 0x00000002 },
-    { 0x00067581, 0x00000002 },
-    { 0x04002580, 0x00000002 },
-    { 0x00067581, 0x00000002 },
-    { 0x0000005a, 0x00000004 },
-    { 0x00005000, 0000000000 },
-    { 0x00061000, 0x00000002 },
-    { 0x0000750e, 0x00000002 },
-    { 0x00019000, 0x00000002 },
-    { 0x00011064, 0x00000014 },
-    { 0x00000064, 0x00000012 },
-    { 0x0400250f, 0x00000002 },
-    { 0x0000505e, 0x00000004 },
-    { 0x00007565, 0x00000002 },
-    { 0x00007566, 0x00000002 },
-    { 0x00000065, 0x00000004 },
-    { 0x01e655b4, 0x00000002 },
-    { 0x4401b0f0, 0x00000002 },
-    { 0x01c110f0, 0x00000002 },
-    { 0x26667071, 0x00000018 },
-    { 0x040c2565, 0x00000002 },
-    { 0x00000071, 0x00000018 },
-    { 0x04002564, 0x00000002 },
-    { 0x00007566, 0x00000002 },
-    { 0x00000068, 0x00000004 },
-    { 0x00401074, 0x00000008 },
-    { 0x00101000, 0x00000002 },
-    { 0x000d80ff, 0x00000002 },
-    { 0x00800077, 0x00000008 },
-    { 0x000f9000, 0x00000002 },
-    { 0x000e00ff, 0x00000002 },
-    { 0000000000, 0x00000006 },
-    { 0x00000094, 0x00000018 },
-    { 0x00000068, 0x00000004 },
-    { 0x00007576, 0x00000002 },
-    { 0x00065000, 0x00000002 },
-    { 0x00009000, 0x00000002 },
-    { 0x00041000, 0x00000002 },
-    { 0x0c00350e, 0x00000002 },
-    { 0x00049000, 0x00000002 },
-    { 0x00051000, 0x00000002 },
-    { 0x01e785f8, 0x00000002 },
-    { 0x00200000, 0x00000002 },
-    { 0x00600087, 0x0000000c },
-    { 0x00007563, 0x00000002 },
-    { 0x006075f0, 0x00000021 },
-    { 0x2000707c, 0x00000004 },
-    { 0x0000507c, 0x00000004 },
-    { 0x00007576, 0x00000002 },
-    { 0x00007577, 0x00000002 },
-    { 0x0000750e, 0x00000002 },
-    { 0x0000750f, 0x00000002 },
-    { 0x00a05000, 0x00000002 },
-    { 0x0060008a, 0x0000000c },
-    { 0x006075f0, 0x00000021 },
-    { 0x000075f8, 0x00000002 },
-    { 0x0000008a, 0x00000004 },
-    { 0x000a750e, 0x00000002 },
-    { 0x0020750f, 0x00000002 },
-    { 0x0060008d, 0x00000004 },
-    { 0x00007570, 0x00000002 },
-    { 0x00007571, 0x00000002 },
-    { 0x00007572, 0x00000006 },
-    { 0x00005000, 0x00000002 },
-    { 0x00a05000, 0x00000002 },
-    { 0x00007568, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x00000098, 0x0000000c },
-    { 0x00058000, 0x00000002 },
-    { 0x0c607562, 0x00000002 },
-    { 0x0000009a, 0x00000004 },
-    { 0x00600099, 0x00000004 },
-    { 0x400070f1, 0000000000 },
-    { 0x000380f1, 0x00000002 },
-    { 0x000000a7, 0x0000001c },
-    { 0x000650a9, 0x00000018 },
-    { 0x040025bb, 0x00000002 },
-    { 0x000610aa, 0x00000018 },
-    { 0x040075bc, 0000000000 },
-    { 0x000075bb, 0x00000002 },
-    { 0x000075bc, 0000000000 },
-    { 0x00090000, 0x00000006 },
-    { 0x00090000, 0x00000002 },
-    { 0x000d8002, 0x00000006 },
-    { 0x00005000, 0x00000002 },
-    { 0x00007821, 0x00000002 },
-    { 0x00007800, 0000000000 },
-    { 0x00007821, 0x00000002 },
-    { 0x00007800, 0000000000 },
-    { 0x01665000, 0x00000002 },
-    { 0x000a0000, 0x00000002 },
-    { 0x000671cc, 0x00000002 },
-    { 0x0286f1cd, 0x00000002 },
-    { 0x000000b7, 0x00000010 },
-    { 0x21007000, 0000000000 },
-    { 0x000000be, 0x0000001c },
-    { 0x00065000, 0x00000002 },
-    { 0x000a0000, 0x00000002 },
-    { 0x00061000, 0x00000002 },
-    { 0x000b0000, 0x00000002 },
-    { 0x38067000, 0x00000002 },
-    { 0x000a00ba, 0x00000004 },
-    { 0x20007000, 0000000000 },
-    { 0x01200000, 0x00000002 },
-    { 0x20077000, 0x00000002 },
-    { 0x01200000, 0x00000002 },
-    { 0x20007000, 0000000000 },
-    { 0x00061000, 0x00000002 },
-    { 0x0120751b, 0x00000002 },
-    { 0x8040750a, 0x00000002 },
-    { 0x8040750b, 0x00000002 },
-    { 0x00110000, 0x00000002 },
-    { 0x000380f1, 0x00000002 },
-    { 0x000000d1, 0x0000001c },
-    { 0x000610aa, 0x00000018 },
-    { 0x844075bd, 0x00000002 },
-    { 0x000610a9, 0x00000018 },
-    { 0x840075bb, 0x00000002 },
-    { 0x000610aa, 0x00000018 },
-    { 0x844075bc, 0x00000002 },
-    { 0x000000d4, 0x00000004 },
-    { 0x804075bd, 0x00000002 },
-    { 0x800075bb, 0x00000002 },
-    { 0x804075bc, 0x00000002 },
-    { 0x00108000, 0x00000002 },
-    { 0x01400000, 0x00000002 },
-    { 0x006000d8, 0x0000000c },
-    { 0x20c07000, 0x00000020 },
-    { 0x000000da, 0x00000012 },
-    { 0x00800000, 0x00000006 },
-    { 0x0080751d, 0x00000006 },
-    { 0x000025bb, 0x00000002 },
-    { 0x000040d4, 0x00000004 },
-    { 0x0000775c, 0x00000002 },
-    { 0x00a05000, 0x00000002 },
-    { 0x00661000, 0x00000002 },
-    { 0x0460275d, 0x00000020 },
-    { 0x00004000, 0000000000 },
-    { 0x00007999, 0x00000002 },
-    { 0x00a05000, 0x00000002 },
-    { 0x00661000, 0x00000002 },
-    { 0x0460299b, 0x00000020 },
-    { 0x00004000, 0000000000 },
-    { 0x01e00830, 0x00000002 },
-    { 0x21007000, 0000000000 },
-    { 0x00005000, 0x00000002 },
-    { 0x00038056, 0x00000002 },
-    { 0x040025e0, 0x00000002 },
-    { 0x000075e1, 0000000000 },
-    { 0x00000001, 0000000000 },
-    { 0x000380ed, 0x00000002 },
-    { 0x04007394, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x000078c4, 0x00000002 },
-    { 0x000078c5, 0x00000002 },
-    { 0x000078c6, 0x00000002 },
-    { 0x00007924, 0x00000002 },
-    { 0x00007925, 0x00000002 },
-    { 0x00007926, 0x00000002 },
-    { 0x000000f2, 0x00000004 },
-    { 0x00007924, 0x00000002 },
-    { 0x00007925, 0x00000002 },
-    { 0x00007926, 0x00000002 },
-    { 0x000000f9, 0x00000004 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-};
-
-static const u32 R300_cp_microcode[][2] = {
-    { 0x4200e000, 0000000000 },
-    { 0x4000e000, 0000000000 },
-    { 0x000000ae, 0x00000008 },
-    { 0x000000b2, 0x00000008 },
-    { 0x67554b4a, 0000000000 },
-    { 0x4a4a4475, 0000000000 },
-    { 0x55527d83, 0000000000 },
-    { 0x4a8c8b65, 0000000000 },
-    { 0x4aef4af6, 0000000000 },
-    { 0x4ae14a4a, 0000000000 },
-    { 0xe4979797, 0000000000 },
-    { 0xdb4aebdd, 0000000000 },
-    { 0x9ccc4a4a, 0000000000 },
-    { 0xd1989898, 0000000000 },
-    { 0x4a0f9ad6, 0000000000 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000d0012, 0x00000038 },
-    { 0x0000e8b4, 0x00000004 },
-    { 0x000d0014, 0x00000038 },
-    { 0x0000e8b6, 0x00000004 },
-    { 0x000d0016, 0x00000038 },
-    { 0x0000e854, 0x00000004 },
-    { 0x000d0018, 0x00000038 },
-    { 0x0000e855, 0x00000004 },
-    { 0x000d001a, 0x00000038 },
-    { 0x0000e856, 0x00000004 },
-    { 0x000d001c, 0x00000038 },
-    { 0x0000e857, 0x00000004 },
-    { 0x000d001e, 0x00000038 },
-    { 0x0000e824, 0x00000004 },
-    { 0x000d0020, 0x00000038 },
-    { 0x0000e825, 0x00000004 },
-    { 0x000d0022, 0x00000038 },
-    { 0x0000e830, 0x00000004 },
-    { 0x000d0024, 0x00000038 },
-    { 0x0000f0c0, 0x00000004 },
-    { 0x000d0026, 0x00000038 },
-    { 0x0000f0c1, 0x00000004 },
-    { 0x000d0028, 0x00000038 },
-    { 0x0000f041, 0x00000004 },
-    { 0x000d002a, 0x00000038 },
-    { 0x0000f184, 0x00000004 },
-    { 0x000d002c, 0x00000038 },
-    { 0x0000f185, 0x00000004 },
-    { 0x000d002e, 0x00000038 },
-    { 0x0000f186, 0x00000004 },
-    { 0x000d0030, 0x00000038 },
-    { 0x0000f187, 0x00000004 },
-    { 0x000d0032, 0x00000038 },
-    { 0x0000f180, 0x00000004 },
-    { 0x000d0034, 0x00000038 },
-    { 0x0000f393, 0x00000004 },
-    { 0x000d0036, 0x00000038 },
-    { 0x0000f38a, 0x00000004 },
-    { 0x000d0038, 0x00000038 },
-    { 0x0000f38e, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000043, 0x00000018 },
-    { 0x00cce800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x0000003a, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x2000451d, 0x00000004 },
-    { 0x0000e580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x08004580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x00000047, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x00032000, 0x00000004 },
-    { 0x00022051, 0x00000028 },
-    { 0x00000051, 0x00000024 },
-    { 0x0800450f, 0x00000004 },
-    { 0x0000a04b, 0x00000008 },
-    { 0x0000e565, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000052, 0x00000008 },
-    { 0x03cca5b4, 0x00000004 },
-    { 0x05432000, 0x00000004 },
-    { 0x00022000, 0x00000004 },
-    { 0x4ccce05e, 0x00000030 },
-    { 0x08274565, 0x00000004 },
-    { 0x0000005e, 0x00000030 },
-    { 0x08004564, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000055, 0x00000008 },
-    { 0x00802061, 0x00000010 },
-    { 0x00202000, 0x00000004 },
-    { 0x001b00ff, 0x00000004 },
-    { 0x01000064, 0x00000010 },
-    { 0x001f2000, 0x00000004 },
-    { 0x001c00ff, 0x00000004 },
-    { 0000000000, 0x0000000c },
-    { 0x00000080, 0x00000030 },
-    { 0x00000055, 0x00000008 },
-    { 0x0000e576, 0x00000004 },
-    { 0x000ca000, 0x00000004 },
-    { 0x00012000, 0x00000004 },
-    { 0x00082000, 0x00000004 },
-    { 0x1800650e, 0x00000004 },
-    { 0x00092000, 0x00000004 },
-    { 0x000a2000, 0x00000004 },
-    { 0x000f0000, 0x00000004 },
-    { 0x00400000, 0x00000004 },
-    { 0x00000074, 0x00000018 },
-    { 0x0000e563, 0x00000004 },
-    { 0x00c0e5f9, 0x000000c2 },
-    { 0x00000069, 0x00000008 },
-    { 0x0000a069, 0x00000008 },
-    { 0x0000e576, 0x00000004 },
-    { 0x0000e577, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x0000e50f, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000077, 0x00000018 },
-    { 0x00c0e5f9, 0x000000c2 },
-    { 0x00000077, 0x00000008 },
-    { 0x0014e50e, 0x00000004 },
-    { 0x0040e50f, 0x00000004 },
-    { 0x00c0007a, 0x00000008 },
-    { 0x0000e570, 0x00000004 },
-    { 0x0000e571, 0x00000004 },
-    { 0x0000e572, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x0000e568, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00000084, 0x00000018 },
-    { 0x000b0000, 0x00000004 },
-    { 0x18c0e562, 0x00000004 },
-    { 0x00000086, 0x00000008 },
-    { 0x00c00085, 0x00000008 },
-    { 0x000700e3, 0x00000004 },
-    { 0x00000092, 0x00000038 },
-    { 0x000ca094, 0x00000030 },
-    { 0x080045bb, 0x00000004 },
-    { 0x000c2095, 0x00000030 },
-    { 0x0800e5bc, 0000000000 },
-    { 0x0000e5bb, 0x00000004 },
-    { 0x0000e5bc, 0000000000 },
-    { 0x00120000, 0x0000000c },
-    { 0x00120000, 0x00000004 },
-    { 0x001b0002, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e800, 0000000000 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e82e, 0000000000 },
-    { 0x02cca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000ce1cc, 0x00000004 },
-    { 0x050de1cd, 0x00000004 },
-    { 0x00400000, 0x00000004 },
-    { 0x000000a4, 0x00000018 },
-    { 0x00c0a000, 0x00000004 },
-    { 0x000000a1, 0x00000008 },
-    { 0x000000a6, 0x00000020 },
-    { 0x4200e000, 0000000000 },
-    { 0x000000ad, 0x00000038 },
-    { 0x000ca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00160000, 0x00000004 },
-    { 0x700ce000, 0x00000004 },
-    { 0x001400a9, 0x00000008 },
-    { 0x4000e000, 0000000000 },
-    { 0x02400000, 0x00000004 },
-    { 0x400ee000, 0x00000004 },
-    { 0x02400000, 0x00000004 },
-    { 0x4000e000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0240e51b, 0x00000004 },
-    { 0x0080e50a, 0x00000005 },
-    { 0x0080e50b, 0x00000005 },
-    { 0x00220000, 0x00000004 },
-    { 0x000700e3, 0x00000004 },
-    { 0x000000c0, 0x00000038 },
-    { 0x000c2095, 0x00000030 },
-    { 0x0880e5bd, 0x00000005 },
-    { 0x000c2094, 0x00000030 },
-    { 0x0800e5bb, 0x00000005 },
-    { 0x000c2095, 0x00000030 },
-    { 0x0880e5bc, 0x00000005 },
-    { 0x000000c3, 0x00000008 },
-    { 0x0080e5bd, 0x00000005 },
-    { 0x0000e5bb, 0x00000005 },
-    { 0x0080e5bc, 0x00000005 },
-    { 0x00210000, 0x00000004 },
-    { 0x02800000, 0x00000004 },
-    { 0x00c000c7, 0x00000018 },
-    { 0x4180e000, 0x00000040 },
-    { 0x000000c9, 0x00000024 },
-    { 0x01000000, 0x0000000c },
-    { 0x0100e51d, 0x0000000c },
-    { 0x000045bb, 0x00000004 },
-    { 0x000080c3, 0x00000008 },
-    { 0x0000f3ce, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053cf, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f3d2, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053d3, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f39d, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c0539e, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x03c00830, 0x00000004 },
-    { 0x4200e000, 0000000000 },
-    { 0x0000a000, 0x00000004 },
-    { 0x200045e0, 0x00000004 },
-    { 0x0000e5e1, 0000000000 },
-    { 0x00000001, 0000000000 },
-    { 0x000700e0, 0x00000004 },
-    { 0x0800e394, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x0000e8c4, 0x00000004 },
-    { 0x0000e8c5, 0x00000004 },
-    { 0x0000e8c6, 0x00000004 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000e4, 0x00000008 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000eb, 0x00000008 },
-    { 0x02c02000, 0x00000004 },
-    { 0x00060000, 0x00000004 },
-    { 0x000000f3, 0x00000034 },
-    { 0x000000f0, 0x00000008 },
-    { 0x00008000, 0x00000004 },
-    { 0xc000e000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x001d0018, 0x00000004 },
-    { 0x001a0001, 0x00000004 },
-    { 0x000000fb, 0x00000034 },
-    { 0x0000004a, 0x00000008 },
-    { 0x0500a04a, 0x00000008 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-};
-
-static const u32 R420_cp_microcode[][2] = {
-    { 0x4200e000, 0000000000 },
-    { 0x4000e000, 0000000000 },
-    { 0x00000099, 0x00000008 },
-    { 0x0000009d, 0x00000008 },
-    { 0x4a554b4a, 0000000000 },
-    { 0x4a4a4467, 0000000000 },
-    { 0x55526f75, 0000000000 },
-    { 0x4a7e7d65, 0000000000 },
-    { 0xd9d3dff6, 0000000000 },
-    { 0x4ac54a4a, 0000000000 },
-    { 0xc8828282, 0000000000 },
-    { 0xbf4acfc1, 0000000000 },
-    { 0x87b04a4a, 0000000000 },
-    { 0xb5838383, 0000000000 },
-    { 0x4a0f85ba, 0000000000 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000d0012, 0x00000038 },
-    { 0x0000e8b4, 0x00000004 },
-    { 0x000d0014, 0x00000038 },
-    { 0x0000e8b6, 0x00000004 },
-    { 0x000d0016, 0x00000038 },
-    { 0x0000e854, 0x00000004 },
-    { 0x000d0018, 0x00000038 },
-    { 0x0000e855, 0x00000004 },
-    { 0x000d001a, 0x00000038 },
-    { 0x0000e856, 0x00000004 },
-    { 0x000d001c, 0x00000038 },
-    { 0x0000e857, 0x00000004 },
-    { 0x000d001e, 0x00000038 },
-    { 0x0000e824, 0x00000004 },
-    { 0x000d0020, 0x00000038 },
-    { 0x0000e825, 0x00000004 },
-    { 0x000d0022, 0x00000038 },
-    { 0x0000e830, 0x00000004 },
-    { 0x000d0024, 0x00000038 },
-    { 0x0000f0c0, 0x00000004 },
-    { 0x000d0026, 0x00000038 },
-    { 0x0000f0c1, 0x00000004 },
-    { 0x000d0028, 0x00000038 },
-    { 0x0000f041, 0x00000004 },
-    { 0x000d002a, 0x00000038 },
-    { 0x0000f184, 0x00000004 },
-    { 0x000d002c, 0x00000038 },
-    { 0x0000f185, 0x00000004 },
-    { 0x000d002e, 0x00000038 },
-    { 0x0000f186, 0x00000004 },
-    { 0x000d0030, 0x00000038 },
-    { 0x0000f187, 0x00000004 },
-    { 0x000d0032, 0x00000038 },
-    { 0x0000f180, 0x00000004 },
-    { 0x000d0034, 0x00000038 },
-    { 0x0000f393, 0x00000004 },
-    { 0x000d0036, 0x00000038 },
-    { 0x0000f38a, 0x00000004 },
-    { 0x000d0038, 0x00000038 },
-    { 0x0000f38e, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000043, 0x00000018 },
-    { 0x00cce800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x0000003a, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x2000451d, 0x00000004 },
-    { 0x0000e580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x08004580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x00000047, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x00032000, 0x00000004 },
-    { 0x00022051, 0x00000028 },
-    { 0x00000051, 0x00000024 },
-    { 0x0800450f, 0x00000004 },
-    { 0x0000a04b, 0x00000008 },
-    { 0x0000e565, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000052, 0x00000008 },
-    { 0x03cca5b4, 0x00000004 },
-    { 0x05432000, 0x00000004 },
-    { 0x00022000, 0x00000004 },
-    { 0x4ccce05e, 0x00000030 },
-    { 0x08274565, 0x00000004 },
-    { 0x0000005e, 0x00000030 },
-    { 0x08004564, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000055, 0x00000008 },
-    { 0x00802061, 0x00000010 },
-    { 0x00202000, 0x00000004 },
-    { 0x001b00ff, 0x00000004 },
-    { 0x01000064, 0x00000010 },
-    { 0x001f2000, 0x00000004 },
-    { 0x001c00ff, 0x00000004 },
-    { 0000000000, 0x0000000c },
-    { 0x00000072, 0x00000030 },
-    { 0x00000055, 0x00000008 },
-    { 0x0000e576, 0x00000004 },
-    { 0x0000e577, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x0000e50f, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000069, 0x00000018 },
-    { 0x00c0e5f9, 0x000000c2 },
-    { 0x00000069, 0x00000008 },
-    { 0x0014e50e, 0x00000004 },
-    { 0x0040e50f, 0x00000004 },
-    { 0x00c0006c, 0x00000008 },
-    { 0x0000e570, 0x00000004 },
-    { 0x0000e571, 0x00000004 },
-    { 0x0000e572, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x0000e568, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00000076, 0x00000018 },
-    { 0x000b0000, 0x00000004 },
-    { 0x18c0e562, 0x00000004 },
-    { 0x00000078, 0x00000008 },
-    { 0x00c00077, 0x00000008 },
-    { 0x000700c7, 0x00000004 },
-    { 0x00000080, 0x00000038 },
-    { 0x0000e5bb, 0x00000004 },
-    { 0x0000e5bc, 0000000000 },
-    { 0x0000a000, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e800, 0000000000 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e82e, 0000000000 },
-    { 0x02cca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000ce1cc, 0x00000004 },
-    { 0x050de1cd, 0x00000004 },
-    { 0x00400000, 0x00000004 },
-    { 0x0000008f, 0x00000018 },
-    { 0x00c0a000, 0x00000004 },
-    { 0x0000008c, 0x00000008 },
-    { 0x00000091, 0x00000020 },
-    { 0x4200e000, 0000000000 },
-    { 0x00000098, 0x00000038 },
-    { 0x000ca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00160000, 0x00000004 },
-    { 0x700ce000, 0x00000004 },
-    { 0x00140094, 0x00000008 },
-    { 0x4000e000, 0000000000 },
-    { 0x02400000, 0x00000004 },
-    { 0x400ee000, 0x00000004 },
-    { 0x02400000, 0x00000004 },
-    { 0x4000e000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0240e51b, 0x00000004 },
-    { 0x0080e50a, 0x00000005 },
-    { 0x0080e50b, 0x00000005 },
-    { 0x00220000, 0x00000004 },
-    { 0x000700c7, 0x00000004 },
-    { 0x000000a4, 0x00000038 },
-    { 0x0080e5bd, 0x00000005 },
-    { 0x0000e5bb, 0x00000005 },
-    { 0x0080e5bc, 0x00000005 },
-    { 0x00210000, 0x00000004 },
-    { 0x02800000, 0x00000004 },
-    { 0x00c000ab, 0x00000018 },
-    { 0x4180e000, 0x00000040 },
-    { 0x000000ad, 0x00000024 },
-    { 0x01000000, 0x0000000c },
-    { 0x0100e51d, 0x0000000c },
-    { 0x000045bb, 0x00000004 },
-    { 0x000080a7, 0x00000008 },
-    { 0x0000f3ce, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053cf, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f3d2, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053d3, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f39d, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c0539e, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x03c00830, 0x00000004 },
-    { 0x4200e000, 0000000000 },
-    { 0x0000a000, 0x00000004 },
-    { 0x200045e0, 0x00000004 },
-    { 0x0000e5e1, 0000000000 },
-    { 0x00000001, 0000000000 },
-    { 0x000700c4, 0x00000004 },
-    { 0x0800e394, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x0000e8c4, 0x00000004 },
-    { 0x0000e8c5, 0x00000004 },
-    { 0x0000e8c6, 0x00000004 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000c8, 0x00000008 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000cf, 0x00000008 },
-    { 0x02c02000, 0x00000004 },
-    { 0x00060000, 0x00000004 },
-    { 0x000000d7, 0x00000034 },
-    { 0x000000d4, 0x00000008 },
-    { 0x00008000, 0x00000004 },
-    { 0xc000e000, 0000000000 },
-    { 0x0000e1cc, 0x00000004 },
-    { 0x0500e1cd, 0x00000004 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000000de, 0x00000034 },
-    { 0x000000da, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x0019e1cc, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x0500a000, 0x00000004 },
-    { 0x080041cd, 0x00000004 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000000fb, 0x00000034 },
-    { 0x0000004a, 0x00000008 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x001d0018, 0x00000004 },
-    { 0x001a0001, 0x00000004 },
-    { 0x000000fb, 0x00000034 },
-    { 0x0000004a, 0x00000008 },
-    { 0x0500a04a, 0x00000008 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-};
-
-static const u32 RS600_cp_microcode[][2] = {
-    { 0x4200e000, 0000000000 },
-    { 0x4000e000, 0000000000 },
-    { 0x000000a0, 0x00000008 },
-    { 0x000000a4, 0x00000008 },
-    { 0x4a554b4a, 0000000000 },
-    { 0x4a4a4467, 0000000000 },
-    { 0x55526f75, 0000000000 },
-    { 0x4a7e7d65, 0000000000 },
-    { 0x4ae74af6, 0000000000 },
-    { 0x4ad34a4a, 0000000000 },
-    { 0xd6898989, 0000000000 },
-    { 0xcd4addcf, 0000000000 },
-    { 0x8ebe4ae2, 0000000000 },
-    { 0xc38a8a8a, 0000000000 },
-    { 0x4a0f8cc8, 0000000000 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000d0012, 0x00000038 },
-    { 0x0000e8b4, 0x00000004 },
-    { 0x000d0014, 0x00000038 },
-    { 0x0000e8b6, 0x00000004 },
-    { 0x000d0016, 0x00000038 },
-    { 0x0000e854, 0x00000004 },
-    { 0x000d0018, 0x00000038 },
-    { 0x0000e855, 0x00000004 },
-    { 0x000d001a, 0x00000038 },
-    { 0x0000e856, 0x00000004 },
-    { 0x000d001c, 0x00000038 },
-    { 0x0000e857, 0x00000004 },
-    { 0x000d001e, 0x00000038 },
-    { 0x0000e824, 0x00000004 },
-    { 0x000d0020, 0x00000038 },
-    { 0x0000e825, 0x00000004 },
-    { 0x000d0022, 0x00000038 },
-    { 0x0000e830, 0x00000004 },
-    { 0x000d0024, 0x00000038 },
-    { 0x0000f0c0, 0x00000004 },
-    { 0x000d0026, 0x00000038 },
-    { 0x0000f0c1, 0x00000004 },
-    { 0x000d0028, 0x00000038 },
-    { 0x0000f041, 0x00000004 },
-    { 0x000d002a, 0x00000038 },
-    { 0x0000f184, 0x00000004 },
-    { 0x000d002c, 0x00000038 },
-    { 0x0000f185, 0x00000004 },
-    { 0x000d002e, 0x00000038 },
-    { 0x0000f186, 0x00000004 },
-    { 0x000d0030, 0x00000038 },
-    { 0x0000f187, 0x00000004 },
-    { 0x000d0032, 0x00000038 },
-    { 0x0000f180, 0x00000004 },
-    { 0x000d0034, 0x00000038 },
-    { 0x0000f393, 0x00000004 },
-    { 0x000d0036, 0x00000038 },
-    { 0x0000f38a, 0x00000004 },
-    { 0x000d0038, 0x00000038 },
-    { 0x0000f38e, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000043, 0x00000018 },
-    { 0x00cce800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x0000003a, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x2000451d, 0x00000004 },
-    { 0x0000e580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x08004580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x00000047, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x00032000, 0x00000004 },
-    { 0x00022051, 0x00000028 },
-    { 0x00000051, 0x00000024 },
-    { 0x0800450f, 0x00000004 },
-    { 0x0000a04b, 0x00000008 },
-    { 0x0000e565, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000052, 0x00000008 },
-    { 0x03cca5b4, 0x00000004 },
-    { 0x05432000, 0x00000004 },
-    { 0x00022000, 0x00000004 },
-    { 0x4ccce05e, 0x00000030 },
-    { 0x08274565, 0x00000004 },
-    { 0x0000005e, 0x00000030 },
-    { 0x08004564, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000055, 0x00000008 },
-    { 0x00802061, 0x00000010 },
-    { 0x00202000, 0x00000004 },
-    { 0x001b00ff, 0x00000004 },
-    { 0x01000064, 0x00000010 },
-    { 0x001f2000, 0x00000004 },
-    { 0x001c00ff, 0x00000004 },
-    { 0000000000, 0x0000000c },
-    { 0x00000072, 0x00000030 },
-    { 0x00000055, 0x00000008 },
-    { 0x0000e576, 0x00000004 },
-    { 0x0000e577, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x0000e50f, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000069, 0x00000018 },
-    { 0x00c0e5f9, 0x000000c2 },
-    { 0x00000069, 0x00000008 },
-    { 0x0014e50e, 0x00000004 },
-    { 0x0040e50f, 0x00000004 },
-    { 0x00c0006c, 0x00000008 },
-    { 0x0000e570, 0x00000004 },
-    { 0x0000e571, 0x00000004 },
-    { 0x0000e572, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x0000e568, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00000076, 0x00000018 },
-    { 0x000b0000, 0x00000004 },
-    { 0x18c0e562, 0x00000004 },
-    { 0x00000078, 0x00000008 },
-    { 0x00c00077, 0x00000008 },
-    { 0x000700d5, 0x00000004 },
-    { 0x00000084, 0x00000038 },
-    { 0x000ca086, 0x00000030 },
-    { 0x080045bb, 0x00000004 },
-    { 0x000c2087, 0x00000030 },
-    { 0x0800e5bc, 0000000000 },
-    { 0x0000e5bb, 0x00000004 },
-    { 0x0000e5bc, 0000000000 },
-    { 0x00120000, 0x0000000c },
-    { 0x00120000, 0x00000004 },
-    { 0x001b0002, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e800, 0000000000 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e82e, 0000000000 },
-    { 0x02cca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000ce1cc, 0x00000004 },
-    { 0x050de1cd, 0x00000004 },
-    { 0x00400000, 0x00000004 },
-    { 0x00000096, 0x00000018 },
-    { 0x00c0a000, 0x00000004 },
-    { 0x00000093, 0x00000008 },
-    { 0x00000098, 0x00000020 },
-    { 0x4200e000, 0000000000 },
-    { 0x0000009f, 0x00000038 },
-    { 0x000ca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00160000, 0x00000004 },
-    { 0x700ce000, 0x00000004 },
-    { 0x0014009b, 0x00000008 },
-    { 0x4000e000, 0000000000 },
-    { 0x02400000, 0x00000004 },
-    { 0x400ee000, 0x00000004 },
-    { 0x02400000, 0x00000004 },
-    { 0x4000e000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0240e51b, 0x00000004 },
-    { 0x0080e50a, 0x00000005 },
-    { 0x0080e50b, 0x00000005 },
-    { 0x00220000, 0x00000004 },
-    { 0x000700d5, 0x00000004 },
-    { 0x000000b2, 0x00000038 },
-    { 0x000c2087, 0x00000030 },
-    { 0x0880e5bd, 0x00000005 },
-    { 0x000c2086, 0x00000030 },
-    { 0x0800e5bb, 0x00000005 },
-    { 0x000c2087, 0x00000030 },
-    { 0x0880e5bc, 0x00000005 },
-    { 0x000000b5, 0x00000008 },
-    { 0x0080e5bd, 0x00000005 },
-    { 0x0000e5bb, 0x00000005 },
-    { 0x0080e5bc, 0x00000005 },
-    { 0x00210000, 0x00000004 },
-    { 0x02800000, 0x00000004 },
-    { 0x00c000b9, 0x00000018 },
-    { 0x4180e000, 0x00000040 },
-    { 0x000000bb, 0x00000024 },
-    { 0x01000000, 0x0000000c },
-    { 0x0100e51d, 0x0000000c },
-    { 0x000045bb, 0x00000004 },
-    { 0x000080b5, 0x00000008 },
-    { 0x0000f3ce, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053cf, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f3d2, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053d3, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f39d, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c0539e, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x03c00830, 0x00000004 },
-    { 0x4200e000, 0000000000 },
-    { 0x0000a000, 0x00000004 },
-    { 0x200045e0, 0x00000004 },
-    { 0x0000e5e1, 0000000000 },
-    { 0x00000001, 0000000000 },
-    { 0x000700d2, 0x00000004 },
-    { 0x0800e394, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x0000e8c4, 0x00000004 },
-    { 0x0000e8c5, 0x00000004 },
-    { 0x0000e8c6, 0x00000004 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000d6, 0x00000008 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000dd, 0x00000008 },
-    { 0x00e00116, 0000000000 },
-    { 0x000700e1, 0x00000004 },
-    { 0x0800401c, 0x00000004 },
-    { 0x200050e7, 0x00000004 },
-    { 0x0000e01d, 0x00000004 },
-    { 0x000000e4, 0x00000008 },
-    { 0x02c02000, 0x00000004 },
-    { 0x00060000, 0x00000004 },
-    { 0x000000eb, 0x00000034 },
-    { 0x000000e8, 0x00000008 },
-    { 0x00008000, 0x00000004 },
-    { 0xc000e000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x001d0018, 0x00000004 },
-    { 0x001a0001, 0x00000004 },
-    { 0x000000fb, 0x00000034 },
-    { 0x0000004a, 0x00000008 },
-    { 0x0500a04a, 0x00000008 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-};
-
-static const u32 RS690_cp_microcode[][2] = {
-    { 0x000000dd, 0x00000008 },
-    { 0x000000df, 0x00000008 },
-    { 0x000000a0, 0x00000008 },
-    { 0x000000a4, 0x00000008 },
-    { 0x4a554b4a, 0000000000 },
-    { 0x4a4a4467, 0000000000 },
-    { 0x55526f75, 0000000000 },
-    { 0x4a7e7d65, 0000000000 },
-    { 0x4ad74af6, 0000000000 },
-    { 0x4ac94a4a, 0000000000 },
-    { 0xcc898989, 0000000000 },
-    { 0xc34ad3c5, 0000000000 },
-    { 0x8e4a4a4a, 0000000000 },
-    { 0x4a8a8a8a, 0000000000 },
-    { 0x4a0f8c4a, 0000000000 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000d0012, 0x00000038 },
-    { 0x0000e8b4, 0x00000004 },
-    { 0x000d0014, 0x00000038 },
-    { 0x0000e8b6, 0x00000004 },
-    { 0x000d0016, 0x00000038 },
-    { 0x0000e854, 0x00000004 },
-    { 0x000d0018, 0x00000038 },
-    { 0x0000e855, 0x00000004 },
-    { 0x000d001a, 0x00000038 },
-    { 0x0000e856, 0x00000004 },
-    { 0x000d001c, 0x00000038 },
-    { 0x0000e857, 0x00000004 },
-    { 0x000d001e, 0x00000038 },
-    { 0x0000e824, 0x00000004 },
-    { 0x000d0020, 0x00000038 },
-    { 0x0000e825, 0x00000004 },
-    { 0x000d0022, 0x00000038 },
-    { 0x0000e830, 0x00000004 },
-    { 0x000d0024, 0x00000038 },
-    { 0x0000f0c0, 0x00000004 },
-    { 0x000d0026, 0x00000038 },
-    { 0x0000f0c1, 0x00000004 },
-    { 0x000d0028, 0x00000038 },
-    { 0x0000f041, 0x00000004 },
-    { 0x000d002a, 0x00000038 },
-    { 0x0000f184, 0x00000004 },
-    { 0x000d002c, 0x00000038 },
-    { 0x0000f185, 0x00000004 },
-    { 0x000d002e, 0x00000038 },
-    { 0x0000f186, 0x00000004 },
-    { 0x000d0030, 0x00000038 },
-    { 0x0000f187, 0x00000004 },
-    { 0x000d0032, 0x00000038 },
-    { 0x0000f180, 0x00000004 },
-    { 0x000d0034, 0x00000038 },
-    { 0x0000f393, 0x00000004 },
-    { 0x000d0036, 0x00000038 },
-    { 0x0000f38a, 0x00000004 },
-    { 0x000d0038, 0x00000038 },
-    { 0x0000f38e, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000043, 0x00000018 },
-    { 0x00cce800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x0000003a, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x2000451d, 0x00000004 },
-    { 0x0000e580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x08004580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x00000047, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x00032000, 0x00000004 },
-    { 0x00022051, 0x00000028 },
-    { 0x00000051, 0x00000024 },
-    { 0x0800450f, 0x00000004 },
-    { 0x0000a04b, 0x00000008 },
-    { 0x0000e565, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000052, 0x00000008 },
-    { 0x03cca5b4, 0x00000004 },
-    { 0x05432000, 0x00000004 },
-    { 0x00022000, 0x00000004 },
-    { 0x4ccce05e, 0x00000030 },
-    { 0x08274565, 0x00000004 },
-    { 0x0000005e, 0x00000030 },
-    { 0x08004564, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000055, 0x00000008 },
-    { 0x00802061, 0x00000010 },
-    { 0x00202000, 0x00000004 },
-    { 0x001b00ff, 0x00000004 },
-    { 0x01000064, 0x00000010 },
-    { 0x001f2000, 0x00000004 },
-    { 0x001c00ff, 0x00000004 },
-    { 0000000000, 0x0000000c },
-    { 0x00000072, 0x00000030 },
-    { 0x00000055, 0x00000008 },
-    { 0x0000e576, 0x00000004 },
-    { 0x0000e577, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x0000e50f, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000069, 0x00000018 },
-    { 0x00c0e5f9, 0x000000c2 },
-    { 0x00000069, 0x00000008 },
-    { 0x0014e50e, 0x00000004 },
-    { 0x0040e50f, 0x00000004 },
-    { 0x00c0006c, 0x00000008 },
-    { 0x0000e570, 0x00000004 },
-    { 0x0000e571, 0x00000004 },
-    { 0x0000e572, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x0000e568, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00000076, 0x00000018 },
-    { 0x000b0000, 0x00000004 },
-    { 0x18c0e562, 0x00000004 },
-    { 0x00000078, 0x00000008 },
-    { 0x00c00077, 0x00000008 },
-    { 0x000700cb, 0x00000004 },
-    { 0x00000084, 0x00000038 },
-    { 0x000ca086, 0x00000030 },
-    { 0x080045bb, 0x00000004 },
-    { 0x000c2087, 0x00000030 },
-    { 0x0800e5bc, 0000000000 },
-    { 0x0000e5bb, 0x00000004 },
-    { 0x0000e5bc, 0000000000 },
-    { 0x00120000, 0x0000000c },
-    { 0x00120000, 0x00000004 },
-    { 0x001b0002, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e800, 0000000000 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e82e, 0000000000 },
-    { 0x02cca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000ce1cc, 0x00000004 },
-    { 0x050de1cd, 0x00000004 },
-    { 0x00400000, 0x00000004 },
-    { 0x00000096, 0x00000018 },
-    { 0x00c0a000, 0x00000004 },
-    { 0x00000093, 0x00000008 },
-    { 0x00000098, 0x00000020 },
-    { 0x4200e000, 0000000000 },
-    { 0x0000009f, 0x00000038 },
-    { 0x000ca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00160000, 0x00000004 },
-    { 0x700ce000, 0x00000004 },
-    { 0x0014009b, 0x00000008 },
-    { 0x4000e000, 0000000000 },
-    { 0x02400000, 0x00000004 },
-    { 0x400ee000, 0x00000004 },
-    { 0x02400000, 0x00000004 },
-    { 0x4000e000, 0000000000 },
-    { 0x00100000, 0x0000002c },
-    { 0x00004000, 0000000000 },
-    { 0x080045c8, 0x00000004 },
-    { 0x00240005, 0x00000004 },
-    { 0x08004d0b, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0240e51b, 0x00000004 },
-    { 0x0080e50a, 0x00000005 },
-    { 0x0080e50b, 0x00000005 },
-    { 0x00220000, 0x00000004 },
-    { 0x000700cb, 0x00000004 },
-    { 0x000000b7, 0x00000038 },
-    { 0x000c2087, 0x00000030 },
-    { 0x0880e5bd, 0x00000005 },
-    { 0x000c2086, 0x00000030 },
-    { 0x0800e5bb, 0x00000005 },
-    { 0x000c2087, 0x00000030 },
-    { 0x0880e5bc, 0x00000005 },
-    { 0x000000ba, 0x00000008 },
-    { 0x0080e5bd, 0x00000005 },
-    { 0x0000e5bb, 0x00000005 },
-    { 0x0080e5bc, 0x00000005 },
-    { 0x00210000, 0x00000004 },
-    { 0x02800000, 0x00000004 },
-    { 0x00c000be, 0x00000018 },
-    { 0x4180e000, 0x00000040 },
-    { 0x000000c0, 0x00000024 },
-    { 0x01000000, 0x0000000c },
-    { 0x0100e51d, 0x0000000c },
-    { 0x000045bb, 0x00000004 },
-    { 0x000080ba, 0x00000008 },
-    { 0x03c00830, 0x00000004 },
-    { 0x4200e000, 0000000000 },
-    { 0x0000a000, 0x00000004 },
-    { 0x200045e0, 0x00000004 },
-    { 0x0000e5e1, 0000000000 },
-    { 0x00000001, 0000000000 },
-    { 0x000700c8, 0x00000004 },
-    { 0x0800e394, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x0000e8c4, 0x00000004 },
-    { 0x0000e8c5, 0x00000004 },
-    { 0x0000e8c6, 0x00000004 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000cc, 0x00000008 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000d3, 0x00000008 },
-    { 0x02c02000, 0x00000004 },
-    { 0x00060000, 0x00000004 },
-    { 0x000000db, 0x00000034 },
-    { 0x000000d8, 0x00000008 },
-    { 0x00008000, 0x00000004 },
-    { 0xc000e000, 0000000000 },
-    { 0x000000e1, 0x00000030 },
-    { 0x4200e000, 0000000000 },
-    { 0x000000e1, 0x00000030 },
-    { 0x4000e000, 0000000000 },
-    { 0x0025001b, 0x00000004 },
-    { 0x00230000, 0x00000004 },
-    { 0x00250005, 0x00000004 },
-    { 0x000000e6, 0x00000034 },
-    { 0000000000, 0x0000000c },
-    { 0x00244000, 0x00000004 },
-    { 0x080045c8, 0x00000004 },
-    { 0x00240005, 0x00000004 },
-    { 0x08004d0b, 0x0000000c },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x001d0018, 0x00000004 },
-    { 0x001a0001, 0x00000004 },
-    { 0x000000fb, 0x00000034 },
-    { 0x0000004a, 0x00000008 },
-    { 0x0500a04a, 0x00000008 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-};
-
-static const u32 R520_cp_microcode[][2] = {
-    { 0x4200e000, 0000000000 },
-    { 0x4000e000, 0000000000 },
-    { 0x00000099, 0x00000008 },
-    { 0x0000009d, 0x00000008 },
-    { 0x4a554b4a, 0000000000 },
-    { 0x4a4a4467, 0000000000 },
-    { 0x55526f75, 0000000000 },
-    { 0x4a7e7d65, 0000000000 },
-    { 0xe0dae6f6, 0000000000 },
-    { 0x4ac54a4a, 0000000000 },
-    { 0xc8828282, 0000000000 },
-    { 0xbf4acfc1, 0000000000 },
-    { 0x87b04ad5, 0000000000 },
-    { 0xb5838383, 0000000000 },
-    { 0x4a0f85ba, 0000000000 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000d0012, 0x00000038 },
-    { 0x0000e8b4, 0x00000004 },
-    { 0x000d0014, 0x00000038 },
-    { 0x0000e8b6, 0x00000004 },
-    { 0x000d0016, 0x00000038 },
-    { 0x0000e854, 0x00000004 },
-    { 0x000d0018, 0x00000038 },
-    { 0x0000e855, 0x00000004 },
-    { 0x000d001a, 0x00000038 },
-    { 0x0000e856, 0x00000004 },
-    { 0x000d001c, 0x00000038 },
-    { 0x0000e857, 0x00000004 },
-    { 0x000d001e, 0x00000038 },
-    { 0x0000e824, 0x00000004 },
-    { 0x000d0020, 0x00000038 },
-    { 0x0000e825, 0x00000004 },
-    { 0x000d0022, 0x00000038 },
-    { 0x0000e830, 0x00000004 },
-    { 0x000d0024, 0x00000038 },
-    { 0x0000f0c0, 0x00000004 },
-    { 0x000d0026, 0x00000038 },
-    { 0x0000f0c1, 0x00000004 },
-    { 0x000d0028, 0x00000038 },
-    { 0x0000e000, 0x00000004 },
-    { 0x000d002a, 0x00000038 },
-    { 0x0000e000, 0x00000004 },
-    { 0x000d002c, 0x00000038 },
-    { 0x0000e000, 0x00000004 },
-    { 0x000d002e, 0x00000038 },
-    { 0x0000e000, 0x00000004 },
-    { 0x000d0030, 0x00000038 },
-    { 0x0000e000, 0x00000004 },
-    { 0x000d0032, 0x00000038 },
-    { 0x0000f180, 0x00000004 },
-    { 0x000d0034, 0x00000038 },
-    { 0x0000f393, 0x00000004 },
-    { 0x000d0036, 0x00000038 },
-    { 0x0000f38a, 0x00000004 },
-    { 0x000d0038, 0x00000038 },
-    { 0x0000f38e, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000043, 0x00000018 },
-    { 0x00cce800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x08004800, 0x00000004 },
-    { 0x0000003a, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x2000451d, 0x00000004 },
-    { 0x0000e580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x08004580, 0x00000004 },
-    { 0x000ce581, 0x00000004 },
-    { 0x00000047, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x00032000, 0x00000004 },
-    { 0x00022051, 0x00000028 },
-    { 0x00000051, 0x00000024 },
-    { 0x0800450f, 0x00000004 },
-    { 0x0000a04b, 0x00000008 },
-    { 0x0000e565, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000052, 0x00000008 },
-    { 0x03cca5b4, 0x00000004 },
-    { 0x05432000, 0x00000004 },
-    { 0x00022000, 0x00000004 },
-    { 0x4ccce05e, 0x00000030 },
-    { 0x08274565, 0x00000004 },
-    { 0x0000005e, 0x00000030 },
-    { 0x08004564, 0x00000004 },
-    { 0x0000e566, 0x00000004 },
-    { 0x00000055, 0x00000008 },
-    { 0x00802061, 0x00000010 },
-    { 0x00202000, 0x00000004 },
-    { 0x001b00ff, 0x00000004 },
-    { 0x01000064, 0x00000010 },
-    { 0x001f2000, 0x00000004 },
-    { 0x001c00ff, 0x00000004 },
-    { 0000000000, 0x0000000c },
-    { 0x00000072, 0x00000030 },
-    { 0x00000055, 0x00000008 },
-    { 0x0000e576, 0x00000004 },
-    { 0x0000e577, 0x00000004 },
-    { 0x0000e50e, 0x00000004 },
-    { 0x0000e50f, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00000069, 0x00000018 },
-    { 0x00c0e5f9, 0x000000c2 },
-    { 0x00000069, 0x00000008 },
-    { 0x0014e50e, 0x00000004 },
-    { 0x0040e50f, 0x00000004 },
-    { 0x00c0006c, 0x00000008 },
-    { 0x0000e570, 0x00000004 },
-    { 0x0000e571, 0x00000004 },
-    { 0x0000e572, 0x0000000c },
-    { 0x0000a000, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x0000e568, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00000076, 0x00000018 },
-    { 0x000b0000, 0x00000004 },
-    { 0x18c0e562, 0x00000004 },
-    { 0x00000078, 0x00000008 },
-    { 0x00c00077, 0x00000008 },
-    { 0x000700c7, 0x00000004 },
-    { 0x00000080, 0x00000038 },
-    { 0x0000e5bb, 0x00000004 },
-    { 0x0000e5bc, 0000000000 },
-    { 0x0000a000, 0x00000004 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e800, 0000000000 },
-    { 0x0000e821, 0x00000004 },
-    { 0x0000e82e, 0000000000 },
-    { 0x02cca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000ce1cc, 0x00000004 },
-    { 0x050de1cd, 0x00000004 },
-    { 0x00400000, 0x00000004 },
-    { 0x0000008f, 0x00000018 },
-    { 0x00c0a000, 0x00000004 },
-    { 0x0000008c, 0x00000008 },
-    { 0x00000091, 0x00000020 },
-    { 0x4200e000, 0000000000 },
-    { 0x00000098, 0x00000038 },
-    { 0x000ca000, 0x00000004 },
-    { 0x00140000, 0x00000004 },
-    { 0x000c2000, 0x00000004 },
-    { 0x00160000, 0x00000004 },
-    { 0x700ce000, 0x00000004 },
-    { 0x00140094, 0x00000008 },
-    { 0x4000e000, 0000000000 },
-    { 0x02400000, 0x00000004 },
-    { 0x400ee000, 0x00000004 },
-    { 0x02400000, 0x00000004 },
-    { 0x4000e000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x0240e51b, 0x00000004 },
-    { 0x0080e50a, 0x00000005 },
-    { 0x0080e50b, 0x00000005 },
-    { 0x00220000, 0x00000004 },
-    { 0x000700c7, 0x00000004 },
-    { 0x000000a4, 0x00000038 },
-    { 0x0080e5bd, 0x00000005 },
-    { 0x0000e5bb, 0x00000005 },
-    { 0x0080e5bc, 0x00000005 },
-    { 0x00210000, 0x00000004 },
-    { 0x02800000, 0x00000004 },
-    { 0x00c000ab, 0x00000018 },
-    { 0x4180e000, 0x00000040 },
-    { 0x000000ad, 0x00000024 },
-    { 0x01000000, 0x0000000c },
-    { 0x0100e51d, 0x0000000c },
-    { 0x000045bb, 0x00000004 },
-    { 0x000080a7, 0x00000008 },
-    { 0x0000f3ce, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053cf, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f3d2, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c053d3, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x0000f39d, 0x00000004 },
-    { 0x0140a000, 0x00000004 },
-    { 0x00cc2000, 0x00000004 },
-    { 0x08c0539e, 0x00000040 },
-    { 0x00008000, 0000000000 },
-    { 0x03c00830, 0x00000004 },
-    { 0x4200e000, 0000000000 },
-    { 0x0000a000, 0x00000004 },
-    { 0x200045e0, 0x00000004 },
-    { 0x0000e5e1, 0000000000 },
-    { 0x00000001, 0000000000 },
-    { 0x000700c4, 0x00000004 },
-    { 0x0800e394, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x0000e8c4, 0x00000004 },
-    { 0x0000e8c5, 0x00000004 },
-    { 0x0000e8c6, 0x00000004 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000c8, 0x00000008 },
-    { 0x0000e928, 0x00000004 },
-    { 0x0000e929, 0x00000004 },
-    { 0x0000e92a, 0x00000004 },
-    { 0x000000cf, 0x00000008 },
-    { 0xdeadbeef, 0000000000 },
-    { 0x00000116, 0000000000 },
-    { 0x000700d3, 0x00000004 },
-    { 0x080050e7, 0x00000004 },
-    { 0x000700d4, 0x00000004 },
-    { 0x0800401c, 0x00000004 },
-    { 0x0000e01d, 0000000000 },
-    { 0x02c02000, 0x00000004 },
-    { 0x00060000, 0x00000004 },
-    { 0x000000de, 0x00000034 },
-    { 0x000000db, 0x00000008 },
-    { 0x00008000, 0x00000004 },
-    { 0xc000e000, 0000000000 },
-    { 0x0000e1cc, 0x00000004 },
-    { 0x0500e1cd, 0x00000004 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000000e5, 0x00000034 },
-    { 0x000000e1, 0x00000008 },
-    { 0x0000a000, 0000000000 },
-    { 0x0019e1cc, 0x00000004 },
-    { 0x001b0001, 0x00000004 },
-    { 0x0500a000, 0x00000004 },
-    { 0x080041cd, 0x00000004 },
-    { 0x000ca000, 0x00000004 },
-    { 0x000000fb, 0x00000034 },
-    { 0x0000004a, 0x00000008 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0x000c2000, 0x00000004 },
-    { 0x001d0018, 0x00000004 },
-    { 0x001a0001, 0x00000004 },
-    { 0x000000fb, 0x00000034 },
-    { 0x0000004a, 0x00000008 },
-    { 0x0500a04a, 0x00000008 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-    { 0000000000, 0000000000 },
-};
-
-
-#endif
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 3b09a1f..570a587 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -175,6 +175,15 @@ struct radeon_mode_info {
 	enum radeon_connector_table connector_table;
 	bool mode_config_initialized;
 	struct radeon_crtc *crtcs[2];
+	/* DVI-I properties */
+	struct drm_property *coherent_mode_property;
+	/* DAC enable load detect */
+	struct drm_property *load_detect_property;
+	/* TV standard load detect */
+	struct drm_property *tv_std_property;
+	/* legacy TMDS PLL detect */
+	struct drm_property *tmds_pll_property;
+
 };
 
 struct radeon_native_mode {
@@ -188,6 +197,21 @@ struct radeon_native_mode {
 	uint32_t flags;
 };
 
+#define MAX_H_CODE_TIMING_LEN 32
+#define MAX_V_CODE_TIMING_LEN 32
+
+/* need to store these as reading
+   back code tables is excessive */
+struct radeon_tv_regs {
+	uint32_t tv_uv_adr;
+	uint32_t timing_cntl;
+	uint32_t hrestart;
+	uint32_t vrestart;
+	uint32_t frestart;
+	uint16_t h_code_timing[MAX_H_CODE_TIMING_LEN];
+	uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN];
+};
+
 struct radeon_crtc {
 	struct drm_crtc base;
 	int crtc_id;
@@ -195,8 +219,6 @@ struct radeon_crtc {
 	bool enabled;
 	bool can_tile;
 	uint32_t crtc_offset;
-	struct radeon_framebuffer *fbdev_fb;
-	struct drm_mode_set mode_set;
 	struct drm_gem_object *cursor_bo;
 	uint64_t cursor_addr;
 	int cursor_width;
@@ -204,7 +226,6 @@ struct radeon_crtc {
 	uint32_t legacy_display_base_addr;
 	uint32_t legacy_cursor_offset;
 	enum radeon_rmx_type rmx_type;
-	uint32_t devices;
 	fixed20_12 vsc;
 	fixed20_12 hsc;
 	struct radeon_native_mode native_mode;
@@ -236,7 +257,13 @@ struct radeon_encoder_tv_dac {
 	uint32_t ntsc_tvdac_adj;
 	uint32_t pal_tvdac_adj;
 
+	int               h_pos;
+	int               v_pos;
+	int               h_size;
+	int               supported_tv_stds;
+	bool              tv_on;
 	enum radeon_tv_std tv_std;
+	struct radeon_tv_regs tv;
 };
 
 struct radeon_encoder_int_tmds {
@@ -255,10 +282,15 @@ struct radeon_encoder_atom_dig {
 	struct radeon_native_mode native_mode;
 };
 
+struct radeon_encoder_atom_dac {
+	enum radeon_tv_std tv_std;
+};
+
 struct radeon_encoder {
 	struct drm_encoder base;
 	uint32_t encoder_id;
 	uint32_t devices;
+	uint32_t active_device;
 	uint32_t flags;
 	uint32_t pixel_clock;
 	enum radeon_rmx_type rmx_type;
@@ -276,8 +308,12 @@ struct radeon_connector {
 	uint32_t connector_id;
 	uint32_t devices;
 	struct radeon_i2c_chan *ddc_bus;
-	int use_digital;
+	bool use_digital;
+	/* we need to mind the EDID between detect
+	   and get modes due to analog/digital/tvencoder */
+	struct edid *edid;
 	void *con_priv;
+	bool dac_load_detect;
 };
 
 struct radeon_framebuffer {
@@ -310,6 +346,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, i
 struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index);
 extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action);
 extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
+extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
 extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
@@ -337,16 +374,18 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev);
 extern bool radeon_combios_get_clock_info(struct drm_device *dev);
 extern struct radeon_encoder_atom_dig *
 radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
-extern struct radeon_encoder_int_tmds *
-radeon_atombios_get_tmds_info(struct radeon_encoder *encoder);
+bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
+				   struct radeon_encoder_int_tmds *tmds);
+bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
+					   struct radeon_encoder_int_tmds *tmds);
+bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
+					    struct radeon_encoder_int_tmds *tmds);
 extern struct radeon_encoder_primary_dac *
 radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_tv_dac *
 radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_lvds *
 radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
-extern struct radeon_encoder_int_tmds *
-radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
 extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder);
 extern struct radeon_encoder_tv_dac *
 radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
@@ -356,6 +395,8 @@ extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock);
 extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev);
 extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock);
 extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev);
+extern void radeon_save_bios_scratch_regs(struct radeon_device *rdev);
+extern void radeon_restore_bios_scratch_regs(struct radeon_device *rdev);
 extern void
 radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc);
 extern void
@@ -396,6 +437,19 @@ extern int radeon_static_clocks_init(struct drm_device *dev);
 bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
 					struct drm_display_mode *mode,
 					struct drm_display_mode *adjusted_mode);
-void atom_rv515_force_tv_scaler(struct radeon_device *rdev);
-
+void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc);
+
+/* legacy tv */
+void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder,
+				      uint32_t *h_total_disp, uint32_t *h_sync_strt_wid,
+				      uint32_t *v_total_disp, uint32_t *v_sync_strt_wid);
+void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder,
+				  uint32_t *htotal_cntl, uint32_t *ppll_ref_div,
+				  uint32_t *ppll_div_3, uint32_t *pixclks_cntl);
+void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder,
+				  uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div,
+				  uint32_t *p2pll_div_0, uint32_t *pixclks_cntl);
+void radeon_legacy_tv_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode);
 #endif
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index b85fb83..73af463 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -188,6 +188,7 @@ int radeon_object_kmap(struct radeon_object *robj, void **ptr)
 	if (ptr) {
 		*ptr = robj->kptr;
 	}
+	radeon_object_check_tiling(robj, 0, 0);
 	return 0;
 }
 
@@ -200,6 +201,7 @@ void radeon_object_kunmap(struct radeon_object *robj)
 	}
 	robj->kptr = NULL;
 	spin_unlock(&robj->tobj.lock);
+	radeon_object_check_tiling(robj, 0, 0);
 	ttm_bo_kunmap(&robj->kmap);
 }
 
@@ -369,6 +371,14 @@ void radeon_object_force_delete(struct radeon_device *rdev)
 
 int radeon_object_init(struct radeon_device *rdev)
 {
+	/* Add an MTRR for the VRAM */
+	rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size,
+			MTRR_TYPE_WRCOMB, 1);
+	DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n",
+		rdev->mc.mc_vram_size >> 20,
+		(unsigned long long)rdev->mc.aper_size >> 20);
+	DRM_INFO("RAM width %dbits %cDR\n",
+			rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S');
 	return radeon_ttm_init(rdev);
 }
 
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index 473e477..10e8af6 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -37,6 +37,7 @@
  * TTM.
  */
 struct radeon_mman {
+	struct ttm_bo_global_ref        bo_global_ref;
 	struct ttm_global_reference	mem_global_ref;
 	bool				mem_global_referenced;
 	struct ttm_bo_device		bdev;
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
index 4df43f6..21da871 100644
--- a/drivers/gpu/drm/radeon/radeon_reg.h
+++ b/drivers/gpu/drm/radeon/radeon_reg.h
@@ -1945,6 +1945,11 @@
 #       define RADEON_TXFORMAT_DXT1               (12 <<  0)
 #       define RADEON_TXFORMAT_DXT23              (14 <<  0)
 #       define RADEON_TXFORMAT_DXT45              (15 <<  0)
+#	define RADEON_TXFORMAT_SHADOW16           (16 <<  0)
+#	define RADEON_TXFORMAT_SHADOW32           (17 <<  0)
+#       define RADEON_TXFORMAT_DUDV88             (18 <<  0)
+#       define RADEON_TXFORMAT_LDUDV655           (19 <<  0)
+#       define RADEON_TXFORMAT_LDUDUV8888         (20 <<  0)
 #       define RADEON_TXFORMAT_FORMAT_MASK        (31 <<  0)
 #       define RADEON_TXFORMAT_FORMAT_SHIFT       0
 #       define RADEON_TXFORMAT_APPLE_YUV_MODE     (1  <<  5)
@@ -2203,7 +2208,7 @@
 #       define RADEON_ROP_ENABLE               (1  <<  6)
 #       define RADEON_STENCIL_ENABLE           (1  <<  7)
 #       define RADEON_Z_ENABLE                 (1  <<  8)
-#       define RADEON_DEPTH_XZ_OFFEST_ENABLE   (1  <<  9)
+#       define RADEON_DEPTHXY_OFFSET_ENABLE    (1  <<  9)
 #       define RADEON_RB3D_COLOR_FORMAT_SHIFT  10
 
 #       define RADEON_COLOR_FORMAT_ARGB1555    3
@@ -2773,7 +2778,12 @@
 #       define R200_TXFORMAT_DXT1		(12 << 0)
 #       define R200_TXFORMAT_DXT23		(14 << 0)
 #       define R200_TXFORMAT_DXT45		(15 << 0)
+#       define R200_TXFORMAT_DVDU88		(18 << 0)
+#       define R200_TXFORMAT_LDVDU655		(19 << 0)
+#       define R200_TXFORMAT_LDVDU8888		(20 << 0)
+#       define R200_TXFORMAT_GR1616		(21 << 0)
 #       define R200_TXFORMAT_ABGR8888		(22 << 0)
+#       define R200_TXFORMAT_BGR111110		(23 << 0)
 #       define R200_TXFORMAT_FORMAT_MASK	(31 <<	0)
 #       define R200_TXFORMAT_FORMAT_SHIFT	0
 #       define R200_TXFORMAT_ALPHA_IN_MAP	(1 << 6)
@@ -2818,6 +2828,13 @@
 #define R200_PP_TXPITCH_4			0x2c90 /* NPOT only */
 #define R200_PP_TXPITCH_5			0x2cb0 /* NPOT only */
 
+#define R200_PP_CUBIC_FACES_0			0x2c18
+#define R200_PP_CUBIC_FACES_1			0x2c38
+#define R200_PP_CUBIC_FACES_2			0x2c58
+#define R200_PP_CUBIC_FACES_3			0x2c78
+#define R200_PP_CUBIC_FACES_4			0x2c98
+#define R200_PP_CUBIC_FACES_5			0x2cb8
+
 #define R200_PP_TXOFFSET_0			0x2d00
 #       define R200_TXO_ENDIAN_NO_SWAP		(0 << 0)
 #       define R200_TXO_ENDIAN_BYTE_SWAP	(1 << 0)
@@ -2829,11 +2846,44 @@
 #       define R200_TXO_MICRO_TILE		(1 << 3)
 #       define R200_TXO_OFFSET_MASK		0xffffffe0
 #       define R200_TXO_OFFSET_SHIFT		5
+#define R200_PP_CUBIC_OFFSET_F1_0         0x2d04
+#define R200_PP_CUBIC_OFFSET_F2_0         0x2d08
+#define R200_PP_CUBIC_OFFSET_F3_0         0x2d0c
+#define R200_PP_CUBIC_OFFSET_F4_0         0x2d10
+#define R200_PP_CUBIC_OFFSET_F5_0         0x2d14
+
 #define R200_PP_TXOFFSET_1			0x2d18
+#define R200_PP_CUBIC_OFFSET_F1_1         0x2d1c
+#define R200_PP_CUBIC_OFFSET_F2_1         0x2d20
+#define R200_PP_CUBIC_OFFSET_F3_1         0x2d24
+#define R200_PP_CUBIC_OFFSET_F4_1         0x2d28
+#define R200_PP_CUBIC_OFFSET_F5_1         0x2d2c
+
 #define R200_PP_TXOFFSET_2			0x2d30
+#define R200_PP_CUBIC_OFFSET_F1_2         0x2d34
+#define R200_PP_CUBIC_OFFSET_F2_2         0x2d38
+#define R200_PP_CUBIC_OFFSET_F3_2         0x2d3c
+#define R200_PP_CUBIC_OFFSET_F4_2         0x2d40
+#define R200_PP_CUBIC_OFFSET_F5_2         0x2d44
+
 #define R200_PP_TXOFFSET_3			0x2d48
+#define R200_PP_CUBIC_OFFSET_F1_3         0x2d4c
+#define R200_PP_CUBIC_OFFSET_F2_3         0x2d50
+#define R200_PP_CUBIC_OFFSET_F3_3         0x2d54
+#define R200_PP_CUBIC_OFFSET_F4_3         0x2d58
+#define R200_PP_CUBIC_OFFSET_F5_3         0x2d5c
 #define R200_PP_TXOFFSET_4			0x2d60
+#define R200_PP_CUBIC_OFFSET_F1_4         0x2d64
+#define R200_PP_CUBIC_OFFSET_F2_4         0x2d68
+#define R200_PP_CUBIC_OFFSET_F3_4         0x2d6c
+#define R200_PP_CUBIC_OFFSET_F4_4         0x2d70
+#define R200_PP_CUBIC_OFFSET_F5_4         0x2d74
 #define R200_PP_TXOFFSET_5			0x2d78
+#define R200_PP_CUBIC_OFFSET_F1_5         0x2d7c
+#define R200_PP_CUBIC_OFFSET_F2_5         0x2d80
+#define R200_PP_CUBIC_OFFSET_F3_5         0x2d84
+#define R200_PP_CUBIC_OFFSET_F4_5         0x2d88
+#define R200_PP_CUBIC_OFFSET_F5_5         0x2d8c
 
 #define R200_PP_TFACTOR_0			0x2ee0
 #define R200_PP_TFACTOR_1			0x2ee4
@@ -3175,6 +3225,11 @@
 #       define R200_FORCE_INORDER_PROC		(1<<31)
 #define R200_PP_CNTL_X				0x2cc4
 #define R200_PP_TXMULTI_CTL_0			0x2c1c
+#define R200_PP_TXMULTI_CTL_1			0x2c3c
+#define R200_PP_TXMULTI_CTL_2			0x2c5c
+#define R200_PP_TXMULTI_CTL_3			0x2c7c
+#define R200_PP_TXMULTI_CTL_4			0x2c9c
+#define R200_PP_TXMULTI_CTL_5			0x2cbc
 #define R200_SE_VTX_STATE_CNTL			0x2180
 #       define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16)
 
@@ -3200,6 +3255,24 @@
 #define RADEON_CP_RB_WPTR                   0x0714
 #define RADEON_CP_RB_RPTR_WR                0x071c
 
+#define RADEON_SCRATCH_UMSK		    0x0770
+#define RADEON_SCRATCH_ADDR		    0x0774
+
+#define R600_CP_RB_BASE                     0xc100
+#define R600_CP_RB_CNTL                     0xc104
+#       define R600_RB_BUFSZ(x)             ((x) << 0)
+#       define R600_RB_BLKSZ(x)             ((x) << 8)
+#       define R600_RB_NO_UPDATE            (1 << 27)
+#       define R600_RB_RPTR_WR_ENA          (1 << 31)
+#define R600_CP_RB_RPTR_WR                  0xc108
+#define R600_CP_RB_RPTR_ADDR                0xc10c
+#define R600_CP_RB_RPTR_ADDR_HI             0xc110
+#define R600_CP_RB_WPTR                     0xc114
+#define R600_CP_RB_WPTR_ADDR                0xc118
+#define R600_CP_RB_WPTR_ADDR_HI             0xc11c
+#define R600_CP_RB_RPTR                     0x8700
+#define R600_CP_RB_WPTR_DELAY               0x8704
+
 #define RADEON_CP_IB_BASE                   0x0738
 #define RADEON_CP_IB_BUFSZ                  0x073c
 
@@ -3407,7 +3480,9 @@
 #       define RADEON_RGB_CONVERT_BY_PASS	  (1 << 10)
 #       define RADEON_UVRAM_READ_MARGIN_SHIFT	  16
 #       define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT	  20
-#	define RADEON_TVOUT_SCALE_EN		  (1 << 26)
+#       define RADEON_RGB_ATTEN_SEL(x)            ((x) << 24)
+#       define RADEON_TVOUT_SCALE_EN              (1 << 26)
+#       define RADEON_RGB_ATTEN_VAL(x)            ((x) << 28)
 #define RADEON_TV_SYNC_CNTL                          0x0808
 #       define RADEON_SYNC_OE                     (1 <<  0)
 #       define RADEON_SYNC_OUT                    (1 <<  1)
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 60d1593..747b4bf 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -56,10 +56,12 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
 		set_bit(i, rdev->ib_pool.alloc_bm);
 		rdev->ib_pool.ibs[i].length_dw = 0;
 		*ib = &rdev->ib_pool.ibs[i];
+		mutex_unlock(&rdev->ib_pool.mutex);
 		goto out;
 	}
 	if (list_empty(&rdev->ib_pool.scheduled_ibs)) {
 		/* we go do nothings here */
+		mutex_unlock(&rdev->ib_pool.mutex);
 		DRM_ERROR("all IB allocated none scheduled.\n");
 		r = -EINVAL;
 		goto out;
@@ -69,10 +71,13 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
 			 struct radeon_ib, list);
 	if (nib->fence == NULL) {
 		/* we go do nothings here */
+		mutex_unlock(&rdev->ib_pool.mutex);
 		DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx);
 		r = -EINVAL;
 		goto out;
 	}
+	mutex_unlock(&rdev->ib_pool.mutex);
+
 	r = radeon_fence_wait(nib->fence, false);
 	if (r) {
 		DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx,
@@ -81,12 +86,17 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
 		goto out;
 	}
 	radeon_fence_unref(&nib->fence);
+
 	nib->length_dw = 0;
+
+	/* scheduled list is accessed here */
+	mutex_lock(&rdev->ib_pool.mutex);
 	list_del(&nib->list);
 	INIT_LIST_HEAD(&nib->list);
+	mutex_unlock(&rdev->ib_pool.mutex);
+
 	*ib = nib;
 out:
-	mutex_unlock(&rdev->ib_pool.mutex);
 	if (r) {
 		radeon_fence_unref(&fence);
 	} else {
@@ -111,47 +121,36 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
 	}
 	list_del(&tmp->list);
 	INIT_LIST_HEAD(&tmp->list);
-	if (tmp->fence) {
+	if (tmp->fence)
 		radeon_fence_unref(&tmp->fence);
-	}
+
 	tmp->length_dw = 0;
 	clear_bit(tmp->idx, rdev->ib_pool.alloc_bm);
 	mutex_unlock(&rdev->ib_pool.mutex);
 }
 
-static void radeon_ib_align(struct radeon_device *rdev, struct radeon_ib *ib)
-{
-	while ((ib->length_dw & rdev->cp.align_mask)) {
-		ib->ptr[ib->length_dw++] = PACKET2(0);
-	}
-}
-
 int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
 {
 	int r = 0;
 
-	mutex_lock(&rdev->ib_pool.mutex);
-	radeon_ib_align(rdev, ib);
 	if (!ib->length_dw || !rdev->cp.ready) {
 		/* TODO: Nothings in the ib we should report. */
-		mutex_unlock(&rdev->ib_pool.mutex);
 		DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx);
 		return -EINVAL;
 	}
+
 	/* 64 dwords should be enough for fence too */
 	r = radeon_ring_lock(rdev, 64);
 	if (r) {
 		DRM_ERROR("radeon: scheduling IB failled (%d).\n", r);
-		mutex_unlock(&rdev->ib_pool.mutex);
 		return r;
 	}
-	radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1));
-	radeon_ring_write(rdev, ib->gpu_addr);
-	radeon_ring_write(rdev, ib->length_dw);
+	radeon_ring_ib_execute(rdev, ib);
 	radeon_fence_emit(rdev, ib->fence);
-	radeon_ring_unlock_commit(rdev);
+	mutex_lock(&rdev->ib_pool.mutex);
 	list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs);
 	mutex_unlock(&rdev->ib_pool.mutex);
+	radeon_ring_unlock_commit(rdev);
 	return 0;
 }
 
@@ -162,6 +161,8 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
 	int i;
 	int r = 0;
 
+	if (rdev->ib_pool.robj)
+		return 0;
 	/* Allocate 1M object buffer */
 	INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
 	r = radeon_object_create(rdev, NULL,  RADEON_IB_POOL_SIZE*64*1024,
@@ -215,69 +216,16 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
 	mutex_unlock(&rdev->ib_pool.mutex);
 }
 
-int radeon_ib_test(struct radeon_device *rdev)
-{
-	struct radeon_ib *ib;
-	uint32_t scratch;
-	uint32_t tmp = 0;
-	unsigned i;
-	int r;
-
-	r = radeon_scratch_get(rdev, &scratch);
-	if (r) {
-		DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
-		return r;
-	}
-	WREG32(scratch, 0xCAFEDEAD);
-	r = radeon_ib_get(rdev, &ib);
-	if (r) {
-		return r;
-	}
-	ib->ptr[0] = PACKET0(scratch, 0);
-	ib->ptr[1] = 0xDEADBEEF;
-	ib->ptr[2] = PACKET2(0);
-	ib->ptr[3] = PACKET2(0);
-	ib->ptr[4] = PACKET2(0);
-	ib->ptr[5] = PACKET2(0);
-	ib->ptr[6] = PACKET2(0);
-	ib->ptr[7] = PACKET2(0);
-	ib->length_dw = 8;
-	r = radeon_ib_schedule(rdev, ib);
-	if (r) {
-		radeon_scratch_free(rdev, scratch);
-		radeon_ib_free(rdev, &ib);
-		return r;
-	}
-	r = radeon_fence_wait(ib->fence, false);
-	if (r) {
-		return r;
-	}
-	for (i = 0; i < rdev->usec_timeout; i++) {
-		tmp = RREG32(scratch);
-		if (tmp == 0xDEADBEEF) {
-			break;
-		}
-		DRM_UDELAY(1);
-	}
-	if (i < rdev->usec_timeout) {
-		DRM_INFO("ib test succeeded in %u usecs\n", i);
-	} else {
-		DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
-			  scratch, tmp);
-		r = -EINVAL;
-	}
-	radeon_scratch_free(rdev, scratch);
-	radeon_ib_free(rdev, &ib);
-	return r;
-}
-
 
 /*
  * Ring.
  */
 void radeon_ring_free_size(struct radeon_device *rdev)
 {
-	rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
+	if (rdev->family >= CHIP_R600)
+		rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
+	else
+		rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
 	/* This works because ring_size is a power of 2 */
 	rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4));
 	rdev->cp.ring_free_dw -= rdev->cp.wptr;
@@ -320,11 +268,10 @@ void radeon_ring_unlock_commit(struct radeon_device *rdev)
 	count_dw_pad = (rdev->cp.align_mask + 1) -
 		       (rdev->cp.wptr & rdev->cp.align_mask);
 	for (i = 0; i < count_dw_pad; i++) {
-		radeon_ring_write(rdev, PACKET2(0));
+		radeon_ring_write(rdev, 2 << 30);
 	}
 	DRM_MEMORYBARRIER();
-	WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
-	(void)RREG32(RADEON_CP_RB_WPTR);
+	radeon_cp_commit(rdev);
 	mutex_unlock(&rdev->cp.mutex);
 }
 
@@ -334,46 +281,6 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev)
 	mutex_unlock(&rdev->cp.mutex);
 }
 
-int radeon_ring_test(struct radeon_device *rdev)
-{
-	uint32_t scratch;
-	uint32_t tmp = 0;
-	unsigned i;
-	int r;
-
-	r = radeon_scratch_get(rdev, &scratch);
-	if (r) {
-		DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
-		return r;
-	}
-	WREG32(scratch, 0xCAFEDEAD);
-	r = radeon_ring_lock(rdev, 2);
-	if (r) {
-		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
-		radeon_scratch_free(rdev, scratch);
-		return r;
-	}
-	radeon_ring_write(rdev, PACKET0(scratch, 0));
-	radeon_ring_write(rdev, 0xDEADBEEF);
-	radeon_ring_unlock_commit(rdev);
-	for (i = 0; i < rdev->usec_timeout; i++) {
-		tmp = RREG32(scratch);
-		if (tmp == 0xDEADBEEF) {
-			break;
-		}
-		DRM_UDELAY(1);
-	}
-	if (i < rdev->usec_timeout) {
-		DRM_INFO("ring test succeeded in %d usecs\n", i);
-	} else {
-		DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n",
-			  scratch, tmp);
-		r = -EINVAL;
-	}
-	radeon_scratch_free(rdev, scratch);
-	return r;
-}
-
 int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size)
 {
 	int r;
diff --git a/drivers/gpu/drm/radeon/radeon_share.h b/drivers/gpu/drm/radeon/radeon_share.h
deleted file mode 100644
index 63a7735..0000000
--- a/drivers/gpu/drm/radeon/radeon_share.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2008 Advanced Micro Devices, Inc.
- * Copyright 2008 Red Hat Inc.
- * Copyright 2009 Jerome Glisse.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Dave Airlie
- *          Alex Deucher
- *          Jerome Glisse
- */
-#ifndef __RADEON_SHARE_H__
-#define __RADEON_SHARE_H__
-
-void r100_vram_init_sizes(struct radeon_device *rdev);
-
-void rs690_line_buffer_adjust(struct radeon_device *rdev,
-			      struct drm_display_mode *mode1,
-			      struct drm_display_mode *mode2);
-
-void rv515_bandwidth_avivo_update(struct radeon_device *rdev);
-
-#endif
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index 2882f40..38537d9 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -1546,7 +1546,7 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev,
 	} while (i < nbox);
 }
 
-static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf)
+void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	struct drm_radeon_master_private *master_priv = master->driver_priv;
@@ -2213,7 +2213,10 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f
 	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
 		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
 
-	radeon_cp_dispatch_swap(dev, file_priv->master);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		r600_cp_dispatch_swap(dev, file_priv);
+	else
+		radeon_cp_dispatch_swap(dev, file_priv->master);
 	sarea_priv->ctx_owner = 0;
 
 	COMMIT_RING();
@@ -2412,7 +2415,10 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file
 	RING_SPACE_TEST_WITH_RETURN(dev_priv);
 	VB_AGE_TEST_WITH_RETURN(dev_priv);
 
-	ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
+	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+		ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image);
+	else
+		ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
 
 	return ret;
 }
@@ -2495,8 +2501,9 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
 		radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
 	}
 
-	if (indirect->discard)
+	if (indirect->discard) {
 		radeon_cp_discard_buffer(dev, file_priv->master, buf);
+	}
 
 	COMMIT_RING();
 	return 0;
@@ -3027,7 +3034,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
 		value = GET_SCRATCH(dev_priv, 2);
 		break;
 	case RADEON_PARAM_IRQ_NR:
-		value = drm_dev_to_irq(dev);
+		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+			value = 0;
+		else
+			value = drm_dev_to_irq(dev);
 		break;
 	case RADEON_PARAM_GART_BASE:
 		value = dev_priv->gart_vm_start;
@@ -3227,7 +3237,8 @@ struct drm_ioctl_desc radeon_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
 	DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
-	DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH)
+	DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH),
+	DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH)
 };
 
 int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 15c3531..acd889c 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -35,11 +35,14 @@
 #include <ttm/ttm_module.h>
 #include <drm/drmP.h>
 #include <drm/radeon_drm.h>
+#include <linux/seq_file.h>
 #include "radeon_reg.h"
 #include "radeon.h"
 
 #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
 
+static int radeon_ttm_debugfs_init(struct radeon_device *rdev);
+
 static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev)
 {
 	struct radeon_mman *mman;
@@ -77,9 +80,25 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
 	global_ref->release = &radeon_ttm_mem_global_release;
 	r = ttm_global_item_ref(global_ref);
 	if (r != 0) {
-		DRM_ERROR("Failed referencing a global TTM memory object.\n");
+		DRM_ERROR("Failed setting up TTM memory accounting "
+			  "subsystem.\n");
+		return r;
+	}
+
+	rdev->mman.bo_global_ref.mem_glob =
+		rdev->mman.mem_global_ref.object;
+	global_ref = &rdev->mman.bo_global_ref.ref;
+	global_ref->global_type = TTM_GLOBAL_TTM_BO;
+	global_ref->size = sizeof(struct ttm_bo_global);
+	global_ref->init = &ttm_bo_global_init;
+	global_ref->release = &ttm_bo_global_release;
+	r = ttm_global_item_ref(global_ref);
+	if (r != 0) {
+		DRM_ERROR("Failed setting up TTM BO subsystem.\n");
+		ttm_global_item_unref(&rdev->mman.mem_global_ref);
 		return r;
 	}
+
 	rdev->mman.mem_global_referenced = true;
 	return 0;
 }
@@ -87,6 +106,7 @@ static int radeon_ttm_global_init(struct radeon_device *rdev)
 static void radeon_ttm_global_fini(struct radeon_device *rdev)
 {
 	if (rdev->mman.mem_global_referenced) {
+		ttm_global_item_unref(&rdev->mman.bo_global_ref.ref);
 		ttm_global_item_unref(&rdev->mman.mem_global_ref);
 		rdev->mman.mem_global_referenced = false;
 	}
@@ -286,9 +306,11 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
 	r = ttm_bo_move_ttm(bo, true, no_wait, new_mem);
 out_cleanup:
 	if (tmp_mem.mm_node) {
-		spin_lock(&rdev->mman.bdev.lru_lock);
+		struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+
+		spin_lock(&glob->lru_lock);
 		drm_mm_put_block(tmp_mem.mm_node);
-		spin_unlock(&rdev->mman.bdev.lru_lock);
+		spin_unlock(&glob->lru_lock);
 		return r;
 	}
 	return r;
@@ -323,9 +345,11 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo,
 	}
 out_cleanup:
 	if (tmp_mem.mm_node) {
-		spin_lock(&rdev->mman.bdev.lru_lock);
+		struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+
+		spin_lock(&glob->lru_lock);
 		drm_mm_put_block(tmp_mem.mm_node);
-		spin_unlock(&rdev->mman.bdev.lru_lock);
+		spin_unlock(&glob->lru_lock);
 		return r;
 	}
 	return r;
@@ -352,9 +376,8 @@ static int radeon_bo_move(struct ttm_buffer_object *bo,
 		radeon_move_null(bo, new_mem);
 		return 0;
 	}
-	if (!rdev->cp.ready) {
+	if (!rdev->cp.ready || rdev->asic->copy == NULL) {
 		/* use memcpy */
-		DRM_ERROR("CP is not ready use memcpy.\n");
 		goto memcpy;
 	}
 
@@ -446,7 +469,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
 	}
 	/* No others user of address space so set it to 0 */
 	r = ttm_bo_device_init(&rdev->mman.bdev,
-			       rdev->mman.mem_global_ref.object,
+			       rdev->mman.bo_global_ref.ref.object,
 			       &radeon_bo_driver, DRM_FILE_PAGE_OFFSET,
 			       rdev->need_dma32);
 	if (r) {
@@ -471,7 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev)
 		return r;
 	}
 	DRM_INFO("radeon: %uM of VRAM memory ready\n",
-		 rdev->mc.real_vram_size / (1024 * 1024));
+		 (unsigned)rdev->mc.real_vram_size / (1024 * 1024));
 	r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0,
 			   ((rdev->mc.gtt_size) >> PAGE_SHIFT));
 	if (r) {
@@ -479,10 +502,16 @@ int radeon_ttm_init(struct radeon_device *rdev)
 		return r;
 	}
 	DRM_INFO("radeon: %uM of GTT memory ready.\n",
-		 rdev->mc.gtt_size / (1024 * 1024));
+		 (unsigned)(rdev->mc.gtt_size / (1024 * 1024)));
 	if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) {
 		rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping;
 	}
+
+	r = radeon_ttm_debugfs_init(rdev);
+	if (r) {
+		DRM_ERROR("Failed to init debugfs\n");
+		return r;
+	}
 	return 0;
 }
 
@@ -657,3 +686,50 @@ struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev)
 	gtt->bound = false;
 	return &gtt->backend;
 }
+
+#define RADEON_DEBUGFS_MEM_TYPES 2
+
+static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES];
+static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32];
+
+#if defined(CONFIG_DEBUG_FS)
+static int radeon_mm_dump_table(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *)m->private;
+	struct drm_mm *mm = (struct drm_mm *)node->info_ent->data;
+	struct drm_device *dev = node->minor->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	int ret;
+	struct ttm_bo_global *glob = rdev->mman.bdev.glob;
+
+	spin_lock(&glob->lru_lock);
+	ret = drm_mm_dump_table(m, mm);
+	spin_unlock(&glob->lru_lock);
+	return ret;
+}
+#endif
+
+static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
+{
+	unsigned i;
+
+#if defined(CONFIG_DEBUG_FS)
+	for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) {
+		if (i == 0)
+			sprintf(radeon_mem_types_names[i], "radeon_vram_mm");
+		else
+			sprintf(radeon_mem_types_names[i], "radeon_gtt_mm");
+		radeon_mem_types_list[i].name = radeon_mem_types_names[i];
+		radeon_mem_types_list[i].show = &radeon_mm_dump_table;
+		radeon_mem_types_list[i].driver_features = 0;
+		if (i == 0)
+			radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].manager;
+		else
+			radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].manager;
+
+	}
+	return radeon_debugfs_add_files(rdev, radeon_mem_types_list, RADEON_DEBUGFS_MEM_TYPES);
+
+#endif
+	return 0;
+}
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r100 b/drivers/gpu/drm/radeon/reg_srcs/r100
new file mode 100644
index 0000000..f7ee062
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r100
@@ -0,0 +1,105 @@
+r100 0x3294
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1810 FOG_3D_TABLE_START
+0x1814 FOG_3D_TABLE_END
+0x1a14 FOG_TABLE_INDEX
+0x1a18 FOG_TABLE_DATA
+0x1c14 PP_MISC
+0x1c18 PP_FOG_COLOR
+0x1c1c RE_SOLID_COLOR
+0x1c20 RB3D_BLENDCNTL
+0x1c4c SE_CNTL
+0x1c50 SE_COORD_FMT
+0x1c60 PP_TXCBLEND_0
+0x1c64 PP_TXABLEND_0
+0x1c68 PP_TFACTOR_0
+0x1c78 PP_TXCBLEND_1
+0x1c7c PP_TXABLEND_1
+0x1c80 PP_TFACTOR_1
+0x1c90 PP_TXCBLEND_2
+0x1c94 PP_TXABLEND_2
+0x1c98 PP_TFACTOR_2
+0x1cc8 RE_STIPPLE_ADDR
+0x1ccc RE_STIPPLE_DATA
+0x1cd0 RE_LINE_PATTERN
+0x1cd4 RE_LINE_STATE
+0x1d40 PP_BORDER_COLOR0
+0x1d44 PP_BORDER_COLOR1
+0x1d48 PP_BORDER_COLOR2
+0x1d7c RB3D_STENCILREFMASK
+0x1d80 RB3D_ROPCNTL
+0x1d84 RB3D_PLANEMASK
+0x1d98 VAP_VPORT_XSCALE
+0x1d9C VAP_VPORT_XOFFSET
+0x1da0 VAP_VPORT_YSCALE
+0x1da4 VAP_VPORT_YOFFSET
+0x1da8 VAP_VPORT_ZSCALE
+0x1dac VAP_VPORT_ZOFFSET
+0x1db0 SE_ZBIAS_FACTOR
+0x1db4 SE_ZBIAS_CONSTANT
+0x1db8 SE_LINE_WIDTH
+0x2140 SE_CNTL_STATUS
+0x2200 SE_TCL_VECTOR_INDX_REG
+0x2204 SE_TCL_VECTOR_DATA_REG
+0x2208 SE_TCL_SCALAR_INDX_REG
+0x220c SE_TCL_SCALAR_DATA_REG
+0x2210 SE_TCL_MATERIAL_EMISSIVE_RED
+0x2214 SE_TCL_MATERIAL_EMISSIVE_GREEN
+0x2218 SE_TCL_MATERIAL_EMISSIVE_BLUE
+0x221c SE_TCL_MATERIAL_EMISSIVE_ALPHA
+0x2220 SE_TCL_MATERIAL_AMBIENT_RED
+0x2224 SE_TCL_MATERIAL_AMBIENT_GREEN
+0x2228 SE_TCL_MATERIAL_AMBIENT_BLUE
+0x222c SE_TCL_MATERIAL_AMBIENT_ALPHA
+0x2230 SE_TCL_MATERIAL_DIFFUSE_RED
+0x2234 SE_TCL_MATERIAL_DIFFUSE_GREEN
+0x2238 SE_TCL_MATERIAL_DIFFUSE_BLUE
+0x223c SE_TCL_MATERIAL_DIFFUSE_ALPHA
+0x2240 SE_TCL_MATERIAL_SPECULAR_RED
+0x2244 SE_TCL_MATERIAL_SPECULAR_GREEN
+0x2248 SE_TCL_MATERIAL_SPECULAR_BLUE
+0x224c SE_TCL_MATERIAL_SPECULAR_ALPHA
+0x2250 SE_TCL_SHININESS
+0x2254 SE_TCL_OUTPUT_VTX_FMT
+0x2258 SE_TCL_OUTPUT_VTX_SEL
+0x225c SE_TCL_MATRIX_SELECT_0
+0x2260 SE_TCL_MATRIX_SELECT_1
+0x2264 SE_TCL_UCP_VERT_BLEND_CNTL
+0x2268 SE_TCL_TEXTURE_PROC_CTL
+0x226c SE_TCL_LIGHT_MODEL_CTL
+0x2270 SE_TCL_PER_LIGHT_CTL_0
+0x2274 SE_TCL_PER_LIGHT_CTL_1
+0x2278 SE_TCL_PER_LIGHT_CTL_2
+0x227c SE_TCL_PER_LIGHT_CTL_3
+0x2284 SE_TCL_STATE_FLUSH
+0x26c0 RE_TOP_LEFT
+0x26c4 RE_MISC
+0x3290 RB3D_ZPASS_DATA
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r200 b/drivers/gpu/drm/radeon/reg_srcs/r200
new file mode 100644
index 0000000..6021c88
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r200
@@ -0,0 +1,184 @@
+r200 0x3294
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1c14 PP_MISC
+0x1c18 PP_FOG_COLOR
+0x1c1c RE_SOLID_COLOR
+0x1c20 RB3D_BLENDCNTL
+0x1c4c SE_CNTL
+0x1c50 RE_CNTL
+0x1cc8 RE_STIPPLE_ADDR
+0x1ccc RE_STIPPLE_DATA
+0x1cd0 RE_LINE_PATTERN
+0x1cd4 RE_LINE_STATE
+0x1cd8 RE_SCISSOR_TL_0
+0x1cdc RE_SCISSOR_BR_0
+0x1ce0 RE_SCISSOR_TL_1
+0x1ce4 RE_SCISSOR_BR_1
+0x1ce8 RE_SCISSOR_TL_2
+0x1cec RE_SCISSOR_BR_2
+0x1d60 RB3D_DEPTHXY_OFFSET
+0x1d7c RB3D_STENCILREFMASK
+0x1d80 RB3D_ROPCNTL
+0x1d84 RB3D_PLANEMASK
+0x1d98 VAP_VPORT_XSCALE
+0x1d9c VAP_VPORT_XOFFSET
+0x1da0 VAP_VPORT_YSCALE
+0x1da4 VAP_VPORT_YOFFSET
+0x1da8 VAP_VPORT_ZSCALE
+0x1dac VAP_VPORT_ZOFFSET
+0x1db0 SE_ZBIAS_FACTOR
+0x1db4 SE_ZBIAS_CONSTANT
+0x1db8 SE_LINE_WIDTH
+0x2080 SE_VAP_CNTL
+0x2090 SE_TCL_OUTPUT_VTX_FMT_0
+0x2094 SE_TCL_OUTPUT_VTX_FMT_1
+0x20b0 SE_VTE_CNTL
+0x2140 SE_CNTL_STATUS
+0x2180 SE_VTX_STATE_CNTL
+0x2200 SE_TCL_VECTOR_INDX_REG
+0x2204 SE_TCL_VECTOR_DATA_REG
+0x2208 SE_TCL_SCALAR_INDX_REG
+0x220c SE_TCL_SCALAR_DATA_REG
+0x2230 SE_TCL_MATRIX_SEL_0
+0x2234 SE_TCL_MATRIX_SEL_1
+0x2238 SE_TCL_MATRIX_SEL_2
+0x223c SE_TCL_MATRIX_SEL_3
+0x2240 SE_TCL_MATRIX_SEL_4
+0x2250 SE_TCL_OUTPUT_VTX_COMP_SEL
+0x2254 SE_TCL_INPUT_VTX_VECTOR_ADDR_0
+0x2258 SE_TCL_INPUT_VTX_VECTOR_ADDR_1
+0x225c SE_TCL_INPUT_VTX_VECTOR_ADDR_2
+0x2260 SE_TCL_INPUT_VTX_VECTOR_ADDR_3
+0x2268 SE_TCL_LIGHT_MODEL_CTL_0
+0x226c SE_TCL_LIGHT_MODEL_CTL_1
+0x2270 SE_TCL_PER_LIGHT_CTL_0
+0x2274 SE_TCL_PER_LIGHT_CTL_1
+0x2278 SE_TCL_PER_LIGHT_CTL_2
+0x227c SE_TCL_PER_LIGHT_CTL_3
+0x2284 VAP_PVS_STATE_FLUSH_REG
+0x22a8 SE_TCL_TEX_PROC_CTL_2
+0x22ac SE_TCL_TEX_PROC_CTL_3
+0x22b0 SE_TCL_TEX_PROC_CTL_0
+0x22b4 SE_TCL_TEX_PROC_CTL_1
+0x22b8 SE_TCL_TEX_CYL_WRAP_CTL
+0x22c0 SE_TCL_UCP_VERT_BLEND_CNTL
+0x22c4 SE_TCL_POINT_SPRITE_CNTL
+0x2648 RE_POINTSIZE
+0x26c0 RE_TOP_LEFT
+0x26c4 RE_MISC
+0x26f0 RE_AUX_SCISSOR_CNTL
+0x2c14 PP_BORDER_COLOR_0
+0x2c34 PP_BORDER_COLOR_1
+0x2c54 PP_BORDER_COLOR_2
+0x2c74 PP_BORDER_COLOR_3
+0x2c94 PP_BORDER_COLOR_4
+0x2cb4 PP_BORDER_COLOR_5
+0x2cc4 PP_CNTL_X
+0x2cf8 PP_TRI_PERF
+0x2cfc PP_PERF_CNTL
+0x2d9c PP_TAM_DEBUG3
+0x2ee0 PP_TFACTOR_0
+0x2ee4 PP_TFACTOR_1
+0x2ee8 PP_TFACTOR_2
+0x2eec PP_TFACTOR_3
+0x2ef0 PP_TFACTOR_4
+0x2ef4 PP_TFACTOR_5
+0x2ef8 PP_TFACTOR_6
+0x2efc PP_TFACTOR_7
+0x2f00 PP_TXCBLEND_0
+0x2f04 PP_TXCBLEND2_0
+0x2f08 PP_TXABLEND_0
+0x2f0c PP_TXABLEND2_0
+0x2f10 PP_TXCBLEND_1
+0x2f14 PP_TXCBLEND2_1
+0x2f18 PP_TXABLEND_1
+0x2f1c PP_TXABLEND2_1
+0x2f20 PP_TXCBLEND_2
+0x2f24 PP_TXCBLEND2_2
+0x2f28 PP_TXABLEND_2
+0x2f2c PP_TXABLEND2_2
+0x2f30 PP_TXCBLEND_3
+0x2f34 PP_TXCBLEND2_3
+0x2f38 PP_TXABLEND_3
+0x2f3c PP_TXABLEND2_3
+0x2f40 PP_TXCBLEND_4
+0x2f44 PP_TXCBLEND2_4
+0x2f48 PP_TXABLEND_4
+0x2f4c PP_TXABLEND2_4
+0x2f50 PP_TXCBLEND_5
+0x2f54 PP_TXCBLEND2_5
+0x2f58 PP_TXABLEND_5
+0x2f5c PP_TXABLEND2_5
+0x2f60 PP_TXCBLEND_6
+0x2f64 PP_TXCBLEND2_6
+0x2f68 PP_TXABLEND_6
+0x2f6c PP_TXABLEND2_6
+0x2f70 PP_TXCBLEND_7
+0x2f74 PP_TXCBLEND2_7
+0x2f78 PP_TXABLEND_7
+0x2f7c PP_TXABLEND2_7
+0x2f80 PP_TXCBLEND_8
+0x2f84 PP_TXCBLEND2_8
+0x2f88 PP_TXABLEND_8
+0x2f8c PP_TXABLEND2_8
+0x2f90 PP_TXCBLEND_9
+0x2f94 PP_TXCBLEND2_9
+0x2f98 PP_TXABLEND_9
+0x2f9c PP_TXABLEND2_9
+0x2fa0 PP_TXCBLEND_10
+0x2fa4 PP_TXCBLEND2_10
+0x2fa8 PP_TXABLEND_10
+0x2fac PP_TXABLEND2_10
+0x2fb0 PP_TXCBLEND_11
+0x2fb4 PP_TXCBLEND2_11
+0x2fb8 PP_TXABLEND_11
+0x2fbc PP_TXABLEND2_11
+0x2fc0 PP_TXCBLEND_12
+0x2fc4 PP_TXCBLEND2_12
+0x2fc8 PP_TXABLEND_12
+0x2fcc PP_TXABLEND2_12
+0x2fd0 PP_TXCBLEND_13
+0x2fd4 PP_TXCBLEND2_13
+0x2fd8 PP_TXABLEND_13
+0x2fdc PP_TXABLEND2_13
+0x2fe0 PP_TXCBLEND_14
+0x2fe4 PP_TXCBLEND2_14
+0x2fe8 PP_TXABLEND_14
+0x2fec PP_TXABLEND2_14
+0x2ff0 PP_TXCBLEND_15
+0x2ff4 PP_TXCBLEND2_15
+0x2ff8 PP_TXABLEND_15
+0x2ffc PP_TXABLEND2_15
+0x3218 RB3D_BLENCOLOR
+0x321c RB3D_ABLENDCNTL
+0x3220 RB3D_CBLENDCNTL
+0x3290 RB3D_ZPASS_DATA
+
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300
new file mode 100644
index 0000000..19c4663
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/r300
@@ -0,0 +1,729 @@
+r300 0x4f60
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1D98 VAP_VPORT_XSCALE
+0x1D9C VAP_VPORT_XOFFSET
+0x1DA0 VAP_VPORT_YSCALE
+0x1DA4 VAP_VPORT_YOFFSET
+0x1DA8 VAP_VPORT_ZSCALE
+0x1DAC VAP_VPORT_ZOFFSET
+0x2080 VAP_CNTL
+0x2090 VAP_OUT_VTX_FMT_0
+0x2094 VAP_OUT_VTX_FMT_1
+0x20B0 VAP_VTE_CNTL
+0x2138 VAP_VF_MIN_VTX_INDX
+0x2140 VAP_CNTL_STATUS
+0x2150 VAP_PROG_STREAM_CNTL_0
+0x2154 VAP_PROG_STREAM_CNTL_1
+0x2158 VAP_PROG_STREAM_CNTL_2
+0x215C VAP_PROG_STREAM_CNTL_3
+0x2160 VAP_PROG_STREAM_CNTL_4
+0x2164 VAP_PROG_STREAM_CNTL_5
+0x2168 VAP_PROG_STREAM_CNTL_6
+0x216C VAP_PROG_STREAM_CNTL_7
+0x2180 VAP_VTX_STATE_CNTL
+0x2184 VAP_VSM_VTX_ASSM
+0x2188 VAP_VTX_STATE_IND_REG_0
+0x218C VAP_VTX_STATE_IND_REG_1
+0x2190 VAP_VTX_STATE_IND_REG_2
+0x2194 VAP_VTX_STATE_IND_REG_3
+0x2198 VAP_VTX_STATE_IND_REG_4
+0x219C VAP_VTX_STATE_IND_REG_5
+0x21A0 VAP_VTX_STATE_IND_REG_6
+0x21A4 VAP_VTX_STATE_IND_REG_7
+0x21A8 VAP_VTX_STATE_IND_REG_8
+0x21AC VAP_VTX_STATE_IND_REG_9
+0x21B0 VAP_VTX_STATE_IND_REG_10
+0x21B4 VAP_VTX_STATE_IND_REG_11
+0x21B8 VAP_VTX_STATE_IND_REG_12
+0x21BC VAP_VTX_STATE_IND_REG_13
+0x21C0 VAP_VTX_STATE_IND_REG_14
+0x21C4 VAP_VTX_STATE_IND_REG_15
+0x21DC VAP_PSC_SGN_NORM_CNTL
+0x21E0 VAP_PROG_STREAM_CNTL_EXT_0
+0x21E4 VAP_PROG_STREAM_CNTL_EXT_1
+0x21E8 VAP_PROG_STREAM_CNTL_EXT_2
+0x21EC VAP_PROG_STREAM_CNTL_EXT_3
+0x21F0 VAP_PROG_STREAM_CNTL_EXT_4
+0x21F4 VAP_PROG_STREAM_CNTL_EXT_5
+0x21F8 VAP_PROG_STREAM_CNTL_EXT_6
+0x21FC VAP_PROG_STREAM_CNTL_EXT_7
+0x2200 VAP_PVS_VECTOR_INDX_REG
+0x2204 VAP_PVS_VECTOR_DATA_REG
+0x2208 VAP_PVS_VECTOR_DATA_REG_128
+0x221C VAP_CLIP_CNTL
+0x2220 VAP_GB_VERT_CLIP_ADJ
+0x2224 VAP_GB_VERT_DISC_ADJ
+0x2228 VAP_GB_HORZ_CLIP_ADJ
+0x222C VAP_GB_HORZ_DISC_ADJ
+0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0
+0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1
+0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2
+0x223C VAP_PVS_FLOW_CNTL_ADDRS_3
+0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4
+0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5
+0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6
+0x224C VAP_PVS_FLOW_CNTL_ADDRS_7
+0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8
+0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9
+0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10
+0x225C VAP_PVS_FLOW_CNTL_ADDRS_11
+0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12
+0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13
+0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14
+0x226C VAP_PVS_FLOW_CNTL_ADDRS_15
+0x2284 VAP_PVS_STATE_FLUSH_REG
+0x2288 VAP_PVS_VTX_TIMEOUT_REG
+0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0
+0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1
+0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2
+0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3
+0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4
+0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5
+0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6
+0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7
+0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8
+0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9
+0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10
+0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11
+0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12
+0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13
+0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14
+0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15
+0x22D0 VAP_PVS_CODE_CNTL_0
+0x22D4 VAP_PVS_CONST_CNTL
+0x22D8 VAP_PVS_CODE_CNTL_1
+0x22DC VAP_PVS_FLOW_CNTL_OPC
+0x342C RB2D_DSTCACHE_CTLSTAT
+0x4000 GB_VAP_RASTER_VTX_FMT_0
+0x4004 GB_VAP_RASTER_VTX_FMT_1
+0x4008 GB_ENABLE
+0x401C GB_SELECT
+0x4020 GB_AA_CONFIG
+0x4024 GB_FIFO_SIZE
+0x4100 TX_INVALTAGS
+0x4200 GA_POINT_S0
+0x4204 GA_POINT_T0
+0x4208 GA_POINT_S1
+0x420C GA_POINT_T1
+0x4214 GA_TRIANGLE_STIPPLE
+0x421C GA_POINT_SIZE
+0x4230 GA_POINT_MINMAX
+0x4234 GA_LINE_CNTL
+0x4238 GA_LINE_STIPPLE_CONFIG
+0x4260 GA_LINE_STIPPLE_VALUE
+0x4264 GA_LINE_S0
+0x4268 GA_LINE_S1
+0x4278 GA_COLOR_CONTROL
+0x427C GA_SOLID_RG
+0x4280 GA_SOLID_BA
+0x4288 GA_POLY_MODE
+0x428C GA_ROUND_MODE
+0x4290 GA_OFFSET
+0x4294 GA_FOG_SCALE
+0x4298 GA_FOG_OFFSET
+0x42A0 SU_TEX_WRAP
+0x42A4 SU_POLY_OFFSET_FRONT_SCALE
+0x42A8 SU_POLY_OFFSET_FRONT_OFFSET
+0x42AC SU_POLY_OFFSET_BACK_SCALE
+0x42B0 SU_POLY_OFFSET_BACK_OFFSET
+0x42B4 SU_POLY_OFFSET_ENABLE
+0x42B8 SU_CULL_MODE
+0x42C0 SU_DEPTH_SCALE
+0x42C4 SU_DEPTH_OFFSET
+0x42C8 SU_REG_DEST
+0x4300 RS_COUNT
+0x4304 RS_INST_COUNT
+0x4310 RS_IP_0
+0x4314 RS_IP_1
+0x4318 RS_IP_2
+0x431C RS_IP_3
+0x4320 RS_IP_4
+0x4324 RS_IP_5
+0x4328 RS_IP_6
+0x432C RS_IP_7
+0x4330 RS_INST_0
+0x4334 RS_INST_1
+0x4338 RS_INST_2
+0x433C RS_INST_3
+0x4340 RS_INST_4
+0x4344 RS_INST_5
+0x4348 RS_INST_6
+0x434C RS_INST_7
+0x4350 RS_INST_8
+0x4354 RS_INST_9
+0x4358 RS_INST_10
+0x435C RS_INST_11
+0x4360 RS_INST_12
+0x4364 RS_INST_13
+0x4368 RS_INST_14
+0x436C RS_INST_15
+0x43A4 SC_HYPERZ_EN
+0x43A8 SC_EDGERULE
+0x43B0 SC_CLIP_0_A
+0x43B4 SC_CLIP_0_B
+0x43B8 SC_CLIP_1_A
+0x43BC SC_CLIP_1_B
+0x43C0 SC_CLIP_2_A
+0x43C4 SC_CLIP_2_B
+0x43C8 SC_CLIP_3_A
+0x43CC SC_CLIP_3_B
+0x43D0 SC_CLIP_RULE
+0x43E0 SC_SCISSOR0
+0x43E8 SC_SCREENDOOR
+0x4440 TX_FILTER1_0
+0x4444 TX_FILTER1_1
+0x4448 TX_FILTER1_2
+0x444C TX_FILTER1_3
+0x4450 TX_FILTER1_4
+0x4454 TX_FILTER1_5
+0x4458 TX_FILTER1_6
+0x445C TX_FILTER1_7
+0x4460 TX_FILTER1_8
+0x4464 TX_FILTER1_9
+0x4468 TX_FILTER1_10
+0x446C TX_FILTER1_11
+0x4470 TX_FILTER1_12
+0x4474 TX_FILTER1_13
+0x4478 TX_FILTER1_14
+0x447C TX_FILTER1_15
+0x4580 TX_CHROMA_KEY_0
+0x4584 TX_CHROMA_KEY_1
+0x4588 TX_CHROMA_KEY_2
+0x458C TX_CHROMA_KEY_3
+0x4590 TX_CHROMA_KEY_4
+0x4594 TX_CHROMA_KEY_5
+0x4598 TX_CHROMA_KEY_6
+0x459C TX_CHROMA_KEY_7
+0x45A0 TX_CHROMA_KEY_8
+0x45A4 TX_CHROMA_KEY_9
+0x45A8 TX_CHROMA_KEY_10
+0x45AC TX_CHROMA_KEY_11
+0x45B0 TX_CHROMA_KEY_12
+0x45B4 TX_CHROMA_KEY_13
+0x45B8 TX_CHROMA_KEY_14
+0x45BC TX_CHROMA_KEY_15
+0x45C0 TX_BORDER_COLOR_0
+0x45C4 TX_BORDER_COLOR_1
+0x45C8 TX_BORDER_COLOR_2
+0x45CC TX_BORDER_COLOR_3
+0x45D0 TX_BORDER_COLOR_4
+0x45D4 TX_BORDER_COLOR_5
+0x45D8 TX_BORDER_COLOR_6
+0x45DC TX_BORDER_COLOR_7
+0x45E0 TX_BORDER_COLOR_8
+0x45E4 TX_BORDER_COLOR_9
+0x45E8 TX_BORDER_COLOR_10
+0x45EC TX_BORDER_COLOR_11
+0x45F0 TX_BORDER_COLOR_12
+0x45F4 TX_BORDER_COLOR_13
+0x45F8 TX_BORDER_COLOR_14
+0x45FC TX_BORDER_COLOR_15
+0x4600 US_CONFIG
+0x4604 US_PIXSIZE
+0x4608 US_CODE_OFFSET
+0x460C US_RESET
+0x4610 US_CODE_ADDR_0
+0x4614 US_CODE_ADDR_1
+0x4618 US_CODE_ADDR_2
+0x461C US_CODE_ADDR_3
+0x4620 US_TEX_INST_0
+0x4624 US_TEX_INST_1
+0x4628 US_TEX_INST_2
+0x462C US_TEX_INST_3
+0x4630 US_TEX_INST_4
+0x4634 US_TEX_INST_5
+0x4638 US_TEX_INST_6
+0x463C US_TEX_INST_7
+0x4640 US_TEX_INST_8
+0x4644 US_TEX_INST_9
+0x4648 US_TEX_INST_10
+0x464C US_TEX_INST_11
+0x4650 US_TEX_INST_12
+0x4654 US_TEX_INST_13
+0x4658 US_TEX_INST_14
+0x465C US_TEX_INST_15
+0x4660 US_TEX_INST_16
+0x4664 US_TEX_INST_17
+0x4668 US_TEX_INST_18
+0x466C US_TEX_INST_19
+0x4670 US_TEX_INST_20
+0x4674 US_TEX_INST_21
+0x4678 US_TEX_INST_22
+0x467C US_TEX_INST_23
+0x4680 US_TEX_INST_24
+0x4684 US_TEX_INST_25
+0x4688 US_TEX_INST_26
+0x468C US_TEX_INST_27
+0x4690 US_TEX_INST_28
+0x4694 US_TEX_INST_29
+0x4698 US_TEX_INST_30
+0x469C US_TEX_INST_31
+0x46A4 US_OUT_FMT_0
+0x46A8 US_OUT_FMT_1
+0x46AC US_OUT_FMT_2
+0x46B0 US_OUT_FMT_3
+0x46B4 US_W_FMT
+0x46C0 US_ALU_RGB_ADDR_0
+0x46C4 US_ALU_RGB_ADDR_1
+0x46C8 US_ALU_RGB_ADDR_2
+0x46CC US_ALU_RGB_ADDR_3
+0x46D0 US_ALU_RGB_ADDR_4
+0x46D4 US_ALU_RGB_ADDR_5
+0x46D8 US_ALU_RGB_ADDR_6
+0x46DC US_ALU_RGB_ADDR_7
+0x46E0 US_ALU_RGB_ADDR_8
+0x46E4 US_ALU_RGB_ADDR_9
+0x46E8 US_ALU_RGB_ADDR_10
+0x46EC US_ALU_RGB_ADDR_11
+0x46F0 US_ALU_RGB_ADDR_12
+0x46F4 US_ALU_RGB_ADDR_13
+0x46F8 US_ALU_RGB_ADDR_14
+0x46FC US_ALU_RGB_ADDR_15
+0x4700 US_ALU_RGB_ADDR_16
+0x4704 US_ALU_RGB_ADDR_17
+0x4708 US_ALU_RGB_ADDR_18
+0x470C US_ALU_RGB_ADDR_19
+0x4710 US_ALU_RGB_ADDR_20
+0x4714 US_ALU_RGB_ADDR_21
+0x4718 US_ALU_RGB_ADDR_22
+0x471C US_ALU_RGB_ADDR_23
+0x4720 US_ALU_RGB_ADDR_24
+0x4724 US_ALU_RGB_ADDR_25
+0x4728 US_ALU_RGB_ADDR_26
+0x472C US_ALU_RGB_ADDR_27
+0x4730 US_ALU_RGB_ADDR_28
+0x4734 US_ALU_RGB_ADDR_29
+0x4738 US_ALU_RGB_ADDR_30
+0x473C US_ALU_RGB_ADDR_31
+0x4740 US_ALU_RGB_ADDR_32
+0x4744 US_ALU_RGB_ADDR_33
+0x4748 US_ALU_RGB_ADDR_34
+0x474C US_ALU_RGB_ADDR_35
+0x4750 US_ALU_RGB_ADDR_36
+0x4754 US_ALU_RGB_ADDR_37
+0x4758 US_ALU_RGB_ADDR_38
+0x475C US_ALU_RGB_ADDR_39
+0x4760 US_ALU_RGB_ADDR_40
+0x4764 US_ALU_RGB_ADDR_41
+0x4768 US_ALU_RGB_ADDR_42
+0x476C US_ALU_RGB_ADDR_43
+0x4770 US_ALU_RGB_ADDR_44
+0x4774 US_ALU_RGB_ADDR_45
+0x4778 US_ALU_RGB_ADDR_46
+0x477C US_ALU_RGB_ADDR_47
+0x4780 US_ALU_RGB_ADDR_48
+0x4784 US_ALU_RGB_ADDR_49
+0x4788 US_ALU_RGB_ADDR_50
+0x478C US_ALU_RGB_ADDR_51
+0x4790 US_ALU_RGB_ADDR_52
+0x4794 US_ALU_RGB_ADDR_53
+0x4798 US_ALU_RGB_ADDR_54
+0x479C US_ALU_RGB_ADDR_55
+0x47A0 US_ALU_RGB_ADDR_56
+0x47A4 US_ALU_RGB_ADDR_57
+0x47A8 US_ALU_RGB_ADDR_58
+0x47AC US_ALU_RGB_ADDR_59
+0x47B0 US_ALU_RGB_ADDR_60
+0x47B4 US_ALU_RGB_ADDR_61
+0x47B8 US_ALU_RGB_ADDR_62
+0x47BC US_ALU_RGB_ADDR_63
+0x47C0 US_ALU_ALPHA_ADDR_0
+0x47C4 US_ALU_ALPHA_ADDR_1
+0x47C8 US_ALU_ALPHA_ADDR_2
+0x47CC US_ALU_ALPHA_ADDR_3
+0x47D0 US_ALU_ALPHA_ADDR_4
+0x47D4 US_ALU_ALPHA_ADDR_5
+0x47D8 US_ALU_ALPHA_ADDR_6
+0x47DC US_ALU_ALPHA_ADDR_7
+0x47E0 US_ALU_ALPHA_ADDR_8
+0x47E4 US_ALU_ALPHA_ADDR_9
+0x47E8 US_ALU_ALPHA_ADDR_10
+0x47EC US_ALU_ALPHA_ADDR_11
+0x47F0 US_ALU_ALPHA_ADDR_12
+0x47F4 US_ALU_ALPHA_ADDR_13
+0x47F8 US_ALU_ALPHA_ADDR_14
+0x47FC US_ALU_ALPHA_ADDR_15
+0x4800 US_ALU_ALPHA_ADDR_16
+0x4804 US_ALU_ALPHA_ADDR_17
+0x4808 US_ALU_ALPHA_ADDR_18
+0x480C US_ALU_ALPHA_ADDR_19
+0x4810 US_ALU_ALPHA_ADDR_20
+0x4814 US_ALU_ALPHA_ADDR_21
+0x4818 US_ALU_ALPHA_ADDR_22
+0x481C US_ALU_ALPHA_ADDR_23
+0x4820 US_ALU_ALPHA_ADDR_24
+0x4824 US_ALU_ALPHA_ADDR_25
+0x4828 US_ALU_ALPHA_ADDR_26
+0x482C US_ALU_ALPHA_ADDR_27
+0x4830 US_ALU_ALPHA_ADDR_28
+0x4834 US_ALU_ALPHA_ADDR_29
+0x4838 US_ALU_ALPHA_ADDR_30
+0x483C US_ALU_ALPHA_ADDR_31
+0x4840 US_ALU_ALPHA_ADDR_32
+0x4844 US_ALU_ALPHA_ADDR_33
+0x4848 US_ALU_ALPHA_ADDR_34
+0x484C US_ALU_ALPHA_ADDR_35
+0x4850 US_ALU_ALPHA_ADDR_36
+0x4854 US_ALU_ALPHA_ADDR_37
+0x4858 US_ALU_ALPHA_ADDR_38
+0x485C US_ALU_ALPHA_ADDR_39
+0x4860 US_ALU_ALPHA_ADDR_40
+0x4864 US_ALU_ALPHA_ADDR_41
+0x4868 US_ALU_ALPHA_ADDR_42
+0x486C US_ALU_ALPHA_ADDR_43
+0x4870 US_ALU_ALPHA_ADDR_44
+0x4874 US_ALU_ALPHA_ADDR_45
+0x4878 US_ALU_ALPHA_ADDR_46
+0x487C US_ALU_ALPHA_ADDR_47
+0x4880 US_ALU_ALPHA_ADDR_48
+0x4884 US_ALU_ALPHA_ADDR_49
+0x4888 US_ALU_ALPHA_ADDR_50
+0x488C US_ALU_ALPHA_ADDR_51
+0x4890 US_ALU_ALPHA_ADDR_52
+0x4894 US_ALU_ALPHA_ADDR_53
+0x4898 US_ALU_ALPHA_ADDR_54
+0x489C US_ALU_ALPHA_ADDR_55
+0x48A0 US_ALU_ALPHA_ADDR_56
+0x48A4 US_ALU_ALPHA_ADDR_57
+0x48A8 US_ALU_ALPHA_ADDR_58
+0x48AC US_ALU_ALPHA_ADDR_59
+0x48B0 US_ALU_ALPHA_ADDR_60
+0x48B4 US_ALU_ALPHA_ADDR_61
+0x48B8 US_ALU_ALPHA_ADDR_62
+0x48BC US_ALU_ALPHA_ADDR_63
+0x48C0 US_ALU_RGB_INST_0
+0x48C4 US_ALU_RGB_INST_1
+0x48C8 US_ALU_RGB_INST_2
+0x48CC US_ALU_RGB_INST_3
+0x48D0 US_ALU_RGB_INST_4
+0x48D4 US_ALU_RGB_INST_5
+0x48D8 US_ALU_RGB_INST_6
+0x48DC US_ALU_RGB_INST_7
+0x48E0 US_ALU_RGB_INST_8
+0x48E4 US_ALU_RGB_INST_9
+0x48E8 US_ALU_RGB_INST_10
+0x48EC US_ALU_RGB_INST_11
+0x48F0 US_ALU_RGB_INST_12
+0x48F4 US_ALU_RGB_INST_13
+0x48F8 US_ALU_RGB_INST_14
+0x48FC US_ALU_RGB_INST_15
+0x4900 US_ALU_RGB_INST_16
+0x4904 US_ALU_RGB_INST_17
+0x4908 US_ALU_RGB_INST_18
+0x490C US_ALU_RGB_INST_19
+0x4910 US_ALU_RGB_INST_20
+0x4914 US_ALU_RGB_INST_21
+0x4918 US_ALU_RGB_INST_22
+0x491C US_ALU_RGB_INST_23
+0x4920 US_ALU_RGB_INST_24
+0x4924 US_ALU_RGB_INST_25
+0x4928 US_ALU_RGB_INST_26
+0x492C US_ALU_RGB_INST_27
+0x4930 US_ALU_RGB_INST_28
+0x4934 US_ALU_RGB_INST_29
+0x4938 US_ALU_RGB_INST_30
+0x493C US_ALU_RGB_INST_31
+0x4940 US_ALU_RGB_INST_32
+0x4944 US_ALU_RGB_INST_33
+0x4948 US_ALU_RGB_INST_34
+0x494C US_ALU_RGB_INST_35
+0x4950 US_ALU_RGB_INST_36
+0x4954 US_ALU_RGB_INST_37
+0x4958 US_ALU_RGB_INST_38
+0x495C US_ALU_RGB_INST_39
+0x4960 US_ALU_RGB_INST_40
+0x4964 US_ALU_RGB_INST_41
+0x4968 US_ALU_RGB_INST_42
+0x496C US_ALU_RGB_INST_43
+0x4970 US_ALU_RGB_INST_44
+0x4974 US_ALU_RGB_INST_45
+0x4978 US_ALU_RGB_INST_46
+0x497C US_ALU_RGB_INST_47
+0x4980 US_ALU_RGB_INST_48
+0x4984 US_ALU_RGB_INST_49
+0x4988 US_ALU_RGB_INST_50
+0x498C US_ALU_RGB_INST_51
+0x4990 US_ALU_RGB_INST_52
+0x4994 US_ALU_RGB_INST_53
+0x4998 US_ALU_RGB_INST_54
+0x499C US_ALU_RGB_INST_55
+0x49A0 US_ALU_RGB_INST_56
+0x49A4 US_ALU_RGB_INST_57
+0x49A8 US_ALU_RGB_INST_58
+0x49AC US_ALU_RGB_INST_59
+0x49B0 US_ALU_RGB_INST_60
+0x49B4 US_ALU_RGB_INST_61
+0x49B8 US_ALU_RGB_INST_62
+0x49BC US_ALU_RGB_INST_63
+0x49C0 US_ALU_ALPHA_INST_0
+0x49C4 US_ALU_ALPHA_INST_1
+0x49C8 US_ALU_ALPHA_INST_2
+0x49CC US_ALU_ALPHA_INST_3
+0x49D0 US_ALU_ALPHA_INST_4
+0x49D4 US_ALU_ALPHA_INST_5
+0x49D8 US_ALU_ALPHA_INST_6
+0x49DC US_ALU_ALPHA_INST_7
+0x49E0 US_ALU_ALPHA_INST_8
+0x49E4 US_ALU_ALPHA_INST_9
+0x49E8 US_ALU_ALPHA_INST_10
+0x49EC US_ALU_ALPHA_INST_11
+0x49F0 US_ALU_ALPHA_INST_12
+0x49F4 US_ALU_ALPHA_INST_13
+0x49F8 US_ALU_ALPHA_INST_14
+0x49FC US_ALU_ALPHA_INST_15
+0x4A00 US_ALU_ALPHA_INST_16
+0x4A04 US_ALU_ALPHA_INST_17
+0x4A08 US_ALU_ALPHA_INST_18
+0x4A0C US_ALU_ALPHA_INST_19
+0x4A10 US_ALU_ALPHA_INST_20
+0x4A14 US_ALU_ALPHA_INST_21
+0x4A18 US_ALU_ALPHA_INST_22
+0x4A1C US_ALU_ALPHA_INST_23
+0x4A20 US_ALU_ALPHA_INST_24
+0x4A24 US_ALU_ALPHA_INST_25
+0x4A28 US_ALU_ALPHA_INST_26
+0x4A2C US_ALU_ALPHA_INST_27
+0x4A30 US_ALU_ALPHA_INST_28
+0x4A34 US_ALU_ALPHA_INST_29
+0x4A38 US_ALU_ALPHA_INST_30
+0x4A3C US_ALU_ALPHA_INST_31
+0x4A40 US_ALU_ALPHA_INST_32
+0x4A44 US_ALU_ALPHA_INST_33
+0x4A48 US_ALU_ALPHA_INST_34
+0x4A4C US_ALU_ALPHA_INST_35
+0x4A50 US_ALU_ALPHA_INST_36
+0x4A54 US_ALU_ALPHA_INST_37
+0x4A58 US_ALU_ALPHA_INST_38
+0x4A5C US_ALU_ALPHA_INST_39
+0x4A60 US_ALU_ALPHA_INST_40
+0x4A64 US_ALU_ALPHA_INST_41
+0x4A68 US_ALU_ALPHA_INST_42
+0x4A6C US_ALU_ALPHA_INST_43
+0x4A70 US_ALU_ALPHA_INST_44
+0x4A74 US_ALU_ALPHA_INST_45
+0x4A78 US_ALU_ALPHA_INST_46
+0x4A7C US_ALU_ALPHA_INST_47
+0x4A80 US_ALU_ALPHA_INST_48
+0x4A84 US_ALU_ALPHA_INST_49
+0x4A88 US_ALU_ALPHA_INST_50
+0x4A8C US_ALU_ALPHA_INST_51
+0x4A90 US_ALU_ALPHA_INST_52
+0x4A94 US_ALU_ALPHA_INST_53
+0x4A98 US_ALU_ALPHA_INST_54
+0x4A9C US_ALU_ALPHA_INST_55
+0x4AA0 US_ALU_ALPHA_INST_56
+0x4AA4 US_ALU_ALPHA_INST_57
+0x4AA8 US_ALU_ALPHA_INST_58
+0x4AAC US_ALU_ALPHA_INST_59
+0x4AB0 US_ALU_ALPHA_INST_60
+0x4AB4 US_ALU_ALPHA_INST_61
+0x4AB8 US_ALU_ALPHA_INST_62
+0x4ABC US_ALU_ALPHA_INST_63
+0x4BC0 FG_FOG_BLEND
+0x4BC4 FG_FOG_FACTOR
+0x4BC8 FG_FOG_COLOR_R
+0x4BCC FG_FOG_COLOR_G
+0x4BD0 FG_FOG_COLOR_B
+0x4BD4 FG_ALPHA_FUNC
+0x4BD8 FG_DEPTH_SRC
+0x4C00 US_ALU_CONST_R_0
+0x4C04 US_ALU_CONST_G_0
+0x4C08 US_ALU_CONST_B_0
+0x4C0C US_ALU_CONST_A_0
+0x4C10 US_ALU_CONST_R_1
+0x4C14 US_ALU_CONST_G_1
+0x4C18 US_ALU_CONST_B_1
+0x4C1C US_ALU_CONST_A_1
+0x4C20 US_ALU_CONST_R_2
+0x4C24 US_ALU_CONST_G_2
+0x4C28 US_ALU_CONST_B_2
+0x4C2C US_ALU_CONST_A_2
+0x4C30 US_ALU_CONST_R_3
+0x4C34 US_ALU_CONST_G_3
+0x4C38 US_ALU_CONST_B_3
+0x4C3C US_ALU_CONST_A_3
+0x4C40 US_ALU_CONST_R_4
+0x4C44 US_ALU_CONST_G_4
+0x4C48 US_ALU_CONST_B_4
+0x4C4C US_ALU_CONST_A_4
+0x4C50 US_ALU_CONST_R_5
+0x4C54 US_ALU_CONST_G_5
+0x4C58 US_ALU_CONST_B_5
+0x4C5C US_ALU_CONST_A_5
+0x4C60 US_ALU_CONST_R_6
+0x4C64 US_ALU_CONST_G_6
+0x4C68 US_ALU_CONST_B_6
+0x4C6C US_ALU_CONST_A_6
+0x4C70 US_ALU_CONST_R_7
+0x4C74 US_ALU_CONST_G_7
+0x4C78 US_ALU_CONST_B_7
+0x4C7C US_ALU_CONST_A_7
+0x4C80 US_ALU_CONST_R_8
+0x4C84 US_ALU_CONST_G_8
+0x4C88 US_ALU_CONST_B_8
+0x4C8C US_ALU_CONST_A_8
+0x4C90 US_ALU_CONST_R_9
+0x4C94 US_ALU_CONST_G_9
+0x4C98 US_ALU_CONST_B_9
+0x4C9C US_ALU_CONST_A_9
+0x4CA0 US_ALU_CONST_R_10
+0x4CA4 US_ALU_CONST_G_10
+0x4CA8 US_ALU_CONST_B_10
+0x4CAC US_ALU_CONST_A_10
+0x4CB0 US_ALU_CONST_R_11
+0x4CB4 US_ALU_CONST_G_11
+0x4CB8 US_ALU_CONST_B_11
+0x4CBC US_ALU_CONST_A_11
+0x4CC0 US_ALU_CONST_R_12
+0x4CC4 US_ALU_CONST_G_12
+0x4CC8 US_ALU_CONST_B_12
+0x4CCC US_ALU_CONST_A_12
+0x4CD0 US_ALU_CONST_R_13
+0x4CD4 US_ALU_CONST_G_13
+0x4CD8 US_ALU_CONST_B_13
+0x4CDC US_ALU_CONST_A_13
+0x4CE0 US_ALU_CONST_R_14
+0x4CE4 US_ALU_CONST_G_14
+0x4CE8 US_ALU_CONST_B_14
+0x4CEC US_ALU_CONST_A_14
+0x4CF0 US_ALU_CONST_R_15
+0x4CF4 US_ALU_CONST_G_15
+0x4CF8 US_ALU_CONST_B_15
+0x4CFC US_ALU_CONST_A_15
+0x4D00 US_ALU_CONST_R_16
+0x4D04 US_ALU_CONST_G_16
+0x4D08 US_ALU_CONST_B_16
+0x4D0C US_ALU_CONST_A_16
+0x4D10 US_ALU_CONST_R_17
+0x4D14 US_ALU_CONST_G_17
+0x4D18 US_ALU_CONST_B_17
+0x4D1C US_ALU_CONST_A_17
+0x4D20 US_ALU_CONST_R_18
+0x4D24 US_ALU_CONST_G_18
+0x4D28 US_ALU_CONST_B_18
+0x4D2C US_ALU_CONST_A_18
+0x4D30 US_ALU_CONST_R_19
+0x4D34 US_ALU_CONST_G_19
+0x4D38 US_ALU_CONST_B_19
+0x4D3C US_ALU_CONST_A_19
+0x4D40 US_ALU_CONST_R_20
+0x4D44 US_ALU_CONST_G_20
+0x4D48 US_ALU_CONST_B_20
+0x4D4C US_ALU_CONST_A_20
+0x4D50 US_ALU_CONST_R_21
+0x4D54 US_ALU_CONST_G_21
+0x4D58 US_ALU_CONST_B_21
+0x4D5C US_ALU_CONST_A_21
+0x4D60 US_ALU_CONST_R_22
+0x4D64 US_ALU_CONST_G_22
+0x4D68 US_ALU_CONST_B_22
+0x4D6C US_ALU_CONST_A_22
+0x4D70 US_ALU_CONST_R_23
+0x4D74 US_ALU_CONST_G_23
+0x4D78 US_ALU_CONST_B_23
+0x4D7C US_ALU_CONST_A_23
+0x4D80 US_ALU_CONST_R_24
+0x4D84 US_ALU_CONST_G_24
+0x4D88 US_ALU_CONST_B_24
+0x4D8C US_ALU_CONST_A_24
+0x4D90 US_ALU_CONST_R_25
+0x4D94 US_ALU_CONST_G_25
+0x4D98 US_ALU_CONST_B_25
+0x4D9C US_ALU_CONST_A_25
+0x4DA0 US_ALU_CONST_R_26
+0x4DA4 US_ALU_CONST_G_26
+0x4DA8 US_ALU_CONST_B_26
+0x4DAC US_ALU_CONST_A_26
+0x4DB0 US_ALU_CONST_R_27
+0x4DB4 US_ALU_CONST_G_27
+0x4DB8 US_ALU_CONST_B_27
+0x4DBC US_ALU_CONST_A_27
+0x4DC0 US_ALU_CONST_R_28
+0x4DC4 US_ALU_CONST_G_28
+0x4DC8 US_ALU_CONST_B_28
+0x4DCC US_ALU_CONST_A_28
+0x4DD0 US_ALU_CONST_R_29
+0x4DD4 US_ALU_CONST_G_29
+0x4DD8 US_ALU_CONST_B_29
+0x4DDC US_ALU_CONST_A_29
+0x4DE0 US_ALU_CONST_R_30
+0x4DE4 US_ALU_CONST_G_30
+0x4DE8 US_ALU_CONST_B_30
+0x4DEC US_ALU_CONST_A_30
+0x4DF0 US_ALU_CONST_R_31
+0x4DF4 US_ALU_CONST_G_31
+0x4DF8 US_ALU_CONST_B_31
+0x4DFC US_ALU_CONST_A_31
+0x4E04 RB3D_BLENDCNTL_R3
+0x4E08 RB3D_ABLENDCNTL_R3
+0x4E0C RB3D_COLOR_CHANNEL_MASK
+0x4E10 RB3D_CONSTANT_COLOR
+0x4E14 RB3D_COLOR_CLEAR_VALUE
+0x4E18 RB3D_ROPCNTL_R3
+0x4E1C RB3D_CLRCMP_FLIPE_R3
+0x4E20 RB3D_CLRCMP_CLR_R3
+0x4E24 RB3D_CLRCMP_MSK_R3
+0x4E48 RB3D_DEBUG_CTL
+0x4E4C RB3D_DSTCACHE_CTLSTAT_R3
+0x4E50 RB3D_DITHER_CTL
+0x4E54 RB3D_CMASK_OFFSET0
+0x4E58 RB3D_CMASK_OFFSET1
+0x4E5C RB3D_CMASK_OFFSET2
+0x4E60 RB3D_CMASK_OFFSET3
+0x4E64 RB3D_CMASK_PITCH0
+0x4E68 RB3D_CMASK_PITCH1
+0x4E6C RB3D_CMASK_PITCH2
+0x4E70 RB3D_CMASK_PITCH3
+0x4E74 RB3D_CMASK_WRINDEX
+0x4E78 RB3D_CMASK_DWORD
+0x4E7C RB3D_CMASK_RDINDEX
+0x4E80 RB3D_AARESOLVE_OFFSET
+0x4E84 RB3D_AARESOLVE_PITCH
+0x4E88 RB3D_AARESOLVE_CTL
+0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
+0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
+0x4F04 ZB_ZSTENCILCNTL
+0x4F08 ZB_STENCILREFMASK
+0x4F14 ZB_ZTOP
+0x4F18 ZB_ZCACHE_CTLSTAT
+0x4F1C ZB_BW_CNTL
+0x4F28 ZB_DEPTHCLEARVALUE
+0x4F30 ZB_ZMASK_OFFSET
+0x4F34 ZB_ZMASK_PITCH
+0x4F38 ZB_ZMASK_WRINDEX
+0x4F3C ZB_ZMASK_DWORD
+0x4F40 ZB_ZMASK_RDINDEX
+0x4F44 ZB_HIZ_OFFSET
+0x4F48 ZB_HIZ_WRINDEX
+0x4F4C ZB_HIZ_DWORD
+0x4F50 ZB_HIZ_RDINDEX
+0x4F54 ZB_HIZ_PITCH
+0x4F58 ZB_ZPASS_DATA
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rn50 b/drivers/gpu/drm/radeon/reg_srcs/rn50
new file mode 100644
index 0000000..2687b63
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/rn50
@@ -0,0 +1,30 @@
+rn50 0x3294
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600
new file mode 100644
index 0000000..8e3c0b8
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/rs600
@@ -0,0 +1,729 @@
+rs600 0x6d40
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1D98 VAP_VPORT_XSCALE
+0x1D9C VAP_VPORT_XOFFSET
+0x1DA0 VAP_VPORT_YSCALE
+0x1DA4 VAP_VPORT_YOFFSET
+0x1DA8 VAP_VPORT_ZSCALE
+0x1DAC VAP_VPORT_ZOFFSET
+0x2080 VAP_CNTL
+0x2090 VAP_OUT_VTX_FMT_0
+0x2094 VAP_OUT_VTX_FMT_1
+0x20B0 VAP_VTE_CNTL
+0x2138 VAP_VF_MIN_VTX_INDX
+0x2140 VAP_CNTL_STATUS
+0x2150 VAP_PROG_STREAM_CNTL_0
+0x2154 VAP_PROG_STREAM_CNTL_1
+0x2158 VAP_PROG_STREAM_CNTL_2
+0x215C VAP_PROG_STREAM_CNTL_3
+0x2160 VAP_PROG_STREAM_CNTL_4
+0x2164 VAP_PROG_STREAM_CNTL_5
+0x2168 VAP_PROG_STREAM_CNTL_6
+0x216C VAP_PROG_STREAM_CNTL_7
+0x2180 VAP_VTX_STATE_CNTL
+0x2184 VAP_VSM_VTX_ASSM
+0x2188 VAP_VTX_STATE_IND_REG_0
+0x218C VAP_VTX_STATE_IND_REG_1
+0x2190 VAP_VTX_STATE_IND_REG_2
+0x2194 VAP_VTX_STATE_IND_REG_3
+0x2198 VAP_VTX_STATE_IND_REG_4
+0x219C VAP_VTX_STATE_IND_REG_5
+0x21A0 VAP_VTX_STATE_IND_REG_6
+0x21A4 VAP_VTX_STATE_IND_REG_7
+0x21A8 VAP_VTX_STATE_IND_REG_8
+0x21AC VAP_VTX_STATE_IND_REG_9
+0x21B0 VAP_VTX_STATE_IND_REG_10
+0x21B4 VAP_VTX_STATE_IND_REG_11
+0x21B8 VAP_VTX_STATE_IND_REG_12
+0x21BC VAP_VTX_STATE_IND_REG_13
+0x21C0 VAP_VTX_STATE_IND_REG_14
+0x21C4 VAP_VTX_STATE_IND_REG_15
+0x21DC VAP_PSC_SGN_NORM_CNTL
+0x21E0 VAP_PROG_STREAM_CNTL_EXT_0
+0x21E4 VAP_PROG_STREAM_CNTL_EXT_1
+0x21E8 VAP_PROG_STREAM_CNTL_EXT_2
+0x21EC VAP_PROG_STREAM_CNTL_EXT_3
+0x21F0 VAP_PROG_STREAM_CNTL_EXT_4
+0x21F4 VAP_PROG_STREAM_CNTL_EXT_5
+0x21F8 VAP_PROG_STREAM_CNTL_EXT_6
+0x21FC VAP_PROG_STREAM_CNTL_EXT_7
+0x2200 VAP_PVS_VECTOR_INDX_REG
+0x2204 VAP_PVS_VECTOR_DATA_REG
+0x2208 VAP_PVS_VECTOR_DATA_REG_128
+0x221C VAP_CLIP_CNTL
+0x2220 VAP_GB_VERT_CLIP_ADJ
+0x2224 VAP_GB_VERT_DISC_ADJ
+0x2228 VAP_GB_HORZ_CLIP_ADJ
+0x222C VAP_GB_HORZ_DISC_ADJ
+0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0
+0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1
+0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2
+0x223C VAP_PVS_FLOW_CNTL_ADDRS_3
+0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4
+0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5
+0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6
+0x224C VAP_PVS_FLOW_CNTL_ADDRS_7
+0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8
+0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9
+0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10
+0x225C VAP_PVS_FLOW_CNTL_ADDRS_11
+0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12
+0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13
+0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14
+0x226C VAP_PVS_FLOW_CNTL_ADDRS_15
+0x2284 VAP_PVS_STATE_FLUSH_REG
+0x2288 VAP_PVS_VTX_TIMEOUT_REG
+0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0
+0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1
+0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2
+0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3
+0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4
+0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5
+0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6
+0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7
+0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8
+0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9
+0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10
+0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11
+0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12
+0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13
+0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14
+0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15
+0x22D0 VAP_PVS_CODE_CNTL_0
+0x22D4 VAP_PVS_CONST_CNTL
+0x22D8 VAP_PVS_CODE_CNTL_1
+0x22DC VAP_PVS_FLOW_CNTL_OPC
+0x342C RB2D_DSTCACHE_CTLSTAT
+0x4000 GB_VAP_RASTER_VTX_FMT_0
+0x4004 GB_VAP_RASTER_VTX_FMT_1
+0x4008 GB_ENABLE
+0x401C GB_SELECT
+0x4020 GB_AA_CONFIG
+0x4024 GB_FIFO_SIZE
+0x4100 TX_INVALTAGS
+0x4200 GA_POINT_S0
+0x4204 GA_POINT_T0
+0x4208 GA_POINT_S1
+0x420C GA_POINT_T1
+0x4214 GA_TRIANGLE_STIPPLE
+0x421C GA_POINT_SIZE
+0x4230 GA_POINT_MINMAX
+0x4234 GA_LINE_CNTL
+0x4238 GA_LINE_STIPPLE_CONFIG
+0x4260 GA_LINE_STIPPLE_VALUE
+0x4264 GA_LINE_S0
+0x4268 GA_LINE_S1
+0x4278 GA_COLOR_CONTROL
+0x427C GA_SOLID_RG
+0x4280 GA_SOLID_BA
+0x4288 GA_POLY_MODE
+0x428C GA_ROUND_MODE
+0x4290 GA_OFFSET
+0x4294 GA_FOG_SCALE
+0x4298 GA_FOG_OFFSET
+0x42A0 SU_TEX_WRAP
+0x42A4 SU_POLY_OFFSET_FRONT_SCALE
+0x42A8 SU_POLY_OFFSET_FRONT_OFFSET
+0x42AC SU_POLY_OFFSET_BACK_SCALE
+0x42B0 SU_POLY_OFFSET_BACK_OFFSET 
+0x42B4 SU_POLY_OFFSET_ENABLE
+0x42B8 SU_CULL_MODE
+0x42C0 SU_DEPTH_SCALE
+0x42C4 SU_DEPTH_OFFSET
+0x42C8 SU_REG_DEST
+0x4300 RS_COUNT
+0x4304 RS_INST_COUNT
+0x4310 RS_IP_0
+0x4314 RS_IP_1
+0x4318 RS_IP_2
+0x431C RS_IP_3
+0x4320 RS_IP_4
+0x4324 RS_IP_5
+0x4328 RS_IP_6
+0x432C RS_IP_7
+0x4330 RS_INST_0
+0x4334 RS_INST_1
+0x4338 RS_INST_2
+0x433C RS_INST_3
+0x4340 RS_INST_4
+0x4344 RS_INST_5
+0x4348 RS_INST_6
+0x434C RS_INST_7
+0x4350 RS_INST_8
+0x4354 RS_INST_9
+0x4358 RS_INST_10
+0x435C RS_INST_11
+0x4360 RS_INST_12
+0x4364 RS_INST_13
+0x4368 RS_INST_14
+0x436C RS_INST_15
+0x43A4 SC_HYPERZ_EN
+0x43A8 SC_EDGERULE
+0x43B0 SC_CLIP_0_A
+0x43B4 SC_CLIP_0_B
+0x43B8 SC_CLIP_1_A
+0x43BC SC_CLIP_1_B
+0x43C0 SC_CLIP_2_A
+0x43C4 SC_CLIP_2_B
+0x43C8 SC_CLIP_3_A
+0x43CC SC_CLIP_3_B
+0x43D0 SC_CLIP_RULE
+0x43E0 SC_SCISSOR0
+0x43E8 SC_SCREENDOOR
+0x4440 TX_FILTER1_0
+0x4444 TX_FILTER1_1
+0x4448 TX_FILTER1_2
+0x444C TX_FILTER1_3
+0x4450 TX_FILTER1_4
+0x4454 TX_FILTER1_5
+0x4458 TX_FILTER1_6
+0x445C TX_FILTER1_7
+0x4460 TX_FILTER1_8
+0x4464 TX_FILTER1_9
+0x4468 TX_FILTER1_10
+0x446C TX_FILTER1_11
+0x4470 TX_FILTER1_12
+0x4474 TX_FILTER1_13
+0x4478 TX_FILTER1_14
+0x447C TX_FILTER1_15
+0x4580 TX_CHROMA_KEY_0
+0x4584 TX_CHROMA_KEY_1
+0x4588 TX_CHROMA_KEY_2
+0x458C TX_CHROMA_KEY_3
+0x4590 TX_CHROMA_KEY_4
+0x4594 TX_CHROMA_KEY_5
+0x4598 TX_CHROMA_KEY_6
+0x459C TX_CHROMA_KEY_7
+0x45A0 TX_CHROMA_KEY_8
+0x45A4 TX_CHROMA_KEY_9
+0x45A8 TX_CHROMA_KEY_10
+0x45AC TX_CHROMA_KEY_11
+0x45B0 TX_CHROMA_KEY_12
+0x45B4 TX_CHROMA_KEY_13
+0x45B8 TX_CHROMA_KEY_14
+0x45BC TX_CHROMA_KEY_15
+0x45C0 TX_BORDER_COLOR_0
+0x45C4 TX_BORDER_COLOR_1
+0x45C8 TX_BORDER_COLOR_2
+0x45CC TX_BORDER_COLOR_3
+0x45D0 TX_BORDER_COLOR_4
+0x45D4 TX_BORDER_COLOR_5
+0x45D8 TX_BORDER_COLOR_6
+0x45DC TX_BORDER_COLOR_7
+0x45E0 TX_BORDER_COLOR_8
+0x45E4 TX_BORDER_COLOR_9
+0x45E8 TX_BORDER_COLOR_10
+0x45EC TX_BORDER_COLOR_11
+0x45F0 TX_BORDER_COLOR_12
+0x45F4 TX_BORDER_COLOR_13
+0x45F8 TX_BORDER_COLOR_14
+0x45FC TX_BORDER_COLOR_15
+0x4600 US_CONFIG
+0x4604 US_PIXSIZE
+0x4608 US_CODE_OFFSET
+0x460C US_RESET
+0x4610 US_CODE_ADDR_0
+0x4614 US_CODE_ADDR_1
+0x4618 US_CODE_ADDR_2
+0x461C US_CODE_ADDR_3
+0x4620 US_TEX_INST_0
+0x4624 US_TEX_INST_1
+0x4628 US_TEX_INST_2
+0x462C US_TEX_INST_3
+0x4630 US_TEX_INST_4
+0x4634 US_TEX_INST_5
+0x4638 US_TEX_INST_6
+0x463C US_TEX_INST_7
+0x4640 US_TEX_INST_8
+0x4644 US_TEX_INST_9
+0x4648 US_TEX_INST_10
+0x464C US_TEX_INST_11
+0x4650 US_TEX_INST_12
+0x4654 US_TEX_INST_13
+0x4658 US_TEX_INST_14
+0x465C US_TEX_INST_15
+0x4660 US_TEX_INST_16
+0x4664 US_TEX_INST_17
+0x4668 US_TEX_INST_18
+0x466C US_TEX_INST_19
+0x4670 US_TEX_INST_20
+0x4674 US_TEX_INST_21
+0x4678 US_TEX_INST_22
+0x467C US_TEX_INST_23
+0x4680 US_TEX_INST_24
+0x4684 US_TEX_INST_25
+0x4688 US_TEX_INST_26
+0x468C US_TEX_INST_27
+0x4690 US_TEX_INST_28
+0x4694 US_TEX_INST_29
+0x4698 US_TEX_INST_30
+0x469C US_TEX_INST_31
+0x46A4 US_OUT_FMT_0
+0x46A8 US_OUT_FMT_1
+0x46AC US_OUT_FMT_2
+0x46B0 US_OUT_FMT_3
+0x46B4 US_W_FMT
+0x46C0 US_ALU_RGB_ADDR_0
+0x46C4 US_ALU_RGB_ADDR_1
+0x46C8 US_ALU_RGB_ADDR_2
+0x46CC US_ALU_RGB_ADDR_3
+0x46D0 US_ALU_RGB_ADDR_4
+0x46D4 US_ALU_RGB_ADDR_5
+0x46D8 US_ALU_RGB_ADDR_6
+0x46DC US_ALU_RGB_ADDR_7
+0x46E0 US_ALU_RGB_ADDR_8
+0x46E4 US_ALU_RGB_ADDR_9
+0x46E8 US_ALU_RGB_ADDR_10
+0x46EC US_ALU_RGB_ADDR_11
+0x46F0 US_ALU_RGB_ADDR_12
+0x46F4 US_ALU_RGB_ADDR_13
+0x46F8 US_ALU_RGB_ADDR_14
+0x46FC US_ALU_RGB_ADDR_15
+0x4700 US_ALU_RGB_ADDR_16
+0x4704 US_ALU_RGB_ADDR_17
+0x4708 US_ALU_RGB_ADDR_18
+0x470C US_ALU_RGB_ADDR_19
+0x4710 US_ALU_RGB_ADDR_20
+0x4714 US_ALU_RGB_ADDR_21
+0x4718 US_ALU_RGB_ADDR_22
+0x471C US_ALU_RGB_ADDR_23
+0x4720 US_ALU_RGB_ADDR_24
+0x4724 US_ALU_RGB_ADDR_25
+0x4728 US_ALU_RGB_ADDR_26
+0x472C US_ALU_RGB_ADDR_27
+0x4730 US_ALU_RGB_ADDR_28
+0x4734 US_ALU_RGB_ADDR_29
+0x4738 US_ALU_RGB_ADDR_30
+0x473C US_ALU_RGB_ADDR_31
+0x4740 US_ALU_RGB_ADDR_32
+0x4744 US_ALU_RGB_ADDR_33
+0x4748 US_ALU_RGB_ADDR_34
+0x474C US_ALU_RGB_ADDR_35
+0x4750 US_ALU_RGB_ADDR_36
+0x4754 US_ALU_RGB_ADDR_37
+0x4758 US_ALU_RGB_ADDR_38
+0x475C US_ALU_RGB_ADDR_39
+0x4760 US_ALU_RGB_ADDR_40
+0x4764 US_ALU_RGB_ADDR_41
+0x4768 US_ALU_RGB_ADDR_42
+0x476C US_ALU_RGB_ADDR_43
+0x4770 US_ALU_RGB_ADDR_44
+0x4774 US_ALU_RGB_ADDR_45
+0x4778 US_ALU_RGB_ADDR_46
+0x477C US_ALU_RGB_ADDR_47
+0x4780 US_ALU_RGB_ADDR_48
+0x4784 US_ALU_RGB_ADDR_49
+0x4788 US_ALU_RGB_ADDR_50
+0x478C US_ALU_RGB_ADDR_51
+0x4790 US_ALU_RGB_ADDR_52
+0x4794 US_ALU_RGB_ADDR_53
+0x4798 US_ALU_RGB_ADDR_54
+0x479C US_ALU_RGB_ADDR_55
+0x47A0 US_ALU_RGB_ADDR_56
+0x47A4 US_ALU_RGB_ADDR_57
+0x47A8 US_ALU_RGB_ADDR_58
+0x47AC US_ALU_RGB_ADDR_59
+0x47B0 US_ALU_RGB_ADDR_60
+0x47B4 US_ALU_RGB_ADDR_61
+0x47B8 US_ALU_RGB_ADDR_62
+0x47BC US_ALU_RGB_ADDR_63
+0x47C0 US_ALU_ALPHA_ADDR_0
+0x47C4 US_ALU_ALPHA_ADDR_1
+0x47C8 US_ALU_ALPHA_ADDR_2
+0x47CC US_ALU_ALPHA_ADDR_3
+0x47D0 US_ALU_ALPHA_ADDR_4
+0x47D4 US_ALU_ALPHA_ADDR_5
+0x47D8 US_ALU_ALPHA_ADDR_6
+0x47DC US_ALU_ALPHA_ADDR_7
+0x47E0 US_ALU_ALPHA_ADDR_8
+0x47E4 US_ALU_ALPHA_ADDR_9
+0x47E8 US_ALU_ALPHA_ADDR_10
+0x47EC US_ALU_ALPHA_ADDR_11
+0x47F0 US_ALU_ALPHA_ADDR_12
+0x47F4 US_ALU_ALPHA_ADDR_13
+0x47F8 US_ALU_ALPHA_ADDR_14
+0x47FC US_ALU_ALPHA_ADDR_15
+0x4800 US_ALU_ALPHA_ADDR_16
+0x4804 US_ALU_ALPHA_ADDR_17
+0x4808 US_ALU_ALPHA_ADDR_18
+0x480C US_ALU_ALPHA_ADDR_19
+0x4810 US_ALU_ALPHA_ADDR_20
+0x4814 US_ALU_ALPHA_ADDR_21
+0x4818 US_ALU_ALPHA_ADDR_22
+0x481C US_ALU_ALPHA_ADDR_23
+0x4820 US_ALU_ALPHA_ADDR_24
+0x4824 US_ALU_ALPHA_ADDR_25
+0x4828 US_ALU_ALPHA_ADDR_26
+0x482C US_ALU_ALPHA_ADDR_27
+0x4830 US_ALU_ALPHA_ADDR_28
+0x4834 US_ALU_ALPHA_ADDR_29
+0x4838 US_ALU_ALPHA_ADDR_30
+0x483C US_ALU_ALPHA_ADDR_31
+0x4840 US_ALU_ALPHA_ADDR_32
+0x4844 US_ALU_ALPHA_ADDR_33
+0x4848 US_ALU_ALPHA_ADDR_34
+0x484C US_ALU_ALPHA_ADDR_35
+0x4850 US_ALU_ALPHA_ADDR_36
+0x4854 US_ALU_ALPHA_ADDR_37
+0x4858 US_ALU_ALPHA_ADDR_38
+0x485C US_ALU_ALPHA_ADDR_39
+0x4860 US_ALU_ALPHA_ADDR_40
+0x4864 US_ALU_ALPHA_ADDR_41
+0x4868 US_ALU_ALPHA_ADDR_42
+0x486C US_ALU_ALPHA_ADDR_43
+0x4870 US_ALU_ALPHA_ADDR_44
+0x4874 US_ALU_ALPHA_ADDR_45
+0x4878 US_ALU_ALPHA_ADDR_46
+0x487C US_ALU_ALPHA_ADDR_47
+0x4880 US_ALU_ALPHA_ADDR_48
+0x4884 US_ALU_ALPHA_ADDR_49
+0x4888 US_ALU_ALPHA_ADDR_50
+0x488C US_ALU_ALPHA_ADDR_51
+0x4890 US_ALU_ALPHA_ADDR_52
+0x4894 US_ALU_ALPHA_ADDR_53
+0x4898 US_ALU_ALPHA_ADDR_54
+0x489C US_ALU_ALPHA_ADDR_55
+0x48A0 US_ALU_ALPHA_ADDR_56
+0x48A4 US_ALU_ALPHA_ADDR_57
+0x48A8 US_ALU_ALPHA_ADDR_58
+0x48AC US_ALU_ALPHA_ADDR_59
+0x48B0 US_ALU_ALPHA_ADDR_60
+0x48B4 US_ALU_ALPHA_ADDR_61
+0x48B8 US_ALU_ALPHA_ADDR_62
+0x48BC US_ALU_ALPHA_ADDR_63
+0x48C0 US_ALU_RGB_INST_0
+0x48C4 US_ALU_RGB_INST_1
+0x48C8 US_ALU_RGB_INST_2
+0x48CC US_ALU_RGB_INST_3
+0x48D0 US_ALU_RGB_INST_4
+0x48D4 US_ALU_RGB_INST_5
+0x48D8 US_ALU_RGB_INST_6
+0x48DC US_ALU_RGB_INST_7
+0x48E0 US_ALU_RGB_INST_8
+0x48E4 US_ALU_RGB_INST_9
+0x48E8 US_ALU_RGB_INST_10
+0x48EC US_ALU_RGB_INST_11
+0x48F0 US_ALU_RGB_INST_12
+0x48F4 US_ALU_RGB_INST_13
+0x48F8 US_ALU_RGB_INST_14
+0x48FC US_ALU_RGB_INST_15
+0x4900 US_ALU_RGB_INST_16
+0x4904 US_ALU_RGB_INST_17
+0x4908 US_ALU_RGB_INST_18
+0x490C US_ALU_RGB_INST_19
+0x4910 US_ALU_RGB_INST_20
+0x4914 US_ALU_RGB_INST_21
+0x4918 US_ALU_RGB_INST_22
+0x491C US_ALU_RGB_INST_23
+0x4920 US_ALU_RGB_INST_24
+0x4924 US_ALU_RGB_INST_25
+0x4928 US_ALU_RGB_INST_26
+0x492C US_ALU_RGB_INST_27
+0x4930 US_ALU_RGB_INST_28
+0x4934 US_ALU_RGB_INST_29
+0x4938 US_ALU_RGB_INST_30
+0x493C US_ALU_RGB_INST_31
+0x4940 US_ALU_RGB_INST_32
+0x4944 US_ALU_RGB_INST_33
+0x4948 US_ALU_RGB_INST_34
+0x494C US_ALU_RGB_INST_35
+0x4950 US_ALU_RGB_INST_36
+0x4954 US_ALU_RGB_INST_37
+0x4958 US_ALU_RGB_INST_38
+0x495C US_ALU_RGB_INST_39
+0x4960 US_ALU_RGB_INST_40
+0x4964 US_ALU_RGB_INST_41
+0x4968 US_ALU_RGB_INST_42
+0x496C US_ALU_RGB_INST_43
+0x4970 US_ALU_RGB_INST_44
+0x4974 US_ALU_RGB_INST_45
+0x4978 US_ALU_RGB_INST_46
+0x497C US_ALU_RGB_INST_47
+0x4980 US_ALU_RGB_INST_48
+0x4984 US_ALU_RGB_INST_49
+0x4988 US_ALU_RGB_INST_50
+0x498C US_ALU_RGB_INST_51
+0x4990 US_ALU_RGB_INST_52
+0x4994 US_ALU_RGB_INST_53
+0x4998 US_ALU_RGB_INST_54
+0x499C US_ALU_RGB_INST_55
+0x49A0 US_ALU_RGB_INST_56
+0x49A4 US_ALU_RGB_INST_57
+0x49A8 US_ALU_RGB_INST_58
+0x49AC US_ALU_RGB_INST_59
+0x49B0 US_ALU_RGB_INST_60
+0x49B4 US_ALU_RGB_INST_61
+0x49B8 US_ALU_RGB_INST_62
+0x49BC US_ALU_RGB_INST_63
+0x49C0 US_ALU_ALPHA_INST_0
+0x49C4 US_ALU_ALPHA_INST_1
+0x49C8 US_ALU_ALPHA_INST_2
+0x49CC US_ALU_ALPHA_INST_3
+0x49D0 US_ALU_ALPHA_INST_4
+0x49D4 US_ALU_ALPHA_INST_5
+0x49D8 US_ALU_ALPHA_INST_6
+0x49DC US_ALU_ALPHA_INST_7
+0x49E0 US_ALU_ALPHA_INST_8
+0x49E4 US_ALU_ALPHA_INST_9
+0x49E8 US_ALU_ALPHA_INST_10
+0x49EC US_ALU_ALPHA_INST_11
+0x49F0 US_ALU_ALPHA_INST_12
+0x49F4 US_ALU_ALPHA_INST_13
+0x49F8 US_ALU_ALPHA_INST_14
+0x49FC US_ALU_ALPHA_INST_15
+0x4A00 US_ALU_ALPHA_INST_16
+0x4A04 US_ALU_ALPHA_INST_17
+0x4A08 US_ALU_ALPHA_INST_18
+0x4A0C US_ALU_ALPHA_INST_19
+0x4A10 US_ALU_ALPHA_INST_20
+0x4A14 US_ALU_ALPHA_INST_21
+0x4A18 US_ALU_ALPHA_INST_22
+0x4A1C US_ALU_ALPHA_INST_23
+0x4A20 US_ALU_ALPHA_INST_24
+0x4A24 US_ALU_ALPHA_INST_25
+0x4A28 US_ALU_ALPHA_INST_26
+0x4A2C US_ALU_ALPHA_INST_27
+0x4A30 US_ALU_ALPHA_INST_28
+0x4A34 US_ALU_ALPHA_INST_29
+0x4A38 US_ALU_ALPHA_INST_30
+0x4A3C US_ALU_ALPHA_INST_31
+0x4A40 US_ALU_ALPHA_INST_32
+0x4A44 US_ALU_ALPHA_INST_33
+0x4A48 US_ALU_ALPHA_INST_34
+0x4A4C US_ALU_ALPHA_INST_35
+0x4A50 US_ALU_ALPHA_INST_36
+0x4A54 US_ALU_ALPHA_INST_37
+0x4A58 US_ALU_ALPHA_INST_38
+0x4A5C US_ALU_ALPHA_INST_39
+0x4A60 US_ALU_ALPHA_INST_40
+0x4A64 US_ALU_ALPHA_INST_41
+0x4A68 US_ALU_ALPHA_INST_42
+0x4A6C US_ALU_ALPHA_INST_43
+0x4A70 US_ALU_ALPHA_INST_44
+0x4A74 US_ALU_ALPHA_INST_45
+0x4A78 US_ALU_ALPHA_INST_46
+0x4A7C US_ALU_ALPHA_INST_47
+0x4A80 US_ALU_ALPHA_INST_48
+0x4A84 US_ALU_ALPHA_INST_49
+0x4A88 US_ALU_ALPHA_INST_50
+0x4A8C US_ALU_ALPHA_INST_51
+0x4A90 US_ALU_ALPHA_INST_52
+0x4A94 US_ALU_ALPHA_INST_53
+0x4A98 US_ALU_ALPHA_INST_54
+0x4A9C US_ALU_ALPHA_INST_55
+0x4AA0 US_ALU_ALPHA_INST_56
+0x4AA4 US_ALU_ALPHA_INST_57
+0x4AA8 US_ALU_ALPHA_INST_58
+0x4AAC US_ALU_ALPHA_INST_59
+0x4AB0 US_ALU_ALPHA_INST_60
+0x4AB4 US_ALU_ALPHA_INST_61
+0x4AB8 US_ALU_ALPHA_INST_62
+0x4ABC US_ALU_ALPHA_INST_63
+0x4BC0 FG_FOG_BLEND
+0x4BC4 FG_FOG_FACTOR
+0x4BC8 FG_FOG_COLOR_R
+0x4BCC FG_FOG_COLOR_G
+0x4BD0 FG_FOG_COLOR_B
+0x4BD4 FG_ALPHA_FUNC
+0x4BD8 FG_DEPTH_SRC
+0x4C00 US_ALU_CONST_R_0
+0x4C04 US_ALU_CONST_G_0
+0x4C08 US_ALU_CONST_B_0
+0x4C0C US_ALU_CONST_A_0
+0x4C10 US_ALU_CONST_R_1
+0x4C14 US_ALU_CONST_G_1
+0x4C18 US_ALU_CONST_B_1
+0x4C1C US_ALU_CONST_A_1
+0x4C20 US_ALU_CONST_R_2
+0x4C24 US_ALU_CONST_G_2
+0x4C28 US_ALU_CONST_B_2
+0x4C2C US_ALU_CONST_A_2
+0x4C30 US_ALU_CONST_R_3
+0x4C34 US_ALU_CONST_G_3
+0x4C38 US_ALU_CONST_B_3
+0x4C3C US_ALU_CONST_A_3
+0x4C40 US_ALU_CONST_R_4
+0x4C44 US_ALU_CONST_G_4
+0x4C48 US_ALU_CONST_B_4
+0x4C4C US_ALU_CONST_A_4
+0x4C50 US_ALU_CONST_R_5
+0x4C54 US_ALU_CONST_G_5
+0x4C58 US_ALU_CONST_B_5
+0x4C5C US_ALU_CONST_A_5
+0x4C60 US_ALU_CONST_R_6
+0x4C64 US_ALU_CONST_G_6
+0x4C68 US_ALU_CONST_B_6
+0x4C6C US_ALU_CONST_A_6
+0x4C70 US_ALU_CONST_R_7
+0x4C74 US_ALU_CONST_G_7
+0x4C78 US_ALU_CONST_B_7
+0x4C7C US_ALU_CONST_A_7
+0x4C80 US_ALU_CONST_R_8
+0x4C84 US_ALU_CONST_G_8
+0x4C88 US_ALU_CONST_B_8
+0x4C8C US_ALU_CONST_A_8
+0x4C90 US_ALU_CONST_R_9
+0x4C94 US_ALU_CONST_G_9
+0x4C98 US_ALU_CONST_B_9
+0x4C9C US_ALU_CONST_A_9
+0x4CA0 US_ALU_CONST_R_10
+0x4CA4 US_ALU_CONST_G_10
+0x4CA8 US_ALU_CONST_B_10
+0x4CAC US_ALU_CONST_A_10
+0x4CB0 US_ALU_CONST_R_11
+0x4CB4 US_ALU_CONST_G_11
+0x4CB8 US_ALU_CONST_B_11
+0x4CBC US_ALU_CONST_A_11
+0x4CC0 US_ALU_CONST_R_12
+0x4CC4 US_ALU_CONST_G_12
+0x4CC8 US_ALU_CONST_B_12
+0x4CCC US_ALU_CONST_A_12
+0x4CD0 US_ALU_CONST_R_13
+0x4CD4 US_ALU_CONST_G_13
+0x4CD8 US_ALU_CONST_B_13
+0x4CDC US_ALU_CONST_A_13
+0x4CE0 US_ALU_CONST_R_14
+0x4CE4 US_ALU_CONST_G_14
+0x4CE8 US_ALU_CONST_B_14
+0x4CEC US_ALU_CONST_A_14
+0x4CF0 US_ALU_CONST_R_15
+0x4CF4 US_ALU_CONST_G_15
+0x4CF8 US_ALU_CONST_B_15
+0x4CFC US_ALU_CONST_A_15
+0x4D00 US_ALU_CONST_R_16
+0x4D04 US_ALU_CONST_G_16
+0x4D08 US_ALU_CONST_B_16
+0x4D0C US_ALU_CONST_A_16
+0x4D10 US_ALU_CONST_R_17
+0x4D14 US_ALU_CONST_G_17
+0x4D18 US_ALU_CONST_B_17
+0x4D1C US_ALU_CONST_A_17
+0x4D20 US_ALU_CONST_R_18
+0x4D24 US_ALU_CONST_G_18
+0x4D28 US_ALU_CONST_B_18
+0x4D2C US_ALU_CONST_A_18
+0x4D30 US_ALU_CONST_R_19
+0x4D34 US_ALU_CONST_G_19
+0x4D38 US_ALU_CONST_B_19
+0x4D3C US_ALU_CONST_A_19
+0x4D40 US_ALU_CONST_R_20
+0x4D44 US_ALU_CONST_G_20
+0x4D48 US_ALU_CONST_B_20
+0x4D4C US_ALU_CONST_A_20
+0x4D50 US_ALU_CONST_R_21
+0x4D54 US_ALU_CONST_G_21
+0x4D58 US_ALU_CONST_B_21
+0x4D5C US_ALU_CONST_A_21
+0x4D60 US_ALU_CONST_R_22
+0x4D64 US_ALU_CONST_G_22
+0x4D68 US_ALU_CONST_B_22
+0x4D6C US_ALU_CONST_A_22
+0x4D70 US_ALU_CONST_R_23
+0x4D74 US_ALU_CONST_G_23
+0x4D78 US_ALU_CONST_B_23
+0x4D7C US_ALU_CONST_A_23
+0x4D80 US_ALU_CONST_R_24
+0x4D84 US_ALU_CONST_G_24
+0x4D88 US_ALU_CONST_B_24
+0x4D8C US_ALU_CONST_A_24
+0x4D90 US_ALU_CONST_R_25
+0x4D94 US_ALU_CONST_G_25
+0x4D98 US_ALU_CONST_B_25
+0x4D9C US_ALU_CONST_A_25
+0x4DA0 US_ALU_CONST_R_26
+0x4DA4 US_ALU_CONST_G_26
+0x4DA8 US_ALU_CONST_B_26
+0x4DAC US_ALU_CONST_A_26
+0x4DB0 US_ALU_CONST_R_27
+0x4DB4 US_ALU_CONST_G_27
+0x4DB8 US_ALU_CONST_B_27
+0x4DBC US_ALU_CONST_A_27
+0x4DC0 US_ALU_CONST_R_28
+0x4DC4 US_ALU_CONST_G_28
+0x4DC8 US_ALU_CONST_B_28
+0x4DCC US_ALU_CONST_A_28
+0x4DD0 US_ALU_CONST_R_29
+0x4DD4 US_ALU_CONST_G_29
+0x4DD8 US_ALU_CONST_B_29
+0x4DDC US_ALU_CONST_A_29
+0x4DE0 US_ALU_CONST_R_30
+0x4DE4 US_ALU_CONST_G_30
+0x4DE8 US_ALU_CONST_B_30
+0x4DEC US_ALU_CONST_A_30
+0x4DF0 US_ALU_CONST_R_31
+0x4DF4 US_ALU_CONST_G_31
+0x4DF8 US_ALU_CONST_B_31
+0x4DFC US_ALU_CONST_A_31
+0x4E04 RB3D_BLENDCNTL_R3
+0x4E08 RB3D_ABLENDCNTL_R3
+0x4E0C RB3D_COLOR_CHANNEL_MASK
+0x4E10 RB3D_CONSTANT_COLOR
+0x4E14 RB3D_COLOR_CLEAR_VALUE
+0x4E18 RB3D_ROPCNTL_R3
+0x4E1C RB3D_CLRCMP_FLIPE_R3
+0x4E20 RB3D_CLRCMP_CLR_R3
+0x4E24 RB3D_CLRCMP_MSK_R3
+0x4E48 RB3D_DEBUG_CTL
+0x4E4C RB3D_DSTCACHE_CTLSTAT_R3
+0x4E50 RB3D_DITHER_CTL
+0x4E54 RB3D_CMASK_OFFSET0
+0x4E58 RB3D_CMASK_OFFSET1
+0x4E5C RB3D_CMASK_OFFSET2
+0x4E60 RB3D_CMASK_OFFSET3
+0x4E64 RB3D_CMASK_PITCH0
+0x4E68 RB3D_CMASK_PITCH1
+0x4E6C RB3D_CMASK_PITCH2
+0x4E70 RB3D_CMASK_PITCH3
+0x4E74 RB3D_CMASK_WRINDEX
+0x4E78 RB3D_CMASK_DWORD
+0x4E7C RB3D_CMASK_RDINDEX
+0x4E80 RB3D_AARESOLVE_OFFSET
+0x4E84 RB3D_AARESOLVE_PITCH
+0x4E88 RB3D_AARESOLVE_CTL
+0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
+0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
+0x4F04 ZB_ZSTENCILCNTL
+0x4F08 ZB_STENCILREFMASK
+0x4F14 ZB_ZTOP
+0x4F18 ZB_ZCACHE_CTLSTAT
+0x4F1C ZB_BW_CNTL
+0x4F28 ZB_DEPTHCLEARVALUE
+0x4F30 ZB_ZMASK_OFFSET
+0x4F34 ZB_ZMASK_PITCH
+0x4F38 ZB_ZMASK_WRINDEX
+0x4F3C ZB_ZMASK_DWORD
+0x4F40 ZB_ZMASK_RDINDEX
+0x4F44 ZB_HIZ_OFFSET
+0x4F48 ZB_HIZ_WRINDEX
+0x4F4C ZB_HIZ_DWORD
+0x4F50 ZB_HIZ_RDINDEX
+0x4F54 ZB_HIZ_PITCH
+0x4F58 ZB_ZPASS_DATA
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515
new file mode 100644
index 0000000..0102a0d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/reg_srcs/rv515
@@ -0,0 +1,486 @@
+rv515 0x6d40
+0x1434 SRC_Y_X
+0x1438 DST_Y_X
+0x143C DST_HEIGHT_WIDTH
+0x146C DP_GUI_MASTER_CNTL
+0x1474 BRUSH_Y_X
+0x1478 DP_BRUSH_BKGD_CLR
+0x147C DP_BRUSH_FRGD_CLR
+0x1480 BRUSH_DATA0
+0x1484 BRUSH_DATA1
+0x1598 DST_WIDTH_HEIGHT
+0x15C0 CLR_CMP_CNTL
+0x15C4 CLR_CMP_CLR_SRC
+0x15C8 CLR_CMP_CLR_DST
+0x15CC CLR_CMP_MSK
+0x15D8 DP_SRC_FRGD_CLR
+0x15DC DP_SRC_BKGD_CLR
+0x1600 DST_LINE_START
+0x1604 DST_LINE_END
+0x1608 DST_LINE_PATCOUNT
+0x16C0 DP_CNTL
+0x16CC DP_WRITE_MSK
+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR
+0x16E8 DEFAULT_SC_BOTTOM_RIGHT
+0x16EC SC_TOP_LEFT
+0x16F0 SC_BOTTOM_RIGHT
+0x16F4 SRC_SC_BOTTOM_RIGHT
+0x1714 DSTCACHE_CTLSTAT
+0x1720 WAIT_UNTIL
+0x172C RBBM_GUICNTL
+0x1D98 VAP_VPORT_XSCALE
+0x1D9C VAP_VPORT_XOFFSET
+0x1DA0 VAP_VPORT_YSCALE
+0x1DA4 VAP_VPORT_YOFFSET
+0x1DA8 VAP_VPORT_ZSCALE
+0x1DAC VAP_VPORT_ZOFFSET
+0x2080 VAP_CNTL
+0x2090 VAP_OUT_VTX_FMT_0
+0x2094 VAP_OUT_VTX_FMT_1
+0x20B0 VAP_VTE_CNTL
+0x2138 VAP_VF_MIN_VTX_INDX
+0x2140 VAP_CNTL_STATUS
+0x2150 VAP_PROG_STREAM_CNTL_0
+0x2154 VAP_PROG_STREAM_CNTL_1
+0x2158 VAP_PROG_STREAM_CNTL_2
+0x215C VAP_PROG_STREAM_CNTL_3
+0x2160 VAP_PROG_STREAM_CNTL_4
+0x2164 VAP_PROG_STREAM_CNTL_5
+0x2168 VAP_PROG_STREAM_CNTL_6
+0x216C VAP_PROG_STREAM_CNTL_7
+0x2180 VAP_VTX_STATE_CNTL
+0x2184 VAP_VSM_VTX_ASSM
+0x2188 VAP_VTX_STATE_IND_REG_0
+0x218C VAP_VTX_STATE_IND_REG_1
+0x2190 VAP_VTX_STATE_IND_REG_2
+0x2194 VAP_VTX_STATE_IND_REG_3
+0x2198 VAP_VTX_STATE_IND_REG_4
+0x219C VAP_VTX_STATE_IND_REG_5
+0x21A0 VAP_VTX_STATE_IND_REG_6
+0x21A4 VAP_VTX_STATE_IND_REG_7
+0x21A8 VAP_VTX_STATE_IND_REG_8
+0x21AC VAP_VTX_STATE_IND_REG_9
+0x21B0 VAP_VTX_STATE_IND_REG_10
+0x21B4 VAP_VTX_STATE_IND_REG_11
+0x21B8 VAP_VTX_STATE_IND_REG_12
+0x21BC VAP_VTX_STATE_IND_REG_13
+0x21C0 VAP_VTX_STATE_IND_REG_14
+0x21C4 VAP_VTX_STATE_IND_REG_15
+0x21DC VAP_PSC_SGN_NORM_CNTL
+0x21E0 VAP_PROG_STREAM_CNTL_EXT_0
+0x21E4 VAP_PROG_STREAM_CNTL_EXT_1
+0x21E8 VAP_PROG_STREAM_CNTL_EXT_2
+0x21EC VAP_PROG_STREAM_CNTL_EXT_3
+0x21F0 VAP_PROG_STREAM_CNTL_EXT_4
+0x21F4 VAP_PROG_STREAM_CNTL_EXT_5
+0x21F8 VAP_PROG_STREAM_CNTL_EXT_6
+0x21FC VAP_PROG_STREAM_CNTL_EXT_7
+0x2200 VAP_PVS_VECTOR_INDX_REG
+0x2204 VAP_PVS_VECTOR_DATA_REG
+0x2208 VAP_PVS_VECTOR_DATA_REG_128
+0x2218 VAP_TEX_TO_COLOR_CNTL
+0x221C VAP_CLIP_CNTL
+0x2220 VAP_GB_VERT_CLIP_ADJ
+0x2224 VAP_GB_VERT_DISC_ADJ
+0x2228 VAP_GB_HORZ_CLIP_ADJ
+0x222C VAP_GB_HORZ_DISC_ADJ
+0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0
+0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1
+0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2
+0x223C VAP_PVS_FLOW_CNTL_ADDRS_3
+0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4
+0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5
+0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6
+0x224C VAP_PVS_FLOW_CNTL_ADDRS_7
+0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8
+0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9
+0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10
+0x225C VAP_PVS_FLOW_CNTL_ADDRS_11
+0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12
+0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13
+0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14
+0x226C VAP_PVS_FLOW_CNTL_ADDRS_15
+0x2284 VAP_PVS_STATE_FLUSH_REG
+0x2288 VAP_PVS_VTX_TIMEOUT_REG
+0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0
+0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1
+0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2
+0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3
+0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4
+0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5
+0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6
+0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7
+0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8
+0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9
+0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10
+0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11
+0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12
+0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13
+0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14
+0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15
+0x22D0 VAP_PVS_CODE_CNTL_0
+0x22D4 VAP_PVS_CONST_CNTL
+0x22D8 VAP_PVS_CODE_CNTL_1
+0x22DC VAP_PVS_FLOW_CNTL_OPC
+0x2500 VAP_PVS_FLOW_CNTL_ADDRS_LW_0
+0x2504 VAP_PVS_FLOW_CNTL_ADDRS_UW_0
+0x2508 VAP_PVS_FLOW_CNTL_ADDRS_LW_1
+0x250C VAP_PVS_FLOW_CNTL_ADDRS_UW_1
+0x2510 VAP_PVS_FLOW_CNTL_ADDRS_LW_2
+0x2514 VAP_PVS_FLOW_CNTL_ADDRS_UW_2
+0x2518 VAP_PVS_FLOW_CNTL_ADDRS_LW_3
+0x251C VAP_PVS_FLOW_CNTL_ADDRS_UW_3
+0x2520 VAP_PVS_FLOW_CNTL_ADDRS_LW_4
+0x2524 VAP_PVS_FLOW_CNTL_ADDRS_UW_4
+0x2528 VAP_PVS_FLOW_CNTL_ADDRS_LW_5
+0x252C VAP_PVS_FLOW_CNTL_ADDRS_UW_5
+0x2530 VAP_PVS_FLOW_CNTL_ADDRS_LW_6
+0x2534 VAP_PVS_FLOW_CNTL_ADDRS_UW_6
+0x2538 VAP_PVS_FLOW_CNTL_ADDRS_LW_7
+0x253C VAP_PVS_FLOW_CNTL_ADDRS_UW_7
+0x2540 VAP_PVS_FLOW_CNTL_ADDRS_LW_8
+0x2544 VAP_PVS_FLOW_CNTL_ADDRS_UW_8
+0x2548 VAP_PVS_FLOW_CNTL_ADDRS_LW_9
+0x254C VAP_PVS_FLOW_CNTL_ADDRS_UW_9
+0x2550 VAP_PVS_FLOW_CNTL_ADDRS_LW_10
+0x2554 VAP_PVS_FLOW_CNTL_ADDRS_UW_10
+0x2558 VAP_PVS_FLOW_CNTL_ADDRS_LW_11
+0x255C VAP_PVS_FLOW_CNTL_ADDRS_UW_11
+0x2560 VAP_PVS_FLOW_CNTL_ADDRS_LW_12
+0x2564 VAP_PVS_FLOW_CNTL_ADDRS_UW_12
+0x2568 VAP_PVS_FLOW_CNTL_ADDRS_LW_13
+0x256C VAP_PVS_FLOW_CNTL_ADDRS_UW_13
+0x2570 VAP_PVS_FLOW_CNTL_ADDRS_LW_14
+0x2574 VAP_PVS_FLOW_CNTL_ADDRS_UW_14
+0x2578 VAP_PVS_FLOW_CNTL_ADDRS_LW_15
+0x257C VAP_PVS_FLOW_CNTL_ADDRS_UW_15
+0x342C RB2D_DSTCACHE_CTLSTAT
+0x4000 GB_VAP_RASTER_VTX_FMT_0
+0x4004 GB_VAP_RASTER_VTX_FMT_1
+0x4008 GB_ENABLE
+0x401C GB_SELECT
+0x4020 GB_AA_CONFIG
+0x4024 GB_FIFO_SIZE
+0x4100 TX_INVALTAGS
+0x4200 GA_POINT_S0
+0x4204 GA_POINT_T0
+0x4208 GA_POINT_S1
+0x420C GA_POINT_T1
+0x4214 GA_TRIANGLE_STIPPLE
+0x421C GA_POINT_SIZE
+0x4230 GA_POINT_MINMAX
+0x4234 GA_LINE_CNTL
+0x4238 GA_LINE_STIPPLE_CONFIG
+0x4260 GA_LINE_STIPPLE_VALUE
+0x4264 GA_LINE_S0
+0x4268 GA_LINE_S1
+0x4278 GA_COLOR_CONTROL
+0x427C GA_SOLID_RG
+0x4280 GA_SOLID_BA
+0x4288 GA_POLY_MODE
+0x428C GA_ROUND_MODE
+0x4290 GA_OFFSET
+0x4294 GA_FOG_SCALE
+0x4298 GA_FOG_OFFSET
+0x42A0 SU_TEX_WRAP
+0x42A4 SU_POLY_OFFSET_FRONT_SCALE
+0x42A8 SU_POLY_OFFSET_FRONT_OFFSET
+0x42AC SU_POLY_OFFSET_BACK_SCALE
+0x42B0 SU_POLY_OFFSET_BACK_OFFSET
+0x42B4 SU_POLY_OFFSET_ENABLE
+0x42B8 SU_CULL_MODE
+0x42C0 SU_DEPTH_SCALE
+0x42C4 SU_DEPTH_OFFSET
+0x42C8 SU_REG_DEST
+0x4300 RS_COUNT
+0x4304 RS_INST_COUNT
+0x4074 RS_IP_0
+0x4078 RS_IP_1
+0x407C RS_IP_2
+0x4080 RS_IP_3
+0x4084 RS_IP_4
+0x4088 RS_IP_5
+0x408C RS_IP_6
+0x4090 RS_IP_7
+0x4094 RS_IP_8
+0x4098 RS_IP_9
+0x409C RS_IP_10
+0x40A0 RS_IP_11
+0x40A4 RS_IP_12
+0x40A8 RS_IP_13
+0x40AC RS_IP_14
+0x40B0 RS_IP_15
+0x4320 RS_INST_0
+0x4324 RS_INST_1
+0x4328 RS_INST_2
+0x432C RS_INST_3
+0x4330 RS_INST_4
+0x4334 RS_INST_5
+0x4338 RS_INST_6
+0x433C RS_INST_7
+0x4340 RS_INST_8
+0x4344 RS_INST_9
+0x4348 RS_INST_10
+0x434C RS_INST_11
+0x4350 RS_INST_12
+0x4354 RS_INST_13
+0x4358 RS_INST_14
+0x435C RS_INST_15
+0x43A4 SC_HYPERZ_EN
+0x43A8 SC_EDGERULE
+0x43B0 SC_CLIP_0_A
+0x43B4 SC_CLIP_0_B
+0x43B8 SC_CLIP_1_A
+0x43BC SC_CLIP_1_B
+0x43C0 SC_CLIP_2_A
+0x43C4 SC_CLIP_2_B
+0x43C8 SC_CLIP_3_A
+0x43CC SC_CLIP_3_B
+0x43D0 SC_CLIP_RULE
+0x43E0 SC_SCISSOR0
+0x43E8 SC_SCREENDOOR
+0x4440 TX_FILTER1_0
+0x4444 TX_FILTER1_1
+0x4448 TX_FILTER1_2
+0x444C TX_FILTER1_3
+0x4450 TX_FILTER1_4
+0x4454 TX_FILTER1_5
+0x4458 TX_FILTER1_6
+0x445C TX_FILTER1_7
+0x4460 TX_FILTER1_8
+0x4464 TX_FILTER1_9
+0x4468 TX_FILTER1_10
+0x446C TX_FILTER1_11
+0x4470 TX_FILTER1_12
+0x4474 TX_FILTER1_13
+0x4478 TX_FILTER1_14
+0x447C TX_FILTER1_15
+0x4580 TX_CHROMA_KEY_0
+0x4584 TX_CHROMA_KEY_1
+0x4588 TX_CHROMA_KEY_2
+0x458C TX_CHROMA_KEY_3
+0x4590 TX_CHROMA_KEY_4
+0x4594 TX_CHROMA_KEY_5
+0x4598 TX_CHROMA_KEY_6
+0x459C TX_CHROMA_KEY_7
+0x45A0 TX_CHROMA_KEY_8
+0x45A4 TX_CHROMA_KEY_9
+0x45A8 TX_CHROMA_KEY_10
+0x45AC TX_CHROMA_KEY_11
+0x45B0 TX_CHROMA_KEY_12
+0x45B4 TX_CHROMA_KEY_13
+0x45B8 TX_CHROMA_KEY_14
+0x45BC TX_CHROMA_KEY_15
+0x45C0 TX_BORDER_COLOR_0
+0x45C4 TX_BORDER_COLOR_1
+0x45C8 TX_BORDER_COLOR_2
+0x45CC TX_BORDER_COLOR_3
+0x45D0 TX_BORDER_COLOR_4
+0x45D4 TX_BORDER_COLOR_5
+0x45D8 TX_BORDER_COLOR_6
+0x45DC TX_BORDER_COLOR_7
+0x45E0 TX_BORDER_COLOR_8
+0x45E4 TX_BORDER_COLOR_9
+0x45E8 TX_BORDER_COLOR_10
+0x45EC TX_BORDER_COLOR_11
+0x45F0 TX_BORDER_COLOR_12
+0x45F4 TX_BORDER_COLOR_13
+0x45F8 TX_BORDER_COLOR_14
+0x45FC TX_BORDER_COLOR_15
+0x4250 GA_US_VECTOR_INDEX
+0x4254 GA_US_VECTOR_DATA
+0x4600 US_CONFIG
+0x4604 US_PIXSIZE
+0x4620 US_FC_BOOL_CONST
+0x4624 US_FC_CTRL
+0x4630 US_CODE_ADDR
+0x4634 US_CODE_RANGE
+0x4638 US_CODE_OFFSET
+0x46A4 US_OUT_FMT_0
+0x46A8 US_OUT_FMT_1
+0x46AC US_OUT_FMT_2
+0x46B0 US_OUT_FMT_3
+0x46B4 US_W_FMT
+0x4BC0 FG_FOG_BLEND
+0x4BC4 FG_FOG_FACTOR
+0x4BC8 FG_FOG_COLOR_R
+0x4BCC FG_FOG_COLOR_G
+0x4BD0 FG_FOG_COLOR_B
+0x4BD4 FG_ALPHA_FUNC
+0x4BD8 FG_DEPTH_SRC
+0x4C00 US_ALU_CONST_R_0
+0x4C04 US_ALU_CONST_G_0
+0x4C08 US_ALU_CONST_B_0
+0x4C0C US_ALU_CONST_A_0
+0x4C10 US_ALU_CONST_R_1
+0x4C14 US_ALU_CONST_G_1
+0x4C18 US_ALU_CONST_B_1
+0x4C1C US_ALU_CONST_A_1
+0x4C20 US_ALU_CONST_R_2
+0x4C24 US_ALU_CONST_G_2
+0x4C28 US_ALU_CONST_B_2
+0x4C2C US_ALU_CONST_A_2
+0x4C30 US_ALU_CONST_R_3
+0x4C34 US_ALU_CONST_G_3
+0x4C38 US_ALU_CONST_B_3
+0x4C3C US_ALU_CONST_A_3
+0x4C40 US_ALU_CONST_R_4
+0x4C44 US_ALU_CONST_G_4
+0x4C48 US_ALU_CONST_B_4
+0x4C4C US_ALU_CONST_A_4
+0x4C50 US_ALU_CONST_R_5
+0x4C54 US_ALU_CONST_G_5
+0x4C58 US_ALU_CONST_B_5
+0x4C5C US_ALU_CONST_A_5
+0x4C60 US_ALU_CONST_R_6
+0x4C64 US_ALU_CONST_G_6
+0x4C68 US_ALU_CONST_B_6
+0x4C6C US_ALU_CONST_A_6
+0x4C70 US_ALU_CONST_R_7
+0x4C74 US_ALU_CONST_G_7
+0x4C78 US_ALU_CONST_B_7
+0x4C7C US_ALU_CONST_A_7
+0x4C80 US_ALU_CONST_R_8
+0x4C84 US_ALU_CONST_G_8
+0x4C88 US_ALU_CONST_B_8
+0x4C8C US_ALU_CONST_A_8
+0x4C90 US_ALU_CONST_R_9
+0x4C94 US_ALU_CONST_G_9
+0x4C98 US_ALU_CONST_B_9
+0x4C9C US_ALU_CONST_A_9
+0x4CA0 US_ALU_CONST_R_10
+0x4CA4 US_ALU_CONST_G_10
+0x4CA8 US_ALU_CONST_B_10
+0x4CAC US_ALU_CONST_A_10
+0x4CB0 US_ALU_CONST_R_11
+0x4CB4 US_ALU_CONST_G_11
+0x4CB8 US_ALU_CONST_B_11
+0x4CBC US_ALU_CONST_A_11
+0x4CC0 US_ALU_CONST_R_12
+0x4CC4 US_ALU_CONST_G_12
+0x4CC8 US_ALU_CONST_B_12
+0x4CCC US_ALU_CONST_A_12
+0x4CD0 US_ALU_CONST_R_13
+0x4CD4 US_ALU_CONST_G_13
+0x4CD8 US_ALU_CONST_B_13
+0x4CDC US_ALU_CONST_A_13
+0x4CE0 US_ALU_CONST_R_14
+0x4CE4 US_ALU_CONST_G_14
+0x4CE8 US_ALU_CONST_B_14
+0x4CEC US_ALU_CONST_A_14
+0x4CF0 US_ALU_CONST_R_15
+0x4CF4 US_ALU_CONST_G_15
+0x4CF8 US_ALU_CONST_B_15
+0x4CFC US_ALU_CONST_A_15
+0x4D00 US_ALU_CONST_R_16
+0x4D04 US_ALU_CONST_G_16
+0x4D08 US_ALU_CONST_B_16
+0x4D0C US_ALU_CONST_A_16
+0x4D10 US_ALU_CONST_R_17
+0x4D14 US_ALU_CONST_G_17
+0x4D18 US_ALU_CONST_B_17
+0x4D1C US_ALU_CONST_A_17
+0x4D20 US_ALU_CONST_R_18
+0x4D24 US_ALU_CONST_G_18
+0x4D28 US_ALU_CONST_B_18
+0x4D2C US_ALU_CONST_A_18
+0x4D30 US_ALU_CONST_R_19
+0x4D34 US_ALU_CONST_G_19
+0x4D38 US_ALU_CONST_B_19
+0x4D3C US_ALU_CONST_A_19
+0x4D40 US_ALU_CONST_R_20
+0x4D44 US_ALU_CONST_G_20
+0x4D48 US_ALU_CONST_B_20
+0x4D4C US_ALU_CONST_A_20
+0x4D50 US_ALU_CONST_R_21
+0x4D54 US_ALU_CONST_G_21
+0x4D58 US_ALU_CONST_B_21
+0x4D5C US_ALU_CONST_A_21
+0x4D60 US_ALU_CONST_R_22
+0x4D64 US_ALU_CONST_G_22
+0x4D68 US_ALU_CONST_B_22
+0x4D6C US_ALU_CONST_A_22
+0x4D70 US_ALU_CONST_R_23
+0x4D74 US_ALU_CONST_G_23
+0x4D78 US_ALU_CONST_B_23
+0x4D7C US_ALU_CONST_A_23
+0x4D80 US_ALU_CONST_R_24
+0x4D84 US_ALU_CONST_G_24
+0x4D88 US_ALU_CONST_B_24
+0x4D8C US_ALU_CONST_A_24
+0x4D90 US_ALU_CONST_R_25
+0x4D94 US_ALU_CONST_G_25
+0x4D98 US_ALU_CONST_B_25
+0x4D9C US_ALU_CONST_A_25
+0x4DA0 US_ALU_CONST_R_26
+0x4DA4 US_ALU_CONST_G_26
+0x4DA8 US_ALU_CONST_B_26
+0x4DAC US_ALU_CONST_A_26
+0x4DB0 US_ALU_CONST_R_27
+0x4DB4 US_ALU_CONST_G_27
+0x4DB8 US_ALU_CONST_B_27
+0x4DBC US_ALU_CONST_A_27
+0x4DC0 US_ALU_CONST_R_28
+0x4DC4 US_ALU_CONST_G_28
+0x4DC8 US_ALU_CONST_B_28
+0x4DCC US_ALU_CONST_A_28
+0x4DD0 US_ALU_CONST_R_29
+0x4DD4 US_ALU_CONST_G_29
+0x4DD8 US_ALU_CONST_B_29
+0x4DDC US_ALU_CONST_A_29
+0x4DE0 US_ALU_CONST_R_30
+0x4DE4 US_ALU_CONST_G_30
+0x4DE8 US_ALU_CONST_B_30
+0x4DEC US_ALU_CONST_A_30
+0x4DF0 US_ALU_CONST_R_31
+0x4DF4 US_ALU_CONST_G_31
+0x4DF8 US_ALU_CONST_B_31
+0x4DFC US_ALU_CONST_A_31
+0x4E04 RB3D_BLENDCNTL_R3
+0x4E08 RB3D_ABLENDCNTL_R3
+0x4E0C RB3D_COLOR_CHANNEL_MASK
+0x4E10 RB3D_CONSTANT_COLOR
+0x4E14 RB3D_COLOR_CLEAR_VALUE
+0x4E18 RB3D_ROPCNTL_R3
+0x4E1C RB3D_CLRCMP_FLIPE_R3
+0x4E20 RB3D_CLRCMP_CLR_R3
+0x4E24 RB3D_CLRCMP_MSK_R3
+0x4E48 RB3D_DEBUG_CTL
+0x4E4C RB3D_DSTCACHE_CTLSTAT_R3
+0x4E50 RB3D_DITHER_CTL
+0x4E54 RB3D_CMASK_OFFSET0
+0x4E58 RB3D_CMASK_OFFSET1
+0x4E5C RB3D_CMASK_OFFSET2
+0x4E60 RB3D_CMASK_OFFSET3
+0x4E64 RB3D_CMASK_PITCH0
+0x4E68 RB3D_CMASK_PITCH1
+0x4E6C RB3D_CMASK_PITCH2
+0x4E70 RB3D_CMASK_PITCH3
+0x4E74 RB3D_CMASK_WRINDEX
+0x4E78 RB3D_CMASK_DWORD
+0x4E7C RB3D_CMASK_RDINDEX
+0x4E80 RB3D_AARESOLVE_OFFSET
+0x4E84 RB3D_AARESOLVE_PITCH
+0x4E88 RB3D_AARESOLVE_CTL
+0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
+0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
+0x4EF8 RB3D_CONSTANT_COLOR_AR
+0x4EFC RB3D_CONSTANT_COLOR_GB
+0x4F04 ZB_ZSTENCILCNTL
+0x4F08 ZB_STENCILREFMASK
+0x4F14 ZB_ZTOP
+0x4F18 ZB_ZCACHE_CTLSTAT
+0x4F1C ZB_BW_CNTL
+0x4F28 ZB_DEPTHCLEARVALUE
+0x4F30 ZB_ZMASK_OFFSET
+0x4F34 ZB_ZMASK_PITCH
+0x4F38 ZB_ZMASK_WRINDEX
+0x4F3C ZB_ZMASK_DWORD
+0x4F40 ZB_ZMASK_RDINDEX
+0x4F44 ZB_HIZ_OFFSET
+0x4F48 ZB_HIZ_WRINDEX
+0x4F4C ZB_HIZ_DWORD
+0x4F50 ZB_HIZ_RDINDEX
+0x4F54 ZB_HIZ_PITCH
+0x4F58 ZB_ZPASS_DATA
+0x4FD4 ZB_STENCILREFMASK_BF
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index b29affd..a3fbdad 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -29,7 +29,6 @@
 #include <drm/drmP.h>
 #include "radeon_reg.h"
 #include "radeon.h"
-#include "radeon_share.h"
 
 /* rs400,rs480 depends on : */
 void r100_hdp_reset(struct radeon_device *rdev);
@@ -63,7 +62,7 @@ void rs400_gart_adjust_size(struct radeon_device *rdev)
 		break;
 	default:
 		DRM_ERROR("Unable to use IGP GART size %uM\n",
-			  rdev->mc.gtt_size >> 20);
+			  (unsigned)(rdev->mc.gtt_size >> 20));
 		DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n");
 		DRM_ERROR("Forcing to 32M GART size\n");
 		rdev->mc.gtt_size = 32 * 1024 * 1024;
@@ -93,20 +92,41 @@ void rs400_gart_tlb_flush(struct radeon_device *rdev)
 	WREG32_MC(RS480_GART_CACHE_CNTRL, 0);
 }
 
-int rs400_gart_enable(struct radeon_device *rdev)
+int rs400_gart_init(struct radeon_device *rdev)
 {
-	uint32_t size_reg;
-	uint32_t tmp;
 	int r;
 
+	if (rdev->gart.table.ram.ptr) {
+		WARN(1, "RS400 GART already initialized.\n");
+		return 0;
+	}
+	/* Check gart size */
+	switch(rdev->mc.gtt_size / (1024 * 1024)) {
+	case 32:
+	case 64:
+	case 128:
+	case 256:
+	case 512:
+	case 1024:
+	case 2048:
+		break;
+	default:
+		return -EINVAL;
+	}
 	/* Initialize common gart structure */
 	r = radeon_gart_init(rdev);
-	if (r) {
+	if (r)
 		return r;
-	}
-	if (rs400_debugfs_pcie_gart_info_init(rdev)) {
+	if (rs400_debugfs_pcie_gart_info_init(rdev))
 		DRM_ERROR("Failed to register debugfs file for RS400 GART !\n");
-	}
+	rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
+	return radeon_gart_table_ram_alloc(rdev);
+}
+
+int rs400_gart_enable(struct radeon_device *rdev)
+{
+	uint32_t size_reg;
+	uint32_t tmp;
 
 	tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);
 	tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;
@@ -137,13 +157,6 @@ int rs400_gart_enable(struct radeon_device *rdev)
 	default:
 		return -EINVAL;
 	}
-	if (rdev->gart.table.ram.ptr == NULL) {
-		rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
-		r = radeon_gart_table_ram_alloc(rdev);
-		if (r) {
-			return r;
-		}
-	}
 	/* It should be fine to program it to max value */
 	if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) {
 		WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF);
@@ -202,6 +215,13 @@ void rs400_gart_disable(struct radeon_device *rdev)
 	WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
 }
 
+void rs400_gart_fini(struct radeon_device *rdev)
+{
+	rs400_gart_disable(rdev);
+	radeon_gart_table_ram_free(rdev);
+	radeon_gart_fini(rdev);
+}
+
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
 	uint32_t entry;
@@ -256,14 +276,12 @@ int rs400_mc_init(struct radeon_device *rdev)
 	(void)RREG32(RADEON_HOST_PATH_CNTL);
 	WREG32(RADEON_HOST_PATH_CNTL, tmp);
 	(void)RREG32(RADEON_HOST_PATH_CNTL);
+
 	return 0;
 }
 
 void rs400_mc_fini(struct radeon_device *rdev)
 {
-	rs400_gart_disable(rdev);
-	radeon_gart_table_ram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 02fd11a..0e791e2 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -28,6 +28,9 @@
 #include "drmP.h"
 #include "radeon_reg.h"
 #include "radeon.h"
+#include "avivod.h"
+
+#include "rs600_reg_safe.h"
 
 /* rs600 depends on : */
 void r100_hdp_reset(struct radeon_device *rdev);
@@ -66,22 +69,35 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
 	tmp = RREG32_MC(RS600_MC_PT0_CNTL);
 }
 
-int rs600_gart_enable(struct radeon_device *rdev)
+int rs600_gart_init(struct radeon_device *rdev)
 {
-	uint32_t tmp;
-	int i;
 	int r;
 
+	if (rdev->gart.table.vram.robj) {
+		WARN(1, "RS600 GART already initialized.\n");
+		return 0;
+	}
 	/* Initialize common gart structure */
 	r = radeon_gart_init(rdev);
 	if (r) {
 		return r;
 	}
 	rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
-	r = radeon_gart_table_vram_alloc(rdev);
-	if (r) {
-		return r;
+	return radeon_gart_table_vram_alloc(rdev);
+}
+
+int rs600_gart_enable(struct radeon_device *rdev)
+{
+	uint32_t tmp;
+	int r, i;
+
+	if (rdev->gart.table.vram.robj == NULL) {
+		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
+		return -EINVAL;
 	}
+	r = radeon_gart_table_vram_pin(rdev);
+	if (r)
+		return r;
 	/* FIXME: setup default page */
 	WREG32_MC(RS600_MC_PT0_CNTL,
 		 (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
@@ -136,8 +152,17 @@ void rs600_gart_disable(struct radeon_device *rdev)
 	tmp = RREG32_MC(RS600_MC_CNTL1);
 	tmp &= ~RS600_ENABLE_PAGE_TABLES;
 	WREG32_MC(RS600_MC_CNTL1, tmp);
-	radeon_object_kunmap(rdev->gart.table.vram.robj);
-	radeon_object_unpin(rdev->gart.table.vram.robj);
+	if (rdev->gart.table.vram.robj) {
+		radeon_object_kunmap(rdev->gart.table.vram.robj);
+		radeon_object_unpin(rdev->gart.table.vram.robj);
+	}
+}
+
+void rs600_gart_fini(struct radeon_device *rdev)
+{
+	rs600_gart_disable(rdev);
+	radeon_gart_table_vram_free(rdev);
+	radeon_gart_fini(rdev);
 }
 
 #define R600_PTE_VALID     (1 << 0)
@@ -173,6 +198,8 @@ void rs600_mc_disable_clients(struct radeon_device *rdev)
 		       "programming pipes. Bad things might happen.\n");
 	}
 
+	radeon_avivo_vga_render_disable(rdev);
+
 	tmp = RREG32(AVIVO_D1VGA_CONTROL);
 	WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
 	tmp = RREG32(AVIVO_D2VGA_CONTROL);
@@ -233,9 +260,6 @@ int rs600_mc_init(struct radeon_device *rdev)
 
 void rs600_mc_fini(struct radeon_device *rdev)
 {
-	rs600_gart_disable(rdev);
-	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 
@@ -251,11 +275,9 @@ int rs600_irq_set(struct radeon_device *rdev)
 		tmp |= RADEON_SW_INT_ENABLE;
 	}
 	if (rdev->irq.crtc_vblank_int[0]) {
-		tmp |= AVIVO_DISPLAY_INT_STATUS;
 		mode_int |= AVIVO_D1MODE_INT_MASK;
 	}
 	if (rdev->irq.crtc_vblank_int[1]) {
-		tmp |= AVIVO_DISPLAY_INT_STATUS;
 		mode_int |= AVIVO_D2MODE_INT_MASK;
 	}
 	WREG32(RADEON_GEN_INT_CNTL, tmp);
@@ -410,64 +432,6 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
 	WREG32(RS600_MC_DATA, v);
 }
 
-static const unsigned rs600_reg_safe_bm[219] = {
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
-	0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
-	0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
-	0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF,
-	0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
-	0x00000000, 0x0000C100, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x0003FC01, 0xFFFFFCF8, 0xFF800B19, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-};
-
 int rs600_init(struct radeon_device *rdev)
 {
 	rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm;
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 8798825..0f585ca 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -94,9 +94,6 @@ int rs690_mc_init(struct radeon_device *rdev)
 
 void rs690_mc_fini(struct radeon_device *rdev)
 {
-	rs400_gart_disable(rdev);
-	radeon_gart_table_ram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 
@@ -652,4 +649,3 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
 	WREG32(RS690_MC_DATA, v);
 	WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
 }
-
diff --git a/drivers/gpu/drm/radeon/rs780.c b/drivers/gpu/drm/radeon/rs780.c
deleted file mode 100644
index 0affcff..0000000
--- a/drivers/gpu/drm/radeon/rs780.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2008 Advanced Micro Devices, Inc.
- * Copyright 2008 Red Hat Inc.
- * Copyright 2009 Jerome Glisse.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Dave Airlie
- *          Alex Deucher
- *          Jerome Glisse
- */
-#include "drmP.h"
-#include "radeon_reg.h"
-#include "radeon.h"
-
-/* rs780  depends on : */
-void rs600_mc_disable_clients(struct radeon_device *rdev);
-
-/* This files gather functions specifics to:
- * rs780
- *
- * Some of these functions might be used by newer ASICs.
- */
-int rs780_mc_wait_for_idle(struct radeon_device *rdev);
-void rs780_gpu_init(struct radeon_device *rdev);
-
-
-/*
- * MC
- */
-int rs780_mc_init(struct radeon_device *rdev)
-{
-	rs780_gpu_init(rdev);
-	/* FIXME: implement */
-
-	rs600_mc_disable_clients(rdev);
-	if (rs780_mc_wait_for_idle(rdev)) {
-		printk(KERN_WARNING "Failed to wait MC idle while "
-		       "programming pipes. Bad things might happen.\n");
-	}
-	return 0;
-}
-
-void rs780_mc_fini(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
-}
-
-
-/*
- * Global GPU functions
- */
-void rs780_errata(struct radeon_device *rdev)
-{
-	rdev->pll_errata = 0;
-}
-
-int rs780_mc_wait_for_idle(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
-	return 0;
-}
-
-void rs780_gpu_init(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
-}
-
-
-/*
- * VRAM info
- */
-void rs780_vram_get_type(struct radeon_device *rdev)
-{
-	/* FIXME: implement */
-}
-
-void rs780_vram_info(struct radeon_device *rdev)
-{
-	rs780_vram_get_type(rdev);
-
-	/* FIXME: implement */
-	/* Could aper size report 0 ? */
-	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
-	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
-}
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 0566fb6..fd79974 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -27,18 +27,16 @@
  */
 #include <linux/seq_file.h>
 #include "drmP.h"
-#include "rv515r.h"
+#include "rv515d.h"
 #include "radeon.h"
-#include "radeon_share.h"
 
+#include "rv515_reg_safe.h"
 /* rv515 depends on : */
 void r100_hdp_reset(struct radeon_device *rdev);
 int r100_cp_reset(struct radeon_device *rdev);
 int r100_rb2d_reset(struct radeon_device *rdev);
 int r100_gui_wait_for_idle(struct radeon_device *rdev);
 int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
-int rv370_pcie_gart_enable(struct radeon_device *rdev);
-void rv370_pcie_gart_disable(struct radeon_device *rdev);
 void r420_pipes_init(struct radeon_device *rdev);
 void rs600_mc_disable_clients(struct radeon_device *rdev);
 void rs600_disable_vga(struct radeon_device *rdev);
@@ -126,9 +124,6 @@ int rv515_mc_init(struct radeon_device *rdev)
 
 void rv515_mc_fini(struct radeon_device *rdev)
 {
-	rv370_pcie_gart_disable(rdev);
-	radeon_gart_table_vram_free(rdev);
-	radeon_gart_fini(rdev);
 }
 
 
@@ -464,301 +459,244 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev)
 #endif
 }
 
-
 /*
  * Asic initialization
  */
-static const unsigned r500_reg_safe_bm[219] = {
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
-	0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
-	0xF0000038, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0x1FFFFC78, 0xFFFFE000, 0xFFFFFFFE, 0xFFFFFFFF,
-	0x38CF8F50, 0xFFF88082, 0xFF0000FC, 0xFAE009FF,
-	0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
-	0xFFFF8CFC, 0xFFFFC1FF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x0003FC01, 0x3FFFFCF8, 0xFF800B19, 0xFFDFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-};
-
 int rv515_init(struct radeon_device *rdev)
 {
-	rdev->config.r300.reg_safe_bm = r500_reg_safe_bm;
-	rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r500_reg_safe_bm);
+	rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm;
+	rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm);
 	return 0;
 }
 
-void atom_rv515_force_tv_scaler(struct radeon_device *rdev)
+void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc)
 {
-
-	WREG32(0x659C, 0x0);
-	WREG32(0x6594, 0x705);
-	WREG32(0x65A4, 0x10001);
-	WREG32(0x65D8, 0x0);
-	WREG32(0x65B0, 0x0);
-	WREG32(0x65C0, 0x0);
-	WREG32(0x65D4, 0x0);
-	WREG32(0x6578, 0x0);
-	WREG32(0x657C, 0x841880A8);
-	WREG32(0x6578, 0x1);
-	WREG32(0x657C, 0x84208680);
-	WREG32(0x6578, 0x2);
-	WREG32(0x657C, 0xBFF880B0);
-	WREG32(0x6578, 0x100);
-	WREG32(0x657C, 0x83D88088);
-	WREG32(0x6578, 0x101);
-	WREG32(0x657C, 0x84608680);
-	WREG32(0x6578, 0x102);
-	WREG32(0x657C, 0xBFF080D0);
-	WREG32(0x6578, 0x200);
-	WREG32(0x657C, 0x83988068);
-	WREG32(0x6578, 0x201);
-	WREG32(0x657C, 0x84A08680);
-	WREG32(0x6578, 0x202);
-	WREG32(0x657C, 0xBFF080F8);
-	WREG32(0x6578, 0x300);
-	WREG32(0x657C, 0x83588058);
-	WREG32(0x6578, 0x301);
-	WREG32(0x657C, 0x84E08660);
-	WREG32(0x6578, 0x302);
-	WREG32(0x657C, 0xBFF88120);
-	WREG32(0x6578, 0x400);
-	WREG32(0x657C, 0x83188040);
-	WREG32(0x6578, 0x401);
-	WREG32(0x657C, 0x85008660);
-	WREG32(0x6578, 0x402);
-	WREG32(0x657C, 0xBFF88150);
-	WREG32(0x6578, 0x500);
-	WREG32(0x657C, 0x82D88030);
-	WREG32(0x6578, 0x501);
-	WREG32(0x657C, 0x85408640);
-	WREG32(0x6578, 0x502);
-	WREG32(0x657C, 0xBFF88180);
-	WREG32(0x6578, 0x600);
-	WREG32(0x657C, 0x82A08018);
-	WREG32(0x6578, 0x601);
-	WREG32(0x657C, 0x85808620);
-	WREG32(0x6578, 0x602);
-	WREG32(0x657C, 0xBFF081B8);
-	WREG32(0x6578, 0x700);
-	WREG32(0x657C, 0x82608010);
-	WREG32(0x6578, 0x701);
-	WREG32(0x657C, 0x85A08600);
-	WREG32(0x6578, 0x702);
-	WREG32(0x657C, 0x800081F0);
-	WREG32(0x6578, 0x800);
-	WREG32(0x657C, 0x8228BFF8);
-	WREG32(0x6578, 0x801);
-	WREG32(0x657C, 0x85E085E0);
-	WREG32(0x6578, 0x802);
-	WREG32(0x657C, 0xBFF88228);
-	WREG32(0x6578, 0x10000);
-	WREG32(0x657C, 0x82A8BF00);
-	WREG32(0x6578, 0x10001);
-	WREG32(0x657C, 0x82A08CC0);
-	WREG32(0x6578, 0x10002);
-	WREG32(0x657C, 0x8008BEF8);
-	WREG32(0x6578, 0x10100);
-	WREG32(0x657C, 0x81F0BF28);
-	WREG32(0x6578, 0x10101);
-	WREG32(0x657C, 0x83608CA0);
-	WREG32(0x6578, 0x10102);
-	WREG32(0x657C, 0x8018BED0);
-	WREG32(0x6578, 0x10200);
-	WREG32(0x657C, 0x8148BF38);
-	WREG32(0x6578, 0x10201);
-	WREG32(0x657C, 0x84408C80);
-	WREG32(0x6578, 0x10202);
-	WREG32(0x657C, 0x8008BEB8);
-	WREG32(0x6578, 0x10300);
-	WREG32(0x657C, 0x80B0BF78);
-	WREG32(0x6578, 0x10301);
-	WREG32(0x657C, 0x85008C20);
-	WREG32(0x6578, 0x10302);
-	WREG32(0x657C, 0x8020BEA0);
-	WREG32(0x6578, 0x10400);
-	WREG32(0x657C, 0x8028BF90);
-	WREG32(0x6578, 0x10401);
-	WREG32(0x657C, 0x85E08BC0);
-	WREG32(0x6578, 0x10402);
-	WREG32(0x657C, 0x8018BE90);
-	WREG32(0x6578, 0x10500);
-	WREG32(0x657C, 0xBFB8BFB0);
-	WREG32(0x6578, 0x10501);
-	WREG32(0x657C, 0x86C08B40);
-	WREG32(0x6578, 0x10502);
-	WREG32(0x657C, 0x8010BE90);
-	WREG32(0x6578, 0x10600);
-	WREG32(0x657C, 0xBF58BFC8);
-	WREG32(0x6578, 0x10601);
-	WREG32(0x657C, 0x87A08AA0);
-	WREG32(0x6578, 0x10602);
-	WREG32(0x657C, 0x8010BE98);
-	WREG32(0x6578, 0x10700);
-	WREG32(0x657C, 0xBF10BFF0);
-	WREG32(0x6578, 0x10701);
-	WREG32(0x657C, 0x886089E0);
-	WREG32(0x6578, 0x10702);
-	WREG32(0x657C, 0x8018BEB0);
-	WREG32(0x6578, 0x10800);
-	WREG32(0x657C, 0xBED8BFE8);
-	WREG32(0x6578, 0x10801);
-	WREG32(0x657C, 0x89408940);
-	WREG32(0x6578, 0x10802);
-	WREG32(0x657C, 0xBFE8BED8);
-	WREG32(0x6578, 0x20000);
-	WREG32(0x657C, 0x80008000);
-	WREG32(0x6578, 0x20001);
-	WREG32(0x657C, 0x90008000);
-	WREG32(0x6578, 0x20002);
-	WREG32(0x657C, 0x80008000);
-	WREG32(0x6578, 0x20003);
-	WREG32(0x657C, 0x80008000);
-	WREG32(0x6578, 0x20100);
-	WREG32(0x657C, 0x80108000);
-	WREG32(0x6578, 0x20101);
-	WREG32(0x657C, 0x8FE0BF70);
-	WREG32(0x6578, 0x20102);
-	WREG32(0x657C, 0xBFE880C0);
-	WREG32(0x6578, 0x20103);
-	WREG32(0x657C, 0x80008000);
-	WREG32(0x6578, 0x20200);
-	WREG32(0x657C, 0x8018BFF8);
-	WREG32(0x6578, 0x20201);
-	WREG32(0x657C, 0x8F80BF08);
-	WREG32(0x6578, 0x20202);
-	WREG32(0x657C, 0xBFD081A0);
-	WREG32(0x6578, 0x20203);
-	WREG32(0x657C, 0xBFF88000);
-	WREG32(0x6578, 0x20300);
-	WREG32(0x657C, 0x80188000);
-	WREG32(0x6578, 0x20301);
-	WREG32(0x657C, 0x8EE0BEC0);
-	WREG32(0x6578, 0x20302);
-	WREG32(0x657C, 0xBFB082A0);
-	WREG32(0x6578, 0x20303);
-	WREG32(0x657C, 0x80008000);
-	WREG32(0x6578, 0x20400);
-	WREG32(0x657C, 0x80188000);
-	WREG32(0x6578, 0x20401);
-	WREG32(0x657C, 0x8E00BEA0);
-	WREG32(0x6578, 0x20402);
-	WREG32(0x657C, 0xBF8883C0);
-	WREG32(0x6578, 0x20403);
-	WREG32(0x657C, 0x80008000);
-	WREG32(0x6578, 0x20500);
-	WREG32(0x657C, 0x80188000);
-	WREG32(0x6578, 0x20501);
-	WREG32(0x657C, 0x8D00BE90);
-	WREG32(0x6578, 0x20502);
-	WREG32(0x657C, 0xBF588500);
-	WREG32(0x6578, 0x20503);
-	WREG32(0x657C, 0x80008008);
-	WREG32(0x6578, 0x20600);
-	WREG32(0x657C, 0x80188000);
-	WREG32(0x6578, 0x20601);
-	WREG32(0x657C, 0x8BC0BE98);
-	WREG32(0x6578, 0x20602);
-	WREG32(0x657C, 0xBF308660);
-	WREG32(0x6578, 0x20603);
-	WREG32(0x657C, 0x80008008);
-	WREG32(0x6578, 0x20700);
-	WREG32(0x657C, 0x80108000);
-	WREG32(0x6578, 0x20701);
-	WREG32(0x657C, 0x8A80BEB0);
-	WREG32(0x6578, 0x20702);
-	WREG32(0x657C, 0xBF0087C0);
-	WREG32(0x6578, 0x20703);
-	WREG32(0x657C, 0x80008008);
-	WREG32(0x6578, 0x20800);
-	WREG32(0x657C, 0x80108000);
-	WREG32(0x6578, 0x20801);
-	WREG32(0x657C, 0x8920BED0);
-	WREG32(0x6578, 0x20802);
-	WREG32(0x657C, 0xBED08920);
-	WREG32(0x6578, 0x20803);
-	WREG32(0x657C, 0x80008010);
-	WREG32(0x6578, 0x30000);
-	WREG32(0x657C, 0x90008000);
-	WREG32(0x6578, 0x30001);
-	WREG32(0x657C, 0x80008000);
-	WREG32(0x6578, 0x30100);
-	WREG32(0x657C, 0x8FE0BF90);
-	WREG32(0x6578, 0x30101);
-	WREG32(0x657C, 0xBFF880A0);
-	WREG32(0x6578, 0x30200);
-	WREG32(0x657C, 0x8F60BF40);
-	WREG32(0x6578, 0x30201);
-	WREG32(0x657C, 0xBFE88180);
-	WREG32(0x6578, 0x30300);
-	WREG32(0x657C, 0x8EC0BF00);
-	WREG32(0x6578, 0x30301);
-	WREG32(0x657C, 0xBFC88280);
-	WREG32(0x6578, 0x30400);
-	WREG32(0x657C, 0x8DE0BEE0);
-	WREG32(0x6578, 0x30401);
-	WREG32(0x657C, 0xBFA083A0);
-	WREG32(0x6578, 0x30500);
-	WREG32(0x657C, 0x8CE0BED0);
-	WREG32(0x6578, 0x30501);
-	WREG32(0x657C, 0xBF7884E0);
-	WREG32(0x6578, 0x30600);
-	WREG32(0x657C, 0x8BA0BED8);
-	WREG32(0x6578, 0x30601);
-	WREG32(0x657C, 0xBF508640);
-	WREG32(0x6578, 0x30700);
-	WREG32(0x657C, 0x8A60BEE8);
-	WREG32(0x6578, 0x30701);
-	WREG32(0x657C, 0xBF2087A0);
-	WREG32(0x6578, 0x30800);
-	WREG32(0x657C, 0x8900BF00);
-	WREG32(0x6578, 0x30801);
-	WREG32(0x657C, 0xBF008900);
+	int index_reg = 0x6578 + crtc->crtc_offset;
+	int data_reg = 0x657c + crtc->crtc_offset;
+
+	WREG32(0x659C + crtc->crtc_offset, 0x0);
+	WREG32(0x6594 + crtc->crtc_offset, 0x705);
+	WREG32(0x65A4 + crtc->crtc_offset, 0x10001);
+	WREG32(0x65D8 + crtc->crtc_offset, 0x0);
+	WREG32(0x65B0 + crtc->crtc_offset, 0x0);
+	WREG32(0x65C0 + crtc->crtc_offset, 0x0);
+	WREG32(0x65D4 + crtc->crtc_offset, 0x0);
+	WREG32(index_reg, 0x0);
+	WREG32(data_reg, 0x841880A8);
+	WREG32(index_reg, 0x1);
+	WREG32(data_reg, 0x84208680);
+	WREG32(index_reg, 0x2);
+	WREG32(data_reg, 0xBFF880B0);
+	WREG32(index_reg, 0x100);
+	WREG32(data_reg, 0x83D88088);
+	WREG32(index_reg, 0x101);
+	WREG32(data_reg, 0x84608680);
+	WREG32(index_reg, 0x102);
+	WREG32(data_reg, 0xBFF080D0);
+	WREG32(index_reg, 0x200);
+	WREG32(data_reg, 0x83988068);
+	WREG32(index_reg, 0x201);
+	WREG32(data_reg, 0x84A08680);
+	WREG32(index_reg, 0x202);
+	WREG32(data_reg, 0xBFF080F8);
+	WREG32(index_reg, 0x300);
+	WREG32(data_reg, 0x83588058);
+	WREG32(index_reg, 0x301);
+	WREG32(data_reg, 0x84E08660);
+	WREG32(index_reg, 0x302);
+	WREG32(data_reg, 0xBFF88120);
+	WREG32(index_reg, 0x400);
+	WREG32(data_reg, 0x83188040);
+	WREG32(index_reg, 0x401);
+	WREG32(data_reg, 0x85008660);
+	WREG32(index_reg, 0x402);
+	WREG32(data_reg, 0xBFF88150);
+	WREG32(index_reg, 0x500);
+	WREG32(data_reg, 0x82D88030);
+	WREG32(index_reg, 0x501);
+	WREG32(data_reg, 0x85408640);
+	WREG32(index_reg, 0x502);
+	WREG32(data_reg, 0xBFF88180);
+	WREG32(index_reg, 0x600);
+	WREG32(data_reg, 0x82A08018);
+	WREG32(index_reg, 0x601);
+	WREG32(data_reg, 0x85808620);
+	WREG32(index_reg, 0x602);
+	WREG32(data_reg, 0xBFF081B8);
+	WREG32(index_reg, 0x700);
+	WREG32(data_reg, 0x82608010);
+	WREG32(index_reg, 0x701);
+	WREG32(data_reg, 0x85A08600);
+	WREG32(index_reg, 0x702);
+	WREG32(data_reg, 0x800081F0);
+	WREG32(index_reg, 0x800);
+	WREG32(data_reg, 0x8228BFF8);
+	WREG32(index_reg, 0x801);
+	WREG32(data_reg, 0x85E085E0);
+	WREG32(index_reg, 0x802);
+	WREG32(data_reg, 0xBFF88228);
+	WREG32(index_reg, 0x10000);
+	WREG32(data_reg, 0x82A8BF00);
+	WREG32(index_reg, 0x10001);
+	WREG32(data_reg, 0x82A08CC0);
+	WREG32(index_reg, 0x10002);
+	WREG32(data_reg, 0x8008BEF8);
+	WREG32(index_reg, 0x10100);
+	WREG32(data_reg, 0x81F0BF28);
+	WREG32(index_reg, 0x10101);
+	WREG32(data_reg, 0x83608CA0);
+	WREG32(index_reg, 0x10102);
+	WREG32(data_reg, 0x8018BED0);
+	WREG32(index_reg, 0x10200);
+	WREG32(data_reg, 0x8148BF38);
+	WREG32(index_reg, 0x10201);
+	WREG32(data_reg, 0x84408C80);
+	WREG32(index_reg, 0x10202);
+	WREG32(data_reg, 0x8008BEB8);
+	WREG32(index_reg, 0x10300);
+	WREG32(data_reg, 0x80B0BF78);
+	WREG32(index_reg, 0x10301);
+	WREG32(data_reg, 0x85008C20);
+	WREG32(index_reg, 0x10302);
+	WREG32(data_reg, 0x8020BEA0);
+	WREG32(index_reg, 0x10400);
+	WREG32(data_reg, 0x8028BF90);
+	WREG32(index_reg, 0x10401);
+	WREG32(data_reg, 0x85E08BC0);
+	WREG32(index_reg, 0x10402);
+	WREG32(data_reg, 0x8018BE90);
+	WREG32(index_reg, 0x10500);
+	WREG32(data_reg, 0xBFB8BFB0);
+	WREG32(index_reg, 0x10501);
+	WREG32(data_reg, 0x86C08B40);
+	WREG32(index_reg, 0x10502);
+	WREG32(data_reg, 0x8010BE90);
+	WREG32(index_reg, 0x10600);
+	WREG32(data_reg, 0xBF58BFC8);
+	WREG32(index_reg, 0x10601);
+	WREG32(data_reg, 0x87A08AA0);
+	WREG32(index_reg, 0x10602);
+	WREG32(data_reg, 0x8010BE98);
+	WREG32(index_reg, 0x10700);
+	WREG32(data_reg, 0xBF10BFF0);
+	WREG32(index_reg, 0x10701);
+	WREG32(data_reg, 0x886089E0);
+	WREG32(index_reg, 0x10702);
+	WREG32(data_reg, 0x8018BEB0);
+	WREG32(index_reg, 0x10800);
+	WREG32(data_reg, 0xBED8BFE8);
+	WREG32(index_reg, 0x10801);
+	WREG32(data_reg, 0x89408940);
+	WREG32(index_reg, 0x10802);
+	WREG32(data_reg, 0xBFE8BED8);
+	WREG32(index_reg, 0x20000);
+	WREG32(data_reg, 0x80008000);
+	WREG32(index_reg, 0x20001);
+	WREG32(data_reg, 0x90008000);
+	WREG32(index_reg, 0x20002);
+	WREG32(data_reg, 0x80008000);
+	WREG32(index_reg, 0x20003);
+	WREG32(data_reg, 0x80008000);
+	WREG32(index_reg, 0x20100);
+	WREG32(data_reg, 0x80108000);
+	WREG32(index_reg, 0x20101);
+	WREG32(data_reg, 0x8FE0BF70);
+	WREG32(index_reg, 0x20102);
+	WREG32(data_reg, 0xBFE880C0);
+	WREG32(index_reg, 0x20103);
+	WREG32(data_reg, 0x80008000);
+	WREG32(index_reg, 0x20200);
+	WREG32(data_reg, 0x8018BFF8);
+	WREG32(index_reg, 0x20201);
+	WREG32(data_reg, 0x8F80BF08);
+	WREG32(index_reg, 0x20202);
+	WREG32(data_reg, 0xBFD081A0);
+	WREG32(index_reg, 0x20203);
+	WREG32(data_reg, 0xBFF88000);
+	WREG32(index_reg, 0x20300);
+	WREG32(data_reg, 0x80188000);
+	WREG32(index_reg, 0x20301);
+	WREG32(data_reg, 0x8EE0BEC0);
+	WREG32(index_reg, 0x20302);
+	WREG32(data_reg, 0xBFB082A0);
+	WREG32(index_reg, 0x20303);
+	WREG32(data_reg, 0x80008000);
+	WREG32(index_reg, 0x20400);
+	WREG32(data_reg, 0x80188000);
+	WREG32(index_reg, 0x20401);
+	WREG32(data_reg, 0x8E00BEA0);
+	WREG32(index_reg, 0x20402);
+	WREG32(data_reg, 0xBF8883C0);
+	WREG32(index_reg, 0x20403);
+	WREG32(data_reg, 0x80008000);
+	WREG32(index_reg, 0x20500);
+	WREG32(data_reg, 0x80188000);
+	WREG32(index_reg, 0x20501);
+	WREG32(data_reg, 0x8D00BE90);
+	WREG32(index_reg, 0x20502);
+	WREG32(data_reg, 0xBF588500);
+	WREG32(index_reg, 0x20503);
+	WREG32(data_reg, 0x80008008);
+	WREG32(index_reg, 0x20600);
+	WREG32(data_reg, 0x80188000);
+	WREG32(index_reg, 0x20601);
+	WREG32(data_reg, 0x8BC0BE98);
+	WREG32(index_reg, 0x20602);
+	WREG32(data_reg, 0xBF308660);
+	WREG32(index_reg, 0x20603);
+	WREG32(data_reg, 0x80008008);
+	WREG32(index_reg, 0x20700);
+	WREG32(data_reg, 0x80108000);
+	WREG32(index_reg, 0x20701);
+	WREG32(data_reg, 0x8A80BEB0);
+	WREG32(index_reg, 0x20702);
+	WREG32(data_reg, 0xBF0087C0);
+	WREG32(index_reg, 0x20703);
+	WREG32(data_reg, 0x80008008);
+	WREG32(index_reg, 0x20800);
+	WREG32(data_reg, 0x80108000);
+	WREG32(index_reg, 0x20801);
+	WREG32(data_reg, 0x8920BED0);
+	WREG32(index_reg, 0x20802);
+	WREG32(data_reg, 0xBED08920);
+	WREG32(index_reg, 0x20803);
+	WREG32(data_reg, 0x80008010);
+	WREG32(index_reg, 0x30000);
+	WREG32(data_reg, 0x90008000);
+	WREG32(index_reg, 0x30001);
+	WREG32(data_reg, 0x80008000);
+	WREG32(index_reg, 0x30100);
+	WREG32(data_reg, 0x8FE0BF90);
+	WREG32(index_reg, 0x30101);
+	WREG32(data_reg, 0xBFF880A0);
+	WREG32(index_reg, 0x30200);
+	WREG32(data_reg, 0x8F60BF40);
+	WREG32(index_reg, 0x30201);
+	WREG32(data_reg, 0xBFE88180);
+	WREG32(index_reg, 0x30300);
+	WREG32(data_reg, 0x8EC0BF00);
+	WREG32(index_reg, 0x30301);
+	WREG32(data_reg, 0xBFC88280);
+	WREG32(index_reg, 0x30400);
+	WREG32(data_reg, 0x8DE0BEE0);
+	WREG32(index_reg, 0x30401);
+	WREG32(data_reg, 0xBFA083A0);
+	WREG32(index_reg, 0x30500);
+	WREG32(data_reg, 0x8CE0BED0);
+	WREG32(index_reg, 0x30501);
+	WREG32(data_reg, 0xBF7884E0);
+	WREG32(index_reg, 0x30600);
+	WREG32(data_reg, 0x8BA0BED8);
+	WREG32(index_reg, 0x30601);
+	WREG32(data_reg, 0xBF508640);
+	WREG32(index_reg, 0x30700);
+	WREG32(data_reg, 0x8A60BEE8);
+	WREG32(index_reg, 0x30701);
+	WREG32(data_reg, 0xBF2087A0);
+	WREG32(index_reg, 0x30800);
+	WREG32(data_reg, 0x8900BF00);
+	WREG32(index_reg, 0x30801);
+	WREG32(data_reg, 0xBF008900);
 }
 
 struct rv515_watermark {
diff --git a/drivers/gpu/drm/radeon/rv515d.h b/drivers/gpu/drm/radeon/rv515d.h
new file mode 100644
index 0000000..a65e17e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv515d.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2008 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ * Copyright 2009 Jerome Glisse.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef __RV515D_H__
+#define __RV515D_H__
+
+/*
+ * RV515 registers
+ */
+#define PCIE_INDEX			0x0030
+#define PCIE_DATA			0x0034
+#define	MC_IND_INDEX			0x0070
+#define		MC_IND_WR_EN				(1 << 24)
+#define	MC_IND_DATA			0x0074
+#define	RBBM_SOFT_RESET			0x00F0
+#define	CONFIG_MEMSIZE			0x00F8
+#define HDP_FB_LOCATION			0x0134
+#define	CP_CSQ_CNTL			0x0740
+#define	CP_CSQ_MODE			0x0744
+#define	CP_CSQ_ADDR			0x07F0
+#define	CP_CSQ_DATA			0x07F4
+#define	CP_CSQ_STAT			0x07F8
+#define	CP_CSQ2_STAT			0x07FC
+#define	RBBM_STATUS			0x0E40
+#define	DST_PIPE_CONFIG			0x170C
+#define	WAIT_UNTIL			0x1720
+#define		WAIT_2D_IDLE				(1 << 14)
+#define		WAIT_3D_IDLE				(1 << 15)
+#define		WAIT_2D_IDLECLEAN			(1 << 16)
+#define		WAIT_3D_IDLECLEAN			(1 << 17)
+#define	ISYNC_CNTL			0x1724
+#define		ISYNC_ANY2D_IDLE3D			(1 << 0)
+#define		ISYNC_ANY3D_IDLE2D			(1 << 1)
+#define		ISYNC_TRIG2D_IDLE3D			(1 << 2)
+#define		ISYNC_TRIG3D_IDLE2D			(1 << 3)
+#define		ISYNC_WAIT_IDLEGUI			(1 << 4)
+#define		ISYNC_CPSCRATCH_IDLEGUI			(1 << 5)
+#define	VAP_INDEX_OFFSET		0x208C
+#define	VAP_PVS_STATE_FLUSH_REG		0x2284
+#define	GB_ENABLE			0x4008
+#define	GB_MSPOS0			0x4010
+#define		MS_X0_SHIFT				0
+#define		MS_Y0_SHIFT				4
+#define		MS_X1_SHIFT				8
+#define		MS_Y1_SHIFT				12
+#define		MS_X2_SHIFT				16
+#define		MS_Y2_SHIFT				20
+#define		MSBD0_Y_SHIFT				24
+#define		MSBD0_X_SHIFT				28
+#define	GB_MSPOS1			0x4014
+#define		MS_X3_SHIFT				0
+#define		MS_Y3_SHIFT				4
+#define		MS_X4_SHIFT				8
+#define		MS_Y4_SHIFT				12
+#define		MS_X5_SHIFT				16
+#define		MS_Y5_SHIFT				20
+#define		MSBD1_SHIFT				24
+#define GB_TILE_CONFIG			0x4018
+#define		ENABLE_TILING				(1 << 0)
+#define		PIPE_COUNT_MASK				0x0000000E
+#define		PIPE_COUNT_SHIFT			1
+#define		TILE_SIZE_8				(0 << 4)
+#define		TILE_SIZE_16				(1 << 4)
+#define		TILE_SIZE_32				(2 << 4)
+#define		SUBPIXEL_1_12				(0 << 16)
+#define		SUBPIXEL_1_16				(1 << 16)
+#define	GB_SELECT			0x401C
+#define	GB_AA_CONFIG			0x4020
+#define	GB_PIPE_SELECT			0x402C
+#define	GA_ENHANCE			0x4274
+#define		GA_DEADLOCK_CNTL			(1 << 0)
+#define		GA_FASTSYNC_CNTL			(1 << 1)
+#define	GA_POLY_MODE			0x4288
+#define		FRONT_PTYPE_POINT			(0 << 4)
+#define		FRONT_PTYPE_LINE			(1 << 4)
+#define		FRONT_PTYPE_TRIANGE			(2 << 4)
+#define		BACK_PTYPE_POINT			(0 << 7)
+#define		BACK_PTYPE_LINE				(1 << 7)
+#define		BACK_PTYPE_TRIANGE			(2 << 7)
+#define	GA_ROUND_MODE			0x428C
+#define		GEOMETRY_ROUND_TRUNC			(0 << 0)
+#define		GEOMETRY_ROUND_NEAREST			(1 << 0)
+#define		COLOR_ROUND_TRUNC			(0 << 2)
+#define		COLOR_ROUND_NEAREST			(1 << 2)
+#define	SU_REG_DEST			0x42C8
+#define	RB3D_DSTCACHE_CTLSTAT		0x4E4C
+#define		RB3D_DC_FLUSH				(2 << 0)
+#define		RB3D_DC_FREE				(2 << 2)
+#define		RB3D_DC_FINISH				(1 << 4)
+#define ZB_ZCACHE_CTLSTAT		0x4F18
+#define		ZC_FLUSH				(1 << 0)
+#define		ZC_FREE					(1 << 1)
+#define DC_LB_MEMORY_SPLIT		0x6520
+#define		DC_LB_MEMORY_SPLIT_MASK			0x00000003
+#define		DC_LB_MEMORY_SPLIT_SHIFT		0
+#define		DC_LB_MEMORY_SPLIT_D1HALF_D2HALF	0
+#define		DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q		1
+#define		DC_LB_MEMORY_SPLIT_D1_ONLY		2
+#define		DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q		3
+#define		DC_LB_MEMORY_SPLIT_SHIFT_MODE		(1 << 2)
+#define		DC_LB_DISP1_END_ADR_SHIFT		4
+#define		DC_LB_DISP1_END_ADR_MASK		0x00007FF0
+#define D1MODE_PRIORITY_A_CNT		0x6548
+#define		MODE_PRIORITY_MARK_MASK			0x00007FFF
+#define		MODE_PRIORITY_OFF			(1 << 16)
+#define		MODE_PRIORITY_ALWAYS_ON			(1 << 20)
+#define		MODE_PRIORITY_FORCE_MASK		(1 << 24)
+#define D1MODE_PRIORITY_B_CNT		0x654C
+#define LB_MAX_REQ_OUTSTANDING		0x6D58
+#define		LB_D1_MAX_REQ_OUTSTANDING_MASK		0x0000000F
+#define		LB_D1_MAX_REQ_OUTSTANDING_SHIFT		0
+#define		LB_D2_MAX_REQ_OUTSTANDING_MASK		0x000F0000
+#define		LB_D2_MAX_REQ_OUTSTANDING_SHIFT		16
+#define D2MODE_PRIORITY_A_CNT		0x6D48
+#define D2MODE_PRIORITY_B_CNT		0x6D4C
+
+/* ix[MC] registers */
+#define MC_FB_LOCATION			0x01
+#define		MC_FB_START_MASK			0x0000FFFF
+#define		MC_FB_START_SHIFT			0
+#define		MC_FB_TOP_MASK				0xFFFF0000
+#define		MC_FB_TOP_SHIFT				16
+#define MC_AGP_LOCATION			0x02
+#define		MC_AGP_START_MASK			0x0000FFFF
+#define		MC_AGP_START_SHIFT			0
+#define		MC_AGP_TOP_MASK				0xFFFF0000
+#define		MC_AGP_TOP_SHIFT			16
+#define MC_AGP_BASE			0x03
+#define MC_AGP_BASE_2			0x04
+#define	MC_CNTL				0x5
+#define		MEM_NUM_CHANNELS_MASK			0x00000003
+#define	MC_STATUS			0x08
+#define		MC_STATUS_IDLE				(1 << 4)
+#define	MC_MISC_LAT_TIMER		0x09
+#define		MC_CPR_INIT_LAT_MASK			0x0000000F
+#define		MC_VF_INIT_LAT_MASK			0x000000F0
+#define		MC_DISP0R_INIT_LAT_MASK			0x00000F00
+#define		MC_DISP0R_INIT_LAT_SHIFT		8
+#define		MC_DISP1R_INIT_LAT_MASK			0x0000F000
+#define		MC_DISP1R_INIT_LAT_SHIFT		12
+#define		MC_FIXED_INIT_LAT_MASK			0x000F0000
+#define		MC_E2R_INIT_LAT_MASK			0x00F00000
+#define		SAME_PAGE_PRIO_MASK			0x0F000000
+#define		MC_GLOBW_INIT_LAT_MASK			0xF0000000
+
+
+/*
+ * PM4 packet
+ */
+#define CP_PACKET0			0x00000000
+#define		PACKET0_BASE_INDEX_SHIFT	0
+#define		PACKET0_BASE_INDEX_MASK		(0x1ffff << 0)
+#define		PACKET0_COUNT_SHIFT		16
+#define		PACKET0_COUNT_MASK		(0x3fff << 16)
+#define CP_PACKET1			0x40000000
+#define CP_PACKET2			0x80000000
+#define		PACKET2_PAD_SHIFT		0
+#define		PACKET2_PAD_MASK		(0x3fffffff << 0)
+#define CP_PACKET3			0xC0000000
+#define		PACKET3_IT_OPCODE_SHIFT		8
+#define		PACKET3_IT_OPCODE_MASK		(0xff << 8)
+#define		PACKET3_COUNT_SHIFT		16
+#define		PACKET3_COUNT_MASK		(0x3fff << 16)
+/* PACKET3 op code */
+#define		PACKET3_NOP			0x10
+#define		PACKET3_3D_DRAW_VBUF		0x28
+#define		PACKET3_3D_DRAW_IMMD		0x29
+#define		PACKET3_3D_DRAW_INDX		0x2A
+#define		PACKET3_3D_LOAD_VBPNTR		0x2F
+#define		PACKET3_INDX_BUFFER		0x33
+#define		PACKET3_3D_DRAW_VBUF_2		0x34
+#define		PACKET3_3D_DRAW_IMMD_2		0x35
+#define		PACKET3_3D_DRAW_INDX_2		0x36
+#define		PACKET3_BITBLT_MULTI		0x9B
+
+#define PACKET0(reg, n)	(CP_PACKET0 |					\
+			 REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) |	\
+			 REG_SET(PACKET0_COUNT, (n)))
+#define PACKET2(v)	(CP_PACKET2 | REG_SET(PACKET2_PAD, (v)))
+#define PACKET3(op, n)	(CP_PACKET3 |					\
+			 REG_SET(PACKET3_IT_OPCODE, (op)) |		\
+			 REG_SET(PACKET3_COUNT, (n)))
+
+#define	PACKET_TYPE0	0
+#define	PACKET_TYPE1	1
+#define	PACKET_TYPE2	2
+#define	PACKET_TYPE3	3
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
+#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+
+#endif
+
diff --git a/drivers/gpu/drm/radeon/rv515r.h b/drivers/gpu/drm/radeon/rv515r.h
deleted file mode 100644
index f3cf840..0000000
--- a/drivers/gpu/drm/radeon/rv515r.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2008 Advanced Micro Devices, Inc.
- * Copyright 2008 Red Hat Inc.
- * Copyright 2009 Jerome Glisse.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Dave Airlie
- *          Alex Deucher
- *          Jerome Glisse
- */
-#ifndef RV515R_H
-#define RV515R_H
-
-/* RV515 registers */
-#define PCIE_INDEX			0x0030
-#define PCIE_DATA			0x0034
-#define	MC_IND_INDEX			0x0070
-#define		MC_IND_WR_EN				(1 << 24)
-#define	MC_IND_DATA			0x0074
-#define	RBBM_SOFT_RESET			0x00F0
-#define	CONFIG_MEMSIZE			0x00F8
-#define HDP_FB_LOCATION			0x0134
-#define	CP_CSQ_CNTL			0x0740
-#define	CP_CSQ_MODE			0x0744
-#define	CP_CSQ_ADDR			0x07F0
-#define	CP_CSQ_DATA			0x07F4
-#define	CP_CSQ_STAT			0x07F8
-#define	CP_CSQ2_STAT			0x07FC
-#define	RBBM_STATUS			0x0E40
-#define	DST_PIPE_CONFIG			0x170C
-#define	WAIT_UNTIL			0x1720
-#define		WAIT_2D_IDLE				(1 << 14)
-#define		WAIT_3D_IDLE				(1 << 15)
-#define		WAIT_2D_IDLECLEAN			(1 << 16)
-#define		WAIT_3D_IDLECLEAN			(1 << 17)
-#define	ISYNC_CNTL			0x1724
-#define		ISYNC_ANY2D_IDLE3D			(1 << 0)
-#define		ISYNC_ANY3D_IDLE2D			(1 << 1)
-#define		ISYNC_TRIG2D_IDLE3D			(1 << 2)
-#define		ISYNC_TRIG3D_IDLE2D			(1 << 3)
-#define		ISYNC_WAIT_IDLEGUI			(1 << 4)
-#define		ISYNC_CPSCRATCH_IDLEGUI			(1 << 5)
-#define	VAP_INDEX_OFFSET		0x208C
-#define	VAP_PVS_STATE_FLUSH_REG		0x2284
-#define	GB_ENABLE			0x4008
-#define	GB_MSPOS0			0x4010
-#define		MS_X0_SHIFT				0
-#define		MS_Y0_SHIFT				4
-#define		MS_X1_SHIFT				8
-#define		MS_Y1_SHIFT				12
-#define		MS_X2_SHIFT				16
-#define		MS_Y2_SHIFT				20
-#define		MSBD0_Y_SHIFT				24
-#define		MSBD0_X_SHIFT				28
-#define	GB_MSPOS1			0x4014
-#define		MS_X3_SHIFT				0
-#define		MS_Y3_SHIFT				4
-#define		MS_X4_SHIFT				8
-#define		MS_Y4_SHIFT				12
-#define		MS_X5_SHIFT				16
-#define		MS_Y5_SHIFT				20
-#define		MSBD1_SHIFT				24
-#define GB_TILE_CONFIG			0x4018
-#define		ENABLE_TILING				(1 << 0)
-#define		PIPE_COUNT_MASK				0x0000000E
-#define		PIPE_COUNT_SHIFT			1
-#define		TILE_SIZE_8				(0 << 4)
-#define		TILE_SIZE_16				(1 << 4)
-#define		TILE_SIZE_32				(2 << 4)
-#define		SUBPIXEL_1_12				(0 << 16)
-#define		SUBPIXEL_1_16				(1 << 16)
-#define	GB_SELECT			0x401C
-#define	GB_AA_CONFIG			0x4020
-#define	GB_PIPE_SELECT			0x402C
-#define	GA_ENHANCE			0x4274
-#define		GA_DEADLOCK_CNTL			(1 << 0)
-#define		GA_FASTSYNC_CNTL			(1 << 1)
-#define	GA_POLY_MODE			0x4288
-#define		FRONT_PTYPE_POINT			(0 << 4)
-#define		FRONT_PTYPE_LINE			(1 << 4)
-#define		FRONT_PTYPE_TRIANGE			(2 << 4)
-#define		BACK_PTYPE_POINT			(0 << 7)
-#define		BACK_PTYPE_LINE				(1 << 7)
-#define		BACK_PTYPE_TRIANGE			(2 << 7)
-#define	GA_ROUND_MODE			0x428C
-#define		GEOMETRY_ROUND_TRUNC			(0 << 0)
-#define		GEOMETRY_ROUND_NEAREST			(1 << 0)
-#define		COLOR_ROUND_TRUNC			(0 << 2)
-#define		COLOR_ROUND_NEAREST			(1 << 2)
-#define	SU_REG_DEST			0x42C8
-#define	RB3D_DSTCACHE_CTLSTAT		0x4E4C
-#define		RB3D_DC_FLUSH				(2 << 0)
-#define		RB3D_DC_FREE				(2 << 2)
-#define		RB3D_DC_FINISH				(1 << 4)
-#define ZB_ZCACHE_CTLSTAT		0x4F18
-#define		ZC_FLUSH				(1 << 0)
-#define		ZC_FREE					(1 << 1)
-#define DC_LB_MEMORY_SPLIT		0x6520
-#define		DC_LB_MEMORY_SPLIT_MASK			0x00000003
-#define		DC_LB_MEMORY_SPLIT_SHIFT		0
-#define		DC_LB_MEMORY_SPLIT_D1HALF_D2HALF	0
-#define		DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q		1
-#define		DC_LB_MEMORY_SPLIT_D1_ONLY		2
-#define		DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q		3
-#define		DC_LB_MEMORY_SPLIT_SHIFT_MODE		(1 << 2)
-#define		DC_LB_DISP1_END_ADR_SHIFT		4
-#define		DC_LB_DISP1_END_ADR_MASK		0x00007FF0
-#define D1MODE_PRIORITY_A_CNT		0x6548
-#define		MODE_PRIORITY_MARK_MASK			0x00007FFF
-#define		MODE_PRIORITY_OFF			(1 << 16)
-#define		MODE_PRIORITY_ALWAYS_ON			(1 << 20)
-#define		MODE_PRIORITY_FORCE_MASK		(1 << 24)
-#define D1MODE_PRIORITY_B_CNT		0x654C
-#define LB_MAX_REQ_OUTSTANDING		0x6D58
-#define		LB_D1_MAX_REQ_OUTSTANDING_MASK		0x0000000F
-#define		LB_D1_MAX_REQ_OUTSTANDING_SHIFT		0
-#define		LB_D2_MAX_REQ_OUTSTANDING_MASK		0x000F0000
-#define		LB_D2_MAX_REQ_OUTSTANDING_SHIFT		16
-#define D2MODE_PRIORITY_A_CNT		0x6D48
-#define D2MODE_PRIORITY_B_CNT		0x6D4C
-
-/* ix[MC] registers */
-#define MC_FB_LOCATION			0x01
-#define		MC_FB_START_MASK			0x0000FFFF
-#define		MC_FB_START_SHIFT			0
-#define		MC_FB_TOP_MASK				0xFFFF0000
-#define		MC_FB_TOP_SHIFT				16
-#define MC_AGP_LOCATION			0x02
-#define		MC_AGP_START_MASK			0x0000FFFF
-#define		MC_AGP_START_SHIFT			0
-#define		MC_AGP_TOP_MASK				0xFFFF0000
-#define		MC_AGP_TOP_SHIFT			16
-#define MC_AGP_BASE			0x03
-#define MC_AGP_BASE_2			0x04
-#define	MC_CNTL				0x5
-#define		MEM_NUM_CHANNELS_MASK			0x00000003
-#define	MC_STATUS			0x08
-#define		MC_STATUS_IDLE				(1 << 4)
-#define	MC_MISC_LAT_TIMER		0x09
-#define		MC_CPR_INIT_LAT_MASK			0x0000000F
-#define		MC_VF_INIT_LAT_MASK			0x000000F0
-#define		MC_DISP0R_INIT_LAT_MASK			0x00000F00
-#define		MC_DISP0R_INIT_LAT_SHIFT		8
-#define		MC_DISP1R_INIT_LAT_MASK			0x0000F000
-#define		MC_DISP1R_INIT_LAT_SHIFT		12
-#define		MC_FIXED_INIT_LAT_MASK			0x000F0000
-#define		MC_E2R_INIT_LAT_MASK			0x00F00000
-#define		SAME_PAGE_PRIO_MASK			0x0F000000
-#define		MC_GLOBW_INIT_LAT_MASK			0xF0000000
-
-
-#endif
-
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 21d8ffd..b574c73 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -25,100 +25,1038 @@
  *          Alex Deucher
  *          Jerome Glisse
  */
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
 #include "drmP.h"
-#include "radeon_reg.h"
 #include "radeon.h"
+#include "radeon_drm.h"
+#include "rv770d.h"
+#include "avivod.h"
+#include "atom.h"
 
-/* rv770,rv730,rv710  depends on : */
-void rs600_mc_disable_clients(struct radeon_device *rdev);
+#define R700_PFP_UCODE_SIZE 848
+#define R700_PM4_UCODE_SIZE 1360
 
-/* This files gather functions specifics to:
- * rv770,rv730,rv710
- *
- * Some of these functions might be used by newer ASICs.
- */
-int rv770_mc_wait_for_idle(struct radeon_device *rdev);
-void rv770_gpu_init(struct radeon_device *rdev);
+static void rv770_gpu_init(struct radeon_device *rdev);
+void rv770_fini(struct radeon_device *rdev);
 
 
 /*
- * MC
+ * GART
  */
-int rv770_mc_init(struct radeon_device *rdev)
+int rv770_pcie_gart_enable(struct radeon_device *rdev)
 {
-	uint32_t tmp;
+	u32 tmp;
+	int r, i;
 
-	rv770_gpu_init(rdev);
+	if (rdev->gart.table.vram.robj == NULL) {
+		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
+		return -EINVAL;
+	}
+	r = radeon_gart_table_vram_pin(rdev);
+	if (r)
+		return r;
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
+				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
+				EFFECTIVE_L2_QUEUE_SIZE(7));
+	WREG32(VM_L2_CNTL2, 0);
+	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
+	/* Setup TLB control */
+	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
+		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
+		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
+	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12);
+	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
+	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
+				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
+	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
+			(u32)(rdev->dummy_page.addr >> 12));
+	for (i = 1; i < 7; i++)
+		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
 
-	/* setup the gart before changing location so we can ask to
-	 * discard unmapped mc request
-	 */
-	/* FIXME: disable out of gart access */
-	tmp = rdev->mc.gtt_location / 4096;
-	tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp);
-	WREG32(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp);
-	tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096;
-	tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp);
-	WREG32(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp);
-
-	rs600_mc_disable_clients(rdev);
-	if (rv770_mc_wait_for_idle(rdev)) {
-		printk(KERN_WARNING "Failed to wait MC idle while "
-		       "programming pipes. Bad things might happen.\n");
-	}
-
-	tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
-	tmp = REG_SET(R700_MC_FB_TOP, tmp >> 24);
-	tmp |= REG_SET(R700_MC_FB_BASE, rdev->mc.vram_location >> 24);
-	WREG32(R700_MC_VM_FB_LOCATION, tmp);
-	tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
-	tmp = REG_SET(R700_MC_AGP_TOP, tmp >> 22);
-	WREG32(R700_MC_VM_AGP_TOP, tmp);
-	tmp = REG_SET(R700_MC_AGP_BOT, rdev->mc.gtt_location >> 22);
-	WREG32(R700_MC_VM_AGP_BOT, tmp);
+	r600_pcie_gart_tlb_flush(rdev);
+	rdev->gart.ready = true;
 	return 0;
 }
 
-void rv770_mc_fini(struct radeon_device *rdev)
+void rv770_pcie_gart_disable(struct radeon_device *rdev)
+{
+	u32 tmp;
+	int i;
+
+	/* Disable all tables */
+	for (i = 0; i < 7; i++)
+		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
+
+	/* Setup L2 cache */
+	WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
+				EFFECTIVE_L2_QUEUE_SIZE(7));
+	WREG32(VM_L2_CNTL2, 0);
+	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
+	/* Setup TLB control */
+	tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
+	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
+	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
+	if (rdev->gart.table.vram.robj) {
+		radeon_object_kunmap(rdev->gart.table.vram.robj);
+		radeon_object_unpin(rdev->gart.table.vram.robj);
+	}
+}
+
+void rv770_pcie_gart_fini(struct radeon_device *rdev)
 {
-	/* FIXME: implement */
+	rv770_pcie_gart_disable(rdev);
+	radeon_gart_table_vram_free(rdev);
+	radeon_gart_fini(rdev);
 }
 
 
 /*
- * Global GPU functions
+ * MC
  */
-void rv770_errata(struct radeon_device *rdev)
+static void rv770_mc_resume(struct radeon_device *rdev)
 {
-	rdev->pll_errata = 0;
+	u32 d1vga_control, d2vga_control;
+	u32 vga_render_control, vga_hdp_control;
+	u32 d1crtc_control, d2crtc_control;
+	u32 new_d1grph_primary, new_d1grph_secondary;
+	u32 new_d2grph_primary, new_d2grph_secondary;
+	u64 old_vram_start;
+	u32 tmp;
+	int i, j;
+
+	/* Initialize HDP */
+	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
+		WREG32((0x2c14 + j), 0x00000000);
+		WREG32((0x2c18 + j), 0x00000000);
+		WREG32((0x2c1c + j), 0x00000000);
+		WREG32((0x2c20 + j), 0x00000000);
+		WREG32((0x2c24 + j), 0x00000000);
+	}
+	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
+
+	d1vga_control = RREG32(D1VGA_CONTROL);
+	d2vga_control = RREG32(D2VGA_CONTROL);
+	vga_render_control = RREG32(VGA_RENDER_CONTROL);
+	vga_hdp_control = RREG32(VGA_HDP_CONTROL);
+	d1crtc_control = RREG32(D1CRTC_CONTROL);
+	d2crtc_control = RREG32(D2CRTC_CONTROL);
+	old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
+	new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
+	new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
+	new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
+	new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
+	new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
+	new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
+	new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
+	new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
+
+	/* Stop all video */
+	WREG32(D1VGA_CONTROL, 0);
+	WREG32(D2VGA_CONTROL, 0);
+	WREG32(VGA_RENDER_CONTROL, 0);
+	WREG32(D1CRTC_UPDATE_LOCK, 1);
+	WREG32(D2CRTC_UPDATE_LOCK, 1);
+	WREG32(D1CRTC_CONTROL, 0);
+	WREG32(D2CRTC_CONTROL, 0);
+	WREG32(D1CRTC_UPDATE_LOCK, 0);
+	WREG32(D2CRTC_UPDATE_LOCK, 0);
+
+	mdelay(1);
+	if (r600_mc_wait_for_idle(rdev)) {
+		printk(KERN_WARNING "[drm] MC not idle !\n");
+	}
+
+	/* Lockout access through VGA aperture*/
+	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
+
+	/* Update configuration */
+	WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
+	WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
+	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+	tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16;
+	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
+	WREG32(MC_VM_FB_LOCATION, tmp);
+	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
+	WREG32(HDP_NONSURFACE_INFO, (2 << 7));
+	WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
+	if (rdev->flags & RADEON_IS_AGP) {
+		WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16);
+		WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
+		WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
+	} else {
+		WREG32(MC_VM_AGP_BASE, 0);
+		WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
+		WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
+	}
+	WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
+	WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
+	WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
+	WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
+	WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
+
+	/* Unlock host access */
+	WREG32(VGA_HDP_CONTROL, vga_hdp_control);
+
+	mdelay(1);
+	if (r600_mc_wait_for_idle(rdev)) {
+		printk(KERN_WARNING "[drm] MC not idle !\n");
+	}
+
+	/* Restore video state */
+	WREG32(D1CRTC_UPDATE_LOCK, 1);
+	WREG32(D2CRTC_UPDATE_LOCK, 1);
+	WREG32(D1CRTC_CONTROL, d1crtc_control);
+	WREG32(D2CRTC_CONTROL, d2crtc_control);
+	WREG32(D1CRTC_UPDATE_LOCK, 0);
+	WREG32(D2CRTC_UPDATE_LOCK, 0);
+	WREG32(D1VGA_CONTROL, d1vga_control);
+	WREG32(D2VGA_CONTROL, d2vga_control);
+	WREG32(VGA_RENDER_CONTROL, vga_render_control);
+
+	/* we need to own VRAM, so turn off the VGA renderer here
+	 * to stop it overwriting our objects */
+	radeon_avivo_vga_render_disable(rdev);
 }
 
-int rv770_mc_wait_for_idle(struct radeon_device *rdev)
+
+/*
+ * CP.
+ */
+void r700_cp_stop(struct radeon_device *rdev)
 {
-	/* FIXME: implement */
-	return 0;
+	WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
 }
 
-void rv770_gpu_init(struct radeon_device *rdev)
+
+static int rv770_cp_load_microcode(struct radeon_device *rdev)
 {
-	/* FIXME: implement */
+	const __be32 *fw_data;
+	int i;
+
+	if (!rdev->me_fw || !rdev->pfp_fw)
+		return -EINVAL;
+
+	r700_cp_stop(rdev);
+	WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0));
+
+	/* Reset cp */
+	WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
+	RREG32(GRBM_SOFT_RESET);
+	mdelay(15);
+	WREG32(GRBM_SOFT_RESET, 0);
+
+	fw_data = (const __be32 *)rdev->pfp_fw->data;
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+	for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+		WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+
+	fw_data = (const __be32 *)rdev->me_fw->data;
+	WREG32(CP_ME_RAM_WADDR, 0);
+	for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+		WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
+
+	WREG32(CP_PFP_UCODE_ADDR, 0);
+	WREG32(CP_ME_RAM_WADDR, 0);
+	WREG32(CP_ME_RAM_RADDR, 0);
+	return 0;
 }
 
 
 /*
- * VRAM info
+ * Core functions
  */
-void rv770_vram_get_type(struct radeon_device *rdev)
+static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+						u32 num_backends,
+						u32 backend_disable_mask)
+{
+	u32 backend_map = 0;
+	u32 enabled_backends_mask;
+	u32 enabled_backends_count;
+	u32 cur_pipe;
+	u32 swizzle_pipe[R7XX_MAX_PIPES];
+	u32 cur_backend;
+	u32 i;
+
+	if (num_tile_pipes > R7XX_MAX_PIPES)
+		num_tile_pipes = R7XX_MAX_PIPES;
+	if (num_tile_pipes < 1)
+		num_tile_pipes = 1;
+	if (num_backends > R7XX_MAX_BACKENDS)
+		num_backends = R7XX_MAX_BACKENDS;
+	if (num_backends < 1)
+		num_backends = 1;
+
+	enabled_backends_mask = 0;
+	enabled_backends_count = 0;
+	for (i = 0; i < R7XX_MAX_BACKENDS; ++i) {
+		if (((backend_disable_mask >> i) & 1) == 0) {
+			enabled_backends_mask |= (1 << i);
+			++enabled_backends_count;
+		}
+		if (enabled_backends_count == num_backends)
+			break;
+	}
+
+	if (enabled_backends_count == 0) {
+		enabled_backends_mask = 1;
+		enabled_backends_count = 1;
+	}
+
+	if (enabled_backends_count != num_backends)
+		num_backends = enabled_backends_count;
+
+	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
+	switch (num_tile_pipes) {
+	case 1:
+		swizzle_pipe[0] = 0;
+		break;
+	case 2:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 1;
+		break;
+	case 3:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 1;
+		break;
+	case 4:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 3;
+		swizzle_pipe[3] = 1;
+		break;
+	case 5:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 1;
+		swizzle_pipe[4] = 3;
+		break;
+	case 6:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 5;
+		swizzle_pipe[4] = 3;
+		swizzle_pipe[5] = 1;
+		break;
+	case 7:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 3;
+		swizzle_pipe[5] = 1;
+		swizzle_pipe[6] = 5;
+		break;
+	case 8:
+		swizzle_pipe[0] = 0;
+		swizzle_pipe[1] = 2;
+		swizzle_pipe[2] = 4;
+		swizzle_pipe[3] = 6;
+		swizzle_pipe[4] = 3;
+		swizzle_pipe[5] = 1;
+		swizzle_pipe[6] = 7;
+		swizzle_pipe[7] = 5;
+		break;
+	}
+
+	cur_backend = 0;
+	for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+		while (((1 << cur_backend) & enabled_backends_mask) == 0)
+			cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+
+		backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+		cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+	}
+
+	return backend_map;
+}
+
+static void rv770_gpu_init(struct radeon_device *rdev)
 {
-	/* FIXME: implement */
+	int i, j, num_qd_pipes;
+	u32 sx_debug_1;
+	u32 smx_dc_ctl0;
+	u32 num_gs_verts_per_thread;
+	u32 vgt_gs_per_es;
+	u32 gs_prim_buffer_depth = 0;
+	u32 sq_ms_fifo_sizes;
+	u32 sq_config;
+	u32 sq_thread_resource_mgmt;
+	u32 hdp_host_path_cntl;
+	u32 sq_dyn_gpr_size_simd_ab_0;
+	u32 backend_map;
+	u32 gb_tiling_config = 0;
+	u32 cc_rb_backend_disable = 0;
+	u32 cc_gc_shader_pipe_config = 0;
+	u32 mc_arb_ramcfg;
+	u32 db_debug4;
+
+	/* setup chip specs */
+	switch (rdev->family) {
+	case CHIP_RV770:
+		rdev->config.rv770.max_pipes = 4;
+		rdev->config.rv770.max_tile_pipes = 8;
+		rdev->config.rv770.max_simds = 10;
+		rdev->config.rv770.max_backends = 4;
+		rdev->config.rv770.max_gprs = 256;
+		rdev->config.rv770.max_threads = 248;
+		rdev->config.rv770.max_stack_entries = 512;
+		rdev->config.rv770.max_hw_contexts = 8;
+		rdev->config.rv770.max_gs_threads = 16 * 2;
+		rdev->config.rv770.sx_max_export_size = 128;
+		rdev->config.rv770.sx_max_export_pos_size = 16;
+		rdev->config.rv770.sx_max_export_smx_size = 112;
+		rdev->config.rv770.sq_num_cf_insts = 2;
+
+		rdev->config.rv770.sx_num_of_sets = 7;
+		rdev->config.rv770.sc_prim_fifo_size = 0xF9;
+		rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
+		break;
+	case CHIP_RV730:
+		rdev->config.rv770.max_pipes = 2;
+		rdev->config.rv770.max_tile_pipes = 4;
+		rdev->config.rv770.max_simds = 8;
+		rdev->config.rv770.max_backends = 2;
+		rdev->config.rv770.max_gprs = 128;
+		rdev->config.rv770.max_threads = 248;
+		rdev->config.rv770.max_stack_entries = 256;
+		rdev->config.rv770.max_hw_contexts = 8;
+		rdev->config.rv770.max_gs_threads = 16 * 2;
+		rdev->config.rv770.sx_max_export_size = 256;
+		rdev->config.rv770.sx_max_export_pos_size = 32;
+		rdev->config.rv770.sx_max_export_smx_size = 224;
+		rdev->config.rv770.sq_num_cf_insts = 2;
+
+		rdev->config.rv770.sx_num_of_sets = 7;
+		rdev->config.rv770.sc_prim_fifo_size = 0xf9;
+		rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
+		if (rdev->config.rv770.sx_max_export_pos_size > 16) {
+			rdev->config.rv770.sx_max_export_pos_size -= 16;
+			rdev->config.rv770.sx_max_export_smx_size += 16;
+		}
+		break;
+	case CHIP_RV710:
+		rdev->config.rv770.max_pipes = 2;
+		rdev->config.rv770.max_tile_pipes = 2;
+		rdev->config.rv770.max_simds = 2;
+		rdev->config.rv770.max_backends = 1;
+		rdev->config.rv770.max_gprs = 256;
+		rdev->config.rv770.max_threads = 192;
+		rdev->config.rv770.max_stack_entries = 256;
+		rdev->config.rv770.max_hw_contexts = 4;
+		rdev->config.rv770.max_gs_threads = 8 * 2;
+		rdev->config.rv770.sx_max_export_size = 128;
+		rdev->config.rv770.sx_max_export_pos_size = 16;
+		rdev->config.rv770.sx_max_export_smx_size = 112;
+		rdev->config.rv770.sq_num_cf_insts = 1;
+
+		rdev->config.rv770.sx_num_of_sets = 7;
+		rdev->config.rv770.sc_prim_fifo_size = 0x40;
+		rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
+		break;
+	case CHIP_RV740:
+		rdev->config.rv770.max_pipes = 4;
+		rdev->config.rv770.max_tile_pipes = 4;
+		rdev->config.rv770.max_simds = 8;
+		rdev->config.rv770.max_backends = 4;
+		rdev->config.rv770.max_gprs = 256;
+		rdev->config.rv770.max_threads = 248;
+		rdev->config.rv770.max_stack_entries = 512;
+		rdev->config.rv770.max_hw_contexts = 8;
+		rdev->config.rv770.max_gs_threads = 16 * 2;
+		rdev->config.rv770.sx_max_export_size = 256;
+		rdev->config.rv770.sx_max_export_pos_size = 32;
+		rdev->config.rv770.sx_max_export_smx_size = 224;
+		rdev->config.rv770.sq_num_cf_insts = 2;
+
+		rdev->config.rv770.sx_num_of_sets = 7;
+		rdev->config.rv770.sc_prim_fifo_size = 0x100;
+		rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130;
+
+		if (rdev->config.rv770.sx_max_export_pos_size > 16) {
+			rdev->config.rv770.sx_max_export_pos_size -= 16;
+			rdev->config.rv770.sx_max_export_smx_size += 16;
+		}
+		break;
+	default:
+		break;
+	}
+
+	/* Initialize HDP */
+	j = 0;
+	for (i = 0; i < 32; i++) {
+		WREG32((0x2c14 + j), 0x00000000);
+		WREG32((0x2c18 + j), 0x00000000);
+		WREG32((0x2c1c + j), 0x00000000);
+		WREG32((0x2c20 + j), 0x00000000);
+		WREG32((0x2c24 + j), 0x00000000);
+		j += 0x18;
+	}
+
+	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
+
+	/* setup tiling, simd, pipe config */
+	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
+
+	switch (rdev->config.rv770.max_tile_pipes) {
+	case 1:
+		gb_tiling_config |= PIPE_TILING(0);
+		break;
+	case 2:
+		gb_tiling_config |= PIPE_TILING(1);
+		break;
+	case 4:
+		gb_tiling_config |= PIPE_TILING(2);
+		break;
+	case 8:
+		gb_tiling_config |= PIPE_TILING(3);
+		break;
+	default:
+		break;
+	}
+
+	if (rdev->family == CHIP_RV770)
+		gb_tiling_config |= BANK_TILING(1);
+	else
+		gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK);
+
+	gb_tiling_config |= GROUP_SIZE(0);
+
+	if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) {
+		gb_tiling_config |= ROW_TILING(3);
+		gb_tiling_config |= SAMPLE_SPLIT(3);
+	} else {
+		gb_tiling_config |=
+			ROW_TILING(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
+		gb_tiling_config |=
+			SAMPLE_SPLIT(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT));
+	}
+
+	gb_tiling_config |= BANK_SWAPS(1);
+
+	backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes,
+							rdev->config.rv770.max_backends,
+							(0xff << rdev->config.rv770.max_backends) & 0xff);
+	gb_tiling_config |= BACKEND_MAP(backend_map);
+
+	cc_gc_shader_pipe_config =
+		INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK);
+	cc_gc_shader_pipe_config |=
+		INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK);
+
+	cc_rb_backend_disable =
+		BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK);
+
+	WREG32(GB_TILING_CONFIG, gb_tiling_config);
+	WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+	WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+
+	WREG32(CC_RB_BACKEND_DISABLE,      cc_rb_backend_disable);
+	WREG32(CC_GC_SHADER_PIPE_CONFIG,   cc_gc_shader_pipe_config);
+	WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+
+	WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+	WREG32(CGTS_SYS_TCC_DISABLE, 0);
+	WREG32(CGTS_TCC_DISABLE, 0);
+	WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
+	WREG32(CGTS_USER_TCC_DISABLE, 0);
+
+	num_qd_pipes =
+		R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK);
+	WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK);
+	WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK);
+
+	/* set HW defaults for 3D engine */
+	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
+						ROQ_IB2_START(0x2b)));
+
+	WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
+
+	WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
+					SYNC_GRADIENT |
+					SYNC_WALKER |
+					SYNC_ALIGNER));
+
+	sx_debug_1 = RREG32(SX_DEBUG_1);
+	sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
+	WREG32(SX_DEBUG_1, sx_debug_1);
+
+	smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
+	smx_dc_ctl0 &= ~CACHE_DEPTH(0x1ff);
+	smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1);
+	WREG32(SMX_DC_CTL0, smx_dc_ctl0);
+
+	WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) |
+					  GS_FLUSH_CTL(4) |
+					  ACK_FLUSH_CTL(3) |
+					  SYNC_FLUSH_CTL));
+
+	if (rdev->family == CHIP_RV770)
+		WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f));
+	else {
+		db_debug4 = RREG32(DB_DEBUG4);
+		db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER;
+		WREG32(DB_DEBUG4, db_debug4);
+	}
+
+	WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) |
+						   POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) |
+						   SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1)));
+
+	WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) |
+						 SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) |
+						 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize)));
+
+	WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
+
+	WREG32(VGT_NUM_INSTANCES, 1);
+
+	WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0));
+
+	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
+
+	WREG32(CP_PERFMON_CNTL, 0);
+
+	sq_ms_fifo_sizes = (CACHE_FIFO_SIZE(16 * rdev->config.rv770.sq_num_cf_insts) |
+			    DONE_FIFO_HIWATER(0xe0) |
+			    ALU_UPDATE_FIFO_HIWATER(0x8));
+	switch (rdev->family) {
+	case CHIP_RV770:
+		sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1);
+		break;
+	case CHIP_RV730:
+	case CHIP_RV710:
+	case CHIP_RV740:
+	default:
+		sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4);
+		break;
+	}
+	WREG32(SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
+
+	/* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+	 * should be adjusted as needed by the 2D/3D drivers.  This just sets default values
+	 */
+	sq_config = RREG32(SQ_CONFIG);
+	sq_config &= ~(PS_PRIO(3) |
+		       VS_PRIO(3) |
+		       GS_PRIO(3) |
+		       ES_PRIO(3));
+	sq_config |= (DX9_CONSTS |
+		      VC_ENABLE |
+		      EXPORT_SRC_C |
+		      PS_PRIO(0) |
+		      VS_PRIO(1) |
+		      GS_PRIO(2) |
+		      ES_PRIO(3));
+	if (rdev->family == CHIP_RV710)
+		/* no vertex cache */
+		sq_config &= ~VC_ENABLE;
+
+	WREG32(SQ_CONFIG, sq_config);
+
+	WREG32(SQ_GPR_RESOURCE_MGMT_1,  (NUM_PS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
+					 NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) |
+					 NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2)));
+
+	WREG32(SQ_GPR_RESOURCE_MGMT_2,  (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) |
+					 NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64)));
+
+	sq_thread_resource_mgmt = (NUM_PS_THREADS((rdev->config.rv770.max_threads * 4)/8) |
+				   NUM_VS_THREADS((rdev->config.rv770.max_threads * 2)/8) |
+				   NUM_ES_THREADS((rdev->config.rv770.max_threads * 1)/8));
+	if (((rdev->config.rv770.max_threads * 1) / 8) > rdev->config.rv770.max_gs_threads)
+		sq_thread_resource_mgmt |= NUM_GS_THREADS(rdev->config.rv770.max_gs_threads);
+	else
+		sq_thread_resource_mgmt |= NUM_GS_THREADS((rdev->config.rv770.max_gs_threads * 1)/8);
+	WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+
+	WREG32(SQ_STACK_RESOURCE_MGMT_1, (NUM_PS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
+						     NUM_VS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
+
+	WREG32(SQ_STACK_RESOURCE_MGMT_2, (NUM_GS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) |
+						     NUM_ES_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4)));
+
+	sq_dyn_gpr_size_simd_ab_0 = (SIMDA_RING0((rdev->config.rv770.max_gprs * 38)/64) |
+				     SIMDA_RING1((rdev->config.rv770.max_gprs * 38)/64) |
+				     SIMDB_RING0((rdev->config.rv770.max_gprs * 38)/64) |
+				     SIMDB_RING1((rdev->config.rv770.max_gprs * 38)/64));
+
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0);
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0);
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0);
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0);
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0);
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0);
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0);
+	WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0);
+
+	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
+					  FORCE_EOV_MAX_REZ_CNT(255)));
+
+	if (rdev->family == CHIP_RV710)
+		WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) |
+						AUTO_INVLD_EN(ES_AND_GS_AUTO)));
+	else
+		WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) |
+						AUTO_INVLD_EN(ES_AND_GS_AUTO)));
+
+	switch (rdev->family) {
+	case CHIP_RV770:
+	case CHIP_RV730:
+	case CHIP_RV740:
+		gs_prim_buffer_depth = 384;
+		break;
+	case CHIP_RV710:
+		gs_prim_buffer_depth = 128;
+		break;
+	default:
+		break;
+	}
+
+	num_gs_verts_per_thread = rdev->config.rv770.max_pipes * 16;
+	vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
+	/* Max value for this is 256 */
+	if (vgt_gs_per_es > 256)
+		vgt_gs_per_es = 256;
+
+	WREG32(VGT_ES_PER_GS, 128);
+	WREG32(VGT_GS_PER_ES, vgt_gs_per_es);
+	WREG32(VGT_GS_PER_VS, 2);
+
+	/* more default values. 2D/3D driver should adjust as needed */
+	WREG32(VGT_GS_VERTEX_REUSE, 16);
+	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
+	WREG32(VGT_STRMOUT_EN, 0);
+	WREG32(SX_MISC, 0);
+	WREG32(PA_SC_MODE_CNTL, 0);
+	WREG32(PA_SC_EDGERULE, 0xaaaaaaaa);
+	WREG32(PA_SC_AA_CONFIG, 0);
+	WREG32(PA_SC_CLIPRECT_RULE, 0xffff);
+	WREG32(PA_SC_LINE_STIPPLE, 0);
+	WREG32(SPI_INPUT_Z, 0);
+	WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
+	WREG32(CB_COLOR7_FRAG, 0);
+
+	/* clear render buffer base addresses */
+	WREG32(CB_COLOR0_BASE, 0);
+	WREG32(CB_COLOR1_BASE, 0);
+	WREG32(CB_COLOR2_BASE, 0);
+	WREG32(CB_COLOR3_BASE, 0);
+	WREG32(CB_COLOR4_BASE, 0);
+	WREG32(CB_COLOR5_BASE, 0);
+	WREG32(CB_COLOR6_BASE, 0);
+	WREG32(CB_COLOR7_BASE, 0);
+
+	WREG32(TCP_CNTL, 0);
+
+	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
+	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+	WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
+
+	WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
+					  NUM_CLIP_SEQ(3)));
+
 }
 
-void rv770_vram_info(struct radeon_device *rdev)
+int rv770_mc_init(struct radeon_device *rdev)
 {
-	rv770_vram_get_type(rdev);
+	fixed20_12 a;
+	u32 tmp;
+	int r;
 
-	/* FIXME: implement */
+	/* Get VRAM informations */
+	/* FIXME: Don't know how to determine vram width, need to check
+	 * vram_width usage
+	 */
+	rdev->mc.vram_width = 128;
+	rdev->mc.vram_is_ddr = true;
 	/* Could aper size report 0 ? */
 	rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
 	rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
+	/* Setup GPU memory space */
+	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
+	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
+	if (rdev->flags & RADEON_IS_AGP) {
+		r = radeon_agp_init(rdev);
+		if (r)
+			return r;
+		/* gtt_size is setup by radeon_agp_init */
+		rdev->mc.gtt_location = rdev->mc.agp_base;
+		tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
+		/* Try to put vram before or after AGP because we
+		 * we want SYSTEM_APERTURE to cover both VRAM and
+		 * AGP so that GPU can catch out of VRAM/AGP access
+		 */
+		if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
+			/* Enought place before */
+			rdev->mc.vram_location = rdev->mc.gtt_location -
+							rdev->mc.mc_vram_size;
+		} else if (tmp > rdev->mc.mc_vram_size) {
+			/* Enought place after */
+			rdev->mc.vram_location = rdev->mc.gtt_location +
+							rdev->mc.gtt_size;
+		} else {
+			/* Try to setup VRAM then AGP might not
+			 * not work on some card
+			 */
+			rdev->mc.vram_location = 0x00000000UL;
+			rdev->mc.gtt_location = rdev->mc.mc_vram_size;
+		}
+	} else {
+		rdev->mc.vram_location = 0x00000000UL;
+		rdev->mc.gtt_location = rdev->mc.mc_vram_size;
+		rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
+	}
+	rdev->mc.vram_start = rdev->mc.vram_location;
+	rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size;
+	rdev->mc.gtt_start = rdev->mc.gtt_location;
+	rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size;
+	/* FIXME: we should enforce default clock in case GPU is not in
+	 * default setup
+	 */
+	a.full = rfixed_const(100);
+	rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
+	rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
+	return 0;
+}
+int rv770_gpu_reset(struct radeon_device *rdev)
+{
+	/* FIXME: implement any rv770 specific bits */
+	return r600_gpu_reset(rdev);
+}
+
+static int rv770_startup(struct radeon_device *rdev)
+{
+	int r;
+
+	radeon_gpu_reset(rdev);
+	rv770_mc_resume(rdev);
+	r = rv770_pcie_gart_enable(rdev);
+	if (r)
+		return r;
+	rv770_gpu_init(rdev);
+
+	r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
+			      &rdev->r600_blit.shader_gpu_addr);
+	if (r) {
+		DRM_ERROR("failed to pin blit object %d\n", r);
+		return r;
+	}
+
+	r = radeon_ring_init(rdev, rdev->cp.ring_size);
+	if (r)
+		return r;
+	r = rv770_cp_load_microcode(rdev);
+	if (r)
+		return r;
+	r = r600_cp_resume(rdev);
+	if (r)
+		return r;
+	r = r600_wb_init(rdev);
+	if (r)
+		return r;
+	return 0;
+}
+
+int rv770_resume(struct radeon_device *rdev)
+{
+	int r;
+
+	if (radeon_gpu_reset(rdev)) {
+		/* FIXME: what do we want to do here ? */
+	}
+	/* post card */
+	if (rdev->is_atom_bios) {
+		atom_asic_init(rdev->mode_info.atom_context);
+	} else {
+		radeon_combios_asic_init(rdev->ddev);
+	}
+	/* Initialize clocks */
+	r = radeon_clocks_init(rdev);
+	if (r) {
+		return r;
+	}
+
+	r = rv770_startup(rdev);
+	if (r) {
+		DRM_ERROR("r600 startup failed on resume\n");
+		return r;
+	}
+
+	r = radeon_ib_test(rdev);
+	if (r) {
+		DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+		return r;
+	}
+	return r;
+
+}
+
+int rv770_suspend(struct radeon_device *rdev)
+{
+	/* FIXME: we should wait for ring to be empty */
+	r700_cp_stop(rdev);
+	rdev->cp.ready = false;
+	rv770_pcie_gart_disable(rdev);
+
+	/* unpin shaders bo */
+        radeon_object_unpin(rdev->r600_blit.shader_obj);
+	return 0;
+}
+
+/* Plan is to move initialization in that function and use
+ * helper function so that radeon_device_init pretty much
+ * do nothing more than calling asic specific function. This
+ * should also allow to remove a bunch of callback function
+ * like vram_info.
+ */
+int rv770_init(struct radeon_device *rdev)
+{
+	int r;
+
+	rdev->new_init_path = true;
+	r = radeon_dummy_page_init(rdev);
+	if (r)
+		return r;
+	/* This don't do much */
+	r = radeon_gem_init(rdev);
+	if (r)
+		return r;
+	/* Read BIOS */
+	if (!radeon_get_bios(rdev)) {
+		if (ASIC_IS_AVIVO(rdev))
+			return -EINVAL;
+	}
+	/* Must be an ATOMBIOS */
+	if (!rdev->is_atom_bios)
+		return -EINVAL;
+	r = radeon_atombios_init(rdev);
+	if (r)
+		return r;
+	/* Post card if necessary */
+	if (!r600_card_posted(rdev) && rdev->bios) {
+		DRM_INFO("GPU not posted. posting now...\n");
+		atom_asic_init(rdev->mode_info.atom_context);
+	}
+	/* Initialize scratch registers */
+	r600_scratch_init(rdev);
+	/* Initialize surface registers */
+	radeon_surface_init(rdev);
+	radeon_get_clock_info(rdev->ddev);
+	r = radeon_clocks_init(rdev);
+	if (r)
+		return r;
+	/* Fence driver */
+	r = radeon_fence_driver_init(rdev);
+	if (r)
+		return r;
+	r = rv770_mc_init(rdev);
+	if (r) {
+		if (rdev->flags & RADEON_IS_AGP) {
+			/* Retry with disabling AGP */
+			rv770_fini(rdev);
+			rdev->flags &= ~RADEON_IS_AGP;
+			return rv770_init(rdev);
+		}
+		return r;
+	}
+	/* Memory manager */
+	r = radeon_object_init(rdev);
+	if (r)
+		return r;
+	rdev->cp.ring_obj = NULL;
+	r600_ring_init(rdev, 1024 * 1024);
+
+	if (!rdev->me_fw || !rdev->pfp_fw) {
+		r = r600_cp_init_microcode(rdev);
+		if (r) {
+			DRM_ERROR("Failed to load firmware!\n");
+			return r;
+		}
+	}
+
+	r = r600_pcie_gart_init(rdev);
+	if (r)
+		return r;
+
+	rdev->accel_working = true;
+	r = r600_blit_init(rdev);
+	if (r) {
+		DRM_ERROR("radeon: failled blitter (%d).\n", r);
+		rdev->accel_working = false;
+	}
+
+	r = rv770_startup(rdev);
+	if (r) {
+		if (rdev->flags & RADEON_IS_AGP) {
+			/* Retry with disabling AGP */
+			rv770_fini(rdev);
+			rdev->flags &= ~RADEON_IS_AGP;
+			return rv770_init(rdev);
+		}
+		rdev->accel_working = false;
+	}
+	if (rdev->accel_working) {
+		r = radeon_ib_pool_init(rdev);
+		if (r) {
+			DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
+			rdev->accel_working = false;
+		}
+		r = radeon_ib_test(rdev);
+		if (r) {
+			DRM_ERROR("radeon: failled testing IB (%d).\n", r);
+			rdev->accel_working = false;
+		}
+	}
+	return 0;
+}
+
+void rv770_fini(struct radeon_device *rdev)
+{
+	rv770_suspend(rdev);
+
+	r600_blit_fini(rdev);
+	radeon_ring_fini(rdev);
+	rv770_pcie_gart_fini(rdev);
+	radeon_gem_fini(rdev);
+	radeon_fence_driver_fini(rdev);
+	radeon_clocks_fini(rdev);
+#if __OS_HAS_AGP
+	if (rdev->flags & RADEON_IS_AGP)
+		radeon_agp_fini(rdev);
+#endif
+	radeon_object_fini(rdev);
+	if (rdev->is_atom_bios) {
+		radeon_atombios_fini(rdev);
+	} else {
+		radeon_combios_fini(rdev);
+	}
+	kfree(rdev->bios);
+	rdev->bios = NULL;
+	radeon_dummy_page_fini(rdev);
 }
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
new file mode 100644
index 0000000..4b9c3d6
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2009 Advanced Micro Devices, Inc.
+ * Copyright 2009 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Dave Airlie
+ *          Alex Deucher
+ *          Jerome Glisse
+ */
+#ifndef RV770_H
+#define RV770_H
+
+#define R7XX_MAX_SH_GPRS           256
+#define R7XX_MAX_TEMP_GPRS         16
+#define R7XX_MAX_SH_THREADS        256
+#define R7XX_MAX_SH_STACK_ENTRIES  4096
+#define R7XX_MAX_BACKENDS          8
+#define R7XX_MAX_BACKENDS_MASK     0xff
+#define R7XX_MAX_SIMDS             16
+#define R7XX_MAX_SIMDS_MASK        0xffff
+#define R7XX_MAX_PIPES             8
+#define R7XX_MAX_PIPES_MASK        0xff
+
+/* Registers */
+#define	CB_COLOR0_BASE					0x28040
+#define	CB_COLOR1_BASE					0x28044
+#define	CB_COLOR2_BASE					0x28048
+#define	CB_COLOR3_BASE					0x2804C
+#define	CB_COLOR4_BASE					0x28050
+#define	CB_COLOR5_BASE					0x28054
+#define	CB_COLOR6_BASE					0x28058
+#define	CB_COLOR7_BASE					0x2805C
+#define	CB_COLOR7_FRAG					0x280FC
+
+#define	CC_GC_SHADER_PIPE_CONFIG			0x8950
+#define	CC_RB_BACKEND_DISABLE				0x98F4
+#define		BACKEND_DISABLE(x)				((x) << 16)
+#define	CC_SYS_RB_BACKEND_DISABLE			0x3F88
+
+#define	CGTS_SYS_TCC_DISABLE				0x3F90
+#define	CGTS_TCC_DISABLE				0x9148
+#define	CGTS_USER_SYS_TCC_DISABLE			0x3F94
+#define	CGTS_USER_TCC_DISABLE				0x914C
+
+#define	CONFIG_MEMSIZE					0x5428
+
+#define	CP_ME_CNTL					0x86D8
+#define		CP_ME_HALT					(1<<28)
+#define		CP_PFP_HALT					(1<<26)
+#define	CP_ME_RAM_DATA					0xC160
+#define	CP_ME_RAM_RADDR					0xC158
+#define	CP_ME_RAM_WADDR					0xC15C
+#define CP_MEQ_THRESHOLDS				0x8764
+#define		STQ_SPLIT(x)					((x) << 0)
+#define	CP_PERFMON_CNTL					0x87FC
+#define	CP_PFP_UCODE_ADDR				0xC150
+#define	CP_PFP_UCODE_DATA				0xC154
+#define	CP_QUEUE_THRESHOLDS				0x8760
+#define		ROQ_IB1_START(x)				((x) << 0)
+#define		ROQ_IB2_START(x)				((x) << 8)
+#define	CP_RB_CNTL					0xC104
+#define		RB_BUFSZ(x)					((x)<<0)
+#define		RB_BLKSZ(x)					((x)<<8)
+#define		RB_NO_UPDATE					(1<<27)
+#define		RB_RPTR_WR_ENA					(1<<31)
+#define		BUF_SWAP_32BIT					(2 << 16)
+#define	CP_RB_RPTR					0x8700
+#define	CP_RB_RPTR_ADDR					0xC10C
+#define	CP_RB_RPTR_ADDR_HI				0xC110
+#define	CP_RB_RPTR_WR					0xC108
+#define	CP_RB_WPTR					0xC114
+#define	CP_RB_WPTR_ADDR					0xC118
+#define	CP_RB_WPTR_ADDR_HI				0xC11C
+#define	CP_RB_WPTR_DELAY				0x8704
+#define	CP_SEM_WAIT_TIMER				0x85BC
+
+#define	DB_DEBUG3					0x98B0
+#define		DB_CLK_OFF_DELAY(x)				((x) << 11)
+#define DB_DEBUG4					0x9B8C
+#define		DISABLE_TILE_COVERED_FOR_PS_ITER		(1 << 6)
+
+#define	DCP_TILING_CONFIG				0x6CA0
+#define		PIPE_TILING(x)					((x) << 1)
+#define 	BANK_TILING(x)					((x) << 4)
+#define		GROUP_SIZE(x)					((x) << 6)
+#define		ROW_TILING(x)					((x) << 8)
+#define		BANK_SWAPS(x)					((x) << 11)
+#define		SAMPLE_SPLIT(x)					((x) << 14)
+#define		BACKEND_MAP(x)					((x) << 16)
+
+#define GB_TILING_CONFIG				0x98F0
+
+#define	GC_USER_SHADER_PIPE_CONFIG			0x8954
+#define		INACTIVE_QD_PIPES(x)				((x) << 8)
+#define		INACTIVE_QD_PIPES_MASK				0x0000FF00
+#define		INACTIVE_SIMDS(x)				((x) << 16)
+#define		INACTIVE_SIMDS_MASK				0x00FF0000
+
+#define	GRBM_CNTL					0x8000
+#define		GRBM_READ_TIMEOUT(x)				((x) << 0)
+#define	GRBM_SOFT_RESET					0x8020
+#define		SOFT_RESET_CP					(1<<0)
+#define	GRBM_STATUS					0x8010
+#define		CMDFIFO_AVAIL_MASK				0x0000000F
+#define		GUI_ACTIVE					(1<<31)
+#define	GRBM_STATUS2					0x8014
+
+#define	HDP_HOST_PATH_CNTL				0x2C00
+#define	HDP_NONSURFACE_BASE				0x2C04
+#define	HDP_NONSURFACE_INFO				0x2C08
+#define	HDP_NONSURFACE_SIZE				0x2C0C
+#define HDP_REG_COHERENCY_FLUSH_CNTL			0x54A0
+#define	HDP_TILING_CONFIG				0x2F3C
+
+#define	MC_ARB_RAMCFG					0x2760
+#define		NOOFBANK_SHIFT					0
+#define		NOOFBANK_MASK					0x00000003
+#define		NOOFRANK_SHIFT					2
+#define		NOOFRANK_MASK					0x00000004
+#define		NOOFROWS_SHIFT					3
+#define		NOOFROWS_MASK					0x00000038
+#define		NOOFCOLS_SHIFT					6
+#define		NOOFCOLS_MASK					0x000000C0
+#define		CHANSIZE_SHIFT					8
+#define		CHANSIZE_MASK					0x00000100
+#define		BURSTLENGTH_SHIFT				9
+#define		BURSTLENGTH_MASK				0x00000200
+#define	MC_VM_AGP_TOP					0x2028
+#define	MC_VM_AGP_BOT					0x202C
+#define	MC_VM_AGP_BASE					0x2030
+#define	MC_VM_FB_LOCATION				0x2024
+#define	MC_VM_MB_L1_TLB0_CNTL				0x2234
+#define	MC_VM_MB_L1_TLB1_CNTL				0x2238
+#define	MC_VM_MB_L1_TLB2_CNTL				0x223C
+#define	MC_VM_MB_L1_TLB3_CNTL				0x2240
+#define		ENABLE_L1_TLB					(1 << 0)
+#define		ENABLE_L1_FRAGMENT_PROCESSING			(1 << 1)
+#define		SYSTEM_ACCESS_MODE_PA_ONLY			(0 << 3)
+#define		SYSTEM_ACCESS_MODE_USE_SYS_MAP			(1 << 3)
+#define		SYSTEM_ACCESS_MODE_IN_SYS			(2 << 3)
+#define		SYSTEM_ACCESS_MODE_NOT_IN_SYS			(3 << 3)
+#define		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU	(0 << 5)
+#define		EFFECTIVE_L1_TLB_SIZE(x)			((x)<<15)
+#define		EFFECTIVE_L1_QUEUE_SIZE(x)			((x)<<18)
+#define	MC_VM_MD_L1_TLB0_CNTL				0x2654
+#define	MC_VM_MD_L1_TLB1_CNTL				0x2658
+#define	MC_VM_MD_L1_TLB2_CNTL				0x265C
+#define	MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR		0x203C
+#define	MC_VM_SYSTEM_APERTURE_HIGH_ADDR			0x2038
+#define	MC_VM_SYSTEM_APERTURE_LOW_ADDR			0x2034
+
+#define	PA_CL_ENHANCE					0x8A14
+#define		CLIP_VTX_REORDER_ENA				(1 << 0)
+#define		NUM_CLIP_SEQ(x)					((x) << 1)
+#define PA_SC_AA_CONFIG					0x28C04
+#define PA_SC_CLIPRECT_RULE				0x2820C
+#define	PA_SC_EDGERULE					0x28230
+#define	PA_SC_FIFO_SIZE					0x8BCC
+#define		SC_PRIM_FIFO_SIZE(x)				((x) << 0)
+#define		SC_HIZ_TILE_FIFO_SIZE(x)			((x) << 12)
+#define	PA_SC_FORCE_EOV_MAX_CNTS			0x8B24
+#define		FORCE_EOV_MAX_CLK_CNT(x)			((x)<<0)
+#define		FORCE_EOV_MAX_REZ_CNT(x)			((x)<<16)
+#define PA_SC_LINE_STIPPLE				0x28A0C
+#define	PA_SC_LINE_STIPPLE_STATE			0x8B10
+#define PA_SC_MODE_CNTL					0x28A4C
+#define	PA_SC_MULTI_CHIP_CNTL				0x8B20
+#define		SC_EARLYZ_TILE_FIFO_SIZE(x)			((x) << 20)
+
+#define	SCRATCH_REG0					0x8500
+#define	SCRATCH_REG1					0x8504
+#define	SCRATCH_REG2					0x8508
+#define	SCRATCH_REG3					0x850C
+#define	SCRATCH_REG4					0x8510
+#define	SCRATCH_REG5					0x8514
+#define	SCRATCH_REG6					0x8518
+#define	SCRATCH_REG7					0x851C
+#define	SCRATCH_UMSK					0x8540
+#define	SCRATCH_ADDR					0x8544
+
+#define	SMX_DC_CTL0					0xA020
+#define		USE_HASH_FUNCTION				(1 << 0)
+#define		CACHE_DEPTH(x)					((x) << 1)
+#define		FLUSH_ALL_ON_EVENT				(1 << 10)
+#define		STALL_ON_EVENT					(1 << 11)
+#define	SMX_EVENT_CTL					0xA02C
+#define		ES_FLUSH_CTL(x)					((x) << 0)
+#define		GS_FLUSH_CTL(x)					((x) << 3)
+#define		ACK_FLUSH_CTL(x)				((x) << 6)
+#define		SYNC_FLUSH_CTL					(1 << 8)
+
+#define	SPI_CONFIG_CNTL					0x9100
+#define		GPR_WRITE_PRIORITY(x)				((x) << 0)
+#define		DISABLE_INTERP_1				(1 << 5)
+#define	SPI_CONFIG_CNTL_1				0x913C
+#define		VTX_DONE_DELAY(x)				((x) << 0)
+#define		INTERP_ONE_PRIM_PER_ROW				(1 << 4)
+#define	SPI_INPUT_Z					0x286D8
+#define	SPI_PS_IN_CONTROL_0				0x286CC
+#define		NUM_INTERP(x)					((x)<<0)
+#define		POSITION_ENA					(1<<8)
+#define		POSITION_CENTROID				(1<<9)
+#define		POSITION_ADDR(x)				((x)<<10)
+#define		PARAM_GEN(x)					((x)<<15)
+#define		PARAM_GEN_ADDR(x)				((x)<<19)
+#define		BARYC_SAMPLE_CNTL(x)				((x)<<26)
+#define		PERSP_GRADIENT_ENA				(1<<28)
+#define		LINEAR_GRADIENT_ENA				(1<<29)
+#define		POSITION_SAMPLE					(1<<30)
+#define		BARYC_AT_SAMPLE_ENA				(1<<31)
+
+#define	SQ_CONFIG					0x8C00
+#define		VC_ENABLE					(1 << 0)
+#define		EXPORT_SRC_C					(1 << 1)
+#define		DX9_CONSTS					(1 << 2)
+#define		ALU_INST_PREFER_VECTOR				(1 << 3)
+#define		DX10_CLAMP					(1 << 4)
+#define		CLAUSE_SEQ_PRIO(x)				((x) << 8)
+#define		PS_PRIO(x)					((x) << 24)
+#define		VS_PRIO(x)					((x) << 26)
+#define		GS_PRIO(x)					((x) << 28)
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_0			0x8DB0
+#define		SIMDA_RING0(x)					((x)<<0)
+#define		SIMDA_RING1(x)					((x)<<8)
+#define		SIMDB_RING0(x)					((x)<<16)
+#define		SIMDB_RING1(x)					((x)<<24)
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_1			0x8DB4
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_2			0x8DB8
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_3			0x8DBC
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_4			0x8DC0
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_5			0x8DC4
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_6			0x8DC8
+#define	SQ_DYN_GPR_SIZE_SIMD_AB_7			0x8DCC
+#define		ES_PRIO(x)					((x) << 30)
+#define	SQ_GPR_RESOURCE_MGMT_1				0x8C04
+#define		NUM_PS_GPRS(x)					((x) << 0)
+#define		NUM_VS_GPRS(x)					((x) << 16)
+#define		DYN_GPR_ENABLE					(1 << 27)
+#define		NUM_CLAUSE_TEMP_GPRS(x)				((x) << 28)
+#define	SQ_GPR_RESOURCE_MGMT_2				0x8C08
+#define		NUM_GS_GPRS(x)					((x) << 0)
+#define		NUM_ES_GPRS(x)					((x) << 16)
+#define	SQ_MS_FIFO_SIZES				0x8CF0
+#define		CACHE_FIFO_SIZE(x)				((x) << 0)
+#define		FETCH_FIFO_HIWATER(x)				((x) << 8)
+#define		DONE_FIFO_HIWATER(x)				((x) << 16)
+#define		ALU_UPDATE_FIFO_HIWATER(x)			((x) << 24)
+#define	SQ_STACK_RESOURCE_MGMT_1			0x8C10
+#define		NUM_PS_STACK_ENTRIES(x)				((x) << 0)
+#define		NUM_VS_STACK_ENTRIES(x)				((x) << 16)
+#define	SQ_STACK_RESOURCE_MGMT_2			0x8C14
+#define		NUM_GS_STACK_ENTRIES(x)				((x) << 0)
+#define		NUM_ES_STACK_ENTRIES(x)				((x) << 16)
+#define	SQ_THREAD_RESOURCE_MGMT				0x8C0C
+#define		NUM_PS_THREADS(x)				((x) << 0)
+#define		NUM_VS_THREADS(x)				((x) << 8)
+#define		NUM_GS_THREADS(x)				((x) << 16)
+#define		NUM_ES_THREADS(x)				((x) << 24)
+
+#define	SX_DEBUG_1					0x9058
+#define		ENABLE_NEW_SMX_ADDRESS				(1 << 16)
+#define	SX_EXPORT_BUFFER_SIZES				0x900C
+#define		COLOR_BUFFER_SIZE(x)				((x) << 0)
+#define		POSITION_BUFFER_SIZE(x)				((x) << 8)
+#define		SMX_BUFFER_SIZE(x)				((x) << 16)
+#define	SX_MISC						0x28350
+
+#define	TA_CNTL_AUX					0x9508
+#define		DISABLE_CUBE_WRAP				(1 << 0)
+#define		DISABLE_CUBE_ANISO				(1 << 1)
+#define		SYNC_GRADIENT					(1 << 24)
+#define		SYNC_WALKER					(1 << 25)
+#define		SYNC_ALIGNER					(1 << 26)
+#define		BILINEAR_PRECISION_6_BIT			(0 << 31)
+#define		BILINEAR_PRECISION_8_BIT			(1 << 31)
+
+#define	TCP_CNTL					0x9610
+
+#define	VGT_CACHE_INVALIDATION				0x88C4
+#define		CACHE_INVALIDATION(x)				((x)<<0)
+#define			VC_ONLY						0
+#define			TC_ONLY						1
+#define			VC_AND_TC					2
+#define		AUTO_INVLD_EN(x)				((x) << 6)
+#define			NO_AUTO						0
+#define			ES_AUTO						1
+#define			GS_AUTO						2
+#define			ES_AND_GS_AUTO					3
+#define	VGT_ES_PER_GS					0x88CC
+#define	VGT_GS_PER_ES					0x88C8
+#define	VGT_GS_PER_VS					0x88E8
+#define	VGT_GS_VERTEX_REUSE				0x88D4
+#define	VGT_NUM_INSTANCES				0x8974
+#define	VGT_OUT_DEALLOC_CNTL				0x28C5C
+#define		DEALLOC_DIST_MASK				0x0000007F
+#define	VGT_STRMOUT_EN					0x28AB0
+#define	VGT_VERTEX_REUSE_BLOCK_CNTL			0x28C58
+#define		VTX_REUSE_DEPTH_MASK				0x000000FF
+
+#define VM_CONTEXT0_CNTL				0x1410
+#define		ENABLE_CONTEXT					(1 << 0)
+#define		PAGE_TABLE_DEPTH(x)				(((x) & 3) << 1)
+#define		RANGE_PROTECTION_FAULT_ENABLE_DEFAULT		(1 << 4)
+#define	VM_CONTEXT0_PAGE_TABLE_BASE_ADDR		0x153C
+#define	VM_CONTEXT0_PAGE_TABLE_END_ADDR			0x157C
+#define	VM_CONTEXT0_PAGE_TABLE_START_ADDR		0x155C
+#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR	0x1518
+#define VM_L2_CNTL					0x1400
+#define		ENABLE_L2_CACHE					(1 << 0)
+#define		ENABLE_L2_FRAGMENT_PROCESSING			(1 << 1)
+#define		ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE		(1 << 9)
+#define		EFFECTIVE_L2_QUEUE_SIZE(x)			(((x) & 7) << 14)
+#define VM_L2_CNTL2					0x1404
+#define		INVALIDATE_ALL_L1_TLBS				(1 << 0)
+#define		INVALIDATE_L2_CACHE				(1 << 1)
+#define VM_L2_CNTL3					0x1408
+#define		BANK_SELECT(x)					((x) << 0)
+#define		CACHE_UPDATE_MODE(x)				((x) << 6)
+#define	VM_L2_STATUS					0x140C
+#define		L2_BUSY						(1 << 0)
+
+#define	WAIT_UNTIL					0x8040
+
+#endif
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index c2b0d71..87c0625 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -44,6 +44,39 @@
 
 static int ttm_bo_setup_vm(struct ttm_buffer_object *bo);
 static int ttm_bo_swapout(struct ttm_mem_shrink *shrink);
+static void ttm_bo_global_kobj_release(struct kobject *kobj);
+
+static struct attribute ttm_bo_count = {
+	.name = "bo_count",
+	.mode = S_IRUGO
+};
+
+static ssize_t ttm_bo_global_show(struct kobject *kobj,
+				  struct attribute *attr,
+				  char *buffer)
+{
+	struct ttm_bo_global *glob =
+		container_of(kobj, struct ttm_bo_global, kobj);
+
+	return snprintf(buffer, PAGE_SIZE, "%lu\n",
+			(unsigned long) atomic_read(&glob->bo_count));
+}
+
+static struct attribute *ttm_bo_global_attrs[] = {
+	&ttm_bo_count,
+	NULL
+};
+
+static struct sysfs_ops ttm_bo_global_ops = {
+	.show = &ttm_bo_global_show
+};
+
+static struct kobj_type ttm_bo_glob_kobj_type  = {
+	.release = &ttm_bo_global_kobj_release,
+	.sysfs_ops = &ttm_bo_global_ops,
+	.default_attrs = ttm_bo_global_attrs
+};
+
 
 static inline uint32_t ttm_bo_type_flags(unsigned type)
 {
@@ -66,10 +99,11 @@ static void ttm_bo_release_list(struct kref *list_kref)
 
 	if (bo->ttm)
 		ttm_tt_destroy(bo->ttm);
+	atomic_dec(&bo->glob->bo_count);
 	if (bo->destroy)
 		bo->destroy(bo);
 	else {
-		ttm_mem_global_free(bdev->mem_glob, bo->acc_size, false);
+		ttm_mem_global_free(bdev->glob->mem_glob, bo->acc_size);
 		kfree(bo);
 	}
 }
@@ -106,7 +140,7 @@ static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
 		kref_get(&bo->list_kref);
 
 		if (bo->ttm != NULL) {
-			list_add_tail(&bo->swap, &bdev->swap_lru);
+			list_add_tail(&bo->swap, &bo->glob->swap_lru);
 			kref_get(&bo->list_kref);
 		}
 	}
@@ -141,7 +175,7 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
 			  bool interruptible,
 			  bool no_wait, bool use_sequence, uint32_t sequence)
 {
-	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 	int ret;
 
 	while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) {
@@ -153,9 +187,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo,
 		if (no_wait)
 			return -EBUSY;
 
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 		ret = ttm_bo_wait_unreserved(bo, interruptible);
-		spin_lock(&bdev->lru_lock);
+		spin_lock(&glob->lru_lock);
 
 		if (unlikely(ret))
 			return ret;
@@ -181,16 +215,16 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo,
 		   bool interruptible,
 		   bool no_wait, bool use_sequence, uint32_t sequence)
 {
-	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 	int put_count = 0;
 	int ret;
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, use_sequence,
 				    sequence);
 	if (likely(ret == 0))
 		put_count = ttm_bo_del_from_lru(bo);
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 
 	while (put_count--)
 		kref_put(&bo->list_kref, ttm_bo_ref_bug);
@@ -200,13 +234,13 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo,
 
 void ttm_bo_unreserve(struct ttm_buffer_object *bo)
 {
-	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	ttm_bo_add_to_lru(bo);
 	atomic_set(&bo->reserved, 0);
 	wake_up_all(&bo->event_queue);
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 }
 EXPORT_SYMBOL(ttm_bo_unreserve);
 
@@ -217,6 +251,7 @@ EXPORT_SYMBOL(ttm_bo_unreserve);
 static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 	int ret = 0;
 	uint32_t page_flags = 0;
 
@@ -232,14 +267,14 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc)
 			page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC;
 	case ttm_bo_type_kernel:
 		bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
-					page_flags, bdev->dummy_read_page);
+					page_flags, glob->dummy_read_page);
 		if (unlikely(bo->ttm == NULL))
 			ret = -ENOMEM;
 		break;
 	case ttm_bo_type_user:
 		bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT,
 					page_flags | TTM_PAGE_FLAG_USER,
-					bdev->dummy_read_page);
+					glob->dummy_read_page);
 		if (unlikely(bo->ttm == NULL))
 			ret = -ENOMEM;
 		break;
@@ -360,6 +395,7 @@ out_err:
 static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 	struct ttm_bo_driver *driver = bdev->driver;
 	int ret;
 
@@ -371,7 +407,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
 
 		spin_unlock(&bo->lock);
 
-		spin_lock(&bdev->lru_lock);
+		spin_lock(&glob->lru_lock);
 		ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
 		BUG_ON(ret);
 		if (bo->ttm)
@@ -386,7 +422,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
 			bo->mem.mm_node = NULL;
 		}
 		put_count = ttm_bo_del_from_lru(bo);
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 
 		atomic_set(&bo->reserved, 0);
 
@@ -396,14 +432,14 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
 		return 0;
 	}
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	if (list_empty(&bo->ddestroy)) {
 		void *sync_obj = bo->sync_obj;
 		void *sync_obj_arg = bo->sync_obj_arg;
 
 		kref_get(&bo->list_kref);
 		list_add_tail(&bo->ddestroy, &bdev->ddestroy);
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 		spin_unlock(&bo->lock);
 
 		if (sync_obj)
@@ -413,7 +449,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
 		ret = 0;
 
 	} else {
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 		spin_unlock(&bo->lock);
 		ret = -EBUSY;
 	}
@@ -428,11 +464,12 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
 
 static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
 {
+	struct ttm_bo_global *glob = bdev->glob;
 	struct ttm_buffer_object *entry, *nentry;
 	struct list_head *list, *next;
 	int ret;
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	list_for_each_safe(list, next, &bdev->ddestroy) {
 		entry = list_entry(list, struct ttm_buffer_object, ddestroy);
 		nentry = NULL;
@@ -449,16 +486,16 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
 		}
 		kref_get(&entry->list_kref);
 
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 		ret = ttm_bo_cleanup_refs(entry, remove_all);
 		kref_put(&entry->list_kref, ttm_bo_release_list);
 
-		spin_lock(&bdev->lru_lock);
+		spin_lock(&glob->lru_lock);
 		if (nentry) {
 			bool next_onlist = !list_empty(next);
-			spin_unlock(&bdev->lru_lock);
+			spin_unlock(&glob->lru_lock);
 			kref_put(&nentry->list_kref, ttm_bo_release_list);
-			spin_lock(&bdev->lru_lock);
+			spin_lock(&glob->lru_lock);
 			/*
 			 * Someone might have raced us and removed the
 			 * next entry from the list. We don't bother restarting
@@ -472,7 +509,7 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
 			break;
 	}
 	ret = !list_empty(&bdev->ddestroy);
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 
 	return ret;
 }
@@ -522,6 +559,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
 {
 	int ret = 0;
 	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 	struct ttm_mem_reg evict_mem;
 	uint32_t proposed_placement;
 
@@ -570,12 +608,12 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type,
 		goto out;
 	}
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	if (evict_mem.mm_node) {
 		drm_mm_put_block(evict_mem.mm_node);
 		evict_mem.mm_node = NULL;
 	}
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 	bo->evicted = true;
 out:
 	return ret;
@@ -590,6 +628,7 @@ static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev,
 				  uint32_t mem_type,
 				  bool interruptible, bool no_wait)
 {
+	struct ttm_bo_global *glob = bdev->glob;
 	struct drm_mm_node *node;
 	struct ttm_buffer_object *entry;
 	struct ttm_mem_type_manager *man = &bdev->man[mem_type];
@@ -603,7 +642,7 @@ retry_pre_get:
 	if (unlikely(ret != 0))
 		return ret;
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	do {
 		node = drm_mm_search_free(&man->manager, num_pages,
 					  mem->page_alignment, 1);
@@ -624,7 +663,7 @@ retry_pre_get:
 		if (likely(ret == 0))
 			put_count = ttm_bo_del_from_lru(entry);
 
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 
 		if (unlikely(ret != 0))
 			return ret;
@@ -640,21 +679,21 @@ retry_pre_get:
 		if (ret)
 			return ret;
 
-		spin_lock(&bdev->lru_lock);
+		spin_lock(&glob->lru_lock);
 	} while (1);
 
 	if (!node) {
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 		return -ENOMEM;
 	}
 
 	node = drm_mm_get_block_atomic(node, num_pages, mem->page_alignment);
 	if (unlikely(!node)) {
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 		goto retry_pre_get;
 	}
 
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 	mem->mm_node = node;
 	mem->mem_type = mem_type;
 	return 0;
@@ -723,6 +762,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
 		     bool interruptible, bool no_wait)
 {
 	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 	struct ttm_mem_type_manager *man;
 
 	uint32_t num_prios = bdev->driver->num_mem_type_prio;
@@ -762,20 +802,20 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo,
 				if (unlikely(ret))
 					return ret;
 
-				spin_lock(&bdev->lru_lock);
+				spin_lock(&glob->lru_lock);
 				node = drm_mm_search_free(&man->manager,
 							  mem->num_pages,
 							  mem->page_alignment,
 							  1);
 				if (unlikely(!node)) {
-					spin_unlock(&bdev->lru_lock);
+					spin_unlock(&glob->lru_lock);
 					break;
 				}
 				node = drm_mm_get_block_atomic(node,
 							       mem->num_pages,
 							       mem->
 							       page_alignment);
-				spin_unlock(&bdev->lru_lock);
+				spin_unlock(&glob->lru_lock);
 			} while (!node);
 		}
 		if (node)
@@ -848,7 +888,7 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
 		       uint32_t proposed_placement,
 		       bool interruptible, bool no_wait)
 {
-	struct ttm_bo_device *bdev = bo->bdev;
+	struct ttm_bo_global *glob = bo->glob;
 	int ret = 0;
 	struct ttm_mem_reg mem;
 
@@ -884,9 +924,9 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo,
 
 out_unlock:
 	if (ret && mem.mm_node) {
-		spin_lock(&bdev->lru_lock);
+		spin_lock(&glob->lru_lock);
 		drm_mm_put_block(mem.mm_node);
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 	}
 	return ret;
 }
@@ -1022,6 +1062,7 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev,
 	INIT_LIST_HEAD(&bo->ddestroy);
 	INIT_LIST_HEAD(&bo->swap);
 	bo->bdev = bdev;
+	bo->glob = bdev->glob;
 	bo->type = type;
 	bo->num_pages = num_pages;
 	bo->mem.mem_type = TTM_PL_SYSTEM;
@@ -1034,6 +1075,7 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev,
 	bo->seq_valid = false;
 	bo->persistant_swap_storage = persistant_swap_storage;
 	bo->acc_size = acc_size;
+	atomic_inc(&bo->glob->bo_count);
 
 	ret = ttm_bo_check_placement(bo, flags, 0ULL);
 	if (unlikely(ret != 0))
@@ -1072,13 +1114,13 @@ out_err:
 }
 EXPORT_SYMBOL(ttm_buffer_object_init);
 
-static inline size_t ttm_bo_size(struct ttm_bo_device *bdev,
+static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
 				 unsigned long num_pages)
 {
 	size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) &
 	    PAGE_MASK;
 
-	return bdev->ttm_bo_size + 2 * page_array_size;
+	return glob->ttm_bo_size + 2 * page_array_size;
 }
 
 int ttm_buffer_object_create(struct ttm_bo_device *bdev,
@@ -1093,18 +1135,18 @@ int ttm_buffer_object_create(struct ttm_bo_device *bdev,
 {
 	struct ttm_buffer_object *bo;
 	int ret;
-	struct ttm_mem_global *mem_glob = bdev->mem_glob;
+	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
 
 	size_t acc_size =
-	    ttm_bo_size(bdev, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
-	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false, false);
+	    ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
+	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
 	if (unlikely(ret != 0))
 		return ret;
 
 	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
 
 	if (unlikely(bo == NULL)) {
-		ttm_mem_global_free(mem_glob, acc_size, false);
+		ttm_mem_global_free(mem_glob, acc_size);
 		return -ENOMEM;
 	}
 
@@ -1150,6 +1192,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
 				   struct list_head *head,
 				   unsigned mem_type, bool allow_errors)
 {
+	struct ttm_bo_global *glob = bdev->glob;
 	struct ttm_buffer_object *entry;
 	int ret;
 	int put_count;
@@ -1158,30 +1201,31 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
 	 * Can't use standard list traversal since we're unlocking.
 	 */
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 
 	while (!list_empty(head)) {
 		entry = list_first_entry(head, struct ttm_buffer_object, lru);
 		kref_get(&entry->list_kref);
 		ret = ttm_bo_reserve_locked(entry, false, false, false, 0);
 		put_count = ttm_bo_del_from_lru(entry);
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 		while (put_count--)
 			kref_put(&entry->list_kref, ttm_bo_ref_bug);
 		BUG_ON(ret);
 		ret = ttm_bo_leave_list(entry, mem_type, allow_errors);
 		ttm_bo_unreserve(entry);
 		kref_put(&entry->list_kref, ttm_bo_release_list);
-		spin_lock(&bdev->lru_lock);
+		spin_lock(&glob->lru_lock);
 	}
 
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 
 	return 0;
 }
 
 int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
 {
+	struct ttm_bo_global *glob = bdev->glob;
 	struct ttm_mem_type_manager *man;
 	int ret = -EINVAL;
 
@@ -1204,13 +1248,13 @@ int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
 	if (mem_type > 0) {
 		ttm_bo_force_list_clean(bdev, &man->lru, mem_type, false);
 
-		spin_lock(&bdev->lru_lock);
+		spin_lock(&glob->lru_lock);
 		if (drm_mm_clean(&man->manager))
 			drm_mm_takedown(&man->manager);
 		else
 			ret = -EBUSY;
 
-		spin_unlock(&bdev->lru_lock);
+		spin_unlock(&glob->lru_lock);
 	}
 
 	return ret;
@@ -1284,11 +1328,82 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
 }
 EXPORT_SYMBOL(ttm_bo_init_mm);
 
+static void ttm_bo_global_kobj_release(struct kobject *kobj)
+{
+	struct ttm_bo_global *glob =
+		container_of(kobj, struct ttm_bo_global, kobj);
+
+	ttm_mem_unregister_shrink(glob->mem_glob, &glob->shrink);
+	__free_page(glob->dummy_read_page);
+	kfree(glob);
+}
+
+void ttm_bo_global_release(struct ttm_global_reference *ref)
+{
+	struct ttm_bo_global *glob = ref->object;
+
+	kobject_del(&glob->kobj);
+	kobject_put(&glob->kobj);
+}
+EXPORT_SYMBOL(ttm_bo_global_release);
+
+int ttm_bo_global_init(struct ttm_global_reference *ref)
+{
+	struct ttm_bo_global_ref *bo_ref =
+		container_of(ref, struct ttm_bo_global_ref, ref);
+	struct ttm_bo_global *glob = ref->object;
+	int ret;
+
+	mutex_init(&glob->device_list_mutex);
+	spin_lock_init(&glob->lru_lock);
+	glob->mem_glob = bo_ref->mem_glob;
+	glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
+
+	if (unlikely(glob->dummy_read_page == NULL)) {
+		ret = -ENOMEM;
+		goto out_no_drp;
+	}
+
+	INIT_LIST_HEAD(&glob->swap_lru);
+	INIT_LIST_HEAD(&glob->device_list);
+
+	ttm_mem_init_shrink(&glob->shrink, ttm_bo_swapout);
+	ret = ttm_mem_register_shrink(glob->mem_glob, &glob->shrink);
+	if (unlikely(ret != 0)) {
+		printk(KERN_ERR TTM_PFX
+		       "Could not register buffer object swapout.\n");
+		goto out_no_shrink;
+	}
+
+	glob->ttm_bo_extra_size =
+		ttm_round_pot(sizeof(struct ttm_tt)) +
+		ttm_round_pot(sizeof(struct ttm_backend));
+
+	glob->ttm_bo_size = glob->ttm_bo_extra_size +
+		ttm_round_pot(sizeof(struct ttm_buffer_object));
+
+	atomic_set(&glob->bo_count, 0);
+
+	kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type);
+	ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects");
+	if (unlikely(ret != 0))
+		kobject_put(&glob->kobj);
+	return ret;
+out_no_shrink:
+	__free_page(glob->dummy_read_page);
+out_no_drp:
+	kfree(glob);
+	return ret;
+}
+EXPORT_SYMBOL(ttm_bo_global_init);
+
+
 int ttm_bo_device_release(struct ttm_bo_device *bdev)
 {
 	int ret = 0;
 	unsigned i = TTM_NUM_MEM_TYPES;
 	struct ttm_mem_type_manager *man;
+	struct ttm_bo_global *glob = bdev->glob;
 
 	while (i--) {
 		man = &bdev->man[i];
@@ -1304,100 +1419,74 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev)
 		}
 	}
 
+	mutex_lock(&glob->device_list_mutex);
+	list_del(&bdev->device_list);
+	mutex_unlock(&glob->device_list_mutex);
+
 	if (!cancel_delayed_work(&bdev->wq))
 		flush_scheduled_work();
 
 	while (ttm_bo_delayed_delete(bdev, true))
 		;
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	if (list_empty(&bdev->ddestroy))
 		TTM_DEBUG("Delayed destroy list was clean\n");
 
 	if (list_empty(&bdev->man[0].lru))
 		TTM_DEBUG("Swap list was clean\n");
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 
-	ttm_mem_unregister_shrink(bdev->mem_glob, &bdev->shrink);
 	BUG_ON(!drm_mm_clean(&bdev->addr_space_mm));
 	write_lock(&bdev->vm_lock);
 	drm_mm_takedown(&bdev->addr_space_mm);
 	write_unlock(&bdev->vm_lock);
 
-	__free_page(bdev->dummy_read_page);
 	return ret;
 }
 EXPORT_SYMBOL(ttm_bo_device_release);
 
-/*
- * This function is intended to be called on drm driver load.
- * If you decide to call it from firstopen, you must protect the call
- * from a potentially racing ttm_bo_driver_finish in lastclose.
- * (This may happen on X server restart).
- */
-
 int ttm_bo_device_init(struct ttm_bo_device *bdev,
-		       struct ttm_mem_global *mem_glob,
-		       struct ttm_bo_driver *driver, uint64_t file_page_offset,
+		       struct ttm_bo_global *glob,
+		       struct ttm_bo_driver *driver,
+		       uint64_t file_page_offset,
 		       bool need_dma32)
 {
 	int ret = -EINVAL;
 
-	bdev->dummy_read_page = NULL;
 	rwlock_init(&bdev->vm_lock);
-	spin_lock_init(&bdev->lru_lock);
-
 	bdev->driver = driver;
-	bdev->mem_glob = mem_glob;
 
 	memset(bdev->man, 0, sizeof(bdev->man));
 
-	bdev->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
-	if (unlikely(bdev->dummy_read_page == NULL)) {
-		ret = -ENOMEM;
-		goto out_err0;
-	}
-
 	/*
 	 * Initialize the system memory buffer type.
 	 * Other types need to be driver / IOCTL initialized.
 	 */
 	ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0, 0);
 	if (unlikely(ret != 0))
-		goto out_err1;
+		goto out_no_sys;
 
 	bdev->addr_space_rb = RB_ROOT;
 	ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000);
 	if (unlikely(ret != 0))
-		goto out_err2;
+		goto out_no_addr_mm;
 
 	INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
 	bdev->nice_mode = true;
 	INIT_LIST_HEAD(&bdev->ddestroy);
-	INIT_LIST_HEAD(&bdev->swap_lru);
 	bdev->dev_mapping = NULL;
+	bdev->glob = glob;
 	bdev->need_dma32 = need_dma32;
-	ttm_mem_init_shrink(&bdev->shrink, ttm_bo_swapout);
-	ret = ttm_mem_register_shrink(mem_glob, &bdev->shrink);
-	if (unlikely(ret != 0)) {
-		printk(KERN_ERR TTM_PFX
-		       "Could not register buffer object swapout.\n");
-		goto out_err2;
-	}
 
-	bdev->ttm_bo_extra_size =
-		ttm_round_pot(sizeof(struct ttm_tt)) +
-		ttm_round_pot(sizeof(struct ttm_backend));
-
-	bdev->ttm_bo_size = bdev->ttm_bo_extra_size +
-		ttm_round_pot(sizeof(struct ttm_buffer_object));
+	mutex_lock(&glob->device_list_mutex);
+	list_add_tail(&bdev->device_list, &glob->device_list);
+	mutex_unlock(&glob->device_list_mutex);
 
 	return 0;
-out_err2:
+out_no_addr_mm:
 	ttm_bo_clean_mm(bdev, 0);
-out_err1:
-	__free_page(bdev->dummy_read_page);
-out_err0:
+out_no_sys:
 	return ret;
 }
 EXPORT_SYMBOL(ttm_bo_device_init);
@@ -1647,21 +1736,21 @@ void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo)
 
 static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
 {
-	struct ttm_bo_device *bdev =
-	    container_of(shrink, struct ttm_bo_device, shrink);
+	struct ttm_bo_global *glob =
+	    container_of(shrink, struct ttm_bo_global, shrink);
 	struct ttm_buffer_object *bo;
 	int ret = -EBUSY;
 	int put_count;
 	uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM);
 
-	spin_lock(&bdev->lru_lock);
+	spin_lock(&glob->lru_lock);
 	while (ret == -EBUSY) {
-		if (unlikely(list_empty(&bdev->swap_lru))) {
-			spin_unlock(&bdev->lru_lock);
+		if (unlikely(list_empty(&glob->swap_lru))) {
+			spin_unlock(&glob->lru_lock);
 			return -EBUSY;
 		}
 
-		bo = list_first_entry(&bdev->swap_lru,
+		bo = list_first_entry(&glob->swap_lru,
 				      struct ttm_buffer_object, swap);
 		kref_get(&bo->list_kref);
 
@@ -1673,16 +1762,16 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
 
 		ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
 		if (unlikely(ret == -EBUSY)) {
-			spin_unlock(&bdev->lru_lock);
+			spin_unlock(&glob->lru_lock);
 			ttm_bo_wait_unreserved(bo, false);
 			kref_put(&bo->list_kref, ttm_bo_release_list);
-			spin_lock(&bdev->lru_lock);
+			spin_lock(&glob->lru_lock);
 		}
 	}
 
 	BUG_ON(ret != 0);
 	put_count = ttm_bo_del_from_lru(bo);
-	spin_unlock(&bdev->lru_lock);
+	spin_unlock(&glob->lru_lock);
 
 	while (put_count--)
 		kref_put(&bo->list_kref, ttm_bo_ref_bug);
@@ -1736,6 +1825,6 @@ out:
 
 void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
 {
-	while (ttm_bo_swapout(&bdev->shrink) == 0)
+	while (ttm_bo_swapout(&bdev->glob->shrink) == 0)
 		;
 }
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index ad4ada0..c70927e 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -41,9 +41,9 @@ void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
 	struct ttm_mem_reg *old_mem = &bo->mem;
 
 	if (old_mem->mm_node) {
-		spin_lock(&bo->bdev->lru_lock);
+		spin_lock(&bo->glob->lru_lock);
 		drm_mm_put_block(old_mem->mm_node);
-		spin_unlock(&bo->bdev->lru_lock);
+		spin_unlock(&bo->glob->lru_lock);
 	}
 	old_mem->mm_node = NULL;
 }
diff --git a/drivers/gpu/drm/ttm/ttm_global.c b/drivers/gpu/drm/ttm/ttm_global.c
index 0b14eb1..541744d 100644
--- a/drivers/gpu/drm/ttm/ttm_global.c
+++ b/drivers/gpu/drm/ttm/ttm_global.c
@@ -71,7 +71,7 @@ int ttm_global_item_ref(struct ttm_global_reference *ref)
 
 	mutex_lock(&item->mutex);
 	if (item->refcount == 0) {
-		item->object = kmalloc(ref->size, GFP_KERNEL);
+		item->object = kzalloc(ref->size, GFP_KERNEL);
 		if (unlikely(item->object == NULL)) {
 			ret = -ENOMEM;
 			goto out_err;
@@ -89,7 +89,6 @@ int ttm_global_item_ref(struct ttm_global_reference *ref)
 	mutex_unlock(&item->mutex);
 	return 0;
 out_err:
-	kfree(item->object);
 	mutex_unlock(&item->mutex);
 	item->object = NULL;
 	return ret;
@@ -105,7 +104,6 @@ void ttm_global_item_unref(struct ttm_global_reference *ref)
 	BUG_ON(ref->object != item->object);
 	if (--item->refcount == 0) {
 		ref->release(ref);
-		kfree(item->object);
 		item->object = NULL;
 	}
 	mutex_unlock(&item->mutex);
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index 87323d4..072c281 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -26,15 +26,180 @@
  **************************************************************************/
 
 #include "ttm/ttm_memory.h"
+#include "ttm/ttm_module.h"
 #include <linux/spinlock.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 
-#define TTM_PFX "[TTM] "
 #define TTM_MEMORY_ALLOC_RETRIES 4
 
+struct ttm_mem_zone {
+	struct kobject kobj;
+	struct ttm_mem_global *glob;
+	const char *name;
+	uint64_t zone_mem;
+	uint64_t emer_mem;
+	uint64_t max_mem;
+	uint64_t swap_limit;
+	uint64_t used_mem;
+};
+
+static struct attribute ttm_mem_sys = {
+	.name = "zone_memory",
+	.mode = S_IRUGO
+};
+static struct attribute ttm_mem_emer = {
+	.name = "emergency_memory",
+	.mode = S_IRUGO | S_IWUSR
+};
+static struct attribute ttm_mem_max = {
+	.name = "available_memory",
+	.mode = S_IRUGO | S_IWUSR
+};
+static struct attribute ttm_mem_swap = {
+	.name = "swap_limit",
+	.mode = S_IRUGO | S_IWUSR
+};
+static struct attribute ttm_mem_used = {
+	.name = "used_memory",
+	.mode = S_IRUGO
+};
+
+static void ttm_mem_zone_kobj_release(struct kobject *kobj)
+{
+	struct ttm_mem_zone *zone =
+		container_of(kobj, struct ttm_mem_zone, kobj);
+
+	printk(KERN_INFO TTM_PFX
+	       "Zone %7s: Used memory at exit: %llu kiB.\n",
+	       zone->name, (unsigned long long) zone->used_mem >> 10);
+	kfree(zone);
+}
+
+static ssize_t ttm_mem_zone_show(struct kobject *kobj,
+				 struct attribute *attr,
+				 char *buffer)
+{
+	struct ttm_mem_zone *zone =
+		container_of(kobj, struct ttm_mem_zone, kobj);
+	uint64_t val = 0;
+
+	spin_lock(&zone->glob->lock);
+	if (attr == &ttm_mem_sys)
+		val = zone->zone_mem;
+	else if (attr == &ttm_mem_emer)
+		val = zone->emer_mem;
+	else if (attr == &ttm_mem_max)
+		val = zone->max_mem;
+	else if (attr == &ttm_mem_swap)
+		val = zone->swap_limit;
+	else if (attr == &ttm_mem_used)
+		val = zone->used_mem;
+	spin_unlock(&zone->glob->lock);
+
+	return snprintf(buffer, PAGE_SIZE, "%llu\n",
+			(unsigned long long) val >> 10);
+}
+
+static void ttm_check_swapping(struct ttm_mem_global *glob);
+
+static ssize_t ttm_mem_zone_store(struct kobject *kobj,
+				  struct attribute *attr,
+				  const char *buffer,
+				  size_t size)
+{
+	struct ttm_mem_zone *zone =
+		container_of(kobj, struct ttm_mem_zone, kobj);
+	int chars;
+	unsigned long val;
+	uint64_t val64;
+
+	chars = sscanf(buffer, "%lu", &val);
+	if (chars == 0)
+		return size;
+
+	val64 = val;
+	val64 <<= 10;
+
+	spin_lock(&zone->glob->lock);
+	if (val64 > zone->zone_mem)
+		val64 = zone->zone_mem;
+	if (attr == &ttm_mem_emer) {
+		zone->emer_mem = val64;
+		if (zone->max_mem > val64)
+			zone->max_mem = val64;
+	} else if (attr == &ttm_mem_max) {
+		zone->max_mem = val64;
+		if (zone->emer_mem < val64)
+			zone->emer_mem = val64;
+	} else if (attr == &ttm_mem_swap)
+		zone->swap_limit = val64;
+	spin_unlock(&zone->glob->lock);
+
+	ttm_check_swapping(zone->glob);
+
+	return size;
+}
+
+static struct attribute *ttm_mem_zone_attrs[] = {
+	&ttm_mem_sys,
+	&ttm_mem_emer,
+	&ttm_mem_max,
+	&ttm_mem_swap,
+	&ttm_mem_used,
+	NULL
+};
+
+static struct sysfs_ops ttm_mem_zone_ops = {
+	.show = &ttm_mem_zone_show,
+	.store = &ttm_mem_zone_store
+};
+
+static struct kobj_type ttm_mem_zone_kobj_type = {
+	.release = &ttm_mem_zone_kobj_release,
+	.sysfs_ops = &ttm_mem_zone_ops,
+	.default_attrs = ttm_mem_zone_attrs,
+};
+
+static void ttm_mem_global_kobj_release(struct kobject *kobj)
+{
+	struct ttm_mem_global *glob =
+		container_of(kobj, struct ttm_mem_global, kobj);
+
+	kfree(glob);
+}
+
+static struct kobj_type ttm_mem_glob_kobj_type = {
+	.release = &ttm_mem_global_kobj_release,
+};
+
+static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob,
+					bool from_wq, uint64_t extra)
+{
+	unsigned int i;
+	struct ttm_mem_zone *zone;
+	uint64_t target;
+
+	for (i = 0; i < glob->num_zones; ++i) {
+		zone = glob->zones[i];
+
+		if (from_wq)
+			target = zone->swap_limit;
+		else if (capable(CAP_SYS_ADMIN))
+			target = zone->emer_mem;
+		else
+			target = zone->max_mem;
+
+		target = (extra > target) ? 0ULL : target;
+
+		if (zone->used_mem > target)
+			return true;
+	}
+	return false;
+}
+
 /**
  * At this point we only support a single shrink callback.
  * Extend this if needed, perhaps using a linked list of callbacks.
@@ -42,34 +207,17 @@
  * many threads may try to swap out at any given time.
  */
 
-static void ttm_shrink(struct ttm_mem_global *glob, bool from_workqueue,
+static void ttm_shrink(struct ttm_mem_global *glob, bool from_wq,
 		       uint64_t extra)
 {
 	int ret;
 	struct ttm_mem_shrink *shrink;
-	uint64_t target;
-	uint64_t total_target;
 
 	spin_lock(&glob->lock);
 	if (glob->shrink == NULL)
 		goto out;
 
-	if (from_workqueue) {
-		target = glob->swap_limit;
-		total_target = glob->total_memory_swap_limit;
-	} else if (capable(CAP_SYS_ADMIN)) {
-		total_target = glob->emer_total_memory;
-		target = glob->emer_memory;
-	} else {
-		total_target = glob->max_total_memory;
-		target = glob->max_memory;
-	}
-
-	total_target = (extra >= total_target) ? 0 : total_target - extra;
-	target = (extra >= target) ? 0 : target - extra;
-
-	while (glob->used_memory > target ||
-	       glob->used_total_memory > total_target) {
+	while (ttm_zones_above_swap_target(glob, from_wq, extra)) {
 		shrink = glob->shrink;
 		spin_unlock(&glob->lock);
 		ret = shrink->do_shrink(shrink);
@@ -81,6 +229,8 @@ out:
 	spin_unlock(&glob->lock);
 }
 
+
+
 static void ttm_shrink_work(struct work_struct *work)
 {
 	struct ttm_mem_global *glob =
@@ -89,63 +239,198 @@ static void ttm_shrink_work(struct work_struct *work)
 	ttm_shrink(glob, true, 0ULL);
 }
 
+static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob,
+				    const struct sysinfo *si)
+{
+	struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
+	uint64_t mem;
+	int ret;
+
+	if (unlikely(!zone))
+		return -ENOMEM;
+
+	mem = si->totalram - si->totalhigh;
+	mem *= si->mem_unit;
+
+	zone->name = "kernel";
+	zone->zone_mem = mem;
+	zone->max_mem = mem >> 1;
+	zone->emer_mem = (mem >> 1) + (mem >> 2);
+	zone->swap_limit = zone->max_mem - (mem >> 3);
+	zone->used_mem = 0;
+	zone->glob = glob;
+	glob->zone_kernel = zone;
+	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
+	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+	if (unlikely(ret != 0)) {
+		kobject_put(&zone->kobj);
+		return ret;
+	}
+	glob->zones[glob->num_zones++] = zone;
+	return 0;
+}
+
+#ifdef CONFIG_HIGHMEM
+static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob,
+				     const struct sysinfo *si)
+{
+	struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
+	uint64_t mem;
+	int ret;
+
+	if (unlikely(!zone))
+		return -ENOMEM;
+
+	if (si->totalhigh == 0)
+		return 0;
+
+	mem = si->totalram;
+	mem *= si->mem_unit;
+
+	zone->name = "highmem";
+	zone->zone_mem = mem;
+	zone->max_mem = mem >> 1;
+	zone->emer_mem = (mem >> 1) + (mem >> 2);
+	zone->swap_limit = zone->max_mem - (mem >> 3);
+	zone->used_mem = 0;
+	zone->glob = glob;
+	glob->zone_highmem = zone;
+	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
+	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+	if (unlikely(ret != 0)) {
+		kobject_put(&zone->kobj);
+		return ret;
+	}
+	glob->zones[glob->num_zones++] = zone;
+	return 0;
+}
+#else
+static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob,
+				   const struct sysinfo *si)
+{
+	struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL);
+	uint64_t mem;
+	int ret;
+
+	if (unlikely(!zone))
+		return -ENOMEM;
+
+	mem = si->totalram;
+	mem *= si->mem_unit;
+
+	/**
+	 * No special dma32 zone needed.
+	 */
+
+	if (mem <= ((uint64_t) 1ULL << 32))
+		return 0;
+
+	/*
+	 * Limit max dma32 memory to 4GB for now
+	 * until we can figure out how big this
+	 * zone really is.
+	 */
+
+	mem = ((uint64_t) 1ULL << 32);
+	zone->name = "dma32";
+	zone->zone_mem = mem;
+	zone->max_mem = mem >> 1;
+	zone->emer_mem = (mem >> 1) + (mem >> 2);
+	zone->swap_limit = zone->max_mem - (mem >> 3);
+	zone->used_mem = 0;
+	zone->glob = glob;
+	glob->zone_dma32 = zone;
+	kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type);
+	ret = kobject_add(&zone->kobj, &glob->kobj, zone->name);
+	if (unlikely(ret != 0)) {
+		kobject_put(&zone->kobj);
+		return ret;
+	}
+	glob->zones[glob->num_zones++] = zone;
+	return 0;
+}
+#endif
+
 int ttm_mem_global_init(struct ttm_mem_global *glob)
 {
 	struct sysinfo si;
-	uint64_t mem;
+	int ret;
+	int i;
+	struct ttm_mem_zone *zone;
 
 	spin_lock_init(&glob->lock);
 	glob->swap_queue = create_singlethread_workqueue("ttm_swap");
 	INIT_WORK(&glob->work, ttm_shrink_work);
 	init_waitqueue_head(&glob->queue);
+	kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type);
+	ret = kobject_add(&glob->kobj,
+			  ttm_get_kobj(),
+			  "memory_accounting");
+	if (unlikely(ret != 0)) {
+		kobject_put(&glob->kobj);
+		return ret;
+	}
 
 	si_meminfo(&si);
 
-	mem = si.totalram - si.totalhigh;
-	mem *= si.mem_unit;
-
-	glob->max_memory = mem >> 1;
-	glob->emer_memory = (mem >> 1) + (mem >> 2);
-	glob->swap_limit = glob->max_memory - (mem >> 3);
-	glob->used_memory = 0;
-	glob->used_total_memory = 0;
-	glob->shrink = NULL;
-
-	mem = si.totalram;
-	mem *= si.mem_unit;
-
-	glob->max_total_memory = mem >> 1;
-	glob->emer_total_memory = (mem >> 1) + (mem >> 2);
-
-	glob->total_memory_swap_limit = glob->max_total_memory - (mem >> 3);
-
-	printk(KERN_INFO TTM_PFX "TTM available graphics memory: %llu MiB\n",
-	       glob->max_total_memory >> 20);
-	printk(KERN_INFO TTM_PFX "TTM available object memory: %llu MiB\n",
-	       glob->max_memory >> 20);
-
+	ret = ttm_mem_init_kernel_zone(glob, &si);
+	if (unlikely(ret != 0))
+		goto out_no_zone;
+#ifdef CONFIG_HIGHMEM
+	ret = ttm_mem_init_highmem_zone(glob, &si);
+	if (unlikely(ret != 0))
+		goto out_no_zone;
+#else
+	ret = ttm_mem_init_dma32_zone(glob, &si);
+	if (unlikely(ret != 0))
+		goto out_no_zone;
+#endif
+	for (i = 0; i < glob->num_zones; ++i) {
+		zone = glob->zones[i];
+		printk(KERN_INFO TTM_PFX
+		       "Zone %7s: Available graphics memory: %llu kiB.\n",
+		       zone->name, (unsigned long long) zone->max_mem >> 10);
+	}
 	return 0;
+out_no_zone:
+	ttm_mem_global_release(glob);
+	return ret;
 }
 EXPORT_SYMBOL(ttm_mem_global_init);
 
 void ttm_mem_global_release(struct ttm_mem_global *glob)
 {
-	printk(KERN_INFO TTM_PFX "Used total memory is %llu bytes.\n",
-	       (unsigned long long)glob->used_total_memory);
+	unsigned int i;
+	struct ttm_mem_zone *zone;
+
 	flush_workqueue(glob->swap_queue);
 	destroy_workqueue(glob->swap_queue);
 	glob->swap_queue = NULL;
+	for (i = 0; i < glob->num_zones; ++i) {
+		zone = glob->zones[i];
+		kobject_del(&zone->kobj);
+		kobject_put(&zone->kobj);
+	}
+	kobject_del(&glob->kobj);
+	kobject_put(&glob->kobj);
 }
 EXPORT_SYMBOL(ttm_mem_global_release);
 
-static inline void ttm_check_swapping(struct ttm_mem_global *glob)
+static void ttm_check_swapping(struct ttm_mem_global *glob)
 {
-	bool needs_swapping;
+	bool needs_swapping = false;
+	unsigned int i;
+	struct ttm_mem_zone *zone;
 
 	spin_lock(&glob->lock);
-	needs_swapping = (glob->used_memory > glob->swap_limit ||
-			  glob->used_total_memory >
-			  glob->total_memory_swap_limit);
+	for (i = 0; i < glob->num_zones; ++i) {
+		zone = glob->zones[i];
+		if (zone->used_mem > zone->swap_limit) {
+			needs_swapping = true;
+			break;
+		}
+	}
+
 	spin_unlock(&glob->lock);
 
 	if (unlikely(needs_swapping))
@@ -153,44 +438,60 @@ static inline void ttm_check_swapping(struct ttm_mem_global *glob)
 
 }
 
-void ttm_mem_global_free(struct ttm_mem_global *glob,
-			 uint64_t amount, bool himem)
+static void ttm_mem_global_free_zone(struct ttm_mem_global *glob,
+				     struct ttm_mem_zone *single_zone,
+				     uint64_t amount)
 {
+	unsigned int i;
+	struct ttm_mem_zone *zone;
+
 	spin_lock(&glob->lock);
-	glob->used_total_memory -= amount;
-	if (!himem)
-		glob->used_memory -= amount;
-	wake_up_all(&glob->queue);
+	for (i = 0; i < glob->num_zones; ++i) {
+		zone = glob->zones[i];
+		if (single_zone && zone != single_zone)
+			continue;
+		zone->used_mem -= amount;
+	}
 	spin_unlock(&glob->lock);
 }
 
+void ttm_mem_global_free(struct ttm_mem_global *glob,
+			 uint64_t amount)
+{
+	return ttm_mem_global_free_zone(glob, NULL, amount);
+}
+
 static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
-				  uint64_t amount, bool himem, bool reserve)
+				  struct ttm_mem_zone *single_zone,
+				  uint64_t amount, bool reserve)
 {
 	uint64_t limit;
-	uint64_t lomem_limit;
 	int ret = -ENOMEM;
+	unsigned int i;
+	struct ttm_mem_zone *zone;
 
 	spin_lock(&glob->lock);
+	for (i = 0; i < glob->num_zones; ++i) {
+		zone = glob->zones[i];
+		if (single_zone && zone != single_zone)
+			continue;
 
-	if (capable(CAP_SYS_ADMIN)) {
-		limit = glob->emer_total_memory;
-		lomem_limit = glob->emer_memory;
-	} else {
-		limit = glob->max_total_memory;
-		lomem_limit = glob->max_memory;
-	}
+		limit = (capable(CAP_SYS_ADMIN)) ?
+			zone->emer_mem : zone->max_mem;
 
-	if (unlikely(glob->used_total_memory + amount > limit))
-		goto out_unlock;
-	if (unlikely(!himem && glob->used_memory + amount > lomem_limit))
-		goto out_unlock;
+		if (zone->used_mem > limit)
+			goto out_unlock;
+	}
 
 	if (reserve) {
-		glob->used_total_memory += amount;
-		if (!himem)
-			glob->used_memory += amount;
+		for (i = 0; i < glob->num_zones; ++i) {
+			zone = glob->zones[i];
+			if (single_zone && zone != single_zone)
+				continue;
+			zone->used_mem += amount;
+		}
 	}
+
 	ret = 0;
 out_unlock:
 	spin_unlock(&glob->lock);
@@ -199,12 +500,17 @@ out_unlock:
 	return ret;
 }
 
-int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
-			 bool no_wait, bool interruptible, bool himem)
+
+static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob,
+				     struct ttm_mem_zone *single_zone,
+				     uint64_t memory,
+				     bool no_wait, bool interruptible)
 {
 	int count = TTM_MEMORY_ALLOC_RETRIES;
 
-	while (unlikely(ttm_mem_global_reserve(glob, memory, himem, true)
+	while (unlikely(ttm_mem_global_reserve(glob,
+					       single_zone,
+					       memory, true)
 			!= 0)) {
 		if (no_wait)
 			return -ENOMEM;
@@ -216,6 +522,56 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
 	return 0;
 }
 
+int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
+			 bool no_wait, bool interruptible)
+{
+	/**
+	 * Normal allocations of kernel memory are registered in
+	 * all zones.
+	 */
+
+	return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait,
+					 interruptible);
+}
+
+int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
+			      struct page *page,
+			      bool no_wait, bool interruptible)
+{
+
+	struct ttm_mem_zone *zone = NULL;
+
+	/**
+	 * Page allocations may be registed in a single zone
+	 * only if highmem or !dma32.
+	 */
+
+#ifdef CONFIG_HIGHMEM
+	if (PageHighMem(page) && glob->zone_highmem != NULL)
+		zone = glob->zone_highmem;
+#else
+	if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
+		zone = glob->zone_kernel;
+#endif
+	return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, no_wait,
+					 interruptible);
+}
+
+void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page)
+{
+	struct ttm_mem_zone *zone = NULL;
+
+#ifdef CONFIG_HIGHMEM
+	if (PageHighMem(page) && glob->zone_highmem != NULL)
+		zone = glob->zone_highmem;
+#else
+	if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
+		zone = glob->zone_kernel;
+#endif
+	ttm_mem_global_free_zone(glob, zone, PAGE_SIZE);
+}
+
+
 size_t ttm_round_pot(size_t size)
 {
 	if ((size & (size - 1)) == 0)
diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c
index 59ce819..9a6edbf 100644
--- a/drivers/gpu/drm/ttm/ttm_module.c
+++ b/drivers/gpu/drm/ttm/ttm_module.c
@@ -29,16 +29,72 @@
  * 	    Jerome Glisse
  */
 #include <linux/module.h>
-#include <ttm/ttm_module.h>
+#include <linux/device.h>
+#include <linux/sched.h>
+#include "ttm/ttm_module.h"
+#include "drm_sysfs.h"
+
+static DECLARE_WAIT_QUEUE_HEAD(exit_q);
+atomic_t device_released;
+
+static struct device_type ttm_drm_class_type = {
+	.name = "ttm",
+	/**
+	 * Add pm ops here.
+	 */
+};
+
+static void ttm_drm_class_device_release(struct device *dev)
+{
+	atomic_set(&device_released, 1);
+	wake_up_all(&exit_q);
+}
+
+static struct device ttm_drm_class_device = {
+	.type = &ttm_drm_class_type,
+	.release = &ttm_drm_class_device_release
+};
+
+struct kobject *ttm_get_kobj(void)
+{
+	struct kobject *kobj = &ttm_drm_class_device.kobj;
+	BUG_ON(kobj == NULL);
+	return kobj;
+}
 
 static int __init ttm_init(void)
 {
+	int ret;
+
+	ret = dev_set_name(&ttm_drm_class_device, "ttm");
+	if (unlikely(ret != 0))
+		return ret;
+
 	ttm_global_init();
+
+	atomic_set(&device_released, 0);
+	ret = drm_class_device_register(&ttm_drm_class_device);
+	if (unlikely(ret != 0))
+		goto out_no_dev_reg;
+
 	return 0;
+out_no_dev_reg:
+	atomic_set(&device_released, 1);
+	wake_up_all(&exit_q);
+	ttm_global_release();
+	return ret;
 }
 
 static void __exit ttm_exit(void)
 {
+	drm_class_device_unregister(&ttm_drm_class_device);
+
+	/**
+	 * Refuse to unload until the TTM device is released.
+	 * Not sure this is 100% needed.
+	 */
+
+	wait_event(exit_q, atomic_read(&device_released) == 1);
 	ttm_global_release();
 }
 
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index b8b6c4a..a55ee1a 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -34,76 +34,13 @@
 #include <linux/pagemap.h>
 #include <linux/file.h>
 #include <linux/swap.h>
+#include "drm_cache.h"
 #include "ttm/ttm_module.h"
 #include "ttm/ttm_bo_driver.h"
 #include "ttm/ttm_placement.h"
 
 static int ttm_tt_swapin(struct ttm_tt *ttm);
 
-#if defined(CONFIG_X86)
-static void ttm_tt_clflush_page(struct page *page)
-{
-	uint8_t *page_virtual;
-	unsigned int i;
-
-	if (unlikely(page == NULL))
-		return;
-
-	page_virtual = kmap_atomic(page, KM_USER0);
-
-	for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
-		clflush(page_virtual + i);
-
-	kunmap_atomic(page_virtual, KM_USER0);
-}
-
-static void ttm_tt_cache_flush_clflush(struct page *pages[],
-				       unsigned long num_pages)
-{
-	unsigned long i;
-
-	mb();
-	for (i = 0; i < num_pages; ++i)
-		ttm_tt_clflush_page(*pages++);
-	mb();
-}
-#elif !defined(__powerpc__)
-static void ttm_tt_ipi_handler(void *null)
-{
-	;
-}
-#endif
-
-void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages)
-{
-
-#if defined(CONFIG_X86)
-	if (cpu_has_clflush) {
-		ttm_tt_cache_flush_clflush(pages, num_pages);
-		return;
-	}
-#elif defined(__powerpc__)
-	unsigned long i;
-
-	for (i = 0; i < num_pages; ++i) {
-		struct page *page = pages[i];
-		void *page_virtual;
-
-		if (unlikely(page == NULL))
-			continue;
-
-		page_virtual = kmap_atomic(page, KM_USER0);
-		flush_dcache_range((unsigned long) page_virtual,
-				   (unsigned long) page_virtual + PAGE_SIZE);
-		kunmap_atomic(page_virtual, KM_USER0);
-	}
-#else
-	if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1) != 0)
-		printk(KERN_ERR TTM_PFX
-		       "Timed out waiting for drm cache flush.\n");
-#endif
-}
-
 /**
  * Allocates storage for pointers to the pages that back the ttm.
  *
@@ -179,7 +116,7 @@ static void ttm_tt_free_user_pages(struct ttm_tt *ttm)
 			set_page_dirty_lock(page);
 
 		ttm->pages[i] = NULL;
-		ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE, false);
+		ttm_mem_global_free(ttm->glob->mem_glob, PAGE_SIZE);
 		put_page(page);
 	}
 	ttm->state = tt_unpopulated;
@@ -190,8 +127,7 @@ static void ttm_tt_free_user_pages(struct ttm_tt *ttm)
 static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
 {
 	struct page *p;
-	struct ttm_bo_device *bdev = ttm->bdev;
-	struct ttm_mem_global *mem_glob = bdev->mem_glob;
+	struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
 	int ret;
 
 	while (NULL == (p = ttm->pages[index])) {
@@ -200,21 +136,14 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
 		if (!p)
 			return NULL;
 
-		if (PageHighMem(p)) {
-			ret =
-			    ttm_mem_global_alloc(mem_glob, PAGE_SIZE,
-						 false, false, true);
-			if (unlikely(ret != 0))
-				goto out_err;
+		ret = ttm_mem_global_alloc_page(mem_glob, p, false, false);
+		if (unlikely(ret != 0))
+			goto out_err;
+
+		if (PageHighMem(p))
 			ttm->pages[--ttm->first_himem_page] = p;
-		} else {
-			ret =
-			    ttm_mem_global_alloc(mem_glob, PAGE_SIZE,
-						 false, false, false);
-			if (unlikely(ret != 0))
-				goto out_err;
+		else
 			ttm->pages[++ttm->last_lomem_page] = p;
-		}
 	}
 	return p;
 out_err:
@@ -310,7 +239,7 @@ static int ttm_tt_set_caching(struct ttm_tt *ttm,
 	}
 
 	if (ttm->caching_state == tt_cached)
-		ttm_tt_cache_flush(ttm->pages, ttm->num_pages);
+		drm_clflush_pages(ttm->pages, ttm->num_pages);
 
 	for (i = 0; i < ttm->num_pages; ++i) {
 		cur_page = ttm->pages[i];
@@ -368,8 +297,8 @@ static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
 				printk(KERN_ERR TTM_PFX
 				       "Erroneous page count. "
 				       "Leaking pages.\n");
-			ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE,
-					    PageHighMem(cur_page));
+			ttm_mem_global_free_page(ttm->glob->mem_glob,
+						 cur_page);
 			__free_page(cur_page);
 		}
 	}
@@ -414,7 +343,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm,
 	struct mm_struct *mm = tsk->mm;
 	int ret;
 	int write = (ttm->page_flags & TTM_PAGE_FLAG_WRITE) != 0;
-	struct ttm_mem_global *mem_glob = ttm->bdev->mem_glob;
+	struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
 
 	BUG_ON(num_pages != ttm->num_pages);
 	BUG_ON((ttm->page_flags & TTM_PAGE_FLAG_USER) == 0);
@@ -424,7 +353,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm,
 	 */
 
 	ret = ttm_mem_global_alloc(mem_glob, num_pages * PAGE_SIZE,
-				   false, false, false);
+				   false, false);
 	if (unlikely(ret != 0))
 		return ret;
 
@@ -435,7 +364,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm,
 
 	if (ret != num_pages && write) {
 		ttm_tt_free_user_pages(ttm);
-		ttm_mem_global_free(mem_glob, num_pages * PAGE_SIZE, false);
+		ttm_mem_global_free(mem_glob, num_pages * PAGE_SIZE);
 		return -ENOMEM;
 	}
 
@@ -459,8 +388,7 @@ struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size,
 	if (!ttm)
 		return NULL;
 
-	ttm->bdev = bdev;
-
+	ttm->glob = bdev->glob;
 	ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	ttm->first_himem_page = ttm->num_pages;
 	ttm->last_lomem_page = -1;
diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig
new file mode 100644
index 0000000..790e675
--- /dev/null
+++ b/drivers/gpu/vga/Kconfig
@@ -0,0 +1,10 @@
+config VGA_ARB
+	bool "VGA Arbitration" if EMBEDDED
+	default y
+	depends on PCI
+	help
+	  Some "legacy" VGA devices implemented on PCI typically have the same
+	  hard-decoded addresses as they did on ISA. When multiple PCI devices
+	  are accessed at same time they need some kind of coordination. Please
+	  see Documentation/vgaarbiter.txt for more details. Select this to
+	  enable VGA arbiter.
diff --git a/drivers/gpu/vga/Makefile b/drivers/gpu/vga/Makefile
new file mode 100644
index 0000000..7cc8c1e
--- /dev/null
+++ b/drivers/gpu/vga/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VGA_ARB)  += vgaarb.o
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
new file mode 100644
index 0000000..1ac0c93
--- /dev/null
+++ b/drivers/gpu/vga/vgaarb.c
@@ -0,0 +1,1205 @@
+/*
+ * vgaarb.c
+ *
+ * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
+ * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
+ *
+ * Implements the VGA arbitration. For details refer to
+ * Documentation/vgaarbiter.txt
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/poll.h>
+#include <linux/miscdevice.h>
+
+#include <linux/uaccess.h>
+
+#include <linux/vgaarb.h>
+
+static void vga_arbiter_notify_clients(void);
+/*
+ * We keep a list of all vga devices in the system to speed
+ * up the various operations of the arbiter
+ */
+struct vga_device {
+	struct list_head list;
+	struct pci_dev *pdev;
+	unsigned int decodes;	/* what does it decodes */
+	unsigned int owns;	/* what does it owns */
+	unsigned int locks;	/* what does it locks */
+	unsigned int io_lock_cnt;	/* legacy IO lock count */
+	unsigned int mem_lock_cnt;	/* legacy MEM lock count */
+	unsigned int io_norm_cnt;	/* normal IO count */
+	unsigned int mem_norm_cnt;	/* normal MEM count */
+
+	/* allow IRQ enable/disable hook */
+	void *cookie;
+	void (*irq_set_state)(void *cookie, bool enable);
+	unsigned int (*set_vga_decode)(void *cookie, bool decode);
+};
+
+static LIST_HEAD(vga_list);
+static int vga_count, vga_decode_count;
+static bool vga_arbiter_used;
+static DEFINE_SPINLOCK(vga_lock);
+static DECLARE_WAIT_QUEUE_HEAD(vga_wait_queue);
+
+
+static const char *vga_iostate_to_str(unsigned int iostate)
+{
+	/* Ignore VGA_RSRC_IO and VGA_RSRC_MEM */
+	iostate &= VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+	switch (iostate) {
+	case VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM:
+		return "io+mem";
+	case VGA_RSRC_LEGACY_IO:
+		return "io";
+	case VGA_RSRC_LEGACY_MEM:
+		return "mem";
+	}
+	return "none";
+}
+
+static int vga_str_to_iostate(char *buf, int str_size, int *io_state)
+{
+	/* we could in theory hand out locks on IO and mem
+	 * separately to userspace but it can cause deadlocks */
+	if (strncmp(buf, "none", 4) == 0) {
+		*io_state = VGA_RSRC_NONE;
+		return 1;
+	}
+
+	/* XXX We're not chekcing the str_size! */
+	if (strncmp(buf, "io+mem", 6) == 0)
+		goto both;
+	else if (strncmp(buf, "io", 2) == 0)
+		goto both;
+	else if (strncmp(buf, "mem", 3) == 0)
+		goto both;
+	return 0;
+both:
+	*io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+	return 1;
+}
+
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+/* this is only used a cookie - it should not be dereferenced */
+static struct pci_dev *vga_default;
+#endif
+
+static void vga_arb_device_card_gone(struct pci_dev *pdev);
+
+/* Find somebody in our list */
+static struct vga_device *vgadev_find(struct pci_dev *pdev)
+{
+	struct vga_device *vgadev;
+
+	list_for_each_entry(vgadev, &vga_list, list)
+		if (pdev == vgadev->pdev)
+			return vgadev;
+	return NULL;
+}
+
+/* Returns the default VGA device (vgacon's babe) */
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+struct pci_dev *vga_default_device(void)
+{
+	return vga_default;
+}
+#endif
+
+static inline void vga_irq_set_state(struct vga_device *vgadev, bool state)
+{
+	if (vgadev->irq_set_state)
+		vgadev->irq_set_state(vgadev->cookie, state);
+}
+
+
+/* If we don't ever use VGA arb we should avoid
+   turning off anything anywhere due to old X servers getting
+   confused about the boot device not being VGA */
+static void vga_check_first_use(void)
+{
+	/* we should inform all GPUs in the system that
+	 * VGA arb has occured and to try and disable resources
+	 * if they can */
+	if (!vga_arbiter_used) {
+		vga_arbiter_used = true;
+		vga_arbiter_notify_clients();
+	}
+}
+
+static struct vga_device *__vga_tryget(struct vga_device *vgadev,
+				       unsigned int rsrc)
+{
+	unsigned int wants, legacy_wants, match;
+	struct vga_device *conflict;
+	unsigned int pci_bits;
+	/* Account for "normal" resources to lock. If we decode the legacy,
+	 * counterpart, we need to request it as well
+	 */
+	if ((rsrc & VGA_RSRC_NORMAL_IO) &&
+	    (vgadev->decodes & VGA_RSRC_LEGACY_IO))
+		rsrc |= VGA_RSRC_LEGACY_IO;
+	if ((rsrc & VGA_RSRC_NORMAL_MEM) &&
+	    (vgadev->decodes & VGA_RSRC_LEGACY_MEM))
+		rsrc |= VGA_RSRC_LEGACY_MEM;
+
+	pr_devel("%s: %d\n", __func__, rsrc);
+	pr_devel("%s: owns: %d\n", __func__, vgadev->owns);
+
+	/* Check what resources we need to acquire */
+	wants = rsrc & ~vgadev->owns;
+
+	/* We already own everything, just mark locked & bye bye */
+	if (wants == 0)
+		goto lock_them;
+
+	/* We don't need to request a legacy resource, we just enable
+	 * appropriate decoding and go
+	 */
+	legacy_wants = wants & VGA_RSRC_LEGACY_MASK;
+	if (legacy_wants == 0)
+		goto enable_them;
+
+	/* Ok, we don't, let's find out how we need to kick off */
+	list_for_each_entry(conflict, &vga_list, list) {
+		unsigned int lwants = legacy_wants;
+		unsigned int change_bridge = 0;
+
+		/* Don't conflict with myself */
+		if (vgadev == conflict)
+			continue;
+
+		/* Check if the architecture allows a conflict between those
+		 * 2 devices or if they are on separate domains
+		 */
+		if (!vga_conflicts(vgadev->pdev, conflict->pdev))
+			continue;
+
+		/* We have a possible conflict. before we go further, we must
+		 * check if we sit on the same bus as the conflicting device.
+		 * if we don't, then we must tie both IO and MEM resources
+		 * together since there is only a single bit controlling
+		 * VGA forwarding on P2P bridges
+		 */
+		if (vgadev->pdev->bus != conflict->pdev->bus) {
+			change_bridge = 1;
+			lwants = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+		}
+
+		/* Check if the guy has a lock on the resource. If he does,
+		 * return the conflicting entry
+		 */
+		if (conflict->locks & lwants)
+			return conflict;
+
+		/* Ok, now check if he owns the resource we want. We don't need
+		 * to check "decodes" since it should be impossible to own
+		 * own legacy resources you don't decode unless I have a bug
+		 * in this code...
+		 */
+		WARN_ON(conflict->owns & ~conflict->decodes);
+		match = lwants & conflict->owns;
+		if (!match)
+			continue;
+
+		/* looks like he doesn't have a lock, we can steal
+		 * them from him
+		 */
+		vga_irq_set_state(conflict, false);
+
+		pci_bits = 0;
+		if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+			pci_bits |= PCI_COMMAND_MEMORY;
+		if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+			pci_bits |= PCI_COMMAND_IO;
+
+		pci_set_vga_state(conflict->pdev, false, pci_bits,
+				  change_bridge);
+		conflict->owns &= ~lwants;
+		/* If he also owned non-legacy, that is no longer the case */
+		if (lwants & VGA_RSRC_LEGACY_MEM)
+			conflict->owns &= ~VGA_RSRC_NORMAL_MEM;
+		if (lwants & VGA_RSRC_LEGACY_IO)
+			conflict->owns &= ~VGA_RSRC_NORMAL_IO;
+	}
+
+enable_them:
+	/* ok dude, we got it, everybody conflicting has been disabled, let's
+	 * enable us. Make sure we don't mark a bit in "owns" that we don't
+	 * also have in "decodes". We can lock resources we don't decode but
+	 * not own them.
+	 */
+	pci_bits = 0;
+	if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+		pci_bits |= PCI_COMMAND_MEMORY;
+	if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+		pci_bits |= PCI_COMMAND_IO;
+	pci_set_vga_state(vgadev->pdev, true, pci_bits, !!(wants & VGA_RSRC_LEGACY_MASK));
+
+	vga_irq_set_state(vgadev, true);
+	vgadev->owns |= (wants & vgadev->decodes);
+lock_them:
+	vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK);
+	if (rsrc & VGA_RSRC_LEGACY_IO)
+		vgadev->io_lock_cnt++;
+	if (rsrc & VGA_RSRC_LEGACY_MEM)
+		vgadev->mem_lock_cnt++;
+	if (rsrc & VGA_RSRC_NORMAL_IO)
+		vgadev->io_norm_cnt++;
+	if (rsrc & VGA_RSRC_NORMAL_MEM)
+		vgadev->mem_norm_cnt++;
+
+	return NULL;
+}
+
+static void __vga_put(struct vga_device *vgadev, unsigned int rsrc)
+{
+	unsigned int old_locks = vgadev->locks;
+
+	pr_devel("%s\n", __func__);
+
+	/* Update our counters, and account for equivalent legacy resources
+	 * if we decode them
+	 */
+	if ((rsrc & VGA_RSRC_NORMAL_IO) && vgadev->io_norm_cnt > 0) {
+		vgadev->io_norm_cnt--;
+		if (vgadev->decodes & VGA_RSRC_LEGACY_IO)
+			rsrc |= VGA_RSRC_LEGACY_IO;
+	}
+	if ((rsrc & VGA_RSRC_NORMAL_MEM) && vgadev->mem_norm_cnt > 0) {
+		vgadev->mem_norm_cnt--;
+		if (vgadev->decodes & VGA_RSRC_LEGACY_MEM)
+			rsrc |= VGA_RSRC_LEGACY_MEM;
+	}
+	if ((rsrc & VGA_RSRC_LEGACY_IO) && vgadev->io_lock_cnt > 0)
+		vgadev->io_lock_cnt--;
+	if ((rsrc & VGA_RSRC_LEGACY_MEM) && vgadev->mem_lock_cnt > 0)
+		vgadev->mem_lock_cnt--;
+
+	/* Just clear lock bits, we do lazy operations so we don't really
+	 * have to bother about anything else at this point
+	 */
+	if (vgadev->io_lock_cnt == 0)
+		vgadev->locks &= ~VGA_RSRC_LEGACY_IO;
+	if (vgadev->mem_lock_cnt == 0)
+		vgadev->locks &= ~VGA_RSRC_LEGACY_MEM;
+
+	/* Kick the wait queue in case somebody was waiting if we actually
+	 * released something
+	 */
+	if (old_locks != vgadev->locks)
+		wake_up_all(&vga_wait_queue);
+}
+
+int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible)
+{
+	struct vga_device *vgadev, *conflict;
+	unsigned long flags;
+	wait_queue_t wait;
+	int rc = 0;
+
+	vga_check_first_use();
+	/* The one who calls us should check for this, but lets be sure... */
+	if (pdev == NULL)
+		pdev = vga_default_device();
+	if (pdev == NULL)
+		return 0;
+
+	for (;;) {
+		spin_lock_irqsave(&vga_lock, flags);
+		vgadev = vgadev_find(pdev);
+		if (vgadev == NULL) {
+			spin_unlock_irqrestore(&vga_lock, flags);
+			rc = -ENODEV;
+			break;
+		}
+		conflict = __vga_tryget(vgadev, rsrc);
+		spin_unlock_irqrestore(&vga_lock, flags);
+		if (conflict == NULL)
+			break;
+
+
+		/* We have a conflict, we wait until somebody kicks the
+		 * work queue. Currently we have one work queue that we
+		 * kick each time some resources are released, but it would
+		 * be fairly easy to have a per device one so that we only
+		 * need to attach to the conflicting device
+		 */
+		init_waitqueue_entry(&wait, current);
+		add_wait_queue(&vga_wait_queue, &wait);
+		set_current_state(interruptible ?
+				  TASK_INTERRUPTIBLE :
+				  TASK_UNINTERRUPTIBLE);
+		if (signal_pending(current)) {
+			rc = -EINTR;
+			break;
+		}
+		schedule();
+		remove_wait_queue(&vga_wait_queue, &wait);
+		set_current_state(TASK_RUNNING);
+	}
+	return rc;
+}
+EXPORT_SYMBOL(vga_get);
+
+int vga_tryget(struct pci_dev *pdev, unsigned int rsrc)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+	int rc = 0;
+
+	vga_check_first_use();
+
+	/* The one who calls us should check for this, but lets be sure... */
+	if (pdev == NULL)
+		pdev = vga_default_device();
+	if (pdev == NULL)
+		return 0;
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL) {
+		rc = -ENODEV;
+		goto bail;
+	}
+	if (__vga_tryget(vgadev, rsrc))
+		rc = -EBUSY;
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	return rc;
+}
+EXPORT_SYMBOL(vga_tryget);
+
+void vga_put(struct pci_dev *pdev, unsigned int rsrc)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+
+	/* The one who calls us should check for this, but lets be sure... */
+	if (pdev == NULL)
+		pdev = vga_default_device();
+	if (pdev == NULL)
+		return;
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL)
+		goto bail;
+	__vga_put(vgadev, rsrc);
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+EXPORT_SYMBOL(vga_put);
+
+/*
+ * Currently, we assume that the "initial" setup of the system is
+ * not sane, that is we come up with conflicting devices and let
+ * the arbiter's client decides if devices decodes or not legacy
+ * things.
+ */
+static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+	struct pci_bus *bus;
+	struct pci_dev *bridge;
+	u16 cmd;
+
+	/* Only deal with VGA class devices */
+	if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+		return false;
+
+	/* Allocate structure */
+	vgadev = kmalloc(sizeof(struct vga_device), GFP_KERNEL);
+	if (vgadev == NULL) {
+		pr_err("vgaarb: failed to allocate pci device\n");
+		/* What to do on allocation failure ? For now, let's
+		 * just do nothing, I'm not sure there is anything saner
+		 * to be done
+		 */
+		return false;
+	}
+
+	memset(vgadev, 0, sizeof(*vgadev));
+
+	/* Take lock & check for duplicates */
+	spin_lock_irqsave(&vga_lock, flags);
+	if (vgadev_find(pdev) != NULL) {
+		BUG_ON(1);
+		goto fail;
+	}
+	vgadev->pdev = pdev;
+
+	/* By default, assume we decode everything */
+	vgadev->decodes = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
+			  VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
+
+	/* by default mark it as decoding */
+	vga_decode_count++;
+	/* Mark that we "own" resources based on our enables, we will
+	 * clear that below if the bridge isn't forwarding
+	 */
+	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+	if (cmd & PCI_COMMAND_IO)
+		vgadev->owns |= VGA_RSRC_LEGACY_IO;
+	if (cmd & PCI_COMMAND_MEMORY)
+		vgadev->owns |= VGA_RSRC_LEGACY_MEM;
+
+	/* Check if VGA cycles can get down to us */
+	bus = pdev->bus;
+	while (bus) {
+		bridge = bus->self;
+		if (bridge) {
+			u16 l;
+			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+					     &l);
+			if (!(l & PCI_BRIDGE_CTL_VGA)) {
+				vgadev->owns = 0;
+				break;
+			}
+		}
+		bus = bus->parent;
+	}
+
+	/* Deal with VGA default device. Use first enabled one
+	 * by default if arch doesn't have it's own hook
+	 */
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+	if (vga_default == NULL &&
+	    ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK))
+		vga_default = pci_dev_get(pdev);
+#endif
+
+	/* Add to the list */
+	list_add(&vgadev->list, &vga_list);
+	vga_count++;
+	pr_info("vgaarb: device added: PCI:%s,decodes=%s,owns=%s,locks=%s\n",
+		pci_name(pdev),
+		vga_iostate_to_str(vgadev->decodes),
+		vga_iostate_to_str(vgadev->owns),
+		vga_iostate_to_str(vgadev->locks));
+
+	spin_unlock_irqrestore(&vga_lock, flags);
+	return true;
+fail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	kfree(vgadev);
+	return false;
+}
+
+static bool vga_arbiter_del_pci_device(struct pci_dev *pdev)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+	bool ret = true;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL) {
+		ret = false;
+		goto bail;
+	}
+
+	if (vga_default == pdev) {
+		pci_dev_put(vga_default);
+		vga_default = NULL;
+	}
+
+	if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
+		vga_decode_count--;
+
+	/* Remove entry from list */
+	list_del(&vgadev->list);
+	vga_count--;
+	/* Notify userland driver that the device is gone so it discards
+	 * it's copies of the pci_dev pointer
+	 */
+	vga_arb_device_card_gone(pdev);
+
+	/* Wake up all possible waiters */
+	wake_up_all(&vga_wait_queue);
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	kfree(vgadev);
+	return ret;
+}
+
+/* this is called with the lock */
+static inline void vga_update_device_decodes(struct vga_device *vgadev,
+					     int new_decodes)
+{
+	int old_decodes;
+	struct vga_device *new_vgadev, *conflict;
+
+	old_decodes = vgadev->decodes;
+	vgadev->decodes = new_decodes;
+
+	pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n",
+		pci_name(vgadev->pdev),
+		vga_iostate_to_str(old_decodes),
+		vga_iostate_to_str(vgadev->decodes),
+		vga_iostate_to_str(vgadev->owns));
+
+
+	/* if we own the decodes we should move them along to
+	   another card */
+	if ((vgadev->owns & old_decodes) && (vga_count > 1)) {
+		/* set us to own nothing */
+		vgadev->owns &= ~old_decodes;
+		list_for_each_entry(new_vgadev, &vga_list, list) {
+			if ((new_vgadev != vgadev) &&
+			    (new_vgadev->decodes & VGA_RSRC_LEGACY_MASK)) {
+				pr_info("vgaarb: transferring owner from PCI:%s to PCI:%s\n", pci_name(vgadev->pdev), pci_name(new_vgadev->pdev));
+				conflict = __vga_tryget(new_vgadev, VGA_RSRC_LEGACY_MASK);
+				if (!conflict)
+					__vga_put(new_vgadev, VGA_RSRC_LEGACY_MASK);
+				break;
+			}
+		}
+	}
+
+	/* change decodes counter */
+	if (old_decodes != new_decodes) {
+		if (new_decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM))
+			vga_decode_count++;
+		else
+			vga_decode_count--;
+	}
+}
+
+void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+
+	decodes &= VGA_RSRC_LEGACY_MASK;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL)
+		goto bail;
+
+	/* don't let userspace futz with kernel driver decodes */
+	if (userspace && vgadev->set_vga_decode)
+		goto bail;
+
+	/* update the device decodes + counter */
+	vga_update_device_decodes(vgadev, decodes);
+
+	/* XXX if somebody is going from "doesn't decode" to "decodes" state
+	 * here, additional care must be taken as we may have pending owner
+	 * ship of non-legacy region ...
+	 */
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+
+void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes)
+{
+	__vga_set_legacy_decoding(pdev, decodes, false);
+}
+EXPORT_SYMBOL(vga_set_legacy_decoding);
+
+/* call with NULL to unregister */
+int vga_client_register(struct pci_dev *pdev, void *cookie,
+			void (*irq_set_state)(void *cookie, bool state),
+			unsigned int (*set_vga_decode)(void *cookie, bool decode))
+{
+	int ret = -1;
+	struct vga_device *vgadev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	vgadev = vgadev_find(pdev);
+	if (!vgadev)
+		goto bail;
+
+	vgadev->irq_set_state = irq_set_state;
+	vgadev->set_vga_decode = set_vga_decode;
+	vgadev->cookie = cookie;
+	ret = 0;
+
+bail:
+	spin_unlock_irqrestore(&vga_lock, flags);
+	return ret;
+
+}
+EXPORT_SYMBOL(vga_client_register);
+
+/*
+ * Char driver implementation
+ *
+ * Semantics is:
+ *
+ *  open       : open user instance of the arbitrer. by default, it's
+ *                attached to the default VGA device of the system.
+ *
+ *  close      : close user instance, release locks
+ *
+ *  read       : return a string indicating the status of the target.
+ *                an IO state string is of the form {io,mem,io+mem,none},
+ *                mc and ic are respectively mem and io lock counts (for
+ *                debugging/diagnostic only). "decodes" indicate what the
+ *                card currently decodes, "owns" indicates what is currently
+ *                enabled on it, and "locks" indicates what is locked by this
+ *                card. If the card is unplugged, we get "invalid" then for
+ *                card_ID and an -ENODEV error is returned for any command
+ *                until a new card is targeted
+ *
+ *   "<card_ID>,decodes=<io_state>,owns=<io_state>,locks=<io_state> (ic,mc)"
+ *
+ * write       : write a command to the arbiter. List of commands is:
+ *
+ *   target <card_ID>   : switch target to card <card_ID> (see below)
+ *   lock <io_state>    : acquires locks on target ("none" is invalid io_state)
+ *   trylock <io_state> : non-blocking acquire locks on target
+ *   unlock <io_state>  : release locks on target
+ *   unlock all         : release all locks on target held by this user
+ *   decodes <io_state> : set the legacy decoding attributes for the card
+ *
+ * poll         : event if something change on any card (not just the target)
+ *
+ * card_ID is of the form "PCI:domain:bus:dev.fn". It can be set to "default"
+ * to go back to the system default card (TODO: not implemented yet).
+ * Currently, only PCI is supported as a prefix, but the userland API may
+ * support other bus types in the future, even if the current kernel
+ * implementation doesn't.
+ *
+ * Note about locks:
+ *
+ * The driver keeps track of which user has what locks on which card. It
+ * supports stacking, like the kernel one. This complexifies the implementation
+ * a bit, but makes the arbiter more tolerant to userspace problems and able
+ * to properly cleanup in all cases when a process dies.
+ * Currently, a max of 16 cards simultaneously can have locks issued from
+ * userspace for a given user (file descriptor instance) of the arbiter.
+ *
+ * If the device is hot-unplugged, there is a hook inside the module to notify
+ * they being added/removed in the system and automatically added/removed in
+ * the arbiter.
+ */
+
+#define MAX_USER_CARDS         16
+#define PCI_INVALID_CARD       ((struct pci_dev *)-1UL)
+
+/*
+ * Each user has an array of these, tracking which cards have locks
+ */
+struct vga_arb_user_card {
+	struct pci_dev *pdev;
+	unsigned int mem_cnt;
+	unsigned int io_cnt;
+};
+
+struct vga_arb_private {
+	struct list_head list;
+	struct pci_dev *target;
+	struct vga_arb_user_card cards[MAX_USER_CARDS];
+	spinlock_t lock;
+};
+
+static LIST_HEAD(vga_user_list);
+static DEFINE_SPINLOCK(vga_user_lock);
+
+
+/*
+ * This function gets a string in the format: "PCI:domain:bus:dev.fn" and
+ * returns the respective values. If the string is not in this format,
+ * it returns 0.
+ */
+static int vga_pci_str_to_vars(char *buf, int count, unsigned int *domain,
+			       unsigned int *bus, unsigned int *devfn)
+{
+	int n;
+	unsigned int slot, func;
+
+
+	n = sscanf(buf, "PCI:%x:%x:%x.%x", domain, bus, &slot, &func);
+	if (n != 4)
+		return 0;
+
+	*devfn = PCI_DEVFN(slot, func);
+
+	return 1;
+}
+
+static ssize_t vga_arb_read(struct file *file, char __user * buf,
+			    size_t count, loff_t *ppos)
+{
+	struct vga_arb_private *priv = file->private_data;
+	struct vga_device *vgadev;
+	struct pci_dev *pdev;
+	unsigned long flags;
+	size_t len;
+	int rc;
+	char *lbuf;
+
+	lbuf = kmalloc(1024, GFP_KERNEL);
+	if (lbuf == NULL)
+		return -ENOMEM;
+
+	/* Shields against vga_arb_device_card_gone (pci_dev going
+	 * away), and allows access to vga list
+	 */
+	spin_lock_irqsave(&vga_lock, flags);
+
+	/* If we are targetting the default, use it */
+	pdev = priv->target;
+	if (pdev == NULL || pdev == PCI_INVALID_CARD) {
+		spin_unlock_irqrestore(&vga_lock, flags);
+		len = sprintf(lbuf, "invalid");
+		goto done;
+	}
+
+	/* Find card vgadev structure */
+	vgadev = vgadev_find(pdev);
+	if (vgadev == NULL) {
+		/* Wow, it's not in the list, that shouldn't happen,
+		 * let's fix us up and return invalid card
+		 */
+		if (pdev == priv->target)
+			vga_arb_device_card_gone(pdev);
+		spin_unlock_irqrestore(&vga_lock, flags);
+		len = sprintf(lbuf, "invalid");
+		goto done;
+	}
+
+	/* Fill the buffer with infos */
+	len = snprintf(lbuf, 1024,
+		       "count:%d,PCI:%s,decodes=%s,owns=%s,locks=%s(%d:%d)\n",
+		       vga_decode_count, pci_name(pdev),
+		       vga_iostate_to_str(vgadev->decodes),
+		       vga_iostate_to_str(vgadev->owns),
+		       vga_iostate_to_str(vgadev->locks),
+		       vgadev->io_lock_cnt, vgadev->mem_lock_cnt);
+
+	spin_unlock_irqrestore(&vga_lock, flags);
+done:
+
+	/* Copy that to user */
+	if (len > count)
+		len = count;
+	rc = copy_to_user(buf, lbuf, len);
+	kfree(lbuf);
+	if (rc)
+		return -EFAULT;
+	return len;
+}
+
+/*
+ * TODO: To avoid parsing inside kernel and to improve the speed we may
+ * consider use ioctl here
+ */
+static ssize_t vga_arb_write(struct file *file, const char __user * buf,
+			     size_t count, loff_t *ppos)
+{
+	struct vga_arb_private *priv = file->private_data;
+	struct vga_arb_user_card *uc = NULL;
+	struct pci_dev *pdev;
+
+	unsigned int io_state;
+
+	char *kbuf, *curr_pos;
+	size_t remaining = count;
+
+	int ret_val;
+	int i;
+
+
+	kbuf = kmalloc(count + 1, GFP_KERNEL);
+	if (!kbuf)
+		return -ENOMEM;
+
+	if (copy_from_user(kbuf, buf, count)) {
+		kfree(kbuf);
+		return -EFAULT;
+	}
+	curr_pos = kbuf;
+	kbuf[count] = '\0';	/* Just to make sure... */
+
+	if (strncmp(curr_pos, "lock ", 5) == 0) {
+		curr_pos += 5;
+		remaining -= 5;
+
+		pr_devel("client 0x%p called 'lock'\n", priv);
+
+		if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+		if (io_state == VGA_RSRC_NONE) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		vga_get_uninterruptible(pdev, io_state);
+
+		/* Update the client's locks lists... */
+		for (i = 0; i < MAX_USER_CARDS; i++) {
+			if (priv->cards[i].pdev == pdev) {
+				if (io_state & VGA_RSRC_LEGACY_IO)
+					priv->cards[i].io_cnt++;
+				if (io_state & VGA_RSRC_LEGACY_MEM)
+					priv->cards[i].mem_cnt++;
+				break;
+			}
+		}
+
+		ret_val = count;
+		goto done;
+	} else if (strncmp(curr_pos, "unlock ", 7) == 0) {
+		curr_pos += 7;
+		remaining -= 7;
+
+		pr_devel("client 0x%p called 'unlock'\n", priv);
+
+		if (strncmp(curr_pos, "all", 3) == 0)
+			io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM;
+		else {
+			if (!vga_str_to_iostate
+			    (curr_pos, remaining, &io_state)) {
+				ret_val = -EPROTO;
+				goto done;
+			}
+			/* TODO: Add this?
+			   if (io_state == VGA_RSRC_NONE) {
+			   ret_val = -EPROTO;
+			   goto done;
+			   }
+			  */
+		}
+
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+		for (i = 0; i < MAX_USER_CARDS; i++) {
+			if (priv->cards[i].pdev == pdev)
+				uc = &priv->cards[i];
+		}
+
+		if (!uc)
+			return -EINVAL;
+
+		if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0)
+			return -EINVAL;
+
+		if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0)
+			return -EINVAL;
+
+		vga_put(pdev, io_state);
+
+		if (io_state & VGA_RSRC_LEGACY_IO)
+			uc->io_cnt--;
+		if (io_state & VGA_RSRC_LEGACY_MEM)
+			uc->mem_cnt--;
+
+		ret_val = count;
+		goto done;
+	} else if (strncmp(curr_pos, "trylock ", 8) == 0) {
+		curr_pos += 8;
+		remaining -= 8;
+
+		pr_devel("client 0x%p called 'trylock'\n", priv);
+
+		if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+		/* TODO: Add this?
+		   if (io_state == VGA_RSRC_NONE) {
+		   ret_val = -EPROTO;
+		   goto done;
+		   }
+		 */
+
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		if (vga_tryget(pdev, io_state)) {
+			/* Update the client's locks lists... */
+			for (i = 0; i < MAX_USER_CARDS; i++) {
+				if (priv->cards[i].pdev == pdev) {
+					if (io_state & VGA_RSRC_LEGACY_IO)
+						priv->cards[i].io_cnt++;
+					if (io_state & VGA_RSRC_LEGACY_MEM)
+						priv->cards[i].mem_cnt++;
+					break;
+				}
+			}
+			ret_val = count;
+			goto done;
+		} else {
+			ret_val = -EBUSY;
+			goto done;
+		}
+
+	} else if (strncmp(curr_pos, "target ", 7) == 0) {
+		unsigned int domain, bus, devfn;
+		struct vga_device *vgadev;
+
+		curr_pos += 7;
+		remaining -= 7;
+		pr_devel("client 0x%p called 'target'\n", priv);
+		/* if target is default */
+		if (!strncmp(buf, "default", 7))
+			pdev = pci_dev_get(vga_default_device());
+		else {
+			if (!vga_pci_str_to_vars(curr_pos, remaining,
+						 &domain, &bus, &devfn)) {
+				ret_val = -EPROTO;
+				goto done;
+			}
+
+			pdev = pci_get_bus_and_slot(bus, devfn);
+			if (!pdev) {
+				pr_info("vgaarb: invalid PCI address!\n");
+				ret_val = -ENODEV;
+				goto done;
+			}
+		}
+
+		vgadev = vgadev_find(pdev);
+		if (vgadev == NULL) {
+			pr_info("vgaarb: this pci device is not a vga device\n");
+			pci_dev_put(pdev);
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		priv->target = pdev;
+		for (i = 0; i < MAX_USER_CARDS; i++) {
+			if (priv->cards[i].pdev == pdev)
+				break;
+			if (priv->cards[i].pdev == NULL) {
+				priv->cards[i].pdev = pdev;
+				priv->cards[i].io_cnt = 0;
+				priv->cards[i].mem_cnt = 0;
+				break;
+			}
+		}
+		if (i == MAX_USER_CARDS) {
+			pr_err("vgaarb: maximum user cards number reached!\n");
+			pci_dev_put(pdev);
+			/* XXX: which value to return? */
+			ret_val =  -ENOMEM;
+			goto done;
+		}
+
+		ret_val = count;
+		pci_dev_put(pdev);
+		goto done;
+
+
+	} else if (strncmp(curr_pos, "decodes ", 8) == 0) {
+		curr_pos += 8;
+		remaining -= 8;
+		pr_devel("vgaarb: client 0x%p called 'decodes'\n", priv);
+
+		if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) {
+			ret_val = -EPROTO;
+			goto done;
+		}
+		pdev = priv->target;
+		if (priv->target == NULL) {
+			ret_val = -ENODEV;
+			goto done;
+		}
+
+		__vga_set_legacy_decoding(pdev, io_state, true);
+		ret_val = count;
+		goto done;
+	}
+	/* If we got here, the message written is not part of the protocol! */
+	kfree(kbuf);
+	return -EPROTO;
+
+done:
+	kfree(kbuf);
+	return ret_val;
+}
+
+static unsigned int vga_arb_fpoll(struct file *file, poll_table * wait)
+{
+	struct vga_arb_private *priv = file->private_data;
+
+	pr_devel("%s\n", __func__);
+
+	if (priv == NULL)
+		return -ENODEV;
+	poll_wait(file, &vga_wait_queue, wait);
+	return POLLIN;
+}
+
+static int vga_arb_open(struct inode *inode, struct file *file)
+{
+	struct vga_arb_private *priv;
+	unsigned long flags;
+
+	pr_devel("%s\n", __func__);
+
+	priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL);
+	if (priv == NULL)
+		return -ENOMEM;
+	memset(priv, 0, sizeof(*priv));
+	spin_lock_init(&priv->lock);
+	file->private_data = priv;
+
+	spin_lock_irqsave(&vga_user_lock, flags);
+	list_add(&priv->list, &vga_user_list);
+	spin_unlock_irqrestore(&vga_user_lock, flags);
+
+	/* Set the client' lists of locks */
+	priv->target = vga_default_device(); /* Maybe this is still null! */
+	priv->cards[0].pdev = priv->target;
+	priv->cards[0].io_cnt = 0;
+	priv->cards[0].mem_cnt = 0;
+
+
+	return 0;
+}
+
+static int vga_arb_release(struct inode *inode, struct file *file)
+{
+	struct vga_arb_private *priv = file->private_data;
+	struct vga_arb_user_card *uc;
+	unsigned long flags;
+	int i;
+
+	pr_devel("%s\n", __func__);
+
+	if (priv == NULL)
+		return -ENODEV;
+
+	spin_lock_irqsave(&vga_user_lock, flags);
+	list_del(&priv->list);
+	for (i = 0; i < MAX_USER_CARDS; i++) {
+		uc = &priv->cards[i];
+		if (uc->pdev == NULL)
+			continue;
+		pr_devel("uc->io_cnt == %d, uc->mem_cnt == %d\n",
+			 uc->io_cnt, uc->mem_cnt);
+		while (uc->io_cnt--)
+			vga_put(uc->pdev, VGA_RSRC_LEGACY_IO);
+		while (uc->mem_cnt--)
+			vga_put(uc->pdev, VGA_RSRC_LEGACY_MEM);
+	}
+	spin_unlock_irqrestore(&vga_user_lock, flags);
+
+	kfree(priv);
+
+	return 0;
+}
+
+static void vga_arb_device_card_gone(struct pci_dev *pdev)
+{
+}
+
+/*
+ * callback any registered clients to let them know we have a
+ * change in VGA cards
+ */
+static void vga_arbiter_notify_clients(void)
+{
+	struct vga_device *vgadev;
+	unsigned long flags;
+	uint32_t new_decodes;
+	bool new_state;
+
+	if (!vga_arbiter_used)
+		return;
+
+	spin_lock_irqsave(&vga_lock, flags);
+	list_for_each_entry(vgadev, &vga_list, list) {
+		if (vga_count > 1)
+			new_state = false;
+		else
+			new_state = true;
+		if (vgadev->set_vga_decode) {
+			new_decodes = vgadev->set_vga_decode(vgadev->cookie, new_state);
+			vga_update_device_decodes(vgadev, new_decodes);
+		}
+	}
+	spin_unlock_irqrestore(&vga_lock, flags);
+}
+
+static int pci_notify(struct notifier_block *nb, unsigned long action,
+		      void *data)
+{
+	struct device *dev = data;
+	struct pci_dev *pdev = to_pci_dev(dev);
+	bool notify = false;
+
+	pr_devel("%s\n", __func__);
+
+	/* For now we're only intereted in devices added and removed. I didn't
+	 * test this thing here, so someone needs to double check for the
+	 * cases of hotplugable vga cards. */
+	if (action == BUS_NOTIFY_ADD_DEVICE)
+		notify = vga_arbiter_add_pci_device(pdev);
+	else if (action == BUS_NOTIFY_DEL_DEVICE)
+		notify = vga_arbiter_del_pci_device(pdev);
+
+	if (notify)
+		vga_arbiter_notify_clients();
+	return 0;
+}
+
+static struct notifier_block pci_notifier = {
+	.notifier_call = pci_notify,
+};
+
+static const struct file_operations vga_arb_device_fops = {
+	.read = vga_arb_read,
+	.write = vga_arb_write,
+	.poll = vga_arb_fpoll,
+	.open = vga_arb_open,
+	.release = vga_arb_release,
+};
+
+static struct miscdevice vga_arb_device = {
+	MISC_DYNAMIC_MINOR, "vga_arbiter", &vga_arb_device_fops
+};
+
+static int __init vga_arb_device_init(void)
+{
+	int rc;
+	struct pci_dev *pdev;
+
+	rc = misc_register(&vga_arb_device);
+	if (rc < 0)
+		pr_err("vgaarb: error %d registering device\n", rc);
+
+	bus_register_notifier(&pci_bus_type, &pci_notifier);
+
+	/* We add all pci devices satisfying vga class in the arbiter by
+	 * default */
+	pdev = NULL;
+	while ((pdev =
+		pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+			       PCI_ANY_ID, pdev)) != NULL)
+		vga_arbiter_add_pci_device(pdev);
+
+	pr_info("vgaarb: loaded\n");
+	return rc;
+}
+subsys_initcall(vga_arb_device_init);
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 7831a03..111afbe 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -31,21 +31,6 @@ config HID
 
 	  If unsure, say Y.
 
-config HID_DEBUG
-	bool "HID debugging support"
-	default y
-	depends on HID
-	---help---
-	This option lets the HID layer output diagnostics about its internal
-	state, resolve HID usages, dump HID fields, etc. Individual HID drivers
-	use this debugging facility to output information about individual HID
-	devices, etc.
-
-	This feature is useful for those who are either debugging the HID parser
-	or any HID hardware device.
-
-	If unsure, say Y.
-
 config HIDRAW
 	bool "/dev/hidraw raw HID device support"
 	depends on HID
@@ -152,6 +137,13 @@ config HID_GYRATION
 	---help---
 	Support for Gyration remote control.
 
+config HID_TWINHAN
+	tristate "Twinhan" if EMBEDDED
+	depends on USB_HID
+	default !EMBEDDED
+	---help---
+	Support for Twinhan IR remote control.
+
 config HID_KENSINGTON
 	tristate "Kensington" if EMBEDDED
 	depends on USB_HID
@@ -176,6 +168,7 @@ config LOGITECH_FF
 	  - Logitech WingMan Cordless RumblePad 2
 	  - Logitech WingMan Force 3D
 	  - Logitech Formula Force EX
+	  - Logitech WingMan Formula Force GP
 	  - Logitech MOMO Force wheel
 
 	  and if you want to enable force feedback for them.
@@ -314,9 +307,9 @@ config THRUSTMASTER_FF
 	depends on HID_THRUSTMASTER
 	select INPUT_FF_MEMLESS
 	---help---
-	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
-	  a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel and
-	  want to enable force feedback support for it.
+	  Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3,
+	  a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT
+	  Rumble Force or Force Feedback Wheel.
 
 config HID_WACOM
 	tristate "Wacom Bluetooth devices support" if EMBEDDED
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index db35151..0de2dff 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -3,9 +3,12 @@
 #
 hid-objs			:= hid-core.o hid-input.o
 
+ifdef CONFIG_DEBUG_FS
+	hid-objs		+= hid-debug.o
+endif
+
 obj-$(CONFIG_HID)		+= hid.o
 
-hid-$(CONFIG_HID_DEBUG)		+= hid-debug.o
 hid-$(CONFIG_HIDRAW)		+= hidraw.o
 
 hid-logitech-objs		:= hid-lg.o
@@ -40,6 +43,7 @@ obj-$(CONFIG_HID_SUNPLUS)	+= hid-sunplus.o
 obj-$(CONFIG_HID_GREENASIA)	+= hid-gaff.o
 obj-$(CONFIG_HID_THRUSTMASTER)	+= hid-tmff.o
 obj-$(CONFIG_HID_TOPSEED)	+= hid-topseed.o
+obj-$(CONFIG_HID_TWINHAN)	+= hid-twinhan.o
 obj-$(CONFIG_HID_ZEROPLUS)	+= hid-zpff.o
 obj-$(CONFIG_HID_WACOM)		+= hid-wacom.o
 
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index 42ea359..df474c6 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -145,12 +145,12 @@ static struct hid_driver a4_driver = {
 	.remove = a4_remove,
 };
 
-static int a4_init(void)
+static int __init a4_init(void)
 {
 	return hid_register_driver(&a4_driver);
 }
 
-static void a4_exit(void)
+static void __exit a4_exit(void)
 {
 	hid_unregister_driver(&a4_driver);
 }
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 303ccce..4b96e7a 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -451,7 +451,7 @@ static struct hid_driver apple_driver = {
 	.input_mapped = apple_input_mapped,
 };
 
-static int apple_init(void)
+static int __init apple_init(void)
 {
 	int ret;
 
@@ -462,7 +462,7 @@ static int apple_init(void)
 	return ret;
 }
 
-static void apple_exit(void)
+static void __exit apple_exit(void)
 {
 	hid_unregister_driver(&apple_driver);
 }
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 2f67231..4ce7aa3 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -88,12 +88,12 @@ static struct hid_driver belkin_driver = {
 	.probe = belkin_probe,
 };
 
-static int belkin_init(void)
+static int __init belkin_init(void)
 {
 	return hid_register_driver(&belkin_driver);
 }
 
-static void belkin_exit(void)
+static void __exit belkin_exit(void)
 {
 	hid_unregister_driver(&belkin_driver);
 }
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index ab8209e..7e597d7 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -70,12 +70,12 @@ static struct hid_driver ch_driver = {
 	.input_mapping = ch_input_mapping,
 };
 
-static int ch_init(void)
+static int __init ch_init(void)
 {
 	return hid_register_driver(&ch_driver);
 }
 
-static void ch_exit(void)
+static void __exit ch_exit(void)
 {
 	hid_unregister_driver(&ch_driver);
 }
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index 7f91076..8965ad9 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -63,12 +63,12 @@ static struct hid_driver ch_driver = {
 	.input_mapping = ch_input_mapping,
 };
 
-static int ch_init(void)
+static int __init ch_init(void)
 {
 	return hid_register_driver(&ch_driver);
 }
 
-static void ch_exit(void)
+static void __exit ch_exit(void)
 {
 	hid_unregister_driver(&ch_driver);
 }
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5eb10c2..342b7d3 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -44,12 +44,10 @@
 #define DRIVER_DESC "HID core driver"
 #define DRIVER_LICENSE "GPL"
 
-#ifdef CONFIG_HID_DEBUG
 int hid_debug = 0;
 module_param_named(debug, hid_debug, int, 0600);
-MODULE_PARM_DESC(debug, "HID debugging (0=off, 1=probing info, 2=continuous data dumping)");
+MODULE_PARM_DESC(debug, "toggle HID debugging messages");
 EXPORT_SYMBOL_GPL(hid_debug);
-#endif
 
 /*
  * Register a new report for a device.
@@ -861,7 +859,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field,
 	struct hid_driver *hdrv = hid->driver;
 	int ret;
 
-	hid_dump_input(usage, value);
+	hid_dump_input(hid, usage, value);
 
 	if (hdrv && hdrv->event && hid_match_usage(hid, usage)) {
 		ret = hdrv->event(hid, field, usage, value);
@@ -983,11 +981,10 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
 {
 	unsigned size = field->report_size;
 
-	hid_dump_input(field->usage + offset, value);
+	hid_dump_input(field->report->device, field->usage + offset, value);
 
 	if (offset >= field->report_count) {
 		dbg_hid("offset (%d) exceeds report_count (%d)\n", offset, field->report_count);
-		hid_dump_field(field, 8);
 		return -1;
 	}
 	if (field->logical_minimum < 0) {
@@ -1078,6 +1075,7 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
 	struct hid_report_enum *report_enum;
 	struct hid_driver *hdrv;
 	struct hid_report *report;
+	char *buf;
 	unsigned int i;
 	int ret;
 
@@ -1091,18 +1089,38 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
 		return -1;
 	}
 
-	dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
+	buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE,
+			interrupt ? GFP_ATOMIC : GFP_KERNEL);
+
+	if (!buf) {
+		report = hid_get_report(report_enum, data);
+		goto nomem;
+	}
+
+	snprintf(buf, HID_DEBUG_BUFSIZE - 1,
+			"\nreport (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un");
+	hid_debug_event(hid, buf);
 
 	report = hid_get_report(report_enum, data);
-	if (!report)
+	if (!report) {
+		kfree(buf);
 		return -1;
+	}
 
 	/* dump the report */
-	dbg_hid("report %d (size %u) = ", report->id, size);
-	for (i = 0; i < size; i++)
-		dbg_hid_line(" %02x", data[i]);
-	dbg_hid_line("\n");
+	snprintf(buf, HID_DEBUG_BUFSIZE - 1,
+			"report %d (size %u) = ", report->id, size);
+	hid_debug_event(hid, buf);
+	for (i = 0; i < size; i++) {
+		snprintf(buf, HID_DEBUG_BUFSIZE - 1,
+				" %02x", data[i]);
+		hid_debug_event(hid, buf);
+	}
+	hid_debug_event(hid, "\n");
+
+	kfree(buf);
 
+nomem:
 	if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
 		ret = hdrv->raw_event(hid, report, data, size);
 		if (ret != 0)
@@ -1292,6 +1310,7 @@ static const struct hid_device_id hid_blacklist[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
@@ -1311,15 +1330,17 @@ static const struct hid_device_id hid_blacklist[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
 
-	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
 	{ }
 };
@@ -1622,12 +1643,8 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) },
@@ -1694,6 +1711,11 @@ static bool hid_ignore(struct hid_device *hdev)
 				hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST)
 			return true;
 		break;
+	case USB_VENDOR_ID_SOUNDGRAPH:
+		if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST &&
+		    hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
+			return true;
+		break;
 	}
 
 	if (hdev->type == HID_TYPE_USBMOUSE &&
@@ -1725,6 +1747,8 @@ int hid_add_device(struct hid_device *hdev)
 	if (!ret)
 		hdev->status |= HID_STAT_ADDED;
 
+	hid_debug_register(hdev, dev_name(&hdev->dev));
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(hid_add_device);
@@ -1761,6 +1785,9 @@ struct hid_device *hid_allocate_device(void)
 	for (i = 0; i < HID_REPORT_TYPES; i++)
 		INIT_LIST_HEAD(&hdev->report_enum[i].report_list);
 
+	init_waitqueue_head(&hdev->debug_wait);
+	INIT_LIST_HEAD(&hdev->debug_list);
+
 	return hdev;
 err:
 	put_device(&hdev->dev);
@@ -1772,6 +1799,7 @@ static void hid_remove_device(struct hid_device *hdev)
 {
 	if (hdev->status & HID_STAT_ADDED) {
 		device_del(&hdev->dev);
+		hid_debug_unregister(hdev);
 		hdev->status &= ~HID_STAT_ADDED;
 	}
 }
@@ -1847,6 +1875,10 @@ static int __init hid_init(void)
 {
 	int ret;
 
+	if (hid_debug)
+		printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n"
+				"HID: debugfs is now used for inspecting the device (report descriptor, reports)\n");
+
 	ret = bus_register(&hid_bus_type);
 	if (ret) {
 		printk(KERN_ERR "HID: can't register hid bus\n");
@@ -1857,6 +1889,8 @@ static int __init hid_init(void)
 	if (ret)
 		goto err_bus;
 
+	hid_debug_init();
+
 	return 0;
 err_bus:
 	bus_unregister(&hid_bus_type);
@@ -1866,6 +1900,7 @@ err:
 
 static void __exit hid_exit(void)
 {
+	hid_debug_exit();
 	hidraw_exit();
 	bus_unregister(&hid_bus_type);
 }
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 9d6d3b9..62e9cb1 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -141,12 +141,12 @@ static struct hid_driver cp_driver = {
 	.probe = cp_probe,
 };
 
-static int cp_init(void)
+static int __init cp_init(void)
 {
 	return hid_register_driver(&cp_driver);
 }
 
-static void cp_exit(void)
+static void __exit cp_exit(void)
 {
 	hid_unregister_driver(&cp_driver);
 }
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 04359ed..6abd036 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -1,9 +1,9 @@
 /*
  *  (c) 1999 Andreas Gal		<gal@cs.uni-magdeburg.de>
  *  (c) 2000-2001 Vojtech Pavlik	<vojtech@ucw.cz>
- *  (c) 2007 Jiri Kosina
+ *  (c) 2007-2009 Jiri Kosina
  *
- *  Some debug stuff for the HID parser.
+ *  HID debugging support
  */
 
 /*
@@ -26,9 +26,17 @@
  * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
  */
 
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+
 #include <linux/hid.h>
 #include <linux/hid-debug.h>
 
+static struct dentry *hid_debug_root;
+
 struct hid_usage_entry {
 	unsigned  page;
 	unsigned  usage;
@@ -339,72 +347,120 @@ static const struct hid_usage_entry hid_usage_table[] = {
   { 0, 0, NULL }
 };
 
-static void resolv_usage_page(unsigned page) {
+/* Either output directly into simple seq_file, or (if f == NULL)
+ * allocate a separate buffer that will then be passed to the 'events'
+ * ringbuffer.
+ *
+ * This is because these functions can be called both for "one-shot"
+ * "rdesc" while resolving, or for blocking "events".
+ *
+ * This holds both for resolv_usage_page() and hid_resolv_usage().
+ */
+static char *resolv_usage_page(unsigned page, struct seq_file *f) {
 	const struct hid_usage_entry *p;
+	char *buf = NULL;
+
+	if (!f) {
+		buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
+		if (!buf)
+			return ERR_PTR(-ENOMEM);
+	}
 
 	for (p = hid_usage_table; p->description; p++)
 		if (p->page == page) {
-			printk("%s", p->description);
-			return;
+			if (!f) {
+				snprintf(buf, HID_DEBUG_BUFSIZE, "%s",
+						p->description);
+				return buf;
+			}
+			else {
+				seq_printf(f, "%s", p->description);
+				return NULL;
+			}
 		}
-	printk("%04x", page);
+	if (!f)
+		snprintf(buf, HID_DEBUG_BUFSIZE, "%04x", page);
+	else
+		seq_printf(f, "%04x", page);
+	return buf;
 }
 
-void hid_resolv_usage(unsigned usage) {
+char *hid_resolv_usage(unsigned usage, struct seq_file *f) {
 	const struct hid_usage_entry *p;
+	char *buf = NULL;
+	int len = 0;
+
+	buf = resolv_usage_page(usage >> 16, f);
+	if (IS_ERR(buf)) {
+		printk(KERN_ERR "error allocating HID debug buffer\n");
+		return NULL;
+	}
 
-	if (!hid_debug)
-		return;
 
-	resolv_usage_page(usage >> 16);
-	printk(".");
+	if (!f) {
+		len = strlen(buf);
+		snprintf(buf+len, max(0, HID_DEBUG_BUFSIZE - len), ".");
+		len++;
+	}
+	else {
+		seq_printf(f, ".");
+	}
 	for (p = hid_usage_table; p->description; p++)
 		if (p->page == (usage >> 16)) {
 			for(++p; p->description && p->usage != 0; p++)
 				if (p->usage == (usage & 0xffff)) {
-					printk("%s", p->description);
-					return;
+					if (!f)
+						snprintf(buf + len,
+							max(0,HID_DEBUG_BUFSIZE - len - 1),
+							"%s", p->description);
+					else
+						seq_printf(f,
+							"%s",
+							p->description);
+					return buf;
 				}
 			break;
 		}
-	printk("%04x", usage & 0xffff);
+	if (!f)
+		snprintf(buf + len, max(0, HID_DEBUG_BUFSIZE - len - 1),
+				"%04x", usage & 0xffff);
+	else
+		seq_printf(f, "%04x", usage & 0xffff);
+	return buf;
 }
 EXPORT_SYMBOL_GPL(hid_resolv_usage);
 
-static void tab(int n) {
-	printk(KERN_DEBUG "%*s", n, "");
+static void tab(int n, struct seq_file *f) {
+	seq_printf(f, "%*s", n, "");
 }
 
-void hid_dump_field(struct hid_field *field, int n) {
+void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
 	int j;
 
-	if (!hid_debug)
-		return;
-
 	if (field->physical) {
-		tab(n);
-		printk("Physical(");
-		hid_resolv_usage(field->physical); printk(")\n");
+		tab(n, f);
+		seq_printf(f, "Physical(");
+		hid_resolv_usage(field->physical, f); seq_printf(f, ")\n");
 	}
 	if (field->logical) {
-		tab(n);
-		printk("Logical(");
-		hid_resolv_usage(field->logical); printk(")\n");
+		tab(n, f);
+		seq_printf(f, "Logical(");
+		hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
 	}
-	tab(n); printk("Usage(%d)\n", field->maxusage);
+	tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
 	for (j = 0; j < field->maxusage; j++) {
-		tab(n+2); hid_resolv_usage(field->usage[j].hid); printk("\n");
+		tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
 	}
 	if (field->logical_minimum != field->logical_maximum) {
-		tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum);
-		tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum);
+		tab(n, f); seq_printf(f, "Logical Minimum(%d)\n", field->logical_minimum);
+		tab(n, f); seq_printf(f, "Logical Maximum(%d)\n", field->logical_maximum);
 	}
 	if (field->physical_minimum != field->physical_maximum) {
-		tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum);
-		tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum);
+		tab(n, f); seq_printf(f, "Physical Minimum(%d)\n", field->physical_minimum);
+		tab(n, f); seq_printf(f, "Physical Maximum(%d)\n", field->physical_maximum);
 	}
 	if (field->unit_exponent) {
-		tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent);
+		tab(n, f); seq_printf(f, "Unit Exponent(%d)\n", field->unit_exponent);
 	}
 	if (field->unit) {
 		static const char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" };
@@ -425,77 +481,75 @@ void hid_dump_field(struct hid_field *field, int n) {
 		data >>= 4;
 
 		if(sys > 4) {
-			tab(n); printk("Unit(Invalid)\n");
+			tab(n, f); seq_printf(f, "Unit(Invalid)\n");
 		}
 		else {
 			int earlier_unit = 0;
 
-			tab(n); printk("Unit(%s : ", systems[sys]);
+			tab(n, f); seq_printf(f, "Unit(%s : ", systems[sys]);
 
 			for (i=1 ; i<sizeof(__u32)*2 ; i++) {
 				char nibble = data & 0xf;
 				data >>= 4;
 				if (nibble != 0) {
 					if(earlier_unit++ > 0)
-						printk("*");
-					printk("%s", units[sys][i]);
+						seq_printf(f, "*");
+					seq_printf(f, "%s", units[sys][i]);
 					if(nibble != 1) {
 						/* This is a _signed_ nibble(!) */
 
 						int val = nibble & 0x7;
 						if(nibble & 0x08)
 							val = -((0x7 & ~val) +1);
-						printk("^%d", val);
+						seq_printf(f, "^%d", val);
 					}
 				}
 			}
-			printk(")\n");
+			seq_printf(f, ")\n");
 		}
 	}
-	tab(n); printk("Report Size(%u)\n", field->report_size);
-	tab(n); printk("Report Count(%u)\n", field->report_count);
-	tab(n); printk("Report Offset(%u)\n", field->report_offset);
+	tab(n, f); seq_printf(f, "Report Size(%u)\n", field->report_size);
+	tab(n, f); seq_printf(f, "Report Count(%u)\n", field->report_count);
+	tab(n, f); seq_printf(f, "Report Offset(%u)\n", field->report_offset);
 
-	tab(n); printk("Flags( ");
+	tab(n, f); seq_printf(f, "Flags( ");
 	j = field->flags;
-	printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
-	printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
-	printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
-	printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
-	printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
-	printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
-	printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
-	printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
-	printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
-	printk(")\n");
+	seq_printf(f, "%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : "");
+	seq_printf(f, "%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array ");
+	seq_printf(f, "%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute ");
+	seq_printf(f, "%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : "");
+	seq_printf(f, "%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : "");
+	seq_printf(f, "%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPreferredState " : "");
+	seq_printf(f, "%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : "");
+	seq_printf(f, "%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : "");
+	seq_printf(f, "%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : "");
+	seq_printf(f, ")\n");
 }
 EXPORT_SYMBOL_GPL(hid_dump_field);
 
-void hid_dump_device(struct hid_device *device) {
+void hid_dump_device(struct hid_device *device, struct seq_file *f)
+{
 	struct hid_report_enum *report_enum;
 	struct hid_report *report;
 	struct list_head *list;
 	unsigned i,k;
 	static const char *table[] = {"INPUT", "OUTPUT", "FEATURE"};
 
-	if (!hid_debug)
-		return;
-
 	for (i = 0; i < HID_REPORT_TYPES; i++) {
 		report_enum = device->report_enum + i;
 		list = report_enum->report_list.next;
 		while (list != &report_enum->report_list) {
 			report = (struct hid_report *) list;
-			tab(2);
-			printk("%s", table[i]);
+			tab(2, f);
+			seq_printf(f, "%s", table[i]);
 			if (report->id)
-				printk("(%d)", report->id);
-			printk("[%s]", table[report->type]);
-			printk("\n");
+				seq_printf(f, "(%d)", report->id);
+			seq_printf(f, "[%s]", table[report->type]);
+			seq_printf(f, "\n");
 			for (k = 0; k < report->maxfield; k++) {
-				tab(4);
-				printk("Field(%d)\n", k);
-				hid_dump_field(report->field[k], 6);
+				tab(4, f);
+				seq_printf(f, "Field(%d)\n", k);
+				hid_dump_field(report->field[k], 6, f);
 			}
 			list = list->next;
 		}
@@ -503,13 +557,37 @@ void hid_dump_device(struct hid_device *device) {
 }
 EXPORT_SYMBOL_GPL(hid_dump_device);
 
-void hid_dump_input(struct hid_usage *usage, __s32 value) {
-	if (hid_debug < 2)
+/* enqueue string to 'events' ring buffer */
+void hid_debug_event(struct hid_device *hdev, char *buf)
+{
+	int i;
+	struct hid_debug_list *list;
+
+	list_for_each_entry(list, &hdev->debug_list, node) {
+		for (i = 0; i <= strlen(buf); i++)
+			list->hid_debug_buf[(list->tail + i) % (HID_DEBUG_BUFSIZE - 1)] =
+				buf[i];
+		list->tail = (list->tail + i) % (HID_DEBUG_BUFSIZE - 1);
+        }
+}
+EXPORT_SYMBOL_GPL(hid_debug_event);
+
+void hid_dump_input(struct hid_device *hdev, struct hid_usage *usage, __s32 value)
+{
+	char *buf;
+	int len;
+
+	buf = hid_resolv_usage(usage->hid, NULL);
+	if (!buf)
 		return;
+	len = strlen(buf);
+	snprintf(buf + len, HID_DEBUG_BUFSIZE - len - 1, " = %d\n", value);
+
+	hid_debug_event(hdev, buf);
+
+	kfree(buf);
+        wake_up_interruptible(&hdev->debug_wait);
 
-	printk(KERN_DEBUG "hid-debug: input ");
-	hid_resolv_usage(usage->hid);
-	printk(" = %d\n", value);
 }
 EXPORT_SYMBOL_GPL(hid_dump_input);
 
@@ -786,12 +864,221 @@ static const char **names[EV_MAX + 1] = {
 	[EV_SND] = sounds,			[EV_REP] = repeats,
 };
 
-void hid_resolv_event(__u8 type, __u16 code) {
+void hid_resolv_event(__u8 type, __u16 code, struct seq_file *f) {
 
-	if (!hid_debug)
-		return;
-
-	printk("%s.%s", events[type] ? events[type] : "?",
+	seq_printf(f, "%s.%s", events[type] ? events[type] : "?",
 		names[type] ? (names[type][code] ? names[type][code] : "?") : "?");
 }
-EXPORT_SYMBOL_GPL(hid_resolv_event);
+
+void hid_dump_input_mapping(struct hid_device *hid, struct seq_file *f)
+{
+	int i, j, k;
+	struct hid_report *report;
+	struct hid_usage *usage;
+
+	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+		list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
+			for (i = 0; i < report->maxfield; i++) {
+				for ( j = 0; j < report->field[i]->maxusage; j++) {
+					usage = report->field[i]->usage + j;
+					hid_resolv_usage(usage->hid, f);
+					seq_printf(f, " ---> ");
+					hid_resolv_event(usage->type, usage->code, f);
+					seq_printf(f, "\n");
+				}
+			}
+		}
+	}
+
+}
+
+
+static int hid_debug_rdesc_show(struct seq_file *f, void *p)
+{
+	struct hid_device *hdev = f->private;
+	int i;
+
+	/* dump HID report descriptor */
+	for (i = 0; i < hdev->rsize; i++)
+		seq_printf(f, "%02x ", hdev->rdesc[i]);
+	seq_printf(f, "\n\n");
+
+	/* dump parsed data and input mappings */
+	hid_dump_device(hdev, f);
+	seq_printf(f, "\n");
+	hid_dump_input_mapping(hdev, f);
+
+	return 0;
+}
+
+static int hid_debug_rdesc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, hid_debug_rdesc_show, inode->i_private);
+}
+
+static int hid_debug_events_open(struct inode *inode, struct file *file)
+{
+	int err = 0;
+	struct hid_debug_list *list;
+
+	if (!(list = kzalloc(sizeof(struct hid_debug_list), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	if (!(list->hid_debug_buf = kzalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_KERNEL))) {
+		err = -ENOMEM;
+		kfree(list);
+		goto out;
+	}
+	list->hdev = (struct hid_device *) inode->i_private;
+	file->private_data = list;
+	mutex_init(&list->read_mutex);
+
+	list_add_tail(&list->node, &list->hdev->debug_list);
+
+out:
+	return err;
+}
+
+static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
+		size_t count, loff_t *ppos)
+{
+	struct hid_debug_list *list = file->private_data;
+	int ret = 0, len;
+	DECLARE_WAITQUEUE(wait, current);
+
+	while (ret == 0) {
+		mutex_lock(&list->read_mutex);
+		if (list->head == list->tail) {
+			add_wait_queue(&list->hdev->debug_wait, &wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+
+			while (list->head == list->tail) {
+				if (file->f_flags & O_NONBLOCK) {
+					ret = -EAGAIN;
+					break;
+				}
+				if (signal_pending(current)) {
+					ret = -ERESTARTSYS;
+					break;
+				}
+
+				if (!list->hdev || !list->hdev->debug) {
+					ret = -EIO;
+					break;
+				}
+
+				/* allow O_NONBLOCK from other threads */
+				mutex_unlock(&list->read_mutex);
+				schedule();
+				mutex_lock(&list->read_mutex);
+				set_current_state(TASK_INTERRUPTIBLE);
+			}
+
+			set_current_state(TASK_RUNNING);
+			remove_wait_queue(&list->hdev->debug_wait, &wait);
+		}
+
+		if (ret)
+			goto out;
+
+		/* pass the ringbuffer contents to userspace */
+copy_rest:
+		if (list->tail == list->head)
+			goto out;
+		if (list->tail > list->head) {
+			len = list->tail - list->head;
+
+			if (copy_to_user(buffer + ret, &list->hid_debug_buf[list->head], len)) {
+				ret = -EFAULT;
+				goto out;
+			}
+			ret += len;
+			list->head += len;
+		} else {
+			len = HID_DEBUG_BUFSIZE - list->head;
+
+			if (copy_to_user(buffer, &list->hid_debug_buf[list->head], len)) {
+				ret = -EFAULT;
+				goto out;
+			}
+			list->head = 0;
+			ret += len;
+			goto copy_rest;
+		}
+
+	}
+out:
+	mutex_unlock(&list->read_mutex);
+	return ret;
+}
+
+static unsigned int hid_debug_events_poll(struct file *file, poll_table *wait)
+{
+	struct hid_debug_list *list = file->private_data;
+
+	poll_wait(file, &list->hdev->debug_wait, wait);
+	if (list->head != list->tail)
+		return POLLIN | POLLRDNORM;
+	if (!list->hdev->debug)
+		return POLLERR | POLLHUP;
+	return 0;
+}
+
+static int hid_debug_events_release(struct inode *inode, struct file *file)
+{
+	struct hid_debug_list *list = file->private_data;
+
+	list_del(&list->node);
+	kfree(list->hid_debug_buf);
+	kfree(list);
+
+	return 0;
+}
+
+static const struct file_operations hid_debug_rdesc_fops = {
+	.open           = hid_debug_rdesc_open,
+	.read           = seq_read,
+	.llseek         = seq_lseek,
+	.release        = single_release,
+};
+
+static const struct file_operations hid_debug_events_fops = {
+	.owner =        THIS_MODULE,
+	.open           = hid_debug_events_open,
+	.read           = hid_debug_events_read,
+	.poll		= hid_debug_events_poll,
+	.release        = hid_debug_events_release,
+};
+
+
+void hid_debug_register(struct hid_device *hdev, const char *name)
+{
+	hdev->debug_dir = debugfs_create_dir(name, hid_debug_root);
+	hdev->debug_rdesc = debugfs_create_file("rdesc", 0400,
+			hdev->debug_dir, hdev, &hid_debug_rdesc_fops);
+	hdev->debug_events = debugfs_create_file("events", 0400,
+			hdev->debug_dir, hdev, &hid_debug_events_fops);
+	hdev->debug = 1;
+}
+
+void hid_debug_unregister(struct hid_device *hdev)
+{
+	hdev->debug = 0;
+	wake_up_interruptible(&hdev->debug_wait);
+	debugfs_remove(hdev->debug_rdesc);
+	debugfs_remove(hdev->debug_events);
+	debugfs_remove(hdev->debug_dir);
+}
+
+void hid_debug_init(void)
+{
+	hid_debug_root = debugfs_create_dir("hid", NULL);
+}
+
+void hid_debug_exit(void)
+{
+	debugfs_remove_recursive(hid_debug_root);
+}
+
diff --git a/drivers/hid/hid-ezkey.c b/drivers/hid/hid-ezkey.c
index 0a1fe05..ca1163e 100644
--- a/drivers/hid/hid-ezkey.c
+++ b/drivers/hid/hid-ezkey.c
@@ -78,12 +78,12 @@ static struct hid_driver ez_driver = {
 	.event = ez_event,
 };
 
-static int ez_init(void)
+static int __init ez_init(void)
 {
 	return hid_register_driver(&ez_driver);
 }
 
-static void ez_exit(void)
+static void __exit ez_exit(void)
 {
 	hid_unregister_driver(&ez_driver);
 }
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index d42d222..cab13e8 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -81,12 +81,12 @@ static struct hid_driver gyration_driver = {
 	.event = gyration_event,
 };
 
-static int gyration_init(void)
+static int __init gyration_init(void)
 {
 	return hid_register_driver(&gyration_driver);
 }
 
-static void gyration_exit(void)
+static void __exit gyration_exit(void)
 {
 	hid_unregister_driver(&gyration_driver);
 }
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 6301010..adbef5d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -296,6 +296,7 @@
 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D	0xc283
 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO	0xc286
 #define USB_DEVICE_ID_LOGITECH_WHEEL	0xc294
+#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG	0xc293
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL	0xc295
 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL	0xc299
 #define USB_DEVICE_ID_LOGITECH_ELITE_KBD	0xc30a
@@ -359,6 +360,9 @@
 #define USB_VENDOR_ID_PETALYNX		0x18b1
 #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE	0x0037
 
+#define USB_VENDOR_ID_PHILIPS       0x0471
+#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
+
 #define USB_VENDOR_ID_PLAYDOTCOM	0x0b43
 #define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII	0x0003
 
@@ -376,11 +380,8 @@
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER	0x0268
 
 #define USB_VENDOR_ID_SOUNDGRAPH	0x15c2
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD	0x0038
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2	0x0036
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3	0x0034
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD4	0x0044
-#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD5	0x0045
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST	0x0034
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST	0x0046
 
 #define USB_VENDOR_ID_SUN		0x0430
 #define USB_DEVICE_ID_RARITAN_KVM_DONGLE	0xcdab
@@ -403,6 +404,9 @@
 #define USB_VENDOR_ID_TURBOX		0x062a
 #define USB_DEVICE_ID_TURBOX_KEYBOARD	0x0201
 
+#define USB_VENDOR_ID_TWINHAN           0x6253
+#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
+
 #define USB_VENDOR_ID_UCLOGIC		0x5543
 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209	0x0042
 
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7f183b7..5862b0f 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -159,17 +159,12 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 
 	field->hidinput = hidinput;
 
-	dbg_hid("Mapping: ");
-	hid_resolv_usage(usage->hid);
-	dbg_hid_line(" ---> ");
-
 	if (field->flags & HID_MAIN_ITEM_CONSTANT)
 		goto ignore;
 
 	/* only LED usages are supported in output fields */
 	if (field->report_type == HID_OUTPUT_REPORT &&
 			(usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
-		dbg_hid_line(" [non-LED output field] ");
 		goto ignore;
 	}
 
@@ -561,15 +556,9 @@ mapped:
 		set_bit(MSC_SCAN, input->mscbit);
 	}
 
-	hid_resolv_event(usage->type, usage->code);
-
-	dbg_hid_line("\n");
-
-	return;
-
 ignore:
-	dbg_hid_line("IGNORED\n");
 	return;
+
 }
 
 void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
diff --git a/drivers/hid/hid-kensington.c b/drivers/hid/hid-kensington.c
index 7353bd7..a5b4016 100644
--- a/drivers/hid/hid-kensington.c
+++ b/drivers/hid/hid-kensington.c
@@ -48,12 +48,12 @@ static struct hid_driver ks_driver = {
 	.input_mapping = ks_input_mapping,
 };
 
-static int ks_init(void)
+static int __init ks_init(void)
 {
 	return hid_register_driver(&ks_driver);
 }
 
-static void ks_exit(void)
+static void __exit ks_exit(void)
 {
 	hid_unregister_driver(&ks_driver);
 }
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
index 72ee3fe..f887171 100644
--- a/drivers/hid/hid-kye.c
+++ b/drivers/hid/hid-kye.c
@@ -54,12 +54,12 @@ static struct hid_driver kye_driver = {
 	.report_fixup = kye_report_fixup,
 };
 
-static int kye_init(void)
+static int __init kye_init(void)
 {
 	return hid_register_driver(&kye_driver);
 }
 
-static void kye_exit(void)
+static void __exit kye_exit(void)
 {
 	hid_unregister_driver(&kye_driver);
 }
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 7afbaa0..0f870a3 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -299,6 +299,8 @@ static const struct hid_device_id lg_devices[] = {
 		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
 		.driver_data = LG_FF },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
+		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
 		.driver_data = LG_FF2 },
 	{ }
@@ -315,12 +317,12 @@ static struct hid_driver lg_driver = {
 	.probe = lg_probe,
 };
 
-static int lg_init(void)
+static int __init lg_init(void)
 {
 	return hid_register_driver(&lg_driver);
 }
 
-static void lg_exit(void)
+static void __exit lg_exit(void)
 {
 	hid_unregister_driver(&lg_driver);
 }
diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
index 5609970..987abeb 100644
--- a/drivers/hid/hid-lgff.c
+++ b/drivers/hid/hid-lgff.c
@@ -67,6 +67,7 @@ static const struct dev_type devices[] = {
 	{ 0x046d, 0xc219, ff_rumble },
 	{ 0x046d, 0xc283, ff_joystick },
 	{ 0x046d, 0xc286, ff_joystick_ac },
+	{ 0x046d, 0xc293, ff_joystick },
 	{ 0x046d, 0xc294, ff_wheel },
 	{ 0x046d, 0xc295, ff_joystick },
 	{ 0x046d, 0xca03, ff_wheel },
@@ -150,11 +151,6 @@ int lgff_init(struct hid_device* hid)
 
 	/* Check that the report looks ok */
 	report = list_entry(report_list->next, struct hid_report, list);
-	if (!report) {
-		err_hid("NULL output report");
-		return -1;
-	}
-
 	field = report->field[0];
 	if (!field) {
 		err_hid("NULL field");
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 5e9e37a..359cc44 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -197,12 +197,12 @@ static struct hid_driver ms_driver = {
 	.probe = ms_probe,
 };
 
-static int ms_init(void)
+static int __init ms_init(void)
 {
 	return hid_register_driver(&ms_driver);
 }
 
-static void ms_exit(void)
+static void __exit ms_exit(void)
 {
 	hid_unregister_driver(&ms_driver);
 }
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index 240f876..2cd05aa 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -65,12 +65,12 @@ static struct hid_driver mr_driver = {
 	.input_mapping = mr_input_mapping,
 };
 
-static int mr_init(void)
+static int __init mr_init(void)
 {
 	return hid_register_driver(&mr_driver);
 }
 
-static void mr_exit(void)
+static void __exit mr_exit(void)
 {
 	hid_unregister_driver(&mr_driver);
 }
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index 75ed9d2..49ce69d 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -27,6 +27,9 @@
 struct ntrig_data {
 	__s32 x, y, id, w, h;
 	char reading_a_point, found_contact_id;
+	char pen_active;
+	char finger_active;
+	char inverted;
 };
 
 /*
@@ -63,10 +66,7 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 	case HID_UP_DIGITIZER:
 		switch (usage->hid) {
 		/* we do not want to map these for now */
-		case HID_DG_INVERT: /* value is always 0 */
-		case HID_DG_ERASER: /* value is always 0 */
 		case HID_DG_CONTACTID: /* value is useless */
-		case HID_DG_BARRELSWITCH:  /* doubtful */
 		case HID_DG_INPUTMODE:
 		case HID_DG_DEVICEINDEX:
 		case HID_DG_CONTACTCOUNT:
@@ -125,6 +125,18 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 
         if (hid->claimed & HID_CLAIMED_INPUT) {
 		switch (usage->hid) {
+
+		case HID_DG_INRANGE:
+			if (field->application & 0x3)
+				nd->pen_active = (value != 0);
+			else
+				nd->finger_active = (value != 0);
+			return 0;
+
+		case HID_DG_INVERT:
+			nd->inverted = value;
+			return 0;
+
 		case HID_GD_X:
 			nd->x = value;
 			nd->reading_a_point = 1;
@@ -147,7 +159,11 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 			 * report received in a finger event. We want
 			 * to emit a normal (X, Y) position
 			 */
-			if (! nd->found_contact_id) {
+			if (!nd->found_contact_id) {
+				if (nd->pen_active && nd->finger_active) {
+					input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
+					input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
+				}
 				input_event(input, EV_ABS, ABS_X, nd->x);
 				input_event(input, EV_ABS, ABS_Y, nd->y);
 			}
@@ -159,6 +175,14 @@ static int ntrig_event (struct hid_device *hid, struct hid_field *field,
 			 * to emit a normal (X, Y) position
 			 */
 			if (! nd->found_contact_id) {
+				if (nd->pen_active && nd->finger_active) {
+					input_report_key(input,
+							nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
+							, 0);
+					input_report_key(input,
+							nd->inverted ? BTN_TOOL_RUBBER : BTN_TOOL_PEN
+							, 1);
+				}
 				input_event(input, EV_ABS, ABS_X, nd->x);
 				input_event(input, EV_ABS, ABS_Y, nd->y);
 				input_event(input, EV_ABS, ABS_PRESSURE, value);
@@ -233,6 +257,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 	if (ret)
 		kfree (nd);
+
 	return ret;
 }
 
@@ -265,12 +290,12 @@ static struct hid_driver ntrig_driver = {
 	.event = ntrig_event,
 };
 
-static int ntrig_init(void)
+static int __init ntrig_init(void)
 {
 	return hid_register_driver(&ntrig_driver);
 }
 
-static void ntrig_exit(void)
+static void __exit ntrig_exit(void)
 {
 	hid_unregister_driver(&ntrig_driver);
 }
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 2e83e8f..500fbd0 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -105,12 +105,12 @@ static struct hid_driver pl_driver = {
 	.probe = pl_probe,
 };
 
-static int pl_init(void)
+static int __init pl_init(void)
 {
 	return hid_register_driver(&pl_driver);
 }
 
-static void pl_exit(void)
+static void __exit pl_exit(void)
 {
 	hid_unregister_driver(&pl_driver);
 }
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index 4db9a34..c6d7dbc 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -217,12 +217,12 @@ static struct hid_driver pl_driver = {
 	.probe = pl_probe,
 };
 
-static int pl_init(void)
+static int __init pl_init(void)
 {
 	return hid_register_driver(&pl_driver);
 }
 
-static void pl_exit(void)
+static void __exit pl_exit(void)
 {
 	hid_unregister_driver(&pl_driver);
 }
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 07083aa..5b222ee 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -25,25 +25,48 @@
 /*
  * Samsung IrDA remote controller (reports as Cypress USB Mouse).
  *
+ * There are several variants for 0419:0001:
+ *
+ * 1. 184 byte report descriptor
  * Vendor specific report #4 has a size of 48 bit,
  * and therefore is not accepted when inspecting the descriptors.
  * As a workaround we reinterpret the report as:
  *   Variable type, count 6, size 8 bit, log. maximum 255
  * The burden to reconstruct the data is moved into user space.
+ *
+ * 2. 203 byte report descriptor
+ * Report #4 has an array field with logical range 0..18 instead of 1..15.
+ *
+ * 3. 135 byte report descriptor
+ * Report #4 has an array field with logical range 0..17 instead of 1..14.
  */
 static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int rsize)
 {
-	if (rsize >= 182 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
+	if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
 			rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
 			rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
 			rdesc[182] == 0x40) {
-		dev_info(&hdev->dev, "fixing up Samsung IrDA report "
-				"descriptor\n");
+		dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
+				"descriptor\n", 184);
 		rdesc[176] = 0xff;
 		rdesc[178] = 0x08;
 		rdesc[180] = 0x06;
 		rdesc[182] = 0x42;
+	} else
+	if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
+			rdesc[194] == 0x25 && rdesc[195] == 0x12) {
+		dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
+				"descriptor\n", 203);
+		rdesc[193] = 0x1;
+		rdesc[195] = 0xf;
+	} else
+	if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
+			rdesc[126] == 0x25 && rdesc[127] == 0x11) {
+		dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report "
+				"descriptor\n", 135);
+		rdesc[125] = 0x1;
+		rdesc[127] = 0xe;
 	}
 }
 
@@ -51,6 +74,7 @@ static int samsung_probe(struct hid_device *hdev,
 		const struct hid_device_id *id)
 {
 	int ret;
+	unsigned int cmask = HID_CONNECT_DEFAULT;
 
 	ret = hid_parse(hdev);
 	if (ret) {
@@ -58,8 +82,13 @@ static int samsung_probe(struct hid_device *hdev,
 		goto err_free;
 	}
 
-	ret = hid_hw_start(hdev, (HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDINPUT) |
-			HID_CONNECT_HIDDEV_FORCE);
+	if (hdev->rsize == 184) {
+		/* disable hidinput, force hiddev */
+		cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
+			HID_CONNECT_HIDDEV_FORCE;
+	}
+
+	ret = hid_hw_start(hdev, cmask);
 	if (ret) {
 		dev_err(&hdev->dev, "hw start failed\n");
 		goto err_free;
@@ -83,12 +112,12 @@ static struct hid_driver samsung_driver = {
 	.probe = samsung_probe,
 };
 
-static int samsung_init(void)
+static int __init samsung_init(void)
 {
 	return hid_register_driver(&samsung_driver);
 }
 
-static void samsung_exit(void)
+static void __exit samsung_exit(void)
 {
 	hid_unregister_driver(&samsung_driver);
 }
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
index eab169e..203c438 100644
--- a/drivers/hid/hid-sjoy.c
+++ b/drivers/hid/hid-sjoy.c
@@ -163,12 +163,12 @@ static struct hid_driver sjoy_driver = {
 	.probe = sjoy_probe,
 };
 
-static int sjoy_init(void)
+static int __init sjoy_init(void)
 {
 	return hid_register_driver(&sjoy_driver);
 }
 
-static void sjoy_exit(void)
+static void __exit sjoy_exit(void)
 {
 	hid_unregister_driver(&sjoy_driver);
 }
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index c259938..4e84502 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -135,12 +135,12 @@ static struct hid_driver sony_driver = {
 	.report_fixup = sony_report_fixup,
 };
 
-static int sony_init(void)
+static int __init sony_init(void)
 {
 	return hid_register_driver(&sony_driver);
 }
 
-static void sony_exit(void)
+static void __exit sony_exit(void)
 {
 	hid_unregister_driver(&sony_driver);
 }
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index e0a8fd3..438107d 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -65,12 +65,12 @@ static struct hid_driver sp_driver = {
 	.input_mapping = sp_input_mapping,
 };
 
-static int sp_init(void)
+static int __init sp_init(void)
 {
 	return hid_register_driver(&sp_driver);
 }
 
-static void sp_exit(void)
+static void __exit sp_exit(void)
 {
 	hid_unregister_driver(&sp_driver);
 }
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index fcd6ccd..167ea74 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -243,7 +243,11 @@ err:
 static const struct hid_device_id tm_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300),
 		.driver_data = (unsigned long)ff_rumble },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304),
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304),   /* FireStorm Dual Power 2 (and 3) */
+		.driver_data = (unsigned long)ff_rumble },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323),   /* Dual Trigger 3-in-1 (PC Mode) */
+		.driver_data = (unsigned long)ff_rumble },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324),   /* Dual Trigger 3-in-1 (PS3 Mode) */
 		.driver_data = (unsigned long)ff_rumble },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651),	/* FGT Rumble Force Wheel */
 		.driver_data = (unsigned long)ff_rumble },
@@ -259,12 +263,12 @@ static struct hid_driver tm_driver = {
 	.probe = tm_probe,
 };
 
-static int tm_init(void)
+static int __init tm_init(void)
 {
 	return hid_register_driver(&tm_driver);
 }
 
-static void tm_exit(void)
+static void __exit tm_exit(void)
 {
 	hid_unregister_driver(&tm_driver);
 }
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index 152ccfa..6925eda 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -60,12 +60,12 @@ static struct hid_driver ts_driver = {
 	.input_mapping = ts_input_mapping,
 };
 
-static int ts_init(void)
+static int __init ts_init(void)
 {
 	return hid_register_driver(&ts_driver);
 }
 
-static void ts_exit(void)
+static void __exit ts_exit(void)
 {
 	hid_unregister_driver(&ts_driver);
 }
diff --git a/drivers/hid/hid-twinhan.c b/drivers/hid/hid-twinhan.c
new file mode 100644
index 0000000..b05f602
--- /dev/null
+++ b/drivers/hid/hid-twinhan.c
@@ -0,0 +1,147 @@
+/*
+ * HID driver for TwinHan IR remote control
+ *
+ * Based on hid-gyration.c
+ *
+ * Copyright (c) 2009 Bruno Prémont <bonbons@linux-vserver.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.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/*	Remote control key layout + listing:
+ *
+ * 	Full Screen                              Power
+ *	KEY_SCREEN                          KEY_POWER2
+ *
+ *	1                     2                      3
+ *	KEY_NUMERIC_1   KEY_NUMERIC_2    KEY_NUMERIC_3
+ *
+ *	4                     5                      6
+ *	KEY_NUMERIC_4   KEY_NUMERIC_5    KEY_NUMERIC_6
+ *
+ *	7                     8                      9
+ *	KEY_NUMERIC_7   KEY_NUMERIC_8    KEY_NUMERIC_9
+ *
+ *	REC                   0               Favorite
+ *	KEY_RECORD      KEY_NUMERIC_0    KEY_FAVORITES
+ *
+ *	Rewind                                 Forward
+ *	KEY_REWIND           CH+           KEY_FORWARD
+ *	               KEY_CHANNELUP
+ *
+ *	VOL-                  >                   VOL+
+ *	KEY_VOLUMEDOWN    KEY_PLAY        KEY_VOLUMEUP
+ *
+ *	                     CH-
+ *	              KEY_CHANNELDOWN
+ *	Recall                                    Stop
+ *	KEY_RESTART                           KEY_STOP
+ *
+ *	Timeshift/Pause     Mute                Cancel
+ *	KEY_PAUSE         KEY_MUTE          KEY_CANCEL
+ *
+ *	Capture            Preview                 EPG
+ *	KEY_PRINT        KEY_PROGRAM           KEY_EPG
+ *
+ *	Record List          Tab              Teletext
+ *	KEY_LIST            KEY_TAB           KEY_TEXT
+ */
+
+#define th_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
+					EV_KEY, (c))
+static int twinhan_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_KEYBOARD)
+		return 0;
+
+	switch (usage->hid & HID_USAGE) {
+	/* Map all keys from Twinhan Remote */
+	case 0x004: th_map_key_clear(KEY_TEXT);         break;
+	case 0x006: th_map_key_clear(KEY_RESTART);      break;
+	case 0x008: th_map_key_clear(KEY_EPG);          break;
+	case 0x00c: th_map_key_clear(KEY_REWIND);       break;
+	case 0x00e: th_map_key_clear(KEY_PROGRAM);      break;
+	case 0x00f: th_map_key_clear(KEY_LIST);         break;
+	case 0x010: th_map_key_clear(KEY_MUTE);         break;
+	case 0x011: th_map_key_clear(KEY_FORWARD);      break;
+	case 0x013: th_map_key_clear(KEY_PRINT);        break;
+	case 0x017: th_map_key_clear(KEY_PAUSE);        break;
+	case 0x019: th_map_key_clear(KEY_FAVORITES);    break;
+	case 0x01d: th_map_key_clear(KEY_SCREEN);       break;
+	case 0x01e: th_map_key_clear(KEY_NUMERIC_1);    break;
+	case 0x01f: th_map_key_clear(KEY_NUMERIC_2);    break;
+	case 0x020: th_map_key_clear(KEY_NUMERIC_3);    break;
+	case 0x021: th_map_key_clear(KEY_NUMERIC_4);    break;
+	case 0x022: th_map_key_clear(KEY_NUMERIC_5);    break;
+	case 0x023: th_map_key_clear(KEY_NUMERIC_6);    break;
+	case 0x024: th_map_key_clear(KEY_NUMERIC_7);    break;
+	case 0x025: th_map_key_clear(KEY_NUMERIC_8);    break;
+	case 0x026: th_map_key_clear(KEY_NUMERIC_9);    break;
+	case 0x027: th_map_key_clear(KEY_NUMERIC_0);    break;
+	case 0x028: th_map_key_clear(KEY_PLAY);         break;
+	case 0x029: th_map_key_clear(KEY_CANCEL);       break;
+	case 0x02b: th_map_key_clear(KEY_TAB);          break;
+	/* Power       = 0x0e0 + 0x0e1 + 0x0e2 + 0x03f */
+	case 0x03f: th_map_key_clear(KEY_POWER2);       break;
+	case 0x04a: th_map_key_clear(KEY_RECORD);       break;
+	case 0x04b: th_map_key_clear(KEY_CHANNELUP);    break;
+	case 0x04d: th_map_key_clear(KEY_STOP);         break;
+	case 0x04e: th_map_key_clear(KEY_CHANNELDOWN);  break;
+	/* Volume down = 0x0e1 + 0x051                 */
+	case 0x051: th_map_key_clear(KEY_VOLUMEDOWN);   break;
+	/* Volume up   = 0x0e1 + 0x052                 */
+	case 0x052: th_map_key_clear(KEY_VOLUMEUP);     break;
+	/* Kill the extra keys used for multi-key "power" and "volume" keys
+	 * as well as continuously to release CTRL,ALT,META,... keys */
+	case 0x0e0:
+	case 0x0e1:
+	case 0x0e2:
+	case 0x0e3:
+	case 0x0e4:
+	case 0x0e5:
+	case 0x0e6:
+	case 0x0e7:
+	default:
+		return -1;
+	}
+	return 1;
+}
+
+static const struct hid_device_id twinhan_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, twinhan_devices);
+
+static struct hid_driver twinhan_driver = {
+	.name = "twinhan",
+	.id_table = twinhan_devices,
+	.input_mapping = twinhan_input_mapping,
+};
+
+static int twinhan_init(void)
+{
+	return hid_register_driver(&twinhan_driver);
+}
+
+static void twinhan_exit(void)
+{
+	hid_unregister_driver(&twinhan_driver);
+}
+
+module_init(twinhan_init);
+module_exit(twinhan_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index 1f9237f..7475421 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -237,7 +237,7 @@ static struct hid_driver wacom_driver = {
 	.raw_event = wacom_raw_event,
 };
 
-static int wacom_init(void)
+static int __init wacom_init(void)
 {
 	int ret;
 
@@ -248,7 +248,7 @@ static int wacom_init(void)
 	return ret;
 }
 
-static void wacom_exit(void)
+static void __exit wacom_exit(void)
 {
 	hid_unregister_driver(&wacom_driver);
 }
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index 57f7107..a79f0d7 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -152,12 +152,12 @@ static struct hid_driver zp_driver = {
 	.probe = zp_probe,
 };
 
-static int zp_init(void)
+static int __init zp_init(void)
 {
 	return hid_register_driver(&zp_driver);
 }
 
-static void zp_exit(void)
+static void __exit zp_exit(void)
 {
 	hid_unregister_driver(&zp_driver);
 }
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 3c1fcb7..1b0e07a 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -4,8 +4,8 @@
  *  Copyright (c) 1999 Andreas Gal
  *  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
+ *  Copyright (c) 2006-2009 Jiri Kosina
  */
 
 /*
@@ -489,7 +489,8 @@ static void hid_ctrl(struct urb *urb)
 	wake_up(&usbhid->wait);
 }
 
-void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report,
+				   unsigned char dir)
 {
 	int head;
 	struct usbhid_device *usbhid = hid->driver_data;
@@ -885,11 +886,6 @@ static int usbhid_parse(struct hid_device *hid)
 		goto err;
 	}
 
-	dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
-	for (n = 0; n < rsize; n++)
-		dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
-	dbg_hid_line("\n");
-
 	ret = hid_parse_report(hid, rdesc, rsize);
 	kfree(rdesc);
 	if (ret) {
@@ -986,7 +982,6 @@ static int usbhid_start(struct hid_device *hid)
 	setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
 
 	spin_lock_init(&usbhid->lock);
-	spin_lock_init(&usbhid->lock);
 
 	usbhid->intf = intf;
 	usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -1004,7 +999,6 @@ static int usbhid_start(struct hid_device *hid)
 	usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
 	usbhid_init_reports(hid);
-	hid_dump_device(hid);
 
 	set_bit(HID_STARTED, &usbhid->iofl);
 
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index d8f7423..0d9045a 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -201,7 +201,7 @@ int usbhid_quirks_init(char **quirks_param)
 	u32 quirks;
 	int n = 0, m;
 
-	for (; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) {
+	for (; n < MAX_USBHID_BOOT_QUIRKS && quirks_param[n]; n++) {
 
 		m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
 				&idVendor, &idProduct, &quirks);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 215b2ad..8b6ee24 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -44,7 +44,7 @@
 #define HIDDEV_MINOR_BASE	96
 #define HIDDEV_MINORS		16
 #endif
-#define HIDDEV_BUFFER_SIZE	64
+#define HIDDEV_BUFFER_SIZE	2048
 
 struct hiddev {
 	int exist;
@@ -852,14 +852,14 @@ static const struct file_operations hiddev_fops = {
 #endif
 };
 
-static char *hiddev_nodename(struct device *dev)
+static char *hiddev_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
 }
 
 static struct usb_class_driver hiddev_class = {
 	.name =		"hiddev%d",
-	.nodename =	hiddev_nodename,
+	.devnode =	hiddev_devnode,
 	.fops =		&hiddev_fops,
 	.minor_base =	HIDDEV_MINOR_BASE,
 };
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2d50166..ed7711d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -28,6 +28,17 @@ config HWMON_VID
 	tristate
 	default n
 
+config HWMON_DEBUG_CHIP
+	bool "Hardware Monitoring Chip debugging messages"
+	default n
+	help
+	  Say Y here if you want the I2C chip drivers to produce a bunch of
+	  debug messages to the system log.  Select this if you are having
+	  a problem with I2C support and want to see more of what is going
+	  on.
+
+comment "Native drivers"
+
 config SENSORS_ABITUGURU
 	tristate "Abit uGuru (rev 1 & 2)"
 	depends on X86 && EXPERIMENTAL
@@ -248,18 +259,6 @@ config SENSORS_ASB100
 	  This driver can also be built as a module.  If so, the module
 	  will be called asb100.
 
-config SENSORS_ATK0110
-	tristate "ASUS ATK0110 ACPI hwmon"
-	depends on X86 && ACPI && EXPERIMENTAL
-	help
-	  If you say yes here you get support for the ACPI hardware
-	  monitoring interface found in many ASUS motherboards. This
-	  driver will provide readings of fans, voltages and temperatures
-	  through the system firmware.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called asus_atk0110.
-
 config SENSORS_ATXP1
 	tristate "Attansic ATXP1 VID controller"
 	depends on I2C && EXPERIMENTAL
@@ -702,6 +701,23 @@ config SENSORS_SHT15
 	  This driver can also be built as a module.  If so, the module
 	  will be called sht15.
 
+config SENSORS_S3C
+	tristate "S3C24XX/S3C64XX Inbuilt ADC"
+	depends on ARCH_S3C2410 || ARCH_S3C64XX
+	help
+	  If you say yes here you get support for the on-board ADCs of
+	  the Samsung S3C24XX or S3C64XX series of SoC
+
+	  This driver can also be built as a module. If so, the module
+	  will be called s3c-hwmo.
+
+config SENSORS_S3C_RAW
+	bool "Include raw channel attributes in sysfs"
+	depends on SENSORS_S3C
+	help
+	  Say Y here if you want to include raw copies of all the ADC
+	  channels in sysfs.
+
 config SENSORS_SIS5595
 	tristate "Silicon Integrated Systems Corp. SiS5595"
 	depends on PCI
@@ -797,6 +813,16 @@ config SENSORS_TMP401
 	  This driver can also be built as a module.  If so, the module
 	  will be called tmp401.
 
+config SENSORS_TMP421
+	tristate "Texas Instruments TMP421 and compatible"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for Texas Instruments TMP421,
+	  TMP422 and TMP423 temperature sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tmp421.
+
 config SENSORS_VIA686A
 	tristate "VIA686A"
 	depends on PCI
@@ -920,6 +946,27 @@ config SENSORS_W83627EHF
 	  This driver can also be built as a module.  If so, the module
 	  will be called w83627ehf.
 
+config SENSORS_WM831X
+	tristate "WM831x PMICs"
+	depends on MFD_WM831X
+	help
+	  If you say yes here you get support for the hardware
+	  monitoring functionality of the Wolfson Microelectronics
+	  WM831x series of PMICs.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called wm831x-hwmon.
+
+config SENSORS_WM8350
+	tristate "Wolfson Microelectronics WM835x"
+	depends on MFD_WM8350
+	help
+	  If you say yes here you get support for the hardware
+	  monitoring features of the WM835x series of PMICs.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called wm8350-hwmon.
+
 config SENSORS_ULTRA45
 	tristate "Sun Ultra45 PIC16F747"
 	depends on SPARC64
@@ -947,34 +994,6 @@ config SENSORS_HDAPS
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of hdaps.
 
-config SENSORS_LIS3LV02D
-	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
-	depends on ACPI && INPUT
-	select INPUT_POLLDEV
-	select NEW_LEDS
-	select LEDS_CLASS
-	default n
-	help
-	  This driver provides support for the LIS3LV02Dx accelerometer. In
-	  particular, it can be found in a number of HP laptops, which have the
-	  "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
-	  systems the driver should load automatically (via ACPI). The
-	  accelerometer might also be found in other systems, connected via SPI
-	  or I2C.  The accelerometer data is readable via
-	  /sys/devices/platform/lis3lv02d.
-
-	  This driver also provides an absolute input class device, allowing
-	  the laptop to act as a pinball machine-esque joystick. On HP laptops,
-	  if the led infrastructure is activated, support for a led indicating
-	  disk protection will be provided as hp:red:hddprotection.
-
-	  This driver can also be built as modules.  If so, the core module
-	  will be called lis3lv02d and a specific module for HP laptops will be
-	  called hp_accel.
-
-	  Say Y here if you have an applicable laptop and want to experience
-	  the awesome power of lis3lv02d.
-
 config SENSORS_LIS3_SPI
 	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
 	depends on !ACPI && SPI_MASTER && INPUT
@@ -1017,13 +1036,50 @@ config SENSORS_APPLESMC
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
-config HWMON_DEBUG_CHIP
-	bool "Hardware Monitoring Chip debugging messages"
+if ACPI
+
+comment "ACPI drivers"
+
+config SENSORS_ATK0110
+	tristate "ASUS ATK0110"
+	depends on X86 && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the ACPI hardware
+	  monitoring interface found in many ASUS motherboards. This
+	  driver will provide readings of fans, voltages and temperatures
+	  through the system firmware.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called asus_atk0110.
+
+config SENSORS_LIS3LV02D
+	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
+	depends on INPUT
+	select INPUT_POLLDEV
+	select NEW_LEDS
+	select LEDS_CLASS
 	default n
 	help
-	  Say Y here if you want the I2C chip drivers to produce a bunch of
-	  debug messages to the system log.  Select this if you are having
-	  a problem with I2C support and want to see more of what is going
-	  on.
+	  This driver provides support for the LIS3LV02Dx accelerometer. In
+	  particular, it can be found in a number of HP laptops, which have the
+	  "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
+	  systems the driver should load automatically (via ACPI). The
+	  accelerometer might also be found in other systems, connected via SPI
+	  or I2C.  The accelerometer data is readable via
+	  /sys/devices/platform/lis3lv02d.
+
+	  This driver also provides an absolute input class device, allowing
+	  the laptop to act as a pinball machine-esque joystick. On HP laptops,
+	  if the led infrastructure is activated, support for a led indicating
+	  disk protection will be provided as hp:red:hddprotection.
+
+	  This driver can also be built as modules.  If so, the core module
+	  will be called lis3lv02d and a specific module for HP laptops will be
+	  called hp_accel.
+
+	  Say Y here if you have an applicable laptop and want to experience
+	  the awesome power of lis3lv02d.
+
+endif # ACPI
 
 endif # HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index b793dce..bcf73a9 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -5,6 +5,10 @@
 obj-$(CONFIG_HWMON)		+= hwmon.o
 obj-$(CONFIG_HWMON_VID)		+= hwmon-vid.o
 
+# APCI drivers
+obj-$(CONFIG_SENSORS_ATK0110)	+= asus_atk0110.o
+
+# Native drivers
 # asb100, then w83781d go first, as they can override other drivers' addresses.
 obj-$(CONFIG_SENSORS_ASB100)	+= asb100.o
 obj-$(CONFIG_SENSORS_W83627HF)	+= w83627hf.o
@@ -29,10 +33,8 @@ obj-$(CONFIG_SENSORS_ADT7462)	+= adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)	+= adt7470.o
 obj-$(CONFIG_SENSORS_ADT7473)	+= adt7473.o
 obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475.o
-
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
 obj-$(CONFIG_SENSORS_AMS)	+= ams/
-obj-$(CONFIG_SENSORS_ATK0110)	+= asus_atk0110.o
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
 obj-$(CONFIG_SENSORS_DME1737)	+= dme1737.o
@@ -76,6 +78,7 @@ obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
+obj-$(CONFIG_SENSORS_S3C)	+= s3c-hwmon.o
 obj-$(CONFIG_SENSORS_SHT15)	+= sht15.o
 obj-$(CONFIG_SENSORS_SIS5595)	+= sis5595.o
 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
@@ -83,12 +86,15 @@ obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
 obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
 obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
+obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_VT1211)	+= vt1211.o
 obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
 obj-$(CONFIG_SENSORS_W83627EHF)	+= w83627ehf.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 obj-$(CONFIG_SENSORS_W83L786NG)	+= w83l786ng.o
+obj-$(CONFIG_SENSORS_WM831X)	+= wm831x-hwmon.o
+obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
 
 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index 4dbdb81..03694cc 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -32,7 +32,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* Banks */
 #define ABIT_UGURU_ALARM_BANK			0x20 /* 1x 3 bytes */
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index 7d3f15d..3cf28af 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -34,7 +34,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* uGuru3 bank addresses */
 #define ABIT_UGURU3_SETTINGS_BANK		0x01
@@ -117,9 +117,12 @@ struct abituguru3_sensor_info {
 	int offset;
 };
 
+/* Avoid use of flexible array members */
+#define ABIT_UGURU3_MAX_DMI_NAMES 2
+
 struct abituguru3_motherboard_info {
 	u16 id;
-	const char *dmi_name;
+	const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1];
 	/* + 1 -> end of sensors indicated by a sensor with name == NULL */
 	struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
 };
@@ -164,7 +167,7 @@ struct abituguru3_data {
 
 /* Constants */
 static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
-	{ 0x000C, NULL /* Unknown, need DMI string */, {
+	{ 0x000C, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -186,7 +189,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x000D, NULL /* Abit AW8, need DMI string */, {
+	{ 0x000D, { NULL } /* Abit AW8, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -215,7 +218,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX5 Fan",		39, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x000E, NULL /* AL-8, need DMI string */, {
+	{ 0x000E, { NULL } /* AL-8, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -236,7 +239,8 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "SYS Fan",		34, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x000F, NULL /* Unknown, need DMI string */, {
+	{ 0x000F, { NULL } /* Unknown, need DMI string */, {
+
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -257,7 +261,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "SYS Fan",		34, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, {
+	{ 0x0010, { NULL } /* Abit NI8 SLI GR, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -279,7 +283,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "OTES1 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0011, "AT8 32X", {
+	{ 0x0011, { "AT8 32X", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 20, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -306,7 +310,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX3 Fan",		37, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
+	{ 0x0012, { NULL } /* Abit AN8 32X, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 20, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -328,7 +332,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX1 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0013, NULL /* Abit AW8D, need DMI string */, {
+	{ 0x0013, { NULL } /* Abit AW8D, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -357,7 +361,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX5 Fan",		39, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0014, "AB9", /* + AB9 Pro */ {
+	{ 0x0014, { "AB9", "AB9 Pro", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -378,7 +382,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "SYS Fan",		34, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0015, NULL /* Unknown, need DMI string */, {
+	{ 0x0015, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 20, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -402,7 +406,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0016, "AW9D-MAX", {
+	{ 0x0016, { "AW9D-MAX", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -430,7 +434,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "OTES1 Fan",		38, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0017, NULL /* Unknown, need DMI string */, {
+	{ 0x0017, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -455,7 +459,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX3 FAN",		37, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0018, "AB9 QuadGT", {
+	{ 0x0018, { "AB9 QuadGT", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -482,7 +486,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0019, "IN9 32X MAX", {
+	{ 0x0019, { "IN9 32X MAX", NULL }, {
 		{ "CPU Core",		 7, 0, 10, 1, 0 },
 		{ "DDR2",		13, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		14, 0, 10, 1, 0 },
@@ -509,7 +513,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX3 FAN",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x001A, "IP35 Pro", {
+	{ 0x001A, { "IP35 Pro", "IP35 Pro XE", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -537,7 +541,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX4 Fan",		37, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x001B, NULL /* Unknown, need DMI string */, {
+	{ 0x001B, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR3",		 1, 0, 20, 1, 0 },
 		{ "DDR3 VTT",		 2, 0, 10, 1, 0 },
@@ -564,7 +568,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x001C, "IX38 QuadGT", {
+	{ 0x001C, { "IX38 QuadGT", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -591,7 +595,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } }
+	{ 0x0000, { NULL }, { { NULL, 0, 0, 0, 0, 0 } } }
 };
 
 
@@ -946,15 +950,6 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
 	printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard "
 		"ID: %04X\n", (unsigned int)id);
 
-#ifdef CONFIG_DMI
-	if (!abituguru3_motherboards[i].dmi_name) {
-		printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
-			"not detected using DMI. Please send the output of "
-			"\"dmidecode\" to the abituguru3 maintainer "
-			"(see MAINTAINERS)\n");
-	}
-#endif
-
 	/* Fill the sysfs attr array */
 	sysfs_attr_i = 0;
 	sysfs_filename = data->sysfs_names;
@@ -1131,6 +1126,7 @@ static int __init abituguru3_dmi_detect(void)
 {
 	const char *board_vendor, *board_name;
 	int i, err = (force) ? 1 : -ENODEV;
+	const char *const *dmi_name;
 	size_t sublen;
 
 	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1151,17 +1147,17 @@ static int __init abituguru3_dmi_detect(void)
 		sublen--;
 
 	for (i = 0; abituguru3_motherboards[i].id; i++) {
-		const char *dmi_name = abituguru3_motherboards[i].dmi_name;
-		if (!dmi_name || strlen(dmi_name) != sublen)
-			continue;
-		if (!strncasecmp(board_name, dmi_name, sublen))
-			break;
+		dmi_name = abituguru3_motherboards[i].dmi_name;
+		for ( ; *dmi_name; dmi_name++) {
+			if (strlen(*dmi_name) != sublen)
+				continue;
+			if (!strncasecmp(board_name, *dmi_name, sublen))
+				return 0;
+		}
 	}
 
-	if (!abituguru3_motherboards[i].id)
-		return 1;
-
-	return 0;
+	/* No match found */
+	return 1;
 }
 
 #else /* !CONFIG_DMI */
@@ -1221,6 +1217,13 @@ static int __init abituguru3_init(void)
 		err = abituguru3_detect();
 		if (err)
 			return err;
+
+#ifdef CONFIG_DMI
+		printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
+			"not detected using DMI. Please send the output of "
+			"\"dmidecode\" to the abituguru3 maintainer "
+			"(see MAINTAINERS)\n");
+#endif
 	}
 
 	err = platform_driver_register(&abituguru3_driver);
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 678e34b..753b348 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -35,7 +35,7 @@
 #include <linux/dmi.h>
 #include <linux/mutex.h>
 #include <linux/hwmon-sysfs.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/leds.h>
 #include <linux/hwmon.h>
 #include <linux/workqueue.h>
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 3df202a..9814d51 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -35,7 +35,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* ISA device, if found */
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 8998765..525a00b 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -40,7 +40,7 @@
 #include <linux/sysfs.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index d3612a1..be2d131 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -35,8 +35,7 @@
 #include <linux/timer.h>
 #include <linux/dmi.h>
 #include <linux/jiffies.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define HDAPS_LOW_PORT		0x1600	/* first port used by hdaps */
 #define HDAPS_NR_PORTS		0x30	/* number of ports: 0x1600 - 0x162f */
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index bfc2961..bf0862a 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -179,8 +179,14 @@ struct vrm_model {
 static struct vrm_model vrm_models[] = {
 	{X86_VENDOR_AMD, 0x6, ANY, ANY, 90},		/* Athlon Duron etc */
 	{X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24},		/* Athlon 64, Opteron */
-	{X86_VENDOR_AMD, 0xF, ANY, ANY, 25},		/* NPT family 0Fh */
+	/* In theory, all NPT family 0Fh processors have 6 VID pins and should
+	   thus use vrm 25, however in practice not all mainboards route the
+	   6th VID pin because it is never needed. So we use the 5 VID pin
+	   variant (vrm 24) for the models which exist today. */
+	{X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24},		/* NPT family 0Fh */
+	{X86_VENDOR_AMD, 0xF, ANY, ANY, 25},		/* future fam. 0Fh */
 	{X86_VENDOR_AMD, 0x10, ANY, ANY, 25},		/* NPT family 10h */
+
 	{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13},		/* Pentium M (130 nm) */
 	{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85},		/* Tualatin */
 	{X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13},		/* Pentium M (90 nm) */
@@ -191,12 +197,14 @@ static struct vrm_model vrm_models[] = {
 	{X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90},		/* P4 Willamette */
 	{X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90},		/* P4 Northwood */
 	{X86_VENDOR_INTEL, 0xF, ANY, ANY, 100},		/* Prescott and above assume VRD 10 */
+
 	{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85},	/* Eden ESP/Ezra */
 	{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85},	/* Ezra T */
 	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},	/* Nemiah */
 	{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17},	/* C3-M, Eden-N */
 	{X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0},		/* No information */
 	{X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13},	/* C7, Esther */
+
 	{X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0}		/* stop here */
 };
 
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 9157247..ffeb2a1 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -50,7 +50,7 @@
 #include <linux/string.h>
 #include <linux/dmi.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define DRVNAME "it87"
 
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index a1787fd..f7e7016 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -31,7 +31,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* ISA device, if found */
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index b251d86..6c53d98 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -75,6 +75,8 @@ I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100,
 #define	LM85_VERSTEP_GENERIC2		0x70
 #define	LM85_VERSTEP_LM85C		0x60
 #define	LM85_VERSTEP_LM85B		0x62
+#define	LM85_VERSTEP_LM96000_1		0x68
+#define	LM85_VERSTEP_LM96000_2		0x69
 #define	LM85_VERSTEP_ADM1027		0x60
 #define	LM85_VERSTEP_ADT7463		0x62
 #define	LM85_VERSTEP_ADT7463C		0x6A
@@ -1133,6 +1135,26 @@ static void lm85_init_client(struct i2c_client *client)
 		dev_warn(&client->dev, "Device is not ready\n");
 }
 
+static int lm85_is_fake(struct i2c_client *client)
+{
+	/*
+	 * Differenciate between real LM96000 and Winbond WPCD377I. The latter
+	 * emulate the former except that it has no hardware monitoring function
+	 * so the readings are always 0.
+	 */
+	int i;
+	u8 in_temp, fan;
+
+	for (i = 0; i < 8; i++) {
+		in_temp = i2c_smbus_read_byte_data(client, 0x20 + i);
+		fan = i2c_smbus_read_byte_data(client, 0x28 + i);
+		if (in_temp != 0x00 || fan != 0xff)
+			return 0;
+	}
+
+	return 1;
+}
+
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int lm85_detect(struct i2c_client *client, int kind,
 		       struct i2c_board_info *info)
@@ -1173,6 +1195,16 @@ static int lm85_detect(struct i2c_client *client, int kind,
 			case LM85_VERSTEP_LM85B:
 				kind = lm85b;
 				break;
+			case LM85_VERSTEP_LM96000_1:
+			case LM85_VERSTEP_LM96000_2:
+				/* Check for Winbond WPCD377I */
+				if (lm85_is_fake(client)) {
+					dev_dbg(&adapter->dev,
+						"Found Winbond WPCD377I, "
+						"ignoring\n");
+					return -ENODEV;
+				}
+				break;
 			}
 		} else if (company == LM85_COMPANY_ANALOG_DEV) {
 			switch (verstep) {
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index fb052fe..4a64b85 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -44,7 +44,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static u8 devid;
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 3a8a0f7..3170b26 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -33,7 +33,7 @@
 #include <linux/sysfs.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
@@ -435,7 +435,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev)
 	/* This will need to be revisited when we add support for
 	   temperature and voltage monitoring. */
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+	if (!request_region(res->start, resource_size(res), DRVNAME)) {
 		err = -EBUSY;
 		dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
 			(unsigned long)res->start, (unsigned long)res->end);
@@ -475,7 +475,7 @@ exit_remove_files:
 		sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
 	}
 exit_release_region:
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 exit_kfree:
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
@@ -500,7 +500,7 @@ static int __devexit pc87427_remove(struct platform_device *pdev)
 	kfree(data);
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 
 	return 0;
 }
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
new file mode 100644
index 0000000..3a524f2
--- /dev/null
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -0,0 +1,405 @@
+/* linux/drivers/hwmon/s3c-hwmon.c
+ *
+ * Copyright (C) 2005, 2008, 2009 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX/S3C64XX ADC hwmon support
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+#include <plat/adc.h>
+#include <plat/hwmon.h>
+
+struct s3c_hwmon_attr {
+	struct sensor_device_attribute	in;
+	struct sensor_device_attribute	label;
+	char				in_name[12];
+	char				label_name[12];
+};
+
+/**
+ * struct s3c_hwmon - ADC hwmon client information
+ * @lock: Access lock to serialise the conversions.
+ * @client: The client we registered with the S3C ADC core.
+ * @hwmon_dev: The hwmon device we created.
+ * @attr: The holders for the channel attributes.
+*/
+struct s3c_hwmon {
+	struct semaphore	lock;
+	struct s3c_adc_client	*client;
+	struct device		*hwmon_dev;
+
+	struct s3c_hwmon_attr	attrs[8];
+};
+
+/**
+ * s3c_hwmon_read_ch - read a value from a given adc channel.
+ * @dev: The device.
+ * @hwmon: Our state.
+ * @channel: The channel we're reading from.
+ *
+ * Read a value from the @channel with the proper locking and sleep until
+ * either the read completes or we timeout awaiting the ADC core to get
+ * back to us.
+ */
+static int s3c_hwmon_read_ch(struct device *dev,
+			     struct s3c_hwmon *hwmon, int channel)
+{
+	int ret;
+
+	ret = down_interruptible(&hwmon->lock);
+	if (ret < 0)
+		return ret;
+
+	dev_dbg(dev, "reading channel %d\n", channel);
+
+	ret = s3c_adc_read(hwmon->client, channel);
+	up(&hwmon->lock);
+
+	return ret;
+}
+
+#ifdef CONFIG_SENSORS_S3C_RAW
+/**
+ * s3c_hwmon_show_raw - show a conversion from the raw channel number.
+ * @dev: The device that the attribute belongs to.
+ * @attr: The attribute being read.
+ * @buf: The result buffer.
+ *
+ * This show deals with the raw attribute, registered for each possible
+ * ADC channel. This does a conversion and returns the raw (un-scaled)
+ * value returned from the hardware.
+ */
+static ssize_t s3c_hwmon_show_raw(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct s3c_hwmon *adc = platform_get_drvdata(to_platform_device(dev));
+	struct sensor_device_attribute *sa = to_sensor_dev_attr(attr);
+	int ret;
+
+	ret = s3c_hwmon_read_ch(dev, adc, sa->index);
+
+	return  (ret < 0) ? ret : snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+#define DEF_ADC_ATTR(x)	\
+	static SENSOR_DEVICE_ATTR(adc##x##_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, x)
+
+DEF_ADC_ATTR(0);
+DEF_ADC_ATTR(1);
+DEF_ADC_ATTR(2);
+DEF_ADC_ATTR(3);
+DEF_ADC_ATTR(4);
+DEF_ADC_ATTR(5);
+DEF_ADC_ATTR(6);
+DEF_ADC_ATTR(7);
+
+static struct attribute *s3c_hwmon_attrs[9] = {
+	&sensor_dev_attr_adc0_raw.dev_attr.attr,
+	&sensor_dev_attr_adc1_raw.dev_attr.attr,
+	&sensor_dev_attr_adc2_raw.dev_attr.attr,
+	&sensor_dev_attr_adc3_raw.dev_attr.attr,
+	&sensor_dev_attr_adc4_raw.dev_attr.attr,
+	&sensor_dev_attr_adc5_raw.dev_attr.attr,
+	&sensor_dev_attr_adc6_raw.dev_attr.attr,
+	&sensor_dev_attr_adc7_raw.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group s3c_hwmon_attrgroup = {
+	.attrs	= s3c_hwmon_attrs,
+};
+
+static inline int s3c_hwmon_add_raw(struct device *dev)
+{
+	return sysfs_create_group(&dev->kobj, &s3c_hwmon_attrgroup);
+}
+
+static inline void s3c_hwmon_remove_raw(struct device *dev)
+{
+	sysfs_remove_group(&dev->kobj, &s3c_hwmon_attrgroup);
+}
+
+#else
+
+static inline int s3c_hwmon_add_raw(struct device *dev) { return 0; }
+static inline void s3c_hwmon_remove_raw(struct device *dev) { }
+
+#endif /* CONFIG_SENSORS_S3C_RAW */
+
+/**
+ * s3c_hwmon_ch_show - show value of a given channel
+ * @dev: The device that the attribute belongs to.
+ * @attr: The attribute being read.
+ * @buf: The result buffer.
+ *
+ * Read a value from the ADC and scale it before returning it to the
+ * caller. The scale factor is gained from the channel configuration
+ * passed via the platform data when the device was registered.
+ */
+static ssize_t s3c_hwmon_ch_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr);
+	struct s3c_hwmon *hwmon = platform_get_drvdata(to_platform_device(dev));
+	struct s3c_hwmon_pdata *pdata = dev->platform_data;
+	struct s3c_hwmon_chcfg *cfg;
+	int ret;
+
+	cfg = pdata->in[sen_attr->index];
+
+	ret = s3c_hwmon_read_ch(dev, hwmon, sen_attr->index);
+	if (ret < 0)
+		return ret;
+
+	ret *= cfg->mult;
+	ret = DIV_ROUND_CLOSEST(ret, cfg->div);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ret);
+}
+
+/**
+ * s3c_hwmon_label_show - show label name of the given channel.
+ * @dev: The device that the attribute belongs to.
+ * @attr: The attribute being read.
+ * @buf: The result buffer.
+ *
+ * Return the label name of a given channel
+ */
+static ssize_t s3c_hwmon_label_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr);
+	struct s3c_hwmon_pdata *pdata = dev->platform_data;
+	struct s3c_hwmon_chcfg *cfg;
+
+	cfg = pdata->in[sen_attr->index];
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", cfg->name);
+}
+
+/**
+ * s3c_hwmon_create_attr - create hwmon attribute for given channel.
+ * @dev: The device to create the attribute on.
+ * @cfg: The channel configuration passed from the platform data.
+ * @channel: The ADC channel number to process.
+ *
+ * Create the scaled attribute for use with hwmon from the specified
+ * platform data in @pdata. The sysfs entry is handled by the routine
+ * s3c_hwmon_ch_show().
+ *
+ * The attribute name is taken from the configuration data if present
+ * otherwise the name is taken by concatenating in_ with the channel
+ * number.
+ */
+static int s3c_hwmon_create_attr(struct device *dev,
+				 struct s3c_hwmon_chcfg *cfg,
+				 struct s3c_hwmon_attr *attrs,
+				 int channel)
+{
+	struct sensor_device_attribute *attr;
+	int ret;
+
+	snprintf(attrs->in_name, sizeof(attrs->in_name), "in%d_input", channel);
+
+	attr = &attrs->in;
+	attr->index = channel;
+	attr->dev_attr.attr.name  = attrs->in_name;
+	attr->dev_attr.attr.mode  = S_IRUGO;
+	attr->dev_attr.attr.owner = THIS_MODULE;
+	attr->dev_attr.show = s3c_hwmon_ch_show;
+
+	ret =  device_create_file(dev, &attr->dev_attr);
+	if (ret < 0) {
+		dev_err(dev, "failed to create input attribute\n");
+		return ret;
+	}
+
+	/* if this has a name, add a label */
+	if (cfg->name) {
+		snprintf(attrs->label_name, sizeof(attrs->label_name),
+			 "in%d_label", channel);
+
+		attr = &attrs->label;
+		attr->index = channel;
+		attr->dev_attr.attr.name  = attrs->label_name;
+		attr->dev_attr.attr.mode  = S_IRUGO;
+		attr->dev_attr.attr.owner = THIS_MODULE;
+		attr->dev_attr.show = s3c_hwmon_label_show;
+
+		ret = device_create_file(dev, &attr->dev_attr);
+		if (ret < 0) {
+			device_remove_file(dev, &attrs->in.dev_attr);
+			dev_err(dev, "failed to create label attribute\n");
+		}
+	}
+
+	return ret;
+}
+
+static void s3c_hwmon_remove_attr(struct device *dev,
+				  struct s3c_hwmon_attr *attrs)
+{
+	device_remove_file(dev, &attrs->in.dev_attr);
+	device_remove_file(dev, &attrs->label.dev_attr);
+}
+
+/**
+ * s3c_hwmon_probe - device probe entry.
+ * @dev: The device being probed.
+*/
+static int __devinit s3c_hwmon_probe(struct platform_device *dev)
+{
+	struct s3c_hwmon_pdata *pdata = dev->dev.platform_data;
+	struct s3c_hwmon *hwmon;
+	int ret = 0;
+	int i;
+
+	if (!pdata) {
+		dev_err(&dev->dev, "no platform data supplied\n");
+		return -EINVAL;
+	}
+
+	hwmon = kzalloc(sizeof(struct s3c_hwmon), GFP_KERNEL);
+	if (hwmon == NULL) {
+		dev_err(&dev->dev, "no memory\n");
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(dev, hwmon);
+
+	init_MUTEX(&hwmon->lock);
+
+	/* Register with the core ADC driver. */
+
+	hwmon->client = s3c_adc_register(dev, NULL, NULL, 0);
+	if (IS_ERR(hwmon->client)) {
+		dev_err(&dev->dev, "cannot register adc\n");
+		ret = PTR_ERR(hwmon->client);
+		goto err_mem;
+	}
+
+	/* add attributes for our adc devices. */
+
+	ret = s3c_hwmon_add_raw(&dev->dev);
+	if (ret)
+		goto err_registered;
+
+	/* register with the hwmon core */
+
+	hwmon->hwmon_dev = hwmon_device_register(&dev->dev);
+	if (IS_ERR(hwmon->hwmon_dev)) {
+		dev_err(&dev->dev, "error registering with hwmon\n");
+		ret = PTR_ERR(hwmon->hwmon_dev);
+		goto err_raw_attribute;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(pdata->in); i++) {
+		if (!pdata->in[i])
+			continue;
+
+		if (pdata->in[i]->mult >= 0x10000)
+			dev_warn(&dev->dev,
+				 "channel %d multiplier too large\n",
+				 i);
+
+		ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i],
+					    &hwmon->attrs[i], i);
+		if (ret) {
+			dev_err(&dev->dev,
+					"error creating channel %d\n", i);
+
+			for (i--; i >= 0; i--)
+				s3c_hwmon_remove_attr(&dev->dev,
+							      &hwmon->attrs[i]);
+
+			goto err_hwmon_register;
+		}
+	}
+
+	return 0;
+
+ err_hwmon_register:
+	hwmon_device_unregister(hwmon->hwmon_dev);
+
+ err_raw_attribute:
+	s3c_hwmon_remove_raw(&dev->dev);
+
+ err_registered:
+	s3c_adc_release(hwmon->client);
+
+ err_mem:
+	kfree(hwmon);
+	return ret;
+}
+
+static int __devexit s3c_hwmon_remove(struct platform_device *dev)
+{
+	struct s3c_hwmon *hwmon = platform_get_drvdata(dev);
+	int i;
+
+	s3c_hwmon_remove_raw(&dev->dev);
+
+	for (i = 0; i < ARRAY_SIZE(hwmon->attrs); i++)
+		s3c_hwmon_remove_attr(&dev->dev, &hwmon->attrs[i]);
+
+	hwmon_device_unregister(hwmon->hwmon_dev);
+	s3c_adc_release(hwmon->client);
+
+	return 0;
+}
+
+static struct platform_driver s3c_hwmon_driver = {
+	.driver	= {
+		.name		= "s3c-hwmon",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= s3c_hwmon_probe,
+	.remove		= __devexit_p(s3c_hwmon_remove),
+};
+
+static int __init s3c_hwmon_init(void)
+{
+	return platform_driver_register(&s3c_hwmon_driver);
+}
+
+static void __exit s3c_hwmon_exit(void)
+{
+	platform_driver_unregister(&s3c_hwmon_driver);
+}
+
+module_init(s3c_hwmon_init);
+module_exit(s3c_hwmon_exit);
+
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("S3C ADC HWMon driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:s3c-hwmon");
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index aa2e831..12f2e70 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -63,7 +63,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 /* If force_addr is set to anything different from 0, we forcibly enable
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 6f6d52b..f46d936 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -37,7 +37,7 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index ba75bfc..8ad50fd 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -38,7 +38,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
new file mode 100644
index 0000000..2092434
--- /dev/null
+++ b/drivers/hwmon/tmp421.c
@@ -0,0 +1,347 @@
+/* tmp421.c
+ *
+ * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
+ * Preliminary support by:
+ * Melvin Rook, Raymond Ng
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 for the Texas Instruments TMP421 SMBus temperature sensor IC.
+ * Supported models: TMP421, TMP422, TMP423
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
+				       I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423);
+
+/* The TMP421 registers */
+#define TMP421_CONFIG_REG_1			0x09
+#define TMP421_CONVERSION_RATE_REG		0x0B
+#define TMP421_MANUFACTURER_ID_REG		0xFE
+#define TMP421_DEVICE_ID_REG			0xFF
+
+static const u8 TMP421_TEMP_MSB[4]		= { 0x00, 0x01, 0x02, 0x03 };
+static const u8 TMP421_TEMP_LSB[4]		= { 0x10, 0x11, 0x12, 0x13 };
+
+/* Flags */
+#define TMP421_CONFIG_SHUTDOWN			0x40
+#define TMP421_CONFIG_RANGE			0x04
+
+/* Manufacturer / Device ID's */
+#define TMP421_MANUFACTURER_ID			0x55
+#define TMP421_DEVICE_ID			0x21
+#define TMP422_DEVICE_ID			0x22
+#define TMP423_DEVICE_ID			0x23
+
+static const struct i2c_device_id tmp421_id[] = {
+	{ "tmp421", tmp421 },
+	{ "tmp422", tmp422 },
+	{ "tmp423", tmp423 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tmp421_id);
+
+struct tmp421_data {
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	char valid;
+	unsigned long last_updated;
+	int kind;
+	u8 config;
+	s16 temp[4];
+};
+
+static int temp_from_s16(s16 reg)
+{
+	int temp = reg;
+
+	return (temp * 1000 + 128) / 256;
+}
+
+static int temp_from_u16(u16 reg)
+{
+	int temp = reg;
+
+	/* Add offset for extended temperature range. */
+	temp -= 64 * 256;
+
+	return (temp * 1000 + 128) / 256;
+}
+
+static struct tmp421_data *tmp421_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tmp421_data *data = i2c_get_clientdata(client);
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+		data->config = i2c_smbus_read_byte_data(client,
+			TMP421_CONFIG_REG_1);
+
+		for (i = 0; i <= data->kind; i++) {
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+				TMP421_TEMP_MSB[i]) << 8;
+			data->temp[i] |= i2c_smbus_read_byte_data(client,
+				TMP421_TEMP_LSB[i]);
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+static ssize_t show_temp_value(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
+{
+	int index = to_sensor_dev_attr(devattr)->index;
+	struct tmp421_data *data = tmp421_update_device(dev);
+	int temp;
+
+	mutex_lock(&data->update_lock);
+	if (data->config & TMP421_CONFIG_RANGE)
+		temp = temp_from_u16(data->temp[index]);
+	else
+		temp = temp_from_s16(data->temp[index]);
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%d\n", temp);
+}
+
+static ssize_t show_fault(struct device *dev,
+			  struct device_attribute *devattr, char *buf)
+{
+	int index = to_sensor_dev_attr(devattr)->index;
+	struct tmp421_data *data = tmp421_update_device(dev);
+
+	/*
+	 * The OPEN bit signals a fault. This is bit 0 of the temperature
+	 * register (low byte).
+	 */
+	if (data->temp[index] & 0x01)
+		return sprintf(buf, "1\n");
+	else
+		return sprintf(buf, "0\n");
+}
+
+static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
+				int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct tmp421_data *data = dev_get_drvdata(dev);
+	struct device_attribute *devattr;
+	unsigned int index;
+
+	devattr = container_of(a, struct device_attribute, attr);
+	index = to_sensor_dev_attr(devattr)->index;
+
+	if (data->kind > index)
+		return a->mode;
+
+	return 0;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
+
+static struct attribute *tmp421_attr[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_fault.dev_attr.attr,
+	&sensor_dev_attr_temp3_input.dev_attr.attr,
+	&sensor_dev_attr_temp3_fault.dev_attr.attr,
+	&sensor_dev_attr_temp4_input.dev_attr.attr,
+	&sensor_dev_attr_temp4_fault.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group tmp421_group = {
+	.attrs = tmp421_attr,
+	.is_visible = tmp421_is_visible,
+};
+
+static int tmp421_init_client(struct i2c_client *client)
+{
+	int config, config_orig;
+
+	/* Set the conversion rate to 2 Hz */
+	i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05);
+
+	/* Start conversions (disable shutdown if necessary) */
+	config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1);
+	if (config < 0) {
+		dev_err(&client->dev, "Could not read configuration"
+			 " register (%d)\n", config);
+		return -ENODEV;
+	}
+
+	config_orig = config;
+	config &= ~TMP421_CONFIG_SHUTDOWN;
+
+	if (config != config_orig) {
+		dev_info(&client->dev, "Enable monitoring chip\n");
+		i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config);
+	}
+
+	return 0;
+}
+
+static int tmp421_detect(struct i2c_client *client, int kind,
+			 struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	const char *names[] = { "TMP421", "TMP422", "TMP423" };
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	if (kind <= 0) {
+		u8 reg;
+
+		reg = i2c_smbus_read_byte_data(client,
+					       TMP421_MANUFACTURER_ID_REG);
+		if (reg != TMP421_MANUFACTURER_ID)
+			return -ENODEV;
+
+		reg = i2c_smbus_read_byte_data(client,
+					       TMP421_DEVICE_ID_REG);
+		switch (reg) {
+		case TMP421_DEVICE_ID:
+			kind = tmp421;
+			break;
+		case TMP422_DEVICE_ID:
+			kind = tmp422;
+			break;
+		case TMP423_DEVICE_ID:
+			kind = tmp423;
+			break;
+		default:
+			return -ENODEV;
+		}
+	}
+	strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
+	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
+		 names[kind - 1], client->addr);
+
+	return 0;
+}
+
+static int tmp421_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct tmp421_data *data;
+	int err;
+
+	data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+	data->kind = id->driver_data;
+
+	err = tmp421_init_client(client);
+	if (err)
+		goto exit_free;
+
+	err = sysfs_create_group(&client->dev.kobj, &tmp421_group);
+	if (err)
+		goto exit_free;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		data->hwmon_dev = NULL;
+		goto exit_remove;
+	}
+	return 0;
+
+exit_remove:
+	sysfs_remove_group(&client->dev.kobj, &tmp421_group);
+
+exit_free:
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+
+	return err;
+}
+
+static int tmp421_remove(struct i2c_client *client)
+{
+	struct tmp421_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &tmp421_group);
+
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+
+	return 0;
+}
+
+static struct i2c_driver tmp421_driver = {
+	.class = I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "tmp421",
+	},
+	.probe = tmp421_probe,
+	.remove = tmp421_remove,
+	.id_table = tmp421_id,
+	.detect = tmp421_detect,
+	.address_data = &addr_data,
+};
+
+static int __init tmp421_init(void)
+{
+	return i2c_add_driver(&tmp421_driver);
+}
+
+static void __exit tmp421_exit(void)
+{
+	i2c_del_driver(&tmp421_driver);
+}
+
+MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
+MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor"
+		   " driver");
+MODULE_LICENSE("GPL");
+
+module_init(tmp421_init);
+module_exit(tmp421_exit);
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index a022aed..39e82a4 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -42,7 +42,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 /* If force_addr is set to anything different from 0, we forcibly enable
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 73f77a9..ae33bbb 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -33,7 +33,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int uch_config = -1;
 module_param(uch_config, int, 0);
@@ -1136,7 +1136,7 @@ static int __devinit vt1211_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+	if (!request_region(res->start, resource_size(res), DRVNAME)) {
 		err = -EBUSY;
 		dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
 			(unsigned long)res->start, (unsigned long)res->end);
@@ -1209,7 +1209,7 @@ EXIT_DEV_REMOVE:
 	dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
 EXIT_DEV_REMOVE_SILENT:
 	vt1211_remove_sysfs(pdev);
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 EXIT_KFREE:
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
@@ -1228,7 +1228,7 @@ static int __devexit vt1211_remove(struct platform_device *pdev)
 	kfree(data);
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 
 	return 0;
 }
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index 9982b45..470a122 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -36,7 +36,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int force_addr;
 module_param(force_addr, int, 0);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 0e97469..bb5e787 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -51,7 +51,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "lm75.h"
 
 enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg };
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 389150b..2be28ac 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -51,7 +51,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "lm75.h"
 
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 0bdab95..d27ed1b 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -48,7 +48,7 @@
 #ifdef CONFIG_ISA
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #endif
 
 #include "lm75.h"
diff --git a/drivers/hwmon/wm831x-hwmon.c b/drivers/hwmon/wm831x-hwmon.c
new file mode 100644
index 0000000..c16e9e7
--- /dev/null
+++ b/drivers/hwmon/wm831x-hwmon.c
@@ -0,0 +1,226 @@
+/*
+ * drivers/hwmon/wm831x-hwmon.c - Wolfson Microelectronics WM831x PMIC
+ *                                hardware monitoring features.
+ *
+ * Copyright (C) 2009 Wolfson Microelectronics plc
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/auxadc.h>
+
+struct wm831x_hwmon {
+	struct wm831x *wm831x;
+	struct device *classdev;
+};
+
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "wm831x\n");
+}
+
+static const char *input_names[] = {
+	[WM831X_AUX_SYSVDD]    = "SYSVDD",
+	[WM831X_AUX_USB]       = "USB",
+	[WM831X_AUX_BKUP_BATT] = "Backup battery",
+	[WM831X_AUX_BATT]      = "Battery",
+	[WM831X_AUX_WALL]      = "WALL",
+	[WM831X_AUX_CHIP_TEMP] = "PMIC",
+	[WM831X_AUX_BATT_TEMP] = "Battery",
+};
+
+
+static ssize_t show_voltage(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct wm831x_hwmon *hwmon = dev_get_drvdata(dev);
+	int channel = to_sensor_dev_attr(attr)->index;
+	int ret;
+
+	ret = wm831x_auxadc_read_uv(hwmon->wm831x, channel);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(ret, 1000));
+}
+
+static ssize_t show_chip_temp(struct device *dev,
+			      struct device_attribute *attr, char *buf)
+{
+	struct wm831x_hwmon *hwmon = dev_get_drvdata(dev);
+	int channel = to_sensor_dev_attr(attr)->index;
+	int ret;
+
+	ret = wm831x_auxadc_read(hwmon->wm831x, channel);
+	if (ret < 0)
+		return ret;
+
+	/* Degrees celsius = (512.18-ret) / 1.0983 */
+	ret = 512180 - (ret * 1000);
+	ret = DIV_ROUND_CLOSEST(ret * 10000, 10983);
+
+	return sprintf(buf, "%d\n", ret);
+}
+
+static ssize_t show_label(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	int channel = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%s\n", input_names[channel]);
+}
+
+#define WM831X_VOLTAGE(id, name) \
+	static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage, \
+				  NULL, name)
+
+#define WM831X_NAMED_VOLTAGE(id, name) \
+	WM831X_VOLTAGE(id, name); \
+	static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label,	\
+				  NULL, name)
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+WM831X_VOLTAGE(0, WM831X_AUX_AUX1);
+WM831X_VOLTAGE(1, WM831X_AUX_AUX2);
+WM831X_VOLTAGE(2, WM831X_AUX_AUX3);
+WM831X_VOLTAGE(3, WM831X_AUX_AUX4);
+
+WM831X_NAMED_VOLTAGE(4, WM831X_AUX_SYSVDD);
+WM831X_NAMED_VOLTAGE(5, WM831X_AUX_USB);
+WM831X_NAMED_VOLTAGE(6, WM831X_AUX_BATT);
+WM831X_NAMED_VOLTAGE(7, WM831X_AUX_WALL);
+WM831X_NAMED_VOLTAGE(8, WM831X_AUX_BKUP_BATT);
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_chip_temp, NULL,
+			  WM831X_AUX_CHIP_TEMP);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_label, NULL,
+			  WM831X_AUX_CHIP_TEMP);
+/* Report as a voltage since conversion depends on external components
+ * and that's what the ABI wants. */
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_voltage, NULL,
+			  WM831X_AUX_BATT_TEMP);
+static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL,
+			  WM831X_AUX_BATT_TEMP);
+
+static struct attribute *wm831x_attributes[] = {
+	&dev_attr_name.attr,
+
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in4_label.dev_attr.attr,
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in5_label.dev_attr.attr,
+	&sensor_dev_attr_in6_input.dev_attr.attr,
+	&sensor_dev_attr_in6_label.dev_attr.attr,
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in7_label.dev_attr.attr,
+	&sensor_dev_attr_in8_input.dev_attr.attr,
+	&sensor_dev_attr_in8_label.dev_attr.attr,
+
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_label.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_label.dev_attr.attr,
+
+	NULL
+};
+
+static const struct attribute_group wm831x_attr_group = {
+	.attrs	= wm831x_attributes,
+};
+
+static int __devinit wm831x_hwmon_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_hwmon *hwmon;
+	int ret;
+
+	hwmon = kzalloc(sizeof(struct wm831x_hwmon), GFP_KERNEL);
+	if (!hwmon)
+		return -ENOMEM;
+
+	hwmon->wm831x = wm831x;
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &wm831x_attr_group);
+	if (ret)
+		goto err;
+
+	hwmon->classdev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(hwmon->classdev)) {
+		ret = PTR_ERR(hwmon->classdev);
+		goto err_sysfs;
+	}
+
+	platform_set_drvdata(pdev, hwmon);
+
+	return 0;
+
+err_sysfs:
+	sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group);
+err:
+	kfree(hwmon);
+	return ret;
+}
+
+static int __devexit wm831x_hwmon_remove(struct platform_device *pdev)
+{
+	struct wm831x_hwmon *hwmon = platform_get_drvdata(pdev);
+
+	hwmon_device_unregister(hwmon->classdev);
+	sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group);
+	platform_set_drvdata(pdev, NULL);
+	kfree(hwmon);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_hwmon_driver = {
+	.probe = wm831x_hwmon_probe,
+	.remove = __devexit_p(wm831x_hwmon_remove),
+	.driver = {
+		.name = "wm831x-hwmon",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init wm831x_hwmon_init(void)
+{
+	return platform_driver_register(&wm831x_hwmon_driver);
+}
+module_init(wm831x_hwmon_init);
+
+static void __exit wm831x_hwmon_exit(void)
+{
+	platform_driver_unregister(&wm831x_hwmon_driver);
+}
+module_exit(wm831x_hwmon_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("WM831x Hardware Monitoring");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-hwmon");
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c
new file mode 100644
index 0000000..1329059
--- /dev/null
+++ b/drivers/hwmon/wm8350-hwmon.c
@@ -0,0 +1,151 @@
+/*
+ * drivers/hwmon/wm8350-hwmon.c - Wolfson Microelectronics WM8350 PMIC
+ *                                  hardware monitoring features.
+ *
+ * Copyright (C) 2009 Wolfson Microelectronics plc
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/comparator.h>
+
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "wm8350\n");
+}
+
+static const char *input_names[] = {
+	[WM8350_AUXADC_USB]  = "USB",
+	[WM8350_AUXADC_LINE] = "Line",
+	[WM8350_AUXADC_BATT] = "Battery",
+};
+
+
+static ssize_t show_voltage(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct wm8350 *wm8350 = dev_get_drvdata(dev);
+	int channel = to_sensor_dev_attr(attr)->index;
+	int val;
+
+	val = wm8350_read_auxadc(wm8350, channel, 0, 0) * WM8350_AUX_COEFF;
+	val = DIV_ROUND_CLOSEST(val, 1000);
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t show_label(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	int channel = to_sensor_dev_attr(attr)->index;
+
+	return sprintf(buf, "%s\n", input_names[channel]);
+}
+
+#define WM8350_NAMED_VOLTAGE(id, name) \
+	static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage,\
+				  NULL, name);		\
+	static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label,	\
+				  NULL, name)
+
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB);
+WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT);
+WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE);
+
+static struct attribute *wm8350_attributes[] = {
+	&dev_attr_name.attr,
+
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in0_label.dev_attr.attr,
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in1_label.dev_attr.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in2_label.dev_attr.attr,
+
+	NULL,
+};
+
+static const struct attribute_group wm8350_attr_group = {
+	.attrs	= wm8350_attributes,
+};
+
+static int __devinit wm8350_hwmon_probe(struct platform_device *pdev)
+{
+	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &wm8350_attr_group);
+	if (ret)
+		goto err;
+
+	wm8350->hwmon.classdev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(wm8350->hwmon.classdev)) {
+		ret = PTR_ERR(wm8350->hwmon.classdev);
+		goto err_group;
+	}
+
+	return 0;
+
+err_group:
+	sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
+err:
+	return ret;
+}
+
+static int __devexit wm8350_hwmon_remove(struct platform_device *pdev)
+{
+	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
+
+	hwmon_device_unregister(wm8350->hwmon.classdev);
+	sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
+
+	return 0;
+}
+
+static struct platform_driver wm8350_hwmon_driver = {
+	.probe = wm8350_hwmon_probe,
+	.remove = __devexit_p(wm8350_hwmon_remove),
+	.driver = {
+		.name = "wm8350-hwmon",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init wm8350_hwmon_init(void)
+{
+	return platform_driver_register(&wm8350_hwmon_driver);
+}
+module_init(wm8350_hwmon_init);
+
+static void __exit wm8350_hwmon_exit(void)
+{
+	platform_driver_unregister(&wm8350_hwmon_driver);
+}
+module_exit(wm8350_hwmon_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("WM8350 Hardware Monitoring");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8350-hwmon");
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 0b486a6..4afba3e 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -609,13 +609,12 @@ static int __init i2c_adap_imx_init(void)
 {
 	return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe);
 }
+subsys_initcall(i2c_adap_imx_init);
 
 static void __exit i2c_adap_imx_exit(void)
 {
 	platform_driver_unregister(&i2c_imx_driver);
 }
-
-module_init(i2c_adap_imx_init);
 module_exit(i2c_adap_imx_exit);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index c3869d9..bbab0e1 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -293,13 +293,13 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 	}
 }
 
-static int
+static irqreturn_t
 mv64xxx_i2c_intr(int irq, void *dev_id)
 {
 	struct mv64xxx_i2c_data	*drv_data = dev_id;
 	unsigned long	flags;
 	u32		status;
-	int		rc = IRQ_NONE;
+	irqreturn_t	rc = IRQ_NONE;
 
 	spin_lock_irqsave(&drv_data->lock, flags);
 	while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) &
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 762e1e5..0495557 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -1134,35 +1134,44 @@ static int __exit i2c_pxa_remove(struct platform_device *dev)
 }
 
 #ifdef CONFIG_PM
-static int i2c_pxa_suspend_late(struct platform_device *dev, pm_message_t state)
+static int i2c_pxa_suspend_noirq(struct device *dev)
 {
-	struct pxa_i2c *i2c = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pxa_i2c *i2c = platform_get_drvdata(pdev);
+
 	clk_disable(i2c->clk);
+
 	return 0;
 }
 
-static int i2c_pxa_resume_early(struct platform_device *dev)
+static int i2c_pxa_resume_noirq(struct device *dev)
 {
-	struct pxa_i2c *i2c = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pxa_i2c *i2c = platform_get_drvdata(pdev);
 
 	clk_enable(i2c->clk);
 	i2c_pxa_reset(i2c);
 
 	return 0;
 }
+
+static struct dev_pm_ops i2c_pxa_dev_pm_ops = {
+	.suspend_noirq = i2c_pxa_suspend_noirq,
+	.resume_noirq = i2c_pxa_resume_noirq,
+};
+
+#define I2C_PXA_DEV_PM_OPS (&i2c_pxa_dev_pm_ops)
 #else
-#define i2c_pxa_suspend_late NULL
-#define i2c_pxa_resume_early NULL
+#define I2C_PXA_DEV_PM_OPS NULL
 #endif
 
 static struct platform_driver i2c_pxa_driver = {
 	.probe		= i2c_pxa_probe,
 	.remove		= __exit_p(i2c_pxa_remove),
-	.suspend_late	= i2c_pxa_suspend_late,
-	.resume_early	= i2c_pxa_resume_early,
 	.driver		= {
 		.name	= "pxa2xx-i2c",
 		.owner	= THIS_MODULE,
+		.pm	= I2C_PXA_DEV_PM_OPS,
 	},
 	.id_table	= i2c_pxa_id_table,
 };
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 20bb0ce..96aafb9 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -946,17 +946,20 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int s3c24xx_i2c_suspend_late(struct platform_device *dev,
-				    pm_message_t msg)
+static int s3c24xx_i2c_suspend_noirq(struct device *dev)
 {
-	struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
+
 	i2c->suspended = 1;
+
 	return 0;
 }
 
-static int s3c24xx_i2c_resume(struct platform_device *dev)
+static int s3c24xx_i2c_resume(struct device *dev)
 {
-	struct s3c24xx_i2c *i2c = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
 
 	i2c->suspended = 0;
 	s3c24xx_i2c_init(i2c);
@@ -964,9 +967,14 @@ static int s3c24xx_i2c_resume(struct platform_device *dev)
 	return 0;
 }
 
+static struct dev_pm_ops s3c24xx_i2c_dev_pm_ops = {
+	.suspend_noirq = s3c24xx_i2c_suspend_noirq,
+	.resume = s3c24xx_i2c_resume,
+};
+
+#define S3C24XX_DEV_PM_OPS (&s3c24xx_i2c_dev_pm_ops)
 #else
-#define s3c24xx_i2c_suspend_late NULL
-#define s3c24xx_i2c_resume NULL
+#define S3C24XX_DEV_PM_OPS NULL
 #endif
 
 /* device driver for platform bus bits */
@@ -985,12 +993,11 @@ MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
 static struct platform_driver s3c24xx_i2c_driver = {
 	.probe		= s3c24xx_i2c_probe,
 	.remove		= s3c24xx_i2c_remove,
-	.suspend_late	= s3c24xx_i2c_suspend_late,
-	.resume		= s3c24xx_i2c_resume,
 	.id_table	= s3c24xx_driver_ids,
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "s3c-i2c",
+		.pm	= S3C24XX_DEV_PM_OPS,
 	},
 };
 
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index 820487d..86a9d4e 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -28,6 +28,7 @@
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/err.h>
+#include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
@@ -165,7 +166,8 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
 	u_int32_t denom;
 	u_int32_t tmp;
 
-	/* Make sure the clock is enabled */
+	/* Wake up device and enable clock */
+	pm_runtime_get_sync(pd->dev);
 	clk_enable(pd->clk);
 
 	/* Get clock rate after clock is enabled */
@@ -213,8 +215,9 @@ static void deactivate_ch(struct sh_mobile_i2c_data *pd)
 	/* Disable channel */
 	iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
 
-	/* Disable clock */
+	/* Disable clock and mark device as idle */
 	clk_disable(pd->clk);
+	pm_runtime_put_sync(pd->dev);
 }
 
 static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
@@ -572,6 +575,19 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
 		goto err_irq;
 	}
 
+	/* Enable Runtime PM for this device.
+	 *
+	 * Also tell the Runtime PM core to ignore children
+	 * for this device since it is valid for us to suspend
+	 * this I2C master driver even though the slave devices
+	 * on the I2C bus may not be suspended.
+	 *
+	 * The state of the I2C hardware bus is unaffected by
+	 * the Runtime PM state.
+	 */
+	pm_suspend_ignore_children(&dev->dev, true);
+	pm_runtime_enable(&dev->dev);
+
 	/* setup the private data */
 	adap = &pd->adap;
 	i2c_set_adapdata(adap, pd);
@@ -614,14 +630,33 @@ static int sh_mobile_i2c_remove(struct platform_device *dev)
 	iounmap(pd->reg);
 	sh_mobile_i2c_hook_irqs(dev, 0);
 	clk_put(pd->clk);
+	pm_runtime_disable(&dev->dev);
 	kfree(pd);
 	return 0;
 }
 
+static int sh_mobile_i2c_runtime_nop(struct device *dev)
+{
+	/* Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * This driver re-initializes all registers after
+	 * pm_runtime_get_sync() anyway so there is no need
+	 * to save and restore registers here.
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
+	.runtime_suspend = sh_mobile_i2c_runtime_nop,
+	.runtime_resume = sh_mobile_i2c_runtime_nop,
+};
+
 static struct platform_driver sh_mobile_i2c_driver = {
 	.driver		= {
 		.name		= "i2c-sh_mobile",
 		.owner		= THIS_MODULE,
+		.pm		= &sh_mobile_i2c_dev_pm_ops,
 	},
 	.probe		= sh_mobile_i2c_probe,
 	.remove		= sh_mobile_i2c_remove,
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
index dbfeda4..248219a 100644
--- a/drivers/ide/at91_ide.c
+++ b/drivers/ide/at91_ide.c
@@ -29,9 +29,7 @@
 
 #include <mach/board.h>
 #include <mach/gpio.h>
-#include <mach/at91sam9263.h>
 #include <mach/at91sam9_smc.h>
-#include <mach/at91sam9263_matrix.h>
 
 #define DRV_NAME "at91_ide"
 
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 6a9a769..b79ca41 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -1146,8 +1147,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
 	ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
 				     curspeed, maxspeed);
 
-	cd->current_speed = (curspeed + (176/2)) / 176;
-	cd->max_speed = (maxspeed + (176/2)) / 176;
+	cd->current_speed = DIV_ROUND_CLOSEST(curspeed, 176);
+	cd->max_speed = DIV_ROUND_CLOSEST(maxspeed, 176);
 }
 
 #define IDE_CD_CAPABILITIES \
@@ -1389,19 +1390,30 @@ static sector_t ide_cdrom_capacity(ide_drive_t *drive)
 	return capacity * sectors_per_frame;
 }
 
-static int proc_idecd_read_capacity(char *page, char **start, off_t off,
-					int count, int *eof, void *data)
+static int idecd_capacity_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t *drive = data;
-	int len;
+	ide_drive_t *drive = m->private;
 
-	len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	seq_printf(m, "%llu\n", (long long)ide_cdrom_capacity(drive));
+	return 0;
+}
+
+static int idecd_capacity_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idecd_capacity_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations idecd_capacity_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= idecd_capacity_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static ide_proc_entry_t idecd_proc[] = {
-	{ "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
-	{ NULL, 0, NULL, NULL }
+	{ "capacity", S_IFREG|S_IRUGO, &idecd_capacity_proc_fops },
+	{}
 };
 
 static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 19f263b..60b0590 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -1,5 +1,6 @@
 #include <linux/kernel.h>
 #include <linux/ide.h>
+#include <linux/seq_file.h>
 
 #include "ide-disk.h"
 
@@ -37,77 +38,117 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
 	return ide_raw_taskfile(drive, &cmd, buf, 1);
 }
 
-static int proc_idedisk_read_cache
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int idedisk_cache_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
-	char		*out = page;
-	int		len;
+	ide_drive_t	*drive = (ide_drive_t *) m->private;
 
 	if (drive->dev_flags & IDE_DFLAG_ID_READ)
-		len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
+		seq_printf(m, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
 	else
-		len = sprintf(out, "(none)\n");
+		seq_printf(m, "(none)\n");
+	return 0;
+}
 
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int idedisk_cache_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idedisk_cache_proc_show, PDE(inode)->data);
 }
 
-static int proc_idedisk_read_capacity
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations idedisk_cache_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= idedisk_cache_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int idedisk_capacity_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t*drive = (ide_drive_t *)data;
-	int len;
+	ide_drive_t*drive = (ide_drive_t *)m->private;
 
-	len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
+	seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive));
+	return 0;
+}
 
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int idedisk_capacity_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idedisk_capacity_proc_show, PDE(inode)->data);
 }
 
-static int proc_idedisk_read_smart(char *page, char **start, off_t off,
-				   int count, int *eof, void *data, u8 sub_cmd)
+static const struct file_operations idedisk_capacity_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= idedisk_capacity_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __idedisk_proc_show(struct seq_file *m, ide_drive_t *drive, u8 sub_cmd)
 {
-	ide_drive_t	*drive = (ide_drive_t *)data;
-	int		len = 0, i = 0;
+	u8 *buf;
+
+	buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	(void)smart_enable(drive);
 
-	if (get_smart_data(drive, page, sub_cmd) == 0) {
-		unsigned short *val = (unsigned short *) page;
-		char *out = (char *)val + SECTOR_SIZE;
-
-		page = out;
-		do {
-			out += sprintf(out, "%04x%c", le16_to_cpu(*val),
-				       (++i & 7) ? ' ' : '\n');
-			val += 1;
-		} while (i < SECTOR_SIZE / 2);
-		len = out - page;
+	if (get_smart_data(drive, buf, sub_cmd) == 0) {
+		__le16 *val = (__le16 *)buf;
+		int i;
+
+		for (i = 0; i < SECTOR_SIZE / 2; i++) {
+			seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
+					(i % 8) == 7 ? '\n' : ' ');
+		}
 	}
+	kfree(buf);
+	return 0;
+}
 
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int idedisk_sv_proc_show(struct seq_file *m, void *v)
+{
+	return __idedisk_proc_show(m, m->private, ATA_SMART_READ_VALUES);
 }
 
-static int proc_idedisk_read_sv
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int idedisk_sv_proc_open(struct inode *inode, struct file *file)
 {
-	return proc_idedisk_read_smart(page, start, off, count, eof, data,
-				       ATA_SMART_READ_VALUES);
+	return single_open(file, idedisk_sv_proc_show, PDE(inode)->data);
 }
 
-static int proc_idedisk_read_st
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations idedisk_sv_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= idedisk_sv_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int idedisk_st_proc_show(struct seq_file *m, void *v)
 {
-	return proc_idedisk_read_smart(page, start, off, count, eof, data,
-				       ATA_SMART_READ_THRESHOLDS);
+	return __idedisk_proc_show(m, m->private, ATA_SMART_READ_THRESHOLDS);
 }
 
+static int idedisk_st_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idedisk_st_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations idedisk_st_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= idedisk_st_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 ide_proc_entry_t ide_disk_proc[] = {
-	{ "cache",	  S_IFREG|S_IRUGO, proc_idedisk_read_cache,    NULL },
-	{ "capacity",	  S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
-	{ "geometry",	  S_IFREG|S_IRUGO, proc_ide_read_geometry,     NULL },
-	{ "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv,       NULL },
-	{ "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st,   NULL },
-	{ NULL, 0, NULL, NULL }
+	{ "cache",	  S_IFREG|S_IRUGO, &idedisk_cache_proc_fops	},
+	{ "capacity",	  S_IFREG|S_IRUGO, &idedisk_capacity_proc_fops	},
+	{ "geometry",	  S_IFREG|S_IRUGO, &ide_geometry_proc_fops	},
+	{ "smart_values", S_IFREG|S_IRUSR, &idedisk_sv_proc_fops	},
+	{ "smart_thresholds", S_IFREG|S_IRUSR, &idedisk_st_proc_fops	},
+	{}
 };
 
 ide_devset_rw_field(bios_cyl, bios_cyl);
diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c
index fcd4d81..d711d9b 100644
--- a/drivers/ide/ide-floppy_proc.c
+++ b/drivers/ide/ide-floppy_proc.c
@@ -1,22 +1,34 @@
 #include <linux/kernel.h>
 #include <linux/ide.h>
+#include <linux/seq_file.h>
 
 #include "ide-floppy.h"
 
-static int proc_idefloppy_read_capacity(char *page, char **start, off_t off,
-		int count, int *eof, void *data)
+static int idefloppy_capacity_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t*drive = (ide_drive_t *)data;
-	int len;
+	ide_drive_t*drive = (ide_drive_t *)m->private;
 
-	len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive));
+	return 0;
 }
 
+static int idefloppy_capacity_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idefloppy_capacity_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations idefloppy_capacity_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= idefloppy_capacity_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 ide_proc_entry_t ide_floppy_proc[] = {
-	{ "capacity",	S_IFREG|S_IRUGO, proc_idefloppy_read_capacity,	NULL },
-	{ "geometry",	S_IFREG|S_IRUGO, proc_ide_read_geometry,	NULL },
-	{ NULL, 0, NULL, NULL }
+	{ "capacity",	S_IFREG|S_IRUGO, &idefloppy_capacity_proc_fops	},
+	{ "geometry",	S_IFREG|S_IRUGO, &ide_geometry_proc_fops	},
+	{}
 };
 
 ide_devset_rw_field(bios_cyl, bios_cyl);
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index e246d3d..d3440b5 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -167,6 +167,8 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
 			err = -EINVAL;
 			goto abort;
 		}
+
+		cmd.tf_flags |= IDE_TFLAG_SET_XFER;
 	}
 
 	err = ide_raw_taskfile(drive, &cmd, buf, args[3]);
@@ -174,12 +176,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
 	args[0] = tf->status;
 	args[1] = tf->error;
 	args[2] = tf->nsect;
-
-	if (!err && xfer_rate) {
-		/* active-retuning-calls future */
-		ide_set_xfer_rate(drive, xfer_rate);
-		ide_driveid_update(drive);
-	}
 abort:
 	if (copy_to_user((void __user *)arg, &args, 4))
 		err = -EFAULT;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 2892b24..222c1ef 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -102,8 +102,8 @@ EXPORT_SYMBOL(ide_fixstring);
  * setting a timer to wake up at half second intervals thereafter,
  * until timeout is achieved, before timing out.
  */
-static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
-			   unsigned long timeout, u8 *rstat)
+int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
+		    unsigned long timeout, u8 *rstat)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -292,6 +292,7 @@ static const char *nien_quirk_list[] = {
 	"QUANTUM FIREBALLP KX27.3",
 	"QUANTUM FIREBALLP LM20.4",
 	"QUANTUM FIREBALLP LM20.5",
+	"FUJITSU MHZ2160BH G2",
 	NULL
 };
 
@@ -316,7 +317,7 @@ int ide_driveid_update(ide_drive_t *drive)
 		return 0;
 
 	SELECT_MASK(drive, 1);
-	rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id);
+	rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id, 1);
 	SELECT_MASK(drive, 0);
 
 	if (rc)
@@ -363,14 +364,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 	 * this point (lost interrupt).
 	 */
 
-	/*
-	 *	FIXME: we race against the running IRQ here if
-	 *	this is called from non IRQ context. If we use
-	 *	disable_irq() we hang on the error path. Work
-	 *	is needed.
-	 */
-	disable_irq_nosync(hwif->irq);
-
 	udelay(1);
 	tp_ops->dev_select(drive);
 	SELECT_MASK(drive, 1);
@@ -394,8 +387,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
 
 	SELECT_MASK(drive, 0);
 
-	enable_irq(hwif->irq);
-
 	if (error) {
 		(void) ide_dump_status(drive, "set_drive_speed_status", stat);
 		return error;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 1bb106f..8de442c 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
  *	@drive: drive to identify
  *	@cmd: command to use
  *	@id: buffer for IDENTIFY data
+ *	@irq_ctx: flag set when called from the IRQ context
  *
  *	Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
  *
@@ -246,7 +247,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
  *			2  device aborted the command (refused to identify itself)
  */
 
-int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
+int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -263,7 +264,10 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
 		tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
 
 	/* take a deep breath */
-	msleep(50);
+	if (irq_ctx)
+		mdelay(50);
+	else
+		msleep(50);
 
 	if (io_ports->ctl_addr &&
 	    (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
@@ -295,12 +299,19 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
 
 	timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
 
-	if (ide_busy_sleep(drive, timeout, use_altstatus))
-		return 1;
-
 	/* wait for IRQ and ATA_DRQ */
-	msleep(50);
-	s = tp_ops->read_status(hwif);
+	if (irq_ctx) {
+		rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s);
+		if (rc)
+			return 1;
+	} else {
+		rc = ide_busy_sleep(drive, timeout, use_altstatus);
+		if (rc)
+			return 1;
+
+		msleep(50);
+		s = tp_ops->read_status(hwif);
+	}
 
 	if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
 		/* drive returned ID */
@@ -406,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
 
 	if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
 	    present || cmd == ATA_CMD_ID_ATAPI) {
-		rc = ide_dev_read_id(drive, cmd, id);
+		rc = ide_dev_read_id(drive, cmd, id, 0);
 		if (rc)
 			/* failed: try again */
-			rc = ide_dev_read_id(drive, cmd, id);
+			rc = ide_dev_read_id(drive, cmd, id, 0);
 
 		stat = tp_ops->read_status(hwif);
 
@@ -424,7 +435,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
 			msleep(50);
 			tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
 			(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
-			rc = ide_dev_read_id(drive, cmd, id);
+			rc = ide_dev_read_id(drive, cmd, id, 0);
 		}
 
 		/* ensure drive IRQ is clear */
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 3242698..28d09a5 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -30,11 +30,9 @@
 
 static struct proc_dir_entry *proc_ide_root;
 
-static int proc_ide_read_imodel
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_imodel_proc_show(struct seq_file *m, void *v)
 {
-	ide_hwif_t	*hwif = (ide_hwif_t *) data;
-	int		len;
+	ide_hwif_t	*hwif = (ide_hwif_t *) m->private;
 	const char	*name;
 
 	switch (hwif->chipset) {
@@ -53,63 +51,108 @@ static int proc_ide_read_imodel
 	case ide_acorn:		name = "acorn";		break;
 	default:		name = "(unknown)";	break;
 	}
-	len = sprintf(page, "%s\n", name);
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	seq_printf(m, "%s\n", name);
+	return 0;
 }
 
-static int proc_ide_read_mate
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_imodel_proc_open(struct inode *inode, struct file *file)
 {
-	ide_hwif_t	*hwif = (ide_hwif_t *) data;
-	int		len;
+	return single_open(file, ide_imodel_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations ide_imodel_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_imodel_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int ide_mate_proc_show(struct seq_file *m, void *v)
+{
+	ide_hwif_t	*hwif = (ide_hwif_t *) m->private;
 
 	if (hwif && hwif->mate)
-		len = sprintf(page, "%s\n", hwif->mate->name);
+		seq_printf(m, "%s\n", hwif->mate->name);
 	else
-		len = sprintf(page, "(none)\n");
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+		seq_printf(m, "(none)\n");
+	return 0;
+}
+
+static int ide_mate_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ide_mate_proc_show, PDE(inode)->data);
 }
 
-static int proc_ide_read_channel
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations ide_mate_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_mate_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int ide_channel_proc_show(struct seq_file *m, void *v)
 {
-	ide_hwif_t	*hwif = (ide_hwif_t *) data;
-	int		len;
+	ide_hwif_t	*hwif = (ide_hwif_t *) m->private;
 
-	page[0] = hwif->channel ? '1' : '0';
-	page[1] = '\n';
-	len = 2;
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	seq_printf(m, "%c\n", hwif->channel ? '1' : '0');
+	return 0;
 }
 
-static int proc_ide_read_identify
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_channel_proc_open(struct inode *inode, struct file *file)
 {
-	ide_drive_t	*drive = (ide_drive_t *)data;
-	int		len = 0, i = 0;
-	int		err = 0;
+	return single_open(file, ide_channel_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations ide_channel_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_channel_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
-	len = sprintf(page, "\n");
+static int ide_identify_proc_show(struct seq_file *m, void *v)
+{
+	ide_drive_t *drive = (ide_drive_t *)m->private;
+	u8 *buf;
 
-	if (drive) {
-		__le16 *val = (__le16 *)page;
+	if (!drive) {
+		seq_putc(m, '\n');
+		return 0;
+	}
 
-		err = taskfile_lib_get_identify(drive, page);
-		if (!err) {
-			char *out = (char *)page + SECTOR_SIZE;
+	buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	if (taskfile_lib_get_identify(drive, buf) == 0) {
+		__le16 *val = (__le16 *)buf;
+		int i;
 
-			page = out;
-			do {
-				out += sprintf(out, "%04x%c",
-					le16_to_cpup(val), (++i & 7) ? ' ' : '\n');
-				val += 1;
-			} while (i < SECTOR_SIZE / 2);
-			len = out - page;
+		for (i = 0; i < SECTOR_SIZE / 2; i++) {
+			seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
+					(i % 8) == 7 ? '\n' : ' ');
 		}
-	}
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	} else
+		seq_putc(m, buf[0]);
+	kfree(buf);
+	return 0;
+}
+
+static int ide_identify_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ide_identify_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations ide_identify_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_identify_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /**
  *	ide_find_setting	-	find a specific setting
  *	@st: setting table pointer
@@ -195,7 +238,6 @@ ide_devset_get(xfer_rate, current_speed);
 static int set_xfer_rate (ide_drive_t *drive, int arg)
 {
 	struct ide_cmd cmd;
-	int err;
 
 	if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
 		return -EINVAL;
@@ -206,14 +248,9 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
 	cmd.tf.nsect   = (u8)arg;
 	cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
 	cmd.valid.in.tf  = IDE_VALID_NSECT;
+	cmd.tf_flags   = IDE_TFLAG_SET_XFER;
 
-	err = ide_no_data_taskfile(drive, &cmd);
-
-	if (!err) {
-		ide_set_xfer_rate(drive, (u8) arg);
-		ide_driveid_update(drive);
-	}
-	return err;
+	return ide_no_data_taskfile(drive, &cmd);
 }
 
 ide_devset_rw(current_speed, xfer_rate);
@@ -246,22 +283,20 @@ static void proc_ide_settings_warn(void)
 	warned = 1;
 }
 
-static int proc_ide_read_settings
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_settings_proc_show(struct seq_file *m, void *v)
 {
 	const struct ide_proc_devset *setting, *g, *d;
 	const struct ide_devset *ds;
-	ide_drive_t	*drive = (ide_drive_t *) data;
-	char		*out = page;
-	int		len, rc, mul_factor, div_factor;
+	ide_drive_t	*drive = (ide_drive_t *) m->private;
+	int		rc, mul_factor, div_factor;
 
 	proc_ide_settings_warn();
 
 	mutex_lock(&ide_setting_mtx);
 	g = ide_generic_settings;
 	d = drive->settings;
-	out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
-	out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
+	seq_printf(m, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
+	seq_printf(m, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
 	while (g->name || (d && d->name)) {
 		/* read settings in the alphabetical order */
 		if (g->name && d && d->name) {
@@ -275,31 +310,35 @@ static int proc_ide_read_settings
 			setting = g++;
 		mul_factor = setting->mulf ? setting->mulf(drive) : 1;
 		div_factor = setting->divf ? setting->divf(drive) : 1;
-		out += sprintf(out, "%-24s", setting->name);
+		seq_printf(m, "%-24s", setting->name);
 		rc = ide_read_setting(drive, setting);
 		if (rc >= 0)
-			out += sprintf(out, "%-16d", rc * mul_factor / div_factor);
+			seq_printf(m, "%-16d", rc * mul_factor / div_factor);
 		else
-			out += sprintf(out, "%-16s", "write-only");
-		out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
+			seq_printf(m, "%-16s", "write-only");
+		seq_printf(m, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
 		ds = setting->setting;
 		if (ds->get)
-			out += sprintf(out, "r");
+			seq_printf(m, "r");
 		if (ds->set)
-			out += sprintf(out, "w");
-		out += sprintf(out, "\n");
+			seq_printf(m, "w");
+		seq_printf(m, "\n");
 	}
-	len = out - page;
 	mutex_unlock(&ide_setting_mtx);
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	return 0;
+}
+
+static int ide_settings_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ide_settings_proc_show, PDE(inode)->data);
 }
 
 #define MAX_LEN	30
 
-static int proc_ide_write_settings(struct file *file, const char __user *buffer,
-				   unsigned long count, void *data)
+static ssize_t ide_settings_proc_write(struct file *file, const char __user *buffer,
+				       size_t count, loff_t *pos)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	ide_drive_t	*drive = (ide_drive_t *) PDE(file->f_path.dentry->d_inode)->data;
 	char		name[MAX_LEN + 1];
 	int		for_real = 0, mul_factor, div_factor;
 	unsigned long	n;
@@ -394,63 +433,104 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
 	return count;
 parse_error:
 	free_page((unsigned long)buf);
-	printk("proc_ide_write_settings(): parse error\n");
+	printk("%s(): parse error\n", __func__);
 	return -EINVAL;
 }
 
-int proc_ide_read_capacity
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations ide_settings_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_settings_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= ide_settings_proc_write,
+};
+
+static int ide_capacity_proc_show(struct seq_file *m, void *v)
+{
+	seq_printf(m, "%llu\n", (long long)0x7fffffff);
+	return 0;
+}
+
+static int ide_capacity_proc_open(struct inode *inode, struct file *file)
 {
-	int len = sprintf(page, "%llu\n", (long long)0x7fffffff);
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	return single_open(file, ide_capacity_proc_show, NULL);
 }
 
-EXPORT_SYMBOL_GPL(proc_ide_read_capacity);
+const struct file_operations ide_capacity_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_capacity_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+EXPORT_SYMBOL_GPL(ide_capacity_proc_fops);
 
-int proc_ide_read_geometry
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_geometry_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
-	char		*out = page;
-	int		len;
+	ide_drive_t	*drive = (ide_drive_t *) m->private;
 
-	out += sprintf(out, "physical     %d/%d/%d\n",
+	seq_printf(m, "physical     %d/%d/%d\n",
 			drive->cyl, drive->head, drive->sect);
-	out += sprintf(out, "logical      %d/%d/%d\n",
+	seq_printf(m, "logical      %d/%d/%d\n",
 			drive->bios_cyl, drive->bios_head, drive->bios_sect);
+	return 0;
+}
 
-	len = out - page;
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int ide_geometry_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ide_geometry_proc_show, PDE(inode)->data);
 }
 
-EXPORT_SYMBOL(proc_ide_read_geometry);
+const struct file_operations ide_geometry_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_geometry_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+EXPORT_SYMBOL(ide_geometry_proc_fops);
 
-static int proc_ide_read_dmodel
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_dmodel_proc_show(struct seq_file *seq, void *v)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	ide_drive_t	*drive = (ide_drive_t *) seq->private;
 	char		*m = (char *)&drive->id[ATA_ID_PROD];
-	int		len;
 
-	len = sprintf(page, "%.40s\n", m[0] ? m : "(none)");
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	seq_printf(seq, "%.40s\n", m[0] ? m : "(none)");
+	return 0;
+}
+
+static int ide_dmodel_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ide_dmodel_proc_show, PDE(inode)->data);
 }
 
-static int proc_ide_read_driver
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations ide_dmodel_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_dmodel_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int ide_driver_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t		*drive = (ide_drive_t *)data;
+	ide_drive_t		*drive = (ide_drive_t *)m->private;
 	struct device		*dev = &drive->gendev;
 	struct ide_driver	*ide_drv;
-	int			len;
 
 	if (dev->driver) {
 		ide_drv = to_ide_driver(dev->driver);
-		len = sprintf(page, "%s version %s\n",
+		seq_printf(m, "%s version %s\n",
 				dev->driver->name, ide_drv->version);
 	} else
-		len = sprintf(page, "ide-default version 0.9.newide\n");
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+		seq_printf(m, "ide-default version 0.9.newide\n");
+	return 0;
+}
+
+static int ide_driver_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ide_driver_proc_show, PDE(inode)->data);
 }
 
 static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
@@ -480,10 +560,10 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
 	return ret;
 }
 
-static int proc_ide_write_driver
-	(struct file *file, const char __user *buffer, unsigned long count, void *data)
+static ssize_t ide_driver_proc_write(struct file *file, const char __user *buffer,
+				     size_t count, loff_t *pos)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	ide_drive_t	*drive = (ide_drive_t *) PDE(file->f_path.dentry->d_inode)->data;
 	char name[32];
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -498,12 +578,19 @@ static int proc_ide_write_driver
 	return count;
 }
 
-static int proc_ide_read_media
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations ide_driver_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_driver_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= ide_driver_proc_write,
+};
+
+static int ide_media_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	ide_drive_t	*drive = (ide_drive_t *) m->private;
 	const char	*media;
-	int		len;
 
 	switch (drive->media) {
 	case ide_disk:		media = "disk\n";	break;
@@ -513,20 +600,30 @@ static int proc_ide_read_media
 	case ide_optical:	media = "optical\n";	break;
 	default:		media = "UNKNOWN\n";	break;
 	}
-	strcpy(page, media);
-	len = strlen(media);
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	seq_puts(m, media);
+	return 0;
+}
+
+static int ide_media_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ide_media_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations ide_media_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= ide_media_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static ide_proc_entry_t generic_drive_entries[] = {
-	{ "driver",	S_IFREG|S_IRUGO,	 proc_ide_read_driver,
-						 proc_ide_write_driver },
-	{ "identify",	S_IFREG|S_IRUSR,	 proc_ide_read_identify, NULL },
-	{ "media",	S_IFREG|S_IRUGO,	 proc_ide_read_media,    NULL },
-	{ "model",	S_IFREG|S_IRUGO,	 proc_ide_read_dmodel,   NULL },
-	{ "settings",	S_IFREG|S_IRUSR|S_IWUSR, proc_ide_read_settings,
-						 proc_ide_write_settings },
-	{ NULL,	0, NULL, NULL }
+	{ "driver",	S_IFREG|S_IRUGO,	 &ide_driver_proc_fops	},
+	{ "identify",	S_IFREG|S_IRUSR,	 &ide_identify_proc_fops},
+	{ "media",	S_IFREG|S_IRUGO,	 &ide_media_proc_fops	},
+	{ "model",	S_IFREG|S_IRUGO,	 &ide_dmodel_proc_fops	},
+	{ "settings",	S_IFREG|S_IRUSR|S_IWUSR, &ide_settings_proc_fops},
+	{}
 };
 
 static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data)
@@ -536,11 +633,8 @@ static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p
 	if (!dir || !p)
 		return;
 	while (p->name != NULL) {
-		ent = create_proc_entry(p->name, p->mode, dir);
+		ent = proc_create_data(p->name, p->mode, dir, p->proc_fops, data);
 		if (!ent) return;
-		ent->data = data;
-		ent->read_proc = p->read_proc;
-		ent->write_proc = p->write_proc;
 		p++;
 	}
 }
@@ -623,10 +717,10 @@ void ide_proc_unregister_device(ide_drive_t *drive)
 }
 
 static ide_proc_entry_t hwif_entries[] = {
-	{ "channel",	S_IFREG|S_IRUGO,	proc_ide_read_channel,	NULL },
-	{ "mate",	S_IFREG|S_IRUGO,	proc_ide_read_mate,	NULL },
-	{ "model",	S_IFREG|S_IRUGO,	proc_ide_read_imodel,	NULL },
-	{ NULL,	0, NULL, NULL }
+	{ "channel",	S_IFREG|S_IRUGO,	&ide_channel_proc_fops	},
+	{ "mate",	S_IFREG|S_IRUGO,	&ide_mate_proc_fops	},
+	{ "model",	S_IFREG|S_IRUGO,	&ide_imodel_proc_fops	},
+	{}
 };
 
 void ide_proc_register_port(ide_hwif_t *hwif)
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index bc5fb12..9d6f62b 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -31,6 +31,7 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/genhd.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
@@ -47,28 +48,13 @@
 #include <asm/unaligned.h>
 #include <linux/mtio.h>
 
-enum {
-	/* output errors only */
-	DBG_ERR =		(1 << 0),
-	/* output all sense key/asc */
-	DBG_SENSE =		(1 << 1),
-	/* info regarding all chrdev-related procedures */
-	DBG_CHRDEV =		(1 << 2),
-	/* all remaining procedures */
-	DBG_PROCS =		(1 << 3),
-};
-
 /* define to see debug info */
-#define IDETAPE_DEBUG_LOG		0
+#undef IDETAPE_DEBUG_LOG
 
-#if IDETAPE_DEBUG_LOG
-#define debug_log(lvl, fmt, args...)			\
-{							\
-	if (tape->debug_mask & lvl)			\
-	printk(KERN_INFO "ide-tape: " fmt, ## args);	\
-}
+#ifdef IDETAPE_DEBUG_LOG
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
 #else
-#define debug_log(lvl, fmt, args...) do {} while (0)
+#define ide_debug_log(lvl, fmt, args...) do {} while (0)
 #endif
 
 /**************************** Tunable parameters *****************************/
@@ -170,7 +156,8 @@ typedef struct ide_tape_obj {
 	 * other device. Note that at most we will have only one DSC (usually
 	 * data transfer) request in the device request queue.
 	 */
-	struct request *postponed_rq;
+	bool postponed_rq;
+
 	/* The time in which we started polling for DSC */
 	unsigned long dsc_polling_start;
 	/* Timer used to poll for dsc */
@@ -230,8 +217,6 @@ typedef struct ide_tape_obj {
 	char drv_write_prot;
 	/* the tape is write protected (hardware or opened as read-only) */
 	char write_prot;
-
-	u32 debug_mask;
 } idetape_tape_t;
 
 static DEFINE_MUTEX(idetape_ref_mutex);
@@ -290,8 +275,9 @@ static void idetape_analyze_error(ide_drive_t *drive)
 	tape->asc       = sense[12];
 	tape->ascq      = sense[13];
 
-	debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n",
-		 pc->c[0], tape->sense_key, tape->asc, tape->ascq);
+	ide_debug_log(IDE_DBG_FUNC,
+		      "cmd: 0x%x, sense key = %x, asc = %x, ascq = %x",
+		      rq->cmd[0], tape->sense_key, tape->asc, tape->ascq);
 
 	/* correct remaining bytes to transfer */
 	if (pc->flags & PC_FLAG_DMA_ERROR)
@@ -344,7 +330,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
 	int uptodate = pc->error ? 0 : 1;
 	int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
 
-	debug_log(DBG_PROCS, "Enter %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc: %d, err: %d", rq->cmd[0],
+		      dsc, err);
 
 	if (dsc)
 		ide_tape_handle_dsc(drive);
@@ -387,13 +374,14 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
  * Postpone the current request so that ide.c will be able to service requests
  * from another device on the same port while we are polling for DSC.
  */
-static void idetape_postpone_request(ide_drive_t *drive)
+static void ide_tape_stall_queue(ide_drive_t *drive)
 {
 	idetape_tape_t *tape = drive->driver_data;
 
-	debug_log(DBG_PROCS, "Enter %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc_poll_freq: %lu",
+		      drive->hwif->rq->cmd[0], tape->dsc_poll_freq);
 
-	tape->postponed_rq = drive->hwif->rq;
+	tape->postponed_rq = true;
 
 	ide_stall_queue(drive, tape->dsc_poll_freq);
 }
@@ -407,7 +395,7 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
 	tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST;
 	tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
 	/* Allow ide.c to handle other requests */
-	idetape_postpone_request(drive);
+	ide_tape_stall_queue(drive);
 }
 
 /*
@@ -488,7 +476,8 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
 		ide_complete_rq(drive, -EIO, blk_rq_bytes(rq));
 		return ide_stopped;
 	}
-	debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
+	ide_debug_log(IDE_DBG_SENSE, "retry #%d, cmd: 0x%02x", pc->retries,
+		      pc->c[0]);
 
 	pc->retries++;
 
@@ -579,12 +568,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
 	ide_hwif_t *hwif = drive->hwif;
 	idetape_tape_t *tape = drive->driver_data;
 	struct ide_atapi_pc *pc = NULL;
-	struct request *postponed_rq = tape->postponed_rq;
 	struct ide_cmd cmd;
 	u8 stat;
 
-	debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n"
-		  (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq));
+	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, sector: %llu, nr_sectors: %u",
+		      rq->cmd[0], (unsigned long long)blk_rq_pos(rq),
+		      blk_rq_sectors(rq));
 
 	BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq)));
 
@@ -594,18 +583,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
 		goto out;
 	}
 
-	if (postponed_rq != NULL)
-		if (rq != postponed_rq) {
-			printk(KERN_ERR "ide-tape: ide-tape.c bug - "
-					"Two DSC requests were queued\n");
-			drive->failed_pc = NULL;
-			rq->errors = 0;
-			ide_complete_rq(drive, 0, blk_rq_bytes(rq));
-			return ide_stopped;
-		}
-
-	tape->postponed_rq = NULL;
-
 	/*
 	 * If the tape is still busy, postpone our request and service
 	 * the other device meanwhile.
@@ -623,7 +600,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
 
 	if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) &&
 	    !(stat & ATA_DSC)) {
-		if (postponed_rq == NULL) {
+		if (!tape->postponed_rq) {
 			tape->dsc_polling_start = jiffies;
 			tape->dsc_poll_freq = tape->best_dsc_rw_freq;
 			tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
@@ -640,10 +617,12 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
 					tape->dsc_polling_start +
 					IDETAPE_DSC_MA_THRESHOLD))
 			tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW;
-		idetape_postpone_request(drive);
+		ide_tape_stall_queue(drive);
 		return ide_stopped;
-	} else
+	} else {
 		drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC;
+		tape->postponed_rq = false;
+	}
 
 	if (rq->cmd[13] & REQ_IDETAPE_READ) {
 		pc = &tape->queued_pc;
@@ -745,7 +724,7 @@ static int ide_tape_read_position(ide_drive_t *drive)
 	struct ide_atapi_pc pc;
 	u8 buf[20];
 
-	debug_log(DBG_PROCS, "Enter %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	/* prep cmd */
 	ide_init_pc(&pc);
@@ -756,9 +735,9 @@ static int ide_tape_read_position(ide_drive_t *drive)
 		return -1;
 
 	if (!pc.error) {
-		debug_log(DBG_SENSE, "BOP - %s\n",
+		ide_debug_log(IDE_DBG_FUNC, "BOP - %s",
 				(buf[0] & 0x80) ? "Yes" : "No");
-		debug_log(DBG_SENSE, "EOP - %s\n",
+		ide_debug_log(IDE_DBG_FUNC, "EOP - %s",
 				(buf[0] & 0x40) ? "Yes" : "No");
 
 		if (buf[0] & 0x4) {
@@ -768,8 +747,8 @@ static int ide_tape_read_position(ide_drive_t *drive)
 				  &drive->atapi_flags);
 			return -1;
 		} else {
-			debug_log(DBG_SENSE, "Block Location - %u\n",
-					be32_to_cpup((__be32 *)&buf[4]));
+			ide_debug_log(IDE_DBG_FUNC, "Block Location: %u",
+				      be32_to_cpup((__be32 *)&buf[4]));
 
 			tape->partition = buf[1];
 			tape->first_frame = be32_to_cpup((__be32 *)&buf[4]);
@@ -866,7 +845,8 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
 	struct request *rq;
 	int ret;
 
-	debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd);
+	ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, size: %d", cmd, size);
+
 	BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE);
 	BUG_ON(size < 0 || size % tape->blk_size);
 
@@ -1029,7 +1009,7 @@ static int idetape_rewind_tape(ide_drive_t *drive)
 	struct ide_atapi_pc pc;
 	int ret;
 
-	debug_log(DBG_SENSE, "Enter %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	idetape_create_rewind_cmd(drive, &pc);
 	ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
@@ -1055,7 +1035,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
 		int nr_stages;
 	} config;
 
-	debug_log(DBG_PROCS, "Enter %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%04x", cmd);
 
 	switch (cmd) {
 	case 0x0340:
@@ -1085,6 +1065,9 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
 	int retval, count = 0;
 	int sprev = !!(tape->caps[4] & 0x20);
 
+
+	ide_debug_log(IDE_DBG_FUNC, "mt_op: %d, mt_count: %d", mt_op, mt_count);
+
 	if (mt_count == 0)
 		return 0;
 	if (MTBSF == mt_op || MTBSFM == mt_op) {
@@ -1148,7 +1131,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
 	ssize_t ret = 0;
 	int rc;
 
-	debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
+	ide_debug_log(IDE_DBG_FUNC, "count %Zd", count);
 
 	if (tape->chrdev_dir != IDETAPE_DIR_READ) {
 		if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags))
@@ -1187,8 +1170,6 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
 	}
 
 	if (!done && test_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags)) {
-		debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);
-
 		idetape_space_over_filemarks(drive, MTFSF, 1);
 		return 0;
 	}
@@ -1209,7 +1190,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
 	if (tape->write_prot)
 		return -EACCES;
 
-	debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
+	ide_debug_log(IDE_DBG_FUNC, "count %Zd", count);
 
 	/* Initialize write operation */
 	rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE);
@@ -1273,8 +1254,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
 	struct ide_atapi_pc pc;
 	int i, retval;
 
-	debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n",
-			mt_op, mt_count);
+	ide_debug_log(IDE_DBG_FUNC, "MTIOCTOP ioctl: mt_op: %d, mt_count: %d",
+		      mt_op, mt_count);
 
 	switch (mt_op) {
 	case MTFSF:
@@ -1393,7 +1374,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
 	int block_offset = 0, position = tape->first_frame;
 	void __user *argp = (void __user *)arg;
 
-	debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd);
+	ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x", cmd);
 
 	if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
 		ide_tape_flush_merge_buffer(drive);
@@ -1461,6 +1442,9 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
 				(buf[4 + 6] << 8)  +
 				 buf[4 + 7];
 	tape->drv_write_prot = (buf[2] & 0x80) >> 7;
+
+	ide_debug_log(IDE_DBG_FUNC, "blk_size: %d, write_prot: %d",
+		      tape->blk_size, tape->drv_write_prot);
 }
 
 static int idetape_chrdev_open(struct inode *inode, struct file *filp)
@@ -1480,7 +1464,10 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
 		return -ENXIO;
 	}
 
-	debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
+	drive = tape->drive;
+	filp->private_data = tape;
+
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	/*
 	 * We really want to do nonseekable_open(inode, filp); here, but some
@@ -1489,9 +1476,6 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
 	 */
 	filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
 
-	drive = tape->drive;
-
-	filp->private_data = tape;
 
 	if (test_and_set_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags)) {
 		retval = -EBUSY;
@@ -1570,7 +1554,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
 	lock_kernel();
 	tape = drive->driver_data;
 
-	debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
+	ide_debug_log(IDE_DBG_FUNC, "enter");
 
 	if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
 		idetape_write_release(drive, minor);
@@ -1707,7 +1691,6 @@ static int divf_buffer_size(ide_drive_t *drive)	{ return 1024; }
 
 ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP);
 
-ide_tape_devset_rw_field(debug_mask, debug_mask);
 ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq);
 
 ide_tape_devset_r_field(avg_speed, avg_speed);
@@ -1719,7 +1702,6 @@ static const struct ide_proc_devset idetape_settings[] = {
 	__IDE_PROC_DEVSET(avg_speed,	0, 0xffff, NULL, NULL),
 	__IDE_PROC_DEVSET(buffer,	0, 0xffff, NULL, divf_buffer),
 	__IDE_PROC_DEVSET(buffer_size,	0, 0xffff, NULL, divf_buffer_size),
-	__IDE_PROC_DEVSET(debug_mask,	0, 0xffff, NULL, NULL),
 	__IDE_PROC_DEVSET(dsc_overlap,	0,      1, NULL, NULL),
 	__IDE_PROC_DEVSET(speed,	0, 0xffff, NULL, NULL),
 	__IDE_PROC_DEVSET(tdsc,		IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
@@ -1746,7 +1728,9 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
 	int buffer_size;
 	u16 *ctl = (u16 *)&tape->caps[12];
 
-	drive->pc_callback	 = ide_tape_callback;
+	ide_debug_log(IDE_DBG_FUNC, "minor: %d", minor);
+
+	drive->pc_callback = ide_tape_callback;
 
 	drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
 
@@ -1833,22 +1817,32 @@ static void ide_tape_release(struct device *dev)
 }
 
 #ifdef CONFIG_IDE_PROC_FS
-static int proc_idetape_read_name
-	(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int idetape_name_proc_show(struct seq_file *m, void *v)
 {
-	ide_drive_t	*drive = (ide_drive_t *) data;
+	ide_drive_t	*drive = (ide_drive_t *) m->private;
 	idetape_tape_t	*tape = drive->driver_data;
-	char		*out = page;
-	int		len;
 
-	len = sprintf(out, "%s\n", tape->name);
-	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+	seq_printf(m, "%s\n", tape->name);
+	return 0;
+}
+
+static int idetape_name_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, idetape_name_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations idetape_name_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= idetape_name_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static ide_proc_entry_t idetape_proc[] = {
-	{ "capacity",	S_IFREG|S_IRUGO,	proc_ide_read_capacity, NULL },
-	{ "name",	S_IFREG|S_IRUGO,	proc_idetape_read_name,	NULL },
-	{ NULL, 0, NULL, NULL }
+	{ "capacity",	S_IFREG|S_IRUGO,	&ide_capacity_proc_fops	},
+	{ "name",	S_IFREG|S_IRUGO,	&idetape_name_proc_fops	},
+	{}
 };
 
 static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive)
@@ -1932,7 +1926,9 @@ static int ide_tape_probe(ide_drive_t *drive)
 	struct gendisk *g;
 	int minor;
 
-	if (!strstr("ide-tape", drive->driver_req))
+	ide_debug_log(IDE_DBG_FUNC, "enter");
+
+	if (!strstr(DRV_NAME, drive->driver_req))
 		goto failed;
 
 	if (drive->media != ide_tape)
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 75b85a8..cc8633c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -19,8 +19,8 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
+#include <linux/uaccess.h>
 
-#include <asm/uaccess.h>
 #include <asm/io.h>
 
 void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
@@ -53,7 +53,7 @@ void ide_tf_dump(const char *s, struct ide_cmd *cmd)
 #endif
 }
 
-int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
+int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf)
 {
 	struct ide_cmd cmd;
 
@@ -86,7 +86,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
 	if (orig_cmd->protocol == ATA_PROT_PIO &&
 	    (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
 	    drive->mult_count == 0) {
-		printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+		pr_err("%s: multimode not set!\n", drive->name);
 		return ide_stopped;
 	}
 
@@ -214,7 +214,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
 	}
 
 	if (stat & ATA_BUSY)
-		printk(KERN_ERR "%s: drive still BUSY!\n", drive->name);
+		pr_err("%s: drive still BUSY!\n", drive->name);
 
 	return stat;
 }
@@ -225,8 +225,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
 	struct scatterlist *cursg = cmd->cursg;
+	unsigned long uninitialized_var(flags);
 	struct page *page;
-	unsigned long flags;
 	unsigned int offset;
 	u8 *buf;
 
@@ -236,6 +236,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
 
 	while (len) {
 		unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
+		int page_is_high;
 
 		if (nr_bytes > PAGE_SIZE)
 			nr_bytes = PAGE_SIZE;
@@ -247,7 +248,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
 		page = nth_page(page, (offset >> PAGE_SHIFT));
 		offset %= PAGE_SIZE;
 
-		if (PageHighMem(page))
+		page_is_high = PageHighMem(page);
+		if (page_is_high)
 			local_irq_save(flags);
 
 		buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
@@ -268,7 +270,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
 
 		kunmap_atomic(buf, KM_BIO_SRC_IRQ);
 
-		if (PageHighMem(page))
+		if (page_is_high)
 			local_irq_restore(flags);
 
 		len -= nr_bytes;
@@ -322,10 +324,17 @@ static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
 void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
 {
 	struct request *rq = drive->hwif->rq;
-	u8 err = ide_read_error(drive);
+	u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
+	u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
 
 	ide_complete_cmd(drive, cmd, stat, err);
 	rq->errors = err;
+
+	if (err == 0 && set_xfer) {
+		ide_set_xfer_rate(drive, nsect);
+		ide_driveid_update(drive);
+	}
+
 	ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
 }
 
@@ -398,8 +407,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
 
 	if (ide_wait_stat(&startstop, drive, ATA_DRQ,
 			  drive->bad_wstat, WAIT_DRQ)) {
-		printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
-			drive->name,
+		pr_err("%s: no DRQ after issuing %sWRITE%s\n", drive->name,
 			(cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
 			(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
 		return startstop;
@@ -449,7 +457,6 @@ put_req:
 	blk_put_request(rq);
 	return error;
 }
-
 EXPORT_SYMBOL(ide_raw_taskfile);
 
 int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
@@ -475,10 +482,9 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 	u16 nsect		= 0;
 	char __user *buf = (char __user *)arg;
 
-//	printk("IDE Taskfile ...\n");
-
 	req_task = kzalloc(tasksize, GFP_KERNEL);
-	if (req_task == NULL) return -ENOMEM;
+	if (req_task == NULL)
+		return -ENOMEM;
 	if (copy_from_user(req_task, buf, tasksize)) {
 		kfree(req_task);
 		return -EFAULT;
@@ -486,7 +492,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 
 	taskout = req_task->out_size;
 	taskin  = req_task->in_size;
-	
+
 	if (taskin > 65536 || taskout > 65536) {
 		err = -EINVAL;
 		goto abort;
@@ -576,51 +582,49 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 	cmd.protocol = ATA_PROT_DMA;
 
 	switch (req_task->data_phase) {
-		case TASKFILE_MULTI_OUT:
-			if (!drive->mult_count) {
-				/* (hs): give up if multcount is not set */
-				printk(KERN_ERR "%s: %s Multimode Write " \
-					"multcount is not set\n",
-					drive->name, __func__);
-				err = -EPERM;
-				goto abort;
-			}
-			cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
-			/* fall through */
-		case TASKFILE_OUT:
-			cmd.protocol = ATA_PROT_PIO;
-			/* fall through */
-		case TASKFILE_OUT_DMAQ:
-		case TASKFILE_OUT_DMA:
-			cmd.tf_flags |= IDE_TFLAG_WRITE;
-			nsect = taskout / SECTOR_SIZE;
-			data_buf = outbuf;
-			break;
-		case TASKFILE_MULTI_IN:
-			if (!drive->mult_count) {
-				/* (hs): give up if multcount is not set */
-				printk(KERN_ERR "%s: %s Multimode Read failure " \
-					"multcount is not set\n",
-					drive->name, __func__);
-				err = -EPERM;
-				goto abort;
-			}
-			cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
-			/* fall through */
-		case TASKFILE_IN:
-			cmd.protocol = ATA_PROT_PIO;
-			/* fall through */
-		case TASKFILE_IN_DMAQ:
-		case TASKFILE_IN_DMA:
-			nsect = taskin / SECTOR_SIZE;
-			data_buf = inbuf;
-			break;
-		case TASKFILE_NO_DATA:
-			cmd.protocol = ATA_PROT_NODATA;
-			break;
-		default:
-			err = -EFAULT;
+	case TASKFILE_MULTI_OUT:
+		if (!drive->mult_count) {
+			/* (hs): give up if multcount is not set */
+			pr_err("%s: %s Multimode Write multcount is not set\n",
+				drive->name, __func__);
+			err = -EPERM;
+			goto abort;
+		}
+		cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
+		/* fall through */
+	case TASKFILE_OUT:
+		cmd.protocol = ATA_PROT_PIO;
+		/* fall through */
+	case TASKFILE_OUT_DMAQ:
+	case TASKFILE_OUT_DMA:
+		cmd.tf_flags |= IDE_TFLAG_WRITE;
+		nsect = taskout / SECTOR_SIZE;
+		data_buf = outbuf;
+		break;
+	case TASKFILE_MULTI_IN:
+		if (!drive->mult_count) {
+			/* (hs): give up if multcount is not set */
+			pr_err("%s: %s Multimode Read multcount is not set\n",
+				drive->name, __func__);
+			err = -EPERM;
 			goto abort;
+		}
+		cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
+		/* fall through */
+	case TASKFILE_IN:
+		cmd.protocol = ATA_PROT_PIO;
+		/* fall through */
+	case TASKFILE_IN_DMAQ:
+	case TASKFILE_IN_DMA:
+		nsect = taskin / SECTOR_SIZE;
+		data_buf = inbuf;
+		break;
+	case TASKFILE_NO_DATA:
+		cmd.protocol = ATA_PROT_NODATA;
+		break;
+	default:
+		err = -EFAULT;
+		goto abort;
 	}
 
 	if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
@@ -629,7 +633,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 		nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
 
 		if (!nsect) {
-			printk(KERN_ERR "%s: in/out command without data\n",
+			pr_err("%s: in/out command without data\n",
 					drive->name);
 			err = -EFAULT;
 			goto abort;
@@ -671,8 +675,6 @@ abort:
 	kfree(outbuf);
 	kfree(inbuf);
 
-//	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
-
 	return err;
 }
 #endif
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index 3c1dc01..f8eddf0 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -318,7 +318,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
 	int i, rc;
 	struct ide_hw hw, *hws[] = { &hw };
 
-	clk = clk_get(&pdev->dev, "IDECLK");
+	clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(clk))
 		return -ENODEV;
 
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index f5c586c..a4e9dcb 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -169,10 +169,11 @@ static int ether1394_header_cache(const struct neighbour *neigh,
 static void ether1394_header_cache_update(struct hh_cache *hh,
 					  const struct net_device *dev,
 					  const unsigned char *haddr);
-static int ether1394_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ether1394_tx(struct sk_buff *skb,
+				struct net_device *dev);
 static void ether1394_iso(struct hpsb_iso *iso);
 
-static struct ethtool_ops ethtool_ops;
+static const struct ethtool_ops ethtool_ops;
 
 static int ether1394_write(struct hpsb_host *host, int srcid, int destid,
 			   quadlet_t *data, u64 addr, size_t len, u16 flags);
@@ -1300,7 +1301,6 @@ static void ether1394_iso(struct hpsb_iso *iso)
 
 	hpsb_iso_recv_release_packets(iso, i);
 
-	dev->last_rx = jiffies;
 }
 
 /******************************************
@@ -1555,7 +1555,8 @@ static void ether1394_complete_cb(void *__ptask)
 }
 
 /* Transmit a packet (called by kernel) */
-static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ether1394_tx(struct sk_buff *skb,
+				struct net_device *dev)
 {
 	struct eth1394hdr hdr_buf;
 	struct eth1394_priv *priv = netdev_priv(dev);
@@ -1694,14 +1695,6 @@ fail:
 	dev->stats.tx_errors++;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/*
-	 * FIXME: According to a patch from 2003-02-26, "returning non-zero
-	 * causes serious problems" here, allegedly.  Before that patch,
-	 * -ERRNO was returned which is not appropriate under Linux 2.6.
-	 * Perhaps more needs to be done?  Stop the queue in serious
-	 * conditions and restart it elsewhere?
-	 */
-	/* return NETDEV_TX_BUSY; */
 	return NETDEV_TX_OK;
 }
 
@@ -1712,7 +1705,7 @@ static void ether1394_get_drvinfo(struct net_device *dev,
 	strcpy(info->bus_info, "ieee1394"); /* FIXME provide more detail? */
 }
 
-static struct ethtool_ops ethtool_ops = {
+static const struct ethtool_ops ethtool_ops = {
 	.get_drvinfo = ether1394_get_drvinfo
 };
 
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
index 0384144..96a2959 100644
--- a/drivers/ieee802154/fakehard.c
+++ b/drivers/ieee802154/fakehard.c
@@ -26,11 +26,23 @@
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 
-#include <net/ieee802154/af_ieee802154.h>
-#include <net/ieee802154/netdevice.h>
-#include <net/ieee802154/mac_def.h>
-#include <net/ieee802154/nl802154.h>
+#include <net/af_ieee802154.h>
+#include <net/ieee802154_netdev.h>
+#include <net/ieee802154.h>
+#include <net/nl802154.h>
+#include <net/wpan-phy.h>
 
+struct wpan_phy *net_to_phy(struct net_device *dev)
+{
+	return container_of(dev->dev.parent, struct wpan_phy, dev);
+}
+
+/**
+ * fake_get_pan_id - Retrieve the PAN ID of the device.
+ * @dev: The network device to retrieve the PAN of.
+ *
+ * Return the ID of the PAN from the PIB.
+ */
 static u16 fake_get_pan_id(struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -38,6 +50,14 @@ static u16 fake_get_pan_id(struct net_device *dev)
 	return 0xeba1;
 }
 
+/**
+ * fake_get_short_addr - Retrieve the short address of the device.
+ * @dev: The network device to retrieve the short address of.
+ *
+ * Returns the IEEE 802.15.4 short-form address cached for this
+ * device. If the device has not yet had a short address assigned
+ * then this should return 0xFFFF to indicate a lack of association.
+ */
 static u16 fake_get_short_addr(struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -45,6 +65,19 @@ static u16 fake_get_short_addr(struct net_device *dev)
 	return 0x1;
 }
 
+/**
+ * fake_get_dsn - Retrieve the DSN of the device.
+ * @dev: The network device to retrieve the DSN for.
+ *
+ * Returns the IEEE 802.15.4 DSN for the network device.
+ * The DSN is the sequence number which will be added to each
+ * packet or MAC command frame by the MAC during transmission.
+ *
+ * DSN means 'Data Sequence Number'.
+ *
+ * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
+ *       document.
+ */
 static u8 fake_get_dsn(struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -52,6 +85,19 @@ static u8 fake_get_dsn(struct net_device *dev)
 	return 0x00; /* DSN are implemented in HW, so return just 0 */
 }
 
+/**
+ * fake_get_bsn - Retrieve the BSN of the device.
+ * @dev: The network device to retrieve the BSN for.
+ *
+ * Returns the IEEE 802.15.4 BSN for the network device.
+ * The BSN is the sequence number which will be added to each
+ * beacon frame sent by the MAC.
+ *
+ * BSN means 'Beacon Sequence Number'.
+ *
+ * Note: This is in section 7.2.1.2 of the IEEE 802.15.4-2006
+ *       document.
+ */
 static u8 fake_get_bsn(struct net_device *dev)
 {
 	BUG_ON(dev->type != ARPHRD_IEEE802154);
@@ -59,40 +105,130 @@ static u8 fake_get_bsn(struct net_device *dev)
 	return 0x00; /* BSN are implemented in HW, so return just 0 */
 }
 
+/**
+ * fake_assoc_req - Make an association request to the HW.
+ * @dev: The network device which we are associating to a network.
+ * @addr: The coordinator with which we wish to associate.
+ * @channel: The channel on which to associate.
+ * @cap: The capability information field to use in the association.
+ *
+ * Start an association with a coordinator. The coordinator's address
+ * and PAN ID can be found in @addr.
+ *
+ * Note: This is in section 7.3.1 and 7.5.3.1 of the IEEE
+ *       802.15.4-2006 document.
+ */
 static int fake_assoc_req(struct net_device *dev,
-		struct ieee802154_addr *addr, u8 channel, u8 cap)
+		struct ieee802154_addr *addr, u8 channel, u8 page, u8 cap)
 {
+	struct wpan_phy *phy = net_to_phy(dev);
+
+	mutex_lock(&phy->pib_lock);
+	phy->current_channel = channel;
+	phy->current_page = page;
+	mutex_unlock(&phy->pib_lock);
+
 	/* We simply emulate it here */
 	return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev),
 			IEEE802154_SUCCESS);
 }
 
+/**
+ * fake_assoc_resp - Send an association response to a device.
+ * @dev: The network device on which to send the response.
+ * @addr: The address of the device to respond to.
+ * @short_addr: The assigned short address for the device (if any).
+ * @status: The result of the association request.
+ *
+ * Queue the association response of the coordinator to another
+ * device's attempt to associate with the network which we
+ * coordinate. This is then added to the indirect-send queue to be
+ * transmitted to the end device when it polls for data.
+ *
+ * Note: This is in section 7.3.2 and 7.5.3.1 of the IEEE
+ *       802.15.4-2006 document.
+ */
 static int fake_assoc_resp(struct net_device *dev,
 		struct ieee802154_addr *addr, u16 short_addr, u8 status)
 {
 	return 0;
 }
 
+/**
+ * fake_disassoc_req - Disassociate a device from a network.
+ * @dev: The network device on which we're disassociating a device.
+ * @addr: The device to disassociate from the network.
+ * @reason: The reason to give to the device for being disassociated.
+ *
+ * This sends a disassociation notification to the device being
+ * disassociated from the network.
+ *
+ * Note: This is in section 7.5.3.2 of the IEEE 802.15.4-2006
+ *       document, with the reason described in 7.3.3.2.
+ */
 static int fake_disassoc_req(struct net_device *dev,
 		struct ieee802154_addr *addr, u8 reason)
 {
 	return ieee802154_nl_disassoc_confirm(dev, IEEE802154_SUCCESS);
 }
 
+/**
+ * fake_start_req - Start an IEEE 802.15.4 PAN.
+ * @dev: The network device on which to start the PAN.
+ * @addr: The coordinator address to use when starting the PAN.
+ * @channel: The channel on which to start the PAN.
+ * @bcn_ord: Beacon order.
+ * @sf_ord: Superframe order.
+ * @pan_coord: Whether or not we are the PAN coordinator or just
+ *             requesting a realignment perhaps?
+ * @blx: Battery Life Extension feature bitfield.
+ * @coord_realign: Something to realign something else.
+ *
+ * If pan_coord is non-zero then this starts a network with the
+ * provided parameters, otherwise it attempts a coordinator
+ * realignment of the stated network instead.
+ *
+ * Note: This is in section 7.5.2.3 of the IEEE 802.15.4-2006
+ * document, with 7.3.8 describing coordinator realignment.
+ */
 static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr,
-				u8 channel,
+				u8 channel, u8 page,
 				u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
 				u8 coord_realign)
 {
+	struct wpan_phy *phy = net_to_phy(dev);
+
+	mutex_lock(&phy->pib_lock);
+	phy->current_channel = channel;
+	phy->current_page = page;
+	mutex_unlock(&phy->pib_lock);
+
+	/* We don't emulate beacons here at all, so START should fail */
+	ieee802154_nl_start_confirm(dev, IEEE802154_INVALID_PARAMETER);
 	return 0;
 }
 
+/**
+ * fake_scan_req - Start a channel scan.
+ * @dev: The network device on which to perform a channel scan.
+ * @type: The type of scan to perform.
+ * @channels: The channel bitmask to scan.
+ * @duration: How long to spend on each channel.
+ *
+ * This starts either a passive (energy) scan or an active (PAN) scan
+ * on the channels indicated in the @channels bitmask. The duration of
+ * the scan is measured in terms of superframe duration. Specifically,
+ * the scan will spend aBaseSuperFrameDuration * ((2^n) + 1) on each
+ * channel.
+ *
+ * Note: This is in section 7.5.2.1 of the IEEE 802.15.4-2006 document.
+ */
 static int fake_scan_req(struct net_device *dev, u8 type, u32 channels,
-		u8 duration)
+		u8 page, u8 duration)
 {
 	u8 edl[27] = {};
 	return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type,
-			channels,
+			channels, page,
 			type == IEEE802154_MAC_SCAN_ED ? edl : NULL);
 }
 
@@ -121,7 +257,8 @@ static int ieee802154_fake_close(struct net_device *dev)
 	return 0;
 }
 
-static int ieee802154_fake_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb,
+					      struct net_device *dev)
 {
 	skb->iif = dev->ifindex;
 	skb->dev = dev;
@@ -132,7 +269,7 @@ static int ieee802154_fake_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* FIXME: do hardware work here ... */
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
@@ -174,6 +311,14 @@ static const struct net_device_ops fake_ops = {
 	.ndo_set_mac_address	= ieee802154_fake_mac_addr,
 };
 
+static void ieee802154_fake_destruct(struct net_device *dev)
+{
+	struct wpan_phy *phy = net_to_phy(dev);
+
+	wpan_phy_unregister(phy);
+	free_netdev(dev);
+	wpan_phy_free(phy);
+}
 
 static void ieee802154_fake_setup(struct net_device *dev)
 {
@@ -186,22 +331,34 @@ static void ieee802154_fake_setup(struct net_device *dev)
 	dev->type		= ARPHRD_IEEE802154;
 	dev->flags		= IFF_NOARP | IFF_BROADCAST;
 	dev->watchdog_timeo	= 0;
+	dev->destructor		= ieee802154_fake_destruct;
 }
 
 
 static int __devinit ieee802154fake_probe(struct platform_device *pdev)
 {
-	struct net_device *dev =
-		alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
+	struct net_device *dev;
+	struct wpan_phy *phy = wpan_phy_alloc(0);
 	int err;
 
-	if (!dev)
+	if (!phy)
 		return -ENOMEM;
 
+	dev = alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
+	if (!dev) {
+		wpan_phy_free(phy);
+		return -ENOMEM;
+	}
+
+	phy->dev.platform_data = dev;
+
 	memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef",
 			dev->addr_len);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
+	phy->channels_supported = (1 << 27) - 1;
+	phy->transmit_power = 0xbf;
+
 	dev->netdev_ops = &fake_ops;
 	dev->ml_priv = &fake_mlme;
 
@@ -215,15 +372,18 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
 			goto out;
 	}
 
-	SET_NETDEV_DEV(dev, &pdev->dev);
+	SET_NETDEV_DEV(dev, &phy->dev);
 
 	platform_set_drvdata(pdev, dev);
 
+	err = wpan_phy_register(&pdev->dev, phy);
+	if (err)
+		goto out;
+
 	err = register_netdev(dev);
 	if (err < 0)
 		goto out;
 
-
 	dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n");
 	return 0;
 
@@ -236,7 +396,6 @@ static int __devexit ieee802154fake_remove(struct platform_device *pdev)
 {
 	struct net_device *dev = platform_get_drvdata(pdev);
 	unregister_netdev(dev);
-	free_netdev(dev);
 	return 0;
 }
 
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c
index 8250740..c61fd2b 100644
--- a/drivers/infiniband/hw/amso1100/c2.c
+++ b/drivers/infiniband/hw/amso1100/c2.c
@@ -526,7 +526,6 @@ static void c2_rx_interrupt(struct net_device *netdev)
 
 		netif_rx(skb);
 
-		netdev->last_rx = jiffies;
 		netdev->stats.rx_packets++;
 		netdev->stats.rx_bytes += buflen;
 	}
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 5b635aa..fb2d83c 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -623,7 +623,7 @@ static struct attribute_group ehca_drv_attr_grp = {
 	.attrs = ehca_drv_attrs
 };
 
-static struct attribute_group *ehca_drv_attr_groups[] = {
+static const struct attribute_group *ehca_drv_attr_groups[] = {
 	&ehca_drv_attr_grp,
 	NULL,
 };
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 6ba4861..b3d7efc 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -1286,7 +1286,7 @@ struct device_driver;
 
 extern const char ib_ipath_version[];
 
-extern struct attribute_group *ipath_driver_attr_groups[];
+extern const struct attribute_group *ipath_driver_attr_groups[];
 
 int ipath_device_create_group(struct device *, struct ipath_devdata *);
 void ipath_device_remove_group(struct device *, struct ipath_devdata *);
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c
index a6c8efb..b8cb2f1 100644
--- a/drivers/infiniband/hw/ipath/ipath_sysfs.c
+++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c
@@ -1069,7 +1069,7 @@ static ssize_t show_tempsense(struct device *dev,
 	return ret;
 }
 
-struct attribute_group *ipath_driver_attr_groups[] = {
+const struct attribute_group *ipath_driver_attr_groups[] = {
 	&driver_attr_group,
 	NULL,
 };
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 63a1a8e..3512d6d 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -2743,7 +2743,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
 				}
 
 skip_rx_indicate0:
-				nesvnic->netdev->last_rx = jiffies;
+				;
 				/* nesvnic->netstats.rx_packets++; */
 				/* nesvnic->netstats.rx_bytes += rx_pkt_size; */
 			}
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index c6e6611..538e409 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -1508,7 +1508,7 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd
 }
 
 
-static struct ethtool_ops nes_ethtool_ops = {
+static const struct ethtool_ops nes_ethtool_ops = {
 	.get_link = ethtool_op_get_link,
 	.get_settings = nes_netdev_get_settings,
 	.set_settings = nes_netdev_set_settings,
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 8f4b4fc..30bdf42 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -662,7 +662,6 @@ copied:
 	skb_reset_mac_header(skb);
 	skb_pull(skb, IPOIB_ENCAP_LEN);
 
-	dev->last_rx = jiffies;
 	++dev->stats.rx_packets;
 	dev->stats.rx_bytes += skb->len;
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index e35f4a0..8c91d9f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -276,7 +276,6 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
 	skb_reset_mac_header(skb);
 	skb_pull(skb, IPOIB_ENCAP_LEN);
 
-	dev->last_rx = jiffies;
 	++dev->stats.rx_packets;
 	dev->stats.rx_bytes += skb->len;
 
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 7c237e6..556539d 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1144,7 +1144,7 @@ static struct attribute_group input_dev_caps_attr_group = {
 	.attrs	= input_dev_caps_attrs,
 };
 
-static struct attribute_group *input_dev_attr_groups[] = {
+static const struct attribute_group *input_dev_attr_groups[] = {
 	&input_dev_attr_group,
 	&input_dev_id_attr_group,
 	&input_dev_caps_attr_group,
@@ -1265,14 +1265,14 @@ static struct device_type input_dev_type = {
 	.uevent		= input_dev_uevent,
 };
 
-static char *input_nodename(struct device *dev)
+static char *input_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev));
 }
 
 struct class input_class = {
 	.name		= "input",
-	.nodename	= input_nodename,
+	.devnode	= input_devnode,
 };
 EXPORT_SYMBOL_GPL(input_class);
 
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9a1d55b..901b252 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -452,6 +452,76 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
 		(joydev->exist ?  0 : (POLLHUP | POLLERR));
 }
 
+static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev,
+				     void __user *argp, size_t len)
+{
+	__u8 *abspam;
+	int i;
+	int retval = 0;
+
+	len = min(len, sizeof(joydev->abspam));
+
+	/* Validate the map. */
+	abspam = kmalloc(len, GFP_KERNEL);
+	if (!abspam)
+		return -ENOMEM;
+
+	if (copy_from_user(abspam, argp, len)) {
+		retval = -EFAULT;
+		goto out;
+	}
+
+	for (i = 0; i < joydev->nabs; i++) {
+		if (abspam[i] > ABS_MAX) {
+			retval = -EINVAL;
+			goto out;
+		}
+	}
+
+	memcpy(joydev->abspam, abspam, len);
+
+ out:
+	kfree(abspam);
+	return retval;
+}
+
+static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
+				      void __user *argp, size_t len)
+{
+	__u16 *keypam;
+	int i;
+	int retval = 0;
+
+	len = min(len, sizeof(joydev->keypam));
+
+	/* Validate the map. */
+	keypam = kmalloc(len, GFP_KERNEL);
+	if (!keypam)
+		return -ENOMEM;
+
+	if (copy_from_user(keypam, argp, len)) {
+		retval = -EFAULT;
+		goto out;
+	}
+
+	for (i = 0; i < joydev->nkey; i++) {
+		if (keypam[i] > KEY_MAX || keypam[i] < BTN_MISC) {
+			retval = -EINVAL;
+			goto out;
+		}
+	}
+
+	memcpy(joydev->keypam, keypam, len);
+
+	for (i = 0; i < joydev->nkey; i++)
+		joydev->keymap[keypam[i] - BTN_MISC] = i;
+
+ out:
+	kfree(keypam);
+	return retval;
+}
+
+
 static int joydev_ioctl_common(struct joydev *joydev,
 				unsigned int cmd, void __user *argp)
 {
@@ -512,46 +582,18 @@ static int joydev_ioctl_common(struct joydev *joydev,
 	switch (cmd & ~IOCSIZE_MASK) {
 
 	case (JSIOCSAXMAP & ~IOCSIZE_MASK):
-		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
-		/*
-		 * FIXME: we should not copy into our axis map before
-		 * validating the data.
-		 */
-		if (copy_from_user(joydev->abspam, argp, len))
-			return -EFAULT;
-
-		for (i = 0; i < joydev->nabs; i++) {
-			if (joydev->abspam[i] > ABS_MAX)
-				return -EINVAL;
-			joydev->absmap[joydev->abspam[i]] = i;
-		}
-		return 0;
+		return joydev_handle_JSIOCSAXMAP(joydev, argp, _IOC_SIZE(cmd));
 
 	case (JSIOCGAXMAP & ~IOCSIZE_MASK):
 		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
-		return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
+		return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : len;
 
 	case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
-		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
-		/*
-		 * FIXME: we should not copy into our keymap before
-		 * validating the data.
-		 */
-		if (copy_from_user(joydev->keypam, argp, len))
-			return -EFAULT;
-
-		for (i = 0; i < joydev->nkey; i++) {
-			if (joydev->keypam[i] > KEY_MAX ||
-			    joydev->keypam[i] < BTN_MISC)
-				return -EINVAL;
-			joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
-		}
-
-		return 0;
+		return joydev_handle_JSIOCSBTNMAP(joydev, argp, _IOC_SIZE(cmd));
 
 	case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
 		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
-		return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
+		return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : len;
 
 	case JSIOCGNAME(0):
 		name = dev->name;
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index f155ad8..2388cf5 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -144,6 +144,7 @@ static const struct xpad_device {
 	{ 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
 	{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
+	{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
 	{ 0x0000, 0x0000, "Generic X-Box pad", MAP_DPAD_UNKNOWN, XTYPE_UNKNOWN }
 };
@@ -208,6 +209,7 @@ static struct usb_device_id xpad_table [] = {
 	XPAD_XBOX360_VENDOR(0x0738),		/* Mad Catz X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x0e6f),		/* 0x0e6f X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x1430),		/* RedOctane X-Box 360 controllers */
+	XPAD_XBOX360_VENDOR(0x1bad),		/* Rock Band Drums */
 	{ }
 };
 
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index a6b989a..3525c19 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -187,7 +187,7 @@ config KEYBOARD_HIL_OLD
 	  submenu.
 
 config KEYBOARD_HIL
-	tristate "HP HIL keyboard support"
+	tristate "HP HIL keyboard/pointer support"
 	depends on GSC || HP300
 	default y
 	select HP_SDC
@@ -196,7 +196,8 @@ config KEYBOARD_HIL
 	help
 	  The "Human Interface Loop" is a older, 8-channel USB-like
 	  controller used in several Hewlett Packard models.
-	  This driver implements support for HIL-keyboards attached
+	  This driver implements support for HIL-keyboards and pointing
+	  devices (mice, tablets, touchscreens) attached
 	  to your machine, so normally you should say Y here.
 
 config KEYBOARD_HP6XX
@@ -329,6 +330,17 @@ config KEYBOARD_OMAP
 	  To compile this driver as a module, choose M here: the
 	  module will be called omap-keypad.
 
+config KEYBOARD_TWL4030
+	tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
+	depends on TWL4030_CORE
+	help
+	  Say Y here if your board use the keypad controller on
+	  TWL4030 family chips.  It's safe to say enable this
+	  even on boards that don't use the keypad controller.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called twl4030_keypad.
+
 config KEYBOARD_TOSA
 	tristate "Tosa keyboard"
 	depends on MACH_TOSA
@@ -361,4 +373,14 @@ config KEYBOARD_XTKBD
 	  To compile this driver as a module, choose M here: the
 	  module will be called xtkbd.
 
+config KEYBOARD_W90P910
+	tristate "W90P910 Matrix Keypad support"
+	depends on ARCH_W90X900
+	help
+	  Say Y here to enable the matrix keypad on evaluation board
+	  based on W90P910.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called w90p910_keypad.
+
 endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index b5b5eae..8a7a22b 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -30,4 +30,6 @@ obj-$(CONFIG_KEYBOARD_SPITZ)		+= spitzkbd.o
 obj-$(CONFIG_KEYBOARD_STOWAWAY)		+= stowaway.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)		+= sunkbd.o
 obj-$(CONFIG_KEYBOARD_TOSA)		+= tosakbd.o
+obj-$(CONFIG_KEYBOARD_TWL4030)		+= twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
+obj-$(CONFIG_KEYBOARD_W90P910)		+= w90p910_keypad.o
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 6c6a09b..c9523e4 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -68,7 +68,9 @@ MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and
  * are loadable via a userland utility.
  */
 
-static const unsigned short atkbd_set2_keycode[512] = {
+#define ATKBD_KEYMAP_SIZE	512
+
+static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
 
 #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
 
@@ -99,7 +101,7 @@ static const unsigned short atkbd_set2_keycode[512] = {
 #endif
 };
 
-static const unsigned short atkbd_set3_keycode[512] = {
+static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = {
 
 	  0,  0,  0,  0,  0,  0,  0, 59,  1,138,128,129,130, 15, 41, 60,
 	131, 29, 42, 86, 58, 16,  2, 61,133, 56, 44, 31, 30, 17,  3, 62,
@@ -200,8 +202,8 @@ struct atkbd {
 	char phys[32];
 
 	unsigned short id;
-	unsigned short keycode[512];
-	DECLARE_BITMAP(force_release_mask, 512);
+	unsigned short keycode[ATKBD_KEYMAP_SIZE];
+	DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE);
 	unsigned char set;
 	unsigned char translated;
 	unsigned char extra;
@@ -253,6 +255,7 @@ static struct device_attribute atkbd_attr_##_name =				\
 	__ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name);
 
 ATKBD_DEFINE_ATTR(extra);
+ATKBD_DEFINE_ATTR(force_release);
 ATKBD_DEFINE_ATTR(scroll);
 ATKBD_DEFINE_ATTR(set);
 ATKBD_DEFINE_ATTR(softrepeat);
@@ -272,6 +275,7 @@ ATKBD_DEFINE_RO_ATTR(err_count);
 
 static struct attribute *atkbd_attributes[] = {
 	&atkbd_attr_extra.attr,
+	&atkbd_attr_force_release.attr,
 	&atkbd_attr_scroll.attr,
 	&atkbd_attr_set.attr,
 	&atkbd_attr_softrepeat.attr,
@@ -934,7 +938,7 @@ static void atkbd_set_keycode_table(struct atkbd *atkbd)
 	int i, j;
 
 	memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
-	bitmap_zero(atkbd->force_release_mask, 512);
+	bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
 
 	if (atkbd->translated) {
 		for (i = 0; i < 128; i++) {
@@ -1041,7 +1045,7 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
 	input_dev->keycodesize = sizeof(unsigned short);
 	input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
 
-	for (i = 0; i < 512; i++)
+	for (i = 0; i < ATKBD_KEYMAP_SIZE; i++)
 		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
 			__set_bit(atkbd->keycode[i], input_dev->keybit);
 }
@@ -1309,6 +1313,33 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
 	return count;
 }
 
+static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf)
+{
+	size_t len = bitmap_scnlistprintf(buf, PAGE_SIZE - 2,
+			atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
+
+	buf[len++] = '\n';
+	buf[len] = '\0';
+
+	return len;
+}
+
+static ssize_t atkbd_set_force_release(struct atkbd *atkbd,
+					const char *buf, size_t count)
+{
+	/* 64 bytes on stack should be acceptable */
+	DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE);
+	int err;
+
+	err = bitmap_parselist(buf, new_mask, ATKBD_KEYMAP_SIZE);
+	if (err)
+		return err;
+
+	memcpy(atkbd->force_release_mask, new_mask, sizeof(atkbd->force_release_mask));
+	return count;
+}
+
+
 static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf)
 {
 	return sprintf(buf, "%d\n", atkbd->scroll ? 1 : 0);
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index d427f32..fe376a2 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -184,14 +184,13 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 	int i, error;
 
 	if (!pdata->rows || !pdata->cols || !pdata->keymap) {
-		printk(KERN_ERR DRV_NAME
-			": No rows, cols or keymap from pdata\n");
+		dev_err(&pdev->dev, "no rows, cols or keymap from pdata\n");
 		return -EINVAL;
 	}
 
 	if (!pdata->keymapsize ||
 	    pdata->keymapsize > (pdata->rows * pdata->cols)) {
-		printk(KERN_ERR DRV_NAME ": Invalid keymapsize\n");
+		dev_err(&pdev->dev, "invalid keymapsize\n");
 		return -EINVAL;
 	}
 
@@ -211,8 +210,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 
 	if (!pdata->debounce_time || pdata->debounce_time > MAX_MULT ||
 	    !pdata->coldrive_time || pdata->coldrive_time > MAX_MULT) {
-		printk(KERN_WARNING DRV_NAME
-			": Invalid Debounce/Columndrive Time in platform data\n");
+		dev_warn(&pdev->dev,
+			"invalid platform debounce/columndrive time\n");
 		bfin_write_KPAD_MSEL(0xFF0);	/* Default MSEL	*/
 	} else {
 		bfin_write_KPAD_MSEL(
@@ -231,16 +230,14 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 
 	if (peripheral_request_list((u16 *)&per_rows[MAX_RC - pdata->rows],
 				    DRV_NAME)) {
-		printk(KERN_ERR DRV_NAME
-			": Requesting Peripherals failed\n");
+		dev_err(&pdev->dev, "requesting peripherals failed\n");
 		error = -EFAULT;
 		goto out0;
 	}
 
 	if (peripheral_request_list((u16 *)&per_cols[MAX_RC - pdata->cols],
 				    DRV_NAME)) {
-		printk(KERN_ERR DRV_NAME
-			": Requesting Peripherals failed\n");
+		dev_err(&pdev->dev, "requesting peripherals failed\n");
 		error = -EFAULT;
 		goto out1;
 	}
@@ -254,9 +251,8 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 	error = request_irq(bf54x_kpad->irq, bfin_kpad_isr,
 				0, DRV_NAME, pdev);
 	if (error) {
-		printk(KERN_ERR DRV_NAME
-			": unable to claim irq %d; error %d\n",
-			bf54x_kpad->irq, error);
+		dev_err(&pdev->dev, "unable to claim irq %d\n",
+			bf54x_kpad->irq);
 		goto out2;
 	}
 
@@ -297,8 +293,7 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 
 	error = input_register_device(input);
 	if (error) {
-		printk(KERN_ERR DRV_NAME
-			": Unable to register input device (%d)\n", error);
+		dev_err(&pdev->dev, "unable to register input device\n");
 		goto out4;
 	}
 
@@ -316,9 +311,6 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
 
 	device_init_wakeup(&pdev->dev, 1);
 
-	printk(KERN_ERR DRV_NAME
-		": Blackfin BF54x Keypad registered IRQ %d\n", bf54x_kpad->irq);
-
 	return 0;
 
 out4:
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index efed0c9..a88aff3 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -216,8 +216,9 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
 
 
 #ifdef CONFIG_PM
-static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
+static int gpio_keys_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	int i;
 
@@ -234,8 +235,9 @@ static int gpio_keys_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int gpio_keys_resume(struct platform_device *pdev)
+static int gpio_keys_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	int i;
 
@@ -251,19 +253,22 @@ static int gpio_keys_resume(struct platform_device *pdev)
 
 	return 0;
 }
-#else
-#define gpio_keys_suspend	NULL
-#define gpio_keys_resume	NULL
+
+static const struct dev_pm_ops gpio_keys_pm_ops = {
+	.suspend	= gpio_keys_suspend,
+	.resume		= gpio_keys_resume,
+};
 #endif
 
 static struct platform_driver gpio_keys_device_driver = {
 	.probe		= gpio_keys_probe,
 	.remove		= __devexit_p(gpio_keys_remove),
-	.suspend	= gpio_keys_suspend,
-	.resume		= gpio_keys_resume,
 	.driver		= {
 		.name	= "gpio-keys",
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &gpio_keys_pm_ops,
+#endif
 	}
 };
 
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index 6f35670..c83f4b2 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -37,19 +37,19 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/semaphore.h>
+#include <linux/completion.h>
 #include <linux/slab.h>
 #include <linux/pci_ids.h>
 
-#define PREFIX "HIL KEYB: "
-#define HIL_GENERIC_NAME "HIL keyboard"
+#define PREFIX "HIL: "
 
 MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
-MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
+MODULE_DESCRIPTION("HIL keyboard/mouse driver");
 MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("serio:ty03pr25id00ex*");
+MODULE_ALIAS("serio:ty03pr25id00ex*"); /* HIL keyboard */
+MODULE_ALIAS("serio:ty03pr25id0Fex*"); /* HIL mouse */
 
-#define HIL_KBD_MAX_LENGTH 16
+#define HIL_PACKET_MAX_LENGTH 16
 
 #define HIL_KBD_SET1_UPBIT 0x01
 #define HIL_KBD_SET1_SHIFT 1
@@ -67,308 +67,497 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly =
 
 static const char hil_language[][16] = { HIL_LOCALE_MAP };
 
-struct hil_kbd {
+struct hil_dev {
 	struct input_dev *dev;
 	struct serio *serio;
 
 	/* Input buffer and index for packets from HIL bus. */
-	hil_packet data[HIL_KBD_MAX_LENGTH];
+	hil_packet data[HIL_PACKET_MAX_LENGTH];
 	int idx4; /* four counts per packet */
 
 	/* Raw device info records from HIL bus, see hil.h for fields. */
-	char	idd[HIL_KBD_MAX_LENGTH];	/* DID byte and IDD record */
-	char	rsc[HIL_KBD_MAX_LENGTH];	/* RSC record */
-	char	exd[HIL_KBD_MAX_LENGTH];	/* EXD record */
-	char	rnm[HIL_KBD_MAX_LENGTH + 1];	/* RNM record + NULL term. */
+	char	idd[HIL_PACKET_MAX_LENGTH];	/* DID byte and IDD record */
+	char	rsc[HIL_PACKET_MAX_LENGTH];	/* RSC record */
+	char	exd[HIL_PACKET_MAX_LENGTH];	/* EXD record */
+	char	rnm[HIL_PACKET_MAX_LENGTH + 1];	/* RNM record + NULL term. */
 
-	/* Something to sleep around with. */
-	struct semaphore sem;
+	struct completion cmd_done;
+
+	bool is_pointer;
+	/* Extra device details needed for pointing devices. */
+	unsigned int nbtn, naxes;
+	unsigned int btnmap[7];
 };
 
-/* Process a complete packet after transfer from the HIL */
-static void hil_kbd_process_record(struct hil_kbd *kbd)
+static bool hil_dev_is_command_response(hil_packet p)
 {
-	struct input_dev *dev = kbd->dev;
-	hil_packet *data = kbd->data;
-	hil_packet p;
-	int idx, i, cnt;
+	if ((p & ~HIL_CMDCT_POL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
+		return false;
 
-	idx = kbd->idx4/4;
-	p = data[idx - 1];
+	if ((p & ~HIL_CMDCT_RPL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
+		return false;
 
-	if ((p & ~HIL_CMDCT_POL) ==
-	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
-		goto report;
-	if ((p & ~HIL_CMDCT_RPL) ==
-	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
-		goto report;
+	return true;
+}
+
+static void hil_dev_handle_command_response(struct hil_dev *dev)
+{
+	hil_packet p;
+	char *buf;
+	int i, idx;
+
+	idx = dev->idx4 / 4;
+	p = dev->data[idx - 1];
 
-	/* Not a poll response.  See if we are loading config records. */
 	switch (p & HIL_PKT_DATA_MASK) {
 	case HIL_CMD_IDD:
-		for (i = 0; i < idx; i++)
-			kbd->idd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_KBD_MAX_LENGTH; i++)
-			kbd->idd[i] = 0;
+		buf = dev->idd;
 		break;
 
 	case HIL_CMD_RSC:
-		for (i = 0; i < idx; i++)
-			kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_KBD_MAX_LENGTH; i++)
-			kbd->rsc[i] = 0;
+		buf = dev->rsc;
 		break;
 
 	case HIL_CMD_EXD:
-		for (i = 0; i < idx; i++)
-			kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_KBD_MAX_LENGTH; i++)
-			kbd->exd[i] = 0;
+		buf = dev->exd;
 		break;
 
 	case HIL_CMD_RNM:
-		for (i = 0; i < idx; i++)
-			kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_KBD_MAX_LENGTH + 1; i++)
-			kbd->rnm[i] = '\0';
+		dev->rnm[HIL_PACKET_MAX_LENGTH] = 0;
+		buf = dev->rnm;
 		break;
 
 	default:
 		/* These occur when device isn't present */
-		if (p == (HIL_ERR_INT | HIL_PKT_CMD))
-			break;
-		/* Anything else we'd like to know about. */
-		printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
-		break;
+		if (p != (HIL_ERR_INT | HIL_PKT_CMD)) {
+			/* Anything else we'd like to know about. */
+			printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
+		}
+		goto out;
 	}
-	goto out;
 
- report:
-	cnt = 1;
+	for (i = 0; i < idx; i++)
+		buf[i] = dev->data[i] & HIL_PKT_DATA_MASK;
+	for (; i < HIL_PACKET_MAX_LENGTH; i++)
+		buf[i] = 0;
+ out:
+	complete(&dev->cmd_done);
+}
+
+static void hil_dev_handle_kbd_events(struct hil_dev *kbd)
+{
+	struct input_dev *dev = kbd->dev;
+	int idx = kbd->idx4 / 4;
+	int i;
+
 	switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) {
 	case HIL_POL_CHARTYPE_NONE:
-		break;
+		return;
 
 	case HIL_POL_CHARTYPE_ASCII:
-		while (cnt < idx - 1)
-			input_report_key(dev, kbd->data[cnt++] & 0x7f, 1);
+		for (i = 1; i < idx - 1; i++)
+			input_report_key(dev, kbd->data[i] & 0x7f, 1);
 		break;
 
 	case HIL_POL_CHARTYPE_RSVD1:
 	case HIL_POL_CHARTYPE_RSVD2:
 	case HIL_POL_CHARTYPE_BINARY:
-		while (cnt < idx - 1)
-			input_report_key(dev, kbd->data[cnt++], 1);
+		for (i = 1; i < idx - 1; i++)
+			input_report_key(dev, kbd->data[i], 1);
 		break;
 
 	case HIL_POL_CHARTYPE_SET1:
-		while (cnt < idx - 1) {
-			unsigned int key;
-			int up;
-			key = kbd->data[cnt++];
-			up = key & HIL_KBD_SET1_UPBIT;
+		for (i = 1; i < idx - 1; i++) {
+			unsigned int key = kbd->data[i];
+			int up = key & HIL_KBD_SET1_UPBIT;
+
 			key &= (~HIL_KBD_SET1_UPBIT & 0xff);
 			key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT];
-			if (key != KEY_RESERVED)
-				input_report_key(dev, key, !up);
+			input_report_key(dev, key, !up);
 		}
 		break;
 
 	case HIL_POL_CHARTYPE_SET2:
-		while (cnt < idx - 1) {
-			unsigned int key;
-			int up;
-			key = kbd->data[cnt++];
-			up = key & HIL_KBD_SET2_UPBIT;
+		for (i = 1; i < idx - 1; i++) {
+			unsigned int key = kbd->data[i];
+			int up = key & HIL_KBD_SET2_UPBIT;
+
 			key &= (~HIL_KBD_SET1_UPBIT & 0xff);
 			key = key >> HIL_KBD_SET2_SHIFT;
-			if (key != KEY_RESERVED)
-				input_report_key(dev, key, !up);
+			input_report_key(dev, key, !up);
 		}
 		break;
 
 	case HIL_POL_CHARTYPE_SET3:
-		while (cnt < idx - 1) {
-			unsigned int key;
-			int up;
-			key = kbd->data[cnt++];
-			up = key & HIL_KBD_SET3_UPBIT;
+		for (i = 1; i < idx - 1; i++) {
+			unsigned int key = kbd->data[i];
+			int up = key & HIL_KBD_SET3_UPBIT;
+
 			key &= (~HIL_KBD_SET1_UPBIT & 0xff);
 			key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT];
-			if (key != KEY_RESERVED)
-				input_report_key(dev, key, !up);
+			input_report_key(dev, key, !up);
 		}
 		break;
 	}
- out:
-	kbd->idx4 = 0;
-	up(&kbd->sem);
+
+	input_sync(dev);
 }
 
-static void hil_kbd_process_err(struct hil_kbd *kbd)
+static void hil_dev_handle_ptr_events(struct hil_dev *ptr)
+{
+	struct input_dev *dev = ptr->dev;
+	int idx = ptr->idx4 / 4;
+	hil_packet p = ptr->data[idx - 1];
+	int i, cnt, laxis;
+	bool absdev, ax16;
+
+	if ((p & HIL_CMDCT_POL) != idx - 1) {
+		printk(KERN_WARNING PREFIX
+			"Malformed poll packet %x (idx = %i)\n", p, idx);
+		return;
+	}
+
+	i = (p & HIL_POL_AXIS_ALT) ? 3 : 0;
+	laxis = (p & HIL_POL_NUM_AXES_MASK) + i;
+
+	ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
+	absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
+
+	for (cnt = 1; i < laxis; i++) {
+		unsigned int lo, hi, val;
+
+		lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK;
+		hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0;
+
+		if (absdev) {
+			val = lo + (hi << 8);
+#ifdef TABLET_AUTOADJUST
+			if (val < dev->absmin[ABS_X + i])
+				dev->absmin[ABS_X + i] = val;
+			if (val > dev->absmax[ABS_X + i])
+				dev->absmax[ABS_X + i] = val;
+#endif
+			if (i%3) val = dev->absmax[ABS_X + i] - val;
+			input_report_abs(dev, ABS_X + i, val);
+		} else {
+			val = (int) (((int8_t)lo) | ((int8_t)hi << 8));
+			if (i % 3)
+				val *= -1;
+			input_report_rel(dev, REL_X + i, val);
+		}
+	}
+
+	while (cnt < idx - 1) {
+		unsigned int btn = ptr->data[cnt++];
+		int up = btn & 1;
+
+		btn &= 0xfe;
+		if (btn == 0x8e)
+			continue; /* TODO: proximity == touch? */
+		if (btn > 0x8c || btn < 0x80)
+			continue;
+		btn = (btn - 0x80) >> 1;
+		btn = ptr->btnmap[btn];
+		input_report_key(dev, btn, !up);
+	}
+
+	input_sync(dev);
+}
+
+static void hil_dev_process_err(struct hil_dev *dev)
 {
 	printk(KERN_WARNING PREFIX "errored HIL packet\n");
-	kbd->idx4 = 0;
-	up(&kbd->sem);
+	dev->idx4 = 0;
+	complete(&dev->cmd_done); /* just in case somebody is waiting */
 }
 
-static irqreturn_t hil_kbd_interrupt(struct serio *serio,
+static irqreturn_t hil_dev_interrupt(struct serio *serio,
 				unsigned char data, unsigned int flags)
 {
-	struct hil_kbd *kbd;
+	struct hil_dev *dev;
 	hil_packet packet;
 	int idx;
 
-	kbd = serio_get_drvdata(serio);
-	BUG_ON(kbd == NULL);
+	dev = serio_get_drvdata(serio);
+	BUG_ON(dev == NULL);
 
-	if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) {
-		hil_kbd_process_err(kbd);
-		return IRQ_HANDLED;
+	if (dev->idx4 >= HIL_PACKET_MAX_LENGTH * sizeof(hil_packet)) {
+		hil_dev_process_err(dev);
+		goto out;
 	}
-	idx = kbd->idx4/4;
-	if (!(kbd->idx4 % 4))
-		kbd->data[idx] = 0;
-	packet = kbd->data[idx];
-	packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8);
-	kbd->data[idx] = packet;
+
+	idx = dev->idx4 / 4;
+	if (!(dev->idx4 % 4))
+		dev->data[idx] = 0;
+	packet = dev->data[idx];
+	packet |= ((hil_packet)data) << ((3 - (dev->idx4 % 4)) * 8);
+	dev->data[idx] = packet;
 
 	/* Records of N 4-byte hil_packets must terminate with a command. */
-	if ((++(kbd->idx4)) % 4)
-		return IRQ_HANDLED;
-	if ((packet & 0xffff0000) != HIL_ERR_INT) {
-		hil_kbd_process_err(kbd);
-		return IRQ_HANDLED;
+	if ((++dev->idx4 % 4) == 0) {
+		if ((packet & 0xffff0000) != HIL_ERR_INT) {
+			hil_dev_process_err(dev);
+		} else if (packet & HIL_PKT_CMD) {
+			if (hil_dev_is_command_response(packet))
+				hil_dev_handle_command_response(dev);
+			else if (dev->is_pointer)
+				hil_dev_handle_ptr_events(dev);
+			else
+				hil_dev_handle_kbd_events(dev);
+			dev->idx4 = 0;
+		}
 	}
-	if (packet & HIL_PKT_CMD)
-		hil_kbd_process_record(kbd);
+ out:
 	return IRQ_HANDLED;
 }
 
-static void hil_kbd_disconnect(struct serio *serio)
+static void hil_dev_disconnect(struct serio *serio)
 {
-	struct hil_kbd *kbd;
+	struct hil_dev *dev = serio_get_drvdata(serio);
 
-	kbd = serio_get_drvdata(serio);
-	BUG_ON(kbd == NULL);
+	BUG_ON(dev == NULL);
 
 	serio_close(serio);
-	input_unregister_device(kbd->dev);
-	kfree(kbd);
+	input_unregister_device(dev->dev);
+	serio_set_drvdata(serio, NULL);
+	kfree(dev);
+}
+
+static void hil_dev_keyboard_setup(struct hil_dev *kbd)
+{
+	struct input_dev *input_dev = kbd->dev;
+	uint8_t did = kbd->idd[0];
+	int i;
+
+	input_dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+	input_dev->ledbit[0]	= BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+				  BIT_MASK(LED_SCROLLL);
+
+	for (i = 0; i < 128; i++) {
+		__set_bit(hil_kbd_set1[i], input_dev->keybit);
+		__set_bit(hil_kbd_set3[i], input_dev->keybit);
+	}
+	__clear_bit(KEY_RESERVED, input_dev->keybit);
+
+	input_dev->keycodemax	= HIL_KEYCODES_SET1_TBLSIZE;
+	input_dev->keycodesize	= sizeof(hil_kbd_set1[0]);
+	input_dev->keycode	= hil_kbd_set1;
+
+	input_dev->name	= strlen(kbd->rnm) ? kbd->rnm : "HIL keyboard";
+	input_dev->phys	= "hpkbd/input0";
+
+	printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n",
+		did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
 }
 
-static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
+static void hil_dev_pointer_setup(struct hil_dev *ptr)
 {
-	struct hil_kbd	*kbd;
-	uint8_t		did, *idd;
-	int		i;
+	struct input_dev *input_dev = ptr->dev;
+	uint8_t did = ptr->idd[0];
+	uint8_t *idd = ptr->idd + 1;
+	unsigned int naxsets = HIL_IDD_NUM_AXSETS(*idd);
+	unsigned int i, btntype;
+	const char *txt;
+
+	ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
+
+	switch (did & HIL_IDD_DID_TYPE_MASK) {
+	case HIL_IDD_DID_TYPE_REL:
+		input_dev->evbit[0] = BIT_MASK(EV_REL);
 
-	kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
-	if (!kbd)
-		return -ENOMEM;
+		for (i = 0; i < ptr->naxes; i++)
+			__set_bit(REL_X + i, input_dev->relbit);
 
-	kbd->dev = input_allocate_device();
-	if (!kbd->dev)
+		for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++)
+			__set_bit(REL_X + i, input_dev->relbit);
+
+		txt = "relative";
+		break;
+
+	case HIL_IDD_DID_TYPE_ABS:
+		input_dev->evbit[0] = BIT_MASK(EV_ABS);
+
+		for (i = 0; i < ptr->naxes; i++)
+			input_set_abs_params(input_dev, ABS_X + i,
+					0, HIL_IDD_AXIS_MAX(idd, i), 0, 0);
+
+		for (i = 3; naxsets > 1 && i < ptr->naxes + 3; i++)
+			input_set_abs_params(input_dev, ABS_X + i,
+					0, HIL_IDD_AXIS_MAX(idd, i - 3), 0, 0);
+
+#ifdef TABLET_AUTOADJUST
+		for (i = 0; i < ABS_MAX; i++) {
+			int diff = input_dev->absmax[ABS_X + i] / 10;
+			input_dev->absmin[ABS_X + i] += diff;
+			input_dev->absmax[ABS_X + i] -= diff;
+		}
+#endif
+
+		txt = "absolute";
+		break;
+
+	default:
+		BUG();
+	}
+
+	ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
+	if (ptr->nbtn)
+		input_dev->evbit[0] |= BIT_MASK(EV_KEY);
+
+	btntype = BTN_MISC;
+	if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
+#ifdef TABLET_SIMULATES_MOUSE
+		btntype = BTN_TOUCH;
+#else
+		btntype = BTN_DIGI;
+#endif
+	if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
+		btntype = BTN_TOUCH;
+
+	if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
+		btntype = BTN_MOUSE;
+
+	for (i = 0; i < ptr->nbtn; i++) {
+		__set_bit(btntype | i, input_dev->keybit);
+		ptr->btnmap[i] = btntype | i;
+	}
+
+	if (btntype == BTN_MOUSE) {
+		/* Swap buttons 2 and 3 */
+		ptr->btnmap[1] = BTN_MIDDLE;
+		ptr->btnmap[2] = BTN_RIGHT;
+	}
+
+	input_dev->name = strlen(ptr->rnm) ? ptr->rnm : "HIL pointer device";
+
+	printk(KERN_INFO PREFIX
+		"HIL pointer device found (did: 0x%02x, axis: %s)\n",
+		did, txt);
+	printk(KERN_INFO PREFIX
+		"HIL pointer has %i buttons and %i sets of %i axes\n",
+		ptr->nbtn, naxsets, ptr->naxes);
+}
+
+static int hil_dev_connect(struct serio *serio, struct serio_driver *drv)
+{
+	struct hil_dev *dev;
+	struct input_dev *input_dev;
+	uint8_t did, *idd;
+	int error;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!dev || !input_dev) {
+		error = -ENOMEM;
 		goto bail0;
+	}
 
-	if (serio_open(serio, drv))
-		goto bail1;
+	dev->serio = serio;
+	dev->dev = input_dev;
 
-	serio_set_drvdata(serio, kbd);
-	kbd->serio = serio;
+	error = serio_open(serio, drv);
+	if (error)
+		goto bail0;
 
-	init_MUTEX_LOCKED(&kbd->sem);
+	serio_set_drvdata(serio, dev);
 
 	/* Get device info.  MLC driver supplies devid/status/etc. */
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_IDD);
-	down(&kbd->sem);
-
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_RSC);
-	down(&kbd->sem);
-
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_RNM);
-	down(&kbd->sem);
-
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_EXD);
-	down(&kbd->sem);
-
-	up(&kbd->sem);
-
-	did = kbd->idd[0];
-	idd = kbd->idd + 1;
+	init_completion(&dev->cmd_done);
+	serio_write(serio, 0);
+	serio_write(serio, 0);
+	serio_write(serio, HIL_PKT_CMD >> 8);
+	serio_write(serio, HIL_CMD_IDD);
+	error = wait_for_completion_killable(&dev->cmd_done);
+	if (error)
+		goto bail1;
+
+	init_completion(&dev->cmd_done);
+	serio_write(serio, 0);
+	serio_write(serio, 0);
+	serio_write(serio, HIL_PKT_CMD >> 8);
+	serio_write(serio, HIL_CMD_RSC);
+	error = wait_for_completion_killable(&dev->cmd_done);
+	if (error)
+		goto bail1;
+
+	init_completion(&dev->cmd_done);
+	serio_write(serio, 0);
+	serio_write(serio, 0);
+	serio_write(serio, HIL_PKT_CMD >> 8);
+	serio_write(serio, HIL_CMD_RNM);
+	error = wait_for_completion_killable(&dev->cmd_done);
+	if (error)
+		goto bail1;
+
+	init_completion(&dev->cmd_done);
+	serio_write(serio, 0);
+	serio_write(serio, 0);
+	serio_write(serio, HIL_PKT_CMD >> 8);
+	serio_write(serio, HIL_CMD_EXD);
+	error = wait_for_completion_killable(&dev->cmd_done);
+	if (error)
+		goto bail1;
+
+	did = dev->idd[0];
+	idd = dev->idd + 1;
+
 	switch (did & HIL_IDD_DID_TYPE_MASK) {
 	case HIL_IDD_DID_TYPE_KB_INTEGRAL:
 	case HIL_IDD_DID_TYPE_KB_ITF:
 	case HIL_IDD_DID_TYPE_KB_RSVD:
 	case HIL_IDD_DID_TYPE_CHAR:
-		printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n",
-			did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
-		break;
-	default:
-		goto bail2;
-	}
+		if (HIL_IDD_NUM_BUTTONS(idd) ||
+		    HIL_IDD_NUM_AXES_PER_SET(*idd)) {
+			printk(KERN_INFO PREFIX
+				"combo devices are not supported.\n");
+			goto bail1;
+		}
 
-	if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) {
-		printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n");
-		goto bail2;
-	}
+		dev->is_pointer = false;
+		hil_dev_keyboard_setup(dev);
+		break;
 
-	kbd->dev->evbit[0]	= BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
-	kbd->dev->ledbit[0]	= BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
-		BIT_MASK(LED_SCROLLL);
-	kbd->dev->keycodemax	= HIL_KEYCODES_SET1_TBLSIZE;
-	kbd->dev->keycodesize	= sizeof(hil_kbd_set1[0]);
-	kbd->dev->keycode	= hil_kbd_set1;
-	kbd->dev->name		= strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
-	kbd->dev->phys		= "hpkbd/input0";	/* XXX */
-
-	kbd->dev->id.bustype	= BUS_HIL;
-	kbd->dev->id.vendor	= PCI_VENDOR_ID_HP;
-	kbd->dev->id.product	= 0x0001; /* TODO: get from kbd->rsc */
-	kbd->dev->id.version	= 0x0100; /* TODO: get from kbd->rsc */
-	kbd->dev->dev.parent	= &serio->dev;
+	case HIL_IDD_DID_TYPE_REL:
+	case HIL_IDD_DID_TYPE_ABS:
+		dev->is_pointer = true;
+		hil_dev_pointer_setup(dev);
+		break;
 
-	for (i = 0; i < 128; i++) {
-		set_bit(hil_kbd_set1[i], kbd->dev->keybit);
-		set_bit(hil_kbd_set3[i], kbd->dev->keybit);
+	default:
+		goto bail1;
 	}
-	clear_bit(0, kbd->dev->keybit);
 
-	input_register_device(kbd->dev);
-	printk(KERN_INFO "input: %s, ID: %d\n",
-		kbd->dev->name, did);
+	input_dev->id.bustype	= BUS_HIL;
+	input_dev->id.vendor	= PCI_VENDOR_ID_HP;
+	input_dev->id.product	= 0x0001; /* TODO: get from kbd->rsc */
+	input_dev->id.version	= 0x0100; /* TODO: get from kbd->rsc */
+	input_dev->dev.parent	= &serio->dev;
+
+	if (!dev->is_pointer) {
+		serio_write(serio, 0);
+		serio_write(serio, 0);
+		serio_write(serio, HIL_PKT_CMD >> 8);
+		/* Enable Keyswitch Autorepeat 1 */
+		serio_write(serio, HIL_CMD_EK1);
+		/* No need to wait for completion */
+	}
 
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */
-	down(&kbd->sem);
-	up(&kbd->sem);
+	error = input_register_device(input_dev);
+	if (error)
+		goto bail1;
 
 	return 0;
- bail2:
+
+ bail1:
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
- bail1:
-	input_free_device(kbd->dev);
  bail0:
-	kfree(kbd);
-	return -EIO;
+	input_free_device(input_dev);
+	kfree(dev);
+	return error;
 }
 
-static struct serio_device_id hil_kbd_ids[] = {
+static struct serio_device_id hil_dev_ids[] = {
 	{
 		.type = SERIO_HIL_MLC,
 		.proto = SERIO_HIL,
@@ -378,26 +567,26 @@ static struct serio_device_id hil_kbd_ids[] = {
 	{ 0 }
 };
 
-static struct serio_driver hil_kbd_serio_drv = {
+static struct serio_driver hil_serio_drv = {
 	.driver		= {
-		.name	= "hil_kbd",
+		.name	= "hil_dev",
 	},
-	.description	= "HP HIL keyboard driver",
-	.id_table	= hil_kbd_ids,
-	.connect	= hil_kbd_connect,
-	.disconnect	= hil_kbd_disconnect,
-	.interrupt	= hil_kbd_interrupt
+	.description	= "HP HIL keyboard/mouse/tablet driver",
+	.id_table	= hil_dev_ids,
+	.connect	= hil_dev_connect,
+	.disconnect	= hil_dev_disconnect,
+	.interrupt	= hil_dev_interrupt
 };
 
-static int __init hil_kbd_init(void)
+static int __init hil_dev_init(void)
 {
-	return serio_register_driver(&hil_kbd_serio_drv);
+	return serio_register_driver(&hil_serio_drv);
 }
 
-static void __exit hil_kbd_exit(void)
+static void __exit hil_dev_exit(void)
 {
-	serio_unregister_driver(&hil_kbd_serio_drv);
+	serio_unregister_driver(&hil_serio_drv);
 }
 
-module_init(hil_kbd_init);
-module_exit(hil_kbd_exit);
+module_init(hil_dev_init);
+module_exit(hil_dev_exit);
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 4730ef3..f9847e0 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -525,12 +525,12 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
 			CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
 			CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
 			if (leds_on != 0) {
-				lk->serio->write (lk->serio, LK_CMD_LED_ON);
-				lk->serio->write (lk->serio, leds_on);
+				serio_write (lk->serio, LK_CMD_LED_ON);
+				serio_write (lk->serio, leds_on);
 			}
 			if (leds_off != 0) {
-				lk->serio->write (lk->serio, LK_CMD_LED_OFF);
-				lk->serio->write (lk->serio, leds_off);
+				serio_write (lk->serio, LK_CMD_LED_OFF);
+				serio_write (lk->serio, leds_off);
 			}
 			return 0;
 
@@ -539,20 +539,20 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
 				case SND_CLICK:
 					if (value == 0) {
 						DBG ("%s: Deactivating key clicks\n", __func__);
-						lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
-						lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
+						serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
+						serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
 					} else {
 						DBG ("%s: Activating key clicks\n", __func__);
-						lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
-						lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
-						lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
-						lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
+						serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
+						serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
+						serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
+						serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
 					}
 					return 0;
 
 				case SND_BELL:
 					if (value != 0)
-						lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
+						serio_write (lk->serio, LK_CMD_SOUND_BELL);
 
 					return 0;
 			}
@@ -579,10 +579,10 @@ lkkbd_reinit (struct work_struct *work)
 	unsigned char leds_off = 0;
 
 	/* Ask for ID */
-	lk->serio->write (lk->serio, LK_CMD_REQUEST_ID);
+	serio_write (lk->serio, LK_CMD_REQUEST_ID);
 
 	/* Reset parameters */
-	lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS);
+	serio_write (lk->serio, LK_CMD_SET_DEFAULTS);
 
 	/* Set LEDs */
 	CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
@@ -590,12 +590,12 @@ lkkbd_reinit (struct work_struct *work)
 	CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
 	CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
 	if (leds_on != 0) {
-		lk->serio->write (lk->serio, LK_CMD_LED_ON);
-		lk->serio->write (lk->serio, leds_on);
+		serio_write (lk->serio, LK_CMD_LED_ON);
+		serio_write (lk->serio, leds_on);
 	}
 	if (leds_off != 0) {
-		lk->serio->write (lk->serio, LK_CMD_LED_OFF);
-		lk->serio->write (lk->serio, leds_off);
+		serio_write (lk->serio, LK_CMD_LED_OFF);
+		serio_write (lk->serio, leds_off);
 	}
 
 	/*
@@ -603,31 +603,31 @@ lkkbd_reinit (struct work_struct *work)
 	 * only work with a LK401 keyboard and grants access to
 	 * LAlt, RAlt, RCompose and RShift.
 	 */
-	lk->serio->write (lk->serio, LK_CMD_ENABLE_LK401);
+	serio_write (lk->serio, LK_CMD_ENABLE_LK401);
 
 	/* Set all keys to UPDOWN mode */
 	for (division = 1; division <= 14; division++)
-		lk->serio->write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
+		serio_write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
 					division));
 
 	/* Enable bell and set volume */
-	lk->serio->write (lk->serio, LK_CMD_ENABLE_BELL);
-	lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));
+	serio_write (lk->serio, LK_CMD_ENABLE_BELL);
+	serio_write (lk->serio, volume_to_hw (lk->bell_volume));
 
 	/* Enable/disable keyclick (and possibly set volume) */
 	if (test_bit (SND_CLICK, lk->dev->snd)) {
-		lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
-		lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
-		lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
-		lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
+		serio_write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
+		serio_write (lk->serio, volume_to_hw (lk->keyclick_volume));
+		serio_write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
+		serio_write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
 	} else {
-		lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
-		lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
+		serio_write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
+		serio_write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
 	}
 
 	/* Sound the bell if needed */
 	if (test_bit (SND_BELL, lk->dev->snd))
-		lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
+		serio_write (lk->serio, LK_CMD_SOUND_BELL);
 }
 
 /*
@@ -684,8 +684,10 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv)
 	input_dev->keycode = lk->keycode;
 	input_dev->keycodesize = sizeof (lk_keycode_t);
 	input_dev->keycodemax = LK_NUM_KEYCODES;
+
 	for (i = 0; i < LK_NUM_KEYCODES; i++)
-		set_bit (lk->keycode[i], input_dev->keybit);
+		__set_bit (lk->keycode[i], input_dev->keybit);
+	__clear_bit(KEY_RESERVED, input_dev->keybit);
 
 	serio_set_drvdata (serio, lk);
 
@@ -697,7 +699,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv)
 	if (err)
 		goto fail3;
 
-	lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
+	serio_write (lk->serio, LK_CMD_POWERCYCLE_RESET);
 
 	return 0;
 
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 541b981..91cfe51 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -319,7 +319,6 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 	struct input_dev *input_dev;
 	unsigned short *keycodes;
 	unsigned int row_shift;
-	int i;
 	int err;
 
 	pdata = pdev->dev.platform_data;
@@ -363,18 +362,10 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
 
 	input_dev->keycode	= keycodes;
 	input_dev->keycodesize	= sizeof(*keycodes);
-	input_dev->keycodemax	= pdata->num_row_gpios << keypad->row_shift;
-
-	for (i = 0; i < keymap_data->keymap_size; i++) {
-		unsigned int key = keymap_data->keymap[i];
-		unsigned int row = KEY_ROW(key);
-		unsigned int col = KEY_COL(key);
-		unsigned short code = KEY_VAL(key);
+	input_dev->keycodemax	= pdata->num_row_gpios << row_shift;
 
-		keycodes[MATRIX_SCAN_CODE(row, col, row_shift)] = code;
-		__set_bit(code, input_dev->keybit);
-	}
-	__clear_bit(KEY_RESERVED, input_dev->keybit);
+	matrix_keypad_build_keymap(keymap_data, row_shift,
+				   input_dev->keycode, input_dev->keybit);
 
 	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 	input_set_drvdata(input_dev, keypad);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 87ec7b1..bba85ad 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -116,7 +116,7 @@ static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
 		}
 	} else
 		/* disable keyboard interrupt and schedule for handling */
-		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+		omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 
 	tasklet_schedule(&kp_tasklet);
 
@@ -143,20 +143,20 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state)
 
 	} else {
 		/* disable keyboard interrupt and schedule for handling */
-		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+		omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 
 		/* read the keypad status */
-		omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+		omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 		for (col = 0; col < omap_kp->cols; col++) {
 			omap_writew(~(1 << col) & 0xff,
-				    OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+				    OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 
 			udelay(omap_kp->delay);
 
-			state[col] = ~omap_readw(OMAP_MPUIO_BASE +
+			state[col] = ~omap_readw(OMAP1_MPUIO_BASE +
 						 OMAP_MPUIO_KBR_LATCH) & 0xff;
 		}
-		omap_writew(0x00, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
+		omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 		udelay(2);
 	}
 }
@@ -234,7 +234,7 @@ static void omap_kp_tasklet(unsigned long data)
 			for (i = 0; i < omap_kp_data->rows; i++)
 				enable_irq(gpio_to_irq(row_gpios[i]));
 		} else {
-			omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+			omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 			kp_cur_group = -1;
 		}
 	}
@@ -317,7 +317,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
 
 	/* Disable the interrupt for the MPUIO keyboard */
 	if (!cpu_is_omap24xx())
-		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+		omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 
 	keymap = pdata->keymap;
 
@@ -391,7 +391,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
 	}
 
 	if (pdata->dbounce)
-		omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
+		omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
 
 	/* scan current status and enable interrupt */
 	omap_kp_scan_keypad(omap_kp, keypad_state);
@@ -402,7 +402,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev)
 					"omap-keypad", omap_kp) < 0)
 				goto err4;
 		}
-		omap_writew(0, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+		omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 	} else {
 		for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
 			if (request_irq(gpio_to_irq(row_gpios[irq_idx]),
@@ -449,7 +449,7 @@ static int __devexit omap_kp_remove(struct platform_device *pdev)
 			free_irq(gpio_to_irq(row_gpios[i]), 0);
 		}
 	} else {
-		omap_writew(1, OMAP_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
+		omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 		free_irq(omap_kp->irq, 0);
 	}
 
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c
index 0d2fc64..79cd3e9 100644
--- a/drivers/input/keyboard/pxa27x_keypad.c
+++ b/drivers/input/keyboard/pxa27x_keypad.c
@@ -8,7 +8,7 @@
  *
  * Based on a previous implementations by Kevin O'Connor
  * <kevin_at_koconnor.net> and Alex Osborne <bobofdoom@gmail.com> and
- * on some suggestions by Nicolas Pitre <nico@cam.org>.
+ * on some suggestions by Nicolas Pitre <nico@fluxnic.net>.
  *
  * 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
@@ -25,13 +25,13 @@
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/input/matrix_keypad.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
 #include <mach/hardware.h>
 #include <mach/pxa27x_keypad.h>
-
 /*
  * Keypad Controller registers
  */
@@ -95,7 +95,8 @@
 #define keypad_readl(off)	__raw_readl(keypad->mmio_base + (off))
 #define keypad_writel(off, v)	__raw_writel((v), keypad->mmio_base + (off))
 
-#define MAX_MATRIX_KEY_NUM	(8 * 8)
+#define MAX_MATRIX_KEY_NUM	(MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS)
+#define MAX_KEYPAD_KEYS		(MAX_MATRIX_KEY_NUM + MAX_DIRECT_KEY_NUM)
 
 struct pxa27x_keypad {
 	struct pxa27x_keypad_platform_data *pdata;
@@ -106,73 +107,82 @@ struct pxa27x_keypad {
 
 	int irq;
 
-	/* matrix key code map */
-	unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM];
+	unsigned short keycodes[MAX_KEYPAD_KEYS];
+	int rotary_rel_code[2];
 
 	/* state row bits of each column scan */
 	uint32_t matrix_key_state[MAX_MATRIX_KEY_COLS];
 	uint32_t direct_key_state;
 
 	unsigned int direct_key_mask;
-
-	int rotary_rel_code[2];
-	int rotary_up_key[2];
-	int rotary_down_key[2];
 };
 
 static void pxa27x_keypad_build_keycode(struct pxa27x_keypad *keypad)
 {
 	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
 	struct input_dev *input_dev = keypad->input_dev;
-	unsigned int *key;
+	unsigned short keycode;
 	int i;
 
-	key = &pdata->matrix_key_map[0];
-	for (i = 0; i < pdata->matrix_key_map_size; i++, key++) {
-		int row = ((*key) >> 28) & 0xf;
-		int col = ((*key) >> 24) & 0xf;
-		int code = (*key) & 0xffffff;
+	for (i = 0; i < pdata->matrix_key_map_size; i++) {
+		unsigned int key = pdata->matrix_key_map[i];
+		unsigned int row = KEY_ROW(key);
+		unsigned int col = KEY_COL(key);
+		unsigned int scancode = MATRIX_SCAN_CODE(row, col,
+							 MATRIX_ROW_SHIFT);
 
-		keypad->matrix_keycodes[(row << 3) + col] = code;
-		set_bit(code, input_dev->keybit);
+		keycode = KEY_VAL(key);
+		keypad->keycodes[scancode] = keycode;
+		__set_bit(keycode, input_dev->keybit);
 	}
 
-	for (i = 0; i < pdata->direct_key_num; i++)
-		set_bit(pdata->direct_key_map[i], input_dev->keybit);
-
-	keypad->rotary_up_key[0] = pdata->rotary0_up_key;
-	keypad->rotary_up_key[1] = pdata->rotary1_up_key;
-	keypad->rotary_down_key[0] = pdata->rotary0_down_key;
-	keypad->rotary_down_key[1] = pdata->rotary1_down_key;
-	keypad->rotary_rel_code[0] = pdata->rotary0_rel_code;
-	keypad->rotary_rel_code[1] = pdata->rotary1_rel_code;
+	for (i = 0; i < pdata->direct_key_num; i++) {
+		keycode = pdata->direct_key_map[i];
+		keypad->keycodes[MAX_MATRIX_KEY_NUM + i] = keycode;
+		__set_bit(keycode, input_dev->keybit);
+	}
 
 	if (pdata->enable_rotary0) {
 		if (pdata->rotary0_up_key && pdata->rotary0_down_key) {
-			set_bit(pdata->rotary0_up_key, input_dev->keybit);
-			set_bit(pdata->rotary0_down_key, input_dev->keybit);
-		} else
-			set_bit(pdata->rotary0_rel_code, input_dev->relbit);
+			keycode = pdata->rotary0_up_key;
+			keypad->keycodes[MAX_MATRIX_KEY_NUM + 0] = keycode;
+			__set_bit(keycode, input_dev->keybit);
+
+			keycode = pdata->rotary0_down_key;
+			keypad->keycodes[MAX_MATRIX_KEY_NUM + 1] = keycode;
+			__set_bit(keycode, input_dev->keybit);
+
+			keypad->rotary_rel_code[0] = -1;
+		} else {
+			keypad->rotary_rel_code[0] = pdata->rotary0_rel_code;
+			__set_bit(pdata->rotary0_rel_code, input_dev->relbit);
+		}
 	}
 
 	if (pdata->enable_rotary1) {
 		if (pdata->rotary1_up_key && pdata->rotary1_down_key) {
-			set_bit(pdata->rotary1_up_key, input_dev->keybit);
-			set_bit(pdata->rotary1_down_key, input_dev->keybit);
-		} else
-			set_bit(pdata->rotary1_rel_code, input_dev->relbit);
+			keycode = pdata->rotary1_up_key;
+			keypad->keycodes[MAX_MATRIX_KEY_NUM + 2] = keycode;
+			__set_bit(keycode, input_dev->keybit);
+
+			keycode = pdata->rotary1_down_key;
+			keypad->keycodes[MAX_MATRIX_KEY_NUM + 3] = keycode;
+			__set_bit(keycode, input_dev->keybit);
+
+			keypad->rotary_rel_code[1] = -1;
+		} else {
+			keypad->rotary_rel_code[1] = pdata->rotary1_rel_code;
+			__set_bit(pdata->rotary1_rel_code, input_dev->relbit);
+		}
 	}
-}
 
-static inline unsigned int lookup_matrix_keycode(
-		struct pxa27x_keypad *keypad, int row, int col)
-{
-	return keypad->matrix_keycodes[(row << 3) + col];
+	__clear_bit(KEY_RESERVED, input_dev->keybit);
 }
 
 static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
 {
 	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	struct input_dev *input_dev = keypad->input_dev;
 	int row, col, num_keys_pressed = 0;
 	uint32_t new_state[MAX_MATRIX_KEY_COLS];
 	uint32_t kpas = keypad_readl(KPAS);
@@ -215,6 +225,7 @@ static void pxa27x_keypad_scan_matrix(struct pxa27x_keypad *keypad)
 scan:
 	for (col = 0; col < pdata->matrix_key_cols; col++) {
 		uint32_t bits_changed;
+		int code;
 
 		bits_changed = keypad->matrix_key_state[col] ^ new_state[col];
 		if (bits_changed == 0)
@@ -224,12 +235,13 @@ scan:
 			if ((bits_changed & (1 << row)) == 0)
 				continue;
 
-			input_report_key(keypad->input_dev,
-				lookup_matrix_keycode(keypad, row, col),
-				new_state[col] & (1 << row));
+			code = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT);
+			input_event(input_dev, EV_MSC, MSC_SCAN, code);
+			input_report_key(input_dev, keypad->keycodes[code],
+					 new_state[col] & (1 << row));
 		}
 	}
-	input_sync(keypad->input_dev);
+	input_sync(input_dev);
 	memcpy(keypad->matrix_key_state, new_state, sizeof(new_state));
 }
 
@@ -252,13 +264,15 @@ static void report_rotary_event(struct pxa27x_keypad *keypad, int r, int delta)
 	if (delta == 0)
 		return;
 
-	if (keypad->rotary_up_key[r] && keypad->rotary_down_key[r]) {
-		int keycode = (delta > 0) ? keypad->rotary_up_key[r] :
-					    keypad->rotary_down_key[r];
+	if (keypad->rotary_rel_code[r] == -1) {
+		int code = MAX_MATRIX_KEY_NUM + 2 * r + (delta > 0 ? 0 : 1);
+		unsigned char keycode = keypad->keycodes[code];
 
 		/* simulate a press-n-release */
+		input_event(dev, EV_MSC, MSC_SCAN, code);
 		input_report_key(dev, keycode, 1);
 		input_sync(dev);
+		input_event(dev, EV_MSC, MSC_SCAN, code);
 		input_report_key(dev, keycode, 0);
 		input_sync(dev);
 	} else {
@@ -286,6 +300,7 @@ static void pxa27x_keypad_scan_rotary(struct pxa27x_keypad *keypad)
 static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 {
 	struct pxa27x_keypad_platform_data *pdata = keypad->pdata;
+	struct input_dev *input_dev = keypad->input_dev;
 	unsigned int new_state;
 	uint32_t kpdk, bits_changed;
 	int i;
@@ -295,9 +310,6 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 	if (pdata->enable_rotary0 || pdata->enable_rotary1)
 		pxa27x_keypad_scan_rotary(keypad);
 
-	if (pdata->direct_key_map == NULL)
-		return;
-
 	new_state = KPDK_DK(kpdk) & keypad->direct_key_mask;
 	bits_changed = keypad->direct_key_state ^ new_state;
 
@@ -305,12 +317,15 @@ static void pxa27x_keypad_scan_direct(struct pxa27x_keypad *keypad)
 		return;
 
 	for (i = 0; i < pdata->direct_key_num; i++) {
-		if (bits_changed & (1 << i))
-			input_report_key(keypad->input_dev,
-					pdata->direct_key_map[i],
-					(new_state & (1 << i)));
+		if (bits_changed & (1 << i)) {
+			int code = MAX_MATRIX_KEY_NUM + i;
+
+			input_event(input_dev, EV_MSC, MSC_SCAN, code);
+			input_report_key(input_dev, keypad->keycodes[code],
+					 new_state & (1 << i));
+		}
 	}
-	input_sync(keypad->input_dev);
+	input_sync(input_dev);
 	keypad->direct_key_state = new_state;
 }
 
@@ -388,8 +403,9 @@ static void pxa27x_keypad_close(struct input_dev *dev)
 }
 
 #ifdef CONFIG_PM
-static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t state)
+static int pxa27x_keypad_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
 
 	clk_disable(keypad->clk);
@@ -400,8 +416,9 @@ static int pxa27x_keypad_suspend(struct platform_device *pdev, pm_message_t stat
 	return 0;
 }
 
-static int pxa27x_keypad_resume(struct platform_device *pdev)
+static int pxa27x_keypad_resume(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct pxa27x_keypad *keypad = platform_get_drvdata(pdev);
 	struct input_dev *input_dev = keypad->input_dev;
 
@@ -420,55 +437,58 @@ static int pxa27x_keypad_resume(struct platform_device *pdev)
 
 	return 0;
 }
-#else
-#define pxa27x_keypad_suspend	NULL
-#define pxa27x_keypad_resume	NULL
-#endif
 
-#define res_size(res)	((res)->end - (res)->start + 1)
+static const struct dev_pm_ops pxa27x_keypad_pm_ops = {
+	.suspend	= pxa27x_keypad_suspend,
+	.resume		= pxa27x_keypad_resume,
+};
+#endif
 
 static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
 {
+	struct pxa27x_keypad_platform_data *pdata = pdev->dev.platform_data;
 	struct pxa27x_keypad *keypad;
 	struct input_dev *input_dev;
 	struct resource *res;
 	int irq, error;
 
-	keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
-	if (keypad == NULL) {
-		dev_err(&pdev->dev, "failed to allocate driver data\n");
-		return -ENOMEM;
-	}
-
-	keypad->pdata = pdev->dev.platform_data;
-	if (keypad->pdata == NULL) {
+	if (pdata == NULL) {
 		dev_err(&pdev->dev, "no platform data defined\n");
-		error = -EINVAL;
-		goto failed_free;
+		return -EINVAL;
 	}
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		dev_err(&pdev->dev, "failed to get keypad irq\n");
-		error = -ENXIO;
-		goto failed_free;
+		return -ENXIO;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
 		dev_err(&pdev->dev, "failed to get I/O memory\n");
-		error = -ENXIO;
+		return -ENXIO;
+	}
+
+	keypad = kzalloc(sizeof(struct pxa27x_keypad), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!keypad || !input_dev) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		error = -ENOMEM;
 		goto failed_free;
 	}
 
-	res = request_mem_region(res->start, res_size(res), pdev->name);
+	keypad->pdata = pdata;
+	keypad->input_dev = input_dev;
+	keypad->irq = irq;
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
 	if (res == NULL) {
 		dev_err(&pdev->dev, "failed to request I/O memory\n");
 		error = -EBUSY;
 		goto failed_free;
 	}
 
-	keypad->mmio_base = ioremap(res->start, res_size(res));
+	keypad->mmio_base = ioremap(res->start, resource_size(res));
 	if (keypad->mmio_base == NULL) {
 		dev_err(&pdev->dev, "failed to remap I/O memory\n");
 		error = -ENXIO;
@@ -482,43 +502,35 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
 		goto failed_free_io;
 	}
 
-	/* Create and register the input driver. */
-	input_dev = input_allocate_device();
-	if (!input_dev) {
-		dev_err(&pdev->dev, "failed to allocate input device\n");
-		error = -ENOMEM;
-		goto failed_put_clk;
-	}
-
 	input_dev->name = pdev->name;
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->open = pxa27x_keypad_open;
 	input_dev->close = pxa27x_keypad_close;
 	input_dev->dev.parent = &pdev->dev;
 
-	keypad->input_dev = input_dev;
+	input_dev->keycode = keypad->keycodes;
+	input_dev->keycodesize = sizeof(keypad->keycodes[0]);
+	input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes);
+
 	input_set_drvdata(input_dev, keypad);
 
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
-	if ((keypad->pdata->enable_rotary0 &&
-			keypad->pdata->rotary0_rel_code) ||
-	    (keypad->pdata->enable_rotary1 &&
-			keypad->pdata->rotary1_rel_code)) {
-		input_dev->evbit[0] |= BIT_MASK(EV_REL);
-	}
+	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
 
 	pxa27x_keypad_build_keycode(keypad);
-	platform_set_drvdata(pdev, keypad);
+
+	if ((pdata->enable_rotary0 && keypad->rotary_rel_code[0] != -1) ||
+	    (pdata->enable_rotary1 && keypad->rotary_rel_code[1] != -1)) {
+		input_dev->evbit[0] |= BIT_MASK(EV_REL);
+	}
 
 	error = request_irq(irq, pxa27x_keypad_irq_handler, IRQF_DISABLED,
 			    pdev->name, keypad);
 	if (error) {
 		dev_err(&pdev->dev, "failed to request IRQ\n");
-		goto failed_free_dev;
+		goto failed_put_clk;
 	}
 
-	keypad->irq = irq;
-
 	/* Register the input device */
 	error = input_register_device(input_dev);
 	if (error) {
@@ -526,22 +538,21 @@ static int __devinit pxa27x_keypad_probe(struct platform_device *pdev)
 		goto failed_free_irq;
 	}
 
+	platform_set_drvdata(pdev, keypad);
 	device_init_wakeup(&pdev->dev, 1);
 
 	return 0;
 
 failed_free_irq:
 	free_irq(irq, pdev);
-	platform_set_drvdata(pdev, NULL);
-failed_free_dev:
-	input_free_device(input_dev);
 failed_put_clk:
 	clk_put(keypad->clk);
 failed_free_io:
 	iounmap(keypad->mmio_base);
 failed_free_mem:
-	release_mem_region(res->start, res_size(res));
+	release_mem_region(res->start, resource_size(res));
 failed_free:
+	input_free_device(input_dev);
 	kfree(keypad);
 	return error;
 }
@@ -552,8 +563,6 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
 	struct resource *res;
 
 	free_irq(keypad->irq, pdev);
-
-	clk_disable(keypad->clk);
 	clk_put(keypad->clk);
 
 	input_unregister_device(keypad->input_dev);
@@ -562,10 +571,11 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev)
 	iounmap(keypad->mmio_base);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res_size(res));
+	release_mem_region(res->start, resource_size(res));
 
 	platform_set_drvdata(pdev, NULL);
 	kfree(keypad);
+
 	return 0;
 }
 
@@ -575,11 +585,12 @@ MODULE_ALIAS("platform:pxa27x-keypad");
 static struct platform_driver pxa27x_keypad_driver = {
 	.probe		= pxa27x_keypad_probe,
 	.remove		= __devexit_p(pxa27x_keypad_remove),
-	.suspend	= pxa27x_keypad_suspend,
-	.resume		= pxa27x_keypad_resume,
 	.driver		= {
 		.name	= "pxa27x-keypad",
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &pxa27x_keypad_pm_ops,
+#endif
 	},
 };
 
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index cea70e6..887af79 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -80,6 +80,9 @@ static irqreturn_t sh_keysc_isr(int irq, void *dev_id)
 		iowrite16(KYCR2_IRQ_LEVEL | (keyin_set << 8),
 			  priv->iomem_base + KYCR2_OFFS);
 
+		if (pdata->kycr2_delay)
+			udelay(pdata->kycr2_delay);
+
 		keys ^= ~0;
 		keys &= (1 << (sh_keysc_mode[pdata->mode].keyin *
 			       sh_keysc_mode[pdata->mode].keyout)) - 1;
@@ -128,7 +131,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct input_dev *input;
 	char clk_name[8];
-	int i, k;
+	int i;
 	int irq, error;
 
 	if (!pdev->dev.platform_data) {
@@ -195,17 +198,19 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
 	input->id.product = 0x0001;
 	input->id.version = 0x0100;
 
+	input->keycode = pdata->keycodes;
+	input->keycodesize = sizeof(pdata->keycodes[0]);
+	input->keycodemax = ARRAY_SIZE(pdata->keycodes);
+
 	error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
 	if (error) {
 		dev_err(&pdev->dev, "failed to request IRQ\n");
 		goto err4;
 	}
 
-	for (i = 0; i < SH_KEYSC_MAXKEYS; i++) {
-		k = pdata->keycodes[i];
-		if (k)
-			input_set_capability(input, EV_KEY, k);
-	}
+	for (i = 0; i < SH_KEYSC_MAXKEYS; i++)
+		__set_bit(pdata->keycodes[i], input->keybit);
+	__clear_bit(KEY_RESERVED, input->keybit);
 
 	error = input_register_device(input);
 	if (error) {
@@ -221,7 +226,9 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev)
 	iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS);
 
 	device_init_wakeup(&pdev->dev, 1);
+
 	return 0;
+
  err5:
 	free_irq(irq, pdev);
  err4:
@@ -252,6 +259,7 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
+
 	return 0;
 }
 
@@ -267,11 +275,12 @@ static int sh_keysc_suspend(struct device *dev)
 	if (device_may_wakeup(dev)) {
 		value |= 0x80;
 		enable_irq_wake(irq);
-	}
-	else
+	} else {
 		value &= ~0x80;
+	}
 
 	iowrite16(value, priv->iomem_base + KYCR1_OFFS);
+
 	return 0;
 }
 
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 9fce6d1..472b566 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -73,7 +73,7 @@ static unsigned char sunkbd_keycode[128] = {
  */
 
 struct sunkbd {
-	unsigned char keycode[128];
+	unsigned char keycode[ARRAY_SIZE(sunkbd_keycode)];
 	struct input_dev *dev;
 	struct serio *serio;
 	struct work_struct tq;
@@ -81,7 +81,7 @@ struct sunkbd {
 	char name[64];
 	char phys[32];
 	char type;
-	unsigned char enabled;
+	bool enabled;
 	volatile s8 reset;
 	volatile s8 layout;
 };
@@ -94,10 +94,14 @@ struct sunkbd {
 static irqreturn_t sunkbd_interrupt(struct serio *serio,
 		unsigned char data, unsigned int flags)
 {
-	struct sunkbd* sunkbd = serio_get_drvdata(serio);
+	struct sunkbd *sunkbd = serio_get_drvdata(serio);
 
-	if (sunkbd->reset <= -1) {		/* If cp[i] is 0xff, sunkbd->reset will stay -1. */
-		sunkbd->reset = data;		/* The keyboard sends 0xff 0xff 0xID on powerup */
+	if (sunkbd->reset <= -1) {
+		/*
+		 * If cp[i] is 0xff, sunkbd->reset will stay -1.
+		 * The keyboard sends 0xff 0xff 0xID on powerup.
+		 */
+		sunkbd->reset = data;
 		wake_up_interruptible(&sunkbd->wait);
 		goto out;
 	}
@@ -110,29 +114,33 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
 
 	switch (data) {
 
-		case SUNKBD_RET_RESET:
-			schedule_work(&sunkbd->tq);
-			sunkbd->reset = -1;
-			break;
+	case SUNKBD_RET_RESET:
+		schedule_work(&sunkbd->tq);
+		sunkbd->reset = -1;
+		break;
 
-		case SUNKBD_RET_LAYOUT:
-			sunkbd->layout = -1;
-			break;
+	case SUNKBD_RET_LAYOUT:
+		sunkbd->layout = -1;
+		break;
+
+	case SUNKBD_RET_ALLUP: /* All keys released */
+		break;
 
-		case SUNKBD_RET_ALLUP: /* All keys released */
+	default:
+		if (!sunkbd->enabled)
 			break;
 
-		default:
-			if (!sunkbd->enabled)
-				break;
-
-			if (sunkbd->keycode[data & SUNKBD_KEY]) {
-                                input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
-				input_sync(sunkbd->dev);
-                        } else {
-                                printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n",
-                                        data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed");
-                        }
+		if (sunkbd->keycode[data & SUNKBD_KEY]) {
+			input_report_key(sunkbd->dev,
+					 sunkbd->keycode[data & SUNKBD_KEY],
+					 !(data & SUNKBD_RELEASE));
+			input_sync(sunkbd->dev);
+		} else {
+			printk(KERN_WARNING
+				"sunkbd.c: Unknown key (scancode %#x) %s.\n",
+				data & SUNKBD_KEY,
+				data & SUNKBD_RELEASE ? "released" : "pressed");
+		}
 	}
 out:
 	return IRQ_HANDLED;
@@ -142,34 +150,37 @@ out:
  * sunkbd_event() handles events from the input module.
  */
 
-static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+static int sunkbd_event(struct input_dev *dev,
+			unsigned int type, unsigned int code, int value)
 {
 	struct sunkbd *sunkbd = input_get_drvdata(dev);
 
 	switch (type) {
 
-		case EV_LED:
+	case EV_LED:
 
-			sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
-			sunkbd->serio->write(sunkbd->serio,
-				(!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) |
-				(!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led));
-			return 0;
+		serio_write(sunkbd->serio, SUNKBD_CMD_SETLED);
+		serio_write(sunkbd->serio,
+			(!!test_bit(LED_CAPSL,   dev->led) << 3) |
+			(!!test_bit(LED_SCROLLL, dev->led) << 2) |
+			(!!test_bit(LED_COMPOSE, dev->led) << 1) |
+			 !!test_bit(LED_NUML,    dev->led));
+		return 0;
 
-		case EV_SND:
+	case EV_SND:
 
-			switch (code) {
+		switch (code) {
 
-				case SND_CLICK:
-					sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
-					return 0;
+		case SND_CLICK:
+			serio_write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
+			return 0;
 
-				case SND_BELL:
-					sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
-					return 0;
-			}
+		case SND_BELL:
+			serio_write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
+			return 0;
+		}
 
-			break;
+		break;
 	}
 
 	return -1;
@@ -183,7 +194,7 @@ static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int c
 static int sunkbd_initialize(struct sunkbd *sunkbd)
 {
 	sunkbd->reset = -2;
-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
+	serio_write(sunkbd->serio, SUNKBD_CMD_RESET);
 	wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
 	if (sunkbd->reset < 0)
 		return -1;
@@ -192,10 +203,13 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
 
 	if (sunkbd->type == 4) {	/* Type 4 keyboard */
 		sunkbd->layout = -2;
-		sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_LAYOUT);
-		wait_event_interruptible_timeout(sunkbd->wait, sunkbd->layout >= 0, HZ/4);
-		if (sunkbd->layout < 0) return -1;
-		if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK) sunkbd->type = 5;
+		serio_write(sunkbd->serio, SUNKBD_CMD_LAYOUT);
+		wait_event_interruptible_timeout(sunkbd->wait,
+						 sunkbd->layout >= 0, HZ / 4);
+		if (sunkbd->layout < 0)
+			return -1;
+		if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK)
+			sunkbd->type = 5;
 	}
 
 	return 0;
@@ -212,15 +226,19 @@ static void sunkbd_reinit(struct work_struct *work)
 
 	wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
 
-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
-	sunkbd->serio->write(sunkbd->serio,
-		(!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
-		(!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | !!test_bit(LED_NUML, sunkbd->dev->led));
-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
+	serio_write(sunkbd->serio, SUNKBD_CMD_SETLED);
+	serio_write(sunkbd->serio,
+		(!!test_bit(LED_CAPSL,   sunkbd->dev->led) << 3) |
+		(!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
+		(!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) |
+		 !!test_bit(LED_NUML,    sunkbd->dev->led));
+	serio_write(sunkbd->serio,
+		SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
+	serio_write(sunkbd->serio,
+		SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
 }
 
-static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
+static void sunkbd_enable(struct sunkbd *sunkbd, bool enable)
 {
 	serio_pause_rx(sunkbd->serio);
 	sunkbd->enabled = enable;
@@ -228,7 +246,8 @@ static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
 }
 
 /*
- * sunkbd_connect() probes for a Sun keyboard and fills the necessary structures.
+ * sunkbd_connect() probes for a Sun keyboard and fills the necessary
+ * structures.
  */
 
 static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
@@ -260,7 +279,8 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 		goto fail3;
 	}
 
-	snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type);
+	snprintf(sunkbd->name, sizeof(sunkbd->name),
+		 "Sun Type %d keyboard", sunkbd->type);
 	memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
 
 	input_dev->name = sunkbd->name;
@@ -284,11 +304,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 	input_dev->keycode = sunkbd->keycode;
 	input_dev->keycodesize = sizeof(unsigned char);
 	input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode);
-	for (i = 0; i < 128; i++)
-		set_bit(sunkbd->keycode[i], input_dev->keybit);
-	clear_bit(0, input_dev->keybit);
+	for (i = 0; i < ARRAY_SIZE(sunkbd_keycode); i++)
+		__set_bit(sunkbd->keycode[i], input_dev->keybit);
+	__clear_bit(KEY_RESERVED, input_dev->keybit);
 
-	sunkbd_enable(sunkbd, 1);
+	sunkbd_enable(sunkbd, true);
 
 	err = input_register_device(sunkbd->dev);
 	if (err)
@@ -296,7 +316,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 
 	return 0;
 
- fail4:	sunkbd_enable(sunkbd, 0);
+ fail4:	sunkbd_enable(sunkbd, false);
  fail3:	serio_close(serio);
  fail2:	serio_set_drvdata(serio, NULL);
  fail1:	input_free_device(input_dev);
@@ -312,7 +332,7 @@ static void sunkbd_disconnect(struct serio *serio)
 {
 	struct sunkbd *sunkbd = serio_get_drvdata(serio);
 
-	sunkbd_enable(sunkbd, 0);
+	sunkbd_enable(sunkbd, false);
 	input_unregister_device(sunkbd->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
index 677276b..42cb3fa 100644
--- a/drivers/input/keyboard/tosakbd.c
+++ b/drivers/input/keyboard/tosakbd.c
@@ -31,7 +31,7 @@
 #define KB_DISCHARGE_DELAY	10
 #define KB_ACTIVATE_DELAY	10
 
-static unsigned int tosakbd_keycode[NR_SCANCODES] = {
+static unsigned short tosakbd_keycode[NR_SCANCODES] = {
 0,
 0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P,
 0, 0, 0, 0, 0, 0, 0, 0,
@@ -50,9 +50,9 @@ KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_
 };
 
 struct tosakbd {
-	unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)];
+	unsigned short keycode[ARRAY_SIZE(tosakbd_keycode)];
 	struct input_dev *input;
-	int suspended;
+	bool suspended;
 	spinlock_t lock; /* protect kbd scanning */
 	struct timer_list timer;
 };
@@ -215,7 +215,7 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
 	unsigned long flags;
 
 	spin_lock_irqsave(&tosakbd->lock, flags);
-	tosakbd->suspended = 1;
+	tosakbd->suspended = true;
 	spin_unlock_irqrestore(&tosakbd->lock, flags);
 
 	del_timer_sync(&tosakbd->timer);
@@ -227,7 +227,7 @@ static int tosakbd_resume(struct platform_device *dev)
 {
 	struct tosakbd *tosakbd = platform_get_drvdata(dev);
 
-	tosakbd->suspended = 0;
+	tosakbd->suspended = false;
 	tosakbd_scankeyboard(dev);
 
 	return 0;
@@ -277,14 +277,14 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) {
 
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
 	input_dev->keycode = tosakbd->keycode;
-	input_dev->keycodesize = sizeof(unsigned int);
+	input_dev->keycodesize = sizeof(tosakbd->keycode[0]);
 	input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode);
 
 	memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode));
 
 	for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++)
 		__set_bit(tosakbd->keycode[i], input_dev->keybit);
-	clear_bit(0, input_dev->keybit);
+	__clear_bit(KEY_RESERVED, input_dev->keybit);
 
 	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
 	for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
@@ -344,7 +344,7 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) {
 				" direction for GPIO %d, error %d\n",
 				gpio, error);
 			gpio_free(gpio);
-			goto fail;
+			goto fail2;
 		}
 
 	}
@@ -353,7 +353,7 @@ static int __devinit tosakbd_probe(struct platform_device *pdev) {
 	if (error) {
 		printk(KERN_ERR "tosakbd: Unable to register input device, "
 			"error: %d\n", error);
-		goto fail;
+		goto fail2;
 	}
 
 	printk(KERN_INFO "input: Tosa Keyboard Registered\n");
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c
new file mode 100644
index 0000000..9a2977c
--- /dev/null
+++ b/drivers/input/keyboard/twl4030_keypad.c
@@ -0,0 +1,480 @@
+/*
+ * twl4030_keypad.c - driver for 8x8 keypad controller in twl4030 chips
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Code re-written for 2430SDP by:
+ * Syed Mohammed Khasim <x0khasim@ti.com>
+ *
+ * Initial Code:
+ * Manjunatha G K <manjugk@ti.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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * The TWL4030 family chips include a keypad controller that supports
+ * up to an 8x8 switch matrix.  The controller can issue system wakeup
+ * events, since it uses only the always-on 32KiHz oscillator, and has
+ * an internal state machine that decodes pressed keys, including
+ * multi-key combinations.
+ *
+ * This driver lets boards define what keycodes they wish to report for
+ * which scancodes, as part of the "struct twl4030_keypad_data" used in
+ * the probe() routine.
+ *
+ * See the TPS65950 documentation; that's the general availability
+ * version of the TWL5030 second generation part.
+ */
+#define TWL4030_MAX_ROWS	8	/* TWL4030 hard limit */
+#define TWL4030_MAX_COLS	8
+#define TWL4030_ROW_SHIFT	3
+#define TWL4030_KEYMAP_SIZE	(TWL4030_MAX_ROWS * TWL4030_MAX_COLS)
+
+struct twl4030_keypad {
+	unsigned short	keymap[TWL4030_KEYMAP_SIZE];
+	u16		kp_state[TWL4030_MAX_ROWS];
+	unsigned	n_rows;
+	unsigned	n_cols;
+	unsigned	irq;
+
+	struct device *dbg_dev;
+	struct input_dev *input;
+};
+
+/*----------------------------------------------------------------------*/
+
+/* arbitrary prescaler value 0..7 */
+#define PTV_PRESCALER			4
+
+/* Register Offsets */
+#define KEYP_CTRL			0x00
+#define KEYP_DEB			0x01
+#define KEYP_LONG_KEY			0x02
+#define KEYP_LK_PTV			0x03
+#define KEYP_TIMEOUT_L			0x04
+#define KEYP_TIMEOUT_H			0x05
+#define KEYP_KBC			0x06
+#define KEYP_KBR			0x07
+#define KEYP_SMS			0x08
+#define KEYP_FULL_CODE_7_0		0x09	/* row 0 column status */
+#define KEYP_FULL_CODE_15_8		0x0a	/* ... row 1 ... */
+#define KEYP_FULL_CODE_23_16		0x0b
+#define KEYP_FULL_CODE_31_24		0x0c
+#define KEYP_FULL_CODE_39_32		0x0d
+#define KEYP_FULL_CODE_47_40		0x0e
+#define KEYP_FULL_CODE_55_48		0x0f
+#define KEYP_FULL_CODE_63_56		0x10
+#define KEYP_ISR1			0x11
+#define KEYP_IMR1			0x12
+#define KEYP_ISR2			0x13
+#define KEYP_IMR2			0x14
+#define KEYP_SIR			0x15
+#define KEYP_EDR			0x16	/* edge triggers */
+#define KEYP_SIH_CTRL			0x17
+
+/* KEYP_CTRL_REG Fields */
+#define KEYP_CTRL_SOFT_NRST		BIT(0)
+#define KEYP_CTRL_SOFTMODEN		BIT(1)
+#define KEYP_CTRL_LK_EN			BIT(2)
+#define KEYP_CTRL_TOE_EN		BIT(3)
+#define KEYP_CTRL_TOLE_EN		BIT(4)
+#define KEYP_CTRL_RP_EN			BIT(5)
+#define KEYP_CTRL_KBD_ON		BIT(6)
+
+/* KEYP_DEB, KEYP_LONG_KEY, KEYP_TIMEOUT_x*/
+#define KEYP_PERIOD_US(t, prescale)	((t) / (31 << (prescale + 1)) - 1)
+
+/* KEYP_LK_PTV_REG Fields */
+#define KEYP_LK_PTV_PTV_SHIFT		5
+
+/* KEYP_{IMR,ISR,SIR} Fields */
+#define KEYP_IMR1_MIS			BIT(3)
+#define KEYP_IMR1_TO			BIT(2)
+#define KEYP_IMR1_LK			BIT(1)
+#define KEYP_IMR1_KP			BIT(0)
+
+/* KEYP_EDR Fields */
+#define KEYP_EDR_KP_FALLING		0x01
+#define KEYP_EDR_KP_RISING		0x02
+#define KEYP_EDR_KP_BOTH		0x03
+#define KEYP_EDR_LK_FALLING		0x04
+#define KEYP_EDR_LK_RISING		0x08
+#define KEYP_EDR_TO_FALLING		0x10
+#define KEYP_EDR_TO_RISING		0x20
+#define KEYP_EDR_MIS_FALLING		0x40
+#define KEYP_EDR_MIS_RISING		0x80
+
+
+/*----------------------------------------------------------------------*/
+
+static int twl4030_kpread(struct twl4030_keypad *kp,
+		u8 *data, u32 reg, u8 num_bytes)
+{
+	int ret = twl4030_i2c_read(TWL4030_MODULE_KEYPAD, data, reg, num_bytes);
+
+	if (ret < 0)
+		dev_warn(kp->dbg_dev,
+			"Couldn't read TWL4030: %X - ret %d[%x]\n",
+			 reg, ret, ret);
+
+	return ret;
+}
+
+static int twl4030_kpwrite_u8(struct twl4030_keypad *kp, u8 data, u32 reg)
+{
+	int ret = twl4030_i2c_write_u8(TWL4030_MODULE_KEYPAD, data, reg);
+
+	if (ret < 0)
+		dev_warn(kp->dbg_dev,
+			"Could not write TWL4030: %X - ret %d[%x]\n",
+			 reg, ret, ret);
+
+	return ret;
+}
+
+static inline u16 twl4030_col_xlate(struct twl4030_keypad *kp, u8 col)
+{
+	/* If all bits in a row are active for all coloumns then
+	 * we have that row line connected to gnd. Mark this
+	 * key on as if it was on matrix position n_cols (ie
+	 * one higher than the size of the matrix).
+	 */
+	if (col == 0xFF)
+		return 1 << kp->n_cols;
+	else
+		return col & ((1 << kp->n_cols) - 1);
+}
+
+static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state)
+{
+	u8 new_state[TWL4030_MAX_ROWS];
+	int row;
+	int ret = twl4030_kpread(kp, new_state,
+				 KEYP_FULL_CODE_7_0, kp->n_rows);
+	if (ret >= 0)
+		for (row = 0; row < kp->n_rows; row++)
+			state[row] = twl4030_col_xlate(kp, new_state[row]);
+
+	return ret;
+}
+
+static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state)
+{
+	int i;
+	u16 check = 0;
+
+	for (i = 0; i < kp->n_rows; i++) {
+		u16 col = key_state[i];
+
+		if ((col & check) && hweight16(col) > 1)
+			return 1;
+
+		check |= col;
+	}
+
+	return 0;
+}
+
+static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all)
+{
+	struct input_dev *input = kp->input;
+	u16 new_state[TWL4030_MAX_ROWS];
+	int col, row;
+
+	if (release_all)
+		memset(new_state, 0, sizeof(new_state));
+	else {
+		/* check for any changes */
+		int ret = twl4030_read_kp_matrix_state(kp, new_state);
+
+		if (ret < 0)	/* panic ... */
+			return;
+
+		if (twl4030_is_in_ghost_state(kp, new_state))
+			return;
+	}
+
+	/* check for changes and print those */
+	for (row = 0; row < kp->n_rows; row++) {
+		int changed = new_state[row] ^ kp->kp_state[row];
+
+		if (!changed)
+			continue;
+
+		for (col = 0; col < kp->n_cols; col++) {
+			int code;
+
+			if (!(changed & (1 << col)))
+				continue;
+
+			dev_dbg(kp->dbg_dev, "key [%d:%d] %s\n", row, col,
+				(new_state[row] & (1 << col)) ?
+				"press" : "release");
+
+			code = MATRIX_SCAN_CODE(row, col, TWL4030_ROW_SHIFT);
+			input_event(input, EV_MSC, MSC_SCAN, code);
+			input_report_key(input, kp->keymap[code],
+					 new_state[row] & (1 << col));
+		}
+		kp->kp_state[row] = new_state[row];
+	}
+	input_sync(input);
+}
+
+/*
+ * Keypad interrupt handler
+ */
+static irqreturn_t do_kp_irq(int irq, void *_kp)
+{
+	struct twl4030_keypad *kp = _kp;
+	u8 reg;
+	int ret;
+
+#ifdef CONFIG_LOCKDEP
+	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
+	 * we don't want and can't tolerate.  Although it might be
+	 * friendlier not to borrow this thread context...
+	 */
+	local_irq_enable();
+#endif
+
+	/* Read & Clear TWL4030 pending interrupt */
+	ret = twl4030_kpread(kp, &reg, KEYP_ISR1, 1);
+
+	/* Release all keys if I2C has gone bad or
+	 * the KEYP has gone to idle state */
+	if (ret >= 0 && (reg & KEYP_IMR1_KP))
+		twl4030_kp_scan(kp, false);
+	else
+		twl4030_kp_scan(kp, true);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit twl4030_kp_program(struct twl4030_keypad *kp)
+{
+	u8 reg;
+	int i;
+
+	/* Enable controller, with hardware decoding but not autorepeat */
+	reg = KEYP_CTRL_SOFT_NRST | KEYP_CTRL_SOFTMODEN
+		| KEYP_CTRL_TOE_EN | KEYP_CTRL_KBD_ON;
+	if (twl4030_kpwrite_u8(kp, reg, KEYP_CTRL) < 0)
+		return -EIO;
+
+	/* NOTE:  we could use sih_setup() here to package keypad
+	 * event sources as four different IRQs ... but we don't.
+	 */
+
+	/* Enable TO rising and KP rising and falling edge detection */
+	reg = KEYP_EDR_KP_BOTH | KEYP_EDR_TO_RISING;
+	if (twl4030_kpwrite_u8(kp, reg, KEYP_EDR) < 0)
+		return -EIO;
+
+	/* Set PTV prescaler Field */
+	reg = (PTV_PRESCALER << KEYP_LK_PTV_PTV_SHIFT);
+	if (twl4030_kpwrite_u8(kp, reg, KEYP_LK_PTV) < 0)
+		return -EIO;
+
+	/* Set key debounce time to 20 ms */
+	i = KEYP_PERIOD_US(20000, PTV_PRESCALER);
+	if (twl4030_kpwrite_u8(kp, i, KEYP_DEB) < 0)
+		return -EIO;
+
+	/* Set timeout period to 100 ms */
+	i = KEYP_PERIOD_US(200000, PTV_PRESCALER);
+	if (twl4030_kpwrite_u8(kp, (i & 0xFF), KEYP_TIMEOUT_L) < 0)
+		return -EIO;
+
+	if (twl4030_kpwrite_u8(kp, (i >> 8), KEYP_TIMEOUT_H) < 0)
+		return -EIO;
+
+	/*
+	 * Enable Clear-on-Read; disable remembering events that fire
+	 * after the IRQ but before our handler acks (reads) them,
+	 */
+	reg = TWL4030_SIH_CTRL_COR_MASK | TWL4030_SIH_CTRL_PENDDIS_MASK;
+	if (twl4030_kpwrite_u8(kp, reg, KEYP_SIH_CTRL) < 0)
+		return -EIO;
+
+	/* initialize key state; irqs update it from here on */
+	if (twl4030_read_kp_matrix_state(kp, kp->kp_state) < 0)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Registers keypad device with input subsystem
+ * and configures TWL4030 keypad registers
+ */
+static int __devinit twl4030_kp_probe(struct platform_device *pdev)
+{
+	struct twl4030_keypad_data *pdata = pdev->dev.platform_data;
+	const struct matrix_keymap_data *keymap_data = pdata->keymap_data;
+	struct twl4030_keypad *kp;
+	struct input_dev *input;
+	u8 reg;
+	int error;
+
+	if (!pdata || !pdata->rows || !pdata->cols ||
+	    pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) {
+		dev_err(&pdev->dev, "Invalid platform_data\n");
+		return -EINVAL;
+	}
+
+	kp = kzalloc(sizeof(*kp), GFP_KERNEL);
+	input = input_allocate_device();
+	if (!kp || !input) {
+		error = -ENOMEM;
+		goto err1;
+	}
+
+	/* Get the debug Device */
+	kp->dbg_dev = &pdev->dev;
+	kp->input = input;
+
+	kp->n_rows = pdata->rows;
+	kp->n_cols = pdata->cols;
+	kp->irq = platform_get_irq(pdev, 0);
+
+	/* setup input device */
+	__set_bit(EV_KEY, input->evbit);
+
+	/* Enable auto repeat feature of Linux input subsystem */
+	if (pdata->rep)
+		__set_bit(EV_REP, input->evbit);
+
+	input_set_capability(input, EV_MSC, MSC_SCAN);
+
+	input->name		= "TWL4030 Keypad";
+	input->phys		= "twl4030_keypad/input0";
+	input->dev.parent	= &pdev->dev;
+
+	input->id.bustype	= BUS_HOST;
+	input->id.vendor	= 0x0001;
+	input->id.product	= 0x0001;
+	input->id.version	= 0x0003;
+
+	input->keycode		= kp->keymap;
+	input->keycodesize	= sizeof(kp->keymap[0]);
+	input->keycodemax	= ARRAY_SIZE(kp->keymap);
+
+	matrix_keypad_build_keymap(keymap_data, TWL4030_ROW_SHIFT,
+				   input->keycode, input->keybit);
+
+	error = input_register_device(input);
+	if (error) {
+		dev_err(kp->dbg_dev,
+			"Unable to register twl4030 keypad device\n");
+		goto err1;
+	}
+
+	error = twl4030_kp_program(kp);
+	if (error)
+		goto err2;
+
+	/*
+	 * This ISR will always execute in kernel thread context because of
+	 * the need to access the TWL4030 over the I2C bus.
+	 *
+	 * NOTE:  we assume this host is wired to TWL4040 INT1, not INT2 ...
+	 */
+	error = request_irq(kp->irq, do_kp_irq, 0, pdev->name, kp);
+	if (error) {
+		dev_info(kp->dbg_dev, "request_irq failed for irq no=%d\n",
+			kp->irq);
+		goto err3;
+	}
+
+	/* Enable KP and TO interrupts now. */
+	reg = (u8) ~(KEYP_IMR1_KP | KEYP_IMR1_TO);
+	if (twl4030_kpwrite_u8(kp, reg, KEYP_IMR1)) {
+		error = -EIO;
+		goto err4;
+	}
+
+	platform_set_drvdata(pdev, kp);
+	return 0;
+
+err4:
+	/* mask all events - we don't care about the result */
+	(void) twl4030_kpwrite_u8(kp, 0xff, KEYP_IMR1);
+err3:
+	free_irq(kp->irq, NULL);
+err2:
+	input_unregister_device(input);
+	input = NULL;
+err1:
+	input_free_device(input);
+	kfree(kp);
+	return error;
+}
+
+static int __devexit twl4030_kp_remove(struct platform_device *pdev)
+{
+	struct twl4030_keypad *kp = platform_get_drvdata(pdev);
+
+	free_irq(kp->irq, kp);
+	input_unregister_device(kp->input);
+	platform_set_drvdata(pdev, NULL);
+	kfree(kp);
+
+	return 0;
+}
+
+/*
+ * NOTE: twl4030 are multi-function devices connected via I2C.
+ * So this device is a child of an I2C parent, thus it needs to
+ * support unplug/replug (which most platform devices don't).
+ */
+
+static struct platform_driver twl4030_kp_driver = {
+	.probe		= twl4030_kp_probe,
+	.remove		= __devexit_p(twl4030_kp_remove),
+	.driver		= {
+		.name	= "twl4030_keypad",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init twl4030_kp_init(void)
+{
+	return platform_driver_register(&twl4030_kp_driver);
+}
+module_init(twl4030_kp_init);
+
+static void __exit twl4030_kp_exit(void)
+{
+	platform_driver_unregister(&twl4030_kp_driver);
+}
+module_exit(twl4030_kp_exit);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("TWL4030 Keypad Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:twl4030_keypad");
+
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c
new file mode 100644
index 0000000..6032def
--- /dev/null
+++ b/drivers/input/keyboard/w90p910_keypad.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2008-2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/w90p910_keypad.h>
+
+/* Keypad Interface Control Registers */
+#define KPI_CONF		0x00
+#define KPI_3KCONF		0x04
+#define KPI_LPCONF		0x08
+#define KPI_STATUS		0x0C
+
+#define IS1KEY			(0x01 << 16)
+#define INTTR			(0x01 << 21)
+#define KEY0R			(0x0f << 3)
+#define KEY0C			0x07
+#define DEBOUNCE_BIT		0x08
+#define KSIZE0			(0x01 << 16)
+#define KSIZE1			(0x01 << 17)
+#define KPSEL			(0x01 << 19)
+#define ENKP			(0x01 << 18)
+
+#define KGET_RAW(n)		(((n) & KEY0R) >> 3)
+#define KGET_COLUMN(n)		((n) & KEY0C)
+
+#define W90P910_MAX_KEY_NUM	(8 * 8)
+#define W90P910_ROW_SHIFT	3
+
+struct w90p910_keypad {
+	const struct w90p910_keypad_platform_data *pdata;
+	struct clk *clk;
+	struct input_dev *input_dev;
+	void __iomem *mmio_base;
+	int irq;
+	unsigned short keymap[W90P910_MAX_KEY_NUM];
+};
+
+static void w90p910_keypad_scan_matrix(struct w90p910_keypad *keypad,
+							unsigned int status)
+{
+	struct input_dev *input_dev = keypad->input_dev;
+	unsigned int row = KGET_RAW(status);
+	unsigned int col = KGET_COLUMN(status);
+	unsigned int code = MATRIX_SCAN_CODE(row, col, W90P910_ROW_SHIFT);
+	unsigned int key = keypad->keymap[code];
+
+	input_event(input_dev, EV_MSC, MSC_SCAN, code);
+	input_report_key(input_dev, key, 1);
+	input_sync(input_dev);
+
+	input_event(input_dev, EV_MSC, MSC_SCAN, code);
+	input_report_key(input_dev, key, 0);
+	input_sync(input_dev);
+}
+
+static irqreturn_t w90p910_keypad_irq_handler(int irq, void *dev_id)
+{
+	struct w90p910_keypad *keypad = dev_id;
+	unsigned int  kstatus, val;
+
+	kstatus = __raw_readl(keypad->mmio_base + KPI_STATUS);
+
+	val = INTTR | IS1KEY;
+
+	if (kstatus & val)
+		w90p910_keypad_scan_matrix(keypad, kstatus);
+
+	return IRQ_HANDLED;
+}
+
+static int w90p910_keypad_open(struct input_dev *dev)
+{
+	struct w90p910_keypad *keypad = input_get_drvdata(dev);
+	const struct w90p910_keypad_platform_data *pdata = keypad->pdata;
+	unsigned int val, config;
+
+	/* Enable unit clock */
+	clk_enable(keypad->clk);
+
+	val = __raw_readl(keypad->mmio_base + KPI_CONF);
+	val |= (KPSEL | ENKP);
+	val &= ~(KSIZE0 | KSIZE1);
+
+	config = pdata->prescale | (pdata->debounce << DEBOUNCE_BIT);
+
+	val |= config;
+
+	__raw_writel(val, keypad->mmio_base + KPI_CONF);
+
+	return 0;
+}
+
+static void w90p910_keypad_close(struct input_dev *dev)
+{
+	struct w90p910_keypad *keypad = input_get_drvdata(dev);
+
+	/* Disable clock unit */
+	clk_disable(keypad->clk);
+}
+
+static int __devinit w90p910_keypad_probe(struct platform_device *pdev)
+{
+	const struct w90p910_keypad_platform_data *pdata =
+						pdev->dev.platform_data;
+	const struct matrix_keymap_data *keymap_data;
+	struct w90p910_keypad *keypad;
+	struct input_dev *input_dev;
+	struct resource *res;
+	int irq;
+	int error;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data defined\n");
+		return -EINVAL;
+	}
+
+	keymap_data = pdata->keymap_data;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get keypad irq\n");
+		return -ENXIO;
+	}
+
+	keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!keypad || !input_dev) {
+		dev_err(&pdev->dev, "failed to allocate driver data\n");
+		error = -ENOMEM;
+		goto failed_free;
+	}
+
+	keypad->pdata = pdata;
+	keypad->input_dev = input_dev;
+	keypad->irq = irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to get I/O memory\n");
+		error = -ENXIO;
+		goto failed_free;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to request I/O memory\n");
+		error = -EBUSY;
+		goto failed_free;
+	}
+
+	keypad->mmio_base = ioremap(res->start, resource_size(res));
+	if (keypad->mmio_base == NULL) {
+		dev_err(&pdev->dev, "failed to remap I/O memory\n");
+		error = -ENXIO;
+		goto failed_free_res;
+	}
+
+	keypad->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(keypad->clk)) {
+		dev_err(&pdev->dev, "failed to get keypad clock\n");
+		error = PTR_ERR(keypad->clk);
+		goto failed_free_io;
+	}
+
+	/* set multi-function pin for w90p910 kpi. */
+	mfp_set_groupi(&pdev->dev);
+
+	input_dev->name = pdev->name;
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->open = w90p910_keypad_open;
+	input_dev->close = w90p910_keypad_close;
+	input_dev->dev.parent = &pdev->dev;
+
+	input_dev->keycode = keypad->keymap;
+	input_dev->keycodesize = sizeof(keypad->keymap[0]);
+	input_dev->keycodemax = ARRAY_SIZE(keypad->keymap);
+
+	input_set_drvdata(input_dev, keypad);
+
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+	matrix_keypad_build_keymap(keymap_data, W90P910_ROW_SHIFT,
+				   input_dev->keycode, input_dev->keybit);
+
+	error = request_irq(keypad->irq, w90p910_keypad_irq_handler,
+			    IRQF_DISABLED, pdev->name, keypad);
+	if (error) {
+		dev_err(&pdev->dev, "failed to request IRQ\n");
+		goto failed_put_clk;
+	}
+
+	/* Register the input device */
+	error = input_register_device(input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register input device\n");
+		goto failed_free_irq;
+	}
+
+	platform_set_drvdata(pdev, keypad);
+	return 0;
+
+failed_free_irq:
+	free_irq(irq, pdev);
+failed_put_clk:
+	clk_put(keypad->clk);
+failed_free_io:
+	iounmap(keypad->mmio_base);
+failed_free_res:
+	release_mem_region(res->start, resource_size(res));
+failed_free:
+	input_free_device(input_dev);
+	kfree(keypad);
+	return error;
+}
+
+static int __devexit w90p910_keypad_remove(struct platform_device *pdev)
+{
+	struct w90p910_keypad *keypad = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	free_irq(keypad->irq, pdev);
+
+	clk_put(keypad->clk);
+
+	input_unregister_device(keypad->input_dev);
+
+	iounmap(keypad->mmio_base);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, resource_size(res));
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(keypad);
+
+	return 0;
+}
+
+static struct platform_driver w90p910_keypad_driver = {
+	.probe		= w90p910_keypad_probe,
+	.remove		= __devexit_p(w90p910_keypad_remove),
+	.driver		= {
+		.name	= "nuc900-keypad",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init w90p910_keypad_init(void)
+{
+	return platform_driver_register(&w90p910_keypad_driver);
+}
+
+static void __exit w90p910_keypad_exit(void)
+{
+	platform_driver_unregister(&w90p910_keypad_driver);
+}
+
+module_init(w90p910_keypad_init);
+module_exit(w90p910_keypad_exit);
+
+MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
+MODULE_DESCRIPTION("w90p910 keypad driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:nuc900-keypad");
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 1acfa3a..1a50be3 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -269,4 +269,34 @@ config INPUT_DM355EVM
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called dm355evm_keys.
+
+config INPUT_BFIN_ROTARY
+	tristate "Blackfin Rotary support"
+	depends on BF54x || BF52x
+	help
+	  Say Y here if you want to use the Blackfin Rotary.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bfin-rotary.
+
+config INPUT_WM831X_ON
+	tristate "WM831X ON pin"
+	depends on MFD_WM831X
+	help
+	  Support the ON pin of WM831X PMICs as an input device
+	  reporting power button status.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called wm831x_on.
+
+config INPUT_PCAP
+	tristate "Motorola EZX PCAP misc input events"
+	depends on EZX_PCAP
+	help
+	  Say Y here if you want to use Power key and Headphone button
+	  on Motorola EZX phones.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pcap_keys.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 0d979fd..bf4db62 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_INPUT_APANEL)		+= apanel.o
 obj-$(CONFIG_INPUT_ATI_REMOTE)		+= ati_remote.o
 obj-$(CONFIG_INPUT_ATI_REMOTE2)		+= ati_remote2.o
 obj-$(CONFIG_INPUT_ATLAS_BTNS)		+= atlas_btns.o
+obj-$(CONFIG_INPUT_BFIN_ROTARY)		+= bfin_rotary.o
 obj-$(CONFIG_INPUT_CM109)		+= cm109.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
 obj-$(CONFIG_INPUT_DM355EVM)		+= dm355evm_keys.o
@@ -15,6 +16,7 @@ obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
 obj-$(CONFIG_INPUT_KEYSPAN_REMOTE)	+= keyspan_remote.o
 obj-$(CONFIG_INPUT_M68K_BEEP)		+= m68kspkr.o
+obj-$(CONFIG_INPUT_PCAP)		+= pcap_keys.o
 obj-$(CONFIG_INPUT_PCF50633_PMU)	+= pcf50633-input.o
 obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
 obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
@@ -25,4 +27,6 @@ obj-$(CONFIG_INPUT_SPARCSPKR)		+= sparcspkr.o
 obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON)	+= twl4030-pwrbutton.o
 obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
+obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
 obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
+
diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c
new file mode 100644
index 0000000..690f3fa
--- /dev/null
+++ b/drivers/input/misc/bfin_rotary.c
@@ -0,0 +1,283 @@
+/*
+ * Rotary counter driver for Analog Devices Blackfin Processors
+ *
+ * Copyright 2008-2009 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+
+#include <asm/portmux.h>
+#include <asm/bfin_rotary.h>
+
+static const u16 per_cnt[] = {
+	P_CNT_CUD,
+	P_CNT_CDG,
+	P_CNT_CZM,
+	0
+};
+
+struct bfin_rot {
+	struct input_dev *input;
+	int irq;
+	unsigned int up_key;
+	unsigned int down_key;
+	unsigned int button_key;
+	unsigned int rel_code;
+	unsigned short cnt_config;
+	unsigned short cnt_imask;
+	unsigned short cnt_debounce;
+};
+
+static void report_key_event(struct input_dev *input, int keycode)
+{
+	/* simulate a press-n-release */
+	input_report_key(input, keycode, 1);
+	input_sync(input);
+	input_report_key(input, keycode, 0);
+	input_sync(input);
+}
+
+static void report_rotary_event(struct bfin_rot *rotary, int delta)
+{
+	struct input_dev *input = rotary->input;
+
+	if (rotary->up_key) {
+		report_key_event(input,
+				 delta > 0 ? rotary->up_key : rotary->down_key);
+	} else {
+		input_report_rel(input, rotary->rel_code, delta);
+		input_sync(input);
+	}
+}
+
+static irqreturn_t bfin_rotary_isr(int irq, void *dev_id)
+{
+	struct platform_device *pdev = dev_id;
+	struct bfin_rot *rotary = platform_get_drvdata(pdev);
+	int delta;
+
+	switch (bfin_read_CNT_STATUS()) {
+
+	case ICII:
+		break;
+
+	case UCII:
+	case DCII:
+		delta = bfin_read_CNT_COUNTER();
+		if (delta)
+			report_rotary_event(rotary, delta);
+		break;
+
+	case CZMII:
+		report_key_event(rotary->input, rotary->button_key);
+		break;
+
+	default:
+		break;
+	}
+
+	bfin_write_CNT_COMMAND(W1LCNT_ZERO);	/* Clear COUNTER */
+	bfin_write_CNT_STATUS(-1);	/* Clear STATUS */
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit bfin_rotary_probe(struct platform_device *pdev)
+{
+	struct bfin_rotary_platform_data *pdata = pdev->dev.platform_data;
+	struct bfin_rot *rotary;
+	struct input_dev *input;
+	int error;
+
+	/* Basic validation */
+	if ((pdata->rotary_up_key && !pdata->rotary_down_key) ||
+	    (!pdata->rotary_up_key && pdata->rotary_down_key)) {
+		return -EINVAL;
+	}
+
+	error = peripheral_request_list(per_cnt, dev_name(&pdev->dev));
+	if (error) {
+		dev_err(&pdev->dev, "requesting peripherals failed\n");
+		return error;
+	}
+
+	rotary = kzalloc(sizeof(struct bfin_rot), GFP_KERNEL);
+	input = input_allocate_device();
+	if (!rotary || !input) {
+		error = -ENOMEM;
+		goto out1;
+	}
+
+	rotary->input = input;
+
+	rotary->up_key = pdata->rotary_up_key;
+	rotary->down_key = pdata->rotary_down_key;
+	rotary->button_key = pdata->rotary_button_key;
+	rotary->rel_code = pdata->rotary_rel_code;
+
+	error = rotary->irq = platform_get_irq(pdev, 0);
+	if (error < 0)
+		goto out1;
+
+	input->name = pdev->name;
+	input->phys = "bfin-rotary/input0";
+	input->dev.parent = &pdev->dev;
+
+	input_set_drvdata(input, rotary);
+
+	input->id.bustype = BUS_HOST;
+	input->id.vendor = 0x0001;
+	input->id.product = 0x0001;
+	input->id.version = 0x0100;
+
+	if (rotary->up_key) {
+		__set_bit(EV_KEY, input->evbit);
+		__set_bit(rotary->up_key, input->keybit);
+		__set_bit(rotary->down_key, input->keybit);
+	} else {
+		__set_bit(EV_REL, input->evbit);
+		__set_bit(rotary->rel_code, input->relbit);
+	}
+
+	if (rotary->button_key) {
+		__set_bit(EV_KEY, input->evbit);
+		__set_bit(rotary->button_key, input->keybit);
+	}
+
+	error = request_irq(rotary->irq, bfin_rotary_isr,
+			    0, dev_name(&pdev->dev), pdev);
+	if (error) {
+		dev_err(&pdev->dev,
+			"unable to claim irq %d; error %d\n",
+			rotary->irq, error);
+		goto out1;
+	}
+
+	error = input_register_device(input);
+	if (error) {
+		dev_err(&pdev->dev,
+			"unable to register input device (%d)\n", error);
+		goto out2;
+	}
+
+	if (pdata->rotary_button_key)
+		bfin_write_CNT_IMASK(CZMIE);
+
+	if (pdata->mode & ROT_DEBE)
+		bfin_write_CNT_DEBOUNCE(pdata->debounce & DPRESCALE);
+
+	if (pdata->mode)
+		bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() |
+					(pdata->mode & ~CNTE));
+
+	bfin_write_CNT_IMASK(bfin_read_CNT_IMASK() | UCIE | DCIE);
+	bfin_write_CNT_CONFIG(bfin_read_CNT_CONFIG() | CNTE);
+
+	platform_set_drvdata(pdev, rotary);
+	device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+
+out2:
+	free_irq(rotary->irq, pdev);
+out1:
+	input_free_device(input);
+	kfree(rotary);
+	peripheral_free_list(per_cnt);
+
+	return error;
+}
+
+static int __devexit bfin_rotary_remove(struct platform_device *pdev)
+{
+	struct bfin_rot *rotary = platform_get_drvdata(pdev);
+
+	bfin_write_CNT_CONFIG(0);
+	bfin_write_CNT_IMASK(0);
+
+	free_irq(rotary->irq, pdev);
+	input_unregister_device(rotary->input);
+	peripheral_free_list(per_cnt);
+
+	kfree(rotary);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int bfin_rotary_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct bfin_rot *rotary = platform_get_drvdata(pdev);
+
+	rotary->cnt_config = bfin_read_CNT_CONFIG();
+	rotary->cnt_imask = bfin_read_CNT_IMASK();
+	rotary->cnt_debounce = bfin_read_CNT_DEBOUNCE();
+
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(rotary->irq);
+
+	return 0;
+}
+
+static int bfin_rotary_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct bfin_rot *rotary = platform_get_drvdata(pdev);
+
+	bfin_write_CNT_DEBOUNCE(rotary->cnt_debounce);
+	bfin_write_CNT_IMASK(rotary->cnt_imask);
+	bfin_write_CNT_CONFIG(rotary->cnt_config & ~CNTE);
+
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(rotary->irq);
+
+	if (rotary->cnt_config & CNTE)
+		bfin_write_CNT_CONFIG(rotary->cnt_config);
+
+	return 0;
+}
+
+static struct dev_pm_ops bfin_rotary_pm_ops = {
+	.suspend	= bfin_rotary_suspend,
+	.resume		= bfin_rotary_resume,
+};
+#endif
+
+static struct platform_driver bfin_rotary_device_driver = {
+	.probe		= bfin_rotary_probe,
+	.remove		= __devexit_p(bfin_rotary_remove),
+	.driver		= {
+		.name	= "bfin-rotary",
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &bfin_rotary_pm_ops,
+#endif
+	},
+};
+
+static int __init bfin_rotary_init(void)
+{
+	return platform_driver_register(&bfin_rotary_device_driver);
+}
+module_init(bfin_rotary_init);
+
+static void __exit bfin_rotary_exit(void)
+{
+	platform_driver_unregister(&bfin_rotary_device_driver);
+}
+module_exit(bfin_rotary_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Rotary Counter driver for Blackfin Processors");
+MODULE_ALIAS("platform:bfin-rotary");
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index d114d3a..ee73d72 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -116,7 +116,7 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
 	}
 
 	bdev->poll_dev = poll_dev;
-	bdev->reg = ioremap(res->start, res->end - res->start + 1);
+	bdev->reg = ioremap(res->start, resource_size(res));
 	dev_set_drvdata(&pdev->dev, bdev);
 
 	error = input_register_polled_device(poll_dev);
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c
index a63315c..0918aca 100644
--- a/drivers/input/misc/dm355evm_keys.c
+++ b/drivers/input/misc/dm355evm_keys.c
@@ -23,30 +23,16 @@
  * pressed, or its autorepeat kicks in, an event is sent.  This driver
  * read those events from the small (32 event) queue and reports them.
  *
- * Because we communicate with the MSP430 using I2C, and all I2C calls
- * in Linux sleep, we need to cons up a kind of threaded IRQ handler
- * using a work_struct.  The IRQ is active low, but we use it through
- * the GPIO controller so we can trigger on falling edges.
- *
  * Note that physically there can only be one of these devices.
  *
  * This driver was tested with firmware revision A4.
  */
 struct dm355evm_keys {
-	struct work_struct	work;
 	struct input_dev	*input;
 	struct device		*dev;
 	int			irq;
 };
 
-static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
-{
-	struct dm355evm_keys	*keys = _keys;
-
-	schedule_work(&keys->work);
-	return IRQ_HANDLED;
-}
-
 /* These initial keycodes can be remapped by dm355evm_setkeycode(). */
 static struct {
 	u16	event;
@@ -110,13 +96,12 @@ static struct {
 	{ 0x3169, KEY_PAUSE, },
 };
 
-static void dm355evm_keys_work(struct work_struct *work)
+/* runs in an IRQ thread -- can (and will!) sleep */
+static irqreturn_t dm355evm_keys_irq(int irq, void *_keys)
 {
-	struct dm355evm_keys	*keys;
+	struct dm355evm_keys	*keys = _keys;
 	int			status;
 
-	keys = container_of(work, struct dm355evm_keys, work);
-
 	/* For simplicity we ignore INPUT_COUNT and just read
 	 * events until we get the "queue empty" indicator.
 	 * Reading INPUT_LOW decrements the count.
@@ -183,6 +168,19 @@ static void dm355evm_keys_work(struct work_struct *work)
 		input_report_key(keys->input, keycode, 0);
 		input_sync(keys->input);
 	}
+	return IRQ_HANDLED;
+}
+
+/*
+ * Because we communicate with the MSP430 using I2C, and all I2C calls
+ * in Linux sleep, we use a threaded IRQ handler.  The IRQ itself is
+ * active low, but we go through the GPIO controller so we can trigger
+ * on falling edges and not worry about enabling/disabling the IRQ in
+ * the keypress handling path.
+ */
+static irqreturn_t dm355evm_keys_hardirq(int irq, void *_keys)
+{
+	return IRQ_WAKE_THREAD;
 }
 
 static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode)
@@ -233,7 +231,6 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
 
 	keys->dev = &pdev->dev;
 	keys->input = input;
-	INIT_WORK(&keys->work, dm355evm_keys_work);
 
 	/* set up "threaded IRQ handler" */
 	status = platform_get_irq(pdev, 0);
@@ -260,9 +257,10 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev)
 
 	/* REVISIT:  flush the event queue? */
 
-	status = request_irq(keys->irq, dm355evm_keys_irq,
-			     IRQF_TRIGGER_FALLING,
-			     dev_name(&pdev->dev), keys);
+	status = request_threaded_irq(keys->irq,
+			dm355evm_keys_hardirq, dm355evm_keys_irq,
+			IRQF_TRIGGER_FALLING,
+			dev_name(&pdev->dev), keys);
 	if (status < 0)
 		goto fail1;
 
diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c
new file mode 100644
index 0000000..7ea9693
--- /dev/null
+++ b/drivers/input/misc/pcap_keys.c
@@ -0,0 +1,144 @@
+/*
+ *  Input driver for PCAP events:
+ *   * Power key
+ *   * Headphone button
+ *
+ *  Copyright (c) 2008,2009 Ilya Petrov <ilya.muromec@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 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/mfd/ezx-pcap.h>
+
+struct pcap_keys {
+	struct pcap_chip *pcap;
+	struct input_dev *input;
+};
+
+/* PCAP2 interrupts us on keypress */
+static irqreturn_t pcap_keys_handler(int irq, void *_pcap_keys)
+{
+	struct pcap_keys *pcap_keys = _pcap_keys;
+	int pirq = irq_to_pcap(pcap_keys->pcap, irq);
+	u32 pstat;
+
+	ezx_pcap_read(pcap_keys->pcap, PCAP_REG_PSTAT, &pstat);
+	pstat &= 1 << pirq;
+
+	switch (pirq) {
+	case PCAP_IRQ_ONOFF:
+		input_report_key(pcap_keys->input, KEY_POWER, !pstat);
+		break;
+	case PCAP_IRQ_MIC:
+		input_report_key(pcap_keys->input, KEY_HP, !pstat);
+		break;
+	}
+
+	input_sync(pcap_keys->input);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit pcap_keys_probe(struct platform_device *pdev)
+{
+	int err = -ENOMEM;
+	struct pcap_keys *pcap_keys;
+	struct input_dev *input_dev;
+
+	pcap_keys = kmalloc(sizeof(struct pcap_keys), GFP_KERNEL);
+	if (!pcap_keys)
+		return err;
+
+	pcap_keys->pcap = dev_get_drvdata(pdev->dev.parent);
+
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		goto fail;
+
+	pcap_keys->input = input_dev;
+
+	platform_set_drvdata(pdev, pcap_keys);
+	input_dev->name = pdev->name;
+	input_dev->phys = "pcap-keys/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->dev.parent = &pdev->dev;
+
+	__set_bit(EV_KEY, input_dev->evbit);
+	__set_bit(KEY_POWER, input_dev->keybit);
+	__set_bit(KEY_HP, input_dev->keybit);
+
+	err = input_register_device(input_dev);
+	if (err)
+		goto fail_allocate;
+
+	err = request_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF),
+			pcap_keys_handler, 0, "Power key", pcap_keys);
+	if (err)
+		goto fail_register;
+
+	err = request_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_MIC),
+			pcap_keys_handler, 0, "Headphone button", pcap_keys);
+	if (err)
+		goto fail_pwrkey;
+
+	return 0;
+
+fail_pwrkey:
+	free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF), pcap_keys);
+fail_register:
+	input_unregister_device(input_dev);
+	goto fail;
+fail_allocate:
+	input_free_device(input_dev);
+fail:
+	kfree(pcap_keys);
+	return err;
+}
+
+static int __devexit pcap_keys_remove(struct platform_device *pdev)
+{
+	struct pcap_keys *pcap_keys = platform_get_drvdata(pdev);
+
+	free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_ONOFF), pcap_keys);
+	free_irq(pcap_to_irq(pcap_keys->pcap, PCAP_IRQ_MIC), pcap_keys);
+
+	input_unregister_device(pcap_keys->input);
+	kfree(pcap_keys);
+
+	return 0;
+}
+
+static struct platform_driver pcap_keys_device_driver = {
+	.probe		= pcap_keys_probe,
+	.remove		= __devexit_p(pcap_keys_remove),
+	.driver		= {
+		.name	= "pcap-keys",
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init pcap_keys_init(void)
+{
+	return platform_driver_register(&pcap_keys_device_driver);
+};
+
+static void __exit pcap_keys_exit(void)
+{
+	platform_driver_unregister(&pcap_keys_device_driver);
+};
+
+module_init(pcap_keys_init);
+module_exit(pcap_keys_exit);
+
+MODULE_DESCRIPTION("Motorola PCAP2 input events driver");
+MODULE_AUTHOR("Ilya Petrov <ilya.muromec@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pcap_keys");
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 27ee976..11fd038 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -243,9 +243,9 @@ enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
 #define FE_UNTESTED 0x80
 
 static struct key_entry *keymap; /* = NULL; Current key map */
-static int have_wifi;
-static int have_bluetooth;
-static int have_leds;
+static bool have_wifi;
+static bool have_bluetooth;
+static int leds_present;	/* bitmask of leds present */
 
 static int __init dmi_matched(const struct dmi_system_id *dmi)
 {
@@ -254,11 +254,11 @@ static int __init dmi_matched(const struct dmi_system_id *dmi)
 	keymap = dmi->driver_data;
 	for (key = keymap; key->type != KE_END; key++) {
 		if (key->type == KE_WIFI)
-			have_wifi = 1;
+			have_wifi = true;
 		else if (key->type == KE_BLUETOOTH)
-			have_bluetooth = 1;
+			have_bluetooth = true;
 	}
-	have_leds = key->code & (FE_MAIL_LED | FE_WIFI_LED);
+	leds_present = key->code & (FE_MAIL_LED | FE_WIFI_LED);
 
 	return 1;
 }
@@ -611,10 +611,24 @@ static struct key_entry keymap_wistron_generic[] __initdata = {
 	{ KE_END, 0 }
 };
 
+static struct key_entry keymap_aopen_1557[] __initdata = {
+	{ KE_KEY,  0x01, {KEY_HELP} },
+	{ KE_KEY,  0x11, {KEY_PROG1} },
+	{ KE_KEY,  0x12, {KEY_PROG2} },
+	{ KE_WIFI, 0x30 },
+	{ KE_KEY,  0x22, {KEY_REWIND} },
+	{ KE_KEY,  0x23, {KEY_FORWARD} },
+	{ KE_KEY,  0x24, {KEY_PLAYPAUSE} },
+	{ KE_KEY,  0x25, {KEY_STOPCD} },
+	{ KE_KEY,  0x31, {KEY_MAIL} },
+	{ KE_KEY,  0x36, {KEY_WWW} },
+	{ KE_END,  0 }
+};
+
 static struct key_entry keymap_prestigio[] __initdata = {
 	{ KE_KEY,  0x11, {KEY_PROG1} },
 	{ KE_KEY,  0x12, {KEY_PROG2} },
-	{ KE_WIFI,  0x30 },
+	{ KE_WIFI, 0x30 },
 	{ KE_KEY,  0x22, {KEY_REWIND} },
 	{ KE_KEY,  0x23, {KEY_FORWARD} },
 	{ KE_KEY,  0x24, {KEY_PLAYPAUSE} },
@@ -985,6 +999,8 @@ static int __init select_keymap(void)
 	if (keymap_name != NULL) {
 		if (strcmp (keymap_name, "1557/MS2141") == 0)
 			keymap = keymap_wistron_ms2141;
+		else if (strcmp (keymap_name, "aopen1557") == 0)
+			keymap = keymap_aopen_1557;
 		else if (strcmp (keymap_name, "prestigio") == 0)
 			keymap = keymap_prestigio;
 		else if (strcmp (keymap_name, "generic") == 0)
@@ -1009,8 +1025,8 @@ static int __init select_keymap(void)
 
 static struct input_polled_dev *wistron_idev;
 static unsigned long jiffies_last_press;
-static int wifi_enabled;
-static int bluetooth_enabled;
+static bool wifi_enabled;
+static bool bluetooth_enabled;
 
 static void report_key(struct input_dev *dev, unsigned int keycode)
 {
@@ -1053,24 +1069,24 @@ static struct led_classdev wistron_wifi_led = {
 
 static void __devinit wistron_led_init(struct device *parent)
 {
-	if (have_leds & FE_WIFI_LED) {
+	if (leds_present & FE_WIFI_LED) {
 		u16 wifi = bios_get_default_setting(WIFI);
 		if (wifi & 1) {
 			wistron_wifi_led.brightness = (wifi & 2) ? LED_FULL : LED_OFF;
 			if (led_classdev_register(parent, &wistron_wifi_led))
-				have_leds &= ~FE_WIFI_LED;
+				leds_present &= ~FE_WIFI_LED;
 			else
 				bios_set_state(WIFI, wistron_wifi_led.brightness);
 
 		} else
-			have_leds &= ~FE_WIFI_LED;
+			leds_present &= ~FE_WIFI_LED;
 	}
 
-	if (have_leds & FE_MAIL_LED) {
+	if (leds_present & FE_MAIL_LED) {
 		/* bios_get_default_setting(MAIL) always retuns 0, so just turn the led off */
 		wistron_mail_led.brightness = LED_OFF;
 		if (led_classdev_register(parent, &wistron_mail_led))
-			have_leds &= ~FE_MAIL_LED;
+			leds_present &= ~FE_MAIL_LED;
 		else
 			bios_set_state(MAIL_LED, wistron_mail_led.brightness);
 	}
@@ -1078,28 +1094,28 @@ static void __devinit wistron_led_init(struct device *parent)
 
 static void __devexit wistron_led_remove(void)
 {
-	if (have_leds & FE_MAIL_LED)
+	if (leds_present & FE_MAIL_LED)
 		led_classdev_unregister(&wistron_mail_led);
 
-	if (have_leds & FE_WIFI_LED)
+	if (leds_present & FE_WIFI_LED)
 		led_classdev_unregister(&wistron_wifi_led);
 }
 
 static inline void wistron_led_suspend(void)
 {
-	if (have_leds & FE_MAIL_LED)
+	if (leds_present & FE_MAIL_LED)
 		led_classdev_suspend(&wistron_mail_led);
 
-	if (have_leds & FE_WIFI_LED)
+	if (leds_present & FE_WIFI_LED)
 		led_classdev_suspend(&wistron_wifi_led);
 }
 
 static inline void wistron_led_resume(void)
 {
-	if (have_leds & FE_MAIL_LED)
+	if (leds_present & FE_MAIL_LED)
 		led_classdev_resume(&wistron_mail_led);
 
-	if (have_leds & FE_WIFI_LED)
+	if (leds_present & FE_WIFI_LED)
 		led_classdev_resume(&wistron_wifi_led);
 }
 
@@ -1312,7 +1328,7 @@ static int __devinit wistron_probe(struct platform_device *dev)
 	if (have_wifi) {
 		u16 wifi = bios_get_default_setting(WIFI);
 		if (wifi & 1)
-			wifi_enabled = (wifi & 2) ? 1 : 0;
+			wifi_enabled = wifi & 2;
 		else
 			have_wifi = 0;
 
@@ -1323,15 +1339,16 @@ static int __devinit wistron_probe(struct platform_device *dev)
 	if (have_bluetooth) {
 		u16 bt = bios_get_default_setting(BLUETOOTH);
 		if (bt & 1)
-			bluetooth_enabled = (bt & 2) ? 1 : 0;
+			bluetooth_enabled = bt & 2;
 		else
-			have_bluetooth = 0;
+			have_bluetooth = false;
 
 		if (have_bluetooth)
 			bios_set_state(BLUETOOTH, bluetooth_enabled);
 	}
 
 	wistron_led_init(&dev->dev);
+
 	err = setup_input_dev();
 	if (err) {
 		bios_detach();
@@ -1352,7 +1369,7 @@ static int __devexit wistron_remove(struct platform_device *dev)
 }
 
 #ifdef CONFIG_PM
-static int wistron_suspend(struct platform_device *dev, pm_message_t state)
+static int wistron_suspend(struct device *dev)
 {
 	if (have_wifi)
 		bios_set_state(WIFI, 0);
@@ -1361,10 +1378,11 @@ static int wistron_suspend(struct platform_device *dev, pm_message_t state)
 		bios_set_state(BLUETOOTH, 0);
 
 	wistron_led_suspend();
+
 	return 0;
 }
 
-static int wistron_resume(struct platform_device *dev)
+static int wistron_resume(struct device *dev)
 {
 	if (have_wifi)
 		bios_set_state(WIFI, wifi_enabled);
@@ -1373,24 +1391,30 @@ static int wistron_resume(struct platform_device *dev)
 		bios_set_state(BLUETOOTH, bluetooth_enabled);
 
 	wistron_led_resume();
+
 	poll_bios(true);
 
 	return 0;
 }
-#else
-#define wistron_suspend		NULL
-#define wistron_resume		NULL
+
+static const struct dev_pm_ops wistron_pm_ops = {
+	.suspend	= wistron_suspend,
+	.resume		= wistron_resume,
+	.poweroff	= wistron_suspend,
+	.restore	= wistron_resume,
+};
 #endif
 
 static struct platform_driver wistron_driver = {
 	.driver		= {
 		.name	= "wistron-bios",
 		.owner	= THIS_MODULE,
+#if CONFIG_PM
+		.pm	= &wistron_pm_ops,
+#endif
 	},
 	.probe		= wistron_probe,
 	.remove		= __devexit_p(wistron_remove),
-	.suspend	= wistron_suspend,
-	.resume		= wistron_resume,
 };
 
 static int __init wb_module_init(void)
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c
new file mode 100644
index 0000000..ba4f5dd
--- /dev/null
+++ b/drivers/input/misc/wm831x-on.c
@@ -0,0 +1,163 @@
+/**
+ * wm831x-on.c - WM831X ON pin driver
+ *
+ * Copyright (C) 2009 Wolfson Microelectronics plc
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/mfd/wm831x/core.h>
+
+struct wm831x_on {
+	struct input_dev *dev;
+	struct delayed_work work;
+	struct wm831x *wm831x;
+};
+
+/*
+ * The chip gives us an interrupt when the ON pin is asserted but we
+ * then need to poll to see when the pin is deasserted.
+ */
+static void wm831x_poll_on(struct work_struct *work)
+{
+	struct wm831x_on *wm831x_on = container_of(work, struct wm831x_on,
+						   work.work);
+	struct wm831x *wm831x = wm831x_on->wm831x;
+	int poll, ret;
+
+	ret = wm831x_reg_read(wm831x, WM831X_ON_PIN_CONTROL);
+	if (ret >= 0) {
+		poll = !(ret & WM831X_ON_PIN_STS);
+
+		input_report_key(wm831x_on->dev, KEY_POWER, poll);
+		input_sync(wm831x_on->dev);
+	} else {
+		dev_err(wm831x->dev, "Failed to read ON status: %d\n", ret);
+		poll = 1;
+	}
+
+	if (poll)
+		schedule_delayed_work(&wm831x_on->work, 100);
+}
+
+static irqreturn_t wm831x_on_irq(int irq, void *data)
+{
+	struct wm831x_on *wm831x_on = data;
+
+	schedule_delayed_work(&wm831x_on->work, 0);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit wm831x_on_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_on *wm831x_on;
+	int irq = platform_get_irq(pdev, 0);
+	int ret;
+
+	wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL);
+	if (!wm831x_on) {
+		dev_err(&pdev->dev, "Can't allocate data\n");
+		return -ENOMEM;
+	}
+
+	wm831x_on->wm831x = wm831x;
+	INIT_DELAYED_WORK(&wm831x_on->work, wm831x_poll_on);
+
+	wm831x_on->dev = input_allocate_device();
+	if (!wm831x_on->dev) {
+		dev_err(&pdev->dev, "Can't allocate input dev\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	wm831x_on->dev->evbit[0] = BIT_MASK(EV_KEY);
+	wm831x_on->dev->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER);
+	wm831x_on->dev->name = "wm831x_on";
+	wm831x_on->dev->phys = "wm831x_on/input0";
+	wm831x_on->dev->dev.parent = &pdev->dev;
+
+	ret = wm831x_request_irq(wm831x, irq, wm831x_on_irq,
+				 IRQF_TRIGGER_RISING, "wm831x_on", wm831x_on);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Unable to request IRQ: %d\n", ret);
+		goto err_input_dev;
+	}
+	ret = input_register_device(wm831x_on->dev);
+	if (ret) {
+		dev_dbg(&pdev->dev, "Can't register input device: %d\n", ret);
+		goto err_irq;
+	}
+
+	platform_set_drvdata(pdev, wm831x_on);
+
+	return 0;
+
+err_irq:
+	wm831x_free_irq(wm831x, irq, NULL);
+err_input_dev:
+	input_free_device(wm831x_on->dev);
+err:
+	kfree(wm831x_on);
+	return ret;
+}
+
+static int __devexit wm831x_on_remove(struct platform_device *pdev)
+{
+	struct wm831x_on *wm831x_on = platform_get_drvdata(pdev);
+	int irq = platform_get_irq(pdev, 0);
+
+	wm831x_free_irq(wm831x_on->wm831x, irq, wm831x_on);
+	cancel_delayed_work_sync(&wm831x_on->work);
+	input_unregister_device(wm831x_on->dev);
+	kfree(wm831x_on);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_on_driver = {
+	.probe		= wm831x_on_probe,
+	.remove		= __devexit_p(wm831x_on_remove),
+	.driver		= {
+		.name	= "wm831x-on",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init wm831x_on_init(void)
+{
+	return platform_driver_register(&wm831x_on_driver);
+}
+module_init(wm831x_on_init);
+
+static void __exit wm831x_on_exit(void)
+{
+	platform_driver_unregister(&wm831x_on_driver);
+}
+module_exit(wm831x_on_exit);
+
+MODULE_ALIAS("platform:wm831x-on");
+MODULE_DESCRIPTION("WM831x ON pin");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index 8a2c5b1..3feeb3a 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -107,6 +107,14 @@ config MOUSE_PS2_ELANTECH
 	  entries. For further information,
 	  see <file:Documentation/input/elantech.txt>.
 
+config MOUSE_PS2_SENTELIC
+	bool "Sentelic Finger Sensing Pad PS/2 protocol extension"
+	depends on MOUSE_PS2
+	help
+	  Say Y here if you have a laptop (such as MSI WIND Netbook)
+	  with Sentelic Finger Sensing Pad touchpad.
+
+	  If unsure, say N.
 
 config MOUSE_PS2_TOUCHKIT
 	bool "eGalax TouchKit PS/2 protocol extension"
@@ -262,14 +270,6 @@ config MOUSE_VSXXXAA
 	  described in the source file). This driver also works with the
 	  digitizer (VSXXX-AB) DEC produced.
 
-config MOUSE_HIL
-	tristate "HIL pointers (mice etc)."
-	depends on GSC || HP300
-	select HP_SDC
-	select HIL_MLC
-	help
-	  Say Y here to support HIL pointers.
-
 config MOUSE_GPIO
 	tristate "GPIO mouse"
 	depends on GENERIC_GPIO
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 010f265..570c84a 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_MOUSE_APPLETOUCH)		+= appletouch.o
 obj-$(CONFIG_MOUSE_ATARI)		+= atarimouse.o
 obj-$(CONFIG_MOUSE_BCM5974)		+= bcm5974.o
 obj-$(CONFIG_MOUSE_GPIO)		+= gpio_mouse.o
-obj-$(CONFIG_MOUSE_HIL)			+= hil_ptr.o
 obj-$(CONFIG_MOUSE_INPORT)		+= inport.o
 obj-$(CONFIG_MOUSE_LOGIBM)		+= logibm.o
 obj-$(CONFIG_MOUSE_MAPLE)		+= maplemouse.o
@@ -28,5 +27,6 @@ psmouse-$(CONFIG_MOUSE_PS2_ELANTECH)	+= elantech.o
 psmouse-$(CONFIG_MOUSE_PS2_OLPC)	+= hgpk.o
 psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP)	+= logips2pp.o
 psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK)	+= lifebook.o
+psmouse-$(CONFIG_MOUSE_PS2_SENTELIC)	+= sentelic.o
 psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT)	+= trackpoint.o
 psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT)	+= touchkit_ps2.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 5547e24..f361106 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -279,7 +279,7 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int
  * subsequent commands. It looks like glidepad is behind stickpointer,
  * I'd thought it would be other way around...
  */
-static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
+static int alps_passthrough_mode(struct psmouse *psmouse, bool enable)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
@@ -367,16 +367,16 @@ static int alps_poll(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
 	unsigned char buf[6];
-	int poll_failed;
+	bool poll_failed;
 
 	if (priv->i->flags & ALPS_PASS)
-		alps_passthrough_mode(psmouse, 1);
+		alps_passthrough_mode(psmouse, true);
 
 	poll_failed = ps2_command(&psmouse->ps2dev, buf,
 				  PSMOUSE_CMD_POLL | (psmouse->pktsize << 8)) < 0;
 
 	if (priv->i->flags & ALPS_PASS)
-		alps_passthrough_mode(psmouse, 0);
+		alps_passthrough_mode(psmouse, false);
 
 	if (poll_failed || (buf[0] & priv->i->mask0) != priv->i->byte0)
 		return -1;
@@ -401,10 +401,12 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
 	if (!priv->i)
 		return -1;
 
-	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
+	if ((priv->i->flags & ALPS_PASS) &&
+	    alps_passthrough_mode(psmouse, true)) {
 		return -1;
+	}
 
-	if (alps_tap_mode(psmouse, 1)) {
+	if (alps_tap_mode(psmouse, true)) {
 		printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n");
 		return -1;
 	}
@@ -414,8 +416,10 @@ static int alps_hw_init(struct psmouse *psmouse, int *version)
 		return -1;
 	}
 
-	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
+	if ((priv->i->flags & ALPS_PASS) &&
+	    alps_passthrough_mode(psmouse, false)) {
 		return -1;
+	}
 
 	/* ALPS needs stream mode, otherwise it won't report any data */
 	if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM)) {
@@ -519,7 +523,7 @@ init_fail:
 	return -1;
 }
 
-int alps_detect(struct psmouse *psmouse, int set_properties)
+int alps_detect(struct psmouse *psmouse, bool set_properties)
 {
 	int version;
 	const struct alps_model_info *model;
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 4bbddc9..bc87936 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -26,10 +26,10 @@ struct alps_data {
 };
 
 #ifdef CONFIG_MOUSE_PS2_ALPS
-int alps_detect(struct psmouse *psmouse, int set_properties);
+int alps_detect(struct psmouse *psmouse, bool set_properties);
 int alps_init(struct psmouse *psmouse);
 #else
-inline int alps_detect(struct psmouse *psmouse, int set_properties)
+inline int alps_detect(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENOSYS;
 }
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 2d8fc0b..0d1d334 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -317,7 +317,7 @@ static int report_tp_state(struct bcm5974 *dev, int size)
 	const struct tp_finger *f;
 	struct input_dev *input = dev->input;
 	int raw_p, raw_w, raw_x, raw_y, raw_n;
-	int ptest = 0, origin = 0, ibt = 0, nmin = 0, nmax = 0;
+	int ptest, origin, ibt = 0, nmin = 0, nmax = 0;
 	int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
 
 	if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
@@ -345,21 +345,22 @@ static int report_tp_state(struct bcm5974 *dev, int size)
 		/* set the integrated button if applicable */
 		if (c->tp_type == TYPE2)
 			ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
-	}
 
-	/* while tracking finger still valid, count all fingers */
-	if (ptest > PRESSURE_LOW && origin) {
-		abs_p = ptest;
-		abs_w = int2bound(&c->w, raw_w);
-		abs_x = int2bound(&c->x, raw_x - c->x.devmin);
-		abs_y = int2bound(&c->y, c->y.devmax - raw_y);
-		while (raw_n--) {
-			ptest = int2bound(&c->p, raw2int(f->force_major));
-			if (ptest > PRESSURE_LOW)
-				nmax++;
-			if (ptest > PRESSURE_HIGH)
-				nmin++;
-			f++;
+		/* while tracking finger still valid, count all fingers */
+		if (ptest > PRESSURE_LOW && origin) {
+			abs_p = ptest;
+			abs_w = int2bound(&c->w, raw_w);
+			abs_x = int2bound(&c->x, raw_x - c->x.devmin);
+			abs_y = int2bound(&c->y, c->y.devmax - raw_y);
+			while (raw_n--) {
+				ptest = int2bound(&c->p,
+						  raw2int(f->force_major));
+				if (ptest > PRESSURE_LOW)
+					nmax++;
+				if (ptest > PRESSURE_HIGH)
+					nmin++;
+				f++;
+			}
 		}
 	}
 
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 4bc7889..fda35e6 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -553,7 +553,7 @@ static struct attribute_group elantech_attr_group = {
 /*
  * Use magic knock to detect Elantech touchpad
  */
-int elantech_detect(struct psmouse *psmouse, int set_properties)
+int elantech_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[3];
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index ed848cc..feac5f7 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -109,10 +109,10 @@ struct elantech_data {
 };
 
 #ifdef CONFIG_MOUSE_PS2_ELANTECH
-int elantech_detect(struct psmouse *psmouse, int set_properties);
+int elantech_detect(struct psmouse *psmouse, bool set_properties);
 int elantech_init(struct psmouse *psmouse);
 #else
-static inline int elantech_detect(struct psmouse *psmouse, int set_properties)
+static inline int elantech_detect(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENOSYS;
 }
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index a1ad2f1..de1e553 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -367,7 +367,36 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
 }
 
 __PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
-		      hgpk_show_powered, hgpk_set_powered, 0);
+		      hgpk_show_powered, hgpk_set_powered, false);
+
+static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
+		void *data, char *buf)
+{
+	return -EINVAL;
+}
+
+static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
+				const char *buf, size_t count)
+{
+	struct hgpk_data *priv = psmouse->private;
+	unsigned long value;
+	int err;
+
+	err = strict_strtoul(buf, 10, &value);
+	if (err || value != 1)
+		return -EINVAL;
+
+	/*
+	 * We queue work instead of doing recalibration right here
+	 * to avoid adding locking to to hgpk_force_recalibrate()
+	 * since workqueue provides serialization.
+	 */
+	psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
+	return count;
+}
+
+__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
+		      hgpk_trigger_recal_show, hgpk_trigger_recal, false);
 
 static void hgpk_disconnect(struct psmouse *psmouse)
 {
@@ -375,6 +404,11 @@ static void hgpk_disconnect(struct psmouse *psmouse)
 
 	device_remove_file(&psmouse->ps2dev.serio->dev,
 			   &psmouse_attr_powered.dattr);
+
+	if (psmouse->model >= HGPK_MODEL_C)
+		device_remove_file(&psmouse->ps2dev.serio->dev,
+				   &psmouse_attr_recalibrate.dattr);
+
 	psmouse_reset(psmouse);
 	kfree(priv);
 }
@@ -423,10 +457,25 @@ static int hgpk_register(struct psmouse *psmouse)
 
 	err = device_create_file(&psmouse->ps2dev.serio->dev,
 				 &psmouse_attr_powered.dattr);
-	if (err)
-		hgpk_err(psmouse, "Failed to create sysfs attribute\n");
+	if (err) {
+		hgpk_err(psmouse, "Failed creating 'powered' sysfs node\n");
+		return err;
+	}
 
-	return err;
+	/* C-series touchpads added the recalibrate command */
+	if (psmouse->model >= HGPK_MODEL_C) {
+		err = device_create_file(&psmouse->ps2dev.serio->dev,
+					 &psmouse_attr_recalibrate.dattr);
+		if (err) {
+			hgpk_err(psmouse,
+				"Failed creating 'recalibrate' sysfs node\n");
+			device_remove_file(&psmouse->ps2dev.serio->dev,
+					&psmouse_attr_powered.dattr);
+			return err;
+		}
+	}
+
+	return 0;
 }
 
 int hgpk_init(struct psmouse *psmouse)
@@ -440,7 +489,7 @@ int hgpk_init(struct psmouse *psmouse)
 
 	psmouse->private = priv;
 	priv->psmouse = psmouse;
-	priv->powered = 1;
+	priv->powered = true;
 	INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
 
 	err = psmouse_reset(psmouse);
@@ -483,7 +532,7 @@ static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
 	return param[2];
 }
 
-int hgpk_detect(struct psmouse *psmouse, int set_properties)
+int hgpk_detect(struct psmouse *psmouse, bool set_properties)
 {
 	int version;
 
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
index a4b2a96..d61cfd3 100644
--- a/drivers/input/mouse/hgpk.h
+++ b/drivers/input/mouse/hgpk.h
@@ -15,7 +15,7 @@ enum hgpk_model_t {
 
 struct hgpk_data {
 	struct psmouse *psmouse;
-	int powered;
+	bool powered;
 	int count, x_tally, y_tally;	/* hardware workaround stuff */
 	unsigned long recalib_window;
 	struct delayed_work recalib_wq;
@@ -33,10 +33,10 @@ struct hgpk_data {
 	dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
 
 #ifdef CONFIG_MOUSE_PS2_OLPC
-int hgpk_detect(struct psmouse *psmouse, int set_properties);
+int hgpk_detect(struct psmouse *psmouse, bool set_properties);
 int hgpk_init(struct psmouse *psmouse);
 #else
-static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
+static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENODEV;
 }
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
deleted file mode 100644
index 3263ce0..0000000
--- a/drivers/input/mouse/hil_ptr.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Generic linux-input device driver for axis-bearing devices
- *
- * Copyright (c) 2001 Brian S. Julin
- * 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. The name of the author may not 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").
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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
- *
- * References:
- * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
- *
- */
-
-#include <linux/hil.h>
-#include <linux/input.h>
-#include <linux/serio.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pci_ids.h>
-
-#define PREFIX "HIL PTR: "
-#define HIL_GENERIC_NAME "HIL pointer device"
-
-MODULE_AUTHOR("Brian S. Julin <bri@calyx.com>");
-MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("serio:ty03pr25id0Fex*");
-
-#define TABLET_SIMULATES_MOUSE	/* allow tablet to be used as mouse */
-#undef  TABLET_AUTOADJUST	/* auto-adjust valid tablet ranges */
-
-
-#define HIL_PTR_MAX_LENGTH 16
-
-struct hil_ptr {
-	struct input_dev *dev;
-	struct serio *serio;
-
-	/* Input buffer and index for packets from HIL bus. */
-	hil_packet data[HIL_PTR_MAX_LENGTH];
-	int idx4; /* four counts per packet */
-
-	/* Raw device info records from HIL bus, see hil.h for fields. */
-	char	idd[HIL_PTR_MAX_LENGTH];	/* DID byte and IDD record */
-	char	rsc[HIL_PTR_MAX_LENGTH];	/* RSC record */
-	char	exd[HIL_PTR_MAX_LENGTH];	/* EXD record */
-	char	rnm[HIL_PTR_MAX_LENGTH + 1];	/* RNM record + NULL term. */
-
-	/* Extra device details not contained in struct input_dev. */
-	unsigned int nbtn, naxes;
-	unsigned int btnmap[7];
-
-	/* Something to sleep around with. */
-	struct semaphore sem;
-};
-
-/* Process a complete packet after transfer from the HIL */
-static void hil_ptr_process_record(struct hil_ptr *ptr)
-{
-	struct input_dev *dev = ptr->dev;
-	hil_packet *data = ptr->data;
-	hil_packet p;
-	int idx, i, cnt, laxis;
-	int ax16, absdev;
-
-	idx = ptr->idx4/4;
-	p = data[idx - 1];
-
-	if ((p & ~HIL_CMDCT_POL) ==
-	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
-		goto report;
-	if ((p & ~HIL_CMDCT_RPL) ==
-	    (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
-		goto report;
-
-	/* Not a poll response.  See if we are loading config records. */
-	switch (p & HIL_PKT_DATA_MASK) {
-	case HIL_CMD_IDD:
-		for (i = 0; i < idx; i++)
-			ptr->idd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_PTR_MAX_LENGTH; i++)
-			ptr->idd[i] = 0;
-		break;
-
-	case HIL_CMD_RSC:
-		for (i = 0; i < idx; i++)
-			ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_PTR_MAX_LENGTH; i++)
-			ptr->rsc[i] = 0;
-		break;
-
-	case HIL_CMD_EXD:
-		for (i = 0; i < idx; i++)
-			ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_PTR_MAX_LENGTH; i++)
-			ptr->exd[i] = 0;
-		break;
-
-	case HIL_CMD_RNM:
-		for (i = 0; i < idx; i++)
-			ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
-		for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
-			ptr->rnm[i] = 0;
-		break;
-
-	default:
-		/* These occur when device isn't present */
-		if (p == (HIL_ERR_INT | HIL_PKT_CMD))
-			break;
-		/* Anything else we'd like to know about. */
-		printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
-		break;
-	}
-	goto out;
-
- report:
-	if ((p & HIL_CMDCT_POL) != idx - 1) {
-		printk(KERN_WARNING PREFIX
-			"Malformed poll packet %x (idx = %i)\n", p, idx);
-		goto out;
-	}
-
-	i = (ptr->data[0] & HIL_POL_AXIS_ALT) ? 3 : 0;
-	laxis = ptr->data[0] & HIL_POL_NUM_AXES_MASK;
-	laxis += i;
-
-	ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
-	absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
-
-	for (cnt = 1; i < laxis; i++) {
-		unsigned int lo,hi,val;
-		lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK;
-		hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0;
-		if (absdev) {
-			val = lo + (hi<<8);
-#ifdef TABLET_AUTOADJUST
-			if (val < dev->absmin[ABS_X + i])
-				dev->absmin[ABS_X + i] = val;
-			if (val > dev->absmax[ABS_X + i])
-				dev->absmax[ABS_X + i] = val;
-#endif
-			if (i%3) val = dev->absmax[ABS_X + i] - val;
-			input_report_abs(dev, ABS_X + i, val);
-		} else {
-			val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
-			if (i%3)
-				val *= -1;
-			input_report_rel(dev, REL_X + i, val);
-		}
-	}
-
-	while (cnt < idx - 1) {
-		unsigned int btn;
-		int up;
-		btn = ptr->data[cnt++];
-		up = btn & 1;
-		btn &= 0xfe;
-		if (btn == 0x8e)
-			continue; /* TODO: proximity == touch? */
-		else
-			if ((btn > 0x8c) || (btn < 0x80))
-				continue;
-		btn = (btn - 0x80) >> 1;
-		btn = ptr->btnmap[btn];
-		input_report_key(dev, btn, !up);
-	}
-	input_sync(dev);
- out:
-	ptr->idx4 = 0;
-	up(&ptr->sem);
-}
-
-static void hil_ptr_process_err(struct hil_ptr *ptr)
-{
-	printk(KERN_WARNING PREFIX "errored HIL packet\n");
-	ptr->idx4 = 0;
-	up(&ptr->sem);
-}
-
-static irqreturn_t hil_ptr_interrupt(struct serio *serio,
-        unsigned char data, unsigned int flags)
-{
-	struct hil_ptr *ptr;
-	hil_packet packet;
-	int idx;
-
-	ptr = serio_get_drvdata(serio);
-	BUG_ON(ptr == NULL);
-
-	if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
-		hil_ptr_process_err(ptr);
-		return IRQ_HANDLED;
-	}
-	idx = ptr->idx4/4;
-	if (!(ptr->idx4 % 4))
-		ptr->data[idx] = 0;
-	packet = ptr->data[idx];
-	packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
-	ptr->data[idx] = packet;
-
-	/* Records of N 4-byte hil_packets must terminate with a command. */
-	if ((++(ptr->idx4)) % 4)
-		return IRQ_HANDLED;
-	if ((packet & 0xffff0000) != HIL_ERR_INT) {
-		hil_ptr_process_err(ptr);
-		return IRQ_HANDLED;
-	}
-	if (packet & HIL_PKT_CMD)
-		hil_ptr_process_record(ptr);
-
-	return IRQ_HANDLED;
-}
-
-static void hil_ptr_disconnect(struct serio *serio)
-{
-	struct hil_ptr *ptr;
-
-	ptr = serio_get_drvdata(serio);
-	BUG_ON(ptr == NULL);
-
-	serio_close(serio);
-	input_unregister_device(ptr->dev);
-	kfree(ptr);
-}
-
-static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
-{
-	struct hil_ptr	*ptr;
-	const char	*txt;
-	unsigned int	i, naxsets, btntype;
-	uint8_t		did, *idd;
-	int		error;
-
-	ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL);
-	if (!ptr)
-		return -ENOMEM;
-
-	ptr->dev = input_allocate_device();
-	if (!ptr->dev) {
-		error = -ENOMEM;
-		goto bail0;
-	}
-
-	error = serio_open(serio, driver);
-	if (error)
-		goto bail1;
-
-	serio_set_drvdata(serio, ptr);
-	ptr->serio = serio;
-
-	init_MUTEX_LOCKED(&ptr->sem);
-
-	/* Get device info.  MLC driver supplies devid/status/etc. */
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_IDD);
-	down(&ptr->sem);
-
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_RSC);
-	down(&ptr->sem);
-
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_RNM);
-	down(&ptr->sem);
-
-	serio->write(serio, 0);
-	serio->write(serio, 0);
-	serio->write(serio, HIL_PKT_CMD >> 8);
-	serio->write(serio, HIL_CMD_EXD);
-	down(&ptr->sem);
-
-	up(&ptr->sem);
-
-	did = ptr->idd[0];
-	idd = ptr->idd + 1;
-	txt = "unknown";
-
-	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
-		ptr->dev->evbit[0] = BIT_MASK(EV_REL);
-		txt = "relative";
-	}
-
-	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
-		ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
-		txt = "absolute";
-	}
-
-	if (!ptr->dev->evbit[0]) {
-		error = -ENODEV;
-		goto bail2;
-	}
-
-	ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
-	if (ptr->nbtn)
-		ptr->dev->evbit[0] |= BIT_MASK(EV_KEY);
-
-	naxsets = HIL_IDD_NUM_AXSETS(*idd);
-	ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
-
-	printk(KERN_INFO PREFIX "HIL pointer device found (did: 0x%02x, axis: %s)\n",
-			did, txt);
-	printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n",
-			ptr->nbtn, naxsets, ptr->naxes);
-
-	btntype = BTN_MISC;
-	if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
-#ifdef TABLET_SIMULATES_MOUSE
-		btntype = BTN_TOUCH;
-#else
-		btntype = BTN_DIGI;
-#endif
-	if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
-		btntype = BTN_TOUCH;
-
-	if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
-		btntype = BTN_MOUSE;
-
-	for (i = 0; i < ptr->nbtn; i++) {
-		set_bit(btntype | i, ptr->dev->keybit);
-		ptr->btnmap[i] = btntype | i;
-	}
-
-	if (btntype == BTN_MOUSE) {
-		/* Swap buttons 2 and 3 */
-		ptr->btnmap[1] = BTN_MIDDLE;
-		ptr->btnmap[2] = BTN_RIGHT;
-	}
-
-	if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
-		for (i = 0; i < ptr->naxes; i++)
-			set_bit(REL_X + i, ptr->dev->relbit);
-		for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++)
-			set_bit(REL_X + i, ptr->dev->relbit);
-	} else {
-		for (i = 0; i < ptr->naxes; i++) {
-			set_bit(ABS_X + i, ptr->dev->absbit);
-			ptr->dev->absmin[ABS_X + i] = 0;
-			ptr->dev->absmax[ABS_X + i] =
-				HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
-		}
-		for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
-			set_bit(ABS_X + i, ptr->dev->absbit);
-			ptr->dev->absmin[ABS_X + i] = 0;
-			ptr->dev->absmax[ABS_X + i] =
-				HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
-		}
-#ifdef TABLET_AUTOADJUST
-		for (i = 0; i < ABS_MAX; i++) {
-			int diff = ptr->dev->absmax[ABS_X + i] / 10;
-			ptr->dev->absmin[ABS_X + i] += diff;
-			ptr->dev->absmax[ABS_X + i] -= diff;
-		}
-#endif
-	}
-
-	ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
-
-	ptr->dev->id.bustype	= BUS_HIL;
-	ptr->dev->id.vendor	= PCI_VENDOR_ID_HP;
-	ptr->dev->id.product	= 0x0001; /* TODO: get from ptr->rsc */
-	ptr->dev->id.version	= 0x0100; /* TODO: get from ptr->rsc */
-	ptr->dev->dev.parent	= &serio->dev;
-
-	error = input_register_device(ptr->dev);
-	if (error) {
-		printk(KERN_INFO PREFIX "Unable to register input device\n");
-		goto bail2;
-	}
-
-	printk(KERN_INFO "input: %s (%s), ID: %d\n",
-		ptr->dev->name,
-		(btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
-		did);
-
-	return 0;
-
- bail2:
-	serio_close(serio);
- bail1:
-	input_free_device(ptr->dev);
- bail0:
-	kfree(ptr);
-	serio_set_drvdata(serio, NULL);
-	return error;
-}
-
-static struct serio_device_id hil_ptr_ids[] = {
-	{
-		.type = SERIO_HIL_MLC,
-		.proto = SERIO_HIL,
-		.id = SERIO_ANY,
-		.extra = SERIO_ANY,
-	},
-	{ 0 }
-};
-
-static struct serio_driver hil_ptr_serio_driver = {
-	.driver		= {
-		.name	= "hil_ptr",
-	},
-	.description	= "HP HIL mouse/tablet driver",
-	.id_table	= hil_ptr_ids,
-	.connect	= hil_ptr_connect,
-	.disconnect	= hil_ptr_disconnect,
-	.interrupt	= hil_ptr_interrupt
-};
-
-static int __init hil_ptr_init(void)
-{
-	return serio_register_driver(&hil_ptr_serio_driver);
-}
-
-static void __exit hil_ptr_exit(void)
-{
-	serio_unregister_driver(&hil_ptr_serio_driver);
-}
-
-module_init(hil_ptr_init);
-module_exit(hil_ptr_exit);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index dcd4236..5e63086 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -33,11 +33,11 @@ static int lifebook_set_serio_phys(const struct dmi_system_id *d)
 	return 0;
 }
 
-static unsigned char lifebook_use_6byte_proto;
+static bool lifebook_use_6byte_proto;
 
 static int lifebook_set_6byte_proto(const struct dmi_system_id *d)
 {
-	lifebook_use_6byte_proto = 1;
+	lifebook_use_6byte_proto = true;
 	return 0;
 }
 
@@ -125,7 +125,7 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
 	struct input_dev *dev1 = psmouse->dev;
 	struct input_dev *dev2 = priv ? priv->dev2 : NULL;
 	unsigned char *packet = psmouse->packet;
-	int relative_packet = packet[0] & 0x08;
+	bool relative_packet = packet[0] & 0x08;
 
 	if (relative_packet || !lifebook_use_6byte_proto) {
 		if (psmouse->pktcnt != 3)
@@ -242,7 +242,7 @@ static void lifebook_disconnect(struct psmouse *psmouse)
 	psmouse->private = NULL;
 }
 
-int lifebook_detect(struct psmouse *psmouse, int set_properties)
+int lifebook_detect(struct psmouse *psmouse, bool set_properties)
 {
         if (!dmi_check_system(lifebook_dmi_table))
                 return -1;
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h
index c1647cf..407cb22 100644
--- a/drivers/input/mouse/lifebook.h
+++ b/drivers/input/mouse/lifebook.h
@@ -12,10 +12,10 @@
 #define _LIFEBOOK_H
 
 #ifdef CONFIG_MOUSE_PS2_LIFEBOOK
-int lifebook_detect(struct psmouse *psmouse, int set_properties);
+int lifebook_detect(struct psmouse *psmouse, bool set_properties);
 int lifebook_init(struct psmouse *psmouse);
 #else
-inline int lifebook_detect(struct psmouse *psmouse, int set_properties)
+inline int lifebook_detect(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENOSYS;
 }
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 390f1db..de745d7 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -130,14 +130,11 @@ static int ps2pp_cmd(struct psmouse *psmouse, unsigned char *param, unsigned cha
  * 0 - disabled
  */
 
-static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscroll)
+static void ps2pp_set_smartscroll(struct psmouse *psmouse, bool smartscroll)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
 
-	if (smartscroll > 1)
-		smartscroll = 1;
-
 	ps2pp_cmd(psmouse, param, 0x32);
 
 	param[0] = 0;
@@ -149,12 +146,14 @@ static void ps2pp_set_smartscroll(struct psmouse *psmouse, unsigned int smartscr
 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
 }
 
-static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data, char *buf)
+static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse,
+					   void *data, char *buf)
 {
-	return sprintf(buf, "%d\n", psmouse->smartscroll ? 1 : 0);
+	return sprintf(buf, "%d\n", psmouse->smartscroll);
 }
 
-static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
+static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data,
+					  const char *buf, size_t count)
 {
 	unsigned long value;
 
@@ -261,29 +260,29 @@ static const struct ps2pp_info *get_model_info(unsigned char model)
 
 static void ps2pp_set_model_properties(struct psmouse *psmouse,
 				       const struct ps2pp_info *model_info,
-				       int using_ps2pp)
+				       bool using_ps2pp)
 {
 	struct input_dev *input_dev = psmouse->dev;
 
 	if (model_info->features & PS2PP_SIDE_BTN)
-		set_bit(BTN_SIDE, input_dev->keybit);
+		__set_bit(BTN_SIDE, input_dev->keybit);
 
 	if (model_info->features & PS2PP_EXTRA_BTN)
-		set_bit(BTN_EXTRA, input_dev->keybit);
+		__set_bit(BTN_EXTRA, input_dev->keybit);
 
 	if (model_info->features & PS2PP_TASK_BTN)
-		set_bit(BTN_TASK, input_dev->keybit);
+		__set_bit(BTN_TASK, input_dev->keybit);
 
 	if (model_info->features & PS2PP_NAV_BTN) {
-		set_bit(BTN_FORWARD, input_dev->keybit);
-		set_bit(BTN_BACK, input_dev->keybit);
+		__set_bit(BTN_FORWARD, input_dev->keybit);
+		__set_bit(BTN_BACK, input_dev->keybit);
 	}
 
 	if (model_info->features & PS2PP_WHEEL)
-		set_bit(REL_WHEEL, input_dev->relbit);
+		__set_bit(REL_WHEEL, input_dev->relbit);
 
 	if (model_info->features & PS2PP_HWHEEL)
-		set_bit(REL_HWHEEL, input_dev->relbit);
+		__set_bit(REL_HWHEEL, input_dev->relbit);
 
 	switch (model_info->kind) {
 		case PS2PP_KIND_WHEEL:
@@ -321,13 +320,13 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse,
  * that support it.
  */
 
-int ps2pp_init(struct psmouse *psmouse, int set_properties)
+int ps2pp_init(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
 	unsigned char model, buttons;
 	const struct ps2pp_info *model_info;
-	int use_ps2pp = 0;
+	bool use_ps2pp = false;
 	int error;
 
 	param[0] = 0;
@@ -364,7 +363,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
 			param[0] = 0;
 			if (!ps2_command(ps2dev, param, 0x13d1) &&
 			    param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) {
-				use_ps2pp = 1;
+				use_ps2pp = true;
 			}
 
 		} else {
@@ -376,8 +375,8 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
 			if ((param[0] & 0x78) == 0x48 &&
 			    (param[1] & 0xf3) == 0xc2 &&
 			    (param[2] & 0x03) == ((param[1] >> 2) & 3)) {
-				ps2pp_set_smartscroll(psmouse, psmouse->smartscroll);
-				use_ps2pp = 1;
+				ps2pp_set_smartscroll(psmouse, false);
+				use_ps2pp = true;
 			}
 		}
 	}
@@ -406,7 +405,7 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
 		}
 
 		if (buttons < 3)
-			clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
+			__clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
 
 		if (model_info)
 			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
index 6e57125..0c186f0 100644
--- a/drivers/input/mouse/logips2pp.h
+++ b/drivers/input/mouse/logips2pp.h
@@ -12,9 +12,9 @@
 #define _LOGIPS2PP_H
 
 #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
-int ps2pp_init(struct psmouse *psmouse, int set_properties);
+int ps2pp_init(struct psmouse *psmouse, bool set_properties);
 #else
-inline int ps2pp_init(struct psmouse *psmouse, int set_properties)
+inline int ps2pp_init(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENOSYS;
 }
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index b407b35..690aed9 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -30,6 +30,7 @@
 #include "trackpoint.h"
 #include "touchkit_ps2.h"
 #include "elantech.h"
+#include "sentelic.h"
 
 #define DRIVER_DESC	"PS/2 mouse driver"
 
@@ -108,10 +109,10 @@ static struct workqueue_struct *kpsmoused_wq;
 
 struct psmouse_protocol {
 	enum psmouse_type type;
+	bool maxproto;
 	const char *name;
 	const char *alias;
-	int maxproto;
-	int (*detect)(struct psmouse *, int);
+	int (*detect)(struct psmouse *, bool);
 	int (*init)(struct psmouse *);
 };
 
@@ -216,7 +217,7 @@ void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
 static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
 {
 	psmouse->state = new_state;
-	psmouse->pktcnt = psmouse->out_of_sync = 0;
+	psmouse->pktcnt = psmouse->out_of_sync_cnt = 0;
 	psmouse->ps2dev.flags = 0;
 	psmouse->last = jiffies;
 }
@@ -249,7 +250,7 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
 			if (psmouse->state == PSMOUSE_ACTIVATED) {
 				printk(KERN_WARNING "psmouse.c: %s at %s lost sync at byte %d\n",
 					psmouse->name, psmouse->phys, psmouse->pktcnt);
-				if (++psmouse->out_of_sync == psmouse->resetafter) {
+				if (++psmouse->out_of_sync_cnt == psmouse->resetafter) {
 					__psmouse_set_state(psmouse, PSMOUSE_IGNORE);
 					printk(KERN_NOTICE "psmouse.c: issuing reconnect request\n");
 					serio_reconnect(psmouse->ps2dev.serio);
@@ -261,8 +262,8 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
 
 		case PSMOUSE_FULL_PACKET:
 			psmouse->pktcnt = 0;
-			if (psmouse->out_of_sync) {
-				psmouse->out_of_sync = 0;
+			if (psmouse->out_of_sync_cnt) {
+				psmouse->out_of_sync_cnt = 0;
 				printk(KERN_NOTICE "psmouse.c: %s at %s - driver resynched.\n",
 					psmouse->name, psmouse->phys);
 			}
@@ -408,7 +409,7 @@ int psmouse_reset(struct psmouse *psmouse)
 /*
  * Genius NetMouse magic init.
  */
-static int genius_detect(struct psmouse *psmouse, int set_properties)
+static int genius_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
@@ -424,9 +425,9 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
 		return -1;
 
 	if (set_properties) {
-		set_bit(BTN_EXTRA, psmouse->dev->keybit);
-		set_bit(BTN_SIDE, psmouse->dev->keybit);
-		set_bit(REL_WHEEL, psmouse->dev->relbit);
+		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
+		__set_bit(BTN_SIDE, psmouse->dev->keybit);
+		__set_bit(REL_WHEEL, psmouse->dev->relbit);
 
 		psmouse->vendor = "Genius";
 		psmouse->name = "Mouse";
@@ -439,7 +440,7 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
 /*
  * IntelliMouse magic init.
  */
-static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
+static int intellimouse_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[2];
@@ -456,8 +457,8 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
 		return -1;
 
 	if (set_properties) {
-		set_bit(BTN_MIDDLE, psmouse->dev->keybit);
-		set_bit(REL_WHEEL, psmouse->dev->relbit);
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		__set_bit(REL_WHEEL, psmouse->dev->relbit);
 
 		if (!psmouse->vendor) psmouse->vendor = "Generic";
 		if (!psmouse->name) psmouse->name = "Wheel Mouse";
@@ -470,7 +471,7 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
 /*
  * Try IntelliMouse/Explorer magic init.
  */
-static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
+static int im_explorer_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[2];
@@ -497,11 +498,11 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
 	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
 
 	if (set_properties) {
-		set_bit(BTN_MIDDLE, psmouse->dev->keybit);
-		set_bit(REL_WHEEL, psmouse->dev->relbit);
-		set_bit(REL_HWHEEL, psmouse->dev->relbit);
-		set_bit(BTN_SIDE, psmouse->dev->keybit);
-		set_bit(BTN_EXTRA, psmouse->dev->keybit);
+		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		__set_bit(REL_WHEEL, psmouse->dev->relbit);
+		__set_bit(REL_HWHEEL, psmouse->dev->relbit);
+		__set_bit(BTN_SIDE, psmouse->dev->keybit);
+		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
 		if (!psmouse->vendor) psmouse->vendor = "Generic";
 		if (!psmouse->name) psmouse->name = "Explorer Mouse";
@@ -514,7 +515,7 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
 /*
  * Kensington ThinkingMouse / ExpertMouse magic init.
  */
-static int thinking_detect(struct psmouse *psmouse, int set_properties)
+static int thinking_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[2];
@@ -535,7 +536,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
 		return -1;
 
 	if (set_properties) {
-		set_bit(BTN_EXTRA, psmouse->dev->keybit);
+		__set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
 		psmouse->vendor = "Kensington";
 		psmouse->name = "ThinkingMouse";
@@ -547,7 +548,7 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
 /*
  * Bare PS/2 protocol "detection". Always succeeds.
  */
-static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
+static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
 {
 	if (set_properties) {
 		if (!psmouse->vendor) psmouse->vendor = "Generic";
@@ -561,12 +562,12 @@ static int ps2bare_detect(struct psmouse *psmouse, int set_properties)
  * Cortron PS/2 protocol detection. There's no special way to detect it, so it
  * must be forced by sysfs protocol writing.
  */
-static int cortron_detect(struct psmouse *psmouse, int set_properties)
+static int cortron_detect(struct psmouse *psmouse, bool set_properties)
 {
 	if (set_properties) {
 		psmouse->vendor = "Cortron";
 		psmouse->name = "PS/2 Trackball";
-		set_bit(BTN_SIDE, psmouse->dev->keybit);
+		__set_bit(BTN_SIDE, psmouse->dev->keybit);
 	}
 
 	return 0;
@@ -578,9 +579,9 @@ static int cortron_detect(struct psmouse *psmouse, int set_properties)
  */
 
 static int psmouse_extensions(struct psmouse *psmouse,
-			      unsigned int max_proto, int set_properties)
+			      unsigned int max_proto, bool set_properties)
 {
-	int synaptics_hardware = 0;
+	bool synaptics_hardware = true;
 
 /*
  * We always check for lifebook because it does not disturb mouse
@@ -607,7 +608,7 @@ static int psmouse_extensions(struct psmouse *psmouse,
  * can reset it properly after probing for intellimouse.
  */
 	if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
-		synaptics_hardware = 1;
+		synaptics_hardware = true;
 
 		if (max_proto > PSMOUSE_IMEX) {
 			if (!set_properties || synaptics_init(psmouse) == 0)
@@ -666,6 +667,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
 		max_proto = PSMOUSE_IMEX;
 	}
 
+/*
+ * Try Finger Sensing Pad
+ */
+	if (max_proto > PSMOUSE_IMEX) {
+		if (fsp_detect(psmouse, set_properties) == 0) {
+			if (!set_properties || fsp_init(psmouse) == 0)
+				return PSMOUSE_FSP;
+/*
+ * Init failed, try basic relative protocols
+ */
+			max_proto = PSMOUSE_IMEX;
+		}
+	}
+
 	if (max_proto > PSMOUSE_IMEX) {
 		if (genius_detect(psmouse, set_properties) == 0)
 			return PSMOUSE_GENPS;
@@ -718,7 +733,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
 		.type		= PSMOUSE_PS2,
 		.name		= "PS/2",
 		.alias		= "bare",
-		.maxproto	= 1,
+		.maxproto	= true,
 		.detect		= ps2bare_detect,
 	},
 #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
@@ -745,14 +760,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
 		.type		= PSMOUSE_IMPS,
 		.name		= "ImPS/2",
 		.alias		= "imps",
-		.maxproto	= 1,
+		.maxproto	= true,
 		.detect		= intellimouse_detect,
 	},
 	{
 		.type		= PSMOUSE_IMEX,
 		.name		= "ImExPS/2",
 		.alias		= "exps",
-		.maxproto	= 1,
+		.maxproto	= true,
 		.detect		= im_explorer_detect,
 	},
 #ifdef CONFIG_MOUSE_PS2_SYNAPTICS
@@ -813,7 +828,16 @@ static const struct psmouse_protocol psmouse_protocols[] = {
 		.detect		= elantech_detect,
 		.init		= elantech_init,
 	},
- #endif
+#endif
+#ifdef CONFIG_MOUSE_PS2_SENTELIC
+	{
+		.type		= PSMOUSE_FSP,
+		.name		= "FSPPS/2",
+		.alias		= "fsp",
+		.detect		= fsp_detect,
+		.init		= fsp_init,
+	},
+#endif
 	{
 		.type		= PSMOUSE_CORTRON,
 		.name		= "CortronPS/2",
@@ -824,7 +848,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
 		.type		= PSMOUSE_AUTO,
 		.name		= "auto",
 		.alias		= "any",
-		.maxproto	= 1,
+		.maxproto	= true,
 	},
 };
 
@@ -990,7 +1014,7 @@ static void psmouse_resync(struct work_struct *work)
 		container_of(work, struct psmouse, resync_work.work);
 	struct serio *serio = psmouse->ps2dev.serio;
 	psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
-	int failed = 0, enabled = 0;
+	bool failed = false, enabled = false;
 	int i;
 
 	mutex_lock(&psmouse_mutex);
@@ -1017,9 +1041,9 @@ static void psmouse_resync(struct work_struct *work)
 
 	if (ps2_sendbyte(&psmouse->ps2dev, PSMOUSE_CMD_DISABLE, 20)) {
 		if (psmouse->num_resyncs < 3 || psmouse->acks_disable_command)
-			failed = 1;
+			failed = true;
 	} else
-		psmouse->acks_disable_command = 1;
+		psmouse->acks_disable_command = true;
 
 /*
  * Poll the mouse. If it was reset the packet will be shorter than
@@ -1030,7 +1054,7 @@ static void psmouse_resync(struct work_struct *work)
  */
 	if (!failed) {
 		if (psmouse->poll(psmouse))
-			failed = 1;
+			failed = true;
 		else {
 			psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 			for (i = 0; i < psmouse->pktsize; i++) {
@@ -1040,7 +1064,7 @@ static void psmouse_resync(struct work_struct *work)
 					break;
 			}
 			if (rc != PSMOUSE_FULL_PACKET)
-				failed = 1;
+				failed = true;
 			psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
 		}
 	}
@@ -1051,7 +1075,7 @@ static void psmouse_resync(struct work_struct *work)
  */
 	for (i = 0; i < 5; i++) {
 		if (!ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE)) {
-			enabled = 1;
+			enabled = true;
 			break;
 		}
 		msleep(200);
@@ -1060,7 +1084,7 @@ static void psmouse_resync(struct work_struct *work)
 	if (!enabled) {
 		printk(KERN_WARNING "psmouse.c: failed to re-enable mouse on %s\n",
 			psmouse->ps2dev.serio->phys);
-		failed = 1;
+		failed = true;
 	}
 
 	if (failed) {
@@ -1187,7 +1211,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
 		psmouse->type = proto->type;
 	}
 	else
-		psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1);
+		psmouse->type = psmouse_extensions(psmouse,
+						   psmouse_max_proto, true);
 
 	/*
 	 * If mouse's packet size is 3 there is no point in polling the
@@ -1342,8 +1367,10 @@ static int psmouse_reconnect(struct serio *serio)
 		if (psmouse->reconnect(psmouse))
 			goto out;
 	} else if (psmouse_probe(psmouse) < 0 ||
-		   psmouse->type != psmouse_extensions(psmouse, psmouse_max_proto, 0))
+		   psmouse->type != psmouse_extensions(psmouse,
+						psmouse_max_proto, false)) {
 		goto out;
+	}
 
 	/* ok, the device type (and capabilities) match the old one,
 	 * we can continue using it, complete intialization
@@ -1528,7 +1555,9 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
 
 	while (serio->child) {
 		if (++retry > 3) {
-			printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n");
+			printk(KERN_WARNING
+				"psmouse: failed to destroy child port, "
+				"protocol change aborted.\n");
 			input_free_device(new_dev);
 			return -EIO;
 		}
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 54ed267..e053bdd 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -47,10 +47,10 @@ struct psmouse {
 	unsigned char pktcnt;
 	unsigned char pktsize;
 	unsigned char type;
-	unsigned char acks_disable_command;
+	bool acks_disable_command;
 	unsigned int model;
 	unsigned long last;
-	unsigned long out_of_sync;
+	unsigned long out_of_sync_cnt;
 	unsigned long num_resyncs;
 	enum psmouse_state state;
 	char devname[64];
@@ -60,7 +60,7 @@ struct psmouse {
 	unsigned int resolution;
 	unsigned int resetafter;
 	unsigned int resync_time;
-	unsigned int smartscroll;	/* Logitech only */
+	bool smartscroll;	/* Logitech only */
 
 	psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse);
 	void (*set_rate)(struct psmouse *psmouse, unsigned int rate);
@@ -91,6 +91,7 @@ enum psmouse_type {
 	PSMOUSE_CORTRON,
 	PSMOUSE_HGPK,
 	PSMOUSE_ELANTECH,
+	PSMOUSE_FSP,
 	PSMOUSE_AUTO		/* This one should always be last */
 };
 
@@ -107,7 +108,7 @@ struct psmouse_attribute {
 	ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
 	ssize_t (*set)(struct psmouse *psmouse, void *data,
 			const char *buf, size_t count);
-	int protect;
+	bool protect;
 };
 #define to_psmouse_attr(a)	container_of((a), struct psmouse_attribute, dattr)
 
@@ -116,9 +117,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
 ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
 				const char *buf, size_t count);
 
-#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect)	\
-static ssize_t _show(struct psmouse *, void *data, char *);			\
-static ssize_t _set(struct psmouse *, void *data, const char *, size_t);	\
+#define __PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect)	\
 static struct psmouse_attribute psmouse_attr_##_name = {			\
 	.dattr	= {								\
 		.attr	= {							\
@@ -134,7 +133,20 @@ static struct psmouse_attribute psmouse_attr_##_name = {			\
 	.protect = _protect,							\
 }
 
-#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set)	\
-		__PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1)
+#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect)	\
+	static ssize_t _show(struct psmouse *, void *, char *);			\
+	static ssize_t _set(struct psmouse *, void *, const char *, size_t);	\
+	__PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, _set, _protect)
+
+#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set)			\
+	__PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, true)
+
+#define PSMOUSE_DEFINE_RO_ATTR(_name, _mode, _data, _show)			\
+	static ssize_t _show(struct psmouse *, void *, char *);			\
+	__PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, _show, NULL, true)
+
+#define PSMOUSE_DEFINE_WO_ATTR(_name, _mode, _data, _set)			\
+	static ssize_t _set(struct psmouse *, void *, const char *, size_t);	\
+	__PSMOUSE_DEFINE_ATTR_VAR(_name, _mode, _data, NULL, _set, true)
 
 #endif /* _PSMOUSE_H */
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c
new file mode 100644
index 0000000..84e2fc0
--- /dev/null
+++ b/drivers/input/mouse/sentelic.c
@@ -0,0 +1,867 @@
+/*-
+ * Finger Sensing Pad PS/2 mouse driver.
+ *
+ * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
+ * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/input.h>
+#include <linux/ctype.h>
+#include <linux/libps2.h>
+#include <linux/serio.h>
+#include <linux/jiffies.h>
+
+#include "psmouse.h"
+#include "sentelic.h"
+
+/*
+ * Timeout for FSP PS/2 command only (in milliseconds).
+ */
+#define	FSP_CMD_TIMEOUT		200
+#define	FSP_CMD_TIMEOUT2	30
+
+/** Driver version. */
+static const char fsp_drv_ver[] = "1.0.0-K";
+
+/*
+ * Make sure that the value being sent to FSP will not conflict with
+ * possible sample rate values.
+ */
+static unsigned char fsp_test_swap_cmd(unsigned char reg_val)
+{
+	switch (reg_val) {
+	case 10: case 20: case 40: case 60: case 80: case 100: case 200:
+		/*
+		 * The requested value being sent to FSP matched to possible
+		 * sample rates, swap the given value such that the hardware
+		 * wouldn't get confused.
+		 */
+		return (reg_val >> 4) | (reg_val << 4);
+	default:
+		return reg_val;	/* swap isn't necessary */
+	}
+}
+
+/*
+ * Make sure that the value being sent to FSP will not conflict with certain
+ * commands.
+ */
+static unsigned char fsp_test_invert_cmd(unsigned char reg_val)
+{
+	switch (reg_val) {
+	case 0xe9: case 0xee: case 0xf2: case 0xff:
+		/*
+		 * The requested value being sent to FSP matched to certain
+		 * commands, inverse the given value such that the hardware
+		 * wouldn't get confused.
+		 */
+		return ~reg_val;
+	default:
+		return reg_val;	/* inversion isn't necessary */
+	}
+}
+
+static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[3];
+	unsigned char addr;
+	int rc = -1;
+
+	/*
+	 * We need to shut off the device and switch it into command
+	 * mode so we don't confuse our protocol handler. We don't need
+	 * to do that for writes because sysfs set helper does this for
+	 * us.
+	 */
+	ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+	mutex_lock(&ps2dev->cmd_mutex);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		goto out;
+
+	/* should return 0xfe(request for resending) */
+	ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
+	/* should return 0xfc(failed) */
+	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		goto out;
+
+	if ((addr = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
+		ps2_sendbyte(ps2dev, 0x68, FSP_CMD_TIMEOUT2);
+	} else if ((addr = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
+		/* swapping is required */
+		ps2_sendbyte(ps2dev, 0xcc, FSP_CMD_TIMEOUT2);
+		/* expect 0xfe */
+	} else {
+		/* swapping isn't necessary */
+		ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
+		/* expect 0xfe */
+	}
+	/* should return 0xfc(failed) */
+	ps2_sendbyte(ps2dev, addr, FSP_CMD_TIMEOUT);
+
+	if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO) < 0)
+		goto out;
+
+	*reg_val = param[2];
+	rc = 0;
+
+ out:
+	mutex_unlock(&ps2dev->cmd_mutex);
+	ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+	psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+	dev_dbg(&ps2dev->serio->dev, "READ REG: 0x%02x is 0x%02x (rc = %d)\n",
+		reg_addr, *reg_val, rc);
+	return rc;
+}
+
+static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char v;
+	int rc = -1;
+
+	mutex_lock(&ps2dev->cmd_mutex);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		goto out;
+
+	if ((v = fsp_test_invert_cmd(reg_addr)) != reg_addr) {
+		/* inversion is required */
+		ps2_sendbyte(ps2dev, 0x74, FSP_CMD_TIMEOUT2);
+	} else {
+		if ((v = fsp_test_swap_cmd(reg_addr)) != reg_addr) {
+			/* swapping is required */
+			ps2_sendbyte(ps2dev, 0x77, FSP_CMD_TIMEOUT2);
+		} else {
+			/* swapping isn't necessary */
+			ps2_sendbyte(ps2dev, 0x55, FSP_CMD_TIMEOUT2);
+		}
+	}
+	/* write the register address in correct order */
+	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		return -1;
+
+	if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
+		/* inversion is required */
+		ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
+	} else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
+		/* swapping is required */
+		ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
+	} else {
+		/* swapping isn't necessary */
+		ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
+	}
+
+	/* write the register value in correct order */
+	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
+	rc = 0;
+
+ out:
+	mutex_unlock(&ps2dev->cmd_mutex);
+	dev_dbg(&ps2dev->serio->dev, "WRITE REG: 0x%02x to 0x%02x (rc = %d)\n",
+		reg_addr, reg_val, rc);
+	return rc;
+}
+
+/* Enable register clock gating for writing certain registers */
+static int fsp_reg_write_enable(struct psmouse *psmouse, bool enable)
+{
+	int v, nv;
+
+	if (fsp_reg_read(psmouse, FSP_REG_SYSCTL1, &v) == -1)
+		return -1;
+
+	if (enable)
+		nv = v | FSP_BIT_EN_REG_CLK;
+	else
+		nv = v & ~FSP_BIT_EN_REG_CLK;
+
+	/* only write if necessary */
+	if (nv != v)
+		if (fsp_reg_write(psmouse, FSP_REG_SYSCTL1, nv) == -1)
+			return -1;
+
+	return 0;
+}
+
+static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[3];
+	int rc = -1;
+
+	ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+	mutex_lock(&ps2dev->cmd_mutex);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		goto out;
+
+	ps2_sendbyte(ps2dev, 0x66, FSP_CMD_TIMEOUT2);
+	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		goto out;
+
+	ps2_sendbyte(ps2dev, 0x83, FSP_CMD_TIMEOUT2);
+	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+	/* get the returned result */
+	if (__ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
+		goto out;
+
+	*reg_val = param[2];
+	rc = 0;
+
+ out:
+	mutex_unlock(&ps2dev->cmd_mutex);
+	ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+	psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+	dev_dbg(&ps2dev->serio->dev, "READ PAGE REG: 0x%02x (rc = %d)\n",
+		*reg_val, rc);
+	return rc;
+}
+
+static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
+{
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char v;
+	int rc = -1;
+
+	mutex_lock(&ps2dev->cmd_mutex);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		goto out;
+
+	ps2_sendbyte(ps2dev, 0x38, FSP_CMD_TIMEOUT2);
+	ps2_sendbyte(ps2dev, 0x88, FSP_CMD_TIMEOUT2);
+
+	if (ps2_sendbyte(ps2dev, 0xf3, FSP_CMD_TIMEOUT) < 0)
+		return -1;
+
+	if ((v = fsp_test_invert_cmd(reg_val)) != reg_val) {
+		ps2_sendbyte(ps2dev, 0x47, FSP_CMD_TIMEOUT2);
+	} else if ((v = fsp_test_swap_cmd(reg_val)) != reg_val) {
+		/* swapping is required */
+		ps2_sendbyte(ps2dev, 0x44, FSP_CMD_TIMEOUT2);
+	} else {
+		/* swapping isn't necessary */
+		ps2_sendbyte(ps2dev, 0x33, FSP_CMD_TIMEOUT2);
+	}
+
+	ps2_sendbyte(ps2dev, v, FSP_CMD_TIMEOUT2);
+	rc = 0;
+
+ out:
+	mutex_unlock(&ps2dev->cmd_mutex);
+	dev_dbg(&ps2dev->serio->dev, "WRITE PAGE REG: to 0x%02x (rc = %d)\n",
+		reg_val, rc);
+	return rc;
+}
+
+static int fsp_get_version(struct psmouse *psmouse, int *version)
+{
+	if (fsp_reg_read(psmouse, FSP_REG_VERSION, version))
+		return -EIO;
+
+	return 0;
+}
+
+static int fsp_get_revision(struct psmouse *psmouse, int *rev)
+{
+	if (fsp_reg_read(psmouse, FSP_REG_REVISION, rev))
+		return -EIO;
+
+	return 0;
+}
+
+static int fsp_get_buttons(struct psmouse *psmouse, int *btn)
+{
+	static const int buttons[] = {
+		0x16, /* Left/Middle/Right/Forward/Backward & Scroll Up/Down */
+		0x06, /* Left/Middle/Right & Scroll Up/Down/Right/Left */
+		0x04, /* Left/Middle/Right & Scroll Up/Down */
+		0x02, /* Left/Middle/Right */
+	};
+	int val;
+
+	if (fsp_reg_read(psmouse, FSP_REG_TMOD_STATUS1, &val) == -1)
+		return -EIO;
+
+	*btn = buttons[(val & 0x30) >> 4];
+	return 0;
+}
+
+/* Enable on-pad command tag output */
+static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
+{
+	int v, nv;
+	int res = 0;
+
+	if (fsp_reg_read(psmouse, FSP_REG_OPC_QDOWN, &v) == -1) {
+		dev_err(&psmouse->ps2dev.serio->dev, "Unable get OPC state.\n");
+		return -EIO;
+	}
+
+	if (enable)
+		nv = v | FSP_BIT_EN_OPC_TAG;
+	else
+		nv = v & ~FSP_BIT_EN_OPC_TAG;
+
+	/* only write if necessary */
+	if (nv != v) {
+		fsp_reg_write_enable(psmouse, true);
+		res = fsp_reg_write(psmouse, FSP_REG_OPC_QDOWN, nv);
+		fsp_reg_write_enable(psmouse, false);
+	}
+
+	if (res != 0) {
+		dev_err(&psmouse->ps2dev.serio->dev,
+			"Unable to enable OPC tag.\n");
+		res = -EIO;
+	}
+
+	return res;
+}
+
+static int fsp_onpad_vscr(struct psmouse *psmouse, bool enable)
+{
+	struct fsp_data *pad = psmouse->private;
+	int val;
+
+	if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
+		return -EIO;
+
+	pad->vscroll = enable;
+
+	if (enable)
+		val |= (FSP_BIT_FIX_VSCR | FSP_BIT_ONPAD_ENABLE);
+	else
+		val &= ~FSP_BIT_FIX_VSCR;
+
+	if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
+		return -EIO;
+
+	return 0;
+}
+
+static int fsp_onpad_hscr(struct psmouse *psmouse, bool enable)
+{
+	struct fsp_data *pad = psmouse->private;
+	int val, v2;
+
+	if (fsp_reg_read(psmouse, FSP_REG_ONPAD_CTL, &val))
+		return -EIO;
+
+	if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &v2))
+		return -EIO;
+
+	pad->hscroll = enable;
+
+	if (enable) {
+		val |= (FSP_BIT_FIX_HSCR | FSP_BIT_ONPAD_ENABLE);
+		v2 |= FSP_BIT_EN_MSID6;
+	} else {
+		val &= ~FSP_BIT_FIX_HSCR;
+		v2 &= ~(FSP_BIT_EN_MSID6 | FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8);
+	}
+
+	if (fsp_reg_write(psmouse, FSP_REG_ONPAD_CTL, val))
+		return -EIO;
+
+	/* reconfigure horizontal scrolling packet output */
+	if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, v2))
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Write device specific initial parameters.
+ *
+ * ex: 0xab 0xcd - write oxcd into register 0xab
+ */
+static ssize_t fsp_attr_set_setreg(struct psmouse *psmouse, void *data,
+				   const char *buf, size_t count)
+{
+	unsigned long reg, val;
+	char *rest;
+	ssize_t retval;
+
+	reg = simple_strtoul(buf, &rest, 16);
+	if (rest == buf || *rest != ' ' || reg > 0xff)
+		return -EINVAL;
+
+	if (strict_strtoul(rest + 1, 16, &val) || val > 0xff)
+		return -EINVAL;
+
+	if (fsp_reg_write_enable(psmouse, true))
+		return -EIO;
+
+	retval = fsp_reg_write(psmouse, reg, val) < 0 ? -EIO : count;
+
+	fsp_reg_write_enable(psmouse, false);
+
+	return count;
+}
+
+PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg);
+
+static ssize_t fsp_attr_show_getreg(struct psmouse *psmouse,
+					void *data, char *buf)
+{
+	struct fsp_data *pad = psmouse->private;
+
+	return sprintf(buf, "%02x%02x\n", pad->last_reg, pad->last_val);
+}
+
+/*
+ * Read a register from device.
+ *
+ * ex: 0xab -- read content from register 0xab
+ */
+static ssize_t fsp_attr_set_getreg(struct psmouse *psmouse, void *data,
+					const char *buf, size_t count)
+{
+	struct fsp_data *pad = psmouse->private;
+	unsigned long reg;
+	int val;
+
+	if (strict_strtoul(buf, 16, &reg) || reg > 0xff)
+		return -EINVAL;
+
+	if (fsp_reg_read(psmouse, reg, &val))
+		return -EIO;
+
+	pad->last_reg = reg;
+	pad->last_val = val;
+
+	return count;
+}
+
+PSMOUSE_DEFINE_ATTR(getreg, S_IWUSR | S_IRUGO, NULL,
+			fsp_attr_show_getreg, fsp_attr_set_getreg);
+
+static ssize_t fsp_attr_show_pagereg(struct psmouse *psmouse,
+					void *data, char *buf)
+{
+	int val = 0;
+
+	if (fsp_page_reg_read(psmouse, &val))
+		return -EIO;
+
+	return sprintf(buf, "%02x\n", val);
+}
+
+static ssize_t fsp_attr_set_pagereg(struct psmouse *psmouse, void *data,
+					const char *buf, size_t count)
+{
+	unsigned long val;
+
+	if (strict_strtoul(buf, 16, &val) || val > 0xff)
+		return -EINVAL;
+
+	if (fsp_page_reg_write(psmouse, val))
+		return -EIO;
+
+	return count;
+}
+
+PSMOUSE_DEFINE_ATTR(page, S_IWUSR | S_IRUGO, NULL,
+			fsp_attr_show_pagereg, fsp_attr_set_pagereg);
+
+static ssize_t fsp_attr_show_vscroll(struct psmouse *psmouse,
+					void *data, char *buf)
+{
+	struct fsp_data *pad = psmouse->private;
+
+	return sprintf(buf, "%d\n", pad->vscroll);
+}
+
+static ssize_t fsp_attr_set_vscroll(struct psmouse *psmouse, void *data,
+					const char *buf, size_t count)
+{
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val) || val > 1)
+		return -EINVAL;
+
+	fsp_onpad_vscr(psmouse, val);
+
+	return count;
+}
+
+PSMOUSE_DEFINE_ATTR(vscroll, S_IWUSR | S_IRUGO, NULL,
+			fsp_attr_show_vscroll, fsp_attr_set_vscroll);
+
+static ssize_t fsp_attr_show_hscroll(struct psmouse *psmouse,
+					void *data, char *buf)
+{
+	struct fsp_data *pad = psmouse->private;
+
+	return sprintf(buf, "%d\n", pad->hscroll);
+}
+
+static ssize_t fsp_attr_set_hscroll(struct psmouse *psmouse, void *data,
+					const char *buf, size_t count)
+{
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val) || val > 1)
+		return -EINVAL;
+
+	fsp_onpad_hscr(psmouse, val);
+
+	return count;
+}
+
+PSMOUSE_DEFINE_ATTR(hscroll, S_IWUSR | S_IRUGO, NULL,
+			fsp_attr_show_hscroll, fsp_attr_set_hscroll);
+
+static ssize_t fsp_attr_show_flags(struct psmouse *psmouse,
+					void *data, char *buf)
+{
+	struct fsp_data *pad = psmouse->private;
+
+	return sprintf(buf, "%c\n",
+			pad->flags & FSPDRV_FLAG_EN_OPC ? 'C' : 'c');
+}
+
+static ssize_t fsp_attr_set_flags(struct psmouse *psmouse, void *data,
+					const char *buf, size_t count)
+{
+	struct fsp_data *pad = psmouse->private;
+	size_t i;
+
+	for (i = 0; i < count; i++) {
+		switch (buf[i]) {
+		case 'C':
+			pad->flags |= FSPDRV_FLAG_EN_OPC;
+			break;
+		case 'c':
+			pad->flags &= ~FSPDRV_FLAG_EN_OPC;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+	return count;
+}
+
+PSMOUSE_DEFINE_ATTR(flags, S_IWUSR | S_IRUGO, NULL,
+			fsp_attr_show_flags, fsp_attr_set_flags);
+
+static ssize_t fsp_attr_show_ver(struct psmouse *psmouse,
+					void *data, char *buf)
+{
+	return sprintf(buf, "Sentelic FSP kernel module %s\n", fsp_drv_ver);
+}
+
+PSMOUSE_DEFINE_RO_ATTR(ver, S_IRUGO, NULL, fsp_attr_show_ver);
+
+static struct attribute *fsp_attributes[] = {
+	&psmouse_attr_setreg.dattr.attr,
+	&psmouse_attr_getreg.dattr.attr,
+	&psmouse_attr_page.dattr.attr,
+	&psmouse_attr_vscroll.dattr.attr,
+	&psmouse_attr_hscroll.dattr.attr,
+	&psmouse_attr_flags.dattr.attr,
+	&psmouse_attr_ver.dattr.attr,
+	NULL
+};
+
+static struct attribute_group fsp_attribute_group = {
+	.attrs = fsp_attributes,
+};
+
+#ifdef FSP_DEBUG
+static void fsp_packet_debug(unsigned char packet[])
+{
+	static unsigned int ps2_packet_cnt;
+	static unsigned int ps2_last_second;
+	unsigned int jiffies_msec;
+
+	ps2_packet_cnt++;
+	jiffies_msec = jiffies_to_msecs(jiffies);
+	printk(KERN_DEBUG "%08dms PS/2 packets: %02x, %02x, %02x, %02x\n",
+		jiffies_msec, packet[0], packet[1], packet[2], packet[3]);
+
+	if (jiffies_msec - ps2_last_second > 1000) {
+		printk(KERN_DEBUG "PS/2 packets/sec = %d\n", ps2_packet_cnt);
+		ps2_packet_cnt = 0;
+		ps2_last_second = jiffies_msec;
+	}
+}
+#else
+static void fsp_packet_debug(unsigned char packet[])
+{
+}
+#endif
+
+static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
+{
+	struct input_dev *dev = psmouse->dev;
+	struct fsp_data *ad = psmouse->private;
+	unsigned char *packet = psmouse->packet;
+	unsigned char button_status = 0, lscroll = 0, rscroll = 0;
+	int rel_x, rel_y;
+
+	if (psmouse->pktcnt < 4)
+		return PSMOUSE_GOOD_DATA;
+
+	/*
+	 * Full packet accumulated, process it
+	 */
+
+	switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) {
+	case FSP_PKT_TYPE_ABS:
+		dev_warn(&psmouse->ps2dev.serio->dev,
+			 "Unexpected absolute mode packet, ignored.\n");
+		break;
+
+	case FSP_PKT_TYPE_NORMAL_OPC:
+		/* on-pad click, filter it if necessary */
+		if ((ad->flags & FSPDRV_FLAG_EN_OPC) != FSPDRV_FLAG_EN_OPC)
+			packet[0] &= ~BIT(0);
+		/* fall through */
+
+	case FSP_PKT_TYPE_NORMAL:
+		/* normal packet */
+		/* special packet data translation from on-pad packets */
+		if (packet[3] != 0) {
+			if (packet[3] & BIT(0))
+				button_status |= 0x01;	/* wheel down */
+			if (packet[3] & BIT(1))
+				button_status |= 0x0f;	/* wheel up */
+			if (packet[3] & BIT(2))
+				button_status |= BIT(5);/* horizontal left */
+			if (packet[3] & BIT(3))
+				button_status |= BIT(4);/* horizontal right */
+			/* push back to packet queue */
+			if (button_status != 0)
+				packet[3] = button_status;
+			rscroll = (packet[3] >> 4) & 1;
+			lscroll = (packet[3] >> 5) & 1;
+		}
+		/*
+		 * Processing wheel up/down and extra button events
+		 */
+		input_report_rel(dev, REL_WHEEL,
+				 (int)(packet[3] & 8) - (int)(packet[3] & 7));
+		input_report_rel(dev, REL_HWHEEL, lscroll - rscroll);
+		input_report_key(dev, BTN_BACK, lscroll);
+		input_report_key(dev, BTN_FORWARD, rscroll);
+
+		/*
+		 * Standard PS/2 Mouse
+		 */
+		input_report_key(dev, BTN_LEFT, packet[0] & 1);
+		input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
+		input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
+
+		rel_x = packet[1] ? (int)packet[1] - (int)((packet[0] << 4) & 0x100) : 0;
+		rel_y = packet[2] ? (int)((packet[0] << 3) & 0x100) - (int)packet[2] : 0;
+
+		input_report_rel(dev, REL_X, rel_x);
+		input_report_rel(dev, REL_Y, rel_y);
+		break;
+	}
+
+	input_sync(dev);
+
+	fsp_packet_debug(packet);
+
+	return PSMOUSE_FULL_PACKET;
+}
+
+static int fsp_activate_protocol(struct psmouse *psmouse)
+{
+	struct fsp_data *pad = psmouse->private;
+	struct ps2dev *ps2dev = &psmouse->ps2dev;
+	unsigned char param[2];
+	int val;
+
+	/*
+	 * Standard procedure to enter FSP Intellimouse mode
+	 * (scrolling wheel, 4th and 5th buttons)
+	 */
+	param[0] = 200;
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+	param[0] = 200;
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+	param[0] =  80;
+	ps2_command(ps2dev, param, PSMOUSE_CMD_SETRATE);
+
+	ps2_command(ps2dev, param, PSMOUSE_CMD_GETID);
+	if (param[0] != 0x04) {
+		dev_err(&psmouse->ps2dev.serio->dev,
+			"Unable to enable 4 bytes packet format.\n");
+		return -EIO;
+	}
+
+	if (fsp_reg_read(psmouse, FSP_REG_SYSCTL5, &val)) {
+		dev_err(&psmouse->ps2dev.serio->dev,
+			"Unable to read SYSCTL5 register.\n");
+		return -EIO;
+	}
+
+	val &= ~(FSP_BIT_EN_MSID7 | FSP_BIT_EN_MSID8 | FSP_BIT_EN_AUTO_MSID8);
+	/* Ensure we are not in absolute mode */
+	val &= ~FSP_BIT_EN_PKT_G0;
+	if (pad->buttons == 0x06) {
+		/* Left/Middle/Right & Scroll Up/Down/Right/Left */
+		val |= FSP_BIT_EN_MSID6;
+	}
+
+	if (fsp_reg_write(psmouse, FSP_REG_SYSCTL5, val)) {
+		dev_err(&psmouse->ps2dev.serio->dev,
+			"Unable to set up required mode bits.\n");
+		return -EIO;
+	}
+
+	/*
+	 * Enable OPC tags such that driver can tell the difference between
+	 * on-pad and real button click
+	 */
+	if (fsp_opc_tag_enable(psmouse, true))
+		dev_warn(&psmouse->ps2dev.serio->dev,
+			 "Failed to enable OPC tag mode.\n");
+
+	/* Enable on-pad vertical and horizontal scrolling */
+	fsp_onpad_vscr(psmouse, true);
+	fsp_onpad_hscr(psmouse, true);
+
+	return 0;
+}
+
+int fsp_detect(struct psmouse *psmouse, bool set_properties)
+{
+	int id;
+
+	if (fsp_reg_read(psmouse, FSP_REG_DEVICE_ID, &id))
+		return -EIO;
+
+	if (id != 0x01)
+		return -ENODEV;
+
+	if (set_properties) {
+		psmouse->vendor = "Sentelic";
+		psmouse->name = "FingerSensingPad";
+	}
+
+	return 0;
+}
+
+static void fsp_reset(struct psmouse *psmouse)
+{
+	fsp_opc_tag_enable(psmouse, false);
+	fsp_onpad_vscr(psmouse, false);
+	fsp_onpad_hscr(psmouse, false);
+}
+
+static void fsp_disconnect(struct psmouse *psmouse)
+{
+	sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj,
+			   &fsp_attribute_group);
+
+	fsp_reset(psmouse);
+	kfree(psmouse->private);
+}
+
+static int fsp_reconnect(struct psmouse *psmouse)
+{
+	int version;
+
+	if (fsp_detect(psmouse, 0))
+		return -ENODEV;
+
+	if (fsp_get_version(psmouse, &version))
+		return -ENODEV;
+
+	if (fsp_activate_protocol(psmouse))
+		return -EIO;
+
+	return 0;
+}
+
+int fsp_init(struct psmouse *psmouse)
+{
+	struct fsp_data *priv;
+	int ver, rev, buttons;
+	int error;
+
+	if (fsp_get_version(psmouse, &ver) ||
+	    fsp_get_revision(psmouse, &rev) ||
+	    fsp_get_buttons(psmouse, &buttons)) {
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO
+		"Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d\n",
+		ver >> 4, ver & 0x0F, rev, fsp_drv_ver, buttons & 7);
+
+	psmouse->private = priv = kzalloc(sizeof(struct fsp_data), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->ver = ver;
+	priv->rev = rev;
+	priv->buttons = buttons;
+
+	/* enable on-pad click by default */
+	priv->flags |= FSPDRV_FLAG_EN_OPC;
+
+	/* Set up various supported input event bits */
+	__set_bit(BTN_BACK, psmouse->dev->keybit);
+	__set_bit(BTN_FORWARD, psmouse->dev->keybit);
+	__set_bit(REL_WHEEL, psmouse->dev->relbit);
+	__set_bit(REL_HWHEEL, psmouse->dev->relbit);
+
+	psmouse->protocol_handler = fsp_process_byte;
+	psmouse->disconnect = fsp_disconnect;
+	psmouse->reconnect = fsp_reconnect;
+	psmouse->cleanup = fsp_reset;
+	psmouse->pktsize = 4;
+
+	/* set default packet output based on number of buttons we found */
+	error = fsp_activate_protocol(psmouse);
+	if (error)
+		goto err_out;
+
+	error = sysfs_create_group(&psmouse->ps2dev.serio->dev.kobj,
+				   &fsp_attribute_group);
+	if (error) {
+		dev_err(&psmouse->ps2dev.serio->dev,
+			"Failed to create sysfs attributes (%d)", error);
+		goto err_out;
+	}
+
+	return 0;
+
+ err_out:
+	kfree(psmouse->private);
+	psmouse->private = NULL;
+	return error;
+}
diff --git a/drivers/input/mouse/sentelic.h b/drivers/input/mouse/sentelic.h
new file mode 100644
index 0000000..ed1395a
--- /dev/null
+++ b/drivers/input/mouse/sentelic.h
@@ -0,0 +1,98 @@
+/*-
+ * Finger Sensing Pad PS/2 mouse driver.
+ *
+ * Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
+ * Copyright (C) 2005-2009 Tai-hwa Liang, Sentelic Corporation.
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef	__SENTELIC_H
+#define	__SENTELIC_H
+
+/* Finger-sensing Pad information registers */
+#define	FSP_REG_DEVICE_ID	0x00
+#define	FSP_REG_VERSION		0x01
+#define	FSP_REG_REVISION	0x04
+#define	FSP_REG_TMOD_STATUS1	0x0B
+#define	FSP_BIT_NO_ROTATION	BIT(3)
+#define	FSP_REG_PAGE_CTRL	0x0F
+
+/* Finger-sensing Pad control registers */
+#define	FSP_REG_SYSCTL1		0x10
+#define	FSP_BIT_EN_REG_CLK	BIT(5)
+#define	FSP_REG_OPC_QDOWN	0x31
+#define	FSP_BIT_EN_OPC_TAG	BIT(7)
+#define	FSP_REG_OPTZ_XLO	0x34
+#define	FSP_REG_OPTZ_XHI	0x35
+#define	FSP_REG_OPTZ_YLO	0x36
+#define	FSP_REG_OPTZ_YHI	0x37
+#define	FSP_REG_SYSCTL5		0x40
+#define	FSP_BIT_90_DEGREE	BIT(0)
+#define	FSP_BIT_EN_MSID6	BIT(1)
+#define	FSP_BIT_EN_MSID7	BIT(2)
+#define	FSP_BIT_EN_MSID8	BIT(3)
+#define	FSP_BIT_EN_AUTO_MSID8	BIT(5)
+#define	FSP_BIT_EN_PKT_G0	BIT(6)
+
+#define	FSP_REG_ONPAD_CTL	0x43
+#define	FSP_BIT_ONPAD_ENABLE	BIT(0)
+#define	FSP_BIT_ONPAD_FBBB	BIT(1)
+#define	FSP_BIT_FIX_VSCR	BIT(3)
+#define	FSP_BIT_FIX_HSCR	BIT(5)
+#define	FSP_BIT_DRAG_LOCK	BIT(6)
+
+/* Finger-sensing Pad packet formating related definitions */
+
+/* absolute packet type */
+#define	FSP_PKT_TYPE_NORMAL	(0x00)
+#define	FSP_PKT_TYPE_ABS	(0x01)
+#define	FSP_PKT_TYPE_NOTIFY	(0x02)
+#define	FSP_PKT_TYPE_NORMAL_OPC	(0x03)
+#define	FSP_PKT_TYPE_SHIFT	(6)
+
+#ifdef __KERNEL__
+
+struct fsp_data {
+	unsigned char	ver;		/* hardware version */
+	unsigned char	rev;		/* hardware revison */
+	unsigned char	buttons;	/* Number of buttons */
+	unsigned int	flags;
+#define	FSPDRV_FLAG_EN_OPC	(0x001)	/* enable on-pad clicking */
+
+	bool		vscroll;	/* Vertical scroll zone enabled */
+	bool		hscroll;	/* Horizontal scroll zone enabled */
+
+	unsigned char	last_reg;	/* Last register we requested read from */
+	unsigned char	last_val;
+};
+
+#ifdef CONFIG_MOUSE_PS2_SENTELIC
+extern int fsp_detect(struct psmouse *psmouse, bool set_properties);
+extern int fsp_init(struct psmouse *psmouse);
+#else
+inline int fsp_detect(struct psmouse *psmouse, bool set_properties)
+{
+	return -ENOSYS;
+}
+inline int fsp_init(struct psmouse *psmouse)
+{
+	return -ENOSYS;
+}
+#endif
+
+#endif	/* __KERNEL__ */
+
+#endif	/* !__SENTELIC_H */
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 19984bf..b66ff1a 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -60,7 +60,7 @@ static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
 	return 0;
 }
 
-int synaptics_detect(struct psmouse *psmouse, int set_properties)
+int synaptics_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
 	unsigned char param[4];
@@ -556,38 +556,38 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
 {
 	int i;
 
-	set_bit(EV_ABS, dev->evbit);
+	__set_bit(EV_ABS, dev->evbit);
 	input_set_abs_params(dev, ABS_X, XMIN_NOMINAL, XMAX_NOMINAL, 0, 0);
 	input_set_abs_params(dev, ABS_Y, YMIN_NOMINAL, YMAX_NOMINAL, 0, 0);
 	input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
-	set_bit(ABS_TOOL_WIDTH, dev->absbit);
+	__set_bit(ABS_TOOL_WIDTH, dev->absbit);
 
-	set_bit(EV_KEY, dev->evbit);
-	set_bit(BTN_TOUCH, dev->keybit);
-	set_bit(BTN_TOOL_FINGER, dev->keybit);
-	set_bit(BTN_LEFT, dev->keybit);
-	set_bit(BTN_RIGHT, dev->keybit);
+	__set_bit(EV_KEY, dev->evbit);
+	__set_bit(BTN_TOUCH, dev->keybit);
+	__set_bit(BTN_TOOL_FINGER, dev->keybit);
+	__set_bit(BTN_LEFT, dev->keybit);
+	__set_bit(BTN_RIGHT, dev->keybit);
 
 	if (SYN_CAP_MULTIFINGER(priv->capabilities)) {
-		set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
-		set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
+		__set_bit(BTN_TOOL_DOUBLETAP, dev->keybit);
+		__set_bit(BTN_TOOL_TRIPLETAP, dev->keybit);
 	}
 
 	if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities))
-		set_bit(BTN_MIDDLE, dev->keybit);
+		__set_bit(BTN_MIDDLE, dev->keybit);
 
 	if (SYN_CAP_FOUR_BUTTON(priv->capabilities) ||
 	    SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) {
-		set_bit(BTN_FORWARD, dev->keybit);
-		set_bit(BTN_BACK, dev->keybit);
+		__set_bit(BTN_FORWARD, dev->keybit);
+		__set_bit(BTN_BACK, dev->keybit);
 	}
 
 	for (i = 0; i < SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap); i++)
-		set_bit(BTN_0 + i, dev->keybit);
+		__set_bit(BTN_0 + i, dev->keybit);
 
-	clear_bit(EV_REL, dev->evbit);
-	clear_bit(REL_X, dev->relbit);
-	clear_bit(REL_Y, dev->relbit);
+	__clear_bit(EV_REL, dev->evbit);
+	__clear_bit(REL_X, dev->relbit);
+	__clear_bit(REL_Y, dev->relbit);
 
 	dev->absres[ABS_X] = priv->x_res;
 	dev->absres[ABS_Y] = priv->y_res;
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 3023821..871f6fe 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -105,7 +105,7 @@ struct synaptics_data {
 	int scroll;
 };
 
-int synaptics_detect(struct psmouse *psmouse, int set_properties);
+int synaptics_detect(struct psmouse *psmouse, bool set_properties);
 int synaptics_init(struct psmouse *psmouse);
 void synaptics_reset(struct psmouse *psmouse);
 
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 3fadb2a..0308a0f 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -67,7 +67,7 @@ static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
 	return PSMOUSE_FULL_PACKET;
 }
 
-int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
+int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct input_dev *dev = psmouse->dev;
 	unsigned char param[3];
@@ -86,7 +86,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
 
 	if (set_properties) {
 		dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
-		set_bit(BTN_TOUCH, dev->keybit);
+		__set_bit(BTN_TOUCH, dev->keybit);
 		input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
 		input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
 
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h
index 8a0dd35..2efe9ea 100644
--- a/drivers/input/mouse/touchkit_ps2.h
+++ b/drivers/input/mouse/touchkit_ps2.h
@@ -13,10 +13,10 @@
 #define _TOUCHKIT_PS2_H
 
 #ifdef CONFIG_MOUSE_PS2_TOUCHKIT
-int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties);
+int touchkit_ps2_detect(struct psmouse *psmouse, bool set_properties);
 #else
 static inline int touchkit_ps2_detect(struct psmouse *psmouse,
-				      int set_properties)
+				      bool set_properties)
 {
 	return -ENOSYS;
 }
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index e68c814..e354362 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -282,7 +282,7 @@ static int trackpoint_reconnect(struct psmouse *psmouse)
 	return 0;
 }
 
-int trackpoint_detect(struct psmouse *psmouse, int set_properties)
+int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct trackpoint_data *priv;
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
index c10a6e7..e558a70 100644
--- a/drivers/input/mouse/trackpoint.h
+++ b/drivers/input/mouse/trackpoint.h
@@ -143,9 +143,9 @@ struct trackpoint_data
 };
 
 #ifdef CONFIG_MOUSE_PS2_TRACKPOINT
-int trackpoint_detect(struct psmouse *psmouse, int set_properties);
+int trackpoint_detect(struct psmouse *psmouse, bool set_properties);
 #else
-inline int trackpoint_detect(struct psmouse *psmouse, int set_properties)
+inline int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 {
 	return -ENOSYS;
 }
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index 404eedd..7011144 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -384,11 +384,11 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
 	printk (KERN_NOTICE "%s on %s: Forceing standard packet format, "
 			"incremental streaming mode and 72 samples/sec\n",
 			mouse->name, mouse->phys);
-	mouse->serio->write (mouse->serio, 'S');	/* Standard format */
+	serio_write (mouse->serio, 'S');	/* Standard format */
 	mdelay (50);
-	mouse->serio->write (mouse->serio, 'R');	/* Incremental */
+	serio_write (mouse->serio, 'R');	/* Incremental */
 	mdelay (50);
-	mouse->serio->write (mouse->serio, 'L');	/* 72 samples/sec */
+	serio_write (mouse->serio, 'L');	/* 72 samples/sec */
 }
 
 static void
@@ -532,7 +532,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
 	 * Request selftest. Standard packet format and differential
 	 * mode will be requested after the device ID'ed successfully.
 	 */
-	serio->write (serio, 'T'); /* Test */
+	serio_write (serio, 'T'); /* Test */
 
 	err = input_register_device (input_dev);
 	if (err)
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c
index 41fda8c..a6fb7a3 100644
--- a/drivers/input/serio/at32psif.c
+++ b/drivers/input/serio/at32psif.c
@@ -231,7 +231,7 @@ static int __init psif_probe(struct platform_device *pdev)
 		goto out_free_io;
 	}
 
-	psif->regs = ioremap(regs->start, regs->end - regs->start + 1);
+	psif->regs = ioremap(regs->start, resource_size(regs));
 	if (!psif->regs) {
 		ret = -ENOMEM;
 		dev_dbg(&pdev->dev, "could not map I/O memory\n");
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index ccbf23e..a39bc4e 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -457,6 +457,34 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
 	},
 	{ }
 };
+
+static struct dmi_system_id __initdata i8042_dmi_laptop_table[] = {
+	{
+		.ident = "Portable",
+		.matches = {
+			DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
+		},
+	},
+	{
+		.ident = "Laptop",
+		.matches = {
+			DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */
+		},
+	},
+	{
+		.ident = "Notebook",
+		.matches = {
+			DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
+		},
+	},
+	{
+		.ident = "Sub-Notebook",
+		.matches = {
+			DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */
+		},
+	},
+	{ }
+};
 #endif
 
 /*
@@ -530,9 +558,9 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = {
 #ifdef CONFIG_PNP
 #include <linux/pnp.h>
 
-static int i8042_pnp_kbd_registered;
+static bool i8042_pnp_kbd_registered;
 static unsigned int i8042_pnp_kbd_devices;
-static int i8042_pnp_aux_registered;
+static bool i8042_pnp_aux_registered;
 static unsigned int i8042_pnp_aux_devices;
 
 static int i8042_pnp_command_reg;
@@ -620,12 +648,12 @@ static struct pnp_driver i8042_pnp_aux_driver = {
 static void i8042_pnp_exit(void)
 {
 	if (i8042_pnp_kbd_registered) {
-		i8042_pnp_kbd_registered = 0;
+		i8042_pnp_kbd_registered = false;
 		pnp_unregister_driver(&i8042_pnp_kbd_driver);
 	}
 
 	if (i8042_pnp_aux_registered) {
-		i8042_pnp_aux_registered = 0;
+		i8042_pnp_aux_registered = false;
 		pnp_unregister_driver(&i8042_pnp_aux_driver);
 	}
 }
@@ -633,12 +661,12 @@ static void i8042_pnp_exit(void)
 static int __init i8042_pnp_init(void)
 {
 	char kbd_irq_str[4] = { 0 }, aux_irq_str[4] = { 0 };
-	int pnp_data_busted = 0;
+	int pnp_data_busted = false;
 	int err;
 
 #ifdef CONFIG_X86
 	if (dmi_check_system(i8042_dmi_nopnp_table))
-		i8042_nopnp = 1;
+		i8042_nopnp = true;
 #endif
 
 	if (i8042_nopnp) {
@@ -648,11 +676,11 @@ static int __init i8042_pnp_init(void)
 
 	err = pnp_register_driver(&i8042_pnp_kbd_driver);
 	if (!err)
-		i8042_pnp_kbd_registered = 1;
+		i8042_pnp_kbd_registered = true;
 
 	err = pnp_register_driver(&i8042_pnp_aux_driver);
 	if (!err)
-		i8042_pnp_aux_registered = 1;
+		i8042_pnp_aux_registered = true;
 
 	if (!i8042_pnp_kbd_devices && !i8042_pnp_aux_devices) {
 		i8042_pnp_exit();
@@ -680,9 +708,9 @@ static int __init i8042_pnp_init(void)
 
 #if defined(__ia64__)
 	if (!i8042_pnp_kbd_devices)
-		i8042_nokbd = 1;
+		i8042_nokbd = true;
 	if (!i8042_pnp_aux_devices)
-		i8042_noaux = 1;
+		i8042_noaux = true;
 #endif
 
 	if (((i8042_pnp_data_reg & ~0xf) == (i8042_data_reg & ~0xf) &&
@@ -693,7 +721,7 @@ static int __init i8042_pnp_init(void)
 			"using default %#x\n",
 			i8042_pnp_data_reg, i8042_data_reg);
 		i8042_pnp_data_reg = i8042_data_reg;
-		pnp_data_busted = 1;
+		pnp_data_busted = true;
 	}
 
 	if (((i8042_pnp_command_reg & ~0xf) == (i8042_command_reg & ~0xf) &&
@@ -704,7 +732,7 @@ static int __init i8042_pnp_init(void)
 			"using default %#x\n",
 			i8042_pnp_command_reg, i8042_command_reg);
 		i8042_pnp_command_reg = i8042_command_reg;
-		pnp_data_busted = 1;
+		pnp_data_busted = true;
 	}
 
 	if (!i8042_nokbd && !i8042_pnp_kbd_irq) {
@@ -712,7 +740,7 @@ static int __init i8042_pnp_init(void)
 			"PNP: PS/2 controller doesn't have KBD irq; "
 			"using default %d\n", i8042_kbd_irq);
 		i8042_pnp_kbd_irq = i8042_kbd_irq;
-		pnp_data_busted = 1;
+		pnp_data_busted = true;
 	}
 
 	if (!i8042_noaux && !i8042_pnp_aux_irq) {
@@ -721,7 +749,7 @@ static int __init i8042_pnp_init(void)
 				"PNP: PS/2 appears to have AUX port disabled, "
 				"if this is incorrect please boot with "
 				"i8042.nopnp\n");
-			i8042_noaux = 1;
+			i8042_noaux = true;
 		} else {
 			printk(KERN_WARNING
 				"PNP: PS/2 controller doesn't have AUX irq; "
@@ -735,6 +763,11 @@ static int __init i8042_pnp_init(void)
 	i8042_kbd_irq = i8042_pnp_kbd_irq;
 	i8042_aux_irq = i8042_pnp_aux_irq;
 
+#ifdef CONFIG_X86
+	i8042_bypass_aux_irq_test = !pnp_data_busted &&
+				    dmi_check_system(i8042_dmi_laptop_table);
+#endif
+
 	return 0;
 }
 
@@ -763,21 +796,21 @@ static int __init i8042_platform_init(void)
 		return retval;
 
 #if defined(__ia64__)
-        i8042_reset = 1;
+        i8042_reset = true;
 #endif
 
 #ifdef CONFIG_X86
 	if (dmi_check_system(i8042_dmi_reset_table))
-		i8042_reset = 1;
+		i8042_reset = true;
 
 	if (dmi_check_system(i8042_dmi_noloop_table))
-		i8042_noloop = 1;
+		i8042_noloop = true;
 
 	if (dmi_check_system(i8042_dmi_nomux_table))
-		i8042_nomux = 1;
+		i8042_nomux = true;
 
 	if (dmi_check_system(i8042_dmi_dritek_table))
-		i8042_dritek = 1;
+		i8042_dritek = true;
 #endif /* CONFIG_X86 */
 
 	return retval;
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 582245c..eb3ff94 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -28,35 +28,35 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("i8042 keyboard and mouse controller driver");
 MODULE_LICENSE("GPL");
 
-static unsigned int i8042_nokbd;
+static bool i8042_nokbd;
 module_param_named(nokbd, i8042_nokbd, bool, 0);
 MODULE_PARM_DESC(nokbd, "Do not probe or use KBD port.");
 
-static unsigned int i8042_noaux;
+static bool i8042_noaux;
 module_param_named(noaux, i8042_noaux, bool, 0);
 MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
 
-static unsigned int i8042_nomux;
+static bool i8042_nomux;
 module_param_named(nomux, i8042_nomux, bool, 0);
 MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
 
-static unsigned int i8042_unlock;
+static bool i8042_unlock;
 module_param_named(unlock, i8042_unlock, bool, 0);
 MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
 
-static unsigned int i8042_reset;
+static bool i8042_reset;
 module_param_named(reset, i8042_reset, bool, 0);
 MODULE_PARM_DESC(reset, "Reset controller during init and cleanup.");
 
-static unsigned int i8042_direct;
+static bool i8042_direct;
 module_param_named(direct, i8042_direct, bool, 0);
 MODULE_PARM_DESC(direct, "Put keyboard port into non-translated mode.");
 
-static unsigned int i8042_dumbkbd;
+static bool i8042_dumbkbd;
 module_param_named(dumbkbd, i8042_dumbkbd, bool, 0);
 MODULE_PARM_DESC(dumbkbd, "Pretend that controller can only read data from keyboard");
 
-static unsigned int i8042_noloop;
+static bool i8042_noloop;
 module_param_named(noloop, i8042_noloop, bool, 0);
 MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port");
 
@@ -65,24 +65,26 @@ module_param_named(panicblink, i8042_blink_frequency, uint, 0600);
 MODULE_PARM_DESC(panicblink, "Frequency with which keyboard LEDs should blink when kernel panics");
 
 #ifdef CONFIG_X86
-static unsigned int i8042_dritek;
+static bool i8042_dritek;
 module_param_named(dritek, i8042_dritek, bool, 0);
 MODULE_PARM_DESC(dritek, "Force enable the Dritek keyboard extension");
 #endif
 
 #ifdef CONFIG_PNP
-static int i8042_nopnp;
+static bool i8042_nopnp;
 module_param_named(nopnp, i8042_nopnp, bool, 0);
 MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
 #endif
 
 #define DEBUG
 #ifdef DEBUG
-static int i8042_debug;
+static bool i8042_debug;
 module_param_named(debug, i8042_debug, bool, 0600);
 MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off");
 #endif
 
+static bool i8042_bypass_aux_irq_test;
+
 #include "i8042.h"
 
 static DEFINE_SPINLOCK(i8042_lock);
@@ -90,7 +92,7 @@ static DEFINE_SPINLOCK(i8042_lock);
 struct i8042_port {
 	struct serio *serio;
 	int irq;
-	unsigned char exists;
+	bool exists;
 	signed char mux;
 };
 
@@ -103,9 +105,9 @@ static struct i8042_port i8042_ports[I8042_NUM_PORTS];
 
 static unsigned char i8042_initial_ctr;
 static unsigned char i8042_ctr;
-static unsigned char i8042_mux_present;
-static unsigned char i8042_kbd_irq_registered;
-static unsigned char i8042_aux_irq_registered;
+static bool i8042_mux_present;
+static bool i8042_kbd_irq_registered;
+static bool i8042_aux_irq_registered;
 static unsigned char i8042_suppress_kbd_ack;
 static struct platform_device *i8042_platform_device;
 
@@ -262,6 +264,49 @@ static int i8042_aux_write(struct serio *serio, unsigned char c)
 					I8042_CMD_MUX_SEND + port->mux);
 }
 
+
+/*
+ * i8042_aux_close attempts to clear AUX or KBD port state by disabling
+ * and then re-enabling it.
+ */
+
+static void i8042_port_close(struct serio *serio)
+{
+	int irq_bit;
+	int disable_bit;
+	const char *port_name;
+
+	if (serio == i8042_ports[I8042_AUX_PORT_NO].serio) {
+		irq_bit = I8042_CTR_AUXINT;
+		disable_bit = I8042_CTR_AUXDIS;
+		port_name = "AUX";
+	} else {
+		irq_bit = I8042_CTR_KBDINT;
+		disable_bit = I8042_CTR_KBDDIS;
+		port_name = "KBD";
+	}
+
+	i8042_ctr &= ~irq_bit;
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+		printk(KERN_WARNING
+			"i8042.c: Can't write CTR while closing %s port.\n",
+			port_name);
+
+	udelay(50);
+
+	i8042_ctr &= ~disable_bit;
+	i8042_ctr |= irq_bit;
+	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR))
+		printk(KERN_ERR "i8042.c: Can't reactivate %s port.\n",
+			port_name);
+
+	/*
+	 * See if there is any data appeared while we were messing with
+	 * port state.
+	 */
+	i8042_interrupt(0, NULL);
+}
+
 /*
  * i8042_start() is called by serio core when port is about to finish
  * registering. It will mark port as existing so i8042_interrupt can
@@ -271,7 +316,7 @@ static int i8042_start(struct serio *serio)
 {
 	struct i8042_port *port = serio->port_data;
 
-	port->exists = 1;
+	port->exists = true;
 	mb();
 	return 0;
 }
@@ -285,7 +330,7 @@ static void i8042_stop(struct serio *serio)
 {
 	struct i8042_port *port = serio->port_data;
 
-	port->exists = 0;
+	port->exists = false;
 
 	/*
 	 * We synchronize with both AUX and KBD IRQs because there is
@@ -391,7 +436,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
 }
 
 /*
- * i8042_enable_kbd_port enables keybaord port on chip
+ * i8042_enable_kbd_port enables keyboard port on chip
  */
 
 static int i8042_enable_kbd_port(void)
@@ -447,14 +492,15 @@ static int i8042_enable_mux_ports(void)
 }
 
 /*
- * i8042_set_mux_mode checks whether the controller has an active
- * multiplexor and puts the chip into Multiplexed (1) or Legacy (0) mode.
+ * i8042_set_mux_mode checks whether the controller has an
+ * active multiplexor and puts the chip into Multiplexed (true)
+ * or Legacy (false) mode.
  */
 
-static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
+static int i8042_set_mux_mode(bool multiplex, unsigned char *mux_version)
 {
 
-	unsigned char param;
+	unsigned char param, val;
 /*
  * Get rid of bytes in the queue.
  */
@@ -466,14 +512,21 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
  * mouse interface, the last should be version.
  */
 
-	param = 0xf0;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != 0xf0)
+	param = val = 0xf0;
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != val)
 		return -1;
-	param = mode ? 0x56 : 0xf6;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6))
+	param = val = multiplex ? 0x56 : 0xf6;
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param != val)
 		return -1;
-	param = mode ? 0xa4 : 0xa5;
-	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5))
+	param = val = multiplex ? 0xa4 : 0xa5;
+	if (i8042_command(&param, I8042_CMD_AUX_LOOP) || param == val)
+		return -1;
+
+/*
+ * Workaround for interference with USB Legacy emulation
+ * that causes a v10.12 MUX to be found.
+ */
+	if (param == 0xac)
 		return -1;
 
 	if (mux_version)
@@ -488,18 +541,11 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version)
  * LCS/Telegraphics.
  */
 
-static int __devinit i8042_check_mux(void)
+static int __init i8042_check_mux(void)
 {
 	unsigned char mux_version;
 
-	if (i8042_set_mux_mode(1, &mux_version))
-		return -1;
-
-/*
- * Workaround for interference with USB Legacy emulation
- * that causes a v10.12 MUX to be found.
- */
-	if (mux_version == 0xAC)
+	if (i8042_set_mux_mode(true, &mux_version))
 		return -1;
 
 	printk(KERN_INFO "i8042.c: Detected active multiplexing controller, rev %d.%d.\n",
@@ -516,7 +562,7 @@ static int __devinit i8042_check_mux(void)
 		return -EIO;
 	}
 
-	i8042_mux_present = 1;
+	i8042_mux_present = true;
 
 	return 0;
 }
@@ -524,10 +570,10 @@ static int __devinit i8042_check_mux(void)
 /*
  * The following is used to test AUX IRQ delivery.
  */
-static struct completion i8042_aux_irq_delivered __devinitdata;
-static int i8042_irq_being_tested __devinitdata;
+static struct completion i8042_aux_irq_delivered __initdata;
+static bool i8042_irq_being_tested __initdata;
 
-static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id)
+static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
 {
 	unsigned long flags;
 	unsigned char str, data;
@@ -552,7 +598,7 @@ static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id)
  * verifies success by readinng CTR. Used when testing for presence of AUX
  * port.
  */
-static int __devinit i8042_toggle_aux(int on)
+static int __init i8042_toggle_aux(bool on)
 {
 	unsigned char param;
 	int i;
@@ -580,11 +626,11 @@ static int __devinit i8042_toggle_aux(int on)
  * the presence of an AUX interface.
  */
 
-static int __devinit i8042_check_aux(void)
+static int __init i8042_check_aux(void)
 {
 	int retval = -1;
-	int irq_registered = 0;
-	int aux_loop_broken = 0;
+	bool irq_registered = false;
+	bool aux_loop_broken = false;
 	unsigned long flags;
 	unsigned char param;
 
@@ -621,19 +667,19 @@ static int __devinit i8042_check_aux(void)
  * mark it as broken
  */
 		if (!retval)
-			aux_loop_broken = 1;
+			aux_loop_broken = true;
 	}
 
 /*
  * Bit assignment test - filters out PS/2 i8042's in AT mode
  */
 
-	if (i8042_toggle_aux(0)) {
+	if (i8042_toggle_aux(false)) {
 		printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n");
 		printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n");
 	}
 
-	if (i8042_toggle_aux(1))
+	if (i8042_toggle_aux(true))
 		return -1;
 
 /*
@@ -641,7 +687,7 @@ static int __devinit i8042_check_aux(void)
  * used it for a PCI card or somethig else.
  */
 
-	if (i8042_noloop || aux_loop_broken) {
+	if (i8042_noloop || i8042_bypass_aux_irq_test || aux_loop_broken) {
 /*
  * Without LOOP command we can't test AUX IRQ delivery. Assume the port
  * is working and hope we are right.
@@ -654,7 +700,7 @@ static int __devinit i8042_check_aux(void)
 			"i8042", i8042_platform_device))
 		goto out;
 
-	irq_registered = 1;
+	irq_registered = true;
 
 	if (i8042_enable_aux_port())
 		goto out;
@@ -662,7 +708,7 @@ static int __devinit i8042_check_aux(void)
 	spin_lock_irqsave(&i8042_lock, flags);
 
 	init_completion(&i8042_aux_irq_delivered);
-	i8042_irq_being_tested = 1;
+	i8042_irq_being_tested = true;
 
 	param = 0xa5;
 	retval = __i8042_command(&param, I8042_CMD_AUX_LOOP & 0xf0ff);
@@ -799,7 +845,7 @@ static int i8042_controller_init(void)
  */
 
 	if (~i8042_ctr & I8042_CTR_XLATE)
-		i8042_direct = 1;
+		i8042_direct = true;
 
 /*
  * Set nontranslated mode for the kbd interface if requested by an option.
@@ -839,12 +885,15 @@ static void i8042_controller_reset(void)
 	i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS;
 	i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT);
 
+	if (i8042_command(&i8042_initial_ctr, I8042_CMD_CTL_WCTR))
+		printk(KERN_WARNING "i8042.c: Can't write CTR while resetting.\n");
+
 /*
  * Disable MUX mode if present.
  */
 
 	if (i8042_mux_present)
-		i8042_set_mux_mode(0, NULL);
+		i8042_set_mux_mode(false, NULL);
 
 /*
  * Reset the controller if requested.
@@ -923,41 +972,27 @@ static void i8042_dritek_enable(void)
 
 #ifdef CONFIG_PM
 
-static bool i8042_suspended;
-
 /*
- * Here we try to restore the original BIOS settings. We only want to
- * do that once, when we really suspend, not when we taking memory
- * snapshot for swsusp (in this case we'll perform required cleanup
- * as part of shutdown process).
+ * Here we try to restore the original BIOS settings to avoid
+ * upsetting it.
  */
 
-static int i8042_suspend(struct platform_device *dev, pm_message_t state)
+static int i8042_pm_reset(struct device *dev)
 {
-	if (!i8042_suspended && state.event == PM_EVENT_SUSPEND)
-		i8042_controller_reset();
-
-	i8042_suspended = state.event == PM_EVENT_SUSPEND ||
-			  state.event == PM_EVENT_FREEZE;
+	i8042_controller_reset();
 
 	return 0;
 }
 
-
 /*
- * Here we try to reset everything back to a state in which suspended
+ * Here we try to reset everything back to a state we had
+ * before suspending.
  */
 
-static int i8042_resume(struct platform_device *dev)
+static int i8042_pm_restore(struct device *dev)
 {
 	int error;
 
-/*
- * Do not bother with restoring state if we haven't suspened yet
- */
-	if (!i8042_suspended)
-		return 0;
-
 	error = i8042_controller_check();
 	if (error)
 		return error;
@@ -991,7 +1026,7 @@ static int i8042_resume(struct platform_device *dev)
 #endif
 
 	if (i8042_mux_present) {
-		if (i8042_set_mux_mode(1, NULL) || i8042_enable_mux_ports())
+		if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports())
 			printk(KERN_WARNING
 				"i8042: failed to resume active multiplexor, "
 				"mouse won't work.\n");
@@ -1001,11 +1036,18 @@ static int i8042_resume(struct platform_device *dev)
 	if (i8042_ports[I8042_KBD_PORT_NO].serio)
 		i8042_enable_kbd_port();
 
-	i8042_suspended = false;
 	i8042_interrupt(0, NULL);
 
 	return 0;
 }
+
+static const struct dev_pm_ops i8042_pm_ops = {
+	.suspend	= i8042_pm_reset,
+	.resume		= i8042_pm_restore,
+	.poweroff	= i8042_pm_reset,
+	.restore	= i8042_pm_restore,
+};
+
 #endif /* CONFIG_PM */
 
 /*
@@ -1018,7 +1060,7 @@ static void i8042_shutdown(struct platform_device *dev)
 	i8042_controller_reset();
 }
 
-static int __devinit i8042_create_kbd_port(void)
+static int __init i8042_create_kbd_port(void)
 {
 	struct serio *serio;
 	struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
@@ -1031,6 +1073,7 @@ static int __devinit i8042_create_kbd_port(void)
 	serio->write		= i8042_dumbkbd ? NULL : i8042_kbd_write;
 	serio->start		= i8042_start;
 	serio->stop		= i8042_stop;
+	serio->close		= i8042_port_close;
 	serio->port_data	= port;
 	serio->dev.parent	= &i8042_platform_device->dev;
 	strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name));
@@ -1042,7 +1085,7 @@ static int __devinit i8042_create_kbd_port(void)
 	return 0;
 }
 
-static int __devinit i8042_create_aux_port(int idx)
+static int __init i8042_create_aux_port(int idx)
 {
 	struct serio *serio;
 	int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
@@ -1061,6 +1104,7 @@ static int __devinit i8042_create_aux_port(int idx)
 	if (idx < 0) {
 		strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name));
 		strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys));
+		serio->close = i8042_port_close;
 	} else {
 		snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx);
 		snprintf(serio->phys, sizeof(serio->phys), I8042_MUX_PHYS_DESC, idx + 1);
@@ -1073,13 +1117,13 @@ static int __devinit i8042_create_aux_port(int idx)
 	return 0;
 }
 
-static void __devinit i8042_free_kbd_port(void)
+static void __init i8042_free_kbd_port(void)
 {
 	kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
 	i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
 }
 
-static void __devinit i8042_free_aux_ports(void)
+static void __init i8042_free_aux_ports(void)
 {
 	int i;
 
@@ -1089,7 +1133,7 @@ static void __devinit i8042_free_aux_ports(void)
 	}
 }
 
-static void __devinit i8042_register_ports(void)
+static void __init i8042_register_ports(void)
 {
 	int i;
 
@@ -1124,10 +1168,10 @@ static void i8042_free_irqs(void)
 	if (i8042_kbd_irq_registered)
 		free_irq(I8042_KBD_IRQ, i8042_platform_device);
 
-	i8042_aux_irq_registered = i8042_kbd_irq_registered = 0;
+	i8042_aux_irq_registered = i8042_kbd_irq_registered = false;
 }
 
-static int __devinit i8042_setup_aux(void)
+static int __init i8042_setup_aux(void)
 {
 	int (*aux_enable)(void);
 	int error;
@@ -1158,7 +1202,7 @@ static int __devinit i8042_setup_aux(void)
 	if (aux_enable())
 		goto err_free_irq;
 
-	i8042_aux_irq_registered = 1;
+	i8042_aux_irq_registered = true;
 	return 0;
 
  err_free_irq:
@@ -1168,7 +1212,7 @@ static int __devinit i8042_setup_aux(void)
 	return error;
 }
 
-static int __devinit i8042_setup_kbd(void)
+static int __init i8042_setup_kbd(void)
 {
 	int error;
 
@@ -1185,7 +1229,7 @@ static int __devinit i8042_setup_kbd(void)
 	if (error)
 		goto err_free_irq;
 
-	i8042_kbd_irq_registered = 1;
+	i8042_kbd_irq_registered = true;
 	return 0;
 
  err_free_irq:
@@ -1195,7 +1239,7 @@ static int __devinit i8042_setup_kbd(void)
 	return error;
 }
 
-static int __devinit i8042_probe(struct platform_device *dev)
+static int __init i8042_probe(struct platform_device *dev)
 {
 	int error;
 
@@ -1251,14 +1295,12 @@ static struct platform_driver i8042_driver = {
 	.driver		= {
 		.name	= "i8042",
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &i8042_pm_ops,
+#endif
 	},
-	.probe		= i8042_probe,
 	.remove		= __devexit_p(i8042_remove),
 	.shutdown	= i8042_shutdown,
-#ifdef CONFIG_PM
-	.suspend	= i8042_suspend,
-	.resume		= i8042_resume,
-#endif
 };
 
 static int __init i8042_init(void)
@@ -1275,28 +1317,28 @@ static int __init i8042_init(void)
 	if (err)
 		goto err_platform_exit;
 
-	err = platform_driver_register(&i8042_driver);
-	if (err)
-		goto err_platform_exit;
-
 	i8042_platform_device = platform_device_alloc("i8042", -1);
 	if (!i8042_platform_device) {
 		err = -ENOMEM;
-		goto err_unregister_driver;
+		goto err_platform_exit;
 	}
 
 	err = platform_device_add(i8042_platform_device);
 	if (err)
 		goto err_free_device;
 
+	err = platform_driver_probe(&i8042_driver, i8042_probe);
+	if (err)
+		goto err_del_device;
+
 	panic_blink = i8042_panic_blink;
 
 	return 0;
 
+ err_del_device:
+	platform_device_del(i8042_platform_device);
  err_free_device:
 	platform_device_put(i8042_platform_device);
- err_unregister_driver:
-	platform_driver_unregister(&i8042_driver);
  err_platform_exit:
 	i8042_platform_exit();
 
@@ -1305,8 +1347,8 @@ static int __init i8042_init(void)
 
 static void __exit i8042_exit(void)
 {
-	platform_device_unregister(i8042_platform_device);
 	platform_driver_unregister(&i8042_driver);
+	platform_device_unregister(i8042_platform_device);
 	i8042_platform_exit();
 
 	panic_blink = NULL;
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index be5bbbb..3a95b50 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -161,7 +161,7 @@ static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
  * ps2_command() can only be called from a process context
  */
 
-int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 {
 	int timeout;
 	int send = (command >> 12) & 0xf;
@@ -179,8 +179,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 		return -1;
 	}
 
-	mutex_lock(&ps2dev->cmd_mutex);
-
 	serio_pause_rx(ps2dev->serio);
 	ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
 	ps2dev->cmdcnt = receive;
@@ -231,7 +229,18 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
 	ps2dev->flags = 0;
 	serio_continue_rx(ps2dev->serio);
 
+	return rc;
+}
+EXPORT_SYMBOL(__ps2_command);
+
+int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
+{
+	int rc;
+
+	mutex_lock(&ps2dev->cmd_mutex);
+	rc = __ps2_command(ps2dev, param, command);
 	mutex_unlock(&ps2dev->cmd_mutex);
+
 	return rc;
 }
 EXPORT_SYMBOL(ps2_command);
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index d66f494..0236f0d 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -931,15 +931,11 @@ static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
 #endif /* CONFIG_HOTPLUG */
 
 #ifdef CONFIG_PM
-static int serio_suspend(struct device *dev, pm_message_t state)
+static int serio_suspend(struct device *dev)
 {
 	struct serio *serio = to_serio_port(dev);
 
-	if (!serio->suspended && state.event == PM_EVENT_SUSPEND)
-		serio_cleanup(serio);
-
-	serio->suspended = state.event == PM_EVENT_SUSPEND ||
-			   state.event == PM_EVENT_FREEZE;
+	serio_cleanup(serio);
 
 	return 0;
 }
@@ -952,13 +948,17 @@ static int serio_resume(struct device *dev)
 	 * Driver reconnect can take a while, so better let kseriod
 	 * deal with it.
 	 */
-	if (serio->suspended) {
-		serio->suspended = false;
-		serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
-	}
+	serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
 
 	return 0;
 }
+
+static const struct dev_pm_ops serio_pm_ops = {
+	.suspend	= serio_suspend,
+	.resume		= serio_resume,
+	.poweroff	= serio_suspend,
+	.restore	= serio_resume,
+};
 #endif /* CONFIG_PM */
 
 /* called from serio_driver->connect/disconnect methods under serio_mutex */
@@ -1015,8 +1015,7 @@ static struct bus_type serio_bus = {
 	.remove		= serio_driver_remove,
 	.shutdown	= serio_shutdown,
 #ifdef CONFIG_PM
-	.suspend	= serio_suspend,
-	.resume		= serio_resume,
+	.pm		= &serio_pm_ops,
 #endif
 };
 
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 72e2712..ab02d72 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -366,11 +366,11 @@ config TOUCHSCREEN_WM97XX_ATMEL
 	  be called atmel-wm97xx.
 
 config TOUCHSCREEN_WM97XX_MAINSTONE
-	tristate "WM97xx Mainstone accelerated touch"
+	tristate "WM97xx Mainstone/Palm accelerated touch"
 	depends on TOUCHSCREEN_WM97XX && ARCH_PXA
 	help
 	  Say Y here for support for streaming mode with WM97xx touchscreens
-	  on Mainstone systems.
+	  on Mainstone, Palm Tungsten T5, TX and LifeDrive systems.
 
 	  If unsure, say N.
 
@@ -406,6 +406,7 @@ config TOUCHSCREEN_USB_COMPOSITE
 	  - IRTOUCHSYSTEMS/UNITOP
 	  - IdealTEK URTC1000
 	  - GoTop Super_Q2/GogoPen/PenPower tablets
+	  - JASTEC USB Touch Controller/DigiTech DTR-02U
 
 	  Have a look at <http://linux.chapter7.ch/touchkit/> for
 	  a usage description and the required user-space stuff.
@@ -468,6 +469,16 @@ config TOUCHSCREEN_USB_GOTOP
 	bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
 	depends on TOUCHSCREEN_USB_COMPOSITE
 
+config TOUCHSCREEN_USB_JASTEC
+	default y
+	bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EMBEDDED
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
+config TOUCHSCREEN_USB_E2I
+	default y
+	bool "e2i Touchscreen controller (e.g. from Mimo 740)"
+	depends on TOUCHSCREEN_USB_COMPOSITE
+
 config TOUCHSCREEN_TOUCHIT213
 	tristate "Sahara TouchIT-213 touchscreen"
 	select SERIO
@@ -492,10 +503,20 @@ config TOUCHSCREEN_TSC2007
 
 config TOUCHSCREEN_W90X900
 	tristate "W90P910 touchscreen driver"
+	depends on HAVE_CLK
 	help
 	  Say Y here if you have a W90P910 based touchscreen.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called w90p910_ts.
 
+config TOUCHSCREEN_PCAP
+	tristate "Motorola PCAP touchscreen"
+	depends on EZX_PCAP
+	help
+	  Say Y here if you have a Motorola EZX telephone and
+	  want to enable support for the built-in touchscreen.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pcap_ts.
 endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 3e1c5e0..4599bf7 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -40,3 +40,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL)	+= atmel-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE)	+= mainstone-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE)	+= zylonite-wm97xx.o
 obj-$(CONFIG_TOUCHSCREEN_W90X900)	+= w90p910_ts.o
+obj-$(CONFIG_TOUCHSCREEN_PCAP)		+= pcap_ts.o
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index 055969e..9c7fce4 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -204,14 +204,14 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
 		goto err_free_dev;
 	}
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
+	if (!request_mem_region(res->start, resource_size(res),
 				"atmel tsadcc regs")) {
 		dev_err(&pdev->dev, "resources is unavailable.\n");
 		err = -EBUSY;
 		goto err_free_dev;
 	}
 
-	tsc_base = ioremap(res->start, res->end - res->start + 1);
+	tsc_base = ioremap(res->start, resource_size(res));
 	if (!tsc_base) {
 		dev_err(&pdev->dev, "failed to map registers.\n");
 		err = -ENOMEM;
@@ -286,7 +286,7 @@ err_free_irq:
 err_unmap_regs:
 	iounmap(tsc_base);
 err_release_mem:
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 err_free_dev:
 	input_free_device(ts_dev->input);
 err_free_mem:
@@ -305,7 +305,7 @@ static int __devexit atmel_tsadcc_remove(struct platform_device *pdev)
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	iounmap(tsc_base);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	clk_disable(ts_dev->clk);
 	clk_put(ts_dev->clk);
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 3ab9222..9029bd3 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -32,6 +32,7 @@
 #include <linux/i2c.h>
 #include <linux/timer.h>
 #include <linux/gpio.h>
+#include <linux/input/eeti_ts.h>
 
 static int flip_x;
 module_param(flip_x, bool, 0644);
@@ -46,7 +47,7 @@ struct eeti_ts_priv {
 	struct input_dev *input;
 	struct work_struct work;
 	struct mutex mutex;
-	int irq;
+	int irq, irq_active_high;
 };
 
 #define EETI_TS_BITDEPTH	(11)
@@ -58,6 +59,11 @@ struct eeti_ts_priv {
 #define REPORT_BIT_HAS_PRESSURE	(1 << 6)
 #define REPORT_RES_BITS(v)	(((v) >> 1) + EETI_TS_BITDEPTH)
 
+static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv)
+{
+	return gpio_get_value(irq_to_gpio(priv->irq)) == priv->irq_active_high;
+}
+
 static void eeti_ts_read(struct work_struct *work)
 {
 	char buf[6];
@@ -67,7 +73,7 @@ static void eeti_ts_read(struct work_struct *work)
 
 	mutex_lock(&priv->mutex);
 
-	while (!gpio_get_value(irq_to_gpio(priv->irq)) && --to)
+	while (eeti_ts_irq_active(priv) && --to)
 		i2c_master_recv(priv->client, buf, sizeof(buf));
 
 	if (!to) {
@@ -140,8 +146,10 @@ static void eeti_ts_close(struct input_dev *dev)
 static int __devinit eeti_ts_probe(struct i2c_client *client,
 				   const struct i2c_device_id *idp)
 {
+	struct eeti_ts_platform_data *pdata;
 	struct eeti_ts_priv *priv;
 	struct input_dev *input;
+	unsigned int irq_flags;
 	int err = -ENOMEM;
 
 	/* In contrast to what's described in the datasheet, there seems
@@ -180,6 +188,14 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
 	priv->input = input;
 	priv->irq = client->irq;
 
+	pdata = client->dev.platform_data;
+
+	if (pdata)
+		priv->irq_active_high = pdata->irq_active_high;
+
+	irq_flags = priv->irq_active_high ?
+		IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
+
 	INIT_WORK(&priv->work, eeti_ts_read);
 	i2c_set_clientdata(client, priv);
 	input_set_drvdata(input, priv);
@@ -188,7 +204,7 @@ static int __devinit eeti_ts_probe(struct i2c_client *client,
 	if (err)
 		goto err1;
 
-	err = request_irq(priv->irq, eeti_ts_isr, IRQF_TRIGGER_FALLING,
+	err = request_irq(priv->irq, eeti_ts_isr, irq_flags,
 			  client->name, priv);
 	if (err) {
 		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index 4d3139e..b4d7f63 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -148,9 +148,10 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
 	struct h3600_dev *ts = input_get_drvdata(dev);
 
 	/* Must be in this order */
-	ts->serio->write(ts->serio, 1);
-	ts->serio->write(ts->serio, pwr);
-	ts->serio->write(ts->serio, brightness);
+	serio_write(ts->serio, 1);
+	serio_write(ts->serio, pwr);
+	serio_write(ts->serio, brightness);
+
 	return 0;
 }
 
@@ -262,7 +263,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type,
 
 	switch (type) {
 		case EV_LED: {
-		//	ts->serio->write(ts->serio, SOME_CMD);
+		//	serio_write(ts->serio, SOME_CMD);
 			return 0;
 		}
 	}
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 4cc047a..8fc3b08 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -31,9 +31,11 @@
 #include <linux/interrupt.h>
 #include <linux/wm97xx.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
+
 #include <mach/regs-ac97.h>
 
-#define VERSION		"0.13"
+#include <asm/mach-types.h>
 
 struct continuous {
 	u16 id;    /* codec id */
@@ -62,6 +64,7 @@ static const struct continuous cinfo[] = {
 /* continuous speed index */
 static int sp_idx;
 static u16 last, tries;
+static int irq;
 
 /*
  * Pen sampling frequency (Hz) in continuous mode.
@@ -171,7 +174,7 @@ up:
 
 static int wm97xx_acc_startup(struct wm97xx *wm)
 {
-	int idx = 0;
+	int idx = 0, ret = 0;
 
 	/* check we have a codec */
 	if (wm->ac97 == NULL)
@@ -191,18 +194,40 @@ static int wm97xx_acc_startup(struct wm97xx *wm)
 		 "mainstone accelerated touchscreen driver, %d samples/sec\n",
 		 cinfo[sp_idx].speed);
 
+	/* IRQ driven touchscreen is used on Palm hardware */
+	if (machine_is_palmt5() || machine_is_palmtx() || machine_is_palmld()) {
+		pen_int = 1;
+		irq = 27;
+		/* There is some obscure mutant of WM9712 interbred with WM9713
+		 * used on Palm HW */
+		wm->variant = WM97xx_WM1613;
+	} else if (machine_is_mainstone() && pen_int)
+		irq = 4;
+
+	if (irq) {
+		ret = gpio_request(irq, "Touchscreen IRQ");
+		if (ret)
+			goto out;
+
+		ret = gpio_direction_input(irq);
+		if (ret) {
+			gpio_free(irq);
+			goto out;
+		}
+
+		wm->pen_irq = gpio_to_irq(irq);
+		set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH);
+	} else /* pen irq not supported */
+		pen_int = 0;
+
 	/* codec specific irq config */
 	if (pen_int) {
 		switch (wm->id) {
 		case WM9705_ID2:
-			wm->pen_irq = IRQ_GPIO(4);
-			set_irq_type(IRQ_GPIO(4), IRQ_TYPE_EDGE_BOTH);
 			break;
 		case WM9712_ID2:
 		case WM9713_ID2:
-			/* enable pen down interrupt */
 			/* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
-			wm->pen_irq = MAINSTONE_AC97_IRQ;
 			wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
 					   WM97XX_GPIO_POL_HIGH,
 					   WM97XX_GPIO_STICKY,
@@ -220,23 +245,17 @@ static int wm97xx_acc_startup(struct wm97xx *wm)
 		}
 	}
 
-	return 0;
+out:
+	return ret;
 }
 
 static void wm97xx_acc_shutdown(struct wm97xx *wm)
 {
 	/* codec specific deconfig */
 	if (pen_int) {
-		switch (wm->id & 0xffff) {
-		case WM9705_ID2:
-			wm->pen_irq = 0;
-			break;
-		case WM9712_ID2:
-		case WM9713_ID2:
-			/* disable interrupt */
-			wm->pen_irq = 0;
-			break;
-		}
+		if (irq)
+			gpio_free(irq);
+		wm->pen_irq = 0;
 	}
 }
 
diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c
new file mode 100644
index 0000000..67fcd33
--- /dev/null
+++ b/drivers/input/touchscreen/pcap_ts.c
@@ -0,0 +1,271 @@
+/*
+ * Driver for Motorola PCAP2 touchscreen as found in the EZX phone platform.
+ *
+ *  Copyright (C) 2006 Harald Welte <laforge@openezx.org>
+ *  Copyright (C) 2009 Daniel Ribeiro <drwyrm@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 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/pm.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/mfd/ezx-pcap.h>
+
+struct pcap_ts {
+	struct pcap_chip *pcap;
+	struct input_dev *input;
+	struct delayed_work work;
+	u16 x, y;
+	u16 pressure;
+	u8 read_state;
+};
+
+#define SAMPLE_DELAY	20 /* msecs */
+
+#define X_AXIS_MIN	0
+#define X_AXIS_MAX	1023
+#define Y_AXIS_MAX	X_AXIS_MAX
+#define Y_AXIS_MIN	X_AXIS_MIN
+#define PRESSURE_MAX	X_AXIS_MAX
+#define PRESSURE_MIN	X_AXIS_MIN
+
+static void pcap_ts_read_xy(void *data, u16 res[2])
+{
+	struct pcap_ts *pcap_ts = data;
+
+	switch (pcap_ts->read_state) {
+	case PCAP_ADC_TS_M_PRESSURE:
+		/* pressure reading is unreliable */
+		if (res[0] > PRESSURE_MIN && res[0] < PRESSURE_MAX)
+			pcap_ts->pressure = res[0];
+		pcap_ts->read_state = PCAP_ADC_TS_M_XY;
+		schedule_delayed_work(&pcap_ts->work, 0);
+		break;
+	case PCAP_ADC_TS_M_XY:
+		pcap_ts->y = res[0];
+		pcap_ts->x = res[1];
+		if (pcap_ts->x <= X_AXIS_MIN || pcap_ts->x >= X_AXIS_MAX ||
+		    pcap_ts->y <= Y_AXIS_MIN || pcap_ts->y >= Y_AXIS_MAX) {
+			/* pen has been released */
+			input_report_abs(pcap_ts->input, ABS_PRESSURE, 0);
+			input_report_key(pcap_ts->input, BTN_TOUCH, 0);
+
+			pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY;
+			schedule_delayed_work(&pcap_ts->work, 0);
+		} else {
+			/* pen is touching the screen */
+			input_report_abs(pcap_ts->input, ABS_X, pcap_ts->x);
+			input_report_abs(pcap_ts->input, ABS_Y, pcap_ts->y);
+			input_report_key(pcap_ts->input, BTN_TOUCH, 1);
+			input_report_abs(pcap_ts->input, ABS_PRESSURE,
+						pcap_ts->pressure);
+
+			/* switch back to pressure read mode */
+			pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE;
+			schedule_delayed_work(&pcap_ts->work,
+					msecs_to_jiffies(SAMPLE_DELAY));
+		}
+		input_sync(pcap_ts->input);
+		break;
+	default:
+		dev_warn(&pcap_ts->input->dev,
+				"pcap_ts: Warning, unhandled read_state %d\n",
+				pcap_ts->read_state);
+		break;
+	}
+}
+
+static void pcap_ts_work(struct work_struct *work)
+{
+	struct delayed_work *dw = container_of(work, struct delayed_work, work);
+	struct pcap_ts *pcap_ts = container_of(dw, struct pcap_ts, work);
+	u8 ch[2];
+
+	pcap_set_ts_bits(pcap_ts->pcap,
+			pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
+
+	if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY)
+		return;
+
+	/* start adc conversion */
+	ch[0] = PCAP_ADC_CH_TS_X1;
+	ch[1] = PCAP_ADC_CH_TS_Y1;
+	pcap_adc_async(pcap_ts->pcap, PCAP_ADC_BANK_1, 0, ch,
+						pcap_ts_read_xy, pcap_ts);
+}
+
+static irqreturn_t pcap_ts_event_touch(int pirq, void *data)
+{
+	struct pcap_ts *pcap_ts = data;
+
+	if (pcap_ts->read_state == PCAP_ADC_TS_M_STANDBY) {
+		pcap_ts->read_state = PCAP_ADC_TS_M_PRESSURE;
+		schedule_delayed_work(&pcap_ts->work, 0);
+	}
+	return IRQ_HANDLED;
+}
+
+static int pcap_ts_open(struct input_dev *dev)
+{
+	struct pcap_ts *pcap_ts = input_get_drvdata(dev);
+
+	pcap_ts->read_state = PCAP_ADC_TS_M_STANDBY;
+	schedule_delayed_work(&pcap_ts->work, 0);
+
+	return 0;
+}
+
+static void pcap_ts_close(struct input_dev *dev)
+{
+	struct pcap_ts *pcap_ts = input_get_drvdata(dev);
+
+	cancel_delayed_work_sync(&pcap_ts->work);
+
+	pcap_ts->read_state = PCAP_ADC_TS_M_NONTS;
+	pcap_set_ts_bits(pcap_ts->pcap,
+				pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
+}
+
+static int __devinit pcap_ts_probe(struct platform_device *pdev)
+{
+	struct input_dev *input_dev;
+	struct pcap_ts *pcap_ts;
+	int err = -ENOMEM;
+
+	pcap_ts = kzalloc(sizeof(*pcap_ts), GFP_KERNEL);
+	if (!pcap_ts)
+		return err;
+
+	pcap_ts->pcap = dev_get_drvdata(pdev->dev.parent);
+	platform_set_drvdata(pdev, pcap_ts);
+
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		goto fail;
+
+	INIT_DELAYED_WORK(&pcap_ts->work, pcap_ts_work);
+
+	pcap_ts->read_state = PCAP_ADC_TS_M_NONTS;
+	pcap_set_ts_bits(pcap_ts->pcap,
+				pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
+
+	pcap_ts->input = input_dev;
+	input_set_drvdata(input_dev, pcap_ts);
+
+	input_dev->name = "pcap-touchscreen";
+	input_dev->phys = "pcap_ts/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = 0x0002;
+	input_dev->id.version = 0x0100;
+	input_dev->dev.parent = &pdev->dev;
+	input_dev->open = pcap_ts_open;
+	input_dev->close = pcap_ts_close;
+
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+	input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN,
+			     PRESSURE_MAX, 0, 0);
+
+	err = input_register_device(pcap_ts->input);
+	if (err)
+		goto fail_allocate;
+
+	err = request_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS),
+			pcap_ts_event_touch, 0, "Touch Screen", pcap_ts);
+	if (err)
+		goto fail_register;
+
+	return 0;
+
+fail_register:
+	input_unregister_device(input_dev);
+	goto fail;
+fail_allocate:
+	input_free_device(input_dev);
+fail:
+	kfree(pcap_ts);
+
+	return err;
+}
+
+static int __devexit pcap_ts_remove(struct platform_device *pdev)
+{
+	struct pcap_ts *pcap_ts = platform_get_drvdata(pdev);
+
+	free_irq(pcap_to_irq(pcap_ts->pcap, PCAP_IRQ_TS), pcap_ts);
+	cancel_delayed_work_sync(&pcap_ts->work);
+
+	input_unregister_device(pcap_ts->input);
+
+	kfree(pcap_ts);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int pcap_ts_suspend(struct device *dev)
+{
+	struct pcap_ts *pcap_ts = dev_get_drvdata(dev);
+
+	pcap_set_ts_bits(pcap_ts->pcap, PCAP_ADC_TS_REF_LOWPWR);
+	return 0;
+}
+
+static int pcap_ts_resume(struct device *dev)
+{
+	struct pcap_ts *pcap_ts = dev_get_drvdata(dev);
+
+	pcap_set_ts_bits(pcap_ts->pcap,
+				pcap_ts->read_state << PCAP_ADC_TS_M_SHIFT);
+	return 0;
+}
+
+static struct dev_pm_ops pcap_ts_pm_ops = {
+	.suspend	= pcap_ts_suspend,
+	.resume		= pcap_ts_resume,
+};
+#define PCAP_TS_PM_OPS (&pcap_ts_pm_ops)
+#else
+#define PCAP_TS_PM_OPS NULL
+#endif
+
+static struct platform_driver pcap_ts_driver = {
+	.probe		= pcap_ts_probe,
+	.remove		= __devexit_p(pcap_ts_remove),
+	.driver		= {
+		.name	= "pcap-ts",
+		.owner	= THIS_MODULE,
+		.pm	= PCAP_TS_PM_OPS,
+	},
+};
+
+static int __init pcap_ts_init(void)
+{
+	return platform_driver_register(&pcap_ts_driver);
+}
+
+static void __exit pcap_ts_exit(void)
+{
+	platform_driver_unregister(&pcap_ts_driver);
+}
+
+module_init(pcap_ts_init);
+module_exit(pcap_ts_exit);
+
+MODULE_DESCRIPTION("Motorola PCAP2 touchscreen driver");
+MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pcap_ts");
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c
index 880f58c..7ef0d14 100644
--- a/drivers/input/touchscreen/tsc2007.c
+++ b/drivers/input/touchscreen/tsc2007.c
@@ -21,15 +21,14 @@
  */
 
 #include <linux/module.h>
-#include <linux/hrtimer.h>
 #include <linux/slab.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
 
-#define TS_POLL_DELAY	(10 * 1000)	/* ns delay before the first sample */
-#define TS_POLL_PERIOD	(5 * 1000)	/* ns delay between samples */
+#define TS_POLL_DELAY			1 /* ms delay between samples */
+#define TS_POLL_PERIOD			1 /* ms delay between samples */
 
 #define TSC2007_MEASURE_TEMP0		(0x0 << 4)
 #define TSC2007_MEASURE_AUX		(0x2 << 4)
@@ -70,17 +69,14 @@ struct ts_event {
 struct tsc2007 {
 	struct input_dev	*input;
 	char			phys[32];
-	struct hrtimer		timer;
-	struct ts_event		tc;
+	struct delayed_work	work;
 
 	struct i2c_client	*client;
 
-	spinlock_t		lock;
-
 	u16			model;
 	u16			x_plate_ohms;
 
-	unsigned		pendown;
+	bool			pendown;
 	int			irq;
 
 	int			(*get_pendown_state)(void);
@@ -109,52 +105,96 @@ static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
 	return val;
 }
 
-static void tsc2007_send_event(void *tsc)
+static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc)
 {
-	struct tsc2007	*ts = tsc;
-	u32		rt;
-	u16		x, y, z1, z2;
+	/* y- still on; turn on only y+ (and ADC) */
+	tc->y = tsc2007_xfer(tsc, READ_Y);
+
+	/* turn y- off, x+ on, then leave in lowpower */
+	tc->x = tsc2007_xfer(tsc, READ_X);
+
+	/* turn y+ off, x- on; we'll use formula #1 */
+	tc->z1 = tsc2007_xfer(tsc, READ_Z1);
+	tc->z2 = tsc2007_xfer(tsc, READ_Z2);
 
-	x = ts->tc.x;
-	y = ts->tc.y;
-	z1 = ts->tc.z1;
-	z2 = ts->tc.z2;
+	/* Prepare for next touch reading - power down ADC, enable PENIRQ */
+	tsc2007_xfer(tsc, PWRDOWN);
+}
+
+static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
+{
+	u32 rt = 0;
 
 	/* range filtering */
-	if (x == MAX_12BIT)
-		x = 0;
+	if (tc->x == MAX_12BIT)
+		tc->x = 0;
 
-	if (likely(x && z1)) {
+	if (likely(tc->x && tc->z1)) {
 		/* compute touch pressure resistance using equation #1 */
-		rt = z2;
-		rt -= z1;
-		rt *= x;
-		rt *= ts->x_plate_ohms;
-		rt /= z1;
+		rt = tc->z2 - tc->z1;
+		rt *= tc->x;
+		rt *= tsc->x_plate_ohms;
+		rt /= tc->z1;
 		rt = (rt + 2047) >> 12;
-	} else
-		rt = 0;
+	}
+
+	return rt;
+}
+
+static void tsc2007_send_up_event(struct tsc2007 *tsc)
+{
+	struct input_dev *input = tsc->input;
 
-	/* Sample found inconsistent by debouncing or pressure is beyond
-	 * the maximum. Don't report it to user space, repeat at least
-	 * once more the measurement
+	dev_dbg(&tsc->client->dev, "UP\n");
+
+	input_report_key(input, BTN_TOUCH, 0);
+	input_report_abs(input, ABS_PRESSURE, 0);
+	input_sync(input);
+}
+
+static void tsc2007_work(struct work_struct *work)
+{
+	struct tsc2007 *ts =
+		container_of(to_delayed_work(work), struct tsc2007, work);
+	struct ts_event tc;
+	u32 rt;
+
+	/*
+	 * NOTE: We can't rely on the pressure to determine the pen down
+	 * state, even though this controller has a pressure sensor.
+	 * The pressure value can fluctuate for quite a while after
+	 * lifting the pen and in some cases may not even settle at the
+	 * expected value.
+	 *
+	 * The only safe way to check for the pen up condition is in the
+	 * work function by reading the pen signal state (it's a GPIO
+	 * and IRQ). Unfortunately such callback is not always available,
+	 * in that case we have rely on the pressure anyway.
 	 */
+	if (ts->get_pendown_state) {
+		if (unlikely(!ts->get_pendown_state())) {
+			tsc2007_send_up_event(ts);
+			ts->pendown = false;
+			goto out;
+		}
+
+		dev_dbg(&ts->client->dev, "pen is still down\n");
+	}
+
+	tsc2007_read_values(ts, &tc);
+
+	rt = tsc2007_calculate_pressure(ts, &tc);
 	if (rt > MAX_12BIT) {
+		/*
+		 * Sample found inconsistent by debouncing or pressure is
+		 * beyond the maximum. Don't report it to user space,
+		 * repeat at least once more the measurement.
+		 */
 		dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
+		goto out;
 
-		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
-			      HRTIMER_MODE_REL);
-		return;
 	}
 
-	/* NOTE: We can't rely on the pressure to determine the pen down
-	 * state, even this controller has a pressure sensor.  The pressure
-	 * value can fluctuate for quite a while after lifting the pen and
-	 * in some cases may not even settle at the expected value.
-	 *
-	 * The only safe way to check for the pen up condition is in the
-	 * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
-	 */
 	if (rt) {
 		struct input_dev *input = ts->input;
 
@@ -162,102 +202,74 @@ static void tsc2007_send_event(void *tsc)
 			dev_dbg(&ts->client->dev, "DOWN\n");
 
 			input_report_key(input, BTN_TOUCH, 1);
-			ts->pendown = 1;
+			ts->pendown = true;
 		}
 
-		input_report_abs(input, ABS_X, x);
-		input_report_abs(input, ABS_Y, y);
+		input_report_abs(input, ABS_X, tc.x);
+		input_report_abs(input, ABS_Y, tc.y);
 		input_report_abs(input, ABS_PRESSURE, rt);
 
 		input_sync(input);
 
 		dev_dbg(&ts->client->dev, "point(%4d,%4d), pressure (%4u)\n",
-			x, y, rt);
+			tc.x, tc.y, rt);
+
+	} else if (!ts->get_pendown_state && ts->pendown) {
+		/*
+		 * We don't have callback to check pendown state, so we
+		 * have to assume that since pressure reported is 0 the
+		 * pen was lifted up.
+		 */
+		tsc2007_send_up_event(ts);
+		ts->pendown = false;
 	}
 
-	hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
-			HRTIMER_MODE_REL);
-}
-
-static int tsc2007_read_values(struct tsc2007 *tsc)
-{
-	/* y- still on; turn on only y+ (and ADC) */
-	tsc->tc.y = tsc2007_xfer(tsc, READ_Y);
-
-	/* turn y- off, x+ on, then leave in lowpower */
-	tsc->tc.x = tsc2007_xfer(tsc, READ_X);
-
-	/* turn y+ off, x- on; we'll use formula #1 */
-	tsc->tc.z1 = tsc2007_xfer(tsc, READ_Z1);
-	tsc->tc.z2 = tsc2007_xfer(tsc, READ_Z2);
-
-	/* power down */
-	tsc2007_xfer(tsc, PWRDOWN);
-
-	return 0;
-}
-
-static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
-{
-	struct tsc2007 *ts = container_of(handle, struct tsc2007, timer);
-	unsigned long flags;
-
-	spin_lock_irqsave(&ts->lock, flags);
-
-	if (unlikely(!ts->get_pendown_state() && ts->pendown)) {
-		struct input_dev *input = ts->input;
-
-		dev_dbg(&ts->client->dev, "UP\n");
-
-		input_report_key(input, BTN_TOUCH, 0);
-		input_report_abs(input, ABS_PRESSURE, 0);
-		input_sync(input);
-
-		ts->pendown = 0;
+ out:
+	if (ts->pendown)
+		schedule_delayed_work(&ts->work,
+				      msecs_to_jiffies(TS_POLL_PERIOD));
+	else
 		enable_irq(ts->irq);
-	} else {
-		/* pen is still down, continue with the measurement */
-		dev_dbg(&ts->client->dev, "pen is still down\n");
-
-		tsc2007_read_values(ts);
-		tsc2007_send_event(ts);
-	}
-
-	spin_unlock_irqrestore(&ts->lock, flags);
-
-	return HRTIMER_NORESTART;
 }
 
 static irqreturn_t tsc2007_irq(int irq, void *handle)
 {
 	struct tsc2007 *ts = handle;
-	unsigned long flags;
-
-	spin_lock_irqsave(&ts->lock, flags);
 
-	if (likely(ts->get_pendown_state())) {
+	if (!ts->get_pendown_state || likely(ts->get_pendown_state())) {
 		disable_irq_nosync(ts->irq);
-		hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
-					HRTIMER_MODE_REL);
+		schedule_delayed_work(&ts->work,
+				      msecs_to_jiffies(TS_POLL_DELAY));
 	}
 
 	if (ts->clear_penirq)
 		ts->clear_penirq();
 
-	spin_unlock_irqrestore(&ts->lock, flags);
-
 	return IRQ_HANDLED;
 }
 
-static int tsc2007_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static void tsc2007_free_irq(struct tsc2007 *ts)
+{
+	free_irq(ts->irq, ts);
+	if (cancel_delayed_work_sync(&ts->work)) {
+		/*
+		 * Work was pending, therefore we need to enable
+		 * IRQ here to balance the disable_irq() done in the
+		 * interrupt handler.
+		 */
+		enable_irq(ts->irq);
+	}
+}
+
+static int __devinit tsc2007_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
 {
 	struct tsc2007 *ts;
 	struct tsc2007_platform_data *pdata = pdata = client->dev.platform_data;
 	struct input_dev *input_dev;
 	int err;
 
-	if (!pdata || !pdata->get_pendown_state) {
+	if (!pdata) {
 		dev_err(&client->dev, "platform data is required!\n");
 		return -EINVAL;
 	}
@@ -274,22 +286,15 @@ static int tsc2007_probe(struct i2c_client *client,
 	}
 
 	ts->client = client;
-	i2c_set_clientdata(client, ts);
-
+	ts->irq = client->irq;
 	ts->input = input_dev;
-
-	hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	ts->timer.function = tsc2007_timer;
-
-	spin_lock_init(&ts->lock);
+	INIT_DELAYED_WORK(&ts->work, tsc2007_work);
 
 	ts->model             = pdata->model;
 	ts->x_plate_ohms      = pdata->x_plate_ohms;
 	ts->get_pendown_state = pdata->get_pendown_state;
 	ts->clear_penirq      = pdata->clear_penirq;
 
-	pdata->init_platform_hw();
-
 	snprintf(ts->phys, sizeof(ts->phys),
 		 "%s/input0", dev_name(&client->dev));
 
@@ -304,9 +309,8 @@ static int tsc2007_probe(struct i2c_client *client,
 	input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
 
-	tsc2007_read_values(ts);
-
-	ts->irq = client->irq;
+	if (pdata->init_platform_hw)
+		pdata->init_platform_hw();
 
 	err = request_irq(ts->irq, tsc2007_irq, 0,
 			client->dev.driver->name, ts);
@@ -315,33 +319,39 @@ static int tsc2007_probe(struct i2c_client *client,
 		goto err_free_mem;
 	}
 
+	/* Prepare for touch readings - power down ADC and enable PENIRQ */
+	err = tsc2007_xfer(ts, PWRDOWN);
+	if (err < 0)
+		goto err_free_irq;
+
 	err = input_register_device(input_dev);
 	if (err)
 		goto err_free_irq;
 
-	dev_info(&client->dev, "registered with irq (%d)\n", ts->irq);
+	i2c_set_clientdata(client, ts);
 
 	return 0;
 
  err_free_irq:
-	free_irq(ts->irq, ts);
-	hrtimer_cancel(&ts->timer);
+	tsc2007_free_irq(ts);
+	if (pdata->exit_platform_hw)
+		pdata->exit_platform_hw();
  err_free_mem:
 	input_free_device(input_dev);
 	kfree(ts);
 	return err;
 }
 
-static int tsc2007_remove(struct i2c_client *client)
+static int __devexit tsc2007_remove(struct i2c_client *client)
 {
 	struct tsc2007	*ts = i2c_get_clientdata(client);
-	struct tsc2007_platform_data *pdata;
+	struct tsc2007_platform_data *pdata = client->dev.platform_data;
 
-	pdata = client->dev.platform_data;
-	pdata->exit_platform_hw();
+	tsc2007_free_irq(ts);
+
+	if (pdata->exit_platform_hw)
+		pdata->exit_platform_hw();
 
-	free_irq(ts->irq, ts);
-	hrtimer_cancel(&ts->timer);
 	input_unregister_device(ts->input);
 	kfree(ts);
 
@@ -362,7 +372,7 @@ static struct i2c_driver tsc2007_driver = {
 	},
 	.id_table	= tsc2007_idtable,
 	.probe		= tsc2007_probe,
-	.remove		= tsc2007_remove,
+	.remove		= __devexit_p(tsc2007_remove),
 };
 
 static int __init tsc2007_init(void)
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 3a7a582..095f84b 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -128,9 +128,10 @@ static inline unsigned int ucb1400_ts_read_yres(struct ucb1400_ts *ucb)
 	return ucb1400_adc_read(ucb->ac97, 0, adcsync);
 }
 
-static inline int ucb1400_ts_pen_down(struct snd_ac97 *ac97)
+static inline int ucb1400_ts_pen_up(struct snd_ac97 *ac97)
 {
 	unsigned short val = ucb1400_reg_read(ac97, UCB_TS_CR);
+
 	return val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW);
 }
 
@@ -209,7 +210,7 @@ static int ucb1400_ts_thread(void *_ucb)
 
 		msleep(10);
 
-		if (ucb1400_ts_pen_down(ucb->ac97)) {
+		if (ucb1400_ts_pen_up(ucb->ac97)) {
 			ucb1400_ts_irq_enable(ucb->ac97);
 
 			/*
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index fb7cb9b..68ece58 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -13,6 +13,7 @@
  *  - IdealTEK URTC1000
  *  - General Touch
  *  - GoTop Super_Q2/GogoPen/PenPower tablets
+ *  - JASTEC USB touch controller/DigiTech DTR-02U
  *
  * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
@@ -118,6 +119,8 @@ enum {
 	DEVTYPE_IDEALTEK,
 	DEVTYPE_GENERAL_TOUCH,
 	DEVTYPE_GOTOP,
+	DEVTYPE_JASTEC,
+	DEVTYPE_E2I,
 };
 
 #define USB_DEVICE_HID_CLASS(vend, prod) \
@@ -191,11 +194,51 @@ static struct usb_device_id usbtouch_devices[] = {
 	{USB_DEVICE(0x08f2, 0x00f4), .driver_info = DEVTYPE_GOTOP},
 #endif
 
+#ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
+	{USB_DEVICE(0x0f92, 0x0001), .driver_info = DEVTYPE_JASTEC},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_E2I
+	{USB_DEVICE(0x1ac7, 0x0001), .driver_info = DEVTYPE_E2I},
+#endif
 	{}
 };
 
 
 /*****************************************************************************
+ * e2i Part
+ */
+
+#ifdef CONFIG_TOUCHSCREEN_USB_E2I
+static int e2i_init(struct usbtouch_usb *usbtouch)
+{
+	int ret;
+
+	ret = usb_control_msg(usbtouch->udev, usb_rcvctrlpipe(usbtouch->udev, 0),
+	                      0x01, 0x02, 0x0000, 0x0081,
+	                      NULL, 0, USB_CTRL_SET_TIMEOUT);
+
+	dbg("%s - usb_control_msg - E2I_RESET - bytes|err: %d",
+	    __func__, ret);
+	return ret;
+}
+
+static int e2i_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	int tmp = (pkt[0] << 8) | pkt[1];
+	dev->x  = (pkt[2] << 8) | pkt[3];
+	dev->y  = (pkt[4] << 8) | pkt[5];
+
+	tmp = tmp - 0xA000;
+	dev->touch = (tmp > 0);
+	dev->press = (tmp > 0 ? tmp : 0);
+
+	return 1;
+}
+#endif
+
+
+/*****************************************************************************
  * eGalax part
  */
 
@@ -559,6 +602,21 @@ static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
 	dev->x = ((pkt[1] & 0x38) << 4) | pkt[2];
 	dev->y = ((pkt[1] & 0x07) << 7) | pkt[3];
 	dev->touch = pkt[0] & 0x01;
+
+	return 1;
+}
+#endif
+
+/*****************************************************************************
+ * JASTEC Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
+static int jastec_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+	dev->x = ((pkt[0] & 0x3f) << 6) | (pkt[2] & 0x3f);
+	dev->y = ((pkt[1] & 0x3f) << 6) | (pkt[3] & 0x3f);
+	dev->touch = (pkt[0] & 0x40) >> 6;
+
 	return 1;
 }
 #endif
@@ -702,6 +760,29 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
 		.read_data	= gotop_read_data,
 	},
 #endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_JASTEC
+	[DEVTYPE_JASTEC] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x0fff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x0fff,
+		.rept_size	= 4,
+		.read_data	= jastec_read_data,
+	},
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_USB_E2I
+	[DEVTYPE_E2I] = {
+		.min_xc		= 0x0,
+		.max_xc		= 0x7fff,
+		.min_yc		= 0x0,
+		.max_yc		= 0x7fff,
+		.rept_size	= 6,
+		.init		= e2i_init,
+		.read_data	= e2i_read_data,
+	},
+#endif
 };
 
 
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c
index 6071f58..6ccbdbb 100644
--- a/drivers/input/touchscreen/w90p910_ts.c
+++ b/drivers/input/touchscreen/w90p910_ts.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
 
@@ -47,8 +48,8 @@ enum ts_state {
 struct w90p910_ts {
 	struct input_dev *input;
 	struct timer_list timer;
+	struct clk *clk;
 	int irq_num;
-	void __iomem *clocken;
 	void __iomem *ts_reg;
 	spinlock_t lock;
 	enum ts_state state;
@@ -166,8 +167,7 @@ static int w90p910_open(struct input_dev *dev)
 	unsigned long val;
 
 	/* enable the ADC clock */
-	val = __raw_readl(w90p910_ts->clocken);
-	__raw_writel(val | ADC_CLK_EN, w90p910_ts->clocken);
+	clk_enable(w90p910_ts->clk);
 
 	__raw_writel(ADC_RST1, w90p910_ts->ts_reg);
 	msleep(1);
@@ -211,8 +211,7 @@ static void w90p910_close(struct input_dev *dev)
 	del_timer_sync(&w90p910_ts->timer);
 
 	/* stop the ADC clock */
-	val = __raw_readl(w90p910_ts->clocken);
-	__raw_writel(val & ~ADC_CLK_EN, w90p910_ts->clocken);
+	clk_disable(w90p910_ts->clk);
 }
 
 static int __devinit w90x900ts_probe(struct platform_device *pdev)
@@ -241,26 +240,24 @@ static int __devinit w90x900ts_probe(struct platform_device *pdev)
 		goto fail1;
 	}
 
-	if (!request_mem_region(res->start, res->end - res->start + 1,
+	if (!request_mem_region(res->start, resource_size(res),
 				pdev->name)) {
 		err = -EBUSY;
 		goto fail1;
 	}
 
-	w90p910_ts->ts_reg = ioremap(res->start, res->end - res->start + 1);
+	w90p910_ts->ts_reg = ioremap(res->start, resource_size(res));
 	if (!w90p910_ts->ts_reg) {
 		err = -ENOMEM;
 		goto fail2;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!res) {
-		err = -ENXIO;
+	w90p910_ts->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(w90p910_ts->clk)) {
+		err = PTR_ERR(w90p910_ts->clk);
 		goto fail3;
 	}
 
-	w90p910_ts->clocken = (void __iomem *)res->start;
-
 	input_dev->name = "W90P910 TouchScreen";
 	input_dev->phys = "w90p910ts/event0";
 	input_dev->id.bustype = BUS_HOST;
@@ -283,20 +280,21 @@ static int __devinit w90x900ts_probe(struct platform_device *pdev)
 	if (request_irq(w90p910_ts->irq_num, w90p910_ts_interrupt,
 			IRQF_DISABLED, "w90p910ts", w90p910_ts)) {
 		err = -EBUSY;
-		goto fail3;
+		goto fail4;
 	}
 
 	err = input_register_device(w90p910_ts->input);
 	if (err)
-		goto fail4;
+		goto fail5;
 
 	platform_set_drvdata(pdev, w90p910_ts);
 
 	return 0;
 
-fail4:	free_irq(w90p910_ts->irq_num, w90p910_ts);
+fail5:	free_irq(w90p910_ts->irq_num, w90p910_ts);
+fail4:	clk_put(w90p910_ts->clk);
 fail3:	iounmap(w90p910_ts->ts_reg);
-fail2:	release_mem_region(res->start, res->end - res->start + 1);
+fail2:	release_mem_region(res->start, resource_size(res));
 fail1:	input_free_device(input_dev);
 	kfree(w90p910_ts);
 	return err;
@@ -311,8 +309,10 @@ static int __devexit w90x900ts_remove(struct platform_device *pdev)
 	del_timer_sync(&w90p910_ts->timer);
 	iounmap(w90p910_ts->ts_reg);
 
+	clk_put(w90p910_ts->clk);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 
 	input_unregister_device(w90p910_ts->input);
 	kfree(w90p910_ts);
@@ -326,7 +326,7 @@ static struct platform_driver w90x900ts_driver = {
 	.probe		= w90x900ts_probe,
 	.remove		= __devexit_p(w90x900ts_remove),
 	.driver		= {
-		.name	= "w90x900-ts",
+		.name	= "nuc900-ts",
 		.owner	= THIS_MODULE,
 	},
 };
@@ -347,4 +347,4 @@ module_exit(w90x900ts_exit);
 MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
 MODULE_DESCRIPTION("w90p910 touch screen driver!");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:w90p910-ts");
+MODULE_ALIAS("platform:nuc900-ts");
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 2f33a01..56dc35c 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -25,18 +25,16 @@ MODULE_AUTHOR("Jaya Kumar <jayakumar.lkml@gmail.com>");
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-/*
- * Definitions & global arrays.
- */
-
 #define W8001_MAX_LENGTH	11
-#define W8001_PACKET_LEN	11
-#define W8001_LEAD_MASK 0x80
-#define W8001_LEAD_BYTE 0x80
-#define W8001_TAB_MASK 0x40
-#define W8001_TAB_BYTE 0x40
+#define W8001_LEAD_MASK		0x80
+#define W8001_LEAD_BYTE		0x80
+#define W8001_TAB_MASK		0x40
+#define W8001_TAB_BYTE		0x40
 
-#define W8001_QUERY_PACKET 0x20
+#define W8001_QUERY_PACKET	0x20
+
+#define W8001_CMD_START		'1'
+#define W8001_CMD_QUERY		'*'
 
 struct w8001_coord {
 	u8 rdy;
@@ -57,18 +55,19 @@ struct w8001_coord {
 struct w8001 {
 	struct input_dev *dev;
 	struct serio *serio;
-	struct mutex cmd_mutex;
 	struct completion cmd_done;
 	int id;
 	int idx;
-	unsigned char expected_packet;
+	unsigned char response_type;
+	unsigned char response[W8001_MAX_LENGTH];
 	unsigned char data[W8001_MAX_LENGTH];
-	unsigned char response[W8001_PACKET_LEN];
 	char phys[32];
 };
 
-static int parse_data(u8 *data, struct w8001_coord *coord)
+static void parse_data(u8 *data, struct w8001_coord *coord)
 {
+	memset(coord, 0, sizeof(*coord));
+
 	coord->rdy = data[0] & 0x20;
 	coord->tsw = data[0] & 0x01;
 	coord->f1 = data[0] & 0x02;
@@ -87,15 +86,15 @@ static int parse_data(u8 *data, struct w8001_coord *coord)
 
 	coord->tilt_x = data[7] & 0x7F;
 	coord->tilt_y = data[8] & 0x7F;
-
-	return 0;
 }
 
-static void w8001_process_data(struct w8001 *w8001, unsigned char data)
+static irqreturn_t w8001_interrupt(struct serio *serio,
+				   unsigned char data, unsigned int flags)
 {
+	struct w8001 *w8001 = serio_get_drvdata(serio);
 	struct input_dev *dev = w8001->dev;
-	u8 tmp;
 	struct w8001_coord coord;
+	unsigned char tmp;
 
 	w8001->data[w8001->idx] = data;
 	switch (w8001->idx++) {
@@ -105,12 +104,13 @@ static void w8001_process_data(struct w8001 *w8001, unsigned char data)
 			w8001->idx = 0;
 		}
 		break;
+
 	case 8:
 		tmp = w8001->data[0] & W8001_TAB_MASK;
 		if (unlikely(tmp == W8001_TAB_BYTE))
 			break;
+
 		w8001->idx = 0;
-		memset(&coord, 0, sizeof(coord));
 		parse_data(w8001->data, &coord);
 		input_report_abs(dev, ABS_X, coord.x);
 		input_report_abs(dev, ABS_Y, coord.y);
@@ -118,86 +118,48 @@ static void w8001_process_data(struct w8001 *w8001, unsigned char data)
 		input_report_key(dev, BTN_TOUCH, coord.tsw);
 		input_sync(dev);
 		break;
+
 	case 10:
 		w8001->idx = 0;
-		memcpy(w8001->response, &w8001->data, W8001_PACKET_LEN);
-		w8001->expected_packet = W8001_QUERY_PACKET;
+		memcpy(w8001->response, w8001->data, W8001_MAX_LENGTH);
+		w8001->response_type = W8001_QUERY_PACKET;
 		complete(&w8001->cmd_done);
 		break;
 	}
-}
-
-
-static irqreturn_t w8001_interrupt(struct serio *serio,
-		unsigned char data, unsigned int flags)
-{
-	struct w8001 *w8001 = serio_get_drvdata(serio);
-
-	w8001_process_data(w8001, data);
 
 	return IRQ_HANDLED;
 }
 
-static int w8001_async_command(struct w8001 *w8001, unsigned char *packet,
-					int len)
-{
-	int rc = -1;
-	int i;
-
-	mutex_lock(&w8001->cmd_mutex);
-
-	for (i = 0; i < len; i++) {
-		if (serio_write(w8001->serio, packet[i]))
-			goto out;
-	}
-	rc = 0;
-
-out:
-	mutex_unlock(&w8001->cmd_mutex);
-	return rc;
-}
-
-static int w8001_command(struct w8001 *w8001, unsigned char *packet, int len)
+static int w8001_command(struct w8001 *w8001, unsigned char command,
+			 bool wait_response)
 {
-	int rc = -1;
-	int i;
+	int rc;
 
-	mutex_lock(&w8001->cmd_mutex);
-
-	serio_pause_rx(w8001->serio);
+	w8001->response_type = 0;
 	init_completion(&w8001->cmd_done);
-	serio_continue_rx(w8001->serio);
-
-	for (i = 0; i < len; i++) {
-		if (serio_write(w8001->serio, packet[i]))
-			goto out;
-	}
 
-	wait_for_completion_timeout(&w8001->cmd_done, HZ);
+	rc = serio_write(w8001->serio, command);
+	if (rc == 0 && wait_response) {
 
-	if (w8001->expected_packet == W8001_QUERY_PACKET) {
-		/* We are back in reporting mode, the query was ACKed */
-		memcpy(packet, w8001->response, W8001_PACKET_LEN);
-		rc = 0;
+		wait_for_completion_timeout(&w8001->cmd_done, HZ);
+		if (w8001->response_type != W8001_QUERY_PACKET)
+			rc = -EIO;
 	}
 
-out:
-	mutex_unlock(&w8001->cmd_mutex);
 	return rc;
 }
 
 static int w8001_setup(struct w8001 *w8001)
 {
-	struct w8001_coord coord;
 	struct input_dev *dev = w8001->dev;
-	unsigned char start[1] = { '1' };
-	unsigned char query[11] = { '*' };
+	struct w8001_coord coord;
+	int error;
 
-	if (w8001_command(w8001, query, 1))
-		return -1;
+	error = w8001_command(w8001, W8001_CMD_QUERY, true);
+	if (error)
+		return error;
 
-	memset(&coord, 0, sizeof(coord));
-	parse_data(query, &coord);
+	parse_data(w8001->response, &coord);
 
 	input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
 	input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
@@ -205,10 +167,7 @@ static int w8001_setup(struct w8001 *w8001)
 	input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
 	input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
 
-	if (w8001_async_command(w8001, start, 1))
-		return -1;
-
-	return 0;
+	return w8001_command(w8001, W8001_CMD_START, false);
 }
 
 /*
@@ -249,7 +208,6 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
 	w8001->serio = serio;
 	w8001->id = serio->id.id;
 	w8001->dev = input_dev;
-	mutex_init(&w8001->cmd_mutex);
 	init_completion(&w8001->cmd_done);
 	snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
 
@@ -269,7 +227,8 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
 	if (err)
 		goto fail2;
 
-	if (w8001_setup(w8001))
+	err = w8001_setup(w8001);
+	if (err)
 		goto fail3;
 
 	err = input_register_device(w8001->dev);
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 2957d48..252eb11 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -204,7 +204,7 @@ void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
 	else
 		reg &= ~gpio;
 
-	if (wm->id == WM9712_ID2)
+	if (wm->id == WM9712_ID2 && wm->variant != WM97xx_WM1613)
 		wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
 	else
 		wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
@@ -307,7 +307,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work)
 					 WM97XX_GPIO_13);
 		}
 
-		if (wm->id == WM9712_ID2)
+		if (wm->id == WM9712_ID2 && wm->variant != WM97xx_WM1613)
 			wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status &
 						~WM97XX_GPIO_13) << 1);
 		else
@@ -582,6 +582,8 @@ static int wm97xx_probe(struct device *dev)
 
 	wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
 
+	wm->variant = WM97xx_GENERIC;
+
 	dev_info(wm->dev, "detected a wm97%02x codec\n", wm->id & 0xff);
 
 	switch (wm->id & 0xff) {
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index 02bdca6..022a194 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -21,8 +21,6 @@ menuconfig ISDN
 
 if ISDN
 
-source "drivers/isdn/mISDN/Kconfig"
-
 menuconfig ISDN_I4L
 	tristate "Old ISDN4Linux (deprecated)"
 	---help---
@@ -41,9 +39,9 @@ menuconfig ISDN_I4L
 	  It is still available, though, for use with adapters that are not
 	  supported by the new CAPI subsystem yet.
 
-if ISDN_I4L
+source "drivers/isdn/mISDN/Kconfig"
+
 source "drivers/isdn/i4l/Kconfig"
-endif
 
 menuconfig ISDN_CAPI
 	tristate "CAPI 2.0 subsystem"
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
index 946c38c..1f0a949 100644
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -78,7 +78,6 @@ static actcapi_msgdsc valid_msg[] = {
 #endif
 	{{ 0x00, 0x00}, NULL},
 };
-#define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
 #define num_valid_imsg 27 /* MANUFACTURER_IND */
 
 /*
@@ -1025,7 +1024,7 @@ actcapi_debug_msg(struct sk_buff *skb, int direction)
 #ifdef DEBUG_DUMP_SKB
 	dump_skb(skb);
 #endif
-	for (i = 0; i < num_valid_msg; i++)
+	for (i = 0; i < ARRAY_SIZE(valid_msg); i++)
 		if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) &&
 		    (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) {
 			descr = valid_msg[i].description;
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
index 8325022..f774e12 100644
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -23,7 +23,6 @@ static unsigned short act2000_isa_ports[] =
         0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
         0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
 };
-#define ISA_NRPORTS (sizeof(act2000_isa_ports)/sizeof(unsigned short))
 
 static act2000_card *cards = (act2000_card *) NULL;
 
@@ -686,21 +685,21 @@ act2000_addcard(int bus, int port, int irq, char *id)
 		 * This may result in more than one card detected.
 		 */
 		switch (bus) {
-			case ACT2000_BUS_ISA:
-				for (i = 0; i < ISA_NRPORTS; i++)
-					if (act2000_isa_detect(act2000_isa_ports[i])) {
-						printk(KERN_INFO
-						       "act2000: Detected ISA card at port 0x%x\n",
-						       act2000_isa_ports[i]);
-						act2000_alloccard(bus, act2000_isa_ports[i], irq, id);
-					}
-				break;
-			case ACT2000_BUS_MCA:
-			case ACT2000_BUS_PCMCIA:
-			default:
-				printk(KERN_WARNING
-				       "act2000: addcard: Invalid BUS type %d\n",
-				       bus);
+		case ACT2000_BUS_ISA:
+			for (i = 0; i < ARRAY_SIZE(act2000_isa_ports); i++)
+				if (act2000_isa_detect(act2000_isa_ports[i])) {
+					printk(KERN_INFO "act2000: Detected "
+						"ISA card at port 0x%x\n",
+						act2000_isa_ports[i]);
+					act2000_alloccard(bus,
+						act2000_isa_ports[i], irq, id);
+				}
+			break;
+		case ACT2000_BUS_MCA:
+		case ACT2000_BUS_PCMCIA:
+		default:
+			printk(KERN_WARNING
+				"act2000: addcard: Invalid BUS type %d\n", bus);
 		}
 	}
 	if (!cards)
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 8ff7e35..f33ac27 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -408,33 +408,28 @@ static int if_write_room(struct tty_struct *tty)
 	return retval;
 }
 
-/* FIXME: This function does not have error returns */
-
 static int if_chars_in_buffer(struct tty_struct *tty)
 {
 	struct cardstate *cs;
-	int retval = -ENODEV;
+	int retval = 0;
 
 	cs = (struct cardstate *) tty->driver_data;
 	if (!cs) {
 		pr_err("%s: no cardstate\n", __func__);
-		return -ENODEV;
+		return 0;
 	}
 
 	gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
 
-	if (mutex_lock_interruptible(&cs->mutex))
-		return -ERESTARTSYS; // FIXME -EINTR?
+	mutex_lock(&cs->mutex);
 
-	if (!cs->connected) {
+	if (!cs->connected)
 		gig_dbg(DEBUG_IF, "not connected");
-		retval = -ENODEV;
-	} else if (!cs->open_count)
+	else if (!cs->open_count)
 		dev_warn(cs->dev, "%s: device not opened\n", __func__);
-	else if (cs->mstate != MS_LOCKED) {
+	else if (cs->mstate != MS_LOCKED)
 		dev_warn(cs->dev, "can't write to unlocked device\n");
-		retval = -EBUSY;
-	} else
+	else
 		retval = cs->ops->chars_in_buffer(cs);
 
 	mutex_unlock(&cs->mutex);
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 31f91c1..27d5dd6 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -551,9 +551,7 @@ word api_put(APPL   * appl, CAPI_MSG   * msg)
   dbug(1,dprintf("com=%x",msg->header.command));
 
   for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0;
-  for(i=0, ret = _BAD_MSG;
-      i<(sizeof(ftable)/sizeof(struct _ftable));
-      i++) {
+  for(i=0, ret = _BAD_MSG; i < ARRAY_SIZE(ftable); i++) {
 
     if(ftable[i].command==msg->header.command) {
       /* break loop if the message is correct, otherwise continue scan  */
diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
index c964b8d..cb7616c 100644
--- a/drivers/isdn/hardware/eicon/os_4bri.c
+++ b/drivers/isdn/hardware/eicon/os_4bri.c
@@ -149,8 +149,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 	diva_os_xdi_adapter_t *diva_current;
 	diva_os_xdi_adapter_t *adapter_list[4];
 	PISDN_ADAPTER Slave;
-	unsigned long bar_length[sizeof(_4bri_bar_length) /
-				 sizeof(_4bri_bar_length[0])];
+	unsigned long bar_length[ARRAY_SIZE(_4bri_bar_length)];
 	int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
 	int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT;
 	int factor = (tasks == 1) ? 1 : 2;
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
index 3024566..bde55d7 100644
--- a/drivers/isdn/hardware/mISDN/Kconfig
+++ b/drivers/isdn/hardware/mISDN/Kconfig
@@ -39,3 +39,54 @@ config MISDN_HFCUSB
 	  Enable support for USB ISDN TAs with Cologne Chip AG's
 	  HFC-S USB ISDN Controller
 
+config MISDN_AVMFRITZ
+	tristate "Support for AVM FRITZ!CARD PCI"
+	depends on MISDN
+	depends on PCI
+	select MISDN_IPAC
+	help
+	  Enable support for AVMs FRITZ!CARD PCI cards
+
+config MISDN_SPEEDFAX
+	tristate "Support for Sedlbauer Speedfax+"
+	depends on MISDN
+	depends on PCI
+	select MISDN_IPAC
+	select MISDN_ISAR
+	help
+	  Enable support for Sedlbauer Speedfax+.
+
+config MISDN_INFINEON
+	tristate "Support for cards with Infineon chipset"
+	depends on MISDN
+	depends on PCI
+	select MISDN_IPAC
+	help
+	  Enable support for cards with ISAC + HSCX, IPAC or IPAC-SX
+	  chip from Infineon (former manufacturer Siemens).
+
+config MISDN_W6692
+	tristate "Support for cards with Winbond 6692"
+	depends on MISDN
+	depends on PCI
+	help
+	  Enable support for Winbond 6692 PCI chip based cards.
+
+config MISDN_NETJET
+	tristate "Support for NETJet cards"
+	depends on MISDN
+	depends on PCI
+	select MISDN_IPAC
+	select ISDN_HDLC
+	help
+	  Enable support for Traverse Technologies NETJet PCI cards.
+
+
+config MISDN_IPAC
+	tristate
+	depends on MISDN
+
+config MISDN_ISAR
+	tristate
+	depends on MISDN
+
diff --git a/drivers/isdn/hardware/mISDN/Makefile b/drivers/isdn/hardware/mISDN/Makefile
index b040352..2987d99 100644
--- a/drivers/isdn/hardware/mISDN/Makefile
+++ b/drivers/isdn/hardware/mISDN/Makefile
@@ -6,3 +6,11 @@
 obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o
 obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o
 obj-$(CONFIG_MISDN_HFCUSB) += hfcsusb.o
+obj-$(CONFIG_MISDN_AVMFRITZ) += avmfritz.o
+obj-$(CONFIG_MISDN_SPEEDFAX) += speedfax.o
+obj-$(CONFIG_MISDN_INFINEON) += mISDNinfineon.o
+obj-$(CONFIG_MISDN_W6692) += w6692.o
+obj-$(CONFIG_MISDN_NETJET) += netjet.o
+# chip modules
+obj-$(CONFIG_MISDN_IPAC) += mISDNipac.o
+obj-$(CONFIG_MISDN_ISAR) += mISDNisar.o
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
new file mode 100644
index 0000000..81ac541
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -0,0 +1,1152 @@
+/*
+ * avm_fritz.c    low level stuff for AVM FRITZ!CARD PCI ISDN cards
+ *                Thanks to AVM, Berlin for informations
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mISDNhw.h>
+#include <asm/unaligned.h>
+#include "ipac.h"
+
+
+#define AVMFRITZ_REV	"2.1"
+
+static int AVM_cnt;
+static int debug;
+
+enum {
+	AVM_FRITZ_PCI,
+	AVM_FRITZ_PCIV2,
+};
+
+#define HDLC_FIFO		0x0
+#define HDLC_STATUS		0x4
+#define CHIP_WINDOW		0x10
+
+#define CHIP_INDEX		0x4
+#define AVM_HDLC_1		0x00
+#define AVM_HDLC_2		0x01
+#define AVM_ISAC_FIFO		0x02
+#define AVM_ISAC_REG_LOW	0x04
+#define AVM_ISAC_REG_HIGH	0x06
+
+#define AVM_STATUS0_IRQ_ISAC	0x01
+#define AVM_STATUS0_IRQ_HDLC	0x02
+#define AVM_STATUS0_IRQ_TIMER	0x04
+#define AVM_STATUS0_IRQ_MASK	0x07
+
+#define AVM_STATUS0_RESET	0x01
+#define AVM_STATUS0_DIS_TIMER	0x02
+#define AVM_STATUS0_RES_TIMER	0x04
+#define AVM_STATUS0_ENA_IRQ	0x08
+#define AVM_STATUS0_TESTBIT	0x10
+
+#define AVM_STATUS1_INT_SEL	0x0f
+#define AVM_STATUS1_ENA_IOM	0x80
+
+#define HDLC_MODE_ITF_FLG	0x01
+#define HDLC_MODE_TRANS		0x02
+#define HDLC_MODE_CCR_7		0x04
+#define HDLC_MODE_CCR_16	0x08
+#define HDLC_MODE_TESTLOOP	0x80
+
+#define HDLC_INT_XPR		0x80
+#define HDLC_INT_XDU		0x40
+#define HDLC_INT_RPR		0x20
+#define HDLC_INT_MASK		0xE0
+
+#define HDLC_STAT_RME		0x01
+#define HDLC_STAT_RDO		0x10
+#define HDLC_STAT_CRCVFRRAB	0x0E
+#define HDLC_STAT_CRCVFR	0x06
+#define HDLC_STAT_RML_MASK	0x3f00
+
+#define HDLC_CMD_XRS		0x80
+#define HDLC_CMD_XME		0x01
+#define HDLC_CMD_RRS		0x20
+#define HDLC_CMD_XML_MASK	0x3f00
+#define HDLC_FIFO_SIZE		32
+
+/* Fritz PCI v2.0 */
+
+#define AVM_HDLC_FIFO_1		0x10
+#define AVM_HDLC_FIFO_2		0x18
+
+#define AVM_HDLC_STATUS_1	0x14
+#define AVM_HDLC_STATUS_2	0x1c
+
+#define AVM_ISACX_INDEX		0x04
+#define AVM_ISACX_DATA		0x08
+
+/* data struct */
+#define LOG_SIZE		63
+
+struct hdlc_stat_reg {
+#ifdef __BIG_ENDIAN
+	u8 fill;
+	u8 mode;
+	u8 xml;
+	u8 cmd;
+#else
+	u8 cmd;
+	u8 xml;
+	u8 mode;
+	u8 fill;
+#endif
+} __attribute__((packed));
+
+struct hdlc_hw {
+	union {
+		u32 ctrl;
+		struct hdlc_stat_reg sr;
+	} ctrl;
+	u32 stat;
+};
+
+struct fritzcard {
+	struct list_head	list;
+	struct pci_dev		*pdev;
+	char			name[MISDN_MAX_IDLEN];
+	u8			type;
+	u8			ctrlreg;
+	u16			irq;
+	u32			irqcnt;
+	u32			addr;
+	spinlock_t		lock; /* hw lock */
+	struct isac_hw		isac;
+	struct hdlc_hw		hdlc[2];
+	struct bchannel		bch[2];
+	char			log[LOG_SIZE + 1];
+};
+
+static LIST_HEAD(Cards);
+static DEFINE_RWLOCK(card_lock); /* protect Cards */
+
+static void
+_set_debug(struct fritzcard *card)
+{
+	card->isac.dch.debug = debug;
+	card->bch[0].debug = debug;
+	card->bch[1].debug = debug;
+}
+
+static int
+set_debug(const char *val, struct kernel_param *kp)
+{
+	int ret;
+	struct fritzcard *card;
+
+	ret = param_set_uint(val, kp);
+	if (!ret) {
+		read_lock(&card_lock);
+		list_for_each_entry(card, &Cards, list)
+			_set_debug(card);
+		read_unlock(&card_lock);
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("Karsten Keil");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(AVMFRITZ_REV);
+module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "avmfritz debug mask");
+
+/* Interface functions */
+
+static u8
+ReadISAC_V1(void *p, u8 offset)
+{
+	struct fritzcard *fc = p;
+	u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
+
+	outb(idx, fc->addr + CHIP_INDEX);
+	return inb(fc->addr + CHIP_WINDOW + (offset & 0xf));
+}
+
+static void
+WriteISAC_V1(void *p, u8 offset, u8 value)
+{
+	struct fritzcard *fc = p;
+	u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
+
+	outb(idx, fc->addr + CHIP_INDEX);
+	outb(value, fc->addr + CHIP_WINDOW + (offset & 0xf));
+}
+
+static void
+ReadFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
+{
+	struct fritzcard *fc = p;
+
+	outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
+	insb(fc->addr + CHIP_WINDOW, data, size);
+}
+
+static void
+WriteFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
+{
+	struct fritzcard *fc = p;
+
+	outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
+	outsb(fc->addr + CHIP_WINDOW, data, size);
+}
+
+static u8
+ReadISAC_V2(void *p, u8 offset)
+{
+	struct fritzcard *fc = p;
+
+	outl(offset, fc->addr + AVM_ISACX_INDEX);
+	return 0xff & inl(fc->addr + AVM_ISACX_DATA);
+}
+
+static void
+WriteISAC_V2(void *p, u8 offset, u8 value)
+{
+	struct fritzcard *fc = p;
+
+	outl(offset, fc->addr + AVM_ISACX_INDEX);
+	outl(value, fc->addr + AVM_ISACX_DATA);
+}
+
+static void
+ReadFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
+{
+	struct fritzcard *fc = p;
+	int i;
+
+	outl(off, fc->addr + AVM_ISACX_INDEX);
+	for (i = 0; i < size; i++)
+		data[i] = 0xff & inl(fc->addr + AVM_ISACX_DATA);
+}
+
+static void
+WriteFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
+{
+	struct fritzcard *fc = p;
+	int i;
+
+	outl(off, fc->addr + AVM_ISACX_INDEX);
+	for (i = 0; i < size; i++)
+		outl(data[i], fc->addr + AVM_ISACX_DATA);
+}
+
+static struct bchannel *
+Sel_BCS(struct fritzcard *fc, u32 channel)
+{
+	if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) &&
+		(fc->bch[0].nr & channel))
+		return &fc->bch[0];
+	else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) &&
+		(fc->bch[1].nr & channel))
+		return &fc->bch[1];
+	else
+		return NULL;
+}
+
+static inline void
+__write_ctrl_pci(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
+	u32 idx = channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1;
+
+	outl(idx, fc->addr + CHIP_INDEX);
+	outl(hdlc->ctrl.ctrl, fc->addr + CHIP_WINDOW + HDLC_STATUS);
+}
+
+static inline void
+__write_ctrl_pciv2(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
+	outl(hdlc->ctrl.ctrl, fc->addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
+		AVM_HDLC_STATUS_1));
+}
+
+void
+write_ctrl(struct bchannel *bch, int which) {
+	struct fritzcard *fc = bch->hw;
+	struct hdlc_hw *hdlc;
+
+	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
+	pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc->name, '@' + bch->nr,
+		which, hdlc->ctrl.ctrl);
+	switch (fc->type) {
+	case AVM_FRITZ_PCIV2:
+		__write_ctrl_pciv2(fc, hdlc, bch->nr);
+		break;
+	case AVM_FRITZ_PCI:
+		__write_ctrl_pci(fc, hdlc, bch->nr);
+		break;
+	}
+}
+
+
+static inline u32
+__read_status_pci(u_long addr, u32 channel)
+{
+	outl(channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1, addr + CHIP_INDEX);
+	return inl(addr + CHIP_WINDOW + HDLC_STATUS);
+}
+
+static inline u32
+__read_status_pciv2(u_long addr, u32 channel)
+{
+	return inl(addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
+		AVM_HDLC_STATUS_1));
+}
+
+
+static u32
+read_status(struct fritzcard *fc, u32 channel)
+{
+	switch (fc->type) {
+	case AVM_FRITZ_PCIV2:
+		return __read_status_pciv2(fc->addr, channel);
+	case AVM_FRITZ_PCI:
+		return __read_status_pci(fc->addr, channel);
+	}
+	/* dummy */
+	return 0;
+}
+
+static void
+enable_hwirq(struct fritzcard *fc)
+{
+	fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
+	outb(fc->ctrlreg, fc->addr + 2);
+}
+
+static void
+disable_hwirq(struct fritzcard *fc)
+{
+	fc->ctrlreg &= ~AVM_STATUS0_ENA_IRQ;
+	outb(fc->ctrlreg, fc->addr + 2);
+}
+
+static int
+modehdlc(struct bchannel *bch, int protocol)
+{
+	struct fritzcard *fc = bch->hw;
+	struct hdlc_hw *hdlc;
+
+	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
+	pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name,
+		'@' + bch->nr, bch->state, protocol, bch->nr);
+	hdlc->ctrl.ctrl = 0;
+	switch (protocol) {
+	case -1: /* used for init */
+		bch->state = -1;
+	case ISDN_P_NONE:
+		if (bch->state == ISDN_P_NONE)
+			break;
+		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
+		hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
+		write_ctrl(bch, 5);
+		bch->state = ISDN_P_NONE;
+		test_and_clear_bit(FLG_HDLC, &bch->Flags);
+		test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
+		break;
+	case ISDN_P_B_RAW:
+		bch->state = protocol;
+		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
+		hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
+		write_ctrl(bch, 5);
+		hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
+		write_ctrl(bch, 1);
+		hdlc->ctrl.sr.cmd = 0;
+		test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
+		break;
+	case ISDN_P_B_HDLC:
+		bch->state = protocol;
+		hdlc->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;
+		hdlc->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
+		write_ctrl(bch, 5);
+		hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
+		write_ctrl(bch, 1);
+		hdlc->ctrl.sr.cmd = 0;
+		test_and_set_bit(FLG_HDLC, &bch->Flags);
+		break;
+	default:
+		pr_info("%s: protocol not known %x\n", fc->name, protocol);
+		return -ENOPROTOOPT;
+	}
+	return 0;
+}
+
+static void
+hdlc_empty_fifo(struct bchannel *bch, int count)
+{
+	u32 *ptr;
+	u8 *p;
+	u32  val, addr;
+	int cnt = 0;
+	struct fritzcard *fc = bch->hw;
+
+	pr_debug("%s: %s %d\n", fc->name, __func__, count);
+	if (!bch->rx_skb) {
+		bch->rx_skb = mI_alloc_skb(bch->maxlen, GFP_ATOMIC);
+		if (!bch->rx_skb) {
+			pr_info("%s: B receive out of memory\n",
+				fc->name);
+			return;
+		}
+	}
+	if ((bch->rx_skb->len + count) > bch->maxlen) {
+		pr_debug("%s: overrun %d\n", fc->name,
+			bch->rx_skb->len + count);
+		return;
+	}
+	p = skb_put(bch->rx_skb, count);
+	ptr = (u32 *)p;
+	if (AVM_FRITZ_PCIV2 == fc->type)
+		addr = fc->addr + (bch->nr == 2 ?
+			AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
+	else {
+		addr = fc->addr + CHIP_WINDOW;
+		outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr);
+	}
+	while (cnt < count) {
+		val = le32_to_cpu(inl(addr));
+		put_unaligned(val, ptr);
+		ptr++;
+		cnt += 4;
+	}
+	if (debug & DEBUG_HW_BFIFO) {
+		snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
+			bch->nr, fc->name, count);
+		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
+	}
+}
+
+static void
+hdlc_fill_fifo(struct bchannel *bch)
+{
+	struct fritzcard *fc = bch->hw;
+	struct hdlc_hw *hdlc;
+	int count, cnt = 0;
+	u8 *p;
+	u32 *ptr, val, addr;
+
+	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
+	if (!bch->tx_skb)
+		return;
+	count = bch->tx_skb->len - bch->tx_idx;
+	if (count <= 0)
+		return;
+	p = bch->tx_skb->data + bch->tx_idx;
+	hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
+	if (count > HDLC_FIFO_SIZE) {
+		count = HDLC_FIFO_SIZE;
+	} else {
+		if (test_bit(FLG_HDLC, &bch->Flags))
+			hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
+	}
+	pr_debug("%s: %s %d/%d/%d", fc->name, __func__, count,
+		bch->tx_idx, bch->tx_skb->len);
+	ptr = (u32 *)p;
+	bch->tx_idx += count;
+	hdlc->ctrl.sr.xml = ((count == HDLC_FIFO_SIZE) ? 0 : count);
+	if (AVM_FRITZ_PCIV2 == fc->type) {
+		__write_ctrl_pciv2(fc, hdlc, bch->nr);
+		addr = fc->addr + (bch->nr == 2 ?
+			AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
+	} else {
+		__write_ctrl_pci(fc, hdlc, bch->nr);
+		addr = fc->addr + CHIP_WINDOW;
+	}
+	while (cnt < count) {
+		val = get_unaligned(ptr);
+		outl(cpu_to_le32(val), addr);
+		ptr++;
+		cnt += 4;
+	}
+	if (debug & DEBUG_HW_BFIFO) {
+		snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ",
+			bch->nr, fc->name, count);
+		print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
+	}
+}
+
+static void
+HDLC_irq_xpr(struct bchannel *bch)
+{
+	if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
+		hdlc_fill_fifo(bch);
+	else {
+		if (bch->tx_skb) {
+			/* send confirm, on trans, free on hdlc. */
+			if (test_bit(FLG_TRANSPARENT, &bch->Flags))
+				confirm_Bsend(bch);
+			dev_kfree_skb(bch->tx_skb);
+		}
+		if (get_next_bframe(bch))
+			hdlc_fill_fifo(bch);
+	}
+}
+
+static void
+HDLC_irq(struct bchannel *bch, u32 stat)
+{
+	struct fritzcard *fc = bch->hw;
+	int		len;
+	struct hdlc_hw	*hdlc;
+
+	hdlc = &fc->hdlc[(bch->nr - 1) & 1];
+	pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat);
+	if (stat & HDLC_INT_RPR) {
+		if (stat & HDLC_STAT_RDO) {
+			hdlc->ctrl.sr.xml = 0;
+			hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS;
+			write_ctrl(bch, 1);
+			hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
+			write_ctrl(bch, 1);
+			if (bch->rx_skb)
+				skb_trim(bch->rx_skb, 0);
+		} else {
+			len = (stat & HDLC_STAT_RML_MASK) >> 8;
+			if (!len)
+				len = 32;
+			hdlc_empty_fifo(bch, len);
+			if (!bch->rx_skb)
+				goto handle_tx;
+			if ((stat & HDLC_STAT_RME) || test_bit(FLG_TRANSPARENT,
+			    &bch->Flags)) {
+				if (((stat & HDLC_STAT_CRCVFRRAB) ==
+				    HDLC_STAT_CRCVFR) ||
+				    test_bit(FLG_TRANSPARENT, &bch->Flags)) {
+					recv_Bchannel(bch, 0);
+				} else {
+					pr_debug("%s: got invalid frame\n",
+						fc->name);
+					skb_trim(bch->rx_skb, 0);
+				}
+			}
+		}
+	}
+handle_tx:
+	if (stat & HDLC_INT_XDU) {
+		/* Here we lost an TX interrupt, so
+		 * restart transmitting the whole frame on HDLC
+		 * in transparent mode we send the next data
+		 */
+		if (bch->tx_skb)
+			pr_debug("%s: ch%d XDU len(%d) idx(%d) Flags(%lx)\n",
+				fc->name, bch->nr, bch->tx_skb->len,
+				bch->tx_idx, bch->Flags);
+		else
+			pr_debug("%s: ch%d XDU no tx_skb Flags(%lx)\n",
+				fc->name, bch->nr, bch->Flags);
+		if (bch->tx_skb && bch->tx_skb->len) {
+			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
+				bch->tx_idx = 0;
+		}
+		hdlc->ctrl.sr.xml = 0;
+		hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS;
+		write_ctrl(bch, 1);
+		hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
+		HDLC_irq_xpr(bch);
+		return;
+	} else if (stat & HDLC_INT_XPR)
+		HDLC_irq_xpr(bch);
+}
+
+static inline void
+HDLC_irq_main(struct fritzcard *fc)
+{
+	u32 stat;
+	struct bchannel *bch;
+
+	stat = read_status(fc, 1);
+	if (stat & HDLC_INT_MASK) {
+		bch = Sel_BCS(fc, 1);
+		if (bch)
+			HDLC_irq(bch, stat);
+		else
+			pr_debug("%s: spurious ch1 IRQ\n", fc->name);
+	}
+	stat = read_status(fc, 2);
+	if (stat & HDLC_INT_MASK) {
+		bch = Sel_BCS(fc, 2);
+		if (bch)
+			HDLC_irq(bch, stat);
+		else
+			pr_debug("%s: spurious ch2 IRQ\n", fc->name);
+	}
+}
+
+static irqreturn_t
+avm_fritz_interrupt(int intno, void *dev_id)
+{
+	struct fritzcard *fc = dev_id;
+	u8 val;
+	u8 sval;
+
+	spin_lock(&fc->lock);
+	sval = inb(fc->addr + 2);
+	pr_debug("%s: irq stat0 %x\n", fc->name, sval);
+	if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
+		/* shared  IRQ from other HW */
+		spin_unlock(&fc->lock);
+		return IRQ_NONE;
+	}
+	fc->irqcnt++;
+
+	if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
+		val = ReadISAC_V1(fc, ISAC_ISTA);
+		mISDNisac_irq(&fc->isac, val);
+	}
+	if (!(sval & AVM_STATUS0_IRQ_HDLC))
+		HDLC_irq_main(fc);
+	spin_unlock(&fc->lock);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+avm_fritzv2_interrupt(int intno, void *dev_id)
+{
+	struct fritzcard *fc = dev_id;
+	u8 val;
+	u8 sval;
+
+	spin_lock(&fc->lock);
+	sval = inb(fc->addr + 2);
+	pr_debug("%s: irq stat0 %x\n", fc->name, sval);
+	if (!(sval & AVM_STATUS0_IRQ_MASK)) {
+		/* shared  IRQ from other HW */
+		spin_unlock(&fc->lock);
+		return IRQ_NONE;
+	}
+	fc->irqcnt++;
+
+	if (sval & AVM_STATUS0_IRQ_HDLC)
+		HDLC_irq_main(fc);
+	if (sval & AVM_STATUS0_IRQ_ISAC) {
+		val = ReadISAC_V2(fc, ISACX_ISTA);
+		mISDNisac_irq(&fc->isac, val);
+	}
+	if (sval & AVM_STATUS0_IRQ_TIMER) {
+		pr_debug("%s: timer irq\n", fc->name);
+		outb(fc->ctrlreg | AVM_STATUS0_RES_TIMER, fc->addr + 2);
+		udelay(1);
+		outb(fc->ctrlreg, fc->addr + 2);
+	}
+	spin_unlock(&fc->lock);
+	return IRQ_HANDLED;
+}
+
+static int
+avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct fritzcard *fc = bch->hw;
+	int ret = -EINVAL;
+	struct mISDNhead *hh = mISDN_HEAD_P(skb);
+	u32 id;
+	u_long flags;
+
+	switch (hh->prim) {
+	case PH_DATA_REQ:
+		spin_lock_irqsave(&fc->lock, flags);
+		ret = bchannel_senddata(bch, skb);
+		if (ret > 0) { /* direct TX */
+			id = hh->id; /* skb can be freed */
+			hdlc_fill_fifo(bch);
+			ret = 0;
+			spin_unlock_irqrestore(&fc->lock, flags);
+			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
+				queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
+		} else
+			spin_unlock_irqrestore(&fc->lock, flags);
+		return ret;
+	case PH_ACTIVATE_REQ:
+		spin_lock_irqsave(&fc->lock, flags);
+		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
+			ret = modehdlc(bch, ch->protocol);
+		else
+			ret = 0;
+		spin_unlock_irqrestore(&fc->lock, flags);
+		if (!ret)
+			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
+				NULL, GFP_KERNEL);
+		break;
+	case PH_DEACTIVATE_REQ:
+		spin_lock_irqsave(&fc->lock, flags);
+		mISDN_clear_bchannel(bch);
+		modehdlc(bch, ISDN_P_NONE);
+		spin_unlock_irqrestore(&fc->lock, flags);
+		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
+			NULL, GFP_KERNEL);
+		ret = 0;
+		break;
+	}
+	if (!ret)
+		dev_kfree_skb(skb);
+	return ret;
+}
+
+static void
+inithdlc(struct fritzcard *fc)
+{
+	modehdlc(&fc->bch[0], -1);
+	modehdlc(&fc->bch[1], -1);
+}
+
+void
+clear_pending_hdlc_ints(struct fritzcard *fc)
+{
+	u32 val;
+
+	val = read_status(fc, 1);
+	pr_debug("%s: HDLC 1 STA %x\n", fc->name, val);
+	val = read_status(fc, 2);
+	pr_debug("%s: HDLC 2 STA %x\n", fc->name, val);
+}
+
+static void
+reset_avm(struct fritzcard *fc)
+{
+	switch (fc->type) {
+	case AVM_FRITZ_PCI:
+		fc->ctrlreg = AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER;
+		break;
+	case AVM_FRITZ_PCIV2:
+		fc->ctrlreg = AVM_STATUS0_RESET;
+		break;
+	}
+	if (debug & DEBUG_HW)
+		pr_notice("%s: reset\n", fc->name);
+	disable_hwirq(fc);
+	mdelay(5);
+	switch (fc->type) {
+	case AVM_FRITZ_PCI:
+		fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER;
+		disable_hwirq(fc);
+		outb(AVM_STATUS1_ENA_IOM, fc->addr + 3);
+		break;
+	case AVM_FRITZ_PCIV2:
+		fc->ctrlreg = 0;
+		disable_hwirq(fc);
+		break;
+	}
+	mdelay(1);
+	if (debug & DEBUG_HW)
+		pr_notice("%s: S0/S1 %x/%x\n", fc->name,
+			inb(fc->addr + 2), inb(fc->addr + 3));
+}
+
+static int
+init_card(struct fritzcard *fc)
+{
+	int		ret, cnt = 3;
+	u_long		flags;
+
+	reset_avm(fc); /* disable IRQ */
+	if (fc->type == AVM_FRITZ_PCIV2)
+		ret = request_irq(fc->irq, avm_fritzv2_interrupt,
+			IRQF_SHARED, fc->name, fc);
+	else
+		ret = request_irq(fc->irq, avm_fritz_interrupt,
+			IRQF_SHARED, fc->name, fc);
+	if (ret) {
+		pr_info("%s: couldn't get interrupt %d\n",
+			fc->name, fc->irq);
+		return ret;
+	}
+	while (cnt--) {
+		spin_lock_irqsave(&fc->lock, flags);
+		ret = fc->isac.init(&fc->isac);
+		if (ret) {
+			spin_unlock_irqrestore(&fc->lock, flags);
+			pr_info("%s: ISAC init failed with %d\n",
+				fc->name, ret);
+			break;
+		}
+		clear_pending_hdlc_ints(fc);
+		inithdlc(fc);
+		enable_hwirq(fc);
+		/* RESET Receiver and Transmitter */
+		if (AVM_FRITZ_PCIV2 == fc->type) {
+			WriteISAC_V2(fc, ISACX_MASK, 0);
+			WriteISAC_V2(fc, ISACX_CMDRD, 0x41);
+		} else {
+			WriteISAC_V1(fc, ISAC_MASK, 0);
+			WriteISAC_V1(fc, ISAC_CMDR, 0x41);
+		}
+		spin_unlock_irqrestore(&fc->lock, flags);
+		/* Timeout 10ms */
+		msleep_interruptible(10);
+		if (debug & DEBUG_HW)
+			pr_notice("%s: IRQ %d count %d\n", fc->name,
+				fc->irq, fc->irqcnt);
+		if (!fc->irqcnt) {
+			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
+				fc->name, fc->irq, 3 - cnt);
+			reset_avm(fc);
+		} else
+			return 0;
+	}
+	free_irq(fc->irq, fc);
+	return -EIO;
+}
+
+static int
+channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
+{
+	int ret = 0;
+	struct fritzcard *fc = bch->hw;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = 0;
+		break;
+	/* Nothing implemented yet */
+	case MISDN_CTRL_FILL_EMPTY:
+	default:
+		pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct fritzcard *fc = bch->hw;
+	int ret = -EINVAL;
+	u_long flags;
+
+	pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
+	switch (cmd) {
+	case CLOSE_CHANNEL:
+		test_and_clear_bit(FLG_OPEN, &bch->Flags);
+		if (test_bit(FLG_ACTIVE, &bch->Flags)) {
+			spin_lock_irqsave(&fc->lock, flags);
+			mISDN_freebchannel(bch);
+			test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
+			test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
+			modehdlc(bch, ISDN_P_NONE);
+			spin_unlock_irqrestore(&fc->lock, flags);
+		}
+		ch->protocol = ISDN_P_NONE;
+		ch->peer = NULL;
+		module_put(THIS_MODULE);
+		ret = 0;
+		break;
+	case CONTROL_CHANNEL:
+		ret = channel_bctrl(bch, arg);
+		break;
+	default:
+		pr_info("%s: %s unknown prim(%x)\n", fc->name, __func__, cmd);
+	}
+	return ret;
+}
+
+static int
+channel_ctrl(struct fritzcard  *fc, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = MISDN_CTRL_LOOP;
+		break;
+	case MISDN_CTRL_LOOP:
+		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
+		if (cq->channel < 0 || cq->channel > 3) {
+			ret = -EINVAL;
+			break;
+		}
+		ret = fc->isac.ctrl(&fc->isac, HW_TESTLOOP, cq->channel);
+		break;
+	default:
+		pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+open_bchannel(struct fritzcard *fc, struct channel_req *rq)
+{
+	struct bchannel		*bch;
+
+	if (rq->adr.channel > 2)
+		return -EINVAL;
+	if (rq->protocol == ISDN_P_NONE)
+		return -EINVAL;
+	bch = &fc->bch[rq->adr.channel - 1];
+	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
+		return -EBUSY; /* b-channel can be only open once */
+	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
+	bch->ch.protocol = rq->protocol;
+	rq->ch = &bch->ch;
+	return 0;
+}
+
+/*
+ * device control function
+ */
+static int
+avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
+	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
+	struct fritzcard	*fc = dch->hw;
+	struct channel_req	*rq;
+	int			err = 0;
+
+	pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
+	switch (cmd) {
+	case OPEN_CHANNEL:
+		rq = arg;
+		if (rq->protocol == ISDN_P_TE_S0)
+			err = fc->isac.open(&fc->isac, rq);
+		else
+			err = open_bchannel(fc, rq);
+		if (err)
+			break;
+		if (!try_module_get(THIS_MODULE))
+			pr_info("%s: cannot get module\n", fc->name);
+		break;
+	case CLOSE_CHANNEL:
+		pr_debug("%s: dev(%d) close from %p\n", fc->name, dch->dev.id,
+			__builtin_return_address(0));
+		module_put(THIS_MODULE);
+		break;
+	case CONTROL_CHANNEL:
+		err = channel_ctrl(fc, arg);
+		break;
+	default:
+		pr_debug("%s: %s unknown command %x\n",
+			fc->name, __func__, cmd);
+		return -EINVAL;
+	}
+	return err;
+}
+
+int
+setup_fritz(struct fritzcard *fc)
+{
+	u32 val, ver;
+
+	if (!request_region(fc->addr, 32, fc->name)) {
+		pr_info("%s: AVM config port %x-%x already in use\n",
+			fc->name, fc->addr, fc->addr + 31);
+		return -EIO;
+	}
+	switch (fc->type) {
+	case AVM_FRITZ_PCI:
+		val = inl(fc->addr);
+		outl(AVM_HDLC_1, fc->addr + CHIP_INDEX);
+		ver = inl(fc->addr + CHIP_WINDOW + HDLC_STATUS) >> 24;
+		if (debug & DEBUG_HW) {
+			pr_notice("%s: PCI stat %#x\n", fc->name, val);
+			pr_notice("%s: PCI Class %X Rev %d\n", fc->name,
+				val & 0xff, (val >> 8) & 0xff);
+			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
+		}
+		ASSIGN_FUNC(V1, ISAC, fc->isac);
+		fc->isac.type = IPAC_TYPE_ISAC;
+		break;
+	case AVM_FRITZ_PCIV2:
+		val = inl(fc->addr);
+		ver = inl(fc->addr + AVM_HDLC_STATUS_1) >> 24;
+		if (debug & DEBUG_HW) {
+			pr_notice("%s: PCI V2 stat %#x\n", fc->name, val);
+			pr_notice("%s: PCI V2 Class %X Rev %d\n", fc->name,
+				val & 0xff, (val>>8) & 0xff);
+			pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
+		}
+		ASSIGN_FUNC(V2, ISAC, fc->isac);
+		fc->isac.type = IPAC_TYPE_ISACX;
+		break;
+	default:
+		release_region(fc->addr, 32);
+		pr_info("%s: AVM unknown type %d\n", fc->name, fc->type);
+		return -ENODEV;
+	}
+	pr_notice("%s: %s config irq:%d base:0x%X\n", fc->name,
+		(fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" :
+		"AVM Fritz!CARD PCIv2", fc->irq, fc->addr);
+	return 0;
+}
+
+static void
+release_card(struct fritzcard *card)
+{
+	u_long flags;
+
+	disable_hwirq(card);
+	spin_lock_irqsave(&card->lock, flags);
+	modehdlc(&card->bch[0], ISDN_P_NONE);
+	modehdlc(&card->bch[1], ISDN_P_NONE);
+	spin_unlock_irqrestore(&card->lock, flags);
+	card->isac.release(&card->isac);
+	free_irq(card->irq, card);
+	mISDN_freebchannel(&card->bch[1]);
+	mISDN_freebchannel(&card->bch[0]);
+	mISDN_unregister_device(&card->isac.dch.dev);
+	release_region(card->addr, 32);
+	pci_disable_device(card->pdev);
+	pci_set_drvdata(card->pdev, NULL);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	kfree(card);
+	AVM_cnt--;
+}
+
+static int __devinit
+setup_instance(struct fritzcard *card)
+{
+	int i, err;
+	u_long flags;
+
+	snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1);
+	write_lock_irqsave(&card_lock, flags);
+	list_add_tail(&card->list, &Cards);
+	write_unlock_irqrestore(&card_lock, flags);
+
+	_set_debug(card);
+	card->isac.name = card->name;
+	spin_lock_init(&card->lock);
+	card->isac.hwlock = &card->lock;
+	mISDNisac_init(&card->isac, card);
+
+	card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
+	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+	card->isac.dch.dev.D.ctrl = avm_dctrl;
+	for (i = 0; i < 2; i++) {
+		card->bch[i].nr = i + 1;
+		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
+		mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM);
+		card->bch[i].hw = card;
+		card->bch[i].ch.send = avm_l2l1B;
+		card->bch[i].ch.ctrl = avm_bctrl;
+		card->bch[i].ch.nr = i + 1;
+		list_add(&card->bch[i].ch.list, &card->isac.dch.dev.bchannels);
+	}
+	err = setup_fritz(card);
+	if (err)
+		goto error;
+	err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
+		card->name);
+	if (err)
+		goto error_reg;
+	err = init_card(card);
+	if (!err)  {
+		AVM_cnt++;
+		pr_notice("AVM %d cards installed DEBUG\n", AVM_cnt);
+		return 0;
+	}
+	mISDN_unregister_device(&card->isac.dch.dev);
+error_reg:
+	release_region(card->addr, 32);
+error:
+	card->isac.release(&card->isac);
+	mISDN_freebchannel(&card->bch[1]);
+	mISDN_freebchannel(&card->bch[0]);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	kfree(card);
+	return err;
+}
+
+static int __devinit
+fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int err = -ENOMEM;
+	struct fritzcard *card;
+
+	card = kzalloc(sizeof(struct fritzcard), GFP_KERNEL);
+	if (!card) {
+		pr_info("No kmem for fritzcard\n");
+		return err;
+	}
+	if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
+		card->type = AVM_FRITZ_PCIV2;
+	else
+		card->type = AVM_FRITZ_PCI;
+	card->pdev = pdev;
+	err = pci_enable_device(pdev);
+	if (err) {
+		kfree(card);
+		return err;
+	}
+
+	pr_notice("mISDN: found adapter %s at %s\n",
+	       (char *) ent->driver_data, pci_name(pdev));
+
+	card->addr = pci_resource_start(pdev, 1);
+	card->irq = pdev->irq;
+	pci_set_drvdata(pdev, card);
+	err = setup_instance(card);
+	if (err)
+		pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void __devexit
+fritz_remove_pci(struct pci_dev *pdev)
+{
+	struct fritzcard *card = pci_get_drvdata(pdev);
+
+	if (card)
+		release_card(card);
+	else
+		if (debug)
+			pr_info("%s: drvdata allready removed\n", __func__);
+}
+
+static struct pci_device_id fcpci_ids[] __devinitdata = {
+	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID,
+	  0, 0, (unsigned long) "Fritz!Card PCI"},
+	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
+	  0, 0, (unsigned long) "Fritz!Card PCI v2" },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, fcpci_ids);
+
+static struct pci_driver fcpci_driver = {
+	.name = "fcpci",
+	.probe = fritzpci_probe,
+	.remove = __devexit_p(fritz_remove_pci),
+	.id_table = fcpci_ids,
+};
+
+static int __init AVM_init(void)
+{
+	int err;
+
+	pr_notice("AVM Fritz PCI driver Rev. %s\n", AVMFRITZ_REV);
+	err = pci_register_driver(&fcpci_driver);
+	return err;
+}
+
+static void __exit AVM_cleanup(void)
+{
+	pci_unregister_driver(&fcpci_driver);
+}
+
+module_init(AVM_init);
+module_exit(AVM_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index e1dab30..faed794 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -3416,22 +3416,8 @@ deactivate_bchannel(struct bchannel *bch)
 	u_long			flags;
 
 	spin_lock_irqsave(&hc->lock, flags);
-	if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) {
-		dev_kfree_skb(bch->next_skb);
-		bch->next_skb = NULL;
-	}
-	if (bch->tx_skb) {
-		dev_kfree_skb(bch->tx_skb);
-		bch->tx_skb = NULL;
-	}
-	bch->tx_idx = 0;
-	if (bch->rx_skb) {
-		dev_kfree_skb(bch->rx_skb);
-		bch->rx_skb = NULL;
-	}
+	mISDN_clear_bchannel(bch);
 	hc->chan[bch->slot].coeff_count = 0;
-	test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
-	test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
 	hc->chan[bch->slot].rx_off = 0;
 	hc->chan[bch->slot].conf = -1;
 	mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0);
@@ -5384,9 +5370,10 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	    ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
 	    ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
 		printk(KERN_ERR
-		    "Unknown HFC multiport controller (vendor:%x device:%x "
-		    "subvendor:%x subdevice:%x)\n", ent->vendor, ent->device,
-		    ent->subvendor, ent->subdevice);
+		    "Unknown HFC multiport controller (vendor:%04x device:%04x "
+		    "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
+		    pdev->device, pdev->subsystem_vendor,
+		    pdev->subsystem_device);
 		printk(KERN_ERR
 		    "Please contact the driver maintainer for support.\n");
 		return -ENODEV;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 228ffbe..70e6b0e 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -1522,22 +1522,8 @@ deactivate_bchannel(struct bchannel *bch)
 	u_long		flags;
 
 	spin_lock_irqsave(&hc->lock, flags);
-	if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) {
-		dev_kfree_skb(bch->next_skb);
-		bch->next_skb = NULL;
-	}
-	if (bch->tx_skb) {
-		dev_kfree_skb(bch->tx_skb);
-		bch->tx_skb = NULL;
-	}
-	bch->tx_idx = 0;
-	if (bch->rx_skb) {
-		dev_kfree_skb(bch->rx_skb);
-		bch->rx_skb = NULL;
-	}
+	mISDN_clear_bchannel(bch);
 	mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
-	test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
-	test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
 	spin_unlock_irqrestore(&hc->lock, flags);
 }
 
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 6b7704c..fc46a26 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -1809,21 +1809,7 @@ deactivate_bchannel(struct bchannel *bch)
 		    hw->name, __func__, bch->nr);
 
 	spin_lock_irqsave(&hw->lock, flags);
-	if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) {
-		dev_kfree_skb(bch->next_skb);
-		bch->next_skb = NULL;
-	}
-	if (bch->tx_skb) {
-		dev_kfree_skb(bch->tx_skb);
-		bch->tx_skb = NULL;
-	}
-	bch->tx_idx = 0;
-	if (bch->rx_skb) {
-		dev_kfree_skb(bch->rx_skb);
-		bch->rx_skb = NULL;
-	}
-	clear_bit(FLG_ACTIVE, &bch->Flags);
-	clear_bit(FLG_TX_BUSY, &bch->Flags);
+	mISDN_clear_bchannel(bch);
 	spin_unlock_irqrestore(&hw->lock, flags);
 	hfcsusb_setup_bch(bch, ISDN_P_NONE);
 	hfcsusb_stop_endpoint(hw, bch->nr);
diff --git a/drivers/isdn/hardware/mISDN/iohelper.h b/drivers/isdn/hardware/mISDN/iohelper.h
new file mode 100644
index 0000000..b438981
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/iohelper.h
@@ -0,0 +1,109 @@
+/*
+ * iohelper.h
+ *		helper for define functions to access ISDN hardware
+ *              supported are memory mapped IO
+ *		indirect port IO (one port for address, one for data)
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _IOHELPER_H
+#define _IOHELPER_H
+
+typedef	u8	(read_reg_func)(void *hwp, u8 offset);
+typedef	void	(write_reg_func)(void *hwp, u8 offset, u8 value);
+typedef	void	(fifo_func)(void *hwp, u8 offset, u8 *datap, int size);
+
+struct _ioport {
+	u32	port;
+	u32	ale;
+};
+
+#define IOFUNC_IO(name, hws, ap) \
+	static u8 Read##name##_IO(void *p, u8 off) {\
+		struct hws *hw = p;\
+		return inb(hw->ap.port + off);\
+	} \
+	static void Write##name##_IO(void *p, u8 off, u8 val) {\
+		struct hws *hw = p;\
+		outb(val, hw->ap.port + off);\
+	} \
+	static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) {\
+		struct hws *hw = p;\
+		insb(hw->ap.port + off, dp, size);\
+	} \
+	static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) {\
+		struct hws *hw = p;\
+		outsb(hw->ap.port + off, dp, size);\
+	}
+
+#define IOFUNC_IND(name, hws, ap) \
+	static u8 Read##name##_IND(void *p, u8 off) {\
+		struct hws *hw = p;\
+		outb(off, hw->ap.ale);\
+		return inb(hw->ap.port);\
+	} \
+	static void Write##name##_IND(void *p, u8 off, u8 val) {\
+		struct hws *hw = p;\
+		outb(off, hw->ap.ale);\
+		outb(val, hw->ap.port);\
+	} \
+	static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) {\
+		struct hws *hw = p;\
+		outb(off, hw->ap.ale);\
+		insb(hw->ap.port, dp, size);\
+	} \
+	static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) {\
+		struct hws *hw = p;\
+		outb(off, hw->ap.ale);\
+		outsb(hw->ap.port, dp, size);\
+	}
+
+#define IOFUNC_MEMIO(name, hws, typ, adr) \
+	static u8 Read##name##_MIO(void *p, u8 off) {\
+		struct hws *hw = p;\
+		return readb(((typ *)hw->adr) + off);\
+	} \
+	static void Write##name##_MIO(void *p, u8 off, u8 val) {\
+		struct hws *hw = p;\
+		writeb(val, ((typ *)hw->adr) + off);\
+	} \
+	static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) {\
+		struct hws *hw = p;\
+		while (size--)\
+			*dp++ = readb(((typ *)hw->adr) + off);\
+	} \
+	static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) {\
+		struct hws *hw = p;\
+		while (size--)\
+			writeb(*dp++, ((typ *)hw->adr) + off);\
+	}
+
+#define ASSIGN_FUNC(typ, name, dest)	do {\
+	dest.read_reg = &Read##name##_##typ;\
+	dest.write_reg = &Write##name##_##typ;\
+	dest.read_fifo = &ReadFiFo##name##_##typ;\
+	dest.write_fifo = &WriteFiFo##name##_##typ;\
+	} while (0)
+#define ASSIGN_FUNC_IPAC(typ, target)	do {\
+	ASSIGN_FUNC(typ, ISAC, target.isac);\
+	ASSIGN_FUNC(typ, IPAC, target);\
+	} while (0)
+
+#endif
diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h
new file mode 100644
index 0000000..74a6ccf
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/ipac.h
@@ -0,0 +1,405 @@
+/*
+ *
+ * ipac.h	Defines for the Infineon (former Siemens) ISDN
+ *		chip series
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "iohelper.h"
+
+struct isac_hw {
+	struct dchannel		dch;
+	u32			type;
+	u32			off;		/* offset to isac regs */
+	char			*name;
+	spinlock_t		*hwlock;	/* lock HW acccess */
+	read_reg_func		*read_reg;
+	write_reg_func		*write_reg;
+	fifo_func		*read_fifo;
+	fifo_func		*write_fifo;
+	int			(*monitor)(void *, u32, u8 *, int);
+	void			(*release)(struct isac_hw *);
+	int			(*init)(struct isac_hw *);
+	int			(*ctrl)(struct isac_hw *, u32, u_long);
+	int			(*open)(struct isac_hw *, struct channel_req *);
+	u8			*mon_tx;
+	u8			*mon_rx;
+	int			mon_txp;
+	int			mon_txc;
+	int			mon_rxp;
+	struct arcofi_msg	*arcofi_list;
+	struct timer_list	arcofitimer;
+	wait_queue_head_t	arcofi_wait;
+	u8			arcofi_bc;
+	u8			arcofi_state;
+	u8			mocr;
+	u8			adf2;
+	u8			state;
+};
+
+struct ipac_hw;
+
+struct hscx_hw {
+	struct bchannel		bch;
+	struct ipac_hw		*ip;
+	u8			fifo_size;
+	u8			off;	/* offset to ICA or ICB */
+	u8			slot;
+	char			log[64];
+};
+
+struct ipac_hw {
+	struct isac_hw		isac;
+	struct hscx_hw		hscx[2];
+	char			*name;
+	void			*hw;
+	spinlock_t		*hwlock;	/* lock HW acccess */
+	struct module		*owner;
+	u32			type;
+	read_reg_func		*read_reg;
+	write_reg_func		*write_reg;
+	fifo_func		*read_fifo;
+	fifo_func		*write_fifo;
+	void			(*release)(struct ipac_hw *);
+	int			(*init)(struct ipac_hw *);
+	int			(*ctrl)(struct ipac_hw *, u32, u_long);
+	u8			conf;
+};
+
+#define IPAC_TYPE_ISAC		0x0010
+#define IPAC_TYPE_IPAC		0x0020
+#define IPAC_TYPE_ISACX		0x0040
+#define IPAC_TYPE_IPACX		0x0080
+#define IPAC_TYPE_HSCX		0x0100
+
+#define ISAC_USE_ARCOFI		0x1000
+
+/* Monitor functions */
+#define MONITOR_RX_0		0x1000
+#define MONITOR_RX_1		0x1001
+#define MONITOR_TX_0		0x2000
+#define MONITOR_TX_1		0x2001
+
+/* All registers original Siemens Spec  */
+/* IPAC/ISAC registers */
+#define ISAC_MASK		0x20
+#define ISAC_ISTA		0x20
+#define ISAC_STAR		0x21
+#define ISAC_CMDR		0x21
+#define ISAC_EXIR		0x24
+#define ISAC_ADF2		0x39
+#define ISAC_SPCR		0x30
+#define ISAC_ADF1		0x38
+#define ISAC_CIR0		0x31
+#define ISAC_CIX0		0x31
+#define ISAC_CIR1		0x33
+#define ISAC_CIX1		0x33
+#define ISAC_STCR		0x37
+#define ISAC_MODE		0x22
+#define ISAC_RSTA		0x27
+#define ISAC_RBCL		0x25
+#define ISAC_RBCH		0x2A
+#define ISAC_TIMR		0x23
+#define ISAC_SQXR		0x3b
+#define ISAC_SQRR		0x3b
+#define ISAC_MOSR		0x3a
+#define ISAC_MOCR		0x3a
+#define ISAC_MOR0		0x32
+#define ISAC_MOX0		0x32
+#define ISAC_MOR1		0x34
+#define ISAC_MOX1		0x34
+
+#define ISAC_RBCH_XAC		0x80
+
+#define IPAC_D_TIN2		0x01
+
+/* IPAC/HSCX */
+#define IPAC_ISTAB		0x20	/* RD	*/
+#define IPAC_MASKB		0x20	/* WR	*/
+#define IPAC_STARB		0x21	/* RD	*/
+#define IPAC_CMDRB		0x21	/* WR	*/
+#define IPAC_MODEB		0x22	/* R/W	*/
+#define IPAC_EXIRB		0x24	/* RD	*/
+#define IPAC_RBCLB		0x25	/* RD	*/
+#define IPAC_RAH1		0x26	/* WR	*/
+#define IPAC_RAH2		0x27	/* WR	*/
+#define IPAC_RSTAB		0x27	/* RD	*/
+#define IPAC_RAL1		0x28	/* R/W	*/
+#define IPAC_RAL2		0x29	/* WR	*/
+#define IPAC_RHCRB		0x29	/* RD	*/
+#define IPAC_XBCL		0x2A	/* WR	*/
+#define IPAC_CCR2		0x2C	/* R/W	*/
+#define IPAC_RBCHB		0x2D	/* RD	*/
+#define IPAC_XBCH		0x2D	/* WR	*/
+#define HSCX_VSTR		0x2E	/* RD	*/
+#define IPAC_RLCR		0x2E	/* WR	*/
+#define IPAC_CCR1		0x2F	/* R/W	*/
+#define IPAC_TSAX		0x30	/* WR	*/
+#define IPAC_TSAR		0x31	/* WR	*/
+#define IPAC_XCCR		0x32	/* WR	*/
+#define IPAC_RCCR		0x33	/* WR	*/
+
+/* IPAC_ISTAB/IPAC_MASKB bits */
+#define IPAC_B_XPR		0x10
+#define IPAC_B_RPF		0x40
+#define IPAC_B_RME		0x80
+#define IPAC_B_ON		0x2F
+
+/* IPAC_EXIRB bits */
+#define IPAC_B_RFS		0x04
+#define IPAC_B_RFO		0x10
+#define IPAC_B_XDU		0x40
+#define IPAC_B_XMR		0x80
+
+/* IPAC special registers */
+#define IPAC_CONF		0xC0	/* R/W	*/
+#define IPAC_ISTA		0xC1	/* RD	*/
+#define IPAC_MASK		0xC1	/* WR	*/
+#define IPAC_ID			0xC2	/* RD	*/
+#define IPAC_ACFG		0xC3	/* R/W	*/
+#define IPAC_AOE		0xC4	/* R/W	*/
+#define IPAC_ARX		0xC5	/* RD	*/
+#define IPAC_ATX		0xC5	/* WR	*/
+#define IPAC_PITA1		0xC6	/* R/W	*/
+#define IPAC_PITA2		0xC7	/* R/W	*/
+#define IPAC_POTA1		0xC8	/* R/W	*/
+#define IPAC_POTA2		0xC9	/* R/W	*/
+#define IPAC_PCFG		0xCA	/* R/W	*/
+#define IPAC_SCFG		0xCB	/* R/W	*/
+#define IPAC_TIMR2		0xCC	/* R/W	*/
+
+/* IPAC_ISTA/_MASK bits */
+#define IPAC__EXB		0x01
+#define IPAC__ICB		0x02
+#define IPAC__EXA		0x04
+#define IPAC__ICA		0x08
+#define IPAC__EXD		0x10
+#define IPAC__ICD		0x20
+#define IPAC__INT0		0x40
+#define IPAC__INT1		0x80
+#define IPAC__ON		0xC0
+
+/* HSCX ISTA/MASK bits */
+#define HSCX__EXB		0x01
+#define HSCX__EXA		0x02
+#define HSCX__ICA		0x04
+
+/* ISAC/ISACX/IPAC/IPACX L1 commands */
+#define ISAC_CMD_TIM		0x0
+#define ISAC_CMD_RS		0x1
+#define ISAC_CMD_SCZ		0x4
+#define ISAC_CMD_SSZ		0x2
+#define ISAC_CMD_AR8		0x8
+#define ISAC_CMD_AR10		0x9
+#define ISAC_CMD_ARL		0xA
+#define ISAC_CMD_DUI		0xF
+
+/* ISAC/ISACX/IPAC/IPACX L1 indications */
+#define ISAC_IND_RS		0x1
+#define ISAC_IND_PU		0x7
+#define ISAC_IND_DR		0x0
+#define ISAC_IND_SD		0x2
+#define ISAC_IND_DIS		0x3
+#define ISAC_IND_EI		0x6
+#define ISAC_IND_RSY		0x4
+#define ISAC_IND_ARD		0x8
+#define ISAC_IND_TI		0xA
+#define ISAC_IND_ATI		0xB
+#define ISAC_IND_AI8		0xC
+#define ISAC_IND_AI10		0xD
+#define ISAC_IND_DID		0xF
+
+/* the new ISACX / IPACX */
+/* D-channel registers   */
+#define ISACX_RFIFOD		0x00	/* RD	*/
+#define ISACX_XFIFOD		0x00	/* WR	*/
+#define ISACX_ISTAD		0x20	/* RD	*/
+#define ISACX_MASKD		0x20	/* WR	*/
+#define ISACX_STARD		0x21	/* RD	*/
+#define ISACX_CMDRD		0x21	/* WR	*/
+#define ISACX_MODED		0x22	/* R/W	*/
+#define ISACX_EXMD1		0x23	/* R/W	*/
+#define ISACX_TIMR1		0x24	/* R/W	*/
+#define ISACX_SAP1		0x25	/* WR	*/
+#define ISACX_SAP2		0x26	/* WR	*/
+#define ISACX_RBCLD		0x26	/* RD	*/
+#define ISACX_RBCHD		0x27	/* RD	*/
+#define ISACX_TEI1		0x27	/* WR	*/
+#define ISACX_TEI2		0x28	/* WR	*/
+#define ISACX_RSTAD		0x28	/* RD	*/
+#define ISACX_TMD		0x29	/* R/W	*/
+#define ISACX_CIR0		0x2E	/* RD	*/
+#define ISACX_CIX0		0x2E	/* WR	*/
+#define ISACX_CIR1		0x2F	/* RD	*/
+#define ISACX_CIX1		0x2F	/* WR	*/
+
+/* Transceiver registers  */
+#define ISACX_TR_CONF0		0x30	/* R/W	*/
+#define ISACX_TR_CONF1		0x31	/* R/W	*/
+#define ISACX_TR_CONF2		0x32	/* R/W	*/
+#define ISACX_TR_STA		0x33	/* RD	*/
+#define ISACX_TR_CMD		0x34	/* R/W	*/
+#define ISACX_SQRR1		0x35	/* RD	*/
+#define ISACX_SQXR1		0x35	/* WR	*/
+#define ISACX_SQRR2		0x36	/* RD	*/
+#define ISACX_SQXR2		0x36	/* WR	*/
+#define ISACX_SQRR3		0x37	/* RD	*/
+#define ISACX_SQXR3		0x37	/* WR	*/
+#define ISACX_ISTATR		0x38	/* RD	*/
+#define ISACX_MASKTR		0x39	/* R/W	*/
+#define ISACX_TR_MODE		0x3A	/* R/W	*/
+#define ISACX_ACFG1		0x3C	/* R/W	*/
+#define ISACX_ACFG2		0x3D	/* R/W	*/
+#define ISACX_AOE		0x3E	/* R/W	*/
+#define ISACX_ARX		0x3F	/* RD	*/
+#define ISACX_ATX		0x3F	/* WR	*/
+
+/* IOM: Timeslot, DPS, CDA  */
+#define ISACX_CDA10		0x40	/* R/W	*/
+#define ISACX_CDA11		0x41	/* R/W	*/
+#define ISACX_CDA20		0x42	/* R/W	*/
+#define ISACX_CDA21		0x43	/* R/W	*/
+#define ISACX_CDA_TSDP10	0x44	/* R/W	*/
+#define ISACX_CDA_TSDP11	0x45	/* R/W	*/
+#define ISACX_CDA_TSDP20	0x46	/* R/W	*/
+#define ISACX_CDA_TSDP21	0x47	/* R/W	*/
+#define ISACX_BCHA_TSDP_BC1	0x48	/* R/W	*/
+#define ISACX_BCHA_TSDP_BC2	0x49	/* R/W	*/
+#define ISACX_BCHB_TSDP_BC1	0x4A	/* R/W	*/
+#define ISACX_BCHB_TSDP_BC2	0x4B	/* R/W	*/
+#define ISACX_TR_TSDP_BC1	0x4C	/* R/W	*/
+#define ISACX_TR_TSDP_BC2	0x4D	/* R/W	*/
+#define ISACX_CDA1_CR		0x4E	/* R/W	*/
+#define ISACX_CDA2_CR		0x4F	/* R/W	*/
+
+/* IOM: Contol, Sync transfer, Monitor    */
+#define ISACX_TR_CR		0x50	/* R/W	*/
+#define ISACX_TRC_CR		0x50	/* R/W	*/
+#define ISACX_BCHA_CR		0x51	/* R/W	*/
+#define ISACX_BCHB_CR		0x52	/* R/W	*/
+#define ISACX_DCI_CR		0x53	/* R/W	*/
+#define ISACX_DCIC_CR		0x53	/* R/W	*/
+#define ISACX_MON_CR		0x54	/* R/W	*/
+#define ISACX_SDS1_CR		0x55	/* R/W	*/
+#define ISACX_SDS2_CR		0x56	/* R/W	*/
+#define ISACX_IOM_CR		0x57	/* R/W	*/
+#define ISACX_STI		0x58	/* RD	*/
+#define ISACX_ASTI		0x58	/* WR	*/
+#define ISACX_MSTI		0x59	/* R/W	*/
+#define ISACX_SDS_CONF		0x5A	/* R/W	*/
+#define ISACX_MCDA		0x5B	/* RD	*/
+#define ISACX_MOR		0x5C	/* RD	*/
+#define ISACX_MOX		0x5C	/* WR	*/
+#define ISACX_MOSR		0x5D	/* RD	*/
+#define ISACX_MOCR		0x5E	/* R/W	*/
+#define ISACX_MSTA		0x5F	/* RD	*/
+#define ISACX_MCONF		0x5F	/* WR	*/
+
+/* Interrupt and general registers */
+#define ISACX_ISTA		0x60	/* RD	*/
+#define ISACX_MASK		0x60	/* WR	*/
+#define ISACX_AUXI		0x61	/* RD	*/
+#define ISACX_AUXM		0x61	/* WR	*/
+#define ISACX_MODE1		0x62	/* R/W	*/
+#define ISACX_MODE2		0x63	/* R/W	*/
+#define ISACX_ID		0x64	/* RD	*/
+#define ISACX_SRES		0x64	/* WR	*/
+#define ISACX_TIMR2		0x65	/* R/W	*/
+
+/* Register Bits */
+/* ISACX/IPACX _ISTAD (R) and _MASKD (W) */
+#define ISACX_D_XDU		0x04
+#define ISACX_D_XMR		0x08
+#define ISACX_D_XPR		0x10
+#define ISACX_D_RFO		0x20
+#define ISACX_D_RPF		0x40
+#define ISACX_D_RME		0x80
+
+/* ISACX/IPACX _ISTA (R) and _MASK (W) */
+#define ISACX__ICD		0x01
+#define ISACX__MOS		0x02
+#define ISACX__TRAN		0x04
+#define ISACX__AUX		0x08
+#define ISACX__CIC		0x10
+#define ISACX__ST		0x20
+#define IPACX__ICB		0x40
+#define IPACX__ICA		0x80
+#define IPACX__ON		0x2C
+
+/* ISACX/IPACX _CMDRD (W) */
+#define ISACX_CMDRD_XRES	0x01
+#define ISACX_CMDRD_XME		0x02
+#define ISACX_CMDRD_XTF		0x08
+#define ISACX_CMDRD_STI		0x10
+#define ISACX_CMDRD_RRES	0x40
+#define ISACX_CMDRD_RMC		0x80
+
+/* ISACX/IPACX _RSTAD (R) */
+#define ISACX_RSTAD_TA		0x01
+#define ISACX_RSTAD_CR		0x02
+#define ISACX_RSTAD_SA0		0x04
+#define ISACX_RSTAD_SA1		0x08
+#define ISACX_RSTAD_RAB		0x10
+#define ISACX_RSTAD_CRC		0x20
+#define ISACX_RSTAD_RDO		0x40
+#define ISACX_RSTAD_VFR		0x80
+
+/* ISACX/IPACX _CIR0 (R) */
+#define ISACX_CIR0_BAS		0x01
+#define ISACX_CIR0_SG		0x08
+#define ISACX_CIR0_CIC1		0x08
+#define ISACX_CIR0_CIC0		0x08
+
+/* B-channel registers */
+#define IPACX_OFF_ICA		0x70
+#define IPACX_OFF_ICB		0x80
+
+/* ICA: IPACX_OFF_ICA + Reg ICB: IPACX_OFF_ICB + Reg */
+
+#define IPACX_ISTAB		0x00    /* RD	*/
+#define IPACX_MASKB		0x00	/* WR	*/
+#define IPACX_STARB		0x01	/* RD	*/
+#define IPACX_CMDRB		0x01	/* WR	*/
+#define IPACX_MODEB		0x02	/* R/W	*/
+#define IPACX_EXMB		0x03	/* R/W	*/
+#define IPACX_RAH1		0x05	/* WR	*/
+#define IPACX_RAH2		0x06	/* WR	*/
+#define IPACX_RBCLB		0x06	/* RD	*/
+#define IPACX_RBCHB		0x07	/* RD	*/
+#define IPACX_RAL1		0x07	/* WR	*/
+#define IPACX_RAL2		0x08	/* WR	*/
+#define IPACX_RSTAB		0x08	/* RD	*/
+#define IPACX_TMB		0x09	/* R/W	*/
+#define IPACX_RFIFOB		0x0A	/* RD	*/
+#define IPACX_XFIFOB		0x0A	/* WR	*/
+
+/* IPACX_ISTAB / IPACX_MASKB bits */
+#define IPACX_B_XDU		0x04
+#define IPACX_B_XPR		0x10
+#define IPACX_B_RFO		0x20
+#define IPACX_B_RPF		0x40
+#define IPACX_B_RME		0x80
+
+#define IPACX_B_ON		0x0B
+
+extern int mISDNisac_init(struct isac_hw *, void *);
+extern irqreturn_t mISDNisac_irq(struct isac_hw *, u8);
+extern u32 mISDNipac_init(struct ipac_hw *, void *);
+extern irqreturn_t mISDNipac_irq(struct ipac_hw *, int);
diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h
new file mode 100644
index 0000000..4a134ac
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/isar.h
@@ -0,0 +1,269 @@
+/*
+ *
+ * isar.h   ISAR (Siemens PSB 7110) specific defines
+ *
+ * Author Karsten Keil (keil@isdn4linux.de)
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "iohelper.h"
+
+struct isar_hw;
+
+struct isar_ch {
+	struct bchannel		bch;
+	struct isar_hw		*is;
+	struct timer_list	ftimer;
+	u8			nr;
+	u8			dpath;
+	u8			mml;
+	u8			state;
+	u8			cmd;
+	u8			mod;
+	u8			newcmd;
+	u8			newmod;
+	u8			try_mod;
+	u8			conmsg[16];
+};
+
+struct isar_hw {
+	struct	isar_ch	ch[2];
+	void		*hw;
+	spinlock_t	*hwlock;	/* lock HW acccess */
+	char		*name;
+	struct module	*owner;
+	read_reg_func	*read_reg;
+	write_reg_func	*write_reg;
+	fifo_func	*read_fifo;
+	fifo_func	*write_fifo;
+	int		(*ctrl)(void *, u32, u_long);
+	void		(*release)(struct isar_hw *);
+	int		(*init)(struct isar_hw *);
+	int		(*open)(struct isar_hw *, struct channel_req *);
+	int		(*firmware)(struct isar_hw *, const u8 *, int);
+	unsigned long	Flags;
+	int		version;
+	u8		bstat;
+	u8		iis;
+	u8		cmsb;
+	u8		clsb;
+	u8		buf[256];
+	u8		log[256];
+};
+
+#define ISAR_IRQMSK	0x04
+#define ISAR_IRQSTA	0x04
+#define ISAR_IRQBIT	0x75
+#define ISAR_CTRL_H	0x61
+#define ISAR_CTRL_L	0x60
+#define ISAR_IIS	0x58
+#define ISAR_IIA	0x58
+#define ISAR_HIS	0x50
+#define ISAR_HIA	0x50
+#define ISAR_MBOX	0x4c
+#define ISAR_WADR	0x4a
+#define ISAR_RADR	0x48
+
+#define ISAR_HIS_VNR		0x14
+#define ISAR_HIS_DKEY		0x02
+#define ISAR_HIS_FIRM		0x1e
+#define ISAR_HIS_STDSP		0x08
+#define ISAR_HIS_DIAG		0x05
+#define ISAR_HIS_P0CFG		0x3c
+#define ISAR_HIS_P12CFG		0x24
+#define ISAR_HIS_SARTCFG	0x25
+#define ISAR_HIS_PUMPCFG	0x26
+#define ISAR_HIS_PUMPCTRL	0x2a
+#define ISAR_HIS_IOM2CFG	0x27
+#define ISAR_HIS_IOM2REQ	0x07
+#define ISAR_HIS_IOM2CTRL	0x2b
+#define ISAR_HIS_BSTREQ		0x0c
+#define ISAR_HIS_PSTREQ		0x0e
+#define ISAR_HIS_SDATA		0x20
+#define ISAR_HIS_DPS1		0x40
+#define ISAR_HIS_DPS2		0x80
+#define SET_DPS(x)		((x<<6) & 0xc0)
+
+#define ISAR_IIS_MSCMSD		0x3f
+#define ISAR_IIS_VNR		0x15
+#define ISAR_IIS_DKEY		0x03
+#define ISAR_IIS_FIRM		0x1f
+#define ISAR_IIS_STDSP		0x09
+#define ISAR_IIS_DIAG		0x25
+#define ISAR_IIS_GSTEV		0x00
+#define ISAR_IIS_BSTEV		0x28
+#define ISAR_IIS_BSTRSP		0x2c
+#define ISAR_IIS_PSTRSP		0x2e
+#define ISAR_IIS_PSTEV		0x2a
+#define ISAR_IIS_IOM2RSP	0x27
+#define ISAR_IIS_RDATA		0x20
+#define ISAR_IIS_INVMSG		0x3f
+
+#define ISAR_CTRL_SWVER	0x10
+#define ISAR_CTRL_STST	0x40
+
+#define ISAR_MSG_HWVER	0x20
+
+#define ISAR_DP1_USE	1
+#define ISAR_DP2_USE	2
+#define ISAR_RATE_REQ	3
+
+#define PMOD_DISABLE	0
+#define PMOD_FAX	1
+#define PMOD_DATAMODEM	2
+#define PMOD_HALFDUPLEX	3
+#define PMOD_V110	4
+#define PMOD_DTMF	5
+#define PMOD_DTMF_TRANS	6
+#define PMOD_BYPASS	7
+
+#define PCTRL_ORIG	0x80
+#define PV32P2_V23R	0x40
+#define PV32P2_V22A	0x20
+#define PV32P2_V22B	0x10
+#define PV32P2_V22C	0x08
+#define PV32P2_V21	0x02
+#define PV32P2_BEL	0x01
+
+/* LSB MSB in ISAR doc wrong !!! Arghhh */
+#define PV32P3_AMOD	0x80
+#define PV32P3_V32B	0x02
+#define PV32P3_V23B	0x01
+#define PV32P4_48	0x11
+#define PV32P5_48	0x05
+#define PV32P4_UT48	0x11
+#define PV32P5_UT48	0x0d
+#define PV32P4_96	0x11
+#define PV32P5_96	0x03
+#define PV32P4_UT96	0x11
+#define PV32P5_UT96	0x0f
+#define PV32P4_B96	0x91
+#define PV32P5_B96	0x0b
+#define PV32P4_UTB96	0xd1
+#define PV32P5_UTB96	0x0f
+#define PV32P4_120	0xb1
+#define PV32P5_120	0x09
+#define PV32P4_UT120	0xf1
+#define PV32P5_UT120	0x0f
+#define PV32P4_144	0x99
+#define PV32P5_144	0x09
+#define PV32P4_UT144	0xf9
+#define PV32P5_UT144	0x0f
+#define PV32P6_CTN	0x01
+#define PV32P6_ATN	0x02
+
+#define PFAXP2_CTN	0x01
+#define PFAXP2_ATN	0x04
+
+#define PSEV_10MS_TIMER	0x02
+#define PSEV_CON_ON	0x18
+#define PSEV_CON_OFF	0x19
+#define PSEV_V24_OFF	0x20
+#define PSEV_CTS_ON	0x21
+#define PSEV_CTS_OFF	0x22
+#define PSEV_DCD_ON	0x23
+#define PSEV_DCD_OFF	0x24
+#define PSEV_DSR_ON	0x25
+#define PSEV_DSR_OFF	0x26
+#define PSEV_REM_RET	0xcc
+#define PSEV_REM_REN	0xcd
+#define PSEV_GSTN_CLR	0xd4
+
+#define PSEV_RSP_READY	0xbc
+#define PSEV_LINE_TX_H	0xb3
+#define PSEV_LINE_TX_B	0xb2
+#define PSEV_LINE_RX_H	0xb1
+#define PSEV_LINE_RX_B	0xb0
+#define PSEV_RSP_CONN	0xb5
+#define PSEV_RSP_DISC	0xb7
+#define PSEV_RSP_FCERR	0xb9
+#define PSEV_RSP_SILDET	0xbe
+#define PSEV_RSP_SILOFF	0xab
+#define PSEV_FLAGS_DET	0xba
+
+#define PCTRL_CMD_TDTMF	0x5a
+
+#define PCTRL_CMD_FTH	0xa7
+#define PCTRL_CMD_FRH	0xa5
+#define PCTRL_CMD_FTM	0xa8
+#define PCTRL_CMD_FRM	0xa6
+#define PCTRL_CMD_SILON	0xac
+#define PCTRL_CMD_CONT	0xa2
+#define PCTRL_CMD_ESC	0xa4
+#define PCTRL_CMD_SILOFF 0xab
+#define PCTRL_CMD_HALT	0xa9
+
+#define PCTRL_LOC_RET	0xcf
+#define PCTRL_LOC_REN	0xce
+
+#define SMODE_DISABLE	0
+#define SMODE_V14	2
+#define SMODE_HDLC	3
+#define SMODE_BINARY	4
+#define SMODE_FSK_V14	5
+
+#define SCTRL_HDMC_BOTH	0x00
+#define SCTRL_HDMC_DTX	0x80
+#define SCTRL_HDMC_DRX	0x40
+#define S_P1_OVSP	0x40
+#define S_P1_SNP	0x20
+#define S_P1_EOP	0x10
+#define S_P1_EDP	0x08
+#define S_P1_NSB	0x04
+#define S_P1_CHS_8	0x03
+#define S_P1_CHS_7	0x02
+#define S_P1_CHS_6	0x01
+#define S_P1_CHS_5	0x00
+
+#define S_P2_BFT_DEF	0x10
+
+#define IOM_CTRL_ENA	0x80
+#define IOM_CTRL_NOPCM	0x00
+#define IOM_CTRL_ALAW	0x02
+#define IOM_CTRL_ULAW	0x04
+#define IOM_CTRL_RCV	0x01
+
+#define IOM_P1_TXD	0x10
+
+#define HDLC_FED	0x40
+#define HDLC_FSD	0x20
+#define HDLC_FST	0x20
+#define HDLC_ERROR	0x1c
+#define HDLC_ERR_FAD	0x10
+#define HDLC_ERR_RER	0x08
+#define HDLC_ERR_CER	0x04
+#define SART_NMD	0x01
+
+#define BSTAT_RDM0	0x1
+#define BSTAT_RDM1	0x2
+#define BSTAT_RDM2	0x4
+#define BSTAT_RDM3	0x8
+#define BSTEV_TBO	0x1f
+#define BSTEV_RBO	0x2f
+
+/* FAX State Machine */
+#define STFAX_NULL	0
+#define STFAX_READY	1
+#define STFAX_LINE	2
+#define STFAX_CONT	3
+#define STFAX_ACTIV	4
+#define STFAX_ESCAPE	5
+#define STFAX_SILDET	6
+
+extern u32 mISDNisar_init(struct isar_hw *, void *);
+extern void mISDNisar_irq(struct isar_hw *);
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
new file mode 100644
index 0000000..62441ba
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
@@ -0,0 +1,1178 @@
+/*
+ * mISDNinfineon.c
+ *		Support for cards based on following Infineon ISDN chipsets
+ *		- ISAC + HSCX
+ *		- IPAC and IPAC-X
+ *		- ISAC-SX + HSCX
+ *
+ * Supported cards:
+ *		- Dialogic Diva 2.0
+ *		- Dialogic Diva 2.0U
+ *		- Dialogic Diva 2.01
+ *		- Dialogic Diva 2.02
+ *		- Sedlbauer Speedwin
+ *		- HST Saphir3
+ *		- Develo (former ELSA) Microlink PCI (Quickstep 1000)
+ *		- Develo (former ELSA) Quickstep 3000
+ *		- Berkom Scitel BRIX Quadro
+ *		- Dr.Neuhaus (Sagem) Niccy
+ *
+ *
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mISDNhw.h>
+#include "ipac.h"
+
+#define INFINEON_REV	"1.0"
+
+static int inf_cnt;
+static u32 debug;
+static u32 irqloops = 4;
+
+enum inf_types {
+	INF_NONE,
+	INF_DIVA20,
+	INF_DIVA20U,
+	INF_DIVA201,
+	INF_DIVA202,
+	INF_SPEEDWIN,
+	INF_SAPHIR3,
+	INF_QS1000,
+	INF_QS3000,
+	INF_NICCY,
+	INF_SCT_1,
+	INF_SCT_2,
+	INF_SCT_3,
+	INF_SCT_4,
+	INF_GAZEL_R685,
+	INF_GAZEL_R753
+};
+
+enum addr_mode {
+	AM_NONE = 0,
+	AM_IO,
+	AM_MEMIO,
+	AM_IND_IO,
+};
+
+struct inf_cinfo {
+	enum inf_types	typ;
+	const char	*full;
+	const char	*name;
+	enum addr_mode	cfg_mode;
+	enum addr_mode	addr_mode;
+	u8		cfg_bar;
+	u8		addr_bar;
+	void		*irqfunc;
+};
+
+struct _ioaddr {
+	enum addr_mode	mode;
+	union {
+		void __iomem	*p;
+		struct _ioport	io;
+	} a;
+};
+
+struct _iohandle {
+	enum addr_mode	mode;
+	resource_size_t	size;
+	resource_size_t	start;
+	void __iomem	*p;
+};
+
+struct inf_hw {
+	struct list_head	list;
+	struct pci_dev		*pdev;
+	const struct inf_cinfo	*ci;
+	char			name[MISDN_MAX_IDLEN];
+	u32			irq;
+	u32			irqcnt;
+	struct _iohandle	cfg;
+	struct _iohandle	addr;
+	struct _ioaddr		isac;
+	struct _ioaddr		hscx;
+	spinlock_t		lock;	/* HW access lock */
+	struct ipac_hw		ipac;
+	struct inf_hw		*sc[3];	/* slave cards */
+};
+
+
+#define PCI_SUBVENDOR_HST_SAPHIR3       0x52
+#define PCI_SUBVENDOR_SEDLBAUER_PCI     0x53
+#define PCI_SUB_ID_SEDLBAUER            0x01
+
+static struct pci_device_id infineon_ids[] __devinitdata = {
+	{ PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA20},
+	{ PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA20U},
+	{ PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA201,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA201},
+	{ PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA202,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA202},
+	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
+	  PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
+	  INF_SPEEDWIN},
+	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
+	  PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3},
+	{ PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_QS1000},
+	{ PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_QS3000},
+	{ PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_NICCY},
+	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+	  PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
+	  INF_SCT_1},
+	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R685,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R685},
+	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R753,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
+	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
+	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_OLITEC,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, infineon_ids);
+
+/* PCI interface specific defines */
+/* Diva 2.0/2.0U */
+#define DIVA_HSCX_PORT		0x00
+#define DIVA_HSCX_ALE		0x04
+#define DIVA_ISAC_PORT		0x08
+#define DIVA_ISAC_ALE		0x0C
+#define DIVA_PCI_CTRL           0x10
+
+/* DIVA_PCI_CTRL bits */
+#define DIVA_IRQ_BIT		0x01
+#define DIVA_RESET_BIT		0x08
+#define DIVA_EEPROM_CLK		0x40
+#define DIVA_LED_A		0x10
+#define DIVA_LED_B		0x20
+#define DIVA_IRQ_CLR		0x80
+
+/* Diva 2.01/2.02 */
+/* Siemens PITA */
+#define PITA_ICR_REG		0x00
+#define PITA_INT0_STATUS	0x02
+
+#define PITA_MISC_REG		0x1c
+#define PITA_PARA_SOFTRESET	0x01000000
+#define PITA_SER_SOFTRESET	0x02000000
+#define PITA_PARA_MPX_MODE	0x04000000
+#define PITA_INT0_ENABLE	0x00020000
+
+/* TIGER 100 Registers */
+#define TIGER_RESET_ADDR	0x00
+#define TIGER_EXTERN_RESET	0x01
+#define TIGER_AUX_CTRL		0x02
+#define TIGER_AUX_DATA		0x03
+#define TIGER_AUX_IRQMASK	0x05
+#define TIGER_AUX_STATUS	0x07
+
+/* Tiger AUX BITs */
+#define TIGER_IOMASK		0xdd	/* 1 and 5 are inputs */
+#define TIGER_IRQ_BIT		0x02
+
+#define TIGER_IPAC_ALE		0xC0
+#define TIGER_IPAC_PORT		0xC8
+
+/* ELSA (now Develo) PCI cards */
+#define ELSA_IRQ_ADDR		0x4c
+#define ELSA_IRQ_MASK		0x04
+#define QS1000_IRQ_OFF		0x01
+#define QS3000_IRQ_OFF		0x03
+#define QS1000_IRQ_ON		0x41
+#define QS3000_IRQ_ON		0x43
+
+/* Dr Neuhaus/Sagem Niccy */
+#define NICCY_ISAC_PORT		0x00
+#define NICCY_HSCX_PORT		0x01
+#define NICCY_ISAC_ALE		0x02
+#define NICCY_HSCX_ALE		0x03
+
+#define NICCY_IRQ_CTRL_REG	0x38
+#define NICCY_IRQ_ENABLE	0x001f00
+#define NICCY_IRQ_DISABLE	0xff0000
+#define NICCY_IRQ_BIT		0x800000
+
+
+/* Scitel PLX */
+#define SCT_PLX_IRQ_ADDR	0x4c
+#define SCT_PLX_RESET_ADDR	0x50
+#define SCT_PLX_IRQ_ENABLE	0x41
+#define SCT_PLX_RESET_BIT	0x04
+
+/* Gazel */
+#define	GAZEL_IPAC_DATA_PORT	0x04
+/* Gazel PLX */
+#define GAZEL_CNTRL		0x50
+#define GAZEL_RESET		0x04
+#define GAZEL_RESET_9050	0x40000000
+#define GAZEL_INCSR		0x4C
+#define GAZEL_ISAC_EN		0x08
+#define GAZEL_INT_ISAC		0x20
+#define GAZEL_HSCX_EN		0x01
+#define GAZEL_INT_HSCX		0x04
+#define GAZEL_PCI_EN		0x40
+#define GAZEL_IPAC_EN		0x03
+
+
+static LIST_HEAD(Cards);
+static DEFINE_RWLOCK(card_lock); /* protect Cards */
+
+static void
+_set_debug(struct inf_hw *card)
+{
+	card->ipac.isac.dch.debug = debug;
+	card->ipac.hscx[0].bch.debug = debug;
+	card->ipac.hscx[1].bch.debug = debug;
+}
+
+static int
+set_debug(const char *val, struct kernel_param *kp)
+{
+	int ret;
+	struct inf_hw *card;
+
+	ret = param_set_uint(val, kp);
+	if (!ret) {
+		read_lock(&card_lock);
+		list_for_each_entry(card, &Cards, list)
+			_set_debug(card);
+		read_unlock(&card_lock);
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("Karsten Keil");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(INFINEON_REV);
+module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "infineon debug mask");
+module_param(irqloops, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
+
+/* Interface functions */
+
+IOFUNC_IO(ISAC, inf_hw, isac.a.io)
+IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
+IOFUNC_IND(ISAC, inf_hw, isac.a.io)
+IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
+IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
+IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
+
+static irqreturn_t
+diva_irq(int intno, void *dev_id)
+{
+	struct inf_hw *hw = dev_id;
+	u8 val;
+
+	spin_lock(&hw->lock);
+	val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
+	if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
+		spin_unlock(&hw->lock);
+		return IRQ_NONE; /* shared */
+	}
+	hw->irqcnt++;
+	mISDNipac_irq(&hw->ipac, irqloops);
+	spin_unlock(&hw->lock);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+diva20x_irq(int intno, void *dev_id)
+{
+	struct inf_hw *hw = dev_id;
+	u8 val;
+
+	spin_lock(&hw->lock);
+	val = readb(hw->cfg.p);
+	if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
+		spin_unlock(&hw->lock);
+		return IRQ_NONE; /* shared */
+	}
+	hw->irqcnt++;
+	mISDNipac_irq(&hw->ipac, irqloops);
+	writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
+	spin_unlock(&hw->lock);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+tiger_irq(int intno, void *dev_id)
+{
+	struct inf_hw *hw = dev_id;
+	u8 val;
+
+	spin_lock(&hw->lock);
+	val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
+	if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
+		spin_unlock(&hw->lock);
+		return IRQ_NONE; /* shared */
+	}
+	hw->irqcnt++;
+	mISDNipac_irq(&hw->ipac, irqloops);
+	spin_unlock(&hw->lock);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+elsa_irq(int intno, void *dev_id)
+{
+	struct inf_hw *hw = dev_id;
+	u8 val;
+
+	spin_lock(&hw->lock);
+	val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
+	if (!(val & ELSA_IRQ_MASK)) {
+		spin_unlock(&hw->lock);
+		return IRQ_NONE; /* shared */
+	}
+	hw->irqcnt++;
+	mISDNipac_irq(&hw->ipac, irqloops);
+	spin_unlock(&hw->lock);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+niccy_irq(int intno, void *dev_id)
+{
+	struct inf_hw *hw = dev_id;
+	u32 val;
+
+	spin_lock(&hw->lock);
+	val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
+	if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
+		spin_unlock(&hw->lock);
+		return IRQ_NONE; /* shared */
+	}
+	outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
+	hw->irqcnt++;
+	mISDNipac_irq(&hw->ipac, irqloops);
+	spin_unlock(&hw->lock);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+gazel_irq(int intno, void *dev_id)
+{
+	struct inf_hw *hw = dev_id;
+	irqreturn_t ret;
+
+	spin_lock(&hw->lock);
+	ret = mISDNipac_irq(&hw->ipac, irqloops);
+	spin_unlock(&hw->lock);
+	return ret;
+}
+
+static irqreturn_t
+ipac_irq(int intno, void *dev_id)
+{
+	struct inf_hw *hw = dev_id;
+	u8 val;
+
+	spin_lock(&hw->lock);
+	val = hw->ipac.read_reg(hw, IPAC_ISTA);
+	if (!(val & 0x3f)) {
+		spin_unlock(&hw->lock);
+		return IRQ_NONE; /* shared */
+	}
+	hw->irqcnt++;
+	mISDNipac_irq(&hw->ipac, irqloops);
+	spin_unlock(&hw->lock);
+	return IRQ_HANDLED;
+}
+
+static void
+enable_hwirq(struct inf_hw *hw)
+{
+	u16 w;
+	u32 val;
+
+	switch (hw->ci->typ) {
+	case INF_DIVA201:
+	case INF_DIVA202:
+		writel(PITA_INT0_ENABLE, hw->cfg.p);
+		break;
+	case INF_SPEEDWIN:
+	case INF_SAPHIR3:
+		outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
+		break;
+	case INF_QS1000:
+		outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
+		break;
+	case INF_QS3000:
+		outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
+		break;
+	case INF_NICCY:
+		val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
+		val |= NICCY_IRQ_ENABLE;;
+		outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
+		break;
+	case INF_SCT_1:
+		w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
+		w |= SCT_PLX_IRQ_ENABLE;
+		outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
+		break;
+	case INF_GAZEL_R685:
+		outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
+			(u32)hw->cfg.start + GAZEL_INCSR);
+		break;
+	case INF_GAZEL_R753:
+		outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
+			(u32)hw->cfg.start + GAZEL_INCSR);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+disable_hwirq(struct inf_hw *hw)
+{
+	u16 w;
+	u32 val;
+
+	switch (hw->ci->typ) {
+	case INF_DIVA201:
+	case INF_DIVA202:
+		writel(0, hw->cfg.p);
+		break;
+	case INF_SPEEDWIN:
+	case INF_SAPHIR3:
+		outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
+		break;
+	case INF_QS1000:
+		outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
+		break;
+	case INF_QS3000:
+		outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
+		break;
+	case INF_NICCY:
+		val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
+		val &= NICCY_IRQ_DISABLE;
+		outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
+		break;
+	case INF_SCT_1:
+		w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
+		w &= (~SCT_PLX_IRQ_ENABLE);
+		outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
+		break;
+	case INF_GAZEL_R685:
+	case INF_GAZEL_R753:
+		outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+ipac_chip_reset(struct inf_hw *hw)
+{
+	hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
+	mdelay(5);
+	hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
+	mdelay(5);
+	hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
+	hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
+}
+
+static void
+reset_inf(struct inf_hw *hw)
+{
+	u16 w;
+	u32 val;
+
+	if (debug & DEBUG_HW)
+		pr_notice("%s: resetting card\n", hw->name);
+	switch (hw->ci->typ) {
+	case INF_DIVA20:
+	case INF_DIVA20U:
+		outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
+		mdelay(10);
+		outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
+		mdelay(10);
+		/* Workaround PCI9060 */
+		outb(9, (u32)hw->cfg.start + 0x69);
+		outb(DIVA_RESET_BIT | DIVA_LED_A,
+			(u32)hw->cfg.start + DIVA_PCI_CTRL);
+		break;
+	case INF_DIVA201:
+		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
+			hw->cfg.p + PITA_MISC_REG);
+		mdelay(1);
+		writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
+		mdelay(10);
+		break;
+	case INF_DIVA202:
+		writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
+			hw->cfg.p + PITA_MISC_REG);
+		mdelay(1);
+		writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
+			hw->cfg.p + PITA_MISC_REG);
+		mdelay(10);
+		break;
+	case INF_SPEEDWIN:
+	case INF_SAPHIR3:
+		ipac_chip_reset(hw);
+		hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
+		hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
+		hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
+		break;
+	case INF_QS1000:
+	case INF_QS3000:
+		ipac_chip_reset(hw);
+		hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
+		hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
+		hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
+		break;
+	case INF_NICCY:
+		break;
+	case INF_SCT_1:
+		w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
+		w &= (~SCT_PLX_RESET_BIT);
+		outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
+		mdelay(10);
+		w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
+		w |= SCT_PLX_RESET_BIT;
+		outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
+		mdelay(10);
+		break;
+	case INF_GAZEL_R685:
+		val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
+		val |= (GAZEL_RESET_9050 + GAZEL_RESET);
+		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
+		val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
+		mdelay(4);
+		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
+		mdelay(10);
+		hw->ipac.isac.adf2 = 0x87;
+		hw->ipac.hscx[0].slot = 0x1f;
+		hw->ipac.hscx[0].slot = 0x23;
+		break;
+	case INF_GAZEL_R753:
+		val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
+		val |= (GAZEL_RESET_9050 + GAZEL_RESET);
+		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
+		val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
+		mdelay(4);
+		outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
+		mdelay(10);
+		ipac_chip_reset(hw);
+		hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
+		hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
+		hw->ipac.conf = 0x01; /* IOM off */
+		break;
+	default:
+		return;
+	}
+	enable_hwirq(hw);
+}
+
+static int
+inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
+{
+	int ret = 0;
+
+	switch (cmd) {
+	case HW_RESET_REQ:
+		reset_inf(hw);
+		break;
+	default:
+		pr_info("%s: %s unknown command %x %lx\n",
+			hw->name, __func__, cmd, arg);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int __devinit
+init_irq(struct inf_hw *hw)
+{
+	int	ret, cnt = 3;
+	u_long	flags;
+
+	if (!hw->ci->irqfunc)
+		return -EINVAL;
+	ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
+	if (ret) {
+		pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
+		return ret;
+	}
+	while (cnt--) {
+		spin_lock_irqsave(&hw->lock, flags);
+		reset_inf(hw);
+		ret = hw->ipac.init(&hw->ipac);
+		if (ret) {
+			spin_unlock_irqrestore(&hw->lock, flags);
+			pr_info("%s: ISAC init failed with %d\n",
+				hw->name, ret);
+			break;
+		}
+		spin_unlock_irqrestore(&hw->lock, flags);
+		msleep_interruptible(10);
+		if (debug & DEBUG_HW)
+			pr_notice("%s: IRQ %d count %d\n", hw->name,
+				hw->irq, hw->irqcnt);
+		if (!hw->irqcnt) {
+			pr_info("%s: IRQ(%d) got no requests during init %d\n",
+				hw->name, hw->irq, 3 - cnt);
+		} else
+			return 0;
+	}
+	free_irq(hw->irq, hw);
+	return -EIO;
+}
+
+static void
+release_io(struct inf_hw *hw)
+{
+	if (hw->cfg.mode) {
+		if (hw->cfg.p) {
+			release_mem_region(hw->cfg.start, hw->cfg.size);
+			iounmap(hw->cfg.p);
+		} else
+			release_region(hw->cfg.start, hw->cfg.size);
+		hw->cfg.mode = AM_NONE;
+	}
+	if (hw->addr.mode) {
+		if (hw->addr.p) {
+			release_mem_region(hw->addr.start, hw->addr.size);
+			iounmap(hw->addr.p);
+		} else
+			release_region(hw->addr.start, hw->addr.size);
+		hw->addr.mode = AM_NONE;
+	}
+}
+
+static int __devinit
+setup_io(struct inf_hw *hw)
+{
+	int err = 0;
+
+	if (hw->ci->cfg_mode) {
+		hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
+		hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
+		if (hw->ci->cfg_mode == AM_MEMIO) {
+			if (!request_mem_region(hw->cfg.start, hw->cfg.size,
+			    hw->name))
+				err = -EBUSY;
+		} else {
+			if (!request_region(hw->cfg.start, hw->cfg.size,
+			    hw->name))
+				err = -EBUSY;
+		}
+		if (err) {
+			pr_info("mISDN: %s config port %lx (%lu bytes)"
+				"already in use\n", hw->name,
+				(ulong)hw->cfg.start, (ulong)hw->cfg.size);
+			return err;
+		}
+		if (hw->ci->cfg_mode == AM_MEMIO)
+			hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
+		hw->cfg.mode = hw->ci->cfg_mode;
+		if (debug & DEBUG_HW)
+			pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
+				hw->name, (ulong)hw->cfg.start,
+				(ulong)hw->cfg.size, hw->ci->cfg_mode);
+
+	}
+	if (hw->ci->addr_mode) {
+		hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
+		hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
+		if (hw->ci->addr_mode == AM_MEMIO) {
+			if (!request_mem_region(hw->addr.start, hw->addr.size,
+			    hw->name))
+				err = -EBUSY;
+		} else {
+			if (!request_region(hw->addr.start, hw->addr.size,
+			    hw->name))
+				err = -EBUSY;
+		}
+		if (err) {
+			pr_info("mISDN: %s address port %lx (%lu bytes)"
+				"already in use\n", hw->name,
+				(ulong)hw->addr.start, (ulong)hw->addr.size);
+			return err;
+		}
+		if (hw->ci->addr_mode == AM_MEMIO)
+			hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
+		hw->addr.mode = hw->ci->addr_mode;
+		if (debug & DEBUG_HW)
+			pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
+				hw->name, (ulong)hw->addr.start,
+				(ulong)hw->addr.size, hw->ci->addr_mode);
+
+	}
+
+	switch (hw->ci->typ) {
+	case INF_DIVA20:
+	case INF_DIVA20U:
+		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
+		hw->isac.mode = hw->cfg.mode;
+		hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
+		hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
+		hw->hscx.mode = hw->cfg.mode;
+		hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
+		hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
+		break;
+	case INF_DIVA201:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.mode = hw->addr.mode;
+		hw->isac.a.p = hw->addr.p;
+		hw->hscx.mode = hw->addr.mode;
+		hw->hscx.a.p = hw->addr.p;
+		break;
+	case INF_DIVA202:
+		hw->ipac.type = IPAC_TYPE_IPACX;
+		hw->isac.mode = hw->addr.mode;
+		hw->isac.a.p = hw->addr.p;
+		hw->hscx.mode = hw->addr.mode;
+		hw->hscx.a.p = hw->addr.p;
+		break;
+	case INF_SPEEDWIN:
+	case INF_SAPHIR3:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.mode = hw->cfg.mode;
+		hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
+		hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
+		hw->hscx.mode = hw->cfg.mode;
+		hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
+		hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
+		outb(0xff, (ulong)hw->cfg.start);
+		mdelay(1);
+		outb(0x00, (ulong)hw->cfg.start);
+		mdelay(1);
+		outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
+		break;
+	case INF_QS1000:
+	case INF_QS3000:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.a.io.ale = (u32)hw->addr.start;
+		hw->isac.a.io.port = (u32)hw->addr.start + 1;
+		hw->isac.mode = hw->addr.mode;
+		hw->hscx.a.io.ale = (u32)hw->addr.start;
+		hw->hscx.a.io.port = (u32)hw->addr.start + 1;
+		hw->hscx.mode = hw->addr.mode;
+		break;
+	case INF_NICCY:
+		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
+		hw->isac.mode = hw->addr.mode;
+		hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
+		hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
+		hw->hscx.mode = hw->addr.mode;
+		hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
+		hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
+		break;
+	case INF_SCT_1:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.a.io.ale = (u32)hw->addr.start;
+		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
+		hw->isac.mode = hw->addr.mode;
+		hw->hscx.a.io.ale = hw->isac.a.io.ale;
+		hw->hscx.a.io.port = hw->isac.a.io.port;
+		hw->hscx.mode = hw->addr.mode;
+		break;
+	case INF_SCT_2:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
+		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
+		hw->isac.mode = hw->addr.mode;
+		hw->hscx.a.io.ale = hw->isac.a.io.ale;
+		hw->hscx.a.io.port = hw->isac.a.io.port;
+		hw->hscx.mode = hw->addr.mode;
+		break;
+	case INF_SCT_3:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
+		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
+		hw->isac.mode = hw->addr.mode;
+		hw->hscx.a.io.ale = hw->isac.a.io.ale;
+		hw->hscx.a.io.port = hw->isac.a.io.port;
+		hw->hscx.mode = hw->addr.mode;
+		break;
+	case INF_SCT_4:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
+		hw->isac.a.io.port = hw->isac.a.io.ale + 4;
+		hw->isac.mode = hw->addr.mode;
+		hw->hscx.a.io.ale = hw->isac.a.io.ale;
+		hw->hscx.a.io.port = hw->isac.a.io.port;
+		hw->hscx.mode = hw->addr.mode;
+		break;
+	case INF_GAZEL_R685:
+		hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.mode = hw->addr.mode;
+		hw->isac.a.io.port = (u32)hw->addr.start;
+		hw->hscx.mode = hw->addr.mode;
+		hw->hscx.a.io.port = hw->isac.a.io.port;
+		break;
+	case INF_GAZEL_R753:
+		hw->ipac.type = IPAC_TYPE_IPAC;
+		hw->ipac.isac.off = 0x80;
+		hw->isac.mode = hw->addr.mode;
+		hw->isac.a.io.ale = (u32)hw->addr.start;
+		hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
+		hw->hscx.mode = hw->addr.mode;
+		hw->hscx.a.io.ale = hw->isac.a.io.ale;
+		hw->hscx.a.io.port = hw->isac.a.io.port;
+		break;
+	default:
+		return -EINVAL;
+	}
+	switch (hw->isac.mode) {
+	case AM_MEMIO:
+		ASSIGN_FUNC_IPAC(MIO, hw->ipac);
+		break;
+	case AM_IND_IO:
+		ASSIGN_FUNC_IPAC(IND, hw->ipac);
+		break;
+	case AM_IO:
+		ASSIGN_FUNC_IPAC(IO, hw->ipac);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static void
+release_card(struct inf_hw *card) {
+	ulong	flags;
+	int	i;
+
+	spin_lock_irqsave(&card->lock, flags);
+	disable_hwirq(card);
+	spin_unlock_irqrestore(&card->lock, flags);
+	card->ipac.isac.release(&card->ipac.isac);
+	free_irq(card->irq, card);
+	mISDN_unregister_device(&card->ipac.isac.dch.dev);
+	release_io(card);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	switch (card->ci->typ) {
+	case INF_SCT_2:
+	case INF_SCT_3:
+	case INF_SCT_4:
+		break;
+	case INF_SCT_1:
+		for (i = 0; i < 3; i++) {
+			if (card->sc[i])
+				release_card(card->sc[i]);
+			card->sc[i] = NULL;
+		}
+	default:
+		pci_disable_device(card->pdev);
+		pci_set_drvdata(card->pdev, NULL);
+		break;
+	}
+	kfree(card);
+	inf_cnt--;
+}
+
+static int __devinit
+setup_instance(struct inf_hw *card)
+{
+	int err;
+	ulong flags;
+
+	snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
+		inf_cnt + 1);
+	write_lock_irqsave(&card_lock, flags);
+	list_add_tail(&card->list, &Cards);
+	write_unlock_irqrestore(&card_lock, flags);
+
+	_set_debug(card);
+	card->ipac.isac.name = card->name;
+	card->ipac.name = card->name;
+	card->ipac.owner = THIS_MODULE;
+	spin_lock_init(&card->lock);
+	card->ipac.isac.hwlock = &card->lock;
+	card->ipac.hwlock = &card->lock;
+	card->ipac.ctrl = (void *)&inf_ctrl;
+
+	err = setup_io(card);
+	if (err)
+		goto error_setup;
+
+	card->ipac.isac.dch.dev.Bprotocols =
+		mISDNipac_init(&card->ipac, card);
+
+	if (card->ipac.isac.dch.dev.Bprotocols == 0)
+		goto error_setup;;
+
+	err = mISDN_register_device(&card->ipac.isac.dch.dev,
+		&card->pdev->dev, card->name);
+	if (err)
+		goto error;
+
+	err = init_irq(card);
+	if (!err)  {
+		inf_cnt++;
+		pr_notice("Infineon %d cards installed\n", inf_cnt);
+		return 0;
+	}
+	mISDN_unregister_device(&card->ipac.isac.dch.dev);
+error:
+	card->ipac.release(&card->ipac);
+error_setup:
+	release_io(card);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	return err;
+}
+
+static const struct inf_cinfo inf_card_info[] = {
+	{
+		INF_DIVA20,
+		"Dialogic Diva 2.0",
+		"diva20",
+		AM_IND_IO, AM_NONE, 2, 0,
+		&diva_irq
+	},
+	{
+		INF_DIVA20U,
+		"Dialogic Diva 2.0U",
+		"diva20U",
+		AM_IND_IO, AM_NONE, 2, 0,
+		&diva_irq
+	},
+	{
+		INF_DIVA201,
+		"Dialogic Diva 2.01",
+		"diva201",
+		AM_MEMIO, AM_MEMIO, 0, 1,
+		&diva20x_irq
+	},
+	{
+		INF_DIVA202,
+		"Dialogic Diva 2.02",
+		"diva202",
+		AM_MEMIO, AM_MEMIO, 0, 1,
+		&diva20x_irq
+	},
+	{
+		INF_SPEEDWIN,
+		"Sedlbauer SpeedWin PCI",
+		"speedwin",
+		AM_IND_IO, AM_NONE, 0, 0,
+		&tiger_irq
+	},
+	{
+		INF_SAPHIR3,
+		"HST Saphir 3",
+		"saphir",
+		AM_IND_IO, AM_NONE, 0, 0,
+		&tiger_irq
+	},
+	{
+		INF_QS1000,
+		"Develo Microlink PCI",
+		"qs1000",
+		AM_IO, AM_IND_IO, 1, 3,
+		&elsa_irq
+	},
+	{
+		INF_QS3000,
+		"Develo QuickStep 3000",
+		"qs3000",
+		AM_IO, AM_IND_IO, 1, 3,
+		&elsa_irq
+	},
+	{
+		INF_NICCY,
+		"Sagem NICCY",
+		"niccy",
+		AM_IO, AM_IND_IO, 0, 1,
+		&niccy_irq
+	},
+	{
+		INF_SCT_1,
+		"SciTel Quadro",
+		"p1_scitel",
+		AM_IO, AM_IND_IO, 1, 5,
+		&ipac_irq
+	},
+	{
+		INF_SCT_2,
+		"SciTel Quadro",
+		"p2_scitel",
+		AM_NONE, AM_IND_IO, 0, 4,
+		&ipac_irq
+	},
+	{
+		INF_SCT_3,
+		"SciTel Quadro",
+		"p3_scitel",
+		AM_NONE, AM_IND_IO, 0, 3,
+		&ipac_irq
+	},
+	{
+		INF_SCT_4,
+		"SciTel Quadro",
+		"p4_scitel",
+		AM_NONE, AM_IND_IO, 0, 2,
+		&ipac_irq
+	},
+	{
+		INF_GAZEL_R685,
+		"Gazel R685",
+		"gazel685",
+		AM_IO, AM_IO, 1, 2,
+		&gazel_irq
+	},
+	{
+		INF_GAZEL_R753,
+		"Gazel R753",
+		"gazel753",
+		AM_IO, AM_IND_IO, 1, 2,
+		&ipac_irq
+	},
+	{
+		INF_NONE,
+	}
+};
+
+static const struct inf_cinfo * __devinit
+get_card_info(enum inf_types typ)
+{
+	const struct inf_cinfo *ci = inf_card_info;
+
+	while (ci->typ != INF_NONE) {
+		if (ci->typ == typ)
+			return ci;
+		ci++;
+	}
+	return NULL;
+}
+
+static int __devinit
+inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int err = -ENOMEM;
+	struct inf_hw *card;
+
+	card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
+	if (!card) {
+		pr_info("No memory for Infineon ISDN card\n");
+		return err;
+	}
+	card->pdev = pdev;
+	err = pci_enable_device(pdev);
+	if (err) {
+		kfree(card);
+		return err;
+	}
+	card->ci = get_card_info(ent->driver_data);
+	if (!card->ci) {
+		pr_info("mISDN: do not have informations about adapter at %s\n",
+			pci_name(pdev));
+		kfree(card);
+		return -EINVAL;
+	} else
+		pr_notice("mISDN: found adapter %s at %s\n",
+			card->ci->full, pci_name(pdev));
+
+	card->irq = pdev->irq;
+	pci_set_drvdata(pdev, card);
+	err = setup_instance(card);
+	if (err) {
+		pci_disable_device(card->pdev);
+		kfree(card);
+		pci_set_drvdata(pdev, NULL);
+	} else if (ent->driver_data == INF_SCT_1) {
+		int i;
+		struct inf_hw *sc;
+
+		for (i = 1; i < 4; i++) {
+			sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
+			if (!sc) {
+				release_card(card);
+				return -ENOMEM;
+			}
+			sc->irq = card->irq;
+			sc->pdev = card->pdev;
+			sc->ci = card->ci + i;
+			err = setup_instance(sc);
+			if (err) {
+				kfree(sc);
+				release_card(card);
+			} else
+				card->sc[i - 1] = sc;
+		}
+	}
+	return err;
+}
+
+static void __devexit
+inf_remove(struct pci_dev *pdev)
+{
+	struct inf_hw	*card = pci_get_drvdata(pdev);
+
+	if (card)
+		release_card(card);
+	else
+		pr_debug("%s: drvdata allready removed\n", __func__);
+}
+
+static struct pci_driver infineon_driver = {
+	.name = "ISDN Infineon pci",
+	.probe = inf_probe,
+	.remove = __devexit_p(inf_remove),
+	.id_table = infineon_ids,
+};
+
+static int __init
+infineon_init(void)
+{
+	int err;
+
+	pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
+	err = pci_register_driver(&infineon_driver);
+	return err;
+}
+
+static void __exit
+infineon_cleanup(void)
+{
+	pci_unregister_driver(&infineon_driver);
+}
+
+module_init(infineon_init);
+module_exit(infineon_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
new file mode 100644
index 0000000..613ba04
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -0,0 +1,1655 @@
+/*
+ * isac.c   ISAC specific routines
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/mISDNhw.h>
+#include "ipac.h"
+
+
+#define DBUSY_TIMER_VALUE	80
+#define ARCOFI_USE		1
+
+#define ISAC_REV		"2.0"
+
+MODULE_AUTHOR("Karsten Keil");
+MODULE_VERSION(ISAC_REV);
+MODULE_LICENSE("GPL v2");
+
+#define ReadISAC(is, o)		(is->read_reg(is->dch.hw, o + is->off))
+#define	WriteISAC(is, o, v)	(is->write_reg(is->dch.hw, o + is->off, v))
+#define ReadHSCX(h, o)		(h->ip->read_reg(h->ip->hw, h->off + o))
+#define WriteHSCX(h, o, v)	(h->ip->write_reg(h->ip->hw, h->off + o, v))
+#define ReadIPAC(ip, o)		(ip->read_reg(ip->hw, o))
+#define WriteIPAC(ip, o, v)	(ip->write_reg(ip->hw, o, v))
+
+static inline void
+ph_command(struct isac_hw *isac, u8 command)
+{
+	pr_debug("%s: ph_command %x\n", isac->name, command);
+	if (isac->type & IPAC_TYPE_ISACX)
+		WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
+	else
+		WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
+}
+
+static void
+isac_ph_state_change(struct isac_hw *isac)
+{
+	switch (isac->state) {
+	case (ISAC_IND_RS):
+	case (ISAC_IND_EI):
+		ph_command(isac, ISAC_CMD_DUI);
+	}
+	schedule_event(&isac->dch, FLG_PHCHANGE);
+}
+
+static void
+isac_ph_state_bh(struct dchannel *dch)
+{
+	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
+
+	switch (isac->state) {
+	case ISAC_IND_RS:
+	case ISAC_IND_EI:
+		dch->state = 0;
+		l1_event(dch->l1, HW_RESET_IND);
+		break;
+	case ISAC_IND_DID:
+		dch->state = 3;
+		l1_event(dch->l1, HW_DEACT_CNF);
+		break;
+	case ISAC_IND_DR:
+		dch->state = 3;
+		l1_event(dch->l1, HW_DEACT_IND);
+		break;
+	case ISAC_IND_PU:
+		dch->state = 4;
+		l1_event(dch->l1, HW_POWERUP_IND);
+		break;
+	case ISAC_IND_RSY:
+		if (dch->state <= 5) {
+			dch->state = 5;
+			l1_event(dch->l1, ANYSIGNAL);
+		} else {
+			dch->state = 8;
+			l1_event(dch->l1, LOSTFRAMING);
+		}
+		break;
+	case ISAC_IND_ARD:
+		dch->state = 6;
+		l1_event(dch->l1, INFO2);
+		break;
+	case ISAC_IND_AI8:
+		dch->state = 7;
+		l1_event(dch->l1, INFO4_P8);
+		break;
+	case ISAC_IND_AI10:
+		dch->state = 7;
+		l1_event(dch->l1, INFO4_P10);
+		break;
+	}
+	pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
+}
+
+void
+isac_empty_fifo(struct isac_hw *isac, int count)
+{
+	u8 *ptr;
+
+	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
+
+	if (!isac->dch.rx_skb) {
+		isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
+		if (!isac->dch.rx_skb) {
+			pr_info("%s: D receive out of memory\n", isac->name);
+			WriteISAC(isac, ISAC_CMDR, 0x80);
+			return;
+		}
+	}
+	if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
+		pr_debug("%s: %s overrun %d\n", isac->name, __func__,
+			    isac->dch.rx_skb->len + count);
+		WriteISAC(isac, ISAC_CMDR, 0x80);
+		return;
+	}
+	ptr = skb_put(isac->dch.rx_skb, count);
+	isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
+	WriteISAC(isac, ISAC_CMDR, 0x80);
+	if (isac->dch.debug & DEBUG_HW_DFIFO) {
+		char	pfx[MISDN_MAX_IDLEN + 16];
+
+		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
+			isac->name, count);
+		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
+	}
+}
+
+static void
+isac_fill_fifo(struct isac_hw *isac)
+{
+	int count, more;
+	u8 *ptr;
+
+	if (!isac->dch.tx_skb)
+		return;
+	count = isac->dch.tx_skb->len - isac->dch.tx_idx;
+	if (count <= 0)
+		return;
+
+	more = 0;
+	if (count > 32) {
+		more = !0;
+		count = 32;
+	}
+	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
+	ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
+	isac->dch.tx_idx += count;
+	isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
+	WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
+	if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
+		pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
+		del_timer(&isac->dch.timer);
+	}
+	init_timer(&isac->dch.timer);
+	isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
+	add_timer(&isac->dch.timer);
+	if (isac->dch.debug & DEBUG_HW_DFIFO) {
+		char	pfx[MISDN_MAX_IDLEN + 16];
+
+		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
+			isac->name, count);
+		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
+	}
+}
+
+static void
+isac_rme_irq(struct isac_hw *isac)
+{
+	u8 val, count;
+
+	val = ReadISAC(isac, ISAC_RSTA);
+	if ((val & 0x70) != 0x20) {
+		if (val & 0x40) {
+			pr_debug("%s: ISAC RDO\n", isac->name);
+#ifdef ERROR_STATISTIC
+			isac->dch.err_rx++;
+#endif
+		}
+		if (!(val & 0x20)) {
+			pr_debug("%s: ISAC CRC error\n", isac->name);
+#ifdef ERROR_STATISTIC
+			isac->dch.err_crc++;
+#endif
+		}
+		WriteISAC(isac, ISAC_CMDR, 0x80);
+		if (isac->dch.rx_skb)
+			dev_kfree_skb(isac->dch.rx_skb);
+		isac->dch.rx_skb = NULL;
+	} else {
+		count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
+		if (count == 0)
+			count = 32;
+		isac_empty_fifo(isac, count);
+		recv_Dchannel(&isac->dch);
+	}
+}
+
+static void
+isac_xpr_irq(struct isac_hw *isac)
+{
+	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
+		del_timer(&isac->dch.timer);
+	if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
+		isac_fill_fifo(isac);
+	} else {
+		if (isac->dch.tx_skb)
+			dev_kfree_skb(isac->dch.tx_skb);
+		if (get_next_dframe(&isac->dch))
+			isac_fill_fifo(isac);
+	}
+}
+
+static void
+isac_retransmit(struct isac_hw *isac)
+{
+	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
+		del_timer(&isac->dch.timer);
+	if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
+		/* Restart frame */
+		isac->dch.tx_idx = 0;
+		isac_fill_fifo(isac);
+	} else if (isac->dch.tx_skb) { /* should not happen */
+		pr_info("%s: tx_skb exist but not busy\n", isac->name);
+		test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags);
+		isac->dch.tx_idx = 0;
+		isac_fill_fifo(isac);
+	} else {
+		pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name);
+		if (get_next_dframe(&isac->dch))
+			isac_fill_fifo(isac);
+	}
+}
+
+static void
+isac_mos_irq(struct isac_hw *isac)
+{
+	u8 val;
+	int ret;
+
+	val = ReadISAC(isac, ISAC_MOSR);
+	pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
+#if ARCOFI_USE
+	if (val & 0x08) {
+		if (!isac->mon_rx) {
+			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
+			if (!isac->mon_rx) {
+				pr_info("%s: ISAC MON RX out of memory!\n",
+					isac->name);
+				isac->mocr &= 0xf0;
+				isac->mocr |= 0x0a;
+				WriteISAC(isac, ISAC_MOCR, isac->mocr);
+				goto afterMONR0;
+			} else
+				isac->mon_rxp = 0;
+		}
+		if (isac->mon_rxp >= MAX_MON_FRAME) {
+			isac->mocr &= 0xf0;
+			isac->mocr |= 0x0a;
+			WriteISAC(isac, ISAC_MOCR, isac->mocr);
+			isac->mon_rxp = 0;
+			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
+			goto afterMONR0;
+		}
+		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
+		pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
+			isac->mon_rx[isac->mon_rxp - 1]);
+		if (isac->mon_rxp == 1) {
+			isac->mocr |= 0x04;
+			WriteISAC(isac, ISAC_MOCR, isac->mocr);
+		}
+	}
+afterMONR0:
+	if (val & 0x80) {
+		if (!isac->mon_rx) {
+			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
+			if (!isac->mon_rx) {
+				pr_info("%s: ISAC MON RX out of memory!\n",
+					isac->name);
+				isac->mocr &= 0x0f;
+				isac->mocr |= 0xa0;
+				WriteISAC(isac, ISAC_MOCR, isac->mocr);
+				goto afterMONR1;
+			} else
+				isac->mon_rxp = 0;
+		}
+		if (isac->mon_rxp >= MAX_MON_FRAME) {
+			isac->mocr &= 0x0f;
+			isac->mocr |= 0xa0;
+			WriteISAC(isac, ISAC_MOCR, isac->mocr);
+			isac->mon_rxp = 0;
+			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
+			goto afterMONR1;
+		}
+		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
+		pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
+			isac->mon_rx[isac->mon_rxp - 1]);
+		isac->mocr |= 0x40;
+		WriteISAC(isac, ISAC_MOCR, isac->mocr);
+	}
+afterMONR1:
+	if (val & 0x04) {
+		isac->mocr &= 0xf0;
+		WriteISAC(isac, ISAC_MOCR, isac->mocr);
+		isac->mocr |= 0x0a;
+		WriteISAC(isac, ISAC_MOCR, isac->mocr);
+		if (isac->monitor) {
+			ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
+				isac->mon_rx, isac->mon_rxp);
+			if (ret)
+				kfree(isac->mon_rx);
+		} else {
+			pr_info("%s: MONITOR 0 received %d but no user\n",
+				isac->name, isac->mon_rxp);
+			kfree(isac->mon_rx);
+		}
+		isac->mon_rx = NULL;
+		isac->mon_rxp = 0;
+	}
+	if (val & 0x40) {
+		isac->mocr &= 0x0f;
+		WriteISAC(isac, ISAC_MOCR, isac->mocr);
+		isac->mocr |= 0xa0;
+		WriteISAC(isac, ISAC_MOCR, isac->mocr);
+		if (isac->monitor) {
+			ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
+				isac->mon_rx, isac->mon_rxp);
+			if (ret)
+				kfree(isac->mon_rx);
+		} else {
+			pr_info("%s: MONITOR 1 received %d but no user\n",
+				isac->name, isac->mon_rxp);
+			kfree(isac->mon_rx);
+		}
+		isac->mon_rx = NULL;
+		isac->mon_rxp = 0;
+	}
+	if (val & 0x02) {
+		if ((!isac->mon_tx) || (isac->mon_txc &&
+			(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
+			isac->mocr &= 0xf0;
+			WriteISAC(isac, ISAC_MOCR, isac->mocr);
+			isac->mocr |= 0x0a;
+			WriteISAC(isac, ISAC_MOCR, isac->mocr);
+			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
+				if (isac->monitor)
+					ret = isac->monitor(isac->dch.hw,
+						MONITOR_TX_0, NULL, 0);
+			}
+			kfree(isac->mon_tx);
+			isac->mon_tx = NULL;
+			isac->mon_txc = 0;
+			isac->mon_txp = 0;
+			goto AfterMOX0;
+		}
+		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
+			if (isac->monitor)
+				ret = isac->monitor(isac->dch.hw,
+					MONITOR_TX_0, NULL, 0);
+			kfree(isac->mon_tx);
+			isac->mon_tx = NULL;
+			isac->mon_txc = 0;
+			isac->mon_txp = 0;
+			goto AfterMOX0;
+		}
+		WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
+		pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
+			isac->mon_tx[isac->mon_txp - 1]);
+	}
+AfterMOX0:
+	if (val & 0x20) {
+		if ((!isac->mon_tx) || (isac->mon_txc &&
+			(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
+			isac->mocr &= 0x0f;
+			WriteISAC(isac, ISAC_MOCR, isac->mocr);
+			isac->mocr |= 0xa0;
+			WriteISAC(isac, ISAC_MOCR, isac->mocr);
+			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
+				if (isac->monitor)
+					ret = isac->monitor(isac->dch.hw,
+						MONITOR_TX_1, NULL, 0);
+			}
+			kfree(isac->mon_tx);
+			isac->mon_tx = NULL;
+			isac->mon_txc = 0;
+			isac->mon_txp = 0;
+			goto AfterMOX1;
+		}
+		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
+			if (isac->monitor)
+				ret = isac->monitor(isac->dch.hw,
+					MONITOR_TX_1, NULL, 0);
+			kfree(isac->mon_tx);
+			isac->mon_tx = NULL;
+			isac->mon_txc = 0;
+			isac->mon_txp = 0;
+			goto AfterMOX1;
+		}
+		WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
+		pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
+			isac->mon_tx[isac->mon_txp - 1]);
+	}
+AfterMOX1:
+	val = 0; /* dummy to avoid warning */
+#endif
+}
+
+static void
+isac_cisq_irq(struct isac_hw *isac) {
+	u8 val;
+
+	val = ReadISAC(isac, ISAC_CIR0);
+	pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
+	if (val & 2) {
+		pr_debug("%s: ph_state change %x->%x\n", isac->name,
+			isac->state, (val >> 2) & 0xf);
+		isac->state = (val >> 2) & 0xf;
+		isac_ph_state_change(isac);
+	}
+	if (val & 1) {
+		val = ReadISAC(isac, ISAC_CIR1);
+		pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val);
+	}
+}
+
+static void
+isacsx_cic_irq(struct isac_hw *isac)
+{
+	u8 val;
+
+	val = ReadISAC(isac, ISACX_CIR0);
+	pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
+	if (val & ISACX_CIR0_CIC0) {
+		pr_debug("%s: ph_state change %x->%x\n", isac->name,
+			isac->state, val >> 4);
+		isac->state = val >> 4;
+		isac_ph_state_change(isac);
+	}
+}
+
+static void
+isacsx_rme_irq(struct isac_hw *isac)
+{
+	int count;
+	u8 val;
+
+	val = ReadISAC(isac, ISACX_RSTAD);
+	if ((val & (ISACX_RSTAD_VFR |
+		    ISACX_RSTAD_RDO |
+		    ISACX_RSTAD_CRC |
+		    ISACX_RSTAD_RAB))
+	    != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) {
+		pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val);
+#ifdef ERROR_STATISTIC
+		if (val & ISACX_RSTAD_CRC)
+			isac->dch.err_rx++;
+		else
+			isac->dch.err_crc++;
+#endif
+		WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
+		if (isac->dch.rx_skb)
+			dev_kfree_skb(isac->dch.rx_skb);
+		isac->dch.rx_skb = NULL;
+	} else {
+		count = ReadISAC(isac, ISACX_RBCLD) & 0x1f;
+		if (count == 0)
+			count = 32;
+		isac_empty_fifo(isac, count);
+		if (isac->dch.rx_skb) {
+			skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
+			pr_debug("%s: dchannel received %d\n", isac->name,
+				isac->dch.rx_skb->len);
+			recv_Dchannel(&isac->dch);
+		}
+	}
+}
+
+irqreturn_t
+mISDNisac_irq(struct isac_hw *isac, u8 val)
+{
+	if (unlikely(!val))
+		return IRQ_NONE;
+	pr_debug("%s: ISAC interrupt %02x\n", isac->name, val);
+	if (isac->type & IPAC_TYPE_ISACX) {
+		if (val & ISACX__CIC)
+			isacsx_cic_irq(isac);
+		if (val & ISACX__ICD) {
+			val = ReadISAC(isac, ISACX_ISTAD);
+			pr_debug("%s: ISTAD %02x\n", isac->name, val);
+			if (val & ISACX_D_XDU) {
+				pr_debug("%s: ISAC XDU\n", isac->name);
+#ifdef ERROR_STATISTIC
+				isac->dch.err_tx++;
+#endif
+				isac_retransmit(isac);
+			}
+			if (val & ISACX_D_XMR) {
+				pr_debug("%s: ISAC XMR\n", isac->name);
+#ifdef ERROR_STATISTIC
+				isac->dch.err_tx++;
+#endif
+				isac_retransmit(isac);
+			}
+			if (val & ISACX_D_XPR)
+				isac_xpr_irq(isac);
+			if (val & ISACX_D_RFO) {
+				pr_debug("%s: ISAC RFO\n", isac->name);
+				WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
+			}
+			if (val & ISACX_D_RME)
+				isacsx_rme_irq(isac);
+			if (val & ISACX_D_RPF)
+				isac_empty_fifo(isac, 0x20);
+		}
+	} else {
+		if (val & 0x80)	/* RME */
+			isac_rme_irq(isac);
+		if (val & 0x40)	/* RPF */
+			isac_empty_fifo(isac, 32);
+		if (val & 0x10)	/* XPR */
+			isac_xpr_irq(isac);
+		if (val & 0x04)	/* CISQ */
+			isac_cisq_irq(isac);
+		if (val & 0x20)	/* RSC - never */
+			pr_debug("%s: ISAC RSC interrupt\n", isac->name);
+		if (val & 0x02)	/* SIN - never */
+			pr_debug("%s: ISAC SIN interrupt\n", isac->name);
+		if (val & 0x01) {	/* EXI */
+			val = ReadISAC(isac, ISAC_EXIR);
+			pr_debug("%s: ISAC EXIR %02x\n", isac->name, val);
+			if (val & 0x80)	/* XMR */
+				pr_debug("%s: ISAC XMR\n", isac->name);
+			if (val & 0x40) { /* XDU */
+				pr_debug("%s: ISAC XDU\n", isac->name);
+#ifdef ERROR_STATISTIC
+				isac->dch.err_tx++;
+#endif
+				isac_retransmit(isac);
+			}
+			if (val & 0x04)	/* MOS */
+				isac_mos_irq(isac);
+		}
+	}
+	return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(mISDNisac_irq);
+
+static int
+isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb)
+{
+	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
+	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
+	struct isac_hw		*isac = container_of(dch, struct isac_hw, dch);
+	int			ret = -EINVAL;
+	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
+	u32			id;
+	u_long			flags;
+
+	switch (hh->prim) {
+	case PH_DATA_REQ:
+		spin_lock_irqsave(isac->hwlock, flags);
+		ret = dchannel_senddata(dch, skb);
+		if (ret > 0) { /* direct TX */
+			id = hh->id; /* skb can be freed */
+			isac_fill_fifo(isac);
+			ret = 0;
+			spin_unlock_irqrestore(isac->hwlock, flags);
+			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
+		} else
+			spin_unlock_irqrestore(isac->hwlock, flags);
+		return ret;
+	case PH_ACTIVATE_REQ:
+		ret = l1_event(dch->l1, hh->prim);
+		break;
+	case PH_DEACTIVATE_REQ:
+		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+		ret = l1_event(dch->l1, hh->prim);
+		break;
+	}
+
+	if (!ret)
+		dev_kfree_skb(skb);
+	return ret;
+}
+
+static int
+isac_ctrl(struct isac_hw *isac, u32 cmd, u_long para)
+{
+	u8 tl = 0;
+	u_long flags;
+
+	switch (cmd) {
+	case HW_TESTLOOP:
+		spin_lock_irqsave(isac->hwlock, flags);
+		if (!(isac->type & IPAC_TYPE_ISACX)) {
+			/* TODO: implement for IPAC_TYPE_ISACX */
+			if (para & 1) /* B1 */
+				tl |= 0x0c;
+			else if (para & 2) /* B2 */
+				tl |= 0x3;
+			/* we only support IOM2 mode */
+			WriteISAC(isac, ISAC_SPCR, tl);
+			if (tl)
+				WriteISAC(isac, ISAC_ADF1, 0x8);
+			else
+				WriteISAC(isac, ISAC_ADF1, 0x0);
+		}
+		spin_unlock_irqrestore(isac->hwlock, flags);
+		break;
+	default:
+		pr_debug("%s: %s unknown command %x %lx\n", isac->name,
+			__func__, cmd, para);
+		return -1;
+	}
+	return 0;
+}
+
+static int
+isac_l1cmd(struct dchannel *dch, u32 cmd)
+{
+	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
+	u_long flags;
+
+	pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state);
+	switch (cmd) {
+	case INFO3_P8:
+		spin_lock_irqsave(isac->hwlock, flags);
+		ph_command(isac, ISAC_CMD_AR8);
+		spin_unlock_irqrestore(isac->hwlock, flags);
+		break;
+	case INFO3_P10:
+		spin_lock_irqsave(isac->hwlock, flags);
+		ph_command(isac, ISAC_CMD_AR10);
+		spin_unlock_irqrestore(isac->hwlock, flags);
+		break;
+	case HW_RESET_REQ:
+		spin_lock_irqsave(isac->hwlock, flags);
+		if ((isac->state == ISAC_IND_EI) ||
+		    (isac->state == ISAC_IND_DR) ||
+		    (isac->state == ISAC_IND_RS))
+			ph_command(isac, ISAC_CMD_TIM);
+		else
+			ph_command(isac, ISAC_CMD_RS);
+		spin_unlock_irqrestore(isac->hwlock, flags);
+		break;
+	case HW_DEACT_REQ:
+		skb_queue_purge(&dch->squeue);
+		if (dch->tx_skb) {
+			dev_kfree_skb(dch->tx_skb);
+			dch->tx_skb = NULL;
+		}
+		dch->tx_idx = 0;
+		if (dch->rx_skb) {
+			dev_kfree_skb(dch->rx_skb);
+			dch->rx_skb = NULL;
+		}
+		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
+			del_timer(&dch->timer);
+		break;
+	case HW_POWERUP_REQ:
+		spin_lock_irqsave(isac->hwlock, flags);
+		ph_command(isac, ISAC_CMD_TIM);
+		spin_unlock_irqrestore(isac->hwlock, flags);
+		break;
+	case PH_ACTIVATE_IND:
+		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
+		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
+			GFP_ATOMIC);
+		break;
+	case PH_DEACTIVATE_IND:
+		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
+		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
+			GFP_ATOMIC);
+		break;
+	default:
+		pr_debug("%s: %s unknown command %x\n", isac->name,
+			__func__, cmd);
+		return -1;
+	}
+	return 0;
+}
+
+static void
+isac_release(struct isac_hw *isac)
+{
+	if (isac->type & IPAC_TYPE_ISACX)
+		WriteISAC(isac, ISACX_MASK, 0xff);
+	else
+		WriteISAC(isac, ISAC_MASK, 0xff);
+	if (isac->dch.timer.function != NULL) {
+		del_timer(&isac->dch.timer);
+		isac->dch.timer.function = NULL;
+	}
+	kfree(isac->mon_rx);
+	isac->mon_rx = NULL;
+	kfree(isac->mon_tx);
+	isac->mon_tx = NULL;
+	if (isac->dch.l1)
+		l1_event(isac->dch.l1, CLOSE_CHANNEL);
+	mISDN_freedchannel(&isac->dch);
+}
+
+static void
+dbusy_timer_handler(struct isac_hw *isac)
+{
+	int rbch, star;
+	u_long flags;
+
+	if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
+		spin_lock_irqsave(isac->hwlock, flags);
+		rbch = ReadISAC(isac, ISAC_RBCH);
+		star = ReadISAC(isac, ISAC_STAR);
+		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
+			isac->name, rbch, star);
+		if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
+			test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
+		else {
+			/* discard frame; reset transceiver */
+			test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags);
+			if (isac->dch.tx_idx)
+				isac->dch.tx_idx = 0;
+			else
+				pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
+					isac->name);
+			/* Transmitter reset */
+			WriteISAC(isac, ISAC_CMDR, 0x01);
+		}
+		spin_unlock_irqrestore(isac->hwlock, flags);
+	}
+}
+
+static int
+open_dchannel(struct isac_hw *isac, struct channel_req *rq)
+{
+	pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
+		isac->dch.dev.id, __builtin_return_address(1));
+	if (rq->protocol != ISDN_P_TE_S0)
+		return -EINVAL;
+	if (rq->adr.channel == 1)
+		/* E-Channel not supported */
+		return -EINVAL;
+	rq->ch = &isac->dch.dev.D;
+	rq->ch->protocol = rq->protocol;
+	if (isac->dch.state == 7)
+		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
+		    0, NULL, GFP_KERNEL);
+	return 0;
+}
+
+static const char *ISACVer[] =
+{"2086/2186 V1.1", "2085 B1", "2085 B2",
+ "2085 V2.3"};
+
+static int
+isac_init(struct isac_hw *isac)
+{
+	u8 val;
+	int err = 0;
+
+	if (!isac->dch.l1) {
+		err = create_l1(&isac->dch, isac_l1cmd);
+		if (err)
+			return err;
+	}
+	isac->mon_tx = NULL;
+	isac->mon_rx = NULL;
+	isac->dch.timer.function = (void *) dbusy_timer_handler;
+	isac->dch.timer.data = (long)isac;
+	init_timer(&isac->dch.timer);
+	isac->mocr = 0xaa;
+	if (isac->type & IPAC_TYPE_ISACX) {
+		/* Disable all IRQ */
+		WriteISAC(isac, ISACX_MASK, 0xff);
+		val = ReadISAC(isac, ISACX_STARD);
+		pr_debug("%s: ISACX STARD %x\n", isac->name, val);
+		val = ReadISAC(isac, ISACX_ISTAD);
+		pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
+		val = ReadISAC(isac, ISACX_ISTA);
+		pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
+		/* clear LDD */
+		WriteISAC(isac, ISACX_TR_CONF0, 0x00);
+		/* enable transmitter */
+		WriteISAC(isac, ISACX_TR_CONF2, 0x00);
+		/* transparent mode 0, RAC, stop/go */
+		WriteISAC(isac, ISACX_MODED, 0xc9);
+		/* all HDLC IRQ unmasked */
+		val = ReadISAC(isac, ISACX_ID);
+		if (isac->dch.debug & DEBUG_HW)
+			pr_notice("%s: ISACX Design ID %x\n",
+				isac->name, val & 0x3f);
+		val = ReadISAC(isac, ISACX_CIR0);
+		pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
+		isac->state = val >> 4;
+		isac_ph_state_change(isac);
+		ph_command(isac, ISAC_CMD_RS);
+		WriteISAC(isac, ISACX_MASK, IPACX__ON);
+		WriteISAC(isac, ISACX_MASKD, 0x00);
+	} else { /* old isac */
+		WriteISAC(isac, ISAC_MASK, 0xff);
+		val = ReadISAC(isac, ISAC_STAR);
+		pr_debug("%s: ISAC STAR %x\n", isac->name, val);
+		val = ReadISAC(isac, ISAC_MODE);
+		pr_debug("%s: ISAC MODE %x\n", isac->name, val);
+		val = ReadISAC(isac, ISAC_ADF2);
+		pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
+		val = ReadISAC(isac, ISAC_ISTA);
+		pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
+		if (val & 0x01) {
+			val = ReadISAC(isac, ISAC_EXIR);
+			pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
+		}
+		val = ReadISAC(isac, ISAC_RBCH);
+		if (isac->dch.debug & DEBUG_HW)
+			pr_notice("%s: ISAC version (%x): %s\n", isac->name,
+				val, ISACVer[(val >> 5) & 3]);
+		isac->type |= ((val >> 5) & 3);
+		if (!isac->adf2)
+			isac->adf2 = 0x80;
+		if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
+			pr_info("%s: only support IOM2 mode but adf2=%02x\n",
+				isac->name, isac->adf2);
+			isac_release(isac);
+			return -EINVAL;
+		}
+		WriteISAC(isac, ISAC_ADF2, isac->adf2);
+		WriteISAC(isac, ISAC_SQXR, 0x2f);
+		WriteISAC(isac, ISAC_SPCR, 0x00);
+		WriteISAC(isac, ISAC_STCR, 0x70);
+		WriteISAC(isac, ISAC_MODE, 0xc9);
+		WriteISAC(isac, ISAC_TIMR, 0x00);
+		WriteISAC(isac, ISAC_ADF1, 0x00);
+		val = ReadISAC(isac, ISAC_CIR0);
+		pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
+		isac->state = (val >> 2) & 0xf;
+		isac_ph_state_change(isac);
+		ph_command(isac, ISAC_CMD_RS);
+		WriteISAC(isac, ISAC_MASK, 0);
+	}
+	return err;
+}
+
+int
+mISDNisac_init(struct isac_hw *isac, void *hw)
+{
+	mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
+	isac->dch.hw = hw;
+	isac->dch.dev.D.send = isac_l1hw;
+	isac->init = isac_init;
+	isac->release = isac_release;
+	isac->ctrl = isac_ctrl;
+	isac->open = open_dchannel;
+	isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
+	isac->dch.dev.nrbchan = 2;
+	return 0;
+}
+EXPORT_SYMBOL(mISDNisac_init);
+
+static void
+waitforCEC(struct hscx_hw *hx)
+{
+	u8 starb, to = 50;
+
+	while (to) {
+		starb = ReadHSCX(hx, IPAC_STARB);
+		if (!(starb & 0x04))
+			break;
+		udelay(1);
+		to--;
+	}
+	if (to < 50)
+		pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
+			50 - to);
+	if (!to)
+		pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
+}
+
+
+static void
+waitforXFW(struct hscx_hw *hx)
+{
+	u8 starb, to = 50;
+
+	while (to) {
+		starb = ReadHSCX(hx, IPAC_STARB);
+		if ((starb & 0x44) == 0x40)
+			break;
+		udelay(1);
+		to--;
+	}
+	if (to < 50)
+		pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
+			50 - to);
+	if (!to)
+		pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
+}
+
+static void
+hscx_cmdr(struct hscx_hw *hx, u8 cmd)
+{
+	if (hx->ip->type & IPAC_TYPE_IPACX)
+		WriteHSCX(hx, IPACX_CMDRB, cmd);
+	else {
+		waitforCEC(hx);
+		WriteHSCX(hx, IPAC_CMDRB, cmd);
+	}
+}
+
+static void
+hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
+{
+	u8 *p;
+
+	pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
+	if (!hscx->bch.rx_skb) {
+		hscx->bch.rx_skb = mI_alloc_skb(hscx->bch.maxlen, GFP_ATOMIC);
+		if (!hscx->bch.rx_skb) {
+			pr_info("%s: B receive out of memory\n",
+				hscx->ip->name);
+			hscx_cmdr(hscx, 0x80); /* RMC */
+			return;
+		}
+	}
+	if ((hscx->bch.rx_skb->len + count) > hscx->bch.maxlen) {
+		pr_debug("%s: overrun %d\n", hscx->ip->name,
+			hscx->bch.rx_skb->len + count);
+		skb_trim(hscx->bch.rx_skb, 0);
+		hscx_cmdr(hscx, 0x80); /* RMC */
+		return;
+	}
+	p = skb_put(hscx->bch.rx_skb, count);
+
+	if (hscx->ip->type & IPAC_TYPE_IPACX)
+		hscx->ip->read_fifo(hscx->ip->hw,
+			hscx->off + IPACX_RFIFOB, p, count);
+	else
+		hscx->ip->read_fifo(hscx->ip->hw,
+			hscx->off, p, count);
+
+	hscx_cmdr(hscx, 0x80); /* RMC */
+
+	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
+		snprintf(hscx->log, 64, "B%1d-recv %s %d ",
+			hscx->bch.nr, hscx->ip->name, count);
+		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
+	}
+}
+
+static void
+hscx_fill_fifo(struct hscx_hw *hscx)
+{
+	int count, more;
+	u8 *p;
+
+	if (!hscx->bch.tx_skb)
+		return;
+	count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
+	if (count <= 0)
+		return;
+	p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
+
+	more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
+	if (count > hscx->fifo_size) {
+		count = hscx->fifo_size;
+		more = 1;
+	}
+	pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, count,
+		hscx->bch.tx_idx, hscx->bch.tx_skb->len);
+	hscx->bch.tx_idx += count;
+
+	if (hscx->ip->type & IPAC_TYPE_IPACX)
+		hscx->ip->write_fifo(hscx->ip->hw,
+			hscx->off + IPACX_XFIFOB, p, count);
+	else {
+		waitforXFW(hscx);
+		hscx->ip->write_fifo(hscx->ip->hw,
+			hscx->off, p, count);
+	}
+	hscx_cmdr(hscx, more ? 0x08 : 0x0a);
+
+	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
+		snprintf(hscx->log, 64, "B%1d-send %s %d ",
+			hscx->bch.nr, hscx->ip->name, count);
+		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
+	}
+}
+
+static void
+hscx_xpr(struct hscx_hw *hx)
+{
+	if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len)
+		hscx_fill_fifo(hx);
+	else {
+		if (hx->bch.tx_skb) {
+			/* send confirm, on trans, free on hdlc. */
+			if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
+				confirm_Bsend(&hx->bch);
+			dev_kfree_skb(hx->bch.tx_skb);
+		}
+		if (get_next_bframe(&hx->bch))
+			hscx_fill_fifo(hx);
+	}
+}
+
+static void
+ipac_rme(struct hscx_hw *hx)
+{
+	int count;
+	u8 rstab;
+
+	if (hx->ip->type & IPAC_TYPE_IPACX)
+		rstab = ReadHSCX(hx, IPACX_RSTAB);
+	else
+		rstab = ReadHSCX(hx, IPAC_RSTAB);
+	pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
+	if ((rstab & 0xf0) != 0xa0) {
+		/* !(VFR && !RDO && CRC && !RAB) */
+		if (!(rstab & 0x80)) {
+			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
+				pr_notice("%s: B%1d invalid frame\n",
+					hx->ip->name, hx->bch.nr);
+		}
+		if (rstab & 0x40) {
+			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
+				pr_notice("%s: B%1d RDO proto=%x\n",
+					hx->ip->name, hx->bch.nr,
+					hx->bch.state);
+		}
+		if (!(rstab & 0x20)) {
+			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
+				pr_notice("%s: B%1d CRC error\n",
+					hx->ip->name, hx->bch.nr);
+		}
+		hscx_cmdr(hx, 0x80); /* Do RMC */
+		return;
+	}
+	if (hx->ip->type & IPAC_TYPE_IPACX)
+		count = ReadHSCX(hx, IPACX_RBCLB);
+	else
+		count = ReadHSCX(hx, IPAC_RBCLB);
+	count &= (hx->fifo_size - 1);
+	if (count == 0)
+		count = hx->fifo_size;
+	hscx_empty_fifo(hx, count);
+	if (!hx->bch.rx_skb)
+		return;
+	if (hx->bch.rx_skb->len < 2) {
+		pr_debug("%s: B%1d frame to short %d\n",
+			hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
+		skb_trim(hx->bch.rx_skb, 0);
+	} else {
+		skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
+		recv_Bchannel(&hx->bch, 0);
+	}
+}
+
+static void
+ipac_irq(struct hscx_hw *hx, u8 ista)
+{
+	u8 istab, m, exirb = 0;
+
+	if (hx->ip->type & IPAC_TYPE_IPACX)
+		istab = ReadHSCX(hx, IPACX_ISTAB);
+	else if (hx->ip->type & IPAC_TYPE_IPAC) {
+		istab = ReadHSCX(hx, IPAC_ISTAB);
+		m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
+		if (m & ista) {
+			exirb = ReadHSCX(hx, IPAC_EXIRB);
+			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
+				hx->bch.nr, exirb);
+		}
+	} else if (hx->bch.nr & 2) { /* HSCX B */
+		if (ista & (HSCX__EXA | HSCX__ICA))
+			ipac_irq(&hx->ip->hscx[0], ista);
+		if (ista & HSCX__EXB) {
+			exirb = ReadHSCX(hx, IPAC_EXIRB);
+			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
+				hx->bch.nr, exirb);
+		}
+		istab = ista & 0xF8;
+	} else { /* HSCX A */
+		istab = ReadHSCX(hx, IPAC_ISTAB);
+		if (ista & HSCX__EXA) {
+			exirb = ReadHSCX(hx, IPAC_EXIRB);
+			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
+				hx->bch.nr, exirb);
+		}
+		istab = istab & 0xF8;
+	}
+	if (exirb & IPAC_B_XDU)
+		istab |= IPACX_B_XDU;
+	if (exirb & IPAC_B_RFO)
+		istab |= IPACX_B_RFO;
+	pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
+
+	if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
+		return;
+
+	if (istab & IPACX_B_RME)
+		ipac_rme(hx);
+
+	if (istab & IPACX_B_RPF) {
+		hscx_empty_fifo(hx, hx->fifo_size);
+		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
+			/* receive transparent audio data */
+			if (hx->bch.rx_skb)
+				recv_Bchannel(&hx->bch, 0);
+		}
+	}
+
+	if (istab & IPACX_B_RFO) {
+		pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
+		hscx_cmdr(hx, 0x40);	/* RRES */
+	}
+
+	if (istab & IPACX_B_XPR)
+		hscx_xpr(hx);
+
+	if (istab & IPACX_B_XDU) {
+		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
+			hscx_fill_fifo(hx);
+			return;
+		}
+		pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
+			hx->bch.nr, hx->bch.tx_idx);
+		hx->bch.tx_idx = 0;
+		hscx_cmdr(hx, 0x01);	/* XRES */
+	}
+}
+
+irqreturn_t
+mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
+{
+	int cnt = maxloop + 1;
+	u8 ista, istad;
+	struct isac_hw  *isac = &ipac->isac;
+
+	if (ipac->type & IPAC_TYPE_IPACX) {
+		ista = ReadIPAC(ipac, ISACX_ISTA);
+		while (ista && cnt--) {
+			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
+			if (ista & IPACX__ICA)
+				ipac_irq(&ipac->hscx[0], ista);
+			if (ista & IPACX__ICB)
+				ipac_irq(&ipac->hscx[1], ista);
+			if (ista & (ISACX__ICD | ISACX__CIC))
+				mISDNisac_irq(&ipac->isac, ista);
+			ista = ReadIPAC(ipac, ISACX_ISTA);
+		}
+	} else if (ipac->type & IPAC_TYPE_IPAC) {
+		ista = ReadIPAC(ipac, IPAC_ISTA);
+		while (ista && cnt--) {
+			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
+			if (ista & (IPAC__ICD | IPAC__EXD)) {
+				istad = ReadISAC(isac, ISAC_ISTA);
+				pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
+				if (istad & IPAC_D_TIN2)
+					pr_debug("%s TIN2 irq\n", ipac->name);
+				if (ista & IPAC__EXD)
+					istad |= 1; /* ISAC EXI */
+				mISDNisac_irq(isac, istad);
+			}
+			if (ista & (IPAC__ICA | IPAC__EXA))
+				ipac_irq(&ipac->hscx[0], ista);
+			if (ista & (IPAC__ICB | IPAC__EXB))
+				ipac_irq(&ipac->hscx[1], ista);
+			ista = ReadIPAC(ipac, IPAC_ISTA);
+		}
+	} else if (ipac->type & IPAC_TYPE_HSCX) {
+		while (cnt) {
+			ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
+			pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
+			if (ista)
+				ipac_irq(&ipac->hscx[1], ista);
+			istad = ReadISAC(isac, ISAC_ISTA);
+			pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
+			if (istad)
+				mISDNisac_irq(isac, istad);
+			if (0 == (ista | istad))
+				break;
+			cnt--;
+		}
+	}
+	if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
+		return IRQ_NONE;
+	if (cnt < maxloop)
+		pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
+			maxloop - cnt, smp_processor_id());
+	if (maxloop && !cnt)
+		pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
+			maxloop, smp_processor_id());
+	return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(mISDNipac_irq);
+
+static int
+hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
+{
+	pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
+		'@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
+	if (hscx->ip->type & IPAC_TYPE_IPACX) {
+		if (hscx->bch.nr & 1) { /* B1 and ICA */
+			WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
+			WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
+		} else { /* B2 and ICB */
+			WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
+			WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
+		}
+		switch (bprotocol) {
+		case ISDN_P_NONE: /* init */
+			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* rec off */
+			WriteHSCX(hscx, IPACX_EXMB,  0x30);	/* std adj. */
+			WriteHSCX(hscx, IPACX_MASKB, 0xFF);	/* ints off */
+			hscx_cmdr(hscx, 0x41);
+			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
+			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
+			break;
+		case ISDN_P_B_RAW:
+			WriteHSCX(hscx, IPACX_MODEB, 0x88);	/* ex trans */
+			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* trans */
+			hscx_cmdr(hscx, 0x41);
+			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
+			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
+			break;
+		case ISDN_P_B_HDLC:
+			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* trans */
+			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* hdlc,crc */
+			hscx_cmdr(hscx, 0x41);
+			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
+			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
+			break;
+		default:
+			pr_info("%s: protocol not known %x\n", hscx->ip->name,
+				bprotocol);
+			return -ENOPROTOOPT;
+		}
+	} else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
+		WriteHSCX(hscx, IPAC_CCR1, 0x82);
+		WriteHSCX(hscx, IPAC_CCR2, 0x30);
+		WriteHSCX(hscx, IPAC_XCCR, 0x07);
+		WriteHSCX(hscx, IPAC_RCCR, 0x07);
+		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
+		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
+		switch (bprotocol) {
+		case ISDN_P_NONE:
+			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
+			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
+			WriteHSCX(hscx, IPAC_MODEB, 0x84);
+			WriteHSCX(hscx, IPAC_CCR1, 0x82);
+			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
+			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
+			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
+			break;
+		case ISDN_P_B_RAW:
+			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
+			WriteHSCX(hscx, IPAC_CCR1, 0x82);
+			hscx_cmdr(hscx, 0x41);
+			WriteHSCX(hscx, IPAC_MASKB, 0);
+			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
+			break;
+		case ISDN_P_B_HDLC:
+			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
+			WriteHSCX(hscx, IPAC_CCR1, 0x8a);
+			hscx_cmdr(hscx, 0x41);
+			WriteHSCX(hscx, IPAC_MASKB, 0);
+			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
+			break;
+		default:
+			pr_info("%s: protocol not known %x\n", hscx->ip->name,
+				bprotocol);
+			return -ENOPROTOOPT;
+		}
+	} else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
+		WriteHSCX(hscx, IPAC_CCR1, 0x85);
+		WriteHSCX(hscx, IPAC_CCR2, 0x30);
+		WriteHSCX(hscx, IPAC_XCCR, 0x07);
+		WriteHSCX(hscx, IPAC_RCCR, 0x07);
+		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
+		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
+		switch (bprotocol) {
+		case ISDN_P_NONE:
+			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
+			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
+			WriteHSCX(hscx, IPAC_MODEB, 0x84);
+			WriteHSCX(hscx, IPAC_CCR1, 0x85);
+			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
+			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
+			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
+			break;
+		case ISDN_P_B_RAW:
+			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
+			WriteHSCX(hscx, IPAC_CCR1, 0x85);
+			hscx_cmdr(hscx, 0x41);
+			WriteHSCX(hscx, IPAC_MASKB, 0);
+			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
+			break;
+		case ISDN_P_B_HDLC:
+			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
+			WriteHSCX(hscx, IPAC_CCR1, 0x8d);
+			hscx_cmdr(hscx, 0x41);
+			WriteHSCX(hscx, IPAC_MASKB, 0);
+			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
+			break;
+		default:
+			pr_info("%s: protocol not known %x\n", hscx->ip->name,
+				bprotocol);
+			return -ENOPROTOOPT;
+		}
+	} else
+		return -EINVAL;
+	hscx->bch.state = bprotocol;
+	return 0;
+}
+
+static int
+hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
+	int ret = -EINVAL;
+	struct mISDNhead *hh = mISDN_HEAD_P(skb);
+	u32 id;
+	u_long flags;
+
+	switch (hh->prim) {
+	case PH_DATA_REQ:
+		spin_lock_irqsave(hx->ip->hwlock, flags);
+		ret = bchannel_senddata(bch, skb);
+		if (ret > 0) { /* direct TX */
+			id = hh->id; /* skb can be freed */
+			ret = 0;
+			hscx_fill_fifo(hx);
+			spin_unlock_irqrestore(hx->ip->hwlock, flags);
+			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
+				queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
+		} else
+			spin_unlock_irqrestore(hx->ip->hwlock, flags);
+		return ret;
+	case PH_ACTIVATE_REQ:
+		spin_lock_irqsave(hx->ip->hwlock, flags);
+		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
+			ret = hscx_mode(hx, ch->protocol);
+		else
+			ret = 0;
+		spin_unlock_irqrestore(hx->ip->hwlock, flags);
+		if (!ret)
+			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
+				NULL, GFP_KERNEL);
+		break;
+	case PH_DEACTIVATE_REQ:
+		spin_lock_irqsave(hx->ip->hwlock, flags);
+		mISDN_clear_bchannel(bch);
+		hscx_mode(hx, ISDN_P_NONE);
+		spin_unlock_irqrestore(hx->ip->hwlock, flags);
+		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
+			NULL, GFP_KERNEL);
+		ret = 0;
+		break;
+	default:
+		pr_info("%s: %s unknown prim(%x,%x)\n",
+			hx->ip->name, __func__, hh->prim, hh->id);
+		ret = -EINVAL;
+	}
+	if (!ret)
+		dev_kfree_skb(skb);
+	return ret;
+}
+
+static int
+channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = 0;
+		break;
+	/* Nothing implemented yet */
+	case MISDN_CTRL_FILL_EMPTY:
+	default:
+		pr_info("%s: unknown Op %x\n", __func__, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
+	int ret = -EINVAL;
+	u_long flags;
+
+	pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
+	switch (cmd) {
+	case CLOSE_CHANNEL:
+		test_and_clear_bit(FLG_OPEN, &bch->Flags);
+		if (test_bit(FLG_ACTIVE, &bch->Flags)) {
+			spin_lock_irqsave(hx->ip->hwlock, flags);
+			mISDN_freebchannel(bch);
+			hscx_mode(hx, ISDN_P_NONE);
+			spin_unlock_irqrestore(hx->ip->hwlock, flags);
+		} else {
+			skb_queue_purge(&bch->rqueue);
+			bch->rcount = 0;
+		}
+		ch->protocol = ISDN_P_NONE;
+		ch->peer = NULL;
+		module_put(hx->ip->owner);
+		ret = 0;
+		break;
+	case CONTROL_CHANNEL:
+		ret = channel_bctrl(bch, arg);
+		break;
+	default:
+		pr_info("%s: %s unknown prim(%x)\n",
+			hx->ip->name, __func__, cmd);
+	}
+	return ret;
+}
+
+static void
+free_ipac(struct ipac_hw *ipac)
+{
+	isac_release(&ipac->isac);
+}
+
+static const char *HSCXVer[] =
+{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
+ "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
+
+
+
+static void
+hscx_init(struct hscx_hw *hx)
+{
+	u8 val;
+
+	WriteHSCX(hx, IPAC_RAH2, 0xFF);
+	WriteHSCX(hx, IPAC_XBCH, 0x00);
+	WriteHSCX(hx, IPAC_RLCR, 0x00);
+
+	if (hx->ip->type & IPAC_TYPE_HSCX) {
+		WriteHSCX(hx, IPAC_CCR1, 0x85);
+		val = ReadHSCX(hx, HSCX_VSTR);
+		pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
+		if (hx->bch.debug & DEBUG_HW)
+			pr_notice("%s: HSCX version %s\n", hx->ip->name,
+				HSCXVer[val & 0x0f]);
+	} else
+		WriteHSCX(hx, IPAC_CCR1, 0x82);
+	WriteHSCX(hx, IPAC_CCR2, 0x30);
+	WriteHSCX(hx, IPAC_XCCR, 0x07);
+	WriteHSCX(hx, IPAC_RCCR, 0x07);
+}
+
+static int
+ipac_init(struct ipac_hw *ipac)
+{
+	u8 val;
+
+	if (ipac->type & IPAC_TYPE_HSCX) {
+		hscx_init(&ipac->hscx[0]);
+		hscx_init(&ipac->hscx[1]);
+		val = ReadIPAC(ipac, IPAC_ID);
+	} else if (ipac->type & IPAC_TYPE_IPAC) {
+		hscx_init(&ipac->hscx[0]);
+		hscx_init(&ipac->hscx[1]);
+		WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
+		val = ReadIPAC(ipac, IPAC_CONF);
+		/* conf is default 0, but can be overwritten by card setup */
+		pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
+			val, ipac->conf);
+		WriteIPAC(ipac, IPAC_CONF, ipac->conf);
+		val = ReadIPAC(ipac, IPAC_ID);
+		if (ipac->hscx[0].bch.debug & DEBUG_HW)
+			pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
+	}
+	/* nothing special for IPACX to do here */
+	return isac_init(&ipac->isac);
+}
+
+static int
+open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
+{
+	struct bchannel		*bch;
+
+	if (rq->adr.channel > 2)
+		return -EINVAL;
+	if (rq->protocol == ISDN_P_NONE)
+		return -EINVAL;
+	bch = &ipac->hscx[rq->adr.channel - 1].bch;
+	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
+		return -EBUSY; /* b-channel can be only open once */
+	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
+	bch->ch.protocol = rq->protocol;
+	rq->ch = &bch->ch;
+	return 0;
+}
+
+static int
+channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = MISDN_CTRL_LOOP;
+		break;
+	case MISDN_CTRL_LOOP:
+		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
+		if (cq->channel < 0 || cq->channel > 3) {
+			ret = -EINVAL;
+			break;
+		}
+		ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
+		break;
+	default:
+		pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
+	struct dchannel *dch = container_of(dev, struct dchannel, dev);
+	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
+	struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
+	struct channel_req *rq;
+	int err = 0;
+
+	pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
+	switch (cmd) {
+	case OPEN_CHANNEL:
+		rq = arg;
+		if (rq->protocol == ISDN_P_TE_S0)
+			err = open_dchannel(isac, rq);
+		else
+			err = open_bchannel(ipac, rq);
+		if (err)
+			break;
+		if (!try_module_get(ipac->owner))
+			pr_info("%s: cannot get module\n", ipac->name);
+		break;
+	case CLOSE_CHANNEL:
+		pr_debug("%s: dev(%d) close from %p\n", ipac->name,
+			dch->dev.id, __builtin_return_address(0));
+		module_put(ipac->owner);
+		break;
+	case CONTROL_CHANNEL:
+		err = channel_ctrl(ipac, arg);
+		break;
+	default:
+		pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
+		return -EINVAL;
+	}
+	return err;
+}
+
+u32
+mISDNipac_init(struct ipac_hw *ipac, void *hw)
+{
+	u32 ret;
+	u8 i;
+
+	ipac->hw = hw;
+	if (ipac->isac.dch.debug & DEBUG_HW)
+		pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
+	if (ipac->type & IPAC_TYPE_HSCX) {
+		ipac->isac.type = IPAC_TYPE_ISAC;
+		ipac->hscx[0].off = 0;
+		ipac->hscx[1].off = 0x40;
+		ipac->hscx[0].fifo_size = 32;
+		ipac->hscx[1].fifo_size = 32;
+	} else if (ipac->type & IPAC_TYPE_IPAC) {
+		ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
+		ipac->hscx[0].off = 0;
+		ipac->hscx[1].off = 0x40;
+		ipac->hscx[0].fifo_size = 64;
+		ipac->hscx[1].fifo_size = 64;
+	} else if (ipac->type & IPAC_TYPE_IPACX) {
+		ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
+		ipac->hscx[0].off = IPACX_OFF_ICA;
+		ipac->hscx[1].off = IPACX_OFF_ICB;
+		ipac->hscx[0].fifo_size = 64;
+		ipac->hscx[1].fifo_size = 64;
+	} else
+		return 0;
+
+	mISDNisac_init(&ipac->isac, hw);
+
+	ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
+
+	for (i = 0; i < 2; i++) {
+		ipac->hscx[i].bch.nr = i + 1;
+		set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
+		list_add(&ipac->hscx[i].bch.ch.list,
+			&ipac->isac.dch.dev.bchannels);
+		mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM);
+		ipac->hscx[i].bch.ch.nr = i + 1;
+		ipac->hscx[i].bch.ch.send = &hscx_l2l1;
+		ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
+		ipac->hscx[i].bch.hw = hw;
+		ipac->hscx[i].ip = ipac;
+		/* default values for IOM time slots
+		 * can be overwriten by card */
+		ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
+	}
+
+	ipac->init = ipac_init;
+	ipac->release = free_ipac;
+
+	ret =	(1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+	return ret;
+}
+EXPORT_SYMBOL(mISDNipac_init);
+
+static int __init
+isac_mod_init(void)
+{
+	pr_notice("mISDNipac module version %s\n", ISAC_REV);
+	return 0;
+}
+
+static void __exit
+isac_mod_cleanup(void)
+{
+	pr_notice("mISDNipac module unloaded\n");
+}
+module_init(isac_mod_init);
+module_exit(isac_mod_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
new file mode 100644
index 0000000..de352a1
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -0,0 +1,1726 @@
+/*
+ * mISDNisar.c   ISAR (Siemens PSB 7110) specific functions
+ *
+ * Author Karsten Keil (keil@isdn4linux.de)
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* define this to enable static debug messages, if you kernel supports
+ * dynamic debugging, you should use debugfs for this
+ */
+/* #define DEBUG */
+
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include <linux/mISDNhw.h>
+#include "isar.h"
+
+#define ISAR_REV	"2.1"
+
+MODULE_AUTHOR("Karsten Keil");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(ISAR_REV);
+
+#define DEBUG_HW_FIRMWARE_FIFO	0x10000
+
+static const u8 faxmodulation_s[] = "3,24,48,72,73,74,96,97,98,121,122,145,146";
+static const u8 faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121,
+					122, 145, 146};
+#define FAXMODCNT 13
+
+static void isar_setup(struct isar_hw *);
+
+static inline int
+waitforHIA(struct isar_hw *isar, int timeout)
+{
+	int t = timeout;
+	u8 val = isar->read_reg(isar->hw, ISAR_HIA);
+
+	while ((val & 1) && t) {
+		udelay(1);
+		t--;
+		val = isar->read_reg(isar->hw, ISAR_HIA);
+	}
+	pr_debug("%s: HIA after %dus\n", isar->name, timeout - t);
+	return timeout;
+}
+
+/*
+ * send msg to ISAR mailbox
+ * if msg is NULL use isar->buf
+ */
+static int
+send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 *msg)
+{
+	if (!waitforHIA(isar, 1000))
+		return 0;
+	pr_debug("send_mbox(%02x,%02x,%d)\n", his, creg, len);
+	isar->write_reg(isar->hw, ISAR_CTRL_H, creg);
+	isar->write_reg(isar->hw, ISAR_CTRL_L, len);
+	isar->write_reg(isar->hw, ISAR_WADR, 0);
+	if (!msg)
+		msg = isar->buf;
+	if (msg && len) {
+		isar->write_fifo(isar->hw, ISAR_MBOX, msg, len);
+		if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
+			int l = 0;
+
+			while (l < (int)len) {
+				hex_dump_to_buffer(msg + l, len - l, 32, 1,
+					isar->log, 256, 1);
+				pr_debug("%s: %s %02x: %s\n", isar->name,
+					__func__, l, isar->log);
+				l += 32;
+			}
+		}
+	}
+	isar->write_reg(isar->hw, ISAR_HIS, his);
+	waitforHIA(isar, 1000);
+	return 1;
+}
+
+/*
+ * receive message from ISAR mailbox
+ * if msg is NULL use isar->buf
+ */
+static void
+rcv_mbox(struct isar_hw *isar, u8 *msg)
+{
+	if (!msg)
+		msg = isar->buf;
+	isar->write_reg(isar->hw, ISAR_RADR, 0);
+	if (msg && isar->clsb) {
+		isar->read_fifo(isar->hw, ISAR_MBOX, msg, isar->clsb);
+		if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
+			int l = 0;
+
+			while (l < (int)isar->clsb) {
+				hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
+					1, isar->log, 256, 1);
+				pr_debug("%s: %s %02x: %s\n", isar->name,
+					__func__, l, isar->log);
+				l += 32;
+			}
+		}
+	}
+	isar->write_reg(isar->hw, ISAR_IIA, 0);
+}
+
+static inline void
+get_irq_infos(struct isar_hw *isar)
+{
+	isar->iis = isar->read_reg(isar->hw, ISAR_IIS);
+	isar->cmsb = isar->read_reg(isar->hw, ISAR_CTRL_H);
+	isar->clsb = isar->read_reg(isar->hw, ISAR_CTRL_L);
+	pr_debug("%s: rcv_mbox(%02x,%02x,%d)\n", isar->name,
+		isar->iis, isar->cmsb, isar->clsb);
+}
+
+/*
+ * poll answer message from ISAR mailbox
+ * should be used only with ISAR IRQs disabled before DSP was started
+ *
+ */
+static int
+poll_mbox(struct isar_hw *isar, int maxdelay)
+{
+	int t = maxdelay;
+	u8 irq;
+
+	irq = isar->read_reg(isar->hw, ISAR_IRQBIT);
+	while (t && !(irq & ISAR_IRQSTA)) {
+		udelay(1);
+		t--;
+	}
+	if (t)	{
+		get_irq_infos(isar);
+		rcv_mbox(isar, NULL);
+	}
+	pr_debug("%s: pulled %d bytes after %d us\n",
+		isar->name, isar->clsb, maxdelay - t);
+	return t;
+}
+
+static int
+ISARVersion(struct isar_hw *isar)
+{
+	int ver;
+
+	/* disable ISAR IRQ */
+	isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
+	isar->buf[0] = ISAR_MSG_HWVER;
+	isar->buf[1] = 0;
+	isar->buf[2] = 1;
+	if (!send_mbox(isar, ISAR_HIS_VNR, 0, 3, NULL))
+		return -1;
+	if (!poll_mbox(isar, 1000))
+		return -2;
+	if (isar->iis == ISAR_IIS_VNR) {
+		if (isar->clsb == 1) {
+			ver = isar->buf[0] & 0xf;
+			return ver;
+		}
+		return -3;
+	}
+	return -4;
+}
+
+static int
+load_firmware(struct isar_hw *isar, const u8 *buf, int size)
+{
+	u32	saved_debug = isar->ch[0].bch.debug;
+	int	ret, cnt;
+	u8	nom, noc;
+	u16	left, val, *sp = (u16 *)buf;
+	u8	*mp;
+	u_long	flags;
+
+	struct {
+		u16 sadr;
+		u16 len;
+		u16 d_key;
+	} blk_head;
+
+	if (1 != isar->version) {
+		pr_err("%s: ISAR wrong version %d firmware download aborted\n",
+			isar->name, isar->version);
+		return -EINVAL;
+	}
+	if (!(saved_debug & DEBUG_HW_FIRMWARE_FIFO))
+		isar->ch[0].bch.debug &= ~DEBUG_HW_BFIFO;
+	pr_debug("%s: load firmware %d words (%d bytes)\n",
+		isar->name, size/2, size);
+	cnt = 0;
+	size /= 2;
+	/* disable ISAR IRQ */
+	spin_lock_irqsave(isar->hwlock, flags);
+	isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
+	spin_unlock_irqrestore(isar->hwlock, flags);
+	while (cnt < size) {
+		blk_head.sadr = le16_to_cpu(*sp++);
+		blk_head.len = le16_to_cpu(*sp++);
+		blk_head.d_key = le16_to_cpu(*sp++);
+		cnt += 3;
+		pr_debug("ISAR firmware block (%#x,%d,%#x)\n",
+			blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
+		left = blk_head.len;
+		if (cnt + left > size) {
+			pr_info("%s: firmware error have %d need %d words\n",
+				isar->name, size, cnt + left);
+			ret = -EINVAL;
+			goto reterrflg;
+		}
+		spin_lock_irqsave(isar->hwlock, flags);
+		if (!send_mbox(isar, ISAR_HIS_DKEY, blk_head.d_key & 0xff,
+		    0, NULL)) {
+			pr_info("ISAR send_mbox dkey failed\n");
+			ret = -ETIME;
+			goto reterror;
+		}
+		if (!poll_mbox(isar, 1000)) {
+			pr_warning("ISAR poll_mbox dkey failed\n");
+			ret = -ETIME;
+			goto reterror;
+		}
+		spin_unlock_irqrestore(isar->hwlock, flags);
+		if ((isar->iis != ISAR_IIS_DKEY) || isar->cmsb || isar->clsb) {
+			pr_info("ISAR wrong dkey response (%x,%x,%x)\n",
+				isar->iis, isar->cmsb, isar->clsb);
+			ret = 1;
+			goto reterrflg;
+		}
+		while (left > 0) {
+			if (left > 126)
+				noc = 126;
+			else
+				noc = left;
+			nom = (2 * noc) + 3;
+			mp  = isar->buf;
+			/* the ISAR is big endian */
+			*mp++ = blk_head.sadr >> 8;
+			*mp++ = blk_head.sadr & 0xFF;
+			left -= noc;
+			cnt += noc;
+			*mp++ = noc;
+			pr_debug("%s: load %3d words at %04x\n", isar->name,
+				noc, blk_head.sadr);
+			blk_head.sadr += noc;
+			while (noc) {
+				val = le16_to_cpu(*sp++);
+				*mp++ = val >> 8;
+				*mp++ = val & 0xFF;;
+				noc--;
+			}
+			spin_lock_irqsave(isar->hwlock, flags);
+			if (!send_mbox(isar, ISAR_HIS_FIRM, 0, nom, NULL)) {
+				pr_info("ISAR send_mbox prog failed\n");
+				ret = -ETIME;
+				goto reterror;
+			}
+			if (!poll_mbox(isar, 1000)) {
+				pr_info("ISAR poll_mbox prog failed\n");
+				ret = -ETIME;
+				goto reterror;
+			}
+			spin_unlock_irqrestore(isar->hwlock, flags);
+			if ((isar->iis != ISAR_IIS_FIRM) ||
+			    isar->cmsb || isar->clsb) {
+				pr_info("ISAR wrong prog response (%x,%x,%x)\n",
+					isar->iis, isar->cmsb, isar->clsb);
+				ret = -EIO;
+				goto reterrflg;
+			}
+		}
+		pr_debug("%s: ISAR firmware block %d words loaded\n",
+			isar->name, blk_head.len);
+	}
+	isar->ch[0].bch.debug = saved_debug;
+	/* 10ms delay */
+	cnt = 10;
+	while (cnt--)
+		mdelay(1);
+	isar->buf[0] = 0xff;
+	isar->buf[1] = 0xfe;
+	isar->bstat = 0;
+	spin_lock_irqsave(isar->hwlock, flags);
+	if (!send_mbox(isar, ISAR_HIS_STDSP, 0, 2, NULL)) {
+		pr_info("ISAR send_mbox start dsp failed\n");
+		ret = -ETIME;
+		goto reterror;
+	}
+	if (!poll_mbox(isar, 1000)) {
+		pr_info("ISAR poll_mbox start dsp failed\n");
+		ret = -ETIME;
+		goto reterror;
+	}
+	if ((isar->iis != ISAR_IIS_STDSP) || isar->cmsb || isar->clsb) {
+		pr_info("ISAR wrong start dsp response (%x,%x,%x)\n",
+			isar->iis, isar->cmsb, isar->clsb);
+		ret = -EIO;
+		goto reterror;
+	} else
+		pr_debug("%s: ISAR start dsp success\n", isar->name);
+
+	/* NORMAL mode entered */
+	/* Enable IRQs of ISAR */
+	isar->write_reg(isar->hw, ISAR_IRQBIT, ISAR_IRQSTA);
+	spin_unlock_irqrestore(isar->hwlock, flags);
+	cnt = 1000; /* max 1s */
+	while ((!isar->bstat) && cnt) {
+		mdelay(1);
+		cnt--;
+	}
+	if (!cnt) {
+		pr_info("ISAR no general status event received\n");
+		ret = -ETIME;
+		goto reterrflg;
+	} else
+		pr_debug("%s: ISAR general status event %x\n",
+			isar->name, isar->bstat);
+	/* 10ms delay */
+	cnt = 10;
+	while (cnt--)
+		mdelay(1);
+	isar->iis = 0;
+	spin_lock_irqsave(isar->hwlock, flags);
+	if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
+		pr_info("ISAR send_mbox self tst failed\n");
+		ret = -ETIME;
+		goto reterror;
+	}
+	spin_unlock_irqrestore(isar->hwlock, flags);
+	cnt = 10000; /* max 100 ms */
+	while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
+		udelay(10);
+		cnt--;
+	}
+	mdelay(1);
+	if (!cnt) {
+		pr_info("ISAR no self tst response\n");
+		ret = -ETIME;
+		goto reterrflg;
+	}
+	if ((isar->cmsb == ISAR_CTRL_STST) && (isar->clsb == 1)
+	    && (isar->buf[0] == 0))
+		pr_debug("%s: ISAR selftest OK\n", isar->name);
+	else {
+		pr_info("ISAR selftest not OK %x/%x/%x\n",
+			isar->cmsb, isar->clsb, isar->buf[0]);
+		ret = -EIO;
+		goto reterrflg;
+	}
+	spin_lock_irqsave(isar->hwlock, flags);
+	isar->iis = 0;
+	if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
+		pr_info("ISAR RQST SVN failed\n");
+		ret = -ETIME;
+		goto reterror;
+	}
+	spin_unlock_irqrestore(isar->hwlock, flags);
+	cnt = 30000; /* max 300 ms */
+	while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
+		udelay(10);
+		cnt--;
+	}
+	mdelay(1);
+	if (!cnt) {
+		pr_info("ISAR no SVN response\n");
+		ret = -ETIME;
+		goto reterrflg;
+	} else {
+		if ((isar->cmsb == ISAR_CTRL_SWVER) && (isar->clsb == 1)) {
+			pr_notice("%s: ISAR software version %#x\n",
+				isar->name, isar->buf[0]);
+		} else {
+			pr_info("%s: ISAR wrong swver response (%x,%x)"
+				" cnt(%d)\n", isar->name, isar->cmsb,
+				isar->clsb, cnt);
+			ret = -EIO;
+			goto reterrflg;
+		}
+	}
+	spin_lock_irqsave(isar->hwlock, flags);
+	isar_setup(isar);
+	spin_unlock_irqrestore(isar->hwlock, flags);
+	ret = 0;
+reterrflg:
+	spin_lock_irqsave(isar->hwlock, flags);
+reterror:
+	isar->ch[0].bch.debug = saved_debug;
+	if (ret)
+		/* disable ISAR IRQ */
+		isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
+	spin_unlock_irqrestore(isar->hwlock, flags);
+	return ret;
+}
+
+static inline void
+deliver_status(struct isar_ch *ch, int status)
+{
+	pr_debug("%s: HL->LL FAXIND %x\n", ch->is->name, status);
+	_queue_data(&ch->bch.ch, PH_CONTROL_IND, status, 0, NULL, GFP_ATOMIC);
+}
+
+static inline void
+isar_rcv_frame(struct isar_ch *ch)
+{
+	u8		*ptr;
+
+	if (!ch->is->clsb) {
+		pr_debug("%s; ISAR zero len frame\n", ch->is->name);
+		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+		return;
+	}
+	switch (ch->bch.state) {
+	case ISDN_P_NONE:
+		pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n",
+			ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb);
+		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+		break;
+	case ISDN_P_B_RAW:
+	case ISDN_P_B_L2DTMF:
+	case ISDN_P_B_MODEM_ASYNC:
+		if (!ch->bch.rx_skb) {
+			ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
+						GFP_ATOMIC);
+			if (unlikely(!ch->bch.rx_skb)) {
+				pr_info("%s: B receive out of memory\n",
+					ch->is->name);
+				ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+				break;
+			}
+		}
+		rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
+		recv_Bchannel(&ch->bch, 0);
+		break;
+	case ISDN_P_B_HDLC:
+		if (!ch->bch.rx_skb) {
+			ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
+						GFP_ATOMIC);
+			if (unlikely(!ch->bch.rx_skb)) {
+				pr_info("%s: B receive out of memory\n",
+					ch->is->name);
+				ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+				break;
+			}
+		}
+		if ((ch->bch.rx_skb->len + ch->is->clsb) >
+		    (ch->bch.maxlen + 2)) {
+			pr_debug("%s: incoming packet too large\n",
+				ch->is->name);
+			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+			skb_trim(ch->bch.rx_skb, 0);
+			break;
+		}
+		if (ch->is->cmsb & HDLC_ERROR) {
+			pr_debug("%s: ISAR frame error %x len %d\n",
+				ch->is->name, ch->is->cmsb, ch->is->clsb);
+#ifdef ERROR_STATISTIC
+			if (ch->is->cmsb & HDLC_ERR_RER)
+				ch->bch.err_inv++;
+			if (ch->is->cmsb & HDLC_ERR_CER)
+				ch->bch.err_crc++;
+#endif
+			skb_trim(ch->bch.rx_skb, 0);
+			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+			break;
+		}
+		if (ch->is->cmsb & HDLC_FSD)
+			skb_trim(ch->bch.rx_skb, 0);
+		ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
+		rcv_mbox(ch->is, ptr);
+		if (ch->is->cmsb & HDLC_FED) {
+			if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
+				pr_debug("%s: ISAR frame to short %d\n",
+					ch->is->name, ch->bch.rx_skb->len);
+				skb_trim(ch->bch.rx_skb, 0);
+				break;
+			}
+			skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
+			recv_Bchannel(&ch->bch, 0);
+		}
+		break;
+	case ISDN_P_B_T30_FAX:
+		if (ch->state != STFAX_ACTIV) {
+			pr_debug("%s: isar_rcv_frame: not ACTIV\n",
+				ch->is->name);
+			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+			if (ch->bch.rx_skb)
+				skb_trim(ch->bch.rx_skb, 0);
+			break;
+		}
+		if (!ch->bch.rx_skb) {
+			ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
+						GFP_ATOMIC);
+			if (unlikely(!ch->bch.rx_skb)) {
+				pr_info("%s: B receive out of memory\n",
+					__func__);
+				ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+				break;
+			}
+		}
+		if (ch->cmd == PCTRL_CMD_FRM) {
+			rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
+			pr_debug("%s: isar_rcv_frame: %d\n",
+				ch->is->name, ch->bch.rx_skb->len);
+			if (ch->is->cmsb & SART_NMD) { /* ABORT */
+				pr_debug("%s: isar_rcv_frame: no more data\n",
+					ch->is->name);
+				ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+				send_mbox(ch->is, SET_DPS(ch->dpath) |
+					ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
+					0, NULL);
+				ch->state = STFAX_ESCAPE;
+				/* set_skb_flag(skb, DF_NOMOREDATA); */
+			}
+			recv_Bchannel(&ch->bch, 0);
+			if (ch->is->cmsb & SART_NMD)
+				deliver_status(ch, HW_MOD_NOCARR);
+			break;
+		}
+		if (ch->cmd != PCTRL_CMD_FRH) {
+			pr_debug("%s: isar_rcv_frame: unknown fax mode %x\n",
+				ch->is->name, ch->cmd);
+			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+			if (ch->bch.rx_skb)
+				skb_trim(ch->bch.rx_skb, 0);
+			break;
+		}
+		/* PCTRL_CMD_FRH */
+		if ((ch->bch.rx_skb->len + ch->is->clsb) >
+		    (ch->bch.maxlen + 2)) {
+			pr_info("%s: %s incoming packet too large\n",
+				ch->is->name, __func__);
+			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+			skb_trim(ch->bch.rx_skb, 0);
+			break;
+		}  else if (ch->is->cmsb & HDLC_ERROR) {
+			pr_info("%s: ISAR frame error %x len %d\n",
+				ch->is->name, ch->is->cmsb, ch->is->clsb);
+			skb_trim(ch->bch.rx_skb, 0);
+			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+			break;
+		}
+		if (ch->is->cmsb & HDLC_FSD)
+			skb_trim(ch->bch.rx_skb, 0);
+		ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
+		rcv_mbox(ch->is, ptr);
+		if (ch->is->cmsb & HDLC_FED) {
+			if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
+				pr_info("%s: ISAR frame to short %d\n",
+					ch->is->name, ch->bch.rx_skb->len);
+				skb_trim(ch->bch.rx_skb, 0);
+				break;
+			}
+			skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
+			recv_Bchannel(&ch->bch, 0);
+		}
+		if (ch->is->cmsb & SART_NMD) { /* ABORT */
+			pr_debug("%s: isar_rcv_frame: no more data\n",
+				ch->is->name);
+			ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+			if (ch->bch.rx_skb)
+				skb_trim(ch->bch.rx_skb, 0);
+			send_mbox(ch->is, SET_DPS(ch->dpath) |
+				ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
+			ch->state = STFAX_ESCAPE;
+			deliver_status(ch, HW_MOD_NOCARR);
+		}
+		break;
+	default:
+		pr_info("isar_rcv_frame protocol (%x)error\n", ch->bch.state);
+		ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
+		break;
+	}
+}
+
+static void
+isar_fill_fifo(struct isar_ch *ch)
+{
+	int count;
+	u8 msb;
+	u8 *ptr;
+
+	pr_debug("%s: ch%d  tx_skb %p tx_idx %d\n",
+		ch->is->name, ch->bch.nr, ch->bch.tx_skb, ch->bch.tx_idx);
+	if (!ch->bch.tx_skb)
+		return;
+	count = ch->bch.tx_skb->len - ch->bch.tx_idx;
+	if (count <= 0)
+		return;
+	if (!(ch->is->bstat &
+		(ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
+		return;
+	if (count > ch->mml) {
+		msb = 0;
+		count = ch->mml;
+	} else {
+		msb = HDLC_FED;
+	}
+	ptr = ch->bch.tx_skb->data + ch->bch.tx_idx;
+	if (!ch->bch.tx_idx) {
+		pr_debug("%s: frame start\n", ch->is->name);
+		if ((ch->bch.state == ISDN_P_B_T30_FAX) &&
+			(ch->cmd == PCTRL_CMD_FTH)) {
+			if (count > 1) {
+				if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) {
+					/* last frame */
+					test_and_set_bit(FLG_LASTDATA,
+						&ch->bch.Flags);
+					pr_debug("%s: set LASTDATA\n",
+						ch->is->name);
+					if (msb == HDLC_FED)
+						test_and_set_bit(FLG_DLEETX,
+							&ch->bch.Flags);
+				}
+			}
+		}
+		msb |= HDLC_FST;
+	}
+	ch->bch.tx_idx += count;
+	switch (ch->bch.state) {
+	case ISDN_P_NONE:
+		pr_info("%s: wrong protocol 0\n", __func__);
+		break;
+	case ISDN_P_B_RAW:
+	case ISDN_P_B_L2DTMF:
+	case ISDN_P_B_MODEM_ASYNC:
+		send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
+			0, count, ptr);
+		break;
+	case ISDN_P_B_HDLC:
+		send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
+			msb, count, ptr);
+		break;
+	case ISDN_P_B_T30_FAX:
+		if (ch->state != STFAX_ACTIV)
+			pr_debug("%s: not ACTIV\n", ch->is->name);
+		else if (ch->cmd == PCTRL_CMD_FTH)
+			send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
+				msb, count, ptr);
+		else if (ch->cmd == PCTRL_CMD_FTM)
+			send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
+				0, count, ptr);
+		else
+			pr_debug("%s: not FTH/FTM\n", ch->is->name);
+		break;
+	default:
+		pr_info("%s: protocol(%x) error\n",
+			__func__, ch->bch.state);
+		break;
+	}
+}
+
+static inline struct isar_ch *
+sel_bch_isar(struct isar_hw *isar, u8 dpath)
+{
+	struct isar_ch	*base = &isar->ch[0];
+
+	if ((!dpath) || (dpath > 2))
+		return NULL;
+	if (base->dpath == dpath)
+		return base;
+	base++;
+	if (base->dpath == dpath)
+		return base;
+	return NULL;
+}
+
+static void
+send_next(struct isar_ch *ch)
+{
+	pr_debug("%s: %s ch%d tx_skb %p tx_idx %d\n",
+		ch->is->name, __func__, ch->bch.nr,
+		ch->bch.tx_skb, ch->bch.tx_idx);
+	if (ch->bch.state == ISDN_P_B_T30_FAX) {
+		if (ch->cmd == PCTRL_CMD_FTH) {
+			if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
+				pr_debug("set NMD_DATA\n");
+				test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
+			}
+		} else if (ch->cmd == PCTRL_CMD_FTM) {
+			if (test_bit(FLG_DLEETX, &ch->bch.Flags)) {
+				test_and_set_bit(FLG_LASTDATA, &ch->bch.Flags);
+				test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
+			}
+		}
+	}
+	if (ch->bch.tx_skb) {
+		/* send confirm, on trans, free on hdlc. */
+		if (test_bit(FLG_TRANSPARENT, &ch->bch.Flags))
+			confirm_Bsend(&ch->bch);
+		dev_kfree_skb(ch->bch.tx_skb);
+	}
+	if (get_next_bframe(&ch->bch))
+		isar_fill_fifo(ch);
+	else {
+		if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
+			if (test_and_clear_bit(FLG_LASTDATA,
+			    &ch->bch.Flags)) {
+				if (test_and_clear_bit(FLG_NMD_DATA,
+				    &ch->bch.Flags)) {
+					u8 zd = 0;
+					send_mbox(ch->is, SET_DPS(ch->dpath) |
+						ISAR_HIS_SDATA, 0x01, 1, &zd);
+				}
+				test_and_set_bit(FLG_LL_OK, &ch->bch.Flags);
+			} else {
+				deliver_status(ch, HW_MOD_CONNECT);
+			}
+		}
+	}
+}
+
+static void
+check_send(struct isar_hw *isar, u8 rdm)
+{
+	struct isar_ch	*ch;
+
+	pr_debug("%s: rdm %x\n", isar->name, rdm);
+	if (rdm & BSTAT_RDM1) {
+		ch = sel_bch_isar(isar, 1);
+		if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
+			if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
+			    ch->bch.tx_idx))
+				isar_fill_fifo(ch);
+			else
+				send_next(ch);
+		}
+	}
+	if (rdm & BSTAT_RDM2) {
+		ch = sel_bch_isar(isar, 2);
+		if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
+			if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
+			    ch->bch.tx_idx))
+				isar_fill_fifo(ch);
+			else
+				send_next(ch);
+		}
+	}
+}
+
+const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
+			"300", "600", "1200", "2400", "4800", "7200",
+			"9600nt", "9600t", "12000", "14400", "WRONG"};
+const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
+			"Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
+
+static void
+isar_pump_status_rsp(struct isar_ch *ch) {
+	u8 ril = ch->is->buf[0];
+	u8 rim;
+
+	if (!test_and_clear_bit(ISAR_RATE_REQ, &ch->is->Flags))
+		return;
+	if (ril > 14) {
+		pr_info("%s: wrong pstrsp ril=%d\n", ch->is->name, ril);
+		ril = 15;
+	}
+	switch (ch->is->buf[1]) {
+	case 0:
+		rim = 0;
+		break;
+	case 0x20:
+		rim = 2;
+		break;
+	case 0x40:
+		rim = 3;
+		break;
+	case 0x41:
+		rim = 4;
+		break;
+	case 0x51:
+		rim = 5;
+		break;
+	case 0x61:
+		rim = 6;
+		break;
+	case 0x71:
+		rim = 7;
+		break;
+	case 0x82:
+		rim = 8;
+		break;
+	case 0x92:
+		rim = 9;
+		break;
+	case 0xa2:
+		rim = 10;
+		break;
+	default:
+		rim = 1;
+		break;
+	}
+	sprintf(ch->conmsg, "%s %s", dmril[ril], dmrim[rim]);
+	pr_debug("%s: pump strsp %s\n", ch->is->name, ch->conmsg);
+}
+
+static void
+isar_pump_statev_modem(struct isar_ch *ch, u8 devt) {
+	u8 dps = SET_DPS(ch->dpath);
+
+	switch (devt) {
+	case PSEV_10MS_TIMER:
+		pr_debug("%s: pump stev TIMER\n", ch->is->name);
+		break;
+	case PSEV_CON_ON:
+		pr_debug("%s: pump stev CONNECT\n", ch->is->name);
+		deliver_status(ch, HW_MOD_CONNECT);
+		break;
+	case PSEV_CON_OFF:
+		pr_debug("%s: pump stev NO CONNECT\n", ch->is->name);
+		send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+		deliver_status(ch, HW_MOD_NOCARR);
+		break;
+	case PSEV_V24_OFF:
+		pr_debug("%s: pump stev V24 OFF\n", ch->is->name);
+		break;
+	case PSEV_CTS_ON:
+		pr_debug("%s: pump stev CTS ON\n", ch->is->name);
+		break;
+	case PSEV_CTS_OFF:
+		pr_debug("%s pump stev CTS OFF\n", ch->is->name);
+		break;
+	case PSEV_DCD_ON:
+		pr_debug("%s: pump stev CARRIER ON\n", ch->is->name);
+		test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
+		send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+		break;
+	case PSEV_DCD_OFF:
+		pr_debug("%s: pump stev CARRIER OFF\n", ch->is->name);
+		break;
+	case PSEV_DSR_ON:
+		pr_debug("%s: pump stev DSR ON\n", ch->is->name);
+		break;
+	case PSEV_DSR_OFF:
+		pr_debug("%s: pump stev DSR_OFF\n", ch->is->name);
+		break;
+	case PSEV_REM_RET:
+		pr_debug("%s: pump stev REMOTE RETRAIN\n", ch->is->name);
+		break;
+	case PSEV_REM_REN:
+		pr_debug("%s: pump stev REMOTE RENEGOTIATE\n", ch->is->name);
+		break;
+	case PSEV_GSTN_CLR:
+		pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
+		break;
+	default:
+		pr_info("u%s: nknown pump stev %x\n", ch->is->name, devt);
+		break;
+	}
+}
+
+static void
+isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
+	u8 dps = SET_DPS(ch->dpath);
+	u8 p1;
+
+	switch (devt) {
+	case PSEV_10MS_TIMER:
+		pr_debug("%s: pump stev TIMER\n", ch->is->name);
+		break;
+	case PSEV_RSP_READY:
+		pr_debug("%s: pump stev RSP_READY\n", ch->is->name);
+		ch->state = STFAX_READY;
+		deliver_status(ch, HW_MOD_READY);
+#ifdef AUTOCON
+		if (test_bit(BC_FLG_ORIG, &ch->bch.Flags))
+			isar_pump_cmd(bch, HW_MOD_FRH, 3);
+		else
+			isar_pump_cmd(bch, HW_MOD_FTH, 3);
+#endif
+		break;
+	case PSEV_LINE_TX_H:
+		if (ch->state == STFAX_LINE) {
+			pr_debug("%s: pump stev LINE_TX_H\n", ch->is->name);
+			ch->state = STFAX_CONT;
+			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+				PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			pr_debug("%s: pump stev LINE_TX_H wrong st %x\n",
+				ch->is->name, ch->state);
+		}
+		break;
+	case PSEV_LINE_RX_H:
+		if (ch->state == STFAX_LINE) {
+			pr_debug("%s: pump stev LINE_RX_H\n", ch->is->name);
+			ch->state = STFAX_CONT;
+			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+				PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			pr_debug("%s: pump stev LINE_RX_H wrong st %x\n",
+				ch->is->name, ch->state);
+		}
+		break;
+	case PSEV_LINE_TX_B:
+		if (ch->state == STFAX_LINE) {
+			pr_debug("%s: pump stev LINE_TX_B\n", ch->is->name);
+			ch->state = STFAX_CONT;
+			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+				PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			pr_debug("%s: pump stev LINE_TX_B wrong st %x\n",
+				ch->is->name, ch->state);
+		}
+		break;
+	case PSEV_LINE_RX_B:
+		if (ch->state == STFAX_LINE) {
+			pr_debug("%s: pump stev LINE_RX_B\n", ch->is->name);
+			ch->state = STFAX_CONT;
+			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+				PCTRL_CMD_CONT, 0, NULL);
+		} else {
+			pr_debug("%s: pump stev LINE_RX_B wrong st %x\n",
+				ch->is->name, ch->state);
+		}
+		break;
+	case PSEV_RSP_CONN:
+		if (ch->state == STFAX_CONT) {
+			pr_debug("%s: pump stev RSP_CONN\n", ch->is->name);
+			ch->state = STFAX_ACTIV;
+			test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
+			send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+			if (ch->cmd == PCTRL_CMD_FTH) {
+				int delay = (ch->mod == 3) ? 1000 : 200;
+				/* 1s (200 ms) Flags before data */
+				if (test_and_set_bit(FLG_FTI_RUN,
+				    &ch->bch.Flags))
+					del_timer(&ch->ftimer);
+				ch->ftimer.expires =
+					jiffies + ((delay * HZ)/1000);
+				test_and_set_bit(FLG_LL_CONN,
+					&ch->bch.Flags);
+				add_timer(&ch->ftimer);
+			} else {
+				deliver_status(ch, HW_MOD_CONNECT);
+			}
+		} else {
+			pr_debug("%s: pump stev RSP_CONN wrong st %x\n",
+				ch->is->name, ch->state);
+		}
+		break;
+	case PSEV_FLAGS_DET:
+		pr_debug("%s: pump stev FLAGS_DET\n", ch->is->name);
+		break;
+	case PSEV_RSP_DISC:
+		pr_debug("%s: pump stev RSP_DISC state(%d)\n",
+			ch->is->name, ch->state);
+		if (ch->state == STFAX_ESCAPE) {
+			p1 = 5;
+			switch (ch->newcmd) {
+			case 0:
+				ch->state = STFAX_READY;
+				break;
+			case PCTRL_CMD_FTM:
+				p1 = 2;
+			case PCTRL_CMD_FTH:
+				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+					PCTRL_CMD_SILON, 1, &p1);
+				ch->state = STFAX_SILDET;
+				break;
+			case PCTRL_CMD_FRH:
+			case PCTRL_CMD_FRM:
+				ch->mod = ch->newmod;
+				p1 = ch->newmod;
+				ch->newmod = 0;
+				ch->cmd = ch->newcmd;
+				ch->newcmd = 0;
+				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+					ch->cmd, 1, &p1);
+				ch->state = STFAX_LINE;
+				ch->try_mod = 3;
+				break;
+			default:
+				pr_debug("%s: RSP_DISC unknown newcmd %x\n",
+					ch->is->name, ch->newcmd);
+				break;
+			}
+		} else if (ch->state == STFAX_ACTIV) {
+			if (test_and_clear_bit(FLG_LL_OK, &ch->bch.Flags))
+				deliver_status(ch, HW_MOD_OK);
+			else if (ch->cmd == PCTRL_CMD_FRM)
+				deliver_status(ch, HW_MOD_NOCARR);
+			else
+				deliver_status(ch, HW_MOD_FCERROR);
+			ch->state = STFAX_READY;
+		} else if (ch->state != STFAX_SILDET) {
+			/* ignore in STFAX_SILDET */
+			ch->state = STFAX_READY;
+			deliver_status(ch, HW_MOD_FCERROR);
+		}
+		break;
+	case PSEV_RSP_SILDET:
+		pr_debug("%s: pump stev RSP_SILDET\n", ch->is->name);
+		if (ch->state == STFAX_SILDET) {
+			ch->mod = ch->newmod;
+			p1 = ch->newmod;
+			ch->newmod = 0;
+			ch->cmd = ch->newcmd;
+			ch->newcmd = 0;
+			send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+				ch->cmd, 1, &p1);
+			ch->state = STFAX_LINE;
+			ch->try_mod = 3;
+		}
+		break;
+	case PSEV_RSP_SILOFF:
+		pr_debug("%s: pump stev RSP_SILOFF\n", ch->is->name);
+		break;
+	case PSEV_RSP_FCERR:
+		if (ch->state == STFAX_LINE) {
+			pr_debug("%s: pump stev RSP_FCERR try %d\n",
+				ch->is->name, ch->try_mod);
+			if (ch->try_mod--) {
+				send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
+					ch->cmd, 1, &ch->mod);
+				break;
+			}
+		}
+		pr_debug("%s: pump stev RSP_FCERR\n", ch->is->name);
+		ch->state = STFAX_ESCAPE;
+		send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
+			0, NULL);
+		deliver_status(ch, HW_MOD_FCERROR);
+		break;
+	default:
+		break;
+	}
+}
+
+void
+mISDNisar_irq(struct isar_hw *isar)
+{
+	struct isar_ch *ch;
+
+	get_irq_infos(isar);
+	switch (isar->iis & ISAR_IIS_MSCMSD) {
+	case ISAR_IIS_RDATA:
+		ch = sel_bch_isar(isar, isar->iis >> 6);
+		if (ch)
+			isar_rcv_frame(ch);
+		else {
+			pr_debug("%s: ISAR spurious IIS_RDATA %x/%x/%x\n",
+				isar->name, isar->iis, isar->cmsb,
+				isar->clsb);
+			isar->write_reg(isar->hw, ISAR_IIA, 0);
+		}
+		break;
+	case ISAR_IIS_GSTEV:
+		isar->write_reg(isar->hw, ISAR_IIA, 0);
+		isar->bstat |= isar->cmsb;
+		check_send(isar, isar->cmsb);
+		break;
+	case ISAR_IIS_BSTEV:
+#ifdef ERROR_STATISTIC
+		ch = sel_bch_isar(isar, isar->iis >> 6);
+		if (ch) {
+			if (isar->cmsb == BSTEV_TBO)
+				ch->bch.err_tx++;
+			if (isar->cmsb == BSTEV_RBO)
+				ch->bch.err_rdo++;
+		}
+#endif
+		pr_debug("%s: Buffer STEV dpath%d msb(%x)\n",
+			isar->name, isar->iis>>6, isar->cmsb);
+		isar->write_reg(isar->hw, ISAR_IIA, 0);
+		break;
+	case ISAR_IIS_PSTEV:
+		ch = sel_bch_isar(isar, isar->iis >> 6);
+		if (ch) {
+			rcv_mbox(isar, NULL);
+			if (ch->bch.state == ISDN_P_B_MODEM_ASYNC)
+				isar_pump_statev_modem(ch, isar->cmsb);
+			else if (ch->bch.state == ISDN_P_B_T30_FAX)
+				isar_pump_statev_fax(ch, isar->cmsb);
+			else if (ch->bch.state == ISDN_P_B_RAW) {
+				int	tt;
+				tt = isar->cmsb | 0x30;
+				if (tt == 0x3e)
+					tt = '*';
+				else if (tt == 0x3f)
+					tt = '#';
+				else if (tt > '9')
+					tt += 7;
+				tt |= DTMF_TONE_VAL;
+				_queue_data(&ch->bch.ch, PH_CONTROL_IND,
+					MISDN_ID_ANY, sizeof(tt), &tt,
+					GFP_ATOMIC);
+			} else
+				pr_debug("%s: ISAR IIS_PSTEV pm %d sta %x\n",
+					isar->name, ch->bch.state,
+					isar->cmsb);
+		} else {
+			pr_debug("%s: ISAR spurious IIS_PSTEV %x/%x/%x\n",
+				isar->name, isar->iis, isar->cmsb,
+				isar->clsb);
+			isar->write_reg(isar->hw, ISAR_IIA, 0);
+		}
+		break;
+	case ISAR_IIS_PSTRSP:
+		ch = sel_bch_isar(isar, isar->iis >> 6);
+		if (ch) {
+			rcv_mbox(isar, NULL);
+			isar_pump_status_rsp(ch);
+		} else {
+			pr_debug("%s: ISAR spurious IIS_PSTRSP %x/%x/%x\n",
+				isar->name, isar->iis, isar->cmsb,
+				isar->clsb);
+			isar->write_reg(isar->hw, ISAR_IIA, 0);
+		}
+		break;
+	case ISAR_IIS_DIAG:
+	case ISAR_IIS_BSTRSP:
+	case ISAR_IIS_IOM2RSP:
+		rcv_mbox(isar, NULL);
+		break;
+	case ISAR_IIS_INVMSG:
+		rcv_mbox(isar, NULL);
+		pr_debug("%s: invalid msg his:%x\n", isar->name, isar->cmsb);
+		break;
+	default:
+		rcv_mbox(isar, NULL);
+		pr_debug("%s: unhandled msg iis(%x) ctrl(%x/%x)\n",
+			isar->name, isar->iis, isar->cmsb, isar->clsb);
+		break;
+	}
+}
+EXPORT_SYMBOL(mISDNisar_irq);
+
+static void
+ftimer_handler(unsigned long data)
+{
+	struct isar_ch *ch = (struct isar_ch *)data;
+
+	pr_debug("%s: ftimer flags %lx\n", ch->is->name, ch->bch.Flags);
+	test_and_clear_bit(FLG_FTI_RUN, &ch->bch.Flags);
+	if (test_and_clear_bit(FLG_LL_CONN, &ch->bch.Flags))
+		deliver_status(ch, HW_MOD_CONNECT);
+}
+
+static void
+setup_pump(struct isar_ch *ch) {
+	u8 dps = SET_DPS(ch->dpath);
+	u8 ctrl, param[6];
+
+	switch (ch->bch.state) {
+	case ISDN_P_NONE:
+	case ISDN_P_B_RAW:
+	case ISDN_P_B_HDLC:
+		send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL);
+		break;
+	case ISDN_P_B_L2DTMF:
+		if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) {
+			param[0] = 5; /* TOA 5 db */
+			send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
+				PMOD_DTMF_TRANS, 1, param);
+		} else {
+			param[0] = 40; /* REL -46 dbm */
+			send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
+				PMOD_DTMF, 1, param);
+		}
+	case ISDN_P_B_MODEM_ASYNC:
+		ctrl = PMOD_DATAMODEM;
+		if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
+			ctrl |= PCTRL_ORIG;
+			param[5] = PV32P6_CTN;
+		} else {
+			param[5] = PV32P6_ATN;
+		}
+		param[0] = 6; /* 6 db */
+		param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
+			PV32P2_V22C | PV32P2_V21 | PV32P2_BEL;
+		param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
+		param[3] = PV32P4_UT144;
+		param[4] = PV32P5_UT144;
+		send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param);
+		break;
+	case ISDN_P_B_T30_FAX:
+		ctrl = PMOD_FAX;
+		if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
+			ctrl |= PCTRL_ORIG;
+			param[1] = PFAXP2_CTN;
+		} else {
+			param[1] = PFAXP2_ATN;
+		}
+		param[0] = 6; /* 6 db */
+		send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
+		ch->state = STFAX_NULL;
+		ch->newcmd = 0;
+		ch->newmod = 0;
+		test_and_set_bit(FLG_FTI_RUN, &ch->bch.Flags);
+		break;
+	}
+	udelay(1000);
+	send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
+	udelay(1000);
+}
+
+static void
+setup_sart(struct isar_ch *ch) {
+	u8 dps = SET_DPS(ch->dpath);
+	u8 ctrl, param[2] = {0, 0};
+
+	switch (ch->bch.state) {
+	case ISDN_P_NONE:
+		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE,
+			0, NULL);
+		break;
+	case ISDN_P_B_RAW:
+	case ISDN_P_B_L2DTMF:
+		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_BINARY,
+			2, param);
+		break;
+	case ISDN_P_B_HDLC:
+	case ISDN_P_B_T30_FAX:
+		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_HDLC,
+			1, param);
+		break;
+	case ISDN_P_B_MODEM_ASYNC:
+		ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
+		param[0] = S_P1_CHS_8;
+		param[1] = S_P2_BFT_DEF;
+		send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, ctrl, 2, param);
+		break;
+	}
+	udelay(1000);
+	send_mbox(ch->is, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
+	udelay(1000);
+}
+
+static void
+setup_iom2(struct isar_ch *ch) {
+	u8 dps = SET_DPS(ch->dpath);
+	u8 cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0};
+
+	if (ch->bch.nr == 2) {
+		msg[1] = 1;
+		msg[3] = 1;
+	}
+	switch (ch->bch.state) {
+	case ISDN_P_NONE:
+		cmsb = 0;
+		/* dummy slot */
+		msg[1] = ch->dpath + 2;
+		msg[3] = ch->dpath + 2;
+		break;
+	case ISDN_P_B_RAW:
+	case ISDN_P_B_HDLC:
+		break;
+	case ISDN_P_B_MODEM_ASYNC:
+	case ISDN_P_B_T30_FAX:
+		cmsb |= IOM_CTRL_RCV;
+	case ISDN_P_B_L2DTMF:
+		if (test_bit(FLG_DTMFSEND, &ch->bch.Flags))
+			cmsb |= IOM_CTRL_RCV;
+		cmsb |= IOM_CTRL_ALAW;
+		break;
+	}
+	send_mbox(ch->is, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg);
+	udelay(1000);
+	send_mbox(ch->is, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL);
+	udelay(1000);
+}
+
+static int
+modeisar(struct isar_ch *ch, u32 bprotocol)
+{
+	/* Here we are selecting the best datapath for requested protocol */
+	if (ch->bch.state == ISDN_P_NONE) { /* New Setup */
+		switch (bprotocol) {
+		case ISDN_P_NONE: /* init */
+			if (!ch->dpath)
+				/* no init for dpath 0 */
+				return 0;
+			test_and_clear_bit(FLG_HDLC, &ch->bch.Flags);
+			test_and_clear_bit(FLG_TRANSPARENT, &ch->bch.Flags);
+			break;
+		case ISDN_P_B_RAW:
+		case ISDN_P_B_HDLC:
+			/* best is datapath 2 */
+			if (!test_and_set_bit(ISAR_DP2_USE, &ch->is->Flags))
+				ch->dpath = 2;
+			else if (!test_and_set_bit(ISAR_DP1_USE,
+			    &ch->is->Flags))
+				ch->dpath = 1;
+			else {
+				pr_info("modeisar both pathes in use\n");
+				return -EBUSY;
+			}
+			if (bprotocol == ISDN_P_B_HDLC)
+				test_and_set_bit(FLG_HDLC, &ch->bch.Flags);
+			else
+				test_and_set_bit(FLG_TRANSPARENT,
+					&ch->bch.Flags);
+			break;
+		case ISDN_P_B_MODEM_ASYNC:
+		case ISDN_P_B_T30_FAX:
+		case ISDN_P_B_L2DTMF:
+			/* only datapath 1 */
+			if (!test_and_set_bit(ISAR_DP1_USE, &ch->is->Flags))
+				ch->dpath = 1;
+			else {
+				pr_info("%s: ISAR modeisar analog functions"
+					"only with DP1\n", ch->is->name);
+				return -EBUSY;
+			}
+			break;
+		default:
+			pr_info("%s: protocol not known %x\n", ch->is->name,
+				bprotocol);
+			return -ENOPROTOOPT;
+		}
+	}
+	pr_debug("%s: ISAR ch%d dp%d protocol %x->%x\n", ch->is->name,
+		ch->bch.nr, ch->dpath, ch->bch.state, bprotocol);
+	ch->bch.state = bprotocol;
+	setup_pump(ch);
+	setup_iom2(ch);
+	setup_sart(ch);
+	if (ch->bch.state == ISDN_P_NONE) {
+		/* Clear resources */
+		if (ch->dpath == 1)
+			test_and_clear_bit(ISAR_DP1_USE, &ch->is->Flags);
+		else if (ch->dpath == 2)
+			test_and_clear_bit(ISAR_DP2_USE, &ch->is->Flags);
+		ch->dpath = 0;
+		ch->is->ctrl(ch->is->hw, HW_DEACT_IND, ch->bch.nr);
+	} else
+		ch->is->ctrl(ch->is->hw, HW_ACTIVATE_IND, ch->bch.nr);
+	return 0;
+}
+
+static void
+isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
+{
+	u8 dps = SET_DPS(ch->dpath);
+	u8 ctrl = 0, nom = 0, p1 = 0;
+
+	pr_debug("%s: isar_pump_cmd %x/%x state(%x)\n",
+		ch->is->name, cmd, para, ch->bch.state);
+	switch (cmd) {
+	case HW_MOD_FTM:
+		if (ch->state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FTM;
+			nom = 1;
+			ch->state = STFAX_LINE;
+			ch->cmd = ctrl;
+			ch->mod = para;
+			ch->newmod = 0;
+			ch->newcmd = 0;
+			ch->try_mod = 3;
+		} else if ((ch->state == STFAX_ACTIV) &&
+		    (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para))
+			deliver_status(ch, HW_MOD_CONNECT);
+		else {
+			ch->newmod = para;
+			ch->newcmd = PCTRL_CMD_FTM;
+			nom = 0;
+			ctrl = PCTRL_CMD_ESC;
+			ch->state = STFAX_ESCAPE;
+		}
+		break;
+	case HW_MOD_FTH:
+		if (ch->state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FTH;
+			nom = 1;
+			ch->state = STFAX_LINE;
+			ch->cmd = ctrl;
+			ch->mod = para;
+			ch->newmod = 0;
+			ch->newcmd = 0;
+			ch->try_mod = 3;
+		} else if ((ch->state == STFAX_ACTIV) &&
+		    (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para))
+				deliver_status(ch, HW_MOD_CONNECT);
+		else {
+			ch->newmod = para;
+			ch->newcmd = PCTRL_CMD_FTH;
+			nom = 0;
+			ctrl = PCTRL_CMD_ESC;
+			ch->state = STFAX_ESCAPE;
+		}
+		break;
+	case HW_MOD_FRM:
+		if (ch->state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FRM;
+			nom = 1;
+			ch->state = STFAX_LINE;
+			ch->cmd = ctrl;
+			ch->mod = para;
+			ch->newmod = 0;
+			ch->newcmd = 0;
+			ch->try_mod = 3;
+		} else if ((ch->state == STFAX_ACTIV) &&
+		    (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para))
+			deliver_status(ch, HW_MOD_CONNECT);
+		else {
+			ch->newmod = para;
+			ch->newcmd = PCTRL_CMD_FRM;
+			nom = 0;
+			ctrl = PCTRL_CMD_ESC;
+			ch->state = STFAX_ESCAPE;
+		}
+		break;
+	case HW_MOD_FRH:
+		if (ch->state == STFAX_READY) {
+			p1 = para;
+			ctrl = PCTRL_CMD_FRH;
+			nom = 1;
+			ch->state = STFAX_LINE;
+			ch->cmd = ctrl;
+			ch->mod = para;
+			ch->newmod = 0;
+			ch->newcmd = 0;
+			ch->try_mod = 3;
+		} else if ((ch->state == STFAX_ACTIV) &&
+		    (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para))
+			deliver_status(ch, HW_MOD_CONNECT);
+		else {
+			ch->newmod = para;
+			ch->newcmd = PCTRL_CMD_FRH;
+			nom = 0;
+			ctrl = PCTRL_CMD_ESC;
+			ch->state = STFAX_ESCAPE;
+		}
+		break;
+	case PCTRL_CMD_TDTMF:
+		p1 = para;
+		nom = 1;
+		ctrl = PCTRL_CMD_TDTMF;
+		break;
+	}
+	if (ctrl)
+		send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
+}
+
+static void
+isar_setup(struct isar_hw *isar)
+{
+	u8 msg;
+	int i;
+
+	/* Dpath 1, 2 */
+	msg = 61;
+	for (i = 0; i < 2; i++) {
+		/* Buffer Config */
+		send_mbox(isar, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
+			ISAR_HIS_P12CFG, 4, 1, &msg);
+		isar->ch[i].mml = msg;
+		isar->ch[i].bch.state = 0;
+		isar->ch[i].dpath = i + 1;
+		modeisar(&isar->ch[i], ISDN_P_NONE);
+	}
+}
+
+static int
+isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
+	int ret = -EINVAL;
+	struct mISDNhead *hh = mISDN_HEAD_P(skb);
+	u32 id, *val;
+	u_long flags;
+
+	switch (hh->prim) {
+	case PH_DATA_REQ:
+		spin_lock_irqsave(ich->is->hwlock, flags);
+		ret = bchannel_senddata(bch, skb);
+		if (ret > 0) { /* direct TX */
+			id = hh->id; /* skb can be freed */
+			ret = 0;
+			isar_fill_fifo(ich);
+			spin_unlock_irqrestore(ich->is->hwlock, flags);
+			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
+				queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
+		} else
+			spin_unlock_irqrestore(ich->is->hwlock, flags);
+		return ret;
+	case PH_ACTIVATE_REQ:
+		spin_lock_irqsave(ich->is->hwlock, flags);
+		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
+			ret = modeisar(ich, ch->protocol);
+		else
+			ret = 0;
+		spin_unlock_irqrestore(ich->is->hwlock, flags);
+		if (!ret)
+			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
+				NULL, GFP_KERNEL);
+		break;
+	case PH_DEACTIVATE_REQ:
+		spin_lock_irqsave(ich->is->hwlock, flags);
+		mISDN_clear_bchannel(bch);
+		modeisar(ich, ISDN_P_NONE);
+		spin_unlock_irqrestore(ich->is->hwlock, flags);
+		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
+			NULL, GFP_KERNEL);
+		ret = 0;
+		break;
+	case PH_CONTROL_REQ:
+		val = (u32 *)skb->data;
+		pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name,
+			hh->id, *val);
+		if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) ==
+		    DTMF_TONE_VAL)) {
+			if (bch->state == ISDN_P_B_L2DTMF) {
+				char tt = *val & DTMF_TONE_MASK;
+
+				if (tt == '*')
+					tt = 0x1e;
+				else if (tt == '#')
+					tt = 0x1f;
+				else if (tt > '9')
+					tt -= 7;
+				tt &= 0x1f;
+				spin_lock_irqsave(ich->is->hwlock, flags);
+				isar_pump_cmd(ich, PCTRL_CMD_TDTMF, tt);
+				spin_unlock_irqrestore(ich->is->hwlock, flags);
+			} else {
+				pr_info("%s: DTMF send wrong protocol %x\n",
+					__func__, bch->state);
+				return -EINVAL;
+			}
+		} else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) ||
+		    (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
+			for (id = 0; id < FAXMODCNT; id++)
+				if (faxmodulation[id] == *val)
+					break;
+			if ((FAXMODCNT > id) &&
+			    test_bit(FLG_INITIALIZED, &bch->Flags)) {
+				pr_debug("%s: isar: new mod\n", ich->is->name);
+				isar_pump_cmd(ich, hh->id, *val);
+				ret = 0;
+			} else {
+				pr_info("%s: wrong modulation\n",
+					ich->is->name);
+				ret = -EINVAL;
+			}
+		} else if (hh->id == HW_MOD_LASTDATA)
+			test_and_set_bit(FLG_DLEETX, &bch->Flags);
+		else {
+			pr_info("%s: unknown PH_CONTROL_REQ %x\n",
+				ich->is->name, hh->id);
+			ret = -EINVAL;
+		}
+	default:
+		pr_info("%s: %s unknown prim(%x,%x)\n",
+			ich->is->name, __func__, hh->prim, hh->id);
+		ret = -EINVAL;
+	}
+	if (!ret)
+		dev_kfree_skb(skb);
+	return ret;
+}
+
+static int
+channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = 0;
+		break;
+	/* Nothing implemented yet */
+	case MISDN_CTRL_FILL_EMPTY:
+	default:
+		pr_info("%s: unknown Op %x\n", __func__, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
+	int ret = -EINVAL;
+	u_long flags;
+
+	pr_debug("%s: %s cmd:%x %p\n", ich->is->name, __func__, cmd, arg);
+	switch (cmd) {
+	case CLOSE_CHANNEL:
+		test_and_clear_bit(FLG_OPEN, &bch->Flags);
+		if (test_bit(FLG_ACTIVE, &bch->Flags)) {
+			spin_lock_irqsave(ich->is->hwlock, flags);
+			mISDN_freebchannel(bch);
+			modeisar(ich, ISDN_P_NONE);
+			spin_unlock_irqrestore(ich->is->hwlock, flags);
+		} else {
+			skb_queue_purge(&bch->rqueue);
+			bch->rcount = 0;
+		}
+		ch->protocol = ISDN_P_NONE;
+		ch->peer = NULL;
+		module_put(ich->is->owner);
+		ret = 0;
+		break;
+	case CONTROL_CHANNEL:
+		ret = channel_bctrl(bch, arg);
+		break;
+	default:
+		pr_info("%s: %s unknown prim(%x)\n",
+			ich->is->name, __func__, cmd);
+	}
+	return ret;
+}
+
+static void
+free_isar(struct isar_hw *isar)
+{
+	modeisar(&isar->ch[0], ISDN_P_NONE);
+	modeisar(&isar->ch[1], ISDN_P_NONE);
+	del_timer(&isar->ch[0].ftimer);
+	del_timer(&isar->ch[1].ftimer);
+	test_and_clear_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
+	test_and_clear_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
+}
+
+static int
+init_isar(struct isar_hw *isar)
+{
+	int	cnt = 3;
+
+	while (cnt--) {
+		isar->version = ISARVersion(isar);
+		if (isar->ch[0].bch.debug & DEBUG_HW)
+			pr_notice("%s: Testing version %d (%d time)\n",
+				isar->name, isar->version, 3 - cnt);
+		if (isar->version == 1)
+			break;
+		isar->ctrl(isar->hw, HW_RESET_REQ, 0);
+	}
+	if (isar->version != 1)
+		return -EINVAL;
+	isar->ch[0].ftimer.function = &ftimer_handler;
+	isar->ch[0].ftimer.data = (long)&isar->ch[0];
+	init_timer(&isar->ch[0].ftimer);
+	test_and_set_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
+	isar->ch[1].ftimer.function = &ftimer_handler;
+	isar->ch[1].ftimer.data = (long)&isar->ch[1];
+	init_timer(&isar->ch[1].ftimer);
+	test_and_set_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
+	return 0;
+}
+
+static int
+isar_open(struct isar_hw *isar, struct channel_req *rq)
+{
+	struct bchannel		*bch;
+
+	if (rq->adr.channel > 2)
+		return -EINVAL;
+	if (rq->protocol == ISDN_P_NONE)
+		return -EINVAL;
+	bch = &isar->ch[rq->adr.channel - 1].bch;
+	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
+		return -EBUSY; /* b-channel can be only open once */
+	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
+	bch->ch.protocol = rq->protocol;
+	rq->ch = &bch->ch;
+	return 0;
+}
+
+u32
+mISDNisar_init(struct isar_hw *isar, void *hw)
+{
+	u32 ret, i;
+
+	isar->hw = hw;
+	for (i = 0; i < 2; i++) {
+		isar->ch[i].bch.nr = i + 1;
+		mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM);
+		isar->ch[i].bch.ch.nr = i + 1;
+		isar->ch[i].bch.ch.send = &isar_l2l1;
+		isar->ch[i].bch.ch.ctrl = isar_bctrl;
+		isar->ch[i].bch.hw = hw;
+		isar->ch[i].is = isar;
+	}
+
+	isar->init = &init_isar;
+	isar->release = &free_isar;
+	isar->firmware = &load_firmware;
+	isar->open = &isar_open;
+
+	ret =	(1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)) |
+		(1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK)) |
+		(1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK)) |
+		(1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK));
+
+	return ret;
+}
+EXPORT_SYMBOL(mISDNisar_init);
+
+static int isar_mod_init(void)
+{
+	pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
+	return 0;
+}
+
+static void isar_mod_cleanup(void)
+{
+	pr_notice("mISDN: ISAR module unloaded\n");
+}
+module_init(isar_mod_init);
+module_exit(isar_mod_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
new file mode 100644
index 0000000..6c1b164
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -0,0 +1,1156 @@
+/*
+ * NETJet mISDN driver
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mISDNhw.h>
+#include "ipac.h"
+#include "iohelper.h"
+#include "netjet.h"
+#include <linux/isdn/hdlc.h>
+
+#define NETJET_REV	"2.0"
+
+enum nj_types {
+	NETJET_S_TJ300,
+	NETJET_S_TJ320,
+	ENTERNOW__TJ320,
+};
+
+struct tiger_dma {
+	size_t		size;
+	u32		*start;
+	int		idx;
+	u32		dmastart;
+	u32		dmairq;
+	u32		dmaend;
+	u32		dmacur;
+};
+
+struct tiger_hw;
+
+struct tiger_ch {
+	struct bchannel		bch;
+	struct tiger_hw		*nj;
+	int			idx;
+	int			free;
+	int			lastrx;
+	u16			rxstate;
+	u16			txstate;
+	struct isdnhdlc_vars	hsend;
+	struct isdnhdlc_vars	hrecv;
+	u8			*hsbuf;
+	u8			*hrbuf;
+};
+
+#define TX_INIT		0x0001
+#define TX_IDLE		0x0002
+#define TX_RUN		0x0004
+#define TX_UNDERRUN	0x0100
+#define RX_OVERRUN	0x0100
+
+#define LOG_SIZE	64
+
+struct tiger_hw {
+	struct list_head	list;
+	struct pci_dev		*pdev;
+	char			name[MISDN_MAX_IDLEN];
+	enum nj_types		typ;
+	int			irq;
+	u32			irqcnt;
+	u32			base;
+	size_t			base_s;
+	dma_addr_t		dma;
+	void			*dma_p;
+	spinlock_t		lock;	/* lock HW */
+	struct isac_hw		isac;
+	struct tiger_dma	send;
+	struct tiger_dma	recv;
+	struct tiger_ch		bc[2];
+	u8			ctrlreg;
+	u8			dmactrl;
+	u8			auxd;
+	u8			last_is0;
+	u8			irqmask0;
+	char			log[LOG_SIZE];
+};
+
+static LIST_HEAD(Cards);
+static DEFINE_RWLOCK(card_lock); /* protect Cards */
+static u32 debug;
+static int nj_cnt;
+
+static void
+_set_debug(struct tiger_hw *card)
+{
+	card->isac.dch.debug = debug;
+	card->bc[0].bch.debug = debug;
+	card->bc[1].bch.debug = debug;
+}
+
+static int
+set_debug(const char *val, struct kernel_param *kp)
+{
+	int ret;
+	struct tiger_hw *card;
+
+	ret = param_set_uint(val, kp);
+	if (!ret) {
+		read_lock(&card_lock);
+		list_for_each_entry(card, &Cards, list)
+			_set_debug(card);
+		read_unlock(&card_lock);
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("Karsten Keil");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(NETJET_REV);
+module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Netjet debug mask");
+
+static void
+nj_disable_hwirq(struct tiger_hw *card)
+{
+	outb(0, card->base + NJ_IRQMASK0);
+	outb(0, card->base + NJ_IRQMASK1);
+}
+
+
+static u8
+ReadISAC_nj(void *p, u8 offset)
+{
+	struct tiger_hw *card = p;
+	u8 ret;
+
+	card->auxd &= 0xfc;
+	card->auxd |= (offset >> 4) & 3;
+	outb(card->auxd, card->base + NJ_AUXDATA);
+	ret = inb(card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
+	return ret;
+}
+
+static void
+WriteISAC_nj(void *p, u8 offset, u8 value)
+{
+	struct tiger_hw *card = p;
+
+	card->auxd &= 0xfc;
+	card->auxd |= (offset >> 4) & 3;
+	outb(card->auxd, card->base + NJ_AUXDATA);
+	outb(value, card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
+}
+
+static void
+ReadFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
+{
+	struct tiger_hw *card = p;
+
+	card->auxd &= 0xfc;
+	outb(card->auxd, card->base + NJ_AUXDATA);
+	insb(card->base + NJ_ISAC_OFF, data, size);
+}
+
+static void
+WriteFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
+{
+	struct tiger_hw *card = p;
+
+	card->auxd &= 0xfc;
+	outb(card->auxd, card->base + NJ_AUXDATA);
+	outsb(card->base + NJ_ISAC_OFF, data, size);
+}
+
+static void
+fill_mem(struct tiger_ch *bc, u32 idx, u32 cnt, u32 fill)
+{
+	struct tiger_hw *card = bc->bch.hw;
+	u32 mask = 0xff, val;
+
+	pr_debug("%s: B%1d fill %02x len %d idx %d/%d\n", card->name,
+		bc->bch.nr, fill, cnt, idx, card->send.idx);
+	if (bc->bch.nr & 2) {
+		fill  <<= 8;
+		mask <<= 8;
+	}
+	mask ^= 0xffffffff;
+	while (cnt--) {
+		val = card->send.start[idx];
+		val &= mask;
+		val |= fill;
+		card->send.start[idx++] = val;
+		if (idx >= card->send.size)
+			idx = 0;
+	}
+}
+
+static int
+mode_tiger(struct tiger_ch *bc, u32 protocol)
+{
+	struct tiger_hw *card = bc->bch.hw;
+
+	pr_debug("%s: B%1d protocol %x-->%x\n", card->name,
+		bc->bch.nr, bc->bch.state, protocol);
+	switch (protocol) {
+	case ISDN_P_NONE:
+		if (bc->bch.state == ISDN_P_NONE)
+			break;
+		fill_mem(bc, 0, card->send.size, 0xff);
+		bc->bch.state = protocol;
+		/* only stop dma and interrupts if both channels NULL */
+		if ((card->bc[0].bch.state == ISDN_P_NONE) &&
+		    (card->bc[1].bch.state == ISDN_P_NONE)) {
+			card->dmactrl = 0;
+			outb(card->dmactrl, card->base + NJ_DMACTRL);
+			outb(0, card->base + NJ_IRQMASK0);
+		}
+		test_and_clear_bit(FLG_HDLC, &bc->bch.Flags);
+		test_and_clear_bit(FLG_TRANSPARENT, &bc->bch.Flags);
+		bc->txstate = 0;
+		bc->rxstate = 0;
+		bc->lastrx = -1;
+		break;
+	case ISDN_P_B_RAW:
+		test_and_set_bit(FLG_TRANSPARENT, &bc->bch.Flags);
+		bc->bch.state = protocol;
+		bc->idx = 0;
+		bc->free = card->send.size/2;
+		bc->rxstate = 0;
+		bc->txstate = TX_INIT | TX_IDLE;
+		bc->lastrx = -1;
+		if (!card->dmactrl) {
+			card->dmactrl = 1;
+			outb(card->dmactrl, card->base + NJ_DMACTRL);
+			outb(0x0f, card->base + NJ_IRQMASK0);
+		}
+		break;
+	case ISDN_P_B_HDLC:
+		test_and_set_bit(FLG_HDLC, &bc->bch.Flags);
+		bc->bch.state = protocol;
+		bc->idx = 0;
+		bc->free = card->send.size/2;
+		bc->rxstate = 0;
+		bc->txstate = TX_INIT | TX_IDLE;
+		isdnhdlc_rcv_init(&bc->hrecv, 0);
+		isdnhdlc_out_init(&bc->hsend, 0);
+		bc->lastrx = -1;
+		if (!card->dmactrl) {
+			card->dmactrl = 1;
+			outb(card->dmactrl, card->base + NJ_DMACTRL);
+			outb(0x0f, card->base + NJ_IRQMASK0);
+		}
+		break;
+	default:
+		pr_info("%s: %s protocol %x not handled\n", card->name,
+			__func__, protocol);
+		return -ENOPROTOOPT;
+	}
+	card->send.dmacur = inl(card->base + NJ_DMA_READ_ADR);
+	card->recv.dmacur = inl(card->base + NJ_DMA_WRITE_ADR);
+	card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
+	card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
+	pr_debug("%s: %s ctrl %x irq  %02x/%02x idx %d/%d\n",
+		card->name, __func__,
+		inb(card->base + NJ_DMACTRL),
+		inb(card->base + NJ_IRQMASK0),
+		inb(card->base + NJ_IRQSTAT0),
+		card->send.idx,
+		card->recv.idx);
+	return 0;
+}
+
+static void
+nj_reset(struct tiger_hw *card)
+{
+	outb(0xff, card->base + NJ_CTRL); /* Reset On */
+	mdelay(1);
+
+	/* now edge triggered for TJ320 GE 13/07/00 */
+	/* see comment in IRQ function */
+	if (card->typ == NETJET_S_TJ320) /* TJ320 */
+		card->ctrlreg = 0x40;  /* Reset Off and status read clear */
+	else
+		card->ctrlreg = 0x00;  /* Reset Off and status read clear */
+	outb(card->ctrlreg, card->base + NJ_CTRL);
+	mdelay(10);
+
+	/* configure AUX pins (all output except ISAC IRQ pin) */
+	card->auxd = 0;
+	card->dmactrl = 0;
+	outb(~NJ_ISACIRQ, card->base + NJ_AUXCTRL);
+	outb(NJ_ISACIRQ,  card->base + NJ_IRQMASK1);
+	outb(card->auxd, card->base + NJ_AUXDATA);
+}
+
+static int
+inittiger(struct tiger_hw *card)
+{
+	int i;
+
+	card->dma_p = pci_alloc_consistent(card->pdev, NJ_DMA_SIZE,
+			&card->dma);
+	if (!card->dma_p) {
+		pr_info("%s: No DMA memory\n", card->name);
+		return -ENOMEM;
+	}
+	if ((u64)card->dma > 0xffffffff) {
+		pr_info("%s: DMA outside 32 bit\n", card->name);
+		return -ENOMEM;
+	}
+	for (i = 0; i < 2; i++) {
+		card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_KERNEL);
+		if (!card->bc[i].hsbuf) {
+			pr_info("%s: no B%d send buffer\n", card->name, i + 1);
+			return -ENOMEM;
+		}
+		card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_KERNEL);
+		if (!card->bc[i].hrbuf) {
+			pr_info("%s: no B%d recv buffer\n", card->name, i + 1);
+			return -ENOMEM;
+		}
+	}
+	memset(card->dma_p, 0xff, NJ_DMA_SIZE);
+
+	card->send.start = card->dma_p;
+	card->send.dmastart = (u32)card->dma;
+	card->send.dmaend = card->send.dmastart +
+		(4 * (NJ_DMA_TXSIZE - 1));
+	card->send.dmairq = card->send.dmastart +
+		(4 * ((NJ_DMA_TXSIZE / 2) - 1));
+	card->send.size = NJ_DMA_TXSIZE;
+
+	if (debug & DEBUG_HW)
+		pr_notice("%s: send buffer phy %#x - %#x - %#x  virt %p"
+			" size %zu u32\n", card->name,
+			card->send.dmastart, card->send.dmairq,
+			card->send.dmaend, card->send.start, card->send.size);
+
+	outl(card->send.dmastart, card->base + NJ_DMA_READ_START);
+	outl(card->send.dmairq, card->base + NJ_DMA_READ_IRQ);
+	outl(card->send.dmaend, card->base + NJ_DMA_READ_END);
+
+	card->recv.start = card->dma_p + (NJ_DMA_SIZE / 2);
+	card->recv.dmastart = (u32)card->dma  + (NJ_DMA_SIZE / 2);
+	card->recv.dmaend = card->recv.dmastart +
+		(4 * (NJ_DMA_RXSIZE - 1));
+	card->recv.dmairq = card->recv.dmastart +
+		(4 * ((NJ_DMA_RXSIZE / 2) - 1));
+	card->recv.size = NJ_DMA_RXSIZE;
+
+	if (debug & DEBUG_HW)
+		pr_notice("%s: recv buffer phy %#x - %#x - %#x  virt %p"
+			" size %zu u32\n", card->name,
+			card->recv.dmastart, card->recv.dmairq,
+			card->recv.dmaend, card->recv.start, card->recv.size);
+
+	outl(card->recv.dmastart, card->base + NJ_DMA_WRITE_START);
+	outl(card->recv.dmairq, card->base + NJ_DMA_WRITE_IRQ);
+	outl(card->recv.dmaend, card->base + NJ_DMA_WRITE_END);
+	return 0;
+}
+
+static void
+read_dma(struct tiger_ch *bc, u32 idx, int cnt)
+{
+	struct tiger_hw *card = bc->bch.hw;
+	int i, stat;
+	u32 val;
+	u8 *p, *pn;
+
+	if (bc->lastrx == idx) {
+		bc->rxstate |= RX_OVERRUN;
+		pr_info("%s: B%1d overrun at idx %d\n", card->name,
+			bc->bch.nr, idx);
+	}
+	bc->lastrx = idx;
+	if (!bc->bch.rx_skb) {
+		bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen, GFP_ATOMIC);
+		if (!bc->bch.rx_skb) {
+			pr_info("%s: B%1d receive out of memory\n",
+				card->name, bc->bch.nr);
+			return;
+		}
+	}
+
+	if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) {
+		if ((bc->bch.rx_skb->len + cnt) > bc->bch.maxlen) {
+			pr_debug("%s: B%1d overrun %d\n", card->name,
+				bc->bch.nr, bc->bch.rx_skb->len + cnt);
+			skb_trim(bc->bch.rx_skb, 0);
+			return;
+		}
+		p = skb_put(bc->bch.rx_skb, cnt);
+	} else
+		p = bc->hrbuf;
+
+	for (i = 0; i < cnt; i++) {
+		val = card->recv.start[idx++];
+		if (bc->bch.nr & 2)
+			val >>= 8;
+		if (idx >= card->recv.size)
+			idx = 0;
+		p[i] = val & 0xff;
+	}
+	pn = bc->hrbuf;
+next_frame:
+	if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
+		stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i,
+			bc->bch.rx_skb->data, bc->bch.maxlen);
+		if (stat > 0) /* valid frame received */ 
+			p = skb_put(bc->bch.rx_skb, stat);
+		else if (stat == -HDLC_CRC_ERROR)
+			pr_info("%s: B%1d receive frame CRC error\n",
+				card->name, bc->bch.nr);
+		else if (stat == -HDLC_FRAMING_ERROR)
+			pr_info("%s: B%1d receive framing error\n",
+				card->name, bc->bch.nr);
+		else if (stat == -HDLC_LENGTH_ERROR)
+			pr_info("%s: B%1d receive frame too long (> %d)\n",
+				card->name, bc->bch.nr, bc->bch.maxlen);
+	} else
+		stat = cnt;	
+
+	if (stat > 0) {
+		if (debug & DEBUG_HW_BFIFO) {
+			snprintf(card->log, LOG_SIZE, "B%1d-recv %s %d ",
+				bc->bch.nr, card->name, stat);
+			print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET,
+				p, stat);
+		}
+		recv_Bchannel(&bc->bch, 0);
+	}
+	if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
+		pn += i;
+		cnt -= i;
+		if (!bc->bch.rx_skb) {
+			bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen,
+				GFP_ATOMIC);
+			if (!bc->bch.rx_skb) {
+				pr_info("%s: B%1d receive out of memory\n",
+					card->name, bc->bch.nr);
+				return;
+			}
+		}
+		if (cnt > 0)
+			goto next_frame;
+	}
+}
+
+static void
+recv_tiger(struct tiger_hw *card, u8 irq_stat)
+{
+	u32 idx;
+	int cnt = card->recv.size / 2;
+
+	/* Note receive is via the WRITE DMA channel */
+	card->last_is0 &= ~NJ_IRQM0_WR_MASK;
+	card->last_is0 |= (irq_stat & NJ_IRQM0_WR_MASK);
+
+	if (irq_stat & NJ_IRQM0_WR_END)
+		idx = cnt - 1;
+	else
+		idx = card->recv.size - 1;
+
+	if (test_bit(FLG_ACTIVE, &card->bc[0].bch.Flags))
+		read_dma(&card->bc[0], idx, cnt);
+	if (test_bit(FLG_ACTIVE, &card->bc[1].bch.Flags))
+		read_dma(&card->bc[1], idx, cnt);
+}
+
+/* sync with current DMA address at start or after exception */
+static void
+resync(struct tiger_ch *bc, struct tiger_hw *card)
+{
+	card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
+	card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
+	if (bc->free > card->send.size / 2)
+		bc->free = card->send.size / 2;
+	/* currently we simple sync to the next complete free area
+	 * this hast the advantage that we have always maximum time to
+	 * handle TX irq
+	 */
+	if (card->send.idx < ((card->send.size / 2) - 1))
+		bc->idx = (card->recv.size / 2) - 1;
+	else
+		bc->idx = card->recv.size - 1;
+	bc->txstate = TX_RUN;
+	pr_debug("%s: %s B%1d free %d idx %d/%d\n", card->name,
+		__func__, bc->bch.nr, bc->free, bc->idx, card->send.idx);
+}
+
+static int bc_next_frame(struct tiger_ch *);
+
+static void
+fill_hdlc_flag(struct tiger_ch *bc)
+{
+	struct tiger_hw *card = bc->bch.hw;
+	int count, i;
+	u32 m, v;
+	u8  *p;
+
+	if (bc->free == 0)
+		return;
+	pr_debug("%s: %s B%1d %d state %x idx %d/%d\n", card->name,
+		__func__, bc->bch.nr, bc->free, bc->txstate,
+		bc->idx, card->send.idx);
+	if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
+		resync(bc, card);
+	count = isdnhdlc_encode(&bc->hsend, NULL, 0, &i,
+			bc->hsbuf, bc->free);
+	pr_debug("%s: B%1d hdlc encoded %d flags\n", card->name,
+			bc->bch.nr, count);
+	bc->free -= count;
+	p = bc->hsbuf;
+	m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
+	for (i = 0; i < count; i++) {
+		if (bc->idx >= card->send.size)
+			bc->idx = 0;
+		v = card->send.start[bc->idx];
+		v &= m;
+		v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8;
+		card->send.start[bc->idx++] = v;
+	}
+	if (debug & DEBUG_HW_BFIFO) {
+		snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
+			bc->bch.nr, card->name, count);
+		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
+	}
+}
+
+static void
+fill_dma(struct tiger_ch *bc)
+{
+	struct tiger_hw *card = bc->bch.hw;
+	int count, i;
+	u32 m, v;
+	u8  *p;
+
+	if (bc->free == 0)
+		return;
+	count = bc->bch.tx_skb->len - bc->bch.tx_idx;
+	if (count <= 0)
+		return;
+	pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", card->name,
+		__func__, bc->bch.nr, count, bc->free, bc->bch.tx_idx,
+		bc->bch.tx_skb->len, bc->txstate, bc->idx, card->send.idx);
+	if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
+		resync(bc, card);
+	p = bc->bch.tx_skb->data + bc->bch.tx_idx;
+	if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
+		count = isdnhdlc_encode(&bc->hsend, p, count, &i,
+			bc->hsbuf, bc->free);
+		pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name,
+			bc->bch.nr, i, count);
+		bc->bch.tx_idx += i;
+		bc->free -= count;
+		p = bc->hsbuf;
+	} else {
+		if (count > bc->free)
+			count = bc->free;
+		bc->bch.tx_idx += count;
+		bc->free -= count;
+	}
+	m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
+	for (i = 0; i < count; i++) {
+		if (bc->idx >= card->send.size)
+			bc->idx = 0;
+		v = card->send.start[bc->idx];
+		v &= m;
+		v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8;
+		card->send.start[bc->idx++] = v;
+	}
+	if (debug & DEBUG_HW_BFIFO) {
+		snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
+			bc->bch.nr, card->name, count);
+		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
+	}
+	if (bc->free)
+		bc_next_frame(bc);
+}
+
+
+static int
+bc_next_frame(struct tiger_ch *bc)
+{
+	if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len)
+		fill_dma(bc);
+	else {
+		if (bc->bch.tx_skb) {
+			/* send confirm, on trans, free on hdlc. */
+			if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags))
+				confirm_Bsend(&bc->bch);
+			dev_kfree_skb(bc->bch.tx_skb);
+		}
+		if (get_next_bframe(&bc->bch))
+			fill_dma(bc);
+		else
+			return 0;
+	}
+	return 1;
+}
+
+static void
+send_tiger_bc(struct tiger_hw *card, struct tiger_ch *bc)
+{
+	int ret;
+
+	bc->free += card->send.size / 2;
+	if (bc->free >= card->send.size) {
+		if (!(bc->txstate & (TX_UNDERRUN | TX_INIT))) {
+			pr_info("%s: B%1d TX underrun state %x\n", card->name,
+				bc->bch.nr, bc->txstate);
+			bc->txstate |= TX_UNDERRUN;
+		}
+		bc->free = card->send.size;
+	}
+	ret = bc_next_frame(bc);
+	if (!ret) {
+		if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
+			fill_hdlc_flag(bc);
+			return;
+		}
+		pr_debug("%s: B%1d TX no data free %d idx %d/%d\n", card->name,
+			bc->bch.nr, bc->free, bc->idx, card->send.idx);
+		if (!(bc->txstate & (TX_IDLE | TX_INIT))) {
+			fill_mem(bc, bc->idx, bc->free, 0xff);
+			if (bc->free == card->send.size)
+				bc->txstate |= TX_IDLE;
+		}
+	}
+}
+
+static void
+send_tiger(struct tiger_hw *card, u8 irq_stat)
+{
+	int i;
+
+	/* Note send is via the READ DMA channel */
+	if ((irq_stat & card->last_is0) & NJ_IRQM0_RD_MASK) {
+		pr_info("%s: tiger warn write double dma %x/%x\n",
+			card->name, irq_stat, card->last_is0);
+		return;
+	} else {
+		card->last_is0 &= ~NJ_IRQM0_RD_MASK;
+		card->last_is0 |= (irq_stat & NJ_IRQM0_RD_MASK);
+	}
+	for (i = 0; i < 2; i++) {
+		if (test_bit(FLG_ACTIVE, &card->bc[i].bch.Flags))
+			send_tiger_bc(card, &card->bc[i]);
+	}
+}
+
+static irqreturn_t
+nj_irq(int intno, void *dev_id)
+{
+	struct tiger_hw *card = dev_id;
+	u8 val, s1val, s0val;
+
+	spin_lock(&card->lock);
+	s0val = inb(card->base | NJ_IRQSTAT0);
+	s1val = inb(card->base | NJ_IRQSTAT1);
+	if ((s1val & NJ_ISACIRQ) && (s0val == 0)) {
+		/* shared IRQ */
+		spin_unlock(&card->lock);
+		return IRQ_NONE;
+	}
+	pr_debug("%s: IRQSTAT0 %02x IRQSTAT1 %02x\n", card->name, s0val, s1val);
+	card->irqcnt++;
+	if (!(s1val & NJ_ISACIRQ)) {
+		val = ReadISAC_nj(card, ISAC_ISTA);
+		if (val)
+			mISDNisac_irq(&card->isac, val);
+	}
+
+	if (s0val)
+		/* write to clear */
+		outb(s0val, card->base | NJ_IRQSTAT0);
+	else
+		goto end;
+	s1val = s0val;
+	/* set bits in sval to indicate which page is free */
+	card->recv.dmacur = inl(card->base | NJ_DMA_WRITE_ADR);
+	card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
+	if (card->recv.dmacur < card->recv.dmairq)
+		s0val = 0x08;	/* the 2nd write area is free */
+	else
+		s0val = 0x04;	/* the 1st write area is free */
+
+	card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
+	card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
+	if (card->send.dmacur < card->send.dmairq)
+		s0val |= 0x02;	/* the 2nd read area is free */
+	else
+		s0val |= 0x01;	/* the 1st read area is free */
+
+	pr_debug("%s: DMA Status %02x/%02x/%02x %d/%d\n", card->name,
+		s1val, s0val, card->last_is0,
+		card->recv.idx, card->send.idx);
+	/* test if we have a DMA interrupt */
+	if (s0val != card->last_is0) {
+		if ((s0val & NJ_IRQM0_RD_MASK) !=
+		    (card->last_is0 & NJ_IRQM0_RD_MASK))
+			/* got a write dma int */
+			send_tiger(card, s0val);
+		if ((s0val & NJ_IRQM0_WR_MASK) !=
+		    (card->last_is0 & NJ_IRQM0_WR_MASK))
+			/* got a read dma int */
+			recv_tiger(card, s0val);
+	}
+end:
+	spin_unlock(&card->lock);
+	return IRQ_HANDLED;
+}
+
+static int
+nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
+{
+	int ret = -EINVAL;
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
+	struct tiger_hw *card = bch->hw;
+	struct mISDNhead *hh = mISDN_HEAD_P(skb);
+	u32 id;
+	u_long flags;
+
+	switch (hh->prim) {
+	case PH_DATA_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		ret = bchannel_senddata(bch, skb);
+		if (ret > 0) { /* direct TX */
+			id = hh->id; /* skb can be freed */
+			fill_dma(bc);
+			ret = 0;
+			spin_unlock_irqrestore(&card->lock, flags);
+			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
+				queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
+		} else
+			spin_unlock_irqrestore(&card->lock, flags);
+		return ret;
+	case PH_ACTIVATE_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
+			ret = mode_tiger(bc, ch->protocol);
+		else
+			ret = 0;
+		spin_unlock_irqrestore(&card->lock, flags);
+		if (!ret)
+			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
+				NULL, GFP_KERNEL);
+		break;
+	case PH_DEACTIVATE_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		mISDN_clear_bchannel(bch);
+		mode_tiger(bc, ISDN_P_NONE);
+		spin_unlock_irqrestore(&card->lock, flags);
+		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
+			NULL, GFP_KERNEL);
+		ret = 0;
+		break;
+	}
+	if (!ret)
+		dev_kfree_skb(skb);
+	return ret;
+}
+
+static int
+channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq)
+{
+	int ret = 0;
+	struct tiger_hw *card  = bc->bch.hw;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = 0;
+		break;
+	/* Nothing implemented yet */
+	case MISDN_CTRL_FILL_EMPTY:
+	default:
+		pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
+	struct tiger_hw *card  = bch->hw;
+	int ret = -EINVAL;
+	u_long flags;
+
+	pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
+	switch (cmd) {
+	case CLOSE_CHANNEL:
+		test_and_clear_bit(FLG_OPEN, &bch->Flags);
+		if (test_bit(FLG_ACTIVE, &bch->Flags)) {
+			spin_lock_irqsave(&card->lock, flags);
+			mISDN_freebchannel(bch);
+			test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
+			test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
+			mode_tiger(bc, ISDN_P_NONE);
+			spin_unlock_irqrestore(&card->lock, flags);
+		}
+		ch->protocol = ISDN_P_NONE;
+		ch->peer = NULL;
+		module_put(THIS_MODULE);
+		ret = 0;
+		break;
+	case CONTROL_CHANNEL:
+		ret = channel_bctrl(bc, arg);
+		break;
+	default:
+		pr_info("%s: %s unknown prim(%x)\n", card->name, __func__, cmd);
+	}
+	return ret;
+}
+
+static int
+channel_ctrl(struct tiger_hw *card, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = MISDN_CTRL_LOOP;
+		break;
+	case MISDN_CTRL_LOOP:
+		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
+		if (cq->channel < 0 || cq->channel > 3) {
+			ret = -EINVAL;
+			break;
+		}
+		ret = card->isac.ctrl(&card->isac, HW_TESTLOOP, cq->channel);
+		break;
+	default:
+		pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+open_bchannel(struct tiger_hw *card, struct channel_req *rq)
+{
+	struct bchannel *bch;
+
+	if (rq->adr.channel > 2)
+		return -EINVAL;
+	if (rq->protocol == ISDN_P_NONE)
+		return -EINVAL;
+	bch = &card->bc[rq->adr.channel - 1].bch;
+	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
+		return -EBUSY; /* b-channel can be only open once */
+	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
+	bch->ch.protocol = rq->protocol;
+	rq->ch = &bch->ch;
+	return 0;
+}
+
+/*
+ * device control function
+ */
+static int
+nj_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
+	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
+	struct tiger_hw	*card = dch->hw;
+	struct channel_req	*rq;
+	int			err = 0;
+
+	pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
+	switch (cmd) {
+	case OPEN_CHANNEL:
+		rq = arg;
+		if (rq->protocol == ISDN_P_TE_S0)
+			err = card->isac.open(&card->isac, rq);
+		else
+			err = open_bchannel(card, rq);
+		if (err)
+			break;
+		if (!try_module_get(THIS_MODULE))
+			pr_info("%s: cannot get module\n", card->name);
+		break;
+	case CLOSE_CHANNEL:
+		pr_debug("%s: dev(%d) close from %p\n", card->name, dch->dev.id,
+			__builtin_return_address(0));
+		module_put(THIS_MODULE);
+		break;
+	case CONTROL_CHANNEL:
+		err = channel_ctrl(card, arg);
+		break;
+	default:
+		pr_debug("%s: %s unknown command %x\n",
+			card->name, __func__, cmd);
+		return -EINVAL;
+	}
+	return err;
+}
+
+static int
+nj_init_card(struct tiger_hw *card)
+{
+	u_long flags;
+	int ret;
+
+	spin_lock_irqsave(&card->lock, flags);
+	nj_disable_hwirq(card);
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	card->irq = card->pdev->irq;
+	if (request_irq(card->irq, nj_irq, IRQF_SHARED, card->name, card)) {
+		pr_info("%s: couldn't get interrupt %d\n",
+			card->name, card->irq);
+		card->irq = -1;
+		return -EIO;
+	}
+
+	spin_lock_irqsave(&card->lock, flags);
+	nj_reset(card);
+	ret = card->isac.init(&card->isac);
+	if (ret)
+		goto error;
+	ret = inittiger(card);
+	if (ret)
+		goto error;
+	mode_tiger(&card->bc[0], ISDN_P_NONE);
+	mode_tiger(&card->bc[1], ISDN_P_NONE);
+error:
+	spin_unlock_irqrestore(&card->lock, flags);
+	return ret;
+}
+
+
+static void
+nj_release(struct tiger_hw *card)
+{
+	u_long flags;
+	int i;
+
+	if (card->base_s) {
+		spin_lock_irqsave(&card->lock, flags);
+		nj_disable_hwirq(card);
+		mode_tiger(&card->bc[0], ISDN_P_NONE);
+		mode_tiger(&card->bc[1], ISDN_P_NONE);
+		card->isac.release(&card->isac);
+		spin_unlock_irqrestore(&card->lock, flags);
+		release_region(card->base, card->base_s);
+		card->base_s = 0;
+	}
+	if (card->irq > 0)
+		free_irq(card->irq, card);
+	if (card->isac.dch.dev.dev.class)
+		mISDN_unregister_device(&card->isac.dch.dev);
+	
+	for (i = 0; i < 2; i++) {
+		mISDN_freebchannel(&card->bc[i].bch);
+		kfree(card->bc[i].hsbuf);
+		kfree(card->bc[i].hrbuf);
+	}
+	if (card->dma_p)
+		pci_free_consistent(card->pdev, NJ_DMA_SIZE,
+			card->dma_p, card->dma);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	pci_clear_master(card->pdev);
+	pci_disable_device(card->pdev);
+	pci_set_drvdata(card->pdev, NULL);
+	kfree(card);
+}
+
+
+static int
+nj_setup(struct tiger_hw *card)
+{
+	card->base = pci_resource_start(card->pdev, 0);
+	card->base_s = pci_resource_len(card->pdev, 0);
+	if (!request_region(card->base, card->base_s, card->name)) {
+		pr_info("%s: NETjet config port %#x-%#x already in use\n",
+			card->name, card->base,
+			(u32)(card->base + card->base_s - 1));
+		card->base_s = 0;
+		return -EIO;
+	}
+	ASSIGN_FUNC(nj, ISAC, card->isac);
+	return 0;
+}
+
+
+static int __devinit
+setup_instance(struct tiger_hw *card)
+{
+	int i, err;
+	u_long flags;
+
+	snprintf(card->name, MISDN_MAX_IDLEN - 1, "netjet.%d", nj_cnt + 1);
+	write_lock_irqsave(&card_lock, flags);
+	list_add_tail(&card->list, &Cards);
+	write_unlock_irqrestore(&card_lock, flags);
+
+	_set_debug(card);
+	card->isac.name = card->name;
+	spin_lock_init(&card->lock);
+	card->isac.hwlock = &card->lock;
+	mISDNisac_init(&card->isac, card);
+
+	card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+	card->isac.dch.dev.D.ctrl = nj_dctrl;
+	for (i = 0; i < 2; i++) {
+		card->bc[i].bch.nr = i + 1;
+		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
+		mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM);
+		card->bc[i].bch.hw = card;
+		card->bc[i].bch.ch.send = nj_l2l1B;
+		card->bc[i].bch.ch.ctrl = nj_bctrl;
+		card->bc[i].bch.ch.nr = i + 1;
+		list_add(&card->bc[i].bch.ch.list,
+			&card->isac.dch.dev.bchannels);
+		card->bc[i].bch.hw = card;
+	}
+	err = nj_setup(card);
+	if (err)
+		goto error;
+	err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
+		card->name);
+	if (err)
+		goto error;
+	err = nj_init_card(card);
+	if (!err)  {
+		nj_cnt++;
+		pr_notice("Netjet %d cards installed\n", nj_cnt);
+		return 0;
+	}
+error:
+	nj_release(card);
+	return err;
+}
+
+static int __devinit
+nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int err = -ENOMEM;
+	int cfg;
+	struct tiger_hw *card;
+
+	if (pdev->subsystem_vendor == 0x8086 &&
+	    pdev->subsystem_device == 0x0003) {
+		pr_notice("Netjet: Digium X100P/X101P not handled\n");
+		return -ENODEV;
+	}
+
+	if (pdev->subsystem_vendor == 0x55 &&
+	    pdev->subsystem_device == 0x02) {
+		pr_notice("Netjet: Enter!Now not handled yet\n");
+		return -ENODEV;
+	}
+
+	card = kzalloc(sizeof(struct tiger_hw), GFP_ATOMIC);
+	if (!card) {
+		pr_info("No kmem for Netjet\n");
+		return err;
+	}
+
+	card->pdev = pdev;
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		kfree(card);
+		return err;
+	}
+
+	printk(KERN_INFO "nj_probe(mISDN): found adapter at %s\n",
+		pci_name(pdev));
+
+	pci_set_master(pdev);
+
+	/* the TJ300 and TJ320 must be detected, the IRQ handling is different
+	 * unfortunately the chips use the same device ID, but the TJ320 has
+	 * the bit20 in status PCI cfg register set
+	 */
+	pci_read_config_dword(pdev, 0x04, &cfg);
+	if (cfg & 0x00100000)
+		card->typ = NETJET_S_TJ320;
+	else
+		card->typ = NETJET_S_TJ300;
+
+	card->base = pci_resource_start(pdev, 0);
+	card->irq = pdev->irq;
+	pci_set_drvdata(pdev, card);
+	err = setup_instance(card);
+	if (err)
+		pci_set_drvdata(pdev, NULL);
+
+	return err;
+}
+
+
+static void __devexit nj_remove(struct pci_dev *pdev)
+{
+	struct tiger_hw *card = pci_get_drvdata(pdev);
+
+	if (card)
+		nj_release(card);
+	else
+		pr_info("%s drvdata already removed\n", __func__);
+}
+
+/* We cannot select cards with PCI_SUB... IDs, since here are cards with
+ * SUB IDs set to PCI_ANY_ID, so we need to match all and reject
+ * known other cards which not work with this driver - see probe function */
+static struct pci_device_id nj_pci_ids[] __devinitdata = {
+	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, nj_pci_ids);
+
+static struct pci_driver nj_driver = {
+	.name = "netjet",
+	.probe = nj_probe,
+	.remove = __devexit_p(nj_remove),
+	.id_table = nj_pci_ids,
+};
+
+static int __init nj_init(void)
+{
+	int err;
+
+	pr_notice("Netjet PCI driver Rev. %s\n", NETJET_REV);
+	err = pci_register_driver(&nj_driver);
+	return err;
+}
+
+static void __exit nj_cleanup(void)
+{
+	pci_unregister_driver(&nj_driver);
+}
+
+module_init(nj_init);
+module_exit(nj_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/netjet.h b/drivers/isdn/hardware/mISDN/netjet.h
new file mode 100644
index 0000000..d061ff9
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/netjet.h
@@ -0,0 +1,58 @@
+/*
+ * NETjet common header file
+ *
+ * Author	Karsten Keil
+ *              based on work of Matt Henderson and Daniel Potts,
+ *              Traverse Technologies P/L www.traverse.com.au
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define NJ_CTRL			0x00
+#define NJ_DMACTRL		0x01
+#define NJ_AUXCTRL		0x02
+#define NJ_AUXDATA		0x03
+#define NJ_IRQMASK0		0x04
+#define NJ_IRQMASK1		0x05
+#define NJ_IRQSTAT0		0x06
+#define NJ_IRQSTAT1		0x07
+#define NJ_DMA_READ_START	0x08
+#define NJ_DMA_READ_IRQ		0x0c
+#define NJ_DMA_READ_END		0x10
+#define NJ_DMA_READ_ADR		0x14
+#define NJ_DMA_WRITE_START	0x18
+#define NJ_DMA_WRITE_IRQ	0x1c
+#define NJ_DMA_WRITE_END	0x20
+#define NJ_DMA_WRITE_ADR	0x24
+#define NJ_PULSE_CNT		0x28
+
+#define NJ_ISAC_OFF		0xc0
+#define NJ_ISACIRQ		0x10
+
+#define NJ_IRQM0_RD_MASK	0x03
+#define NJ_IRQM0_RD_IRQ		0x01
+#define NJ_IRQM0_RD_END		0x02
+#define NJ_IRQM0_WR_MASK	0x0c
+#define NJ_IRQM0_WR_IRQ		0x04
+#define NJ_IRQM0_WR_END		0x08
+
+/* one page here is no need to be smaller */
+#define NJ_DMA_SIZE		4096
+/* 2 * 64 byte is a compromise between IRQ count and latency */
+#define NJ_DMA_RXSIZE		128  /* 2 * 64 */
+#define NJ_DMA_TXSIZE		128  /* 2 * 64 */
+
diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c
new file mode 100644
index 0000000..ff3a4e2
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/speedfax.c
@@ -0,0 +1,526 @@
+/*
+ * speedfax.c	low level stuff for Sedlbauer Speedfax+ cards
+ *		based on the ISAR DSP
+ *		Thanks to Sedlbauer AG for informations and HW
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mISDNhw.h>
+#include <linux/firmware.h>
+#include "ipac.h"
+#include "isar.h"
+
+#define SPEEDFAX_REV	"2.0"
+
+#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID	0x51
+#define PCI_SUBVENDOR_SPEEDFAX_PCI	0x54
+#define PCI_SUB_ID_SEDLBAUER		0x01
+
+#define SFAX_PCI_ADDR		0xc8
+#define SFAX_PCI_ISAC		0xd0
+#define SFAX_PCI_ISAR		0xe0
+
+/* TIGER 100 Registers */
+
+#define TIGER_RESET_ADDR	0x00
+#define TIGER_EXTERN_RESET_ON	0x01
+#define TIGER_EXTERN_RESET_OFF	0x00
+#define TIGER_AUX_CTRL		0x02
+#define TIGER_AUX_DATA		0x03
+#define TIGER_AUX_IRQMASK	0x05
+#define TIGER_AUX_STATUS	0x07
+
+/* Tiger AUX BITs */
+#define SFAX_AUX_IOMASK		0xdd	/* 1 and 5 are inputs */
+#define SFAX_ISAR_RESET_BIT_OFF 0x00
+#define SFAX_ISAR_RESET_BIT_ON	0x01
+#define SFAX_TIGER_IRQ_BIT	0x02
+#define SFAX_LED1_BIT		0x08
+#define SFAX_LED2_BIT		0x10
+
+#define SFAX_PCI_RESET_ON	(SFAX_ISAR_RESET_BIT_ON)
+#define SFAX_PCI_RESET_OFF	(SFAX_LED1_BIT | SFAX_LED2_BIT)
+
+static int sfax_cnt;
+static u32 debug;
+static u32 irqloops = 4;
+
+struct sfax_hw {
+	struct list_head	list;
+	struct pci_dev		*pdev;
+	char			name[MISDN_MAX_IDLEN];
+	u32			irq;
+	u32			irqcnt;
+	u32			cfg;
+	struct _ioport		p_isac;
+	struct _ioport		p_isar;
+	u8			aux_data;
+	spinlock_t		lock;	/* HW access lock */
+	struct isac_hw		isac;
+	struct isar_hw		isar;
+};
+
+static LIST_HEAD(Cards);
+static DEFINE_RWLOCK(card_lock); /* protect Cards */
+
+static void
+_set_debug(struct sfax_hw *card)
+{
+	card->isac.dch.debug = debug;
+	card->isar.ch[0].bch.debug = debug;
+	card->isar.ch[1].bch.debug = debug;
+}
+
+static int
+set_debug(const char *val, struct kernel_param *kp)
+{
+	int ret;
+	struct sfax_hw *card;
+
+	ret = param_set_uint(val, kp);
+	if (!ret) {
+		read_lock(&card_lock);
+		list_for_each_entry(card, &Cards, list)
+			_set_debug(card);
+		read_unlock(&card_lock);
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("Karsten Keil");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(SPEEDFAX_REV);
+module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Speedfax debug mask");
+module_param(irqloops, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
+
+IOFUNC_IND(ISAC, sfax_hw, p_isac)
+IOFUNC_IND(ISAR, sfax_hw, p_isar)
+
+static irqreturn_t
+speedfax_irq(int intno, void *dev_id)
+{
+	struct sfax_hw	*sf = dev_id;
+	u8 val;
+	int cnt = irqloops;
+
+	spin_lock(&sf->lock);
+	val = inb(sf->cfg + TIGER_AUX_STATUS);
+	if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
+		spin_unlock(&sf->lock);
+		return IRQ_NONE; /* shared */
+	}
+	sf->irqcnt++;
+	val = ReadISAR_IND(sf, ISAR_IRQBIT);
+Start_ISAR:
+	if (val & ISAR_IRQSTA)
+		mISDNisar_irq(&sf->isar);
+	val = ReadISAC_IND(sf, ISAC_ISTA);
+	if (val)
+		mISDNisac_irq(&sf->isac, val);
+	val = ReadISAR_IND(sf, ISAR_IRQBIT);
+	if ((val & ISAR_IRQSTA) && cnt--)
+		goto Start_ISAR;
+	if (cnt < irqloops)
+		pr_debug("%s: %d irqloops cpu%d\n", sf->name,
+			irqloops - cnt, smp_processor_id());
+	if (irqloops && !cnt)
+		pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
+			irqloops, smp_processor_id());
+	spin_unlock(&sf->lock);
+	return IRQ_HANDLED;
+}
+
+static void
+enable_hwirq(struct sfax_hw *sf)
+{
+	WriteISAC_IND(sf, ISAC_MASK, 0);
+	WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
+	outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
+}
+
+static void
+disable_hwirq(struct sfax_hw *sf)
+{
+	WriteISAC_IND(sf, ISAC_MASK, 0xFF);
+	WriteISAR_IND(sf, ISAR_IRQBIT, 0);
+	outb(0, sf->cfg + TIGER_AUX_IRQMASK);
+}
+
+static void
+reset_speedfax(struct sfax_hw *sf)
+{
+
+	pr_debug("%s: resetting card\n", sf->name);
+	outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
+	outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
+	mdelay(1);
+	outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
+	sf->aux_data = SFAX_PCI_RESET_OFF;
+	outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
+	mdelay(1);
+}
+
+static int
+sfax_ctrl(struct sfax_hw  *sf, u32 cmd, u_long arg)
+{
+	int ret = 0;
+
+	switch (cmd) {
+	case HW_RESET_REQ:
+		reset_speedfax(sf);
+		break;
+	case HW_ACTIVATE_IND:
+		if (arg & 1)
+			sf->aux_data &= ~SFAX_LED1_BIT;
+		if (arg & 2)
+			sf->aux_data &= ~SFAX_LED2_BIT;
+		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
+		break;
+	case HW_DEACT_IND:
+		if (arg & 1)
+			sf->aux_data |= SFAX_LED1_BIT;
+		if (arg & 2)
+			sf->aux_data |= SFAX_LED2_BIT;
+		outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
+		break;
+	default:
+		pr_info("%s: %s unknown command %x %lx\n",
+			sf->name, __func__, cmd, arg);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+channel_ctrl(struct sfax_hw  *sf, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = MISDN_CTRL_LOOP;
+		break;
+	case MISDN_CTRL_LOOP:
+		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
+		if (cq->channel < 0 || cq->channel > 3) {
+			ret = -EINVAL;
+			break;
+		}
+		ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
+		break;
+	default:
+		pr_info("%s: unknown Op %x\n", sf->name, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
+	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
+	struct sfax_hw		*sf = dch->hw;
+	struct channel_req	*rq;
+	int			err = 0;
+
+	pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
+	switch (cmd) {
+	case OPEN_CHANNEL:
+		rq = arg;
+		if (rq->protocol == ISDN_P_TE_S0)
+			err = sf->isac.open(&sf->isac, rq);
+		else
+			err = sf->isar.open(&sf->isar, rq);
+		if (err)
+			break;
+		if (!try_module_get(THIS_MODULE))
+			pr_info("%s: cannot get module\n", sf->name);
+		break;
+	case CLOSE_CHANNEL:
+		pr_debug("%s: dev(%d) close from %p\n", sf->name,
+			dch->dev.id, __builtin_return_address(0));
+		module_put(THIS_MODULE);
+		break;
+	case CONTROL_CHANNEL:
+		err = channel_ctrl(sf, arg);
+		break;
+	default:
+		pr_debug("%s: unknown command %x\n", sf->name, cmd);
+		return -EINVAL;
+	}
+	return err;
+}
+
+static int __devinit
+init_card(struct sfax_hw *sf)
+{
+	int	ret, cnt = 3;
+	u_long	flags;
+
+	ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
+	if (ret) {
+		pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
+		return ret;
+	}
+	while (cnt--) {
+		spin_lock_irqsave(&sf->lock, flags);
+		ret = sf->isac.init(&sf->isac);
+		if (ret) {
+			spin_unlock_irqrestore(&sf->lock, flags);
+			pr_info("%s: ISAC init failed with %d\n",
+				sf->name, ret);
+			break;
+		}
+		enable_hwirq(sf);
+		/* RESET Receiver and Transmitter */
+		WriteISAC_IND(sf, ISAC_CMDR, 0x41);
+		spin_unlock_irqrestore(&sf->lock, flags);
+		msleep_interruptible(10);
+		if (debug & DEBUG_HW)
+			pr_notice("%s: IRQ %d count %d\n", sf->name,
+				sf->irq, sf->irqcnt);
+		if (!sf->irqcnt) {
+			pr_info("%s: IRQ(%d) got no requests during init %d\n",
+			       sf->name, sf->irq, 3 - cnt);
+		} else
+			return 0;
+	}
+	free_irq(sf->irq, sf);
+	return -EIO;
+}
+
+
+static int __devinit
+setup_speedfax(struct sfax_hw *sf)
+{
+	u_long flags;
+
+	if (!request_region(sf->cfg, 256, sf->name)) {
+		pr_info("mISDN: %s config port %x-%x already in use\n",
+		       sf->name, sf->cfg, sf->cfg + 255);
+		return -EIO;
+	}
+	outb(0xff, sf->cfg);
+	outb(0, sf->cfg);
+	outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
+	outb(0, sf->cfg + TIGER_AUX_IRQMASK);
+
+	sf->isac.type = IPAC_TYPE_ISAC;
+	sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
+	sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
+	sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
+	sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
+	ASSIGN_FUNC(IND, ISAC, sf->isac);
+	ASSIGN_FUNC(IND, ISAR, sf->isar);
+	spin_lock_irqsave(&sf->lock, flags);
+	reset_speedfax(sf);
+	disable_hwirq(sf);
+	spin_unlock_irqrestore(&sf->lock, flags);
+	return 0;
+}
+
+static void
+release_card(struct sfax_hw *card) {
+	u_long	flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+	disable_hwirq(card);
+	spin_unlock_irqrestore(&card->lock, flags);
+	card->isac.release(&card->isac);
+	free_irq(card->irq, card);
+	card->isar.release(&card->isar);
+	mISDN_unregister_device(&card->isac.dch.dev);
+	release_region(card->cfg, 256);
+	pci_disable_device(card->pdev);
+	pci_set_drvdata(card->pdev, NULL);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	kfree(card);
+	sfax_cnt--;
+}
+
+static int __devinit
+setup_instance(struct sfax_hw *card)
+{
+	const struct firmware *firmware;
+	int i, err;
+	u_long flags;
+
+	snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
+	write_lock_irqsave(&card_lock, flags);
+	list_add_tail(&card->list, &Cards);
+	write_unlock_irqrestore(&card_lock, flags);
+	_set_debug(card);
+	spin_lock_init(&card->lock);
+	card->isac.hwlock = &card->lock;
+	card->isar.hwlock = &card->lock;
+	card->isar.ctrl = (void *)&sfax_ctrl;
+	card->isac.name = card->name;
+	card->isar.name = card->name;
+	card->isar.owner = THIS_MODULE;
+
+	err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
+	if (err < 0) {
+		pr_info("%s: firmware request failed %d\n",
+			card->name, err);
+		goto error_fw;
+	}
+	if (debug & DEBUG_HW)
+		pr_notice("%s: got firmware %zu bytes\n",
+			card->name, firmware->size);
+
+	mISDNisac_init(&card->isac, card);
+
+	card->isac.dch.dev.D.ctrl = sfax_dctrl;
+	card->isac.dch.dev.Bprotocols =
+		mISDNisar_init(&card->isar, card);
+	for (i = 0; i < 2; i++) {
+		set_channelmap(i + 1, card->isac.dch.dev.channelmap);
+		list_add(&card->isar.ch[i].bch.ch.list,
+			&card->isac.dch.dev.bchannels);
+	}
+
+	err = setup_speedfax(card);
+	if (err)
+		goto error_setup;
+	err = card->isar.init(&card->isar);
+	if (err)
+		goto error;
+	err = mISDN_register_device(&card->isac.dch.dev,
+		&card->pdev->dev, card->name);
+	if (err)
+		goto error;
+	err = init_card(card);
+	if (err)
+		goto error_init;
+	err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
+	if (!err)  {
+		release_firmware(firmware);
+		sfax_cnt++;
+		pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
+		return 0;
+	}
+	disable_hwirq(card);
+	free_irq(card->irq, card);
+error_init:
+	mISDN_unregister_device(&card->isac.dch.dev);
+error:
+	release_region(card->cfg, 256);
+error_setup:
+	card->isac.release(&card->isac);
+	card->isar.release(&card->isar);
+	release_firmware(firmware);
+error_fw:
+	pci_disable_device(card->pdev);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	kfree(card);
+	return err;
+}
+
+static int __devinit
+sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int err = -ENOMEM;
+	struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL);
+
+	if (!card) {
+		pr_info("No memory for Speedfax+ PCI\n");
+		return err;
+	}
+	card->pdev = pdev;
+	err = pci_enable_device(pdev);
+	if (err) {
+		kfree(card);
+		return err;
+	}
+
+	pr_notice("mISDN: Speedfax found adapter %s at %s\n",
+		(char *)ent->driver_data, pci_name(pdev));
+
+	card->cfg = pci_resource_start(pdev, 0);
+	card->irq = pdev->irq;
+	pci_set_drvdata(pdev, card);
+	err = setup_instance(card);
+	if (err)
+		pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void __devexit
+sfax_remove_pci(struct pci_dev *pdev)
+{
+	struct sfax_hw	*card = pci_get_drvdata(pdev);
+
+	if (card)
+		release_card(card);
+	else
+		pr_debug("%s: drvdata allready removed\n", __func__);
+}
+
+static struct pci_device_id sfaxpci_ids[] __devinitdata = {
+	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
+	  PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
+	  0, 0, (unsigned long) "Pyramid Speedfax + PCI"
+	},
+	{ PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
+	  PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
+	  0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
+
+static struct pci_driver sfaxpci_driver = {
+	.name = "speedfax+ pci",
+	.probe = sfaxpci_probe,
+	.remove = __devexit_p(sfax_remove_pci),
+	.id_table = sfaxpci_ids,
+};
+
+static int __init
+Speedfax_init(void)
+{
+	int err;
+
+	pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
+		SPEEDFAX_REV);
+	err = pci_register_driver(&sfaxpci_driver);
+	return err;
+}
+
+static void __exit
+Speedfax_cleanup(void)
+{
+	pci_unregister_driver(&sfaxpci_driver);
+}
+
+module_init(Speedfax_init);
+module_exit(Speedfax_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
new file mode 100644
index 0000000..d3f1077
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -0,0 +1,1440 @@
+/*
+ * w6692.c     mISDN driver for Winbond w6692 based cards
+ *
+ * Author      Karsten Keil <kkeil@suse.de>
+ *             based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/mISDNhw.h>
+#include "w6692.h"
+
+#define W6692_REV	"2.0"
+
+#define DBUSY_TIMER_VALUE	80
+
+enum {
+	W6692_ASUS,
+	W6692_WINBOND,
+	W6692_USR
+};
+
+/* private data in the PCI devices list */
+struct w6692map {
+	u_int	subtype;
+	char	*name;
+};
+
+static const struct w6692map  w6692_map[] =
+{
+	{W6692_ASUS, "Dynalink/AsusCom IS64PH"},
+	{W6692_WINBOND, "Winbond W6692"},
+	{W6692_USR, "USR W6692"}
+};
+
+#ifndef PCI_VENDOR_ID_USR
+#define PCI_VENDOR_ID_USR	0x16ec
+#define PCI_DEVICE_ID_USR_6692	0x3409
+#endif
+
+struct w6692_ch {
+	struct bchannel		bch;
+	u32			addr;
+	struct timer_list	timer;
+	u8			b_mode;
+};
+
+struct w6692_hw {
+	struct list_head	list;
+	struct pci_dev		*pdev;
+	char			name[MISDN_MAX_IDLEN];
+	u32			irq;
+	u32			irqcnt;
+	u32			addr;
+	u32			fmask;	/* feature mask - bit set per card nr */
+	int			subtype;
+	spinlock_t		lock;	/* hw lock */
+	u8			imask;
+	u8			pctl;
+	u8			xaddr;
+	u8			xdata;
+	u8			state;
+	struct w6692_ch		bc[2];
+	struct dchannel		dch;
+	char			log[64];
+};
+
+static LIST_HEAD(Cards);
+static DEFINE_RWLOCK(card_lock); /* protect Cards */
+
+static int w6692_cnt;
+static int debug;
+static u32 led;
+static u32 pots;
+
+static void
+_set_debug(struct w6692_hw *card)
+{
+	card->dch.debug = debug;
+	card->bc[0].bch.debug = debug;
+	card->bc[1].bch.debug = debug;
+}
+
+static int
+set_debug(const char *val, struct kernel_param *kp)
+{
+	int ret;
+	struct w6692_hw *card;
+
+	ret = param_set_uint(val, kp);
+	if (!ret) {
+		read_lock(&card_lock);
+		list_for_each_entry(card, &Cards, list)
+			_set_debug(card);
+		read_unlock(&card_lock);
+	}
+	return ret;
+}
+
+MODULE_AUTHOR("Karsten Keil");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(W6692_REV);
+module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "W6692 debug mask");
+module_param(led, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(led, "W6692 LED support bitmask (one bit per card)");
+module_param(pots, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(pots, "W6692 POTS support bitmask (one bit per card)");
+
+static inline u8
+ReadW6692(struct w6692_hw *card, u8 offset)
+{
+	return inb(card->addr + offset);
+}
+
+static inline void
+WriteW6692(struct w6692_hw *card, u8 offset, u8 value)
+{
+	outb(value, card->addr + offset);
+}
+
+static inline u8
+ReadW6692B(struct w6692_ch *bc, u8 offset)
+{
+	return inb(bc->addr + offset);
+}
+
+static inline void
+WriteW6692B(struct w6692_ch *bc, u8 offset, u8 value)
+{
+	outb(value, bc->addr + offset);
+}
+
+static void
+enable_hwirq(struct w6692_hw *card)
+{
+	WriteW6692(card, W_IMASK, card->imask);
+}
+
+static void
+disable_hwirq(struct w6692_hw *card)
+{
+	WriteW6692(card, W_IMASK, 0xff);
+}
+
+static const char *W6692Ver[] = {"V00", "V01", "V10", "V11"};
+
+static void
+W6692Version(struct w6692_hw *card)
+{
+	int val;
+
+	val = ReadW6692(card, W_D_RBCH);
+	pr_notice("%s: Winbond W6692 version: %s\n", card->name,
+		W6692Ver[(val >> 6) & 3]);
+}
+
+static void
+w6692_led_handler(struct w6692_hw *card, int on)
+{
+	if ((!(card->fmask & led)) || card->subtype == W6692_USR)
+		return;
+	if (on) {
+		card->xdata &= 0xfb;	/*  LED ON */
+		WriteW6692(card, W_XDATA, card->xdata);
+	} else {
+		card->xdata |= 0x04;	/*  LED OFF */
+		WriteW6692(card, W_XDATA, card->xdata);
+	}
+}
+
+static void
+ph_command(struct w6692_hw *card, u8 cmd)
+{
+	pr_debug("%s: ph_command %x\n", card->name, cmd);
+	WriteW6692(card, W_CIX, cmd);
+}
+
+static void
+W6692_new_ph(struct w6692_hw *card)
+{
+	if (card->state == W_L1CMD_RST)
+		ph_command(card, W_L1CMD_DRC);
+	schedule_event(&card->dch, FLG_PHCHANGE);
+}
+
+static void
+W6692_ph_bh(struct dchannel *dch)
+{
+	struct w6692_hw *card = dch->hw;
+
+	switch (card->state) {
+	case W_L1CMD_RST:
+		dch->state = 0;
+		l1_event(dch->l1, HW_RESET_IND);
+		break;
+	case W_L1IND_CD:
+		dch->state = 3;
+		l1_event(dch->l1, HW_DEACT_CNF);
+		break;
+	case W_L1IND_DRD:
+		dch->state = 3;
+		l1_event(dch->l1, HW_DEACT_IND);
+		break;
+	case W_L1IND_CE:
+		dch->state = 4;
+		l1_event(dch->l1, HW_POWERUP_IND);
+		break;
+	case W_L1IND_LD:
+		if (dch->state <= 5) {
+			dch->state = 5;
+			l1_event(dch->l1, ANYSIGNAL);
+		} else {
+			dch->state = 8;
+			l1_event(dch->l1, LOSTFRAMING);
+		}
+		break;
+	case W_L1IND_ARD:
+		dch->state = 6;
+		l1_event(dch->l1, INFO2);
+		break;
+	case W_L1IND_AI8:
+		dch->state = 7;
+		l1_event(dch->l1, INFO4_P8);
+		break;
+	case W_L1IND_AI10:
+		dch->state = 7;
+		l1_event(dch->l1, INFO4_P10);
+		break;
+	default:
+		pr_debug("%s: TE unknown state %02x dch state %02x\n",
+			card->name, card->state, dch->state);
+		break;
+	}
+	pr_debug("%s: TE newstate %02x\n", card->name, dch->state);
+}
+
+static void
+W6692_empty_Dfifo(struct w6692_hw *card, int count)
+{
+	struct dchannel *dch = &card->dch;
+	u8 *ptr;
+
+	pr_debug("%s: empty_Dfifo %d\n", card->name, count);
+	if (!dch->rx_skb) {
+		dch->rx_skb = mI_alloc_skb(card->dch.maxlen, GFP_ATOMIC);
+		if (!dch->rx_skb) {
+			pr_info("%s: D receive out of memory\n", card->name);
+			WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
+			return;
+		}
+	}
+	if ((dch->rx_skb->len + count) >= dch->maxlen) {
+		pr_debug("%s: empty_Dfifo overrun %d\n", card->name,
+			dch->rx_skb->len + count);
+		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
+		return;
+	}
+	ptr = skb_put(dch->rx_skb, count);
+	insb(card->addr + W_D_RFIFO, ptr, count);
+	WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
+	if (debug & DEBUG_HW_DFIFO) {
+		snprintf(card->log, 63, "D-recv %s %d ",
+			card->name, count);
+		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
+	}
+}
+
+static void
+W6692_fill_Dfifo(struct w6692_hw *card)
+{
+	struct dchannel *dch = &card->dch;
+	int count;
+	u8 *ptr;
+	u8 cmd = W_D_CMDR_XMS;
+
+	pr_debug("%s: fill_Dfifo\n", card->name);
+	if (!dch->tx_skb)
+		return;
+	count = dch->tx_skb->len - dch->tx_idx;
+	if (count <= 0)
+		return;
+	if (count > W_D_FIFO_THRESH)
+		count = W_D_FIFO_THRESH;
+	else
+		cmd |= W_D_CMDR_XME;
+	ptr = dch->tx_skb->data + dch->tx_idx;
+	dch->tx_idx += count;
+	outsb(card->addr + W_D_XFIFO, ptr, count);
+	WriteW6692(card, W_D_CMDR, cmd);
+	if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
+		pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name);
+		del_timer(&dch->timer);
+	}
+	init_timer(&dch->timer);
+	dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
+	add_timer(&dch->timer);
+	if (debug & DEBUG_HW_DFIFO) {
+		snprintf(card->log, 63, "D-send %s %d ",
+			card->name, count);
+		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
+	}
+}
+
+static void
+d_retransmit(struct w6692_hw *card)
+{
+	struct dchannel *dch = &card->dch;
+
+	if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
+		del_timer(&dch->timer);
+#ifdef FIXME
+	if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
+		dchannel_sched_event(dch, D_CLEARBUSY);
+#endif
+	if (test_bit(FLG_TX_BUSY, &dch->Flags)) {
+		/* Restart frame */
+		dch->tx_idx = 0;
+		W6692_fill_Dfifo(card);
+	} else if (dch->tx_skb) { /* should not happen */
+		pr_info("%s: %s without TX_BUSY\n", card->name, __func__);
+		test_and_set_bit(FLG_TX_BUSY, &dch->Flags);
+		dch->tx_idx = 0;
+		W6692_fill_Dfifo(card);
+	} else {
+		pr_info("%s: XDU no TX_BUSY\n", card->name);
+		if (get_next_dframe(dch))
+			W6692_fill_Dfifo(card);
+	}
+}
+
+static void
+handle_rxD(struct w6692_hw *card) {
+	u8	stat;
+	int	count;
+
+	stat = ReadW6692(card, W_D_RSTA);
+	if (stat & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
+		if (stat & W_D_RSTA_RDOV) {
+			pr_debug("%s: D-channel RDOV\n", card->name);
+#ifdef ERROR_STATISTIC
+			card->dch.err_rx++;
+#endif
+		}
+		if (stat & W_D_RSTA_CRCE) {
+			pr_debug("%s: D-channel CRC error\n", card->name);
+#ifdef ERROR_STATISTIC
+			card->dch.err_crc++;
+#endif
+		}
+		if (stat & W_D_RSTA_RMB) {
+			pr_debug("%s: D-channel ABORT\n", card->name);
+#ifdef ERROR_STATISTIC
+			card->dch.err_rx++;
+#endif
+		}
+		if (card->dch.rx_skb)
+			dev_kfree_skb(card->dch.rx_skb);
+		card->dch.rx_skb = NULL;
+		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
+	} else {
+		count = ReadW6692(card, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
+		if (count == 0)
+			count = W_D_FIFO_THRESH;
+		W6692_empty_Dfifo(card, count);
+		recv_Dchannel(&card->dch);
+	}
+}
+
+static void
+handle_txD(struct w6692_hw *card) {
+	if (test_and_clear_bit(FLG_BUSY_TIMER, &card->dch.Flags))
+		del_timer(&card->dch.timer);
+	if (card->dch.tx_skb && card->dch.tx_idx < card->dch.tx_skb->len) {
+		W6692_fill_Dfifo(card);
+	} else {
+		if (card->dch.tx_skb)
+			dev_kfree_skb(card->dch.tx_skb);
+		if (get_next_dframe(&card->dch))
+			W6692_fill_Dfifo(card);
+	}
+}
+
+static void
+handle_statusD(struct w6692_hw *card)
+{
+	struct dchannel *dch = &card->dch;
+	u8 exval, v1, cir;
+
+	exval = ReadW6692(card, W_D_EXIR);
+
+	pr_debug("%s: D_EXIR %02x\n", card->name, exval);
+	if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {
+		/* Transmit underrun/collision */
+		pr_debug("%s: D-channel underrun/collision\n", card->name);
+#ifdef ERROR_STATISTIC
+		dch->err_tx++;
+#endif
+		d_retransmit(card);
+	}
+	if (exval & W_D_EXI_RDOV) {	/* RDOV */
+		pr_debug("%s: D-channel RDOV\n", card->name);
+		WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST);
+	}
+	if (exval & W_D_EXI_TIN2)	/* TIN2 - never */
+		pr_debug("%s: spurious TIN2 interrupt\n", card->name);
+	if (exval & W_D_EXI_MOC) {	/* MOC - not supported */
+		v1 = ReadW6692(card, W_MOSR);
+		pr_debug("%s: spurious MOC interrupt MOSR %02x\n",
+			card->name, v1);
+	}
+	if (exval & W_D_EXI_ISC) {	/* ISC - Level1 change */
+		cir = ReadW6692(card, W_CIR);
+		pr_debug("%s: ISC CIR %02X\n", card->name, cir);
+		if (cir & W_CIR_ICC) {
+			v1 = cir & W_CIR_COD_MASK;
+			pr_debug("%s: ph_state_change %x -> %x\n", card->name,
+				dch->state, v1);
+			card->state = v1;
+			if (card->fmask & led) {
+				switch (v1) {
+				case W_L1IND_AI8:
+				case W_L1IND_AI10:
+					w6692_led_handler(card, 1);
+					break;
+				default:
+					w6692_led_handler(card, 0);
+					break;
+				}
+			}
+			W6692_new_ph(card);
+		}
+		if (cir & W_CIR_SCC) {
+			v1 = ReadW6692(card, W_SQR);
+			pr_debug("%s: SCC SQR %02X\n", card->name, v1);
+		}
+	}
+	if (exval & W_D_EXI_WEXP)
+		pr_debug("%s: spurious WEXP interrupt!\n", card->name);
+	if (exval & W_D_EXI_TEXP)
+		pr_debug("%s: spurious TEXP interrupt!\n", card->name);
+}
+
+static void
+W6692_empty_Bfifo(struct w6692_ch *wch, int count)
+{
+	struct w6692_hw *card = wch->bch.hw;
+	u8 *ptr;
+
+	pr_debug("%s: empty_Bfifo %d\n", card->name, count);
+	if (unlikely(wch->bch.state == ISDN_P_NONE)) {
+		pr_debug("%s: empty_Bfifo ISDN_P_NONE\n", card->name);
+		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
+		if (wch->bch.rx_skb)
+			skb_trim(wch->bch.rx_skb, 0);
+		return;
+	}
+	if (!wch->bch.rx_skb) {
+		wch->bch.rx_skb = mI_alloc_skb(wch->bch.maxlen, GFP_ATOMIC);
+		if (unlikely(!wch->bch.rx_skb)) {
+			pr_info("%s: B receive out of memory\n", card->name);
+			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
+				W_B_CMDR_RACT);
+			return;
+		}
+	}
+	if (wch->bch.rx_skb->len + count > wch->bch.maxlen) {
+		pr_debug("%s: empty_Bfifo incoming packet too large\n",
+			card->name);
+		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
+		skb_trim(wch->bch.rx_skb, 0);
+		return;
+	}
+	ptr = skb_put(wch->bch.rx_skb, count);
+	insb(wch->addr + W_B_RFIFO, ptr, count);
+	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
+	if (debug & DEBUG_HW_DFIFO) {
+		snprintf(card->log, 63, "B%1d-recv %s %d ",
+			wch->bch.nr, card->name, count);
+		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
+	}
+}
+
+static void
+W6692_fill_Bfifo(struct w6692_ch *wch)
+{
+	struct w6692_hw *card = wch->bch.hw;
+	int count;
+	u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
+
+	pr_debug("%s: fill Bfifo\n", card->name);
+	if (!wch->bch.tx_skb)
+		return;
+	count = wch->bch.tx_skb->len - wch->bch.tx_idx;
+	if (count <= 0)
+		return;
+	ptr = wch->bch.tx_skb->data + wch->bch.tx_idx;
+	if (count > W_B_FIFO_THRESH)
+		count = W_B_FIFO_THRESH;
+	else if (test_bit(FLG_HDLC, &wch->bch.Flags))
+		cmd |= W_B_CMDR_XME;
+
+	pr_debug("%s: fill Bfifo%d/%d\n", card->name,
+			count, wch->bch.tx_idx);
+	wch->bch.tx_idx += count;
+	outsb(wch->addr + W_B_XFIFO, ptr, count);
+	WriteW6692B(wch, W_B_CMDR, cmd);
+	if (debug & DEBUG_HW_DFIFO) {
+		snprintf(card->log, 63, "B%1d-send %s %d ",
+			wch->bch.nr, card->name, count);
+		print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
+	}
+}
+
+static int
+setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
+{
+	struct w6692_hw *card = wch->bch.hw;
+	u16 *vol = (u16 *)skb->data;
+	u8 val;
+
+	if ((!(card->fmask & pots)) ||
+	    !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
+		return -ENODEV;
+	if (skb->len < 2)
+		return -EINVAL;
+	if (*vol > 7)
+		return -EINVAL;
+	val = *vol & 7;
+	val = 7 - val;
+	if (mic) {
+		val <<= 3;
+		card->xaddr &= 0xc7;
+	} else {
+		card->xaddr &= 0xf8;
+	}
+	card->xaddr |= val;
+	WriteW6692(card, W_XADDR, card->xaddr);
+	return 0;
+}
+
+static int
+enable_pots(struct w6692_ch *wch)
+{
+	struct w6692_hw *card = wch->bch.hw;
+
+	if ((!(card->fmask & pots)) ||
+	    !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
+		return -ENODEV;
+	wch->b_mode |= W_B_MODE_EPCM | W_B_MODE_BSW0;
+	WriteW6692B(wch, W_B_MODE, wch->b_mode);
+	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
+	card->pctl |= ((wch->bch.nr & 2) ? W_PCTL_PCX : 0);
+	WriteW6692(card, W_PCTL, card->pctl);
+	return 0;
+}
+
+static int
+disable_pots(struct w6692_ch *wch)
+{
+	struct w6692_hw *card = wch->bch.hw;
+
+	if (!(card->fmask & pots))
+		return -ENODEV;
+	wch->b_mode &= ~(W_B_MODE_EPCM | W_B_MODE_BSW0);
+	WriteW6692B(wch, W_B_MODE, wch->b_mode);
+	WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
+		W_B_CMDR_XRST);
+	return 0;
+}
+
+static int
+w6692_mode(struct w6692_ch *wch, u32 pr)
+{
+	struct w6692_hw	*card;
+
+	card = wch->bch.hw;
+	pr_debug("%s: B%d protocol %x-->%x\n", card->name,
+		wch->bch.nr, wch->bch.state, pr);
+	switch (pr) {
+	case ISDN_P_NONE:
+		if ((card->fmask & pots) && (wch->b_mode & W_B_MODE_EPCM))
+			disable_pots(wch);
+		wch->b_mode = 0;
+		mISDN_clear_bchannel(&wch->bch);
+		WriteW6692B(wch, W_B_MODE, wch->b_mode);
+		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
+		test_and_clear_bit(FLG_HDLC, &wch->bch.Flags);
+		test_and_clear_bit(FLG_TRANSPARENT, &wch->bch.Flags);
+		break;
+	case ISDN_P_B_RAW:
+		wch->b_mode = W_B_MODE_MMS;
+		WriteW6692B(wch, W_B_MODE, wch->b_mode);
+		WriteW6692B(wch, W_B_EXIM, 0);
+		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
+			W_B_CMDR_XRST);
+		test_and_set_bit(FLG_TRANSPARENT, &wch->bch.Flags);
+		break;
+	case ISDN_P_B_HDLC:
+		wch->b_mode = W_B_MODE_ITF;
+		WriteW6692B(wch, W_B_MODE, wch->b_mode);
+		WriteW6692B(wch, W_B_ADM1, 0xff);
+		WriteW6692B(wch, W_B_ADM2, 0xff);
+		WriteW6692B(wch, W_B_EXIM, 0);
+		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
+			W_B_CMDR_XRST);
+		test_and_set_bit(FLG_HDLC, &wch->bch.Flags);
+		break;
+	default:
+		pr_info("%s: protocol %x not known\n", card->name, pr);
+		return -ENOPROTOOPT;
+	}
+	wch->bch.state = pr;
+	return 0;
+}
+
+static void
+send_next(struct w6692_ch *wch)
+{
+	if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len)
+		W6692_fill_Bfifo(wch);
+	else {
+		if (wch->bch.tx_skb) {
+			/* send confirm, on trans, free on hdlc. */
+			if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
+				confirm_Bsend(&wch->bch);
+			dev_kfree_skb(wch->bch.tx_skb);
+		}
+		if (get_next_bframe(&wch->bch))
+			W6692_fill_Bfifo(wch);
+	}
+}
+
+static void
+W6692B_interrupt(struct w6692_hw *card, int ch)
+{
+	struct w6692_ch	*wch = &card->bc[ch];
+	int		count;
+	u8		stat, star = 0;
+
+	stat = ReadW6692B(wch, W_B_EXIR);
+	pr_debug("%s: B%d EXIR %02x\n", card->name, wch->bch.nr, stat);
+	if (stat & W_B_EXI_RME) {
+		star = ReadW6692B(wch, W_B_STAR);
+		if (star & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
+			if ((star & W_B_STAR_RDOV) &&
+			    test_bit(FLG_ACTIVE, &wch->bch.Flags)) {
+				pr_debug("%s: B%d RDOV proto=%x\n", card->name,
+					wch->bch.nr, wch->bch.state);
+#ifdef ERROR_STATISTIC
+				wch->bch.err_rdo++;
+#endif
+			}
+			if (test_bit(FLG_HDLC, &wch->bch.Flags)) {
+				if (star & W_B_STAR_CRCE) {
+					pr_debug("%s: B%d CRC error\n",
+						card->name, wch->bch.nr);
+#ifdef ERROR_STATISTIC
+					wch->bch.err_crc++;
+#endif
+				}
+				if (star & W_B_STAR_RMB) {
+					pr_debug("%s: B%d message abort\n",
+						card->name, wch->bch.nr);
+#ifdef ERROR_STATISTIC
+					wch->bch.err_inv++;
+#endif
+				}
+			}
+			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
+				W_B_CMDR_RRST | W_B_CMDR_RACT);
+			if (wch->bch.rx_skb)
+				skb_trim(wch->bch.rx_skb, 0);
+		} else {
+			count = ReadW6692B(wch, W_B_RBCL) &
+				(W_B_FIFO_THRESH - 1);
+			if (count == 0)
+				count = W_B_FIFO_THRESH;
+			W6692_empty_Bfifo(wch, count);
+			recv_Bchannel(&wch->bch, 0);
+		}
+	}
+	if (stat & W_B_EXI_RMR) {
+		if (!(stat & W_B_EXI_RME))
+			star = ReadW6692B(wch, W_B_STAR);
+		if (star & W_B_STAR_RDOV) {
+			pr_debug("%s: B%d RDOV proto=%x\n", card->name,
+				wch->bch.nr, wch->bch.state);
+#ifdef ERROR_STATISTIC
+			wch->bch.err_rdo++;
+#endif
+			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
+				W_B_CMDR_RRST | W_B_CMDR_RACT);
+		} else {
+			W6692_empty_Bfifo(wch, W_B_FIFO_THRESH);
+			if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags) &&
+			    wch->bch.rx_skb && (wch->bch.rx_skb->len > 0))
+				recv_Bchannel(&wch->bch, 0);
+		}
+	}
+	if (stat & W_B_EXI_RDOV) {
+		/* only if it is not handled yet */
+		if (!(star & W_B_STAR_RDOV)) {
+			pr_debug("%s: B%d RDOV IRQ proto=%x\n", card->name,
+				wch->bch.nr, wch->bch.state);
+#ifdef ERROR_STATISTIC
+			wch->bch.err_rdo++;
+#endif
+			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
+				W_B_CMDR_RRST | W_B_CMDR_RACT);
+		}
+	}
+	if (stat & W_B_EXI_XFR) {
+		if (!(stat & (W_B_EXI_RME | W_B_EXI_RMR))) {
+			star = ReadW6692B(wch, W_B_STAR);
+			pr_debug("%s: B%d star %02x\n", card->name,
+				wch->bch.nr, star);
+		}
+		if (star & W_B_STAR_XDOW) {
+			pr_debug("%s: B%d XDOW proto=%x\n", card->name,
+				wch->bch.nr, wch->bch.state);
+#ifdef ERROR_STATISTIC
+			wch->bch.err_xdu++;
+#endif
+			WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST |
+				W_B_CMDR_RACT);
+			/* resend */
+			if (wch->bch.tx_skb) {
+				if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
+					wch->bch.tx_idx = 0;
+			}
+		}
+		send_next(wch);
+		if (stat & W_B_EXI_XDUN)
+			return; /* handle XDOW only once */
+	}
+	if (stat & W_B_EXI_XDUN) {
+		pr_debug("%s: B%d XDUN proto=%x\n", card->name,
+			wch->bch.nr, wch->bch.state);
+#ifdef ERROR_STATISTIC
+		wch->bch.err_xdu++;
+#endif
+		WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
+		/* resend */
+		if (wch->bch.tx_skb) {
+			if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
+				wch->bch.tx_idx = 0;
+		}
+		send_next(wch);
+	}
+}
+
+static irqreturn_t
+w6692_irq(int intno, void *dev_id)
+{
+	struct w6692_hw	*card = dev_id;
+	u8		ista;
+
+	spin_lock(&card->lock);
+	ista = ReadW6692(card, W_ISTA);
+	if ((ista | card->imask) == card->imask) {
+		/* possible a shared  IRQ reqest */
+		spin_unlock(&card->lock);
+		return IRQ_NONE;
+	}
+	card->irqcnt++;
+	pr_debug("%s: ista %02x\n", card->name, ista);
+	ista &= ~card->imask;
+	if (ista & W_INT_B1_EXI)
+		W6692B_interrupt(card, 0);
+	if (ista & W_INT_B2_EXI)
+		W6692B_interrupt(card, 1);
+	if (ista & W_INT_D_RME)
+		handle_rxD(card);
+	if (ista & W_INT_D_RMR)
+		W6692_empty_Dfifo(card, W_D_FIFO_THRESH);
+	if (ista & W_INT_D_XFR)
+		handle_txD(card);
+	if (ista & W_INT_D_EXI)
+		handle_statusD(card);
+	if (ista & (W_INT_XINT0 | W_INT_XINT1)) /* XINT0/1 - never */
+		pr_debug("%s: W6692 spurious XINT!\n", card->name);
+/* End IRQ Handler */
+	spin_unlock(&card->lock);
+	return IRQ_HANDLED;
+}
+
+static void
+dbusy_timer_handler(struct dchannel *dch)
+{
+	struct w6692_hw	*card = dch->hw;
+	int		rbch, star;
+	u_long		flags;
+
+	if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) {
+		spin_lock_irqsave(&card->lock, flags);
+		rbch = ReadW6692(card, W_D_RBCH);
+		star = ReadW6692(card, W_D_STAR);
+		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
+			card->name, rbch, star);
+		if (star & W_D_STAR_XBZ)	/* D-Channel Busy */
+			test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
+		else {
+			/* discard frame; reset transceiver */
+			test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags);
+			if (dch->tx_idx)
+				dch->tx_idx = 0;
+			else
+				pr_info("%s: W6692 D-Channel Busy no tx_idx\n",
+					card->name);
+			/* Transmitter reset */
+			WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST);
+		}
+		spin_unlock_irqrestore(&card->lock, flags);
+	}
+}
+
+void initW6692(struct w6692_hw *card)
+{
+	u8	val;
+
+	card->dch.timer.function = (void *)dbusy_timer_handler;
+	card->dch.timer.data = (u_long)&card->dch;
+	init_timer(&card->dch.timer);
+	w6692_mode(&card->bc[0], ISDN_P_NONE);
+	w6692_mode(&card->bc[1], ISDN_P_NONE);
+	WriteW6692(card, W_D_CTL, 0x00);
+	disable_hwirq(card);
+	WriteW6692(card, W_D_SAM, 0xff);
+	WriteW6692(card, W_D_TAM, 0xff);
+	WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
+	card->state = W_L1CMD_RST;
+	ph_command(card, W_L1CMD_RST);
+	ph_command(card, W_L1CMD_ECK);
+	/* enable all IRQ but extern */
+	card->imask = 0x18;
+	WriteW6692(card, W_D_EXIM, 0x00);
+	WriteW6692B(&card->bc[0], W_B_EXIM, 0);
+	WriteW6692B(&card->bc[1], W_B_EXIM, 0);
+	/* Reset D-chan receiver and transmitter */
+	WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
+	/* Reset B-chan receiver and transmitter */
+	WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
+	WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
+	/* enable peripheral */
+	if (card->subtype == W6692_USR) {
+		/* seems that USR implemented some power control features
+		 * Pin 79 is connected to the oscilator circuit so we
+		 * have to handle it here
+		 */
+		card->pctl = 0x80;
+		card->xdata = 0;
+		WriteW6692(card, W_PCTL, card->pctl);
+		WriteW6692(card, W_XDATA, card->xdata);
+	} else {
+		card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 |
+			W_PCTL_OE1 | W_PCTL_OE0;
+		card->xaddr = 0x00;/* all sw off */
+		if (card->fmask & pots)
+			card->xdata |= 0x06;	/*  POWER UP/ LED OFF / ALAW */
+		if (card->fmask & led)
+			card->xdata |= 0x04;	/* LED OFF */
+		if ((card->fmask & pots) || (card->fmask & led)) {
+			WriteW6692(card, W_PCTL, card->pctl);
+			WriteW6692(card, W_XADDR, card->xaddr);
+			WriteW6692(card, W_XDATA, card->xdata);
+			val = ReadW6692(card, W_XADDR);
+			if (debug & DEBUG_HW)
+				pr_notice("%s: W_XADDR=%02x\n",
+					card->name, val);
+		}
+	}
+}
+
+static void
+reset_w6692(struct w6692_hw *card)
+{
+	WriteW6692(card, W_D_CTL, W_D_CTL_SRST);
+	mdelay(10);
+	WriteW6692(card, W_D_CTL, 0);
+}
+
+static int
+init_card(struct w6692_hw *card)
+{
+	int	cnt = 3;
+	u_long	flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+	disable_hwirq(card);
+	spin_unlock_irqrestore(&card->lock, flags);
+	if (request_irq(card->irq, w6692_irq, IRQF_SHARED, card->name, card)) {
+		pr_info("%s: couldn't get interrupt %d\n", card->name,
+			card->irq);
+		return -EIO;
+	}
+	while (cnt--) {
+		spin_lock_irqsave(&card->lock, flags);
+		initW6692(card);
+		enable_hwirq(card);
+		spin_unlock_irqrestore(&card->lock, flags);
+		/* Timeout 10ms */
+		msleep_interruptible(10);
+		if (debug & DEBUG_HW)
+			pr_notice("%s: IRQ %d count %d\n", card->name,
+				card->irq, card->irqcnt);
+		if (!card->irqcnt) {
+			pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
+				card->name, card->irq, 3 - cnt);
+			reset_w6692(card);
+		} else
+			return 0;
+	}
+	free_irq(card->irq, card);
+	return -EIO;
+}
+
+static int
+w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct w6692_ch	*bc = container_of(bch, struct w6692_ch, bch);
+	struct w6692_hw *card = bch->hw;
+	int ret = -EINVAL;
+	struct mISDNhead *hh = mISDN_HEAD_P(skb);
+	u32 id;
+	u_long flags;
+
+	switch (hh->prim) {
+	case PH_DATA_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		ret = bchannel_senddata(bch, skb);
+		if (ret > 0) { /* direct TX */
+			id = hh->id; /* skb can be freed */
+			ret = 0;
+			W6692_fill_Bfifo(bc);
+			spin_unlock_irqrestore(&card->lock, flags);
+			if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
+				queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
+		} else
+			spin_unlock_irqrestore(&card->lock, flags);
+		return ret;
+	case PH_ACTIVATE_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
+			ret = w6692_mode(bc, ch->protocol);
+		else
+			ret = 0;
+		spin_unlock_irqrestore(&card->lock, flags);
+		if (!ret)
+			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
+				NULL, GFP_KERNEL);
+		break;
+	case PH_DEACTIVATE_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		mISDN_clear_bchannel(bch);
+		w6692_mode(bc, ISDN_P_NONE);
+		spin_unlock_irqrestore(&card->lock, flags);
+		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
+			NULL, GFP_KERNEL);
+		ret = 0;
+		break;
+	default:
+		pr_info("%s: %s unknown prim(%x,%x)\n",
+			card->name, __func__, hh->prim, hh->id);
+		ret = -EINVAL;
+	}
+	if (!ret)
+		dev_kfree_skb(skb);
+	return ret;
+}
+
+static int
+channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = 0;
+		break;
+	/* Nothing implemented yet */
+	case MISDN_CTRL_FILL_EMPTY:
+	default:
+		pr_info("%s: unknown Op %x\n", __func__, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+open_bchannel(struct w6692_hw *card, struct channel_req *rq)
+{
+	struct bchannel *bch;
+
+	if (rq->adr.channel > 2)
+		return -EINVAL;
+	if (rq->protocol == ISDN_P_NONE)
+		return -EINVAL;
+	bch = &card->bc[rq->adr.channel - 1].bch;
+	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
+		return -EBUSY; /* b-channel can be only open once */
+	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
+	bch->ch.protocol = rq->protocol;
+	rq->ch = &bch->ch;
+	return 0;
+}
+
+static int
+channel_ctrl(struct w6692_hw *card, struct mISDN_ctrl_req *cq)
+{
+	int	ret = 0;
+
+	switch (cq->op) {
+	case MISDN_CTRL_GETOP:
+		cq->op = 0;
+		break;
+	default:
+		pr_info("%s: unknown CTRL OP %x\n", card->name, cq->op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct bchannel *bch = container_of(ch, struct bchannel, ch);
+	struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch);
+	struct w6692_hw *card = bch->hw;
+	int ret = -EINVAL;
+	u_long flags;
+
+	pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
+	switch (cmd) {
+	case CLOSE_CHANNEL:
+		test_and_clear_bit(FLG_OPEN, &bch->Flags);
+		if (test_bit(FLG_ACTIVE, &bch->Flags)) {
+			spin_lock_irqsave(&card->lock, flags);
+			mISDN_freebchannel(bch);
+			w6692_mode(bc, ISDN_P_NONE);
+			spin_unlock_irqrestore(&card->lock, flags);
+		} else {
+			skb_queue_purge(&bch->rqueue);
+			bch->rcount = 0;
+		}
+		ch->protocol = ISDN_P_NONE;
+		ch->peer = NULL;
+		module_put(THIS_MODULE);
+		ret = 0;
+		break;
+	case CONTROL_CHANNEL:
+		ret = channel_bctrl(bch, arg);
+		break;
+	default:
+		pr_info("%s: %s unknown prim(%x)\n",
+			card->name, __func__, cmd);
+	}
+	return ret;
+}
+
+static int
+w6692_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
+{
+	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
+	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
+	struct w6692_hw		*card = container_of(dch, struct w6692_hw, dch);
+	int			ret = -EINVAL;
+	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
+	u32			id;
+	u_long			flags;
+
+	switch (hh->prim) {
+	case PH_DATA_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		ret = dchannel_senddata(dch, skb);
+		if (ret > 0) { /* direct TX */
+			id = hh->id; /* skb can be freed */
+			W6692_fill_Dfifo(card);
+			ret = 0;
+			spin_unlock_irqrestore(&card->lock, flags);
+			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
+		} else
+			spin_unlock_irqrestore(&card->lock, flags);
+		return ret;
+	case PH_ACTIVATE_REQ:
+		ret = l1_event(dch->l1, hh->prim);
+		break;
+	case PH_DEACTIVATE_REQ:
+		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
+		ret = l1_event(dch->l1, hh->prim);
+		break;
+	}
+
+	if (!ret)
+		dev_kfree_skb(skb);
+	return ret;
+}
+
+static int
+w6692_l1callback(struct dchannel *dch, u32 cmd)
+{
+	struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
+	u_long flags;
+
+	pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state);
+	switch (cmd) {
+	case INFO3_P8:
+		spin_lock_irqsave(&card->lock, flags);
+		ph_command(card, W_L1CMD_AR8);
+		spin_unlock_irqrestore(&card->lock, flags);
+		break;
+	case INFO3_P10:
+		spin_lock_irqsave(&card->lock, flags);
+		ph_command(card, W_L1CMD_AR10);
+		spin_unlock_irqrestore(&card->lock, flags);
+		break;
+	case HW_RESET_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		if (card->state != W_L1IND_DRD)
+			ph_command(card, W_L1CMD_RST);
+		ph_command(card, W_L1CMD_ECK);
+		spin_unlock_irqrestore(&card->lock, flags);
+		break;
+	case HW_DEACT_REQ:
+		skb_queue_purge(&dch->squeue);
+		if (dch->tx_skb) {
+			dev_kfree_skb(dch->tx_skb);
+			dch->tx_skb = NULL;
+		}
+		dch->tx_idx = 0;
+		if (dch->rx_skb) {
+			dev_kfree_skb(dch->rx_skb);
+			dch->rx_skb = NULL;
+		}
+		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
+		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
+			del_timer(&dch->timer);
+		break;
+	case HW_POWERUP_REQ:
+		spin_lock_irqsave(&card->lock, flags);
+		ph_command(card, W_L1CMD_ECK);
+		spin_unlock_irqrestore(&card->lock, flags);
+		break;
+	case PH_ACTIVATE_IND:
+		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
+		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
+			GFP_ATOMIC);
+		break;
+	case PH_DEACTIVATE_IND:
+		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
+		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
+			GFP_ATOMIC);
+		break;
+	default:
+		pr_debug("%s: %s unknown command %x\n", card->name,
+			__func__, cmd);
+		return -1;
+	}
+	return 0;
+}
+
+static int
+open_dchannel(struct w6692_hw *card, struct channel_req *rq)
+{
+	pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__,
+		card->dch.dev.id, __builtin_return_address(1));
+	if (rq->protocol != ISDN_P_TE_S0)
+		return -EINVAL;
+	if (rq->adr.channel == 1)
+		/* E-Channel not supported */
+		return -EINVAL;
+	rq->ch = &card->dch.dev.D;
+	rq->ch->protocol = rq->protocol;
+	if (card->dch.state == 7)
+		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
+		    0, NULL, GFP_KERNEL);
+	return 0;
+}
+
+static int
+w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
+{
+	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
+	struct dchannel *dch = container_of(dev, struct dchannel, dev);
+	struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
+	struct channel_req *rq;
+	int err = 0;
+
+	pr_debug("%s: DCTRL: %x %p\n", card->name, cmd, arg);
+	switch (cmd) {
+	case OPEN_CHANNEL:
+		rq = arg;
+		if (rq->protocol == ISDN_P_TE_S0)
+			err = open_dchannel(card, rq);
+		else
+			err = open_bchannel(card, rq);
+		if (err)
+			break;
+		if (!try_module_get(THIS_MODULE))
+			pr_info("%s: cannot get module\n", card->name);
+		break;
+	case CLOSE_CHANNEL:
+		pr_debug("%s: dev(%d) close from %p\n", card->name,
+			dch->dev.id, __builtin_return_address(0));
+		module_put(THIS_MODULE);
+		break;
+	case CONTROL_CHANNEL:
+		err = channel_ctrl(card, arg);
+		break;
+	default:
+		pr_debug("%s: unknown DCTRL command %x\n", card->name, cmd);
+		return -EINVAL;
+	}
+	return err;
+}
+
+static int
+setup_w6692(struct w6692_hw *card)
+{
+	u32	val;
+
+	if (!request_region(card->addr, 256, card->name)) {
+		pr_info("%s: config port %x-%x already in use\n", card->name,
+		       card->addr, card->addr + 255);
+		return -EIO;
+	}
+	W6692Version(card);
+	card->bc[0].addr = card->addr;
+	card->bc[1].addr = card->addr + 0x40;
+	val = ReadW6692(card, W_ISTA);
+	if (debug & DEBUG_HW)
+		pr_notice("%s ISTA=%02x\n", card->name, val);
+	val = ReadW6692(card, W_IMASK);
+	if (debug & DEBUG_HW)
+		pr_notice("%s IMASK=%02x\n", card->name, val);
+	val = ReadW6692(card, W_D_EXIR);
+	if (debug & DEBUG_HW)
+		pr_notice("%s D_EXIR=%02x\n", card->name, val);
+	val = ReadW6692(card, W_D_EXIM);
+	if (debug & DEBUG_HW)
+		pr_notice("%s D_EXIM=%02x\n", card->name, val);
+	val = ReadW6692(card, W_D_RSTA);
+	if (debug & DEBUG_HW)
+		pr_notice("%s D_RSTA=%02x\n", card->name, val);
+	return 0;
+}
+
+static void
+release_card(struct w6692_hw *card)
+{
+	u_long	flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+	disable_hwirq(card);
+	w6692_mode(&card->bc[0], ISDN_P_NONE);
+	w6692_mode(&card->bc[1], ISDN_P_NONE);
+	if ((card->fmask & led) || card->subtype == W6692_USR) {
+		card->xdata |= 0x04;	/*  LED OFF */
+		WriteW6692(card, W_XDATA, card->xdata);
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+	free_irq(card->irq, card);
+	l1_event(card->dch.l1, CLOSE_CHANNEL);
+	mISDN_unregister_device(&card->dch.dev);
+	release_region(card->addr, 256);
+	mISDN_freebchannel(&card->bc[1].bch);
+	mISDN_freebchannel(&card->bc[0].bch);
+	mISDN_freedchannel(&card->dch);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	pci_disable_device(card->pdev);
+	pci_set_drvdata(card->pdev, NULL);
+	kfree(card);
+}
+
+static int
+setup_instance(struct w6692_hw *card)
+{
+	int		i, err;
+	u_long		flags;
+
+	snprintf(card->name, MISDN_MAX_IDLEN - 1, "w6692.%d", w6692_cnt + 1);
+	write_lock_irqsave(&card_lock, flags);
+	list_add_tail(&card->list, &Cards);
+	write_unlock_irqrestore(&card_lock, flags);
+	card->fmask = (1 << w6692_cnt);
+	_set_debug(card);
+	spin_lock_init(&card->lock);
+	mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, W6692_ph_bh);
+	card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
+	card->dch.dev.D.send = w6692_l2l1D;
+	card->dch.dev.D.ctrl = w6692_dctrl;
+	card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
+		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
+	card->dch.hw = card;
+	card->dch.dev.nrbchan = 2;
+	for (i = 0; i < 2; i++) {
+		mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM);
+		card->bc[i].bch.hw = card;
+		card->bc[i].bch.nr = i + 1;
+		card->bc[i].bch.ch.nr = i + 1;
+		card->bc[i].bch.ch.send = w6692_l2l1B;
+		card->bc[i].bch.ch.ctrl = w6692_bctrl;
+		set_channelmap(i + 1, card->dch.dev.channelmap);
+		list_add(&card->bc[i].bch.ch.list, &card->dch.dev.bchannels);
+	}
+	err = setup_w6692(card);
+	if (err)
+		goto error_setup;
+	err = mISDN_register_device(&card->dch.dev, &card->pdev->dev,
+		card->name);
+	if (err)
+		goto error_reg;
+	err = init_card(card);
+	if (err)
+		goto error_init;
+	err = create_l1(&card->dch, w6692_l1callback);
+	if (!err) {
+		w6692_cnt++;
+		pr_notice("W6692 %d cards installed\n", w6692_cnt);
+		return 0;
+	}
+
+	free_irq(card->irq, card);
+error_init:
+	mISDN_unregister_device(&card->dch.dev);
+error_reg:
+	release_region(card->addr, 256);
+error_setup:
+	mISDN_freebchannel(&card->bc[1].bch);
+	mISDN_freebchannel(&card->bc[0].bch);
+	mISDN_freedchannel(&card->dch);
+	write_lock_irqsave(&card_lock, flags);
+	list_del(&card->list);
+	write_unlock_irqrestore(&card_lock, flags);
+	kfree(card);
+	return err;
+}
+
+static int __devinit
+w6692_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int		err = -ENOMEM;
+	struct w6692_hw	*card;
+	struct w6692map	*m = (struct w6692map *)ent->driver_data;
+
+	card = kzalloc(sizeof(struct w6692_hw), GFP_KERNEL);
+	if (!card) {
+		pr_info("No kmem for w6692 card\n");
+		return err;
+	}
+	card->pdev = pdev;
+	card->subtype = m->subtype;
+	err = pci_enable_device(pdev);
+	if (err) {
+		kfree(card);
+		return err;
+	}
+
+	printk(KERN_INFO "mISDN_w6692: found adapter %s at %s\n",
+	       m->name, pci_name(pdev));
+
+	card->addr = pci_resource_start(pdev, 1);
+	card->irq = pdev->irq;
+	pci_set_drvdata(pdev, card);
+	err = setup_instance(card);
+	if (err)
+		pci_set_drvdata(pdev, NULL);
+	return err;
+}
+
+static void __devexit
+w6692_remove_pci(struct pci_dev *pdev)
+{
+	struct w6692_hw	*card = pci_get_drvdata(pdev);
+
+	if (card)
+		release_card(card);
+	else
+		if (debug)
+			pr_notice("%s: drvdata allready removed\n", __func__);
+}
+
+static struct pci_device_id w6692_ids[] = {
+	{ PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[0]},
+	{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
+	  PCI_VENDOR_ID_USR, PCI_DEVICE_ID_USR_6692, 0, 0,
+	  (ulong)&w6692_map[2]},
+	{ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[1]},
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, w6692_ids);
+
+static struct pci_driver w6692_driver = {
+	.name =  "w6692",
+	.probe = w6692_probe,
+	.remove = __devexit_p(w6692_remove_pci),
+	.id_table = w6692_ids,
+};
+
+static int __init w6692_init(void)
+{
+	int err;
+
+	pr_notice("Winbond W6692 PCI driver Rev. %s\n", W6692_REV);
+
+	err = pci_register_driver(&w6692_driver);
+	return err;
+}
+
+static void __exit w6692_cleanup(void)
+{
+	pci_unregister_driver(&w6692_driver);
+}
+
+module_init(w6692_init);
+module_exit(w6692_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/w6692.h b/drivers/isdn/hardware/mISDN/w6692.h
new file mode 100644
index 0000000..f956977
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/w6692.h
@@ -0,0 +1,190 @@
+/*
+ * Winbond W6692 specific defines
+ *
+ * Author       Karsten Keil <keil@isdn4linux.de>
+ *		based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
+ *
+ * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/* Specifications of W6692 registers */
+
+#define W_D_RFIFO	0x00	/* R */
+#define W_D_XFIFO	0x04	/* W */
+#define W_D_CMDR	0x08	/* W */
+#define W_D_MODE	0x0c	/* R/W */
+#define W_D_TIMR	0x10	/* R/W */
+#define W_ISTA		0x14	/* R_clr */
+#define W_IMASK		0x18	/* R/W */
+#define W_D_EXIR	0x1c	/* R_clr */
+#define W_D_EXIM	0x20	/* R/W */
+#define W_D_STAR	0x24	/* R */
+#define W_D_RSTA	0x28	/* R */
+#define W_D_SAM		0x2c	/* R/W */
+#define W_D_SAP1	0x30	/* R/W */
+#define W_D_SAP2	0x34	/* R/W */
+#define W_D_TAM		0x38	/* R/W */
+#define W_D_TEI1	0x3c	/* R/W */
+#define W_D_TEI2	0x40	/* R/W */
+#define W_D_RBCH	0x44	/* R */
+#define W_D_RBCL	0x48	/* R */
+#define W_TIMR2		0x4c	/* W */
+#define W_L1_RC		0x50	/* R/W */
+#define W_D_CTL		0x54	/* R/W */
+#define W_CIR		0x58	/* R */
+#define W_CIX		0x5c	/* W */
+#define W_SQR		0x60	/* R */
+#define W_SQX		0x64	/* W */
+#define W_PCTL		0x68	/* R/W */
+#define W_MOR		0x6c	/* R */
+#define W_MOX		0x70	/* R/W */
+#define W_MOSR		0x74	/* R_clr */
+#define W_MOCR		0x78	/* R/W */
+#define W_GCR		0x7c	/* R/W */
+
+#define	W_B_RFIFO	0x80	/* R */
+#define	W_B_XFIFO	0x84	/* W */
+#define	W_B_CMDR	0x88	/* W */
+#define	W_B_MODE	0x8c	/* R/W */
+#define	W_B_EXIR	0x90	/* R_clr */
+#define	W_B_EXIM	0x94	/* R/W */
+#define	W_B_STAR	0x98	/* R */
+#define	W_B_ADM1	0x9c	/* R/W */
+#define	W_B_ADM2	0xa0	/* R/W */
+#define	W_B_ADR1	0xa4	/* R/W */
+#define	W_B_ADR2	0xa8	/* R/W */
+#define	W_B_RBCL	0xac	/* R */
+#define	W_B_RBCH	0xb0	/* R */
+
+#define W_XADDR		0xf4	/* R/W */
+#define W_XDATA		0xf8	/* R/W */
+#define W_EPCTL		0xfc	/* W */
+
+/* W6692 register bits */
+
+#define	W_D_CMDR_XRST	0x01
+#define	W_D_CMDR_XME	0x02
+#define	W_D_CMDR_XMS	0x08
+#define	W_D_CMDR_STT	0x10
+#define	W_D_CMDR_RRST	0x40
+#define	W_D_CMDR_RACK	0x80
+
+#define	W_D_MODE_RLP	0x01
+#define	W_D_MODE_DLP	0x02
+#define	W_D_MODE_MFD	0x04
+#define	W_D_MODE_TEE	0x08
+#define	W_D_MODE_TMS	0x10
+#define	W_D_MODE_RACT	0x40
+#define	W_D_MODE_MMS	0x80
+
+#define W_INT_B2_EXI	0x01
+#define W_INT_B1_EXI	0x02
+#define W_INT_D_EXI	0x04
+#define W_INT_XINT0	0x08
+#define W_INT_XINT1	0x10
+#define W_INT_D_XFR	0x20
+#define W_INT_D_RME	0x40
+#define W_INT_D_RMR	0x80
+
+#define W_D_EXI_WEXP	0x01
+#define W_D_EXI_TEXP	0x02
+#define W_D_EXI_ISC	0x04
+#define W_D_EXI_MOC	0x08
+#define W_D_EXI_TIN2	0x10
+#define W_D_EXI_XCOL	0x20
+#define W_D_EXI_XDUN	0x40
+#define W_D_EXI_RDOV	0x80
+
+#define	W_D_STAR_DRDY	0x10
+#define	W_D_STAR_XBZ	0x20
+#define	W_D_STAR_XDOW	0x80
+
+#define W_D_RSTA_RMB	0x10
+#define W_D_RSTA_CRCE	0x20
+#define W_D_RSTA_RDOV	0x40
+
+#define W_D_CTL_SRST	0x20
+
+#define W_CIR_SCC	0x80
+#define W_CIR_ICC	0x40
+#define W_CIR_COD_MASK	0x0f
+
+#define W_PCTL_PCX	0x01
+#define W_PCTL_XMODE	0x02
+#define W_PCTL_OE0	0x04
+#define W_PCTL_OE1	0x08
+#define W_PCTL_OE2	0x10
+#define W_PCTL_OE3	0x20
+#define W_PCTL_OE4	0x40
+#define W_PCTL_OE5	0x80
+
+#define	W_B_CMDR_XRST	0x01
+#define	W_B_CMDR_XME	0x02
+#define	W_B_CMDR_XMS	0x04
+#define	W_B_CMDR_RACT	0x20
+#define	W_B_CMDR_RRST	0x40
+#define	W_B_CMDR_RACK	0x80
+
+#define	W_B_MODE_FTS0	0x01
+#define	W_B_MODE_FTS1	0x02
+#define	W_B_MODE_SW56	0x04
+#define	W_B_MODE_BSW0	0x08
+#define	W_B_MODE_BSW1	0x10
+#define	W_B_MODE_EPCM	0x20
+#define	W_B_MODE_ITF	0x40
+#define	W_B_MODE_MMS	0x80
+
+#define	W_B_EXI_XDUN	0x01
+#define	W_B_EXI_XFR	0x02
+#define	W_B_EXI_RDOV	0x10
+#define	W_B_EXI_RME	0x20
+#define	W_B_EXI_RMR	0x40
+
+#define	W_B_STAR_XBZ	0x01
+#define	W_B_STAR_XDOW	0x04
+#define	W_B_STAR_RMB	0x10
+#define	W_B_STAR_CRCE	0x20
+#define	W_B_STAR_RDOV	0x40
+
+#define	W_B_RBCH_LOV	0x20
+
+/* W6692 Layer1 commands */
+
+#define	W_L1CMD_ECK	0x00
+#define W_L1CMD_RST	0x01
+#define W_L1CMD_SCP	0x04
+#define W_L1CMD_SSP	0x02
+#define W_L1CMD_AR8	0x08
+#define W_L1CMD_AR10	0x09
+#define W_L1CMD_EAL	0x0a
+#define W_L1CMD_DRC	0x0f
+
+/* W6692 Layer1 indications */
+
+#define W_L1IND_CE	0x07
+#define W_L1IND_DRD	0x00
+#define W_L1IND_LD	0x04
+#define W_L1IND_ARD	0x08
+#define W_L1IND_TI	0x0a
+#define W_L1IND_ATI	0x0b
+#define W_L1IND_AI8	0x0c
+#define W_L1IND_AI10	0x0d
+#define W_L1IND_CD	0x0f
+
+/* FIFO thresholds */
+#define W_D_FIFO_THRESH	64
+#define W_B_FIFO_THRESH	64
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 7832d8b..3464ebc 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -391,6 +391,7 @@ comment "HiSax sub driver modules"
 config HISAX_ST5481
 	tristate "ST5481 USB ISDN modem (EXPERIMENTAL)"
 	depends on USB && EXPERIMENTAL
+	select ISDN_HDLC
 	select CRC_CCITT
 	select BITREVERSE
 	help
@@ -418,11 +419,6 @@ config HISAX_FRITZ_PCIPNP
 	  (the latter also needs you to select "ISA Plug and Play support"
 	  from the menu "Plug and Play configuration")
 
-config HISAX_HDLC
-	bool
-	depends on HISAX_ST5481
-	default y
-
 config HISAX_AVM_A1_PCMCIA
 	bool
 	depends on HISAX_AVM_A1_CS
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
index c7a3794..ab638b0 100644
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -16,10 +16,6 @@ obj-$(CONFIG_HISAX_HFCUSB)		+= hfc_usb.o
 obj-$(CONFIG_HISAX_HFC4S8S)		+= hfc4s8s_l1.o
 obj-$(CONFIG_HISAX_FRITZ_PCIPNP)        += hisax_isac.o hisax_fcpcipnp.o
 
-ifdef CONFIG_HISAX_HDLC
-obj-$(CONFIG_ISDN_DRV_HISAX)		+= isdnhdlc.o
-endif
-
 # Multipart objects.
 
 hisax_st5481-y 				:= st5481_init.o st5481_usb.o st5481_d.o \
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index 341faf5..bf526a7 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -238,8 +238,6 @@ Amd7930_bh(struct work_struct *work)
 		container_of(work, struct IsdnCardState, tqueue);
         struct PStack *stptr;
 
-	if (!cs)
-		return;
 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
                 if (cs->debug)
 			debugl1(cs, "Amd7930: bh, D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 025a20d..475b1a0 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -833,8 +833,6 @@ static struct FsmNode fnlist[] __initdata =
 };
 /* *INDENT-ON* */
 
-#define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
-
 int __init
 CallcNew(void)
 {
@@ -842,7 +840,7 @@ CallcNew(void)
 	callcfsm.event_count = EVENT_COUNT;
 	callcfsm.strEvent = strEvent;
 	callcfsm.strState = strState;
-	return FsmNew(&callcfsm, fnlist, FNCOUNT);
+	return FsmNew(&callcfsm, fnlist, ARRAY_SIZE(fnlist));
 }
 
 void
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 3d337d9..d110a77 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1506,8 +1506,6 @@ hfcpci_bh(struct work_struct *work)
 	u_long	flags;
 //      struct PStack *stptr;
 
-	if (!cs)
-		return;
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		if (!cs->hw.hfcpci.nt_mode)
 			switch (cs->dc.hfcpci.ph_state) {
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index d92e8d6..419f87c 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -1255,8 +1255,6 @@ hfcsx_bh(struct work_struct *work)
 		container_of(work, struct IsdnCardState, tqueue);
 	u_long flags;
 
-	if (!cs)
-		return;
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		if (!cs->hw.hfcsx.nt_mode)
 			switch (cs->dc.hfcsx.ph_state) {
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index 682cac3..9aba646 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -83,8 +83,6 @@ icc_bh(struct work_struct *work)
 		container_of(work, struct IsdnCardState, tqueue);
 	struct PStack *stptr;
 	
-	if (!cs)
-		return;
 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
 		if (cs->debug)
 			debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 07b1673..a19354d 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -86,8 +86,6 @@ isac_bh(struct work_struct *work)
 		container_of(work, struct IsdnCardState, tqueue);
 	struct PStack *stptr;
 	
-	if (!cs)
-		return;
 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
 		if (cs->debug)
 			debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/isdnhdlc.c b/drivers/isdn/hisax/isdnhdlc.c
deleted file mode 100644
index c69a77a..0000000
--- a/drivers/isdn/hisax/isdnhdlc.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
- *
- *Copyright (C) 2002	Wolfgang MÃ¼es      <wolfgang@iksw-muees.de>
- *		2001 	Frode Isaksen      <fisaksen@bewan.com>
- *              2001 	Kai Germaschewski  <kai.germaschewski@gmx.de>
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU 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.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/crc-ccitt.h>
-#include "isdnhdlc.h"
-
-/*-------------------------------------------------------------------*/
-
-MODULE_AUTHOR("Wolfgang MÃ¼es <wolfgang@iksw-muees.de>, "
-	      "Frode Isaksen <fisaksen@bewan.com>, "
-	      "Kai Germaschewski <kai.germaschewski@gmx.de>");
-MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
-MODULE_LICENSE("GPL");
-
-/*-------------------------------------------------------------------*/
-
-enum {
-	HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
-	HDLC_GET_DATA,HDLC_FAST_FLAG
-};
-
-enum {
-	HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
-	HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
-	HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
-	HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
-};
-
-void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
-{
-   	hdlc->bit_shift = 0;
-	hdlc->hdlc_bits1 = 0;
-	hdlc->data_bits = 0;
-	hdlc->ffbit_shift = 0;
-	hdlc->data_received = 0;
-	hdlc->state = HDLC_GET_DATA;
-	hdlc->do_adapt56 = do_adapt56;
-	hdlc->dchannel = 0;
-	hdlc->crc = 0;
-	hdlc->cbin = 0;
-	hdlc->shift_reg = 0;
-	hdlc->ffvalue = 0;
-	hdlc->dstpos = 0;
-}
-
-void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56)
-{
-   	hdlc->bit_shift = 0;
-	hdlc->hdlc_bits1 = 0;
-	hdlc->data_bits = 0;
-	hdlc->ffbit_shift = 0;
-	hdlc->data_received = 0;
-	hdlc->do_closing = 0;
-	hdlc->ffvalue = 0;
-	if (is_d_channel) {
-		hdlc->dchannel = 1;
-		hdlc->state = HDLC_SEND_FIRST_FLAG;
-	} else {
-		hdlc->dchannel = 0;
-		hdlc->state = HDLC_SEND_FAST_FLAG;
-		hdlc->ffvalue = 0x7e;
-	}
-	hdlc->cbin = 0x7e;
-	hdlc->bit_shift = 0;
-	if(do_adapt56){
-		hdlc->do_adapt56 = 1;
-		hdlc->data_bits = 0;
-		hdlc->state = HDLC_SENDFLAG_B0;
-	} else {
-		hdlc->do_adapt56 = 0;
-		hdlc->data_bits = 8;
-	}
-	hdlc->shift_reg = 0;
-}
-
-/*
-  isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
-
-  The source buffer is scanned for valid HDLC frames looking for
-  flags (01111110) to indicate the start of a frame. If the start of
-  the frame is found, the bit stuffing is removed (0 after 5 1's).
-  When a new flag is found, the complete frame has been received
-  and the CRC is checked.
-  If a valid frame is found, the function returns the frame length
-  excluding the CRC with the bit HDLC_END_OF_FRAME set.
-  If the beginning of a valid frame is found, the function returns
-  the length.
-  If a framing error is found (too many 1s and not a flag) the function
-  returns the length with the bit HDLC_FRAMING_ERROR set.
-  If a CRC error is found the function returns the length with the
-  bit HDLC_CRC_ERROR set.
-  If the frame length exceeds the destination buffer size, the function
-  returns the length with the bit HDLC_LENGTH_ERROR set.
-
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (decoded) from the source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of decoded bytes in the destination buffer and status
-  flag.
- */
-int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
-		     int slen, int *count, unsigned char *dst, int dsize)
-{
-	int status=0;
-
-	static const unsigned char fast_flag[]={
-		0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
-	};
-
-	static const unsigned char fast_flag_value[]={
-		0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
-	};
-
-	static const unsigned char fast_abort[]={
-		0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
-	};
-
-	*count = slen;
-
-	while(slen > 0){
-		if(hdlc->bit_shift==0){
-			hdlc->cbin = *src++;
-			slen--;
-			hdlc->bit_shift = 8;
-			if(hdlc->do_adapt56){
-				hdlc->bit_shift --;
-			}
-		}
-
-		switch(hdlc->state){
-		case STOPPED:
-			return 0;
-		case HDLC_FAST_IDLE:
-			if(hdlc->cbin == 0xff){
-				hdlc->bit_shift = 0;
-				break;
-			}
-			hdlc->state = HDLC_GET_FLAG_B0;
-			hdlc->hdlc_bits1 = 0;
-			hdlc->bit_shift = 8;
-			break;
-		case HDLC_GET_FLAG_B0:
-			if(!(hdlc->cbin & 0x80)) {
-				hdlc->state = HDLC_GETFLAG_B1A6;
-				hdlc->hdlc_bits1 = 0;
-			} else {
-				if(!hdlc->do_adapt56){
-					if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
-						hdlc->state = HDLC_FAST_IDLE;
-				}
-			}
-			hdlc->cbin<<=1;
-			hdlc->bit_shift --;
-			break;
-		case HDLC_GETFLAG_B1A6:
-			if(hdlc->cbin & 0x80){
-				hdlc->hdlc_bits1++;
-				if(hdlc->hdlc_bits1==6){
-					hdlc->state = HDLC_GETFLAG_B7;
-				}
-			} else {
-				hdlc->hdlc_bits1 = 0;
-			}
-			hdlc->cbin<<=1;
-			hdlc->bit_shift --;
-			break;
-		case HDLC_GETFLAG_B7:
-			if(hdlc->cbin & 0x80) {
-				hdlc->state = HDLC_GET_FLAG_B0;
-			} else {
-				hdlc->state = HDLC_GET_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->shift_reg = 0;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_bits = 0;
-				hdlc->data_received = 0;
-			}
-			hdlc->cbin<<=1;
-			hdlc->bit_shift --;
-			break;
-		case HDLC_GET_DATA:
-			if(hdlc->cbin & 0x80){
-				hdlc->hdlc_bits1++;
-				switch(hdlc->hdlc_bits1){
-				case 6:
-					break;
-				case 7:
-					if(hdlc->data_received) {
-						// bad frame
-						status = -HDLC_FRAMING_ERROR;
-					}
-					if(!hdlc->do_adapt56){
-						if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
-							hdlc->state = HDLC_FAST_IDLE;
-							hdlc->bit_shift=1;
-							break;
-						}
-					} else {
-						hdlc->state = HDLC_GET_FLAG_B0;
-					}
-					break;
-				default:
-					hdlc->shift_reg>>=1;
-					hdlc->shift_reg |= 0x80;
-					hdlc->data_bits++;
-					break;
-				}
-			} else {
-				switch(hdlc->hdlc_bits1){
-				case 5:
-					break;
-				case 6:
-					if(hdlc->data_received){
-						if (hdlc->dstpos < 2) {
-							status = -HDLC_FRAMING_ERROR;
-						} else if (hdlc->crc != 0xf0b8){
-							// crc error
-							status = -HDLC_CRC_ERROR;
-						} else {
-							// remove CRC
-							hdlc->dstpos -= 2;
-							// good frame
-							status = hdlc->dstpos;
-						}
-					}
-					hdlc->crc = 0xffff;
-					hdlc->shift_reg = 0;
-					hdlc->data_bits = 0;
-					if(!hdlc->do_adapt56){
-						if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
-							hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
-							hdlc->state = HDLC_FAST_FLAG;
-							hdlc->ffbit_shift = hdlc->bit_shift;
-							hdlc->bit_shift = 1;
-						} else {
-							hdlc->state = HDLC_GET_DATA;
-							hdlc->data_received = 0;
-						}
-					} else {
-						hdlc->state = HDLC_GET_DATA;
-						hdlc->data_received = 0;
-					}
-					break;
-				default:
-					hdlc->shift_reg>>=1;
-					hdlc->data_bits++;
-					break;
-				}
-				hdlc->hdlc_bits1 = 0;
-			}
-			if (status) {
-				hdlc->dstpos = 0;
-				*count -= slen;
-				hdlc->cbin <<= 1;
-				hdlc->bit_shift--;
-				return status;
-			}
-			if(hdlc->data_bits==8){
-				hdlc->data_bits = 0;
-				hdlc->data_received = 1;
-				hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
-
-				// good byte received
-				if (hdlc->dstpos < dsize) {
-					dst[hdlc->dstpos++] = hdlc->shift_reg;
-				} else {
-					// frame too long
-					status = -HDLC_LENGTH_ERROR;
-					hdlc->dstpos = 0;
-				}
-			}
-			hdlc->cbin <<= 1;
-			hdlc->bit_shift--;
-			break;
-		case HDLC_FAST_FLAG:
-			if(hdlc->cbin==hdlc->ffvalue){
-				hdlc->bit_shift = 0;
-				break;
-			} else {
-				if(hdlc->cbin == 0xff){
-					hdlc->state = HDLC_FAST_IDLE;
-					hdlc->bit_shift=0;
-				} else if(hdlc->ffbit_shift==8){
-					hdlc->state = HDLC_GETFLAG_B7;
-					break;
-				} else {
-					hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
-					hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
-					if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
-					hdlc->data_bits = hdlc->ffbit_shift-1;
-					hdlc->state = HDLC_GET_DATA;
-					hdlc->data_received = 0;
-				}
-			}
-			break;
-		default:
-			break;
-		}
-	}
-	*count -= slen;
-	return 0;
-}
-
-/*
-  isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
-
-  The bit stream starts with a beginning flag (01111110). After
-  that each byte is added to the bit stream with bit stuffing added
-  (0 after 5 1's).
-  When the last byte has been removed from the source buffer, the
-  CRC (2 bytes is added) and the frame terminates with the ending flag.
-  For the dchannel, the idle character (all 1's) is also added at the end.
-  If this function is called with empty source buffer (slen=0), flags or
-  idle character will be generated.
-
-  src - source buffer
-  slen - source buffer length
-  count - number of bytes removed (encoded) from source buffer
-  dst _ destination buffer
-  dsize - destination buffer size
-  returns - number of encoded bytes in the destination buffer
-*/
-int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
-		unsigned short slen, int *count,
-		unsigned char *dst, int dsize)
-{
-	static const unsigned char xfast_flag_value[] = {
-		0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
-	};
-
-	int len = 0;
-
-	*count = slen;
-
-	while (dsize > 0) {
-		if(hdlc->bit_shift==0){
-			if(slen && !hdlc->do_closing){
-				hdlc->shift_reg = *src++;
-				slen--;
-				if (slen == 0)
-					hdlc->do_closing = 1;  /* closing sequence, CRC + flag(s) */
-				hdlc->bit_shift = 8;
-			} else {
-				if(hdlc->state == HDLC_SEND_DATA){
-					if(hdlc->data_received){
-						hdlc->state = HDLC_SEND_CRC1;
-						hdlc->crc ^= 0xffff;
-						hdlc->bit_shift = 8;
-						hdlc->shift_reg = hdlc->crc & 0xff;
-					} else if(!hdlc->do_adapt56){
-						hdlc->state = HDLC_SEND_FAST_FLAG;
-					} else {
-						hdlc->state = HDLC_SENDFLAG_B0;
-					}
-				}
-
-			}
-		}
-
-		switch(hdlc->state){
-		case STOPPED:
-			while (dsize--)
-				*dst++ = 0xff;
-
-			return dsize;
-		case HDLC_SEND_FAST_FLAG:
-			hdlc->do_closing = 0;
-			if(slen == 0){
-				*dst++ = hdlc->ffvalue;
-				len++;
-				dsize--;
-				break;
-			}
-			if(hdlc->bit_shift==8){
-				hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_received = 1;
-			}
-			break;
-		case HDLC_SENDFLAG_B0:
-			hdlc->do_closing = 0;
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			hdlc->hdlc_bits1 = 0;
-			hdlc->state = HDLC_SENDFLAG_B1A6;
-			break;
-		case HDLC_SENDFLAG_B1A6:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			hdlc->cbin++;
-			if(++hdlc->hdlc_bits1 == 6)
-				hdlc->state = HDLC_SENDFLAG_B7;
-			break;
-		case HDLC_SENDFLAG_B7:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(slen == 0){
-				hdlc->state = HDLC_SENDFLAG_B0;
-				break;
-			}
-			if(hdlc->bit_shift==8){
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				hdlc->data_received = 1;
-			}
-			break;
-		case HDLC_SEND_FIRST_FLAG:
-			hdlc->data_received = 1;
-			if(hdlc->data_bits==8){
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->shift_reg & 0x01)
-				hdlc->cbin++;
-			hdlc->shift_reg >>= 1;
-			hdlc->bit_shift--;
-			if(hdlc->bit_shift==0){
-				hdlc->state = HDLC_SEND_DATA;
-				hdlc->crc = 0xffff;
-				hdlc->hdlc_bits1 = 0;
-			}
-			break;
-		case HDLC_SEND_DATA:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->bit_shift==8){
-				hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			break;
-		case HDLC_SEND_CRC1:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			if(hdlc->bit_shift==0){
-				hdlc->shift_reg = (hdlc->crc >> 8);
-				hdlc->state = HDLC_SEND_CRC2;
-				hdlc->bit_shift = 8;
-			}
-			break;
-		case HDLC_SEND_CRC2:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->hdlc_bits1++;
-				hdlc->cbin++;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			} else {
-				hdlc->hdlc_bits1 = 0;
-				hdlc->shift_reg >>= 1;
-				hdlc->bit_shift--;
-			}
-			if(hdlc->bit_shift==0){
-				hdlc->shift_reg = 0x7e;
-				hdlc->state = HDLC_SEND_CLOSING_FLAG;
-				hdlc->bit_shift = 8;
-			}
-			break;
-		case HDLC_SEND_CLOSING_FLAG:
-			hdlc->cbin <<= 1;
-			hdlc->data_bits++;
-			if(hdlc->hdlc_bits1 == 5){
-				hdlc->hdlc_bits1 = 0;
-				break;
-			}
-			if(hdlc->shift_reg & 0x01){
-				hdlc->cbin++;
-			}
-			hdlc->shift_reg >>= 1;
-			hdlc->bit_shift--;
-			if(hdlc->bit_shift==0){
-				hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
-				if(hdlc->dchannel){
-					hdlc->ffvalue = 0x7e;
-					hdlc->state = HDLC_SEND_IDLE1;
-					hdlc->bit_shift = 8-hdlc->data_bits;
-					if(hdlc->bit_shift==0)
-						hdlc->state = HDLC_SEND_FAST_IDLE;
-				} else {
-					if(!hdlc->do_adapt56){
-						hdlc->state = HDLC_SEND_FAST_FLAG;
-						hdlc->data_received = 0;
-					} else {
-						hdlc->state = HDLC_SENDFLAG_B0;
-						hdlc->data_received = 0;
-					}
-					// Finished with this frame, send flags
-					if (dsize > 1) dsize = 1;
-				}
-			}
-			break;
-		case HDLC_SEND_IDLE1:
-			hdlc->do_closing = 0;
-			hdlc->cbin <<= 1;
-			hdlc->cbin++;
-			hdlc->data_bits++;
-			hdlc->bit_shift--;
-			if(hdlc->bit_shift==0){
-				hdlc->state = HDLC_SEND_FAST_IDLE;
-				hdlc->bit_shift = 0;
-			}
-			break;
-		case HDLC_SEND_FAST_IDLE:
-			hdlc->do_closing = 0;
-			hdlc->cbin = 0xff;
-			hdlc->data_bits = 8;
-			if(hdlc->bit_shift == 8){
-				hdlc->cbin = 0x7e;
-				hdlc->state = HDLC_SEND_FIRST_FLAG;
-			} else {
-				*dst++ = hdlc->cbin;
-				hdlc->bit_shift = hdlc->data_bits = 0;
-				len++;
-				dsize = 0;
-			}
-			break;
-		default:
-			break;
-		}
-		if(hdlc->do_adapt56){
-			if(hdlc->data_bits==7){
-				hdlc->cbin <<= 1;
-				hdlc->cbin++;
-				hdlc->data_bits++;
-			}
-		}
-		if(hdlc->data_bits==8){
-			*dst++ = hdlc->cbin;
-			hdlc->data_bits = 0;
-			len++;
-			dsize--;
-		}
-	}
-	*count -= slen;
-
-	return len;
-}
-
-EXPORT_SYMBOL(isdnhdlc_rcv_init);
-EXPORT_SYMBOL(isdnhdlc_decode);
-EXPORT_SYMBOL(isdnhdlc_out_init);
-EXPORT_SYMBOL(isdnhdlc_encode);
diff --git a/drivers/isdn/hisax/isdnhdlc.h b/drivers/isdn/hisax/isdnhdlc.h
deleted file mode 100644
index cf0a95a..0000000
--- a/drivers/isdn/hisax/isdnhdlc.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * isdnhdlc.h  --  General purpose ISDN HDLC decoder.
- *
- * Implementation of a HDLC decoder/encoder in software.
- * Neccessary because some ISDN devices don't have HDLC
- * controllers. Also included: a bit reversal table.
- *
- *Copyright (C) 2002    Wolfgang MÃ¼es      <wolfgang@iksw-muees.de>
- *		2001 	Frode Isaksen      <fisaksen@bewan.com>
- *              2001 	Kai Germaschewski  <kai.germaschewski@gmx.de>
- *
- *      This program is free software; you can redistribute it and/or modify
- *      it under the terms of the GNU General Public License as published by
- *      the Free Software Foundation; either version 2 of the License, or
- *      (at your option) any later version.
- *
- *      This program is distributed in the hope that it will be useful,
- *      but WITHOUT ANY WARRANTY; without even the implied warranty of
- *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *      GNU 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 __ISDNHDLC_H__
-#define __ISDNHDLC_H__
-
-struct isdnhdlc_vars {
-	int bit_shift;
-	int hdlc_bits1;
-	int data_bits;
-	int ffbit_shift; 	// encoding only
-	int state;
-	int dstpos;
-
-	unsigned short crc;
-
-	unsigned char cbin;
-	unsigned char shift_reg;
-	unsigned char ffvalue;
-
-	unsigned int data_received:1; 	// set if transferring data
-	unsigned int dchannel:1; 	// set if D channel (send idle instead of flags)
-	unsigned int do_adapt56:1; 	// set if 56K adaptation
-	unsigned int do_closing:1; 	// set if in closing phase (need to send CRC + flag
-};
-
-
-/*
-  The return value from isdnhdlc_decode is
-  the frame length, 0 if no complete frame was decoded,
-  or a negative error number
-*/
-#define HDLC_FRAMING_ERROR     1
-#define HDLC_CRC_ERROR         2
-#define HDLC_LENGTH_ERROR      3
-
-extern void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56);
-
-extern int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src, int slen,int *count,
-	                    unsigned char *dst, int dsize);
-
-extern void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc,int is_d_channel,int do_adapt56);
-
-extern int isdnhdlc_encode (struct isdnhdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count,
-	                    unsigned char *dst,int dsize);
-
-#endif /* __ISDNHDLC_H__ */
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index 317f16f..9ce6abe 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -647,8 +647,6 @@ static struct FsmNode L1SFnList[] __initdata =
 	{ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
 };
 
-#define L1S_FN_COUNT (sizeof(L1SFnList)/sizeof(struct FsmNode))
-
 #ifdef HISAX_UINTERFACE
 static void
 l1_deact_req_u(struct FsmInst *fi, int event, void *arg)
@@ -706,8 +704,6 @@ static struct FsmNode L1UFnList[] __initdata =
 	{ST_L1_RESET, EV_TIMER_DEACT, l1_timer_deact},
 };
 
-#define L1U_FN_COUNT (sizeof(L1UFnList)/sizeof(struct FsmNode))
-
 #endif
 
 static void
@@ -754,8 +750,6 @@ static struct FsmNode L1BFnList[] __initdata =
 	{ST_L1_WAIT_DEACT, EV_TIMER_DEACT, l1b_timer_deact},
 };
 
-#define L1B_FN_COUNT (sizeof(L1BFnList)/sizeof(struct FsmNode))
-
 int __init 
 Isdnl1New(void)
 {
@@ -765,7 +759,7 @@ Isdnl1New(void)
 	l1fsm_s.event_count = L1_EVENT_COUNT;
 	l1fsm_s.strEvent = strL1Event;
 	l1fsm_s.strState = strL1SState;
-	retval = FsmNew(&l1fsm_s, L1SFnList, L1S_FN_COUNT);
+	retval = FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
 	if (retval)
 		return retval;
 
@@ -773,7 +767,7 @@ Isdnl1New(void)
 	l1fsm_b.event_count = L1_EVENT_COUNT;
 	l1fsm_b.strEvent = strL1Event;
 	l1fsm_b.strState = strL1BState;
-	retval = FsmNew(&l1fsm_b, L1BFnList, L1B_FN_COUNT);
+	retval = FsmNew(&l1fsm_b, L1BFnList, ARRAY_SIZE(L1BFnList));
 	if (retval) {
 		FsmFree(&l1fsm_s);
 		return retval;
@@ -783,7 +777,7 @@ Isdnl1New(void)
 	l1fsm_u.event_count = L1_EVENT_COUNT;
 	l1fsm_u.strEvent = strL1Event;
 	l1fsm_u.strState = strL1UState;
-	retval = FsmNew(&l1fsm_u, L1UFnList, L1U_FN_COUNT);
+	retval = FsmNew(&l1fsm_u, L1UFnList, ARRAY_SIZE(L1UFnList));
 	if (retval) {
 		FsmFree(&l1fsm_s);
 		FsmFree(&l1fsm_b);
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index 3446f24..7b9496a 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -1623,8 +1623,6 @@ static struct FsmNode L2FnList[] __initdata =
 	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
 };
 
-#define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
-
 static void
 isdnl2_l1l2(struct PStack *st, int pr, void *arg)
 {
@@ -1836,7 +1834,7 @@ Isdnl2New(void)
 	l2fsm.event_count = L2_EVENT_COUNT;
 	l2fsm.strEvent = strL2Event;
 	l2fsm.strState = strL2State;
-	return FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);
+	return FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
 }
 
 void
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index 935f233..0676602 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -543,8 +543,6 @@ static struct FsmNode L3FnList[] __initdata =
 };
 /* *INDENT-ON* */
 
-#define L3_FN_COUNT (sizeof(L3FnList)/sizeof(struct FsmNode))
-
 void
 l3_msg(struct PStack *st, int pr, void *arg)
 {
@@ -587,7 +585,7 @@ Isdnl3New(void)
 	l3fsm.event_count = L3_EVENT_COUNT;
 	l3fsm.strEvent = strL3Event;
 	l3fsm.strState = strL3State;
-	return FsmNew(&l3fsm, L3FnList, L3_FN_COUNT);
+	return FsmNew(&l3fsm, L3FnList, ARRAY_SIZE(L3FnList));
 }
 
 void
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c
index c5c36ee..b0554f8 100644
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ b/drivers/isdn/hisax/l3_1tr6.c
@@ -698,9 +698,6 @@ static struct stateentry downstl[] =
 	 CC_T308_2, l3_1tr6_t308_2},
 };
 
-#define DOWNSTL_LEN \
-	(sizeof(downstl) / sizeof(struct stateentry))
-
 static struct stateentry datastln1[] =
 {
 	{SBIT(0),
@@ -735,9 +732,6 @@ static struct stateentry datastln1[] =
 	 MT_N1_REL_ACK, l3_1tr6_rel_ack}
 };
 
-#define DATASTLN1_LEN \
-	(sizeof(datastln1) / sizeof(struct stateentry))
-
 static struct stateentry manstatelist[] =
 {
         {SBIT(2),
@@ -746,8 +740,6 @@ static struct stateentry manstatelist[] =
          DL_RELEASE | INDICATION, l3_1tr6_dl_release},
 };
  
-#define MANSLLEN \
-        (sizeof(manstatelist) / sizeof(struct stateentry))
 /* *INDENT-ON* */
 
 static void
@@ -840,11 +832,11 @@ up1tr6(struct PStack *st, int pr, void *arg)
 				mt = MT_N1_INVALID;
 			}
 		}
-		for (i = 0; i < DATASTLN1_LEN; i++)
+		for (i = 0; i < ARRAY_SIZE(datastln1); i++)
 			if ((mt == datastln1[i].primitive) &&
 			    ((1 << proc->state) & datastln1[i].state))
 				break;
-		if (i == DATASTLN1_LEN) {
+		if (i == ARRAY_SIZE(datastln1)) {
 			dev_kfree_skb(skb);
 			if (st->l3.debug & L3_DEB_STATE) {
 				sprintf(tmp, "up1tr6%sstate %d mt %x unhandled",
@@ -892,11 +884,11 @@ down1tr6(struct PStack *st, int pr, void *arg)
 		proc = arg;
 	}
 
-	for (i = 0; i < DOWNSTL_LEN; i++)
+	for (i = 0; i < ARRAY_SIZE(downstl); i++)
 		if ((pr == downstl[i].primitive) &&
 		    ((1 << proc->state) & downstl[i].state))
 			break;
-	if (i == DOWNSTL_LEN) {
+	if (i == ARRAY_SIZE(downstl)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			sprintf(tmp, "down1tr6 state %d prim %d unhandled",
 				proc->state, pr);
@@ -922,11 +914,11 @@ man1tr6(struct PStack *st, int pr, void *arg)
                 printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr);
                 return;
         }
-        for (i = 0; i < MANSLLEN; i++)
+        for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
                 if ((pr == manstatelist[i].primitive) &&
                     ((1 << proc->state) & manstatelist[i].state))
                         break;
-        if (i == MANSLLEN) {
+        if (i == ARRAY_SIZE(manstatelist)) {
                 if (st->l3.debug & L3_DEB_STATE) {
                         l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled",
                                 proc->callref & 0x7f, proc->state, pr);
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index 99feae8..a12fa4d 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -2820,9 +2820,6 @@ static struct stateentry downstatelist[] =
 	 CC_T309, l3dss1_dl_release},
 };
 
-#define DOWNSLLEN \
-	(sizeof(downstatelist) / sizeof(struct stateentry))
-
 static struct stateentry datastatelist[] =
 {
 	{ALL_STATES,
@@ -2875,9 +2872,6 @@ static struct stateentry datastatelist[] =
 	 MT_RESUME_REJECT, l3dss1_resume_rej},
 };
 
-#define DATASLLEN \
-	(sizeof(datastatelist) / sizeof(struct stateentry))
-
 static struct stateentry globalmes_list[] =
 {
 	{ALL_STATES,
@@ -2888,8 +2882,6 @@ static struct stateentry globalmes_list[] =
 	 MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
 */
 };
-#define GLOBALM_LEN \
-	(sizeof(globalmes_list) / sizeof(struct stateentry))
 
 static struct stateentry manstatelist[] =
 {
@@ -2903,8 +2895,6 @@ static struct stateentry manstatelist[] =
          DL_RELEASE | INDICATION, l3dss1_dl_release},
 };
 
-#define MANSLLEN \
-        (sizeof(manstatelist) / sizeof(struct stateentry))
 /* *INDENT-ON* */
 
 
@@ -2918,11 +2908,11 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 	struct l3_process *proc = st->l3.global;
 
 	proc->callref = skb->data[2]; /* cr flag */
-	for (i = 0; i < GLOBALM_LEN; i++)
+	for (i = 0; i < ARRAY_SIZE(globalmes_list); i++)
 		if ((mt == globalmes_list[i].primitive) &&
 		    ((1 << proc->state) & globalmes_list[i].state))
 			break;
-	if (i == GLOBALM_LEN) {
+	if (i == ARRAY_SIZE(globalmes_list)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1 global state %d mt %x unhandled",
 				proc->state, mt);
@@ -3097,11 +3087,11 @@ dss1up(struct PStack *st, int pr, void *arg)
 	}
 	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) 
 	  l3dss1_deliver_display(proc, pr, p); /* Display IE included */
-	for (i = 0; i < DATASLLEN; i++)
+	for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
 		if ((mt == datastatelist[i].primitive) &&
 		    ((1 << proc->state) & datastatelist[i].state))
 			break;
-	if (i == DATASLLEN) {
+	if (i == ARRAY_SIZE(datastatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1up%sstate %d mt %#x unhandled",
 				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
@@ -3156,11 +3146,11 @@ dss1down(struct PStack *st, int pr, void *arg)
 		return;
 	}  
 
-	for (i = 0; i < DOWNSLLEN; i++)
+	for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
 		if ((pr == downstatelist[i].primitive) &&
 		    ((1 << proc->state) & downstatelist[i].state))
 			break;
-	if (i == DOWNSLLEN) {
+	if (i == ARRAY_SIZE(downstatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "dss1down state %d prim %#x unhandled",
 				proc->state, pr);
@@ -3184,11 +3174,11 @@ dss1man(struct PStack *st, int pr, void *arg)
                 printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
                 return;
         }
-        for (i = 0; i < MANSLLEN; i++)
+        for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
                 if ((pr == manstatelist[i].primitive) &&
                     ((1 << proc->state) & manstatelist[i].state))
                         break;
-        if (i == MANSLLEN) {
+        if (i == ARRAY_SIZE(manstatelist)) {
                 if (st->l3.debug & L3_DEB_STATE) {
                         l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
                                 proc->callref & 0x7f, proc->state, pr);
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index f7041d5..4622d43 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -2755,9 +2755,6 @@ static struct stateentry downstatelist[] =
 	 CC_TSPID, l3ni1_spid_tout },
 };
 
-#define DOWNSLLEN \
-	(sizeof(downstatelist) / sizeof(struct stateentry))
-
 static struct stateentry datastatelist[] =
 {
 	{ALL_STATES,
@@ -2810,9 +2807,6 @@ static struct stateentry datastatelist[] =
 	 MT_RESUME_REJECT, l3ni1_resume_rej},
 };
 
-#define DATASLLEN \
-	(sizeof(datastatelist) / sizeof(struct stateentry))
-
 static struct stateentry globalmes_list[] =
 {
 	{ALL_STATES,
@@ -2825,8 +2819,6 @@ static struct stateentry globalmes_list[] =
 	{ SBIT( 0 ), MT_DL_ESTABLISHED, l3ni1_spid_send },
 	{ SBIT( 20 ) | SBIT( 21 ) | SBIT( 22 ), MT_INFORMATION, l3ni1_spid_epid },
 };
-#define GLOBALM_LEN \
-	(sizeof(globalmes_list) / sizeof(struct stateentry))
 
 static struct stateentry manstatelist[] =
 {
@@ -2840,8 +2832,6 @@ static struct stateentry manstatelist[] =
          DL_RELEASE | INDICATION, l3ni1_dl_release},
 };
 
-#define MANSLLEN \
-        (sizeof(manstatelist) / sizeof(struct stateentry))
 /* *INDENT-ON* */
 
 
@@ -2858,11 +2848,11 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 		proc->callref = skb->data[2]; /* cr flag */
 	else
 		proc->callref = 0;
-	for (i = 0; i < GLOBALM_LEN; i++)
+	for (i = 0; i < ARRAY_SIZE(globalmes_list); i++)
 		if ((mt == globalmes_list[i].primitive) &&
 		    ((1 << proc->state) & globalmes_list[i].state))
 			break;
-	if (i == GLOBALM_LEN) {
+	if (i == ARRAY_SIZE(globalmes_list)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1 global state %d mt %x unhandled",
 				proc->state, mt);
@@ -3049,11 +3039,11 @@ ni1up(struct PStack *st, int pr, void *arg)
 	}
 	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) 
 	  l3ni1_deliver_display(proc, pr, p); /* Display IE included */
-	for (i = 0; i < DATASLLEN; i++)
+	for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
 		if ((mt == datastatelist[i].primitive) &&
 		    ((1 << proc->state) & datastatelist[i].state))
 			break;
-	if (i == DATASLLEN) {
+	if (i == ARRAY_SIZE(datastatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1up%sstate %d mt %#x unhandled",
 				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
@@ -3108,11 +3098,11 @@ ni1down(struct PStack *st, int pr, void *arg)
 		return;
 	}  
 
-	for (i = 0; i < DOWNSLLEN; i++)
+	for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
 		if ((pr == downstatelist[i].primitive) &&
 		    ((1 << proc->state) & downstatelist[i].state))
 			break;
-	if (i == DOWNSLLEN) {
+	if (i == ARRAY_SIZE(downstatelist)) {
 		if (st->l3.debug & L3_DEB_STATE) {
 			l3_debug(st, "ni1down state %d prim %#x unhandled",
 				proc->state, pr);
@@ -3136,11 +3126,11 @@ ni1man(struct PStack *st, int pr, void *arg)
                 printk(KERN_ERR "HiSax ni1man without proc pr=%04x\n", pr);
                 return;
         }
-        for (i = 0; i < MANSLLEN; i++)
+        for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
                 if ((pr == manstatelist[i].primitive) &&
                     ((1 << proc->state) & manstatelist[i].state))
                         break;
-        if (i == MANSLLEN) {
+        if (i == ARRAY_SIZE(manstatelist)) {
                 if (st->l3.debug & L3_DEB_STATE) {
                         l3_debug(st, "cr %d ni1man state %d prim %#x unhandled",
                                 proc->callref & 0x7f, proc->state, pr);
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c
index aacbf0d..8b853d5 100644
--- a/drivers/isdn/hisax/q931.c
+++ b/drivers/isdn/hisax/q931.c
@@ -140,7 +140,7 @@ struct MessageType {
 	}
 };
 
-#define MTSIZE sizeof(mtlist)/sizeof(struct MessageType)
+#define MTSIZE ARRAY_SIZE(mtlist)
 
 static
 struct MessageType mt_n0[] =
@@ -157,7 +157,7 @@ struct MessageType mt_n0[] =
 	{MT_N0_CLO_ACK, "CLOse ACKnowledge"}
 };
 
-#define MT_N0_LEN (sizeof(mt_n0) / sizeof(struct MessageType))
+#define MT_N0_LEN ARRAY_SIZE(mt_n0)
 
 static
 struct MessageType mt_n1[] =
@@ -194,7 +194,7 @@ struct MessageType mt_n1[] =
 	{MT_N1_STAT, "STATus"}
 };
 
-#define MT_N1_LEN (sizeof(mt_n1) / sizeof(struct MessageType))
+#define MT_N1_LEN ARRAY_SIZE(mt_n1)
 
 
 static int
@@ -438,7 +438,7 @@ struct CauseValue {
 	},
 };
 
-#define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue)
+#define CVSIZE ARRAY_SIZE(cvlist)
 
 static
 int
@@ -516,7 +516,7 @@ struct MessageType cause_1tr6[] =
 	{CAUSE_UserInfoDiscarded, "User Info Discarded"}
 };
 
-static int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
+static int cause_1tr6_len = ARRAY_SIZE(cause_1tr6);
 
 static int
 prcause_1tr6(char *dest, u_char * p)
@@ -865,7 +865,7 @@ struct DTag { /* Display tags */
 	{ 0x96, "Redirection name" },
 	{ 0x9e, "Text" },
 };
-#define DTAGSIZE sizeof(dtaglist)/sizeof(struct DTag)
+#define DTAGSIZE ARRAY_SIZE(dtaglist)
 
 static int
 disptext_ni1(char *dest, u_char * p)
@@ -1074,7 +1074,7 @@ struct InformationElement {
 };
 
 
-#define IESIZE sizeof(ielist)/sizeof(struct InformationElement)
+#define IESIZE ARRAY_SIZE(ielist)
 
 static
 struct InformationElement ielist_ni1[] = {
@@ -1102,7 +1102,7 @@ struct InformationElement ielist_ni1[] = {
 };
 
 
-#define IESIZE_NI1 sizeof(ielist_ni1)/sizeof(struct InformationElement)
+#define IESIZE_NI1 ARRAY_SIZE(ielist_ni1)
 
 static
 struct InformationElement ielist_ni1_cs5[] = {
@@ -1110,14 +1110,14 @@ struct InformationElement ielist_ni1_cs5[] = {
 	{ 0x2a, "Display text", disptext_ni1 },
 };
 
-#define IESIZE_NI1_CS5 sizeof(ielist_ni1_cs5)/sizeof(struct InformationElement)
+#define IESIZE_NI1_CS5 ARRAY_SIZE(ielist_ni1_cs5)
 
 static
 struct InformationElement ielist_ni1_cs6[] = {
 	{ 0x7b, "Call appearance", general_ni1 },
 };
 
-#define IESIZE_NI1_CS6 sizeof(ielist_ni1_cs6)/sizeof(struct InformationElement)
+#define IESIZE_NI1_CS6 ARRAY_SIZE(ielist_ni1_cs6)
 
 static struct InformationElement we_0[] =
 {
@@ -1133,7 +1133,7 @@ static struct InformationElement we_0[] =
 	{WE0_userInfo, "User Info", general}
 };
 
-#define WE_0_LEN (sizeof(we_0) / sizeof(struct InformationElement))
+#define WE_0_LEN ARRAY_SIZE(we_0)
 
 static struct InformationElement we_6[] =
 {
@@ -1145,7 +1145,7 @@ static struct InformationElement we_6[] =
 	{WE6_statusCalled, "Status Called", general},
 	{WE6_addTransAttr, "Additional Transmission Attributes", general}
 };
-#define WE_6_LEN (sizeof(we_6) / sizeof(struct InformationElement))
+#define WE_6_LEN ARRAY_SIZE(we_6)
 
 int
 QuickHex(char *txt, u_char * p, int cnt)
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
index cff7a63..64f78a8 100644
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -226,7 +226,7 @@ printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
 #define INFO(format, arg...) \
 printk(KERN_INFO "%s:%s: " format "\n" , __FILE__,  __func__ , ## arg)
 
-#include "isdnhdlc.h"
+#include <linux/isdn/hdlc.h>
 #include "fsm.h"
 #include "hisax_if.h"
 #include <linux/skbuff.h>
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 0074b60..95b1cdd 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -218,7 +218,10 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode)
 	if (bcs->mode != L1_MODE_NULL) {
 		// Open the B channel
 		if (bcs->mode != L1_MODE_TRANS) {
-			isdnhdlc_out_init(&b_out->hdlc_state, 0, bcs->mode == L1_MODE_HDLC_56K);
+			u32 features = HDLC_BITREVERSE;
+			if (bcs->mode == L1_MODE_HDLC_56K)
+				features |= HDLC_56KBIT;
+			isdnhdlc_out_init(&b_out->hdlc_state, features);
 		}
 		st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL);
 	
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 077991c..39e8e49 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -417,7 +417,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
 
 	DBG(2,"len=%d",skb->len);
 
-	isdnhdlc_out_init(&d_out->hdlc_state, 1, 0);
+	isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE);
 
 	if (test_and_set_bit(buf_nr, &d_out->busy)) {
 		WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 2b3a055..10d41c5 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -637,10 +637,13 @@ void st5481_in_mode(struct st5481_in *in, int mode)
 	usb_unlink_urb(in->urb[1]);
 
 	if (in->mode != L1_MODE_NULL) {
-		if (in->mode != L1_MODE_TRANS)
-			isdnhdlc_rcv_init(&in->hdlc_state,
-				in->mode == L1_MODE_HDLC_56K);
-		
+		if (in->mode != L1_MODE_TRANS) {
+			u32 features = HDLC_BITREVERSE;
+
+			if (in->mode == L1_MODE_HDLC_56K)
+				features |= HDLC_56KBIT;
+			isdnhdlc_rcv_init(&in->hdlc_state, features);
+		}
 		st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL);
 		st5481_usb_device_ctrl_msg(in->adapter, in->counter,
 					   in->packet_size,
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c
index ceb0df9..6e65424 100644
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -447,8 +447,6 @@ static struct FsmNode TeiFnList[] __initdata =
 	{ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
 };
 
-#define TEI_FN_COUNT (sizeof(TeiFnList)/sizeof(struct FsmNode))
-
 int __init
 TeiNew(void)
 {
@@ -456,7 +454,7 @@ TeiNew(void)
 	teifsm.event_count = TEI_EVENT_COUNT;
 	teifsm.strEvent = strTeiEvent;
 	teifsm.strState = strTeiState;
-	return FsmNew(&teifsm, TeiFnList, TEI_FN_COUNT);
+	return FsmNew(&teifsm, TeiFnList, ARRAY_SIZE(TeiFnList));
 }
 
 void
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index bb1c8dd..c4d862c 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -105,8 +105,6 @@ W6692_bh(struct work_struct *work)
 		container_of(work, struct IsdnCardState, tqueue);
 	struct PStack *stptr;
 
-	if (!cs)
-		return;
 	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
 		if (cs->debug)
 			debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index 579974c..72eb926 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -119,7 +119,7 @@ net_close(struct net_device *dev)
 /* send a packet on this interface. */
 /* new style for kernel >= 2.3.33   */
 /************************************/
-static int
+static netdev_tx_t
 net_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_local *lp = (struct net_local *) dev;
@@ -148,7 +148,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
 	if (lp->sk_count <= 3) {
 		schedule_work(&((hysdn_card *) dev->ml_priv)->irq_queue);
 	}
-	return (0);		/* success */
+	return NETDEV_TX_OK;	/* success */
 }				/* net_send_packet */
 
 
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig
index ed3510f..dd744ff 100644
--- a/drivers/isdn/i4l/Kconfig
+++ b/drivers/isdn/i4l/Kconfig
@@ -2,6 +2,8 @@
 # Old ISDN4Linux config
 #
 
+if ISDN_I4L
+
 config ISDN_PPP
 	bool "Support synchronous PPP"
 	depends on INET
@@ -135,3 +137,12 @@ source "drivers/isdn/act2000/Kconfig"
 source "drivers/isdn/hysdn/Kconfig"
 
 endmenu
+# end ISDN_I4L
+endif
+
+config ISDN_HDLC
+	tristate 
+	depends on HISAX_ST5481
+	select CRC_CCITT
+	select BITREVERSE
+
diff --git a/drivers/isdn/i4l/Makefile b/drivers/isdn/i4l/Makefile
index 49a06c0..cb9d3bb 100644
--- a/drivers/isdn/i4l/Makefile
+++ b/drivers/isdn/i4l/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_ISDN_I4L)		+= isdn.o
 obj-$(CONFIG_ISDN_PPP_BSDCOMP)	+= isdn_bsdcomp.o
+obj-$(CONFIG_ISDN_HDLC)		+= isdnhdlc.o
 
 # Multipart objects.
 
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index de4aad0..90b56ed 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -176,7 +176,8 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
 /* Prototypes */
 
 static int isdn_net_force_dial_lp(isdn_net_local *);
-static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
+static netdev_tx_t isdn_net_start_xmit(struct sk_buff *,
+					     struct net_device *);
 
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
@@ -1051,12 +1052,12 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
 	isdn_net_dev *nd;
 	isdn_net_local *slp;
 	isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
-	int retv = 0;
+	int retv = NETDEV_TX_OK;
 
 	if (((isdn_net_local *) netdev_priv(ndev))->master) {
 		printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* For the other encaps the header has already been built */
@@ -1160,7 +1161,7 @@ static void isdn_net_tx_timeout(struct net_device * ndev)
  * If this interface isn't connected to a ISDN-Channel, find a free channel,
  * and start dialing.
  */
-static int
+static netdev_tx_t
 isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
 	isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
@@ -1202,7 +1203,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 			if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
 				isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
 				dev_kfree_skb(skb);
-				return 0;
+				return NETDEV_TX_OK;
 			}
 			if (lp->phone[1]) {
 				ulong flags;
@@ -1215,7 +1216,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 					if(time_before(jiffies, lp->dialwait_timer)) {
 						isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
 						dev_kfree_skb(skb);
-						return 0;
+						return NETDEV_TX_OK;
 					} else
 						lp->dialwait_timer = 0;
 				}
@@ -1243,7 +1244,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 					isdn_net_unreachable(ndev, skb,
 							   "No channel");
 					dev_kfree_skb(skb);
-					return 0;
+					return NETDEV_TX_OK;
 				}
 				/* Log packet, which triggered dialing */
 				if (dev->net_verbose)
@@ -1258,7 +1259,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 						dev_kfree_skb(skb);
 						isdn_net_unbind_channel(lp);
 						spin_unlock_irqrestore(&dev->lock, flags);
-						return 0;	/* STN (skb to nirvana) ;) */
+						return NETDEV_TX_OK;	/* STN (skb to nirvana) ;) */
 					}
 #ifdef CONFIG_IPPP_FILTER
 					if (isdn_ppp_autodial_filter(skb, lp)) {
@@ -1267,7 +1268,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 						spin_unlock_irqrestore(&dev->lock, flags);
 						isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered");
 						dev_kfree_skb(skb);
-						return 0;
+						return NETDEV_TX_OK;
 					}
 #endif
 					spin_unlock_irqrestore(&dev->lock, flags);
@@ -1285,7 +1286,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 				isdn_net_unreachable(ndev, skb,
 						     "No phone number");
 				dev_kfree_skb(skb);
-				return 0;
+				return NETDEV_TX_OK;
 			}
 		} else {
 			/* Device is connected to an ISDN channel */ 
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index aa30b5c..2d14b64 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -1223,7 +1223,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	isdn_net_dev *nd;
 	unsigned int proto = PPP_IP;     /* 0x21 */
 	struct ippp_struct *ipt,*ipts;
-	int slot, retval = 0;
+	int slot, retval = NETDEV_TX_OK;
 
 	mlp = (isdn_net_local *) netdev_priv(netdev);
 	nd = mlp->netdev;       /* get master lp */
@@ -1240,7 +1240,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	if (!(ipts->pppcfg & SC_ENABLE_IP)) {	/* PPP connected ? */
 		if (ipts->debug & 0x1)
 			printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
-		retval = 1;
+		retval = NETDEV_TX_BUSY;
 		goto out;
 	}
 
@@ -1261,7 +1261,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
 	lp = isdn_net_get_locked_lp(nd);
 	if (!lp) {
 		printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
-		retval = 1;
+		retval = NETDEV_TX_BUSY;
 		goto out;
 	}
 	/* we have our lp locked from now on */
diff --git a/drivers/isdn/i4l/isdnhdlc.c b/drivers/isdn/i4l/isdnhdlc.c
new file mode 100644
index 0000000..c989aa3
--- /dev/null
+++ b/drivers/isdn/i4l/isdnhdlc.c
@@ -0,0 +1,630 @@
+/*
+ * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
+ *
+ * Copyright (C)
+ *	2009	Karsten Keil		<keil@b1-systems.de>
+ *	2002	Wolfgang MÃ¼es		<wolfgang@iksw-muees.de>
+ *	2001	Frode Isaksen		<fisaksen@bewan.com>
+ *      2001	Kai Germaschewski	<kai.germaschewski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/crc-ccitt.h>
+#include <linux/isdn/hdlc.h>
+#include <linux/bitrev.h>
+
+/*-------------------------------------------------------------------*/
+
+MODULE_AUTHOR("Wolfgang MÃ¼es <wolfgang@iksw-muees.de>, "
+	      "Frode Isaksen <fisaksen@bewan.com>, "
+	      "Kai Germaschewski <kai.germaschewski@gmx.de>");
+MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
+MODULE_LICENSE("GPL");
+
+/*-------------------------------------------------------------------*/
+
+enum {
+	HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
+	HDLC_GET_DATA, HDLC_FAST_FLAG
+};
+
+enum {
+	HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
+	HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
+	HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
+	HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE
+};
+
+void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
+{
+	memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
+	hdlc->state = HDLC_GET_DATA;
+	if (features & HDLC_56KBIT)
+		hdlc->do_adapt56 = 1;
+	if (features & HDLC_BITREVERSE)
+		hdlc->do_bitreverse = 1;
+}
+EXPORT_SYMBOL(isdnhdlc_out_init);
+
+void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
+{
+	memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
+	if (features & HDLC_DCHANNEL) {
+		hdlc->dchannel = 1;
+		hdlc->state = HDLC_SEND_FIRST_FLAG;
+	} else {
+		hdlc->dchannel = 0;
+		hdlc->state = HDLC_SEND_FAST_FLAG;
+		hdlc->ffvalue = 0x7e;
+	}
+	hdlc->cbin = 0x7e;
+	if (features & HDLC_56KBIT) {
+		hdlc->do_adapt56 = 1;
+		hdlc->state = HDLC_SENDFLAG_B0;
+	} else
+		hdlc->data_bits = 8;
+	if (features & HDLC_BITREVERSE)
+		hdlc->do_bitreverse = 1;
+}
+EXPORT_SYMBOL(isdnhdlc_rcv_init);
+
+static int
+check_frame(struct isdnhdlc_vars *hdlc)
+{
+	int status;
+
+	if (hdlc->dstpos < 2) 	/* too small - framing error */
+		status = -HDLC_FRAMING_ERROR;
+	else if (hdlc->crc != 0xf0b8)	/* crc error */
+		status = -HDLC_CRC_ERROR;
+	else {
+		/* remove CRC */
+		hdlc->dstpos -= 2;
+		/* good frame */
+		status = hdlc->dstpos;
+	}
+	return status;
+}
+
+/*
+  isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
+
+  The source buffer is scanned for valid HDLC frames looking for
+  flags (01111110) to indicate the start of a frame. If the start of
+  the frame is found, the bit stuffing is removed (0 after 5 1's).
+  When a new flag is found, the complete frame has been received
+  and the CRC is checked.
+  If a valid frame is found, the function returns the frame length
+  excluding the CRC with the bit HDLC_END_OF_FRAME set.
+  If the beginning of a valid frame is found, the function returns
+  the length.
+  If a framing error is found (too many 1s and not a flag) the function
+  returns the length with the bit HDLC_FRAMING_ERROR set.
+  If a CRC error is found the function returns the length with the
+  bit HDLC_CRC_ERROR set.
+  If the frame length exceeds the destination buffer size, the function
+  returns the length with the bit HDLC_LENGTH_ERROR set.
+
+  src - source buffer
+  slen - source buffer length
+  count - number of bytes removed (decoded) from the source buffer
+  dst _ destination buffer
+  dsize - destination buffer size
+  returns - number of decoded bytes in the destination buffer and status
+  flag.
+ */
+int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
+	int *count, u8 *dst, int dsize)
+{
+	int status = 0;
+
+	static const unsigned char fast_flag[] = {
+		0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
+	};
+
+	static const unsigned char fast_flag_value[] = {
+		0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
+	};
+
+	static const unsigned char fast_abort[] = {
+		0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
+	};
+
+#define handle_fast_flag(h) \
+	do {\
+		if (h->cbin == fast_flag[h->bit_shift]) {\
+			h->ffvalue = fast_flag_value[h->bit_shift];\
+			h->state = HDLC_FAST_FLAG;\
+			h->ffbit_shift = h->bit_shift;\
+			h->bit_shift = 1;\
+		} else {\
+			h->state = HDLC_GET_DATA;\
+			h->data_received = 0;\
+		} \
+	} while (0)
+
+#define handle_abort(h) \
+	do {\
+		h->shift_reg = fast_abort[h->ffbit_shift - 1];\
+		h->hdlc_bits1 = h->ffbit_shift - 2;\
+		if (h->hdlc_bits1 < 0)\
+			h->hdlc_bits1 = 0;\
+		h->data_bits = h->ffbit_shift - 1;\
+		h->state = HDLC_GET_DATA;\
+		h->data_received = 0;\
+	} while (0)
+
+	*count = slen;
+
+	while (slen > 0) {
+		if (hdlc->bit_shift == 0) {
+			/* the code is for bitreverse streams */
+			if (hdlc->do_bitreverse == 0)
+				hdlc->cbin = bitrev8(*src++);
+			else
+				hdlc->cbin = *src++;
+			slen--;
+			hdlc->bit_shift = 8;
+			if (hdlc->do_adapt56)
+				hdlc->bit_shift--;
+		}
+
+		switch (hdlc->state) {
+		case STOPPED:
+			return 0;
+		case HDLC_FAST_IDLE:
+			if (hdlc->cbin == 0xff) {
+				hdlc->bit_shift = 0;
+				break;
+			}
+			hdlc->state = HDLC_GET_FLAG_B0;
+			hdlc->hdlc_bits1 = 0;
+			hdlc->bit_shift = 8;
+			break;
+		case HDLC_GET_FLAG_B0:
+			if (!(hdlc->cbin & 0x80)) {
+				hdlc->state = HDLC_GETFLAG_B1A6;
+				hdlc->hdlc_bits1 = 0;
+			} else {
+				if ((!hdlc->do_adapt56) &&
+				    (++hdlc->hdlc_bits1 >= 8) &&
+				    (hdlc->bit_shift == 1))
+						hdlc->state = HDLC_FAST_IDLE;
+			}
+			hdlc->cbin <<= 1;
+			hdlc->bit_shift--;
+			break;
+		case HDLC_GETFLAG_B1A6:
+			if (hdlc->cbin & 0x80) {
+				hdlc->hdlc_bits1++;
+				if (hdlc->hdlc_bits1 == 6)
+					hdlc->state = HDLC_GETFLAG_B7;
+			} else
+				hdlc->hdlc_bits1 = 0;
+			hdlc->cbin <<= 1;
+			hdlc->bit_shift--;
+			break;
+		case HDLC_GETFLAG_B7:
+			if (hdlc->cbin & 0x80) {
+				hdlc->state = HDLC_GET_FLAG_B0;
+			} else {
+				hdlc->state = HDLC_GET_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->shift_reg = 0;
+				hdlc->hdlc_bits1 = 0;
+				hdlc->data_bits = 0;
+				hdlc->data_received = 0;
+			}
+			hdlc->cbin <<= 1;
+			hdlc->bit_shift--;
+			break;
+		case HDLC_GET_DATA:
+			if (hdlc->cbin & 0x80) {
+				hdlc->hdlc_bits1++;
+				switch (hdlc->hdlc_bits1) {
+				case 6:
+					break;
+				case 7:
+					if (hdlc->data_received)
+						/* bad frame */
+						status = -HDLC_FRAMING_ERROR;
+					if (!hdlc->do_adapt56) {
+						if (hdlc->cbin == fast_abort
+						    [hdlc->bit_shift + 1]) {
+							hdlc->state =
+								HDLC_FAST_IDLE;
+							hdlc->bit_shift = 1;
+							break;
+						}
+					} else
+						hdlc->state = HDLC_GET_FLAG_B0;
+					break;
+				default:
+					hdlc->shift_reg >>= 1;
+					hdlc->shift_reg |= 0x80;
+					hdlc->data_bits++;
+					break;
+				}
+			} else {
+				switch (hdlc->hdlc_bits1) {
+				case 5:
+					break;
+				case 6:
+					if (hdlc->data_received)
+						status = check_frame(hdlc);
+					hdlc->crc = 0xffff;
+					hdlc->shift_reg = 0;
+					hdlc->data_bits = 0;
+					if (!hdlc->do_adapt56)
+						handle_fast_flag(hdlc);
+					else {
+						hdlc->state = HDLC_GET_DATA;
+						hdlc->data_received = 0;
+					}
+					break;
+				default:
+					hdlc->shift_reg >>= 1;
+					hdlc->data_bits++;
+					break;
+				}
+				hdlc->hdlc_bits1 = 0;
+			}
+			if (status) {
+				hdlc->dstpos = 0;
+				*count -= slen;
+				hdlc->cbin <<= 1;
+				hdlc->bit_shift--;
+				return status;
+			}
+			if (hdlc->data_bits == 8) {
+				hdlc->data_bits = 0;
+				hdlc->data_received = 1;
+				hdlc->crc = crc_ccitt_byte(hdlc->crc,
+						hdlc->shift_reg);
+
+				/* good byte received */
+				if (hdlc->dstpos < dsize)
+					dst[hdlc->dstpos++] = hdlc->shift_reg;
+				else {
+					/* frame too long */
+					status = -HDLC_LENGTH_ERROR;
+					hdlc->dstpos = 0;
+				}
+			}
+			hdlc->cbin <<= 1;
+			hdlc->bit_shift--;
+			break;
+		case HDLC_FAST_FLAG:
+			if (hdlc->cbin == hdlc->ffvalue) {
+				hdlc->bit_shift = 0;
+				break;
+			} else {
+				if (hdlc->cbin == 0xff) {
+					hdlc->state = HDLC_FAST_IDLE;
+					hdlc->bit_shift = 0;
+				} else if (hdlc->ffbit_shift == 8) {
+					hdlc->state = HDLC_GETFLAG_B7;
+					break;
+				} else
+					handle_abort(hdlc);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+	*count -= slen;
+	return 0;
+}
+EXPORT_SYMBOL(isdnhdlc_decode);
+/*
+  isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
+
+  The bit stream starts with a beginning flag (01111110). After
+  that each byte is added to the bit stream with bit stuffing added
+  (0 after 5 1's).
+  When the last byte has been removed from the source buffer, the
+  CRC (2 bytes is added) and the frame terminates with the ending flag.
+  For the dchannel, the idle character (all 1's) is also added at the end.
+  If this function is called with empty source buffer (slen=0), flags or
+  idle character will be generated.
+
+  src - source buffer
+  slen - source buffer length
+  count - number of bytes removed (encoded) from source buffer
+  dst _ destination buffer
+  dsize - destination buffer size
+  returns - number of encoded bytes in the destination buffer
+*/
+int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
+	int *count, u8 *dst, int dsize)
+{
+	static const unsigned char xfast_flag_value[] = {
+		0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
+	};
+
+	int len = 0;
+
+	*count = slen;
+
+	/* special handling for one byte frames */
+	if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG))
+		hdlc->state = HDLC_SENDFLAG_ONE;
+	while (dsize > 0) {
+		if (hdlc->bit_shift == 0) {
+			if (slen && !hdlc->do_closing) {
+				hdlc->shift_reg = *src++;
+				slen--;
+				if (slen == 0)
+					/* closing sequence, CRC + flag(s) */
+					hdlc->do_closing = 1;
+				hdlc->bit_shift = 8;
+			} else {
+				if (hdlc->state == HDLC_SEND_DATA) {
+					if (hdlc->data_received) {
+						hdlc->state = HDLC_SEND_CRC1;
+						hdlc->crc ^= 0xffff;
+						hdlc->bit_shift = 8;
+						hdlc->shift_reg =
+							hdlc->crc & 0xff;
+					} else if (!hdlc->do_adapt56)
+						hdlc->state =
+							HDLC_SEND_FAST_FLAG;
+					else
+						hdlc->state =
+							HDLC_SENDFLAG_B0;
+				}
+
+			}
+		}
+
+		switch (hdlc->state) {
+		case STOPPED:
+			while (dsize--)
+				*dst++ = 0xff;
+			return dsize;
+		case HDLC_SEND_FAST_FLAG:
+			hdlc->do_closing = 0;
+			if (slen == 0) {
+				/* the code is for bitreverse streams */
+				if (hdlc->do_bitreverse == 0)
+					*dst++ = bitrev8(hdlc->ffvalue);
+				else
+					*dst++ = hdlc->ffvalue;
+				len++;
+				dsize--;
+				break;
+			}
+			/* fall through */
+		case HDLC_SENDFLAG_ONE:
+			if (hdlc->bit_shift == 8) {
+				hdlc->cbin = hdlc->ffvalue >>
+					(8 - hdlc->data_bits);
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+				hdlc->data_received = 1;
+			}
+			break;
+		case HDLC_SENDFLAG_B0:
+			hdlc->do_closing = 0;
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			hdlc->hdlc_bits1 = 0;
+			hdlc->state = HDLC_SENDFLAG_B1A6;
+			break;
+		case HDLC_SENDFLAG_B1A6:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			hdlc->cbin++;
+			if (++hdlc->hdlc_bits1 == 6)
+				hdlc->state = HDLC_SENDFLAG_B7;
+			break;
+		case HDLC_SENDFLAG_B7:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if (slen == 0) {
+				hdlc->state = HDLC_SENDFLAG_B0;
+				break;
+			}
+			if (hdlc->bit_shift == 8) {
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+				hdlc->data_received = 1;
+			}
+			break;
+		case HDLC_SEND_FIRST_FLAG:
+			hdlc->data_received = 1;
+			if (hdlc->data_bits == 8) {
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if (hdlc->shift_reg & 0x01)
+				hdlc->cbin++;
+			hdlc->shift_reg >>= 1;
+			hdlc->bit_shift--;
+			if (hdlc->bit_shift == 0) {
+				hdlc->state = HDLC_SEND_DATA;
+				hdlc->crc = 0xffff;
+				hdlc->hdlc_bits1 = 0;
+			}
+			break;
+		case HDLC_SEND_DATA:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if (hdlc->hdlc_bits1 == 5) {
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if (hdlc->bit_shift == 8)
+				hdlc->crc = crc_ccitt_byte(hdlc->crc,
+					hdlc->shift_reg);
+			if (hdlc->shift_reg & 0x01) {
+				hdlc->hdlc_bits1++;
+				hdlc->cbin++;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			} else {
+				hdlc->hdlc_bits1 = 0;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			}
+			break;
+		case HDLC_SEND_CRC1:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if (hdlc->hdlc_bits1 == 5) {
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if (hdlc->shift_reg & 0x01) {
+				hdlc->hdlc_bits1++;
+				hdlc->cbin++;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			} else {
+				hdlc->hdlc_bits1 = 0;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			}
+			if (hdlc->bit_shift == 0) {
+				hdlc->shift_reg = (hdlc->crc >> 8);
+				hdlc->state = HDLC_SEND_CRC2;
+				hdlc->bit_shift = 8;
+			}
+			break;
+		case HDLC_SEND_CRC2:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if (hdlc->hdlc_bits1 == 5) {
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if (hdlc->shift_reg & 0x01) {
+				hdlc->hdlc_bits1++;
+				hdlc->cbin++;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			} else {
+				hdlc->hdlc_bits1 = 0;
+				hdlc->shift_reg >>= 1;
+				hdlc->bit_shift--;
+			}
+			if (hdlc->bit_shift == 0) {
+				hdlc->shift_reg = 0x7e;
+				hdlc->state = HDLC_SEND_CLOSING_FLAG;
+				hdlc->bit_shift = 8;
+			}
+			break;
+		case HDLC_SEND_CLOSING_FLAG:
+			hdlc->cbin <<= 1;
+			hdlc->data_bits++;
+			if (hdlc->hdlc_bits1 == 5) {
+				hdlc->hdlc_bits1 = 0;
+				break;
+			}
+			if (hdlc->shift_reg & 0x01)
+				hdlc->cbin++;
+			hdlc->shift_reg >>= 1;
+			hdlc->bit_shift--;
+			if (hdlc->bit_shift == 0) {
+				hdlc->ffvalue =
+					xfast_flag_value[hdlc->data_bits];
+				if (hdlc->dchannel) {
+					hdlc->ffvalue = 0x7e;
+					hdlc->state = HDLC_SEND_IDLE1;
+					hdlc->bit_shift = 8-hdlc->data_bits;
+					if (hdlc->bit_shift == 0)
+						hdlc->state =
+							HDLC_SEND_FAST_IDLE;
+				} else {
+					if (!hdlc->do_adapt56) {
+						hdlc->state =
+							HDLC_SEND_FAST_FLAG;
+						hdlc->data_received = 0;
+					} else {
+						hdlc->state = HDLC_SENDFLAG_B0;
+						hdlc->data_received = 0;
+					}
+					/* Finished this frame, send flags */
+					if (dsize > 1)
+						dsize = 1;
+				}
+			}
+			break;
+		case HDLC_SEND_IDLE1:
+			hdlc->do_closing = 0;
+			hdlc->cbin <<= 1;
+			hdlc->cbin++;
+			hdlc->data_bits++;
+			hdlc->bit_shift--;
+			if (hdlc->bit_shift == 0) {
+				hdlc->state = HDLC_SEND_FAST_IDLE;
+				hdlc->bit_shift = 0;
+			}
+			break;
+		case HDLC_SEND_FAST_IDLE:
+			hdlc->do_closing = 0;
+			hdlc->cbin = 0xff;
+			hdlc->data_bits = 8;
+			if (hdlc->bit_shift == 8) {
+				hdlc->cbin = 0x7e;
+				hdlc->state = HDLC_SEND_FIRST_FLAG;
+			} else {
+				/* the code is for bitreverse streams */
+				if (hdlc->do_bitreverse == 0)
+					*dst++ = bitrev8(hdlc->cbin);
+				else
+					*dst++ = hdlc->cbin;
+				hdlc->bit_shift = 0;
+				hdlc->data_bits = 0;
+				len++;
+				dsize = 0;
+			}
+			break;
+		default:
+			break;
+		}
+		if (hdlc->do_adapt56) {
+			if (hdlc->data_bits == 7) {
+				hdlc->cbin <<= 1;
+				hdlc->cbin++;
+				hdlc->data_bits++;
+			}
+		}
+		if (hdlc->data_bits == 8) {
+			/* the code is for bitreverse streams */
+			if (hdlc->do_bitreverse == 0)
+				*dst++ = bitrev8(hdlc->cbin);
+			else
+				*dst++ = hdlc->cbin;
+			hdlc->data_bits = 0;
+			len++;
+			dsize--;
+		}
+	}
+	*count -= slen;
+
+	return len;
+}
+EXPORT_SYMBOL(isdnhdlc_encode);
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index 0481a0c..e8049be 100644
--- a/drivers/isdn/mISDN/hwchannel.c
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -114,13 +114,14 @@ mISDN_freedchannel(struct dchannel *ch)
 }
 EXPORT_SYMBOL(mISDN_freedchannel);
 
-int
-mISDN_freebchannel(struct bchannel *ch)
+void
+mISDN_clear_bchannel(struct bchannel *ch)
 {
 	if (ch->tx_skb) {
 		dev_kfree_skb(ch->tx_skb);
 		ch->tx_skb = NULL;
 	}
+	ch->tx_idx = 0;
 	if (ch->rx_skb) {
 		dev_kfree_skb(ch->rx_skb);
 		ch->rx_skb = NULL;
@@ -129,6 +130,16 @@ mISDN_freebchannel(struct bchannel *ch)
 		dev_kfree_skb(ch->next_skb);
 		ch->next_skb = NULL;
 	}
+	test_and_clear_bit(FLG_TX_BUSY, &ch->Flags);
+	test_and_clear_bit(FLG_TX_NEXT, &ch->Flags);
+	test_and_clear_bit(FLG_ACTIVE, &ch->Flags);
+}
+EXPORT_SYMBOL(mISDN_clear_bchannel);
+
+int
+mISDN_freebchannel(struct bchannel *ch)
+{
+	mISDN_clear_bchannel(ch);
 	skb_queue_purge(&ch->rqueue);
 	ch->rcount = 0;
 	flush_scheduled_work();
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index 9c2589e..e17f004 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -1832,8 +1832,6 @@ static struct FsmNode L2FnList[] =
 	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},
 };
 
-#define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
-
 static int
 ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
 {
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index a0f6838..588a5b0 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -294,10 +294,11 @@ static void macio_setup_interrupts(struct macio_dev *dev)
 	int i = 0, j = 0;
 
 	for (;;) {
-		struct resource *res = &dev->interrupt[j];
+		struct resource *res;
 
 		if (j >= MACIO_DEV_COUNT_IRQS)
 			break;
+		res = &dev->interrupt[j];
 		irq = irq_of_parse_and_map(np, i++);
 		if (irq == NO_IRQ)
 			break;
@@ -321,9 +322,10 @@ static void macio_setup_resources(struct macio_dev *dev,
 	int index;
 
 	for (index = 0; of_address_to_resource(np, index, &r) == 0; index++) {
-		struct resource *res = &dev->resource[index];
+		struct resource *res;
 		if (index >= MACIO_DEV_COUNT_RESOURCES)
 			break;
+		res = &dev->resource[index];
 		*res = r;
 		res->name = dev_name(&dev->ofdev.dev);
 
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 4002331..8b93644 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -239,8 +239,8 @@ setup_hardware( void )
 	 * to be on the safe side (OSX doesn't)...
 	 */
 	if( x.overheat_temp == (80 << 8) ) {
-		x.overheat_temp = 65 << 8;
-		x.overheat_hyst = 60 << 8;
+		x.overheat_temp = 75 << 8;
+		x.overheat_hyst = 70 << 8;
 		write_reg( x.thermostat, 2, x.overheat_hyst, 2 );
 		write_reg( x.thermostat, 3, x.overheat_temp, 2 );
 
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 7f77f18..a679429 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1532,7 +1532,7 @@ static const struct file_operations _ctl_fops = {
 static struct miscdevice _dm_misc = {
 	.minor 		= MISC_DYNAMIC_MINOR,
 	.name  		= DM_NAME,
-	.devnode	= "mapper/control",
+	.nodename	= "mapper/control",
 	.fops  		= &_ctl_fops
 };
 
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 6f0d90d..32d0b87 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -64,6 +64,7 @@ struct multipath {
 	spinlock_t lock;
 
 	const char *hw_handler_name;
+	char *hw_handler_params;
 	unsigned nr_priority_groups;
 	struct list_head priority_groups;
 	unsigned pg_init_required;	/* pg_init needs calling? */
@@ -219,6 +220,7 @@ static void free_multipath(struct multipath *m)
 	}
 
 	kfree(m->hw_handler_name);
+	kfree(m->hw_handler_params);
 	mempool_destroy(m->mpio_pool);
 	kfree(m);
 }
@@ -615,6 +617,17 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
 			dm_put_device(ti, p->path.dev);
 			goto bad;
 		}
+
+		if (m->hw_handler_params) {
+			r = scsi_dh_set_params(q, m->hw_handler_params);
+			if (r < 0) {
+				ti->error = "unable to set hardware "
+							"handler parameters";
+				scsi_dh_detach(q);
+				dm_put_device(ti, p->path.dev);
+				goto bad;
+			}
+		}
 	}
 
 	r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error);
@@ -705,6 +718,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
 static int parse_hw_handler(struct arg_set *as, struct multipath *m)
 {
 	unsigned hw_argc;
+	int ret;
 	struct dm_target *ti = m->ti;
 
 	static struct param _params[] = {
@@ -726,17 +740,33 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m)
 	request_module("scsi_dh_%s", m->hw_handler_name);
 	if (scsi_dh_handler_exist(m->hw_handler_name) == 0) {
 		ti->error = "unknown hardware handler type";
-		kfree(m->hw_handler_name);
-		m->hw_handler_name = NULL;
-		return -EINVAL;
+		ret = -EINVAL;
+		goto fail;
 	}
 
-	if (hw_argc > 1)
-		DMWARN("Ignoring user-specified arguments for "
-		       "hardware handler \"%s\"", m->hw_handler_name);
+	if (hw_argc > 1) {
+		char *p;
+		int i, j, len = 4;
+
+		for (i = 0; i <= hw_argc - 2; i++)
+			len += strlen(as->argv[i]) + 1;
+		p = m->hw_handler_params = kzalloc(len, GFP_KERNEL);
+		if (!p) {
+			ti->error = "memory allocation failed";
+			ret = -ENOMEM;
+			goto fail;
+		}
+		j = sprintf(p, "%d", hw_argc - 1);
+		for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1)
+			j = sprintf(p, "%s", as->argv[i]);
+	}
 	consume(as, hw_argc - 1);
 
 	return 0;
+fail:
+	kfree(m->hw_handler_name);
+	m->hw_handler_name = NULL;
+	return ret;
 }
 
 static int parse_features(struct arg_set *as, struct multipath *m)
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 33f179e..cc9dc79 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -1129,7 +1129,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio,
 	if (error == -EOPNOTSUPP)
 		goto out;
 
-	if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
+	if ((error == -EWOULDBLOCK) && bio_rw_flagged(bio, BIO_RW_AHEAD))
 		goto out;
 
 	if (unlikely(error)) {
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 3e563d2..e0efc1a 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -285,7 +285,7 @@ static int stripe_end_io(struct dm_target *ti, struct bio *bio,
 	if (!error)
 		return 0; /* I/O complete */
 
-	if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio))
+	if ((error == -EWOULDBLOCK) && bio_rw_flagged(bio, BIO_RW_AHEAD))
 		return error;
 
 	if (error == -EOPNOTSUPP)
@@ -336,7 +336,7 @@ static void stripe_io_hints(struct dm_target *ti,
 	unsigned chunk_size = (sc->chunk_mask + 1) << 9;
 
 	blk_limits_io_min(limits, chunk_size);
-	limits->io_opt = chunk_size * sc->stripes;
+	blk_limits_io_opt(limits, chunk_size * sc->stripes);
 }
 
 static struct target_type stripe_target = {
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index b4845b1..eee28fa 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -130,7 +130,7 @@ struct mapped_device {
 	/*
 	 * A list of ios that arrived while we were suspended.
 	 */
-	atomic_t pending;
+	atomic_t pending[2];
 	wait_queue_head_t wait;
 	struct work_struct work;
 	struct bio_list deferred;
@@ -453,13 +453,14 @@ static void start_io_acct(struct dm_io *io)
 {
 	struct mapped_device *md = io->md;
 	int cpu;
+	int rw = bio_data_dir(io->bio);
 
 	io->start_time = jiffies;
 
 	cpu = part_stat_lock();
 	part_round_stats(cpu, &dm_disk(md)->part0);
 	part_stat_unlock();
-	dm_disk(md)->part0.in_flight = atomic_inc_return(&md->pending);
+	dm_disk(md)->part0.in_flight[rw] = atomic_inc_return(&md->pending[rw]);
 }
 
 static void end_io_acct(struct dm_io *io)
@@ -479,8 +480,9 @@ static void end_io_acct(struct dm_io *io)
 	 * After this is decremented the bio must not be touched if it is
 	 * a barrier.
 	 */
-	dm_disk(md)->part0.in_flight = pending =
-		atomic_dec_return(&md->pending);
+	dm_disk(md)->part0.in_flight[rw] = pending =
+		atomic_dec_return(&md->pending[rw]);
+	pending += atomic_read(&md->pending[rw^0x1]);
 
 	/* nudge anyone waiting on suspend queue */
 	if (!pending)
@@ -586,7 +588,7 @@ static void dec_pending(struct dm_io *io, int error)
 			 */
 			spin_lock_irqsave(&md->deferred_lock, flags);
 			if (__noflush_suspending(md)) {
-				if (!bio_barrier(io->bio))
+				if (!bio_rw_flagged(io->bio, BIO_RW_BARRIER))
 					bio_list_add_head(&md->deferred,
 							  io->bio);
 			} else
@@ -598,7 +600,7 @@ static void dec_pending(struct dm_io *io, int error)
 		io_error = io->error;
 		bio = io->bio;
 
-		if (bio_barrier(bio)) {
+		if (bio_rw_flagged(bio, BIO_RW_BARRIER)) {
 			/*
 			 * There can be just one barrier request so we use
 			 * a per-device variable for error reporting.
@@ -1209,7 +1211,7 @@ static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
 
 	ci.map = dm_get_table(md);
 	if (unlikely(!ci.map)) {
-		if (!bio_barrier(bio))
+		if (!bio_rw_flagged(bio, BIO_RW_BARRIER))
 			bio_io_error(bio);
 		else
 			if (!md->barrier_error)
@@ -1321,7 +1323,7 @@ static int _dm_request(struct request_queue *q, struct bio *bio)
 	 * we have to queue this io for later.
 	 */
 	if (unlikely(test_bit(DMF_QUEUE_IO_TO_THREAD, &md->flags)) ||
-	    unlikely(bio_barrier(bio))) {
+	    unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		up_read(&md->io_lock);
 
 		if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) &&
@@ -1344,7 +1346,7 @@ static int dm_make_request(struct request_queue *q, struct bio *bio)
 {
 	struct mapped_device *md = q->queuedata;
 
-	if (unlikely(bio_barrier(bio))) {
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		bio_endio(bio, -EOPNOTSUPP);
 		return 0;
 	}
@@ -1785,7 +1787,8 @@ static struct mapped_device *alloc_dev(int minor)
 	if (!md->disk)
 		goto bad_disk;
 
-	atomic_set(&md->pending, 0);
+	atomic_set(&md->pending[0], 0);
+	atomic_set(&md->pending[1], 0);
 	init_waitqueue_head(&md->wait);
 	INIT_WORK(&md->work, dm_wq_work);
 	init_waitqueue_head(&md->eventq);
@@ -2088,7 +2091,8 @@ static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
 				break;
 			}
 			spin_unlock_irqrestore(q->queue_lock, flags);
-		} else if (!atomic_read(&md->pending))
+		} else if (!atomic_read(&md->pending[0]) &&
+					!atomic_read(&md->pending[1]))
 			break;
 
 		if (interruptible == TASK_INTERRUPTIBLE &&
@@ -2164,7 +2168,7 @@ static void dm_wq_work(struct work_struct *work)
 		if (dm_request_based(md))
 			generic_make_request(c);
 		else {
-			if (bio_barrier(c))
+			if (bio_rw_flagged(c, BIO_RW_BARRIER))
 				process_barrier(md, c);
 			else
 				__split_and_process_bio(md, c);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 5fe39c2..ea48429 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -288,7 +288,7 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
 	sector_t start_sector;
 	int cpu;
 
-	if (unlikely(bio_barrier(bio))) {
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		bio_endio(bio, -EOPNOTSUPP);
 		return 0;
 	}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 7140909..89e7681 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -90,7 +90,7 @@ static void multipath_end_request(struct bio *bio, int error)
 
 	if (uptodate)
 		multipath_end_bh_io(mp_bh, 0);
-	else if (!bio_rw_ahead(bio)) {
+	else if (!bio_rw_flagged(bio, BIO_RW_AHEAD)) {
 		/*
 		 * oops, IO error:
 		 */
@@ -144,7 +144,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio)
 	const int rw = bio_data_dir(bio);
 	int cpu;
 
-	if (unlikely(bio_barrier(bio))) {
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		bio_endio(bio, -EOPNOTSUPP);
 		return 0;
 	}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 898e2bd..f845ed9 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -448,7 +448,7 @@ static int raid0_make_request(struct request_queue *q, struct bio *bio)
 	const int rw = bio_data_dir(bio);
 	int cpu;
 
-	if (unlikely(bio_barrier(bio))) {
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		bio_endio(bio, -EOPNOTSUPP);
 		return 0;
 	}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 8726fd7..ff7ed33 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -782,8 +782,9 @@ static int make_request(struct request_queue *q, struct bio * bio)
 	struct bio_list bl;
 	struct page **behind_pages = NULL;
 	const int rw = bio_data_dir(bio);
-	const int do_sync = bio_sync(bio);
-	int cpu, do_barriers;
+	const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO);
+	int cpu;
+	bool do_barriers;
 	mdk_rdev_t *blocked_rdev;
 
 	/*
@@ -797,7 +798,8 @@ static int make_request(struct request_queue *q, struct bio * bio)
 
 	md_write_start(mddev, bio); /* wait on superblock update early */
 
-	if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
+	if (unlikely(!mddev->barriers_work &&
+		     bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		if (rw == WRITE)
 			md_write_end(mddev);
 		bio_endio(bio, -EOPNOTSUPP);
@@ -925,7 +927,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
 	atomic_set(&r1_bio->remaining, 0);
 	atomic_set(&r1_bio->behind_remaining, 0);
 
-	do_barriers = bio_barrier(bio);
+	do_barriers = bio_rw_flagged(bio, BIO_RW_BARRIER);
 	if (do_barriers)
 		set_bit(R1BIO_Barrier, &r1_bio->state);
 
@@ -1600,7 +1602,7 @@ static void raid1d(mddev_t *mddev)
 			 * We already have a nr_pending reference on these rdevs.
 			 */
 			int i;
-			const int do_sync = bio_sync(r1_bio->master_bio);
+			const bool do_sync = bio_rw_flagged(r1_bio->master_bio, BIO_RW_SYNCIO);
 			clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
 			clear_bit(R1BIO_Barrier, &r1_bio->state);
 			for (i=0; i < conf->raid_disks; i++)
@@ -1654,7 +1656,7 @@ static void raid1d(mddev_t *mddev)
 				       (unsigned long long)r1_bio->sector);
 				raid_end_bio_io(r1_bio);
 			} else {
-				const int do_sync = bio_sync(r1_bio->master_bio);
+				const bool do_sync = bio_rw_flagged(r1_bio->master_bio, BIO_RW_SYNCIO);
 				r1_bio->bios[r1_bio->read_disk] =
 					mddev->ro ? IO_BLOCKED : NULL;
 				r1_bio->read_disk = disk;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 3d9020c..d0a2152 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -796,12 +796,12 @@ static int make_request(struct request_queue *q, struct bio * bio)
 	int i;
 	int chunk_sects = conf->chunk_mask + 1;
 	const int rw = bio_data_dir(bio);
-	const int do_sync = bio_sync(bio);
+	const bool do_sync = bio_rw_flagged(bio, BIO_RW_SYNCIO);
 	struct bio_list bl;
 	unsigned long flags;
 	mdk_rdev_t *blocked_rdev;
 
-	if (unlikely(bio_barrier(bio))) {
+	if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) {
 		bio_endio(bio, -EOPNOTSUPP);
 		return 0;
 	}
@@ -1610,7 +1610,7 @@ static void raid10d(mddev_t *mddev)
 				raid_end_bio_io(r10_bio);
 				bio_put(bio);
 			} else {
-				const int do_sync = bio_sync(r10_bio->master_bio);
+				const bool do_sync = bio_rw_flagged(r10_bio->master_bio, BIO_RW_SYNCIO);
 				bio_put(bio);
 				rdev = conf->mirrors[mirror].rdev;
 				if (printk_ratelimit())
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index b8a2c5d..826eb34 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3606,7 +3606,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
 	const int rw = bio_data_dir(bi);
 	int cpu, remaining;
 
-	if (unlikely(bio_barrier(bi))) {
+	if (unlikely(bio_rw_flagged(bi, BIO_RW_BARRIER))) {
 		bio_endio(bi, -EOPNOTSUPP);
 		return 0;
 	}
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index 16792a6..655474b 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -58,13 +58,24 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
 /* -------------------------------------------------------------------------- */
 
 void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-		   int ir_type, IR_KEYTAB_TYPE *ir_codes)
+		   int ir_type, struct ir_scancode_table *ir_codes)
 {
 	int i;
 
 	ir->ir_type = ir_type;
+
+	memset(ir->ir_codes, sizeof(ir->ir_codes), 0);
+
+	/*
+	 * FIXME: This is a temporary workaround to use the new IR tables
+	 * with the old approach. Later patches will replace this to a
+	 * proper method
+	 */
+
 	if (ir_codes)
-		memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
+		for (i = 0; i < ir_codes->size; i++)
+			if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE)
+				ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode;
 
 	dev->keycode     = ir->ir_codes;
 	dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index 4216328..f679017 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1,8 +1,6 @@
 /*
-
-
-    Keytables for supported remote controls. This file is part of
-    video4linux.
+    Keytables for supported remote controls, used on drivers/media
+    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
@@ -17,7 +15,13 @@
     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.
+*/
 
+/*
+ * NOTICE FOR DEVELOPERS:
+ *   The IR mappings should be as close as possible to what's
+ *   specified at:
+ *      http://linuxtv.org/wiki/index.php/Remote_Controllers
  */
 #include <linux/module.h>
 
@@ -25,589 +29,627 @@
 #include <media/ir-common.h>
 
 /* empty keytable, can be used as placeholder for not-yet created keytables */
-IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
-	[ 0x2a ] = KEY_COFFEE,
+static struct ir_scancode ir_codes_empty[] = {
+	{ 0x2a, KEY_COFFEE },
 };
 
-EXPORT_SYMBOL_GPL(ir_codes_empty);
+struct ir_scancode_table ir_codes_empty_table = {
+	.scan = ir_codes_empty,
+	.size = ARRAY_SIZE(ir_codes_empty),
+};
+EXPORT_SYMBOL_GPL(ir_codes_empty_table);
 
 /* Michal Majchrowicz <mmajchrowicz@gmail.com> */
-IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_proteus_2309[] = {
 	/* numeric */
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x5c ] = KEY_POWER,     /* power       */
-	[ 0x20 ] = KEY_F,         /* full screen */
-	[ 0x0f ] = KEY_BACKSPACE, /* recall      */
-	[ 0x1b ] = KEY_ENTER,     /* mute        */
-	[ 0x41 ] = KEY_RECORD,    /* record      */
-	[ 0x43 ] = KEY_STOP,      /* stop        */
-	[ 0x16 ] = KEY_S,
-	[ 0x1a ] = KEY_Q,         /* off         */
-	[ 0x2e ] = KEY_RED,
-	[ 0x1f ] = KEY_DOWN,      /* channel -   */
-	[ 0x1c ] = KEY_UP,        /* channel +   */
-	[ 0x10 ] = KEY_LEFT,      /* volume -    */
-	[ 0x1e ] = KEY_RIGHT,     /* volume +    */
-	[ 0x14 ] = KEY_F1,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_proteus_2309);
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x5c, KEY_POWER },		/* power       */
+	{ 0x20, KEY_ZOOM },		/* full screen */
+	{ 0x0f, KEY_BACKSPACE },	/* recall      */
+	{ 0x1b, KEY_ENTER },		/* mute        */
+	{ 0x41, KEY_RECORD },		/* record      */
+	{ 0x43, KEY_STOP },		/* stop        */
+	{ 0x16, KEY_S },
+	{ 0x1a, KEY_POWER2 },		/* off         */
+	{ 0x2e, KEY_RED },
+	{ 0x1f, KEY_CHANNELDOWN },	/* channel -   */
+	{ 0x1c, KEY_CHANNELUP },	/* channel +   */
+	{ 0x10, KEY_VOLUMEDOWN },	/* volume -    */
+	{ 0x1e, KEY_VOLUMEUP },		/* volume +    */
+	{ 0x14, KEY_F1 },
+};
+
+struct ir_scancode_table ir_codes_proteus_2309_table = {
+	.scan = ir_codes_proteus_2309,
+	.size = ARRAY_SIZE(ir_codes_proteus_2309),
+};
+EXPORT_SYMBOL_GPL(ir_codes_proteus_2309_table);
+
 /* Matt Jesson <dvb@jesson.eclipse.co.uk */
-IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
-	[ 0x28 ] = KEY_0,         //'0' / 'enter'
-	[ 0x22 ] = KEY_1,         //'1'
-	[ 0x12 ] = KEY_2,         //'2' / 'up arrow'
-	[ 0x32 ] = KEY_3,         //'3'
-	[ 0x24 ] = KEY_4,         //'4' / 'left arrow'
-	[ 0x14 ] = KEY_5,         //'5'
-	[ 0x34 ] = KEY_6,         //'6' / 'right arrow'
-	[ 0x26 ] = KEY_7,         //'7'
-	[ 0x16 ] = KEY_8,         //'8' / 'down arrow'
-	[ 0x36 ] = KEY_9,         //'9'
-
-	[ 0x20 ] = KEY_LIST,        // 'source'
-	[ 0x10 ] = KEY_TEXT,        // 'teletext'
-	[ 0x00 ] = KEY_POWER,       // 'power'
-	[ 0x04 ] = KEY_AUDIO,       // 'audio'
-	[ 0x06 ] = KEY_ZOOM,        // 'full screen'
-	[ 0x18 ] = KEY_VIDEO,       // 'display'
-	[ 0x38 ] = KEY_SEARCH,      // 'loop'
-	[ 0x08 ] = KEY_INFO,        // 'preview'
-	[ 0x2a ] = KEY_REWIND,      // 'backward <<'
-	[ 0x1a ] = KEY_FASTFORWARD, // 'forward >>'
-	[ 0x3a ] = KEY_RECORD,      // 'capture'
-	[ 0x0a ] = KEY_MUTE,        // 'mute'
-	[ 0x2c ] = KEY_RECORD,      // 'record'
-	[ 0x1c ] = KEY_PAUSE,       // 'pause'
-	[ 0x3c ] = KEY_STOP,        // 'stop'
-	[ 0x0c ] = KEY_PLAY,        // 'play'
-	[ 0x2e ] = KEY_RED,         // 'red'
-	[ 0x01 ] = KEY_BLUE,        // 'blue' / 'cancel'
-	[ 0x0e ] = KEY_YELLOW,      // 'yellow' / 'ok'
-	[ 0x21 ] = KEY_GREEN,       // 'green'
-	[ 0x11 ] = KEY_CHANNELDOWN, // 'channel -'
-	[ 0x31 ] = KEY_CHANNELUP,   // 'channel +'
-	[ 0x1e ] = KEY_VOLUMEDOWN,  // 'volume -'
-	[ 0x3e ] = KEY_VOLUMEUP,    // 'volume +'
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt);
+static struct ir_scancode ir_codes_avermedia_dvbt[] = {
+	{ 0x28, KEY_0 },		/* '0' / 'enter' */
+	{ 0x22, KEY_1 },		/* '1' */
+	{ 0x12, KEY_2 },		/* '2' / 'up arrow' */
+	{ 0x32, KEY_3 },		/* '3' */
+	{ 0x24, KEY_4 },		/* '4' / 'left arrow' */
+	{ 0x14, KEY_5 },		/* '5' */
+	{ 0x34, KEY_6 },		/* '6' / 'right arrow' */
+	{ 0x26, KEY_7 },		/* '7' */
+	{ 0x16, KEY_8 },		/* '8' / 'down arrow' */
+	{ 0x36, KEY_9 },		/* '9' */
+
+	{ 0x20, KEY_LIST },		/* 'source' */
+	{ 0x10, KEY_TEXT },		/* 'teletext' */
+	{ 0x00, KEY_POWER },		/* 'power' */
+	{ 0x04, KEY_AUDIO },		/* 'audio' */
+	{ 0x06, KEY_ZOOM },		/* 'full screen' */
+	{ 0x18, KEY_VIDEO },		/* 'display' */
+	{ 0x38, KEY_SEARCH },		/* 'loop' */
+	{ 0x08, KEY_INFO },		/* 'preview' */
+	{ 0x2a, KEY_REWIND },		/* 'backward <<' */
+	{ 0x1a, KEY_FASTFORWARD },	/* 'forward >>' */
+	{ 0x3a, KEY_RECORD },		/* 'capture' */
+	{ 0x0a, KEY_MUTE },		/* 'mute' */
+	{ 0x2c, KEY_RECORD },		/* 'record' */
+	{ 0x1c, KEY_PAUSE },		/* 'pause' */
+	{ 0x3c, KEY_STOP },		/* 'stop' */
+	{ 0x0c, KEY_PLAY },		/* 'play' */
+	{ 0x2e, KEY_RED },		/* 'red' */
+	{ 0x01, KEY_BLUE },		/* 'blue' / 'cancel' */
+	{ 0x0e, KEY_YELLOW },		/* 'yellow' / 'ok' */
+	{ 0x21, KEY_GREEN },		/* 'green' */
+	{ 0x11, KEY_CHANNELDOWN },	/* 'channel -' */
+	{ 0x31, KEY_CHANNELUP },	/* 'channel +' */
+	{ 0x1e, KEY_VOLUMEDOWN },	/* 'volume -' */
+	{ 0x3e, KEY_VOLUMEUP },		/* 'volume +' */
+};
+
+struct ir_scancode_table ir_codes_avermedia_dvbt_table = {
+	.scan = ir_codes_avermedia_dvbt,
+	.size = ARRAY_SIZE(ir_codes_avermedia_dvbt),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_dvbt_table);
 
 /* Mauro Carvalho Chehab <mchehab@infradead.org> */
-IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = {
-	[0x00] = KEY_POWER2,
-	[0x2e] = KEY_DOT,		/* '.' */
-	[0x01] = KEY_MODE,		/* TV/FM */
-
-	[0x05] = KEY_1,
-	[0x06] = KEY_2,
-	[0x07] = KEY_3,
-	[0x09] = KEY_4,
-	[0x0a] = KEY_5,
-	[0x0b] = KEY_6,
-	[0x0d] = KEY_7,
-	[0x0e] = KEY_8,
-	[0x0f] = KEY_9,
-	[0x11] = KEY_0,
-
-	[0x13] = KEY_RIGHT,		/* -> */
-	[0x12] = KEY_LEFT,		/* <- */
-
-	[0x17] = KEY_SLEEP,		/* Capturar Imagem */
-	[0x10] = KEY_SHUFFLE,		/* Amostra */
+static struct ir_scancode ir_codes_avermedia_m135a[] = {
+	{ 0x00, KEY_POWER2 },
+	{ 0x2e, KEY_DOT },		/* '.' */
+	{ 0x01, KEY_MODE },		/* TV/FM */
+
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+	{ 0x11, KEY_0 },
+
+	{ 0x13, KEY_RIGHT },		/* -> */
+	{ 0x12, KEY_LEFT },		/* <- */
+
+	{ 0x17, KEY_SLEEP },		/* Capturar Imagem */
+	{ 0x10, KEY_SHUFFLE },		/* Amostra */
 
 	/* FIXME: The keys bellow aren't ok */
 
-	[0x43] = KEY_CHANNELUP,
-	[0x42] = KEY_CHANNELDOWN,
-	[0x1f] = KEY_VOLUMEUP,
-	[0x1e] = KEY_VOLUMEDOWN,
-	[0x0c] = KEY_ENTER,
+	{ 0x43, KEY_CHANNELUP },
+	{ 0x42, KEY_CHANNELDOWN },
+	{ 0x1f, KEY_VOLUMEUP },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x0c, KEY_ENTER },
 
-	[0x14] = KEY_MUTE,
-	[0x08] = KEY_AUDIO,
+	{ 0x14, KEY_MUTE },
+	{ 0x08, KEY_AUDIO },
 
-	[0x03] = KEY_TEXT,
-	[0x04] = KEY_EPG,
-	[0x2b] = KEY_TV2,		/* TV2 */
+	{ 0x03, KEY_TEXT },
+	{ 0x04, KEY_EPG },
+	{ 0x2b, KEY_TV2 },		/* TV2 */
 
-	[0x1d] = KEY_RED,
-	[0x1c] = KEY_YELLOW,
-	[0x41] = KEY_GREEN,
-	[0x40] = KEY_BLUE,
+	{ 0x1d, KEY_RED },
+	{ 0x1c, KEY_YELLOW },
+	{ 0x41, KEY_GREEN },
+	{ 0x40, KEY_BLUE },
 
-	[0x1a] = KEY_PLAYPAUSE,
-	[0x19] = KEY_RECORD,
-	[0x18] = KEY_PLAY,
-	[0x1b] = KEY_STOP,
+	{ 0x1a, KEY_PLAYPAUSE },
+	{ 0x19, KEY_RECORD },
+	{ 0x18, KEY_PLAY },
+	{ 0x1b, KEY_STOP },
 };
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a);
+
+struct ir_scancode_table ir_codes_avermedia_m135a_table = {
+	.scan = ir_codes_avermedia_m135a,
+	.size = ARRAY_SIZE(ir_codes_avermedia_m135a),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a_table);
 
 /* Oldrich Jedlicka <oldium.pro@seznam.cz> */
-IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = {
-	[0x00] = KEY_POWER,
-	[0x01] = KEY_TUNER,		/* TV/FM */
-	[0x03] = KEY_TEXT,		/* Teletext */
-	[0x04] = KEY_EPG,
-	[0x05] = KEY_1,
-	[0x06] = KEY_2,
-	[0x07] = KEY_3,
-	[0x08] = KEY_AUDIO,
-	[0x09] = KEY_4,
-	[0x0a] = KEY_5,
-	[0x0b] = KEY_6,
-	[0x0c] = KEY_ZOOM,		/* Full screen */
-	[0x0d] = KEY_7,
-	[0x0e] = KEY_8,
-	[0x0f] = KEY_9,
-	[0x10] = KEY_PAGEUP,		/* 16-CH PREV */
-	[0x11] = KEY_0,
-	[0x12] = KEY_INFO,
-	[0x13] = KEY_AGAIN,		/* CH RTN - channel return */
-	[0x14] = KEY_MUTE,
-	[0x15] = KEY_EDIT,		/* Autoscan */
-	[0x17] = KEY_SAVE,		/* Screenshot */
-	[0x18] = KEY_PLAYPAUSE,
-	[0x19] = KEY_RECORD,
-	[0x1a] = KEY_PLAY,
-	[0x1b] = KEY_STOP,
-	[0x1c] = KEY_FASTFORWARD,
-	[0x1d] = KEY_REWIND,
-	[0x1e] = KEY_VOLUMEDOWN,
-	[0x1f] = KEY_VOLUMEUP,
-	[0x22] = KEY_SLEEP,		/* Sleep */
-	[0x23] = KEY_ZOOM,		/* Aspect */
-	[0x26] = KEY_SCREEN,		/* Pos */
-	[0x27] = KEY_ANGLE,		/* Size */
-	[0x28] = KEY_SELECT,		/* Select */
-	[0x29] = KEY_BLUE,		/* Blue/Picture */
-	[0x2a] = KEY_BACKSPACE,	/* Back */
-	[0x2b] = KEY_MEDIA,		/* PIP (Picture-in-picture) */
-	[0x2c] = KEY_DOWN,
-	[0x2e] = KEY_DOT,
-	[0x2f] = KEY_TV,		/* Live TV */
-	[0x32] = KEY_LEFT,
-	[0x33] = KEY_CLEAR,		/* Clear */
-	[0x35] = KEY_RED,		/* Red/TV */
-	[0x36] = KEY_UP,
-	[0x37] = KEY_HOME,		/* Home */
-	[0x39] = KEY_GREEN,		/* Green/Video */
-	[0x3d] = KEY_YELLOW,		/* Yellow/Music */
-	[0x3e] = KEY_OK,		/* Ok */
-	[0x3f] = KEY_RIGHT,
-	[0x40] = KEY_NEXT,		/* Next */
-	[0x41] = KEY_PREVIOUS,	/* Previous */
-	[0x42] = KEY_CHANNELDOWN,	/* Channel down */
-	[0x43] = KEY_CHANNELUP	/* Channel up */
-};
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus);
+static struct ir_scancode ir_codes_avermedia_cardbus[] = {
+	{ 0x00, KEY_POWER },
+	{ 0x01, KEY_TUNER },		/* TV/FM */
+	{ 0x03, KEY_TEXT },		/* Teletext */
+	{ 0x04, KEY_EPG },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x08, KEY_AUDIO },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0c, KEY_ZOOM },		/* Full screen */
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+	{ 0x10, KEY_PAGEUP },		/* 16-CH PREV */
+	{ 0x11, KEY_0 },
+	{ 0x12, KEY_INFO },
+	{ 0x13, KEY_AGAIN },		/* CH RTN - channel return */
+	{ 0x14, KEY_MUTE },
+	{ 0x15, KEY_EDIT },		/* Autoscan */
+	{ 0x17, KEY_SAVE },		/* Screenshot */
+	{ 0x18, KEY_PLAYPAUSE },
+	{ 0x19, KEY_RECORD },
+	{ 0x1a, KEY_PLAY },
+	{ 0x1b, KEY_STOP },
+	{ 0x1c, KEY_FASTFORWARD },
+	{ 0x1d, KEY_REWIND },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x1f, KEY_VOLUMEUP },
+	{ 0x22, KEY_SLEEP },		/* Sleep */
+	{ 0x23, KEY_ZOOM },		/* Aspect */
+	{ 0x26, KEY_SCREEN },		/* Pos */
+	{ 0x27, KEY_ANGLE },		/* Size */
+	{ 0x28, KEY_SELECT },		/* Select */
+	{ 0x29, KEY_BLUE },		/* Blue/Picture */
+	{ 0x2a, KEY_BACKSPACE },	/* Back */
+	{ 0x2b, KEY_MEDIA },		/* PIP (Picture-in-picture) */
+	{ 0x2c, KEY_DOWN },
+	{ 0x2e, KEY_DOT },
+	{ 0x2f, KEY_TV },		/* Live TV */
+	{ 0x32, KEY_LEFT },
+	{ 0x33, KEY_CLEAR },		/* Clear */
+	{ 0x35, KEY_RED },		/* Red/TV */
+	{ 0x36, KEY_UP },
+	{ 0x37, KEY_HOME },		/* Home */
+	{ 0x39, KEY_GREEN },		/* Green/Video */
+	{ 0x3d, KEY_YELLOW },		/* Yellow/Music */
+	{ 0x3e, KEY_OK },		/* Ok */
+	{ 0x3f, KEY_RIGHT },
+	{ 0x40, KEY_NEXT },		/* Next */
+	{ 0x41, KEY_PREVIOUS },		/* Previous */
+	{ 0x42, KEY_CHANNELDOWN },	/* Channel down */
+	{ 0x43, KEY_CHANNELUP },	/* Channel up */
+};
+
+struct ir_scancode_table ir_codes_avermedia_cardbus_table = {
+	.scan = ir_codes_avermedia_cardbus,
+	.size = ARRAY_SIZE(ir_codes_avermedia_cardbus),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus_table);
 
 /* Attila Kondoros <attila.kondoros@chello.hu> */
-IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
-
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-	[ 0x00 ] = KEY_0,
-	[ 0x17 ] = KEY_LAST,        // +100
-	[ 0x0a ] = KEY_LIST,        // recall
-
-
-	[ 0x1c ] = KEY_TUNER,       // TV/FM
-	[ 0x15 ] = KEY_SEARCH,      // scan
-	[ 0x12 ] = KEY_POWER,       // power
-	[ 0x1f ] = KEY_VOLUMEDOWN,  // vol up
-	[ 0x1b ] = KEY_VOLUMEUP,    // vol down
-	[ 0x1e ] = KEY_CHANNELDOWN, // chn up
-	[ 0x1a ] = KEY_CHANNELUP,   // chn down
-
-	[ 0x11 ] = KEY_VIDEO,       // video
-	[ 0x0f ] = KEY_ZOOM,        // full screen
-	[ 0x13 ] = KEY_MUTE,        // mute/unmute
-	[ 0x10 ] = KEY_TEXT,        // min
-
-	[ 0x0d ] = KEY_STOP,        // freeze
-	[ 0x0e ] = KEY_RECORD,      // record
-	[ 0x1d ] = KEY_PLAYPAUSE,   // stop
-	[ 0x19 ] = KEY_PLAY,        // play
-
-	[ 0x16 ] = KEY_GOTO,        // osd
-	[ 0x14 ] = KEY_REFRESH,     // default
-	[ 0x0c ] = KEY_KPPLUS,      // fine tune >>>>
-	[ 0x18 ] = KEY_KPMINUS      // fine tune <<<<
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp);
+static struct ir_scancode ir_codes_apac_viewcomp[] = {
+
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x00, KEY_0 },
+	{ 0x17, KEY_LAST },		/* +100 */
+	{ 0x0a, KEY_LIST },		/* recall */
+
+
+	{ 0x1c, KEY_TUNER },		/* TV/FM */
+	{ 0x15, KEY_SEARCH },		/* scan */
+	{ 0x12, KEY_POWER },		/* power */
+	{ 0x1f, KEY_VOLUMEDOWN },	/* vol up */
+	{ 0x1b, KEY_VOLUMEUP },		/* vol down */
+	{ 0x1e, KEY_CHANNELDOWN },	/* chn up */
+	{ 0x1a, KEY_CHANNELUP },	/* chn down */
+
+	{ 0x11, KEY_VIDEO },		/* video */
+	{ 0x0f, KEY_ZOOM },		/* full screen */
+	{ 0x13, KEY_MUTE },		/* mute/unmute */
+	{ 0x10, KEY_TEXT },		/* min */
+
+	{ 0x0d, KEY_STOP },		/* freeze */
+	{ 0x0e, KEY_RECORD },		/* record */
+	{ 0x1d, KEY_PLAYPAUSE },	/* stop */
+	{ 0x19, KEY_PLAY },		/* play */
+
+	{ 0x16, KEY_GOTO },		/* osd */
+	{ 0x14, KEY_REFRESH },		/* default */
+	{ 0x0c, KEY_KPPLUS },		/* fine tune >>>> */
+	{ 0x18, KEY_KPMINUS },		/* fine tune <<<< */
+};
+
+struct ir_scancode_table ir_codes_apac_viewcomp_table = {
+	.scan = ir_codes_apac_viewcomp,
+	.size = ARRAY_SIZE(ir_codes_apac_viewcomp),
+};
+EXPORT_SYMBOL_GPL(ir_codes_apac_viewcomp_table);
 
 /* ---------------------------------------------------------------------- */
 
-IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_pixelview[] = {
 
-	[ 0x1e ] = KEY_POWER,       // power
-	[ 0x07 ] = KEY_MEDIA,       // source
-	[ 0x1c ] = KEY_SEARCH,      // scan
+	{ 0x1e, KEY_POWER },	/* power */
+	{ 0x07, KEY_MEDIA },	/* source */
+	{ 0x1c, KEY_SEARCH },	/* scan */
 
-/* FIXME: duplicate keycodes?
- *
- * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
- * The GPIO values are
- * 6397fb for both "Scan <" and "CH -",
- * 639ffb for "Scan >" and "CH+",
- * 6384fb for "Tune <" and "<<<",
- * 638cfb for "Tune >" and ">>>", regardless of the mask.
- *
- *	[ 0x17 ] = KEY_BACK,        // fm scan <<
- *	[ 0x1f ] = KEY_FORWARD,     // fm scan >>
- *
- *	[ 0x04 ] = KEY_LEFT,        // fm tuning <
- *	[ 0x0c ] = KEY_RIGHT,       // fm tuning >
- *
- * For now, these four keys are disabled. Pressing them will generate
- * the CH+/CH-/<<</>>> events
- */
 
-	[ 0x03 ] = KEY_TUNER,       // TV/FM
+	{ 0x03, KEY_TUNER },		/* TV/FM */
 
-	[ 0x00 ] = KEY_RECORD,
-	[ 0x08 ] = KEY_STOP,
-	[ 0x11 ] = KEY_PLAY,
+	{ 0x00, KEY_RECORD },
+	{ 0x08, KEY_STOP },
+	{ 0x11, KEY_PLAY },
 
-	[ 0x1a ] = KEY_PLAYPAUSE,   // freeze
-	[ 0x19 ] = KEY_ZOOM,        // zoom
-	[ 0x0f ] = KEY_TEXT,        // min
+	{ 0x1a, KEY_PLAYPAUSE },	/* freeze */
+	{ 0x19, KEY_ZOOM },		/* zoom */
+	{ 0x0f, KEY_TEXT },		/* min */
 
-	[ 0x01 ] = KEY_1,
-	[ 0x0b ] = KEY_2,
-	[ 0x1b ] = KEY_3,
-	[ 0x05 ] = KEY_4,
-	[ 0x09 ] = KEY_5,
-	[ 0x15 ] = KEY_6,
-	[ 0x06 ] = KEY_7,
-	[ 0x0a ] = KEY_8,
-	[ 0x12 ] = KEY_9,
-	[ 0x02 ] = KEY_0,
-	[ 0x10 ] = KEY_LAST,        // +100
-	[ 0x13 ] = KEY_LIST,        // recall
+	{ 0x01, KEY_1 },
+	{ 0x0b, KEY_2 },
+	{ 0x1b, KEY_3 },
+	{ 0x05, KEY_4 },
+	{ 0x09, KEY_5 },
+	{ 0x15, KEY_6 },
+	{ 0x06, KEY_7 },
+	{ 0x0a, KEY_8 },
+	{ 0x12, KEY_9 },
+	{ 0x02, KEY_0 },
+	{ 0x10, KEY_LAST },		/* +100 */
+	{ 0x13, KEY_LIST },		/* recall */
 
-	[ 0x1f ] = KEY_CHANNELUP,   // chn down
-	[ 0x17 ] = KEY_CHANNELDOWN, // chn up
-	[ 0x16 ] = KEY_VOLUMEUP,    // vol down
-	[ 0x14 ] = KEY_VOLUMEDOWN,  // vol up
+	{ 0x1f, KEY_CHANNELUP },	/* chn down */
+	{ 0x17, KEY_CHANNELDOWN },	/* chn up */
+	{ 0x16, KEY_VOLUMEUP },		/* vol down */
+	{ 0x14, KEY_VOLUMEDOWN },	/* vol up */
 
-	[ 0x04 ] = KEY_KPMINUS,     // <<<
-	[ 0x0e ] = KEY_SETUP,       // function
-	[ 0x0c ] = KEY_KPPLUS,      // >>>
+	{ 0x04, KEY_KPMINUS },		/* <<< */
+	{ 0x0e, KEY_SETUP },		/* function */
+	{ 0x0c, KEY_KPPLUS },		/* >>> */
 
-	[ 0x0d ] = KEY_GOTO,        // mts
-	[ 0x1d ] = KEY_REFRESH,     // reset
-	[ 0x18 ] = KEY_MUTE         // mute/unmute
+	{ 0x0d, KEY_GOTO },		/* mts */
+	{ 0x1d, KEY_REFRESH },		/* reset */
+	{ 0x18, KEY_MUTE },		/* mute/unmute */
 };
 
-EXPORT_SYMBOL_GPL(ir_codes_pixelview);
+struct ir_scancode_table ir_codes_pixelview_table = {
+	.scan = ir_codes_pixelview,
+	.size = ARRAY_SIZE(ir_codes_pixelview),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pixelview_table);
 
 /*
    Mauro Carvalho Chehab <mchehab@infradead.org>
    present on PV MPEG 8000GT
  */
-IR_KEYTAB_TYPE ir_codes_pixelview_new[IR_KEYTAB_SIZE] = {
-	[0x3c] = KEY_PAUSE,		/* Timeshift */
-	[0x12] = KEY_POWER,
-
-	[0x3d] = KEY_1,
-	[0x38] = KEY_2,
-	[0x18] = KEY_3,
-	[0x35] = KEY_4,
-	[0x39] = KEY_5,
-	[0x15] = KEY_6,
-	[0x36] = KEY_7,
-	[0x3a] = KEY_8,
-	[0x1e] = KEY_9,
-	[0x3e] = KEY_0,
-
-	[0x1c] = KEY_AGAIN,		/* LOOP	*/
-	[0x3f] = KEY_MEDIA,		/* Source */
-	[0x1f] = KEY_LAST,		/* +100 */
-	[0x1b] = KEY_MUTE,
-
-	[0x17] = KEY_CHANNELDOWN,
-	[0x16] = KEY_CHANNELUP,
-	[0x10] = KEY_VOLUMEUP,
-	[0x14] = KEY_VOLUMEDOWN,
-	[0x13] = KEY_ZOOM,
-
-	[0x19] = KEY_SHUFFLE,		/* SNAPSHOT */
-	[0x1a] = KEY_SEARCH,		/* scan */
-
-	[0x37] = KEY_REWIND,		/* << */
-	[0x32] = KEY_RECORD,		/* o (red) */
-	[0x33] = KEY_FORWARD,		/* >> */
-	[0x11] = KEY_STOP,		/* square */
-	[0x3b] = KEY_PLAY,		/* > */
-	[0x30] = KEY_PLAYPAUSE,		/* || */
-
-	[0x31] = KEY_TV,
-	[0x34] = KEY_RADIO,
-};
-EXPORT_SYMBOL_GPL(ir_codes_pixelview_new);
-
-IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-	[ 0x0a ] = KEY_TV,
-	[ 0x0b ] = KEY_AUX,
-	[ 0x0c ] = KEY_DVD,
-	[ 0x0d ] = KEY_POWER,
-	[ 0x0e ] = KEY_MHP,	/* labelled 'Picture' */
-	[ 0x0f ] = KEY_AUDIO,
-	[ 0x10 ] = KEY_INFO,
-	[ 0x11 ] = KEY_F13,	/* 16:9 */
-	[ 0x12 ] = KEY_F14,	/* 14:9 */
-	[ 0x13 ] = KEY_EPG,
-	[ 0x14 ] = KEY_EXIT,
-	[ 0x15 ] = KEY_MENU,
-	[ 0x16 ] = KEY_UP,
-	[ 0x17 ] = KEY_DOWN,
-	[ 0x18 ] = KEY_LEFT,
-	[ 0x19 ] = KEY_RIGHT,
-	[ 0x1a ] = KEY_ENTER,
-	[ 0x1b ] = KEY_CHANNELUP,
-	[ 0x1c ] = KEY_CHANNELDOWN,
-	[ 0x1d ] = KEY_VOLUMEUP,
-	[ 0x1e ] = KEY_VOLUMEDOWN,
-	[ 0x1f ] = KEY_RED,
-	[ 0x20 ] = KEY_GREEN,
-	[ 0x21 ] = KEY_YELLOW,
-	[ 0x22 ] = KEY_BLUE,
-	[ 0x23 ] = KEY_SUBTITLE,
-	[ 0x24 ] = KEY_F15,	/* AD */
-	[ 0x25 ] = KEY_TEXT,
-	[ 0x26 ] = KEY_MUTE,
-	[ 0x27 ] = KEY_REWIND,
-	[ 0x28 ] = KEY_STOP,
-	[ 0x29 ] = KEY_PLAY,
-	[ 0x2a ] = KEY_FASTFORWARD,
-	[ 0x2b ] = KEY_F16,	/* chapter */
-	[ 0x2c ] = KEY_PAUSE,
-	[ 0x2d ] = KEY_PLAY,
-	[ 0x2e ] = KEY_RECORD,
-	[ 0x2f ] = KEY_F17,	/* picture in picture */
-	[ 0x30 ] = KEY_KPPLUS,	/* zoom in */
-	[ 0x31 ] = KEY_KPMINUS,	/* zoom out */
-	[ 0x32 ] = KEY_F18,	/* capture */
-	[ 0x33 ] = KEY_F19,	/* web */
-	[ 0x34 ] = KEY_EMAIL,
-	[ 0x35 ] = KEY_PHONE,
-	[ 0x36 ] = KEY_PC
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_nebula);
+static struct ir_scancode ir_codes_pixelview_new[] = {
+	{ 0x3c, KEY_TIME },		/* Timeshift */
+	{ 0x12, KEY_POWER },
+
+	{ 0x3d, KEY_1 },
+	{ 0x38, KEY_2 },
+	{ 0x18, KEY_3 },
+	{ 0x35, KEY_4 },
+	{ 0x39, KEY_5 },
+	{ 0x15, KEY_6 },
+	{ 0x36, KEY_7 },
+	{ 0x3a, KEY_8 },
+	{ 0x1e, KEY_9 },
+	{ 0x3e, KEY_0 },
+
+	{ 0x1c, KEY_AGAIN },		/* LOOP	*/
+	{ 0x3f, KEY_MEDIA },		/* Source */
+	{ 0x1f, KEY_LAST },		/* +100 */
+	{ 0x1b, KEY_MUTE },
+
+	{ 0x17, KEY_CHANNELDOWN },
+	{ 0x16, KEY_CHANNELUP },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x14, KEY_VOLUMEDOWN },
+	{ 0x13, KEY_ZOOM },
+
+	{ 0x19, KEY_CAMERA },		/* SNAPSHOT */
+	{ 0x1a, KEY_SEARCH },		/* scan */
+
+	{ 0x37, KEY_REWIND },		/* << */
+	{ 0x32, KEY_RECORD },		/* o (red) */
+	{ 0x33, KEY_FORWARD },		/* >> */
+	{ 0x11, KEY_STOP },		/* square */
+	{ 0x3b, KEY_PLAY },		/* > */
+	{ 0x30, KEY_PLAYPAUSE },	/* || */
+
+	{ 0x31, KEY_TV },
+	{ 0x34, KEY_RADIO },
+};
+
+struct ir_scancode_table ir_codes_pixelview_new_table = {
+	.scan = ir_codes_pixelview_new,
+	.size = ARRAY_SIZE(ir_codes_pixelview_new),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pixelview_new_table);
+
+static struct ir_scancode ir_codes_nebula[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0a, KEY_TV },
+	{ 0x0b, KEY_AUX },
+	{ 0x0c, KEY_DVD },
+	{ 0x0d, KEY_POWER },
+	{ 0x0e, KEY_MHP },	/* labelled 'Picture' */
+	{ 0x0f, KEY_AUDIO },
+	{ 0x10, KEY_INFO },
+	{ 0x11, KEY_F13 },	/* 16:9 */
+	{ 0x12, KEY_F14 },	/* 14:9 */
+	{ 0x13, KEY_EPG },
+	{ 0x14, KEY_EXIT },
+	{ 0x15, KEY_MENU },
+	{ 0x16, KEY_UP },
+	{ 0x17, KEY_DOWN },
+	{ 0x18, KEY_LEFT },
+	{ 0x19, KEY_RIGHT },
+	{ 0x1a, KEY_ENTER },
+	{ 0x1b, KEY_CHANNELUP },
+	{ 0x1c, KEY_CHANNELDOWN },
+	{ 0x1d, KEY_VOLUMEUP },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x1f, KEY_RED },
+	{ 0x20, KEY_GREEN },
+	{ 0x21, KEY_YELLOW },
+	{ 0x22, KEY_BLUE },
+	{ 0x23, KEY_SUBTITLE },
+	{ 0x24, KEY_F15 },	/* AD */
+	{ 0x25, KEY_TEXT },
+	{ 0x26, KEY_MUTE },
+	{ 0x27, KEY_REWIND },
+	{ 0x28, KEY_STOP },
+	{ 0x29, KEY_PLAY },
+	{ 0x2a, KEY_FASTFORWARD },
+	{ 0x2b, KEY_F16 },	/* chapter */
+	{ 0x2c, KEY_PAUSE },
+	{ 0x2d, KEY_PLAY },
+	{ 0x2e, KEY_RECORD },
+	{ 0x2f, KEY_F17 },	/* picture in picture */
+	{ 0x30, KEY_KPPLUS },	/* zoom in */
+	{ 0x31, KEY_KPMINUS },	/* zoom out */
+	{ 0x32, KEY_F18 },	/* capture */
+	{ 0x33, KEY_F19 },	/* web */
+	{ 0x34, KEY_EMAIL },
+	{ 0x35, KEY_PHONE },
+	{ 0x36, KEY_PC },
+};
+
+struct ir_scancode_table ir_codes_nebula_table = {
+	.scan = ir_codes_nebula,
+	.size = ARRAY_SIZE(ir_codes_nebula),
+};
+EXPORT_SYMBOL_GPL(ir_codes_nebula_table);
 
 /* DigitalNow DNTV Live DVB-T Remote */
-IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_ESC,		/* 'go up a level?' */
+static struct ir_scancode ir_codes_dntv_live_dvb_t[] = {
+	{ 0x00, KEY_ESC },		/* 'go up a level?' */
 	/* Keys 0 to 9 */
-	[ 0x0a ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x0b ] = KEY_TUNER,		/* tv/fm */
-	[ 0x0c ] = KEY_SEARCH,		/* scan */
-	[ 0x0d ] = KEY_STOP,
-	[ 0x0e ] = KEY_PAUSE,
-	[ 0x0f ] = KEY_LIST,		/* source */
-
-	[ 0x10 ] = KEY_MUTE,
-	[ 0x11 ] = KEY_REWIND,		/* backward << */
-	[ 0x12 ] = KEY_POWER,
-	[ 0x13 ] = KEY_S,			/* snap */
-	[ 0x14 ] = KEY_AUDIO,		/* stereo */
-	[ 0x15 ] = KEY_CLEAR,		/* reset */
-	[ 0x16 ] = KEY_PLAY,
-	[ 0x17 ] = KEY_ENTER,
-	[ 0x18 ] = KEY_ZOOM,		/* full screen */
-	[ 0x19 ] = KEY_FASTFORWARD,	/* forward >> */
-	[ 0x1a ] = KEY_CHANNELUP,
-	[ 0x1b ] = KEY_VOLUMEUP,
-	[ 0x1c ] = KEY_INFO,		/* preview */
-	[ 0x1d ] = KEY_RECORD,		/* record */
-	[ 0x1e ] = KEY_CHANNELDOWN,
-	[ 0x1f ] = KEY_VOLUMEDOWN,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t);
+	{ 0x0a, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0b, KEY_TUNER },		/* tv/fm */
+	{ 0x0c, KEY_SEARCH },		/* scan */
+	{ 0x0d, KEY_STOP },
+	{ 0x0e, KEY_PAUSE },
+	{ 0x0f, KEY_LIST },		/* source */
+
+	{ 0x10, KEY_MUTE },
+	{ 0x11, KEY_REWIND },		/* backward << */
+	{ 0x12, KEY_POWER },
+	{ 0x13, KEY_CAMERA },		/* snap */
+	{ 0x14, KEY_AUDIO },		/* stereo */
+	{ 0x15, KEY_CLEAR },		/* reset */
+	{ 0x16, KEY_PLAY },
+	{ 0x17, KEY_ENTER },
+	{ 0x18, KEY_ZOOM },		/* full screen */
+	{ 0x19, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1c, KEY_INFO },		/* preview */
+	{ 0x1d, KEY_RECORD },		/* record */
+	{ 0x1e, KEY_CHANNELDOWN },
+	{ 0x1f, KEY_VOLUMEDOWN },
+};
+
+struct ir_scancode_table ir_codes_dntv_live_dvb_t_table = {
+	.scan = ir_codes_dntv_live_dvb_t,
+	.size = ARRAY_SIZE(ir_codes_dntv_live_dvb_t),
+};
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvb_t_table);
 
 /* ---------------------------------------------------------------------- */
 
 /* IO-DATA BCTV7E Remote */
-IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE] = {
-	[ 0x40 ] = KEY_TV,
-	[ 0x20 ] = KEY_RADIO,		/* FM */
-	[ 0x60 ] = KEY_EPG,
-	[ 0x00 ] = KEY_POWER,
+static struct ir_scancode ir_codes_iodata_bctv7e[] = {
+	{ 0x40, KEY_TV },
+	{ 0x20, KEY_RADIO },		/* FM */
+	{ 0x60, KEY_EPG },
+	{ 0x00, KEY_POWER },
 
 	/* Keys 0 to 9 */
-	[ 0x44 ] = KEY_0,		/* 10 */
-	[ 0x50 ] = KEY_1,
-	[ 0x30 ] = KEY_2,
-	[ 0x70 ] = KEY_3,
-	[ 0x48 ] = KEY_4,
-	[ 0x28 ] = KEY_5,
-	[ 0x68 ] = KEY_6,
-	[ 0x58 ] = KEY_7,
-	[ 0x38 ] = KEY_8,
-	[ 0x78 ] = KEY_9,
-
-	[ 0x10 ] = KEY_L,			/* Live */
-	[ 0x08 ] = KEY_T,			/* Time Shift */
-
-	[ 0x18 ] = KEY_PLAYPAUSE,		/* Play */
-
-	[ 0x24 ] = KEY_ENTER,		/* 11 */
-	[ 0x64 ] = KEY_ESC,		/* 12 */
-	[ 0x04 ] = KEY_M,			/* Multi */
-
-	[ 0x54 ] = KEY_VIDEO,
-	[ 0x34 ] = KEY_CHANNELUP,
-	[ 0x74 ] = KEY_VOLUMEUP,
-	[ 0x14 ] = KEY_MUTE,
-
-	[ 0x4c ] = KEY_S,			/* SVIDEO */
-	[ 0x2c ] = KEY_CHANNELDOWN,
-	[ 0x6c ] = KEY_VOLUMEDOWN,
-	[ 0x0c ] = KEY_ZOOM,
-
-	[ 0x5c ] = KEY_PAUSE,
-	[ 0x3c ] = KEY_C,			/* || (red) */
-	[ 0x7c ] = KEY_RECORD,		/* recording */
-	[ 0x1c ] = KEY_STOP,
-
-	[ 0x41 ] = KEY_REWIND,		/* backward << */
-	[ 0x21 ] = KEY_PLAY,
-	[ 0x61 ] = KEY_FASTFORWARD,	/* forward >> */
-	[ 0x01 ] = KEY_NEXT,		/* skip >| */
+	{ 0x44, KEY_0 },		/* 10 */
+	{ 0x50, KEY_1 },
+	{ 0x30, KEY_2 },
+	{ 0x70, KEY_3 },
+	{ 0x48, KEY_4 },
+	{ 0x28, KEY_5 },
+	{ 0x68, KEY_6 },
+	{ 0x58, KEY_7 },
+	{ 0x38, KEY_8 },
+	{ 0x78, KEY_9 },
+
+	{ 0x10, KEY_L },		/* Live */
+	{ 0x08, KEY_TIME },		/* Time Shift */
+
+	{ 0x18, KEY_PLAYPAUSE },	/* Play */
+
+	{ 0x24, KEY_ENTER },		/* 11 */
+	{ 0x64, KEY_ESC },		/* 12 */
+	{ 0x04, KEY_M },		/* Multi */
+
+	{ 0x54, KEY_VIDEO },
+	{ 0x34, KEY_CHANNELUP },
+	{ 0x74, KEY_VOLUMEUP },
+	{ 0x14, KEY_MUTE },
+
+	{ 0x4c, KEY_VCR },		/* SVIDEO */
+	{ 0x2c, KEY_CHANNELDOWN },
+	{ 0x6c, KEY_VOLUMEDOWN },
+	{ 0x0c, KEY_ZOOM },
+
+	{ 0x5c, KEY_PAUSE },
+	{ 0x3c, KEY_RED },		/* || (red) */
+	{ 0x7c, KEY_RECORD },		/* recording */
+	{ 0x1c, KEY_STOP },
+
+	{ 0x41, KEY_REWIND },		/* backward << */
+	{ 0x21, KEY_PLAY },
+	{ 0x61, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x01, KEY_NEXT },		/* skip >| */
 };
 
-EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e);
+struct ir_scancode_table ir_codes_iodata_bctv7e_table = {
+	.scan = ir_codes_iodata_bctv7e,
+	.size = ARRAY_SIZE(ir_codes_iodata_bctv7e),
+};
+EXPORT_SYMBOL_GPL(ir_codes_iodata_bctv7e_table);
 
 /* ---------------------------------------------------------------------- */
 
 /* ADS Tech Instant TV DVB-T PCI Remote */
-IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_adstech_dvb_t_pci[] = {
 	/* Keys 0 to 9 */
-	[ 0x4d ] = KEY_0,
-	[ 0x57 ] = KEY_1,
-	[ 0x4f ] = KEY_2,
-	[ 0x53 ] = KEY_3,
-	[ 0x56 ] = KEY_4,
-	[ 0x4e ] = KEY_5,
-	[ 0x5e ] = KEY_6,
-	[ 0x54 ] = KEY_7,
-	[ 0x4c ] = KEY_8,
-	[ 0x5c ] = KEY_9,
-
-	[ 0x5b ] = KEY_POWER,
-	[ 0x5f ] = KEY_MUTE,
-	[ 0x55 ] = KEY_GOTO,
-	[ 0x5d ] = KEY_SEARCH,
-	[ 0x17 ] = KEY_EPG,		/* Guide */
-	[ 0x1f ] = KEY_MENU,
-	[ 0x0f ] = KEY_UP,
-	[ 0x46 ] = KEY_DOWN,
-	[ 0x16 ] = KEY_LEFT,
-	[ 0x1e ] = KEY_RIGHT,
-	[ 0x0e ] = KEY_SELECT,		/* Enter */
-	[ 0x5a ] = KEY_INFO,
-	[ 0x52 ] = KEY_EXIT,
-	[ 0x59 ] = KEY_PREVIOUS,
-	[ 0x51 ] = KEY_NEXT,
-	[ 0x58 ] = KEY_REWIND,
-	[ 0x50 ] = KEY_FORWARD,
-	[ 0x44 ] = KEY_PLAYPAUSE,
-	[ 0x07 ] = KEY_STOP,
-	[ 0x1b ] = KEY_RECORD,
-	[ 0x13 ] = KEY_TUNER,		/* Live */
-	[ 0x0a ] = KEY_A,
-	[ 0x12 ] = KEY_B,
-	[ 0x03 ] = KEY_PROG1,		/* 1 */
-	[ 0x01 ] = KEY_PROG2,		/* 2 */
-	[ 0x00 ] = KEY_PROG3,		/* 3 */
-	[ 0x06 ] = KEY_DVD,
-	[ 0x48 ] = KEY_AUX,		/* Photo */
-	[ 0x40 ] = KEY_VIDEO,
-	[ 0x19 ] = KEY_AUDIO,		/* Music */
-	[ 0x0b ] = KEY_CHANNELUP,
-	[ 0x08 ] = KEY_CHANNELDOWN,
-	[ 0x15 ] = KEY_VOLUMEUP,
-	[ 0x1c ] = KEY_VOLUMEDOWN,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci);
+	{ 0x4d, KEY_0 },
+	{ 0x57, KEY_1 },
+	{ 0x4f, KEY_2 },
+	{ 0x53, KEY_3 },
+	{ 0x56, KEY_4 },
+	{ 0x4e, KEY_5 },
+	{ 0x5e, KEY_6 },
+	{ 0x54, KEY_7 },
+	{ 0x4c, KEY_8 },
+	{ 0x5c, KEY_9 },
+
+	{ 0x5b, KEY_POWER },
+	{ 0x5f, KEY_MUTE },
+	{ 0x55, KEY_GOTO },
+	{ 0x5d, KEY_SEARCH },
+	{ 0x17, KEY_EPG },		/* Guide */
+	{ 0x1f, KEY_MENU },
+	{ 0x0f, KEY_UP },
+	{ 0x46, KEY_DOWN },
+	{ 0x16, KEY_LEFT },
+	{ 0x1e, KEY_RIGHT },
+	{ 0x0e, KEY_SELECT },		/* Enter */
+	{ 0x5a, KEY_INFO },
+	{ 0x52, KEY_EXIT },
+	{ 0x59, KEY_PREVIOUS },
+	{ 0x51, KEY_NEXT },
+	{ 0x58, KEY_REWIND },
+	{ 0x50, KEY_FORWARD },
+	{ 0x44, KEY_PLAYPAUSE },
+	{ 0x07, KEY_STOP },
+	{ 0x1b, KEY_RECORD },
+	{ 0x13, KEY_TUNER },		/* Live */
+	{ 0x0a, KEY_A },
+	{ 0x12, KEY_B },
+	{ 0x03, KEY_PROG1 },		/* 1 */
+	{ 0x01, KEY_PROG2 },		/* 2 */
+	{ 0x00, KEY_PROG3 },		/* 3 */
+	{ 0x06, KEY_DVD },
+	{ 0x48, KEY_AUX },		/* Photo */
+	{ 0x40, KEY_VIDEO },
+	{ 0x19, KEY_AUDIO },		/* Music */
+	{ 0x0b, KEY_CHANNELUP },
+	{ 0x08, KEY_CHANNELDOWN },
+	{ 0x15, KEY_VOLUMEUP },
+	{ 0x1c, KEY_VOLUMEDOWN },
+};
+
+struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table = {
+	.scan = ir_codes_adstech_dvb_t_pci,
+	.size = ARRAY_SIZE(ir_codes_adstech_dvb_t_pci),
+};
+EXPORT_SYMBOL_GPL(ir_codes_adstech_dvb_t_pci_table);
 
 /* ---------------------------------------------------------------------- */
 
 /* MSI TV@nywhere MASTER remote */
 
-IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_msi_tvanywhere[] = {
 	/* Keys 0 to 9 */
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x0c ] = KEY_MUTE,
-	[ 0x0f ] = KEY_SCREEN,		/* Full Screen */
-	[ 0x10 ] = KEY_F,			/* Funtion */
-	[ 0x11 ] = KEY_T,			/* Time shift */
-	[ 0x12 ] = KEY_POWER,
-	[ 0x13 ] = KEY_MEDIA,		/* MTS */
-	[ 0x14 ] = KEY_SLOW,
-	[ 0x16 ] = KEY_REWIND,		/* backward << */
-	[ 0x17 ] = KEY_ENTER,		/* Return */
-	[ 0x18 ] = KEY_FASTFORWARD,	/* forward >> */
-	[ 0x1a ] = KEY_CHANNELUP,
-	[ 0x1b ] = KEY_VOLUMEUP,
-	[ 0x1e ] = KEY_CHANNELDOWN,
-	[ 0x1f ] = KEY_VOLUMEDOWN,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere);
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0c, KEY_MUTE },
+	{ 0x0f, KEY_SCREEN },		/* Full Screen */
+	{ 0x10, KEY_FN },		/* Funtion */
+	{ 0x11, KEY_TIME },		/* Time shift */
+	{ 0x12, KEY_POWER },
+	{ 0x13, KEY_MEDIA },		/* MTS */
+	{ 0x14, KEY_SLOW },
+	{ 0x16, KEY_REWIND },		/* backward << */
+	{ 0x17, KEY_ENTER },		/* Return */
+	{ 0x18, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1e, KEY_CHANNELDOWN },
+	{ 0x1f, KEY_VOLUMEDOWN },
+};
+
+struct ir_scancode_table ir_codes_msi_tvanywhere_table = {
+	.scan = ir_codes_msi_tvanywhere,
+	.size = ARRAY_SIZE(ir_codes_msi_tvanywhere),
+};
+EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_table);
 
 /* ---------------------------------------------------------------------- */
 
@@ -626,7 +668,7 @@ EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere);
 
 */
 
-IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_msi_tvanywhere_plus[] = {
 
 /*  ---- Remote Button Layout ----
 
@@ -648,596 +690,645 @@ IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE] = {
      <<      FUNC    >>     RESET
 */
 
-	[0x01] = KEY_KP1,             /* 1 */
-	[0x0b] = KEY_KP2,             /* 2 */
-	[0x1b] = KEY_KP3,             /* 3 */
-	[0x05] = KEY_KP4,             /* 4 */
-	[0x09] = KEY_KP5,             /* 5 */
-	[0x15] = KEY_KP6,             /* 6 */
-	[0x06] = KEY_KP7,             /* 7 */
-	[0x0a] = KEY_KP8,             /* 8 */
-	[0x12] = KEY_KP9,             /* 9 */
-	[0x02] = KEY_KP0,             /* 0 */
-	[0x10] = KEY_KPPLUS,          /* + */
-	[0x13] = KEY_AGAIN,           /* Recall */
-
-	[0x1e] = KEY_POWER,           /* Power */
-	[0x07] = KEY_TUNER,           /* Source */
-	[0x1c] = KEY_SEARCH,          /* Scan */
-	[0x18] = KEY_MUTE,            /* Mute */
-
-	[0x03] = KEY_RADIO,           /* TV/FM */
+	{ 0x01, KEY_1 },		/* 1 */
+	{ 0x0b, KEY_2 },		/* 2 */
+	{ 0x1b, KEY_3 },		/* 3 */
+	{ 0x05, KEY_4 },		/* 4 */
+	{ 0x09, KEY_5 },		/* 5 */
+	{ 0x15, KEY_6 },		/* 6 */
+	{ 0x06, KEY_7 },		/* 7 */
+	{ 0x0a, KEY_8 },		/* 8 */
+	{ 0x12, KEY_9 },		/* 9 */
+	{ 0x02, KEY_0 },		/* 0 */
+	{ 0x10, KEY_KPPLUS },		/* + */
+	{ 0x13, KEY_AGAIN },		/* Recall */
+
+	{ 0x1e, KEY_POWER },		/* Power */
+	{ 0x07, KEY_TUNER },		/* Source */
+	{ 0x1c, KEY_SEARCH },		/* Scan */
+	{ 0x18, KEY_MUTE },		/* Mute */
+
+	{ 0x03, KEY_RADIO },		/* TV/FM */
 	/* The next four keys are duplicates that appear to send the
 	   same IR code as Ch+, Ch-, >>, and << .  The raw code assigned
 	   to them is the actual code + 0x20 - they will never be
 	   detected as such unless some way is discovered to distinguish
 	   these buttons from those that have the same code. */
-	[0x3f] = KEY_RIGHT,           /* |> and Ch+ */
-	[0x37] = KEY_LEFT,            /* <| and Ch- */
-	[0x2c] = KEY_UP,              /* ^^Up and >> */
-	[0x24] = KEY_DOWN,            /* vvDn and << */
-
-	[0x00] = KEY_RECORD,          /* Record */
-	[0x08] = KEY_STOP,            /* Stop */
-	[0x11] = KEY_PLAY,            /* Play */
-
-	[0x0f] = KEY_CLOSE,           /* Minimize */
-	[0x19] = KEY_ZOOM,            /* Zoom */
-	[0x1a] = KEY_SHUFFLE,         /* Snapshot */
-	[0x0d] = KEY_LANGUAGE,        /* MTS */
-
-	[0x14] = KEY_VOLUMEDOWN,      /* Vol- */
-	[0x16] = KEY_VOLUMEUP,        /* Vol+ */
-	[0x17] = KEY_CHANNELDOWN,     /* Ch- */
-	[0x1f] = KEY_CHANNELUP,       /* Ch+ */
+	{ 0x3f, KEY_RIGHT },		/* |> and Ch+ */
+	{ 0x37, KEY_LEFT },		/* <| and Ch- */
+	{ 0x2c, KEY_UP },		/* ^^Up and >> */
+	{ 0x24, KEY_DOWN },		/* vvDn and << */
+
+	{ 0x00, KEY_RECORD },		/* Record */
+	{ 0x08, KEY_STOP },		/* Stop */
+	{ 0x11, KEY_PLAY },		/* Play */
+
+	{ 0x0f, KEY_CLOSE },		/* Minimize */
+	{ 0x19, KEY_ZOOM },		/* Zoom */
+	{ 0x1a, KEY_CAMERA },		/* Snapshot */
+	{ 0x0d, KEY_LANGUAGE },		/* MTS */
+
+	{ 0x14, KEY_VOLUMEDOWN },	/* Vol- */
+	{ 0x16, KEY_VOLUMEUP },		/* Vol+ */
+	{ 0x17, KEY_CHANNELDOWN },	/* Ch- */
+	{ 0x1f, KEY_CHANNELUP },	/* Ch+ */
+
+	{ 0x04, KEY_REWIND },		/* << */
+	{ 0x0e, KEY_MENU },		/* Function */
+	{ 0x0c, KEY_FASTFORWARD },	/* >> */
+	{ 0x1d, KEY_RESTART },		/* Reset */
+};
 
-	[0x04] = KEY_REWIND,          /* << */
-	[0x0e] = KEY_MENU,            /* Function */
-	[0x0c] = KEY_FASTFORWARD,     /* >> */
-	[0x1d] = KEY_RESTART,         /* Reset */
+struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table = {
+	.scan = ir_codes_msi_tvanywhere_plus,
+	.size = ARRAY_SIZE(ir_codes_msi_tvanywhere_plus),
 };
-EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus);
+EXPORT_SYMBOL_GPL(ir_codes_msi_tvanywhere_plus_table);
 
 /* ---------------------------------------------------------------------- */
 
 /* Cinergy 1400 DVB-T */
-IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
-	[ 0x01 ] = KEY_POWER,
-	[ 0x02 ] = KEY_1,
-	[ 0x03 ] = KEY_2,
-	[ 0x04 ] = KEY_3,
-	[ 0x05 ] = KEY_4,
-	[ 0x06 ] = KEY_5,
-	[ 0x07 ] = KEY_6,
-	[ 0x08 ] = KEY_7,
-	[ 0x09 ] = KEY_8,
-	[ 0x0a ] = KEY_9,
-	[ 0x0c ] = KEY_0,
-
-	[ 0x0b ] = KEY_VIDEO,
-	[ 0x0d ] = KEY_REFRESH,
-	[ 0x0e ] = KEY_SELECT,
-	[ 0x0f ] = KEY_EPG,
-	[ 0x10 ] = KEY_UP,
-	[ 0x11 ] = KEY_LEFT,
-	[ 0x12 ] = KEY_OK,
-	[ 0x13 ] = KEY_RIGHT,
-	[ 0x14 ] = KEY_DOWN,
-	[ 0x15 ] = KEY_TEXT,
-	[ 0x16 ] = KEY_INFO,
-
-	[ 0x17 ] = KEY_RED,
-	[ 0x18 ] = KEY_GREEN,
-	[ 0x19 ] = KEY_YELLOW,
-	[ 0x1a ] = KEY_BLUE,
-
-	[ 0x1b ] = KEY_CHANNELUP,
-	[ 0x1c ] = KEY_VOLUMEUP,
-	[ 0x1d ] = KEY_MUTE,
-	[ 0x1e ] = KEY_VOLUMEDOWN,
-	[ 0x1f ] = KEY_CHANNELDOWN,
-
-	[ 0x40 ] = KEY_PAUSE,
-	[ 0x4c ] = KEY_PLAY,
-	[ 0x58 ] = KEY_RECORD,
-	[ 0x54 ] = KEY_PREVIOUS,
-	[ 0x48 ] = KEY_STOP,
-	[ 0x5c ] = KEY_NEXT,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400);
+static struct ir_scancode ir_codes_cinergy_1400[] = {
+	{ 0x01, KEY_POWER },
+	{ 0x02, KEY_1 },
+	{ 0x03, KEY_2 },
+	{ 0x04, KEY_3 },
+	{ 0x05, KEY_4 },
+	{ 0x06, KEY_5 },
+	{ 0x07, KEY_6 },
+	{ 0x08, KEY_7 },
+	{ 0x09, KEY_8 },
+	{ 0x0a, KEY_9 },
+	{ 0x0c, KEY_0 },
+
+	{ 0x0b, KEY_VIDEO },
+	{ 0x0d, KEY_REFRESH },
+	{ 0x0e, KEY_SELECT },
+	{ 0x0f, KEY_EPG },
+	{ 0x10, KEY_UP },
+	{ 0x11, KEY_LEFT },
+	{ 0x12, KEY_OK },
+	{ 0x13, KEY_RIGHT },
+	{ 0x14, KEY_DOWN },
+	{ 0x15, KEY_TEXT },
+	{ 0x16, KEY_INFO },
+
+	{ 0x17, KEY_RED },
+	{ 0x18, KEY_GREEN },
+	{ 0x19, KEY_YELLOW },
+	{ 0x1a, KEY_BLUE },
+
+	{ 0x1b, KEY_CHANNELUP },
+	{ 0x1c, KEY_VOLUMEUP },
+	{ 0x1d, KEY_MUTE },
+	{ 0x1e, KEY_VOLUMEDOWN },
+	{ 0x1f, KEY_CHANNELDOWN },
+
+	{ 0x40, KEY_PAUSE },
+	{ 0x4c, KEY_PLAY },
+	{ 0x58, KEY_RECORD },
+	{ 0x54, KEY_PREVIOUS },
+	{ 0x48, KEY_STOP },
+	{ 0x5c, KEY_NEXT },
+};
+
+struct ir_scancode_table ir_codes_cinergy_1400_table = {
+	.scan = ir_codes_cinergy_1400,
+	.size = ARRAY_SIZE(ir_codes_cinergy_1400),
+};
+EXPORT_SYMBOL_GPL(ir_codes_cinergy_1400_table);
 
 /* ---------------------------------------------------------------------- */
 
 /* AVERTV STUDIO 303 Remote */
-IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = {
-	[ 0x2a ] = KEY_1,
-	[ 0x32 ] = KEY_2,
-	[ 0x3a ] = KEY_3,
-	[ 0x4a ] = KEY_4,
-	[ 0x52 ] = KEY_5,
-	[ 0x5a ] = KEY_6,
-	[ 0x6a ] = KEY_7,
-	[ 0x72 ] = KEY_8,
-	[ 0x7a ] = KEY_9,
-	[ 0x0e ] = KEY_0,
-
-	[ 0x02 ] = KEY_POWER,
-	[ 0x22 ] = KEY_VIDEO,
-	[ 0x42 ] = KEY_AUDIO,
-	[ 0x62 ] = KEY_ZOOM,
-	[ 0x0a ] = KEY_TV,
-	[ 0x12 ] = KEY_CD,
-	[ 0x1a ] = KEY_TEXT,
-
-	[ 0x16 ] = KEY_SUBTITLE,
-	[ 0x1e ] = KEY_REWIND,
-	[ 0x06 ] = KEY_PRINT,
-
-	[ 0x2e ] = KEY_SEARCH,
-	[ 0x36 ] = KEY_SLEEP,
-	[ 0x3e ] = KEY_SHUFFLE,
-	[ 0x26 ] = KEY_MUTE,
-
-	[ 0x4e ] = KEY_RECORD,
-	[ 0x56 ] = KEY_PAUSE,
-	[ 0x5e ] = KEY_STOP,
-	[ 0x46 ] = KEY_PLAY,
-
-	[ 0x6e ] = KEY_RED,
-	[ 0x0b ] = KEY_GREEN,
-	[ 0x66 ] = KEY_YELLOW,
-	[ 0x03 ] = KEY_BLUE,
-
-	[ 0x76 ] = KEY_LEFT,
-	[ 0x7e ] = KEY_RIGHT,
-	[ 0x13 ] = KEY_DOWN,
-	[ 0x1b ] = KEY_UP,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_avertv_303);
+static struct ir_scancode ir_codes_avertv_303[] = {
+	{ 0x2a, KEY_1 },
+	{ 0x32, KEY_2 },
+	{ 0x3a, KEY_3 },
+	{ 0x4a, KEY_4 },
+	{ 0x52, KEY_5 },
+	{ 0x5a, KEY_6 },
+	{ 0x6a, KEY_7 },
+	{ 0x72, KEY_8 },
+	{ 0x7a, KEY_9 },
+	{ 0x0e, KEY_0 },
+
+	{ 0x02, KEY_POWER },
+	{ 0x22, KEY_VIDEO },
+	{ 0x42, KEY_AUDIO },
+	{ 0x62, KEY_ZOOM },
+	{ 0x0a, KEY_TV },
+	{ 0x12, KEY_CD },
+	{ 0x1a, KEY_TEXT },
+
+	{ 0x16, KEY_SUBTITLE },
+	{ 0x1e, KEY_REWIND },
+	{ 0x06, KEY_PRINT },
+
+	{ 0x2e, KEY_SEARCH },
+	{ 0x36, KEY_SLEEP },
+	{ 0x3e, KEY_SHUFFLE },
+	{ 0x26, KEY_MUTE },
+
+	{ 0x4e, KEY_RECORD },
+	{ 0x56, KEY_PAUSE },
+	{ 0x5e, KEY_STOP },
+	{ 0x46, KEY_PLAY },
+
+	{ 0x6e, KEY_RED },
+	{ 0x0b, KEY_GREEN },
+	{ 0x66, KEY_YELLOW },
+	{ 0x03, KEY_BLUE },
+
+	{ 0x76, KEY_LEFT },
+	{ 0x7e, KEY_RIGHT },
+	{ 0x13, KEY_DOWN },
+	{ 0x1b, KEY_UP },
+};
+
+struct ir_scancode_table ir_codes_avertv_303_table = {
+	.scan = ir_codes_avertv_303,
+	.size = ARRAY_SIZE(ir_codes_avertv_303),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avertv_303_table);
 
 /* ---------------------------------------------------------------------- */
 
 /* DigitalNow DNTV Live! DVB-T Pro Remote */
-IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = {
-	[ 0x16 ] = KEY_POWER,
-	[ 0x5b ] = KEY_HOME,
-
-	[ 0x55 ] = KEY_TV,		/* live tv */
-	[ 0x58 ] = KEY_TUNER,		/* digital Radio */
-	[ 0x5a ] = KEY_RADIO,		/* FM radio */
-	[ 0x59 ] = KEY_DVD,		/* dvd menu */
-	[ 0x03 ] = KEY_1,
-	[ 0x01 ] = KEY_2,
-	[ 0x06 ] = KEY_3,
-	[ 0x09 ] = KEY_4,
-	[ 0x1d ] = KEY_5,
-	[ 0x1f ] = KEY_6,
-	[ 0x0d ] = KEY_7,
-	[ 0x19 ] = KEY_8,
-	[ 0x1b ] = KEY_9,
-	[ 0x0c ] = KEY_CANCEL,
-	[ 0x15 ] = KEY_0,
-	[ 0x4a ] = KEY_CLEAR,
-	[ 0x13 ] = KEY_BACK,
-	[ 0x00 ] = KEY_TAB,
-	[ 0x4b ] = KEY_UP,
-	[ 0x4e ] = KEY_LEFT,
-	[ 0x4f ] = KEY_OK,
-	[ 0x52 ] = KEY_RIGHT,
-	[ 0x51 ] = KEY_DOWN,
-	[ 0x1e ] = KEY_VOLUMEUP,
-	[ 0x0a ] = KEY_VOLUMEDOWN,
-	[ 0x02 ] = KEY_CHANNELDOWN,
-	[ 0x05 ] = KEY_CHANNELUP,
-	[ 0x11 ] = KEY_RECORD,
-	[ 0x14 ] = KEY_PLAY,
-	[ 0x4c ] = KEY_PAUSE,
-	[ 0x1a ] = KEY_STOP,
-	[ 0x40 ] = KEY_REWIND,
-	[ 0x12 ] = KEY_FASTFORWARD,
-	[ 0x41 ] = KEY_PREVIOUSSONG,	/* replay |< */
-	[ 0x42 ] = KEY_NEXTSONG,	/* skip >| */
-	[ 0x54 ] = KEY_CAMERA,		/* capture */
-	[ 0x50 ] = KEY_LANGUAGE,	/* sap */
-	[ 0x47 ] = KEY_TV2,		/* pip */
-	[ 0x4d ] = KEY_SCREEN,
-	[ 0x43 ] = KEY_SUBTITLE,
-	[ 0x10 ] = KEY_MUTE,
-	[ 0x49 ] = KEY_AUDIO,		/* l/r */
-	[ 0x07 ] = KEY_SLEEP,
-	[ 0x08 ] = KEY_VIDEO,		/* a/v */
-	[ 0x0e ] = KEY_PREVIOUS,	/* recall */
-	[ 0x45 ] = KEY_ZOOM,		/* zoom + */
-	[ 0x46 ] = KEY_ANGLE,		/* zoom - */
-	[ 0x56 ] = KEY_RED,
-	[ 0x57 ] = KEY_GREEN,
-	[ 0x5c ] = KEY_YELLOW,
-	[ 0x5d ] = KEY_BLUE,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro);
-
-IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
-	[ 0x01 ] = KEY_CHANNEL,
-	[ 0x02 ] = KEY_SELECT,
-	[ 0x03 ] = KEY_MUTE,
-	[ 0x04 ] = KEY_POWER,
-	[ 0x05 ] = KEY_1,
-	[ 0x06 ] = KEY_2,
-	[ 0x07 ] = KEY_3,
-	[ 0x08 ] = KEY_CHANNELUP,
-	[ 0x09 ] = KEY_4,
-	[ 0x0a ] = KEY_5,
-	[ 0x0b ] = KEY_6,
-	[ 0x0c ] = KEY_CHANNELDOWN,
-	[ 0x0d ] = KEY_7,
-	[ 0x0e ] = KEY_8,
-	[ 0x0f ] = KEY_9,
-	[ 0x10 ] = KEY_VOLUMEUP,
-	[ 0x11 ] = KEY_0,
-	[ 0x12 ] = KEY_MENU,
-	[ 0x13 ] = KEY_PRINT,
-	[ 0x14 ] = KEY_VOLUMEDOWN,
-	[ 0x16 ] = KEY_PAUSE,
-	[ 0x18 ] = KEY_RECORD,
-	[ 0x19 ] = KEY_REWIND,
-	[ 0x1a ] = KEY_PLAY,
-	[ 0x1b ] = KEY_FORWARD,
-	[ 0x1c ] = KEY_BACKSPACE,
-	[ 0x1e ] = KEY_STOP,
-	[ 0x40 ] = KEY_ZOOM,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_em_terratec);
-
-IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE] = {
-	[ 0x3a ] = KEY_0,
-	[ 0x31 ] = KEY_1,
-	[ 0x32 ] = KEY_2,
-	[ 0x33 ] = KEY_3,
-	[ 0x34 ] = KEY_4,
-	[ 0x35 ] = KEY_5,
-	[ 0x36 ] = KEY_6,
-	[ 0x37 ] = KEY_7,
-	[ 0x38 ] = KEY_8,
-	[ 0x39 ] = KEY_9,
-
-	[ 0x2f ] = KEY_POWER,
-
-	[ 0x2e ] = KEY_P,
-	[ 0x1f ] = KEY_L,
-	[ 0x2b ] = KEY_I,
-
-	[ 0x2d ] = KEY_SCREEN,
-	[ 0x1e ] = KEY_ZOOM,
-	[ 0x1b ] = KEY_VOLUMEUP,
-	[ 0x0f ] = KEY_VOLUMEDOWN,
-	[ 0x17 ] = KEY_CHANNELUP,
-	[ 0x1c ] = KEY_CHANNELDOWN,
-	[ 0x25 ] = KEY_INFO,
-
-	[ 0x3c ] = KEY_MUTE,
-
-	[ 0x3d ] = KEY_LEFT,
-	[ 0x3b ] = KEY_RIGHT,
-
-	[ 0x3f ] = KEY_UP,
-	[ 0x3e ] = KEY_DOWN,
-	[ 0x1a ] = KEY_ENTER,
-
-	[ 0x1d ] = KEY_MENU,
-	[ 0x19 ] = KEY_AGAIN,
-	[ 0x16 ] = KEY_PREVIOUSSONG,
-	[ 0x13 ] = KEY_NEXTSONG,
-	[ 0x15 ] = KEY_PAUSE,
-	[ 0x0e ] = KEY_REWIND,
-	[ 0x0d ] = KEY_PLAY,
-	[ 0x0b ] = KEY_STOP,
-	[ 0x07 ] = KEY_FORWARD,
-	[ 0x27 ] = KEY_RECORD,
-	[ 0x26 ] = KEY_TUNER,
-	[ 0x29 ] = KEY_TEXT,
-	[ 0x2a ] = KEY_MEDIA,
-	[ 0x18 ] = KEY_EPG,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey);
-
-IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE] = {
-	[ 0x0f ] = KEY_0,
-	[ 0x03 ] = KEY_1,
-	[ 0x04 ] = KEY_2,
-	[ 0x05 ] = KEY_3,
-	[ 0x07 ] = KEY_4,
-	[ 0x08 ] = KEY_5,
-	[ 0x09 ] = KEY_6,
-	[ 0x0b ] = KEY_7,
-	[ 0x0c ] = KEY_8,
-	[ 0x0d ] = KEY_9,
-
-	[ 0x0e ] = KEY_MODE,         // Air/Cable
-	[ 0x11 ] = KEY_VIDEO,        // Video
-	[ 0x15 ] = KEY_AUDIO,        // Audio
-	[ 0x00 ] = KEY_POWER,        // Power
-	[ 0x18 ] = KEY_TUNER,        // AV Source
-	[ 0x02 ] = KEY_ZOOM,         // Fullscreen
-	[ 0x1a ] = KEY_LANGUAGE,     // Stereo
-	[ 0x1b ] = KEY_MUTE,         // Mute
-	[ 0x14 ] = KEY_VOLUMEUP,     // Volume +
-	[ 0x17 ] = KEY_VOLUMEDOWN,   // Volume -
-	[ 0x12 ] = KEY_CHANNELUP,    // Channel +
-	[ 0x13 ] = KEY_CHANNELDOWN,  // Channel -
-	[ 0x06 ] = KEY_AGAIN,        // Recall
-	[ 0x10 ] = KEY_ENTER,        // Enter
-
-	[ 0x19 ] = KEY_BACK,         // Rewind  ( <<< )
-	[ 0x1f ] = KEY_FORWARD,      // Forward ( >>> )
-	[ 0x0a ] = KEY_ANGLE,        // (no label, may be used as the PAUSE button)
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_flyvideo);
-
-IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE] = {
-	[ 0x01 ] = KEY_ZOOM,		// Full Screen
-	[ 0x00 ] = KEY_POWER,		// Power
-
-	[ 0x03 ] = KEY_1,
-	[ 0x04 ] = KEY_2,
-	[ 0x05 ] = KEY_3,
-	[ 0x07 ] = KEY_4,
-	[ 0x08 ] = KEY_5,
-	[ 0x09 ] = KEY_6,
-	[ 0x0b ] = KEY_7,
-	[ 0x0c ] = KEY_8,
-	[ 0x0d ] = KEY_9,
-	[ 0x06 ] = KEY_AGAIN,		// Recall
-	[ 0x0f ] = KEY_0,
-	[ 0x10 ] = KEY_MUTE,		// Mute
-	[ 0x02 ] = KEY_RADIO,		// TV/Radio
-	[ 0x1b ] = KEY_LANGUAGE,		// SAP (Second Audio Program)
-
-	[ 0x14 ] = KEY_VOLUMEUP,		// VOL+
-	[ 0x17 ] = KEY_VOLUMEDOWN,	// VOL-
-	[ 0x12 ] = KEY_CHANNELUP,		// CH+
-	[ 0x13 ] = KEY_CHANNELDOWN,	// CH-
-	[ 0x1d ] = KEY_ENTER,		// Enter
-
-	[ 0x1a ] = KEY_MODE,		// PIP
-	[ 0x18 ] = KEY_TUNER,		// Source
-
-	[ 0x1e ] = KEY_RECORD,		// Record/Pause
-	[ 0x15 ] = KEY_ANGLE,		// Swap (no label on key)
-	[ 0x1c ] = KEY_PAUSE,		// Timeshift/Pause
-	[ 0x19 ] = KEY_BACK,		// Rewind <<
-	[ 0x0a ] = KEY_PLAYPAUSE,		// Play/Pause
-	[ 0x1f ] = KEY_FORWARD,		// Forward >>
-	[ 0x16 ] = KEY_PREVIOUS,		// Back |<<
-	[ 0x11 ] = KEY_STOP,		// Stop
-	[ 0x0e ] = KEY_NEXT,		// End >>|
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_flydvb);
-
-IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x0a ] = KEY_POWER,
-	[ 0x0b ] = KEY_PROG1,           // app
-	[ 0x0c ] = KEY_ZOOM,            // zoom/fullscreen
-	[ 0x0d ] = KEY_CHANNELUP,       // channel
-	[ 0x0e ] = KEY_CHANNELDOWN,     // channel-
-	[ 0x0f ] = KEY_VOLUMEUP,
-	[ 0x10 ] = KEY_VOLUMEDOWN,
-	[ 0x11 ] = KEY_TUNER,           // AV
-	[ 0x12 ] = KEY_NUMLOCK,         // -/--
-	[ 0x13 ] = KEY_AUDIO,           // audio
-	[ 0x14 ] = KEY_MUTE,
-	[ 0x15 ] = KEY_UP,
-	[ 0x16 ] = KEY_DOWN,
-	[ 0x17 ] = KEY_LEFT,
-	[ 0x18 ] = KEY_RIGHT,
-	[ 0x19 ] = BTN_LEFT,
-	[ 0x1a ] = BTN_RIGHT,
-	[ 0x1b ] = KEY_WWW,             // text
-	[ 0x1c ] = KEY_REWIND,
-	[ 0x1d ] = KEY_FORWARD,
-	[ 0x1e ] = KEY_RECORD,
-	[ 0x1f ] = KEY_PLAY,
-	[ 0x20 ] = KEY_PREVIOUSSONG,
-	[ 0x21 ] = KEY_NEXTSONG,
-	[ 0x22 ] = KEY_PAUSE,
-	[ 0x23 ] = KEY_STOP,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_cinergy);
+static struct ir_scancode ir_codes_dntv_live_dvbt_pro[] = {
+	{ 0x16, KEY_POWER },
+	{ 0x5b, KEY_HOME },
+
+	{ 0x55, KEY_TV },		/* live tv */
+	{ 0x58, KEY_TUNER },		/* digital Radio */
+	{ 0x5a, KEY_RADIO },		/* FM radio */
+	{ 0x59, KEY_DVD },		/* dvd menu */
+	{ 0x03, KEY_1 },
+	{ 0x01, KEY_2 },
+	{ 0x06, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x1d, KEY_5 },
+	{ 0x1f, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x19, KEY_8 },
+	{ 0x1b, KEY_9 },
+	{ 0x0c, KEY_CANCEL },
+	{ 0x15, KEY_0 },
+	{ 0x4a, KEY_CLEAR },
+	{ 0x13, KEY_BACK },
+	{ 0x00, KEY_TAB },
+	{ 0x4b, KEY_UP },
+	{ 0x4e, KEY_LEFT },
+	{ 0x4f, KEY_OK },
+	{ 0x52, KEY_RIGHT },
+	{ 0x51, KEY_DOWN },
+	{ 0x1e, KEY_VOLUMEUP },
+	{ 0x0a, KEY_VOLUMEDOWN },
+	{ 0x02, KEY_CHANNELDOWN },
+	{ 0x05, KEY_CHANNELUP },
+	{ 0x11, KEY_RECORD },
+	{ 0x14, KEY_PLAY },
+	{ 0x4c, KEY_PAUSE },
+	{ 0x1a, KEY_STOP },
+	{ 0x40, KEY_REWIND },
+	{ 0x12, KEY_FASTFORWARD },
+	{ 0x41, KEY_PREVIOUSSONG },	/* replay |< */
+	{ 0x42, KEY_NEXTSONG },		/* skip >| */
+	{ 0x54, KEY_CAMERA },		/* capture */
+	{ 0x50, KEY_LANGUAGE },		/* sap */
+	{ 0x47, KEY_TV2 },		/* pip */
+	{ 0x4d, KEY_SCREEN },
+	{ 0x43, KEY_SUBTITLE },
+	{ 0x10, KEY_MUTE },
+	{ 0x49, KEY_AUDIO },		/* l/r */
+	{ 0x07, KEY_SLEEP },
+	{ 0x08, KEY_VIDEO },		/* a/v */
+	{ 0x0e, KEY_PREVIOUS },		/* recall */
+	{ 0x45, KEY_ZOOM },		/* zoom + */
+	{ 0x46, KEY_ANGLE },		/* zoom - */
+	{ 0x56, KEY_RED },
+	{ 0x57, KEY_GREEN },
+	{ 0x5c, KEY_YELLOW },
+	{ 0x5d, KEY_BLUE },
+};
+
+struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table = {
+	.scan = ir_codes_dntv_live_dvbt_pro,
+	.size = ARRAY_SIZE(ir_codes_dntv_live_dvbt_pro),
+};
+EXPORT_SYMBOL_GPL(ir_codes_dntv_live_dvbt_pro_table);
+
+static struct ir_scancode ir_codes_em_terratec[] = {
+	{ 0x01, KEY_CHANNEL },
+	{ 0x02, KEY_SELECT },
+	{ 0x03, KEY_MUTE },
+	{ 0x04, KEY_POWER },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x08, KEY_CHANNELUP },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0c, KEY_CHANNELDOWN },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_0 },
+	{ 0x12, KEY_MENU },
+	{ 0x13, KEY_PRINT },
+	{ 0x14, KEY_VOLUMEDOWN },
+	{ 0x16, KEY_PAUSE },
+	{ 0x18, KEY_RECORD },
+	{ 0x19, KEY_REWIND },
+	{ 0x1a, KEY_PLAY },
+	{ 0x1b, KEY_FORWARD },
+	{ 0x1c, KEY_BACKSPACE },
+	{ 0x1e, KEY_STOP },
+	{ 0x40, KEY_ZOOM },
+};
+
+struct ir_scancode_table ir_codes_em_terratec_table = {
+	.scan = ir_codes_em_terratec,
+	.size = ARRAY_SIZE(ir_codes_em_terratec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_em_terratec_table);
+
+static struct ir_scancode ir_codes_pinnacle_grey[] = {
+	{ 0x3a, KEY_0 },
+	{ 0x31, KEY_1 },
+	{ 0x32, KEY_2 },
+	{ 0x33, KEY_3 },
+	{ 0x34, KEY_4 },
+	{ 0x35, KEY_5 },
+	{ 0x36, KEY_6 },
+	{ 0x37, KEY_7 },
+	{ 0x38, KEY_8 },
+	{ 0x39, KEY_9 },
+
+	{ 0x2f, KEY_POWER },
+
+	{ 0x2e, KEY_P },
+	{ 0x1f, KEY_L },
+	{ 0x2b, KEY_I },
+
+	{ 0x2d, KEY_SCREEN },
+	{ 0x1e, KEY_ZOOM },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x0f, KEY_VOLUMEDOWN },
+	{ 0x17, KEY_CHANNELUP },
+	{ 0x1c, KEY_CHANNELDOWN },
+	{ 0x25, KEY_INFO },
+
+	{ 0x3c, KEY_MUTE },
+
+	{ 0x3d, KEY_LEFT },
+	{ 0x3b, KEY_RIGHT },
+
+	{ 0x3f, KEY_UP },
+	{ 0x3e, KEY_DOWN },
+	{ 0x1a, KEY_ENTER },
+
+	{ 0x1d, KEY_MENU },
+	{ 0x19, KEY_AGAIN },
+	{ 0x16, KEY_PREVIOUSSONG },
+	{ 0x13, KEY_NEXTSONG },
+	{ 0x15, KEY_PAUSE },
+	{ 0x0e, KEY_REWIND },
+	{ 0x0d, KEY_PLAY },
+	{ 0x0b, KEY_STOP },
+	{ 0x07, KEY_FORWARD },
+	{ 0x27, KEY_RECORD },
+	{ 0x26, KEY_TUNER },
+	{ 0x29, KEY_TEXT },
+	{ 0x2a, KEY_MEDIA },
+	{ 0x18, KEY_EPG },
+};
+
+struct ir_scancode_table ir_codes_pinnacle_grey_table = {
+	.scan = ir_codes_pinnacle_grey,
+	.size = ARRAY_SIZE(ir_codes_pinnacle_grey),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle_grey_table);
+
+static struct ir_scancode ir_codes_flyvideo[] = {
+	{ 0x0f, KEY_0 },
+	{ 0x03, KEY_1 },
+	{ 0x04, KEY_2 },
+	{ 0x05, KEY_3 },
+	{ 0x07, KEY_4 },
+	{ 0x08, KEY_5 },
+	{ 0x09, KEY_6 },
+	{ 0x0b, KEY_7 },
+	{ 0x0c, KEY_8 },
+	{ 0x0d, KEY_9 },
+
+	{ 0x0e, KEY_MODE },	/* Air/Cable */
+	{ 0x11, KEY_VIDEO },	/* Video */
+	{ 0x15, KEY_AUDIO },	/* Audio */
+	{ 0x00, KEY_POWER },	/* Power */
+	{ 0x18, KEY_TUNER },	/* AV Source */
+	{ 0x02, KEY_ZOOM },	/* Fullscreen */
+	{ 0x1a, KEY_LANGUAGE },	/* Stereo */
+	{ 0x1b, KEY_MUTE },	/* Mute */
+	{ 0x14, KEY_VOLUMEUP },	/* Volume + */
+	{ 0x17, KEY_VOLUMEDOWN },/* Volume - */
+	{ 0x12, KEY_CHANNELUP },/* Channel + */
+	{ 0x13, KEY_CHANNELDOWN },/* Channel - */
+	{ 0x06, KEY_AGAIN },	/* Recall */
+	{ 0x10, KEY_ENTER },	/* Enter */
+
+	{ 0x19, KEY_BACK },	/* Rewind  ( <<< ) */
+	{ 0x1f, KEY_FORWARD },	/* Forward ( >>> ) */
+	{ 0x0a, KEY_ANGLE },	/* no label, may be used as the PAUSE button */
+};
+
+struct ir_scancode_table ir_codes_flyvideo_table = {
+	.scan = ir_codes_flyvideo,
+	.size = ARRAY_SIZE(ir_codes_flyvideo),
+};
+EXPORT_SYMBOL_GPL(ir_codes_flyvideo_table);
+
+static struct ir_scancode ir_codes_flydvb[] = {
+	{ 0x01, KEY_ZOOM },		/* Full Screen */
+	{ 0x00, KEY_POWER },		/* Power */
+
+	{ 0x03, KEY_1 },
+	{ 0x04, KEY_2 },
+	{ 0x05, KEY_3 },
+	{ 0x07, KEY_4 },
+	{ 0x08, KEY_5 },
+	{ 0x09, KEY_6 },
+	{ 0x0b, KEY_7 },
+	{ 0x0c, KEY_8 },
+	{ 0x0d, KEY_9 },
+	{ 0x06, KEY_AGAIN },		/* Recall */
+	{ 0x0f, KEY_0 },
+	{ 0x10, KEY_MUTE },		/* Mute */
+	{ 0x02, KEY_RADIO },		/* TV/Radio */
+	{ 0x1b, KEY_LANGUAGE },		/* SAP (Second Audio Program) */
+
+	{ 0x14, KEY_VOLUMEUP },		/* VOL+ */
+	{ 0x17, KEY_VOLUMEDOWN },	/* VOL- */
+	{ 0x12, KEY_CHANNELUP },	/* CH+ */
+	{ 0x13, KEY_CHANNELDOWN },	/* CH- */
+	{ 0x1d, KEY_ENTER },		/* Enter */
+
+	{ 0x1a, KEY_MODE },		/* PIP */
+	{ 0x18, KEY_TUNER },		/* Source */
+
+	{ 0x1e, KEY_RECORD },		/* Record/Pause */
+	{ 0x15, KEY_ANGLE },		/* Swap (no label on key) */
+	{ 0x1c, KEY_PAUSE },		/* Timeshift/Pause */
+	{ 0x19, KEY_BACK },		/* Rewind << */
+	{ 0x0a, KEY_PLAYPAUSE },	/* Play/Pause */
+	{ 0x1f, KEY_FORWARD },		/* Forward >> */
+	{ 0x16, KEY_PREVIOUS },		/* Back |<< */
+	{ 0x11, KEY_STOP },		/* Stop */
+	{ 0x0e, KEY_NEXT },		/* End >>| */
+};
+
+struct ir_scancode_table ir_codes_flydvb_table = {
+	.scan = ir_codes_flydvb,
+	.size = ARRAY_SIZE(ir_codes_flydvb),
+};
+EXPORT_SYMBOL_GPL(ir_codes_flydvb_table);
+
+static struct ir_scancode ir_codes_cinergy[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0a, KEY_POWER },
+	{ 0x0b, KEY_PROG1 },		/* app */
+	{ 0x0c, KEY_ZOOM },		/* zoom/fullscreen */
+	{ 0x0d, KEY_CHANNELUP },	/* channel */
+	{ 0x0e, KEY_CHANNELDOWN },	/* channel- */
+	{ 0x0f, KEY_VOLUMEUP },
+	{ 0x10, KEY_VOLUMEDOWN },
+	{ 0x11, KEY_TUNER },		/* AV */
+	{ 0x12, KEY_NUMLOCK },		/* -/-- */
+	{ 0x13, KEY_AUDIO },		/* audio */
+	{ 0x14, KEY_MUTE },
+	{ 0x15, KEY_UP },
+	{ 0x16, KEY_DOWN },
+	{ 0x17, KEY_LEFT },
+	{ 0x18, KEY_RIGHT },
+	{ 0x19, BTN_LEFT, },
+	{ 0x1a, BTN_RIGHT, },
+	{ 0x1b, KEY_WWW },		/* text */
+	{ 0x1c, KEY_REWIND },
+	{ 0x1d, KEY_FORWARD },
+	{ 0x1e, KEY_RECORD },
+	{ 0x1f, KEY_PLAY },
+	{ 0x20, KEY_PREVIOUSSONG },
+	{ 0x21, KEY_NEXTSONG },
+	{ 0x22, KEY_PAUSE },
+	{ 0x23, KEY_STOP },
+};
+
+struct ir_scancode_table ir_codes_cinergy_table = {
+	.scan = ir_codes_cinergy,
+	.size = ARRAY_SIZE(ir_codes_cinergy),
+};
+EXPORT_SYMBOL_GPL(ir_codes_cinergy_table);
 
 /* Alfons Geser <a.geser@cox.net>
  * updates from Job D. R. Borges <jobdrb@ig.com.br> */
-IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE] = {
-	[ 0x12 ] = KEY_POWER,
-	[ 0x01 ] = KEY_TV,             // DVR
-	[ 0x15 ] = KEY_DVD,            // DVD
-	[ 0x17 ] = KEY_AUDIO,          // music
-				     // DVR mode / DVD mode / music mode
-
-	[ 0x1b ] = KEY_MUTE,           // mute
-	[ 0x02 ] = KEY_LANGUAGE,       // MTS/SAP / audio / autoseek
-	[ 0x1e ] = KEY_SUBTITLE,       // closed captioning / subtitle / seek
-	[ 0x16 ] = KEY_ZOOM,           // full screen
-	[ 0x1c ] = KEY_VIDEO,          // video source / eject / delall
-	[ 0x1d ] = KEY_RESTART,        // playback / angle / del
-	[ 0x2f ] = KEY_SEARCH,         // scan / menu / playlist
-	[ 0x30 ] = KEY_CHANNEL,        // CH surfing / bookmark / memo
-
-	[ 0x31 ] = KEY_HELP,           // help
-	[ 0x32 ] = KEY_MODE,           // num/memo
-	[ 0x33 ] = KEY_ESC,            // cancel
-
-	[ 0x0c ] = KEY_UP,             // up
-	[ 0x10 ] = KEY_DOWN,           // down
-	[ 0x08 ] = KEY_LEFT,           // left
-	[ 0x04 ] = KEY_RIGHT,          // right
-	[ 0x03 ] = KEY_SELECT,         // select
-
-	[ 0x1f ] = KEY_REWIND,         // rewind
-	[ 0x20 ] = KEY_PLAYPAUSE,      // play/pause
-	[ 0x29 ] = KEY_FORWARD,        // forward
-	[ 0x14 ] = KEY_AGAIN,          // repeat
-	[ 0x2b ] = KEY_RECORD,         // recording
-	[ 0x2c ] = KEY_STOP,           // stop
-	[ 0x2d ] = KEY_PLAY,           // play
-	[ 0x2e ] = KEY_SHUFFLE,        // snapshot / shuffle
-
-	[ 0x00 ] = KEY_0,
-	[ 0x05 ] = KEY_1,
-	[ 0x06 ] = KEY_2,
-	[ 0x07 ] = KEY_3,
-	[ 0x09 ] = KEY_4,
-	[ 0x0a ] = KEY_5,
-	[ 0x0b ] = KEY_6,
-	[ 0x0d ] = KEY_7,
-	[ 0x0e ] = KEY_8,
-	[ 0x0f ] = KEY_9,
-
-	[ 0x2a ] = KEY_VOLUMEUP,
-	[ 0x11 ] = KEY_VOLUMEDOWN,
-	[ 0x18 ] = KEY_CHANNELUP,      // CH.tracking up
-	[ 0x19 ] = KEY_CHANNELDOWN,    // CH.tracking down
-
-	[ 0x13 ] = KEY_ENTER,        // enter
-	[ 0x21 ] = KEY_DOT,          // . (decimal dot)
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_eztv);
+static struct ir_scancode ir_codes_eztv[] = {
+	{ 0x12, KEY_POWER },
+	{ 0x01, KEY_TV },	/* DVR */
+	{ 0x15, KEY_DVD },	/* DVD */
+	{ 0x17, KEY_AUDIO },	/* music */
+				/* DVR mode / DVD mode / music mode */
+
+	{ 0x1b, KEY_MUTE },	/* mute */
+	{ 0x02, KEY_LANGUAGE },	/* MTS/SAP / audio / autoseek */
+	{ 0x1e, KEY_SUBTITLE },	/* closed captioning / subtitle / seek */
+	{ 0x16, KEY_ZOOM },	/* full screen */
+	{ 0x1c, KEY_VIDEO },	/* video source / eject / delall */
+	{ 0x1d, KEY_RESTART },	/* playback / angle / del */
+	{ 0x2f, KEY_SEARCH },	/* scan / menu / playlist */
+	{ 0x30, KEY_CHANNEL },	/* CH surfing / bookmark / memo */
+
+	{ 0x31, KEY_HELP },	/* help */
+	{ 0x32, KEY_MODE },	/* num/memo */
+	{ 0x33, KEY_ESC },	/* cancel */
+
+	{ 0x0c, KEY_UP },	/* up */
+	{ 0x10, KEY_DOWN },	/* down */
+	{ 0x08, KEY_LEFT },	/* left */
+	{ 0x04, KEY_RIGHT },	/* right */
+	{ 0x03, KEY_SELECT },	/* select */
+
+	{ 0x1f, KEY_REWIND },	/* rewind */
+	{ 0x20, KEY_PLAYPAUSE },/* play/pause */
+	{ 0x29, KEY_FORWARD },	/* forward */
+	{ 0x14, KEY_AGAIN },	/* repeat */
+	{ 0x2b, KEY_RECORD },	/* recording */
+	{ 0x2c, KEY_STOP },	/* stop */
+	{ 0x2d, KEY_PLAY },	/* play */
+	{ 0x2e, KEY_CAMERA },	/* snapshot / shuffle */
+
+	{ 0x00, KEY_0 },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+
+	{ 0x2a, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x18, KEY_CHANNELUP },/* CH.tracking up */
+	{ 0x19, KEY_CHANNELDOWN },/* CH.tracking down */
+
+	{ 0x13, KEY_ENTER },	/* enter */
+	{ 0x21, KEY_DOT },	/* . (decimal dot) */
+};
+
+struct ir_scancode_table ir_codes_eztv_table = {
+	.scan = ir_codes_eztv,
+	.size = ARRAY_SIZE(ir_codes_eztv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_eztv_table);
 
 /* Alex Hermann <gaaf@gmx.net> */
-IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE] = {
-	[ 0x28 ] = KEY_1,
-	[ 0x18 ] = KEY_2,
-	[ 0x38 ] = KEY_3,
-	[ 0x24 ] = KEY_4,
-	[ 0x14 ] = KEY_5,
-	[ 0x34 ] = KEY_6,
-	[ 0x2c ] = KEY_7,
-	[ 0x1c ] = KEY_8,
-	[ 0x3c ] = KEY_9,
-	[ 0x22 ] = KEY_0,
-
-	[ 0x20 ] = KEY_TV,		/* TV/FM */
-	[ 0x10 ] = KEY_CD,		/* CD */
-	[ 0x30 ] = KEY_TEXT,		/* TELETEXT */
-	[ 0x00 ] = KEY_POWER,		/* POWER */
-
-	[ 0x08 ] = KEY_VIDEO,		/* VIDEO */
-	[ 0x04 ] = KEY_AUDIO,		/* AUDIO */
-	[ 0x0c ] = KEY_ZOOM,		/* FULL SCREEN */
-
-	[ 0x12 ] = KEY_SUBTITLE,	/* DISPLAY */
-	[ 0x32 ] = KEY_REWIND,		/* LOOP	*/
-	[ 0x02 ] = KEY_PRINT,		/* PREVIEW */
-
-	[ 0x2a ] = KEY_SEARCH,		/* AUTOSCAN */
-	[ 0x1a ] = KEY_SLEEP,		/* FREEZE */
-	[ 0x3a ] = KEY_SHUFFLE,		/* SNAPSHOT */
-	[ 0x0a ] = KEY_MUTE,		/* MUTE */
-
-	[ 0x26 ] = KEY_RECORD,		/* RECORD */
-	[ 0x16 ] = KEY_PAUSE,		/* PAUSE */
-	[ 0x36 ] = KEY_STOP,		/* STOP */
-	[ 0x06 ] = KEY_PLAY,		/* PLAY */
-
-	[ 0x2e ] = KEY_RED,		/* RED */
-	[ 0x21 ] = KEY_GREEN,		/* GREEN */
-	[ 0x0e ] = KEY_YELLOW,		/* YELLOW */
-	[ 0x01 ] = KEY_BLUE,		/* BLUE */
-
-	[ 0x1e ] = KEY_VOLUMEDOWN,	/* VOLUME- */
-	[ 0x3e ] = KEY_VOLUMEUP,	/* VOLUME+ */
-	[ 0x11 ] = KEY_CHANNELDOWN,	/* CHANNEL/PAGE- */
-	[ 0x31 ] = KEY_CHANNELUP	/* CHANNEL/PAGE+ */
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_avermedia);
-
-IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE] = {
-	[ 0x14 ] = KEY_MUTE,
-	[ 0x24 ] = KEY_ZOOM,
-
-	[ 0x01 ] = KEY_DVD,
-	[ 0x23 ] = KEY_RADIO,
-	[ 0x00 ] = KEY_TV,
-
-	[ 0x0a ] = KEY_REWIND,
-	[ 0x08 ] = KEY_PLAYPAUSE,
-	[ 0x0f ] = KEY_FORWARD,
-
-	[ 0x02 ] = KEY_PREVIOUS,
-	[ 0x07 ] = KEY_STOP,
-	[ 0x06 ] = KEY_NEXT,
-
-	[ 0x0c ] = KEY_UP,
-	[ 0x0e ] = KEY_DOWN,
-	[ 0x0b ] = KEY_LEFT,
-	[ 0x0d ] = KEY_RIGHT,
-	[ 0x11 ] = KEY_OK,
-
-	[ 0x03 ] = KEY_MENU,
-	[ 0x09 ] = KEY_SETUP,
-	[ 0x05 ] = KEY_VIDEO,
-	[ 0x22 ] = KEY_CHANNEL,
-
-	[ 0x12 ] = KEY_VOLUMEUP,
-	[ 0x15 ] = KEY_VOLUMEDOWN,
-	[ 0x10 ] = KEY_CHANNELUP,
-	[ 0x13 ] = KEY_CHANNELDOWN,
-
-	[ 0x04 ] = KEY_RECORD,
-
-	[ 0x16 ] = KEY_1,
-	[ 0x17 ] = KEY_2,
-	[ 0x18 ] = KEY_3,
-	[ 0x19 ] = KEY_4,
-	[ 0x1a ] = KEY_5,
-	[ 0x1b ] = KEY_6,
-	[ 0x1c ] = KEY_7,
-	[ 0x1d ] = KEY_8,
-	[ 0x1e ] = KEY_9,
-	[ 0x1f ] = KEY_0,
-
-	[ 0x20 ] = KEY_LANGUAGE,
-	[ 0x21 ] = KEY_SLEEP,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr);
+static struct ir_scancode ir_codes_avermedia[] = {
+	{ 0x28, KEY_1 },
+	{ 0x18, KEY_2 },
+	{ 0x38, KEY_3 },
+	{ 0x24, KEY_4 },
+	{ 0x14, KEY_5 },
+	{ 0x34, KEY_6 },
+	{ 0x2c, KEY_7 },
+	{ 0x1c, KEY_8 },
+	{ 0x3c, KEY_9 },
+	{ 0x22, KEY_0 },
+
+	{ 0x20, KEY_TV },		/* TV/FM */
+	{ 0x10, KEY_CD },		/* CD */
+	{ 0x30, KEY_TEXT },		/* TELETEXT */
+	{ 0x00, KEY_POWER },		/* POWER */
+
+	{ 0x08, KEY_VIDEO },		/* VIDEO */
+	{ 0x04, KEY_AUDIO },		/* AUDIO */
+	{ 0x0c, KEY_ZOOM },		/* FULL SCREEN */
+
+	{ 0x12, KEY_SUBTITLE },		/* DISPLAY */
+	{ 0x32, KEY_REWIND },		/* LOOP	*/
+	{ 0x02, KEY_PRINT },		/* PREVIEW */
+
+	{ 0x2a, KEY_SEARCH },		/* AUTOSCAN */
+	{ 0x1a, KEY_SLEEP },		/* FREEZE */
+	{ 0x3a, KEY_CAMERA },		/* SNAPSHOT */
+	{ 0x0a, KEY_MUTE },		/* MUTE */
+
+	{ 0x26, KEY_RECORD },		/* RECORD */
+	{ 0x16, KEY_PAUSE },		/* PAUSE */
+	{ 0x36, KEY_STOP },		/* STOP */
+	{ 0x06, KEY_PLAY },		/* PLAY */
+
+	{ 0x2e, KEY_RED },		/* RED */
+	{ 0x21, KEY_GREEN },		/* GREEN */
+	{ 0x0e, KEY_YELLOW },		/* YELLOW */
+	{ 0x01, KEY_BLUE },		/* BLUE */
+
+	{ 0x1e, KEY_VOLUMEDOWN },	/* VOLUME- */
+	{ 0x3e, KEY_VOLUMEUP },		/* VOLUME+ */
+	{ 0x11, KEY_CHANNELDOWN },	/* CHANNEL/PAGE- */
+	{ 0x31, KEY_CHANNELUP }		/* CHANNEL/PAGE+ */
+};
+
+struct ir_scancode_table ir_codes_avermedia_table = {
+	.scan = ir_codes_avermedia,
+	.size = ARRAY_SIZE(ir_codes_avermedia),
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_table);
+
+static struct ir_scancode ir_codes_videomate_tv_pvr[] = {
+	{ 0x14, KEY_MUTE },
+	{ 0x24, KEY_ZOOM },
+
+	{ 0x01, KEY_DVD },
+	{ 0x23, KEY_RADIO },
+	{ 0x00, KEY_TV },
+
+	{ 0x0a, KEY_REWIND },
+	{ 0x08, KEY_PLAYPAUSE },
+	{ 0x0f, KEY_FORWARD },
+
+	{ 0x02, KEY_PREVIOUS },
+	{ 0x07, KEY_STOP },
+	{ 0x06, KEY_NEXT },
+
+	{ 0x0c, KEY_UP },
+	{ 0x0e, KEY_DOWN },
+	{ 0x0b, KEY_LEFT },
+	{ 0x0d, KEY_RIGHT },
+	{ 0x11, KEY_OK },
+
+	{ 0x03, KEY_MENU },
+	{ 0x09, KEY_SETUP },
+	{ 0x05, KEY_VIDEO },
+	{ 0x22, KEY_CHANNEL },
+
+	{ 0x12, KEY_VOLUMEUP },
+	{ 0x15, KEY_VOLUMEDOWN },
+	{ 0x10, KEY_CHANNELUP },
+	{ 0x13, KEY_CHANNELDOWN },
+
+	{ 0x04, KEY_RECORD },
+
+	{ 0x16, KEY_1 },
+	{ 0x17, KEY_2 },
+	{ 0x18, KEY_3 },
+	{ 0x19, KEY_4 },
+	{ 0x1a, KEY_5 },
+	{ 0x1b, KEY_6 },
+	{ 0x1c, KEY_7 },
+	{ 0x1d, KEY_8 },
+	{ 0x1e, KEY_9 },
+	{ 0x1f, KEY_0 },
+
+	{ 0x20, KEY_LANGUAGE },
+	{ 0x21, KEY_SLEEP },
+};
+
+struct ir_scancode_table ir_codes_videomate_tv_pvr_table = {
+	.scan = ir_codes_videomate_tv_pvr,
+	.size = ARRAY_SIZE(ir_codes_videomate_tv_pvr),
+};
+EXPORT_SYMBOL_GPL(ir_codes_videomate_tv_pvr_table);
 
 /* Michael Tokarev <mjt@tls.msk.ru>
    http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
-   keytable is used by MANLI MTV00[ 0x0c ] and BeholdTV 40[13] at
+   keytable is used by MANLI MTV00[0x0c] and BeholdTV 40[13] at
    least, and probably other cards too.
    The "ascii-art picture" below (in comments, first row
    is the keycode in hex, and subsequent row(s) shows
    the button labels (several variants when appropriate)
    helps to descide which keycodes to assign to the buttons.
  */
-IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_manli[] = {
 
 	/*  0x1c            0x12  *
 	 * FUNCTION         POWER *
 	 *   FM              (|)  *
 	 *                        */
-	[ 0x1c ] = KEY_RADIO,	/*XXX*/
-	[ 0x12 ] = KEY_POWER,
+	{ 0x1c, KEY_RADIO },	/*XXX*/
+	{ 0x12, KEY_POWER },
 
 	/*  0x01    0x02    0x03  *
 	 *   1       2       3    *
@@ -1248,29 +1339,29 @@ IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
 	 *  0x07    0x08    0x09  *
 	 *   7       8       9    *
 	 *                        */
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
 
 	/*  0x0a    0x00    0x17  *
 	 * RECALL    0      +100  *
 	 *                  PLUS  *
 	 *                        */
-	[ 0x0a ] = KEY_AGAIN,	/*XXX KEY_REWIND? */
-	[ 0x00 ] = KEY_0,
-	[ 0x17 ] = KEY_DIGITS,	/*XXX*/
+	{ 0x0a, KEY_AGAIN },	/*XXX KEY_REWIND? */
+	{ 0x00, KEY_0 },
+	{ 0x17, KEY_DIGITS },	/*XXX*/
 
 	/*  0x14            0x10  *
 	 *  MENU            INFO  *
 	 *  OSD                   */
-	[ 0x14 ] = KEY_MENU,
-	[ 0x10 ] = KEY_INFO,
+	{ 0x14, KEY_MENU },
+	{ 0x10, KEY_INFO },
 
 	/*          0x0b          *
 	 *           Up           *
@@ -1281,18 +1372,18 @@ IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
 	 *         0x015          *
 	 *         Down           *
 	 *                        */
-	[ 0x0b ] = KEY_UP,	/*XXX KEY_SCROLLUP? */
-	[ 0x18 ] = KEY_LEFT,	/*XXX KEY_BACK? */
-	[ 0x16 ] = KEY_OK,	/*XXX KEY_SELECT? KEY_ENTER? */
-	[ 0x0c ] = KEY_RIGHT,	/*XXX KEY_FORWARD? */
-	[ 0x15 ] = KEY_DOWN,	/*XXX KEY_SCROLLDOWN? */
+	{ 0x0b, KEY_UP },
+	{ 0x18, KEY_LEFT },
+	{ 0x16, KEY_OK },	/*XXX KEY_SELECT? KEY_ENTER? */
+	{ 0x0c, KEY_RIGHT },
+	{ 0x15, KEY_DOWN },
 
 	/*  0x11            0x0d  *
 	 *  TV/AV           MODE  *
 	 *  SOURCE         STEREO *
 	 *                        */
-	[ 0x11 ] = KEY_TV,	/*XXX*/
-	[ 0x0d ] = KEY_MODE,	/*XXX there's no KEY_STEREO */
+	{ 0x11, KEY_TV },	/*XXX*/
+	{ 0x0d, KEY_MODE },	/*XXX there's no KEY_STEREO	*/
 
 	/*  0x0f    0x1b    0x1a  *
 	 *  AUDIO   Vol+    Chan+ *
@@ -1301,891 +1392,967 @@ IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE] = {
 	 *  0x0e    0x1f    0x1e  *
 	 *  SLEEP   Vol-    Chan- *
 	 *                        */
-	[ 0x0f ] = KEY_AUDIO,
-	[ 0x1b ] = KEY_VOLUMEUP,
-	[ 0x1a ] = KEY_CHANNELUP,
-	[ 0x0e ] = KEY_SLEEP,	/*XXX maybe KEY_PAUSE */
-	[ 0x1f ] = KEY_VOLUMEDOWN,
-	[ 0x1e ] = KEY_CHANNELDOWN,
+	{ 0x0f, KEY_AUDIO },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x0e, KEY_TIME },
+	{ 0x1f, KEY_VOLUMEDOWN },
+	{ 0x1e, KEY_CHANNELDOWN },
 
 	/*         0x13     0x19  *
 	 *         MUTE   SNAPSHOT*
 	 *                        */
-	[ 0x13 ] = KEY_MUTE,
-	[ 0x19 ] = KEY_RECORD,	/*XXX*/
+	{ 0x13, KEY_MUTE },
+	{ 0x19, KEY_CAMERA },
 
-	// 0x1d unused ?
+	/* 0x1d unused ? */
 };
 
-EXPORT_SYMBOL_GPL(ir_codes_manli);
+struct ir_scancode_table ir_codes_manli_table = {
+	.scan = ir_codes_manli,
+	.size = ARRAY_SIZE(ir_codes_manli),
+};
+EXPORT_SYMBOL_GPL(ir_codes_manli_table);
 
 /* Mike Baikov <mike@baikov.com> */
-IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = {
-
-	[ 0x11 ] = KEY_POWER,
-	[ 0x35 ] = KEY_TV,
-	[ 0x1b ] = KEY_0,
-	[ 0x29 ] = KEY_1,
-	[ 0x19 ] = KEY_2,
-	[ 0x39 ] = KEY_3,
-	[ 0x1f ] = KEY_4,
-	[ 0x2c ] = KEY_5,
-	[ 0x21 ] = KEY_6,
-	[ 0x24 ] = KEY_7,
-	[ 0x18 ] = KEY_8,
-	[ 0x2b ] = KEY_9,
-	[ 0x3b ] = KEY_AGAIN, /* LOOP */
-	[ 0x06 ] = KEY_AUDIO,
-	[ 0x31 ] = KEY_PRINT, /* PREVIEW */
-	[ 0x3e ] = KEY_VIDEO,
-	[ 0x10 ] = KEY_CHANNELUP,
-	[ 0x20 ] = KEY_CHANNELDOWN,
-	[ 0x0c ] = KEY_VOLUMEDOWN,
-	[ 0x28 ] = KEY_VOLUMEUP,
-	[ 0x08 ] = KEY_MUTE,
-	[ 0x26 ] = KEY_SEARCH, /*SCAN*/
-	[ 0x3f ] = KEY_SHUFFLE, /* SNAPSHOT */
-	[ 0x12 ] = KEY_RECORD,
-	[ 0x32 ] = KEY_STOP,
-	[ 0x3c ] = KEY_PLAY,
-	[ 0x1d ] = KEY_REWIND,
-	[ 0x2d ] = KEY_PAUSE,
-	[ 0x0d ] = KEY_FORWARD,
-	[ 0x05 ] = KEY_ZOOM,  /*FULL*/
-
-	[ 0x2a ] = KEY_F21, /* LIVE TIMESHIFT */
-	[ 0x0e ] = KEY_F22, /* MIN TIMESHIFT */
-	[ 0x1e ] = KEY_F23, /* TIMESHIFT */
-	[ 0x38 ] = KEY_F24, /* NORMAL TIMESHIFT */
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_gotview7135);
-
-IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
-	[ 0x03 ] = KEY_POWER,
-	[ 0x6f ] = KEY_MUTE,
-	[ 0x10 ] = KEY_BACKSPACE,       /* Recall */
-
-	[ 0x11 ] = KEY_0,
-	[ 0x04 ] = KEY_1,
-	[ 0x05 ] = KEY_2,
-	[ 0x06 ] = KEY_3,
-	[ 0x08 ] = KEY_4,
-	[ 0x09 ] = KEY_5,
-	[ 0x0a ] = KEY_6,
-	[ 0x0c ] = KEY_7,
-	[ 0x0d ] = KEY_8,
-	[ 0x0e ] = KEY_9,
-	[ 0x12 ] = KEY_DOT,           /* 100+ */
-
-	[ 0x07 ] = KEY_VOLUMEUP,
-	[ 0x0b ] = KEY_VOLUMEDOWN,
-	[ 0x1a ] = KEY_KPPLUS,
-	[ 0x18 ] = KEY_KPMINUS,
-	[ 0x15 ] = KEY_UP,
-	[ 0x1d ] = KEY_DOWN,
-	[ 0x0f ] = KEY_CHANNELUP,
-	[ 0x13 ] = KEY_CHANNELDOWN,
-	[ 0x48 ] = KEY_ZOOM,
-
-	[ 0x1b ] = KEY_VIDEO,           /* Video source */
-	[ 0x49 ] = KEY_LANGUAGE,        /* MTS Select */
-	[ 0x19 ] = KEY_SEARCH,          /* Auto Scan */
-
-	[ 0x4b ] = KEY_RECORD,
-	[ 0x46 ] = KEY_PLAY,
-	[ 0x45 ] = KEY_PAUSE,           /* Pause */
-	[ 0x44 ] = KEY_STOP,
-	[ 0x40 ] = KEY_FORWARD,         /* Forward ? */
-	[ 0x42 ] = KEY_REWIND,          /* Backward ? */
-
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_purpletv);
+static struct ir_scancode ir_codes_gotview7135[] = {
+
+	{ 0x11, KEY_POWER },
+	{ 0x35, KEY_TV },
+	{ 0x1b, KEY_0 },
+	{ 0x29, KEY_1 },
+	{ 0x19, KEY_2 },
+	{ 0x39, KEY_3 },
+	{ 0x1f, KEY_4 },
+	{ 0x2c, KEY_5 },
+	{ 0x21, KEY_6 },
+	{ 0x24, KEY_7 },
+	{ 0x18, KEY_8 },
+	{ 0x2b, KEY_9 },
+	{ 0x3b, KEY_AGAIN },	/* LOOP */
+	{ 0x06, KEY_AUDIO },
+	{ 0x31, KEY_PRINT },	/* PREVIEW */
+	{ 0x3e, KEY_VIDEO },
+	{ 0x10, KEY_CHANNELUP },
+	{ 0x20, KEY_CHANNELDOWN },
+	{ 0x0c, KEY_VOLUMEDOWN },
+	{ 0x28, KEY_VOLUMEUP },
+	{ 0x08, KEY_MUTE },
+	{ 0x26, KEY_SEARCH },	/* SCAN */
+	{ 0x3f, KEY_CAMERA },	/* SNAPSHOT */
+	{ 0x12, KEY_RECORD },
+	{ 0x32, KEY_STOP },
+	{ 0x3c, KEY_PLAY },
+	{ 0x1d, KEY_REWIND },
+	{ 0x2d, KEY_PAUSE },
+	{ 0x0d, KEY_FORWARD },
+	{ 0x05, KEY_ZOOM },	/*FULL*/
+
+	{ 0x2a, KEY_F21 },	/* LIVE TIMESHIFT */
+	{ 0x0e, KEY_F22 },	/* MIN TIMESHIFT */
+	{ 0x1e, KEY_TIME },	/* TIMESHIFT */
+	{ 0x38, KEY_F24 },	/* NORMAL TIMESHIFT */
+};
+
+struct ir_scancode_table ir_codes_gotview7135_table = {
+	.scan = ir_codes_gotview7135,
+	.size = ARRAY_SIZE(ir_codes_gotview7135),
+};
+EXPORT_SYMBOL_GPL(ir_codes_gotview7135_table);
+
+static struct ir_scancode ir_codes_purpletv[] = {
+	{ 0x03, KEY_POWER },
+	{ 0x6f, KEY_MUTE },
+	{ 0x10, KEY_BACKSPACE },	/* Recall */
+
+	{ 0x11, KEY_0 },
+	{ 0x04, KEY_1 },
+	{ 0x05, KEY_2 },
+	{ 0x06, KEY_3 },
+	{ 0x08, KEY_4 },
+	{ 0x09, KEY_5 },
+	{ 0x0a, KEY_6 },
+	{ 0x0c, KEY_7 },
+	{ 0x0d, KEY_8 },
+	{ 0x0e, KEY_9 },
+	{ 0x12, KEY_DOT },	/* 100+ */
+
+	{ 0x07, KEY_VOLUMEUP },
+	{ 0x0b, KEY_VOLUMEDOWN },
+	{ 0x1a, KEY_KPPLUS },
+	{ 0x18, KEY_KPMINUS },
+	{ 0x15, KEY_UP },
+	{ 0x1d, KEY_DOWN },
+	{ 0x0f, KEY_CHANNELUP },
+	{ 0x13, KEY_CHANNELDOWN },
+	{ 0x48, KEY_ZOOM },
+
+	{ 0x1b, KEY_VIDEO },	/* Video source */
+	{ 0x1f, KEY_CAMERA },	/* Snapshot */
+	{ 0x49, KEY_LANGUAGE },	/* MTS Select */
+	{ 0x19, KEY_SEARCH },	/* Auto Scan */
+
+	{ 0x4b, KEY_RECORD },
+	{ 0x46, KEY_PLAY },
+	{ 0x45, KEY_PAUSE },	/* Pause */
+	{ 0x44, KEY_STOP },
+	{ 0x43, KEY_TIME },	/* Time Shift */
+	{ 0x17, KEY_CHANNEL },	/* SURF CH */
+	{ 0x40, KEY_FORWARD },	/* Forward ? */
+	{ 0x42, KEY_REWIND },	/* Backward ? */
+
+};
+
+struct ir_scancode_table ir_codes_purpletv_table = {
+	.scan = ir_codes_purpletv,
+	.size = ARRAY_SIZE(ir_codes_purpletv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_purpletv_table);
 
 /* Mapping for the 28 key remote control as seen at
    http://www.sednacomputer.com/photo/cardbus-tv.jpg
    Pavel Mihaylov <bin@bash.info>
    Also for the remote bundled with Kozumi KTV-01C card */
-IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x0a ] = KEY_AGAIN,          /* Recall */
-	[ 0x0b ] = KEY_CHANNELUP,
-	[ 0x0c ] = KEY_VOLUMEUP,
-	[ 0x0d ] = KEY_MODE,           /* Stereo */
-	[ 0x0e ] = KEY_STOP,
-	[ 0x0f ] = KEY_PREVIOUSSONG,
-	[ 0x10 ] = KEY_ZOOM,
-	[ 0x11 ] = KEY_TUNER,          /* Source */
-	[ 0x12 ] = KEY_POWER,
-	[ 0x13 ] = KEY_MUTE,
-	[ 0x15 ] = KEY_CHANNELDOWN,
-	[ 0x18 ] = KEY_VOLUMEDOWN,
-	[ 0x19 ] = KEY_SHUFFLE,        /* Snapshot */
-	[ 0x1a ] = KEY_NEXTSONG,
-	[ 0x1b ] = KEY_TEXT,           /* Time Shift */
-	[ 0x1c ] = KEY_RADIO,          /* FM Radio */
-	[ 0x1d ] = KEY_RECORD,
-	[ 0x1e ] = KEY_PAUSE,
+static struct ir_scancode ir_codes_pctv_sedna[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0a, KEY_AGAIN },	/* Recall */
+	{ 0x0b, KEY_CHANNELUP },
+	{ 0x0c, KEY_VOLUMEUP },
+	{ 0x0d, KEY_MODE },	/* Stereo */
+	{ 0x0e, KEY_STOP },
+	{ 0x0f, KEY_PREVIOUSSONG },
+	{ 0x10, KEY_ZOOM },
+	{ 0x11, KEY_TUNER },	/* Source */
+	{ 0x12, KEY_POWER },
+	{ 0x13, KEY_MUTE },
+	{ 0x15, KEY_CHANNELDOWN },
+	{ 0x18, KEY_VOLUMEDOWN },
+	{ 0x19, KEY_CAMERA },	/* Snapshot */
+	{ 0x1a, KEY_NEXTSONG },
+	{ 0x1b, KEY_TIME },	/* Time Shift */
+	{ 0x1c, KEY_RADIO },	/* FM Radio */
+	{ 0x1d, KEY_RECORD },
+	{ 0x1e, KEY_PAUSE },
 	/* additional codes for Kozumi's remote */
-	[0x14] = KEY_INFO,        /* OSD */
-	[0x16] = KEY_OK,          /* OK */
-	[0x17] = KEY_DIGITS,      /* Plus */
-	[0x1f] = KEY_PLAY,        /* Play */
+	{ 0x14, KEY_INFO },	/* OSD */
+	{ 0x16, KEY_OK },	/* OK */
+	{ 0x17, KEY_DIGITS },	/* Plus */
+	{ 0x1f, KEY_PLAY },	/* Play */
 };
 
-EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna);
+struct ir_scancode_table ir_codes_pctv_sedna_table = {
+	.scan = ir_codes_pctv_sedna,
+	.size = ARRAY_SIZE(ir_codes_pctv_sedna),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pctv_sedna_table);
 
 /* Mark Phalan <phalanm@o2.ie> */
-IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x12 ] = KEY_POWER,
-	[ 0x10 ] = KEY_MUTE,
-	[ 0x1f ] = KEY_VOLUMEDOWN,
-	[ 0x1b ] = KEY_VOLUMEUP,
-	[ 0x1a ] = KEY_CHANNELUP,
-	[ 0x1e ] = KEY_CHANNELDOWN,
-	[ 0x0e ] = KEY_PAGEUP,
-	[ 0x1d ] = KEY_PAGEDOWN,
-	[ 0x13 ] = KEY_SOUND,
-
-	[ 0x18 ] = KEY_KPPLUSMINUS,	/* CH +/- */
-	[ 0x16 ] = KEY_SUBTITLE,		/* CC */
-	[ 0x0d ] = KEY_TEXT,		/* TTX */
-	[ 0x0b ] = KEY_TV,		/* AIR/CBL */
-	[ 0x11 ] = KEY_PC,		/* PC/TV */
-	[ 0x17 ] = KEY_OK,		/* CH RTN */
-	[ 0x19 ] = KEY_MODE, 		/* FUNC */
-	[ 0x0c ] = KEY_SEARCH, 		/* AUTOSCAN */
+static struct ir_scancode ir_codes_pv951[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x12, KEY_POWER },
+	{ 0x10, KEY_MUTE },
+	{ 0x1f, KEY_VOLUMEDOWN },
+	{ 0x1b, KEY_VOLUMEUP },
+	{ 0x1a, KEY_CHANNELUP },
+	{ 0x1e, KEY_CHANNELDOWN },
+	{ 0x0e, KEY_PAGEUP },
+	{ 0x1d, KEY_PAGEDOWN },
+	{ 0x13, KEY_SOUND },
+
+	{ 0x18, KEY_KPPLUSMINUS },	/* CH +/- */
+	{ 0x16, KEY_SUBTITLE },		/* CC */
+	{ 0x0d, KEY_TEXT },		/* TTX */
+	{ 0x0b, KEY_TV },		/* AIR/CBL */
+	{ 0x11, KEY_PC },		/* PC/TV */
+	{ 0x17, KEY_OK },		/* CH RTN */
+	{ 0x19, KEY_MODE },		/* FUNC */
+	{ 0x0c, KEY_SEARCH },		/* AUTOSCAN */
 
 	/* Not sure what to do with these ones! */
-	[ 0x0f ] = KEY_SELECT, 		/* SOURCE */
-	[ 0x0a ] = KEY_KPPLUS,		/* +100 */
-	[ 0x14 ] = KEY_EQUAL,		/* SYNC */
-	[ 0x1c ] = KEY_MEDIA,             /* PC/TV */
+	{ 0x0f, KEY_SELECT },		/* SOURCE */
+	{ 0x0a, KEY_KPPLUS },		/* +100 */
+	{ 0x14, KEY_EQUAL },		/* SYNC */
+	{ 0x1c, KEY_MEDIA },		/* PC/TV */
 };
 
-EXPORT_SYMBOL_GPL(ir_codes_pv951);
+struct ir_scancode_table ir_codes_pv951_table = {
+	.scan = ir_codes_pv951,
+	.size = ARRAY_SIZE(ir_codes_pv951),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pv951_table);
 
 /* generic RC5 keytable                                          */
 /* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
 /* used by old (black) Hauppauge remotes                         */
-IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_rc5_tv[] = {
 	/* Keys 0 to 9 */
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x0b ] = KEY_CHANNEL,		/* channel / program (japan: 11) */
-	[ 0x0c ] = KEY_POWER,		/* standby */
-	[ 0x0d ] = KEY_MUTE,		/* mute / demute */
-	[ 0x0f ] = KEY_TV,		/* display */
-	[ 0x10 ] = KEY_VOLUMEUP,
-	[ 0x11 ] = KEY_VOLUMEDOWN,
-	[ 0x12 ] = KEY_BRIGHTNESSUP,
-	[ 0x13 ] = KEY_BRIGHTNESSDOWN,
-	[ 0x1e ] = KEY_SEARCH,		/* search + */
-	[ 0x20 ] = KEY_CHANNELUP,	/* channel / program + */
-	[ 0x21 ] = KEY_CHANNELDOWN,	/* channel / program - */
-	[ 0x22 ] = KEY_CHANNEL,		/* alt / channel */
-	[ 0x23 ] = KEY_LANGUAGE,	/* 1st / 2nd language */
-	[ 0x26 ] = KEY_SLEEP,		/* sleeptimer */
-	[ 0x2e ] = KEY_MENU,		/* 2nd controls (USA: menu) */
-	[ 0x30 ] = KEY_PAUSE,
-	[ 0x32 ] = KEY_REWIND,
-	[ 0x33 ] = KEY_GOTO,
-	[ 0x35 ] = KEY_PLAY,
-	[ 0x36 ] = KEY_STOP,
-	[ 0x37 ] = KEY_RECORD,		/* recording */
-	[ 0x3c ] = KEY_TEXT,    	/* teletext submode (Japan: 12) */
-	[ 0x3d ] = KEY_SUSPEND,		/* system standby */
-
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_rc5_tv);
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0b, KEY_CHANNEL },		/* channel / program (japan: 11) */
+	{ 0x0c, KEY_POWER },		/* standby */
+	{ 0x0d, KEY_MUTE },		/* mute / demute */
+	{ 0x0f, KEY_TV },		/* display */
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x12, KEY_BRIGHTNESSUP },
+	{ 0x13, KEY_BRIGHTNESSDOWN },
+	{ 0x1e, KEY_SEARCH },		/* search + */
+	{ 0x20, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x21, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x22, KEY_CHANNEL },		/* alt / channel */
+	{ 0x23, KEY_LANGUAGE },		/* 1st / 2nd language */
+	{ 0x26, KEY_SLEEP },		/* sleeptimer */
+	{ 0x2e, KEY_MENU },		/* 2nd controls (USA: menu) */
+	{ 0x30, KEY_PAUSE },
+	{ 0x32, KEY_REWIND },
+	{ 0x33, KEY_GOTO },
+	{ 0x35, KEY_PLAY },
+	{ 0x36, KEY_STOP },
+	{ 0x37, KEY_RECORD },		/* recording */
+	{ 0x3c, KEY_TEXT },		/* teletext submode (Japan: 12) */
+	{ 0x3d, KEY_SUSPEND },		/* system standby */
+
+};
+
+struct ir_scancode_table ir_codes_rc5_tv_table = {
+	.scan = ir_codes_rc5_tv,
+	.size = ARRAY_SIZE(ir_codes_rc5_tv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_rc5_tv_table);
 
 /* Table for Leadtek Winfast Remote Controls - used by both bttv and cx88 */
-IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_winfast[] = {
 	/* Keys 0 to 9 */
-	[ 0x12 ] = KEY_0,
-	[ 0x05 ] = KEY_1,
-	[ 0x06 ] = KEY_2,
-	[ 0x07 ] = KEY_3,
-	[ 0x09 ] = KEY_4,
-	[ 0x0a ] = KEY_5,
-	[ 0x0b ] = KEY_6,
-	[ 0x0d ] = KEY_7,
-	[ 0x0e ] = KEY_8,
-	[ 0x0f ] = KEY_9,
-
-	[ 0x00 ] = KEY_POWER,
-	[ 0x1b ] = KEY_AUDIO,           /* Audio Source */
-	[ 0x02 ] = KEY_TUNER,		/* TV/FM, not on Y0400052 */
-	[ 0x1e ] = KEY_VIDEO,           /* Video Source */
-	[ 0x16 ] = KEY_INFO,            /* Display information */
-	[ 0x04 ] = KEY_VOLUMEUP,
-	[ 0x08 ] = KEY_VOLUMEDOWN,
-	[ 0x0c ] = KEY_CHANNELUP,
-	[ 0x10 ] = KEY_CHANNELDOWN,
-	[ 0x03 ] = KEY_ZOOM,		/* fullscreen */
-	[ 0x1f ] = KEY_TEXT,		/* closed caption/teletext */
-	[ 0x20 ] = KEY_SLEEP,
-	[ 0x29 ] = KEY_CLEAR,           /* boss key */
-	[ 0x14 ] = KEY_MUTE,
-	[ 0x2b ] = KEY_RED,
-	[ 0x2c ] = KEY_GREEN,
-	[ 0x2d ] = KEY_YELLOW,
-	[ 0x2e ] = KEY_BLUE,
-	[ 0x18 ] = KEY_KPPLUS,		/* fine tune + , not on Y040052 */
-	[ 0x19 ] = KEY_KPMINUS,		/* fine tune - , not on Y040052 */
-	[ 0x2a ] = KEY_MEDIA,           /* PIP (Picture in picture */
-	[ 0x21 ] = KEY_DOT,
-	[ 0x13 ] = KEY_ENTER,
-	[ 0x11 ] = KEY_LAST,            /* Recall (last channel */
-	[ 0x22 ] = KEY_PREVIOUS,
-	[ 0x23 ] = KEY_PLAYPAUSE,
-	[ 0x24 ] = KEY_NEXT,
-	[ 0x25 ] = KEY_ARCHIVE,       /* Time Shifting */
-	[ 0x26 ] = KEY_STOP,
-	[ 0x27 ] = KEY_RECORD,
-	[ 0x28 ] = KEY_SAVE,          /* Screenshot */
-	[ 0x2f ] = KEY_MENU,
-	[ 0x30 ] = KEY_CANCEL,
-	[ 0x31 ] = KEY_CHANNEL,       /* Channel Surf */
-	[ 0x32 ] = KEY_SUBTITLE,
-	[ 0x33 ] = KEY_LANGUAGE,
-	[ 0x34 ] = KEY_REWIND,
-	[ 0x35 ] = KEY_FASTFORWARD,
-	[ 0x36 ] = KEY_TV,
-	[ 0x37 ] = KEY_RADIO,         /* FM */
-	[ 0x38 ] = KEY_DVD,
-
-	[ 0x3e ] = KEY_F21,           /* MCE +VOL, on Y04G0033 */
-	[ 0x3a ] = KEY_F22,           /* MCE -VOL, on Y04G0033 */
-	[ 0x3b ] = KEY_F23,           /* MCE +CH,  on Y04G0033 */
-	[ 0x3f ] = KEY_F24            /* MCE -CH,  on Y04G0033 */
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_winfast);
-
-IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE] = {
-	[ 0x59 ] = KEY_MUTE,
-	[ 0x4a ] = KEY_POWER,
-
-	[ 0x18 ] = KEY_TEXT,
-	[ 0x26 ] = KEY_TV,
-	[ 0x3d ] = KEY_PRINT,
-
-	[ 0x48 ] = KEY_RED,
-	[ 0x04 ] = KEY_GREEN,
-	[ 0x11 ] = KEY_YELLOW,
-	[ 0x00 ] = KEY_BLUE,
-
-	[ 0x2d ] = KEY_VOLUMEUP,
-	[ 0x1e ] = KEY_VOLUMEDOWN,
-
-	[ 0x49 ] = KEY_MENU,
-
-	[ 0x16 ] = KEY_CHANNELUP,
-	[ 0x17 ] = KEY_CHANNELDOWN,
-
-	[ 0x20 ] = KEY_UP,
-	[ 0x21 ] = KEY_DOWN,
-	[ 0x22 ] = KEY_LEFT,
-	[ 0x23 ] = KEY_RIGHT,
-	[ 0x0d ] = KEY_SELECT,
-
-
-
-	[ 0x08 ] = KEY_BACK,
-	[ 0x07 ] = KEY_REFRESH,
-
-	[ 0x2f ] = KEY_ZOOM,
-	[ 0x29 ] = KEY_RECORD,
-
-	[ 0x4b ] = KEY_PAUSE,
-	[ 0x4d ] = KEY_REWIND,
-	[ 0x2e ] = KEY_PLAY,
-	[ 0x4e ] = KEY_FORWARD,
-	[ 0x53 ] = KEY_PREVIOUS,
-	[ 0x4c ] = KEY_STOP,
-	[ 0x54 ] = KEY_NEXT,
-
-	[ 0x69 ] = KEY_0,
-	[ 0x6a ] = KEY_1,
-	[ 0x6b ] = KEY_2,
-	[ 0x6c ] = KEY_3,
-	[ 0x6d ] = KEY_4,
-	[ 0x6e ] = KEY_5,
-	[ 0x6f ] = KEY_6,
-	[ 0x70 ] = KEY_7,
-	[ 0x71 ] = KEY_8,
-	[ 0x72 ] = KEY_9,
-
-	[ 0x74 ] = KEY_CHANNEL,
-	[ 0x0a ] = KEY_BACKSPACE,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color);
+	{ 0x12, KEY_0 },
+	{ 0x05, KEY_1 },
+	{ 0x06, KEY_2 },
+	{ 0x07, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0a, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x0d, KEY_7 },
+	{ 0x0e, KEY_8 },
+	{ 0x0f, KEY_9 },
+
+	{ 0x00, KEY_POWER },
+	{ 0x1b, KEY_AUDIO },		/* Audio Source */
+	{ 0x02, KEY_TUNER },		/* TV/FM, not on Y0400052 */
+	{ 0x1e, KEY_VIDEO },		/* Video Source */
+	{ 0x16, KEY_INFO },		/* Display information */
+	{ 0x04, KEY_VOLUMEUP },
+	{ 0x08, KEY_VOLUMEDOWN },
+	{ 0x0c, KEY_CHANNELUP },
+	{ 0x10, KEY_CHANNELDOWN },
+	{ 0x03, KEY_ZOOM },		/* fullscreen */
+	{ 0x1f, KEY_TEXT },		/* closed caption/teletext */
+	{ 0x20, KEY_SLEEP },
+	{ 0x29, KEY_CLEAR },		/* boss key */
+	{ 0x14, KEY_MUTE },
+	{ 0x2b, KEY_RED },
+	{ 0x2c, KEY_GREEN },
+	{ 0x2d, KEY_YELLOW },
+	{ 0x2e, KEY_BLUE },
+	{ 0x18, KEY_KPPLUS },		/* fine tune + , not on Y040052 */
+	{ 0x19, KEY_KPMINUS },		/* fine tune - , not on Y040052 */
+	{ 0x2a, KEY_MEDIA },		/* PIP (Picture in picture */
+	{ 0x21, KEY_DOT },
+	{ 0x13, KEY_ENTER },
+	{ 0x11, KEY_LAST },		/* Recall (last channel */
+	{ 0x22, KEY_PREVIOUS },
+	{ 0x23, KEY_PLAYPAUSE },
+	{ 0x24, KEY_NEXT },
+	{ 0x25, KEY_TIME },		/* Time Shifting */
+	{ 0x26, KEY_STOP },
+	{ 0x27, KEY_RECORD },
+	{ 0x28, KEY_SAVE },		/* Screenshot */
+	{ 0x2f, KEY_MENU },
+	{ 0x30, KEY_CANCEL },
+	{ 0x31, KEY_CHANNEL },		/* Channel Surf */
+	{ 0x32, KEY_SUBTITLE },
+	{ 0x33, KEY_LANGUAGE },
+	{ 0x34, KEY_REWIND },
+	{ 0x35, KEY_FASTFORWARD },
+	{ 0x36, KEY_TV },
+	{ 0x37, KEY_RADIO },		/* FM */
+	{ 0x38, KEY_DVD },
+
+	{ 0x3e, KEY_F21 },		/* MCE +VOL, on Y04G0033 */
+	{ 0x3a, KEY_F22 },		/* MCE -VOL, on Y04G0033 */
+	{ 0x3b, KEY_F23 },		/* MCE +CH,  on Y04G0033 */
+	{ 0x3f, KEY_F24 }		/* MCE -CH,  on Y04G0033 */
+};
+
+struct ir_scancode_table ir_codes_winfast_table = {
+	.scan = ir_codes_winfast,
+	.size = ARRAY_SIZE(ir_codes_winfast),
+};
+EXPORT_SYMBOL_GPL(ir_codes_winfast_table);
+
+static struct ir_scancode ir_codes_pinnacle_color[] = {
+	{ 0x59, KEY_MUTE },
+	{ 0x4a, KEY_POWER },
+
+	{ 0x18, KEY_TEXT },
+	{ 0x26, KEY_TV },
+	{ 0x3d, KEY_PRINT },
+
+	{ 0x48, KEY_RED },
+	{ 0x04, KEY_GREEN },
+	{ 0x11, KEY_YELLOW },
+	{ 0x00, KEY_BLUE },
+
+	{ 0x2d, KEY_VOLUMEUP },
+	{ 0x1e, KEY_VOLUMEDOWN },
+
+	{ 0x49, KEY_MENU },
+
+	{ 0x16, KEY_CHANNELUP },
+	{ 0x17, KEY_CHANNELDOWN },
+
+	{ 0x20, KEY_UP },
+	{ 0x21, KEY_DOWN },
+	{ 0x22, KEY_LEFT },
+	{ 0x23, KEY_RIGHT },
+	{ 0x0d, KEY_SELECT },
+
+	{ 0x08, KEY_BACK },
+	{ 0x07, KEY_REFRESH },
+
+	{ 0x2f, KEY_ZOOM },
+	{ 0x29, KEY_RECORD },
+
+	{ 0x4b, KEY_PAUSE },
+	{ 0x4d, KEY_REWIND },
+	{ 0x2e, KEY_PLAY },
+	{ 0x4e, KEY_FORWARD },
+	{ 0x53, KEY_PREVIOUS },
+	{ 0x4c, KEY_STOP },
+	{ 0x54, KEY_NEXT },
+
+	{ 0x69, KEY_0 },
+	{ 0x6a, KEY_1 },
+	{ 0x6b, KEY_2 },
+	{ 0x6c, KEY_3 },
+	{ 0x6d, KEY_4 },
+	{ 0x6e, KEY_5 },
+	{ 0x6f, KEY_6 },
+	{ 0x70, KEY_7 },
+	{ 0x71, KEY_8 },
+	{ 0x72, KEY_9 },
+
+	{ 0x74, KEY_CHANNEL },
+	{ 0x0a, KEY_BACKSPACE },
+};
+
+struct ir_scancode_table ir_codes_pinnacle_color_table = {
+	.scan = ir_codes_pinnacle_color,
+	.size = ARRAY_SIZE(ir_codes_pinnacle_color),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle_color_table);
 
 /* Hauppauge: the newer, gray remotes (seems there are multiple
  * slightly different versions), shipped with cx88+ivtv cards.
  * almost rc5 coding, but some non-standard keys */
-IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_hauppauge_new[] = {
 	/* Keys 0 to 9 */
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-
-	[ 0x0a ] = KEY_TEXT,      	/* keypad asterisk as well */
-	[ 0x0b ] = KEY_RED,		/* red button */
-	[ 0x0c ] = KEY_RADIO,
-	[ 0x0d ] = KEY_MENU,
-	[ 0x0e ] = KEY_SUBTITLE,	/* also the # key */
-	[ 0x0f ] = KEY_MUTE,
-	[ 0x10 ] = KEY_VOLUMEUP,
-	[ 0x11 ] = KEY_VOLUMEDOWN,
-	[ 0x12 ] = KEY_PREVIOUS,	/* previous channel */
-	[ 0x14 ] = KEY_UP,
-	[ 0x15 ] = KEY_DOWN,
-	[ 0x16 ] = KEY_LEFT,
-	[ 0x17 ] = KEY_RIGHT,
-	[ 0x18 ] = KEY_VIDEO,		/* Videos */
-	[ 0x19 ] = KEY_AUDIO,		/* Music */
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+
+	{ 0x0a, KEY_TEXT },		/* keypad asterisk as well */
+	{ 0x0b, KEY_RED },		/* red button */
+	{ 0x0c, KEY_RADIO },
+	{ 0x0d, KEY_MENU },
+	{ 0x0e, KEY_SUBTITLE },		/* also the # key */
+	{ 0x0f, KEY_MUTE },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x12, KEY_PREVIOUS },		/* previous channel */
+	{ 0x14, KEY_UP },
+	{ 0x15, KEY_DOWN },
+	{ 0x16, KEY_LEFT },
+	{ 0x17, KEY_RIGHT },
+	{ 0x18, KEY_VIDEO },		/* Videos */
+	{ 0x19, KEY_AUDIO },		/* Music */
 	/* 0x1a: Pictures - presume this means
 	   "Multimedia Home Platform" -
 	   no "PICTURES" key in input.h
 	 */
-	[ 0x1a ] = KEY_MHP,
-
-	[ 0x1b ] = KEY_EPG,		/* Guide */
-	[ 0x1c ] = KEY_TV,
-	[ 0x1e ] = KEY_NEXTSONG,	/* skip >| */
-	[ 0x1f ] = KEY_EXIT,		/* back/exit */
-	[ 0x20 ] = KEY_CHANNELUP,	/* channel / program + */
-	[ 0x21 ] = KEY_CHANNELDOWN,	/* channel / program - */
-	[ 0x22 ] = KEY_CHANNEL,		/* source (old black remote) */
-	[ 0x24 ] = KEY_PREVIOUSSONG,	/* replay |< */
-	[ 0x25 ] = KEY_ENTER,		/* OK */
-	[ 0x26 ] = KEY_SLEEP,		/* minimize (old black remote) */
-	[ 0x29 ] = KEY_BLUE,		/* blue key */
-	[ 0x2e ] = KEY_GREEN,		/* green button */
-	[ 0x30 ] = KEY_PAUSE,		/* pause */
-	[ 0x32 ] = KEY_REWIND,		/* backward << */
-	[ 0x34 ] = KEY_FASTFORWARD,	/* forward >> */
-	[ 0x35 ] = KEY_PLAY,
-	[ 0x36 ] = KEY_STOP,
-	[ 0x37 ] = KEY_RECORD,		/* recording */
-	[ 0x38 ] = KEY_YELLOW,		/* yellow key */
-	[ 0x3b ] = KEY_SELECT,		/* top right button */
-	[ 0x3c ] = KEY_ZOOM,		/* full */
-	[ 0x3d ] = KEY_POWER,		/* system power (green button) */
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new);
-
-IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE] = {
-	[ 0x1d ] = KEY_SWITCHVIDEOMODE, /* switch inputs */
-	[ 0x2a ] = KEY_FRONT,
-
-	[ 0x3e ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x06 ] = KEY_3,
-	[ 0x0a ] = KEY_4,
-	[ 0x0e ] = KEY_5,
-	[ 0x12 ] = KEY_6,
-	[ 0x16 ] = KEY_7,
-	[ 0x1a ] = KEY_8,
-	[ 0x1e ] = KEY_9,
-	[ 0x3a ] = KEY_0,
-	[ 0x22 ] = KEY_NUMLOCK,         /* -/-- */
-	[ 0x20 ] = KEY_REFRESH,
-
-	[ 0x03 ] = KEY_BRIGHTNESSDOWN,
-	[ 0x28 ] = KEY_AUDIO,
-	[ 0x3c ] = KEY_UP,
-	[ 0x3f ] = KEY_LEFT,
-	[ 0x2e ] = KEY_MUTE,
-	[ 0x3b ] = KEY_RIGHT,
-	[ 0x00 ] = KEY_DOWN,
-	[ 0x07 ] = KEY_BRIGHTNESSUP,
-	[ 0x2c ] = KEY_TEXT,
-
-	[ 0x37 ] = KEY_RECORD,
-	[ 0x17 ] = KEY_PLAY,
-	[ 0x13 ] = KEY_PAUSE,
-	[ 0x26 ] = KEY_STOP,
-	[ 0x18 ] = KEY_FASTFORWARD,
-	[ 0x14 ] = KEY_REWIND,
-	[ 0x33 ] = KEY_ZOOM,
-	[ 0x32 ] = KEY_KEYBOARD,
-	[ 0x30 ] = KEY_GOTO,            /* Pointing arrow */
-	[ 0x36 ] = KEY_MACRO,           /* Maximize/Minimize (yellow) */
-	[ 0x0b ] = KEY_RADIO,
-	[ 0x10 ] = KEY_POWER,
-
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_npgtech);
+	{ 0x1a, KEY_MHP },
+
+	{ 0x1b, KEY_EPG },		/* Guide */
+	{ 0x1c, KEY_TV },
+	{ 0x1e, KEY_NEXTSONG },		/* skip >| */
+	{ 0x1f, KEY_EXIT },		/* back/exit */
+	{ 0x20, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x21, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x22, KEY_CHANNEL },		/* source (old black remote) */
+	{ 0x24, KEY_PREVIOUSSONG },	/* replay |< */
+	{ 0x25, KEY_ENTER },		/* OK */
+	{ 0x26, KEY_SLEEP },		/* minimize (old black remote) */
+	{ 0x29, KEY_BLUE },		/* blue key */
+	{ 0x2e, KEY_GREEN },		/* green button */
+	{ 0x30, KEY_PAUSE },		/* pause */
+	{ 0x32, KEY_REWIND },		/* backward << */
+	{ 0x34, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x35, KEY_PLAY },
+	{ 0x36, KEY_STOP },
+	{ 0x37, KEY_RECORD },		/* recording */
+	{ 0x38, KEY_YELLOW },		/* yellow key */
+	{ 0x3b, KEY_SELECT },		/* top right button */
+	{ 0x3c, KEY_ZOOM },		/* full */
+	{ 0x3d, KEY_POWER },		/* system power (green button) */
+};
+
+struct ir_scancode_table ir_codes_hauppauge_new_table = {
+	.scan = ir_codes_hauppauge_new,
+	.size = ARRAY_SIZE(ir_codes_hauppauge_new),
+};
+EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
+
+static struct ir_scancode ir_codes_npgtech[] = {
+	{ 0x1d, KEY_SWITCHVIDEOMODE },	/* switch inputs */
+	{ 0x2a, KEY_FRONT },
+
+	{ 0x3e, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x06, KEY_3 },
+	{ 0x0a, KEY_4 },
+	{ 0x0e, KEY_5 },
+	{ 0x12, KEY_6 },
+	{ 0x16, KEY_7 },
+	{ 0x1a, KEY_8 },
+	{ 0x1e, KEY_9 },
+	{ 0x3a, KEY_0 },
+	{ 0x22, KEY_NUMLOCK },		/* -/-- */
+	{ 0x20, KEY_REFRESH },
+
+	{ 0x03, KEY_BRIGHTNESSDOWN },
+	{ 0x28, KEY_AUDIO },
+	{ 0x3c, KEY_CHANNELUP },
+	{ 0x3f, KEY_VOLUMEDOWN },
+	{ 0x2e, KEY_MUTE },
+	{ 0x3b, KEY_VOLUMEUP },
+	{ 0x00, KEY_CHANNELDOWN },
+	{ 0x07, KEY_BRIGHTNESSUP },
+	{ 0x2c, KEY_TEXT },
+
+	{ 0x37, KEY_RECORD },
+	{ 0x17, KEY_PLAY },
+	{ 0x13, KEY_PAUSE },
+	{ 0x26, KEY_STOP },
+	{ 0x18, KEY_FASTFORWARD },
+	{ 0x14, KEY_REWIND },
+	{ 0x33, KEY_ZOOM },
+	{ 0x32, KEY_KEYBOARD },
+	{ 0x30, KEY_GOTO },		/* Pointing arrow */
+	{ 0x36, KEY_MACRO },		/* Maximize/Minimize (yellow) */
+	{ 0x0b, KEY_RADIO },
+	{ 0x10, KEY_POWER },
+
+};
+
+struct ir_scancode_table ir_codes_npgtech_table = {
+	.scan = ir_codes_npgtech,
+	.size = ARRAY_SIZE(ir_codes_npgtech),
+};
+EXPORT_SYMBOL_GPL(ir_codes_npgtech_table);
 
 /* Norwood Micro (non-Pro) TV Tuner
    By Peter Naulls <peter@chocky.org>
    Key comments are the functions given in the manual */
-IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_norwood[] = {
 	/* Keys 0 to 9 */
-	[ 0x20 ] = KEY_0,
-	[ 0x21 ] = KEY_1,
-	[ 0x22 ] = KEY_2,
-	[ 0x23 ] = KEY_3,
-	[ 0x24 ] = KEY_4,
-	[ 0x25 ] = KEY_5,
-	[ 0x26 ] = KEY_6,
-	[ 0x27 ] = KEY_7,
-	[ 0x28 ] = KEY_8,
-	[ 0x29 ] = KEY_9,
-
-	[ 0x78 ] = KEY_TUNER,             /* Video Source        */
-	[ 0x2c ] = KEY_EXIT,              /* Open/Close software */
-	[ 0x2a ] = KEY_SELECT,            /* 2 Digit Select      */
-	[ 0x69 ] = KEY_AGAIN,             /* Recall              */
-
-	[ 0x32 ] = KEY_BRIGHTNESSUP,      /* Brightness increase */
-	[ 0x33 ] = KEY_BRIGHTNESSDOWN,    /* Brightness decrease */
-	[ 0x6b ] = KEY_KPPLUS,            /* (not named >>>>>)   */
-	[ 0x6c ] = KEY_KPMINUS,           /* (not named <<<<<)   */
-
-	[ 0x2d ] = KEY_MUTE,              /* Mute                */
-	[ 0x30 ] = KEY_VOLUMEUP,          /* Volume up           */
-	[ 0x31 ] = KEY_VOLUMEDOWN,        /* Volume down         */
-	[ 0x60 ] = KEY_CHANNELUP,         /* Channel up          */
-	[ 0x61 ] = KEY_CHANNELDOWN,       /* Channel down        */
-
-	[ 0x3f ] = KEY_RECORD,            /* Record              */
-	[ 0x37 ] = KEY_PLAY,              /* Play                */
-	[ 0x36 ] = KEY_PAUSE,             /* Pause               */
-	[ 0x2b ] = KEY_STOP,              /* Stop                */
-	[ 0x67 ] = KEY_FASTFORWARD,       /* Foward              */
-	[ 0x66 ] = KEY_REWIND,            /* Rewind              */
-	[ 0x3e ] = KEY_SEARCH,            /* Auto Scan           */
-	[ 0x2e ] = KEY_CAMERA,            /* Capture Video       */
-	[ 0x6d ] = KEY_MENU,              /* Show/Hide Control   */
-	[ 0x2f ] = KEY_ZOOM,              /* Full Screen         */
-	[ 0x34 ] = KEY_RADIO,             /* FM                  */
-	[ 0x65 ] = KEY_POWER,             /* Computer power      */
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_norwood);
+	{ 0x20, KEY_0 },
+	{ 0x21, KEY_1 },
+	{ 0x22, KEY_2 },
+	{ 0x23, KEY_3 },
+	{ 0x24, KEY_4 },
+	{ 0x25, KEY_5 },
+	{ 0x26, KEY_6 },
+	{ 0x27, KEY_7 },
+	{ 0x28, KEY_8 },
+	{ 0x29, KEY_9 },
+
+	{ 0x78, KEY_TUNER },		/* Video Source        */
+	{ 0x2c, KEY_EXIT },		/* Open/Close software */
+	{ 0x2a, KEY_SELECT },		/* 2 Digit Select      */
+	{ 0x69, KEY_AGAIN },		/* Recall              */
+
+	{ 0x32, KEY_BRIGHTNESSUP },	/* Brightness increase */
+	{ 0x33, KEY_BRIGHTNESSDOWN },	/* Brightness decrease */
+	{ 0x6b, KEY_KPPLUS },		/* (not named >>>>>)   */
+	{ 0x6c, KEY_KPMINUS },		/* (not named <<<<<)   */
+
+	{ 0x2d, KEY_MUTE },		/* Mute                */
+	{ 0x30, KEY_VOLUMEUP },		/* Volume up           */
+	{ 0x31, KEY_VOLUMEDOWN },	/* Volume down         */
+	{ 0x60, KEY_CHANNELUP },	/* Channel up          */
+	{ 0x61, KEY_CHANNELDOWN },	/* Channel down        */
+
+	{ 0x3f, KEY_RECORD },		/* Record              */
+	{ 0x37, KEY_PLAY },		/* Play                */
+	{ 0x36, KEY_PAUSE },		/* Pause               */
+	{ 0x2b, KEY_STOP },		/* Stop                */
+	{ 0x67, KEY_FASTFORWARD },	/* Foward              */
+	{ 0x66, KEY_REWIND },		/* Rewind              */
+	{ 0x3e, KEY_SEARCH },		/* Auto Scan           */
+	{ 0x2e, KEY_CAMERA },		/* Capture Video       */
+	{ 0x6d, KEY_MENU },		/* Show/Hide Control   */
+	{ 0x2f, KEY_ZOOM },		/* Full Screen         */
+	{ 0x34, KEY_RADIO },		/* FM                  */
+	{ 0x65, KEY_POWER },		/* Computer power      */
+};
+
+struct ir_scancode_table ir_codes_norwood_table = {
+	.scan = ir_codes_norwood,
+	.size = ARRAY_SIZE(ir_codes_norwood),
+};
+EXPORT_SYMBOL_GPL(ir_codes_norwood_table);
 
 /* From reading the following remotes:
  * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
  * Hauppauge (from NOVA-CI-s box product)
  * This is a "middle of the road" approach, differences are noted
  */
-IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = {
-	[ 0x00 ] = KEY_0,
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
-	[ 0x0a ] = KEY_ENTER,
-	[ 0x0b ] = KEY_RED,
-	[ 0x0c ] = KEY_POWER,             /* RADIO on Hauppauge */
-	[ 0x0d ] = KEY_MUTE,
-	[ 0x0f ] = KEY_A,                 /* TV on Hauppauge */
-	[ 0x10 ] = KEY_VOLUMEUP,
-	[ 0x11 ] = KEY_VOLUMEDOWN,
-	[ 0x14 ] = KEY_B,
-	[ 0x1c ] = KEY_UP,
-	[ 0x1d ] = KEY_DOWN,
-	[ 0x1e ] = KEY_OPTION,            /* RESERVED on Hauppauge */
-	[ 0x1f ] = KEY_BREAK,
-	[ 0x20 ] = KEY_CHANNELUP,
-	[ 0x21 ] = KEY_CHANNELDOWN,
-	[ 0x22 ] = KEY_PREVIOUS,          /* Prev. Ch on Zenith, SOURCE on Hauppauge */
-	[ 0x24 ] = KEY_RESTART,
-	[ 0x25 ] = KEY_OK,
-	[ 0x26 ] = KEY_CYCLEWINDOWS,      /* MINIMIZE on Hauppauge */
-	[ 0x28 ] = KEY_ENTER,             /* VCR mode on Zenith */
-	[ 0x29 ] = KEY_PAUSE,
-	[ 0x2b ] = KEY_RIGHT,
-	[ 0x2c ] = KEY_LEFT,
-	[ 0x2e ] = KEY_MENU,              /* FULL SCREEN on Hauppauge */
-	[ 0x30 ] = KEY_SLOW,
-	[ 0x31 ] = KEY_PREVIOUS,          /* VCR mode on Zenith */
-	[ 0x32 ] = KEY_REWIND,
-	[ 0x34 ] = KEY_FASTFORWARD,
-	[ 0x35 ] = KEY_PLAY,
-	[ 0x36 ] = KEY_STOP,
-	[ 0x37 ] = KEY_RECORD,
-	[ 0x38 ] = KEY_TUNER,             /* TV/VCR on Zenith */
-	[ 0x3a ] = KEY_C,
-	[ 0x3c ] = KEY_EXIT,
-	[ 0x3d ] = KEY_POWER2,
-	[ 0x3e ] = KEY_TUNER,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old);
+static struct ir_scancode ir_codes_budget_ci_old[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0a, KEY_ENTER },
+	{ 0x0b, KEY_RED },
+	{ 0x0c, KEY_POWER },		/* RADIO on Hauppauge */
+	{ 0x0d, KEY_MUTE },
+	{ 0x0f, KEY_A },		/* TV on Hauppauge */
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x14, KEY_B },
+	{ 0x1c, KEY_UP },
+	{ 0x1d, KEY_DOWN },
+	{ 0x1e, KEY_OPTION },		/* RESERVED on Hauppauge */
+	{ 0x1f, KEY_BREAK },
+	{ 0x20, KEY_CHANNELUP },
+	{ 0x21, KEY_CHANNELDOWN },
+	{ 0x22, KEY_PREVIOUS },		/* Prev Ch on Zenith, SOURCE on Hauppauge */
+	{ 0x24, KEY_RESTART },
+	{ 0x25, KEY_OK },
+	{ 0x26, KEY_CYCLEWINDOWS },	/* MINIMIZE on Hauppauge */
+	{ 0x28, KEY_ENTER },		/* VCR mode on Zenith */
+	{ 0x29, KEY_PAUSE },
+	{ 0x2b, KEY_RIGHT },
+	{ 0x2c, KEY_LEFT },
+	{ 0x2e, KEY_MENU },		/* FULL SCREEN on Hauppauge */
+	{ 0x30, KEY_SLOW },
+	{ 0x31, KEY_PREVIOUS },		/* VCR mode on Zenith */
+	{ 0x32, KEY_REWIND },
+	{ 0x34, KEY_FASTFORWARD },
+	{ 0x35, KEY_PLAY },
+	{ 0x36, KEY_STOP },
+	{ 0x37, KEY_RECORD },
+	{ 0x38, KEY_TUNER },		/* TV/VCR on Zenith */
+	{ 0x3a, KEY_C },
+	{ 0x3c, KEY_EXIT },
+	{ 0x3d, KEY_POWER2 },
+	{ 0x3e, KEY_TUNER },
+};
+
+struct ir_scancode_table ir_codes_budget_ci_old_table = {
+	.scan = ir_codes_budget_ci_old,
+	.size = ARRAY_SIZE(ir_codes_budget_ci_old),
+};
+EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old_table);
 
 /*
  * Marc Fargas <telenieko@telenieko.com>
  * this is the remote control that comes with the asus p7131
  * which has a label saying is "Model PC-39"
  */
-IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_asus_pc39[] = {
 	/* Keys 0 to 9 */
-	[ 0x15 ] = KEY_0,
-	[ 0x29 ] = KEY_1,
-	[ 0x2d ] = KEY_2,
-	[ 0x2b ] = KEY_3,
-	[ 0x09 ] = KEY_4,
-	[ 0x0d ] = KEY_5,
-	[ 0x0b ] = KEY_6,
-	[ 0x31 ] = KEY_7,
-	[ 0x35 ] = KEY_8,
-	[ 0x33 ] = KEY_9,
-
-	[ 0x3e ] = KEY_RADIO,		/* radio */
-	[ 0x03 ] = KEY_MENU,		/* dvd/menu */
-	[ 0x2a ] = KEY_VOLUMEUP,
-	[ 0x19 ] = KEY_VOLUMEDOWN,
-	[ 0x37 ] = KEY_UP,
-	[ 0x3b ] = KEY_DOWN,
-	[ 0x27 ] = KEY_LEFT,
-	[ 0x2f ] = KEY_RIGHT,
-	[ 0x25 ] = KEY_VIDEO,		/* video */
-	[ 0x39 ] = KEY_AUDIO,		/* music */
-
-	[ 0x21 ] = KEY_TV,		/* tv */
-	[ 0x1d ] = KEY_EXIT,		/* back */
-	[ 0x0a ] = KEY_CHANNELUP,	/* channel / program + */
-	[ 0x1b ] = KEY_CHANNELDOWN,	/* channel / program - */
-	[ 0x1a ] = KEY_ENTER,		/* enter */
-
-	[ 0x06 ] = KEY_PAUSE,		/* play/pause */
-	[ 0x1e ] = KEY_PREVIOUS,	/* rew */
-	[ 0x26 ] = KEY_NEXT,		/* forward */
-	[ 0x0e ] = KEY_REWIND,		/* backward << */
-	[ 0x3a ] = KEY_FASTFORWARD,	/* forward >> */
-	[ 0x36 ] = KEY_STOP,
-	[ 0x2e ] = KEY_RECORD,		/* recording */
-	[ 0x16 ] = KEY_POWER,		/* the button that reads "close" */
-
-	[ 0x11 ] = KEY_ZOOM,		/* full screen */
-	[ 0x13 ] = KEY_MACRO,		/* recall */
-	[ 0x23 ] = KEY_HOME,		/* home */
-	[ 0x05 ] = KEY_PVR,		/* picture */
-	[ 0x3d ] = KEY_MUTE,		/* mute */
-	[ 0x01 ] = KEY_DVD,		/* dvd */
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_asus_pc39);
+	{ 0x15, KEY_0 },
+	{ 0x29, KEY_1 },
+	{ 0x2d, KEY_2 },
+	{ 0x2b, KEY_3 },
+	{ 0x09, KEY_4 },
+	{ 0x0d, KEY_5 },
+	{ 0x0b, KEY_6 },
+	{ 0x31, KEY_7 },
+	{ 0x35, KEY_8 },
+	{ 0x33, KEY_9 },
+
+	{ 0x3e, KEY_RADIO },		/* radio */
+	{ 0x03, KEY_MENU },		/* dvd/menu */
+	{ 0x2a, KEY_VOLUMEUP },
+	{ 0x19, KEY_VOLUMEDOWN },
+	{ 0x37, KEY_UP },
+	{ 0x3b, KEY_DOWN },
+	{ 0x27, KEY_LEFT },
+	{ 0x2f, KEY_RIGHT },
+	{ 0x25, KEY_VIDEO },		/* video */
+	{ 0x39, KEY_AUDIO },		/* music */
+
+	{ 0x21, KEY_TV },		/* tv */
+	{ 0x1d, KEY_EXIT },		/* back */
+	{ 0x0a, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x1b, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x1a, KEY_ENTER },		/* enter */
+
+	{ 0x06, KEY_PAUSE },		/* play/pause */
+	{ 0x1e, KEY_PREVIOUS },		/* rew */
+	{ 0x26, KEY_NEXT },		/* forward */
+	{ 0x0e, KEY_REWIND },		/* backward << */
+	{ 0x3a, KEY_FASTFORWARD },	/* forward >> */
+	{ 0x36, KEY_STOP },
+	{ 0x2e, KEY_RECORD },		/* recording */
+	{ 0x16, KEY_POWER },		/* the button that reads "close" */
+
+	{ 0x11, KEY_ZOOM },		/* full screen */
+	{ 0x13, KEY_MACRO },		/* recall */
+	{ 0x23, KEY_HOME },		/* home */
+	{ 0x05, KEY_PVR },		/* picture */
+	{ 0x3d, KEY_MUTE },		/* mute */
+	{ 0x01, KEY_DVD },		/* dvd */
+};
+
+struct ir_scancode_table ir_codes_asus_pc39_table = {
+	.scan = ir_codes_asus_pc39,
+	.size = ARRAY_SIZE(ir_codes_asus_pc39),
+};
+EXPORT_SYMBOL_GPL(ir_codes_asus_pc39_table);
 
 
 /* Encore ENLTV-FM  - black plastic, white front cover with white glowing buttons
     Juan Pablo Sormani <sorman@gmail.com> */
-IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_encore_enltv[] = {
 
 	/* Power button does nothing, neither in Windows app,
 	 although it sends data (used for BIOS wakeup?) */
-	[ 0x0d ] = KEY_MUTE,
-
-	[ 0x1e ] = KEY_TV,
-	[ 0x00 ] = KEY_VIDEO,
-	[ 0x01 ] = KEY_AUDIO,		/* music */
-	[ 0x02 ] = KEY_MHP,		/* picture */
-
-	[ 0x1f ] = KEY_1,
-	[ 0x03 ] = KEY_2,
-	[ 0x04 ] = KEY_3,
-	[ 0x05 ] = KEY_4,
-	[ 0x1c ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x1d ] = KEY_9,
-	[ 0x0a ] = KEY_0,
-
-	[ 0x09 ] = KEY_LIST,        /* -/-- */
-	[ 0x0b ] = KEY_LAST,        /* recall */
-
-	[ 0x14 ] = KEY_HOME,		/* win start menu */
-	[ 0x15 ] = KEY_EXIT,		/* exit */
-	[ 0x16 ] = KEY_UP,
-	[ 0x12 ] = KEY_DOWN,
-	[ 0x0c ] = KEY_RIGHT,
-	[ 0x17 ] = KEY_LEFT,
-
-	[ 0x18 ] = KEY_ENTER,		/* OK */
-
-	[ 0x0e ] = KEY_ESC,
-	[ 0x13 ] = KEY_D,		/* desktop */
-	[ 0x11 ] = KEY_TAB,
-	[ 0x19 ] = KEY_SWITCHVIDEOMODE,	/* switch */
-
-	[ 0x1a ] = KEY_MENU,
-	[ 0x1b ] = KEY_ZOOM,		/* fullscreen */
-	[ 0x44 ] = KEY_TIME,		/* time shift */
-	[ 0x40 ] = KEY_MODE,		/* source */
-
-	[ 0x5a ] = KEY_RECORD,
-	[ 0x42 ] = KEY_PLAY,		/* play/pause */
-	[ 0x45 ] = KEY_STOP,
-	[ 0x43 ] = KEY_CAMERA,		/* camera icon */
-
-	[ 0x48 ] = KEY_REWIND,
-	[ 0x4a ] = KEY_FASTFORWARD,
-	[ 0x49 ] = KEY_PREVIOUS,
-	[ 0x4b ] = KEY_NEXT,
-
-	[ 0x4c ] = KEY_FAVORITES,	/* tv wall */
-	[ 0x4d ] = KEY_SOUND,		/* DVD sound */
-	[ 0x4e ] = KEY_LANGUAGE,	/* DVD lang */
-	[ 0x4f ] = KEY_TEXT,		/* DVD text */
-
-	[ 0x50 ] = KEY_SLEEP,		/* shutdown */
-	[ 0x51 ] = KEY_MODE,		/* stereo > main */
-	[ 0x52 ] = KEY_SELECT,		/* stereo > sap */
-	[ 0x53 ] = KEY_PROG1,		/* teletext */
-
-
-	[ 0x59 ] = KEY_RED,		/* AP1 */
-	[ 0x41 ] = KEY_GREEN,		/* AP2 */
-	[ 0x47 ] = KEY_YELLOW,		/* AP3 */
-	[ 0x57 ] = KEY_BLUE,		/* AP4 */
-};
-EXPORT_SYMBOL_GPL(ir_codes_encore_enltv);
+	{ 0x0d, KEY_MUTE },
+
+	{ 0x1e, KEY_TV },
+	{ 0x00, KEY_VIDEO },
+	{ 0x01, KEY_AUDIO },		/* music */
+	{ 0x02, KEY_MHP },		/* picture */
+
+	{ 0x1f, KEY_1 },
+	{ 0x03, KEY_2 },
+	{ 0x04, KEY_3 },
+	{ 0x05, KEY_4 },
+	{ 0x1c, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x1d, KEY_9 },
+	{ 0x0a, KEY_0 },
+
+	{ 0x09, KEY_LIST },		/* -/-- */
+	{ 0x0b, KEY_LAST },		/* recall */
+
+	{ 0x14, KEY_HOME },		/* win start menu */
+	{ 0x15, KEY_EXIT },		/* exit */
+	{ 0x16, KEY_CHANNELUP },	/* UP */
+	{ 0x12, KEY_CHANNELDOWN },	/* DOWN */
+	{ 0x0c, KEY_VOLUMEUP },		/* RIGHT */
+	{ 0x17, KEY_VOLUMEDOWN },	/* LEFT */
+
+	{ 0x18, KEY_ENTER },		/* OK */
+
+	{ 0x0e, KEY_ESC },
+	{ 0x13, KEY_CYCLEWINDOWS },	/* desktop */
+	{ 0x11, KEY_TAB },
+	{ 0x19, KEY_SWITCHVIDEOMODE },	/* switch */
+
+	{ 0x1a, KEY_MENU },
+	{ 0x1b, KEY_ZOOM },		/* fullscreen */
+	{ 0x44, KEY_TIME },		/* time shift */
+	{ 0x40, KEY_MODE },		/* source */
+
+	{ 0x5a, KEY_RECORD },
+	{ 0x42, KEY_PLAY },		/* play/pause */
+	{ 0x45, KEY_STOP },
+	{ 0x43, KEY_CAMERA },		/* camera icon */
+
+	{ 0x48, KEY_REWIND },
+	{ 0x4a, KEY_FASTFORWARD },
+	{ 0x49, KEY_PREVIOUS },
+	{ 0x4b, KEY_NEXT },
+
+	{ 0x4c, KEY_FAVORITES },	/* tv wall */
+	{ 0x4d, KEY_SOUND },		/* DVD sound */
+	{ 0x4e, KEY_LANGUAGE },		/* DVD lang */
+	{ 0x4f, KEY_TEXT },		/* DVD text */
+
+	{ 0x50, KEY_SLEEP },		/* shutdown */
+	{ 0x51, KEY_MODE },		/* stereo > main */
+	{ 0x52, KEY_SELECT },		/* stereo > sap */
+	{ 0x53, KEY_PROG1 },		/* teletext */
+
+
+	{ 0x59, KEY_RED },		/* AP1 */
+	{ 0x41, KEY_GREEN },		/* AP2 */
+	{ 0x47, KEY_YELLOW },		/* AP3 */
+	{ 0x57, KEY_BLUE },		/* AP4 */
+};
+
+struct ir_scancode_table ir_codes_encore_enltv_table = {
+	.scan = ir_codes_encore_enltv,
+	.size = ARRAY_SIZE(ir_codes_encore_enltv),
+};
+EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_table);
 
 /* Encore ENLTV2-FM  - silver plastic - "Wand Media" written at the botton
     Mauro Carvalho Chehab <mchehab@infradead.org> */
-IR_KEYTAB_TYPE ir_codes_encore_enltv2[IR_KEYTAB_SIZE] = {
-	[0x4c] = KEY_POWER2,
-	[0x4a] = KEY_TUNER,
-	[0x40] = KEY_1,
-	[0x60] = KEY_2,
-	[0x50] = KEY_3,
-	[0x70] = KEY_4,
-	[0x48] = KEY_5,
-	[0x68] = KEY_6,
-	[0x58] = KEY_7,
-	[0x78] = KEY_8,
-	[0x44] = KEY_9,
-	[0x54] = KEY_0,
-
-	[0x64] = KEY_LAST,		/* +100 */
-	[0x4e] = KEY_AGAIN,		/* Recall */
-
-	[0x6c] = KEY_SWITCHVIDEOMODE,	/* Video Source */
-	[0x5e] = KEY_MENU,
-	[0x56] = KEY_SCREEN,
-	[0x7a] = KEY_SETUP,
-
-	[0x46] = KEY_MUTE,
-	[0x5c] = KEY_MODE,		/* Stereo */
-	[0x74] = KEY_INFO,
-	[0x7c] = KEY_CLEAR,
-
-	[0x55] = KEY_UP,
-	[0x49] = KEY_DOWN,
-	[0x7e] = KEY_LEFT,
-	[0x59] = KEY_RIGHT,
-	[0x6a] = KEY_ENTER,
-
-	[0x42] = KEY_VOLUMEUP,
-	[0x62] = KEY_VOLUMEDOWN,
-	[0x52] = KEY_CHANNELUP,
-	[0x72] = KEY_CHANNELDOWN,
-
-	[0x41] = KEY_RECORD,
-	[0x51] = KEY_SHUFFLE,	/* Snapshot */
-	[0x75] = KEY_TIME,	/* Timeshift */
-	[0x71] = KEY_TV2,	/* PIP */
-
-	[0x45] = KEY_REWIND,
-	[0x6f] = KEY_PAUSE,
-	[0x7d] = KEY_FORWARD,
-	[0x79] = KEY_STOP,
-};
-EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2);
+static struct ir_scancode ir_codes_encore_enltv2[] = {
+	{ 0x4c, KEY_POWER2 },
+	{ 0x4a, KEY_TUNER },
+	{ 0x40, KEY_1 },
+	{ 0x60, KEY_2 },
+	{ 0x50, KEY_3 },
+	{ 0x70, KEY_4 },
+	{ 0x48, KEY_5 },
+	{ 0x68, KEY_6 },
+	{ 0x58, KEY_7 },
+	{ 0x78, KEY_8 },
+	{ 0x44, KEY_9 },
+	{ 0x54, KEY_0 },
+
+	{ 0x64, KEY_LAST },		/* +100 */
+	{ 0x4e, KEY_AGAIN },		/* Recall */
+
+	{ 0x6c, KEY_SWITCHVIDEOMODE },	/* Video Source */
+	{ 0x5e, KEY_MENU },
+	{ 0x56, KEY_SCREEN },
+	{ 0x7a, KEY_SETUP },
+
+	{ 0x46, KEY_MUTE },
+	{ 0x5c, KEY_MODE },		/* Stereo */
+	{ 0x74, KEY_INFO },
+	{ 0x7c, KEY_CLEAR },
+
+	{ 0x55, KEY_UP },
+	{ 0x49, KEY_DOWN },
+	{ 0x7e, KEY_LEFT },
+	{ 0x59, KEY_RIGHT },
+	{ 0x6a, KEY_ENTER },
+
+	{ 0x42, KEY_VOLUMEUP },
+	{ 0x62, KEY_VOLUMEDOWN },
+	{ 0x52, KEY_CHANNELUP },
+	{ 0x72, KEY_CHANNELDOWN },
+
+	{ 0x41, KEY_RECORD },
+	{ 0x51, KEY_CAMERA },		/* Snapshot */
+	{ 0x75, KEY_TIME },		/* Timeshift */
+	{ 0x71, KEY_TV2 },		/* PIP */
+
+	{ 0x45, KEY_REWIND },
+	{ 0x6f, KEY_PAUSE },
+	{ 0x7d, KEY_FORWARD },
+	{ 0x79, KEY_STOP },
+};
+
+struct ir_scancode_table ir_codes_encore_enltv2_table = {
+	.scan = ir_codes_encore_enltv2,
+	.size = ARRAY_SIZE(ir_codes_encore_enltv2),
+};
+EXPORT_SYMBOL_GPL(ir_codes_encore_enltv2_table);
 
 /* for the Technotrend 1500 bundled remotes (grey and black): */
-IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
-	[ 0x01 ] = KEY_POWER,
-	[ 0x02 ] = KEY_SHUFFLE,	/* ? double-arrow key */
-	[ 0x03 ] = KEY_1,
-	[ 0x04 ] = KEY_2,
-	[ 0x05 ] = KEY_3,
-	[ 0x06 ] = KEY_4,
-	[ 0x07 ] = KEY_5,
-	[ 0x08 ] = KEY_6,
-	[ 0x09 ] = KEY_7,
-	[ 0x0a ] = KEY_8,
-	[ 0x0b ] = KEY_9,
-	[ 0x0c ] = KEY_0,
-	[ 0x0d ] = KEY_UP,
-	[ 0x0e ] = KEY_LEFT,
-	[ 0x0f ] = KEY_OK,
-	[ 0x10 ] = KEY_RIGHT,
-	[ 0x11 ] = KEY_DOWN,
-	[ 0x12 ] = KEY_INFO,
-	[ 0x13 ] = KEY_EXIT,
-	[ 0x14 ] = KEY_RED,
-	[ 0x15 ] = KEY_GREEN,
-	[ 0x16 ] = KEY_YELLOW,
-	[ 0x17 ] = KEY_BLUE,
-	[ 0x18 ] = KEY_MUTE,
-	[ 0x19 ] = KEY_TEXT,
-	[ 0x1a ] = KEY_MODE,	/* ? TV/Radio */
-	[ 0x21 ] = KEY_OPTION,
-	[ 0x22 ] = KEY_EPG,
-	[ 0x23 ] = KEY_CHANNELUP,
-	[ 0x24 ] = KEY_CHANNELDOWN,
-	[ 0x25 ] = KEY_VOLUMEUP,
-	[ 0x26 ] = KEY_VOLUMEDOWN,
-	[ 0x27 ] = KEY_SETUP,
-	[ 0x3a ] = KEY_RECORD, /* these keys are only in the black remote */
-	[ 0x3b ] = KEY_PLAY,
-	[ 0x3c ] = KEY_STOP,
-	[ 0x3d ] = KEY_REWIND,
-	[ 0x3e ] = KEY_PAUSE,
-	[ 0x3f ] = KEY_FORWARD,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
+static struct ir_scancode ir_codes_tt_1500[] = {
+	{ 0x01, KEY_POWER },
+	{ 0x02, KEY_SHUFFLE },		/* ? double-arrow key */
+	{ 0x03, KEY_1 },
+	{ 0x04, KEY_2 },
+	{ 0x05, KEY_3 },
+	{ 0x06, KEY_4 },
+	{ 0x07, KEY_5 },
+	{ 0x08, KEY_6 },
+	{ 0x09, KEY_7 },
+	{ 0x0a, KEY_8 },
+	{ 0x0b, KEY_9 },
+	{ 0x0c, KEY_0 },
+	{ 0x0d, KEY_UP },
+	{ 0x0e, KEY_LEFT },
+	{ 0x0f, KEY_OK },
+	{ 0x10, KEY_RIGHT },
+	{ 0x11, KEY_DOWN },
+	{ 0x12, KEY_INFO },
+	{ 0x13, KEY_EXIT },
+	{ 0x14, KEY_RED },
+	{ 0x15, KEY_GREEN },
+	{ 0x16, KEY_YELLOW },
+	{ 0x17, KEY_BLUE },
+	{ 0x18, KEY_MUTE },
+	{ 0x19, KEY_TEXT },
+	{ 0x1a, KEY_MODE },		/* ? TV/Radio */
+	{ 0x21, KEY_OPTION },
+	{ 0x22, KEY_EPG },
+	{ 0x23, KEY_CHANNELUP },
+	{ 0x24, KEY_CHANNELDOWN },
+	{ 0x25, KEY_VOLUMEUP },
+	{ 0x26, KEY_VOLUMEDOWN },
+	{ 0x27, KEY_SETUP },
+	{ 0x3a, KEY_RECORD },		/* these keys are only in the black remote */
+	{ 0x3b, KEY_PLAY },
+	{ 0x3c, KEY_STOP },
+	{ 0x3d, KEY_REWIND },
+	{ 0x3e, KEY_PAUSE },
+	{ 0x3f, KEY_FORWARD },
+};
+
+struct ir_scancode_table ir_codes_tt_1500_table = {
+	.scan = ir_codes_tt_1500,
+	.size = ARRAY_SIZE(ir_codes_tt_1500),
+};
+EXPORT_SYMBOL_GPL(ir_codes_tt_1500_table);
 
 /* DViCO FUSION HDTV MCE remote */
-IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE] = {
-
-	[ 0x0b ] = KEY_1,
-	[ 0x17 ] = KEY_2,
-	[ 0x1b ] = KEY_3,
-	[ 0x07 ] = KEY_4,
-	[ 0x50 ] = KEY_5,
-	[ 0x54 ] = KEY_6,
-	[ 0x48 ] = KEY_7,
-	[ 0x4c ] = KEY_8,
-	[ 0x58 ] = KEY_9,
-	[ 0x03 ] = KEY_0,
-
-	[ 0x5e ] = KEY_OK,
-	[ 0x51 ] = KEY_UP,
-	[ 0x53 ] = KEY_DOWN,
-	[ 0x5b ] = KEY_LEFT,
-	[ 0x5f ] = KEY_RIGHT,
-
-	[ 0x02 ] = KEY_TV,		/* Labeled DTV on remote */
-	[ 0x0e ] = KEY_MP3,
-	[ 0x1a ] = KEY_DVD,
-	[ 0x1e ] = KEY_FAVORITES,	/* Labeled CPF on remote */
-	[ 0x16 ] = KEY_SETUP,
-	[ 0x46 ] = KEY_POWER2,		/* TV On/Off button on remote */
-	[ 0x0a ] = KEY_EPG,		/* Labeled Guide on remote */
-
-	[ 0x49 ] = KEY_BACK,
-	[ 0x59 ] = KEY_INFO,		/* Labeled MORE on remote */
-	[ 0x4d ] = KEY_MENU,		/* Labeled DVDMENU on remote */
-	[ 0x55 ] = KEY_CYCLEWINDOWS,	/* Labeled ALT-TAB on remote */
-
-	[ 0x0f ] = KEY_PREVIOUSSONG,	/* Labeled |<< REPLAY on remote */
-	[ 0x12 ] = KEY_NEXTSONG,	/* Labeled >>| SKIP on remote */
-	[ 0x42 ] = KEY_ENTER, 		/* Labeled START with a green
-					 * MS windows logo on remote */
-
-	[ 0x15 ] = KEY_VOLUMEUP,
-	[ 0x05 ] = KEY_VOLUMEDOWN,
-	[ 0x11 ] = KEY_CHANNELUP,
-	[ 0x09 ] = KEY_CHANNELDOWN,
-
-	[ 0x52 ] = KEY_CAMERA,
-	[ 0x5a ] = KEY_TUNER,
-	[ 0x19 ] = KEY_OPEN,
-
-	[ 0x13 ] = KEY_MODE,		/* 4:3 16:9 select */
-	[ 0x1f ] = KEY_ZOOM,
-
-	[ 0x43 ] = KEY_REWIND,
-	[ 0x47 ] = KEY_PLAYPAUSE,
-	[ 0x4f ] = KEY_FASTFORWARD,
-	[ 0x57 ] = KEY_MUTE,
-	[ 0x0d ] = KEY_STOP,
-	[ 0x01 ] = KEY_RECORD,
-	[ 0x4e ] = KEY_POWER,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce);
+static struct ir_scancode ir_codes_fusionhdtv_mce[] = {
+
+	{ 0x0b, KEY_1 },
+	{ 0x17, KEY_2 },
+	{ 0x1b, KEY_3 },
+	{ 0x07, KEY_4 },
+	{ 0x50, KEY_5 },
+	{ 0x54, KEY_6 },
+	{ 0x48, KEY_7 },
+	{ 0x4c, KEY_8 },
+	{ 0x58, KEY_9 },
+	{ 0x03, KEY_0 },
+
+	{ 0x5e, KEY_OK },
+	{ 0x51, KEY_UP },
+	{ 0x53, KEY_DOWN },
+	{ 0x5b, KEY_LEFT },
+	{ 0x5f, KEY_RIGHT },
+
+	{ 0x02, KEY_TV },		/* Labeled DTV on remote */
+	{ 0x0e, KEY_MP3 },
+	{ 0x1a, KEY_DVD },
+	{ 0x1e, KEY_FAVORITES },	/* Labeled CPF on remote */
+	{ 0x16, KEY_SETUP },
+	{ 0x46, KEY_POWER2 },		/* TV On/Off button on remote */
+	{ 0x0a, KEY_EPG },		/* Labeled Guide on remote */
+
+	{ 0x49, KEY_BACK },
+	{ 0x59, KEY_INFO },		/* Labeled MORE on remote */
+	{ 0x4d, KEY_MENU },		/* Labeled DVDMENU on remote */
+	{ 0x55, KEY_CYCLEWINDOWS },	/* Labeled ALT-TAB on remote */
+
+	{ 0x0f, KEY_PREVIOUSSONG },	/* Labeled |<< REPLAY on remote */
+	{ 0x12, KEY_NEXTSONG },		/* Labeled >>| SKIP on remote */
+	{ 0x42, KEY_ENTER },		/* Labeled START with a green
+					   MS windows logo on remote */
+
+	{ 0x15, KEY_VOLUMEUP },
+	{ 0x05, KEY_VOLUMEDOWN },
+	{ 0x11, KEY_CHANNELUP },
+	{ 0x09, KEY_CHANNELDOWN },
+
+	{ 0x52, KEY_CAMERA },
+	{ 0x5a, KEY_TUNER },
+	{ 0x19, KEY_OPEN },
+
+	{ 0x13, KEY_MODE },		/* 4:3 16:9 select */
+	{ 0x1f, KEY_ZOOM },
+
+	{ 0x43, KEY_REWIND },
+	{ 0x47, KEY_PLAYPAUSE },
+	{ 0x4f, KEY_FASTFORWARD },
+	{ 0x57, KEY_MUTE },
+	{ 0x0d, KEY_STOP },
+	{ 0x01, KEY_RECORD },
+	{ 0x4e, KEY_POWER },
+};
+
+struct ir_scancode_table ir_codes_fusionhdtv_mce_table = {
+	.scan = ir_codes_fusionhdtv_mce,
+	.size = ARRAY_SIZE(ir_codes_fusionhdtv_mce),
+};
+EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce_table);
 
 /* Pinnacle PCTV HD 800i mini remote */
-IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE] = {
-
-	[0x0f] = KEY_1,
-	[0x15] = KEY_2,
-	[0x10] = KEY_3,
-	[0x18] = KEY_4,
-	[0x1b] = KEY_5,
-	[0x1e] = KEY_6,
-	[0x11] = KEY_7,
-	[0x21] = KEY_8,
-	[0x12] = KEY_9,
-	[0x27] = KEY_0,
-
-	[0x24] = KEY_ZOOM,
-	[0x2a] = KEY_SUBTITLE,
-
-	[0x00] = KEY_MUTE,
-	[0x01] = KEY_ENTER,	/* Pinnacle Logo */
-	[0x39] = KEY_POWER,
-
-	[0x03] = KEY_VOLUMEUP,
-	[0x09] = KEY_VOLUMEDOWN,
-	[0x06] = KEY_CHANNELUP,
-	[0x0c] = KEY_CHANNELDOWN,
-
-	[0x2d] = KEY_REWIND,
-	[0x30] = KEY_PLAYPAUSE,
-	[0x33] = KEY_FASTFORWARD,
-	[0x3c] = KEY_STOP,
-	[0x36] = KEY_RECORD,
-	[0x3f] = KEY_EPG,	/* Labeled "?" */
-};
-EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd);
+static struct ir_scancode ir_codes_pinnacle_pctv_hd[] = {
+
+	{ 0x0f, KEY_1 },
+	{ 0x15, KEY_2 },
+	{ 0x10, KEY_3 },
+	{ 0x18, KEY_4 },
+	{ 0x1b, KEY_5 },
+	{ 0x1e, KEY_6 },
+	{ 0x11, KEY_7 },
+	{ 0x21, KEY_8 },
+	{ 0x12, KEY_9 },
+	{ 0x27, KEY_0 },
+
+	{ 0x24, KEY_ZOOM },
+	{ 0x2a, KEY_SUBTITLE },
+
+	{ 0x00, KEY_MUTE },
+	{ 0x01, KEY_ENTER },	/* Pinnacle Logo */
+	{ 0x39, KEY_POWER },
+
+	{ 0x03, KEY_VOLUMEUP },
+	{ 0x09, KEY_VOLUMEDOWN },
+	{ 0x06, KEY_CHANNELUP },
+	{ 0x0c, KEY_CHANNELDOWN },
+
+	{ 0x2d, KEY_REWIND },
+	{ 0x30, KEY_PLAYPAUSE },
+	{ 0x33, KEY_FASTFORWARD },
+	{ 0x3c, KEY_STOP },
+	{ 0x36, KEY_RECORD },
+	{ 0x3f, KEY_EPG },	/* Labeled "?" */
+};
+
+struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table = {
+	.scan = ir_codes_pinnacle_pctv_hd,
+	.size = ARRAY_SIZE(ir_codes_pinnacle_pctv_hd),
+};
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd_table);
 
 /*
  * Igor Kuznetsov <igk72@ya.ru>
@@ -2198,13 +2365,13 @@ EXPORT_SYMBOL_GPL(ir_codes_pinnacle_pctv_hd);
  * the button labels (several variants when appropriate)
  * helps to descide which keycodes to assign to the buttons.
  */
-IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_behold[] = {
 
 	/*  0x1c            0x12  *
 	 *  TV/FM          POWER  *
 	 *                        */
-	[ 0x1c ] = KEY_TUNER,	/*XXX KEY_TV KEY_RADIO */
-	[ 0x12 ] = KEY_POWER,
+	{ 0x1c, KEY_TUNER },	/* XXX KEY_TV / KEY_RADIO */
+	{ 0x12, KEY_POWER },
 
 	/*  0x01    0x02    0x03  *
 	 *   1       2       3    *
@@ -2215,28 +2382,28 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
 	 *  0x07    0x08    0x09  *
 	 *   7       8       9    *
 	 *                        */
-	[ 0x01 ] = KEY_1,
-	[ 0x02 ] = KEY_2,
-	[ 0x03 ] = KEY_3,
-	[ 0x04 ] = KEY_4,
-	[ 0x05 ] = KEY_5,
-	[ 0x06 ] = KEY_6,
-	[ 0x07 ] = KEY_7,
-	[ 0x08 ] = KEY_8,
-	[ 0x09 ] = KEY_9,
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
 
 	/*  0x0a    0x00    0x17  *
 	 * RECALL    0      MODE  *
 	 *                        */
-	[ 0x0a ] = KEY_AGAIN,
-	[ 0x00 ] = KEY_0,
-	[ 0x17 ] = KEY_MODE,
+	{ 0x0a, KEY_AGAIN },
+	{ 0x00, KEY_0 },
+	{ 0x17, KEY_MODE },
 
 	/*  0x14          0x10    *
 	 * ASPECT      FULLSCREEN *
 	 *                        */
-	[ 0x14 ] = KEY_SCREEN,
-	[ 0x10 ] = KEY_ZOOM,
+	{ 0x14, KEY_SCREEN },
+	{ 0x10, KEY_ZOOM },
 
 	/*          0x0b          *
 	 *           Up           *
@@ -2247,17 +2414,17 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
 	 *         0x015          *
 	 *         Down           *
 	 *                        */
-	[ 0x0b ] = KEY_CHANNELUP,	/*XXX KEY_UP */
-	[ 0x18 ] = KEY_VOLUMEDOWN,	/*XXX KEY_LEFT */
-	[ 0x16 ] = KEY_OK,		/*XXX KEY_ENTER */
-	[ 0x0c ] = KEY_VOLUMEUP,	/*XXX KEY_RIGHT */
-	[ 0x15 ] = KEY_CHANNELDOWN,	/*XXX KEY_DOWN */
+	{ 0x0b, KEY_CHANNELUP },
+	{ 0x18, KEY_VOLUMEDOWN },
+	{ 0x16, KEY_OK },		/* XXX KEY_ENTER */
+	{ 0x0c, KEY_VOLUMEUP },
+	{ 0x15, KEY_CHANNELDOWN },
 
 	/*  0x11            0x0d  *
 	 *  MUTE            INFO  *
 	 *                        */
-	[ 0x11 ] = KEY_MUTE,
-	[ 0x0d ] = KEY_INFO,
+	{ 0x11, KEY_MUTE },
+	{ 0x0d, KEY_INFO },
 
 	/*  0x0f    0x1b    0x1a  *
 	 * RECORD PLAY/PAUSE STOP *
@@ -2266,30 +2433,34 @@ IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE] = {
 	 *TELETEXT  AUDIO  SOURCE *
 	 *           RED   YELLOW *
 	 *                        */
-	[ 0x0f ] = KEY_RECORD,
-	[ 0x1b ] = KEY_PLAYPAUSE,
-	[ 0x1a ] = KEY_STOP,
-	[ 0x0e ] = KEY_TEXT,
-	[ 0x1f ] = KEY_RED,	/*XXX KEY_AUDIO */
-	[ 0x1e ] = KEY_YELLOW,	/*XXX KEY_SOURCE */
+	{ 0x0f, KEY_RECORD },
+	{ 0x1b, KEY_PLAYPAUSE },
+	{ 0x1a, KEY_STOP },
+	{ 0x0e, KEY_TEXT },
+	{ 0x1f, KEY_RED },	/*XXX KEY_AUDIO	*/
+	{ 0x1e, KEY_YELLOW },	/*XXX KEY_SOURCE	*/
 
 	/*  0x1d   0x13     0x19  *
 	 * SLEEP  PREVIEW   DVB   *
 	 *         GREEN    BLUE  *
 	 *                        */
-	[ 0x1d ] = KEY_SLEEP,
-	[ 0x13 ] = KEY_GREEN,
-	[ 0x19 ] = KEY_BLUE,	/*XXX KEY_SAT */
+	{ 0x1d, KEY_SLEEP },
+	{ 0x13, KEY_GREEN },
+	{ 0x19, KEY_BLUE },	/* XXX KEY_SAT	*/
 
 	/*  0x58           0x5c   *
 	 * FREEZE        SNAPSHOT *
 	 *                        */
-	[ 0x58 ] = KEY_SLOW,
-	[ 0x5c ] = KEY_SAVE,
+	{ 0x58, KEY_SLOW },
+	{ 0x5c, KEY_CAMERA },
 
 };
 
-EXPORT_SYMBOL_GPL(ir_codes_behold);
+struct ir_scancode_table ir_codes_behold_table = {
+	.scan = ir_codes_behold,
+	.size = ARRAY_SIZE(ir_codes_behold),
+};
+EXPORT_SYMBOL_GPL(ir_codes_behold_table);
 
 /* Beholder Intl. Ltd. 2008
  * Dmitry Belimov d.belimov@google.com
@@ -2299,16 +2470,16 @@ EXPORT_SYMBOL_GPL(ir_codes_behold);
  * the button labels (several variants when appropriate)
  * helps to descide which keycodes to assign to the buttons.
  */
-IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_behold_columbus[] = {
 
 	/*  0x13   0x11   0x1C   0x12  *
 	 *  Mute  Source  TV/FM  Power *
 	 *                             */
 
-	[0x13] = KEY_MUTE,
-	[0x11] = KEY_PROPS,
-	[0x1C] = KEY_TUNER,	/* KEY_TV/KEY_RADIO */
-	[0x12] = KEY_POWER,
+	{ 0x13, KEY_MUTE },
+	{ 0x11, KEY_PROPS },
+	{ 0x1C, KEY_TUNER },	/* KEY_TV/KEY_RADIO	*/
+	{ 0x12, KEY_POWER },
 
 	/*  0x01    0x02    0x03  0x0D    *
 	 *   1       2       3   Stereo   *
@@ -2319,173 +2490,188 @@ IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE] = {
 	 *  0x07    0x08    0x09  0x10    *
 	 *   7       8       9    Zoom 	  *
 	 *                                */
-	[0x01] = KEY_1,
-	[0x02] = KEY_2,
-	[0x03] = KEY_3,
-	[0x0D] = KEY_SETUP,	  /* Setup key */
-	[0x04] = KEY_4,
-	[0x05] = KEY_5,
-	[0x06] = KEY_6,
-	[0x19] = KEY_BOOKMARKS, /* Snapshot key */
-	[0x07] = KEY_7,
-	[0x08] = KEY_8,
-	[0x09] = KEY_9,
-	[0x10] = KEY_ZOOM,
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x0D, KEY_SETUP },	  /* Setup key */
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x19, KEY_CAMERA },	/* Snapshot key */
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x10, KEY_ZOOM },
 
 	/*  0x0A    0x00    0x0B       0x0C   *
 	 * RECALL    0    ChannelUp  VolumeUp *
 	 *                                    */
-	[0x0A] = KEY_AGAIN,
-	[0x00] = KEY_0,
-	[0x0B] = KEY_CHANNELUP,
-	[0x0C] = KEY_VOLUMEUP,
+	{ 0x0A, KEY_AGAIN },
+	{ 0x00, KEY_0 },
+	{ 0x0B, KEY_CHANNELUP },
+	{ 0x0C, KEY_VOLUMEUP },
 
 	/*   0x1B      0x1D      0x15        0x18     *
 	 * Timeshift  Record  ChannelDown  VolumeDown *
 	 *                                            */
 
-	[0x1B] = KEY_REWIND,
-	[0x1D] = KEY_RECORD,
-	[0x15] = KEY_CHANNELDOWN,
-	[0x18] = KEY_VOLUMEDOWN,
+	{ 0x1B, KEY_TIME },
+	{ 0x1D, KEY_RECORD },
+	{ 0x15, KEY_CHANNELDOWN },
+	{ 0x18, KEY_VOLUMEDOWN },
 
 	/*   0x0E   0x1E     0x0F     0x1A  *
 	 *   Stop   Pause  Previouse  Next  *
 	 *                                  */
 
-	[0x0E] = KEY_STOP,
-	[0x1E] = KEY_PAUSE,
-	[0x0F] = KEY_PREVIOUS,
-	[0x1A] = KEY_NEXT,
+	{ 0x0E, KEY_STOP },
+	{ 0x1E, KEY_PAUSE },
+	{ 0x0F, KEY_PREVIOUS },
+	{ 0x1A, KEY_NEXT },
+
+};
 
+struct ir_scancode_table ir_codes_behold_columbus_table = {
+	.scan = ir_codes_behold_columbus,
+	.size = ARRAY_SIZE(ir_codes_behold_columbus),
 };
-EXPORT_SYMBOL_GPL(ir_codes_behold_columbus);
+EXPORT_SYMBOL_GPL(ir_codes_behold_columbus_table);
 
 /*
  * Remote control for the Genius TVGO A11MCE
  * Adrian Pardini <pardo.bsso@gmail.com>
  */
-IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE] = {
+static struct ir_scancode ir_codes_genius_tvgo_a11mce[] = {
 	/* Keys 0 to 9 */
-	[0x48] = KEY_0,
-	[0x09] = KEY_1,
-	[0x1d] = KEY_2,
-	[0x1f] = KEY_3,
-	[0x19] = KEY_4,
-	[0x1b] = KEY_5,
-	[0x11] = KEY_6,
-	[0x17] = KEY_7,
-	[0x12] = KEY_8,
-	[0x16] = KEY_9,
-
-	[0x54] = KEY_RECORD,		/* recording */
-	[0x06] = KEY_MUTE,		/* mute */
-	[0x10] = KEY_POWER,
-	[0x40] = KEY_LAST,		/* recall */
-	[0x4c] = KEY_CHANNELUP,		/* channel / program + */
-	[0x00] = KEY_CHANNELDOWN,	/* channel / program - */
-	[0x0d] = KEY_VOLUMEUP,
-	[0x15] = KEY_VOLUMEDOWN,
-	[0x4d] = KEY_OK,		/* also labeled as Pause */
-	[0x1c] = KEY_ZOOM,		/* full screen and Stop*/
-	[0x02] = KEY_MODE,		/* AV Source or Rewind*/
-	[0x04] = KEY_LIST,		/* -/-- */
+	{ 0x48, KEY_0 },
+	{ 0x09, KEY_1 },
+	{ 0x1d, KEY_2 },
+	{ 0x1f, KEY_3 },
+	{ 0x19, KEY_4 },
+	{ 0x1b, KEY_5 },
+	{ 0x11, KEY_6 },
+	{ 0x17, KEY_7 },
+	{ 0x12, KEY_8 },
+	{ 0x16, KEY_9 },
+
+	{ 0x54, KEY_RECORD },		/* recording */
+	{ 0x06, KEY_MUTE },		/* mute */
+	{ 0x10, KEY_POWER },
+	{ 0x40, KEY_LAST },		/* recall */
+	{ 0x4c, KEY_CHANNELUP },	/* channel / program + */
+	{ 0x00, KEY_CHANNELDOWN },	/* channel / program - */
+	{ 0x0d, KEY_VOLUMEUP },
+	{ 0x15, KEY_VOLUMEDOWN },
+	{ 0x4d, KEY_OK },		/* also labeled as Pause */
+	{ 0x1c, KEY_ZOOM },		/* full screen and Stop*/
+	{ 0x02, KEY_MODE },		/* AV Source or Rewind*/
+	{ 0x04, KEY_LIST },		/* -/-- */
 	/* small arrows above numbers */
-	[0x1a] = KEY_NEXT,		/* also Fast Forward */
-	[0x0e] = KEY_PREVIOUS,	/* also Rewind */
+	{ 0x1a, KEY_NEXT },		/* also Fast Forward */
+	{ 0x0e, KEY_PREVIOUS },		/* also Rewind */
 	/* these are in a rather non standard layout and have
 	an alternate name written */
-	[0x1e] = KEY_UP,		/* Video Setting */
-	[0x0a] = KEY_DOWN,		/* Video Default */
-	[0x05] = KEY_LEFT,		/* Snapshot */
-	[0x0c] = KEY_RIGHT,		/* Hide Panel */
+	{ 0x1e, KEY_UP },		/* Video Setting */
+	{ 0x0a, KEY_DOWN },		/* Video Default */
+	{ 0x05, KEY_CAMERA },		/* Snapshot */
+	{ 0x0c, KEY_RIGHT },		/* Hide Panel */
 	/* Four buttons without label */
-	[0x49] = KEY_RED,
-	[0x0b] = KEY_GREEN,
-	[0x13] = KEY_YELLOW,
-	[0x50] = KEY_BLUE,
+	{ 0x49, KEY_RED },
+	{ 0x0b, KEY_GREEN },
+	{ 0x13, KEY_YELLOW },
+	{ 0x50, KEY_BLUE },
+};
+
+struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table = {
+	.scan = ir_codes_genius_tvgo_a11mce,
+	.size = ARRAY_SIZE(ir_codes_genius_tvgo_a11mce),
 };
-EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce);
+EXPORT_SYMBOL_GPL(ir_codes_genius_tvgo_a11mce_table);
 
 /*
  * Remote control for Powercolor Real Angel 330
  * Daniel Fraga <fragabr@gmail.com>
  */
-IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = {
-	[0x38] = KEY_SWITCHVIDEOMODE,	/* switch inputs */
-	[0x0c] = KEY_MEDIA,		/* Turn ON/OFF App */
-	[0x00] = KEY_0,
-	[0x01] = KEY_1,
-	[0x02] = KEY_2,
-	[0x03] = KEY_3,
-	[0x04] = KEY_4,
-	[0x05] = KEY_5,
-	[0x06] = KEY_6,
-	[0x07] = KEY_7,
-	[0x08] = KEY_8,
-	[0x09] = KEY_9,
-	[0x0a] = KEY_DIGITS,		/* single, double, tripple digit */
-	[0x29] = KEY_PREVIOUS,		/* previous channel */
-	[0x12] = KEY_BRIGHTNESSUP,
-	[0x13] = KEY_BRIGHTNESSDOWN,
-	[0x2b] = KEY_MODE,		/* stereo/mono */
-	[0x2c] = KEY_TEXT,		/* teletext */
-	[0x20] = KEY_UP,		/* channel up */
-	[0x21] = KEY_DOWN,		/* channel down */
-	[0x10] = KEY_RIGHT,		/* volume up */
-	[0x11] = KEY_LEFT,		/* volume down */
-	[0x0d] = KEY_MUTE,
-	[0x1f] = KEY_RECORD,
-	[0x17] = KEY_PLAY,
-	[0x16] = KEY_PAUSE,
-	[0x0b] = KEY_STOP,
-	[0x27] = KEY_FASTFORWARD,
-	[0x26] = KEY_REWIND,
-	[0x1e] = KEY_SEARCH,		/* autoscan */
-	[0x0e] = KEY_SHUFFLE,		/* snapshot */
-	[0x2d] = KEY_SETUP,
-	[0x0f] = KEY_SCREEN,		/* full screen */
-	[0x14] = KEY_RADIO,		/* FM radio */
-	[0x25] = KEY_POWER,		/* power */
-};
-EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel);
+static struct ir_scancode ir_codes_powercolor_real_angel[] = {
+	{ 0x38, KEY_SWITCHVIDEOMODE },	/* switch inputs */
+	{ 0x0c, KEY_MEDIA },		/* Turn ON/OFF App */
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0a, KEY_DIGITS },		/* single, double, tripple digit */
+	{ 0x29, KEY_PREVIOUS },		/* previous channel */
+	{ 0x12, KEY_BRIGHTNESSUP },
+	{ 0x13, KEY_BRIGHTNESSDOWN },
+	{ 0x2b, KEY_MODE },		/* stereo/mono */
+	{ 0x2c, KEY_TEXT },		/* teletext */
+	{ 0x20, KEY_CHANNELUP },	/* channel up */
+	{ 0x21, KEY_CHANNELDOWN },	/* channel down */
+	{ 0x10, KEY_VOLUMEUP },		/* volume up */
+	{ 0x11, KEY_VOLUMEDOWN },	/* volume down */
+	{ 0x0d, KEY_MUTE },
+	{ 0x1f, KEY_RECORD },
+	{ 0x17, KEY_PLAY },
+	{ 0x16, KEY_PAUSE },
+	{ 0x0b, KEY_STOP },
+	{ 0x27, KEY_FASTFORWARD },
+	{ 0x26, KEY_REWIND },
+	{ 0x1e, KEY_SEARCH },		/* autoscan */
+	{ 0x0e, KEY_CAMERA },		/* snapshot */
+	{ 0x2d, KEY_SETUP },
+	{ 0x0f, KEY_SCREEN },		/* full screen */
+	{ 0x14, KEY_RADIO },		/* FM radio */
+	{ 0x25, KEY_POWER },		/* power */
+};
+
+struct ir_scancode_table ir_codes_powercolor_real_angel_table = {
+	.scan = ir_codes_powercolor_real_angel,
+	.size = ARRAY_SIZE(ir_codes_powercolor_real_angel),
+};
+EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel_table);
 
 /* Kworld Plus TV Analog Lite PCI IR
    Mauro Carvalho Chehab <mchehab@infradead.org>
  */
-IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = {
-	[0x0c] = KEY_PROG1,		/* Kworld key */
-	[0x16] = KEY_CLOSECD,		/* -> ) */
-	[0x1d] = KEY_POWER2,
-
-	[0x00] = KEY_1,
-	[0x01] = KEY_2,
-	[0x02] = KEY_3,			/* Two keys have the same code: 3 and left */
-	[0x03] = KEY_4,			/* Two keys have the same code: 3 and right */
-	[0x04] = KEY_5,
-	[0x05] = KEY_6,
-	[0x06] = KEY_7,
-	[0x07] = KEY_8,
-	[0x08] = KEY_9,
-	[0x0a] = KEY_0,
-
-	[0x09] = KEY_AGAIN,
-	[0x14] = KEY_MUTE,
-
-	[0x20] = KEY_UP,
-	[0x21] = KEY_DOWN,
-	[0x0b] = KEY_ENTER,
-
-	[0x10] = KEY_CHANNELUP,
-	[0x11] = KEY_CHANNELDOWN,
+static struct ir_scancode ir_codes_kworld_plus_tv_analog[] = {
+	{ 0x0c, KEY_PROG1 },		/* Kworld key */
+	{ 0x16, KEY_CLOSECD },		/* -> ) */
+	{ 0x1d, KEY_POWER2 },
+
+	{ 0x00, KEY_1 },
+	{ 0x01, KEY_2 },
+	{ 0x02, KEY_3 },		/* Two keys have the same code: 3 and left */
+	{ 0x03, KEY_4 },		/* Two keys have the same code: 3 and right */
+	{ 0x04, KEY_5 },
+	{ 0x05, KEY_6 },
+	{ 0x06, KEY_7 },
+	{ 0x07, KEY_8 },
+	{ 0x08, KEY_9 },
+	{ 0x0a, KEY_0 },
+
+	{ 0x09, KEY_AGAIN },
+	{ 0x14, KEY_MUTE },
+
+	{ 0x20, KEY_UP },
+	{ 0x21, KEY_DOWN },
+	{ 0x0b, KEY_ENTER },
+
+	{ 0x10, KEY_CHANNELUP },
+	{ 0x11, KEY_CHANNELDOWN },
 
 	/* Couldn't map key left/key right since those
 	   conflict with '3' and '4' scancodes
 	   I dunno what the original driver does
 	 */
 
-	[0x13] = KEY_VOLUMEUP,
-	[0x12] = KEY_VOLUMEDOWN,
+	{ 0x13, KEY_VOLUMEUP },
+	{ 0x12, KEY_VOLUMEDOWN },
 
 	/* The lower part of the IR
 	   There are several duplicated keycodes there.
@@ -2496,280 +2682,468 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = {
 	   Also, it is not related to the time between keyup
 	   and keydown.
 	 */
-	[0x19] = KEY_PAUSE,		/* Timeshift */
-	[0x1a] = KEY_STOP,
-	[0x1b] = KEY_RECORD,
+	{ 0x19, KEY_TIME},		/* Timeshift */
+	{ 0x1a, KEY_STOP},
+	{ 0x1b, KEY_RECORD},
 
-	[0x22] = KEY_TEXT,
+	{ 0x22, KEY_TEXT},
 
-	[0x15] = KEY_AUDIO,		/* ((*)) */
-	[0x0f] = KEY_ZOOM,
-	[0x1c] = KEY_SHUFFLE,		/* snapshot */
+	{ 0x15, KEY_AUDIO},		/* ((*)) */
+	{ 0x0f, KEY_ZOOM},
+	{ 0x1c, KEY_CAMERA},		/* snapshot */
 
-	[0x18] = KEY_RED,		/* B */
-	[0x23] = KEY_GREEN,		/* C */
+	{ 0x18, KEY_RED},		/* B */
+	{ 0x23, KEY_GREEN},		/* C */
 };
-EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog);
+struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table = {
+	.scan = ir_codes_kworld_plus_tv_analog,
+	.size = ARRAY_SIZE(ir_codes_kworld_plus_tv_analog),
+};
+EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog_table);
 
 /* Kaiomy TVnPC U2
    Mauro Carvalho Chehab <mchehab@infradead.org>
  */
-IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = {
-	[0x43] = KEY_POWER2,
-	[0x01] = KEY_LIST,
-	[0x0b] = KEY_ZOOM,
-	[0x03] = KEY_POWER,
-
-	[0x04] = KEY_1,
-	[0x08] = KEY_2,
-	[0x02] = KEY_3,
-
-	[0x0f] = KEY_4,
-	[0x05] = KEY_5,
-	[0x06] = KEY_6,
-
-	[0x0c] = KEY_7,
-	[0x0d] = KEY_8,
-	[0x0a] = KEY_9,
-
-	[0x11] = KEY_0,
-
-	[0x09] = KEY_CHANNELUP,
-	[0x07] = KEY_CHANNELDOWN,
-
-	[0x0e] = KEY_VOLUMEUP,
-	[0x13] = KEY_VOLUMEDOWN,
-
-	[0x10] = KEY_HOME,
-	[0x12] = KEY_ENTER,
-
-	[0x14] = KEY_RECORD,
-	[0x15] = KEY_STOP,
-	[0x16] = KEY_PLAY,
-	[0x17] = KEY_MUTE,
-
-	[0x18] = KEY_UP,
-	[0x19] = KEY_DOWN,
-	[0x1a] = KEY_LEFT,
-	[0x1b] = KEY_RIGHT,
-
-	[0x1c] = KEY_RED,
-	[0x1d] = KEY_GREEN,
-	[0x1e] = KEY_YELLOW,
-	[0x1f] = KEY_BLUE,
-};
-EXPORT_SYMBOL_GPL(ir_codes_kaiomy);
-
-IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
-	[0x20] = KEY_LIST,
-	[0x00] = KEY_POWER,
-	[0x28] = KEY_1,
-	[0x18] = KEY_2,
-	[0x38] = KEY_3,
-	[0x24] = KEY_4,
-	[0x14] = KEY_5,
-	[0x34] = KEY_6,
-	[0x2c] = KEY_7,
-	[0x1c] = KEY_8,
-	[0x3c] = KEY_9,
-	[0x12] = KEY_SUBTITLE,
-	[0x22] = KEY_0,
-	[0x32] = KEY_REWIND,
-	[0x3a] = KEY_SHUFFLE,
-	[0x02] = KEY_PRINT,
-	[0x11] = KEY_CHANNELDOWN,
-	[0x31] = KEY_CHANNELUP,
-	[0x0c] = KEY_ZOOM,
-	[0x1e] = KEY_VOLUMEDOWN,
-	[0x3e] = KEY_VOLUMEUP,
-	[0x0a] = KEY_MUTE,
-	[0x04] = KEY_AUDIO,
-	[0x26] = KEY_RECORD,
-	[0x06] = KEY_PLAY,
-	[0x36] = KEY_STOP,
-	[0x16] = KEY_PAUSE,
-	[0x2e] = KEY_REWIND,
-	[0x0e] = KEY_FASTFORWARD,
-	[0x30] = KEY_TEXT,
-	[0x21] = KEY_GREEN,
-	[0x01] = KEY_BLUE,
-	[0x08] = KEY_EPG,
-	[0x2a] = KEY_MENU,
-};
-EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d);
+static struct ir_scancode ir_codes_kaiomy[] = {
+	{ 0x43, KEY_POWER2},
+	{ 0x01, KEY_LIST},
+	{ 0x0b, KEY_ZOOM},
+	{ 0x03, KEY_POWER},
 
-/* Encore ENLTV-FM v5.3
-   Mauro Carvalho Chehab <mchehab@infradead.org>
- */
-IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE] = {
-	[0x10] = KEY_POWER2,
-	[0x06] = KEY_MUTE,
-
-	[0x09] = KEY_1,
-	[0x1d] = KEY_2,
-	[0x1f] = KEY_3,
-	[0x19] = KEY_4,
-	[0x1b] = KEY_5,
-	[0x11] = KEY_6,
-	[0x17] = KEY_7,
-	[0x12] = KEY_8,
-	[0x16] = KEY_9,
-	[0x48] = KEY_0,
-
-	[0x04] = KEY_LIST,		/* -/-- */
-	[0x40] = KEY_LAST,		/* recall */
-
-	[0x02] = KEY_MODE,		/* TV/AV */
-	[0x05] = KEY_SHUFFLE,		/* SNAPSHOT */
-
-	[0x4c] = KEY_CHANNELUP,		/* UP */
-	[0x00] = KEY_CHANNELDOWN,	/* DOWN */
-	[0x0d] = KEY_VOLUMEUP,		/* RIGHT */
-	[0x15] = KEY_VOLUMEDOWN,	/* LEFT */
-	[0x49] = KEY_ENTER,		/* OK */
-
-	[0x54] = KEY_RECORD,
-	[0x4d] = KEY_PLAY,		/* pause */
-
-	[0x1e] = KEY_UP,		/* video setting */
-	[0x0e] = KEY_RIGHT,		/* <- */
-	[0x1a] = KEY_LEFT,		/* -> */
-
-	[0x0a] = KEY_DOWN,		/* video default */
-	[0x0c] = KEY_ZOOM,		/* hide pannel */
-	[0x47] = KEY_SLEEP,		/* shutdown */
-};
-EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53);
+	{ 0x04, KEY_1},
+	{ 0x08, KEY_2},
+	{ 0x02, KEY_3},
 
-/* Zogis Real Audio 220 - 32 keys IR */
-IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE] = {
-	[0x1c] = KEY_RADIO,
-	[0x12] = KEY_POWER2,
+	{ 0x0f, KEY_4},
+	{ 0x05, KEY_5},
+	{ 0x06, KEY_6},
+
+	{ 0x0c, KEY_7},
+	{ 0x0d, KEY_8},
+	{ 0x0a, KEY_9},
 
-	[0x01] = KEY_1,
-	[0x02] = KEY_2,
-	[0x03] = KEY_3,
-	[0x04] = KEY_4,
-	[0x05] = KEY_5,
-	[0x06] = KEY_6,
-	[0x07] = KEY_7,
-	[0x08] = KEY_8,
-	[0x09] = KEY_9,
-	[0x00] = KEY_0,
+	{ 0x11, KEY_0},
 
-	[0x0c] = KEY_VOLUMEUP,
-	[0x18] = KEY_VOLUMEDOWN,
-	[0x0b] = KEY_CHANNELUP,
-	[0x15] = KEY_CHANNELDOWN,
-	[0x16] = KEY_ENTER,
+	{ 0x09, KEY_CHANNELUP},
+	{ 0x07, KEY_CHANNELDOWN},
 
-	[0x11] = KEY_LIST,		/* Source */
-	[0x0d] = KEY_AUDIO,		/* stereo */
+	{ 0x0e, KEY_VOLUMEUP},
+	{ 0x13, KEY_VOLUMEDOWN},
 
-	[0x0f] = KEY_PREVIOUS,		/* Prev */
-	[0x1b] = KEY_PAUSE,		/* Timeshift */
-	[0x1a] = KEY_NEXT,		/* Next */
+	{ 0x10, KEY_HOME},
+	{ 0x12, KEY_ENTER},
 
-	[0x0e] = KEY_STOP,
-	[0x1f] = KEY_PLAY,
-	[0x1e] = KEY_PLAYPAUSE,		/* Pause */
+	{ 0x14, KEY_RECORD},
+	{ 0x15, KEY_STOP},
+	{ 0x16, KEY_PLAY},
+	{ 0x17, KEY_MUTE},
 
-	[0x1d] = KEY_RECORD,
-	[0x13] = KEY_MUTE,
-	[0x19] = KEY_SHUFFLE,		/* Snapshot */
+	{ 0x18, KEY_UP},
+	{ 0x19, KEY_DOWN},
+	{ 0x1a, KEY_LEFT},
+	{ 0x1b, KEY_RIGHT},
 
+	{ 0x1c, KEY_RED},
+	{ 0x1d, KEY_GREEN},
+	{ 0x1e, KEY_YELLOW},
+	{ 0x1f, KEY_BLUE},
+};
+struct ir_scancode_table ir_codes_kaiomy_table = {
+	.scan = ir_codes_kaiomy,
+	.size = ARRAY_SIZE(ir_codes_kaiomy),
+};
+EXPORT_SYMBOL_GPL(ir_codes_kaiomy_table);
+
+static struct ir_scancode ir_codes_avermedia_a16d[] = {
+	{ 0x20, KEY_LIST},
+	{ 0x00, KEY_POWER},
+	{ 0x28, KEY_1},
+	{ 0x18, KEY_2},
+	{ 0x38, KEY_3},
+	{ 0x24, KEY_4},
+	{ 0x14, KEY_5},
+	{ 0x34, KEY_6},
+	{ 0x2c, KEY_7},
+	{ 0x1c, KEY_8},
+	{ 0x3c, KEY_9},
+	{ 0x12, KEY_SUBTITLE},
+	{ 0x22, KEY_0},
+	{ 0x32, KEY_REWIND},
+	{ 0x3a, KEY_SHUFFLE},
+	{ 0x02, KEY_PRINT},
+	{ 0x11, KEY_CHANNELDOWN},
+	{ 0x31, KEY_CHANNELUP},
+	{ 0x0c, KEY_ZOOM},
+	{ 0x1e, KEY_VOLUMEDOWN},
+	{ 0x3e, KEY_VOLUMEUP},
+	{ 0x0a, KEY_MUTE},
+	{ 0x04, KEY_AUDIO},
+	{ 0x26, KEY_RECORD},
+	{ 0x06, KEY_PLAY},
+	{ 0x36, KEY_STOP},
+	{ 0x16, KEY_PAUSE},
+	{ 0x2e, KEY_REWIND},
+	{ 0x0e, KEY_FASTFORWARD},
+	{ 0x30, KEY_TEXT},
+	{ 0x21, KEY_GREEN},
+	{ 0x01, KEY_BLUE},
+	{ 0x08, KEY_EPG},
+	{ 0x2a, KEY_MENU},
+};
+struct ir_scancode_table ir_codes_avermedia_a16d_table = {
+	.scan = ir_codes_avermedia_a16d,
+	.size = ARRAY_SIZE(ir_codes_avermedia_a16d),
 };
-EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys);
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d_table);
+
+/* Encore ENLTV-FM v5.3
+   Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+static struct ir_scancode ir_codes_encore_enltv_fm53[] = {
+	{ 0x10, KEY_POWER2},
+	{ 0x06, KEY_MUTE},
+
+	{ 0x09, KEY_1},
+	{ 0x1d, KEY_2},
+	{ 0x1f, KEY_3},
+	{ 0x19, KEY_4},
+	{ 0x1b, KEY_5},
+	{ 0x11, KEY_6},
+	{ 0x17, KEY_7},
+	{ 0x12, KEY_8},
+	{ 0x16, KEY_9},
+	{ 0x48, KEY_0},
+
+	{ 0x04, KEY_LIST},		/* -/-- */
+	{ 0x40, KEY_LAST},		/* recall */
+
+	{ 0x02, KEY_MODE},		/* TV/AV */
+	{ 0x05, KEY_CAMERA},		/* SNAPSHOT */
+
+	{ 0x4c, KEY_CHANNELUP},		/* UP */
+	{ 0x00, KEY_CHANNELDOWN},	/* DOWN */
+	{ 0x0d, KEY_VOLUMEUP},		/* RIGHT */
+	{ 0x15, KEY_VOLUMEDOWN},	/* LEFT */
+	{ 0x49, KEY_ENTER},		/* OK */
+
+	{ 0x54, KEY_RECORD},
+	{ 0x4d, KEY_PLAY},		/* pause */
+
+	{ 0x1e, KEY_MENU},		/* video setting */
+	{ 0x0e, KEY_RIGHT},		/* <- */
+	{ 0x1a, KEY_LEFT},		/* -> */
+
+	{ 0x0a, KEY_CLEAR},		/* video default */
+	{ 0x0c, KEY_ZOOM},		/* hide pannel */
+	{ 0x47, KEY_SLEEP},		/* shutdown */
+};
+struct ir_scancode_table ir_codes_encore_enltv_fm53_table = {
+	.scan = ir_codes_encore_enltv_fm53,
+	.size = ARRAY_SIZE(ir_codes_encore_enltv_fm53),
+};
+EXPORT_SYMBOL_GPL(ir_codes_encore_enltv_fm53_table);
+
+/* Zogis Real Audio 220 - 32 keys IR */
+static struct ir_scancode ir_codes_real_audio_220_32_keys[] = {
+	{ 0x1c, KEY_RADIO},
+	{ 0x12, KEY_POWER2},
+
+	{ 0x01, KEY_1},
+	{ 0x02, KEY_2},
+	{ 0x03, KEY_3},
+	{ 0x04, KEY_4},
+	{ 0x05, KEY_5},
+	{ 0x06, KEY_6},
+	{ 0x07, KEY_7},
+	{ 0x08, KEY_8},
+	{ 0x09, KEY_9},
+	{ 0x00, KEY_0},
+
+	{ 0x0c, KEY_VOLUMEUP},
+	{ 0x18, KEY_VOLUMEDOWN},
+	{ 0x0b, KEY_CHANNELUP},
+	{ 0x15, KEY_CHANNELDOWN},
+	{ 0x16, KEY_ENTER},
+
+	{ 0x11, KEY_LIST},		/* Source */
+	{ 0x0d, KEY_AUDIO},		/* stereo */
+
+	{ 0x0f, KEY_PREVIOUS},		/* Prev */
+	{ 0x1b, KEY_TIME},		/* Timeshift */
+	{ 0x1a, KEY_NEXT},		/* Next */
+
+	{ 0x0e, KEY_STOP},
+	{ 0x1f, KEY_PLAY},
+	{ 0x1e, KEY_PLAYPAUSE},		/* Pause */
+
+	{ 0x1d, KEY_RECORD},
+	{ 0x13, KEY_MUTE},
+	{ 0x19, KEY_CAMERA},		/* Snapshot */
+
+};
+struct ir_scancode_table ir_codes_real_audio_220_32_keys_table = {
+	.scan = ir_codes_real_audio_220_32_keys,
+	.size = ARRAY_SIZE(ir_codes_real_audio_220_32_keys),
+};
+EXPORT_SYMBOL_GPL(ir_codes_real_audio_220_32_keys_table);
 
 /* ATI TV Wonder HD 600 USB
    Devin Heitmueller <devin.heitmueller@gmail.com>
  */
-IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = {
-	[0x00] = KEY_RECORD,		/* Row 1 */
-	[0x01] = KEY_PLAYPAUSE,
-	[0x02] = KEY_STOP,
-	[0x03] = KEY_POWER,
-	[0x04] = KEY_PREVIOUS,	/* Row 2 */
-	[0x05] = KEY_REWIND,
-	[0x06] = KEY_FORWARD,
-	[0x07] = KEY_NEXT,
-	[0x08] = KEY_EPG,		/* Row 3 */
-	[0x09] = KEY_HOME,
-	[0x0a] = KEY_MENU,
-	[0x0b] = KEY_CHANNELUP,
-	[0x0c] = KEY_BACK,		/* Row 4 */
-	[0x0d] = KEY_UP,
-	[0x0e] = KEY_INFO,
-	[0x0f] = KEY_CHANNELDOWN,
-	[0x10] = KEY_LEFT,		/* Row 5 */
-	[0x11] = KEY_SELECT,
-	[0x12] = KEY_RIGHT,
-	[0x13] = KEY_VOLUMEUP,
-	[0x14] = KEY_LAST,		/* Row 6 */
-	[0x15] = KEY_DOWN,
-	[0x16] = KEY_MUTE,
-	[0x17] = KEY_VOLUMEDOWN,
-};
-
-EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600);
+static struct ir_scancode ir_codes_ati_tv_wonder_hd_600[] = {
+	{ 0x00, KEY_RECORD},		/* Row 1 */
+	{ 0x01, KEY_PLAYPAUSE},
+	{ 0x02, KEY_STOP},
+	{ 0x03, KEY_POWER},
+	{ 0x04, KEY_PREVIOUS},	/* Row 2 */
+	{ 0x05, KEY_REWIND},
+	{ 0x06, KEY_FORWARD},
+	{ 0x07, KEY_NEXT},
+	{ 0x08, KEY_EPG},		/* Row 3 */
+	{ 0x09, KEY_HOME},
+	{ 0x0a, KEY_MENU},
+	{ 0x0b, KEY_CHANNELUP},
+	{ 0x0c, KEY_BACK},		/* Row 4 */
+	{ 0x0d, KEY_UP},
+	{ 0x0e, KEY_INFO},
+	{ 0x0f, KEY_CHANNELDOWN},
+	{ 0x10, KEY_LEFT},		/* Row 5 */
+	{ 0x11, KEY_SELECT},
+	{ 0x12, KEY_RIGHT},
+	{ 0x13, KEY_VOLUMEUP},
+	{ 0x14, KEY_LAST},		/* Row 6 */
+	{ 0x15, KEY_DOWN},
+	{ 0x16, KEY_MUTE},
+	{ 0x17, KEY_VOLUMEDOWN},
+};
+struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table = {
+	.scan = ir_codes_ati_tv_wonder_hd_600,
+	.size = ARRAY_SIZE(ir_codes_ati_tv_wonder_hd_600),
+};
+EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600_table);
 
 /* DVBWorld remotes
    Igor M. Liplianin <liplianin@me.by>
  */
-IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = {
-	[0x0a] = KEY_Q,		/*power*/
-	[0x0c] = KEY_M,		/*mute*/
-	[0x11] = KEY_1,
-	[0x12] = KEY_2,
-	[0x13] = KEY_3,
-	[0x14] = KEY_4,
-	[0x15] = KEY_5,
-	[0x16] = KEY_6,
-	[0x17] = KEY_7,
-	[0x18] = KEY_8,
-	[0x19] = KEY_9,
-	[0x10] = KEY_0,
-	[0x1c] = KEY_PAGEUP,	/*ch+*/
-	[0x0f] = KEY_PAGEDOWN,	/*ch-*/
-	[0x1a] = KEY_O,		/*vol+*/
-	[0x0e] = KEY_Z,		/*vol-*/
-	[0x04] = KEY_R,		/*rec*/
-	[0x09] = KEY_D,		/*fav*/
-	[0x08] = KEY_BACKSPACE,	/*rewind*/
-	[0x07] = KEY_A,		/*fast*/
-	[0x0b] = KEY_P,		/*pause*/
-	[0x02] = KEY_ESC,	/*cancel*/
-	[0x03] = KEY_G,		/*tab*/
-	[0x00] = KEY_UP,	/*up*/
-	[0x1f] = KEY_ENTER,	/*ok*/
-	[0x01] = KEY_DOWN,	/*down*/
-	[0x05] = KEY_C,		/*cap*/
-	[0x06] = KEY_S,		/*stop*/
-	[0x40] = KEY_F,		/*full*/
-	[0x1e] = KEY_W,		/*tvmode*/
-	[0x1b] = KEY_B,		/*recall*/
-};
-EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec);
+static struct ir_scancode ir_codes_dm1105_nec[] = {
+	{ 0x0a, KEY_POWER2},		/* power */
+	{ 0x0c, KEY_MUTE},		/* mute */
+	{ 0x11, KEY_1},
+	{ 0x12, KEY_2},
+	{ 0x13, KEY_3},
+	{ 0x14, KEY_4},
+	{ 0x15, KEY_5},
+	{ 0x16, KEY_6},
+	{ 0x17, KEY_7},
+	{ 0x18, KEY_8},
+	{ 0x19, KEY_9},
+	{ 0x10, KEY_0},
+	{ 0x1c, KEY_CHANNELUP},		/* ch+ */
+	{ 0x0f, KEY_CHANNELDOWN},	/* ch- */
+	{ 0x1a, KEY_VOLUMEUP},		/* vol+ */
+	{ 0x0e, KEY_VOLUMEDOWN},	/* vol- */
+	{ 0x04, KEY_RECORD},		/* rec */
+	{ 0x09, KEY_CHANNEL},		/* fav */
+	{ 0x08, KEY_BACKSPACE},		/* rewind */
+	{ 0x07, KEY_FASTFORWARD},	/* fast */
+	{ 0x0b, KEY_PAUSE},		/* pause */
+	{ 0x02, KEY_ESC},		/* cancel */
+	{ 0x03, KEY_TAB},		/* tab */
+	{ 0x00, KEY_UP},		/* up */
+	{ 0x1f, KEY_ENTER},		/* ok */
+	{ 0x01, KEY_DOWN},		/* down */
+	{ 0x05, KEY_RECORD},		/* cap */
+	{ 0x06, KEY_STOP},		/* stop */
+	{ 0x40, KEY_ZOOM},		/* full */
+	{ 0x1e, KEY_TV},		/* tvmode */
+	{ 0x1b, KEY_B},			/* recall */
+};
+struct ir_scancode_table ir_codes_dm1105_nec_table = {
+	.scan = ir_codes_dm1105_nec,
+	.size = ARRAY_SIZE(ir_codes_dm1105_nec),
+};
+EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
+
+/* Terratec Cinergy Hybrid T USB XS
+   Devin Heitmueller <dheitmueller@linuxtv.org>
+ */
+static struct ir_scancode ir_codes_terratec_cinergy_xs[] = {
+	{ 0x41, KEY_HOME},
+	{ 0x01, KEY_POWER},
+	{ 0x42, KEY_MENU},
+	{ 0x02, KEY_1},
+	{ 0x03, KEY_2},
+	{ 0x04, KEY_3},
+	{ 0x43, KEY_SUBTITLE},
+	{ 0x05, KEY_4},
+	{ 0x06, KEY_5},
+	{ 0x07, KEY_6},
+	{ 0x44, KEY_TEXT},
+	{ 0x08, KEY_7},
+	{ 0x09, KEY_8},
+	{ 0x0a, KEY_9},
+	{ 0x45, KEY_DELETE},
+	{ 0x0b, KEY_TUNER},
+	{ 0x0c, KEY_0},
+	{ 0x0d, KEY_MODE},
+	{ 0x46, KEY_TV},
+	{ 0x47, KEY_DVD},
+	{ 0x49, KEY_VIDEO},
+	{ 0x4b, KEY_AUX},
+	{ 0x10, KEY_UP},
+	{ 0x11, KEY_LEFT},
+	{ 0x12, KEY_OK},
+	{ 0x13, KEY_RIGHT},
+	{ 0x14, KEY_DOWN},
+	{ 0x0f, KEY_EPG},
+	{ 0x16, KEY_INFO},
+	{ 0x4d, KEY_BACKSPACE},
+	{ 0x1c, KEY_VOLUMEUP},
+	{ 0x4c, KEY_PLAY},
+	{ 0x1b, KEY_CHANNELUP},
+	{ 0x1e, KEY_VOLUMEDOWN},
+	{ 0x1d, KEY_MUTE},
+	{ 0x1f, KEY_CHANNELDOWN},
+	{ 0x17, KEY_RED},
+	{ 0x18, KEY_GREEN},
+	{ 0x19, KEY_YELLOW},
+	{ 0x1a, KEY_BLUE},
+	{ 0x58, KEY_RECORD},
+	{ 0x48, KEY_STOP},
+	{ 0x40, KEY_PAUSE},
+	{ 0x54, KEY_LAST},
+	{ 0x4e, KEY_REWIND},
+	{ 0x4f, KEY_FASTFORWARD},
+	{ 0x5c, KEY_NEXT},
+};
+struct ir_scancode_table ir_codes_terratec_cinergy_xs_table = {
+	.scan = ir_codes_terratec_cinergy_xs,
+	.size = ARRAY_SIZE(ir_codes_terratec_cinergy_xs),
+};
+EXPORT_SYMBOL_GPL(ir_codes_terratec_cinergy_xs_table);
 
 /* EVGA inDtube
    Devin Heitmueller <devin.heitmueller@gmail.com>
  */
-IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE] = {
-	[0x12] = KEY_POWER,
-	[0x02] = KEY_MODE,	/* TV */
-	[0x14] = KEY_MUTE,
-	[0x1a] = KEY_CHANNELUP,
-	[0x16] = KEY_TV2,	/* PIP */
-	[0x1d] = KEY_VOLUMEUP,
-	[0x05] = KEY_CHANNELDOWN,
-	[0x0f] = KEY_PLAYPAUSE,
-	[0x19] = KEY_VOLUMEDOWN,
-	[0x1c] = KEY_REWIND,
-	[0x0d] = KEY_RECORD,
-	[0x18] = KEY_FORWARD,
-	[0x1e] = KEY_PREVIOUS,
-	[0x1b] = KEY_STOP,
-	[0x1f] = KEY_NEXT,
-	[0x13] = KEY_CAMERA,
-};
-EXPORT_SYMBOL_GPL(ir_codes_evga_indtube);
+static struct ir_scancode ir_codes_evga_indtube[] = {
+	{ 0x12, KEY_POWER},
+	{ 0x02, KEY_MODE},	/* TV */
+	{ 0x14, KEY_MUTE},
+	{ 0x1a, KEY_CHANNELUP},
+	{ 0x16, KEY_TV2},	/* PIP */
+	{ 0x1d, KEY_VOLUMEUP},
+	{ 0x05, KEY_CHANNELDOWN},
+	{ 0x0f, KEY_PLAYPAUSE},
+	{ 0x19, KEY_VOLUMEDOWN},
+	{ 0x1c, KEY_REWIND},
+	{ 0x0d, KEY_RECORD},
+	{ 0x18, KEY_FORWARD},
+	{ 0x1e, KEY_PREVIOUS},
+	{ 0x1b, KEY_STOP},
+	{ 0x1f, KEY_NEXT},
+	{ 0x13, KEY_CAMERA},
+};
+struct ir_scancode_table ir_codes_evga_indtube_table = {
+	.scan = ir_codes_evga_indtube,
+	.size = ARRAY_SIZE(ir_codes_evga_indtube),
+};
+EXPORT_SYMBOL_GPL(ir_codes_evga_indtube_table);
+
+static struct ir_scancode ir_codes_videomate_s350[] = {
+	{ 0x00, KEY_TV},
+	{ 0x01, KEY_DVD},
+	{ 0x04, KEY_RECORD},
+	{ 0x05, KEY_VIDEO},	/* TV/Video */
+	{ 0x07, KEY_STOP},
+	{ 0x08, KEY_PLAYPAUSE},
+	{ 0x0a, KEY_REWIND},
+	{ 0x0f, KEY_FASTFORWARD},
+	{ 0x10, KEY_CHANNELUP},
+	{ 0x12, KEY_VOLUMEUP},
+	{ 0x13, KEY_CHANNELDOWN},
+	{ 0x14, KEY_MUTE},
+	{ 0x15, KEY_VOLUMEDOWN},
+	{ 0x16, KEY_1},
+	{ 0x17, KEY_2},
+	{ 0x18, KEY_3},
+	{ 0x19, KEY_4},
+	{ 0x1a, KEY_5},
+	{ 0x1b, KEY_6},
+	{ 0x1c, KEY_7},
+	{ 0x1d, KEY_8},
+	{ 0x1e, KEY_9},
+	{ 0x1f, KEY_0},
+	{ 0x21, KEY_SLEEP},
+	{ 0x24, KEY_ZOOM},
+	{ 0x25, KEY_LAST},	/* Recall */
+	{ 0x26, KEY_SUBTITLE},	/* CC */
+	{ 0x27, KEY_LANGUAGE},	/* MTS */
+	{ 0x29, KEY_CHANNEL},	/* SURF */
+	{ 0x2b, KEY_A},
+	{ 0x2c, KEY_B},
+	{ 0x2f, KEY_CAMERA},	/* Snapshot */
+	{ 0x23, KEY_RADIO},
+	{ 0x02, KEY_PREVIOUSSONG},
+	{ 0x06, KEY_NEXTSONG},
+	{ 0x03, KEY_EPG},
+	{ 0x09, KEY_SETUP},
+	{ 0x22, KEY_BACKSPACE},
+	{ 0x0c, KEY_UP},
+	{ 0x0e, KEY_DOWN},
+	{ 0x0b, KEY_LEFT},
+	{ 0x0d, KEY_RIGHT},
+	{ 0x11, KEY_ENTER},
+	{ 0x20, KEY_TEXT},
+};
+struct ir_scancode_table ir_codes_videomate_s350_table = {
+	.scan = ir_codes_videomate_s350,
+	.size = ARRAY_SIZE(ir_codes_videomate_s350),
+};
+EXPORT_SYMBOL_GPL(ir_codes_videomate_s350_table);
+
+/* GADMEI UTV330+ RM008Z remote
+   Shine Liu <shinel@foxmail.com>
+ */
+static struct ir_scancode ir_codes_gadmei_rm008z[] = {
+	{ 0x14, KEY_POWER2},		/* POWER OFF */
+	{ 0x0c, KEY_MUTE},		/* MUTE */
+
+	{ 0x18, KEY_TV},		/* TV */
+	{ 0x0e, KEY_VIDEO},		/* AV */
+	{ 0x0b, KEY_AUDIO},		/* SV */
+	{ 0x0f, KEY_RADIO},		/* FM */
+
+	{ 0x00, KEY_1},
+	{ 0x01, KEY_2},
+	{ 0x02, KEY_3},
+	{ 0x03, KEY_4},
+	{ 0x04, KEY_5},
+	{ 0x05, KEY_6},
+	{ 0x06, KEY_7},
+	{ 0x07, KEY_8},
+	{ 0x08, KEY_9},
+	{ 0x09, KEY_0},
+	{ 0x0a, KEY_INFO},		/* OSD */
+	{ 0x1c, KEY_BACKSPACE},		/* LAST */
+
+	{ 0x0d, KEY_PLAY},		/* PLAY */
+	{ 0x1e, KEY_CAMERA},		/* SNAPSHOT */
+	{ 0x1a, KEY_RECORD},		/* RECORD */
+	{ 0x17, KEY_STOP},		/* STOP */
+
+	{ 0x1f, KEY_UP},		/* UP */
+	{ 0x44, KEY_DOWN},		/* DOWN */
+	{ 0x46, KEY_TAB},		/* BACK */
+	{ 0x4a, KEY_ZOOM},		/* FULLSECREEN */
+
+	{ 0x10, KEY_VOLUMEUP},		/* VOLUMEUP */
+	{ 0x11, KEY_VOLUMEDOWN},	/* VOLUMEDOWN */
+	{ 0x12, KEY_CHANNELUP},		/* CHANNELUP */
+	{ 0x13, KEY_CHANNELDOWN},	/* CHANNELDOWN */
+	{ 0x15, KEY_ENTER},		/* OK */
+};
+struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
+	.scan = ir_codes_gadmei_rm008z,
+	.size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
+};
+EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index fc76c30..155c93e 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -210,7 +210,8 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
 	tda18271_i2c_gate_ctrl(fe, 0);
 
 	if (ret != 1)
-		tda_err("ERROR: i2c_transfer returned: %d\n", ret);
+		tda_err("ERROR: idx = 0x%x, len = %d, "
+			"i2c_transfer returned: %d\n", idx, len, ret);
 
 	return (ret == 1 ? 0 : ret);
 }
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index b109356..6459511 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -27,7 +27,7 @@ module_param_named(debug, tda18271_debug, int, 0644);
 MODULE_PARM_DESC(debug, "set debug level "
 		 "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))");
 
-static int tda18271_cal_on_startup;
+static int tda18271_cal_on_startup = -1;
 module_param_named(cal, tda18271_cal_on_startup, int, 0644);
 MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
 
@@ -36,6 +36,27 @@ static LIST_HEAD(hybrid_tuner_instance_list);
 
 /*---------------------------------------------------------------------*/
 
+static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)
+{
+	struct tda18271_priv *priv = fe->tuner_priv;
+
+	int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,
+			priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,
+			priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);
+
+	if (tda_fail(ret))
+		goto fail;
+
+	tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n",
+		standby ? "standby" : "active",
+		priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",
+		priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");
+fail:
+	return ret;
+}
+
+/*---------------------------------------------------------------------*/
+
 static inline int charge_pump_source(struct dvb_frontend *fe, int force)
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
@@ -271,7 +292,7 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
 	tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
 
 	/* calculate temperature compensation */
-	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
+	rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000;
 
 	regs[R_EB14] = approx + rfcal_comp;
 	ret = tda18271_write_regs(fe, R_EB14, 1);
@@ -800,7 +821,7 @@ static int tda18271_init(struct dvb_frontend *fe)
 
 	mutex_lock(&priv->lock);
 
-	/* power up */
+	/* full power up */
 	ret = tda18271_set_standby_mode(fe, 0, 0, 0);
 	if (tda_fail(ret))
 		goto fail;
@@ -818,6 +839,21 @@ fail:
 	return ret;
 }
 
+static int tda18271_sleep(struct dvb_frontend *fe)
+{
+	struct tda18271_priv *priv = fe->tuner_priv;
+	int ret;
+
+	mutex_lock(&priv->lock);
+
+	/* enter standby mode, with required output features enabled */
+	ret = tda18271_toggle_output(fe, 1);
+
+	mutex_unlock(&priv->lock);
+
+	return ret;
+}
+
 /* ------------------------------------------------------------------ */
 
 static int tda18271_agc(struct dvb_frontend *fe)
@@ -827,8 +863,9 @@ static int tda18271_agc(struct dvb_frontend *fe)
 
 	switch (priv->config) {
 	case 0:
-		/* no LNA */
-		tda_dbg("no agc configuration provided\n");
+		/* no external agc configuration required */
+		if (tda18271_debug & DBG_ADV)
+			tda_dbg("no agc configuration provided\n");
 		break;
 	case 3:
 		/* switch with GPIO of saa713x */
@@ -1010,22 +1047,6 @@ fail:
 	return ret;
 }
 
-static int tda18271_sleep(struct dvb_frontend *fe)
-{
-	struct tda18271_priv *priv = fe->tuner_priv;
-	int ret;
-
-	mutex_lock(&priv->lock);
-
-	/* standby mode w/ slave tuner output
-	 * & loop thru & xtal oscillator on */
-	ret = tda18271_set_standby_mode(fe, 1, 0, 0);
-
-	mutex_unlock(&priv->lock);
-
-	return ret;
-}
-
 static int tda18271_release(struct dvb_frontend *fe)
 {
 	struct tda18271_priv *priv = fe->tuner_priv;
@@ -1192,18 +1213,33 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
 	case 0:
 		goto fail;
 	case 1:
+	{
 		/* new tuner instance */
+		int rf_cal_on_startup;
+
 		priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
 		priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
 		priv->config = (cfg) ? cfg->config : 0;
+		priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
+		priv->output_opt = (cfg) ?
+			cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
+
+		/* tda18271_cal_on_startup == -1 when cal
+		 * module option is unset */
+		if (tda18271_cal_on_startup == -1) {
+			/* honor attach-time configuration */
+			rf_cal_on_startup =
+				((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
+		} else {
+			/* module option overrides attach configuration */
+			rf_cal_on_startup = tda18271_cal_on_startup;
+		}
+
 		priv->cal_initialized = false;
 		mutex_init(&priv->lock);
 
 		fe->tuner_priv = priv;
 
-		if (cfg)
-			priv->small_i2c = cfg->small_i2c;
-
 		if (tda_fail(tda18271_get_id(fe)))
 			goto fail;
 
@@ -1213,18 +1249,29 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
 		mutex_lock(&priv->lock);
 		tda18271_init_regs(fe);
 
-		if ((tda18271_cal_on_startup) && (priv->id == TDA18271HDC2))
+		if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2))
 			tda18271c2_rf_cal_init(fe);
 
 		mutex_unlock(&priv->lock);
 		break;
+	}
 	default:
 		/* existing tuner instance */
 		fe->tuner_priv = priv;
 
-		/* allow dvb driver to override i2c gate setting */
-		if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
-			priv->gate = cfg->gate;
+		/* allow dvb driver to override configuration settings */
+		if (cfg) {
+			if (cfg->gate != TDA18271_GATE_ANALOG)
+				priv->gate = cfg->gate;
+			if (cfg->role)
+				priv->role = cfg->role;
+			if (cfg->config)
+				priv->config = cfg->config;
+			if (cfg->small_i2c)
+				priv->small_i2c = cfg->small_i2c;
+			if (cfg->output_opt)
+				priv->output_opt = cfg->output_opt;
+		}
 		break;
 	}
 
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index ab14ceb..e21fdef 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -962,10 +962,9 @@ struct tda18271_cid_target_map {
 static struct tda18271_cid_target_map tda18271_cid_target[] = {
 	{ .rfmax =  46000, .target = 0x04, .limit =  1800 },
 	{ .rfmax =  52200, .target = 0x0a, .limit =  1500 },
-	{ .rfmax =  79100, .target = 0x01, .limit =  4000 },
+	{ .rfmax =  70100, .target = 0x01, .limit =  4000 },
 	{ .rfmax = 136800, .target = 0x18, .limit =  4000 },
 	{ .rfmax = 156700, .target = 0x18, .limit =  4000 },
-	{ .rfmax = 156700, .target = 0x18, .limit =  4000 },
 	{ .rfmax = 186250, .target = 0x0a, .limit =  4000 },
 	{ .rfmax = 230000, .target = 0x0a, .limit =  4000 },
 	{ .rfmax = 345000, .target = 0x18, .limit =  4000 },
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 74beb28..2bee229 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -108,6 +108,7 @@ struct tda18271_priv {
 	enum tda18271_role role;
 	enum tda18271_i2c_gate gate;
 	enum tda18271_ver id;
+	enum tda18271_output_options output_opt;
 
 	unsigned int config; /* interface to saa713x / tda829x */
 	unsigned int tm_rfcal;
@@ -137,17 +138,17 @@ extern int tda18271_debug;
 #define tda_printk(kern, fmt, arg...) \
 	printk(kern "%s: " fmt, __func__, ##arg)
 
-#define dprintk(kern, lvl, fmt, arg...) do {\
+#define tda_dprintk(lvl, fmt, arg...) do {\
 	if (tda18271_debug & lvl) \
-		tda_printk(kern, fmt, ##arg); } while (0)
-
-#define tda_info(fmt, arg...) printk(KERN_INFO              fmt, ##arg)
-#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING,      fmt, ##arg)
-#define tda_err(fmt, arg...)  tda_printk(KERN_ERR,          fmt, ##arg)
-#define tda_dbg(fmt, arg...)  dprintk(KERN_DEBUG, DBG_INFO, fmt, ##arg)
-#define tda_map(fmt, arg...)  dprintk(KERN_DEBUG, DBG_MAP,  fmt, ##arg)
-#define tda_reg(fmt, arg...)  dprintk(KERN_DEBUG, DBG_REG,  fmt, ##arg)
-#define tda_cal(fmt, arg...)  dprintk(KERN_DEBUG, DBG_CAL,  fmt, ##arg)
+		tda_printk(KERN_DEBUG, fmt, ##arg); } while (0)
+
+#define tda_info(fmt, arg...)     printk(KERN_INFO     fmt, ##arg)
+#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
+#define tda_err(fmt, arg...)  tda_printk(KERN_ERR,     fmt, ##arg)
+#define tda_dbg(fmt, arg...)  tda_dprintk(DBG_INFO,    fmt, ##arg)
+#define tda_map(fmt, arg...)  tda_dprintk(DBG_MAP,     fmt, ##arg)
+#define tda_reg(fmt, arg...)  tda_dprintk(DBG_REG,     fmt, ##arg)
+#define tda_cal(fmt, arg...)  tda_dprintk(DBG_CAL,     fmt, ##arg)
 
 #define tda_fail(ret)							     \
 ({									     \
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 53a9892..323f291 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -67,6 +67,17 @@ enum tda18271_i2c_gate {
 	TDA18271_GATE_DIGITAL,
 };
 
+enum tda18271_output_options {
+	/* slave tuner output & loop thru & xtal oscillator always on */
+	TDA18271_OUTPUT_LT_XT_ON = 0,
+
+	/* slave tuner output loop thru off */
+	TDA18271_OUTPUT_LT_OFF = 1,
+
+	/* xtal oscillator off */
+	TDA18271_OUTPUT_XT_OFF = 2,
+};
+
 struct tda18271_config {
 	/* override default if freq / std settings (optional) */
 	struct tda18271_std_map *std_map;
@@ -77,6 +88,12 @@ struct tda18271_config {
 	/* use i2c gate provided by analog or digital demod */
 	enum tda18271_i2c_gate gate;
 
+	/* output options that can be disabled */
+	enum tda18271_output_options output_opt;
+
+	/* force rf tracking filter calibration on startup */
+	unsigned int rf_cal_on_startup:1;
+
 	/* some i2c providers cant write all 39 registers at once */
 	unsigned int small_i2c:1;
 
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 149d54c..8abbcc5 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -144,6 +144,8 @@ static inline int tuner_stereo(const int type, const int status)
 	case TUNER_LG_NTSC_TAPE:
 	case TUNER_TCL_MF02GIP_5N:
 		return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
+	case TUNER_PHILIPS_FM1216MK5:
+		return status | TUNER_STEREO;
 	default:
 		return status & TUNER_STEREO;
 	}
@@ -508,6 +510,10 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
 	case TUNER_TCL_MF02GIP_5N:
 		buffer[3] = 0x19;
 		break;
+	case TUNER_PHILIPS_FM1216MK5:
+		buffer[2] = 0x88;
+		buffer[3] = 0x09;
+		break;
 	case TUNER_TNF_5335MF:
 		buffer[3] = 0x11;
 		break;
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 6a7f1a4..2b876f3 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1301,6 +1301,42 @@ static struct tuner_params tuner_fq1216lme_mk3_params[] = {
 	},
 };
 
+/* ----- TUNER_PARTSNIC_PTI_5NF05 - Partsnic (Daewoo) PTI-5NF05 NTSC ----- */
+
+static struct tuner_range tuner_partsnic_pti_5nf05_ranges[] = {
+	/* The datasheet specified channel ranges and the bandswitch byte */
+	/* The control byte value of 0x8e is just a guess */
+	{ 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, /* Channels    2 -    B */
+	{ 16 * 367.25 /*MHz*/, 0x8e, 0x02, }, /* Channels    C - W+11 */
+	{ 16 * 999.99        , 0x8e, 0x08, }, /* Channels W+12 -   69 */
+};
+
+static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_NTSC,
+		.ranges = tuner_partsnic_pti_5nf05_ranges,
+		.count  = ARRAY_SIZE(tuner_partsnic_pti_5nf05_ranges),
+		.cb_first_if_lower_freq = 1, /* not specified but safe to do */
+	},
+};
+
+/* --------- TUNER_PHILIPS_CU1216L - DVB-C NIM ------------------------- */
+
+static struct tuner_range tuner_cu1216l_ranges[] = {
+	{ 16 * 160.25 /*MHz*/, 0xce, 0x01 },
+	{ 16 * 444.25 /*MHz*/, 0xce, 0x02 },
+	{ 16 * 999.99        , 0xce, 0x04 },
+};
+
+static struct tuner_params tuner_philips_cu1216l_params[] = {
+	{
+		.type   = TUNER_PARAM_TYPE_DIGITAL,
+		.ranges = tuner_cu1216l_ranges,
+		.count  = ARRAY_SIZE(tuner_cu1216l_ranges),
+		.iffreq = 16 * 36.125, /*MHz*/
+	},
+};
+
 /* --------------------------------------------------------------------- */
 
 struct tunertype tuners[] = {
@@ -1753,6 +1789,22 @@ struct tunertype tuners[] = {
 		.params = tuner_fq1216lme_mk3_params,
 		.count  = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
 	},
+
+	[TUNER_PARTSNIC_PTI_5NF05] = {
+		.name = "Partsnic (Daewoo) PTI-5NF05",
+		.params = tuner_partsnic_pti_5nf05_params,
+		.count  = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
+	},
+	[TUNER_PHILIPS_CU1216L] = {
+		.name = "Philips CU1216L",
+		.params = tuner_philips_cu1216l_params,
+		.count  = ARRAY_SIZE(tuner_philips_cu1216l_params),
+		.stepsize = 62500,
+	},
+	[TUNER_NXP_TDA18271] = {
+		.name   = "NXP TDA18271",
+		/* see tda18271-fe.c for details */
+	},
 };
 EXPORT_SYMBOL(tuners);
 
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index b019869..35d0817 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -2,6 +2,19 @@
 # DVB device configuration
 #
 
+config DVB_MAX_ADAPTERS
+	int "maximum number of DVB/ATSC adapters"
+	depends on DVB_CORE
+	default 8
+	range 1 255
+	help
+	  Maximum number of DVB/ATSC adapters. Increasing this number
+	  increases the memory consumption of the DVB subsystem even
+	  if a much lower number of DVB/ATSC adapters is present.
+	  Only values in the range 4-32 are tested.
+
+	  If you are unsure about this, use the default value 8
+
 config DVB_DYNAMIC_MINORS
 	bool "Dynamic DVB minor allocation"
 	depends on DVB_CORE
@@ -55,6 +68,10 @@ comment "Supported FireWire (IEEE 1394) Adapters"
 	depends on DVB_CORE && IEEE1394
 source "drivers/media/dvb/firewire/Kconfig"
 
+comment "Supported Earthsoft PT1 Adapters"
+	depends on DVB_CORE && PCI && I2C
+source "drivers/media/dvb/pt1/Kconfig"
+
 comment "Supported DVB Frontends"
 	depends on DVB_CORE
 source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 6092a5b..16d262d 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,6 +2,6 @@
 # Makefile for the kernel multimedia device drivers.
 #
 
-obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/
+obj-y        := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ pt1/
 
 obj-$(CONFIG_DVB_FIREDTV)	+= firewire/
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 9a6307a..850a6c6 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -66,7 +66,7 @@ static int flexcop_sleep(struct dvb_frontend* fe)
 #endif
 
 /* SkyStar2 DVB-S rev 2.3 */
-#if FE_SUPPORTED(MT312)
+#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
 static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
 {
 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
@@ -155,55 +155,34 @@ static struct mt312_config skystar23_samsung_tbdu18132_config = {
 	.demod_address = 0x0e,
 };
 
-static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe,
-	struct dvb_frontend_parameters *params)
-{
-	u8 buf[4];
-	u32 div;
-	struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf,
-	.len = sizeof(buf) };
-	struct flexcop_device *fc = fe->dvb->priv;
-	div = (params->frequency + (125/2)) / 125;
-
-	buf[0] = (div >> 8) & 0x7f;
-	buf[1] = (div >> 0) & 0xff;
-	buf[2] = 0x84 | ((div >> 10) & 0x60);
-	buf[3] = 0x80;
-
-	if (params->frequency < 1550000)
-		buf[3] |= 0x02;
-
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
-		return -EIO;
-	return 0;
-}
-
 static int skystar2_rev23_attach(struct flexcop_device *fc,
 	struct i2c_adapter *i2c)
 {
+	struct dvb_frontend_ops *ops;
+
 	fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
-	if (fc->fe != NULL) {
-		struct dvb_frontend_ops *ops = &fc->fe->ops;
-		ops->tuner_ops.set_params   =
-			skystar23_samsung_tbdu18132_tuner_set_params;
-		ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
-		ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
-		ops->set_tone               = flexcop_set_tone;
-		ops->set_voltage            = flexcop_set_voltage;
-		fc->fe_sleep                = ops->sleep;
-		ops->sleep                  = flexcop_sleep;
-		return 1;
-	}
-	return 0;
+	if (!fc->fe)
+		return 0;
+
+	if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
+			DVB_PLL_SAMSUNG_TBDU18132))
+		return 0;
+
+	ops = &fc->fe->ops;
+	ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
+	ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
+	ops->set_tone               = flexcop_set_tone;
+	ops->set_voltage            = flexcop_set_voltage;
+	fc->fe_sleep                = ops->sleep;
+	ops->sleep                  = flexcop_sleep;
+	return 1;
 }
 #else
 #define skystar2_rev23_attach NULL
 #endif
 
 /* SkyStar2 DVB-S rev 2.6 */
-#if FE_SUPPORTED(STV0299)
+#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
 static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
 	u32 srate, u32 ratio)
 {
@@ -232,31 +211,6 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
 	return 0;
 }
 
-static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend *fe,
-	struct dvb_frontend_parameters *params)
-{
-	u8 buf[4];
-	u32 div;
-	struct i2c_msg msg = {
-	.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
-	struct flexcop_device *fc = fe->dvb->priv;
-	div = params->frequency / 125;
-
-	buf[0] = (div >> 8) & 0x7f;
-	buf[1] = div & 0xff;
-	buf[2] = 0x84; /* 0xC4 */
-	buf[3] = 0x08;
-
-	if (params->frequency < 1500000)
-		buf[3] |= 0x10;
-
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-	if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
-		return -EIO;
-	return 0;
-}
-
 static u8 samsung_tbmu24112_inittab[] = {
 	0x01, 0x15,
 	0x02, 0x30,
@@ -318,15 +272,18 @@ static int skystar2_rev26_attach(struct flexcop_device *fc,
 	struct i2c_adapter *i2c)
 {
 	fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
-	if (fc->fe != NULL) {
-		struct dvb_frontend_ops *ops  = &fc->fe->ops;
-		ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
-		ops->set_voltage = flexcop_set_voltage;
-		fc->fe_sleep = ops->sleep;
-		ops->sleep = flexcop_sleep;
-		return 1;
-	}
-	return 0;
+	if (!fc->fe)
+		return 0;
+
+	if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
+			DVB_PLL_SAMSUNG_TBMU24112))
+		return 0;
+
+	fc->fe->ops.set_voltage = flexcop_set_voltage;
+	fc->fe_sleep = fc->fe->ops.sleep;
+	fc->fe->ops.sleep = flexcop_sleep;
+	return 1;
+
 }
 #else
 #define skystar2_rev26_attach NULL
@@ -421,7 +378,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
 	if (!fc->fe)
 		return 0;
 
-	i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);;
+	i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
 	if (!i2c_tuner)
 		return 0;
 
@@ -449,7 +406,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
 #endif
 
 /* AirStar DVB-T */
-#if FE_SUPPORTED(MT352)
+#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
 static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
 {
 	static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
@@ -467,32 +424,6 @@ static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
 	return 0;
 }
 
-static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend *fe,
-	struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
-{
-	u32 div;
-	unsigned char bs = 0;
-
-	if (buf_len < 5)
-		return -EINVAL;
-
-#define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
-	div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-	if (params->frequency >= 48000000 && params->frequency <= 154000000) \
-		bs = 0x09;
-	if (params->frequency >= 161000000 && params->frequency <= 439000000) \
-		bs = 0x0a;
-	if (params->frequency >= 447000000 && params->frequency <= 863000000) \
-		bs = 0x08;
-
-	pllbuf[0] = 0x61;
-	pllbuf[1] = div >> 8;
-	pllbuf[2] = div & 0xff;
-	pllbuf[3] = 0xcc;
-	pllbuf[4] = bs;
-	return 5;
-}
-
 static struct mt352_config samsung_tdtc9251dh0_config = {
 	.demod_address = 0x0f,
 	.demod_init    = samsung_tdtc9251dh0_demod_init,
@@ -502,11 +433,11 @@ static int airstar_dvbt_attach(struct flexcop_device *fc,
 	struct i2c_adapter *i2c)
 {
 	fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
-	if (fc->fe != NULL) {
-		fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
-		return 1;
-	}
-	return 0;
+	if (!fc->fe)
+		return 0;
+
+	return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
+			    DVB_PLL_SAMSUNG_TDTC9251DH0);
 }
 #else
 #define airstar_dvbt_attach NULL
@@ -580,54 +511,7 @@ static int airstar_atsc3_attach(struct flexcop_device *fc,
 #endif
 
 /* CableStar2 DVB-C */
-#if FE_SUPPORTED(STV0297)
-static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
-		struct dvb_frontend_parameters *fep)
-{
-	struct flexcop_device *fc = fe->dvb->priv;
-	u8 buf[4];
-	u16 div;
-	int ret;
-
-/* 62.5 kHz * 10 */
-#define REF_FREQ    625
-#define FREQ_OFFSET 36125
-
-	div = ((fep->frequency/1000 + FREQ_OFFSET) * 10) / REF_FREQ;
-/* 4 MHz = 4000 KHz */
-
-	buf[0] = (u8)( div >> 8) & 0x7f;
-	buf[1] = (u8)        div & 0xff;
-
-/* F(osc) = N * Reference Freq. (62.5 kHz)
- * byte 2 :  0 N14 N13 N12 N11 N10 N9  N8
- * byte 3 : N7 N6  N5  N4  N3  N2  N1  N0
- * byte 4 : 1  *   *   AGD R3  R2  R1  R0
- * byte 5 : C1 *   RE  RTS BS4 BS3 BS2 BS1
- * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
-	buf[2] = 0x95;
-
-/* Range(MHz)  C1 *  RE RTS BS4 BS3 BS2 BS1  Byte 5
- *  47 - 153   0  *  0   0   0   0   0   1   0x01
- * 153 - 430   0  *  0   0   0   0   1   0   0x02
- * 430 - 822   0  *  0   0   1   0   0   0   0x08
- * 822 - 862   1  *  0   0   1   0   0   0   0x88 */
-
-	     if (fep->frequency <= 153000000) buf[3] = 0x01;
-	else if (fep->frequency <= 430000000) buf[3] = 0x02;
-	else if (fep->frequency <= 822000000) buf[3] = 0x08;
-	else buf[3] = 0x88;
-
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 0);
-	deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n", fep->frequency,
-	buf[0], buf[1], buf[2], buf[3]);
-	ret = fc->i2c_request(&fc->fc_i2c_adap[2],
-			FC_WRITE, 0x61, buf[0], &buf[1], 3);
-	deb_tuner("tuner write returned: %d\n",ret);
-	return ret;
-}
-
+#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
 static u8 alps_tdee4_stv0297_inittab[] = {
 	0x80, 0x01,
 	0x80, 0x00,
@@ -711,13 +595,25 @@ static int cablestar2_attach(struct flexcop_device *fc,
 {
 	fc->fc_i2c_adap[0].no_base_addr = 1;
 	fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
-	if (!fc->fe) {
-		/* Reset for next frontend to try */
-		fc->fc_i2c_adap[0].no_base_addr = 0;
-		return 0;
-	}
-	fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
+	if (!fc->fe)
+		goto fail;
+
+	/* This tuner doesn't use the stv0297's I2C gate, but instead the
+	 * tuner is connected to a different flexcop I2C adapter.  */
+	if (fc->fe->ops.i2c_gate_ctrl)
+		fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
+	fc->fe->ops.i2c_gate_ctrl = NULL;
+
+	if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
+			&fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
+		goto fail;
+
 	return 1;
+
+fail:
+	/* Reset for next frontend to try */
+	fc->fc_i2c_adap[0].no_base_addr = 0;
+	return 0;
 }
 #else
 #define cablestar2_attach NULL
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index fec1d77..91353a6 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -1059,7 +1059,7 @@ static int dst_get_tuner_info(struct dst_state *state)
 		dprintk(verbose, DST_ERROR, 1, "DST type has TS=188");
 	}
 	if (state->board_info[0] == 0xbc) {
-		if (state->type_flags != DST_TYPE_IS_ATSC)
+		if (state->dst_type != DST_TYPE_IS_ATSC)
 			state->type_flags |= DST_TYPE_HAS_TS188;
 		else
 			state->type_flags |= DST_TYPE_HAS_NEWTUNE_2;
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index 4dbd7d4..2d099e2 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -44,6 +44,14 @@
 #include "cx24116.h"
 #include "z0194a.h"
 
+#define UNSET (-1U)
+
+#define DM1105_BOARD_NOAUTO		UNSET
+#define DM1105_BOARD_UNKNOWN		0
+#define DM1105_BOARD_DVBWORLD_2002	1
+#define DM1105_BOARD_DVBWORLD_2004	2
+#define DM1105_BOARD_AXESS_DM05		3
+
 /* ----------------------------------------------- */
 /*
  * PCI ID's
@@ -153,20 +161,105 @@
 
 /* GPIO's for LNB power control */
 #define DM1105_LNB_MASK				0x00000000
+#define DM1105_LNB_OFF				0x00020000
 #define DM1105_LNB_13V				0x00010100
 #define DM1105_LNB_18V				0x00000100
 
 /* GPIO's for LNB power control for Axess DM05 */
 #define DM05_LNB_MASK				0x00000000
+#define DM05_LNB_OFF				0x00020000/* actually 13v */
 #define DM05_LNB_13V				0x00020000
 #define DM05_LNB_18V				0x00030000
 
+static unsigned int card[]  = {[0 ... 3] = UNSET };
+module_param_array(card,  int, NULL, 0444);
+MODULE_PARM_DESC(card, "card type");
+
 static int ir_debug;
 module_param(ir_debug, int, 0644);
 MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
 
+static unsigned int dm1105_devcount;
+
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
+struct dm1105_board {
+	char                    *name;
+};
+
+struct dm1105_subid {
+	u16     subvendor;
+	u16     subdevice;
+	u32     card;
+};
+
+static const struct dm1105_board dm1105_boards[] = {
+	[DM1105_BOARD_UNKNOWN] = {
+		.name		= "UNKNOWN/GENERIC",
+	},
+	[DM1105_BOARD_DVBWORLD_2002] = {
+		.name		= "DVBWorld PCI 2002",
+	},
+	[DM1105_BOARD_DVBWORLD_2004] = {
+		.name		= "DVBWorld PCI 2004",
+	},
+	[DM1105_BOARD_AXESS_DM05] = {
+		.name		= "Axess/EasyTv DM05",
+	},
+};
+
+static const struct dm1105_subid dm1105_subids[] = {
+	{
+		.subvendor = 0x0000,
+		.subdevice = 0x2002,
+		.card      = DM1105_BOARD_DVBWORLD_2002,
+	}, {
+		.subvendor = 0x0001,
+		.subdevice = 0x2002,
+		.card      = DM1105_BOARD_DVBWORLD_2002,
+	}, {
+		.subvendor = 0x0000,
+		.subdevice = 0x2004,
+		.card      = DM1105_BOARD_DVBWORLD_2004,
+	}, {
+		.subvendor = 0x0001,
+		.subdevice = 0x2004,
+		.card      = DM1105_BOARD_DVBWORLD_2004,
+	}, {
+		.subvendor = 0x195d,
+		.subdevice = 0x1105,
+		.card      = DM1105_BOARD_AXESS_DM05,
+	},
+};
+
+static void dm1105_card_list(struct pci_dev *pci)
+{
+	int i;
+
+	if (0 == pci->subsystem_vendor &&
+			0 == pci->subsystem_device) {
+		printk(KERN_ERR
+			"dm1105: Your board has no valid PCI Subsystem ID\n"
+			"dm1105: and thus can't be autodetected\n"
+			"dm1105: Please pass card=<n> insmod option to\n"
+			"dm1105: workaround that.  Redirect complaints to\n"
+			"dm1105: the vendor of the TV card.  Best regards,\n"
+			"dm1105: -- tux\n");
+	} else {
+		printk(KERN_ERR
+			"dm1105: Your board isn't known (yet) to the driver.\n"
+			"dm1105: You can try to pick one of the existing\n"
+			"dm1105: card configs via card=<n> insmod option.\n"
+			"dm1105: Updating to the latest version might help\n"
+			"dm1105: as well.\n");
+	}
+	printk(KERN_ERR "Here is a list of valid choices for the card=<n> "
+		   "insmod option:\n");
+	for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++)
+		printk(KERN_ERR "dm1105:    card=%d -> %s\n",
+				i, dm1105_boards[i].name);
+}
+
 /* infrared remote control */
 struct infrared {
 	struct input_dev	*input_dev;
@@ -193,6 +286,8 @@ struct dm1105dvb {
 	struct dvb_frontend *fe;
 	struct dvb_net dvbnet;
 	unsigned int full_ts_users;
+	unsigned int boardnr;
+	int nr;
 
 	/* i2c */
 	struct i2c_adapter i2c_adap;
@@ -211,7 +306,6 @@ struct dm1105dvb {
 	unsigned int	PacketErrorCount;
 	unsigned int dmarst;
 	spinlock_t lock;
-
 };
 
 #define dm_io_mem(reg)	((unsigned long)(&dm1105dvb->io_mem[reg]))
@@ -326,16 +420,20 @@ static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe)
 static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 {
 	struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe);
-	u32 lnb_mask, lnb_13v, lnb_18v;
+	u32 lnb_mask, lnb_13v, lnb_18v, lnb_off;
 
-	switch (dm1105dvb->pdev->subsystem_device) {
-	case PCI_DEVICE_ID_DM05:
+	switch (dm1105dvb->boardnr) {
+	case DM1105_BOARD_AXESS_DM05:
 		lnb_mask = DM05_LNB_MASK;
+		lnb_off = DM05_LNB_OFF;
 		lnb_13v = DM05_LNB_13V;
 		lnb_18v = DM05_LNB_18V;
 		break;
+	case DM1105_BOARD_DVBWORLD_2002:
+	case DM1105_BOARD_DVBWORLD_2004:
 	default:
 		lnb_mask = DM1105_LNB_MASK;
+		lnb_off = DM1105_LNB_OFF;
 		lnb_13v = DM1105_LNB_13V;
 		lnb_18v = DM1105_LNB_18V;
 	}
@@ -343,8 +441,10 @@ static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volta
 	outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR));
 	if (voltage == SEC_VOLTAGE_18)
 		outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL));
-	else
+	else if (voltage == SEC_VOLTAGE_13)
 		outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL));
+	else
+		outl(lnb_off, dm_io_mem(DM1105_GPIOVAL));
 
 	return 0;
 }
@@ -477,7 +577,7 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
 int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
 {
 	struct input_dev *input_dev;
-	IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec;
+	struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table;
 	int ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
@@ -589,8 +689,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
 {
 	int ret;
 
-	switch (dm1105dvb->pdev->subsystem_device) {
-	case PCI_DEVICE_ID_DW2004:
+	switch (dm1105dvb->boardnr) {
+	case DM1105_BOARD_DVBWORLD_2004:
 		dm1105dvb->fe = dvb_attach(
 			cx24116_attach, &serit_sp2633_config,
 			&dm1105dvb->i2c_adap);
@@ -598,6 +698,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb)
 			dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage;
 
 		break;
+	case DM1105_BOARD_DVBWORLD_2002:
+	case DM1105_BOARD_AXESS_DM05:
 	default:
 		dm1105dvb->fe = dvb_attach(
 			stv0299_attach, &sharp_z0194a_config,
@@ -676,11 +778,31 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
 	struct dvb_demux *dvbdemux;
 	struct dmx_demux *dmx;
 	int ret = -ENOMEM;
+	int i;
 
 	dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
 	if (!dm1105dvb)
 		return -ENOMEM;
 
+	/* board config */
+	dm1105dvb->nr = dm1105_devcount;
+	dm1105dvb->boardnr = UNSET;
+	if (card[dm1105dvb->nr] < ARRAY_SIZE(dm1105_boards))
+		dm1105dvb->boardnr = card[dm1105dvb->nr];
+	for (i = 0; UNSET == dm1105dvb->boardnr &&
+				i < ARRAY_SIZE(dm1105_subids); i++)
+		if (pdev->subsystem_vendor ==
+			dm1105_subids[i].subvendor &&
+				pdev->subsystem_device ==
+					dm1105_subids[i].subdevice)
+			dm1105dvb->boardnr = dm1105_subids[i].card;
+
+	if (UNSET == dm1105dvb->boardnr) {
+		dm1105dvb->boardnr = DM1105_BOARD_UNKNOWN;
+		dm1105_card_list(pdev);
+	}
+
+	dm1105_devcount++;
 	dm1105dvb->pdev = pdev;
 	dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
 	dm1105dvb->PacketErrorCount = 0;
@@ -853,6 +975,7 @@ static void __devexit dm1105_remove(struct pci_dev *pdev)
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
+	dm1105_devcount--;
 	kfree(dm1105dvb);
 }
 
@@ -861,17 +984,12 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = {
 		.vendor = PCI_VENDOR_ID_TRIGEM,
 		.device = PCI_DEVICE_ID_DM1105,
 		.subvendor = PCI_ANY_ID,
-		.subdevice = PCI_DEVICE_ID_DW2002,
-	}, {
-		.vendor = PCI_VENDOR_ID_TRIGEM,
-		.device = PCI_DEVICE_ID_DM1105,
-		.subvendor = PCI_ANY_ID,
-		.subdevice = PCI_DEVICE_ID_DW2004,
+		.subdevice = PCI_ANY_ID,
 	}, {
 		.vendor = PCI_VENDOR_ID_AXESS,
 		.device = PCI_DEVICE_ID_DM05,
-		.subvendor = PCI_VENDOR_ID_AXESS,
-		.subdevice = PCI_DEVICE_ID_DM05,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
 	}, {
 		/* empty */
 	},
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 6d6121e..3750ff4 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -430,6 +430,8 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
 /* stop feed but only mark the specified filter as stopped (state set) */
 static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
 {
+	struct dmxdev_feed *feed;
+
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
 	switch (dmxdevfilter->type) {
@@ -438,7 +440,8 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
 		dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
 		break;
 	case DMXDEV_TYPE_PES:
-		dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts);
+		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next)
+			feed->ts->stop_filtering(feed->ts);
 		break;
 	default:
 		return -EINVAL;
@@ -449,13 +452,23 @@ static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter)
 /* start feed associated with the specified filter */
 static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter)
 {
+	struct dmxdev_feed *feed;
+	int ret;
+
 	dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO);
 
 	switch (filter->type) {
 	case DMXDEV_TYPE_SEC:
 		return filter->feed.sec->start_filtering(filter->feed.sec);
 	case DMXDEV_TYPE_PES:
-		return filter->feed.ts->start_filtering(filter->feed.ts);
+		list_for_each_entry(feed, &filter->feed.ts, next) {
+			ret = feed->ts->start_filtering(feed->ts);
+			if (ret < 0) {
+				dvb_dmxdev_feed_stop(filter);
+				return ret;
+			}
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -487,6 +500,9 @@ static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter)
 
 static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
 {
+	struct dmxdev_feed *feed;
+	struct dmx_demux *demux;
+
 	if (dmxdevfilter->state < DMXDEV_STATE_GO)
 		return 0;
 
@@ -503,13 +519,12 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
 		dmxdevfilter->feed.sec = NULL;
 		break;
 	case DMXDEV_TYPE_PES:
-		if (!dmxdevfilter->feed.ts)
-			break;
 		dvb_dmxdev_feed_stop(dmxdevfilter);
-		dmxdevfilter->dev->demux->
-		    release_ts_feed(dmxdevfilter->dev->demux,
-				    dmxdevfilter->feed.ts);
-		dmxdevfilter->feed.ts = NULL;
+		demux = dmxdevfilter->dev->demux;
+		list_for_each_entry(feed, &dmxdevfilter->feed.ts, next) {
+			demux->release_ts_feed(demux, feed->ts);
+			feed->ts = NULL;
+		}
 		break;
 	default:
 		if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED)
@@ -521,19 +536,88 @@ static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter)
 	return 0;
 }
 
+static void dvb_dmxdev_delete_pids(struct dmxdev_filter *dmxdevfilter)
+{
+	struct dmxdev_feed *feed, *tmp;
+
+	/* delete all PIDs */
+	list_for_each_entry_safe(feed, tmp, &dmxdevfilter->feed.ts, next) {
+		list_del(&feed->next);
+		kfree(feed);
+	}
+
+	BUG_ON(!list_empty(&dmxdevfilter->feed.ts));
+}
+
 static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter)
 {
 	if (dmxdevfilter->state < DMXDEV_STATE_SET)
 		return 0;
 
+	if (dmxdevfilter->type == DMXDEV_TYPE_PES)
+		dvb_dmxdev_delete_pids(dmxdevfilter);
+
 	dmxdevfilter->type = DMXDEV_TYPE_NONE;
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
 	return 0;
 }
 
+static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
+				 struct dmxdev_filter *filter,
+				 struct dmxdev_feed *feed)
+{
+	struct timespec timeout = { 0 };
+	struct dmx_pes_filter_params *para = &filter->params.pes;
+	dmx_output_t otype;
+	int ret;
+	int ts_type;
+	enum dmx_ts_pes ts_pes;
+	struct dmx_ts_feed *tsfeed;
+
+	feed->ts = NULL;
+	otype = para->output;
+
+	ts_pes = (enum dmx_ts_pes)para->pes_type;
+
+	if (ts_pes < DMX_PES_OTHER)
+		ts_type = TS_DECODER;
+	else
+		ts_type = 0;
+
+	if (otype == DMX_OUT_TS_TAP)
+		ts_type |= TS_PACKET;
+	else if (otype == DMX_OUT_TSDEMUX_TAP)
+		ts_type |= TS_PACKET | TS_DEMUX;
+	else if (otype == DMX_OUT_TAP)
+		ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
+
+	ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, &feed->ts,
+					      dvb_dmxdev_ts_callback);
+	if (ret < 0)
+		return ret;
+
+	tsfeed = feed->ts;
+	tsfeed->priv = filter;
+
+	ret = tsfeed->set(tsfeed, feed->pid, ts_type, ts_pes, 32768, timeout);
+	if (ret < 0) {
+		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
+		return ret;
+	}
+
+	ret = tsfeed->start_filtering(tsfeed);
+	if (ret < 0) {
+		dmxdev->demux->release_ts_feed(dmxdev->demux, tsfeed);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 {
 	struct dmxdev *dmxdev = filter->dev;
+	struct dmxdev_feed *feed;
 	void *mem;
 	int ret, i;
 
@@ -631,56 +715,14 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
 		break;
 	}
 	case DMXDEV_TYPE_PES:
-	{
-		struct timespec timeout = { 0 };
-		struct dmx_pes_filter_params *para = &filter->params.pes;
-		dmx_output_t otype;
-		int ts_type;
-		enum dmx_ts_pes ts_pes;
-		struct dmx_ts_feed **tsfeed = &filter->feed.ts;
-
-		filter->feed.ts = NULL;
-		otype = para->output;
-
-		ts_pes = (enum dmx_ts_pes)para->pes_type;
-
-		if (ts_pes < DMX_PES_OTHER)
-			ts_type = TS_DECODER;
-		else
-			ts_type = 0;
-
-		if (otype == DMX_OUT_TS_TAP)
-			ts_type |= TS_PACKET;
-		else if (otype == DMX_OUT_TSDEMUX_TAP)
-			ts_type |= TS_PACKET | TS_DEMUX;
-		else if (otype == DMX_OUT_TAP)
-			ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY;
-
-		ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux,
-						      tsfeed,
-						      dvb_dmxdev_ts_callback);
-		if (ret < 0)
-			return ret;
-
-		(*tsfeed)->priv = filter;
-
-		ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes,
-				     32768, timeout);
-		if (ret < 0) {
-			dmxdev->demux->release_ts_feed(dmxdev->demux,
-						       *tsfeed);
-			return ret;
-		}
-
-		ret = filter->feed.ts->start_filtering(filter->feed.ts);
-		if (ret < 0) {
-			dmxdev->demux->release_ts_feed(dmxdev->demux,
-						       *tsfeed);
-			return ret;
+		list_for_each_entry(feed, &filter->feed.ts, next) {
+			ret = dvb_dmxdev_start_feed(dmxdev, filter, feed);
+			if (ret < 0) {
+				dvb_dmxdev_filter_stop(filter);
+				return ret;
+			}
 		}
-
 		break;
-	}
 	default:
 		return -EINVAL;
 	}
@@ -718,7 +760,7 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
 	dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
 	dmxdevfilter->type = DMXDEV_TYPE_NONE;
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
-	dmxdevfilter->feed.ts = NULL;
+	INIT_LIST_HEAD(&dmxdevfilter->feed.ts);
 	init_timer(&dmxdevfilter->timer);
 
 	dvbdev->users++;
@@ -760,6 +802,55 @@ static inline void invert_mode(dmx_filter_t *filter)
 		filter->mode[i] ^= 0xff;
 }
 
+static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev,
+			      struct dmxdev_filter *filter, u16 pid)
+{
+	struct dmxdev_feed *feed;
+
+	if ((filter->type != DMXDEV_TYPE_PES) ||
+	    (filter->state < DMXDEV_STATE_SET))
+		return -EINVAL;
+
+	/* only TS packet filters may have multiple PIDs */
+	if ((filter->params.pes.output != DMX_OUT_TSDEMUX_TAP) &&
+	    (!list_empty(&filter->feed.ts)))
+		return -EINVAL;
+
+	feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL);
+	if (feed == NULL)
+		return -ENOMEM;
+
+	feed->pid = pid;
+	list_add(&feed->next, &filter->feed.ts);
+
+	if (filter->state >= DMXDEV_STATE_GO)
+		return dvb_dmxdev_start_feed(dmxdev, filter, feed);
+
+	return 0;
+}
+
+static int dvb_dmxdev_remove_pid(struct dmxdev *dmxdev,
+				  struct dmxdev_filter *filter, u16 pid)
+{
+	struct dmxdev_feed *feed, *tmp;
+
+	if ((filter->type != DMXDEV_TYPE_PES) ||
+	    (filter->state < DMXDEV_STATE_SET))
+		return -EINVAL;
+
+	list_for_each_entry_safe(feed, tmp, &filter->feed.ts, next) {
+		if ((feed->pid == pid) && (feed->ts != NULL)) {
+			feed->ts->stop_filtering(feed->ts);
+			filter->dev->demux->release_ts_feed(filter->dev->demux,
+							    feed->ts);
+			list_del(&feed->next);
+			kfree(feed);
+		}
+	}
+
+	return 0;
+}
+
 static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
 				 struct dmxdev_filter *dmxdevfilter,
 				 struct dmx_sct_filter_params *params)
@@ -784,7 +875,10 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
 				     struct dmxdev_filter *dmxdevfilter,
 				     struct dmx_pes_filter_params *params)
 {
+	int ret;
+
 	dvb_dmxdev_filter_stop(dmxdevfilter);
+	dvb_dmxdev_filter_reset(dmxdevfilter);
 
 	if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0)
 		return -EINVAL;
@@ -795,6 +889,11 @@ static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev,
 
 	dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET);
 
+	ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter,
+				 dmxdevfilter->params.pes.pid);
+	if (ret < 0)
+		return ret;
+
 	if (params->flags & DMX_IMMEDIATE_START)
 		return dvb_dmxdev_filter_start(dmxdevfilter);
 
@@ -958,6 +1057,24 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file,
 					     &((struct dmx_stc *)parg)->base);
 		break;
 
+	case DMX_ADD_PID:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+		ret = dvb_dmxdev_add_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
+	case DMX_REMOVE_PID:
+		if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+			ret = -ERESTARTSYS;
+			break;
+		}
+		ret = dvb_dmxdev_remove_pid(dmxdev, dmxdevfilter, *(u16 *)parg);
+		mutex_unlock(&dmxdevfilter->mutex);
+		break;
+
 	default:
 		ret = -EINVAL;
 		break;
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index 29746e7..c1379b5 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -53,13 +53,20 @@ enum dmxdev_state {
 	DMXDEV_STATE_TIMEDOUT
 };
 
+struct dmxdev_feed {
+	u16 pid;
+	struct dmx_ts_feed *ts;
+	struct list_head next;
+};
+
 struct dmxdev_filter {
 	union {
 		struct dmx_section_filter *sec;
 	} filter;
 
 	union {
-		struct dmx_ts_feed *ts;
+		/* list of TS and PES feeds (struct dmxdev_feed) */
+		struct list_head ts;
 		struct dmx_section_feed *sec;
 	} feed;
 
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index cfe2768..eef6d36 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -425,13 +425,9 @@ no_dvb_demux_tscheck:
 		if ((DVR_FEED(feed)) && (dvr_done++))
 			continue;
 
-		if (feed->pid == pid) {
+		if (feed->pid == pid)
 			dvb_dmx_swfilter_packet_type(feed, buf);
-			if (DVR_FEED(feed))
-				continue;
-		}
-
-		if (feed->pid == 0x2000)
+		else if (feed->pid == 0x2000)
 			feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK);
 	}
 }
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index f50ca72..ddf639e 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -72,6 +72,7 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
 #define FESTATE_ZIGZAG_FAST 32
 #define FESTATE_ZIGZAG_SLOW 64
 #define FESTATE_DISEQC 128
+#define FESTATE_ERROR 256
 #define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
 #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
 #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
@@ -269,6 +270,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
 {
 	int autoinversion;
 	int ready = 0;
+	int fe_set_err = 0;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	int original_inversion = fepriv->parameters.inversion;
 	u32 original_frequency = fepriv->parameters.frequency;
@@ -345,7 +347,11 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
 	if (autoinversion)
 		fepriv->parameters.inversion = fepriv->inversion;
 	if (fe->ops.set_frontend)
-		fe->ops.set_frontend(fe, &fepriv->parameters);
+		fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
+	if (fe_set_err < 0) {
+		fepriv->state = FESTATE_ERROR;
+		return fe_set_err;
+	}
 
 	fepriv->parameters.frequency = original_frequency;
 	fepriv->parameters.inversion = original_inversion;
@@ -357,6 +363,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
 static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
 {
 	fe_status_t s = 0;
+	int retval = 0;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 
 	/* if we've got no parameters, just keep idling */
@@ -370,8 +377,12 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
 	if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
 		if (fepriv->state & FESTATE_RETUNE) {
 			if (fe->ops.set_frontend)
-				fe->ops.set_frontend(fe, &fepriv->parameters);
-			fepriv->state = FESTATE_TUNED;
+				retval = fe->ops.set_frontend(fe,
+							&fepriv->parameters);
+			if (retval < 0)
+				fepriv->state = FESTATE_ERROR;
+			else
+				fepriv->state = FESTATE_TUNED;
 		}
 		fepriv->delay = 3*HZ;
 		fepriv->quality = 0;
@@ -449,7 +460,11 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
 		fepriv->delay = fepriv->min_delay;
 
 		/* peform a tune */
-		if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) {
+		retval = dvb_frontend_swzigzag_autotune(fe,
+							fepriv->check_wrapped);
+		if (retval < 0) {
+			return;
+		} else if (retval) {
 			/* OK, if we've run out of trials at the fast speed.
 			 * Drop back to slow for the _next_ attempt */
 			fepriv->state = FESTATE_SEARCHING_SLOW;
@@ -823,9 +838,61 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
 		}
 	}
 
+	/* check for supported modulation */
+	if (fe->ops.info.type == FE_QAM &&
+	    (parms->u.qam.modulation > QAM_AUTO ||
+	     !((1 << (parms->u.qam.modulation + 10)) & fe->ops.info.caps))) {
+		printk(KERN_WARNING "DVB: adapter %i frontend %i modulation %u not supported\n",
+		       fe->dvb->num, fe->id, parms->u.qam.modulation);
+			return -EINVAL;
+	}
+
 	return 0;
 }
 
+static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
+{
+	int i;
+
+	memset(&(fe->dtv_property_cache), 0,
+			sizeof(struct dtv_frontend_properties));
+
+	fe->dtv_property_cache.state = DTV_CLEAR;
+	fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
+	fe->dtv_property_cache.inversion = INVERSION_AUTO;
+	fe->dtv_property_cache.fec_inner = FEC_AUTO;
+	fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
+	fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO;
+	fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
+	fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
+	fe->dtv_property_cache.symbol_rate = QAM_AUTO;
+	fe->dtv_property_cache.code_rate_HP = FEC_AUTO;
+	fe->dtv_property_cache.code_rate_LP = FEC_AUTO;
+
+	fe->dtv_property_cache.isdbt_partial_reception = -1;
+	fe->dtv_property_cache.isdbt_sb_mode = -1;
+	fe->dtv_property_cache.isdbt_sb_subchannel = -1;
+	fe->dtv_property_cache.isdbt_sb_segment_idx = -1;
+	fe->dtv_property_cache.isdbt_sb_segment_count = -1;
+	fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
+	for (i = 0; i < 3; i++) {
+		fe->dtv_property_cache.layer[i].fec = FEC_AUTO;
+		fe->dtv_property_cache.layer[i].modulation = QAM_AUTO;
+		fe->dtv_property_cache.layer[i].interleaving = -1;
+		fe->dtv_property_cache.layer[i].segment_count = -1;
+	}
+
+	return 0;
+}
+
+#define _DTV_CMD(n, s, b) \
+[n] = { \
+	.name = #n, \
+	.cmd  = n, \
+	.set  = s,\
+	.buffer = b \
+}
+
 static struct dtv_cmds_h dtv_cmds[] = {
 	[DTV_TUNE] = {
 		.name	= "DTV_TUNE",
@@ -925,6 +992,47 @@ static struct dtv_cmds_h dtv_cmds[] = {
 		.cmd	= DTV_TRANSMISSION_MODE,
 		.set	= 1,
 	},
+
+	_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
+	_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
+	_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
+	_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
+	_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
+
+	_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0),
+	_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0),
+	_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0),
+	_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0),
+	_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0),
+	_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
+
+	_DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
+
 	/* Get */
 	[DTV_DISEQC_SLAVE_REPLY] = {
 		.name	= "DTV_DISEQC_SLAVE_REPLY",
@@ -932,6 +1040,7 @@ static struct dtv_cmds_h dtv_cmds[] = {
 		.set	= 0,
 		.buffer	= 1,
 	},
+
 	[DTV_API_VERSION] = {
 		.name	= "DTV_API_VERSION",
 		.cmd	= DTV_API_VERSION,
@@ -1141,14 +1250,21 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
 	if(c->delivery_system == SYS_ISDBT) {
 		/* Fake out a generic DVB-T request so we pass validation in the ioctl */
 		p->frequency = c->frequency;
-		p->inversion = INVERSION_AUTO;
+		p->inversion = c->inversion;
 		p->u.ofdm.constellation = QAM_AUTO;
 		p->u.ofdm.code_rate_HP = FEC_AUTO;
 		p->u.ofdm.code_rate_LP = FEC_AUTO;
-		p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
 		p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
 		p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
 		p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
+		if (c->bandwidth_hz == 8000000)
+			p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+		else if (c->bandwidth_hz == 7000000)
+			p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
+		else if (c->bandwidth_hz == 6000000)
+			p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
+		else
+			p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
 	}
 }
 
@@ -1250,6 +1366,65 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
 	case DTV_HIERARCHY:
 		tvp->u.data = fe->dtv_property_cache.hierarchy;
 		break;
+
+	/* ISDB-T Support here */
+	case DTV_ISDBT_PARTIAL_RECEPTION:
+		tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception;
+		break;
+	case DTV_ISDBT_SOUND_BROADCASTING:
+		tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode;
+		break;
+	case DTV_ISDBT_SB_SUBCHANNEL_ID:
+		tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel;
+		break;
+	case DTV_ISDBT_SB_SEGMENT_IDX:
+		tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx;
+		break;
+	case DTV_ISDBT_SB_SEGMENT_COUNT:
+		tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count;
+		break;
+	case DTV_ISDBT_LAYER_ENABLED:
+		tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled;
+		break;
+	case DTV_ISDBT_LAYERA_FEC:
+		tvp->u.data = fe->dtv_property_cache.layer[0].fec;
+		break;
+	case DTV_ISDBT_LAYERA_MODULATION:
+		tvp->u.data = fe->dtv_property_cache.layer[0].modulation;
+		break;
+	case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
+		tvp->u.data = fe->dtv_property_cache.layer[0].segment_count;
+		break;
+	case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
+		tvp->u.data = fe->dtv_property_cache.layer[0].interleaving;
+		break;
+	case DTV_ISDBT_LAYERB_FEC:
+		tvp->u.data = fe->dtv_property_cache.layer[1].fec;
+		break;
+	case DTV_ISDBT_LAYERB_MODULATION:
+		tvp->u.data = fe->dtv_property_cache.layer[1].modulation;
+		break;
+	case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
+		tvp->u.data = fe->dtv_property_cache.layer[1].segment_count;
+		break;
+	case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
+		tvp->u.data = fe->dtv_property_cache.layer[1].interleaving;
+		break;
+	case DTV_ISDBT_LAYERC_FEC:
+		tvp->u.data = fe->dtv_property_cache.layer[2].fec;
+		break;
+	case DTV_ISDBT_LAYERC_MODULATION:
+		tvp->u.data = fe->dtv_property_cache.layer[2].modulation;
+		break;
+	case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
+		tvp->u.data = fe->dtv_property_cache.layer[2].segment_count;
+		break;
+	case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
+		tvp->u.data = fe->dtv_property_cache.layer[2].interleaving;
+		break;
+	case DTV_ISDBS_TS_ID:
+		tvp->u.data = fe->dtv_property_cache.isdbs_ts_id;
+		break;
 	default:
 		r = -1;
 	}
@@ -1278,10 +1453,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
 		/* Reset a cache of data specific to the frontend here. This does
 		 * not effect hardware.
 		 */
+		dvb_frontend_clear_cache(fe);
 		dprintk("%s() Flushing property cache\n", __func__);
-		memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
-		fe->dtv_property_cache.state = tvp->cmd;
-		fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
 		break;
 	case DTV_TUNE:
 		/* interpret the cache of data, build either a traditional frontend
@@ -1347,6 +1520,65 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
 	case DTV_HIERARCHY:
 		fe->dtv_property_cache.hierarchy = tvp->u.data;
 		break;
+
+	/* ISDB-T Support here */
+	case DTV_ISDBT_PARTIAL_RECEPTION:
+		fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data;
+		break;
+	case DTV_ISDBT_SOUND_BROADCASTING:
+		fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data;
+		break;
+	case DTV_ISDBT_SB_SUBCHANNEL_ID:
+		fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data;
+		break;
+	case DTV_ISDBT_SB_SEGMENT_IDX:
+		fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data;
+		break;
+	case DTV_ISDBT_SB_SEGMENT_COUNT:
+		fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYER_ENABLED:
+		fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERA_FEC:
+		fe->dtv_property_cache.layer[0].fec = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERA_MODULATION:
+		fe->dtv_property_cache.layer[0].modulation = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
+		fe->dtv_property_cache.layer[0].segment_count = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
+		fe->dtv_property_cache.layer[0].interleaving = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERB_FEC:
+		fe->dtv_property_cache.layer[1].fec = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERB_MODULATION:
+		fe->dtv_property_cache.layer[1].modulation = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
+		fe->dtv_property_cache.layer[1].segment_count = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
+		fe->dtv_property_cache.layer[1].interleaving = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERC_FEC:
+		fe->dtv_property_cache.layer[2].fec = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERC_MODULATION:
+		fe->dtv_property_cache.layer[2].modulation = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
+		fe->dtv_property_cache.layer[2].segment_count = tvp->u.data;
+		break;
+	case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
+		fe->dtv_property_cache.layer[2].interleaving = tvp->u.data;
+		break;
+	case DTV_ISDBS_TS_ID:
+		fe->dtv_property_cache.isdbs_ts_id = tvp->u.data;
+		break;
 	default:
 		r = -1;
 	}
@@ -1499,7 +1731,8 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
 
 		/* if retune was requested but hasn't occured yet, prevent
 		 * that user get signal state from previous tuning */
-		if(fepriv->state == FESTATE_RETUNE) {
+		if (fepriv->state == FESTATE_RETUNE ||
+		    fepriv->state == FESTATE_ERROR) {
 			err=0;
 			*status = 0;
 			break;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index e176da4..810f07d 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -341,6 +341,23 @@ struct dtv_frontend_properties {
 	fe_rolloff_t		rolloff;
 
 	fe_delivery_system_t	delivery_system;
+
+	/* ISDB-T specifics */
+	u8			isdbt_partial_reception;
+	u8			isdbt_sb_mode;
+	u8			isdbt_sb_subchannel;
+	u32			isdbt_sb_segment_idx;
+	u32			isdbt_sb_segment_count;
+	u8			isdbt_layer_enabled;
+	struct {
+	    u8			segment_count;
+	    fe_code_rate_t	fec;
+	    fe_modulation_t	modulation;
+	    u8			interleaving;
+	} layer[3];
+
+	/* ISDB-T specifics */
+	u32			isdbs_ts_id;
 };
 
 struct dvb_frontend {
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 8280f8d..8c9ae0a 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -904,7 +904,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
 static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static u8 mask_normal[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 479dd05..94159b9 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -447,7 +447,7 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
 	return 0;
 }
 
-static char *dvb_nodename(struct device *dev)
+static char *dvb_devnode(struct device *dev, mode_t *mode)
 {
 	struct dvb_device *dvbdev = dev_get_drvdata(dev);
 
@@ -478,7 +478,7 @@ static int __init init_dvbdev(void)
 		goto error;
 	}
 	dvb_class->dev_uevent = dvb_uevent;
-	dvb_class->nodename = dvb_nodename;
+	dvb_class->devnode = dvb_devnode;
 	return 0;
 
 error:
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 487919b..895e2ef 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -30,7 +30,12 @@
 
 #define DVB_MAJOR 212
 
+#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
+#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
+#else
+#warning invalid CONFIG_DVB_MAX_ADAPTERS value
 #define DVB_MAX_ADAPTERS 8
+#endif
 
 #define DVB_UNSET (-1)
 
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 496c1a3..0e4b97f 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -71,6 +71,7 @@ config DVB_USB_DIB0700
 	depends on DVB_USB
 	select DVB_DIB7000P if !DVB_FE_CUSTOMISE
 	select DVB_DIB7000M if !DVB_FE_CUSTOMISE
+	select DVB_DIB8000 if !DVB_FE_CUSTOMISE
 	select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
 	select DVB_S5H1411 if !DVB_FE_CUSTOMISE
 	select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
@@ -87,7 +88,7 @@ config DVB_USB_DIB0700
 	  Avermedia and other big and small companies.
 
 	  For an up-to-date list of devices supported by this driver, have a look
-	  on the Linux-DVB Wiki at www.linuxtv.org.
+	  on the LinuxTV Wiki at www.linuxtv.org.
 
 	  Say Y if you own such a device and want to use it. You should build it as
 	  a module.
@@ -253,7 +254,7 @@ config DVB_USB_AF9005_REMOTE
 	  Afatech AF9005 based receiver.
 
 config DVB_USB_DW2102
-	tristate "DvbWorld DVB-S/S2 USB2.0 support"
+	tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
 	depends on DVB_USB
 	select DVB_PLL if !DVB_FE_CUSTOMISE
 	select DVB_STV0299 if !DVB_FE_CUSTOMISE
@@ -262,9 +263,11 @@ config DVB_USB_DW2102
 	select DVB_CX24116 if !DVB_FE_CUSTOMISE
 	select DVB_SI21XX if !DVB_FE_CUSTOMISE
 	select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+	select DVB_MT312 if !DVB_FE_CUSTOMISE
+	select DVB_ZL10039 if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers
-	  and the TeVii S650.
+	  and the TeVii S650, S630.
 
 config DVB_USB_CINERGY_T2
 	tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
@@ -313,3 +316,9 @@ config DVB_USB_CE6230
 	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
 	help
 	  Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
+
+config DVB_USB_FRIIO
+	tristate "Friio ISDB-T USB2.0 Receiver support"
+	depends on DVB_USB
+	help
+	  Say Y here to support the Japanese DTV receiver Friio.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index f92734e..85b83a4 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -79,6 +79,9 @@ obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
 dvb-usb-ce6230-objs = ce6230.o
 obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
 
+dvb-usb-friio-objs = friio.o friio-fe.o
+obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
 # due to tuner-xc3028
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index dc8c878..6247239 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -38,41 +38,41 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
 }
 
 static struct dvb_usb_rc_key a800_rc_keys[] = {
-	{ 0x02, 0x01, KEY_PROG1 },       /* SOURCE */
-	{ 0x02, 0x00, KEY_POWER },       /* POWER */
-	{ 0x02, 0x05, KEY_1 },           /* 1 */
-	{ 0x02, 0x06, KEY_2 },           /* 2 */
-	{ 0x02, 0x07, KEY_3 },           /* 3 */
-	{ 0x02, 0x09, KEY_4 },           /* 4 */
-	{ 0x02, 0x0a, KEY_5 },           /* 5 */
-	{ 0x02, 0x0b, KEY_6 },           /* 6 */
-	{ 0x02, 0x0d, KEY_7 },           /* 7 */
-	{ 0x02, 0x0e, KEY_8 },           /* 8 */
-	{ 0x02, 0x0f, KEY_9 },           /* 9 */
-	{ 0x02, 0x12, KEY_LEFT },        /* L / DISPLAY */
-	{ 0x02, 0x11, KEY_0 },           /* 0 */
-	{ 0x02, 0x13, KEY_RIGHT },       /* R / CH RTN */
-	{ 0x02, 0x17, KEY_PROG2 },       /* SNAP SHOT */
-	{ 0x02, 0x10, KEY_PROG3 },       /* 16-CH PREV */
-	{ 0x02, 0x1e, KEY_VOLUMEDOWN },  /* VOL DOWN */
-	{ 0x02, 0x0c, KEY_ZOOM },        /* FULL SCREEN */
-	{ 0x02, 0x1f, KEY_VOLUMEUP },    /* VOL UP */
-	{ 0x02, 0x14, KEY_MUTE },        /* MUTE */
-	{ 0x02, 0x08, KEY_AUDIO },       /* AUDIO */
-	{ 0x02, 0x19, KEY_RECORD },      /* RECORD */
-	{ 0x02, 0x18, KEY_PLAY },        /* PLAY */
-	{ 0x02, 0x1b, KEY_STOP },        /* STOP */
-	{ 0x02, 0x1a, KEY_PLAYPAUSE },   /* TIMESHIFT / PAUSE */
-	{ 0x02, 0x1d, KEY_BACK },        /* << / RED */
-	{ 0x02, 0x1c, KEY_FORWARD },     /* >> / YELLOW */
-	{ 0x02, 0x03, KEY_TEXT },        /* TELETEXT */
-	{ 0x02, 0x04, KEY_EPG },         /* EPG */
-	{ 0x02, 0x15, KEY_MENU },        /* MENU */
-
-	{ 0x03, 0x03, KEY_CHANNELUP },   /* CH UP */
-	{ 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
-	{ 0x03, 0x01, KEY_FIRST },       /* |<< / GREEN */
-	{ 0x03, 0x00, KEY_LAST },        /* >>| / BLUE */
+	{ 0x0201, KEY_PROG1 },       /* SOURCE */
+	{ 0x0200, KEY_POWER },       /* POWER */
+	{ 0x0205, KEY_1 },           /* 1 */
+	{ 0x0206, KEY_2 },           /* 2 */
+	{ 0x0207, KEY_3 },           /* 3 */
+	{ 0x0209, KEY_4 },           /* 4 */
+	{ 0x020a, KEY_5 },           /* 5 */
+	{ 0x020b, KEY_6 },           /* 6 */
+	{ 0x020d, KEY_7 },           /* 7 */
+	{ 0x020e, KEY_8 },           /* 8 */
+	{ 0x020f, KEY_9 },           /* 9 */
+	{ 0x0212, KEY_LEFT },        /* L / DISPLAY */
+	{ 0x0211, KEY_0 },           /* 0 */
+	{ 0x0213, KEY_RIGHT },       /* R / CH RTN */
+	{ 0x0217, KEY_PROG2 },       /* SNAP SHOT */
+	{ 0x0210, KEY_PROG3 },       /* 16-CH PREV */
+	{ 0x021e, KEY_VOLUMEDOWN },  /* VOL DOWN */
+	{ 0x020c, KEY_ZOOM },        /* FULL SCREEN */
+	{ 0x021f, KEY_VOLUMEUP },    /* VOL UP */
+	{ 0x0214, KEY_MUTE },        /* MUTE */
+	{ 0x0208, KEY_AUDIO },       /* AUDIO */
+	{ 0x0219, KEY_RECORD },      /* RECORD */
+	{ 0x0218, KEY_PLAY },        /* PLAY */
+	{ 0x021b, KEY_STOP },        /* STOP */
+	{ 0x021a, KEY_PLAYPAUSE },   /* TIMESHIFT / PAUSE */
+	{ 0x021d, KEY_BACK },        /* << / RED */
+	{ 0x021c, KEY_FORWARD },     /* >> / YELLOW */
+	{ 0x0203, KEY_TEXT },        /* TELETEXT */
+	{ 0x0204, KEY_EPG },         /* EPG */
+	{ 0x0215, KEY_MENU },        /* MENU */
+
+	{ 0x0303, KEY_CHANNELUP },   /* CH UP */
+	{ 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
+	{ 0x0301, KEY_FIRST },       /* |<< / GREEN */
+	{ 0x0300, KEY_LAST },        /* >>| / BLUE */
 
 };
 
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
index 7c596f9..f4379c6 100644
--- a/drivers/media/dvb/dvb-usb/af9005-remote.c
+++ b/drivers/media/dvb/dvb-usb/af9005-remote.c
@@ -35,43 +35,43 @@ MODULE_PARM_DESC(debug,
 
 struct dvb_usb_rc_key af9005_rc_keys[] = {
 
-	{0x01, 0xb7, KEY_POWER},
-	{0x01, 0xa7, KEY_VOLUMEUP},
-	{0x01, 0x87, KEY_CHANNELUP},
-	{0x01, 0x7f, KEY_MUTE},
-	{0x01, 0xbf, KEY_VOLUMEDOWN},
-	{0x01, 0x3f, KEY_CHANNELDOWN},
-	{0x01, 0xdf, KEY_1},
-	{0x01, 0x5f, KEY_2},
-	{0x01, 0x9f, KEY_3},
-	{0x01, 0x1f, KEY_4},
-	{0x01, 0xef, KEY_5},
-	{0x01, 0x6f, KEY_6},
-	{0x01, 0xaf, KEY_7},
-	{0x01, 0x27, KEY_8},
-	{0x01, 0x07, KEY_9},
-	{0x01, 0xcf, KEY_ZOOM},
-	{0x01, 0x4f, KEY_0},
-	{0x01, 0x8f, KEY_GOTO},	/* marked jump on the remote */
+	{0x01b7, KEY_POWER},
+	{0x01a7, KEY_VOLUMEUP},
+	{0x0187, KEY_CHANNELUP},
+	{0x017f, KEY_MUTE},
+	{0x01bf, KEY_VOLUMEDOWN},
+	{0x013f, KEY_CHANNELDOWN},
+	{0x01df, KEY_1},
+	{0x015f, KEY_2},
+	{0x019f, KEY_3},
+	{0x011f, KEY_4},
+	{0x01ef, KEY_5},
+	{0x016f, KEY_6},
+	{0x01af, KEY_7},
+	{0x0127, KEY_8},
+	{0x0107, KEY_9},
+	{0x01cf, KEY_ZOOM},
+	{0x014f, KEY_0},
+	{0x018f, KEY_GOTO},	/* marked jump on the remote */
 
-	{0x00, 0xbd, KEY_POWER},
-	{0x00, 0x7d, KEY_VOLUMEUP},
-	{0x00, 0xfd, KEY_CHANNELUP},
-	{0x00, 0x9d, KEY_MUTE},
-	{0x00, 0x5d, KEY_VOLUMEDOWN},
-	{0x00, 0xdd, KEY_CHANNELDOWN},
-	{0x00, 0xad, KEY_1},
-	{0x00, 0x6d, KEY_2},
-	{0x00, 0xed, KEY_3},
-	{0x00, 0x8d, KEY_4},
-	{0x00, 0x4d, KEY_5},
-	{0x00, 0xcd, KEY_6},
-	{0x00, 0xb5, KEY_7},
-	{0x00, 0x75, KEY_8},
-	{0x00, 0xf5, KEY_9},
-	{0x00, 0x95, KEY_ZOOM},
-	{0x00, 0x55, KEY_0},
-	{0x00, 0xd5, KEY_GOTO},	/* marked jump on the remote */
+	{0x00bd, KEY_POWER},
+	{0x007d, KEY_VOLUMEUP},
+	{0x00fd, KEY_CHANNELUP},
+	{0x009d, KEY_MUTE},
+	{0x005d, KEY_VOLUMEDOWN},
+	{0x00dd, KEY_CHANNELDOWN},
+	{0x00ad, KEY_1},
+	{0x006d, KEY_2},
+	{0x00ed, KEY_3},
+	{0x008d, KEY_4},
+	{0x004d, KEY_5},
+	{0x00cd, KEY_6},
+	{0x00b5, KEY_7},
+	{0x0075, KEY_8},
+	{0x00f5, KEY_9},
+	{0x0095, KEY_ZOOM},
+	{0x0055, KEY_0},
+	{0x00d5, KEY_GOTO},	/* marked jump on the remote */
 };
 
 int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys);
@@ -131,8 +131,8 @@ int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
 				return 0;
 			}
 			for (i = 0; i < af9005_rc_keys_size; i++) {
-				if (af9005_rc_keys[i].custom == cust
-				    && af9005_rc_keys[i].data == dat) {
+				if (rc5_custom(&af9005_rc_keys[i]) == cust
+				    && rc5_data(&af9005_rc_keys[i]) == dat) {
 					*event = af9005_rc_keys[i].event;
 					*state = REMOTE_KEY_PRESSED;
 					deb_decode
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 26690df..cf042b3 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -61,10 +61,13 @@ static struct af9013_config af9015_af9013_config[] = {
 
 static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
 {
+#define BUF_LEN 63
+#define REQ_HDR_LEN 8 /* send header size */
+#define ACK_HDR_LEN 2 /* rece header size */
 	int act_len, ret;
-	u8 buf[64];
+	u8 buf[BUF_LEN];
 	u8 write = 1;
-	u8 msg_len = 8;
+	u8 msg_len = REQ_HDR_LEN;
 	static u8 seq; /* packet sequence number */
 
 	if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
@@ -94,7 +97,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
 		break;
 	case WRITE_MEMORY:
 		if (((req->addr & 0xff00) == 0xff00) ||
-		    ((req->addr & 0xae00) == 0xae00))
+		    ((req->addr & 0xff00) == 0xae00))
 			buf[0] = WRITE_VIRTUAL_MEMORY;
 	case WRITE_VIRTUAL_MEMORY:
 	case COPY_FIRMWARE:
@@ -107,17 +110,26 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
 		goto error_unlock;
 	}
 
+	/* buffer overflow check */
+	if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
+		(!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
+		err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
+		ret = -EINVAL;
+		goto error_unlock;
+	}
+
 	/* write requested */
 	if (write) {
-		memcpy(&buf[8], req->data, req->data_len);
+		memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
 		msg_len += req->data_len;
 	}
+
 	deb_xfer(">>> ");
 	debug_dump(buf, msg_len, deb_xfer);
 
 	/* send req */
 	ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
-	&act_len, AF9015_USB_TIMEOUT);
+		&act_len, AF9015_USB_TIMEOUT);
 	if (ret)
 		err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
 	else
@@ -130,10 +142,14 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
 	if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
 		goto exit_unlock;
 
-	/* receive ack and data if read req */
-	msg_len = 1 + 1 + req->data_len;  /* seq + status + data len */
+	/* write receives seq + status = 2 bytes
+	   read receives seq + status + data = 2 + N bytes */
+	msg_len = ACK_HDR_LEN;
+	if (!write)
+		msg_len += req->data_len;
+
 	ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
-			   &act_len, AF9015_USB_TIMEOUT);
+		&act_len, AF9015_USB_TIMEOUT);
 	if (ret) {
 		err("recv bulk message failed:%d", ret);
 		ret = -1;
@@ -159,7 +175,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
 
 	/* read request, copy returned data to return buf */
 	if (!write)
-		memcpy(req->data, &buf[2], req->data_len);
+		memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
 
 error_unlock:
 exit_unlock:
@@ -369,12 +385,14 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
 	u8  packet_size;
 	deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
 
+	/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
+	   We use smaller - about 1/4 from the original, 5 and 87. */
 #define TS_PACKET_SIZE            188
 
-#define TS_USB20_PACKET_COUNT     348
+#define TS_USB20_PACKET_COUNT      87
 #define TS_USB20_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
 
-#define TS_USB11_PACKET_COUNT      21
+#define TS_USB11_PACKET_COUNT       5
 #define TS_USB11_FRAME_SIZE       (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
 
 #define TS_USB20_MAX_PACKET_SIZE  512
@@ -538,24 +556,22 @@ exit:
 /* dump eeprom */
 static int af9015_eeprom_dump(struct dvb_usb_device *d)
 {
-	char buf[4+3*16+1], buf2[4];
 	u8 reg, val;
 
 	for (reg = 0; ; reg++) {
 		if (reg % 16 == 0) {
 			if (reg)
-				deb_info("%s\n", buf);
-			sprintf(buf, "%02x: ", reg);
+				deb_info(KERN_CONT "\n");
+			deb_info(KERN_DEBUG "%02x:", reg);
 		}
 		if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0)
-			sprintf(buf2, "%02x ", val);
+			deb_info(KERN_CONT " %02x", val);
 		else
-			strcpy(buf2, "-- ");
-		strcat(buf, buf2);
+			deb_info(KERN_CONT " --");
 		if (reg == 0xff)
 			break;
 	}
-	deb_info("%s\n", buf);
+	deb_info(KERN_CONT "\n");
 	return 0;
 }
 
@@ -870,13 +886,13 @@ static int af9015_read_config(struct usb_device *udev)
 		/* USB1.1 set smaller buffersize and disable 2nd adapter */
 		if (udev->speed == USB_SPEED_FULL) {
 			af9015_properties[i].adapter[0].stream.u.bulk.buffersize
-				= TS_USB11_MAX_PACKET_SIZE;
+				= TS_USB11_FRAME_SIZE;
 			/* disable 2nd adapter because we don't have
 			   PID-filters */
 			af9015_config.dual_mode = 0;
 		} else {
 			af9015_properties[i].adapter[0].stream.u.bulk.buffersize
-				= TS_USB20_MAX_PACKET_SIZE;
+				= TS_USB20_FRAME_SIZE;
 		}
 	}
 
@@ -1045,8 +1061,8 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	*state = REMOTE_NO_KEY_PRESSED;
 
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (!buf[1] && keymap[i].custom == buf[0] &&
-		    keymap[i].data == buf[2]) {
+		if (!buf[1] && rc5_custom(&keymap[i]) == buf[0] &&
+		    rc5_data(&keymap[i]) == buf[2]) {
 			*event = keymap[i].event;
 			*state = REMOTE_KEY_PRESSED;
 			break;
@@ -1266,6 +1282,7 @@ static struct usb_device_id af9015_usb_table[] = {
 	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_CONCEPTRONIC_CTVDIGRCU)},
 	{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_MC810)},
 	{USB_DEVICE(USB_VID_KYE,       USB_PID_GENIUS_TVGO_DVB_T03)},
+/* 25 */{USB_DEVICE(USB_VID_KWORLD_2,  USB_PID_KWORLD_399U_2)},
 	{0},
 };
 MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1311,7 +1328,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 					.u = {
 						.bulk = {
 							.buffersize =
-						TS_USB20_MAX_PACKET_SIZE,
+						TS_USB20_FRAME_SIZE,
 						}
 					}
 				},
@@ -1346,7 +1363,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 			{
 				.name = "KWorld PlusTV Dual DVB-T Stick " \
 					"(DVB-T 399U)",
-				.cold_ids = {&af9015_usb_table[4], NULL},
+				.cold_ids = {&af9015_usb_table[4],
+					     &af9015_usb_table[25], NULL},
 				.warm_ids = {NULL},
 			},
 			{
@@ -1416,7 +1434,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 					.u = {
 						.bulk = {
 							.buffersize =
-						TS_USB20_MAX_PACKET_SIZE,
+						TS_USB20_FRAME_SIZE,
 						}
 					}
 				},
@@ -1522,7 +1540,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
 					.u = {
 						.bulk = {
 							.buffersize =
-						TS_USB20_MAX_PACKET_SIZE,
+						TS_USB20_FRAME_SIZE,
 						}
 					}
 				},
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 8d81a17..c41f30e 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -121,21 +121,21 @@ enum af9015_remote {
 
 /* Leadtek WinFast DTV Dongle Gold */
 static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = {
-	{ 0x00, 0x1e, KEY_1 },
-	{ 0x00, 0x1f, KEY_2 },
-	{ 0x00, 0x20, KEY_3 },
-	{ 0x00, 0x21, KEY_4 },
-	{ 0x00, 0x22, KEY_5 },
-	{ 0x00, 0x23, KEY_6 },
-	{ 0x00, 0x24, KEY_7 },
-	{ 0x00, 0x25, KEY_8 },
-	{ 0x00, 0x26, KEY_9 },
-	{ 0x00, 0x27, KEY_0 },
-	{ 0x00, 0x28, KEY_ENTER },
-	{ 0x00, 0x4f, KEY_VOLUMEUP },
-	{ 0x00, 0x50, KEY_VOLUMEDOWN },
-	{ 0x00, 0x51, KEY_CHANNELDOWN },
-	{ 0x00, 0x52, KEY_CHANNELUP },
+	{ 0x001e, KEY_1 },
+	{ 0x001f, KEY_2 },
+	{ 0x0020, KEY_3 },
+	{ 0x0021, KEY_4 },
+	{ 0x0022, KEY_5 },
+	{ 0x0023, KEY_6 },
+	{ 0x0024, KEY_7 },
+	{ 0x0025, KEY_8 },
+	{ 0x0026, KEY_9 },
+	{ 0x0027, KEY_0 },
+	{ 0x0028, KEY_ENTER },
+	{ 0x004f, KEY_VOLUMEUP },
+	{ 0x0050, KEY_VOLUMEDOWN },
+	{ 0x0051, KEY_CHANNELDOWN },
+	{ 0x0052, KEY_CHANNELUP },
 };
 
 static u8 af9015_ir_table_leadtek[] = {
@@ -193,60 +193,60 @@ static u8 af9015_ir_table_leadtek[] = {
 
 /* TwinHan AzureWave AD-TU700(704J) */
 static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = {
-	{ 0x05, 0x3f, KEY_POWER },
-	{ 0x00, 0x19, KEY_FAVORITES },    /* Favorite List */
-	{ 0x00, 0x04, KEY_TEXT },         /* Teletext */
-	{ 0x00, 0x0e, KEY_POWER },
-	{ 0x00, 0x0e, KEY_INFO },         /* Preview */
-	{ 0x00, 0x08, KEY_EPG },          /* Info/EPG */
-	{ 0x00, 0x0f, KEY_LIST },         /* Record List */
-	{ 0x00, 0x1e, KEY_1 },
-	{ 0x00, 0x1f, KEY_2 },
-	{ 0x00, 0x20, KEY_3 },
-	{ 0x00, 0x21, KEY_4 },
-	{ 0x00, 0x22, KEY_5 },
-	{ 0x00, 0x23, KEY_6 },
-	{ 0x00, 0x24, KEY_7 },
-	{ 0x00, 0x25, KEY_8 },
-	{ 0x00, 0x26, KEY_9 },
-	{ 0x00, 0x27, KEY_0 },
-	{ 0x00, 0x29, KEY_CANCEL },       /* Cancel */
-	{ 0x00, 0x4c, KEY_CLEAR },        /* Clear */
-	{ 0x00, 0x2a, KEY_BACK },         /* Back */
-	{ 0x00, 0x2b, KEY_TAB },          /* Tab */
-	{ 0x00, 0x52, KEY_UP },           /* up arrow */
-	{ 0x00, 0x51, KEY_DOWN },         /* down arrow */
-	{ 0x00, 0x4f, KEY_RIGHT },        /* right arrow */
-	{ 0x00, 0x50, KEY_LEFT },         /* left arrow */
-	{ 0x00, 0x28, KEY_ENTER },        /* Enter / ok */
-	{ 0x02, 0x52, KEY_VOLUMEUP },
-	{ 0x02, 0x51, KEY_VOLUMEDOWN },
-	{ 0x00, 0x4e, KEY_CHANNELDOWN },
-	{ 0x00, 0x4b, KEY_CHANNELUP },
-	{ 0x00, 0x4a, KEY_RECORD },
-	{ 0x01, 0x11, KEY_PLAY },
-	{ 0x00, 0x17, KEY_PAUSE },
-	{ 0x00, 0x0c, KEY_REWIND },       /* FR << */
-	{ 0x00, 0x11, KEY_FASTFORWARD },  /* FF >> */
-	{ 0x01, 0x15, KEY_PREVIOUS },     /* Replay */
-	{ 0x01, 0x0e, KEY_NEXT },         /* Skip */
-	{ 0x00, 0x13, KEY_CAMERA },       /* Capture */
-	{ 0x01, 0x0f, KEY_LANGUAGE },     /* SAP */
-	{ 0x01, 0x13, KEY_TV2 },          /* PIP */
-	{ 0x00, 0x1d, KEY_ZOOM },         /* Full Screen */
-	{ 0x01, 0x17, KEY_SUBTITLE },     /* Subtitle / CC */
-	{ 0x00, 0x10, KEY_MUTE },
-	{ 0x01, 0x19, KEY_AUDIO },        /* L/R */ /* TODO better event */
-	{ 0x01, 0x16, KEY_SLEEP },        /* Hibernate */
-	{ 0x01, 0x16, KEY_SWITCHVIDEOMODE },
+	{ 0x053f, KEY_POWER },
+	{ 0x0019, KEY_FAVORITES },    /* Favorite List */
+	{ 0x0004, KEY_TEXT },         /* Teletext */
+	{ 0x000e, KEY_POWER },
+	{ 0x000e, KEY_INFO },         /* Preview */
+	{ 0x0008, KEY_EPG },          /* Info/EPG */
+	{ 0x000f, KEY_LIST },         /* Record List */
+	{ 0x001e, KEY_1 },
+	{ 0x001f, KEY_2 },
+	{ 0x0020, KEY_3 },
+	{ 0x0021, KEY_4 },
+	{ 0x0022, KEY_5 },
+	{ 0x0023, KEY_6 },
+	{ 0x0024, KEY_7 },
+	{ 0x0025, KEY_8 },
+	{ 0x0026, KEY_9 },
+	{ 0x0027, KEY_0 },
+	{ 0x0029, KEY_CANCEL },       /* Cancel */
+	{ 0x004c, KEY_CLEAR },        /* Clear */
+	{ 0x002a, KEY_BACK },         /* Back */
+	{ 0x002b, KEY_TAB },          /* Tab */
+	{ 0x0052, KEY_UP },           /* up arrow */
+	{ 0x0051, KEY_DOWN },         /* down arrow */
+	{ 0x004f, KEY_RIGHT },        /* right arrow */
+	{ 0x0050, KEY_LEFT },         /* left arrow */
+	{ 0x0028, KEY_ENTER },        /* Enter / ok */
+	{ 0x0252, KEY_VOLUMEUP },
+	{ 0x0251, KEY_VOLUMEDOWN },
+	{ 0x004e, KEY_CHANNELDOWN },
+	{ 0x004b, KEY_CHANNELUP },
+	{ 0x004a, KEY_RECORD },
+	{ 0x0111, KEY_PLAY },
+	{ 0x0017, KEY_PAUSE },
+	{ 0x000c, KEY_REWIND },       /* FR << */
+	{ 0x0011, KEY_FASTFORWARD },  /* FF >> */
+	{ 0x0115, KEY_PREVIOUS },     /* Replay */
+	{ 0x010e, KEY_NEXT },         /* Skip */
+	{ 0x0013, KEY_CAMERA },       /* Capture */
+	{ 0x010f, KEY_LANGUAGE },     /* SAP */
+	{ 0x0113, KEY_TV2 },          /* PIP */
+	{ 0x001d, KEY_ZOOM },         /* Full Screen */
+	{ 0x0117, KEY_SUBTITLE },     /* Subtitle / CC */
+	{ 0x0010, KEY_MUTE },
+	{ 0x0119, KEY_AUDIO },        /* L/R */ /* TODO better event */
+	{ 0x0116, KEY_SLEEP },        /* Hibernate */
+	{ 0x0116, KEY_SWITCHVIDEOMODE },
 					  /* A/V */ /* TODO does not work */
-	{ 0x00, 0x06, KEY_AGAIN },        /* Recall */
-	{ 0x01, 0x16, KEY_KPPLUS },       /* Zoom+ */ /* TODO does not work */
-	{ 0x01, 0x16, KEY_KPMINUS },      /* Zoom- */ /* TODO does not work */
-	{ 0x02, 0x15, KEY_RED },
-	{ 0x02, 0x0a, KEY_GREEN },
-	{ 0x02, 0x1c, KEY_YELLOW },
-	{ 0x02, 0x05, KEY_BLUE },
+	{ 0x0006, KEY_AGAIN },        /* Recall */
+	{ 0x0116, KEY_KPPLUS },       /* Zoom+ */ /* TODO does not work */
+	{ 0x0116, KEY_KPMINUS },      /* Zoom- */ /* TODO does not work */
+	{ 0x0215, KEY_RED },
+	{ 0x020a, KEY_GREEN },
+	{ 0x021c, KEY_YELLOW },
+	{ 0x0205, KEY_BLUE },
 };
 
 static u8 af9015_ir_table_twinhan[] = {
@@ -304,24 +304,24 @@ static u8 af9015_ir_table_twinhan[] = {
 
 /* A-Link DTU(m) */
 static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = {
-	{ 0x00, 0x1e, KEY_1 },
-	{ 0x00, 0x1f, KEY_2 },
-	{ 0x00, 0x20, KEY_3 },
-	{ 0x00, 0x21, KEY_4 },
-	{ 0x00, 0x22, KEY_5 },
-	{ 0x00, 0x23, KEY_6 },
-	{ 0x00, 0x24, KEY_7 },
-	{ 0x00, 0x25, KEY_8 },
-	{ 0x00, 0x26, KEY_9 },
-	{ 0x00, 0x27, KEY_0 },
-	{ 0x00, 0x2e, KEY_CHANNELUP },
-	{ 0x00, 0x2d, KEY_CHANNELDOWN },
-	{ 0x04, 0x28, KEY_ZOOM },
-	{ 0x00, 0x41, KEY_MUTE },
-	{ 0x00, 0x42, KEY_VOLUMEDOWN },
-	{ 0x00, 0x43, KEY_VOLUMEUP },
-	{ 0x00, 0x44, KEY_GOTO },         /* jump */
-	{ 0x05, 0x45, KEY_POWER },
+	{ 0x001e, KEY_1 },
+	{ 0x001f, KEY_2 },
+	{ 0x0020, KEY_3 },
+	{ 0x0021, KEY_4 },
+	{ 0x0022, KEY_5 },
+	{ 0x0023, KEY_6 },
+	{ 0x0024, KEY_7 },
+	{ 0x0025, KEY_8 },
+	{ 0x0026, KEY_9 },
+	{ 0x0027, KEY_0 },
+	{ 0x002e, KEY_CHANNELUP },
+	{ 0x002d, KEY_CHANNELDOWN },
+	{ 0x0428, KEY_ZOOM },
+	{ 0x0041, KEY_MUTE },
+	{ 0x0042, KEY_VOLUMEDOWN },
+	{ 0x0043, KEY_VOLUMEUP },
+	{ 0x0044, KEY_GOTO },         /* jump */
+	{ 0x0545, KEY_POWER },
 };
 
 static u8 af9015_ir_table_a_link[] = {
@@ -347,24 +347,24 @@ static u8 af9015_ir_table_a_link[] = {
 
 /* MSI DIGIVOX mini II V3.0 */
 static struct dvb_usb_rc_key af9015_rc_keys_msi[] = {
-	{ 0x00, 0x1e, KEY_1 },
-	{ 0x00, 0x1f, KEY_2 },
-	{ 0x00, 0x20, KEY_3 },
-	{ 0x00, 0x21, KEY_4 },
-	{ 0x00, 0x22, KEY_5 },
-	{ 0x00, 0x23, KEY_6 },
-	{ 0x00, 0x24, KEY_7 },
-	{ 0x00, 0x25, KEY_8 },
-	{ 0x00, 0x26, KEY_9 },
-	{ 0x00, 0x27, KEY_0 },
-	{ 0x03, 0x0f, KEY_CHANNELUP },
-	{ 0x03, 0x0e, KEY_CHANNELDOWN },
-	{ 0x00, 0x42, KEY_VOLUMEDOWN },
-	{ 0x00, 0x43, KEY_VOLUMEUP },
-	{ 0x05, 0x45, KEY_POWER },
-	{ 0x00, 0x52, KEY_UP },           /* up */
-	{ 0x00, 0x51, KEY_DOWN },         /* down */
-	{ 0x00, 0x28, KEY_ENTER },
+	{ 0x001e, KEY_1 },
+	{ 0x001f, KEY_2 },
+	{ 0x0020, KEY_3 },
+	{ 0x0021, KEY_4 },
+	{ 0x0022, KEY_5 },
+	{ 0x0023, KEY_6 },
+	{ 0x0024, KEY_7 },
+	{ 0x0025, KEY_8 },
+	{ 0x0026, KEY_9 },
+	{ 0x0027, KEY_0 },
+	{ 0x030f, KEY_CHANNELUP },
+	{ 0x030e, KEY_CHANNELDOWN },
+	{ 0x0042, KEY_VOLUMEDOWN },
+	{ 0x0043, KEY_VOLUMEUP },
+	{ 0x0545, KEY_POWER },
+	{ 0x0052, KEY_UP },           /* up */
+	{ 0x0051, KEY_DOWN },         /* down */
+	{ 0x0028, KEY_ENTER },
 };
 
 static u8 af9015_ir_table_msi[] = {
@@ -390,42 +390,42 @@ static u8 af9015_ir_table_msi[] = {
 
 /* MYGICTV U718 */
 static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = {
-	{ 0x00, 0x3d, KEY_SWITCHVIDEOMODE },
+	{ 0x003d, KEY_SWITCHVIDEOMODE },
 					  /* TV / AV */
-	{ 0x05, 0x45, KEY_POWER },
-	{ 0x00, 0x1e, KEY_1 },
-	{ 0x00, 0x1f, KEY_2 },
-	{ 0x00, 0x20, KEY_3 },
-	{ 0x00, 0x21, KEY_4 },
-	{ 0x00, 0x22, KEY_5 },
-	{ 0x00, 0x23, KEY_6 },
-	{ 0x00, 0x24, KEY_7 },
-	{ 0x00, 0x25, KEY_8 },
-	{ 0x00, 0x26, KEY_9 },
-	{ 0x00, 0x27, KEY_0 },
-	{ 0x00, 0x41, KEY_MUTE },
-	{ 0x00, 0x2a, KEY_ESC },          /* Esc */
-	{ 0x00, 0x2e, KEY_CHANNELUP },
-	{ 0x00, 0x2d, KEY_CHANNELDOWN },
-	{ 0x00, 0x42, KEY_VOLUMEDOWN },
-	{ 0x00, 0x43, KEY_VOLUMEUP },
-	{ 0x00, 0x52, KEY_UP },           /* up arrow */
-	{ 0x00, 0x51, KEY_DOWN },         /* down arrow */
-	{ 0x00, 0x4f, KEY_RIGHT },        /* right arrow */
-	{ 0x00, 0x50, KEY_LEFT },         /* left arrow */
-	{ 0x00, 0x28, KEY_ENTER },        /* ok */
-	{ 0x01, 0x15, KEY_RECORD },
-	{ 0x03, 0x13, KEY_PLAY },
-	{ 0x01, 0x13, KEY_PAUSE },
-	{ 0x01, 0x16, KEY_STOP },
-	{ 0x03, 0x07, KEY_REWIND },       /* FR << */
-	{ 0x03, 0x09, KEY_FASTFORWARD },  /* FF >> */
-	{ 0x00, 0x3b, KEY_TIME },         /* TimeShift */
-	{ 0x00, 0x3e, KEY_CAMERA },       /* Snapshot */
-	{ 0x03, 0x16, KEY_CYCLEWINDOWS }, /* yellow, min / max */
-	{ 0x00, 0x00, KEY_ZOOM },         /* 'select' (?) */
-	{ 0x03, 0x16, KEY_SHUFFLE },      /* Shuffle */
-	{ 0x03, 0x45, KEY_POWER },
+	{ 0x0545, KEY_POWER },
+	{ 0x001e, KEY_1 },
+	{ 0x001f, KEY_2 },
+	{ 0x0020, KEY_3 },
+	{ 0x0021, KEY_4 },
+	{ 0x0022, KEY_5 },
+	{ 0x0023, KEY_6 },
+	{ 0x0024, KEY_7 },
+	{ 0x0025, KEY_8 },
+	{ 0x0026, KEY_9 },
+	{ 0x0027, KEY_0 },
+	{ 0x0041, KEY_MUTE },
+	{ 0x002a, KEY_ESC },          /* Esc */
+	{ 0x002e, KEY_CHANNELUP },
+	{ 0x002d, KEY_CHANNELDOWN },
+	{ 0x0042, KEY_VOLUMEDOWN },
+	{ 0x0043, KEY_VOLUMEUP },
+	{ 0x0052, KEY_UP },           /* up arrow */
+	{ 0x0051, KEY_DOWN },         /* down arrow */
+	{ 0x004f, KEY_RIGHT },        /* right arrow */
+	{ 0x0050, KEY_LEFT },         /* left arrow */
+	{ 0x0028, KEY_ENTER },        /* ok */
+	{ 0x0115, KEY_RECORD },
+	{ 0x0313, KEY_PLAY },
+	{ 0x0113, KEY_PAUSE },
+	{ 0x0116, KEY_STOP },
+	{ 0x0307, KEY_REWIND },       /* FR << */
+	{ 0x0309, KEY_FASTFORWARD },  /* FF >> */
+	{ 0x003b, KEY_TIME },         /* TimeShift */
+	{ 0x003e, KEY_CAMERA },       /* Snapshot */
+	{ 0x0316, KEY_CYCLEWINDOWS }, /* yellow, min / max */
+	{ 0x0000, KEY_ZOOM },         /* 'select' (?) */
+	{ 0x0316, KEY_SHUFFLE },      /* Shuffle */
+	{ 0x0345, KEY_POWER },
 };
 
 static u8 af9015_ir_table_mygictv[] = {
@@ -516,41 +516,41 @@ static u8 af9015_ir_table_kworld[] = {
 
 /* AverMedia Volar X */
 static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = {
-	{ 0x05, 0x3d, KEY_PROG1 },       /* SOURCE */
-	{ 0x05, 0x12, KEY_POWER },       /* POWER */
-	{ 0x05, 0x1e, KEY_1 },           /* 1 */
-	{ 0x05, 0x1f, KEY_2 },           /* 2 */
-	{ 0x05, 0x20, KEY_3 },           /* 3 */
-	{ 0x05, 0x21, KEY_4 },           /* 4 */
-	{ 0x05, 0x22, KEY_5 },           /* 5 */
-	{ 0x05, 0x23, KEY_6 },           /* 6 */
-	{ 0x05, 0x24, KEY_7 },           /* 7 */
-	{ 0x05, 0x25, KEY_8 },           /* 8 */
-	{ 0x05, 0x26, KEY_9 },           /* 9 */
-	{ 0x05, 0x3f, KEY_LEFT },        /* L / DISPLAY */
-	{ 0x05, 0x27, KEY_0 },           /* 0 */
-	{ 0x05, 0x0f, KEY_RIGHT },       /* R / CH RTN */
-	{ 0x05, 0x18, KEY_PROG2 },       /* SNAP SHOT */
-	{ 0x05, 0x1c, KEY_PROG3 },       /* 16-CH PREV */
-	{ 0x05, 0x2d, KEY_VOLUMEDOWN },  /* VOL DOWN */
-	{ 0x05, 0x3e, KEY_ZOOM },        /* FULL SCREEN */
-	{ 0x05, 0x2e, KEY_VOLUMEUP },    /* VOL UP */
-	{ 0x05, 0x10, KEY_MUTE },        /* MUTE */
-	{ 0x05, 0x04, KEY_AUDIO },       /* AUDIO */
-	{ 0x05, 0x15, KEY_RECORD },      /* RECORD */
-	{ 0x05, 0x11, KEY_PLAY },        /* PLAY */
-	{ 0x05, 0x16, KEY_STOP },        /* STOP */
-	{ 0x05, 0x0c, KEY_PLAYPAUSE },   /* TIMESHIFT / PAUSE */
-	{ 0x05, 0x05, KEY_BACK },        /* << / RED */
-	{ 0x05, 0x09, KEY_FORWARD },     /* >> / YELLOW */
-	{ 0x05, 0x17, KEY_TEXT },        /* TELETEXT */
-	{ 0x05, 0x0a, KEY_EPG },         /* EPG */
-	{ 0x05, 0x13, KEY_MENU },        /* MENU */
-
-	{ 0x05, 0x0e, KEY_CHANNELUP },   /* CH UP */
-	{ 0x05, 0x0d, KEY_CHANNELDOWN }, /* CH DOWN */
-	{ 0x05, 0x19, KEY_FIRST },       /* |<< / GREEN */
-	{ 0x05, 0x08, KEY_LAST },        /* >>| / BLUE */
+	{ 0x053d, KEY_PROG1 },       /* SOURCE */
+	{ 0x0512, KEY_POWER },       /* POWER */
+	{ 0x051e, KEY_1 },           /* 1 */
+	{ 0x051f, KEY_2 },           /* 2 */
+	{ 0x0520, KEY_3 },           /* 3 */
+	{ 0x0521, KEY_4 },           /* 4 */
+	{ 0x0522, KEY_5 },           /* 5 */
+	{ 0x0523, KEY_6 },           /* 6 */
+	{ 0x0524, KEY_7 },           /* 7 */
+	{ 0x0525, KEY_8 },           /* 8 */
+	{ 0x0526, KEY_9 },           /* 9 */
+	{ 0x053f, KEY_LEFT },        /* L / DISPLAY */
+	{ 0x0527, KEY_0 },           /* 0 */
+	{ 0x050f, KEY_RIGHT },       /* R / CH RTN */
+	{ 0x0518, KEY_PROG2 },       /* SNAP SHOT */
+	{ 0x051c, KEY_PROG3 },       /* 16-CH PREV */
+	{ 0x052d, KEY_VOLUMEDOWN },  /* VOL DOWN */
+	{ 0x053e, KEY_ZOOM },        /* FULL SCREEN */
+	{ 0x052e, KEY_VOLUMEUP },    /* VOL UP */
+	{ 0x0510, KEY_MUTE },        /* MUTE */
+	{ 0x0504, KEY_AUDIO },       /* AUDIO */
+	{ 0x0515, KEY_RECORD },      /* RECORD */
+	{ 0x0511, KEY_PLAY },        /* PLAY */
+	{ 0x0516, KEY_STOP },        /* STOP */
+	{ 0x050c, KEY_PLAYPAUSE },   /* TIMESHIFT / PAUSE */
+	{ 0x0505, KEY_BACK },        /* << / RED */
+	{ 0x0509, KEY_FORWARD },     /* >> / YELLOW */
+	{ 0x0517, KEY_TEXT },        /* TELETEXT */
+	{ 0x050a, KEY_EPG },         /* EPG */
+	{ 0x0513, KEY_MENU },        /* MENU */
+
+	{ 0x050e, KEY_CHANNELUP },   /* CH UP */
+	{ 0x050d, KEY_CHANNELDOWN }, /* CH DOWN */
+	{ 0x0519, KEY_FIRST },       /* |<< / GREEN */
+	{ 0x0508, KEY_LAST },        /* >>| / BLUE */
 };
 
 static u8 af9015_ir_table_avermedia[] = {
@@ -622,34 +622,34 @@ static u8 af9015_ir_table_avermedia_ks[] = {
 
 /* Digittrade DVB-T USB Stick */
 static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
-	{ 0x01, 0x0f, KEY_LAST },	/* RETURN */
-	{ 0x05, 0x17, KEY_TEXT },	/* TELETEXT */
-	{ 0x01, 0x08, KEY_EPG },	/* EPG */
-	{ 0x05, 0x13, KEY_POWER },	/* POWER */
-	{ 0x01, 0x09, KEY_ZOOM },	/* FULLSCREEN */
-	{ 0x00, 0x40, KEY_AUDIO },	/* DUAL SOUND */
-	{ 0x00, 0x2c, KEY_PRINT },	/* SNAPSHOT */
-	{ 0x05, 0x16, KEY_SUBTITLE },	/* SUBTITLE */
-	{ 0x00, 0x52, KEY_CHANNELUP },	/* CH Up */
-	{ 0x00, 0x51, KEY_CHANNELDOWN },/* Ch Dn */
-	{ 0x00, 0x57, KEY_VOLUMEUP },	/* Vol Up */
-	{ 0x00, 0x56, KEY_VOLUMEDOWN },	/* Vol Dn */
-	{ 0x01, 0x10, KEY_MUTE },	/* MUTE */
-	{ 0x00, 0x27, KEY_0 },
-	{ 0x00, 0x1e, KEY_1 },
-	{ 0x00, 0x1f, KEY_2 },
-	{ 0x00, 0x20, KEY_3 },
-	{ 0x00, 0x21, KEY_4 },
-	{ 0x00, 0x22, KEY_5 },
-	{ 0x00, 0x23, KEY_6 },
-	{ 0x00, 0x24, KEY_7 },
-	{ 0x00, 0x25, KEY_8 },
-	{ 0x00, 0x26, KEY_9 },
-	{ 0x01, 0x17, KEY_PLAYPAUSE },	/* TIMESHIFT */
-	{ 0x01, 0x15, KEY_RECORD },	/* RECORD */
-	{ 0x03, 0x13, KEY_PLAY },	/* PLAY */
-	{ 0x01, 0x16, KEY_STOP },	/* STOP */
-	{ 0x01, 0x13, KEY_PAUSE },	/* PAUSE */
+	{ 0x010f, KEY_LAST },	/* RETURN */
+	{ 0x0517, KEY_TEXT },	/* TELETEXT */
+	{ 0x0108, KEY_EPG },	/* EPG */
+	{ 0x0513, KEY_POWER },	/* POWER */
+	{ 0x0109, KEY_ZOOM },	/* FULLSCREEN */
+	{ 0x0040, KEY_AUDIO },	/* DUAL SOUND */
+	{ 0x002c, KEY_PRINT },	/* SNAPSHOT */
+	{ 0x0516, KEY_SUBTITLE },	/* SUBTITLE */
+	{ 0x0052, KEY_CHANNELUP },	/* CH Up */
+	{ 0x0051, KEY_CHANNELDOWN },/* Ch Dn */
+	{ 0x0057, KEY_VOLUMEUP },	/* Vol Up */
+	{ 0x0056, KEY_VOLUMEDOWN },	/* Vol Dn */
+	{ 0x0110, KEY_MUTE },	/* MUTE */
+	{ 0x0027, KEY_0 },
+	{ 0x001e, KEY_1 },
+	{ 0x001f, KEY_2 },
+	{ 0x0020, KEY_3 },
+	{ 0x0021, KEY_4 },
+	{ 0x0022, KEY_5 },
+	{ 0x0023, KEY_6 },
+	{ 0x0024, KEY_7 },
+	{ 0x0025, KEY_8 },
+	{ 0x0026, KEY_9 },
+	{ 0x0117, KEY_PLAYPAUSE },	/* TIMESHIFT */
+	{ 0x0115, KEY_RECORD },	/* RECORD */
+	{ 0x0313, KEY_PLAY },	/* PLAY */
+	{ 0x0116, KEY_STOP },	/* STOP */
+	{ 0x0113, KEY_PAUSE },	/* PAUSE */
 };
 
 static u8 af9015_ir_table_digittrade[] = {
@@ -685,34 +685,34 @@ static u8 af9015_ir_table_digittrade[] = {
 
 /* TREKSTOR DVB-T USB Stick */
 static struct dvb_usb_rc_key af9015_rc_keys_trekstor[] = {
-	{ 0x07, 0x04, KEY_AGAIN },		/* Home */
-	{ 0x07, 0x05, KEY_MUTE },		/* Mute */
-	{ 0x07, 0x06, KEY_UP },			/* Up */
-	{ 0x07, 0x07, KEY_DOWN },		/* Down */
-	{ 0x07, 0x09, KEY_RIGHT },		/* Right */
-	{ 0x07, 0x0a, KEY_ENTER },		/* OK */
-	{ 0x07, 0x0b, KEY_FASTFORWARD },	/* Fast forward */
-	{ 0x07, 0x0c, KEY_REWIND },		/* Rewind */
-	{ 0x07, 0x0d, KEY_PLAY },		/* Play/Pause */
-	{ 0x07, 0x0e, KEY_VOLUMEUP },		/* Volume + */
-	{ 0x07, 0x0f, KEY_VOLUMEDOWN },		/* Volume - */
-	{ 0x07, 0x10, KEY_RECORD },		/* Record */
-	{ 0x07, 0x11, KEY_STOP },		/* Stop */
-	{ 0x07, 0x12, KEY_ZOOM },		/* TV */
-	{ 0x07, 0x13, KEY_EPG },		/* Info/EPG */
-	{ 0x07, 0x14, KEY_CHANNELDOWN },	/* Channel - */
-	{ 0x07, 0x15, KEY_CHANNELUP },		/* Channel + */
-	{ 0x07, 0x1e, KEY_1 },
-	{ 0x07, 0x1f, KEY_2 },
-	{ 0x07, 0x20, KEY_3 },
-	{ 0x07, 0x21, KEY_4 },
-	{ 0x07, 0x22, KEY_5 },
-	{ 0x07, 0x23, KEY_6 },
-	{ 0x07, 0x24, KEY_7 },
-	{ 0x07, 0x25, KEY_8 },
-	{ 0x07, 0x26, KEY_9 },
-	{ 0x07, 0x08, KEY_LEFT },		/* LEFT */
-	{ 0x07, 0x27, KEY_0 },
+	{ 0x0704, KEY_AGAIN },		/* Home */
+	{ 0x0705, KEY_MUTE },		/* Mute */
+	{ 0x0706, KEY_UP },			/* Up */
+	{ 0x0707, KEY_DOWN },		/* Down */
+	{ 0x0709, KEY_RIGHT },		/* Right */
+	{ 0x070a, KEY_ENTER },		/* OK */
+	{ 0x070b, KEY_FASTFORWARD },	/* Fast forward */
+	{ 0x070c, KEY_REWIND },		/* Rewind */
+	{ 0x070d, KEY_PLAY },		/* Play/Pause */
+	{ 0x070e, KEY_VOLUMEUP },		/* Volume + */
+	{ 0x070f, KEY_VOLUMEDOWN },		/* Volume - */
+	{ 0x0710, KEY_RECORD },		/* Record */
+	{ 0x0711, KEY_STOP },		/* Stop */
+	{ 0x0712, KEY_ZOOM },		/* TV */
+	{ 0x0713, KEY_EPG },		/* Info/EPG */
+	{ 0x0714, KEY_CHANNELDOWN },	/* Channel - */
+	{ 0x0715, KEY_CHANNELUP },		/* Channel + */
+	{ 0x071e, KEY_1 },
+	{ 0x071f, KEY_2 },
+	{ 0x0720, KEY_3 },
+	{ 0x0721, KEY_4 },
+	{ 0x0722, KEY_5 },
+	{ 0x0723, KEY_6 },
+	{ 0x0724, KEY_7 },
+	{ 0x0725, KEY_8 },
+	{ 0x0726, KEY_9 },
+	{ 0x0708, KEY_LEFT },		/* LEFT */
+	{ 0x0727, KEY_0 },
 };
 
 static u8 af9015_ir_table_trekstor[] = {
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index c6e7b42..2ae7f64 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -203,11 +203,11 @@ static struct i2c_algorithm anysee_i2c_algo = {
 
 static int anysee_mt352_demod_init(struct dvb_frontend *fe)
 {
-	static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x28 };
-	static u8 reset []         = { RESET,      0x80 };
-	static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
-	static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0x20 };
-	static u8 gpp_ctl_cfg []   = { GPP_CTL,    0x33 };
+	static u8 clock_config[]   = { CLOCK_CTL,  0x38, 0x28 };
+	static u8 reset[]          = { RESET,      0x80 };
+	static u8 adc_ctl_1_cfg[]  = { ADC_CTL_1,  0x40 };
+	static u8 agc_cfg[]        = { AGC_TARGET, 0x28, 0x20 };
+	static u8 gpp_ctl_cfg[]    = { GPP_CTL,    0x33 };
 	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
 
 	mt352_write(fe, clock_config,   sizeof(clock_config));
@@ -389,8 +389,8 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	*state = REMOTE_NO_KEY_PRESSED;
 
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (keymap[i].custom == ircode[0] &&
-		    keymap[i].data == ircode[1]) {
+		if (rc5_custom(&keymap[i]) == ircode[0] &&
+		    rc5_data(&keymap[i]) == ircode[1]) {
 			*event = keymap[i].event;
 			*state = REMOTE_KEY_PRESSED;
 			return 0;
@@ -400,50 +400,50 @@ static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 }
 
 static struct dvb_usb_rc_key anysee_rc_keys[] = {
-	{ 0x01, 0x00, KEY_0 },
-	{ 0x01, 0x01, KEY_1 },
-	{ 0x01, 0x02, KEY_2 },
-	{ 0x01, 0x03, KEY_3 },
-	{ 0x01, 0x04, KEY_4 },
-	{ 0x01, 0x05, KEY_5 },
-	{ 0x01, 0x06, KEY_6 },
-	{ 0x01, 0x07, KEY_7 },
-	{ 0x01, 0x08, KEY_8 },
-	{ 0x01, 0x09, KEY_9 },
-	{ 0x01, 0x0a, KEY_POWER },
-	{ 0x01, 0x0b, KEY_DOCUMENTS },    /* * */
-	{ 0x01, 0x19, KEY_FAVORITES },
-	{ 0x01, 0x20, KEY_SLEEP },
-	{ 0x01, 0x21, KEY_MODE },         /* 4:3 / 16:9 select */
-	{ 0x01, 0x22, KEY_ZOOM },
-	{ 0x01, 0x47, KEY_TEXT },
-	{ 0x01, 0x16, KEY_TV },           /* TV / radio select */
-	{ 0x01, 0x1e, KEY_LANGUAGE },     /* Second Audio Program */
-	{ 0x01, 0x1a, KEY_SUBTITLE },
-	{ 0x01, 0x1b, KEY_CAMERA },       /* screenshot */
-	{ 0x01, 0x42, KEY_MUTE },
-	{ 0x01, 0x0e, KEY_MENU },
-	{ 0x01, 0x0f, KEY_EPG },
-	{ 0x01, 0x17, KEY_INFO },
-	{ 0x01, 0x10, KEY_EXIT },
-	{ 0x01, 0x13, KEY_VOLUMEUP },
-	{ 0x01, 0x12, KEY_VOLUMEDOWN },
-	{ 0x01, 0x11, KEY_CHANNELUP },
-	{ 0x01, 0x14, KEY_CHANNELDOWN },
-	{ 0x01, 0x15, KEY_OK },
-	{ 0x01, 0x1d, KEY_RED },
-	{ 0x01, 0x1f, KEY_GREEN },
-	{ 0x01, 0x1c, KEY_YELLOW },
-	{ 0x01, 0x44, KEY_BLUE },
-	{ 0x01, 0x0c, KEY_SHUFFLE },      /* snapshot */
-	{ 0x01, 0x48, KEY_STOP },
-	{ 0x01, 0x50, KEY_PLAY },
-	{ 0x01, 0x51, KEY_PAUSE },
-	{ 0x01, 0x49, KEY_RECORD },
-	{ 0x01, 0x18, KEY_PREVIOUS },     /* |<< */
-	{ 0x01, 0x0d, KEY_NEXT },         /* >>| */
-	{ 0x01, 0x24, KEY_PROG1 },        /* F1 */
-	{ 0x01, 0x25, KEY_PROG2 },        /* F2 */
+	{ 0x0100, KEY_0 },
+	{ 0x0101, KEY_1 },
+	{ 0x0102, KEY_2 },
+	{ 0x0103, KEY_3 },
+	{ 0x0104, KEY_4 },
+	{ 0x0105, KEY_5 },
+	{ 0x0106, KEY_6 },
+	{ 0x0107, KEY_7 },
+	{ 0x0108, KEY_8 },
+	{ 0x0109, KEY_9 },
+	{ 0x010a, KEY_POWER },
+	{ 0x010b, KEY_DOCUMENTS },    /* * */
+	{ 0x0119, KEY_FAVORITES },
+	{ 0x0120, KEY_SLEEP },
+	{ 0x0121, KEY_MODE },         /* 4:3 / 16:9 select */
+	{ 0x0122, KEY_ZOOM },
+	{ 0x0147, KEY_TEXT },
+	{ 0x0116, KEY_TV },           /* TV / radio select */
+	{ 0x011e, KEY_LANGUAGE },     /* Second Audio Program */
+	{ 0x011a, KEY_SUBTITLE },
+	{ 0x011b, KEY_CAMERA },       /* screenshot */
+	{ 0x0142, KEY_MUTE },
+	{ 0x010e, KEY_MENU },
+	{ 0x010f, KEY_EPG },
+	{ 0x0117, KEY_INFO },
+	{ 0x0110, KEY_EXIT },
+	{ 0x0113, KEY_VOLUMEUP },
+	{ 0x0112, KEY_VOLUMEDOWN },
+	{ 0x0111, KEY_CHANNELUP },
+	{ 0x0114, KEY_CHANNELDOWN },
+	{ 0x0115, KEY_OK },
+	{ 0x011d, KEY_RED },
+	{ 0x011f, KEY_GREEN },
+	{ 0x011c, KEY_YELLOW },
+	{ 0x0144, KEY_BLUE },
+	{ 0x010c, KEY_SHUFFLE },      /* snapshot */
+	{ 0x0148, KEY_STOP },
+	{ 0x0150, KEY_PLAY },
+	{ 0x0151, KEY_PAUSE },
+	{ 0x0149, KEY_RECORD },
+	{ 0x0118, KEY_PREVIOUS },     /* |<< */
+	{ 0x010d, KEY_NEXT },         /* >>| */
+	{ 0x0124, KEY_PROG1 },        /* F1 */
+	{ 0x0125, KEY_PROG2 },        /* F2 */
 };
 
 /* DVB USB Driver stuff */
@@ -485,7 +485,7 @@ static int anysee_probe(struct usb_interface *intf,
 	return ret;
 }
 
-static struct usb_device_id anysee_table [] = {
+static struct usb_device_id anysee_table[] = {
 	{ USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
 	{ USB_DEVICE(USB_VID_AMT,     USB_PID_ANYSEE) },
 	{ }		/* Terminating entry */
@@ -511,7 +511,7 @@ static struct dvb_usb_device_properties anysee_properties = {
 				.endpoint = 0x82,
 				.u = {
 					.bulk = {
-						.buffersize = 512,
+						.buffersize = (16*512),
 					}
 				}
 			},
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
index 52badc0..0737c63 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -274,7 +274,7 @@ static struct dvb_usb_device_properties ce6230_properties = {
 				.endpoint = 0x82,
 				.u = {
 					.bulk = {
-						.buffersize = 512,
+						.buffersize = (16*512),
 					}
 				}
 			},
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
index 80e37a0..e37ac4d 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -85,43 +85,43 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
 }
 
 static struct dvb_usb_rc_key cinergyt2_rc_keys[] = {
-	{ 0x04,	0x01,	KEY_POWER },
-	{ 0x04,	0x02,	KEY_1 },
-	{ 0x04,	0x03,	KEY_2 },
-	{ 0x04,	0x04,	KEY_3 },
-	{ 0x04,	0x05,	KEY_4 },
-	{ 0x04,	0x06,	KEY_5 },
-	{ 0x04,	0x07,	KEY_6 },
-	{ 0x04,	0x08,	KEY_7 },
-	{ 0x04,	0x09,	KEY_8 },
-	{ 0x04,	0x0a,	KEY_9 },
-	{ 0x04,	0x0c,	KEY_0 },
-	{ 0x04,	0x0b,	KEY_VIDEO },
-	{ 0x04,	0x0d,	KEY_REFRESH },
-	{ 0x04,	0x0e,	KEY_SELECT },
-	{ 0x04,	0x0f,	KEY_EPG },
-	{ 0x04,	0x10,	KEY_UP },
-	{ 0x04,	0x14,	KEY_DOWN },
-	{ 0x04,	0x11,	KEY_LEFT },
-	{ 0x04,	0x13,	KEY_RIGHT },
-	{ 0x04,	0x12,	KEY_OK },
-	{ 0x04,	0x15,	KEY_TEXT },
-	{ 0x04,	0x16,	KEY_INFO },
-	{ 0x04,	0x17,	KEY_RED },
-	{ 0x04,	0x18,	KEY_GREEN },
-	{ 0x04,	0x19,	KEY_YELLOW },
-	{ 0x04,	0x1a,	KEY_BLUE },
-	{ 0x04,	0x1c,	KEY_VOLUMEUP },
-	{ 0x04,	0x1e,	KEY_VOLUMEDOWN },
-	{ 0x04,	0x1d,	KEY_MUTE },
-	{ 0x04,	0x1b,	KEY_CHANNELUP },
-	{ 0x04,	0x1f,	KEY_CHANNELDOWN },
-	{ 0x04,	0x40,	KEY_PAUSE },
-	{ 0x04,	0x4c,	KEY_PLAY },
-	{ 0x04,	0x58,	KEY_RECORD },
-	{ 0x04,	0x54,	KEY_PREVIOUS },
-	{ 0x04,	0x48,	KEY_STOP },
-	{ 0x04,	0x5c,	KEY_NEXT }
+	{ 0x0401, KEY_POWER },
+	{ 0x0402, KEY_1 },
+	{ 0x0403, KEY_2 },
+	{ 0x0404, KEY_3 },
+	{ 0x0405, KEY_4 },
+	{ 0x0406, KEY_5 },
+	{ 0x0407, KEY_6 },
+	{ 0x0408, KEY_7 },
+	{ 0x0409, KEY_8 },
+	{ 0x040a, KEY_9 },
+	{ 0x040c, KEY_0 },
+	{ 0x040b, KEY_VIDEO },
+	{ 0x040d, KEY_REFRESH },
+	{ 0x040e, KEY_SELECT },
+	{ 0x040f, KEY_EPG },
+	{ 0x0410, KEY_UP },
+	{ 0x0414, KEY_DOWN },
+	{ 0x0411, KEY_LEFT },
+	{ 0x0413, KEY_RIGHT },
+	{ 0x0412, KEY_OK },
+	{ 0x0415, KEY_TEXT },
+	{ 0x0416, KEY_INFO },
+	{ 0x0417, KEY_RED },
+	{ 0x0418, KEY_GREEN },
+	{ 0x0419, KEY_YELLOW },
+	{ 0x041a, KEY_BLUE },
+	{ 0x041c, KEY_VOLUMEUP },
+	{ 0x041e, KEY_VOLUMEDOWN },
+	{ 0x041d, KEY_MUTE },
+	{ 0x041b, KEY_CHANNELUP },
+	{ 0x041f, KEY_CHANNELDOWN },
+	{ 0x0440, KEY_PAUSE },
+	{ 0x044c, KEY_PLAY },
+	{ 0x0458, KEY_RECORD },
+	{ 0x0454, KEY_PREVIOUS },
+	{ 0x0448, KEY_STOP },
+	{ 0x045c, KEY_NEXT }
 };
 
 /* Number of keypresses to ignore before detect repeating */
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
index 649f25c..9cd51ac 100644
--- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
@@ -275,6 +275,7 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe,
 	param.tps = cpu_to_le16(compute_tps(fep));
 	param.freq = cpu_to_le32(fep->frequency / 1000);
 	param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
+	param.flags = 0;
 
 	err = dvb_usb_generic_rw(state->d,
 			(char *)&param, sizeof(param),
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 406d7fb..f65591f 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -38,7 +38,7 @@
 #include "mxl5005s.h"
 #include "dib7000p.h"
 #include "dib0070.h"
-#include "lgs8gl5.h"
+#include "lgs8gxx.h"
 
 /* debug */
 static int dvb_usb_cxusb_debug;
@@ -392,8 +392,8 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	*state = REMOTE_NO_KEY_PRESSED;
 
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (keymap[i].custom == ircode[2] &&
-		    keymap[i].data == ircode[3]) {
+		if (rc5_custom(&keymap[i]) == ircode[2] &&
+		    rc5_data(&keymap[i]) == ircode[3]) {
 			*event = keymap[i].event;
 			*state = REMOTE_KEY_PRESSED;
 
@@ -420,8 +420,8 @@ static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
 		return 0;
 
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (keymap[i].custom == ircode[1] &&
-		    keymap[i].data == ircode[2]) {
+		if (rc5_custom(&keymap[i]) == ircode[1] &&
+		    rc5_data(&keymap[i]) == ircode[2]) {
 			*event = keymap[i].event;
 			*state = REMOTE_KEY_PRESSED;
 
@@ -446,8 +446,8 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
 		return 0;
 
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (keymap[i].custom == ircode[0] &&
-		    keymap[i].data == ircode[1]) {
+		if (rc5_custom(&keymap[i]) == ircode[0] &&
+		    rc5_data(&keymap[i]) == ircode[1]) {
 			*event = keymap[i].event;
 			*state = REMOTE_KEY_PRESSED;
 
@@ -459,128 +459,128 @@ static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
 }
 
 static struct dvb_usb_rc_key dvico_mce_rc_keys[] = {
-	{ 0xfe, 0x02, KEY_TV },
-	{ 0xfe, 0x0e, KEY_MP3 },
-	{ 0xfe, 0x1a, KEY_DVD },
-	{ 0xfe, 0x1e, KEY_FAVORITES },
-	{ 0xfe, 0x16, KEY_SETUP },
-	{ 0xfe, 0x46, KEY_POWER2 },
-	{ 0xfe, 0x0a, KEY_EPG },
-	{ 0xfe, 0x49, KEY_BACK },
-	{ 0xfe, 0x4d, KEY_MENU },
-	{ 0xfe, 0x51, KEY_UP },
-	{ 0xfe, 0x5b, KEY_LEFT },
-	{ 0xfe, 0x5f, KEY_RIGHT },
-	{ 0xfe, 0x53, KEY_DOWN },
-	{ 0xfe, 0x5e, KEY_OK },
-	{ 0xfe, 0x59, KEY_INFO },
-	{ 0xfe, 0x55, KEY_TAB },
-	{ 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */
-	{ 0xfe, 0x12, KEY_NEXTSONG },	/* Skip */
-	{ 0xfe, 0x42, KEY_ENTER	 },	/* Windows/Start */
-	{ 0xfe, 0x15, KEY_VOLUMEUP },
-	{ 0xfe, 0x05, KEY_VOLUMEDOWN },
-	{ 0xfe, 0x11, KEY_CHANNELUP },
-	{ 0xfe, 0x09, KEY_CHANNELDOWN },
-	{ 0xfe, 0x52, KEY_CAMERA },
-	{ 0xfe, 0x5a, KEY_TUNER },	/* Live */
-	{ 0xfe, 0x19, KEY_OPEN },
-	{ 0xfe, 0x0b, KEY_1 },
-	{ 0xfe, 0x17, KEY_2 },
-	{ 0xfe, 0x1b, KEY_3 },
-	{ 0xfe, 0x07, KEY_4 },
-	{ 0xfe, 0x50, KEY_5 },
-	{ 0xfe, 0x54, KEY_6 },
-	{ 0xfe, 0x48, KEY_7 },
-	{ 0xfe, 0x4c, KEY_8 },
-	{ 0xfe, 0x58, KEY_9 },
-	{ 0xfe, 0x13, KEY_ANGLE },	/* Aspect */
-	{ 0xfe, 0x03, KEY_0 },
-	{ 0xfe, 0x1f, KEY_ZOOM },
-	{ 0xfe, 0x43, KEY_REWIND },
-	{ 0xfe, 0x47, KEY_PLAYPAUSE },
-	{ 0xfe, 0x4f, KEY_FASTFORWARD },
-	{ 0xfe, 0x57, KEY_MUTE },
-	{ 0xfe, 0x0d, KEY_STOP },
-	{ 0xfe, 0x01, KEY_RECORD },
-	{ 0xfe, 0x4e, KEY_POWER },
+	{ 0xfe02, KEY_TV },
+	{ 0xfe0e, KEY_MP3 },
+	{ 0xfe1a, KEY_DVD },
+	{ 0xfe1e, KEY_FAVORITES },
+	{ 0xfe16, KEY_SETUP },
+	{ 0xfe46, KEY_POWER2 },
+	{ 0xfe0a, KEY_EPG },
+	{ 0xfe49, KEY_BACK },
+	{ 0xfe4d, KEY_MENU },
+	{ 0xfe51, KEY_UP },
+	{ 0xfe5b, KEY_LEFT },
+	{ 0xfe5f, KEY_RIGHT },
+	{ 0xfe53, KEY_DOWN },
+	{ 0xfe5e, KEY_OK },
+	{ 0xfe59, KEY_INFO },
+	{ 0xfe55, KEY_TAB },
+	{ 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
+	{ 0xfe12, KEY_NEXTSONG },	/* Skip */
+	{ 0xfe42, KEY_ENTER	 },	/* Windows/Start */
+	{ 0xfe15, KEY_VOLUMEUP },
+	{ 0xfe05, KEY_VOLUMEDOWN },
+	{ 0xfe11, KEY_CHANNELUP },
+	{ 0xfe09, KEY_CHANNELDOWN },
+	{ 0xfe52, KEY_CAMERA },
+	{ 0xfe5a, KEY_TUNER },	/* Live */
+	{ 0xfe19, KEY_OPEN },
+	{ 0xfe0b, KEY_1 },
+	{ 0xfe17, KEY_2 },
+	{ 0xfe1b, KEY_3 },
+	{ 0xfe07, KEY_4 },
+	{ 0xfe50, KEY_5 },
+	{ 0xfe54, KEY_6 },
+	{ 0xfe48, KEY_7 },
+	{ 0xfe4c, KEY_8 },
+	{ 0xfe58, KEY_9 },
+	{ 0xfe13, KEY_ANGLE },	/* Aspect */
+	{ 0xfe03, KEY_0 },
+	{ 0xfe1f, KEY_ZOOM },
+	{ 0xfe43, KEY_REWIND },
+	{ 0xfe47, KEY_PLAYPAUSE },
+	{ 0xfe4f, KEY_FASTFORWARD },
+	{ 0xfe57, KEY_MUTE },
+	{ 0xfe0d, KEY_STOP },
+	{ 0xfe01, KEY_RECORD },
+	{ 0xfe4e, KEY_POWER },
 };
 
 static struct dvb_usb_rc_key dvico_portable_rc_keys[] = {
-	{ 0xfc, 0x02, KEY_SETUP },       /* Profile */
-	{ 0xfc, 0x43, KEY_POWER2 },
-	{ 0xfc, 0x06, KEY_EPG },
-	{ 0xfc, 0x5a, KEY_BACK },
-	{ 0xfc, 0x05, KEY_MENU },
-	{ 0xfc, 0x47, KEY_INFO },
-	{ 0xfc, 0x01, KEY_TAB },
-	{ 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */
-	{ 0xfc, 0x49, KEY_VOLUMEUP },
-	{ 0xfc, 0x09, KEY_VOLUMEDOWN },
-	{ 0xfc, 0x54, KEY_CHANNELUP },
-	{ 0xfc, 0x0b, KEY_CHANNELDOWN },
-	{ 0xfc, 0x16, KEY_CAMERA },
-	{ 0xfc, 0x40, KEY_TUNER },	/* ATV/DTV */
-	{ 0xfc, 0x45, KEY_OPEN },
-	{ 0xfc, 0x19, KEY_1 },
-	{ 0xfc, 0x18, KEY_2 },
-	{ 0xfc, 0x1b, KEY_3 },
-	{ 0xfc, 0x1a, KEY_4 },
-	{ 0xfc, 0x58, KEY_5 },
-	{ 0xfc, 0x59, KEY_6 },
-	{ 0xfc, 0x15, KEY_7 },
-	{ 0xfc, 0x14, KEY_8 },
-	{ 0xfc, 0x17, KEY_9 },
-	{ 0xfc, 0x44, KEY_ANGLE },	/* Aspect */
-	{ 0xfc, 0x55, KEY_0 },
-	{ 0xfc, 0x07, KEY_ZOOM },
-	{ 0xfc, 0x0a, KEY_REWIND },
-	{ 0xfc, 0x08, KEY_PLAYPAUSE },
-	{ 0xfc, 0x4b, KEY_FASTFORWARD },
-	{ 0xfc, 0x5b, KEY_MUTE },
-	{ 0xfc, 0x04, KEY_STOP },
-	{ 0xfc, 0x56, KEY_RECORD },
-	{ 0xfc, 0x57, KEY_POWER },
-	{ 0xfc, 0x41, KEY_UNKNOWN },    /* INPUT */
-	{ 0xfc, 0x00, KEY_UNKNOWN },    /* HD */
+	{ 0xfc02, KEY_SETUP },       /* Profile */
+	{ 0xfc43, KEY_POWER2 },
+	{ 0xfc06, KEY_EPG },
+	{ 0xfc5a, KEY_BACK },
+	{ 0xfc05, KEY_MENU },
+	{ 0xfc47, KEY_INFO },
+	{ 0xfc01, KEY_TAB },
+	{ 0xfc42, KEY_PREVIOUSSONG },/* Replay */
+	{ 0xfc49, KEY_VOLUMEUP },
+	{ 0xfc09, KEY_VOLUMEDOWN },
+	{ 0xfc54, KEY_CHANNELUP },
+	{ 0xfc0b, KEY_CHANNELDOWN },
+	{ 0xfc16, KEY_CAMERA },
+	{ 0xfc40, KEY_TUNER },	/* ATV/DTV */
+	{ 0xfc45, KEY_OPEN },
+	{ 0xfc19, KEY_1 },
+	{ 0xfc18, KEY_2 },
+	{ 0xfc1b, KEY_3 },
+	{ 0xfc1a, KEY_4 },
+	{ 0xfc58, KEY_5 },
+	{ 0xfc59, KEY_6 },
+	{ 0xfc15, KEY_7 },
+	{ 0xfc14, KEY_8 },
+	{ 0xfc17, KEY_9 },
+	{ 0xfc44, KEY_ANGLE },	/* Aspect */
+	{ 0xfc55, KEY_0 },
+	{ 0xfc07, KEY_ZOOM },
+	{ 0xfc0a, KEY_REWIND },
+	{ 0xfc08, KEY_PLAYPAUSE },
+	{ 0xfc4b, KEY_FASTFORWARD },
+	{ 0xfc5b, KEY_MUTE },
+	{ 0xfc04, KEY_STOP },
+	{ 0xfc56, KEY_RECORD },
+	{ 0xfc57, KEY_POWER },
+	{ 0xfc41, KEY_UNKNOWN },    /* INPUT */
+	{ 0xfc00, KEY_UNKNOWN },    /* HD */
 };
 
 static struct dvb_usb_rc_key d680_dmb_rc_keys[] = {
-	{ 0x00, 0x38, KEY_UNKNOWN },	/* TV/AV */
-	{ 0x08, 0x0c, KEY_ZOOM },
-	{ 0x08, 0x00, KEY_0 },
-	{ 0x00, 0x01, KEY_1 },
-	{ 0x08, 0x02, KEY_2 },
-	{ 0x00, 0x03, KEY_3 },
-	{ 0x08, 0x04, KEY_4 },
-	{ 0x00, 0x05, KEY_5 },
-	{ 0x08, 0x06, KEY_6 },
-	{ 0x00, 0x07, KEY_7 },
-	{ 0x08, 0x08, KEY_8 },
-	{ 0x00, 0x09, KEY_9 },
-	{ 0x00, 0x0a, KEY_MUTE },
-	{ 0x08, 0x29, KEY_BACK },
-	{ 0x00, 0x12, KEY_CHANNELUP },
-	{ 0x08, 0x13, KEY_CHANNELDOWN },
-	{ 0x00, 0x2b, KEY_VOLUMEUP },
-	{ 0x08, 0x2c, KEY_VOLUMEDOWN },
-	{ 0x00, 0x20, KEY_UP },
-	{ 0x08, 0x21, KEY_DOWN },
-	{ 0x00, 0x11, KEY_LEFT },
-	{ 0x08, 0x10, KEY_RIGHT },
-	{ 0x00, 0x0d, KEY_OK },
-	{ 0x08, 0x1f, KEY_RECORD },
-	{ 0x00, 0x17, KEY_PLAYPAUSE },
-	{ 0x08, 0x16, KEY_PLAYPAUSE },
-	{ 0x00, 0x0b, KEY_STOP },
-	{ 0x08, 0x27, KEY_FASTFORWARD },
-	{ 0x00, 0x26, KEY_REWIND },
-	{ 0x08, 0x1e, KEY_UNKNOWN },    /* Time Shift */
-	{ 0x00, 0x0e, KEY_UNKNOWN },    /* Snapshot */
-	{ 0x08, 0x2d, KEY_UNKNOWN },    /* Mouse Cursor */
-	{ 0x00, 0x0f, KEY_UNKNOWN },    /* Minimize/Maximize */
-	{ 0x08, 0x14, KEY_UNKNOWN },    /* Shuffle */
-	{ 0x00, 0x25, KEY_POWER },
+	{ 0x0038, KEY_UNKNOWN },	/* TV/AV */
+	{ 0x080c, KEY_ZOOM },
+	{ 0x0800, KEY_0 },
+	{ 0x0001, KEY_1 },
+	{ 0x0802, KEY_2 },
+	{ 0x0003, KEY_3 },
+	{ 0x0804, KEY_4 },
+	{ 0x0005, KEY_5 },
+	{ 0x0806, KEY_6 },
+	{ 0x0007, KEY_7 },
+	{ 0x0808, KEY_8 },
+	{ 0x0009, KEY_9 },
+	{ 0x000a, KEY_MUTE },
+	{ 0x0829, KEY_BACK },
+	{ 0x0012, KEY_CHANNELUP },
+	{ 0x0813, KEY_CHANNELDOWN },
+	{ 0x002b, KEY_VOLUMEUP },
+	{ 0x082c, KEY_VOLUMEDOWN },
+	{ 0x0020, KEY_UP },
+	{ 0x0821, KEY_DOWN },
+	{ 0x0011, KEY_LEFT },
+	{ 0x0810, KEY_RIGHT },
+	{ 0x000d, KEY_OK },
+	{ 0x081f, KEY_RECORD },
+	{ 0x0017, KEY_PLAYPAUSE },
+	{ 0x0816, KEY_PLAYPAUSE },
+	{ 0x000b, KEY_STOP },
+	{ 0x0827, KEY_FASTFORWARD },
+	{ 0x0026, KEY_REWIND },
+	{ 0x081e, KEY_UNKNOWN },    /* Time Shift */
+	{ 0x000e, KEY_UNKNOWN },    /* Snapshot */
+	{ 0x082d, KEY_UNKNOWN },    /* Mouse Cursor */
+	{ 0x000f, KEY_UNKNOWN },    /* Minimize/Maximize */
+	{ 0x0814, KEY_UNKNOWN },    /* Shuffle */
+	{ 0x0025, KEY_POWER },
 };
 
 static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
@@ -1094,8 +1094,18 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
 	return -EIO;
 }
 
-static struct lgs8gl5_config lgs8gl5_cfg = {
+static struct lgs8gxx_config d680_lgs8gl5_cfg = {
+	.prod = LGS8GXX_PROD_LGS8GL5,
 	.demod_address = 0x19,
+	.serial_ts = 0,
+	.ts_clk_pol = 0,
+	.ts_clk_gated = 1,
+	.if_clk_freq = 30400, /* 30.4 MHz */
+	.if_freq = 5725, /* 5.725 MHz */
+	.if_neg_center = 0,
+	.ext_adc = 0,
+	.adc_signed = 0,
+	.if_neg_edge = 0,
 };
 
 static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
@@ -1135,7 +1145,7 @@ static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
 	msleep(100);
 
 	/* Attach frontend */
-	adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap);
+	adap->fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
 	if (adap->fe == NULL)
 		return -EIO;
 
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 818b2ab..0b2812a 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -4,13 +4,14 @@
  *	under the terms of the GNU General Public License as published by the Free
  *	Software Foundation, version 2.
  *
- *  Copyright (C) 2005-7 DiBcom, SA
+ *  Copyright (C) 2005-9 DiBcom, SA et al
  */
 #include "dib0700.h"
 
 #include "dib3000mc.h"
 #include "dib7000m.h"
 #include "dib7000p.h"
+#include "dib8000.h"
 #include "mt2060.h"
 #include "mt2266.h"
 #include "tuner-xc2028.h"
@@ -310,7 +311,7 @@ static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
 	struct i2c_adapter *tun_i2c;
 	tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
 	return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
-		&stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;;
+		&stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
 }
 
 /* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
@@ -509,7 +510,8 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
 			return 0;
 		}
 		for (i=0;i<d->props.rc_key_map_size; i++) {
-			if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
+			if (rc5_custom(&keymap[i]) == key[3-2] &&
+			    rc5_data(&keymap[i]) == key[3-3]) {
 				st->rc_counter = 0;
 				*event = keymap[i].event;
 				*state = REMOTE_KEY_PRESSED;
@@ -522,7 +524,8 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event,
 	default: {
 		/* RC-5 protocol changes toggle bit on new keypress */
 		for (i = 0; i < d->props.rc_key_map_size; i++) {
-			if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) {
+			if (rc5_custom(&keymap[i]) == key[3-2] &&
+			    rc5_data(&keymap[i]) == key[3-3]) {
 				if (d->last_event == keymap[i].event &&
 					key[3-1] == st->rc_toggle) {
 					st->rc_counter++;
@@ -616,8 +619,8 @@ static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event,
 
 	/* Find the key in the map */
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		if (keymap[i].custom == poll_reply.system_lsb &&
-		    keymap[i].data == poll_reply.data) {
+		if (rc5_custom(&keymap[i]) == poll_reply.system_lsb &&
+		    rc5_data(&keymap[i]) == poll_reply.data) {
 			*event = keymap[i].event;
 			found = 1;
 			break;
@@ -684,193 +687,193 @@ static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 
 static struct dvb_usb_rc_key dib0700_rc_keys[] = {
 	/* Key codes for the tiny Pinnacle remote*/
-	{ 0x07, 0x00, KEY_MUTE },
-	{ 0x07, 0x01, KEY_MENU }, // Pinnacle logo
-	{ 0x07, 0x39, KEY_POWER },
-	{ 0x07, 0x03, KEY_VOLUMEUP },
-	{ 0x07, 0x09, KEY_VOLUMEDOWN },
-	{ 0x07, 0x06, KEY_CHANNELUP },
-	{ 0x07, 0x0c, KEY_CHANNELDOWN },
-	{ 0x07, 0x0f, KEY_1 },
-	{ 0x07, 0x15, KEY_2 },
-	{ 0x07, 0x10, KEY_3 },
-	{ 0x07, 0x18, KEY_4 },
-	{ 0x07, 0x1b, KEY_5 },
-	{ 0x07, 0x1e, KEY_6 },
-	{ 0x07, 0x11, KEY_7 },
-	{ 0x07, 0x21, KEY_8 },
-	{ 0x07, 0x12, KEY_9 },
-	{ 0x07, 0x27, KEY_0 },
-	{ 0x07, 0x24, KEY_SCREEN }, // 'Square' key
-	{ 0x07, 0x2a, KEY_TEXT },   // 'T' key
-	{ 0x07, 0x2d, KEY_REWIND },
-	{ 0x07, 0x30, KEY_PLAY },
-	{ 0x07, 0x33, KEY_FASTFORWARD },
-	{ 0x07, 0x36, KEY_RECORD },
-	{ 0x07, 0x3c, KEY_STOP },
-	{ 0x07, 0x3f, KEY_CANCEL }, // '?' key
+	{ 0x0700, KEY_MUTE },
+	{ 0x0701, KEY_MENU }, /* Pinnacle logo */
+	{ 0x0739, KEY_POWER },
+	{ 0x0703, KEY_VOLUMEUP },
+	{ 0x0709, KEY_VOLUMEDOWN },
+	{ 0x0706, KEY_CHANNELUP },
+	{ 0x070c, KEY_CHANNELDOWN },
+	{ 0x070f, KEY_1 },
+	{ 0x0715, KEY_2 },
+	{ 0x0710, KEY_3 },
+	{ 0x0718, KEY_4 },
+	{ 0x071b, KEY_5 },
+	{ 0x071e, KEY_6 },
+	{ 0x0711, KEY_7 },
+	{ 0x0721, KEY_8 },
+	{ 0x0712, KEY_9 },
+	{ 0x0727, KEY_0 },
+	{ 0x0724, KEY_SCREEN }, /* 'Square' key */
+	{ 0x072a, KEY_TEXT },   /* 'T' key */
+	{ 0x072d, KEY_REWIND },
+	{ 0x0730, KEY_PLAY },
+	{ 0x0733, KEY_FASTFORWARD },
+	{ 0x0736, KEY_RECORD },
+	{ 0x073c, KEY_STOP },
+	{ 0x073f, KEY_CANCEL }, /* '?' key */
 	/* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */
-	{ 0xeb, 0x01, KEY_POWER },
-	{ 0xeb, 0x02, KEY_1 },
-	{ 0xeb, 0x03, KEY_2 },
-	{ 0xeb, 0x04, KEY_3 },
-	{ 0xeb, 0x05, KEY_4 },
-	{ 0xeb, 0x06, KEY_5 },
-	{ 0xeb, 0x07, KEY_6 },
-	{ 0xeb, 0x08, KEY_7 },
-	{ 0xeb, 0x09, KEY_8 },
-	{ 0xeb, 0x0a, KEY_9 },
-	{ 0xeb, 0x0b, KEY_VIDEO },
-	{ 0xeb, 0x0c, KEY_0 },
-	{ 0xeb, 0x0d, KEY_REFRESH },
-	{ 0xeb, 0x0f, KEY_EPG },
-	{ 0xeb, 0x10, KEY_UP },
-	{ 0xeb, 0x11, KEY_LEFT },
-	{ 0xeb, 0x12, KEY_OK },
-	{ 0xeb, 0x13, KEY_RIGHT },
-	{ 0xeb, 0x14, KEY_DOWN },
-	{ 0xeb, 0x16, KEY_INFO },
-	{ 0xeb, 0x17, KEY_RED },
-	{ 0xeb, 0x18, KEY_GREEN },
-	{ 0xeb, 0x19, KEY_YELLOW },
-	{ 0xeb, 0x1a, KEY_BLUE },
-	{ 0xeb, 0x1b, KEY_CHANNELUP },
-	{ 0xeb, 0x1c, KEY_VOLUMEUP },
-	{ 0xeb, 0x1d, KEY_MUTE },
-	{ 0xeb, 0x1e, KEY_VOLUMEDOWN },
-	{ 0xeb, 0x1f, KEY_CHANNELDOWN },
-	{ 0xeb, 0x40, KEY_PAUSE },
-	{ 0xeb, 0x41, KEY_HOME },
-	{ 0xeb, 0x42, KEY_MENU }, /* DVD Menu */
-	{ 0xeb, 0x43, KEY_SUBTITLE },
-	{ 0xeb, 0x44, KEY_TEXT }, /* Teletext */
-	{ 0xeb, 0x45, KEY_DELETE },
-	{ 0xeb, 0x46, KEY_TV },
-	{ 0xeb, 0x47, KEY_DVD },
-	{ 0xeb, 0x48, KEY_STOP },
-	{ 0xeb, 0x49, KEY_VIDEO },
-	{ 0xeb, 0x4a, KEY_AUDIO }, /* Music */
-	{ 0xeb, 0x4b, KEY_SCREEN }, /* Pic */
-	{ 0xeb, 0x4c, KEY_PLAY },
-	{ 0xeb, 0x4d, KEY_BACK },
-	{ 0xeb, 0x4e, KEY_REWIND },
-	{ 0xeb, 0x4f, KEY_FASTFORWARD },
-	{ 0xeb, 0x54, KEY_PREVIOUS },
-	{ 0xeb, 0x58, KEY_RECORD },
-	{ 0xeb, 0x5c, KEY_NEXT },
+	{ 0xeb01, KEY_POWER },
+	{ 0xeb02, KEY_1 },
+	{ 0xeb03, KEY_2 },
+	{ 0xeb04, KEY_3 },
+	{ 0xeb05, KEY_4 },
+	{ 0xeb06, KEY_5 },
+	{ 0xeb07, KEY_6 },
+	{ 0xeb08, KEY_7 },
+	{ 0xeb09, KEY_8 },
+	{ 0xeb0a, KEY_9 },
+	{ 0xeb0b, KEY_VIDEO },
+	{ 0xeb0c, KEY_0 },
+	{ 0xeb0d, KEY_REFRESH },
+	{ 0xeb0f, KEY_EPG },
+	{ 0xeb10, KEY_UP },
+	{ 0xeb11, KEY_LEFT },
+	{ 0xeb12, KEY_OK },
+	{ 0xeb13, KEY_RIGHT },
+	{ 0xeb14, KEY_DOWN },
+	{ 0xeb16, KEY_INFO },
+	{ 0xeb17, KEY_RED },
+	{ 0xeb18, KEY_GREEN },
+	{ 0xeb19, KEY_YELLOW },
+	{ 0xeb1a, KEY_BLUE },
+	{ 0xeb1b, KEY_CHANNELUP },
+	{ 0xeb1c, KEY_VOLUMEUP },
+	{ 0xeb1d, KEY_MUTE },
+	{ 0xeb1e, KEY_VOLUMEDOWN },
+	{ 0xeb1f, KEY_CHANNELDOWN },
+	{ 0xeb40, KEY_PAUSE },
+	{ 0xeb41, KEY_HOME },
+	{ 0xeb42, KEY_MENU }, /* DVD Menu */
+	{ 0xeb43, KEY_SUBTITLE },
+	{ 0xeb44, KEY_TEXT }, /* Teletext */
+	{ 0xeb45, KEY_DELETE },
+	{ 0xeb46, KEY_TV },
+	{ 0xeb47, KEY_DVD },
+	{ 0xeb48, KEY_STOP },
+	{ 0xeb49, KEY_VIDEO },
+	{ 0xeb4a, KEY_AUDIO }, /* Music */
+	{ 0xeb4b, KEY_SCREEN }, /* Pic */
+	{ 0xeb4c, KEY_PLAY },
+	{ 0xeb4d, KEY_BACK },
+	{ 0xeb4e, KEY_REWIND },
+	{ 0xeb4f, KEY_FASTFORWARD },
+	{ 0xeb54, KEY_PREVIOUS },
+	{ 0xeb58, KEY_RECORD },
+	{ 0xeb5c, KEY_NEXT },
 
 	/* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */
-	{ 0x1e, 0x00, KEY_0 },
-	{ 0x1e, 0x01, KEY_1 },
-	{ 0x1e, 0x02, KEY_2 },
-	{ 0x1e, 0x03, KEY_3 },
-	{ 0x1e, 0x04, KEY_4 },
-	{ 0x1e, 0x05, KEY_5 },
-	{ 0x1e, 0x06, KEY_6 },
-	{ 0x1e, 0x07, KEY_7 },
-	{ 0x1e, 0x08, KEY_8 },
-	{ 0x1e, 0x09, KEY_9 },
-	{ 0x1e, 0x0a, KEY_KPASTERISK },
-	{ 0x1e, 0x0b, KEY_RED },
-	{ 0x1e, 0x0c, KEY_RADIO },
-	{ 0x1e, 0x0d, KEY_MENU },
-	{ 0x1e, 0x0e, KEY_GRAVE }, /* # */
-	{ 0x1e, 0x0f, KEY_MUTE },
-	{ 0x1e, 0x10, KEY_VOLUMEUP },
-	{ 0x1e, 0x11, KEY_VOLUMEDOWN },
-	{ 0x1e, 0x12, KEY_CHANNEL },
-	{ 0x1e, 0x14, KEY_UP },
-	{ 0x1e, 0x15, KEY_DOWN },
-	{ 0x1e, 0x16, KEY_LEFT },
-	{ 0x1e, 0x17, KEY_RIGHT },
-	{ 0x1e, 0x18, KEY_VIDEO },
-	{ 0x1e, 0x19, KEY_AUDIO },
-	{ 0x1e, 0x1a, KEY_MEDIA },
-	{ 0x1e, 0x1b, KEY_EPG },
-	{ 0x1e, 0x1c, KEY_TV },
-	{ 0x1e, 0x1e, KEY_NEXT },
-	{ 0x1e, 0x1f, KEY_BACK },
-	{ 0x1e, 0x20, KEY_CHANNELUP },
-	{ 0x1e, 0x21, KEY_CHANNELDOWN },
-	{ 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
-	{ 0x1e, 0x25, KEY_OK },
-	{ 0x1e, 0x29, KEY_BLUE},
-	{ 0x1e, 0x2e, KEY_GREEN },
-	{ 0x1e, 0x30, KEY_PAUSE },
-	{ 0x1e, 0x32, KEY_REWIND },
-	{ 0x1e, 0x34, KEY_FASTFORWARD },
-	{ 0x1e, 0x35, KEY_PLAY },
-	{ 0x1e, 0x36, KEY_STOP },
-	{ 0x1e, 0x37, KEY_RECORD },
-	{ 0x1e, 0x38, KEY_YELLOW },
-	{ 0x1e, 0x3b, KEY_GOTO },
-	{ 0x1e, 0x3d, KEY_POWER },
+	{ 0x1e00, KEY_0 },
+	{ 0x1e01, KEY_1 },
+	{ 0x1e02, KEY_2 },
+	{ 0x1e03, KEY_3 },
+	{ 0x1e04, KEY_4 },
+	{ 0x1e05, KEY_5 },
+	{ 0x1e06, KEY_6 },
+	{ 0x1e07, KEY_7 },
+	{ 0x1e08, KEY_8 },
+	{ 0x1e09, KEY_9 },
+	{ 0x1e0a, KEY_KPASTERISK },
+	{ 0x1e0b, KEY_RED },
+	{ 0x1e0c, KEY_RADIO },
+	{ 0x1e0d, KEY_MENU },
+	{ 0x1e0e, KEY_GRAVE }, /* # */
+	{ 0x1e0f, KEY_MUTE },
+	{ 0x1e10, KEY_VOLUMEUP },
+	{ 0x1e11, KEY_VOLUMEDOWN },
+	{ 0x1e12, KEY_CHANNEL },
+	{ 0x1e14, KEY_UP },
+	{ 0x1e15, KEY_DOWN },
+	{ 0x1e16, KEY_LEFT },
+	{ 0x1e17, KEY_RIGHT },
+	{ 0x1e18, KEY_VIDEO },
+	{ 0x1e19, KEY_AUDIO },
+	{ 0x1e1a, KEY_MEDIA },
+	{ 0x1e1b, KEY_EPG },
+	{ 0x1e1c, KEY_TV },
+	{ 0x1e1e, KEY_NEXT },
+	{ 0x1e1f, KEY_BACK },
+	{ 0x1e20, KEY_CHANNELUP },
+	{ 0x1e21, KEY_CHANNELDOWN },
+	{ 0x1e24, KEY_LAST }, /* Skip backwards */
+	{ 0x1e25, KEY_OK },
+	{ 0x1e29, KEY_BLUE},
+	{ 0x1e2e, KEY_GREEN },
+	{ 0x1e30, KEY_PAUSE },
+	{ 0x1e32, KEY_REWIND },
+	{ 0x1e34, KEY_FASTFORWARD },
+	{ 0x1e35, KEY_PLAY },
+	{ 0x1e36, KEY_STOP },
+	{ 0x1e37, KEY_RECORD },
+	{ 0x1e38, KEY_YELLOW },
+	{ 0x1e3b, KEY_GOTO },
+	{ 0x1e3d, KEY_POWER },
 
 	/* Key codes for the Leadtek Winfast DTV Dongle */
-	{ 0x00, 0x42, KEY_POWER },
-	{ 0x07, 0x7c, KEY_TUNER },
-	{ 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */
-	{ 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/
-	{ 0x0f, 0x71, KEY_DOT }, /* frequency */
-	{ 0x07, 0x43, KEY_0 },
-	{ 0x0c, 0x41, KEY_1 },
-	{ 0x04, 0x43, KEY_2 },
-	{ 0x0b, 0x7f, KEY_3 },
-	{ 0x0e, 0x41, KEY_4 },
-	{ 0x06, 0x43, KEY_5 },
-	{ 0x09, 0x7f, KEY_6 },
-	{ 0x0d, 0x7e, KEY_7 },
-	{ 0x05, 0x7c, KEY_8 },
-	{ 0x0a, 0x40, KEY_9 },
-	{ 0x0e, 0x4e, KEY_CLEAR },
-	{ 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */
-	{ 0x0f, 0x41, KEY_LAST }, /* recall */
-	{ 0x03, 0x42, KEY_MUTE },
-	{ 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/
-	{ 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */
-	{ 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
-	{ 0x0b, 0x70, KEY_RECORD },
-	{ 0x03, 0x7d, KEY_VOLUMEUP },
-	{ 0x01, 0x7d, KEY_VOLUMEDOWN },
-	{ 0x02, 0x42, KEY_CHANNELUP },
-	{ 0x00, 0x7d, KEY_CHANNELDOWN },
+	{ 0x0042, KEY_POWER },
+	{ 0x077c, KEY_TUNER },
+	{ 0x0f4e, KEY_PRINT }, /* PREVIEW */
+	{ 0x0840, KEY_SCREEN }, /* full screen toggle*/
+	{ 0x0f71, KEY_DOT }, /* frequency */
+	{ 0x0743, KEY_0 },
+	{ 0x0c41, KEY_1 },
+	{ 0x0443, KEY_2 },
+	{ 0x0b7f, KEY_3 },
+	{ 0x0e41, KEY_4 },
+	{ 0x0643, KEY_5 },
+	{ 0x097f, KEY_6 },
+	{ 0x0d7e, KEY_7 },
+	{ 0x057c, KEY_8 },
+	{ 0x0a40, KEY_9 },
+	{ 0x0e4e, KEY_CLEAR },
+	{ 0x047c, KEY_CHANNEL }, /* show channel number */
+	{ 0x0f41, KEY_LAST }, /* recall */
+	{ 0x0342, KEY_MUTE },
+	{ 0x064c, KEY_RESERVED }, /* PIP button*/
+	{ 0x0172, KEY_SHUFFLE }, /* SNAPSHOT */
+	{ 0x0c4e, KEY_PLAYPAUSE }, /* TIMESHIFT */
+	{ 0x0b70, KEY_RECORD },
+	{ 0x037d, KEY_VOLUMEUP },
+	{ 0x017d, KEY_VOLUMEDOWN },
+	{ 0x0242, KEY_CHANNELUP },
+	{ 0x007d, KEY_CHANNELDOWN },
 
 	/* Key codes for Nova-TD "credit card" remote control. */
-	{ 0x1d, 0x00, KEY_0 },
-	{ 0x1d, 0x01, KEY_1 },
-	{ 0x1d, 0x02, KEY_2 },
-	{ 0x1d, 0x03, KEY_3 },
-	{ 0x1d, 0x04, KEY_4 },
-	{ 0x1d, 0x05, KEY_5 },
-	{ 0x1d, 0x06, KEY_6 },
-	{ 0x1d, 0x07, KEY_7 },
-	{ 0x1d, 0x08, KEY_8 },
-	{ 0x1d, 0x09, KEY_9 },
-	{ 0x1d, 0x0a, KEY_TEXT },
-	{ 0x1d, 0x0d, KEY_MENU },
-	{ 0x1d, 0x0f, KEY_MUTE },
-	{ 0x1d, 0x10, KEY_VOLUMEUP },
-	{ 0x1d, 0x11, KEY_VOLUMEDOWN },
-	{ 0x1d, 0x12, KEY_CHANNEL },
-	{ 0x1d, 0x14, KEY_UP },
-	{ 0x1d, 0x15, KEY_DOWN },
-	{ 0x1d, 0x16, KEY_LEFT },
-	{ 0x1d, 0x17, KEY_RIGHT },
-	{ 0x1d, 0x1c, KEY_TV },
-	{ 0x1d, 0x1e, KEY_NEXT },
-	{ 0x1d, 0x1f, KEY_BACK },
-	{ 0x1d, 0x20, KEY_CHANNELUP },
-	{ 0x1d, 0x21, KEY_CHANNELDOWN },
-	{ 0x1d, 0x24, KEY_LAST },
-	{ 0x1d, 0x25, KEY_OK },
-	{ 0x1d, 0x30, KEY_PAUSE },
-	{ 0x1d, 0x32, KEY_REWIND },
-	{ 0x1d, 0x34, KEY_FASTFORWARD },
-	{ 0x1d, 0x35, KEY_PLAY },
-	{ 0x1d, 0x36, KEY_STOP },
-	{ 0x1d, 0x37, KEY_RECORD },
-	{ 0x1d, 0x3b, KEY_GOTO },
-	{ 0x1d, 0x3d, KEY_POWER },
+	{ 0x1d00, KEY_0 },
+	{ 0x1d01, KEY_1 },
+	{ 0x1d02, KEY_2 },
+	{ 0x1d03, KEY_3 },
+	{ 0x1d04, KEY_4 },
+	{ 0x1d05, KEY_5 },
+	{ 0x1d06, KEY_6 },
+	{ 0x1d07, KEY_7 },
+	{ 0x1d08, KEY_8 },
+	{ 0x1d09, KEY_9 },
+	{ 0x1d0a, KEY_TEXT },
+	{ 0x1d0d, KEY_MENU },
+	{ 0x1d0f, KEY_MUTE },
+	{ 0x1d10, KEY_VOLUMEUP },
+	{ 0x1d11, KEY_VOLUMEDOWN },
+	{ 0x1d12, KEY_CHANNEL },
+	{ 0x1d14, KEY_UP },
+	{ 0x1d15, KEY_DOWN },
+	{ 0x1d16, KEY_LEFT },
+	{ 0x1d17, KEY_RIGHT },
+	{ 0x1d1c, KEY_TV },
+	{ 0x1d1e, KEY_NEXT },
+	{ 0x1d1f, KEY_BACK },
+	{ 0x1d20, KEY_CHANNELUP },
+	{ 0x1d21, KEY_CHANNELDOWN },
+	{ 0x1d24, KEY_LAST },
+	{ 0x1d25, KEY_OK },
+	{ 0x1d30, KEY_PAUSE },
+	{ 0x1d32, KEY_REWIND },
+	{ 0x1d34, KEY_FASTFORWARD },
+	{ 0x1d35, KEY_PLAY },
+	{ 0x1d36, KEY_STOP },
+	{ 0x1d37, KEY_RECORD },
+	{ 0x1d3b, KEY_GOTO },
+	{ 0x1d3d, KEY_POWER },
 };
 
 /* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
@@ -1096,11 +1099,13 @@ static struct dibx000_agc_config dib7070_agc_config = {
 
 static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
 {
+	deb_info("reset: %d", onoff);
 	return dib7000p_set_gpio(fe, 8, 0, !onoff);
 }
 
 static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
 {
+	deb_info("sleep: %d", onoff);
 	return dib7000p_set_gpio(fe, 9, 0, onoff);
 }
 
@@ -1110,16 +1115,26 @@ static struct dib0070_config dib7070p_dib0070_config[2] = {
 		.reset = dib7070_tuner_reset,
 		.sleep = dib7070_tuner_sleep,
 		.clock_khz = 12000,
-		.clock_pad_drive = 4
+		.clock_pad_drive = 4,
+		.charge_pump = 2,
 	}, {
 		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
 		.reset = dib7070_tuner_reset,
 		.sleep = dib7070_tuner_sleep,
 		.clock_khz = 12000,
-
+		.charge_pump = 2,
 	}
 };
 
+static struct dib0070_config dib7770p_dib0070_config = {
+	 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+	 .reset = dib7070_tuner_reset,
+	 .sleep = dib7070_tuner_sleep,
+	 .clock_khz = 12000,
+	 .clock_pad_drive = 0,
+	 .flip_chip = 1,
+};
+
 static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
 {
 	struct dvb_usb_adapter *adap = fe->dvb->priv;
@@ -1137,6 +1152,45 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_fronte
 	return state->set_param_save(fe, fep);
 }
 
+static int dib7770_set_param_override(struct dvb_frontend *fe,
+		struct dvb_frontend_parameters *fep)
+{
+	 struct dvb_usb_adapter *adap = fe->dvb->priv;
+	 struct dib0700_adapter_state *state = adap->priv;
+
+	 u16 offset;
+	 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+	 switch (band) {
+	 case BAND_VHF:
+		  dib7000p_set_gpio(fe, 0, 0, 1);
+		  offset = 850;
+		  break;
+	 case BAND_UHF:
+	 default:
+		  dib7000p_set_gpio(fe, 0, 0, 0);
+		  offset = 250;
+		  break;
+	 }
+	 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
+	 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
+	 return state->set_param_save(fe, fep);
+}
+
+static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	 struct dib0700_adapter_state *st = adap->priv;
+	 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe,
+			 DIBX000_I2C_INTERFACE_TUNER, 1);
+
+	 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
+				 &dib7770p_dib0070_config) == NULL)
+		 return -ENODEV;
+
+	 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+	 adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
+	 return 0;
+}
+
 static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	struct dib0700_adapter_state *st = adap->priv;
@@ -1215,6 +1269,306 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
 	return adap->fe == NULL ? -ENODEV : 0;
 }
 
+/* DIB807x generic */
+static struct dibx000_agc_config dib807x_agc_config[2] = {
+	{
+		BAND_VHF,
+		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+		 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+		 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
+		 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+		 * P_agc_write=0 */
+		(0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
+			(0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
+			(0 << 0), /* setup*/
+
+		600, /* inv_gain*/
+		10,  /* time_stabiliz*/
+
+		0,  /* alpha_level*/
+		118,  /* thlock*/
+
+		0,     /* wbd_inv*/
+		3530,  /* wbd_ref*/
+		1,     /* wbd_sel*/
+		5,     /* wbd_alpha*/
+
+		65535,  /* agc1_max*/
+		0,  /* agc1_min*/
+
+		65535,  /* agc2_max*/
+		0,      /* agc2_min*/
+
+		0,      /* agc1_pt1*/
+		40,     /* agc1_pt2*/
+		183,    /* agc1_pt3*/
+		206,    /* agc1_slope1*/
+		255,    /* agc1_slope2*/
+		72,     /* agc2_pt1*/
+		152,    /* agc2_pt2*/
+		88,     /* agc2_slope1*/
+		90,     /* agc2_slope2*/
+
+		17,  /* alpha_mant*/
+		27,  /* alpha_exp*/
+		23,  /* beta_mant*/
+		51,  /* beta_exp*/
+
+		0,  /* perform_agc_softsplit*/
+	}, {
+		BAND_UHF,
+		/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
+		 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
+		 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
+		 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
+		 * P_agc_write=0 */
+		(0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
+			(0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
+			(0 << 0), /* setup */
+
+		600, /* inv_gain*/
+		10,  /* time_stabiliz*/
+
+		0,  /* alpha_level*/
+		118,  /* thlock*/
+
+		0,     /* wbd_inv*/
+		3530,  /* wbd_ref*/
+		1,     /* wbd_sel*/
+		5,     /* wbd_alpha*/
+
+		65535,  /* agc1_max*/
+		0,  /* agc1_min*/
+
+		65535,  /* agc2_max*/
+		0,      /* agc2_min*/
+
+		0,      /* agc1_pt1*/
+		40,     /* agc1_pt2*/
+		183,    /* agc1_pt3*/
+		206,    /* agc1_slope1*/
+		255,    /* agc1_slope2*/
+		72,     /* agc2_pt1*/
+		152,    /* agc2_pt2*/
+		88,     /* agc2_slope1*/
+		90,     /* agc2_slope2*/
+
+		17,  /* alpha_mant*/
+		27,  /* alpha_exp*/
+		23,  /* beta_mant*/
+		51,  /* beta_exp*/
+
+		0,  /* perform_agc_softsplit*/
+	}
+};
+
+static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
+	60000, 15000, /* internal, sampling*/
+	1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
+	0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
+			  ADClkSrc, modulo */
+	(3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
+	(0 << 25) | 0, /* ifreq = 0.000000 MHz*/
+	18179755, /* timf*/
+	12000000, /* xtal_hz*/
+};
+
+static struct dib8000_config dib807x_dib8000_config[2] = {
+	{
+		.output_mpeg2_in_188_bytes = 1,
+
+		.agc_config_count = 2,
+		.agc = dib807x_agc_config,
+		.pll = &dib807x_bw_config_12_mhz,
+		.tuner_is_baseband = 1,
+
+		.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+		.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+		.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+		.hostbus_diversity = 1,
+		.div_cfg = 1,
+		.agc_control = &dib0070_ctrl_agc_filter,
+		.output_mode = OUTMODE_MPEG2_FIFO,
+		.drives = 0x2d98,
+	}, {
+		.output_mpeg2_in_188_bytes = 1,
+
+		.agc_config_count = 2,
+		.agc = dib807x_agc_config,
+		.pll = &dib807x_bw_config_12_mhz,
+		.tuner_is_baseband = 1,
+
+		.gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
+		.gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
+		.gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
+
+		.hostbus_diversity = 1,
+		.agc_control = &dib0070_ctrl_agc_filter,
+		.output_mode = OUTMODE_MPEG2_FIFO,
+		.drives = 0x2d98,
+	}
+};
+
+static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
+{
+	return dib8000_set_gpio(fe, 5, 0, !onoff);
+}
+
+static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
+{
+	return dib8000_set_gpio(fe, 0, 0, onoff);
+}
+
+static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
+    { 240,      7},
+    { 0xffff,   6},
+};
+
+static struct dib0070_config dib807x_dib0070_config[2] = {
+	{
+		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+		.reset = dib807x_tuner_reset,
+		.sleep = dib807x_tuner_sleep,
+		.clock_khz = 12000,
+		.clock_pad_drive = 4,
+		.vga_filter = 1,
+		.force_crystal_mode = 1,
+		.enable_third_order_filter = 1,
+		.charge_pump = 0,
+		.wbd_gain = dib8070_wbd_gain_cfg,
+		.osc_buffer_state = 0,
+		.freq_offset_khz_uhf = -100,
+		.freq_offset_khz_vhf = -100,
+	}, {
+		.i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
+		.reset = dib807x_tuner_reset,
+		.sleep = dib807x_tuner_sleep,
+		.clock_khz = 12000,
+		.clock_pad_drive = 2,
+		.vga_filter = 1,
+		.force_crystal_mode = 1,
+		.enable_third_order_filter = 1,
+		.charge_pump = 0,
+		.wbd_gain = dib8070_wbd_gain_cfg,
+		.osc_buffer_state = 0,
+		.freq_offset_khz_uhf = -25,
+		.freq_offset_khz_vhf = -25,
+	}
+};
+
+static int dib807x_set_param_override(struct dvb_frontend *fe,
+		struct dvb_frontend_parameters *fep)
+{
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct dib0700_adapter_state *state = adap->priv;
+
+	u16 offset = dib0070_wbd_offset(fe);
+	u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
+	switch (band) {
+	case BAND_VHF:
+		offset += 750;
+		break;
+	case BAND_UHF:  /* fall-thru wanted */
+	default:
+		offset += 250; break;
+	}
+	deb_info("WBD for DiB8000: %d\n", offset);
+	dib8000_set_wbd_ref(fe, offset);
+
+	return state->set_param_save(fe, fep);
+}
+
+static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	struct dib0700_adapter_state *st = adap->priv;
+	struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe,
+			DIBX000_I2C_INTERFACE_TUNER, 1);
+
+	if (adap->id == 0) {
+		if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
+				&dib807x_dib0070_config[0]) == NULL)
+			return -ENODEV;
+	} else {
+		if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
+				&dib807x_dib0070_config[1]) == NULL)
+			return -ENODEV;
+	}
+
+	st->set_param_save = adap->fe->ops.tuner_ops.set_params;
+	adap->fe->ops.tuner_ops.set_params = dib807x_set_param_override;
+	return 0;
+}
+
+
+/* STK807x */
+static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+	dib0700_ctrl_clock(adap->dev, 72, 1);
+
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+				0x80);
+
+	adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+			      &dib807x_dib8000_config[0]);
+
+	return adap->fe == NULL ?  -ENODEV : 0;
+}
+
+/* STK807xPVR */
+static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
+{
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+	msleep(30);
+	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+	msleep(500);
+	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
+	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
+
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+
+	dib0700_ctrl_clock(adap->dev, 72, 1);
+
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+	msleep(10);
+	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+	/* initialize IC 0 */
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
+
+	adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
+			      &dib807x_dib8000_config[0]);
+
+	return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
+{
+	/* initialize IC 1 */
+	dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
+
+	adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
+			      &dib807x_dib8000_config[1]);
+
+	return adap->fe == NULL ? -ENODEV : 0;
+}
+
+
 /* STK7070PD */
 static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
 	{
@@ -1497,6 +1851,16 @@ struct usb_device_id dib0700_usb_id_table[] = {
 	{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_H) },
 	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_T3) },
 	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_T5) },
+	{ USB_DEVICE(USB_VID_YUAN,      USB_PID_YUAN_STK7700D) },
+/* 55 */{ USB_DEVICE(USB_VID_YUAN,	USB_PID_YUAN_STK7700D_2) },
+	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV73A) },
+	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV73ESE) },
+	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV282E) },
+	{ USB_DEVICE(USB_VID_DIBCOM,	USB_PID_DIBCOM_STK7770P) },
+/* 60 */{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_T_XXS_2) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XPVR) },
+	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK807XP) },
+	{ USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1561,7 +1925,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				{ NULL },
 			},
 			{   "Leadtek Winfast DTV Dongle (STK7700P based)",
-				{ &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
+				{ &dib0700_usb_id_table[8] },
 				{ NULL },
 			},
 			{   "AVerMedia AVerTV DVB-T Express",
@@ -1624,7 +1988,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			}
 		},
 
-		.num_device_descs = 4,
+		.num_device_descs = 5,
 		.devices = {
 			{   "Pinnacle PCTV 2000e",
 				{ &dib0700_usb_id_table[11], NULL },
@@ -1642,6 +2006,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				{ &dib0700_usb_id_table[14], NULL },
 				{ NULL },
 			},
+			{   "YUAN High-Tech DiBcom STK7700D",
+				{ &dib0700_usb_id_table[55], NULL },
+				{ NULL },
+			},
 
 		},
 
@@ -1756,6 +2124,41 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 
 	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
 
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.frontend_attach  = stk7070p_frontend_attach,
+				.tuner_attach     = dib7070p_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				.size_of_priv     = sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 3,
+		.devices = {
+			{   "Pinnacle PCTV 73A",
+				{ &dib0700_usb_id_table[56], NULL },
+				{ NULL },
+			},
+			{   "Pinnacle PCTV 73e SE",
+				{ &dib0700_usb_id_table[57], NULL },
+				{ NULL },
+			},
+			{   "Pinnacle PCTV 282e",
+				{ &dib0700_usb_id_table[58], NULL },
+				{ NULL },
+			},
+		},
+
+		.rc_interval      = DEFAULT_RC_INTERVAL,
+		.rc_key_map       = dib0700_rc_keys,
+		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+		.rc_query         = dib0700_rc_query
+
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
 		.num_adapters = 2,
 		.adapter = {
 			{
@@ -1822,7 +2225,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 			},
 		},
 
-		.num_device_descs = 8,
+		.num_device_descs = 9,
 		.devices = {
 			{   "Terratec Cinergy HT USB XE",
 				{ &dib0700_usb_id_table[27], NULL },
@@ -1856,7 +2259,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				{ &dib0700_usb_id_table[51], NULL },
 				{ NULL },
 			},
-
+			{   "YUAN High-Tech STK7700D",
+				{ &dib0700_usb_id_table[54], NULL },
+				{ NULL },
+			},
 		},
 		.rc_interval      = DEFAULT_RC_INTERVAL,
 		.rc_key_map       = dib0700_rc_keys,
@@ -1916,6 +2322,102 @@ struct dvb_usb_device_properties dib0700_devices[] = {
 				{ NULL },
 			},
 		},
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.frontend_attach  = stk7070p_frontend_attach,
+				.tuner_attach     = dib7770p_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 2,
+		.devices = {
+			{   "DiBcom STK7770P reference design",
+				{ &dib0700_usb_id_table[59], NULL },
+				{ NULL },
+			},
+			{   "Terratec Cinergy T USB XXS (HD)",
+				{ &dib0700_usb_id_table[34], &dib0700_usb_id_table[60] },
+				{ NULL },
+			},
+		},
+		.rc_interval      = DEFAULT_RC_INTERVAL,
+		.rc_key_map       = dib0700_rc_keys,
+		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+		.rc_query         = dib0700_rc_query
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 1,
+		.adapter = {
+			{
+				.frontend_attach  = stk807x_frontend_attach,
+				.tuner_attach     = dib807x_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 2,
+		.devices = {
+			{   "DiBcom STK807xP reference design",
+				{ &dib0700_usb_id_table[62], NULL },
+				{ NULL },
+			},
+			{   "Prolink Pixelview SBTVD",
+				{ &dib0700_usb_id_table[63], NULL },
+				{ NULL },
+			},
+		},
+
+		.rc_interval      = DEFAULT_RC_INTERVAL,
+		.rc_key_map       = dib0700_rc_keys,
+		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+		.rc_query         = dib0700_rc_query
+
+	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+		.num_adapters = 2,
+		.adapter = {
+			{
+				.frontend_attach  = stk807xpvr_frontend_attach0,
+				.tuner_attach     = dib807x_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+			{
+				.frontend_attach  = stk807xpvr_frontend_attach1,
+				.tuner_attach     = dib807x_tuner_attach,
+
+				DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
+
+				.size_of_priv =
+					sizeof(struct dib0700_adapter_state),
+			},
+		},
+
+		.num_device_descs = 1,
+		.devices = {
+			{   "DiBcom STK807xPVR reference design",
+				{ &dib0700_usb_id_table[61], NULL },
+				{ NULL },
+			},
+		},
+
+		.rc_interval      = DEFAULT_RC_INTERVAL,
+		.rc_key_map       = dib0700_rc_keys,
+		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
+		.rc_query         = dib0700_rc_query
 	},
 };
 
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 8dbad1e..da34979 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -318,132 +318,132 @@ EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
  */
 struct dvb_usb_rc_key dibusb_rc_keys[] = {
 	/* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
-	{ 0x00, 0x16, KEY_POWER },
-	{ 0x00, 0x10, KEY_MUTE },
-	{ 0x00, 0x03, KEY_1 },
-	{ 0x00, 0x01, KEY_2 },
-	{ 0x00, 0x06, KEY_3 },
-	{ 0x00, 0x09, KEY_4 },
-	{ 0x00, 0x1d, KEY_5 },
-	{ 0x00, 0x1f, KEY_6 },
-	{ 0x00, 0x0d, KEY_7 },
-	{ 0x00, 0x19, KEY_8 },
-	{ 0x00, 0x1b, KEY_9 },
-	{ 0x00, 0x15, KEY_0 },
-	{ 0x00, 0x05, KEY_CHANNELUP },
-	{ 0x00, 0x02, KEY_CHANNELDOWN },
-	{ 0x00, 0x1e, KEY_VOLUMEUP },
-	{ 0x00, 0x0a, KEY_VOLUMEDOWN },
-	{ 0x00, 0x11, KEY_RECORD },
-	{ 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
-	{ 0x00, 0x14, KEY_PLAY },
-	{ 0x00, 0x1a, KEY_STOP },
-	{ 0x00, 0x40, KEY_REWIND },
-	{ 0x00, 0x12, KEY_FASTFORWARD },
-	{ 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
-	{ 0x00, 0x4c, KEY_PAUSE },
-	{ 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
-	{ 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+	{ 0x0016, KEY_POWER },
+	{ 0x0010, KEY_MUTE },
+	{ 0x0003, KEY_1 },
+	{ 0x0001, KEY_2 },
+	{ 0x0006, KEY_3 },
+	{ 0x0009, KEY_4 },
+	{ 0x001d, KEY_5 },
+	{ 0x001f, KEY_6 },
+	{ 0x000d, KEY_7 },
+	{ 0x0019, KEY_8 },
+	{ 0x001b, KEY_9 },
+	{ 0x0015, KEY_0 },
+	{ 0x0005, KEY_CHANNELUP },
+	{ 0x0002, KEY_CHANNELDOWN },
+	{ 0x001e, KEY_VOLUMEUP },
+	{ 0x000a, KEY_VOLUMEDOWN },
+	{ 0x0011, KEY_RECORD },
+	{ 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+	{ 0x0014, KEY_PLAY },
+	{ 0x001a, KEY_STOP },
+	{ 0x0040, KEY_REWIND },
+	{ 0x0012, KEY_FASTFORWARD },
+	{ 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+	{ 0x004c, KEY_PAUSE },
+	{ 0x004d, KEY_SCREEN }, /* Full screen mode. */
+	{ 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
 	/* additional keys TwinHan VisionPlus, the Artec seemingly not have */
-	{ 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
-	{ 0x00, 0x1c, KEY_EPG }, /* EPG */
-	{ 0x00, 0x00, KEY_TAB }, /* Tab */
-	{ 0x00, 0x48, KEY_INFO }, /* Preview */
-	{ 0x00, 0x04, KEY_LIST }, /* RecordList */
-	{ 0x00, 0x0f, KEY_TEXT }, /* Teletext */
+	{ 0x000c, KEY_CANCEL }, /* Cancel */
+	{ 0x001c, KEY_EPG }, /* EPG */
+	{ 0x0000, KEY_TAB }, /* Tab */
+	{ 0x0048, KEY_INFO }, /* Preview */
+	{ 0x0004, KEY_LIST }, /* RecordList */
+	{ 0x000f, KEY_TEXT }, /* Teletext */
 	/* Key codes for the KWorld/ADSTech/JetWay remote. */
-	{ 0x86, 0x12, KEY_POWER },
-	{ 0x86, 0x0f, KEY_SELECT }, /* source */
-	{ 0x86, 0x0c, KEY_UNKNOWN }, /* scan */
-	{ 0x86, 0x0b, KEY_EPG },
-	{ 0x86, 0x10, KEY_MUTE },
-	{ 0x86, 0x01, KEY_1 },
-	{ 0x86, 0x02, KEY_2 },
-	{ 0x86, 0x03, KEY_3 },
-	{ 0x86, 0x04, KEY_4 },
-	{ 0x86, 0x05, KEY_5 },
-	{ 0x86, 0x06, KEY_6 },
-	{ 0x86, 0x07, KEY_7 },
-	{ 0x86, 0x08, KEY_8 },
-	{ 0x86, 0x09, KEY_9 },
-	{ 0x86, 0x0a, KEY_0 },
-	{ 0x86, 0x18, KEY_ZOOM },
-	{ 0x86, 0x1c, KEY_UNKNOWN }, /* preview */
-	{ 0x86, 0x13, KEY_UNKNOWN }, /* snap */
-	{ 0x86, 0x00, KEY_UNDO },
-	{ 0x86, 0x1d, KEY_RECORD },
-	{ 0x86, 0x0d, KEY_STOP },
-	{ 0x86, 0x0e, KEY_PAUSE },
-	{ 0x86, 0x16, KEY_PLAY },
-	{ 0x86, 0x11, KEY_BACK },
-	{ 0x86, 0x19, KEY_FORWARD },
-	{ 0x86, 0x14, KEY_UNKNOWN }, /* pip */
-	{ 0x86, 0x15, KEY_ESC },
-	{ 0x86, 0x1a, KEY_UP },
-	{ 0x86, 0x1e, KEY_DOWN },
-	{ 0x86, 0x1f, KEY_LEFT },
-	{ 0x86, 0x1b, KEY_RIGHT },
+	{ 0x8612, KEY_POWER },
+	{ 0x860f, KEY_SELECT }, /* source */
+	{ 0x860c, KEY_UNKNOWN }, /* scan */
+	{ 0x860b, KEY_EPG },
+	{ 0x8610, KEY_MUTE },
+	{ 0x8601, KEY_1 },
+	{ 0x8602, KEY_2 },
+	{ 0x8603, KEY_3 },
+	{ 0x8604, KEY_4 },
+	{ 0x8605, KEY_5 },
+	{ 0x8606, KEY_6 },
+	{ 0x8607, KEY_7 },
+	{ 0x8608, KEY_8 },
+	{ 0x8609, KEY_9 },
+	{ 0x860a, KEY_0 },
+	{ 0x8618, KEY_ZOOM },
+	{ 0x861c, KEY_UNKNOWN }, /* preview */
+	{ 0x8613, KEY_UNKNOWN }, /* snap */
+	{ 0x8600, KEY_UNDO },
+	{ 0x861d, KEY_RECORD },
+	{ 0x860d, KEY_STOP },
+	{ 0x860e, KEY_PAUSE },
+	{ 0x8616, KEY_PLAY },
+	{ 0x8611, KEY_BACK },
+	{ 0x8619, KEY_FORWARD },
+	{ 0x8614, KEY_UNKNOWN }, /* pip */
+	{ 0x8615, KEY_ESC },
+	{ 0x861a, KEY_UP },
+	{ 0x861e, KEY_DOWN },
+	{ 0x861f, KEY_LEFT },
+	{ 0x861b, KEY_RIGHT },
 
 	/* Key codes for the DiBcom MOD3000 remote. */
-	{ 0x80, 0x00, KEY_MUTE },
-	{ 0x80, 0x01, KEY_TEXT },
-	{ 0x80, 0x02, KEY_HOME },
-	{ 0x80, 0x03, KEY_POWER },
-
-	{ 0x80, 0x04, KEY_RED },
-	{ 0x80, 0x05, KEY_GREEN },
-	{ 0x80, 0x06, KEY_YELLOW },
-	{ 0x80, 0x07, KEY_BLUE },
-
-	{ 0x80, 0x08, KEY_DVD },
-	{ 0x80, 0x09, KEY_AUDIO },
-	{ 0x80, 0x0a, KEY_MEDIA },      /* Pictures */
-	{ 0x80, 0x0b, KEY_VIDEO },
-
-	{ 0x80, 0x0c, KEY_BACK },
-	{ 0x80, 0x0d, KEY_UP },
-	{ 0x80, 0x0e, KEY_RADIO },
-	{ 0x80, 0x0f, KEY_EPG },
-
-	{ 0x80, 0x10, KEY_LEFT },
-	{ 0x80, 0x11, KEY_OK },
-	{ 0x80, 0x12, KEY_RIGHT },
-	{ 0x80, 0x13, KEY_UNKNOWN },    /* SAP */
-
-	{ 0x80, 0x14, KEY_TV },
-	{ 0x80, 0x15, KEY_DOWN },
-	{ 0x80, 0x16, KEY_MENU },       /* DVD Menu */
-	{ 0x80, 0x17, KEY_LAST },
-
-	{ 0x80, 0x18, KEY_RECORD },
-	{ 0x80, 0x19, KEY_STOP },
-	{ 0x80, 0x1a, KEY_PAUSE },
-	{ 0x80, 0x1b, KEY_PLAY },
-
-	{ 0x80, 0x1c, KEY_PREVIOUS },
-	{ 0x80, 0x1d, KEY_REWIND },
-	{ 0x80, 0x1e, KEY_FASTFORWARD },
-	{ 0x80, 0x1f, KEY_NEXT},
-
-	{ 0x80, 0x40, KEY_1 },
-	{ 0x80, 0x41, KEY_2 },
-	{ 0x80, 0x42, KEY_3 },
-	{ 0x80, 0x43, KEY_CHANNELUP },
-
-	{ 0x80, 0x44, KEY_4 },
-	{ 0x80, 0x45, KEY_5 },
-	{ 0x80, 0x46, KEY_6 },
-	{ 0x80, 0x47, KEY_CHANNELDOWN },
-
-	{ 0x80, 0x48, KEY_7 },
-	{ 0x80, 0x49, KEY_8 },
-	{ 0x80, 0x4a, KEY_9 },
-	{ 0x80, 0x4b, KEY_VOLUMEUP },
-
-	{ 0x80, 0x4c, KEY_CLEAR },
-	{ 0x80, 0x4d, KEY_0 },
-	{ 0x80, 0x4e, KEY_ENTER },
-	{ 0x80, 0x4f, KEY_VOLUMEDOWN },
+	{ 0x8000, KEY_MUTE },
+	{ 0x8001, KEY_TEXT },
+	{ 0x8002, KEY_HOME },
+	{ 0x8003, KEY_POWER },
+
+	{ 0x8004, KEY_RED },
+	{ 0x8005, KEY_GREEN },
+	{ 0x8006, KEY_YELLOW },
+	{ 0x8007, KEY_BLUE },
+
+	{ 0x8008, KEY_DVD },
+	{ 0x8009, KEY_AUDIO },
+	{ 0x800a, KEY_MEDIA },      /* Pictures */
+	{ 0x800b, KEY_VIDEO },
+
+	{ 0x800c, KEY_BACK },
+	{ 0x800d, KEY_UP },
+	{ 0x800e, KEY_RADIO },
+	{ 0x800f, KEY_EPG },
+
+	{ 0x8010, KEY_LEFT },
+	{ 0x8011, KEY_OK },
+	{ 0x8012, KEY_RIGHT },
+	{ 0x8013, KEY_UNKNOWN },    /* SAP */
+
+	{ 0x8014, KEY_TV },
+	{ 0x8015, KEY_DOWN },
+	{ 0x8016, KEY_MENU },       /* DVD Menu */
+	{ 0x8017, KEY_LAST },
+
+	{ 0x8018, KEY_RECORD },
+	{ 0x8019, KEY_STOP },
+	{ 0x801a, KEY_PAUSE },
+	{ 0x801b, KEY_PLAY },
+
+	{ 0x801c, KEY_PREVIOUS },
+	{ 0x801d, KEY_REWIND },
+	{ 0x801e, KEY_FASTFORWARD },
+	{ 0x801f, KEY_NEXT},
+
+	{ 0x8040, KEY_1 },
+	{ 0x8041, KEY_2 },
+	{ 0x8042, KEY_3 },
+	{ 0x8043, KEY_CHANNELUP },
+
+	{ 0x8044, KEY_4 },
+	{ 0x8045, KEY_5 },
+	{ 0x8046, KEY_6 },
+	{ 0x8047, KEY_CHANNELDOWN },
+
+	{ 0x8048, KEY_7 },
+	{ 0x8049, KEY_8 },
+	{ 0x804a, KEY_9 },
+	{ 0x804b, KEY_VOLUMEUP },
+
+	{ 0x804c, KEY_CLEAR },
+	{ 0x804d, KEY_0 },
+	{ 0x804e, KEY_ENTER },
+	{ 0x804f, KEY_VOLUMEDOWN },
 };
 EXPORT_SYMBOL(dibusb_rc_keys);
 
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 059cec9..a05b9f8 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -42,6 +42,8 @@ static struct usb_device_id dibusb_dib3000mc_table [] = {
 /* 11 */	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC,	USB_PID_ARTEC_T14_WARM) },
 /* 12 */	{ USB_DEVICE(USB_VID_LEADTEK,		USB_PID_WINFAST_DTV_DONGLE_COLD) },
 /* 13 */	{ USB_DEVICE(USB_VID_LEADTEK,		USB_PID_WINFAST_DTV_DONGLE_WARM) },
+/* 14 */	{ USB_DEVICE(USB_VID_HUMAX_COEX,	USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD) },
+/* 15 */	{ USB_DEVICE(USB_VID_HUMAX_COEX,	USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM) },
 			{ }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
@@ -66,7 +68,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
 	/* parameter for the MPEG2-data transfer */
 			.stream = {
 				.type = USB_BULK,
-				.count = 7,
+				.count = 8,
 				.endpoint = 0x06,
 				.u = {
 					.bulk = {
@@ -88,7 +90,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
 
 	.generic_bulk_ctrl_endpoint = 0x01,
 
-	.num_device_descs = 7,
+	.num_device_descs = 8,
 	.devices = {
 		{   "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
 			{ &dibusb_dib3000mc_table[0], NULL },
@@ -119,6 +121,10 @@ static struct dvb_usb_device_properties dibusb_mc_properties = {
 			{ &dibusb_dib3000mc_table[12], NULL },
 			{ &dibusb_dib3000mc_table[13], NULL },
 		},
+		{   "Humax/Coex DVB-T USB Stick 2.0 High Speed",
+			{ &dibusb_dib3000mc_table[14], NULL },
+			{ &dibusb_dib3000mc_table[15], NULL },
+		},
 		{ NULL },
 	}
 };
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index b545cf3..955147d 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -162,61 +162,61 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
 }
 
 static struct dvb_usb_rc_key digitv_rc_keys[] = {
-	{ 0x5f, 0x55, KEY_0 },
-	{ 0x6f, 0x55, KEY_1 },
-	{ 0x9f, 0x55, KEY_2 },
-	{ 0xaf, 0x55, KEY_3 },
-	{ 0x5f, 0x56, KEY_4 },
-	{ 0x6f, 0x56, KEY_5 },
-	{ 0x9f, 0x56, KEY_6 },
-	{ 0xaf, 0x56, KEY_7 },
-	{ 0x5f, 0x59, KEY_8 },
-	{ 0x6f, 0x59, KEY_9 },
-	{ 0x9f, 0x59, KEY_TV },
-	{ 0xaf, 0x59, KEY_AUX },
-	{ 0x5f, 0x5a, KEY_DVD },
-	{ 0x6f, 0x5a, KEY_POWER },
-	{ 0x9f, 0x5a, KEY_MHP },     /* labelled 'Picture' */
-	{ 0xaf, 0x5a, KEY_AUDIO },
-	{ 0x5f, 0x65, KEY_INFO },
-	{ 0x6f, 0x65, KEY_F13 },     /* 16:9 */
-	{ 0x9f, 0x65, KEY_F14 },     /* 14:9 */
-	{ 0xaf, 0x65, KEY_EPG },
-	{ 0x5f, 0x66, KEY_EXIT },
-	{ 0x6f, 0x66, KEY_MENU },
-	{ 0x9f, 0x66, KEY_UP },
-	{ 0xaf, 0x66, KEY_DOWN },
-	{ 0x5f, 0x69, KEY_LEFT },
-	{ 0x6f, 0x69, KEY_RIGHT },
-	{ 0x9f, 0x69, KEY_ENTER },
-	{ 0xaf, 0x69, KEY_CHANNELUP },
-	{ 0x5f, 0x6a, KEY_CHANNELDOWN },
-	{ 0x6f, 0x6a, KEY_VOLUMEUP },
-	{ 0x9f, 0x6a, KEY_VOLUMEDOWN },
-	{ 0xaf, 0x6a, KEY_RED },
-	{ 0x5f, 0x95, KEY_GREEN },
-	{ 0x6f, 0x95, KEY_YELLOW },
-	{ 0x9f, 0x95, KEY_BLUE },
-	{ 0xaf, 0x95, KEY_SUBTITLE },
-	{ 0x5f, 0x96, KEY_F15 },     /* AD */
-	{ 0x6f, 0x96, KEY_TEXT },
-	{ 0x9f, 0x96, KEY_MUTE },
-	{ 0xaf, 0x96, KEY_REWIND },
-	{ 0x5f, 0x99, KEY_STOP },
-	{ 0x6f, 0x99, KEY_PLAY },
-	{ 0x9f, 0x99, KEY_FASTFORWARD },
-	{ 0xaf, 0x99, KEY_F16 },     /* chapter */
-	{ 0x5f, 0x9a, KEY_PAUSE },
-	{ 0x6f, 0x9a, KEY_PLAY },
-	{ 0x9f, 0x9a, KEY_RECORD },
-	{ 0xaf, 0x9a, KEY_F17 },     /* picture in picture */
-	{ 0x5f, 0xa5, KEY_KPPLUS },  /* zoom in */
-	{ 0x6f, 0xa5, KEY_KPMINUS }, /* zoom out */
-	{ 0x9f, 0xa5, KEY_F18 },     /* capture */
-	{ 0xaf, 0xa5, KEY_F19 },     /* web */
-	{ 0x5f, 0xa6, KEY_EMAIL },
-	{ 0x6f, 0xa6, KEY_PHONE },
-	{ 0x9f, 0xa6, KEY_PC },
+	{ 0x5f55, KEY_0 },
+	{ 0x6f55, KEY_1 },
+	{ 0x9f55, KEY_2 },
+	{ 0xaf55, KEY_3 },
+	{ 0x5f56, KEY_4 },
+	{ 0x6f56, KEY_5 },
+	{ 0x9f56, KEY_6 },
+	{ 0xaf56, KEY_7 },
+	{ 0x5f59, KEY_8 },
+	{ 0x6f59, KEY_9 },
+	{ 0x9f59, KEY_TV },
+	{ 0xaf59, KEY_AUX },
+	{ 0x5f5a, KEY_DVD },
+	{ 0x6f5a, KEY_POWER },
+	{ 0x9f5a, KEY_MHP },     /* labelled 'Picture' */
+	{ 0xaf5a, KEY_AUDIO },
+	{ 0x5f65, KEY_INFO },
+	{ 0x6f65, KEY_F13 },     /* 16:9 */
+	{ 0x9f65, KEY_F14 },     /* 14:9 */
+	{ 0xaf65, KEY_EPG },
+	{ 0x5f66, KEY_EXIT },
+	{ 0x6f66, KEY_MENU },
+	{ 0x9f66, KEY_UP },
+	{ 0xaf66, KEY_DOWN },
+	{ 0x5f69, KEY_LEFT },
+	{ 0x6f69, KEY_RIGHT },
+	{ 0x9f69, KEY_ENTER },
+	{ 0xaf69, KEY_CHANNELUP },
+	{ 0x5f6a, KEY_CHANNELDOWN },
+	{ 0x6f6a, KEY_VOLUMEUP },
+	{ 0x9f6a, KEY_VOLUMEDOWN },
+	{ 0xaf6a, KEY_RED },
+	{ 0x5f95, KEY_GREEN },
+	{ 0x6f95, KEY_YELLOW },
+	{ 0x9f95, KEY_BLUE },
+	{ 0xaf95, KEY_SUBTITLE },
+	{ 0x5f96, KEY_F15 },     /* AD */
+	{ 0x6f96, KEY_TEXT },
+	{ 0x9f96, KEY_MUTE },
+	{ 0xaf96, KEY_REWIND },
+	{ 0x5f99, KEY_STOP },
+	{ 0x6f99, KEY_PLAY },
+	{ 0x9f99, KEY_FASTFORWARD },
+	{ 0xaf99, KEY_F16 },     /* chapter */
+	{ 0x5f9a, KEY_PAUSE },
+	{ 0x6f9a, KEY_PLAY },
+	{ 0x9f9a, KEY_RECORD },
+	{ 0xaf9a, KEY_F17 },     /* picture in picture */
+	{ 0x5fa5, KEY_KPPLUS },  /* zoom in */
+	{ 0x6fa5, KEY_KPMINUS }, /* zoom out */
+	{ 0x9fa5, KEY_F18 },     /* capture */
+	{ 0xafa5, KEY_F19 },     /* web */
+	{ 0x5fa6, KEY_EMAIL },
+	{ 0x6fa6, KEY_PHONE },
+	{ 0x9fa6, KEY_PC },
 };
 
 static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -238,8 +238,8 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	if (key[1] != 0)
 	{
 		  for (i = 0; i < d->props.rc_key_map_size; i++) {
-			if (d->props.rc_key_map[i].custom == key[1] &&
-			    d->props.rc_key_map[i].data == key[2]) {
+			if (rc5_custom(&d->props.rc_key_map[i]) == key[1] &&
+			    rc5_data(&d->props.rc_key_map[i]) == key[2]) {
 				*event = d->props.rc_key_map[i].event;
 				*state = REMOTE_KEY_PRESSED;
 				return 0;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 81a6cbf..a1b12b0 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -58,24 +58,24 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
 /* remote control */
 /* key list for the tiny remote control (Yakumo, don't know about the others) */
 static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
-	{ 0x80, 0x01, KEY_MUTE },
-	{ 0x80, 0x02, KEY_CHANNELDOWN },
-	{ 0x80, 0x03, KEY_VOLUMEDOWN },
-	{ 0x80, 0x04, KEY_1 },
-	{ 0x80, 0x05, KEY_2 },
-	{ 0x80, 0x06, KEY_3 },
-	{ 0x80, 0x07, KEY_4 },
-	{ 0x80, 0x08, KEY_5 },
-	{ 0x80, 0x09, KEY_6 },
-	{ 0x80, 0x0a, KEY_7 },
-	{ 0x80, 0x0c, KEY_ZOOM },
-	{ 0x80, 0x0d, KEY_0 },
-	{ 0x80, 0x0e, KEY_SELECT },
-	{ 0x80, 0x12, KEY_POWER },
-	{ 0x80, 0x1a, KEY_CHANNELUP },
-	{ 0x80, 0x1b, KEY_8 },
-	{ 0x80, 0x1e, KEY_VOLUMEUP },
-	{ 0x80, 0x1f, KEY_9 },
+	{ 0x8001, KEY_MUTE },
+	{ 0x8002, KEY_CHANNELDOWN },
+	{ 0x8003, KEY_VOLUMEDOWN },
+	{ 0x8004, KEY_1 },
+	{ 0x8005, KEY_2 },
+	{ 0x8006, KEY_3 },
+	{ 0x8007, KEY_4 },
+	{ 0x8008, KEY_5 },
+	{ 0x8009, KEY_6 },
+	{ 0x800a, KEY_7 },
+	{ 0x800c, KEY_ZOOM },
+	{ 0x800d, KEY_0 },
+	{ 0x800e, KEY_SELECT },
+	{ 0x8012, KEY_POWER },
+	{ 0x801a, KEY_CHANNELUP },
+	{ 0x801b, KEY_8 },
+	{ 0x801e, KEY_VOLUMEUP },
+	{ 0x801f, KEY_9 },
 };
 
 static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 326f760..cead089 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
 		return -EINVAL;
 	}
 
-	strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
+	strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
 	d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
 	d->i2c_adap.algo      = d->props.i2c_algo;
 	d->i2c_adap.algo_data = NULL;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 9593b72..a548c14 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -46,6 +46,7 @@
 #define USB_VID_MSI_2				0x1462
 #define USB_VID_OPERA1				0x695c
 #define USB_VID_PINNACLE			0x2304
+#define USB_VID_PIXELVIEW			0x1554
 #define USB_VID_TECHNOTREND			0x0b48
 #define USB_VID_TERRATEC			0x0ccd
 #define USB_VID_TELESTAR			0x10b9
@@ -58,6 +59,8 @@
 #define USB_VID_GIGABYTE			0x1044
 #define USB_VID_YUAN				0x1164
 #define USB_VID_XTENSIONS			0x1ae7
+#define USB_VID_HUMAX_COEX			0x10b9
+#define USB_VID_774				0x7a69
 
 /* Product IDs */
 #define USB_PID_ADSTECH_USB2_COLD			0xa333
@@ -94,7 +97,10 @@
 #define USB_PID_DIBCOM_STK7700_U7000			0x7001
 #define USB_PID_DIBCOM_STK7070P				0x1ebc
 #define USB_PID_DIBCOM_STK7070PD			0x1ebe
+#define USB_PID_DIBCOM_STK807XP				0x1f90
+#define USB_PID_DIBCOM_STK807XPVR			0x1f98
 #define USB_PID_DIBCOM_ANCHOR_2135_COLD			0x2131
+#define USB_PID_DIBCOM_STK7770P				0x1e80
 #define USB_PID_DPOSH_M9206_COLD			0x9206
 #define USB_PID_DPOSH_M9206_WARM			0xa090
 #define USB_PID_UNIWILL_STK7700P			0x6003
@@ -103,6 +109,7 @@
 #define USB_PID_GRANDTEC_DVBT_USB_WARM			0x0fa1
 #define USB_PID_INTEL_CE9500				0x9500
 #define USB_PID_KWORLD_399U				0xe399
+#define USB_PID_KWORLD_399U_2				0xe400
 #define USB_PID_KWORLD_395U				0xe396
 #define USB_PID_KWORLD_395U_2				0xe39b
 #define USB_PID_KWORLD_395U_3				0xe395
@@ -182,6 +189,7 @@
 #define USB_PID_TERRATEC_CINERGY_HT_EXPRESS		0x0060
 #define USB_PID_TERRATEC_CINERGY_T_EXPRESS		0x0062
 #define USB_PID_TERRATEC_CINERGY_T_XXS			0x0078
+#define USB_PID_TERRATEC_CINERGY_T_XXS_2		0x00ab
 #define USB_PID_TERRATEC_T3				0x10a0
 #define USB_PID_TERRATEC_T5				0x10a1
 #define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
@@ -193,6 +201,10 @@
 #define USB_PID_PINNACLE_PCTV73E			0x0237
 #define USB_PID_PINNACLE_PCTV801E			0x023a
 #define USB_PID_PINNACLE_PCTV801E_SE			0x023b
+#define USB_PID_PINNACLE_PCTV73A			0x0243
+#define USB_PID_PINNACLE_PCTV73ESE			0x0245
+#define USB_PID_PINNACLE_PCTV282E			0x0248
+#define USB_PID_PIXELVIEW_SBTVD				0x5010
 #define USB_PID_PCTV_200E				0x020e
 #define USB_PID_PCTV_400E				0x020f
 #define USB_PID_PCTV_450E				0x0222
@@ -252,6 +264,8 @@
 #define USB_PID_YUAN_STK7700PH				0x1f08
 #define USB_PID_YUAN_PD378S				0x2edc
 #define USB_PID_YUAN_MC770				0x0871
+#define USB_PID_YUAN_STK7700D				0x1efc
+#define USB_PID_YUAN_STK7700D_2				0x1e8c
 #define USB_PID_DW2102					0x2102
 #define USB_PID_XTENSIONS_XD_380			0x0381
 #define USB_PID_TELESTAR_STARSTICK_2			0x8000
@@ -259,5 +273,8 @@
 #define USB_PID_SONY_PLAYTV				0x0003
 #define USB_PID_ELGATO_EYETV_DTT			0x0021
 #define USB_PID_ELGATO_EYETV_DTT_Dlx			0x0020
+#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD		0x5000
+#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM		0x5001
+#define USB_PID_FRIIO_WHITE				0x0001
 
 #endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index c0c2c22..edde87c 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -8,6 +8,71 @@
 #include "dvb-usb-common.h"
 #include <linux/usb/input.h>
 
+static int dvb_usb_getkeycode(struct input_dev *dev,
+				    int scancode, int *keycode)
+{
+	struct dvb_usb_device *d = input_get_drvdata(dev);
+
+	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+	int i;
+
+	/* See if we can match the raw key code. */
+	for (i = 0; i < d->props.rc_key_map_size; i++)
+		if (keymap[i].scan == scancode) {
+			*keycode = keymap[i].event;
+			return 0;
+		}
+
+	/*
+	 * If is there extra space, returns KEY_RESERVED,
+	 * otherwise, input core won't let dvb_usb_setkeycode
+	 * to work
+	 */
+	for (i = 0; i < d->props.rc_key_map_size; i++)
+		if (keymap[i].event == KEY_RESERVED ||
+		    keymap[i].event == KEY_UNKNOWN) {
+			*keycode = KEY_RESERVED;
+			return 0;
+		}
+
+	return -EINVAL;
+}
+
+static int dvb_usb_setkeycode(struct input_dev *dev,
+				    int scancode, int keycode)
+{
+	struct dvb_usb_device *d = input_get_drvdata(dev);
+
+	struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+	int i;
+
+	/* Search if it is replacing an existing keycode */
+	for (i = 0; i < d->props.rc_key_map_size; i++)
+		if (keymap[i].scan == scancode) {
+			keymap[i].event = keycode;
+			return 0;
+		}
+
+	/* Search if is there a clean entry. If so, use it */
+	for (i = 0; i < d->props.rc_key_map_size; i++)
+		if (keymap[i].event == KEY_RESERVED ||
+		    keymap[i].event == KEY_UNKNOWN) {
+			keymap[i].scan = scancode;
+			keymap[i].event = keycode;
+			return 0;
+		}
+
+	/*
+	 * FIXME: Currently, it is not possible to increase the size of
+	 * scancode table. For it to happen, one possibility
+	 * would be to allocate a table with key_map_size + 1,
+	 * copying data, appending the new key on it, and freeing
+	 * the old one - or maybe just allocating some spare space
+	 */
+
+	return -EINVAL;
+}
+
 /* Remote-control poll function - called every dib->rc_query_interval ms to see
  * whether the remote control has received anything.
  *
@@ -111,6 +176,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
 	input_dev->phys = d->rc_phys;
 	usb_to_input_id(d->udev, &input_dev->id);
 	input_dev->dev.parent = &d->udev->dev;
+	input_dev->getkeycode = dvb_usb_getkeycode;
+	input_dev->setkeycode = dvb_usb_setkeycode;
 
 	/* set the bits for the keys */
 	deb_rc("key map size: %d\n", d->props.rc_key_map_size);
@@ -128,6 +195,8 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
 	input_dev->rep[REP_PERIOD] = d->props.rc_interval;
 	input_dev->rep[REP_DELAY]  = d->props.rc_interval + 150;
 
+	input_set_drvdata(input_dev, d);
+
 	err = input_register_device(input_dev);
 	if (err) {
 		input_free_device(input_dev);
@@ -178,8 +247,8 @@ int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
 			}
 			/* See if we can match the raw key code. */
 			for (i = 0; i < d->props.rc_key_map_size; i++)
-				if (keymap[i].custom == keybuf[1] &&
-					keymap[i].data == keybuf[3]) {
+				if (rc5_custom(&keymap[i]) == keybuf[1] &&
+					rc5_data(&keymap[i]) == keybuf[3]) {
 					*event = keymap[i].event;
 					*state = REMOTE_KEY_PRESSED;
 					return 0;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index e441d27..fe2b87e 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -81,10 +81,25 @@ struct dvb_usb_device_description {
  * @event: the input event assigned to key identified by custom and data
  */
 struct dvb_usb_rc_key {
-	u8 custom,data;
+	u16 scan;
 	u32 event;
 };
 
+static inline u8 rc5_custom(struct dvb_usb_rc_key *key)
+{
+	return (key->scan >> 8) & 0xff;
+}
+
+static inline u8 rc5_data(struct dvb_usb_rc_key *key)
+{
+	return key->scan & 0xff;
+}
+
+static inline u8 rc5_scan(struct dvb_usb_rc_key *key)
+{
+	return key->scan & 0xffff;
+}
+
 struct dvb_usb_device;
 struct dvb_usb_adapter;
 struct usb_data_stream;
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 75de49c..5bb9479 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,6 +1,6 @@
 /* DVB USB framework compliant Linux driver for the
 *	DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
-*	TeVii S600, S650 Cards
+*	TeVii S600, S630, S650 Cards
 * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by)
 *
 *	This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,8 @@
 #include "eds1547.h"
 #include "cx24116.h"
 #include "tda1002x.h"
+#include "mt312.h"
+#include "zl10039.h"
 
 #ifndef USB_PID_DW2102
 #define USB_PID_DW2102 0x2102
@@ -39,6 +41,10 @@
 #define USB_PID_TEVII_S650 0xd650
 #endif
 
+#ifndef USB_PID_TEVII_S630
+#define USB_PID_TEVII_S630 0xd630
+#endif
+
 #define DW210X_READ_MSG 0
 #define DW210X_WRITE_MSG 1
 
@@ -436,6 +442,69 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
 	return num;
 }
 
+static int s630_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+								int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int ret = 0;
+
+	if (!d)
+		return -ENODEV;
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	switch (num) {
+	case 2: { /* read */
+		u8 ibuf[msg[1].len], obuf[3];
+		obuf[0] = msg[1].len;
+		obuf[1] = (msg[0].addr << 1);
+		obuf[2] = msg[0].buf[0];
+
+		ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
+					obuf, 3, DW210X_WRITE_MSG);
+		msleep(5);
+		ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
+					ibuf, msg[1].len, DW210X_READ_MSG);
+		memcpy(msg[1].buf, ibuf, msg[1].len);
+		break;
+	}
+	case 1:
+		switch (msg[0].addr) {
+		case 0x60:
+		case 0x0e: {
+			/* write to zl10313, zl10039 register, */
+			u8 obuf[msg[0].len + 2];
+			obuf[0] = msg[0].len + 1;
+			obuf[1] = (msg[0].addr << 1);
+			memcpy(obuf + 2, msg[0].buf, msg[0].len);
+			ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
+					obuf, msg[0].len + 2, DW210X_WRITE_MSG);
+			break;
+		}
+		case (DW2102_RC_QUERY): {
+			u8 ibuf[4];
+			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0,
+					ibuf, 4, DW210X_READ_MSG);
+			msg[0].buf[0] = ibuf[3];
+			break;
+		}
+		case (DW2102_VOLTAGE_CTRL): {
+			u8 obuf[2];
+			obuf[0] = 0x03;
+			obuf[1] = msg[0].buf[0];
+			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
+					obuf, 2, DW210X_WRITE_MSG);
+			break;
+		}
+		}
+
+		break;
+	}
+
+	mutex_unlock(&d->i2c_mutex);
+	return num;
+}
+
 static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
 {
 	return I2C_FUNC_I2C;
@@ -466,6 +535,11 @@ static struct i2c_algorithm dw3101_i2c_algo = {
 	.functionality = dw210x_i2c_func,
 };
 
+static struct i2c_algorithm s630_i2c_algo = {
+	.master_xfer = s630_i2c_transfer,
+	.functionality = dw210x_i2c_func,
+};
+
 static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 {
 	int i;
@@ -490,6 +564,37 @@ static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
 	return 0;
 };
 
+static int s630_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
+{
+	int i, ret;
+	u8 buf[3], eeprom[256], eepromline[16];
+
+	for (i = 0; i < 256; i++) {
+		buf[0] = 1;
+		buf[1] = 0xa0;
+		buf[2] = i;
+		ret = dw210x_op_rw(d->udev, 0x90, 0, 0,
+					buf, 3, DW210X_WRITE_MSG);
+		ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
+					buf, 1, DW210X_READ_MSG);
+		if (ret < 0) {
+			err("read eeprom failed.");
+			return -1;
+		} else {
+			eepromline[i % 16] = buf[0];
+			eeprom[i] = buf[0];
+		}
+
+		if ((i % 16) == 15) {
+			deb_xfer("%02x: ", i - 15);
+			debug_dump(eepromline, 16, deb_xfer);
+		}
+	}
+
+	memcpy(mac, eeprom + 16, 6);
+	return 0;
+};
+
 static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 {
 	static u8 command_13v[1] = {0x00};
@@ -535,6 +640,10 @@ static struct tda10023_config dw3101_tda10023_config = {
 	.invert = 1,
 };
 
+static struct mt312_config zl313_config = {
+	.demod_address = 0x0e,
+};
+
 static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
 {
 	if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config,
@@ -596,6 +705,18 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
 	return -EIO;
 }
 
+static int s630_frontend_attach(struct dvb_usb_adapter *d)
+{
+	d->fe = dvb_attach(mt312_attach, &zl313_config,
+				&d->dev->i2c_adap);
+	if (d->fe != NULL) {
+		d->fe->ops.set_voltage = dw210x_set_voltage;
+		info("Attached zl10313!\n");
+		return 0;
+	}
+	return -EIO;
+}
+
 static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -619,123 +740,131 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
 	return 0;
 }
 
+static int s630_zl10039_tuner_attach(struct dvb_usb_adapter *adap)
+{
+	dvb_attach(zl10039_attach, adap->fe, 0x60,
+		&adap->dev->i2c_adap);
+
+	return 0;
+}
+
 static struct dvb_usb_rc_key dw210x_rc_keys[] = {
-	{ 0xf8,	0x0a, KEY_Q },		/*power*/
-	{ 0xf8,	0x0c, KEY_M },		/*mute*/
-	{ 0xf8,	0x11, KEY_1 },
-	{ 0xf8,	0x12, KEY_2 },
-	{ 0xf8,	0x13, KEY_3 },
-	{ 0xf8,	0x14, KEY_4 },
-	{ 0xf8,	0x15, KEY_5 },
-	{ 0xf8,	0x16, KEY_6 },
-	{ 0xf8,	0x17, KEY_7 },
-	{ 0xf8,	0x18, KEY_8 },
-	{ 0xf8,	0x19, KEY_9 },
-	{ 0xf8, 0x10, KEY_0 },
-	{ 0xf8, 0x1c, KEY_PAGEUP },	/*ch+*/
-	{ 0xf8, 0x0f, KEY_PAGEDOWN },	/*ch-*/
-	{ 0xf8, 0x1a, KEY_O },		/*vol+*/
-	{ 0xf8, 0x0e, KEY_Z },		/*vol-*/
-	{ 0xf8, 0x04, KEY_R },		/*rec*/
-	{ 0xf8, 0x09, KEY_D },		/*fav*/
-	{ 0xf8, 0x08, KEY_BACKSPACE },	/*rewind*/
-	{ 0xf8, 0x07, KEY_A },		/*fast*/
-	{ 0xf8, 0x0b, KEY_P },		/*pause*/
-	{ 0xf8, 0x02, KEY_ESC },	/*cancel*/
-	{ 0xf8, 0x03, KEY_G },		/*tab*/
-	{ 0xf8, 0x00, KEY_UP },		/*up*/
-	{ 0xf8, 0x1f, KEY_ENTER },	/*ok*/
-	{ 0xf8, 0x01, KEY_DOWN },	/*down*/
-	{ 0xf8, 0x05, KEY_C },		/*cap*/
-	{ 0xf8, 0x06, KEY_S },		/*stop*/
-	{ 0xf8, 0x40, KEY_F },		/*full*/
-	{ 0xf8, 0x1e, KEY_W },		/*tvmode*/
-	{ 0xf8, 0x1b, KEY_B },		/*recall*/
+	{ 0xf80a, KEY_Q },		/*power*/
+	{ 0xf80c, KEY_M },		/*mute*/
+	{ 0xf811, KEY_1 },
+	{ 0xf812, KEY_2 },
+	{ 0xf813, KEY_3 },
+	{ 0xf814, KEY_4 },
+	{ 0xf815, KEY_5 },
+	{ 0xf816, KEY_6 },
+	{ 0xf817, KEY_7 },
+	{ 0xf818, KEY_8 },
+	{ 0xf819, KEY_9 },
+	{ 0xf810, KEY_0 },
+	{ 0xf81c, KEY_PAGEUP },	/*ch+*/
+	{ 0xf80f, KEY_PAGEDOWN },	/*ch-*/
+	{ 0xf81a, KEY_O },		/*vol+*/
+	{ 0xf80e, KEY_Z },		/*vol-*/
+	{ 0xf804, KEY_R },		/*rec*/
+	{ 0xf809, KEY_D },		/*fav*/
+	{ 0xf808, KEY_BACKSPACE },	/*rewind*/
+	{ 0xf807, KEY_A },		/*fast*/
+	{ 0xf80b, KEY_P },		/*pause*/
+	{ 0xf802, KEY_ESC },	/*cancel*/
+	{ 0xf803, KEY_G },		/*tab*/
+	{ 0xf800, KEY_UP },		/*up*/
+	{ 0xf81f, KEY_ENTER },	/*ok*/
+	{ 0xf801, KEY_DOWN },	/*down*/
+	{ 0xf805, KEY_C },		/*cap*/
+	{ 0xf806, KEY_S },		/*stop*/
+	{ 0xf840, KEY_F },		/*full*/
+	{ 0xf81e, KEY_W },		/*tvmode*/
+	{ 0xf81b, KEY_B },		/*recall*/
 };
 
 static struct dvb_usb_rc_key tevii_rc_keys[] = {
-	{ 0xf8, 0x0a, KEY_POWER },
-	{ 0xf8, 0x0c, KEY_MUTE },
-	{ 0xf8, 0x11, KEY_1 },
-	{ 0xf8, 0x12, KEY_2 },
-	{ 0xf8, 0x13, KEY_3 },
-	{ 0xf8, 0x14, KEY_4 },
-	{ 0xf8, 0x15, KEY_5 },
-	{ 0xf8, 0x16, KEY_6 },
-	{ 0xf8, 0x17, KEY_7 },
-	{ 0xf8, 0x18, KEY_8 },
-	{ 0xf8, 0x19, KEY_9 },
-	{ 0xf8, 0x10, KEY_0 },
-	{ 0xf8, 0x1c, KEY_MENU },
-	{ 0xf8, 0x0f, KEY_VOLUMEDOWN },
-	{ 0xf8, 0x1a, KEY_LAST },
-	{ 0xf8, 0x0e, KEY_OPEN },
-	{ 0xf8, 0x04, KEY_RECORD },
-	{ 0xf8, 0x09, KEY_VOLUMEUP },
-	{ 0xf8, 0x08, KEY_CHANNELUP },
-	{ 0xf8, 0x07, KEY_PVR },
-	{ 0xf8, 0x0b, KEY_TIME },
-	{ 0xf8, 0x02, KEY_RIGHT },
-	{ 0xf8, 0x03, KEY_LEFT },
-	{ 0xf8, 0x00, KEY_UP },
-	{ 0xf8, 0x1f, KEY_OK },
-	{ 0xf8, 0x01, KEY_DOWN },
-	{ 0xf8, 0x05, KEY_TUNER },
-	{ 0xf8, 0x06, KEY_CHANNELDOWN },
-	{ 0xf8, 0x40, KEY_PLAYPAUSE },
-	{ 0xf8, 0x1e, KEY_REWIND },
-	{ 0xf8, 0x1b, KEY_FAVORITES },
-	{ 0xf8, 0x1d, KEY_BACK },
-	{ 0xf8, 0x4d, KEY_FASTFORWARD },
-	{ 0xf8, 0x44, KEY_EPG },
-	{ 0xf8, 0x4c, KEY_INFO },
-	{ 0xf8, 0x41, KEY_AB },
-	{ 0xf8, 0x43, KEY_AUDIO },
-	{ 0xf8, 0x45, KEY_SUBTITLE },
-	{ 0xf8, 0x4a, KEY_LIST },
-	{ 0xf8, 0x46, KEY_F1 },
-	{ 0xf8, 0x47, KEY_F2 },
-	{ 0xf8, 0x5e, KEY_F3 },
-	{ 0xf8, 0x5c, KEY_F4 },
-	{ 0xf8, 0x52, KEY_F5 },
-	{ 0xf8, 0x5a, KEY_F6 },
-	{ 0xf8, 0x56, KEY_MODE },
-	{ 0xf8, 0x58, KEY_SWITCHVIDEOMODE },
+	{ 0xf80a, KEY_POWER },
+	{ 0xf80c, KEY_MUTE },
+	{ 0xf811, KEY_1 },
+	{ 0xf812, KEY_2 },
+	{ 0xf813, KEY_3 },
+	{ 0xf814, KEY_4 },
+	{ 0xf815, KEY_5 },
+	{ 0xf816, KEY_6 },
+	{ 0xf817, KEY_7 },
+	{ 0xf818, KEY_8 },
+	{ 0xf819, KEY_9 },
+	{ 0xf810, KEY_0 },
+	{ 0xf81c, KEY_MENU },
+	{ 0xf80f, KEY_VOLUMEDOWN },
+	{ 0xf81a, KEY_LAST },
+	{ 0xf80e, KEY_OPEN },
+	{ 0xf804, KEY_RECORD },
+	{ 0xf809, KEY_VOLUMEUP },
+	{ 0xf808, KEY_CHANNELUP },
+	{ 0xf807, KEY_PVR },
+	{ 0xf80b, KEY_TIME },
+	{ 0xf802, KEY_RIGHT },
+	{ 0xf803, KEY_LEFT },
+	{ 0xf800, KEY_UP },
+	{ 0xf81f, KEY_OK },
+	{ 0xf801, KEY_DOWN },
+	{ 0xf805, KEY_TUNER },
+	{ 0xf806, KEY_CHANNELDOWN },
+	{ 0xf840, KEY_PLAYPAUSE },
+	{ 0xf81e, KEY_REWIND },
+	{ 0xf81b, KEY_FAVORITES },
+	{ 0xf81d, KEY_BACK },
+	{ 0xf84d, KEY_FASTFORWARD },
+	{ 0xf844, KEY_EPG },
+	{ 0xf84c, KEY_INFO },
+	{ 0xf841, KEY_AB },
+	{ 0xf843, KEY_AUDIO },
+	{ 0xf845, KEY_SUBTITLE },
+	{ 0xf84a, KEY_LIST },
+	{ 0xf846, KEY_F1 },
+	{ 0xf847, KEY_F2 },
+	{ 0xf85e, KEY_F3 },
+	{ 0xf85c, KEY_F4 },
+	{ 0xf852, KEY_F5 },
+	{ 0xf85a, KEY_F6 },
+	{ 0xf856, KEY_MODE },
+	{ 0xf858, KEY_SWITCHVIDEOMODE },
 };
 
 static struct dvb_usb_rc_key tbs_rc_keys[] = {
-	{ 0xf8,	0x84, KEY_POWER },
-	{ 0xf8,	0x94, KEY_MUTE },
-	{ 0xf8,	0x87, KEY_1 },
-	{ 0xf8,	0x86, KEY_2 },
-	{ 0xf8,	0x85, KEY_3 },
-	{ 0xf8,	0x8b, KEY_4 },
-	{ 0xf8,	0x8a, KEY_5 },
-	{ 0xf8,	0x89, KEY_6 },
-	{ 0xf8,	0x8f, KEY_7 },
-	{ 0xf8,	0x8e, KEY_8 },
-	{ 0xf8,	0x8d, KEY_9 },
-	{ 0xf8, 0x92, KEY_0 },
-	{ 0xf8, 0x96, KEY_CHANNELUP },
-	{ 0xf8, 0x91, KEY_CHANNELDOWN },
-	{ 0xf8, 0x93, KEY_VOLUMEUP },
-	{ 0xf8, 0x8c, KEY_VOLUMEDOWN },
-	{ 0xf8, 0x83, KEY_RECORD },
-	{ 0xf8, 0x98, KEY_PAUSE  },
-	{ 0xf8, 0x99, KEY_OK },
-	{ 0xf8, 0x9a, KEY_SHUFFLE },
-	{ 0xf8, 0x81, KEY_UP },
-	{ 0xf8, 0x90, KEY_LEFT },
-	{ 0xf8, 0x82, KEY_RIGHT },
-	{ 0xf8, 0x88, KEY_DOWN },
-	{ 0xf8, 0x95, KEY_FAVORITES },
-	{ 0xf8, 0x97, KEY_SUBTITLE },
-	{ 0xf8, 0x9d, KEY_ZOOM },
-	{ 0xf8, 0x9f, KEY_EXIT },
-	{ 0xf8, 0x9e, KEY_MENU },
-	{ 0xf8, 0x9c, KEY_EPG },
-	{ 0xf8, 0x80, KEY_PREVIOUS },
-	{ 0xf8, 0x9b, KEY_MODE }
+	{ 0xf884, KEY_POWER },
+	{ 0xf894, KEY_MUTE },
+	{ 0xf887, KEY_1 },
+	{ 0xf886, KEY_2 },
+	{ 0xf885, KEY_3 },
+	{ 0xf88b, KEY_4 },
+	{ 0xf88a, KEY_5 },
+	{ 0xf889, KEY_6 },
+	{ 0xf88f, KEY_7 },
+	{ 0xf88e, KEY_8 },
+	{ 0xf88d, KEY_9 },
+	{ 0xf892, KEY_0 },
+	{ 0xf896, KEY_CHANNELUP },
+	{ 0xf891, KEY_CHANNELDOWN },
+	{ 0xf893, KEY_VOLUMEUP },
+	{ 0xf88c, KEY_VOLUMEDOWN },
+	{ 0xf883, KEY_RECORD },
+	{ 0xf898, KEY_PAUSE  },
+	{ 0xf899, KEY_OK },
+	{ 0xf89a, KEY_SHUFFLE },
+	{ 0xf881, KEY_UP },
+	{ 0xf890, KEY_LEFT },
+	{ 0xf882, KEY_RIGHT },
+	{ 0xf888, KEY_DOWN },
+	{ 0xf895, KEY_FAVORITES },
+	{ 0xf897, KEY_SUBTITLE },
+	{ 0xf89d, KEY_ZOOM },
+	{ 0xf89f, KEY_EXIT },
+	{ 0xf89e, KEY_MENU },
+	{ 0xf89c, KEY_EPG },
+	{ 0xf880, KEY_PREVIOUS },
+	{ 0xf89b, KEY_MODE }
 };
 
 static struct dvb_usb_rc_keys_table keys_tables[] = {
@@ -763,9 +892,9 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	}
 
 	*state = REMOTE_NO_KEY_PRESSED;
-	if (dw2102_i2c_transfer(&d->i2c_adap, &msg, 1) == 1) {
+	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
 		for (i = 0; i < keymap_size ; i++) {
-			if (keymap[i].data == msg.buf[0]) {
+			if (rc5_data(&keymap[i]) == msg.buf[0]) {
 				*state = REMOTE_KEY_PRESSED;
 				*event = keymap[i].event;
 				break;
@@ -792,6 +921,7 @@ static struct usb_device_id dw2102_table[] = {
 	{USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
 	{USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
 	{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
+	{USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
 	{ }
 };
 
@@ -806,6 +936,7 @@ static int dw2102_load_firmware(struct usb_device *dev,
 	u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
 	const struct firmware *fw;
 	const char *filename = "dvb-usb-dw2101.fw";
+
 	switch (dev->descriptor.idProduct) {
 	case 0x2101:
 		ret = request_firmware(&fw, filename, &dev->dev);
@@ -1053,6 +1184,48 @@ static struct dvb_usb_device_properties dw3101_properties = {
 	}
 };
 
+static struct dvb_usb_device_properties s630_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = DEVICE_SPECIFIC,
+	.firmware = "dvb-usb-s630.fw",
+	.no_reconnect = 1,
+
+	.i2c_algo = &s630_i2c_algo,
+	.rc_key_map = tevii_rc_keys,
+	.rc_key_map_size = ARRAY_SIZE(tevii_rc_keys),
+	.rc_interval = 150,
+	.rc_query = dw2102_rc_query,
+
+	.generic_bulk_ctrl_endpoint = 0x81,
+	.num_adapters = 1,
+	.download_firmware = dw2102_load_firmware,
+	.read_mac_address = s630_read_mac_address,
+	.adapter = {
+		{
+			.frontend_attach = s630_frontend_attach,
+			.streaming_ctrl = NULL,
+			.tuner_attach = s630_zl10039_tuner_attach,
+			.stream = {
+				.type = USB_BULK,
+				.count = 8,
+				.endpoint = 0x82,
+				.u = {
+					.bulk = {
+						.buffersize = 4096,
+					}
+				}
+			},
+		}
+	},
+	.num_device_descs = 1,
+	.devices = {
+		{"TeVii S630 USB",
+			{&dw2102_table[6], NULL},
+			{NULL},
+		},
+	}
+};
+
 static int dw2102_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
@@ -1061,6 +1234,8 @@ static int dw2102_probe(struct usb_interface *intf,
 	    0 == dvb_usb_device_init(intf, &dw2104_properties,
 			THIS_MODULE, NULL, adapter_nr) ||
 	    0 == dvb_usb_device_init(intf, &dw3101_properties,
+			THIS_MODULE, NULL, adapter_nr) ||
+	    0 == dvb_usb_device_init(intf, &s630_properties,
 			THIS_MODULE, NULL, adapter_nr)) {
 		return 0;
 	}
@@ -1094,6 +1269,6 @@ module_exit(dw2102_module_exit);
 MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
 MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
 				" DVB-C 3101 USB2.0,"
-				" TeVii S600, S650 USB2.0 devices");
+				" TeVii S600, S630, S650 USB2.0 devices");
 MODULE_VERSION("0.1");
 MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
new file mode 100644
index 0000000..c4dfe25
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -0,0 +1,483 @@
+/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
+ *
+ * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
+ *
+ * This module is based off the the gl861 and vp702x modules.
+ *
+ * This program is free software; 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "friio.h"
+
+struct jdvbt90502_state {
+	struct i2c_adapter *i2c;
+	struct dvb_frontend frontend;
+	struct jdvbt90502_config config;
+};
+
+/* NOTE: TC90502 has 16bit register-address? */
+/* register 0x0100 is used for reading PLL status, so reg is u16 here */
+static int jdvbt90502_reg_read(struct jdvbt90502_state *state,
+			       const u16 reg, u8 *buf, const size_t count)
+{
+	int ret;
+	u8 wbuf[3];
+	struct i2c_msg msg[2];
+
+	wbuf[0] = reg & 0xFF;
+	wbuf[1] = 0;
+	wbuf[2] = reg >> 8;
+
+	msg[0].addr = state->config.demod_address;
+	msg[0].flags = 0;
+	msg[0].buf = wbuf;
+	msg[0].len = sizeof(wbuf);
+
+	msg[1].addr = msg[0].addr;
+	msg[1].flags = I2C_M_RD;
+	msg[1].buf = buf;
+	msg[1].len = count;
+
+	ret = i2c_transfer(state->i2c, msg, 2);
+	if (ret != 2) {
+		deb_fe(" reg read failed.\n");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+/* currently 16bit register-address is not used, so reg is u8 here */
+static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
+				       const u8 reg, const u8 val)
+{
+	struct i2c_msg msg;
+	u8 wbuf[2];
+
+	wbuf[0] = reg;
+	wbuf[1] = val;
+
+	msg.addr = state->config.demod_address;
+	msg.flags = 0;
+	msg.buf = wbuf;
+	msg.len = sizeof(wbuf);
+
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		deb_fe(" reg write failed.");
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int _jdvbt90502_write(struct dvb_frontend *fe, u8 *buf, int len)
+{
+	struct jdvbt90502_state *state = fe->demodulator_priv;
+	int err, i;
+	for (i = 0; i < len - 1; i++) {
+		err = jdvbt90502_single_reg_write(state,
+						  buf[0] + i, buf[i + 1]);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+/* read pll status byte via the demodulator's I2C register */
+/* note: Win box reads it by 8B block at the I2C addr 0x30 from reg:0x80 */
+static int jdvbt90502_pll_read(struct jdvbt90502_state *state, u8 *result)
+{
+	int ret;
+
+	/* +1 for reading */
+	u8 pll_addr_byte = (state->config.pll_address << 1) + 1;
+
+	*result = 0;
+
+	ret = jdvbt90502_single_reg_write(state, JDVBT90502_2ND_I2C_REG,
+					  pll_addr_byte);
+	if (ret)
+		goto error;
+
+	ret = jdvbt90502_reg_read(state, 0x0100, result, 1);
+	if (ret)
+		goto error;
+
+	deb_fe("PLL read val:%02x\n", *result);
+	return 0;
+
+error:
+	deb_fe("%s:ret == %d\n", __func__, ret);
+	return -EREMOTEIO;
+}
+
+
+/* set pll frequency via the demodulator's I2C register */
+static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
+{
+	int ret;
+	int retry;
+	u8 res1;
+	u8 res2[9];
+
+	u8 pll_freq_cmd[PLL_CMD_LEN];
+	u8 pll_agc_cmd[PLL_CMD_LEN];
+	struct i2c_msg msg[2];
+	u32 f;
+
+	deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
+	       state->frontend.ops.info.frequency_stepsize);
+	/* freq -> oscilator frequency conversion. */
+	/* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
+	/* add 400[1/7 MHZ] = 57.142857MHz.   57MHz for the IF,  */
+	/*                                   1/7MHz for center freq shift */
+	f = freq / state->frontend.ops.info.frequency_stepsize;
+	f += 400;
+	pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
+	pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
+	pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
+	pll_freq_cmd[DIVIDER_BYTE2] = f & 0xFF;
+	pll_freq_cmd[CONTROL_BYTE] = 0xB2; /* ref.divider:28, 4MHz/28=1/7MHz */
+	pll_freq_cmd[BANDSWITCH_BYTE] = 0x08;	/* UHF band */
+
+	msg[0].addr = state->config.demod_address;
+	msg[0].flags = 0;
+	msg[0].buf = pll_freq_cmd;
+	msg[0].len = sizeof(pll_freq_cmd);
+
+	ret = i2c_transfer(state->i2c, &msg[0], 1);
+	if (ret != 1)
+		goto error;
+
+	udelay(50);
+
+	pll_agc_cmd[DEMOD_REDIRECT_REG] = pll_freq_cmd[DEMOD_REDIRECT_REG];
+	pll_agc_cmd[ADDRESS_BYTE] = pll_freq_cmd[ADDRESS_BYTE];
+	pll_agc_cmd[DIVIDER_BYTE1] = pll_freq_cmd[DIVIDER_BYTE1];
+	pll_agc_cmd[DIVIDER_BYTE2] = pll_freq_cmd[DIVIDER_BYTE2];
+	pll_agc_cmd[CONTROL_BYTE] = 0x9A; /*  AGC_CTRL instead of BANDSWITCH */
+	pll_agc_cmd[AGC_CTRL_BYTE] = 0x50;
+	/* AGC Time Constant 2s, AGC take-over point:103dBuV(lowest) */
+
+	msg[1].addr = msg[0].addr;
+	msg[1].flags = 0;
+	msg[1].buf = pll_agc_cmd;
+	msg[1].len = sizeof(pll_agc_cmd);
+
+	ret = i2c_transfer(state->i2c, &msg[1], 1);
+	if (ret != 1)
+		goto error;
+
+	/* I don't know what these cmds are for,  */
+	/* but the USB log on a windows box contains them */
+	ret = jdvbt90502_single_reg_write(state, 0x01, 0x40);
+	ret |= jdvbt90502_single_reg_write(state, 0x01, 0x00);
+	if (ret)
+		goto error;
+	udelay(100);
+
+	/* wait for the demod to be ready? */
+#define RETRY_COUNT 5
+	for (retry = 0; retry < RETRY_COUNT; retry++) {
+		ret = jdvbt90502_reg_read(state, 0x0096, &res1, 1);
+		if (ret)
+			goto error;
+		/* if (res1 != 0x00) goto error; */
+		ret = jdvbt90502_reg_read(state, 0x00B0, res2, sizeof(res2));
+		if (ret)
+			goto error;
+		if (res2[0] >= 0xA7)
+			break;
+		msleep(100);
+	}
+	if (retry >= RETRY_COUNT) {
+		deb_fe("%s: FE does not get ready after freq setting.\n",
+		       __func__);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+error:
+	deb_fe("%s:ret == %d\n", __func__, ret);
+	return -EREMOTEIO;
+}
+
+static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
+{
+	u8 result;
+	int ret;
+
+	*state = FE_HAS_SIGNAL;
+
+	ret = jdvbt90502_pll_read(fe->demodulator_priv, &result);
+	if (ret) {
+		deb_fe("%s:ret == %d\n", __func__, ret);
+		return -EREMOTEIO;
+	}
+
+	*state = FE_HAS_SIGNAL
+		| FE_HAS_CARRIER
+		| FE_HAS_VITERBI
+		| FE_HAS_SYNC;
+
+	if (result & PLL_STATUS_LOCKED)
+		*state |= FE_HAS_LOCK;
+
+	return 0;
+}
+
+static int jdvbt90502_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	*ber = 0;
+	return 0;
+}
+
+static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
+					   u16 *strength)
+{
+	int ret;
+	u8 rbuf[37];
+
+	*strength = 0;
+
+	/* status register (incl. signal strength) : 0x89  */
+	/* TODO: read just the necessary registers [0x8B..0x8D]? */
+	ret = jdvbt90502_reg_read(fe->demodulator_priv, 0x0089,
+				  rbuf, sizeof(rbuf));
+
+	if (ret) {
+		deb_fe("%s:ret == %d\n", __func__, ret);
+		return -EREMOTEIO;
+	}
+
+	/* signal_strength: rbuf[2-4] (24bit BE), use lower 16bit for now. */
+	*strength = (rbuf[3] << 8) + rbuf[4];
+	if (rbuf[2])
+		*strength = 0xffff;
+
+	return 0;
+}
+
+static int jdvbt90502_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	*snr = 0x0101;
+	return 0;
+}
+
+static int jdvbt90502_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	return 0;
+}
+
+static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe,
+					struct dvb_frontend_tune_settings *fs)
+{
+	fs->min_delay_ms = 500;
+	fs->step_size = 0;
+	fs->max_drift = 0;
+
+	return 0;
+}
+
+static int jdvbt90502_get_frontend(struct dvb_frontend *fe,
+				   struct dvb_frontend_parameters *p)
+{
+	p->inversion = INVERSION_AUTO;
+	p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
+	p->u.ofdm.code_rate_HP = FEC_AUTO;
+	p->u.ofdm.code_rate_LP = FEC_AUTO;
+	p->u.ofdm.constellation = QAM_64;
+	p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
+	p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
+	p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
+	return 0;
+}
+
+static int jdvbt90502_set_frontend(struct dvb_frontend *fe,
+				   struct dvb_frontend_parameters *p)
+{
+	/**
+	 * NOTE: ignore all the paramters except frequency.
+	 *       others should be fixed to the proper value for ISDB-T,
+	 *       but don't check here.
+	 */
+
+	struct jdvbt90502_state *state = fe->demodulator_priv;
+	int ret;
+
+	deb_fe("%s: Freq:%d\n", __func__, p->frequency);
+
+	ret = jdvbt90502_pll_set_freq(state, p->frequency);
+	if (ret) {
+		deb_fe("%s:ret == %d\n", __func__, ret);
+		return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+static int jdvbt90502_sleep(struct dvb_frontend *fe)
+{
+	deb_fe("%s called.\n", __func__);
+	return 0;
+}
+
+
+/**
+ * (reg, val) commad list to initialize this module.
+ *  captured on a Windows box.
+ */
+static u8 init_code[][2] = {
+	{0x01, 0x40},
+	{0x04, 0x38},
+	{0x05, 0x40},
+	{0x07, 0x40},
+	{0x0F, 0x4F},
+	{0x11, 0x21},
+	{0x12, 0x0B},
+	{0x13, 0x2F},
+	{0x14, 0x31},
+	{0x16, 0x02},
+	{0x21, 0xC4},
+	{0x22, 0x20},
+	{0x2C, 0x79},
+	{0x2D, 0x34},
+	{0x2F, 0x00},
+	{0x30, 0x28},
+	{0x31, 0x31},
+	{0x32, 0xDF},
+	{0x38, 0x01},
+	{0x39, 0x78},
+	{0x3B, 0x33},
+	{0x3C, 0x33},
+	{0x48, 0x90},
+	{0x51, 0x68},
+	{0x5E, 0x38},
+	{0x71, 0x00},
+	{0x72, 0x08},
+	{0x77, 0x00},
+	{0xC0, 0x21},
+	{0xC1, 0x10},
+	{0xE4, 0x1A},
+	{0xEA, 0x1F},
+	{0x77, 0x00},
+	{0x71, 0x00},
+	{0x71, 0x00},
+	{0x76, 0x0C},
+};
+
+const static int init_code_len = sizeof(init_code) / sizeof(u8[2]);
+
+static int jdvbt90502_init(struct dvb_frontend *fe)
+{
+	int i = -1;
+	int ret;
+	struct i2c_msg msg;
+
+	struct jdvbt90502_state *state = fe->demodulator_priv;
+
+	deb_fe("%s called.\n", __func__);
+
+	msg.addr = state->config.demod_address;
+	msg.flags = 0;
+	msg.len = 2;
+	for (i = 0; i < init_code_len; i++) {
+		msg.buf = init_code[i];
+		ret = i2c_transfer(state->i2c, &msg, 1);
+		if (ret != 1)
+			goto error;
+	}
+	msleep(100);
+
+	return 0;
+
+error:
+	deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
+	return -EREMOTEIO;
+}
+
+
+static void jdvbt90502_release(struct dvb_frontend *fe)
+{
+	struct jdvbt90502_state *state = fe->demodulator_priv;
+	kfree(state);
+}
+
+
+static struct dvb_frontend_ops jdvbt90502_ops;
+
+struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
+{
+	struct jdvbt90502_state *state = NULL;
+
+	deb_info("%s called.\n", __func__);
+
+	/* allocate memory for the internal state */
+	state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	/* setup the state */
+	state->i2c = &d->i2c_adap;
+	memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
+
+	/* create dvb_frontend */
+	memcpy(&state->frontend.ops, &jdvbt90502_ops,
+	       sizeof(jdvbt90502_ops));
+	state->frontend.demodulator_priv = state;
+
+	if (jdvbt90502_init(&state->frontend) < 0)
+		goto error;
+
+	return &state->frontend;
+
+error:
+	kfree(state);
+	return NULL;
+}
+
+static struct dvb_frontend_ops jdvbt90502_ops = {
+
+	.info = {
+		.name			= "Comtech JDVBT90502 ISDB-T",
+		.type			= FE_OFDM,
+		.frequency_min		= 473000000, /* UHF 13ch, center */
+		.frequency_max		= 767142857, /* UHF 62ch, center */
+		.frequency_stepsize	= JDVBT90502_PLL_CLK /
+							JDVBT90502_PLL_DIVIDER,
+		.frequency_tolerance	= 0,
+
+		/* NOTE: this driver ignores all parameters but frequency. */
+		.caps = FE_CAN_INVERSION_AUTO |
+			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+			FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+			FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO |
+			FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.release = jdvbt90502_release,
+
+	.init = jdvbt90502_init,
+	.sleep = jdvbt90502_sleep,
+	.write = _jdvbt90502_write,
+
+	.set_frontend = jdvbt90502_set_frontend,
+	.get_frontend = jdvbt90502_get_frontend,
+	.get_tune_settings = jdvbt90502_get_tune_settings,
+
+	.read_status = jdvbt90502_read_status,
+	.read_ber = jdvbt90502_read_ber,
+	.read_signal_strength = jdvbt90502_read_signal_strength,
+	.read_snr = jdvbt90502_read_snr,
+	.read_ucblocks = jdvbt90502_read_ucblocks,
+};
diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/dvb/dvb-usb/friio.c
new file mode 100644
index 0000000..14a65b4
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.c
@@ -0,0 +1,525 @@
+/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
+ *
+ * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
+ *
+ * This module is based off the the gl861 and vp702x modules.
+ *
+ * This program is free software; 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "friio.h"
+
+/* debug */
+int dvb_usb_friio_debug;
+module_param_named(debug, dvb_usb_friio_debug, int, 0644);
+MODULE_PARM_DESC(debug,
+		 "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
+		 DVB_USB_DEBUG_STATUS);
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/**
+ * Indirect I2C access to the PLL via FE.
+ * whole I2C protocol data to the PLL is sent via the FE's I2C register.
+ * This is done by a control msg to the FE with the I2C data accompanied, and
+ * a specific USB request number is assigned for that purpose.
+ *
+ * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
+ * TODO: refoctored, smarter i2c functions.
+ */
+static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
+				  u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+	u16 index = wbuf[0];	/* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
+	u16 value = addr << (8 + 1);
+	int wo = (rbuf == NULL || rlen == 0);	/* write only */
+	u8 req, type;
+
+	deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
+		 wbuf[1], wbuf[0], wlen - 1);
+
+	if (wo && wlen >= 2) {
+		req = GL861_REQ_I2C_DATA_CTRL_WRITE;
+		type = GL861_WRITE;
+		udelay(20);
+		return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+				       req, type, value, index,
+				       &wbuf[1], wlen - 1, 2000);
+	}
+
+	deb_xfer("not supported ctrl-msg, aborting.");
+	return -EINVAL;
+}
+
+/* normal I2C access (without extra data arguments).
+ * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
+ *  or read from the register wbuf[0].
+ * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
+ */
+static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
+			 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+	u16 index;
+	u16 value = addr << (8 + 1);
+	int wo = (rbuf == NULL || rlen == 0);	/* write-only */
+	u8 req, type;
+	unsigned int pipe;
+
+	/* special case for the indirect I2C access to the PLL via FE, */
+	if (addr == friio_fe_config.demod_address &&
+	    wbuf[0] == JDVBT90502_2ND_I2C_REG)
+		return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
+
+	if (wo) {
+		req = GL861_REQ_I2C_WRITE;
+		type = GL861_WRITE;
+		pipe = usb_sndctrlpipe(d->udev, 0);
+	} else {		/* rw */
+		req = GL861_REQ_I2C_READ;
+		type = GL861_READ;
+		pipe = usb_rcvctrlpipe(d->udev, 0);
+	}
+
+	switch (wlen) {
+	case 1:
+		index = wbuf[0];
+		break;
+	case 2:
+		index = wbuf[0];
+		value = value + wbuf[1];
+		break;
+	case 3:
+		/* special case for 16bit register-address */
+		index = (wbuf[2] << 8) | wbuf[0];
+		value = value + wbuf[1];
+		break;
+	default:
+		deb_xfer("wlen = %x, aborting.", wlen);
+		return -EINVAL;
+	}
+	msleep(1);
+	return usb_control_msg(d->udev, pipe, req, type,
+			       value, index, rbuf, rlen, 2000);
+}
+
+/* I2C */
+static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+			  int num)
+{
+	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	int i;
+
+
+	if (num > 2)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
+
+	for (i = 0; i < num; i++) {
+		/* write/read request */
+		if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
+			if (gl861_i2c_msg(d, msg[i].addr,
+					  msg[i].buf, msg[i].len,
+					  msg[i + 1].buf, msg[i + 1].len) < 0)
+				break;
+			i++;
+		} else
+			if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
+					  msg[i].len, NULL, 0) < 0)
+				break;
+	}
+
+	mutex_unlock(&d->i2c_mutex);
+	return i;
+}
+
+static u32 gl861_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+
+static int friio_ext_ctl(struct dvb_usb_adapter *adap,
+			 u32 sat_color, int lnb_on)
+{
+	int i;
+	int ret;
+	struct i2c_msg msg;
+	u8 buf[2];
+	u32 mask;
+	u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
+
+	msg.addr = 0x00;
+	msg.flags = 0;
+	msg.len = 2;
+	msg.buf = buf;
+
+	buf[0] = 0x00;
+
+	/* send 2bit header (&B10) */
+	buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
+	ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+	buf[1] |= FRIIO_CTL_CLK;
+	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+
+	buf[1] = lnb | FRIIO_CTL_STROBE;
+	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+	buf[1] |= FRIIO_CTL_CLK;
+	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+
+	/* send 32bit(satur, R, G, B) data in serial */
+	mask = 1 << 31;
+	for (i = 0; i < 32; i++) {
+		buf[1] = lnb | FRIIO_CTL_STROBE;
+		if (sat_color & mask)
+			buf[1] |= FRIIO_CTL_LED;
+		ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+		buf[1] |= FRIIO_CTL_CLK;
+		ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+		mask >>= 1;
+	}
+
+	/* set the strobe off */
+	buf[1] = lnb;
+	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+	buf[1] |= FRIIO_CTL_CLK;
+	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
+
+	return (ret == 70);
+}
+
+
+static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
+
+/* TODO: move these init cmds to the FE's init routine? */
+static u8 streaming_init_cmds[][2] = {
+	{0x33, 0x08},
+	{0x37, 0x40},
+	{0x3A, 0x1F},
+	{0x3B, 0xFF},
+	{0x3C, 0x1F},
+	{0x3D, 0xFF},
+	{0x38, 0x00},
+	{0x35, 0x00},
+	{0x39, 0x00},
+	{0x36, 0x00},
+};
+static int cmdlen = sizeof(streaming_init_cmds) / 2;
+
+/*
+ * Command sequence in this init function is a replay
+ *  of the captured USB commands from the Windows proprietary driver.
+ */
+static int friio_initialize(struct dvb_usb_device *d)
+{
+	int ret;
+	int i;
+	int retry = 0;
+	u8 rbuf[2];
+	u8 wbuf[3];
+
+	deb_info("%s called.\n", __func__);
+
+	/* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
+	/* because the i2c device is not set up yet. */
+	wbuf[0] = 0x11;
+	wbuf[1] = 0x02;
+	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+	if (ret < 0)
+		goto error;
+	msleep(2);
+
+	wbuf[0] = 0x11;
+	wbuf[1] = 0x00;
+	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+	if (ret < 0)
+		goto error;
+	msleep(1);
+
+	/* following msgs should be in the FE's init code? */
+	/* cmd sequence to identify the device type? (friio black/white) */
+	wbuf[0] = 0x03;
+	wbuf[1] = 0x80;
+	/* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
+	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+			      GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
+			      0x1200, 0x0100, wbuf, 2, 2000);
+	if (ret < 0)
+		goto error;
+
+	msleep(2);
+	wbuf[0] = 0x00;
+	wbuf[2] = 0x01;		/* reg.0x0100 */
+	wbuf[1] = 0x00;
+	ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
+	/* my Friio White returns 0xffff. */
+	if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
+		goto error;
+
+	msleep(2);
+	wbuf[0] = 0x03;
+	wbuf[1] = 0x80;
+	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
+			      GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
+			      0x9000, 0x0100, wbuf, 2, 2000);
+	if (ret < 0)
+		goto error;
+
+	msleep(2);
+	wbuf[0] = 0x00;
+	wbuf[2] = 0x01;		/* reg.0x0100 */
+	wbuf[1] = 0x00;
+	ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
+	/* my Friio White returns 0xffff again. */
+	if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
+		goto error;
+
+	msleep(1);
+
+restart:
+	/* ============ start DEMOD init cmds ================== */
+	/* read PLL status to clear the POR bit */
+	wbuf[0] = JDVBT90502_2ND_I2C_REG;
+	wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1;	/* +1 for reading */
+	ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
+	if (ret < 0)
+		goto error;
+
+	msleep(5);
+	/* note: DEMODULATOR has 16bit register-address. */
+	wbuf[0] = 0x00;
+	wbuf[2] = 0x01;		/* reg addr: 0x0100 */
+	wbuf[1] = 0x00;		/* val: not used */
+	ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
+	if (ret < 0)
+		goto error;
+/*
+	msleep(1);
+	wbuf[0] = 0x80;
+	wbuf[1] = 0x00;
+	ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
+	if (ret < 0)
+		goto error;
+ */
+	if (rbuf[0] & 0x80) {	/* still in PowerOnReset state? */
+		if (++retry > 3) {
+			deb_info("failed to get the correct"
+				 " FE demod status:0x%02x\n", rbuf[0]);
+			goto error;
+		}
+		msleep(100);
+		goto restart;
+	}
+
+	/* TODO: check return value in rbuf */
+	/* =========== end DEMOD init cmds ===================== */
+	msleep(1);
+
+	wbuf[0] = 0x30;
+	wbuf[1] = 0x04;
+	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+	if (ret < 0)
+		goto error;
+
+	msleep(2);
+	/* following 2 cmds unnecessary? */
+	wbuf[0] = 0x00;
+	wbuf[1] = 0x01;
+	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+	if (ret < 0)
+		goto error;
+
+	wbuf[0] = 0x06;
+	wbuf[1] = 0x0F;
+	ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
+	if (ret < 0)
+		goto error;
+
+	/* some streaming ctl cmds (maybe) */
+	msleep(10);
+	for (i = 0; i < cmdlen; i++) {
+		ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
+				    NULL, 0);
+		if (ret < 0)
+			goto error;
+		msleep(1);
+	}
+	msleep(20);
+
+	/* change the LED color etc. */
+	ret = friio_streaming_ctrl(&d->adapter[0], 0);
+	if (ret < 0)
+		goto error;
+
+	return 0;
+
+error:
+	deb_info("%s:ret == %d\n", __func__, ret);
+	return -EIO;
+}
+
+/* Callbacks for DVB USB */
+
+static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	int ret;
+
+	deb_info("%s called.(%d)\n", __func__, onoff);
+
+	/* set the LED color and saturation (and LNB on) */
+	if (onoff)
+		ret = friio_ext_ctl(adap, 0x6400ff64, 1);
+	else
+		ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
+
+	if (ret != 1) {
+		deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
+		return -EREMOTEIO;
+	}
+	return 0;
+}
+
+static int friio_frontend_attach(struct dvb_usb_adapter *adap)
+{
+	if (friio_initialize(adap->dev) < 0)
+		return -EIO;
+
+	adap->fe = jdvbt90502_attach(adap->dev);
+	if (adap->fe == NULL)
+		return -EIO;
+
+	return 0;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties friio_properties;
+
+static int friio_probe(struct usb_interface *intf,
+		       const struct usb_device_id *id)
+{
+	struct dvb_usb_device *d;
+	struct usb_host_interface *alt;
+	int ret;
+
+	if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
+		return -ENODEV;
+
+	alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
+	if (alt == NULL) {
+		deb_rc("not alt found!\n");
+		return -ENODEV;
+	}
+	ret = usb_set_interface(interface_to_usbdev(intf),
+				alt->desc.bInterfaceNumber,
+				alt->desc.bAlternateSetting);
+	if (ret != 0) {
+		deb_rc("failed to set alt-setting!\n");
+		return ret;
+	}
+
+	ret = dvb_usb_device_init(intf, &friio_properties,
+				  THIS_MODULE, &d, adapter_nr);
+	if (ret == 0)
+		friio_streaming_ctrl(&d->adapter[0], 1);
+
+	return ret;
+}
+
+
+struct jdvbt90502_config friio_fe_config = {
+	.demod_address = FRIIO_DEMOD_ADDR,
+	.pll_address = FRIIO_PLL_ADDR,
+};
+
+static struct i2c_algorithm gl861_i2c_algo = {
+	.master_xfer   = gl861_i2c_xfer,
+	.functionality = gl861_i2c_func,
+};
+
+static struct usb_device_id friio_table[] = {
+	{ USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
+	{ }		/* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, friio_table);
+
+
+static struct dvb_usb_device_properties friio_properties = {
+	.caps = DVB_USB_IS_AN_I2C_ADAPTER,
+	.usb_ctrl = DEVICE_SPECIFIC,
+
+	.size_of_priv = 0,
+
+	.num_adapters = 1,
+	.adapter = {
+		/* caps:0 =>  no pid filter, 188B TS packet */
+		/* GL861 has a HW pid filter, but no info available. */
+		{
+			.caps  = 0,
+
+			.frontend_attach  = friio_frontend_attach,
+			.streaming_ctrl = friio_streaming_ctrl,
+
+			.stream = {
+				.type = USB_BULK,
+				/* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
+				.count = 8,
+				.endpoint = 0x01,
+				.u = {
+					/* GL861 has 6KB buf inside */
+					.bulk = {
+						.buffersize = 16384,
+					}
+				}
+			},
+		}
+	},
+	.i2c_algo = &gl861_i2c_algo,
+
+	.num_device_descs = 1,
+	.devices = {
+		{
+			.name = "774 Friio ISDB-T USB2.0",
+			.cold_ids = { NULL },
+			.warm_ids = { &friio_table[0], NULL },
+		},
+	}
+};
+
+static struct usb_driver friio_driver = {
+	.name		= "dvb_usb_friio",
+	.probe		= friio_probe,
+	.disconnect	= dvb_usb_device_exit,
+	.id_table	= friio_table,
+};
+
+
+/* module stuff */
+static int __init friio_module_init(void)
+{
+	int ret;
+
+	ret = usb_register(&friio_driver);
+	if (ret)
+		err("usb_register failed. Error number %d", ret);
+
+	return ret;
+}
+
+
+static void __exit friio_module_exit(void)
+{
+	/* deregister this driver from the USB subsystem */
+	usb_deregister(&friio_driver);
+}
+
+module_init(friio_module_init);
+module_exit(friio_module_exit);
+
+MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
+MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
+MODULE_VERSION("0.2");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio.h b/drivers/media/dvb/dvb-usb/friio.h
new file mode 100644
index 0000000..af8d55e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.h
@@ -0,0 +1,99 @@
+/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
+ *
+ * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
+ *
+ * This module is based off the the gl861 and vp702x modules.
+ *
+ * This program is free software; 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.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_FRIIO_H_
+#define _DVB_USB_FRIIO_H_
+
+/**
+ *      Friio Components
+ *       USB hub:                                AU4254
+ *         USB controller(+ TS dmx & streaming): GL861
+ *         Frontend:                             comtech JDVBT-90502
+ *             (tuner PLL:                       tua6034, I2C addr:(0xC0 >> 1))
+ *             (OFDM demodulator:                TC90502, I2C addr:(0x30 >> 1))
+ *         LED x3 (+LNB) controll:               PIC 16F676
+ *         EEPROM:                               24C08
+ *
+ *        (USB smart card reader:                AU9522)
+ *
+ */
+
+#define DVB_USB_LOG_PREFIX "friio"
+#include "dvb-usb.h"
+
+extern int dvb_usb_friio_debug;
+#define deb_info(args...) dprintk(dvb_usb_friio_debug, 0x01, args)
+#define deb_xfer(args...) dprintk(dvb_usb_friio_debug, 0x02, args)
+#define deb_rc(args...)   dprintk(dvb_usb_friio_debug, 0x04, args)
+#define deb_fe(args...)   dprintk(dvb_usb_friio_debug, 0x08, args)
+
+/* Vendor requests */
+#define GL861_WRITE		0x40
+#define GL861_READ		0xc0
+
+/* command bytes */
+#define GL861_REQ_I2C_WRITE	0x01
+#define GL861_REQ_I2C_READ	0x02
+/* For control msg with data argument */
+/* Used for accessing the PLL on the secondary I2C bus of FE via GL861 */
+#define GL861_REQ_I2C_DATA_CTRL_WRITE	0x03
+
+#define GL861_ALTSETTING_COUNT	2
+#define FRIIO_BULK_ALTSETTING	0
+#define FRIIO_ISOC_ALTSETTING	1
+
+/* LED & LNB control via PIC. */
+/* basically, it's serial control with clock and strobe. */
+/* write the below 4bit control data to the reg 0x00 at the I2C addr 0x00 */
+/* when controlling the LEDs, 32bit(saturation, R, G, B) is sent on the bit3*/
+#define FRIIO_CTL_LNB (1 << 0)
+#define FRIIO_CTL_STROBE (1 << 1)
+#define FRIIO_CTL_CLK (1 << 2)
+#define FRIIO_CTL_LED (1 << 3)
+
+/* Front End related */
+
+#define FRIIO_DEMOD_ADDR  (0x30 >> 1)
+#define FRIIO_PLL_ADDR  (0xC0 >> 1)
+
+#define JDVBT90502_PLL_CLK	4000000
+#define JDVBT90502_PLL_DIVIDER	28
+
+#define JDVBT90502_2ND_I2C_REG 0xFE
+
+/* byte index for pll i2c command data structure*/
+/* see datasheet for tua6034 */
+#define DEMOD_REDIRECT_REG 0
+#define ADDRESS_BYTE       1
+#define DIVIDER_BYTE1      2
+#define DIVIDER_BYTE2      3
+#define CONTROL_BYTE       4
+#define BANDSWITCH_BYTE    5
+#define AGC_CTRL_BYTE      5
+#define PLL_CMD_LEN        6
+
+/* bit masks for PLL STATUS response */
+#define PLL_STATUS_POR_MODE   0x80 /* 1: Power on Reset (test) Mode */
+#define PLL_STATUS_LOCKED     0x40 /* 1: locked */
+#define PLL_STATUS_AGC_ACTIVE 0x08 /* 1:active */
+#define PLL_STATUS_TESTMODE   0x07 /* digital output level (5 level) */
+  /* 0.15Vcc step   0x00: < 0.15Vcc, ..., 0x04: >= 0.6Vcc (<= 1Vcc) */
+
+
+struct jdvbt90502_config {
+	u8 demod_address; /* i2c addr for demodulator IC */
+	u8 pll_address;   /* PLL addr on the secondary i2c*/
+};
+extern struct jdvbt90502_config friio_fe_config;
+
+extern struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d);
+#endif
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index 54626a0..ef9b7be 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -140,7 +140,7 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 		goto unlock;
 
 	for (i = 0; i < d->props.rc_key_map_size; i++)
-		if (d->props.rc_key_map[i].data == rc_state[1]) {
+		if (rc5_data(&d->props.rc_key_map[i]) == rc_state[1]) {
 			*event = d->props.rc_key_map[i].event;
 
 			switch(rc_state[0]) {
@@ -337,6 +337,8 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar
 	int i, pass, ret = 0;
 
 	buff = kmalloc(65536, GFP_KERNEL);
+	if (buff == NULL)
+		return -ENOMEM;
 
 	if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
 		goto done;
@@ -562,42 +564,42 @@ static struct m920x_inits tvwalkertwin_rc_init [] = {
 
 /* ir keymaps */
 static struct dvb_usb_rc_key megasky_rc_keys [] = {
-	{ 0x0, 0x12, KEY_POWER },
-	{ 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */
-	{ 0x0, 0x02, KEY_CHANNELUP },
-	{ 0x0, 0x05, KEY_CHANNELDOWN },
-	{ 0x0, 0x03, KEY_VOLUMEUP },
-	{ 0x0, 0x06, KEY_VOLUMEDOWN },
-	{ 0x0, 0x04, KEY_MUTE },
-	{ 0x0, 0x07, KEY_OK }, /* TS */
-	{ 0x0, 0x08, KEY_STOP },
-	{ 0x0, 0x09, KEY_MENU }, /* swap */
-	{ 0x0, 0x0a, KEY_REWIND },
-	{ 0x0, 0x1b, KEY_PAUSE },
-	{ 0x0, 0x1f, KEY_FASTFORWARD },
-	{ 0x0, 0x0c, KEY_RECORD },
-	{ 0x0, 0x0d, KEY_CAMERA }, /* screenshot */
-	{ 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */
+	{ 0x0012, KEY_POWER },
+	{ 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
+	{ 0x0002, KEY_CHANNELUP },
+	{ 0x0005, KEY_CHANNELDOWN },
+	{ 0x0003, KEY_VOLUMEUP },
+	{ 0x0006, KEY_VOLUMEDOWN },
+	{ 0x0004, KEY_MUTE },
+	{ 0x0007, KEY_OK }, /* TS */
+	{ 0x0008, KEY_STOP },
+	{ 0x0009, KEY_MENU }, /* swap */
+	{ 0x000a, KEY_REWIND },
+	{ 0x001b, KEY_PAUSE },
+	{ 0x001f, KEY_FASTFORWARD },
+	{ 0x000c, KEY_RECORD },
+	{ 0x000d, KEY_CAMERA }, /* screenshot */
+	{ 0x000e, KEY_COFFEE }, /* "MTS" */
 };
 
 static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = {
-	{ 0x0, 0x01, KEY_ZOOM }, /* Full Screen */
-	{ 0x0, 0x02, KEY_CAMERA }, /* snapshot */
-	{ 0x0, 0x03, KEY_MUTE },
-	{ 0x0, 0x04, KEY_REWIND },
-	{ 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */
-	{ 0x0, 0x06, KEY_FASTFORWARD },
-	{ 0x0, 0x07, KEY_RECORD },
-	{ 0x0, 0x08, KEY_STOP },
-	{ 0x0, 0x09, KEY_TIME }, /* Timeshift */
-	{ 0x0, 0x0c, KEY_COFFEE }, /* Recall */
-	{ 0x0, 0x0e, KEY_CHANNELUP },
-	{ 0x0, 0x12, KEY_POWER },
-	{ 0x0, 0x15, KEY_MENU }, /* source */
-	{ 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */
-	{ 0x0, 0x1a, KEY_CHANNELDOWN },
-	{ 0x0, 0x1b, KEY_VOLUMEDOWN },
-	{ 0x0, 0x1e, KEY_VOLUMEUP },
+	{ 0x0001, KEY_ZOOM }, /* Full Screen */
+	{ 0x0002, KEY_CAMERA }, /* snapshot */
+	{ 0x0003, KEY_MUTE },
+	{ 0x0004, KEY_REWIND },
+	{ 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
+	{ 0x0006, KEY_FASTFORWARD },
+	{ 0x0007, KEY_RECORD },
+	{ 0x0008, KEY_STOP },
+	{ 0x0009, KEY_TIME }, /* Timeshift */
+	{ 0x000c, KEY_COFFEE }, /* Recall */
+	{ 0x000e, KEY_CHANNELUP },
+	{ 0x0012, KEY_POWER },
+	{ 0x0015, KEY_MENU }, /* source */
+	{ 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
+	{ 0x001a, KEY_CHANNELDOWN },
+	{ 0x001b, KEY_VOLUMEDOWN },
+	{ 0x001e, KEY_VOLUMEUP },
 };
 
 /* DVB USB Driver stuff */
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 07fb843..b41d66e 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -22,51 +22,51 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 /* Hauppauge NOVA-T USB2 keys */
 static struct dvb_usb_rc_key haupp_rc_keys [] = {
-	{ 0x1e, 0x00, KEY_0 },
-	{ 0x1e, 0x01, KEY_1 },
-	{ 0x1e, 0x02, KEY_2 },
-	{ 0x1e, 0x03, KEY_3 },
-	{ 0x1e, 0x04, KEY_4 },
-	{ 0x1e, 0x05, KEY_5 },
-	{ 0x1e, 0x06, KEY_6 },
-	{ 0x1e, 0x07, KEY_7 },
-	{ 0x1e, 0x08, KEY_8 },
-	{ 0x1e, 0x09, KEY_9 },
-	{ 0x1e, 0x0a, KEY_KPASTERISK },
-	{ 0x1e, 0x0b, KEY_RED },
-	{ 0x1e, 0x0c, KEY_RADIO },
-	{ 0x1e, 0x0d, KEY_MENU },
-	{ 0x1e, 0x0e, KEY_GRAVE }, /* # */
-	{ 0x1e, 0x0f, KEY_MUTE },
-	{ 0x1e, 0x10, KEY_VOLUMEUP },
-	{ 0x1e, 0x11, KEY_VOLUMEDOWN },
-	{ 0x1e, 0x12, KEY_CHANNEL },
-	{ 0x1e, 0x14, KEY_UP },
-	{ 0x1e, 0x15, KEY_DOWN },
-	{ 0x1e, 0x16, KEY_LEFT },
-	{ 0x1e, 0x17, KEY_RIGHT },
-	{ 0x1e, 0x18, KEY_VIDEO },
-	{ 0x1e, 0x19, KEY_AUDIO },
-	{ 0x1e, 0x1a, KEY_MEDIA },
-	{ 0x1e, 0x1b, KEY_EPG },
-	{ 0x1e, 0x1c, KEY_TV },
-	{ 0x1e, 0x1e, KEY_NEXT },
-	{ 0x1e, 0x1f, KEY_BACK },
-	{ 0x1e, 0x20, KEY_CHANNELUP },
-	{ 0x1e, 0x21, KEY_CHANNELDOWN },
-	{ 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
-	{ 0x1e, 0x25, KEY_OK },
-	{ 0x1e, 0x29, KEY_BLUE},
-	{ 0x1e, 0x2e, KEY_GREEN },
-	{ 0x1e, 0x30, KEY_PAUSE },
-	{ 0x1e, 0x32, KEY_REWIND },
-	{ 0x1e, 0x34, KEY_FASTFORWARD },
-	{ 0x1e, 0x35, KEY_PLAY },
-	{ 0x1e, 0x36, KEY_STOP },
-	{ 0x1e, 0x37, KEY_RECORD },
-	{ 0x1e, 0x38, KEY_YELLOW },
-	{ 0x1e, 0x3b, KEY_GOTO },
-	{ 0x1e, 0x3d, KEY_POWER },
+	{ 0x1e00, KEY_0 },
+	{ 0x1e01, KEY_1 },
+	{ 0x1e02, KEY_2 },
+	{ 0x1e03, KEY_3 },
+	{ 0x1e04, KEY_4 },
+	{ 0x1e05, KEY_5 },
+	{ 0x1e06, KEY_6 },
+	{ 0x1e07, KEY_7 },
+	{ 0x1e08, KEY_8 },
+	{ 0x1e09, KEY_9 },
+	{ 0x1e0a, KEY_KPASTERISK },
+	{ 0x1e0b, KEY_RED },
+	{ 0x1e0c, KEY_RADIO },
+	{ 0x1e0d, KEY_MENU },
+	{ 0x1e0e, KEY_GRAVE }, /* # */
+	{ 0x1e0f, KEY_MUTE },
+	{ 0x1e10, KEY_VOLUMEUP },
+	{ 0x1e11, KEY_VOLUMEDOWN },
+	{ 0x1e12, KEY_CHANNEL },
+	{ 0x1e14, KEY_UP },
+	{ 0x1e15, KEY_DOWN },
+	{ 0x1e16, KEY_LEFT },
+	{ 0x1e17, KEY_RIGHT },
+	{ 0x1e18, KEY_VIDEO },
+	{ 0x1e19, KEY_AUDIO },
+	{ 0x1e1a, KEY_MEDIA },
+	{ 0x1e1b, KEY_EPG },
+	{ 0x1e1c, KEY_TV },
+	{ 0x1e1e, KEY_NEXT },
+	{ 0x1e1f, KEY_BACK },
+	{ 0x1e20, KEY_CHANNELUP },
+	{ 0x1e21, KEY_CHANNELDOWN },
+	{ 0x1e24, KEY_LAST }, /* Skip backwards */
+	{ 0x1e25, KEY_OK },
+	{ 0x1e29, KEY_BLUE},
+	{ 0x1e2e, KEY_GREEN },
+	{ 0x1e30, KEY_PAUSE },
+	{ 0x1e32, KEY_REWIND },
+	{ 0x1e34, KEY_FASTFORWARD },
+	{ 0x1e35, KEY_PLAY },
+	{ 0x1e36, KEY_STOP },
+	{ 0x1e37, KEY_RECORD },
+	{ 0x1e38, KEY_YELLOW },
+	{ 0x1e3b, KEY_GOTO },
+	{ 0x1e3d, KEY_POWER },
 };
 
 /* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
@@ -92,10 +92,11 @@ static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 			deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
 
 			for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
-				if (haupp_rc_keys[i].data == data &&
-					haupp_rc_keys[i].custom == custom) {
+				if (rc5_data(&haupp_rc_keys[i]) == data &&
+					rc5_custom(&haupp_rc_keys[i]) == custom) {
 
-					deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
+					deb_rc("c: %x, d: %x\n", rc5_data(&haupp_rc_keys[i]),
+								 rc5_custom(&haupp_rc_keys[i]));
 
 					*event = haupp_rc_keys[i].event;
 					*state = REMOTE_KEY_PRESSED;
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 7e32d11..d4e2309 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -332,32 +332,32 @@ static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
 }
 
 static struct dvb_usb_rc_key opera1_rc_keys[] = {
-	{0x5f, 0xa0, KEY_1},
-	{0x51, 0xaf, KEY_2},
-	{0x5d, 0xa2, KEY_3},
-	{0x41, 0xbe, KEY_4},
-	{0x0b, 0xf5, KEY_5},
-	{0x43, 0xbd, KEY_6},
-	{0x47, 0xb8, KEY_7},
-	{0x49, 0xb6, KEY_8},
-	{0x05, 0xfa, KEY_9},
-	{0x45, 0xba, KEY_0},
-	{0x09, 0xf6, KEY_UP},	/*chanup */
-	{0x1b, 0xe5, KEY_DOWN},	/*chandown */
-	{0x5d, 0xa3, KEY_LEFT},	/*voldown */
-	{0x5f, 0xa1, KEY_RIGHT},	/*volup */
-	{0x07, 0xf8, KEY_SPACE},	/*tab */
-	{0x1f, 0xe1, KEY_ENTER},	/*play ok */
-	{0x1b, 0xe4, KEY_Z},	/*zoom */
-	{0x59, 0xa6, KEY_M},	/*mute */
-	{0x5b, 0xa5, KEY_F},	/*tv/f */
-	{0x19, 0xe7, KEY_R},	/*rec */
-	{0x01, 0xfe, KEY_S},	/*Stop */
-	{0x03, 0xfd, KEY_P},	/*pause */
-	{0x03, 0xfc, KEY_W},	/*<- -> */
-	{0x07, 0xf9, KEY_C},	/*capture */
-	{0x47, 0xb9, KEY_Q},	/*exit */
-	{0x43, 0xbc, KEY_O},	/*power */
+	{0x5fa0, KEY_1},
+	{0x51af, KEY_2},
+	{0x5da2, KEY_3},
+	{0x41be, KEY_4},
+	{0x0bf5, KEY_5},
+	{0x43bd, KEY_6},
+	{0x47b8, KEY_7},
+	{0x49b6, KEY_8},
+	{0x05fa, KEY_9},
+	{0x45ba, KEY_0},
+	{0x09f6, KEY_UP},	/*chanup */
+	{0x1be5, KEY_DOWN},	/*chandown */
+	{0x5da3, KEY_LEFT},	/*voldown */
+	{0x5fa1, KEY_RIGHT},	/*volup */
+	{0x07f8, KEY_SPACE},	/*tab */
+	{0x1fe1, KEY_ENTER},	/*play ok */
+	{0x1be4, KEY_Z},	/*zoom */
+	{0x59a6, KEY_M},	/*mute */
+	{0x5ba5, KEY_F},	/*tv/f */
+	{0x19e7, KEY_R},	/*rec */
+	{0x01fe, KEY_S},	/*Stop */
+	{0x03fd, KEY_P},	/*pause */
+	{0x03fc, KEY_W},	/*<- -> */
+	{0x07f9, KEY_C},	/*capture */
+	{0x47b9, KEY_Q},	/*exit */
+	{0x43bc, KEY_O},	/*power */
 
 };
 
@@ -405,8 +405,7 @@ static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
 		send_key = (send_key & 0xffff) | 0x0100;
 
 		for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) {
-			if ((opera1_rc_keys[i].custom * 256 +
-					opera1_rc_keys[i].data) == (send_key & 0xffff)) {
+			if (rc5_scan(&opera1_rc_keys[i]) == (send_key & 0xffff)) {
 				*state = REMOTE_KEY_PRESSED;
 				*event = opera1_rc_keys[i].event;
 				opst->last_key_pressed =
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index 986fff9..ef4e37d 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -175,8 +175,8 @@ static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 
 /* keys for the enclosed remote control */
 static struct dvb_usb_rc_key vp702x_rc_keys[] = {
-	{ 0x00, 0x01, KEY_1 },
-	{ 0x00, 0x02, KEY_2 },
+	{ 0x0001, KEY_1 },
+	{ 0x0002, KEY_2 },
 };
 
 /* remote control stuff (does not work with my box) */
@@ -198,7 +198,7 @@ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	}
 
 	for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++)
-		if (vp702x_rc_keys[i].custom == key[1]) {
+		if (rc5_custom(&vp702x_rc_keys[i]) == key[1]) {
 			*state = REMOTE_KEY_PRESSED;
 			*event = vp702x_rc_keys[i].event;
 			break;
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index acb3455..a59faa2 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -100,56 +100,56 @@ static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
 /* The keymapping struct. Somehow this should be loaded to the driver, but
  * currently it is hardcoded. */
 static struct dvb_usb_rc_key vp7045_rc_keys[] = {
-	{ 0x00, 0x16, KEY_POWER },
-	{ 0x00, 0x10, KEY_MUTE },
-	{ 0x00, 0x03, KEY_1 },
-	{ 0x00, 0x01, KEY_2 },
-	{ 0x00, 0x06, KEY_3 },
-	{ 0x00, 0x09, KEY_4 },
-	{ 0x00, 0x1d, KEY_5 },
-	{ 0x00, 0x1f, KEY_6 },
-	{ 0x00, 0x0d, KEY_7 },
-	{ 0x00, 0x19, KEY_8 },
-	{ 0x00, 0x1b, KEY_9 },
-	{ 0x00, 0x15, KEY_0 },
-	{ 0x00, 0x05, KEY_CHANNELUP },
-	{ 0x00, 0x02, KEY_CHANNELDOWN },
-	{ 0x00, 0x1e, KEY_VOLUMEUP },
-	{ 0x00, 0x0a, KEY_VOLUMEDOWN },
-	{ 0x00, 0x11, KEY_RECORD },
-	{ 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
-	{ 0x00, 0x14, KEY_PLAY },
-	{ 0x00, 0x1a, KEY_STOP },
-	{ 0x00, 0x40, KEY_REWIND },
-	{ 0x00, 0x12, KEY_FASTFORWARD },
-	{ 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
-	{ 0x00, 0x4c, KEY_PAUSE },
-	{ 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
-	{ 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
-	{ 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
-	{ 0x00, 0x1c, KEY_EPG }, /* EPG */
-	{ 0x00, 0x00, KEY_TAB }, /* Tab */
-	{ 0x00, 0x48, KEY_INFO }, /* Preview */
-	{ 0x00, 0x04, KEY_LIST }, /* RecordList */
-	{ 0x00, 0x0f, KEY_TEXT }, /* Teletext */
-	{ 0x00, 0x41, KEY_PREVIOUSSONG },
-	{ 0x00, 0x42, KEY_NEXTSONG },
-	{ 0x00, 0x4b, KEY_UP },
-	{ 0x00, 0x51, KEY_DOWN },
-	{ 0x00, 0x4e, KEY_LEFT },
-	{ 0x00, 0x52, KEY_RIGHT },
-	{ 0x00, 0x4f, KEY_ENTER },
-	{ 0x00, 0x13, KEY_CANCEL },
-	{ 0x00, 0x4a, KEY_CLEAR },
-	{ 0x00, 0x54, KEY_PRINT }, /* Capture */
-	{ 0x00, 0x43, KEY_SUBTITLE }, /* Subtitle/CC */
-	{ 0x00, 0x08, KEY_VIDEO }, /* A/V */
-	{ 0x00, 0x07, KEY_SLEEP }, /* Hibernate */
-	{ 0x00, 0x45, KEY_ZOOM }, /* Zoom+ */
-	{ 0x00, 0x18, KEY_RED},
-	{ 0x00, 0x53, KEY_GREEN},
-	{ 0x00, 0x5e, KEY_YELLOW},
-	{ 0x00, 0x5f, KEY_BLUE}
+	{ 0x0016, KEY_POWER },
+	{ 0x0010, KEY_MUTE },
+	{ 0x0003, KEY_1 },
+	{ 0x0001, KEY_2 },
+	{ 0x0006, KEY_3 },
+	{ 0x0009, KEY_4 },
+	{ 0x001d, KEY_5 },
+	{ 0x001f, KEY_6 },
+	{ 0x000d, KEY_7 },
+	{ 0x0019, KEY_8 },
+	{ 0x001b, KEY_9 },
+	{ 0x0015, KEY_0 },
+	{ 0x0005, KEY_CHANNELUP },
+	{ 0x0002, KEY_CHANNELDOWN },
+	{ 0x001e, KEY_VOLUMEUP },
+	{ 0x000a, KEY_VOLUMEDOWN },
+	{ 0x0011, KEY_RECORD },
+	{ 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+	{ 0x0014, KEY_PLAY },
+	{ 0x001a, KEY_STOP },
+	{ 0x0040, KEY_REWIND },
+	{ 0x0012, KEY_FASTFORWARD },
+	{ 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+	{ 0x004c, KEY_PAUSE },
+	{ 0x004d, KEY_SCREEN }, /* Full screen mode. */
+	{ 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+	{ 0x000c, KEY_CANCEL }, /* Cancel */
+	{ 0x001c, KEY_EPG }, /* EPG */
+	{ 0x0000, KEY_TAB }, /* Tab */
+	{ 0x0048, KEY_INFO }, /* Preview */
+	{ 0x0004, KEY_LIST }, /* RecordList */
+	{ 0x000f, KEY_TEXT }, /* Teletext */
+	{ 0x0041, KEY_PREVIOUSSONG },
+	{ 0x0042, KEY_NEXTSONG },
+	{ 0x004b, KEY_UP },
+	{ 0x0051, KEY_DOWN },
+	{ 0x004e, KEY_LEFT },
+	{ 0x0052, KEY_RIGHT },
+	{ 0x004f, KEY_ENTER },
+	{ 0x0013, KEY_CANCEL },
+	{ 0x004a, KEY_CLEAR },
+	{ 0x0054, KEY_PRINT }, /* Capture */
+	{ 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
+	{ 0x0008, KEY_VIDEO }, /* A/V */
+	{ 0x0007, KEY_SLEEP }, /* Hibernate */
+	{ 0x0045, KEY_ZOOM }, /* Zoom+ */
+	{ 0x0018, KEY_RED},
+	{ 0x0053, KEY_GREEN},
+	{ 0x005e, KEY_YELLOW},
+	{ 0x005f, KEY_BLUE}
 };
 
 static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -166,7 +166,7 @@ static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 	}
 
 	for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++)
-		if (vp7045_rc_keys[i].data == key) {
+		if (rc5_data(&vp7045_rc_keys[i]) == key) {
 			*state = REMOTE_KEY_PRESSED;
 			*event = vp7045_rc_keys[i].event;
 			break;
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 32526f1..d1b67fe 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -89,15 +89,33 @@ struct avc_response_frame {
 	u8 operand[509];
 };
 
-#define AVC_DEBUG_FCP_SUBACTIONS	1
-#define AVC_DEBUG_FCP_PAYLOADS		2
+#define AVC_DEBUG_READ_DESCRIPTOR              0x0001
+#define AVC_DEBUG_DSIT                         0x0002
+#define AVC_DEBUG_DSD                          0x0004
+#define AVC_DEBUG_REGISTER_REMOTE_CONTROL      0x0008
+#define AVC_DEBUG_LNB_CONTROL                  0x0010
+#define AVC_DEBUG_TUNE_QPSK                    0x0020
+#define AVC_DEBUG_TUNE_QPSK2                   0x0040
+#define AVC_DEBUG_HOST2CA                      0x0080
+#define AVC_DEBUG_CA2HOST                      0x0100
+#define AVC_DEBUG_APPLICATION_PMT              0x4000
+#define AVC_DEBUG_FCP_PAYLOADS                 0x8000
 
 static int avc_debug;
 module_param_named(debug, avc_debug, int, 0644);
-MODULE_PARM_DESC(debug, "Verbose logging (default = 0"
-	", FCP subactions = "	__stringify(AVC_DEBUG_FCP_SUBACTIONS)
-	", FCP payloads = "	__stringify(AVC_DEBUG_FCP_PAYLOADS)
-	", or all = -1)");
+MODULE_PARM_DESC(debug, "Verbose logging (none = 0"
+	", FCP subactions"
+	": READ DESCRIPTOR = "		__stringify(AVC_DEBUG_READ_DESCRIPTOR)
+	", DSIT = "			__stringify(AVC_DEBUG_DSIT)
+	", REGISTER_REMOTE_CONTROL = "	__stringify(AVC_DEBUG_REGISTER_REMOTE_CONTROL)
+	", LNB CONTROL = "		__stringify(AVC_DEBUG_LNB_CONTROL)
+	", TUNE QPSK = "		__stringify(AVC_DEBUG_TUNE_QPSK)
+	", TUNE QPSK2 = "		__stringify(AVC_DEBUG_TUNE_QPSK2)
+	", HOST2CA = "			__stringify(AVC_DEBUG_HOST2CA)
+	", CA2HOST = "			__stringify(AVC_DEBUG_CA2HOST)
+	"; Application sent PMT = "	__stringify(AVC_DEBUG_APPLICATION_PMT)
+	", FCP payloads = "		__stringify(AVC_DEBUG_FCP_PAYLOADS)
+	", or a combination, or all = -1)");
 
 static const char *debug_fcp_ctype(unsigned int ctype)
 {
@@ -118,48 +136,70 @@ static const char *debug_fcp_opcode(unsigned int opcode,
 				    const u8 *data, int length)
 {
 	switch (opcode) {
-	case AVC_OPCODE_VENDOR:			break;
-	case AVC_OPCODE_READ_DESCRIPTOR:	return "ReadDescriptor";
-	case AVC_OPCODE_DSIT:			return "DirectSelectInfo.Type";
-	case AVC_OPCODE_DSD:			return "DirectSelectData";
-	default:				return "?";
+	case AVC_OPCODE_VENDOR:
+		break;
+	case AVC_OPCODE_READ_DESCRIPTOR:
+		return avc_debug & AVC_DEBUG_READ_DESCRIPTOR ?
+				"ReadDescriptor" : NULL;
+	case AVC_OPCODE_DSIT:
+		return avc_debug & AVC_DEBUG_DSIT ?
+				"DirectSelectInfo.Type" : NULL;
+	case AVC_OPCODE_DSD:
+		return avc_debug & AVC_DEBUG_DSD ? "DirectSelectData" : NULL;
+	default:
+		return "Unknown";
 	}
 
 	if (length < 7 ||
 	    data[3] != SFE_VENDOR_DE_COMPANYID_0 ||
 	    data[4] != SFE_VENDOR_DE_COMPANYID_1 ||
 	    data[5] != SFE_VENDOR_DE_COMPANYID_2)
-		return "Vendor";
+		return "Vendor/Unknown";
 
 	switch (data[6]) {
-	case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL:	return "RegisterRC";
-	case SFE_VENDOR_OPCODE_LNB_CONTROL:		return "LNBControl";
-	case SFE_VENDOR_OPCODE_TUNE_QPSK:		return "TuneQPSK";
-	case SFE_VENDOR_OPCODE_TUNE_QPSK2:		return "TuneQPSK2";
-	case SFE_VENDOR_OPCODE_HOST2CA:			return "Host2CA";
-	case SFE_VENDOR_OPCODE_CA2HOST:			return "CA2Host";
+	case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL:
+		return avc_debug & AVC_DEBUG_REGISTER_REMOTE_CONTROL ?
+				"RegisterRC" : NULL;
+	case SFE_VENDOR_OPCODE_LNB_CONTROL:
+		return avc_debug & AVC_DEBUG_LNB_CONTROL ? "LNBControl" : NULL;
+	case SFE_VENDOR_OPCODE_TUNE_QPSK:
+		return avc_debug & AVC_DEBUG_TUNE_QPSK ? "TuneQPSK" : NULL;
+	case SFE_VENDOR_OPCODE_TUNE_QPSK2:
+		return avc_debug & AVC_DEBUG_TUNE_QPSK2 ? "TuneQPSK2" : NULL;
+	case SFE_VENDOR_OPCODE_HOST2CA:
+		return avc_debug & AVC_DEBUG_HOST2CA ? "Host2CA" : NULL;
+	case SFE_VENDOR_OPCODE_CA2HOST:
+		return avc_debug & AVC_DEBUG_CA2HOST ? "CA2Host" : NULL;
 	}
-	return "Vendor";
+	return "Vendor/Unknown";
 }
 
 static void debug_fcp(const u8 *data, int length)
 {
-	unsigned int subunit_type, subunit_id, op;
-	const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
+	unsigned int subunit_type, subunit_id, opcode;
+	const char *op, *prefix;
+
+	prefix       = data[0] > 7 ? "FCP <- " : "FCP -> ";
+	subunit_type = data[1] >> 3;
+	subunit_id   = data[1] & 7;
+	opcode       = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
+	op           = debug_fcp_opcode(opcode, data, length);
 
-	if (avc_debug & AVC_DEBUG_FCP_SUBACTIONS) {
-		subunit_type = data[1] >> 3;
-		subunit_id = data[1] & 7;
-		op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
+	if (op) {
 		printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
 		       prefix, subunit_type, subunit_id, length,
-		       debug_fcp_ctype(data[0]),
-		       debug_fcp_opcode(op, data, length));
+		       debug_fcp_ctype(data[0]), op);
+		if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
+			print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE,
+				       16, 1, data, length, false);
 	}
+}
 
-	if (avc_debug & AVC_DEBUG_FCP_PAYLOADS)
-		print_hex_dump(KERN_INFO, prefix, DUMP_PREFIX_NONE, 16, 1,
-			       data, length, false);
+static void debug_pmt(char *msg, int length)
+{
+	printk(KERN_INFO "APP PMT -> l=%d\n", length);
+	print_hex_dump(KERN_INFO, "APP PMT -> ", DUMP_PREFIX_NONE,
+		       16, 1, msg, length, false);
 }
 
 static int __avc_write(struct firedtv *fdtv,
@@ -254,6 +294,26 @@ int avc_recv(struct firedtv *fdtv, void *data, size_t length)
 	return 0;
 }
 
+static int add_pid_filter(struct firedtv *fdtv, u8 *operand)
+{
+	int i, n, pos = 1;
+
+	for (i = 0, n = 0; i < 16; i++) {
+		if (test_bit(i, &fdtv->channel_active)) {
+			operand[pos++] = 0x13; /* flowfunction relay */
+			operand[pos++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
+			operand[pos++] = (fdtv->channel_pid[i] >> 8) & 0x1f;
+			operand[pos++] = fdtv->channel_pid[i] & 0xff;
+			operand[pos++] = 0x00; /* tableID */
+			operand[pos++] = 0x00; /* filter_length */
+			n++;
+		}
+	}
+	operand[0] = n;
+
+	return pos;
+}
+
 /*
  * tuning command for setting the relative LNB frequency
  * (not supported by the AVC standard)
@@ -316,7 +376,8 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
 	}
 }
 
-static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
+static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv,
+				struct dvb_frontend_parameters *params,
 				struct avc_command_frame *c)
 {
 	c->opcode = AVC_OPCODE_DSD;
@@ -378,13 +439,13 @@ static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
 
 	c->operand[20] = 0x00;
 	c->operand[21] = 0x00;
-	/* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
-	c->operand[22] = 0x00;
 
-	c->length = 28;
+	/* Add PIDs to filter */
+	c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4);
 }
 
-static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
+static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv,
+				struct dvb_frontend_parameters *params,
 				struct avc_command_frame *c)
 {
 	struct dvb_ofdm_parameters *ofdm = &params->u.ofdm;
@@ -481,10 +542,9 @@ static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
 
 	c->operand[15] = 0x00; /* network_ID[0] */
 	c->operand[16] = 0x00; /* network_ID[1] */
-	/* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
-	c->operand[17] = 0x00;
 
-	c->length = 24;
+	/* Add PIDs to filter */
+	c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4);
 }
 
 int avc_tuner_dsd(struct firedtv *fdtv,
@@ -502,8 +562,8 @@ int avc_tuner_dsd(struct firedtv *fdtv,
 	switch (fdtv->type) {
 	case FIREDTV_DVB_S:
 	case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break;
-	case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(params, c); break;
-	case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(params, c); break;
+	case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break;
+	case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break;
 	default:
 		BUG();
 	}
@@ -963,6 +1023,9 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length)
 	int es_info_length;
 	int crc32_csum;
 
+	if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT))
+		debug_pmt(msg, length);
+
 	memset(c, 0, sizeof(*c));
 
 	c->ctype   = AVC_CTYPE_CONTROL;
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index be967ac..d7c4837 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -81,6 +81,13 @@ config DVB_ZL10036
 	help
 	  A DVB-S tuner module. Say Y when you want to support this frontend.
 
+config DVB_ZL10039
+	tristate "Zarlink ZL10039 silicon tuner"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A DVB-S tuner module. Say Y when you want to support this frontend.
+
 config DVB_S5H1420
 	tristate "Samsung S5H1420 based"
 	depends on DVB_CORE && I2C
@@ -477,6 +484,14 @@ config DVB_S921
 	  AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
 	  Say Y when you want to support this frontend.
 
+config DVB_DIB8000
+	tristate "DiBcom 8000MB/MC"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
+	  Say Y when you want to support this frontend.
+
 comment "Digital terrestrial only tuners/PLL"
 	depends on DVB_CORE
 
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 832473c..3523767 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
 obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
 obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
 obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
+obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
 obj-$(CONFIG_DVB_MT312) += mt312.o
 obj-$(CONFIG_DVB_VES1820) += ves1820.o
 obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -31,6 +32,7 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o
 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
 obj-$(CONFIG_DVB_MT352) += mt352.o
 obj-$(CONFIG_DVB_ZL10036) += zl10036.o
+obj-$(CONFIG_DVB_ZL10039) += zl10039.o
 obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
 obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 9e9a755..74981ee 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -792,6 +792,11 @@ static int au8522_probe(struct i2c_client *client,
 	}
 
 	demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
+	if (demod_config == NULL) {
+		if (instance == 1)
+			kfree(state);
+		return -ENOMEM;
+	}
 	demod_config->demod_address = 0x8e >> 1;
 
 	state->config = demod_config;
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
index fbd838e..5fbc0fc 100644
--- a/drivers/media/dvb/frontends/cx22700.c
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -155,7 +155,7 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet
 	    p->hierarchy_information > HIERARCHY_4)
 		return -EINVAL;
 
-	if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ)
+	if (p->bandwidth < BANDWIDTH_8_MHZ || p->bandwidth > BANDWIDTH_6_MHZ)
 		return -EINVAL;
 
 	if (p->bandwidth == BANDWIDTH_7_MHZ)
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
index e4fd533..075b2b5 100644
--- a/drivers/media/dvb/frontends/cx24113.c
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -303,6 +303,7 @@ static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
 {
 	s32 N;
 	s64 F;
+	u64 dividend;
 	u8 R, r;
 	u8 vcodiv;
 	u8 factor;
@@ -346,7 +347,10 @@ static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
 	F = freq_hz;
 	F *= (u64) (R * vcodiv * 262144);
 	dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
-	do_div(F, state->config->xtal_khz*1000 * factor * 2);
+	/* do_div needs an u64 as first argument */
+	dividend = F;
+	do_div(dividend, state->config->xtal_khz * 1000 * factor * 2);
+	F = dividend;
 	dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
 	F -= (N + 32) * 262144;
 
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 0592f04..d8f921b 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -458,7 +458,7 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
 	/*  check if symbol rate is within limits */
 	if ((srate > state->frontend.ops.info.symbol_rate_max) ||
 	    (srate < state->frontend.ops.info.symbol_rate_min))
-		return -EOPNOTSUPP;;
+		return -EOPNOTSUPP;
 
 	/* choose the sampling rate high enough for the required operation,
 	   while optimizing the power consumed by the demodulator */
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index fe895bf..2be17b9 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -1,12 +1,29 @@
 /*
  * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
  *
- * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
+ * Copyright (C) 2005-9 DiBcom (http://www.dibcom.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, version 2.
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU 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 code is more or less generated from another driver, please
+ * excuse some codingstyle oddities.
+ *
  */
+
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 
@@ -19,27 +36,65 @@ static int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
 
-#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0)
+#define dprintk(args...) do { \
+	if (debug) { \
+		printk(KERN_DEBUG "DiB0070: "); \
+		printk(args); \
+		printk("\n"); \
+	} \
+} while (0)
 
 #define DIB0070_P1D  0x00
 #define DIB0070_P1F  0x01
 #define DIB0070_P1G  0x03
 #define DIB0070S_P1A 0x02
 
+enum frontend_tune_state {
+	CT_TUNER_START = 10,
+	CT_TUNER_STEP_0,
+	CT_TUNER_STEP_1,
+	CT_TUNER_STEP_2,
+	CT_TUNER_STEP_3,
+	CT_TUNER_STEP_4,
+	CT_TUNER_STEP_5,
+	CT_TUNER_STEP_6,
+	CT_TUNER_STEP_7,
+	CT_TUNER_STOP,
+};
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+
 struct dib0070_state {
 	struct i2c_adapter *i2c;
 	struct dvb_frontend *fe;
 	const struct dib0070_config *cfg;
 	u16 wbd_ff_offset;
 	u8 revision;
+
+	enum frontend_tune_state tune_state;
+	u32 current_rf;
+
+	/* for the captrim binary search */
+	s8 step;
+	u16 adc_diff;
+
+	s8 captrim;
+	s8 fcaptrim;
+	u16 lo4;
+
+	const struct dib0070_tuning *current_tune_table_index;
+	const struct dib0070_lna_match *lna_match;
+
+	u8 wbd_gain_current;
+	u16 wbd_offset_3_3[2];
 };
 
 static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
 {
 	u8 b[2];
 	struct i2c_msg msg[2] = {
-		{ .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
-		{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b,  .len = 2 },
+		{.addr = state->cfg->i2c_address,.flags = 0,.buf = &reg,.len = 1},
+		{.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
 	};
 	if (i2c_transfer(state->i2c, msg, 2) != 2) {
 		printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -51,7 +106,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
 static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
 {
 	u8 b[3] = { reg, val >> 8, val & 0xff };
-	struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
+	struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
 	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0070 I2C write failed\n");
 		return -EREMOTEIO;
@@ -59,55 +114,71 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
 	return 0;
 }
 
-#define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0)
+#define HARD_RESET(state) do { \
+    state->cfg->sleep(state->fe, 0); \
+    if (state->cfg->reset) { \
+	state->cfg->reset(state->fe,1); msleep(10); \
+	state->cfg->reset(state->fe,0); msleep(10); \
+    } \
+} while (0)
 
 static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
 {
-	struct dib0070_state *st = fe->tuner_priv;
-	u16 tmp = 0;
-	tmp = dib0070_read_reg(st, 0x02) & 0x3fff;
+	struct dib0070_state *state = fe->tuner_priv;
+	u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
+
+	if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
+		tmp |= (0 << 14);
+	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
+		tmp |= (1 << 14);
+	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
+		tmp |= (2 << 14);
+	else
+		tmp |= (3 << 14);
 
-    switch(BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)) {
-		case  8000:
-			tmp |= (0 << 14);
-			break;
-		case  7000:
-			tmp |= (1 << 14);
-			break;
-	case  6000:
-			tmp |= (2 << 14);
-			break;
-	case 5000:
-		default:
-			tmp |= (3 << 14);
-			break;
+	dib0070_write_reg(state, 0x02, tmp);
+
+	/* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
+	if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
+		u16 value = dib0070_read_reg(state, 0x17);
+
+		dib0070_write_reg(state, 0x17, value & 0xfffc);
+		tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
+		dib0070_write_reg(state, 0x01, tmp | (60 << 9));
+
+		dib0070_write_reg(state, 0x17, value);
 	}
-	dib0070_write_reg(st, 0x02, tmp);
 	return 0;
 }
 
-static void dib0070_captrim(struct dib0070_state *st, u16 LO4)
+static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
 {
-	int8_t captrim, fcaptrim, step_sign, step;
-	u16 adc, adc_diff = 3000;
+	int8_t step_sign;
+	u16 adc;
+	int ret = 0;
 
+	if (*tune_state == CT_TUNER_STEP_0) {
 
+		dib0070_write_reg(state, 0x0f, 0xed10);
+		dib0070_write_reg(state, 0x17, 0x0034);
 
-	dib0070_write_reg(st, 0x0f, 0xed10);
-	dib0070_write_reg(st, 0x17,    0x0034);
+		dib0070_write_reg(state, 0x18, 0x0032);
+		state->step = state->captrim = state->fcaptrim = 64;
+		state->adc_diff = 3000;
+		ret = 20;
 
-	dib0070_write_reg(st, 0x18, 0x0032);
-	msleep(2);
+		*tune_state = CT_TUNER_STEP_1;
+	} else if (*tune_state == CT_TUNER_STEP_1) {
+		state->step /= 2;
+		dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
+		ret = 15;
 
-	step = captrim = fcaptrim = 64;
+		*tune_state = CT_TUNER_STEP_2;
+	} else if (*tune_state == CT_TUNER_STEP_2) {
 
-	do {
-		step /= 2;
-		dib0070_write_reg(st, 0x14, LO4 | captrim);
-		msleep(1);
-		adc = dib0070_read_reg(st, 0x19);
+		adc = dib0070_read_reg(state, 0x19);
 
-		dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024);
+		dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
 
 		if (adc >= 400) {
 			adc -= 400;
@@ -117,379 +188,430 @@ static void dib0070_captrim(struct dib0070_state *st, u16 LO4)
 			step_sign = 1;
 		}
 
-		if (adc < adc_diff) {
-			dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff);
-			adc_diff = adc;
-			fcaptrim = captrim;
+		if (adc < state->adc_diff) {
+			dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
+			state->adc_diff = adc;
+			state->fcaptrim = state->captrim;
 
+		}
+		state->captrim += (step_sign * state->step);
 
+		if (state->step >= 1)
+			*tune_state = CT_TUNER_STEP_1;
+		else
+			*tune_state = CT_TUNER_STEP_3;
 
-		}
-		captrim += (step_sign * step);
-	} while (step >= 1);
+	} else if (*tune_state == CT_TUNER_STEP_3) {
+		dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
+		dib0070_write_reg(state, 0x18, 0x07ff);
+		*tune_state = CT_TUNER_STEP_4;
+	}
 
-	dib0070_write_reg(st, 0x14, LO4 | fcaptrim);
-	dib0070_write_reg(st, 0x18, 0x07ff);
+	return ret;
 }
 
-#define LPF	100                       // define for the loop filter 100kHz by default 16-07-06
-#define LO4_SET_VCO_HFDIV(l, v, h)   l |= ((v) << 11) | ((h) << 7)
-#define LO4_SET_SD(l, s)             l |= ((s) << 14) | ((s) << 12)
-#define LO4_SET_CTRIM(l, c)          l |=  (c) << 10
-static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
+static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
 {
-	struct dib0070_state *st = fe->tuner_priv;
-	u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf);
-
-	u8 band = BAND_OF_FREQUENCY(freq), c;
+	struct dib0070_state *state = fe->tuner_priv;
+	u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
+	dprintk("CTRL_LO5: 0x%x", lo5);
+	return dib0070_write_reg(state, 0x15, lo5);
+}
 
-	/*******************VCO***********************************/
-	u16 lo4 = 0;
+void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
+{
+	struct dib0070_state *state = fe->tuner_priv;
 
-	u8 REFDIV, PRESC = 2;
-	u32 FBDiv, Rest, FREF, VCOF_kHz;
-	u16 Num, Den;
-	/*******************FrontEnd******************************/
-	u16 value = 0;
+	if (open) {
+		dib0070_write_reg(state, 0x1b, 0xff00);
+		dib0070_write_reg(state, 0x1a, 0x0000);
+	} else {
+		dib0070_write_reg(state, 0x1b, 0x4112);
+		if (state->cfg->vga_filter != 0) {
+			dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
+			dprintk("vga filter register is set to %x", state->cfg->vga_filter);
+		} else
+			dib0070_write_reg(state, 0x1a, 0x0009);
+	}
+}
 
-	dprintk( "Tuning for Band: %hd (%d kHz)", band, freq);
+EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
+struct dib0070_tuning {
+	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
+	u8 switch_trim;
+	u8 vco_band;
+	u8 hfdiv;
+	u8 vco_multi;
+	u8 presc;
+	u8 wbdmux;
+	u16 tuner_enable;
+};
 
+struct dib0070_lna_match {
+	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
+	u8 lna_band;
+};
 
-	dib0070_write_reg(st, 0x17, 0x30);
+static const struct dib0070_tuning dib0070s_tuning_table[] = {
+	{570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800},	/* UHF */
+	{700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
+	{863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
+	{1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},	/* LBAND */
+	{1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
+	{2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
+	{0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000},	/* SBAND */
+};
 
-	dib0070_set_bandwidth(fe, ch);	/* c is used as HF */
-	switch (st->revision) {
-		case DIB0070S_P1A:
-			switch (band) {
-				case BAND_LBAND:
-					LO4_SET_VCO_HFDIV(lo4, 1, 1);
-					c = 2;
-					break;
-				case BAND_SBAND:
-					LO4_SET_VCO_HFDIV(lo4, 0, 0);
-					LO4_SET_CTRIM(lo4, 1);;
-					c = 1;
-					break;
-				case BAND_UHF:
-				default:
-					if (freq < 570000) {
-						LO4_SET_VCO_HFDIV(lo4, 1, 3);
-						PRESC = 6; c = 6;
-					} else if (freq < 680000) {
-						LO4_SET_VCO_HFDIV(lo4, 0, 2);
-						c = 4;
-					} else {
-						LO4_SET_VCO_HFDIV(lo4, 1, 2);
-						c = 4;
-					}
-					break;
-			} break;
-
-		case DIB0070_P1G:
-		case DIB0070_P1F:
-		default:
-			switch (band) {
-				case BAND_FM:
-						LO4_SET_VCO_HFDIV(lo4, 0, 7);
-						c = 24;
-					break;
-				case BAND_LBAND:
-						LO4_SET_VCO_HFDIV(lo4, 1, 0);
-						c = 2;
-					break;
-				case BAND_VHF:
-					if (freq < 180000) {
-						LO4_SET_VCO_HFDIV(lo4, 0, 3);
-						c = 16;
-					} else if (freq < 190000) {
-						LO4_SET_VCO_HFDIV(lo4, 1, 3);
-						c = 16;
-					} else {
-						LO4_SET_VCO_HFDIV(lo4, 0, 6);
-						c = 12;
-					}
-					break;
-
-				case BAND_UHF:
-				default:
-					if (freq < 570000) {
-						LO4_SET_VCO_HFDIV(lo4, 1, 5);
-						c = 6;
-					} else if (freq < 700000) {
-						LO4_SET_VCO_HFDIV(lo4, 0, 1);
-						c = 4;
-					} else {
-						LO4_SET_VCO_HFDIV(lo4, 1, 1);
-						c = 4;
-					}
-					break;
-			}
-		break;
-	}
+static const struct dib0070_tuning dib0070_tuning_table[] = {
+	{115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000},	/* FM below 92MHz cannot be tuned */
+	{179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000},	/* VHF */
+	{189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
+	{250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
+	{569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800},	/* UHF */
+	{699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
+	{863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
+	{0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400},	/* LBAND or everything higher than UHF */
+};
 
-	dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf);
-	dprintk( "VCO = %hd", (lo4 >> 11) & 0x3);
+static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
+	{180000, 0},		/* VHF */
+	{188000, 1},
+	{196400, 2},
+	{250000, 3},
+	{550000, 0},		/* UHF */
+	{590000, 1},
+	{666000, 3},
+	{864000, 5},
+	{1500000, 0},		/* LBAND or everything higher than UHF */
+	{1600000, 1},
+	{2000000, 3},
+	{0xffffffff, 7},
+};
 
+static const struct dib0070_lna_match dib0070_lna[] = {
+	{180000, 0},		/* VHF */
+	{188000, 1},
+	{196400, 2},
+	{250000, 3},
+	{550000, 2},		/* UHF */
+	{650000, 3},
+	{750000, 5},
+	{850000, 6},
+	{864000, 7},
+	{1500000, 0},		/* LBAND or everything higher than UHF */
+	{1600000, 1},
+	{2000000, 3},
+	{0xffffffff, 7},
+};
 
-	VCOF_kHz = (c * freq) * 2;
-	dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq);
+#define LPF	100		// define for the loop filter 100kHz by default 16-07-06
+static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
+{
+	struct dib0070_state *state = fe->tuner_priv;
 
-	switch (band) {
-		case BAND_VHF:
-			REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000);
-			break;
-		case BAND_FM:
-			REFDIV = (u8) ((st->cfg->clock_khz) / 1000);
-			break;
-		default:
-			REFDIV = (u8) ( st->cfg->clock_khz  / 10000);
-			break;
-	}
-	FREF = st->cfg->clock_khz / REFDIV;
+	const struct dib0070_tuning *tune;
+	const struct dib0070_lna_match *lna_match;
 
-	dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF);
+	enum frontend_tune_state *tune_state = &state->tune_state;
+	int ret = 10;		/* 1ms is the default delay most of the time */
 
+	u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
+	u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
 
+#ifdef CONFIG_SYS_ISDBT
+	if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
+		if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
+		     && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+		    || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+			&& (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
+		    || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+			&& (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
+			freq += 850;
+#endif
+	if (state->current_rf != freq) {
 
-	switch (st->revision) {
+		switch (state->revision) {
 		case DIB0070S_P1A:
-			FBDiv = (VCOF_kHz / PRESC / FREF);
-			Rest  = (VCOF_kHz / PRESC) - FBDiv * FREF;
+			tune = dib0070s_tuning_table;
+			lna_match = dib0070_lna;
 			break;
-
-		case DIB0070_P1G:
-		case DIB0070_P1F:
 		default:
-			FBDiv = (freq / (FREF / 2));
-			Rest  = 2 * freq - FBDiv * FREF;
+			tune = dib0070_tuning_table;
+			if (state->cfg->flip_chip)
+				lna_match = dib0070_lna_flip_chip;
+			else
+				lna_match = dib0070_lna;
 			break;
-	}
-
-
-	     if (Rest < LPF)              Rest = 0;
-	else if (Rest < 2 * LPF)          Rest = 2 * LPF;
-	else if (Rest > (FREF - LPF))   { Rest = 0 ; FBDiv += 1; }
-	else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF;
-	Rest = (Rest * 6528) / (FREF / 10);
-	dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest);
-
-	Num = 0;
-	Den = 1;
+		}
+		while (freq > tune->max_freq)	/* find the right one */
+			tune++;
+		while (freq > lna_match->max_freq)	/* find the right one */
+			lna_match++;
 
-	if (Rest > 0) {
-		LO4_SET_SD(lo4, 1);
-		Den = 255;
-		Num = (u16)Rest;
+		state->current_tune_table_index = tune;
+		state->lna_match = lna_match;
 	}
-	dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1);
 
+	if (*tune_state == CT_TUNER_START) {
+		dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
+		if (state->current_rf != freq) {
+			u8 REFDIV;
+			u32 FBDiv, Rest, FREF, VCOF_kHz;
+			u8 Den;
 
+			state->current_rf = freq;
+			state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
 
-	dib0070_write_reg(st, 0x11, (u16)FBDiv);
+			dib0070_write_reg(state, 0x17, 0x30);
 
+			VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
 
-	dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV);
-
+			switch (band) {
+			case BAND_VHF:
+				REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
+				break;
+			case BAND_FM:
+				REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
+				break;
+			default:
+				REFDIV = (u8) (state->cfg->clock_khz / 10000);
+				break;
+			}
+			FREF = state->cfg->clock_khz / REFDIV;
+
+			switch (state->revision) {
+			case DIB0070S_P1A:
+				FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
+				Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
+				break;
+
+			case DIB0070_P1G:
+			case DIB0070_P1F:
+			default:
+				FBDiv = (freq / (FREF / 2));
+				Rest = 2 * freq - FBDiv * FREF;
+				break;
+			}
 
-	dib0070_write_reg(st, 0x13, Num);
+			if (Rest < LPF)
+				Rest = 0;
+			else if (Rest < 2 * LPF)
+				Rest = 2 * LPF;
+			else if (Rest > (FREF - LPF)) {
+				Rest = 0;
+				FBDiv += 1;
+			} else if (Rest > (FREF - 2 * LPF))
+				Rest = FREF - 2 * LPF;
+			Rest = (Rest * 6528) / (FREF / 10);
+
+			Den = 1;
+			if (Rest > 0) {
+				state->lo4 |= (1 << 14) | (1 << 12);
+				Den = 255;
+			}
 
+			dib0070_write_reg(state, 0x11, (u16) FBDiv);
+			dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
+			dib0070_write_reg(state, 0x13, (u16) Rest);
 
-	value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001;
+			if (state->revision == DIB0070S_P1A) {
 
-	switch (band) {
-		case BAND_UHF:   value |= 0x4000 | 0x0800; break;
-		case BAND_LBAND: value |= 0x2000 | 0x0400; break;
-		default:         value |= 0x8000 | 0x1000; break;
-	}
-	dib0070_write_reg(st, 0x20, value);
+				if (band == BAND_SBAND) {
+					dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
+					dib0070_write_reg(state, 0x1d, 0xFFFF);
+				} else
+					dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
+			}
 
-	dib0070_captrim(st, lo4);
-	if (st->revision == DIB0070S_P1A) {
-		if (band == BAND_SBAND)
-			dib0070_write_reg(st, 0x15, 0x16e2);
-		else
-			dib0070_write_reg(st, 0x15, 0x56e5);
-	}
+			dib0070_write_reg(state, 0x20,
+					  0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
 
+			dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
+			dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
+			dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
+			dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
+			dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
+			dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
 
+			*tune_state = CT_TUNER_STEP_0;
+		} else {	/* we are already tuned to this frequency - the configuration is correct  */
+			ret = 50;	/* wakeup time */
+			*tune_state = CT_TUNER_STEP_5;
+		}
+	} else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
+
+		ret = dib0070_captrim(state, tune_state);
+
+	} else if (*tune_state == CT_TUNER_STEP_4) {
+		const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+		if (tmp != NULL) {
+			while (freq / 1000 > tmp->freq)	/* find the right one */
+				tmp++;
+			dib0070_write_reg(state, 0x0f,
+					  (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
+																current_tune_table_index->
+																wbdmux << 0));
+			state->wbd_gain_current = tmp->wbd_gain_val;
+		} else {
+			dib0070_write_reg(state, 0x0f,
+					  (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
+														wbdmux << 0));
+			state->wbd_gain_current = 6;
+		}
 
-	switch (band) {
-		case BAND_UHF:   value = 0x7c82; break;
-		case BAND_LBAND: value = 0x7c84; break;
-		default:         value = 0x7c81; break;
-	}
-	dib0070_write_reg(st, 0x0f, value);
-	dib0070_write_reg(st, 0x06, 0x3fff);
-
-	/* Front End */
-	/* c == TUNE, value = SWITCH */
-	c = 0;
-	value = 0;
-	switch (band) {
-		case BAND_FM:
-			c = 0; value = 1;
-		break;
-
-		case BAND_VHF:
-			if (freq <= 180000) c = 0;
-			else if (freq <= 188200) c = 1;
-			else if (freq <= 196400) c = 2;
-			else c = 3;
-			value = 1;
-		break;
-
-		case BAND_LBAND:
-			if (freq <= 1500000) c = 0;
-			else if (freq <= 1600000) c = 1;
-			else c = 3;
-		break;
-
-		case BAND_SBAND:
-			c = 7;
-			dib0070_write_reg(st, 0x1d,0xFFFF);
-		break;
-
-		case BAND_UHF:
-		default:
-			if (st->cfg->flip_chip) {
-				if (freq <= 550000) c = 0;
-				else if (freq <= 590000) c = 1;
-				else if (freq <= 666000) c = 3;
-				else c = 5;
-			} else {
-				if (freq <= 550000) c = 2;
-				else if (freq <= 650000) c = 3;
-				else if (freq <= 750000) c = 5;
-				else if (freq <= 850000) c = 6;
-				else c = 7;
-			}
-			value = 2;
-		break;
+		dib0070_write_reg(state, 0x06, 0x3fff);
+		dib0070_write_reg(state, 0x07,
+				  (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
+		dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
+		dib0070_write_reg(state, 0x0d, 0x0d80);
+
+		dib0070_write_reg(state, 0x18, 0x07ff);
+		dib0070_write_reg(state, 0x17, 0x0033);
+
+		*tune_state = CT_TUNER_STEP_5;
+	} else if (*tune_state == CT_TUNER_STEP_5) {
+		dib0070_set_bandwidth(fe, ch);
+		*tune_state = CT_TUNER_STOP;
+	} else {
+		ret = FE_CALLBACK_TIME_NEVER;	/* tuner finished, time to call again infinite */
 	}
+	return ret;
+}
 
-	/* default: LNA_MATCH=7, BIAS=3 */
-	dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0));
-	dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127));
-	dib0070_write_reg(st, 0x0d, 0x0d80);
+static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+	struct dib0070_state *state = fe->tuner_priv;
+	uint32_t ret;
 
+	state->tune_state = CT_TUNER_START;
 
-	dib0070_write_reg(st, 0x18,   0x07ff);
-	dib0070_write_reg(st, 0x17, 0x0033);
+	do {
+		ret = dib0070_tune_digital(fe, p);
+		if (ret != FE_CALLBACK_TIME_NEVER)
+			msleep(ret / 10);
+		else
+			break;
+	} while (state->tune_state != CT_TUNER_STOP);
 
 	return 0;
 }
 
 static int dib0070_wakeup(struct dvb_frontend *fe)
 {
-	struct dib0070_state *st = fe->tuner_priv;
-	if (st->cfg->sleep)
-		st->cfg->sleep(fe, 0);
+	struct dib0070_state *state = fe->tuner_priv;
+	if (state->cfg->sleep)
+		state->cfg->sleep(fe, 0);
 	return 0;
 }
 
 static int dib0070_sleep(struct dvb_frontend *fe)
 {
-	struct dib0070_state *st = fe->tuner_priv;
-	if (st->cfg->sleep)
-		st->cfg->sleep(fe, 1);
+	struct dib0070_state *state = fe->tuner_priv;
+	if (state->cfg->sleep)
+		state->cfg->sleep(fe, 1);
 	return 0;
 }
 
-static u16 dib0070_p1f_defaults[] =
-
-{
+static const u16 dib0070_p1f_defaults[] = {
 	7, 0x02,
-		0x0008,
-		0x0000,
-		0x0000,
-		0x0000,
-		0x0000,
-		0x0002,
-		0x0100,
+	0x0008,
+	0x0000,
+	0x0000,
+	0x0000,
+	0x0000,
+	0x0002,
+	0x0100,
 
 	3, 0x0d,
-		0x0d80,
-		0x0001,
-		0x0000,
+	0x0d80,
+	0x0001,
+	0x0000,
 
 	4, 0x11,
-		0x0000,
-		0x0103,
-		0x0000,
-		0x0000,
+	0x0000,
+	0x0103,
+	0x0000,
+	0x0000,
 
 	3, 0x16,
-		0x0004 | 0x0040,
-		0x0030,
-		0x07ff,
+	0x0004 | 0x0040,
+	0x0030,
+	0x07ff,
 
 	6, 0x1b,
-		0x4112,
-		0xff00,
-		0xc07f,
-		0x0000,
-		0x0180,
-		0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
+	0x4112,
+	0xff00,
+	0xc07f,
+	0x0000,
+	0x0180,
+	0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
 
 	0,
 };
 
-static void dib0070_wbd_calibration(struct dvb_frontend *fe)
+static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
 {
-	u16 wbd_offs;
-	struct dib0070_state *state = fe->tuner_priv;
-
-	if (state->cfg->sleep)
-		state->cfg->sleep(fe, 0);
+	u16 tuner_en = dib0070_read_reg(state, 0x20);
+	u16 offset;
 
-	dib0070_write_reg(state, 0x0f, 0x6d81);
-	dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+	dib0070_write_reg(state, 0x18, 0x07ff);
+	dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
+	dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
 	msleep(9);
-	wbd_offs = dib0070_read_reg(state, 0x19);
-	dib0070_write_reg(state, 0x20, 0);
-	state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2);
-	dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset);
-
-	if (state->cfg->sleep)
-		state->cfg->sleep(fe, 1);
-
+	offset = dib0070_read_reg(state, 0x19);
+	dib0070_write_reg(state, 0x20, tuner_en);
+	return offset;
 }
 
-u16 dib0070_wbd_offset(struct dvb_frontend *fe)
+static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
 {
-	struct dib0070_state *st = fe->tuner_priv;
-	return st->wbd_ff_offset;
+	u8 gain;
+	for (gain = 6; gain < 8; gain++) {
+		state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
+		dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
+	}
 }
 
-EXPORT_SYMBOL(dib0070_wbd_offset);
-static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
+u16 dib0070_wbd_offset(struct dvb_frontend *fe)
 {
 	struct dib0070_state *state = fe->tuner_priv;
-    u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
-	dprintk( "CTRL_LO5: 0x%x", lo5);
-	return dib0070_write_reg(state, 0x15, lo5);
+	const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
+	u32 freq = fe->dtv_property_cache.frequency / 1000;
+
+	if (tmp != NULL) {
+		while (freq / 1000 > tmp->freq)	/* find the right one */
+			tmp++;
+		state->wbd_gain_current = tmp->wbd_gain_val;
+	} else
+		state->wbd_gain_current = 6;
+
+	return state->wbd_offset_3_3[state->wbd_gain_current - 6];
 }
 
+EXPORT_SYMBOL(dib0070_wbd_offset);
+
 #define pgm_read_word(w) (*w)
-static int dib0070_reset(struct dib0070_state *state)
+static int dib0070_reset(struct dvb_frontend *fe)
 {
+	struct dib0070_state *state = fe->tuner_priv;
 	u16 l, r, *n;
 
 	HARD_RESET(state);
 
-
 #ifndef FORCE_SBAND_TUNER
 	if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
 		state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
 	else
+#else
+#warning forcing SBAND
 #endif
-		state->revision = DIB0070S_P1A;
+	state->revision = DIB0070S_P1A;
 
 	/* P1F or not */
-	dprintk( "Revision: %x", state->revision);
+	dprintk("Revision: %x", state->revision);
 
 	if (state->revision == DIB0070_P1D) {
-		dprintk( "Error: this driver is not to be used meant for P1D or earlier");
+		dprintk("Error: this driver is not to be used meant for P1D or earlier");
 		return -EINVAL;
 	}
 
@@ -498,7 +620,7 @@ static int dib0070_reset(struct dib0070_state *state)
 	while (l) {
 		r = pgm_read_word(n++);
 		do {
-			dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
+			dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
 			r++;
 		} while (--l);
 		l = pgm_read_word(n++);
@@ -514,24 +636,25 @@ static int dib0070_reset(struct dib0070_state *state)
 	r |= state->cfg->osc_buffer_state << 3;
 
 	dib0070_write_reg(state, 0x10, r);
-	dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4));
+	dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
 
 	if (state->cfg->invert_iq) {
 		r = dib0070_read_reg(state, 0x02) & 0xffdf;
 		dib0070_write_reg(state, 0x02, r | (1 << 5));
 	}
 
-
 	if (state->revision == DIB0070S_P1A)
-		dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1);
+		dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
 	else
-		dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0);
+		dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
 
 	dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
+
+	dib0070_wbd_offset_calibration(state);
+
 	return 0;
 }
 
-
 static int dib0070_release(struct dvb_frontend *fe)
 {
 	kfree(fe->tuner_priv);
@@ -539,23 +662,24 @@ static int dib0070_release(struct dvb_frontend *fe)
 	return 0;
 }
 
-static struct dvb_tuner_ops dib0070_ops = {
+static const struct dvb_tuner_ops dib0070_ops = {
 	.info = {
-		.name           = "DiBcom DiB0070",
-		.frequency_min  =  45000000,
-		.frequency_max  = 860000000,
-		.frequency_step =      1000,
-	},
-	.release       = dib0070_release,
-
-	.init          = dib0070_wakeup,
-	.sleep         = dib0070_sleep,
-	.set_params    = dib0070_tune_digital,
-//	.get_frequency = dib0070_get_frequency,
-//	.get_bandwidth = dib0070_get_bandwidth
+		 .name = "DiBcom DiB0070",
+		 .frequency_min = 45000000,
+		 .frequency_max = 860000000,
+		 .frequency_step = 1000,
+		 },
+	.release = dib0070_release,
+
+	.init = dib0070_wakeup,
+	.sleep = dib0070_sleep,
+	.set_params = dib0070_tune,
+
+//      .get_frequency = dib0070_get_frequency,
+//      .get_bandwidth = dib0070_get_bandwidth
 };
 
-struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
+struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
 {
 	struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
 	if (state == NULL)
@@ -563,25 +687,24 @@ struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
 
 	state->cfg = cfg;
 	state->i2c = i2c;
-	state->fe  = fe;
+	state->fe = fe;
 	fe->tuner_priv = state;
 
-	if (dib0070_reset(state) != 0)
+	if (dib0070_reset(fe) != 0)
 		goto free_mem;
 
-	dib0070_wbd_calibration(fe);
-
 	printk(KERN_INFO "DiB0070: successfully identified\n");
 	memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
 
 	fe->tuner_priv = state;
 	return fe;
 
-free_mem:
+ free_mem:
 	kfree(state);
 	fe->tuner_priv = NULL;
 	return NULL;
 }
+
 EXPORT_SYMBOL(dib0070_attach);
 
 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 9670f5d..8a2e1e7 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -15,6 +15,11 @@ struct i2c_adapter;
 
 #define DEFAULT_DIB0070_I2C_ADDRESS 0x60
 
+struct dib0070_wbd_gain_cfg {
+	u16 freq;
+	u16 wbd_gain_val;
+};
+
 struct dib0070_config {
 	u8 i2c_address;
 
@@ -26,26 +31,28 @@ struct dib0070_config {
 	int freq_offset_khz_uhf;
 	int freq_offset_khz_vhf;
 
-	u8 osc_buffer_state; /* 0= normal, 1= tri-state */
-	u32  clock_khz;
-	u8 clock_pad_drive; /* (Drive + 1) * 2mA */
+	u8 osc_buffer_state;	/* 0= normal, 1= tri-state */
+	u32 clock_khz;
+	u8 clock_pad_drive;	/* (Drive + 1) * 2mA */
 
-	u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
+	u8 invert_iq;		/* invert Q - in case I or Q is inverted on the board */
 
-	u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
+	u8 force_crystal_mode;	/* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
 
 	u8 flip_chip;
+	u8 enable_third_order_filter;
+	u8 charge_pump;
+
+	const struct dib0070_wbd_gain_cfg *wbd_gain;
+
+	u8 vga_filter;
 };
 
 #if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
-extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
-					   struct i2c_adapter *i2c,
-					   struct dib0070_config *cfg);
+extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
 extern u16 dib0070_wbd_offset(struct dvb_frontend *);
 #else
-static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
-						  struct i2c_adapter *i2c,
-						  struct dib0070_config *cfg)
+static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
 {
 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
 	return NULL;
@@ -57,5 +64,6 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
 	return -ENODEV;
 }
 #endif
+extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
 
 #endif
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 8217e5b..55ef6ee 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/i2c.h>
 
+#include "dvb_math.h"
 #include "dvb_frontend.h"
 
 #include "dib7000p.h"
@@ -883,7 +884,7 @@ static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32
 	255, 255, 255, 255, 255, 255};
 
 	u32 xtal = state->cfg.bw->xtal_hz / 1000;
-	int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;
+	int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
 	int k;
 	int coef_re[8],coef_im[8];
 	int bw_khz = bw;
@@ -1217,7 +1218,37 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 
 static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
 {
-	*snr = 0x0000;
+	struct dib7000p_state *state = fe->demodulator_priv;
+	u16 val;
+	s32 signal_mant, signal_exp, noise_mant, noise_exp;
+	u32 result = 0;
+
+	val = dib7000p_read_word(state, 479);
+	noise_mant = (val >> 4) & 0xff;
+	noise_exp = ((val & 0xf) << 2);
+	val = dib7000p_read_word(state, 480);
+	noise_exp += ((val >> 14) & 0x3);
+	if ((noise_exp & 0x20) != 0)
+		noise_exp -= 0x40;
+
+	signal_mant = (val >> 6) & 0xFF;
+	signal_exp  = (val & 0x3F);
+	if ((signal_exp & 0x20) != 0)
+		signal_exp -= 0x40;
+
+	if (signal_mant != 0)
+		result = intlog10(2) * 10 * signal_exp + 10 *
+			intlog10(signal_mant);
+	else
+		result = intlog10(2) * 10 * signal_exp - 100;
+
+	if (noise_mant != 0)
+		result -= intlog10(2) * 10 * noise_exp + 10 *
+			intlog10(noise_mant);
+	else
+		result -= intlog10(2) * 10 * noise_exp - 100;
+
+	*snr = result / ((1 << 24) / 10);
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
new file mode 100644
index 0000000..852c790
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -0,0 +1,2277 @@
+/*
+ * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
+ *
+ * Copyright (C) 2009 DiBcom (http://www.dibcom.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, version 2.
+ */
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include "dvb_math.h"
+
+#include "dvb_frontend.h"
+
+#include "dib8000.h"
+
+#define LAYER_ALL -1
+#define LAYER_A   1
+#define LAYER_B   2
+#define LAYER_C   3
+
+#define FE_CALLBACK_TIME_NEVER 0xffffffff
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
+
+#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
+
+enum frontend_tune_state {
+	CT_AGC_START = 20,
+	CT_AGC_STEP_0,
+	CT_AGC_STEP_1,
+	CT_AGC_STEP_2,
+	CT_AGC_STEP_3,
+	CT_AGC_STEP_4,
+	CT_AGC_STOP,
+
+	CT_DEMOD_START = 30,
+};
+
+#define FE_STATUS_TUNE_FAILED 0
+
+struct i2c_device {
+	struct i2c_adapter *adap;
+	u8 addr;
+};
+
+struct dib8000_state {
+	struct dvb_frontend fe;
+	struct dib8000_config cfg;
+
+	struct i2c_device i2c;
+
+	struct dibx000_i2c_master i2c_master;
+
+	u16 wbd_ref;
+
+	u8 current_band;
+	u32 current_bandwidth;
+	struct dibx000_agc_config *current_agc;
+	u32 timf;
+	u32 timf_default;
+
+	u8 div_force_off:1;
+	u8 div_state:1;
+	u16 div_sync_wait;
+
+	u8 agc_state;
+	u8 differential_constellation;
+	u8 diversity_onoff;
+
+	s16 ber_monitored_layer;
+	u16 gpio_dir;
+	u16 gpio_val;
+
+	u16 revision;
+	u8 isdbt_cfg_loaded;
+	enum frontend_tune_state tune_state;
+	u32 status;
+};
+
+enum dib8000_power_mode {
+	DIB8000M_POWER_ALL = 0,
+	DIB8000M_POWER_INTERFACE_ONLY,
+};
+
+static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
+{
+	u8 wb[2] = { reg >> 8, reg & 0xff };
+	u8 rb[2];
+	struct i2c_msg msg[2] = {
+		{.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
+		{.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
+	};
+
+	if (i2c_transfer(i2c->adap, msg, 2) != 2)
+		dprintk("i2c read error on %d", reg);
+
+	return (rb[0] << 8) | rb[1];
+}
+
+static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
+{
+	return dib8000_i2c_read16(&state->i2c, reg);
+}
+
+static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
+{
+	u16 rw[2];
+
+	rw[0] = dib8000_read_word(state, reg + 0);
+	rw[1] = dib8000_read_word(state, reg + 1);
+
+	return ((rw[0] << 16) | (rw[1]));
+}
+
+static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
+{
+	u8 b[4] = {
+		(reg >> 8) & 0xff, reg & 0xff,
+		(val >> 8) & 0xff, val & 0xff,
+	};
+	struct i2c_msg msg = {
+		.addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
+	};
+	return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+}
+
+static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
+{
+	return dib8000_i2c_write16(&state->i2c, reg, val);
+}
+
+const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
+	(769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
+	    (920 << 5) | 0x09
+};
+
+const int16_t coeff_2k_sb_1seg[8] = {
+	(692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
+};
+
+const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
+	(832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
+	    (-931 << 5) | 0x0f
+};
+
+const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
+	(622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
+	    (982 << 5) | 0x0c
+};
+
+const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
+	(699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
+	    (-720 << 5) | 0x0d
+};
+
+const int16_t coeff_2k_sb_3seg[8] = {
+	(664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
+	    (-610 << 5) | 0x0a
+};
+
+const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
+	(-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
+	    (-922 << 5) | 0x0d
+};
+
+const int16_t coeff_4k_sb_1seg[8] = {
+	(638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
+	    (-655 << 5) | 0x0a
+};
+
+const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
+	(-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
+	    (-958 << 5) | 0x13
+};
+
+const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
+	(-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
+	    (-568 << 5) | 0x0f
+};
+
+const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
+	(-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
+	    (-848 << 5) | 0x13
+};
+
+const int16_t coeff_4k_sb_3seg[8] = {
+	(612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
+	    (-869 << 5) | 0x13
+};
+
+const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
+	(-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
+	    (-598 << 5) | 0x10
+};
+
+const int16_t coeff_8k_sb_1seg[8] = {
+	(673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
+	    (585 << 5) | 0x0f
+};
+
+const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
+	(863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
+	    (0 << 5) | 0x14
+};
+
+const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
+	(-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
+	    (-877 << 5) | 0x15
+};
+
+const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
+	(-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
+	    (-921 << 5) | 0x14
+};
+
+const int16_t coeff_8k_sb_3seg[8] = {
+	(514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
+	    (690 << 5) | 0x14
+};
+
+const int16_t ana_fe_coeff_3seg[24] = {
+	81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
+};
+
+const int16_t ana_fe_coeff_1seg[24] = {
+	249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
+};
+
+const int16_t ana_fe_coeff_13seg[24] = {
+	396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
+};
+
+static u16 fft_to_mode(struct dib8000_state *state)
+{
+	u16 mode;
+	switch (state->fe.dtv_property_cache.transmission_mode) {
+	case TRANSMISSION_MODE_2K:
+		mode = 1;
+		break;
+	case TRANSMISSION_MODE_4K:
+		mode = 2;
+		break;
+	default:
+	case TRANSMISSION_MODE_AUTO:
+	case TRANSMISSION_MODE_8K:
+		mode = 3;
+		break;
+	}
+	return mode;
+}
+
+static void dib8000_set_acquisition_mode(struct dib8000_state *state)
+{
+	u16 nud = dib8000_read_word(state, 298);
+	nud |= (1 << 3) | (1 << 0);
+	dprintk("acquisition mode activated");
+	dib8000_write_word(state, 298, nud);
+}
+
+static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
+{
+	u16 outreg, fifo_threshold, smo_mode, sram = 0x0205;	/* by default SDRAM deintlv is enabled */
+
+	outreg = 0;
+	fifo_threshold = 1792;
+	smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
+
+	dprintk("-I-  Setting output mode for demod %p to %d", &state->fe, mode);
+
+	switch (mode) {
+	case OUTMODE_MPEG2_PAR_GATED_CLK:	// STBs with parallel gated clock
+		outreg = (1 << 10);	/* 0x0400 */
+		break;
+	case OUTMODE_MPEG2_PAR_CONT_CLK:	// STBs with parallel continues clock
+		outreg = (1 << 10) | (1 << 6);	/* 0x0440 */
+		break;
+	case OUTMODE_MPEG2_SERIAL:	// STBs with serial input
+		outreg = (1 << 10) | (2 << 6) | (0 << 1);	/* 0x0482 */
+		break;
+	case OUTMODE_DIVERSITY:
+		if (state->cfg.hostbus_diversity) {
+			outreg = (1 << 10) | (4 << 6);	/* 0x0500 */
+			sram &= 0xfdff;
+		} else
+			sram |= 0x0c00;
+		break;
+	case OUTMODE_MPEG2_FIFO:	// e.g. USB feeding
+		smo_mode |= (3 << 1);
+		fifo_threshold = 512;
+		outreg = (1 << 10) | (5 << 6);
+		break;
+	case OUTMODE_HIGH_Z:	// disable
+		outreg = 0;
+		break;
+
+	case OUTMODE_ANALOG_ADC:
+		outreg = (1 << 10) | (3 << 6);
+		dib8000_set_acquisition_mode(state);
+		break;
+
+	default:
+		dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
+		return -EINVAL;
+	}
+
+	if (state->cfg.output_mpeg2_in_188_bytes)
+		smo_mode |= (1 << 5);
+
+	dib8000_write_word(state, 299, smo_mode);
+	dib8000_write_word(state, 300, fifo_threshold);	/* synchronous fread */
+	dib8000_write_word(state, 1286, outreg);
+	dib8000_write_word(state, 1291, sram);
+
+	return 0;
+}
+
+static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
+
+	if (!state->differential_constellation) {
+		dib8000_write_word(state, 272, 1 << 9);	//dvsy_off_lmod4 = 1
+		dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2);	// sync_enable = 1; comb_mode = 2
+	} else {
+		dib8000_write_word(state, 272, 0);	//dvsy_off_lmod4 = 0
+		dib8000_write_word(state, 273, sync_wait);	// sync_enable = 0; comb_mode = 0
+	}
+	state->diversity_onoff = onoff;
+
+	switch (onoff) {
+	case 0:		/* only use the internal way - not the diversity input */
+		dib8000_write_word(state, 270, 1);
+		dib8000_write_word(state, 271, 0);
+		break;
+	case 1:		/* both ways */
+		dib8000_write_word(state, 270, 6);
+		dib8000_write_word(state, 271, 6);
+		break;
+	case 2:		/* only the diversity input */
+		dib8000_write_word(state, 270, 0);
+		dib8000_write_word(state, 271, 1);
+		break;
+	}
+	return 0;
+}
+
+static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
+{
+	/* by default everything is going to be powered off */
+	u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
+	    reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
+
+	/* now, depending on the requested mode, we power on */
+	switch (mode) {
+		/* power up everything in the demod */
+	case DIB8000M_POWER_ALL:
+		reg_774 = 0x0000;
+		reg_775 = 0x0000;
+		reg_776 = 0x0000;
+		reg_900 &= 0xfffc;
+		reg_1280 &= 0x00ff;
+		break;
+	case DIB8000M_POWER_INTERFACE_ONLY:
+		reg_1280 &= 0x00ff;
+		break;
+	}
+
+	dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
+	dib8000_write_word(state, 774, reg_774);
+	dib8000_write_word(state, 775, reg_775);
+	dib8000_write_word(state, 776, reg_776);
+	dib8000_write_word(state, 900, reg_900);
+	dib8000_write_word(state, 1280, reg_1280);
+}
+
+static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
+{
+	int ret = 0;
+	u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
+
+	switch (no) {
+	case DIBX000_SLOW_ADC_ON:
+		reg_908 |= (1 << 1) | (1 << 0);
+		ret |= dib8000_write_word(state, 908, reg_908);
+		reg_908 &= ~(1 << 1);
+		break;
+
+	case DIBX000_SLOW_ADC_OFF:
+		reg_908 |= (1 << 1) | (1 << 0);
+		break;
+
+	case DIBX000_ADC_ON:
+		reg_907 &= 0x0fff;
+		reg_908 &= 0x0003;
+		break;
+
+	case DIBX000_ADC_OFF:	// leave the VBG voltage on
+		reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
+		reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
+		break;
+
+	case DIBX000_VBG_ENABLE:
+		reg_907 &= ~(1 << 15);
+		break;
+
+	case DIBX000_VBG_DISABLE:
+		reg_907 |= (1 << 15);
+		break;
+
+	default:
+		break;
+	}
+
+	ret |= dib8000_write_word(state, 907, reg_907);
+	ret |= dib8000_write_word(state, 908, reg_908);
+
+	return ret;
+}
+
+static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
+{
+	u32 timf;
+
+	if (bw == 0)
+		bw = 6000;
+
+	if (state->timf == 0) {
+		dprintk("using default timf");
+		timf = state->timf_default;
+	} else {
+		dprintk("using updated timf");
+		timf = state->timf;
+	}
+
+	dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
+	dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
+
+	return 0;
+}
+
+static int dib8000_sad_calib(struct dib8000_state *state)
+{
+/* internal */
+	dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
+	dib8000_write_word(state, 924, 776);	// 0.625*3.3 / 4096
+
+	/* do the calibration */
+	dib8000_write_word(state, 923, (1 << 0));
+	dib8000_write_word(state, 923, (0 << 0));
+
+	msleep(1);
+	return 0;
+}
+
+int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	if (value > 4095)
+		value = 4095;
+	state->wbd_ref = value;
+	return dib8000_write_word(state, 106, value);
+}
+
+EXPORT_SYMBOL(dib8000_set_wbd_ref);
+static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
+{
+	dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
+	dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff));	/* P_sec_len */
+	dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
+	dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
+	dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
+	dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
+
+	dib8000_write_word(state, 922, bw->sad_cfg);
+}
+
+static void dib8000_reset_pll(struct dib8000_state *state)
+{
+	const struct dibx000_bandwidth_config *pll = state->cfg.pll;
+	u16 clk_cfg1;
+
+	// clk_cfg0
+	dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
+
+	// clk_cfg1
+	clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
+	    (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
+
+	dib8000_write_word(state, 902, clk_cfg1);
+	clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
+	dib8000_write_word(state, 902, clk_cfg1);
+
+	dprintk("clk_cfg1: 0x%04x", clk_cfg1);	/* 0x507 1 0 1 000 0 0 11 1 */
+
+	/* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
+	if (state->cfg.pll->ADClkSrc == 0)
+		dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
+	else if (state->cfg.refclksel != 0)
+		dib8000_write_word(state, 904,
+				   (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
+															ADClkSrc << 7) | (0 << 1));
+	else
+		dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
+
+	dib8000_reset_pll_common(state, pll);
+}
+
+static int dib8000_reset_gpio(struct dib8000_state *st)
+{
+	/* reset the GPIOs */
+	dib8000_write_word(st, 1029, st->cfg.gpio_dir);
+	dib8000_write_word(st, 1030, st->cfg.gpio_val);
+
+	/* TODO 782 is P_gpio_od */
+
+	dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
+
+	dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
+	return 0;
+}
+
+static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
+{
+	st->cfg.gpio_dir = dib8000_read_word(st, 1029);
+	st->cfg.gpio_dir &= ~(1 << num);	/* reset the direction bit */
+	st->cfg.gpio_dir |= (dir & 0x1) << num;	/* set the new direction */
+	dib8000_write_word(st, 1029, st->cfg.gpio_dir);
+
+	st->cfg.gpio_val = dib8000_read_word(st, 1030);
+	st->cfg.gpio_val &= ~(1 << num);	/* reset the direction bit */
+	st->cfg.gpio_val |= (val & 0x01) << num;	/* set the new value */
+	dib8000_write_word(st, 1030, st->cfg.gpio_val);
+
+	dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
+
+	return 0;
+}
+
+int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	return dib8000_cfg_gpio(state, num, dir, val);
+}
+
+EXPORT_SYMBOL(dib8000_set_gpio);
+static const u16 dib8000_defaults[] = {
+	/* auto search configuration - lock0 by default waiting
+	 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
+	3, 7,
+	0x0004,
+	0x0400,
+	0x0814,
+
+	12, 11,
+	0x001b,
+	0x7740,
+	0x005b,
+	0x8d80,
+	0x01c9,
+	0xc380,
+	0x0000,
+	0x0080,
+	0x0000,
+	0x0090,
+	0x0001,
+	0xd4c0,
+
+	/*1, 32,
+	   0x6680 // P_corm_thres Lock algorithms configuration */
+
+	11, 80,			/* set ADC level to -16 */
+	(1 << 13) - 825 - 117,
+	(1 << 13) - 837 - 117,
+	(1 << 13) - 811 - 117,
+	(1 << 13) - 766 - 117,
+	(1 << 13) - 737 - 117,
+	(1 << 13) - 693 - 117,
+	(1 << 13) - 648 - 117,
+	(1 << 13) - 619 - 117,
+	(1 << 13) - 575 - 117,
+	(1 << 13) - 531 - 117,
+	(1 << 13) - 501 - 117,
+
+	4, 108,
+	0,
+	0,
+	0,
+	0,
+
+	1, 175,
+	0x0410,
+	1, 179,
+	8192,			// P_fft_nb_to_cut
+
+	6, 181,
+	0x2800,			// P_coff_corthres_ ( 2k 4k 8k ) 0x2800
+	0x2800,
+	0x2800,
+	0x2800,			// P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
+	0x2800,
+	0x2800,
+
+	2, 193,
+	0x0666,			// P_pha3_thres
+	0x0000,			// P_cti_use_cpe, P_cti_use_prog
+
+	2, 205,
+	0x200f,			// P_cspu_regul, P_cspu_win_cut
+	0x000f,			// P_des_shift_work
+
+	5, 215,
+	0x023d,			// P_adp_regul_cnt
+	0x00a4,			// P_adp_noise_cnt
+	0x00a4,			// P_adp_regul_ext
+	0x7ff0,			// P_adp_noise_ext
+	0x3ccc,			// P_adp_fil
+
+	1, 230,
+	0x0000,			// P_2d_byp_ti_num
+
+	1, 263,
+	0x800,			//P_equal_thres_wgn
+
+	1, 268,
+	(2 << 9) | 39,		// P_equal_ctrl_synchro, P_equal_speedmode
+
+	1, 270,
+	0x0001,			// P_div_lock0_wait
+	1, 285,
+	0x0020,			//p_fec_
+	1, 299,
+	0x0062,			// P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
+
+	1, 338,
+	(1 << 12) |		// P_ctrl_corm_thres4pre_freq_inh=1
+	    (1 << 10) |		// P_ctrl_pre_freq_mode_sat=1
+	    (0 << 9) |		// P_ctrl_pre_freq_inh=0
+	    (3 << 5) |		// P_ctrl_pre_freq_step=3
+	    (1 << 0),		// P_pre_freq_win_len=1
+
+	1, 903,
+	(0 << 4) | 2,		// P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
+
+	0,
+};
+
+static u16 dib8000_identify(struct i2c_device *client)
+{
+	u16 value;
+
+	//because of glitches sometimes
+	value = dib8000_i2c_read16(client, 896);
+
+	if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
+		dprintk("wrong Vendor ID (read=0x%x)", value);
+		return 0;
+	}
+
+	value = dib8000_i2c_read16(client, 897);
+	if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
+		dprintk("wrong Device ID (%x)", value);
+		return 0;
+	}
+
+	switch (value) {
+	case 0x8000:
+		dprintk("found DiB8000A");
+		break;
+	case 0x8001:
+		dprintk("found DiB8000B");
+		break;
+	case 0x8002:
+		dprintk("found DiB8000C");
+		break;
+	}
+	return value;
+}
+
+static int dib8000_reset(struct dvb_frontend *fe)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+
+	dib8000_write_word(state, 1287, 0x0003);	/* sram lead in, rdy */
+
+	if ((state->revision = dib8000_identify(&state->i2c)) == 0)
+		return -EINVAL;
+
+	if (state->revision == 0x8000)
+		dprintk("error : dib8000 MA not supported");
+
+	dibx000_reset_i2c_master(&state->i2c_master);
+
+	dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
+
+	/* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
+	dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
+
+	/* restart all parts */
+	dib8000_write_word(state, 770, 0xffff);
+	dib8000_write_word(state, 771, 0xffff);
+	dib8000_write_word(state, 772, 0xfffc);
+	dib8000_write_word(state, 898, 0x000c);	// sad
+	dib8000_write_word(state, 1280, 0x004d);
+	dib8000_write_word(state, 1281, 0x000c);
+
+	dib8000_write_word(state, 770, 0x0000);
+	dib8000_write_word(state, 771, 0x0000);
+	dib8000_write_word(state, 772, 0x0000);
+	dib8000_write_word(state, 898, 0x0004);	// sad
+	dib8000_write_word(state, 1280, 0x0000);
+	dib8000_write_word(state, 1281, 0x0000);
+
+	/* drives */
+	if (state->cfg.drives)
+		dib8000_write_word(state, 906, state->cfg.drives);
+	else {
+		dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
+		dib8000_write_word(state, 906, 0x2d98);	// min drive SDRAM - not optimal - adjust
+	}
+
+	dib8000_reset_pll(state);
+
+	if (dib8000_reset_gpio(state) != 0)
+		dprintk("GPIO reset was not successful.");
+
+	if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
+		dprintk("OUTPUT_MODE could not be resetted.");
+
+	state->current_agc = NULL;
+
+	// P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
+	/* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
+	if (state->cfg.pll->ifreq == 0)
+		dib8000_write_word(state, 40, 0x0755);	/* P_iqc_corr_inh = 0 enable IQcorr block */
+	else
+		dib8000_write_word(state, 40, 0x1f55);	/* P_iqc_corr_inh = 1 disable IQcorr block */
+
+	{
+		u16 l = 0, r;
+		const u16 *n;
+		n = dib8000_defaults;
+		l = *n++;
+		while (l) {
+			r = *n++;
+			do {
+				dib8000_write_word(state, r, *n++);
+				r++;
+			} while (--l);
+			l = *n++;
+		}
+	}
+	state->isdbt_cfg_loaded = 0;
+
+	//div_cfg override for special configs
+	if (state->cfg.div_cfg != 0)
+		dib8000_write_word(state, 903, state->cfg.div_cfg);
+
+	/* unforce divstr regardless whether i2c enumeration was done or not */
+	dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
+
+	dib8000_set_bandwidth(state, 6000);
+
+	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
+	dib8000_sad_calib(state);
+	dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
+
+	dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
+
+	return 0;
+}
+
+static void dib8000_restart_agc(struct dib8000_state *state)
+{
+	// P_restart_iqc & P_restart_agc
+	dib8000_write_word(state, 770, 0x0a00);
+	dib8000_write_word(state, 770, 0x0000);
+}
+
+static int dib8000_update_lna(struct dib8000_state *state)
+{
+	u16 dyn_gain;
+
+	if (state->cfg.update_lna) {
+		// read dyn_gain here (because it is demod-dependent and not tuner)
+		dyn_gain = dib8000_read_word(state, 390);
+
+		if (state->cfg.update_lna(&state->fe, dyn_gain)) {	// LNA has changed
+			dib8000_restart_agc(state);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
+{
+	struct dibx000_agc_config *agc = NULL;
+	int i;
+	if (state->current_band == band && state->current_agc != NULL)
+		return 0;
+	state->current_band = band;
+
+	for (i = 0; i < state->cfg.agc_config_count; i++)
+		if (state->cfg.agc[i].band_caps & band) {
+			agc = &state->cfg.agc[i];
+			break;
+		}
+
+	if (agc == NULL) {
+		dprintk("no valid AGC configuration found for band 0x%02x", band);
+		return -EINVAL;
+	}
+
+	state->current_agc = agc;
+
+	/* AGC */
+	dib8000_write_word(state, 76, agc->setup);
+	dib8000_write_word(state, 77, agc->inv_gain);
+	dib8000_write_word(state, 78, agc->time_stabiliz);
+	dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
+
+	// Demod AGC loop configuration
+	dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
+	dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
+
+	dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
+		state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
+
+	/* AGC continued */
+	if (state->wbd_ref != 0)
+		dib8000_write_word(state, 106, state->wbd_ref);
+	else			// use default
+		dib8000_write_word(state, 106, agc->wbd_ref);
+	dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
+	dib8000_write_word(state, 108, agc->agc1_max);
+	dib8000_write_word(state, 109, agc->agc1_min);
+	dib8000_write_word(state, 110, agc->agc2_max);
+	dib8000_write_word(state, 111, agc->agc2_min);
+	dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
+	dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
+	dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
+	dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
+
+	dib8000_write_word(state, 75, agc->agc1_pt3);
+	dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));	/*LB : 929 -> 923 */
+
+	return 0;
+}
+
+static int dib8000_agc_soft_split(struct dib8000_state *state)
+{
+	u16 agc, split_offset;
+
+	if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
+		return FE_CALLBACK_TIME_NEVER;
+
+	// n_agc_global
+	agc = dib8000_read_word(state, 390);
+
+	if (agc > state->current_agc->split.min_thres)
+		split_offset = state->current_agc->split.min;
+	else if (agc < state->current_agc->split.max_thres)
+		split_offset = state->current_agc->split.max;
+	else
+		split_offset = state->current_agc->split.max *
+		    (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
+
+	dprintk("AGC split_offset: %d", split_offset);
+
+	// P_agc_force_split and P_agc_split_offset
+	dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
+	return 5000;
+}
+
+static int dib8000_agc_startup(struct dvb_frontend *fe)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	enum frontend_tune_state *tune_state = &state->tune_state;
+
+	int ret = 0;
+
+	switch (*tune_state) {
+	case CT_AGC_START:
+		// set power-up level: interf+analog+AGC
+
+		dib8000_set_adc_state(state, DIBX000_ADC_ON);
+
+		if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
+			*tune_state = CT_AGC_STOP;
+			state->status = FE_STATUS_TUNE_FAILED;
+			break;
+		}
+
+		ret = 70;
+		*tune_state = CT_AGC_STEP_0;
+		break;
+
+	case CT_AGC_STEP_0:
+		//AGC initialization
+		if (state->cfg.agc_control)
+			state->cfg.agc_control(&state->fe, 1);
+
+		dib8000_restart_agc(state);
+
+		// wait AGC rough lock time
+		ret = 50;
+		*tune_state = CT_AGC_STEP_1;
+		break;
+
+	case CT_AGC_STEP_1:
+		// wait AGC accurate lock time
+		ret = 70;
+
+		if (dib8000_update_lna(state))
+			// wait only AGC rough lock time
+			ret = 50;
+		else
+			*tune_state = CT_AGC_STEP_2;
+		break;
+
+	case CT_AGC_STEP_2:
+		dib8000_agc_soft_split(state);
+
+		if (state->cfg.agc_control)
+			state->cfg.agc_control(&state->fe, 0);
+
+		*tune_state = CT_AGC_STOP;
+		break;
+	default:
+		ret = dib8000_agc_soft_split(state);
+		break;
+	}
+	return ret;
+
+}
+
+static void dib8000_update_timf(struct dib8000_state *state)
+{
+	u32 timf = state->timf = dib8000_read32(state, 435);
+
+	dib8000_write_word(state, 29, (u16) (timf >> 16));
+	dib8000_write_word(state, 30, (u16) (timf & 0xffff));
+	dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
+}
+
+static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
+{
+	u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
+	u8 guard, crate, constellation, timeI;
+	u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
+	u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;	// All 13 segments enabled
+	const s16 *ncoeff, *ana_fe;
+	u16 tmcc_pow = 0;
+	u16 coff_pow = 0x2800;
+	u16 init_prbs = 0xfff;
+	u16 ana_gain = 0;
+	u16 adc_target_16dB[11] = {
+		(1 << 13) - 825 - 117,
+		(1 << 13) - 837 - 117,
+		(1 << 13) - 811 - 117,
+		(1 << 13) - 766 - 117,
+		(1 << 13) - 737 - 117,
+		(1 << 13) - 693 - 117,
+		(1 << 13) - 648 - 117,
+		(1 << 13) - 619 - 117,
+		(1 << 13) - 575 - 117,
+		(1 << 13) - 531 - 117,
+		(1 << 13) - 501 - 117
+	};
+
+	if (state->ber_monitored_layer != LAYER_ALL)
+		dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
+	else
+		dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
+
+	i = dib8000_read_word(state, 26) & 1;	// P_dds_invspec
+	dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
+
+	if (state->fe.dtv_property_cache.isdbt_sb_mode) {
+		//compute new dds_freq for the seg and adjust prbs
+		int seg_offset =
+		    state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
+		    (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
+		int clk = state->cfg.pll->internal;
+		u32 segtodds = ((u32) (430 << 23) / clk) << 3;	// segtodds = SegBW / Fclk * pow(2,26)
+		int dds_offset = seg_offset * segtodds;
+		int new_dds, sub_channel;
+		if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)	// if even
+			dds_offset -= (int)(segtodds / 2);
+
+		if (state->cfg.pll->ifreq == 0) {
+			if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
+				dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
+				new_dds = dds_offset;
+			} else
+				new_dds = dds_offset;
+
+			// We shift tuning frequency if the wanted segment is :
+			//  - the segment of center frequency with an odd total number of segments
+			//  - the segment to the left of center frequency with an even total number of segments
+			//  - the segment to the right of center frequency with an even total number of segments
+			if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
+			    &&
+			    (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
+			      && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
+				  ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+			     || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+				 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
+			     || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
+				 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
+				     ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
+			    )) {
+				new_dds -= ((u32) (850 << 22) / clk) << 4;	// new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
+			}
+		} else {
+			if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
+				new_dds = state->cfg.pll->ifreq - dds_offset;
+			else
+				new_dds = state->cfg.pll->ifreq + dds_offset;
+		}
+		dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
+		dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
+		if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)	// if odd
+			sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
+		else		// if even
+			sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
+		sub_channel -= 6;
+
+		if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
+		    || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
+			dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1);	//adp_pass =1
+			dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14));	//pha3_force_pha_shift = 1
+		} else {
+			dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe);	//adp_pass =0
+			dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff);	//pha3_force_pha_shift = 0
+		}
+
+		switch (state->fe.dtv_property_cache.transmission_mode) {
+		case TRANSMISSION_MODE_2K:
+			switch (sub_channel) {
+			case -6:
+				init_prbs = 0x0;
+				break;	// 41, 0, 1
+			case -5:
+				init_prbs = 0x423;
+				break;	// 02~04
+			case -4:
+				init_prbs = 0x9;
+				break;	// 05~07
+			case -3:
+				init_prbs = 0x5C7;
+				break;	// 08~10
+			case -2:
+				init_prbs = 0x7A6;
+				break;	// 11~13
+			case -1:
+				init_prbs = 0x3D8;
+				break;	// 14~16
+			case 0:
+				init_prbs = 0x527;
+				break;	// 17~19
+			case 1:
+				init_prbs = 0x7FF;
+				break;	// 20~22
+			case 2:
+				init_prbs = 0x79B;
+				break;	// 23~25
+			case 3:
+				init_prbs = 0x3D6;
+				break;	// 26~28
+			case 4:
+				init_prbs = 0x3A2;
+				break;	// 29~31
+			case 5:
+				init_prbs = 0x53B;
+				break;	// 32~34
+			case 6:
+				init_prbs = 0x2F4;
+				break;	// 35~37
+			default:
+			case 7:
+				init_prbs = 0x213;
+				break;	// 38~40
+			}
+			break;
+
+		case TRANSMISSION_MODE_4K:
+			switch (sub_channel) {
+			case -6:
+				init_prbs = 0x0;
+				break;	// 41, 0, 1
+			case -5:
+				init_prbs = 0x208;
+				break;	// 02~04
+			case -4:
+				init_prbs = 0xC3;
+				break;	// 05~07
+			case -3:
+				init_prbs = 0x7B9;
+				break;	// 08~10
+			case -2:
+				init_prbs = 0x423;
+				break;	// 11~13
+			case -1:
+				init_prbs = 0x5C7;
+				break;	// 14~16
+			case 0:
+				init_prbs = 0x3D8;
+				break;	// 17~19
+			case 1:
+				init_prbs = 0x7FF;
+				break;	// 20~22
+			case 2:
+				init_prbs = 0x3D6;
+				break;	// 23~25
+			case 3:
+				init_prbs = 0x53B;
+				break;	// 26~28
+			case 4:
+				init_prbs = 0x213;
+				break;	// 29~31
+			case 5:
+				init_prbs = 0x29;
+				break;	// 32~34
+			case 6:
+				init_prbs = 0xD0;
+				break;	// 35~37
+			default:
+			case 7:
+				init_prbs = 0x48E;
+				break;	// 38~40
+			}
+			break;
+
+		default:
+		case TRANSMISSION_MODE_8K:
+			switch (sub_channel) {
+			case -6:
+				init_prbs = 0x0;
+				break;	// 41, 0, 1
+			case -5:
+				init_prbs = 0x740;
+				break;	// 02~04
+			case -4:
+				init_prbs = 0x069;
+				break;	// 05~07
+			case -3:
+				init_prbs = 0x7DD;
+				break;	// 08~10
+			case -2:
+				init_prbs = 0x208;
+				break;	// 11~13
+			case -1:
+				init_prbs = 0x7B9;
+				break;	// 14~16
+			case 0:
+				init_prbs = 0x5C7;
+				break;	// 17~19
+			case 1:
+				init_prbs = 0x7FF;
+				break;	// 20~22
+			case 2:
+				init_prbs = 0x53B;
+				break;	// 23~25
+			case 3:
+				init_prbs = 0x29;
+				break;	// 26~28
+			case 4:
+				init_prbs = 0x48E;
+				break;	// 29~31
+			case 5:
+				init_prbs = 0x4C4;
+				break;	// 32~34
+			case 6:
+				init_prbs = 0x367;
+				break;	// 33~37
+			default:
+			case 7:
+				init_prbs = 0x684;
+				break;	// 38~40
+			}
+			break;
+		}
+	} else {		// if not state->fe.dtv_property_cache.isdbt_sb_mode
+		dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
+		dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
+		dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
+	}
+	/*P_mode == ?? */
+	dib8000_write_word(state, 10, (seq << 4));
+	//  dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
+
+	switch (state->fe.dtv_property_cache.guard_interval) {
+	case GUARD_INTERVAL_1_32:
+		guard = 0;
+		break;
+	case GUARD_INTERVAL_1_16:
+		guard = 1;
+		break;
+	case GUARD_INTERVAL_1_8:
+		guard = 2;
+		break;
+	case GUARD_INTERVAL_1_4:
+	default:
+		guard = 3;
+		break;
+	}
+
+	dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3));	// ADDR 1
+
+	max_constellation = DQPSK;
+	for (i = 0; i < 3; i++) {
+		switch (state->fe.dtv_property_cache.layer[i].modulation) {
+		case DQPSK:
+			constellation = 0;
+			break;
+		case QPSK:
+			constellation = 1;
+			break;
+		case QAM_16:
+			constellation = 2;
+			break;
+		case QAM_64:
+		default:
+			constellation = 3;
+			break;
+		}
+
+		switch (state->fe.dtv_property_cache.layer[i].fec) {
+		case FEC_1_2:
+			crate = 1;
+			break;
+		case FEC_2_3:
+			crate = 2;
+			break;
+		case FEC_3_4:
+			crate = 3;
+			break;
+		case FEC_5_6:
+			crate = 5;
+			break;
+		case FEC_7_8:
+		default:
+			crate = 7;
+			break;
+		}
+
+		if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
+		    ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
+		     (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
+		    )
+			timeI = state->fe.dtv_property_cache.layer[i].interleaving;
+		else
+			timeI = 0;
+		dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
+				   (crate << 3) | timeI);
+		if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
+			switch (max_constellation) {
+			case DQPSK:
+			case QPSK:
+				if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
+				    state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
+					max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
+				break;
+			case QAM_16:
+				if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
+					max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
+				break;
+			}
+		}
+	}
+
+	mode = fft_to_mode(state);
+
+	//dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
+
+	dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
+			   ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
+												 isdbt_sb_mode & 1) << 4));
+
+	dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
+
+	/* signal optimization parameter */
+
+	if (state->fe.dtv_property_cache.isdbt_partial_reception) {
+		seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
+		for (i = 1; i < 3; i++)
+			nbseg_diff +=
+			    (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
+		for (i = 0; i < nbseg_diff; i++)
+			seg_diff_mask |= 1 << permu_seg[i + 1];
+	} else {
+		for (i = 0; i < 3; i++)
+			nbseg_diff +=
+			    (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
+		for (i = 0; i < nbseg_diff; i++)
+			seg_diff_mask |= 1 << permu_seg[i];
+	}
+	dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
+
+	state->differential_constellation = (seg_diff_mask != 0);
+	dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
+
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {	// ISDB-Tsb
+		if (state->fe.dtv_property_cache.isdbt_partial_reception == 1)	// 3-segments
+			seg_mask13 = 0x00E0;
+		else		// 1-segment
+			seg_mask13 = 0x0040;
+	} else
+		seg_mask13 = 0x1fff;
+
+	// WRITE: Mode & Diff mask
+	dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
+
+	if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
+		dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
+	else
+		dib8000_write_word(state, 268, (2 << 9) | 39);	//init value
+
+	// ---- SMALL ----
+	// P_small_seg_diff
+	dib8000_write_word(state, 352, seg_diff_mask);	// ADDR 352
+
+	dib8000_write_word(state, 353, seg_mask13);	// ADDR 353
+
+/*     // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
+	// dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
+
+	// ---- SMALL ----
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+		switch (state->fe.dtv_property_cache.transmission_mode) {
+		case TRANSMISSION_MODE_2K:
+			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// 1-seg
+				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)	// DQPSK
+					ncoeff = coeff_2k_sb_1seg_dqpsk;
+				else	// QPSK or QAM
+					ncoeff = coeff_2k_sb_1seg;
+			} else {	// 3-segments
+				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {	// DQPSK on central segment
+					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK)	// DQPSK on external segments
+						ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
+					else	// QPSK or QAM on external segments
+						ncoeff = coeff_2k_sb_3seg_0dqpsk;
+				} else {	// QPSK or QAM on central segment
+					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK)	// DQPSK on external segments
+						ncoeff = coeff_2k_sb_3seg_1dqpsk;
+					else	// QPSK or QAM on external segments
+						ncoeff = coeff_2k_sb_3seg;
+				}
+			}
+			break;
+
+		case TRANSMISSION_MODE_4K:
+			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// 1-seg
+				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)	// DQPSK
+					ncoeff = coeff_4k_sb_1seg_dqpsk;
+				else	// QPSK or QAM
+					ncoeff = coeff_4k_sb_1seg;
+			} else {	// 3-segments
+				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {	// DQPSK on central segment
+					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
+						ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
+					} else {	// QPSK or QAM on external segments
+						ncoeff = coeff_4k_sb_3seg_0dqpsk;
+					}
+				} else {	// QPSK or QAM on central segment
+					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
+						ncoeff = coeff_4k_sb_3seg_1dqpsk;
+					} else	// QPSK or QAM on external segments
+						ncoeff = coeff_4k_sb_3seg;
+				}
+			}
+			break;
+
+		case TRANSMISSION_MODE_AUTO:
+		case TRANSMISSION_MODE_8K:
+		default:
+			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// 1-seg
+				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)	// DQPSK
+					ncoeff = coeff_8k_sb_1seg_dqpsk;
+				else	// QPSK or QAM
+					ncoeff = coeff_8k_sb_1seg;
+			} else {	// 3-segments
+				if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {	// DQPSK on central segment
+					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
+						ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
+					} else {	// QPSK or QAM on external segments
+						ncoeff = coeff_8k_sb_3seg_0dqpsk;
+					}
+				} else {	// QPSK or QAM on central segment
+					if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {	// DQPSK on external segments
+						ncoeff = coeff_8k_sb_3seg_1dqpsk;
+					} else	// QPSK or QAM on external segments
+						ncoeff = coeff_8k_sb_3seg;
+				}
+			}
+			break;
+		}
+	}
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
+		for (i = 0; i < 8; i++)
+			dib8000_write_word(state, 343 + i, ncoeff[i]);
+
+	// P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
+	dib8000_write_word(state, 351,
+			   (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
+
+	// ---- COFF ----
+	// Carloff, the most robust
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {	// Sound Broadcasting mode - use both TMCC and AC pilots
+
+		// P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
+		// P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
+		dib8000_write_word(state, 187,
+				   (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
+				   | 0x3);
+
+/*             // P_small_coef_ext_enable = 1 */
+/*             dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
+
+		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// Sound Broadcasting mode 1 seg
+
+			// P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
+			if (mode == 3)
+				dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
+			else
+				dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
+			// P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
+			// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
+			dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
+			// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
+			dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
+			// P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
+			dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+
+			// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
+			dib8000_write_word(state, 181, 300);
+			dib8000_write_word(state, 182, 150);
+			dib8000_write_word(state, 183, 80);
+			dib8000_write_word(state, 184, 300);
+			dib8000_write_word(state, 185, 150);
+			dib8000_write_word(state, 186, 80);
+		} else {	// Sound Broadcasting mode 3 seg
+			// P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
+			/*                 if (mode == 3) */
+			/*                     dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
+			/*                 else */
+			/*                     dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
+			dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
+
+			// P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
+			// P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
+			dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
+			// P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
+			dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
+			//P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
+			dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+
+			// P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
+			dib8000_write_word(state, 181, 350);
+			dib8000_write_word(state, 182, 300);
+			dib8000_write_word(state, 183, 250);
+			dib8000_write_word(state, 184, 350);
+			dib8000_write_word(state, 185, 300);
+			dib8000_write_word(state, 186, 250);
+		}
+
+	} else if (state->isdbt_cfg_loaded == 0) {	// if not Sound Broadcasting mode : put default values for 13 segments
+		dib8000_write_word(state, 180, (16 << 6) | 9);
+		dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
+		coff_pow = 0x2800;
+		for (i = 0; i < 6; i++)
+			dib8000_write_word(state, 181 + i, coff_pow);
+
+		// P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
+		// P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
+		dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
+
+		// P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
+		dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
+		// P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
+		dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+	}
+	// ---- FFT ----
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// 1-seg
+		dib8000_write_word(state, 178, 64);	// P_fft_powrange=64
+	else
+		dib8000_write_word(state, 178, 32);	// P_fft_powrange=32
+
+	/* make the cpil_coff_lock more robust but slower p_coff_winlen
+	 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
+	 */
+	/* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
+	   dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
+
+	dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask);	/* P_lmod4_seg_inh       */
+	dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask);	/* P_pha3_seg_inh        */
+	dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask);	/* P_tac_seg_inh         */
+	if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
+		dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40);	/* P_equal_noise_seg_inh */
+	else
+		dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask);	/* P_equal_noise_seg_inh */
+	dib8000_write_word(state, 287, ~seg_mask13 | 0x1000);	/* P_tmcc_seg_inh        */
+	//dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
+	if (!autosearching)
+		dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff);	/* P_tmcc_seg_eq_inh */
+	else
+		dib8000_write_word(state, 288, 0x1fff);	//disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
+	dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
+
+	dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask));	/* P_des_seg_enabled     */
+
+	/* offset loop parameters */
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// Sound Broadcasting mode 1 seg
+			/* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
+			dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
+
+		else		// Sound Broadcasting mode 3 seg
+			/* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
+			dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
+	} else
+		// TODO in 13 seg, timf_alpha can always be the same or not ?
+		/* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
+		dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
+
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// Sound Broadcasting mode 1 seg
+			/* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (11-P_mode)  */
+			dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
+
+		else		// Sound Broadcasting mode 3 seg
+			/* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (10-P_mode)  */
+			dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
+	} else
+		/* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = 9  */
+		dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
+
+	/* P_dvsy_sync_wait - reuse mode */
+	switch (state->fe.dtv_property_cache.transmission_mode) {
+	case TRANSMISSION_MODE_8K:
+		mode = 256;
+		break;
+	case TRANSMISSION_MODE_4K:
+		mode = 128;
+		break;
+	default:
+	case TRANSMISSION_MODE_2K:
+		mode = 64;
+		break;
+	}
+	if (state->cfg.diversity_delay == 0)
+		mode = (mode * (1 << (guard)) * 3) / 2 + 48;	// add 50% SFN margin + compensate for one DVSY-fifo
+	else
+		mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay;	// add 50% SFN margin + compensate for DVSY-fifo
+	mode <<= 4;
+	dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
+
+	/* channel estimation fine configuration */
+	switch (max_constellation) {
+	case QAM_64:
+		ana_gain = 0x7;	// -1 : avoid def_est saturation when ADC target is -16dB
+		coeff[0] = 0x0148;	/* P_adp_regul_cnt 0.04 */
+		coeff[1] = 0xfff0;	/* P_adp_noise_cnt -0.002 */
+		coeff[2] = 0x00a4;	/* P_adp_regul_ext 0.02 */
+		coeff[3] = 0xfff8;	/* P_adp_noise_ext -0.001 */
+		//if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
+		break;
+	case QAM_16:
+		ana_gain = 0x7;	// -1 : avoid def_est saturation when ADC target is -16dB
+		coeff[0] = 0x023d;	/* P_adp_regul_cnt 0.07 */
+		coeff[1] = 0xffdf;	/* P_adp_noise_cnt -0.004 */
+		coeff[2] = 0x00a4;	/* P_adp_regul_ext 0.02 */
+		coeff[3] = 0xfff0;	/* P_adp_noise_ext -0.002 */
+		//if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
+		break;
+	default:
+		ana_gain = 0;	// 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
+		coeff[0] = 0x099a;	/* P_adp_regul_cnt 0.3 */
+		coeff[1] = 0xffae;	/* P_adp_noise_cnt -0.01 */
+		coeff[2] = 0x0333;	/* P_adp_regul_ext 0.1 */
+		coeff[3] = 0xfff8;	/* P_adp_noise_ext -0.002 */
+		break;
+	}
+	for (mode = 0; mode < 4; mode++)
+		dib8000_write_word(state, 215 + mode, coeff[mode]);
+
+	// update ana_gain depending on max constellation
+	dib8000_write_word(state, 116, ana_gain);
+	// update ADC target depending on ana_gain
+	if (ana_gain) {		// set -16dB ADC target for ana_gain=-1
+		for (i = 0; i < 10; i++)
+			dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
+	} else {		// set -22dB ADC target for ana_gain=0
+		for (i = 0; i < 10; i++)
+			dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
+	}
+
+	// ---- ANA_FE ----
+	if (state->fe.dtv_property_cache.isdbt_sb_mode) {
+		if (state->fe.dtv_property_cache.isdbt_partial_reception == 1)	// 3-segments
+			ana_fe = ana_fe_coeff_3seg;
+		else		// 1-segment
+			ana_fe = ana_fe_coeff_1seg;
+	} else
+		ana_fe = ana_fe_coeff_13seg;
+
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
+		for (mode = 0; mode < 24; mode++)
+			dib8000_write_word(state, 117 + mode, ana_fe[mode]);
+
+	// ---- CHAN_BLK ----
+	for (i = 0; i < 13; i++) {
+		if ((((~seg_diff_mask) >> i) & 1) == 1) {
+			P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
+			P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
+		}
+	}
+	dib8000_write_word(state, 222, P_cfr_left_edge);	// P_cfr_left_edge
+	dib8000_write_word(state, 223, P_cfr_right_edge);	// P_cfr_right_edge
+	// "P_cspu_left_edge"  not used => do not care
+	// "P_cspu_right_edge" not used => do not care
+
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {	// ISDB-Tsb
+		dib8000_write_word(state, 228, 1);	// P_2d_mode_byp=1
+		dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0);	// P_cspu_win_cut = 0
+		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0	// 1-segment
+		    && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
+			//dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
+			dib8000_write_word(state, 265, 15);	// P_equal_noise_sel = 15
+		}
+	} else if (state->isdbt_cfg_loaded == 0) {
+		dib8000_write_word(state, 228, 0);	// default value
+		dib8000_write_word(state, 265, 31);	// default value
+		dib8000_write_word(state, 205, 0x200f);	// init value
+	}
+	// ---- TMCC ----
+	for (i = 0; i < 3; i++)
+		tmcc_pow +=
+		    (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
+	// Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
+	// Threshold is set at 1/4 of max power.
+	tmcc_pow *= (1 << (9 - 2));
+
+	dib8000_write_word(state, 290, tmcc_pow);	// P_tmcc_dec_thres_2k
+	dib8000_write_word(state, 291, tmcc_pow);	// P_tmcc_dec_thres_4k
+	dib8000_write_word(state, 292, tmcc_pow);	// P_tmcc_dec_thres_8k
+	//dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
+	// ---- PHA3 ----
+
+	if (state->isdbt_cfg_loaded == 0)
+		dib8000_write_word(state, 250, 3285);	/*p_2d_hspeed_thr0 */
+
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
+		state->isdbt_cfg_loaded = 0;
+	else
+		state->isdbt_cfg_loaded = 1;
+
+}
+
+static int dib8000_autosearch_start(struct dvb_frontend *fe)
+{
+	u8 factor;
+	u32 value;
+	struct dib8000_state *state = fe->demodulator_priv;
+
+	int slist = 0;
+
+	state->fe.dtv_property_cache.inversion = 0;
+	if (!state->fe.dtv_property_cache.isdbt_sb_mode)
+		state->fe.dtv_property_cache.layer[0].segment_count = 13;
+	state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
+	state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
+	state->fe.dtv_property_cache.layer[0].interleaving = 0;
+
+	//choose the right list, in sb, always do everything
+	if (state->fe.dtv_property_cache.isdbt_sb_mode) {
+		state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+		state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+		slist = 7;
+		dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
+	} else {
+		if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
+			if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
+				slist = 7;
+				dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));	// P_mode = 1 to have autosearch start ok with mode2
+			} else
+				slist = 3;
+		} else {
+			if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
+				slist = 2;
+				dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));	// P_mode = 1
+			} else
+				slist = 0;
+		}
+
+		if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
+			state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+		if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
+			state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+
+		dprintk("using list for autosearch : %d", slist);
+		dib8000_set_channel(state, (unsigned char)slist, 1);
+		//dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));  // P_mode = 1
+
+		factor = 1;
+
+		//set lock_mask values
+		dib8000_write_word(state, 6, 0x4);
+		dib8000_write_word(state, 7, 0x8);
+		dib8000_write_word(state, 8, 0x1000);
+
+		//set lock_mask wait time values
+		value = 50 * state->cfg.pll->internal * factor;
+		dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff));	// lock0 wait time
+		dib8000_write_word(state, 12, (u16) (value & 0xffff));	// lock0 wait time
+		value = 100 * state->cfg.pll->internal * factor;
+		dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff));	// lock1 wait time
+		dib8000_write_word(state, 14, (u16) (value & 0xffff));	// lock1 wait time
+		value = 1000 * state->cfg.pll->internal * factor;
+		dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff));	// lock2 wait time
+		dib8000_write_word(state, 16, (u16) (value & 0xffff));	// lock2 wait time
+
+		value = dib8000_read_word(state, 0);
+		dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
+		dib8000_read_word(state, 1284);	// reset the INT. n_irq_pending
+		dib8000_write_word(state, 0, (u16) value);
+
+	}
+
+	return 0;
+}
+
+static int dib8000_autosearch_irq(struct dvb_frontend *fe)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 irq_pending = dib8000_read_word(state, 1284);
+
+	if (irq_pending & 0x1) {	// failed
+		dprintk("dib8000_autosearch_irq failed");
+		return 1;
+	}
+
+	if (irq_pending & 0x2) {	// succeeded
+		dprintk("dib8000_autosearch_irq succeeded");
+		return 2;
+	}
+
+	return 0;		// still pending
+}
+
+static int dib8000_tune(struct dvb_frontend *fe)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	int ret = 0;
+	u16 value, mode = fft_to_mode(state);
+
+	// we are already tuned - just resuming from suspend
+	if (state == NULL)
+		return -EINVAL;
+
+	dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
+	dib8000_set_channel(state, 0, 0);
+
+	// restart demod
+	ret |= dib8000_write_word(state, 770, 0x4000);
+	ret |= dib8000_write_word(state, 770, 0x0000);
+	msleep(45);
+
+	/* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
+	/*  ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) );  workaround inh_isi stays at 1 */
+
+	// never achieved a lock before - wait for timfreq to update
+	if (state->timf == 0) {
+		if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+			if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)	// Sound Broadcasting mode 1 seg
+				msleep(300);
+			else	// Sound Broadcasting mode 3 seg
+				msleep(500);
+		} else		// 13 seg
+			msleep(200);
+	}
+	//dump_reg(state);
+	if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
+		if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {	// Sound Broadcasting mode 1 seg
+
+			/* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40  alpha to check on board */
+			dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
+			//dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
+
+			/*  P_ctrl_sfreq_step= (12-P_mode)   P_ctrl_sfreq_inh =0     P_ctrl_pha_off_max  */
+			ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
+
+		} else {	// Sound Broadcasting mode 3 seg
+
+			/* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60  alpha to check on board */
+			dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
+
+			ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
+		}
+
+	} else {		// 13 seg
+		/* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80  alpha to check on board */
+		dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
+
+		ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
+
+	}
+
+	// we achieved a coff_cpil_lock - it's time to update the timf
+	if ((dib8000_read_word(state, 568) >> 11) & 0x1)
+		dib8000_update_timf(state);
+
+	//now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
+	dib8000_write_word(state, 6, 0x200);
+
+	if (state->revision == 0x8002) {
+		value = dib8000_read_word(state, 903);
+		dib8000_write_word(state, 903, value & ~(1 << 3));
+		msleep(1);
+		dib8000_write_word(state, 903, value | (1 << 3));
+	}
+
+	return ret;
+}
+
+static int dib8000_wakeup(struct dvb_frontend *fe)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+
+	dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
+	dib8000_set_adc_state(state, DIBX000_ADC_ON);
+	if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
+		dprintk("could not start Slow ADC");
+
+	return 0;
+}
+
+static int dib8000_sleep(struct dvb_frontend *fe)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+	if (1) {
+		dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
+		dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
+		return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
+	} else {
+
+		return 0;
+	}
+}
+
+static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 i, val = 0;
+
+	fe->dtv_property_cache.bandwidth_hz = 6000000;
+
+	fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
+
+	val = dib8000_read_word(state, 570);
+	fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
+	switch ((val & 0x30) >> 4) {
+	case 1:
+		fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
+		break;
+	case 3:
+	default:
+		fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
+		break;
+	}
+
+	switch (val & 0x3) {
+	case 0:
+		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
+		dprintk("dib8000_get_frontend GI = 1/32 ");
+		break;
+	case 1:
+		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
+		dprintk("dib8000_get_frontend GI = 1/16 ");
+		break;
+	case 2:
+		dprintk("dib8000_get_frontend GI = 1/8 ");
+		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
+		break;
+	case 3:
+		dprintk("dib8000_get_frontend GI = 1/4 ");
+		fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
+		break;
+	}
+
+	val = dib8000_read_word(state, 505);
+	fe->dtv_property_cache.isdbt_partial_reception = val & 1;
+	dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
+
+	for (i = 0; i < 3; i++) {
+		val = dib8000_read_word(state, 493 + i);
+		fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
+		dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
+
+		val = dib8000_read_word(state, 499 + i);
+		fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
+		dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
+
+		val = dib8000_read_word(state, 481 + i);
+		switch (val & 0x7) {
+		case 1:
+			fe->dtv_property_cache.layer[i].fec = FEC_1_2;
+			dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
+			break;
+		case 2:
+			fe->dtv_property_cache.layer[i].fec = FEC_2_3;
+			dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
+			break;
+		case 3:
+			fe->dtv_property_cache.layer[i].fec = FEC_3_4;
+			dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
+			break;
+		case 5:
+			fe->dtv_property_cache.layer[i].fec = FEC_5_6;
+			dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
+			break;
+		default:
+			fe->dtv_property_cache.layer[i].fec = FEC_7_8;
+			dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
+			break;
+		}
+
+		val = dib8000_read_word(state, 487 + i);
+		switch (val & 0x3) {
+		case 0:
+			dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
+			fe->dtv_property_cache.layer[i].modulation = DQPSK;
+			break;
+		case 1:
+			fe->dtv_property_cache.layer[i].modulation = QPSK;
+			dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
+			break;
+		case 2:
+			fe->dtv_property_cache.layer[i].modulation = QAM_16;
+			dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
+			break;
+		case 3:
+		default:
+			dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
+			fe->dtv_property_cache.layer[i].modulation = QAM_64;
+			break;
+		}
+	}
+	return 0;
+}
+
+static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	int time, ret;
+
+	dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
+
+	if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe, fep);
+
+	/* start up the AGC */
+	state->tune_state = CT_AGC_START;
+	do {
+		time = dib8000_agc_startup(fe);
+		if (time != FE_CALLBACK_TIME_NEVER)
+			msleep(time / 10);
+		else
+			break;
+	} while (state->tune_state != CT_AGC_STOP);
+
+	if (state->fe.dtv_property_cache.frequency == 0) {
+		dprintk("dib8000: must at least specify frequency ");
+		return 0;
+	}
+
+	if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
+		dprintk("dib8000: no bandwidth specified, set to default ");
+		state->fe.dtv_property_cache.bandwidth_hz = 6000000;
+	}
+
+	state->tune_state = CT_DEMOD_START;
+
+	if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
+	    (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
+	    (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
+	    (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
+	    (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
+	     (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
+	     (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
+	     ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
+	      (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
+	    (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
+	     (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
+	     (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
+	     ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
+	      (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
+	    (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
+	     (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
+	     (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
+	     ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
+	      (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
+	    (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
+	      ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
+	     ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
+	      ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
+	     ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
+		int i = 800, found;
+
+		dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
+		dib8000_autosearch_start(fe);
+		do {
+			msleep(10);
+			found = dib8000_autosearch_irq(fe);
+		} while (found == 0 && i--);
+
+		dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
+
+		if (found == 0 || found == 1)
+			return 0;	// no channel found
+
+		dib8000_get_frontend(fe, fep);
+	}
+
+	ret = dib8000_tune(fe);
+
+	/* make this a config parameter */
+	dib8000_set_output_mode(state, state->cfg.output_mode);
+
+	return ret;
+}
+
+static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 lock = dib8000_read_word(state, 568);
+
+	*stat = 0;
+
+	if ((lock >> 14) & 1)	// AGC
+		*stat |= FE_HAS_SIGNAL;
+
+	if ((lock >> 8) & 1)	// Equal
+		*stat |= FE_HAS_CARRIER;
+
+	if ((lock >> 3) & 1)	// TMCC_SYNC
+		*stat |= FE_HAS_SYNC;
+
+	if ((lock >> 5) & 7)	// FEC MPEG
+		*stat |= FE_HAS_LOCK;
+
+	lock = dib8000_read_word(state, 554);	// Viterbi Layer A
+	if (lock & 0x01)
+		*stat |= FE_HAS_VITERBI;
+
+	lock = dib8000_read_word(state, 555);	// Viterbi Layer B
+	if (lock & 0x01)
+		*stat |= FE_HAS_VITERBI;
+
+	lock = dib8000_read_word(state, 556);	// Viterbi Layer C
+	if (lock & 0x01)
+		*stat |= FE_HAS_VITERBI;
+
+	return 0;
+}
+
+static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	*ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561);	// 13 segments
+	return 0;
+}
+
+static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	*unc = dib8000_read_word(state, 565);	// packet error on 13 seg
+	return 0;
+}
+
+static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 val = dib8000_read_word(state, 390);
+	*strength = 65535 - val;
+	return 0;
+}
+
+static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+	struct dib8000_state *state = fe->demodulator_priv;
+	u16 val;
+	s32 signal_mant, signal_exp, noise_mant, noise_exp;
+	u32 result = 0;
+
+	val = dib8000_read_word(state, 542);
+	noise_mant = (val >> 6) & 0xff;
+	noise_exp = (val & 0x3f);
+
+	val = dib8000_read_word(state, 543);
+	signal_mant = (val >> 6) & 0xff;
+	signal_exp = (val & 0x3f);
+
+	if ((noise_exp & 0x20) != 0)
+		noise_exp -= 0x40;
+	if ((signal_exp & 0x20) != 0)
+		signal_exp -= 0x40;
+
+	if (signal_mant != 0)
+		result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
+	else
+		result = intlog10(2) * 10 * signal_exp - 100;
+	if (noise_mant != 0)
+		result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
+	else
+		result -= intlog10(2) * 10 * noise_exp - 100;
+
+	*snr = result / (1 << 24);
+	return 0;
+}
+
+int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+{
+	int k = 0;
+	u8 new_addr = 0;
+	struct i2c_device client = {.adap = host };
+
+	for (k = no_of_demods - 1; k >= 0; k--) {
+		/* designated i2c address */
+		new_addr = first_addr + (k << 1);
+
+		client.addr = new_addr;
+		dib8000_i2c_write16(&client, 1287, 0x0003);	/* sram lead in, rdy */
+		if (dib8000_identify(&client) == 0) {
+			dib8000_i2c_write16(&client, 1287, 0x0003);	/* sram lead in, rdy */
+			client.addr = default_addr;
+			if (dib8000_identify(&client) == 0) {
+				dprintk("#%d: not identified", k);
+				return -EINVAL;
+			}
+		}
+
+		/* start diversity to pull_down div_str - just for i2c-enumeration */
+		dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
+
+		/* set new i2c address and force divstart */
+		dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
+		client.addr = new_addr;
+		dib8000_identify(&client);
+
+		dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
+	}
+
+	for (k = 0; k < no_of_demods; k++) {
+		new_addr = first_addr | (k << 1);
+		client.addr = new_addr;
+
+		// unforce divstr
+		dib8000_i2c_write16(&client, 1285, new_addr << 2);
+
+		/* deactivate div - it was just for i2c-enumeration */
+		dib8000_i2c_write16(&client, 1286, 0);
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL(dib8000_i2c_enumeration);
+static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
+{
+	tune->min_delay_ms = 1000;
+	tune->step_size = 0;
+	tune->max_drift = 0;
+	return 0;
+}
+
+static void dib8000_release(struct dvb_frontend *fe)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+	dibx000_exit_i2c_master(&st->i2c_master);
+	kfree(st);
+}
+
+struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
+{
+	struct dib8000_state *st = fe->demodulator_priv;
+	return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
+}
+
+EXPORT_SYMBOL(dib8000_get_i2c_master);
+
+static const struct dvb_frontend_ops dib8000_ops = {
+	.info = {
+		 .name = "DiBcom 8000 ISDB-T",
+		 .type = FE_OFDM,
+		 .frequency_min = 44250000,
+		 .frequency_max = 867250000,
+		 .frequency_stepsize = 62500,
+		 .caps = FE_CAN_INVERSION_AUTO |
+		 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+		 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+		 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+		 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
+		 },
+
+	.release = dib8000_release,
+
+	.init = dib8000_wakeup,
+	.sleep = dib8000_sleep,
+
+	.set_frontend = dib8000_set_frontend,
+	.get_tune_settings = dib8000_fe_get_tune_settings,
+	.get_frontend = dib8000_get_frontend,
+
+	.read_status = dib8000_read_status,
+	.read_ber = dib8000_read_ber,
+	.read_signal_strength = dib8000_read_signal_strength,
+	.read_snr = dib8000_read_snr,
+	.read_ucblocks = dib8000_read_unc_blocks,
+};
+
+struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
+{
+	struct dvb_frontend *fe;
+	struct dib8000_state *state;
+
+	dprintk("dib8000_attach");
+
+	state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
+	if (state == NULL)
+		return NULL;
+
+	memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
+	state->i2c.adap = i2c_adap;
+	state->i2c.addr = i2c_addr;
+	state->gpio_val = cfg->gpio_val;
+	state->gpio_dir = cfg->gpio_dir;
+
+	/* Ensure the output mode remains at the previous default if it's
+	 * not specifically set by the caller.
+	 */
+	if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
+		state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
+
+	fe = &state->fe;
+	fe->demodulator_priv = state;
+	memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
+
+	state->timf_default = cfg->pll->timf;
+
+	if (dib8000_identify(&state->i2c) == 0)
+		goto error;
+
+	dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
+
+	dib8000_reset(fe);
+
+	dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));	/* ber_rs_len = 3 */
+
+	return fe;
+
+ error:
+	kfree(state);
+	return NULL;
+}
+
+EXPORT_SYMBOL(dib8000_attach);
+
+MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
+MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
new file mode 100644
index 0000000..a86de34
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -0,0 +1,79 @@
+#ifndef DIB8000_H
+#define DIB8000_H
+
+#include "dibx000_common.h"
+
+struct dib8000_config {
+	u8 output_mpeg2_in_188_bytes;
+	u8 hostbus_diversity;
+	u8 tuner_is_baseband;
+	int (*update_lna) (struct dvb_frontend *, u16 agc_global);
+
+	u8 agc_config_count;
+	struct dibx000_agc_config *agc;
+	struct dibx000_bandwidth_config *pll;
+
+#define DIB8000_GPIO_DEFAULT_DIRECTIONS 0xffff
+	u16 gpio_dir;
+#define DIB8000_GPIO_DEFAULT_VALUES     0x0000
+	u16 gpio_val;
+#define DIB8000_GPIO_PWM_POS0(v)        ((v & 0xf) << 12)
+#define DIB8000_GPIO_PWM_POS1(v)        ((v & 0xf) << 8 )
+#define DIB8000_GPIO_PWM_POS2(v)        ((v & 0xf) << 4 )
+#define DIB8000_GPIO_PWM_POS3(v)         (v & 0xf)
+#define DIB8000_GPIO_DEFAULT_PWM_POS    0xffff
+	u16 gpio_pwm_pos;
+	u16 pwm_freq_div;
+
+	void (*agc_control) (struct dvb_frontend *, u8 before);
+
+	u16 drives;
+	u16 diversity_delay;
+	u8 div_cfg;
+	u8 output_mode;
+	u8 refclksel;
+};
+
+#define DEFAULT_DIB8000_I2C_ADDRESS 18
+
+#if defined(CONFIG_DVB_DIB8000) || (defined(CONFIG_DVB_DIB8000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
+extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
+
+extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
+
+extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
+extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
+#else
+static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
+static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+
+int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+
+int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return -ENODEV;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index 315e09e..4efca30 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -15,29 +15,31 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
 		(val >> 8) & 0xff, val & 0xff,
 	};
 	struct i2c_msg msg = {
-		.addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4
+		.addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
 	};
 	return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
 
-static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf)
+static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
+					enum dibx000_i2c_interface intf)
 {
 	if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
-		dprintk("selecting interface: %d\n",intf);
+		dprintk("selecting interface: %d\n", intf);
 		mst->selected_interface = intf;
 		return dibx000_write_word(mst, mst->base_reg + 4, intf);
 	}
 	return 0;
 }
 
-static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff)
+static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
+				 u8 addr, int onoff)
 {
 	u16 val;
 
 
 	if (onoff)
-		val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
+		val = addr << 8;	// bit 7 = use master or not, if 0, the gate is open
 	else
 		val = 1 << 7;
 
@@ -45,7 +47,7 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 ad
 		val <<= 1;
 
 	tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
-	tx[1] = ( (mst->base_reg + 1)       & 0xff);
+	tx[1] = ((mst->base_reg + 1) & 0xff);
 	tx[2] = val >> 8;
 	tx[3] = val & 0xff;
 
@@ -57,59 +59,78 @@ static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
 	return I2C_FUNC_I2C;
 }
 
-static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
+					struct i2c_msg msg[], int num)
 {
 	struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
 	struct i2c_msg m[2 + num];
 	u8 tx_open[4], tx_close[4];
 
-	memset(m,0, sizeof(struct i2c_msg) * (2 + num));
+	memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
 
 	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
 
-	dibx000_i2c_gate_ctrl(mst, tx_open,  msg[0].addr, 1);
+	dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
 	m[0].addr = mst->i2c_addr;
-	m[0].buf  = tx_open;
-	m[0].len  = 4;
+	m[0].buf = tx_open;
+	m[0].len = 4;
 
 	memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
 
 	dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
-	m[num+1].addr = mst->i2c_addr;
-	m[num+1].buf  = tx_close;
-	m[num+1].len  = 4;
+	m[num + 1].addr = mst->i2c_addr;
+	m[num + 1].buf = tx_close;
+	m[num + 1].len = 4;
 
-	return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO;
+	return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
 }
 
 static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
-	.master_xfer   = dibx000_i2c_gated_tuner_xfer,
+	.master_xfer = dibx000_i2c_gated_tuner_xfer,
 	.functionality = dibx000_i2c_func,
 };
 
-struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating)
+struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
+					    enum dibx000_i2c_interface intf,
+					    int gating)
 {
 	struct i2c_adapter *i2c = NULL;
 
 	switch (intf) {
-		case DIBX000_I2C_INTERFACE_TUNER:
-			if (gating)
-				i2c = &mst->gated_tuner_i2c_adap;
-			break;
-		default:
-			printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
-			break;
+	case DIBX000_I2C_INTERFACE_TUNER:
+		if (gating)
+			i2c = &mst->gated_tuner_i2c_adap;
+		break;
+	default:
+		printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
+		break;
 	}
 
 	return i2c;
 }
+
 EXPORT_SYMBOL(dibx000_get_i2c_adapter);
 
-static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst)
+void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
+{
+	/* initialize the i2c-master by closing the gate */
+	u8 tx[4];
+	struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
+
+	dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
+	i2c_transfer(mst->i2c_adap, &m, 1);
+	mst->selected_interface = 0xff;	// the first time force a select of the I2C
+	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
+}
+
+EXPORT_SYMBOL(dibx000_reset_i2c_master);
+
+static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
+			    struct i2c_algorithm *algo, const char *name,
+			    struct dibx000_i2c_master *mst)
 {
 	strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
-	i2c_adap->class     = I2C_CLASS_TV_DIGITAL,
-	i2c_adap->algo      = algo;
+	i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo;
 	i2c_adap->algo_data = NULL;
 	i2c_set_adapdata(i2c_adap, mst);
 	if (i2c_add_adapter(i2c_adap) < 0)
@@ -117,34 +138,40 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *
 	return 0;
 }
 
-int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr)
+int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
+			    struct i2c_adapter *i2c_adap, u8 i2c_addr)
 {
 	u8 tx[4];
-	struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 };
+	struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
 
 	mst->device_rev = device_rev;
-	mst->i2c_adap   = i2c_adap;
-	mst->i2c_addr   = i2c_addr >> 1;
+	mst->i2c_adap = i2c_adap;
+	mst->i2c_addr = i2c_addr >> 1;
 
-	if (device_rev == DIB7000P)
+	if (device_rev == DIB7000P || device_rev == DIB8000)
 		mst->base_reg = 1024;
 	else
 		mst->base_reg = 768;
 
-    if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0)
-		printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n");
+	if (i2c_adapter_init
+	    (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
+	     "DiBX000 tuner I2C bus", mst) != 0)
+		printk(KERN_ERR
+		       "DiBX000: could not initialize the tuner i2c_adapter\n");
 
 	/* initialize the i2c-master by closing the gate */
 	dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
 
 	return i2c_transfer(i2c_adap, &m, 1) == 1;
 }
+
 EXPORT_SYMBOL(dibx000_init_i2c_master);
 
 void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
 {
 	i2c_del_adapter(&mst->gated_tuner_i2c_adap);
 }
+
 EXPORT_SYMBOL(dibx000_exit_i2c_master);
 
 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index 84e4d53..5be10ec 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -2,7 +2,7 @@
 #define DIBX000_COMMON_H
 
 enum dibx000_i2c_interface {
-	DIBX000_I2C_INTERFACE_TUNER    = 0,
+	DIBX000_I2C_INTERFACE_TUNER = 0,
 	DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
 	DIBX000_I2C_INTERFACE_GPIO_3_4 = 2
 };
@@ -12,22 +12,29 @@ struct dibx000_i2c_master {
 #define DIB7000   2
 #define DIB7000P  11
 #define DIB7000MC 12
+#define DIB8000   13
 	u16 device_rev;
 
 	enum dibx000_i2c_interface selected_interface;
 
-//	struct i2c_adapter  tuner_i2c_adap;
-	struct i2c_adapter  gated_tuner_i2c_adap;
+//      struct i2c_adapter  tuner_i2c_adap;
+	struct i2c_adapter gated_tuner_i2c_adap;
 
 	struct i2c_adapter *i2c_adap;
-	u8                  i2c_addr;
+	u8 i2c_addr;
 
 	u16 base_reg;
 };
 
-extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr);
-extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating);
+extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
+				   u16 device_rev, struct i2c_adapter *i2c_adap,
+				   u8 i2c_addr);
+extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
+						   *mst,
+						   enum dibx000_i2c_interface
+						   intf, int gating);
 extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
+extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
 
 #define BAND_LBAND 0x01
 #define BAND_UHF   0x02
@@ -41,18 +48,18 @@ extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
 									(freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
 
 struct dibx000_agc_config {
-	/* defines the capabilities of this AGC-setting - using the BAND_-defines*/
-	u8  band_caps;
+	/* defines the capabilities of this AGC-setting - using the BAND_-defines */
+	u8 band_caps;
 
 	u16 setup;
 
 	u16 inv_gain;
 	u16 time_stabiliz;
 
-	u8  alpha_level;
+	u8 alpha_level;
 	u16 thlock;
 
-	u8  wbd_inv;
+	u8 wbd_inv;
 	u16 wbd_ref;
 	u8 wbd_sel;
 	u8 wbd_alpha;
@@ -92,8 +99,8 @@ struct dibx000_agc_config {
 };
 
 struct dibx000_bandwidth_config {
-	u32   internal;
-	u32   sampling;
+	u32 internal;
+	u32 sampling;
 
 	u8 pll_prediv;
 	u8 pll_ratio;
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 9f63499..6d865d6 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -389,6 +389,77 @@ static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
 	}
 };
 
+/* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
+static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
+	.name	= "Samsung TDTC9251DH0",
+	.min	=  48000000,
+	.max	= 863000000,
+	.iffreq	=  36166667,
+	.count	= 3,
+	.entries = {
+		{ 157500000, 166667, 0xcc, 0x09 },
+		{ 443000000, 166667, 0xcc, 0x0a },
+		{ 863000000, 166667, 0xcc, 0x08 },
+	}
+};
+
+/* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
+static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
+	.name = "Samsung TBDU18132",
+	.min	=  950000,
+	.max	= 2150000, /* guesses */
+	.iffreq = 0,
+	.count = 2,
+	.entries = {
+		{ 1550000, 125, 0x84, 0x82 },
+		{ 4095937, 125, 0x84, 0x80 },
+	}
+	/* TSA5059 PLL has a 17 bit divisor rather than the 15 bits supported
+	 * by this driver.  The two extra bits are 0x60 in the third byte.  15
+	 * bits is enough for over 4 GHz, which is enough to cover the range
+	 * of this tuner.  We could use the additional divisor bits by adding
+	 * more entries, e.g.
+	 { 0x0ffff * 125 + 125/2, 125, 0x84 | 0x20, },
+	 { 0x17fff * 125 + 125/2, 125, 0x84 | 0x40, },
+	 { 0x1ffff * 125 + 125/2, 125, 0x84 | 0x60, }, */
+};
+
+/* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
+static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
+	.name = "Samsung TBMU24112",
+	.min	=  950000,
+	.max	= 2150000, /* guesses */
+	.iffreq = 0,
+	.count = 2,
+	.entries = {
+		{ 1500000, 125, 0x84, 0x18 },
+		{ 9999999, 125, 0x84, 0x08 },
+	}
+};
+
+/* Alps TDEE4 DVB-C NIM, used on Cablestar 2 */
+/* byte 4 : 1  *   *   AGD R3  R2  R1  R0
+ * byte 5 : C1 *   RE  RTS BS4 BS3 BS2 BS1
+ * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95
+ * Range(MHz)  C1 *  RE RTS BS4 BS3 BS2 BS1  Byte 5
+ *  47 - 153   0  *  0   0   0   0   0   1   0x01
+ * 153 - 430   0  *  0   0   0   0   1   0   0x02
+ * 430 - 822   0  *  0   0   1   0   0   0   0x08
+ * 822 - 862   1  *  0   0   1   0   0   0   0x88 */
+static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
+	.name = "ALPS TDEE4",
+	.min	=  47000000,
+	.max	= 862000000,
+	.iffreq	=  36125000,
+	.count = 4,
+	.entries = {
+		{ 153000000, 62500, 0x95, 0x01 },
+		{ 430000000, 62500, 0x95, 0x02 },
+		{ 822000000, 62500, 0x95, 0x08 },
+		{ 999999999, 62500, 0x95, 0x88 },
+	}
+};
+
 /* ----------------------------------------------------------- */
 
 static struct dvb_pll_desc *pll_list[] = {
@@ -402,11 +473,15 @@ static struct dvb_pll_desc *pll_list[] = {
 	[DVB_PLL_TUA6034]                = &dvb_pll_tua6034,
 	[DVB_PLL_TDA665X]                = &dvb_pll_tda665x,
 	[DVB_PLL_TDED4]                  = &dvb_pll_tded4,
+	[DVB_PLL_TDEE4]                  = &dvb_pll_alps_tdee4,
 	[DVB_PLL_TDHU2]                  = &dvb_pll_tdhu2,
 	[DVB_PLL_SAMSUNG_TBMV]           = &dvb_pll_samsung_tbmv,
 	[DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
 	[DVB_PLL_OPERA1]                 = &dvb_pll_opera1,
 	[DVB_PLL_SAMSUNG_DTOS403IH102A]  = &dvb_pll_samsung_dtos403ih102a,
+	[DVB_PLL_SAMSUNG_TDTC9251DH0]    = &dvb_pll_samsung_tdtc9251dh0,
+	[DVB_PLL_SAMSUNG_TBDU18132]	 = &dvb_pll_samsung_tbdu18132,
+	[DVB_PLL_SAMSUNG_TBMU24112]      = &dvb_pll_samsung_tbmu24112,
 };
 
 /* ----------------------------------------------------------- */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 05239f5..0869643 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -23,6 +23,10 @@
 #define DVB_PLL_PHILIPS_SD1878_TDA8261 12
 #define DVB_PLL_OPERA1                 13
 #define DVB_PLL_SAMSUNG_DTOS403IH102A  14
+#define DVB_PLL_SAMSUNG_TDTC9251DH0    15
+#define DVB_PLL_SAMSUNG_TBDU18132      16
+#define DVB_PLL_SAMSUNG_TBMU24112      17
+#define DVB_PLL_TDEE4		       18
 
 /**
  * Attach a dvb-pll to the supplied frontend structure.
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
index eb72a98..e334b5d 100644
--- a/drivers/media/dvb/frontends/lgdt3304.c
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -363,6 +363,8 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
 
 	struct lgdt3304_state *state;
 	state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
+	if (state == NULL)
+		return NULL;
 	state->addr = config->i2c_address;
 	state->i2c = i2c;
 
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index fde2764..eabcadc 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -1,9 +1,9 @@
 /*
- *    Support for Legend Silicon DMB-TH demodulator
- *    LGS8913, LGS8GL5
+ *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
+ *    LGS8913, LGS8GL5, LGS8G75
  *    experimental support LGS8G42, LGS8G52
  *
- *    Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
  *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
  *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
  *
@@ -46,6 +46,42 @@ module_param(fake_signal_str, int, 0644);
 MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
 "Signal strength calculation is slow.(default:on).");
 
+static const u8 lgs8g75_initdat[] = {
+	0x01, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0xE4, 0xF5, 0xA8, 0xF5, 0xB8, 0xF5, 0x88, 0xF5,
+	0x89, 0xF5, 0x87, 0x75, 0xD0, 0x00, 0x11, 0x50,
+	0x11, 0x50, 0xF4, 0xF5, 0x80, 0xF5, 0x90, 0xF5,
+	0xA0, 0xF5, 0xB0, 0x75, 0x81, 0x30, 0x80, 0x01,
+	0x32, 0x90, 0x80, 0x12, 0x74, 0xFF, 0xF0, 0x90,
+	0x80, 0x13, 0x74, 0x1F, 0xF0, 0x90, 0x80, 0x23,
+	0x74, 0x01, 0xF0, 0x90, 0x80, 0x22, 0xF0, 0x90,
+	0x00, 0x48, 0x74, 0x00, 0xF0, 0x90, 0x80, 0x4D,
+	0x74, 0x05, 0xF0, 0x90, 0x80, 0x09, 0xE0, 0x60,
+	0x21, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x1B, 0x12,
+	0x00, 0xDD, 0x14, 0x60, 0x15, 0x12, 0x00, 0xDD,
+	0x14, 0x60, 0x0F, 0x12, 0x00, 0xDD, 0x14, 0x60,
+	0x09, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x03, 0x12,
+	0x00, 0xDD, 0x90, 0x80, 0x42, 0xE0, 0x60, 0x0B,
+	0x14, 0x60, 0x0C, 0x14, 0x60, 0x0D, 0x14, 0x60,
+	0x0E, 0x01, 0xB3, 0x74, 0x04, 0x01, 0xB9, 0x74,
+	0x05, 0x01, 0xB9, 0x74, 0x07, 0x01, 0xB9, 0x74,
+	0x0A, 0xC0, 0xE0, 0x74, 0xC8, 0x12, 0x00, 0xE2,
+	0xD0, 0xE0, 0x14, 0x70, 0xF4, 0x90, 0x80, 0x09,
+	0xE0, 0x70, 0xAE, 0x12, 0x00, 0xF6, 0x12, 0x00,
+	0xFE, 0x90, 0x00, 0x48, 0xE0, 0x04, 0xF0, 0x90,
+	0x80, 0x4E, 0xF0, 0x01, 0x73, 0x90, 0x80, 0x08,
+	0xF0, 0x22, 0xF8, 0x7A, 0x0C, 0x79, 0xFD, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9,
+	0xF6, 0xDA, 0xF2, 0xD8, 0xEE, 0x22, 0x90, 0x80,
+	0x65, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x80,
+	0x65, 0xE0, 0x44, 0xC2, 0xF0, 0x22
+};
+
 /* LGS8GXX internal helper functions */
 
 static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
@@ -55,7 +91,7 @@ static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
 	struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
 
 	msg.addr = priv->config->demod_address;
-	if (reg >= 0xC0)
+	if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
 		msg.addr += 0x02;
 
 	if (debug >= 2)
@@ -84,7 +120,7 @@ static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
 	};
 
 	dev_addr = priv->config->demod_address;
-	if (reg >= 0xC0)
+	if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
 		dev_addr += 0x02;
 	msg[1].addr =  msg[0].addr = dev_addr;
 
@@ -112,19 +148,36 @@ static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
 	return 0;
 }
 
+static int wait_reg_mask(struct lgs8gxx_state *priv, u8 reg, u8 mask,
+	u8 val, u8 delay, u8 tries)
+{
+	u8 t;
+	int i;
+
+	for (i = 0; i < tries; i++) {
+		lgs8gxx_read_reg(priv, reg, &t);
+
+		if ((t & mask) == val)
+			return 0;
+		msleep(delay);
+	}
+
+	return 1;
+}
+
 static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
 {
 	const struct lgs8gxx_config *config = priv->config;
 	u8 if_conf;
 
-	if_conf = 0x10; /* AGC output on; */
+	if_conf = 0x10; /* AGC output on, RF_AGC output off; */
 
 	if_conf |=
 		((config->ext_adc) ? 0x80 : 0x00) |
 		((config->if_neg_center) ? 0x04 : 0x00) |
 		((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
-		((config->ext_adc && config->adc_signed) ? 0x02 : 0x00) |
-		((config->ext_adc && config->if_neg_edge) ? 0x01 : 0x00);
+		((config->adc_signed) ? 0x02 : 0x00) |
+		((config->if_neg_edge) ? 0x01 : 0x00);
 
 	if (config->ext_adc &&
 		(config->prod == LGS8GXX_PROD_LGS8G52)) {
@@ -157,39 +210,82 @@ static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
 	}
 	dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
 
-	lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
-	lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
-	lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
-	lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		lgs8gxx_write_reg(priv, 0x08, 0xFF & (v32));
+		lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32 >> 8));
+		lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 16));
+		lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 24));
+	} else {
+		lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
+		lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
+		lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
+		lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
+	}
+
+	return 0;
+}
+
+static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
+{
+	u64 val;
+	u32 v32 = 0;
+	u8 reg_addr, t;
+	int i;
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+		reg_addr = 0x23;
+	else
+		reg_addr = 0x48;
+
+	for (i = 0; i < 4; i++) {
+		lgs8gxx_read_reg(priv, reg_addr, &t);
+		v32 <<= 8;
+		v32 |= t;
+		reg_addr--;
+	}
 
+	val = v32;
+	val *= priv->config->if_clk_freq;
+	val /= (u64)1 << 32;
+	dprintk("AFC = %u kHz\n", (u32)val);
 	return 0;
 }
 
 static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
 {
 	u8 t;
+	u8 prod = priv->config->prod;
 
-	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+	if (prod == LGS8GXX_PROD_LGS8913)
 		lgs8gxx_write_reg(priv, 0xC6, 0x01);
 
-	lgs8gxx_read_reg(priv, 0x7E, &t);
-	lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
-
-	/* clear FEC self reset */
-	lgs8gxx_read_reg(priv, 0xC5, &t);
-	lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
+	if (prod == LGS8GXX_PROD_LGS8G75) {
+		lgs8gxx_read_reg(priv, 0x0C, &t);
+		t &= (~0x04);
+		lgs8gxx_write_reg(priv, 0x0C, t | 0x80);
+		lgs8gxx_write_reg(priv, 0x39, 0x00);
+		lgs8gxx_write_reg(priv, 0x3D, 0x04);
+	} else if (prod == LGS8GXX_PROD_LGS8913 ||
+		prod == LGS8GXX_PROD_LGS8GL5 ||
+		prod == LGS8GXX_PROD_LGS8G42 ||
+		prod == LGS8GXX_PROD_LGS8G52 ||
+		prod == LGS8GXX_PROD_LGS8G54) {
+		lgs8gxx_read_reg(priv, 0x7E, &t);
+		lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
+
+		/* clear FEC self reset */
+		lgs8gxx_read_reg(priv, 0xC5, &t);
+		lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
+	}
 
-	if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
+	if (prod == LGS8GXX_PROD_LGS8913) {
 		/* FEC auto detect */
 		lgs8gxx_write_reg(priv, 0xC1, 0x03);
 
 		lgs8gxx_read_reg(priv, 0x7C, &t);
 		t = (t & 0x8C) | 0x03;
 		lgs8gxx_write_reg(priv, 0x7C, t);
-	}
-
 
-	if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
 		/* BER test mode */
 		lgs8gxx_read_reg(priv, 0xC3, &t);
 		t = (t & 0xEF) |  0x10;
@@ -207,6 +303,32 @@ static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
 	int ret = 0;
 	u8 t;
 
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		u8 t2;
+		lgs8gxx_read_reg(priv, 0x0C, &t);
+		t &= (~0x80);
+		lgs8gxx_write_reg(priv, 0x0C, t);
+
+		lgs8gxx_read_reg(priv, 0x0C, &t);
+		lgs8gxx_read_reg(priv, 0x19, &t2);
+
+		if (((t&0x03) == 0x01) && (t2&0x01)) {
+			lgs8gxx_write_reg(priv, 0x6E, 0x05);
+			lgs8gxx_write_reg(priv, 0x39, 0x02);
+			lgs8gxx_write_reg(priv, 0x39, 0x03);
+			lgs8gxx_write_reg(priv, 0x3D, 0x05);
+			lgs8gxx_write_reg(priv, 0x3E, 0x28);
+			lgs8gxx_write_reg(priv, 0x53, 0x80);
+		} else {
+			lgs8gxx_write_reg(priv, 0x6E, 0x3F);
+			lgs8gxx_write_reg(priv, 0x39, 0x00);
+			lgs8gxx_write_reg(priv, 0x3D, 0x04);
+		}
+
+		lgs8gxx_soft_reset(priv);
+		return 0;
+	}
+
 	/* turn off auto-detect; manual settings */
 	lgs8gxx_write_reg(priv, 0x7E, 0);
 	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
@@ -226,11 +348,39 @@ static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
 	int ret = 0;
 	u8 t;
 
-	ret = lgs8gxx_read_reg(priv, 0x4B, &t);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+		ret = lgs8gxx_read_reg(priv, 0x13, &t);
+	else
+		ret = lgs8gxx_read_reg(priv, 0x4B, &t);
 	if (ret != 0)
 		return ret;
 
-	*locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+		*locked = ((t & 0x80) == 0x80) ? 1 : 0;
+	else
+		*locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
+	return 0;
+}
+
+/* Wait for Code Acquisition Lock */
+static int lgs8gxx_wait_ca_lock(struct lgs8gxx_state *priv, u8 *locked)
+{
+	int ret = 0;
+	u8 reg, mask, val;
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		reg = 0x13;
+		mask = 0x80;
+		val = 0x80;
+	} else {
+		reg = 0x4B;
+		mask = 0xC0;
+		val = 0xC0;
+	}
+
+	ret = wait_reg_mask(priv, reg, mask, val, 50, 40);
+	*locked = (ret == 0) ? 1 : 0;
+
 	return 0;
 }
 
@@ -238,21 +388,30 @@ static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
 					  u8 *finished)
 {
 	int ret = 0;
-	u8 t;
+	u8 reg, mask, val;
 
-	ret = lgs8gxx_read_reg(priv, 0xA4, &t);
-	if (ret != 0)
-		return ret;
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		reg = 0x1f;
+		mask = 0xC0;
+		val = 0x80;
+	} else {
+		reg = 0xA4;
+		mask = 0x03;
+		val = 0x01;
+	}
 
-	*finished = ((t & 0x3) == 0x1) ? 1 : 0;
+	ret = wait_reg_mask(priv, reg, mask, val, 10, 20);
+	*finished = (ret == 0) ? 1 : 0;
 
 	return 0;
 }
 
-static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked)
+static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 cpn,
+	u8 *locked)
 {
-	int err;
+	int err = 0;
 	u8 ad_fini = 0;
+	u8 t1, t2;
 
 	if (gi == GI_945)
 		dprintk("try GI 945\n");
@@ -260,17 +419,29 @@ static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 *locked)
 		dprintk("try GI 595\n");
 	else if (gi == GI_420)
 		dprintk("try GI 420\n");
-	lgs8gxx_write_reg(priv, 0x04, gi);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		lgs8gxx_read_reg(priv, 0x0C, &t1);
+		lgs8gxx_read_reg(priv, 0x18, &t2);
+		t1 &= ~(GI_MASK);
+		t1 |= gi;
+		t2 &= 0xFE;
+		t2 |= cpn ? 0x01 : 0x00;
+		lgs8gxx_write_reg(priv, 0x0C, t1);
+		lgs8gxx_write_reg(priv, 0x18, t2);
+	} else {
+		lgs8gxx_write_reg(priv, 0x04, gi);
+	}
 	lgs8gxx_soft_reset(priv);
-	msleep(50);
+	err = lgs8gxx_wait_ca_lock(priv, locked);
+	if (err || !(*locked))
+		return err;
 	err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
 	if (err != 0)
 		return err;
 	if (ad_fini) {
-		err = lgs8gxx_is_locked(priv, locked);
-		if (err != 0)
-			return err;
-	}
+		dprintk("auto detect finished\n");
+	} else
+		*locked = 0;
 
 	return 0;
 }
@@ -285,13 +456,18 @@ static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
 	dprintk("%s\n", __func__);
 
 	lgs8gxx_set_mode_auto(priv);
-	/* Guard Interval */
-	lgs8gxx_write_reg(priv, 0x03, 00);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		lgs8gxx_write_reg(priv, 0x67, 0xAA);
+		lgs8gxx_write_reg(priv, 0x6E, 0x3F);
+	} else {
+		/* Guard Interval */
+		lgs8gxx_write_reg(priv, 0x03, 00);
+	}
 
 	for (i = 0; i < 2; i++) {
 		for (j = 0; j < 2; j++) {
 			tmp_gi = GI_945;
-			err = lgs8gxx_autolock_gi(priv, GI_945, &locked);
+			err = lgs8gxx_autolock_gi(priv, GI_945, j, &locked);
 			if (err)
 				goto out;
 			if (locked)
@@ -299,14 +475,14 @@ static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
 		}
 		for (j = 0; j < 2; j++) {
 			tmp_gi = GI_420;
-			err = lgs8gxx_autolock_gi(priv, GI_420, &locked);
+			err = lgs8gxx_autolock_gi(priv, GI_420, j, &locked);
 			if (err)
 				goto out;
 			if (locked)
 				goto locked;
 		}
 		tmp_gi = GI_595;
-		err = lgs8gxx_autolock_gi(priv, GI_595, &locked);
+		err = lgs8gxx_autolock_gi(priv, GI_595, 1, &locked);
 		if (err)
 			goto out;
 		if (locked)
@@ -317,8 +493,13 @@ locked:
 	if ((err == 0) && (locked == 1)) {
 		u8 t;
 
-		lgs8gxx_read_reg(priv, 0xA2, &t);
-		*detected_param = t;
+		if (priv->config->prod != LGS8GXX_PROD_LGS8G75) {
+			lgs8gxx_read_reg(priv, 0xA2, &t);
+			*detected_param = t;
+		} else {
+			lgs8gxx_read_reg(priv, 0x1F, &t);
+			*detected_param = t & 0x3F;
+		}
 
 		if (tmp_gi == GI_945)
 			dprintk("GI 945 locked\n");
@@ -345,18 +526,28 @@ static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
 
 	if (err != 0) {
 		dprintk("lgs8gxx_auto_detect failed\n");
-	}
+	} else
+		dprintk("detected param = 0x%02X\n", detected_param);
 
 	/* Apply detected parameters */
 	if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
 		u8 inter_leave_len = detected_param & TIM_MASK ;
-		inter_leave_len = (inter_leave_len == TIM_LONG) ? 0x60 : 0x40;
+		/* Fix 8913 time interleaver detection bug */
+		inter_leave_len = (inter_leave_len == TIM_MIDDLE) ? 0x60 : 0x40;
 		detected_param &= CF_MASK | SC_MASK  | LGS_FEC_MASK;
 		detected_param |= inter_leave_len;
 	}
-	lgs8gxx_write_reg(priv, 0x7D, detected_param);
-	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
-		lgs8gxx_write_reg(priv, 0xC0, detected_param);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		u8 t;
+		lgs8gxx_read_reg(priv, 0x19, &t);
+		t &= 0x81;
+		t |= detected_param << 1;
+		lgs8gxx_write_reg(priv, 0x19, t);
+	} else {
+		lgs8gxx_write_reg(priv, 0x7D, detected_param);
+		if (priv->config->prod == LGS8GXX_PROD_LGS8913)
+			lgs8gxx_write_reg(priv, 0xC0, detected_param);
+	}
 	/* lgs8gxx_soft_reset(priv); */
 
 	/* Enter manual mode */
@@ -378,9 +569,10 @@ static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
 	u8 serial, u8 clk_pol, u8 clk_gated)
 {
 	int ret = 0;
-	u8 t;
+	u8 t, reg_addr;
 
-	ret = lgs8gxx_read_reg(priv, 0xC2, &t);
+	reg_addr = (priv->config->prod == LGS8GXX_PROD_LGS8G75) ? 0x30 : 0xC2;
+	ret = lgs8gxx_read_reg(priv, reg_addr, &t);
 	if (ret != 0)
 		return ret;
 
@@ -389,13 +581,29 @@ static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
 	t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
 	t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
 
-	ret = lgs8gxx_write_reg(priv, 0xC2, t);
+	ret = lgs8gxx_write_reg(priv, reg_addr, t);
 	if (ret != 0)
 		return ret;
 
 	return 0;
 }
 
+/* A/D input peak-to-peak voltage range */
+static int lgs8g75_set_adc_vpp(struct lgs8gxx_state *priv,
+	u8 sel)
+{
+	u8 r26 = 0x73, r27 = 0x90;
+
+	if (priv->config->prod != LGS8GXX_PROD_LGS8G75)
+		return 0;
+
+	r26 |= (sel & 0x01) << 7;
+	r27 |= (sel & 0x02) >> 1;
+	lgs8gxx_write_reg(priv, 0x26, r26);
+	lgs8gxx_write_reg(priv, 0x27, r27);
+
+	return 0;
+}
 
 /* LGS8913 demod frontend functions */
 
@@ -417,6 +625,34 @@ static int lgs8913_init(struct lgs8gxx_state *priv)
 	return 0;
 }
 
+static int lgs8g75_init_data(struct lgs8gxx_state *priv)
+{
+	const u8 *p = lgs8g75_initdat;
+	int i;
+
+	lgs8gxx_write_reg(priv, 0xC6, 0x40);
+
+	lgs8gxx_write_reg(priv, 0x3D, 0x04);
+	lgs8gxx_write_reg(priv, 0x39, 0x00);
+
+	lgs8gxx_write_reg(priv, 0x3A, 0x00);
+	lgs8gxx_write_reg(priv, 0x38, 0x00);
+	lgs8gxx_write_reg(priv, 0x3B, 0x00);
+	lgs8gxx_write_reg(priv, 0x38, 0x00);
+
+	for (i = 0; i < sizeof(lgs8g75_initdat); i++) {
+		lgs8gxx_write_reg(priv, 0x38, 0x00);
+		lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff));
+		lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8));
+		lgs8gxx_write_reg(priv, 0x3C, *p);
+		p++;
+	}
+
+	lgs8gxx_write_reg(priv, 0x38, 0x00);
+
+	return 0;
+}
+
 static int lgs8gxx_init(struct dvb_frontend *fe)
 {
 	struct lgs8gxx_state *priv =
@@ -429,6 +665,9 @@ static int lgs8gxx_init(struct dvb_frontend *fe)
 	lgs8gxx_read_reg(priv, 0, &data);
 	dprintk("reg 0 = 0x%02X\n", data);
 
+	if (config->prod == LGS8GXX_PROD_LGS8G75)
+		lgs8g75_set_adc_vpp(priv, config->adc_vpp);
+
 	/* Setup MPEG output format */
 	err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
 				    config->ts_clk_pol,
@@ -439,8 +678,7 @@ static int lgs8gxx_init(struct dvb_frontend *fe)
 	if (config->prod == LGS8GXX_PROD_LGS8913)
 		lgs8913_init(priv);
 	lgs8gxx_set_if_freq(priv, priv->config->if_freq);
-	if (config->prod != LGS8GXX_PROD_LGS8913)
-		lgs8gxx_set_ad_mode(priv);
+	lgs8gxx_set_ad_mode(priv);
 
 	return 0;
 }
@@ -489,9 +727,6 @@ static int lgs8gxx_set_fe(struct dvb_frontend *fe,
 static int lgs8gxx_get_fe(struct dvb_frontend *fe,
 			  struct dvb_frontend_parameters *fe_params)
 {
-	struct lgs8gxx_state *priv = fe->demodulator_priv;
-	u8 t;
-
 	dprintk("%s\n", __func__);
 
 	/* TODO: get real readings from device */
@@ -501,29 +736,10 @@ static int lgs8gxx_get_fe(struct dvb_frontend *fe,
 	/* bandwidth */
 	fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
 
-
-	lgs8gxx_read_reg(priv, 0x7D, &t);
 	fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
 	fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
 
-	/* constellation */
-	switch (t & SC_MASK) {
-	case SC_QAM64:
-		fe_params->u.ofdm.constellation = QAM_64;
-		break;
-	case SC_QAM32:
-		fe_params->u.ofdm.constellation = QAM_32;
-		break;
-	case SC_QAM16:
-		fe_params->u.ofdm.constellation = QAM_16;
-		break;
-	case SC_QAM4:
-	case SC_QAM4NR:
-		fe_params->u.ofdm.constellation = QPSK;
-		break;
-	default:
-		fe_params->u.ofdm.constellation = QAM_64;
-	}
+	fe_params->u.ofdm.constellation = QAM_AUTO;
 
 	/* transmission mode */
 	fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
@@ -552,9 +768,19 @@ static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
 {
 	struct lgs8gxx_state *priv = fe->demodulator_priv;
 	s8 ret;
-	u8 t;
+	u8 t, locked = 0;
 
 	dprintk("%s\n", __func__);
+	*fe_status = 0;
+
+	lgs8gxx_get_afc_phase(priv);
+	lgs8gxx_is_locked(priv, &locked);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		if (locked)
+			*fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+		return 0;
+	}
 
 	ret = lgs8gxx_read_reg(priv, 0x4B, &t);
 	if (ret != 0)
@@ -658,12 +884,33 @@ static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
 	return 0;
 }
 
+static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
+{
+	u8 t;
+	s16 v = 0;
+
+	dprintk("%s\n", __func__);
+
+	lgs8gxx_read_reg(priv, 0xB1, &t);
+	v |= t;
+	v <<= 8;
+	lgs8gxx_read_reg(priv, 0xB0, &t);
+	v |= t;
+
+	*signal = v;
+	dprintk("%s: signal=0x%02X\n", __func__, *signal);
+
+	return 0;
+}
+
 static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
 {
 	struct lgs8gxx_state *priv = fe->demodulator_priv;
 
 	if (priv->config->prod == LGS8GXX_PROD_LGS8913)
 		return lgs8913_read_signal_strength(priv, signal);
+	else if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+		return lgs8g75_read_signal_strength(priv, signal);
 	else
 		return lgs8gxx_read_signal_agc(priv, signal);
 }
@@ -674,7 +921,10 @@ static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
 	u8 t;
 	*snr = 0;
 
-	lgs8gxx_read_reg(priv, 0x95, &t);
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
+		lgs8gxx_read_reg(priv, 0x34, &t);
+	else
+		lgs8gxx_read_reg(priv, 0x95, &t);
 	dprintk("AVG Noise=0x%02X\n", t);
 	*snr = 256 - t;
 	*snr <<= 8;
@@ -690,31 +940,68 @@ static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 	return 0;
 }
 
+static void packet_counter_start(struct lgs8gxx_state *priv)
+{
+	u8 orig, t;
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		lgs8gxx_read_reg(priv, 0x30, &orig);
+		orig &= 0xE7;
+		t = orig | 0x10;
+		lgs8gxx_write_reg(priv, 0x30, t);
+		t = orig | 0x18;
+		lgs8gxx_write_reg(priv, 0x30, t);
+		t = orig | 0x10;
+		lgs8gxx_write_reg(priv, 0x30, t);
+	} else {
+		lgs8gxx_write_reg(priv, 0xC6, 0x01);
+		lgs8gxx_write_reg(priv, 0xC6, 0x41);
+		lgs8gxx_write_reg(priv, 0xC6, 0x01);
+	}
+}
+
+static void packet_counter_stop(struct lgs8gxx_state *priv)
+{
+	u8 t;
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		lgs8gxx_read_reg(priv, 0x30, &t);
+		t &= 0xE7;
+		lgs8gxx_write_reg(priv, 0x30, t);
+	} else {
+		lgs8gxx_write_reg(priv, 0xC6, 0x81);
+	}
+}
+
 static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
 {
 	struct lgs8gxx_state *priv = fe->demodulator_priv;
-	u8 r0, r1, r2, r3;
-	u32 total_cnt, err_cnt;
+	u8 reg_err, reg_total, t;
+	u32 total_cnt = 0, err_cnt = 0;
+	int i;
 
 	dprintk("%s\n", __func__);
 
-	lgs8gxx_write_reg(priv, 0xc6, 0x01);
-	lgs8gxx_write_reg(priv, 0xc6, 0x41);
-	lgs8gxx_write_reg(priv, 0xc6, 0x01);
-
+	packet_counter_start(priv);
 	msleep(200);
+	packet_counter_stop(priv);
+
+	if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
+		reg_total = 0x28; reg_err = 0x2C;
+	} else {
+		reg_total = 0xD0; reg_err = 0xD4;
+	}
 
-	lgs8gxx_write_reg(priv, 0xc6, 0x81);
-	lgs8gxx_read_reg(priv, 0xd0, &r0);
-	lgs8gxx_read_reg(priv, 0xd1, &r1);
-	lgs8gxx_read_reg(priv, 0xd2, &r2);
-	lgs8gxx_read_reg(priv, 0xd3, &r3);
-	total_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0);
-	lgs8gxx_read_reg(priv, 0xd4, &r0);
-	lgs8gxx_read_reg(priv, 0xd5, &r1);
-	lgs8gxx_read_reg(priv, 0xd6, &r2);
-	lgs8gxx_read_reg(priv, 0xd7, &r3);
-	err_cnt = (r3 << 24) | (r2 << 16) | (r1 << 8) | (r0);
+	for (i = 0; i < 4; i++) {
+		total_cnt <<= 8;
+		lgs8gxx_read_reg(priv, reg_total+3-i, &t);
+		total_cnt |= t;
+	}
+	for (i = 0; i < 4; i++) {
+		err_cnt <<= 8;
+		lgs8gxx_read_reg(priv, reg_err+3-i, &t);
+		err_cnt |= t;
+	}
 	dprintk("error=%d total=%d\n", err_cnt, total_cnt);
 
 	if (total_cnt == 0)
@@ -801,6 +1088,9 @@ struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
 	       sizeof(struct dvb_frontend_ops));
 	priv->frontend.demodulator_priv = priv;
 
+	if (config->prod == LGS8GXX_PROD_LGS8G75)
+		lgs8g75_init_data(priv);
+
 	return &priv->frontend;
 
 error_out:
diff --git a/drivers/media/dvb/frontends/lgs8gxx.h b/drivers/media/dvb/frontends/lgs8gxx.h
index 321d366..33c3c5e 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.h
+++ b/drivers/media/dvb/frontends/lgs8gxx.h
@@ -1,9 +1,9 @@
 /*
- *    Support for Legend Silicon DMB-TH demodulator
- *    LGS8913, LGS8GL5
+ *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
+ *    LGS8913, LGS8GL5, LGS8G75
  *    experimental support LGS8G42, LGS8G52
  *
- *    Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
  *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
  *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
  *
@@ -34,6 +34,7 @@
 #define LGS8GXX_PROD_LGS8G42 3
 #define LGS8GXX_PROD_LGS8G52 4
 #define LGS8GXX_PROD_LGS8G54 5
+#define LGS8GXX_PROD_LGS8G75 6
 
 struct lgs8gxx_config {
 
@@ -70,6 +71,10 @@ struct lgs8gxx_config {
 	/*IF use Negative center frequency*/
 	u8 if_neg_center;
 
+	/*8G75 internal ADC input range selection*/
+	/*0: 0.8Vpp, 1: 1.0Vpp, 2: 1.6Vpp, 3: 2.0Vpp*/
+	u8 adc_vpp;
+
 	/* slave address and configuration of the tuner */
 	u8 tuner_address;
 };
diff --git a/drivers/media/dvb/frontends/lgs8gxx_priv.h b/drivers/media/dvb/frontends/lgs8gxx_priv.h
index 9776d30..8ef376f 100644
--- a/drivers/media/dvb/frontends/lgs8gxx_priv.h
+++ b/drivers/media/dvb/frontends/lgs8gxx_priv.h
@@ -1,9 +1,9 @@
 /*
- *    Support for Legend Silicon DMB-TH demodulator
- *    LGS8913, LGS8GL5
+ *    Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
+ *    LGS8913, LGS8GL5, LGS8G75
  *    experimental support LGS8G42, LGS8G52
  *
- *    Copyright (C) 2007,2008 David T.L. Wong <davidtlwong@gmail.com>
+ *    Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
  *    Copyright (C) 2008 Sirius International (Hong Kong) Limited
  *    Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
  *
@@ -38,7 +38,7 @@ struct lgs8gxx_state {
 #define SC_QAM64	0x10	/* 64QAM modulation */
 #define SC_QAM32	0x0C	/* 32QAM modulation */
 #define SC_QAM16	0x08	/* 16QAM modulation */
-#define SC_QAM4NR	0x04	/* 4QAM modulation */
+#define SC_QAM4NR	0x04	/* 4QAM-NR modulation */
 #define SC_QAM4		0x00	/* 4QAM modulation */
 
 #define LGS_FEC_MASK	0x03	/* FEC Rate Mask */
@@ -47,8 +47,8 @@ struct lgs8gxx_state {
 #define LGS_FEC_0_8	0x02	/* FEC Rate 0.8 */
 
 #define TIM_MASK	  0x20	/* Time Interleave Length Mask */
-#define TIM_LONG	  0x00	/* Time Interleave Length = 720 */
-#define TIM_MIDDLE     0x20   /* Time Interleave Length = 240 */
+#define TIM_LONG	  0x20	/* Time Interleave Length = 720 */
+#define TIM_MIDDLE     0x00   /* Time Interleave Length = 240 */
 
 #define CF_MASK	0x80	/* Control Frame Mask */
 #define CF_EN	0x80	/* Control Frame On */
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index f69daaa..472907d 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -85,7 +85,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
 		int i;
 		dprintk("R(%d):", reg & 0x7f);
 		for (i = 0; i < count; i++)
-			printk(" %02x", buf[i]);
+			printk(KERN_CONT " %02x", buf[i]);
 		printk("\n");
 	}
 
@@ -103,7 +103,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
 		int i;
 		dprintk("W(%d):", reg & 0x7f);
 		for (i = 0; i < count; i++)
-			printk(" %02x", src[i]);
+			printk(KERN_CONT " %02x", src[i]);
 		printk("\n");
 	}
 
@@ -744,7 +744,8 @@ static struct dvb_frontend_ops mt312_ops = {
 		.type = FE_QPSK,
 		.frequency_min = 950000,
 		.frequency_max = 2150000,
-		.frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, /* FIXME: adjust freq to real used xtal */
+		/* FIXME: adjust freq to real used xtal */
+		.frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
 		.symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */
 		.symbol_rate_max = MT312_SYS_CLK / 2,
 		.caps =
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
index 3f5a0e1..3156b64 100644
--- a/drivers/media/dvb/frontends/s921_module.c
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -169,6 +169,8 @@ struct dvb_frontend* s921_attach(const struct s921_config *config,
 
 	struct s921_state *state;
 	state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
+	if (state == NULL)
+		return NULL;
 
 	state->addr = config->i2c_address;
 	state->i2c = i2c;
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
index 1ed5a7d..60ee18a 100644
--- a/drivers/media/dvb/frontends/stb6100.c
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -367,7 +367,9 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
 	/* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1)))	*/
 	nint = fvco / (state->reference << psd2);
 	/* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9	*/
-	nfrac = (((fvco - (nint * state->reference << psd2)) << (9 - psd2)) + state->reference / 2) / state->reference;
+	nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
+					 << (9 - psd2),
+				  state->reference);
 	dprintk(verbose, FE_DEBUG, 1,
 		"frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
 		frequency, srate, (unsigned int)g, (unsigned int)odiv,
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 1da045f..3bde332 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -230,8 +230,8 @@ enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
 			stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
 			stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
 			stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
-			stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x24);
-			stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24);
+			stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x20);
+			stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x20);
 			stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
 			msleep(3);
 			stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
@@ -370,8 +370,8 @@ static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
 	u32 fi2c;
 
 	dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
-	if (enable)
-		stv0900_write_bits(i_params, fi2c, 1);
+
+	stv0900_write_bits(i_params, fi2c, enable);
 
 	return 0;
 }
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
index a5a3153..962fde1 100644
--- a/drivers/media/dvb/frontends/stv0900_sw.c
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -1721,7 +1721,7 @@ static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_front
 
 	s32 srate, demod_timeout,
 		fec_timeout, freq1, freq0;
-	enum fe_stv0900_signal_type signal_type = STV0900_NODATA;;
+	enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
 
 	switch (demod) {
 	case STV0900_DEMOD_1:
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
index 70efac8..dcf1b21 100644
--- a/drivers/media/dvb/frontends/stv6110.c
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -36,6 +36,7 @@ struct stv6110_priv {
 	struct i2c_adapter *i2c;
 
 	u32 mclk;
+	u8 clk_div;
 	u8 regs[8];
 };
 
@@ -100,35 +101,25 @@ static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
 	struct stv6110_priv *priv = fe->tuner_priv;
 	int rc;
 	u8 reg[] = { start };
-	struct i2c_msg msg_wr = {
-		.addr	= priv->i2c_address,
-		.flags	= 0,
-		.buf	= reg,
-		.len	= 1,
+	struct i2c_msg msg[] = {
+		{
+			.addr	= priv->i2c_address,
+			.flags	= 0,
+			.buf	= reg,
+			.len	= 1,
+		}, {
+			.addr	= priv->i2c_address,
+			.flags	= I2C_M_RD,
+			.buf	= regs,
+			.len	= len,
+		},
 	};
 
-	struct i2c_msg msg_rd = {
-		.addr	= priv->i2c_address,
-		.flags	= I2C_M_RD,
-		.buf	= regs,
-		.len	= len,
-	};
-	/* write subaddr */
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
-	rc = i2c_transfer(priv->i2c, &msg_wr, 1);
-	if (rc != 1)
-		dprintk("%s: i2c error\n", __func__);
-
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 0);
-	/* read registers */
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 1);
-
-	rc = i2c_transfer(priv->i2c, &msg_rd, 1);
-	if (rc != 1)
+	rc = i2c_transfer(priv->i2c, msg, 2);
+	if (rc != 2)
 		dprintk("%s: i2c error\n", __func__);
 
 	if (fe->ops.i2c_gate_ctrl)
@@ -221,6 +212,10 @@ static int stv6110_init(struct dvb_frontend *fe)
 	priv->regs[RSTV6110_CTRL1] |=
 				((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
 
+	/* divisor value for the output clock */
+	priv->regs[RSTV6110_CTRL2] &= ~0xc0;
+	priv->regs[RSTV6110_CTRL2] |= (priv->clk_div << 6);
+
 	stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
 	msleep(1);
 	stv6110_set_bandwidth(fe, 72000000);
@@ -418,6 +413,10 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
 	};
 	int ret;
 
+	/* divisor value for the output clock */
+	reg0[2] &= ~0xc0;
+	reg0[2] |= (config->clk_div << 6);
+
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
@@ -436,6 +435,7 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
 	priv->i2c_address = config->i2c_address;
 	priv->i2c = i2c;
 	priv->mclk = config->mclk;
+	priv->clk_div = config->clk_div;
 
 	memcpy(&priv->regs, &reg0[1], 8);
 
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
index 1c0314d..9db2402 100644
--- a/drivers/media/dvb/frontends/stv6110.h
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -41,7 +41,7 @@
 struct stv6110_config {
 	u8 i2c_address;
 	u32 mclk;
-	int iq_wiring;
+	u8 clk_div;	/* divisor value for the output clock */
 };
 
 #if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index f5d7b32..6c1dbf9 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -176,7 +176,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
 	tmp =  ((symbolrate << 4) % FIN) << 8;
 	ratio = (ratio << 8) + tmp / FIN;
 	tmp = (tmp % FIN) << 8;
-	ratio = (ratio << 8) + (tmp + FIN/2) / FIN;
+	ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, FIN);
 
 	BDR = ratio;
 	BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
index b6d1777..320c3c3 100644
--- a/drivers/media/dvb/frontends/tda8261.c
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -136,9 +136,9 @@ static int tda8261_set_state(struct dvb_frontend *fe,
 
 		if (frequency < 1450000)
 			buf[3] = 0x00;
-		if (frequency < 2000000)
+		else if (frequency < 2000000)
 			buf[3] = 0x40;
-		if (frequency < 2150000)
+		else if (frequency < 2150000)
 			buf[3] = 0x80;
 
 		/* Set params */
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index 6e78e48..550a07a 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -165,7 +165,7 @@ static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
 	tmp = ((symbolrate << 4) % fin) << 8;
 	ratio = (ratio << 8) + tmp / fin;
 	tmp = (tmp % fin) << 8;
-	ratio = (ratio << 8) + (tmp + fin / 2) / fin;
+	ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, fin);
 
 	BDR = ratio;
 	BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
index e22a0b3..4e814ff 100644
--- a/drivers/media/dvb/frontends/zl10036.c
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -29,7 +29,7 @@
 
 #include <linux/module.h>
 #include <linux/dvb/frontend.h>
-#include <asm/types.h>
+#include <linux/types.h>
 
 #include "zl10036.h"
 
diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb/frontends/zl10039.c
new file mode 100644
index 0000000..11b29cb
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10039.c
@@ -0,0 +1,308 @@
+/*
+ *  Driver for Zarlink ZL10039 DVB-S tuner
+ *
+ *  Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/dvb/frontend.h>
+
+#include "dvb_frontend.h"
+#include "zl10039.h"
+
+static int debug;
+
+#define dprintk(args...) \
+	do { \
+		if (debug) \
+			printk(KERN_DEBUG args); \
+	} while (0)
+
+enum zl10039_model_id {
+	ID_ZL10039 = 1
+};
+
+struct zl10039_state {
+	struct i2c_adapter *i2c;
+	u8 i2c_addr;
+	u8 id;
+};
+
+enum zl10039_reg_addr {
+	PLL0 = 0,
+	PLL1,
+	PLL2,
+	PLL3,
+	RFFE,
+	BASE0,
+	BASE1,
+	BASE2,
+	LO0,
+	LO1,
+	LO2,
+	LO3,
+	LO4,
+	LO5,
+	LO6,
+	GENERAL
+};
+
+static int zl10039_read(const struct zl10039_state *state,
+			const enum zl10039_reg_addr reg, u8 *buf,
+			const size_t count)
+{
+	u8 regbuf[] = { reg };
+	struct i2c_msg msg[] = {
+		{/* Write register address */
+			.addr = state->i2c_addr,
+			.flags = 0,
+			.buf = regbuf,
+			.len = 1,
+		}, {/* Read count bytes */
+			.addr = state->i2c_addr,
+			.flags = I2C_M_RD,
+			.buf = buf,
+			.len = count,
+		},
+	};
+
+	dprintk("%s\n", __func__);
+
+	if (i2c_transfer(state->i2c, msg, 2) != 2) {
+		dprintk("%s: i2c read error\n", __func__);
+		return -EREMOTEIO;
+	}
+
+	return 0; /* Success */
+}
+
+static int zl10039_write(struct zl10039_state *state,
+			const enum zl10039_reg_addr reg, const u8 *src,
+			const size_t count)
+{
+	u8 buf[count + 1];
+	struct i2c_msg msg = {
+		.addr = state->i2c_addr,
+		.flags = 0,
+		.buf = buf,
+		.len = count + 1,
+	};
+
+	dprintk("%s\n", __func__);
+	/* Write register address and data in one go */
+	buf[0] = reg;
+	memcpy(&buf[1], src, count);
+	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+		dprintk("%s: i2c write error\n", __func__);
+		return -EREMOTEIO;
+	}
+
+	return 0; /* Success */
+}
+
+static inline int zl10039_readreg(struct zl10039_state *state,
+				const enum zl10039_reg_addr reg, u8 *val)
+{
+	return zl10039_read(state, reg, val, 1);
+}
+
+static inline int zl10039_writereg(struct zl10039_state *state,
+				const enum zl10039_reg_addr reg,
+				const u8 val)
+{
+	return zl10039_write(state, reg, &val, 1);
+}
+
+static int zl10039_init(struct dvb_frontend *fe)
+{
+	struct zl10039_state *state = fe->tuner_priv;
+	int ret;
+
+	dprintk("%s\n", __func__);
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	/* Reset logic */
+	ret = zl10039_writereg(state, GENERAL, 0x40);
+	if (ret < 0) {
+		dprintk("Note: i2c write error normal when resetting the "
+			"tuner\n");
+	}
+	/* Wake up */
+	ret = zl10039_writereg(state, GENERAL, 0x01);
+	if (ret < 0) {
+		dprintk("Tuner power up failed\n");
+		return ret;
+	}
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
+static int zl10039_sleep(struct dvb_frontend *fe)
+{
+	struct zl10039_state *state = fe->tuner_priv;
+	int ret;
+
+	dprintk("%s\n", __func__);
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	ret = zl10039_writereg(state, GENERAL, 0x80);
+	if (ret < 0) {
+		dprintk("Tuner sleep failed\n");
+		return ret;
+	}
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	return 0;
+}
+
+static int zl10039_set_params(struct dvb_frontend *fe,
+			struct dvb_frontend_parameters *params)
+{
+	struct zl10039_state *state = fe->tuner_priv;
+	u8 buf[6];
+	u8 bf;
+	u32 fbw;
+	u32 div;
+	int ret;
+
+	dprintk("%s\n", __func__);
+	dprintk("Set frequency = %d, symbol rate = %d\n",
+			params->frequency, params->u.qpsk.symbol_rate);
+
+	/* Assumed 10.111 MHz crystal oscillator */
+	/* Cancelled num/den 80 to prevent overflow */
+	div = (params->frequency * 1000) / 126387;
+	fbw = (params->u.qpsk.symbol_rate * 27) / 32000;
+	/* Cancelled num/den 10 to prevent overflow */
+	bf = ((fbw * 5088) / 1011100) - 1;
+
+	/*PLL divider*/
+	buf[0] = (div >> 8) & 0x7f;
+	buf[1] = (div >> 0) & 0xff;
+	/*Reference divider*/
+	/* Select reference ratio of 80 */
+	buf[2] = 0x1D;
+	/*PLL test modes*/
+	buf[3] = 0x40;
+	/*RF Control register*/
+	buf[4] = 0x6E; /* Bypass enable */
+	/*Baseband filter cutoff */
+	buf[5] = bf;
+
+	/* Open i2c gate */
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	/* BR = 10, Enable filter adjustment */
+	ret = zl10039_writereg(state, BASE1, 0x0A);
+	if (ret < 0)
+		goto error;
+	/* Write new config values */
+	ret = zl10039_write(state, PLL0, buf, sizeof(buf));
+	if (ret < 0)
+		goto error;
+	/* BR = 10, Disable filter adjustment */
+	ret = zl10039_writereg(state, BASE1, 0x6A);
+	if (ret < 0)
+		goto error;
+
+	/* Close i2c gate */
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+	return 0;
+error:
+	dprintk("Error setting tuner\n");
+	return ret;
+}
+
+static int zl10039_release(struct dvb_frontend *fe)
+{
+	struct zl10039_state *state = fe->tuner_priv;
+
+	dprintk("%s\n", __func__);
+	kfree(state);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+
+static struct dvb_tuner_ops zl10039_ops = {
+	.release = zl10039_release,
+	.init = zl10039_init,
+	.sleep = zl10039_sleep,
+	.set_params = zl10039_set_params,
+};
+
+struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
+		u8 i2c_addr, struct i2c_adapter *i2c)
+{
+	struct zl10039_state *state = NULL;
+
+	dprintk("%s\n", __func__);
+	state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
+	if (state == NULL)
+		goto error;
+
+	state->i2c = i2c;
+	state->i2c_addr = i2c_addr;
+
+	/* Open i2c gate */
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+	/* check if this is a valid tuner */
+	if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
+		/* Close i2c gate */
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+		goto error;
+	}
+	/* Close i2c gate */
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0);
+
+	state->id = state->id & 0x0f;
+	switch (state->id) {
+	case ID_ZL10039:
+		strcpy(fe->ops.tuner_ops.info.name,
+			"Zarlink ZL10039 DVB-S tuner");
+		break;
+	default:
+		dprintk("Chip ID=%x does not match a known type\n", state->id);
+		break;
+		goto error;
+	}
+
+	memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
+	fe->tuner_priv = state;
+	dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
+	return fe;
+error:
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(zl10039_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
+MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10039.h b/drivers/media/dvb/frontends/zl10039.h
new file mode 100644
index 0000000..5eee7ea
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10039.h
@@ -0,0 +1,40 @@
+/*
+    Driver for Zarlink ZL10039 DVB-S tuner
+
+    Copyright (C) 2007 Jan D. Louw <jd.louw@mweb.co.za>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+    GNU 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 ZL10039_H
+#define ZL10039_H
+
+#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \
+	    && defined(MODULE))
+struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
+					u8 i2c_addr,
+					struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
+					u8 i2c_addr,
+					struct i2c_adapter *i2c)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif /* CONFIG_DVB_ZL10039 */
+
+#endif /* ZL10039_H */
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 66f5c1f..8c61271 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -38,6 +38,8 @@ struct zl10353_state {
 	struct zl10353_config config;
 
 	enum fe_bandwidth bandwidth;
+       u32 ucblocks;
+       u32 frequency;
 };
 
 static int debug;
@@ -199,6 +201,8 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
 	u16 tps = 0;
 	struct dvb_ofdm_parameters *op = &param->u.ofdm;
 
+       state->frequency = param->frequency;
+
 	zl10353_single_write(fe, RESET, 0x80);
 	udelay(200);
 	zl10353_single_write(fe, 0xEA, 0x01);
@@ -464,7 +468,7 @@ static int zl10353_get_parameters(struct dvb_frontend *fe,
 		break;
 	}
 
-	param->frequency = 0;
+       param->frequency = state->frequency;
 	op->bandwidth = state->bandwidth;
 	param->inversion = INVERSION_AUTO;
 
@@ -542,9 +546,13 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
 static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
 {
 	struct zl10353_state *state = fe->demodulator_priv;
+       u32 ubl = 0;
+
+       ubl = zl10353_read_register(state, RS_UBC_1) << 8 |
+	     zl10353_read_register(state, RS_UBC_0);
 
-	*ucblocks = zl10353_read_register(state, RS_UBC_1) << 8 |
-		    zl10353_read_register(state, RS_UBC_0);
+       state->ucblocks += ubl;
+       *ucblocks = state->ucblocks;
 
 	return 0;
 }
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 598eaf8..80d14a0 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -439,7 +439,7 @@ static inline u32 divide(u32 numerator, u32 denominator)
 	if (denominator == 0)
 		return ~0;
 
-	return (numerator + denominator / 2) / denominator;
+	return DIV_ROUND_CLOSEST(numerator, denominator);
 }
 
 /* LG Innotek TDTE-E001P (Infineon TUA6034) */
diff --git a/drivers/media/dvb/pt1/Kconfig b/drivers/media/dvb/pt1/Kconfig
new file mode 100644
index 0000000..24501d5
--- /dev/null
+++ b/drivers/media/dvb/pt1/Kconfig
@@ -0,0 +1,12 @@
+config DVB_PT1
+	tristate "PT1 cards"
+	depends on DVB_CORE && PCI && I2C
+	help
+	  Support for Earthsoft PT1 PCI cards.
+
+	  Since these cards have no MPEG decoder onboard, they transmit
+	  only compressed MPEG data over the PCI bus, so you need
+	  an external software decoder to watch TV on your computer.
+
+	  Say Y or M if you own such a device and want to use it.
+
diff --git a/drivers/media/dvb/pt1/Makefile b/drivers/media/dvb/pt1/Makefile
new file mode 100644
index 0000000..a66da17
--- /dev/null
+++ b/drivers/media/dvb/pt1/Makefile
@@ -0,0 +1,5 @@
+earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
+
+obj-$(CONFIG_DVB_PT1) += earth-pt1.o
+
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
new file mode 100644
index 0000000..8ffbcec
--- /dev/null
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -0,0 +1,1056 @@
+/*
+ * driver for Earthsoft PT1
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
+
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_net.h"
+#include "dvb_frontend.h"
+
+#include "va1j5jf8007t.h"
+#include "va1j5jf8007s.h"
+
+#define DRIVER_NAME "earth-pt1"
+
+#define PT1_PAGE_SHIFT 12
+#define PT1_PAGE_SIZE (1 << PT1_PAGE_SHIFT)
+#define PT1_NR_UPACKETS 1024
+#define PT1_NR_BUFS 511
+
+struct pt1_buffer_page {
+	__le32 upackets[PT1_NR_UPACKETS];
+};
+
+struct pt1_table_page {
+	__le32 next_pfn;
+	__le32 buf_pfns[PT1_NR_BUFS];
+};
+
+struct pt1_buffer {
+	struct pt1_buffer_page *page;
+	dma_addr_t addr;
+};
+
+struct pt1_table {
+	struct pt1_table_page *page;
+	dma_addr_t addr;
+	struct pt1_buffer bufs[PT1_NR_BUFS];
+};
+
+#define PT1_NR_ADAPS 4
+
+struct pt1_adapter;
+
+struct pt1 {
+	struct pci_dev *pdev;
+	void __iomem *regs;
+	struct i2c_adapter i2c_adap;
+	int i2c_running;
+	struct pt1_adapter *adaps[PT1_NR_ADAPS];
+	struct pt1_table *tables;
+	struct task_struct *kthread;
+};
+
+struct pt1_adapter {
+	struct pt1 *pt1;
+	int index;
+
+	u8 *buf;
+	int upacket_count;
+	int packet_count;
+
+	struct dvb_adapter adap;
+	struct dvb_demux demux;
+	int users;
+	struct dmxdev dmxdev;
+	struct dvb_net net;
+	struct dvb_frontend *fe;
+	int (*orig_set_voltage)(struct dvb_frontend *fe,
+				fe_sec_voltage_t voltage);
+};
+
+#define pt1_printk(level, pt1, format, arg...)	\
+	dev_printk(level, &(pt1)->pdev->dev, format, ##arg)
+
+static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data)
+{
+	writel(data, pt1->regs + reg * 4);
+}
+
+static u32 pt1_read_reg(struct pt1 *pt1, int reg)
+{
+	return readl(pt1->regs + reg * 4);
+}
+
+static int pt1_nr_tables = 64;
+module_param_named(nr_tables, pt1_nr_tables, int, 0);
+
+static void pt1_increment_table_count(struct pt1 *pt1)
+{
+	pt1_write_reg(pt1, 0, 0x00000020);
+}
+
+static void pt1_init_table_count(struct pt1 *pt1)
+{
+	pt1_write_reg(pt1, 0, 0x00000010);
+}
+
+static void pt1_register_tables(struct pt1 *pt1, u32 first_pfn)
+{
+	pt1_write_reg(pt1, 5, first_pfn);
+	pt1_write_reg(pt1, 0, 0x0c000040);
+}
+
+static void pt1_unregister_tables(struct pt1 *pt1)
+{
+	pt1_write_reg(pt1, 0, 0x08080000);
+}
+
+static int pt1_sync(struct pt1 *pt1)
+{
+	int i;
+	for (i = 0; i < 57; i++) {
+		if (pt1_read_reg(pt1, 0) & 0x20000000)
+			return 0;
+		pt1_write_reg(pt1, 0, 0x00000008);
+	}
+	pt1_printk(KERN_ERR, pt1, "could not sync\n");
+	return -EIO;
+}
+
+static u64 pt1_identify(struct pt1 *pt1)
+{
+	int i;
+	u64 id;
+	id = 0;
+	for (i = 0; i < 57; i++) {
+		id |= (u64)(pt1_read_reg(pt1, 0) >> 30 & 1) << i;
+		pt1_write_reg(pt1, 0, 0x00000008);
+	}
+	return id;
+}
+
+static int pt1_unlock(struct pt1 *pt1)
+{
+	int i;
+	pt1_write_reg(pt1, 0, 0x00000008);
+	for (i = 0; i < 3; i++) {
+		if (pt1_read_reg(pt1, 0) & 0x80000000)
+			return 0;
+		schedule_timeout_uninterruptible((HZ + 999) / 1000);
+	}
+	pt1_printk(KERN_ERR, pt1, "could not unlock\n");
+	return -EIO;
+}
+
+static int pt1_reset_pci(struct pt1 *pt1)
+{
+	int i;
+	pt1_write_reg(pt1, 0, 0x01010000);
+	pt1_write_reg(pt1, 0, 0x01000000);
+	for (i = 0; i < 10; i++) {
+		if (pt1_read_reg(pt1, 0) & 0x00000001)
+			return 0;
+		schedule_timeout_uninterruptible((HZ + 999) / 1000);
+	}
+	pt1_printk(KERN_ERR, pt1, "could not reset PCI\n");
+	return -EIO;
+}
+
+static int pt1_reset_ram(struct pt1 *pt1)
+{
+	int i;
+	pt1_write_reg(pt1, 0, 0x02020000);
+	pt1_write_reg(pt1, 0, 0x02000000);
+	for (i = 0; i < 10; i++) {
+		if (pt1_read_reg(pt1, 0) & 0x00000002)
+			return 0;
+		schedule_timeout_uninterruptible((HZ + 999) / 1000);
+	}
+	pt1_printk(KERN_ERR, pt1, "could not reset RAM\n");
+	return -EIO;
+}
+
+static int pt1_do_enable_ram(struct pt1 *pt1)
+{
+	int i, j;
+	u32 status;
+	status = pt1_read_reg(pt1, 0) & 0x00000004;
+	pt1_write_reg(pt1, 0, 0x00000002);
+	for (i = 0; i < 10; i++) {
+		for (j = 0; j < 1024; j++) {
+			if ((pt1_read_reg(pt1, 0) & 0x00000004) != status)
+				return 0;
+		}
+		schedule_timeout_uninterruptible((HZ + 999) / 1000);
+	}
+	pt1_printk(KERN_ERR, pt1, "could not enable RAM\n");
+	return -EIO;
+}
+
+static int pt1_enable_ram(struct pt1 *pt1)
+{
+	int i, ret;
+	schedule_timeout_uninterruptible((HZ + 999) / 1000);
+	for (i = 0; i < 10; i++) {
+		ret = pt1_do_enable_ram(pt1);
+		if (ret < 0)
+			return ret;
+	}
+	return 0;
+}
+
+static void pt1_disable_ram(struct pt1 *pt1)
+{
+	pt1_write_reg(pt1, 0, 0x0b0b0000);
+}
+
+static void pt1_set_stream(struct pt1 *pt1, int index, int enabled)
+{
+	pt1_write_reg(pt1, 2, 1 << (index + 8) | enabled << index);
+}
+
+static void pt1_init_streams(struct pt1 *pt1)
+{
+	int i;
+	for (i = 0; i < PT1_NR_ADAPS; i++)
+		pt1_set_stream(pt1, i, 0);
+}
+
+static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
+{
+	u32 upacket;
+	int i;
+	int index;
+	struct pt1_adapter *adap;
+	int offset;
+	u8 *buf;
+
+	if (!page->upackets[PT1_NR_UPACKETS - 1])
+		return 0;
+
+	for (i = 0; i < PT1_NR_UPACKETS; i++) {
+		upacket = le32_to_cpu(page->upackets[i]);
+		index = (upacket >> 29) - 1;
+		if (index < 0 || index >=  PT1_NR_ADAPS)
+			continue;
+
+		adap = pt1->adaps[index];
+		if (upacket >> 25 & 1)
+			adap->upacket_count = 0;
+		else if (!adap->upacket_count)
+			continue;
+
+		buf = adap->buf;
+		offset = adap->packet_count * 188 + adap->upacket_count * 3;
+		buf[offset] = upacket >> 16;
+		buf[offset + 1] = upacket >> 8;
+		if (adap->upacket_count != 62)
+			buf[offset + 2] = upacket;
+
+		if (++adap->upacket_count >= 63) {
+			adap->upacket_count = 0;
+			if (++adap->packet_count >= 21) {
+				dvb_dmx_swfilter_packets(&adap->demux, buf, 21);
+				adap->packet_count = 0;
+			}
+		}
+	}
+
+	page->upackets[PT1_NR_UPACKETS - 1] = 0;
+	return 1;
+}
+
+static int pt1_thread(void *data)
+{
+	struct pt1 *pt1;
+	int table_index;
+	int buf_index;
+	struct pt1_buffer_page *page;
+
+	pt1 = data;
+	set_freezable();
+
+	table_index = 0;
+	buf_index = 0;
+
+	while (!kthread_should_stop()) {
+		try_to_freeze();
+
+		page = pt1->tables[table_index].bufs[buf_index].page;
+		if (!pt1_filter(pt1, page)) {
+			schedule_timeout_interruptible((HZ + 999) / 1000);
+			continue;
+		}
+
+		if (++buf_index >= PT1_NR_BUFS) {
+			pt1_increment_table_count(pt1);
+			buf_index = 0;
+			if (++table_index >= pt1_nr_tables)
+				table_index = 0;
+		}
+	}
+
+	return 0;
+}
+
+static void pt1_free_page(struct pt1 *pt1, void *page, dma_addr_t addr)
+{
+	dma_free_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, page, addr);
+}
+
+static void *pt1_alloc_page(struct pt1 *pt1, dma_addr_t *addrp, u32 *pfnp)
+{
+	void *page;
+	dma_addr_t addr;
+
+	page = dma_alloc_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, &addr,
+				  GFP_KERNEL);
+	if (page == NULL)
+		return NULL;
+
+	BUG_ON(addr & (PT1_PAGE_SIZE - 1));
+	BUG_ON(addr >> PT1_PAGE_SHIFT >> 31 >> 1);
+
+	*addrp = addr;
+	*pfnp = addr >> PT1_PAGE_SHIFT;
+	return page;
+}
+
+static void pt1_cleanup_buffer(struct pt1 *pt1, struct pt1_buffer *buf)
+{
+	pt1_free_page(pt1, buf->page, buf->addr);
+}
+
+static int
+pt1_init_buffer(struct pt1 *pt1, struct pt1_buffer *buf,  u32 *pfnp)
+{
+	struct pt1_buffer_page *page;
+	dma_addr_t addr;
+
+	page = pt1_alloc_page(pt1, &addr, pfnp);
+	if (page == NULL)
+		return -ENOMEM;
+
+	page->upackets[PT1_NR_UPACKETS - 1] = 0;
+
+	buf->page = page;
+	buf->addr = addr;
+	return 0;
+}
+
+static void pt1_cleanup_table(struct pt1 *pt1, struct pt1_table *table)
+{
+	int i;
+
+	for (i = 0; i < PT1_NR_BUFS; i++)
+		pt1_cleanup_buffer(pt1, &table->bufs[i]);
+
+	pt1_free_page(pt1, table->page, table->addr);
+}
+
+static int
+pt1_init_table(struct pt1 *pt1, struct pt1_table *table, u32 *pfnp)
+{
+	struct pt1_table_page *page;
+	dma_addr_t addr;
+	int i, ret;
+	u32 buf_pfn;
+
+	page = pt1_alloc_page(pt1, &addr, pfnp);
+	if (page == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < PT1_NR_BUFS; i++) {
+		ret = pt1_init_buffer(pt1, &table->bufs[i], &buf_pfn);
+		if (ret < 0)
+			goto err;
+
+		page->buf_pfns[i] = cpu_to_le32(buf_pfn);
+	}
+
+	pt1_increment_table_count(pt1);
+	table->page = page;
+	table->addr = addr;
+	return 0;
+
+err:
+	while (i--)
+		pt1_cleanup_buffer(pt1, &table->bufs[i]);
+
+	pt1_free_page(pt1, page, addr);
+	return ret;
+}
+
+static void pt1_cleanup_tables(struct pt1 *pt1)
+{
+	struct pt1_table *tables;
+	int i;
+
+	tables = pt1->tables;
+	pt1_unregister_tables(pt1);
+
+	for (i = 0; i < pt1_nr_tables; i++)
+		pt1_cleanup_table(pt1, &tables[i]);
+
+	vfree(tables);
+}
+
+static int pt1_init_tables(struct pt1 *pt1)
+{
+	struct pt1_table *tables;
+	int i, ret;
+	u32 first_pfn, pfn;
+
+	tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables);
+	if (tables == NULL)
+		return -ENOMEM;
+
+	pt1_init_table_count(pt1);
+
+	i = 0;
+	if (pt1_nr_tables) {
+		ret = pt1_init_table(pt1, &tables[0], &first_pfn);
+		if (ret)
+			goto err;
+		i++;
+	}
+
+	while (i < pt1_nr_tables) {
+		ret = pt1_init_table(pt1, &tables[i], &pfn);
+		if (ret)
+			goto err;
+		tables[i - 1].page->next_pfn = cpu_to_le32(pfn);
+		i++;
+	}
+
+	tables[pt1_nr_tables - 1].page->next_pfn = cpu_to_le32(first_pfn);
+
+	pt1_register_tables(pt1, first_pfn);
+	pt1->tables = tables;
+	return 0;
+
+err:
+	while (i--)
+		pt1_cleanup_table(pt1, &tables[i]);
+
+	vfree(tables);
+	return ret;
+}
+
+static int pt1_start_feed(struct dvb_demux_feed *feed)
+{
+	struct pt1_adapter *adap;
+	adap = container_of(feed->demux, struct pt1_adapter, demux);
+	if (!adap->users++)
+		pt1_set_stream(adap->pt1, adap->index, 1);
+	return 0;
+}
+
+static int pt1_stop_feed(struct dvb_demux_feed *feed)
+{
+	struct pt1_adapter *adap;
+	adap = container_of(feed->demux, struct pt1_adapter, demux);
+	if (!--adap->users)
+		pt1_set_stream(adap->pt1, adap->index, 0);
+	return 0;
+}
+
+static void
+pt1_set_power(struct pt1 *pt1, int power, int lnb, int reset)
+{
+	pt1_write_reg(pt1, 1, power | lnb << 1 | !reset << 3);
+}
+
+static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+	struct pt1_adapter *adap;
+	int lnb;
+
+	adap = container_of(fe->dvb, struct pt1_adapter, adap);
+
+	switch (voltage) {
+	case SEC_VOLTAGE_13: /* actually 11V */
+		lnb = 2;
+		break;
+	case SEC_VOLTAGE_18: /* actually 15V */
+		lnb = 3;
+		break;
+	case SEC_VOLTAGE_OFF:
+		lnb = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	pt1_set_power(adap->pt1, 1, lnb, 0);
+
+	if (adap->orig_set_voltage)
+		return adap->orig_set_voltage(fe, voltage);
+	else
+		return 0;
+}
+
+static void pt1_free_adapter(struct pt1_adapter *adap)
+{
+	dvb_unregister_frontend(adap->fe);
+	dvb_net_release(&adap->net);
+	adap->demux.dmx.close(&adap->demux.dmx);
+	dvb_dmxdev_release(&adap->dmxdev);
+	dvb_dmx_release(&adap->demux);
+	dvb_unregister_adapter(&adap->adap);
+	free_page((unsigned long)adap->buf);
+	kfree(adap);
+}
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct pt1_adapter *
+pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe)
+{
+	struct pt1_adapter *adap;
+	void *buf;
+	struct dvb_adapter *dvb_adap;
+	struct dvb_demux *demux;
+	struct dmxdev *dmxdev;
+	int ret;
+
+	adap = kzalloc(sizeof(struct pt1_adapter), GFP_KERNEL);
+	if (!adap) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	adap->pt1 = pt1;
+
+	adap->orig_set_voltage = fe->ops.set_voltage;
+	fe->ops.set_voltage = pt1_set_voltage;
+
+	buf = (u8 *)__get_free_page(GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto err_kfree;
+	}
+
+	adap->buf = buf;
+	adap->upacket_count = 0;
+	adap->packet_count = 0;
+
+	dvb_adap = &adap->adap;
+	dvb_adap->priv = adap;
+	ret = dvb_register_adapter(dvb_adap, DRIVER_NAME, THIS_MODULE,
+				   &pt1->pdev->dev, adapter_nr);
+	if (ret < 0)
+		goto err_free_page;
+
+	demux = &adap->demux;
+	demux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+	demux->priv = adap;
+	demux->feednum = 256;
+	demux->filternum = 256;
+	demux->start_feed = pt1_start_feed;
+	demux->stop_feed = pt1_stop_feed;
+	demux->write_to_decoder = NULL;
+	ret = dvb_dmx_init(demux);
+	if (ret < 0)
+		goto err_unregister_adapter;
+
+	dmxdev = &adap->dmxdev;
+	dmxdev->filternum = 256;
+	dmxdev->demux = &demux->dmx;
+	dmxdev->capabilities = 0;
+	ret = dvb_dmxdev_init(dmxdev, dvb_adap);
+	if (ret < 0)
+		goto err_dmx_release;
+
+	dvb_net_init(dvb_adap, &adap->net, &demux->dmx);
+
+	ret = dvb_register_frontend(dvb_adap, fe);
+	if (ret < 0)
+		goto err_net_release;
+	adap->fe = fe;
+
+	return adap;
+
+err_net_release:
+	dvb_net_release(&adap->net);
+	adap->demux.dmx.close(&adap->demux.dmx);
+	dvb_dmxdev_release(&adap->dmxdev);
+err_dmx_release:
+	dvb_dmx_release(demux);
+err_unregister_adapter:
+	dvb_unregister_adapter(dvb_adap);
+err_free_page:
+	free_page((unsigned long)buf);
+err_kfree:
+	kfree(adap);
+err:
+	return ERR_PTR(ret);
+}
+
+static void pt1_cleanup_adapters(struct pt1 *pt1)
+{
+	int i;
+	for (i = 0; i < PT1_NR_ADAPS; i++)
+		pt1_free_adapter(pt1->adaps[i]);
+}
+
+struct pt1_config {
+	struct va1j5jf8007s_config va1j5jf8007s_config;
+	struct va1j5jf8007t_config va1j5jf8007t_config;
+};
+
+static const struct pt1_config pt1_configs[2] = {
+	{
+		{ .demod_address = 0x1b },
+		{ .demod_address = 0x1a },
+	}, {
+		{ .demod_address = 0x19 },
+		{ .demod_address = 0x18 },
+	},
+};
+
+static int pt1_init_adapters(struct pt1 *pt1)
+{
+	int i, j;
+	struct i2c_adapter *i2c_adap;
+	const struct pt1_config *config;
+	struct dvb_frontend *fe[4];
+	struct pt1_adapter *adap;
+	int ret;
+
+	i = 0;
+	j = 0;
+
+	i2c_adap = &pt1->i2c_adap;
+	do {
+		config = &pt1_configs[i / 2];
+
+		fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config,
+					    i2c_adap);
+		if (!fe[i]) {
+			ret = -ENODEV; /* This does not sound nice... */
+			goto err;
+		}
+		i++;
+
+		fe[i] = va1j5jf8007t_attach(&config->va1j5jf8007t_config,
+					    i2c_adap);
+		if (!fe[i]) {
+			ret = -ENODEV;
+			goto err;
+		}
+		i++;
+
+		ret = va1j5jf8007s_prepare(fe[i - 2]);
+		if (ret < 0)
+			goto err;
+
+		ret = va1j5jf8007t_prepare(fe[i - 1]);
+		if (ret < 0)
+			goto err;
+
+	} while (i < 4);
+
+	do {
+		adap = pt1_alloc_adapter(pt1, fe[j]);
+		if (IS_ERR(adap))
+			goto err;
+		adap->index = j;
+		pt1->adaps[j] = adap;
+	} while (++j < 4);
+
+	return 0;
+
+err:
+	while (i-- > j)
+		fe[i]->ops.release(fe[i]);
+
+	while (j--)
+		pt1_free_adapter(pt1->adaps[j]);
+
+	return ret;
+}
+
+static void pt1_i2c_emit(struct pt1 *pt1, int addr, int busy, int read_enable,
+			 int clock, int data, int next_addr)
+{
+	pt1_write_reg(pt1, 4, addr << 18 | busy << 13 | read_enable << 12 |
+		      !clock << 11 | !data << 10 | next_addr);
+}
+
+static void pt1_i2c_write_bit(struct pt1 *pt1, int addr, int *addrp, int data)
+{
+	pt1_i2c_emit(pt1, addr,     1, 0, 0, data, addr + 1);
+	pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, data, addr + 2);
+	pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, data, addr + 3);
+	*addrp = addr + 3;
+}
+
+static void pt1_i2c_read_bit(struct pt1 *pt1, int addr, int *addrp)
+{
+	pt1_i2c_emit(pt1, addr,     1, 0, 0, 1, addr + 1);
+	pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 1, addr + 2);
+	pt1_i2c_emit(pt1, addr + 2, 1, 1, 1, 1, addr + 3);
+	pt1_i2c_emit(pt1, addr + 3, 1, 0, 0, 1, addr + 4);
+	*addrp = addr + 4;
+}
+
+static void pt1_i2c_write_byte(struct pt1 *pt1, int addr, int *addrp, int data)
+{
+	int i;
+	for (i = 0; i < 8; i++)
+		pt1_i2c_write_bit(pt1, addr, &addr, data >> (7 - i) & 1);
+	pt1_i2c_write_bit(pt1, addr, &addr, 1);
+	*addrp = addr;
+}
+
+static void pt1_i2c_read_byte(struct pt1 *pt1, int addr, int *addrp, int last)
+{
+	int i;
+	for (i = 0; i < 8; i++)
+		pt1_i2c_read_bit(pt1, addr, &addr);
+	pt1_i2c_write_bit(pt1, addr, &addr, last);
+	*addrp = addr;
+}
+
+static void pt1_i2c_prepare(struct pt1 *pt1, int addr, int *addrp)
+{
+	pt1_i2c_emit(pt1, addr,     1, 0, 1, 1, addr + 1);
+	pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
+	pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, 0, addr + 3);
+	*addrp = addr + 3;
+}
+
+static void
+pt1_i2c_write_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
+{
+	int i;
+	pt1_i2c_prepare(pt1, addr, &addr);
+	pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1);
+	for (i = 0; i < msg->len; i++)
+		pt1_i2c_write_byte(pt1, addr, &addr, msg->buf[i]);
+	*addrp = addr;
+}
+
+static void
+pt1_i2c_read_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
+{
+	int i;
+	pt1_i2c_prepare(pt1, addr, &addr);
+	pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1 | 1);
+	for (i = 0; i < msg->len; i++)
+		pt1_i2c_read_byte(pt1, addr, &addr, i == msg->len - 1);
+	*addrp = addr;
+}
+
+static int pt1_i2c_end(struct pt1 *pt1, int addr)
+{
+	pt1_i2c_emit(pt1, addr,     1, 0, 0, 0, addr + 1);
+	pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
+	pt1_i2c_emit(pt1, addr + 2, 1, 0, 1, 1, 0);
+
+	pt1_write_reg(pt1, 0, 0x00000004);
+	do {
+		if (signal_pending(current))
+			return -EINTR;
+		schedule_timeout_interruptible((HZ + 999) / 1000);
+	} while (pt1_read_reg(pt1, 0) & 0x00000080);
+	return 0;
+}
+
+static void pt1_i2c_begin(struct pt1 *pt1, int *addrp)
+{
+	int addr;
+	addr = 0;
+
+	pt1_i2c_emit(pt1, addr,     0, 0, 1, 1, addr /* itself */);
+	addr = addr + 1;
+
+	if (!pt1->i2c_running) {
+		pt1_i2c_emit(pt1, addr,     1, 0, 1, 1, addr + 1);
+		pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
+		addr = addr + 2;
+		pt1->i2c_running = 1;
+	}
+	*addrp = addr;
+}
+
+static int pt1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct pt1 *pt1;
+	int i;
+	struct i2c_msg *msg, *next_msg;
+	int addr, ret;
+	u16 len;
+	u32 word;
+
+	pt1 = i2c_get_adapdata(adap);
+
+	for (i = 0; i < num; i++) {
+		msg = &msgs[i];
+		if (msg->flags & I2C_M_RD)
+			return -ENOTSUPP;
+
+		if (i + 1 < num)
+			next_msg = &msgs[i + 1];
+		else
+			next_msg = NULL;
+
+		if (next_msg && next_msg->flags & I2C_M_RD) {
+			i++;
+
+			len = next_msg->len;
+			if (len > 4)
+				return -ENOTSUPP;
+
+			pt1_i2c_begin(pt1, &addr);
+			pt1_i2c_write_msg(pt1, addr, &addr, msg);
+			pt1_i2c_read_msg(pt1, addr, &addr, next_msg);
+			ret = pt1_i2c_end(pt1, addr);
+			if (ret < 0)
+				return ret;
+
+			word = pt1_read_reg(pt1, 2);
+			while (len--) {
+				next_msg->buf[len] = word;
+				word >>= 8;
+			}
+		} else {
+			pt1_i2c_begin(pt1, &addr);
+			pt1_i2c_write_msg(pt1, addr, &addr, msg);
+			ret = pt1_i2c_end(pt1, addr);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return num;
+}
+
+static u32 pt1_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C;
+}
+
+static const struct i2c_algorithm pt1_i2c_algo = {
+	.master_xfer = pt1_i2c_xfer,
+	.functionality = pt1_i2c_func,
+};
+
+static void pt1_i2c_wait(struct pt1 *pt1)
+{
+	int i;
+	for (i = 0; i < 128; i++)
+		pt1_i2c_emit(pt1, 0, 0, 0, 1, 1, 0);
+}
+
+static void pt1_i2c_init(struct pt1 *pt1)
+{
+	int i;
+	for (i = 0; i < 1024; i++)
+		pt1_i2c_emit(pt1, i, 0, 0, 1, 1, 0);
+}
+
+static void __devexit pt1_remove(struct pci_dev *pdev)
+{
+	struct pt1 *pt1;
+	void __iomem *regs;
+
+	pt1 = pci_get_drvdata(pdev);
+	regs = pt1->regs;
+
+	kthread_stop(pt1->kthread);
+	pt1_cleanup_tables(pt1);
+	pt1_cleanup_adapters(pt1);
+	pt1_disable_ram(pt1);
+	pt1_set_power(pt1, 0, 0, 1);
+	i2c_del_adapter(&pt1->i2c_adap);
+	pci_set_drvdata(pdev, NULL);
+	kfree(pt1);
+	pci_iounmap(pdev, regs);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+static int __devinit
+pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int ret;
+	void __iomem *regs;
+	struct pt1 *pt1;
+	struct i2c_adapter *i2c_adap;
+	struct task_struct *kthread;
+
+	ret = pci_enable_device(pdev);
+	if (ret < 0)
+		goto err;
+
+	ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+	if (ret < 0)
+		goto err_pci_disable_device;
+
+	pci_set_master(pdev);
+
+	ret = pci_request_regions(pdev, DRIVER_NAME);
+	if (ret < 0)
+		goto err_pci_disable_device;
+
+	regs = pci_iomap(pdev, 0, 0);
+	if (!regs) {
+		ret = -EIO;
+		goto err_pci_release_regions;
+	}
+
+	pt1 = kzalloc(sizeof(struct pt1), GFP_KERNEL);
+	if (!pt1) {
+		ret = -ENOMEM;
+		goto err_pci_iounmap;
+	}
+
+	pt1->pdev = pdev;
+	pt1->regs = regs;
+	pci_set_drvdata(pdev, pt1);
+
+	i2c_adap = &pt1->i2c_adap;
+	i2c_adap->class = I2C_CLASS_TV_DIGITAL;
+	i2c_adap->algo = &pt1_i2c_algo;
+	i2c_adap->algo_data = NULL;
+	i2c_adap->dev.parent = &pdev->dev;
+	i2c_set_adapdata(i2c_adap, pt1);
+	ret = i2c_add_adapter(i2c_adap);
+	if (ret < 0)
+		goto err_kfree;
+
+	pt1_set_power(pt1, 0, 0, 1);
+
+	pt1_i2c_init(pt1);
+	pt1_i2c_wait(pt1);
+
+	ret = pt1_sync(pt1);
+	if (ret < 0)
+		goto err_i2c_del_adapter;
+
+	pt1_identify(pt1);
+
+	ret = pt1_unlock(pt1);
+	if (ret < 0)
+		goto err_i2c_del_adapter;
+
+	ret = pt1_reset_pci(pt1);
+	if (ret < 0)
+		goto err_i2c_del_adapter;
+
+	ret = pt1_reset_ram(pt1);
+	if (ret < 0)
+		goto err_i2c_del_adapter;
+
+	ret = pt1_enable_ram(pt1);
+	if (ret < 0)
+		goto err_i2c_del_adapter;
+
+	pt1_init_streams(pt1);
+
+	pt1_set_power(pt1, 1, 0, 1);
+	schedule_timeout_uninterruptible((HZ + 49) / 50);
+
+	pt1_set_power(pt1, 1, 0, 0);
+	schedule_timeout_uninterruptible((HZ + 999) / 1000);
+
+	ret = pt1_init_adapters(pt1);
+	if (ret < 0)
+		goto err_pt1_disable_ram;
+
+	ret = pt1_init_tables(pt1);
+	if (ret < 0)
+		goto err_pt1_cleanup_adapters;
+
+	kthread = kthread_run(pt1_thread, pt1, "pt1");
+	if (IS_ERR(kthread)) {
+		ret = PTR_ERR(kthread);
+		goto err_pt1_cleanup_tables;
+	}
+
+	pt1->kthread = kthread;
+	return 0;
+
+err_pt1_cleanup_tables:
+	pt1_cleanup_tables(pt1);
+err_pt1_cleanup_adapters:
+	pt1_cleanup_adapters(pt1);
+err_pt1_disable_ram:
+	pt1_disable_ram(pt1);
+	pt1_set_power(pt1, 0, 0, 1);
+err_i2c_del_adapter:
+	i2c_del_adapter(i2c_adap);
+err_kfree:
+	pci_set_drvdata(pdev, NULL);
+	kfree(pt1);
+err_pci_iounmap:
+	pci_iounmap(pdev, regs);
+err_pci_release_regions:
+	pci_release_regions(pdev);
+err_pci_disable_device:
+	pci_disable_device(pdev);
+err:
+	return ret;
+
+}
+
+static struct pci_device_id pt1_id_table[] = {
+	{ PCI_DEVICE(0x10ee, 0x211a) },
+	{ },
+};
+MODULE_DEVICE_TABLE(pci, pt1_id_table);
+
+static struct pci_driver pt1_driver = {
+	.name		= DRIVER_NAME,
+	.probe		= pt1_probe,
+	.remove		= __devexit_p(pt1_remove),
+	.id_table	= pt1_id_table,
+};
+
+
+static int __init pt1_init(void)
+{
+	return pci_register_driver(&pt1_driver);
+}
+
+
+static void __exit pt1_cleanup(void)
+{
+	pci_unregister_driver(&pt1_driver);
+}
+
+module_init(pt1_init);
+module_exit(pt1_cleanup);
+
+MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
+MODULE_DESCRIPTION("Earthsoft PT1 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c
new file mode 100644
index 0000000..2db940f
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.c
@@ -0,0 +1,658 @@
+/*
+ * ISDB-S driver for VA1J5JF8007
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "va1j5jf8007s.h"
+
+enum va1j5jf8007s_tune_state {
+	VA1J5JF8007S_IDLE,
+	VA1J5JF8007S_SET_FREQUENCY_1,
+	VA1J5JF8007S_SET_FREQUENCY_2,
+	VA1J5JF8007S_SET_FREQUENCY_3,
+	VA1J5JF8007S_CHECK_FREQUENCY,
+	VA1J5JF8007S_SET_MODULATION,
+	VA1J5JF8007S_CHECK_MODULATION,
+	VA1J5JF8007S_SET_TS_ID,
+	VA1J5JF8007S_CHECK_TS_ID,
+	VA1J5JF8007S_TRACK,
+};
+
+struct va1j5jf8007s_state {
+	const struct va1j5jf8007s_config *config;
+	struct i2c_adapter *adap;
+	struct dvb_frontend fe;
+	enum va1j5jf8007s_tune_state tune_state;
+};
+
+static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_HW;
+}
+
+static int
+va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct va1j5jf8007s_state *state;
+
+	state = fe->demodulator_priv;
+
+	switch (state->tune_state) {
+	case VA1J5JF8007S_IDLE:
+	case VA1J5JF8007S_SET_FREQUENCY_1:
+	case VA1J5JF8007S_SET_FREQUENCY_2:
+	case VA1J5JF8007S_SET_FREQUENCY_3:
+	case VA1J5JF8007S_CHECK_FREQUENCY:
+		*status = 0;
+		return 0;
+
+
+	case VA1J5JF8007S_SET_MODULATION:
+	case VA1J5JF8007S_CHECK_MODULATION:
+		*status |= FE_HAS_SIGNAL;
+		return 0;
+
+	case VA1J5JF8007S_SET_TS_ID:
+	case VA1J5JF8007S_CHECK_TS_ID:
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+		return 0;
+
+	case VA1J5JF8007S_TRACK:
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+		return 0;
+	}
+
+	BUG();
+}
+
+struct va1j5jf8007s_cb_map {
+	u32 frequency;
+	u8 cb;
+};
+
+static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = {
+	{  986000, 0xb2 },
+	{ 1072000, 0xd2 },
+	{ 1154000, 0xe2 },
+	{ 1291000, 0x20 },
+	{ 1447000, 0x40 },
+	{ 1615000, 0x60 },
+	{ 1791000, 0x80 },
+	{ 1972000, 0xa0 },
+};
+
+static u8 va1j5jf8007s_lookup_cb(u32 frequency)
+{
+	int i;
+	const struct va1j5jf8007s_cb_map *map;
+
+	for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) {
+		map = &va1j5jf8007s_cb_maps[i];
+		if (frequency < map->frequency)
+			return map->cb;
+	}
+	return 0xc0;
+}
+
+static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state)
+{
+	u32 frequency;
+	u16 word;
+	u8 buf[6];
+	struct i2c_msg msg;
+
+	frequency = state->fe.dtv_property_cache.frequency;
+
+	word = (frequency + 500) / 1000;
+	if (frequency < 1072000)
+		word = (word << 1 & ~0x1f) | (word & 0x0f);
+
+	buf[0] = 0xfe;
+	buf[1] = 0xc0;
+	buf[2] = 0x40 | word >> 8;
+	buf[3] = word;
+	buf[4] = 0xe0;
+	buf[5] = va1j5jf8007s_lookup_cb(frequency);
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state)
+{
+	u8 buf[3];
+	struct i2c_msg msg;
+
+	buf[0] = 0xfe;
+	buf[1] = 0xc0;
+	buf[2] = 0xe4;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state)
+{
+	u32 frequency;
+	u8 buf[4];
+	struct i2c_msg msg;
+
+	frequency = state->fe.dtv_property_cache.frequency;
+
+	buf[0] = 0xfe;
+	buf[1] = 0xc0;
+	buf[2] = 0xf4;
+	buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int
+va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock)
+{
+	u8 addr;
+	u8 write_buf[2], read_buf[1];
+	struct i2c_msg msgs[2];
+
+	addr = state->config->demod_address;
+
+	write_buf[0] = 0xfe;
+	write_buf[1] = 0xc1;
+
+	msgs[0].addr = addr;
+	msgs[0].flags = 0;
+	msgs[0].len = sizeof(write_buf);
+	msgs[0].buf = write_buf;
+
+	msgs[1].addr = addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = sizeof(read_buf);
+	msgs[1].buf = read_buf;
+
+	if (i2c_transfer(state->adap, msgs, 2) != 2)
+		return -EREMOTEIO;
+
+	*lock = read_buf[0] & 0x40;
+	return 0;
+}
+
+static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state)
+{
+	u8 buf[2];
+	struct i2c_msg msg;
+
+	buf[0] = 0x03;
+	buf[1] = 0x01;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int
+va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock)
+{
+	u8 addr;
+	u8 write_buf[1], read_buf[1];
+	struct i2c_msg msgs[2];
+
+	addr = state->config->demod_address;
+
+	write_buf[0] = 0xc3;
+
+	msgs[0].addr = addr;
+	msgs[0].flags = 0;
+	msgs[0].len = sizeof(write_buf);
+	msgs[0].buf = write_buf;
+
+	msgs[1].addr = addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = sizeof(read_buf);
+	msgs[1].buf = read_buf;
+
+	if (i2c_transfer(state->adap, msgs, 2) != 2)
+		return -EREMOTEIO;
+
+	*lock = !(read_buf[0] & 0x10);
+	return 0;
+}
+
+static int
+va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
+{
+	u32 ts_id;
+	u8 buf[3];
+	struct i2c_msg msg;
+
+	ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
+	if (!ts_id)
+		return 0;
+
+	buf[0] = 0x8f;
+	buf[1] = ts_id >> 8;
+	buf[2] = ts_id;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int
+va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
+{
+	u8 addr;
+	u8 write_buf[1], read_buf[2];
+	struct i2c_msg msgs[2];
+	u32 ts_id;
+
+	ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
+	if (!ts_id) {
+		*lock = 1;
+		return 0;
+	}
+
+	addr = state->config->demod_address;
+
+	write_buf[0] = 0xe6;
+
+	msgs[0].addr = addr;
+	msgs[0].flags = 0;
+	msgs[0].len = sizeof(write_buf);
+	msgs[0].buf = write_buf;
+
+	msgs[1].addr = addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = sizeof(read_buf);
+	msgs[1].buf = read_buf;
+
+	if (i2c_transfer(state->adap, msgs, 2) != 2)
+		return -EREMOTEIO;
+
+	*lock = (read_buf[0] << 8 | read_buf[1]) == ts_id;
+	return 0;
+}
+
+static int
+va1j5jf8007s_tune(struct dvb_frontend *fe,
+		  struct dvb_frontend_parameters *params,
+		  unsigned int mode_flags,  unsigned int *delay,
+		  fe_status_t *status)
+{
+	struct va1j5jf8007s_state *state;
+	int ret;
+	int lock;
+
+	state = fe->demodulator_priv;
+
+	if (params != NULL)
+		state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1;
+
+	switch (state->tune_state) {
+	case VA1J5JF8007S_IDLE:
+		*delay = 3 * HZ;
+		*status = 0;
+		return 0;
+
+	case VA1J5JF8007S_SET_FREQUENCY_1:
+		ret = va1j5jf8007s_set_frequency_1(state);
+		if (ret < 0)
+			return ret;
+
+		state->tune_state = VA1J5JF8007S_SET_FREQUENCY_2;
+		*delay = 0;
+		*status = 0;
+		return 0;
+
+	case VA1J5JF8007S_SET_FREQUENCY_2:
+		ret = va1j5jf8007s_set_frequency_2(state);
+		if (ret < 0)
+			return ret;
+
+		state->tune_state = VA1J5JF8007S_SET_FREQUENCY_3;
+		*delay = (HZ + 99) / 100;
+		*status = 0;
+		return 0;
+
+	case VA1J5JF8007S_SET_FREQUENCY_3:
+		ret = va1j5jf8007s_set_frequency_3(state);
+		if (ret < 0)
+			return ret;
+
+		state->tune_state = VA1J5JF8007S_CHECK_FREQUENCY;
+		*delay = 0;
+		*status = 0;
+		return 0;
+
+	case VA1J5JF8007S_CHECK_FREQUENCY:
+		ret = va1j5jf8007s_check_frequency(state, &lock);
+		if (ret < 0)
+			return ret;
+
+		if (!lock)  {
+			*delay = (HZ + 999) / 1000;
+			*status = 0;
+			return 0;
+		}
+
+		state->tune_state = VA1J5JF8007S_SET_MODULATION;
+		*delay = 0;
+		*status = FE_HAS_SIGNAL;
+		return 0;
+
+	case VA1J5JF8007S_SET_MODULATION:
+		ret = va1j5jf8007s_set_modulation(state);
+		if (ret < 0)
+			return ret;
+
+		state->tune_state = VA1J5JF8007S_CHECK_MODULATION;
+		*delay = 0;
+		*status = FE_HAS_SIGNAL;
+		return 0;
+
+	case VA1J5JF8007S_CHECK_MODULATION:
+		ret = va1j5jf8007s_check_modulation(state, &lock);
+		if (ret < 0)
+			return ret;
+
+		if (!lock)  {
+			*delay = (HZ + 49) / 50;
+			*status = FE_HAS_SIGNAL;
+			return 0;
+		}
+
+		state->tune_state = VA1J5JF8007S_SET_TS_ID;
+		*delay = 0;
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+		return 0;
+
+	case VA1J5JF8007S_SET_TS_ID:
+		ret = va1j5jf8007s_set_ts_id(state);
+		if (ret < 0)
+			return ret;
+
+		state->tune_state = VA1J5JF8007S_CHECK_TS_ID;
+		return 0;
+
+	case VA1J5JF8007S_CHECK_TS_ID:
+		ret = va1j5jf8007s_check_ts_id(state, &lock);
+		if (ret < 0)
+			return ret;
+
+		if (!lock)  {
+			*delay = (HZ + 99) / 100;
+			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
+			return 0;
+		}
+
+		state->tune_state = VA1J5JF8007S_TRACK;
+		/* fall through */
+
+	case VA1J5JF8007S_TRACK:
+		*delay = 3 * HZ;
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+		return 0;
+	}
+
+	BUG();
+}
+
+static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state)
+{
+	u8 buf[4];
+	struct i2c_msg msg;
+
+	buf[0] = 0xfe;
+	buf[1] = 0xc0;
+	buf[2] = 0xf0;
+	buf[3] = 0x04;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep)
+{
+	u8 buf[2];
+	struct i2c_msg msg;
+
+	buf[0] = 0x17;
+	buf[1] = sleep ? 0x01 : 0x00;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int va1j5jf8007s_sleep(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007s_state *state;
+	int ret;
+
+	state = fe->demodulator_priv;
+
+	ret = va1j5jf8007s_init_frequency(state);
+	if (ret < 0)
+		return ret;
+
+	return va1j5jf8007s_set_sleep(state, 1);
+}
+
+static int va1j5jf8007s_init(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007s_state *state;
+
+	state = fe->demodulator_priv;
+	state->tune_state = VA1J5JF8007S_IDLE;
+
+	return va1j5jf8007s_set_sleep(state, 0);
+}
+
+static void va1j5jf8007s_release(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007s_state *state;
+	state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops va1j5jf8007s_ops = {
+	.info = {
+		.name = "VA1J5JF8007 ISDB-S",
+		.type = FE_QPSK,
+		.frequency_min = 950000,
+		.frequency_max = 2150000,
+		.frequency_stepsize = 1000,
+		.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.get_frontend_algo = va1j5jf8007s_get_frontend_algo,
+	.read_status = va1j5jf8007s_read_status,
+	.tune = va1j5jf8007s_tune,
+	.sleep = va1j5jf8007s_sleep,
+	.init = va1j5jf8007s_init,
+	.release = va1j5jf8007s_release,
+};
+
+static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
+{
+	u8 addr;
+	u8 write_buf[1], read_buf[1];
+	struct i2c_msg msgs[2];
+
+	addr = state->config->demod_address;
+
+	write_buf[0] = 0x07;
+
+	msgs[0].addr = addr;
+	msgs[0].flags = 0;
+	msgs[0].len = sizeof(write_buf);
+	msgs[0].buf = write_buf;
+
+	msgs[1].addr = addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = sizeof(read_buf);
+	msgs[1].buf = read_buf;
+
+	if (i2c_transfer(state->adap, msgs, 2) != 2)
+		return -EREMOTEIO;
+
+	if (read_buf[0] != 0x41)
+		return -EIO;
+
+	return 0;
+}
+
+static const u8 va1j5jf8007s_prepare_bufs[][2] = {
+	{0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
+	{0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
+	{0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
+	{0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
+};
+
+static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
+{
+	u8 addr;
+	u8 buf[2];
+	struct i2c_msg msg;
+	int i;
+
+	addr = state->config->demod_address;
+
+	msg.addr = addr;
+	msg.flags = 0;
+	msg.len = 2;
+	msg.buf = buf;
+	for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_prepare_bufs); i++) {
+		memcpy(buf, va1j5jf8007s_prepare_bufs[i], sizeof(buf));
+		if (i2c_transfer(state->adap, &msg, 1) != 1)
+			return -EREMOTEIO;
+	}
+
+	return 0;
+}
+
+/* must be called after va1j5jf8007t_attach */
+int va1j5jf8007s_prepare(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007s_state *state;
+	int ret;
+
+	state = fe->demodulator_priv;
+
+	ret = va1j5jf8007s_prepare_1(state);
+	if (ret < 0)
+		return ret;
+
+	ret = va1j5jf8007s_prepare_2(state);
+	if (ret < 0)
+		return ret;
+
+	return va1j5jf8007s_init_frequency(state);
+}
+
+struct dvb_frontend *
+va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
+		    struct i2c_adapter *adap)
+{
+	struct va1j5jf8007s_state *state;
+	struct dvb_frontend *fe;
+	u8 buf[2];
+	struct i2c_msg msg;
+
+	state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	state->config = config;
+	state->adap = adap;
+
+	fe = &state->fe;
+	memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops));
+	fe->demodulator_priv = state;
+
+	buf[0] = 0x01;
+	buf[1] = 0x80;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1) {
+		kfree(state);
+		return NULL;
+	}
+
+	return fe;
+}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/dvb/pt1/va1j5jf8007s.h
new file mode 100644
index 0000000..aa228a8
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.h
@@ -0,0 +1,40 @@
+/*
+ * ISDB-S driver for VA1J5JF8007
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 VA1J5JF8007S_H
+#define VA1J5JF8007S_H
+
+struct va1j5jf8007s_config {
+	u8 demod_address;
+};
+
+struct i2c_adapter;
+
+struct dvb_frontend *
+va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
+		    struct i2c_adapter *adap);
+
+/* must be called after va1j5jf8007t_attach */
+int va1j5jf8007s_prepare(struct dvb_frontend *fe);
+
+#endif
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c
new file mode 100644
index 0000000..71117f4
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.c
@@ -0,0 +1,468 @@
+/*
+ * ISDB-T driver for VA1J5JF8007
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "va1j5jf8007t.h"
+
+enum va1j5jf8007t_tune_state {
+	VA1J5JF8007T_IDLE,
+	VA1J5JF8007T_SET_FREQUENCY,
+	VA1J5JF8007T_CHECK_FREQUENCY,
+	VA1J5JF8007T_SET_MODULATION,
+	VA1J5JF8007T_CHECK_MODULATION,
+	VA1J5JF8007T_TRACK,
+	VA1J5JF8007T_ABORT,
+};
+
+struct va1j5jf8007t_state {
+	const struct va1j5jf8007t_config *config;
+	struct i2c_adapter *adap;
+	struct dvb_frontend fe;
+	enum va1j5jf8007t_tune_state tune_state;
+};
+
+static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_HW;
+}
+
+static int
+va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct va1j5jf8007t_state *state;
+
+	state = fe->demodulator_priv;
+
+	switch (state->tune_state) {
+	case VA1J5JF8007T_IDLE:
+	case VA1J5JF8007T_SET_FREQUENCY:
+	case VA1J5JF8007T_CHECK_FREQUENCY:
+		*status = 0;
+		return 0;
+
+
+	case VA1J5JF8007T_SET_MODULATION:
+	case VA1J5JF8007T_CHECK_MODULATION:
+	case VA1J5JF8007T_ABORT:
+		*status |= FE_HAS_SIGNAL;
+		return 0;
+
+	case VA1J5JF8007T_TRACK:
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+		return 0;
+	}
+
+	BUG();
+}
+
+struct va1j5jf8007t_cb_map {
+	u32 frequency;
+	u8 cb;
+};
+
+static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = {
+	{  90000000, 0x80 },
+	{ 140000000, 0x81 },
+	{ 170000000, 0xa1 },
+	{ 220000000, 0x62 },
+	{ 330000000, 0xa2 },
+	{ 402000000, 0xe2 },
+	{ 450000000, 0x64 },
+	{ 550000000, 0x84 },
+	{ 600000000, 0xa4 },
+	{ 700000000, 0xc4 },
+};
+
+static u8 va1j5jf8007t_lookup_cb(u32 frequency)
+{
+	int i;
+	const struct va1j5jf8007t_cb_map *map;
+
+	for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) {
+		map = &va1j5jf8007t_cb_maps[i];
+		if (frequency < map->frequency)
+			return map->cb;
+	}
+	return 0xe4;
+}
+
+static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state)
+{
+	u32 frequency;
+	u16 word;
+	u8 buf[6];
+	struct i2c_msg msg;
+
+	frequency = state->fe.dtv_property_cache.frequency;
+
+	word = (frequency + 71428) / 142857 + 399;
+	buf[0] = 0xfe;
+	buf[1] = 0xc2;
+	buf[2] = word >> 8;
+	buf[3] = word;
+	buf[4] = 0x80;
+	buf[5] = va1j5jf8007t_lookup_cb(frequency);
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int
+va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock)
+{
+	u8 addr;
+	u8 write_buf[2], read_buf[1];
+	struct i2c_msg msgs[2];
+
+	addr = state->config->demod_address;
+
+	write_buf[0] = 0xfe;
+	write_buf[1] = 0xc3;
+
+	msgs[0].addr = addr;
+	msgs[0].flags = 0;
+	msgs[0].len = sizeof(write_buf);
+	msgs[0].buf = write_buf;
+
+	msgs[1].addr = addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = sizeof(read_buf);
+	msgs[1].buf = read_buf;
+
+	if (i2c_transfer(state->adap, msgs, 2) != 2)
+		return -EREMOTEIO;
+
+	*lock = read_buf[0] & 0x40;
+	return 0;
+}
+
+static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state)
+{
+	u8 buf[2];
+	struct i2c_msg msg;
+
+	buf[0] = 0x01;
+	buf[1] = 0x40;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state,
+					 int *lock, int *retry)
+{
+	u8 addr;
+	u8 write_buf[1], read_buf[1];
+	struct i2c_msg msgs[2];
+
+	addr = state->config->demod_address;
+
+	write_buf[0] = 0x80;
+
+	msgs[0].addr = addr;
+	msgs[0].flags = 0;
+	msgs[0].len = sizeof(write_buf);
+	msgs[0].buf = write_buf;
+
+	msgs[1].addr = addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = sizeof(read_buf);
+	msgs[1].buf = read_buf;
+
+	if (i2c_transfer(state->adap, msgs, 2) != 2)
+		return -EREMOTEIO;
+
+	*lock = !(read_buf[0] & 0x10);
+	*retry = read_buf[0] & 0x80;
+	return 0;
+}
+
+static int
+va1j5jf8007t_tune(struct dvb_frontend *fe,
+		  struct dvb_frontend_parameters *params,
+		  unsigned int mode_flags,  unsigned int *delay,
+		  fe_status_t *status)
+{
+	struct va1j5jf8007t_state *state;
+	int ret;
+	int lock, retry;
+
+	state = fe->demodulator_priv;
+
+	if (params != NULL)
+		state->tune_state = VA1J5JF8007T_SET_FREQUENCY;
+
+	switch (state->tune_state) {
+	case VA1J5JF8007T_IDLE:
+		*delay = 3 * HZ;
+		*status = 0;
+		return 0;
+
+	case VA1J5JF8007T_SET_FREQUENCY:
+		ret = va1j5jf8007t_set_frequency(state);
+		if (ret < 0)
+			return ret;
+
+		state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY;
+		*delay = 0;
+		*status = 0;
+		return 0;
+
+	case VA1J5JF8007T_CHECK_FREQUENCY:
+		ret = va1j5jf8007t_check_frequency(state, &lock);
+		if (ret < 0)
+			return ret;
+
+		if (!lock)  {
+			*delay = (HZ + 999) / 1000;
+			*status = 0;
+			return 0;
+		}
+
+		state->tune_state = VA1J5JF8007T_SET_MODULATION;
+		*delay = 0;
+		*status = FE_HAS_SIGNAL;
+		return 0;
+
+	case VA1J5JF8007T_SET_MODULATION:
+		ret = va1j5jf8007t_set_modulation(state);
+		if (ret < 0)
+			return ret;
+
+		state->tune_state = VA1J5JF8007T_CHECK_MODULATION;
+		*delay = 0;
+		*status = FE_HAS_SIGNAL;
+		return 0;
+
+	case VA1J5JF8007T_CHECK_MODULATION:
+		ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
+		if (ret < 0)
+			return ret;
+
+		if (!lock)  {
+			if (!retry)  {
+				state->tune_state = VA1J5JF8007T_ABORT;
+				*delay = 3 * HZ;
+				*status = FE_HAS_SIGNAL;
+				return 0;
+			}
+			*delay = (HZ + 999) / 1000;
+			*status = FE_HAS_SIGNAL;
+			return 0;
+		}
+
+		state->tune_state = VA1J5JF8007T_TRACK;
+		/* fall through */
+
+	case VA1J5JF8007T_TRACK:
+		*delay = 3 * HZ;
+		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
+		return 0;
+
+	case VA1J5JF8007T_ABORT:
+		*delay = 3 * HZ;
+		*status = FE_HAS_SIGNAL;
+		return 0;
+	}
+
+	BUG();
+}
+
+static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state)
+{
+	u8 buf[7];
+	struct i2c_msg msg;
+
+	buf[0] = 0xfe;
+	buf[1] = 0xc2;
+	buf[2] = 0x01;
+	buf[3] = 0x8f;
+	buf[4] = 0xc1;
+	buf[5] = 0x80;
+	buf[6] = 0x80;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep)
+{
+	u8 buf[2];
+	struct i2c_msg msg;
+
+	buf[0] = 0x03;
+	buf[1] = sleep ? 0x90 : 0x80;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1)
+		return -EREMOTEIO;
+
+	return 0;
+}
+
+static int va1j5jf8007t_sleep(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007t_state *state;
+	int ret;
+
+	state = fe->demodulator_priv;
+
+	ret = va1j5jf8007t_init_frequency(state);
+	if (ret < 0)
+		return ret;
+
+	return va1j5jf8007t_set_sleep(state, 1);
+}
+
+static int va1j5jf8007t_init(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007t_state *state;
+
+	state = fe->demodulator_priv;
+	state->tune_state = VA1J5JF8007T_IDLE;
+
+	return va1j5jf8007t_set_sleep(state, 0);
+}
+
+static void va1j5jf8007t_release(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007t_state *state;
+	state = fe->demodulator_priv;
+	kfree(state);
+}
+
+static struct dvb_frontend_ops va1j5jf8007t_ops = {
+	.info = {
+		.name = "VA1J5JF8007 ISDB-T",
+		.type = FE_OFDM,
+		.frequency_min = 90000000,
+		.frequency_max = 770000000,
+		.frequency_stepsize = 142857,
+		.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.get_frontend_algo = va1j5jf8007t_get_frontend_algo,
+	.read_status = va1j5jf8007t_read_status,
+	.tune = va1j5jf8007t_tune,
+	.sleep = va1j5jf8007t_sleep,
+	.init = va1j5jf8007t_init,
+	.release = va1j5jf8007t_release,
+};
+
+static const u8 va1j5jf8007t_prepare_bufs[][2] = {
+	{0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
+	{0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
+	{0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
+	{0xef, 0x01}
+};
+
+int va1j5jf8007t_prepare(struct dvb_frontend *fe)
+{
+	struct va1j5jf8007t_state *state;
+	u8 buf[2];
+	struct i2c_msg msg;
+	int i;
+
+	state = fe->demodulator_priv;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_prepare_bufs); i++) {
+		memcpy(buf, va1j5jf8007t_prepare_bufs[i], sizeof(buf));
+		if (i2c_transfer(state->adap, &msg, 1) != 1)
+			return -EREMOTEIO;
+	}
+
+	return va1j5jf8007t_init_frequency(state);
+}
+
+struct dvb_frontend *
+va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
+		    struct i2c_adapter *adap)
+{
+	struct va1j5jf8007t_state *state;
+	struct dvb_frontend *fe;
+	u8 buf[2];
+	struct i2c_msg msg;
+
+	state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	state->config = config;
+	state->adap = adap;
+
+	fe = &state->fe;
+	memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops));
+	fe->demodulator_priv = state;
+
+	buf[0] = 0x01;
+	buf[1] = 0x80;
+
+	msg.addr = state->config->demod_address;
+	msg.flags = 0;
+	msg.len = sizeof(buf);
+	msg.buf = buf;
+
+	if (i2c_transfer(state->adap, &msg, 1) != 1) {
+		kfree(state);
+		return NULL;
+	}
+
+	return fe;
+}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/dvb/pt1/va1j5jf8007t.h
new file mode 100644
index 0000000..ed49906
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.h
@@ -0,0 +1,40 @@
+/*
+ * ISDB-T driver for VA1J5JF8007
+ *
+ * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
+ *
+ * based on pt1dvr - http://pt1dvr.sourceforge.jp/
+ * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 VA1J5JF8007T_H
+#define VA1J5JF8007T_H
+
+struct va1j5jf8007t_config {
+	u8 demod_address;
+};
+
+struct i2c_adapter;
+
+struct dvb_frontend *
+va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
+		    struct i2c_adapter *adap);
+
+/* must be called after va1j5jf8007s_attach */
+int va1j5jf8007t_prepare(struct dvb_frontend *fe);
+
+#endif
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index ce64c62..8986d96 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -490,7 +490,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
 	if (!av7110->analog_tuner_flags)
 		return 0;
 
-	if (input < 0 || input >= 4)
+	if (input >= 4)
 		return -EINVAL;
 
 	av7110->current_input = input;
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 371a716..b5c6813 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -225,7 +225,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
 	case 0x1012:
 		/* The hauppauge keymap is a superset of these remotes */
 		ir_input_init(input_dev, &budget_ci->ir.state,
-			      IR_TYPE_RC5, ir_codes_hauppauge_new);
+			      IR_TYPE_RC5, &ir_codes_hauppauge_new_table);
 
 		if (rc5_device < 0)
 			budget_ci->ir.rc5_device = 0x1f;
@@ -237,7 +237,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
 	case 0x101a:
 		/* for the Technotrend 1500 bundled remote */
 		ir_input_init(input_dev, &budget_ci->ir.state,
-			      IR_TYPE_RC5, ir_codes_tt_1500);
+			      IR_TYPE_RC5, &ir_codes_tt_1500_table);
 
 		if (rc5_device < 0)
 			budget_ci->ir.rc5_device = IR_DEVICE_ANY;
@@ -247,7 +247,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
 	default:
 		/* unknown remote */
 		ir_input_init(input_dev, &budget_ci->ir.state,
-			      IR_TYPE_RC5, ir_codes_budget_ci_old);
+			      IR_TYPE_RC5, &ir_codes_budget_ci_old_table);
 
 		if (rc5_device < 0)
 			budget_ci->ir.rc5_device = IR_DEVICE_ANY;
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 3315cac..a87a477 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -288,16 +288,6 @@ config RADIO_TYPHOON
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-typhoon.
 
-config RADIO_TYPHOON_PROC_FS
-	bool "Support for /proc/radio-typhoon"
-	depends on PROC_FS && RADIO_TYPHOON
-	help
-	  Say Y here if you want the typhoon radio card driver to write
-	  status information (frequency, volume, muted, mute frequency,
-	  base address) to /proc/radio-typhoon. The file can be viewed with
-	  your favorite pager (i.e. use "more /proc/radio-typhoon" or "less
-	  /proc/radio-typhoon" or simply "cat /proc/radio-typhoon").
-
 config RADIO_TYPHOON_PORT
 	hex "Typhoon I/O port (0x316 or 0x336)"
 	depends on RADIO_TYPHOON=y
@@ -339,6 +329,29 @@ config RADIO_ZOLTRIX_PORT
 	help
 	  Enter the I/O port of your Zoltrix radio card.
 
+config I2C_SI4713
+	tristate "I2C driver for Silicon Labs Si4713 device"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  Say Y here if you want support to Si4713 I2C device.
+	  This device driver supports only i2c bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called si4713.
+
+config RADIO_SI4713
+	tristate "Silicon Labs Si4713 FM Radio Transmitter support"
+	depends on I2C && VIDEO_V4L2
+	select I2C_SI4713
+	---help---
+	  Say Y here if you want support to Si4713 FM Radio Transmitter.
+	  This device can transmit audio through FM. It can transmit
+	  RDS and RBDS signals as well. This module is the v4l2 radio
+	  interface for the i2c driver of this device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-si4713.
+
 config USB_DSBR
 	tristate "D-Link/GemTek USB FM radio support"
 	depends on USB && VIDEO_V4L2
@@ -351,29 +364,11 @@ config USB_DSBR
 	  To compile this driver as a module, choose M here: the
 	  module will be called dsbr100.
 
-config USB_SI470X
-	tristate "Silicon Labs Si470x FM Radio Receiver support"
-	depends on USB && VIDEO_V4L2
-	---help---
-	  This is a driver for USB devices with the Silicon Labs SI470x
-	  chip. Currently these devices are known to work:
-	  - 10c4:818a: Silicon Labs USB FM Radio Reference Design
-	  - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music)
-	  - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
-
-	  Sound is provided by the ALSA USB Audio/MIDI driver. Therefore
-	  if you don't want to use the device solely for RDS receiving,
-	  it is recommended to also select SND_USB_AUDIO.
-
-	  Please have a look at the documentation, especially on how
-	  to redirect the audio stream from the radio to your sound device:
-	  Documentation/video4linux/si470x.txt
-
-	  Say Y here if you want to connect this type of radio to your
-	  computer's USB port.
+config RADIO_SI470X
+	bool "Silicon Labs Si470x FM Radio Receiver support"
+	depends on VIDEO_V4L2
 
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-si470x.
+source "drivers/media/radio/si470x/Kconfig"
 
 config USB_MR800
 	tristate "AverMedia MR 800 USB FM radio support"
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 0f2b35b..2a1be3b 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -15,9 +15,11 @@ obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o
 obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o
 obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o
 obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
+obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
+obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
 obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
 obj-$(CONFIG_USB_DSBR) += dsbr100.o
-obj-$(CONFIG_USB_SI470X) += radio-si470x.o
+obj-$(CONFIG_RADIO_SI470X) += si470x/
 obj-$(CONFIG_USB_MR800) += radio-mr800.o
 obj-$(CONFIG_RADIO_TEA5764) += radio-tea5764.o
 
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index d30fc0c..8b14401 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -359,7 +359,8 @@ static int vidioc_querycap(struct file *file, void *priv,
 	strlcpy(v->card, "ADS Cadet", sizeof(v->card));
 	strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
 	v->version = CADET_VERSION;
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_READWRITE;
+	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO |
+			  V4L2_CAP_READWRITE | V4L2_CAP_RDS_CAPTURE;
 	return 0;
 }
 
@@ -372,7 +373,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 	switch (v->index) {
 	case 0:
 		strlcpy(v->name, "FM", sizeof(v->name));
-		v->capability = V4L2_TUNER_CAP_STEREO;
+		v->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS;
 		v->rangelow = 1400;     /* 87.5 MHz */
 		v->rangehigh = 1728;    /* 108.0 MHz */
 		v->rxsubchans = cadet_getstereo(dev);
@@ -386,6 +387,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 		default:
 			break;
 		}
+		v->rxsubchans |= V4L2_TUNER_SUB_RDS;
 		break;
 	case 1:
 		strlcpy(v->name, "AM", sizeof(v->name));
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
deleted file mode 100644
index e85f318..0000000
--- a/drivers/media/radio/radio-si470x.c
+++ /dev/null
@@ -1,1863 +0,0 @@
-/*
- *  drivers/media/radio/radio-si470x.c
- *
- *  Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers:
- *   - Silicon Labs USB FM Radio Reference Design
- *   - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
- *   - KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
- *   - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
- *
- *  Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-/*
- * History:
- * 2008-01-12	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Version 1.0.0
- *		- First working version
- * 2008-01-13	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Version 1.0.1
- *		- Improved error handling, every function now returns errno
- *		- Improved multi user access (start/mute/stop)
- *		- Channel doesn't get lost anymore after start/mute/stop
- *		- RDS support added (polling mode via interrupt EP 1)
- *		- marked default module parameters with *value*
- *		- switched from bit structs to bit masks
- *		- header file cleaned and integrated
- * 2008-01-14	Tobias Lorenz <tobias.lorenz@gmx.net>
- * 		Version 1.0.2
- * 		- hex values are now lower case
- * 		- commented USB ID for ADS/Tech moved on todo list
- * 		- blacklisted si470x in hid-quirks.c
- * 		- rds buffer handling functions integrated into *_work, *_read
- * 		- rds_command in si470x_poll exchanged against simple retval
- * 		- check for firmware version 15
- * 		- code order and prototypes still remain the same
- * 		- spacing and bottom of band codes remain the same
- * 2008-01-16	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Version 1.0.3
- * 		- code reordered to avoid function prototypes
- *		- switch/case defaults are now more user-friendly
- *		- unified comment style
- *		- applied all checkpatch.pl v1.12 suggestions
- *		  except the warning about the too long lines with bit comments
- *		- renamed FMRADIO to RADIO to cut line length (checkpatch.pl)
- * 2008-01-22	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Version 1.0.4
- *		- avoid poss. locking when doing copy_to_user which may sleep
- *		- RDS is automatically activated on read now
- *		- code cleaned of unnecessary rds_commands
- *		- USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
- *		  (thanks to Guillaume RAMOUSSE)
- * 2008-01-27	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Version 1.0.5
- *		- number of seek_retries changed to tune_timeout
- *		- fixed problem with incomplete tune operations by own buffers
- *		- optimization of variables and printf types
- *		- improved error logging
- * 2008-01-31	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Oliver Neukum <oliver@neukum.org>
- *		Version 1.0.6
- *		- fixed coverity checker warnings in *_usb_driver_disconnect
- *		- probe()/open() race by correct ordering in probe()
- *		- DMA coherency rules by separate allocation of all buffers
- *		- use of endianness macros
- *		- abuse of spinlock, replaced by mutex
- *		- racy handling of timer in disconnect,
- *		  replaced by delayed_work
- *		- racy interruptible_sleep_on(),
- *		  replaced with wait_event_interruptible()
- *		- handle signals in read()
- * 2008-02-08	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Oliver Neukum <oliver@neukum.org>
- *		Version 1.0.7
- *		- usb autosuspend support
- *		- unplugging fixed
- * 2008-05-07	Tobias Lorenz <tobias.lorenz@gmx.net>
- *		Version 1.0.8
- *		- hardware frequency seek support
- *		- afc indication
- *		- more safety checks, let si470x_get_freq return errno
- *		- vidioc behavior corrected according to v4l2 spec
- * 2008-10-20	Alexey Klimov <klimov.linux@gmail.com>
- * 		- add support for KWorld USB FM Radio FM700
- * 		- blacklisted KWorld radio in hid-core.c and hid-ids.h
- * 2008-12-03	Mark Lord <mlord@pobox.com>
- *		- add support for DealExtreme USB Radio
- * 2009-01-31	Bob Ross <pigiron@gmx.com>
- *		- correction of stereo detection/setting
- *		- correction of signal strength indicator scaling
- * 2009-01-31	Rick Bronson <rick@efn.org>
- *		Tobias Lorenz <tobias.lorenz@gmx.net>
- *		- add LED status output
- *		- get HW/SW version from scratchpad
- *
- * ToDo:
- * - add firmware download/update support
- * - RDS support: interrupt mode, instead of polling
- */
-
-
-/* driver definitions */
-#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
-#define DRIVER_NAME "radio-si470x"
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9)
-#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
-#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.9"
-
-
-/* kernel includes */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/input.h>
-#include <linux/usb.h>
-#include <linux/hid.h>
-#include <linux/version.h>
-#include <linux/videodev2.h>
-#include <linux/mutex.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <media/rds.h>
-#include <asm/unaligned.h>
-
-
-/* USB Device ID List */
-static struct usb_device_id si470x_usb_driver_id_table[] = {
-	/* Silicon Labs USB FM Radio Reference Design */
-	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
-	/* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
-	{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
-	/* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
-	{ USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
-	/* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
-	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
-	/* Terminating entry */
-	{ }
-};
-MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
-
-
-
-/**************************************************************************
- * Module Parameters
- **************************************************************************/
-
-/* Radio Nr */
-static int radio_nr = -1;
-module_param(radio_nr, int, 0444);
-MODULE_PARM_DESC(radio_nr, "Radio Nr");
-
-/* Spacing (kHz) */
-/* 0: 200 kHz (USA, Australia) */
-/* 1: 100 kHz (Europe, Japan) */
-/* 2:  50 kHz */
-static unsigned short space = 2;
-module_param(space, ushort, 0444);
-MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
-
-/* Bottom of Band (MHz) */
-/* 0: 87.5 - 108 MHz (USA, Europe)*/
-/* 1: 76   - 108 MHz (Japan wide band) */
-/* 2: 76   -  90 MHz (Japan) */
-static unsigned short band = 1;
-module_param(band, ushort, 0444);
-MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
-
-/* De-emphasis */
-/* 0: 75 us (USA) */
-/* 1: 50 us (Europe, Australia, Japan) */
-static unsigned short de = 1;
-module_param(de, ushort, 0444);
-MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
-
-/* USB timeout */
-static unsigned int usb_timeout = 500;
-module_param(usb_timeout, uint, 0644);
-MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
-
-/* Tune timeout */
-static unsigned int tune_timeout = 3000;
-module_param(tune_timeout, uint, 0644);
-MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
-
-/* Seek timeout */
-static unsigned int seek_timeout = 5000;
-module_param(seek_timeout, uint, 0644);
-MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
-
-/* RDS buffer blocks */
-static unsigned int rds_buf = 100;
-module_param(rds_buf, uint, 0444);
-MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
-
-/* RDS maximum block errors */
-static unsigned short max_rds_errors = 1;
-/* 0 means   0  errors requiring correction */
-/* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
-/* 2 means 3-5  errors requiring correction */
-/* 3 means   6+ errors or errors in checkword, correction not possible */
-module_param(max_rds_errors, ushort, 0644);
-MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
-
-/* RDS poll frequency */
-static unsigned int rds_poll_time = 40;
-/* 40 is used by the original USBRadio.exe */
-/* 50 is used by radio-cadet */
-/* 75 should be okay */
-/* 80 is the usual RDS receive interval */
-module_param(rds_poll_time, uint, 0644);
-MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
-
-
-
-/**************************************************************************
- * Register Definitions
- **************************************************************************/
-#define RADIO_REGISTER_SIZE	2	/* 16 register bit width */
-#define RADIO_REGISTER_NUM	16	/* DEVICEID   ... RDSD */
-#define RDS_REGISTER_NUM	6	/* STATUSRSSI ... RDSD */
-
-#define DEVICEID		0	/* Device ID */
-#define DEVICEID_PN		0xf000	/* bits 15..12: Part Number */
-#define DEVICEID_MFGID		0x0fff	/* bits 11..00: Manufacturer ID */
-
-#define CHIPID			1	/* Chip ID */
-#define CHIPID_REV		0xfc00	/* bits 15..10: Chip Version */
-#define CHIPID_DEV		0x0200	/* bits 09..09: Device */
-#define CHIPID_FIRMWARE		0x01ff	/* bits 08..00: Firmware Version */
-
-#define POWERCFG		2	/* Power Configuration */
-#define POWERCFG_DSMUTE		0x8000	/* bits 15..15: Softmute Disable */
-#define POWERCFG_DMUTE		0x4000	/* bits 14..14: Mute Disable */
-#define POWERCFG_MONO		0x2000	/* bits 13..13: Mono Select */
-#define POWERCFG_RDSM		0x0800	/* bits 11..11: RDS Mode (Si4701 only) */
-#define POWERCFG_SKMODE		0x0400	/* bits 10..10: Seek Mode */
-#define POWERCFG_SEEKUP		0x0200	/* bits 09..09: Seek Direction */
-#define POWERCFG_SEEK		0x0100	/* bits 08..08: Seek */
-#define POWERCFG_DISABLE	0x0040	/* bits 06..06: Powerup Disable */
-#define POWERCFG_ENABLE		0x0001	/* bits 00..00: Powerup Enable */
-
-#define CHANNEL			3	/* Channel */
-#define CHANNEL_TUNE		0x8000	/* bits 15..15: Tune */
-#define CHANNEL_CHAN		0x03ff	/* bits 09..00: Channel Select */
-
-#define SYSCONFIG1		4	/* System Configuration 1 */
-#define SYSCONFIG1_RDSIEN	0x8000	/* bits 15..15: RDS Interrupt Enable (Si4701 only) */
-#define SYSCONFIG1_STCIEN	0x4000	/* bits 14..14: Seek/Tune Complete Interrupt Enable */
-#define SYSCONFIG1_RDS		0x1000	/* bits 12..12: RDS Enable (Si4701 only) */
-#define SYSCONFIG1_DE		0x0800	/* bits 11..11: De-emphasis (0=75us 1=50us) */
-#define SYSCONFIG1_AGCD		0x0400	/* bits 10..10: AGC Disable */
-#define SYSCONFIG1_BLNDADJ	0x00c0	/* bits 07..06: Stereo/Mono Blend Level Adjustment */
-#define SYSCONFIG1_GPIO3	0x0030	/* bits 05..04: General Purpose I/O 3 */
-#define SYSCONFIG1_GPIO2	0x000c	/* bits 03..02: General Purpose I/O 2 */
-#define SYSCONFIG1_GPIO1	0x0003	/* bits 01..00: General Purpose I/O 1 */
-
-#define SYSCONFIG2		5	/* System Configuration 2 */
-#define SYSCONFIG2_SEEKTH	0xff00	/* bits 15..08: RSSI Seek Threshold */
-#define SYSCONFIG2_BAND		0x0080	/* bits 07..06: Band Select */
-#define SYSCONFIG2_SPACE	0x0030	/* bits 05..04: Channel Spacing */
-#define SYSCONFIG2_VOLUME	0x000f	/* bits 03..00: Volume */
-
-#define SYSCONFIG3		6	/* System Configuration 3 */
-#define SYSCONFIG3_SMUTER	0xc000	/* bits 15..14: Softmute Attack/Recover Rate */
-#define SYSCONFIG3_SMUTEA	0x3000	/* bits 13..12: Softmute Attenuation */
-#define SYSCONFIG3_SKSNR	0x00f0	/* bits 07..04: Seek SNR Threshold */
-#define SYSCONFIG3_SKCNT	0x000f	/* bits 03..00: Seek FM Impulse Detection Threshold */
-
-#define TEST1			7	/* Test 1 */
-#define TEST1_AHIZEN		0x4000	/* bits 14..14: Audio High-Z Enable */
-
-#define TEST2			8	/* Test 2 */
-/* TEST2 only contains reserved bits */
-
-#define BOOTCONFIG		9	/* Boot Configuration */
-/* BOOTCONFIG only contains reserved bits */
-
-#define STATUSRSSI		10	/* Status RSSI */
-#define STATUSRSSI_RDSR		0x8000	/* bits 15..15: RDS Ready (Si4701 only) */
-#define STATUSRSSI_STC		0x4000	/* bits 14..14: Seek/Tune Complete */
-#define STATUSRSSI_SF		0x2000	/* bits 13..13: Seek Fail/Band Limit */
-#define STATUSRSSI_AFCRL	0x1000	/* bits 12..12: AFC Rail */
-#define STATUSRSSI_RDSS		0x0800	/* bits 11..11: RDS Synchronized (Si4701 only) */
-#define STATUSRSSI_BLERA	0x0600	/* bits 10..09: RDS Block A Errors (Si4701 only) */
-#define STATUSRSSI_ST		0x0100	/* bits 08..08: Stereo Indicator */
-#define STATUSRSSI_RSSI		0x00ff	/* bits 07..00: RSSI (Received Signal Strength Indicator) */
-
-#define READCHAN		11	/* Read Channel */
-#define READCHAN_BLERB		0xc000	/* bits 15..14: RDS Block D Errors (Si4701 only) */
-#define READCHAN_BLERC		0x3000	/* bits 13..12: RDS Block C Errors (Si4701 only) */
-#define READCHAN_BLERD		0x0c00	/* bits 11..10: RDS Block B Errors (Si4701 only) */
-#define READCHAN_READCHAN	0x03ff	/* bits 09..00: Read Channel */
-
-#define RDSA			12	/* RDSA */
-#define RDSA_RDSA		0xffff	/* bits 15..00: RDS Block A Data (Si4701 only) */
-
-#define RDSB			13	/* RDSB */
-#define RDSB_RDSB		0xffff	/* bits 15..00: RDS Block B Data (Si4701 only) */
-
-#define RDSC			14	/* RDSC */
-#define RDSC_RDSC		0xffff	/* bits 15..00: RDS Block C Data (Si4701 only) */
-
-#define RDSD			15	/* RDSD */
-#define RDSD_RDSD		0xffff	/* bits 15..00: RDS Block D Data (Si4701 only) */
-
-
-
-/**************************************************************************
- * USB HID Reports
- **************************************************************************/
-
-/* Reports 1-16 give direct read/write access to the 16 Si470x registers */
-/* with the (REPORT_ID - 1) corresponding to the register address across USB */
-/* endpoint 0 using GET_REPORT and SET_REPORT */
-#define REGISTER_REPORT_SIZE	(RADIO_REGISTER_SIZE + 1)
-#define REGISTER_REPORT(reg)	((reg) + 1)
-
-/* Report 17 gives direct read/write access to the entire Si470x register */
-/* map across endpoint 0 using GET_REPORT and SET_REPORT */
-#define ENTIRE_REPORT_SIZE	(RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
-#define ENTIRE_REPORT		17
-
-/* Report 18 is used to send the lowest 6 Si470x registers up the HID */
-/* interrupt endpoint 1 to Windows every 20 milliseconds for status */
-#define RDS_REPORT_SIZE		(RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
-#define RDS_REPORT		18
-
-/* Report 19: LED state */
-#define LED_REPORT_SIZE		3
-#define LED_REPORT		19
-
-/* Report 19: stream */
-#define STREAM_REPORT_SIZE	3
-#define STREAM_REPORT		19
-
-/* Report 20: scratch */
-#define SCRATCH_PAGE_SIZE	63
-#define SCRATCH_REPORT_SIZE	(SCRATCH_PAGE_SIZE + 1)
-#define SCRATCH_REPORT		20
-
-/* Reports 19-22: flash upgrade of the C8051F321 */
-#define WRITE_REPORT_SIZE	4
-#define WRITE_REPORT		19
-#define FLASH_REPORT_SIZE	64
-#define FLASH_REPORT		20
-#define CRC_REPORT_SIZE		3
-#define CRC_REPORT		21
-#define RESPONSE_REPORT_SIZE	2
-#define RESPONSE_REPORT		22
-
-/* Report 23: currently unused, but can accept 60 byte reports on the HID */
-/* interrupt out endpoint 2 every 1 millisecond */
-#define UNUSED_REPORT		23
-
-
-
-/**************************************************************************
- * Software/Hardware Versions
- **************************************************************************/
-#define RADIO_SW_VERSION_NOT_BOOTLOADABLE	6
-#define RADIO_SW_VERSION			7
-#define RADIO_SW_VERSION_CURRENT		15
-#define RADIO_HW_VERSION			1
-
-#define SCRATCH_PAGE_SW_VERSION	1
-#define SCRATCH_PAGE_HW_VERSION	2
-
-
-
-/**************************************************************************
- * LED State Definitions
- **************************************************************************/
-#define LED_COMMAND		0x35
-
-#define NO_CHANGE_LED		0x00
-#define ALL_COLOR_LED		0x01	/* streaming state */
-#define BLINK_GREEN_LED		0x02	/* connect state */
-#define BLINK_RED_LED		0x04
-#define BLINK_ORANGE_LED	0x10	/* disconnect state */
-#define SOLID_GREEN_LED		0x20	/* tuning/seeking state */
-#define SOLID_RED_LED		0x40	/* bootload state */
-#define SOLID_ORANGE_LED	0x80
-
-
-
-/**************************************************************************
- * Stream State Definitions
- **************************************************************************/
-#define STREAM_COMMAND	0x36
-#define STREAM_VIDPID	0x00
-#define STREAM_AUDIO	0xff
-
-
-
-/**************************************************************************
- * Bootloader / Flash Commands
- **************************************************************************/
-
-/* unique id sent to bootloader and required to put into a bootload state */
-#define UNIQUE_BL_ID		0x34
-
-/* mask for the flash data */
-#define FLASH_DATA_MASK		0x55
-
-/* bootloader commands */
-#define GET_SW_VERSION_COMMAND	0x00
-#define SET_PAGE_COMMAND	0x01
-#define ERASE_PAGE_COMMAND	0x02
-#define WRITE_PAGE_COMMAND	0x03
-#define CRC_ON_PAGE_COMMAND	0x04
-#define READ_FLASH_BYTE_COMMAND	0x05
-#define RESET_DEVICE_COMMAND	0x06
-#define GET_HW_VERSION_COMMAND	0x07
-#define BLANK			0xff
-
-/* bootloader command responses */
-#define COMMAND_OK		0x01
-#define COMMAND_FAILED		0x02
-#define COMMAND_PENDING		0x03
-
-
-
-/**************************************************************************
- * General Driver Definitions
- **************************************************************************/
-
-/*
- * si470x_device - private data
- */
-struct si470x_device {
-	/* reference to USB and video device */
-	struct usb_device *usbdev;
-	struct usb_interface *intf;
-	struct video_device *videodev;
-
-	/* driver management */
-	unsigned int users;
-	unsigned char disconnected;
-	struct mutex disconnect_lock;
-
-	/* Silabs internal registers (0..15) */
-	unsigned short registers[RADIO_REGISTER_NUM];
-
-	/* RDS receive buffer */
-	struct delayed_work work;
-	wait_queue_head_t read_queue;
-	struct mutex lock;		/* buffer locking */
-	unsigned char *buffer;		/* size is always multiple of three */
-	unsigned int buf_size;
-	unsigned int rd_index;
-	unsigned int wr_index;
-
-	/* scratch page */
-	unsigned char software_version;
-	unsigned char hardware_version;
-};
-
-
-/*
- * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW,
- * 62.5 kHz otherwise.
- * The tuner is able to have a channel spacing of 50, 100 or 200 kHz.
- * tuner->capability is therefore set to V4L2_TUNER_CAP_LOW
- * The FREQ_MUL is then: 1 MHz / 62.5 Hz = 16000
- */
-#define FREQ_MUL (1000000 / 62.5)
-
-
-
-/**************************************************************************
- * General Driver Functions - REGISTER_REPORTs
- **************************************************************************/
-
-/*
- * si470x_get_report - receive a HID report
- */
-static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
-{
-	unsigned char *report = (unsigned char *) buf;
-	int retval;
-
-	retval = usb_control_msg(radio->usbdev,
-		usb_rcvctrlpipe(radio->usbdev, 0),
-		HID_REQ_GET_REPORT,
-		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
-		report[0], 2,
-		buf, size, usb_timeout);
-
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": si470x_get_report: usb_control_msg returned %d\n",
-			retval);
-	return retval;
-}
-
-
-/*
- * si470x_set_report - send a HID report
- */
-static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
-{
-	unsigned char *report = (unsigned char *) buf;
-	int retval;
-
-	retval = usb_control_msg(radio->usbdev,
-		usb_sndctrlpipe(radio->usbdev, 0),
-		HID_REQ_SET_REPORT,
-		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
-		report[0], 2,
-		buf, size, usb_timeout);
-
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": si470x_set_report: usb_control_msg returned %d\n",
-			retval);
-	return retval;
-}
-
-
-/*
- * si470x_get_register - read register
- */
-static int si470x_get_register(struct si470x_device *radio, int regnr)
-{
-	unsigned char buf[REGISTER_REPORT_SIZE];
-	int retval;
-
-	buf[0] = REGISTER_REPORT(regnr);
-
-	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
-
-	if (retval >= 0)
-		radio->registers[regnr] = get_unaligned_be16(&buf[1]);
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
- * si470x_set_register - write register
- */
-static int si470x_set_register(struct si470x_device *radio, int regnr)
-{
-	unsigned char buf[REGISTER_REPORT_SIZE];
-	int retval;
-
-	buf[0] = REGISTER_REPORT(regnr);
-	put_unaligned_be16(radio->registers[regnr], &buf[1]);
-
-	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
- * si470x_set_chan - set the channel
- */
-static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
-{
-	int retval;
-	unsigned long timeout;
-	bool timed_out = 0;
-
-	/* start tuning */
-	radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
-	radio->registers[CHANNEL] |= CHANNEL_TUNE | chan;
-	retval = si470x_set_register(radio, CHANNEL);
-	if (retval < 0)
-		goto done;
-
-	/* wait till tune operation has completed */
-	timeout = jiffies + msecs_to_jiffies(tune_timeout);
-	do {
-		retval = si470x_get_register(radio, STATUSRSSI);
-		if (retval < 0)
-			goto stop;
-		timed_out = time_after(jiffies, timeout);
-	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
-		(!timed_out));
-	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
-		printk(KERN_WARNING DRIVER_NAME ": tune does not complete\n");
-	if (timed_out)
-		printk(KERN_WARNING DRIVER_NAME
-			": tune timed out after %u ms\n", tune_timeout);
-
-stop:
-	/* stop tuning */
-	radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
-	retval = si470x_set_register(radio, CHANNEL);
-
-done:
-	return retval;
-}
-
-
-/*
- * si470x_get_freq - get the frequency
- */
-static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
-{
-	unsigned int spacing, band_bottom;
-	unsigned short chan;
-	int retval;
-
-	/* Spacing (kHz) */
-	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
-	/* 0: 200 kHz (USA, Australia) */
-	case 0:
-		spacing = 0.200 * FREQ_MUL; break;
-	/* 1: 100 kHz (Europe, Japan) */
-	case 1:
-		spacing = 0.100 * FREQ_MUL; break;
-	/* 2:  50 kHz */
-	default:
-		spacing = 0.050 * FREQ_MUL; break;
-	};
-
-	/* Bottom of Band (MHz) */
-	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
-	/* 0: 87.5 - 108 MHz (USA, Europe) */
-	case 0:
-		band_bottom = 87.5 * FREQ_MUL; break;
-	/* 1: 76   - 108 MHz (Japan wide band) */
-	default:
-		band_bottom = 76   * FREQ_MUL; break;
-	/* 2: 76   -  90 MHz (Japan) */
-	case 2:
-		band_bottom = 76   * FREQ_MUL; break;
-	};
-
-	/* read channel */
-	retval = si470x_get_register(radio, READCHAN);
-	chan = radio->registers[READCHAN] & READCHAN_READCHAN;
-
-	/* Frequency (MHz) = Spacing (kHz) x Channel + Bottom of Band (MHz) */
-	*freq = chan * spacing + band_bottom;
-
-	return retval;
-}
-
-
-/*
- * si470x_set_freq - set the frequency
- */
-static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
-{
-	unsigned int spacing, band_bottom;
-	unsigned short chan;
-
-	/* Spacing (kHz) */
-	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
-	/* 0: 200 kHz (USA, Australia) */
-	case 0:
-		spacing = 0.200 * FREQ_MUL; break;
-	/* 1: 100 kHz (Europe, Japan) */
-	case 1:
-		spacing = 0.100 * FREQ_MUL; break;
-	/* 2:  50 kHz */
-	default:
-		spacing = 0.050 * FREQ_MUL; break;
-	};
-
-	/* Bottom of Band (MHz) */
-	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
-	/* 0: 87.5 - 108 MHz (USA, Europe) */
-	case 0:
-		band_bottom = 87.5 * FREQ_MUL; break;
-	/* 1: 76   - 108 MHz (Japan wide band) */
-	default:
-		band_bottom = 76   * FREQ_MUL; break;
-	/* 2: 76   -  90 MHz (Japan) */
-	case 2:
-		band_bottom = 76   * FREQ_MUL; break;
-	};
-
-	/* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
-	chan = (freq - band_bottom) / spacing;
-
-	return si470x_set_chan(radio, chan);
-}
-
-
-/*
- * si470x_set_seek - set seek
- */
-static int si470x_set_seek(struct si470x_device *radio,
-		unsigned int wrap_around, unsigned int seek_upward)
-{
-	int retval = 0;
-	unsigned long timeout;
-	bool timed_out = 0;
-
-	/* start seeking */
-	radio->registers[POWERCFG] |= POWERCFG_SEEK;
-	if (wrap_around == 1)
-		radio->registers[POWERCFG] &= ~POWERCFG_SKMODE;
-	else
-		radio->registers[POWERCFG] |= POWERCFG_SKMODE;
-	if (seek_upward == 1)
-		radio->registers[POWERCFG] |= POWERCFG_SEEKUP;
-	else
-		radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
-	retval = si470x_set_register(radio, POWERCFG);
-	if (retval < 0)
-		goto done;
-
-	/* wait till seek operation has completed */
-	timeout = jiffies + msecs_to_jiffies(seek_timeout);
-	do {
-		retval = si470x_get_register(radio, STATUSRSSI);
-		if (retval < 0)
-			goto stop;
-		timed_out = time_after(jiffies, timeout);
-	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
-		(!timed_out));
-	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
-		printk(KERN_WARNING DRIVER_NAME ": seek does not complete\n");
-	if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
-		printk(KERN_WARNING DRIVER_NAME
-			": seek failed / band limit reached\n");
-	if (timed_out)
-		printk(KERN_WARNING DRIVER_NAME
-			": seek timed out after %u ms\n", seek_timeout);
-
-stop:
-	/* stop seeking */
-	radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
-	retval = si470x_set_register(radio, POWERCFG);
-
-done:
-	/* try again, if timed out */
-	if ((retval == 0) && timed_out)
-		retval = -EAGAIN;
-
-	return retval;
-}
-
-
-/*
- * si470x_start - switch on radio
- */
-static int si470x_start(struct si470x_device *radio)
-{
-	int retval;
-
-	/* powercfg */
-	radio->registers[POWERCFG] =
-		POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM;
-	retval = si470x_set_register(radio, POWERCFG);
-	if (retval < 0)
-		goto done;
-
-	/* sysconfig 1 */
-	radio->registers[SYSCONFIG1] = SYSCONFIG1_DE;
-	retval = si470x_set_register(radio, SYSCONFIG1);
-	if (retval < 0)
-		goto done;
-
-	/* sysconfig 2 */
-	radio->registers[SYSCONFIG2] =
-		(0x3f  << 8) |				/* SEEKTH */
-		((band  << 6) & SYSCONFIG2_BAND)  |	/* BAND */
-		((space << 4) & SYSCONFIG2_SPACE) |	/* SPACE */
-		15;					/* VOLUME (max) */
-	retval = si470x_set_register(radio, SYSCONFIG2);
-	if (retval < 0)
-		goto done;
-
-	/* reset last channel */
-	retval = si470x_set_chan(radio,
-		radio->registers[CHANNEL] & CHANNEL_CHAN);
-
-done:
-	return retval;
-}
-
-
-/*
- * si470x_stop - switch off radio
- */
-static int si470x_stop(struct si470x_device *radio)
-{
-	int retval;
-
-	/* sysconfig 1 */
-	radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
-	retval = si470x_set_register(radio, SYSCONFIG1);
-	if (retval < 0)
-		goto done;
-
-	/* powercfg */
-	radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
-	/* POWERCFG_ENABLE has to automatically go low */
-	radio->registers[POWERCFG] |= POWERCFG_ENABLE |	POWERCFG_DISABLE;
-	retval = si470x_set_register(radio, POWERCFG);
-
-done:
-	return retval;
-}
-
-
-/*
- * si470x_rds_on - switch on rds reception
- */
-static int si470x_rds_on(struct si470x_device *radio)
-{
-	int retval;
-
-	/* sysconfig 1 */
-	mutex_lock(&radio->lock);
-	radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
-	retval = si470x_set_register(radio, SYSCONFIG1);
-	if (retval < 0)
-		radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
-	mutex_unlock(&radio->lock);
-
-	return retval;
-}
-
-
-
-/**************************************************************************
- * General Driver Functions - ENTIRE_REPORT
- **************************************************************************/
-
-/*
- * si470x_get_all_registers - read entire registers
- */
-static int si470x_get_all_registers(struct si470x_device *radio)
-{
-	unsigned char buf[ENTIRE_REPORT_SIZE];
-	int retval;
-	unsigned char regnr;
-
-	buf[0] = ENTIRE_REPORT;
-
-	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
-
-	if (retval >= 0)
-		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
-			radio->registers[regnr] = get_unaligned_be16(
-				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-
-/**************************************************************************
- * General Driver Functions - RDS_REPORT
- **************************************************************************/
-
-/*
- * si470x_get_rds_registers - read rds registers
- */
-static int si470x_get_rds_registers(struct si470x_device *radio)
-{
-	unsigned char buf[RDS_REPORT_SIZE];
-	int retval;
-	int size;
-	unsigned char regnr;
-
-	buf[0] = RDS_REPORT;
-
-	retval = usb_interrupt_msg(radio->usbdev,
-		usb_rcvintpipe(radio->usbdev, 1),
-		(void *) &buf, sizeof(buf), &size, usb_timeout);
-	if (size != sizeof(buf))
-		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
-			"return size differs: %d != %zu\n", size, sizeof(buf));
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
-			"usb_interrupt_msg returned %d\n", retval);
-
-	if (retval >= 0)
-		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
-			radio->registers[STATUSRSSI + regnr] =
-				get_unaligned_be16(
-				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-
-/**************************************************************************
- * General Driver Functions - LED_REPORT
- **************************************************************************/
-
-/*
- * si470x_set_led_state - sets the led state
- */
-static int si470x_set_led_state(struct si470x_device *radio,
-		unsigned char led_state)
-{
-	unsigned char buf[LED_REPORT_SIZE];
-	int retval;
-
-	buf[0] = LED_REPORT;
-	buf[1] = LED_COMMAND;
-	buf[2] = led_state;
-
-	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-
-/**************************************************************************
- * General Driver Functions - SCRATCH_REPORT
- **************************************************************************/
-
-/*
- * si470x_get_scratch_versions - gets the scratch page and version infos
- */
-static int si470x_get_scratch_page_versions(struct si470x_device *radio)
-{
-	unsigned char buf[SCRATCH_REPORT_SIZE];
-	int retval;
-
-	buf[0] = SCRATCH_REPORT;
-
-	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
-
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: "
-			"si470x_get_report returned %d\n", retval);
-	else {
-		radio->software_version = buf[1];
-		radio->hardware_version = buf[2];
-	}
-
-	return (retval < 0) ? -EINVAL : 0;
-}
-
-
-
-/**************************************************************************
- * RDS Driver Functions
- **************************************************************************/
-
-/*
- * si470x_rds - rds processing function
- */
-static void si470x_rds(struct si470x_device *radio)
-{
-	unsigned char blocknum;
-	unsigned short bler; /* rds block errors */
-	unsigned short rds;
-	unsigned char tmpbuf[3];
-
-	/* get rds blocks */
-	if (si470x_get_rds_registers(radio) < 0)
-		return;
-	if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
-		/* No RDS group ready */
-		return;
-	}
-	if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
-		/* RDS decoder not synchronized */
-		return;
-	}
-
-	/* copy all four RDS blocks to internal buffer */
-	mutex_lock(&radio->lock);
-	for (blocknum = 0; blocknum < 4; blocknum++) {
-		switch (blocknum) {
-		default:
-			bler = (radio->registers[STATUSRSSI] &
-					STATUSRSSI_BLERA) >> 9;
-			rds = radio->registers[RDSA];
-			break;
-		case 1:
-			bler = (radio->registers[READCHAN] &
-					READCHAN_BLERB) >> 14;
-			rds = radio->registers[RDSB];
-			break;
-		case 2:
-			bler = (radio->registers[READCHAN] &
-					READCHAN_BLERC) >> 12;
-			rds = radio->registers[RDSC];
-			break;
-		case 3:
-			bler = (radio->registers[READCHAN] &
-					READCHAN_BLERD) >> 10;
-			rds = radio->registers[RDSD];
-			break;
-		};
-
-		/* Fill the V4L2 RDS buffer */
-		put_unaligned_le16(rds, &tmpbuf);
-		tmpbuf[2] = blocknum;		/* offset name */
-		tmpbuf[2] |= blocknum << 3;	/* received offset */
-		if (bler > max_rds_errors)
-			tmpbuf[2] |= 0x80; /* uncorrectable errors */
-		else if (bler > 0)
-			tmpbuf[2] |= 0x40; /* corrected error(s) */
-
-		/* copy RDS block to internal buffer */
-		memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
-		radio->wr_index += 3;
-
-		/* wrap write pointer */
-		if (radio->wr_index >= radio->buf_size)
-			radio->wr_index = 0;
-
-		/* check for overflow */
-		if (radio->wr_index == radio->rd_index) {
-			/* increment and wrap read pointer */
-			radio->rd_index += 3;
-			if (radio->rd_index >= radio->buf_size)
-				radio->rd_index = 0;
-		}
-	}
-	mutex_unlock(&radio->lock);
-
-	/* wake up read queue */
-	if (radio->wr_index != radio->rd_index)
-		wake_up_interruptible(&radio->read_queue);
-}
-
-
-/*
- * si470x_work - rds work function
- */
-static void si470x_work(struct work_struct *work)
-{
-	struct si470x_device *radio = container_of(work, struct si470x_device,
-		work.work);
-
-	/* safety checks */
-	if (radio->disconnected)
-		return;
-	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
-		return;
-
-	si470x_rds(radio);
-	schedule_delayed_work(&radio->work, msecs_to_jiffies(rds_poll_time));
-}
-
-
-
-/**************************************************************************
- * File Operations Interface
- **************************************************************************/
-
-/*
- * si470x_fops_read - read RDS data
- */
-static ssize_t si470x_fops_read(struct file *file, char __user *buf,
-		size_t count, loff_t *ppos)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-	unsigned int block_count = 0;
-
-	/* switch on rds reception */
-	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
-		si470x_rds_on(radio);
-		schedule_delayed_work(&radio->work,
-			msecs_to_jiffies(rds_poll_time));
-	}
-
-	/* block if no new data available */
-	while (radio->wr_index == radio->rd_index) {
-		if (file->f_flags & O_NONBLOCK) {
-			retval = -EWOULDBLOCK;
-			goto done;
-		}
-		if (wait_event_interruptible(radio->read_queue,
-			radio->wr_index != radio->rd_index) < 0) {
-			retval = -EINTR;
-			goto done;
-		}
-	}
-
-	/* calculate block count from byte count */
-	count /= 3;
-
-	/* copy RDS block out of internal buffer and to user buffer */
-	mutex_lock(&radio->lock);
-	while (block_count < count) {
-		if (radio->rd_index == radio->wr_index)
-			break;
-
-		/* always transfer rds complete blocks */
-		if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
-			/* retval = -EFAULT; */
-			break;
-
-		/* increment and wrap read pointer */
-		radio->rd_index += 3;
-		if (radio->rd_index >= radio->buf_size)
-			radio->rd_index = 0;
-
-		/* increment counters */
-		block_count++;
-		buf += 3;
-		retval += 3;
-	}
-	mutex_unlock(&radio->lock);
-
-done:
-	return retval;
-}
-
-
-/*
- * si470x_fops_poll - poll RDS data
- */
-static unsigned int si470x_fops_poll(struct file *file,
-		struct poll_table_struct *pts)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* switch on rds reception */
-	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) {
-		si470x_rds_on(radio);
-		schedule_delayed_work(&radio->work,
-			msecs_to_jiffies(rds_poll_time));
-	}
-
-	poll_wait(file, &radio->read_queue, pts);
-
-	if (radio->rd_index != radio->wr_index)
-		retval = POLLIN | POLLRDNORM;
-
-	return retval;
-}
-
-
-/*
- * si470x_fops_open - file open
- */
-static int si470x_fops_open(struct file *file)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval;
-
-	lock_kernel();
-	radio->users++;
-
-	retval = usb_autopm_get_interface(radio->intf);
-	if (retval < 0) {
-		radio->users--;
-		retval = -EIO;
-		goto done;
-	}
-
-	if (radio->users == 1) {
-		/* start radio */
-		retval = si470x_start(radio);
-		if (retval < 0)
-			usb_autopm_put_interface(radio->intf);
-	}
-
-done:
-	unlock_kernel();
-	return retval;
-}
-
-
-/*
- * si470x_fops_release - file release
- */
-static int si470x_fops_release(struct file *file)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* safety check */
-	if (!radio) {
-		retval = -ENODEV;
-		goto done;
-	}
-
-	mutex_lock(&radio->disconnect_lock);
-	radio->users--;
-	if (radio->users == 0) {
-		if (radio->disconnected) {
-			video_unregister_device(radio->videodev);
-			kfree(radio->buffer);
-			kfree(radio);
-			goto unlock;
-		}
-
-		/* stop rds reception */
-		cancel_delayed_work_sync(&radio->work);
-
-		/* cancel read processes */
-		wake_up_interruptible(&radio->read_queue);
-
-		/* stop radio */
-		retval = si470x_stop(radio);
-		usb_autopm_put_interface(radio->intf);
-	}
-unlock:
-	mutex_unlock(&radio->disconnect_lock);
-done:
-	return retval;
-}
-
-
-/*
- * si470x_fops - file operations interface
- */
-static const struct v4l2_file_operations si470x_fops = {
-	.owner		= THIS_MODULE,
-	.read		= si470x_fops_read,
-	.poll		= si470x_fops_poll,
-	.ioctl		= video_ioctl2,
-	.open		= si470x_fops_open,
-	.release	= si470x_fops_release,
-};
-
-
-
-/**************************************************************************
- * Video4Linux Interface
- **************************************************************************/
-
-/*
- * si470x_v4l2_queryctrl - query control
- */
-static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
-	{
-		.id		= V4L2_CID_AUDIO_VOLUME,
-		.type		= V4L2_CTRL_TYPE_INTEGER,
-		.name		= "Volume",
-		.minimum	= 0,
-		.maximum	= 15,
-		.step		= 1,
-		.default_value	= 15,
-	},
-	{
-		.id		= V4L2_CID_AUDIO_MUTE,
-		.type		= V4L2_CTRL_TYPE_BOOLEAN,
-		.name		= "Mute",
-		.minimum	= 0,
-		.maximum	= 1,
-		.step		= 1,
-		.default_value	= 1,
-	},
-};
-
-
-/*
- * si470x_vidioc_querycap - query device capabilities
- */
-static int si470x_vidioc_querycap(struct file *file, void *priv,
-		struct v4l2_capability *capability)
-{
-	struct si470x_device *radio = video_drvdata(file);
-
-	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
-	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
-	usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info));
-	capability->version = DRIVER_KERNEL_VERSION;
-	capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
-		V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-
-	return 0;
-}
-
-
-/*
- * si470x_vidioc_queryctrl - enumerate control items
- */
-static int si470x_vidioc_queryctrl(struct file *file, void *priv,
-		struct v4l2_queryctrl *qc)
-{
-	unsigned char i = 0;
-	int retval = -EINVAL;
-
-	/* abort if qc->id is below V4L2_CID_BASE */
-	if (qc->id < V4L2_CID_BASE)
-		goto done;
-
-	/* search video control */
-	for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
-		if (qc->id == si470x_v4l2_queryctrl[i].id) {
-			memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
-			retval = 0; /* found */
-			break;
-		}
-	}
-
-	/* disable unsupported base controls */
-	/* to satisfy kradio and such apps */
-	if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
-		qc->flags = V4L2_CTRL_FLAG_DISABLED;
-		retval = 0;
-	}
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": query controls failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_g_ctrl - get the value of a control
- */
-static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
-		struct v4l2_control *ctrl)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* safety checks */
-	if (radio->disconnected) {
-		retval = -EIO;
-		goto done;
-	}
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_VOLUME:
-		ctrl->value = radio->registers[SYSCONFIG2] &
-				SYSCONFIG2_VOLUME;
-		break;
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = ((radio->registers[POWERCFG] &
-				POWERCFG_DMUTE) == 0) ? 1 : 0;
-		break;
-	default:
-		retval = -EINVAL;
-	}
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": get control failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_s_ctrl - set the value of a control
- */
-static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
-		struct v4l2_control *ctrl)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* safety checks */
-	if (radio->disconnected) {
-		retval = -EIO;
-		goto done;
-	}
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_VOLUME:
-		radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
-		radio->registers[SYSCONFIG2] |= ctrl->value;
-		retval = si470x_set_register(radio, SYSCONFIG2);
-		break;
-	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value == 1)
-			radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
-		else
-			radio->registers[POWERCFG] |= POWERCFG_DMUTE;
-		retval = si470x_set_register(radio, POWERCFG);
-		break;
-	default:
-		retval = -EINVAL;
-	}
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": set control failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_g_audio - get audio attributes
- */
-static int si470x_vidioc_g_audio(struct file *file, void *priv,
-		struct v4l2_audio *audio)
-{
-	/* driver constants */
-	audio->index = 0;
-	strcpy(audio->name, "Radio");
-	audio->capability = V4L2_AUDCAP_STEREO;
-	audio->mode = 0;
-
-	return 0;
-}
-
-
-/*
- * si470x_vidioc_g_tuner - get tuner attributes
- */
-static int si470x_vidioc_g_tuner(struct file *file, void *priv,
-		struct v4l2_tuner *tuner)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* safety checks */
-	if (radio->disconnected) {
-		retval = -EIO;
-		goto done;
-	}
-	if (tuner->index != 0) {
-		retval = -EINVAL;
-		goto done;
-	}
-
-	retval = si470x_get_register(radio, STATUSRSSI);
-	if (retval < 0)
-		goto done;
-
-	/* driver constants */
-	strcpy(tuner->name, "FM");
-	tuner->type = V4L2_TUNER_RADIO;
-	tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
-
-	/* range limits */
-	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
-	/* 0: 87.5 - 108 MHz (USA, Europe, default) */
-	default:
-		tuner->rangelow  =  87.5 * FREQ_MUL;
-		tuner->rangehigh = 108   * FREQ_MUL;
-		break;
-	/* 1: 76   - 108 MHz (Japan wide band) */
-	case 1 :
-		tuner->rangelow  =  76   * FREQ_MUL;
-		tuner->rangehigh = 108   * FREQ_MUL;
-		break;
-	/* 2: 76   -  90 MHz (Japan) */
-	case 2 :
-		tuner->rangelow  =  76   * FREQ_MUL;
-		tuner->rangehigh =  90   * FREQ_MUL;
-		break;
-	};
-
-	/* stereo indicator == stereo (instead of mono) */
-	if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
-		tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
-	else
-		tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-
-	/* mono/stereo selector */
-	if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
-		tuner->audmode = V4L2_TUNER_MODE_STEREO;
-	else
-		tuner->audmode = V4L2_TUNER_MODE_MONO;
-
-	/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
-	/* measured in units of dbÂµV in 1 db increments (max at ~75 dbÂµV) */
-	tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
-	/* the ideal factor is 0xffff/75 = 873,8 */
-	tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
-
-	/* automatic frequency control: -1: freq to low, 1 freq to high */
-	/* AFCRL does only indicate that freq. differs, not if too low/high */
-	tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0;
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": get tuner failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_s_tuner - set tuner attributes
- */
-static int si470x_vidioc_s_tuner(struct file *file, void *priv,
-		struct v4l2_tuner *tuner)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = -EINVAL;
-
-	/* safety checks */
-	if (radio->disconnected) {
-		retval = -EIO;
-		goto done;
-	}
-	if (tuner->index != 0)
-		goto done;
-
-	/* mono/stereo selector */
-	switch (tuner->audmode) {
-	case V4L2_TUNER_MODE_MONO:
-		radio->registers[POWERCFG] |= POWERCFG_MONO;  /* force mono */
-		break;
-	case V4L2_TUNER_MODE_STEREO:
-		radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
-		break;
-	default:
-		goto done;
-	}
-
-	retval = si470x_set_register(radio, POWERCFG);
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": set tuner failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_g_frequency - get tuner or modulator radio frequency
- */
-static int si470x_vidioc_g_frequency(struct file *file, void *priv,
-		struct v4l2_frequency *freq)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* safety checks */
-	if (radio->disconnected) {
-		retval = -EIO;
-		goto done;
-	}
-	if (freq->tuner != 0) {
-		retval = -EINVAL;
-		goto done;
-	}
-
-	freq->type = V4L2_TUNER_RADIO;
-	retval = si470x_get_freq(radio, &freq->frequency);
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": get frequency failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_s_frequency - set tuner or modulator radio frequency
- */
-static int si470x_vidioc_s_frequency(struct file *file, void *priv,
-		struct v4l2_frequency *freq)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* safety checks */
-	if (radio->disconnected) {
-		retval = -EIO;
-		goto done;
-	}
-	if (freq->tuner != 0) {
-		retval = -EINVAL;
-		goto done;
-	}
-
-	retval = si470x_set_freq(radio, freq->frequency);
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": set frequency failed with %d\n", retval);
-	return retval;
-}
-
-
-/*
- * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
- */
-static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
-		struct v4l2_hw_freq_seek *seek)
-{
-	struct si470x_device *radio = video_drvdata(file);
-	int retval = 0;
-
-	/* safety checks */
-	if (radio->disconnected) {
-		retval = -EIO;
-		goto done;
-	}
-	if (seek->tuner != 0) {
-		retval = -EINVAL;
-		goto done;
-	}
-
-	retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward);
-
-done:
-	if (retval < 0)
-		printk(KERN_WARNING DRIVER_NAME
-			": set hardware frequency seek failed with %d\n",
-			retval);
-	return retval;
-}
-
-
-/*
- * si470x_ioctl_ops - video device ioctl operations
- */
-static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
-	.vidioc_querycap	= si470x_vidioc_querycap,
-	.vidioc_queryctrl	= si470x_vidioc_queryctrl,
-	.vidioc_g_ctrl		= si470x_vidioc_g_ctrl,
-	.vidioc_s_ctrl		= si470x_vidioc_s_ctrl,
-	.vidioc_g_audio		= si470x_vidioc_g_audio,
-	.vidioc_g_tuner		= si470x_vidioc_g_tuner,
-	.vidioc_s_tuner		= si470x_vidioc_s_tuner,
-	.vidioc_g_frequency	= si470x_vidioc_g_frequency,
-	.vidioc_s_frequency	= si470x_vidioc_s_frequency,
-	.vidioc_s_hw_freq_seek	= si470x_vidioc_s_hw_freq_seek,
-};
-
-
-/*
- * si470x_viddev_template - video device interface
- */
-static struct video_device si470x_viddev_template = {
-	.fops			= &si470x_fops,
-	.name			= DRIVER_NAME,
-	.release		= video_device_release,
-	.ioctl_ops		= &si470x_ioctl_ops,
-};
-
-
-
-/**************************************************************************
- * USB Interface
- **************************************************************************/
-
-/*
- * si470x_usb_driver_probe - probe for the device
- */
-static int si470x_usb_driver_probe(struct usb_interface *intf,
-		const struct usb_device_id *id)
-{
-	struct si470x_device *radio;
-	int retval = 0;
-
-	/* private data allocation and initialization */
-	radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
-	if (!radio) {
-		retval = -ENOMEM;
-		goto err_initial;
-	}
-	radio->users = 0;
-	radio->disconnected = 0;
-	radio->usbdev = interface_to_usbdev(intf);
-	radio->intf = intf;
-	mutex_init(&radio->disconnect_lock);
-	mutex_init(&radio->lock);
-
-	/* video device allocation and initialization */
-	radio->videodev = video_device_alloc();
-	if (!radio->videodev) {
-		retval = -ENOMEM;
-		goto err_radio;
-	}
-	memcpy(radio->videodev, &si470x_viddev_template,
-			sizeof(si470x_viddev_template));
-	video_set_drvdata(radio->videodev, radio);
-
-	/* show some infos about the specific si470x device */
-	if (si470x_get_all_registers(radio) < 0) {
-		retval = -EIO;
-		goto err_video;
-	}
-	printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
-			radio->registers[DEVICEID], radio->registers[CHIPID]);
-
-	/* get software and hardware versions */
-	if (si470x_get_scratch_page_versions(radio) < 0) {
-		retval = -EIO;
-		goto err_video;
-	}
-	printk(KERN_INFO DRIVER_NAME
-			": software version %d, hardware version %d\n",
-			radio->software_version, radio->hardware_version);
-
-	/* check if device and firmware is current */
-	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
-			< RADIO_SW_VERSION_CURRENT) {
-		printk(KERN_WARNING DRIVER_NAME
-			": This driver is known to work with "
-			"firmware version %hu,\n", RADIO_SW_VERSION_CURRENT);
-		printk(KERN_WARNING DRIVER_NAME
-			": but the device has firmware version %hu.\n",
-			radio->registers[CHIPID] & CHIPID_FIRMWARE);
-		printk(KERN_WARNING DRIVER_NAME
-			": If you have some trouble using this driver,\n");
-		printk(KERN_WARNING DRIVER_NAME
-			": please report to V4L ML at "
-			"linux-media@vger.kernel.org\n");
-	}
-
-	/* set initial frequency */
-	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
-
-	/* set led to connect state */
-	si470x_set_led_state(radio, BLINK_GREEN_LED);
-
-	/* rds buffer allocation */
-	radio->buf_size = rds_buf * 3;
-	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
-	if (!radio->buffer) {
-		retval = -EIO;
-		goto err_video;
-	}
-
-	/* rds buffer configuration */
-	radio->wr_index = 0;
-	radio->rd_index = 0;
-	init_waitqueue_head(&radio->read_queue);
-
-	/* prepare rds work function */
-	INIT_DELAYED_WORK(&radio->work, si470x_work);
-
-	/* register video device */
-	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
-	if (retval) {
-		printk(KERN_WARNING DRIVER_NAME
-				": Could not register video device\n");
-		goto err_all;
-	}
-	usb_set_intfdata(intf, radio);
-
-	return 0;
-err_all:
-	kfree(radio->buffer);
-err_video:
-	video_device_release(radio->videodev);
-err_radio:
-	kfree(radio);
-err_initial:
-	return retval;
-}
-
-
-/*
- * si470x_usb_driver_suspend - suspend the device
- */
-static int si470x_usb_driver_suspend(struct usb_interface *intf,
-		pm_message_t message)
-{
-	struct si470x_device *radio = usb_get_intfdata(intf);
-
-	printk(KERN_INFO DRIVER_NAME ": suspending now...\n");
-
-	cancel_delayed_work_sync(&radio->work);
-
-	return 0;
-}
-
-
-/*
- * si470x_usb_driver_resume - resume the device
- */
-static int si470x_usb_driver_resume(struct usb_interface *intf)
-{
-	struct si470x_device *radio = usb_get_intfdata(intf);
-
-	printk(KERN_INFO DRIVER_NAME ": resuming now...\n");
-
-	mutex_lock(&radio->lock);
-	if (radio->users && radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS)
-		schedule_delayed_work(&radio->work,
-			msecs_to_jiffies(rds_poll_time));
-	mutex_unlock(&radio->lock);
-
-	return 0;
-}
-
-
-/*
- * si470x_usb_driver_disconnect - disconnect the device
- */
-static void si470x_usb_driver_disconnect(struct usb_interface *intf)
-{
-	struct si470x_device *radio = usb_get_intfdata(intf);
-
-	mutex_lock(&radio->disconnect_lock);
-	radio->disconnected = 1;
-	cancel_delayed_work_sync(&radio->work);
-	usb_set_intfdata(intf, NULL);
-	if (radio->users == 0) {
-		/* set led to disconnect state */
-		si470x_set_led_state(radio, BLINK_ORANGE_LED);
-
-		video_unregister_device(radio->videodev);
-		kfree(radio->buffer);
-		kfree(radio);
-	}
-	mutex_unlock(&radio->disconnect_lock);
-}
-
-
-/*
- * si470x_usb_driver - usb driver interface
- */
-static struct usb_driver si470x_usb_driver = {
-	.name			= DRIVER_NAME,
-	.probe			= si470x_usb_driver_probe,
-	.disconnect		= si470x_usb_driver_disconnect,
-	.suspend		= si470x_usb_driver_suspend,
-	.resume			= si470x_usb_driver_resume,
-	.id_table		= si470x_usb_driver_id_table,
-	.supports_autosuspend	= 1,
-};
-
-
-
-/**************************************************************************
- * Module Interface
- **************************************************************************/
-
-/*
- * si470x_module_init - module init
- */
-static int __init si470x_module_init(void)
-{
-	printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
-	return usb_register(&si470x_usb_driver);
-}
-
-
-/*
- * si470x_module_exit - module exit
- */
-static void __exit si470x_module_exit(void)
-{
-	usb_deregister(&si470x_usb_driver);
-}
-
-
-module_init(si470x_module_init);
-module_exit(si470x_module_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
new file mode 100644
index 0000000..170bbe5
--- /dev/null
+++ b/drivers/media/radio/radio-si4713.c
@@ -0,0 +1,366 @@
+/*
+ * drivers/media/radio/radio-si4713.c
+ *
+ * Platform Driver for Silicon Labs Si4713 FM Radio Transmitter:
+ *
+ * Copyright (c) 2008 Instituto Nokia de Tecnologia - INdT
+ * Contact: Eduardo Valentin <eduardo.valentin@nokia.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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/radio-si4713.h>
+
+/* module parameters */
+static int radio_nr = -1;	/* radio device minor (-1 ==> auto assign) */
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(radio_nr,
+		 "Minor number for radio device (-1 ==> auto assign)");
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
+MODULE_DESCRIPTION("Platform driver for Si4713 FM Radio Transmitter");
+MODULE_VERSION("0.0.1");
+
+/* Driver state struct */
+struct radio_si4713_device {
+	struct v4l2_device		v4l2_dev;
+	struct video_device		*radio_dev;
+};
+
+/* radio_si4713_fops - file operations interface */
+static const struct v4l2_file_operations radio_si4713_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= video_ioctl2,
+};
+
+/* Video4Linux Interface */
+static int radio_si4713_fill_audout(struct v4l2_audioout *vao)
+{
+	/* TODO: check presence of audio output */
+	strlcpy(vao->name, "FM Modulator Audio Out", 32);
+
+	return 0;
+}
+
+static int radio_si4713_enumaudout(struct file *file, void *priv,
+						struct v4l2_audioout *vao)
+{
+	return radio_si4713_fill_audout(vao);
+}
+
+static int radio_si4713_g_audout(struct file *file, void *priv,
+					struct v4l2_audioout *vao)
+{
+	int rval = radio_si4713_fill_audout(vao);
+
+	vao->index = 0;
+
+	return rval;
+}
+
+static int radio_si4713_s_audout(struct file *file, void *priv,
+					struct v4l2_audioout *vao)
+{
+	return vao->index ? -EINVAL : 0;
+}
+
+/* radio_si4713_querycap - query device capabilities */
+static int radio_si4713_querycap(struct file *file, void *priv,
+					struct v4l2_capability *capability)
+{
+	struct radio_si4713_device *rsdev;
+
+	rsdev = video_get_drvdata(video_devdata(file));
+
+	strlcpy(capability->driver, "radio-si4713", sizeof(capability->driver));
+	strlcpy(capability->card, "Silicon Labs Si4713 Modulator",
+				sizeof(capability->card));
+	capability->capabilities = V4L2_CAP_MODULATOR | V4L2_CAP_RDS_OUTPUT;
+
+	return 0;
+}
+
+/* radio_si4713_queryctrl - enumerate control items */
+static int radio_si4713_queryctrl(struct file *file, void *priv,
+						struct v4l2_queryctrl *qc)
+{
+	/* Must be sorted from low to high control ID! */
+	static const u32 user_ctrls[] = {
+		V4L2_CID_USER_CLASS,
+		V4L2_CID_AUDIO_MUTE,
+		0
+	};
+
+	/* Must be sorted from low to high control ID! */
+	static const u32 fmtx_ctrls[] = {
+		V4L2_CID_FM_TX_CLASS,
+		V4L2_CID_RDS_TX_DEVIATION,
+		V4L2_CID_RDS_TX_PI,
+		V4L2_CID_RDS_TX_PTY,
+		V4L2_CID_RDS_TX_PS_NAME,
+		V4L2_CID_RDS_TX_RADIO_TEXT,
+		V4L2_CID_AUDIO_LIMITER_ENABLED,
+		V4L2_CID_AUDIO_LIMITER_RELEASE_TIME,
+		V4L2_CID_AUDIO_LIMITER_DEVIATION,
+		V4L2_CID_AUDIO_COMPRESSION_ENABLED,
+		V4L2_CID_AUDIO_COMPRESSION_GAIN,
+		V4L2_CID_AUDIO_COMPRESSION_THRESHOLD,
+		V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME,
+		V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME,
+		V4L2_CID_PILOT_TONE_ENABLED,
+		V4L2_CID_PILOT_TONE_DEVIATION,
+		V4L2_CID_PILOT_TONE_FREQUENCY,
+		V4L2_CID_TUNE_PREEMPHASIS,
+		V4L2_CID_TUNE_POWER_LEVEL,
+		V4L2_CID_TUNE_ANTENNA_CAPACITOR,
+		0
+	};
+	static const u32 *ctrl_classes[] = {
+		user_ctrls,
+		fmtx_ctrls,
+		NULL
+	};
+	struct radio_si4713_device *rsdev;
+
+	rsdev = video_get_drvdata(video_devdata(file));
+
+	qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);
+	if (qc->id == 0)
+		return -EINVAL;
+
+	if (qc->id == V4L2_CID_USER_CLASS || qc->id == V4L2_CID_FM_TX_CLASS)
+		return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);
+
+	return v4l2_device_call_until_err(&rsdev->v4l2_dev, 0, core,
+						queryctrl, qc);
+}
+
+/*
+ * v4l2 ioctl call backs.
+ * we are just a wrapper for v4l2_sub_devs.
+ */
+static inline struct v4l2_device *get_v4l2_dev(struct file *file)
+{
+	return &((struct radio_si4713_device *)video_drvdata(file))->v4l2_dev;
+}
+
+static int radio_si4713_g_ext_ctrls(struct file *file, void *p,
+						struct v4l2_ext_controls *vecs)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
+							g_ext_ctrls, vecs);
+}
+
+static int radio_si4713_s_ext_ctrls(struct file *file, void *p,
+						struct v4l2_ext_controls *vecs)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
+							s_ext_ctrls, vecs);
+}
+
+static int radio_si4713_g_ctrl(struct file *file, void *p,
+						struct v4l2_control *vc)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
+							g_ctrl, vc);
+}
+
+static int radio_si4713_s_ctrl(struct file *file, void *p,
+						struct v4l2_control *vc)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
+							s_ctrl, vc);
+}
+
+static int radio_si4713_g_modulator(struct file *file, void *p,
+						struct v4l2_modulator *vm)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
+							g_modulator, vm);
+}
+
+static int radio_si4713_s_modulator(struct file *file, void *p,
+						struct v4l2_modulator *vm)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
+							s_modulator, vm);
+}
+
+static int radio_si4713_g_frequency(struct file *file, void *p,
+						struct v4l2_frequency *vf)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
+							g_frequency, vf);
+}
+
+static int radio_si4713_s_frequency(struct file *file, void *p,
+						struct v4l2_frequency *vf)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, tuner,
+							s_frequency, vf);
+}
+
+static long radio_si4713_default(struct file *file, void *p, int cmd, void *arg)
+{
+	return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
+							ioctl, cmd, arg);
+}
+
+static struct v4l2_ioctl_ops radio_si4713_ioctl_ops = {
+	.vidioc_enumaudout	= radio_si4713_enumaudout,
+	.vidioc_g_audout	= radio_si4713_g_audout,
+	.vidioc_s_audout	= radio_si4713_s_audout,
+	.vidioc_querycap	= radio_si4713_querycap,
+	.vidioc_queryctrl	= radio_si4713_queryctrl,
+	.vidioc_g_ext_ctrls	= radio_si4713_g_ext_ctrls,
+	.vidioc_s_ext_ctrls	= radio_si4713_s_ext_ctrls,
+	.vidioc_g_ctrl		= radio_si4713_g_ctrl,
+	.vidioc_s_ctrl		= radio_si4713_s_ctrl,
+	.vidioc_g_modulator	= radio_si4713_g_modulator,
+	.vidioc_s_modulator	= radio_si4713_s_modulator,
+	.vidioc_g_frequency	= radio_si4713_g_frequency,
+	.vidioc_s_frequency	= radio_si4713_s_frequency,
+	.vidioc_default		= radio_si4713_default,
+};
+
+/* radio_si4713_vdev_template - video device interface */
+static struct video_device radio_si4713_vdev_template = {
+	.fops			= &radio_si4713_fops,
+	.name			= "radio-si4713",
+	.release		= video_device_release,
+	.ioctl_ops		= &radio_si4713_ioctl_ops,
+};
+
+/* Platform driver interface */
+/* radio_si4713_pdriver_probe - probe for the device */
+static int radio_si4713_pdriver_probe(struct platform_device *pdev)
+{
+	struct radio_si4713_platform_data *pdata = pdev->dev.platform_data;
+	struct radio_si4713_device *rsdev;
+	struct i2c_adapter *adapter;
+	struct v4l2_subdev *sd;
+	int rval = 0;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Cannot proceed without platform data.\n");
+		rval = -EINVAL;
+		goto exit;
+	}
+
+	rsdev = kzalloc(sizeof *rsdev, GFP_KERNEL);
+	if (!rsdev) {
+		dev_err(&pdev->dev, "Failed to alloc video device.\n");
+		rval = -ENOMEM;
+		goto exit;
+	}
+
+	rval = v4l2_device_register(&pdev->dev, &rsdev->v4l2_dev);
+	if (rval) {
+		dev_err(&pdev->dev, "Failed to register v4l2 device.\n");
+		goto free_rsdev;
+	}
+
+	adapter = i2c_get_adapter(pdata->i2c_bus);
+	if (!adapter) {
+		dev_err(&pdev->dev, "Cannot get i2c adapter %d\n",
+							pdata->i2c_bus);
+		rval = -ENODEV;
+		goto unregister_v4l2_dev;
+	}
+
+	sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter, "si4713_i2c",
+					pdata->subdev_board_info, NULL);
+	if (!sd) {
+		dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
+		rval = -ENODEV;
+		goto unregister_v4l2_dev;
+	}
+
+	rsdev->radio_dev = video_device_alloc();
+	if (!rsdev->radio_dev) {
+		dev_err(&pdev->dev, "Failed to alloc video device.\n");
+		rval = -ENOMEM;
+		goto unregister_v4l2_dev;
+	}
+
+	memcpy(rsdev->radio_dev, &radio_si4713_vdev_template,
+			sizeof(radio_si4713_vdev_template));
+	video_set_drvdata(rsdev->radio_dev, rsdev);
+	if (video_register_device(rsdev->radio_dev, VFL_TYPE_RADIO, radio_nr)) {
+		dev_err(&pdev->dev, "Could not register video device.\n");
+		rval = -EIO;
+		goto free_vdev;
+	}
+	dev_info(&pdev->dev, "New device successfully probed\n");
+
+	goto exit;
+
+free_vdev:
+	video_device_release(rsdev->radio_dev);
+unregister_v4l2_dev:
+	v4l2_device_unregister(&rsdev->v4l2_dev);
+free_rsdev:
+	kfree(rsdev);
+exit:
+	return rval;
+}
+
+/* radio_si4713_pdriver_remove - remove the device */
+static int __exit radio_si4713_pdriver_remove(struct platform_device *pdev)
+{
+	struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
+	struct radio_si4713_device *rsdev = container_of(v4l2_dev,
+						struct radio_si4713_device,
+						v4l2_dev);
+
+	video_unregister_device(rsdev->radio_dev);
+	v4l2_device_unregister(&rsdev->v4l2_dev);
+	kfree(rsdev);
+
+	return 0;
+}
+
+static struct platform_driver radio_si4713_pdriver = {
+	.driver		= {
+		.name	= "radio-si4713",
+	},
+	.probe		= radio_si4713_pdriver_probe,
+	.remove         = __exit_p(radio_si4713_pdriver_remove),
+};
+
+/* Module Interface */
+static int __init radio_si4713_module_init(void)
+{
+	return platform_driver_register(&radio_si4713_pdriver);
+}
+
+static void __exit radio_si4713_module_exit(void)
+{
+	platform_driver_unregister(&radio_si4713_pdriver);
+}
+
+module_init(radio_si4713_module_init);
+module_exit(radio_si4713_module_exit);
+
diff --git a/drivers/media/radio/si470x/Kconfig b/drivers/media/radio/si470x/Kconfig
new file mode 100644
index 0000000..a466654
--- /dev/null
+++ b/drivers/media/radio/si470x/Kconfig
@@ -0,0 +1,37 @@
+config USB_SI470X
+	tristate "Silicon Labs Si470x FM Radio Receiver support with USB"
+	depends on USB && RADIO_SI470X
+	---help---
+	  This is a driver for USB devices with the Silicon Labs SI470x
+	  chip. Currently these devices are known to work:
+	  - 10c4:818a: Silicon Labs USB FM Radio Reference Design
+	  - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music)
+	  - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
+	  - 10c5:819a: Sanei Electric FM USB Radio (aka DealExtreme.com PCear)
+
+	  Sound is provided by the ALSA USB Audio/MIDI driver. Therefore
+	  if you don't want to use the device solely for RDS receiving,
+	  it is recommended to also select SND_USB_AUDIO.
+
+	  Please have a look at the documentation, especially on how
+	  to redirect the audio stream from the radio to your sound device:
+	  Documentation/video4linux/si470x.txt
+
+	  Say Y here if you want to connect this type of radio to your
+	  computer's USB port.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-usb-si470x.
+
+config I2C_SI470X
+	tristate "Silicon Labs Si470x FM Radio Receiver support with I2C"
+	depends on I2C && RADIO_SI470X && !USB_SI470X
+	---help---
+	  This is a driver for I2C devices with the Silicon Labs SI470x
+	  chip.
+
+	  Say Y here if you want to connect this type of radio to your
+	  computer's I2C port.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called radio-i2c-si470x.
diff --git a/drivers/media/radio/si470x/Makefile b/drivers/media/radio/si470x/Makefile
new file mode 100644
index 0000000..0696481
--- /dev/null
+++ b/drivers/media/radio/si470x/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for radios with Silicon Labs Si470x FM Radio Receivers
+#
+
+radio-usb-si470x-objs	:= radio-si470x-usb.o radio-si470x-common.o
+radio-i2c-si470x-objs	:= radio-si470x-i2c.o radio-si470x-common.o
+
+obj-$(CONFIG_USB_SI470X) += radio-usb-si470x.o
+obj-$(CONFIG_I2C_SI470X) += radio-i2c-si470x.o
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
new file mode 100644
index 0000000..f33315f
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -0,0 +1,798 @@
+/*
+ *  drivers/media/radio/si470x/radio-si470x-common.c
+ *
+ *  Driver for radios with Silicon Labs Si470x FM Radio Receivers
+ *
+ *  Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/*
+ * History:
+ * 2008-01-12	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Version 1.0.0
+ *		- First working version
+ * 2008-01-13	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Version 1.0.1
+ *		- Improved error handling, every function now returns errno
+ *		- Improved multi user access (start/mute/stop)
+ *		- Channel doesn't get lost anymore after start/mute/stop
+ *		- RDS support added (polling mode via interrupt EP 1)
+ *		- marked default module parameters with *value*
+ *		- switched from bit structs to bit masks
+ *		- header file cleaned and integrated
+ * 2008-01-14	Tobias Lorenz <tobias.lorenz@gmx.net>
+ * 		Version 1.0.2
+ * 		- hex values are now lower case
+ * 		- commented USB ID for ADS/Tech moved on todo list
+ * 		- blacklisted si470x in hid-quirks.c
+ * 		- rds buffer handling functions integrated into *_work, *_read
+ * 		- rds_command in si470x_poll exchanged against simple retval
+ * 		- check for firmware version 15
+ * 		- code order and prototypes still remain the same
+ * 		- spacing and bottom of band codes remain the same
+ * 2008-01-16	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Version 1.0.3
+ * 		- code reordered to avoid function prototypes
+ *		- switch/case defaults are now more user-friendly
+ *		- unified comment style
+ *		- applied all checkpatch.pl v1.12 suggestions
+ *		  except the warning about the too long lines with bit comments
+ *		- renamed FMRADIO to RADIO to cut line length (checkpatch.pl)
+ * 2008-01-22	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Version 1.0.4
+ *		- avoid poss. locking when doing copy_to_user which may sleep
+ *		- RDS is automatically activated on read now
+ *		- code cleaned of unnecessary rds_commands
+ *		- USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
+ *		  (thanks to Guillaume RAMOUSSE)
+ * 2008-01-27	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Version 1.0.5
+ *		- number of seek_retries changed to tune_timeout
+ *		- fixed problem with incomplete tune operations by own buffers
+ *		- optimization of variables and printf types
+ *		- improved error logging
+ * 2008-01-31	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Oliver Neukum <oliver@neukum.org>
+ *		Version 1.0.6
+ *		- fixed coverity checker warnings in *_usb_driver_disconnect
+ *		- probe()/open() race by correct ordering in probe()
+ *		- DMA coherency rules by separate allocation of all buffers
+ *		- use of endianness macros
+ *		- abuse of spinlock, replaced by mutex
+ *		- racy handling of timer in disconnect,
+ *		  replaced by delayed_work
+ *		- racy interruptible_sleep_on(),
+ *		  replaced with wait_event_interruptible()
+ *		- handle signals in read()
+ * 2008-02-08	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Oliver Neukum <oliver@neukum.org>
+ *		Version 1.0.7
+ *		- usb autosuspend support
+ *		- unplugging fixed
+ * 2008-05-07	Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		Version 1.0.8
+ *		- hardware frequency seek support
+ *		- afc indication
+ *		- more safety checks, let si470x_get_freq return errno
+ *		- vidioc behavior corrected according to v4l2 spec
+ * 2008-10-20	Alexey Klimov <klimov.linux@gmail.com>
+ * 		- add support for KWorld USB FM Radio FM700
+ * 		- blacklisted KWorld radio in hid-core.c and hid-ids.h
+ * 2008-12-03	Mark Lord <mlord@pobox.com>
+ *		- add support for DealExtreme USB Radio
+ * 2009-01-31	Bob Ross <pigiron@gmx.com>
+ *		- correction of stereo detection/setting
+ *		- correction of signal strength indicator scaling
+ * 2009-01-31	Rick Bronson <rick@efn.org>
+ *		Tobias Lorenz <tobias.lorenz@gmx.net>
+ *		- add LED status output
+ *		- get HW/SW version from scratchpad
+ * 2009-06-16   Edouard Lafargue <edouard@lafargue.name>
+ *		Version 1.0.10
+ *		- add support for interrupt mode for RDS endpoint,
+ *                instead of polling.
+ *                Improves RDS reception significantly
+ */
+
+
+/* kernel includes */
+#include "radio-si470x.h"
+
+
+
+/**************************************************************************
+ * Module Parameters
+ **************************************************************************/
+
+/* Spacing (kHz) */
+/* 0: 200 kHz (USA, Australia) */
+/* 1: 100 kHz (Europe, Japan) */
+/* 2:  50 kHz */
+static unsigned short space = 2;
+module_param(space, ushort, 0444);
+MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
+
+/* Bottom of Band (MHz) */
+/* 0: 87.5 - 108 MHz (USA, Europe)*/
+/* 1: 76   - 108 MHz (Japan wide band) */
+/* 2: 76   -  90 MHz (Japan) */
+static unsigned short band = 1;
+module_param(band, ushort, 0444);
+MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
+
+/* De-emphasis */
+/* 0: 75 us (USA) */
+/* 1: 50 us (Europe, Australia, Japan) */
+static unsigned short de = 1;
+module_param(de, ushort, 0444);
+MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
+
+/* Tune timeout */
+static unsigned int tune_timeout = 3000;
+module_param(tune_timeout, uint, 0644);
+MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
+
+/* Seek timeout */
+static unsigned int seek_timeout = 5000;
+module_param(seek_timeout, uint, 0644);
+MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
+
+
+
+/**************************************************************************
+ * Generic Functions
+ **************************************************************************/
+
+/*
+ * si470x_set_chan - set the channel
+ */
+static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
+{
+	int retval;
+	unsigned long timeout;
+	bool timed_out = 0;
+
+	/* start tuning */
+	radio->registers[CHANNEL] &= ~CHANNEL_CHAN;
+	radio->registers[CHANNEL] |= CHANNEL_TUNE | chan;
+	retval = si470x_set_register(radio, CHANNEL);
+	if (retval < 0)
+		goto done;
+
+	/* wait till tune operation has completed */
+	timeout = jiffies + msecs_to_jiffies(tune_timeout);
+	do {
+		retval = si470x_get_register(radio, STATUSRSSI);
+		if (retval < 0)
+			goto stop;
+		timed_out = time_after(jiffies, timeout);
+	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
+		(!timed_out));
+	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
+		dev_warn(&radio->videodev->dev, "tune does not complete\n");
+	if (timed_out)
+		dev_warn(&radio->videodev->dev,
+			"tune timed out after %u ms\n", tune_timeout);
+
+stop:
+	/* stop tuning */
+	radio->registers[CHANNEL] &= ~CHANNEL_TUNE;
+	retval = si470x_set_register(radio, CHANNEL);
+
+done:
+	return retval;
+}
+
+
+/*
+ * si470x_get_freq - get the frequency
+ */
+static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
+{
+	unsigned int spacing, band_bottom;
+	unsigned short chan;
+	int retval;
+
+	/* Spacing (kHz) */
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
+	/* 0: 200 kHz (USA, Australia) */
+	case 0:
+		spacing = 0.200 * FREQ_MUL; break;
+	/* 1: 100 kHz (Europe, Japan) */
+	case 1:
+		spacing = 0.100 * FREQ_MUL; break;
+	/* 2:  50 kHz */
+	default:
+		spacing = 0.050 * FREQ_MUL; break;
+	};
+
+	/* Bottom of Band (MHz) */
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
+	/* 0: 87.5 - 108 MHz (USA, Europe) */
+	case 0:
+		band_bottom = 87.5 * FREQ_MUL; break;
+	/* 1: 76   - 108 MHz (Japan wide band) */
+	default:
+		band_bottom = 76   * FREQ_MUL; break;
+	/* 2: 76   -  90 MHz (Japan) */
+	case 2:
+		band_bottom = 76   * FREQ_MUL; break;
+	};
+
+	/* read channel */
+	retval = si470x_get_register(radio, READCHAN);
+	chan = radio->registers[READCHAN] & READCHAN_READCHAN;
+
+	/* Frequency (MHz) = Spacing (kHz) x Channel + Bottom of Band (MHz) */
+	*freq = chan * spacing + band_bottom;
+
+	return retval;
+}
+
+
+/*
+ * si470x_set_freq - set the frequency
+ */
+int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
+{
+	unsigned int spacing, band_bottom;
+	unsigned short chan;
+
+	/* Spacing (kHz) */
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
+	/* 0: 200 kHz (USA, Australia) */
+	case 0:
+		spacing = 0.200 * FREQ_MUL; break;
+	/* 1: 100 kHz (Europe, Japan) */
+	case 1:
+		spacing = 0.100 * FREQ_MUL; break;
+	/* 2:  50 kHz */
+	default:
+		spacing = 0.050 * FREQ_MUL; break;
+	};
+
+	/* Bottom of Band (MHz) */
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
+	/* 0: 87.5 - 108 MHz (USA, Europe) */
+	case 0:
+		band_bottom = 87.5 * FREQ_MUL; break;
+	/* 1: 76   - 108 MHz (Japan wide band) */
+	default:
+		band_bottom = 76   * FREQ_MUL; break;
+	/* 2: 76   -  90 MHz (Japan) */
+	case 2:
+		band_bottom = 76   * FREQ_MUL; break;
+	};
+
+	/* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
+	chan = (freq - band_bottom) / spacing;
+
+	return si470x_set_chan(radio, chan);
+}
+
+
+/*
+ * si470x_set_seek - set seek
+ */
+static int si470x_set_seek(struct si470x_device *radio,
+		unsigned int wrap_around, unsigned int seek_upward)
+{
+	int retval = 0;
+	unsigned long timeout;
+	bool timed_out = 0;
+
+	/* start seeking */
+	radio->registers[POWERCFG] |= POWERCFG_SEEK;
+	if (wrap_around == 1)
+		radio->registers[POWERCFG] &= ~POWERCFG_SKMODE;
+	else
+		radio->registers[POWERCFG] |= POWERCFG_SKMODE;
+	if (seek_upward == 1)
+		radio->registers[POWERCFG] |= POWERCFG_SEEKUP;
+	else
+		radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP;
+	retval = si470x_set_register(radio, POWERCFG);
+	if (retval < 0)
+		goto done;
+
+	/* wait till seek operation has completed */
+	timeout = jiffies + msecs_to_jiffies(seek_timeout);
+	do {
+		retval = si470x_get_register(radio, STATUSRSSI);
+		if (retval < 0)
+			goto stop;
+		timed_out = time_after(jiffies, timeout);
+	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
+		(!timed_out));
+	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
+		dev_warn(&radio->videodev->dev, "seek does not complete\n");
+	if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
+		dev_warn(&radio->videodev->dev,
+			"seek failed / band limit reached\n");
+	if (timed_out)
+		dev_warn(&radio->videodev->dev,
+			"seek timed out after %u ms\n", seek_timeout);
+
+stop:
+	/* stop seeking */
+	radio->registers[POWERCFG] &= ~POWERCFG_SEEK;
+	retval = si470x_set_register(radio, POWERCFG);
+
+done:
+	/* try again, if timed out */
+	if ((retval == 0) && timed_out)
+		retval = -EAGAIN;
+
+	return retval;
+}
+
+
+/*
+ * si470x_start - switch on radio
+ */
+int si470x_start(struct si470x_device *radio)
+{
+	int retval;
+
+	/* powercfg */
+	radio->registers[POWERCFG] =
+		POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM;
+	retval = si470x_set_register(radio, POWERCFG);
+	if (retval < 0)
+		goto done;
+
+	/* sysconfig 1 */
+	radio->registers[SYSCONFIG1] = SYSCONFIG1_DE;
+	retval = si470x_set_register(radio, SYSCONFIG1);
+	if (retval < 0)
+		goto done;
+
+	/* sysconfig 2 */
+	radio->registers[SYSCONFIG2] =
+		(0x3f  << 8) |				/* SEEKTH */
+		((band  << 6) & SYSCONFIG2_BAND)  |	/* BAND */
+		((space << 4) & SYSCONFIG2_SPACE) |	/* SPACE */
+		15;					/* VOLUME (max) */
+	retval = si470x_set_register(radio, SYSCONFIG2);
+	if (retval < 0)
+		goto done;
+
+	/* reset last channel */
+	retval = si470x_set_chan(radio,
+		radio->registers[CHANNEL] & CHANNEL_CHAN);
+
+done:
+	return retval;
+}
+
+
+/*
+ * si470x_stop - switch off radio
+ */
+int si470x_stop(struct si470x_device *radio)
+{
+	int retval;
+
+	/* sysconfig 1 */
+	radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
+	retval = si470x_set_register(radio, SYSCONFIG1);
+	if (retval < 0)
+		goto done;
+
+	/* powercfg */
+	radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
+	/* POWERCFG_ENABLE has to automatically go low */
+	radio->registers[POWERCFG] |= POWERCFG_ENABLE |	POWERCFG_DISABLE;
+	retval = si470x_set_register(radio, POWERCFG);
+
+done:
+	return retval;
+}
+
+
+/*
+ * si470x_rds_on - switch on rds reception
+ */
+int si470x_rds_on(struct si470x_device *radio)
+{
+	int retval;
+
+	/* sysconfig 1 */
+	mutex_lock(&radio->lock);
+	radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDS;
+	retval = si470x_set_register(radio, SYSCONFIG1);
+	if (retval < 0)
+		radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS;
+	mutex_unlock(&radio->lock);
+
+	return retval;
+}
+
+
+
+/**************************************************************************
+ * Video4Linux Interface
+ **************************************************************************/
+
+/*
+ * si470x_vidioc_queryctrl - enumerate control items
+ */
+static int si470x_vidioc_queryctrl(struct file *file, void *priv,
+		struct v4l2_queryctrl *qc)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = -EINVAL;
+
+	/* abort if qc->id is below V4L2_CID_BASE */
+	if (qc->id < V4L2_CID_BASE)
+		goto done;
+
+	/* search video control */
+	switch (qc->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		return v4l2_ctrl_query_fill(qc, 0, 15, 1, 15);
+	case V4L2_CID_AUDIO_MUTE:
+		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+	}
+
+	/* disable unsupported base controls */
+	/* to satisfy kradio and such apps */
+	if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
+		qc->flags = V4L2_CTRL_FLAG_DISABLED;
+		retval = 0;
+	}
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"query controls failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_vidioc_g_ctrl - get the value of a control
+ */
+static int si470x_vidioc_g_ctrl(struct file *file, void *priv,
+		struct v4l2_control *ctrl)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety checks */
+	retval = si470x_disconnect_check(radio);
+	if (retval)
+		goto done;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		ctrl->value = radio->registers[SYSCONFIG2] &
+				SYSCONFIG2_VOLUME;
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = ((radio->registers[POWERCFG] &
+				POWERCFG_DMUTE) == 0) ? 1 : 0;
+		break;
+	default:
+		retval = -EINVAL;
+	}
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"get control failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_vidioc_s_ctrl - set the value of a control
+ */
+static int si470x_vidioc_s_ctrl(struct file *file, void *priv,
+		struct v4l2_control *ctrl)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety checks */
+	retval = si470x_disconnect_check(radio);
+	if (retval)
+		goto done;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_VOLUME:
+		radio->registers[SYSCONFIG2] &= ~SYSCONFIG2_VOLUME;
+		radio->registers[SYSCONFIG2] |= ctrl->value;
+		retval = si470x_set_register(radio, SYSCONFIG2);
+		break;
+	case V4L2_CID_AUDIO_MUTE:
+		if (ctrl->value == 1)
+			radio->registers[POWERCFG] &= ~POWERCFG_DMUTE;
+		else
+			radio->registers[POWERCFG] |= POWERCFG_DMUTE;
+		retval = si470x_set_register(radio, POWERCFG);
+		break;
+	default:
+		retval = -EINVAL;
+	}
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"set control failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_vidioc_g_audio - get audio attributes
+ */
+static int si470x_vidioc_g_audio(struct file *file, void *priv,
+		struct v4l2_audio *audio)
+{
+	/* driver constants */
+	audio->index = 0;
+	strcpy(audio->name, "Radio");
+	audio->capability = V4L2_AUDCAP_STEREO;
+	audio->mode = 0;
+
+	return 0;
+}
+
+
+/*
+ * si470x_vidioc_g_tuner - get tuner attributes
+ */
+static int si470x_vidioc_g_tuner(struct file *file, void *priv,
+		struct v4l2_tuner *tuner)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety checks */
+	retval = si470x_disconnect_check(radio);
+	if (retval)
+		goto done;
+
+	if (tuner->index != 0) {
+		retval = -EINVAL;
+		goto done;
+	}
+
+	retval = si470x_get_register(radio, STATUSRSSI);
+	if (retval < 0)
+		goto done;
+
+	/* driver constants */
+	strcpy(tuner->name, "FM");
+	tuner->type = V4L2_TUNER_RADIO;
+#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
+	tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+			    V4L2_TUNER_CAP_RDS;
+#else
+	tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+#endif
+
+	/* range limits */
+	switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
+	/* 0: 87.5 - 108 MHz (USA, Europe, default) */
+	default:
+		tuner->rangelow  =  87.5 * FREQ_MUL;
+		tuner->rangehigh = 108   * FREQ_MUL;
+		break;
+	/* 1: 76   - 108 MHz (Japan wide band) */
+	case 1:
+		tuner->rangelow  =  76   * FREQ_MUL;
+		tuner->rangehigh = 108   * FREQ_MUL;
+		break;
+	/* 2: 76   -  90 MHz (Japan) */
+	case 2:
+		tuner->rangelow  =  76   * FREQ_MUL;
+		tuner->rangehigh =  90   * FREQ_MUL;
+		break;
+	};
+
+	/* stereo indicator == stereo (instead of mono) */
+	if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 0)
+		tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+	else
+		tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
+	/* If there is a reliable method of detecting an RDS channel,
+	   then this code should check for that before setting this
+	   RDS subchannel. */
+	tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
+#endif
+
+	/* mono/stereo selector */
+	if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0)
+		tuner->audmode = V4L2_TUNER_MODE_STEREO;
+	else
+		tuner->audmode = V4L2_TUNER_MODE_MONO;
+
+	/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
+	/* measured in units of dbì¨‰V in 1 db increments (max at ~75 dbì¨‰V) */
+	tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI);
+	/* the ideal factor is 0xffff/75 = 873,8 */
+	tuner->signal = (tuner->signal * 873) + (8 * tuner->signal / 10);
+
+	/* automatic frequency control: -1: freq to low, 1 freq to high */
+	/* AFCRL does only indicate that freq. differs, not if too low/high */
+	tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0;
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"get tuner failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_vidioc_s_tuner - set tuner attributes
+ */
+static int si470x_vidioc_s_tuner(struct file *file, void *priv,
+		struct v4l2_tuner *tuner)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = -EINVAL;
+
+	/* safety checks */
+	retval = si470x_disconnect_check(radio);
+	if (retval)
+		goto done;
+
+	if (tuner->index != 0)
+		goto done;
+
+	/* mono/stereo selector */
+	switch (tuner->audmode) {
+	case V4L2_TUNER_MODE_MONO:
+		radio->registers[POWERCFG] |= POWERCFG_MONO;  /* force mono */
+		break;
+	case V4L2_TUNER_MODE_STEREO:
+		radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
+		break;
+	default:
+		goto done;
+	}
+
+	retval = si470x_set_register(radio, POWERCFG);
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"set tuner failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_vidioc_g_frequency - get tuner or modulator radio frequency
+ */
+static int si470x_vidioc_g_frequency(struct file *file, void *priv,
+		struct v4l2_frequency *freq)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety checks */
+	retval = si470x_disconnect_check(radio);
+	if (retval)
+		goto done;
+
+	if (freq->tuner != 0) {
+		retval = -EINVAL;
+		goto done;
+	}
+
+	freq->type = V4L2_TUNER_RADIO;
+	retval = si470x_get_freq(radio, &freq->frequency);
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"get frequency failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_vidioc_s_frequency - set tuner or modulator radio frequency
+ */
+static int si470x_vidioc_s_frequency(struct file *file, void *priv,
+		struct v4l2_frequency *freq)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety checks */
+	retval = si470x_disconnect_check(radio);
+	if (retval)
+		goto done;
+
+	if (freq->tuner != 0) {
+		retval = -EINVAL;
+		goto done;
+	}
+
+	retval = si470x_set_freq(radio, freq->frequency);
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"set frequency failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
+ */
+static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
+		struct v4l2_hw_freq_seek *seek)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety checks */
+	retval = si470x_disconnect_check(radio);
+	if (retval)
+		goto done;
+
+	if (seek->tuner != 0) {
+		retval = -EINVAL;
+		goto done;
+	}
+
+	retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward);
+
+done:
+	if (retval < 0)
+		dev_warn(&radio->videodev->dev,
+			"set hardware frequency seek failed with %d\n", retval);
+	return retval;
+}
+
+
+/*
+ * si470x_ioctl_ops - video device ioctl operations
+ */
+static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
+	.vidioc_querycap	= si470x_vidioc_querycap,
+	.vidioc_queryctrl	= si470x_vidioc_queryctrl,
+	.vidioc_g_ctrl		= si470x_vidioc_g_ctrl,
+	.vidioc_s_ctrl		= si470x_vidioc_s_ctrl,
+	.vidioc_g_audio		= si470x_vidioc_g_audio,
+	.vidioc_g_tuner		= si470x_vidioc_g_tuner,
+	.vidioc_s_tuner		= si470x_vidioc_s_tuner,
+	.vidioc_g_frequency	= si470x_vidioc_g_frequency,
+	.vidioc_s_frequency	= si470x_vidioc_s_frequency,
+	.vidioc_s_hw_freq_seek	= si470x_vidioc_s_hw_freq_seek,
+};
+
+
+/*
+ * si470x_viddev_template - video device interface
+ */
+struct video_device si470x_viddev_template = {
+	.fops			= &si470x_fops,
+	.name			= DRIVER_NAME,
+	.release		= video_device_release,
+	.ioctl_ops		= &si470x_ioctl_ops,
+};
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
new file mode 100644
index 0000000..2d53b6a
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -0,0 +1,401 @@
+/*
+ * drivers/media/radio/si470x/radio-si470x-i2c.c
+ *
+ * I2C driver for radios with Silicon Labs Si470x FM Radio Receivers
+ *
+ * Copyright (c) 2009 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.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
+ */
+
+
+/*
+ * ToDo:
+ * - RDS support
+ */
+
+
+/* driver definitions */
+#define DRIVER_AUTHOR "Joonyoung Shim <jy0922.shim@samsung.com>";
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 0)
+#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
+#define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers"
+#define DRIVER_VERSION "1.0.0"
+
+/* kernel includes */
+#include <linux/i2c.h>
+#include <linux/delay.h>
+
+#include "radio-si470x.h"
+
+
+/* I2C Device ID List */
+static const struct i2c_device_id si470x_i2c_id[] = {
+	/* Generic Entry */
+	{ "si470x", 0 },
+	/* Terminating entry */
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, si470x_i2c_id);
+
+
+
+/**************************************************************************
+ * Module Parameters
+ **************************************************************************/
+
+/* Radio Nr */
+static int radio_nr = -1;
+module_param(radio_nr, int, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio Nr");
+
+
+
+/**************************************************************************
+ * I2C Definitions
+ **************************************************************************/
+
+/* Write starts with the upper byte of register 0x02 */
+#define WRITE_REG_NUM		8
+#define WRITE_INDEX(i)		(i + 0x02)
+
+/* Read starts with the upper byte of register 0x0a */
+#define READ_REG_NUM		RADIO_REGISTER_NUM
+#define READ_INDEX(i)		((i + RADIO_REGISTER_NUM - 0x0a) % READ_REG_NUM)
+
+
+
+/**************************************************************************
+ * General Driver Functions - REGISTERs
+ **************************************************************************/
+
+/*
+ * si470x_get_register - read register
+ */
+int si470x_get_register(struct si470x_device *radio, int regnr)
+{
+	u16 buf[READ_REG_NUM];
+	struct i2c_msg msgs[1] = {
+		{ radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
+			(void *)buf },
+	};
+
+	if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
+		return -EIO;
+
+	radio->registers[regnr] = __be16_to_cpu(buf[READ_INDEX(regnr)]);
+
+	return 0;
+}
+
+
+/*
+ * si470x_set_register - write register
+ */
+int si470x_set_register(struct si470x_device *radio, int regnr)
+{
+	int i;
+	u16 buf[WRITE_REG_NUM];
+	struct i2c_msg msgs[1] = {
+		{ radio->client->addr, 0, sizeof(u16) * WRITE_REG_NUM,
+			(void *)buf },
+	};
+
+	for (i = 0; i < WRITE_REG_NUM; i++)
+		buf[i] = __cpu_to_be16(radio->registers[WRITE_INDEX(i)]);
+
+	if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
+		return -EIO;
+
+	return 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - ENTIRE REGISTERS
+ **************************************************************************/
+
+/*
+ * si470x_get_all_registers - read entire registers
+ */
+static int si470x_get_all_registers(struct si470x_device *radio)
+{
+	int i;
+	u16 buf[READ_REG_NUM];
+	struct i2c_msg msgs[1] = {
+		{ radio->client->addr, I2C_M_RD, sizeof(u16) * READ_REG_NUM,
+			(void *)buf },
+	};
+
+	if (i2c_transfer(radio->client->adapter, msgs, 1) != 1)
+		return -EIO;
+
+	for (i = 0; i < READ_REG_NUM; i++)
+		radio->registers[i] = __be16_to_cpu(buf[READ_INDEX(i)]);
+
+	return 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - DISCONNECT_CHECK
+ **************************************************************************/
+
+/*
+ * si470x_disconnect_check - check whether radio disconnects
+ */
+int si470x_disconnect_check(struct si470x_device *radio)
+{
+	return 0;
+}
+
+
+
+/**************************************************************************
+ * File Operations Interface
+ **************************************************************************/
+
+/*
+ * si470x_fops_open - file open
+ */
+static int si470x_fops_open(struct file *file)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	mutex_lock(&radio->lock);
+	radio->users++;
+
+	if (radio->users == 1)
+		/* start radio */
+		retval = si470x_start(radio);
+
+	mutex_unlock(&radio->lock);
+
+	return retval;
+}
+
+
+/*
+ * si470x_fops_release - file release
+ */
+static int si470x_fops_release(struct file *file)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety check */
+	if (!radio)
+		return -ENODEV;
+
+	mutex_lock(&radio->lock);
+	radio->users--;
+	if (radio->users == 0)
+		/* stop radio */
+		retval = si470x_stop(radio);
+
+	mutex_unlock(&radio->lock);
+
+	return retval;
+}
+
+
+/*
+ * si470x_fops - file operations interface
+ */
+const struct v4l2_file_operations si470x_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= video_ioctl2,
+	.open		= si470x_fops_open,
+	.release	= si470x_fops_release,
+};
+
+
+
+/**************************************************************************
+ * Video4Linux Interface
+ **************************************************************************/
+
+/*
+ * si470x_vidioc_querycap - query device capabilities
+ */
+int si470x_vidioc_querycap(struct file *file, void *priv,
+		struct v4l2_capability *capability)
+{
+	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
+	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
+	capability->version = DRIVER_KERNEL_VERSION;
+	capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
+		V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+
+	return 0;
+}
+
+
+
+/**************************************************************************
+ * I2C Interface
+ **************************************************************************/
+
+/*
+ * si470x_i2c_probe - probe for the device
+ */
+static int __devinit si470x_i2c_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct si470x_device *radio;
+	int retval = 0;
+	unsigned char version_warning = 0;
+
+	/* private data allocation and initialization */
+	radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
+	if (!radio) {
+		retval = -ENOMEM;
+		goto err_initial;
+	}
+	radio->users = 0;
+	radio->client = client;
+	mutex_init(&radio->lock);
+
+	/* video device allocation and initialization */
+	radio->videodev = video_device_alloc();
+	if (!radio->videodev) {
+		retval = -ENOMEM;
+		goto err_radio;
+	}
+	memcpy(radio->videodev, &si470x_viddev_template,
+			sizeof(si470x_viddev_template));
+	video_set_drvdata(radio->videodev, radio);
+
+	/* power up : need 110ms */
+	radio->registers[POWERCFG] = POWERCFG_ENABLE;
+	if (si470x_set_register(radio, POWERCFG) < 0) {
+		retval = -EIO;
+		goto err_all;
+	}
+	msleep(110);
+
+	/* get device and chip versions */
+	if (si470x_get_all_registers(radio) < 0) {
+		retval = -EIO;
+		goto err_video;
+	}
+	dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
+			radio->registers[DEVICEID], radio->registers[CHIPID]);
+	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
+		dev_warn(&client->dev,
+			"This driver is known to work with "
+			"firmware version %hu,\n", RADIO_FW_VERSION);
+		dev_warn(&client->dev,
+			"but the device has firmware version %hu.\n",
+			radio->registers[CHIPID] & CHIPID_FIRMWARE);
+		version_warning = 1;
+	}
+
+	/* give out version warning */
+	if (version_warning == 1) {
+		dev_warn(&client->dev,
+			"If you have some trouble using this driver,\n");
+		dev_warn(&client->dev,
+			"please report to V4L ML at "
+			"linux-media@vger.kernel.org\n");
+	}
+
+	/* set initial frequency */
+	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+
+	/* register video device */
+	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
+			radio_nr);
+	if (retval) {
+		dev_warn(&client->dev, "Could not register video device\n");
+		goto err_all;
+	}
+	i2c_set_clientdata(client, radio);
+
+	return 0;
+err_all:
+err_video:
+	video_device_release(radio->videodev);
+err_radio:
+	kfree(radio);
+err_initial:
+	return retval;
+}
+
+
+/*
+ * si470x_i2c_remove - remove the device
+ */
+static __devexit int si470x_i2c_remove(struct i2c_client *client)
+{
+	struct si470x_device *radio = i2c_get_clientdata(client);
+
+	video_unregister_device(radio->videodev);
+	kfree(radio);
+	i2c_set_clientdata(client, NULL);
+
+	return 0;
+}
+
+
+/*
+ * si470x_i2c_driver - i2c driver interface
+ */
+static struct i2c_driver si470x_i2c_driver = {
+	.driver = {
+		.name		= "si470x",
+		.owner		= THIS_MODULE,
+	},
+	.probe			= si470x_i2c_probe,
+	.remove			= __devexit_p(si470x_i2c_remove),
+	.id_table		= si470x_i2c_id,
+};
+
+
+
+/**************************************************************************
+ * Module Interface
+ **************************************************************************/
+
+/*
+ * si470x_i2c_init - module init
+ */
+static int __init si470x_i2c_init(void)
+{
+	printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
+	return i2c_add_driver(&si470x_i2c_driver);
+}
+
+
+/*
+ * si470x_i2c_exit - module exit
+ */
+static void __exit si470x_i2c_exit(void)
+{
+	i2c_del_driver(&si470x_i2c_driver);
+}
+
+
+module_init(si470x_i2c_init);
+module_exit(si470x_i2c_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c
new file mode 100644
index 0000000..f2d0e1d
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x-usb.c
@@ -0,0 +1,988 @@
+/*
+ *  drivers/media/radio/si470x/radio-si470x-usb.c
+ *
+ *  USB driver for radios with Silicon Labs Si470x FM Radio Receivers
+ *
+ *  Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/*
+ * ToDo:
+ * - add firmware download/update support
+ */
+
+
+/* driver definitions */
+#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 10)
+#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
+#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
+#define DRIVER_VERSION "1.0.10"
+
+/* kernel includes */
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "radio-si470x.h"
+
+
+/* USB Device ID List */
+static struct usb_device_id si470x_usb_driver_id_table[] = {
+	/* Silicon Labs USB FM Radio Reference Design */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
+	/* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
+	/* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
+	/* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
+	/* Terminating entry */
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
+
+
+
+/**************************************************************************
+ * Module Parameters
+ **************************************************************************/
+
+/* Radio Nr */
+static int radio_nr = -1;
+module_param(radio_nr, int, 0444);
+MODULE_PARM_DESC(radio_nr, "Radio Nr");
+
+/* USB timeout */
+static unsigned int usb_timeout = 500;
+module_param(usb_timeout, uint, 0644);
+MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
+
+/* RDS buffer blocks */
+static unsigned int rds_buf = 100;
+module_param(rds_buf, uint, 0444);
+MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
+
+/* RDS maximum block errors */
+static unsigned short max_rds_errors = 1;
+/* 0 means   0  errors requiring correction */
+/* 1 means 1-2  errors requiring correction (used by original USBRadio.exe) */
+/* 2 means 3-5  errors requiring correction */
+/* 3 means   6+ errors or errors in checkword, correction not possible */
+module_param(max_rds_errors, ushort, 0644);
+MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
+
+
+
+/**************************************************************************
+ * USB HID Reports
+ **************************************************************************/
+
+/* Reports 1-16 give direct read/write access to the 16 Si470x registers */
+/* with the (REPORT_ID - 1) corresponding to the register address across USB */
+/* endpoint 0 using GET_REPORT and SET_REPORT */
+#define REGISTER_REPORT_SIZE	(RADIO_REGISTER_SIZE + 1)
+#define REGISTER_REPORT(reg)	((reg) + 1)
+
+/* Report 17 gives direct read/write access to the entire Si470x register */
+/* map across endpoint 0 using GET_REPORT and SET_REPORT */
+#define ENTIRE_REPORT_SIZE	(RADIO_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
+#define ENTIRE_REPORT		17
+
+/* Report 18 is used to send the lowest 6 Si470x registers up the HID */
+/* interrupt endpoint 1 to Windows every 20 milliseconds for status */
+#define RDS_REPORT_SIZE		(RDS_REGISTER_NUM * RADIO_REGISTER_SIZE + 1)
+#define RDS_REPORT		18
+
+/* Report 19: LED state */
+#define LED_REPORT_SIZE		3
+#define LED_REPORT		19
+
+/* Report 19: stream */
+#define STREAM_REPORT_SIZE	3
+#define STREAM_REPORT		19
+
+/* Report 20: scratch */
+#define SCRATCH_PAGE_SIZE	63
+#define SCRATCH_REPORT_SIZE	(SCRATCH_PAGE_SIZE + 1)
+#define SCRATCH_REPORT		20
+
+/* Reports 19-22: flash upgrade of the C8051F321 */
+#define WRITE_REPORT_SIZE	4
+#define WRITE_REPORT		19
+#define FLASH_REPORT_SIZE	64
+#define FLASH_REPORT		20
+#define CRC_REPORT_SIZE		3
+#define CRC_REPORT		21
+#define RESPONSE_REPORT_SIZE	2
+#define RESPONSE_REPORT		22
+
+/* Report 23: currently unused, but can accept 60 byte reports on the HID */
+/* interrupt out endpoint 2 every 1 millisecond */
+#define UNUSED_REPORT		23
+
+
+
+/**************************************************************************
+ * Software/Hardware Versions from Scratch Page
+ **************************************************************************/
+#define RADIO_SW_VERSION_NOT_BOOTLOADABLE	6
+#define RADIO_SW_VERSION			7
+#define RADIO_HW_VERSION			1
+
+
+
+/**************************************************************************
+ * LED State Definitions
+ **************************************************************************/
+#define LED_COMMAND		0x35
+
+#define NO_CHANGE_LED		0x00
+#define ALL_COLOR_LED		0x01	/* streaming state */
+#define BLINK_GREEN_LED		0x02	/* connect state */
+#define BLINK_RED_LED		0x04
+#define BLINK_ORANGE_LED	0x10	/* disconnect state */
+#define SOLID_GREEN_LED		0x20	/* tuning/seeking state */
+#define SOLID_RED_LED		0x40	/* bootload state */
+#define SOLID_ORANGE_LED	0x80
+
+
+
+/**************************************************************************
+ * Stream State Definitions
+ **************************************************************************/
+#define STREAM_COMMAND	0x36
+#define STREAM_VIDPID	0x00
+#define STREAM_AUDIO	0xff
+
+
+
+/**************************************************************************
+ * Bootloader / Flash Commands
+ **************************************************************************/
+
+/* unique id sent to bootloader and required to put into a bootload state */
+#define UNIQUE_BL_ID		0x34
+
+/* mask for the flash data */
+#define FLASH_DATA_MASK		0x55
+
+/* bootloader commands */
+#define GET_SW_VERSION_COMMAND	0x00
+#define SET_PAGE_COMMAND	0x01
+#define ERASE_PAGE_COMMAND	0x02
+#define WRITE_PAGE_COMMAND	0x03
+#define CRC_ON_PAGE_COMMAND	0x04
+#define READ_FLASH_BYTE_COMMAND	0x05
+#define RESET_DEVICE_COMMAND	0x06
+#define GET_HW_VERSION_COMMAND	0x07
+#define BLANK			0xff
+
+/* bootloader command responses */
+#define COMMAND_OK		0x01
+#define COMMAND_FAILED		0x02
+#define COMMAND_PENDING		0x03
+
+
+
+/**************************************************************************
+ * General Driver Functions - REGISTER_REPORTs
+ **************************************************************************/
+
+/*
+ * si470x_get_report - receive a HID report
+ */
+static int si470x_get_report(struct si470x_device *radio, void *buf, int size)
+{
+	unsigned char *report = (unsigned char *) buf;
+	int retval;
+
+	retval = usb_control_msg(radio->usbdev,
+		usb_rcvctrlpipe(radio->usbdev, 0),
+		HID_REQ_GET_REPORT,
+		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
+		report[0], 2,
+		buf, size, usb_timeout);
+
+	if (retval < 0)
+		dev_warn(&radio->intf->dev,
+			"si470x_get_report: usb_control_msg returned %d\n",
+			retval);
+	return retval;
+}
+
+
+/*
+ * si470x_set_report - send a HID report
+ */
+static int si470x_set_report(struct si470x_device *radio, void *buf, int size)
+{
+	unsigned char *report = (unsigned char *) buf;
+	int retval;
+
+	retval = usb_control_msg(radio->usbdev,
+		usb_sndctrlpipe(radio->usbdev, 0),
+		HID_REQ_SET_REPORT,
+		USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
+		report[0], 2,
+		buf, size, usb_timeout);
+
+	if (retval < 0)
+		dev_warn(&radio->intf->dev,
+			"si470x_set_report: usb_control_msg returned %d\n",
+			retval);
+	return retval;
+}
+
+
+/*
+ * si470x_get_register - read register
+ */
+int si470x_get_register(struct si470x_device *radio, int regnr)
+{
+	unsigned char buf[REGISTER_REPORT_SIZE];
+	int retval;
+
+	buf[0] = REGISTER_REPORT(regnr);
+
+	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+	if (retval >= 0)
+		radio->registers[regnr] = get_unaligned_be16(&buf[1]);
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+/*
+ * si470x_set_register - write register
+ */
+int si470x_set_register(struct si470x_device *radio, int regnr)
+{
+	unsigned char buf[REGISTER_REPORT_SIZE];
+	int retval;
+
+	buf[0] = REGISTER_REPORT(regnr);
+	put_unaligned_be16(radio->registers[regnr], &buf[1]);
+
+	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - ENTIRE_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_all_registers - read entire registers
+ */
+static int si470x_get_all_registers(struct si470x_device *radio)
+{
+	unsigned char buf[ENTIRE_REPORT_SIZE];
+	int retval;
+	unsigned char regnr;
+
+	buf[0] = ENTIRE_REPORT;
+
+	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+	if (retval >= 0)
+		for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
+			radio->registers[regnr] = get_unaligned_be16(
+				&buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - LED_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_set_led_state - sets the led state
+ */
+static int si470x_set_led_state(struct si470x_device *radio,
+		unsigned char led_state)
+{
+	unsigned char buf[LED_REPORT_SIZE];
+	int retval;
+
+	buf[0] = LED_REPORT;
+	buf[1] = LED_COMMAND;
+	buf[2] = led_state;
+
+	retval = si470x_set_report(radio, (void *) &buf, sizeof(buf));
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - SCRATCH_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_scratch_versions - gets the scratch page and version infos
+ */
+static int si470x_get_scratch_page_versions(struct si470x_device *radio)
+{
+	unsigned char buf[SCRATCH_REPORT_SIZE];
+	int retval;
+
+	buf[0] = SCRATCH_REPORT;
+
+	retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+	if (retval < 0)
+		dev_warn(&radio->intf->dev, "si470x_get_scratch: "
+			"si470x_get_report returned %d\n", retval);
+	else {
+		radio->software_version = buf[1];
+		radio->hardware_version = buf[2];
+	}
+
+	return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - DISCONNECT_CHECK
+ **************************************************************************/
+
+/*
+ * si470x_disconnect_check - check whether radio disconnects
+ */
+int si470x_disconnect_check(struct si470x_device *radio)
+{
+	if (radio->disconnected)
+		return -EIO;
+	else
+		return 0;
+}
+
+
+
+/**************************************************************************
+ * RDS Driver Functions
+ **************************************************************************/
+
+/*
+ * si470x_int_in_callback - rds callback and processing function
+ *
+ * TODO: do we need to use mutex locks in some sections?
+ */
+static void si470x_int_in_callback(struct urb *urb)
+{
+	struct si470x_device *radio = urb->context;
+	unsigned char buf[RDS_REPORT_SIZE];
+	int retval;
+	unsigned char regnr;
+	unsigned char blocknum;
+	unsigned short bler; /* rds block errors */
+	unsigned short rds;
+	unsigned char tmpbuf[3];
+
+	if (urb->status) {
+		if (urb->status == -ENOENT ||
+				urb->status == -ECONNRESET ||
+				urb->status == -ESHUTDOWN) {
+			return;
+		} else {
+			dev_warn(&radio->intf->dev,
+			 "non-zero urb status (%d)\n", urb->status);
+			goto resubmit; /* Maybe we can recover. */
+		}
+	}
+
+	/* safety checks */
+	if (radio->disconnected)
+		return;
+	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+		goto resubmit;
+
+	if (urb->actual_length > 0) {
+		/* Update RDS registers with URB data */
+		buf[0] = RDS_REPORT;
+		for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
+			radio->registers[STATUSRSSI + regnr] =
+			    get_unaligned_be16(&radio->int_in_buffer[
+				regnr * RADIO_REGISTER_SIZE + 1]);
+		/* get rds blocks */
+		if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0) {
+			/* No RDS group ready, better luck next time */
+			goto resubmit;
+		}
+		if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSS) == 0) {
+			/* RDS decoder not synchronized */
+			goto resubmit;
+		}
+		for (blocknum = 0; blocknum < 4; blocknum++) {
+			switch (blocknum) {
+			default:
+				bler = (radio->registers[STATUSRSSI] &
+						STATUSRSSI_BLERA) >> 9;
+				rds = radio->registers[RDSA];
+				break;
+			case 1:
+				bler = (radio->registers[READCHAN] &
+						READCHAN_BLERB) >> 14;
+				rds = radio->registers[RDSB];
+				break;
+			case 2:
+				bler = (radio->registers[READCHAN] &
+						READCHAN_BLERC) >> 12;
+				rds = radio->registers[RDSC];
+				break;
+			case 3:
+				bler = (radio->registers[READCHAN] &
+						READCHAN_BLERD) >> 10;
+				rds = radio->registers[RDSD];
+				break;
+			};
+
+			/* Fill the V4L2 RDS buffer */
+			put_unaligned_le16(rds, &tmpbuf);
+			tmpbuf[2] = blocknum;		/* offset name */
+			tmpbuf[2] |= blocknum << 3;	/* received offset */
+			if (bler > max_rds_errors)
+				tmpbuf[2] |= 0x80; /* uncorrectable errors */
+			else if (bler > 0)
+				tmpbuf[2] |= 0x40; /* corrected error(s) */
+
+			/* copy RDS block to internal buffer */
+			memcpy(&radio->buffer[radio->wr_index], &tmpbuf, 3);
+			radio->wr_index += 3;
+
+			/* wrap write pointer */
+			if (radio->wr_index >= radio->buf_size)
+				radio->wr_index = 0;
+
+			/* check for overflow */
+			if (radio->wr_index == radio->rd_index) {
+				/* increment and wrap read pointer */
+				radio->rd_index += 3;
+				if (radio->rd_index >= radio->buf_size)
+					radio->rd_index = 0;
+			}
+		}
+		if (radio->wr_index != radio->rd_index)
+			wake_up_interruptible(&radio->read_queue);
+	}
+
+resubmit:
+	/* Resubmit if we're still running. */
+	if (radio->int_in_running && radio->usbdev) {
+		retval = usb_submit_urb(radio->int_in_urb, GFP_ATOMIC);
+		if (retval) {
+			dev_warn(&radio->intf->dev,
+			       "resubmitting urb failed (%d)", retval);
+			radio->int_in_running = 0;
+		}
+	}
+}
+
+
+
+/**************************************************************************
+ * File Operations Interface
+ **************************************************************************/
+
+/*
+ * si470x_fops_read - read RDS data
+ */
+static ssize_t si470x_fops_read(struct file *file, char __user *buf,
+		size_t count, loff_t *ppos)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+	unsigned int block_count = 0;
+
+	/* switch on rds reception */
+	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+		si470x_rds_on(radio);
+
+	/* block if no new data available */
+	while (radio->wr_index == radio->rd_index) {
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EWOULDBLOCK;
+			goto done;
+		}
+		if (wait_event_interruptible(radio->read_queue,
+			radio->wr_index != radio->rd_index) < 0) {
+			retval = -EINTR;
+			goto done;
+		}
+	}
+
+	/* calculate block count from byte count */
+	count /= 3;
+
+	/* copy RDS block out of internal buffer and to user buffer */
+	mutex_lock(&radio->lock);
+	while (block_count < count) {
+		if (radio->rd_index == radio->wr_index)
+			break;
+
+		/* always transfer rds complete blocks */
+		if (copy_to_user(buf, &radio->buffer[radio->rd_index], 3))
+			/* retval = -EFAULT; */
+			break;
+
+		/* increment and wrap read pointer */
+		radio->rd_index += 3;
+		if (radio->rd_index >= radio->buf_size)
+			radio->rd_index = 0;
+
+		/* increment counters */
+		block_count++;
+		buf += 3;
+		retval += 3;
+	}
+	mutex_unlock(&radio->lock);
+
+done:
+	return retval;
+}
+
+
+/*
+ * si470x_fops_poll - poll RDS data
+ */
+static unsigned int si470x_fops_poll(struct file *file,
+		struct poll_table_struct *pts)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* switch on rds reception */
+	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
+		si470x_rds_on(radio);
+
+	poll_wait(file, &radio->read_queue, pts);
+
+	if (radio->rd_index != radio->wr_index)
+		retval = POLLIN | POLLRDNORM;
+
+	return retval;
+}
+
+
+/*
+ * si470x_fops_open - file open
+ */
+static int si470x_fops_open(struct file *file)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval;
+
+	lock_kernel();
+	radio->users++;
+
+	retval = usb_autopm_get_interface(radio->intf);
+	if (retval < 0) {
+		radio->users--;
+		retval = -EIO;
+		goto done;
+	}
+
+	if (radio->users == 1) {
+		/* start radio */
+		retval = si470x_start(radio);
+		if (retval < 0) {
+			usb_autopm_put_interface(radio->intf);
+			goto done;
+		}
+
+		/* initialize interrupt urb */
+		usb_fill_int_urb(radio->int_in_urb, radio->usbdev,
+			usb_rcvintpipe(radio->usbdev,
+			radio->int_in_endpoint->bEndpointAddress),
+			radio->int_in_buffer,
+			le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize),
+			si470x_int_in_callback,
+			radio,
+			radio->int_in_endpoint->bInterval);
+
+		radio->int_in_running = 1;
+		mb();
+
+		retval = usb_submit_urb(radio->int_in_urb, GFP_KERNEL);
+		if (retval) {
+			dev_info(&radio->intf->dev,
+				 "submitting int urb failed (%d)\n", retval);
+			radio->int_in_running = 0;
+			usb_autopm_put_interface(radio->intf);
+		}
+	}
+
+done:
+	unlock_kernel();
+	return retval;
+}
+
+
+/*
+ * si470x_fops_release - file release
+ */
+static int si470x_fops_release(struct file *file)
+{
+	struct si470x_device *radio = video_drvdata(file);
+	int retval = 0;
+
+	/* safety check */
+	if (!radio) {
+		retval = -ENODEV;
+		goto done;
+	}
+
+	mutex_lock(&radio->disconnect_lock);
+	radio->users--;
+	if (radio->users == 0) {
+		/* shutdown interrupt handler */
+		if (radio->int_in_running) {
+			radio->int_in_running = 0;
+		if (radio->int_in_urb)
+			usb_kill_urb(radio->int_in_urb);
+		}
+
+		if (radio->disconnected) {
+			video_unregister_device(radio->videodev);
+			kfree(radio->int_in_buffer);
+			kfree(radio->buffer);
+			kfree(radio);
+			goto unlock;
+		}
+
+		/* cancel read processes */
+		wake_up_interruptible(&radio->read_queue);
+
+		/* stop radio */
+		retval = si470x_stop(radio);
+		usb_autopm_put_interface(radio->intf);
+	}
+unlock:
+	mutex_unlock(&radio->disconnect_lock);
+done:
+	return retval;
+}
+
+
+/*
+ * si470x_fops - file operations interface
+ */
+const struct v4l2_file_operations si470x_fops = {
+	.owner		= THIS_MODULE,
+	.read		= si470x_fops_read,
+	.poll		= si470x_fops_poll,
+	.ioctl		= video_ioctl2,
+	.open		= si470x_fops_open,
+	.release	= si470x_fops_release,
+};
+
+
+
+/**************************************************************************
+ * Video4Linux Interface
+ **************************************************************************/
+
+/*
+ * si470x_vidioc_querycap - query device capabilities
+ */
+int si470x_vidioc_querycap(struct file *file, void *priv,
+		struct v4l2_capability *capability)
+{
+	struct si470x_device *radio = video_drvdata(file);
+
+	strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
+	strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
+	usb_make_path(radio->usbdev, capability->bus_info,
+			sizeof(capability->bus_info));
+	capability->version = DRIVER_KERNEL_VERSION;
+	capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
+		V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE;
+
+	return 0;
+}
+
+
+
+/**************************************************************************
+ * USB Interface
+ **************************************************************************/
+
+/*
+ * si470x_usb_driver_probe - probe for the device
+ */
+static int si470x_usb_driver_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	struct si470x_device *radio;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
+	int i, int_end_size, retval = 0;
+	unsigned char version_warning = 0;
+
+	/* private data allocation and initialization */
+	radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL);
+	if (!radio) {
+		retval = -ENOMEM;
+		goto err_initial;
+	}
+	radio->users = 0;
+	radio->disconnected = 0;
+	radio->usbdev = interface_to_usbdev(intf);
+	radio->intf = intf;
+	mutex_init(&radio->disconnect_lock);
+	mutex_init(&radio->lock);
+
+	iface_desc = intf->cur_altsetting;
+
+	/* Set up interrupt endpoint information. */
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+		if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
+		 USB_DIR_IN) && ((endpoint->bmAttributes &
+		 USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT))
+			radio->int_in_endpoint = endpoint;
+	}
+	if (!radio->int_in_endpoint) {
+		dev_info(&intf->dev, "could not find interrupt in endpoint\n");
+		retval = -EIO;
+		goto err_radio;
+	}
+
+	int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize);
+
+	radio->int_in_buffer = kmalloc(int_end_size, GFP_KERNEL);
+	if (!radio->int_in_buffer) {
+		dev_info(&intf->dev, "could not allocate int_in_buffer");
+		retval = -ENOMEM;
+		goto err_radio;
+	}
+
+	radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!radio->int_in_urb) {
+		dev_info(&intf->dev, "could not allocate int_in_urb");
+		retval = -ENOMEM;
+		goto err_intbuffer;
+	}
+
+	/* video device allocation and initialization */
+	radio->videodev = video_device_alloc();
+	if (!radio->videodev) {
+		retval = -ENOMEM;
+		goto err_intbuffer;
+	}
+	memcpy(radio->videodev, &si470x_viddev_template,
+			sizeof(si470x_viddev_template));
+	video_set_drvdata(radio->videodev, radio);
+
+	/* get device and chip versions */
+	if (si470x_get_all_registers(radio) < 0) {
+		retval = -EIO;
+		goto err_video;
+	}
+	dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
+			radio->registers[DEVICEID], radio->registers[CHIPID]);
+	if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) {
+		dev_warn(&intf->dev,
+			"This driver is known to work with "
+			"firmware version %hu,\n", RADIO_FW_VERSION);
+		dev_warn(&intf->dev,
+			"but the device has firmware version %hu.\n",
+			radio->registers[CHIPID] & CHIPID_FIRMWARE);
+		version_warning = 1;
+	}
+
+	/* get software and hardware versions */
+	if (si470x_get_scratch_page_versions(radio) < 0) {
+		retval = -EIO;
+		goto err_video;
+	}
+	dev_info(&intf->dev, "software version %d, hardware version %d\n",
+			radio->software_version, radio->hardware_version);
+	if (radio->software_version < RADIO_SW_VERSION) {
+		dev_warn(&intf->dev,
+			"This driver is known to work with "
+			"software version %hu,\n", RADIO_SW_VERSION);
+		dev_warn(&intf->dev,
+			"but the device has software version %hu.\n",
+			radio->software_version);
+		version_warning = 1;
+	}
+	if (radio->hardware_version < RADIO_HW_VERSION) {
+		dev_warn(&intf->dev,
+			"This driver is known to work with "
+			"hardware version %hu,\n", RADIO_HW_VERSION);
+		dev_warn(&intf->dev,
+			"but the device has hardware version %hu.\n",
+			radio->hardware_version);
+		version_warning = 1;
+	}
+
+	/* give out version warning */
+	if (version_warning == 1) {
+		dev_warn(&intf->dev,
+			"If you have some trouble using this driver,\n");
+		dev_warn(&intf->dev,
+			"please report to V4L ML at "
+			"linux-media@vger.kernel.org\n");
+	}
+
+	/* set initial frequency */
+	si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */
+
+	/* set led to connect state */
+	si470x_set_led_state(radio, BLINK_GREEN_LED);
+
+	/* rds buffer allocation */
+	radio->buf_size = rds_buf * 3;
+	radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL);
+	if (!radio->buffer) {
+		retval = -EIO;
+		goto err_video;
+	}
+
+	/* rds buffer configuration */
+	radio->wr_index = 0;
+	radio->rd_index = 0;
+	init_waitqueue_head(&radio->read_queue);
+
+	/* register video device */
+	retval = video_register_device(radio->videodev, VFL_TYPE_RADIO,
+			radio_nr);
+	if (retval) {
+		dev_warn(&intf->dev, "Could not register video device\n");
+		goto err_all;
+	}
+	usb_set_intfdata(intf, radio);
+
+	return 0;
+err_all:
+	kfree(radio->buffer);
+err_video:
+	video_device_release(radio->videodev);
+err_intbuffer:
+	kfree(radio->int_in_buffer);
+err_radio:
+	kfree(radio);
+err_initial:
+	return retval;
+}
+
+
+/*
+ * si470x_usb_driver_suspend - suspend the device
+ */
+static int si470x_usb_driver_suspend(struct usb_interface *intf,
+		pm_message_t message)
+{
+	dev_info(&intf->dev, "suspending now...\n");
+
+	return 0;
+}
+
+
+/*
+ * si470x_usb_driver_resume - resume the device
+ */
+static int si470x_usb_driver_resume(struct usb_interface *intf)
+{
+	dev_info(&intf->dev, "resuming now...\n");
+
+	return 0;
+}
+
+
+/*
+ * si470x_usb_driver_disconnect - disconnect the device
+ */
+static void si470x_usb_driver_disconnect(struct usb_interface *intf)
+{
+	struct si470x_device *radio = usb_get_intfdata(intf);
+
+	mutex_lock(&radio->disconnect_lock);
+	radio->disconnected = 1;
+	usb_set_intfdata(intf, NULL);
+	if (radio->users == 0) {
+		/* set led to disconnect state */
+		si470x_set_led_state(radio, BLINK_ORANGE_LED);
+
+		/* Free data structures. */
+		usb_free_urb(radio->int_in_urb);
+
+		kfree(radio->int_in_buffer);
+		video_unregister_device(radio->videodev);
+		kfree(radio->buffer);
+		kfree(radio);
+	}
+	mutex_unlock(&radio->disconnect_lock);
+}
+
+
+/*
+ * si470x_usb_driver - usb driver interface
+ */
+static struct usb_driver si470x_usb_driver = {
+	.name			= DRIVER_NAME,
+	.probe			= si470x_usb_driver_probe,
+	.disconnect		= si470x_usb_driver_disconnect,
+	.suspend		= si470x_usb_driver_suspend,
+	.resume			= si470x_usb_driver_resume,
+	.id_table		= si470x_usb_driver_id_table,
+	.supports_autosuspend	= 1,
+};
+
+
+
+/**************************************************************************
+ * Module Interface
+ **************************************************************************/
+
+/*
+ * si470x_module_init - module init
+ */
+static int __init si470x_module_init(void)
+{
+	printk(KERN_INFO DRIVER_DESC ", Version " DRIVER_VERSION "\n");
+	return usb_register(&si470x_usb_driver);
+}
+
+
+/*
+ * si470x_module_exit - module exit
+ */
+static void __exit si470x_module_exit(void)
+{
+	usb_deregister(&si470x_usb_driver);
+}
+
+
+module_init(si470x_module_init);
+module_exit(si470x_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/media/radio/si470x/radio-si470x.h b/drivers/media/radio/si470x/radio-si470x.h
new file mode 100644
index 0000000..d0af194
--- /dev/null
+++ b/drivers/media/radio/si470x/radio-si470x.h
@@ -0,0 +1,225 @@
+/*
+ *  drivers/media/radio/si470x/radio-si470x.h
+ *
+ *  Driver for radios with Silicon Labs Si470x FM Radio Receivers
+ *
+ *  Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/* driver definitions */
+#define DRIVER_NAME "radio-si470x"
+
+
+/* kernel includes */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/input.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+#include <linux/mutex.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/rds.h>
+#include <asm/unaligned.h>
+
+
+
+/**************************************************************************
+ * Register Definitions
+ **************************************************************************/
+#define RADIO_REGISTER_SIZE	2	/* 16 register bit width */
+#define RADIO_REGISTER_NUM	16	/* DEVICEID   ... RDSD */
+#define RDS_REGISTER_NUM	6	/* STATUSRSSI ... RDSD */
+
+#define DEVICEID		0	/* Device ID */
+#define DEVICEID_PN		0xf000	/* bits 15..12: Part Number */
+#define DEVICEID_MFGID		0x0fff	/* bits 11..00: Manufacturer ID */
+
+#define CHIPID			1	/* Chip ID */
+#define CHIPID_REV		0xfc00	/* bits 15..10: Chip Version */
+#define CHIPID_DEV		0x0200	/* bits 09..09: Device */
+#define CHIPID_FIRMWARE		0x01ff	/* bits 08..00: Firmware Version */
+
+#define POWERCFG		2	/* Power Configuration */
+#define POWERCFG_DSMUTE		0x8000	/* bits 15..15: Softmute Disable */
+#define POWERCFG_DMUTE		0x4000	/* bits 14..14: Mute Disable */
+#define POWERCFG_MONO		0x2000	/* bits 13..13: Mono Select */
+#define POWERCFG_RDSM		0x0800	/* bits 11..11: RDS Mode (Si4701 only) */
+#define POWERCFG_SKMODE		0x0400	/* bits 10..10: Seek Mode */
+#define POWERCFG_SEEKUP		0x0200	/* bits 09..09: Seek Direction */
+#define POWERCFG_SEEK		0x0100	/* bits 08..08: Seek */
+#define POWERCFG_DISABLE	0x0040	/* bits 06..06: Powerup Disable */
+#define POWERCFG_ENABLE		0x0001	/* bits 00..00: Powerup Enable */
+
+#define CHANNEL			3	/* Channel */
+#define CHANNEL_TUNE		0x8000	/* bits 15..15: Tune */
+#define CHANNEL_CHAN		0x03ff	/* bits 09..00: Channel Select */
+
+#define SYSCONFIG1		4	/* System Configuration 1 */
+#define SYSCONFIG1_RDSIEN	0x8000	/* bits 15..15: RDS Interrupt Enable (Si4701 only) */
+#define SYSCONFIG1_STCIEN	0x4000	/* bits 14..14: Seek/Tune Complete Interrupt Enable */
+#define SYSCONFIG1_RDS		0x1000	/* bits 12..12: RDS Enable (Si4701 only) */
+#define SYSCONFIG1_DE		0x0800	/* bits 11..11: De-emphasis (0=75us 1=50us) */
+#define SYSCONFIG1_AGCD		0x0400	/* bits 10..10: AGC Disable */
+#define SYSCONFIG1_BLNDADJ	0x00c0	/* bits 07..06: Stereo/Mono Blend Level Adjustment */
+#define SYSCONFIG1_GPIO3	0x0030	/* bits 05..04: General Purpose I/O 3 */
+#define SYSCONFIG1_GPIO2	0x000c	/* bits 03..02: General Purpose I/O 2 */
+#define SYSCONFIG1_GPIO1	0x0003	/* bits 01..00: General Purpose I/O 1 */
+
+#define SYSCONFIG2		5	/* System Configuration 2 */
+#define SYSCONFIG2_SEEKTH	0xff00	/* bits 15..08: RSSI Seek Threshold */
+#define SYSCONFIG2_BAND		0x0080	/* bits 07..06: Band Select */
+#define SYSCONFIG2_SPACE	0x0030	/* bits 05..04: Channel Spacing */
+#define SYSCONFIG2_VOLUME	0x000f	/* bits 03..00: Volume */
+
+#define SYSCONFIG3		6	/* System Configuration 3 */
+#define SYSCONFIG3_SMUTER	0xc000	/* bits 15..14: Softmute Attack/Recover Rate */
+#define SYSCONFIG3_SMUTEA	0x3000	/* bits 13..12: Softmute Attenuation */
+#define SYSCONFIG3_SKSNR	0x00f0	/* bits 07..04: Seek SNR Threshold */
+#define SYSCONFIG3_SKCNT	0x000f	/* bits 03..00: Seek FM Impulse Detection Threshold */
+
+#define TEST1			7	/* Test 1 */
+#define TEST1_AHIZEN		0x4000	/* bits 14..14: Audio High-Z Enable */
+
+#define TEST2			8	/* Test 2 */
+/* TEST2 only contains reserved bits */
+
+#define BOOTCONFIG		9	/* Boot Configuration */
+/* BOOTCONFIG only contains reserved bits */
+
+#define STATUSRSSI		10	/* Status RSSI */
+#define STATUSRSSI_RDSR		0x8000	/* bits 15..15: RDS Ready (Si4701 only) */
+#define STATUSRSSI_STC		0x4000	/* bits 14..14: Seek/Tune Complete */
+#define STATUSRSSI_SF		0x2000	/* bits 13..13: Seek Fail/Band Limit */
+#define STATUSRSSI_AFCRL	0x1000	/* bits 12..12: AFC Rail */
+#define STATUSRSSI_RDSS		0x0800	/* bits 11..11: RDS Synchronized (Si4701 only) */
+#define STATUSRSSI_BLERA	0x0600	/* bits 10..09: RDS Block A Errors (Si4701 only) */
+#define STATUSRSSI_ST		0x0100	/* bits 08..08: Stereo Indicator */
+#define STATUSRSSI_RSSI		0x00ff	/* bits 07..00: RSSI (Received Signal Strength Indicator) */
+
+#define READCHAN		11	/* Read Channel */
+#define READCHAN_BLERB		0xc000	/* bits 15..14: RDS Block D Errors (Si4701 only) */
+#define READCHAN_BLERC		0x3000	/* bits 13..12: RDS Block C Errors (Si4701 only) */
+#define READCHAN_BLERD		0x0c00	/* bits 11..10: RDS Block B Errors (Si4701 only) */
+#define READCHAN_READCHAN	0x03ff	/* bits 09..00: Read Channel */
+
+#define RDSA			12	/* RDSA */
+#define RDSA_RDSA		0xffff	/* bits 15..00: RDS Block A Data (Si4701 only) */
+
+#define RDSB			13	/* RDSB */
+#define RDSB_RDSB		0xffff	/* bits 15..00: RDS Block B Data (Si4701 only) */
+
+#define RDSC			14	/* RDSC */
+#define RDSC_RDSC		0xffff	/* bits 15..00: RDS Block C Data (Si4701 only) */
+
+#define RDSD			15	/* RDSD */
+#define RDSD_RDSD		0xffff	/* bits 15..00: RDS Block D Data (Si4701 only) */
+
+
+
+/**************************************************************************
+ * General Driver Definitions
+ **************************************************************************/
+
+/*
+ * si470x_device - private data
+ */
+struct si470x_device {
+	struct video_device *videodev;
+
+	/* driver management */
+	unsigned int users;
+
+	/* Silabs internal registers (0..15) */
+	unsigned short registers[RADIO_REGISTER_NUM];
+
+	/* RDS receive buffer */
+	wait_queue_head_t read_queue;
+	struct mutex lock;		/* buffer locking */
+	unsigned char *buffer;		/* size is always multiple of three */
+	unsigned int buf_size;
+	unsigned int rd_index;
+	unsigned int wr_index;
+
+#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
+	/* reference to USB and video device */
+	struct usb_device *usbdev;
+	struct usb_interface *intf;
+
+	/* Interrupt endpoint handling */
+	char *int_in_buffer;
+	struct usb_endpoint_descriptor *int_in_endpoint;
+	struct urb *int_in_urb;
+	int int_in_running;
+
+	/* scratch page */
+	unsigned char software_version;
+	unsigned char hardware_version;
+
+	/* driver management */
+	unsigned char disconnected;
+	struct mutex disconnect_lock;
+#endif
+
+#if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
+	struct i2c_client *client;
+#endif
+};
+
+
+
+/**************************************************************************
+ * Firmware Versions
+ **************************************************************************/
+
+#define RADIO_FW_VERSION	15
+
+
+
+/**************************************************************************
+ * Frequency Multiplicator
+ **************************************************************************/
+
+/*
+ * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW,
+ * 62.5 kHz otherwise.
+ * The tuner is able to have a channel spacing of 50, 100 or 200 kHz.
+ * tuner->capability is therefore set to V4L2_TUNER_CAP_LOW
+ * The FREQ_MUL is then: 1 MHz / 62.5 Hz = 16000
+ */
+#define FREQ_MUL (1000000 / 62.5)
+
+
+
+/**************************************************************************
+ * Common Functions
+ **************************************************************************/
+extern const struct v4l2_file_operations si470x_fops;
+extern struct video_device si470x_viddev_template;
+int si470x_get_register(struct si470x_device *radio, int regnr);
+int si470x_set_register(struct si470x_device *radio, int regnr);
+int si470x_disconnect_check(struct si470x_device *radio);
+int si470x_set_freq(struct si470x_device *radio, unsigned int freq);
+int si470x_start(struct si470x_device *radio);
+int si470x_stop(struct si470x_device *radio);
+int si470x_rds_on(struct si470x_device *radio);
+int si470x_vidioc_querycap(struct file *file, void *priv,
+		struct v4l2_capability *capability);
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
new file mode 100644
index 0000000..6a0028e
--- /dev/null
+++ b/drivers/media/radio/si4713-i2c.c
@@ -0,0 +1,2060 @@
+/*
+ * drivers/media/radio/si4713-i2c.c
+ *
+ * Silicon Labs Si4713 FM Radio Transmitter I2C commands.
+ *
+ * Copyright (c) 2009 Nokia Corporation
+ * Contact: Eduardo Valentin <eduardo.valentin@nokia.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/mutex.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-common.h>
+
+#include "si4713-i2c.h"
+
+/* module parameters */
+static int debug;
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug level (0 - 2)");
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
+MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter");
+MODULE_VERSION("0.0.1");
+
+#define DEFAULT_RDS_PI			0x00
+#define DEFAULT_RDS_PTY			0x00
+#define DEFAULT_RDS_PS_NAME		""
+#define DEFAULT_RDS_RADIO_TEXT		DEFAULT_RDS_PS_NAME
+#define DEFAULT_RDS_DEVIATION		0x00C8
+#define DEFAULT_RDS_PS_REPEAT_COUNT	0x0003
+#define DEFAULT_LIMITER_RTIME		0x1392
+#define DEFAULT_LIMITER_DEV		0x102CA
+#define DEFAULT_PILOT_FREQUENCY 	0x4A38
+#define DEFAULT_PILOT_DEVIATION		0x1A5E
+#define DEFAULT_ACOMP_ATIME		0x0000
+#define DEFAULT_ACOMP_RTIME		0xF4240L
+#define DEFAULT_ACOMP_GAIN		0x0F
+#define DEFAULT_ACOMP_THRESHOLD 	(-0x28)
+#define DEFAULT_MUTE			0x01
+#define DEFAULT_POWER_LEVEL		88
+#define DEFAULT_FREQUENCY		8800
+#define DEFAULT_PREEMPHASIS		FMPE_EU
+#define DEFAULT_TUNE_RNL		0xFF
+
+#define to_si4713_device(sd)	container_of(sd, struct si4713_device, sd)
+
+/* frequency domain transformation (using times 10 to avoid floats) */
+#define FREQDEV_UNIT	100000
+#define FREQV4L2_MULTI	625
+#define si4713_to_v4l2(f)	((f * FREQDEV_UNIT) / FREQV4L2_MULTI)
+#define v4l2_to_si4713(f)	((f * FREQV4L2_MULTI) / FREQDEV_UNIT)
+#define FREQ_RANGE_LOW			7600
+#define FREQ_RANGE_HIGH			10800
+
+#define MAX_ARGS 7
+
+#define RDS_BLOCK			8
+#define RDS_BLOCK_CLEAR			0x03
+#define RDS_BLOCK_LOAD			0x04
+#define RDS_RADIOTEXT_2A		0x20
+#define RDS_RADIOTEXT_BLK_SIZE		4
+#define RDS_RADIOTEXT_INDEX_MAX		0x0F
+#define RDS_CARRIAGE_RETURN		0x0D
+
+#define rds_ps_nblocks(len)	((len / RDS_BLOCK) + (len % RDS_BLOCK ? 1 : 0))
+
+#define get_status_bit(p, b, m)	(((p) & (m)) >> (b))
+#define set_bits(p, v, b, m)	(((p) & ~(m)) | ((v) << (b)))
+
+#define ATTACK_TIME_UNIT	500
+
+#define POWER_OFF			0x00
+#define POWER_ON			0x01
+
+#define msb(x)                  ((u8)((u16) x >> 8))
+#define lsb(x)                  ((u8)((u16) x &  0x00FF))
+#define compose_u16(msb, lsb)	(((u16)msb << 8) | lsb)
+#define check_command_failed(status)	(!(status & SI4713_CTS) || \
+					(status & SI4713_ERR))
+/* mute definition */
+#define set_mute(p)	((p & 1) | ((p & 1) << 1));
+#define get_mute(p)	(p & 0x01)
+
+#ifdef DEBUG
+#define DBG_BUFFER(device, message, buffer, size)			\
+	{								\
+		int i;							\
+		char str[(size)*5];					\
+		for (i = 0; i < size; i++)				\
+			sprintf(str + i * 5, " 0x%02x", buffer[i]);	\
+		v4l2_dbg(2, debug, device, "%s:%s\n", message, str);	\
+	}
+#else
+#define DBG_BUFFER(device, message, buffer, size)
+#endif
+
+/*
+ * Values for limiter release time (sorted by second column)
+ *	device	release
+ *	value	time (us)
+ */
+static long limiter_times[] = {
+	2000,	250,
+	1000,	500,
+	510,	1000,
+	255,	2000,
+	170,	3000,
+	127,	4020,
+	102,	5010,
+	85,	6020,
+	73,	7010,
+	64,	7990,
+	57,	8970,
+	51,	10030,
+	25,	20470,
+	17,	30110,
+	13,	39380,
+	10,	51190,
+	8,	63690,
+	7,	73140,
+	6,	85330,
+	5,	102390,
+};
+
+/*
+ * Values for audio compression release time (sorted by second column)
+ *	device	release
+ *	value	time (us)
+ */
+static unsigned long acomp_rtimes[] = {
+	0,	100000,
+	1,	200000,
+	2,	350000,
+	3,	525000,
+	4,	1000000,
+};
+
+/*
+ * Values for preemphasis (sorted by second column)
+ *	device	preemphasis
+ *	value	value (v4l2)
+ */
+static unsigned long preemphasis_values[] = {
+	FMPE_DISABLED,	V4L2_PREEMPHASIS_DISABLED,
+	FMPE_EU,	V4L2_PREEMPHASIS_50_uS,
+	FMPE_USA,	V4L2_PREEMPHASIS_75_uS,
+};
+
+static int usecs_to_dev(unsigned long usecs, unsigned long const array[],
+			int size)
+{
+	int i;
+	int rval = -EINVAL;
+
+	for (i = 0; i < size / 2; i++)
+		if (array[(i * 2) + 1] >= usecs) {
+			rval = array[i * 2];
+			break;
+		}
+
+	return rval;
+}
+
+static unsigned long dev_to_usecs(int value, unsigned long const array[],
+			int size)
+{
+	int i;
+	int rval = -EINVAL;
+
+	for (i = 0; i < size / 2; i++)
+		if (array[i * 2] == value) {
+			rval = array[(i * 2) + 1];
+			break;
+		}
+
+	return rval;
+}
+
+/* si4713_handler: IRQ handler, just complete work */
+static irqreturn_t si4713_handler(int irq, void *dev)
+{
+	struct si4713_device *sdev = dev;
+
+	v4l2_dbg(2, debug, &sdev->sd,
+			"%s: sending signal to completion work.\n", __func__);
+	complete(&sdev->work);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * si4713_send_command - sends a command to si4713 and waits its response
+ * @sdev: si4713_device structure for the device we are communicating
+ * @command: command id
+ * @args: command arguments we are sending (up to 7)
+ * @argn: actual size of @args
+ * @response: buffer to place the expected response from the device (up to 15)
+ * @respn: actual size of @response
+ * @usecs: amount of time to wait before reading the response (in usecs)
+ */
+static int si4713_send_command(struct si4713_device *sdev, const u8 command,
+				const u8 args[], const int argn,
+				u8 response[], const int respn, const int usecs)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
+	u8 data1[MAX_ARGS + 1];
+	int err;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	/* First send the command and its arguments */
+	data1[0] = command;
+	memcpy(data1 + 1, args, argn);
+	DBG_BUFFER(&sdev->sd, "Parameters", data1, argn + 1);
+
+	err = i2c_master_send(client, data1, argn + 1);
+	if (err != argn + 1) {
+		v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n",
+			command);
+		return (err > 0) ? -EIO : err;
+	}
+
+	/* Wait response from interrupt */
+	if (!wait_for_completion_timeout(&sdev->work,
+				usecs_to_jiffies(usecs) + 1))
+		v4l2_warn(&sdev->sd,
+				"(%s) Device took too much time to answer.\n",
+				__func__);
+
+	/* Then get the response */
+	err = i2c_master_recv(client, response, respn);
+	if (err != respn) {
+		v4l2_err(&sdev->sd,
+			"Error while reading response for command 0x%02x\n",
+			command);
+		return (err > 0) ? -EIO : err;
+	}
+
+	DBG_BUFFER(&sdev->sd, "Response", response, respn);
+	if (check_command_failed(response[0]))
+		return -EBUSY;
+
+	return 0;
+}
+
+/*
+ * si4713_read_property - reads a si4713 property
+ * @sdev: si4713_device structure for the device we are communicating
+ * @prop: property identification number
+ * @pv: property value to be returned on success
+ */
+static int si4713_read_property(struct si4713_device *sdev, u16 prop, u32 *pv)
+{
+	int err;
+	u8 val[SI4713_GET_PROP_NRESP];
+	/*
+	 * 	.First byte = 0
+	 * 	.Second byte = property's MSB
+	 * 	.Third byte = property's LSB
+	 */
+	const u8 args[SI4713_GET_PROP_NARGS] = {
+		0x00,
+		msb(prop),
+		lsb(prop),
+	};
+
+	err = si4713_send_command(sdev, SI4713_CMD_GET_PROPERTY,
+				  args, ARRAY_SIZE(args), val,
+				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
+
+	if (err < 0)
+		return err;
+
+	*pv = compose_u16(val[2], val[3]);
+
+	v4l2_dbg(1, debug, &sdev->sd,
+			"%s: property=0x%02x value=0x%02x status=0x%02x\n",
+			__func__, prop, *pv, val[0]);
+
+	return err;
+}
+
+/*
+ * si4713_write_property - modifies a si4713 property
+ * @sdev: si4713_device structure for the device we are communicating
+ * @prop: property identification number
+ * @val: new value for that property
+ */
+static int si4713_write_property(struct si4713_device *sdev, u16 prop, u16 val)
+{
+	int rval;
+	u8 resp[SI4713_SET_PROP_NRESP];
+	/*
+	 * 	.First byte = 0
+	 * 	.Second byte = property's MSB
+	 * 	.Third byte = property's LSB
+	 * 	.Fourth byte = value's MSB
+	 * 	.Fifth byte = value's LSB
+	 */
+	const u8 args[SI4713_SET_PROP_NARGS] = {
+		0x00,
+		msb(prop),
+		lsb(prop),
+		msb(val),
+		lsb(val),
+	};
+
+	rval = si4713_send_command(sdev, SI4713_CMD_SET_PROPERTY,
+					args, ARRAY_SIZE(args),
+					resp, ARRAY_SIZE(resp),
+					DEFAULT_TIMEOUT);
+
+	if (rval < 0)
+		return rval;
+
+	v4l2_dbg(1, debug, &sdev->sd,
+			"%s: property=0x%02x value=0x%02x status=0x%02x\n",
+			__func__, prop, val, resp[0]);
+
+	/*
+	 * As there is no command response for SET_PROPERTY,
+	 * wait Tcomp time to finish before proceed, in order
+	 * to have property properly set.
+	 */
+	msleep(TIMEOUT_SET_PROPERTY);
+
+	return rval;
+}
+
+/*
+ * si4713_powerup - Powers the device up
+ * @sdev: si4713_device structure for the device we are communicating
+ */
+static int si4713_powerup(struct si4713_device *sdev)
+{
+	int err;
+	u8 resp[SI4713_PWUP_NRESP];
+	/*
+	 * 	.First byte = Enabled interrupts and boot function
+	 * 	.Second byte = Input operation mode
+	 */
+	const u8 args[SI4713_PWUP_NARGS] = {
+		SI4713_PWUP_CTSIEN | SI4713_PWUP_GPO2OEN | SI4713_PWUP_FUNC_TX,
+		SI4713_PWUP_OPMOD_ANALOG,
+	};
+
+	if (sdev->power_state)
+		return 0;
+
+	sdev->platform_data->set_power(1);
+	err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
+					args, ARRAY_SIZE(args),
+					resp, ARRAY_SIZE(resp),
+					TIMEOUT_POWER_UP);
+
+	if (!err) {
+		v4l2_dbg(1, debug, &sdev->sd, "Powerup response: 0x%02x\n",
+				resp[0]);
+		v4l2_dbg(1, debug, &sdev->sd, "Device in power up mode\n");
+		sdev->power_state = POWER_ON;
+
+		err = si4713_write_property(sdev, SI4713_GPO_IEN,
+						SI4713_STC_INT | SI4713_CTS);
+	} else {
+		sdev->platform_data->set_power(0);
+	}
+
+	return err;
+}
+
+/*
+ * si4713_powerdown - Powers the device down
+ * @sdev: si4713_device structure for the device we are communicating
+ */
+static int si4713_powerdown(struct si4713_device *sdev)
+{
+	int err;
+	u8 resp[SI4713_PWDN_NRESP];
+
+	if (!sdev->power_state)
+		return 0;
+
+	err = si4713_send_command(sdev, SI4713_CMD_POWER_DOWN,
+					NULL, 0,
+					resp, ARRAY_SIZE(resp),
+					DEFAULT_TIMEOUT);
+
+	if (!err) {
+		v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
+				resp[0]);
+		v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
+		sdev->platform_data->set_power(0);
+		sdev->power_state = POWER_OFF;
+	}
+
+	return err;
+}
+
+/*
+ * si4713_checkrev - Checks if we are treating a device with the correct rev.
+ * @sdev: si4713_device structure for the device we are communicating
+ */
+static int si4713_checkrev(struct si4713_device *sdev)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
+	int rval;
+	u8 resp[SI4713_GETREV_NRESP];
+
+	mutex_lock(&sdev->mutex);
+
+	rval = si4713_send_command(sdev, SI4713_CMD_GET_REV,
+					NULL, 0,
+					resp, ARRAY_SIZE(resp),
+					DEFAULT_TIMEOUT);
+
+	if (rval < 0)
+		goto unlock;
+
+	if (resp[1] == SI4713_PRODUCT_NUMBER) {
+		v4l2_info(&sdev->sd, "chip found @ 0x%02x (%s)\n",
+				client->addr << 1, client->adapter->name);
+	} else {
+		v4l2_err(&sdev->sd, "Invalid product number\n");
+		rval = -EINVAL;
+	}
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+/*
+ * si4713_wait_stc - Waits STC interrupt and clears status bits. Usefull
+ *		     for TX_TUNE_POWER, TX_TUNE_FREQ and TX_TUNE_MEAS
+ * @sdev: si4713_device structure for the device we are communicating
+ * @usecs: timeout to wait for STC interrupt signal
+ */
+static int si4713_wait_stc(struct si4713_device *sdev, const int usecs)
+{
+	int err;
+	u8 resp[SI4713_GET_STATUS_NRESP];
+
+	/* Wait response from STC interrupt */
+	if (!wait_for_completion_timeout(&sdev->work,
+			usecs_to_jiffies(usecs) + 1))
+		v4l2_warn(&sdev->sd,
+			"%s: device took too much time to answer (%d usec).\n",
+				__func__, usecs);
+
+	/* Clear status bits */
+	err = si4713_send_command(sdev, SI4713_CMD_GET_INT_STATUS,
+					NULL, 0,
+					resp, ARRAY_SIZE(resp),
+					DEFAULT_TIMEOUT);
+
+	if (err < 0)
+		goto exit;
+
+	v4l2_dbg(1, debug, &sdev->sd,
+			"%s: status bits: 0x%02x\n", __func__, resp[0]);
+
+	if (!(resp[0] & SI4713_STC_INT))
+		err = -EIO;
+
+exit:
+	return err;
+}
+
+/*
+ * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning
+ * 			frequency between 76 and 108 MHz in 10 kHz units and
+ * 			steps of 50 kHz.
+ * @sdev: si4713_device structure for the device we are communicating
+ * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
+ */
+static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency)
+{
+	int err;
+	u8 val[SI4713_TXFREQ_NRESP];
+	/*
+	 * 	.First byte = 0
+	 * 	.Second byte = frequency's MSB
+	 * 	.Third byte = frequency's LSB
+	 */
+	const u8 args[SI4713_TXFREQ_NARGS] = {
+		0x00,
+		msb(frequency),
+		lsb(frequency),
+	};
+
+	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_FREQ,
+				  args, ARRAY_SIZE(args), val,
+				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
+
+	if (err < 0)
+		return err;
+
+	v4l2_dbg(1, debug, &sdev->sd,
+			"%s: frequency=0x%02x status=0x%02x\n", __func__,
+			frequency, val[0]);
+
+	err = si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
+	if (err < 0)
+		return err;
+
+	return compose_u16(args[1], args[2]);
+}
+
+/*
+ * si4713_tx_tune_power - Sets the RF voltage level between 88 and 115 dBuV in
+ * 			1 dB units. A value of 0x00 indicates off. The command
+ * 			also sets the antenna tuning capacitance. A value of 0
+ * 			indicates autotuning, and a value of 1 - 191 indicates
+ * 			a manual override, which results in a tuning
+ * 			capacitance of 0.25 pF x @antcap.
+ * @sdev: si4713_device structure for the device we are communicating
+ * @power: tuning power (88 - 115 dBuV, unit/step 1 dB)
+ * @antcap: value of antenna tuning capacitor (0 - 191)
+ */
+static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
+				u8 antcap)
+{
+	int err;
+	u8 val[SI4713_TXPWR_NRESP];
+	/*
+	 * 	.First byte = 0
+	 * 	.Second byte = 0
+	 * 	.Third byte = power
+	 * 	.Fourth byte = antcap
+	 */
+	const u8 args[SI4713_TXPWR_NARGS] = {
+		0x00,
+		0x00,
+		power,
+		antcap,
+	};
+
+	if (((power > 0) && (power < SI4713_MIN_POWER)) ||
+		power > SI4713_MAX_POWER || antcap > SI4713_MAX_ANTCAP)
+		return -EDOM;
+
+	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER,
+				  args, ARRAY_SIZE(args), val,
+				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
+
+	if (err < 0)
+		return err;
+
+	v4l2_dbg(1, debug, &sdev->sd,
+			"%s: power=0x%02x antcap=0x%02x status=0x%02x\n",
+			__func__, power, antcap, val[0]);
+
+	return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE_POWER);
+}
+
+/*
+ * si4713_tx_tune_measure - Enters receive mode and measures the received noise
+ * 			level in units of dBuV on the selected frequency.
+ * 			The Frequency must be between 76 and 108 MHz in 10 kHz
+ * 			units and steps of 50 kHz. The command also sets the
+ * 			antenna	tuning capacitance. A value of 0 means
+ * 			autotuning, and a value of 1 to 191 indicates manual
+ * 			override.
+ * @sdev: si4713_device structure for the device we are communicating
+ * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
+ * @antcap: value of antenna tuning capacitor (0 - 191)
+ */
+static int si4713_tx_tune_measure(struct si4713_device *sdev, u16 frequency,
+					u8 antcap)
+{
+	int err;
+	u8 val[SI4713_TXMEA_NRESP];
+	/*
+	 * 	.First byte = 0
+	 * 	.Second byte = frequency's MSB
+	 * 	.Third byte = frequency's LSB
+	 * 	.Fourth byte = antcap
+	 */
+	const u8 args[SI4713_TXMEA_NARGS] = {
+		0x00,
+		msb(frequency),
+		lsb(frequency),
+		antcap,
+	};
+
+	sdev->tune_rnl = DEFAULT_TUNE_RNL;
+
+	if (antcap > SI4713_MAX_ANTCAP)
+		return -EDOM;
+
+	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_MEASURE,
+				  args, ARRAY_SIZE(args), val,
+				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
+
+	if (err < 0)
+		return err;
+
+	v4l2_dbg(1, debug, &sdev->sd,
+			"%s: frequency=0x%02x antcap=0x%02x status=0x%02x\n",
+			__func__, frequency, antcap, val[0]);
+
+	return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
+}
+
+/*
+ * si4713_tx_tune_status- Returns the status of the tx_tune_freq, tx_tune_mea or
+ * 			tx_tune_power commands. This command return the current
+ * 			frequency, output voltage in dBuV, the antenna tunning
+ * 			capacitance value and the received noise level. The
+ * 			command also clears the stcint interrupt bit when the
+ * 			first bit of its arguments is high.
+ * @sdev: si4713_device structure for the device we are communicating
+ * @intack: 0x01 to clear the seek/tune complete interrupt status indicator.
+ * @frequency: returned frequency
+ * @power: returned power
+ * @antcap: returned antenna capacitance
+ * @noise: returned noise level
+ */
+static int si4713_tx_tune_status(struct si4713_device *sdev, u8 intack,
+					u16 *frequency,	u8 *power,
+					u8 *antcap, u8 *noise)
+{
+	int err;
+	u8 val[SI4713_TXSTATUS_NRESP];
+	/*
+	 * 	.First byte = intack bit
+	 */
+	const u8 args[SI4713_TXSTATUS_NARGS] = {
+		intack & SI4713_INTACK_MASK,
+	};
+
+	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_STATUS,
+				  args, ARRAY_SIZE(args), val,
+				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
+
+	if (!err) {
+		v4l2_dbg(1, debug, &sdev->sd,
+			"%s: status=0x%02x\n", __func__, val[0]);
+		*frequency = compose_u16(val[2], val[3]);
+		sdev->frequency = *frequency;
+		*power = val[5];
+		*antcap = val[6];
+		*noise = val[7];
+		v4l2_dbg(1, debug, &sdev->sd, "%s: response: %d x 10 kHz "
+				"(power %d, antcap %d, rnl %d)\n", __func__,
+				*frequency, *power, *antcap, *noise);
+	}
+
+	return err;
+}
+
+/*
+ * si4713_tx_rds_buff - Loads the RDS group buffer FIFO or circular buffer.
+ * @sdev: si4713_device structure for the device we are communicating
+ * @mode: the buffer operation mode.
+ * @rdsb: RDS Block B
+ * @rdsc: RDS Block C
+ * @rdsd: RDS Block D
+ * @cbleft: returns the number of available circular buffer blocks minus the
+ *          number of used circular buffer blocks.
+ */
+static int si4713_tx_rds_buff(struct si4713_device *sdev, u8 mode, u16 rdsb,
+				u16 rdsc, u16 rdsd, s8 *cbleft)
+{
+	int err;
+	u8 val[SI4713_RDSBUFF_NRESP];
+
+	const u8 args[SI4713_RDSBUFF_NARGS] = {
+		mode & SI4713_RDSBUFF_MODE_MASK,
+		msb(rdsb),
+		lsb(rdsb),
+		msb(rdsc),
+		lsb(rdsc),
+		msb(rdsd),
+		lsb(rdsd),
+	};
+
+	err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_BUFF,
+				  args, ARRAY_SIZE(args), val,
+				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
+
+	if (!err) {
+		v4l2_dbg(1, debug, &sdev->sd,
+			"%s: status=0x%02x\n", __func__, val[0]);
+		*cbleft = (s8)val[2] - val[3];
+		v4l2_dbg(1, debug, &sdev->sd, "%s: response: interrupts"
+				" 0x%02x cb avail: %d cb used %d fifo avail"
+				" %d fifo used %d\n", __func__, val[1],
+				val[2], val[3], val[4], val[5]);
+	}
+
+	return err;
+}
+
+/*
+ * si4713_tx_rds_ps - Loads the program service buffer.
+ * @sdev: si4713_device structure for the device we are communicating
+ * @psid: program service id to be loaded.
+ * @pschar: assumed 4 size char array to be loaded into the program service
+ */
+static int si4713_tx_rds_ps(struct si4713_device *sdev, u8 psid,
+				unsigned char *pschar)
+{
+	int err;
+	u8 val[SI4713_RDSPS_NRESP];
+
+	const u8 args[SI4713_RDSPS_NARGS] = {
+		psid & SI4713_RDSPS_PSID_MASK,
+		pschar[0],
+		pschar[1],
+		pschar[2],
+		pschar[3],
+	};
+
+	err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_PS,
+				  args, ARRAY_SIZE(args), val,
+				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
+
+	if (err < 0)
+		return err;
+
+	v4l2_dbg(1, debug, &sdev->sd, "%s: status=0x%02x\n", __func__, val[0]);
+
+	return err;
+}
+
+static int si4713_set_power_state(struct si4713_device *sdev, u8 value)
+{
+	int rval;
+
+	mutex_lock(&sdev->mutex);
+
+	if (value)
+		rval = si4713_powerup(sdev);
+	else
+		rval = si4713_powerdown(sdev);
+
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+static int si4713_set_mute(struct si4713_device *sdev, u16 mute)
+{
+	int rval = 0;
+
+	mute = set_mute(mute);
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state)
+		rval = si4713_write_property(sdev,
+				SI4713_TX_LINE_INPUT_MUTE, mute);
+
+	if (rval >= 0)
+		sdev->mute = get_mute(mute);
+
+	mutex_unlock(&sdev->mutex);
+
+	return rval;
+}
+
+static int si4713_set_rds_ps_name(struct si4713_device *sdev, char *ps_name)
+{
+	int rval = 0, i;
+	u8 len = 0;
+
+	/* We want to clear the whole thing */
+	if (!strlen(ps_name))
+		memset(ps_name, 0, MAX_RDS_PS_NAME + 1);
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		/* Write the new ps name and clear the padding */
+		for (i = 0; i < MAX_RDS_PS_NAME; i += (RDS_BLOCK / 2)) {
+			rval = si4713_tx_rds_ps(sdev, (i / (RDS_BLOCK / 2)),
+						ps_name + i);
+			if (rval < 0)
+				goto unlock;
+		}
+
+		/* Setup the size to be sent */
+		if (strlen(ps_name))
+			len = strlen(ps_name) - 1;
+		else
+			len = 1;
+
+		rval = si4713_write_property(sdev,
+				SI4713_TX_RDS_PS_MESSAGE_COUNT,
+				rds_ps_nblocks(len));
+		if (rval < 0)
+			goto unlock;
+
+		rval = si4713_write_property(sdev,
+				SI4713_TX_RDS_PS_REPEAT_COUNT,
+				DEFAULT_RDS_PS_REPEAT_COUNT * 2);
+		if (rval < 0)
+			goto unlock;
+	}
+
+	strncpy(sdev->rds_info.ps_name, ps_name, MAX_RDS_PS_NAME);
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+static int si4713_set_rds_radio_text(struct si4713_device *sdev, char *rt)
+{
+	int rval = 0, i;
+	u16 t_index = 0;
+	u8 b_index = 0, cr_inserted = 0;
+	s8 left;
+
+	mutex_lock(&sdev->mutex);
+
+	if (!sdev->power_state)
+		goto copy;
+
+	rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_CLEAR, 0, 0, 0, &left);
+	if (rval < 0)
+		goto unlock;
+
+	if (!strlen(rt))
+		goto copy;
+
+	do {
+		/* RDS spec says that if the last block isn't used,
+		 * then apply a carriage return
+		 */
+		if (t_index < (RDS_RADIOTEXT_INDEX_MAX *
+			RDS_RADIOTEXT_BLK_SIZE)) {
+			for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) {
+				if (!rt[t_index + i] || rt[t_index + i] ==
+					RDS_CARRIAGE_RETURN) {
+					rt[t_index + i] = RDS_CARRIAGE_RETURN;
+					cr_inserted = 1;
+					break;
+				}
+			}
+		}
+
+		rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_LOAD,
+				compose_u16(RDS_RADIOTEXT_2A, b_index++),
+				compose_u16(rt[t_index], rt[t_index + 1]),
+				compose_u16(rt[t_index + 2], rt[t_index + 3]),
+				&left);
+		if (rval < 0)
+			goto unlock;
+
+		t_index += RDS_RADIOTEXT_BLK_SIZE;
+
+		if (cr_inserted)
+			break;
+	} while (left > 0);
+
+copy:
+	strncpy(sdev->rds_info.radio_text, rt, MAX_RDS_RADIO_TEXT);
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
+		u32 **shadow, s32 *bit, s32 *mask, u16 *property, int *mul,
+		unsigned long **table, int *size)
+{
+	s32 rval = 0;
+
+	switch (id) {
+	/* FM_TX class controls */
+	case V4L2_CID_RDS_TX_PI:
+		*property = SI4713_TX_RDS_PI;
+		*mul = 1;
+		*shadow = &sdev->rds_info.pi;
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
+		*property = SI4713_TX_ACOMP_THRESHOLD;
+		*mul = 1;
+		*shadow = &sdev->acomp_info.threshold;
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_GAIN:
+		*property = SI4713_TX_ACOMP_GAIN;
+		*mul = 1;
+		*shadow = &sdev->acomp_info.gain;
+		break;
+	case V4L2_CID_PILOT_TONE_FREQUENCY:
+		*property = SI4713_TX_PILOT_FREQUENCY;
+		*mul = 1;
+		*shadow = &sdev->pilot_info.frequency;
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
+		*property = SI4713_TX_ACOMP_ATTACK_TIME;
+		*mul = ATTACK_TIME_UNIT;
+		*shadow = &sdev->acomp_info.attack_time;
+		break;
+	case V4L2_CID_PILOT_TONE_DEVIATION:
+		*property = SI4713_TX_PILOT_DEVIATION;
+		*mul = 10;
+		*shadow = &sdev->pilot_info.deviation;
+		break;
+	case V4L2_CID_AUDIO_LIMITER_DEVIATION:
+		*property = SI4713_TX_AUDIO_DEVIATION;
+		*mul = 10;
+		*shadow = &sdev->limiter_info.deviation;
+		break;
+	case V4L2_CID_RDS_TX_DEVIATION:
+		*property = SI4713_TX_RDS_DEVIATION;
+		*mul = 1;
+		*shadow = &sdev->rds_info.deviation;
+		break;
+
+	case V4L2_CID_RDS_TX_PTY:
+		*property = SI4713_TX_RDS_PS_MISC;
+		*bit = 5;
+		*mask = 0x1F << 5;
+		*shadow = &sdev->rds_info.pty;
+		break;
+	case V4L2_CID_AUDIO_LIMITER_ENABLED:
+		*property = SI4713_TX_ACOMP_ENABLE;
+		*bit = 1;
+		*mask = 1 << 1;
+		*shadow = &sdev->limiter_info.enabled;
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
+		*property = SI4713_TX_ACOMP_ENABLE;
+		*bit = 0;
+		*mask = 1 << 0;
+		*shadow = &sdev->acomp_info.enabled;
+		break;
+	case V4L2_CID_PILOT_TONE_ENABLED:
+		*property = SI4713_TX_COMPONENT_ENABLE;
+		*bit = 0;
+		*mask = 1 << 0;
+		*shadow = &sdev->pilot_info.enabled;
+		break;
+
+	case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
+		*property = SI4713_TX_LIMITER_RELEASE_TIME;
+		*table = limiter_times;
+		*size = ARRAY_SIZE(limiter_times);
+		*shadow = &sdev->limiter_info.release_time;
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
+		*property = SI4713_TX_ACOMP_RELEASE_TIME;
+		*table = acomp_rtimes;
+		*size = ARRAY_SIZE(acomp_rtimes);
+		*shadow = &sdev->acomp_info.release_time;
+		break;
+	case V4L2_CID_TUNE_PREEMPHASIS:
+		*property = SI4713_TX_PREEMPHASIS;
+		*table = preemphasis_values;
+		*size = ARRAY_SIZE(preemphasis_values);
+		*shadow = &sdev->preemphasis;
+		break;
+
+	default:
+		rval = -EINVAL;
+	};
+
+	return rval;
+}
+
+static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
+
+/* write string property */
+static int si4713_write_econtrol_string(struct si4713_device *sdev,
+				struct v4l2_ext_control *control)
+{
+	struct v4l2_queryctrl vqc;
+	int len;
+	s32 rval = 0;
+
+	vqc.id = control->id;
+	rval = si4713_queryctrl(&sdev->sd, &vqc);
+	if (rval < 0)
+		goto exit;
+
+	switch (control->id) {
+	case V4L2_CID_RDS_TX_PS_NAME: {
+		char ps_name[MAX_RDS_PS_NAME + 1];
+
+		len = control->size - 1;
+		if (len > MAX_RDS_PS_NAME) {
+			rval = -ERANGE;
+			goto exit;
+		}
+		rval = copy_from_user(ps_name, control->string, len);
+		if (rval < 0)
+			goto exit;
+		ps_name[len] = '\0';
+
+		if (strlen(ps_name) % vqc.step) {
+			rval = -ERANGE;
+			goto exit;
+		}
+
+		rval = si4713_set_rds_ps_name(sdev, ps_name);
+	}
+		break;
+
+	case V4L2_CID_RDS_TX_RADIO_TEXT: {
+		char radio_text[MAX_RDS_RADIO_TEXT + 1];
+
+		len = control->size - 1;
+		if (len > MAX_RDS_RADIO_TEXT) {
+			rval = -ERANGE;
+			goto exit;
+		}
+		rval = copy_from_user(radio_text, control->string, len);
+		if (rval < 0)
+			goto exit;
+		radio_text[len] = '\0';
+
+		if (strlen(radio_text) % vqc.step) {
+			rval = -ERANGE;
+			goto exit;
+		}
+
+		rval = si4713_set_rds_radio_text(sdev, radio_text);
+	}
+		break;
+
+	default:
+		rval = -EINVAL;
+		break;
+	};
+
+exit:
+	return rval;
+}
+
+static int validate_range(struct v4l2_subdev *sd,
+					struct v4l2_ext_control *control)
+{
+	struct v4l2_queryctrl vqc;
+	int rval;
+
+	vqc.id = control->id;
+	rval = si4713_queryctrl(sd, &vqc);
+	if (rval < 0)
+		goto exit;
+
+	if (control->value < vqc.minimum || control->value > vqc.maximum)
+		rval = -ERANGE;
+
+exit:
+	return rval;
+}
+
+/* properties which use tx_tune_power*/
+static int si4713_write_econtrol_tune(struct si4713_device *sdev,
+				struct v4l2_ext_control *control)
+{
+	s32 rval = 0;
+	u8 power, antcap;
+
+	rval = validate_range(&sdev->sd, control);
+	if (rval < 0)
+		goto exit;
+
+	mutex_lock(&sdev->mutex);
+
+	switch (control->id) {
+	case V4L2_CID_TUNE_POWER_LEVEL:
+		power = control->value;
+		antcap = sdev->antenna_capacitor;
+		break;
+	case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+		power = sdev->power_level;
+		antcap = control->value;
+		break;
+	default:
+		rval = -EINVAL;
+		goto unlock;
+	};
+
+	if (sdev->power_state)
+		rval = si4713_tx_tune_power(sdev, power, antcap);
+
+	if (rval == 0) {
+		sdev->power_level = power;
+		sdev->antenna_capacitor = antcap;
+	}
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+exit:
+	return rval;
+}
+
+static int si4713_write_econtrol_integers(struct si4713_device *sdev,
+					struct v4l2_ext_control *control)
+{
+	s32 rval;
+	u32 *shadow = NULL, val = 0;
+	s32 bit = 0, mask = 0;
+	u16 property = 0;
+	int mul = 0;
+	unsigned long *table = NULL;
+	int size = 0;
+
+	rval = validate_range(&sdev->sd, control);
+	if (rval < 0)
+		goto exit;
+
+	rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit,
+			&mask, &property, &mul, &table, &size);
+	if (rval < 0)
+		goto exit;
+
+	val = control->value;
+	if (mul) {
+		val = control->value / mul;
+	} else if (table) {
+		rval = usecs_to_dev(control->value, table, size);
+		if (rval < 0)
+			goto exit;
+		val = rval;
+		rval = 0;
+	}
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		if (mask) {
+			rval = si4713_read_property(sdev, property, &val);
+			if (rval < 0)
+				goto unlock;
+			val = set_bits(val, control->value, bit, mask);
+		}
+
+		rval = si4713_write_property(sdev, property, val);
+		if (rval < 0)
+			goto unlock;
+		if (mask)
+			val = control->value;
+	}
+
+	if (mul) {
+		*shadow = val * mul;
+	} else if (table) {
+		rval = dev_to_usecs(val, table, size);
+		if (rval < 0)
+			goto unlock;
+		*shadow = rval;
+		rval = 0;
+	} else {
+		*shadow = val;
+	}
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+exit:
+	return rval;
+}
+
+static int si4713_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f);
+static int si4713_s_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *);
+/*
+ * si4713_setup - Sets the device up with current configuration.
+ * @sdev: si4713_device structure for the device we are communicating
+ */
+static int si4713_setup(struct si4713_device *sdev)
+{
+	struct v4l2_ext_control ctrl;
+	struct v4l2_frequency f;
+	struct v4l2_modulator vm;
+	struct si4713_device *tmp;
+	int rval = 0;
+
+	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	/* Get a local copy to avoid race */
+	mutex_lock(&sdev->mutex);
+	memcpy(tmp, sdev, sizeof(*sdev));
+	mutex_unlock(&sdev->mutex);
+
+	ctrl.id = V4L2_CID_RDS_TX_PI;
+	ctrl.value = tmp->rds_info.pi;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_COMPRESSION_THRESHOLD;
+	ctrl.value = tmp->acomp_info.threshold;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_COMPRESSION_GAIN;
+	ctrl.value = tmp->acomp_info.gain;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_PILOT_TONE_FREQUENCY;
+	ctrl.value = tmp->pilot_info.frequency;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME;
+	ctrl.value = tmp->acomp_info.attack_time;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_PILOT_TONE_DEVIATION;
+	ctrl.value = tmp->pilot_info.deviation;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_LIMITER_DEVIATION;
+	ctrl.value = tmp->limiter_info.deviation;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_RDS_TX_DEVIATION;
+	ctrl.value = tmp->rds_info.deviation;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_RDS_TX_PTY;
+	ctrl.value = tmp->rds_info.pty;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_LIMITER_ENABLED;
+	ctrl.value = tmp->limiter_info.enabled;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ENABLED;
+	ctrl.value = tmp->acomp_info.enabled;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_PILOT_TONE_ENABLED;
+	ctrl.value = tmp->pilot_info.enabled;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_LIMITER_RELEASE_TIME;
+	ctrl.value = tmp->limiter_info.release_time;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME;
+	ctrl.value = tmp->acomp_info.release_time;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_TUNE_PREEMPHASIS;
+	ctrl.value = tmp->preemphasis;
+	rval |= si4713_write_econtrol_integers(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_RDS_TX_PS_NAME;
+	rval |= si4713_set_rds_ps_name(sdev, tmp->rds_info.ps_name);
+
+	ctrl.id = V4L2_CID_RDS_TX_RADIO_TEXT;
+	rval |= si4713_set_rds_radio_text(sdev, tmp->rds_info.radio_text);
+
+	/* Device procedure needs to set frequency first */
+	f.frequency = tmp->frequency ? tmp->frequency : DEFAULT_FREQUENCY;
+	f.frequency = si4713_to_v4l2(f.frequency);
+	rval |= si4713_s_frequency(&sdev->sd, &f);
+
+	ctrl.id = V4L2_CID_TUNE_POWER_LEVEL;
+	ctrl.value = tmp->power_level;
+	rval |= si4713_write_econtrol_tune(sdev, &ctrl);
+
+	ctrl.id = V4L2_CID_TUNE_ANTENNA_CAPACITOR;
+	ctrl.value = tmp->antenna_capacitor;
+	rval |= si4713_write_econtrol_tune(sdev, &ctrl);
+
+	vm.index = 0;
+	if (tmp->stereo)
+		vm.txsubchans = V4L2_TUNER_SUB_STEREO;
+	else
+		vm.txsubchans = V4L2_TUNER_SUB_MONO;
+	if (tmp->rds_info.enabled)
+		vm.txsubchans |= V4L2_TUNER_SUB_RDS;
+	si4713_s_modulator(&sdev->sd, &vm);
+
+	kfree(tmp);
+
+	return rval;
+}
+
+/*
+ * si4713_initialize - Sets the device up with default configuration.
+ * @sdev: si4713_device structure for the device we are communicating
+ */
+static int si4713_initialize(struct si4713_device *sdev)
+{
+	int rval;
+
+	rval = si4713_set_power_state(sdev, POWER_ON);
+	if (rval < 0)
+		goto exit;
+
+	rval = si4713_checkrev(sdev);
+	if (rval < 0)
+		goto exit;
+
+	rval = si4713_set_power_state(sdev, POWER_OFF);
+	if (rval < 0)
+		goto exit;
+
+	mutex_lock(&sdev->mutex);
+
+	sdev->rds_info.pi = DEFAULT_RDS_PI;
+	sdev->rds_info.pty = DEFAULT_RDS_PTY;
+	sdev->rds_info.deviation = DEFAULT_RDS_DEVIATION;
+	strlcpy(sdev->rds_info.ps_name, DEFAULT_RDS_PS_NAME, MAX_RDS_PS_NAME);
+	strlcpy(sdev->rds_info.radio_text, DEFAULT_RDS_RADIO_TEXT,
+							MAX_RDS_RADIO_TEXT);
+	sdev->rds_info.enabled = 1;
+
+	sdev->limiter_info.release_time = DEFAULT_LIMITER_RTIME;
+	sdev->limiter_info.deviation = DEFAULT_LIMITER_DEV;
+	sdev->limiter_info.enabled = 1;
+
+	sdev->pilot_info.deviation = DEFAULT_PILOT_DEVIATION;
+	sdev->pilot_info.frequency = DEFAULT_PILOT_FREQUENCY;
+	sdev->pilot_info.enabled = 1;
+
+	sdev->acomp_info.release_time = DEFAULT_ACOMP_RTIME;
+	sdev->acomp_info.attack_time = DEFAULT_ACOMP_ATIME;
+	sdev->acomp_info.threshold = DEFAULT_ACOMP_THRESHOLD;
+	sdev->acomp_info.gain = DEFAULT_ACOMP_GAIN;
+	sdev->acomp_info.enabled = 1;
+
+	sdev->frequency = DEFAULT_FREQUENCY;
+	sdev->preemphasis = DEFAULT_PREEMPHASIS;
+	sdev->mute = DEFAULT_MUTE;
+	sdev->power_level = DEFAULT_POWER_LEVEL;
+	sdev->antenna_capacitor = 0;
+	sdev->stereo = 1;
+	sdev->tune_rnl = DEFAULT_TUNE_RNL;
+
+	mutex_unlock(&sdev->mutex);
+
+exit:
+	return rval;
+}
+
+/* read string property */
+static int si4713_read_econtrol_string(struct si4713_device *sdev,
+				struct v4l2_ext_control *control)
+{
+	s32 rval = 0;
+
+	switch (control->id) {
+	case V4L2_CID_RDS_TX_PS_NAME:
+		if (strlen(sdev->rds_info.ps_name) + 1 > control->size) {
+			control->size = MAX_RDS_PS_NAME + 1;
+			rval = -ENOSPC;
+			goto exit;
+		}
+		rval = copy_to_user(control->string, sdev->rds_info.ps_name,
+					strlen(sdev->rds_info.ps_name) + 1);
+		break;
+
+	case V4L2_CID_RDS_TX_RADIO_TEXT:
+		if (strlen(sdev->rds_info.radio_text) + 1 > control->size) {
+			control->size = MAX_RDS_RADIO_TEXT + 1;
+			rval = -ENOSPC;
+			goto exit;
+		}
+		rval = copy_to_user(control->string, sdev->rds_info.radio_text,
+					strlen(sdev->rds_info.radio_text) + 1);
+		break;
+
+	default:
+		rval = -EINVAL;
+		break;
+	};
+
+exit:
+	return rval;
+}
+
+/*
+ * si4713_update_tune_status - update properties from tx_tune_status
+ * command. Must be called with sdev->mutex held.
+ * @sdev: si4713_device structure for the device we are communicating
+ */
+static int si4713_update_tune_status(struct si4713_device *sdev)
+{
+	int rval;
+	u16 f = 0;
+	u8 p = 0, a = 0, n = 0;
+
+	rval = si4713_tx_tune_status(sdev, 0x00, &f, &p, &a, &n);
+
+	if (rval < 0)
+		goto exit;
+
+	sdev->power_level = p;
+	sdev->antenna_capacitor = a;
+	sdev->tune_rnl = n;
+
+exit:
+	return rval;
+}
+
+/* properties which use tx_tune_status */
+static int si4713_read_econtrol_tune(struct si4713_device *sdev,
+				struct v4l2_ext_control *control)
+{
+	s32 rval = 0;
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		rval = si4713_update_tune_status(sdev);
+		if (rval < 0)
+			goto unlock;
+	}
+
+	switch (control->id) {
+	case V4L2_CID_TUNE_POWER_LEVEL:
+		control->value = sdev->power_level;
+		break;
+	case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+		control->value = sdev->antenna_capacitor;
+		break;
+	default:
+		rval = -EINVAL;
+	};
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+static int si4713_read_econtrol_integers(struct si4713_device *sdev,
+				struct v4l2_ext_control *control)
+{
+	s32 rval;
+	u32 *shadow = NULL, val = 0;
+	s32 bit = 0, mask = 0;
+	u16 property = 0;
+	int mul = 0;
+	unsigned long *table = NULL;
+	int size = 0;
+
+	rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit,
+			&mask, &property, &mul, &table, &size);
+	if (rval < 0)
+		goto exit;
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		rval = si4713_read_property(sdev, property, &val);
+		if (rval < 0)
+			goto unlock;
+
+		/* Keep negative values for threshold */
+		if (control->id == V4L2_CID_AUDIO_COMPRESSION_THRESHOLD)
+			*shadow = (s16)val;
+		else if (mask)
+			*shadow = get_status_bit(val, bit, mask);
+		else if (mul)
+			*shadow = val * mul;
+		else
+			*shadow = dev_to_usecs(val, table, size);
+	}
+
+	control->value = *shadow;
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+exit:
+	return rval;
+}
+
+/*
+ * Video4Linux Subdev Interface
+ */
+/* si4713_s_ext_ctrls - set extended controls value */
+static int si4713_s_ext_ctrls(struct v4l2_subdev *sd,
+				struct v4l2_ext_controls *ctrls)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int i;
+
+	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
+		return -EINVAL;
+
+	for (i = 0; i < ctrls->count; i++) {
+		int err;
+
+		switch ((ctrls->controls + i)->id) {
+		case V4L2_CID_RDS_TX_PS_NAME:
+		case V4L2_CID_RDS_TX_RADIO_TEXT:
+			err = si4713_write_econtrol_string(sdev,
+							ctrls->controls + i);
+			break;
+		case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+		case V4L2_CID_TUNE_POWER_LEVEL:
+			err = si4713_write_econtrol_tune(sdev,
+							ctrls->controls + i);
+			break;
+		default:
+			err = si4713_write_econtrol_integers(sdev,
+							ctrls->controls + i);
+		}
+
+		if (err < 0) {
+			ctrls->error_idx = i;
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+/* si4713_g_ext_ctrls - get extended controls value */
+static int si4713_g_ext_ctrls(struct v4l2_subdev *sd,
+				struct v4l2_ext_controls *ctrls)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int i;
+
+	if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
+		return -EINVAL;
+
+	for (i = 0; i < ctrls->count; i++) {
+		int err;
+
+		switch ((ctrls->controls + i)->id) {
+		case V4L2_CID_RDS_TX_PS_NAME:
+		case V4L2_CID_RDS_TX_RADIO_TEXT:
+			err = si4713_read_econtrol_string(sdev,
+							ctrls->controls + i);
+			break;
+		case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+		case V4L2_CID_TUNE_POWER_LEVEL:
+			err = si4713_read_econtrol_tune(sdev,
+							ctrls->controls + i);
+			break;
+		default:
+			err = si4713_read_econtrol_integers(sdev,
+							ctrls->controls + i);
+		}
+
+		if (err < 0) {
+			ctrls->error_idx = i;
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+/* si4713_queryctrl - enumerate control items */
+static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+	int rval = 0;
+
+	switch (qc->id) {
+	/* User class controls */
+	case V4L2_CID_AUDIO_MUTE:
+		rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, DEFAULT_MUTE);
+		break;
+	/* FM_TX class controls */
+	case V4L2_CID_RDS_TX_PI:
+		rval = v4l2_ctrl_query_fill(qc, 0, 0xFFFF, 1, DEFAULT_RDS_PI);
+		break;
+	case V4L2_CID_RDS_TX_PTY:
+		rval = v4l2_ctrl_query_fill(qc, 0, 31, 1, DEFAULT_RDS_PTY);
+		break;
+	case V4L2_CID_RDS_TX_DEVIATION:
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_DEVIATION,
+						10, DEFAULT_RDS_DEVIATION);
+		break;
+	case V4L2_CID_RDS_TX_PS_NAME:
+		/*
+		 * Report step as 8. From RDS spec, psname
+		 * should be 8. But there are receivers which scroll strings
+		 * sized as 8xN.
+		 */
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_PS_NAME, 8, 0);
+		break;
+	case V4L2_CID_RDS_TX_RADIO_TEXT:
+		/*
+		 * Report step as 32 (2A block). From RDS spec,
+		 * radio text should be 32 for 2A block. But there are receivers
+		 * which scroll strings sized as 32xN. Setting default to 32.
+		 */
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_RADIO_TEXT, 32, 0);
+		break;
+
+	case V4L2_CID_AUDIO_LIMITER_ENABLED:
+		rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+		break;
+	case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
+		rval = v4l2_ctrl_query_fill(qc, 250, MAX_LIMITER_RELEASE_TIME,
+						50, DEFAULT_LIMITER_RTIME);
+		break;
+	case V4L2_CID_AUDIO_LIMITER_DEVIATION:
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_LIMITER_DEVIATION,
+						10, DEFAULT_LIMITER_DEV);
+		break;
+
+	case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
+		rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_GAIN:
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_GAIN, 1,
+						DEFAULT_ACOMP_GAIN);
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
+		rval = v4l2_ctrl_query_fill(qc, MIN_ACOMP_THRESHOLD,
+						MAX_ACOMP_THRESHOLD, 1,
+						DEFAULT_ACOMP_THRESHOLD);
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_ATTACK_TIME,
+						500, DEFAULT_ACOMP_ATIME);
+		break;
+	case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
+		rval = v4l2_ctrl_query_fill(qc, 100000, MAX_ACOMP_RELEASE_TIME,
+						100000, DEFAULT_ACOMP_RTIME);
+		break;
+
+	case V4L2_CID_PILOT_TONE_ENABLED:
+		rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+		break;
+	case V4L2_CID_PILOT_TONE_DEVIATION:
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_DEVIATION,
+						10, DEFAULT_PILOT_DEVIATION);
+		break;
+	case V4L2_CID_PILOT_TONE_FREQUENCY:
+		rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_FREQUENCY,
+						1, DEFAULT_PILOT_FREQUENCY);
+		break;
+
+	case V4L2_CID_TUNE_PREEMPHASIS:
+		rval = v4l2_ctrl_query_fill(qc, V4L2_PREEMPHASIS_DISABLED,
+						V4L2_PREEMPHASIS_75_uS, 1,
+						V4L2_PREEMPHASIS_50_uS);
+		break;
+	case V4L2_CID_TUNE_POWER_LEVEL:
+		rval = v4l2_ctrl_query_fill(qc, 0, 120, 1, DEFAULT_POWER_LEVEL);
+		break;
+	case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+		rval = v4l2_ctrl_query_fill(qc, 0, 191, 1, 0);
+		break;
+	default:
+		rval = -EINVAL;
+		break;
+	};
+
+	return rval;
+}
+
+/* si4713_g_ctrl - get the value of a control */
+static int si4713_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int rval = 0;
+
+	if (!sdev)
+		return -ENODEV;
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		rval = si4713_read_property(sdev, SI4713_TX_LINE_INPUT_MUTE,
+						&sdev->mute);
+
+		if (rval < 0)
+			goto unlock;
+	}
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		ctrl->value = get_mute(sdev->mute);
+		break;
+	}
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+/* si4713_s_ctrl - set the value of a control */
+static int si4713_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int rval = 0;
+
+	if (!sdev)
+		return -ENODEV;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUDIO_MUTE:
+		if (ctrl->value) {
+			rval = si4713_set_mute(sdev, ctrl->value);
+			if (rval < 0)
+				goto exit;
+
+			rval = si4713_set_power_state(sdev, POWER_DOWN);
+		} else {
+			rval = si4713_set_power_state(sdev, POWER_UP);
+			if (rval < 0)
+				goto exit;
+
+			rval = si4713_setup(sdev);
+			if (rval < 0)
+				goto exit;
+
+			rval = si4713_set_mute(sdev, ctrl->value);
+		}
+		break;
+	}
+
+exit:
+	return rval;
+}
+
+/* si4713_ioctl - deal with private ioctls (only rnl for now) */
+long si4713_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	struct si4713_rnl *rnl = arg;
+	u16 frequency;
+	int rval = 0;
+
+	if (!arg)
+		return -EINVAL;
+
+	mutex_lock(&sdev->mutex);
+	switch (cmd) {
+	case SI4713_IOC_MEASURE_RNL:
+		frequency = v4l2_to_si4713(rnl->frequency);
+
+		if (sdev->power_state) {
+			/* Set desired measurement frequency */
+			rval = si4713_tx_tune_measure(sdev, frequency, 0);
+			if (rval < 0)
+				goto unlock;
+			/* get results from tune status */
+			rval = si4713_update_tune_status(sdev);
+			if (rval < 0)
+				goto unlock;
+		}
+		rnl->rnl = sdev->tune_rnl;
+		break;
+
+	default:
+		/* nothing */
+		rval = -ENOIOCTLCMD;
+	}
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+static const struct v4l2_subdev_core_ops si4713_subdev_core_ops = {
+	.queryctrl	= si4713_queryctrl,
+	.g_ext_ctrls	= si4713_g_ext_ctrls,
+	.s_ext_ctrls	= si4713_s_ext_ctrls,
+	.g_ctrl		= si4713_g_ctrl,
+	.s_ctrl		= si4713_s_ctrl,
+	.ioctl		= si4713_ioctl,
+};
+
+/* si4713_g_modulator - get modulator attributes */
+static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int rval = 0;
+
+	if (!sdev) {
+		rval = -ENODEV;
+		goto exit;
+	}
+
+	if (vm->index > 0) {
+		rval = -EINVAL;
+		goto exit;
+	}
+
+	strncpy(vm->name, "FM Modulator", 32);
+	vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW |
+						V4L2_TUNER_CAP_RDS;
+
+	/* Report current frequency range limits */
+	vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW);
+	vm->rangehigh = si4713_to_v4l2(FREQ_RANGE_HIGH);
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		u32 comp_en = 0;
+
+		rval = si4713_read_property(sdev, SI4713_TX_COMPONENT_ENABLE,
+						&comp_en);
+		if (rval < 0)
+			goto unlock;
+
+		sdev->stereo = get_status_bit(comp_en, 1, 1 << 1);
+		sdev->rds_info.enabled = get_status_bit(comp_en, 2, 1 << 2);
+	}
+
+	/* Report current audio mode: mono or stereo */
+	if (sdev->stereo)
+		vm->txsubchans = V4L2_TUNER_SUB_STEREO;
+	else
+		vm->txsubchans = V4L2_TUNER_SUB_MONO;
+
+	/* Report rds feature status */
+	if (sdev->rds_info.enabled)
+		vm->txsubchans |= V4L2_TUNER_SUB_RDS;
+	else
+		vm->txsubchans &= ~V4L2_TUNER_SUB_RDS;
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+exit:
+	return rval;
+}
+
+/* si4713_s_modulator - set modulator attributes */
+static int si4713_s_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int rval = 0;
+	u16 stereo, rds;
+	u32 p;
+
+	if (!sdev)
+		return -ENODEV;
+
+	if (vm->index > 0)
+		return -EINVAL;
+
+	/* Set audio mode: mono or stereo */
+	if (vm->txsubchans & V4L2_TUNER_SUB_STEREO)
+		stereo = 1;
+	else if (vm->txsubchans & V4L2_TUNER_SUB_MONO)
+		stereo = 0;
+	else
+		return -EINVAL;
+
+	rds = !!(vm->txsubchans & V4L2_TUNER_SUB_RDS);
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		rval = si4713_read_property(sdev,
+						SI4713_TX_COMPONENT_ENABLE, &p);
+		if (rval < 0)
+			goto unlock;
+
+		p = set_bits(p, stereo, 1, 1 << 1);
+		p = set_bits(p, rds, 2, 1 << 2);
+
+		rval = si4713_write_property(sdev,
+						SI4713_TX_COMPONENT_ENABLE, p);
+		if (rval < 0)
+			goto unlock;
+	}
+
+	sdev->stereo = stereo;
+	sdev->rds_info.enabled = rds;
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+/* si4713_g_frequency - get tuner or modulator radio frequency */
+static int si4713_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int rval = 0;
+
+	f->type = V4L2_TUNER_RADIO;
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		u16 freq;
+		u8 p, a, n;
+
+		rval = si4713_tx_tune_status(sdev, 0x00, &freq, &p, &a, &n);
+		if (rval < 0)
+			goto unlock;
+
+		sdev->frequency = freq;
+	}
+
+	f->frequency = si4713_to_v4l2(sdev->frequency);
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+/* si4713_s_frequency - set tuner or modulator radio frequency */
+static int si4713_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
+{
+	struct si4713_device *sdev = to_si4713_device(sd);
+	int rval = 0;
+	u16 frequency = v4l2_to_si4713(f->frequency);
+
+	/* Check frequency range */
+	if (frequency < FREQ_RANGE_LOW || frequency > FREQ_RANGE_HIGH)
+		return -EDOM;
+
+	mutex_lock(&sdev->mutex);
+
+	if (sdev->power_state) {
+		rval = si4713_tx_tune_freq(sdev, frequency);
+		if (rval < 0)
+			goto unlock;
+		frequency = rval;
+		rval = 0;
+	}
+	sdev->frequency = frequency;
+	f->frequency = si4713_to_v4l2(frequency);
+
+unlock:
+	mutex_unlock(&sdev->mutex);
+	return rval;
+}
+
+static const struct v4l2_subdev_tuner_ops si4713_subdev_tuner_ops = {
+	.g_frequency	= si4713_g_frequency,
+	.s_frequency	= si4713_s_frequency,
+	.g_modulator	= si4713_g_modulator,
+	.s_modulator	= si4713_s_modulator,
+};
+
+static const struct v4l2_subdev_ops si4713_subdev_ops = {
+	.core		= &si4713_subdev_core_ops,
+	.tuner		= &si4713_subdev_tuner_ops,
+};
+
+/*
+ * I2C driver interface
+ */
+/* si4713_probe - probe for the device */
+static int si4713_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	struct si4713_device *sdev;
+	int rval;
+
+	sdev = kzalloc(sizeof *sdev, GFP_KERNEL);
+	if (!sdev) {
+		dev_err(&client->dev, "Failed to alloc video device.\n");
+		rval = -ENOMEM;
+		goto exit;
+	}
+
+	sdev->platform_data = client->dev.platform_data;
+	if (!sdev->platform_data) {
+		v4l2_err(&sdev->sd, "No platform data registered.\n");
+		rval = -ENODEV;
+		goto free_sdev;
+	}
+
+	v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops);
+
+	mutex_init(&sdev->mutex);
+	init_completion(&sdev->work);
+
+	if (client->irq) {
+		rval = request_irq(client->irq,
+			si4713_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED,
+			client->name, sdev);
+		if (rval < 0) {
+			v4l2_err(&sdev->sd, "Could not request IRQ\n");
+			goto free_sdev;
+		}
+		v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n");
+	} else {
+		v4l2_warn(&sdev->sd, "IRQ not configured. Using timeouts.\n");
+	}
+
+	rval = si4713_initialize(sdev);
+	if (rval < 0) {
+		v4l2_err(&sdev->sd, "Failed to probe device information.\n");
+		goto free_irq;
+	}
+
+	return 0;
+
+free_irq:
+	if (client->irq)
+		free_irq(client->irq, sdev);
+free_sdev:
+	kfree(sdev);
+exit:
+	return rval;
+}
+
+/* si4713_remove - remove the device */
+static int si4713_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct si4713_device *sdev = to_si4713_device(sd);
+
+	if (sdev->power_state)
+		si4713_set_power_state(sdev, POWER_DOWN);
+
+	if (client->irq > 0)
+		free_irq(client->irq, sdev);
+
+	v4l2_device_unregister_subdev(sd);
+
+	kfree(sdev);
+
+	return 0;
+}
+
+/* si4713_i2c_driver - i2c driver interface */
+static const struct i2c_device_id si4713_id[] = {
+	{ "si4713" , 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, si4713_id);
+
+static struct i2c_driver si4713_i2c_driver = {
+	.driver		= {
+		.name	= "si4713",
+	},
+	.probe		= si4713_probe,
+	.remove         = si4713_remove,
+	.id_table       = si4713_id,
+};
+
+/* Module Interface */
+static int __init si4713_module_init(void)
+{
+	return i2c_add_driver(&si4713_i2c_driver);
+}
+
+static void __exit si4713_module_exit(void)
+{
+	i2c_del_driver(&si4713_i2c_driver);
+}
+
+module_init(si4713_module_init);
+module_exit(si4713_module_exit);
+
diff --git a/drivers/media/radio/si4713-i2c.h b/drivers/media/radio/si4713-i2c.h
new file mode 100644
index 0000000..faf8cff
--- /dev/null
+++ b/drivers/media/radio/si4713-i2c.h
@@ -0,0 +1,237 @@
+/*
+ * drivers/media/radio/si4713-i2c.h
+ *
+ * Property and commands definitions for Si4713 radio transmitter chip.
+ *
+ * Copyright (c) 2008 Instituto Nokia de Tecnologia - INdT
+ * Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+
+#ifndef SI4713_I2C_H
+#define SI4713_I2C_H
+
+#include <media/v4l2-subdev.h>
+#include <media/si4713.h>
+
+#define SI4713_PRODUCT_NUMBER		0x0D
+
+/* Command Timeouts */
+#define DEFAULT_TIMEOUT			500
+#define TIMEOUT_SET_PROPERTY		20
+#define TIMEOUT_TX_TUNE_POWER		30000
+#define TIMEOUT_TX_TUNE			110000
+#define TIMEOUT_POWER_UP		200000
+
+/*
+ * Command and its arguments definitions
+ */
+#define SI4713_PWUP_CTSIEN		(1<<7)
+#define SI4713_PWUP_GPO2OEN		(1<<6)
+#define SI4713_PWUP_PATCH		(1<<5)
+#define SI4713_PWUP_XOSCEN		(1<<4)
+#define SI4713_PWUP_FUNC_TX		0x02
+#define SI4713_PWUP_FUNC_PATCH		0x0F
+#define SI4713_PWUP_OPMOD_ANALOG	0x50
+#define SI4713_PWUP_OPMOD_DIGITAL	0x0F
+#define SI4713_PWUP_NARGS		2
+#define SI4713_PWUP_NRESP		1
+#define SI4713_CMD_POWER_UP		0x01
+
+#define SI4713_GETREV_NRESP		9
+#define SI4713_CMD_GET_REV		0x10
+
+#define SI4713_PWDN_NRESP		1
+#define SI4713_CMD_POWER_DOWN		0x11
+
+#define SI4713_SET_PROP_NARGS		5
+#define SI4713_SET_PROP_NRESP		1
+#define SI4713_CMD_SET_PROPERTY		0x12
+
+#define SI4713_GET_PROP_NARGS		3
+#define SI4713_GET_PROP_NRESP		4
+#define SI4713_CMD_GET_PROPERTY		0x13
+
+#define SI4713_GET_STATUS_NRESP		1
+#define SI4713_CMD_GET_INT_STATUS	0x14
+
+#define SI4713_CMD_PATCH_ARGS		0x15
+#define SI4713_CMD_PATCH_DATA		0x16
+
+#define SI4713_MAX_FREQ			10800
+#define SI4713_MIN_FREQ			7600
+#define SI4713_TXFREQ_NARGS		3
+#define SI4713_TXFREQ_NRESP		1
+#define SI4713_CMD_TX_TUNE_FREQ		0x30
+
+#define SI4713_MAX_POWER		120
+#define SI4713_MIN_POWER		88
+#define SI4713_MAX_ANTCAP		191
+#define SI4713_MIN_ANTCAP		0
+#define SI4713_TXPWR_NARGS		4
+#define SI4713_TXPWR_NRESP		1
+#define SI4713_CMD_TX_TUNE_POWER	0x31
+
+#define SI4713_TXMEA_NARGS		4
+#define SI4713_TXMEA_NRESP		1
+#define SI4713_CMD_TX_TUNE_MEASURE	0x32
+
+#define SI4713_INTACK_MASK		0x01
+#define SI4713_TXSTATUS_NARGS		1
+#define SI4713_TXSTATUS_NRESP		8
+#define SI4713_CMD_TX_TUNE_STATUS	0x33
+
+#define SI4713_OVERMOD_BIT		(1 << 2)
+#define SI4713_IALH_BIT			(1 << 1)
+#define SI4713_IALL_BIT			(1 << 0)
+#define SI4713_ASQSTATUS_NARGS		1
+#define SI4713_ASQSTATUS_NRESP		5
+#define SI4713_CMD_TX_ASQ_STATUS	0x34
+
+#define SI4713_RDSBUFF_MODE_MASK	0x87
+#define SI4713_RDSBUFF_NARGS		7
+#define SI4713_RDSBUFF_NRESP		6
+#define SI4713_CMD_TX_RDS_BUFF		0x35
+
+#define SI4713_RDSPS_PSID_MASK		0x1F
+#define SI4713_RDSPS_NARGS		5
+#define SI4713_RDSPS_NRESP		1
+#define SI4713_CMD_TX_RDS_PS		0x36
+
+#define SI4713_CMD_GPO_CTL		0x80
+#define SI4713_CMD_GPO_SET		0x81
+
+/*
+ * Bits from status response
+ */
+#define SI4713_CTS			(1<<7)
+#define SI4713_ERR			(1<<6)
+#define SI4713_RDS_INT			(1<<2)
+#define SI4713_ASQ_INT			(1<<1)
+#define SI4713_STC_INT			(1<<0)
+
+/*
+ * Property definitions
+ */
+#define SI4713_GPO_IEN			0x0001
+#define SI4713_DIG_INPUT_FORMAT		0x0101
+#define SI4713_DIG_INPUT_SAMPLE_RATE	0x0103
+#define SI4713_REFCLK_FREQ		0x0201
+#define SI4713_REFCLK_PRESCALE		0x0202
+#define SI4713_TX_COMPONENT_ENABLE	0x2100
+#define SI4713_TX_AUDIO_DEVIATION	0x2101
+#define SI4713_TX_PILOT_DEVIATION	0x2102
+#define SI4713_TX_RDS_DEVIATION		0x2103
+#define SI4713_TX_LINE_INPUT_LEVEL	0x2104
+#define SI4713_TX_LINE_INPUT_MUTE	0x2105
+#define SI4713_TX_PREEMPHASIS		0x2106
+#define SI4713_TX_PILOT_FREQUENCY	0x2107
+#define SI4713_TX_ACOMP_ENABLE		0x2200
+#define SI4713_TX_ACOMP_THRESHOLD	0x2201
+#define SI4713_TX_ACOMP_ATTACK_TIME	0x2202
+#define SI4713_TX_ACOMP_RELEASE_TIME	0x2203
+#define SI4713_TX_ACOMP_GAIN		0x2204
+#define SI4713_TX_LIMITER_RELEASE_TIME	0x2205
+#define SI4713_TX_ASQ_INTERRUPT_SOURCE	0x2300
+#define SI4713_TX_ASQ_LEVEL_LOW		0x2301
+#define SI4713_TX_ASQ_DURATION_LOW	0x2302
+#define SI4713_TX_ASQ_LEVEL_HIGH	0x2303
+#define SI4713_TX_ASQ_DURATION_HIGH	0x2304
+#define SI4713_TX_RDS_INTERRUPT_SOURCE	0x2C00
+#define SI4713_TX_RDS_PI		0x2C01
+#define SI4713_TX_RDS_PS_MIX		0x2C02
+#define SI4713_TX_RDS_PS_MISC		0x2C03
+#define SI4713_TX_RDS_PS_REPEAT_COUNT	0x2C04
+#define SI4713_TX_RDS_PS_MESSAGE_COUNT	0x2C05
+#define SI4713_TX_RDS_PS_AF		0x2C06
+#define SI4713_TX_RDS_FIFO_SIZE		0x2C07
+
+#define PREEMPHASIS_USA			75
+#define PREEMPHASIS_EU			50
+#define PREEMPHASIS_DISABLED		0
+#define FMPE_USA			0x00
+#define FMPE_EU				0x01
+#define FMPE_DISABLED			0x02
+
+#define POWER_UP			0x01
+#define POWER_DOWN			0x00
+
+struct rds_info {
+	u32 pi;
+#define MAX_RDS_PTY			31
+	u32 pty;
+#define MAX_RDS_DEVIATION		90000
+	u32 deviation;
+/*
+ * PSNAME is known to be defined as 8 character sized (RDS Spec).
+ * However, there is receivers which scroll PSNAME 8xN sized.
+ */
+#define MAX_RDS_PS_NAME			96
+	u8 ps_name[MAX_RDS_PS_NAME + 1];
+/*
+ * MAX_RDS_RADIO_TEXT is known to be defined as 32 (2A group) or 64 (2B group)
+ * character sized (RDS Spec).
+ * However, there is receivers which scroll them as well.
+ */
+#define MAX_RDS_RADIO_TEXT		384
+	u8 radio_text[MAX_RDS_RADIO_TEXT + 1];
+	u32 enabled;
+};
+
+struct limiter_info {
+#define MAX_LIMITER_RELEASE_TIME	102390
+	u32 release_time;
+#define MAX_LIMITER_DEVIATION		90000
+	u32 deviation;
+	u32 enabled;
+};
+
+struct pilot_info {
+#define MAX_PILOT_DEVIATION		90000
+	u32 deviation;
+#define MAX_PILOT_FREQUENCY		19000
+	u32 frequency;
+	u32 enabled;
+};
+
+struct acomp_info {
+#define MAX_ACOMP_RELEASE_TIME		1000000
+	u32 release_time;
+#define MAX_ACOMP_ATTACK_TIME		5000
+	u32 attack_time;
+#define MAX_ACOMP_THRESHOLD		0
+#define MIN_ACOMP_THRESHOLD		(-40)
+	s32 threshold;
+#define MAX_ACOMP_GAIN			20
+	u32 gain;
+	u32 enabled;
+};
+
+/*
+ * si4713_device - private data
+ */
+struct si4713_device {
+	/* v4l2_subdev and i2c reference (v4l2_subdev priv data) */
+	struct v4l2_subdev sd;
+	/* private data structures */
+	struct mutex mutex;
+	struct completion work;
+	struct si4713_platform_data *platform_data;
+	struct rds_info rds_info;
+	struct limiter_info limiter_info;
+	struct pilot_info pilot_info;
+	struct acomp_info acomp_info;
+	u32 frequency;
+	u32 preemphasis;
+	u32 mute;
+	u32 power_level;
+	u32 power_state;
+	u32 antenna_capacitor;
+	u32 stereo;
+	u32 tune_rnl;
+};
+#endif /* ifndef SI4713_I2C_H */
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index dcf9fa9..e6186b3 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -203,9 +203,9 @@ config VIDEO_CS53L32A
 	  module will be called cs53l32a.
 
 config VIDEO_M52790
-       tristate "Mitsubishi M52790 A/V switch"
-       depends on VIDEO_V4L2 && I2C
-       ---help---
+	tristate "Mitsubishi M52790 A/V switch"
+	depends on VIDEO_V4L2 && I2C
+	---help---
 	 Support for the Mitsubishi M52790 A/V switch.
 
 	 To compile this driver as a module, choose M here: the
@@ -265,6 +265,15 @@ config VIDEO_SAA6588
 
 comment "Video decoders"
 
+config VIDEO_ADV7180
+	tristate "Analog Devices ADV7180 decoder"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Analog Devices ADV7180 video decoder.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called adv7180.
+
 config VIDEO_BT819
 	tristate "BT819A VideoStream decoder"
 	depends on VIDEO_V4L2 && I2C
@@ -493,6 +502,39 @@ config VIDEO_UPD64083
 
 endmenu # encoder / decoder chips
 
+config DISPLAY_DAVINCI_DM646X_EVM
+	tristate "DM646x EVM Video Display"
+	depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
+	select VIDEOBUF_DMA_CONTIG
+	select VIDEO_DAVINCI_VPIF
+	select VIDEO_ADV7343
+	select VIDEO_THS7303
+	help
+	  Support for DM6467 based display device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vpif_display.
+
+config CAPTURE_DAVINCI_DM646X_EVM
+	tristate "DM646x EVM Video Capture"
+	depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
+	select VIDEOBUF_DMA_CONTIG
+	select VIDEO_DAVINCI_VPIF
+	help
+	  Support for DM6467 based capture device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vpif_capture.
+
+config VIDEO_DAVINCI_VPIF
+	tristate "DaVinci VPIF Driver"
+	depends on DISPLAY_DAVINCI_DM646X_EVM
+	help
+	  Support for DaVinci VPIF Driver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vpif.
+
 config VIDEO_VIVI
 	tristate "Virtual Video Driver"
 	depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
@@ -505,6 +547,55 @@ config VIDEO_VIVI
 	  Say Y here if you want to test video apps or debug V4L devices.
 	  In doubt, say N.
 
+config VIDEO_VPSS_SYSTEM
+	tristate "VPSS System module driver"
+	depends on ARCH_DAVINCI
+	help
+	  Support for vpss system module for video driver
+	default y
+
+config VIDEO_VPFE_CAPTURE
+	tristate "VPFE Video Capture Driver"
+	depends on VIDEO_V4L2 && ARCH_DAVINCI
+	select VIDEOBUF_DMA_CONTIG
+	help
+	  Support for DMXXXX VPFE based frame grabber. This is the
+	  common V4L2 module for following DMXXX SoCs from Texas
+	  Instruments:- DM6446 & DM355.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called vpfe-capture.
+
+config VIDEO_DM6446_CCDC
+	tristate "DM6446 CCDC HW module"
+	depends on ARCH_DAVINCI_DM644x && VIDEO_VPFE_CAPTURE
+	select VIDEO_VPSS_SYSTEM
+	default y
+	help
+	   Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
+	   with decoder modules such as TVP5146 over BT656 or
+	   sensor module such as MT9T001 over a raw interface. This
+	   module configures the interface and CCDC/ISIF to do
+	   video frame capture from slave decoders.
+
+	   To compile this driver as a module, choose M here: the
+	   module will be called vpfe.
+
+config VIDEO_DM355_CCDC
+	tristate "DM355 CCDC HW module"
+	depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
+	select VIDEO_VPSS_SYSTEM
+	default y
+	help
+	   Enables DM355 CCD hw module. DM355 CCDC hw interfaces
+	   with decoder modules such as TVP5146 over BT656 or
+	   sensor module such as MT9T001 over a raw interface. This
+	   module configures the interface and CCDC/ISIF to do
+	   video frame capture from a slave decoders
+
+	   To compile this driver as a module, choose M here: the
+	   module will be called vpfe.
+
 source "drivers/media/video/bt8xx/Kconfig"
 
 config VIDEO_PMS
@@ -690,6 +781,8 @@ source "drivers/media/video/ivtv/Kconfig"
 
 source "drivers/media/video/cx18/Kconfig"
 
+source "drivers/media/video/saa7164/Kconfig"
+
 config VIDEO_M32R_AR
 	tristate "AR devices"
 	depends on M32R && VIDEO_V4L1
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 9f2e321..e541932 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
 obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
 obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
 obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
+obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
 obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
 obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
 obj-$(CONFIG_VIDEO_BT819) += bt819.o
@@ -154,12 +155,17 @@ obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.o
 obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 
+obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
+
 obj-$(CONFIG_VIDEO_AU0828) += au0828/
 
 obj-$(CONFIG_USB_VIDEO_CLASS)	+= uvc/
+obj-$(CONFIG_VIDEO_SAA7164)     += saa7164/
 
 obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
 
+obj-$(CONFIG_ARCH_DAVINCI)	+= davinci/
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
new file mode 100644
index 0000000..1b3cbd0
--- /dev/null
+++ b/drivers/media/video/adv7180.c
@@ -0,0 +1,202 @@
+/*
+ * adv7180.c Analog Devices ADV7180 video decoder driver
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+
+#define DRIVER_NAME "adv7180"
+
+#define ADV7180_INPUT_CONTROL_REG	0x00
+#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM	0x00
+#define ADV7180_AUTODETECT_ENABLE_REG	0x07
+#define ADV7180_AUTODETECT_DEFAULT	0x7f
+
+
+#define ADV7180_STATUS1_REG 0x10
+#define ADV7180_STATUS1_AUTOD_MASK 0x70
+#define ADV7180_STATUS1_AUTOD_NTSM_M_J	0x00
+#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
+#define ADV7180_STATUS1_AUTOD_PAL_M	0x20
+#define ADV7180_STATUS1_AUTOD_PAL_60	0x30
+#define ADV7180_STATUS1_AUTOD_PAL_B_G	0x40
+#define ADV7180_STATUS1_AUTOD_SECAM	0x50
+#define ADV7180_STATUS1_AUTOD_PAL_COMB	0x60
+#define ADV7180_STATUS1_AUTOD_SECAM_525	0x70
+
+#define ADV7180_IDENT_REG 0x11
+#define ADV7180_ID_7180 0x18
+
+
+struct adv7180_state {
+	struct v4l2_subdev sd;
+};
+
+static v4l2_std_id determine_norm(struct i2c_client *client)
+{
+	u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
+
+	switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
+	case ADV7180_STATUS1_AUTOD_NTSM_M_J:
+		return V4L2_STD_NTSC_M_JP;
+	case ADV7180_STATUS1_AUTOD_NTSC_4_43:
+		return V4L2_STD_NTSC_443;
+	case ADV7180_STATUS1_AUTOD_PAL_M:
+		return V4L2_STD_PAL_M;
+	case ADV7180_STATUS1_AUTOD_PAL_60:
+		return V4L2_STD_PAL_60;
+	case ADV7180_STATUS1_AUTOD_PAL_B_G:
+		return V4L2_STD_PAL;
+	case ADV7180_STATUS1_AUTOD_SECAM:
+		return V4L2_STD_SECAM;
+	case ADV7180_STATUS1_AUTOD_PAL_COMB:
+		return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
+	case ADV7180_STATUS1_AUTOD_SECAM_525:
+		return V4L2_STD_SECAM;
+	default:
+		return V4L2_STD_UNKNOWN;
+	}
+}
+
+static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct adv7180_state, sd);
+}
+
+static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	*std = determine_norm(client);
+	return 0;
+}
+
+static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
+	struct v4l2_dbg_chip_ident *chip)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
+}
+
+static const struct v4l2_subdev_video_ops adv7180_video_ops = {
+	.querystd = adv7180_querystd,
+};
+
+static const struct v4l2_subdev_core_ops adv7180_core_ops = {
+	.g_chip_ident = adv7180_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops adv7180_ops = {
+	.core = &adv7180_core_ops,
+	.video = &adv7180_video_ops,
+};
+
+/*
+ * Generic i2c probe
+ * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
+ */
+
+static int adv7180_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct adv7180_state *state;
+	struct v4l2_subdev *sd;
+	int ret;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -EIO;
+
+	v4l_info(client, "chip found @ 0x%02x (%s)\n",
+			client->addr << 1, client->adapter->name);
+
+	state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
+	if (state == NULL)
+		return -ENOMEM;
+	sd = &state->sd;
+	v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
+
+	/* Initialize adv7180 */
+	/* enable autodetection */
+	ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
+		ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM);
+	if (ret > 0)
+		ret = i2c_smbus_write_byte_data(client,
+			ADV7180_AUTODETECT_ENABLE_REG,
+			ADV7180_AUTODETECT_DEFAULT);
+	if (ret < 0) {
+		printk(KERN_ERR DRIVER_NAME
+			": Failed to communicate to chip: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int adv7180_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+	v4l2_device_unregister_subdev(sd);
+	kfree(to_state(sd));
+	return 0;
+}
+
+static const struct i2c_device_id adv7180_id[] = {
+	{DRIVER_NAME, 0},
+	{},
+};
+
+MODULE_DEVICE_TABLE(i2c, adv7180_id);
+
+static struct i2c_driver adv7180_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= DRIVER_NAME,
+	},
+	.probe		= adv7180_probe,
+	.remove		= adv7180_remove,
+	.id_table	= adv7180_id,
+};
+
+static __init int adv7180_init(void)
+{
+	return i2c_add_driver(&adv7180_driver);
+}
+
+static __exit void adv7180_exit(void)
+{
+	i2c_del_driver(&adv7180_driver);
+}
+
+module_init(adv7180_init);
+module_exit(adv7180_exit);
+
+MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
+MODULE_AUTHOR("Mocean Laboratories");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 30f5caf..df26f2f 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -24,7 +24,6 @@
 #include <linux/module.h>
 #include <linux/videodev2.h>
 #include <linux/uaccess.h>
-#include <linux/version.h>
 
 #include <media/adv7343.h>
 #include <media/v4l2-device.h>
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 830c4a9..57dd919 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev)
 		   be abstracted out if we ever need to support a different
 		   demod) */
 		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-				"au8522", "au8522", 0x8e >> 1);
+				"au8522", "au8522", 0x8e >> 1, NULL);
 		if (sd == NULL)
 			printk(KERN_ERR "analog subdev registration failed\n");
 	}
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev)
 	if (dev->board.tuner_type != TUNER_ABSENT) {
 		/* Load the tuner module, which does the attach */
 		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-				"tuner", "tuner", dev->board.tuner_addr);
+				"tuner", "tuner", dev->board.tuner_addr, NULL);
 		if (sd == NULL)
 			printk(KERN_ERR "tuner subdev registration fail\n");
 
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index 14baffc..b8a4b52 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -151,7 +151,7 @@ static int start_urb_transfer(struct au0828_dev *dev)
 	dprintk(2, "%s()\n", __func__);
 
 	if (dev->urb_streaming) {
-		dprintk(2, "%s: iso xfer already running!\n", __func__);
+		dprintk(2, "%s: bulk xfer already running!\n", __func__);
 		return 0;
 	}
 
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index 13e4943..cbdb65c 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -320,7 +320,6 @@ static struct i2c_algorithm au0828_i2c_algo_template = {
 static struct i2c_adapter au0828_i2c_adap_template = {
 	.name              = DRIVER_NAME,
 	.owner             = THIS_MODULE,
-	.id                = I2C_HW_B_AU0828,
 	.algo              = &au0828_i2c_algo_template,
 };
 
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index ca6558c..12279f6 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -1274,6 +1274,7 @@ struct tvcard bttv_tvcards[] = {
 		.pll            = PLL_28,
 		.tuner_type	= TUNER_TEMIC_PAL,
 		.tuner_addr	= ADDR_UNSET,
+		.has_remote	= 1,
 	},
 
 	/* ---- card 0x3c ---------------------------------- */
@@ -3523,8 +3524,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
 		};
 		struct v4l2_subdev *sd;
 
-		sd = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
-			&btv->c.i2c_adap, "saa6588", "saa6588", addrs);
+		sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "saa6588", "saa6588", 0, addrs);
 		btv->has_saa6588 = (sd != NULL);
 	}
 
@@ -3548,8 +3549,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
 			I2C_CLIENT_END
 		};
 
-		btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
-			&btv->c.i2c_adap, "msp3400", "msp3400", addrs);
+		btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "msp3400", "msp3400", 0, addrs);
 		if (btv->sd_msp34xx)
 			return;
 		goto no_audio;
@@ -3562,16 +3563,16 @@ void __devinit bttv_init_card2(struct bttv *btv)
 			I2C_CLIENT_END
 		};
 
-		if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
-				&btv->c.i2c_adap, "tda7432", "tda7432", addrs))
+		if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
+				&btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs))
 			return;
 		goto no_audio;
 	}
 
 	case 3: {
 		/* The user specified that we should probe for tvaudio */
-		btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
-			&btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs());
+		btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
+			&btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs());
 		if (btv->sd_tvaudio)
 			return;
 		goto no_audio;
@@ -3590,13 +3591,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
 	   it really is a msp3400, so it will return NULL when the device
 	   found is really something else (e.g. a tea6300). */
 	if (!bttv_tvcards[btv->c.type].no_msp34xx) {
-		btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev,
+		btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
 			&btv->c.i2c_adap, "msp3400", "msp3400",
-			I2C_ADDR_MSP3400 >> 1);
+			0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
 	} else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
-		btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev,
+		btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
 			&btv->c.i2c_adap, "msp3400", "msp3400",
-			I2C_ADDR_MSP3400_ALT >> 1);
+			0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
 	}
 
 	/* If we found a msp34xx, then we're done. */
@@ -3610,14 +3611,14 @@ void __devinit bttv_init_card2(struct bttv *btv)
 			I2C_CLIENT_END
 		};
 
-		if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
-				&btv->c.i2c_adap, "tda7432", "tda7432", addrs))
+		if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
+				&btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs))
 			return;
 	}
 
 	/* Now see if we can find one of the tvaudio devices. */
-	btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
-		&btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs());
+	btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
+		&btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs());
 	if (btv->sd_tvaudio)
 		return;
 
@@ -3640,15 +3641,15 @@ void __devinit bttv_init_tuner(struct bttv *btv)
 
 		/* Load tuner module before issuing tuner config call! */
 		if (bttv_tvcards[btv->c.type].has_radio)
-			v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+			v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
 				&btv->c.i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(ADDRS_RADIO));
-		v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+				0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+		v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
 				&btv->c.i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
-		v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev,
+				0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+		v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
 				&btv->c.i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
+				0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
 
 		tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
 		tun_setup.type = btv->tuner_type;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 8cc6dd2..939d1e5 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -2652,6 +2652,8 @@ static int bttv_querycap(struct file *file, void  *priv,
 		V4L2_CAP_VBI_CAPTURE |
 		V4L2_CAP_READWRITE |
 		V4L2_CAP_STREAMING;
+	if (btv->has_saa6588)
+		cap->capabilities |= V4L2_CAP_RDS_CAPTURE;
 	if (no_overlay <= 0)
 		cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
 
@@ -4593,14 +4595,10 @@ static int bttv_resume(struct pci_dev *pci_dev)
 #endif
 
 static struct pci_device_id bttv_pci_tbl[] = {
-	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
-	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0},
+	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0},
+	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0},
+	{PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0},
 	{0,}
 };
 
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index ebd1ee9..beda363 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -352,7 +352,6 @@ int __devinit init_bttv_i2c(struct bttv *btv)
 		/* bt878 */
 		strlcpy(btv->c.i2c_adap.name, "bt878",
 			sizeof(btv->c.i2c_adap.name));
-		btv->c.i2c_adap.id = I2C_HW_B_BT848;	/* FIXME */
 		btv->c.i2c_adap.algo = &bttv_algo;
 	} else {
 		/* bt848 */
@@ -362,7 +361,6 @@ int __devinit init_bttv_i2c(struct bttv *btv)
 
 		strlcpy(btv->c.i2c_adap.name, "bttv",
 			sizeof(btv->c.i2c_adap.name));
-		btv->c.i2c_adap.id = I2C_HW_B_BT848;
 		memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
 		       sizeof(bttv_i2c_algo_bit_template));
 		btv->i2c_algo.udelay = i2c_udelay;
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index 2f289d9..ebd51af 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -245,7 +245,7 @@ static void bttv_ir_stop(struct bttv *btv)
 int bttv_input_init(struct bttv *btv)
 {
 	struct card_ir *ir;
-	IR_KEYTAB_TYPE *ir_codes = NULL;
+	struct ir_scancode_table *ir_codes = NULL;
 	struct input_dev *input_dev;
 	int ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
@@ -263,7 +263,7 @@ int bttv_input_init(struct bttv *btv)
 	case BTTV_BOARD_AVERMEDIA:
 	case BTTV_BOARD_AVPHONE98:
 	case BTTV_BOARD_AVERMEDIA98:
-		ir_codes         = ir_codes_avermedia;
+		ir_codes         = &ir_codes_avermedia_table;
 		ir->mask_keycode = 0xf88000;
 		ir->mask_keydown = 0x010000;
 		ir->polling      = 50; // ms
@@ -271,14 +271,14 @@ int bttv_input_init(struct bttv *btv)
 
 	case BTTV_BOARD_AVDVBT_761:
 	case BTTV_BOARD_AVDVBT_771:
-		ir_codes         = ir_codes_avermedia_dvbt;
+		ir_codes         = &ir_codes_avermedia_dvbt_table;
 		ir->mask_keycode = 0x0f00c0;
 		ir->mask_keydown = 0x000020;
 		ir->polling      = 50; // ms
 		break;
 
 	case BTTV_BOARD_PXELVWPLTVPAK:
-		ir_codes         = ir_codes_pixelview;
+		ir_codes         = &ir_codes_pixelview_table;
 		ir->mask_keycode = 0x003e00;
 		ir->mask_keyup   = 0x010000;
 		ir->polling      = 50; // ms
@@ -286,54 +286,55 @@ int bttv_input_init(struct bttv *btv)
 	case BTTV_BOARD_PV_M4900:
 	case BTTV_BOARD_PV_BT878P_9B:
 	case BTTV_BOARD_PV_BT878P_PLUS:
-		ir_codes         = ir_codes_pixelview;
+		ir_codes         = &ir_codes_pixelview_table;
 		ir->mask_keycode = 0x001f00;
 		ir->mask_keyup   = 0x008000;
 		ir->polling      = 50; // ms
 		break;
 
 	case BTTV_BOARD_WINFAST2000:
-		ir_codes         = ir_codes_winfast;
+		ir_codes         = &ir_codes_winfast_table;
 		ir->mask_keycode = 0x1f8;
 		break;
 	case BTTV_BOARD_MAGICTVIEW061:
 	case BTTV_BOARD_MAGICTVIEW063:
-		ir_codes         = ir_codes_winfast;
+		ir_codes         = &ir_codes_winfast_table;
 		ir->mask_keycode = 0x0008e000;
 		ir->mask_keydown = 0x00200000;
 		break;
 	case BTTV_BOARD_APAC_VIEWCOMP:
-		ir_codes         = ir_codes_apac_viewcomp;
+		ir_codes         = &ir_codes_apac_viewcomp_table;
 		ir->mask_keycode = 0x001f00;
 		ir->mask_keyup   = 0x008000;
 		ir->polling      = 50; // ms
 		break;
+	case BTTV_BOARD_ASKEY_CPH03X:
 	case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
 	case BTTV_BOARD_CONTVFMI:
-		ir_codes         = ir_codes_pixelview;
+		ir_codes         = &ir_codes_pixelview_table;
 		ir->mask_keycode = 0x001F00;
 		ir->mask_keyup   = 0x006000;
 		ir->polling      = 50; // ms
 		break;
 	case BTTV_BOARD_NEBULA_DIGITV:
-		ir_codes = ir_codes_nebula;
+		ir_codes = &ir_codes_nebula_table;
 		btv->custom_irq = bttv_rc5_irq;
 		ir->rc5_gpio = 1;
 		break;
 	case BTTV_BOARD_MACHTV_MAGICTV:
-		ir_codes         = ir_codes_apac_viewcomp;
+		ir_codes         = &ir_codes_apac_viewcomp_table;
 		ir->mask_keycode = 0x001F00;
 		ir->mask_keyup   = 0x004000;
 		ir->polling      = 50; /* ms */
 		break;
 	case BTTV_BOARD_KOZUMI_KTV_01C:
-		ir_codes         = ir_codes_pctv_sedna;
+		ir_codes         = &ir_codes_pctv_sedna_table;
 		ir->mask_keycode = 0x001f00;
 		ir->mask_keyup   = 0x006000;
 		ir->polling      = 50; /* ms */
 		break;
 	case BTTV_BOARD_ENLTV_FM_2:
-		ir_codes         = ir_codes_encore_enltv2;
+		ir_codes         = &ir_codes_encore_enltv2_table;
 		ir->mask_keycode = 0x00fd00;
 		ir->mask_keyup   = 0x000080;
 		ir->polling      = 1; /* ms */
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index c4d181d..657c481 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -490,7 +490,6 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
 	int ret;
 
 	cafe_smbus_enable_irq(cam);
-	adap->id = I2C_HW_SMBUS_CAFE;
 	adap->owner = THIS_MODULE;
 	adap->algo = &cafe_smbus_algo;
 	strcpy(adap->name, "cafe_ccic");
@@ -1956,7 +1955,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
 
 	cam->sensor_addr = 0x42;
 	cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter,
-			"ov7670", "ov7670", cam->sensor_addr);
+			"ov7670", "ov7670", cam->sensor_addr, NULL);
 	if (cam->sensor == NULL) {
 		ret = -ENODEV;
 		goto out_smbus;
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index 36f2d76..f11e47a 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -56,7 +56,8 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
 	.hw_audio_ctrl = CX18_HW_418_AV,
 	.hw_muxer = CX18_HW_CS5345,
 	.hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
-		  CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
+		  CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
+		  CX18_HW_Z8F0811_IR_HAUP,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX18_AV_SVIDEO1    },
@@ -102,7 +103,8 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
 	.hw_audio_ctrl = CX18_HW_418_AV,
 	.hw_muxer = CX18_HW_CS5345,
 	.hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
-		  CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
+		  CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
+		  CX18_HW_Z8F0811_IR_HAUP,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE7 },
 		{ CX18_CARD_INPUT_SVIDEO1,    1, CX18_AV_SVIDEO1    },
@@ -204,7 +206,7 @@ static const struct cx18_card cx18_card_mpc718 = {
 	.v4l2_capabilities = CX18_CAP_ENCODER,
 	.hw_audio_ctrl = CX18_HW_418_AV,
 	.hw_muxer = CX18_HW_GPIO_MUX,
-	.hw_all = CX18_HW_418_AV | CX18_HW_TUNER |
+	.hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
 		  CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
 	.video_inputs = {
 		{ CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 3c552b6..444e3c7 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -22,13 +22,17 @@
  */
 
 /* hardware flags */
-#define CX18_HW_TUNER		(1 << 0)
-#define CX18_HW_TVEEPROM	(1 << 1)
-#define CX18_HW_CS5345		(1 << 2)
-#define CX18_HW_DVB		(1 << 3)
-#define CX18_HW_418_AV		(1 << 4)
-#define CX18_HW_GPIO_MUX	(1 << 5)
-#define CX18_HW_GPIO_RESET_CTRL	(1 << 6)
+#define CX18_HW_TUNER			(1 << 0)
+#define CX18_HW_TVEEPROM		(1 << 1)
+#define CX18_HW_CS5345			(1 << 2)
+#define CX18_HW_DVB			(1 << 3)
+#define CX18_HW_418_AV			(1 << 4)
+#define CX18_HW_GPIO_MUX		(1 << 5)
+#define CX18_HW_GPIO_RESET_CTRL		(1 << 6)
+#define CX18_HW_Z8F0811_IR_TX_HAUP	(1 << 7)
+#define CX18_HW_Z8F0811_IR_RX_HAUP	(1 << 8)
+#define CX18_HW_Z8F0811_IR_HAUP	(CX18_HW_Z8F0811_IR_RX_HAUP | \
+				 CX18_HW_Z8F0811_IR_TX_HAUP)
 
 /* video inputs */
 #define	CX18_CARD_INPUT_VID_TUNER	1
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 92026e8..6dd51e2 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -231,7 +231,7 @@ MODULE_PARM_DESC(enc_pcm_bufs,
 		 "Number of encoder PCM buffers\n"
 		 "\t\t\tDefault is computed from other enc_pcm_* parameters");
 
-MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card");
+MODULE_PARM_DESC(cx18_first_minor, "Set device node number assigned to first card");
 
 MODULE_AUTHOR("Hans Verkuil");
 MODULE_DESCRIPTION("CX23418 driver");
@@ -268,6 +268,20 @@ static void cx18_iounmap(struct cx18 *cx)
 	}
 }
 
+static void cx18_eeprom_dump(struct cx18 *cx, unsigned char *eedata, int len)
+{
+	int i;
+
+	CX18_INFO("eeprom dump:\n");
+	for (i = 0; i < len; i++) {
+		if (0 == (i % 16))
+			CX18_INFO("eeprom %02x:", i);
+		printk(KERN_CONT " %02x", eedata[i]);
+		if (15 == (i % 16))
+			printk(KERN_CONT "\n");
+	}
+}
+
 /* Hauppauge card? get values from tveeprom */
 void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
 {
@@ -279,8 +293,26 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
 	c.adapter = &cx->i2c_adap[0];
 	c.addr = 0xA0 >> 1;
 
-	tveeprom_read(&c, eedata, sizeof(eedata));
-	tveeprom_hauppauge_analog(&c, tv, eedata);
+	memset(tv, 0, sizeof(*tv));
+	if (tveeprom_read(&c, eedata, sizeof(eedata)))
+		return;
+
+	switch (cx->card->type) {
+	case CX18_CARD_HVR_1600_ESMT:
+	case CX18_CARD_HVR_1600_SAMSUNG:
+		tveeprom_hauppauge_analog(&c, tv, eedata);
+		break;
+	case CX18_CARD_YUAN_MPC718:
+		tv->model = 0x718;
+		cx18_eeprom_dump(cx, eedata, sizeof(eedata));
+		CX18_INFO("eeprom PCI ID: %02x%02x:%02x%02x\n",
+			  eedata[2], eedata[1], eedata[4], eedata[3]);
+		break;
+	default:
+		tv->model = 0xffffffff;
+		cx18_eeprom_dump(cx, eedata, sizeof(eedata));
+		break;
+	}
 }
 
 static void cx18_process_eeprom(struct cx18 *cx)
@@ -298,6 +330,11 @@ static void cx18_process_eeprom(struct cx18 *cx)
 	case 74000 ... 74999:
 		cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
 		break;
+	case 0x718:
+		return;
+	case 0xffffffff:
+		CX18_INFO("Unknown EEPROM encoding\n");
+		return;
 	case 0:
 		CX18_ERR("Invalid EEPROM\n");
 		return;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 29969c1..04d9c25 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -690,7 +690,7 @@ int cx18_v4l2_open(struct file *filp)
 	int res;
 	struct video_device *video_dev = video_devdata(filp);
 	struct cx18_stream *s = video_get_drvdata(video_dev);
-	struct cx18 *cx = s->cx;;
+	struct cx18 *cx = s->cx;
 
 	mutex_lock(&cx->serialize_lock);
 	if (cx18_init_on_first_open(cx)) {
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 8591e4f..2477461 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -28,6 +28,7 @@
 #include "cx18-gpio.h"
 #include "cx18-i2c.h"
 #include "cx18-irq.h"
+#include <media/ir-kbd-i2c.h>
 
 #define CX18_REG_I2C_1_WR   0xf15000
 #define CX18_REG_I2C_1_RD   0xf15008
@@ -40,16 +41,20 @@
 #define GETSDL_BIT      0x0008
 
 #define CX18_CS5345_I2C_ADDR		0x4c
+#define CX18_Z8F0811_IR_TX_I2C_ADDR	0x70
+#define CX18_Z8F0811_IR_RX_I2C_ADDR	0x71
 
 /* This array should match the CX18_HW_ defines */
 static const u8 hw_addrs[] = {
-	0,			/* CX18_HW_TUNER */
-	0,			/* CX18_HW_TVEEPROM */
-	CX18_CS5345_I2C_ADDR,	/* CX18_HW_CS5345 */
-	0,			/* CX18_HW_DVB */
-	0,			/* CX18_HW_418_AV */
-	0,			/* CX18_HW_GPIO_MUX */
-	0,			/* CX18_HW_GPIO_RESET_CTRL */
+	0,				/* CX18_HW_TUNER */
+	0,				/* CX18_HW_TVEEPROM */
+	CX18_CS5345_I2C_ADDR,		/* CX18_HW_CS5345 */
+	0,				/* CX18_HW_DVB */
+	0,				/* CX18_HW_418_AV */
+	0,				/* CX18_HW_GPIO_MUX */
+	0,				/* CX18_HW_GPIO_RESET_CTRL */
+	CX18_Z8F0811_IR_TX_I2C_ADDR,	/* CX18_HW_Z8F0811_IR_TX_HAUP */
+	CX18_Z8F0811_IR_RX_I2C_ADDR,	/* CX18_HW_Z8F0811_IR_RX_HAUP */
 };
 
 /* This array should match the CX18_HW_ defines */
@@ -62,6 +67,8 @@ static const u8 hw_bus[] = {
 	0,	/* CX18_HW_418_AV */
 	0,	/* CX18_HW_GPIO_MUX */
 	0,	/* CX18_HW_GPIO_RESET_CTRL */
+	0,	/* CX18_HW_Z8F0811_IR_TX_HAUP */
+	0,	/* CX18_HW_Z8F0811_IR_RX_HAUP */
 };
 
 /* This array should match the CX18_HW_ defines */
@@ -73,6 +80,8 @@ static const char * const hw_modules[] = {
 	NULL,		/* CX18_HW_418_AV */
 	NULL,		/* CX18_HW_GPIO_MUX */
 	NULL,		/* CX18_HW_GPIO_RESET_CTRL */
+	NULL,		/* CX18_HW_Z8F0811_IR_TX_HAUP */
+	NULL,		/* CX18_HW_Z8F0811_IR_RX_HAUP */
 };
 
 /* This array should match the CX18_HW_ defines */
@@ -84,8 +93,38 @@ static const char * const hw_devicenames[] = {
 	"cx23418_AV",
 	"gpio_mux",
 	"gpio_reset_ctrl",
+	"ir_tx_z8f0811_haup",
+	"ir_rx_z8f0811_haup",
 };
 
+static const struct IR_i2c_init_data z8f0811_ir_init_data = {
+	.ir_codes = &ir_codes_hauppauge_new_table,
+	.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR,
+	.type = IR_TYPE_RC5,
+	.name = "CX23418 Z8F0811 Hauppauge",
+};
+
+static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
+			   u8 addr)
+{
+	struct i2c_board_info info;
+	unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
+
+	memset(&info, 0, sizeof(struct i2c_board_info));
+	strlcpy(info.type, type, I2C_NAME_SIZE);
+
+	/* Our default information for ir-kbd-i2c.c to use */
+	switch (hw) {
+	case CX18_HW_Z8F0811_IR_RX_HAUP:
+		info.platform_data = (void *) &z8f0811_ir_init_data;
+		break;
+	default:
+		break;
+	}
+
+	return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
+}
+
 int cx18_i2c_register(struct cx18 *cx, unsigned idx)
 {
 	struct v4l2_subdev *sd;
@@ -100,27 +139,30 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
 
 	if (hw == CX18_HW_TUNER) {
 		/* special tuner group handling */
-		sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
-				adap, mod, type, cx->card_i2c->radio);
+		sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
+				adap, mod, type, 0, cx->card_i2c->radio);
 		if (sd != NULL)
 			sd->grp_id = hw;
-		sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
-				adap, mod, type, cx->card_i2c->demod);
+		sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
+				adap, mod, type, 0, cx->card_i2c->demod);
 		if (sd != NULL)
 			sd->grp_id = hw;
-		sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev,
-				adap, mod, type, cx->card_i2c->tv);
+		sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
+				adap, mod, type, 0, cx->card_i2c->tv);
 		if (sd != NULL)
 			sd->grp_id = hw;
 		return sd != NULL ? 0 : -1;
 	}
 
+	if (hw & CX18_HW_Z8F0811_IR_HAUP)
+		return cx18_i2c_new_ir(adap, hw, type, hw_addrs[idx]);
+
 	/* Is it not an I2C device or one we do not wish to register? */
 	if (!hw_addrs[idx])
 		return -1;
 
-	/* It's an I2C device other than an analog tuner */
-	sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]);
+	/* It's an I2C device other than an analog tuner or IR chip */
+	sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx], NULL);
 	if (sd != NULL)
 		sd->grp_id = hw;
 	return sd != NULL ? 0 : -1;
@@ -190,7 +232,6 @@ static int cx18_getsda(void *data)
 /* template for i2c-bit-algo */
 static struct i2c_adapter cx18_i2c_adap_template = {
 	.name = "cx18 i2c driver",
-	.id = I2C_HW_B_CX2341X,
 	.algo = NULL,                   /* set by i2c-algo-bit */
 	.algo_data = NULL,              /* filled from template */
 	.owner = THIS_MODULE,
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index d7b1921..fc76e4d 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -605,7 +605,7 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
 	if (ret)
 		return ret;
 
-	if (inp < 0 || inp >= cx->nof_inputs)
+	if (inp >= cx->nof_inputs)
 		return -EINVAL;
 
 	if (inp == cx->active_input) {
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 54d248e..7df513a 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -245,9 +245,9 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
 	video_set_drvdata(s->video_dev, s);
 
 	/* Register device. First try the desired minor, then any free one. */
-	ret = video_register_device(s->video_dev, vfl_type, num);
+	ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
 	if (ret < 0) {
-		CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
+		CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
 			s->name, num);
 		video_device_release(s->video_dev);
 		s->video_dev = NULL;
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 63d2239..319c459 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -313,7 +313,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
 	if (dev->board.decoder == CX231XX_AVDECODER) {
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 					&dev->i2c_bus[0].i2c_adap,
-					"cx25840", "cx25840", 0x88 >> 1);
+					"cx25840", "cx25840", 0x88 >> 1, NULL);
 		if (dev->sd_cx25840 == NULL)
 			cx231xx_info("cx25840 subdev registration failure\n");
 		cx25840_call(dev, core, load_fw);
@@ -323,7 +323,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
 	if (dev->board.tuner_type != TUNER_ABSENT) {
 		dev->sd_tuner =	v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[1].i2c_adap,
-				"tuner", "tuner", 0xc2 >> 1);
+				"tuner", "tuner", 0xc2 >> 1, NULL);
 		if (dev->sd_tuner == NULL)
 			cx231xx_info("tuner subdev registration failure\n");
 
diff --git a/drivers/media/video/cx231xx/cx231xx-conf-reg.h b/drivers/media/video/cx231xx/cx231xx-conf-reg.h
index a6f398a..31a8759 100644
--- a/drivers/media/video/cx231xx/cx231xx-conf-reg.h
+++ b/drivers/media/video/cx231xx/cx231xx-conf-reg.h
@@ -60,10 +60,10 @@
 #define PWR_RESETOUT_EN         0x100  /* bit8 */
 
 enum AV_MODE{
-       POLARIS_AVMODE_DEFAULT = 0,
-       POLARIS_AVMODE_DIGITAL = 0x10,
-       POLARIS_AVMODE_ANALOGT_TV = 0x20,
-       POLARIS_AVMODE_ENXTERNAL_AV = 0x30,
+	POLARIS_AVMODE_DEFAULT = 0,
+	POLARIS_AVMODE_DIGITAL = 0x10,
+	POLARIS_AVMODE_ANALOGT_TV = 0x20,
+	POLARIS_AVMODE_ENXTERNAL_AV = 0x30,
 
 };
 
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index 33219dc..58d9cc0 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -432,7 +432,6 @@ static struct i2c_algorithm cx231xx_algo = {
 static struct i2c_adapter cx231xx_adap_template = {
 	.owner = THIS_MODULE,
 	.name = "cx231xx",
-	.id = I2C_HW_B_CX231XX,
 	.algo = &cx231xx_algo,
 };
 
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 609bae6..3650372 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -923,8 +923,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 
 	f->fmt.pix.width = dev->width;
 	f->fmt.pix.height = dev->height;
-	f->fmt.pix.pixelformat = dev->format->fourcc;;
-	f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;;
+	f->fmt.pix.pixelformat = dev->format->fourcc;
+	f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
 	f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
 	f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index a0f823a..64e2ddd 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -282,7 +282,7 @@ struct cx231xx_board {
 
 	struct cx231xx_input input[MAX_CX231XX_INPUT];
 	struct cx231xx_input radio;
-	IR_KEYTAB_TYPE *ir_codes;
+	struct ir_scancode_table *ir_codes;
 };
 
 /* device states */
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
index 08582e5..c04222f 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -75,7 +75,6 @@ struct netup_ci_state {
 	void *priv;
 };
 
-struct mutex gpio_mutex;/* Two CiMax's uses same GPIO lines */
 
 int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
 						u8 *buf, int len)
@@ -183,10 +182,11 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
 	if (ret != 0)
 		return ret;
 
-	mutex_lock(&gpio_mutex);
+	mutex_lock(&dev->gpio_lock);
 
 	/* write addr */
 	cx_write(MC417_OEN, NETUP_EN_ALL);
+	msleep(2);
 	cx_write(MC417_RWD, NETUP_CTRL_OFF |
 				NETUP_ADLO | (0xff & addr));
 	cx_clear(MC417_RWD, NETUP_ADLO);
@@ -194,9 +194,10 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
 				NETUP_ADHI | (0xff & (addr >> 8)));
 	cx_clear(MC417_RWD, NETUP_ADHI);
 
-	if (read) /* data in */
+	if (read) { /* data in */
 		cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
-	else /* data out */
+		msleep(2);
+	} else /* data out */
 		cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
 
 	/* choose chip */
@@ -206,7 +207,7 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
 	cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
 	mem = netup_ci_get_mem(dev);
 
-	mutex_unlock(&gpio_mutex);
+	mutex_unlock(&dev->gpio_lock);
 
 	if (!read)
 		if (mem < 0)
@@ -403,7 +404,6 @@ int netup_ci_init(struct cx23885_tsport *port)
 	switch (port->nr) {
 	case 1:
 		state->ci_i2c_addr = 0x40;
-		mutex_init(&gpio_mutex);
 		break;
 	case 2:
 		state->ci_i2c_addr = 0x41;
@@ -443,6 +443,7 @@ int netup_ci_init(struct cx23885_tsport *port)
 		goto err;
 
 	INIT_WORK(&state->work, netup_read_ci_status);
+	schedule_work(&state->work);
 
 	ci_dbg_print("%s: CI initialized!\n", __func__);
 
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index 1a1048b..6c3b51c 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -630,6 +630,39 @@ int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value)
 	return retval;
 }
 
+void mc417_gpio_set(struct cx23885_dev *dev, u32 mask)
+{
+	u32 val;
+
+	/* Set the gpio value */
+	mc417_register_read(dev, 0x900C, &val);
+	val |= (mask & 0x000ffff);
+	mc417_register_write(dev, 0x900C, val);
+}
+
+void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask)
+{
+	u32 val;
+
+	/* Clear the gpio value */
+	mc417_register_read(dev, 0x900C, &val);
+	val &= ~(mask & 0x0000ffff);
+	mc417_register_write(dev, 0x900C, val);
+}
+
+void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
+{
+	u32 val;
+
+	/* Enable GPIO direction bits */
+	mc417_register_read(dev, 0x9020, &val);
+	if (asoutput)
+		val |= (mask & 0x0000ffff);
+	else
+		val &= ~(mask & 0x0000ffff);
+
+	mc417_register_write(dev, 0x9020, val);
+}
 /* ------------------------------------------------------------------ */
 
 /* MPEG encoder API */
@@ -955,25 +988,8 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
 	retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS,
 		IVTV_CMD_HW_BLOCKS_RST);
 
-	/* Restore GPIO settings, make sure EIO14 is enabled as an output. */
-	dprintk(2, "%s: GPIO output EIO 0-15 was = 0x%x\n",
-		__func__, gpio_output);
-	/* Power-up seems to have GPIOs AFU. This was causing digital side
-	 * to fail at power-up. Seems GPIOs should be set to 0x10ff0411 at
-	 * power-up.
-	 * gpio_output |= (1<<14);
-	 */
-	/* Note: GPIO14 is specific to the HVR1800 here */
-	gpio_output = 0x10ff0411 | (1<<14);
-	retval |= mc417_register_write(dev, 0x9020, gpio_output | (1<<14));
-	dprintk(2, "%s: GPIO output EIO 0-15 now = 0x%x\n",
-		__func__, gpio_output);
-
-	dprintk(1, "%s: GPIO value  EIO 0-15 was = 0x%x\n",
-		__func__, value);
-	value |= (1<<14);
-	dprintk(1, "%s: GPIO value  EIO 0-15 now = 0x%x\n",
-		__func__, value);
+	/* F/W power up disturbs the GPIOs, restore state */
+	retval |= mc417_register_write(dev, 0x9020, gpio_output);
 	retval |= mc417_register_write(dev, 0x900C, value);
 
 	retval |= mc417_register_read(dev, IVTV_REG_VPU, &value);
@@ -1788,9 +1804,6 @@ int cx23885_417_register(struct cx23885_dev *dev)
 		return err;
 	}
 
-	/* Initialize MC417 registers */
-	cx23885_mc417_init(dev);
-
 	printk(KERN_INFO "%s: registered device video%d [mpeg]\n",
 	       dev->name, dev->v4l_device->num);
 
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index ce29b5e..bfdf79f 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -201,6 +201,19 @@ struct cx23885_board cx23885_boards[] = {
 		.name		= "Mygica X8506 DMB-TH",
 		.portb		= CX23885_MPEG_DVB,
 	},
+	[CX23885_BOARD_MAGICPRO_PROHDTVE2] = {
+		.name		= "Magic-Pro ProHDTV Extreme 2",
+		.portb		= CX23885_MPEG_DVB,
+	},
+	[CX23885_BOARD_HAUPPAUGE_HVR1850] = {
+		.name		= "Hauppauge WinTV-HVR1850",
+		.portb		= CX23885_MPEG_ENCODER,
+		.portc		= CX23885_MPEG_DVB,
+	},
+	[CX23885_BOARD_COMPRO_VIDEOMATE_E800] = {
+		.name		= "Compro VideoMate E800",
+		.portc		= CX23885_MPEG_DVB,
+	},
 };
 const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
 
@@ -324,6 +337,18 @@ struct cx23885_subid cx23885_subids[] = {
 		.subvendor = 0x14f1,
 		.subdevice = 0x8651,
 		.card      = CX23885_BOARD_MYGICA_X8506,
+	}, {
+		.subvendor = 0x14f1,
+		.subdevice = 0x8657,
+		.card      = CX23885_BOARD_MAGICPRO_PROHDTVE2,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8541,
+		.card      = CX23885_BOARD_HAUPPAUGE_HVR1850,
+	}, {
+		.subvendor = 0x1858,
+		.subdevice = 0xe800,
+		.card      = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
 	},
 };
 const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -483,8 +508,13 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
 		/* WinTV-HVR1700 (PCIe, OEM, No IR, full height)
 		 * DVB-T and MPEG2 HW Encoder */
 		break;
+	case 85021:
+		/* WinTV-HVR1850 (PCIe, OEM, RCA in, IR, FM,
+			Dual channel ATSC and MPEG2 HW Encoder */
+		break;
 	default:
-		printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n",
+		printk(KERN_WARNING "%s: warning: "
+			"unknown hauppauge model #%d\n",
 			dev->name, tv.model);
 		break;
 	}
@@ -514,6 +544,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
 	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
+	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
 		/* Tuner Reset Command */
 		bitmask = 0x04;
 		break;
@@ -574,13 +605,23 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		/* CX23417 GPIO's */
 		/* EIO15 Zilog Reset */
 		/* EIO14 S5H1409/CX24227 Reset */
+		mc417_gpio_enable(dev, GPIO_15 | GPIO_14, 1);
+
+		/* Put the demod into reset and protect the eeprom */
+		mc417_gpio_clear(dev, GPIO_15 | GPIO_14);
+		mdelay(100);
+
+		/* Bring the demod and blaster out of reset */
+		mc417_gpio_set(dev, GPIO_15 | GPIO_14);
+		mdelay(100);
 
 		/* Force the TDA8295A into reset and back */
-		cx_set(GP0_IO, 0x00040004);
+		cx23885_gpio_enable(dev, GPIO_2, 1);
+		cx23885_gpio_set(dev, GPIO_2);
 		mdelay(20);
-		cx_clear(GP0_IO, 0x00000004);
+		cx23885_gpio_clear(dev, GPIO_2);
 		mdelay(20);
-		cx_set(GP0_IO, 0x00040004);
+		cx23885_gpio_set(dev, GPIO_2);
 		mdelay(20);
 		break;
 	case CX23885_BOARD_HAUPPAUGE_HVR1200:
@@ -655,6 +696,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		break;
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
+	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
 		/* GPIO-2  xc3028 tuner reset */
 
 		/* The following GPIO's are on the internal AVCore (cx25840) */
@@ -715,14 +757,45 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
 		cx23885_gpio_set(dev, GPIO_9);
 		break;
 	case CX23885_BOARD_MYGICA_X8506:
+	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
 		/* GPIO-1 reset XC5000 */
-		/* GPIO-2 reset LGS8GL5 */
+		/* GPIO-2 reset LGS8GL5 / LGS8G75 */
 		cx_set(GP0_IO, 0x00060000);
 		cx_clear(GP0_IO, 0x00000006);
 		mdelay(100);
 		cx_set(GP0_IO, 0x00060006);
 		mdelay(100);
 		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+		/* GPIO-0 656_CLK */
+		/* GPIO-1 656_D0 */
+		/* GPIO-2 Wake# */
+		/* GPIO-3-10 cx23417 data0-7 */
+		/* GPIO-11-14 cx23417 addr0-3 */
+		/* GPIO-15-18 cx23417 READY, CS, RD, WR */
+		/* GPIO-19 IR_RX */
+		/* GPIO-20 C_IR_TX */
+		/* GPIO-21 I2S DAT */
+		/* GPIO-22 I2S WCLK */
+		/* GPIO-23 I2S BCLK */
+		/* ALT GPIO: EXP GPIO LATCH */
+
+		/* CX23417 GPIO's */
+		/* GPIO-14 S5H1411/CX24228 Reset */
+		/* GPIO-13 EEPROM write protect */
+		mc417_gpio_enable(dev, GPIO_14 | GPIO_13, 1);
+
+		/* Put the demod into reset and protect the eeprom */
+		mc417_gpio_clear(dev, GPIO_14 | GPIO_13);
+		mdelay(100);
+
+		/* Bring the demod out of reset */
+		mc417_gpio_set(dev, GPIO_14);
+		mdelay(100);
+
+		/* CX24228 GPIO */
+		/* Connected to IF / Mux */
+		break;
 	}
 }
 
@@ -739,6 +812,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
 		/* FIXME: Implement me */
 		break;
 	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -778,6 +852,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
 		if (dev->i2c_bus[0].i2c_rc == 0)
 			hauppauge_eeprom(dev, eeprom+0xc0);
 		break;
@@ -827,6 +902,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 		ts2->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
 		break;
 	case CX23885_BOARD_MYGICA_X8506:
+	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
 		ts1->gen_ctrl_val  = 0x5; /* Parallel */
 		ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
 		ts1->src_sel_val   = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
@@ -844,6 +920,8 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_HAUPPAUGE_HVR1275:
 	case CX23885_BOARD_HAUPPAUGE_HVR1255:
 	case CX23885_BOARD_HAUPPAUGE_HVR1210:
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
 	default:
 		ts2->gen_ctrl_val  = 0xc; /* Serial bus + punctured clock */
 		ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -860,9 +938,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
 	case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
 		dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[2].i2c_adap,
-				"cx25840", "cx25840", 0x88 >> 1);
+				"cx25840", "cx25840", 0x88 >> 1, NULL);
 		v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
 		break;
 	}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index bf7bb1c..c31284b 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -713,12 +713,26 @@ static void cx23885_dev_checkrevision(struct cx23885_dev *dev)
 		dev->hwrevision = 0xa1;
 		break;
 	case 0x02:
-		/* CX23885-13Z */
+		/* CX23885-13Z/14Z */
 		dev->hwrevision = 0xb0;
 		break;
 	case 0x03:
-		/* CX23888-22Z */
-		dev->hwrevision = 0xc0;
+		if (dev->pci->device == 0x8880) {
+			/* CX23888-21Z/22Z */
+			dev->hwrevision = 0xc0;
+		} else {
+			/* CX23885-14Z */
+			dev->hwrevision = 0xa4;
+		}
+		break;
+	case 0x04:
+		if (dev->pci->device == 0x8880) {
+			/* CX23888-31Z */
+			dev->hwrevision = 0xd0;
+		} else {
+			/* CX23885-15Z, CX23888-31Z */
+			dev->hwrevision = 0xa5;
+		}
 		break;
 	case 0x0e:
 		/* CX23887-15Z */
@@ -744,6 +758,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	int i;
 
 	mutex_init(&dev->lock);
+	mutex_init(&dev->gpio_lock);
 
 	atomic_inc(&dev->refcount);
 
@@ -756,6 +771,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 
 	/* Configure the internal memory */
 	if (dev->pci->device == 0x8880) {
+		/* Could be 887 or 888, assume a default */
 		dev->bridge = CX23885_BRIDGE_887;
 		/* Apply a sensible clock frequency for the PCIe bridge */
 		dev->clk_freq = 25000000;
@@ -868,6 +884,14 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
 	dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n",
 		__func__, dev->radio_type, dev->radio_addr);
 
+	/* The cx23417 encoder has GPIO's that need to be initialised
+	 * before DVB, so that demodulators and tuners are out of
+	 * reset before DVB uses them.
+	 */
+	if ((cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) ||
+		(cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER))
+			cx23885_mc417_init(dev);
+
 	/* init hardware */
 	cx23885_reset(dev);
 
@@ -1250,6 +1274,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
 	switch (dev->bridge) {
 	case CX23885_BRIDGE_885:
 	case CX23885_BRIDGE_887:
+	case CX23885_BRIDGE_888:
 		/* enable irqs */
 		dprintk(1, "%s() enabling TS int's and DMA\n", __func__);
 		cx_set(port->reg_ts_int_msk,  port->ts_int_msk_val);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 86ac529..45e13ee 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -255,15 +255,18 @@ static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
 static struct tda18271_config hauppauge_tda18271_config = {
 	.std_map = &hauppauge_tda18271_std_map,
 	.gate    = TDA18271_GATE_ANALOG,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
 };
 
 static struct tda18271_config hauppauge_hvr1200_tuner_config = {
 	.std_map = &hauppauge_hvr1200_tda18271_std_map,
 	.gate    = TDA18271_GATE_ANALOG,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
 };
 
 static struct tda18271_config hauppauge_hvr1210_tuner_config = {
 	.gate    = TDA18271_GATE_DIGITAL,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
 };
 
 static struct tda18271_std_map hauppauge_hvr127x_std_map = {
@@ -275,6 +278,7 @@ static struct tda18271_std_map hauppauge_hvr127x_std_map = {
 
 static struct tda18271_config hauppauge_hvr127x_config = {
 	.std_map = &hauppauge_hvr127x_std_map,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
 };
 
 static struct lgdt3305_config hauppauge_lgdt3305_config = {
@@ -396,7 +400,7 @@ static struct stv0900_reg stv0900_ts_regs[] = {
 
 static struct stv0900_config netup_stv0900_config = {
 	.demod_address = 0x68,
-	.xtal = 27000000,
+	.xtal = 8000000,
 	.clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
 	.diseqc_mode = 2,/* 2/3 PWM */
 	.ts_config_regs = stv0900_ts_regs,
@@ -408,14 +412,14 @@ static struct stv0900_config netup_stv0900_config = {
 
 static struct stv6110_config netup_stv6110_tunerconfig_a = {
 	.i2c_address = 0x60,
-	.mclk = 27000000,
-	.iq_wiring = 0,
+	.mclk = 16000000,
+	.clk_div = 1,
 };
 
 static struct stv6110_config netup_stv6110_tunerconfig_b = {
 	.i2c_address = 0x63,
-	.mclk = 27000000,
-	.iq_wiring = 1,
+	.mclk = 16000000,
+	.clk_div = 1,
 };
 
 static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
@@ -487,6 +491,26 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe,
 		port->set_frontend_save(fe, param) : -ENODEV;
 }
 
+static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = {
+	.prod = LGS8GXX_PROD_LGS8G75,
+	.demod_address = 0x19,
+	.serial_ts = 0,
+	.ts_clk_pol = 1,
+	.ts_clk_gated = 1,
+	.if_clk_freq = 30400, /* 30.4 MHz */
+	.if_freq = 6500, /* 6.50 MHz */
+	.if_neg_center = 1,
+	.ext_adc = 0,
+	.adc_signed = 1,
+	.adc_vpp = 2, /* 1.6 Vpp */
+	.if_neg_edge = 1,
+};
+
+static struct xc5000_config magicpro_prohdtve2_xc5000_config = {
+	.i2c_address = 0x61,
+	.if_khz = 6500,
+};
+
 static int dvb_register(struct cx23885_tsport *port)
 {
 	struct cx23885_dev *dev = port->dev;
@@ -723,6 +747,7 @@ static int dvb_register(struct cx23885_tsport *port)
 	}
 	case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
 	case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
+	case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
 		i2c_bus = &dev->i2c_bus[0];
 
 		fe0->dvb.frontend = dvb_attach(zl10353_attach,
@@ -833,6 +858,30 @@ static int dvb_register(struct cx23885_tsport *port)
 				&mygica_x8506_xc5000_config);
 		}
 		break;
+	case CX23885_BOARD_MAGICPRO_PROHDTVE2:
+		i2c_bus = &dev->i2c_bus[0];
+		i2c_bus2 = &dev->i2c_bus[1];
+		fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
+			&magicpro_prohdtve2_lgs8g75_config,
+			&i2c_bus->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(xc5000_attach,
+				fe0->dvb.frontend,
+				&i2c_bus2->i2c_adap,
+				&magicpro_prohdtve2_xc5000_config);
+		}
+		break;
+	case CX23885_BOARD_HAUPPAUGE_HVR1850:
+		i2c_bus = &dev->i2c_bus[0];
+		fe0->dvb.frontend = dvb_attach(s5h1411_attach,
+			&hcw_s5h1411_config,
+			&i2c_bus->i2c_adap);
+		if (fe0->dvb.frontend != NULL)
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				0x60, &dev->i2c_bus[0].i2c_adap,
+				&hauppauge_tda18271_config);
+		break;
+
 	default:
 		printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
 			" isn't supported yet\n",
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index 384dec3..4172cb3 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -283,7 +283,6 @@ static struct i2c_algorithm cx23885_i2c_algo_template = {
 static struct i2c_adapter cx23885_i2c_adap_template = {
 	.name              = "cx23885",
 	.owner             = THIS_MODULE,
-	.id                = I2C_HW_B_CX23885,
 	.algo              = &cx23885_i2c_algo_template,
 };
 
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 5d60933..654cc25 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1521,11 +1521,11 @@ int cx23885_video_register(struct cx23885_dev *dev)
 		if (dev->tuner_addr)
 			sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[1].i2c_adap,
-				"tuner", "tuner", dev->tuner_addr);
+				"tuner", "tuner", dev->tuner_addr, NULL);
 		else
-			sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+			sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_bus[1].i2c_adap,
-				"tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
+				"tuner", "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
 		if (sd) {
 			struct tuner_setup tun_setup;
 
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 214a55e..cc7a165 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -76,6 +76,9 @@
 #define CX23885_BOARD_HAUPPAUGE_HVR1255        20
 #define CX23885_BOARD_HAUPPAUGE_HVR1210        21
 #define CX23885_BOARD_MYGICA_X8506             22
+#define CX23885_BOARD_MAGICPRO_PROHDTVE2       23
+#define CX23885_BOARD_HAUPPAUGE_HVR1850        24
+#define CX23885_BOARD_COMPRO_VIDEOMATE_E800    25
 
 #define GPIO_0 0x00000001
 #define GPIO_1 0x00000002
@@ -87,6 +90,12 @@
 #define GPIO_7 0x00000080
 #define GPIO_8 0x00000100
 #define GPIO_9 0x00000200
+#define GPIO_10 0x00000400
+#define GPIO_11 0x00000800
+#define GPIO_12 0x00001000
+#define GPIO_13 0x00002000
+#define GPIO_14 0x00004000
+#define GPIO_15 0x00008000
 
 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
 #define CX23885_NORMS (\
@@ -317,6 +326,7 @@ struct cx23885_dev {
 
 	int                        nr;
 	struct mutex               lock;
+	struct mutex               gpio_lock;
 
 	/* board details */
 	unsigned int               board;
@@ -331,6 +341,7 @@ struct cx23885_dev {
 		CX23885_BRIDGE_UNDEFINED = 0,
 		CX23885_BRIDGE_885 = 885,
 		CX23885_BRIDGE_887 = 887,
+		CX23885_BRIDGE_888 = 888,
 	} bridge;
 
 	/* Analog video */
@@ -395,7 +406,7 @@ struct sram_channel {
 	u32  cmds_start;
 	u32  ctrl_start;
 	u32  cdt;
-	u32  fifo_start;;
+	u32  fifo_start;
 	u32  fifo_size;
 	u32  ptr1_reg;
 	u32  ptr2_reg;
@@ -504,6 +515,9 @@ extern void cx23885_417_check_encoder(struct cx23885_dev *dev);
 extern void cx23885_mc417_init(struct cx23885_dev *dev);
 extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value);
 extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value);
+extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask);
+extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask);
+extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput);
 
 
 /* ----------------------------------------------------------- */
diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/video/cx23885/netup-eeprom.c
index 042bbbb..98a48f5 100644
--- a/drivers/media/video/cx23885/netup-eeprom.c
+++ b/drivers/media/video/cx23885/netup-eeprom.c
@@ -97,11 +97,11 @@ void netup_get_card_info(struct i2c_adapter *i2c_adap,
 {
 	int i, j;
 
-	cinfo->rev =  netup_eeprom_read(i2c_adap, 13);
+	cinfo->rev =  netup_eeprom_read(i2c_adap, 63);
 
-	for (i = 0, j = 0; i < 6; i++, j++)
+	for (i = 64, j = 0; i < 70; i++, j++)
 		cinfo->port[0].mac[j] =  netup_eeprom_read(i2c_adap, i);
 
-	for (i = 6, j = 0; i < 12; i++, j++)
+	for (i = 70, j = 0; i < 76; i++, j++)
 		cinfo->port[1].mac[j] =  netup_eeprom_read(i2c_adap, i);
 };
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 0be51b6..1aeaf18 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -321,6 +321,15 @@ static void cx23885_initialize(struct i2c_client *client)
 	/* Select AFE clock pad output source */
 	cx25840_write(client, 0x144, 0x05);
 
+	/* Drive GPIO2 direction and values for HVR1700
+	 * where an onboard mux selects the output of demodulator
+	 * vs the 417. Failure to set this results in no DTV.
+	 * It's safe to set this across all Hauppauge boards
+	 * currently, regardless of the board type.
+	 */
+	cx25840_write(client, 0x160, 0x1d);
+	cx25840_write(client, 0x164, 0x00);
+
 	/* Do the firmware load in a work handler to prevent.
 	   Otherwise the kernel is blocked waiting for the
 	   bit-banging i2c interface to finish uploading the
@@ -1578,12 +1587,6 @@ static int cx25840_probe(struct i2c_client *client,
 	state->id = id;
 	state->rev = device_id;
 
-	if (state->is_cx23885) {
-		/* Drive GPIO2 direction and values */
-		cx25840_write(client, 0x160, 0x1d);
-		cx25840_write(client, 0x164, 0x00);
-	}
-
 	return 0;
 }
 
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
index 0df53b0..1f483c1 100644
--- a/drivers/media/video/cx25840/cx25840-firmware.c
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -23,10 +23,6 @@
 
 #include "cx25840-core.h"
 
-#define FWFILE "v4l-cx25840.fw"
-#define FWFILE_CX23885 "v4l-cx23885-avcore-01.fw"
-#define FWFILE_CX231XX "v4l-cx231xx-avcore-01.fw"
-
 /*
  * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the
  * size of the firmware chunks sent down the I2C bus to the chip.
@@ -40,11 +36,11 @@
 
 #define FWDEV(x) &((x)->dev)
 
-static char *firmware = FWFILE;
+static char *firmware = "";
 
 module_param(firmware, charp, 0444);
 
-MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
+MODULE_PARM_DESC(firmware, "Firmware image to load");
 
 static void start_fw_load(struct i2c_client *client)
 {
@@ -65,6 +61,19 @@ static void end_fw_load(struct i2c_client *client)
 	cx25840_write(client, 0x803, 0x03);
 }
 
+static const char *get_fw_name(struct i2c_client *client)
+{
+	struct cx25840_state *state = to_state(i2c_get_clientdata(client));
+
+	if (firmware[0])
+		return firmware;
+	if (state->is_cx23885)
+		return "v4l-cx23885-avcore-01.fw";
+	if (state->is_cx231xx)
+		return "v4l-cx231xx-avcore-01.fw";
+	return "v4l-cx25840.fw";
+}
+
 static int check_fw_load(struct i2c_client *client, int size)
 {
 	/* DL_ADDR_HB DL_ADDR_LB */
@@ -72,11 +81,13 @@ static int check_fw_load(struct i2c_client *client, int size)
 	s |= cx25840_read(client, 0x800);
 
 	if (size != s) {
-		v4l_err(client, "firmware %s load failed\n", firmware);
+		v4l_err(client, "firmware %s load failed\n",
+				get_fw_name(client));
 		return -EINVAL;
 	}
 
-	v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size);
+	v4l_info(client, "loaded %s firmware (%d bytes)\n",
+			get_fw_name(client), size);
 	return 0;
 }
 
@@ -96,21 +107,24 @@ int cx25840_loadfw(struct i2c_client *client)
 	const struct firmware *fw = NULL;
 	u8 buffer[FWSEND];
 	const u8 *ptr;
+	const char *fwname = get_fw_name(client);
 	int size, retval;
 	int MAX_BUF_SIZE = FWSEND;
+	u32 gpio_oe = 0, gpio_da = 0;
 
-	if (state->is_cx23885)
-		firmware = FWFILE_CX23885;
-	else if (state->is_cx231xx)
-		firmware = FWFILE_CX231XX;
+	if (state->is_cx23885) {
+		/* Preserve the GPIO OE and output bits */
+		gpio_oe = cx25840_read(client, 0x160);
+		gpio_da = cx25840_read(client, 0x164);
+	}
 
 	if ((state->is_cx231xx) && MAX_BUF_SIZE > 16) {
 		v4l_err(client, " Firmware download size changed to 16 bytes max length\n");
 		MAX_BUF_SIZE = 16;  /* cx231xx cannot accept more than 16 bytes at a time */
 	}
 
-	if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
-		v4l_err(client, "unable to open firmware %s\n", firmware);
+	if (request_firmware(&fw, fwname, FWDEV(client)) != 0) {
+		v4l_err(client, "unable to open firmware %s\n", fwname);
 		return -EINVAL;
 	}
 
@@ -142,5 +156,11 @@ int cx25840_loadfw(struct i2c_client *client)
 	size = fw->size;
 	release_firmware(fw);
 
+	if (state->is_cx23885) {
+		/* Restore GPIO configuration after f/w load */
+		cx25840_write(client, 0x160, gpio_oe);
+		cx25840_write(client, 0x164, gpio_da);
+	}
+
 	return check_fw_load(client, size);
 }
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 3946530..33be636 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1283,6 +1283,51 @@ static const struct cx88_board cx88_boards[] = {
 		},
 		.mpeg           = CX88_MPEG_DVB,
 	},
+	[CX88_BOARD_WINFAST_DTV2000H_J] = {
+		.name           = "WinFast DTV2000 H rev. J",
+		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.input          = {{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0  = 0x00017300,
+			.gpio1  = 0x00008207,
+			.gpio2	= 0x00000000,
+			.gpio3  = 0x02000000,
+		},{
+			.type   = CX88_VMUX_TELEVISION,
+			.vmux   = 0,
+			.gpio0  = 0x00018300,
+			.gpio1  = 0x0000f207,
+			.gpio2	= 0x00017304,
+			.gpio3  = 0x02000000,
+		},{
+			.type   = CX88_VMUX_COMPOSITE1,
+			.vmux   = 1,
+			.gpio0  = 0x00018301,
+			.gpio1  = 0x0000f207,
+			.gpio2	= 0x00017304,
+			.gpio3  = 0x02000000,
+		},{
+			.type   = CX88_VMUX_SVIDEO,
+			.vmux   = 2,
+			.gpio0  = 0x00018301,
+			.gpio1  = 0x0000f207,
+			.gpio2	= 0x00017304,
+			.gpio3  = 0x02000000,
+		}},
+		.radio = {
+			 .type  = CX88_RADIO,
+			 .gpio0 = 0x00015702,
+			 .gpio1 = 0x0000f207,
+			 .gpio2 = 0x00015702,
+			 .gpio3 = 0x02000000,
+		},
+		.mpeg           = CX88_MPEG_DVB,
+	},
 	[CX88_BOARD_GENIATECH_DVBS] = {
 		.name          = "Geniatech DVB-S",
 		.tuner_type    = TUNER_ABSENT,
@@ -1908,7 +1953,8 @@ static const struct cx88_board cx88_boards[] = {
 		.radio_addr     = ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_DVB,
-			.vmux   = 1,
+			.vmux   = 0,
+			.gpio0  = 0x8080,
 		} },
 		.mpeg           = CX88_MPEG_DVB,
 	},
@@ -2282,6 +2328,10 @@ static const struct cx88_subid cx88_subids[] = {
 		.subdevice = 0x665e,
 		.card      = CX88_BOARD_WINFAST_DTV2000H,
 	},{
+		.subvendor = 0x107d,
+		.subdevice = 0x6f2b,
+		.card      = CX88_BOARD_WINFAST_DTV2000H_J,
+	},{
 		.subvendor = 0x18ac,
 		.subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */
 		.card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
@@ -3162,7 +3212,11 @@ static void cx88_card_setup(struct cx88_core *core)
 	case  CX88_BOARD_PROF_6200:
 	case  CX88_BOARD_PROF_7300:
 	case  CX88_BOARD_SATTRADE_ST4200:
+		cx_write(MO_GP0_IO, 0x8000);
+		msleep(100);
 		cx_write(MO_SRST_IO, 0);
+		msleep(10);
+		cx_write(MO_GP0_IO, 0x8080);
 		msleep(100);
 		cx_write(MO_SRST_IO, 1);
 		msleep(100);
@@ -3385,20 +3439,20 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
 		   The radio_type is sometimes missing, or set to UNSET but
 		   later code configures a tea5767.
 		 */
-		v4l2_i2c_new_probed_subdev(&core->v4l2_dev, &core->i2c_adap,
+		v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
 				"tuner", "tuner",
-				v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+				0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
 		if (has_demod)
-			v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+			v4l2_i2c_new_subdev(&core->v4l2_dev,
 				&core->i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+				0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
 		if (core->board.tuner_addr == ADDR_UNSET) {
-			v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+			v4l2_i2c_new_subdev(&core->v4l2_dev,
 				&core->i2c_adap, "tuner", "tuner",
-				has_demod ? tv_addrs + 4 : tv_addrs);
+				0, has_demod ? tv_addrs + 4 : tv_addrs);
 		} else {
 			v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-				"tuner", "tuner", core->board.tuner_addr);
+				"tuner", "tuner", core->board.tuner_addr, NULL);
 		}
 	}
 
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index e237b50..6e5d142 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -424,17 +424,16 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
 	struct cx8802_dev *dev= fe->dvb->priv;
 	struct cx88_core *core = dev->core;
 
+	cx_set(MO_GP0_IO, 0x6040);
 	switch (voltage) {
 		case SEC_VOLTAGE_13:
-			printk("LNB Voltage SEC_VOLTAGE_13\n");
-			cx_write(MO_GP0_IO, 0x00006040);
+			cx_clear(MO_GP0_IO, 0x20);
 			break;
 		case SEC_VOLTAGE_18:
-			printk("LNB Voltage SEC_VOLTAGE_18\n");
-			cx_write(MO_GP0_IO, 0x00006060);
+			cx_set(MO_GP0_IO, 0x20);
 			break;
 		case SEC_VOLTAGE_OFF:
-			printk("LNB Voltage SEC_VOLTAGE_off\n");
+			cx_clear(MO_GP0_IO, 0x20);
 			break;
 	}
 
@@ -499,9 +498,9 @@ static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
 };
 
 static struct zl10353_config cx88_geniatech_x8000_mt = {
-       .demod_address = (0x1e >> 1),
-       .no_tuner = 1,
-       .disable_i2c_gate_ctrl = 1,
+	.demod_address = (0x1e >> 1),
+	.no_tuner = 1,
+	.disable_i2c_gate_ctrl = 1,
 };
 
 static struct s5h1411_config dvico_fusionhdtv7_config = {
@@ -696,6 +695,7 @@ static int dvb_register(struct cx8802_dev *dev)
 		}
 		break;
 	case CX88_BOARD_WINFAST_DTV2000H:
+	case CX88_BOARD_WINFAST_DTV2000H_J:
 	case CX88_BOARD_HAUPPAUGE_HVR1100:
 	case CX88_BOARD_HAUPPAUGE_HVR1100LP:
 	case CX88_BOARD_HAUPPAUGE_HVR1300:
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index d91f5c5..78b3635 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -23,7 +23,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/delay.h>
+#include <linux/hrtimer.h>
 #include <linux/input.h>
 #include <linux/pci.h>
 #include <linux/module.h>
@@ -48,7 +48,7 @@ struct cx88_IR {
 
 	/* poll external decoder */
 	int polling;
-	struct delayed_work work;
+	struct hrtimer timer;
 	u32 gpio_addr;
 	u32 last_gpio;
 	u32 mask_keycode;
@@ -144,19 +144,28 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
 	}
 }
 
-static void cx88_ir_work(struct work_struct *work)
+static enum hrtimer_restart cx88_ir_work(struct hrtimer *timer)
 {
-	struct cx88_IR *ir = container_of(work, struct cx88_IR, work.work);
+	unsigned long missed;
+	struct cx88_IR *ir = container_of(timer, struct cx88_IR, timer);
 
 	cx88_ir_handle_key(ir);
-	schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+	missed = hrtimer_forward_now(&ir->timer,
+				     ktime_set(0, ir->polling * 1000000));
+	if (missed > 1)
+		ir_dprintk("Missed ticks %ld\n", missed - 1);
+
+	return HRTIMER_RESTART;
 }
 
 void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
 {
 	if (ir->polling) {
-		INIT_DELAYED_WORK(&ir->work, cx88_ir_work);
-		schedule_delayed_work(&ir->work, 0);
+		hrtimer_init(&ir->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		ir->timer.function = cx88_ir_work;
+		hrtimer_start(&ir->timer,
+			      ktime_set(0, ir->polling * 1000000),
+			      HRTIMER_MODE_REL);
 	}
 	if (ir->sampling) {
 		core->pci_irqmask |= PCI_INT_IR_SMPINT;
@@ -173,7 +182,7 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
 	}
 
 	if (ir->polling)
-		cancel_delayed_work_sync(&ir->work);
+		hrtimer_cancel(&ir->timer);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -182,7 +191,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 {
 	struct cx88_IR *ir;
 	struct input_dev *input_dev;
-	IR_KEYTAB_TYPE *ir_codes = NULL;
+	struct ir_scancode_table *ir_codes = NULL;
 	int ir_type = IR_TYPE_OTHER;
 	int err = -ENOMEM;
 
@@ -198,14 +207,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 	case CX88_BOARD_DNTV_LIVE_DVB_T:
 	case CX88_BOARD_KWORLD_DVB_T:
 	case CX88_BOARD_KWORLD_DVB_T_CX22702:
-		ir_codes = ir_codes_dntv_live_dvb_t;
+		ir_codes = &ir_codes_dntv_live_dvb_t_table;
 		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0x1f;
 		ir->mask_keyup = 0x60;
 		ir->polling = 50; /* ms */
 		break;
 	case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
-		ir_codes = ir_codes_cinergy_1400;
+		ir_codes = &ir_codes_cinergy_1400_table;
 		ir_type = IR_TYPE_PD;
 		ir->sampling = 0xeb04; /* address */
 		break;
@@ -220,13 +229,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 	case CX88_BOARD_PCHDTV_HD3000:
 	case CX88_BOARD_PCHDTV_HD5500:
 	case CX88_BOARD_HAUPPAUGE_IRONLY:
-		ir_codes = ir_codes_hauppauge_new;
+		ir_codes = &ir_codes_hauppauge_new_table;
 		ir_type = IR_TYPE_RC5;
 		ir->sampling = 1;
 		break;
 	case CX88_BOARD_WINFAST_DTV2000H:
+	case CX88_BOARD_WINFAST_DTV2000H_J:
 	case CX88_BOARD_WINFAST_DTV1800H:
-		ir_codes = ir_codes_winfast;
+		ir_codes = &ir_codes_winfast_table;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
 		ir->mask_keyup = 0x100;
@@ -235,14 +245,14 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 	case CX88_BOARD_WINFAST2000XP_EXPERT:
 	case CX88_BOARD_WINFAST_DTV1000:
 	case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
-		ir_codes = ir_codes_winfast;
+		ir_codes = &ir_codes_winfast_table;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0x8f8;
 		ir->mask_keyup = 0x100;
 		ir->polling = 1; /* ms */
 		break;
 	case CX88_BOARD_IODATA_GVBCTV7E:
-		ir_codes = ir_codes_iodata_bctv7e;
+		ir_codes = &ir_codes_iodata_bctv7e_table;
 		ir->gpio_addr = MO_GP0_IO;
 		ir->mask_keycode = 0xfd;
 		ir->mask_keydown = 0x02;
@@ -250,7 +260,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 		break;
 	case CX88_BOARD_PROLINK_PLAYTVPVR:
 	case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
-		ir_codes = ir_codes_pixelview;
+		ir_codes = &ir_codes_pixelview_table;
 		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0x1f;
 		ir->mask_keyup = 0x80;
@@ -258,28 +268,28 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 		break;
 	case CX88_BOARD_PROLINK_PV_8000GT:
 	case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
-		ir_codes = ir_codes_pixelview_new;
+		ir_codes = &ir_codes_pixelview_new_table;
 		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0x3f;
 		ir->mask_keyup = 0x80;
 		ir->polling = 1; /* ms */
 		break;
 	case CX88_BOARD_KWORLD_LTV883:
-		ir_codes = ir_codes_pixelview;
+		ir_codes = &ir_codes_pixelview_table;
 		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0x1f;
 		ir->mask_keyup = 0x60;
 		ir->polling = 1; /* ms */
 		break;
 	case CX88_BOARD_ADSTECH_DVB_T_PCI:
-		ir_codes = ir_codes_adstech_dvb_t_pci;
+		ir_codes = &ir_codes_adstech_dvb_t_pci_table;
 		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0xbf;
 		ir->mask_keyup = 0x40;
 		ir->polling = 50; /* ms */
 		break;
 	case CX88_BOARD_MSI_TVANYWHERE_MASTER:
-		ir_codes = ir_codes_msi_tvanywhere;
+		ir_codes = &ir_codes_msi_tvanywhere_table;
 		ir->gpio_addr = MO_GP1_IO;
 		ir->mask_keycode = 0x1f;
 		ir->mask_keyup = 0x40;
@@ -287,40 +297,40 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 		break;
 	case CX88_BOARD_AVERTV_303:
 	case CX88_BOARD_AVERTV_STUDIO_303:
-		ir_codes         = ir_codes_avertv_303;
+		ir_codes         = &ir_codes_avertv_303_table;
 		ir->gpio_addr    = MO_GP2_IO;
 		ir->mask_keycode = 0xfb;
 		ir->mask_keydown = 0x02;
 		ir->polling      = 50; /* ms */
 		break;
 	case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
-		ir_codes = ir_codes_dntv_live_dvbt_pro;
-		ir_type = IR_TYPE_PD;
-		ir->sampling = 0xff00; /* address */
+		ir_codes         = &ir_codes_dntv_live_dvbt_pro_table;
+		ir_type          = IR_TYPE_PD;
+		ir->sampling     = 0xff00; /* address */
 		break;
 	case CX88_BOARD_NORWOOD_MICRO:
-		ir_codes         = ir_codes_norwood;
+		ir_codes         = &ir_codes_norwood_table;
 		ir->gpio_addr    = MO_GP1_IO;
 		ir->mask_keycode = 0x0e;
 		ir->mask_keyup   = 0x80;
 		ir->polling      = 50; /* ms */
 		break;
 	case CX88_BOARD_NPGTECH_REALTV_TOP10FM:
-		ir_codes = ir_codes_npgtech;
-		ir->gpio_addr = MO_GP0_IO;
+		ir_codes         = &ir_codes_npgtech_table;
+		ir->gpio_addr    = MO_GP0_IO;
 		ir->mask_keycode = 0xfa;
-		ir->polling = 50; /* ms */
+		ir->polling      = 50; /* ms */
 		break;
 	case CX88_BOARD_PINNACLE_PCTV_HD_800i:
-		ir_codes = ir_codes_pinnacle_pctv_hd;
-		ir_type = IR_TYPE_RC5;
-		ir->sampling = 1;
+		ir_codes         = &ir_codes_pinnacle_pctv_hd_table;
+		ir_type          = IR_TYPE_RC5;
+		ir->sampling     = 1;
 		break;
 	case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
-		ir_codes = ir_codes_powercolor_real_angel;
-		ir->gpio_addr = MO_GP2_IO;
+		ir_codes         = &ir_codes_powercolor_real_angel_table;
+		ir->gpio_addr    = MO_GP2_IO;
 		ir->mask_keycode = 0x7e;
-		ir->polling = 100; /* ms */
+		ir->polling      = 100; /* ms */
 		break;
 	}
 
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 2bb54c3..81d2b5d 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1881,14 +1881,14 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
 
 	if (core->board.audio_chip == V4L2_IDENT_WM8775)
 		v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-				"wm8775", "wm8775", 0x36 >> 1);
+				"wm8775", "wm8775", 0x36 >> 1, NULL);
 
 	if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
 		/* This probes for a tda9874 as is used on some
 		   Pixelview Ultra boards. */
-		v4l2_i2c_new_probed_subdev_addr(&core->v4l2_dev,
+		v4l2_i2c_new_subdev(&core->v4l2_dev,
 				&core->i2c_adap,
-				"tvaudio", "tvaudio", 0xb0 >> 1);
+				"tvaudio", "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
 	}
 
 	switch (core->boardnr) {
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 9d83762..d5cea41 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -237,6 +237,7 @@ extern struct sram_channel cx88_sram_channels[];
 #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
 #define CX88_BOARD_HAUPPAUGE_IRONLY        80
 #define CX88_BOARD_WINFAST_DTV1800H        81
+#define CX88_BOARD_WINFAST_DTV2000H_J      82
 
 enum cx88_itype {
 	CX88_VMUX_COMPOSITE1 = 1,
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 0664d11..ee43876 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -748,14 +748,14 @@ static const struct file_operations dabusb_fops =
 	.release =	dabusb_release,
 };
 
-static char *dabusb_nodename(struct device *dev)
+static char *dabusb_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
 }
 
 static struct usb_class_driver dabusb_class = {
 	.name =		"dabusb%d",
-	.nodename =	dabusb_nodename,
+	.devnode =	dabusb_devnode,
 	.fops =		&dabusb_fops,
 	.minor_base =	DABUSB_MINOR,
 };
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
new file mode 100644
index 0000000..1a8b8f3
--- /dev/null
+++ b/drivers/media/video/davinci/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for the davinci video device drivers.
+#
+
+# VPIF
+obj-$(CONFIG_VIDEO_DAVINCI_VPIF) += vpif.o
+
+#DM646x EVM Display driver
+obj-$(CONFIG_DISPLAY_DAVINCI_DM646X_EVM) += vpif_display.o
+#DM646x EVM Capture driver
+obj-$(CONFIG_CAPTURE_DAVINCI_DM646X_EVM) += vpif_capture.o
+
+# Capture: DM6446 and DM355
+obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
+obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
+obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
+obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
diff --git a/drivers/media/video/davinci/ccdc_hw_device.h b/drivers/media/video/davinci/ccdc_hw_device.h
new file mode 100644
index 0000000..86b9b35
--- /dev/null
+++ b/drivers/media/video/davinci/ccdc_hw_device.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments 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
+ *
+ * ccdc device API
+ */
+#ifndef _CCDC_HW_DEVICE_H
+#define _CCDC_HW_DEVICE_H
+
+#ifdef __KERNEL__
+#include <linux/videodev2.h>
+#include <linux/device.h>
+#include <media/davinci/vpfe_types.h>
+#include <media/davinci/ccdc_types.h>
+
+/*
+ * ccdc hw operations
+ */
+struct ccdc_hw_ops {
+	/* Pointer to initialize function to initialize ccdc device */
+	int (*open) (struct device *dev);
+	/* Pointer to deinitialize function */
+	int (*close) (struct device *dev);
+	/* set ccdc base address */
+	void (*set_ccdc_base)(void *base, int size);
+	/* Pointer to function to enable or disable ccdc */
+	void (*enable) (int en);
+	/* reset sbl. only for 6446 */
+	void (*reset) (void);
+	/* enable output to sdram */
+	void (*enable_out_to_sdram) (int en);
+	/* Pointer to function to set hw parameters */
+	int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
+	/* get interface parameters */
+	int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
+	/*
+	 * Pointer to function to set parameters. Used
+	 * for implementing VPFE_S_CCDC_PARAMS
+	 */
+	int (*set_params) (void *params);
+	/*
+	 * Pointer to function to get parameter. Used
+	 * for implementing VPFE_G_CCDC_PARAMS
+	 */
+	int (*get_params) (void *params);
+	/* Pointer to function to configure ccdc */
+	int (*configure) (void);
+
+	/* Pointer to function to set buffer type */
+	int (*set_buftype) (enum ccdc_buftype buf_type);
+	/* Pointer to function to get buffer type */
+	enum ccdc_buftype (*get_buftype) (void);
+	/* Pointer to function to set frame format */
+	int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
+	/* Pointer to function to get frame format */
+	enum ccdc_frmfmt (*get_frame_format) (void);
+	/* enumerate hw pix formats */
+	int (*enum_pix)(u32 *hw_pix, int i);
+	/* Pointer to function to set buffer type */
+	u32 (*get_pixel_format) (void);
+	/* Pointer to function to get pixel format. */
+	int (*set_pixel_format) (u32 pixfmt);
+	/* Pointer to function to set image window */
+	int (*set_image_window) (struct v4l2_rect *win);
+	/* Pointer to function to set image window */
+	void (*get_image_window) (struct v4l2_rect *win);
+	/* Pointer to function to get line length */
+	unsigned int (*get_line_length) (void);
+
+	/* Query CCDC control IDs */
+	int (*queryctrl)(struct v4l2_queryctrl *qctrl);
+	/* Set CCDC control */
+	int (*set_control)(struct v4l2_control *ctrl);
+	/* Get CCDC control */
+	int (*get_control)(struct v4l2_control *ctrl);
+
+	/* Pointer to function to set frame buffer address */
+	void (*setfbaddr) (unsigned long addr);
+	/* Pointer to function to get field id */
+	int (*getfid) (void);
+};
+
+struct ccdc_hw_device {
+	/* ccdc device name */
+	char name[32];
+	/* module owner */
+	struct module *owner;
+	/* hw ops */
+	struct ccdc_hw_ops hw_ops;
+};
+
+/* Used by CCDC module to register & unregister with vpfe capture driver */
+int vpfe_register_ccdc_device(struct ccdc_hw_device *dev);
+void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev);
+
+#endif
+#endif
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
new file mode 100644
index 0000000..4629cab
--- /dev/null
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -0,0 +1,978 @@
+/*
+ * Copyright (C) 2005-2009 Texas Instruments 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
+ *
+ * CCDC hardware module for DM355
+ * ------------------------------
+ *
+ * This module is for configuring DM355 CCD controller of VPFE to capture
+ * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
+ * such as Defect Pixel Correction, Color Space Conversion etc to
+ * pre-process the Bayer RGB data, before writing it to SDRAM. This
+ * module also allows application to configure individual
+ * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
+ * To do so, application include dm355_ccdc.h and vpfe_capture.h header
+ * files. The setparams() API is called by vpfe_capture driver
+ * to configure module parameters
+ *
+ * TODO: 1) Raw bayer parameter settings and bayer capture
+ * 	 2) Split module parameter structure to module specific ioctl structs
+ *	 3) add support for lense shading correction
+ *	 4) investigate if enum used for user space type definition
+ * 	    to be replaced by #defines or integer
+ */
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+#include <media/davinci/dm355_ccdc.h>
+#include <media/davinci/vpss.h>
+#include "dm355_ccdc_regs.h"
+#include "ccdc_hw_device.h"
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CCDC Driver for DM355");
+MODULE_AUTHOR("Texas Instruments");
+
+static struct device *dev;
+
+/* Object for CCDC raw mode */
+static struct ccdc_params_raw ccdc_hw_params_raw = {
+	.pix_fmt = CCDC_PIXFMT_RAW,
+	.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+	.win = CCDC_WIN_VGA,
+	.fid_pol = VPFE_PINPOL_POSITIVE,
+	.vd_pol = VPFE_PINPOL_POSITIVE,
+	.hd_pol = VPFE_PINPOL_POSITIVE,
+	.gain = {
+		.r_ye = 256,
+		.gb_g = 256,
+		.gr_cy = 256,
+		.b_mg = 256
+	},
+	.config_params = {
+		.datasft = 2,
+		.data_sz = CCDC_DATA_10BITS,
+		.mfilt1 = CCDC_NO_MEDIAN_FILTER1,
+		.mfilt2 = CCDC_NO_MEDIAN_FILTER2,
+		.alaw = {
+			.gama_wd = 2,
+		},
+		.blk_clamp = {
+			.sample_pixel = 1,
+			.dc_sub = 25
+		},
+		.col_pat_field0 = {
+			.olop = CCDC_GREEN_BLUE,
+			.olep = CCDC_BLUE,
+			.elop = CCDC_RED,
+			.elep = CCDC_GREEN_RED
+		},
+		.col_pat_field1 = {
+			.olop = CCDC_GREEN_BLUE,
+			.olep = CCDC_BLUE,
+			.elop = CCDC_RED,
+			.elep = CCDC_GREEN_RED
+		},
+	},
+};
+
+
+/* Object for CCDC ycbcr mode */
+static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
+	.win = CCDC_WIN_PAL,
+	.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+	.frm_fmt = CCDC_FRMFMT_INTERLACED,
+	.fid_pol = VPFE_PINPOL_POSITIVE,
+	.vd_pol = VPFE_PINPOL_POSITIVE,
+	.hd_pol = VPFE_PINPOL_POSITIVE,
+	.bt656_enable = 1,
+	.pix_order = CCDC_PIXORDER_CBYCRY,
+	.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
+};
+
+static enum vpfe_hw_if_type ccdc_if_type;
+static void *__iomem ccdc_base_addr;
+static int ccdc_addr_size;
+
+/* Raw Bayer formats */
+static u32 ccdc_raw_bayer_pix_formats[] =
+		{V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
+
+/* Raw YUV formats */
+static u32 ccdc_raw_yuv_pix_formats[] =
+		{V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
+
+/* register access routines */
+static inline u32 regr(u32 offset)
+{
+	return __raw_readl(ccdc_base_addr + offset);
+}
+
+static inline void regw(u32 val, u32 offset)
+{
+	__raw_writel(val, ccdc_base_addr + offset);
+}
+
+static void ccdc_set_ccdc_base(void *addr, int size)
+{
+	ccdc_base_addr = addr;
+	ccdc_addr_size = size;
+}
+
+static void ccdc_enable(int en)
+{
+	unsigned int temp;
+	temp = regr(SYNCEN);
+	temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
+	temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
+	regw(temp, SYNCEN);
+}
+
+static void ccdc_enable_output_to_sdram(int en)
+{
+	unsigned int temp;
+	temp = regr(SYNCEN);
+	temp &= (~(CCDC_SYNCEN_WEN_MASK));
+	temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
+	regw(temp, SYNCEN);
+}
+
+static void ccdc_config_gain_offset(void)
+{
+	/* configure gain */
+	regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN);
+	regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN);
+	regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN);
+	regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN);
+	/* configure offset */
+	regw(ccdc_hw_params_raw.ccdc_offset, OFFSET);
+}
+
+/*
+ * ccdc_restore_defaults()
+ * This function restore power on defaults in the ccdc registers
+ */
+static int ccdc_restore_defaults(void)
+{
+	int i;
+
+	dev_dbg(dev, "\nstarting ccdc_restore_defaults...");
+	/* set all registers to zero */
+	for (i = 0; i <= CCDC_REG_LAST; i += 4)
+		regw(0, i);
+
+	/* now override the values with power on defaults in registers */
+	regw(MODESET_DEFAULT, MODESET);
+	/* no culling support */
+	regw(CULH_DEFAULT, CULH);
+	regw(CULV_DEFAULT, CULV);
+	/* Set default Gain and Offset */
+	ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT;
+	ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT;
+	ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT;
+	ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT;
+	ccdc_config_gain_offset();
+	regw(OUTCLIP_DEFAULT, OUTCLIP);
+	regw(LSCCFG2_DEFAULT, LSCCFG2);
+	/* select ccdc input */
+	if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
+		dev_dbg(dev, "\ncouldn't select ccdc input source");
+		return -EFAULT;
+	}
+	/* select ccdc clock */
+	if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
+		dev_dbg(dev, "\ncouldn't enable ccdc clock");
+		return -EFAULT;
+	}
+	dev_dbg(dev, "\nEnd of ccdc_restore_defaults...");
+	return 0;
+}
+
+static int ccdc_open(struct device *device)
+{
+	dev = device;
+	return ccdc_restore_defaults();
+}
+
+static int ccdc_close(struct device *device)
+{
+	/* disable clock */
+	vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
+	/* do nothing for now */
+	return 0;
+}
+/*
+ * ccdc_setwin()
+ * This function will configure the window size to
+ * be capture in CCDC reg.
+ */
+static void ccdc_setwin(struct v4l2_rect *image_win,
+			enum ccdc_frmfmt frm_fmt, int ppc)
+{
+	int horz_start, horz_nr_pixels;
+	int vert_start, vert_nr_lines;
+	int mid_img = 0;
+
+	dev_dbg(dev, "\nStarting ccdc_setwin...");
+
+	/*
+	 * ppc - per pixel count. indicates how many pixels per cell
+	 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
+	 * raw capture this is 1
+	 */
+	horz_start = image_win->left << (ppc - 1);
+	horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
+
+	/* Writing the horizontal info into the registers */
+	regw(horz_start, SPH);
+	regw(horz_nr_pixels, NPH);
+	vert_start = image_win->top;
+
+	if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		vert_nr_lines = (image_win->height >> 1) - 1;
+		vert_start >>= 1;
+		/* Since first line doesn't have any data */
+		vert_start += 1;
+		/* configure VDINT0 and VDINT1 */
+		regw(vert_start, VDINT0);
+	} else {
+		/* Since first line doesn't have any data */
+		vert_start += 1;
+		vert_nr_lines = image_win->height - 1;
+		/* configure VDINT0 and VDINT1 */
+		mid_img = vert_start + (image_win->height / 2);
+		regw(vert_start, VDINT0);
+		regw(mid_img, VDINT1);
+	}
+	regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
+	regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
+	regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
+	dev_dbg(dev, "\nEnd of ccdc_setwin...");
+}
+
+static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
+{
+	if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
+	    ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
+		dev_dbg(dev, "Invalid value of data shift\n");
+		return -EINVAL;
+	}
+
+	if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
+	    ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
+		dev_dbg(dev, "Invalid value of median filter1\n");
+		return -EINVAL;
+	}
+
+	if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
+	    ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
+		dev_dbg(dev, "Invalid value of median filter2\n");
+		return -EINVAL;
+	}
+
+	if ((ccdcparam->med_filt_thres < 0) ||
+	   (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
+		dev_dbg(dev, "Invalid value of median filter thresold\n");
+		return -EINVAL;
+	}
+
+	if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
+	    ccdcparam->data_sz > CCDC_DATA_8BITS) {
+		dev_dbg(dev, "Invalid value of data size\n");
+		return -EINVAL;
+	}
+
+	if (ccdcparam->alaw.enable) {
+		if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
+		    ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
+			dev_dbg(dev, "Invalid value of ALAW\n");
+			return -EINVAL;
+		}
+	}
+
+	if (ccdcparam->blk_clamp.b_clamp_enable) {
+		if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
+		    ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
+			dev_dbg(dev, "Invalid value of sample pixel\n");
+			return -EINVAL;
+		}
+		if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
+		    ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
+			dev_dbg(dev, "Invalid value of sample lines\n");
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+/* Parameter operations */
+static int ccdc_set_params(void __user *params)
+{
+	struct ccdc_config_params_raw ccdc_raw_params;
+	int x;
+
+	/* only raw module parameters can be set through the IOCTL */
+	if (ccdc_if_type != VPFE_RAW_BAYER)
+		return -EINVAL;
+
+	x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
+	if (x) {
+		dev_dbg(dev, "ccdc_set_params: error in copying ccdc"
+			"params, %d\n", x);
+		return -EFAULT;
+	}
+
+	if (!validate_ccdc_param(&ccdc_raw_params)) {
+		memcpy(&ccdc_hw_params_raw.config_params,
+			&ccdc_raw_params,
+			sizeof(ccdc_raw_params));
+		return 0;
+	}
+	return -EINVAL;
+}
+
+/* This function will configure CCDC for YCbCr video capture */
+static void ccdc_config_ycbcr(void)
+{
+	struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
+	u32 temp;
+
+	/* first set the CCDC power on defaults values in all registers */
+	dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
+	ccdc_restore_defaults();
+
+	/* configure pixel format & video frame format */
+	temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
+		CCDC_INPUT_MODE_SHIFT) |
+		((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
+		CCDC_FRM_FMT_SHIFT));
+
+	/* setup BT.656 sync mode */
+	if (params->bt656_enable) {
+		regw(CCDC_REC656IF_BT656_EN, REC656IF);
+		/*
+		 * configure the FID, VD, HD pin polarity fld,hd pol positive,
+		 * vd negative, 8-bit pack mode
+		 */
+		temp |= CCDC_VD_POL_NEGATIVE;
+	} else {		/* y/c external sync mode */
+		temp |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
+			CCDC_FID_POL_SHIFT) |
+			((params->hd_pol & CCDC_HD_POL_MASK) <<
+			CCDC_HD_POL_SHIFT) |
+			((params->vd_pol & CCDC_VD_POL_MASK) <<
+			CCDC_VD_POL_SHIFT));
+	}
+
+	/* pack the data to 8-bit */
+	temp |= CCDC_DATA_PACK_ENABLE;
+
+	regw(temp, MODESET);
+
+	/* configure video window */
+	ccdc_setwin(&params->win, params->frm_fmt, 2);
+
+	/* configure the order of y cb cr in SD-RAM */
+	temp = (params->pix_order << CCDC_Y8POS_SHIFT);
+	temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
+	regw(temp, CCDCFG);
+
+	/*
+	 * configure the horizontal line offset. This is done by rounding up
+	 * width to a multiple of 16 pixels and multiply by two to account for
+	 * y:cb:cr 4:2:2 data
+	 */
+	regw(((params->win.width * 2 + 31) >> 5), HSIZE);
+
+	/* configure the memory line offset */
+	if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
+		/* two fields are interleaved in memory */
+		regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
+	}
+
+	dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
+}
+
+/*
+ * ccdc_config_black_clamp()
+ * configure parameters for Optical Black Clamp
+ */
+static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
+{
+	u32 val;
+
+	if (!bclamp->b_clamp_enable) {
+		/* configure DCSub */
+		regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
+		regw(0x0000, CLAMP);
+		return;
+	}
+	/* Enable the Black clamping, set sample lines and pixels */
+	val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
+	      ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
+		CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
+	regw(val, CLAMP);
+
+	/* If Black clamping is enable then make dcsub 0 */
+	val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
+			<< CCDC_NUM_LINE_CALC_SHIFT;
+	regw(val, DCSUB);
+}
+
+/*
+ * ccdc_config_black_compense()
+ * configure parameters for Black Compensation
+ */
+static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
+{
+	u32 val;
+
+	val = (bcomp->b & CCDC_BLK_COMP_MASK) |
+		((bcomp->gb & CCDC_BLK_COMP_MASK) <<
+		CCDC_BLK_COMP_GB_COMP_SHIFT);
+	regw(val, BLKCMP1);
+
+	val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
+		CCDC_BLK_COMP_GR_COMP_SHIFT) |
+		((bcomp->r & CCDC_BLK_COMP_MASK) <<
+		CCDC_BLK_COMP_R_COMP_SHIFT);
+	regw(val, BLKCMP0);
+}
+
+/*
+ * ccdc_write_dfc_entry()
+ * write an entry in the dfc table.
+ */
+int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
+{
+/* TODO This is to be re-visited and adjusted */
+#define DFC_WRITE_WAIT_COUNT	1000
+	u32 val, count = DFC_WRITE_WAIT_COUNT;
+
+	regw(dfc->dft_corr_vert[index], DFCMEM0);
+	regw(dfc->dft_corr_horz[index], DFCMEM1);
+	regw(dfc->dft_corr_sub1[index], DFCMEM2);
+	regw(dfc->dft_corr_sub2[index], DFCMEM3);
+	regw(dfc->dft_corr_sub3[index], DFCMEM4);
+	/* set WR bit to write */
+	val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
+	regw(val, DFCMEMCTL);
+
+	/*
+	 * Assume, it is very short. If we get an error, we need to
+	 * adjust this value
+	 */
+	while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
+		count--;
+	/*
+	 * TODO We expect the count to be non-zero to be successful. Adjust
+	 * the count if write requires more time
+	 */
+
+	if (count) {
+		dev_err(dev, "defect table write timeout !!!\n");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * ccdc_config_vdfc()
+ * configure parameters for Vertical Defect Correction
+ */
+static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
+{
+	u32 val;
+	int i;
+
+	/* Configure General Defect Correction. The table used is from IPIPE */
+	val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
+
+	/* Configure Vertical Defect Correction if needed */
+	if (!dfc->ver_dft_en) {
+		/* Enable only General Defect Correction */
+		regw(val, DFCCTL);
+		return 0;
+	}
+
+	if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
+		return -EINVAL;
+
+	val |= CCDC_DFCCTL_VDFC_DISABLE;
+	val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
+		CCDC_DFCCTL_VDFCSL_SHIFT;
+	val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
+		CCDC_DFCCTL_VDFCUDA_SHIFT;
+	val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
+		CCDC_DFCCTL_VDFLSFT_SHIFT;
+	regw(val , DFCCTL);
+
+	/* clear address ptr to offset 0 */
+	val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
+
+	/* write defect table entries */
+	for (i = 0; i < dfc->table_size; i++) {
+		/* increment address for non zero index */
+		if (i != 0)
+			val = CCDC_DFCMEMCTL_INC_ADDR;
+		regw(val, DFCMEMCTL);
+		if (ccdc_write_dfc_entry(i, dfc) < 0)
+			return -EFAULT;
+	}
+
+	/* update saturation level and enable dfc */
+	regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
+	val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
+			CCDC_DFCCTL_VDFCEN_SHIFT);
+	regw(val, DFCCTL);
+	return 0;
+}
+
+/*
+ * ccdc_config_csc()
+ * configure parameters for color space conversion
+ * Each register CSCM0-7 has two values in S8Q5 format.
+ */
+static void ccdc_config_csc(struct ccdc_csc *csc)
+{
+	u32 val1, val2;
+	int i;
+
+	if (!csc->enable)
+		return;
+
+	/* Enable the CSC sub-module */
+	regw(CCDC_CSC_ENABLE, CSCCTL);
+
+	/* Converting the co-eff as per the format of the register */
+	for (i = 0; i < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
+		if ((i % 2) == 0) {
+			/* CSCM - LSB */
+			val1 = (csc->coeff[i].integer &
+				CCDC_CSC_COEF_INTEG_MASK)
+				<< CCDC_CSC_COEF_INTEG_SHIFT;
+			/*
+			 * convert decimal part to binary. Use 2 decimal
+			 * precision, user values range from .00 - 0.99
+			 */
+			val1 |= (((csc->coeff[i].decimal &
+				CCDC_CSC_COEF_DECIMAL_MASK) *
+				CCDC_CSC_DEC_MAX) / 100);
+		} else {
+
+			/* CSCM - MSB */
+			val2 = (csc->coeff[i].integer &
+				CCDC_CSC_COEF_INTEG_MASK)
+				<< CCDC_CSC_COEF_INTEG_SHIFT;
+			val2 |= (((csc->coeff[i].decimal &
+				 CCDC_CSC_COEF_DECIMAL_MASK) *
+				 CCDC_CSC_DEC_MAX) / 100);
+			val2 <<= CCDC_CSCM_MSB_SHIFT;
+			val2 |= val1;
+			regw(val2, (CSCM0 + ((i - 1) << 1)));
+		}
+	}
+}
+
+/*
+ * ccdc_config_color_patterns()
+ * configure parameters for color patterns
+ */
+static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
+				       struct ccdc_col_pat *pat1)
+{
+	u32 val;
+
+	val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
+		(pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
+		(pat1->elop << 12) | (pat1->elep << 14));
+	regw(val, COLPTN);
+}
+
+/* This function will configure CCDC for Raw mode image capture */
+static int ccdc_config_raw(void)
+{
+	struct ccdc_params_raw *params = &ccdc_hw_params_raw;
+	struct ccdc_config_params_raw *config_params =
+		&ccdc_hw_params_raw.config_params;
+	unsigned int val;
+
+	dev_dbg(dev, "\nStarting ccdc_config_raw...");
+
+	/* restore power on defaults to register */
+	ccdc_restore_defaults();
+
+	/* CCDCFG register:
+	 * set CCD Not to swap input since input is RAW data
+	 * set FID detection function to Latch at V-Sync
+	 * set WENLOG - ccdc valid area to AND
+	 * set TRGSEL to WENBIT
+	 * set EXTRG to DISABLE
+	 * disable latching function on VSYNC - shadowed registers
+	 */
+	regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
+	     CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
+	     CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
+
+	/*
+	 * Set VDHD direction to input,  input type to raw input
+	 * normal data polarity, do not use external WEN
+	 */
+	val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
+		CCDC_EXWEN_DISABLE);
+
+	/*
+	 * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
+	 * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
+	 * frame format(progressive or interlace), & pixel format (Input mode)
+	 */
+	val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
+		((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
+		((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
+		((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
+		((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));
+
+	/* set pack for alaw compression */
+	if ((config_params->data_sz == CCDC_DATA_8BITS) ||
+	     config_params->alaw.enable)
+		val |= CCDC_DATA_PACK_ENABLE;
+
+	/* Configure for LPF */
+	if (config_params->lpf_enable)
+		val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
+			CCDC_LPF_SHIFT;
+
+	/* Configure the data shift */
+	val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
+		CCDC_DATASFT_SHIFT;
+	regw(val , MODESET);
+	dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val);
+
+	/* Configure the Median Filter threshold */
+	regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
+
+	/* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
+	val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
+		CCDC_CFA_MOSAIC;
+
+	/* Enable and configure aLaw register if needed */
+	if (config_params->alaw.enable) {
+		val |= (CCDC_ALAW_ENABLE |
+			((config_params->alaw.gama_wd &
+			CCDC_ALAW_GAMA_WD_MASK) <<
+			CCDC_GAMMAWD_INPUT_SHIFT));
+	}
+
+	/* Configure Median filter1 & filter2 */
+	val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
+		(config_params->mfilt2 << CCDC_MFILT2_SHIFT));
+
+	regw(val, GAMMAWD);
+	dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val);
+
+	/* configure video window */
+	ccdc_setwin(&params->win, params->frm_fmt, 1);
+
+	/* Optical Clamp Averaging */
+	ccdc_config_black_clamp(&config_params->blk_clamp);
+
+	/* Black level compensation */
+	ccdc_config_black_compense(&config_params->blk_comp);
+
+	/* Vertical Defect Correction if needed */
+	if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
+		return -EFAULT;
+
+	/* color space conversion */
+	ccdc_config_csc(&config_params->csc);
+
+	/* color pattern */
+	ccdc_config_color_patterns(&config_params->col_pat_field0,
+				   &config_params->col_pat_field1);
+
+	/* Configure the Gain  & offset control */
+	ccdc_config_gain_offset();
+
+	dev_dbg(dev, "\nWriting %x to COLPTN...\n", val);
+
+	/* Configure DATAOFST  register */
+	val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
+		CCDC_DATAOFST_H_SHIFT;
+	val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
+		CCDC_DATAOFST_V_SHIFT;
+	regw(val, DATAOFST);
+
+	/* configuring HSIZE register */
+	val = (params->horz_flip_enable & CCDC_HSIZE_FLIP_MASK) <<
+		CCDC_HSIZE_FLIP_SHIFT;
+
+	/* If pack 8 is enable then 1 pixel will take 1 byte */
+	if ((config_params->data_sz == CCDC_DATA_8BITS) ||
+	     config_params->alaw.enable) {
+		val |= (((params->win.width) + 31) >> 5) &
+			CCDC_HSIZE_VAL_MASK;
+
+		/* adjust to multiple of 32 */
+		dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
+		       (((params->win.width) + 31) >> 5) &
+			CCDC_HSIZE_VAL_MASK);
+	} else {
+		/* else one pixel will take 2 byte */
+		val |= (((params->win.width * 2) + 31) >> 5) &
+			CCDC_HSIZE_VAL_MASK;
+
+		dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
+		       (((params->win.width * 2) + 31) >> 5) &
+			CCDC_HSIZE_VAL_MASK);
+	}
+	regw(val, HSIZE);
+
+	/* Configure SDOFST register */
+	if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		if (params->image_invert_enable) {
+			/* For interlace inverse mode */
+			regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
+			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+				CCDC_SDOFST_INTERLACE_INVERSE);
+		} else {
+			/* For interlace non inverse mode */
+			regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
+			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+				CCDC_SDOFST_INTERLACE_NORMAL);
+		}
+	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
+		if (params->image_invert_enable) {
+			/* For progessive inverse mode */
+			regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
+			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+				CCDC_SDOFST_PROGRESSIVE_INVERSE);
+		} else {
+			/* For progessive non inverse mode */
+			regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
+			dev_dbg(dev, "\nWriting %x to SDOFST...\n",
+				CCDC_SDOFST_PROGRESSIVE_NORMAL);
+		}
+	}
+	dev_dbg(dev, "\nend of ccdc_config_raw...");
+	return 0;
+}
+
+static int ccdc_configure(void)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		return ccdc_config_raw();
+	else
+		ccdc_config_ycbcr();
+	return 0;
+}
+
+static int ccdc_set_buftype(enum ccdc_buftype buf_type)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_hw_params_raw.buf_type = buf_type;
+	else
+		ccdc_hw_params_ycbcr.buf_type = buf_type;
+	return 0;
+}
+static enum ccdc_buftype ccdc_get_buftype(void)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		return ccdc_hw_params_raw.buf_type;
+	return ccdc_hw_params_ycbcr.buf_type;
+}
+
+static int ccdc_enum_pix(u32 *pix, int i)
+{
+	int ret = -EINVAL;
+	if (ccdc_if_type == VPFE_RAW_BAYER) {
+		if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
+			*pix = ccdc_raw_bayer_pix_formats[i];
+			ret = 0;
+		}
+	} else {
+		if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
+			*pix = ccdc_raw_yuv_pix_formats[i];
+			ret = 0;
+		}
+	}
+	return ret;
+}
+
+static int ccdc_set_pixel_format(u32 pixfmt)
+{
+	struct ccdc_a_law *alaw =
+		&ccdc_hw_params_raw.config_params.alaw;
+
+	if (ccdc_if_type == VPFE_RAW_BAYER) {
+		ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
+		if (pixfmt == V4L2_PIX_FMT_SBGGR8)
+			alaw->enable = 1;
+		else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
+			return -EINVAL;
+	} else {
+		if (pixfmt == V4L2_PIX_FMT_YUYV)
+			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+		else if (pixfmt == V4L2_PIX_FMT_UYVY)
+			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+		else
+			return -EINVAL;
+	}
+	return 0;
+}
+static u32 ccdc_get_pixel_format(void)
+{
+	struct ccdc_a_law *alaw =
+		&ccdc_hw_params_raw.config_params.alaw;
+	u32 pixfmt;
+
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		if (alaw->enable)
+			pixfmt = V4L2_PIX_FMT_SBGGR8;
+		else
+			pixfmt = V4L2_PIX_FMT_SBGGR16;
+	else {
+		if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+			pixfmt = V4L2_PIX_FMT_YUYV;
+		else
+			pixfmt = V4L2_PIX_FMT_UYVY;
+	}
+	return pixfmt;
+}
+static int ccdc_set_image_window(struct v4l2_rect *win)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_hw_params_raw.win = *win;
+	else
+		ccdc_hw_params_ycbcr.win = *win;
+	return 0;
+}
+
+static void ccdc_get_image_window(struct v4l2_rect *win)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		*win = ccdc_hw_params_raw.win;
+	else
+		*win = ccdc_hw_params_ycbcr.win;
+}
+
+static unsigned int ccdc_get_line_length(void)
+{
+	struct ccdc_config_params_raw *config_params =
+		&ccdc_hw_params_raw.config_params;
+	unsigned int len;
+
+	if (ccdc_if_type == VPFE_RAW_BAYER) {
+		if ((config_params->alaw.enable) ||
+		    (config_params->data_sz == CCDC_DATA_8BITS))
+			len = ccdc_hw_params_raw.win.width;
+		else
+			len = ccdc_hw_params_raw.win.width * 2;
+	} else
+		len = ccdc_hw_params_ycbcr.win.width * 2;
+	return ALIGN(len, 32);
+}
+
+static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_hw_params_raw.frm_fmt = frm_fmt;
+	else
+		ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
+	return 0;
+}
+
+static enum ccdc_frmfmt ccdc_get_frame_format(void)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		return ccdc_hw_params_raw.frm_fmt;
+	else
+		return ccdc_hw_params_ycbcr.frm_fmt;
+}
+
+static int ccdc_getfid(void)
+{
+	return  (regr(MODESET) >> 15) & 1;
+}
+
+/* misc operations */
+static inline void ccdc_setfbaddr(unsigned long addr)
+{
+	regw((addr >> 21) & 0x007f, STADRH);
+	regw((addr >> 5) & 0x0ffff, STADRL);
+}
+
+static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
+{
+	ccdc_if_type = params->if_type;
+
+	switch (params->if_type) {
+	case VPFE_BT656:
+	case VPFE_YCBCR_SYNC_16:
+	case VPFE_YCBCR_SYNC_8:
+		ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
+		ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
+		break;
+	default:
+		/* TODO add support for raw bayer here */
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct ccdc_hw_device ccdc_hw_dev = {
+	.name = "DM355 CCDC",
+	.owner = THIS_MODULE,
+	.hw_ops = {
+		.open = ccdc_open,
+		.close = ccdc_close,
+		.set_ccdc_base = ccdc_set_ccdc_base,
+		.enable = ccdc_enable,
+		.enable_out_to_sdram = ccdc_enable_output_to_sdram,
+		.set_hw_if_params = ccdc_set_hw_if_params,
+		.set_params = ccdc_set_params,
+		.configure = ccdc_configure,
+		.set_buftype = ccdc_set_buftype,
+		.get_buftype = ccdc_get_buftype,
+		.enum_pix = ccdc_enum_pix,
+		.set_pixel_format = ccdc_set_pixel_format,
+		.get_pixel_format = ccdc_get_pixel_format,
+		.set_frame_format = ccdc_set_frame_format,
+		.get_frame_format = ccdc_get_frame_format,
+		.set_image_window = ccdc_set_image_window,
+		.get_image_window = ccdc_get_image_window,
+		.get_line_length = ccdc_get_line_length,
+		.setfbaddr = ccdc_setfbaddr,
+		.getfid = ccdc_getfid,
+	},
+};
+
+static int dm355_ccdc_init(void)
+{
+	printk(KERN_NOTICE "dm355_ccdc_init\n");
+	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
+		return -1;
+	printk(KERN_NOTICE "%s is registered with vpfe.\n",
+		ccdc_hw_dev.name);
+	return 0;
+}
+
+static void dm355_ccdc_exit(void)
+{
+	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+}
+
+module_init(dm355_ccdc_init);
+module_exit(dm355_ccdc_exit);
diff --git a/drivers/media/video/davinci/dm355_ccdc_regs.h b/drivers/media/video/davinci/dm355_ccdc_regs.h
new file mode 100644
index 0000000..d6d2ef0
--- /dev/null
+++ b/drivers/media/video/davinci/dm355_ccdc_regs.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2005-2009 Texas Instruments 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 _DM355_CCDC_REGS_H
+#define _DM355_CCDC_REGS_H
+
+/**************************************************************************\
+* Register OFFSET Definitions
+\**************************************************************************/
+#define SYNCEN				0x00
+#define MODESET				0x04
+#define HDWIDTH				0x08
+#define VDWIDTH				0x0c
+#define PPLN				0x10
+#define LPFR				0x14
+#define SPH				0x18
+#define NPH				0x1c
+#define SLV0				0x20
+#define SLV1				0x24
+#define NLV				0x28
+#define CULH				0x2c
+#define CULV				0x30
+#define HSIZE				0x34
+#define SDOFST				0x38
+#define STADRH				0x3c
+#define STADRL				0x40
+#define CLAMP				0x44
+#define DCSUB				0x48
+#define COLPTN				0x4c
+#define BLKCMP0				0x50
+#define BLKCMP1				0x54
+#define MEDFILT				0x58
+#define RYEGAIN				0x5c
+#define GRCYGAIN			0x60
+#define GBGGAIN				0x64
+#define BMGGAIN				0x68
+#define OFFSET				0x6c
+#define OUTCLIP				0x70
+#define VDINT0				0x74
+#define VDINT1				0x78
+#define RSV0				0x7c
+#define GAMMAWD				0x80
+#define REC656IF			0x84
+#define CCDCFG				0x88
+#define FMTCFG				0x8c
+#define FMTPLEN				0x90
+#define FMTSPH				0x94
+#define FMTLNH				0x98
+#define FMTSLV				0x9c
+#define FMTLNV				0xa0
+#define FMTRLEN				0xa4
+#define FMTHCNT				0xa8
+#define FMT_ADDR_PTR_B			0xac
+#define FMT_ADDR_PTR(i)			(FMT_ADDR_PTR_B + (i * 4))
+#define FMTPGM_VF0			0xcc
+#define FMTPGM_VF1			0xd0
+#define FMTPGM_AP0			0xd4
+#define FMTPGM_AP1			0xd8
+#define FMTPGM_AP2			0xdc
+#define FMTPGM_AP3                      0xe0
+#define FMTPGM_AP4                      0xe4
+#define FMTPGM_AP5                      0xe8
+#define FMTPGM_AP6                      0xec
+#define FMTPGM_AP7                      0xf0
+#define LSCCFG1                         0xf4
+#define LSCCFG2                         0xf8
+#define LSCH0                           0xfc
+#define LSCV0                           0x100
+#define LSCKH                           0x104
+#define LSCKV                           0x108
+#define LSCMEMCTL                       0x10c
+#define LSCMEMD                         0x110
+#define LSCMEMQ                         0x114
+#define DFCCTL                          0x118
+#define DFCVSAT                         0x11c
+#define DFCMEMCTL                       0x120
+#define DFCMEM0                         0x124
+#define DFCMEM1                         0x128
+#define DFCMEM2                         0x12c
+#define DFCMEM3                         0x130
+#define DFCMEM4                         0x134
+#define CSCCTL                          0x138
+#define CSCM0                           0x13c
+#define CSCM1                           0x140
+#define CSCM2                           0x144
+#define CSCM3                           0x148
+#define CSCM4                           0x14c
+#define CSCM5                           0x150
+#define CSCM6                           0x154
+#define CSCM7                           0x158
+#define DATAOFST			0x15c
+#define CCDC_REG_LAST			DATAOFST
+/**************************************************************
+*	Define for various register bit mask and shifts for CCDC
+*
+**************************************************************/
+#define CCDC_RAW_IP_MODE			0
+#define CCDC_VDHDOUT_INPUT			0
+#define CCDC_YCINSWP_RAW			(0 << 4)
+#define CCDC_EXWEN_DISABLE 			0
+#define CCDC_DATAPOL_NORMAL			0
+#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC		0
+#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC	(1 << 6)
+#define CCDC_CCDCFG_WENLOG_AND			0
+#define CCDC_CCDCFG_TRGSEL_WEN			0
+#define CCDC_CCDCFG_EXTRG_DISABLE		0
+#define CCDC_CFA_MOSAIC				0
+#define CCDC_Y8POS_SHIFT			11
+
+#define CCDC_VDC_DFCVSAT_MASK			0x3fff
+#define CCDC_DATAOFST_MASK			0x0ff
+#define CCDC_DATAOFST_H_SHIFT			0
+#define CCDC_DATAOFST_V_SHIFT			8
+#define CCDC_GAMMAWD_CFA_MASK			1
+#define CCDC_GAMMAWD_CFA_SHIFT			5
+#define CCDC_GAMMAWD_INPUT_SHIFT		2
+#define CCDC_FID_POL_MASK			1
+#define CCDC_FID_POL_SHIFT			4
+#define CCDC_HD_POL_MASK			1
+#define CCDC_HD_POL_SHIFT			3
+#define CCDC_VD_POL_MASK			1
+#define CCDC_VD_POL_SHIFT			2
+#define CCDC_VD_POL_NEGATIVE			(1 << 2)
+#define CCDC_FRM_FMT_MASK			1
+#define CCDC_FRM_FMT_SHIFT			7
+#define CCDC_DATA_SZ_MASK			7
+#define CCDC_DATA_SZ_SHIFT			8
+#define CCDC_VDHDOUT_MASK			1
+#define CCDC_VDHDOUT_SHIFT			0
+#define CCDC_EXWEN_MASK				1
+#define CCDC_EXWEN_SHIFT			5
+#define CCDC_INPUT_MODE_MASK			3
+#define CCDC_INPUT_MODE_SHIFT			12
+#define CCDC_PIX_FMT_MASK			3
+#define CCDC_PIX_FMT_SHIFT			12
+#define CCDC_DATAPOL_MASK			1
+#define CCDC_DATAPOL_SHIFT			6
+#define CCDC_WEN_ENABLE				(1 << 1)
+#define CCDC_VDHDEN_ENABLE			(1 << 16)
+#define CCDC_LPF_ENABLE				(1 << 14)
+#define CCDC_ALAW_ENABLE			1
+#define CCDC_ALAW_GAMA_WD_MASK			7
+#define CCDC_REC656IF_BT656_EN			3
+
+#define CCDC_FMTCFG_FMTMODE_MASK 		3
+#define CCDC_FMTCFG_FMTMODE_SHIFT		1
+#define CCDC_FMTCFG_LNUM_MASK			3
+#define CCDC_FMTCFG_LNUM_SHIFT			4
+#define CCDC_FMTCFG_ADDRINC_MASK		7
+#define CCDC_FMTCFG_ADDRINC_SHIFT		8
+
+#define CCDC_CCDCFG_FIDMD_SHIFT			6
+#define	CCDC_CCDCFG_WENLOG_SHIFT		8
+#define CCDC_CCDCFG_TRGSEL_SHIFT		9
+#define CCDC_CCDCFG_EXTRG_SHIFT			10
+#define CCDC_CCDCFG_MSBINVI_SHIFT		13
+
+#define CCDC_HSIZE_FLIP_SHIFT			12
+#define CCDC_HSIZE_FLIP_MASK			1
+#define CCDC_HSIZE_VAL_MASK			0xFFF
+#define CCDC_SDOFST_FIELD_INTERLEAVED		0x249
+#define CCDC_SDOFST_INTERLACE_INVERSE		0x4B6D
+#define CCDC_SDOFST_INTERLACE_NORMAL		0x0B6D
+#define CCDC_SDOFST_PROGRESSIVE_INVERSE		0x4000
+#define CCDC_SDOFST_PROGRESSIVE_NORMAL		0
+#define CCDC_START_PX_HOR_MASK			0x7FFF
+#define CCDC_NUM_PX_HOR_MASK			0x7FFF
+#define CCDC_START_VER_ONE_MASK			0x7FFF
+#define CCDC_START_VER_TWO_MASK			0x7FFF
+#define CCDC_NUM_LINES_VER			0x7FFF
+
+#define CCDC_BLK_CLAMP_ENABLE			(1 << 15)
+#define CCDC_BLK_SGAIN_MASK			0x1F
+#define CCDC_BLK_ST_PXL_MASK			0x1FFF
+#define CCDC_BLK_SAMPLE_LN_MASK			3
+#define CCDC_BLK_SAMPLE_LN_SHIFT		13
+
+#define CCDC_NUM_LINE_CALC_MASK			3
+#define CCDC_NUM_LINE_CALC_SHIFT		14
+
+#define CCDC_BLK_DC_SUB_MASK			0x3FFF
+#define CCDC_BLK_COMP_MASK			0xFF
+#define CCDC_BLK_COMP_GB_COMP_SHIFT		8
+#define CCDC_BLK_COMP_GR_COMP_SHIFT		0
+#define CCDC_BLK_COMP_R_COMP_SHIFT		8
+#define CCDC_LATCH_ON_VSYNC_DISABLE		(1 << 15)
+#define CCDC_LATCH_ON_VSYNC_ENABLE		(0 << 15)
+#define CCDC_FPC_ENABLE				(1 << 15)
+#define CCDC_FPC_FPC_NUM_MASK 			0x7FFF
+#define CCDC_DATA_PACK_ENABLE			(1 << 11)
+#define CCDC_FMT_HORZ_FMTLNH_MASK		0x1FFF
+#define CCDC_FMT_HORZ_FMTSPH_MASK		0x1FFF
+#define CCDC_FMT_HORZ_FMTSPH_SHIFT		16
+#define CCDC_FMT_VERT_FMTLNV_MASK		0x1FFF
+#define CCDC_FMT_VERT_FMTSLV_MASK		0x1FFF
+#define CCDC_FMT_VERT_FMTSLV_SHIFT		16
+#define CCDC_VP_OUT_VERT_NUM_MASK		0x3FFF
+#define CCDC_VP_OUT_VERT_NUM_SHIFT		17
+#define CCDC_VP_OUT_HORZ_NUM_MASK		0x1FFF
+#define CCDC_VP_OUT_HORZ_NUM_SHIFT		4
+#define CCDC_VP_OUT_HORZ_ST_MASK		0xF
+
+#define CCDC_CSC_COEF_INTEG_MASK		7
+#define CCDC_CSC_COEF_DECIMAL_MASK		0x1f
+#define CCDC_CSC_COEF_INTEG_SHIFT		5
+#define CCDC_CSCM_MSB_SHIFT			8
+#define CCDC_CSC_ENABLE				1
+#define CCDC_CSC_DEC_MAX			32
+
+#define CCDC_MFILT1_SHIFT			10
+#define CCDC_MFILT2_SHIFT			8
+#define CCDC_MED_FILT_THRESH			0x3FFF
+#define CCDC_LPF_MASK				1
+#define CCDC_LPF_SHIFT				14
+#define CCDC_OFFSET_MASK			0x3FF
+#define CCDC_DATASFT_MASK			7
+#define CCDC_DATASFT_SHIFT			8
+
+#define CCDC_DF_ENABLE				1
+
+#define CCDC_FMTPLEN_P0_MASK			0xF
+#define CCDC_FMTPLEN_P1_MASK			0xF
+#define CCDC_FMTPLEN_P2_MASK			7
+#define CCDC_FMTPLEN_P3_MASK			7
+#define CCDC_FMTPLEN_P0_SHIFT			0
+#define CCDC_FMTPLEN_P1_SHIFT			4
+#define CCDC_FMTPLEN_P2_SHIFT			8
+#define CCDC_FMTPLEN_P3_SHIFT			12
+
+#define CCDC_FMTSPH_MASK			0x1FFF
+#define CCDC_FMTLNH_MASK			0x1FFF
+#define CCDC_FMTSLV_MASK			0x1FFF
+#define CCDC_FMTLNV_MASK			0x7FFF
+#define CCDC_FMTRLEN_MASK			0x1FFF
+#define CCDC_FMTHCNT_MASK			0x1FFF
+
+#define CCDC_ADP_INIT_MASK			0x1FFF
+#define CCDC_ADP_LINE_SHIFT			13
+#define CCDC_ADP_LINE_MASK			3
+#define CCDC_FMTPGN_APTR_MASK			7
+
+#define CCDC_DFCCTL_GDFCEN_MASK			1
+#define CCDC_DFCCTL_VDFCEN_MASK			1
+#define CCDC_DFCCTL_VDFC_DISABLE		(0 << 4)
+#define CCDC_DFCCTL_VDFCEN_SHIFT		4
+#define CCDC_DFCCTL_VDFCSL_MASK			3
+#define CCDC_DFCCTL_VDFCSL_SHIFT		5
+#define CCDC_DFCCTL_VDFCUDA_MASK		1
+#define CCDC_DFCCTL_VDFCUDA_SHIFT		7
+#define CCDC_DFCCTL_VDFLSFT_MASK		3
+#define CCDC_DFCCTL_VDFLSFT_SHIFT		8
+#define CCDC_DFCMEMCTL_DFCMARST_MASK		1
+#define CCDC_DFCMEMCTL_DFCMARST_SHIFT		2
+#define CCDC_DFCMEMCTL_DFCMWR_MASK		1
+#define CCDC_DFCMEMCTL_DFCMWR_SHIFT		0
+#define CCDC_DFCMEMCTL_INC_ADDR			(0 << 2)
+
+#define CCDC_LSCCFG_GFTSF_MASK			7
+#define CCDC_LSCCFG_GFTSF_SHIFT			1
+#define CCDC_LSCCFG_GFTINV_MASK			0xf
+#define CCDC_LSCCFG_GFTINV_SHIFT		4
+#define CCDC_LSC_GFTABLE_SEL_MASK		3
+#define CCDC_LSC_GFTABLE_EPEL_SHIFT		8
+#define CCDC_LSC_GFTABLE_OPEL_SHIFT		10
+#define CCDC_LSC_GFTABLE_EPOL_SHIFT		12
+#define CCDC_LSC_GFTABLE_OPOL_SHIFT		14
+#define CCDC_LSC_GFMODE_MASK			3
+#define CCDC_LSC_GFMODE_SHIFT			4
+#define CCDC_LSC_DISABLE			0
+#define CCDC_LSC_ENABLE				1
+#define CCDC_LSC_TABLE1_SLC			0
+#define CCDC_LSC_TABLE2_SLC			1
+#define CCDC_LSC_TABLE3_SLC			2
+#define CCDC_LSC_MEMADDR_RESET			(1 << 2)
+#define CCDC_LSC_MEMADDR_INCR			(0 << 2)
+#define CCDC_LSC_FRAC_MASK_T1			0xFF
+#define CCDC_LSC_INT_MASK			3
+#define CCDC_LSC_FRAC_MASK			0x3FFF
+#define CCDC_LSC_CENTRE_MASK			0x3FFF
+#define CCDC_LSC_COEF_MASK			0xff
+#define CCDC_LSC_COEFL_SHIFT			0
+#define CCDC_LSC_COEFU_SHIFT			8
+#define CCDC_GAIN_MASK				0x7FF
+#define CCDC_SYNCEN_VDHDEN_MASK			(1 << 0)
+#define CCDC_SYNCEN_WEN_MASK			(1 << 1)
+#define CCDC_SYNCEN_WEN_SHIFT			1
+
+/* Power on Defaults in hardware */
+#define MODESET_DEFAULT				0x200
+#define CULH_DEFAULT				0xFFFF
+#define CULV_DEFAULT				0xFF
+#define GAIN_DEFAULT				256
+#define OUTCLIP_DEFAULT				0x3FFF
+#define LSCCFG2_DEFAULT				0xE
+
+#endif
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
new file mode 100644
index 0000000..2f19a91
--- /dev/null
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -0,0 +1,878 @@
+/*
+ * Copyright (C) 2006-2009 Texas Instruments 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
+ *
+ * CCDC hardware module for DM6446
+ * ------------------------------
+ *
+ * This module is for configuring CCD controller of DM6446 VPFE to capture
+ * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
+ * such as Defect Pixel Correction, Color Space Conversion etc to
+ * pre-process the Raw Bayer RGB data, before writing it to SDRAM. This
+ * module also allows application to configure individual
+ * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
+ * To do so, application includes dm644x_ccdc.h and vpfe_capture.h header
+ * files.  The setparams() API is called by vpfe_capture driver
+ * to configure module parameters. This file is named DM644x so that other
+ * variants such DM6443 may be supported using the same module.
+ *
+ * TODO: Test Raw bayer parameter settings and bayer capture
+ * 	 Split module parameter structure to module specific ioctl structs
+ * 	 investigate if enum used for user space type definition
+ * 	 to be replaced by #defines or integer
+ */
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+#include <media/davinci/dm644x_ccdc.h>
+#include <media/davinci/vpss.h>
+#include "dm644x_ccdc_regs.h"
+#include "ccdc_hw_device.h"
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CCDC Driver for DM6446");
+MODULE_AUTHOR("Texas Instruments");
+
+static struct device *dev;
+
+/* Object for CCDC raw mode */
+static struct ccdc_params_raw ccdc_hw_params_raw = {
+	.pix_fmt = CCDC_PIXFMT_RAW,
+	.frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
+	.win = CCDC_WIN_VGA,
+	.fid_pol = VPFE_PINPOL_POSITIVE,
+	.vd_pol = VPFE_PINPOL_POSITIVE,
+	.hd_pol = VPFE_PINPOL_POSITIVE,
+	.config_params = {
+		.data_sz = CCDC_DATA_10BITS,
+	},
+};
+
+/* Object for CCDC ycbcr mode */
+static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
+	.pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
+	.frm_fmt = CCDC_FRMFMT_INTERLACED,
+	.win = CCDC_WIN_PAL,
+	.fid_pol = VPFE_PINPOL_POSITIVE,
+	.vd_pol = VPFE_PINPOL_POSITIVE,
+	.hd_pol = VPFE_PINPOL_POSITIVE,
+	.bt656_enable = 1,
+	.pix_order = CCDC_PIXORDER_CBYCRY,
+	.buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
+};
+
+#define CCDC_MAX_RAW_YUV_FORMATS	2
+
+/* Raw Bayer formats */
+static u32 ccdc_raw_bayer_pix_formats[] =
+	{V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
+
+/* Raw YUV formats */
+static u32 ccdc_raw_yuv_pix_formats[] =
+	{V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
+
+static void *__iomem ccdc_base_addr;
+static int ccdc_addr_size;
+static enum vpfe_hw_if_type ccdc_if_type;
+
+/* register access routines */
+static inline u32 regr(u32 offset)
+{
+	return __raw_readl(ccdc_base_addr + offset);
+}
+
+static inline void regw(u32 val, u32 offset)
+{
+	__raw_writel(val, ccdc_base_addr + offset);
+}
+
+static void ccdc_set_ccdc_base(void *addr, int size)
+{
+	ccdc_base_addr = addr;
+	ccdc_addr_size = size;
+}
+
+static void ccdc_enable(int flag)
+{
+	regw(flag, CCDC_PCR);
+}
+
+static void ccdc_enable_vport(int flag)
+{
+	if (flag)
+		/* enable video port */
+		regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG);
+	else
+		regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG);
+}
+
+/*
+ * ccdc_setwin()
+ * This function will configure the window size
+ * to be capture in CCDC reg
+ */
+void ccdc_setwin(struct v4l2_rect *image_win,
+		enum ccdc_frmfmt frm_fmt,
+		int ppc)
+{
+	int horz_start, horz_nr_pixels;
+	int vert_start, vert_nr_lines;
+	int val = 0, mid_img = 0;
+
+	dev_dbg(dev, "\nStarting ccdc_setwin...");
+	/*
+	 * ppc - per pixel count. indicates how many pixels per cell
+	 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
+	 * raw capture this is 1
+	 */
+	horz_start = image_win->left << (ppc - 1);
+	horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
+	regw((horz_start << CCDC_HORZ_INFO_SPH_SHIFT) | horz_nr_pixels,
+	     CCDC_HORZ_INFO);
+
+	vert_start = image_win->top;
+
+	if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		vert_nr_lines = (image_win->height >> 1) - 1;
+		vert_start >>= 1;
+		/* Since first line doesn't have any data */
+		vert_start += 1;
+		/* configure VDINT0 */
+		val = (vert_start << CCDC_VDINT_VDINT0_SHIFT);
+		regw(val, CCDC_VDINT);
+
+	} else {
+		/* Since first line doesn't have any data */
+		vert_start += 1;
+		vert_nr_lines = image_win->height - 1;
+		/*
+		 * configure VDINT0 and VDINT1. VDINT1 will be at half
+		 * of image height
+		 */
+		mid_img = vert_start + (image_win->height / 2);
+		val = (vert_start << CCDC_VDINT_VDINT0_SHIFT) |
+		    (mid_img & CCDC_VDINT_VDINT1_MASK);
+		regw(val, CCDC_VDINT);
+
+	}
+	regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
+	     CCDC_VERT_START);
+	regw(vert_nr_lines, CCDC_VERT_LINES);
+	dev_dbg(dev, "\nEnd of ccdc_setwin...");
+}
+
+static void ccdc_readregs(void)
+{
+	unsigned int val = 0;
+
+	val = regr(CCDC_ALAW);
+	dev_notice(dev, "\nReading 0x%x to ALAW...\n", val);
+	val = regr(CCDC_CLAMP);
+	dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val);
+	val = regr(CCDC_DCSUB);
+	dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val);
+	val = regr(CCDC_BLKCMP);
+	dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val);
+	val = regr(CCDC_FPC_ADDR);
+	dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val);
+	val = regr(CCDC_FPC);
+	dev_notice(dev, "\nReading 0x%x to FPC...\n", val);
+	val = regr(CCDC_FMTCFG);
+	dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val);
+	val = regr(CCDC_COLPTN);
+	dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val);
+	val = regr(CCDC_FMT_HORZ);
+	dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val);
+	val = regr(CCDC_FMT_VERT);
+	dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val);
+	val = regr(CCDC_HSIZE_OFF);
+	dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
+	val = regr(CCDC_SDOFST);
+	dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val);
+	val = regr(CCDC_VP_OUT);
+	dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val);
+	val = regr(CCDC_SYN_MODE);
+	dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val);
+	val = regr(CCDC_HORZ_INFO);
+	dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val);
+	val = regr(CCDC_VERT_START);
+	dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val);
+	val = regr(CCDC_VERT_LINES);
+	dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val);
+}
+
+static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
+{
+	if (ccdcparam->alaw.enable) {
+		if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
+		    (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
+		    (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
+			dev_dbg(dev, "\nInvalid data line select");
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
+{
+	struct ccdc_config_params_raw *config_params =
+		&ccdc_hw_params_raw.config_params;
+	unsigned int *fpc_virtaddr = NULL;
+	unsigned int *fpc_physaddr = NULL;
+
+	memcpy(config_params, raw_params, sizeof(*raw_params));
+	/*
+	 * allocate memory for fault pixel table and copy the user
+	 * values to the table
+	 */
+	if (!config_params->fault_pxl.enable)
+		return 0;
+
+	fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
+	fpc_virtaddr = (unsigned int *)phys_to_virt(
+				(unsigned long)fpc_physaddr);
+	/*
+	 * Allocate memory for FPC table if current
+	 * FPC table buffer is not big enough to
+	 * accomodate FPC Number requested
+	 */
+	if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) {
+		if (fpc_physaddr != NULL) {
+			free_pages((unsigned long)fpc_physaddr,
+				   get_order
+				   (config_params->fault_pxl.fp_num *
+				   FP_NUM_BYTES));
+		}
+
+		/* Allocate memory for FPC table */
+		fpc_virtaddr =
+			(unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA,
+							 get_order(raw_params->
+							 fault_pxl.fp_num *
+							 FP_NUM_BYTES));
+
+		if (fpc_virtaddr == NULL) {
+			dev_dbg(dev,
+				"\nUnable to allocate memory for FPC");
+			return -EFAULT;
+		}
+		fpc_physaddr =
+		    (unsigned int *)virt_to_phys((void *)fpc_virtaddr);
+	}
+
+	/* Copy number of fault pixels and FPC table */
+	config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num;
+	if (copy_from_user(fpc_virtaddr,
+			(void __user *)raw_params->fault_pxl.fpc_table_addr,
+			config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
+		dev_dbg(dev, "\n copy_from_user failed");
+		return -EFAULT;
+	}
+	config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
+	return 0;
+}
+
+static int ccdc_close(struct device *dev)
+{
+	struct ccdc_config_params_raw *config_params =
+		&ccdc_hw_params_raw.config_params;
+	unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
+
+	fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
+
+	if (fpc_physaddr != NULL) {
+		fpc_virtaddr = (unsigned int *)
+		    phys_to_virt((unsigned long)fpc_physaddr);
+		free_pages((unsigned long)fpc_virtaddr,
+			   get_order(config_params->fault_pxl.fp_num *
+			   FP_NUM_BYTES));
+	}
+	return 0;
+}
+
+/*
+ * ccdc_restore_defaults()
+ * This function will write defaults to all CCDC registers
+ */
+static void ccdc_restore_defaults(void)
+{
+	int i;
+
+	/* disable CCDC */
+	ccdc_enable(0);
+	/* set all registers to default value */
+	for (i = 4; i <= 0x94; i += 4)
+		regw(0,  i);
+	regw(CCDC_NO_CULLING, CCDC_CULLING);
+	regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW);
+}
+
+static int ccdc_open(struct device *device)
+{
+	dev = device;
+	ccdc_restore_defaults();
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_enable_vport(1);
+	return 0;
+}
+
+static void ccdc_sbl_reset(void)
+{
+	vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
+}
+
+/* Parameter operations */
+static int ccdc_set_params(void __user *params)
+{
+	struct ccdc_config_params_raw ccdc_raw_params;
+	int x;
+
+	if (ccdc_if_type != VPFE_RAW_BAYER)
+		return -EINVAL;
+
+	x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
+	if (x) {
+		dev_dbg(dev, "ccdc_set_params: error in copying"
+			   "ccdc params, %d\n", x);
+		return -EFAULT;
+	}
+
+	if (!validate_ccdc_param(&ccdc_raw_params)) {
+		if (!ccdc_update_raw_params(&ccdc_raw_params))
+			return 0;
+	}
+	return -EINVAL;
+}
+
+/*
+ * ccdc_config_ycbcr()
+ * This function will configure CCDC for YCbCr video capture
+ */
+void ccdc_config_ycbcr(void)
+{
+	struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
+	u32 syn_mode;
+
+	dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
+	/*
+	 * first restore the CCDC registers to default values
+	 * This is important since we assume default values to be set in
+	 * a lot of registers that we didn't touch
+	 */
+	ccdc_restore_defaults();
+
+	/*
+	 * configure pixel format, frame format, configure video frame
+	 * format, enable output to SDRAM, enable internal timing generator
+	 * and 8bit pack mode
+	 */
+	syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) <<
+		    CCDC_SYN_MODE_INPMOD_SHIFT) |
+		    ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) <<
+		    CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE |
+		    CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE);
+
+	/* setup BT.656 sync mode */
+	if (params->bt656_enable) {
+		regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF);
+
+		/*
+		 * configure the FID, VD, HD pin polarity,
+		 * fld,hd pol positive, vd negative, 8-bit data
+		 */
+		syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE | CCDC_SYN_MODE_8BITS;
+	} else {
+		/* y/c external sync mode */
+		syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
+			     CCDC_FID_POL_SHIFT) |
+			     ((params->hd_pol & CCDC_HD_POL_MASK) <<
+			     CCDC_HD_POL_SHIFT) |
+			     ((params->vd_pol & CCDC_VD_POL_MASK) <<
+			     CCDC_VD_POL_SHIFT));
+	}
+	regw(syn_mode, CCDC_SYN_MODE);
+
+	/* configure video window */
+	ccdc_setwin(&params->win, params->frm_fmt, 2);
+
+	/*
+	 * configure the order of y cb cr in SDRAM, and disable latch
+	 * internal register on vsync
+	 */
+	regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
+		 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
+
+	/*
+	 * configure the horizontal line offset. This should be a
+	 * on 32 byte bondary. So clear LSB 5 bits
+	 */
+	regw(((params->win.width * 2  + 31) & ~0x1f), CCDC_HSIZE_OFF);
+
+	/* configure the memory line offset */
+	if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
+		/* two fields are interleaved in memory */
+		regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
+
+	ccdc_sbl_reset();
+	dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
+	ccdc_readregs();
+}
+
+static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
+{
+	u32 val;
+
+	if (!bclamp->enable) {
+		/* configure DCSub */
+		val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
+		regw(val, CCDC_DCSUB);
+		dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val);
+		regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
+		dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n");
+		return;
+	}
+	/*
+	 * Configure gain,  Start pixel, No of line to be avg,
+	 * No of pixel/line to be avg, & Enable the Black clamping
+	 */
+	val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) |
+	       ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) <<
+		CCDC_BLK_ST_PXL_SHIFT) |
+	       ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) <<
+		CCDC_BLK_SAMPLE_LINE_SHIFT) |
+	       ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
+		CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
+	regw(val, CCDC_CLAMP);
+	dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val);
+	/* If Black clamping is enable then make dcsub 0 */
+	regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
+	dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n");
+}
+
+static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
+{
+	u32 val;
+
+	val = ((bcomp->b & CCDC_BLK_COMP_MASK) |
+	      ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
+	       CCDC_BLK_COMP_GB_COMP_SHIFT) |
+	      ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
+	       CCDC_BLK_COMP_GR_COMP_SHIFT) |
+	      ((bcomp->r & CCDC_BLK_COMP_MASK) <<
+	       CCDC_BLK_COMP_R_COMP_SHIFT));
+	regw(val, CCDC_BLKCMP);
+}
+
+static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
+{
+	u32 val;
+
+	/* Initially disable FPC */
+	val = CCDC_FPC_DISABLE;
+	regw(val, CCDC_FPC);
+
+	if (!fpc->enable)
+		return;
+
+	/* Configure Fault pixel if needed */
+	regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
+	dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n",
+		       (fpc->fpc_table_addr));
+	/* Write the FPC params with FPC disable */
+	val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
+	regw(val, CCDC_FPC);
+
+	dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
+	/* read the FPC register */
+	val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
+	regw(val, CCDC_FPC);
+	dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
+}
+
+/*
+ * ccdc_config_raw()
+ * This function will configure CCDC for Raw capture mode
+ */
+void ccdc_config_raw(void)
+{
+	struct ccdc_params_raw *params = &ccdc_hw_params_raw;
+	struct ccdc_config_params_raw *config_params =
+		&ccdc_hw_params_raw.config_params;
+	unsigned int syn_mode = 0;
+	unsigned int val;
+
+	dev_dbg(dev, "\nStarting ccdc_config_raw...");
+
+	/*      Reset CCDC */
+	ccdc_restore_defaults();
+
+	/* Disable latching function registers on VSYNC  */
+	regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
+
+	/*
+	 * Configure the vertical sync polarity(SYN_MODE.VDPOL),
+	 * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity
+	 * (SYN_MODE.FLDPOL), frame format(progressive or interlace),
+	 * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output
+	 * SDRAM, enable internal timing generator
+	 */
+	syn_mode =
+		(((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
+		((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
+		((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
+		((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
+		((config_params->data_sz & CCDC_DATA_SZ_MASK) <<
+		CCDC_DATA_SZ_SHIFT) |
+		((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) |
+		CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE);
+
+	/* Enable and configure aLaw register if needed */
+	if (config_params->alaw.enable) {
+		val = ((config_params->alaw.gama_wd &
+		      CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
+		regw(val, CCDC_ALAW);
+		dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val);
+	}
+
+	/* Configure video window */
+	ccdc_setwin(&params->win, params->frm_fmt, CCDC_PPC_RAW);
+
+	/* Configure Black Clamp */
+	ccdc_config_black_clamp(&config_params->blk_clamp);
+
+	/* Configure Black level compensation */
+	ccdc_config_black_compense(&config_params->blk_comp);
+
+	/* Configure Fault Pixel Correction */
+	ccdc_config_fpc(&config_params->fault_pxl);
+
+	/* If data size is 8 bit then pack the data */
+	if ((config_params->data_sz == CCDC_DATA_8BITS) ||
+	     config_params->alaw.enable)
+		syn_mode |= CCDC_DATA_PACK_ENABLE;
+
+#ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE
+	/* enable video port */
+	val = CCDC_ENABLE_VIDEO_PORT;
+#else
+	/* disable video port */
+	val = CCDC_DISABLE_VIDEO_PORT;
+#endif
+
+	if (config_params->data_sz == CCDC_DATA_8BITS)
+		val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
+		    << CCDC_FMTCFG_VPIN_SHIFT;
+	else
+		val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK)
+		    << CCDC_FMTCFG_VPIN_SHIFT;
+	/* Write value in FMTCFG */
+	regw(val, CCDC_FMTCFG);
+
+	dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val);
+	/* Configure the color pattern according to mt9t001 sensor */
+	regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
+
+	dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
+	/*
+	 * Configure Data formatter(Video port) pixel selection
+	 * (FMT_HORZ, FMT_VERT)
+	 */
+	val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) <<
+	      CCDC_FMT_HORZ_FMTSPH_SHIFT) |
+	      (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
+	regw(val, CCDC_FMT_HORZ);
+
+	dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
+	val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
+	    << CCDC_FMT_VERT_FMTSLV_SHIFT;
+	if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
+		val |= (params->win.height) & CCDC_FMT_VERT_FMTLNV_MASK;
+	else
+		val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
+
+	dev_dbg(dev, "\nparams->win.height  0x%x ...\n",
+	       params->win.height);
+	regw(val, CCDC_FMT_VERT);
+
+	dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val);
+
+	dev_dbg(dev, "\nbelow regw(val, FMT_VERT)...");
+
+	/*
+	 * Configure Horizontal offset register. If pack 8 is enabled then
+	 * 1 pixel will take 1 byte
+	 */
+	if ((config_params->data_sz == CCDC_DATA_8BITS) ||
+	    config_params->alaw.enable)
+		regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) &
+		    CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF);
+	else
+		/* else one pixel will take 2 byte */
+		regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) +
+		    CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK,
+		    CCDC_HSIZE_OFF);
+
+	/* Set value for SDOFST */
+	if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		if (params->image_invert_enable) {
+			/* For intelace inverse mode */
+			regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
+			dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n");
+		}
+
+		else {
+			/* For intelace non inverse mode */
+			regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
+			dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n");
+		}
+	} else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
+		regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
+		dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n");
+	}
+
+	/*
+	 * Configure video port pixel selection (VPOUT)
+	 * Here -1 is to make the height value less than FMT_VERT.FMTLNV
+	 */
+	if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
+		val = (((params->win.height - 1) & CCDC_VP_OUT_VERT_NUM_MASK))
+		    << CCDC_VP_OUT_VERT_NUM_SHIFT;
+	else
+		val =
+		    ((((params->win.height >> CCDC_INTERLACED_HEIGHT_SHIFT) -
+		     1) & CCDC_VP_OUT_VERT_NUM_MASK)) <<
+		    CCDC_VP_OUT_VERT_NUM_SHIFT;
+
+	val |= ((((params->win.width))) & CCDC_VP_OUT_HORZ_NUM_MASK)
+	    << CCDC_VP_OUT_HORZ_NUM_SHIFT;
+	val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
+	regw(val, CCDC_VP_OUT);
+
+	dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val);
+	regw(syn_mode, CCDC_SYN_MODE);
+	dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
+
+	ccdc_sbl_reset();
+	dev_dbg(dev, "\nend of ccdc_config_raw...");
+	ccdc_readregs();
+}
+
+static int ccdc_configure(void)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_config_raw();
+	else
+		ccdc_config_ycbcr();
+	return 0;
+}
+
+static int ccdc_set_buftype(enum ccdc_buftype buf_type)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_hw_params_raw.buf_type = buf_type;
+	else
+		ccdc_hw_params_ycbcr.buf_type = buf_type;
+	return 0;
+}
+
+static enum ccdc_buftype ccdc_get_buftype(void)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		return ccdc_hw_params_raw.buf_type;
+	return ccdc_hw_params_ycbcr.buf_type;
+}
+
+static int ccdc_enum_pix(u32 *pix, int i)
+{
+	int ret = -EINVAL;
+	if (ccdc_if_type == VPFE_RAW_BAYER) {
+		if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
+			*pix = ccdc_raw_bayer_pix_formats[i];
+			ret = 0;
+		}
+	} else {
+		if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
+			*pix = ccdc_raw_yuv_pix_formats[i];
+			ret = 0;
+		}
+	}
+	return ret;
+}
+
+static int ccdc_set_pixel_format(u32 pixfmt)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER) {
+		ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
+		if (pixfmt == V4L2_PIX_FMT_SBGGR8)
+			ccdc_hw_params_raw.config_params.alaw.enable = 1;
+		else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
+			return -EINVAL;
+	} else {
+		if (pixfmt == V4L2_PIX_FMT_YUYV)
+			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
+		else if (pixfmt == V4L2_PIX_FMT_UYVY)
+			ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
+		else
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static u32 ccdc_get_pixel_format(void)
+{
+	struct ccdc_a_law *alaw =
+		&ccdc_hw_params_raw.config_params.alaw;
+	u32 pixfmt;
+
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		if (alaw->enable)
+			pixfmt = V4L2_PIX_FMT_SBGGR8;
+		else
+			pixfmt = V4L2_PIX_FMT_SBGGR16;
+	else {
+		if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
+			pixfmt = V4L2_PIX_FMT_YUYV;
+		else
+			pixfmt = V4L2_PIX_FMT_UYVY;
+	}
+	return pixfmt;
+}
+
+static int ccdc_set_image_window(struct v4l2_rect *win)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_hw_params_raw.win = *win;
+	else
+		ccdc_hw_params_ycbcr.win = *win;
+	return 0;
+}
+
+static void ccdc_get_image_window(struct v4l2_rect *win)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		*win = ccdc_hw_params_raw.win;
+	else
+		*win = ccdc_hw_params_ycbcr.win;
+}
+
+static unsigned int ccdc_get_line_length(void)
+{
+	struct ccdc_config_params_raw *config_params =
+		&ccdc_hw_params_raw.config_params;
+	unsigned int len;
+
+	if (ccdc_if_type == VPFE_RAW_BAYER) {
+		if ((config_params->alaw.enable) ||
+		    (config_params->data_sz == CCDC_DATA_8BITS))
+			len = ccdc_hw_params_raw.win.width;
+		else
+			len = ccdc_hw_params_raw.win.width * 2;
+	} else
+		len = ccdc_hw_params_ycbcr.win.width * 2;
+	return ALIGN(len, 32);
+}
+
+static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		ccdc_hw_params_raw.frm_fmt = frm_fmt;
+	else
+		ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
+	return 0;
+}
+
+static enum ccdc_frmfmt ccdc_get_frame_format(void)
+{
+	if (ccdc_if_type == VPFE_RAW_BAYER)
+		return ccdc_hw_params_raw.frm_fmt;
+	else
+		return ccdc_hw_params_ycbcr.frm_fmt;
+}
+
+static int ccdc_getfid(void)
+{
+	return (regr(CCDC_SYN_MODE) >> 15) & 1;
+}
+
+/* misc operations */
+static inline void ccdc_setfbaddr(unsigned long addr)
+{
+	regw(addr & 0xffffffe0, CCDC_SDR_ADDR);
+}
+
+static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
+{
+	ccdc_if_type = params->if_type;
+
+	switch (params->if_type) {
+	case VPFE_BT656:
+	case VPFE_YCBCR_SYNC_16:
+	case VPFE_YCBCR_SYNC_8:
+		ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
+		ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
+		break;
+	default:
+		/* TODO add support for raw bayer here */
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static struct ccdc_hw_device ccdc_hw_dev = {
+	.name = "DM6446 CCDC",
+	.owner = THIS_MODULE,
+	.hw_ops = {
+		.open = ccdc_open,
+		.close = ccdc_close,
+		.set_ccdc_base = ccdc_set_ccdc_base,
+		.reset = ccdc_sbl_reset,
+		.enable = ccdc_enable,
+		.set_hw_if_params = ccdc_set_hw_if_params,
+		.set_params = ccdc_set_params,
+		.configure = ccdc_configure,
+		.set_buftype = ccdc_set_buftype,
+		.get_buftype = ccdc_get_buftype,
+		.enum_pix = ccdc_enum_pix,
+		.set_pixel_format = ccdc_set_pixel_format,
+		.get_pixel_format = ccdc_get_pixel_format,
+		.set_frame_format = ccdc_set_frame_format,
+		.get_frame_format = ccdc_get_frame_format,
+		.set_image_window = ccdc_set_image_window,
+		.get_image_window = ccdc_get_image_window,
+		.get_line_length = ccdc_get_line_length,
+		.setfbaddr = ccdc_setfbaddr,
+		.getfid = ccdc_getfid,
+	},
+};
+
+static int dm644x_ccdc_init(void)
+{
+	printk(KERN_NOTICE "dm644x_ccdc_init\n");
+	if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
+		return -1;
+	printk(KERN_NOTICE "%s is registered with vpfe.\n",
+		ccdc_hw_dev.name);
+	return 0;
+}
+
+static void dm644x_ccdc_exit(void)
+{
+	vpfe_unregister_ccdc_device(&ccdc_hw_dev);
+}
+
+module_init(dm644x_ccdc_init);
+module_exit(dm644x_ccdc_exit);
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/video/davinci/dm644x_ccdc_regs.h
new file mode 100644
index 0000000..6e5d053
--- /dev/null
+++ b/drivers/media/video/davinci/dm644x_ccdc_regs.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2006-2009 Texas Instruments 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 _DM644X_CCDC_REGS_H
+#define _DM644X_CCDC_REGS_H
+
+/**************************************************************************\
+* Register OFFSET Definitions
+\**************************************************************************/
+#define CCDC_PID				0x0
+#define CCDC_PCR				0x4
+#define CCDC_SYN_MODE				0x8
+#define CCDC_HD_VD_WID				0xc
+#define CCDC_PIX_LINES				0x10
+#define CCDC_HORZ_INFO				0x14
+#define CCDC_VERT_START				0x18
+#define CCDC_VERT_LINES				0x1c
+#define CCDC_CULLING				0x20
+#define CCDC_HSIZE_OFF				0x24
+#define CCDC_SDOFST				0x28
+#define CCDC_SDR_ADDR				0x2c
+#define CCDC_CLAMP				0x30
+#define CCDC_DCSUB				0x34
+#define CCDC_COLPTN				0x38
+#define CCDC_BLKCMP				0x3c
+#define CCDC_FPC				0x40
+#define CCDC_FPC_ADDR				0x44
+#define CCDC_VDINT				0x48
+#define CCDC_ALAW				0x4c
+#define CCDC_REC656IF				0x50
+#define CCDC_CCDCFG				0x54
+#define CCDC_FMTCFG				0x58
+#define CCDC_FMT_HORZ				0x5c
+#define CCDC_FMT_VERT				0x60
+#define CCDC_FMT_ADDR0				0x64
+#define CCDC_FMT_ADDR1				0x68
+#define CCDC_FMT_ADDR2				0x6c
+#define CCDC_FMT_ADDR3				0x70
+#define CCDC_FMT_ADDR4				0x74
+#define CCDC_FMT_ADDR5				0x78
+#define CCDC_FMT_ADDR6				0x7c
+#define CCDC_FMT_ADDR7				0x80
+#define CCDC_PRGEVEN_0				0x84
+#define CCDC_PRGEVEN_1				0x88
+#define CCDC_PRGODD_0				0x8c
+#define CCDC_PRGODD_1				0x90
+#define CCDC_VP_OUT				0x94
+
+
+/***************************************************************
+*	Define for various register bit mask and shifts for CCDC
+****************************************************************/
+#define CCDC_FID_POL_MASK			1
+#define CCDC_FID_POL_SHIFT			4
+#define CCDC_HD_POL_MASK			1
+#define CCDC_HD_POL_SHIFT			3
+#define CCDC_VD_POL_MASK			1
+#define CCDC_VD_POL_SHIFT			2
+#define CCDC_HSIZE_OFF_MASK			0xffffffe0
+#define CCDC_32BYTE_ALIGN_VAL			31
+#define CCDC_FRM_FMT_MASK			0x1
+#define CCDC_FRM_FMT_SHIFT			7
+#define CCDC_DATA_SZ_MASK			7
+#define CCDC_DATA_SZ_SHIFT			8
+#define CCDC_PIX_FMT_MASK			3
+#define CCDC_PIX_FMT_SHIFT			12
+#define CCDC_VP2SDR_DISABLE			0xFFFBFFFF
+#define CCDC_WEN_ENABLE				(1 << 17)
+#define CCDC_SDR2RSZ_DISABLE			0xFFF7FFFF
+#define CCDC_VDHDEN_ENABLE			(1 << 16)
+#define CCDC_LPF_ENABLE				(1 << 14)
+#define CCDC_ALAW_ENABLE			(1 << 3)
+#define CCDC_ALAW_GAMA_WD_MASK			7
+#define CCDC_BLK_CLAMP_ENABLE			(1 << 31)
+#define CCDC_BLK_SGAIN_MASK			0x1F
+#define CCDC_BLK_ST_PXL_MASK			0x7FFF
+#define CCDC_BLK_ST_PXL_SHIFT			10
+#define CCDC_BLK_SAMPLE_LN_MASK			7
+#define CCDC_BLK_SAMPLE_LN_SHIFT		28
+#define CCDC_BLK_SAMPLE_LINE_MASK		7
+#define CCDC_BLK_SAMPLE_LINE_SHIFT		25
+#define CCDC_BLK_DC_SUB_MASK			0x03FFF
+#define CCDC_BLK_COMP_MASK			0xFF
+#define CCDC_BLK_COMP_GB_COMP_SHIFT		8
+#define CCDC_BLK_COMP_GR_COMP_SHIFT		16
+#define CCDC_BLK_COMP_R_COMP_SHIFT		24
+#define CCDC_LATCH_ON_VSYNC_DISABLE		(1 << 15)
+#define CCDC_FPC_ENABLE				(1 << 15)
+#define CCDC_FPC_DISABLE			0
+#define CCDC_FPC_FPC_NUM_MASK 			0x7FFF
+#define CCDC_DATA_PACK_ENABLE			(1 << 11)
+#define CCDC_FMTCFG_VPIN_MASK			7
+#define CCDC_FMTCFG_VPIN_SHIFT			12
+#define CCDC_FMT_HORZ_FMTLNH_MASK		0x1FFF
+#define CCDC_FMT_HORZ_FMTSPH_MASK		0x1FFF
+#define CCDC_FMT_HORZ_FMTSPH_SHIFT		16
+#define CCDC_FMT_VERT_FMTLNV_MASK		0x1FFF
+#define CCDC_FMT_VERT_FMTSLV_MASK		0x1FFF
+#define CCDC_FMT_VERT_FMTSLV_SHIFT		16
+#define CCDC_VP_OUT_VERT_NUM_MASK		0x3FFF
+#define CCDC_VP_OUT_VERT_NUM_SHIFT		17
+#define CCDC_VP_OUT_HORZ_NUM_MASK		0x1FFF
+#define CCDC_VP_OUT_HORZ_NUM_SHIFT		4
+#define CCDC_VP_OUT_HORZ_ST_MASK		0xF
+#define CCDC_HORZ_INFO_SPH_SHIFT		16
+#define CCDC_VERT_START_SLV0_SHIFT		16
+#define CCDC_VDINT_VDINT0_SHIFT			16
+#define CCDC_VDINT_VDINT1_MASK			0xFFFF
+#define CCDC_PPC_RAW				1
+#define CCDC_DCSUB_DEFAULT_VAL			0
+#define CCDC_CLAMP_DEFAULT_VAL			0
+#define CCDC_ENABLE_VIDEO_PORT			0x8000
+#define CCDC_DISABLE_VIDEO_PORT			0
+#define CCDC_COLPTN_VAL				0xBB11BB11
+#define CCDC_TWO_BYTES_PER_PIXEL		2
+#define CCDC_INTERLACED_IMAGE_INVERT		0x4B6D
+#define CCDC_INTERLACED_NO_IMAGE_INVERT		0x0249
+#define CCDC_PROGRESSIVE_IMAGE_INVERT		0x4000
+#define CCDC_PROGRESSIVE_NO_IMAGE_INVERT	0
+#define CCDC_INTERLACED_HEIGHT_SHIFT		1
+#define CCDC_SYN_MODE_INPMOD_SHIFT		12
+#define CCDC_SYN_MODE_INPMOD_MASK		3
+#define CCDC_SYN_MODE_8BITS			(7 << 8)
+#define CCDC_SYN_FLDMODE_MASK			1
+#define CCDC_SYN_FLDMODE_SHIFT			7
+#define CCDC_REC656IF_BT656_EN			3
+#define CCDC_SYN_MODE_VD_POL_NEGATIVE		(1 << 2)
+#define CCDC_CCDCFG_Y8POS_SHIFT			11
+#define CCDC_SDOFST_FIELD_INTERLEAVED		0x249
+#define CCDC_NO_CULLING				0xffff00ff
+#endif
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
new file mode 100644
index 0000000..402ce43
--- /dev/null
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -0,0 +1,2124 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments 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
+ *
+ * Driver name : VPFE Capture driver
+ *    VPFE Capture driver allows applications to capture and stream video
+ *    frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
+ *    TVP5146 or  Raw Bayer RGB image data from an image sensor
+ *    such as Microns' MT9T001, MT9T031 etc.
+ *
+ *    These SoCs have, in common, a Video Processing Subsystem (VPSS) that
+ *    consists of a Video Processing Front End (VPFE) for capturing
+ *    video/raw image data and Video Processing Back End (VPBE) for displaying
+ *    YUV data through an in-built analog encoder or Digital LCD port. This
+ *    driver is for capture through VPFE. A typical EVM using these SoCs have
+ *    following high level configuration.
+ *
+ *
+ *    decoder(TVP5146/		YUV/
+ * 	     MT9T001)   -->  Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
+ *    				data input              |      |
+ *							V      |
+ *						      SDRAM    |
+ *							       V
+ *							   Image Processor
+ *							       |
+ *							       V
+ *							     SDRAM
+ *    The data flow happens from a decoder connected to the VPFE over a
+ *    YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
+ *    and to the input of VPFE through an optional MUX (if more inputs are
+ *    to be interfaced on the EVM). The input data is first passed through
+ *    CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
+ *    does very little or no processing on YUV data and does pre-process Raw
+ *    Bayer RGB data through modules such as Defect Pixel Correction (DFC)
+ *    Color Space Conversion (CSC), data gain/offset etc. After this, data
+ *    can be written to SDRAM or can be connected to the image processing
+ *    block such as IPIPE (on DM355 only).
+ *
+ *    Features supported
+ *  		- MMAP IO
+ *		- Capture using TVP5146 over BT.656
+ *		- support for interfacing decoders using sub device model
+ *		- Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
+ *		  data capture to SDRAM.
+ *    TODO list
+ *		- Support multiple REQBUF after open
+ *		- Support for de-allocating buffers through REQBUF
+ *		- Support for Raw Bayer RGB capture
+ *		- Support for chaining Image Processor
+ *		- Support for static allocation of buffers
+ *		- Support for USERPTR IO
+ *		- Support for STREAMON before QBUF
+ *		- Support for control ioctls
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/version.h>
+#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/davinci/vpfe_capture.h>
+#include "ccdc_hw_device.h"
+
+static int debug;
+static u32 numbuffers = 3;
+static u32 bufsize = (720 * 576 * 2);
+
+module_param(numbuffers, uint, S_IRUGO);
+module_param(bufsize, uint, S_IRUGO);
+module_param(debug, int, 0644);
+
+MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
+MODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)");
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+
+/* standard information */
+struct vpfe_standard {
+	v4l2_std_id std_id;
+	unsigned int width;
+	unsigned int height;
+	struct v4l2_fract pixelaspect;
+	/* 0 - progressive, 1 - interlaced */
+	int frame_format;
+};
+
+/* ccdc configuration */
+struct ccdc_config {
+	/* This make sure vpfe is probed and ready to go */
+	int vpfe_probed;
+	/* name of ccdc device */
+	char name[32];
+	/* for storing mem maps for CCDC */
+	int ccdc_addr_size;
+	void *__iomem ccdc_addr;
+};
+
+/* data structures */
+static struct vpfe_config_params config_params = {
+	.min_numbuffers = 3,
+	.numbuffers = 3,
+	.min_bufsize = 720 * 480 * 2,
+	.device_bufsize = 720 * 576 * 2,
+};
+
+/* ccdc device registered */
+static struct ccdc_hw_device *ccdc_dev;
+/* lock for accessing ccdc information */
+static DEFINE_MUTEX(ccdc_lock);
+/* ccdc configuration */
+static struct ccdc_config *ccdc_cfg;
+
+const struct vpfe_standard vpfe_standards[] = {
+	{V4L2_STD_525_60, 720, 480, {11, 10}, 1},
+	{V4L2_STD_625_50, 720, 576, {54, 59}, 1},
+};
+
+/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
+static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
+	{
+		.fmtdesc = {
+			.index = 0,
+			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.description = "Bayer GrRBGb 8bit A-Law compr.",
+			.pixelformat = V4L2_PIX_FMT_SBGGR8,
+		},
+		.bpp = 1,
+	},
+	{
+		.fmtdesc = {
+			.index = 1,
+			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.description = "Bayer GrRBGb - 16bit",
+			.pixelformat = V4L2_PIX_FMT_SBGGR16,
+		},
+		.bpp = 2,
+	},
+	{
+		.fmtdesc = {
+			.index = 2,
+			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.description = "Bayer GrRBGb 8bit DPCM compr.",
+			.pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
+		},
+		.bpp = 1,
+	},
+	{
+		.fmtdesc = {
+			.index = 3,
+			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.description = "YCbCr 4:2:2 Interleaved UYVY",
+			.pixelformat = V4L2_PIX_FMT_UYVY,
+		},
+		.bpp = 2,
+	},
+	{
+		.fmtdesc = {
+			.index = 4,
+			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.description = "YCbCr 4:2:2 Interleaved YUYV",
+			.pixelformat = V4L2_PIX_FMT_YUYV,
+		},
+		.bpp = 2,
+	},
+	{
+		.fmtdesc = {
+			.index = 5,
+			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.description = "Y/CbCr 4:2:0 - Semi planar",
+			.pixelformat = V4L2_PIX_FMT_NV12,
+		},
+		.bpp = 1,
+	},
+};
+
+/*
+ * vpfe_lookup_pix_format()
+ * lookup an entry in the vpfe pix format table based on pix_format
+ */
+static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
+		if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat)
+			return &vpfe_pix_fmts[i];
+	}
+	return NULL;
+}
+
+/*
+ * vpfe_register_ccdc_device. CCDC module calls this to
+ * register with vpfe capture
+ */
+int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
+{
+	int ret = 0;
+	printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
+
+	BUG_ON(!dev->hw_ops.open);
+	BUG_ON(!dev->hw_ops.enable);
+	BUG_ON(!dev->hw_ops.set_hw_if_params);
+	BUG_ON(!dev->hw_ops.configure);
+	BUG_ON(!dev->hw_ops.set_buftype);
+	BUG_ON(!dev->hw_ops.get_buftype);
+	BUG_ON(!dev->hw_ops.enum_pix);
+	BUG_ON(!dev->hw_ops.set_frame_format);
+	BUG_ON(!dev->hw_ops.get_frame_format);
+	BUG_ON(!dev->hw_ops.get_pixel_format);
+	BUG_ON(!dev->hw_ops.set_pixel_format);
+	BUG_ON(!dev->hw_ops.set_params);
+	BUG_ON(!dev->hw_ops.set_image_window);
+	BUG_ON(!dev->hw_ops.get_image_window);
+	BUG_ON(!dev->hw_ops.get_line_length);
+	BUG_ON(!dev->hw_ops.setfbaddr);
+	BUG_ON(!dev->hw_ops.getfid);
+
+	mutex_lock(&ccdc_lock);
+	if (NULL == ccdc_cfg) {
+		/*
+		 * TODO. Will this ever happen? if so, we need to fix it.
+		 * Proabably we need to add the request to a linked list and
+		 * walk through it during vpfe probe
+		 */
+		printk(KERN_ERR "vpfe capture not initialized\n");
+		ret = -1;
+		goto unlock;
+	}
+
+	if (strcmp(dev->name, ccdc_cfg->name)) {
+		/* ignore this ccdc */
+		ret = -1;
+		goto unlock;
+	}
+
+	if (ccdc_dev) {
+		printk(KERN_ERR "ccdc already registered\n");
+		ret = -1;
+		goto unlock;
+	}
+
+	ccdc_dev = dev;
+	dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr,
+				  ccdc_cfg->ccdc_addr_size);
+unlock:
+	mutex_unlock(&ccdc_lock);
+	return ret;
+}
+EXPORT_SYMBOL(vpfe_register_ccdc_device);
+
+/*
+ * vpfe_unregister_ccdc_device. CCDC module calls this to
+ * unregister with vpfe capture
+ */
+void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev)
+{
+	if (NULL == dev) {
+		printk(KERN_ERR "invalid ccdc device ptr\n");
+		return;
+	}
+
+	printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n",
+		dev->name);
+
+	if (strcmp(dev->name, ccdc_cfg->name)) {
+		/* ignore this ccdc */
+		return;
+	}
+
+	mutex_lock(&ccdc_lock);
+	ccdc_dev = NULL;
+	mutex_unlock(&ccdc_lock);
+	return;
+}
+EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
+
+/*
+ * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings
+ */
+static int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev,
+				 struct v4l2_format *f)
+{
+	struct v4l2_rect image_win;
+	enum ccdc_buftype buf_type;
+	enum ccdc_frmfmt frm_fmt;
+
+	memset(f, 0, sizeof(*f));
+	f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	ccdc_dev->hw_ops.get_image_window(&image_win);
+	f->fmt.pix.width = image_win.width;
+	f->fmt.pix.height = image_win.height;
+	f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length();
+	f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
+				f->fmt.pix.height;
+	buf_type = ccdc_dev->hw_ops.get_buftype();
+	f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format();
+	frm_fmt = ccdc_dev->hw_ops.get_frame_format();
+	if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
+		f->fmt.pix.field = V4L2_FIELD_NONE;
+	else if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
+		if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
+			f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+		else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
+			f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
+		else {
+			v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n");
+			return -EINVAL;
+		}
+	} else {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * vpfe_config_ccdc_image_format()
+ * For a pix format, configure ccdc to setup the capture
+ */
+static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
+{
+	enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
+	int ret = 0;
+
+	if (ccdc_dev->hw_ops.set_pixel_format(
+			vpfe_dev->fmt.fmt.pix.pixelformat) < 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			"couldn't set pix format in ccdc\n");
+		return -EINVAL;
+	}
+	/* configure the image window */
+	ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
+
+	switch (vpfe_dev->fmt.fmt.pix.field) {
+	case V4L2_FIELD_INTERLACED:
+		/* do nothing, since it is default */
+		ret = ccdc_dev->hw_ops.set_buftype(
+				CCDC_BUFTYPE_FLD_INTERLEAVED);
+		break;
+	case V4L2_FIELD_NONE:
+		frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
+		/* buffer type only applicable for interlaced scan */
+		break;
+	case V4L2_FIELD_SEQ_TB:
+		ret = ccdc_dev->hw_ops.set_buftype(
+				CCDC_BUFTYPE_FLD_SEPARATED);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set the frame format */
+	if (!ret)
+		ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt);
+	return ret;
+}
+/*
+ * vpfe_config_image_format()
+ * For a given standard, this functions sets up the default
+ * pix format & crop values in the vpfe device and ccdc.  It first
+ * starts with defaults based values from the standard table.
+ * It then checks if sub device support g_fmt and then override the
+ * values based on that.Sets crop values to match with scan resolution
+ * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
+ * values in ccdc
+ */
+static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
+				    const v4l2_std_id *std_id)
+{
+	struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
+	int i, ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
+		if (vpfe_standards[i].std_id & *std_id) {
+			vpfe_dev->std_info.active_pixels =
+					vpfe_standards[i].width;
+			vpfe_dev->std_info.active_lines =
+					vpfe_standards[i].height;
+			vpfe_dev->std_info.frame_format =
+					vpfe_standards[i].frame_format;
+			vpfe_dev->std_index = i;
+			break;
+		}
+	}
+
+	if (i ==  ARRAY_SIZE(vpfe_standards)) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n");
+		return -EINVAL;
+	}
+
+	vpfe_dev->crop.top = 0;
+	vpfe_dev->crop.left = 0;
+	vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
+	vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
+	vpfe_dev->fmt.fmt.pix.width = vpfe_dev->crop.width;
+	vpfe_dev->fmt.fmt.pix.height = vpfe_dev->crop.height;
+
+	/* first field and frame format based on standard frame format */
+	if (vpfe_dev->std_info.frame_format) {
+		vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
+		/* assume V4L2_PIX_FMT_UYVY as default */
+		vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+	} else {
+		vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_NONE;
+		/* assume V4L2_PIX_FMT_SBGGR8 */
+		vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+	}
+
+	/* if sub device supports g_fmt, override the defaults */
+	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
+			sdinfo->grp_id, video, g_fmt, &vpfe_dev->fmt);
+
+	if (ret && ret != -ENOIOCTLCMD) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			"error in getting g_fmt from sub device\n");
+		return ret;
+	}
+
+	/* Sets the values in CCDC */
+	ret = vpfe_config_ccdc_image_format(vpfe_dev);
+	if (ret)
+		return ret;
+
+	/* Update the values of sizeimage and bytesperline */
+	if (!ret) {
+		vpfe_dev->fmt.fmt.pix.bytesperline =
+			ccdc_dev->hw_ops.get_line_length();
+		vpfe_dev->fmt.fmt.pix.sizeimage =
+			vpfe_dev->fmt.fmt.pix.bytesperline *
+			vpfe_dev->fmt.fmt.pix.height;
+	}
+	return ret;
+}
+
+static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
+{
+	int ret = 0;
+
+	/* set first input of current subdevice as the current input */
+	vpfe_dev->current_input = 0;
+
+	/* set default standard */
+	vpfe_dev->std_index = 0;
+
+	/* Configure the default format information */
+	ret = vpfe_config_image_format(vpfe_dev,
+				&vpfe_standards[vpfe_dev->std_index].std_id);
+	if (ret)
+		return ret;
+
+	/* now open the ccdc device to initialize it */
+	mutex_lock(&ccdc_lock);
+	if (NULL == ccdc_dev) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n");
+		ret = -ENODEV;
+		goto unlock;
+	}
+
+	if (!try_module_get(ccdc_dev->owner)) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n");
+		ret = -ENODEV;
+		goto unlock;
+	}
+	ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
+	if (!ret)
+		vpfe_dev->initialized = 1;
+unlock:
+	mutex_unlock(&ccdc_lock);
+	return ret;
+}
+
+/*
+ * vpfe_open : It creates object of file handle structure and
+ * stores it in private_data  member of filepointer
+ */
+static int vpfe_open(struct file *file)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_fh *fh;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
+
+	if (!vpfe_dev->cfg->num_subdevs) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n");
+		return -ENODEV;
+	}
+
+	/* Allocate memory for the file handle object */
+	fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
+	if (NULL == fh) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			"unable to allocate memory for file handle object\n");
+		return -ENOMEM;
+	}
+	/* store pointer to fh in private_data member of file */
+	file->private_data = fh;
+	fh->vpfe_dev = vpfe_dev;
+	mutex_lock(&vpfe_dev->lock);
+	/* If decoder is not initialized. initialize it */
+	if (!vpfe_dev->initialized) {
+		if (vpfe_initialize_device(vpfe_dev)) {
+			mutex_unlock(&vpfe_dev->lock);
+			return -ENODEV;
+		}
+	}
+	/* Increment device usrs counter */
+	vpfe_dev->usrs++;
+	/* Set io_allowed member to false */
+	fh->io_allowed = 0;
+	/* Initialize priority of this instance to default priority */
+	fh->prio = V4L2_PRIORITY_UNSET;
+	v4l2_prio_open(&vpfe_dev->prio, &fh->prio);
+	mutex_unlock(&vpfe_dev->lock);
+	return 0;
+}
+
+static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
+{
+	unsigned long addr;
+
+	vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
+					struct videobuf_buffer, queue);
+	list_del(&vpfe_dev->next_frm->queue);
+	vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
+	addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
+	ccdc_dev->hw_ops.setfbaddr(addr);
+}
+
+static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev)
+{
+	struct timeval timevalue;
+
+	do_gettimeofday(&timevalue);
+	vpfe_dev->cur_frm->ts = timevalue;
+	vpfe_dev->cur_frm->state = VIDEOBUF_DONE;
+	vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage;
+	wake_up_interruptible(&vpfe_dev->cur_frm->done);
+	vpfe_dev->cur_frm = vpfe_dev->next_frm;
+}
+
+/* ISR for VINT0*/
+static irqreturn_t vpfe_isr(int irq, void *dev_id)
+{
+	struct vpfe_device *vpfe_dev = dev_id;
+	enum v4l2_field field;
+	unsigned long addr;
+	int fid;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
+	field = vpfe_dev->fmt.fmt.pix.field;
+
+	/* if streaming not started, don't do anything */
+	if (!vpfe_dev->started)
+		return IRQ_HANDLED;
+
+	/* only for 6446 this will be applicable */
+	if (NULL != ccdc_dev->hw_ops.reset)
+		ccdc_dev->hw_ops.reset();
+
+	if (field == V4L2_FIELD_NONE) {
+		/* handle progressive frame capture */
+		v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+			"frame format is progressive...\n");
+		if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
+			vpfe_process_buffer_complete(vpfe_dev);
+		return IRQ_HANDLED;
+	}
+
+	/* interlaced or TB capture check which field we are in hardware */
+	fid = ccdc_dev->hw_ops.getfid();
+
+	/* switch the software maintained field id */
+	vpfe_dev->field_id ^= 1;
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n",
+		fid, vpfe_dev->field_id);
+	if (fid == vpfe_dev->field_id) {
+		/* we are in-sync here,continue */
+		if (fid == 0) {
+			/*
+			 * One frame is just being captured. If the next frame
+			 * is available, release the current frame and move on
+			 */
+			if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
+				vpfe_process_buffer_complete(vpfe_dev);
+			/*
+			 * based on whether the two fields are stored
+			 * interleavely or separately in memory, reconfigure
+			 * the CCDC memory address
+			 */
+			if (field == V4L2_FIELD_SEQ_TB) {
+				addr =
+				  videobuf_to_dma_contig(vpfe_dev->cur_frm);
+				addr += vpfe_dev->field_off;
+				ccdc_dev->hw_ops.setfbaddr(addr);
+			}
+			return IRQ_HANDLED;
+		}
+		/*
+		 * if one field is just being captured configure
+		 * the next frame get the next frame from the empty
+		 * queue if no frame is available hold on to the
+		 * current buffer
+		 */
+		spin_lock(&vpfe_dev->dma_queue_lock);
+		if (!list_empty(&vpfe_dev->dma_queue) &&
+		    vpfe_dev->cur_frm == vpfe_dev->next_frm)
+			vpfe_schedule_next_buffer(vpfe_dev);
+		spin_unlock(&vpfe_dev->dma_queue_lock);
+	} else if (fid == 0) {
+		/*
+		 * out of sync. Recover from any hardware out-of-sync.
+		 * May loose one frame
+		 */
+		vpfe_dev->field_id = fid;
+	}
+	return IRQ_HANDLED;
+}
+
+/* vdint1_isr - isr handler for VINT1 interrupt */
+static irqreturn_t vdint1_isr(int irq, void *dev_id)
+{
+	struct vpfe_device *vpfe_dev = dev_id;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
+
+	/* if streaming not started, don't do anything */
+	if (!vpfe_dev->started)
+		return IRQ_HANDLED;
+
+	spin_lock(&vpfe_dev->dma_queue_lock);
+	if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
+	    !list_empty(&vpfe_dev->dma_queue) &&
+	    vpfe_dev->cur_frm == vpfe_dev->next_frm)
+		vpfe_schedule_next_buffer(vpfe_dev);
+	spin_unlock(&vpfe_dev->dma_queue_lock);
+	return IRQ_HANDLED;
+}
+
+static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
+{
+	enum ccdc_frmfmt frame_format;
+
+	frame_format = ccdc_dev->hw_ops.get_frame_format();
+	if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
+		free_irq(IRQ_VDINT1, vpfe_dev);
+}
+
+static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
+{
+	enum ccdc_frmfmt frame_format;
+
+	frame_format = ccdc_dev->hw_ops.get_frame_format();
+	if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
+		return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
+				    IRQF_DISABLED, "vpfe_capture1",
+				    vpfe_dev);
+	}
+	return 0;
+}
+
+/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */
+static void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev)
+{
+	vpfe_dev->started = 0;
+	ccdc_dev->hw_ops.enable(0);
+	if (ccdc_dev->hw_ops.enable_out_to_sdram)
+		ccdc_dev->hw_ops.enable_out_to_sdram(0);
+}
+
+/*
+ * vpfe_release : This function deletes buffer queue, frees the
+ * buffers and the vpfe file  handle
+ */
+static int vpfe_release(struct file *file)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_fh *fh = file->private_data;
+	struct vpfe_subdev_info *sdinfo;
+	int ret;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
+
+	/* Get the device lock */
+	mutex_lock(&vpfe_dev->lock);
+	/* if this instance is doing IO */
+	if (fh->io_allowed) {
+		if (vpfe_dev->started) {
+			sdinfo = vpfe_dev->current_subdev;
+			ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
+							 sdinfo->grp_id,
+							 video, s_stream, 0);
+			if (ret && (ret != -ENOIOCTLCMD))
+				v4l2_err(&vpfe_dev->v4l2_dev,
+				"stream off failed in subdev\n");
+			vpfe_stop_ccdc_capture(vpfe_dev);
+			vpfe_detach_irq(vpfe_dev);
+			videobuf_streamoff(&vpfe_dev->buffer_queue);
+		}
+		vpfe_dev->io_usrs = 0;
+		vpfe_dev->numbuffers = config_params.numbuffers;
+	}
+
+	/* Decrement device usrs counter */
+	vpfe_dev->usrs--;
+	/* Close the priority */
+	v4l2_prio_close(&vpfe_dev->prio, &fh->prio);
+	/* If this is the last file handle */
+	if (!vpfe_dev->usrs) {
+		vpfe_dev->initialized = 0;
+		if (ccdc_dev->hw_ops.close)
+			ccdc_dev->hw_ops.close(vpfe_dev->pdev);
+		module_put(ccdc_dev->owner);
+	}
+	mutex_unlock(&vpfe_dev->lock);
+	file->private_data = NULL;
+	/* Free memory allocated to file handle object */
+	kfree(fh);
+	return 0;
+}
+
+/*
+ * vpfe_mmap : It is used to map kernel space buffers
+ * into user spaces
+ */
+static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	/* Get the device object and file handle object */
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
+
+	return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma);
+}
+
+/*
+ * vpfe_poll: It is used for select/poll system call
+ */
+static unsigned int vpfe_poll(struct file *file, poll_table *wait)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
+
+	if (vpfe_dev->started)
+		return videobuf_poll_stream(file,
+					    &vpfe_dev->buffer_queue, wait);
+	return 0;
+}
+
+/* vpfe capture driver file operations */
+static const struct v4l2_file_operations vpfe_fops = {
+	.owner = THIS_MODULE,
+	.open = vpfe_open,
+	.release = vpfe_release,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap = vpfe_mmap,
+	.poll = vpfe_poll
+};
+
+/*
+ * vpfe_check_format()
+ * This function adjust the input pixel format as per hardware
+ * capabilities and update the same in pixfmt.
+ * Following algorithm used :-
+ *
+ *	If given pixformat is not in the vpfe list of pix formats or not
+ *	supported by the hardware, current value of pixformat in the device
+ *	is used
+ *	If given field is not supported, then current field is used. If field
+ *	is different from current, then it is matched with that from sub device.
+ *	Minimum height is 2 lines for interlaced or tb field and 1 line for
+ *	progressive. Maximum height is clamped to active active lines of scan
+ *	Minimum width is 32 bytes in memory and width is clamped to active
+ *	pixels of scan.
+ *	bytesperline is a multiple of 32.
+ */
+static const struct vpfe_pixel_format *
+	vpfe_check_format(struct vpfe_device *vpfe_dev,
+			  struct v4l2_pix_format *pixfmt)
+{
+	u32 min_height = 1, min_width = 32, max_width, max_height;
+	const struct vpfe_pixel_format *vpfe_pix_fmt;
+	u32 pix;
+	int temp, found;
+
+	vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
+	if (NULL == vpfe_pix_fmt) {
+		/*
+		 * use current pixel format in the vpfe device. We
+		 * will find this pix format in the table
+		 */
+		pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
+		vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
+	}
+
+	/* check if hw supports it */
+	temp = 0;
+	found = 0;
+	while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
+		if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) {
+			found = 1;
+			break;
+		}
+		temp++;
+	}
+
+	if (!found) {
+		/* use current pixel format */
+		pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
+		/*
+		 * Since this is currently used in the vpfe device, we
+		 * will find this pix format in the table
+		 */
+		vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
+	}
+
+	/* check what field format is supported */
+	if (pixfmt->field == V4L2_FIELD_ANY) {
+		/* if field is any, use current value as default */
+		pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
+	}
+
+	/*
+	 * if field is not same as current field in the vpfe device
+	 * try matching the field with the sub device field
+	 */
+	if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) {
+		/*
+		 * If field value is not in the supported fields, use current
+		 * field used in the device as default
+		 */
+		switch (pixfmt->field) {
+		case V4L2_FIELD_INTERLACED:
+		case V4L2_FIELD_SEQ_TB:
+			/* if sub device is supporting progressive, use that */
+			if (!vpfe_dev->std_info.frame_format)
+				pixfmt->field = V4L2_FIELD_NONE;
+			break;
+		case V4L2_FIELD_NONE:
+			if (vpfe_dev->std_info.frame_format)
+				pixfmt->field = V4L2_FIELD_INTERLACED;
+			break;
+
+		default:
+			/* use current field as default */
+			pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
+			break;
+		}
+	}
+
+	/* Now adjust image resolutions supported */
+	if (pixfmt->field == V4L2_FIELD_INTERLACED ||
+	    pixfmt->field == V4L2_FIELD_SEQ_TB)
+		min_height = 2;
+
+	max_width = vpfe_dev->std_info.active_pixels;
+	max_height = vpfe_dev->std_info.active_lines;
+	min_width /= vpfe_pix_fmt->bpp;
+
+	v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n",
+		  pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp);
+
+	pixfmt->width = clamp((pixfmt->width), min_width, max_width);
+	pixfmt->height = clamp((pixfmt->height), min_height, max_height);
+
+	/* If interlaced, adjust height to be a multiple of 2 */
+	if (pixfmt->field == V4L2_FIELD_INTERLACED)
+		pixfmt->height &= (~1);
+	/*
+	 * recalculate bytesperline and sizeimage since width
+	 * and height might have changed
+	 */
+	pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31)
+				& ~31);
+	if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
+		pixfmt->sizeimage =
+			pixfmt->bytesperline * pixfmt->height +
+			((pixfmt->bytesperline * pixfmt->height) >> 1);
+	else
+		pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
+
+	v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height ="
+		 " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n",
+		 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp,
+		 pixfmt->bytesperline, pixfmt->sizeimage);
+	return vpfe_pix_fmt;
+}
+
+static int vpfe_querycap(struct file *file, void  *priv,
+			       struct v4l2_capability *cap)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
+
+	cap->version = VPFE_CAPTURE_VERSION_CODE;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
+	strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
+	strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
+	return 0;
+}
+
+static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
+	/* Fill in the information about format */
+	*fmt = vpfe_dev->fmt;
+	return ret;
+}
+
+static int vpfe_enum_fmt_vid_cap(struct file *file, void  *priv,
+				   struct v4l2_fmtdesc *fmt)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	const struct vpfe_pixel_format *pix_fmt;
+	int temp_index;
+	u32 pix;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
+
+	if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0)
+		return -EINVAL;
+
+	/* Fill in the information about format */
+	pix_fmt = vpfe_lookup_pix_format(pix);
+	if (NULL != pix_fmt) {
+		temp_index = fmt->index;
+		*fmt = pix_fmt->fmtdesc;
+		fmt->index = temp_index;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	const struct vpfe_pixel_format *pix_fmts;
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n");
+
+	/* If streaming is started, return error */
+	if (vpfe_dev->started) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
+		return -EBUSY;
+	}
+
+	/* Check for valid frame format */
+	pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix);
+
+	if (NULL == pix_fmts)
+		return -EINVAL;
+
+	/* store the pixel format in the device  object */
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		return ret;
+
+	/* First detach any IRQ if currently attached */
+	vpfe_detach_irq(vpfe_dev);
+	vpfe_dev->fmt = *fmt;
+	/* set image capture parameters in the ccdc */
+	ret = vpfe_config_ccdc_image_format(vpfe_dev);
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	const struct vpfe_pixel_format *pix_fmts;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n");
+
+	pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix);
+	if (NULL == pix_fmts)
+		return -EINVAL;
+	return 0;
+}
+
+/*
+ * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a
+ * given app input index
+ */
+static int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev,
+					int *subdev_index,
+					int *subdev_input_index,
+					int app_input_index)
+{
+	struct vpfe_config *cfg = vpfe_dev->cfg;
+	struct vpfe_subdev_info *sdinfo;
+	int i, j = 0;
+
+	for (i = 0; i < cfg->num_subdevs; i++) {
+		sdinfo = &cfg->sub_devs[i];
+		if (app_input_index < (j + sdinfo->num_inputs)) {
+			*subdev_index = i;
+			*subdev_input_index = app_input_index - j;
+			return 0;
+		}
+		j += sdinfo->num_inputs;
+	}
+	return -EINVAL;
+}
+
+/*
+ * vpfe_get_app_input - Get app input index for a given subdev input index
+ * driver stores the input index of the current sub device and translate it
+ * when application request the current input
+ */
+static int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev,
+				    int *app_input_index)
+{
+	struct vpfe_config *cfg = vpfe_dev->cfg;
+	struct vpfe_subdev_info *sdinfo;
+	int i, j = 0;
+
+	for (i = 0; i < cfg->num_subdevs; i++) {
+		sdinfo = &cfg->sub_devs[i];
+		if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) {
+			if (vpfe_dev->current_input >= sdinfo->num_inputs)
+				return -1;
+			*app_input_index = j + vpfe_dev->current_input;
+			return 0;
+		}
+		j += sdinfo->num_inputs;
+	}
+	return -EINVAL;
+}
+
+static int vpfe_enum_input(struct file *file, void *priv,
+				 struct v4l2_input *inp)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+	int subdev, index ;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
+
+	if (vpfe_get_subdev_input_index(vpfe_dev,
+					&subdev,
+					&index,
+					inp->index) < 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "input information not found"
+			 " for the subdev\n");
+		return -EINVAL;
+	}
+	sdinfo = &vpfe_dev->cfg->sub_devs[subdev];
+	memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input));
+	return 0;
+}
+
+static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
+
+	return vpfe_get_app_input_index(vpfe_dev, index);
+}
+
+
+static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+	int subdev_index, inp_index;
+	struct vpfe_route *route;
+	u32 input = 0, output = 0;
+	int ret = -EINVAL;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
+
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		return ret;
+
+	/*
+	 * If streaming is started return device busy
+	 * error
+	 */
+	if (vpfe_dev->started) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
+		ret = -EBUSY;
+		goto unlock_out;
+	}
+
+	if (vpfe_get_subdev_input_index(vpfe_dev,
+					&subdev_index,
+					&inp_index,
+					index) < 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
+		goto unlock_out;
+	}
+
+	sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
+	route = &sdinfo->routes[inp_index];
+	if (route && sdinfo->can_route) {
+		input = route->input;
+		output = route->output;
+	}
+
+	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 video, s_routing, input, output, 0);
+
+	if (ret) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			"vpfe_doioctl:error in setting input in decoder\n");
+		ret = -EINVAL;
+		goto unlock_out;
+	}
+	vpfe_dev->current_subdev = sdinfo;
+	vpfe_dev->current_input = index;
+	vpfe_dev->std_index = 0;
+
+	/* set the bus/interface parameter for the sub device in ccdc */
+	ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params);
+	if (ret)
+		goto unlock_out;
+
+	/* set the default image parameters in the device */
+	ret = vpfe_config_image_format(vpfe_dev,
+				&vpfe_standards[vpfe_dev->std_index].std_id);
+unlock_out:
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
+
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	sdinfo = vpfe_dev->current_subdev;
+	if (ret)
+		return ret;
+	/* Call querystd function of decoder device */
+	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 video, querystd, std_id);
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_subdev_info *sdinfo;
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
+
+	/* Call decoder driver function to set the standard */
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		return ret;
+
+	sdinfo = vpfe_dev->current_subdev;
+	/* If streaming is started, return device busy error */
+	if (vpfe_dev->started) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
+		ret = -EBUSY;
+		goto unlock_out;
+	}
+
+	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					 core, s_std, *std_id);
+	if (ret < 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
+		goto unlock_out;
+	}
+	ret = vpfe_config_image_format(vpfe_dev, std_id);
+
+unlock_out:
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
+
+	*std_id = vpfe_standards[vpfe_dev->std_index].std_id;
+	return 0;
+}
+/*
+ *  Videobuf operations
+ */
+static int vpfe_videobuf_setup(struct videobuf_queue *vq,
+				unsigned int *count,
+				unsigned int *size)
+{
+	struct vpfe_fh *fh = vq->priv_data;
+	struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
+	*size = config_params.device_bufsize;
+
+	if (*count < config_params.min_numbuffers)
+		*count = config_params.min_numbuffers;
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+		"count=%d, size=%d\n", *count, *size);
+	return 0;
+}
+
+static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
+				struct videobuf_buffer *vb,
+				enum v4l2_field field)
+{
+	struct vpfe_fh *fh = vq->priv_data;
+	struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
+
+	/* If buffer is not initialized, initialize it */
+	if (VIDEOBUF_NEEDS_INIT == vb->state) {
+		vb->width = vpfe_dev->fmt.fmt.pix.width;
+		vb->height = vpfe_dev->fmt.fmt.pix.height;
+		vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
+		vb->field = field;
+	}
+	vb->state = VIDEOBUF_PREPARED;
+	return 0;
+}
+
+static void vpfe_videobuf_queue(struct videobuf_queue *vq,
+				struct videobuf_buffer *vb)
+{
+	/* Get the file handle object and device object */
+	struct vpfe_fh *fh = vq->priv_data;
+	struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+	unsigned long flags;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n");
+
+	/* add the buffer to the DMA queue */
+	spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
+	list_add_tail(&vb->queue, &vpfe_dev->dma_queue);
+	spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
+
+	/* Change state of the buffer */
+	vb->state = VIDEOBUF_QUEUED;
+}
+
+static void vpfe_videobuf_release(struct videobuf_queue *vq,
+				  struct videobuf_buffer *vb)
+{
+	struct vpfe_fh *fh = vq->priv_data;
+	struct vpfe_device *vpfe_dev = fh->vpfe_dev;
+	unsigned long flags;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n");
+
+	/*
+	 * We need to flush the buffer from the dma queue since
+	 * they are de-allocated
+	 */
+	spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
+	INIT_LIST_HEAD(&vpfe_dev->dma_queue);
+	spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
+	videobuf_dma_contig_free(vq, vb);
+	vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static struct videobuf_queue_ops vpfe_videobuf_qops = {
+	.buf_setup      = vpfe_videobuf_setup,
+	.buf_prepare    = vpfe_videobuf_prepare,
+	.buf_queue      = vpfe_videobuf_queue,
+	.buf_release    = vpfe_videobuf_release,
+};
+
+/*
+ * vpfe_reqbufs. currently support REQBUF only once opening
+ * the device.
+ */
+static int vpfe_reqbufs(struct file *file, void *priv,
+			struct v4l2_requestbuffers *req_buf)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_fh *fh = file->private_data;
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
+		return -EINVAL;
+	}
+
+	if (V4L2_MEMORY_USERPTR == req_buf->memory) {
+		/* we don't support user ptr IO */
+		v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs:"
+			 " USERPTR IO not supported\n");
+		return  -EINVAL;
+	}
+
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		return ret;
+
+	if (vpfe_dev->io_usrs != 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
+		ret = -EBUSY;
+		goto unlock_out;
+	}
+
+	vpfe_dev->memory = req_buf->memory;
+	videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
+				&vpfe_videobuf_qops,
+				NULL,
+				&vpfe_dev->irqlock,
+				req_buf->type,
+				vpfe_dev->fmt.fmt.pix.field,
+				sizeof(struct videobuf_buffer),
+				fh);
+
+	fh->io_allowed = 1;
+	vpfe_dev->io_usrs = 1;
+	INIT_LIST_HEAD(&vpfe_dev->dma_queue);
+	ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf);
+unlock_out:
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+static int vpfe_querybuf(struct file *file, void *priv,
+			 struct v4l2_buffer *buf)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+		return  -EINVAL;
+	}
+
+	if (vpfe_dev->memory != V4L2_MEMORY_MMAP) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
+		return -EINVAL;
+	}
+	/* Call videobuf_querybuf to get information */
+	return videobuf_querybuf(&vpfe_dev->buffer_queue, buf);
+}
+
+static int vpfe_qbuf(struct file *file, void *priv,
+		     struct v4l2_buffer *p)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_fh *fh = file->private_data;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * If this file handle is not allowed to do IO,
+	 * return error
+	 */
+	if (!fh->io_allowed) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
+		return -EACCES;
+	}
+	return videobuf_qbuf(&vpfe_dev->buffer_queue, p);
+}
+
+static int vpfe_dqbuf(struct file *file, void *priv,
+		      struct v4l2_buffer *buf)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+		return -EINVAL;
+	}
+	return videobuf_dqbuf(&vpfe_dev->buffer_queue,
+				      buf, file->f_flags & O_NONBLOCK);
+}
+
+/*
+ * vpfe_calculate_offsets : This function calculates buffers offset
+ * for top and bottom field
+ */
+static void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev)
+{
+	struct v4l2_rect image_win;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n");
+
+	ccdc_dev->hw_ops.get_image_window(&image_win);
+	vpfe_dev->field_off = image_win.height * image_win.width;
+}
+
+/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */
+static void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev)
+{
+	ccdc_dev->hw_ops.enable(1);
+	if (ccdc_dev->hw_ops.enable_out_to_sdram)
+		ccdc_dev->hw_ops.enable_out_to_sdram(1);
+	vpfe_dev->started = 1;
+}
+
+/*
+ * vpfe_streamon. Assume the DMA queue is not empty.
+ * application is expected to call QBUF before calling
+ * this ioctl. If not, driver returns error
+ */
+static int vpfe_streamon(struct file *file, void *priv,
+			 enum v4l2_buf_type buf_type)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_fh *fh = file->private_data;
+	struct vpfe_subdev_info *sdinfo;
+	unsigned long addr;
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+		return -EINVAL;
+	}
+
+	/* If file handle is not allowed IO, return error */
+	if (!fh->io_allowed) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
+		return -EACCES;
+	}
+
+	sdinfo = vpfe_dev->current_subdev;
+	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					video, s_stream, 1);
+
+	if (ret && (ret != -ENOIOCTLCMD)) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n");
+		return -EINVAL;
+	}
+
+	/* If buffer queue is empty, return error */
+	if (list_empty(&vpfe_dev->buffer_queue.stream)) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
+		return -EIO;
+	}
+
+	/* Call videobuf_streamon to start streaming * in videobuf */
+	ret = videobuf_streamon(&vpfe_dev->buffer_queue);
+	if (ret)
+		return ret;
+
+
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		goto streamoff;
+	/* Get the next frame from the buffer queue */
+	vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
+					struct videobuf_buffer, queue);
+	vpfe_dev->cur_frm = vpfe_dev->next_frm;
+	/* Remove buffer from the buffer queue */
+	list_del(&vpfe_dev->cur_frm->queue);
+	/* Mark state of the current frame to active */
+	vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
+	/* Initialize field_id and started member */
+	vpfe_dev->field_id = 0;
+	addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
+
+	/* Calculate field offset */
+	vpfe_calculate_offsets(vpfe_dev);
+
+	if (vpfe_attach_irq(vpfe_dev) < 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			 "Error in attaching interrupt handle\n");
+		ret = -EFAULT;
+		goto unlock_out;
+	}
+	if (ccdc_dev->hw_ops.configure() < 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			 "Error in configuring ccdc\n");
+		ret = -EINVAL;
+		goto unlock_out;
+	}
+	ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr));
+	vpfe_start_ccdc_capture(vpfe_dev);
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+unlock_out:
+	mutex_unlock(&vpfe_dev->lock);
+streamoff:
+	ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
+	return ret;
+}
+
+static int vpfe_streamoff(struct file *file, void *priv,
+			  enum v4l2_buf_type buf_type)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	struct vpfe_fh *fh = file->private_data;
+	struct vpfe_subdev_info *sdinfo;
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
+		return -EINVAL;
+	}
+
+	/* If io is allowed for this file handle, return error */
+	if (!fh->io_allowed) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
+		return -EACCES;
+	}
+
+	/* If streaming is not started, return error */
+	if (!vpfe_dev->started) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "device started\n");
+		return -EINVAL;
+	}
+
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		return ret;
+
+	vpfe_stop_ccdc_capture(vpfe_dev);
+	vpfe_detach_irq(vpfe_dev);
+
+	sdinfo = vpfe_dev->current_subdev;
+	ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
+					video, s_stream, 0);
+
+	if (ret && (ret != -ENOIOCTLCMD))
+		v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n");
+	ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+static int vpfe_cropcap(struct file *file, void *priv,
+			      struct v4l2_cropcap *crop)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
+
+	if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards))
+		return -EINVAL;
+
+	memset(crop, 0, sizeof(struct v4l2_cropcap));
+	crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	crop->bounds.width = crop->defrect.width =
+		vpfe_standards[vpfe_dev->std_index].width;
+	crop->bounds.height = crop->defrect.height =
+		vpfe_standards[vpfe_dev->std_index].height;
+	crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect;
+	return 0;
+}
+
+static int vpfe_g_crop(struct file *file, void *priv,
+			     struct v4l2_crop *crop)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_crop\n");
+
+	crop->c = vpfe_dev->crop;
+	return 0;
+}
+
+static int vpfe_s_crop(struct file *file, void *priv,
+			     struct v4l2_crop *crop)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n");
+
+	if (vpfe_dev->started) {
+		/* make sure streaming is not started */
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			"Cannot change crop when streaming is ON\n");
+		return -EBUSY;
+	}
+
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		return ret;
+
+	if (crop->c.top < 0 || crop->c.left < 0) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			"doesn't support negative values for top & left\n");
+		ret = -EINVAL;
+		goto unlock_out;
+	}
+
+	/* adjust the width to 16 pixel boundry */
+	crop->c.width = ((crop->c.width + 15) & ~0xf);
+
+	/* make sure parameters are valid */
+	if ((crop->c.left + crop->c.width >
+		vpfe_dev->std_info.active_pixels) ||
+	    (crop->c.top + crop->c.height >
+		vpfe_dev->std_info.active_lines)) {
+		v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n");
+		ret = -EINVAL;
+		goto unlock_out;
+	}
+	ccdc_dev->hw_ops.set_image_window(&crop->c);
+	vpfe_dev->fmt.fmt.pix.width = crop->c.width;
+	vpfe_dev->fmt.fmt.pix.height = crop->c.height;
+	vpfe_dev->fmt.fmt.pix.bytesperline =
+		ccdc_dev->hw_ops.get_line_length();
+	vpfe_dev->fmt.fmt.pix.sizeimage =
+		vpfe_dev->fmt.fmt.pix.bytesperline *
+		vpfe_dev->fmt.fmt.pix.height;
+	vpfe_dev->crop = crop->c;
+unlock_out:
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+
+static long vpfe_param_handler(struct file *file, void *priv,
+		int cmd, void *param)
+{
+	struct vpfe_device *vpfe_dev = video_drvdata(file);
+	int ret = 0;
+
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
+
+	if (vpfe_dev->started) {
+		/* only allowed if streaming is not started */
+		v4l2_err(&vpfe_dev->v4l2_dev, "device already started\n");
+		return -EBUSY;
+	}
+
+	ret = mutex_lock_interruptible(&vpfe_dev->lock);
+	if (ret)
+		return ret;
+
+	switch (cmd) {
+	case VPFE_CMD_S_CCDC_RAW_PARAMS:
+		v4l2_warn(&vpfe_dev->v4l2_dev,
+			  "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
+		ret = ccdc_dev->hw_ops.set_params(param);
+		if (ret) {
+			v4l2_err(&vpfe_dev->v4l2_dev,
+				"Error in setting parameters in CCDC\n");
+			goto unlock_out;
+		}
+		if (vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt) < 0) {
+			v4l2_err(&vpfe_dev->v4l2_dev,
+				"Invalid image format at CCDC\n");
+			goto unlock_out;
+		}
+		break;
+	default:
+		ret = -EINVAL;
+	}
+unlock_out:
+	mutex_unlock(&vpfe_dev->lock);
+	return ret;
+}
+
+
+/* vpfe capture ioctl operations */
+static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
+	.vidioc_querycap	 = vpfe_querycap,
+	.vidioc_g_fmt_vid_cap    = vpfe_g_fmt_vid_cap,
+	.vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap    = vpfe_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap  = vpfe_try_fmt_vid_cap,
+	.vidioc_enum_input	 = vpfe_enum_input,
+	.vidioc_g_input		 = vpfe_g_input,
+	.vidioc_s_input		 = vpfe_s_input,
+	.vidioc_querystd	 = vpfe_querystd,
+	.vidioc_s_std		 = vpfe_s_std,
+	.vidioc_g_std		 = vpfe_g_std,
+	.vidioc_reqbufs		 = vpfe_reqbufs,
+	.vidioc_querybuf	 = vpfe_querybuf,
+	.vidioc_qbuf		 = vpfe_qbuf,
+	.vidioc_dqbuf		 = vpfe_dqbuf,
+	.vidioc_streamon	 = vpfe_streamon,
+	.vidioc_streamoff	 = vpfe_streamoff,
+	.vidioc_cropcap		 = vpfe_cropcap,
+	.vidioc_g_crop		 = vpfe_g_crop,
+	.vidioc_s_crop		 = vpfe_s_crop,
+	.vidioc_default		 = vpfe_param_handler,
+};
+
+static struct vpfe_device *vpfe_initialize(void)
+{
+	struct vpfe_device *vpfe_dev;
+
+	/* Default number of buffers should be 3 */
+	if ((numbuffers > 0) &&
+	    (numbuffers < config_params.min_numbuffers))
+		numbuffers = config_params.min_numbuffers;
+
+	/*
+	 * Set buffer size to min buffers size if invalid buffer size is
+	 * given
+	 */
+	if (bufsize < config_params.min_bufsize)
+		bufsize = config_params.min_bufsize;
+
+	config_params.numbuffers = numbuffers;
+
+	if (numbuffers)
+		config_params.device_bufsize = bufsize;
+
+	/* Allocate memory for device objects */
+	vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
+
+	return vpfe_dev;
+}
+
+static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
+{
+	struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
+
+	clk_disable(vpfe_cfg->vpssclk);
+	clk_put(vpfe_cfg->vpssclk);
+	clk_disable(vpfe_cfg->slaveclk);
+	clk_put(vpfe_cfg->slaveclk);
+	v4l2_info(vpfe_dev->pdev->driver,
+		 "vpfe vpss master & slave clocks disabled\n");
+}
+
+static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
+{
+	struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
+	int ret = -ENOENT;
+
+	vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master");
+	if (NULL == vpfe_cfg->vpssclk) {
+		v4l2_err(vpfe_dev->pdev->driver, "No clock defined for"
+			 "vpss_master\n");
+		return ret;
+	}
+
+	if (clk_enable(vpfe_cfg->vpssclk)) {
+		v4l2_err(vpfe_dev->pdev->driver,
+			"vpfe vpss master clock not enabled\n");
+		goto out;
+	}
+	v4l2_info(vpfe_dev->pdev->driver,
+		 "vpfe vpss master clock enabled\n");
+
+	vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave");
+	if (NULL == vpfe_cfg->slaveclk) {
+		v4l2_err(vpfe_dev->pdev->driver,
+			"No clock defined for vpss slave\n");
+		goto out;
+	}
+
+	if (clk_enable(vpfe_cfg->slaveclk)) {
+		v4l2_err(vpfe_dev->pdev->driver,
+			 "vpfe vpss slave clock not enabled\n");
+		goto out;
+	}
+	v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n");
+	return 0;
+out:
+	if (vpfe_cfg->vpssclk)
+		clk_put(vpfe_cfg->vpssclk);
+	if (vpfe_cfg->slaveclk)
+		clk_put(vpfe_cfg->slaveclk);
+
+	return -1;
+}
+
+/*
+ * vpfe_probe : This function creates device entries by register
+ * itself to the V4L2 driver and initializes fields of each
+ * device objects
+ */
+static __init int vpfe_probe(struct platform_device *pdev)
+{
+	struct vpfe_subdev_info *sdinfo;
+	struct vpfe_config *vpfe_cfg;
+	struct resource *res1;
+	struct vpfe_device *vpfe_dev;
+	struct i2c_adapter *i2c_adap;
+	struct video_device *vfd;
+	int ret = -ENOMEM, i, j;
+	int num_subdevs = 0;
+
+	/* Get the pointer to the device object */
+	vpfe_dev = vpfe_initialize();
+
+	if (!vpfe_dev) {
+		v4l2_err(pdev->dev.driver,
+			"Failed to allocate memory for vpfe_dev\n");
+		return ret;
+	}
+
+	vpfe_dev->pdev = &pdev->dev;
+
+	if (NULL == pdev->dev.platform_data) {
+		v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
+		ret = -ENOENT;
+		goto probe_free_dev_mem;
+	}
+
+	vpfe_cfg = pdev->dev.platform_data;
+	vpfe_dev->cfg = vpfe_cfg;
+	if (NULL == vpfe_cfg->ccdc ||
+	    NULL == vpfe_cfg->card_name ||
+	    NULL == vpfe_cfg->sub_devs) {
+		v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
+		ret = -ENOENT;
+		goto probe_free_dev_mem;
+	}
+
+	/* enable vpss clocks */
+	ret = vpfe_enable_clock(vpfe_dev);
+	if (ret)
+		goto probe_free_dev_mem;
+
+	mutex_lock(&ccdc_lock);
+	/* Allocate memory for ccdc configuration */
+	ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
+	if (NULL == ccdc_cfg) {
+		v4l2_err(pdev->dev.driver,
+			 "Memory allocation failed for ccdc_cfg\n");
+		goto probe_disable_clock;
+	}
+
+	strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
+	/* Get VINT0 irq resource */
+	res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!res1) {
+		v4l2_err(pdev->dev.driver,
+			 "Unable to get interrupt for VINT0\n");
+		ret = -ENOENT;
+		goto probe_disable_clock;
+	}
+	vpfe_dev->ccdc_irq0 = res1->start;
+
+	/* Get VINT1 irq resource */
+	res1 = platform_get_resource(pdev,
+				IORESOURCE_IRQ, 1);
+	if (!res1) {
+		v4l2_err(pdev->dev.driver,
+			 "Unable to get interrupt for VINT1\n");
+		ret = -ENOENT;
+		goto probe_disable_clock;
+	}
+	vpfe_dev->ccdc_irq1 = res1->start;
+
+	/* Get address base of CCDC */
+	res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res1) {
+		v4l2_err(pdev->dev.driver,
+			"Unable to get register address map\n");
+		ret = -ENOENT;
+		goto probe_disable_clock;
+	}
+
+	ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1;
+	if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size,
+				pdev->dev.driver->name)) {
+		v4l2_err(pdev->dev.driver,
+			"Failed request_mem_region for ccdc base\n");
+		ret = -ENXIO;
+		goto probe_disable_clock;
+	}
+	ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start,
+					     ccdc_cfg->ccdc_addr_size);
+	if (!ccdc_cfg->ccdc_addr) {
+		v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n");
+		ret = -ENXIO;
+		goto probe_out_release_mem1;
+	}
+
+	ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
+			  "vpfe_capture0", vpfe_dev);
+
+	if (0 != ret) {
+		v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
+		goto probe_out_unmap1;
+	}
+
+	/* Allocate memory for video device */
+	vfd = video_device_alloc();
+	if (NULL == vfd) {
+		ret = -ENOMEM;
+		v4l2_err(pdev->dev.driver,
+			"Unable to alloc video device\n");
+		goto probe_out_release_irq;
+	}
+
+	/* Initialize field of video device */
+	vfd->release		= video_device_release;
+	vfd->fops		= &vpfe_fops;
+	vfd->ioctl_ops		= &vpfe_ioctl_ops;
+	vfd->minor		= -1;
+	vfd->tvnorms		= 0;
+	vfd->current_norm	= V4L2_STD_PAL;
+	vfd->v4l2_dev 		= &vpfe_dev->v4l2_dev;
+	snprintf(vfd->name, sizeof(vfd->name),
+		 "%s_V%d.%d.%d",
+		 CAPTURE_DRV_NAME,
+		 (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff,
+		 (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff,
+		 (VPFE_CAPTURE_VERSION_CODE) & 0xff);
+	/* Set video_dev to the video device */
+	vpfe_dev->video_dev	= vfd;
+
+	ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
+	if (ret) {
+		v4l2_err(pdev->dev.driver,
+			"Unable to register v4l2 device.\n");
+		goto probe_out_video_release;
+	}
+	v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
+	spin_lock_init(&vpfe_dev->irqlock);
+	spin_lock_init(&vpfe_dev->dma_queue_lock);
+	mutex_init(&vpfe_dev->lock);
+
+	/* Initialize field of the device objects */
+	vpfe_dev->numbuffers = config_params.numbuffers;
+
+	/* Initialize prio member of device object */
+	v4l2_prio_init(&vpfe_dev->prio);
+	/* register video device */
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+		"trying to register vpfe device.\n");
+	v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
+		"video_dev=%x\n", (int)&vpfe_dev->video_dev);
+	vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	ret = video_register_device(vpfe_dev->video_dev,
+				    VFL_TYPE_GRABBER, -1);
+
+	if (ret) {
+		v4l2_err(pdev->dev.driver,
+			"Unable to register video device.\n");
+		goto probe_out_v4l2_unregister;
+	}
+
+	v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n");
+	/* set the driver data in platform device */
+	platform_set_drvdata(pdev, vpfe_dev);
+	/* set driver private data */
+	video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
+	i2c_adap = i2c_get_adapter(1);
+	vpfe_cfg = pdev->dev.platform_data;
+	num_subdevs = vpfe_cfg->num_subdevs;
+	vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
+				GFP_KERNEL);
+	if (NULL == vpfe_dev->sd) {
+		v4l2_err(&vpfe_dev->v4l2_dev,
+			"unable to allocate memory for subdevice pointers\n");
+		ret = -ENOMEM;
+		goto probe_out_video_unregister;
+	}
+
+	for (i = 0; i < num_subdevs; i++) {
+		struct v4l2_input *inps;
+
+		sdinfo = &vpfe_cfg->sub_devs[i];
+
+		/* Load up the subdevice */
+		vpfe_dev->sd[i] =
+			v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
+						  i2c_adap,
+						  sdinfo->name,
+						  &sdinfo->board_info,
+						  NULL);
+		if (vpfe_dev->sd[i]) {
+			v4l2_info(&vpfe_dev->v4l2_dev,
+				  "v4l2 sub device %s registered\n",
+				  sdinfo->name);
+			vpfe_dev->sd[i]->grp_id = sdinfo->grp_id;
+			/* update tvnorms from the sub devices */
+			for (j = 0; j < sdinfo->num_inputs; j++) {
+				inps = &sdinfo->inputs[j];
+				vfd->tvnorms |= inps->std;
+			}
+		} else {
+			v4l2_info(&vpfe_dev->v4l2_dev,
+				  "v4l2 sub device %s register fails\n",
+				  sdinfo->name);
+			goto probe_sd_out;
+		}
+	}
+
+	/* set first sub device as current one */
+	vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
+
+	/* We have at least one sub device to work with */
+	mutex_unlock(&ccdc_lock);
+	return 0;
+
+probe_sd_out:
+	kfree(vpfe_dev->sd);
+probe_out_video_unregister:
+	video_unregister_device(vpfe_dev->video_dev);
+probe_out_v4l2_unregister:
+	v4l2_device_unregister(&vpfe_dev->v4l2_dev);
+probe_out_video_release:
+	if (vpfe_dev->video_dev->minor == -1)
+		video_device_release(vpfe_dev->video_dev);
+probe_out_release_irq:
+	free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
+probe_out_unmap1:
+	iounmap(ccdc_cfg->ccdc_addr);
+probe_out_release_mem1:
+	release_mem_region(res1->start, res1->end - res1->start + 1);
+probe_disable_clock:
+	vpfe_disable_clock(vpfe_dev);
+	mutex_unlock(&ccdc_lock);
+	kfree(ccdc_cfg);
+probe_free_dev_mem:
+	kfree(vpfe_dev);
+	return ret;
+}
+
+/*
+ * vpfe_remove : It un-register device from V4L2 driver
+ */
+static int vpfe_remove(struct platform_device *pdev)
+{
+	struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
+	struct resource *res;
+
+	v4l2_info(pdev->dev.driver, "vpfe_remove\n");
+
+	free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
+	kfree(vpfe_dev->sd);
+	v4l2_device_unregister(&vpfe_dev->v4l2_dev);
+	video_unregister_device(vpfe_dev->video_dev);
+	mutex_lock(&ccdc_lock);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, res->end - res->start + 1);
+	iounmap(ccdc_cfg->ccdc_addr);
+	mutex_unlock(&ccdc_lock);
+	vpfe_disable_clock(vpfe_dev);
+	kfree(vpfe_dev);
+	kfree(ccdc_cfg);
+	return 0;
+}
+
+static int
+vpfe_suspend(struct device *dev)
+{
+	/* add suspend code here later */
+	return -1;
+}
+
+static int
+vpfe_resume(struct device *dev)
+{
+	/* add resume code here later */
+	return -1;
+}
+
+static struct dev_pm_ops vpfe_dev_pm_ops = {
+	.suspend = vpfe_suspend,
+	.resume = vpfe_resume,
+};
+
+static struct platform_driver vpfe_driver = {
+	.driver = {
+		.name = CAPTURE_DRV_NAME,
+		.owner = THIS_MODULE,
+		.pm = &vpfe_dev_pm_ops,
+	},
+	.probe = vpfe_probe,
+	.remove = __devexit_p(vpfe_remove),
+};
+
+static __init int vpfe_init(void)
+{
+	printk(KERN_NOTICE "vpfe_init\n");
+	/* Register driver to the kernel */
+	return platform_driver_register(&vpfe_driver);
+}
+
+/*
+ * vpfe_cleanup : This function un-registers device driver
+ */
+static void vpfe_cleanup(void)
+{
+	platform_driver_unregister(&vpfe_driver);
+}
+
+module_init(vpfe_init);
+module_exit(vpfe_cleanup);
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c
new file mode 100644
index 0000000..3b8eac3
--- /dev/null
+++ b/drivers/media/video/davinci/vpif.c
@@ -0,0 +1,296 @@
+/*
+ * vpif - DM646x Video Port Interface driver
+ * VPIF is a receiver and transmitter for video data. It has two channels(0, 1)
+ * that receiveing video byte stream and two channels(2, 3) for video output.
+ * The hardware supports SDTV, HDTV formats, raw data capture.
+ * Currently, the driver supports NTSC and PAL standards.
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+#include "vpif.h"
+
+MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
+MODULE_LICENSE("GPL");
+
+#define VPIF_CH0_MAX_MODES	(22)
+#define VPIF_CH1_MAX_MODES	(02)
+#define VPIF_CH2_MAX_MODES	(15)
+#define VPIF_CH3_MAX_MODES	(02)
+
+static resource_size_t	res_len;
+static struct resource	*res;
+spinlock_t vpif_lock;
+
+void __iomem *vpif_base;
+
+static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
+{
+	if (val)
+		vpif_set_bit(reg, bit);
+	else
+		vpif_clr_bit(reg, bit);
+}
+
+/* This structure is used to keep track of VPIF size register's offsets */
+struct vpif_registers {
+	u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl;
+	u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt;
+	u32 vanc1_size, width_mask, len_mask;
+	u8 max_modes;
+};
+
+static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = {
+	/* Channel0 */
+	{
+		VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01,
+		VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL,
+		VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
+		VPIF_CH0_MAX_MODES,
+	},
+	/* Channel1 */
+	{
+		VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01,
+		VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL,
+		VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
+		VPIF_CH1_MAX_MODES,
+	},
+	/* Channel2 */
+	{
+		VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01,
+		VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL,
+		VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE,
+		VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF,
+		VPIF_CH2_MAX_MODES
+	},
+	/* Channel3 */
+	{
+		VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01,
+		VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL,
+		VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE,
+		VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF,
+		VPIF_CH3_MAX_MODES
+	},
+};
+
+/* vpif_set_mode_info:
+ * This function is used to set horizontal and vertical config parameters
+ * As per the standard in the channel, configure the values of L1, L3,
+ * L5, L7  L9, L11 in VPIF Register , also write width and height
+ */
+static void vpif_set_mode_info(const struct vpif_channel_config_params *config,
+				u8 channel_id, u8 config_channel_id)
+{
+	u32 value;
+
+	value = (config->eav2sav & vpifregs[config_channel_id].width_mask);
+	value <<= VPIF_CH_LEN_SHIFT;
+	value |= (config->sav2eav & vpifregs[config_channel_id].width_mask);
+	regw(value, vpifregs[channel_id].h_cfg);
+
+	value = (config->l1 & vpifregs[config_channel_id].len_mask);
+	value <<= VPIF_CH_LEN_SHIFT;
+	value |= (config->l3 & vpifregs[config_channel_id].len_mask);
+	regw(value, vpifregs[channel_id].v_cfg_00);
+
+	value = (config->l5 & vpifregs[config_channel_id].len_mask);
+	value <<= VPIF_CH_LEN_SHIFT;
+	value |= (config->l7 & vpifregs[config_channel_id].len_mask);
+	regw(value, vpifregs[channel_id].v_cfg_01);
+
+	value = (config->l9 & vpifregs[config_channel_id].len_mask);
+	value <<= VPIF_CH_LEN_SHIFT;
+	value |= (config->l11 & vpifregs[config_channel_id].len_mask);
+	regw(value, vpifregs[channel_id].v_cfg_02);
+
+	value = (config->vsize & vpifregs[config_channel_id].len_mask);
+	regw(value, vpifregs[channel_id].v_cfg);
+}
+
+/* config_vpif_params
+ * Function to set the parameters of a channel
+ * Mainly modifies the channel ciontrol register
+ * It sets frame format, yc mux mode
+ */
+static void config_vpif_params(struct vpif_params *vpifparams,
+				u8 channel_id, u8 found)
+{
+	const struct vpif_channel_config_params *config = &vpifparams->std_info;
+	u32 value, ch_nip, reg;
+	u8 start, end;
+	int i;
+
+	start = channel_id;
+	end = channel_id + found;
+
+	for (i = start; i < end; i++) {
+		reg = vpifregs[i].ch_ctrl;
+		if (channel_id < 2)
+			ch_nip = VPIF_CAPTURE_CH_NIP;
+		else
+			ch_nip = VPIF_DISPLAY_CH_NIP;
+
+		vpif_wr_bit(reg, ch_nip, config->frm_fmt);
+		vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode);
+		vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT,
+					vpifparams->video_params.storage_mode);
+
+		/* Set raster scanning SDR Format */
+		vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT);
+		vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format);
+
+		if (channel_id > 1)	/* Set the Pixel enable bit */
+			vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT);
+		else if (config->capture_format) {
+			/* Set the polarity of various pins */
+			vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
+					vpifparams->iface.fid_pol);
+			vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
+					vpifparams->iface.vd_pol);
+			vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
+					vpifparams->iface.hd_pol);
+
+			value = regr(reg);
+			/* Set data width */
+			value &= ((~(unsigned int)(0x3)) <<
+					VPIF_CH_DATA_WIDTH_BIT);
+			value |= ((vpifparams->params.data_sz) <<
+						     VPIF_CH_DATA_WIDTH_BIT);
+			regw(value, reg);
+		}
+
+		/* Write the pitch in the driver */
+		regw((vpifparams->video_params.hpitch),
+						vpifregs[i].line_offset);
+	}
+}
+
+/* vpif_set_video_params
+ * This function is used to set video parameters in VPIF register
+ */
+int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id)
+{
+	const struct vpif_channel_config_params *config = &vpifparams->std_info;
+	int found = 1;
+
+	vpif_set_mode_info(config, channel_id, channel_id);
+	if (!config->ycmux_mode) {
+		/* YC are on separate channels (HDTV formats) */
+		vpif_set_mode_info(config, channel_id + 1, channel_id);
+		found = 2;
+	}
+
+	config_vpif_params(vpifparams, channel_id, found);
+
+	regw(0x80, VPIF_REQ_SIZE);
+	regw(0x01, VPIF_EMULATION_CTRL);
+
+	return found;
+}
+EXPORT_SYMBOL(vpif_set_video_params);
+
+void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
+				u8 channel_id)
+{
+	u32 value;
+
+	value = 0x3F8 & (vbiparams->hstart0);
+	value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16);
+	regw(value, vpifregs[channel_id].vanc0_strt);
+
+	value = 0x3F8 & (vbiparams->hstart1);
+	value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16);
+	regw(value, vpifregs[channel_id].vanc1_strt);
+
+	value = 0x3F8 & (vbiparams->hsize0);
+	value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16);
+	regw(value, vpifregs[channel_id].vanc0_size);
+
+	value = 0x3F8 & (vbiparams->hsize1);
+	value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16);
+	regw(value, vpifregs[channel_id].vanc1_size);
+
+}
+EXPORT_SYMBOL(vpif_set_vbi_display_params);
+
+int vpif_channel_getfid(u8 channel_id)
+{
+	return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK)
+					>> VPIF_CH_FID_SHIFT;
+}
+EXPORT_SYMBOL(vpif_channel_getfid);
+
+static int __init vpif_probe(struct platform_device *pdev)
+{
+	int status = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENOENT;
+
+	res_len = res->end - res->start + 1;
+
+	res = request_mem_region(res->start, res_len, res->name);
+	if (!res)
+		return -EBUSY;
+
+	vpif_base = ioremap(res->start, res_len);
+	if (!vpif_base) {
+		status = -EBUSY;
+		goto fail;
+	}
+
+	spin_lock_init(&vpif_lock);
+	dev_info(&pdev->dev, "vpif probe success\n");
+	return 0;
+
+fail:
+	release_mem_region(res->start, res_len);
+	return status;
+}
+
+static int vpif_remove(struct platform_device *pdev)
+{
+	iounmap(vpif_base);
+	release_mem_region(res->start, res_len);
+	return 0;
+}
+
+static struct platform_driver vpif_driver = {
+	.driver = {
+		.name	= "vpif",
+		.owner = THIS_MODULE,
+	},
+	.remove = __devexit_p(vpif_remove),
+	.probe = vpif_probe,
+};
+
+static void vpif_exit(void)
+{
+	platform_driver_unregister(&vpif_driver);
+}
+
+static int __init vpif_init(void)
+{
+	return platform_driver_register(&vpif_driver);
+}
+subsys_initcall(vpif_init);
+module_exit(vpif_exit);
+
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h
new file mode 100644
index 0000000..188841b
--- /dev/null
+++ b/drivers/media/video/davinci/vpif.h
@@ -0,0 +1,642 @@
+/*
+ * VPIF header file
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef VPIF_H
+#define VPIF_H
+
+#include <linux/io.h>
+#include <linux/videodev2.h>
+#include <mach/hardware.h>
+#include <mach/dm646x.h>
+
+/* Maximum channel allowed */
+#define VPIF_NUM_CHANNELS		(4)
+#define VPIF_CAPTURE_NUM_CHANNELS	(2)
+#define VPIF_DISPLAY_NUM_CHANNELS	(2)
+
+/* Macros to read/write registers */
+extern void __iomem *vpif_base;
+extern spinlock_t vpif_lock;
+
+#define regr(reg)               readl((reg) + vpif_base)
+#define regw(value, reg)        writel(value, (reg + vpif_base))
+
+/* Register Addresss Offsets */
+#define VPIF_PID			(0x0000)
+#define VPIF_CH0_CTRL			(0x0004)
+#define VPIF_CH1_CTRL			(0x0008)
+#define VPIF_CH2_CTRL			(0x000C)
+#define VPIF_CH3_CTRL			(0x0010)
+
+#define VPIF_INTEN			(0x0020)
+#define VPIF_INTEN_SET			(0x0024)
+#define VPIF_INTEN_CLR			(0x0028)
+#define VPIF_STATUS			(0x002C)
+#define VPIF_STATUS_CLR			(0x0030)
+#define VPIF_EMULATION_CTRL		(0x0034)
+#define VPIF_REQ_SIZE			(0x0038)
+
+#define VPIF_CH0_TOP_STRT_ADD_LUMA	(0x0040)
+#define VPIF_CH0_BTM_STRT_ADD_LUMA	(0x0044)
+#define VPIF_CH0_TOP_STRT_ADD_CHROMA	(0x0048)
+#define VPIF_CH0_BTM_STRT_ADD_CHROMA	(0x004c)
+#define VPIF_CH0_TOP_STRT_ADD_HANC	(0x0050)
+#define VPIF_CH0_BTM_STRT_ADD_HANC	(0x0054)
+#define VPIF_CH0_TOP_STRT_ADD_VANC	(0x0058)
+#define VPIF_CH0_BTM_STRT_ADD_VANC	(0x005c)
+#define VPIF_CH0_SP_CFG			(0x0060)
+#define VPIF_CH0_IMG_ADD_OFST		(0x0064)
+#define VPIF_CH0_HANC_ADD_OFST		(0x0068)
+#define VPIF_CH0_H_CFG			(0x006c)
+#define VPIF_CH0_V_CFG_00		(0x0070)
+#define VPIF_CH0_V_CFG_01		(0x0074)
+#define VPIF_CH0_V_CFG_02		(0x0078)
+#define VPIF_CH0_V_CFG_03		(0x007c)
+
+#define VPIF_CH1_TOP_STRT_ADD_LUMA	(0x0080)
+#define VPIF_CH1_BTM_STRT_ADD_LUMA	(0x0084)
+#define VPIF_CH1_TOP_STRT_ADD_CHROMA	(0x0088)
+#define VPIF_CH1_BTM_STRT_ADD_CHROMA	(0x008c)
+#define VPIF_CH1_TOP_STRT_ADD_HANC	(0x0090)
+#define VPIF_CH1_BTM_STRT_ADD_HANC	(0x0094)
+#define VPIF_CH1_TOP_STRT_ADD_VANC	(0x0098)
+#define VPIF_CH1_BTM_STRT_ADD_VANC	(0x009c)
+#define VPIF_CH1_SP_CFG			(0x00a0)
+#define VPIF_CH1_IMG_ADD_OFST		(0x00a4)
+#define VPIF_CH1_HANC_ADD_OFST		(0x00a8)
+#define VPIF_CH1_H_CFG			(0x00ac)
+#define VPIF_CH1_V_CFG_00		(0x00b0)
+#define VPIF_CH1_V_CFG_01		(0x00b4)
+#define VPIF_CH1_V_CFG_02		(0x00b8)
+#define VPIF_CH1_V_CFG_03		(0x00bc)
+
+#define VPIF_CH2_TOP_STRT_ADD_LUMA	(0x00c0)
+#define VPIF_CH2_BTM_STRT_ADD_LUMA	(0x00c4)
+#define VPIF_CH2_TOP_STRT_ADD_CHROMA	(0x00c8)
+#define VPIF_CH2_BTM_STRT_ADD_CHROMA	(0x00cc)
+#define VPIF_CH2_TOP_STRT_ADD_HANC	(0x00d0)
+#define VPIF_CH2_BTM_STRT_ADD_HANC	(0x00d4)
+#define VPIF_CH2_TOP_STRT_ADD_VANC	(0x00d8)
+#define VPIF_CH2_BTM_STRT_ADD_VANC	(0x00dc)
+#define VPIF_CH2_SP_CFG			(0x00e0)
+#define VPIF_CH2_IMG_ADD_OFST		(0x00e4)
+#define VPIF_CH2_HANC_ADD_OFST		(0x00e8)
+#define VPIF_CH2_H_CFG			(0x00ec)
+#define VPIF_CH2_V_CFG_00		(0x00f0)
+#define VPIF_CH2_V_CFG_01		(0x00f4)
+#define VPIF_CH2_V_CFG_02		(0x00f8)
+#define VPIF_CH2_V_CFG_03		(0x00fc)
+#define VPIF_CH2_HANC0_STRT		(0x0100)
+#define VPIF_CH2_HANC0_SIZE		(0x0104)
+#define VPIF_CH2_HANC1_STRT		(0x0108)
+#define VPIF_CH2_HANC1_SIZE		(0x010c)
+#define VPIF_CH2_VANC0_STRT		(0x0110)
+#define VPIF_CH2_VANC0_SIZE		(0x0114)
+#define VPIF_CH2_VANC1_STRT		(0x0118)
+#define VPIF_CH2_VANC1_SIZE		(0x011c)
+
+#define VPIF_CH3_TOP_STRT_ADD_LUMA	(0x0140)
+#define VPIF_CH3_BTM_STRT_ADD_LUMA	(0x0144)
+#define VPIF_CH3_TOP_STRT_ADD_CHROMA	(0x0148)
+#define VPIF_CH3_BTM_STRT_ADD_CHROMA	(0x014c)
+#define VPIF_CH3_TOP_STRT_ADD_HANC	(0x0150)
+#define VPIF_CH3_BTM_STRT_ADD_HANC	(0x0154)
+#define VPIF_CH3_TOP_STRT_ADD_VANC	(0x0158)
+#define VPIF_CH3_BTM_STRT_ADD_VANC	(0x015c)
+#define VPIF_CH3_SP_CFG			(0x0160)
+#define VPIF_CH3_IMG_ADD_OFST		(0x0164)
+#define VPIF_CH3_HANC_ADD_OFST		(0x0168)
+#define VPIF_CH3_H_CFG			(0x016c)
+#define VPIF_CH3_V_CFG_00		(0x0170)
+#define VPIF_CH3_V_CFG_01		(0x0174)
+#define VPIF_CH3_V_CFG_02		(0x0178)
+#define VPIF_CH3_V_CFG_03		(0x017c)
+#define VPIF_CH3_HANC0_STRT		(0x0180)
+#define VPIF_CH3_HANC0_SIZE		(0x0184)
+#define VPIF_CH3_HANC1_STRT		(0x0188)
+#define VPIF_CH3_HANC1_SIZE		(0x018c)
+#define VPIF_CH3_VANC0_STRT		(0x0190)
+#define VPIF_CH3_VANC0_SIZE		(0x0194)
+#define VPIF_CH3_VANC1_STRT		(0x0198)
+#define VPIF_CH3_VANC1_SIZE		(0x019c)
+
+#define VPIF_IODFT_CTRL			(0x01c0)
+
+/* Functions for bit Manipulation */
+static inline void vpif_set_bit(u32 reg, u32 bit)
+{
+	regw((regr(reg)) | (0x01 << bit), reg);
+}
+
+static inline void vpif_clr_bit(u32 reg, u32 bit)
+{
+	regw(((regr(reg)) & ~(0x01 << bit)), reg);
+}
+
+/* Macro for Generating mask */
+#ifdef GENERATE_MASK
+#undef GENERATE_MASK
+#endif
+
+#define GENERATE_MASK(bits, pos) \
+		((((0xFFFFFFFF) << (32 - bits)) >> (32 - bits)) << pos)
+
+/* Bit positions in the channel control registers */
+#define VPIF_CH_DATA_MODE_BIT	(2)
+#define VPIF_CH_YC_MUX_BIT	(3)
+#define VPIF_CH_SDR_FMT_BIT	(4)
+#define VPIF_CH_HANC_EN_BIT	(8)
+#define VPIF_CH_VANC_EN_BIT	(9)
+
+#define VPIF_CAPTURE_CH_NIP	(10)
+#define VPIF_DISPLAY_CH_NIP	(11)
+
+#define VPIF_DISPLAY_PIX_EN_BIT	(10)
+
+#define VPIF_CH_INPUT_FIELD_FRAME_BIT	(12)
+
+#define VPIF_CH_FID_POLARITY_BIT	(15)
+#define VPIF_CH_V_VALID_POLARITY_BIT	(14)
+#define VPIF_CH_H_VALID_POLARITY_BIT	(13)
+#define VPIF_CH_DATA_WIDTH_BIT		(28)
+
+#define VPIF_CH_CLK_EDGE_CTRL_BIT	(31)
+
+/* Mask various length */
+#define VPIF_CH_EAVSAV_MASK	GENERATE_MASK(13, 0)
+#define VPIF_CH_LEN_MASK	GENERATE_MASK(12, 0)
+#define VPIF_CH_WIDTH_MASK	GENERATE_MASK(13, 0)
+#define VPIF_CH_LEN_SHIFT	(16)
+
+/* VPIF masks for registers */
+#define VPIF_REQ_SIZE_MASK	(0x1ff)
+
+/* bit posotion of interrupt vpif_ch_intr register */
+#define VPIF_INTEN_FRAME_CH0	(0x00000001)
+#define VPIF_INTEN_FRAME_CH1	(0x00000002)
+#define VPIF_INTEN_FRAME_CH2	(0x00000004)
+#define VPIF_INTEN_FRAME_CH3	(0x00000008)
+
+/* bit position of clock and channel enable in vpif_chn_ctrl register */
+
+#define VPIF_CH0_CLK_EN		(0x00000002)
+#define VPIF_CH0_EN		(0x00000001)
+#define VPIF_CH1_CLK_EN		(0x00000002)
+#define VPIF_CH1_EN		(0x00000001)
+#define VPIF_CH2_CLK_EN		(0x00000002)
+#define VPIF_CH2_EN		(0x00000001)
+#define VPIF_CH3_CLK_EN		(0x00000002)
+#define VPIF_CH3_EN		(0x00000001)
+#define VPIF_CH_CLK_EN		(0x00000002)
+#define VPIF_CH_EN		(0x00000001)
+
+#define VPIF_INT_TOP	(0x00)
+#define VPIF_INT_BOTTOM	(0x01)
+#define VPIF_INT_BOTH	(0x02)
+
+#define VPIF_CH0_INT_CTRL_SHIFT	(6)
+#define VPIF_CH1_INT_CTRL_SHIFT	(6)
+#define VPIF_CH2_INT_CTRL_SHIFT	(6)
+#define VPIF_CH3_INT_CTRL_SHIFT	(6)
+#define VPIF_CH_INT_CTRL_SHIFT	(6)
+
+/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
+#define channel0_intr_assert()	(regw((regr(VPIF_CH0_CTRL)|\
+	(VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL))
+
+/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
+#define channel1_intr_assert()	(regw((regr(VPIF_CH1_CTRL)|\
+	(VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
+
+/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
+#define channel2_intr_assert() 	(regw((regr(VPIF_CH2_CTRL)|\
+	(VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
+
+/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
+#define channel3_intr_assert() 	(regw((regr(VPIF_CH3_CTRL)|\
+	(VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
+
+#define VPIF_CH_FID_MASK	(0x20)
+#define VPIF_CH_FID_SHIFT	(5)
+
+#define VPIF_NTSC_VBI_START_FIELD0	(1)
+#define VPIF_NTSC_VBI_START_FIELD1	(263)
+#define VPIF_PAL_VBI_START_FIELD0	(624)
+#define VPIF_PAL_VBI_START_FIELD1	(311)
+
+#define VPIF_NTSC_HBI_START_FIELD0	(1)
+#define VPIF_NTSC_HBI_START_FIELD1	(263)
+#define VPIF_PAL_HBI_START_FIELD0	(624)
+#define VPIF_PAL_HBI_START_FIELD1	(311)
+
+#define VPIF_NTSC_VBI_COUNT_FIELD0	(20)
+#define VPIF_NTSC_VBI_COUNT_FIELD1	(19)
+#define VPIF_PAL_VBI_COUNT_FIELD0	(24)
+#define VPIF_PAL_VBI_COUNT_FIELD1	(25)
+
+#define VPIF_NTSC_HBI_COUNT_FIELD0	(263)
+#define VPIF_NTSC_HBI_COUNT_FIELD1	(262)
+#define VPIF_PAL_HBI_COUNT_FIELD0	(312)
+#define VPIF_PAL_HBI_COUNT_FIELD1	(313)
+
+#define VPIF_NTSC_VBI_SAMPLES_PER_LINE	(720)
+#define VPIF_PAL_VBI_SAMPLES_PER_LINE	(720)
+#define VPIF_NTSC_HBI_SAMPLES_PER_LINE	(268)
+#define VPIF_PAL_HBI_SAMPLES_PER_LINE	(280)
+
+#define VPIF_CH_VANC_EN			(0x20)
+#define VPIF_DMA_REQ_SIZE		(0x080)
+#define VPIF_EMULATION_DISABLE		(0x01)
+
+extern u8 irq_vpif_capture_channel[VPIF_NUM_CHANNELS];
+
+/* inline function to enable/disable channel0 */
+static inline void enable_channel0(int enable)
+{
+	if (enable)
+		regw((regr(VPIF_CH0_CTRL) | (VPIF_CH0_EN)), VPIF_CH0_CTRL);
+	else
+		regw((regr(VPIF_CH0_CTRL) & (~VPIF_CH0_EN)), VPIF_CH0_CTRL);
+}
+
+/* inline function to enable/disable channel1 */
+static inline void enable_channel1(int enable)
+{
+	if (enable)
+		regw((regr(VPIF_CH1_CTRL) | (VPIF_CH1_EN)), VPIF_CH1_CTRL);
+	else
+		regw((regr(VPIF_CH1_CTRL) & (~VPIF_CH1_EN)), VPIF_CH1_CTRL);
+}
+
+/* inline function to enable interrupt for channel0 */
+static inline void channel0_intr_enable(int enable)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&vpif_lock, flags);
+
+	if (enable) {
+		regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+
+		regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
+							VPIF_INTEN_SET);
+	} else {
+		regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH0)), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
+							VPIF_INTEN_SET);
+	}
+	spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to enable interrupt for channel1 */
+static inline void channel1_intr_enable(int enable)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&vpif_lock, flags);
+
+	if (enable) {
+		regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+
+		regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
+							VPIF_INTEN_SET);
+	} else {
+		regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH1)), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
+							VPIF_INTEN_SET);
+	}
+	spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to set buffer addresses in case of Y/C non mux mode */
+static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
+						 unsigned long btm_strt_luma,
+						 unsigned long top_strt_chroma,
+						 unsigned long btm_strt_chroma)
+{
+	regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
+	regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
+	regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
+	regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
+}
+
+/* inline function to set buffer addresses in VPIF registers for video data */
+static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
+					 unsigned long btm_strt_luma,
+					 unsigned long top_strt_chroma,
+					 unsigned long btm_strt_chroma)
+{
+	regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
+	regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
+	regw(top_strt_chroma, VPIF_CH0_TOP_STRT_ADD_CHROMA);
+	regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
+}
+
+static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
+					 unsigned long btm_strt_luma,
+					 unsigned long top_strt_chroma,
+					 unsigned long btm_strt_chroma)
+{
+
+	regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
+	regw(btm_strt_luma, VPIF_CH1_BTM_STRT_ADD_LUMA);
+	regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
+	regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
+}
+
+static inline void ch0_set_vbi_addr(unsigned long top_vbi,
+	unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+	regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_VANC);
+	regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_VANC);
+}
+
+static inline void ch0_set_hbi_addr(unsigned long top_vbi,
+	unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+	regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_HANC);
+	regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_HANC);
+}
+
+static inline void ch1_set_vbi_addr(unsigned long top_vbi,
+	unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+	regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_VANC);
+	regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_VANC);
+}
+
+static inline void ch1_set_hbi_addr(unsigned long top_vbi,
+	unsigned long btm_vbi, unsigned long a, unsigned long b)
+{
+	regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_HANC);
+	regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_HANC);
+}
+
+/* Inline function to enable raw vbi in the given channel */
+static inline void disable_raw_feature(u8 channel_id, u8 index)
+{
+	u32 ctrl_reg;
+	if (0 == channel_id)
+		ctrl_reg = VPIF_CH0_CTRL;
+	else
+		ctrl_reg = VPIF_CH1_CTRL;
+
+	if (1 == index)
+		vpif_clr_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
+	else
+		vpif_clr_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
+}
+
+static inline void enable_raw_feature(u8 channel_id, u8 index)
+{
+	u32 ctrl_reg;
+	if (0 == channel_id)
+		ctrl_reg = VPIF_CH0_CTRL;
+	else
+		ctrl_reg = VPIF_CH1_CTRL;
+
+	if (1 == index)
+		vpif_set_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
+	else
+		vpif_set_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
+}
+
+/* inline function to enable/disable channel2 */
+static inline void enable_channel2(int enable)
+{
+	if (enable) {
+		regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
+		regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_EN)), VPIF_CH2_CTRL);
+	} else {
+		regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
+		regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_EN)), VPIF_CH2_CTRL);
+	}
+}
+
+/* inline function to enable/disable channel3 */
+static inline void enable_channel3(int enable)
+{
+	if (enable) {
+		regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
+		regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_EN)), VPIF_CH3_CTRL);
+	} else {
+		regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
+		regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_EN)), VPIF_CH3_CTRL);
+	}
+}
+
+/* inline function to enable interrupt for channel2 */
+static inline void channel2_intr_enable(int enable)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&vpif_lock, flags);
+
+	if (enable) {
+		regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+		regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
+							VPIF_INTEN_SET);
+	} else {
+		regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH2)), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
+							VPIF_INTEN_SET);
+	}
+	spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to enable interrupt for channel3 */
+static inline void channel3_intr_enable(int enable)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&vpif_lock, flags);
+
+	if (enable) {
+		regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
+
+		regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
+							VPIF_INTEN_SET);
+	} else {
+		regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH3)), VPIF_INTEN);
+		regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
+							VPIF_INTEN_SET);
+	}
+	spin_unlock_irqrestore(&vpif_lock, flags);
+}
+
+/* inline function to enable raw vbi data for channel2 */
+static inline void channel2_raw_enable(int enable, u8 index)
+{
+	u32 mask;
+
+	if (1 == index)
+		mask = VPIF_CH_VANC_EN_BIT;
+	else
+		mask = VPIF_CH_HANC_EN_BIT;
+
+	if (enable)
+		vpif_set_bit(VPIF_CH2_CTRL, mask);
+	else
+		vpif_clr_bit(VPIF_CH2_CTRL, mask);
+}
+
+/* inline function to enable raw vbi data for channel3*/
+static inline void channel3_raw_enable(int enable, u8 index)
+{
+	u32 mask;
+
+	if (1 == index)
+		mask = VPIF_CH_VANC_EN_BIT;
+	else
+		mask = VPIF_CH_HANC_EN_BIT;
+
+	if (enable)
+		vpif_set_bit(VPIF_CH3_CTRL, mask);
+	else
+		vpif_clr_bit(VPIF_CH3_CTRL, mask);
+}
+
+/* inline function to set buffer addresses in case of Y/C non mux mode */
+static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
+						 unsigned long btm_strt_luma,
+						 unsigned long top_strt_chroma,
+						 unsigned long btm_strt_chroma)
+{
+	regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
+	regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
+	regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
+	regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
+}
+
+/* inline function to set buffer addresses in VPIF registers for video data */
+static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
+					 unsigned long btm_strt_luma,
+					 unsigned long top_strt_chroma,
+					 unsigned long btm_strt_chroma)
+{
+	regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
+	regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
+	regw(top_strt_chroma, VPIF_CH2_TOP_STRT_ADD_CHROMA);
+	regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
+}
+
+static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
+					 unsigned long btm_strt_luma,
+					 unsigned long top_strt_chroma,
+					 unsigned long btm_strt_chroma)
+{
+	regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
+	regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
+	regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
+	regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
+}
+
+/* inline function to set buffer addresses in VPIF registers for vbi data */
+static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
+					 unsigned long btm_strt_luma,
+					 unsigned long top_strt_chroma,
+					 unsigned long btm_strt_chroma)
+{
+	regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
+	regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
+}
+
+static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
+					 unsigned long btm_strt_luma,
+					 unsigned long top_strt_chroma,
+					 unsigned long btm_strt_chroma)
+{
+	regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
+	regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
+}
+
+#define VPIF_MAX_NAME	(30)
+
+/* This structure will store size parameters as per the mode selected by user */
+struct vpif_channel_config_params {
+	char name[VPIF_MAX_NAME];	/* Name of the mode */
+	u16 width;			/* Indicates width of the image */
+	u16 height;			/* Indicates height of the image */
+	u8 fps;
+	u8 frm_fmt;			/* Indicates whether this is interlaced
+					 * or progressive format */
+	u8 ycmux_mode;			/* Indicates whether this mode requires
+					 * single or two channels */
+	u16 eav2sav;			/* length of sav 2 eav */
+	u16 sav2eav;			/* length of sav 2 eav */
+	u16 l1, l3, l5, l7, l9, l11;	/* Other parameter configurations */
+	u16 vsize;			/* Vertical size of the image */
+	u8 capture_format;		/* Indicates whether capture format
+					 * is in BT or in CCD/CMOS */
+	u8  vbi_supported;		/* Indicates whether this mode
+					 * supports capturing vbi or not */
+	u8 hd_sd;
+	v4l2_std_id stdid;
+};
+
+struct vpif_video_params;
+struct vpif_params;
+struct vpif_vbi_params;
+
+int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
+void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
+							u8 channel_id);
+int vpif_channel_getfid(u8 channel_id);
+
+enum data_size {
+	_8BITS = 0,
+	_10BITS,
+	_12BITS,
+};
+
+/* Structure for vpif parameters for raw vbi data */
+struct vpif_vbi_params {
+	__u32 hstart0;  /* Horizontal start of raw vbi data for first field */
+	__u32 vstart0;  /* Vertical start of raw vbi data for first field */
+	__u32 hsize0;   /* Horizontal size of raw vbi data for first field */
+	__u32 vsize0;   /* Vertical size of raw vbi data for first field */
+	__u32 hstart1;  /* Horizontal start of raw vbi data for second field */
+	__u32 vstart1;  /* Vertical start of raw vbi data for second field */
+	__u32 hsize1;   /* Horizontal size of raw vbi data for second field */
+	__u32 vsize1;   /* Vertical size of raw vbi data for second field */
+};
+
+/* structure for vpif parameters */
+struct vpif_video_params {
+	__u8 storage_mode;	/* Indicates field or frame mode */
+	unsigned long hpitch;
+	v4l2_std_id stdid;
+};
+
+struct vpif_params {
+	struct vpif_interface iface;
+	struct vpif_video_params video_params;
+	struct vpif_channel_config_params std_info;
+	union param {
+		struct vpif_vbi_params	vbi_params;
+		enum data_size data_sz;
+	} params;
+};
+
+#endif				/* End of #ifndef VPIF_H */
+
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
new file mode 100644
index 0000000..d947ee5
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -0,0 +1,2168 @@
+/*
+ * Copyright (C) 2009 Texas Instruments 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
+ *
+ * TODO : add support for VBI & HBI data service
+ *	  add static buffer allocation
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/videodev2.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/version.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+#include "vpif_capture.h"
+#include "vpif.h"
+
+MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
+MODULE_LICENSE("GPL");
+
+#define vpif_err(fmt, arg...)	v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
+#define vpif_dbg(level, debug, fmt, arg...)	\
+		v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
+
+static int debug = 1;
+static u32 ch0_numbuffers = 3;
+static u32 ch1_numbuffers = 3;
+static u32 ch0_bufsize = 1920 * 1080 * 2;
+static u32 ch1_bufsize = 720 * 576 * 2;
+
+module_param(debug, int, 0644);
+module_param(ch0_numbuffers, uint, S_IRUGO);
+module_param(ch1_numbuffers, uint, S_IRUGO);
+module_param(ch0_bufsize, uint, S_IRUGO);
+module_param(ch1_bufsize, uint, S_IRUGO);
+
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
+MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
+MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
+MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
+
+static struct vpif_config_params config_params = {
+	.min_numbuffers = 3,
+	.numbuffers[0] = 3,
+	.numbuffers[1] = 3,
+	.min_bufsize[0] = 720 * 480 * 2,
+	.min_bufsize[1] = 720 * 480 * 2,
+	.channel_bufsize[0] = 1920 * 1080 * 2,
+	.channel_bufsize[1] = 720 * 576 * 2,
+};
+
+/* global variables */
+static struct vpif_device vpif_obj = { {NULL} };
+static struct device *vpif_dev;
+
+/**
+ * ch_params: video standard configuration parameters for vpif
+ */
+static const struct vpif_channel_config_params ch_params[] = {
+	{
+		"NTSC_M", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
+		286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
+	},
+	{
+		"PAL_BDGHIK", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
+		336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
+	},
+};
+
+/**
+ * vpif_uservirt_to_phys : translate user/virtual address to phy address
+ * @virtp: user/virtual address
+ *
+ * This inline function is used to convert user space virtual address to
+ * physical address.
+ */
+static inline u32 vpif_uservirt_to_phys(u32 virtp)
+{
+	unsigned long physp = 0;
+	struct mm_struct *mm = current->mm;
+	struct vm_area_struct *vma;
+
+	vma = find_vma(mm, virtp);
+
+	/* For kernel direct-mapped memory, take the easy way */
+	if (virtp >= PAGE_OFFSET)
+		physp = virt_to_phys((void *)virtp);
+	else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff))
+		/**
+		 * this will catch, kernel-allocated, mmaped-to-usermode
+		 * addresses
+		 */
+		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
+	else {
+		/* otherwise, use get_user_pages() for general userland pages */
+		int res, nr_pages = 1;
+			struct page *pages;
+
+		down_read(&current->mm->mmap_sem);
+
+		res = get_user_pages(current, current->mm,
+				     virtp, nr_pages, 1, 0, &pages, NULL);
+		up_read(&current->mm->mmap_sem);
+
+		if (res == nr_pages)
+			physp = __pa(page_address(&pages[0]) +
+				     (virtp & ~PAGE_MASK));
+		else {
+			vpif_err("get_user_pages failed\n");
+			return 0;
+		}
+	}
+	return physp;
+}
+
+/**
+ * buffer_prepare :  callback function for buffer prepare
+ * @q : buffer queue ptr
+ * @vb: ptr to video buffer
+ * @field: field info
+ *
+ * This is the callback function for buffer prepare when videobuf_qbuf()
+ * function is called. The buffer is prepared and user space virtual address
+ * or user address is converted into  physical address
+ */
+static int vpif_buffer_prepare(struct videobuf_queue *q,
+			       struct videobuf_buffer *vb,
+			       enum v4l2_field field)
+{
+	/* Get the file handle object and channel object */
+	struct vpif_fh *fh = q->priv_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+	unsigned long addr;
+
+
+	vpif_dbg(2, debug, "vpif_buffer_prepare\n");
+
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	/* If buffer is not initialized, initialize it */
+	if (VIDEOBUF_NEEDS_INIT == vb->state) {
+		vb->width = common->width;
+		vb->height = common->height;
+		vb->size = vb->width * vb->height;
+		vb->field = field;
+	}
+	vb->state = VIDEOBUF_PREPARED;
+	/**
+	 * if user pointer memory mechanism is used, get the physical
+	 * address of the buffer
+	 */
+	if (V4L2_MEMORY_USERPTR == common->memory) {
+		if (0 == vb->baddr) {
+			vpif_dbg(1, debug, "buffer address is 0\n");
+			return -EINVAL;
+
+		}
+		vb->boff = vpif_uservirt_to_phys(vb->baddr);
+		if (!IS_ALIGNED(vb->boff, 8))
+			goto exit;
+	}
+
+	addr = vb->boff;
+	if (q->streaming) {
+		if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
+		    !IS_ALIGNED((addr + common->ybtm_off), 8) ||
+		    !IS_ALIGNED((addr + common->ctop_off), 8) ||
+		    !IS_ALIGNED((addr + common->cbtm_off), 8))
+			goto exit;
+	}
+	return 0;
+exit:
+	vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
+	return -EINVAL;
+}
+
+/**
+ * vpif_buffer_setup : Callback function for buffer setup.
+ * @q: buffer queue ptr
+ * @count: number of buffers
+ * @size: size of the buffer
+ *
+ * This callback function is called when reqbuf() is called to adjust
+ * the buffer count and buffer size
+ */
+static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
+			     unsigned int *size)
+{
+	/* Get the file handle object and channel object */
+	struct vpif_fh *fh = q->priv_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	vpif_dbg(2, debug, "vpif_buffer_setup\n");
+
+	/* If memory type is not mmap, return */
+	if (V4L2_MEMORY_MMAP != common->memory)
+		return 0;
+
+	/* Calculate the size of the buffer */
+	*size = config_params.channel_bufsize[ch->channel_id];
+
+	if (*count < config_params.min_numbuffers)
+		*count = config_params.min_numbuffers;
+	return 0;
+}
+
+/**
+ * vpif_buffer_queue : Callback function to add buffer to DMA queue
+ * @q: ptr to videobuf_queue
+ * @vb: ptr to videobuf_buffer
+ */
+static void vpif_buffer_queue(struct videobuf_queue *q,
+			      struct videobuf_buffer *vb)
+{
+	/* Get the file handle object and channel object */
+	struct vpif_fh *fh = q->priv_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	vpif_dbg(2, debug, "vpif_buffer_queue\n");
+
+	/* add the buffer to the DMA queue */
+	list_add_tail(&vb->queue, &common->dma_queue);
+	/* Change state of the buffer */
+	vb->state = VIDEOBUF_QUEUED;
+}
+
+/**
+ * vpif_buffer_release : Callback function to free buffer
+ * @q: buffer queue ptr
+ * @vb: ptr to video buffer
+ *
+ * This function is called from the videobuf layer to free memory
+ * allocated to  the buffers
+ */
+static void vpif_buffer_release(struct videobuf_queue *q,
+				struct videobuf_buffer *vb)
+{
+	/* Get the file handle object and channel object */
+	struct vpif_fh *fh = q->priv_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	videobuf_dma_contig_free(q, vb);
+	vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+static struct videobuf_queue_ops video_qops = {
+	.buf_setup = vpif_buffer_setup,
+	.buf_prepare = vpif_buffer_prepare,
+	.buf_queue = vpif_buffer_queue,
+	.buf_release = vpif_buffer_release,
+};
+
+static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
+	{ {1, 1} };
+
+/**
+ * vpif_process_buffer_complete: process a completed buffer
+ * @common: ptr to common channel object
+ *
+ * This function time stamp the buffer and mark it as DONE. It also
+ * wake up any process waiting on the QUEUE and set the next buffer
+ * as current
+ */
+static void vpif_process_buffer_complete(struct common_obj *common)
+{
+	do_gettimeofday(&common->cur_frm->ts);
+	common->cur_frm->state = VIDEOBUF_DONE;
+	wake_up_interruptible(&common->cur_frm->done);
+	/* Make curFrm pointing to nextFrm */
+	common->cur_frm = common->next_frm;
+}
+
+/**
+ * vpif_schedule_next_buffer: set next buffer address for capture
+ * @common : ptr to common channel object
+ *
+ * This function will get next buffer from the dma queue and
+ * set the buffer address in the vpif register for capture.
+ * the buffer is marked active
+ */
+static void vpif_schedule_next_buffer(struct common_obj *common)
+{
+	unsigned long addr = 0;
+
+	common->next_frm = list_entry(common->dma_queue.next,
+				     struct videobuf_buffer, queue);
+	/* Remove that buffer from the buffer queue */
+	list_del(&common->next_frm->queue);
+	common->next_frm->state = VIDEOBUF_ACTIVE;
+	if (V4L2_MEMORY_USERPTR == common->memory)
+		addr = common->next_frm->boff;
+	else
+		addr = videobuf_to_dma_contig(common->next_frm);
+
+	/* Set top and bottom field addresses in VPIF registers */
+	common->set_addr(addr + common->ytop_off,
+			 addr + common->ybtm_off,
+			 addr + common->ctop_off,
+			 addr + common->cbtm_off);
+}
+
+/**
+ * vpif_channel_isr : ISR handler for vpif capture
+ * @irq: irq number
+ * @dev_id: dev_id ptr
+ *
+ * It changes status of the captured buffer, takes next buffer from the queue
+ * and sets its address in VPIF  registers
+ */
+static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
+{
+	struct vpif_device *dev = &vpif_obj;
+	struct common_obj *common;
+	struct channel_obj *ch;
+	enum v4l2_field field;
+	int channel_id = 0;
+	int fid = -1, i;
+
+	channel_id = *(int *)(dev_id);
+	ch = dev->dev[channel_id];
+
+	field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
+
+	for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
+		common = &ch->common[i];
+		/* skip If streaming is not started in this channel */
+		if (0 == common->started)
+			continue;
+
+		/* Check the field format */
+		if (1 == ch->vpifparams.std_info.frm_fmt) {
+			/* Progressive mode */
+			if (list_empty(&common->dma_queue))
+				continue;
+
+			if (!channel_first_int[i][channel_id])
+				vpif_process_buffer_complete(common);
+
+			channel_first_int[i][channel_id] = 0;
+
+			vpif_schedule_next_buffer(common);
+
+
+			channel_first_int[i][channel_id] = 0;
+		} else {
+			/**
+			 * Interlaced mode. If it is first interrupt, ignore
+			 * it
+			 */
+			if (channel_first_int[i][channel_id]) {
+				channel_first_int[i][channel_id] = 0;
+				continue;
+			}
+			if (0 == i) {
+				ch->field_id ^= 1;
+				/* Get field id from VPIF registers */
+				fid = vpif_channel_getfid(ch->channel_id);
+				if (fid != ch->field_id) {
+					/**
+					 * If field id does not match stored
+					 * field id, make them in sync
+					 */
+					if (0 == fid)
+						ch->field_id = fid;
+					return IRQ_HANDLED;
+				}
+			}
+			/* device field id and local field id are in sync */
+			if (0 == fid) {
+				/* this is even field */
+				if (common->cur_frm == common->next_frm)
+					continue;
+
+				/* mark the current buffer as done */
+				vpif_process_buffer_complete(common);
+			} else if (1 == fid) {
+				/* odd field */
+				if (list_empty(&common->dma_queue) ||
+				    (common->cur_frm != common->next_frm))
+					continue;
+
+				vpif_schedule_next_buffer(common);
+			}
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+/**
+ * vpif_update_std_info() - update standard related info
+ * @ch: ptr to channel object
+ *
+ * For a given standard selected by application, update values
+ * in the device data structures
+ */
+static int vpif_update_std_info(struct channel_obj *ch)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct vpif_params *vpifparams = &ch->vpifparams;
+	const struct vpif_channel_config_params *config;
+	struct vpif_channel_config_params *std_info;
+	struct video_obj *vid_ch = &ch->video;
+	int index;
+
+	vpif_dbg(2, debug, "vpif_update_std_info\n");
+
+	std_info = &vpifparams->std_info;
+
+	for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
+		config = &ch_params[index];
+		if (config->stdid & vid_ch->stdid) {
+			memcpy(std_info, config, sizeof(*config));
+			break;
+		}
+	}
+
+	/* standard not found */
+	if (index == ARRAY_SIZE(ch_params))
+		return -EINVAL;
+
+	common->fmt.fmt.pix.width = std_info->width;
+	common->width = std_info->width;
+	common->fmt.fmt.pix.height = std_info->height;
+	common->height = std_info->height;
+	common->fmt.fmt.pix.bytesperline = std_info->width;
+	vpifparams->video_params.hpitch = std_info->width;
+	vpifparams->video_params.storage_mode = std_info->frm_fmt;
+	return 0;
+}
+
+/**
+ * vpif_calculate_offsets : This function calculates buffers offsets
+ * @ch : ptr to channel object
+ *
+ * This function calculates buffer offsets for Y and C in the top and
+ * bottom field
+ */
+static void vpif_calculate_offsets(struct channel_obj *ch)
+{
+	unsigned int hpitch, vpitch, sizeimage;
+	struct video_obj *vid_ch = &(ch->video);
+	struct vpif_params *vpifparams = &ch->vpifparams;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	enum v4l2_field field = common->fmt.fmt.pix.field;
+
+	vpif_dbg(2, debug, "vpif_calculate_offsets\n");
+
+	if (V4L2_FIELD_ANY == field) {
+		if (vpifparams->std_info.frm_fmt)
+			vid_ch->buf_field = V4L2_FIELD_NONE;
+		else
+			vid_ch->buf_field = V4L2_FIELD_INTERLACED;
+	} else
+		vid_ch->buf_field = common->fmt.fmt.pix.field;
+
+	if (V4L2_MEMORY_USERPTR == common->memory)
+		sizeimage = common->fmt.fmt.pix.sizeimage;
+	else
+		sizeimage = config_params.channel_bufsize[ch->channel_id];
+
+	hpitch = common->fmt.fmt.pix.bytesperline;
+	vpitch = sizeimage / (hpitch * 2);
+
+	if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+	    (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
+		/* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
+		common->ytop_off = 0;
+		common->ybtm_off = hpitch;
+		common->ctop_off = sizeimage / 2;
+		common->cbtm_off = sizeimage / 2 + hpitch;
+	} else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
+		/* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
+		common->ytop_off = 0;
+		common->ybtm_off = sizeimage / 4;
+		common->ctop_off = sizeimage / 2;
+		common->cbtm_off = common->ctop_off + sizeimage / 4;
+	} else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
+		/* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
+		common->ybtm_off = 0;
+		common->ytop_off = sizeimage / 4;
+		common->cbtm_off = sizeimage / 2;
+		common->ctop_off = common->cbtm_off + sizeimage / 4;
+	}
+	if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+	    (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
+		vpifparams->video_params.storage_mode = 1;
+	else
+		vpifparams->video_params.storage_mode = 0;
+
+	if (1 == vpifparams->std_info.frm_fmt)
+		vpifparams->video_params.hpitch =
+		    common->fmt.fmt.pix.bytesperline;
+	else {
+		if ((field == V4L2_FIELD_ANY)
+		    || (field == V4L2_FIELD_INTERLACED))
+			vpifparams->video_params.hpitch =
+			    common->fmt.fmt.pix.bytesperline * 2;
+		else
+			vpifparams->video_params.hpitch =
+			    common->fmt.fmt.pix.bytesperline;
+	}
+
+	ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
+}
+
+/**
+ * vpif_config_format: configure default frame format in the device
+ * ch : ptr to channel object
+ */
+static void vpif_config_format(struct channel_obj *ch)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	vpif_dbg(2, debug, "vpif_config_format\n");
+
+	common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
+	if (config_params.numbuffers[ch->channel_id] == 0)
+		common->memory = V4L2_MEMORY_USERPTR;
+	else
+		common->memory = V4L2_MEMORY_MMAP;
+
+	common->fmt.fmt.pix.sizeimage
+	    = config_params.channel_bufsize[ch->channel_id];
+
+	if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
+		common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
+	else
+		common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
+	common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+}
+
+/**
+ * vpif_get_default_field() - Get default field type based on interface
+ * @vpif_params - ptr to vpif params
+ */
+static inline enum v4l2_field vpif_get_default_field(
+				struct vpif_interface *iface)
+{
+	return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
+						V4L2_FIELD_INTERLACED;
+}
+
+/**
+ * vpif_check_format()  - check given pixel format for compatibility
+ * @ch - channel  ptr
+ * @pixfmt - Given pixel format
+ * @update - update the values as per hardware requirement
+ *
+ * Check the application pixel format for S_FMT and update the input
+ * values as per hardware limits for TRY_FMT. The default pixel and
+ * field format is selected based on interface type.
+ */
+static int vpif_check_format(struct channel_obj *ch,
+			     struct v4l2_pix_format *pixfmt,
+			     int update)
+{
+	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+	struct vpif_params *vpif_params = &ch->vpifparams;
+	enum v4l2_field field = pixfmt->field;
+	u32 sizeimage, hpitch, vpitch;
+	int ret = -EINVAL;
+
+	vpif_dbg(2, debug, "vpif_check_format\n");
+	/**
+	 * first check for the pixel format. If if_type is Raw bayer,
+	 * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
+	 * V4L2_PIX_FMT_YUV422P is supported
+	 */
+	if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
+		if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
+			if (!update) {
+				vpif_dbg(2, debug, "invalid pix format\n");
+				goto exit;
+			}
+			pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
+		}
+	} else {
+		if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
+			if (!update) {
+				vpif_dbg(2, debug, "invalid pixel format\n");
+				goto exit;
+			}
+			pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
+		}
+	}
+
+	if (!(VPIF_VALID_FIELD(field))) {
+		if (!update) {
+			vpif_dbg(2, debug, "invalid field format\n");
+			goto exit;
+		}
+		/**
+		 * By default use FIELD_NONE for RAW Bayer capture
+		 * and FIELD_INTERLACED for other interfaces
+		 */
+		field = vpif_get_default_field(&vpif_params->iface);
+	} else if (field == V4L2_FIELD_ANY)
+		/* unsupported field. Use default */
+		field = vpif_get_default_field(&vpif_params->iface);
+
+	/* validate the hpitch */
+	hpitch = pixfmt->bytesperline;
+	if (hpitch < vpif_params->std_info.width) {
+		if (!update) {
+			vpif_dbg(2, debug, "invalid hpitch\n");
+			goto exit;
+		}
+		hpitch = vpif_params->std_info.width;
+	}
+
+	if (V4L2_MEMORY_USERPTR == common->memory)
+		sizeimage = pixfmt->sizeimage;
+	else
+		sizeimage = config_params.channel_bufsize[ch->channel_id];
+
+	vpitch = sizeimage / (hpitch * 2);
+
+	/* validate the vpitch */
+	if (vpitch < vpif_params->std_info.height) {
+		if (!update) {
+			vpif_dbg(2, debug, "Invalid vpitch\n");
+			goto exit;
+		}
+		vpitch = vpif_params->std_info.height;
+	}
+
+	/* Check for 8 byte alignment */
+	if (!ALIGN(hpitch, 8)) {
+		if (!update) {
+			vpif_dbg(2, debug, "invalid pitch alignment\n");
+			goto exit;
+		}
+		/* adjust to next 8 byte boundary */
+		hpitch = (((hpitch + 7) / 8) * 8);
+	}
+	/* if update is set, modify the bytesperline and sizeimage */
+	if (update) {
+		pixfmt->bytesperline = hpitch;
+		pixfmt->sizeimage = hpitch * vpitch * 2;
+	}
+	/**
+	 * Image width and height is always based on current standard width and
+	 * height
+	 */
+	pixfmt->width = common->fmt.fmt.pix.width;
+	pixfmt->height = common->fmt.fmt.pix.height;
+	return 0;
+exit:
+	return ret;
+}
+
+/**
+ * vpif_config_addr() - function to configure buffer address in vpif
+ * @ch - channel ptr
+ * @muxmode - channel mux mode
+ */
+static void vpif_config_addr(struct channel_obj *ch, int muxmode)
+{
+	struct common_obj *common;
+
+	vpif_dbg(2, debug, "vpif_config_addr\n");
+
+	common = &(ch->common[VPIF_VIDEO_INDEX]);
+
+	if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
+		common->set_addr = ch1_set_videobuf_addr;
+	else if (2 == muxmode)
+		common->set_addr = ch0_set_videobuf_addr_yc_nmux;
+	else
+		common->set_addr = ch0_set_videobuf_addr;
+}
+
+/**
+ * vpfe_mmap : It is used to map kernel space buffers into user spaces
+ * @filep: file pointer
+ * @vma: ptr to vm_area_struct
+ */
+static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
+{
+	/* Get the channel object and file handle object */
+	struct vpif_fh *fh = filep->private_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
+
+	vpif_dbg(2, debug, "vpif_mmap\n");
+
+	return videobuf_mmap_mapper(&common->buffer_queue, vma);
+}
+
+/**
+ * vpif_poll: It is used for select/poll system call
+ * @filep: file pointer
+ * @wait: poll table to wait
+ */
+static unsigned int vpif_poll(struct file *filep, poll_table * wait)
+{
+	int err = 0;
+	struct vpif_fh *fh = filep->private_data;
+	struct channel_obj *channel = fh->channel;
+	struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
+
+	vpif_dbg(2, debug, "vpif_poll\n");
+
+	if (common->started)
+		err = videobuf_poll_stream(filep, &common->buffer_queue, wait);
+
+	return 0;
+}
+
+/**
+ * vpif_open : vpif open handler
+ * @filep: file ptr
+ *
+ * It creates object of file handle structure and stores it in private_data
+ * member of filepointer
+ */
+static int vpif_open(struct file *filep)
+{
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct video_device *vdev = video_devdata(filep);
+	struct common_obj *common;
+	struct video_obj *vid_ch;
+	struct channel_obj *ch;
+	struct vpif_fh *fh;
+	int i, ret = 0;
+
+	vpif_dbg(2, debug, "vpif_open\n");
+
+	ch = video_get_drvdata(vdev);
+
+	vid_ch = &ch->video;
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	if (NULL == ch->curr_subdev_info) {
+		/**
+		 * search through the sub device to see a registered
+		 * sub device and make it as current sub device
+		 */
+		for (i = 0; i < config->subdev_count; i++) {
+			if (vpif_obj.sd[i]) {
+				/* the sub device is registered */
+				ch->curr_subdev_info = &config->subdev_info[i];
+				/* make first input as the current input */
+				vid_ch->input_idx = 0;
+				break;
+			}
+		}
+		if (i == config->subdev_count) {
+			vpif_err("No sub device registered\n");
+			ret = -ENOENT;
+			goto exit;
+		}
+	}
+
+	/* Allocate memory for the file handle object */
+	fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL);
+	if (NULL == fh) {
+		vpif_err("unable to allocate memory for file handle object\n");
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	/* store pointer to fh in private_data member of filep */
+	filep->private_data = fh;
+	fh->channel = ch;
+	fh->initialized = 0;
+	/* If decoder is not initialized. initialize it */
+	if (!ch->initialized) {
+		fh->initialized = 1;
+		ch->initialized = 1;
+		memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
+	}
+	/* Increment channel usrs counter */
+	ch->usrs++;
+	/* Set io_allowed member to false */
+	fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
+	/* Initialize priority of this instance to default priority */
+	fh->prio = V4L2_PRIORITY_UNSET;
+	v4l2_prio_open(&ch->prio, &fh->prio);
+exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+/**
+ * vpif_release : function to clean up file close
+ * @filep: file pointer
+ *
+ * This function deletes buffer queue, frees the buffers and the vpfe file
+ * handle
+ */
+static int vpif_release(struct file *filep)
+{
+	struct vpif_fh *fh = filep->private_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+
+	vpif_dbg(2, debug, "vpif_release\n");
+
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	/* if this instance is doing IO */
+	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		/* Reset io_usrs member of channel object */
+		common->io_usrs = 0;
+		/* Disable channel as per its device type and channel id */
+		if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
+			enable_channel0(0);
+			channel0_intr_enable(0);
+		}
+		if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
+		    (2 == common->started)) {
+			enable_channel1(0);
+			channel1_intr_enable(0);
+		}
+		common->started = 0;
+		/* Free buffers allocated */
+		videobuf_queue_cancel(&common->buffer_queue);
+		videobuf_mmap_free(&common->buffer_queue);
+	}
+
+	/* Decrement channel usrs counter */
+	ch->usrs--;
+
+	/* unlock mutex on channel object */
+	mutex_unlock(&common->lock);
+
+	/* Close the priority */
+	v4l2_prio_close(&ch->prio, &fh->prio);
+
+	if (fh->initialized)
+		ch->initialized = 0;
+
+	filep->private_data = NULL;
+	kfree(fh);
+	return 0;
+}
+
+/**
+ * vpif_reqbufs() - request buffer handler
+ * @file: file ptr
+ * @priv: file handle
+ * @reqbuf: request buffer structure ptr
+ */
+static int vpif_reqbufs(struct file *file, void *priv,
+			struct v4l2_requestbuffers *reqbuf)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+	u8 index = 0;
+	int ret = 0;
+
+	vpif_dbg(2, debug, "vpif_reqbufs\n");
+
+	/**
+	 * This file handle has not initialized the channel,
+	 * It is not allowed to do settings
+	 */
+	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
+	    || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
+		if (!fh->initialized) {
+			vpif_dbg(1, debug, "Channel Busy\n");
+			return -EBUSY;
+		}
+	}
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type)
+		return -EINVAL;
+
+	index = VPIF_VIDEO_INDEX;
+
+	common = &ch->common[index];
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	if (0 != common->io_usrs) {
+		ret = -EBUSY;
+		goto reqbuf_exit;
+	}
+
+	/* Initialize videobuf queue as per the buffer type */
+	videobuf_queue_dma_contig_init(&common->buffer_queue,
+					    &video_qops, NULL,
+					    &common->irqlock,
+					    reqbuf->type,
+					    common->fmt.fmt.pix.field,
+					    sizeof(struct videobuf_buffer), fh);
+
+	/* Set io allowed member of file handle to TRUE */
+	fh->io_allowed[index] = 1;
+	/* Increment io usrs member of channel object to 1 */
+	common->io_usrs = 1;
+	/* Store type of memory requested in channel object */
+	common->memory = reqbuf->memory;
+	INIT_LIST_HEAD(&common->dma_queue);
+
+	/* Allocate buffers */
+	ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
+
+reqbuf_exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+/**
+ * vpif_querybuf() - query buffer handler
+ * @file: file ptr
+ * @priv: file handle
+ * @buf: v4l2 buffer structure ptr
+ */
+static int vpif_querybuf(struct file *file, void *priv,
+				struct v4l2_buffer *buf)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	vpif_dbg(2, debug, "vpif_querybuf\n");
+
+	if (common->fmt.type != buf->type)
+		return -EINVAL;
+
+	if (common->memory != V4L2_MEMORY_MMAP) {
+		vpif_dbg(1, debug, "Invalid memory\n");
+		return -EINVAL;
+	}
+
+	return videobuf_querybuf(&common->buffer_queue, buf);
+}
+
+/**
+ * vpif_qbuf() - query buffer handler
+ * @file: file ptr
+ * @priv: file handle
+ * @buf: v4l2 buffer structure ptr
+ */
+static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct v4l2_buffer tbuf = *buf;
+	struct videobuf_buffer *buf1;
+	unsigned long addr = 0;
+	unsigned long flags;
+	int ret = 0;
+
+	vpif_dbg(2, debug, "vpif_qbuf\n");
+
+	if (common->fmt.type != tbuf.type) {
+		vpif_err("invalid buffer type\n");
+		return -EINVAL;
+	}
+
+	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		vpif_err("fh io not allowed \n");
+		return -EACCES;
+	}
+
+	if (!(list_empty(&common->dma_queue)) ||
+	    (common->cur_frm != common->next_frm) ||
+	    !common->started ||
+	    (common->started && (0 == ch->field_id)))
+		return videobuf_qbuf(&common->buffer_queue, buf);
+
+	/* bufferqueue is empty store buffer address in VPIF registers */
+	mutex_lock(&common->buffer_queue.vb_lock);
+	buf1 = common->buffer_queue.bufs[tbuf.index];
+
+	if ((buf1->state == VIDEOBUF_QUEUED) ||
+	    (buf1->state == VIDEOBUF_ACTIVE)) {
+		vpif_err("invalid state\n");
+		goto qbuf_exit;
+	}
+
+	switch (buf1->memory) {
+	case V4L2_MEMORY_MMAP:
+		if (buf1->baddr == 0)
+			goto qbuf_exit;
+		break;
+
+	case V4L2_MEMORY_USERPTR:
+		if (tbuf.length < buf1->bsize)
+			goto qbuf_exit;
+
+		if ((VIDEOBUF_NEEDS_INIT != buf1->state)
+			    && (buf1->baddr != tbuf.m.userptr))
+			vpif_buffer_release(&common->buffer_queue, buf1);
+			buf1->baddr = tbuf.m.userptr;
+		break;
+
+	default:
+		goto qbuf_exit;
+	}
+
+	local_irq_save(flags);
+	ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
+					common->buffer_queue.field);
+	if (ret < 0) {
+		local_irq_restore(flags);
+		goto qbuf_exit;
+	}
+
+	buf1->state = VIDEOBUF_ACTIVE;
+
+	if (V4L2_MEMORY_USERPTR == common->memory)
+		addr = buf1->boff;
+	else
+		addr = videobuf_to_dma_contig(buf1);
+
+	common->next_frm = buf1;
+	common->set_addr(addr + common->ytop_off,
+			 addr + common->ybtm_off,
+			 addr + common->ctop_off,
+			 addr + common->cbtm_off);
+
+	local_irq_restore(flags);
+	list_add_tail(&buf1->stream, &common->buffer_queue.stream);
+	mutex_unlock(&common->buffer_queue.vb_lock);
+	return 0;
+
+qbuf_exit:
+	mutex_unlock(&common->buffer_queue.vb_lock);
+	return -EINVAL;
+}
+
+/**
+ * vpif_dqbuf() - query buffer handler
+ * @file: file ptr
+ * @priv: file handle
+ * @buf: v4l2 buffer structure ptr
+ */
+static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	vpif_dbg(2, debug, "vpif_dqbuf\n");
+
+	return videobuf_dqbuf(&common->buffer_queue, buf,
+					file->f_flags & O_NONBLOCK);
+}
+
+/**
+ * vpif_streamon() - streamon handler
+ * @file: file ptr
+ * @priv: file handle
+ * @buftype: v4l2 buffer type
+ */
+static int vpif_streamon(struct file *file, void *priv,
+				enum v4l2_buf_type buftype)
+{
+
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
+	struct vpif_params *vpif;
+	unsigned long addr = 0;
+	int ret = 0;
+
+	vpif_dbg(2, debug, "vpif_streamon\n");
+
+	vpif = &ch->vpifparams;
+
+	if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		vpif_dbg(1, debug, "buffer type not supported\n");
+		return -EINVAL;
+	}
+
+	/* If file handle is not allowed IO, return error */
+	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		vpif_dbg(1, debug, "io not allowed\n");
+		return -EACCES;
+	}
+
+	/* If Streaming is already started, return error */
+	if (common->started) {
+		vpif_dbg(1, debug, "channel->started\n");
+		return -EBUSY;
+	}
+
+	if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
+	    oth_ch->common[VPIF_VIDEO_INDEX].started &&
+	    vpif->std_info.ycmux_mode == 0) ||
+	   ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
+	    (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
+		vpif_dbg(1, debug, "other channel is being used\n");
+		return -EBUSY;
+	}
+
+	ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
+	if (ret)
+		return ret;
+
+	/* Enable streamon on the sub device */
+	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
+				s_stream, 1);
+
+	if (ret && (ret != -ENOIOCTLCMD)) {
+		vpif_dbg(1, debug, "stream on failed in subdev\n");
+		return ret;
+	}
+
+	/* Call videobuf_streamon to start streaming in videobuf */
+	ret = videobuf_streamon(&common->buffer_queue);
+	if (ret) {
+		vpif_dbg(1, debug, "videobuf_streamon\n");
+		return ret;
+	}
+
+	if (mutex_lock_interruptible(&common->lock)) {
+		ret = -ERESTARTSYS;
+		goto streamoff_exit;
+	}
+
+	/* If buffer queue is empty, return error */
+	if (list_empty(&common->dma_queue)) {
+		vpif_dbg(1, debug, "buffer queue is empty\n");
+		ret = -EIO;
+		goto exit;
+	}
+
+	/* Get the next frame from the buffer queue */
+	common->cur_frm = list_entry(common->dma_queue.next,
+				    struct videobuf_buffer, queue);
+	common->next_frm = common->cur_frm;
+
+	/* Remove buffer from the buffer queue */
+	list_del(&common->cur_frm->queue);
+	/* Mark state of the current frame to active */
+	common->cur_frm->state = VIDEOBUF_ACTIVE;
+	/* Initialize field_id and started member */
+	ch->field_id = 0;
+	common->started = 1;
+
+	if (V4L2_MEMORY_USERPTR == common->memory)
+		addr = common->cur_frm->boff;
+	else
+		addr = videobuf_to_dma_contig(common->cur_frm);
+
+	/* Calculate the offset for Y and C data in the buffer */
+	vpif_calculate_offsets(ch);
+
+	if ((vpif->std_info.frm_fmt &&
+	    ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
+	     (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
+	    (!vpif->std_info.frm_fmt &&
+	     (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
+		vpif_dbg(1, debug, "conflict in field format and std format\n");
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* configure 1 or 2 channel mode */
+	ret = config->setup_input_channel_mode(vpif->std_info.ycmux_mode);
+
+	if (ret < 0) {
+		vpif_dbg(1, debug, "can't set vpif channel mode\n");
+		goto exit;
+	}
+
+	/* Call vpif_set_params function to set the parameters and addresses */
+	ret = vpif_set_video_params(vpif, ch->channel_id);
+
+	if (ret < 0) {
+		vpif_dbg(1, debug, "can't set video params\n");
+		goto exit;
+	}
+
+	common->started = ret;
+	vpif_config_addr(ch, ret);
+
+	common->set_addr(addr + common->ytop_off,
+			 addr + common->ybtm_off,
+			 addr + common->ctop_off,
+			 addr + common->cbtm_off);
+
+	/**
+	 * Set interrupt for both the fields in VPIF Register enable channel in
+	 * VPIF register
+	 */
+	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
+		channel0_intr_assert();
+		channel0_intr_enable(1);
+		enable_channel0(1);
+	}
+	if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
+	    (common->started == 2)) {
+		channel1_intr_assert();
+		channel1_intr_enable(1);
+		enable_channel1(1);
+	}
+	channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
+	mutex_unlock(&common->lock);
+	return ret;
+
+exit:
+	mutex_unlock(&common->lock);
+streamoff_exit:
+	ret = videobuf_streamoff(&common->buffer_queue);
+	return ret;
+}
+
+/**
+ * vpif_streamoff() - streamoff handler
+ * @file: file ptr
+ * @priv: file handle
+ * @buftype: v4l2 buffer type
+ */
+static int vpif_streamoff(struct file *file, void *priv,
+				enum v4l2_buf_type buftype)
+{
+
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	int ret;
+
+	vpif_dbg(2, debug, "vpif_streamoff\n");
+
+	if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		vpif_dbg(1, debug, "buffer type not supported\n");
+		return -EINVAL;
+	}
+
+	/* If io is allowed for this file handle, return error */
+	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		vpif_dbg(1, debug, "io not allowed\n");
+		return -EACCES;
+	}
+
+	/* If streaming is not started, return error */
+	if (!common->started) {
+		vpif_dbg(1, debug, "channel->started\n");
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	/* disable channel */
+	if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
+		enable_channel0(0);
+		channel0_intr_enable(0);
+	} else {
+		enable_channel1(0);
+		channel1_intr_enable(0);
+	}
+
+	common->started = 0;
+
+	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
+				s_stream, 0);
+
+	if (ret && (ret != -ENOIOCTLCMD))
+		vpif_dbg(1, debug, "stream off failed in subdev\n");
+
+	mutex_unlock(&common->lock);
+
+	return videobuf_streamoff(&common->buffer_queue);
+}
+
+/**
+ * vpif_map_sub_device_to_input() - Maps sub device to input
+ * @ch - ptr to channel
+ * @config - ptr to capture configuration
+ * @input_index - Given input index from application
+ * @sub_device_index - index into sd table
+ *
+ * lookup the sub device information for a given input index.
+ * we report all the inputs to application. inputs table also
+ * has sub device name for the each input
+ */
+static struct vpif_subdev_info *vpif_map_sub_device_to_input(
+				struct channel_obj *ch,
+				struct vpif_capture_config *vpif_cfg,
+				int input_index,
+				int *sub_device_index)
+{
+	struct vpif_capture_chan_config *chan_cfg;
+	struct vpif_subdev_info *subdev_info = NULL;
+	const char *subdev_name = NULL;
+	int i;
+
+	vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");
+
+	chan_cfg = &vpif_cfg->chan_config[ch->channel_id];
+
+	/**
+	 * search through the inputs to find the sub device supporting
+	 * the input
+	 */
+	for (i = 0; i < chan_cfg->input_count; i++) {
+		/* For each sub device, loop through input */
+		if (i == input_index) {
+			subdev_name = chan_cfg->inputs[i].subdev_name;
+			break;
+		}
+	}
+
+	/* if reached maximum. return null */
+	if (i == chan_cfg->input_count || (NULL == subdev_name))
+		return subdev_info;
+
+	/* loop through the sub device list to get the sub device info */
+	for (i = 0; i < vpif_cfg->subdev_count; i++) {
+		subdev_info = &vpif_cfg->subdev_info[i];
+		if (!strcmp(subdev_info->name, subdev_name))
+			break;
+	}
+
+	if (i == vpif_cfg->subdev_count)
+		return subdev_info;
+
+	/* check if the sub device is registered */
+	if (NULL == vpif_obj.sd[i])
+		return NULL;
+
+	*sub_device_index = i;
+	return subdev_info;
+}
+
+/**
+ * vpif_querystd() - querystd handler
+ * @file: file ptr
+ * @priv: file handle
+ * @std_id: ptr to std id
+ *
+ * This function is called to detect standard at the selected input
+ */
+static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	int ret = 0;
+
+	vpif_dbg(2, debug, "vpif_querystd\n");
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	/* Call querystd function of decoder device */
+	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
+				querystd, std_id);
+	if (ret < 0)
+		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
+
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+/**
+ * vpif_g_std() - get STD handler
+ * @file: file ptr
+ * @priv: file handle
+ * @std_id: ptr to std id
+ */
+static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	vpif_dbg(2, debug, "vpif_g_std\n");
+
+	*std = ch->video.stdid;
+	return 0;
+}
+
+/**
+ * vpif_s_std() - set STD handler
+ * @file: file ptr
+ * @priv: file handle
+ * @std_id: ptr to std id
+ */
+static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	int ret = 0;
+
+	vpif_dbg(2, debug, "vpif_s_std\n");
+
+	if (common->started) {
+		vpif_err("streaming in progress\n");
+		return -EBUSY;
+	}
+
+	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
+	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
+		if (!fh->initialized) {
+			vpif_dbg(1, debug, "Channel Busy\n");
+			return -EBUSY;
+		}
+	}
+
+	ret = v4l2_prio_check(&ch->prio, &fh->prio);
+	if (0 != ret)
+		return ret;
+
+	fh->initialized = 1;
+
+	/* Call encoder subdevice function to set the standard */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	ch->video.stdid = *std_id;
+
+	/* Get the information about the standard */
+	if (vpif_update_std_info(ch)) {
+		ret = -EINVAL;
+		vpif_err("Error getting the standard info\n");
+		goto s_std_exit;
+	}
+
+	/* Configure the default format information */
+	vpif_config_format(ch);
+
+	/* set standard in the sub device */
+	ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
+				s_std, *std_id);
+	if (ret < 0)
+		vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
+
+s_std_exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+/**
+ * vpif_enum_input() - ENUMINPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @input: ptr to input structure
+ */
+static int vpif_enum_input(struct file *file, void *priv,
+				struct v4l2_input *input)
+{
+
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct vpif_capture_chan_config *chan_cfg;
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+
+	if (input->index >= chan_cfg->input_count) {
+		vpif_dbg(1, debug, "Invalid input index\n");
+		return -EINVAL;
+	}
+
+	memcpy(input, &chan_cfg->inputs[input->index].input,
+		sizeof(*input));
+	return 0;
+}
+
+/**
+ * vpif_g_input() - Get INPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @index: ptr to input index
+ */
+static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+
+	*index = vid_ch->input_idx;
+
+	return 0;
+}
+
+/**
+ * vpif_s_input() - Set INPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @index: input index
+ */
+static int vpif_s_input(struct file *file, void *priv, unsigned int index)
+{
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+	struct vpif_capture_chan_config *chan_cfg;
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct video_obj *vid_ch = &ch->video;
+	struct vpif_subdev_info *subdev_info;
+	int ret = 0, sd_index = 0;
+	u32 input = 0, output = 0;
+
+	chan_cfg = &config->chan_config[ch->channel_id];
+
+	if (common->started) {
+		vpif_err("Streaming in progress\n");
+		return -EBUSY;
+	}
+
+	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
+	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
+		if (!fh->initialized) {
+			vpif_dbg(1, debug, "Channel Busy\n");
+			return -EBUSY;
+		}
+	}
+
+	ret = v4l2_prio_check(&ch->prio, &fh->prio);
+	if (0 != ret)
+		return ret;
+
+	fh->initialized = 1;
+	subdev_info = vpif_map_sub_device_to_input(ch, config, index,
+						   &sd_index);
+	if (NULL == subdev_info) {
+		vpif_dbg(1, debug,
+			"couldn't lookup sub device for the input index\n");
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	/* first setup input path from sub device to vpif */
+	if (config->setup_input_path) {
+		ret = config->setup_input_path(ch->channel_id,
+					       subdev_info->name);
+		if (ret < 0) {
+			vpif_dbg(1, debug, "couldn't setup input path for the"
+				" sub device %s, for input index %d\n",
+				subdev_info->name, index);
+			goto exit;
+		}
+	}
+
+	if (subdev_info->can_route) {
+		input = subdev_info->input;
+		output = subdev_info->output;
+		ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
+					input, output, 0);
+		if (ret < 0) {
+			vpif_dbg(1, debug, "Failed to set input\n");
+			goto exit;
+		}
+	}
+	vid_ch->input_idx = index;
+	ch->curr_subdev_info = subdev_info;
+	ch->curr_sd_index = sd_index;
+	/* copy interface parameters to vpif */
+	ch->vpifparams.iface = subdev_info->vpif_if;
+
+	/* update tvnorms from the sub device input info */
+	ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
+
+exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+/**
+ * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @index: input index
+ */
+static int vpif_enum_fmt_vid_cap(struct file *file, void  *priv,
+					struct v4l2_fmtdesc *fmt)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	if (fmt->index != 0) {
+		vpif_dbg(1, debug, "Invalid format index\n");
+		return -EINVAL;
+	}
+
+	/* Fill in the information about format */
+	if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
+		fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
+		fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
+	} else {
+		fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
+		fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
+	}
+	return 0;
+}
+
+/**
+ * vpif_try_fmt_vid_cap() - TRY_FMT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @fmt: ptr to v4l2 format structure
+ */
+static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+
+	return vpif_check_format(ch, pixfmt, 1);
+}
+
+
+/**
+ * vpif_g_fmt_vid_cap() - Set INPUT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @fmt: ptr to v4l2 format structure
+ */
+static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	/* Check the validity of the buffer type */
+	if (common->fmt.type != fmt->type)
+		return -EINVAL;
+
+	/* Fill in the information about format */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	*fmt = common->fmt;
+	mutex_unlock(&common->lock);
+	return 0;
+}
+
+/**
+ * vpif_s_fmt_vid_cap() - Set FMT handler
+ * @file: file ptr
+ * @priv: file handle
+ * @fmt: ptr to v4l2 format structure
+ */
+static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct v4l2_pix_format *pixfmt;
+	int ret = 0;
+
+	vpif_dbg(2, debug, "VIDIOC_S_FMT\n");
+
+	/* If streaming is started, return error */
+	if (common->started) {
+		vpif_dbg(1, debug, "Streaming is started\n");
+		return -EBUSY;
+	}
+
+	if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
+	    (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
+		if (!fh->initialized) {
+			vpif_dbg(1, debug, "Channel Busy\n");
+			return -EBUSY;
+		}
+	}
+
+	ret = v4l2_prio_check(&ch->prio, &fh->prio);
+	if (0 != ret)
+		return ret;
+
+	fh->initialized = 1;
+
+	pixfmt = &fmt->fmt.pix;
+	/* Check for valid field format */
+	ret = vpif_check_format(ch, pixfmt, 0);
+
+	if (ret)
+		return ret;
+	/* store the format in the channel object */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	common->fmt = *fmt;
+	mutex_unlock(&common->lock);
+
+	return 0;
+}
+
+/**
+ * vpif_querycap() - QUERYCAP handler
+ * @file: file ptr
+ * @priv: file handle
+ * @cap: ptr to v4l2_capability structure
+ */
+static int vpif_querycap(struct file *file, void  *priv,
+				struct v4l2_capability *cap)
+{
+	struct vpif_capture_config *config = vpif_dev->platform_data;
+
+	cap->version = VPIF_CAPTURE_VERSION_CODE;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	strlcpy(cap->driver, "vpif capture", sizeof(cap->driver));
+	strlcpy(cap->bus_info, "DM646x Platform", sizeof(cap->bus_info));
+	strlcpy(cap->card, config->card_name, sizeof(cap->card));
+
+	return 0;
+}
+
+/**
+ * vpif_g_priority() - get priority handler
+ * @file: file ptr
+ * @priv: file handle
+ * @prio: ptr to v4l2_priority structure
+ */
+static int vpif_g_priority(struct file *file, void *priv,
+			   enum v4l2_priority *prio)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	*prio = v4l2_prio_max(&ch->prio);
+
+	return 0;
+}
+
+/**
+ * vpif_s_priority() - set priority handler
+ * @file: file ptr
+ * @priv: file handle
+ * @prio: ptr to v4l2_priority structure
+ */
+static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	return v4l2_prio_change(&ch->prio, &fh->prio, p);
+}
+
+/**
+ * vpif_cropcap() - cropcap handler
+ * @file: file ptr
+ * @priv: file handle
+ * @crop: ptr to v4l2_cropcap structure
+ */
+static int vpif_cropcap(struct file *file, void *priv,
+			struct v4l2_cropcap *crop)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
+		return -EINVAL;
+
+	crop->bounds.left = 0;
+	crop->bounds.top = 0;
+	crop->bounds.height = common->height;
+	crop->bounds.width = common->width;
+	crop->defrect = crop->bounds;
+	return 0;
+}
+
+/* vpif capture ioctl operations */
+static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
+	.vidioc_querycap        	= vpif_querycap,
+	.vidioc_g_priority		= vpif_g_priority,
+	.vidioc_s_priority		= vpif_s_priority,
+	.vidioc_enum_fmt_vid_cap	= vpif_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap  		= vpif_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap		= vpif_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap		= vpif_try_fmt_vid_cap,
+	.vidioc_enum_input		= vpif_enum_input,
+	.vidioc_s_input			= vpif_s_input,
+	.vidioc_g_input			= vpif_g_input,
+	.vidioc_reqbufs         	= vpif_reqbufs,
+	.vidioc_querybuf        	= vpif_querybuf,
+	.vidioc_querystd		= vpif_querystd,
+	.vidioc_s_std           	= vpif_s_std,
+	.vidioc_g_std			= vpif_g_std,
+	.vidioc_qbuf            	= vpif_qbuf,
+	.vidioc_dqbuf           	= vpif_dqbuf,
+	.vidioc_streamon        	= vpif_streamon,
+	.vidioc_streamoff       	= vpif_streamoff,
+	.vidioc_cropcap         	= vpif_cropcap,
+};
+
+/* vpif file operations */
+static struct v4l2_file_operations vpif_fops = {
+	.owner = THIS_MODULE,
+	.open = vpif_open,
+	.release = vpif_release,
+	.ioctl = video_ioctl2,
+	.mmap = vpif_mmap,
+	.poll = vpif_poll
+};
+
+/* vpif video template */
+static struct video_device vpif_video_template = {
+	.name		= "vpif",
+	.fops		= &vpif_fops,
+	.minor		= -1,
+	.ioctl_ops	= &vpif_ioctl_ops,
+};
+
+/**
+ * initialize_vpif() - Initialize vpif data structures
+ *
+ * Allocate memory for data structures and initialize them
+ */
+static int initialize_vpif(void)
+{
+	int err = 0, i, j;
+	int free_channel_objects_index;
+
+	/* Default number of buffers should be 3 */
+	if ((ch0_numbuffers > 0) &&
+	    (ch0_numbuffers < config_params.min_numbuffers))
+		ch0_numbuffers = config_params.min_numbuffers;
+	if ((ch1_numbuffers > 0) &&
+	    (ch1_numbuffers < config_params.min_numbuffers))
+		ch1_numbuffers = config_params.min_numbuffers;
+
+	/* Set buffer size to min buffers size if it is invalid */
+	if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
+		ch0_bufsize =
+		    config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
+	if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
+		ch1_bufsize =
+		    config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
+
+	config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
+	config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
+	if (ch0_numbuffers) {
+		config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
+		    = ch0_bufsize;
+	}
+	if (ch1_numbuffers) {
+		config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
+		    = ch1_bufsize;
+	}
+
+	/* Allocate memory for six channel objects */
+	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+		vpif_obj.dev[i] =
+		    kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
+		/* If memory allocation fails, return error */
+		if (!vpif_obj.dev[i]) {
+			free_channel_objects_index = i;
+			err = -ENOMEM;
+			goto vpif_init_free_channel_objects;
+		}
+	}
+	return 0;
+
+vpif_init_free_channel_objects:
+	for (j = 0; j < free_channel_objects_index; j++)
+		kfree(vpif_obj.dev[j]);
+	return err;
+}
+
+/**
+ * vpif_probe : This function probes the vpif capture driver
+ * @pdev: platform device pointer
+ *
+ * This creates device entries by register itself to the V4L2 driver and
+ * initializes fields of each channel objects
+ */
+static __init int vpif_probe(struct platform_device *pdev)
+{
+	struct vpif_subdev_info *subdevdata;
+	struct vpif_capture_config *config;
+	int i, j, k, m, q, err;
+	struct i2c_adapter *i2c_adap;
+	struct channel_obj *ch;
+	struct common_obj *common;
+	struct video_device *vfd;
+	struct resource *res;
+	int subdev_count;
+
+	vpif_dev = &pdev->dev;
+
+	err = initialize_vpif();
+	if (err) {
+		v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
+		return err;
+	}
+
+	k = 0;
+	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
+		for (i = res->start; i <= res->end; i++) {
+			if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
+					"DM646x_Capture",
+				(void *)(&vpif_obj.dev[k]->channel_id))) {
+				err = -EBUSY;
+				i--;
+				goto vpif_int_err;
+			}
+		}
+		k++;
+	}
+
+	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+		/* Get the pointer to the channel object */
+		ch = vpif_obj.dev[i];
+		/* Allocate memory for video device */
+		vfd = video_device_alloc();
+		if (NULL == vfd) {
+			for (j = 0; j < i; j++) {
+				ch = vpif_obj.dev[j];
+				video_device_release(ch->video_dev);
+			}
+			err = -ENOMEM;
+			goto vpif_dev_alloc_err;
+		}
+
+		/* Initialize field of video device */
+		*vfd = vpif_video_template;
+		vfd->v4l2_dev = &vpif_obj.v4l2_dev;
+		vfd->release = video_device_release;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "DM646x_VPIFCapture_DRIVER_V%d.%d.%d",
+			 (VPIF_CAPTURE_VERSION_CODE >> 16) & 0xff,
+			 (VPIF_CAPTURE_VERSION_CODE >> 8) & 0xff,
+			 (VPIF_CAPTURE_VERSION_CODE) & 0xff);
+		/* Set video_dev to the video device */
+		ch->video_dev = vfd;
+	}
+
+	for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
+		ch = vpif_obj.dev[j];
+		ch->channel_id = j;
+		common = &(ch->common[VPIF_VIDEO_INDEX]);
+		spin_lock_init(&common->irqlock);
+		mutex_init(&common->lock);
+		/* Initialize prio member of channel object */
+		v4l2_prio_init(&ch->prio);
+		err = video_register_device(ch->video_dev,
+					    VFL_TYPE_GRABBER, (j ? 1 : 0));
+		if (err)
+			goto probe_out;
+
+		video_set_drvdata(ch->video_dev, ch);
+
+	}
+
+	i2c_adap = i2c_get_adapter(1);
+	config = pdev->dev.platform_data;
+
+	subdev_count = config->subdev_count;
+	vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
+				GFP_KERNEL);
+	if (vpif_obj.sd == NULL) {
+		vpif_err("unable to allocate memory for subdevice pointers\n");
+		err = -ENOMEM;
+		goto probe_out;
+	}
+
+	err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
+	if (err) {
+		v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
+		goto probe_subdev_out;
+	}
+
+	for (i = 0; i < subdev_count; i++) {
+		subdevdata = &config->subdev_info[i];
+		vpif_obj.sd[i] =
+			v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+						  i2c_adap,
+						  subdevdata->name,
+						  &subdevdata->board_info,
+						  NULL);
+
+		if (!vpif_obj.sd[i]) {
+			vpif_err("Error registering v4l2 subdevice\n");
+			goto probe_subdev_out;
+		}
+		v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
+			  subdevdata->name);
+
+		if (vpif_obj.sd[i])
+			vpif_obj.sd[i]->grp_id = 1 << i;
+	}
+	v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver"
+		  " initialized\n");
+
+	return 0;
+
+probe_subdev_out:
+	/* free sub devices memory */
+	kfree(vpif_obj.sd);
+
+	j = VPIF_CAPTURE_MAX_DEVICES;
+probe_out:
+	v4l2_device_unregister(&vpif_obj.v4l2_dev);
+	for (k = 0; k < j; k++) {
+		/* Get the pointer to the channel object */
+		ch = vpif_obj.dev[k];
+		/* Unregister video device */
+		video_unregister_device(ch->video_dev);
+	}
+
+vpif_dev_alloc_err:
+	k = VPIF_CAPTURE_MAX_DEVICES-1;
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
+	i = res->end;
+
+vpif_int_err:
+	for (q = k; q >= 0; q--) {
+		for (m = i; m >= (int)res->start; m--)
+			free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
+
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
+		if (res)
+			i = res->end;
+	}
+	return err;
+}
+
+/**
+ * vpif_remove() - driver remove handler
+ * @device: ptr to platform device structure
+ *
+ * The vidoe device is unregistered
+ */
+static int vpif_remove(struct platform_device *device)
+{
+	int i;
+	struct channel_obj *ch;
+
+	v4l2_device_unregister(&vpif_obj.v4l2_dev);
+
+	/* un-register device */
+	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
+		/* Get the pointer to the channel object */
+		ch = vpif_obj.dev[i];
+		/* Unregister video device */
+		video_unregister_device(ch->video_dev);
+	}
+	return 0;
+}
+
+/**
+ * vpif_suspend: vpif device suspend
+ *
+ * TODO: Add suspend code here
+ */
+static int
+vpif_suspend(struct device *dev)
+{
+	return -1;
+}
+
+/**
+ * vpif_resume: vpif device suspend
+ *
+ * TODO: Add resume code here
+ */
+static int
+vpif_resume(struct device *dev)
+{
+	return -1;
+}
+
+static struct dev_pm_ops vpif_dev_pm_ops = {
+	.suspend = vpif_suspend,
+	.resume = vpif_resume,
+};
+
+static struct platform_driver vpif_driver = {
+	.driver	= {
+		.name	= "vpif_capture",
+		.owner	= THIS_MODULE,
+		.pm = &vpif_dev_pm_ops,
+	},
+	.probe = vpif_probe,
+	.remove = vpif_remove,
+};
+
+/**
+ * vpif_init: initialize the vpif driver
+ *
+ * This function registers device and driver to the kernel, requests irq
+ * handler and allocates memory
+ * for channel objects
+ */
+static __init int vpif_init(void)
+{
+	return platform_driver_register(&vpif_driver);
+}
+
+/**
+ * vpif_cleanup : This function clean up the vpif capture resources
+ *
+ * This will un-registers device and driver to the kernel, frees
+ * requested irq handler and de-allocates memory allocated for channel
+ * objects.
+ */
+static void vpif_cleanup(void)
+{
+	struct platform_device *pdev;
+	struct resource *res;
+	int irq_num;
+	int i = 0;
+
+	pdev = container_of(vpif_dev, struct platform_device, dev);
+	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
+		for (irq_num = res->start; irq_num <= res->end; irq_num++)
+			free_irq(irq_num,
+				 (void *)(&vpif_obj.dev[i]->channel_id));
+		i++;
+	}
+
+	platform_driver_unregister(&vpif_driver);
+
+	kfree(vpif_obj.sd);
+	for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
+		kfree(vpif_obj.dev[i]);
+}
+
+/* Function for module initialization and cleanup */
+module_init(vpif_init);
+module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h
new file mode 100644
index 0000000..4e12ec8
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 Texas Instruments 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 VPIF_CAPTURE_H
+#define VPIF_CAPTURE_H
+
+#ifdef __KERNEL__
+
+/* Header files */
+#include <linux/videodev2.h>
+#include <linux/version.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf-core.h>
+#include <media/videobuf-dma-contig.h>
+#include <mach/dm646x.h>
+
+#include "vpif.h"
+
+/* Macros */
+#define VPIF_MAJOR_RELEASE		0
+#define VPIF_MINOR_RELEASE		0
+#define VPIF_BUILD			1
+#define VPIF_CAPTURE_VERSION_CODE	((VPIF_MAJOR_RELEASE << 16) | \
+	(VPIF_MINOR_RELEASE << 8) | VPIF_BUILD)
+
+#define VPIF_VALID_FIELD(field)		(((V4L2_FIELD_ANY == field) || \
+	(V4L2_FIELD_NONE == field)) || \
+	(((V4L2_FIELD_INTERLACED == field) || \
+	(V4L2_FIELD_SEQ_TB == field)) || \
+	(V4L2_FIELD_SEQ_BT == field)))
+
+#define VPIF_CAPTURE_MAX_DEVICES	2
+#define VPIF_VIDEO_INDEX		0
+#define VPIF_NUMBER_OF_OBJECTS		1
+
+/* Enumerated data type to give id to each device per channel */
+enum vpif_channel_id {
+	VPIF_CHANNEL0_VIDEO = 0,
+	VPIF_CHANNEL1_VIDEO,
+};
+
+struct video_obj {
+	enum v4l2_field buf_field;
+	/* Currently selected or default standard */
+	v4l2_std_id stdid;
+	/* This is to track the last input that is passed to application */
+	u32 input_idx;
+};
+
+struct common_obj {
+	/* Pointer pointing to current v4l2_buffer */
+	struct videobuf_buffer *cur_frm;
+	/* Pointer pointing to current v4l2_buffer */
+	struct videobuf_buffer *next_frm;
+	/*
+	 * This field keeps track of type of buffer exchange mechanism
+	 * user has selected
+	 */
+	enum v4l2_memory memory;
+	/* Used to store pixel format */
+	struct v4l2_format fmt;
+	/* Buffer queue used in video-buf */
+	struct videobuf_queue buffer_queue;
+	/* Queue of filled frames */
+	struct list_head dma_queue;
+	/* Used in video-buf */
+	spinlock_t irqlock;
+	/* lock used to access this structure */
+	struct mutex lock;
+	/* number of users performing IO */
+	u32 io_usrs;
+	/* Indicates whether streaming started */
+	u8 started;
+	/* Function pointer to set the addresses */
+	void (*set_addr) (unsigned long, unsigned long, unsigned long,
+			  unsigned long);
+	/* offset where Y top starts from the starting of the buffer */
+	u32 ytop_off;
+	/* offset where Y bottom starts from the starting of the buffer */
+	u32 ybtm_off;
+	/* offset where C top starts from the starting of the buffer */
+	u32 ctop_off;
+	/* offset where C bottom starts from the starting of the buffer */
+	u32 cbtm_off;
+	/* Indicates width of the image data */
+	u32 width;
+	/* Indicates height of the image data */
+	u32 height;
+};
+
+struct channel_obj {
+	/* Identifies video device for this channel */
+	struct video_device *video_dev;
+	/* Used to keep track of state of the priority */
+	struct v4l2_prio_state prio;
+	/* number of open instances of the channel */
+	int usrs;
+	/* Indicates id of the field which is being displayed */
+	u32 field_id;
+	/* flag to indicate whether decoder is initialized */
+	u8 initialized;
+	/* Identifies channel */
+	enum vpif_channel_id channel_id;
+	/* index into sd table */
+	int curr_sd_index;
+	/* ptr to current sub device information */
+	struct vpif_subdev_info *curr_subdev_info;
+	/* vpif configuration params */
+	struct vpif_params vpifparams;
+	/* common object array */
+	struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
+	/* video object */
+	struct video_obj video;
+};
+
+/* File handle structure */
+struct vpif_fh {
+	/* pointer to channel object for opened device */
+	struct channel_obj *channel;
+	/* Indicates whether this file handle is doing IO */
+	u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
+	/* Used to keep track priority of this instance */
+	enum v4l2_priority prio;
+	/* Used to indicate channel is initialize or not */
+	u8 initialized;
+};
+
+struct vpif_device {
+	struct v4l2_device v4l2_dev;
+	struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
+	struct v4l2_subdev **sd;
+};
+
+struct vpif_config_params {
+	u8 min_numbuffers;
+	u8 numbuffers[VPIF_CAPTURE_NUM_CHANNELS];
+	s8 device_type;
+	u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
+	u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
+	u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
+	u8 max_device_type;
+};
+/* Struct which keeps track of the line numbers for the sliced vbi service */
+struct vpif_service_line {
+	u16 service_id;
+	u16 service_line[2];
+};
+#endif				/* End of __KERNEL__ */
+#endif				/* VPIF_CAPTURE_H */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
new file mode 100644
index 0000000..c015da8
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -0,0 +1,1656 @@
+/*
+ * vpif-display - VPIF display driver
+ * Display driver for TI DaVinci VPIF
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; 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/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/string.h>
+#include <linux/videodev2.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/version.h>
+
+#include <asm/irq.h>
+#include <asm/page.h>
+
+#include <media/adv7343.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+#include <mach/dm646x.h>
+
+#include "vpif_display.h"
+#include "vpif.h"
+
+MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
+MODULE_LICENSE("GPL");
+
+#define DM646X_V4L2_STD (V4L2_STD_525_60 | V4L2_STD_625_50)
+
+#define vpif_err(fmt, arg...)	v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
+#define vpif_dbg(level, debug, fmt, arg...)	\
+		v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
+
+static int debug = 1;
+static u32 ch2_numbuffers = 3;
+static u32 ch3_numbuffers = 3;
+static u32 ch2_bufsize = 1920 * 1080 * 2;
+static u32 ch3_bufsize = 720 * 576 * 2;
+
+module_param(debug, int, 0644);
+module_param(ch2_numbuffers, uint, S_IRUGO);
+module_param(ch3_numbuffers, uint, S_IRUGO);
+module_param(ch2_bufsize, uint, S_IRUGO);
+module_param(ch3_bufsize, uint, S_IRUGO);
+
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)");
+MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)");
+MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x 2)");
+MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x 576 x 2)");
+
+static struct vpif_config_params config_params = {
+	.min_numbuffers		= 3,
+	.numbuffers[0]		= 3,
+	.numbuffers[1]		= 3,
+	.min_bufsize[0]		= 720 * 480 * 2,
+	.min_bufsize[1]		= 720 * 480 * 2,
+	.channel_bufsize[0]	= 1920 * 1080 * 2,
+	.channel_bufsize[1]	= 720 * 576 * 2,
+};
+
+static struct vpif_device vpif_obj = { {NULL} };
+static struct device *vpif_dev;
+
+static const struct vpif_channel_config_params ch_params[] = {
+	{
+		"NTSC", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
+		286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
+	},
+	{
+		"PAL", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
+		336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
+	},
+};
+
+/*
+ * vpif_uservirt_to_phys: This function is used to convert user
+ * space virtual address to physical address.
+ */
+static u32 vpif_uservirt_to_phys(u32 virtp)
+{
+	struct mm_struct *mm = current->mm;
+	unsigned long physp = 0;
+	struct vm_area_struct *vma;
+
+	vma = find_vma(mm, virtp);
+
+	/* For kernel direct-mapped memory, take the easy way */
+	if (virtp >= PAGE_OFFSET) {
+		physp = virt_to_phys((void *)virtp);
+	} else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) {
+		/* this will catch, kernel-allocated, mmaped-to-usermode addr */
+		physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
+	} else {
+		/* otherwise, use get_user_pages() for general userland pages */
+		int res, nr_pages = 1;
+		struct page *pages;
+		down_read(&current->mm->mmap_sem);
+
+		res = get_user_pages(current, current->mm,
+				     virtp, nr_pages, 1, 0, &pages, NULL);
+		up_read(&current->mm->mmap_sem);
+
+		if (res == nr_pages) {
+			physp = __pa(page_address(&pages[0]) +
+							(virtp & ~PAGE_MASK));
+		} else {
+			vpif_err("get_user_pages failed\n");
+			return 0;
+		}
+	}
+
+	return physp;
+}
+
+/*
+ * buffer_prepare: This is the callback function called from videobuf_qbuf()
+ * function the buffer is prepared and user space virtual address is converted
+ * into physical address
+ */
+static int vpif_buffer_prepare(struct videobuf_queue *q,
+			       struct videobuf_buffer *vb,
+			       enum v4l2_field field)
+{
+	struct vpif_fh *fh = q->priv_data;
+	struct common_obj *common;
+	unsigned long addr;
+
+	common = &fh->channel->common[VPIF_VIDEO_INDEX];
+	if (VIDEOBUF_NEEDS_INIT == vb->state) {
+		vb->width	= common->width;
+		vb->height	= common->height;
+		vb->size	= vb->width * vb->height;
+		vb->field	= field;
+	}
+	vb->state = VIDEOBUF_PREPARED;
+
+	/* if user pointer memory mechanism is used, get the physical
+	 * address of the buffer */
+	if (V4L2_MEMORY_USERPTR == common->memory) {
+		if (!vb->baddr) {
+			vpif_err("buffer_address is 0\n");
+			return -EINVAL;
+		}
+
+		vb->boff = vpif_uservirt_to_phys(vb->baddr);
+		if (!ISALIGNED(vb->boff))
+			goto buf_align_exit;
+	}
+
+	addr = vb->boff;
+	if (q->streaming && (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
+		if (!ISALIGNED(addr + common->ytop_off) ||
+		    !ISALIGNED(addr + common->ybtm_off) ||
+		    !ISALIGNED(addr + common->ctop_off) ||
+		    !ISALIGNED(addr + common->cbtm_off))
+			goto buf_align_exit;
+	}
+	return 0;
+
+buf_align_exit:
+	vpif_err("buffer offset not aligned to 8 bytes\n");
+	return -EINVAL;
+}
+
+/*
+ * vpif_buffer_setup: This function allocates memory for the buffers
+ */
+static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
+				unsigned int *size)
+{
+	struct vpif_fh *fh = q->priv_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (V4L2_MEMORY_MMAP != common->memory)
+		return 0;
+
+	*size = config_params.channel_bufsize[ch->channel_id];
+	if (*count < config_params.min_numbuffers)
+		*count = config_params.min_numbuffers;
+
+	return 0;
+}
+
+/*
+ * vpif_buffer_queue: This function adds the buffer to DMA queue
+ */
+static void vpif_buffer_queue(struct videobuf_queue *q,
+			      struct videobuf_buffer *vb)
+{
+	struct vpif_fh *fh = q->priv_data;
+	struct common_obj *common;
+
+	common = &fh->channel->common[VPIF_VIDEO_INDEX];
+
+	/* add the buffer to the DMA queue */
+	list_add_tail(&vb->queue, &common->dma_queue);
+	vb->state = VIDEOBUF_QUEUED;
+}
+
+/*
+ * vpif_buffer_release: This function is called from the videobuf layer to
+ * free memory allocated to the buffers
+ */
+static void vpif_buffer_release(struct videobuf_queue *q,
+				struct videobuf_buffer *vb)
+{
+	struct vpif_fh *fh = q->priv_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+	unsigned int buf_size = 0;
+
+	common = &ch->common[VPIF_VIDEO_INDEX];
+
+	videobuf_dma_contig_free(q, vb);
+	vb->state = VIDEOBUF_NEEDS_INIT;
+
+	if (V4L2_MEMORY_MMAP != common->memory)
+		return;
+
+	buf_size = config_params.channel_bufsize[ch->channel_id];
+}
+
+static struct videobuf_queue_ops video_qops = {
+	.buf_setup	= vpif_buffer_setup,
+	.buf_prepare	= vpif_buffer_prepare,
+	.buf_queue	= vpif_buffer_queue,
+	.buf_release	= vpif_buffer_release,
+};
+static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
+
+static void process_progressive_mode(struct common_obj *common)
+{
+	unsigned long addr = 0;
+
+	/* Get the next buffer from buffer queue */
+	common->next_frm = list_entry(common->dma_queue.next,
+				struct videobuf_buffer, queue);
+	/* Remove that buffer from the buffer queue */
+	list_del(&common->next_frm->queue);
+	/* Mark status of the buffer as active */
+	common->next_frm->state = VIDEOBUF_ACTIVE;
+
+	/* Set top and bottom field addrs in VPIF registers */
+	addr = videobuf_to_dma_contig(common->next_frm);
+	common->set_addr(addr + common->ytop_off,
+				 addr + common->ybtm_off,
+				 addr + common->ctop_off,
+				 addr + common->cbtm_off);
+}
+
+static void process_interlaced_mode(int fid, struct common_obj *common)
+{
+	/* device field id and local field id are in sync */
+	/* If this is even field */
+	if (0 == fid) {
+		if (common->cur_frm == common->next_frm)
+			return;
+
+		/* one frame is displayed If next frame is
+		 *  available, release cur_frm and move on */
+		/* Copy frame display time */
+		do_gettimeofday(&common->cur_frm->ts);
+		/* Change status of the cur_frm */
+		common->cur_frm->state = VIDEOBUF_DONE;
+		/* unlock semaphore on cur_frm */
+		wake_up_interruptible(&common->cur_frm->done);
+		/* Make cur_frm pointing to next_frm */
+		common->cur_frm = common->next_frm;
+
+	} else if (1 == fid) {	/* odd field */
+		if (list_empty(&common->dma_queue)
+		    || (common->cur_frm != common->next_frm)) {
+			return;
+		}
+		/* one field is displayed configure the next
+		 * frame if it is available else hold on current
+		 * frame */
+		/* Get next from the buffer queue */
+		process_progressive_mode(common);
+
+	}
+}
+
+/*
+ * vpif_channel_isr: It changes status of the displayed buffer, takes next
+ * buffer from the queue and sets its address in VPIF registers
+ */
+static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
+{
+	struct vpif_device *dev = &vpif_obj;
+	struct channel_obj *ch;
+	struct common_obj *common;
+	enum v4l2_field field;
+	int fid = -1, i;
+	int channel_id = 0;
+
+	channel_id = *(int *)(dev_id);
+	ch = dev->dev[channel_id];
+	field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
+	for (i = 0; i < VPIF_NUMOBJECTS; i++) {
+		common = &ch->common[i];
+		/* If streaming is started in this channel */
+		if (0 == common->started)
+			continue;
+
+		if (1 == ch->vpifparams.std_info.frm_fmt) {
+			if (list_empty(&common->dma_queue))
+				continue;
+
+			/* Progressive mode */
+			if (!channel_first_int[i][channel_id]) {
+				/* Mark status of the cur_frm to
+				 * done and unlock semaphore on it */
+				do_gettimeofday(&common->cur_frm->ts);
+				common->cur_frm->state = VIDEOBUF_DONE;
+				wake_up_interruptible(&common->cur_frm->done);
+				/* Make cur_frm pointing to next_frm */
+				common->cur_frm = common->next_frm;
+			}
+
+			channel_first_int[i][channel_id] = 0;
+			process_progressive_mode(common);
+		} else {
+			/* Interlaced mode */
+			/* If it is first interrupt, ignore it */
+
+			if (channel_first_int[i][channel_id]) {
+				channel_first_int[i][channel_id] = 0;
+				continue;
+			}
+
+			if (0 == i) {
+				ch->field_id ^= 1;
+				/* Get field id from VPIF registers */
+				fid = vpif_channel_getfid(ch->channel_id + 2);
+				/* If fid does not match with stored field id */
+				if (fid != ch->field_id) {
+					/* Make them in sync */
+					if (0 == fid)
+						ch->field_id = fid;
+
+					return IRQ_HANDLED;
+				}
+			}
+			process_interlaced_mode(fid, common);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int vpif_get_std_info(struct channel_obj *ch)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct video_obj *vid_ch = &ch->video;
+	struct vpif_params *vpifparams = &ch->vpifparams;
+	struct vpif_channel_config_params *std_info = &vpifparams->std_info;
+	const struct vpif_channel_config_params *config;
+
+	int index;
+
+	std_info->stdid = vid_ch->stdid;
+	if (!std_info)
+		return -1;
+
+	for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
+		config = &ch_params[index];
+		if (config->stdid & std_info->stdid) {
+			memcpy(std_info, config, sizeof(*config));
+			break;
+		}
+	}
+
+	if (index == ARRAY_SIZE(ch_params))
+		return -1;
+
+	common->fmt.fmt.pix.width = std_info->width;
+	common->fmt.fmt.pix.height = std_info->height;
+	vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
+			common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
+
+	/* Set height and width paramateres */
+	ch->common[VPIF_VIDEO_INDEX].height = std_info->height;
+	ch->common[VPIF_VIDEO_INDEX].width = std_info->width;
+
+	return 0;
+}
+
+/*
+ * vpif_calculate_offsets: This function calculates buffers offset for Y and C
+ * in the top and bottom field
+ */
+static void vpif_calculate_offsets(struct channel_obj *ch)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct vpif_params *vpifparams = &ch->vpifparams;
+	enum v4l2_field field = common->fmt.fmt.pix.field;
+	struct video_obj *vid_ch = &ch->video;
+	unsigned int hpitch, vpitch, sizeimage;
+
+	if (V4L2_FIELD_ANY == common->fmt.fmt.pix.field) {
+		if (ch->vpifparams.std_info.frm_fmt)
+			vid_ch->buf_field = V4L2_FIELD_NONE;
+		else
+			vid_ch->buf_field = V4L2_FIELD_INTERLACED;
+	} else {
+		vid_ch->buf_field = common->fmt.fmt.pix.field;
+	}
+
+	if (V4L2_MEMORY_USERPTR == common->memory)
+		sizeimage = common->fmt.fmt.pix.sizeimage;
+	else
+		sizeimage = config_params.channel_bufsize[ch->channel_id];
+
+	hpitch = common->fmt.fmt.pix.bytesperline;
+	vpitch = sizeimage / (hpitch * 2);
+	if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+	    (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
+		common->ytop_off = 0;
+		common->ybtm_off = hpitch;
+		common->ctop_off = sizeimage / 2;
+		common->cbtm_off = sizeimage / 2 + hpitch;
+	} else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
+		common->ytop_off = 0;
+		common->ybtm_off = sizeimage / 4;
+		common->ctop_off = sizeimage / 2;
+		common->cbtm_off = common->ctop_off + sizeimage / 4;
+	} else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
+		common->ybtm_off = 0;
+		common->ytop_off = sizeimage / 4;
+		common->cbtm_off = sizeimage / 2;
+		common->ctop_off = common->cbtm_off + sizeimage / 4;
+	}
+
+	if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
+	    (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
+		vpifparams->video_params.storage_mode = 1;
+	} else {
+		vpifparams->video_params.storage_mode = 0;
+	}
+
+	if (ch->vpifparams.std_info.frm_fmt == 1) {
+		vpifparams->video_params.hpitch =
+		    common->fmt.fmt.pix.bytesperline;
+	} else {
+		if ((field == V4L2_FIELD_ANY) ||
+			(field == V4L2_FIELD_INTERLACED))
+			vpifparams->video_params.hpitch =
+			    common->fmt.fmt.pix.bytesperline * 2;
+		else
+			vpifparams->video_params.hpitch =
+			    common->fmt.fmt.pix.bytesperline;
+	}
+
+	ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
+}
+
+static void vpif_config_format(struct channel_obj *ch)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
+	if (config_params.numbuffers[ch->channel_id] == 0)
+		common->memory = V4L2_MEMORY_USERPTR;
+	else
+		common->memory = V4L2_MEMORY_MMAP;
+
+	common->fmt.fmt.pix.sizeimage =
+			config_params.channel_bufsize[ch->channel_id];
+	common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
+	common->fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+}
+
+static int vpif_check_format(struct channel_obj *ch,
+			     struct v4l2_pix_format *pixfmt)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	enum v4l2_field field = pixfmt->field;
+	u32 sizeimage, hpitch, vpitch;
+
+	if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
+		goto invalid_fmt_exit;
+
+	if (!(VPIF_VALID_FIELD(field)))
+		goto invalid_fmt_exit;
+
+	if (pixfmt->bytesperline <= 0)
+		goto invalid_pitch_exit;
+
+	if (V4L2_MEMORY_USERPTR == common->memory)
+		sizeimage = pixfmt->sizeimage;
+	else
+		sizeimage = config_params.channel_bufsize[ch->channel_id];
+
+	if (vpif_get_std_info(ch)) {
+		vpif_err("Error getting the standard info\n");
+		return -EINVAL;
+	}
+
+	hpitch = pixfmt->bytesperline;
+	vpitch = sizeimage / (hpitch * 2);
+
+	/* Check for valid value of pitch */
+	if ((hpitch < ch->vpifparams.std_info.width) ||
+	    (vpitch < ch->vpifparams.std_info.height))
+		goto invalid_pitch_exit;
+
+	/* Check for 8 byte alignment */
+	if (!ISALIGNED(hpitch)) {
+		vpif_err("invalid pitch alignment\n");
+		return -EINVAL;
+	}
+	pixfmt->width = common->fmt.fmt.pix.width;
+	pixfmt->height = common->fmt.fmt.pix.height;
+
+	return 0;
+
+invalid_fmt_exit:
+	vpif_err("invalid field format\n");
+	return -EINVAL;
+
+invalid_pitch_exit:
+	vpif_err("invalid pitch\n");
+	return -EINVAL;
+}
+
+static void vpif_config_addr(struct channel_obj *ch, int muxmode)
+{
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
+		common->set_addr = ch3_set_videobuf_addr;
+	} else {
+		if (2 == muxmode)
+			common->set_addr = ch2_set_videobuf_addr_yc_nmux;
+		else
+			common->set_addr = ch2_set_videobuf_addr;
+	}
+}
+
+/*
+ * vpif_mmap: It is used to map kernel space buffers into user spaces
+ */
+static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
+{
+	struct vpif_fh *fh = filep->private_data;
+	struct common_obj *common = &fh->channel->common[VPIF_VIDEO_INDEX];
+
+	return videobuf_mmap_mapper(&common->buffer_queue, vma);
+}
+
+/*
+ * vpif_poll: It is used for select/poll system call
+ */
+static unsigned int vpif_poll(struct file *filep, poll_table *wait)
+{
+	struct vpif_fh *fh = filep->private_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (common->started)
+		return videobuf_poll_stream(filep, &common->buffer_queue, wait);
+
+	return 0;
+}
+
+/*
+ * vpif_open: It creates object of file handle structure and stores it in
+ * private_data member of filepointer
+ */
+static int vpif_open(struct file *filep)
+{
+	struct video_device *vdev = video_devdata(filep);
+	struct channel_obj *ch = NULL;
+	struct vpif_fh *fh = NULL;
+
+	ch = video_get_drvdata(vdev);
+	/* Allocate memory for the file handle object */
+	fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL);
+	if (fh == NULL) {
+		vpif_err("unable to allocate memory for file handle object\n");
+		return -ENOMEM;
+	}
+
+	/* store pointer to fh in private_data member of filep */
+	filep->private_data = fh;
+	fh->channel = ch;
+	fh->initialized = 0;
+	if (!ch->initialized) {
+		fh->initialized = 1;
+		ch->initialized = 1;
+		memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
+	}
+
+	/* Increment channel usrs counter */
+	atomic_inc(&ch->usrs);
+	/* Set io_allowed[VPIF_VIDEO_INDEX] member to false */
+	fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
+	/* Initialize priority of this instance to default priority */
+	fh->prio = V4L2_PRIORITY_UNSET;
+	v4l2_prio_open(&ch->prio, &fh->prio);
+
+	return 0;
+}
+
+/*
+ * vpif_release: This function deletes buffer queue, frees the buffers and
+ * the vpif file handle
+ */
+static int vpif_release(struct file *filep)
+{
+	struct vpif_fh *fh = filep->private_data;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	/* if this instance is doing IO */
+	if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		/* Reset io_usrs member of channel object */
+		common->io_usrs = 0;
+		/* Disable channel */
+		if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
+			enable_channel2(0);
+			channel2_intr_enable(0);
+		}
+		if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
+		    (2 == common->started)) {
+			enable_channel3(0);
+			channel3_intr_enable(0);
+		}
+		common->started = 0;
+		/* Free buffers allocated */
+		videobuf_queue_cancel(&common->buffer_queue);
+		videobuf_mmap_free(&common->buffer_queue);
+		common->numbuffers =
+		    config_params.numbuffers[ch->channel_id];
+	}
+
+	mutex_unlock(&common->lock);
+
+	/* Decrement channel usrs counter */
+	atomic_dec(&ch->usrs);
+	/* If this file handle has initialize encoder device, reset it */
+	if (fh->initialized)
+		ch->initialized = 0;
+
+	/* Close the priority */
+	v4l2_prio_close(&ch->prio, &fh->prio);
+	filep->private_data = NULL;
+	fh->initialized = 0;
+	kfree(fh);
+
+	return 0;
+}
+
+/* functions implementing ioctls */
+
+static int vpif_querycap(struct file *file, void  *priv,
+				struct v4l2_capability *cap)
+{
+	struct vpif_display_config *config = vpif_dev->platform_data;
+
+	cap->version = VPIF_DISPLAY_VERSION_CODE;
+	cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+	strlcpy(cap->driver, "vpif display", sizeof(cap->driver));
+	strlcpy(cap->bus_info, "Platform", sizeof(cap->bus_info));
+	strlcpy(cap->card, config->card_name, sizeof(cap->card));
+
+	return 0;
+}
+
+static int vpif_enum_fmt_vid_out(struct file *file, void  *priv,
+					struct v4l2_fmtdesc *fmt)
+{
+	if (fmt->index != 0) {
+		vpif_err("Invalid format index\n");
+		return -EINVAL;
+	}
+
+	/* Fill in the information about format */
+	fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
+	fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
+
+	return 0;
+}
+
+static int vpif_g_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	/* Check the validity of the buffer type */
+	if (common->fmt.type != fmt->type)
+		return -EINVAL;
+
+	/* Fill in the information about format */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	if (vpif_get_std_info(ch)) {
+		vpif_err("Error getting the standard info\n");
+		return -EINVAL;
+	}
+
+	*fmt = common->fmt;
+	mutex_unlock(&common->lock);
+	return 0;
+}
+
+static int vpif_s_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpif_fh *fh = priv;
+	struct v4l2_pix_format *pixfmt;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	int ret = 0;
+
+	if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
+	    || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
+		if (!fh->initialized) {
+			vpif_dbg(1, debug, "Channel Busy\n");
+			return -EBUSY;
+		}
+
+		/* Check for the priority */
+		ret = v4l2_prio_check(&ch->prio, &fh->prio);
+		if (0 != ret)
+			return ret;
+		fh->initialized = 1;
+	}
+
+	if (common->started) {
+		vpif_dbg(1, debug, "Streaming in progress\n");
+		return -EBUSY;
+	}
+
+	pixfmt = &fmt->fmt.pix;
+	/* Check for valid field format */
+	ret = vpif_check_format(ch, pixfmt);
+	if (ret)
+		return ret;
+
+	/* store the pix format in the channel object */
+	common->fmt.fmt.pix = *pixfmt;
+	/* store the format in the channel object */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	common->fmt = *fmt;
+	mutex_unlock(&common->lock);
+
+	return 0;
+}
+
+static int vpif_try_fmt_vid_out(struct file *file, void *priv,
+				struct v4l2_format *fmt)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
+	int ret = 0;
+
+	ret = vpif_check_format(ch, pixfmt);
+	if (ret) {
+		*pixfmt = common->fmt.fmt.pix;
+		pixfmt->sizeimage = pixfmt->width * pixfmt->height * 2;
+	}
+
+	return ret;
+}
+
+static int vpif_reqbufs(struct file *file, void *priv,
+			struct v4l2_requestbuffers *reqbuf)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common;
+	enum v4l2_field field;
+	u8 index = 0;
+	int ret = 0;
+
+	/* This file handle has not initialized the channel,
+	   It is not allowed to do settings */
+	if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
+	    || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
+		if (!fh->initialized) {
+			vpif_err("Channel Busy\n");
+			return -EBUSY;
+		}
+	}
+
+	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type)
+		return -EINVAL;
+
+	index = VPIF_VIDEO_INDEX;
+
+	common = &ch->common[index];
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	if (common->fmt.type != reqbuf->type) {
+		ret = -EINVAL;
+		goto reqbuf_exit;
+	}
+
+	if (0 != common->io_usrs) {
+		ret = -EBUSY;
+		goto reqbuf_exit;
+	}
+
+	if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
+			field = V4L2_FIELD_INTERLACED;
+		else
+			field = common->fmt.fmt.pix.field;
+	} else {
+		field = V4L2_VBI_INTERLACED;
+	}
+
+	/* Initialize videobuf queue as per the buffer type */
+	videobuf_queue_dma_contig_init(&common->buffer_queue,
+					    &video_qops, NULL,
+					    &common->irqlock,
+					    reqbuf->type, field,
+					    sizeof(struct videobuf_buffer), fh);
+
+	/* Set io allowed member of file handle to TRUE */
+	fh->io_allowed[index] = 1;
+	/* Increment io usrs member of channel object to 1 */
+	common->io_usrs = 1;
+	/* Store type of memory requested in channel object */
+	common->memory = reqbuf->memory;
+	INIT_LIST_HEAD(&common->dma_queue);
+
+	/* Allocate buffers */
+	ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
+
+reqbuf_exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+static int vpif_querybuf(struct file *file, void *priv,
+				struct v4l2_buffer *tbuf)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (common->fmt.type != tbuf->type)
+		return -EINVAL;
+
+	return videobuf_querybuf(&common->buffer_queue, tbuf);
+}
+
+static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
+{
+
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct v4l2_buffer tbuf = *buf;
+	struct videobuf_buffer *buf1;
+	unsigned long addr = 0;
+	unsigned long flags;
+	int ret = 0;
+
+	if (common->fmt.type != tbuf.type)
+		return -EINVAL;
+
+	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		vpif_err("fh->io_allowed\n");
+		return -EACCES;
+	}
+
+	if (!(list_empty(&common->dma_queue)) ||
+	    (common->cur_frm != common->next_frm) ||
+	    !(common->started) ||
+	    (common->started && (0 == ch->field_id)))
+		return videobuf_qbuf(&common->buffer_queue, buf);
+
+	/* bufferqueue is empty store buffer address in VPIF registers */
+	mutex_lock(&common->buffer_queue.vb_lock);
+	buf1 = common->buffer_queue.bufs[tbuf.index];
+	if (buf1->memory != tbuf.memory) {
+		vpif_err("invalid buffer type\n");
+		goto qbuf_exit;
+	}
+
+	if ((buf1->state == VIDEOBUF_QUEUED) ||
+	    (buf1->state == VIDEOBUF_ACTIVE)) {
+		vpif_err("invalid state\n");
+		goto qbuf_exit;
+	}
+
+	switch (buf1->memory) {
+	case V4L2_MEMORY_MMAP:
+		if (buf1->baddr == 0)
+			goto qbuf_exit;
+		break;
+
+	case V4L2_MEMORY_USERPTR:
+		if (tbuf.length < buf1->bsize)
+			goto qbuf_exit;
+
+		if ((VIDEOBUF_NEEDS_INIT != buf1->state)
+			    && (buf1->baddr != tbuf.m.userptr))
+			vpif_buffer_release(&common->buffer_queue, buf1);
+			buf1->baddr = tbuf.m.userptr;
+		break;
+
+	default:
+		goto qbuf_exit;
+	}
+
+	local_irq_save(flags);
+	ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
+					common->buffer_queue.field);
+	if (ret < 0) {
+		local_irq_restore(flags);
+		goto qbuf_exit;
+	}
+
+	buf1->state = VIDEOBUF_ACTIVE;
+	addr = buf1->boff;
+	common->next_frm = buf1;
+	if (tbuf.type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
+		common->set_addr((addr + common->ytop_off),
+				 (addr + common->ybtm_off),
+				 (addr + common->ctop_off),
+				 (addr + common->cbtm_off));
+	}
+
+	local_irq_restore(flags);
+	list_add_tail(&buf1->stream, &common->buffer_queue.stream);
+	mutex_unlock(&common->buffer_queue.vb_lock);
+	return 0;
+
+qbuf_exit:
+	mutex_unlock(&common->buffer_queue.vb_lock);
+	return -EINVAL;
+}
+
+static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	int ret = 0;
+
+	if (!(*std_id & DM646X_V4L2_STD))
+		return -EINVAL;
+
+	if (common->started) {
+		vpif_err("streaming in progress\n");
+		return -EBUSY;
+	}
+
+	/* Call encoder subdevice function to set the standard */
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	ch->video.stdid = *std_id;
+	/* Get the information about the standard */
+	if (vpif_get_std_info(ch)) {
+		vpif_err("Error getting the standard info\n");
+		return -EINVAL;
+	}
+
+	if ((ch->vpifparams.std_info.width *
+		ch->vpifparams.std_info.height * 2) >
+		config_params.channel_bufsize[ch->channel_id]) {
+		vpif_err("invalid std for this size\n");
+		ret = -EINVAL;
+		goto s_std_exit;
+	}
+
+	common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
+	/* Configure the default format information */
+	vpif_config_format(ch);
+
+	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
+						s_std_output, *std_id);
+	if (ret < 0) {
+		vpif_err("Failed to set output standard\n");
+		goto s_std_exit;
+	}
+
+	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
+							s_std, *std_id);
+	if (ret < 0)
+		vpif_err("Failed to set standard for sub devices\n");
+
+s_std_exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	*std = ch->video.stdid;
+	return 0;
+}
+
+static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	return videobuf_dqbuf(&common->buffer_queue, p,
+					(file->f_flags & O_NONBLOCK));
+}
+
+static int vpif_streamon(struct file *file, void *priv,
+				enum v4l2_buf_type buftype)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
+	struct vpif_params *vpif = &ch->vpifparams;
+	struct vpif_display_config *vpif_config_data =
+					vpif_dev->platform_data;
+	unsigned long addr = 0;
+	int ret = 0;
+
+	if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		vpif_err("buffer type not supported\n");
+		return -EINVAL;
+	}
+
+	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		vpif_err("fh->io_allowed\n");
+		return -EACCES;
+	}
+
+	/* If Streaming is already started, return error */
+	if (common->started) {
+		vpif_err("channel->started\n");
+		return -EBUSY;
+	}
+
+	if ((ch->channel_id == VPIF_CHANNEL2_VIDEO
+		&& oth_ch->common[VPIF_VIDEO_INDEX].started &&
+		ch->vpifparams.std_info.ycmux_mode == 0)
+		|| ((ch->channel_id == VPIF_CHANNEL3_VIDEO)
+		&& (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
+		vpif_err("other channel is using\n");
+		return -EBUSY;
+	}
+
+	ret = vpif_check_format(ch, &common->fmt.fmt.pix);
+	if (ret < 0)
+		return ret;
+
+	/* Call videobuf_streamon to start streaming  in videobuf */
+	ret = videobuf_streamon(&common->buffer_queue);
+	if (ret < 0) {
+		vpif_err("videobuf_streamon\n");
+		return ret;
+	}
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	/* If buffer queue is empty, return error */
+	if (list_empty(&common->dma_queue)) {
+		vpif_err("buffer queue is empty\n");
+		ret = -EIO;
+		goto streamon_exit;
+	}
+
+	/* Get the next frame from the buffer queue */
+	common->next_frm = common->cur_frm =
+			    list_entry(common->dma_queue.next,
+				       struct videobuf_buffer, queue);
+
+	list_del(&common->cur_frm->queue);
+	/* Mark state of the current frame to active */
+	common->cur_frm->state = VIDEOBUF_ACTIVE;
+
+	/* Initialize field_id and started member */
+	ch->field_id = 0;
+	common->started = 1;
+	if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		addr = common->cur_frm->boff;
+		/* Calculate the offset for Y and C data  in the buffer */
+		vpif_calculate_offsets(ch);
+
+		if ((ch->vpifparams.std_info.frm_fmt &&
+			((common->fmt.fmt.pix.field != V4L2_FIELD_NONE)
+			&& (common->fmt.fmt.pix.field != V4L2_FIELD_ANY)))
+			|| (!ch->vpifparams.std_info.frm_fmt
+			&& (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
+			vpif_err("conflict in field format and std format\n");
+			ret = -EINVAL;
+			goto streamon_exit;
+		}
+
+		/* clock settings */
+		ret =
+		 vpif_config_data->set_clock(ch->vpifparams.std_info.ycmux_mode,
+						ch->vpifparams.std_info.hd_sd);
+		if (ret < 0) {
+			vpif_err("can't set clock\n");
+			goto streamon_exit;
+		}
+
+		/* set the parameters and addresses */
+		ret = vpif_set_video_params(vpif, ch->channel_id + 2);
+		if (ret < 0)
+			goto streamon_exit;
+
+		common->started = ret;
+		vpif_config_addr(ch, ret);
+		common->set_addr((addr + common->ytop_off),
+				 (addr + common->ybtm_off),
+				 (addr + common->ctop_off),
+				 (addr + common->cbtm_off));
+
+		/* Set interrupt for both the fields in VPIF
+		   Register enable channel in VPIF register */
+		if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
+			channel2_intr_assert();
+			channel2_intr_enable(1);
+			enable_channel2(1);
+		}
+
+		if ((VPIF_CHANNEL3_VIDEO == ch->channel_id)
+			|| (common->started == 2)) {
+			channel3_intr_assert();
+			channel3_intr_enable(1);
+			enable_channel3(1);
+		}
+		channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
+	}
+
+streamon_exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+static int vpif_streamoff(struct file *file, void *priv,
+				enum v4l2_buf_type buftype)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+
+	if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		vpif_err("buffer type not supported\n");
+		return -EINVAL;
+	}
+
+	if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
+		vpif_err("fh->io_allowed\n");
+		return -EACCES;
+	}
+
+	if (!common->started) {
+		vpif_err("channel->started\n");
+		return -EINVAL;
+	}
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
+		/* disable channel */
+		if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
+			enable_channel2(0);
+			channel2_intr_enable(0);
+		}
+		if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
+					(2 == common->started)) {
+			enable_channel3(0);
+			channel3_intr_enable(0);
+		}
+	}
+
+	common->started = 0;
+	mutex_unlock(&common->lock);
+
+	return videobuf_streamoff(&common->buffer_queue);
+}
+
+static int vpif_cropcap(struct file *file, void *priv,
+			struct v4l2_cropcap *crop)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type)
+		return -EINVAL;
+
+	crop->bounds.left = crop->bounds.top = 0;
+	crop->defrect.left = crop->defrect.top = 0;
+	crop->defrect.height = crop->bounds.height = common->height;
+	crop->defrect.width = crop->bounds.width = common->width;
+
+	return 0;
+}
+
+static int vpif_enum_output(struct file *file, void *fh,
+				struct v4l2_output *output)
+{
+
+	struct vpif_display_config *config = vpif_dev->platform_data;
+
+	if (output->index >= config->output_count) {
+		vpif_dbg(1, debug, "Invalid output index\n");
+		return -EINVAL;
+	}
+
+	strcpy(output->name, config->output[output->index]);
+	output->type = V4L2_OUTPUT_TYPE_ANALOG;
+	output->std = DM646X_V4L2_STD;
+
+	return 0;
+}
+
+static int vpif_s_output(struct file *file, void *priv, unsigned int i)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+	struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+	int ret = 0;
+
+	if (mutex_lock_interruptible(&common->lock))
+		return -ERESTARTSYS;
+
+	if (common->started) {
+		vpif_err("Streaming in progress\n");
+		ret = -EBUSY;
+		goto s_output_exit;
+	}
+
+	ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
+							s_routing, 0, i, 0);
+
+	if (ret < 0)
+		vpif_err("Failed to set output standard\n");
+
+	vid_ch->output_id = i;
+
+s_output_exit:
+	mutex_unlock(&common->lock);
+	return ret;
+}
+
+static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+	struct video_obj *vid_ch = &ch->video;
+
+	*i = vid_ch->output_id;
+
+	return 0;
+}
+
+static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	*p = v4l2_prio_max(&ch->prio);
+
+	return 0;
+}
+
+static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
+{
+	struct vpif_fh *fh = priv;
+	struct channel_obj *ch = fh->channel;
+
+	return v4l2_prio_change(&ch->prio, &fh->prio, p);
+}
+
+/* vpif display ioctl operations */
+static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
+	.vidioc_querycap        	= vpif_querycap,
+	.vidioc_g_priority		= vpif_g_priority,
+	.vidioc_s_priority		= vpif_s_priority,
+	.vidioc_enum_fmt_vid_out	= vpif_enum_fmt_vid_out,
+	.vidioc_g_fmt_vid_out  		= vpif_g_fmt_vid_out,
+	.vidioc_s_fmt_vid_out   	= vpif_s_fmt_vid_out,
+	.vidioc_try_fmt_vid_out 	= vpif_try_fmt_vid_out,
+	.vidioc_reqbufs         	= vpif_reqbufs,
+	.vidioc_querybuf        	= vpif_querybuf,
+	.vidioc_qbuf            	= vpif_qbuf,
+	.vidioc_dqbuf           	= vpif_dqbuf,
+	.vidioc_streamon        	= vpif_streamon,
+	.vidioc_streamoff       	= vpif_streamoff,
+	.vidioc_s_std           	= vpif_s_std,
+	.vidioc_g_std			= vpif_g_std,
+	.vidioc_enum_output		= vpif_enum_output,
+	.vidioc_s_output		= vpif_s_output,
+	.vidioc_g_output		= vpif_g_output,
+	.vidioc_cropcap         	= vpif_cropcap,
+};
+
+static const struct v4l2_file_operations vpif_fops = {
+	.owner		= THIS_MODULE,
+	.open		= vpif_open,
+	.release	= vpif_release,
+	.ioctl		= video_ioctl2,
+	.mmap		= vpif_mmap,
+	.poll		= vpif_poll
+};
+
+static struct video_device vpif_video_template = {
+	.name		= "vpif",
+	.fops		= &vpif_fops,
+	.minor		= -1,
+	.ioctl_ops	= &vpif_ioctl_ops,
+	.tvnorms	= DM646X_V4L2_STD,
+	.current_norm	= V4L2_STD_625_50,
+
+};
+
+/*Configure the channels, buffer sizei, request irq */
+static int initialize_vpif(void)
+{
+	int free_channel_objects_index;
+	int free_buffer_channel_index;
+	int free_buffer_index;
+	int err = 0, i, j;
+
+	/* Default number of buffers should be 3 */
+	if ((ch2_numbuffers > 0) &&
+	    (ch2_numbuffers < config_params.min_numbuffers))
+		ch2_numbuffers = config_params.min_numbuffers;
+	if ((ch3_numbuffers > 0) &&
+	    (ch3_numbuffers < config_params.min_numbuffers))
+		ch3_numbuffers = config_params.min_numbuffers;
+
+	/* Set buffer size to min buffers size if invalid buffer size is
+	 * given */
+	if (ch2_bufsize < config_params.min_bufsize[VPIF_CHANNEL2_VIDEO])
+		ch2_bufsize =
+		    config_params.min_bufsize[VPIF_CHANNEL2_VIDEO];
+	if (ch3_bufsize < config_params.min_bufsize[VPIF_CHANNEL3_VIDEO])
+		ch3_bufsize =
+		    config_params.min_bufsize[VPIF_CHANNEL3_VIDEO];
+
+	config_params.numbuffers[VPIF_CHANNEL2_VIDEO] = ch2_numbuffers;
+
+	if (ch2_numbuffers) {
+		config_params.channel_bufsize[VPIF_CHANNEL2_VIDEO] =
+							ch2_bufsize;
+	}
+	config_params.numbuffers[VPIF_CHANNEL3_VIDEO] = ch3_numbuffers;
+
+	if (ch3_numbuffers) {
+		config_params.channel_bufsize[VPIF_CHANNEL3_VIDEO] =
+							ch3_bufsize;
+	}
+
+	/* Allocate memory for six channel objects */
+	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+		vpif_obj.dev[i] =
+		    kmalloc(sizeof(struct channel_obj), GFP_KERNEL);
+		/* If memory allocation fails, return error */
+		if (!vpif_obj.dev[i]) {
+			free_channel_objects_index = i;
+			err = -ENOMEM;
+			goto vpif_init_free_channel_objects;
+		}
+	}
+
+	free_channel_objects_index = VPIF_DISPLAY_MAX_DEVICES;
+	free_buffer_channel_index = VPIF_DISPLAY_NUM_CHANNELS;
+	free_buffer_index = config_params.numbuffers[i - 1];
+
+	return 0;
+
+vpif_init_free_channel_objects:
+	for (j = 0; j < free_channel_objects_index; j++)
+		kfree(vpif_obj.dev[j]);
+	return err;
+}
+
+/*
+ * vpif_probe: This function creates device entries by register itself to the
+ * V4L2 driver and initializes fields of each channel objects
+ */
+static __init int vpif_probe(struct platform_device *pdev)
+{
+	struct vpif_subdev_info *subdevdata;
+	struct vpif_display_config *config;
+	int i, j = 0, k, q, m, err = 0;
+	struct i2c_adapter *i2c_adap;
+	struct vpif_config *config;
+	struct common_obj *common;
+	struct channel_obj *ch;
+	struct video_device *vfd;
+	struct resource *res;
+	int subdev_count;
+
+	vpif_dev = &pdev->dev;
+
+	err = initialize_vpif();
+
+	if (err) {
+		v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
+		return err;
+	}
+
+	err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
+	if (err) {
+		v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
+		return err;
+	}
+
+	k = 0;
+	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
+		for (i = res->start; i <= res->end; i++) {
+			if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
+					"DM646x_Display",
+				(void *)(&vpif_obj.dev[k]->channel_id))) {
+				err = -EBUSY;
+				goto vpif_int_err;
+			}
+		}
+		k++;
+	}
+
+	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+
+		/* Get the pointer to the channel object */
+		ch = vpif_obj.dev[i];
+
+		/* Allocate memory for video device */
+		vfd = video_device_alloc();
+		if (vfd == NULL) {
+			for (j = 0; j < i; j++) {
+				ch = vpif_obj.dev[j];
+				video_device_release(ch->video_dev);
+			}
+			err = -ENOMEM;
+			goto vpif_int_err;
+		}
+
+		/* Initialize field of video device */
+		*vfd = vpif_video_template;
+		vfd->v4l2_dev = &vpif_obj.v4l2_dev;
+		vfd->release = video_device_release;
+		snprintf(vfd->name, sizeof(vfd->name),
+			 "DM646x_VPIFDisplay_DRIVER_V%d.%d.%d",
+			 (VPIF_DISPLAY_VERSION_CODE >> 16) & 0xff,
+			 (VPIF_DISPLAY_VERSION_CODE >> 8) & 0xff,
+			 (VPIF_DISPLAY_VERSION_CODE) & 0xff);
+
+		/* Set video_dev to the video device */
+		ch->video_dev = vfd;
+	}
+
+	for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
+		ch = vpif_obj.dev[j];
+		/* Initialize field of the channel objects */
+		atomic_set(&ch->usrs, 0);
+		for (k = 0; k < VPIF_NUMOBJECTS; k++) {
+			ch->common[k].numbuffers = 0;
+			common = &ch->common[k];
+			common->io_usrs = 0;
+			common->started = 0;
+			spin_lock_init(&common->irqlock);
+			mutex_init(&common->lock);
+			common->numbuffers = 0;
+			common->set_addr = NULL;
+			common->ytop_off = common->ybtm_off = 0;
+			common->ctop_off = common->cbtm_off = 0;
+			common->cur_frm = common->next_frm = NULL;
+			memset(&common->fmt, 0, sizeof(common->fmt));
+			common->numbuffers = config_params.numbuffers[k];
+
+		}
+		ch->initialized = 0;
+		ch->channel_id = j;
+		if (j < 2)
+			ch->common[VPIF_VIDEO_INDEX].numbuffers =
+			    config_params.numbuffers[ch->channel_id];
+		else
+			ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;
+
+		memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
+
+		/* Initialize prio member of channel object */
+		v4l2_prio_init(&ch->prio);
+		ch->common[VPIF_VIDEO_INDEX].fmt.type =
+						V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+		/* register video device */
+		vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
+				(int)ch, (int)&ch->video_dev);
+
+		err = video_register_device(ch->video_dev,
+					  VFL_TYPE_GRABBER, (j ? 3 : 2));
+		if (err < 0)
+			goto probe_out;
+
+		video_set_drvdata(ch->video_dev, ch);
+	}
+
+	i2c_adap = i2c_get_adapter(1);
+	config = pdev->dev.platform_data;
+	subdev_count = config->subdev_count;
+	subdevdata = config->subdevinfo;
+	vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
+								GFP_KERNEL);
+	if (vpif_obj.sd == NULL) {
+		vpif_err("unable to allocate memory for subdevice pointers\n");
+		err = -ENOMEM;
+		goto probe_out;
+	}
+
+	for (i = 0; i < subdev_count; i++) {
+		vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
+						i2c_adap, subdevdata[i].name,
+						&subdevdata[i].board_info,
+						NULL);
+		if (!vpif_obj.sd[i]) {
+			vpif_err("Error registering v4l2 subdevice\n");
+			goto probe_subdev_out;
+		}
+
+		if (vpif_obj.sd[i])
+			vpif_obj.sd[i]->grp_id = 1 << i;
+	}
+
+	return 0;
+
+probe_subdev_out:
+	kfree(vpif_obj.sd);
+probe_out:
+	for (k = 0; k < j; k++) {
+		ch = vpif_obj.dev[k];
+		video_unregister_device(ch->video_dev);
+		video_device_release(ch->video_dev);
+		ch->video_dev = NULL;
+	}
+vpif_int_err:
+	v4l2_device_unregister(&vpif_obj.v4l2_dev);
+	vpif_err("VPIF IRQ request failed\n");
+	for (q = k; k >= 0; k--) {
+		for (m = i; m >= res->start; m--)
+			free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
+		m = res->end;
+	}
+
+	return err;
+}
+
+/*
+ * vpif_remove: It un-register channels from V4L2 driver
+ */
+static int vpif_remove(struct platform_device *device)
+{
+	struct channel_obj *ch;
+	int i;
+
+	v4l2_device_unregister(&vpif_obj.v4l2_dev);
+
+	/* un-register device */
+	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
+		/* Get the pointer to the channel object */
+		ch = vpif_obj.dev[i];
+		/* Unregister video device */
+		video_unregister_device(ch->video_dev);
+
+		ch->video_dev = NULL;
+	}
+
+	return 0;
+}
+
+static struct platform_driver vpif_driver = {
+	.driver	= {
+			.name	= "vpif_display",
+			.owner	= THIS_MODULE,
+	},
+	.probe	= vpif_probe,
+	.remove	= vpif_remove,
+};
+
+static __init int vpif_init(void)
+{
+	return platform_driver_register(&vpif_driver);
+}
+
+/*
+ * vpif_cleanup: This function un-registers device and driver to the kernel,
+ * frees requested irq handler and de-allocates memory allocated for channel
+ * objects.
+ */
+static void vpif_cleanup(void)
+{
+	struct platform_device *pdev;
+	struct resource *res;
+	int irq_num;
+	int i = 0;
+
+	pdev = container_of(vpif_dev, struct platform_device, dev);
+
+	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
+		for (irq_num = res->start; irq_num <= res->end; irq_num++)
+			free_irq(irq_num,
+				 (void *)(&vpif_obj.dev[i]->channel_id));
+		i++;
+	}
+
+	platform_driver_unregister(&vpif_driver);
+	kfree(vpif_obj.sd);
+	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
+		kfree(vpif_obj.dev[i]);
+}
+
+module_init(vpif_init);
+module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h
new file mode 100644
index 0000000..a2a7cd1
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_display.h
@@ -0,0 +1,175 @@
+/*
+ * DM646x display header file
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef DAVINCIHD_DISPLAY_H
+#define DAVINCIHD_DISPLAY_H
+
+/* Header files */
+#include <linux/videodev2.h>
+#include <linux/version.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf-core.h>
+#include <media/videobuf-dma-contig.h>
+
+#include "vpif.h"
+
+/* Macros */
+#define VPIF_MAJOR_RELEASE	(0)
+#define VPIF_MINOR_RELEASE	(0)
+#define VPIF_BUILD		(1)
+
+#define VPIF_DISPLAY_VERSION_CODE \
+	((VPIF_MAJOR_RELEASE << 16) | (VPIF_MINOR_RELEASE << 8) | VPIF_BUILD)
+
+#define VPIF_VALID_FIELD(field) \
+	(((V4L2_FIELD_ANY == field) || (V4L2_FIELD_NONE == field)) || \
+	(((V4L2_FIELD_INTERLACED == field) || (V4L2_FIELD_SEQ_TB == field)) || \
+	(V4L2_FIELD_SEQ_BT == field)))
+
+#define VPIF_DISPLAY_MAX_DEVICES	(2)
+#define VPIF_SLICED_BUF_SIZE		(256)
+#define VPIF_SLICED_MAX_SERVICES	(3)
+#define VPIF_VIDEO_INDEX		(0)
+#define VPIF_VBI_INDEX			(1)
+#define VPIF_HBI_INDEX			(2)
+
+/* Setting it to 1 as HBI/VBI support yet to be added , else 3*/
+#define VPIF_NUMOBJECTS	(1)
+
+/* Macros */
+#define ISALIGNED(a)    (0 == ((a) & 7))
+
+/* enumerated data types */
+/* Enumerated data type to give id to each device per channel */
+enum vpif_channel_id {
+	VPIF_CHANNEL2_VIDEO = 0,	/* Channel2 Video */
+	VPIF_CHANNEL3_VIDEO,		/* Channel3 Video */
+};
+
+/* structures */
+
+struct video_obj {
+	enum v4l2_field buf_field;
+	u32 latest_only;		/* indicate whether to return
+					 * most recent displayed frame only */
+	v4l2_std_id stdid;		/* Currently selected or default
+					 * standard */
+	u32 output_id;			/* Current output id */
+};
+
+struct vbi_obj {
+	int num_services;
+	struct vpif_vbi_params vbiparams;	/* vpif parameters for the raw
+						 * vbi data */
+};
+
+struct common_obj {
+	/* Buffer specific parameters */
+	u8 *fbuffers[VIDEO_MAX_FRAME];		/* List of buffer pointers for
+						 * storing frames */
+	u32 numbuffers;				/* number of buffers */
+	struct videobuf_buffer *cur_frm;	/* Pointer pointing to current
+						 * videobuf_buffer */
+	struct videobuf_buffer *next_frm;	/* Pointer pointing to next
+						 * videobuf_buffer */
+	enum v4l2_memory memory;		/* This field keeps track of
+						 * type of buffer exchange
+						 * method user has selected */
+	struct v4l2_format fmt;			/* Used to store the format */
+	struct videobuf_queue buffer_queue;	/* Buffer queue used in
+						 * video-buf */
+	struct list_head dma_queue;		/* Queue of filled frames */
+	spinlock_t irqlock;			/* Used in video-buf */
+
+	/* channel specific parameters */
+	struct mutex lock;			/* lock used to access this
+						 * structure */
+	u32 io_usrs;				/* number of users performing
+						 * IO */
+	u8 started;				/* Indicates whether streaming
+						 * started */
+	u32 ytop_off;				/* offset of Y top from the
+						 * starting of the buffer */
+	u32 ybtm_off;				/* offset of Y bottom from the
+						 * starting of the buffer */
+	u32 ctop_off;				/* offset of C top from the
+						 * starting of the buffer */
+	u32 cbtm_off;				/* offset of C bottom from the
+						 * starting of the buffer */
+	/* Function pointer to set the addresses */
+	void (*set_addr) (unsigned long, unsigned long,
+				unsigned long, unsigned long);
+	u32 height;
+	u32 width;
+};
+
+struct channel_obj {
+	/* V4l2 specific parameters */
+	struct video_device *video_dev;	/* Identifies video device for
+					 * this channel */
+	struct v4l2_prio_state prio;	/* Used to keep track of state of
+					 * the priority */
+	atomic_t usrs;			/* number of open instances of
+					 * the channel */
+	u32 field_id;			/* Indicates id of the field
+					 * which is being displayed */
+	u8 initialized;			/* flag to indicate whether
+					 * encoder is initialized */
+
+	enum vpif_channel_id channel_id;/* Identifies channel */
+	struct vpif_params vpifparams;
+	struct common_obj common[VPIF_NUMOBJECTS];
+	struct video_obj video;
+	struct vbi_obj vbi;
+};
+
+/* File handle structure */
+struct vpif_fh {
+	struct channel_obj *channel;	/* pointer to channel object for
+					 * opened device */
+	u8 io_allowed[VPIF_NUMOBJECTS];	/* Indicates whether this file handle
+					 * is doing IO */
+	enum v4l2_priority prio;	/* Used to keep track priority of
+					 * this instance */
+	u8 initialized;			/* Used to keep track of whether this
+					 * file handle has initialized
+					 * channel or not */
+};
+
+/* vpif device structure */
+struct vpif_device {
+	struct v4l2_device v4l2_dev;
+	struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
+	struct v4l2_subdev **sd;
+
+};
+
+struct vpif_config_params {
+	u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
+	u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
+	u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
+	u8 min_numbuffers;
+};
+
+/* Struct which keeps track of the line numbers for the sliced vbi service */
+struct vpif_service_line {
+	u16 service_id;
+	u16 service_line[2];
+	u16 enc_service_id;
+	u8 bytestowrite;
+};
+
+#endif				/* DAVINCIHD_DISPLAY_H */
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
new file mode 100644
index 0000000..6d709ca
--- /dev/null
+++ b/drivers/media/video/davinci/vpss.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2009 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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.
+ *
+ * common vpss driver for all video drivers.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <media/davinci/vpss.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("VPSS Driver");
+MODULE_AUTHOR("Texas Instruments");
+
+/* DM644x defines */
+#define DM644X_SBL_PCR_VPSS		(4)
+
+/* vpss BL register offsets */
+#define DM355_VPSSBL_CCDCMUX		0x1c
+/* vpss CLK register offsets */
+#define DM355_VPSSCLK_CLKCTRL		0x04
+/* masks and shifts */
+#define VPSS_HSSISEL_SHIFT		4
+
+/*
+ * vpss operations. Depends on platform. Not all functions are available
+ * on all platforms. The api, first check if a functio is available before
+ * invoking it. In the probe, the function ptrs are intialized based on
+ * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
+ */
+struct vpss_hw_ops {
+	/* enable clock */
+	int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
+	/* select input to ccdc */
+	void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
+	/* clear wbl overlflow bit */
+	int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
+};
+
+/* vpss configuration */
+struct vpss_oper_config {
+	__iomem void *vpss_bl_regs_base;
+	__iomem void *vpss_regs_base;
+	struct resource		*r1;
+	resource_size_t		len1;
+	struct resource		*r2;
+	resource_size_t		len2;
+	char vpss_name[32];
+	spinlock_t vpss_lock;
+	struct vpss_hw_ops hw_ops;
+};
+
+static struct vpss_oper_config oper_cfg;
+
+/* register access routines */
+static inline u32 bl_regr(u32 offset)
+{
+	return __raw_readl(oper_cfg.vpss_bl_regs_base + offset);
+}
+
+static inline void bl_regw(u32 val, u32 offset)
+{
+	__raw_writel(val, oper_cfg.vpss_bl_regs_base + offset);
+}
+
+static inline u32 vpss_regr(u32 offset)
+{
+	return __raw_readl(oper_cfg.vpss_regs_base + offset);
+}
+
+static inline void vpss_regw(u32 val, u32 offset)
+{
+	__raw_writel(val, oper_cfg.vpss_regs_base + offset);
+}
+
+static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
+{
+	bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
+}
+
+int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
+{
+	if (!oper_cfg.hw_ops.select_ccdc_source)
+		return -1;
+
+	dm355_select_ccdc_source(src_sel);
+	return 0;
+}
+EXPORT_SYMBOL(vpss_select_ccdc_source);
+
+static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
+{
+	u32 mask = 1, val;
+
+	if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
+	    wbl_sel > VPSS_PCR_CCDC_WBL_O)
+		return -1;
+
+	/* writing a 0 clear the overflow */
+	mask = ~(mask << wbl_sel);
+	val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
+	bl_regw(val, DM644X_SBL_PCR_VPSS);
+	return 0;
+}
+
+int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
+{
+	if (!oper_cfg.hw_ops.clear_wbl_overflow)
+		return -1;
+
+	return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
+}
+EXPORT_SYMBOL(vpss_clear_wbl_overflow);
+
+/*
+ *  dm355_enable_clock - Enable VPSS Clock
+ *  @clock_sel: CLock to be enabled/disabled
+ *  @en: enable/disable flag
+ *
+ *  This is called to enable or disable a vpss clock
+ */
+static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
+{
+	unsigned long flags;
+	u32 utemp, mask = 0x1, shift = 0;
+
+	switch (clock_sel) {
+	case VPSS_VPBE_CLOCK:
+		/* nothing since lsb */
+		break;
+	case VPSS_VENC_CLOCK_SEL:
+		shift = 2;
+		break;
+	case VPSS_CFALD_CLOCK:
+		shift = 3;
+		break;
+	case VPSS_H3A_CLOCK:
+		shift = 4;
+		break;
+	case VPSS_IPIPE_CLOCK:
+		shift = 5;
+		break;
+	case VPSS_CCDC_CLOCK:
+		shift = 6;
+		break;
+	default:
+		printk(KERN_ERR "dm355_enable_clock:"
+				" Invalid selector: %d\n", clock_sel);
+		return -1;
+	}
+
+	spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
+	utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
+	if (!en)
+		utemp &= ~(mask << shift);
+	else
+		utemp |= (mask << shift);
+
+	vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
+	spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
+	return 0;
+}
+
+int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
+{
+	if (!oper_cfg.hw_ops.enable_clock)
+		return -1;
+
+	return oper_cfg.hw_ops.enable_clock(clock_sel, en);
+}
+EXPORT_SYMBOL(vpss_enable_clock);
+
+static int __init vpss_probe(struct platform_device *pdev)
+{
+	int status, dm355 = 0;
+
+	if (!pdev->dev.platform_data) {
+		dev_err(&pdev->dev, "no platform data\n");
+		return -ENOENT;
+	}
+	strcpy(oper_cfg.vpss_name, pdev->dev.platform_data);
+
+	if (!strcmp(oper_cfg.vpss_name, "dm355_vpss"))
+		dm355 = 1;
+	else if (strcmp(oper_cfg.vpss_name, "dm644x_vpss")) {
+		dev_err(&pdev->dev, "vpss driver not supported on"
+			" this platform\n");
+		return -ENODEV;
+	}
+
+	dev_info(&pdev->dev, "%s vpss probed\n", oper_cfg.vpss_name);
+	oper_cfg.r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!oper_cfg.r1)
+		return -ENOENT;
+
+	oper_cfg.len1 = oper_cfg.r1->end - oper_cfg.r1->start + 1;
+
+	oper_cfg.r1 = request_mem_region(oper_cfg.r1->start, oper_cfg.len1,
+					 oper_cfg.r1->name);
+	if (!oper_cfg.r1)
+		return -EBUSY;
+
+	oper_cfg.vpss_bl_regs_base = ioremap(oper_cfg.r1->start, oper_cfg.len1);
+	if (!oper_cfg.vpss_bl_regs_base) {
+		status = -EBUSY;
+		goto fail1;
+	}
+
+	if (dm355) {
+		oper_cfg.r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+		if (!oper_cfg.r2) {
+			status = -ENOENT;
+			goto fail2;
+		}
+		oper_cfg.len2 = oper_cfg.r2->end - oper_cfg.r2->start + 1;
+		oper_cfg.r2 = request_mem_region(oper_cfg.r2->start,
+						 oper_cfg.len2,
+						 oper_cfg.r2->name);
+		if (!oper_cfg.r2) {
+			status = -EBUSY;
+			goto fail2;
+		}
+
+		oper_cfg.vpss_regs_base = ioremap(oper_cfg.r2->start,
+						  oper_cfg.len2);
+		if (!oper_cfg.vpss_regs_base) {
+			status = -EBUSY;
+			goto fail3;
+		}
+	}
+
+	if (dm355) {
+		oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
+		oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
+	} else
+		oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
+
+	spin_lock_init(&oper_cfg.vpss_lock);
+	dev_info(&pdev->dev, "%s vpss probe success\n", oper_cfg.vpss_name);
+	return 0;
+
+fail3:
+	release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
+fail2:
+	iounmap(oper_cfg.vpss_bl_regs_base);
+fail1:
+	release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
+	return status;
+}
+
+static int vpss_remove(struct platform_device *pdev)
+{
+	iounmap(oper_cfg.vpss_bl_regs_base);
+	release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
+	if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) {
+		iounmap(oper_cfg.vpss_regs_base);
+		release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
+	}
+	return 0;
+}
+
+static struct platform_driver vpss_driver = {
+	.driver = {
+		.name	= "vpss",
+		.owner = THIS_MODULE,
+	},
+	.remove = __devexit_p(vpss_remove),
+	.probe = vpss_probe,
+};
+
+static void vpss_exit(void)
+{
+	platform_driver_unregister(&vpss_driver);
+}
+
+static int __init vpss_init(void)
+{
+	return platform_driver_register(&vpss_driver);
+}
+subsys_initcall(vpss_init);
+module_exit(vpss_exit);
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 6524b49..c7be0e0 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -36,6 +36,7 @@ config VIDEO_EM28XX_DVB
 	depends on VIDEO_EM28XX && DVB_CORE
 	select DVB_LGDT330X if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
 	select VIDEOBUF_DVB
 	---help---
 	  This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
index 8137a8c..d0f093d 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/video/em28xx/Makefile
@@ -1,5 +1,5 @@
 em28xx-objs     := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
-		   em28xx-input.o
+		   em28xx-input.o em28xx-vbi.o
 
 em28xx-alsa-objs := em28xx-audio.o
 
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 1c2e544..bdb249b 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -170,6 +170,19 @@ static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
 	{	-1,		-1,	-1,		-1},
 };
 
+/* eb1a:2868 Reddo DVB-C USB TV Box
+   GPIO4 - CU1216L NIM
+   Other GPIOs seems to be don't care. */
+static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
+	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
+	{EM28XX_R08_GPIO,	0xde,	0xff,		10},
+	{EM28XX_R08_GPIO,	0xfe,	0xff,		10},
+	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{EM28XX_R08_GPIO,	0x7f,	0xff,		10},
+	{EM28XX_R08_GPIO,	0x6f,	0xff,		10},
+	{EM28XX_R08_GPIO,	0xff,	0xff,		10},
+	{-1,			-1,	-1,		-1},
+};
 
 /* Callback for the most boards */
 static struct em28xx_reg_seq default_tuner_gpio[] = {
@@ -299,6 +312,7 @@ struct em28xx_board em28xx_boards[] = {
 	[EM2820_BOARD_TERRATEC_CINERGY_250] = {
 		.name         = "Terratec Cinergy 250 USB",
 		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
+		.has_ir_i2c   = 1,
 		.tda9887_conf = TDA9887_PRESENT,
 		.decoder      = EM28XX_SAA711X,
 		.input        = { {
@@ -318,6 +332,7 @@ struct em28xx_board em28xx_boards[] = {
 	[EM2820_BOARD_PINNACLE_USB_2] = {
 		.name         = "Pinnacle PCTV USB 2",
 		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
+		.has_ir_i2c   = 1,
 		.tda9887_conf = TDA9887_PRESENT,
 		.decoder      = EM28XX_SAA711X,
 		.input        = { {
@@ -342,6 +357,7 @@ struct em28xx_board em28xx_boards[] = {
 				TDA9887_PORT2_ACTIVE,
 		.decoder      = EM28XX_TVP5150,
 		.has_msp34xx  = 1,
+		.has_ir_i2c   = 1,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -558,6 +574,27 @@ struct em28xx_board em28xx_boards[] = {
 			.amux     = EM28XX_AMUX_LINE_IN,
 		} },
 	},
+	[EM2861_BOARD_GADMEI_UTV330PLUS] = {
+		.name         = "Gadmei UTV330+",
+		.tuner_type   = TUNER_TNF_5335MF,
+		.tda9887_conf = TDA9887_PRESENT,
+		.ir_codes     = &ir_codes_gadmei_rm008z_table,
+		.decoder      = EM28XX_SAA711X,
+		.xclk         = EM28XX_XCLK_FREQUENCY_12MHZ,
+		.input        = { {
+			.type     = EM28XX_VMUX_TELEVISION,
+			.vmux     = SAA7115_COMPOSITE2,
+			.amux     = EM28XX_AMUX_VIDEO,
+		}, {
+			.type     = EM28XX_VMUX_COMPOSITE1,
+			.vmux     = SAA7115_COMPOSITE0,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		}, {
+			.type     = EM28XX_VMUX_SVIDEO,
+			.vmux     = SAA7115_SVIDEO3,
+			.amux     = EM28XX_AMUX_LINE_IN,
+		} },
+	},
 	[EM2860_BOARD_TERRATEC_HYBRID_XS] = {
 		.name         = "Terratec Cinergy A Hybrid XS",
 		.valid        = EM28XX_BOARD_NOT_VALIDATED,
@@ -715,7 +752,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware = 1,
 		.has_dvb      = 1,
 		.dvb_gpio     = hauppauge_wintv_hvr_900_digital,
-		.ir_codes     = ir_codes_hauppauge_new,
+		.ir_codes     = &ir_codes_hauppauge_new_table,
 		.decoder      = EM28XX_TVP5150,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -740,7 +777,7 @@ struct em28xx_board em28xx_boards[] = {
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.mts_firmware = 1,
-		.ir_codes     = ir_codes_hauppauge_new,
+		.ir_codes     = &ir_codes_hauppauge_new_table,
 		.decoder      = EM28XX_TVP5150,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -766,7 +803,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware   = 1,
 		.has_dvb        = 1,
 		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
-		.ir_codes       = ir_codes_hauppauge_new,
+		.ir_codes       = &ir_codes_hauppauge_new_table,
 		.decoder        = EM28XX_TVP5150,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -792,7 +829,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware   = 1,
 		.has_dvb        = 1,
 		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
-		.ir_codes       = ir_codes_hauppauge_new,
+		.ir_codes       = &ir_codes_hauppauge_new_table,
 		.decoder        = EM28XX_TVP5150,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -818,7 +855,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware   = 1,
 		.has_dvb        = 1,
 		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
-		.ir_codes       = ir_codes_pinnacle_pctv_hd,
+		.ir_codes       = &ir_codes_pinnacle_pctv_hd_table,
 		.decoder        = EM28XX_TVP5150,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -844,7 +881,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware   = 1,
 		.has_dvb        = 1,
 		.dvb_gpio       = hauppauge_wintv_hvr_900_digital,
-		.ir_codes       = ir_codes_ati_tv_wonder_hd_600,
+		.ir_codes       = &ir_codes_ati_tv_wonder_hd_600_table,
 		.decoder        = EM28XX_TVP5150,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -870,6 +907,8 @@ struct em28xx_board em28xx_boards[] = {
 		.decoder        = EM28XX_TVP5150,
 		.has_dvb        = 1,
 		.dvb_gpio       = default_digital,
+		.ir_codes       = &ir_codes_terratec_cinergy_xs_table,
+		.xclk           = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -937,6 +976,7 @@ struct em28xx_board em28xx_boards[] = {
 	[EM2800_BOARD_TERRATEC_CINERGY_200] = {
 		.name         = "Terratec Cinergy 200 USB",
 		.is_em2800    = 1,
+		.has_ir_i2c   = 1,
 		.tuner_type   = TUNER_LG_PAL_NEW_TAPC,
 		.tda9887_conf = TDA9887_PRESENT,
 		.decoder      = EM28XX_SAA711X,
@@ -1010,7 +1050,8 @@ struct em28xx_board em28xx_boards[] = {
 		} },
 	},
 	[EM2820_BOARD_PINNACLE_DVC_90] = {
-		.name         = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker",
+		.name         = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker "
+				"/ Kworld DVD Maker 2",
 		.tuner_type   = TUNER_ABSENT, /* capture only board */
 		.decoder      = EM28XX_SAA711X,
 		.input        = { {
@@ -1420,7 +1461,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware = 1,
 		.decoder      = EM28XX_TVP5150,
 		.tuner_gpio   = default_tuner_gpio,
-		.ir_codes     = ir_codes_kaiomy,
+		.ir_codes     = &ir_codes_kaiomy_table,
 		.input          = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -1520,7 +1561,7 @@ struct em28xx_board em28xx_boards[] = {
 		.mts_firmware = 1,
 		.has_dvb      = 1,
 		.dvb_gpio     = evga_indtube_digital,
-		.ir_codes     = ir_codes_evga_indtube,
+		.ir_codes     = &ir_codes_evga_indtube_table,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
 			.vmux     = TVP5150_COMPOSITE0,
@@ -1538,6 +1579,14 @@ struct em28xx_board em28xx_boards[] = {
 			.gpio     = evga_indtube_analog,
 		} },
 	},
+	/* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 +
+	   Infineon TUA6034) */
+	[EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
+		.name          = "Reddo DVB-C USB TV Box",
+		.tuner_type    = TUNER_ABSENT,
+		.has_dvb       = 1,
+		.dvb_gpio      = reddo_dvb_c_usb_box,
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -1565,6 +1614,8 @@ struct usb_device_id em28xx_id_table[] = {
 			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0x2883),
 			.driver_info = EM2820_BOARD_UNKNOWN },
+	{ USB_DEVICE(0xeb1a, 0x2868),
+			.driver_info = EM2820_BOARD_UNKNOWN },
 	{ USB_DEVICE(0xeb1a, 0xe300),
 			.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
 	{ USB_DEVICE(0xeb1a, 0xe303),
@@ -1591,6 +1642,8 @@ struct usb_device_id em28xx_id_table[] = {
 			.driver_info = EM2870_BOARD_KWORLD_355U },
 	{ USB_DEVICE(0x1b80, 0xe302),
 			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */
+	{ USB_DEVICE(0x1b80, 0xe304),
+			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kworld DVD Maker 2 */
 	{ USB_DEVICE(0x0ccd, 0x0036),
 			.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
 	{ USB_DEVICE(0x0ccd, 0x004c),
@@ -1649,6 +1702,8 @@ struct usb_device_id em28xx_id_table[] = {
 			.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
 	{ USB_DEVICE(0x04bb, 0x0515),
 			.driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
+	{ USB_DEVICE(0xeb1a, 0x50a6),
+			.driver_info = EM2860_BOARD_GADMEI_UTV330 },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -1661,9 +1716,10 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
 	{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
 	{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
 	{0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028},
-	{0x9567eb1a, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
+	{0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
 	{0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
 	{0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
+	{0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
 };
 
 /* I2C devicelist hash table for devices with generic USB IDs */
@@ -1672,6 +1728,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
 	{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
 	{0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT},
 	{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
+	{0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF},
 };
 
 /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
@@ -2170,8 +2227,6 @@ static int em28xx_hint_board(struct em28xx *dev)
 /* ----------------------------------------------------------------------- */
 void em28xx_register_i2c_ir(struct em28xx *dev)
 {
-	struct i2c_board_info info;
-	struct IR_i2c_init_data init_data;
 	const unsigned short addr_list[] = {
 		 0x30, 0x47, I2C_CLIENT_END
 	};
@@ -2179,45 +2234,33 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
 	if (disable_ir)
 		return;
 
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
-	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	memset(&dev->info, 0, sizeof(&dev->info));
+	memset(&dev->init_data, 0, sizeof(dev->init_data));
+	strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
 
 	/* detect & configure */
 	switch (dev->model) {
-	case (EM2800_BOARD_UNKNOWN):
-		break;
-	case (EM2820_BOARD_UNKNOWN):
-		break;
-	case (EM2800_BOARD_TERRATEC_CINERGY_200):
-	case (EM2820_BOARD_TERRATEC_CINERGY_250):
-		init_data.ir_codes = ir_codes_em_terratec;
-		init_data.get_key = em28xx_get_key_terratec;
-		init_data.name = "i2c IR (EM28XX Terratec)";
-		break;
-	case (EM2820_BOARD_PINNACLE_USB_2):
-		init_data.ir_codes = ir_codes_pinnacle_grey;
-		init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
-		init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
-		break;
-	case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
-		init_data.ir_codes = ir_codes_hauppauge_new;
-		init_data.get_key = em28xx_get_key_em_haup;
-		init_data.name = "i2c IR (EM2840 Hauppauge)";
-		break;
-	case (EM2820_BOARD_MSI_VOX_USB_2):
+	case EM2800_BOARD_TERRATEC_CINERGY_200:
+	case EM2820_BOARD_TERRATEC_CINERGY_250:
+		dev->init_data.ir_codes = &ir_codes_em_terratec_table;
+		dev->init_data.get_key = em28xx_get_key_terratec;
+		dev->init_data.name = "i2c IR (EM28XX Terratec)";
 		break;
-	case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
+	case EM2820_BOARD_PINNACLE_USB_2:
+		dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
+		dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
+		dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
 		break;
-	case (EM2800_BOARD_KWORLD_USB2800):
-		break;
-	case (EM2800_BOARD_GRABBEEX_USB2800):
+	case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
+		dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
+		dev->init_data.get_key = em28xx_get_key_em_haup;
+		dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
 		break;
 	}
 
-	if (init_data.name)
-		info.platform_data = &init_data;
-	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+	if (dev->init_data.name)
+		dev->info.platform_data = &dev->init_data;
+	i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
 }
 
 void em28xx_card_setup(struct em28xx *dev)
@@ -2253,7 +2296,7 @@ void em28xx_card_setup(struct em28xx *dev)
 	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	{
 		struct tveeprom tv;
-#ifdef CONFIG_MODULES
+#if defined(CONFIG_MODULES) && defined(MODULE)
 		request_module("tveeprom");
 #endif
 		/* Call first TVeeprom */
@@ -2267,10 +2310,6 @@ void em28xx_card_setup(struct em28xx *dev)
 			dev->i2s_speed = 2048000;
 			dev->board.has_msp34xx = 1;
 		}
-#ifdef CONFIG_MODULES
-		if (tv.has_ir)
-			request_module("ir-kbd-i2c");
-#endif
 		break;
 	}
 	case EM2882_BOARD_KWORLD_ATSC_315U:
@@ -2311,6 +2350,10 @@ void em28xx_card_setup(struct em28xx *dev)
 		break;
 	}
 
+#if defined(CONFIG_MODULES) && defined(MODULE)
+	if (dev->board.has_ir_i2c && !disable_ir)
+		request_module("ir-kbd-i2c");
+#endif
 	if (dev->board.has_snapshot_button)
 		em28xx_register_snapshot_button(dev);
 
@@ -2329,55 +2372,55 @@ void em28xx_card_setup(struct em28xx *dev)
 
 	/* request some modules */
 	if (dev->board.has_msp34xx)
-		v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-			"msp3400", "msp3400", msp3400_addrs);
+		v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+			"msp3400", "msp3400", 0, msp3400_addrs);
 
 	if (dev->board.decoder == EM28XX_SAA711X)
-		v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-			"saa7115", "saa7115_auto", saa711x_addrs);
+		v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+			"saa7115", "saa7115_auto", 0, saa711x_addrs);
 
 	if (dev->board.decoder == EM28XX_TVP5150)
-		v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-			"tvp5150", "tvp5150", tvp5150_addrs);
+		v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+			"tvp5150", "tvp5150", 0, tvp5150_addrs);
 
 	if (dev->em28xx_sensor == EM28XX_MT9V011) {
 		struct v4l2_subdev *sd;
 
-		sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
-			 &dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs);
+		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
+			 &dev->i2c_adap, "mt9v011", "mt9v011", 0, mt9v011_addrs);
 		v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
 	}
 
 
 	if (dev->board.adecoder == EM28XX_TVAUDIO)
 		v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-			"tvaudio", "tvaudio", dev->board.tvaudio_addr);
+			"tvaudio", "tvaudio", dev->board.tvaudio_addr, NULL);
 
 	if (dev->board.tuner_type != TUNER_ABSENT) {
 		int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
 
 		if (dev->board.radio.type)
 			v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-				"tuner", "tuner", dev->board.radio_addr);
+				"tuner", "tuner", dev->board.radio_addr, NULL);
 
 		if (has_demod)
-			v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+			v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+				0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
 		if (dev->tuner_addr == 0) {
 			enum v4l2_i2c_tuner_type type =
 				has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 			struct v4l2_subdev *sd;
 
-			sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+			sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(type));
+				0, v4l2_i2c_tuner_addrs(type));
 
 			if (sd)
 				dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
 		} else {
 			v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
-				"tuner", "tuner", dev->tuner_addr);
+				"tuner", "tuner", dev->tuner_addr, NULL);
 		}
 	}
 
@@ -2551,7 +2594,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 	 * Default format, used for tvp5150 or saa711x output formats
 	 */
 	dev->vinmode = 0x10;
-	dev->vinctl  = 0x11;
+	dev->vinctl  = EM28XX_VINCTRL_INTERLACED |
+		       EM28XX_VINCTRL_CCIR656_ENABLE;
 
 	/* Do board specific init and eeprom reading */
 	em28xx_card_setup(dev);
@@ -2570,6 +2614,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
 	/* init video dma queues */
 	INIT_LIST_HEAD(&dev->vidq.active);
 	INIT_LIST_HEAD(&dev->vidq.queued);
+	INIT_LIST_HEAD(&dev->vbiq.active);
+	INIT_LIST_HEAD(&dev->vbiq.queued);
 
 
 	if (dev->board.has_msp34xx) {
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 98e140b..a88257a 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -54,6 +54,10 @@ static int alt = EM28XX_PINOUT;
 module_param(alt, int, 0644);
 MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
 
+static unsigned int disable_vbi;
+module_param(disable_vbi, int, 0644);
+MODULE_PARM_DESC(disable_vbi, "disable vbi support");
+
 /* FIXME */
 #define em28xx_isocdbg(fmt, arg...) do {\
 	if (core_debug) \
@@ -648,9 +652,24 @@ int em28xx_capture_start(struct em28xx *dev, int start)
 	return rc;
 }
 
+int em28xx_vbi_supported(struct em28xx *dev)
+{
+	/* Modprobe option to manually disable */
+	if (disable_vbi == 1)
+		return 0;
+
+	if (dev->chip_id == CHIP_ID_EM2860 ||
+	    dev->chip_id == CHIP_ID_EM2883)
+		return 1;
+
+	/* Version of em28xx that does not support VBI */
+	return 0;
+}
+
 int em28xx_set_outfmt(struct em28xx *dev)
 {
 	int ret;
+	u8 vinctrl;
 
 	ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
 				dev->format->reg | 0x20, 0xff);
@@ -661,7 +680,16 @@ int em28xx_set_outfmt(struct em28xx *dev)
 	if (ret < 0)
 		return ret;
 
-	return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, dev->vinctl);
+	vinctrl = dev->vinctl;
+	if (em28xx_vbi_supported(dev) == 1) {
+		vinctrl |= EM28XX_VINCTRL_VBI_RAW;
+		em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
+		em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
+		em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4);
+		em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c);
+	}
+
+	return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
 }
 
 static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
@@ -732,7 +760,14 @@ int em28xx_resolution_set(struct em28xx *dev)
 
 
 	em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
-	em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
+
+	/* If we don't set the start position to 4 in VBI mode, we end up
+	   with line 21 being YUYV encoded instead of being in 8-bit
+	   greyscale */
+	if (em28xx_vbi_supported(dev) == 1)
+		em28xx_capture_area_set(dev, 0, 4, width >> 2, height >> 2);
+	else
+		em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
 
 	return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
 }
@@ -844,8 +879,7 @@ EXPORT_SYMBOL_GPL(em28xx_set_mode);
  */
 static void em28xx_irq_callback(struct urb *urb)
 {
-	struct em28xx_dmaqueue  *dma_q = urb->context;
-	struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
+	struct em28xx *dev = urb->context;
 	int rc, i;
 
 	switch (urb->status) {
@@ -930,6 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
 		     int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
 {
 	struct em28xx_dmaqueue *dma_q = &dev->vidq;
+	struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
 	int i;
 	int sb_size, pipe;
 	struct urb *urb;
@@ -959,7 +994,8 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
 	}
 
 	dev->isoc_ctl.max_pkt_size = max_pkt_size;
-	dev->isoc_ctl.buf = NULL;
+	dev->isoc_ctl.vid_buf = NULL;
+	dev->isoc_ctl.vbi_buf = NULL;
 
 	sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
 
@@ -994,7 +1030,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
 
 		usb_fill_int_urb(urb, dev->udev, pipe,
 				 dev->isoc_ctl.transfer_buffer[i], sb_size,
-				 em28xx_irq_callback, dma_q, 1);
+				 em28xx_irq_callback, dev, 1);
 
 		urb->number_of_packets = max_packets;
 		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
@@ -1009,6 +1045,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
 	}
 
 	init_waitqueue_head(&dma_q->wq);
+	init_waitqueue_head(&vbi_dma_q->wq);
 
 	em28xx_capture_start(dev, 1);
 
@@ -1094,7 +1131,7 @@ struct em28xx *em28xx_get_device(int minor,
 	list_for_each_entry(h, &em28xx_devlist, devlist) {
 		if (h->vdev->minor == minor)
 			dev = h;
-		if (h->vbi_dev->minor == minor) {
+		if (h->vbi_dev && h->vbi_dev->minor == minor) {
 			dev = h;
 			*fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
 		}
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index d603575..db74946 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -33,6 +33,7 @@
 #include "s5h1409.h"
 #include "mt352.h"
 #include "mt352_priv.h" /* FIXME */
+#include "tda1002x.h"
 
 MODULE_DESCRIPTION("driver for em28xx based DVB cards");
 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -295,6 +296,11 @@ static struct mt352_config terratec_xs_mt352_cfg = {
 	.demod_init = mt352_terratec_xs_init,
 };
 
+static struct tda10023_config em28xx_tda10023_config = {
+	.demod_address = 0x0c,
+	.invert = 1,
+};
+
 /* ------------------------------------------------------------------ */
 
 static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -549,6 +555,19 @@ static int dvb_init(struct em28xx *dev)
 		}
 		break;
 #endif
+	case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
+		/* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
+		dvb->frontend = dvb_attach(tda10023_attach,
+			&em28xx_tda10023_config,
+			&dev->i2c_adap, 0x48);
+		if (dvb->frontend) {
+			if (!dvb_attach(simple_tuner_attach, dvb->frontend,
+				&dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
+				result = -EINVAL;
+				goto out_free;
+			}
+		}
+		break;
 	default:
 		printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
 				" isn't supported yet\n",
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 27e33a2..71474d3 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -459,7 +459,6 @@ static struct i2c_algorithm em28xx_algo = {
 static struct i2c_adapter em28xx_adap_template = {
 	.owner = THIS_MODULE,
 	.name = "em28xx",
-	.id = I2C_HW_B_EM28XX,
 	.algo = &em28xx_algo,
 };
 
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 6bf84bd..ed12e7f 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -86,7 +86,19 @@
 #define EM28XX_XCLK_FREQUENCY_24MHZ	0x0b
 
 #define EM28XX_R10_VINMODE	0x10
+
 #define EM28XX_R11_VINCTRL	0x11
+
+/* em28xx Video Input Control Register 0x11 */
+#define EM28XX_VINCTRL_VBI_SLICED	0x80
+#define EM28XX_VINCTRL_VBI_RAW		0x40
+#define EM28XX_VINCTRL_VOUT_MODE_IN	0x20 /* HREF,VREF,VACT in output */
+#define EM28XX_VINCTRL_CCIR656_ENABLE	0x10
+#define EM28XX_VINCTRL_VBI_16BIT_RAW	0x08 /* otherwise 8-bit raw */
+#define EM28XX_VINCTRL_FID_ON_HREF	0x04
+#define EM28XX_VINCTRL_DUAL_EDGE_STROBE	0x02
+#define EM28XX_VINCTRL_INTERLACED	0x01
+
 #define EM28XX_R12_VINENABLE	0x12	/* */
 
 #define EM28XX_R14_GAMMA	0x14
@@ -135,6 +147,10 @@
 #define EM28XX_R31_HSCALEHIGH	0x31
 #define EM28XX_R32_VSCALELOW	0x32
 #define EM28XX_R33_VSCALEHIGH	0x33
+#define EM28XX_R34_VBI_START_H	0x34
+#define EM28XX_R35_VBI_START_V	0x35
+#define EM28XX_R36_VBI_WIDTH	0x36
+#define EM28XX_R37_VBI_HEIGHT	0x37
 
 #define EM28XX_R40_AC97LSB	0x40
 #define EM28XX_R41_AC97MSB	0x41
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
new file mode 100644
index 0000000..94943e5
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-vbi.c
@@ -0,0 +1,142 @@
+/*
+   em28xx-vbi.c - VBI driver for em28xx
+
+   Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
+
+   This work was sponsored by EyeMagnet Limited.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#include "em28xx.h"
+
+static unsigned int vbibufs = 5;
+module_param(vbibufs, int, 0644);
+MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
+
+static unsigned int vbi_debug;
+module_param(vbi_debug, int, 0644);
+MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
+
+#define dprintk(level, fmt, arg...)	if (vbi_debug >= level) \
+	printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
+
+/* ------------------------------------------------------------------ */
+
+static void
+free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
+{
+	struct em28xx_fh     *fh  = vq->priv_data;
+	struct em28xx        *dev = fh->dev;
+	unsigned long flags = 0;
+	if (in_interrupt())
+		BUG();
+
+	/* We used to wait for the buffer to finish here, but this didn't work
+	   because, as we were keeping the state as VIDEOBUF_QUEUED,
+	   videobuf_queue_cancel marked it as finished for us.
+	   (Also, it could wedge forever if the hardware was misconfigured.)
+
+	   This should be safe; by the time we get here, the buffer isn't
+	   queued anymore. If we ever start marking the buffers as
+	   VIDEOBUF_ACTIVE, it won't be, though.
+	*/
+	spin_lock_irqsave(&dev->slock, flags);
+	if (dev->isoc_ctl.vbi_buf == buf)
+		dev->isoc_ctl.vbi_buf = NULL;
+	spin_unlock_irqrestore(&dev->slock, flags);
+
+	videobuf_vmalloc_free(&buf->vb);
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
+{
+	*size = 720 * 12 * 2;
+	if (0 == *count)
+		*count = vbibufs;
+	if (*count < 2)
+		*count = 2;
+	if (*count > 32)
+		*count = 32;
+	return 0;
+}
+
+static int
+vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
+	    enum v4l2_field field)
+{
+	struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+	int                  rc = 0;
+	unsigned int size;
+
+	size = 720 * 12 * 2;
+
+	buf->vb.size = size;
+
+	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
+		return -EINVAL;
+
+	buf->vb.width  = 720;
+	buf->vb.height = 12;
+	buf->vb.field  = field;
+
+	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+		rc = videobuf_iolock(q, &buf->vb, NULL);
+		if (rc < 0)
+			goto fail;
+	}
+
+	buf->vb.state = VIDEOBUF_PREPARED;
+	return 0;
+
+fail:
+	free_buffer(q, buf);
+	return rc;
+}
+
+static void
+vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct em28xx_buffer    *buf     = container_of(vb,
+							struct em28xx_buffer,
+							vb);
+	struct em28xx_fh        *fh      = vq->priv_data;
+	struct em28xx           *dev     = fh->dev;
+	struct em28xx_dmaqueue  *vbiq    = &dev->vbiq;
+
+	buf->vb.state = VIDEOBUF_QUEUED;
+	list_add_tail(&buf->vb.queue, &vbiq->active);
+}
+
+static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+{
+	struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+	free_buffer(q, buf);
+}
+
+struct videobuf_queue_ops em28xx_vbi_qops = {
+	.buf_setup    = vbi_setup,
+	.buf_prepare  = vbi_prepare,
+	.buf_queue    = vbi_queue,
+	.buf_release  = vbi_release,
+};
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index ab079d9..3a1dfb7 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -124,7 +124,7 @@ static struct em28xx_fmt format[] = {
 
 /* supported controls */
 /* Common to all boards */
-static struct v4l2_queryctrl em28xx_qctrl[] = {
+static struct v4l2_queryctrl ac97_qctrl[] = {
 	{
 		.id = V4L2_CID_AUDIO_VOLUME,
 		.type = V4L2_CTRL_TYPE_INTEGER,
@@ -133,7 +133,7 @@ static struct v4l2_queryctrl em28xx_qctrl[] = {
 		.maximum = 0x1f,
 		.step = 0x1,
 		.default_value = 0x1f,
-		.flags = 0,
+		.flags = V4L2_CTRL_FLAG_SLIDER,
 	}, {
 		.id = V4L2_CID_AUDIO_MUTE,
 		.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -163,7 +163,24 @@ static inline void buffer_filled(struct em28xx *dev,
 	buf->vb.field_count++;
 	do_gettimeofday(&buf->vb.ts);
 
-	dev->isoc_ctl.buf = NULL;
+	dev->isoc_ctl.vid_buf = NULL;
+
+	list_del(&buf->vb.queue);
+	wake_up(&buf->vb.done);
+}
+
+static inline void vbi_buffer_filled(struct em28xx *dev,
+				     struct em28xx_dmaqueue *dma_q,
+				     struct em28xx_buffer *buf)
+{
+	/* Advice that buffer was filled */
+	em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
+
+	buf->vb.state = VIDEOBUF_DONE;
+	buf->vb.field_count++;
+	do_gettimeofday(&buf->vb.ts);
+
+	dev->isoc_ctl.vbi_buf = NULL;
 
 	list_del(&buf->vb.queue);
 	wake_up(&buf->vb.done);
@@ -239,7 +256,8 @@ static void em28xx_copy_video(struct em28xx *dev,
 
 		if ((char *)startwrite + lencopy > (char *)outp +
 		    buf->vb.size) {
-			em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
+			em28xx_isocdbg("Overflow of %zi bytes past buffer end"
+				       "(2)\n",
 				       ((char *)startwrite + lencopy) -
 				       ((char *)outp + buf->vb.size));
 			lencopy = remain = (char *)outp + buf->vb.size -
@@ -256,6 +274,63 @@ static void em28xx_copy_video(struct em28xx *dev,
 	dma_q->pos += len;
 }
 
+static void em28xx_copy_vbi(struct em28xx *dev,
+			      struct em28xx_dmaqueue  *dma_q,
+			      struct em28xx_buffer *buf,
+			      unsigned char *p,
+			      unsigned char *outp, unsigned long len)
+{
+	void *startwrite, *startread;
+	int  offset;
+	int bytesperline = 720;
+
+	if (dev == NULL) {
+		em28xx_isocdbg("dev is null\n");
+		return;
+	}
+
+	if (dma_q == NULL) {
+		em28xx_isocdbg("dma_q is null\n");
+		return;
+	}
+	if (buf == NULL) {
+		return;
+	}
+	if (p == NULL) {
+		em28xx_isocdbg("p is null\n");
+		return;
+	}
+	if (outp == NULL) {
+		em28xx_isocdbg("outp is null\n");
+		return;
+	}
+
+	if (dma_q->pos + len > buf->vb.size)
+		len = buf->vb.size - dma_q->pos;
+
+	if ((p[0] == 0x33 && p[1] == 0x95) ||
+	    (p[0] == 0x88 && p[1] == 0x88)) {
+		/* Header field, advance past it */
+		p += 4;
+	} else {
+		len += 4;
+	}
+
+	startread = p;
+
+	startwrite = outp + dma_q->pos;
+	offset = dma_q->pos;
+
+	/* Make sure the bottom field populates the second half of the frame */
+	if (buf->top_field == 0) {
+		startwrite += bytesperline * 0x0c;
+		offset += bytesperline * 0x0c;
+	}
+
+	memcpy(startwrite, startread, len);
+	dma_q->pos += len;
+}
+
 static inline void print_err_status(struct em28xx *dev,
 				     int packet, int status)
 {
@@ -306,7 +381,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
 
 	if (list_empty(&dma_q->active)) {
 		em28xx_isocdbg("No active queue to serve\n");
-		dev->isoc_ctl.buf = NULL;
+		dev->isoc_ctl.vid_buf = NULL;
 		*buf = NULL;
 		return;
 	}
@@ -318,7 +393,34 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
 	outp = videobuf_to_vmalloc(&(*buf)->vb);
 	memset(outp, 0, (*buf)->vb.size);
 
-	dev->isoc_ctl.buf = *buf;
+	dev->isoc_ctl.vid_buf = *buf;
+
+	return;
+}
+
+/*
+ * video-buf generic routine to get the next available VBI buffer
+ */
+static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q,
+				    struct em28xx_buffer **buf)
+{
+	struct em28xx *dev = container_of(dma_q, struct em28xx, vbiq);
+	char *outp;
+
+	if (list_empty(&dma_q->active)) {
+		em28xx_isocdbg("No active queue to serve\n");
+		dev->isoc_ctl.vbi_buf = NULL;
+		*buf = NULL;
+		return;
+	}
+
+	/* Get the next buffer */
+	*buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue);
+	/* Cleans up buffer - Usefull for testing for frame/URB loss */
+	outp = videobuf_to_vmalloc(&(*buf)->vb);
+	memset(outp, 0x00, (*buf)->vb.size);
+
+	dev->isoc_ctl.vbi_buf = *buf;
 
 	return;
 }
@@ -329,7 +431,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
 static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
 {
 	struct em28xx_buffer    *buf;
-	struct em28xx_dmaqueue  *dma_q = urb->context;
+	struct em28xx_dmaqueue  *dma_q = &dev->vidq;
 	unsigned char *outp = NULL;
 	int i, len = 0, rc = 1;
 	unsigned char *p;
@@ -346,7 +448,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
 			return 0;
 	}
 
-	buf = dev->isoc_ctl.buf;
+	buf = dev->isoc_ctl.vid_buf;
 	if (buf != NULL)
 		outp = videobuf_to_vmalloc(&buf->vb);
 
@@ -410,6 +512,153 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
 	return rc;
 }
 
+/* Version of isoc handler that takes into account a mixture of video and
+   VBI data */
+static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
+{
+	struct em28xx_buffer    *buf, *vbi_buf;
+	struct em28xx_dmaqueue  *dma_q = &dev->vidq;
+	struct em28xx_dmaqueue  *vbi_dma_q = &dev->vbiq;
+	unsigned char *outp = NULL;
+	unsigned char *vbioutp = NULL;
+	int i, len = 0, rc = 1;
+	unsigned char *p;
+	int vbi_size;
+
+	if (!dev)
+		return 0;
+
+	if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
+		return 0;
+
+	if (urb->status < 0) {
+		print_err_status(dev, -1, urb->status);
+		if (urb->status == -ENOENT)
+			return 0;
+	}
+
+	buf = dev->isoc_ctl.vid_buf;
+	if (buf != NULL)
+		outp = videobuf_to_vmalloc(&buf->vb);
+
+	vbi_buf = dev->isoc_ctl.vbi_buf;
+	if (vbi_buf != NULL)
+		vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
+
+	for (i = 0; i < urb->number_of_packets; i++) {
+		int status = urb->iso_frame_desc[i].status;
+
+		if (status < 0) {
+			print_err_status(dev, i, status);
+			if (urb->iso_frame_desc[i].status != -EPROTO)
+				continue;
+		}
+
+		len = urb->iso_frame_desc[i].actual_length - 4;
+
+		if (urb->iso_frame_desc[i].actual_length <= 0) {
+			/* em28xx_isocdbg("packet %d is empty",i); - spammy */
+			continue;
+		}
+		if (urb->iso_frame_desc[i].actual_length >
+						dev->max_pkt_size) {
+			em28xx_isocdbg("packet bigger than packet size");
+			continue;
+		}
+
+		p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+
+		/* capture type 0 = vbi start
+		   capture type 1 = video start
+		   capture type 2 = video in progress */
+		if (p[0] == 0x33 && p[1] == 0x95) {
+			dev->capture_type = 0;
+			dev->vbi_read = 0;
+			em28xx_isocdbg("VBI START HEADER!!!\n");
+			dev->cur_field = p[2];
+		}
+
+		/* FIXME: get rid of hard-coded value */
+		vbi_size = 720 * 0x0c;
+
+		if (dev->capture_type == 0) {
+			if (dev->vbi_read >= vbi_size) {
+				/* We've already read all the VBI data, so
+				   treat the rest as video */
+				em28xx_isocdbg("dev->vbi_read > vbi_size\n");
+			} else if ((dev->vbi_read + len) < vbi_size) {
+				/* This entire frame is VBI data */
+				if (dev->vbi_read == 0 &&
+				    (!(dev->cur_field & 1))) {
+					/* Brand new frame */
+					if (vbi_buf != NULL)
+						vbi_buffer_filled(dev,
+								  vbi_dma_q,
+								  vbi_buf);
+					vbi_get_next_buf(vbi_dma_q, &vbi_buf);
+					if (vbi_buf == NULL)
+						vbioutp = NULL;
+					else
+						vbioutp = videobuf_to_vmalloc(
+							&vbi_buf->vb);
+				}
+
+				if (dev->vbi_read == 0) {
+					vbi_dma_q->pos = 0;
+					if (vbi_buf != NULL) {
+						if (dev->cur_field & 1)
+							vbi_buf->top_field = 0;
+						else
+							vbi_buf->top_field = 1;
+					}
+				}
+
+				dev->vbi_read += len;
+				em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
+						vbioutp, len);
+			} else {
+				/* Some of this frame is VBI data and some is
+				   video data */
+				int vbi_data_len = vbi_size - dev->vbi_read;
+				dev->vbi_read += vbi_data_len;
+				em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
+						vbioutp, vbi_data_len);
+				dev->capture_type = 1;
+				p += vbi_data_len;
+				len -= vbi_data_len;
+			}
+		}
+
+		if (dev->capture_type == 1) {
+			dev->capture_type = 2;
+			em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
+				       len, (p[2] & 1) ? "odd" : "even");
+
+			if (dev->progressive || !(dev->cur_field & 1)) {
+				if (buf != NULL)
+					buffer_filled(dev, dma_q, buf);
+				get_next_buf(dma_q, &buf);
+				if (buf == NULL)
+					outp = NULL;
+				else
+					outp = videobuf_to_vmalloc(&buf->vb);
+			}
+			if (buf != NULL) {
+				if (dev->cur_field & 1)
+					buf->top_field = 0;
+				else
+					buf->top_field = 1;
+			}
+
+			dma_q->pos = 0;
+		}
+		if (buf != NULL && dev->capture_type == 2)
+			em28xx_copy_video(dev, dma_q, buf, p, outp, len);
+	}
+	return rc;
+}
+
+
 /* ------------------------------------------------------------------
 	Videobuf operations
    ------------------------------------------------------------------*/
@@ -421,7 +670,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
 	struct em28xx        *dev = fh->dev;
 	struct v4l2_frequency f;
 
-	*size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
+	*size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)
+		>> 3;
 
 	if (0 == *count)
 		*count = EM28XX_DEF_BUF;
@@ -458,8 +708,8 @@ static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
 	   VIDEOBUF_ACTIVE, it won't be, though.
 	*/
 	spin_lock_irqsave(&dev->slock, flags);
-	if (dev->isoc_ctl.buf == buf)
-		dev->isoc_ctl.buf = NULL;
+	if (dev->isoc_ctl.vid_buf == buf)
+		dev->isoc_ctl.vid_buf = NULL;
 	spin_unlock_irqrestore(&dev->slock, flags);
 
 	videobuf_vmalloc_free(&buf->vb);
@@ -475,7 +725,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 	struct em28xx        *dev = fh->dev;
 	int                  rc = 0, urb_init = 0;
 
-	buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;
+	buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
+			+ 7) >> 3;
 
 	if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
 		return -EINVAL;
@@ -494,9 +745,16 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
 		urb_init = 1;
 
 	if (urb_init) {
-		rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
-				      EM28XX_NUM_BUFS, dev->max_pkt_size,
-				      em28xx_isoc_copy);
+		if (em28xx_vbi_supported(dev) == 1)
+			rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
+					      EM28XX_NUM_BUFS,
+					      dev->max_pkt_size,
+					      em28xx_isoc_copy_vbi);
+		else
+			rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
+					      EM28XX_NUM_BUFS,
+					      dev->max_pkt_size,
+					      em28xx_isoc_copy);
 		if (rc < 0)
 			goto fail;
 	}
@@ -578,41 +836,89 @@ static void video_mux(struct em28xx *dev, int index)
 }
 
 /* Usage lock check functions */
-static int res_get(struct em28xx_fh *fh)
+static int res_get(struct em28xx_fh *fh, unsigned int bit)
 {
 	struct em28xx    *dev = fh->dev;
-	int		 rc   = 0;
 
-	/* This instance already has stream_on */
-	if (fh->stream_on)
-		return rc;
+	if (fh->resources & bit)
+		/* have it already allocated */
+		return 1;
 
-	if (dev->stream_on)
-		return -EBUSY;
+	/* is it free? */
+	mutex_lock(&dev->lock);
+	if (dev->resources & bit) {
+		/* no, someone else uses it */
+		mutex_unlock(&dev->lock);
+		return 0;
+	}
+	/* it's free, grab it */
+	fh->resources  |= bit;
+	dev->resources |= bit;
+	em28xx_videodbg("res: get %d\n", bit);
+	mutex_unlock(&dev->lock);
+	return 1;
+}
 
-	dev->stream_on = 1;
-	fh->stream_on  = 1;
-	return rc;
+static int res_check(struct em28xx_fh *fh, unsigned int bit)
+{
+	return fh->resources & bit;
 }
 
-static int res_check(struct em28xx_fh *fh)
+static int res_locked(struct em28xx *dev, unsigned int bit)
 {
-	return fh->stream_on;
+	return dev->resources & bit;
 }
 
-static void res_free(struct em28xx_fh *fh)
+static void res_free(struct em28xx_fh *fh, unsigned int bits)
 {
 	struct em28xx    *dev = fh->dev;
 
-	fh->stream_on = 0;
-	dev->stream_on = 0;
+	BUG_ON((fh->resources & bits) != bits);
+
+	mutex_lock(&dev->lock);
+	fh->resources  &= ~bits;
+	dev->resources &= ~bits;
+	em28xx_videodbg("res: put %d\n", bits);
+	mutex_unlock(&dev->lock);
+}
+
+static int get_ressource(struct em28xx_fh *fh)
+{
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return EM28XX_RESOURCE_VIDEO;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		return EM28XX_RESOURCE_VBI;
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+/*
+ * ac97_queryctrl()
+ * return the ac97 supported controls
+ */
+static int ac97_queryctrl(struct v4l2_queryctrl *qc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
+		if (qc->id && qc->id == ac97_qctrl[i].id) {
+			memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
+			return 0;
+		}
+	}
+
+	/* Control is not ac97 related */
+	return 1;
 }
 
 /*
- * em28xx_get_ctrl()
- * return the current saturation, brightness or contrast, mute state
+ * ac97_get_ctrl()
+ * return the current values for ac97 mute and volume
  */
-static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
+static int ac97_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
 {
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
@@ -622,29 +928,41 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
 		ctrl->value = dev->volume;
 		return 0;
 	default:
-		return -EINVAL;
+		/* Control is not ac97 related */
+		return 1;
 	}
 }
 
 /*
- * em28xx_set_ctrl()
- * mute or set new saturation, brightness or contrast
+ * ac97_set_ctrl()
+ * set values for ac97 mute and volume
  */
-static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
+static int ac97_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
 {
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++)
+		if (ctrl->id == ac97_qctrl[i].id)
+			goto handle;
+
+	/* Announce that hasn't handle it */
+	return 1;
+
+handle:
+	if (ctrl->value < ac97_qctrl[i].minimum ||
+	    ctrl->value > ac97_qctrl[i].maximum)
+		return -ERANGE;
+
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
-		if (ctrl->value != dev->mute) {
-			dev->mute = ctrl->value;
-			return em28xx_audio_analog_set(dev);
-		}
-		return 0;
+		dev->mute = ctrl->value;
+		break;
 	case V4L2_CID_AUDIO_VOLUME:
 		dev->volume = ctrl->value;
-		return em28xx_audio_analog_set(dev);
-	default:
-		return -EINVAL;
+		break;
 	}
+
+	return em28xx_audio_analog_set(dev);
 }
 
 static int check_dev(struct em28xx *dev)
@@ -751,7 +1069,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 	} else {
 		/* width must even because of the YUYV format
 		   height must be even because of interlacing */
-		v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
+		v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
+				      1, 0);
 	}
 
 	get_scale(dev, width, height, &hscale, &vscale);
@@ -817,12 +1136,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 		goto out;
 	}
 
-	if (dev->stream_on && !fh->stream_on) {
-		em28xx_errdev("%s device in use by another fh\n", __func__);
-		rc = -EBUSY;
-		goto out;
-	}
-
 	rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
 				f->fmt.pix.width, f->fmt.pix.height);
 
@@ -831,6 +1144,21 @@ out:
 	return rc;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
+{
+	struct em28xx_fh   *fh  = priv;
+	struct em28xx      *dev = fh->dev;
+	int                rc;
+
+	rc = check_dev(dev);
+	if (rc < 0)
+		return rc;
+
+	*norm = dev->norm;
+
+	return 0;
+}
+
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
 {
 	struct em28xx_fh   *fh  = priv;
@@ -974,6 +1302,9 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
 	struct em28xx_fh   *fh    = priv;
 	struct em28xx      *dev   = fh->dev;
 
+	if (!dev->audio_mode.has_audio)
+		return -EINVAL;
+
 	switch (a->index) {
 	case EM28XX_AMUX_VIDEO:
 		strcpy(a->name, "Television");
@@ -1015,6 +1346,9 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
 	struct em28xx      *dev = fh->dev;
 
 
+	if (!dev->audio_mode.has_audio)
+		return -EINVAL;
+
 	if (a->index >= MAX_EM28XX_INPUT)
 		return -EINVAL;
 	if (0 == INPUT(a->index)->type)
@@ -1038,7 +1372,6 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 	struct em28xx_fh      *fh  = priv;
 	struct em28xx         *dev = fh->dev;
 	int                   id  = qc->id;
-	int                   i;
 	int                   rc;
 
 	rc = check_dev(dev);
@@ -1049,15 +1382,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
 
 	qc->id = id;
 
-	if (!dev->board.has_msp34xx) {
-		for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
-			if (qc->id && qc->id == em28xx_qctrl[i].id) {
-				memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc));
-				return 0;
-			}
-		}
+	/* enumberate AC97 controls */
+	if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
+		rc = ac97_queryctrl(qc);
+		if (!rc)
+			return 0;
 	}
 
+	/* enumberate V4L2 device controls */
 	mutex_lock(&dev->lock);
 	v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
 	mutex_unlock(&dev->lock);
@@ -1082,14 +1414,16 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
 
 	mutex_lock(&dev->lock);
 
-	if (dev->board.has_msp34xx)
+	/* Set an AC97 control */
+	if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
+		rc = ac97_get_ctrl(dev, ctrl);
+	else
+		rc = 1;
+
+	/* It were not an AC97 control. Sends it to the v4l2 dev interface */
+	if (rc == 1) {
 		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
-	else {
-		rc = em28xx_get_ctrl(dev, ctrl);
-		if (rc < 0) {
-			v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
-			rc = 0;
-		}
+		rc = 0;
 	}
 
 	mutex_unlock(&dev->lock);
@@ -1101,7 +1435,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 {
 	struct em28xx_fh      *fh  = priv;
 	struct em28xx         *dev = fh->dev;
-	u8                    i;
 	int                   rc;
 
 	rc = check_dev(dev);
@@ -1110,28 +1443,31 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 
 	mutex_lock(&dev->lock);
 
-	if (dev->board.has_msp34xx)
-		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
-	else {
+	/* Set an AC97 control */
+	if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
+		rc = ac97_set_ctrl(dev, ctrl);
+	else
 		rc = 1;
-		for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
-			if (ctrl->id == em28xx_qctrl[i].id) {
-				if (ctrl->value < em28xx_qctrl[i].minimum ||
-				    ctrl->value > em28xx_qctrl[i].maximum) {
-					rc = -ERANGE;
-					break;
-				}
-
-				rc = em28xx_set_ctrl(dev, ctrl);
-				break;
-			}
-		}
-	}
 
-	/* Control not found - try to send it to the attached devices */
+	/* It isn't an AC97 control. Sends it to the v4l2 dev interface */
 	if (rc == 1) {
 		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
-		rc = 0;
+
+		/*
+		 * In the case of non-AC97 volume controls, we still need
+		 * to do some setups at em28xx, in order to mute/unmute
+		 * and to adjust audio volume. However, the value ranges
+		 * should be checked by the corresponding V4L subdriver.
+		 */
+		switch (ctrl->id) {
+		case V4L2_CID_AUDIO_MUTE:
+			dev->mute = ctrl->value;
+			rc = em28xx_audio_analog_set(dev);
+			break;
+		case V4L2_CID_AUDIO_VOLUME:
+			dev->volume = ctrl->value;
+			rc = em28xx_audio_analog_set(dev);
+		}
 	}
 
 	mutex_unlock(&dev->lock);
@@ -1275,8 +1611,9 @@ static int vidioc_g_register(struct file *file, void *priv,
 		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
 		return 0;
 	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* Not supported yet */
-		return -EINVAL;
+		/* TODO: is this correct? */
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
+		return 0;
 	default:
 		if (!v4l2_chip_match_host(&reg->match))
 			return -EINVAL;
@@ -1327,8 +1664,9 @@ static int vidioc_s_register(struct file *file, void *priv,
 		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
 		return 0;
 	case V4L2_CHIP_MATCH_I2C_ADDR:
-		/* Not supported yet */
-		return -EINVAL;
+		/* TODO: is this correct? */
+		v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
+		return 0;
 	default:
 		if (!v4l2_chip_match_host(&reg->match))
 			return -EINVAL;
@@ -1372,20 +1710,25 @@ static int vidioc_streamon(struct file *file, void *priv,
 {
 	struct em28xx_fh      *fh  = priv;
 	struct em28xx         *dev = fh->dev;
-	int                   rc;
+	int                   rc = -EINVAL;
 
 	rc = check_dev(dev);
 	if (rc < 0)
 		return rc;
 
+	if (unlikely(type != fh->type))
+		return -EINVAL;
+
+	em28xx_videodbg("vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
+			fh, type, fh->resources, dev->resources);
 
-	mutex_lock(&dev->lock);
-	rc = res_get(fh);
+	if (unlikely(!res_get(fh, get_ressource(fh))))
+		return -EBUSY;
 
-	if (likely(rc >= 0))
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		rc = videobuf_streamon(&fh->vb_vidq);
-
-	mutex_unlock(&dev->lock);
+	else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		rc = videobuf_streamon(&fh->vb_vbiq);
 
 	return rc;
 }
@@ -1401,17 +1744,22 @@ static int vidioc_streamoff(struct file *file, void *priv,
 	if (rc < 0)
 		return rc;
 
-	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+	    fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
 		return -EINVAL;
 	if (type != fh->type)
 		return -EINVAL;
 
-	mutex_lock(&dev->lock);
-
-	videobuf_streamoff(&fh->vb_vidq);
-	res_free(fh);
+	em28xx_videodbg("vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
+			fh, type, fh->resources, dev->resources);
 
-	mutex_unlock(&dev->lock);
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		videobuf_streamoff(&fh->vb_vidq);
+		res_free(fh, EM28XX_RESOURCE_VIDEO);
+	} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		videobuf_streamoff(&fh->vb_vbiq);
+		res_free(fh, EM28XX_RESOURCE_VBI);
+	}
 
 	return 0;
 }
@@ -1431,9 +1779,14 @@ static int vidioc_querycap(struct file *file, void  *priv,
 	cap->capabilities =
 			V4L2_CAP_SLICED_VBI_CAPTURE |
 			V4L2_CAP_VIDEO_CAPTURE |
-			V4L2_CAP_AUDIO |
 			V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
 
+	if (dev->vbi_dev)
+		cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
+
+	if (dev->audio_mode.has_audio)
+		cap->capabilities |= V4L2_CAP_AUDIO;
+
 	if (dev->tuner_type != TUNER_ABSENT)
 		cap->capabilities |= V4L2_CAP_TUNER;
 
@@ -1498,6 +1851,45 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
 	return 0;
 }
 
+/* RAW VBI ioctls */
+
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
+				struct v4l2_format *format)
+{
+	format->fmt.vbi.samples_per_line = 720;
+	format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+	format->fmt.vbi.offset = 0;
+	format->fmt.vbi.flags = 0;
+
+	/* Varies by video standard (NTSC, PAL, etc.) */
+	/* FIXME: hard-coded for NTSC support */
+	format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
+	format->fmt.vbi.count[0] = 12;
+	format->fmt.vbi.count[1] = 12;
+	format->fmt.vbi.start[0] = 10;
+	format->fmt.vbi.start[1] = 273;
+
+	return 0;
+}
+
+static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
+				struct v4l2_format *format)
+{
+	format->fmt.vbi.samples_per_line = 720;
+	format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+	format->fmt.vbi.offset = 0;
+	format->fmt.vbi.flags = 0;
+
+	/* Varies by video standard (NTSC, PAL, etc.) */
+	/* FIXME: hard-coded for NTSC support */
+	format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
+	format->fmt.vbi.count[0] = 12;
+	format->fmt.vbi.count[1] = 12;
+	format->fmt.vbi.start[0] = 10;
+	format->fmt.vbi.start[1] = 273;
+
+	return 0;
+}
 
 static int vidioc_reqbufs(struct file *file, void *priv,
 			  struct v4l2_requestbuffers *rb)
@@ -1510,7 +1902,10 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	if (rc < 0)
 		return rc;
 
-	return videobuf_reqbufs(&fh->vb_vidq, rb);
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_reqbufs(&fh->vb_vidq, rb);
+	else
+		return videobuf_reqbufs(&fh->vb_vbiq, rb);
 }
 
 static int vidioc_querybuf(struct file *file, void *priv,
@@ -1524,7 +1919,18 @@ static int vidioc_querybuf(struct file *file, void *priv,
 	if (rc < 0)
 		return rc;
 
-	return videobuf_querybuf(&fh->vb_vidq, b);
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_querybuf(&fh->vb_vidq, b);
+	else {
+		/* FIXME: I'm not sure yet whether this is a bug in zvbi or
+		   the videobuf framework, but we probably shouldn't be
+		   returning a buffer larger than that which was asked for.
+		   At a minimum, it causes a crash in zvbi since it does
+		   a memcpy based on the source buffer length */
+		int result = videobuf_querybuf(&fh->vb_vbiq, b);
+		b->length = 17280;
+		return result;
+	}
 }
 
 static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1537,7 +1943,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 	if (rc < 0)
 		return rc;
 
-	return videobuf_qbuf(&fh->vb_vidq, b);
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_qbuf(&fh->vb_vidq, b);
+	else
+		return videobuf_qbuf(&fh->vb_vbiq, b);
 }
 
 static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1550,7 +1959,12 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 	if (rc < 0)
 		return rc;
 
-	return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags &
+				      O_NONBLOCK);
+	else
+		return videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags &
+				      O_NONBLOCK);
 }
 
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1558,7 +1972,10 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
 {
 	struct em28xx_fh  *fh = priv;
 
-	return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+	else
+		return videobuf_cgmbuf(&fh->vb_vbiq, mbuf, 8);
 }
 #endif
 
@@ -1654,9 +2071,9 @@ static int radio_queryctrl(struct file *file, void *priv,
 		qc->id >= V4L2_CID_LASTP1)
 		return -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
-		if (qc->id && qc->id == em28xx_qctrl[i].id) {
-			memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc));
+	for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) {
+		if (qc->id && qc->id == ac97_qctrl[i].id) {
+			memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc));
 			return 0;
 		}
 	}
@@ -1723,8 +2140,15 @@ static int em28xx_v4l2_open(struct file *filp)
 		field = V4L2_FIELD_INTERLACED;
 
 	videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
-			NULL, &dev->slock, fh->type, field,
-			sizeof(struct em28xx_buffer), fh);
+				    NULL, &dev->slock,
+				    V4L2_BUF_TYPE_VIDEO_CAPTURE, field,
+				    sizeof(struct em28xx_buffer), fh);
+
+	videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops,
+				    NULL, &dev->slock,
+				    V4L2_BUF_TYPE_VBI_CAPTURE,
+				    V4L2_FIELD_SEQ_TB,
+				    sizeof(struct em28xx_buffer), fh);
 
 	mutex_unlock(&dev->lock);
 
@@ -1781,20 +2205,21 @@ static int em28xx_v4l2_close(struct file *filp)
 
 	em28xx_videodbg("users=%d\n", dev->users);
 
+	if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
+		videobuf_stop(&fh->vb_vidq);
+		res_free(fh, EM28XX_RESOURCE_VIDEO);
+	}
 
-	mutex_lock(&dev->lock);
-	if (res_check(fh))
-		res_free(fh);
+	if (res_check(fh, EM28XX_RESOURCE_VBI)) {
+		videobuf_stop(&fh->vb_vbiq);
+		res_free(fh, EM28XX_RESOURCE_VBI);
+	}
 
 	if (dev->users == 1) {
-		videobuf_stop(&fh->vb_vidq);
-		videobuf_mmap_free(&fh->vb_vidq);
-
 		/* the device is already disconnect,
 		   free the remaining resources */
 		if (dev->state & DEV_DISCONNECTED) {
 			em28xx_release_resources(dev);
-			mutex_unlock(&dev->lock);
 			kfree(dev);
 			return 0;
 		}
@@ -1815,10 +2240,12 @@ static int em28xx_v4l2_close(struct file *filp)
 					"0 (error=%i)\n", errCode);
 		}
 	}
+
+	videobuf_mmap_free(&fh->vb_vidq);
+	videobuf_mmap_free(&fh->vb_vbiq);
 	kfree(fh);
 	dev->users--;
 	wake_up_interruptible_nr(&dev->open, 1);
-	mutex_unlock(&dev->lock);
 	return 0;
 }
 
@@ -1843,16 +2270,22 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
 	 */
 
 	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		mutex_lock(&dev->lock);
-		rc = res_get(fh);
-		mutex_unlock(&dev->lock);
-
-		if (unlikely(rc < 0))
-			return rc;
+		if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
+			return -EBUSY;
 
 		return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
 					filp->f_flags & O_NONBLOCK);
 	}
+
+
+	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		if (!res_get(fh, EM28XX_RESOURCE_VBI))
+			return -EBUSY;
+
+		return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
+					filp->f_flags & O_NONBLOCK);
+	}
+
 	return 0;
 }
 
@@ -1870,17 +2303,17 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
 	if (rc < 0)
 		return rc;
 
-	mutex_lock(&dev->lock);
-	rc = res_get(fh);
-	mutex_unlock(&dev->lock);
-
-	if (unlikely(rc < 0))
-		return POLLERR;
-
-	if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		if (!res_get(fh, EM28XX_RESOURCE_VIDEO))
+			return POLLERR;
+		return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+	} else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+		if (!res_get(fh, EM28XX_RESOURCE_VBI))
+			return POLLERR;
+		return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
+	} else {
 		return POLLERR;
-
-	return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+	}
 }
 
 /*
@@ -1896,14 +2329,10 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
 	if (rc < 0)
 		return rc;
 
-	mutex_lock(&dev->lock);
-	rc = res_get(fh);
-	mutex_unlock(&dev->lock);
-
-	if (unlikely(rc < 0))
-		return rc;
-
-	rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+	else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+		rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
 
 	em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
 		(unsigned long)vma->vm_start,
@@ -1929,6 +2358,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_g_fmt_vid_cap       = vidioc_g_fmt_vid_cap,
 	.vidioc_try_fmt_vid_cap     = vidioc_try_fmt_vid_cap,
 	.vidioc_s_fmt_vid_cap       = vidioc_s_fmt_vid_cap,
+	.vidioc_g_fmt_vbi_cap       = vidioc_g_fmt_vbi_cap,
+	.vidioc_s_fmt_vbi_cap       = vidioc_s_fmt_vbi_cap,
 	.vidioc_g_audio             = vidioc_g_audio,
 	.vidioc_s_audio             = vidioc_s_audio,
 	.vidioc_cropcap             = vidioc_cropcap,
@@ -1941,6 +2372,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querybuf            = vidioc_querybuf,
 	.vidioc_qbuf                = vidioc_qbuf,
 	.vidioc_dqbuf               = vidioc_dqbuf,
+	.vidioc_g_std               = vidioc_g_std,
 	.vidioc_s_std               = vidioc_s_std,
 	.vidioc_g_parm		    = vidioc_g_parm,
 	.vidioc_s_parm		    = vidioc_s_parm,
@@ -2062,13 +2494,10 @@ int em28xx_register_analog_devices(struct em28xx *dev)
 	dev->mute = 1;
 	dev->volume = 0x1f;
 
-	/* enable vbi capturing */
-
 /*	em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
 	val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
 	em28xx_write_reg(dev, EM28XX_R0F_XCLK,
 			 (EM28XX_XCLK_AUDIO_UNMUTE | val));
-	em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
 
 	em28xx_set_outfmt(dev);
 	em28xx_colorlevels_set_default(dev);
@@ -2091,14 +2520,17 @@ int em28xx_register_analog_devices(struct em28xx *dev)
 	}
 
 	/* Allocate and fill vbi video_device struct */
-	dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi");
+	if (em28xx_vbi_supported(dev) == 1) {
+		dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
+						"vbi");
 
-	/* register v4l2 vbi video_device */
-	ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
-					vbi_nr[dev->devno]);
-	if (ret < 0) {
-		em28xx_errdev("unable to register vbi device\n");
-		return ret;
+		/* register v4l2 vbi video_device */
+		ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
+					    vbi_nr[dev->devno]);
+		if (ret < 0) {
+			em28xx_errdev("unable to register vbi device\n");
+			return ret;
+		}
 	}
 
 	if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
@@ -2118,8 +2550,12 @@ int em28xx_register_analog_devices(struct em28xx *dev)
 			    dev->radio_dev->num);
 	}
 
-	em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
-				dev->vdev->num, dev->vbi_dev->num);
+	em28xx_info("V4L2 video device registered as /dev/video%d\n",
+				dev->vdev->num);
+
+	if (dev->vbi_dev)
+		em28xx_info("V4L2 VBI device registered as /dev/vbi%d\n",
+			    dev->vbi_dev->num);
 
 	return 0;
 }
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index a2add61..0a73e8b 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -108,6 +108,8 @@
 #define EM2882_BOARD_KWORLD_ATSC_315U		  69
 #define EM2882_BOARD_EVGA_INDTUBE		  70
 #define EM2820_BOARD_SILVERCREST_WEBCAM           71
+#define EM2861_BOARD_GADMEI_UTV330PLUS           72
+#define EM2870_BOARD_REDDO_DVB_C_USB_BOX          73
 
 /* Limits minimum and default number of buffers */
 #define EM28XX_MIN_BUF 4
@@ -213,7 +215,8 @@ struct em28xx_usb_isoc_ctl {
 	int				tmp_buf_len;
 
 		/* Stores already requested buffers */
-	struct em28xx_buffer    	*buf;
+	struct em28xx_buffer    	*vid_buf;
+	struct em28xx_buffer    	*vbi_buf;
 
 		/* Stores the number of received fields */
 	int				nfields;
@@ -398,6 +401,7 @@ struct em28xx_board {
 	unsigned int has_snapshot_button:1;
 	unsigned int is_webcam:1;
 	unsigned int valid:1;
+	unsigned int has_ir_i2c:1;
 
 	unsigned char xclk, i2c_speed;
 	unsigned char radio_addr;
@@ -408,7 +412,7 @@ struct em28xx_board {
 
 	struct em28xx_input       input[MAX_EM28XX_INPUT];
 	struct em28xx_input	  radio;
-	IR_KEYTAB_TYPE            *ir_codes;
+	struct ir_scancode_table  *ir_codes;
 };
 
 struct em28xx_eeprom {
@@ -441,6 +445,10 @@ enum em28xx_dev_state {
 #define EM28XX_AUDIO   0x10
 #define EM28XX_DVB     0x20
 
+/* em28xx resource types (used for res_get/res_lock etc */
+#define EM28XX_RESOURCE_VIDEO 0x01
+#define EM28XX_RESOURCE_VBI   0x02
+
 struct em28xx_audio {
 	char name[50];
 	char *transfer_buffer[EM28XX_AUDIO_BUFS];
@@ -461,10 +469,11 @@ struct em28xx;
 
 struct em28xx_fh {
 	struct em28xx *dev;
-	unsigned int  stream_on:1;	/* Locks streams */
 	int           radio;
+	unsigned int  resources;
 
 	struct videobuf_queue        vb_vidq;
+	struct videobuf_queue        vb_vbiq;
 
 	enum v4l2_buf_type           type;
 };
@@ -491,7 +500,6 @@ struct em28xx {
 	/* Vinmode/Vinctl used at the driver */
 	int vinmode, vinctl;
 
-	unsigned int stream_on:1;	/* Locks streams */
 	unsigned int has_audio_class:1;
 	unsigned int has_alsa_audio:1;
 
@@ -542,6 +550,12 @@ struct em28xx {
 	enum em28xx_dev_state state;
 	enum em28xx_io_method io;
 
+	/* vbi related state tracking */
+	int capture_type;
+	int vbi_read;
+	unsigned char cur_field;
+
+
 	struct work_struct         request_module_wk;
 
 	/* locks */
@@ -553,10 +567,14 @@ struct em28xx {
 	struct video_device *vbi_dev;
 	struct video_device *radio_dev;
 
+	/* resources in use */
+	unsigned int resources;
+
 	unsigned char eedata[256];
 
 	/* Isoc control struct */
 	struct em28xx_dmaqueue vidq;
+	struct em28xx_dmaqueue vbiq;
 	struct em28xx_usb_isoc_ctl isoc_ctl;
 	spinlock_t slock;
 
@@ -595,6 +613,10 @@ struct em28xx {
 	struct delayed_work sbutton_query_work;
 
 	struct em28xx_dvb *dvb;
+
+	/* I2C keyboard data */
+	struct i2c_board_info info;
+	struct IR_i2c_init_data init_data;
 };
 
 struct em28xx_ops {
@@ -633,6 +655,7 @@ int em28xx_audio_setup(struct em28xx *dev);
 
 int em28xx_colorlevels_set_default(struct em28xx *dev);
 int em28xx_capture_start(struct em28xx *dev, int start);
+int em28xx_vbi_supported(struct em28xx *dev);
 int em28xx_set_outfmt(struct em28xx *dev);
 int em28xx_resolution_set(struct em28xx *dev);
 int em28xx_set_alternate(struct em28xx *dev);
@@ -680,6 +703,9 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev);
 int em28xx_ir_init(struct em28xx *dev);
 int em28xx_ir_fini(struct em28xx *dev);
 
+/* Provided by em28xx-vbi.c */
+extern struct videobuf_queue_ops em28xx_vbi_qops;
+
 /* printk macros */
 
 #define em28xx_err(fmt, arg...) do {\
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index d1c1e45..74092f4 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1379,8 +1379,10 @@ et61x251_read(struct file* filp, char __user * buf,
 			    (!list_empty(&cam->outqueue)) ||
 			    (cam->state & DEV_DISCONNECTED) ||
 			    (cam->state & DEV_MISCONFIGURED),
-			    cam->module_param.frame_timeout *
-			    1000 * msecs_to_jiffies(1) );
+			    msecs_to_jiffies(
+				cam->module_param.frame_timeout * 1000
+			    )
+			  );
 		if (timeout < 0) {
 			mutex_unlock(&cam->fileop_mutex);
 			return timeout;
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index e994dca..fe2e490 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -19,6 +19,7 @@ if USB_GSPCA && VIDEO_V4L2
 
 source "drivers/media/video/gspca/m5602/Kconfig"
 source "drivers/media/video/gspca/stv06xx/Kconfig"
+source "drivers/media/video/gspca/gl860/Kconfig"
 
 config USB_GSPCA_CONEX
 	tristate "Conexant Camera Driver"
@@ -47,6 +48,15 @@ config USB_GSPCA_FINEPIX
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_finepix.
 
+config USB_GSPCA_JEILINJ
+	tristate "Jeilin JPEG USB V4L2 driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on this Jeilin chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_jeilinj.
+
 config USB_GSPCA_MARS
 	tristate "Mars USB Camera Driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
@@ -103,9 +113,9 @@ config USB_GSPCA_PAC7311
 	  module will be called gspca_pac7311.
 
 config USB_GSPCA_SN9C20X
-       tristate "SN9C20X USB Camera Driver"
-       depends on VIDEO_V4L2 && USB_GSPCA
-       help
+	tristate "SN9C20X USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
 	 Say Y here if you want support for cameras based on the
 	 sn9c20x chips (SN9C201 and SN9C202).
 
@@ -113,10 +123,10 @@ config USB_GSPCA_SN9C20X
 	 module will be called gspca_sn9c20x.
 
 config USB_GSPCA_SN9C20X_EVDEV
-       bool "Enable evdev support"
+	bool "Enable evdev support"
 	depends on USB_GSPCA_SN9C20X && INPUT
-       ---help---
-	 Say Y here in order to enable evdev support for sn9c20x webcam button.
+	---help---
+	  Say Y here in order to enable evdev support for sn9c20x webcam button.
 
 config USB_GSPCA_SONIXB
 	tristate "SONIX Bayer USB Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index f6d3b86..b742081 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_USB_GSPCA)          += gspca_main.o
 obj-$(CONFIG_USB_GSPCA_CONEX)    += gspca_conex.o
 obj-$(CONFIG_USB_GSPCA_ETOMS)    += gspca_etoms.o
 obj-$(CONFIG_USB_GSPCA_FINEPIX)  += gspca_finepix.o
+obj-$(CONFIG_USB_GSPCA_JEILINJ)  += gspca_jeilinj.o
 obj-$(CONFIG_USB_GSPCA_MARS)     += gspca_mars.o
 obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
 obj-$(CONFIG_USB_GSPCA_OV519)    += gspca_ov519.o
@@ -30,6 +31,7 @@ gspca_main-objs     := gspca.o
 gspca_conex-objs    := conex.o
 gspca_etoms-objs    := etoms.o
 gspca_finepix-objs  := finepix.o
+gspca_jeilinj-objs  := jeilinj.o
 gspca_mars-objs     := mars.o
 gspca_mr97310a-objs := mr97310a.o
 gspca_ov519-objs    := ov519.o
@@ -56,3 +58,4 @@ gspca_zc3xx-objs    := zc3xx.o
 
 obj-$(CONFIG_USB_M5602)   += m5602/
 obj-$(CONFIG_USB_STV06XX) += stv06xx/
+obj-$(CONFIG_USB_GL860)   += gl860/
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 8d48ea1..eca0035 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -820,7 +820,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
-	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+	cam->nmodes = ARRAY_SIZE(vga_mode);
 
 	sd->brightness = BRIGHTNESS_DEF;
 	sd->contrast = CONTRAST_DEF;
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 2c20d06..c1461e6 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -635,10 +635,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->sensor = id->driver_info;
 	if (sd->sensor == SENSOR_PAS106) {
 		cam->cam_mode = sif_mode;
-		cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+		cam->nmodes = ARRAY_SIZE(sif_mode);
 	} else {
 		cam->cam_mode = vga_mode;
-		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+		cam->nmodes = ARRAY_SIZE(vga_mode);
 		gspca_dev->ctrl_dis = (1 << COLOR_IDX);
 	}
 	sd->brightness = BRIGHTNESS_DEF;
diff --git a/drivers/media/video/gspca/gl860/Kconfig b/drivers/media/video/gspca/gl860/Kconfig
new file mode 100644
index 0000000..22772f5
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/Kconfig
@@ -0,0 +1,8 @@
+config USB_GL860
+	tristate "GL860 USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for cameras based on the GL860 chip.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_gl860.
diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/video/gspca/gl860/Makefile
new file mode 100644
index 0000000..13c9403
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/Makefile
@@ -0,0 +1,10 @@
+obj-$(CONFIG_USB_GL860) += gspca_gl860.o
+
+gspca_gl860-objs := gl860.o \
+		    gl860-mi1320.o \
+		    gl860-ov2640.o \
+		    gl860-ov9655.o \
+		    gl860-mi2020.o
+
+EXTRA_CFLAGS += -Idrivers/media/video/gspca
+
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c
new file mode 100644
index 0000000..39f6261
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c
@@ -0,0 +1,537 @@
+/* @file gl860-mi1320.c
+ * @author Olivier LORIN from my logs
+ * @date 2009-08-27
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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/>.
+ */
+
+/* Sensor : MI1320 */
+
+#include "gl860.h"
+
+static struct validx tbl_common[] = {
+	{0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba51, 0x0066}, {0xba02, 0x00f1},
+	{0xba05, 0x0067}, {0xba05, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
+	{0xffff, 0xffff},
+	{0xba00, 0x00f0}, {0xba02, 0x00f1}, {0xbafa, 0x0028}, {0xba02, 0x00f1},
+	{0xba00, 0x00f0}, {0xba01, 0x00f1}, {0xbaf0, 0x0006}, {0xba0e, 0x00f1},
+	{0xba70, 0x0006}, {0xba0e, 0x00f1},
+	{0xffff, 0xffff},
+	{0xba74, 0x0006}, {0xba0e, 0x00f1},
+	{0xffff, 0xffff},
+	{0x0061, 0x0000}, {0x0068, 0x000d},
+};
+
+static struct validx tbl_init_at_startup[] = {
+	{0x0000, 0x0000}, {0x0010, 0x0010},
+	{35, 0xffff},
+	{0x0008, 0x00c0}, {0x0001, 0x00c1}, {0x0001, 0x00c2}, {0x0020, 0x0006},
+	{0x006a, 0x000d},
+};
+
+static struct validx tbl_sensor_settings_common[] = {
+	{0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0040, 0x0000},
+	{0x006a, 0x0007}, {0x006a, 0x000d}, {0x0063, 0x0006},
+};
+static struct validx tbl_sensor_settings_1280[] = {
+	{0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
+	{0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
+};
+static struct validx tbl_sensor_settings_800[] = {
+	{0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
+	{0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
+};
+static struct validx tbl_sensor_settings_640[] = {
+	{0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
+	{0xba51, 0x0066}, {0xba02, 0x00f1}, {0xba05, 0x0067}, {0xba05, 0x00f1},
+	{0xba20, 0x0065}, {0xba00, 0x00f1},
+};
+static struct validx tbl_post_unset_alt[] = {
+	{0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
+	{0x0061, 0x0000}, {0x0068, 0x000d},
+};
+
+static u8 *tbl_1280[] = {
+	"\x0d\x80\xf1\x08\x03\x04\xf1\x00" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
+	"\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
+	"\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
+	"\xa9\x04\xf1\x00\xa1\x05\xf1\x00" "\xa4\x04\xf1\x00\xae\x0a\xf1\x08"
+	,
+	"\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
+	"\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
+	"\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
+	,
+	"\xd3\x02\xd4\x28\xd5\x01\xd0\x02" "\xd1\x18\xd2\xc1"
+};
+
+static u8 *tbl_800[] = {
+	"\x0d\x80\xf1\x08\x03\x03\xf1\xc0" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
+	"\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
+	"\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
+	"\xa9\x03\xf1\xc0\xa1\x03\xf1\x20" "\xa4\x02\xf1\x5a\xae\x0a\xf1\x08"
+	,
+	"\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
+	"\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
+	"\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
+	,
+	"\xd3\x02\xd4\x18\xd5\x21\xd0\x02" "\xd1\x10\xd2\x59"
+};
+
+static u8 *tbl_640[] = {
+	"\x0d\x80\xf1\x08\x03\x04\xf1\x04" "\x04\x05\xf1\x02\x07\x01\xf1\x7c"
+	"\x08\x00\xf1\x0e\x21\x80\xf1\x00" "\x0d\x00\xf1\x08\xf0\x00\xf1\x01"
+	"\x34\x10\xf1\x10\x3a\x43\xf1\x00" "\xa6\x05\xf1\x02\xa9\x04\xf1\x04"
+	"\xa7\x02\xf1\x81\xaa\x01\xf1\xe2" "\xae\x0c\xf1\x09"
+	,
+	"\xf0\x00\xf1\x02\x39\x03\xf1\xfc" "\x3b\x04\xf1\x04\x57\x01\xf1\xb6"
+	"\x58\x02\xf1\x0d\x5c\x1f\xf1\x19" "\x5d\x24\xf1\x1e\x64\x5e\xf1\x1c"
+	"\xd2\x00\xf1\x00\xcb\x00\xf1\x01"
+	,
+	"\xd3\x02\xd4\x10\xd5\x81\xd0\x02" "\xd1\x08\xd2\xe1"
+};
+
+static s32 tbl_sat[] = {0x25, 0x1d, 0x15, 0x0d, 0x05, 0x4d, 0x55, 0x5d, 0x2d};
+static s32 tbl_bright[] = {0, 8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70};
+static s32 tbl_backlight[] = {0x0e, 0x06, 0x02};
+
+static s32 tbl_cntr1[] = {
+	0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, 0xc8, 0xd0, 0xe0, 0xf0};
+static s32 tbl_cntr2[] = {
+	0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, 0x38, 0x30, 0x20, 0x10};
+
+static u8 dat_wbalNL[] =
+	"\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x3b\x04\xf1\x2a\x47\x10\xf1\x10"
+	"\x9d\x3c\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\x91\xf1\x20"
+	"\x9c\x91\xf1\x20\x37\x03\xf1\x00" "\x9d\xc5\xf1\x0f\xf0\x00\xf1\x00";
+
+static u8 dat_wbalLL[] =
+	"\xf0\x00\xf1\x01\x05\x00\xf1\x0c" "\x3b\x04\xf1\x2a\x47\x40\xf1\x40"
+	"\x9d\x20\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\xd1\xf1\x00"
+	"\x9c\xd1\xf1\x00\x37\x03\xf1\x00" "\x9d\xc5\xf1\x3f\xf0\x00\xf1\x00";
+
+static u8 dat_wbalBL[] =
+	"\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x47\x10\xf1\x30\x9d\x3c\xf1\xae"
+	"\xaf\x10\xf1\x00\xf0\x00\xf1\x02" "\x2f\x91\xf1\x20\x9c\x91\xf1\x20"
+	"\x37\x03\xf1\x00\x9d\xc5\xf1\x2f" "\xf0\x00\xf1\x00";
+
+static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
+
+static u8 s000[] =
+	"\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
+	"\xd8\x04\x58\x00\x04\x02";
+static u8 s001[] =
+	"\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
+	"\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
+static u8 s002[] =
+	"\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
+	"\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
+	"\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
+static u8 s003[] =
+	"\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
+	"\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
+	"\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
+static u8 s004[] =
+	"\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
+static u8 s005[] =
+	"\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
+	"\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
+	"\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
+static u8 s006[] =
+	"\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
+	"\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
+	"\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
+static u8 s007[] =
+	"\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
+	"\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
+	"\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
+	"\xe1\xff\xf1\x00";
+static u8 s008[] =
+	"\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
+	"\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
+	"\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
+static u8 s009[] =
+	"\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
+	"\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
+	"\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
+static u8 s010[] =
+	"\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
+	"\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
+	"\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
+	"\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
+static u8 s011[] =
+	"\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
+	"\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
+	"\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
+
+static int  mi1320_init_at_startup(struct gspca_dev *gspca_dev);
+static int  mi1320_configure_alt(struct gspca_dev *gspca_dev);
+static int  mi1320_init_pre_alt(struct gspca_dev *gspca_dev);
+static int  mi1320_init_post_alt(struct gspca_dev *gspca_dev);
+static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev);
+static int  mi1320_sensor_settings(struct gspca_dev *gspca_dev);
+static int  mi1320_camera_settings(struct gspca_dev *gspca_dev);
+/*==========================================================================*/
+
+void mi1320_init_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vcur.backlight  =  0;
+	sd->vcur.brightness =  0;
+	sd->vcur.sharpness  =  6;
+	sd->vcur.contrast   = 10;
+	sd->vcur.gamma      = 20;
+	sd->vcur.hue        =  0;
+	sd->vcur.saturation =  6;
+	sd->vcur.whitebal   =  0;
+	sd->vcur.mirror     = 0;
+	sd->vcur.flip       = 0;
+	sd->vcur.AC50Hz     = 1;
+
+	sd->vmax.backlight  =  2;
+	sd->vmax.brightness =  8;
+	sd->vmax.sharpness  =  7;
+	sd->vmax.contrast   =  0; /* 10 but not working with tihs driver */
+	sd->vmax.gamma      = 40;
+	sd->vmax.hue        =  5 + 1;
+	sd->vmax.saturation =  8;
+	sd->vmax.whitebal   =  2;
+	sd->vmax.mirror     = 1;
+	sd->vmax.flip       = 1;
+	sd->vmax.AC50Hz     = 1;
+
+	sd->dev_camera_settings = mi1320_camera_settings;
+	sd->dev_init_at_startup = mi1320_init_at_startup;
+	sd->dev_configure_alt   = mi1320_configure_alt;
+	sd->dev_init_pre_alt    = mi1320_init_pre_alt;
+	sd->dev_post_unset_alt  = mi1320_post_unset_alt;
+}
+
+/*==========================================================================*/
+
+static void common(struct gspca_dev *gspca_dev)
+{
+	s32 n; /* reserved for FETCH macros */
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000);
+	ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001);
+	n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006);
+	keep_on_fetching_validx(gspca_dev, tbl_common,
+					ARRAY_SIZE(tbl_common), n);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010);
+	keep_on_fetching_validx(gspca_dev, tbl_common,
+					ARRAY_SIZE(tbl_common), n);
+	ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011);
+	keep_on_fetching_validx(gspca_dev, tbl_common,
+					ARRAY_SIZE(tbl_common), n);
+}
+
+static int mi1320_init_at_startup(struct gspca_dev *gspca_dev)
+{
+	fetch_validx(gspca_dev, tbl_init_at_startup,
+				ARRAY_SIZE(tbl_init_at_startup));
+
+	common(gspca_dev);
+
+/*	ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
+
+	return 0;
+}
+
+static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->mirrorMask = 0;
+
+	sd->vold.backlight  = -1;
+	sd->vold.brightness = -1;
+	sd->vold.sharpness  = -1;
+	sd->vold.contrast   = -1;
+	sd->vold.saturation = -1;
+	sd->vold.gamma    = -1;
+	sd->vold.hue      = -1;
+	sd->vold.whitebal = -1;
+	sd->vold.mirror   = -1;
+	sd->vold.flip     = -1;
+	sd->vold.AC50Hz   = -1;
+
+	common(gspca_dev);
+
+	mi1320_sensor_settings(gspca_dev);
+
+	mi1320_init_post_alt(gspca_dev);
+
+	return 0;
+}
+
+static int mi1320_init_post_alt(struct gspca_dev *gspca_dev)
+{
+	mi1320_camera_settings(gspca_dev);
+
+	return 0;
+}
+
+static int mi1320_sensor_settings(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+
+	ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
+
+	fetch_validx(gspca_dev, tbl_sensor_settings_common,
+				ARRAY_SIZE(tbl_sensor_settings_common));
+
+	switch (reso) {
+	case IMAGE_1280:
+		fetch_validx(gspca_dev, tbl_sensor_settings_1280,
+					ARRAY_SIZE(tbl_sensor_settings_1280));
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_1280[0]);
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_1280[1]);
+		ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_1280[2]);
+		break;
+
+	case IMAGE_800:
+		fetch_validx(gspca_dev, tbl_sensor_settings_800,
+					ARRAY_SIZE(tbl_sensor_settings_800));
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_800[0]);
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_800[1]);
+		ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_800[2]);
+		break;
+
+	default:
+		fetch_validx(gspca_dev, tbl_sensor_settings_640,
+					ARRAY_SIZE(tbl_sensor_settings_640));
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 60, tbl_640[0]);
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_640[1]);
+		ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_640[2]);
+		break;
+	}
+	return 0;
+}
+
+static int mi1320_configure_alt(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+
+	switch (reso) {
+	case IMAGE_640:
+		gspca_dev->alt = 3 + 1;
+		break;
+
+	case IMAGE_800:
+	case IMAGE_1280:
+		gspca_dev->alt = 1 + 1;
+		break;
+	}
+	return 0;
+}
+
+int mi1320_camera_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	s32 backlight = sd->vcur.backlight;
+	s32 bright = sd->vcur.brightness;
+	s32 sharp  = sd->vcur.sharpness;
+	s32 cntr   = sd->vcur.contrast;
+	s32 gam	   = sd->vcur.gamma;
+	s32 hue    = sd->vcur.hue;
+	s32 sat	   = sd->vcur.saturation;
+	s32 wbal   = sd->vcur.whitebal;
+	s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
+	s32 flip   = (((sd->vcur.flip   > 0) ^ sd->mirrorMask) > 0);
+	s32 freq   = (sd->vcur.AC50Hz > 0);
+	s32 i;
+
+	if (freq != sd->vold.AC50Hz) {
+		sd->vold.AC50Hz = freq;
+
+		freq = 2 * (freq == 0);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba02, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00       , 0x005b, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01 + freq, 0x00f1, 0, NULL);
+	}
+
+	if (wbal != sd->vold.whitebal) {
+		sd->vold.whitebal = wbal;
+		if (wbal < 0 || wbal > sd->vmax.whitebal)
+			wbal = 0;
+
+		for (i = 0; i < 2; i++) {
+			if (wbal == 0) { /* Normal light */
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0010, 0x0010, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0003, 0x00c1, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0042, 0x00c2, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 3,
+						0xba00, 0x0200, 48, dat_wbalNL);
+			}
+
+			if (wbal == 1) { /* Low light */
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0010, 0x0010, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0004, 0x00c1, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0043, 0x00c2, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 3,
+						0xba00, 0x0200, 48, dat_wbalLL);
+			}
+
+			if (wbal == 2) { /* Back light */
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0010, 0x0010, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0003, 0x00c1, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 1,
+						0x0042, 0x00c2, 0, NULL);
+				ctrl_out(gspca_dev, 0x40, 3,
+						0xba00, 0x0200, 44, dat_wbalBL);
+			}
+		}
+	}
+
+	if (bright != sd->vold.brightness) {
+		sd->vold.brightness = bright;
+		if (bright < 0 || bright > sd->vmax.brightness)
+			bright = 0;
+
+		bright = tbl_bright[bright];
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x0034, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x00f1, 0, NULL);
+	}
+
+	if (sat != sd->vold.saturation) {
+		sd->vold.saturation = sat;
+		if (sat < 0 || sat > sd->vmax.saturation)
+			sat = 0;
+
+		sat = tbl_sat[sat];
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00      , 0x0025, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sat, 0x00f1, 0, NULL);
+	}
+
+	if (sharp != sd->vold.sharpness) {
+		sd->vold.sharpness = sharp;
+		if (sharp < 0 || sharp > sd->vmax.sharpness)
+			sharp = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00        , 0x0005, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sharp, 0x00f1, 0, NULL);
+	}
+
+	if (hue != sd->vold.hue) {
+		/* 0=normal  1=NB  2="sepia"  3=negative  4=other  5=other2 */
+		if (hue < 0 || hue > sd->vmax.hue)
+			hue = 0;
+		if (hue == sd->vmax.hue)
+			sd->swapRB = 1;
+		else
+			sd->swapRB = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
+							0, NULL);
+	}
+
+	if (backlight != sd->vold.backlight) {
+		sd->vold.backlight = backlight;
+		if (backlight < 0 || backlight > sd->vmax.backlight)
+			backlight = 0;
+
+		backlight = tbl_backlight[backlight];
+		for (i = 0; i < 2; i++) {
+			ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0xba74, 0x0006, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0xba80 + backlight, 0x00f1,
+								0, NULL);
+		}
+	}
+
+	if (hue != sd->vold.hue) {
+		sd->vold.hue = hue;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
+							0, NULL);
+	}
+
+	if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
+		u8 dat_hvflip2[4] = {0x20, 0x01, 0xf1, 0x00};
+		sd->vold.mirror = mirror;
+		sd->vold.flip = flip;
+
+		dat_hvflip2[3] = flip + 2 * mirror;
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip1);
+		ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip2);
+	}
+
+	if (gam != sd->vold.gamma) {
+		sd->vold.gamma = gam;
+		if (gam < 0 || gam > sd->vmax.gamma)
+			gam = 0;
+
+		gam = 2 * gam;
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba04      , 0x003b, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba02 + gam, 0x00f1, 0, NULL);
+	}
+
+	if (cntr != sd->vold.contrast) {
+		sd->vold.contrast = cntr;
+		if (cntr < 0 || cntr > sd->vmax.contrast)
+			cntr = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr1[cntr], 0x0035,
+							0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr2[cntr], 0x00f1,
+							0, NULL);
+	}
+
+	return 0;
+}
+
+static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev)
+{
+	ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
+
+	fetch_validx(gspca_dev, tbl_post_unset_alt,
+				ARRAY_SIZE(tbl_post_unset_alt));
+}
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
new file mode 100644
index 0000000..ffb09fe
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -0,0 +1,937 @@
+/* @file gl860-mi2020.c
+ * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
+ * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
+ * @date 2009-08-27
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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/>.
+ */
+
+/* Sensor : MI2020 */
+
+#include "gl860.h"
+
+static u8 dat_bright1[] = {0x8c, 0xa2, 0x06};
+static u8 dat_bright3[] = {0x8c, 0xa1, 0x02};
+static u8 dat_bright4[] = {0x90, 0x00, 0x0f};
+static u8 dat_bright5[] = {0x8c, 0xa1, 0x03};
+static u8 dat_bright6[] = {0x90, 0x00, 0x05};
+
+static u8 dat_dummy1[] = {0x90, 0x00, 0x06};
+/*static u8 dummy2[] = {0x8c, 0xa1, 0x02};*/
+/*static u8 dummy3[] = {0x90, 0x00, 0x1f};*/
+
+static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19};
+static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b};
+static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03};
+static u8 dat_hvflip6[] = {0x90, 0x00, 0x06};
+
+static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
+
+static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
+static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
+
+static struct validx tbl_common_a[] = {
+	{0x0000, 0x0000},
+	{1, 0xffff}, /* msleep(35); */
+	{0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
+	{0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0004, 0x00d8},
+	{0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
+};
+
+static struct validx tbl_common_b[] = {
+	{0x006a, 0x0007},
+	{35, 0xffff},
+	{0x00ef, 0x0006},
+	{35, 0xffff},
+	{0x006a, 0x000d},
+	{35, 0xffff},
+	{0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2},
+	{0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
+};
+
+static struct idxdata tbl_common_c[] = {
+	{0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
+	{6, "\xff\xff\xff"}, /* 12 */
+	{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
+	{2, "\xff\xff\xff"}, /* - */
+	{0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\x22\x23"},
+	{0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0f"}, {0x33, "\x90\x00\x0d"},
+	{0x33, "\x8c\xa2\x10"}, {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x11"},
+	{0x33, "\x90\x00\x07"}, {0x33, "\xf4\x03\x1d"}, {0x35, "\xa2\x00\xe2"},
+	{0x33, "\x8c\xab\x05"}, {0x33, "\x90\x00\x01"}, {0x32, "\x6e\x00\x86"},
+	{0x32, "\x70\x0f\xaa"}, {0x32, "\x72\x0f\xe4"}, {0x33, "\x8c\xa3\x4a"},
+	{0x33, "\x90\x00\x5a"}, {0x33, "\x8c\xa3\x4b"}, {0x33, "\x90\x00\xa6"},
+	{0x33, "\x8c\xa3\x61"}, {0x33, "\x90\x00\xc8"}, {0x33, "\x8c\xa3\x62"},
+	{0x33, "\x90\x00\xe1"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
+	{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
+	{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
+	{0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
+	{0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
+	{0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
+	{0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
+	{0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
+	{0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
+	{0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
+	{0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
+	{0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
+	{0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
+	{0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
+	{0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
+	{0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
+	{0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
+	{0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
+	{0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
+	{0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
+	{0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
+	{0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
+	{0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
+	{0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
+	{0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
+	{0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
+	{1, "\xff\xff\xff"},
+	{0x33, "\x78\x00\x00"},
+	{1, "\xff\xff\xff"},
+	{0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"},
+	{0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"},
+	{0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"},
+	{0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"},
+	{0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
+};
+
+static struct idxdata tbl_common_d[] = {
+	{0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
+	{0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
+	{0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
+	{0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa0"},
+	{0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc0"}, {0x33, "\x8c\x24\x15"},
+	{0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
+};
+
+static struct idxdata tbl_common_e[] = {
+	{0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
+	{0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
+	{0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
+	{0x33, "\x90\x00\x04"}, {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
+	/* msleep(53); */
+	{0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"},
+	{0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"},
+	{0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
+	{0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"},
+	{0x33, "\x90\x02\x84"}, {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"},
+	{0x33, "\x8c\x27\x07"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"},
+	{0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"},
+	{0x33, "\x8c\x27\x0f"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"},
+	{0x33, "\x90\x04\xbd"}, {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"},
+	{0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
+	{0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
+	{0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"},
+	{0x33, "\x90\x01\x02"}, {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"},
+	{0x33, "\x8c\x27\x21"}, {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"},
+	{0x33, "\x90\x02\x85"}, {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"},
+	{0x33, "\x8c\x27\x27"}, {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"},
+	{0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"},
+	{0x33, "\x8c\x27\x2d"}, {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"},
+	{0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"},
+	{0x33, "\x8c\x27\x33"}, {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"},
+	{0x33, "\x90\x06\x4b"}, {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"},
+	{0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"},
+	{0x33, "\x90\x00\x24"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
+	{0x33, "\x8c\x27\x41"}, {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"},
+	{0x33, "\x90\x04\xed"}, {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"},
+	{0x33, "\x8c\x27\x51"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"},
+	{0x33, "\x90\x03\x20"}, {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"},
+	{0x33, "\x8c\x27\x57"}, {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"},
+	{0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"},
+	{0x33, "\x8c\x27\x63"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"},
+	{0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"},
+	{0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"},
+	{0x33, "\x90\x00\x21"}, {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"},
+	{0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"},
+	{0x33, "\x90\x00\xa1"}, {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"},
+	{0x33, "\x8c\x24\x15"},
+};
+
+static struct validx tbl_init_at_startup[] = {
+	{0x0000, 0x0000},
+	{53, 0xffff},
+	{0x0010, 0x0010},
+	{53, 0xffff},
+	{0x0008, 0x00c0},
+	{53, 0xffff},
+	{0x0001, 0x00c1},
+	{53, 0xffff},
+	{0x0001, 0x00c2},
+	{53, 0xffff},
+	{0x0020, 0x0006},
+	{53, 0xffff},
+	{0x006a, 0x000d},
+	{53, 0xffff},
+};
+
+static struct idxdata tbl_init_post_alt_low_a[] = {
+	{0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
+	{0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
+	{0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
+	{0x33, "\x90\x00\x1d"}, {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x20"},
+	{0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\x24\x13"},
+	{0x33, "\x90\x00\x9b"},
+};
+
+static struct idxdata tbl_init_post_alt_low_b[] = {
+	{0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
+	{0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
+	{2, "\xff\xff\xff"},
+};
+
+static struct idxdata tbl_init_post_alt_low_c[] = {
+	{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
+	{2, "\xff\xff\xff"},
+	{0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
+	{0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"},
+	{0x33, "\x2e\x01\x00"}, {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"},
+	{0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x95"}, {0x33, "\x90\x01\x00"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"},
+	{0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
+	{0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
+	{2, "\xff\xff\xff"}, /* - * */
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
+	{1, "\xff\xff\xff"},
+};
+
+static struct idxdata tbl_init_post_alt_low_d[] = {
+	{0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
+	{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
+	{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
+	{0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
+	{0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
+	{0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
+	{0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
+	{0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
+	{0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
+	{0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
+	{0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
+	{0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
+	{0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
+	{0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
+	{0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
+	{0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
+	{0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
+	{0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
+	{0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
+	{0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
+	{0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
+	{0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
+	{0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
+	{0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
+	{0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
+	{0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"},
+	/* Flip/Mirror h/v=1 */
+	{0x33, "\x90\x00\x3c"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
+	{0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"}, {0x33, "\x8c\xa1\x03"},
+	{0x33, "\x90\x00\x06"},
+	{130, "\xff\xff\xff"},
+	{0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
+	{0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
+	{100, "\xff\xff\xff"},
+	/* ?? */
+	{0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"},
+	{0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
+	{0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
+	/* Brigthness=70 */
+	{0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x46"}, {0x33, "\x8c\xa1\x02"},
+	{0x33, "\x90\x00\x0f"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
+	/* Sharpness=20 */
+	{0x32, "\x6c\x14\x08"},
+};
+
+static struct idxdata tbl_init_post_alt_big_a[] = {
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
+	{2, "\xff\xff\xff"},
+	{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
+	{0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"},
+	{0x33, "\x90\x00\x05"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
+	{2, "\xff\xff\xff"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, {0x33, "\x8c\xa1\x20"},
+	{0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x30"}, {0x33, "\x90\x00\x03"},
+	{0x33, "\x8c\xa1\x31"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x32"},
+	{0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"},
+	{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"},
+	{0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
+};
+
+static struct idxdata tbl_init_post_alt_big_b[] = {
+	{0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
+	{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
+	{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
+	{0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
+	{0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
+	{0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
+	{0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
+	{0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
+	{0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
+	{0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
+	{0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
+	{0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
+	{0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
+	{0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
+	{0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
+	{0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
+	{0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
+	{0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
+	{0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
+	{0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
+	{0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
+	{0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
+	{0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
+	{0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
+	{0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
+	{0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
+};
+
+static struct idxdata tbl_init_post_alt_big_c[] = {
+	{0x33, "\x8c\xa1\x02"},
+	{0x33, "\x90\x00\x1f"},
+	{0x33, "\x8c\xa1\x02"},
+	{0x33, "\x90\x00\x1f"},
+	{0x33, "\x8c\xa1\x02"},
+	{0x33, "\x90\x00\x1f"},
+	{0x33, "\x8c\xa1\x02"},
+	{0x33, "\x90\x00\x1f"},
+};
+
+static u8 *dat_640  = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81";
+static u8 *dat_800  = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21";
+static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01";
+static u8 *dat_1600 = "\xd0\x02\xd1\x20\xd2\xaf\xd3\x02\xd4\x30\xd5\x41";
+
+static int  mi2020_init_at_startup(struct gspca_dev *gspca_dev);
+static int  mi2020_configure_alt(struct gspca_dev *gspca_dev);
+static int  mi2020_init_pre_alt(struct gspca_dev *gspca_dev);
+static int  mi2020_init_post_alt(struct gspca_dev *gspca_dev);
+static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev);
+static int  mi2020_camera_settings(struct gspca_dev *gspca_dev);
+/*==========================================================================*/
+
+void mi2020_init_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vcur.backlight  =  0;
+	sd->vcur.brightness = 70;
+	sd->vcur.sharpness  = 20;
+	sd->vcur.contrast   =  0;
+	sd->vcur.gamma      =  0;
+	sd->vcur.hue        =  0;
+	sd->vcur.saturation = 60;
+	sd->vcur.whitebal   = 50;
+	sd->vcur.mirror = 0;
+	sd->vcur.flip   = 0;
+	sd->vcur.AC50Hz = 1;
+
+	sd->vmax.backlight  =  64;
+	sd->vmax.brightness = 128;
+	sd->vmax.sharpness  =  40;
+	sd->vmax.contrast   =   3;
+	sd->vmax.gamma      =   2;
+	sd->vmax.hue        =   0 + 1; /* 200 */
+	sd->vmax.saturation =   0;     /* 100 */
+	sd->vmax.whitebal   =   0;     /* 100 */
+	sd->vmax.mirror = 1;
+	sd->vmax.flip   = 1;
+	sd->vmax.AC50Hz = 1;
+	if (_MI2020b_) {
+		sd->vmax.contrast  = 0;
+		sd->vmax.gamma     = 0;
+		sd->vmax.backlight = 0;
+	}
+
+	sd->dev_camera_settings = mi2020_camera_settings;
+	sd->dev_init_at_startup = mi2020_init_at_startup;
+	sd->dev_configure_alt   = mi2020_configure_alt;
+	sd->dev_init_pre_alt    = mi2020_init_pre_alt;
+	sd->dev_post_unset_alt  = mi2020_post_unset_alt;
+}
+
+/*==========================================================================*/
+
+static void common(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+
+	if (_MI2020b_) {
+		fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a));
+	} else {
+		if (_MI2020_)
+			ctrl_out(gspca_dev, 0x40,  1, 0x0008, 0x0004,  0, NULL);
+		else
+			ctrl_out(gspca_dev, 0x40,  1, 0x0002, 0x0004,  0, NULL);
+		msleep(35);
+		fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b));
+	}
+	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x01");
+	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0033,  3, "\x86\x25\x00");
+	msleep(2); /* - * */
+	ctrl_out(gspca_dev, 0x40,  3, 0x7a00, 0x0030,  3, "\x1a\x0a\xcc");
+	if (reso == IMAGE_1600)
+		msleep(2); /* 1600 */
+	fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c));
+
+	if (_MI2020b_ || _MI2020_)
+		fetch_idxdata(gspca_dev, tbl_common_d,
+				ARRAY_SIZE(tbl_common_d));
+
+	fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e));
+	if (_MI2020b_ || _MI2020_) {
+		/* Different from fret */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
+		/* Same as fret */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
+		/* Different from fret */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x90");
+	} else {
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x6a");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x80");
+	}
+	ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
+	ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x05");
+	msleep(2);
+	ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
+	if (reso == IMAGE_1600)
+		msleep(14); /* 1600 */
+	ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x06");
+	msleep(2);
+}
+
+static int mi2020_init_at_startup(struct gspca_dev *gspca_dev)
+{
+	u8 c;
+
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
+
+	fetch_validx(gspca_dev, tbl_init_at_startup,
+			ARRAY_SIZE(tbl_init_at_startup));
+
+	common(gspca_dev);
+
+	return 0;
+}
+
+static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->mirrorMask = 0;
+
+	sd->vold.backlight  = -1;
+	sd->vold.brightness = -1;
+	sd->vold.sharpness  = -1;
+	sd->vold.contrast   = -1;
+	sd->vold.gamma  = -1;
+	sd->vold.hue    = -1;
+	sd->vold.mirror = -1;
+	sd->vold.flip   = -1;
+	sd->vold.AC50Hz = -1;
+
+	mi2020_init_post_alt(gspca_dev);
+
+	return 0;
+}
+
+static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+
+	s32 backlight = sd->vcur.backlight;
+	s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
+	s32 flip   = (((sd->vcur.flip   > 0) ^ sd->mirrorMask) > 0);
+	s32 freq   = (sd->vcur.AC50Hz  > 0);
+
+	u8 dat_freq2[] = {0x90, 0x00, 0x80};
+	u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
+	u8 dat_multi2[] = {0x90, 0x00, 0x00};
+	u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
+	u8 dat_multi4[] = {0x90, 0x00, 0x00};
+	u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
+	u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
+	u8 c;
+
+	sd->nbIm = -1;
+
+	dat_freq2[2] = freq ? 0xc0 : 0x80;
+	dat_multi1[2] = 0x9d;
+	dat_multi3[2] = dat_multi1[2] + 1;
+	dat_multi4[2] = dat_multi2[2] = backlight;
+	dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
+	dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
+
+	msleep(200);
+
+	ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
+	msleep(3); /* 35 * */
+
+	common(gspca_dev);
+
+	ctrl_out(gspca_dev, 0x40,  1, 0x0041, 0x0000,  0, NULL);
+	msleep(70);
+
+	if (_MI2020b_)
+		ctrl_out(gspca_dev, 0x40,  1, 0x0040, 0x0000,  0, NULL);
+
+	ctrl_out(gspca_dev, 0x40,  1, 0x0010, 0x0010,  0, NULL);
+	ctrl_out(gspca_dev, 0x40,  1, 0x0003, 0x00c1,  0, NULL);
+	ctrl_out(gspca_dev, 0x40,  1, 0x0042, 0x00c2,  0, NULL);
+	ctrl_out(gspca_dev, 0x40,  1, 0x006a, 0x000d,  0, NULL);
+
+	switch (reso) {
+	case IMAGE_640:
+	case IMAGE_800:
+		if (reso != IMAGE_800)
+			ctrl_out(gspca_dev, 0x40,  3, 0x0000, 0x0200,
+				12, dat_640);
+		else
+			ctrl_out(gspca_dev, 0x40,  3, 0x0000, 0x0200,
+				12, dat_800);
+
+		if (_MI2020c_)
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a,
+					ARRAY_SIZE(tbl_init_post_alt_low_a));
+
+		if (reso == IMAGE_800)
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b,
+					ARRAY_SIZE(tbl_init_post_alt_low_b));
+
+		fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c,
+				ARRAY_SIZE(tbl_init_post_alt_low_c));
+
+		if (_MI2020b_) {
+			ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
+			msleep(150);
+		} else if (_MI2020c_) {
+			ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
+			msleep(120);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
+			msleep(30);
+		} else if (_MI2020_) {
+			ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
+			msleep(120);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
+			msleep(30);
+		}
+
+		/* AC power frequency */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
+		msleep(20);
+		/* backlight */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
+		/* at init time but not after */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
+		/* finish the backlight */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+		msleep(5);/* " */
+
+		if (_MI2020c_) {
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d,
+					ARRAY_SIZE(tbl_init_post_alt_low_d));
+		} else {
+			ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
+			msleep(14); /* 0xd8 */
+
+			/* flip/mirror */
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_hvflip1);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_hvflip2);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_hvflip3);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_hvflip4);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_hvflip5);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_hvflip6);
+			msleep(21);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_dummy1);
+			msleep(5);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_dummy1);
+			msleep(5);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_dummy1);
+			msleep(5);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_dummy1);
+			msleep(5);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_dummy1);
+			msleep(5);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, dat_dummy1);
+			/* end of flip/mirror main part */
+			msleep(246); /* 146 */
+
+			sd->nbIm = 0;
+		}
+		break;
+
+	case IMAGE_1280:
+	case IMAGE_1600:
+		if (reso == IMAGE_1280) {
+			ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
+					12, dat_1280);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x8c\x27\x07");
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x90\x05\x04");
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x8c\x27\x09");
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x90\x04\x02");
+		} else {
+			ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
+					12, dat_1600);
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x8c\x27\x07");
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x90\x06\x40");
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x8c\x27\x09");
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
+					3, "\x90\x04\xb0");
+		}
+
+		fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a,
+				ARRAY_SIZE(tbl_init_post_alt_big_a));
+
+		if (reso == IMAGE_1600)
+			msleep(13); /* 1600 */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x27\x97");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x01\x00");
+		msleep(53);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
+		if (reso == IMAGE_1600)
+			msleep(13); /* 1600 */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
+		msleep(53);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
+		if (reso == IMAGE_1600)
+			msleep(13); /* 1600 */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
+		msleep(53);
+
+		if (_MI2020b_) {
+			ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
+			if (reso == IMAGE_1600)
+				msleep(500); /* 1600 */
+			ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
+			msleep(1850);
+		} else if (_MI2020c_ || _MI2020_) {
+			ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
+			msleep(1850);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
+			msleep(30);
+		}
+
+		/* AC power frequency */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
+		msleep(20);
+		/* backlight */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
+		/* at init time but not after */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
+		/* finish the backlight */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+		msleep(6); /* " */
+
+		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
+		msleep(14);
+
+		if (_MI2020c_)
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b,
+					ARRAY_SIZE(tbl_init_post_alt_big_b));
+
+		/* flip/mirror */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
+		/* end of flip/mirror main part */
+		msleep(16);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
+		if (reso == IMAGE_1600)
+			msleep(25); /* 1600 */
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
+		msleep(103);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
+		sd->nbIm = 0;
+
+		if (_MI2020c_)
+			fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c,
+					ARRAY_SIZE(tbl_init_post_alt_big_c));
+	}
+
+	sd->vold.mirror    = mirror;
+	sd->vold.flip      = flip;
+	sd->vold.AC50Hz    = freq;
+	sd->vold.backlight = backlight;
+
+	mi2020_camera_settings(gspca_dev);
+
+	return 0;
+}
+
+static int mi2020_configure_alt(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+
+	switch (reso) {
+	case IMAGE_640:
+		gspca_dev->alt = 3 + 1;
+		break;
+
+	case IMAGE_800:
+	case IMAGE_1280:
+	case IMAGE_1600:
+		gspca_dev->alt = 1 + 1;
+		break;
+	}
+	return 0;
+}
+
+int mi2020_camera_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	s32 backlight = sd->vcur.backlight;
+	s32 bright =  sd->vcur.brightness;
+	s32 sharp  =  sd->vcur.sharpness;
+	s32 cntr   =  sd->vcur.contrast;
+	s32 gam	   =  sd->vcur.gamma;
+	s32 hue    = (sd->vcur.hue > 0);
+	s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
+	s32 flip   = (((sd->vcur.flip   > 0) ^ sd->mirrorMask) > 0);
+	s32 freq   = (sd->vcur.AC50Hz > 0);
+
+	u8 dat_sharp[] = {0x6c, 0x00, 0x08};
+	u8 dat_bright2[] = {0x90, 0x00, 0x00};
+	u8 dat_freq2[] = {0x90, 0x00, 0x80};
+	u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
+	u8 dat_multi2[] = {0x90, 0x00, 0x00};
+	u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
+	u8 dat_multi4[] = {0x90, 0x00, 0x00};
+	u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
+	u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
+
+	/* Less than 4 images received -> too early to set the settings */
+	if (sd->nbIm < 4) {
+		sd->waitSet = 1;
+		return 0;
+	}
+	sd->waitSet = 0;
+
+	if (freq != sd->vold.AC50Hz) {
+		sd->vold.AC50Hz = freq;
+
+		dat_freq2[2] = freq ? 0xc0 : 0x80;
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
+		msleep(20);
+	}
+
+	if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
+		sd->vold.mirror = mirror;
+		sd->vold.flip   = flip;
+
+		dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
+		dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
+		msleep(130);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
+		msleep(6);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
+		msleep(6);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
+		msleep(6);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
+		msleep(6);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
+		msleep(6);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
+		msleep(6);
+
+		/* Sometimes present, sometimes not, useful? */
+		/* ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
+		 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
+		 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
+		 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
+		 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
+		 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
+		 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
+		 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);*/
+	}
+
+	if (backlight != sd->vold.backlight) {
+		sd->vold.backlight = backlight;
+		if (backlight < 0 || backlight > sd->vmax.backlight)
+			backlight = 0;
+
+		dat_multi1[2] = 0x9d;
+		dat_multi3[2] = dat_multi1[2] + 1;
+		dat_multi4[2] = dat_multi2[2] = backlight;
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+	}
+
+	if (gam != sd->vold.gamma) {
+		sd->vold.gamma = gam;
+		if (gam < 0 || gam > sd->vmax.gamma)
+			gam = 0;
+
+		dat_multi1[2] = 0x6d;
+		dat_multi3[2] = dat_multi1[2] + 1;
+		dat_multi4[2] = dat_multi2[2] = 0x40 + gam;
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+	}
+
+	if (cntr != sd->vold.contrast) {
+		sd->vold.contrast = cntr;
+		if (cntr < 0 || cntr > sd->vmax.contrast)
+			cntr = 0;
+
+		dat_multi1[2] = 0x6d;
+		dat_multi3[2] = dat_multi1[2] + 1;
+		dat_multi4[2] = dat_multi2[2] = 0x12 + 16 * cntr;
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+	}
+
+	if (bright != sd->vold.brightness) {
+		sd->vold.brightness = bright;
+		if (bright < 0 || bright > sd->vmax.brightness)
+			bright = 0;
+
+		dat_bright2[2] = bright;
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5);
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6);
+	}
+
+	if (sharp != sd->vold.sharpness) {
+		sd->vold.sharpness = sharp;
+		if (sharp < 0 || sharp > sd->vmax.sharpness)
+			sharp = 0;
+
+		dat_sharp[1] = sharp;
+		ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0032, 3, dat_sharp);
+	}
+
+	if (hue != sd->vold.hue) {
+		sd->swapRB = hue;
+		sd->vold.hue = hue;
+	}
+
+	return 0;
+}
+
+static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev)
+{
+	ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
+	msleep(20);
+	if (_MI2020c_ || _MI2020_)
+		ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
+	else
+		ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
+}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
new file mode 100644
index 0000000..14b9c37
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c
@@ -0,0 +1,505 @@
+/* @file gl860-ov2640.c
+ * @author Olivier LORIN, from Malmostoso's logs
+ * @date 2009-08-27
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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/>.
+ */
+
+/* Sensor : OV2640 */
+
+#include "gl860.h"
+
+static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
+static u8 dat_init2[] = {0x61}; /* expected */
+static u8 dat_init3[] = {0x51}; /* expected */
+
+static u8 dat_post[] =
+	"\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
+
+static u8 dat_640[]  = "\xd0\x01\xd1\x08\xd2\xe0\xd3\x02\xd4\x10\xd5\x81";
+static u8 dat_800[]  = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21";
+static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
+static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
+
+static u8 c50[] = {0x50}; /* expected */
+static u8 c28[] = {0x28}; /* expected */
+static u8 ca8[] = {0xa8}; /* expected */
+
+static struct validx tbl_init_at_startup[] = {
+	{0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
+	{0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
+	{0x0050, 0x0000}, {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0061, 0x0006},
+	{0x006a, 0x000d}, {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1},
+	{0x0041, 0x00c2}, {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058},
+	{0x0041, 0x0000}, {0x0061, 0x0000},
+};
+
+static struct validx tbl_common[] = {
+	{0x6000, 0x00ff}, {0x60ff, 0x002c}, {0x60df, 0x002e}, {0x6001, 0x00ff},
+	{0x6080, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
+	{0x6035, 0x003c}, {0x6000, 0x0011}, {0x6028, 0x0004}, {0x60e5, 0x0013},
+	{0x6088, 0x0014}, {0x600c, 0x002c}, {0x6078, 0x0033}, {0x60f7, 0x003b},
+	{0x6000, 0x003e}, {0x6011, 0x0043}, {0x6010, 0x0016}, {0x6082, 0x0039},
+	{0x6088, 0x0035}, {0x600a, 0x0022}, {0x6040, 0x0037}, {0x6000, 0x0023},
+	{0x60a0, 0x0034}, {0x601a, 0x0036}, {0x6002, 0x0006}, {0x60c0, 0x0007},
+	{0x60b7, 0x000d}, {0x6001, 0x000e}, {0x6000, 0x004c}, {0x6081, 0x004a},
+	{0x6099, 0x0021}, {0x6002, 0x0009}, {0x603e, 0x0024}, {0x6034, 0x0025},
+	{0x6081, 0x0026}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
+	{0x6000, 0x005c}, {0x6000, 0x0063}, {0x6000, 0x007c}, {0x6070, 0x0061},
+	{0x6080, 0x0062}, {0x6080, 0x0020}, {0x6030, 0x0028}, {0x6000, 0x006c},
+	{0x6000, 0x006e}, {0x6002, 0x0070}, {0x6094, 0x0071}, {0x60c1, 0x0073},
+	{0x6034, 0x003d}, {0x6057, 0x005a}, {0x60bb, 0x004f}, {0x609c, 0x0050},
+	{0x6080, 0x006d}, {0x6002, 0x0039}, {0x6033, 0x003a}, {0x60f1, 0x003b},
+	{0x6031, 0x003c}, {0x6000, 0x00ff}, {0x6014, 0x00e0}, {0x60ff, 0x0076},
+	{0x60a0, 0x0033}, {0x6020, 0x0042}, {0x6018, 0x0043}, {0x6000, 0x004c},
+	{0x60d0, 0x0087}, {0x600f, 0x0088}, {0x6003, 0x00d7}, {0x6010, 0x00d9},
+	{0x6005, 0x00da}, {0x6082, 0x00d3}, {0x60c0, 0x00f9}, {0x6006, 0x0044},
+	{0x6007, 0x00d1}, {0x6002, 0x00d2}, {0x6000, 0x00d2}, {0x6011, 0x00d8},
+	{0x6008, 0x00c8}, {0x6080, 0x00c9}, {0x6008, 0x007c}, {0x6020, 0x007d},
+	{0x6020, 0x007d}, {0x6000, 0x0090}, {0x600e, 0x0091}, {0x601a, 0x0091},
+	{0x6031, 0x0091}, {0x605a, 0x0091}, {0x6069, 0x0091}, {0x6075, 0x0091},
+	{0x607e, 0x0091}, {0x6088, 0x0091}, {0x608f, 0x0091}, {0x6096, 0x0091},
+	{0x60a3, 0x0091}, {0x60af, 0x0091}, {0x60c4, 0x0091}, {0x60d7, 0x0091},
+	{0x60e8, 0x0091}, {0x6020, 0x0091}, {0x6000, 0x0092}, {0x6006, 0x0093},
+	{0x60e3, 0x0093}, {0x6005, 0x0093}, {0x6005, 0x0093}, {0x6000, 0x0093},
+	{0x6004, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
+	{0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
+	{0x6000, 0x0096}, {0x6008, 0x0097}, {0x6019, 0x0097}, {0x6002, 0x0097},
+	{0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, {0x6028, 0x0097},
+	{0x6026, 0x0097}, {0x6002, 0x0097}, {0x6098, 0x0097}, {0x6080, 0x0097},
+	{0x6000, 0x0097}, {0x6000, 0x0097}, {0x60ed, 0x00c3}, {0x609a, 0x00c4},
+	{0x6000, 0x00a4}, {0x6011, 0x00c5}, {0x6051, 0x00c6}, {0x6010, 0x00c7},
+	{0x6066, 0x00b6}, {0x60a5, 0x00b8}, {0x6064, 0x00b7}, {0x607c, 0x00b9},
+	{0x60af, 0x00b3}, {0x6097, 0x00b4}, {0x60ff, 0x00b5}, {0x60c5, 0x00b0},
+	{0x6094, 0x00b1}, {0x600f, 0x00b2}, {0x605c, 0x00c4}, {0x6000, 0x00a8},
+	{0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x601d, 0x0086}, {0x6000, 0x0050},
+	{0x6090, 0x0051}, {0x6018, 0x0052}, {0x6000, 0x0053}, {0x6000, 0x0054},
+	{0x6088, 0x0055}, {0x6000, 0x0057}, {0x6090, 0x005a}, {0x6018, 0x005b},
+	{0x6005, 0x005c}, {0x60ed, 0x00c3}, {0x6000, 0x007f}, {0x6005, 0x00da},
+	{0x601f, 0x00e5}, {0x6067, 0x00e1}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
+	{0x6000, 0x0005}, {0x6001, 0x00ff}, {0x6000, 0x0000}, {0x6000, 0x0045},
+	{0x6000, 0x0010},
+};
+
+static struct validx tbl_sensor_settings_common_a[] = {
+	{0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
+	{0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
+	{0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
+	{50, 0xffff},
+	{0x0061, 0x0000},
+	{0xffff, 0xffff},
+	{0x6000, 0x00ff}, {0x6000, 0x007c}, {0x6007, 0x007d},
+	{30, 0xffff},
+	{0x0040, 0x0000},
+};
+
+static struct validx tbl_sensor_settings_common_b[] = {
+	{0x6001, 0x00ff}, {0x6038, 0x000c},
+	{10, 0xffff},
+	{0x6000, 0x0011},
+	/* backlight=31/64 */
+	{0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
+	/* bright=0/256 */
+	{0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
+	/* wbal=64/128 */
+	{0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
+	/* cntr=0/256 */
+	{0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
+	/* sat=128/256 */
+	{0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
+	/* sharpness=0/32 */
+	{0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
+	/* hue=0/256 */
+	{0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
+	/* gam=32/64 */
+	{0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
+	/* image right up */
+	{0xffff, 0xffff},
+	{15, 0xffff},
+	{0x6001, 0x00ff}, {0x6000, 0x8004},
+	{0xffff, 0xffff},
+	{0x60a8, 0x0004},
+	{15, 0xffff},
+	{0x6001, 0x00ff}, {0x6000, 0x8004},
+	{0xffff, 0xffff},
+	{0x60f8, 0x0004},
+	/* image right up */
+	{0xffff, 0xffff},
+	/* backlight=31/64 */
+	{0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
+};
+
+static struct validx tbl_640[] = {
+	{0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
+	{0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
+	{0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
+	{0x6075, 0x0018}, {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032},
+	{0x60bb, 0x004f}, {0x6057, 0x005a}, {0x609c, 0x0050}, {0x6080, 0x006d},
+	{0x6092, 0x0026}, {0x60ff, 0x0020}, {0x6000, 0x0027}, {0x6000, 0x00ff},
+	{0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, {0x603d, 0x0086},
+	{0x6089, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, {0x6000, 0x0053},
+	{0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, {0x60a0, 0x005a},
+	{0x6078, 0x005b}, {0x6000, 0x005c}, {0x6004, 0x00d3}, {0x6000, 0x00e0},
+	{0x60ff, 0x00dd}, {0x60a1, 0x005a},
+};
+
+static struct validx tbl_800[] = {
+	{0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
+	{0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
+	{0x6001, 0x00ff}, {0x6040, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
+	{0x6043, 0x0018}, {0x6000, 0x0019}, {0x604b, 0x001a}, {0x6009, 0x0032},
+	{0x60ca, 0x004f}, {0x60a8, 0x0050}, {0x6000, 0x006d}, {0x6038, 0x003d},
+	{0x60c8, 0x0035}, {0x6000, 0x0022}, {0x6092, 0x0026}, {0x60ff, 0x0020},
+	{0x6000, 0x0027}, {0x6000, 0x00ff}, {0x6064, 0x00c0}, {0x604b, 0x00c1},
+	{0x6000, 0x008c}, {0x601d, 0x0086}, {0x6082, 0x00d3}, {0x6000, 0x00e0},
+	{0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
+};
+
+static struct validx tbl_big_a[] = {
+	{0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
+	{0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
+	{0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
+	{0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, {0x60bb, 0x004f},
+	{0x609c, 0x0050}, {0x6057, 0x005a}, {0x6080, 0x006d}, {0x6043, 0x000f},
+	{0x608f, 0x0003}, {0x6005, 0x007c}, {0x6081, 0x0026}, {0x6000, 0x00ff},
+	{0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
+};
+
+static struct validx tbl_big_b[] = {
+	{0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
+	{0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
+	{0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
+	{0x6000, 0x008e},
+};
+
+static struct validx tbl_big_c[] = {
+	{0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
+	{0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
+	{0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
+	{0x6000, 0x0092}, {0x6006, 0x0093}, {0x60e3, 0x0093}, {0x6005, 0x0093},
+	{0x6005, 0x0093}, {0x60ed, 0x00c3}, {0x6000, 0x00a4}, {0x60d0, 0x0087},
+	{0x6003, 0x0096}, {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097},
+	{0x6028, 0x0097}, {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6001, 0x00ff},
+	{0x6043, 0x000f}, {0x608f, 0x0003}, {0x6000, 0x002d}, {0x6000, 0x002e},
+	{0x600a, 0x0022}, {0x6002, 0x0070}, {0x6008, 0x0014}, {0x6048, 0x0014},
+	{0x6000, 0x00ff}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
+};
+
+static struct validx tbl_post_unset_alt[] = {
+	{0x006a, 0x000d}, {0x6001, 0x00ff}, {0x6081, 0x0026}, {0x6000, 0x0000},
+	{0x6000, 0x0045}, {0x6000, 0x0010}, {0x6068, 0x000d},
+	{50, 0xffff},
+	{0x0021, 0x0000},
+};
+
+static int  ov2640_init_at_startup(struct gspca_dev *gspca_dev);
+static int  ov2640_configure_alt(struct gspca_dev *gspca_dev);
+static int  ov2640_init_pre_alt(struct gspca_dev *gspca_dev);
+static int  ov2640_init_post_alt(struct gspca_dev *gspca_dev);
+static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev);
+static int  ov2640_camera_settings(struct gspca_dev *gspca_dev);
+/*==========================================================================*/
+
+void ov2640_init_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vcur.backlight  =  32;
+	sd->vcur.brightness =   0;
+	sd->vcur.sharpness  =   6;
+	sd->vcur.contrast   =   0;
+	sd->vcur.gamma      =  32;
+	sd->vcur.hue        =   0;
+	sd->vcur.saturation = 128;
+	sd->vcur.whitebal   =  64;
+
+	sd->vmax.backlight  =  64;
+	sd->vmax.brightness = 255;
+	sd->vmax.sharpness  =  31;
+	sd->vmax.contrast   = 255;
+	sd->vmax.gamma      =  64;
+	sd->vmax.hue        = 255 + 1;
+	sd->vmax.saturation = 255;
+	sd->vmax.whitebal   = 128;
+	sd->vmax.mirror     = 0;
+	sd->vmax.flip       = 0;
+	sd->vmax.AC50Hz     = 0;
+
+	sd->dev_camera_settings = ov2640_camera_settings;
+	sd->dev_init_at_startup = ov2640_init_at_startup;
+	sd->dev_configure_alt   = ov2640_configure_alt;
+	sd->dev_init_pre_alt    = ov2640_init_pre_alt;
+	sd->dev_post_unset_alt  = ov2640_post_unset_alt;
+}
+
+/*==========================================================================*/
+
+static void common(struct gspca_dev *gspca_dev)
+{
+	fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
+}
+
+static int ov2640_init_at_startup(struct gspca_dev *gspca_dev)
+{
+	fetch_validx(gspca_dev, tbl_init_at_startup,
+			ARRAY_SIZE(tbl_init_at_startup));
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_init1);
+
+	common(gspca_dev);
+
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2);
+
+	ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
+
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3);
+
+	ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
+/*	ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
+
+	return 0;
+}
+
+static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vold.backlight  = -1;
+	sd->vold.brightness = -1;
+	sd->vold.sharpness  = -1;
+	sd->vold.contrast   = -1;
+	sd->vold.saturation = -1;
+	sd->vold.gamma    = -1;
+	sd->vold.hue      = -1;
+	sd->vold.whitebal = -1;
+
+	ov2640_init_post_alt(gspca_dev);
+
+	return 0;
+}
+
+static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+	s32 n; /* reserved for FETCH macros */
+
+	ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
+
+	n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a,
+			ARRAY_SIZE(tbl_sensor_settings_common_a));
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
+	common(gspca_dev);
+	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a,
+				ARRAY_SIZE(tbl_sensor_settings_common_a), n);
+
+	switch (reso) {
+	case IMAGE_640:
+		n = fetch_validx(gspca_dev, tbl_640, ARRAY_SIZE(tbl_640));
+		ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_640);
+		break;
+
+	case IMAGE_800:
+		n = fetch_validx(gspca_dev, tbl_800, ARRAY_SIZE(tbl_800));
+		ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_800);
+		break;
+
+	case IMAGE_1600:
+	case IMAGE_1280:
+		n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a));
+
+		if (reso == IMAGE_1280) {
+			n = fetch_validx(gspca_dev, tbl_big_b,
+					ARRAY_SIZE(tbl_big_b));
+		} else {
+			ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
+		}
+
+		n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c));
+
+		if (reso == IMAGE_1280) {
+			ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
+					12, dat_1280);
+		} else {
+			ctrl_out(gspca_dev, 0x40, 1, 0x6020, 0x008c, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 1, 0x6076, 0x0018, 0, NULL);
+			ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
+					12, dat_1600);
+		}
+		break;
+	}
+
+	n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b,
+			ARRAY_SIZE(tbl_sensor_settings_common_b));
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
+	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
+				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
+	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
+				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
+	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
+				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
+	keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
+				ARRAY_SIZE(tbl_sensor_settings_common_b), n);
+
+	ov2640_camera_settings(gspca_dev);
+
+	return 0;
+}
+
+static int ov2640_configure_alt(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+
+	switch (reso) {
+	case IMAGE_640:
+		gspca_dev->alt = 3 + 1;
+		break;
+
+	case IMAGE_800:
+	case IMAGE_1280:
+	case IMAGE_1600:
+		gspca_dev->alt = 1 + 1;
+		break;
+	}
+	return 0;
+}
+
+static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	s32 backlight = sd->vcur.backlight;
+	s32 bright = sd->vcur.brightness;
+	s32 sharp  = sd->vcur.sharpness;
+	s32 gam    = sd->vcur.gamma;
+	s32 cntr   = sd->vcur.contrast;
+	s32 sat    = sd->vcur.saturation;
+	s32 hue    = sd->vcur.hue;
+	s32 wbal   = sd->vcur.whitebal;
+
+	if (backlight != sd->vold.backlight) {
+		if (backlight < 0 || backlight > sd->vmax.backlight)
+			backlight = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001                 , 0x00ff,
+				0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight     , 0x0024,
+				0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
+				0, NULL);
+		/* No sd->vold.backlight=backlight; (to be done again later) */
+	}
+
+	if (bright != sd->vold.brightness) {
+		sd->vold.brightness = bright;
+		if (bright < 0 || bright > sd->vmax.brightness)
+			bright = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000         , 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6009         , 0x007c, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + bright, 0x007d, 0, NULL);
+	}
+
+	if (wbal != sd->vold.whitebal) {
+		sd->vold.whitebal = wbal;
+		if (wbal < 0 || wbal > sd->vmax.whitebal)
+			wbal = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000       , 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6003       , 0x007c, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + wbal, 0x007d, 0, NULL);
+	}
+
+	if (cntr != sd->vold.contrast) {
+		sd->vold.contrast = cntr;
+		if (cntr < 0 || cntr > sd->vmax.contrast)
+			cntr = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000       , 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6007       , 0x007c, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + cntr, 0x007d, 0, NULL);
+	}
+
+	if (sat != sd->vold.saturation) {
+		sd->vold.saturation = sat;
+		if (sat < 0 || sat > sd->vmax.saturation)
+			sat = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000      , 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001      , 0x007c, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + sat, 0x007d, 0, NULL);
+	}
+
+	if (sharp != sd->vold.sharpness) {
+		sd->vold.sharpness = sharp;
+		if (sharp < 0 || sharp > sd->vmax.sharpness)
+			sharp = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000        , 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001        , 0x0092, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x60c0 + sharp, 0x0093, 0, NULL);
+	}
+
+	if (hue != sd->vold.hue) {
+		sd->vold.hue = hue;
+		if (hue < 0 || hue > sd->vmax.hue)
+			hue = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000     , 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6002     , 0x007c, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
+				0, NULL);
+		if (hue >= sd->vmax.hue)
+			sd->swapRB = 1;
+		else
+			sd->swapRB = 0;
+	}
+
+	if (gam != sd->vold.gamma) {
+		sd->vold.gamma = gam;
+		if (gam < 0 || gam > sd->vmax.gamma)
+			gam = 0;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000      , 0x00ff, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6008      , 0x007c, 0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
+	}
+
+	if (backlight != sd->vold.backlight) {
+		sd->vold.backlight = backlight;
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x6001                 , 0x00ff,
+				0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight     , 0x0024,
+				0, NULL);
+		ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
+				0, NULL);
+	}
+
+	return 0;
+}
+
+static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev)
+{
+	ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
+	msleep(20);
+	fetch_validx(gspca_dev, tbl_post_unset_alt,
+			ARRAY_SIZE(tbl_post_unset_alt));
+}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
new file mode 100644
index 0000000..eda3346
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c
@@ -0,0 +1,337 @@
+/* @file gl860-ov9655.c
+ * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
+ * on dsd's weblog
+ * @date 2009-08-27
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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/>.
+ */
+
+/* Sensor : OV9655 */
+
+#include "gl860.h"
+
+static struct validx tbl_init_at_startup[] = {
+	{0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
+	{0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
+
+	{0x0040, 0x0000},
+};
+
+static struct validx tbl_commmon[] = {
+	{0x0041, 0x0000}, {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d},
+	{0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
+	{0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0040, 0x0000},
+	{0x00f3, 0x0006}, {0x0058, 0x0000}, {0x0048, 0x0000}, {0x0061, 0x0000},
+};
+
+static s32 tbl_length[] = {12, 56, 52, 54, 56, 42, 32, 12};
+
+static u8 *tbl_640[] = {
+	"\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
+	,
+	"\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x03\x0b\x57\x0e\x61"
+	"\x0f\x42\x11\x01\x12\x60\x13\x00" "\x14\x3a\x16\x24\x17\x14\x18\x00"
+	"\x19\x01\x1a\x3d\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
+	"\x29\x15\x2a\x00\x2b\x00\x2c\x08"
+	,
+	"\x32\xff\x33\x00\x34\x3d\x35\x00" "\x36\xfa\x38\x72\x39\x57\x3a\x00"
+	"\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc1" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
+	"\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xee\x4b\xe7\x4c\xe7"
+	"\x4d\xe7\x4e\xe7"
+	,
+	"\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
+	"\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
+	"\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x0a\x6b\x5a\x6c\x04"
+	"\x6d\x55\x6e\x00\x6f\x9d"
+	,
+	"\x70\x15\x71\x78\x72\x00\x73\x00" "\x74\x3a\x75\x35\x76\x01\x77\x02"
+	"\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
+	"\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
+	"\x8a\x23\x8c\x8d\x90\x7c\x91\x7b"
+	,
+	"\x9d\x02\x9e\x02\x9f\x74\xa0\x73" "\xa1\x40\xa4\x50\xa5\x68\xa6\x70"
+	"\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
+	"\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
+	,
+	"\xbb\xae\xbc\x4f\xbd\x4e\xbe\x6a" "\xbf\x68\xc0\xaa\xc1\xc0\xc2\x01"
+	"\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
+	,
+	"\xd0\x01\xd1\x08\xd2\xe0\xd3\x01" "\xd4\x10\xd5\x80"
+};
+
+static u8 *tbl_800[] = {
+	"\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
+	,
+	"\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x01\x0b\x57\x0e\x61"
+	"\x0f\x42\x11\x00\x12\x00\x13\x00" "\x14\x3a\x16\x24\x17\x1b\x18\xbb"
+	"\x19\x01\x1a\x81\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
+	"\x29\x15\x2a\x00\x2b\x00\x2c\x08"
+	,
+	"\x32\xa4\x33\x00\x34\x3d\x35\x00" "\x36\xf8\x38\x72\x39\x57\x3a\x00"
+	"\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc2" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
+	"\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xec\x4b\xe8\x4c\xe8"
+	"\x4d\xe8\x4e\xe8"
+	,
+	"\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
+	"\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
+	"\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x02\x6b\x5a\x6c\x04"
+	"\x6d\x55\x6e\x00\x6f\x9d"
+	,
+	"\x70\x08\x71\x78\x72\x00\x73\x01" "\x74\x3a\x75\x35\x76\x01\x77\x02"
+	"\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
+	"\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
+	"\x8a\x23\x8c\x0d\x90\x90\x91\x90"
+	,
+	"\x9d\x02\x9e\x02\x9f\x94\xa0\x94" "\xa1\x01\xa4\x50\xa5\x68\xa6\x70"
+	"\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
+	"\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
+	,
+	"\xbb\xae\xbc\x38\xbd\x39\xbe\x01" "\xbf\x01\xc0\xe2\xc1\xc0\xc2\x01"
+	"\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
+	,
+	"\xd0\x21\xd1\x18\xd2\xe0\xd3\x01" "\xd4\x28\xd5\x00"
+};
+
+static u8 c04[] = {0x04};
+static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
+static u8 dat_post_2[] = "\x10\x10\xc1\x02";
+static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
+static u8 dat_post_4[] = "\x10\x02\xc1\x06";
+static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
+static u8 dat_post_6[] = "\x10\x10\xc1\x05";
+static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
+static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
+
+static struct validx tbl_init_post_alt[] = {
+	{0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
+	{0x6003, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6001, 0x00ff},
+	{0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6012, 0x0003},
+	{0xffff, 0xffff},
+	{0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6012, 0x0003},
+	{0xffff, 0xffff},
+	{0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6000, 0x801e},
+	{0xffff, 0xffff},
+	{0x6004, 0x001e}, {0x6012, 0x0003},
+};
+
+static int  ov9655_init_at_startup(struct gspca_dev *gspca_dev);
+static int  ov9655_configure_alt(struct gspca_dev *gspca_dev);
+static int  ov9655_init_pre_alt(struct gspca_dev *gspca_dev);
+static int  ov9655_init_post_alt(struct gspca_dev *gspca_dev);
+static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev);
+static int  ov9655_camera_settings(struct gspca_dev *gspca_dev);
+/*==========================================================================*/
+
+void ov9655_init_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vcur.backlight  =   0;
+	sd->vcur.brightness = 128;
+	sd->vcur.sharpness  =   0;
+	sd->vcur.contrast   =   0;
+	sd->vcur.gamma      =   0;
+	sd->vcur.hue        =   0;
+	sd->vcur.saturation =   0;
+	sd->vcur.whitebal   =   0;
+
+	sd->vmax.backlight  =   0;
+	sd->vmax.brightness = 255;
+	sd->vmax.sharpness  =   0;
+	sd->vmax.contrast   =   0;
+	sd->vmax.gamma      =   0;
+	sd->vmax.hue        =   0 + 1;
+	sd->vmax.saturation =   0;
+	sd->vmax.whitebal   =   0;
+	sd->vmax.mirror     = 0;
+	sd->vmax.flip       = 0;
+	sd->vmax.AC50Hz     = 0;
+
+	sd->dev_camera_settings = ov9655_camera_settings;
+	sd->dev_init_at_startup = ov9655_init_at_startup;
+	sd->dev_configure_alt   = ov9655_configure_alt;
+	sd->dev_init_pre_alt    = ov9655_init_pre_alt;
+	sd->dev_post_unset_alt  = ov9655_post_unset_alt;
+}
+
+/*==========================================================================*/
+
+static int ov9655_init_at_startup(struct gspca_dev *gspca_dev)
+{
+	fetch_validx(gspca_dev, tbl_init_at_startup,
+			ARRAY_SIZE(tbl_init_at_startup));
+	fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
+/*	ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL);*/
+
+	return 0;
+}
+
+static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->vold.brightness = -1;
+	sd->vold.hue = -1;
+
+	fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
+
+	ov9655_init_post_alt(gspca_dev);
+
+	return 0;
+}
+
+static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+	s32 n; /* reserved for FETCH macros */
+	s32 i;
+	u8 **tbl;
+
+	ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
+
+	tbl = (reso == IMAGE_640) ? tbl_640 : tbl_800;
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
+			tbl_length[0], tbl[0]);
+	for (i = 1; i < 7; i++)
+		ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200,
+				tbl_length[i], tbl[i]);
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
+			tbl_length[7], tbl[7]);
+
+	n = fetch_validx(gspca_dev, tbl_init_post_alt,
+			ARRAY_SIZE(tbl_init_post_alt));
+
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+	ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
+	keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
+					ARRAY_SIZE(tbl_init_post_alt), n);
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3);
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5);
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6);
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7);
+
+	ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8);
+
+	ov9655_camera_settings(gspca_dev);
+
+	return 0;
+}
+
+static int ov9655_configure_alt(struct gspca_dev *gspca_dev)
+{
+	s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
+
+	switch (reso) {
+	case IMAGE_640:
+		gspca_dev->alt = 1 + 1;
+		break;
+
+	default:
+		gspca_dev->alt = 1 + 1;
+		break;
+	}
+	return 0;
+}
+
+static int ov9655_camera_settings(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	u8 dat_bright[] = "\x04\x00\x10\x7c\xa1\x00\x00\x70";
+
+	s32 bright = sd->vcur.brightness;
+	s32 hue    = sd->vcur.hue;
+
+	if (bright != sd->vold.brightness) {
+		sd->vold.brightness = bright;
+		if (bright < 0 || bright > sd->vmax.brightness)
+			bright = 0;
+
+		dat_bright[3] = bright;
+		ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_bright);
+	}
+
+	if (hue != sd->vold.hue) {
+		sd->vold.hue = hue;
+		sd->swapRB = (hue != 0);
+	}
+
+	return 0;
+}
+
+static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev)
+{
+	ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
+	ctrl_out(gspca_dev, 0x40, 1, 0x0061, 0x0000, 0, NULL);
+}
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
new file mode 100644
index 0000000..6ef59ac
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -0,0 +1,785 @@
+/* @file gl860.c
+ * @date 2009-08-27
+ *
+ * Genesys Logic webcam with gl860 subdrivers
+ *
+ * Driver by Olivier Lorin <o.lorin@laposte.net>
+ * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
+ * Thanks BUGabundo and Malmostoso for your amazing help!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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 "gspca.h"
+#include "gl860.h"
+
+MODULE_AUTHOR("Olivier Lorin <lorin@laposte.net>");
+MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/*======================== static function declarations ====================*/
+
+static void (*dev_init_settings)(struct gspca_dev *gspca_dev);
+
+static int  sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id);
+static int  sd_init(struct gspca_dev *gspca_dev);
+static int  sd_isoc_init(struct gspca_dev *gspca_dev);
+static int  sd_start(struct gspca_dev *gspca_dev);
+static void sd_stop0(struct gspca_dev *gspca_dev);
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			struct gspca_frame *frame, u8 *data, s32 len);
+static void sd_callback(struct gspca_dev *gspca_dev);
+
+static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
+				s32 vendor_id, s32 product_id);
+
+/*============================ driver options ==============================*/
+
+static s32 AC50Hz = 0xff;
+module_param(AC50Hz, int, 0644);
+MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)");
+
+static char sensor[7];
+module_param_string(sensor, sensor, sizeof(sensor), 0644);
+MODULE_PARM_DESC(sensor,
+		" Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')");
+
+/*============================ webcam controls =============================*/
+
+/* Functions to get and set a control value */
+#define SD_SETGET(thename) \
+static int sd_set_##thename(struct gspca_dev *gspca_dev, s32 val)\
+{\
+	struct sd *sd = (struct sd *) gspca_dev;\
+\
+	sd->vcur.thename = val;\
+	if (gspca_dev->streaming)\
+		sd->dev_camera_settings(gspca_dev);\
+	return 0;\
+} \
+static int sd_get_##thename(struct gspca_dev *gspca_dev, s32 *val)\
+{\
+	struct sd *sd = (struct sd *) gspca_dev;\
+\
+	*val = sd->vcur.thename;\
+	return 0;\
+}
+
+SD_SETGET(mirror)
+SD_SETGET(flip)
+SD_SETGET(AC50Hz)
+SD_SETGET(backlight)
+SD_SETGET(brightness)
+SD_SETGET(gamma)
+SD_SETGET(hue)
+SD_SETGET(saturation)
+SD_SETGET(sharpness)
+SD_SETGET(whitebal)
+SD_SETGET(contrast)
+
+#define GL860_NCTRLS 11
+
+/* control table */
+static struct ctrl sd_ctrls_mi1320[GL860_NCTRLS];
+static struct ctrl sd_ctrls_mi2020[GL860_NCTRLS];
+static struct ctrl sd_ctrls_mi2020b[GL860_NCTRLS];
+static struct ctrl sd_ctrls_ov2640[GL860_NCTRLS];
+static struct ctrl sd_ctrls_ov9655[GL860_NCTRLS];
+
+#define SET_MY_CTRL(theid, \
+	thetype, thelabel, thename) \
+	if (sd->vmax.thename != 0) {\
+		sd_ctrls[nCtrls].qctrl.id   = theid;\
+		sd_ctrls[nCtrls].qctrl.type = thetype;\
+		strcpy(sd_ctrls[nCtrls].qctrl.name, thelabel);\
+		sd_ctrls[nCtrls].qctrl.minimum = 0;\
+		sd_ctrls[nCtrls].qctrl.maximum = sd->vmax.thename;\
+		sd_ctrls[nCtrls].qctrl.default_value = sd->vcur.thename;\
+		sd_ctrls[nCtrls].qctrl.step = \
+			(sd->vmax.thename < 16) ? 1 : sd->vmax.thename/16;\
+		sd_ctrls[nCtrls].set = sd_set_##thename;\
+		sd_ctrls[nCtrls].get = sd_get_##thename;\
+		nCtrls++;\
+	}
+
+static int gl860_build_control_table(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct ctrl *sd_ctrls;
+	int nCtrls = 0;
+
+	if (_MI1320_)
+		sd_ctrls = sd_ctrls_mi1320;
+	else if (_MI2020_)
+		sd_ctrls = sd_ctrls_mi2020;
+	else if (_MI2020b_)
+		sd_ctrls = sd_ctrls_mi2020b;
+	else if (_OV2640_)
+		sd_ctrls = sd_ctrls_ov2640;
+	else if (_OV9655_)
+		sd_ctrls = sd_ctrls_ov9655;
+	else
+		return 0;
+
+	memset(sd_ctrls, 0, GL860_NCTRLS * sizeof(struct ctrl));
+
+	SET_MY_CTRL(V4L2_CID_BRIGHTNESS,
+		V4L2_CTRL_TYPE_INTEGER, "Brightness", brightness)
+	SET_MY_CTRL(V4L2_CID_SHARPNESS,
+		V4L2_CTRL_TYPE_INTEGER, "Sharpness", sharpness)
+	SET_MY_CTRL(V4L2_CID_CONTRAST,
+		V4L2_CTRL_TYPE_INTEGER, "Contrast", contrast)
+	SET_MY_CTRL(V4L2_CID_GAMMA,
+		V4L2_CTRL_TYPE_INTEGER, "Gamma", gamma)
+	SET_MY_CTRL(V4L2_CID_HUE,
+		V4L2_CTRL_TYPE_INTEGER, "Palette", hue)
+	SET_MY_CTRL(V4L2_CID_SATURATION,
+		V4L2_CTRL_TYPE_INTEGER, "Saturation", saturation)
+	SET_MY_CTRL(V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+		V4L2_CTRL_TYPE_INTEGER, "White Bal.", whitebal)
+	SET_MY_CTRL(V4L2_CID_BACKLIGHT_COMPENSATION,
+		V4L2_CTRL_TYPE_INTEGER, "Backlight" , backlight)
+
+	SET_MY_CTRL(V4L2_CID_HFLIP,
+		V4L2_CTRL_TYPE_BOOLEAN, "Mirror", mirror)
+	SET_MY_CTRL(V4L2_CID_VFLIP,
+		V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
+	SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
+		V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz)
+
+	return nCtrls;
+}
+
+/*==================== sud-driver structure initialisation =================*/
+
+static struct sd_desc sd_desc_mi1320 = {
+	.name        = MODULE_NAME,
+	.ctrls       = sd_ctrls_mi1320,
+	.nctrls      = GL860_NCTRLS,
+	.config      = sd_config,
+	.init        = sd_init,
+	.isoc_init   = sd_isoc_init,
+	.start       = sd_start,
+	.stop0       = sd_stop0,
+	.pkt_scan    = sd_pkt_scan,
+	.dq_callback = sd_callback,
+};
+
+static struct sd_desc sd_desc_mi2020 = {
+	.name        = MODULE_NAME,
+	.ctrls       = sd_ctrls_mi2020,
+	.nctrls      = GL860_NCTRLS,
+	.config      = sd_config,
+	.init        = sd_init,
+	.isoc_init   = sd_isoc_init,
+	.start       = sd_start,
+	.stop0       = sd_stop0,
+	.pkt_scan    = sd_pkt_scan,
+	.dq_callback = sd_callback,
+};
+
+static struct sd_desc sd_desc_mi2020b = {
+	.name        = MODULE_NAME,
+	.ctrls       = sd_ctrls_mi2020b,
+	.nctrls      = GL860_NCTRLS,
+	.config      = sd_config,
+	.init        = sd_init,
+	.isoc_init   = sd_isoc_init,
+	.start       = sd_start,
+	.stop0       = sd_stop0,
+	.pkt_scan    = sd_pkt_scan,
+	.dq_callback = sd_callback,
+};
+
+static struct sd_desc sd_desc_ov2640 = {
+	.name        = MODULE_NAME,
+	.ctrls       = sd_ctrls_ov2640,
+	.nctrls      = GL860_NCTRLS,
+	.config      = sd_config,
+	.init        = sd_init,
+	.isoc_init   = sd_isoc_init,
+	.start       = sd_start,
+	.stop0       = sd_stop0,
+	.pkt_scan    = sd_pkt_scan,
+	.dq_callback = sd_callback,
+};
+
+static struct sd_desc sd_desc_ov9655 = {
+	.name        = MODULE_NAME,
+	.ctrls       = sd_ctrls_ov9655,
+	.nctrls      = GL860_NCTRLS,
+	.config      = sd_config,
+	.init        = sd_init,
+	.isoc_init   = sd_isoc_init,
+	.start       = sd_start,
+	.stop0       = sd_stop0,
+	.pkt_scan    = sd_pkt_scan,
+	.dq_callback = sd_callback,
+};
+
+/*=========================== sub-driver image sizes =======================*/
+
+static struct v4l2_pix_format mi2020_mode[] = {
+	{ 640,  480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	},
+	{ 800,  600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 800,
+		.sizeimage = 800 * 600,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1
+	},
+	{1280, 1024, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 1280,
+		.sizeimage = 1280 * 1024,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2
+	},
+	{1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 1600,
+		.sizeimage = 1600 * 1200,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 3
+	},
+};
+
+static struct v4l2_pix_format ov2640_mode[] = {
+	{ 640,  480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	},
+	{ 800,  600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 800,
+		.sizeimage = 800 * 600,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1
+	},
+	{1280,  960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 1280,
+		.sizeimage = 1280 * 960,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2
+	},
+	{1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 1600,
+		.sizeimage = 1600 * 1200,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 3
+	},
+};
+
+static struct v4l2_pix_format mi1320_mode[] = {
+	{ 640,  480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	},
+	{ 800,  600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 800,
+		.sizeimage = 800 * 600,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1
+	},
+	{1280,  960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 1280,
+		.sizeimage = 1280 * 960,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 2
+	},
+};
+
+static struct v4l2_pix_format ov9655_mode[] = {
+	{ 640,  480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 0
+	},
+	{1280,  960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+		.bytesperline = 1280,
+		.sizeimage = 1280 * 960,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.priv = 1
+	},
+};
+
+/*========================= sud-driver functions ===========================*/
+
+/* This function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+			const struct usb_device_id *id)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct cam *cam;
+	s32 vendor_id, product_id;
+
+	/* Get USB VendorID and ProductID */
+	vendor_id  = le16_to_cpu(id->idVendor);
+	product_id = le16_to_cpu(id->idProduct);
+
+	sd->nbRightUp = 1;
+	sd->nbIm = -1;
+
+	sd->sensor = 0xff;
+	if (strcmp(sensor, "MI1320") == 0)
+		sd->sensor = ID_MI1320;
+	else if (strcmp(sensor, "OV2640") == 0)
+		sd->sensor = ID_OV2640;
+	else if (strcmp(sensor, "OV9655") == 0)
+		sd->sensor = ID_OV9655;
+	else if (strcmp(sensor, "MI2020") == 0)
+		sd->sensor = ID_MI2020;
+	else if (strcmp(sensor, "MI2020b") == 0)
+		sd->sensor = ID_MI2020b;
+
+	/* Get sensor and set the suitable init/start/../stop functions */
+	if (gl860_guess_sensor(gspca_dev, vendor_id, product_id) == -1)
+		return -1;
+
+	cam = &gspca_dev->cam;
+	gspca_dev->nbalt = 4;
+
+	switch (sd->sensor) {
+	case ID_MI1320:
+		gspca_dev->sd_desc = &sd_desc_mi1320;
+		cam->cam_mode = mi1320_mode;
+		cam->nmodes = ARRAY_SIZE(mi1320_mode);
+		dev_init_settings   = mi1320_init_settings;
+		break;
+
+	case ID_MI2020:
+		gspca_dev->sd_desc = &sd_desc_mi2020;
+		cam->cam_mode = mi2020_mode;
+		cam->nmodes = ARRAY_SIZE(mi2020_mode);
+		dev_init_settings   = mi2020_init_settings;
+		break;
+
+	case ID_MI2020b:
+		gspca_dev->sd_desc = &sd_desc_mi2020b;
+		cam->cam_mode = mi2020_mode;
+		cam->nmodes = ARRAY_SIZE(mi2020_mode);
+		dev_init_settings   = mi2020_init_settings;
+		break;
+
+	case ID_OV2640:
+		gspca_dev->sd_desc = &sd_desc_ov2640;
+		cam->cam_mode = ov2640_mode;
+		cam->nmodes = ARRAY_SIZE(ov2640_mode);
+		dev_init_settings   = ov2640_init_settings;
+		break;
+
+	case ID_OV9655:
+		gspca_dev->sd_desc = &sd_desc_ov9655;
+		cam->cam_mode = ov9655_mode;
+		cam->nmodes = ARRAY_SIZE(ov9655_mode);
+		dev_init_settings   = ov9655_init_settings;
+		break;
+	}
+
+	dev_init_settings(gspca_dev);
+	if (AC50Hz != 0xff)
+		((struct sd *) gspca_dev)->vcur.AC50Hz = AC50Hz;
+	gl860_build_control_table(gspca_dev);
+
+	return 0;
+}
+
+/* This function is called at probe time after sd_config */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return sd->dev_init_at_startup(gspca_dev);
+}
+
+/* This function is called before to choose the alt setting */
+static int sd_isoc_init(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return sd->dev_configure_alt(gspca_dev);
+}
+
+/* This function is called to start the webcam */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return sd->dev_init_pre_alt(gspca_dev);
+}
+
+/* This function is called to stop the webcam */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	return sd->dev_post_unset_alt(gspca_dev);
+}
+
+/* This function is called when an image is being received */
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			struct gspca_frame *frame, u8 *data, s32 len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	static s32 nSkipped;
+
+	s32 mode = (s32) gspca_dev->curr_mode;
+	s32 nToSkip =
+		sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1);
+
+	/* Test only against 0202h, so endianess does not matter */
+	switch (*(s16 *) data) {
+	case 0x0202:		/* End of frame, start a new one */
+		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
+		nSkipped = 0;
+		if (sd->nbIm >= 0 && sd->nbIm < 10)
+			sd->nbIm++;
+		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
+		break;
+
+	default:
+		data += 2;
+		len  -= 2;
+		if (nSkipped + len <= nToSkip)
+			nSkipped += len;
+		else {
+			if (nSkipped < nToSkip && nSkipped + len > nToSkip) {
+				data += nToSkip - nSkipped;
+				len  -= nToSkip - nSkipped;
+				nSkipped = nToSkip + 1;
+			}
+			gspca_frame_add(gspca_dev,
+				INTER_PACKET, frame, data, len);
+		}
+		break;
+	}
+}
+
+/* This function is called when an image has been read */
+/* This function is used to monitor webcam orientation */
+static void sd_callback(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (!_OV9655_) {
+		u8 state;
+		u8 upsideDown;
+
+		/* Probe sensor orientation */
+		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, (void *)&state);
+
+		/* C8/40 means upside-down (looking backwards) */
+		/* D8/50 means right-up (looking onwards) */
+		upsideDown = (state == 0xc8 || state == 0x40);
+
+		if (upsideDown && sd->nbRightUp > -4) {
+			if (sd->nbRightUp > 0)
+				sd->nbRightUp = 0;
+			if (sd->nbRightUp == -3) {
+				sd->mirrorMask = 1;
+				sd->waitSet = 1;
+			}
+			sd->nbRightUp--;
+		}
+		if (!upsideDown && sd->nbRightUp < 4) {
+			if (sd->nbRightUp  < 0)
+				sd->nbRightUp = 0;
+			if (sd->nbRightUp == 3) {
+				sd->mirrorMask = 0;
+				sd->waitSet = 1;
+			}
+			sd->nbRightUp++;
+		}
+	}
+
+	if (sd->waitSet)
+		sd->dev_camera_settings(gspca_dev);
+}
+
+/*=================== USB driver structure initialisation ==================*/
+
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x05e3, 0x0503)},
+	{USB_DEVICE(0x05e3, 0xf191)},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+static int sd_probe(struct usb_interface *intf,
+				const struct usb_device_id *id)
+{
+	struct gspca_dev *gspca_dev;
+	s32 ret;
+
+	ret = gspca_dev_probe(intf, id,
+			&sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
+
+	if (ret >= 0) {
+		gspca_dev = usb_get_intfdata(intf);
+
+		PDEBUG(D_PROBE,
+			"Camera is now controlling video device /dev/video%d",
+			gspca_dev->vdev.minor);
+	}
+
+	return ret;
+}
+
+static void sd_disconnect(struct usb_interface *intf)
+{
+	gspca_disconnect(intf);
+}
+
+static struct usb_driver sd_driver = {
+	.name       = MODULE_NAME,
+	.id_table   = device_table,
+	.probe      = sd_probe,
+	.disconnect = sd_disconnect,
+#ifdef CONFIG_PM
+	.suspend    = gspca_suspend,
+	.resume     = gspca_resume,
+#endif
+};
+
+/*====================== Init and Exit module functions ====================*/
+
+static int __init sd_mod_init(void)
+{
+	PDEBUG(D_PROBE, "driver startup - version %s", DRIVER_VERSION);
+
+	if (usb_register(&sd_driver) < 0)
+		return -1;
+	PDEBUG(D_PROBE, "driver registered");
+
+	return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "driver deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
+
+/*==========================================================================*/
+
+int gl860_RTx(struct gspca_dev *gspca_dev,
+		unsigned char pref, u32 req, u16 val, u16 index,
+		s32 len, void *pdata)
+{
+	struct usb_device *udev = gspca_dev->dev;
+	s32 r = 0;
+
+	if (pref == 0x40) { /* Send */
+		if (len > 0) {
+			memcpy(gspca_dev->usb_buf, pdata, len);
+			r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+					req, pref, val, index,
+					gspca_dev->usb_buf,
+					len, 400 + 200 * (len > 1));
+		} else {
+			r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+					req, pref, val, index, NULL, len, 400);
+		}
+	} else { /* Receive */
+		if (len > 0) {
+			r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+					req, pref, val, index,
+					gspca_dev->usb_buf,
+					len, 400 + 200 * (len > 1));
+			memcpy(pdata, gspca_dev->usb_buf, len);
+		} else {
+			r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+					req, pref, val, index, NULL, len, 400);
+		}
+	}
+
+	if (r < 0)
+		PDEBUG(D_ERR,
+			"ctrl transfer failed %4d "
+			"[p%02x r%d v%04x i%04x len%d]",
+			r, pref, req, val, index, len);
+	else if (len > 1 && r < len)
+		PDEBUG(D_ERR, "short ctrl transfer %d/%d", r, len);
+
+	if ((_MI2020_ || _MI2020b_ || _MI2020c_) && (val || index))
+		msleep(1);
+	if (_OV2640_)
+		msleep(1);
+
+	return r;
+}
+
+int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len)
+{
+	int n;
+
+	for (n = 0; n < len; n++) {
+		if (tbl[n].idx != 0xffff)
+			ctrl_out(gspca_dev, 0x40, 1, tbl[n].val,
+					tbl[n].idx, 0, NULL);
+		else if (tbl[n].val == 0xffff)
+			break;
+		else
+			msleep(tbl[n].val);
+	}
+	return n;
+}
+
+int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
+				int len, int n)
+{
+	while (++n < len) {
+		if (tbl[n].idx != 0xffff)
+			ctrl_out(gspca_dev, 0x40, 1, tbl[n].val, tbl[n].idx,
+					0, NULL);
+		else if (tbl[n].val == 0xffff)
+			break;
+		else
+			msleep(tbl[n].val);
+	}
+	return n;
+}
+
+void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len)
+{
+	int n;
+
+	for (n = 0; n < len; n++) {
+		if (memcmp(tbl[n].data, "\xff\xff\xff", 3) != 0)
+			ctrl_out(gspca_dev, 0x40, 3, 0x7a00, tbl[n].idx,
+					3, tbl[n].data);
+		else
+			msleep(tbl[n].idx);
+	}
+}
+
+static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
+				s32 vendor_id, s32 product_id)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 probe, nb26, nb96, nOV, ntry;
+
+	if (product_id == 0xf191)
+		sd->sensor = ID_MI1320;
+
+	if (sd->sensor == 0xff) {
+		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
+		ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
+
+		ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x0000, 0, NULL);
+		msleep(3);
+		ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
+		msleep(3);
+		ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x00c0, 0, NULL);
+		msleep(3);
+		ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c1, 0, NULL);
+		msleep(3);
+		ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c2, 0, NULL);
+		msleep(3);
+		ctrl_out(gspca_dev, 0x40, 1, 0x0020, 0x0006, 0, NULL);
+		msleep(3);
+		ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
+		msleep(56);
+
+		nOV = 0;
+		for (ntry = 0; ntry < 4; ntry++) {
+			ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
+			msleep(3);
+			ctrl_out(gspca_dev, 0x40, 1, 0x0063, 0x0006, 0, NULL);
+			msleep(3);
+			ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
+			msleep(10);
+			ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
+			PDEBUG(D_PROBE, "1st probe=%02x", probe);
+			if (probe == 0xff)
+				nOV++;
+		}
+
+		if (nOV) {
+			PDEBUG(D_PROBE, "0xff -> sensor OVXXXX");
+			PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655");
+
+			nb26 = nb96 = 0;
+			for (ntry = 0; ntry < 4; ntry++) {
+				ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000,
+						0, NULL);
+				msleep(3);
+				ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
+						0, NULL);
+				msleep(10);
+				/* Wait for 26(OV2640) or 96(OV9655) */
+				ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
+						1, &probe);
+
+				PDEBUG(D_PROBE, "2nd probe=%02x", probe);
+				if (probe == 0x00)
+					nb26++;
+				if (probe == 0x26 || probe == 0x40) {
+					sd->sensor = ID_OV2640;
+					nb26 += 4;
+					break;
+				}
+				if (probe == 0x96 || probe == 0x55) {
+					sd->sensor = ID_OV9655;
+					nb96 += 4;
+					break;
+				}
+				if (probe == 0xff)
+					nb96++;
+				msleep(3);
+			}
+			if (nb26 < 4 && nb96 < 4) {
+				PDEBUG(D_PROBE, "No relevant answer ");
+				PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655");
+				PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640");
+				PDEBUG(D_PROBE,
+					"To force a sensor, add that line to "
+					"/etc/modprobe.d/options.conf:");
+				PDEBUG(D_PROBE, "options gspca_gl860 "
+					"sensor=\"OV2640\" or \"OV9655\"");
+				return -1;
+			}
+		} else { /* probe = 0 */
+			PDEBUG(D_PROBE, "No 0xff -> sensor MI2020");
+			sd->sensor = ID_MI2020;
+		}
+	}
+
+	if (_MI1320_) {
+		PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
+	} else if (_MI2020_) {
+		PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
+	} else if (_MI2020b_) {
+		PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 alt. driver (2.0M)");
+	} else if (_OV9655_) {
+		PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
+	} else if (_OV2640_) {
+		PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
+	} else {
+		PDEBUG(D_PROBE, "***** Unknown sensor *****");
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
new file mode 100644
index 0000000..cef4e24
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860.h
@@ -0,0 +1,108 @@
+/* @file gl860.h
+ * @author Olivier LORIN, tirÃ© du pilote Syntek par Nicolas VIVIEN
+ * @date 2009-08-27
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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 GL860_DEV_H
+#define GL860_DEV_H
+#include <linux/version.h>
+
+#include "gspca.h"
+
+#define MODULE_NAME "gspca_gl860"
+#define DRIVER_VERSION "0.9d10"
+
+#define ctrl_in  gl860_RTx
+#define ctrl_out gl860_RTx
+
+#define ID_MI1320   1
+#define ID_OV2640   2
+#define ID_OV9655   4
+#define ID_MI2020   8
+#define ID_MI2020b 16
+
+#define _MI1320_  (((struct sd *) gspca_dev)->sensor == ID_MI1320)
+#define _MI2020_  (((struct sd *) gspca_dev)->sensor == ID_MI2020)
+#define _MI2020b_ (((struct sd *) gspca_dev)->sensor == ID_MI2020b)
+#define _MI2020c_ 0
+#define _OV2640_  (((struct sd *) gspca_dev)->sensor == ID_OV2640)
+#define _OV9655_  (((struct sd *) gspca_dev)->sensor == ID_OV9655)
+
+#define IMAGE_640   0
+#define IMAGE_800   1
+#define IMAGE_1280  2
+#define IMAGE_1600 3
+
+struct sd_gl860 {
+	u16 backlight;
+	u16 brightness;
+	u16 sharpness;
+	u16 contrast;
+	u16 gamma;
+	u16 hue;
+	u16 saturation;
+	u16 whitebal;
+	u8  mirror;
+	u8  flip;
+	u8  AC50Hz;
+};
+
+/* Specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev;	/* !! must be the first item */
+
+	struct sd_gl860 vcur;
+	struct sd_gl860 vold;
+	struct sd_gl860 vmax;
+
+	int  (*dev_configure_alt)  (struct gspca_dev *);
+	int  (*dev_init_at_startup)(struct gspca_dev *);
+	int  (*dev_init_pre_alt)   (struct gspca_dev *);
+	void (*dev_post_unset_alt) (struct gspca_dev *);
+	int  (*dev_camera_settings)(struct gspca_dev *);
+
+	u8   swapRB;
+	u8  mirrorMask;
+	u8  sensor;
+	s32 nbIm;
+	s32 nbRightUp;
+	u8   waitSet;
+};
+
+struct validx {
+	u16 val;
+	u16 idx;
+};
+
+struct idxdata {
+	u8 idx;
+	u8 data[3];
+};
+
+int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len);
+int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
+				int len, int n);
+void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len);
+
+int gl860_RTx(struct gspca_dev *gspca_dev,
+			unsigned char pref, u32 req, u16 val, u16 index,
+			s32 len, void *pdata);
+
+void mi1320_init_settings(struct gspca_dev *);
+void ov2640_init_settings(struct gspca_dev *);
+void ov9655_init_settings(struct gspca_dev *);
+void mi2020_init_settings(struct gspca_dev *);
+
+#endif
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index b8561df..cf6540d 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 6, 0)
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 7, 0)
 
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
@@ -486,6 +486,7 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
 	}
 	PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
 			i, ep->desc.bEndpointAddress);
+	gspca_dev->alt = i;		/* memorize the current alt setting */
 	if (gspca_dev->nbalt > 1) {
 		ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
 		if (ret < 0) {
@@ -493,7 +494,6 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
 			return NULL;
 		}
 	}
-	gspca_dev->alt = i;		/* memorize the current alt setting */
 	return ep;
 }
 
@@ -512,7 +512,10 @@ static int create_urbs(struct gspca_dev *gspca_dev,
 	if (!gspca_dev->cam.bulk) {		/* isoc */
 
 		/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
-		psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+		if (gspca_dev->pkt_size == 0)
+			psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+		else
+			psize = gspca_dev->pkt_size;
 		npkt = gspca_dev->cam.npkt;
 		if (npkt == 0)
 			npkt = 32;		/* default value */
@@ -597,13 +600,18 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
 	/* set the higher alternate setting and
 	 * loop until urb submit succeeds */
 	gspca_dev->alt = gspca_dev->nbalt;
+	if (gspca_dev->sd_desc->isoc_init) {
+		ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
+		if (ret < 0)
+			goto out;
+	}
+	ep = get_ep(gspca_dev);
+	if (ep == NULL) {
+		ret = -EIO;
+		goto out;
+	}
 	for (;;) {
 		PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt);
-		ep = get_ep(gspca_dev);
-		if (ep == NULL) {
-			ret = -EIO;
-			goto out;
-		}
 		ret = create_urbs(gspca_dev, ep);
 		if (ret < 0)
 			goto out;
@@ -628,21 +636,32 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
 		/* submit the URBs */
 		for (n = 0; n < gspca_dev->nurbs; n++) {
 			ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL);
-			if (ret < 0) {
-				PDEBUG(D_ERR|D_STREAM,
-					"usb_submit_urb [%d] err %d", n, ret);
-				gspca_dev->streaming = 0;
-				destroy_urbs(gspca_dev);
-				if (ret == -ENOSPC) {
-					msleep(20);	/* wait for kill
-							 * complete */
-					break;	/* try the previous alt */
-				}
-				goto out;
-			}
+			if (ret < 0)
+				break;
 		}
 		if (ret >= 0)
 			break;
+		PDEBUG(D_ERR|D_STREAM,
+			"usb_submit_urb alt %d err %d", gspca_dev->alt, ret);
+		gspca_dev->streaming = 0;
+		destroy_urbs(gspca_dev);
+		if (ret != -ENOSPC)
+			goto out;
+
+		/* the bandwidth is not wide enough
+		 * negociate or try a lower alternate setting */
+		msleep(20);	/* wait for kill complete */
+		if (gspca_dev->sd_desc->isoc_nego) {
+			ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
+			if (ret < 0)
+				goto out;
+		} else {
+			ep = get_ep(gspca_dev);
+			if (ep == NULL) {
+				ret = -EIO;
+				goto out;
+			}
+		}
 	}
 out:
 	mutex_unlock(&gspca_dev->usb_lock);
@@ -1473,12 +1492,6 @@ static int vidioc_s_parm(struct file *filp, void *priv,
 	return 0;
 }
 
-static int vidioc_s_std(struct file *filp, void *priv,
-			v4l2_std_id *parm)
-{
-	return 0;
-}
-
 #ifdef CONFIG_VIDEO_V4L1_COMPAT
 static int vidiocgmbuf(struct file *file, void *priv,
 			struct video_mbuf *mbuf)
@@ -1949,7 +1962,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
 	.vidioc_s_jpegcomp	= vidioc_s_jpegcomp,
 	.vidioc_g_parm		= vidioc_g_parm,
 	.vidioc_s_parm		= vidioc_s_parm,
-	.vidioc_s_std		= vidioc_s_std,
 	.vidioc_enum_framesizes = vidioc_enum_framesizes,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.vidioc_g_register	= vidioc_g_register,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 46c4eff..70b1fd8 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -98,9 +98,11 @@ struct sd_desc {
 /* mandatory operations */
 	cam_cf_op config;	/* called on probe */
 	cam_op init;		/* called on probe and resume */
-	cam_op start;		/* called on stream on */
+	cam_op start;		/* called on stream on after URBs creation */
 	cam_pkt_op pkt_scan;
 /* optional operations */
+	cam_op isoc_init;	/* called on stream on before getting the EP */
+	cam_op isoc_nego;	/* called when URB submit failed with NOSPC */
 	cam_v_op stopN;		/* called on stream off - main alt */
 	cam_v_op stop0;		/* called on stream off & disconnect - alt 0 */
 	cam_v_op dq_callback;	/* called when a frame has been dequeued */
@@ -178,6 +180,7 @@ struct gspca_dev {
 	__u8 iface;			/* USB interface number */
 	__u8 alt;			/* USB alternate setting */
 	__u8 nbalt;			/* number of USB alternate settings */
+	u16 pkt_size;			/* ISOC packet size */
 };
 
 int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
new file mode 100644
index 0000000..a11c97e
--- /dev/null
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -0,0 +1,390 @@
+/*
+ * Jeilinj subdriver
+ *
+ * Supports some Jeilin dual-mode cameras which use bulk transport and
+ * download raw JPEG data.
+ *
+ * Copyright (C) 2009 Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU 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
+ */
+
+#define MODULE_NAME "jeilinj"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+#include "jpeg.h"
+
+MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define JEILINJ_CMD_TIMEOUT 500
+#define JEILINJ_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define JEILINJ_MAX_TRANSFER 0x200
+
+#define FRAME_HEADER_LEN 0x10
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+	struct gspca_dev gspca_dev;	/* !! must be the first item */
+	const struct v4l2_pix_format *cap_mode;
+	/* Driver stuff */
+	struct work_struct work_struct;
+	struct workqueue_struct *work_thread;
+	u8 quality;				 /* image quality */
+	u8 jpegqual;				/* webcam quality */
+	u8 *jpeg_hdr;
+};
+
+	struct jlj_command {
+		unsigned char instruction[2];
+		unsigned char ack_wanted;
+	};
+
+/* AFAICT these cameras will only do 320x240. */
+static struct v4l2_pix_format jlj_mode[] = {
+	{ 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 320,
+		.sizeimage = 320 * 240,
+		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0}
+};
+
+/*
+ * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
+ * and 0x82 for bulk transfer.
+ */
+
+/* All commands are two bytes only */
+static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
+{
+	int retval;
+
+	memcpy(gspca_dev->usb_buf, command, 2);
+	retval = usb_bulk_msg(gspca_dev->dev,
+			usb_sndbulkpipe(gspca_dev->dev, 3),
+			gspca_dev->usb_buf, 2, NULL, 500);
+	if (retval < 0)
+		PDEBUG(D_ERR, "command write [%02x] error %d",
+				gspca_dev->usb_buf[0], retval);
+	return retval;
+}
+
+/* Responses are one byte only */
+static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
+{
+	int retval;
+
+	retval = usb_bulk_msg(gspca_dev->dev,
+	usb_rcvbulkpipe(gspca_dev->dev, 0x84),
+				gspca_dev->usb_buf, 1, NULL, 500);
+	response = gspca_dev->usb_buf[0];
+	if (retval < 0)
+		PDEBUG(D_ERR, "read command [%02x] error %d",
+				gspca_dev->usb_buf[0], retval);
+	return retval;
+}
+
+static int jlj_start(struct gspca_dev *gspca_dev)
+{
+	int i;
+	int retval = -1;
+	u8 response = 0xff;
+	struct jlj_command start_commands[] = {
+		{{0x71, 0x81}, 0},
+		{{0x70, 0x05}, 0},
+		{{0x95, 0x70}, 1},
+		{{0x71, 0x81}, 0},
+		{{0x70, 0x04}, 0},
+		{{0x95, 0x70}, 1},
+		{{0x71, 0x00}, 0},
+		{{0x70, 0x08}, 0},
+		{{0x95, 0x70}, 1},
+		{{0x94, 0x02}, 0},
+		{{0xde, 0x24}, 0},
+		{{0x94, 0x02}, 0},
+		{{0xdd, 0xf0}, 0},
+		{{0x94, 0x02}, 0},
+		{{0xe3, 0x2c}, 0},
+		{{0x94, 0x02}, 0},
+		{{0xe4, 0x00}, 0},
+		{{0x94, 0x02}, 0},
+		{{0xe5, 0x00}, 0},
+		{{0x94, 0x02}, 0},
+		{{0xe6, 0x2c}, 0},
+		{{0x94, 0x03}, 0},
+		{{0xaa, 0x00}, 0},
+		{{0x71, 0x1e}, 0},
+		{{0x70, 0x06}, 0},
+		{{0x71, 0x80}, 0},
+		{{0x70, 0x07}, 0}
+	};
+	for (i = 0; i < ARRAY_SIZE(start_commands); i++) {
+		retval = jlj_write2(gspca_dev, start_commands[i].instruction);
+		if (retval < 0)
+			return retval;
+		if (start_commands[i].ack_wanted)
+			retval = jlj_read1(gspca_dev, response);
+		if (retval < 0)
+			return retval;
+	}
+	PDEBUG(D_ERR, "jlj_start retval is %d", retval);
+	return retval;
+}
+
+static int jlj_stop(struct gspca_dev *gspca_dev)
+{
+	int i;
+	int retval;
+	struct jlj_command stop_commands[] = {
+		{{0x71, 0x00}, 0},
+		{{0x70, 0x09}, 0},
+		{{0x71, 0x80}, 0},
+		{{0x70, 0x05}, 0}
+	};
+	for (i = 0; i < ARRAY_SIZE(stop_commands); i++) {
+		retval = jlj_write2(gspca_dev, stop_commands[i].instruction);
+		if (retval < 0)
+			return retval;
+	}
+	return retval;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface the gspca usb_lock is
+ * used when performing the one USB control operation inside the workqueue,
+ * which tells the camera to close the stream. In practice the only thing
+ * which needs to be protected against is the usb_set_interface call that
+ * gspca makes during stream_off. Otherwise the camera doesn't provide any
+ * controls that the user could try to change.
+ */
+
+static void jlj_dostream(struct work_struct *work)
+{
+	struct sd *dev = container_of(work, struct sd, work_struct);
+	struct gspca_dev *gspca_dev = &dev->gspca_dev;
+	struct gspca_frame *frame;
+	int blocks_left; /* 0x200-sized blocks remaining in current frame. */
+	int size_in_blocks;
+	int act_len;
+	int discarding = 0; /* true if we failed to get space for frame. */
+	int packet_type;
+	int ret;
+	u8 *buffer;
+
+	buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+	if (!buffer) {
+		PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+		goto quit_stream;
+	}
+	while (gspca_dev->present && gspca_dev->streaming) {
+		if (!gspca_dev->present)
+			goto quit_stream;
+		/* Start a new frame, and add the JPEG header, first thing */
+		frame = gspca_get_i_frame(gspca_dev);
+		if (frame && !discarding)
+			gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+					dev->jpeg_hdr, JPEG_HDR_SZ);
+		 else
+			discarding = 1;
+		/*
+		 * Now request data block 0. Line 0 reports the size
+		 * to download, in blocks of size 0x200, and also tells the
+		 * "actual" data size, in bytes, which seems best to ignore.
+		 */
+		ret = usb_bulk_msg(gspca_dev->dev,
+				usb_rcvbulkpipe(gspca_dev->dev, 0x82),
+				buffer, JEILINJ_MAX_TRANSFER, &act_len,
+				JEILINJ_DATA_TIMEOUT);
+		PDEBUG(D_STREAM,
+			"Got %d bytes out of %d for Block 0",
+			act_len, JEILINJ_MAX_TRANSFER);
+		if (ret < 0 || act_len < FRAME_HEADER_LEN)
+			goto quit_stream;
+		size_in_blocks = buffer[0x0a];
+		blocks_left = buffer[0x0a] - 1;
+		PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
+		packet_type = INTER_PACKET;
+		if (frame && !discarding)
+			/* Toss line 0 of data block 0, keep the rest. */
+			gspca_frame_add(gspca_dev, packet_type,
+				frame, buffer + FRAME_HEADER_LEN,
+				JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
+			else
+				discarding = 1;
+		while (blocks_left > 0) {
+			if (!gspca_dev->present)
+				goto quit_stream;
+			ret = usb_bulk_msg(gspca_dev->dev,
+				usb_rcvbulkpipe(gspca_dev->dev, 0x82),
+				buffer, JEILINJ_MAX_TRANSFER, &act_len,
+				JEILINJ_DATA_TIMEOUT);
+			if (ret < 0 || act_len < JEILINJ_MAX_TRANSFER)
+				goto quit_stream;
+			PDEBUG(D_STREAM,
+				"%d blocks remaining for frame", blocks_left);
+			blocks_left -= 1;
+			if (blocks_left == 0)
+				packet_type = LAST_PACKET;
+			else
+				packet_type = INTER_PACKET;
+			if (frame && !discarding)
+				gspca_frame_add(gspca_dev, packet_type,
+						frame, buffer,
+						JEILINJ_MAX_TRANSFER);
+			else
+				discarding = 1;
+		}
+	}
+quit_stream:
+	mutex_lock(&gspca_dev->usb_lock);
+	if (gspca_dev->present)
+		jlj_stop(gspca_dev);
+	mutex_unlock(&gspca_dev->usb_lock);
+	kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+		const struct usb_device_id *id)
+{
+	struct cam *cam = &gspca_dev->cam;
+	struct sd *dev  = (struct sd *) gspca_dev;
+
+	dev->quality  = 85;
+	dev->jpegqual = 85;
+	PDEBUG(D_PROBE,
+		"JEILINJ camera detected"
+		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+	cam->cam_mode = jlj_mode;
+	cam->nmodes = 1;
+	cam->bulk = 1;
+	/* We don't use the buffer gspca allocates so make it small. */
+	cam->bulk_size = 32;
+	INIT_WORK(&dev->work_struct, jlj_dostream);
+	return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+	struct sd *dev = (struct sd *) gspca_dev;
+
+	/* wait for the work queue to terminate */
+	mutex_unlock(&gspca_dev->usb_lock);
+	/* This waits for jlj_dostream to finish */
+	destroy_workqueue(dev->work_thread);
+	dev->work_thread = NULL;
+	mutex_lock(&gspca_dev->usb_lock);
+	kfree(dev->jpeg_hdr);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	return 0;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *dev = (struct sd *) gspca_dev;
+	int ret;
+
+	/* create the JPEG header */
+	dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+	if (dev->jpeg_hdr == NULL)
+		return -ENOMEM;
+	jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+			0x21);          /* JPEG 422 */
+	jpeg_set_qual(dev->jpeg_hdr, dev->quality);
+	PDEBUG(D_STREAM, "Start streaming at 320x240");
+	ret = jlj_start(gspca_dev);
+	if (ret < 0) {
+		PDEBUG(D_ERR, "Start streaming command failed");
+		return ret;
+	}
+	/* Start the workqueue function to do the streaming */
+	dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+	queue_work(dev->work_thread, &dev->work_struct);
+
+	return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x0979, 0x0280)},
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+	.name   = MODULE_NAME,
+	.config = sd_config,
+	.init   = sd_init,
+	.start  = sd_start,
+	.stop0  = sd_stop0,
+};
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+		const struct usb_device_id *id)
+{
+	return gspca_dev_probe(intf, id,
+			&sd_desc,
+			sizeof(struct sd),
+			THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+	.name       = MODULE_NAME,
+	.id_table   = device_table,
+	.probe      = sd_probe,
+	.disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+	.suspend = gspca_suspend,
+	.resume  = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+	int ret;
+
+	ret = usb_register(&sd_driver);
+	if (ret < 0)
+		return ret;
+	PDEBUG(D_PROBE, "registered");
+	return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+	PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index 7aafeb7..2a28b74 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -20,6 +20,18 @@
 
 static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
 static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 *val);
+static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 val);
+static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
+static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
 
 const static struct ctrl ov7660_ctrls[] = {
 #define GAIN_IDX 1
@@ -37,6 +49,79 @@ const static struct ctrl ov7660_ctrls[] = {
 		.set = ov7660_set_gain,
 		.get = ov7660_get_gain
 	},
+#define BLUE_BALANCE_IDX 2
+#define RED_BALANCE_IDX 3
+#define AUTO_WHITE_BALANCE_IDX 4
+	{
+		{
+			.id 		= V4L2_CID_AUTO_WHITE_BALANCE,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto white balance",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 1
+		},
+		.set = ov7660_set_auto_white_balance,
+		.get = ov7660_get_auto_white_balance
+	},
+#define AUTO_GAIN_CTRL_IDX 5
+	{
+		{
+			.id 		= V4L2_CID_AUTOGAIN,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto gain control",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 1
+		},
+		.set = ov7660_set_auto_gain,
+		.get = ov7660_get_auto_gain
+	},
+#define AUTO_EXPOSURE_IDX 6
+	{
+		{
+			.id 		= V4L2_CID_EXPOSURE_AUTO,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "auto exposure",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 1
+		},
+		.set = ov7660_set_auto_exposure,
+		.get = ov7660_get_auto_exposure
+	},
+#define HFLIP_IDX 7
+	{
+		{
+			.id 		= V4L2_CID_HFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "horizontal flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0
+		},
+		.set = ov7660_set_hflip,
+		.get = ov7660_get_hflip
+	},
+#define VFLIP_IDX 8
+	{
+		{
+			.id 		= V4L2_CID_VFLIP,
+			.type 		= V4L2_CTRL_TYPE_BOOLEAN,
+			.name 		= "vertical flip",
+			.minimum 	= 0,
+			.maximum 	= 1,
+			.step 		= 1,
+			.default_value 	= 0
+		},
+		.set = ov7660_set_vflip,
+		.get = ov7660_get_vflip
+	},
+
 };
 
 static struct v4l2_pix_format ov7660_modes[] = {
@@ -137,7 +222,7 @@ int ov7660_init(struct sd *sd)
 		} else {
 			data[0] = init_ov7660[i][2];
 			err = m5602_write_sensor(sd,
-					init_ov7660[i][1], data, 1);
+				init_ov7660[i][1], data, 1);
 		}
 	}
 
@@ -148,6 +233,28 @@ int ov7660_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
+	err = ov7660_set_auto_white_balance(&sd->gspca_dev,
+		sensor_settings[AUTO_WHITE_BALANCE_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov7660_set_auto_gain(&sd->gspca_dev,
+		sensor_settings[AUTO_GAIN_CTRL_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov7660_set_auto_exposure(&sd->gspca_dev,
+		sensor_settings[AUTO_EXPOSURE_IDX]);
+	if (err < 0)
+		return err;
+	err = ov7660_set_hflip(&sd->gspca_dev,
+		sensor_settings[HFLIP_IDX]);
+	if (err < 0)
+		return err;
+
+	err = ov7660_set_vflip(&sd->gspca_dev,
+		sensor_settings[VFLIP_IDX]);
+
 	return err;
 }
 
@@ -194,6 +301,159 @@ static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 	return err;
 }
 
+
+static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
+	return 0;
+}
+
+static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
+					 __s32 val)
+{
+	int err;
+	u8 i2c_data;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Set auto white balance to %d", val);
+
+	sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
+	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
+	err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
+
+	return err;
+}
+
+static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[AUTO_GAIN_CTRL_IDX];
+	PDEBUG(D_V4L2, "Read auto gain control %d", *val);
+	return 0;
+}
+
+static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	u8 i2c_data;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Set auto gain control to %d", val);
+
+	sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
+	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
+
+	return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
+}
+
+static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[AUTO_EXPOSURE_IDX];
+	PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
+	return 0;
+}
+
+static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
+				    __s32 val)
+{
+	int err;
+	u8 i2c_data;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
+
+	sensor_settings[AUTO_EXPOSURE_IDX] = val;
+	err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
+
+	return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
+}
+
+static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[HFLIP_IDX];
+	PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
+	return 0;
+}
+
+static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	u8 i2c_data;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
+
+	sensor_settings[HFLIP_IDX] = val;
+
+	i2c_data = ((val & 0x01) << 5) |
+		(sensor_settings[VFLIP_IDX] << 4);
+
+	err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
+
+	return err;
+}
+
+static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	*val = sensor_settings[VFLIP_IDX];
+	PDEBUG(D_V4L2, "Read vertical flip %d", *val);
+
+	return 0;
+}
+
+static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+	int err;
+	u8 i2c_data;
+	struct sd *sd = (struct sd *) gspca_dev;
+	s32 *sensor_settings = sd->sensor_priv;
+
+	PDEBUG(D_V4L2, "Set vertical flip to %d", val);
+	sensor_settings[VFLIP_IDX] = val;
+
+	i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
+	err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
+	if (err < 0)
+		return err;
+
+	/* When vflip is toggled we need to readjust the bridge hsync/vsync */
+	if (gspca_dev->streaming)
+		err = ov7660_start(sd);
+
+	return err;
+}
+
 static void ov7660_dump_registers(struct sd *sd)
 {
 	int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 3f2c169..f5588eb 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -66,23 +66,23 @@
 #define OV7660_RBIAS		0x2c
 #define OV7660_HREF		0x32
 #define OV7660_ADC		0x37
-#define OV7660_OFON 		0x39
-#define OV7660_TSLB 		0x3a
-#define OV7660_COM12 		0x3c
-#define OV7660_COM13 		0x3d
+#define OV7660_OFON		0x39
+#define OV7660_TSLB		0x3a
+#define OV7660_COM12		0x3c
+#define OV7660_COM13		0x3d
 #define OV7660_LCC1		0x62
 #define OV7660_LCC2		0x63
 #define OV7660_LCC3		0x64
 #define OV7660_LCC4		0x65
 #define OV7660_LCC5		0x66
-#define OV7660_HV 		0x69
-#define OV7660_RSVDA1 		0xa1
+#define OV7660_HV		0x69
+#define OV7660_RSVDA1		0xa1
 
 #define OV7660_DEFAULT_GAIN		0x0e
-#define OV7660_DEFAULT_RED_GAIN	0x80
+#define OV7660_DEFAULT_RED_GAIN		0x80
 #define OV7660_DEFAULT_BLUE_GAIN 	0x80
 #define OV7660_DEFAULT_SATURATION	0x00
-#define OV7660_DEFAULT_EXPOSURE	0x20
+#define OV7660_DEFAULT_EXPOSURE		0x20
 
 /* Kernel module parameters */
 extern int force_sensor;
@@ -149,45 +149,8 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
 	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
 	{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-
-	{SENSOR, OV7660_OFON, 0x0c},
-	{SENSOR, OV7660_COM2, 0x11},
-	{SENSOR, OV7660_COM7, 0x05},
-
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
-	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
-
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-
-	{SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE},
-	{SENSOR, OV7660_COM1, 0x00},
-
 	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -196,11 +159,8 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
 	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
 	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
-
 	{SENSOR, OV7660_COM7, 0x80},
 	{SENSOR, OV7660_CLKRC, 0x80},
-	{SENSOR, OV7660_BLUE_GAIN, 0x80},
-	{SENSOR, OV7660_RED_GAIN, 0x80},
 	{SENSOR, OV7660_COM9, 0x4c},
 	{SENSOR, OV7660_OFON, 0x43},
 	{SENSOR, OV7660_COM12, 0x28},
@@ -212,17 +172,17 @@ static const unsigned char init_ov7660[][4] =
 	{SENSOR, OV7660_PSHFT, 0x0b},
 	{SENSOR, OV7660_VSTART, 0x01},
 	{SENSOR, OV7660_VSTOP, 0x7a},
-	{SENSOR, OV7660_VREF, 0x00},
+	{SENSOR, OV7660_VSTOP, 0x00},
 	{SENSOR, OV7660_COM7, 0x05},
-	{SENSOR, OV7660_COM6, 0x4b},
-	{SENSOR, OV7660_BBIAS, 0x98},
-	{SENSOR, OV7660_GbBIAS, 0x98},
-	{SENSOR, OV7660_RSVD29, 0x98},
-	{SENSOR, OV7660_RBIAS, 0x98},
+	{SENSOR, OV7660_COM6, 0x42},
+	{SENSOR, OV7660_BBIAS, 0x94},
+	{SENSOR, OV7660_GbBIAS, 0x94},
+	{SENSOR, OV7660_RSVD29, 0x94},
+	{SENSOR, OV7660_RBIAS, 0x94},
 	{SENSOR, OV7660_COM1, 0x00},
 	{SENSOR, OV7660_AECH, 0x00},
 	{SENSOR, OV7660_AECHH, 0x00},
-	{SENSOR, OV7660_ADC, 0x04},
+	{SENSOR, OV7660_ADC, 0x05},
 	{SENSOR, OV7660_COM13, 0x00},
 	{SENSOR, OV7660_RSVDA1, 0x23},
 	{SENSOR, OV7660_TSLB, 0x0d},
@@ -233,6 +193,47 @@ static const unsigned char init_ov7660[][4] =
 	{SENSOR, OV7660_LCC4, 0x40},
 	{SENSOR, OV7660_LCC5, 0x01},
 
+	{SENSOR, OV7660_AECH, 0x20},
+	{SENSOR, OV7660_COM1, 0x00},
+	{SENSOR, OV7660_OFON, 0x0c},
+	{SENSOR, OV7660_COM2, 0x11},
+	{SENSOR, OV7660_COM7, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+	{SENSOR, OV7660_AECH, 0x5f},
+	{SENSOR, OV7660_COM1, 0x03},
+	{SENSOR, OV7660_OFON, 0x0c},
+	{SENSOR, OV7660_COM2, 0x11},
+	{SENSOR, OV7660_COM7, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
+	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
+	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
+	{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
+	{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
+	{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
+	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
+	{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
+
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
 	{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -245,35 +246,18 @@ static const unsigned char init_ov7660[][4] =
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */
+	{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
 	{BRIDGE, M5602_XB_SIG_INI, 0x02},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0x02},
-	{BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
+	{BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
 	{BRIDGE, M5602_XB_SIG_INI, 0x00},
-
 	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
 	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
-
-	{SENSOR, OV7660_AECH, 0x20},
-	{SENSOR, OV7660_COM1, 0x00},
-	{SENSOR, OV7660_OFON, 0x0c},
-	{SENSOR, OV7660_COM2, 0x11},
-	{SENSOR, OV7660_COM7, 0x05},
-	{SENSOR, OV7660_BLUE_GAIN, 0x80},
-	{SENSOR, OV7660_RED_GAIN, 0x80},
-
-	{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
-	{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
-	{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
-	{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
-	{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
-	{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
 };
 
 #endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 0163903..59400e8 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -47,6 +47,12 @@ static
 			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
 		}
 	}, {
+		.ident = "Fujitsu-Siemens Amilo Pa 2548",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548")
+		}
+	}, {
 		.ident = "MSI GX700",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
@@ -54,6 +60,13 @@ static
 			DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
 		}
 	}, {
+		.ident = "MSI GX700",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
+			DMI_MATCH(DMI_BIOS_DATE, "07/19/2007")
+		}
+	}, {
 		.ident = "MSI GX700/GX705/EX700",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 7127321..6b89f33 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -178,8 +178,10 @@ sensor_found:
 
 	sens_priv->settings =
 	kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
-	if (!sens_priv->settings)
+	if (!sens_priv->settings) {
+		kfree(sens_priv);
 		return -ENOMEM;
+	}
 
 	sd->gspca_dev.cam.cam_mode = s5k83a_modes;
 	sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 3013251..140c8f3 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -3,6 +3,21 @@
  *
  * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
  *
+ * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
+ * and for the routines for detecting and classifying these various cameras,
+ *
+ * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
+ *
+ * Acknowledgements:
+ *
+ * The MR97311A support in gspca/mars.c has been helpful in understanding some
+ * of the registers in these cameras.
+ *
+ * Hans de Goede <hdgoede@redhat.com> and
+ * Thomas Kaiser <thomas@kaiser-linux.li>
+ * have assisted with their experience. Each of them has also helped by
+ * testing a previously unsupported camera.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -22,18 +37,108 @@
 
 #include "gspca.h"
 
-MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
+#define CAM_TYPE_CIF			0
+#define CAM_TYPE_VGA			1
+
+#define MR97310A_BRIGHTNESS_MIN		-254
+#define MR97310A_BRIGHTNESS_MAX		255
+#define MR97310A_BRIGHTNESS_DEFAULT	0
+
+#define MR97310A_EXPOSURE_MIN		300
+#define MR97310A_EXPOSURE_MAX		4095
+#define MR97310A_EXPOSURE_DEFAULT	1000
+
+#define MR97310A_GAIN_MIN		0
+#define MR97310A_GAIN_MAX		31
+#define MR97310A_GAIN_DEFAULT		25
+
+MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
+	      "Theodore Kilgore <kilgota@auburn.edu>");
 MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
 MODULE_LICENSE("GPL");
 
+/* global parameters */
+int force_sensor_type = -1;
+module_param(force_sensor_type, int, 0644);
+MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
+
 /* specific webcam descriptor */
 struct sd {
 	struct gspca_dev gspca_dev;  /* !! must be the first item */
 	u8 sof_read;
+	u8 cam_type;	/* 0 is CIF and 1 is VGA */
+	u8 sensor_type;	/* We use 0 and 1 here, too. */
+	u8 do_lcd_stop;
+
+	int brightness;
+	u16 exposure;
+	u8 gain;
+};
+
+struct sensor_w_data {
+	u8 reg;
+	u8 flags;
+	u8 data[16];
+	int len;
 };
 
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static void setbrightness(struct gspca_dev *gspca_dev);
+static void setexposure(struct gspca_dev *gspca_dev);
+static void setgain(struct gspca_dev *gspca_dev);
+
 /* V4L2 controls supported by the driver */
 static struct ctrl sd_ctrls[] = {
+	{
+#define BRIGHTNESS_IDX 0
+		{
+			.id = V4L2_CID_BRIGHTNESS,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Brightness",
+			.minimum = MR97310A_BRIGHTNESS_MIN,
+			.maximum = MR97310A_BRIGHTNESS_MAX,
+			.step = 1,
+			.default_value = MR97310A_BRIGHTNESS_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setbrightness,
+		.get = sd_getbrightness,
+	},
+	{
+#define EXPOSURE_IDX 1
+		{
+			.id = V4L2_CID_EXPOSURE,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Exposure",
+			.minimum = MR97310A_EXPOSURE_MIN,
+			.maximum = MR97310A_EXPOSURE_MAX,
+			.step = 1,
+			.default_value = MR97310A_EXPOSURE_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setexposure,
+		.get = sd_getexposure,
+	},
+	{
+#define GAIN_IDX 2
+		{
+			.id = V4L2_CID_GAIN,
+			.type = V4L2_CTRL_TYPE_INTEGER,
+			.name = "Gain",
+			.minimum = MR97310A_GAIN_MIN,
+			.maximum = MR97310A_GAIN_MAX,
+			.step = 1,
+			.default_value = MR97310A_GAIN_DEFAULT,
+			.flags = 0,
+		},
+		.set = sd_setgain,
+		.get = sd_getgain,
+	},
 };
 
 static const struct v4l2_pix_format vga_mode[] = {
@@ -65,7 +170,7 @@ static const struct v4l2_pix_format vga_mode[] = {
 };
 
 /* the bytes to write are in gspca_dev->usb_buf */
-static int reg_w(struct gspca_dev *gspca_dev, int len)
+static int mr_write(struct gspca_dev *gspca_dev, int len)
 {
 	int rc;
 
@@ -78,15 +183,249 @@ static int reg_w(struct gspca_dev *gspca_dev, int len)
 	return rc;
 }
 
+/* the bytes are read into gspca_dev->usb_buf */
+static int mr_read(struct gspca_dev *gspca_dev, int len)
+{
+	int rc;
+
+	rc = usb_bulk_msg(gspca_dev->dev,
+			  usb_rcvbulkpipe(gspca_dev->dev, 3),
+			  gspca_dev->usb_buf, len, NULL, 500);
+	if (rc < 0)
+		PDEBUG(D_ERR, "reg read [%02x] error %d",
+		       gspca_dev->usb_buf[0], rc);
+	return rc;
+}
+
+static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
+	const u8 *data, int len)
+{
+	gspca_dev->usb_buf[0] = 0x1f;
+	gspca_dev->usb_buf[1] = flags;
+	gspca_dev->usb_buf[2] = reg;
+	memcpy(gspca_dev->usb_buf + 3, data, len);
+
+	return mr_write(gspca_dev, len + 3);
+}
+
+static int sensor_write_regs(struct gspca_dev *gspca_dev,
+	const struct sensor_w_data *data, int len)
+{
+	int i, rc;
+
+	for (i = 0; i < len; i++) {
+		rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
+					  data[i].data, data[i].len);
+		if (rc < 0)
+			return rc;
+	}
+
+	return 0;
+}
+
+static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 buf, confirm_reg;
+	int rc;
+
+	buf = data;
+	rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
+	if (rc < 0)
+		return rc;
+
+	buf = 0x01;
+	confirm_reg = sd->sensor_type ? 0x13 : 0x11;
+	rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static int cam_get_response16(struct gspca_dev *gspca_dev)
+{
+	__u8 *data = gspca_dev->usb_buf;
+	int err_code;
+
+	data[0] = 0x21;
+	err_code = mr_write(gspca_dev, 1);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = mr_read(gspca_dev, 16);
+	return err_code;
+}
+
+static int zero_the_pointer(struct gspca_dev *gspca_dev)
+{
+	__u8 *data = gspca_dev->usb_buf;
+	int err_code;
+	u8 status = 0;
+	int tries = 0;
+
+	err_code = cam_get_response16(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = mr_write(gspca_dev, 1);
+	data[0] = 0x19;
+	data[1] = 0x51;
+	err_code = mr_write(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = cam_get_response16(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x19;
+	data[1] = 0xba;
+	err_code = mr_write(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = cam_get_response16(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x19;
+	data[1] = 0x00;
+	err_code = mr_write(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = cam_get_response16(gspca_dev);
+	if (err_code < 0)
+		return err_code;
+
+	data[0] = 0x19;
+	data[1] = 0x00;
+	err_code = mr_write(gspca_dev, 2);
+	if (err_code < 0)
+		return err_code;
+
+	while (status != 0x0a && tries < 256) {
+		err_code = cam_get_response16(gspca_dev);
+		status = data[0];
+		tries++;
+		if (err_code < 0)
+			return err_code;
+	}
+	if (status != 0x0a)
+		PDEBUG(D_ERR, "status is %02x", status);
+
+	tries = 0;
+	while (tries < 4) {
+		data[0] = 0x19;
+		data[1] = 0x00;
+		err_code = mr_write(gspca_dev, 2);
+		if (err_code < 0)
+			return err_code;
+
+		err_code = cam_get_response16(gspca_dev);
+		status = data[0];
+		tries++;
+		if (err_code < 0)
+			return err_code;
+	}
+
+	data[0] = 0x19;
+	err_code = mr_write(gspca_dev, 1);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = mr_read(gspca_dev, 16);
+	if (err_code < 0)
+		return err_code;
+
+	return 0;
+}
+
+static u8 get_sensor_id(struct gspca_dev *gspca_dev)
+{
+	int err_code;
+
+	gspca_dev->usb_buf[0] = 0x1e;
+	err_code = mr_write(gspca_dev, 1);
+	if (err_code < 0)
+		return err_code;
+
+	err_code = mr_read(gspca_dev, 16);
+	if (err_code < 0)
+		return err_code;
+
+	PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
+
+	return gspca_dev->usb_buf[0];
+}
+
 /* this function is called at probe time */
 static int sd_config(struct gspca_dev *gspca_dev,
 		     const struct usb_device_id *id)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
+	__u8 *data = gspca_dev->usb_buf;
+	int err_code;
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
+
+	if (id->idProduct == 0x010e) {
+		sd->cam_type = CAM_TYPE_CIF;
+		cam->nmodes--;
+
+		data[0] = 0x01;
+		data[1] = 0x01;
+		err_code = mr_write(gspca_dev, 2);
+		if (err_code < 0)
+			return err_code;
+
+		msleep(200);
+		data[0] = get_sensor_id(gspca_dev);
+		/*
+		 * Known CIF cameras. If you have another to report, please do
+		 *
+		 * Name			byte just read		sd->sensor_type
+		 *					reported by
+		 * Sakar Spy-shot	0x28		T. Kilgore	0
+		 * Innovage		0xf5 (unstable)	T. Kilgore	0
+		 * Vivitar Mini		0x53		H. De Goede	0
+		 * Vivitar Mini		0x04 / 0x24	E. Rodriguez	0
+		 * Vivitar Mini		0x08		T. Kilgore	1
+		 * Elta-Media 8212dc	0x23		T. Kaiser	1
+		 * Philips dig. keych.	0x37		T. Kilgore	1
+		 */
+		if ((data[0] & 0x78) == 8 ||
+		    ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
+			sd->sensor_type = 1;
+		else
+			sd->sensor_type = 0;
+
+		PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
+		       sd->sensor_type);
+
+		if (force_sensor_type != -1) {
+			sd->sensor_type = !! force_sensor_type;
+			PDEBUG(D_PROBE, "Forcing sensor type to: %d",
+			       sd->sensor_type);
+		}
+
+		if (sd->sensor_type == 0)
+			gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
+	} else {
+		sd->cam_type = CAM_TYPE_VGA;
+		PDEBUG(D_PROBE, "MR97310A VGA camera detected");
+		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
+				      (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
+	}
+
+	sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
+	sd->exposure = MR97310A_EXPOSURE_DEFAULT;
+	sd->gain = MR97310A_GAIN_DEFAULT;
+
 	return 0;
 }
 
@@ -96,183 +435,462 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	return 0;
 }
 
-static int sd_start(struct gspca_dev *gspca_dev)
+static int start_cif_cam(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	__u8 *data = gspca_dev->usb_buf;
 	int err_code;
-
-	sd->sof_read = 0;
-
-	/* Note:  register descriptions guessed from MR97113A driver */
-
+	const __u8 startup_string[] = {
+		0x00,
+		0x0d,
+		0x01,
+		0x00, /* Hsize/8 for 352 or 320 */
+		0x00, /* Vsize/4 for 288 or 240 */
+		0x13, /* or 0xbb, depends on sensor */
+		0x00, /* Hstart, depends on res. */
+		0x00, /* reserved ? */
+		0x00, /* Vstart, depends on res. and sensor */
+		0x50, /* 0x54 to get 176 or 160 */
+		0xc0
+	};
+
+	/* Note: Some of the above descriptions guessed from MR97113A driver */
 	data[0] = 0x01;
 	data[1] = 0x01;
-	err_code = reg_w(gspca_dev, 2);
+	err_code = mr_write(gspca_dev, 2);
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x00;
-	data[1] = 0x0d;
-	data[2] = 0x01;
-	data[5] = 0x2b;
-	data[7] = 0x00;
-	data[9] = 0x50;  /* reg 8, no scale down */
-	data[10] = 0xc0;
+	memcpy(data, startup_string, 11);
+	if (sd->sensor_type)
+		data[5] = 0xbb;
 
 	switch (gspca_dev->width) {
 	case 160:
-		data[9] |= 0x0c;  /* reg 8, 4:1 scale down */
+		data[9] |= 0x04;  /* reg 8, 2:1 scale down from 320 */
 		/* fall thru */
 	case 320:
-		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
-		/* fall thru */
-	case 640:
 	default:
-		data[3] = 0x50;  /* reg 2, H size */
-		data[4] = 0x78;  /* reg 3, V size */
-		data[6] = 0x04;  /* reg 5, H start */
-		data[8] = 0x03;  /* reg 7, V start */
+		data[3] = 0x28;			   /* reg 2, H size/8 */
+		data[4] = 0x3c;			   /* reg 3, V size/4 */
+		data[6] = 0x14;			   /* reg 5, H start  */
+		data[8] = 0x1a + sd->sensor_type;  /* reg 7, V start  */
 		break;
-
 	case 176:
-		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
+		data[9] |= 0x04;  /* reg 8, 2:1 scale down from 352 */
 		/* fall thru */
 	case 352:
-		data[3] = 0x2c;  /* reg 2, H size */
-		data[4] = 0x48;  /* reg 3, V size */
-		data[6] = 0x94;  /* reg 5, H start */
-		data[8] = 0x63;  /* reg 7, V start */
+		data[3] = 0x2c;			   /* reg 2, H size/8 */
+		data[4] = 0x48;			   /* reg 3, V size/4 */
+		data[6] = 0x06;			   /* reg 5, H start  */
+		data[8] = 0x06 + sd->sensor_type;  /* reg 7, V start  */
 		break;
 	}
-
-	err_code = reg_w(gspca_dev, 11);
+	err_code = mr_write(gspca_dev, 11);
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x0a;
-	data[1] = 0x80;
-	err_code = reg_w(gspca_dev, 2);
+	if (!sd->sensor_type) {
+		const struct sensor_w_data cif_sensor0_init_data[] = {
+			{0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
+				      0x0f, 0x14, 0x0f, 0x10}, 8},
+			{0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
+			{0x12, 0x00, {0x07}, 1},
+			{0x1f, 0x00, {0x06}, 1},
+			{0x27, 0x00, {0x04}, 1},
+			{0x29, 0x00, {0x0c}, 1},
+			{0x40, 0x00, {0x40, 0x00, 0x04}, 3},
+			{0x50, 0x00, {0x60}, 1},
+			{0x60, 0x00, {0x06}, 1},
+			{0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
+			{0x72, 0x00, {0x1e, 0x56}, 2},
+			{0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
+				      0x31, 0x80, 0x00}, 9},
+			{0x11, 0x00, {0x01}, 1},
+			{0, 0, {0}, 0}
+		};
+		err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
+					 ARRAY_SIZE(cif_sensor0_init_data));
+	} else {	/* sd->sensor_type = 1 */
+		const struct sensor_w_data cif_sensor1_init_data[] = {
+			/* Reg 3,4, 7,8 get set by the controls */
+			{0x02, 0x00, {0x10}, 1},
+			{0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
+			{0x06, 0x01, {0x00}, 1},
+			{0x09, 0x02, {0x0e}, 1},
+			{0x0a, 0x02, {0x05}, 1},
+			{0x0b, 0x02, {0x05}, 1},
+			{0x0c, 0x02, {0x0f}, 1},
+			{0x0d, 0x02, {0x07}, 1},
+			{0x0e, 0x02, {0x0c}, 1},
+			{0x0f, 0x00, {0x00}, 1},
+			{0x10, 0x00, {0x06}, 1},
+			{0x11, 0x00, {0x07}, 1},
+			{0x12, 0x00, {0x00}, 1},
+			{0x13, 0x00, {0x01}, 1},
+			{0, 0, {0}, 0}
+		};
+		err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
+					 ARRAY_SIZE(cif_sensor1_init_data));
+	}
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x14;
-	data[1] = 0x0a;
-	err_code = reg_w(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
+	setbrightness(gspca_dev);
+	setexposure(gspca_dev);
+	setgain(gspca_dev);
 
-	data[0] = 0x1b;
-	data[1] = 0x00;
-	err_code = reg_w(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
+	msleep(200);
 
-	data[0] = 0x15;
-	data[1] = 0x16;
-	err_code = reg_w(gspca_dev, 2);
+	data[0] = 0x00;
+	data[1] = 0x4d;  /* ISOC transfering enable... */
+	err_code = mr_write(gspca_dev, 2);
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x16;
-	data[1] = 0x10;
-	err_code = reg_w(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
+	return 0;
+}
 
-	data[0] = 0x17;
-	data[1] = 0x3a;
-	err_code = reg_w(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
+static int start_vga_cam(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	__u8 *data = gspca_dev->usb_buf;
+	int err_code;
+	const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
+				       0x00, 0x00, 0x00, 0x50, 0xc0};
 
-	data[0] = 0x18;
-	data[1] = 0x68;
-	err_code = reg_w(gspca_dev, 2);
-	if (err_code < 0)
-		return err_code;
+	/* What some of these mean is explained in start_cif_cam(), above */
+	sd->sof_read = 0;
 
-	data[0] = 0x1f;
-	data[1] = 0x00;
-	data[2] = 0x02;
-	data[3] = 0x06;
-	data[4] = 0x59;
-	data[5] = 0x0c;
-	data[6] = 0x16;
-	data[7] = 0x00;
-	data[8] = 0x07;
-	data[9] = 0x00;
-	data[10] = 0x01;
-	err_code = reg_w(gspca_dev, 11);
+	/*
+	 * We have to know which camera we have, because the register writes
+	 * depend upon the camera. This test, run before we actually enter
+	 * the initialization routine, distinguishes most of the cameras, If
+	 * needed, another routine is done later, too.
+	 */
+	memset(data, 0, 16);
+	data[0] = 0x20;
+	err_code = mr_write(gspca_dev, 1);
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x1f;
-	data[1] = 0x04;
-	data[2] = 0x11;
-	data[3] = 0x01;
-	err_code = reg_w(gspca_dev, 4);
+	err_code = mr_read(gspca_dev, 16);
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x1f;
-	data[1] = 0x00;
-	data[2] = 0x0a;
-	data[3] = 0x00;
-	data[4] = 0x01;
-	data[5] = 0x00;
-	data[6] = 0x00;
-	data[7] = 0x01;
-	data[8] = 0x00;
-	data[9] = 0x0a;
-	err_code = reg_w(gspca_dev, 10);
-	if (err_code < 0)
-		return err_code;
+	PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
+
+	msleep(200);
+	/*
+	 * Known VGA cameras. If you have another to report, please do
+	 *
+	 * Name			byte just read		sd->sensor_type
+	 *				sd->do_lcd_stop
+	 * Aiptek Pencam VGA+	0x31		0	1
+	 * ION digital		0x31		0	1
+	 * Argus DC-1620	0x30		1	0
+	 * Argus QuickClix	0x30		1	1 (not caught here)
+	 */
+	sd->sensor_type = data[0] & 1;
+	sd->do_lcd_stop = (~data[0]) & 1;
+
+
 
-	data[0] = 0x1f;
-	data[1] = 0x04;
-	data[2] = 0x11;
-	data[3] = 0x01;
-	err_code = reg_w(gspca_dev, 4);
+	/* Streaming setup begins here. */
+
+
+	data[0] = 0x01;
+	data[1] = 0x01;
+	err_code = mr_write(gspca_dev, 2);
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x1f;
-	data[1] = 0x00;
-	data[2] = 0x12;
-	data[3] = 0x00;
-	data[4] = 0x63;
-	data[5] = 0x00;
-	data[6] = 0x70;
-	data[7] = 0x00;
-	data[8] = 0x00;
-	err_code = reg_w(gspca_dev, 9);
+	/*
+	 * A second test can now resolve any remaining ambiguity in the
+	 * identification of the camera type,
+	 */
+	if (!sd->sensor_type) {
+		data[0] = get_sensor_id(gspca_dev);
+		if (data[0] == 0x7f) {
+			sd->sensor_type = 1;
+			PDEBUG(D_PROBE, "sensor_type corrected to 1");
+		}
+		msleep(200);
+	}
+
+	if (force_sensor_type != -1) {
+		sd->sensor_type = !! force_sensor_type;
+		PDEBUG(D_PROBE, "Forcing sensor type to: %d",
+		       sd->sensor_type);
+	}
+
+	/*
+	 * Known VGA cameras.
+	 * This test is only run if the previous test returned 0x30, but
+	 * here is the information for all others, too, just for reference.
+	 *
+	 * Name			byte just read		sd->sensor_type
+	 *
+	 * Aiptek Pencam VGA+	0xfb	(this test not run)	1
+	 * ION digital		0xbd	(this test not run)	1
+	 * Argus DC-1620	0xe5	(no change)		0
+	 * Argus QuickClix	0x7f	(reclassified)		1
+	 */
+	memcpy(data, startup_string, 11);
+	if (!sd->sensor_type) {
+		data[5]  = 0x00;
+		data[10] = 0x91;
+	}
+
+	switch (gspca_dev->width) {
+	case 160:
+		data[9] |= 0x0c;  /* reg 8, 4:1 scale down */
+		/* fall thru */
+	case 320:
+		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
+		/* fall thru */
+	case 640:
+	default:
+		data[3] = 0x50;  /* reg 2, H size/8 */
+		data[4] = 0x78;  /* reg 3, V size/4 */
+		data[6] = 0x04;  /* reg 5, H start */
+		data[8] = 0x03;  /* reg 7, V start */
+		if (sd->do_lcd_stop)
+			data[8] = 0x04;  /* Bayer tile shifted */
+		break;
+
+	case 176:
+		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
+		/* fall thru */
+	case 352:
+		data[3] = 0x2c;  /* reg 2, H size */
+		data[4] = 0x48;  /* reg 3, V size */
+		data[6] = 0x94;  /* reg 5, H start */
+		data[8] = 0x63;  /* reg 7, V start */
+		if (sd->do_lcd_stop)
+			data[8] = 0x64;  /* Bayer tile shifted */
+		break;
+	}
+
+	err_code = mr_write(gspca_dev, 11);
 	if (err_code < 0)
 		return err_code;
 
-	data[0] = 0x1f;
-	data[1] = 0x04;
-	data[2] = 0x11;
-	data[3] = 0x01;
-	err_code = reg_w(gspca_dev, 4);
+	if (!sd->sensor_type) {
+		/* The only known sensor_type 0 cam is the Argus DC-1620 */
+		const struct sensor_w_data vga_sensor0_init_data[] = {
+			{0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
+			{0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
+			{0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
+			{0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
+			{0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
+			{0, 0, {0}, 0}
+		};
+		err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
+					 ARRAY_SIZE(vga_sensor0_init_data));
+	} else {	/* sd->sensor_type = 1 */
+		const struct sensor_w_data vga_sensor1_init_data[] = {
+			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
+				0x07, 0x00, 0x01}, 8},
+			{0x11, 0x04, {0x01}, 1},
+			/*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
+			{0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
+				0x00, 0x0a}, 7},
+			{0x11, 0x04, {0x01}, 1},
+			{0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
+			{0x11, 0x04, {0x01}, 1},
+			{0, 0, {0}, 0}
+		};
+		err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
+					 ARRAY_SIZE(vga_sensor1_init_data));
+	}
 	if (err_code < 0)
 		return err_code;
 
+	msleep(200);
 	data[0] = 0x00;
 	data[1] = 0x4d;  /* ISOC transfering enable... */
-	err_code = reg_w(gspca_dev, 2);
+	err_code = mr_write(gspca_dev, 2);
+
+	return err_code;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int err_code;
+	struct cam *cam;
+
+	cam = &gspca_dev->cam;
+	sd->sof_read = 0;
+	/*
+	 * Some of the supported cameras require the memory pointer to be
+	 * set to 0, or else they will not stream.
+	 */
+	zero_the_pointer(gspca_dev);
+	msleep(200);
+	if (sd->cam_type == CAM_TYPE_CIF) {
+		err_code = start_cif_cam(gspca_dev);
+	} else {
+		err_code = start_vga_cam(gspca_dev);
+	}
 	return err_code;
 }
 
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	int result;
 
 	gspca_dev->usb_buf[0] = 1;
 	gspca_dev->usb_buf[1] = 0;
-	result = reg_w(gspca_dev, 2);
+	result = mr_write(gspca_dev, 2);
 	if (result < 0)
 		PDEBUG(D_ERR, "Camera Stop failed");
+
+	/* Not all the cams need this, but even if not, probably a good idea */
+	zero_the_pointer(gspca_dev);
+	if (sd->do_lcd_stop) {
+		gspca_dev->usb_buf[0] = 0x19;
+		gspca_dev->usb_buf[1] = 0x54;
+		result = mr_write(gspca_dev, 2);
+		if (result < 0)
+			PDEBUG(D_ERR, "Camera Stop failed");
+	}
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
+		return;
+
+	/* Note register 7 is also seen as 0x8x or 0xCx in dumps */
+	if (sd->brightness > 0) {
+		sensor_write1(gspca_dev, 7, 0x00);
+		val = sd->brightness;
+	} else {
+		sensor_write1(gspca_dev, 7, 0x01);
+		val = 257 - sd->brightness;
+	}
+	sensor_write1(gspca_dev, 8, val);
+}
+
+static void setexposure(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 val;
+
+	if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
+		return;
+
+	if (sd->sensor_type) {
+		val = sd->exposure >> 4;
+		sensor_write1(gspca_dev, 3, val);
+		val = sd->exposure & 0xf;
+		sensor_write1(gspca_dev, 4, val);
+	} else {
+		u8 clockdiv;
+		int exposure;
+
+		/* We have both a clock divider and an exposure register.
+		   We first calculate the clock divider, as that determines
+		   the maximum exposure and then we calculayte the exposure
+		   register setting (which goes from 0 - 511).
+
+		   Note our 0 - 4095 exposure is mapped to 0 - 511
+		   milliseconds exposure time */
+		clockdiv = (60 * sd->exposure + 7999) / 8000;
+
+		/* Limit framerate to not exceed usb bandwidth */
+		if (clockdiv < 3 && gspca_dev->width >= 320)
+			clockdiv = 3;
+		else if (clockdiv < 2)
+			clockdiv = 2;
+
+		/* Frame exposure time in ms = 1000 * clockdiv / 60 ->
+		exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
+		exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
+		if (exposure > 511)
+			exposure = 511;
+
+		/* exposure register value is reversed! */
+		exposure = 511 - exposure;
+
+		sensor_write1(gspca_dev, 0x02, clockdiv);
+		sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
+		sensor_write1(gspca_dev, 0x0f, exposure >> 8);
+	}
+}
+
+static void setgain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
+		return;
+
+	if (sd->sensor_type) {
+		sensor_write1(gspca_dev, 0x0e, sd->gain);
+	} else {
+		sensor_write1(gspca_dev, 0x10, sd->gain);
+	}
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->brightness = val;
+	if (gspca_dev->streaming)
+		setbrightness(gspca_dev);
+	return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->brightness;
+	return 0;
+}
+
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->exposure = val;
+	if (gspca_dev->streaming)
+		setexposure(gspca_dev);
+	return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->exposure;
+	return 0;
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	sd->gain = val;
+	if (gspca_dev->streaming)
+		setgain(gspca_dev);
+	return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	*val = sd->gain;
+	return 0;
 }
 
 /* Include pac common sof detection functions */
@@ -320,8 +938,9 @@ static const struct sd_desc sd_desc = {
 
 /* -- module initialisation -- */
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x08ca, 0x0111)},
-	{USB_DEVICE(0x093a, 0x010f)},
+	{USB_DEVICE(0x08ca, 0x0111)},	/* Aiptek Pencam VGA+ */
+	{USB_DEVICE(0x093a, 0x010f)},	/* All other known MR97310A VGA cams */
+	{USB_DEVICE(0x093a, 0x010e)},	/* All known MR97310A CIF cams */
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 95a97ab..9665943 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -35,25 +35,17 @@ MODULE_LICENSE("GPL");
 
 #define PAC207_BRIGHTNESS_MIN		0
 #define PAC207_BRIGHTNESS_MAX		255
-#define PAC207_BRIGHTNESS_DEFAULT	4 /* power on default: 4 */
-
-/* An exposure value of 4 also works (3 does not) but then we need to lower
-   the compression balance setting when in 352x288 mode, otherwise the usb
-   bandwidth is not enough and packets get dropped resulting in corrupt
-   frames. The problem with this is that when the compression balance gets
-   lowered below 0x80, the pac207 starts using a different compression
-   algorithm for some lines, these lines get prefixed with a 0x2dd2 prefix
-   and currently we do not know how to decompress these lines, so for now
-   we use a minimum exposure value of 5 */
-#define PAC207_EXPOSURE_MIN		5
+#define PAC207_BRIGHTNESS_DEFAULT	46
+
+#define PAC207_EXPOSURE_MIN		3
 #define PAC207_EXPOSURE_MAX		26
-#define PAC207_EXPOSURE_DEFAULT		5 /* power on default: 3 ?? */
-#define PAC207_EXPOSURE_KNEE		11 /* 4 = 30 fps, 11 = 8, 15 = 6 */
+#define PAC207_EXPOSURE_DEFAULT		5 /* power on default: 3 */
+#define PAC207_EXPOSURE_KNEE		8 /* 4 = 30 fps, 11 = 8, 15 = 6 */
 
 #define PAC207_GAIN_MIN			0
 #define PAC207_GAIN_MAX			31
 #define PAC207_GAIN_DEFAULT         	9 /* power on default: 9 */
-#define PAC207_GAIN_KNEE		20
+#define PAC207_GAIN_KNEE		31
 
 #define PAC207_AUTOGAIN_DEADZONE	30
 
@@ -166,16 +158,12 @@ static const struct v4l2_pix_format sif_mode[] = {
 };
 
 static const __u8 pac207_sensor_init[][8] = {
-	{0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0},
-	{0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
+	{0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84},
+	{0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
 	{0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
-	{0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02},
 	{0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
 };
 
-			/* 48 reg_72 Rate Control end BalSize_4a =0x36 */
-static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
-
 static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
 	const u8 *buffer, u16 length)
 {
@@ -274,7 +262,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
 				 * Bit_1=LED,
 				 * Bit_2=Compression test mode enable */
 	pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
-	pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
 
 	return 0;
 }
@@ -289,15 +276,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
 	pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
 	pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
-	pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8);
-	pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8);
-	pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4);
+	pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8);
 
 	/* Compression Balance */
 	if (gspca_dev->width == 176)
 		pac207_write_reg(gspca_dev, 0x4a, 0xff);
 	else
-		pac207_write_reg(gspca_dev, 0x4a, 0x88);
+		pac207_write_reg(gspca_dev, 0x4a, 0x30);
 	pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
 	pac207_write_reg(gspca_dev, 0x08, sd->brightness);
 
@@ -346,7 +331,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
 	if (sd->autogain_ignore_frames > 0)
 		sd->autogain_ignore_frames--;
 	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
-			100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
+			100, PAC207_AUTOGAIN_DEADZONE,
 			PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
 		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
 }
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index e1e3a3a..0527144 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -1057,6 +1057,7 @@ static struct sd_desc sd_desc = {
 
 /* -- module initialisation -- */
 static __devinitdata struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302},
 	{USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
 	{USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
 	{USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
@@ -1068,6 +1069,7 @@ static __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
 	{USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
 	{USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
+	{USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
 	{USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
 	{USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
 	{}
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index fcfbbd3..cdad3db 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -94,6 +94,16 @@ struct sd {
 #endif
 };
 
+struct i2c_reg_u8 {
+	u8 reg;
+	u8 val;
+};
+
+struct i2c_reg_u16 {
+	u8 reg;
+	u16 val;
+};
+
 static int sd_setbrightness(struct gspca_dev *gspca_dev, s32 val);
 static int sd_getbrightness(struct gspca_dev *gspca_dev, s32 *val);
 static int sd_setcontrast(struct gspca_dev *gspca_dev, s32 val);
@@ -403,7 +413,7 @@ static const struct v4l2_pix_format sxga_mode[] = {
 		.priv = 3 | MODE_RAW | MODE_SXGA},
 };
 
-static const int hsv_red_x[] = {
+static const s16 hsv_red_x[] = {
 	41,  44,  46,  48,  50,  52,  54,  56,
 	58,  60,  62,  64,  66,  68,  70,  72,
 	74,  76,  78,  80,  81,  83,  85,  87,
@@ -451,7 +461,7 @@ static const int hsv_red_x[] = {
 	24,  26,  28,  30,  33,  35,  37,  39, 41
 };
 
-static const int hsv_red_y[] = {
+static const s16 hsv_red_y[] = {
 	82,  80,  78,  76,  74,  73,  71,  69,
 	67,  65,  63,  61,  58,  56,  54,  52,
 	50,  48,  46,  44,  41,  39,  37,  35,
@@ -499,7 +509,7 @@ static const int hsv_red_y[] = {
 	96, 94, 92, 91, 89, 87, 85, 84, 82
 };
 
-static const int hsv_green_x[] = {
+static const s16 hsv_green_x[] = {
 	-124, -124, -125, -125, -125, -125, -125, -125,
 	-125, -126, -126, -125, -125, -125, -125, -125,
 	-125, -124, -124, -124, -123, -123, -122, -122,
@@ -547,7 +557,7 @@ static const int hsv_green_x[] = {
 	-120, -120, -121, -122, -122, -123, -123, -124, -124
 };
 
-static const int hsv_green_y[] = {
+static const s16 hsv_green_y[] = {
 	-100, -99, -98, -97, -95, -94, -93, -91,
 	-90, -89, -87, -86, -84, -83, -81, -80,
 	-78, -76, -75, -73, -71, -70, -68, -66,
@@ -595,7 +605,7 @@ static const int hsv_green_y[] = {
 	-109, -108, -107, -106, -105, -104, -103, -102, -100
 };
 
-static const int hsv_blue_x[] = {
+static const s16 hsv_blue_x[] = {
 	112, 113, 114, 114, 115, 116, 117, 117,
 	118, 118, 119, 119, 120, 120, 120, 121,
 	121, 121, 122, 122, 122, 122, 122, 122,
@@ -643,7 +653,7 @@ static const int hsv_blue_x[] = {
 	104, 105, 106, 107, 108, 109, 110, 111, 112
 };
 
-static const int hsv_blue_y[] = {
+static const s16 hsv_blue_y[] = {
 	-11, -13, -15, -17, -19, -21, -23, -25,
 	-27, -29, -31, -33, -35, -37, -39, -41,
 	-43, -45, -46, -48, -50, -52, -54, -55,
@@ -792,21 +802,21 @@ static u8 hv7131r_gain[] = {
 	0x78 /* 8x */
 };
 
-static u8 soi968_init[][2] = {
+static struct i2c_reg_u8 soi968_init[] = {
 	{0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
 	{0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
 	{0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
 	{0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
 	{0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
 	{0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
-	{0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13},
+	{0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
 	{0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
 	{0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
 	{0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
 	{0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
 };
 
-static u8 ov7660_init[][2] = {
+static struct i2c_reg_u8 ov7660_init[] = {
 	{0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
 	{0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
 	{0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
@@ -815,7 +825,7 @@ static u8 ov7660_init[][2] = {
 	{0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
 };
 
-static u8 ov7670_init[][2] = {
+static struct i2c_reg_u8 ov7670_init[] = {
 	{0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
 	{0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
 	{0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
@@ -872,7 +882,7 @@ static u8 ov7670_init[][2] = {
 	{0x93, 0x00},
 };
 
-static u8 ov9650_init[][2] = {
+static struct i2c_reg_u8 ov9650_init[] = {
 	{0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
 	{0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
 	{0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
@@ -902,7 +912,7 @@ static u8 ov9650_init[][2] = {
 	{0xaa, 0x92}, {0xab, 0x0a},
 };
 
-static u8 ov9655_init[][2] = {
+static struct i2c_reg_u8 ov9655_init[] = {
 	{0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
 	{0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
 	{0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
@@ -939,7 +949,7 @@ static u8 ov9655_init[][2] = {
 	{0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
 };
 
-static u16 mt9v112_init[][2] = {
+static struct i2c_reg_u16 mt9v112_init[] = {
 	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
 	{0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
 	{0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
@@ -958,7 +968,7 @@ static u16 mt9v112_init[][2] = {
 	{0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
 };
 
-static u16 mt9v111_init[][2] = {
+static struct i2c_reg_u16 mt9v111_init[] = {
 	{0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
 	{0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
 	{0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
@@ -985,7 +995,7 @@ static u16 mt9v111_init[][2] = {
 	{0x0e, 0x0008},	{0x06, 0x002d},	{0x05, 0x0004},
 };
 
-static u16 mt9v011_init[][2] = {
+static struct i2c_reg_u16 mt9v011_init[] = {
 	{0x07, 0x0002},	{0x0d, 0x0001},	{0x0d, 0x0000},
 	{0x01, 0x0008},	{0x02, 0x0016},	{0x03, 0x01e1},
 	{0x04, 0x0281},	{0x05, 0x0083},	{0x06, 0x0006},
@@ -1012,7 +1022,7 @@ static u16 mt9v011_init[][2] = {
 	{0x06, 0x0029},	{0x05, 0x0009},
 };
 
-static u16 mt9m001_init[][2] = {
+static struct i2c_reg_u16 mt9m001_init[] = {
 	{0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
 	{0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
 	{0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
@@ -1025,14 +1035,14 @@ static u16 mt9m001_init[][2] = {
 	{0x2e, 0x0029}, {0x07, 0x0002},
 };
 
-static u16 mt9m111_init[][2] = {
-	{0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009},
-	{0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300},
-	{0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200},
-	{0x06, 0x308e}, {0xf0, 0x0000},
+static struct i2c_reg_u16 mt9m111_init[] = {
+	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
+	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
+	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
+	{0xf0, 0x0000},
 };
 
-static u8 hv7131r_init[][2] = {
+static struct i2c_reg_u8 hv7131r_init[] = {
 	{0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
 	{0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
 	{0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
@@ -1043,7 +1053,7 @@ static u8 hv7131r_init[][2] = {
 	{0x23, 0x09}, {0x01, 0x08},
 };
 
-int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
+static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int result;
@@ -1062,7 +1072,8 @@ int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
 	return 0;
 }
 
-int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length)
+static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
+		 const u8 *buffer, int length)
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int result;
@@ -1082,13 +1093,13 @@ int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length)
 	return 0;
 }
 
-int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
+static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
 {
 	u8 data[1] = {value};
 	return reg_w(gspca_dev, reg, data, 1);
 }
 
-int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
+static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
 {
 	int i;
 	reg_w(gspca_dev, 0x10c0, buffer, 8);
@@ -1096,15 +1107,15 @@ int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
 		reg_r(gspca_dev, 0x10c0, 1);
 		if (gspca_dev->usb_buf[0] & 0x04) {
 			if (gspca_dev->usb_buf[0] & 0x08)
-				return -1;
+				return -EIO;
 			return 0;
 		}
 		msleep(1);
 	}
-	return -1;
+	return -EIO;
 }
 
-int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
+static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
@@ -1126,7 +1137,7 @@ int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
 	return i2c_w(gspca_dev, row);
 }
 
-int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
+static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 row[8];
@@ -1152,7 +1163,7 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 row[8];
 
-	row[0] = 0x81 | 0x10;
+	row[0] = 0x81 | (1 << 4);
 	row[1] = sd->i2c_addr;
 	row[2] = reg;
 	row[3] = 0;
@@ -1160,14 +1171,15 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
 	row[5] = 0;
 	row[6] = 0;
 	row[7] = 0x10;
-	reg_w(gspca_dev, 0x10c0, row, 8);
-	msleep(1);
-	row[0] = 0x81 | (2 << 4) | 0x02;
+	if (i2c_w(gspca_dev, row) < 0)
+		return -EIO;
+	row[0] = 0x81 | (1 << 4) | 0x02;
 	row[2] = 0;
-	reg_w(gspca_dev, 0x10c0, row, 8);
-	msleep(1);
-	reg_r(gspca_dev, 0x10c2, 5);
-	*val = gspca_dev->usb_buf[3];
+	if (i2c_w(gspca_dev, row) < 0)
+		return -EIO;
+	if (reg_r(gspca_dev, 0x10c2, 5) < 0)
+		return -EIO;
+	*val = gspca_dev->usb_buf[4];
 	return 0;
 }
 
@@ -1176,7 +1188,7 @@ int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 row[8];
 
-	row[0] = 0x81 | 0x10;
+	row[0] = 0x81 | (1 << 4);
 	row[1] = sd->i2c_addr;
 	row[2] = reg;
 	row[3] = 0;
@@ -1184,14 +1196,15 @@ int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
 	row[5] = 0;
 	row[6] = 0;
 	row[7] = 0x10;
-	reg_w(gspca_dev, 0x10c0, row, 8);
-	msleep(1);
-	row[0] = 0x81 | (3 << 4) | 0x02;
+	if (i2c_w(gspca_dev, row) < 0)
+		return -EIO;
+	row[0] = 0x81 | (2 << 4) | 0x02;
 	row[2] = 0;
-	reg_w(gspca_dev, 0x10c0, row, 8);
-	msleep(1);
-	reg_r(gspca_dev, 0x10c2, 5);
-	*val = (gspca_dev->usb_buf[2] << 8) | gspca_dev->usb_buf[3];
+	if (i2c_w(gspca_dev, row) < 0)
+		return -EIO;
+	if (reg_r(gspca_dev, 0x10c2, 5) < 0)
+		return -EIO;
+	*val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
 	return 0;
 }
 
@@ -1201,8 +1214,8 @@ static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
-		if (i2c_w1(gspca_dev, ov9650_init[i][0],
-				ov9650_init[i][1]) < 0) {
+		if (i2c_w1(gspca_dev, ov9650_init[i].reg,
+				ov9650_init[i].val) < 0) {
 			err("OV9650 sensor initialization failed");
 			return -ENODEV;
 		}
@@ -1218,8 +1231,8 @@ static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
-		if (i2c_w1(gspca_dev, ov9655_init[i][0],
-				ov9655_init[i][1]) < 0) {
+		if (i2c_w1(gspca_dev, ov9655_init[i].reg,
+				ov9655_init[i].val) < 0) {
 			err("OV9655 sensor initialization failed");
 			return -ENODEV;
 		}
@@ -1237,14 +1250,14 @@ static int soi968_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
-		if (i2c_w1(gspca_dev, soi968_init[i][0],
-				soi968_init[i][1]) < 0) {
+		if (i2c_w1(gspca_dev, soi968_init[i].reg,
+				soi968_init[i].val) < 0) {
 			err("SOI968 sensor initialization failed");
 			return -ENODEV;
 		}
 	}
 	/* disable hflip and vflip */
-	gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
+	gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
 	sd->hstart = 60;
 	sd->vstart = 11;
 	return 0;
@@ -1256,8 +1269,8 @@ static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
-		if (i2c_w1(gspca_dev, ov7660_init[i][0],
-				ov7660_init[i][1]) < 0) {
+		if (i2c_w1(gspca_dev, ov7660_init[i].reg,
+				ov7660_init[i].val) < 0) {
 			err("OV7660 sensor initialization failed");
 			return -ENODEV;
 		}
@@ -1275,8 +1288,8 @@ static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
-		if (i2c_w1(gspca_dev, ov7670_init[i][0],
-				ov7670_init[i][1]) < 0) {
+		if (i2c_w1(gspca_dev, ov7670_init[i].reg,
+				ov7670_init[i].val) < 0) {
 			err("OV7670 sensor initialization failed");
 			return -ENODEV;
 		}
@@ -1299,8 +1312,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
 	ret = i2c_r2(gspca_dev, 0xff, &value);
 	if ((ret == 0) && (value == 0x8243)) {
 		for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
-			if (i2c_w2(gspca_dev, mt9v011_init[i][0],
-					mt9v011_init[i][1]) < 0) {
+			if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
+					mt9v011_init[i].val) < 0) {
 				err("MT9V011 sensor initialization failed");
 				return -ENODEV;
 			}
@@ -1317,8 +1330,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
 	ret = i2c_r2(gspca_dev, 0xff, &value);
 	if ((ret == 0) && (value == 0x823a)) {
 		for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
-			if (i2c_w2(gspca_dev, mt9v111_init[i][0],
-					mt9v111_init[i][1]) < 0) {
+			if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
+					mt9v111_init[i].val) < 0) {
 				err("MT9V111 sensor initialization failed");
 				return -ENODEV;
 			}
@@ -1339,8 +1352,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
 	ret = i2c_r2(gspca_dev, 0x00, &value);
 	if ((ret == 0) && (value == 0x1229)) {
 		for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
-			if (i2c_w2(gspca_dev, mt9v112_init[i][0],
-					mt9v112_init[i][1]) < 0) {
+			if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
+					mt9v112_init[i].val) < 0) {
 				err("MT9V112 sensor initialization failed");
 				return -ENODEV;
 			}
@@ -1360,12 +1373,13 @@ static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
 	for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
-		if (i2c_w2(gspca_dev, mt9m111_init[i][0],
-				mt9m111_init[i][1]) < 0) {
+		if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
+				mt9m111_init[i].val) < 0) {
 			err("MT9M111 sensor initialization failed");
 			return -ENODEV;
 		}
 	}
+	gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
 	sd->hstart = 0;
 	sd->vstart = 2;
 	return 0;
@@ -1376,8 +1390,8 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
 	for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
-		if (i2c_w2(gspca_dev, mt9m001_init[i][0],
-				mt9m001_init[i][1]) < 0) {
+		if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
+				mt9m001_init[i].val) < 0) {
 			err("MT9M001 sensor initialization failed");
 			return -ENODEV;
 		}
@@ -1395,8 +1409,8 @@ static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
 	struct sd *sd = (struct sd *) gspca_dev;
 
 	for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
-		if (i2c_w1(gspca_dev, hv7131r_init[i][0],
-				hv7131r_init[i][1]) < 0) {
+		if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
+				hv7131r_init[i].val) < 0) {
 			err("HV7131R Sensor initialization failed");
 			return -ENODEV;
 		}
@@ -1620,7 +1634,6 @@ static int set_exposure(struct gspca_dev *gspca_dev)
 	switch (sd->sensor) {
 	case SENSOR_OV7660:
 	case SENSOR_OV7670:
-	case SENSOR_SOI968:
 	case SENSOR_OV9655:
 	case SENSOR_OV9650:
 		exp[0] |= (3 << 4);
@@ -1629,7 +1642,6 @@ static int set_exposure(struct gspca_dev *gspca_dev)
 		exp[4] = sd->exposure >> 8;
 		break;
 	case SENSOR_MT9M001:
-	case SENSOR_MT9M111:
 	case SENSOR_MT9V112:
 	case SENSOR_MT9V111:
 	case SENSOR_MT9V011:
@@ -1645,6 +1657,8 @@ static int set_exposure(struct gspca_dev *gspca_dev)
 		exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8;
 		exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff;
 		break;
+	default:
+		return 0;
 	}
 	i2c_w(gspca_dev, exp);
 	return 0;
@@ -1671,7 +1685,6 @@ static int set_gain(struct gspca_dev *gspca_dev)
 		gain[4] = micron1_gain[sd->gain] & 0xff;
 		break;
 	case SENSOR_MT9V112:
-	case SENSOR_MT9M111:
 		gain[0] |= (3 << 4);
 		gain[2] = 0x2f;
 		gain[3] = micron1_gain[sd->gain] >> 8;
@@ -1688,6 +1701,8 @@ static int set_gain(struct gspca_dev *gspca_dev)
 		gain[2] = 0x30;
 		gain[3] = hv7131r_gain[sd->gain];
 		break;
+	default:
+		return 0;
 	}
 	i2c_w(gspca_dev, gain);
 	return 0;
@@ -1990,7 +2005,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	sd->i2c_addr = id->driver_info & 0xff;
 
 	switch (sd->sensor) {
+	case SENSOR_MT9M111:
 	case SENSOR_OV9650:
+	case SENSOR_SOI968:
 		cam->cam_mode = sxga_mode;
 		cam->nmodes = ARRAY_SIZE(sxga_mode);
 		break;
@@ -2106,6 +2123,25 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 value;
 	switch (sd->sensor) {
+	case SENSOR_SOI968:
+		if (mode & MODE_SXGA) {
+			i2c_w1(gspca_dev, 0x17, 0x1d);
+			i2c_w1(gspca_dev, 0x18, 0xbd);
+			i2c_w1(gspca_dev, 0x19, 0x01);
+			i2c_w1(gspca_dev, 0x1a, 0x81);
+			i2c_w1(gspca_dev, 0x12, 0x00);
+			sd->hstart = 140;
+			sd->vstart = 19;
+		} else {
+			i2c_w1(gspca_dev, 0x17, 0x13);
+			i2c_w1(gspca_dev, 0x18, 0x63);
+			i2c_w1(gspca_dev, 0x19, 0x01);
+			i2c_w1(gspca_dev, 0x1a, 0x79);
+			i2c_w1(gspca_dev, 0x12, 0x40);
+			sd->hstart = 60;
+			sd->vstart = 11;
+		}
+		break;
 	case SENSOR_OV9650:
 		if (mode & MODE_SXGA) {
 			i2c_w1(gspca_dev, 0x17, 0x1b);
@@ -2123,6 +2159,17 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
 			i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
 		}
 		break;
+	case SENSOR_MT9M111:
+		if (mode & MODE_SXGA) {
+			i2c_w2(gspca_dev, 0xf0, 0x0002);
+			i2c_w2(gspca_dev, 0xc8, 0x970b);
+			i2c_w2(gspca_dev, 0xf0, 0x0000);
+		} else {
+			i2c_w2(gspca_dev, 0xf0, 0x0002);
+			i2c_w2(gspca_dev, 0xc8, 0x8000);
+			i2c_w2(gspca_dev, 0xf0, 0x0000);
+		}
+		break;
 	}
 }
 
@@ -2211,15 +2258,10 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
 	kfree(sd->jpeg_hdr);
 }
 
-static void do_autoexposure(struct gspca_dev *gspca_dev)
+static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int avg_lum, new_exp;
-
-	if (!sd->auto_exposure)
-		return;
-
-	avg_lum = atomic_read(&sd->avg_lum);
+	s16 new_exp;
 
 	/*
 	 * some hardcoded values are present
@@ -2266,6 +2308,39 @@ static void do_autoexposure(struct gspca_dev *gspca_dev)
 	}
 }
 
+static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (avg_lum < MIN_AVG_LUM) {
+		if (sd->gain + 1 <= 28) {
+			sd->gain++;
+			set_gain(gspca_dev);
+		}
+	}
+	if (avg_lum > MAX_AVG_LUM) {
+		if (sd->gain - 1 >= 0) {
+			sd->gain--;
+			set_gain(gspca_dev);
+		}
+	}
+}
+
+static void sd_dqcallback(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	int avg_lum;
+
+	if (!sd->auto_exposure)
+		return;
+
+	avg_lum = atomic_read(&sd->avg_lum);
+	if (sd->sensor == SENSOR_SOI968)
+		do_autogain(gspca_dev, avg_lum);
+	else
+		do_autoexposure(gspca_dev, avg_lum);
+}
+
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			u8 *data,			/* isoc packet */
@@ -2333,7 +2408,7 @@ static const struct sd_desc sd_desc = {
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
-	.dq_callback = do_autoexposure,
+	.dq_callback = sd_dqcallback,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
 	.set_register = sd_dbg_s_register,
 	.get_register = sd_dbg_g_register,
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index d6332ab..33f4d0a 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -727,7 +727,7 @@ static const u8 ov7660_sensor_init[][8] = {
 	{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
 						/* Outformat = rawRGB */
 	{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
-	{0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
+	{0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
 						/* GAIN BLUE RED VREF */
 	{0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
 						/* COM 1 BAVE GEAVE AECHH */
@@ -783,7 +783,7 @@ static const u8 ov7660_sensor_init[][8] = {
 	{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
 	{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
 	{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
-	{0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
+	{0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
 /****** (some exchanges in the win trace) ******/
 	{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
 						/* bits[3..0]reserved */
@@ -1145,17 +1145,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
 		reg_w1(gspca_dev, 0x01, 0x42);
 		break;
 	case SENSOR_OV7660:
-		reg_w1(gspca_dev, 0x01, 0x61);
-		reg_w1(gspca_dev, 0x17, 0x20);
-		reg_w1(gspca_dev, 0x01, 0x60);
-		reg_w1(gspca_dev, 0x01, 0x40);
-		break;
 	case SENSOR_SP80708:
 		reg_w1(gspca_dev, 0x01, 0x63);
 		reg_w1(gspca_dev, 0x17, 0x20);
 		reg_w1(gspca_dev, 0x01, 0x62);
 		reg_w1(gspca_dev, 0x01, 0x42);
-		mdelay(100);
+		msleep(100);
 		reg_w1(gspca_dev, 0x02, 0x62);
 		break;
 /*	case SENSOR_HV7131R: */
@@ -1624,6 +1619,8 @@ static void setvflip(struct sd *sd)
 
 static void setinfrared(struct sd *sd)
 {
+	if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
+		return;
 /*fixme: different sequence for StarCam Clip and StarCam 370i */
 /* Clip */
 	i2c_w1(&sd->gspca_dev, 0x02,			/* gpio */
@@ -1637,16 +1634,19 @@ static void setfreq(struct gspca_dev *gspca_dev)
 	if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
 		return;
 	if (sd->sensor == SENSOR_OV7660) {
+		u8 com8;
+
+		com8 = 0xdf;		/* auto gain/wb/expo */
 		switch (sd->freq) {
 		case 0: /* Banding filter disabled */
-			i2c_w1(gspca_dev, 0x13, 0xdf);
+			i2c_w1(gspca_dev, 0x13, com8 | 0x20);
 			break;
 		case 1: /* 50 hz */
-			i2c_w1(gspca_dev, 0x13, 0xff);
+			i2c_w1(gspca_dev, 0x13, com8);
 			i2c_w1(gspca_dev, 0x3b, 0x0a);
 			break;
 		case 2: /* 60 hz */
-			i2c_w1(gspca_dev, 0x13, 0xff);
+			i2c_w1(gspca_dev, 0x13, com8);
 			i2c_w1(gspca_dev, 0x3b, 0x02);
 			break;
 		}
@@ -1796,12 +1796,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		reg_w1(gspca_dev, 0x99, 0x60);
 		break;
 	case SENSOR_OV7660:
-		reg_w1(gspca_dev, 0x9a, 0x05);
-		if (sd->bridge == BRIDGE_SN9C105)
-			reg_w1(gspca_dev, 0x99, 0xff);
-		else
-			reg_w1(gspca_dev, 0x99, 0x5b);
-		break;
 	case SENSOR_SP80708:
 		reg_w1(gspca_dev, 0x9a, 0x05);
 		reg_w1(gspca_dev, 0x99, 0x59);
@@ -2325,18 +2319,19 @@ static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
 /*	{USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
 	{USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
-/*	{USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */
 /*	{USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
 	{USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
 /*	{USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
 /*	{USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
 	{USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
-	{USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+	{USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
 	{USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
 #endif
 	{USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
-/*	{USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
+/*	{USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */
+/*	{USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */
 	{USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
 	{USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
 	{USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
@@ -2352,6 +2347,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
 	{USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
 #endif
+/*	{USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */
 	{USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
 	{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
@@ -2359,7 +2355,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
 #endif
 	{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
 	{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
-	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
+/*	{USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/
+	{USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index d48b27c..b74a342 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1923,7 +1923,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
-	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+	cam->nmodes = ARRAY_SIZE(vga_mode);
 	sd->subtype = id->driver_info;
 	sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value;
 	sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 3a0c893..a199298 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -286,7 +286,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
-	cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+	cam->nmodes = ARRAY_SIZE(vga_mode);
 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
 	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
 	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 2ed2669..9696c4c 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1304,19 +1304,70 @@ static int reg_read(struct gspca_dev *gspca_dev,
 	return gspca_dev->usb_buf[0];
 }
 
+/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
+static int ssi_w(struct gspca_dev *gspca_dev,
+		u16 reg, u16 val)
+{
+	struct usb_device *dev = gspca_dev->dev;
+	int ret, retry;
+
+	ret = reg_write(dev, 0x8802, reg >> 8);
+	if (ret < 0)
+		goto out;
+	ret = reg_write(dev, 0x8801, reg & 0x00ff);
+	if (ret < 0)
+		goto out;
+	if ((reg & 0xff00) == 0x1000) {		/* if 2 bytes */
+		ret = reg_write(dev, 0x8805, val & 0x00ff);
+		if (ret < 0)
+			goto out;
+		val >>= 8;
+	}
+	ret = reg_write(dev, 0x8800, val);
+	if (ret < 0)
+		goto out;
+
+	/* poll until not busy */
+	retry = 10;
+	for (;;) {
+		ret = reg_read(gspca_dev, 0x8803);
+		if (ret < 0)
+			break;
+		if (gspca_dev->usb_buf[0] == 0)
+			break;
+		if (--retry <= 0) {
+			PDEBUG(D_ERR, "ssi_w busy %02x",
+					gspca_dev->usb_buf[0]);
+			ret = -1;
+			break;
+		}
+		msleep(8);
+	}
+
+out:
+	return ret;
+}
+
 static int write_vector(struct gspca_dev *gspca_dev,
 			const u16 (*data)[2])
 {
 	struct usb_device *dev = gspca_dev->dev;
-	int ret;
+	int ret = 0;
 
 	while ((*data)[1] != 0) {
-		ret = reg_write(dev, (*data)[1], (*data)[0]);
+		if ((*data)[1] & 0x8000) {
+			if ((*data)[1] == 0xdd00)	/* delay */
+				msleep((*data)[0]);
+			else
+				ret = reg_write(dev, (*data)[1], (*data)[0]);
+		} else {
+			ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
+		}
 		if (ret < 0)
-			return ret;
+			break;
 		data++;
 	}
-	return 0;
+	return ret;
 }
 
 /* this function is called at probe time */
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 0da8e0d..65489d6 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -50,7 +50,6 @@ int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
 			      0x04, 0x40, address, 0, buf, len,
 			      STV06XX_URB_MSG_TIMEOUT);
 
-
 	PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
 	       i2c_data, address, err);
 
@@ -69,7 +68,7 @@ int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
 
 	*i2c_data = buf[0];
 
-	PDEBUG(D_CONF, "Read 0x%x from address 0x%x, status %d",
+	PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d",
 	       *i2c_data, address, err);
 
 	return (err < 0) ? err : 0;
@@ -111,14 +110,14 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
 	struct usb_device *udev = sd->gspca_dev.dev;
 	__u8 *buf = sd->gspca_dev.usb_buf;
 
-	PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len);
+	PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
 	for (i = 0; i < len;) {
 		/* Build the command buffer */
 		memset(buf, 0, I2C_BUFFER_LENGTH);
 		for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
 			buf[j] = data[2*i];
 			buf[0x10 + j] = data[2*i+1];
-			PDEBUG(D_USBO, "I2C: Writing 0x%02x to reg 0x%02x",
+			PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x",
 			data[2*i+1], data[2*i]);
 		}
 		buf[0x20] = sd->sensor->i2c_addr;
@@ -128,10 +127,10 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
 				      0x04, 0x40, 0x0400, 0, buf,
 				      I2C_BUFFER_LENGTH,
 				      STV06XX_URB_MSG_TIMEOUT);
-				      if (err < 0)
-					return err;
-       }
-       return stv06xx_write_sensor_finish(sd);
+		if (err < 0)
+			return err;
+	}
+	return stv06xx_write_sensor_finish(sd);
 }
 
 int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
@@ -140,7 +139,7 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
 	struct usb_device *udev = sd->gspca_dev.dev;
 	__u8 *buf = sd->gspca_dev.usb_buf;
 
-	PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len);
+	PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
 
 	for (i = 0; i < len;) {
 		/* Build the command buffer */
@@ -149,7 +148,7 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
 			buf[j] = data[2*i];
 			buf[0x10 + j * 2] = data[2*i+1];
 			buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
-			PDEBUG(D_USBO, "I2C: Writing 0x%04x to reg 0x%02x",
+			PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x",
 				data[2*i+1], data[2*i]);
 		}
 		buf[0x20] = sd->sensor->i2c_addr;
@@ -189,7 +188,7 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
 			      0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH,
 			      STV06XX_URB_MSG_TIMEOUT);
 	if (err < 0) {
-		PDEBUG(D_ERR, "I2C Read: error writing address: %d", err);
+		PDEBUG(D_ERR, "I2C: Read error writing address: %d", err);
 		return err;
 	}
 
@@ -201,7 +200,7 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
 	else
 		*value = buf[0];
 
-	PDEBUG(D_USBO, "I2C: Read 0x%x from address 0x%x, status: %d",
+	PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d",
 	       *value, address, err);
 
 	return (err < 0) ? err : 0;
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index e5024c8..706e08d 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -37,7 +37,7 @@ static const struct ctrl hdcs1x00_ctrl[] = {
 			.type		= V4L2_CTRL_TYPE_INTEGER,
 			.name		= "exposure",
 			.minimum	= 0x00,
-			.maximum	= 0xffff,
+			.maximum	= 0xff,
 			.step		= 0x1,
 			.default_value 	= HDCS_DEFAULT_EXPOSURE,
 			.flags         	= V4L2_CTRL_FLAG_SLIDER
@@ -74,7 +74,35 @@ static struct v4l2_pix_format hdcs1x00_mode[] = {
 	}
 };
 
-static const struct ctrl hdcs1020_ctrl[] = {};
+static const struct ctrl hdcs1020_ctrl[] = {
+	{
+		{
+			.id		= V4L2_CID_EXPOSURE,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "exposure",
+			.minimum	= 0x00,
+			.maximum	= 0xffff,
+			.step		= 0x1,
+			.default_value 	= HDCS_DEFAULT_EXPOSURE,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = hdcs_set_exposure,
+		.get = hdcs_get_exposure
+	}, {
+		{
+			.id		= V4L2_CID_GAIN,
+			.type		= V4L2_CTRL_TYPE_INTEGER,
+			.name		= "gain",
+			.minimum	= 0x00,
+			.maximum	= 0xff,
+			.step		= 0x1,
+			.default_value 	= HDCS_DEFAULT_GAIN,
+			.flags         	= V4L2_CTRL_FLAG_SLIDER
+		},
+		.set = hdcs_set_gain,
+		.get = hdcs_get_gain
+	}
+};
 
 static struct v4l2_pix_format hdcs1020_mode[] = {
 	{
@@ -120,6 +148,7 @@ struct hdcs {
 	} exp;
 
 	int psmp;
+	u8 exp_cache, gain_cache;
 };
 
 static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
@@ -205,34 +234,8 @@ static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct hdcs *hdcs = sd->sensor_priv;
 
-	/* Column time period */
-	int ct;
-	/* Column processing period */
-	int cp;
-	/* Row processing period */
-	int rp;
-	int cycles;
-	int err;
-	int rowexp;
-	u16 data[2];
-
-	err = stv06xx_read_sensor(sd, HDCS_ROWEXPL, &data[0]);
-	if (err < 0)
-		return err;
-
-	err = stv06xx_read_sensor(sd, HDCS_ROWEXPH, &data[1]);
-	if (err < 0)
-		return err;
-
-	rowexp = (data[1] << 8) | data[0];
-
-	ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
-	cp = hdcs->exp.cto + (hdcs->w * ct / 2);
-	rp = hdcs->exp.rs + cp;
+	*val = hdcs->exp_cache;
 
-	cycles = rp * rowexp;
-	*val = cycles / HDCS_CLK_FREQ_MHZ;
-	PDEBUG(D_V4L2, "Read exposure %d", *val);
 	return 0;
 }
 
@@ -252,9 +255,12 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 	   within the column processing period */
 	int mnct;
 	int cycles, err;
-	u8 exp[4];
+	u8 exp[14];
 
-	cycles = val * HDCS_CLK_FREQ_MHZ;
+	val &= 0xff;
+	hdcs->exp_cache = val;
+
+	cycles = val * HDCS_CLK_FREQ_MHZ * 257;
 
 	ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
 	cp = hdcs->exp.cto + (hdcs->w * ct / 2);
@@ -288,73 +294,79 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
 		srowexp = max_srowexp;
 
 	if (IS_1020(sd)) {
-		exp[0] = rowexp & 0xff;
-		exp[1] = rowexp >> 8;
-		exp[2] = (srowexp >> 2) & 0xff;
-		/* this clears exposure error flag */
-		exp[3] = 0x1;
-		err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4);
+		exp[0] = HDCS20_CONTROL;
+		exp[1] = 0x00;		/* Stop streaming */
+		exp[2] = HDCS_ROWEXPL;
+		exp[3] = rowexp & 0xff;
+		exp[4] = HDCS_ROWEXPH;
+		exp[5] = rowexp >> 8;
+		exp[6] = HDCS20_SROWEXP;
+		exp[7] = (srowexp >> 2) & 0xff;
+		exp[8] = HDCS20_ERROR;
+		exp[9] = 0x10;		/* Clear exposure error flag*/
+		exp[10] = HDCS20_CONTROL;
+		exp[11] = 0x04;		/* Restart streaming */
+		err = stv06xx_write_sensor_bytes(sd, exp, 6);
 	} else {
-		exp[0] = rowexp & 0xff;
-		exp[1] = rowexp >> 8;
-		exp[2] = srowexp & 0xff;
-		exp[3] = srowexp >> 8;
-		err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4);
+		exp[0] = HDCS00_CONTROL;
+		exp[1] = 0x00;         /* Stop streaming */
+		exp[2] = HDCS_ROWEXPL;
+		exp[3] = rowexp & 0xff;
+		exp[4] = HDCS_ROWEXPH;
+		exp[5] = rowexp >> 8;
+		exp[6] = HDCS00_SROWEXPL;
+		exp[7] = srowexp & 0xff;
+		exp[8] = HDCS00_SROWEXPH;
+		exp[9] = srowexp >> 8;
+		exp[10] = HDCS_STATUS;
+		exp[11] = 0x10;         /* Clear exposure error flag*/
+		exp[12] = HDCS00_CONTROL;
+		exp[13] = 0x04;         /* Restart streaming */
+		err = stv06xx_write_sensor_bytes(sd, exp, 7);
 		if (err < 0)
 			return err;
-
-		/* clear exposure error flag */
-		err = stv06xx_write_sensor(sd,
-		     HDCS_STATUS, BIT(4));
 	}
 	PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d",
 	       val, rowexp, srowexp);
 	return err;
 }
 
-static int hdcs_set_gains(struct sd *sd, u8 r, u8 g, u8 b)
+static int hdcs_set_gains(struct sd *sd, u8 g)
 {
+	struct hdcs *hdcs = sd->sensor_priv;
+	int err;
 	u8 gains[4];
 
+	hdcs->gain_cache = g;
+
 	/* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
-	if (r > 127)
-		r = 0x80 | (r / 2);
 	if (g > 127)
 		g = 0x80 | (g / 2);
-	if (b > 127)
-		b = 0x80 | (b / 2);
 
 	gains[0] = g;
-	gains[1] = r;
-	gains[2] = b;
+	gains[1] = g;
+	gains[2] = g;
 	gains[3] = g;
 
-	return hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
+	err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
+		return err;
 }
 
 static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int err;
-	u16 data;
-
-	err = stv06xx_read_sensor(sd, HDCS_ERECPGA, &data);
+	struct hdcs *hdcs = sd->sensor_priv;
 
-	/* Bit 7 doubles the gain */
-	if (data & 0x80)
-		*val = (data & 0x7f) * 2;
-	else
-		*val = data;
+	*val = hdcs->gain_cache;
 
-	PDEBUG(D_V4L2, "Read gain %d", *val);
-	return err;
+	return 0;
 }
 
 static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	PDEBUG(D_V4L2, "Writing gain %d", val);
 	return hdcs_set_gains((struct sd *) gspca_dev,
-			       val & 0xff, val & 0xff, val & 0xff);
+			       val & 0xff);
 }
 
 static int hdcs_set_size(struct sd *sd,
@@ -572,16 +584,15 @@ static int hdcs_init(struct sd *sd)
 	if (err < 0)
 		return err;
 
-	err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN, HDCS_DEFAULT_GAIN,
-			     HDCS_DEFAULT_GAIN);
+	err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN);
 	if (err < 0)
 		return err;
 
-	err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE);
+	err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
 	if (err < 0)
 		return err;
 
-	err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
+	err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE);
 	return err;
 }
 
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 412f06c..37b31c9 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -124,7 +124,7 @@
 #define HDCS_RUN_ENABLE		(1 << 2)
 #define HDCS_SLEEP_MODE		(1 << 1)
 
-#define HDCS_DEFAULT_EXPOSURE	5000
+#define HDCS_DEFAULT_EXPOSURE	48
 #define HDCS_DEFAULT_GAIN	128
 
 static int hdcs_probe_1x00(struct sd *sd);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
index 87cb5b9..c11f06e 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -166,7 +166,7 @@ static int st6422_init(struct sd *sd)
 /* 10 compressed? */
 
 		{ 0x1439, 0x00 },
-/* antiflimmer??  0xa2 ger perfekt bild mot monitor */
+/* anti-noise?  0xa2 gives a perfect image */
 
 		{ 0x143b, 0x05 },
 		{ 0x143c, 0x00 },	/* 0x00-0x01 - ??? */
@@ -197,15 +197,14 @@ static int st6422_init(struct sd *sd)
 		{ 0x1500, 0x50 },	/* 0x00 - 0xFF  0x80 == compr ? */
 
 		{ 0x1501, 0xaf },
-/* high val-> ljus area blir morkare. */
-/* low val -> ljus area blir ljusare. */
+/* high val-> light area gets darker */
+/* low val -> light area gets lighter */
 		{ 0x1502, 0xc2 },
-/* high val-> ljus area blir morkare. */
-/* low val -> ljus area blir ljusare. */
+/* high val-> light area gets darker */
+/* low val -> light area gets lighter */
 		{ 0x1503, 0x45 },
-/* high val-> ljus area blir morkare. */
-/* low val -> ljus area blir ljusare. */
-
+/* high val-> light area gets darker */
+/* low val -> light area gets lighter */
 		{ 0x1505, 0x02 },
 /* 2  : 324x248  80352 bytes */
 /* 7  : 248x162  40176 bytes */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 5127bbf..aa8f995 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -32,26 +32,27 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	unsigned char brightness;
-	unsigned char contrast;
-	unsigned char colors;
-	unsigned char autogain;
+	s8 brightness;
+	u8 contrast;
+	u8 colors;
+	u8 autogain;
 	u8 quality;
 #define QUALITY_MIN 70
 #define QUALITY_MAX 95
 #define QUALITY_DEF 85
 
-	char bridge;
+	u8 bridge;
 #define BRIDGE_SPCA504 0
 #define BRIDGE_SPCA504B 1
 #define BRIDGE_SPCA504C 2
 #define BRIDGE_SPCA533 3
 #define BRIDGE_SPCA536 4
-	char subtype;
+	u8 subtype;
 #define AiptekMiniPenCam13 1
 #define LogitechClickSmart420 2
 #define LogitechClickSmart820 3
 #define MegapixV4 4
+#define MegaImageVI 5
 
 	u8 *jpeg_hdr;
 };
@@ -67,21 +68,20 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
 	{
 	    {
 		.id      = V4L2_CID_BRIGHTNESS,
 		.type    = V4L2_CTRL_TYPE_INTEGER,
 		.name    = "Brightness",
-		.minimum = 0,
-		.maximum = 0xff,
+		.minimum = -128,
+		.maximum = 127,
 		.step    = 1,
-		.default_value = 0,
+#define BRIGHTNESS_DEF 0
+		.default_value = BRIGHTNESS_DEF,
 	    },
 	    .set = sd_setbrightness,
 	    .get = sd_getbrightness,
 	},
-#define SD_CONTRAST 1
 	{
 	    {
 		.id      = V4L2_CID_CONTRAST,
@@ -90,12 +90,12 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 0xff,
 		.step    = 1,
-		.default_value = 0x20,
+#define CONTRAST_DEF 0x20
+		.default_value = CONTRAST_DEF,
 	    },
 	    .set = sd_setcontrast,
 	    .get = sd_getcontrast,
 	},
-#define SD_COLOR 2
 	{
 	    {
 		.id      = V4L2_CID_SATURATION,
@@ -104,12 +104,12 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 0xff,
 		.step    = 1,
-		.default_value = 0x1a,
+#define COLOR_DEF 0x1a
+		.default_value = COLOR_DEF,
 	    },
 	    .set = sd_setcolors,
 	    .get = sd_getcolors,
 	},
-#define SD_AUTOGAIN 3
 	{
 	    {
 		.id      = V4L2_CID_AUTOGAIN,
@@ -118,7 +118,8 @@ static struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 1,
 		.step    = 1,
-		.default_value = 1,
+#define AUTOGAIN_DEF 1
+		.default_value = AUTOGAIN_DEF,
 	    },
 	    .set = sd_setautogain,
 	    .get = sd_getautogain,
@@ -180,14 +181,20 @@ static const struct v4l2_pix_format vga_mode2[] = {
 #define SPCA504_PCCAM600_OFFSET_MODE	 5
 #define SPCA504_PCCAM600_OFFSET_DATA	 14
  /* Frame packet header offsets for the spca533 */
-#define SPCA533_OFFSET_DATA      16
+#define SPCA533_OFFSET_DATA	16
 #define SPCA533_OFFSET_FRAMSEQ	15
 /* Frame packet header offsets for the spca536 */
-#define SPCA536_OFFSET_DATA      4
-#define SPCA536_OFFSET_FRAMSEQ	 1
+#define SPCA536_OFFSET_DATA	4
+#define SPCA536_OFFSET_FRAMSEQ	1
+
+struct cmd {
+	u8 req;
+	u16 val;
+	u16 idx;
+};
 
 /* Initialisation data for the Creative PC-CAM 600 */
-static const __u16 spca504_pccam600_init_data[][3] = {
+static const struct cmd spca504_pccam600_init_data[] = {
 /*	{0xa0, 0x0000, 0x0503},  * capture mode */
 	{0x00, 0x0000, 0x2000},
 	{0x00, 0x0013, 0x2301},
@@ -211,22 +218,20 @@ static const __u16 spca504_pccam600_init_data[][3] = {
 	{0x00, 0x0003, 0x2000},
 	{0x00, 0x0013, 0x2301},
 	{0x00, 0x0003, 0x2000},
-	{}
 };
 
 /* Creative PC-CAM 600 specific open data, sent before using the
  * generic initialisation data from spca504_open_data.
  */
-static const __u16 spca504_pccam600_open_data[][3] = {
+static const struct cmd spca504_pccam600_open_data[] = {
 	{0x00, 0x0001, 0x2501},
 	{0x20, 0x0500, 0x0001},	/* snapshot mode */
 	{0x00, 0x0003, 0x2880},
 	{0x00, 0x0001, 0x2881},
-	{}
 };
 
 /* Initialisation data for the logitech clicksmart 420 */
-static const __u16 spca504A_clicksmart420_init_data[][3] = {
+static const struct cmd spca504A_clicksmart420_init_data[] = {
 /*	{0xa0, 0x0000, 0x0503},  * capture mode */
 	{0x00, 0x0000, 0x2000},
 	{0x00, 0x0013, 0x2301},
@@ -243,7 +248,7 @@ static const __u16 spca504A_clicksmart420_init_data[][3] = {
 	{0xb0, 0x0001, 0x0000},
 
 
-	{0x0a1, 0x0080, 0x0001},
+	{0xa1, 0x0080, 0x0001},
 	{0x30, 0x0049, 0x0000},
 	{0x30, 0x0060, 0x0005},
 	{0x0c, 0x0004, 0x0000},
@@ -253,11 +258,10 @@ static const __u16 spca504A_clicksmart420_init_data[][3] = {
 	{0x00, 0x0003, 0x2000},
 	{0x00, 0x0000, 0x2000},
 
-	{}
 };
 
 /* clicksmart 420 open data ? */
-static const __u16 spca504A_clicksmart420_open_data[][3] = {
+static const struct cmd spca504A_clicksmart420_open_data[] = {
 	{0x00, 0x0001, 0x2501},
 	{0x20, 0x0502, 0x0000},
 	{0x06, 0x0000, 0x0000},
@@ -401,10 +405,9 @@ static const __u16 spca504A_clicksmart420_open_data[][3] = {
 	{0x00, 0x0028, 0x287f},
 
 	{0xa0, 0x0000, 0x0503},
-	{}
 };
 
-static const __u8 qtable_creative_pccam[2][64] = {
+static const u8 qtable_creative_pccam[2][64] = {
 	{				/* Q-table Y-components */
 	 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
 	 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
@@ -429,7 +432,7 @@ static const __u8 qtable_creative_pccam[2][64] = {
  *		except for one byte. Possibly a typo?
  *		NWG: 18/05/2003.
  */
-static const __u8 qtable_spca504_default[2][64] = {
+static const u8 qtable_spca504_default[2][64] = {
 	{				/* Q-table Y-components */
 	 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
 	 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
@@ -453,9 +456,9 @@ static const __u8 qtable_spca504_default[2][64] = {
 
 /* read <len> bytes to gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
-		  __u16 req,
-		  __u16 index,
-		  __u16 len)
+		  u8 req,
+		  u16 index,
+		  u16 len)
 {
 #ifdef GSPCA_DEBUG
 	if (len > USB_BUF_SZ) {
@@ -473,31 +476,26 @@ static void reg_r(struct gspca_dev *gspca_dev,
 			500);
 }
 
-/* write <len> bytes from gspca_dev->usb_buf */
-static void reg_w(struct gspca_dev *gspca_dev,
-		   __u16 req,
-		   __u16 value,
-		   __u16 index,
-		   __u16 len)
+/* write one byte */
+static void reg_w_1(struct gspca_dev *gspca_dev,
+		   u8 req,
+		   u16 value,
+		   u16 index,
+		   u16 byte)
 {
-#ifdef GSPCA_DEBUG
-	if (len > USB_BUF_SZ) {
-		err("reg_w: buffer overflow");
-		return;
-	}
-#endif
+	gspca_dev->usb_buf[0] = byte;
 	usb_control_msg(gspca_dev->dev,
 			usb_sndctrlpipe(gspca_dev->dev, 0),
 			req,
 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 			value, index,
-			len ? gspca_dev->usb_buf : NULL, len,
+			gspca_dev->usb_buf, 1,
 			500);
 }
 
 /* write req / index / value */
 static int reg_w_riv(struct usb_device *dev,
-		     __u16 req, __u16 index, __u16 value)
+		     u8 req, u16 index, u16 value)
 {
 	int ret;
 
@@ -515,7 +513,7 @@ static int reg_w_riv(struct usb_device *dev,
 
 /* read 1 byte */
 static int reg_r_1(struct gspca_dev *gspca_dev,
-			__u16 value)	/* wValue */
+			u16 value)	/* wValue */
 {
 	int ret;
 
@@ -536,9 +534,9 @@ static int reg_r_1(struct gspca_dev *gspca_dev,
 
 /* read 1 or 2 bytes - returns < 0 if error */
 static int reg_r_12(struct gspca_dev *gspca_dev,
-			__u16 req,	/* bRequest */
-			__u16 index,	/* wIndex */
-			__u16 length)	/* wLength (1 or 2 only) */
+			u8 req,		/* bRequest */
+			u16 index,	/* wIndex */
+			u16 length)	/* wLength (1 or 2 only) */
 {
 	int ret;
 
@@ -559,43 +557,40 @@ static int reg_r_12(struct gspca_dev *gspca_dev,
 }
 
 static int write_vector(struct gspca_dev *gspca_dev,
-			const __u16 data[][3])
+			const struct cmd *data, int ncmds)
 {
 	struct usb_device *dev = gspca_dev->dev;
-	int ret, i = 0;
+	int ret;
 
-	while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
-		ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);
+	while (--ncmds >= 0) {
+		ret = reg_w_riv(dev, data->req, data->idx, data->val);
 		if (ret < 0) {
 			PDEBUG(D_ERR,
-				"Register write failed for 0x%x,0x%x,0x%x",
-				data[i][0], data[i][1], data[i][2]);
+			   "Register write failed for 0x%02x, 0x%04x, 0x%04x",
+				data->req, data->val, data->idx);
 			return ret;
 		}
-		i++;
+		data++;
 	}
 	return 0;
 }
 
 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
-				unsigned int request,
-				unsigned int ybase,
-				unsigned int cbase,
-				const __u8 qtable[2][64])
+				const u8 qtable[2][64])
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int i, err;
 
 	/* loop over y components */
 	for (i = 0; i < 64; i++) {
-		err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);
+		err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]);
 		if (err < 0)
 			return err;
 	}
 
 	/* loop over c components */
 	for (i = 0; i < 64; i++) {
-		err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);
+		err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]);
 		if (err < 0)
 			return err;
 	}
@@ -603,34 +598,34 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
 }
 
 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
-			     __u16 req, __u16 idx, __u16 val)
+			     u8 req, u16 idx, u16 val)
 {
 	struct usb_device *dev = gspca_dev->dev;
-	__u8 notdone;
+	int notdone;
 
 	reg_w_riv(dev, req, idx, val);
 	notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
 	reg_w_riv(dev, req, idx, val);
 
-	PDEBUG(D_FRAM, "before wait 0x%x", notdone);
+	PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
 
 	msleep(200);
 	notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
-	PDEBUG(D_FRAM, "after wait 0x%x", notdone);
+	PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
 }
 
 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
-			__u16 req,
-			__u16 idx, __u16 val, __u8 stat, __u8 count)
+			u8 req,
+			u16 idx, u16 val, u8 stat, u8 count)
 {
 	struct usb_device *dev = gspca_dev->dev;
-	__u8 status;
-	__u8 endcode;
+	int status;
+	u8 endcode;
 
 	reg_w_riv(dev, req, idx, val);
 	status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
 	endcode = stat;
-	PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);
+	PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat);
 	if (!count)
 		return;
 	count = 200;
@@ -640,7 +635,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
 /*		reg_w_riv(dev, req, idx, val); */
 		status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
 		if (status == endcode) {
-			PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",
+			PDEBUG(D_FRAM, "status 0x%04x after wait %d",
 				status, 200 - count);
 				break;
 		}
@@ -667,8 +662,7 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
 	while (--count > 0) {
 		reg_r(gspca_dev, 0x21, 1, 1);
 		if (gspca_dev->usb_buf[0] != 0) {
-			gspca_dev->usb_buf[0] = 0;
-			reg_w(gspca_dev, 0x21, 0, 1, 1);
+			reg_w_1(gspca_dev, 0x21, 0, 1, 0);
 			reg_r(gspca_dev, 0x21, 1, 1);
 			spca504B_PollingDataReady(gspca_dev);
 			break;
@@ -679,7 +673,7 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
 
 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
 {
-	__u8 *data;
+	u8 *data;
 
 	data = gspca_dev->usb_buf;
 	reg_r(gspca_dev, 0x20, 0, 5);
@@ -693,41 +687,34 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	__u8 Size;
-	__u8 Type;
+	u8 Size;
 	int rc;
 
-	Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
-	Type = 0;
+	Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	switch (sd->bridge) {
 	case BRIDGE_SPCA533:
-		reg_w(gspca_dev, 0x31, 0, 0, 0);
+		reg_w_riv(dev, 0x31, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		rc = spca504B_PollingDataReady(gspca_dev);
 		spca50x_GetFirmware(gspca_dev);
-		gspca_dev->usb_buf[0] = 2;			/* type */
-		reg_w(gspca_dev, 0x24, 0, 8, 1);
+		reg_w_1(gspca_dev, 0x24, 0, 8, 2);		/* type */
 		reg_r(gspca_dev, 0x24, 8, 1);
 
-		gspca_dev->usb_buf[0] = Size;
-		reg_w(gspca_dev, 0x25, 0, 4, 1);
+		reg_w_1(gspca_dev, 0x25, 0, 4, Size);
 		reg_r(gspca_dev, 0x25, 4, 1);			/* size */
 		rc = spca504B_PollingDataReady(gspca_dev);
 
 		/* Init the cam width height with some values get on init ? */
-		reg_w(gspca_dev, 0x31, 0, 4, 0);
+		reg_w_riv(dev, 0x31, 0, 0x04);
 		spca504B_WaitCmdStatus(gspca_dev);
 		rc = spca504B_PollingDataReady(gspca_dev);
 		break;
 	default:
 /* case BRIDGE_SPCA504B: */
 /* case BRIDGE_SPCA536: */
-		gspca_dev->usb_buf[0] = Size;
-		reg_w(gspca_dev, 0x25, 0, 4, 1);
+		reg_w_1(gspca_dev, 0x25, 0, 4, Size);
 		reg_r(gspca_dev, 0x25, 4, 1);			/* size */
-		Type = 6;
-		gspca_dev->usb_buf[0] = Type;
-		reg_w(gspca_dev, 0x27, 0, 0, 1);
+		reg_w_1(gspca_dev, 0x27, 0, 0, 6);
 		reg_r(gspca_dev, 0x27, 0, 1);			/* type */
 		rc = spca504B_PollingDataReady(gspca_dev);
 		break;
@@ -767,17 +754,51 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
 
 static void spca504B_setQtable(struct gspca_dev *gspca_dev)
 {
-	gspca_dev->usb_buf[0] = 3;
-	reg_w(gspca_dev, 0x26, 0, 0, 1);
+	reg_w_1(gspca_dev, 0x26, 0, 0, 3);
 	reg_r(gspca_dev, 0x26, 0, 1);
 	spca504B_PollingDataReady(gspca_dev);
 }
 
-static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct usb_device *dev = gspca_dev->dev;
+	u16 reg;
+
+	reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
+	reg_w_riv(dev, 0x00, reg, sd->brightness);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct usb_device *dev = gspca_dev->dev;
+	u16 reg;
+
+	reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
+	reg_w_riv(dev, 0x00, reg, sd->contrast);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct usb_device *dev = gspca_dev->dev;
+	u16 reg;
+
+	reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
+	reg_w_riv(dev, 0x00, reg, sd->colors);
+}
+
+static void init_ctl_reg(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	struct usb_device *dev = gspca_dev->dev;
 	int pollreg = 1;
 
+	setbrightness(gspca_dev);
+	setcontrast(gspca_dev);
+	setcolors(gspca_dev);
+
 	switch (sd->bridge) {
 	case BRIDGE_SPCA504:
 	case BRIDGE_SPCA504C:
@@ -786,20 +807,14 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
 	default:
 /*	case BRIDGE_SPCA533: */
 /*	case BRIDGE_SPCA504B: */
-		reg_w(gspca_dev, 0, 0, 0x21a7, 0);	/* brightness */
-		reg_w(gspca_dev, 0, 0x20, 0x21a8, 0);	/* contrast */
-		reg_w(gspca_dev, 0, 0, 0x21ad, 0);	/* hue */
-		reg_w(gspca_dev, 0, 1, 0x21ac, 0);	/* sat/hue */
-		reg_w(gspca_dev, 0, 0x20, 0x21ae, 0);	/* saturation */
-		reg_w(gspca_dev, 0, 0, 0x21a3, 0);	/* gamma */
+		reg_w_riv(dev, 0, 0x00, 0x21ad);	/* hue */
+		reg_w_riv(dev, 0, 0x01, 0x21ac);	/* sat/hue */
+		reg_w_riv(dev, 0, 0x00, 0x21a3);	/* gamma */
 		break;
 	case BRIDGE_SPCA536:
-		reg_w(gspca_dev, 0, 0, 0x20f0, 0);
-		reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);
-		reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);
-		reg_w(gspca_dev, 0, 1, 0x20f4, 0);
-		reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
-		reg_w(gspca_dev, 0, 0, 0x2089, 0);
+		reg_w_riv(dev, 0, 0x40, 0x20f5);
+		reg_w_riv(dev, 0, 0x01, 0x20f4);
+		reg_w_riv(dev, 0, 0x00, 0x2089);
 		break;
 	}
 	if (pollreg)
@@ -840,20 +855,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
 /*	case BRIDGE_SPCA504: */
 /*	case BRIDGE_SPCA536: */
 		cam->cam_mode = vga_mode;
-		cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+		cam->nmodes =ARRAY_SIZE(vga_mode);
 		break;
 	case BRIDGE_SPCA533:
 		cam->cam_mode = custom_mode;
-		cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];
+		if (sd->subtype == MegaImageVI)		/* 320x240 only */
+			cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
+		else
+			cam->nmodes = ARRAY_SIZE(custom_mode);
 		break;
 	case BRIDGE_SPCA504C:
 		cam->cam_mode = vga_mode2;
-		cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
+		cam->nmodes = ARRAY_SIZE(vga_mode2);
 		break;
 	}
-	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
-	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
-	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+	sd->brightness = BRIGHTNESS_DEF;
+	sd->contrast = CONTRAST_DEF;
+	sd->colors = COLOR_DEF;
+	sd->autogain = AUTOGAIN_DEF;
 	sd->quality = QUALITY_DEF;
 	return 0;
 }
@@ -863,32 +882,29 @@ static int sd_init(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	int rc;
-	__u8 i;
-	__u8 info[6];
-	int err_code;
+	int i, err_code;
+	u8 info[6];
 
 	switch (sd->bridge) {
 	case BRIDGE_SPCA504B:
-		reg_w(gspca_dev, 0x1d, 0, 0, 0);
-		reg_w(gspca_dev, 0, 1, 0x2306, 0);
-		reg_w(gspca_dev, 0, 0, 0x0d04, 0);
-		reg_w(gspca_dev, 0, 0, 0x2000, 0);
-		reg_w(gspca_dev, 0, 0x13, 0x2301, 0);
-		reg_w(gspca_dev, 0, 0, 0x2306, 0);
+		reg_w_riv(dev, 0x1d, 0x00, 0);
+		reg_w_riv(dev, 0, 0x01, 0x2306);
+		reg_w_riv(dev, 0, 0x00, 0x0d04);
+		reg_w_riv(dev, 0, 0x00, 0x2000);
+		reg_w_riv(dev, 0, 0x13, 0x2301);
+		reg_w_riv(dev, 0, 0x00, 0x2306);
 		/* fall thru */
 	case BRIDGE_SPCA533:
-		rc = spca504B_PollingDataReady(gspca_dev);
+		spca504B_PollingDataReady(gspca_dev);
 		spca50x_GetFirmware(gspca_dev);
 		break;
 	case BRIDGE_SPCA536:
 		spca50x_GetFirmware(gspca_dev);
 		reg_r(gspca_dev, 0x00, 0x5002, 1);
-		gspca_dev->usb_buf[0] = 0;
-		reg_w(gspca_dev, 0x24, 0, 0, 1);
+		reg_w_1(gspca_dev, 0x24, 0, 0, 0);
 		reg_r(gspca_dev, 0x24, 0, 1);
-		rc = spca504B_PollingDataReady(gspca_dev);
-		reg_w(gspca_dev, 0x34, 0, 0, 0);
+		spca504B_PollingDataReady(gspca_dev);
+		reg_w_riv(dev, 0x34, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		break;
 	case BRIDGE_SPCA504C:	/* pccam600 */
@@ -898,12 +914,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		spca504_wait_status(gspca_dev);
 		if (sd->subtype == LogitechClickSmart420)
 			write_vector(gspca_dev,
-					spca504A_clicksmart420_open_data);
+				spca504A_clicksmart420_open_data,
+				ARRAY_SIZE(spca504A_clicksmart420_open_data));
 		else
-			write_vector(gspca_dev, spca504_pccam600_open_data);
+			write_vector(gspca_dev, spca504_pccam600_open_data,
+				ARRAY_SIZE(spca504_pccam600_open_data));
 		err_code = spca50x_setup_qtable(gspca_dev,
-						0x00, 0x2800,
-						0x2840, qtable_creative_pccam);
+						qtable_creative_pccam);
 		if (err_code < 0) {
 			PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
 			return err_code;
@@ -941,8 +958,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 							6, 0, 0x86, 1); */
 /*			spca504A_acknowledged_command (gspca_dev, 0x24,
 							0, 0, 0x9D, 1); */
-			reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
-			reg_w_riv(dev, 0x0, 0x2310, 0x05);
+			reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
+			reg_w_riv(dev, 0x00, 0x2310, 0x05);
 			spca504A_acknowledged_command(gspca_dev, 0x01,
 							0x0f, 0, 0xff, 0);
 		}
@@ -950,8 +967,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		reg_w_riv(dev, 0, 0x2000, 0);
 		reg_w_riv(dev, 0, 0x2883, 1);
 		err_code = spca50x_setup_qtable(gspca_dev,
-						0x00, 0x2800,
-						0x2840,
 						qtable_spca504_default);
 		if (err_code < 0) {
 			PDEBUG(D_ERR, "spca50x_setup_qtable failed");
@@ -966,10 +981,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
-	int rc;
 	int enable;
-	__u8 i;
-	__u8 info[6];
+	int i;
+	u8 info[6];
 
 	/* create the JPEG header */
 	sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
@@ -987,16 +1001,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
 /*	case BRIDGE_SPCA504B: */
 /*	case BRIDGE_SPCA533: */
 /*	case BRIDGE_SPCA536: */
-		if (sd->subtype == MegapixV4 ||
-		    sd->subtype == LogitechClickSmart820) {
-			reg_w(gspca_dev, 0xf0, 0, 0, 0);
+		switch (sd->subtype) {
+		case MegapixV4:
+		case LogitechClickSmart820:
+		case MegaImageVI:
+			reg_w_riv(dev, 0xf0, 0, 0);
 			spca504B_WaitCmdStatus(gspca_dev);
 			reg_r(gspca_dev, 0xf0, 4, 0);
 			spca504B_WaitCmdStatus(gspca_dev);
-		} else {
-			reg_w(gspca_dev, 0x31, 0, 4, 0);
+			break;
+		default:
+			reg_w_riv(dev, 0x31, 0, 0x04);
 			spca504B_WaitCmdStatus(gspca_dev);
-			rc = spca504B_PollingDataReady(gspca_dev);
+			spca504B_PollingDataReady(gspca_dev);
+			break;
 		}
 		break;
 	case BRIDGE_SPCA504:
@@ -1030,15 +1048,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
 			spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
 		}
 		spca504B_SetSizeType(gspca_dev);
-		reg_w_riv(dev, 0x0, 0x270c, 0x05);	/* L92 sno1t.txt */
-		reg_w_riv(dev, 0x0, 0x2310, 0x05);
+		reg_w_riv(dev, 0x00, 0x270c, 0x05);	/* L92 sno1t.txt */
+		reg_w_riv(dev, 0x00, 0x2310, 0x05);
 		break;
 	case BRIDGE_SPCA504C:
 		if (sd->subtype == LogitechClickSmart420) {
 			write_vector(gspca_dev,
-					spca504A_clicksmart420_init_data);
+				spca504A_clicksmart420_init_data,
+				ARRAY_SIZE(spca504A_clicksmart420_init_data));
 		} else {
-			write_vector(gspca_dev, spca504_pccam600_init_data);
+			write_vector(gspca_dev, spca504_pccam600_init_data,
+				ARRAY_SIZE(spca504_pccam600_init_data));
 		}
 		enable = (sd->autogain ? 0x04 : 0x01);
 		reg_w_riv(dev, 0x0c, 0x0000, enable);	/* auto exposure */
@@ -1050,7 +1070,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		spca504B_SetSizeType(gspca_dev);
 		break;
 	}
-	sp5xx_initContBrigHueRegisters(gspca_dev);
+	init_ctl_reg(gspca_dev);
 	return 0;
 }
 
@@ -1064,7 +1084,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 /*	case BRIDGE_SPCA533: */
 /*	case BRIDGE_SPCA536: */
 /*	case BRIDGE_SPCA504B: */
-		reg_w(gspca_dev, 0x31, 0, 0, 0);
+		reg_w_riv(dev, 0x31, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		spca504B_PollingDataReady(gspca_dev);
 		break;
@@ -1082,7 +1102,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 							0x0f, 0x00, 0xff, 1);
 		} else {
 			spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
-			reg_w_riv(dev, 0x01, 0x000f, 0x00);
+			reg_w_riv(dev, 0x01, 0x000f, 0x0000);
 		}
 		break;
 	}
@@ -1097,12 +1117,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i, sof = 0;
-	static unsigned char ffd9[] = {0xff, 0xd9};
+	static u8 ffd9[] = {0xff, 0xd9};
 
 /* frames are jpeg 4.1.1 without 0xff escape */
 	switch (sd->bridge) {
@@ -1190,63 +1210,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
 }
 
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
-
-	switch (sd->bridge) {
-	default:
-/*	case BRIDGE_SPCA533: */
-/*	case BRIDGE_SPCA504B: */
-/*	case BRIDGE_SPCA504: */
-/*	case BRIDGE_SPCA504C: */
-		reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
-		break;
-	case BRIDGE_SPCA536:
-		reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
-		break;
-	}
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
-
-	switch (sd->bridge) {
-	default:
-/*	case BRIDGE_SPCA533: */
-/*	case BRIDGE_SPCA504B: */
-/*	case BRIDGE_SPCA504: */
-/*	case BRIDGE_SPCA504C: */
-		reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
-		break;
-	case BRIDGE_SPCA536:
-		reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
-		break;
-	}
-}
-
-static void setcolors(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-	struct usb_device *dev = gspca_dev->dev;
-
-	switch (sd->bridge) {
-	default:
-/*	case BRIDGE_SPCA533: */
-/*	case BRIDGE_SPCA504B: */
-/*	case BRIDGE_SPCA504: */
-/*	case BRIDGE_SPCA504C: */
-		reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
-		break;
-	case BRIDGE_SPCA536:
-		reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
-		break;
-	}
-}
-
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -1384,6 +1347,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
 	{USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
 	{USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
 	{USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
+	{USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
 	{USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
 	{USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
 	{USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 404214b..1d321c3 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -264,6 +264,10 @@ static const struct v4l2_pix_format vga_mode_t16[] = {
 
 /* sensor specific data */
 struct additional_sensor_data {
+	const u8 n3[6];
+	const u8 *n4, n4sz;
+	const u8 reg80, reg8e;
+	const u8 nset8[6];
 	const u8 data1[10];
 	const u8 data2[9];
 	const u8 data3[9];
@@ -272,14 +276,55 @@ struct additional_sensor_data {
 	const u8 stream[4];
 };
 
+static const u8 n4_om6802[] = {
+	0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
+	0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
+	0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
+	0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
+	0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
+	0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
+	0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
+	0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
+	0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
+};
+static const u8 n4_other[] = {
+	0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
+	0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
+	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
+	0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
+	0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
+	0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
+	0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
+	0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
+};
+static const u8 n4_tas5130a[] = {
+	0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
+	0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
+	0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
+	0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
+	0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
+	0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
+	0xc6, 0xda
+};
+
 static const struct additional_sensor_data sensor_data[] = {
-    {				/* OM6802 */
+    {				/* 0: OM6802 */
+	.n3 =
+		{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
+	.n4 = n4_om6802,
+	.n4sz = sizeof n4_om6802,
+	.reg80 = 0x3c,
+	.reg8e = 0x33,
+	.nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
 	.data1 =
 		{0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
 		 0xb3, 0xfc},
 	.data2 =
 		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
 		 0xff},
+	.data3 =
+		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
+		 0xff},
 	.data4 =	/*Freq (50/60Hz). Splitted for test purpose */
 		{0x66, 0xca, 0xa8, 0xf0},
 	.data5 =	/* this could be removed later */
@@ -287,13 +332,23 @@ static const struct additional_sensor_data sensor_data[] = {
 	.stream =
 		{0x0b, 0x04, 0x0a, 0x78},
     },
-    {				/* OTHER */
+    {				/* 1: OTHER */
+	.n3 =
+		{0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
+	.n4 = n4_other,
+	.n4sz = sizeof n4_other,
+	.reg80 = 0xac,
+	.reg8e = 0xb8,
+	.nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
 	.data1 =
 		{0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
 		 0xe8, 0xfc},
 	.data2 =
 		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
 		 0xd9},
+	.data3 =
+		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
+		 0xd9},
 	.data4 =
 		{0x66, 0x00, 0xa8, 0xa8},
 	.data5 =
@@ -301,13 +356,23 @@ static const struct additional_sensor_data sensor_data[] = {
 	.stream =
 		{0x0b, 0x04, 0x0a, 0x00},
     },
-    {				/* TAS5130A */
+    {				/* 2: TAS5130A */
+	.n3 =
+		{0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
+	.n4 = n4_tas5130a,
+	.n4sz = sizeof n4_tas5130a,
+	.reg80 = 0x3c,
+	.reg8e = 0xb4,
+	.nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
 	.data1 =
 		{0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
 		 0xc8, 0xfc},
 	.data2 =
 		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
 		 0xe0},
+	.data3 =
+		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
+		 0xe0},
 	.data4 =	/* Freq (50/60Hz). Splitted for test purpose */
 		{0x66, 0x00, 0xa8, 0xe8},
 	.data5 =
@@ -364,7 +429,7 @@ static const u8 gamma_table[GAMMA_MAX][17] = {
 	{0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e,	/* 10 */
 	 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
 	 0xff},
-	{0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B,	/* 11 */
+	{0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8d, 0x9b,	/* 11 */
 	 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
 	 0xff},
 	{0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,	/* 12 */
@@ -385,8 +450,6 @@ static const u8 tas5130a_sensor_init[][8] = {
 	{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
 	{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
 	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
-	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
-	{},
 };
 
 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
@@ -633,10 +696,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	 * but wont hurt anyway, and can help someone with similar webcam
 	 * to see the initial parameters.*/
 	struct sd *sd = (struct sd *) gspca_dev;
+	const struct additional_sensor_data *sensor;
 	int i;
 	u16 sensor_id;
 	u8 test_byte = 0;
-	u16 reg80, reg8e;
 
 	static const u8 read_indexs[] =
 		{ 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
@@ -645,37 +708,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
 			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
 	static const u8 n2[] =
 			{0x08, 0x00};
-	static const u8 n3[6] =
-			{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
-	static const u8 n3_other[6] =
-			{0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
-	static const u8 n4[] =
-		{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
-		 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
-		 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
-		 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
-		 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
-		 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
-		 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
-		 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
-		 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
-	static const u8 n4_other[] =
-		{0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
-		 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
-		 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
-		 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
-		 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
-		 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
-		 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
-		 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
-	static const u8 nset8[6] =
-			{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
-	static const u8 nset8_other[6] =
-			{ 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
-	static const u8 nset9[4] =
-			{ 0x0b, 0x04, 0x0a, 0x78 };
-	static const u8 nset9_other[4] =
-			{ 0x0b, 0x04, 0x0a, 0x00 };
 
 	sensor_id = (reg_r(gspca_dev, 0x06) << 8)
 			| reg_r(gspca_dev, 0x07);
@@ -709,8 +741,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		}
 		if (i < 0) {
 			err("Bad sensor reset %02x", test_byte);
-/*			return -EIO; */
-/*fixme: test - continue */
+			return -EIO;
 		}
 		reg_w_buf(gspca_dev, n2, sizeof n2);
 	}
@@ -723,31 +754,17 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		i++;
 	}
 
-	if (sd->sensor != SENSOR_OTHER) {
-		reg_w_buf(gspca_dev, n3, sizeof n3);
-		reg_w_buf(gspca_dev, n4, sizeof n4);
-		reg_r(gspca_dev, 0x0080);
-		reg_w(gspca_dev, 0x2c80);
-		reg80 = 0x3880;
-		reg8e = 0x338e;
-	} else {
-		reg_w_buf(gspca_dev, n3_other, sizeof n3_other);
-		reg_w_buf(gspca_dev, n4_other, sizeof n4_other);
-		sd->gamma = 5;
-		reg80 = 0xac80;
-		reg8e = 0xb88e;
-	}
+	sensor = &sensor_data[sd->sensor];
+	reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
+	reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
 
-	reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
-			sizeof sensor_data[sd->sensor].data1);
-	reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
-			sizeof sensor_data[sd->sensor].data2);
-	reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
-			sizeof sensor_data[sd->sensor].data2);
+	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
+	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
+	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
 
-	reg_w(gspca_dev, reg80);
-	reg_w(gspca_dev, reg80);
-	reg_w(gspca_dev, reg8e);
+	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
+	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
+	reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
 
 	setbrightness(gspca_dev);
 	setcontrast(gspca_dev);
@@ -760,25 +777,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	reg_w(gspca_dev, 0x2088);
 	reg_w(gspca_dev, 0x2089);
 
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
-			sizeof sensor_data[sd->sensor].data4);
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
-			sizeof sensor_data[sd->sensor].data5);
-	if (sd->sensor != SENSOR_OTHER) {
-		reg_w_buf(gspca_dev, nset8, sizeof nset8);
-		reg_w_buf(gspca_dev, nset9, sizeof nset9);
-		reg_w(gspca_dev, 0x2880);
-	} else {
-		reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other);
-		reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other);
-	}
+	reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
+	reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
+	reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
+	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
 
-	reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
-			sizeof sensor_data[sd->sensor].data1);
-	reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
-			sizeof sensor_data[sd->sensor].data2);
-	reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
-			sizeof sensor_data[sd->sensor].data2);
+	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
+	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
+	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
 
 	return 0;
 }
@@ -828,7 +834,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
  * i added some module parameters for test with some users */
 static void poll_sensor(struct gspca_dev *gspca_dev)
 {
-	struct sd *sd = (struct sd *) gspca_dev;
 	static const u8 poll1[] =
 		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
 		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
@@ -844,24 +849,23 @@ static void poll_sensor(struct gspca_dev *gspca_dev)
 		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
 		 0xc2, 0x80, 0xc3, 0x10};
 
-	if (sd->sensor == SENSOR_OM6802) {
-		PDEBUG(D_STREAM, "[Sensor requires polling]");
-		reg_w_buf(gspca_dev, poll1, sizeof poll1);
-		reg_w_buf(gspca_dev, poll2, sizeof poll2);
-		reg_w_buf(gspca_dev, poll3, sizeof poll3);
-		reg_w_buf(gspca_dev, poll4, sizeof poll4);
-	}
+	PDEBUG(D_STREAM, "[Sensor requires polling]");
+	reg_w_buf(gspca_dev, poll1, sizeof poll1);
+	reg_w_buf(gspca_dev, poll2, sizeof poll2);
+	reg_w_buf(gspca_dev, poll3, sizeof poll3);
+	reg_w_buf(gspca_dev, poll4, sizeof poll4);
 }
 
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	const struct additional_sensor_data *sensor;
 	int i, mode;
 	u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
 	static const u8 t3[] =
 		{ 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
 
-	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
 	switch (mode) {
 	case 0:		/* 640x480 (0x00) */
 		break;
@@ -889,34 +893,33 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	default:
 /*	case SENSOR_TAS5130A: */
 		i = 0;
-		while (tas5130a_sensor_init[i][0] != 0) {
+		for (;;) {
 			reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
 					 sizeof tas5130a_sensor_init[0]);
+			if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
+				break;
 			i++;
 		}
 		reg_w(gspca_dev, 0x3c80);
 		/* just in case and to keep sync with logs (for mine) */
-		reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
+		reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
 				 sizeof tas5130a_sensor_init[0]);
 		reg_w(gspca_dev, 0x3c80);
 		break;
 	}
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
-			sizeof sensor_data[sd->sensor].data4);
+	sensor = &sensor_data[sd->sensor];
+	reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
 	reg_r(gspca_dev, 0x0012);
 	reg_w_buf(gspca_dev, t2, sizeof t2);
 	reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
 	reg_w(gspca_dev, 0x0013);
 	msleep(15);
-	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
-			sizeof sensor_data[sd->sensor].stream);
-	poll_sensor(gspca_dev);
+	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
+	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
+
+	if (sd->sensor == SENSOR_OM6802)
+		poll_sensor(gspca_dev);
 
-	/* restart on each start, just in case, sometimes regs goes wrong
-	 * when using controls from app */
-	setbrightness(gspca_dev);
-	setcontrast(gspca_dev);
-	setcolors(gspca_dev);
 	return 0;
 }
 
@@ -926,10 +929,9 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 
 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
 			sizeof sensor_data[sd->sensor].stream);
-	msleep(20);
 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
 			sizeof sensor_data[sd->sensor].stream);
-	if (sd->sensor != SENSOR_OTHER) {
+	if (sd->sensor == SENSOR_OM6802) {
 		msleep(20);
 		reg_w(gspca_dev, 0x0309);
 	}
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 9f243d7..4b44dde 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -426,7 +426,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	gspca_frame_add(gspca_dev, packet_type0,
 			frame, data + 2, gspca_dev->width);
 	gspca_frame_add(gspca_dev, packet_type1,
-			frame, data + gspca_dev->width + 6, gspca_dev->width);
+			frame, data + gspca_dev->width + 5, gspca_dev->width);
 }
 
 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 26dd155..589042f 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,14 +32,14 @@ MODULE_LICENSE("GPL");
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	__u8 hflip;
-	__u8 vflip;
-	__u8 lightfreq;
-	__u8 sharpness;
+	u8 hflip;
+	u8 vflip;
+	u8 lightfreq;
+	u8 sharpness;
 
 	u8 image_offset;
 
-	char bridge;
+	u8 bridge;
 #define BRIDGE_VC0321 0
 #define BRIDGE_VC0323 1
 	u8 sensor;
@@ -52,6 +52,10 @@ struct sd {
 #define SENSOR_OV7670 6
 #define SENSOR_PO1200 7
 #define SENSOR_PO3130NC 8
+	u8 flags;
+#define FL_SAMSUNG 0x01		/* SamsungQ1 (2 sensors) */
+#define FL_HFLIP 0x02		/* mirrored by default */
+#define FL_VFLIP 0x04		/* vertical flipped by default */
 };
 
 /* V4L2 controls supported by the driver */
@@ -65,7 +69,7 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
 
 static struct ctrl sd_ctrls[] = {
-/* next 2 controls work with ov7660 and ov7670 only */
+/* next 2 controls work with some sensors only */
 #define HFLIP_IDX 0
 	{
 	    {
@@ -152,9 +156,9 @@ static const struct v4l2_pix_format vc0323_mode[] = {
 		.sizeimage = 640 * 480 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0},
-	{1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi13x0_soc only */
+	{1280, 960, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi1310_soc only */
 		.bytesperline = 1280,
-		.sizeimage = 1280 * 1024 * 1 / 4 + 590,
+		.sizeimage = 1280 * 960 * 3 / 8 + 590,
 		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 2},
 };
@@ -188,11 +192,11 @@ static const struct v4l2_pix_format svga_mode[] = {
 #define OV7660_MVFP_MIRROR	0x20
 #define OV7660_MVFP_VFLIP	0x10
 
-static const __u8 mi0360_matrix[9] = {
+static const u8 mi0360_matrix[9] = {
 	0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50
 };
 
-static const __u8 mi0360_initVGA_JPG[][4] = {
+static const u8 mi0360_initVGA_JPG[][4] = {
 	{0xb0, 0x03, 0x19, 0xcc},
 	{0xb0, 0x04, 0x02, 0xcc},
 	{0xb3, 0x00, 0x24, 0xcc},
@@ -301,7 +305,7 @@ static const __u8 mi0360_initVGA_JPG[][4] = {
 	{0xb3, 0x5c, 0x01, 0xcc},
 	{}
 };
-static const __u8 mi0360_initQVGA_JPG[][4] = {
+static const u8 mi0360_initQVGA_JPG[][4] = {
 	{0xb0, 0x03, 0x19, 0xcc},
 	{0xb0, 0x04, 0x02, 0xcc},
 	{0xb3, 0x00, 0x24, 0xcc},
@@ -421,211 +425,95 @@ static const __u8 mi0360_initQVGA_JPG[][4] = {
 	{}
 };
 
-static const __u8 mi1310_socinitVGA_JPG[][4] = {
+static const u8 mi1310_socinitVGA_JPG[][4] = {
 	{0xb0, 0x03, 0x19, 0xcc},
 	{0xb0, 0x04, 0x02, 0xcc},
-	{0xb3, 0x00, 0x24, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},
-	{0xb3, 0x05, 0x01, 0xcc},
-	{0xb3, 0x06, 0x03, 0xcc},
-	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xb3, 0x00, 0x64, 0xcc},
+	{0xb3, 0x00, 0x65, 0xcc},
+	{0xb3, 0x05, 0x00, 0xcc},
+	{0xb3, 0x06, 0x00, 0xcc},
 	{0xb3, 0x08, 0x01, 0xcc},
 	{0xb3, 0x09, 0x0c, 0xcc},
 	{0xb3, 0x34, 0x02, 0xcc},
 	{0xb3, 0x35, 0xdd, 0xcc},
+	{0xb3, 0x02, 0x00, 0xcc},
 	{0xb3, 0x03, 0x0a, 0xcc},
-	{0xb3, 0x04, 0x0d, 0xcc},
+	{0xb3, 0x04, 0x05, 0xcc},
 	{0xb3, 0x20, 0x00, 0xcc},
 	{0xb3, 0x21, 0x00, 0xcc},
-	{0xb3, 0x22, 0x01, 0xcc},
-	{0xb3, 0x23, 0xe0, 0xcc},
+	{0xb3, 0x22, 0x03, 0xcc},
+	{0xb3, 0x23, 0xc0, 0xcc},
 	{0xb3, 0x14, 0x00, 0xcc},
 	{0xb3, 0x15, 0x00, 0xcc},
-	{0xb3, 0x16, 0x02, 0xcc},
-	{0xb3, 0x17, 0x7f, 0xcc},
-	{0xb8, 0x01, 0x7d, 0xcc},
-	{0xb8, 0x81, 0x09, 0xcc},
-	{0xb8, 0x27, 0x20, 0xcc},
-	{0xb8, 0x26, 0x80, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},
-	{0xb8, 0x00, 0x13, 0xcc},
-	{0xbc, 0x00, 0x71, 0xcc},
-	{0xb8, 0x81, 0x01, 0xcc},
-	{0xb8, 0x2c, 0x5a, 0xcc},
-	{0xb8, 0x2d, 0xff, 0xcc},
-	{0xb8, 0x2e, 0xee, 0xcc},
-	{0xb8, 0x2f, 0xfb, 0xcc},
-	{0xb8, 0x30, 0x52, 0xcc},
-	{0xb8, 0x31, 0xf8, 0xcc},
-	{0xb8, 0x32, 0xf1, 0xcc},
-	{0xb8, 0x33, 0xff, 0xcc},
-	{0xb8, 0x34, 0x54, 0xcc},
-	{0xb8, 0x35, 0x00, 0xcc},
-	{0xb8, 0x36, 0x00, 0xcc},
-	{0xb8, 0x37, 0x00, 0xcc},
+	{0xb3, 0x16, 0x04, 0xcc},
+	{0xb3, 0x17, 0xff, 0xcc},
+	{0xb3, 0x00, 0x65, 0xcc},
+	{0xb8, 0x00, 0x00, 0xcc},
+	{0xbc, 0x00, 0xd0, 0xcc},
+	{0xbc, 0x01, 0x01, 0xcc},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0xc8, 0x9f, 0x0b, 0xbb},
+	{0x5b, 0x00, 0x01, 0xbb},
+	{0x2f, 0xde, 0x20, 0xbb},
 	{0xf0, 0x00, 0x00, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x0d, 0x00, 0x09, 0xbb},
-	{0x0d, 0x00, 0x08, 0xbb},
+	{0x20, 0x03, 0x02, 0xbb},	/* h/v flip */
 	{0xf0, 0x00, 0x01, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x06, 0x00, 0x14, 0xbb},
-	{0x3a, 0x10, 0x00, 0xbb},
-	{0x00, 0x00, 0x10, 0xdd},
-	{0x9b, 0x10, 0x00, 0xbb},
-	{0x00, 0x00, 0x10, 0xdd},
+	{0x05, 0x00, 0x07, 0xbb},
+	{0x34, 0x00, 0x00, 0xbb},
+	{0x35, 0xff, 0x00, 0xbb},
+	{0xdc, 0x07, 0x02, 0xbb},
+	{0xdd, 0x3c, 0x18, 0xbb},
+	{0xde, 0x92, 0x6d, 0xbb},
+	{0xdf, 0xcd, 0xb1, 0xbb},
+	{0xe0, 0xff, 0xe7, 0xbb},
+	{0x06, 0xf0, 0x0d, 0xbb},
+	{0x06, 0x70, 0x0e, 0xbb},
+	{0x4c, 0x00, 0x01, 0xbb},
+	{0x4d, 0x00, 0x01, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x2e, 0x0c, 0x55, 0xbb},
+	{0x21, 0xb6, 0x6e, 0xbb},
+	{0x36, 0x30, 0x10, 0xbb},
+	{0x37, 0x00, 0xc1, 0xbb},
 	{0xf0, 0x00, 0x00, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x2b, 0x00, 0x28, 0xbb},
-	{0x2c, 0x00, 0x30, 0xbb},
-	{0x2d, 0x00, 0x30, 0xbb},
-	{0x2e, 0x00, 0x28, 0xbb},
-	{0x41, 0x00, 0xd7, 0xbb},
-	{0x09, 0x02, 0x3a, 0xbb},
-	{0x0c, 0x00, 0x00, 0xbb},
-	{0x20, 0x00, 0x00, 0xbb},
-	{0x05, 0x00, 0x8c, 0xbb},
-	{0x06, 0x00, 0x32, 0xbb},
-	{0x07, 0x00, 0xc6, 0xbb},
-	{0x08, 0x00, 0x19, 0xbb},
-	{0x24, 0x80, 0x6f, 0xbb},
-	{0xc8, 0x00, 0x0f, 0xbb},
-	{0x20, 0x00, 0x0f, 0xbb},
+	{0x07, 0x00, 0x84, 0xbb},
+	{0x08, 0x02, 0x4a, 0xbb},
+	{0x05, 0x01, 0x10, 0xbb},
+	{0x06, 0x00, 0x39, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x58, 0x02, 0x67, 0xbb},
+	{0x57, 0x02, 0x00, 0xbb},
+	{0x5a, 0x02, 0x67, 0xbb},
+	{0x59, 0x02, 0x00, 0xbb},
+	{0x5c, 0x12, 0x0d, 0xbb},
+	{0x5d, 0x16, 0x11, 0xbb},
+	{0x39, 0x06, 0x18, 0xbb},
+	{0x3a, 0x06, 0x18, 0xbb},
+	{0x3b, 0x06, 0x18, 0xbb},
+	{0x3c, 0x06, 0x18, 0xbb},
+	{0x64, 0x7b, 0x5b, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x36, 0x30, 0x10, 0xbb},
+	{0x37, 0x00, 0xc0, 0xbb},
+	{0xbc, 0x0e, 0x00, 0xcc},
+	{0xbc, 0x0f, 0x05, 0xcc},
+	{0xbc, 0x10, 0xc0, 0xcc},
+	{0xbc, 0x11, 0x03, 0xcc},
 	{0xb6, 0x00, 0x00, 0xcc},
 	{0xb6, 0x03, 0x02, 0xcc},
 	{0xb6, 0x02, 0x80, 0xcc},
 	{0xb6, 0x05, 0x01, 0xcc},
 	{0xb6, 0x04, 0xe0, 0xcc},
-	{0xb6, 0x12, 0x78, 0xcc},
+	{0xb6, 0x12, 0xf8, 0xcc},
+	{0xb6, 0x13, 0x25, 0xcc},
 	{0xb6, 0x18, 0x02, 0xcc},
 	{0xb6, 0x17, 0x58, 0xcc},
 	{0xb6, 0x16, 0x00, 0xcc},
 	{0xb6, 0x22, 0x12, 0xcc},
 	{0xb6, 0x23, 0x0b, 0xcc},
-	{0xb3, 0x02, 0x02, 0xcc},
 	{0xbf, 0xc0, 0x39, 0xcc},
 	{0xbf, 0xc1, 0x04, 0xcc},
-	{0xbf, 0xcc, 0x10, 0xcc},
-	{0xb9, 0x12, 0x00, 0xcc},
-	{0xb9, 0x13, 0x0a, 0xcc},
-	{0xb9, 0x14, 0x0a, 0xcc},
-	{0xb9, 0x15, 0x0a, 0xcc},
-	{0xb9, 0x16, 0x0a, 0xcc},
-	{0xb9, 0x18, 0x00, 0xcc},
-	{0xb9, 0x19, 0x0f, 0xcc},
-	{0xb9, 0x1a, 0x0f, 0xcc},
-	{0xb9, 0x1b, 0x0f, 0xcc},
-	{0xb9, 0x1c, 0x0f, 0xcc},
-	{0xb8, 0x8e, 0x00, 0xcc},
-	{0xb8, 0x8f, 0xff, 0xcc},
-	{0xb3, 0x01, 0x41, 0xcc},
-	{0x03, 0x03, 0xc0, 0xbb},
-	{0x06, 0x00, 0x10, 0xbb},
-	{0xb6, 0x12, 0xf8, 0xcc},
-	{0xb8, 0x0c, 0x20, 0xcc},
-	{0xb8, 0x0d, 0x70, 0xcc},
-	{0xb6, 0x13, 0x13, 0xcc},
-	{0x2f, 0x00, 0xC0, 0xbb},
-	{0xb8, 0xa0, 0x12, 0xcc},
-	{},
-};
-static const __u8 mi1310_socinitQVGA_JPG[][4] = {
-	{0xb0, 0x03, 0x19, 0xcc},
-	{0xb0, 0x04, 0x02, 0xcc},
-	{0xb3, 0x00, 0x24, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},
-	{0xb3, 0x05, 0x01, 0xcc},
-	{0xb3, 0x06, 0x03, 0xcc},
-	{0xb3, 0x5c, 0x01, 0xcc},
-	{0xb3, 0x08, 0x01, 0xcc},
-	{0xb3, 0x09, 0x0c, 0xcc},
-	{0xb3, 0x34, 0x02, 0xcc},
-	{0xb3, 0x35, 0xdd, 0xcc},
-	{0xb3, 0x03, 0x0a, 0xcc},
-	{0xb3, 0x04, 0x0d, 0xcc},
-	{0xb3, 0x20, 0x00, 0xcc},
-	{0xb3, 0x21, 0x00, 0xcc},
-	{0xb3, 0x22, 0x01, 0xcc},
-	{0xb3, 0x23, 0xe0, 0xcc},
-	{0xb3, 0x14, 0x00, 0xcc},
-	{0xb3, 0x15, 0x00, 0xcc},
-	{0xb3, 0x16, 0x02, 0xcc},
-	{0xb3, 0x17, 0x7f, 0xcc},
-	{0xb8, 0x01, 0x7d, 0xcc},
-	{0xb8, 0x81, 0x09, 0xcc},
-	{0xb8, 0x27, 0x20, 0xcc},
-	{0xb8, 0x26, 0x80, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},
-	{0xb8, 0x00, 0x13, 0xcc},
-	{0xbc, 0x00, 0xd1, 0xcc},
-	{0xb8, 0x81, 0x01, 0xcc},
-	{0xb8, 0x2c, 0x5a, 0xcc},
-	{0xb8, 0x2d, 0xff, 0xcc},
-	{0xb8, 0x2e, 0xee, 0xcc},
-	{0xb8, 0x2f, 0xfb, 0xcc},
-	{0xb8, 0x30, 0x52, 0xcc},
-	{0xb8, 0x31, 0xf8, 0xcc},
-	{0xb8, 0x32, 0xf1, 0xcc},
-	{0xb8, 0x33, 0xff, 0xcc},
-	{0xb8, 0x34, 0x54, 0xcc},
-	{0xb8, 0x35, 0x00, 0xcc},
-	{0xb8, 0x36, 0x00, 0xcc},
-	{0xb8, 0x37, 0x00, 0xcc},
-	{0xf0, 0x00, 0x00, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x0d, 0x00, 0x09, 0xbb},
-	{0x0d, 0x00, 0x08, 0xbb},
-	{0xf0, 0x00, 0x01, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x06, 0x00, 0x14, 0xbb},
-	{0x3a, 0x10, 0x00, 0xbb},
-	{0x00, 0x00, 0x10, 0xdd},
-	{0x9b, 0x10, 0x00, 0xbb},
-	{0x00, 0x00, 0x10, 0xdd},
-	{0xf0, 0x00, 0x00, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x2b, 0x00, 0x28, 0xbb},
-	{0x2c, 0x00, 0x30, 0xbb},
-	{0x2d, 0x00, 0x30, 0xbb},
-	{0x2e, 0x00, 0x28, 0xbb},
-	{0x41, 0x00, 0xd7, 0xbb},
-	{0x09, 0x02, 0x3a, 0xbb},
-	{0x0c, 0x00, 0x00, 0xbb},
-	{0x20, 0x00, 0x00, 0xbb},
-	{0x05, 0x00, 0x8c, 0xbb},
-	{0x06, 0x00, 0x32, 0xbb},
-	{0x07, 0x00, 0xc6, 0xbb},
-	{0x08, 0x00, 0x19, 0xbb},
-	{0x24, 0x80, 0x6f, 0xbb},
-	{0xc8, 0x00, 0x0f, 0xbb},
-	{0x20, 0x00, 0x0f, 0xbb},
-	{0xb6, 0x00, 0x00, 0xcc},
-	{0xb6, 0x03, 0x01, 0xcc},
-	{0xb6, 0x02, 0x40, 0xcc},
-	{0xb6, 0x05, 0x00, 0xcc},
-	{0xb6, 0x04, 0xf0, 0xcc},
-	{0xb6, 0x12, 0x78, 0xcc},
-	{0xb6, 0x18, 0x00, 0xcc},
-	{0xb6, 0x17, 0x96, 0xcc},
-	{0xb6, 0x16, 0x00, 0xcc},
-	{0xb6, 0x22, 0x12, 0xcc},
-	{0xb6, 0x23, 0x0b, 0xcc},
-	{0xb3, 0x02, 0x02, 0xcc},
-	{0xbf, 0xc0, 0x39, 0xcc},
-	{0xbf, 0xc1, 0x04, 0xcc},
-	{0xbf, 0xcc, 0x10, 0xcc},
-	{0xb9, 0x12, 0x00, 0xcc},
-	{0xb9, 0x13, 0x0a, 0xcc},
-	{0xb9, 0x14, 0x0a, 0xcc},
-	{0xb9, 0x15, 0x0a, 0xcc},
-	{0xb9, 0x16, 0x0a, 0xcc},
-	{0xb9, 0x18, 0x00, 0xcc},
-	{0xb9, 0x19, 0x0f, 0xcc},
-	{0xb9, 0x1a, 0x0f, 0xcc},
-	{0xb9, 0x1b, 0x0f, 0xcc},
-	{0xb9, 0x1c, 0x0f, 0xcc},
-	{0xb8, 0x8e, 0x00, 0xcc},
-	{0xb8, 0x8f, 0xff, 0xcc},
+	{0xbf, 0xcc, 0x00, 0xcc},
 	{0xbc, 0x02, 0x18, 0xcc},
 	{0xbc, 0x03, 0x50, 0xcc},
 	{0xbc, 0x04, 0x18, 0xcc},
@@ -636,133 +524,335 @@ static const __u8 mi1310_socinitQVGA_JPG[][4] = {
 	{0xbc, 0x0a, 0x10, 0xcc},
 	{0xbc, 0x0b, 0x00, 0xcc},
 	{0xbc, 0x0c, 0x00, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x80, 0x00, 0x03, 0xbb},
+	{0x81, 0xc7, 0x14, 0xbb},
+	{0x82, 0xeb, 0xe8, 0xbb},
+	{0x83, 0xfe, 0xf4, 0xbb},
+	{0x84, 0xcd, 0x10, 0xbb},
+	{0x85, 0xf3, 0xee, 0xbb},
+	{0x86, 0xff, 0xf1, 0xbb},
+	{0x87, 0xcd, 0x10, 0xbb},
+	{0x88, 0xf3, 0xee, 0xbb},
+	{0x89, 0x01, 0xf1, 0xbb},
+	{0x8a, 0xe5, 0x17, 0xbb},
+	{0x8b, 0xe8, 0xe2, 0xbb},
+	{0x8c, 0xf7, 0xed, 0xbb},
+	{0x8d, 0x00, 0xff, 0xbb},
+	{0x8e, 0xec, 0x10, 0xbb},
+	{0x8f, 0xf0, 0xed, 0xbb},
+	{0x90, 0xf9, 0xf2, 0xbb},
+	{0x91, 0x00, 0x00, 0xbb},
+	{0x92, 0xe9, 0x0d, 0xbb},
+	{0x93, 0xf4, 0xf2, 0xbb},
+	{0x94, 0xfb, 0xf5, 0xbb},
+	{0x95, 0x00, 0xff, 0xbb},
+	{0xb6, 0x0f, 0x08, 0xbb},
+	{0xb7, 0x3d, 0x16, 0xbb},
+	{0xb8, 0x0c, 0x04, 0xbb},
+	{0xb9, 0x1c, 0x07, 0xbb},
+	{0xba, 0x0a, 0x03, 0xbb},
+	{0xbb, 0x1b, 0x09, 0xbb},
+	{0xbc, 0x17, 0x0d, 0xbb},
+	{0xbd, 0x23, 0x1d, 0xbb},
+	{0xbe, 0x00, 0x28, 0xbb},
+	{0xbf, 0x11, 0x09, 0xbb},
+	{0xc0, 0x16, 0x15, 0xbb},
+	{0xc1, 0x00, 0x1b, 0xbb},
+	{0xc2, 0x0e, 0x07, 0xbb},
+	{0xc3, 0x14, 0x10, 0xbb},
+	{0xc4, 0x00, 0x17, 0xbb},
+	{0x06, 0x74, 0x8e, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x06, 0xf4, 0x8e, 0xbb},
+	{0x00, 0x00, 0x50, 0xdd},
+	{0x06, 0x74, 0x8e, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x24, 0x50, 0x20, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x34, 0x0c, 0x50, 0xbb},
 	{0xb3, 0x01, 0x41, 0xcc},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x03, 0x03, 0xc0, 0xbb},
+	{},
+};
+static const u8 mi1310_socinitQVGA_JPG[][4] = {
+	{0xb0, 0x03, 0x19, 0xcc},	{0xb0, 0x04, 0x02, 0xcc},
+	{0xb3, 0x00, 0x64, 0xcc},	{0xb3, 0x00, 0x65, 0xcc},
+	{0xb3, 0x05, 0x00, 0xcc},	{0xb3, 0x06, 0x00, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x34, 0x02, 0xcc},	{0xb3, 0x35, 0xdd, 0xcc},
+	{0xb3, 0x02, 0x00, 0xcc},	{0xb3, 0x03, 0x0a, 0xcc},
+	{0xb3, 0x04, 0x05, 0xcc},	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x21, 0x00, 0xcc},	{0xb3, 0x22, 0x03, 0xcc},
+	{0xb3, 0x23, 0xc0, 0xcc},	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x00, 0xcc},	{0xb3, 0x16, 0x04, 0xcc},
+	{0xb3, 0x17, 0xff, 0xcc},	{0xb3, 0x00, 0x65, 0xcc},
+	{0xb8, 0x00, 0x00, 0xcc},	{0xbc, 0x00, 0xf0, 0xcc},
+	{0xbc, 0x01, 0x01, 0xcc},	{0xf0, 0x00, 0x02, 0xbb},
+	{0xc8, 0x9f, 0x0b, 0xbb},	{0x5b, 0x00, 0x01, 0xbb},
+	{0x2f, 0xde, 0x20, 0xbb},	{0xf0, 0x00, 0x00, 0xbb},
+	{0x20, 0x03, 0x02, 0xbb},	/* h/v flip */
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x05, 0x00, 0x07, 0xbb},	{0x34, 0x00, 0x00, 0xbb},
+	{0x35, 0xff, 0x00, 0xbb},	{0xdc, 0x07, 0x02, 0xbb},
+	{0xdd, 0x3c, 0x18, 0xbb},	{0xde, 0x92, 0x6d, 0xbb},
+	{0xdf, 0xcd, 0xb1, 0xbb},	{0xe0, 0xff, 0xe7, 0xbb},
+	{0x06, 0xf0, 0x0d, 0xbb},	{0x06, 0x70, 0x0e, 0xbb},
+	{0x4c, 0x00, 0x01, 0xbb},	{0x4d, 0x00, 0x01, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},	{0x2e, 0x0c, 0x55, 0xbb},
+	{0x21, 0xb6, 0x6e, 0xbb},	{0x36, 0x30, 0x10, 0xbb},
+	{0x37, 0x00, 0xc1, 0xbb},	{0xf0, 0x00, 0x00, 0xbb},
+	{0x07, 0x00, 0x84, 0xbb},	{0x08, 0x02, 0x4a, 0xbb},
+	{0x05, 0x01, 0x10, 0xbb},	{0x06, 0x00, 0x39, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},	{0x58, 0x02, 0x67, 0xbb},
+	{0x57, 0x02, 0x00, 0xbb},	{0x5a, 0x02, 0x67, 0xbb},
+	{0x59, 0x02, 0x00, 0xbb},	{0x5c, 0x12, 0x0d, 0xbb},
+	{0x5d, 0x16, 0x11, 0xbb},	{0x39, 0x06, 0x18, 0xbb},
+	{0x3a, 0x06, 0x18, 0xbb},	{0x3b, 0x06, 0x18, 0xbb},
+	{0x3c, 0x06, 0x18, 0xbb},	{0x64, 0x7b, 0x5b, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},	{0x36, 0x30, 0x10, 0xbb},
+	{0x37, 0x00, 0xc0, 0xbb},	{0xbc, 0x0e, 0x00, 0xcc},
+	{0xbc, 0x0f, 0x05, 0xcc},	{0xbc, 0x10, 0xc0, 0xcc},
+	{0xbc, 0x11, 0x03, 0xcc},	{0xb6, 0x00, 0x00, 0xcc},
+	{0xb6, 0x03, 0x01, 0xcc},	{0xb6, 0x02, 0x40, 0xcc},
+	{0xb6, 0x05, 0x00, 0xcc},	{0xb6, 0x04, 0xf0, 0xcc},
+	{0xb6, 0x12, 0xf8, 0xcc},	{0xb6, 0x13, 0x25, 0xcc},
+	{0xb6, 0x18, 0x00, 0xcc},	{0xb6, 0x17, 0x96, 0xcc},
+	{0xb6, 0x16, 0x00, 0xcc},	{0xb6, 0x22, 0x12, 0xcc},
+	{0xb6, 0x23, 0x0b, 0xcc},	{0xbf, 0xc0, 0x39, 0xcc},
+	{0xbf, 0xc1, 0x04, 0xcc},	{0xbf, 0xcc, 0x00, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},	{0xf0, 0x00, 0x01, 0xbb},
+	{0x80, 0x00, 0x03, 0xbb},	{0x81, 0xc7, 0x14, 0xbb},
+	{0x82, 0xeb, 0xe8, 0xbb},	{0x83, 0xfe, 0xf4, 0xbb},
+	{0x84, 0xcd, 0x10, 0xbb},	{0x85, 0xf3, 0xee, 0xbb},
+	{0x86, 0xff, 0xf1, 0xbb},	{0x87, 0xcd, 0x10, 0xbb},
+	{0x88, 0xf3, 0xee, 0xbb},	{0x89, 0x01, 0xf1, 0xbb},
+	{0x8a, 0xe5, 0x17, 0xbb},	{0x8b, 0xe8, 0xe2, 0xbb},
+	{0x8c, 0xf7, 0xed, 0xbb},	{0x8d, 0x00, 0xff, 0xbb},
+	{0x8e, 0xec, 0x10, 0xbb},	{0x8f, 0xf0, 0xed, 0xbb},
+	{0x90, 0xf9, 0xf2, 0xbb},	{0x91, 0x00, 0x00, 0xbb},
+	{0x92, 0xe9, 0x0d, 0xbb},	{0x93, 0xf4, 0xf2, 0xbb},
+	{0x94, 0xfb, 0xf5, 0xbb},	{0x95, 0x00, 0xff, 0xbb},
+	{0xb6, 0x0f, 0x08, 0xbb},	{0xb7, 0x3d, 0x16, 0xbb},
+	{0xb8, 0x0c, 0x04, 0xbb},	{0xb9, 0x1c, 0x07, 0xbb},
+	{0xba, 0x0a, 0x03, 0xbb},	{0xbb, 0x1b, 0x09, 0xbb},
+	{0xbc, 0x17, 0x0d, 0xbb},	{0xbd, 0x23, 0x1d, 0xbb},
+	{0xbe, 0x00, 0x28, 0xbb},	{0xbf, 0x11, 0x09, 0xbb},
+	{0xc0, 0x16, 0x15, 0xbb},	{0xc1, 0x00, 0x1b, 0xbb},
+	{0xc2, 0x0e, 0x07, 0xbb},	{0xc3, 0x14, 0x10, 0xbb},
+	{0xc4, 0x00, 0x17, 0xbb},	{0x06, 0x74, 0x8e, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},	{0x06, 0xf4, 0x8e, 0xbb},
+	{0x00, 0x00, 0x50, 0xdd},	{0x06, 0x74, 0x8e, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},	{0x24, 0x50, 0x20, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},	{0x34, 0x0c, 0x50, 0xbb},
+	{0xb3, 0x01, 0x41, 0xcc},	{0xf0, 0x00, 0x00, 0xbb},
 	{0x03, 0x03, 0xc0, 0xbb},
-	{0x06, 0x00, 0x10, 0xbb},
-	{0xb6, 0x12, 0xf8, 0xcc},
-	{0xb8, 0x0c, 0x20, 0xcc},
-	{0xb8, 0x0d, 0x70, 0xcc},
-	{0xb6, 0x13, 0x13, 0xcc},
-	{0x2f, 0x00, 0xC0, 0xbb},
-	{0xb8, 0xa0, 0x12, 0xcc},
 	{},
 };
 static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
 	{0xb0, 0x03, 0x19, 0xcc},
 	{0xb0, 0x04, 0x02, 0xcc},
-	{0xb3, 0x00, 0x24, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb3, 0x00, 0x64, 0xcc},
+	{0xb3, 0x00, 0x65, 0xcc},
 	{0xb3, 0x05, 0x00, 0xcc},
-	{0xb3, 0x06, 0x01, 0xcc},
-	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xb3, 0x06, 0x00, 0xcc},
 	{0xb3, 0x08, 0x01, 0xcc},
 	{0xb3, 0x09, 0x0c, 0xcc},
 	{0xb3, 0x34, 0x02, 0xcc},
 	{0xb3, 0x35, 0xdd, 0xcc},
+	{0xb3, 0x02, 0x00, 0xcc},
 	{0xb3, 0x03, 0x0a, 0xcc},
 	{0xb3, 0x04, 0x0d, 0xcc},
 	{0xb3, 0x20, 0x00, 0xcc},
 	{0xb3, 0x21, 0x00, 0xcc},
-	{0xb3, 0x22, 0x04, 0xcc},
-	{0xb3, 0x23, 0x00, 0xcc},
+	{0xb3, 0x22, 0x03, 0xcc},
+	{0xb3, 0x23, 0xc0, 0xcc},
 	{0xb3, 0x14, 0x00, 0xcc},
 	{0xb3, 0x15, 0x00, 0xcc},
 	{0xb3, 0x16, 0x04, 0xcc},
 	{0xb3, 0x17, 0xff, 0xcc},
-	{0xb8, 0x01, 0x7d, 0xcc},
-	{0xb8, 0x81, 0x09, 0xcc},
-	{0xb8, 0x27, 0x20, 0xcc},
-	{0xb8, 0x26, 0x80, 0xcc},
-	{0xb8, 0x06, 0x00, 0xcc},
-	{0xb8, 0x07, 0x05, 0xcc},
-	{0xb8, 0x08, 0x00, 0xcc},
-	{0xb8, 0x09, 0x04, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},
-	{0xb8, 0x00, 0x11, 0xcc},
-	{0xbc, 0x00, 0x71, 0xcc},
-	{0xb8, 0x81, 0x01, 0xcc},
-	{0xb8, 0x2c, 0x5a, 0xcc},
-	{0xb8, 0x2d, 0xff, 0xcc},
-	{0xb8, 0x2e, 0xee, 0xcc},
-	{0xb8, 0x2f, 0xfb, 0xcc},
-	{0xb8, 0x30, 0x52, 0xcc},
-	{0xb8, 0x31, 0xf8, 0xcc},
-	{0xb8, 0x32, 0xf1, 0xcc},
-	{0xb8, 0x33, 0xff, 0xcc},
-	{0xb8, 0x34, 0x54, 0xcc},
+	{0xb3, 0x00, 0x65, 0xcc},
+	{0xb8, 0x00, 0x00, 0xcc},
+	{0xbc, 0x00, 0x70, 0xcc},
+	{0xbc, 0x01, 0x01, 0xcc},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0xc8, 0x9f, 0x0b, 0xbb},
+	{0x5b, 0x00, 0x01, 0xbb},
 	{0xf0, 0x00, 0x00, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x0d, 0x00, 0x09, 0xbb},
-	{0x0d, 0x00, 0x08, 0xbb},
+	{0x20, 0x03, 0x02, 0xbb},	/* h/v flip */
 	{0xf0, 0x00, 0x01, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x06, 0x00, 0x14, 0xbb},
-	{0x3a, 0x10, 0x00, 0xbb},
-	{0x00, 0x00, 0x10, 0xdd},
-	{0x9b, 0x10, 0x00, 0xbb},
-	{0x00, 0x00, 0x10, 0xdd},
+	{0x05, 0x00, 0x07, 0xbb},
+	{0x34, 0x00, 0x00, 0xbb},
+	{0x35, 0xff, 0x00, 0xbb},
+	{0xdc, 0x07, 0x02, 0xbb},
+	{0xdd, 0x3c, 0x18, 0xbb},
+	{0xde, 0x92, 0x6d, 0xbb},
+	{0xdf, 0xcd, 0xb1, 0xbb},
+	{0xe0, 0xff, 0xe7, 0xbb},
+	{0x06, 0xf0, 0x0d, 0xbb},
+	{0x06, 0x70, 0x0e, 0xbb},
+	{0x4c, 0x00, 0x01, 0xbb},
+	{0x4d, 0x00, 0x01, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x2e, 0x0c, 0x60, 0xbb},
+	{0x21, 0xb6, 0x6e, 0xbb},
+	{0x37, 0x01, 0x40, 0xbb},
 	{0xf0, 0x00, 0x00, 0xbb},
-	{0x00, 0x01, 0x00, 0xdd},
-	{0x2b, 0x00, 0x28, 0xbb},
-	{0x2c, 0x00, 0x30, 0xbb},
-	{0x2d, 0x00, 0x30, 0xbb},
-	{0x2e, 0x00, 0x28, 0xbb},
-	{0x41, 0x00, 0xd7, 0xbb},
-	{0x09, 0x02, 0x3a, 0xbb},
-	{0x0c, 0x00, 0x00, 0xbb},
-	{0x20, 0x00, 0x00, 0xbb},
-	{0x05, 0x00, 0x8c, 0xbb},
-	{0x06, 0x00, 0x32, 0xbb},
-	{0x07, 0x00, 0xc6, 0xbb},
-	{0x08, 0x00, 0x19, 0xbb},
-	{0x24, 0x80, 0x6f, 0xbb},
-	{0xc8, 0x00, 0x0f, 0xbb},
-	{0x20, 0x00, 0x03, 0xbb},
+	{0x07, 0x00, 0x84, 0xbb},
+	{0x08, 0x02, 0x4a, 0xbb},
+	{0x05, 0x01, 0x10, 0xbb},
+	{0x06, 0x00, 0x39, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x58, 0x02, 0x67, 0xbb},
+	{0x57, 0x02, 0x00, 0xbb},
+	{0x5a, 0x02, 0x67, 0xbb},
+	{0x59, 0x02, 0x00, 0xbb},
+	{0x5c, 0x12, 0x0d, 0xbb},
+	{0x5d, 0x16, 0x11, 0xbb},
+	{0x39, 0x06, 0x18, 0xbb},
+	{0x3a, 0x06, 0x18, 0xbb},
+	{0x3b, 0x06, 0x18, 0xbb},
+	{0x3c, 0x06, 0x18, 0xbb},
+	{0x64, 0x7b, 0x5b, 0xbb},
 	{0xb6, 0x00, 0x00, 0xcc},
 	{0xb6, 0x03, 0x05, 0xcc},
 	{0xb6, 0x02, 0x00, 0xcc},
-	{0xb6, 0x05, 0x04, 0xcc},
-	{0xb6, 0x04, 0x00, 0xcc},
+	{0xb6, 0x05, 0x03, 0xcc},
+	{0xb6, 0x04, 0xc0, 0xcc},
 	{0xb6, 0x12, 0xf8, 0xcc},
-	{0xb6, 0x18, 0x0a, 0xcc},
-	{0xb6, 0x17, 0x00, 0xcc},
+	{0xb6, 0x13, 0x29, 0xcc},
+	{0xb6, 0x18, 0x09, 0xcc},
+	{0xb6, 0x17, 0x60, 0xcc},
 	{0xb6, 0x16, 0x00, 0xcc},
 	{0xb6, 0x22, 0x12, 0xcc},
 	{0xb6, 0x23, 0x0b, 0xcc},
-	{0xb3, 0x02, 0x02, 0xcc},
 	{0xbf, 0xc0, 0x39, 0xcc},
 	{0xbf, 0xc1, 0x04, 0xcc},
-	{0xbf, 0xcc, 0x10, 0xcc},
-	{0xb9, 0x12, 0x00, 0xcc},
-	{0xb9, 0x13, 0x14, 0xcc},
-	{0xb9, 0x14, 0x14, 0xcc},
-	{0xb9, 0x15, 0x14, 0xcc},
-	{0xb9, 0x16, 0x14, 0xcc},
-	{0xb9, 0x18, 0x00, 0xcc},
-	{0xb9, 0x19, 0x1e, 0xcc},
-	{0xb9, 0x1a, 0x1e, 0xcc},
-	{0xb9, 0x1b, 0x1e, 0xcc},
-	{0xb9, 0x1c, 0x1e, 0xcc},
+	{0xbf, 0xcc, 0x00, 0xcc},
 	{0xb3, 0x01, 0x41, 0xcc},
-	{0xb8, 0x8e, 0x00, 0xcc},
-	{0xb8, 0x8f, 0xff, 0xcc},
-	{0xb6, 0x12, 0xf8, 0xcc},
-	{0xb8, 0x0c, 0x20, 0xcc},
-	{0xb8, 0x0d, 0x70, 0xcc},
-	{0xb6, 0x13, 0x13, 0xcc},
-	{0x2f, 0x00, 0xC0, 0xbb},
-	{0xb8, 0xa0, 0x12, 0xcc},
+	{0x00, 0x00, 0x80, 0xdd},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x00, 0x00, 0x10, 0xdd},
+	{0x22, 0xa0, 0x78, 0xbb},
+	{0x23, 0xa0, 0x78, 0xbb},
+	{0x24, 0x7f, 0x00, 0xbb},
+	{0x28, 0xea, 0x02, 0xbb},
+	{0x29, 0x86, 0x7a, 0xbb},
+	{0x5e, 0x52, 0x4c, 0xbb},
+	{0x5f, 0x20, 0x24, 0xbb},
+	{0x60, 0x00, 0x02, 0xbb},
+	{0x02, 0x00, 0xee, 0xbb},
+	{0x03, 0x39, 0x23, 0xbb},
+	{0x04, 0x07, 0x24, 0xbb},
+	{0x09, 0x00, 0xc0, 0xbb},
+	{0x0a, 0x00, 0x79, 0xbb},
+	{0x0b, 0x00, 0x04, 0xbb},
+	{0x0c, 0x00, 0x5c, 0xbb},
+	{0x0d, 0x00, 0xd9, 0xbb},
+	{0x0e, 0x00, 0x53, 0xbb},
+	{0x0f, 0x00, 0x21, 0xbb},
+	{0x10, 0x00, 0xa4, 0xbb},
+	{0x11, 0x00, 0xe5, 0xbb},
+	{0x15, 0x00, 0x00, 0xbb},
+	{0x16, 0x00, 0x00, 0xbb},
+	{0x17, 0x00, 0x00, 0xbb},
+	{0x18, 0x00, 0x00, 0xbb},
+	{0x19, 0x00, 0x00, 0xbb},
+	{0x1a, 0x00, 0x00, 0xbb},
+	{0x1b, 0x00, 0x00, 0xbb},
+	{0x1c, 0x00, 0x00, 0xbb},
+	{0x1d, 0x00, 0x00, 0xbb},
+	{0x1e, 0x00, 0x00, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x00, 0x00, 0x20, 0xdd},
+	{0x06, 0xf0, 0x8e, 0xbb},
+	{0x00, 0x00, 0x80, 0xdd},
+	{0x06, 0x70, 0x8e, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x00, 0x00, 0x20, 0xdd},
+	{0x5e, 0x6a, 0x53, 0xbb},
+	{0x5f, 0x40, 0x2c, 0xbb},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x00, 0x00, 0x20, 0xdd},
+	{0x58, 0x00, 0x00, 0xbb},
+	{0x53, 0x09, 0x03, 0xbb},
+	{0x54, 0x31, 0x18, 0xbb},
+	{0x55, 0x8b, 0x5f, 0xbb},
+	{0x56, 0xc0, 0xa9, 0xbb},
+	{0x57, 0xe0, 0xd2, 0xbb},
+	{0xe1, 0x00, 0x00, 0xbb},
+	{0xdc, 0x09, 0x03, 0xbb},
+	{0xdd, 0x31, 0x18, 0xbb},
+	{0xde, 0x8b, 0x5f, 0xbb},
+	{0xdf, 0xc0, 0xa9, 0xbb},
+	{0xe0, 0xe0, 0xd2, 0xbb},
+	{0xb3, 0x5c, 0x01, 0xcc},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x06, 0xf0, 0x8e, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x2f, 0xde, 0x20, 0xbb},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x24, 0x50, 0x20, 0xbb},
+	{0xbc, 0x0e, 0x00, 0xcc},
+	{0xbc, 0x0f, 0x05, 0xcc},
+	{0xbc, 0x10, 0xc0, 0xcc},
+	{0xf0, 0x00, 0x02, 0xbb},
+	{0x34, 0x0c, 0x50, 0xbb},
+	{0xbc, 0x11, 0x03, 0xcc},
+	{0xf0, 0x00, 0x01, 0xbb},
+	{0x80, 0x00, 0x03, 0xbb},
+	{0x81, 0xc7, 0x14, 0xbb},
+	{0x82, 0xeb, 0xe8, 0xbb},
+	{0x83, 0xfe, 0xf4, 0xbb},
+	{0x84, 0xcd, 0x10, 0xbb},
+	{0x85, 0xf3, 0xee, 0xbb},
+	{0x86, 0xff, 0xf1, 0xbb},
+	{0x87, 0xcd, 0x10, 0xbb},
+	{0x88, 0xf3, 0xee, 0xbb},
+	{0x89, 0x01, 0xf1, 0xbb},
+	{0x8a, 0xe5, 0x17, 0xbb},
+	{0x8b, 0xe8, 0xe2, 0xbb},
+	{0x8c, 0xf7, 0xed, 0xbb},
+	{0x8d, 0x00, 0xff, 0xbb},
+	{0x8e, 0xec, 0x10, 0xbb},
+	{0x8f, 0xf0, 0xed, 0xbb},
+	{0x90, 0xf9, 0xf2, 0xbb},
+	{0x91, 0x00, 0x00, 0xbb},
+	{0x92, 0xe9, 0x0d, 0xbb},
+	{0x93, 0xf4, 0xf2, 0xbb},
+	{0x94, 0xfb, 0xf5, 0xbb},
+	{0x95, 0x00, 0xff, 0xbb},
+	{0xb6, 0x0f, 0x08, 0xbb},
+	{0xb7, 0x3d, 0x16, 0xbb},
+	{0xb8, 0x0c, 0x04, 0xbb},
+	{0xb9, 0x1c, 0x07, 0xbb},
+	{0xba, 0x0a, 0x03, 0xbb},
+	{0xbb, 0x1b, 0x09, 0xbb},
+	{0xbc, 0x17, 0x0d, 0xbb},
+	{0xbd, 0x23, 0x1d, 0xbb},
+	{0xbe, 0x00, 0x28, 0xbb},
+	{0xbf, 0x11, 0x09, 0xbb},
+	{0xc0, 0x16, 0x15, 0xbb},
+	{0xc1, 0x00, 0x1b, 0xbb},
+	{0xc2, 0x0e, 0x07, 0xbb},
+	{0xc3, 0x14, 0x10, 0xbb},
+	{0xc4, 0x00, 0x17, 0xbb},
+	{0x06, 0x74, 0x8e, 0xbb},
+	{0xf0, 0x00, 0x00, 0xbb},
+	{0x03, 0x03, 0xc0, 0xbb},
 	{}
 };
 
-static const __u8 mi1320_gamma[17] = {
+static const u8 mi1320_gamma[17] = {
 	0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
 	0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
 };
-static const __u8 mi1320_matrix[9] = {
+static const u8 mi1320_matrix[9] = {
 	0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52
 };
-static const __u8 mi1320_initVGA_data[][4] = {
+static const u8 mi1320_initVGA_data[][4] = {
 	{0xb3, 0x01, 0x01, 0xcc},	{0x00, 0x00, 0x33, 0xdd},
 	{0xb0, 0x03, 0x19, 0xcc},	{0x00, 0x00, 0x33, 0xdd},
 	{0xb0, 0x04, 0x02, 0xcc},	{0x00, 0x00, 0x33, 0xdd},
@@ -841,7 +931,7 @@ static const __u8 mi1320_initVGA_data[][4] = {
 	{0xb3, 0x5c, 0x01, 0xcc},	{0xb3, 0x01, 0x41, 0xcc},
 	{}
 };
-static const __u8 mi1320_initQVGA_data[][4] = {
+static const u8 mi1320_initQVGA_data[][4] = {
 	{0xb3, 0x01, 0x01, 0xcc},	{0x00, 0x00, 0x33, 0xdd},
 	{0xb0, 0x03, 0x19, 0xcc},	{0x00, 0x00, 0x33, 0xdd},
 	{0xb0, 0x04, 0x02, 0xcc},	{0x00, 0x00, 0x33, 0xdd},
@@ -948,7 +1038,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
 	{0x07, 0x00, 0xe0, 0xbb},
 	{0x08, 0x00, 0x0b, 0xbb},
 	{0x21, 0x00, 0x0c, 0xbb},
-	{0x20, 0x01, 0x03, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},	/* h/v flip */
 	{0xbf, 0xc0, 0x26, 0xcc},
 	{0xbf, 0xc1, 0x02, 0xcc},
 	{0xbf, 0xcc, 0x04, 0xcc},
@@ -958,7 +1048,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
 	{0x06, 0x00, 0x11, 0xbb},
 	{0x07, 0x01, 0x42, 0xbb},
 	{0x08, 0x00, 0x11, 0xbb},
-	{0x20, 0x01, 0x03, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},	/* h/v flip */
 	{0x21, 0x80, 0x00, 0xbb},
 	{0x22, 0x0d, 0x0f, 0xbb},
 	{0x24, 0x80, 0x00, 0xbb},
@@ -1051,7 +1141,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
 	{0x07, 0x00, 0xe0, 0xbb},
 	{0x08, 0x00, 0x0b, 0xbb},
 	{0x21, 0x00, 0x0c, 0xbb},
-	{0x20, 0x01, 0x03, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},	/* h/v flip */
 	{0xbf, 0xc0, 0x26, 0xcc},
 	{0xbf, 0xc1, 0x02, 0xcc},
 	{0xbf, 0xcc, 0x04, 0xcc},
@@ -1071,7 +1161,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
 	{0x06, 0x00, 0x11, 0xbb},
 	{0x07, 0x01, 0x42, 0xbb},
 	{0x08, 0x00, 0x11, 0xbb},
-	{0x20, 0x01, 0x03, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},	/* h/v flip */
 	{0x21, 0x80, 0x00, 0xbb},
 	{0x22, 0x0d, 0x0f, 0xbb},
 	{0x24, 0x80, 0x00, 0xbb},
@@ -1161,7 +1251,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
 	{0x00, 0x00, 0x20, 0xdd},
 	{0xf0, 0x00, 0x00, 0xbb},
 	{0x00, 0x00, 0x30, 0xdd},
-	{0x20, 0x01, 0x03, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},	/* h/v flip */
 	{0x00, 0x00, 0x20, 0xdd},
 	{0xbf, 0xc0, 0x26, 0xcc},
 	{0xbf, 0xc1, 0x02, 0xcc},
@@ -1172,7 +1262,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
 	{0x06, 0x00, 0x11, 0xbb},
 	{0x07, 0x01, 0x42, 0xbb},
 	{0x08, 0x00, 0x11, 0xbb},
-	{0x20, 0x01, 0x03, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},	/* h/v flip */
 	{0x21, 0x80, 0x00, 0xbb},
 	{0x22, 0x0d, 0x0f, 0xbb},
 	{0x24, 0x80, 0x00, 0xbb},
@@ -1230,7 +1320,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
 	{0x06, 0x00, 0x11, 0xbb},
 	{0x07, 0x00, 0x85, 0xbb},
 	{0x08, 0x00, 0x27, 0xbb},
-	{0x20, 0x01, 0x03, 0xbb},
+	{0x20, 0x01, 0x03, 0xbb},	/* h/v flip */
 	{0x21, 0x80, 0x00, 0xbb},
 	{0x22, 0x0d, 0x0f, 0xbb},
 	{0x24, 0x80, 0x00, 0xbb},
@@ -1249,15 +1339,15 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
 	{0x64, 0x5e, 0x1c, 0xbb},
 	{}
 };
-static const __u8 po3130_gamma[17] = {
+static const u8 po3130_gamma[17] = {
 	0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
 	0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
 };
-static const __u8 po3130_matrix[9] = {
+static const u8 po3130_matrix[9] = {
 	0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
 };
 
-static const __u8 po3130_initVGA_data[][4] = {
+static const u8 po3130_initVGA_data[][4] = {
 	{0xb0, 0x4d, 0x00, 0xcc},	{0xb3, 0x01, 0x01, 0xcc},
 	{0x00, 0x00, 0x50, 0xdd},	{0xb0, 0x03, 0x01, 0xcc},
 	{0xb3, 0x00, 0x04, 0xcc},	{0xb3, 0x00, 0x24, 0xcc},
@@ -1340,7 +1430,7 @@ static const __u8 po3130_initVGA_data[][4] = {
 	{0xb3, 0x5c, 0x00, 0xcc},	{0xb3, 0x01, 0x41, 0xcc},
 	{}
 };
-static const __u8 po3130_rundata[][4] = {
+static const u8 po3130_rundata[][4] = {
 	{0x00, 0x47, 0x45, 0xaa},	{0x00, 0x48, 0x9b, 0xaa},
 	{0x00, 0x49, 0x3a, 0xaa},	{0x00, 0x4a, 0x01, 0xaa},
 	{0x00, 0x44, 0x40, 0xaa},
@@ -1355,7 +1445,7 @@ static const __u8 po3130_rundata[][4] = {
 	{}
 };
 
-static const __u8 po3130_initQVGA_data[][4] = {
+static const u8 po3130_initQVGA_data[][4] = {
 	{0xb0, 0x4d, 0x00, 0xcc},	{0xb3, 0x01, 0x01, 0xcc},
 	{0x00, 0x00, 0x50, 0xdd},	{0xb0, 0x03, 0x09, 0xcc},
 	{0xb3, 0x00, 0x04, 0xcc},	{0xb3, 0x00, 0x24, 0xcc},
@@ -1441,121 +1531,207 @@ static const __u8 po3130_initQVGA_data[][4] = {
 	{}
 };
 
-static const __u8 hv7131r_gamma[17] = {
-/*	0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- *	0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */
-	0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1,
-	0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff
+static const u8 hv7131r_gamma[17] = {
+	0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
+	0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
 };
-static const __u8 hv7131r_matrix[9] = {
+static const u8 hv7131r_matrix[9] = {
 	0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
 };
-static const __u8 hv7131r_initVGA_data[][4] = {
-	{0xb0, 0x4d, 0x00, 0xcc},	{0xb3, 0x01, 0x01, 0xcc},
-	{0x00, 0x00, 0x50, 0xdd},	{0xb0, 0x03, 0x01, 0xcc},
+static const u8 hv7131r_initVGA_data[][4] = {
+	{0xb3, 0x01, 0x01, 0xcc},
+	{0xb0, 0x03, 0x19, 0xcc},
+	{0xb0, 0x04, 0x02, 0xcc},
+	{0x00, 0x00, 0x20, 0xdd},
 	{0xb3, 0x00, 0x24, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},	{0xb3, 0x08, 0x01, 0xcc},
-	{0xb3, 0x09, 0x0c, 0xcc},	{0xb3, 0x05, 0x00, 0xcc},
-	{0xb3, 0x06, 0x01, 0xcc},
-	{0xb3, 0x01, 0x45, 0xcc},	{0xb3, 0x03, 0x0b, 0xcc},
-	{0xb3, 0x04, 0x05, 0xcc},	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x05, 0x01, 0xcc},
+	{0xb3, 0x06, 0x03, 0xcc},
+	{0xb3, 0x01, 0x45, 0xcc},
+	{0xb3, 0x03, 0x0b, 0xcc},
+	{0xb3, 0x04, 0x05, 0xcc},
+	{0xb3, 0x20, 0x00, 0xcc},
 	{0xb3, 0x21, 0x00, 0xcc},
-	{0xb3, 0x22, 0x01, 0xcc},	{0xb3, 0x23, 0xe0, 0xcc},
-	{0xb3, 0x14, 0x00, 0xcc},	{0xb3, 0x15, 0x00, 0xcc},
+	{0xb3, 0x22, 0x01, 0xcc},
+	{0xb3, 0x23, 0xe0, 0xcc},
+	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x02, 0xcc},
 	{0xb3, 0x16, 0x02, 0xcc},
-	{0xb3, 0x17, 0x7f, 0xcc},	{0xb3, 0x34, 0x01, 0xcc},
-	{0xb3, 0x35, 0x91, 0xcc},	{0xb3, 0x00, 0x27, 0xcc},
+	{0xb3, 0x17, 0x7f, 0xcc},
+	{0xb3, 0x34, 0x01, 0xcc},
+	{0xb3, 0x35, 0x91, 0xcc},
+	{0xb3, 0x00, 0x27, 0xcc},
 	{0xbc, 0x00, 0x73, 0xcc},
-	{0xb8, 0x00, 0x23, 0xcc},	{0x00, 0x01, 0x0c, 0xaa},
-	{0x00, 0x14, 0x01, 0xaa},	{0x00, 0x15, 0xe6, 0xaa},
-	{0x00, 0x16, 0x02, 0xaa},
-	{0x00, 0x17, 0x86, 0xaa},	{0x00, 0x23, 0x00, 0xaa},
-	{0x00, 0x25, 0x09, 0xaa},	{0x00, 0x26, 0x27, 0xaa},
-	{0x00, 0x27, 0xc0, 0xaa},
-	{0xb8, 0x2c, 0x60, 0xcc},	{0xb8, 0x2d, 0xf8, 0xcc},
-	{0xb8, 0x2e, 0xf8, 0xcc},	{0xb8, 0x2f, 0xf8, 0xcc},
+	{0xb8, 0x00, 0x23, 0xcc},
+	{0xb8, 0x2c, 0x50, 0xcc},
+	{0xb8, 0x2d, 0xf8, 0xcc},
+	{0xb8, 0x2e, 0xf8, 0xcc},
+	{0xb8, 0x2f, 0xf8, 0xcc},
 	{0xb8, 0x30, 0x50, 0xcc},
-	{0xb8, 0x31, 0xf8, 0xcc},	{0xb8, 0x32, 0xf8, 0xcc},
-	{0xb8, 0x33, 0xf8, 0xcc},	{0xb8, 0x34, 0x65, 0xcc},
+	{0xb8, 0x31, 0xf8, 0xcc},
+	{0xb8, 0x32, 0xf8, 0xcc},
+	{0xb8, 0x33, 0xf8, 0xcc},
+	{0xb8, 0x34, 0x58, 0xcc},
 	{0xb8, 0x35, 0x00, 0xcc},
-	{0xb8, 0x36, 0x00, 0xcc},	{0xb8, 0x37, 0x00, 0xcc},
-	{0xb8, 0x27, 0x20, 0xcc},	{0xb8, 0x01, 0x7d, 0xcc},
+	{0xb8, 0x36, 0x00, 0xcc},
+	{0xb8, 0x37, 0x00, 0xcc},
+	{0xb8, 0x27, 0x20, 0xcc},
+	{0xb8, 0x01, 0x7d, 0xcc},
 	{0xb8, 0x81, 0x09, 0xcc},
-	{0xb3, 0x01, 0x41, 0xcc},	{0xb8, 0xfe, 0x00, 0xcc},
-	{0xb8, 0xff, 0x28, 0xcc},	{0xb9, 0x00, 0x28, 0xcc},
-	{0xb9, 0x01, 0x28, 0xcc},
-	{0xb9, 0x02, 0x28, 0xcc},	{0xb9, 0x03, 0x00, 0xcc},
-	{0xb9, 0x04, 0x00, 0xcc},	{0xb9, 0x05, 0x3c, 0xcc},
-	{0xb9, 0x06, 0x3c, 0xcc},
-	{0xb9, 0x07, 0x3c, 0xcc},	{0xb9, 0x08, 0x3c, 0xcc},
-	{0xb8, 0x8e, 0x00, 0xcc},	{0xb8, 0x8f, 0xff, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
+	{0xb8, 0x8e, 0x00, 0xcc},
+	{0xb8, 0x8f, 0xff, 0xcc},
+	{0x00, 0x01, 0x0c, 0xaa},
+	{0x00, 0x14, 0x01, 0xaa},
+	{0x00, 0x15, 0xe6, 0xaa},
+	{0x00, 0x16, 0x02, 0xaa},
+	{0x00, 0x17, 0x86, 0xaa},
+	{0x00, 0x23, 0x00, 0xaa},
+	{0x00, 0x25, 0x03, 0xaa},
+	{0x00, 0x26, 0xa9, 0xaa},
+	{0x00, 0x27, 0x80, 0xaa},
 	{0x00, 0x30, 0x18, 0xaa},
+	{0xb6, 0x00, 0x00, 0xcc},
+	{0xb6, 0x03, 0x02, 0xcc},
+	{0xb6, 0x02, 0x80, 0xcc},
+	{0xb6, 0x05, 0x01, 0xcc},
+	{0xb6, 0x04, 0xe0, 0xcc},
+	{0xb6, 0x12, 0x78, 0xcc},
+	{0xb6, 0x18, 0x02, 0xcc},
+	{0xb6, 0x17, 0x58, 0xcc},
+	{0xb6, 0x16, 0x00, 0xcc},
+	{0xb6, 0x22, 0x12, 0xcc},
+	{0xb6, 0x23, 0x0b, 0xcc},
+	{0xb3, 0x02, 0x02, 0xcc},
+	{0xbf, 0xc0, 0x39, 0xcc},
+	{0xbf, 0xc1, 0x04, 0xcc},
+	{0xbf, 0xcc, 0x10, 0xcc},
+	{0xb6, 0x12, 0xf8, 0xcc},
+	{0xb6, 0x13, 0x13, 0xcc},
+	{0xb9, 0x12, 0x00, 0xcc},
+	{0xb9, 0x13, 0x0a, 0xcc},
+	{0xb9, 0x14, 0x0a, 0xcc},
+	{0xb9, 0x15, 0x0a, 0xcc},
+	{0xb9, 0x16, 0x0a, 0xcc},
+	{0xb8, 0x0c, 0x20, 0xcc},
+	{0xb8, 0x0d, 0x70, 0xcc},
+	{0xb9, 0x18, 0x00, 0xcc},
+	{0xb9, 0x19, 0x0f, 0xcc},
+	{0xb9, 0x1a, 0x0f, 0xcc},
+	{0xb9, 0x1b, 0x0f, 0xcc},
+	{0xb9, 0x1c, 0x0f, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
 	{}
 };
 
-static const __u8 hv7131r_initQVGA_data[][4] = {
-	{0xb0, 0x4d, 0x00, 0xcc},	{0xb3, 0x01, 0x01, 0xcc},
-	{0x00, 0x00, 0x50, 0xdd},	{0xb0, 0x03, 0x01, 0xcc},
+static const u8 hv7131r_initQVGA_data[][4] = {
+	{0xb3, 0x01, 0x01, 0xcc},
+	{0xb0, 0x03, 0x19, 0xcc},
+	{0xb0, 0x04, 0x02, 0xcc},
+	{0x00, 0x00, 0x20, 0xdd},
 	{0xb3, 0x00, 0x24, 0xcc},
-	{0xb3, 0x00, 0x25, 0xcc},	{0xb3, 0x08, 0x01, 0xcc},
-	{0xb3, 0x09, 0x0c, 0xcc},	{0xb3, 0x05, 0x00, 0xcc},
-	{0xb3, 0x06, 0x01, 0xcc},
-	{0xb3, 0x03, 0x0b, 0xcc},	{0xb3, 0x04, 0x05, 0xcc},
-	{0xb3, 0x20, 0x00, 0xcc},	{0xb3, 0x21, 0x00, 0xcc},
+	{0xb3, 0x00, 0x25, 0xcc},
+	{0xb3, 0x08, 0x01, 0xcc},
+	{0xb3, 0x09, 0x0c, 0xcc},
+	{0xb3, 0x05, 0x01, 0xcc},
+	{0xb3, 0x06, 0x03, 0xcc},
+	{0xb3, 0x01, 0x45, 0xcc},
+	{0xb3, 0x03, 0x0b, 0xcc},
+	{0xb3, 0x04, 0x05, 0xcc},
+	{0xb3, 0x20, 0x00, 0xcc},
+	{0xb3, 0x21, 0x00, 0xcc},
 	{0xb3, 0x22, 0x01, 0xcc},
-	{0xb3, 0x23, 0xe0, 0xcc},	{0xb3, 0x14, 0x00, 0xcc},
-	{0xb3, 0x15, 0x00, 0xcc},	{0xb3, 0x16, 0x02, 0xcc},
+	{0xb3, 0x23, 0xe0, 0xcc},
+	{0xb3, 0x14, 0x00, 0xcc},
+	{0xb3, 0x15, 0x02, 0xcc},
+	{0xb3, 0x16, 0x02, 0xcc},
 	{0xb3, 0x17, 0x7f, 0xcc},
-	{0xb3, 0x34, 0x01, 0xcc},	{0xb3, 0x35, 0x91, 0xcc},
-	{0xb3, 0x00, 0x27, 0xcc},	{0xbc, 0x00, 0xd1, 0xcc},
-	{0xb8, 0x00, 0x21, 0xcc},
-	{0x00, 0x01, 0x0c, 0xaa},	{0x00, 0x14, 0x01, 0xaa},
-	{0x00, 0x15, 0xe6, 0xaa},	{0x00, 0x16, 0x02, 0xaa},
-	{0x00, 0x17, 0x86, 0xaa},
-	{0x00, 0x23, 0x00, 0xaa},	{0x00, 0x25, 0x01, 0xaa},
-	{0x00, 0x26, 0xd4, 0xaa},	{0x00, 0x27, 0xc0, 0xaa},
-	{0xbc, 0x02, 0x08, 0xcc},
-	{0xbc, 0x03, 0x70, 0xcc},	{0xbc, 0x04, 0x08, 0xcc},
-	{0xbc, 0x05, 0x00, 0xcc},	{0xbc, 0x06, 0x00, 0xcc},
-	{0xbc, 0x08, 0x3c, 0xcc},
-	{0xbc, 0x09, 0x40, 0xcc},	{0xbc, 0x0a, 0x04, 0xcc},
-	{0xbc, 0x0b, 0x00, 0xcc},	{0xbc, 0x0c, 0x00, 0xcc},
-	{0xb8, 0xfe, 0x02, 0xcc},
-	{0xb8, 0xff, 0x07, 0xcc},	{0xb9, 0x00, 0x14, 0xcc},
-	{0xb9, 0x01, 0x14, 0xcc},	{0xb9, 0x02, 0x14, 0xcc},
-	{0xb9, 0x03, 0x00, 0xcc},
-	{0xb9, 0x04, 0x02, 0xcc},	{0xb9, 0x05, 0x05, 0xcc},
-	{0xb9, 0x06, 0x0f, 0xcc},	{0xb9, 0x07, 0x0f, 0xcc},
-	{0xb9, 0x08, 0x0f, 0xcc},
-	{0xb8, 0x2c, 0x60, 0xcc},	{0xb8, 0x2d, 0xf8, 0xcc},
-	{0xb8, 0x2e, 0xf8, 0xcc},	{0xb8, 0x2f, 0xf8, 0xcc},
+	{0xb3, 0x34, 0x01, 0xcc},
+	{0xb3, 0x35, 0x91, 0xcc},
+	{0xb3, 0x00, 0x27, 0xcc},
+	{0xbc, 0x00, 0xd3, 0xcc},
+	{0xb8, 0x00, 0x23, 0xcc},
+	{0xb8, 0x2c, 0x50, 0xcc},
+	{0xb8, 0x2d, 0xf8, 0xcc},
+	{0xb8, 0x2e, 0xf8, 0xcc},
+	{0xb8, 0x2f, 0xf8, 0xcc},
 	{0xb8, 0x30, 0x50, 0xcc},
-	{0xb8, 0x31, 0xf8, 0xcc},	{0xb8, 0x32, 0xf8, 0xcc},
+	{0xb8, 0x31, 0xf8, 0xcc},
+	{0xb8, 0x32, 0xf8, 0xcc},
 	{0xb8, 0x33, 0xf8, 0xcc},
-	{0xb8, 0x34, 0x65, 0xcc},	{0xb8, 0x35, 0x00, 0xcc},
-	{0xb8, 0x36, 0x00, 0xcc},	{0xb8, 0x37, 0x00, 0xcc},
+	{0xb8, 0x34, 0x58, 0xcc},
+	{0xb8, 0x35, 0x00, 0xcc},
+	{0xb8, 0x36, 0x00, 0xcc},
+	{0xb8, 0x37, 0x00, 0xcc},
 	{0xb8, 0x27, 0x20, 0xcc},
-	{0xb8, 0x01, 0x7d, 0xcc},	{0xb8, 0x81, 0x09, 0xcc},
-	{0xb3, 0x01, 0x41, 0xcc},	{0xb8, 0xfe, 0x00, 0xcc},
-	{0xb8, 0xff, 0x28, 0xcc},
-	{0xb9, 0x00, 0x28, 0xcc},	{0xb9, 0x01, 0x28, 0xcc},
-	{0xb9, 0x02, 0x28, 0xcc},	{0xb9, 0x03, 0x00, 0xcc},
-	{0xb9, 0x04, 0x00, 0xcc},
-	{0xb9, 0x05, 0x3c, 0xcc},	{0xb9, 0x06, 0x3c, 0xcc},
-	{0xb9, 0x07, 0x3c, 0xcc},	{0xb9, 0x08, 0x3c, 0xcc},
+	{0xb8, 0x01, 0x7d, 0xcc},
+	{0xb8, 0x81, 0x09, 0xcc},
+	{0xb3, 0x01, 0x41, 0xcc},
 	{0xb8, 0x8e, 0x00, 0xcc},
-	{0xb8, 0x8f, 0xff, 0xcc},	{0x00, 0x30, 0x18, 0xaa},
+	{0xb8, 0x8f, 0xff, 0xcc},
+	{0x00, 0x01, 0x0c, 0xaa},
+	{0x00, 0x14, 0x01, 0xaa},
+	{0x00, 0x15, 0xe6, 0xaa},
+	{0x00, 0x16, 0x02, 0xaa},
+	{0x00, 0x17, 0x86, 0xaa},
+	{0x00, 0x23, 0x00, 0xaa},
+	{0x00, 0x25, 0x03, 0xaa},
+	{0x00, 0x26, 0xa9, 0xaa},
+	{0x00, 0x27, 0x80, 0xaa},
+	{0x00, 0x30, 0x18, 0xaa},
+	{0xb6, 0x00, 0x00, 0xcc},
+	{0xb6, 0x03, 0x01, 0xcc},
+	{0xb6, 0x02, 0x40, 0xcc},
+	{0xb6, 0x05, 0x00, 0xcc},
+	{0xb6, 0x04, 0xf0, 0xcc},
+	{0xb6, 0x12, 0x78, 0xcc},
+	{0xb6, 0x18, 0x00, 0xcc},
+	{0xb6, 0x17, 0x96, 0xcc},
+	{0xb6, 0x16, 0x00, 0xcc},
+	{0xb6, 0x22, 0x12, 0xcc},
+	{0xb6, 0x23, 0x0b, 0xcc},
+	{0xb3, 0x02, 0x02, 0xcc},
+	{0xbf, 0xc0, 0x39, 0xcc},
+	{0xbf, 0xc1, 0x04, 0xcc},
+	{0xbf, 0xcc, 0x10, 0xcc},
+	{0xbc, 0x02, 0x18, 0xcc},
+	{0xbc, 0x03, 0x50, 0xcc},
+	{0xbc, 0x04, 0x18, 0xcc},
+	{0xbc, 0x05, 0x00, 0xcc},
+	{0xbc, 0x06, 0x00, 0xcc},
+	{0xbc, 0x08, 0x30, 0xcc},
+	{0xbc, 0x09, 0x40, 0xcc},
+	{0xbc, 0x0a, 0x10, 0xcc},
+	{0xbc, 0x0b, 0x00, 0xcc},
+	{0xbc, 0x0c, 0x00, 0xcc},
+	{0xb9, 0x12, 0x00, 0xcc},
+	{0xb9, 0x13, 0x0a, 0xcc},
+	{0xb9, 0x14, 0x0a, 0xcc},
+	{0xb9, 0x15, 0x0a, 0xcc},
+	{0xb9, 0x16, 0x0a, 0xcc},
+	{0xb9, 0x18, 0x00, 0xcc},
+	{0xb9, 0x19, 0x0f, 0xcc},
+	{0xb8, 0x0c, 0x20, 0xcc},
+	{0xb8, 0x0d, 0x70, 0xcc},
+	{0xb9, 0x1a, 0x0f, 0xcc},
+	{0xb9, 0x1b, 0x0f, 0xcc},
+	{0xb9, 0x1c, 0x0f, 0xcc},
+	{0xb6, 0x12, 0xf8, 0xcc},
+	{0xb6, 0x13, 0x13, 0xcc},
+	{0xb3, 0x5c, 0x01, 0xcc},
 	{}
 };
 
-static const __u8 ov7660_gamma[17] = {
+static const u8 ov7660_gamma[17] = {
 	0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
 	0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
 };
-static const __u8 ov7660_matrix[9] = {
+static const u8 ov7660_matrix[9] = {
 	0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62
 };
-static const __u8 ov7660_initVGA_data[][4] = {
+static const u8 ov7660_initVGA_data[][4] = {
 	{0xb0, 0x4d, 0x00, 0xcc},	{0xb3, 0x01, 0x01, 0xcc},
 	{0x00, 0x00, 0x50, 0xdd},
 	{0xb0, 0x03, 0x01, 0xcc},
@@ -1613,7 +1789,7 @@ static const __u8 ov7660_initVGA_data[][4] = {
 	{0x00, 0x29, 0x3c, 0xaa},	{0xb3, 0x01, 0x45, 0xcc},
 	{}
 };
-static const __u8 ov7660_initQVGA_data[][4] = {
+static const u8 ov7660_initQVGA_data[][4] = {
 	{0xb0, 0x4d, 0x00, 0xcc},	{0xb3, 0x01, 0x01, 0xcc},
 	{0x00, 0x00, 0x50, 0xdd},	{0xb0, 0x03, 0x01, 0xcc},
 	{0xb3, 0x00, 0x21, 0xcc},	{0xb3, 0x00, 0x26, 0xcc},
@@ -1682,26 +1858,26 @@ static const __u8 ov7660_initQVGA_data[][4] = {
 	{}
 };
 
-static const __u8 ov7660_50HZ[][4] = {
+static const u8 ov7660_50HZ[][4] = {
 	{0x00, 0x3b, 0x08, 0xaa},
 	{0x00, 0x9d, 0x40, 0xaa},
 	{0x00, 0x13, 0xa7, 0xaa},
 	{}
 };
 
-static const __u8 ov7660_60HZ[][4] = {
+static const u8 ov7660_60HZ[][4] = {
 	{0x00, 0x3b, 0x00, 0xaa},
 	{0x00, 0x9e, 0x40, 0xaa},
 	{0x00, 0x13, 0xa7, 0xaa},
 	{}
 };
 
-static const __u8 ov7660_NoFliker[][4] = {
+static const u8 ov7660_NoFliker[][4] = {
 	{0x00, 0x13, 0x87, 0xaa},
 	{}
 };
 
-static const __u8 ov7670_initVGA_JPG[][4] = {
+static const u8 ov7670_initVGA_JPG[][4] = {
 	{0xb3, 0x01, 0x05, 0xcc},
 	{0x00, 0x00, 0x30, 0xdd},	{0xb0, 0x03, 0x19, 0xcc},
 	{0x00, 0x00, 0x10, 0xdd},
@@ -1831,7 +2007,7 @@ static const __u8 ov7670_initVGA_JPG[][4] = {
 	{},
 };
 
-static const __u8 ov7670_initQVGA_JPG[][4] = {
+static const u8 ov7670_initQVGA_JPG[][4] = {
 	{0xb3, 0x01, 0x05, 0xcc},	{0x00, 0x00, 0x30, 0xdd},
 	{0xb0, 0x03, 0x19, 0xcc},	{0x00, 0x00, 0x10, 0xdd},
 	{0xb0, 0x04, 0x02, 0xcc},	{0x00, 0x00, 0x10, 0xdd},
@@ -1966,14 +2142,14 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
 };
 
 /* PO1200 - values from usbvm326.inf and ms-win trace */
-static const __u8 po1200_gamma[17] = {
+static const u8 po1200_gamma[17] = {
 	0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
 	0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
 };
-static const __u8 po1200_matrix[9] = {
+static const u8 po1200_matrix[9] = {
 	0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e
 };
-static const __u8 po1200_initVGA_data[][4] = {
+static const u8 po1200_initVGA_data[][4] = {
 	{0xb0, 0x03, 0x19, 0xcc},	/* reset? */
 	{0xb0, 0x03, 0x19, 0xcc},
 /*	{0x00, 0x00, 0x33, 0xdd}, */
@@ -2276,9 +2452,9 @@ static const struct sensor_info sensor_info_data[] = {
 
 /* read 'len' bytes in gspca_dev->usb_buf */
 static void reg_r(struct gspca_dev *gspca_dev,
-		  __u16 req,
-		  __u16 index,
-		  __u16 len)
+		  u16 req,
+		  u16 index,
+		  u16 len)
 {
 	usb_control_msg(gspca_dev->dev,
 			usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -2290,9 +2466,9 @@ static void reg_r(struct gspca_dev *gspca_dev,
 }
 
 static void reg_w(struct usb_device *dev,
-			    __u16 req,
-			    __u16 value,
-			    __u16 index)
+			    u16 req,
+			    u16 value,
+			    u16 index)
 {
 	usb_control_msg(dev,
 			usb_sndctrlpipe(dev, 0),
@@ -2342,11 +2518,18 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev,
 
 static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
 	struct usb_device *dev = gspca_dev->dev;
 	int i;
 	u16 value;
 	const struct sensor_info *ptsensor_info;
 
+/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/
+	if (sd->flags & FL_SAMSUNG) {
+		reg_w(dev, 0xa0, 0x01, 0xb301);
+		reg_w(dev, 0x89, 0xf0ff, 0xffff); /* select the back sensor */
+	}
+
 	reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
 	PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]);
 	for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
@@ -2406,17 +2589,17 @@ static void i2c_write(struct gspca_dev *gspca_dev,
 }
 
 static void put_tab_to_reg(struct gspca_dev *gspca_dev,
-			const __u8 *tab, __u8 tabsize, __u16 addr)
+			const u8 *tab, u8 tabsize, u16 addr)
 {
 	int j;
-	__u16 ad = addr;
+	u16 ad = addr;
 
 	for (j = 0; j < tabsize; j++)
 		reg_w(gspca_dev->dev, 0xa0, tab[j], ad++);
 }
 
 static void usb_exchange(struct gspca_dev *gspca_dev,
-			const __u8 data[][4])
+			const u8 data[][4])
 {
 	struct usb_device *dev = gspca_dev->dev;
 	int i = 0;
@@ -2466,7 +2649,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
 	};
 
 	cam = &gspca_dev->cam;
-	sd->bridge = id->driver_info;
+	sd->bridge = id->driver_info >> 8;
+	sd->flags = id->driver_info & 0xff;
 	sensor = vc032x_probe_sensor(gspca_dev);
 	switch (sensor) {
 	case -1:
@@ -2519,8 +2703,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
 		case SENSOR_MI1320_SOC:
 			cam->cam_mode = bi_mode;
 			cam->nmodes = ARRAY_SIZE(bi_mode);
-			cam->input_flags = V4L2_IN_ST_VFLIP |
-					   V4L2_IN_ST_HFLIP;
 			break;
 		default:
 			cam->cam_mode = vc0323_mode;
@@ -2532,14 +2714,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
 
 	sd->hflip = HFLIP_DEF;
 	sd->vflip = VFLIP_DEF;
-	if (sd->sensor == SENSOR_OV7670) {
-		sd->hflip = 1;
-		sd->vflip = 1;
-	}
+	if (sd->sensor == SENSOR_OV7670)
+		sd->flags |= FL_HFLIP | FL_VFLIP;
 	sd->lightfreq = FREQ_DEF;
 	if (sd->sensor != SENSOR_OV7670)
 		gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
 	switch (sd->sensor) {
+	case SENSOR_MI1310_SOC:
+	case SENSOR_MI1320_SOC:
 	case SENSOR_OV7660:
 	case SENSOR_OV7670:
 	case SENSOR_PO1200:
@@ -2568,39 +2750,50 @@ static int sd_init(struct gspca_dev *gspca_dev)
 	return 0;
 }
 
-/* for OV7660 and OV7670 only */
+/* some sensors only */
 static void sethvflip(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 data;
-
+	u8 data[2], hflip, vflip;
+
+	hflip = sd->hflip;
+	if (sd->flags & FL_HFLIP)
+		hflip = !hflip;
+	vflip = sd->vflip;
+	if (sd->flags & FL_VFLIP)
+		vflip = !vflip;
 	switch (sd->sensor) {
-	case SENSOR_OV7660:
-		data = 1;
+	case SENSOR_MI1310_SOC:
+	case SENSOR_MI1320_SOC:
+		data[0] = data[1] = 0;		/* select page 0 */
+		i2c_write(gspca_dev, 0xf0, data, 2);
+		data[0] = sd->sensor == SENSOR_MI1310_SOC ? 0x03 : 0x01;
+		data[1] = 0x02 * hflip
+			| 0x01 * vflip;
+		i2c_write(gspca_dev, 0x20, data, 2);
 		break;
+	case SENSOR_OV7660:
 	case SENSOR_OV7670:
-		data = 7;
+		data[0] = sd->sensor == SENSOR_OV7660 ? 0x01 : 0x07;
+		data[0] |= OV7660_MVFP_MIRROR * hflip
+			| OV7660_MVFP_VFLIP * vflip;
+		i2c_write(gspca_dev, OV7660_REG_MVFP, data, 1);
 		break;
 	case SENSOR_PO1200:
-		data = 0;
-		i2c_write(gspca_dev, 0x03, &data, 1);
-		data = 0x80 * sd->hflip
-			| 0x40 * sd->vflip
+		data[0] = 0;
+		i2c_write(gspca_dev, 0x03, data, 1);
+		data[0] = 0x80 * hflip
+			| 0x40 * vflip
 			| 0x06;
-		i2c_write(gspca_dev, 0x1e, &data, 1);
-		return;
-	default:
-		return;
+		i2c_write(gspca_dev, 0x1e, data, 1);
+		break;
 	}
-	data |= OV7660_MVFP_MIRROR * sd->hflip
-		| OV7660_MVFP_VFLIP * sd->vflip;
-	i2c_write(gspca_dev, OV7660_REG_MVFP, &data, 1);
 }
 
 static void setlightfreq(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	static const __u8 (*ov7660_freq_tb[3])[4] =
+	static const u8 (*ov7660_freq_tb[3])[4] =
 		{ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ};
 
 	if (sd->sensor != SENSOR_OV7660)
@@ -2612,7 +2805,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
 static void setsharpness(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	__u8 data;
+	u8 data;
 
 	if (sd->sensor != SENSOR_PO1200)
 		return;
@@ -2625,9 +2818,9 @@ static void setsharpness(struct gspca_dev *gspca_dev)
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	const __u8 (*init)[4];
-	const __u8 *GammaT = NULL;
-	const __u8 *MatrixT = NULL;
+	const u8 (*init)[4];
+	const u8 *GammaT = NULL;
+	const u8 *MatrixT = NULL;
 	int mode;
 	static const u8 (*mi1320_soc_init[])[4] = {
 		mi1320_soc_InitSXGA,
@@ -2635,6 +2828,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		mi1320_soc_InitQVGA,
 	};
 
+/*fixme: back sensor only*/
+	if (sd->flags & FL_SAMSUNG) {
+		reg_w(gspca_dev->dev, 0x89, 0xf0ff, 0xffff);
+		reg_w(gspca_dev->dev, 0xa9, 0x8348, 0x000e);
+		reg_w(gspca_dev->dev, 0xa9, 0x0000, 0x001a);
+	}
+
 	/* Assume start use the good resolution from gspca_dev->mode */
 	if (sd->bridge == BRIDGE_VC0321) {
 		reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec);
@@ -2737,16 +2937,23 @@ static int sd_start(struct gspca_dev *gspca_dev)
 		put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
 
 		/* set the led on 0x0892 0x0896 */
-		if (sd->sensor != SENSOR_PO1200) {
-			reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
-			msleep(100);
-			sethvflip(gspca_dev);
-			setlightfreq(gspca_dev);
-		} else {
-			setsharpness(gspca_dev);
-			sethvflip(gspca_dev);
+		switch (sd->sensor) {
+		case SENSOR_PO1200:
+		case SENSOR_HV7131R:
 			reg_w(gspca_dev->dev, 0x89, 0x0400, 0x1415);
+			break;
+		case SENSOR_MI1310_SOC:
+			reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
+			break;
+		default:
+			if (!(sd->flags & FL_SAMSUNG))
+				reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
+			break;
 		}
+		msleep(100);
+		setsharpness(gspca_dev);
+		sethvflip(gspca_dev);
+		setlightfreq(gspca_dev);
 	}
 	return 0;
 }
@@ -2754,8 +2961,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
 static void sd_stopN(struct gspca_dev *gspca_dev)
 {
 	struct usb_device *dev = gspca_dev->dev;
+	struct sd *sd = (struct sd *) gspca_dev;
 
-	reg_w(dev, 0x89, 0xffff, 0xffff);
+	if (sd->sensor == SENSOR_MI1310_SOC)
+		reg_w(dev, 0x89, 0x058c, 0x00ff);
+	else if (!(sd->flags & FL_SAMSUNG))
+		reg_w(dev, 0x89, 0xffff, 0xffff);
 	reg_w(dev, 0xa0, 0x01, 0xb301);
 	reg_w(dev, 0xa0, 0x09, 0xb003);
 }
@@ -2764,15 +2975,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
 static void sd_stop0(struct gspca_dev *gspca_dev)
 {
 	struct usb_device *dev = gspca_dev->dev;
+	struct sd *sd = (struct sd *) gspca_dev;
 
 	if (!gspca_dev->present)
 		return;
-	reg_w(dev, 0x89, 0xffff, 0xffff);
+/*fixme: is this useful?*/
+	if (sd->sensor == SENSOR_MI1310_SOC)
+		reg_w(dev, 0x89, 0x058c, 0x00ff);
+	else if (!(sd->flags & FL_SAMSUNG))
+		reg_w(dev, 0x89, 0xffff, 0xffff);
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
-			__u8 *data,			/* isoc packet */
+			u8 *data,			/* isoc packet */
 			int len)			/* iso pkt length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -2872,21 +3088,12 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
 static int sd_querymenu(struct gspca_dev *gspca_dev,
 			struct v4l2_querymenu *menu)
 {
+	static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
+
 	switch (menu->id) {
 	case V4L2_CID_POWER_LINE_FREQUENCY:
-		switch (menu->index) {
-		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
-			strcpy((char *) menu->name, "NoFliker");
-			return 0;
-		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
-			strcpy((char *) menu->name, "50 Hz");
-			return 0;
-		default:
-/*		case 2:		 * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
-			strcpy((char *) menu->name, "60 Hz");
-			return 0;
-		}
-		break;
+		strcpy((char *) menu->name, freq_nm[menu->index]);
+		return 0;
 	}
 	return -EINVAL;
 }
@@ -2906,19 +3113,23 @@ static const struct sd_desc sd_desc = {
 };
 
 /* -- module initialisation -- */
+#define BF(bridge, flags) \
+	.driver_info = (BRIDGE_ ## bridge << 8) \
+		| (flags)
 static const __devinitdata struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323},
-	{USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
-	{USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
-	{USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
-	{USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321},
-	{USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323},
-	{USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
-	{USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
-	{USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
-	{USB_DEVICE(0x15b8, 0x6001), .driver_info = BRIDGE_VC0323},
-	{USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323},
-	{USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
+	{USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
+	{USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
+	{USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},
+	{USB_DEVICE(0x046d, 0x0897), BF(VC0321, 0)},
+	{USB_DEVICE(0x0ac8, 0x0321), BF(VC0321, 0)},
+	{USB_DEVICE(0x0ac8, 0x0323), BF(VC0323, 0)},
+	{USB_DEVICE(0x0ac8, 0x0328), BF(VC0321, 0)},
+	{USB_DEVICE(0x0ac8, 0xc001), BF(VC0321, 0)},
+	{USB_DEVICE(0x0ac8, 0xc002), BF(VC0321, 0)},
+	{USB_DEVICE(0x0ac8, 0xc301), BF(VC0323, FL_SAMSUNG)},
+	{USB_DEVICE(0x15b8, 0x6001), BF(VC0323, 0)},
+	{USB_DEVICE(0x15b8, 0x6002), BF(VC0323, 0)},
+	{USB_DEVICE(0x17ef, 0x4802), BF(VC0323, 0)},
 	{}
 };
 MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 3d2756f..cdf3357 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -7574,7 +7574,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
 static const struct sd_desc sd_desc = {
 	.name = MODULE_NAME,
 	.ctrls = sd_ctrls,
-	.nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
+	.nctrls = ARRAY_SIZE(sd_ctrls),
 	.config = sd_config,
 	.init = sd_init,
 	.start = sd_start,
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c
index 0679174..5a6b78b 100644
--- a/drivers/media/video/hdpvr/hdpvr-control.c
+++ b/drivers/media/video/hdpvr/hdpvr-control.c
@@ -178,24 +178,24 @@ error:
 
 int hdpvr_set_options(struct hdpvr_device *dev)
 {
-       hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);
+	hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);
 
-       hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,
+	hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,
 			 dev->options.video_input+1);
 
-       hdpvr_set_audio(dev, dev->options.audio_input+1,
+	hdpvr_set_audio(dev, dev->options.audio_input+1,
 		       dev->options.audio_codec);
 
-       hdpvr_set_bitrate(dev);
-       hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+	hdpvr_set_bitrate(dev);
+	hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
 			 dev->options.bitrate_mode);
-       hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);
+	hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);
 
-       hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);
-       hdpvr_config_call(dev, CTRL_CONTRAST,   dev->options.contrast);
-       hdpvr_config_call(dev, CTRL_HUE,        dev->options.hue);
-       hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);
-       hdpvr_config_call(dev, CTRL_SHARPNESS,  dev->options.sharpness);
+	hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);
+	hdpvr_config_call(dev, CTRL_CONTRAST,   dev->options.contrast);
+	hdpvr_config_call(dev, CTRL_HUE,        dev->options.hue);
+	hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);
+	hdpvr_config_call(dev, CTRL_SHARPNESS,  dev->options.sharpness);
 
-       return 0;
+	return 0;
 }
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 188bd5a..1c9bc94 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -126,7 +126,7 @@ static int device_authorization(struct hdpvr_device *dev)
 	char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
 	if (!print_buf) {
 		v4l2_err(&dev->v4l2_dev, "Out of memory\n");
-		goto error;
+		return retval;
 	}
 #endif
 
@@ -140,7 +140,7 @@ static int device_authorization(struct hdpvr_device *dev)
 	if (ret != 46) {
 		v4l2_err(&dev->v4l2_dev,
 			 "unexpected answer of status request, len %d\n", ret);
-		goto error;
+		goto unlock;
 	}
 #ifdef HDPVR_DEBUG
 	else {
@@ -163,7 +163,7 @@ static int device_authorization(struct hdpvr_device *dev)
 		v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n",
 			dev->usbc_buf[1]);
 		ret = -EINVAL;
-		goto error;
+		goto unlock;
 	}
 
 	response = dev->usbc_buf+38;
@@ -188,10 +188,10 @@ static int device_authorization(struct hdpvr_device *dev)
 			      10000);
 	v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
 		 "magic request returned %d\n", ret);
-	mutex_unlock(&dev->usbc_mutex);
 
 	retval = ret != 8;
-error:
+unlock:
+	mutex_unlock(&dev->usbc_mutex);
 	return retval;
 }
 
@@ -350,6 +350,7 @@ static int hdpvr_probe(struct usb_interface *interface,
 
 	mutex_lock(&dev->io_mutex);
 	if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
+		mutex_unlock(&dev->io_mutex);
 		v4l2_err(&dev->v4l2_dev,
 			 "allocating transfer buffers failed\n");
 		goto error;
@@ -381,7 +382,6 @@ static int hdpvr_probe(struct usb_interface *interface,
 
 error:
 	if (dev) {
-		mutex_unlock(&dev->io_mutex);
 		/* this frees allocated memory */
 		hdpvr_delete(dev);
 	}
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index c4b5d15..296330a 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -127,7 +127,6 @@ int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
 		sizeof(i2c_adap->name));
 	i2c_adap->algo  = &hdpvr_algo;
 	i2c_adap->class = I2C_CLASS_TV_ANALOG;
-	i2c_adap->id    = I2C_HW_B_HDPVR;
 	i2c_adap->owner = THIS_MODULE;
 	i2c_adap->dev.parent = &dev->udev->dev;
 
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index d678765..2eb9dc2 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -375,6 +375,7 @@ static int hdpvr_open(struct file *file)
 	 * in resumption */
 	mutex_lock(&dev->io_mutex);
 	dev->open_count++;
+	mutex_unlock(&dev->io_mutex);
 
 	fh->dev = dev;
 
@@ -383,7 +384,6 @@ static int hdpvr_open(struct file *file)
 
 	retval = 0;
 err:
-	mutex_unlock(&dev->io_mutex);
 	return retval;
 }
 
@@ -519,8 +519,10 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
 
 	mutex_lock(&dev->io_mutex);
 
-	if (video_is_unregistered(dev->video_dev))
+	if (video_is_unregistered(dev->video_dev)) {
+		mutex_unlock(&dev->io_mutex);
 		return -EIO;
+	}
 
 	if (dev->status == STATUS_IDLE) {
 		if (hdpvr_start_streaming(dev)) {
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 86f2fef..247d311 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -122,12 +122,12 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
 	return 1;
 }
 
-static inline int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
 	return get_key_haup_common (ir, ir_key, ir_raw, 3, 0);
 }
 
-static inline int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+static int get_key_haup_xvr(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 {
 	return get_key_haup_common (ir, ir_key, ir_raw, 6, 3);
 }
@@ -297,7 +297,7 @@ static void ir_work(struct work_struct *work)
 
 static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
-	IR_KEYTAB_TYPE *ir_codes = NULL;
+	struct ir_scancode_table *ir_codes = NULL;
 	const char *name = NULL;
 	int ir_type;
 	struct IR_i2c *ir;
@@ -322,13 +322,13 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		name        = "Pixelview";
 		ir->get_key = get_key_pixelview;
 		ir_type     = IR_TYPE_OTHER;
-		ir_codes    = ir_codes_empty;
+		ir_codes    = &ir_codes_empty_table;
 		break;
 	case 0x4b:
 		name        = "PV951";
 		ir->get_key = get_key_pv951;
 		ir_type     = IR_TYPE_OTHER;
-		ir_codes    = ir_codes_pv951;
+		ir_codes    = &ir_codes_pv951_table;
 		break;
 	case 0x18:
 	case 0x1a:
@@ -336,36 +336,38 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		ir->get_key = get_key_haup;
 		ir_type     = IR_TYPE_RC5;
 		if (hauppauge == 1) {
-			ir_codes    = ir_codes_hauppauge_new;
+			ir_codes    = &ir_codes_hauppauge_new_table;
 		} else {
-			ir_codes    = ir_codes_rc5_tv;
+			ir_codes    = &ir_codes_rc5_tv_table;
 		}
 		break;
 	case 0x30:
 		name        = "KNC One";
 		ir->get_key = get_key_knc1;
 		ir_type     = IR_TYPE_OTHER;
-		ir_codes    = ir_codes_empty;
+		ir_codes    = &ir_codes_empty_table;
 		break;
 	case 0x6b:
 		name        = "FusionHDTV";
 		ir->get_key = get_key_fusionhdtv;
 		ir_type     = IR_TYPE_RC5;
-		ir_codes    = ir_codes_fusionhdtv_mce;
+		ir_codes    = &ir_codes_fusionhdtv_mce_table;
 		break;
 	case 0x7a:
 	case 0x47:
 	case 0x71:
 	case 0x2d:
-		if (adap->id == I2C_HW_B_CX2388x) {
+		if (adap->id == I2C_HW_B_CX2388x ||
+		    adap->id == I2C_HW_B_CX2341X) {
 			/* Handled by cx88-input */
-			name        = "CX2388x remote";
+			name = adap->id == I2C_HW_B_CX2341X ? "CX2341x remote"
+							    : "CX2388x remote";
 			ir_type     = IR_TYPE_RC5;
 			ir->get_key = get_key_haup_xvr;
 			if (hauppauge == 1) {
-				ir_codes    = ir_codes_hauppauge_new;
+				ir_codes    = &ir_codes_hauppauge_new_table;
 			} else {
-				ir_codes    = ir_codes_rc5_tv;
+				ir_codes    = &ir_codes_rc5_tv_table;
 			}
 		} else {
 			/* Handled by saa7134-input */
@@ -377,7 +379,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		name        = "AVerMedia Cardbus remote";
 		ir->get_key = get_key_avermedia_cardbus;
 		ir_type     = IR_TYPE_OTHER;
-		ir_codes    = ir_codes_avermedia_cardbus;
+		ir_codes    = &ir_codes_avermedia_cardbus_table;
 		break;
 	default:
 		dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
@@ -392,7 +394,36 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 		ir_codes = init_data->ir_codes;
 		name = init_data->name;
-		ir->get_key = init_data->get_key;
+		if (init_data->type)
+			ir_type = init_data->type;
+
+		switch (init_data->internal_get_key_func) {
+		case IR_KBD_GET_KEY_CUSTOM:
+			/* The bridge driver provided us its own function */
+			ir->get_key = init_data->get_key;
+			break;
+		case IR_KBD_GET_KEY_PIXELVIEW:
+			ir->get_key = get_key_pixelview;
+			break;
+		case IR_KBD_GET_KEY_PV951:
+			ir->get_key = get_key_pv951;
+			break;
+		case IR_KBD_GET_KEY_HAUP:
+			ir->get_key = get_key_haup;
+			break;
+		case IR_KBD_GET_KEY_KNC1:
+			ir->get_key = get_key_knc1;
+			break;
+		case IR_KBD_GET_KEY_FUSIONHDTV:
+			ir->get_key = get_key_fusionhdtv;
+			break;
+		case IR_KBD_GET_KEY_HAUP_XVR:
+			ir->get_key = get_key_haup_xvr;
+			break;
+		case IR_KBD_GET_KEY_AVERMEDIA_CARDBUS:
+			ir->get_key = get_key_avermedia_cardbus;
+			break;
+		}
 	}
 
 	/* Make sure we are all setup before going on */
@@ -454,7 +485,8 @@ static int ir_remove(struct i2c_client *client)
 static const struct i2c_device_id ir_kbd_id[] = {
 	/* Generic entry for any IR receiver */
 	{ "ir_video", 0 },
-	/* IR device specific entries could be added here */
+	/* IR device specific entries should be added here */
+	{ "ir_rx_z8f0811_haup", 0 },
 	{ }
 };
 
diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c
index 2883c87..4873b6c 100644
--- a/drivers/media/video/ivtv/ivtv-cards.c
+++ b/drivers/media/video/ivtv/ivtv-cards.c
@@ -977,26 +977,27 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
 
 /* ------------------------------------------------------------------------- */
 
-/* AVerMedia PVR-150 Plus (M113) card */
+/* AVerMedia PVR-150 Plus / AVerTV M113 cards with a Daewoo/Partsnic Tuner */
 
 static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = {
-	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 },
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc034 }, /* NTSC */
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 }, /* NTSC FM */
 	{ 0, 0, 0 }
 };
 
 static const struct ivtv_card ivtv_card_aver_pvr150 = {
 	.type = IVTV_CARD_AVER_PVR150PLUS,
-	.name = "AVerMedia PVR-150 Plus",
+	.name = "AVerMedia PVR-150 Plus / AVerTV M113 Partsnic (Daewoo) Tuner",
 	.v4l2_capabilities = IVTV_CAP_ENCODER,
 	.hw_video = IVTV_HW_CX25840,
 	.hw_audio = IVTV_HW_CX25840,
 	.hw_audio_ctrl = IVTV_HW_CX25840,
 	.hw_muxer = IVTV_HW_GPIO,
-	.hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
+	.hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
+		  IVTV_HW_WM8739 | IVTV_HW_GPIO,
 	.video_inputs = {
 		{ IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE2 },
-		{ IVTV_CARD_INPUT_SVIDEO1,    1,
-		  CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
+		{ IVTV_CARD_INPUT_SVIDEO1,    1, CX25840_SVIDEO3    },
 		{ IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
 	},
 	.audio_inputs = {
@@ -1004,18 +1005,66 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = {
 		{ IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL, 1 },
 	},
 	.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
-	.gpio_init = { .direction = 0x0800, .initial_value = 0 },
-	.gpio_audio_input  = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
+	/* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
+	.gpio_init = { .direction = 0xc000, .initial_value = 0 },
+	.gpio_audio_input  = { .mask   = 0xc000,
+			       .tuner  = 0x0000,
+			       .linein = 0x4000,
+			       .radio  = 0x8000 },
 	.tuners = {
-		/* This card has a Partsnic PTI-5NF05 tuner */
-		{ .std = V4L2_STD_MN, .tuner = TUNER_TCL_2002N },
+		/* Subsystem ID's 0xc03[45] have a Partsnic PTI-5NF05 tuner */
+		{ .std = V4L2_STD_MN, .tuner = TUNER_PARTSNIC_PTI_5NF05 },
 	},
 	.pci_list = ivtv_pci_aver_pvr150,
+	/* Subsystem ID 0xc035 has a TEA5767(?) FM tuner, 0xc034 does not */
 	.i2c = &ivtv_i2c_radio,
 };
 
 /* ------------------------------------------------------------------------- */
 
+/* AVerMedia UltraTV 1500 MCE (newer non-cx88 version, M113 variant) card */
+
+static const struct ivtv_card_pci_info ivtv_pci_aver_ultra1500mce[] = {
+	{ PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc019 },
+	{ 0, 0, 0 }
+};
+
+static const struct ivtv_card ivtv_card_aver_ultra1500mce = {
+	.type = IVTV_CARD_AVER_ULTRA1500MCE,
+	.name = "AVerMedia UltraTV 1500 MCE / AVerTV M113 Philips Tuner",
+	.v4l2_capabilities = IVTV_CAP_ENCODER,
+	.hw_video = IVTV_HW_CX25840,
+	.hw_audio = IVTV_HW_CX25840,
+	.hw_audio_ctrl = IVTV_HW_CX25840,
+	.hw_muxer = IVTV_HW_GPIO,
+	.hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER |
+		  IVTV_HW_WM8739 | IVTV_HW_GPIO,
+	.video_inputs = {
+		{ IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE2 },
+		{ IVTV_CARD_INPUT_SVIDEO1,    1, CX25840_SVIDEO3    },
+		{ IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
+	},
+	.audio_inputs = {
+		{ IVTV_CARD_INPUT_AUD_TUNER,  CX25840_AUDIO5,       0 },
+		{ IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL, 1 },
+	},
+	.radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
+	/* The 74HC4052 Dual 4:1 multiplexer is controlled by 2 GPIO lines */
+	.gpio_init = { .direction = 0xc000, .initial_value = 0 },
+	.gpio_audio_input  = { .mask   = 0xc000,
+			       .tuner  = 0x0000,
+			       .linein = 0x4000,
+			       .radio  = 0x8000 },
+	.tuners = {
+		/* The UltraTV 1500 MCE has a Philips FM1236 MK5 TV/FM tuner */
+		{ .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 },
+	},
+	.pci_list = ivtv_pci_aver_ultra1500mce,
+	.i2c = &ivtv_i2c_std,
+};
+
+/* ------------------------------------------------------------------------- */
+
 /* AVerMedia EZMaker PCI Deluxe card */
 
 static const struct ivtv_card_pci_info ivtv_pci_aver_ezmaker[] = {
@@ -1180,6 +1229,7 @@ static const struct ivtv_card *ivtv_card_list[] = {
 	&ivtv_card_aver_ezmaker,
 	&ivtv_card_aver_m104,
 	&ivtv_card_buffalo,
+	&ivtv_card_aver_ultra1500mce,
 
 	/* Variations of standard cards but with the same PCI IDs.
 	   These cards must come last in this list. */
diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h
index 0b8fe85..e99a0a2 100644
--- a/drivers/media/video/ivtv/ivtv-cards.h
+++ b/drivers/media/video/ivtv/ivtv-cards.h
@@ -50,7 +50,8 @@
 #define IVTV_CARD_AVER_EZMAKER       23 /* AVerMedia EZMaker PCI Deluxe */
 #define IVTV_CARD_AVER_M104          24 /* AverMedia M104 miniPCI card */
 #define IVTV_CARD_BUFFALO_MV5L       25 /* Buffalo PC-MV5L/PCI card */
-#define IVTV_CARD_LAST 		     25
+#define IVTV_CARD_AVER_ULTRA1500MCE  26 /* AVerMedia UltraTV 1500 MCE */
+#define IVTV_CARD_LAST 		     26
 
 /* Variants of existing cards but with the same PCI IDs. The driver
    detects these based on other device information.
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 558f8a8..463ec34 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -186,6 +186,7 @@ MODULE_PARM_DESC(cardtype,
 		 "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n"
 		 "\t\t\t25 = AverMedia M104 (not yet working)\n"
 		 "\t\t\t26 = Buffalo PC-MV5L/PCI\n"
+		 "\t\t\t27 = AVerMedia UltraTV 1500 MCE\n"
 		 "\t\t\t 0 = Autodetect (default)\n"
 		 "\t\t\t-1 = Ignore this card\n\t\t");
 MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60");
@@ -218,7 +219,7 @@ MODULE_PARM_DESC(ivtv_yuv_mode,
 		 "\t\t\tDefault: 0 (interlaced)");
 MODULE_PARM_DESC(ivtv_yuv_threshold,
 		 "If ivtv_yuv_mode is 2 (auto) then playback content as\n\t\tprogressive if src height <= ivtv_yuvthreshold\n"
-		 "\t\t\tDefault: 480");;
+		 "\t\t\tDefault: 480");
 MODULE_PARM_DESC(enc_mpg_buffers,
 		 "Encoder MPG Buffers (in MB)\n"
 		 "\t\t\tDefault: " __stringify(IVTV_DEFAULT_ENC_MPG_BUFFERS));
@@ -245,7 +246,7 @@ MODULE_PARM_DESC(newi2c,
 		 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
 		 "\t\t\tDefault is autodetect");
 
-MODULE_PARM_DESC(ivtv_first_minor, "Set kernel number assigned to first card");
+MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
 
 MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
 MODULE_DESCRIPTION("CX23415/CX23416 driver");
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index 85ac707..aede061 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -236,18 +236,6 @@ static int subdev_s_radio(struct v4l2_subdev *sd)
 	return 0;
 }
 
-static int subdev_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
-{
-	struct ivtv *itv = sd_to_ivtv(sd);
-	u16 mask, data;
-
-	mask = itv->card->gpio_audio_input.mask;
-	data = itv->card->gpio_audio_input.tuner;
-	if (mask)
-		write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
-	return 0;
-}
-
 static int subdev_s_audio_routing(struct v4l2_subdev *sd,
 				  u32 input, u32 output, u32 config)
 {
@@ -344,7 +332,6 @@ static const struct v4l2_subdev_core_ops subdev_core_ops = {
 	.g_ctrl = subdev_g_ctrl,
 	.s_ctrl = subdev_s_ctrl,
 	.queryctrl = subdev_queryctrl,
-	.s_std = subdev_s_std,
 };
 
 static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index e52aa32..b9c71e6 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -161,19 +161,19 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
 		return -1;
 	if (hw == IVTV_HW_TUNER) {
 		/* special tuner handling */
-		sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
 				adap, mod, type,
-				itv->card_i2c->radio);
+				0, itv->card_i2c->radio);
 		if (sd)
 			sd->grp_id = 1 << idx;
-		sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
 				adap, mod, type,
-				itv->card_i2c->demod);
+				0, itv->card_i2c->demod);
 		if (sd)
 			sd->grp_id = 1 << idx;
-		sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev,
+		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
 				adap, mod, type,
-				itv->card_i2c->tv);
+				0, itv->card_i2c->tv);
 		if (sd)
 			sd->grp_id = 1 << idx;
 		return sd ? 0 : -1;
@@ -181,11 +181,11 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
 	if (!hw_addrs[idx])
 		return -1;
 	if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
-		sd = v4l2_i2c_new_probed_subdev_addr(&itv->v4l2_dev,
-				adap, mod, type, hw_addrs[idx]);
+		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
+				adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx]));
 	} else {
 		sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
-				adap, mod, type, hw_addrs[idx]);
+				adap, mod, type, hw_addrs[idx], NULL);
 	}
 	if (sd)
 		sd->grp_id = 1 << idx;
@@ -509,7 +509,6 @@ static struct i2c_algorithm ivtv_algo = {
 /* template for our-bit banger */
 static struct i2c_adapter ivtv_i2c_adap_hw_template = {
 	.name = "ivtv i2c driver",
-	.id = I2C_HW_B_CX2341X,
 	.algo = &ivtv_algo,
 	.algo_data = NULL,			/* filled from template */
 	.owner = THIS_MODULE,
@@ -560,7 +559,6 @@ static int ivtv_getsda_old(void *data)
 /* template for i2c-bit-algo */
 static struct i2c_adapter ivtv_i2c_adap_template = {
 	.name = "ivtv i2c driver",
-	.id = I2C_HW_B_CX2341X,
 	.algo = NULL,                   /* set by i2c-algo-bit */
 	.algo_data = NULL,              /* filled from template */
 	.owner = THIS_MODULE,
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 15da017..67699e3 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -261,8 +261,8 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
 	video_set_drvdata(s->vdev, s);
 
 	/* Register device. First try the desired minor, then any free one. */
-	if (video_register_device(s->vdev, vfl_type, num)) {
-		IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
+	if (video_register_device_no_warn(s->vdev, vfl_type, num)) {
+		IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
 				s->name, num);
 		video_device_release(s->vdev);
 		s->vdev = NULL;
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 1d66855..d0765be 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1915,8 +1915,7 @@ static void __devexit meye_remove(struct pci_dev *pcidev)
 }
 
 static struct pci_device_id meye_pci_tbl[] = {
-	{ PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VDEVICE(KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002), 0 },
 	{ }
 };
 
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 4d794b4..45388d2 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -13,13 +13,13 @@
 #include <linux/i2c.h>
 #include <linux/log2.h>
 
-#include <media/v4l2-common.h>
+#include <media/v4l2-subdev.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
 /* mt9m001 i2c address 0x5d
- * The platform has to define i2c_board_info
- * and call i2c_register_board_info() */
+ * The platform has to define ctruct i2c_board_info objects and link to them
+ * from struct soc_camera_link */
 
 /* mt9m001 selected register addresses */
 #define MT9M001_CHIP_VERSION		0x00
@@ -39,6 +39,13 @@
 #define MT9M001_GLOBAL_GAIN		0x35
 #define MT9M001_CHIP_ENABLE		0xF1
 
+#define MT9M001_MAX_WIDTH		1280
+#define MT9M001_MAX_HEIGHT		1024
+#define MT9M001_MIN_WIDTH		48
+#define MT9M001_MIN_HEIGHT		32
+#define MT9M001_COLUMN_SKIP		20
+#define MT9M001_ROW_SKIP		12
+
 static const struct soc_camera_data_format mt9m001_colour_formats[] = {
 	/* Order important: first natively supported,
 	 * second supported with a GPIO extender */
@@ -69,12 +76,20 @@ static const struct soc_camera_data_format mt9m001_monochrome_formats[] = {
 };
 
 struct mt9m001 {
-	struct i2c_client *client;
-	struct soc_camera_device icd;
+	struct v4l2_subdev subdev;
+	struct v4l2_rect rect;	/* Sensor window */
+	__u32 fourcc;
 	int model;	/* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
+	unsigned int gain;
+	unsigned int exposure;
 	unsigned char autoexposure;
 };
 
+static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
+}
+
 static int reg_read(struct i2c_client *client, const u8 reg)
 {
 	s32 data = i2c_smbus_read_word_data(client, reg);
@@ -109,35 +124,20 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
 	return reg_write(client, reg, ret & ~data);
 }
 
-static int mt9m001_init(struct soc_camera_device *icd)
+static int mt9m001_init(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
-	dev_dbg(icd->vdev->parent, "%s\n", __func__);
+	dev_dbg(&client->dev, "%s\n", __func__);
 
-	if (icl->power) {
-		ret = icl->power(&client->dev, 1);
-		if (ret < 0) {
-			dev_err(icd->vdev->parent,
-				"Platform failed to power-on the camera.\n");
-			return ret;
-		}
-	}
-
-	/* The camera could have been already on, we reset it additionally */
-	if (icl->reset)
-		ret = icl->reset(&client->dev);
-	else
-		ret = -ENODEV;
+	/*
+	 * We don't know, whether platform provides reset, issue a soft reset
+	 * too. This returns all registers to their default values.
+	 */
+	ret = reg_write(client, MT9M001_RESET, 1);
+	if (!ret)
+		ret = reg_write(client, MT9M001_RESET, 0);
 
-	if (ret < 0) {
-		/* Either no platform reset, or platform reset failed */
-		ret = reg_write(client, MT9M001_RESET, 1);
-		if (!ret)
-			ret = reg_write(client, MT9M001_RESET, 0);
-	}
 	/* Disable chip, synchronous option update */
 	if (!ret)
 		ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
@@ -145,36 +145,12 @@ static int mt9m001_init(struct soc_camera_device *icd)
 	return ret;
 }
 
-static int mt9m001_release(struct soc_camera_device *icd)
+static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct soc_camera_link *icl = client->dev.platform_data;
-
-	/* Disable the chip */
-	reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
-
-	if (icl->power)
-		icl->power(&client->dev, 0);
-
-	return 0;
-}
+	struct i2c_client *client = sd->priv;
 
-static int mt9m001_start_capture(struct soc_camera_device *icd)
-{
-	struct i2c_client *client = to_i2c_client(icd->control);
-
-	/* Switch to master "normal" mode */
-	if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0)
-		return -EIO;
-	return 0;
-}
-
-static int mt9m001_stop_capture(struct soc_camera_device *icd)
-{
-	struct i2c_client *client = to_i2c_client(icd->control);
-
-	/* Stop sensor readout */
-	if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0)
+	/* Switch to master "normal" mode or stop sensor readout */
+	if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
 		return -EIO;
 	return 0;
 }
@@ -182,8 +158,7 @@ static int mt9m001_stop_capture(struct soc_camera_device *icd)
 static int mt9m001_set_bus_param(struct soc_camera_device *icd,
 				 unsigned long flags)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
 
 	/* Only one width bit may be set */
@@ -205,8 +180,7 @@ static int mt9m001_set_bus_param(struct soc_camera_device *icd,
 
 static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	/* MT9M001 has all capture_format parameters fixed */
 	unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
 		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
@@ -220,13 +194,35 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
 	return soc_camera_apply_sensor_flags(icl, flags);
 }
 
-static int mt9m001_set_crop(struct soc_camera_device *icd,
-			    struct v4l2_rect *rect)
+static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+	struct v4l2_rect rect = a->c;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	int ret;
 	const u16 hblank = 9, vblank = 25;
+	unsigned int total_h;
+
+	if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 ||
+	    mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16)
+		/*
+		 * Bayer format - even number of rows for simplicity,
+		 * but let the user play with the top row.
+		 */
+		rect.height = ALIGN(rect.height, 2);
+
+	/* Datasheet requirement: see register description */
+	rect.width = ALIGN(rect.width, 2);
+	rect.left = ALIGN(rect.left, 2);
+
+	soc_camera_limit_side(&rect.left, &rect.width,
+		     MT9M001_COLUMN_SKIP, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH);
+
+	soc_camera_limit_side(&rect.top, &rect.height,
+		     MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
+
+	total_h = rect.height + icd->y_skip_top + vblank;
 
 	/* Blanking and start values - default... */
 	ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
@@ -236,66 +232,126 @@ static int mt9m001_set_crop(struct soc_camera_device *icd,
 	/* The caller provides a supported format, as verified per
 	 * call to icd->try_fmt() */
 	if (!ret)
-		ret = reg_write(client, MT9M001_COLUMN_START, rect->left);
+		ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
 	if (!ret)
-		ret = reg_write(client, MT9M001_ROW_START, rect->top);
+		ret = reg_write(client, MT9M001_ROW_START, rect.top);
 	if (!ret)
-		ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1);
+		ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
 	if (!ret)
 		ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
-				rect->height + icd->y_skip_top - 1);
+				rect.height + icd->y_skip_top - 1);
 	if (!ret && mt9m001->autoexposure) {
-		ret = reg_write(client, MT9M001_SHUTTER_WIDTH,
-				rect->height + icd->y_skip_top + vblank);
+		ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
 		if (!ret) {
 			const struct v4l2_queryctrl *qctrl =
 				soc_camera_find_qctrl(icd->ops,
 						      V4L2_CID_EXPOSURE);
-			icd->exposure = (524 + (rect->height + icd->y_skip_top +
-						vblank - 1) *
-					 (qctrl->maximum - qctrl->minimum)) /
+			mt9m001->exposure = (524 + (total_h - 1) *
+				 (qctrl->maximum - qctrl->minimum)) /
 				1048 + qctrl->minimum;
 		}
 	}
 
+	if (!ret)
+		mt9m001->rect = rect;
+
 	return ret;
 }
 
-static int mt9m001_set_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+
+	a->c	= mt9m001->rect;
+	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= MT9M001_COLUMN_SKIP;
+	a->bounds.top			= MT9M001_ROW_SKIP;
+	a->bounds.width			= MT9M001_MAX_WIDTH;
+	a->bounds.height		= MT9M001_MAX_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
-	struct v4l2_rect rect = {
-		.left	= icd->x_current,
-		.top	= icd->y_current,
-		.width	= f->fmt.pix.width,
-		.height	= f->fmt.pix.height,
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	pix->width		= mt9m001->rect.width;
+	pix->height		= mt9m001->rect.height;
+	pix->pixelformat	= mt9m001->fourcc;
+	pix->field		= V4L2_FIELD_NONE;
+	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+
+	return 0;
+}
+
+static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_crop a = {
+		.c = {
+			.left	= mt9m001->rect.left,
+			.top	= mt9m001->rect.top,
+			.width	= pix->width,
+			.height	= pix->height,
+		},
 	};
+	int ret;
 
 	/* No support for scaling so far, just crop. TODO: use skipping */
-	return mt9m001_set_crop(icd, &rect);
+	ret = mt9m001_s_crop(sd, &a);
+	if (!ret) {
+		pix->width = mt9m001->rect.width;
+		pix->height = mt9m001->rect.height;
+		mt9m001->fourcc = pix->pixelformat;
+	}
+
+	return ret;
 }
 
-static int mt9m001_try_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
+	struct i2c_client *client = sd->priv;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	v4l_bound_align_image(&pix->width, 48, 1280, 1,
-			      &pix->height, 32 + icd->y_skip_top,
-			      1024 + icd->y_skip_top, 0, 0);
+	v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH,
+		MT9M001_MAX_WIDTH, 1,
+		&pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top,
+		MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0);
+
+	if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
+	    pix->pixelformat == V4L2_PIX_FMT_SBGGR16)
+		pix->height = ALIGN(pix->height - 1, 2);
 
 	return 0;
 }
 
-static int mt9m001_get_chip_id(struct soc_camera_device *icd,
-			       struct v4l2_dbg_chip_ident *id)
+static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *id)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
 
 	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
 		return -EINVAL;
 
-	if (id->match.addr != mt9m001->client->addr)
+	if (id->match.addr != client->addr)
 		return -ENODEV;
 
 	id->ident	= mt9m001->model;
@@ -305,10 +361,10 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd,
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9m001_get_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9m001_g_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
@@ -325,10 +381,10 @@ static int mt9m001_get_register(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int mt9m001_set_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9m001_s_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
@@ -381,39 +437,17 @@ static const struct v4l2_queryctrl mt9m001_controls[] = {
 	}
 };
 
-static int mt9m001_video_probe(struct soc_camera_device *);
-static void mt9m001_video_remove(struct soc_camera_device *);
-static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *);
-static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *);
-
 static struct soc_camera_ops mt9m001_ops = {
-	.owner			= THIS_MODULE,
-	.probe			= mt9m001_video_probe,
-	.remove			= mt9m001_video_remove,
-	.init			= mt9m001_init,
-	.release		= mt9m001_release,
-	.start_capture		= mt9m001_start_capture,
-	.stop_capture		= mt9m001_stop_capture,
-	.set_crop		= mt9m001_set_crop,
-	.set_fmt		= mt9m001_set_fmt,
-	.try_fmt		= mt9m001_try_fmt,
 	.set_bus_param		= mt9m001_set_bus_param,
 	.query_bus_param	= mt9m001_query_bus_param,
 	.controls		= mt9m001_controls,
 	.num_controls		= ARRAY_SIZE(mt9m001_controls),
-	.get_control		= mt9m001_get_control,
-	.set_control		= mt9m001_set_control,
-	.get_chip_id		= mt9m001_get_chip_id,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.get_register		= mt9m001_get_register,
-	.set_register		= mt9m001_set_register,
-#endif
 };
 
-static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
+static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
 	int data;
 
 	switch (ctrl->id) {
@@ -426,14 +460,21 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro
 	case V4L2_CID_EXPOSURE_AUTO:
 		ctrl->value = mt9m001->autoexposure;
 		break;
+	case V4L2_CID_GAIN:
+		ctrl->value = mt9m001->gain;
+		break;
+	case V4L2_CID_EXPOSURE:
+		ctrl->value = mt9m001->exposure;
+		break;
 	}
 	return 0;
 }
 
-static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
+static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 	const struct v4l2_queryctrl *qctrl;
 	int data;
 
@@ -460,7 +501,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 			unsigned long range = qctrl->default_value - qctrl->minimum;
 			data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
 
-			dev_dbg(&icd->dev, "Setting gain %d\n", data);
+			dev_dbg(&client->dev, "Setting gain %d\n", data);
 			data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
 			if (data < 0)
 				return -EIO;
@@ -478,7 +519,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 			else
 				data = ((gain - 64) * 7 + 28) / 56 + 96;
 
-			dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
+			dev_dbg(&client->dev, "Setting gain from %d to %d\n",
 				 reg_read(client, MT9M001_GLOBAL_GAIN), data);
 			data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
 			if (data < 0)
@@ -486,7 +527,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 		}
 
 		/* Success */
-		icd->gain = ctrl->value;
+		mt9m001->gain = ctrl->value;
 		break;
 	case V4L2_CID_EXPOSURE:
 		/* mt9m001 has maximum == default */
@@ -497,23 +538,27 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 			unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 +
 						 range / 2) / range + 1;
 
-			dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n",
-				 reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
+			dev_dbg(&client->dev,
+				"Setting shutter width from %d to %lu\n",
+				reg_read(client, MT9M001_SHUTTER_WIDTH),
+				shutter);
 			if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
 				return -EIO;
-			icd->exposure = ctrl->value;
+			mt9m001->exposure = ctrl->value;
 			mt9m001->autoexposure = 0;
 		}
 		break;
 	case V4L2_CID_EXPOSURE_AUTO:
 		if (ctrl->value) {
 			const u16 vblank = 25;
-			if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height +
-				      icd->y_skip_top + vblank) < 0)
+			unsigned int total_h = mt9m001->rect.height +
+				icd->y_skip_top + vblank;
+			if (reg_write(client, MT9M001_SHUTTER_WIDTH,
+				      total_h) < 0)
 				return -EIO;
 			qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
-			icd->exposure = (524 + (icd->height + icd->y_skip_top + vblank - 1) *
-					 (qctrl->maximum - qctrl->minimum)) /
+			mt9m001->exposure = (524 + (total_h - 1) *
+				 (qctrl->maximum - qctrl->minimum)) /
 				1048 + qctrl->minimum;
 			mt9m001->autoexposure = 1;
 		} else
@@ -525,14 +570,14 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
 
 /* Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one */
-static int mt9m001_video_probe(struct soc_camera_device *icd)
+static int mt9m001_video_probe(struct soc_camera_device *icd,
+			       struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	s32 data;
-	int ret;
 	unsigned long flags;
+	int ret;
 
 	/* We must have a parent by now. And it cannot be a wrong one.
 	 * So this entire test is completely redundant. */
@@ -542,7 +587,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
 
 	/* Enable the chip */
 	data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
-	dev_dbg(&icd->dev, "write: %d\n", data);
+	dev_dbg(&client->dev, "write: %d\n", data);
 
 	/* Read out the chip version register */
 	data = reg_read(client, MT9M001_CHIP_VERSION);
@@ -559,10 +604,9 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
 		icd->formats = mt9m001_monochrome_formats;
 		break;
 	default:
-		ret = -ENODEV;
-		dev_err(&icd->dev,
+		dev_err(&client->dev,
 			"No MT9M001 chip detected, register read %x\n", data);
-		goto ei2c;
+		return -ENODEV;
 	}
 
 	icd->num_formats = 0;
@@ -585,42 +629,72 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
 	if (flags & SOCAM_DATAWIDTH_8)
 		icd->num_formats++;
 
-	dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
+	mt9m001->fourcc = icd->formats->fourcc;
+
+	dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
 		 data == 0x8431 ? "C12STM" : "C12ST");
 
-	/* Now that we know the model, we can start video */
-	ret = soc_camera_video_start(icd);
-	if (ret)
-		goto eisis;
+	ret = mt9m001_init(client);
+	if (ret < 0)
+		dev_err(&client->dev, "Failed to initialise the camera\n");
 
-	return 0;
+	/* mt9m001_init() has reset the chip, returning registers to defaults */
+	mt9m001->gain = 64;
+	mt9m001->exposure = 255;
 
-eisis:
-ei2c:
 	return ret;
 }
 
 static void mt9m001_video_remove(struct soc_camera_device *icd)
 {
-	struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
-	struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 
-	dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr,
+	dev_dbg(&icd->dev, "Video removed: %p, %p\n",
 		icd->dev.parent, icd->vdev);
-	soc_camera_video_stop(icd);
 	if (icl->free_bus)
 		icl->free_bus(icl);
 }
 
+static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
+	.g_ctrl		= mt9m001_g_ctrl,
+	.s_ctrl		= mt9m001_s_ctrl,
+	.g_chip_ident	= mt9m001_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register	= mt9m001_g_register,
+	.s_register	= mt9m001_s_register,
+#endif
+};
+
+static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
+	.s_stream	= mt9m001_s_stream,
+	.s_fmt		= mt9m001_s_fmt,
+	.g_fmt		= mt9m001_g_fmt,
+	.try_fmt	= mt9m001_try_fmt,
+	.s_crop		= mt9m001_s_crop,
+	.g_crop		= mt9m001_g_crop,
+	.cropcap	= mt9m001_cropcap,
+};
+
+static struct v4l2_subdev_ops mt9m001_subdev_ops = {
+	.core	= &mt9m001_subdev_core_ops,
+	.video	= &mt9m001_subdev_video_ops,
+};
+
 static int mt9m001_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
 	struct mt9m001 *mt9m001;
-	struct soc_camera_device *icd;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct soc_camera_link *icl;
 	int ret;
 
+	if (!icd) {
+		dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
 	if (!icl) {
 		dev_err(&client->dev, "MT9M001 driver needs platform data\n");
 		return -EINVAL;
@@ -636,43 +710,40 @@ static int mt9m001_probe(struct i2c_client *client,
 	if (!mt9m001)
 		return -ENOMEM;
 
-	mt9m001->client = client;
-	i2c_set_clientdata(client, mt9m001);
+	v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
 
 	/* Second stage probe - when a capture adapter is there */
-	icd = &mt9m001->icd;
-	icd->ops	= &mt9m001_ops;
-	icd->control	= &client->dev;
-	icd->x_min	= 20;
-	icd->y_min	= 12;
-	icd->x_current	= 20;
-	icd->y_current	= 12;
-	icd->width_min	= 48;
-	icd->width_max	= 1280;
-	icd->height_min	= 32;
-	icd->height_max	= 1024;
-	icd->y_skip_top	= 1;
-	icd->iface	= icl->bus_id;
+	icd->ops		= &mt9m001_ops;
+	icd->y_skip_top		= 0;
+
+	mt9m001->rect.left	= MT9M001_COLUMN_SKIP;
+	mt9m001->rect.top	= MT9M001_ROW_SKIP;
+	mt9m001->rect.width	= MT9M001_MAX_WIDTH;
+	mt9m001->rect.height	= MT9M001_MAX_HEIGHT;
+
 	/* Simulated autoexposure. If enabled, we calculate shutter width
 	 * ourselves in the driver based on vertical blanking and frame width */
 	mt9m001->autoexposure = 1;
 
-	ret = soc_camera_device_register(icd);
-	if (ret)
-		goto eisdr;
-
-	return 0;
+	ret = mt9m001_video_probe(icd, client);
+	if (ret) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(mt9m001);
+	}
 
-eisdr:
-	kfree(mt9m001);
 	return ret;
 }
 
 static int mt9m001_remove(struct i2c_client *client)
 {
-	struct mt9m001 *mt9m001 = i2c_get_clientdata(client);
+	struct mt9m001 *mt9m001 = to_mt9m001(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 
-	soc_camera_device_unregister(&mt9m001->icd);
+	icd->ops = NULL;
+	mt9m001_video_remove(icd);
+	i2c_set_clientdata(client, NULL);
+	client->driver = NULL;
 	kfree(mt9m001);
 
 	return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index fc5e2de..90da699 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -148,12 +148,12 @@ enum mt9m111_context {
 };
 
 struct mt9m111 {
-	struct i2c_client *client;
-	struct soc_camera_device icd;
+	struct v4l2_subdev subdev;
 	int model;	/* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
 	enum mt9m111_context context;
 	struct v4l2_rect rect;
 	u32 pixfmt;
+	unsigned int gain;
 	unsigned char autoexposure;
 	unsigned char datawidth;
 	unsigned int powered:1;
@@ -166,6 +166,11 @@ struct mt9m111 {
 	unsigned int autowhitebalance:1;
 };
 
+static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
+}
+
 static int reg_page_map_set(struct i2c_client *client, const u16 reg)
 {
 	int ret;
@@ -190,7 +195,7 @@ static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
 
 	ret = reg_page_map_set(client, reg);
 	if (!ret)
-		ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff)));
+		ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff));
 
 	dev_dbg(&client->dev, "read  reg.%03x -> %04x\n", reg, ret);
 	return ret;
@@ -203,7 +208,7 @@ static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
 
 	ret = reg_page_map_set(client, reg);
 	if (!ret)
-		ret = i2c_smbus_write_word_data(client, (reg & 0xff),
+		ret = i2c_smbus_write_word_data(client, reg & 0xff,
 						swab16(data));
 	dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
 	return ret;
@@ -229,10 +234,9 @@ static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
 	return mt9m111_reg_write(client, reg, ret & ~data);
 }
 
-static int mt9m111_set_context(struct soc_camera_device *icd,
+static int mt9m111_set_context(struct i2c_client *client,
 			       enum mt9m111_context ctxt)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
 	int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
 		| MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
 		| MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -246,17 +250,16 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
 		return reg_write(CONTEXT_CONTROL, valA);
 }
 
-static int mt9m111_setup_rect(struct soc_camera_device *icd,
+static int mt9m111_setup_rect(struct i2c_client *client,
 			      struct v4l2_rect *rect)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret, is_raw_format;
 	int width = rect->width;
 	int height = rect->height;
 
-	if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8)
-	    || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16))
+	if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
+	    mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)
 		is_raw_format = 1;
 	else
 		is_raw_format = 0;
@@ -292,9 +295,8 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
 	return ret;
 }
 
-static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
+static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
 	int ret;
 
 	ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -303,19 +305,19 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
 	return ret;
 }
 
-static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd)
+static int mt9m111_setfmt_bayer8(struct i2c_client *client)
 {
-	return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER);
+	return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
 }
 
-static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd)
+static int mt9m111_setfmt_bayer10(struct i2c_client *client)
 {
-	return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP);
+	return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP);
 }
 
-static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd)
+static int mt9m111_setfmt_rgb565(struct i2c_client *client)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int val = 0;
 
 	if (mt9m111->swap_rgb_red_blue)
@@ -324,12 +326,12 @@ static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd)
 		val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
 	val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;
 
-	return mt9m111_setup_pixfmt(icd, val);
+	return mt9m111_setup_pixfmt(client, val);
 }
 
-static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd)
+static int mt9m111_setfmt_rgb555(struct i2c_client *client)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int val = 0;
 
 	if (mt9m111->swap_rgb_red_blue)
@@ -338,12 +340,12 @@ static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd)
 		val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
 	val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;
 
-	return mt9m111_setup_pixfmt(icd, val);
+	return mt9m111_setup_pixfmt(client, val);
 }
 
-static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
+static int mt9m111_setfmt_yuv(struct i2c_client *client)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int val = 0;
 
 	if (mt9m111->swap_yuv_cb_cr)
@@ -351,52 +353,22 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
 	if (mt9m111->swap_yuv_y_chromas)
 		val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
 
-	return mt9m111_setup_pixfmt(icd, val);
+	return mt9m111_setup_pixfmt(client, val);
 }
 
-static int mt9m111_enable(struct soc_camera_device *icd)
+static int mt9m111_enable(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
-	if (icl->power) {
-		ret = icl->power(&client->dev, 1);
-		if (ret < 0) {
-			dev_err(icd->vdev->parent,
-				"Platform failed to power-on the camera.\n");
-			return ret;
-		}
-	}
-
 	ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
 	if (!ret)
 		mt9m111->powered = 1;
 	return ret;
 }
 
-static int mt9m111_disable(struct soc_camera_device *icd)
-{
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct soc_camera_link *icl = client->dev.platform_data;
-	int ret;
-
-	ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
-	if (!ret)
-		mt9m111->powered = 0;
-
-	if (icl->power)
-		icl->power(&client->dev, 0);
-
-	return ret;
-}
-
-static int mt9m111_reset(struct soc_camera_device *icd)
+static int mt9m111_reset(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
 	ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -406,26 +378,12 @@ static int mt9m111_reset(struct soc_camera_device *icd)
 		ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
 				| MT9M111_RESET_RESET_SOC);
 
-	if (icl->reset)
-		icl->reset(&client->dev);
-
 	return ret;
 }
 
-static int mt9m111_start_capture(struct soc_camera_device *icd)
-{
-	return 0;
-}
-
-static int mt9m111_stop_capture(struct soc_camera_device *icd)
-{
-	return 0;
-}
-
 static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-	struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
 		SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
 		SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
@@ -438,62 +396,126 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
 	return 0;
 }
 
-static int mt9m111_set_crop(struct soc_camera_device *icd,
-			    struct v4l2_rect *rect)
+static int mt9m111_make_rect(struct i2c_client *client,
+			     struct v4l2_rect *rect)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
+
+	if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
+	    mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) {
+		/* Bayer format - even size lengths */
+		rect->width	= ALIGN(rect->width, 2);
+		rect->height	= ALIGN(rect->height, 2);
+		/* Let the user play with the starting pixel */
+	}
+
+	/* FIXME: the datasheet doesn't specify minimum sizes */
+	soc_camera_limit_side(&rect->left, &rect->width,
+		     MT9M111_MIN_DARK_COLS, 2, MT9M111_MAX_WIDTH);
+
+	soc_camera_limit_side(&rect->top, &rect->height,
+		     MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT);
+
+	return mt9m111_setup_rect(client, rect);
+}
+
+static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct v4l2_rect rect = a->c;
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
-	dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
-		__func__, rect->left, rect->top, rect->width,
-		rect->height);
+	dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
+		__func__, rect.left, rect.top, rect.width, rect.height);
 
-	ret = mt9m111_setup_rect(icd, rect);
+	ret = mt9m111_make_rect(client, &rect);
 	if (!ret)
-		mt9m111->rect = *rect;
+		mt9m111->rect = rect;
 	return ret;
 }
 
-static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
+static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
+
+	a->c	= mt9m111->rect;
+	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= MT9M111_MIN_DARK_COLS;
+	a->bounds.top			= MT9M111_MIN_DARK_ROWS;
+	a->bounds.width			= MT9M111_MAX_WIDTH;
+	a->bounds.height		= MT9M111_MAX_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	pix->width		= mt9m111->rect.width;
+	pix->height		= mt9m111->rect.height;
+	pix->pixelformat	= mt9m111->pixfmt;
+	pix->field		= V4L2_FIELD_NONE;
+	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+
+	return 0;
+}
+
+static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
+{
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
 	switch (pixfmt) {
 	case V4L2_PIX_FMT_SBGGR8:
-		ret = mt9m111_setfmt_bayer8(icd);
+		ret = mt9m111_setfmt_bayer8(client);
 		break;
 	case V4L2_PIX_FMT_SBGGR16:
-		ret = mt9m111_setfmt_bayer10(icd);
+		ret = mt9m111_setfmt_bayer10(client);
 		break;
 	case V4L2_PIX_FMT_RGB555:
-		ret = mt9m111_setfmt_rgb555(icd);
+		ret = mt9m111_setfmt_rgb555(client);
 		break;
 	case V4L2_PIX_FMT_RGB565:
-		ret = mt9m111_setfmt_rgb565(icd);
+		ret = mt9m111_setfmt_rgb565(client);
 		break;
 	case V4L2_PIX_FMT_UYVY:
 		mt9m111->swap_yuv_y_chromas = 0;
 		mt9m111->swap_yuv_cb_cr = 0;
-		ret = mt9m111_setfmt_yuv(icd);
+		ret = mt9m111_setfmt_yuv(client);
 		break;
 	case V4L2_PIX_FMT_VYUY:
 		mt9m111->swap_yuv_y_chromas = 0;
 		mt9m111->swap_yuv_cb_cr = 1;
-		ret = mt9m111_setfmt_yuv(icd);
+		ret = mt9m111_setfmt_yuv(client);
 		break;
 	case V4L2_PIX_FMT_YUYV:
 		mt9m111->swap_yuv_y_chromas = 1;
 		mt9m111->swap_yuv_cb_cr = 0;
-		ret = mt9m111_setfmt_yuv(icd);
+		ret = mt9m111_setfmt_yuv(client);
 		break;
 	case V4L2_PIX_FMT_YVYU:
 		mt9m111->swap_yuv_y_chromas = 1;
 		mt9m111->swap_yuv_cb_cr = 1;
-		ret = mt9m111_setfmt_yuv(icd);
+		ret = mt9m111_setfmt_yuv(client);
 		break;
 	default:
-		dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt);
+		dev_err(&client->dev, "Pixel format not handled : %x\n",
+			pixfmt);
 		ret = -EINVAL;
 	}
 
@@ -503,10 +525,10 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
 	return ret;
 }
 
-static int mt9m111_set_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_rect rect = {
 		.left	= mt9m111->rect.left,
@@ -516,40 +538,56 @@ static int mt9m111_set_fmt(struct soc_camera_device *icd,
 	};
 	int ret;
 
-	dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
-		__func__, pix->pixelformat, rect.left, rect.top, rect.width,
-		rect.height);
+	dev_dbg(&client->dev,
+		"%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
+		pix->pixelformat, rect.left, rect.top, rect.width, rect.height);
 
-	ret = mt9m111_setup_rect(icd, &rect);
+	ret = mt9m111_make_rect(client, &rect);
 	if (!ret)
-		ret = mt9m111_set_pixfmt(icd, pix->pixelformat);
+		ret = mt9m111_set_pixfmt(client, pix->pixelformat);
 	if (!ret)
 		mt9m111->rect = rect;
 	return ret;
 }
 
-static int mt9m111_try_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
+	bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
+		pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
+
+	/*
+	 * With Bayer format enforce even side lengths, but let the user play
+	 * with the starting pixel
+	 */
 
 	if (pix->height > MT9M111_MAX_HEIGHT)
 		pix->height = MT9M111_MAX_HEIGHT;
+	else if (pix->height < 2)
+		pix->height = 2;
+	else if (bayer)
+		pix->height = ALIGN(pix->height, 2);
+
 	if (pix->width > MT9M111_MAX_WIDTH)
 		pix->width = MT9M111_MAX_WIDTH;
+	else if (pix->width < 2)
+		pix->width = 2;
+	else if (bayer)
+		pix->width = ALIGN(pix->width, 2);
 
 	return 0;
 }
 
-static int mt9m111_get_chip_id(struct soc_camera_device *icd,
-			       struct v4l2_dbg_chip_ident *id)
+static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *id)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 
 	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
 		return -EINVAL;
 
-	if (id->match.addr != mt9m111->client->addr)
+	if (id->match.addr != client->addr)
 		return -ENODEV;
 
 	id->ident	= mt9m111->model;
@@ -559,11 +597,11 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd,
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9m111_get_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9m111_g_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
+	struct i2c_client *client = sd->priv;
 	int val;
-	struct i2c_client *client = to_i2c_client(icd->control);
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
 		return -EINVAL;
@@ -580,10 +618,10 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int mt9m111_set_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9m111_s_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
 		return -EINVAL;
@@ -635,45 +673,21 @@ static const struct v4l2_queryctrl mt9m111_controls[] = {
 	}
 };
 
-static int mt9m111_video_probe(struct soc_camera_device *);
-static void mt9m111_video_remove(struct soc_camera_device *);
-static int mt9m111_get_control(struct soc_camera_device *,
-			       struct v4l2_control *);
-static int mt9m111_set_control(struct soc_camera_device *,
-			       struct v4l2_control *);
 static int mt9m111_resume(struct soc_camera_device *icd);
-static int mt9m111_init(struct soc_camera_device *icd);
-static int mt9m111_release(struct soc_camera_device *icd);
+static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state);
 
 static struct soc_camera_ops mt9m111_ops = {
-	.owner			= THIS_MODULE,
-	.probe			= mt9m111_video_probe,
-	.remove			= mt9m111_video_remove,
-	.init			= mt9m111_init,
+	.suspend		= mt9m111_suspend,
 	.resume			= mt9m111_resume,
-	.release		= mt9m111_release,
-	.start_capture		= mt9m111_start_capture,
-	.stop_capture		= mt9m111_stop_capture,
-	.set_crop		= mt9m111_set_crop,
-	.set_fmt		= mt9m111_set_fmt,
-	.try_fmt		= mt9m111_try_fmt,
 	.query_bus_param	= mt9m111_query_bus_param,
 	.set_bus_param		= mt9m111_set_bus_param,
 	.controls		= mt9m111_controls,
 	.num_controls		= ARRAY_SIZE(mt9m111_controls),
-	.get_control		= mt9m111_get_control,
-	.set_control		= mt9m111_set_control,
-	.get_chip_id		= mt9m111_get_chip_id,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.get_register		= mt9m111_get_register,
-	.set_register		= mt9m111_set_register,
-#endif
 };
 
-static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
+static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
 	if (mt9m111->context == HIGHPOWER) {
@@ -691,9 +705,8 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
 	return ret;
 }
 
-static int mt9m111_get_global_gain(struct soc_camera_device *icd)
+static int mt9m111_get_global_gain(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
 	int data;
 
 	data = reg_read(GLOBAL_GAIN);
@@ -703,15 +716,15 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
 	return data;
 }
 
-static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
+static int mt9m111_set_global_gain(struct i2c_client *client, int gain)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	u16 val;
 
 	if (gain > 63 * 2 * 2)
 		return -EINVAL;
 
-	icd->gain = gain;
+	mt9m111->gain = gain;
 	if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
 		val = (1 << 10) | (1 << 9) | (gain / 4);
 	else if ((gain >= 64) && (gain < 64 * 2))
@@ -722,10 +735,9 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
 	return reg_write(GLOBAL_GAIN, val);
 }
 
-static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
+static int mt9m111_set_autoexposure(struct i2c_client *client, int on)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
 	if (on)
@@ -739,10 +751,9 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
 	return ret;
 }
 
-static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
+static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
 	if (on)
@@ -756,11 +767,10 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
 	return ret;
 }
 
-static int mt9m111_get_control(struct soc_camera_device *icd,
-			       struct v4l2_control *ctrl)
+static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int data;
 
 	switch (ctrl->id) {
@@ -785,7 +795,7 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
 		ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
 		break;
 	case V4L2_CID_GAIN:
-		data = mt9m111_get_global_gain(icd);
+		data = mt9m111_get_global_gain(client);
 		if (data < 0)
 			return data;
 		ctrl->value = data;
@@ -800,37 +810,36 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int mt9m111_set_control(struct soc_camera_device *icd,
-			       struct v4l2_control *ctrl)
+static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	const struct v4l2_queryctrl *qctrl;
 	int ret;
 
 	qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
-
 	if (!qctrl)
 		return -EINVAL;
 
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
 		mt9m111->vflip = ctrl->value;
-		ret = mt9m111_set_flip(icd, ctrl->value,
+		ret = mt9m111_set_flip(client, ctrl->value,
 					MT9M111_RMB_MIRROR_ROWS);
 		break;
 	case V4L2_CID_HFLIP:
 		mt9m111->hflip = ctrl->value;
-		ret = mt9m111_set_flip(icd, ctrl->value,
+		ret = mt9m111_set_flip(client, ctrl->value,
 					MT9M111_RMB_MIRROR_COLS);
 		break;
 	case V4L2_CID_GAIN:
-		ret = mt9m111_set_global_gain(icd, ctrl->value);
+		ret = mt9m111_set_global_gain(client, ctrl->value);
 		break;
 	case V4L2_CID_EXPOSURE_AUTO:
-		ret =  mt9m111_set_autoexposure(icd, ctrl->value);
+		ret =  mt9m111_set_autoexposure(client, ctrl->value);
 		break;
 	case V4L2_CID_AUTO_WHITE_BALANCE:
-		ret =  mt9m111_set_autowhitebalance(icd, ctrl->value);
+		ret =  mt9m111_set_autowhitebalance(client, ctrl->value);
 		break;
 	default:
 		ret = -EINVAL;
@@ -839,62 +848,62 @@ static int mt9m111_set_control(struct soc_camera_device *icd,
 	return ret;
 }
 
-static int mt9m111_restore_state(struct soc_camera_device *icd)
+static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
-
-	mt9m111_set_context(icd, mt9m111->context);
-	mt9m111_set_pixfmt(icd, mt9m111->pixfmt);
-	mt9m111_setup_rect(icd, &mt9m111->rect);
-	mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
-	mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
-	mt9m111_set_global_gain(icd, icd->gain);
-	mt9m111_set_autoexposure(icd, mt9m111->autoexposure);
-	mt9m111_set_autowhitebalance(icd, mt9m111->autowhitebalance);
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
+
+	mt9m111->gain = mt9m111_get_global_gain(client);
+
+	return 0;
+}
+
+static int mt9m111_restore_state(struct i2c_client *client)
+{
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
+
+	mt9m111_set_context(client, mt9m111->context);
+	mt9m111_set_pixfmt(client, mt9m111->pixfmt);
+	mt9m111_setup_rect(client, &mt9m111->rect);
+	mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
+	mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
+	mt9m111_set_global_gain(client, mt9m111->gain);
+	mt9m111_set_autoexposure(client, mt9m111->autoexposure);
+	mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance);
 	return 0;
 }
 
 static int mt9m111_resume(struct soc_camera_device *icd)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret = 0;
 
 	if (mt9m111->powered) {
-		ret = mt9m111_enable(icd);
+		ret = mt9m111_enable(client);
 		if (!ret)
-			ret = mt9m111_reset(icd);
+			ret = mt9m111_reset(client);
 		if (!ret)
-			ret = mt9m111_restore_state(icd);
+			ret = mt9m111_restore_state(client);
 	}
 	return ret;
 }
 
-static int mt9m111_init(struct soc_camera_device *icd)
+static int mt9m111_init(struct i2c_client *client)
 {
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	int ret;
 
 	mt9m111->context = HIGHPOWER;
-	ret = mt9m111_enable(icd);
+	ret = mt9m111_enable(client);
 	if (!ret)
-		ret = mt9m111_reset(icd);
+		ret = mt9m111_reset(client);
 	if (!ret)
-		ret = mt9m111_set_context(icd, mt9m111->context);
+		ret = mt9m111_set_context(client, mt9m111->context);
 	if (!ret)
-		ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure);
+		ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure);
 	if (ret)
-		dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret);
-	return ret;
-}
-
-static int mt9m111_release(struct soc_camera_device *icd)
-{
-	int ret;
-
-	ret = mt9m111_disable(icd);
-	if (ret < 0)
-		dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret);
-
+		dev_err(&client->dev, "mt9m11x init failed: %d\n", ret);
 	return ret;
 }
 
@@ -902,10 +911,10 @@ static int mt9m111_release(struct soc_camera_device *icd)
  * Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one
  */
-static int mt9m111_video_probe(struct soc_camera_device *icd)
+static int mt9m111_video_probe(struct soc_camera_device *icd,
+			       struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
 	s32 data;
 	int ret;
 
@@ -917,10 +926,13 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
 	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
 		return -ENODEV;
 
-	ret = mt9m111_enable(icd);
-	if (ret)
-		goto ei2c;
-	ret = mt9m111_reset(icd);
+	mt9m111->autoexposure = 1;
+	mt9m111->autowhitebalance = 1;
+
+	mt9m111->swap_rgb_even_odd = 1;
+	mt9m111->swap_rgb_red_blue = 1;
+
+	ret = mt9m111_init(client);
 	if (ret)
 		goto ei2c;
 
@@ -935,7 +947,7 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
 		break;
 	default:
 		ret = -ENODEV;
-		dev_err(&icd->dev,
+		dev_err(&client->dev,
 			"No MT9M11x chip detected, register read %x\n", data);
 		goto ei2c;
 	}
@@ -943,42 +955,51 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
 	icd->formats = mt9m111_colour_formats;
 	icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);
 
-	dev_info(&icd->dev, "Detected a MT9M11x chip ID %x\n", data);
+	dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data);
 
-	ret = soc_camera_video_start(icd);
-	if (ret)
-		goto eisis;
-
-	mt9m111->autoexposure = 1;
-	mt9m111->autowhitebalance = 1;
-
-	mt9m111->swap_rgb_even_odd = 1;
-	mt9m111->swap_rgb_red_blue = 1;
-
-	return 0;
-eisis:
 ei2c:
 	return ret;
 }
 
-static void mt9m111_video_remove(struct soc_camera_device *icd)
-{
-	struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
+	.g_ctrl		= mt9m111_g_ctrl,
+	.s_ctrl		= mt9m111_s_ctrl,
+	.g_chip_ident	= mt9m111_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register	= mt9m111_g_register,
+	.s_register	= mt9m111_s_register,
+#endif
+};
 
-	dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr,
-		mt9m111->icd.dev.parent, mt9m111->icd.vdev);
-	soc_camera_video_stop(&mt9m111->icd);
-}
+static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
+	.s_fmt		= mt9m111_s_fmt,
+	.g_fmt		= mt9m111_g_fmt,
+	.try_fmt	= mt9m111_try_fmt,
+	.s_crop		= mt9m111_s_crop,
+	.g_crop		= mt9m111_g_crop,
+	.cropcap	= mt9m111_cropcap,
+};
+
+static struct v4l2_subdev_ops mt9m111_subdev_ops = {
+	.core	= &mt9m111_subdev_core_ops,
+	.video	= &mt9m111_subdev_video_ops,
+};
 
 static int mt9m111_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
 	struct mt9m111 *mt9m111;
-	struct soc_camera_device *icd;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct soc_camera_link *icl;
 	int ret;
 
+	if (!icd) {
+		dev_err(&client->dev, "MT9M11x: missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
 	if (!icl) {
 		dev_err(&client->dev, "MT9M11x driver needs platform data\n");
 		return -EINVAL;
@@ -994,38 +1015,35 @@ static int mt9m111_probe(struct i2c_client *client,
 	if (!mt9m111)
 		return -ENOMEM;
 
-	mt9m111->client = client;
-	i2c_set_clientdata(client, mt9m111);
+	v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
 
 	/* Second stage probe - when a capture adapter is there */
-	icd 		= &mt9m111->icd;
-	icd->ops	= &mt9m111_ops;
-	icd->control	= &client->dev;
-	icd->x_min	= MT9M111_MIN_DARK_COLS;
-	icd->y_min	= MT9M111_MIN_DARK_ROWS;
-	icd->x_current	= icd->x_min;
-	icd->y_current	= icd->y_min;
-	icd->width_min	= MT9M111_MIN_DARK_ROWS;
-	icd->width_max	= MT9M111_MAX_WIDTH;
-	icd->height_min	= MT9M111_MIN_DARK_COLS;
-	icd->height_max	= MT9M111_MAX_HEIGHT;
-	icd->y_skip_top	= 0;
-	icd->iface	= icl->bus_id;
-
-	ret = soc_camera_device_register(icd);
-	if (ret)
-		goto eisdr;
-	return 0;
+	icd->ops		= &mt9m111_ops;
+	icd->y_skip_top		= 0;
+
+	mt9m111->rect.left	= MT9M111_MIN_DARK_COLS;
+	mt9m111->rect.top	= MT9M111_MIN_DARK_ROWS;
+	mt9m111->rect.width	= MT9M111_MAX_WIDTH;
+	mt9m111->rect.height	= MT9M111_MAX_HEIGHT;
+
+	ret = mt9m111_video_probe(icd, client);
+	if (ret) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(mt9m111);
+	}
 
-eisdr:
-	kfree(mt9m111);
 	return ret;
 }
 
 static int mt9m111_remove(struct i2c_client *client)
 {
-	struct mt9m111 *mt9m111 = i2c_get_clientdata(client);
-	soc_camera_device_unregister(&mt9m111->icd);
+	struct mt9m111 *mt9m111 = to_mt9m111(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
+
+	icd->ops = NULL;
+	i2c_set_clientdata(client, NULL);
+	client->driver = NULL;
 	kfree(mt9m111);
 
 	return 0;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 4207fb3..6966f64 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -13,13 +13,13 @@
 #include <linux/i2c.h>
 #include <linux/log2.h>
 
-#include <media/v4l2-common.h>
+#include <media/v4l2-subdev.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
 /* mt9t031 i2c address 0x5d
- * The platform has to define i2c_board_info
- * and call i2c_register_board_info() */
+ * The platform has to define i2c_board_info and link to it from
+ * struct soc_camera_link */
 
 /* mt9t031 selected register addresses */
 #define MT9T031_CHIP_VERSION		0x00
@@ -47,7 +47,7 @@
 #define MT9T031_MAX_HEIGHT		1536
 #define MT9T031_MAX_WIDTH		2048
 #define MT9T031_MIN_HEIGHT		2
-#define MT9T031_MIN_WIDTH		2
+#define MT9T031_MIN_WIDTH		18
 #define MT9T031_HORIZONTAL_BLANK	142
 #define MT9T031_VERTICAL_BLANK		25
 #define MT9T031_COLUMN_SKIP		32
@@ -68,14 +68,21 @@ static const struct soc_camera_data_format mt9t031_colour_formats[] = {
 };
 
 struct mt9t031 {
-	struct i2c_client *client;
-	struct soc_camera_device icd;
+	struct v4l2_subdev subdev;
+	struct v4l2_rect rect;	/* Sensor window */
 	int model;	/* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
-	unsigned char autoexposure;
 	u16 xskip;
 	u16 yskip;
+	unsigned int gain;
+	unsigned int exposure;
+	unsigned char autoexposure;
 };
 
+static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct mt9t031, subdev);
+}
+
 static int reg_read(struct i2c_client *client, const u8 reg)
 {
 	s32 data = i2c_smbus_read_word_data(client, reg);
@@ -136,21 +143,10 @@ static int get_shutter(struct i2c_client *client, u32 *data)
 	return ret < 0 ? ret : 0;
 }
 
-static int mt9t031_init(struct soc_camera_device *icd)
+static int mt9t031_idle(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct soc_camera_link *icl = client->dev.platform_data;
 	int ret;
 
-	if (icl->power) {
-		ret = icl->power(&client->dev, 1);
-		if (ret < 0) {
-			dev_err(icd->vdev->parent,
-				"Platform failed to power-on the camera.\n");
-			return ret;
-		}
-	}
-
 	/* Disable chip output, synchronous option update */
 	ret = reg_write(client, MT9T031_RESET, 1);
 	if (ret >= 0)
@@ -158,50 +154,39 @@ static int mt9t031_init(struct soc_camera_device *icd)
 	if (ret >= 0)
 		ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
 
-	if (ret < 0 && icl->power)
-		icl->power(&client->dev, 0);
-
 	return ret >= 0 ? 0 : -EIO;
 }
 
-static int mt9t031_release(struct soc_camera_device *icd)
+static int mt9t031_disable(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct soc_camera_link *icl = client->dev.platform_data;
-
 	/* Disable the chip */
 	reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
 
-	if (icl->power)
-		icl->power(&client->dev, 0);
-
 	return 0;
 }
 
-static int mt9t031_start_capture(struct soc_camera_device *icd)
+static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-
-	/* Switch to master "normal" mode */
-	if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
-		return -EIO;
-	return 0;
-}
+	struct i2c_client *client = sd->priv;
+	int ret;
 
-static int mt9t031_stop_capture(struct soc_camera_device *icd)
-{
-	struct i2c_client *client = to_i2c_client(icd->control);
+	if (enable)
+		/* Switch to master "normal" mode */
+		ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 2);
+	else
+		/* Stop sensor readout */
+		ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
 
-	/* Stop sensor readout */
-	if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
+	if (ret < 0)
 		return -EIO;
+
 	return 0;
 }
 
 static int mt9t031_set_bus_param(struct soc_camera_device *icd,
 				 unsigned long flags)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
 
 	/* The caller should have queried our parameters, check anyway */
 	if (flags & ~MT9T031_BUS_PARAM)
@@ -217,69 +202,73 @@ static int mt9t031_set_bus_param(struct soc_camera_device *icd,
 
 static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
-	struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 
 	return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
 }
 
-/* Round up minima and round down maxima */
-static void recalculate_limits(struct soc_camera_device *icd,
-			       u16 xskip, u16 yskip)
+/* target must be _even_ */
+static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
 {
-	icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip;
-	icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip;
-	icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip;
-	icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip;
-	icd->width_max = MT9T031_MAX_WIDTH / xskip;
-	icd->height_max = MT9T031_MAX_HEIGHT / yskip;
+	unsigned int skip;
+
+	if (*source < target + target / 2) {
+		*source = target;
+		return 1;
+	}
+
+	skip = min(max, *source + target / 2) / target;
+	if (skip > 8)
+		skip = 8;
+	*source = target * skip;
+
+	return skip;
 }
 
+/* rect is the sensor rectangle, the caller guarantees parameter validity */
 static int mt9t031_set_params(struct soc_camera_device *icd,
 			      struct v4l2_rect *rect, u16 xskip, u16 yskip)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	int ret;
-	u16 xbin, ybin, width, height, left, top;
+	u16 xbin, ybin;
 	const u16 hblank = MT9T031_HORIZONTAL_BLANK,
 		vblank = MT9T031_VERTICAL_BLANK;
 
-	/* Make sure we don't exceed sensor limits */
-	if (rect->left + rect->width > icd->width_max)
-		rect->left = (icd->width_max - rect->width) / 2 + icd->x_min;
-
-	if (rect->top + rect->height > icd->height_max)
-		rect->top = (icd->height_max - rect->height) / 2 + icd->y_min;
-
-	width = rect->width * xskip;
-	height = rect->height * yskip;
-	left = rect->left * xskip;
-	top = rect->top * yskip;
-
 	xbin = min(xskip, (u16)3);
 	ybin = min(yskip, (u16)3);
 
-	dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n",
-		xskip, width, rect->width, yskip, height, rect->height);
-
-	/* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */
+	/*
+	 * Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper.
+	 * There is always a valid suitably aligned value. The worst case is
+	 * xbin = 3, width = 2048. Then we will start at 36, the last read out
+	 * pixel will be 2083, which is < 2085 - first black pixel.
+	 *
+	 * MT9T031 datasheet imposes window left border alignment, depending on
+	 * the selected xskip. Failing to conform to this requirement produces
+	 * dark horizontal stripes in the image. However, even obeying to this
+	 * requirement doesn't eliminate the stripes in all configurations. They
+	 * appear "locally reproducibly," but can differ between tests under
+	 * different lighting conditions.
+	 */
 	switch (xbin) {
-	case 2:
-		left = (left + 3) & ~3;
+	case 1:
+		rect->left &= ~1;
 		break;
-	case 3:
-		left = roundup(left, 6);
-	}
-
-	switch (ybin) {
 	case 2:
-		top = (top + 3) & ~3;
+		rect->left &= ~3;
 		break;
 	case 3:
-		top = roundup(top, 6);
+		rect->left = rect->left > roundup(MT9T031_COLUMN_SKIP, 6) ?
+			(rect->left / 6) * 6 : roundup(MT9T031_COLUMN_SKIP, 6);
 	}
 
+	rect->top &= ~1;
+
+	dev_dbg(&client->dev, "skip %u:%u, rect %ux%u@%u:%u\n",
+		xskip, yskip, rect->width, rect->height, rect->left, rect->top);
+
 	/* Disable register update, reconfigure atomically */
 	ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1);
 	if (ret < 0)
@@ -299,29 +288,30 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
 			ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
 					((ybin - 1) << 4) | (yskip - 1));
 	}
-	dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
+	dev_dbg(&client->dev, "new physical left %u, top %u\n",
+		rect->left, rect->top);
 
 	/* The caller provides a supported format, as guaranteed by
 	 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
 	if (ret >= 0)
-		ret = reg_write(client, MT9T031_COLUMN_START, left);
+		ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
 	if (ret >= 0)
-		ret = reg_write(client, MT9T031_ROW_START, top);
+		ret = reg_write(client, MT9T031_ROW_START, rect->top);
 	if (ret >= 0)
-		ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1);
+		ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1);
 	if (ret >= 0)
 		ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
-				height + icd->y_skip_top - 1);
+				rect->height + icd->y_skip_top - 1);
 	if (ret >= 0 && mt9t031->autoexposure) {
-		ret = set_shutter(client, height + icd->y_skip_top + vblank);
+		unsigned int total_h = rect->height + icd->y_skip_top + vblank;
+		ret = set_shutter(client, total_h);
 		if (ret >= 0) {
 			const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
 			const struct v4l2_queryctrl *qctrl =
 				soc_camera_find_qctrl(icd->ops,
 						      V4L2_CID_EXPOSURE);
-			icd->exposure = (shutter_max / 2 + (height +
-					 icd->y_skip_top + vblank - 1) *
-					 (qctrl->maximum - qctrl->minimum)) /
+			mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
+				 (qctrl->maximum - qctrl->minimum)) /
 				shutter_max + qctrl->minimum;
 		}
 	}
@@ -330,58 +320,99 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
 	if (ret >= 0)
 		ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
 
+	if (ret >= 0) {
+		mt9t031->rect = *rect;
+		mt9t031->xskip = xskip;
+		mt9t031->yskip = yskip;
+	}
+
 	return ret < 0 ? ret : 0;
 }
 
-static int mt9t031_set_crop(struct soc_camera_device *icd,
-			    struct v4l2_rect *rect)
+static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct v4l2_rect rect = a->c;
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
+
+	rect.width = ALIGN(rect.width, 2);
+	rect.height = ALIGN(rect.height, 2);
+
+	soc_camera_limit_side(&rect.left, &rect.width,
+		     MT9T031_COLUMN_SKIP, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH);
+
+	soc_camera_limit_side(&rect.top, &rect.height,
+		     MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
 
-	/* CROP - no change in scaling, or in limits */
-	return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
+	return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip);
 }
 
-static int mt9t031_set_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
-	int ret;
-	u16 xskip, yskip;
-	struct v4l2_rect rect = {
-		.left	= icd->x_current,
-		.top	= icd->y_current,
-		.width	= f->fmt.pix.width,
-		.height	= f->fmt.pix.height,
-	};
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
 
-	/*
-	 * try_fmt has put rectangle within limits.
-	 * S_FMT - use binning and skipping for scaling, recalculate
-	 * limits, used for cropping
-	 */
-	/* Is this more optimal than just a division? */
-	for (xskip = 8; xskip > 1; xskip--)
-		if (rect.width * xskip <= MT9T031_MAX_WIDTH)
-			break;
+	a->c	= mt9t031->rect;
+	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-	for (yskip = 8; yskip > 1; yskip--)
-		if (rect.height * yskip <= MT9T031_MAX_HEIGHT)
-			break;
+	return 0;
+}
 
-	recalculate_limits(icd, xskip, yskip);
+static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= MT9T031_COLUMN_SKIP;
+	a->bounds.top			= MT9T031_ROW_SKIP;
+	a->bounds.width			= MT9T031_MAX_WIDTH;
+	a->bounds.height		= MT9T031_MAX_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
 
-	ret = mt9t031_set_params(icd, &rect, xskip, yskip);
-	if (!ret) {
-		mt9t031->xskip = xskip;
-		mt9t031->yskip = yskip;
-	}
+	return 0;
+}
 
-	return ret;
+static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	pix->width		= mt9t031->rect.width / mt9t031->xskip;
+	pix->height		= mt9t031->rect.height / mt9t031->yskip;
+	pix->pixelformat	= V4L2_PIX_FMT_SGRBG10;
+	pix->field		= V4L2_FIELD_NONE;
+	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+
+	return 0;
+}
+
+static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	u16 xskip, yskip;
+	struct v4l2_rect rect = mt9t031->rect;
+
+	/*
+	 * try_fmt has put width and height within limits.
+	 * S_FMT: use binning and skipping for scaling
+	 */
+	xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH);
+	yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT);
+
+	/* mt9t031_set_params() doesn't change width and height */
+	return mt9t031_set_params(icd, &rect, xskip, yskip);
 }
 
-static int mt9t031_try_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+/*
+ * If a user window larger than sensor window is requested, we'll increase the
+ * sensor window.
+ */
+static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
@@ -392,15 +423,16 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int mt9t031_get_chip_id(struct soc_camera_device *icd,
-			       struct v4l2_dbg_chip_ident *id)
+static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *id)
 {
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
 
 	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
 		return -EINVAL;
 
-	if (id->match.addr != mt9t031->client->addr)
+	if (id->match.addr != client->addr)
 		return -ENODEV;
 
 	id->ident	= mt9t031->model;
@@ -410,10 +442,10 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd,
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9t031_get_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9t031_g_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
@@ -429,10 +461,10 @@ static int mt9t031_get_register(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int mt9t031_set_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9t031_s_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
@@ -493,39 +525,17 @@ static const struct v4l2_queryctrl mt9t031_controls[] = {
 	}
 };
 
-static int mt9t031_video_probe(struct soc_camera_device *);
-static void mt9t031_video_remove(struct soc_camera_device *);
-static int mt9t031_get_control(struct soc_camera_device *, struct v4l2_control *);
-static int mt9t031_set_control(struct soc_camera_device *, struct v4l2_control *);
-
 static struct soc_camera_ops mt9t031_ops = {
-	.owner			= THIS_MODULE,
-	.probe			= mt9t031_video_probe,
-	.remove			= mt9t031_video_remove,
-	.init			= mt9t031_init,
-	.release		= mt9t031_release,
-	.start_capture		= mt9t031_start_capture,
-	.stop_capture		= mt9t031_stop_capture,
-	.set_crop		= mt9t031_set_crop,
-	.set_fmt		= mt9t031_set_fmt,
-	.try_fmt		= mt9t031_try_fmt,
 	.set_bus_param		= mt9t031_set_bus_param,
 	.query_bus_param	= mt9t031_query_bus_param,
 	.controls		= mt9t031_controls,
 	.num_controls		= ARRAY_SIZE(mt9t031_controls),
-	.get_control		= mt9t031_get_control,
-	.set_control		= mt9t031_set_control,
-	.get_chip_id		= mt9t031_get_chip_id,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.get_register		= mt9t031_get_register,
-	.set_register		= mt9t031_set_register,
-#endif
 };
 
-static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
+static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	int data;
 
 	switch (ctrl->id) {
@@ -544,14 +554,21 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro
 	case V4L2_CID_EXPOSURE_AUTO:
 		ctrl->value = mt9t031->autoexposure;
 		break;
+	case V4L2_CID_GAIN:
+		ctrl->value = mt9t031->gain;
+		break;
+	case V4L2_CID_EXPOSURE:
+		ctrl->value = mt9t031->exposure;
+		break;
 	}
 	return 0;
 }
 
-static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl)
+static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 	const struct v4l2_queryctrl *qctrl;
 	int data;
 
@@ -586,7 +603,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 			unsigned long range = qctrl->default_value - qctrl->minimum;
 			data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
 
-			dev_dbg(&icd->dev, "Setting gain %d\n", data);
+			dev_dbg(&client->dev, "Setting gain %d\n", data);
 			data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
 			if (data < 0)
 				return -EIO;
@@ -606,7 +623,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 				/* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */
 				data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
 
-			dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
+			dev_dbg(&client->dev, "Set gain from 0x%x to 0x%x\n",
 				reg_read(client, MT9T031_GLOBAL_GAIN), data);
 			data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
 			if (data < 0)
@@ -614,7 +631,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 		}
 
 		/* Success */
-		icd->gain = ctrl->value;
+		mt9t031->gain = ctrl->value;
 		break;
 	case V4L2_CID_EXPOSURE:
 		/* mt9t031 has maximum == default */
@@ -627,11 +644,11 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 			u32 old;
 
 			get_shutter(client, &old);
-			dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n",
+			dev_dbg(&client->dev, "Set shutter from %u to %u\n",
 				old, shutter);
 			if (set_shutter(client, shutter) < 0)
 				return -EIO;
-			icd->exposure = ctrl->value;
+			mt9t031->exposure = ctrl->value;
 			mt9t031->autoexposure = 0;
 		}
 		break;
@@ -639,13 +656,14 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 		if (ctrl->value) {
 			const u16 vblank = MT9T031_VERTICAL_BLANK;
 			const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
-			if (set_shutter(client, icd->height +
-					icd->y_skip_top + vblank) < 0)
+			unsigned int total_h = mt9t031->rect.height +
+				icd->y_skip_top + vblank;
+
+			if (set_shutter(client, total_h) < 0)
 				return -EIO;
 			qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
-			icd->exposure = (shutter_max / 2 + (icd->height +
-					 icd->y_skip_top + vblank - 1) *
-					 (qctrl->maximum - qctrl->minimum)) /
+			mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
+				 (qctrl->maximum - qctrl->minimum)) /
 				shutter_max + qctrl->minimum;
 			mt9t031->autoexposure = 1;
 		} else
@@ -657,22 +675,16 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
 
 /* Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one */
-static int mt9t031_video_probe(struct soc_camera_device *icd)
+static int mt9t031_video_probe(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+	struct soc_camera_device *icd = client->dev.platform_data;
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
 	s32 data;
 	int ret;
 
-	/* We must have a parent by now. And it cannot be a wrong one.
-	 * So this entire test is completely redundant. */
-	if (!icd->dev.parent ||
-	    to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
-		return -ENODEV;
-
 	/* Enable the chip */
 	data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
-	dev_dbg(&icd->dev, "write: %d\n", data);
+	dev_dbg(&client->dev, "write: %d\n", data);
 
 	/* Read out the chip version register */
 	data = reg_read(client, MT9T031_CHIP_VERSION);
@@ -684,44 +696,64 @@ static int mt9t031_video_probe(struct soc_camera_device *icd)
 		icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats);
 		break;
 	default:
-		ret = -ENODEV;
-		dev_err(&icd->dev,
+		dev_err(&client->dev,
 			"No MT9T031 chip detected, register read %x\n", data);
-		goto ei2c;
+		return -ENODEV;
 	}
 
-	dev_info(&icd->dev, "Detected a MT9T031 chip ID %x\n", data);
+	dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
 
-	/* Now that we know the model, we can start video */
-	ret = soc_camera_video_start(icd);
-	if (ret)
-		goto evstart;
+	ret = mt9t031_idle(client);
+	if (ret < 0)
+		dev_err(&client->dev, "Failed to initialise the camera\n");
 
-	return 0;
+	/* mt9t031_idle() has reset the chip to default. */
+	mt9t031->exposure = 255;
+	mt9t031->gain = 64;
 
-evstart:
-ei2c:
 	return ret;
 }
 
-static void mt9t031_video_remove(struct soc_camera_device *icd)
-{
-	struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
+	.g_ctrl		= mt9t031_g_ctrl,
+	.s_ctrl		= mt9t031_s_ctrl,
+	.g_chip_ident	= mt9t031_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register	= mt9t031_g_register,
+	.s_register	= mt9t031_s_register,
+#endif
+};
 
-	dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9t031->client->addr,
-		icd->dev.parent, icd->vdev);
-	soc_camera_video_stop(icd);
-}
+static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
+	.s_stream	= mt9t031_s_stream,
+	.s_fmt		= mt9t031_s_fmt,
+	.g_fmt		= mt9t031_g_fmt,
+	.try_fmt	= mt9t031_try_fmt,
+	.s_crop		= mt9t031_s_crop,
+	.g_crop		= mt9t031_g_crop,
+	.cropcap	= mt9t031_cropcap,
+};
+
+static struct v4l2_subdev_ops mt9t031_subdev_ops = {
+	.core	= &mt9t031_subdev_core_ops,
+	.video	= &mt9t031_subdev_video_ops,
+};
 
 static int mt9t031_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
 	struct mt9t031 *mt9t031;
-	struct soc_camera_device *icd;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct soc_camera_link *icl;
 	int ret;
 
+	if (!icd) {
+		dev_err(&client->dev, "MT9T031: missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
 	if (!icl) {
 		dev_err(&client->dev, "MT9T031 driver needs platform data\n");
 		return -EINVAL;
@@ -737,23 +769,17 @@ static int mt9t031_probe(struct i2c_client *client,
 	if (!mt9t031)
 		return -ENOMEM;
 
-	mt9t031->client = client;
-	i2c_set_clientdata(client, mt9t031);
+	v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
 
 	/* Second stage probe - when a capture adapter is there */
-	icd = &mt9t031->icd;
-	icd->ops	= &mt9t031_ops;
-	icd->control	= &client->dev;
-	icd->x_min	= MT9T031_COLUMN_SKIP;
-	icd->y_min	= MT9T031_ROW_SKIP;
-	icd->x_current	= icd->x_min;
-	icd->y_current	= icd->y_min;
-	icd->width_min	= MT9T031_MIN_WIDTH;
-	icd->width_max	= MT9T031_MAX_WIDTH;
-	icd->height_min	= MT9T031_MIN_HEIGHT;
-	icd->height_max	= MT9T031_MAX_HEIGHT;
-	icd->y_skip_top	= 0;
-	icd->iface	= icl->bus_id;
+	icd->ops		= &mt9t031_ops;
+	icd->y_skip_top		= 0;
+
+	mt9t031->rect.left	= MT9T031_COLUMN_SKIP;
+	mt9t031->rect.top	= MT9T031_ROW_SKIP;
+	mt9t031->rect.width	= MT9T031_MAX_WIDTH;
+	mt9t031->rect.height	= MT9T031_MAX_HEIGHT;
+
 	/* Simulated autoexposure. If enabled, we calculate shutter width
 	 * ourselves in the driver based on vertical blanking and frame width */
 	mt9t031->autoexposure = 1;
@@ -761,24 +787,29 @@ static int mt9t031_probe(struct i2c_client *client,
 	mt9t031->xskip = 1;
 	mt9t031->yskip = 1;
 
-	ret = soc_camera_device_register(icd);
-	if (ret)
-		goto eisdr;
+	mt9t031_idle(client);
 
-	return 0;
+	ret = mt9t031_video_probe(client);
+
+	mt9t031_disable(client);
+
+	if (ret) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(mt9t031);
+	}
 
-eisdr:
-	i2c_set_clientdata(client, NULL);
-	kfree(mt9t031);
 	return ret;
 }
 
 static int mt9t031_remove(struct i2c_client *client)
 {
-	struct mt9t031 *mt9t031 = i2c_get_clientdata(client);
+	struct mt9t031 *mt9t031 = to_mt9t031(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 
-	soc_camera_device_unregister(&mt9t031->icd);
+	icd->ops = NULL;
 	i2c_set_clientdata(client, NULL);
+	client->driver = NULL;
 	kfree(mt9t031);
 
 	return 0;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index dbdcc86..995607f 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -14,13 +14,13 @@
 #include <linux/delay.h>
 #include <linux/log2.h>
 
-#include <media/v4l2-common.h>
+#include <media/v4l2-subdev.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/soc_camera.h>
 
 /* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
- * The platform has to define i2c_board_info
- * and call i2c_register_board_info() */
+ * The platform has to define ctruct i2c_board_info objects and link to them
+ * from struct soc_camera_link */
 
 static char *sensor_type;
 module_param(sensor_type, charp, S_IRUGO);
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
 #define MT9V022_PIXEL_OPERATION_MODE	0x0f
 #define MT9V022_LED_OUT_CONTROL		0x1b
 #define MT9V022_ADC_MODE_CONTROL	0x1c
-#define MT9V022_ANALOG_GAIN		0x34
+#define MT9V022_ANALOG_GAIN		0x35
 #define MT9V022_BLACK_LEVEL_CALIB_CTRL	0x47
 #define MT9V022_PIXCLK_FV_LV		0x74
 #define MT9V022_DIGITAL_TEST_PATTERN	0x7f
@@ -55,6 +55,13 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
 /* Progressive scan, master, defaults */
 #define MT9V022_CHIP_CONTROL_DEFAULT	0x188
 
+#define MT9V022_MAX_WIDTH		752
+#define MT9V022_MAX_HEIGHT		480
+#define MT9V022_MIN_WIDTH		48
+#define MT9V022_MIN_HEIGHT		32
+#define MT9V022_COLUMN_SKIP		1
+#define MT9V022_ROW_SKIP		4
+
 static const struct soc_camera_data_format mt9v022_colour_formats[] = {
 	/* Order important: first natively supported,
 	 * second supported with a GPIO extender */
@@ -85,12 +92,18 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
 };
 
 struct mt9v022 {
-	struct i2c_client *client;
-	struct soc_camera_device icd;
+	struct v4l2_subdev subdev;
+	struct v4l2_rect rect;	/* Sensor window */
+	__u32 fourcc;
 	int model;	/* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
 	u16 chip_control;
 };
 
+static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
+}
+
 static int reg_read(struct i2c_client *client, const u8 reg)
 {
 	s32 data = i2c_smbus_read_word_data(client, reg);
@@ -125,29 +138,11 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
 	return reg_write(client, reg, ret & ~data);
 }
 
-static int mt9v022_init(struct soc_camera_device *icd)
+static int mt9v022_init(struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
 	int ret;
 
-	if (icl->power) {
-		ret = icl->power(&client->dev, 1);
-		if (ret < 0) {
-			dev_err(icd->vdev->parent,
-				"Platform failed to power-on the camera.\n");
-			return ret;
-		}
-	}
-
-	/*
-	 * The camera could have been already on, we hard-reset it additionally,
-	 * if available. Soft reset is done in video_probe().
-	 */
-	if (icl->reset)
-		icl->reset(&client->dev);
-
 	/* Almost the default mode: master, parallel, simultaneous, and an
 	 * undocumented bit 0x200, which is present in table 7, but not in 8,
 	 * plus snapshot mode to disable scan for now */
@@ -161,6 +156,10 @@ static int mt9v022_init(struct soc_camera_device *icd)
 		/* AEC, AGC on */
 		ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
 	if (!ret)
+		ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
+	if (!ret)
+		ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
+	if (!ret)
 		ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
 	if (!ret)
 		/* default - auto */
@@ -171,37 +170,19 @@ static int mt9v022_init(struct soc_camera_device *icd)
 	return ret;
 }
 
-static int mt9v022_release(struct soc_camera_device *icd)
+static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
-
-	if (icl->power)
-		icl->power(&mt9v022->client->dev, 0);
-
-	return 0;
-}
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
 
-static int mt9v022_start_capture(struct soc_camera_device *icd)
-{
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	/* Switch to master "normal" mode */
-	mt9v022->chip_control &= ~0x10;
-	if (reg_write(client, MT9V022_CHIP_CONTROL,
-		      mt9v022->chip_control) < 0)
-		return -EIO;
-	return 0;
-}
+	if (enable)
+		/* Switch to master "normal" mode */
+		mt9v022->chip_control &= ~0x10;
+	else
+		/* Switch to snapshot mode */
+		mt9v022->chip_control |= 0x10;
 
-static int mt9v022_stop_capture(struct soc_camera_device *icd)
-{
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	/* Switch to snapshot mode */
-	mt9v022->chip_control |= 0x10;
-	if (reg_write(client, MT9V022_CHIP_CONTROL,
-		      mt9v022->chip_control) < 0)
+	if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
 		return -EIO;
 	return 0;
 }
@@ -209,9 +190,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
 static int mt9v022_set_bus_param(struct soc_camera_device *icd,
 				 unsigned long flags)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
 	int ret;
 	u16 pixclk = 0;
@@ -255,7 +236,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
 	if (ret < 0)
 		return ret;
 
-	dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
+	dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
 		pixclk, mt9v022->chip_control);
 
 	return 0;
@@ -263,8 +244,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
 
 static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned int width_flag;
 
 	if (icl->query_bus_param)
@@ -280,60 +260,121 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
 		width_flag;
 }
 
-static int mt9v022_set_crop(struct soc_camera_device *icd,
-			    struct v4l2_rect *rect)
+static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+	struct v4l2_rect rect = a->c;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	int ret;
 
+	/* Bayer format - even size lengths */
+	if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 ||
+	    mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
+		rect.width	= ALIGN(rect.width, 2);
+		rect.height	= ALIGN(rect.height, 2);
+		/* Let the user play with the starting pixel */
+	}
+
+	soc_camera_limit_side(&rect.left, &rect.width,
+		     MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
+
+	soc_camera_limit_side(&rect.top, &rect.height,
+		     MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
+
 	/* Like in example app. Contradicts the datasheet though */
 	ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
 	if (ret >= 0) {
 		if (ret & 1) /* Autoexposure */
 			ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
-					rect->height + icd->y_skip_top + 43);
+					rect.height + icd->y_skip_top + 43);
 		else
 			ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
-					rect->height + icd->y_skip_top + 43);
+					rect.height + icd->y_skip_top + 43);
 	}
 	/* Setup frame format: defaults apart from width and height */
 	if (!ret)
-		ret = reg_write(client, MT9V022_COLUMN_START, rect->left);
+		ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
 	if (!ret)
-		ret = reg_write(client, MT9V022_ROW_START, rect->top);
+		ret = reg_write(client, MT9V022_ROW_START, rect.top);
 	if (!ret)
 		/* Default 94, Phytec driver says:
 		 * "width + horizontal blank >= 660" */
 		ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
-				rect->width > 660 - 43 ? 43 :
-				660 - rect->width);
+				rect.width > 660 - 43 ? 43 :
+				660 - rect.width);
 	if (!ret)
 		ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
 	if (!ret)
-		ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width);
+		ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
 	if (!ret)
 		ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
-				rect->height + icd->y_skip_top);
+				rect.height + icd->y_skip_top);
 
 	if (ret < 0)
 		return ret;
 
-	dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height);
+	dev_dbg(&client->dev, "Frame %ux%u pixel\n", rect.width, rect.height);
+
+	mt9v022->rect = rect;
+
+	return 0;
+}
+
+static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+
+	a->c	= mt9v022->rect;
+	a->type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
 	return 0;
 }
 
-static int mt9v022_set_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+	a->bounds.left			= MT9V022_COLUMN_SKIP;
+	a->bounds.top			= MT9V022_ROW_SKIP;
+	a->bounds.width			= MT9V022_MAX_WIDTH;
+	a->bounds.height		= MT9V022_MAX_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
 	struct v4l2_pix_format *pix = &f->fmt.pix;
-	struct v4l2_rect rect = {
-		.left	= icd->x_current,
-		.top	= icd->y_current,
-		.width	= pix->width,
-		.height	= pix->height,
+
+	pix->width		= mt9v022->rect.width;
+	pix->height		= mt9v022->rect.height;
+	pix->pixelformat	= mt9v022->fourcc;
+	pix->field		= V4L2_FIELD_NONE;
+	pix->colorspace		= V4L2_COLORSPACE_SRGB;
+
+	return 0;
+}
+
+static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_crop a = {
+		.c = {
+			.left	= mt9v022->rect.left,
+			.top	= mt9v022->rect.top,
+			.width	= pix->width,
+			.height	= pix->height,
+		},
 	};
+	int ret;
 
 	/* The caller provides a supported format, as verified per call to
 	 * icd->try_fmt(), datawidth is from our supported format list */
@@ -356,30 +397,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
 	}
 
 	/* No support for scaling on this camera, just crop. */
-	return mt9v022_set_crop(icd, &rect);
+	ret = mt9v022_s_crop(sd, &a);
+	if (!ret) {
+		pix->width = mt9v022->rect.width;
+		pix->height = mt9v022->rect.height;
+		mt9v022->fourcc = pix->pixelformat;
+	}
+
+	return ret;
 }
 
-static int mt9v022_try_fmt(struct soc_camera_device *icd,
-			   struct v4l2_format *f)
+static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
+	struct i2c_client *client = sd->priv;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
+	int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
+		pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
 
-	v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */,
-			      &pix->height, 32 + icd->y_skip_top,
-			      480 + icd->y_skip_top, 0, 0);
+	v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
+		MT9V022_MAX_WIDTH, align,
+		&pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top,
+		MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0);
 
 	return 0;
 }
 
-static int mt9v022_get_chip_id(struct soc_camera_device *icd,
-			       struct v4l2_dbg_chip_ident *id)
+static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
+				struct v4l2_dbg_chip_ident *id)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+	struct i2c_client *client = sd->priv;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
 
 	if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
 		return -EINVAL;
 
-	if (id->match.addr != mt9v022->client->addr)
+	if (id->match.addr != client->addr)
 		return -ENODEV;
 
 	id->ident	= mt9v022->model;
@@ -389,10 +442,10 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-static int mt9v022_get_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9v022_g_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
@@ -409,10 +462,10 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int mt9v022_set_register(struct soc_camera_device *icd,
-				struct v4l2_dbg_register *reg)
+static int mt9v022_s_register(struct v4l2_subdev *sd,
+			      struct v4l2_dbg_register *reg)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
 		return -EINVAL;
@@ -481,41 +534,22 @@ static const struct v4l2_queryctrl mt9v022_controls[] = {
 	}
 };
 
-static int mt9v022_video_probe(struct soc_camera_device *);
-static void mt9v022_video_remove(struct soc_camera_device *);
-static int mt9v022_get_control(struct soc_camera_device *, struct v4l2_control *);
-static int mt9v022_set_control(struct soc_camera_device *, struct v4l2_control *);
-
 static struct soc_camera_ops mt9v022_ops = {
-	.owner			= THIS_MODULE,
-	.probe			= mt9v022_video_probe,
-	.remove			= mt9v022_video_remove,
-	.init			= mt9v022_init,
-	.release		= mt9v022_release,
-	.start_capture		= mt9v022_start_capture,
-	.stop_capture		= mt9v022_stop_capture,
-	.set_crop		= mt9v022_set_crop,
-	.set_fmt		= mt9v022_set_fmt,
-	.try_fmt		= mt9v022_try_fmt,
 	.set_bus_param		= mt9v022_set_bus_param,
 	.query_bus_param	= mt9v022_query_bus_param,
 	.controls		= mt9v022_controls,
 	.num_controls		= ARRAY_SIZE(mt9v022_controls),
-	.get_control		= mt9v022_get_control,
-	.set_control		= mt9v022_set_control,
-	.get_chip_id		= mt9v022_get_chip_id,
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	.get_register		= mt9v022_get_register,
-	.set_register		= mt9v022_set_register,
-#endif
 };
 
-static int mt9v022_get_control(struct soc_camera_device *icd,
-			       struct v4l2_control *ctrl)
+static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
+	const struct v4l2_queryctrl *qctrl;
+	unsigned long range;
 	int data;
 
+	qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
+
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
 		data = reg_read(client, MT9V022_READ_MODE);
@@ -541,19 +575,35 @@ static int mt9v022_get_control(struct soc_camera_device *icd,
 			return -EIO;
 		ctrl->value = !!(data & 0x2);
 		break;
+	case V4L2_CID_GAIN:
+		data = reg_read(client, MT9V022_ANALOG_GAIN);
+		if (data < 0)
+			return -EIO;
+
+		range = qctrl->maximum - qctrl->minimum;
+		ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum;
+
+		break;
+	case V4L2_CID_EXPOSURE:
+		data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
+		if (data < 0)
+			return -EIO;
+
+		range = qctrl->maximum - qctrl->minimum;
+		ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum;
+
+		break;
 	}
 	return 0;
 }
 
-static int mt9v022_set_control(struct soc_camera_device *icd,
-			       struct v4l2_control *ctrl)
+static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
 	int data;
-	struct i2c_client *client = to_i2c_client(icd->control);
+	struct i2c_client *client = sd->priv;
 	const struct v4l2_queryctrl *qctrl;
 
 	qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
-
 	if (!qctrl)
 		return -EINVAL;
 
@@ -580,12 +630,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 			return -EINVAL;
 		else {
 			unsigned long range = qctrl->maximum - qctrl->minimum;
-			/* Datasheet says 16 to 64. autogain only works properly
-			 * after setting gain to maximum 14. Larger values
-			 * produce "white fly" noise effect. On the whole,
-			 * manually setting analog gain does no good. */
+			/* Valid values 16 to 64, 32 to 64 must be even. */
 			unsigned long gain = ((ctrl->value - qctrl->minimum) *
-					      10 + range / 2) / range + 4;
+					      48 + range / 2) / range + 16;
 			if (gain >= 32)
 				gain &= ~1;
 			/* The user wants to set gain manually, hope, she
@@ -594,11 +641,10 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
 				return -EIO;
 
-			dev_info(&icd->dev, "Setting gain from %d to %lu\n",
-				 reg_read(client, MT9V022_ANALOG_GAIN), gain);
+			dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
+				reg_read(client, MT9V022_ANALOG_GAIN), gain);
 			if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
 				return -EIO;
-			icd->gain = ctrl->value;
 		}
 		break;
 	case V4L2_CID_EXPOSURE:
@@ -615,13 +661,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 			if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
 				return -EIO;
 
-			dev_dbg(&icd->dev, "Shutter width from %d to %lu\n",
+			dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
 				reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
 				shutter);
 			if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
 				      shutter) < 0)
 				return -EIO;
-			icd->exposure = ctrl->value;
 		}
 		break;
 	case V4L2_CID_AUTOGAIN:
@@ -646,11 +691,11 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
 
 /* Interface active, can use i2c. If it fails, it can indeed mean, that
  * this wasn't our capture interface, so, we wait for the right one */
-static int mt9v022_video_probe(struct soc_camera_device *icd)
+static int mt9v022_video_probe(struct soc_camera_device *icd,
+			       struct i2c_client *client)
 {
-	struct i2c_client *client = to_i2c_client(icd->control);
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	s32 data;
 	int ret;
 	unsigned long flags;
@@ -665,7 +710,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
 	/* must be 0x1311 or 0x1313 */
 	if (data != 0x1311 && data != 0x1313) {
 		ret = -ENODEV;
-		dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n",
+		dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
 			 data);
 		goto ei2c;
 	}
@@ -677,7 +722,9 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
 	/* 15 clock cycles */
 	udelay(200);
 	if (reg_read(client, MT9V022_RESET)) {
-		dev_err(&icd->dev, "Resetting MT9V022 failed!\n");
+		dev_err(&client->dev, "Resetting MT9V022 failed!\n");
+		if (ret > 0)
+			ret = -EIO;
 		goto ei2c;
 	}
 
@@ -694,7 +741,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
 	}
 
 	if (ret < 0)
-		goto eisis;
+		goto ei2c;
 
 	icd->num_formats = 0;
 
@@ -716,42 +763,70 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
 	if (flags & SOCAM_DATAWIDTH_8)
 		icd->num_formats++;
 
-	ret = soc_camera_video_start(icd);
-	if (ret < 0)
-		goto eisis;
+	mt9v022->fourcc = icd->formats->fourcc;
 
-	dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
+	dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
 		 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
 		 "monochrome" : "colour");
 
-	return 0;
+	ret = mt9v022_init(client);
+	if (ret < 0)
+		dev_err(&client->dev, "Failed to initialise the camera\n");
 
-eisis:
 ei2c:
 	return ret;
 }
 
 static void mt9v022_video_remove(struct soc_camera_device *icd)
 {
-	struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
-	struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 
-	dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr,
+	dev_dbg(&icd->dev, "Video removed: %p, %p\n",
 		icd->dev.parent, icd->vdev);
-	soc_camera_video_stop(icd);
 	if (icl->free_bus)
 		icl->free_bus(icl);
 }
 
+static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
+	.g_ctrl		= mt9v022_g_ctrl,
+	.s_ctrl		= mt9v022_s_ctrl,
+	.g_chip_ident	= mt9v022_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.g_register	= mt9v022_g_register,
+	.s_register	= mt9v022_s_register,
+#endif
+};
+
+static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
+	.s_stream	= mt9v022_s_stream,
+	.s_fmt		= mt9v022_s_fmt,
+	.g_fmt		= mt9v022_g_fmt,
+	.try_fmt	= mt9v022_try_fmt,
+	.s_crop		= mt9v022_s_crop,
+	.g_crop		= mt9v022_g_crop,
+	.cropcap	= mt9v022_cropcap,
+};
+
+static struct v4l2_subdev_ops mt9v022_subdev_ops = {
+	.core	= &mt9v022_subdev_core_ops,
+	.video	= &mt9v022_subdev_video_ops,
+};
+
 static int mt9v022_probe(struct i2c_client *client,
 			 const struct i2c_device_id *did)
 {
 	struct mt9v022 *mt9v022;
-	struct soc_camera_device *icd;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
-	struct soc_camera_link *icl = client->dev.platform_data;
+	struct soc_camera_link *icl;
 	int ret;
 
+	if (!icd) {
+		dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
+		return -EINVAL;
+	}
+
+	icl = to_soc_camera_link(icd);
 	if (!icl) {
 		dev_err(&client->dev, "MT9V022 driver needs platform data\n");
 		return -EINVAL;
@@ -767,40 +842,41 @@ static int mt9v022_probe(struct i2c_client *client,
 	if (!mt9v022)
 		return -ENOMEM;
 
+	v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
+
 	mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
-	mt9v022->client = client;
-	i2c_set_clientdata(client, mt9v022);
-
-	icd = &mt9v022->icd;
-	icd->ops	= &mt9v022_ops;
-	icd->control	= &client->dev;
-	icd->x_min	= 1;
-	icd->y_min	= 4;
-	icd->x_current	= 1;
-	icd->y_current	= 4;
-	icd->width_min	= 48;
-	icd->width_max	= 752;
-	icd->height_min	= 32;
-	icd->height_max	= 480;
-	icd->y_skip_top	= 1;
-	icd->iface	= icl->bus_id;
-
-	ret = soc_camera_device_register(icd);
-	if (ret)
-		goto eisdr;
 
-	return 0;
+	icd->ops		= &mt9v022_ops;
+	/*
+	 * MT9V022 _really_ corrupts the first read out line.
+	 * TODO: verify on i.MX31
+	 */
+	icd->y_skip_top		= 1;
+
+	mt9v022->rect.left	= MT9V022_COLUMN_SKIP;
+	mt9v022->rect.top	= MT9V022_ROW_SKIP;
+	mt9v022->rect.width	= MT9V022_MAX_WIDTH;
+	mt9v022->rect.height	= MT9V022_MAX_HEIGHT;
+
+	ret = mt9v022_video_probe(icd, client);
+	if (ret) {
+		icd->ops = NULL;
+		i2c_set_clientdata(client, NULL);
+		kfree(mt9v022);
+	}
 
-eisdr:
-	kfree(mt9v022);
 	return ret;
 }
 
 static int mt9v022_remove(struct i2c_client *client)
 {
-	struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
+	struct mt9v022 *mt9v022 = to_mt9v022(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 
-	soc_camera_device_unregister(&mt9v022->icd);
+	icd->ops = NULL;
+	mt9v022_video_remove(icd);
+	i2c_set_clientdata(client, NULL);
+	client->driver = NULL;
 	kfree(mt9v022);
 
 	return 0;
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 736c31d..5f37952 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -126,7 +126,7 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
 {
 	struct soc_camera_device *icd = vq->priv_data;
 
-	*size = icd->width * icd->height *
+	*size = icd->user_width * icd->user_height *
 		((icd->current_fmt->depth + 7) >> 3);
 
 	if (!*count)
@@ -135,7 +135,7 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
 	while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
 		(*count)--;
 
-	dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
+	dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
 
 	return 0;
 }
@@ -147,7 +147,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
 
 	BUG_ON(in_interrupt());
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	/* This waits until this buffer is out of danger, i.e., until it is no
@@ -165,7 +165,7 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
 	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
 	int ret;
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	/* Added list head initialization on alloc */
@@ -178,12 +178,12 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
 	buf->inwork = 1;
 
 	if (buf->fmt	!= icd->current_fmt ||
-	    vb->width	!= icd->width ||
-	    vb->height	!= icd->height ||
+	    vb->width	!= icd->user_width ||
+	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
 		buf->fmt	= icd->current_fmt;
-		vb->width	= icd->width;
-		vb->height	= icd->height;
+		vb->width	= icd->user_width;
+		vb->height	= icd->user_height;
 		vb->field	= field;
 		vb->state	= VIDEOBUF_NEEDS_INIT;
 	}
@@ -216,10 +216,11 @@ out:
 static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
 {
 	struct videobuf_buffer *vbuf = &pcdev->active->vb;
+	struct device *dev = pcdev->icd->dev.parent;
 	int ret;
 
 	if (unlikely(!pcdev->active)) {
-		dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
+		dev_err(dev, "DMA End IRQ with no active buffer\n");
 		return -EFAULT;
 	}
 
@@ -229,7 +230,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
 		vbuf->size, pcdev->res->start +
 		CSIRXR, DMA_MODE_READ);
 	if (unlikely(ret))
-		dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n");
+		dev_err(dev, "Failed to setup DMA sg list\n");
 
 	return ret;
 }
@@ -243,7 +244,7 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
 	struct mx1_camera_dev *pcdev = ici->priv;
 	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	list_add_tail(&vb->queue, &pcdev->capture);
@@ -270,22 +271,23 @@ static void mx1_videobuf_release(struct videobuf_queue *vq,
 	struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
 #ifdef DEBUG
 	struct soc_camera_device *icd = vq->priv_data;
+	struct device *dev = icd->dev.parent;
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	switch (vb->state) {
 	case VIDEOBUF_ACTIVE:
-		dev_dbg(&icd->dev, "%s (active)\n", __func__);
+		dev_dbg(dev, "%s (active)\n", __func__);
 		break;
 	case VIDEOBUF_QUEUED:
-		dev_dbg(&icd->dev, "%s (queued)\n", __func__);
+		dev_dbg(dev, "%s (queued)\n", __func__);
 		break;
 	case VIDEOBUF_PREPARED:
-		dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
+		dev_dbg(dev, "%s (prepared)\n", __func__);
 		break;
 	default:
-		dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
+		dev_dbg(dev, "%s (unknown)\n", __func__);
 		break;
 	}
 #endif
@@ -325,6 +327,7 @@ static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
 static void mx1_camera_dma_irq(int channel, void *data)
 {
 	struct mx1_camera_dev *pcdev = data;
+	struct device *dev = pcdev->icd->dev.parent;
 	struct mx1_buffer *buf;
 	struct videobuf_buffer *vb;
 	unsigned long flags;
@@ -334,14 +337,14 @@ static void mx1_camera_dma_irq(int channel, void *data)
 	imx_dma_disable(channel);
 
 	if (unlikely(!pcdev->active)) {
-		dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n");
+		dev_err(dev, "DMA End IRQ with no active buffer\n");
 		goto out;
 	}
 
 	vb = &pcdev->active->vb;
 	buf = container_of(vb, struct mx1_buffer, vb);
 	WARN_ON(buf->inwork || list_empty(&vb->queue));
-	dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	mx1_camera_wakeup(pcdev, vb, buf);
@@ -362,7 +365,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q,
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx1_camera_dev *pcdev = ici->priv;
 
-	videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev,
+	videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->dev.parent,
 					&pcdev->lock,
 					V4L2_BUF_TYPE_VIDEO_CAPTURE,
 					V4L2_FIELD_NONE,
@@ -381,8 +384,9 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
 	 * they get a nice Oops */
 	div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
 
-	dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, "
-		"divisor %lu\n", lcdclk / 1000, mclk / 1000, div);
+	dev_dbg(pcdev->icd->dev.parent,
+		"System clock %lukHz, target freq %dkHz, divisor %lu\n",
+		lcdclk / 1000, mclk / 1000, div);
 
 	return div;
 }
@@ -391,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
 {
 	unsigned int csicr1 = CSICR1_EN;
 
-	dev_dbg(pcdev->soc_host.dev, "Activate device\n");
+	dev_dbg(pcdev->icd->dev.parent, "Activate device\n");
 
 	clk_enable(pcdev->clk);
 
@@ -407,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
 
 static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
 {
-	dev_dbg(pcdev->soc_host.dev, "Deactivate device\n");
+	dev_dbg(pcdev->icd->dev.parent, "Deactivate device\n");
 
 	/* Disable all CSI interface */
 	__raw_writel(0x00, pcdev->base + CSICR1);
@@ -428,14 +432,12 @@ static int mx1_camera_add_device(struct soc_camera_device *icd)
 		goto ebusy;
 	}
 
-	dev_info(&icd->dev, "MX1 Camera driver attached to camera %d\n",
+	dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n",
 		 icd->devnum);
 
 	mx1_camera_activate(pcdev);
-	ret = icd->ops->init(icd);
 
-	if (!ret)
-		pcdev->icd = icd;
+	pcdev->icd = icd;
 
 ebusy:
 	return ret;
@@ -456,20 +458,20 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
 	/* Stop DMA engine */
 	imx_dma_disable(pcdev->dma_chan);
 
-	dev_info(&icd->dev, "MX1 Camera driver detached from camera %d\n",
+	dev_info(icd->dev.parent, "MX1 Camera driver detached from camera %d\n",
 		 icd->devnum);
 
-	icd->ops->release(icd);
-
 	mx1_camera_deactivate(pcdev);
 
 	pcdev->icd = NULL;
 }
 
 static int mx1_camera_set_crop(struct soc_camera_device *icd,
-			       struct v4l2_rect *rect)
+			       struct v4l2_crop *a)
 {
-	return icd->ops->set_crop(icd, rect);
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+
+	return v4l2_subdev_call(sd, video, s_crop, a);
 }
 
 static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
@@ -539,18 +541,19 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 static int mx1_camera_set_fmt(struct soc_camera_device *icd,
 			      struct v4l2_format *f)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	int ret;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 	if (!xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
+		dev_warn(icd->dev.parent, "Format %x not found\n",
+			 pix->pixelformat);
 		return -EINVAL;
 	}
 
-	ret = icd->ops->set_fmt(icd, f);
+	ret = v4l2_subdev_call(sd, video, s_fmt, f);
 	if (!ret) {
 		icd->buswidth = xlate->buswidth;
 		icd->current_fmt = xlate->host_fmt;
@@ -562,10 +565,11 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
 static int mx1_camera_try_fmt(struct soc_camera_device *icd,
 			      struct v4l2_format *f)
 {
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	/* TODO: limit to mx1 hardware capabilities */
 
 	/* limit to sensor capabilities */
-	return icd->ops->try_fmt(icd, f);
+	return v4l2_subdev_call(sd, video, try_fmt, f);
 }
 
 static int mx1_camera_reqbufs(struct soc_camera_file *icf,
@@ -737,7 +741,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
 	pcdev->soc_host.drv_name	= DRIVER_NAME;
 	pcdev->soc_host.ops		= &mx1_soc_camera_host_ops;
 	pcdev->soc_host.priv		= pcdev;
-	pcdev->soc_host.dev		= &pdev->dev;
+	pcdev->soc_host.v4l2_dev.dev	= &pdev->dev;
 	pcdev->soc_host.nr		= pdev->id;
 	err = soc_camera_host_register(&pcdev->soc_host);
 	if (err)
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 9770cb7..dff2e5e 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -178,7 +178,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf
 
 	BUG_ON(in_interrupt());
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	/*
@@ -220,7 +220,7 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
 	if (!mx3_cam->idmac_channel[0])
 		return -EINVAL;
 
-	*size = icd->width * icd->height * bpp;
+	*size = icd->user_width * icd->user_height * bpp;
 
 	if (!*count)
 		*count = 32;
@@ -241,7 +241,7 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
 	struct mx3_camera_buffer *buf =
 		container_of(vb, struct mx3_camera_buffer, vb);
 	/* current_fmt _must_ always be set */
-	size_t new_size = icd->width * icd->height *
+	size_t new_size = icd->user_width * icd->user_height *
 		((icd->current_fmt->depth + 7) >> 3);
 	int ret;
 
@@ -251,12 +251,12 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
 	 */
 
 	if (buf->fmt	!= icd->current_fmt ||
-	    vb->width	!= icd->width ||
-	    vb->height	!= icd->height ||
+	    vb->width	!= icd->user_width ||
+	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
 		buf->fmt	= icd->current_fmt;
-		vb->width	= icd->width;
-		vb->height	= icd->height;
+		vb->width	= icd->user_width;
+		vb->height	= icd->user_height;
 		vb->field	= field;
 		if (vb->state != VIDEOBUF_NEEDS_INIT)
 			free_buffer(vq, buf);
@@ -354,9 +354,9 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
 
 	/* This is the configuration of one sg-element */
 	video->out_pixel_fmt	= fourcc_to_ipu_pix(data_fmt->fourcc);
-	video->out_width	= icd->width;
-	video->out_height	= icd->height;
-	video->out_stride	= icd->width;
+	video->out_width	= icd->user_width;
+	video->out_height	= icd->user_height;
+	video->out_stride	= icd->user_width;
 
 #ifdef DEBUG
 	/* helps to see what DMA actually has written */
@@ -375,7 +375,8 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
 	spin_unlock_irq(&mx3_cam->lock);
 
 	cookie = txd->tx_submit(txd);
-	dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg));
+	dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n",
+		cookie, sg_dma_address(&buf->sg));
 
 	spin_lock_irq(&mx3_cam->lock);
 
@@ -402,9 +403,10 @@ static void mx3_videobuf_release(struct videobuf_queue *vq,
 		container_of(vb, struct mx3_camera_buffer, vb);
 	unsigned long flags;
 
-	dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n",
+	dev_dbg(icd->dev.parent,
+		"Release%s DMA 0x%08x (state %d), queue %sempty\n",
 		mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
-		 vb->state, list_empty(&vb->queue) ? "" : "not ");
+		vb->state, list_empty(&vb->queue) ? "" : "not ");
 	spin_lock_irqsave(&mx3_cam->lock, flags);
 	if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
 	    !list_empty(&vb->queue)) {
@@ -431,7 +433,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q,
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
 
-	videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev,
+	videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, icd->dev.parent,
 				       &mx3_cam->lock,
 				       V4L2_BUF_TYPE_VIDEO_CAPTURE,
 				       V4L2_FIELD_NONE,
@@ -484,7 +486,7 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
 
 	clk_enable(mx3_cam->clk);
 	rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
-	dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
+	dev_dbg(icd->dev.parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
 	if (rate)
 		clk_set_rate(mx3_cam->clk, rate);
 }
@@ -494,29 +496,18 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
-	int ret;
 
-	if (mx3_cam->icd) {
-		ret = -EBUSY;
-		goto ebusy;
-	}
+	if (mx3_cam->icd)
+		return -EBUSY;
 
 	mx3_camera_activate(mx3_cam, icd);
-	ret = icd->ops->init(icd);
-	if (ret < 0) {
-		clk_disable(mx3_cam->clk);
-		goto einit;
-	}
 
 	mx3_cam->icd = icd;
 
-einit:
-ebusy:
-	if (!ret)
-		dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
-			 icd->devnum);
+	dev_info(icd->dev.parent, "MX3 Camera driver attached to camera %d\n",
+		 icd->devnum);
 
-	return ret;
+	return 0;
 }
 
 /* Called with .video_lock held */
@@ -533,13 +524,11 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
 		*ichan = NULL;
 	}
 
-	icd->ops->release(icd);
-
 	clk_disable(mx3_cam->clk);
 
 	mx3_cam->icd = NULL;
 
-	dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n",
+	dev_info(icd->dev.parent, "MX3 Camera driver detached from camera %d\n",
 		 icd->devnum);
 }
 
@@ -551,7 +540,8 @@ static bool channel_change_requested(struct soc_camera_device *icd,
 	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
 
 	/* Do buffers have to be re-allocated or channel re-configured? */
-	return ichan && rect->width * rect->height > icd->width * icd->height;
+	return ichan && rect->width * rect->height >
+		icd->user_width * icd->user_height;
 }
 
 static int test_platform_param(struct mx3_camera_dev *mx3_cam,
@@ -599,8 +589,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
 		*flags |= SOCAM_DATAWIDTH_4;
 		break;
 	default:
-		dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n",
-			 buswidth);
+		dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
+			 "Unsupported bus width %d\n", buswidth);
 		return -EINVAL;
 	}
 
@@ -615,7 +605,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
 	unsigned long bus_flags, camera_flags;
 	int ret = test_platform_param(mx3_cam, depth, &bus_flags);
 
-	dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret);
+	dev_dbg(icd->dev.parent, "request bus width %d bit: %d\n", depth, ret);
 
 	if (ret < 0)
 		return ret;
@@ -624,7 +614,8 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
 
 	ret = soc_camera_bus_param_compatible(camera_flags, bus_flags);
 	if (ret < 0)
-		dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n",
+		dev_warn(icd->dev.parent,
+			 "Flags incompatible: camera %lx, host %lx\n",
 			 camera_flags, bus_flags);
 
 	return ret;
@@ -638,7 +629,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
 	if (!rq)
 		return false;
 
-	pdata = rq->mx3_cam->soc_host.dev->platform_data;
+	pdata = rq->mx3_cam->soc_host.v4l2_dev.dev->platform_data;
 
 	return rq->id == chan->chan_id &&
 		pdata->dma_dev == chan->device->dev;
@@ -698,7 +689,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(ici->dev, "Providing format %s using %s\n",
+			dev_dbg(icd->dev.parent,
+				"Providing format %s using %s\n",
 				mx3_camera_formats[0].name,
 				icd->formats[idx].name);
 		}
@@ -710,7 +702,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(ici->dev, "Providing format %s using %s\n",
+			dev_dbg(icd->dev.parent,
+				"Providing format %s using %s\n",
 				mx3_camera_formats[0].name,
 				icd->formats[idx].name);
 		}
@@ -723,7 +716,7 @@ passthrough:
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(ici->dev,
+			dev_dbg(icd->dev.parent,
 				"Providing format %s in pass-through mode\n",
 				icd->formats[idx].name);
 		}
@@ -733,13 +726,13 @@ passthrough:
 }
 
 static void configure_geometry(struct mx3_camera_dev *mx3_cam,
-			       struct v4l2_rect *rect)
+			       unsigned int width, unsigned int height)
 {
 	u32 ctrl, width_field, height_field;
 
 	/* Setup frame size - this cannot be changed on-the-fly... */
-	width_field = rect->width - 1;
-	height_field = rect->height - 1;
+	width_field = width - 1;
+	height_field = height - 1;
 	csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
 
 	csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
@@ -751,11 +744,6 @@ static void configure_geometry(struct mx3_camera_dev *mx3_cam,
 	ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
 	/* Sensor does the cropping */
 	csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
-
-	/*
-	 * No need to free resources here if we fail, we'll see if we need to
-	 * do this next time we are called
-	 */
 }
 
 static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
@@ -792,25 +780,74 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
 	return 0;
 }
 
+/*
+ * FIXME: learn to use stride != width, then we can keep stride properly aligned
+ * and support arbitrary (even) widths.
+ */
+static inline void stride_align(__s32 *width)
+{
+	if (((*width + 7) &  ~7) < 4096)
+		*width = (*width + 7) &  ~7;
+	else
+		*width = *width &  ~7;
+}
+
+/*
+ * As long as we don't implement host-side cropping and scaling, we can use
+ * default g_crop and cropcap from soc_camera.c
+ */
 static int mx3_camera_set_crop(struct soc_camera_device *icd,
-			       struct v4l2_rect *rect)
+			       struct v4l2_crop *a)
 {
+	struct v4l2_rect *rect = &a->c;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
+	struct v4l2_pix_format *pix = &f.fmt.pix;
+	int ret;
 
-	/*
-	 * We now know pixel formats and can decide upon DMA-channel(s)
-	 * So far only direct camera-to-memory is supported
-	 */
-	if (channel_change_requested(icd, rect)) {
-		int ret = acquire_dma_channel(mx3_cam);
+	soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
+	soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
+
+	ret = v4l2_subdev_call(sd, video, s_crop, a);
+	if (ret < 0)
+		return ret;
+
+	/* The capture device might have changed its output  */
+	ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+	if (ret < 0)
+		return ret;
+
+	if (pix->width & 7) {
+		/* Ouch! We can only handle 8-byte aligned width... */
+		stride_align(&pix->width);
+		ret = v4l2_subdev_call(sd, video, s_fmt, &f);
 		if (ret < 0)
 			return ret;
 	}
 
-	configure_geometry(mx3_cam, rect);
+	if (pix->width != icd->user_width || pix->height != icd->user_height) {
+		/*
+		 * We now know pixel formats and can decide upon DMA-channel(s)
+		 * So far only direct camera-to-memory is supported
+		 */
+		if (channel_change_requested(icd, rect)) {
+			int ret = acquire_dma_channel(mx3_cam);
+			if (ret < 0)
+				return ret;
+		}
+
+		configure_geometry(mx3_cam, pix->width, pix->height);
+	}
+
+	dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
+		pix->width, pix->height);
 
-	return icd->ops->set_crop(icd, rect);
+	icd->user_width = pix->width;
+	icd->user_height = pix->height;
+
+	return ret;
 }
 
 static int mx3_camera_set_fmt(struct soc_camera_device *icd,
@@ -818,22 +855,21 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx3_camera_dev *mx3_cam = ici->priv;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
-	struct v4l2_rect rect = {
-		.left	= icd->x_current,
-		.top	= icd->y_current,
-		.width	= pix->width,
-		.height	= pix->height,
-	};
 	int ret;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 	if (!xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
+		dev_warn(icd->dev.parent, "Format %x not found\n",
+			 pix->pixelformat);
 		return -EINVAL;
 	}
 
+	stride_align(&pix->width);
+	dev_dbg(icd->dev.parent, "Set format %dx%d\n", pix->width, pix->height);
+
 	ret = acquire_dma_channel(mx3_cam);
 	if (ret < 0)
 		return ret;
@@ -844,21 +880,23 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
 	 * mxc_v4l2_s_fmt()
 	 */
 
-	configure_geometry(mx3_cam, &rect);
+	configure_geometry(mx3_cam, pix->width, pix->height);
 
-	ret = icd->ops->set_fmt(icd, f);
+	ret = v4l2_subdev_call(sd, video, s_fmt, f);
 	if (!ret) {
 		icd->buswidth = xlate->buswidth;
 		icd->current_fmt = xlate->host_fmt;
 	}
 
+	dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
+
 	return ret;
 }
 
 static int mx3_camera_try_fmt(struct soc_camera_device *icd,
 			      struct v4l2_format *f)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	__u32 pixfmt = pix->pixelformat;
@@ -867,7 +905,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (pixfmt && !xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
@@ -884,7 +922,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
 	/* camera has to see its format, but the user the original one */
 	pix->pixelformat = xlate->cam_fmt->fourcc;
 	/* limit to sensor capabilities */
-	ret = icd->ops->try_fmt(icd, f);
+	ret = v4l2_subdev_call(sd, video, try_fmt, f);
 	pix->pixelformat = xlate->host_fmt->fourcc;
 
 	field = pix->field;
@@ -892,7 +930,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
 	if (field == V4L2_FIELD_ANY) {
 		pix->field = V4L2_FIELD_NONE;
 	} else if (field != V4L2_FIELD_NONE) {
-		dev_err(&icd->dev, "Field type %d unsupported.\n", field);
+		dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
 		return -EINVAL;
 	}
 
@@ -931,14 +969,15 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 	u32 dw, sens_conf;
 	int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags);
 	const struct soc_camera_format_xlate *xlate;
+	struct device *dev = icd->dev.parent;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
-	dev_dbg(ici->dev, "requested bus width %d bit: %d\n",
+	dev_dbg(dev, "requested bus width %d bit: %d\n",
 		icd->buswidth, ret);
 
 	if (ret < 0)
@@ -947,9 +986,10 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 	camera_flags = icd->ops->query_bus_param(icd);
 
 	common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+	dev_dbg(dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n",
+		camera_flags, bus_flags, common_flags);
 	if (!common_flags) {
-		dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n",
-			camera_flags, bus_flags);
+		dev_dbg(dev, "no common flags");
 		return -EINVAL;
 	}
 
@@ -1002,8 +1042,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 			SOCAM_DATAWIDTH_4;
 
 	ret = icd->ops->set_bus_param(icd, common_flags);
-	if (ret < 0)
+	if (ret < 0) {
+		dev_dbg(dev, "camera set_bus_param(%lx) returned %d\n",
+			common_flags, ret);
 		return ret;
+	}
 
 	/*
 	 * So far only gated clock mode is supported. Add a line
@@ -1055,7 +1098,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 
 	csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
 
-	dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
+	dev_dbg(dev, "Set SENS_CONF to %x\n", sens_conf | dw);
 
 	return 0;
 }
@@ -1127,8 +1170,9 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&mx3_cam->capture);
 	spin_lock_init(&mx3_cam->lock);
 
-	base = ioremap(res->start, res->end - res->start + 1);
+	base = ioremap(res->start, resource_size(res));
 	if (!base) {
+		pr_err("Couldn't map %x@%x\n", resource_size(res), res->start);
 		err = -ENOMEM;
 		goto eioremap;
 	}
@@ -1139,7 +1183,7 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
 	soc_host->drv_name	= MX3_CAM_DRV_NAME;
 	soc_host->ops		= &mx3_soc_camera_host_ops;
 	soc_host->priv		= mx3_cam;
-	soc_host->dev		= &pdev->dev;
+	soc_host->v4l2_dev.dev	= &pdev->dev;
 	soc_host->nr		= pdev->id;
 
 	err = soc_camera_host_register(soc_host);
@@ -1215,3 +1259,4 @@ module_exit(mx3_camera_exit);
 MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
 MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 35890e8..3454070 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -186,19 +186,19 @@ static int mxb_probe(struct saa7146_dev *dev)
 	}
 
 	mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-			"saa7115", "saa7111", I2C_SAA7111A);
+			"saa7115", "saa7111", I2C_SAA7111A, NULL);
 	mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-			"tea6420", "tea6420", I2C_TEA6420_1);
+			"tea6420", "tea6420", I2C_TEA6420_1, NULL);
 	mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-			"tea6420", "tea6420", I2C_TEA6420_2);
+			"tea6420", "tea6420", I2C_TEA6420_2, NULL);
 	mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-			"tea6415c", "tea6415c", I2C_TEA6415C);
+			"tea6415c", "tea6415c", I2C_TEA6415C, NULL);
 	mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-			"tda9840", "tda9840", I2C_TDA9840);
+			"tda9840", "tda9840", I2C_TDA9840, NULL);
 	mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-			"tuner", "tuner", I2C_TUNER);
+			"tuner", "tuner", I2C_TUNER, NULL);
 	if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
-			"saa5246a", "saa5246a", I2C_SAA5246A)) {
+			"saa5246a", "saa5246a", I2C_SAA5246A, NULL)) {
 		printk(KERN_INFO "mxb: found teletext decoder\n");
 	}
 
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 0bce255..eccb40a 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -22,7 +22,7 @@
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-subdev.h>
 #include <media/soc_camera.h>
 #include <media/ov772x.h>
 
@@ -382,11 +382,10 @@ struct regval_list {
 };
 
 struct ov772x_color_format {
-	char                     *name;
-	__u32                     fourcc;
-	u8                        dsp3;
-	u8                        com3;
-	u8                        com7;
+	const struct soc_camera_data_format *format;
+	u8 dsp3;
+	u8 com3;
+	u8 com7;
 };
 
 struct ov772x_win_size {
@@ -398,14 +397,15 @@ struct ov772x_win_size {
 };
 
 struct ov772x_priv {
+	struct v4l2_subdev                subdev;
 	struct ov772x_camera_info        *info;
-	struct i2c_client                *client;
-	struct soc_camera_device          icd;
 	const struct ov772x_color_format *fmt;
 	const struct ov772x_win_size     *win;
 	int                               model;
-	unsigned int                      flag_vflip:1;
-	unsigned int                      flag_hflip:1;
+	unsigned short                    flag_vflip:1;
+	unsigned short                    flag_hflip:1;
+	/* band_filter = COM8[5] ? 256 - BDBASE : 0 */
+	unsigned short                    band_filter;
 };
 
 #define ENDMARKER { 0xff, 0xff }
@@ -481,43 +481,43 @@ static const struct soc_camera_data_format ov772x_fmt_lists[] = {
  */
 static const struct ov772x_color_format ov772x_cfmts[] = {
 	{
-		SETFOURCC(YUYV),
+		.format = &ov772x_fmt_lists[0],
 		.dsp3   = 0x0,
 		.com3   = SWAP_YUV,
 		.com7   = OFMT_YUV,
 	},
 	{
-		SETFOURCC(YVYU),
+		.format = &ov772x_fmt_lists[1],
 		.dsp3   = UV_ON,
 		.com3   = SWAP_YUV,
 		.com7   = OFMT_YUV,
 	},
 	{
-		SETFOURCC(UYVY),
+		.format = &ov772x_fmt_lists[2],
 		.dsp3   = 0x0,
 		.com3   = 0x0,
 		.com7   = OFMT_YUV,
 	},
 	{
-		SETFOURCC(RGB555),
+		.format = &ov772x_fmt_lists[3],
 		.dsp3   = 0x0,
 		.com3   = SWAP_RGB,
 		.com7   = FMT_RGB555 | OFMT_RGB,
 	},
 	{
-		SETFOURCC(RGB555X),
+		.format = &ov772x_fmt_lists[4],
 		.dsp3   = 0x0,
 		.com3   = 0x0,
 		.com7   = FMT_RGB555 | OFMT_RGB,
 	},
 	{
-		SETFOURCC(RGB565),
+		.format = &ov772x_fmt_lists[5],
 		.dsp3   = 0x0,
 		.com3   = SWAP_RGB,
 		.com7   = FMT_RGB565 | OFMT_RGB,
 	},
 	{
-		SETFOURCC(RGB565X),
+		.format = &ov772x_fmt_lists[6],
 		.dsp3   = 0x0,
 		.com3   = 0x0,
 		.com7   = FMT_RGB565 | OFMT_RGB,
@@ -570,6 +570,15 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
 		.step		= 1,
 		.default_value	= 0,
 	},
+	{
+		.id		= V4L2_CID_BAND_STOP_FILTER,
+		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.name		= "Band-stop filter",
+		.minimum	= 0,
+		.maximum	= 256,
+		.step		= 1,
+		.default_value	= 0,
+	},
 };
 
 
@@ -577,6 +586,12 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
  * general function
  */
 
+static struct ov772x_priv *to_ov772x(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct ov772x_priv,
+			    subdev);
+}
+
 static int ov772x_write_array(struct i2c_client        *client,
 			      const struct regval_list *vals)
 {
@@ -617,58 +632,29 @@ static int ov772x_reset(struct i2c_client *client)
  * soc_camera_ops function
  */
 
-static int ov772x_init(struct soc_camera_device *icd)
+static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	int ret = 0;
+	struct i2c_client *client = sd->priv;
+	struct ov772x_priv *priv = to_ov772x(client);
 
-	if (priv->info->link.power) {
-		ret = priv->info->link.power(&priv->client->dev, 1);
-		if (ret < 0)
-			return ret;
+	if (!enable) {
+		ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
+		return 0;
 	}
 
-	if (priv->info->link.reset)
-		ret = priv->info->link.reset(&priv->client->dev);
-
-	return ret;
-}
-
-static int ov772x_release(struct soc_camera_device *icd)
-{
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	int ret = 0;
-
-	if (priv->info->link.power)
-		ret = priv->info->link.power(&priv->client->dev, 0);
-
-	return ret;
-}
-
-static int ov772x_start_capture(struct soc_camera_device *icd)
-{
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-
 	if (!priv->win || !priv->fmt) {
-		dev_err(&icd->dev, "norm or win select error\n");
+		dev_err(&client->dev, "norm or win select error\n");
 		return -EPERM;
 	}
 
-	ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0);
+	ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
 
-	dev_dbg(&icd->dev,
-		 "format %s, win %s\n", priv->fmt->name, priv->win->name);
+	dev_dbg(&client->dev, "format %s, win %s\n",
+		priv->fmt->format->name, priv->win->name);
 
 	return 0;
 }
 
-static int ov772x_stop_capture(struct soc_camera_device *icd)
-{
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
-	return 0;
-}
-
 static int ov772x_set_bus_param(struct soc_camera_device *icd,
 				unsigned long		  flags)
 {
@@ -677,8 +663,9 @@ static int ov772x_set_bus_param(struct soc_camera_device *icd,
 
 static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	struct soc_camera_link *icl = &priv->info->link;
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+	struct ov772x_priv *priv = i2c_get_clientdata(client);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
 		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
 		SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -686,10 +673,10 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
 	return soc_camera_apply_sensor_flags(icl, flags);
 }
 
-static int ov772x_get_control(struct soc_camera_device *icd,
-			      struct v4l2_control *ctrl)
+static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	struct i2c_client *client = sd->priv;
+	struct ov772x_priv *priv = to_ov772x(client);
 
 	switch (ctrl->id) {
 	case V4L2_CID_VFLIP:
@@ -698,14 +685,17 @@ static int ov772x_get_control(struct soc_camera_device *icd,
 	case V4L2_CID_HFLIP:
 		ctrl->value = priv->flag_hflip;
 		break;
+	case V4L2_CID_BAND_STOP_FILTER:
+		ctrl->value = priv->band_filter;
+		break;
 	}
 	return 0;
 }
 
-static int ov772x_set_control(struct soc_camera_device *icd,
-			      struct v4l2_control *ctrl)
+static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	struct i2c_client *client = sd->priv;
+	struct ov772x_priv *priv = to_ov772x(client);
 	int ret = 0;
 	u8 val;
 
@@ -715,24 +705,48 @@ static int ov772x_set_control(struct soc_camera_device *icd,
 		priv->flag_vflip = ctrl->value;
 		if (priv->info->flags & OV772X_FLAG_VFLIP)
 			val ^= VFLIP_IMG;
-		ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val);
+		ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val);
 		break;
 	case V4L2_CID_HFLIP:
 		val = ctrl->value ? HFLIP_IMG : 0x00;
 		priv->flag_hflip = ctrl->value;
 		if (priv->info->flags & OV772X_FLAG_HFLIP)
 			val ^= HFLIP_IMG;
-		ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val);
+		ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val);
+		break;
+	case V4L2_CID_BAND_STOP_FILTER:
+		if ((unsigned)ctrl->value > 256)
+			ctrl->value = 256;
+		if (ctrl->value == priv->band_filter)
+			break;
+		if (!ctrl->value) {
+			/* Switch the filter off, it is on now */
+			ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
+			if (!ret)
+				ret = ov772x_mask_set(client, COM8,
+						      BNDF_ON_OFF, 0);
+		} else {
+			/* Switch the filter on, set AEC low limit */
+			val = 256 - ctrl->value;
+			ret = ov772x_mask_set(client, COM8,
+					      BNDF_ON_OFF, BNDF_ON_OFF);
+			if (!ret)
+				ret = ov772x_mask_set(client, BDBASE,
+						      0xff, val);
+		}
+		if (!ret)
+			priv->band_filter = ctrl->value;
 		break;
 	}
 
 	return ret;
 }
 
-static int ov772x_get_chip_id(struct soc_camera_device *icd,
-			      struct v4l2_dbg_chip_ident   *id)
+static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
+			       struct v4l2_dbg_chip_ident *id)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	struct i2c_client *client = sd->priv;
+	struct ov772x_priv *priv = to_ov772x(client);
 
 	id->ident    = priv->model;
 	id->revision = 0;
@@ -741,17 +755,17 @@ static int ov772x_get_chip_id(struct soc_camera_device *icd,
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-static int ov772x_get_register(struct soc_camera_device *icd,
-			       struct v4l2_dbg_register *reg)
+static int ov772x_g_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
-	int                 ret;
+	struct i2c_client *client = sd->priv;
+	int ret;
 
 	reg->size = 1;
 	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	ret = i2c_smbus_read_byte_data(priv->client, reg->reg);
+	ret = i2c_smbus_read_byte_data(client, reg->reg);
 	if (ret < 0)
 		return ret;
 
@@ -760,21 +774,20 @@ static int ov772x_get_register(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int ov772x_set_register(struct soc_camera_device *icd,
-			       struct v4l2_dbg_register *reg)
+static int ov772x_s_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->reg > 0xff ||
 	    reg->val > 0xff)
 		return -EINVAL;
 
-	return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val);
+	return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
 }
 #endif
 
-static const struct ov772x_win_size*
-ov772x_select_win(u32 width, u32 height)
+static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
 {
 	__u32 diff;
 	const struct ov772x_win_size *win;
@@ -793,9 +806,10 @@ ov772x_select_win(u32 width, u32 height)
 	return win;
 }
 
-static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
-			     u32 pixfmt)
+static int ov772x_set_params(struct i2c_client *client,
+			     u32 *width, u32 *height, u32 pixfmt)
 {
+	struct ov772x_priv *priv = to_ov772x(client);
 	int ret = -EINVAL;
 	u8  val;
 	int i;
@@ -805,7 +819,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 	 */
 	priv->fmt = NULL;
 	for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
-		if (pixfmt == ov772x_cfmts[i].fourcc) {
+		if (pixfmt == ov772x_cfmts[i].format->fourcc) {
 			priv->fmt = ov772x_cfmts + i;
 			break;
 		}
@@ -816,12 +830,12 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 	/*
 	 * select win
 	 */
-	priv->win = ov772x_select_win(width, height);
+	priv->win = ov772x_select_win(*width, *height);
 
 	/*
 	 * reset hardware
 	 */
-	ov772x_reset(priv->client);
+	ov772x_reset(client);
 
 	/*
 	 * Edge Ctrl
@@ -835,17 +849,17 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 		 * Remove it when manual mode.
 		 */
 
-		ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00);
+		ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
 		if (ret < 0)
 			goto ov772x_set_fmt_error;
 
-		ret = ov772x_mask_set(priv->client,
+		ret = ov772x_mask_set(client,
 				      EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
 				      priv->info->edgectrl.threshold);
 		if (ret < 0)
 			goto ov772x_set_fmt_error;
 
-		ret = ov772x_mask_set(priv->client,
+		ret = ov772x_mask_set(client,
 				      EDGE_STRNGT, EDGE_STRENGTH_MASK,
 				      priv->info->edgectrl.strength);
 		if (ret < 0)
@@ -857,13 +871,13 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 		 *
 		 * set upper and lower limit
 		 */
-		ret = ov772x_mask_set(priv->client,
+		ret = ov772x_mask_set(client,
 				      EDGE_UPPER, EDGE_UPPER_MASK,
 				      priv->info->edgectrl.upper);
 		if (ret < 0)
 			goto ov772x_set_fmt_error;
 
-		ret = ov772x_mask_set(priv->client,
+		ret = ov772x_mask_set(client,
 				      EDGE_LOWER, EDGE_LOWER_MASK,
 				      priv->info->edgectrl.lower);
 		if (ret < 0)
@@ -873,7 +887,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 	/*
 	 * set size format
 	 */
-	ret = ov772x_write_array(priv->client, priv->win->regs);
+	ret = ov772x_write_array(client, priv->win->regs);
 	if (ret < 0)
 		goto ov772x_set_fmt_error;
 
@@ -882,7 +896,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 	 */
 	val = priv->fmt->dsp3;
 	if (val) {
-		ret = ov772x_mask_set(priv->client,
+		ret = ov772x_mask_set(client,
 				      DSP_CTRL3, UV_MASK, val);
 		if (ret < 0)
 			goto ov772x_set_fmt_error;
@@ -901,7 +915,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 	if (priv->flag_hflip)
 		val ^= HFLIP_IMG;
 
-	ret = ov772x_mask_set(priv->client,
+	ret = ov772x_mask_set(client,
 			      COM3, SWAP_MASK | IMG_MASK, val);
 	if (ret < 0)
 		goto ov772x_set_fmt_error;
@@ -910,47 +924,99 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
 	 * set COM7
 	 */
 	val = priv->win->com7_bit | priv->fmt->com7;
-	ret = ov772x_mask_set(priv->client,
+	ret = ov772x_mask_set(client,
 			      COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
 			      val);
 	if (ret < 0)
 		goto ov772x_set_fmt_error;
 
+	/*
+	 * set COM8
+	 */
+	if (priv->band_filter) {
+		ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, 1);
+		if (!ret)
+			ret = ov772x_mask_set(client, BDBASE,
+					      0xff, 256 - priv->band_filter);
+		if (ret < 0)
+			goto ov772x_set_fmt_error;
+	}
+
+	*width = priv->win->width;
+	*height = priv->win->height;
+
 	return ret;
 
 ov772x_set_fmt_error:
 
-	ov772x_reset(priv->client);
+	ov772x_reset(client);
 	priv->win = NULL;
 	priv->fmt = NULL;
 
 	return ret;
 }
 
-static int ov772x_set_crop(struct soc_camera_device *icd,
-			   struct v4l2_rect *rect)
+static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	a->c.left	= 0;
+	a->c.top	= 0;
+	a->c.width	= VGA_WIDTH;
+	a->c.height	= VGA_HEIGHT;
+	a->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-	if (!priv->fmt)
-		return -EINVAL;
+	return 0;
+}
 
-	return ov772x_set_params(priv, rect->width, rect->height,
-				 priv->fmt->fourcc);
+static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
+{
+	a->bounds.left			= 0;
+	a->bounds.top			= 0;
+	a->bounds.width			= VGA_WIDTH;
+	a->bounds.height		= VGA_HEIGHT;
+	a->defrect			= a->bounds;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
 }
 
-static int ov772x_set_fmt(struct soc_camera_device *icd,
-			  struct v4l2_format *f)
+static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct ov772x_priv *priv = to_ov772x(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	if (!priv->win || !priv->fmt) {
+		u32 width = VGA_WIDTH, height = VGA_HEIGHT;
+		int ret = ov772x_set_params(client, &width, &height,
+					    V4L2_PIX_FMT_YUYV);
+		if (ret < 0)
+			return ret;
+	}
+
+	f->type			= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	pix->width		= priv->win->width;
+	pix->height		= priv->win->height;
+	pix->pixelformat	= priv->fmt->format->fourcc;
+	pix->colorspace		= priv->fmt->format->colorspace;
+	pix->field		= V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	struct i2c_client *client = sd->priv;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
-	return ov772x_set_params(priv, pix->width, pix->height,
+	return ov772x_set_params(client, &pix->width, &pix->height,
 				 pix->pixelformat);
 }
 
-static int ov772x_try_fmt(struct soc_camera_device *icd,
-			  struct v4l2_format       *f)
+static int ov772x_try_fmt(struct v4l2_subdev *sd,
+			  struct v4l2_format *f)
 {
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	const struct ov772x_win_size *win;
@@ -967,9 +1033,10 @@ static int ov772x_try_fmt(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int ov772x_video_probe(struct soc_camera_device *icd)
+static int ov772x_video_probe(struct soc_camera_device *icd,
+			      struct i2c_client *client)
 {
-	struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+	struct ov772x_priv *priv = to_ov772x(client);
 	u8                  pid, ver;
 	const char         *devname;
 
@@ -986,7 +1053,7 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
 	 */
 	if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
 	    SOCAM_DATAWIDTH_8  != priv->info->buswidth) {
-		dev_err(&icd->dev, "bus width error\n");
+		dev_err(&client->dev, "bus width error\n");
 		return -ENODEV;
 	}
 
@@ -996,8 +1063,8 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
 	/*
 	 * check and show product ID and manufacturer ID
 	 */
-	pid = i2c_smbus_read_byte_data(priv->client, PID);
-	ver = i2c_smbus_read_byte_data(priv->client, VER);
+	pid = i2c_smbus_read_byte_data(client, PID);
+	ver = i2c_smbus_read_byte_data(client, VER);
 
 	switch (VERSION(pid, ver)) {
 	case OV7720:
@@ -1009,69 +1076,77 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
 		priv->model = V4L2_IDENT_OV7725;
 		break;
 	default:
-		dev_err(&icd->dev,
+		dev_err(&client->dev,
 			"Product ID error %x:%x\n", pid, ver);
 		return -ENODEV;
 	}
 
-	dev_info(&icd->dev,
+	dev_info(&client->dev,
 		 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
 		 devname,
 		 pid,
 		 ver,
-		 i2c_smbus_read_byte_data(priv->client, MIDH),
-		 i2c_smbus_read_byte_data(priv->client, MIDL));
-
-	return soc_camera_video_start(icd);
-}
+		 i2c_smbus_read_byte_data(client, MIDH),
+		 i2c_smbus_read_byte_data(client, MIDL));
 
-static void ov772x_video_remove(struct soc_camera_device *icd)
-{
-	soc_camera_video_stop(icd);
+	return 0;
 }
 
 static struct soc_camera_ops ov772x_ops = {
-	.owner			= THIS_MODULE,
-	.probe			= ov772x_video_probe,
-	.remove			= ov772x_video_remove,
-	.init			= ov772x_init,
-	.release		= ov772x_release,
-	.start_capture		= ov772x_start_capture,
-	.stop_capture		= ov772x_stop_capture,
-	.set_crop		= ov772x_set_crop,
-	.set_fmt		= ov772x_set_fmt,
-	.try_fmt		= ov772x_try_fmt,
 	.set_bus_param		= ov772x_set_bus_param,
 	.query_bus_param	= ov772x_query_bus_param,
 	.controls		= ov772x_controls,
 	.num_controls		= ARRAY_SIZE(ov772x_controls),
-	.get_control		= ov772x_get_control,
-	.set_control		= ov772x_set_control,
-	.get_chip_id		= ov772x_get_chip_id,
+};
+
+static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
+	.g_ctrl		= ov772x_g_ctrl,
+	.s_ctrl		= ov772x_s_ctrl,
+	.g_chip_ident	= ov772x_g_chip_ident,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	.get_register		= ov772x_get_register,
-	.set_register		= ov772x_set_register,
+	.g_register	= ov772x_g_register,
+	.s_register	= ov772x_s_register,
 #endif
 };
 
+static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
+	.s_stream	= ov772x_s_stream,
+	.g_fmt		= ov772x_g_fmt,
+	.s_fmt		= ov772x_s_fmt,
+	.try_fmt	= ov772x_try_fmt,
+	.cropcap	= ov772x_cropcap,
+	.g_crop		= ov772x_g_crop,
+};
+
+static struct v4l2_subdev_ops ov772x_subdev_ops = {
+	.core	= &ov772x_subdev_core_ops,
+	.video	= &ov772x_subdev_video_ops,
+};
+
 /*
  * i2c_driver function
  */
 
 static int ov772x_probe(struct i2c_client *client,
-			 const struct i2c_device_id *did)
+			const struct i2c_device_id *did)
 {
 	struct ov772x_priv        *priv;
 	struct ov772x_camera_info *info;
-	struct soc_camera_device  *icd;
+	struct soc_camera_device  *icd = client->dev.platform_data;
 	struct i2c_adapter        *adapter = to_i2c_adapter(client->dev.parent);
+	struct soc_camera_link    *icl;
 	int                        ret;
 
-	if (!client->dev.platform_data)
+	if (!icd) {
+		dev_err(&client->dev, "OV772X: missing soc-camera data!\n");
 		return -EINVAL;
+	}
 
-	info = container_of(client->dev.platform_data,
-			    struct ov772x_camera_info, link);
+	icl = to_soc_camera_link(icd);
+	if (!icl)
+		return -EINVAL;
+
+	info = container_of(icl, struct ov772x_camera_info, link);
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&adapter->dev,
@@ -1084,20 +1159,15 @@ static int ov772x_probe(struct i2c_client *client,
 	if (!priv)
 		return -ENOMEM;
 
-	priv->info   = info;
-	priv->client = client;
-	i2c_set_clientdata(client, priv);
+	priv->info = info;
 
-	icd             = &priv->icd;
-	icd->ops        = &ov772x_ops;
-	icd->control    = &client->dev;
-	icd->width_max  = MAX_WIDTH;
-	icd->height_max = MAX_HEIGHT;
-	icd->iface      = priv->info->link.bus_id;
+	v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
 
-	ret = soc_camera_device_register(icd);
+	icd->ops		= &ov772x_ops;
 
+	ret = ov772x_video_probe(icd, client);
 	if (ret) {
+		icd->ops = NULL;
 		i2c_set_clientdata(client, NULL);
 		kfree(priv);
 	}
@@ -1107,9 +1177,10 @@ static int ov772x_probe(struct i2c_client *client,
 
 static int ov772x_remove(struct i2c_client *client)
 {
-	struct ov772x_priv *priv = i2c_get_clientdata(client);
+	struct ov772x_priv *priv = to_ov772x(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 
-	soc_camera_device_unregister(&priv->icd);
+	icd->ops = NULL;
 	i2c_set_clientdata(client, NULL);
 	kfree(priv);
 	return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index 416933c..cc06d5e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -65,9 +65,10 @@ void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 		u32 input;
 
 		pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
+		sp = (sid < ARRAY_SIZE(routing_schemes)) ?
+			routing_schemes[sid] : NULL;
 
-		if ((sid < ARRAY_SIZE(routing_schemes)) &&
-		    ((sp = routing_schemes[sid]) != NULL) &&
+		if ((sp != NULL) &&
 		    (hdw->input_val >= 0) &&
 		    (hdw->input_val < sp->cnt)) {
 			input = sp->def[hdw->input_val];
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 336a20e..e4d7c13 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -298,6 +298,7 @@ static struct tda829x_config tda829x_no_probe = {
 
 static struct tda18271_config hauppauge_tda18271_dvb_config = {
 	.gate    = TDA18271_GATE_ANALOG,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
 };
 
 static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
@@ -393,6 +394,7 @@ static struct tda18271_std_map hauppauge_tda18271_std_map = {
 static struct tda18271_config hauppauge_tda18271_config = {
 	.std_map = &hauppauge_tda18271_std_map,
 	.gate    = TDA18271_GATE_ANALOG,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
 };
 
 static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index cbc3887..13639b3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2063,8 +2063,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
 		return -EINVAL;
 	}
 
-	/* Note how the 2nd and 3rd arguments are the same for both
-	 * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev().  Why?
+	/* Note how the 2nd and 3rd arguments are the same for
+	 * v4l2_i2c_new_subdev().  Why?
 	 * Well the 2nd argument is the module name to load, while the 3rd
 	 * argument is documented in the framework as being the "chipid" -
 	 * and every other place where I can find examples of this, the
@@ -2077,15 +2077,15 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
 			   mid, i2caddr[0]);
 		sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
 					 fname, fname,
-					 i2caddr[0]);
+					 i2caddr[0], NULL);
 	} else {
 		pvr2_trace(PVR2_TRACE_INIT,
 			   "Module ID %u:"
 			   " Setting up with address probe list",
 			   mid);
-		sd = v4l2_i2c_new_probed_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
+		sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
 						fname, fname,
-						i2caddr);
+						0, i2caddr);
 	}
 
 	if (!sd) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 610bd84..a334b1a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -540,7 +540,6 @@ static struct i2c_algorithm pvr2_i2c_algo_template = {
 static struct i2c_adapter pvr2_i2c_adap_template = {
 	.owner         = THIS_MODULE,
 	.class	       = 0,
-	.id            = I2C_HW_B_BT848,
 };
 
 
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 8d17cf6..f976df4 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -1057,7 +1057,8 @@ static int pwc_create_sysfs_files(struct video_device *vdev)
 		goto err;
 	if (pdev->features & FEATURE_MOTOR_PANTILT) {
 		rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt);
-		if (rc) goto err_button;
+		if (rc)
+			goto err_button;
 	}
 
 	return 0;
@@ -1072,6 +1073,7 @@ err:
 static void pwc_remove_sysfs_files(struct video_device *vdev)
 {
 	struct pwc_device *pdev = video_get_drvdata(vdev);
+
 	if (pdev->features & FEATURE_MOTOR_PANTILT)
 		device_remove_file(&vdev->dev, &dev_attr_pan_tilt);
 	device_remove_file(&vdev->dev, &dev_attr_button);
@@ -1229,13 +1231,11 @@ static void pwc_cleanup(struct pwc_device *pdev)
 	video_unregister_device(pdev->vdev);
 
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
-	if (pdev->button_dev) {
+	if (pdev->button_dev)
 		input_unregister_device(pdev->button_dev);
-		input_free_device(pdev->button_dev);
-		kfree(pdev->button_dev->phys);
-		pdev->button_dev = NULL;
-	}
 #endif
+
+	kfree(pdev);
 }
 
 /* Note that all cleanup is done in the reverse order as in _open */
@@ -1281,8 +1281,6 @@ static int pwc_video_close(struct file *file)
 		PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
 	} else {
 		pwc_cleanup(pdev);
-		/* Free memory (don't set pdev to 0 just yet) */
-		kfree(pdev);
 		/* search device_hint[] table if we occupy a slot, by any chance */
 		for (hint = 0; hint < MAX_DEV_HINTS; hint++)
 			if (device_hint[hint].pdev == pdev)
@@ -1499,13 +1497,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct pwc_device *pdev = NULL;
 	int vendor_id, product_id, type_id;
-	int i, hint, rc;
+	int hint, rc;
 	int features = 0;
 	int video_nr = -1; /* default: use next available device */
 	char serial_number[30], *name;
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
-	char *phys = NULL;
-#endif
 
 	vendor_id = le16_to_cpu(udev->descriptor.idVendor);
 	product_id = le16_to_cpu(udev->descriptor.idProduct);
@@ -1757,8 +1752,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 	pdev->vframes = default_fps;
 	strcpy(pdev->serial, serial_number);
 	pdev->features = features;
-	if (vendor_id == 0x046D && product_id == 0x08B5)
-	{
+	if (vendor_id == 0x046D && product_id == 0x08B5) {
 		/* Logitech QuickCam Orbit
 		   The ranges have been determined experimentally; they may differ from cam to cam.
 		   Also, the exact ranges left-right and up-down are different for my cam
@@ -1780,8 +1774,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 	pdev->vdev = video_device_alloc();
 	if (!pdev->vdev) {
 		PWC_ERROR("Err, cannot allocate video_device struture. Failing probe.");
-		kfree(pdev);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto err_free_mem;
 	}
 	memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
 	pdev->vdev->parent = &intf->dev;
@@ -1806,25 +1800,23 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 	}
 
 	pdev->vdev->release = video_device_release;
-	i = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
-	if (i < 0) {
-		PWC_ERROR("Failed to register as video device (%d).\n", i);
-		rc = i;
-		goto err;
-	}
-	else {
-		PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num);
+	rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
+	if (rc < 0) {
+		PWC_ERROR("Failed to register as video device (%d).\n", rc);
+		goto err_video_release;
 	}
 
+	PWC_INFO("Registered as /dev/video%d.\n", pdev->vdev->num);
+
 	/* occupy slot */
 	if (hint < MAX_DEV_HINTS)
 		device_hint[hint].pdev = pdev;
 
 	PWC_DEBUG_PROBE("probe() function returning struct at 0x%p.\n", pdev);
-	usb_set_intfdata (intf, pdev);
+	usb_set_intfdata(intf, pdev);
 	rc = pwc_create_sysfs_files(pdev->vdev);
 	if (rc)
-		goto err_unreg;
+		goto err_video_unreg;
 
 	/* Set the leds off */
 	pwc_set_leds(pdev, 0, 0);
@@ -1835,16 +1827,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 	pdev->button_dev = input_allocate_device();
 	if (!pdev->button_dev) {
 		PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		pwc_remove_sysfs_files(pdev->vdev);
+		goto err_video_unreg;
 	}
 
+	usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
+	strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));
+
 	pdev->button_dev->name = "PWC snapshot button";
-	phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath);
-	if (!phys) {
-		input_free_device(pdev->button_dev);
-		return -ENOMEM;
-	}
-	pdev->button_dev->phys = phys;
+	pdev->button_dev->phys = pdev->button_phys;
 	usb_to_input_id(pdev->udev, &pdev->button_dev->id);
 	pdev->button_dev->dev.parent = &pdev->udev->dev;
 	pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
@@ -1853,25 +1845,27 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 	rc = input_register_device(pdev->button_dev);
 	if (rc) {
 		input_free_device(pdev->button_dev);
-		kfree(pdev->button_dev->phys);
 		pdev->button_dev = NULL;
-		return rc;
+		pwc_remove_sysfs_files(pdev->vdev);
+		goto err_video_unreg;
 	}
 #endif
 
 	return 0;
 
-err_unreg:
+err_video_unreg:
 	if (hint < MAX_DEV_HINTS)
 		device_hint[hint].pdev = NULL;
 	video_unregister_device(pdev->vdev);
-err:
-	video_device_release(pdev->vdev); /* Drip... drip... drip... */
-	kfree(pdev); /* Oops, no memory leaks please */
+	pdev->vdev = NULL;	/* So we don't try to release it below */
+err_video_release:
+	video_device_release(pdev->vdev);
+err_free_mem:
+	kfree(pdev);
 	return rc;
 }
 
-/* The user janked out the cable... */
+/* The user yanked out the cable... */
 static void usb_pwc_disconnect(struct usb_interface *intf)
 {
 	struct pwc_device *pdev;
@@ -1902,7 +1896,7 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
 	/* Alert waiting processes */
 	wake_up_interruptible(&pdev->frameq);
 	/* Wait until device is closed */
-	if(pdev->vopen) {
+	if (pdev->vopen) {
 		mutex_lock(&pdev->modlock);
 		pdev->unplugged = 1;
 		mutex_unlock(&pdev->modlock);
@@ -1911,8 +1905,6 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
 		/* Device is closed, so we can safely unregister it */
 		PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
 		pwc_cleanup(pdev);
-		/* Free memory (don't set pdev to 0 just yet) */
-		kfree(pdev);
 
 disconnect_out:
 		/* search device_hint[] table if we occupy a slot, by any chance */
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 2876ce0..bdb4ced 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -1033,7 +1033,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 			if (std->index != 0)
 				return -EINVAL;
 			std->id = V4L2_STD_UNKNOWN;
-			strncpy(std->name, "webcam", sizeof(std->name));
+			strlcpy(std->name, "webcam", sizeof(std->name));
 			return 0;
 		}
 
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 0b658de..0902355 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -135,12 +135,6 @@
 #define DEVICE_USE_CODEC3(x) ((x)>=700)
 #define DEVICE_USE_CODEC23(x) ((x)>=675)
 
-
-#ifndef V4L2_PIX_FMT_PWC1
-#define V4L2_PIX_FMT_PWC1	v4l2_fourcc('P','W','C','1')
-#define V4L2_PIX_FMT_PWC2	v4l2_fourcc('P','W','C','2')
-#endif
-
 /* The following structures were based on cpia.h. Why reinvent the wheel? :-) */
 struct pwc_iso_buf
 {
@@ -259,6 +253,7 @@ struct pwc_device
    int snapshot_button_status;		/* set to 1 when the user push the button, reset to 0 when this value is read */
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
    struct input_dev *button_dev;	/* webcam snapshot button input */
+   char button_phys[64];
 #endif
 
    /*** Misc. data ***/
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 016bb45..6952e96 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -225,6 +225,10 @@ struct pxa_camera_dev {
 	u32			save_cicr[5];
 };
 
+struct pxa_cam {
+	unsigned long flags;
+};
+
 static const char *pxa_cam_driver_description = "PXA_Camera";
 
 static unsigned int vid_limit = 16;	/* Video memory limit, in Mb */
@@ -237,9 +241,9 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
 {
 	struct soc_camera_device *icd = vq->priv_data;
 
-	dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
+	dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
 
-	*size = roundup(icd->width * icd->height *
+	*size = roundup(icd->user_width * icd->user_height *
 			((icd->current_fmt->depth + 7) >> 3), 8);
 
 	if (0 == *count)
@@ -259,7 +263,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
 
 	BUG_ON(in_interrupt());
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		&buf->vb, buf->vb.baddr, buf->vb.bsize);
 
 	/* This waits until this buffer is out of danger, i.e., until it is no
@@ -270,7 +274,8 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
 
 	for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
 		if (buf->dmas[i].sg_cpu)
-			dma_free_coherent(ici->dev, buf->dmas[i].sg_size,
+			dma_free_coherent(ici->v4l2_dev.dev,
+					  buf->dmas[i].sg_size,
 					  buf->dmas[i].sg_cpu,
 					  buf->dmas[i].sg_dma);
 		buf->dmas[i].sg_cpu = NULL;
@@ -325,19 +330,20 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
 				struct scatterlist **sg_first, int *sg_first_ofs)
 {
 	struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
+	struct device *dev = pcdev->soc_host.v4l2_dev.dev;
 	struct scatterlist *sg;
 	int i, offset, sglen;
 	int dma_len = 0, xfer_len = 0;
 
 	if (pxa_dma->sg_cpu)
-		dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
+		dma_free_coherent(dev, pxa_dma->sg_size,
 				  pxa_dma->sg_cpu, pxa_dma->sg_dma);
 
 	sglen = calculate_dma_sglen(*sg_first, dma->sglen,
 				    *sg_first_ofs, size);
 
 	pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
-	pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size,
+	pxa_dma->sg_cpu = dma_alloc_coherent(dev, pxa_dma->sg_size,
 					     &pxa_dma->sg_dma, GFP_KERNEL);
 	if (!pxa_dma->sg_cpu)
 		return -ENOMEM;
@@ -345,7 +351,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
 	pxa_dma->sglen = sglen;
 	offset = *sg_first_ofs;
 
-	dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
+	dev_dbg(dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
 		*sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
 
 
@@ -368,7 +374,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
 		pxa_dma->sg_cpu[i].ddadr =
 			pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
 
-		dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
+		dev_vdbg(dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
 			 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
 			 sg_dma_address(sg) + offset, xfer_len);
 		offset = 0;
@@ -418,11 +424,12 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 	struct soc_camera_device *icd = vq->priv_data;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
+	struct device *dev = pcdev->soc_host.v4l2_dev.dev;
 	struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
 	int ret;
 	int size_y, size_u = 0, size_v = 0;
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	/* Added list head initialization on alloc */
@@ -441,12 +448,12 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 	buf->inwork = 1;
 
 	if (buf->fmt	!= icd->current_fmt ||
-	    vb->width	!= icd->width ||
-	    vb->height	!= icd->height ||
+	    vb->width	!= icd->user_width ||
+	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
 		buf->fmt	= icd->current_fmt;
-		vb->width	= icd->width;
-		vb->height	= icd->height;
+		vb->width	= icd->user_width;
+		vb->height	= icd->user_height;
 		vb->field	= field;
 		vb->state	= VIDEOBUF_NEEDS_INIT;
 	}
@@ -480,8 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 		ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
 					   &sg, &next_ofs);
 		if (ret) {
-			dev_err(pcdev->soc_host.dev,
-				"DMA initialization for Y/RGB failed\n");
+			dev_err(dev, "DMA initialization for Y/RGB failed\n");
 			goto fail;
 		}
 
@@ -490,8 +496,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 			ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
 						   size_u, &sg, &next_ofs);
 		if (ret) {
-			dev_err(pcdev->soc_host.dev,
-				"DMA initialization for U failed\n");
+			dev_err(dev, "DMA initialization for U failed\n");
 			goto fail_u;
 		}
 
@@ -500,8 +505,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 			ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
 						   size_v, &sg, &next_ofs);
 		if (ret) {
-			dev_err(pcdev->soc_host.dev,
-				"DMA initialization for V failed\n");
+			dev_err(dev, "DMA initialization for V failed\n");
 			goto fail_v;
 		}
 
@@ -514,10 +518,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
 	return 0;
 
 fail_v:
-	dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size,
+	dma_free_coherent(dev, buf->dmas[1].sg_size,
 			  buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
 fail_u:
-	dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size,
+	dma_free_coherent(dev, buf->dmas[0].sg_size,
 			  buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
 fail:
 	free_buffer(vq, buf);
@@ -541,7 +545,8 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
 	active = pcdev->active;
 
 	for (i = 0; i < pcdev->channels; i++) {
-		dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__,
+		dev_dbg(pcdev->soc_host.v4l2_dev.dev,
+			"%s (channel=%d) ddadr=%08x\n", __func__,
 			i, active->dmas[i].sg_dma);
 		DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
 		DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
@@ -553,7 +558,8 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
 	int i;
 
 	for (i = 0; i < pcdev->channels; i++) {
-		dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i);
+		dev_dbg(pcdev->soc_host.v4l2_dev.dev,
+			"%s (channel=%d)\n", __func__, i);
 		DCSR(pcdev->dma_chans[i]) = 0;
 	}
 }
@@ -589,7 +595,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
 {
 	unsigned long cicr0, cifr;
 
-	dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
 	/* Reset the FIFOs */
 	cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
 	__raw_writel(cifr, pcdev->base + CIFR);
@@ -609,7 +615,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
 	__raw_writel(cicr0, pcdev->base + CICR0);
 
 	pcdev->active = NULL;
-	dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
 }
 
 /* Called under spinlock_irqsave(&pcdev->lock, ...) */
@@ -621,8 +627,8 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
 	struct pxa_camera_dev *pcdev = ici->priv;
 	struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__,
-		vb, vb->baddr, vb->bsize, pcdev->active);
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d active=%p\n",
+		__func__, vb, vb->baddr, vb->bsize, pcdev->active);
 
 	list_add_tail(&vb->queue, &pcdev->capture);
 
@@ -639,22 +645,23 @@ static void pxa_videobuf_release(struct videobuf_queue *vq,
 	struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
 #ifdef DEBUG
 	struct soc_camera_device *icd = vq->priv_data;
+	struct device *dev = icd->dev.parent;
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+	dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	switch (vb->state) {
 	case VIDEOBUF_ACTIVE:
-		dev_dbg(&icd->dev, "%s (active)\n", __func__);
+		dev_dbg(dev, "%s (active)\n", __func__);
 		break;
 	case VIDEOBUF_QUEUED:
-		dev_dbg(&icd->dev, "%s (queued)\n", __func__);
+		dev_dbg(dev, "%s (queued)\n", __func__);
 		break;
 	case VIDEOBUF_PREPARED:
-		dev_dbg(&icd->dev, "%s (prepared)\n", __func__);
+		dev_dbg(dev, "%s (prepared)\n", __func__);
 		break;
 	default:
-		dev_dbg(&icd->dev, "%s (unknown)\n", __func__);
+		dev_dbg(dev, "%s (unknown)\n", __func__);
 		break;
 	}
 #endif
@@ -674,7 +681,8 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
 	do_gettimeofday(&vb->ts);
 	vb->field_count++;
 	wake_up(&vb->done);
-	dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s dequeud buffer (vb=0x%p)\n",
+		__func__, vb);
 
 	if (list_empty(&pcdev->capture)) {
 		pxa_camera_stop_capture(pcdev);
@@ -710,7 +718,8 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
 	for (i = 0; i < pcdev->channels; i++)
 		if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
 			is_dma_stopped = 0;
-	dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev,
+		"%s : top queued buffer=%p, dma_stopped=%d\n",
 		__func__, pcdev->active, is_dma_stopped);
 	if (pcdev->active && is_dma_stopped)
 		pxa_camera_start_capture(pcdev);
@@ -719,6 +728,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
 static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 			       enum pxa_camera_active_dma act_dma)
 {
+	struct device *dev = pcdev->soc_host.v4l2_dev.dev;
 	struct pxa_buffer *buf;
 	unsigned long flags;
 	u32 status, camera_status, overrun;
@@ -735,13 +745,13 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 		overrun |= CISR_IFO_1 | CISR_IFO_2;
 
 	if (status & DCSR_BUSERR) {
-		dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n");
+		dev_err(dev, "DMA Bus Error IRQ!\n");
 		goto out;
 	}
 
 	if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
-		dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, "
-			"status: 0x%08x\n", status);
+		dev_err(dev, "Unknown DMA IRQ source, status: 0x%08x\n",
+			status);
 		goto out;
 	}
 
@@ -764,7 +774,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 	buf = container_of(vb, struct pxa_buffer, vb);
 	WARN_ON(buf->inwork || list_empty(&vb->queue));
 
-	dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
+	dev_dbg(dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
 		__func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
 		status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
 
@@ -775,7 +785,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
 		 */
 		if (camera_status & overrun &&
 		    !list_is_last(pcdev->capture.next, &pcdev->capture)) {
-			dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n",
+			dev_dbg(dev, "FIFO overrun! CISR: %x\n",
 				camera_status);
 			pxa_camera_stop_capture(pcdev);
 			pxa_camera_start_capture(pcdev);
@@ -830,9 +840,11 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q,
 				sizeof(struct pxa_buffer), icd);
 }
 
-static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
+static u32 mclk_get_divisor(struct platform_device *pdev,
+			    struct pxa_camera_dev *pcdev)
 {
 	unsigned long mclk = pcdev->mclk;
+	struct device *dev = &pdev->dev;
 	u32 div;
 	unsigned long lcdclk;
 
@@ -842,7 +854,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
 	/* mclk <= ciclk / 4 (27.4.2) */
 	if (mclk > lcdclk / 4) {
 		mclk = lcdclk / 4;
-		dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk);
+		dev_warn(dev, "Limiting master clock to %lu\n", mclk);
 	}
 
 	/* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
@@ -852,8 +864,8 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
 	if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
 		pcdev->mclk = lcdclk / (2 * (div + 1));
 
-	dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, "
-		"divisor %u\n", lcdclk, mclk, div);
+	dev_dbg(dev, "LCD clock %luHz, target freq %luHz, divisor %u\n",
+		lcdclk, mclk, div);
 
 	return div;
 }
@@ -870,14 +882,15 @@ static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
 static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
 {
 	struct pxacamera_platform_data *pdata = pcdev->pdata;
+	struct device *dev = pcdev->soc_host.v4l2_dev.dev;
 	u32 cicr4 = 0;
 
-	dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n",
+	dev_dbg(dev, "Registered platform device at %p data %p\n",
 		pcdev, pdata);
 
 	if (pdata && pdata->init) {
-		dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__);
-		pdata->init(pcdev->soc_host.dev);
+		dev_dbg(dev, "%s: Init gpios\n", __func__);
+		pdata->init(dev);
 	}
 
 	/* disable all interrupts */
@@ -919,7 +932,8 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
 	struct videobuf_buffer *vb;
 
 	status = __raw_readl(pcdev->base + CISR);
-	dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status);
+	dev_dbg(pcdev->soc_host.v4l2_dev.dev,
+		"Camera interrupt status 0x%lx\n", status);
 
 	if (!status)
 		return IRQ_NONE;
@@ -951,24 +965,18 @@ static int pxa_camera_add_device(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
-	int ret;
 
-	if (pcdev->icd) {
-		ret = -EBUSY;
-		goto ebusy;
-	}
-
-	dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n",
-		 icd->devnum);
+	if (pcdev->icd)
+		return -EBUSY;
 
 	pxa_camera_activate(pcdev);
-	ret = icd->ops->init(icd);
 
-	if (!ret)
-		pcdev->icd = icd;
+	pcdev->icd = icd;
 
-ebusy:
-	return ret;
+	dev_info(icd->dev.parent, "PXA Camera driver attached to camera %d\n",
+		 icd->devnum);
+
+	return 0;
 }
 
 /* Called with .video_lock held */
@@ -979,7 +987,7 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
 
 	BUG_ON(icd != pcdev->icd);
 
-	dev_info(&icd->dev, "PXA Camera driver detached from camera %d\n",
+	dev_info(icd->dev.parent, "PXA Camera driver detached from camera %d\n",
 		 icd->devnum);
 
 	/* disable capture, disable interrupts */
@@ -990,8 +998,6 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
 	DCSR(pcdev->dma_chans[1]) = 0;
 	DCSR(pcdev->dma_chans[2]) = 0;
 
-	icd->ops->release(icd);
-
 	pxa_camera_deactivate(pcdev);
 
 	pcdev->icd = NULL;
@@ -1039,57 +1045,17 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
 	return 0;
 }
 
-static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
+static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
+				  unsigned long flags, __u32 pixfmt)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
-	unsigned long dw, bpp, bus_flags, camera_flags, common_flags;
+	unsigned long dw, bpp;
 	u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0;
-	int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
-
-	if (ret < 0)
-		return ret;
-
-	camera_flags = icd->ops->query_bus_param(icd);
-
-	common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
-	if (!common_flags)
-		return -EINVAL;
-
-	pcdev->channels = 1;
-
-	/* Make choises, based on platform preferences */
-	if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
-	    (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
-		if (pcdev->platform_flags & PXA_CAMERA_HSP)
-			common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
-		else
-			common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
-	}
-
-	if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
-	    (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
-		if (pcdev->platform_flags & PXA_CAMERA_VSP)
-			common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
-		else
-			common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
-	}
-
-	if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
-	    (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
-		if (pcdev->platform_flags & PXA_CAMERA_PCP)
-			common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
-		else
-			common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
-	}
-
-	ret = icd->ops->set_bus_param(icd, common_flags);
-	if (ret < 0)
-		return ret;
 
 	/* Datawidth is now guaranteed to be equal to one of the three values.
 	 * We fix bit-per-pixel equal to data-width... */
-	switch (common_flags & SOCAM_DATAWIDTH_MASK) {
+	switch (flags & SOCAM_DATAWIDTH_MASK) {
 	case SOCAM_DATAWIDTH_10:
 		dw = 4;
 		bpp = 0x40;
@@ -1110,18 +1076,18 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 		cicr4 |= CICR4_PCLK_EN;
 	if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
 		cicr4 |= CICR4_MCLK_EN;
-	if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
+	if (flags & SOCAM_PCLK_SAMPLE_FALLING)
 		cicr4 |= CICR4_PCP;
-	if (common_flags & SOCAM_HSYNC_ACTIVE_LOW)
+	if (flags & SOCAM_HSYNC_ACTIVE_LOW)
 		cicr4 |= CICR4_HSP;
-	if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
+	if (flags & SOCAM_VSYNC_ACTIVE_LOW)
 		cicr4 |= CICR4_VSP;
 
 	cicr0 = __raw_readl(pcdev->base + CICR0);
 	if (cicr0 & CICR0_ENB)
 		__raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0);
 
-	cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw;
+	cicr1 = CICR1_PPL_VAL(icd->user_width - 1) | bpp | dw;
 
 	switch (pixfmt) {
 	case V4L2_PIX_FMT_YUV422P:
@@ -1150,7 +1116,7 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 	}
 
 	cicr2 = 0;
-	cicr3 = CICR3_LPF_VAL(icd->height - 1) |
+	cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
 		CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
 	cicr4 |= pcdev->mclk_divisor;
 
@@ -1164,6 +1130,59 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
 		CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP));
 	cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK;
 	__raw_writel(cicr0, pcdev->base + CICR0);
+}
+
+static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct pxa_camera_dev *pcdev = ici->priv;
+	unsigned long bus_flags, camera_flags, common_flags;
+	int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
+	struct pxa_cam *cam = icd->host_priv;
+
+	if (ret < 0)
+		return ret;
+
+	camera_flags = icd->ops->query_bus_param(icd);
+
+	common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+	if (!common_flags)
+		return -EINVAL;
+
+	pcdev->channels = 1;
+
+	/* Make choises, based on platform preferences */
+	if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
+	    (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+		if (pcdev->platform_flags & PXA_CAMERA_HSP)
+			common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+		else
+			common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+	}
+
+	if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
+	    (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+		if (pcdev->platform_flags & PXA_CAMERA_VSP)
+			common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+		else
+			common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+	}
+
+	if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
+	    (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+		if (pcdev->platform_flags & PXA_CAMERA_PCP)
+			common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+		else
+			common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+	}
+
+	cam->flags = common_flags;
+
+	ret = icd->ops->set_bus_param(icd, common_flags);
+	if (ret < 0)
+		return ret;
+
+	pxa_camera_setup_cicr(icd, common_flags, pixfmt);
 
 	return 0;
 }
@@ -1227,8 +1246,9 @@ static int required_buswidth(const struct soc_camera_data_format *fmt)
 static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 				  struct soc_camera_format_xlate *xlate)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct device *dev = icd->dev.parent;
 	int formats = 0, buswidth, ret;
+	struct pxa_cam *cam;
 
 	buswidth = required_buswidth(icd->formats + idx);
 
@@ -1239,6 +1259,16 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 	if (ret < 0)
 		return 0;
 
+	if (!icd->host_priv) {
+		cam = kzalloc(sizeof(*cam), GFP_KERNEL);
+		if (!cam)
+			return -ENOMEM;
+
+		icd->host_priv = cam;
+	} else {
+		cam = icd->host_priv;
+	}
+
 	switch (icd->formats[idx].fourcc) {
 	case V4L2_PIX_FMT_UYVY:
 		formats++;
@@ -1247,7 +1277,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(ici->dev, "Providing format %s using %s\n",
+			dev_dbg(dev, "Providing format %s using %s\n",
 				pxa_camera_formats[0].name,
 				icd->formats[idx].name);
 		}
@@ -1262,7 +1292,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = buswidth;
 			xlate++;
-			dev_dbg(ici->dev, "Providing format %s packed\n",
+			dev_dbg(dev, "Providing format %s packed\n",
 				icd->formats[idx].name);
 		}
 		break;
@@ -1274,7 +1304,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = icd->formats[idx].depth;
 			xlate++;
-			dev_dbg(ici->dev,
+			dev_dbg(dev,
 				"Providing format %s in pass-through mode\n",
 				icd->formats[idx].name);
 		}
@@ -1283,31 +1313,80 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
 	return formats;
 }
 
+static void pxa_camera_put_formats(struct soc_camera_device *icd)
+{
+	kfree(icd->host_priv);
+	icd->host_priv = NULL;
+}
+
+static int pxa_camera_check_frame(struct v4l2_pix_format *pix)
+{
+	/* limit to pxa hardware capabilities */
+	return pix->height < 32 || pix->height > 2048 || pix->width < 48 ||
+		pix->width > 2048 || (pix->width & 0x01);
+}
+
 static int pxa_camera_set_crop(struct soc_camera_device *icd,
-			       struct v4l2_rect *rect)
+			       struct v4l2_crop *a)
 {
+	struct v4l2_rect *rect = &a->c;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
+	struct device *dev = icd->dev.parent;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	struct soc_camera_sense sense = {
 		.master_clock = pcdev->mclk,
 		.pixel_clock_max = pcdev->ciclk / 4,
 	};
+	struct v4l2_format f;
+	struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp;
+	struct pxa_cam *cam = icd->host_priv;
 	int ret;
 
 	/* If PCLK is used to latch data from the sensor, check sense */
 	if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
 		icd->sense = &sense;
 
-	ret = icd->ops->set_crop(icd, rect);
+	ret = v4l2_subdev_call(sd, video, s_crop, a);
 
 	icd->sense = NULL;
 
 	if (ret < 0) {
-		dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n",
+		dev_warn(dev, "Failed to crop to %ux%u@%u:%u\n",
 			 rect->width, rect->height, rect->left, rect->top);
-	} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
+		return ret;
+	}
+
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+	if (ret < 0)
+		return ret;
+
+	pix_tmp = *pix;
+	if (pxa_camera_check_frame(pix)) {
+		/*
+		 * Camera cropping produced a frame beyond our capabilities.
+		 * FIXME: just extract a subframe, that we can process.
+		 */
+		v4l_bound_align_image(&pix->width, 48, 2048, 1,
+			&pix->height, 32, 2048, 0,
+			icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ?
+				4 : 0);
+		ret = v4l2_subdev_call(sd, video, s_fmt, &f);
+		if (ret < 0)
+			return ret;
+
+		if (pxa_camera_check_frame(pix)) {
+			dev_warn(icd->dev.parent,
+				 "Inconsistent state. Use S_FMT to repair\n");
+			return -EINVAL;
+		}
+	}
+
+	if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
 		if (sense.pixel_clock > sense.pixel_clock_max) {
-			dev_err(ici->dev,
+			dev_err(dev,
 				"pixel clock %lu set by the camera too high!",
 				sense.pixel_clock);
 			return -EIO;
@@ -1315,6 +1394,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
 		recalculate_fifo_timeout(pcdev, sense.pixel_clock);
 	}
 
+	icd->user_width = pix->width;
+	icd->user_height = pix->height;
+
+	pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc);
+
 	return ret;
 }
 
@@ -1323,6 +1407,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
+	struct device *dev = icd->dev.parent;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_data_format *cam_fmt = NULL;
 	const struct soc_camera_format_xlate *xlate = NULL;
 	struct soc_camera_sense sense = {
@@ -1335,7 +1421,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
 	if (!xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat);
+		dev_warn(dev, "Format %x not found\n", pix->pixelformat);
 		return -EINVAL;
 	}
 
@@ -1346,16 +1432,21 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
 		icd->sense = &sense;
 
 	cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
-	ret = icd->ops->set_fmt(icd, &cam_f);
+	ret = v4l2_subdev_call(sd, video, s_fmt, f);
 
 	icd->sense = NULL;
 
 	if (ret < 0) {
-		dev_warn(ici->dev, "Failed to configure for format %x\n",
+		dev_warn(dev, "Failed to configure for format %x\n",
 			 pix->pixelformat);
+	} else if (pxa_camera_check_frame(pix)) {
+		dev_warn(dev,
+			 "Camera driver produced an unsupported frame %dx%d\n",
+			 pix->width, pix->height);
+		ret = -EINVAL;
 	} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
 		if (sense.pixel_clock > sense.pixel_clock_max) {
-			dev_err(ici->dev,
+			dev_err(dev,
 				"pixel clock %lu set by the camera too high!",
 				sense.pixel_clock);
 			return -EIO;
@@ -1375,6 +1466,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
 			      struct v4l2_format *f)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	const struct soc_camera_format_xlate *xlate;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	__u32 pixfmt = pix->pixelformat;
@@ -1383,7 +1475,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
@@ -1395,7 +1487,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
 	 */
 	v4l_bound_align_image(&pix->width, 48, 2048, 1,
 			      &pix->height, 32, 2048, 0,
-			      xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
+			      pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
 
 	pix->bytesperline = pix->width *
 		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
@@ -1404,15 +1496,15 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
 	/* camera has to see its format, but the user the original one */
 	pix->pixelformat = xlate->cam_fmt->fourcc;
 	/* limit to sensor capabilities */
-	ret = icd->ops->try_fmt(icd, f);
-	pix->pixelformat = xlate->host_fmt->fourcc;
+	ret = v4l2_subdev_call(sd, video, try_fmt, f);
+	pix->pixelformat = pixfmt;
 
 	field = pix->field;
 
 	if (field == V4L2_FIELD_ANY) {
 		pix->field = V4L2_FIELD_NONE;
 	} else if (field != V4L2_FIELD_NONE) {
-		dev_err(&icd->dev, "Field type %d unsupported.\n", field);
+		dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
 		return -EINVAL;
 	}
 
@@ -1518,6 +1610,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
 	.resume		= pxa_camera_resume,
 	.set_crop	= pxa_camera_set_crop,
 	.get_formats	= pxa_camera_get_formats,
+	.put_formats	= pxa_camera_put_formats,
 	.set_fmt	= pxa_camera_set_fmt,
 	.try_fmt	= pxa_camera_try_fmt,
 	.init_videobuf	= pxa_camera_init_videobuf,
@@ -1575,8 +1668,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
 		pcdev->mclk = 20000000;
 	}
 
-	pcdev->soc_host.dev = &pdev->dev;
-	pcdev->mclk_divisor = mclk_get_divisor(pcdev);
+	pcdev->mclk_divisor = mclk_get_divisor(pdev, pcdev);
 
 	INIT_LIST_HEAD(&pcdev->capture);
 	spin_lock_init(&pcdev->lock);
@@ -1641,6 +1733,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
 	pcdev->soc_host.drv_name	= PXA_CAM_DRV_NAME;
 	pcdev->soc_host.ops		= &pxa_soc_camera_host_ops;
 	pcdev->soc_host.priv		= pcdev;
+	pcdev->soc_host.v4l2_dev.dev	= &pdev->dev;
 	pcdev->soc_host.nr		= pdev->id;
 
 	err = soc_camera_host_register(&pcdev->soc_host);
@@ -1722,3 +1815,4 @@ module_exit(pxa_camera_exit);
 MODULE_DESCRIPTION("PXA27x SoC Camera Host driver");
 MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" PXA_CAM_DRV_NAME);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index c25e81a..c3e96f0 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -40,7 +40,7 @@
 /* insmod options */
 static unsigned int debug;
 static unsigned int xtal;
-static unsigned int rbds;
+static unsigned int mmbs;
 static unsigned int plvl;
 static unsigned int bufblocks = 100;
 
@@ -48,8 +48,8 @@ module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "enable debug messages");
 module_param(xtal, int, 0);
 MODULE_PARM_DESC(xtal, "select oscillator frequency (0..3), default 0");
-module_param(rbds, int, 0);
-MODULE_PARM_DESC(rbds, "select mode, 0=RDS, 1=RBDS, default 0");
+module_param(mmbs, int, 0);
+MODULE_PARM_DESC(mmbs, "enable MMBS mode: 0=off (default), 1=on");
 module_param(plvl, int, 0);
 MODULE_PARM_DESC(plvl, "select pause level (0..3), default 0");
 module_param(bufblocks, int, 0);
@@ -78,6 +78,7 @@ struct saa6588 {
 	unsigned char last_blocknum;
 	wait_queue_head_t read_queue;
 	int data_available_for_read;
+	u8 sync;
 };
 
 static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
@@ -261,13 +262,16 @@ static void saa6588_i2c_poll(struct saa6588 *s)
 	unsigned char tmp;
 
 	/* Although we only need 3 bytes, we have to read at least 6.
-	   SAA6588 returns garbage otherwise */
+	   SAA6588 returns garbage otherwise. */
 	if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) {
 		if (debug > 1)
 			dprintk(PREFIX "read error!\n");
 		return;
 	}
 
+	s->sync = tmpbuf[0] & 0x10;
+	if (!s->sync)
+		return;
 	blocknum = tmpbuf[0] >> 5;
 	if (blocknum == s->last_blocknum) {
 		if (debug > 3)
@@ -286,9 +290,8 @@ static void saa6588_i2c_poll(struct saa6588 *s)
 	   occurred during reception of this block.
 	   Bit 6: Corrected bit. Indicates that an error was
 	   corrected for this data block.
-	   Bits 5-3: Received Offset. Indicates the offset received
-	   by the sync system.
-	   Bits 2-0: Offset Name. Indicates the offset applied to this data.
+	   Bits 5-3: Same as bits 0-2.
+	   Bits 2-0: Block number.
 
 	   SAA6588 byte order is Status-MSB-LSB, so we have to swap the
 	   first and the last of the 3 bytes block.
@@ -298,12 +301,21 @@ static void saa6588_i2c_poll(struct saa6588 *s)
 	tmpbuf[2] = tmpbuf[0];
 	tmpbuf[0] = tmp;
 
+	/* Map 'Invalid block E' to 'Invalid Block' */
+	if (blocknum == 6)
+		blocknum = V4L2_RDS_BLOCK_INVALID;
+	/* And if are not in mmbs mode, then 'Block E' is also mapped
+	   to 'Invalid Block'. As far as I can tell MMBS is discontinued,
+	   and if there is ever a need to support E blocks, then please
+	   contact the linux-media mailinglist. */
+	else if (!mmbs && blocknum == 5)
+		blocknum = V4L2_RDS_BLOCK_INVALID;
 	tmp = blocknum;
 	tmp |= blocknum << 3;	/* Received offset == Offset Name (OK ?) */
 	if ((tmpbuf[2] & 0x03) == 0x03)
-		tmp |= 0x80;	/* uncorrectable error */
+		tmp |= V4L2_RDS_BLOCK_ERROR;	 /* uncorrectable error */
 	else if ((tmpbuf[2] & 0x03) != 0x00)
-		tmp |= 0x40;	/* corrected error */
+		tmp |= V4L2_RDS_BLOCK_CORRECTED; /* corrected error */
 	tmpbuf[2] = tmp;	/* Is this enough ? Should we also check other bits ? */
 
 	spin_lock_irqsave(&s->lock, flags);
@@ -321,14 +333,14 @@ static void saa6588_work(struct work_struct *work)
 	schedule_delayed_work(&s->work, msecs_to_jiffies(20));
 }
 
-static int saa6588_configure(struct saa6588 *s)
+static void saa6588_configure(struct saa6588 *s)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
 	unsigned char buf[3];
 	int rc;
 
 	buf[0] = cSyncRestart;
-	if (rbds)
+	if (mmbs)
 		buf[0] |= cProcessingModeRBDS;
 
 	buf[1] = cFlywheelDefault;
@@ -374,8 +386,6 @@ static int saa6588_configure(struct saa6588 *s)
 	rc = i2c_master_send(client, buf, 3);
 	if (rc != 3)
 		printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
-
-	return 0;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -416,6 +426,24 @@ static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
 	return 0;
 }
 
+static int saa6588_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+	struct saa6588 *s = to_saa6588(sd);
+
+	vt->capability |= V4L2_TUNER_CAP_RDS;
+	if (s->sync)
+		vt->rxsubchans |= V4L2_TUNER_SUB_RDS;
+	return 0;
+}
+
+static int saa6588_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+	struct saa6588 *s = to_saa6588(sd);
+
+	saa6588_configure(s);
+	return 0;
+}
+
 static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
 {
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -430,8 +458,14 @@ static const struct v4l2_subdev_core_ops saa6588_core_ops = {
 	.ioctl = saa6588_ioctl,
 };
 
+static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = {
+	.g_tuner = saa6588_g_tuner,
+	.s_tuner = saa6588_s_tuner,
+};
+
 static const struct v4l2_subdev_ops saa6588_ops = {
 	.core = &saa6588_core_ops,
+	.tuner = &saa6588_tuner_ops,
 };
 
 /* ---------------------------------------------------------------------- */
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 5bcce09..22bfd62 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -47,6 +47,7 @@ config VIDEO_SAA7134_DVB
 	select DVB_TDA10048 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+	select DVB_ZL10039 if !DVB_FE_CUSTOMISE
 	---help---
 	  This adds support for DVB cards based on the
 	  Philips saa7134 chip.
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 63c4b8f..1eabff6 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -468,7 +468,7 @@ static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
 		if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
 		    (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
 			return -ERANGE;
-		new = old;
+		params->au_encoding = new;
 		break;
 	case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
 		old = params->au_l2_bitrate;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 8b0b64a..d48c450 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -40,6 +40,7 @@ MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
  */
 
 /* defaults */
+#define MIXER_ADDR_UNSELECTED	-1
 #define MIXER_ADDR_TVTUNER	0
 #define MIXER_ADDR_LINE1	1
 #define MIXER_ADDR_LINE2	2
@@ -68,7 +69,9 @@ typedef struct snd_card_saa7134 {
 	struct snd_card *card;
 	spinlock_t mixer_lock;
 	int mixer_volume[MIXER_ADDR_LAST+1][2];
-	int capture_source[MIXER_ADDR_LAST+1][2];
+	int capture_source_addr;
+	int capture_source[2];
+	struct snd_kcontrol *capture_ctl[MIXER_ADDR_LAST+1];
 	struct pci_dev *pci;
 	struct saa7134_dev *dev;
 
@@ -314,6 +317,115 @@ static int dsp_buffer_free(struct saa7134_dev *dev)
 	return 0;
 }
 
+/*
+ * Setting the capture source and updating the ALSA controls
+ */
+static int snd_saa7134_capsrc_set(struct snd_kcontrol *kcontrol,
+				  int left, int right, bool force_notify)
+{
+	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
+	int change = 0, addr = kcontrol->private_value;
+	int active, old_addr;
+	u32 anabar, xbarin;
+	int analog_io, rate;
+	struct saa7134_dev *dev;
+
+	dev = chip->dev;
+
+	spin_lock_irq(&chip->mixer_lock);
+
+	active = left != 0 || right != 0;
+	old_addr = chip->capture_source_addr;
+
+	/* The active capture source cannot be deactivated */
+	if (active) {
+		change = old_addr != addr ||
+			 chip->capture_source[0] != left ||
+			 chip->capture_source[1] != right;
+
+		chip->capture_source[0] = left;
+		chip->capture_source[1] = right;
+		chip->capture_source_addr = addr;
+		dev->dmasound.input = addr;
+	}
+	spin_unlock_irq(&chip->mixer_lock);
+
+	if (change) {
+		switch (dev->pci->device) {
+
+		case PCI_DEVICE_ID_PHILIPS_SAA7134:
+			switch (addr) {
+			case MIXER_ADDR_TVTUNER:
+				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
+					   0xc0, 0xc0);
+				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
+					   0x03, 0x00);
+				break;
+			case MIXER_ADDR_LINE1:
+			case MIXER_ADDR_LINE2:
+				analog_io = (MIXER_ADDR_LINE1 == addr) ?
+					     0x00 : 0x08;
+				rate = (32000 == dev->dmasound.rate) ?
+					0x01 : 0x03;
+				saa_andorb(SAA7134_ANALOG_IO_SELECT,
+					   0x08, analog_io);
+				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
+					   0xc0, 0x80);
+				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
+					   0x03, rate);
+				break;
+			}
+
+			break;
+		case PCI_DEVICE_ID_PHILIPS_SAA7133:
+		case PCI_DEVICE_ID_PHILIPS_SAA7135:
+			xbarin = 0x03; /* adc */
+			anabar = 0;
+			switch (addr) {
+			case MIXER_ADDR_TVTUNER:
+				xbarin = 0; /* Demodulator */
+				anabar = 2; /* DACs */
+				break;
+			case MIXER_ADDR_LINE1:
+				anabar = 0;  /* aux1, aux1 */
+				break;
+			case MIXER_ADDR_LINE2:
+				anabar = 9;  /* aux2, aux2 */
+				break;
+			}
+
+			/* output xbar always main channel */
+			saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1,
+				       0xbbbb10);
+
+			if (left || right) {
+				/* We've got data, turn the input on */
+				saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
+					       xbarin);
+				saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
+			} else {
+				saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
+					       0);
+				saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
+			}
+			break;
+		}
+	}
+
+	if (change) {
+		if (force_notify)
+			snd_ctl_notify(chip->card,
+				       SNDRV_CTL_EVENT_MASK_VALUE,
+				       &chip->capture_ctl[addr]->id);
+
+		if (old_addr != MIXER_ADDR_UNSELECTED && old_addr != addr)
+			snd_ctl_notify(chip->card,
+				       SNDRV_CTL_EVENT_MASK_VALUE,
+				       &chip->capture_ctl[old_addr]->id);
+	}
+
+	return change;
+}
 
 /*
  * ALSA PCM preparation
@@ -401,6 +513,10 @@ static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream
 
 	dev->dmasound.rate = runtime->rate;
 
+	/* Setup and update the card/ALSA controls */
+	snd_saa7134_capsrc_set(saa7134->capture_ctl[dev->dmasound.input], 1, 1,
+			       true);
+
 	return 0;
 
 }
@@ -435,6 +551,16 @@ snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
 
 /*
  * ALSA hardware capabilities definition
+ *
+ *  Report only 32kHz for ALSA:
+ *
+ *  - SAA7133/35 uses DDEP (DemDec Easy Programming mode), which works in 32kHz
+ *    only
+ *  - SAA7134 for TV mode uses DemDec mode (32kHz)
+ *  - Radio works in 32kHz only
+ *  - When recording 48kHz from Line1/Line2, switching of capture source to TV
+ *    means
+ *    switching to 32kHz without any frequency translation
  */
 
 static struct snd_pcm_hardware snd_card_saa7134_capture =
@@ -448,9 +574,9 @@ static struct snd_pcm_hardware snd_card_saa7134_capture =
 				SNDRV_PCM_FMTBIT_U8 | \
 				SNDRV_PCM_FMTBIT_U16_LE | \
 				SNDRV_PCM_FMTBIT_U16_BE,
-	.rates =		SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+	.rates =		SNDRV_PCM_RATE_32000,
 	.rate_min =		32000,
-	.rate_max =		48000,
+	.rate_max =		32000,
 	.channels_min =		1,
 	.channels_max =		2,
 	.buffer_bytes_max =	(256*1024),
@@ -836,8 +962,13 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
 	int addr = kcontrol->private_value;
 
 	spin_lock_irq(&chip->mixer_lock);
-	ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
-	ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
+	if (chip->capture_source_addr == addr) {
+		ucontrol->value.integer.value[0] = chip->capture_source[0];
+		ucontrol->value.integer.value[1] = chip->capture_source[1];
+	} else {
+		ucontrol->value.integer.value[0] = 0;
+		ucontrol->value.integer.value[1] = 0;
+	}
 	spin_unlock_irq(&chip->mixer_lock);
 
 	return 0;
@@ -846,87 +977,22 @@ static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
 static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
 				  struct snd_ctl_elem_value * ucontrol)
 {
-	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
-	int change, addr = kcontrol->private_value;
 	int left, right;
-	u32 anabar, xbarin;
-	int analog_io, rate;
-	struct saa7134_dev *dev;
-
-	dev = chip->dev;
-
 	left = ucontrol->value.integer.value[0] & 1;
 	right = ucontrol->value.integer.value[1] & 1;
-	spin_lock_irq(&chip->mixer_lock);
-
-	change = chip->capture_source[addr][0] != left ||
-		 chip->capture_source[addr][1] != right;
-	chip->capture_source[addr][0] = left;
-	chip->capture_source[addr][1] = right;
-	dev->dmasound.input=addr;
-	spin_unlock_irq(&chip->mixer_lock);
-
-
-	if (change) {
-	  switch (dev->pci->device) {
-
-	   case PCI_DEVICE_ID_PHILIPS_SAA7134:
-		switch (addr) {
-			case MIXER_ADDR_TVTUNER:
-				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
-				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, 0x00);
-				break;
-			case MIXER_ADDR_LINE1:
-			case MIXER_ADDR_LINE2:
-				analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
-				rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
-				saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x08, analog_io);
-				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
-				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,   0x03, rate);
-				break;
-		}
-
-		break;
-	   case PCI_DEVICE_ID_PHILIPS_SAA7133:
-	   case PCI_DEVICE_ID_PHILIPS_SAA7135:
-		xbarin = 0x03; // adc
-		anabar = 0;
-		switch (addr) {
-			case MIXER_ADDR_TVTUNER:
-				xbarin = 0; // Demodulator
-				anabar = 2; // DACs
-				break;
-			case MIXER_ADDR_LINE1:
-				anabar = 0;  // aux1, aux1
-				break;
-			case MIXER_ADDR_LINE2:
-				anabar = 9;  // aux2, aux2
-				break;
-		}
-
-		/* output xbar always main channel */
-		saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
 
-		if (left || right) { // We've got data, turn the input on
-		  saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
-		  saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
-		} else {
-		  saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
-		  saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
-		}
-		break;
-	  }
-	}
-
-	return change;
+	return snd_saa7134_capsrc_set(kcontrol, left, right, false);
 }
 
-static struct snd_kcontrol_new snd_saa7134_controls[] = {
+static struct snd_kcontrol_new snd_saa7134_volume_controls[] = {
 SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
-SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
 SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
-SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
 SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
+};
+
+static struct snd_kcontrol_new snd_saa7134_capture_controls[] = {
+SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
+SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
 SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
 };
 
@@ -941,17 +1007,33 @@ SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
 static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
 {
 	struct snd_card *card = chip->card;
+	struct snd_kcontrol *kcontrol;
 	unsigned int idx;
-	int err;
+	int err, addr;
 
 	if (snd_BUG_ON(!chip))
 		return -EINVAL;
 	strcpy(card->mixername, "SAA7134 Mixer");
 
-	for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
-		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
+	for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
+		kcontrol = snd_ctl_new1(&snd_saa7134_volume_controls[idx],
+					chip);
+		err = snd_ctl_add(card, kcontrol);
+		if (err < 0)
 			return err;
 	}
+
+	for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_capture_controls); idx++) {
+		kcontrol = snd_ctl_new1(&snd_saa7134_capture_controls[idx],
+					chip);
+		addr = snd_saa7134_capture_controls[idx].private_value;
+		chip->capture_ctl[addr] = kcontrol;
+		err = snd_ctl_add(card, kcontrol);
+		if (err < 0)
+			return err;
+	}
+
+	chip->capture_source_addr = MIXER_ADDR_UNSELECTED;
 	return 0;
 }
 
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 6eebe3e..71145bf 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -32,6 +32,7 @@
 #include <media/tveeprom.h>
 #include "tea5767.h"
 #include "tda18271.h"
+#include "xc5000.h"
 
 /* commly used strings */
 static char name_mute[]    = "mute";
@@ -265,6 +266,56 @@ struct saa7134_board saa7134_boards[] = {
 			.gpio = 0x10000,
 		},
 	},
+	[SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM] = {
+		/* RoverMedia TV Link Pro FM (LR138 REV:I) */
+		/* Eugene Yudin <Eugene.Yudin@gmail.com> */
+		.name		= "RoverMedia TV Link Pro FM",
+		.audio_clock	= 0x00200000,
+		.tuner_type	= TUNER_PHILIPS_FM1216ME_MK3, /* TCL MFPE05 2 */
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.gpiomask       = 0xe000,
+		.inputs         = { {
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.gpio = 0x8000,
+			.tv   = 1,
+		}, {
+			.name = name_tv_mono,
+			.vmux = 1,
+			.amux = LINE2,
+			.gpio = 0x0000,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+			.gpio = 0x4000,
+		}, {
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE2,
+			.gpio = 0x4000,
+		}, {
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
+			.gpio = 0x4000,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+			.gpio = 0x2000,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = TV,
+			.gpio = 0x8000,
+		},
+	},
 	[SAA7134_BOARD_EMPRESS] = {
 		/* "Gert Vervoort" <gert.vervoort@philips.com> */
 		.name		= "EMPRESS",
@@ -1364,6 +1415,42 @@ struct saa7134_board saa7134_boards[] = {
 			.amux = LINE1,
 		},
 	},
+	[SAA7134_BOARD_AVERMEDIA_STUDIO_505] = {
+		/* Vasiliy Temnikov <vaka@newmail.ru> */
+		.name           = "AverMedia AverTV Studio 505",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
+		.inputs         = { {
+			.name = name_tv,
+			.vmux = 1,
+			.amux = LINE2,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE2,
+		}, {
+			.name = name_comp2,
+			.vmux = 3,
+			.amux = LINE2,
+		},{
+			.name = name_svideo,
+			.vmux = 8,
+			.amux = LINE2,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = LINE2,
+		},
+		.mute = {
+			.name = name_mute,
+			.amux = LINE1,
+		},
+	},
 	[SAA7134_BOARD_UPMOST_PURPLE_TV] = {
 		.name           = "UPMOST PURPLE TV",
 		.audio_clock    = 0x00187de7,
@@ -1633,7 +1720,7 @@ struct saa7134_board saa7134_boards[] = {
 		}},
 		.radio = {
 			.name = name_radio,
-			.amux = LINE1,
+			.amux = TV,
 			.gpio = 0x00300001,
 		},
 		.mute = {
@@ -3663,8 +3750,8 @@ struct saa7134_board saa7134_boards[] = {
 			.amux = TV,
 			.gpio = 0x0200000,
 		},
-       },
-       [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = {
+	},
+	[SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = {
 	       .name           = "ASUSTeK P7131 Analog",
 	       .audio_clock    = 0x00187de7,
 	       .tuner_type     = TUNER_PHILIPS_TDA8290,
@@ -4077,10 +4164,11 @@ struct saa7134_board saa7134_boards[] = {
 		/*Dmitry Belimov <d.belimov@gmail.com> */
 		.name           = "Beholder BeholdTV 505 RDS",
 		.audio_clock    = 0x00200000,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.tuner_type     = TUNER_PHILIPS_FM1216MK5,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs         = {{
@@ -4141,10 +4229,11 @@ struct saa7134_board saa7134_boards[] = {
 		/*Dmitry Belimov <d.belimov@gmail.com> */
 		.name           = "Beholder BeholdTV 507 RDS",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.tuner_type     = TUNER_PHILIPS_FM1216MK5,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs         = {{
@@ -4175,6 +4264,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.gpiomask       = 0x00008000,
 		.inputs         = {{
@@ -4290,7 +4380,7 @@ struct saa7134_board saa7134_boards[] = {
 		/* Andrey Melnikoff <temnota@kmv.ru> */
 		.name           = "Beholder BeholdTV 607 FM",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.tuner_type     = TUNER_PHILIPS_FM1216MK5,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
@@ -4318,7 +4408,7 @@ struct saa7134_board saa7134_boards[] = {
 		/* Andrey Melnikoff <temnota@kmv.ru> */
 		.name           = "Beholder BeholdTV 609 FM",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.tuner_type     = TUNER_PHILIPS_FM1216MK5,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
@@ -4350,6 +4440,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -4378,6 +4469,7 @@ struct saa7134_board saa7134_boards[] = {
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -4402,10 +4494,11 @@ struct saa7134_board saa7134_boards[] = {
 		/* Andrey Melnikoff <temnota@kmv.ru> */
 		.name           = "Beholder BeholdTV 607 RDS",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.tuner_type     = TUNER_PHILIPS_FM1216MK5,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -4430,10 +4523,11 @@ struct saa7134_board saa7134_boards[] = {
 		/* Andrey Melnikoff <temnota@kmv.ru> */
 		.name           = "Beholder BeholdTV 609 RDS",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.tuner_type     = TUNER_PHILIPS_FM1216MK5,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = {{
 			.name = name_tv,
@@ -4536,10 +4630,11 @@ struct saa7134_board saa7134_boards[] = {
 		/* Alexey Osipov <lion-simba@pridelands.ru> */
 		.name           = "Beholder BeholdTV M6 Extra",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */
+		.tuner_type     = TUNER_PHILIPS_FM1216MK5,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
+		.rds_addr 	= 0x10,
 		.empress_addr 	= 0x20,
 		.tda9887_conf   = TDA9887_PRESENT,
 		.inputs         = { {
@@ -4861,7 +4956,7 @@ struct saa7134_board saa7134_boards[] = {
 		/* Igor Kuznetsov <igk@igk.ru> */
 		.name           = "Beholder BeholdTV H6",
 		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
+		.tuner_type     = TUNER_PHILIPS_FMD1216MEX_MK3,
 		.radio_type     = UNSET,
 		.tuner_addr     = ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
@@ -5116,6 +5211,74 @@ struct saa7134_board saa7134_boards[] = {
 			.gpio = 0x00,
 		},
 	},
+	[SAA7134_BOARD_VIDEOMATE_S350] = {
+		/* Jan D. Louw <jd.louw@mweb.co.za */
+		.name		= "Compro VideoMate S350/S300",
+		.audio_clock	= 0x00187de7,
+		.tuner_type	= TUNER_ABSENT,
+		.radio_type	= UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.mpeg		= SAA7134_MPEG_DVB,
+		.inputs = { {
+			.name	= name_comp1,
+			.vmux	= 0,
+			.amux	= LINE1,
+		}, {
+			.name	= name_svideo,
+			.vmux	= 8, /* Not tested */
+			.amux	= LINE1
+		} },
+	},
+	[SAA7134_BOARD_BEHOLD_X7] = {
+		/* Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> */
+		.name           = "Beholder BeholdTV X7",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_XC5000,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.inputs         = { {
+			.name = name_tv,
+			.vmux = 2,
+			.amux = TV,
+			.tv   = 1,
+		}, {
+			.name = name_comp1,
+			.vmux = 0,
+			.amux = LINE1,
+		}, {
+			.name = name_svideo,
+			.vmux = 9,
+			.amux = LINE1,
+		} },
+		.radio = {
+			.name = name_radio,
+			.amux = TV,
+		},
+	},
+	[SAA7134_BOARD_ZOLID_HYBRID_PCI] = {
+		.name           = "Zolid Hybrid TV Tuner PCI",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.tuner_config   = 0,
+		.mpeg           = SAA7134_MPEG_DVB,
+		.ts_type	= SAA7134_MPEG_TS_PARALLEL,
+		.inputs         = {{
+			.name = name_tv,
+			.vmux = 1,
+			.amux = TV,
+			.tv   = 1,
+		} },
+		.radio = {	/* untested */
+			.name = name_radio,
+			.amux = TV,
+		},
+	},
+
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -5374,6 +5537,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
 		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
+		.subdevice    = 0xa115,
+		.driver_data  = SAA7134_BOARD_AVERMEDIA_STUDIO_505,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
 		.subdevice    = 0x2108,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_305,
 	},{
@@ -6223,7 +6392,30 @@ struct pci_device_id saa7134_pci_tbl[] = {
 		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
 		.subdevice    = 0xf31d,
 		.driver_data  = SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS,
-
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x185b,
+		.subdevice    = 0xc900,
+		.driver_data  = SAA7134_BOARD_VIDEOMATE_S350,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x5ace, /* Beholder Intl. Ltd. */
+		.subdevice    = 0x7595,
+		.driver_data  = SAA7134_BOARD_BEHOLD_X7,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x19d1, /* RoverMedia */
+		.subdevice    = 0x0138, /* LifeView FlyTV Prime30 OEM */
+		.driver_data  = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = PCI_VENDOR_ID_PHILIPS,
+		.subdevice    = 0x2004,
+		.driver_data  = SAA7134_BOARD_ZOLID_HYBRID_PCI,
 	}, {
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
@@ -6310,6 +6502,32 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
 	return -EINVAL;
 }
 
+static int saa7134_xc5000_callback(struct saa7134_dev *dev,
+				   int command, int arg)
+{
+	switch (dev->board) {
+	case SAA7134_BOARD_BEHOLD_X7:
+		if (command == XC5000_TUNER_RESET) {
+		/* Down and UP pheripherial RESET pin for reset all chips */
+			saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
+			msleep(10);
+			saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
+			msleep(10);
+		}
+		break;
+	default:
+		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
+		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
+		saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02);
+		saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81);
+		saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7);
+		saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03);
+		saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2,
+			   0x0001e000, 0x0001e000);
+		break;
+	}
+	return 0;
+}
 
 static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev,
 					 int command, int arg)
@@ -6406,6 +6624,8 @@ int saa7134_tuner_callback(void *priv, int component, int command, int arg)
 			return saa7134_tda8290_callback(dev, command, arg);
 		case TUNER_XC2028:
 			return saa7134_xc2028_callback(dev, command, arg);
+		case TUNER_XC5000:
+			return saa7134_xc5000_callback(dev, command, arg);
 		}
 	} else {
 		printk(KERN_ERR "saa7134: Error - device struct undefined.\n");
@@ -6476,6 +6696,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
 	case SAA7134_BOARD_KWORLD_XPERT:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
+	case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
 	case SAA7134_BOARD_AVERMEDIA_305:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
 	case SAA7134_BOARD_AVERMEDIA_307:
@@ -6500,7 +6721,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_FLYDVBT_LR301:
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
-       case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
+	case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
 	case SAA7134_BOARD_FLYDVBTDUO:
 	case SAA7134_BOARD_PROTEUS_2309:
 	case SAA7134_BOARD_AVERMEDIA_A16AR:
@@ -6525,6 +6746,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_REAL_ANGEL_220:
 	case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
+	case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
 		dev->has_remote = SAA7134_REMOTE_GPIO;
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
@@ -6653,6 +6875,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_BEHOLD_M63:
 	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
 	case SAA7134_BOARD_BEHOLD_H6:
+	case SAA7134_BOARD_BEHOLD_X7:
 		dev->has_remote = SAA7134_REMOTE_I2C;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_A169_B:
@@ -6673,6 +6896,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x80040100, 0x80040100);
 		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
 		break;
+	case SAA7134_BOARD_VIDEOMATE_S350:
+		dev->has_remote = SAA7134_REMOTE_GPIO;
+		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00008000, 0x00008000);
+		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
+		break;
 	}
 	return 0;
 }
@@ -7007,22 +7235,22 @@ int saa7134_board_init2(struct saa7134_dev *dev)
 		if (dev->radio_type != UNSET)
 			v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_adap, "tuner", "tuner",
-				dev->radio_addr);
+				dev->radio_addr, NULL);
 		if (has_demod)
-			v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+			v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+				0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
 		if (dev->tuner_addr == ADDR_UNSET) {
 			enum v4l2_i2c_tuner_type type =
 				has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 
-			v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+			v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_adap, "tuner", "tuner",
-				v4l2_i2c_tuner_addrs(type));
+				0, v4l2_i2c_tuner_addrs(type));
 		} else {
 			v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_adap, "tuner", "tuner",
-				dev->tuner_addr);
+				dev->tuner_addr, NULL);
 		}
 	}
 
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 94a023a..f87757f 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1000,7 +1000,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
 		struct v4l2_subdev *sd =
 			v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
 				"saa6752hs", "saa6752hs",
-				saa7134_boards[dev->board].empress_addr);
+				saa7134_boards[dev->board].empress_addr, NULL);
 
 		if (sd)
 			sd->grp_id = GRP_EMPRESS;
@@ -1009,11 +1009,13 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
 	if (saa7134_boards[dev->board].rds_addr) {
 		struct v4l2_subdev *sd;
 
-		sd = v4l2_i2c_new_probed_subdev_addr(&dev->v4l2_dev,
+		sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
 				&dev->i2c_adap,	"saa6588", "saa6588",
-				saa7134_boards[dev->board].rds_addr);
-		if (sd)
+				0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
+		if (sd) {
 			printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
+			dev->has_rds = 1;
+		}
 	}
 
 	request_submodules(dev);
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 98f3efd..a26e997 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -56,6 +56,7 @@
 #include "zl10353.h"
 
 #include "zl10036.h"
+#include "zl10039.h"
 #include "mt312.h"
 
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -968,6 +969,10 @@ static struct zl10036_config avertv_a700_tuner = {
 	.tuner_address = 0x60,
 };
 
+static struct mt312_config zl10313_compro_s350_config = {
+	.demod_address = 0x0e,
+};
+
 static struct lgdt3305_config hcw_lgdt3305_config = {
 	.i2c_addr           = 0x0e,
 	.mpeg_mode          = LGDT3305_MPEG_SERIAL,
@@ -1002,12 +1007,29 @@ static struct tda18271_config hcw_tda18271_config = {
 	.std_map = &hauppauge_tda18271_std_map,
 	.gate    = TDA18271_GATE_ANALOG,
 	.config  = 3,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
 };
 
 static struct tda829x_config tda829x_no_probe = {
 	.probe_tuner = TDA829X_DONT_PROBE,
 };
 
+static struct tda10048_config zolid_tda10048_config = {
+	.demod_address    = 0x10 >> 1,
+	.output_mode      = TDA10048_PARALLEL_OUTPUT,
+	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
+	.inversion        = TDA10048_INVERSION_ON,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3500,
+	.dtv8_if_freq_khz = TDA10048_IF_4000,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+	.disable_gate_access = 1,
+};
+
+static struct tda18271_config zolid_tda18271_config = {
+	.gate    = TDA18271_GATE_ANALOG,
+};
+
 /* ==================================================================
  * Core code
  */
@@ -1457,7 +1479,7 @@ static int dvb_init(struct saa7134_dev *dev)
 		if (fe0->dvb.frontend) {
 			dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
 				   &dev->i2c_adap, 0x61,
-				   TUNER_PHILIPS_FMD1216ME_MK3);
+				   TUNER_PHILIPS_FMD1216MEX_MK3);
 		}
 		break;
 	case SAA7134_BOARD_AVERMEDIA_A700_PRO:
@@ -1473,6 +1495,29 @@ static int dvb_init(struct saa7134_dev *dev)
 			}
 		}
 		break;
+	case SAA7134_BOARD_VIDEOMATE_S350:
+		fe0->dvb.frontend = dvb_attach(mt312_attach,
+				&zl10313_compro_s350_config, &dev->i2c_adap);
+		if (fe0->dvb.frontend)
+			if (dvb_attach(zl10039_attach, fe0->dvb.frontend,
+					0x60, &dev->i2c_adap) == NULL)
+				wprintk("%s: No zl10039 found!\n",
+					__func__);
+
+		break;
+	case SAA7134_BOARD_ZOLID_HYBRID_PCI:
+		fe0->dvb.frontend = dvb_attach(tda10048_attach,
+					       &zolid_tda10048_config,
+					       &dev->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda829x_attach, fe0->dvb.frontend,
+				   &dev->i2c_adap, 0x4b,
+				   &tda829x_no_probe);
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				   0x60, &dev->i2c_adap,
+				   &zolid_tda18271_config);
+		}
+		break;
 	default:
 		wprintk("Huh? unknown DVB card?\n");
 		break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 6e219c2..a0e8c62 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -251,6 +251,10 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
 	if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir)
 		return 0;
 
+	/* Wrong data decode fix */
+	if (data[9] != (unsigned char)(~data[8]))
+		return 0;
+
 	*ir_key = data[9];
 	*ir_raw = data[9];
 
@@ -394,7 +398,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 {
 	struct card_ir *ir;
 	struct input_dev *input_dev;
-	IR_KEYTAB_TYPE *ir_codes = NULL;
+	struct ir_scancode_table *ir_codes = NULL;
 	u32 mask_keycode = 0;
 	u32 mask_keydown = 0;
 	u32 mask_keyup   = 0;
@@ -415,27 +419,28 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_FLYVIDEO3000:
 	case SAA7134_BOARD_FLYTVPLATINUM_FM:
 	case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
-		ir_codes     = ir_codes_flyvideo;
+	case SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM:
+		ir_codes     = &ir_codes_flyvideo_table;
 		mask_keycode = 0xEC00000;
 		mask_keydown = 0x0040000;
 		break;
 	case SAA7134_BOARD_CINERGY400:
 	case SAA7134_BOARD_CINERGY600:
 	case SAA7134_BOARD_CINERGY600_MK3:
-		ir_codes     = ir_codes_cinergy;
+		ir_codes     = &ir_codes_cinergy_table;
 		mask_keycode = 0x00003f;
 		mask_keyup   = 0x040000;
 		break;
 	case SAA7134_BOARD_ECS_TVP3XP:
 	case SAA7134_BOARD_ECS_TVP3XP_4CB5:
-		ir_codes     = ir_codes_eztv;
+		ir_codes     = &ir_codes_eztv_table;
 		mask_keycode = 0x00017c;
 		mask_keyup   = 0x000002;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_KWORLD_XPERT:
 	case SAA7134_BOARD_AVACSSMARTTV:
-		ir_codes     = ir_codes_pixelview;
+		ir_codes     = &ir_codes_pixelview_table;
 		mask_keycode = 0x00001F;
 		mask_keyup   = 0x000020;
 		polling      = 50; // ms
@@ -445,13 +450,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_AVERMEDIA_305:
 	case SAA7134_BOARD_AVERMEDIA_307:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
+	case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
 	case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
 	case SAA7134_BOARD_AVERMEDIA_M102:
 	case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
-		ir_codes     = ir_codes_avermedia;
+		ir_codes     = &ir_codes_avermedia_table;
 		mask_keycode = 0x0007C8;
 		mask_keydown = 0x000010;
 		polling      = 50; // ms
@@ -460,14 +466,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 		saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
 		break;
 	case SAA7134_BOARD_AVERMEDIA_M135A:
-		ir_codes     = ir_codes_avermedia_m135a;
+		ir_codes     = &ir_codes_avermedia_m135a_table;
 		mask_keydown = 0x0040000;
 		mask_keycode = 0x00013f;
 		nec_gpio     = 1;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_777:
 	case SAA7134_BOARD_AVERMEDIA_A16AR:
-		ir_codes     = ir_codes_avermedia;
+		ir_codes     = &ir_codes_avermedia_table;
 		mask_keycode = 0x02F200;
 		mask_keydown = 0x000400;
 		polling      = 50; // ms
@@ -476,7 +482,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 		saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
 		break;
 	case SAA7134_BOARD_AVERMEDIA_A16D:
-		ir_codes     = ir_codes_avermedia_a16d;
+		ir_codes     = &ir_codes_avermedia_a16d_table;
 		mask_keycode = 0x02F200;
 		mask_keydown = 0x000400;
 		polling      = 50; /* ms */
@@ -485,14 +491,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 		saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
 		break;
 	case SAA7134_BOARD_KWORLD_TERMINATOR:
-		ir_codes     = ir_codes_pixelview;
+		ir_codes     = &ir_codes_pixelview_table;
 		mask_keycode = 0x00001f;
 		mask_keyup   = 0x000060;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_MANLI_MTV001:
 	case SAA7134_BOARD_MANLI_MTV002:
-		ir_codes     = ir_codes_manli;
+		ir_codes     = &ir_codes_manli_table;
 		mask_keycode = 0x001f00;
 		mask_keyup   = 0x004000;
 		polling      = 50; /* ms */
@@ -511,25 +517,25 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_BEHOLD_507_9FM:
 	case SAA7134_BOARD_BEHOLD_507RDS_MK3:
 	case SAA7134_BOARD_BEHOLD_507RDS_MK5:
-		ir_codes     = ir_codes_manli;
+		ir_codes     = &ir_codes_manli_table;
 		mask_keycode = 0x003f00;
 		mask_keyup   = 0x004000;
 		polling      = 50; /* ms */
 		break;
 	case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
-		ir_codes     = ir_codes_behold_columbus;
+		ir_codes     = &ir_codes_behold_columbus_table;
 		mask_keycode = 0x003f00;
 		mask_keyup   = 0x004000;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
-		ir_codes     = ir_codes_pctv_sedna;
+		ir_codes     = &ir_codes_pctv_sedna_table;
 		mask_keycode = 0x001f00;
 		mask_keyup   = 0x004000;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_GOTVIEW_7135:
-		ir_codes     = ir_codes_gotview7135;
+		ir_codes     = &ir_codes_gotview7135_table;
 		mask_keycode = 0x0003CC;
 		mask_keydown = 0x000010;
 		polling	     = 5; /* ms */
@@ -538,73 +544,78 @@ int saa7134_input_init1(struct saa7134_dev *dev)
 	case SAA7134_BOARD_VIDEOMATE_TV_PVR:
 	case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
 	case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
-		ir_codes     = ir_codes_videomate_tv_pvr;
+		ir_codes     = &ir_codes_videomate_tv_pvr_table;
 		mask_keycode = 0x00003F;
 		mask_keyup   = 0x400000;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_PROTEUS_2309:
-		ir_codes     = ir_codes_proteus_2309;
+		ir_codes     = &ir_codes_proteus_2309_table;
 		mask_keycode = 0x00007F;
 		mask_keyup   = 0x000080;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_VIDEOMATE_DVBT_300:
 	case SAA7134_BOARD_VIDEOMATE_DVBT_200:
-		ir_codes     = ir_codes_videomate_tv_pvr;
+		ir_codes     = &ir_codes_videomate_tv_pvr_table;
 		mask_keycode = 0x003F00;
 		mask_keyup   = 0x040000;
 		break;
 	case SAA7134_BOARD_FLYDVBS_LR300:
 	case SAA7134_BOARD_FLYDVBT_LR301:
 	case SAA7134_BOARD_FLYDVBTDUO:
-		ir_codes     = ir_codes_flydvb;
+		ir_codes     = &ir_codes_flydvb_table;
 		mask_keycode = 0x0001F00;
 		mask_keydown = 0x0040000;
 		break;
 	case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
 	case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
-       case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
-		ir_codes     = ir_codes_asus_pc39;
+	case SAA7134_BOARD_ASUSTeK_P7131_ANALOG:
+		ir_codes     = &ir_codes_asus_pc39_table;
 		mask_keydown = 0x0040000;
 		rc5_gpio = 1;
 		break;
 	case SAA7134_BOARD_ENCORE_ENLTV:
 	case SAA7134_BOARD_ENCORE_ENLTV_FM:
-		ir_codes     = ir_codes_encore_enltv;
+		ir_codes     = &ir_codes_encore_enltv_table;
 		mask_keycode = 0x00007f;
 		mask_keyup   = 0x040000;
 		polling      = 50; // ms
 		break;
 	case SAA7134_BOARD_ENCORE_ENLTV_FM53:
-		ir_codes     = ir_codes_encore_enltv_fm53;
+		ir_codes     = &ir_codes_encore_enltv_fm53_table;
 		mask_keydown = 0x0040000;
 		mask_keycode = 0x00007f;
 		nec_gpio = 1;
 		break;
 	case SAA7134_BOARD_10MOONSTVMASTER3:
-		ir_codes     = ir_codes_encore_enltv;
+		ir_codes     = &ir_codes_encore_enltv_table;
 		mask_keycode = 0x5f80000;
 		mask_keyup   = 0x8000000;
 		polling      = 50; //ms
 		break;
 	case SAA7134_BOARD_GENIUS_TVGO_A11MCE:
-		ir_codes     = ir_codes_genius_tvgo_a11mce;
+		ir_codes     = &ir_codes_genius_tvgo_a11mce_table;
 		mask_keycode = 0xff;
 		mask_keydown = 0xf00000;
 		polling = 50; /* ms */
 		break;
 	case SAA7134_BOARD_REAL_ANGEL_220:
-		ir_codes     = ir_codes_real_audio_220_32_keys;
+		ir_codes     = &ir_codes_real_audio_220_32_keys_table;
 		mask_keycode = 0x3f00;
 		mask_keyup   = 0x4000;
 		polling = 50; /* ms */
 		break;
 	case SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG:
-		ir_codes     = ir_codes_kworld_plus_tv_analog;
+		ir_codes     = &ir_codes_kworld_plus_tv_analog_table;
 		mask_keycode = 0x7f;
 		polling = 40; /* ms */
 		break;
+	case SAA7134_BOARD_VIDEOMATE_S350:
+		ir_codes     = &ir_codes_videomate_s350_table;
+		mask_keycode = 0x003f00;
+		mask_keydown = 0x040000;
+		break;
 	}
 	if (NULL == ir_codes) {
 		printk("%s: Oops: IR config error [card=%d]\n",
@@ -684,8 +695,6 @@ void saa7134_input_fini(struct saa7134_dev *dev)
 
 void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 {
-	struct i2c_board_info info;
-	struct IR_i2c_init_data init_data;
 	const unsigned short addr_list[] = {
 		0x7a, 0x47, 0x71, 0x2d,
 		I2C_CLIENT_END
@@ -705,32 +714,34 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 		return;
 	}
 
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
-	strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+	memset(&dev->info, 0, sizeof(dev->info));
+	memset(&dev->init_data, 0, sizeof(dev->init_data));
+	strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
 
 	switch (dev->board) {
 	case SAA7134_BOARD_PINNACLE_PCTV_110i:
 	case SAA7134_BOARD_PINNACLE_PCTV_310i:
-		init_data.name = "Pinnacle PCTV";
+		dev->init_data.name = "Pinnacle PCTV";
 		if (pinnacle_remote == 0) {
-			init_data.get_key = get_key_pinnacle_color;
-			init_data.ir_codes = ir_codes_pinnacle_color;
+			dev->init_data.get_key = get_key_pinnacle_color;
+			dev->init_data.ir_codes = &ir_codes_pinnacle_color_table;
+			dev->info.addr = 0x47;
 		} else {
-			init_data.get_key = get_key_pinnacle_grey;
-			init_data.ir_codes = ir_codes_pinnacle_grey;
+			dev->init_data.get_key = get_key_pinnacle_grey;
+			dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
+			dev->info.addr = 0x47;
 		}
 		break;
 	case SAA7134_BOARD_UPMOST_PURPLE_TV:
-		init_data.name = "Purple TV";
-		init_data.get_key = get_key_purpletv;
-		init_data.ir_codes = ir_codes_purpletv;
+		dev->init_data.name = "Purple TV";
+		dev->init_data.get_key = get_key_purpletv;
+		dev->init_data.ir_codes = &ir_codes_purpletv_table;
 		break;
 	case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
-		init_data.name = "MSI TV@nywhere Plus";
-		init_data.get_key = get_key_msi_tvanywhere_plus;
-		init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
-		info.addr = 0x30;
+		dev->init_data.name = "MSI TV@nywhere Plus";
+		dev->init_data.get_key = get_key_msi_tvanywhere_plus;
+		dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table;
+		dev->info.addr = 0x30;
 		/* MSI TV@nywhere Plus controller doesn't seem to
 		   respond to probes unless we read something from
 		   an existing device. Weird...
@@ -741,9 +752,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 			(1 == rc) ? "yes" : "no");
 		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1110:
-		init_data.name = "HVR 1110";
-		init_data.get_key = get_key_hvr1110;
-		init_data.ir_codes = ir_codes_hauppauge_new;
+		dev->init_data.name = "HVR 1110";
+		dev->init_data.get_key = get_key_hvr1110;
+		dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
 		break;
 	case SAA7134_BOARD_BEHOLD_607FM_MK3:
 	case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -757,26 +768,27 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
 	case SAA7134_BOARD_BEHOLD_M63:
 	case SAA7134_BOARD_BEHOLD_M6_EXTRA:
 	case SAA7134_BOARD_BEHOLD_H6:
-		init_data.name = "BeholdTV";
-		init_data.get_key = get_key_beholdm6xx;
-		init_data.ir_codes = ir_codes_behold;
+	case SAA7134_BOARD_BEHOLD_X7:
+		dev->init_data.name = "BeholdTV";
+		dev->init_data.get_key = get_key_beholdm6xx;
+		dev->init_data.ir_codes = &ir_codes_behold_table;
 		break;
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
 	case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
-		info.addr = 0x40;
+		dev->info.addr = 0x40;
 		break;
 	}
 
-	if (init_data.name)
-		info.platform_data = &init_data;
+	if (dev->init_data.name)
+		dev->info.platform_data = &dev->init_data;
 	/* No need to probe if address is known */
-	if (info.addr) {
-		i2c_new_device(&dev->i2c_adap, &info);
+	if (dev->info.addr) {
+		i2c_new_device(&dev->i2c_adap, &dev->info);
 		return;
 	}
 
 	/* Address not known, fallback to probing */
-	i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+	i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
 }
 
 static int saa7134_rc5_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index ba87128..da26f47 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1444,7 +1444,6 @@ video_poll(struct file *file, struct poll_table_struct *wait)
 			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
 			fh->cap.read_off = 0;
 		}
-		mutex_unlock(&fh->cap.vb_lock);
 		buf = fh->cap.read_buf;
 	}
 
@@ -1790,7 +1789,7 @@ static int saa7134_s_input(struct file *file, void *priv, unsigned int i)
 	if (0 != err)
 		return err;
 
-	if (i < 0  ||  i >= SAA7134_INPUT_MAX)
+	if (i >= SAA7134_INPUT_MAX)
 		return -EINVAL;
 	if (NULL == card_in(dev, i).name)
 		return -EINVAL;
@@ -1819,6 +1818,8 @@ static int saa7134_querycap(struct file *file, void  *priv,
 		V4L2_CAP_READWRITE |
 		V4L2_CAP_STREAMING |
 		V4L2_CAP_TUNER;
+	if (dev->has_rds)
+		cap->capabilities |= V4L2_CAP_RDS_CAPTURE;
 	if (saa7134_no_overlay <= 0)
 		cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
 
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index fb564f1..6ee3e9b 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -292,6 +292,11 @@ struct saa7134_format {
 #define SAA7134_BOARD_BEHOLD_607RDS_MK5     166
 #define SAA7134_BOARD_BEHOLD_609RDS_MK3     167
 #define SAA7134_BOARD_BEHOLD_609RDS_MK5     168
+#define SAA7134_BOARD_VIDEOMATE_S350        169
+#define SAA7134_BOARD_AVERMEDIA_STUDIO_505  170
+#define SAA7134_BOARD_BEHOLD_X7             171
+#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
+#define SAA7134_BOARD_ZOLID_HYBRID_PCI		173
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
@@ -539,6 +544,7 @@ struct saa7134_dev {
 	struct i2c_adapter         i2c_adap;
 	struct i2c_client          i2c_client;
 	unsigned char              eedata[256];
+	int 			   has_rds;
 
 	/* video overlay */
 	struct v4l2_framebuffer    ovbuf;
@@ -584,6 +590,10 @@ struct saa7134_dev {
 	int                        nosignal;
 	unsigned int               insuspend;
 
+	/* I2C keyboard data */
+	struct i2c_board_info      info;
+	struct IR_i2c_init_data    init_data;
+
 	/* SAA7134_MPEG_* */
 	struct saa7134_ts          ts;
 	struct saa7134_dmaqueue    ts_q;
diff --git a/drivers/media/video/saa7164/Kconfig b/drivers/media/video/saa7164/Kconfig
new file mode 100644
index 0000000..3532637
--- /dev/null
+++ b/drivers/media/video/saa7164/Kconfig
@@ -0,0 +1,18 @@
+config VIDEO_SAA7164
+	tristate "NXP SAA7164 support"
+	depends on DVB_CORE && PCI && I2C
+	select I2C_ALGOBIT
+	select FW_LOADER
+	select VIDEO_TUNER
+	select VIDEO_TVEEPROM
+	select VIDEOBUF_DVB
+	select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+	select DVB_S5H1411 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+	---help---
+	  This is a video4linux driver for NXP SAA7164 based
+	  TV cards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa7164
+
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile
new file mode 100644
index 0000000..4b329fd
--- /dev/null
+++ b/drivers/media/video/saa7164/Makefile
@@ -0,0 +1,12 @@
+saa7164-objs	:= saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
+			saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
+			saa7164-buffer.o
+
+obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+EXTRA_CFLAGS += -Idrivers/media/common/tuners
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
new file mode 100644
index 0000000..bb6df1b
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -0,0 +1,600 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include <linux/wait.h>
+
+#include "saa7164.h"
+
+int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode)
+{
+	int ret;
+
+	ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
+		SAA_STATE_CONTROL, sizeof(mode), &mode);
+	if (ret != SAA_OK)
+		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+
+	return ret;
+}
+
+int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
+{
+	int ret;
+
+	ret = saa7164_cmd_send(dev, 0, GET_CUR,
+		GET_FW_VERSION_CONTROL, sizeof(u32), version);
+	if (ret != SAA_OK)
+		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+
+	return ret;
+}
+
+int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
+{
+	u8 reg[] = { 0x0f, 0x00 };
+
+	if (buflen < 128)
+		return -ENOMEM;
+
+	/* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
+	/* TODO: Pull the details from the boards struct */
+	return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
+		&reg[0], 128, buf);
+}
+
+
+int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
+	struct saa7164_tsport *port,
+	tmComResTSFormatDescrHeader_t *tsfmt)
+{
+	dprintk(DBGLVL_API, "    bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
+	dprintk(DBGLVL_API, "    bDataOffset  = 0x%x\n", tsfmt->bDataOffset);
+	dprintk(DBGLVL_API, "    bPacketLength= 0x%x\n", tsfmt->bPacketLength);
+	dprintk(DBGLVL_API, "    bStrideLength= 0x%x\n", tsfmt->bStrideLength);
+	dprintk(DBGLVL_API, "    bguid        = (....)\n");
+
+	/* Cache the hardware configuration in the port */
+
+	port->bufcounter = port->hwcfg.BARLocation;
+	port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
+	port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
+	port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
+	port->bufptr32l = port->hwcfg.BARLocation +
+		(4 * sizeof(u32)) +
+		(sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
+	port->bufptr32h = port->hwcfg.BARLocation +
+		(4 * sizeof(u32)) +
+		(sizeof(u32) * port->hwcfg.buffercount);
+	port->bufptr64 = port->hwcfg.BARLocation +
+		(4 * sizeof(u32)) +
+		(sizeof(u32) * port->hwcfg.buffercount);
+	dprintk(DBGLVL_API, "   = port->hwcfg.BARLocation = 0x%x\n",
+		port->hwcfg.BARLocation);
+
+	dprintk(DBGLVL_API, "   = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
+		port->nr);
+
+	return 0;
+}
+
+int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
+{
+	struct saa7164_tsport *port = 0;
+	u32 idx, next_offset;
+	int i;
+	tmComResDescrHeader_t *hdr, *t;
+	tmComResExtDevDescrHeader_t *exthdr;
+	tmComResPathDescrHeader_t *pathhdr;
+	tmComResAntTermDescrHeader_t *anttermhdr;
+	tmComResTunerDescrHeader_t *tunerunithdr;
+	tmComResDMATermDescrHeader_t *vcoutputtermhdr;
+	tmComResTSFormatDescrHeader_t *tsfmt;
+	u32 currpath = 0;
+
+	dprintk(DBGLVL_API,
+		"%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
+		__func__, len, (u32)sizeof(tmComResDescrHeader_t));
+
+	for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
+
+		hdr = (tmComResDescrHeader_t *)(buf + idx);
+
+		if (hdr->type != CS_INTERFACE)
+			return SAA_ERR_NOT_SUPPORTED;
+
+		dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
+		switch (hdr->subtype) {
+		case GENERAL_REQUEST:
+			dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
+			break;
+		case VC_TUNER_PATH:
+			dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
+			pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
+			dprintk(DBGLVL_API, "  pathid = 0x%x\n",
+				pathhdr->pathid);
+			currpath = pathhdr->pathid;
+			break;
+		case VC_INPUT_TERMINAL:
+			dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
+			anttermhdr =
+				(tmComResAntTermDescrHeader_t *)(buf + idx);
+			dprintk(DBGLVL_API, "  terminalid   = 0x%x\n",
+				anttermhdr->terminalid);
+			dprintk(DBGLVL_API, "  terminaltype = 0x%x\n",
+				anttermhdr->terminaltype);
+			switch (anttermhdr->terminaltype) {
+			case ITT_ANTENNA:
+				dprintk(DBGLVL_API, "   = ITT_ANTENNA\n");
+				break;
+			case LINE_CONNECTOR:
+				dprintk(DBGLVL_API, "   = LINE_CONNECTOR\n");
+				break;
+			case SPDIF_CONNECTOR:
+				dprintk(DBGLVL_API, "   = SPDIF_CONNECTOR\n");
+				break;
+			case COMPOSITE_CONNECTOR:
+				dprintk(DBGLVL_API,
+					"   = COMPOSITE_CONNECTOR\n");
+				break;
+			case SVIDEO_CONNECTOR:
+				dprintk(DBGLVL_API, "   = SVIDEO_CONNECTOR\n");
+				break;
+			case COMPONENT_CONNECTOR:
+				dprintk(DBGLVL_API,
+					"   = COMPONENT_CONNECTOR\n");
+				break;
+			case STANDARD_DMA:
+				dprintk(DBGLVL_API, "   = STANDARD_DMA\n");
+				break;
+			default:
+				dprintk(DBGLVL_API, "   = undefined (0x%x)\n",
+					anttermhdr->terminaltype);
+			}
+			dprintk(DBGLVL_API, "  assocterminal= 0x%x\n",
+				anttermhdr->assocterminal);
+			dprintk(DBGLVL_API, "  iterminal    = 0x%x\n",
+				anttermhdr->iterminal);
+			dprintk(DBGLVL_API, "  controlsize  = 0x%x\n",
+				anttermhdr->controlsize);
+			break;
+		case VC_OUTPUT_TERMINAL:
+			dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
+			vcoutputtermhdr =
+				(tmComResDMATermDescrHeader_t *)(buf + idx);
+			dprintk(DBGLVL_API, "  unitid = 0x%x\n",
+				vcoutputtermhdr->unitid);
+			dprintk(DBGLVL_API, "  terminaltype = 0x%x\n",
+				vcoutputtermhdr->terminaltype);
+			switch (vcoutputtermhdr->terminaltype) {
+			case ITT_ANTENNA:
+				dprintk(DBGLVL_API, "   = ITT_ANTENNA\n");
+				break;
+			case LINE_CONNECTOR:
+				dprintk(DBGLVL_API, "   = LINE_CONNECTOR\n");
+				break;
+			case SPDIF_CONNECTOR:
+				dprintk(DBGLVL_API, "   = SPDIF_CONNECTOR\n");
+				break;
+			case COMPOSITE_CONNECTOR:
+				dprintk(DBGLVL_API,
+					"   = COMPOSITE_CONNECTOR\n");
+				break;
+			case SVIDEO_CONNECTOR:
+				dprintk(DBGLVL_API, "   = SVIDEO_CONNECTOR\n");
+				break;
+			case COMPONENT_CONNECTOR:
+				dprintk(DBGLVL_API,
+					"   = COMPONENT_CONNECTOR\n");
+				break;
+			case STANDARD_DMA:
+				dprintk(DBGLVL_API, "   = STANDARD_DMA\n");
+				break;
+			default:
+				dprintk(DBGLVL_API, "   = undefined (0x%x)\n",
+					vcoutputtermhdr->terminaltype);
+			}
+			dprintk(DBGLVL_API, "  assocterminal= 0x%x\n",
+				vcoutputtermhdr->assocterminal);
+			dprintk(DBGLVL_API, "  sourceid     = 0x%x\n",
+				vcoutputtermhdr->sourceid);
+			dprintk(DBGLVL_API, "  iterminal    = 0x%x\n",
+				vcoutputtermhdr->iterminal);
+			dprintk(DBGLVL_API, "  BARLocation  = 0x%x\n",
+				vcoutputtermhdr->BARLocation);
+			dprintk(DBGLVL_API, "  flags        = 0x%x\n",
+				vcoutputtermhdr->flags);
+			dprintk(DBGLVL_API, "  interruptid  = 0x%x\n",
+				vcoutputtermhdr->interruptid);
+			dprintk(DBGLVL_API, "  buffercount  = 0x%x\n",
+				vcoutputtermhdr->buffercount);
+			dprintk(DBGLVL_API, "  metadatasize = 0x%x\n",
+				vcoutputtermhdr->metadatasize);
+			dprintk(DBGLVL_API, "  controlsize  = 0x%x\n",
+				vcoutputtermhdr->controlsize);
+			dprintk(DBGLVL_API, "  numformats   = 0x%x\n",
+				vcoutputtermhdr->numformats);
+
+			t = (tmComResDescrHeader_t *)
+				((tmComResDMATermDescrHeader_t *)(buf + idx));
+			next_offset = idx + (vcoutputtermhdr->len);
+			for (i = 0; i < vcoutputtermhdr->numformats; i++) {
+				t = (tmComResDescrHeader_t *)
+					(buf + next_offset);
+				switch (t->subtype) {
+				case VS_FORMAT_MPEG2TS:
+					tsfmt =
+					(tmComResTSFormatDescrHeader_t *)t;
+					if (currpath == 1)
+						port = &dev->ts1;
+					else
+						port = &dev->ts2;
+					memcpy(&port->hwcfg, vcoutputtermhdr,
+						sizeof(*vcoutputtermhdr));
+					saa7164_api_configure_port_mpeg2ts(dev,
+						port, tsfmt);
+					break;
+				case VS_FORMAT_MPEG2PS:
+					dprintk(DBGLVL_API,
+						"   = VS_FORMAT_MPEG2PS\n");
+					break;
+				case VS_FORMAT_VBI:
+					dprintk(DBGLVL_API,
+						"   = VS_FORMAT_VBI\n");
+					break;
+				case VS_FORMAT_RDS:
+					dprintk(DBGLVL_API,
+						"   = VS_FORMAT_RDS\n");
+					break;
+				case VS_FORMAT_UNCOMPRESSED:
+					dprintk(DBGLVL_API,
+					"   = VS_FORMAT_UNCOMPRESSED\n");
+					break;
+				case VS_FORMAT_TYPE:
+					dprintk(DBGLVL_API,
+						"   = VS_FORMAT_TYPE\n");
+					break;
+				default:
+					dprintk(DBGLVL_API,
+						"   = undefined (0x%x)\n",
+						t->subtype);
+				}
+				next_offset += t->len;
+			}
+
+			break;
+		case TUNER_UNIT:
+			dprintk(DBGLVL_API, " TUNER_UNIT\n");
+			tunerunithdr =
+				(tmComResTunerDescrHeader_t *)(buf + idx);
+			dprintk(DBGLVL_API, "  unitid = 0x%x\n",
+				tunerunithdr->unitid);
+			dprintk(DBGLVL_API, "  sourceid = 0x%x\n",
+				tunerunithdr->sourceid);
+			dprintk(DBGLVL_API, "  iunit = 0x%x\n",
+				tunerunithdr->iunit);
+			dprintk(DBGLVL_API, "  tuningstandards = 0x%x\n",
+				tunerunithdr->tuningstandards);
+			dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
+				tunerunithdr->controlsize);
+			dprintk(DBGLVL_API, "  controls = 0x%x\n",
+				tunerunithdr->controls);
+			break;
+		case VC_SELECTOR_UNIT:
+			dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
+			break;
+		case VC_PROCESSING_UNIT:
+			dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
+			break;
+		case FEATURE_UNIT:
+			dprintk(DBGLVL_API, " FEATURE_UNIT\n");
+			break;
+		case ENCODER_UNIT:
+			dprintk(DBGLVL_API, " ENCODER_UNIT\n");
+			break;
+		case EXTENSION_UNIT:
+			dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
+			exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
+			dprintk(DBGLVL_API, "  unitid = 0x%x\n",
+				exthdr->unitid);
+			dprintk(DBGLVL_API, "  deviceid = 0x%x\n",
+				exthdr->deviceid);
+			dprintk(DBGLVL_API, "  devicetype = 0x%x\n",
+				exthdr->devicetype);
+			if (exthdr->devicetype & 0x1)
+				dprintk(DBGLVL_API, "   = Decoder Device\n");
+			if (exthdr->devicetype & 0x2)
+				dprintk(DBGLVL_API, "   = GPIO Source\n");
+			if (exthdr->devicetype & 0x4)
+				dprintk(DBGLVL_API, "   = Video Decoder\n");
+			if (exthdr->devicetype & 0x8)
+				dprintk(DBGLVL_API, "   = Audio Decoder\n");
+			if (exthdr->devicetype & 0x20)
+				dprintk(DBGLVL_API, "   = Crossbar\n");
+			if (exthdr->devicetype & 0x40)
+				dprintk(DBGLVL_API, "   = Tuner\n");
+			if (exthdr->devicetype & 0x80)
+				dprintk(DBGLVL_API, "   = IF PLL\n");
+			if (exthdr->devicetype & 0x100)
+				dprintk(DBGLVL_API, "   = Demodulator\n");
+			if (exthdr->devicetype & 0x200)
+				dprintk(DBGLVL_API, "   = RDS Decoder\n");
+			if (exthdr->devicetype & 0x400)
+				dprintk(DBGLVL_API, "   = Encoder\n");
+			if (exthdr->devicetype & 0x800)
+				dprintk(DBGLVL_API, "   = IR Decoder\n");
+			if (exthdr->devicetype & 0x1000)
+				dprintk(DBGLVL_API, "   = EEPROM\n");
+			if (exthdr->devicetype & 0x2000)
+				dprintk(DBGLVL_API,
+					"   = VBI Decoder\n");
+			if (exthdr->devicetype & 0x10000)
+				dprintk(DBGLVL_API,
+					"   = Streaming Device\n");
+			if (exthdr->devicetype & 0x20000)
+				dprintk(DBGLVL_API,
+					"   = DRM Device\n");
+			if (exthdr->devicetype & 0x40000000)
+				dprintk(DBGLVL_API,
+					"   = Generic Device\n");
+			if (exthdr->devicetype & 0x80000000)
+				dprintk(DBGLVL_API,
+					"   = Config Space Device\n");
+			dprintk(DBGLVL_API, "  numgpiopins = 0x%x\n",
+				exthdr->numgpiopins);
+			dprintk(DBGLVL_API, "  numgpiogroups = 0x%x\n",
+				exthdr->numgpiogroups);
+			dprintk(DBGLVL_API, "  controlsize = 0x%x\n",
+				exthdr->controlsize);
+			break;
+		case PVC_INFRARED_UNIT:
+			dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
+			break;
+		case DRM_UNIT:
+			dprintk(DBGLVL_API, " DRM_UNIT\n");
+			break;
+		default:
+			dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
+		}
+
+		dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
+		dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
+		dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
+		dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
+
+		idx += hdr->len;
+	}
+
+	return 0;
+}
+
+int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
+{
+	int ret;
+	u32 buflen = 0;
+	u8 *buf;
+
+	dprintk(DBGLVL_API, "%s()\n", __func__);
+
+	/* Get the total descriptor length */
+	ret = saa7164_cmd_send(dev, 0, GET_LEN,
+		GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
+	if (ret != SAA_OK)
+		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+
+	dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
+		__func__, buflen);
+
+	/* Allocate enough storage for all of the descs */
+	buf = kzalloc(buflen, GFP_KERNEL);
+	if (buf == NULL)
+		return SAA_ERR_NO_RESOURCES;
+
+	/* Retrieve them */
+	ret = saa7164_cmd_send(dev, 0, GET_CUR,
+		GET_DESCRIPTORS_CONTROL, buflen, buf);
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
+		goto out;
+	}
+
+	if (debug & DBGLVL_API)
+		saa7164_dumphex16(dev, buf, (buflen/16)*16);
+
+	saa7164_api_dump_subdevs(dev, buf, buflen);
+
+out:
+	kfree(buf);
+	return ret;
+}
+
+int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
+	u32 datalen, u8 *data)
+{
+	struct saa7164_dev *dev = bus->dev;
+	u16 len = 0;
+	int unitid;
+	u32 regval;
+	u8 buf[256];
+	int ret;
+
+	dprintk(DBGLVL_API, "%s()\n", __func__);
+
+	if (reglen > 4)
+		return -EIO;
+
+	if (reglen == 1)
+		regval = *(reg);
+	else
+	if (reglen == 2)
+		regval = ((*(reg) << 8) || *(reg+1));
+	else
+	if (reglen == 3)
+		regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
+	else
+	if (reglen == 4)
+		regval = ((*(reg) << 24) | (*(reg+1) << 16) |
+			(*(reg+2) << 8) | *(reg+3));
+
+	/* Prepare the send buffer */
+	/* Bytes 00-03 source register length
+	 *       04-07 source bytes to read
+	 *       08... register address
+	 */
+	memset(buf, 0, sizeof(buf));
+	memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
+	*((u32 *)(buf + 0 * sizeof(u32))) = reglen;
+	*((u32 *)(buf + 1 * sizeof(u32))) = datalen;
+
+	unitid = saa7164_i2caddr_to_unitid(bus, addr);
+	if (unitid < 0) {
+		printk(KERN_ERR
+			"%s() error, cannot translate regaddr 0x%x to unitid\n",
+			__func__, addr);
+		return -EIO;
+	}
+
+	ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
+		EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
+		return -EIO;
+	}
+
+	dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
+
+	if (debug & DBGLVL_I2C)
+		saa7164_dumphex16(dev, buf, 2 * 16);
+
+	ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
+		EXU_REGISTER_ACCESS_CONTROL, len, &buf);
+	if (ret != SAA_OK)
+		printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
+	else {
+		if (debug & DBGLVL_I2C)
+			saa7164_dumphex16(dev, buf, sizeof(buf));
+		memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
+	}
+
+	return ret == SAA_OK ? 0 : -EIO;
+}
+
+/* For a given 8 bit i2c address device, write the buffer */
+int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
+	u8 *data)
+{
+	struct saa7164_dev *dev = bus->dev;
+	u16 len = 0;
+	int unitid;
+	int reglen;
+	u8 buf[256];
+	int ret;
+
+	dprintk(DBGLVL_API, "%s()\n", __func__);
+
+	if ((datalen == 0) || (datalen > 232))
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	unitid = saa7164_i2caddr_to_unitid(bus, addr);
+	if (unitid < 0) {
+		printk(KERN_ERR
+			"%s() error, cannot translate regaddr 0x%x to unitid\n",
+			__func__, addr);
+		return -EIO;
+	}
+
+	reglen = saa7164_i2caddr_to_reglen(bus, addr);
+	if (unitid < 0) {
+		printk(KERN_ERR
+			"%s() error, cannot translate regaddr to reglen\n",
+			__func__);
+		return -EIO;
+	}
+
+	ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
+		EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
+		return -EIO;
+	}
+
+	dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
+
+	/* Prepare the send buffer */
+	/* Bytes 00-03 dest register length
+	 *       04-07 dest bytes to write
+	 *       08... register address
+	 */
+	*((u32 *)(buf + 0 * sizeof(u32))) = reglen;
+	*((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
+	memcpy((buf + 2 * sizeof(u32)), data, datalen);
+
+	if (debug & DBGLVL_I2C)
+		saa7164_dumphex16(dev, buf, sizeof(buf));
+
+	ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
+		EXU_REGISTER_ACCESS_CONTROL, len, &buf);
+	if (ret != SAA_OK)
+		printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
+
+	return ret == SAA_OK ? 0 : -EIO;
+}
+
+
+int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
+	u8 pin, u8 state)
+{
+	int ret;
+	tmComResGPIO_t t;
+
+	dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
+		__func__, unitid, pin, state);
+
+	if ((pin > 7) || (state > 2))
+		return SAA_ERR_BAD_PARAMETER;
+
+	t.pin = pin;
+	t.state = state;
+
+	ret = saa7164_cmd_send(dev, unitid, SET_CUR,
+		EXU_GPIO_CONTROL, sizeof(t), &t);
+	if (ret != SAA_OK)
+		printk(KERN_ERR "%s() error, ret = 0x%x\n",
+			__func__, ret);
+
+	return ret;
+}
+
+int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
+	u8 pin)
+{
+	return saa7164_api_modify_gpio(dev, unitid, pin, 1);
+}
+
+int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
+	u8 pin)
+{
+	return saa7164_api_modify_gpio(dev, unitid, pin, 0);
+}
+
+
+
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
new file mode 100644
index 0000000..9ca5c83
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -0,0 +1,155 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include "saa7164.h"
+
+/* The PCI address space for buffer handling looks like this:
+
+ +-u32 wide-------------+
+ |                      +
+ +-u64 wide------------------------------------+
+ +                                             +
+ +----------------------+
+ | CurrentBufferPtr     + Pointer to current PCI buffer >-+
+ +----------------------+                                 |
+ | Unused               +                                 |
+ +----------------------+                                 |
+ | Pitch                + = 188 (bytes)                   |
+ +----------------------+                                 |
+ | PCI buffer size      + = pitch * number of lines (312) |
+ +----------------------+                                 |
+ |0| Buf0 Write Offset  +                                 |
+ +----------------------+                                 v
+ |1| Buf1 Write Offset  +                                 |
+ +----------------------+                                 |
+ |2| Buf2 Write Offset  +                                 |
+ +----------------------+                                 |
+ |3| Buf3 Write Offset  +                                 |
+ +----------------------+                                 |
+ ... More write offsets                                   |
+ +---------------------------------------------+          |
+ +0| set of ptrs to PCI pagetables             +          |
+ +---------------------------------------------+          |
+ +1| set of ptrs to PCI pagetables             + <--------+
+ +---------------------------------------------+
+ +2| set of ptrs to PCI pagetables             +
+ +---------------------------------------------+
+ +3| set of ptrs to PCI pagetables             + >--+
+ +---------------------------------------------+    |
+ ... More buffer pointers                           |  +----------------+
+						    +->| pt[0] TS data  |
+						    |  +----------------+
+						    |
+						    |  +----------------+
+						    +->| pt[1] TS data  |
+						    |  +----------------+
+						    | etc
+ */
+
+/* Allocate a new buffer structure and associated PCI space in bytes.
+ * len must be a multiple of sizeof(u64)
+ */
+struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
+	u32 len)
+{
+	struct saa7164_buffer *buf = 0;
+	struct saa7164_dev *dev = port->dev;
+	int i;
+
+	if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
+		log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
+		goto ret;
+	}
+
+	buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
+	if (buf == NULL) {
+		log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
+		goto ret;
+	}
+
+	buf->port = port;
+	buf->flags = SAA7164_BUFFER_FREE;
+	/* TODO: arg len is being ignored */
+	buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
+	buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
+
+	/* Allocate contiguous memory */
+	buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size,
+		&buf->dma);
+	if (!buf->cpu)
+		goto fail1;
+
+	buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size,
+		&buf->pt_dma);
+	if (!buf->pt_cpu)
+		goto fail2;
+
+	/* init the buffers to a known pattern, easier during debugging */
+	memset(buf->cpu, 0xff, buf->pci_size);
+	memset(buf->pt_cpu, 0xff, buf->pt_size);
+
+	dprintk(DBGLVL_BUF, "%s()   allocated buffer @ 0x%p\n", __func__, buf);
+	dprintk(DBGLVL_BUF, "  pci_cpu @ 0x%p    dma @ 0x%08lx len = 0x%x\n",
+		buf->cpu, (long)buf->dma, buf->pci_size);
+	dprintk(DBGLVL_BUF, "   pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
+		buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
+
+	/* Format the Page Table Entries to point into the data buffer */
+	for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
+
+		*(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
+
+	}
+
+	goto ret;
+
+fail2:
+	pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
+fail1:
+	kfree(buf);
+
+	buf = 0;
+ret:
+	return buf;
+}
+
+int saa7164_buffer_dealloc(struct saa7164_tsport *port,
+	struct saa7164_buffer *buf)
+{
+	struct saa7164_dev *dev = port->dev;
+
+	if ((buf == 0) || (port == 0))
+		return SAA_ERR_BAD_PARAMETER;
+
+	dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
+
+	if (buf->flags != SAA7164_BUFFER_FREE)
+		log_warn(" freeing a non-free buffer\n");
+
+	pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
+	pci_free_consistent(port->dev->pci, buf->pt_size, buf->pt_cpu,
+		buf->pt_dma);
+
+	kfree(buf);
+
+	return SAA_OK;
+}
+
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
new file mode 100644
index 0000000..83a0464
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -0,0 +1,448 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include "saa7164.h"
+
+/* The message bus to/from the firmware is a ring buffer in PCI address
+ * space. Establish the defaults.
+ */
+int saa7164_bus_setup(struct saa7164_dev *dev)
+{
+	tmComResBusInfo_t *b	= &dev->bus;
+
+	mutex_init(&b->lock);
+
+	b->Type			= TYPE_BUS_PCIe;
+	b->m_wMaxReqSize	= SAA_DEVICE_MAXREQUESTSIZE;
+
+	b->m_pdwSetRing		= (u8 *)(dev->bmmio +
+		((u32)dev->busdesc.CommandRing));
+
+	b->m_dwSizeSetRing	= SAA_DEVICE_BUFFERBLOCKSIZE;
+
+	b->m_pdwGetRing		= (u8 *)(dev->bmmio +
+		((u32)dev->busdesc.ResponseRing));
+
+	b->m_dwSizeGetRing	= SAA_DEVICE_BUFFERBLOCKSIZE;
+
+	b->m_pdwSetWritePos	= (u32 *)((u8 *)(dev->bmmio +
+		((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64))));
+
+	b->m_pdwSetReadPos	= (u32 *)((u8 *)b->m_pdwSetWritePos +
+		1 * sizeof(u32));
+
+	b->m_pdwGetWritePos	= (u32 *)((u8 *)b->m_pdwSetWritePos +
+		2 * sizeof(u32));
+
+	b->m_pdwGetReadPos	= (u32 *)((u8 *)b->m_pdwSetWritePos +
+		3 * sizeof(u32));
+
+	return 0;
+}
+
+void saa7164_bus_dump(struct saa7164_dev *dev)
+{
+	tmComResBusInfo_t *b = &dev->bus;
+
+	dprintk(DBGLVL_BUS, "Dumping the bus structure:\n");
+	dprintk(DBGLVL_BUS, " .type             = %d\n", b->Type);
+	dprintk(DBGLVL_BUS, " .dev->bmmio       = 0x%p\n", dev->bmmio);
+	dprintk(DBGLVL_BUS, " .m_wMaxReqSize    = 0x%x\n", b->m_wMaxReqSize);
+	dprintk(DBGLVL_BUS, " .m_pdwSetRing     = 0x%p\n", b->m_pdwSetRing);
+	dprintk(DBGLVL_BUS, " .m_dwSizeSetRing  = 0x%x\n", b->m_dwSizeSetRing);
+	dprintk(DBGLVL_BUS, " .m_pdwGetRing     = 0x%p\n", b->m_pdwGetRing);
+	dprintk(DBGLVL_BUS, " .m_dwSizeGetRing  = 0x%x\n", b->m_dwSizeGetRing);
+
+	dprintk(DBGLVL_BUS, " .m_pdwSetWritePos = 0x%p (0x%08x)\n",
+		b->m_pdwSetWritePos, *b->m_pdwSetWritePos);
+
+	dprintk(DBGLVL_BUS, " .m_pdwSetReadPos  = 0x%p (0x%08x)\n",
+		b->m_pdwSetReadPos, *b->m_pdwSetReadPos);
+
+	dprintk(DBGLVL_BUS, " .m_pdwGetWritePos = 0x%p (0x%08x)\n",
+		b->m_pdwGetWritePos, *b->m_pdwGetWritePos);
+
+	dprintk(DBGLVL_BUS, " .m_pdwGetReadPos  = 0x%p (0x%08x)\n",
+		b->m_pdwGetReadPos, *b->m_pdwGetReadPos);
+}
+
+void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf)
+{
+	dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
+	dprintk(DBGLVL_BUS, " .id               = %d\n",   m->id);
+	dprintk(DBGLVL_BUS, " .flags            = 0x%x\n", m->flags);
+	dprintk(DBGLVL_BUS, " .size             = 0x%x\n", m->size);
+	dprintk(DBGLVL_BUS, " .command          = 0x%x\n", m->command);
+	dprintk(DBGLVL_BUS, " .controlselector  = 0x%x\n", m->controlselector);
+	dprintk(DBGLVL_BUS, " .seqno            = %d\n",   m->seqno);
+	if (buf)
+		dprintk(DBGLVL_BUS, " .buffer (ignored)\n");
+}
+
+/*
+ * Places a command or a response on the bus. The implementation does not
+ * know if it is a command or a response it just places the data on the
+ * bus depending on the bus information given in the tmComResBusInfo_t
+ * structure. If the command or response does not fit into the bus ring
+ * buffer it will be refused.
+ *
+ * Return Value:
+ *  SAA_OK     The function executed successfully.
+ *  < 0        One or more members are not initialized.
+ */
+int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
+{
+	tmComResBusInfo_t *bus = &dev->bus;
+	u32 bytes_to_write, read_distance, timeout, curr_srp, curr_swp;
+	u32 new_swp, space_rem;
+	int ret = SAA_ERR_BAD_PARAMETER;
+
+	if (!msg) {
+		printk(KERN_ERR "%s() !msg\n", __func__);
+		return SAA_ERR_BAD_PARAMETER;
+	}
+
+	dprintk(DBGLVL_BUS, "%s()\n", __func__);
+
+	msg->size = cpu_to_le16(msg->size);
+	msg->command = cpu_to_le16(msg->command);
+	msg->controlselector = cpu_to_le16(msg->controlselector);
+
+	if (msg->size > dev->bus.m_wMaxReqSize) {
+		printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
+			__func__);
+		return SAA_ERR_BAD_PARAMETER;
+	}
+
+	if ((msg->size > 0) && (buf == 0)) {
+		printk(KERN_ERR "%s() Missing message buffer\n", __func__);
+		return SAA_ERR_BAD_PARAMETER;
+	}
+
+	/* Lock the bus from any other access */
+	mutex_lock(&bus->lock);
+
+	bytes_to_write = sizeof(*msg) + msg->size;
+	read_distance = 0;
+	timeout = SAA_BUS_TIMEOUT;
+	curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
+	curr_swp = le32_to_cpu(*bus->m_pdwSetWritePos);
+
+	/* Deal with ring wrapping issues */
+	if (curr_srp > curr_swp)
+		/* The ring has not wrapped yet */
+		read_distance = curr_srp - curr_swp;
+	else
+		/* Deal with the wrapped ring */
+		read_distance = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
+
+	dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__,
+		bytes_to_write);
+
+	dprintk(DBGLVL_BUS, "%s() read_distance = %d\n", __func__,
+		read_distance);
+
+	dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp);
+	dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp);
+
+	/* Process the msg and write the content onto the bus */
+	while (bytes_to_write >= read_distance) {
+
+		if (timeout-- == 0) {
+			printk(KERN_ERR "%s() bus timeout\n", __func__);
+			ret = SAA_ERR_NO_RESOURCES;
+			goto out;
+		}
+
+		/* TODO: Review this delay, efficient? */
+		/* Wait, allowing the hardware fetch time */
+		mdelay(1);
+
+		/* Check the space usage again */
+		curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
+
+		/* Deal with ring wrapping issues */
+		if (curr_srp > curr_swp)
+			/* Read didn't wrap around the buffer */
+			read_distance = curr_srp - curr_swp;
+		else
+			/* Deal with the wrapped ring */
+			read_distance = (curr_srp + bus->m_dwSizeSetRing) -
+				curr_swp;
+
+	}
+
+	/* Calculate the new write position */
+	new_swp = curr_swp + bytes_to_write;
+
+	dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
+	dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__,
+		bus->m_dwSizeSetRing);
+
+	/* Mental Note: line 462 tmmhComResBusPCIe.cpp */
+
+	/* Check if we're going to wrap again */
+	if (new_swp > bus->m_dwSizeSetRing) {
+
+		/* Ring wraps */
+		new_swp -= bus->m_dwSizeSetRing;
+
+		space_rem = bus->m_dwSizeSetRing - curr_swp;
+
+		dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__,
+			space_rem);
+
+		dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__,
+			(u32)sizeof(*msg));
+
+		if (space_rem < sizeof(*msg)) {
+			dprintk(DBGLVL_BUS, "%s() tr4\n", __func__);
+
+			/* Split the msg into pieces as the ring wraps */
+			memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem);
+			memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem,
+				sizeof(*msg) - space_rem);
+
+			memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem,
+				buf, msg->size);
+
+		} else if (space_rem == sizeof(*msg)) {
+			dprintk(DBGLVL_BUS, "%s() tr5\n", __func__);
+
+			/* Additional data at the beginning of the ring */
+			memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
+			memcpy(bus->m_pdwSetRing, buf, msg->size);
+
+		} else {
+			/* Additional data wraps around the ring */
+			memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
+			if (msg->size > 0) {
+				memcpy(bus->m_pdwSetRing + curr_swp +
+					sizeof(*msg), buf, space_rem -
+					sizeof(*msg));
+				memcpy(bus->m_pdwSetRing, (u8 *)buf +
+					space_rem - sizeof(*msg),
+					bytes_to_write - space_rem);
+			}
+
+		}
+
+	} /* (new_swp > bus->m_dwSizeSetRing) */
+	else {
+		dprintk(DBGLVL_BUS, "%s() tr6\n", __func__);
+
+		/* The ring buffer doesn't wrap, two simple copies */
+		memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
+		memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf,
+			msg->size);
+	}
+
+	dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
+
+	/* TODO: Convert all of the direct PCI writes into
+	 * saa7164_writel/b calls for consistency.
+	 */
+
+	/* Update the bus write position */
+	*bus->m_pdwSetWritePos = cpu_to_le32(new_swp);
+	ret = SAA_OK;
+
+out:
+	mutex_unlock(&bus->lock);
+	return ret;
+}
+
+/*
+ * Receive a command or a response from the bus. The implementation does not
+ * know if it is a command or a response it simply dequeues the data,
+ * depending on the bus information given in the tmComResBusInfo_t structure.
+ *
+ * Return Value:
+ *  0          The function executed successfully.
+ *  < 0        One or more members are not initialized.
+ */
+int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf,
+	int peekonly)
+{
+	tmComResBusInfo_t *bus = &dev->bus;
+	u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
+		new_grp, buf_size, space_rem;
+	tmComResInfo_t msg_tmp;
+	int ret = SAA_ERR_BAD_PARAMETER;
+
+	if (msg == 0)
+		return ret;
+
+	if (msg->size > dev->bus.m_wMaxReqSize) {
+		printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
+			__func__);
+		return ret;
+	}
+
+	if ((peekonly == 0) && (msg->size > 0) && (buf == 0)) {
+		printk(KERN_ERR
+			"%s() Missing msg buf, size should be %d bytes\n",
+			__func__, msg->size);
+		return ret;
+	}
+
+	mutex_lock(&bus->lock);
+
+	/* Peek the bus to see if a msg exists, if it's not what we're expecting
+	 * then return cleanly else read the message from the bus.
+	 */
+	curr_gwp = le32_to_cpu(*bus->m_pdwGetWritePos);
+	curr_grp = le32_to_cpu(*bus->m_pdwGetReadPos);
+
+	if (curr_gwp == curr_grp) {
+		dprintk(DBGLVL_BUS, "%s() No message on the bus\n", __func__);
+		ret = SAA_ERR_EMPTY;
+		goto out;
+	}
+
+	bytes_to_read = sizeof(*msg);
+
+	/* Calculate write distance to current read position */
+	write_distance = 0;
+	if (curr_gwp >= curr_grp)
+		/* Write doesn't wrap around the ring */
+		write_distance = curr_gwp - curr_grp;
+	else
+		/* Write wraps around the ring */
+		write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
+
+	if (bytes_to_read > write_distance) {
+		printk(KERN_ERR "%s() No message/response found\n", __func__);
+		ret = SAA_ERR_INVALID_COMMAND;
+		goto out;
+	}
+
+	/* Calculate the new read position */
+	new_grp = curr_grp + bytes_to_read;
+	if (new_grp > bus->m_dwSizeGetRing) {
+
+		/* Ring wraps */
+		new_grp -= bus->m_dwSizeGetRing;
+		space_rem = bus->m_dwSizeGetRing - curr_grp;
+
+		memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem);
+		memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing,
+			bytes_to_read - space_rem);
+
+	} else {
+		/* No wrapping */
+		memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read);
+	}
+
+	/* No need to update the read positions, because this was a peek */
+	/* If the caller specifically want to peek, return */
+	if (peekonly) {
+		memcpy(msg, &msg_tmp, sizeof(*msg));
+		goto peekout;
+	}
+
+	/* Check if the command/response matches what is expected */
+	if ((msg_tmp.id != msg->id) || (msg_tmp.command != msg->command) ||
+		(msg_tmp.controlselector != msg->controlselector) ||
+		(msg_tmp.seqno != msg->seqno) || (msg_tmp.size != msg->size)) {
+
+		printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
+		saa7164_bus_dumpmsg(dev, msg, buf);
+		saa7164_bus_dumpmsg(dev, &msg_tmp, 0);
+		ret = SAA_ERR_INVALID_COMMAND;
+		goto out;
+	}
+
+	/* Get the actual command and response from the bus */
+	buf_size = msg->size;
+
+	bytes_to_read = sizeof(*msg) + msg->size;
+	/* Calculate write distance to current read position */
+	write_distance = 0;
+	if (curr_gwp >= curr_grp)
+		/* Write doesn't wrap around the ring */
+		write_distance = curr_gwp - curr_grp;
+	else
+		/* Write wraps around the ring */
+		write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
+
+	if (bytes_to_read > write_distance) {
+		printk(KERN_ERR "%s() Invalid bus state, missing msg "
+			"or mangled ring, faulty H/W / bad code?\n", __func__);
+		ret = SAA_ERR_INVALID_COMMAND;
+		goto out;
+	}
+
+	/* Calculate the new read position */
+	new_grp = curr_grp + bytes_to_read;
+	if (new_grp > bus->m_dwSizeGetRing) {
+
+		/* Ring wraps */
+		new_grp -= bus->m_dwSizeGetRing;
+		space_rem = bus->m_dwSizeGetRing - curr_grp;
+
+		if (space_rem < sizeof(*msg)) {
+			/* msg wraps around the ring */
+			memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem);
+			memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing,
+				sizeof(*msg) - space_rem);
+			if (buf)
+				memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) -
+					space_rem, buf_size);
+
+		} else if (space_rem == sizeof(*msg)) {
+			memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
+			if (buf)
+				memcpy(buf, bus->m_pdwGetRing, buf_size);
+		} else {
+			/* Additional data wraps around the ring */
+			memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
+			if (buf) {
+				memcpy(buf, bus->m_pdwGetRing + curr_grp +
+					sizeof(*msg), space_rem - sizeof(*msg));
+				memcpy(buf + space_rem - sizeof(*msg),
+					bus->m_pdwGetRing, bytes_to_read -
+					space_rem);
+			}
+
+		}
+
+	} else {
+		/* No wrapping */
+		memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
+		if (buf)
+			memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
+				buf_size);
+	}
+
+	/* Update the read positions, adjusting the ring */
+	*bus->m_pdwGetReadPos = cpu_to_le32(new_grp);
+
+peekout:
+	msg->size = le16_to_cpu(msg->size);
+	msg->command = le16_to_cpu(msg->command);
+	msg->controlselector = le16_to_cpu(msg->controlselector);
+	ret = SAA_OK;
+out:
+	mutex_unlock(&bus->lock);
+	return ret;
+}
+
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
new file mode 100644
index 0000000..a3c2994
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cards.c
@@ -0,0 +1,624 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include "saa7164.h"
+
+/* The Bridge API needs to understand register widths (in bytes) for the
+ * attached I2C devices, so we can simplify the virtual i2c mechansms
+ * and keep the -i2c.c implementation clean.
+ */
+#define REGLEN_8bit	1
+#define REGLEN_16bit	2
+
+struct saa7164_board saa7164_boards[] = {
+	[SAA7164_BOARD_UNKNOWN] = {
+		/* Bridge will not load any firmware, without knowing
+		 * the rev this would be fatal. */
+		.name		= "Unknown",
+	},
+	[SAA7164_BOARD_UNKNOWN_REV2] = {
+		/* Bridge will load the v2 f/w and dump descriptors */
+		/* Required during new board bringup */
+		.name		= "Generic Rev2",
+		.chiprev	= SAA7164_CHIP_REV2,
+	},
+	[SAA7164_BOARD_UNKNOWN_REV3] = {
+		/* Bridge will load the v2 f/w and dump descriptors */
+		/* Required during new board bringup */
+		.name		= "Generic Rev3",
+		.chiprev	= SAA7164_CHIP_REV3,
+	},
+	[SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
+		.name		= "Hauppauge WinTV-HVR2200",
+		.porta		= SAA7164_MPEG_DVB,
+		.portb		= SAA7164_MPEG_DVB,
+		.chiprev	= SAA7164_CHIP_REV3,
+		.unit		= {{
+			.id		= 0x1d,
+			.type		= SAA7164_UNIT_EEPROM,
+			.name		= "4K EEPROM",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_0,
+			.i2c_bus_addr	= 0xa0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x04,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1b,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1e,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "TDA10048-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x10 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1f,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "TDA10048-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x12 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		} },
+	},
+	[SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
+		.name		= "Hauppauge WinTV-HVR2200",
+		.porta		= SAA7164_MPEG_DVB,
+		.portb		= SAA7164_MPEG_DVB,
+		.chiprev	= SAA7164_CHIP_REV2,
+		.unit		= {{
+			.id		= 0x06,
+			.type		= SAA7164_UNIT_EEPROM,
+			.name		= "4K EEPROM",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_0,
+			.i2c_bus_addr	= 0xa0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x04,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x05,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "TDA10048-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x10 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1e,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1f,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "TDA10048-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x12 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		} },
+	},
+	[SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
+		.name		= "Hauppauge WinTV-HVR2200",
+		.porta		= SAA7164_MPEG_DVB,
+		.portb		= SAA7164_MPEG_DVB,
+		.chiprev	= SAA7164_CHIP_REV2,
+		.unit		= {{
+			.id		= 0x1d,
+			.type		= SAA7164_UNIT_EEPROM,
+			.name		= "4K EEPROM",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_0,
+			.i2c_bus_addr	= 0xa0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x04,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x05,
+			.type		= SAA7164_UNIT_ANALOG_DEMODULATOR,
+			.name		= "TDA8290-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x84 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1b,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1c,
+			.type		= SAA7164_UNIT_ANALOG_DEMODULATOR,
+			.name		= "TDA8290-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x84 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1e,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "TDA10048-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x10 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1f,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "TDA10048-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x12 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		} },
+	},
+	[SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
+		.name		= "Hauppauge WinTV-HVR2250",
+		.porta		= SAA7164_MPEG_DVB,
+		.portb		= SAA7164_MPEG_DVB,
+		.chiprev	= SAA7164_CHIP_REV3,
+		.unit		= {{
+			.id		= 0x22,
+			.type		= SAA7164_UNIT_EEPROM,
+			.name		= "4K EEPROM",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_0,
+			.i2c_bus_addr	= 0xa0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x04,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x07,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-1 (TOP)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x32 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x08,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-1 (QAM)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x34 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x1e,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x20,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-2 (TOP)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x32 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x23,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-2 (QAM)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x34 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		} },
+	},
+	[SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
+		.name		= "Hauppauge WinTV-HVR2250",
+		.porta		= SAA7164_MPEG_DVB,
+		.portb		= SAA7164_MPEG_DVB,
+		.chiprev	= SAA7164_CHIP_REV3,
+		.unit		= {{
+			.id		= 0x28,
+			.type		= SAA7164_UNIT_EEPROM,
+			.name		= "4K EEPROM",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_0,
+			.i2c_bus_addr	= 0xa0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x04,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x07,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-1 (TOP)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x32 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x08,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-1 (QAM)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x34 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x24,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x26,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-2 (TOP)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x32 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x29,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-2 (QAM)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x34 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		} },
+	},
+	[SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
+		.name		= "Hauppauge WinTV-HVR2250",
+		.porta		= SAA7164_MPEG_DVB,
+		.portb		= SAA7164_MPEG_DVB,
+		.chiprev	= SAA7164_CHIP_REV3,
+		.unit		= {{
+			.id		= 0x26,
+			.type		= SAA7164_UNIT_EEPROM,
+			.name		= "4K EEPROM",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_0,
+			.i2c_bus_addr	= 0xa0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x04,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-1",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x07,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-1 (TOP)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x32 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x08,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-1 (QAM)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_1,
+			.i2c_bus_addr	= 0x34 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x22,
+			.type		= SAA7164_UNIT_TUNER,
+			.name		= "TDA18271-2",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0xc0 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x24,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-2 (TOP)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x32 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		}, {
+			.id		= 0x27,
+			.type		= SAA7164_UNIT_DIGITAL_DEMODULATOR,
+			.name		= "CX24228/S5H1411-2 (QAM)",
+			.i2c_bus_nr	= SAA7164_I2C_BUS_2,
+			.i2c_bus_addr	= 0x34 >> 1,
+			.i2c_reg_len	= REGLEN_8bit,
+		} },
+	},
+};
+const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
+
+/* ------------------------------------------------------------------ */
+/* PCI subsystem IDs                                                  */
+
+struct saa7164_subid saa7164_subids[] = {
+	{
+		.subvendor = 0x0070,
+		.subdevice = 0x8880,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8810,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2250,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8980,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2200,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8900,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8901,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x88A1,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8891,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
+	}, {
+		.subvendor = 0x0070,
+		.subdevice = 0x8851,
+		.card      = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
+	},
+};
+const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
+
+void saa7164_card_list(struct saa7164_dev *dev)
+{
+	int i;
+
+	if (0 == dev->pci->subsystem_vendor &&
+	    0 == dev->pci->subsystem_device) {
+		printk(KERN_ERR
+			"%s: Board has no valid PCIe Subsystem ID and can't\n"
+			"%s: be autodetected. Pass card=<n> insmod option to\n"
+			"%s: workaround that. Send complaints to the vendor\n"
+			"%s: of the TV card. Best regards,\n"
+			"%s:         -- tux\n",
+			dev->name, dev->name, dev->name, dev->name, dev->name);
+	} else {
+		printk(KERN_ERR
+			"%s: Your board isn't known (yet) to the driver.\n"
+			"%s: Try to pick one of the existing card configs via\n"
+			"%s: card=<n> insmod option.  Updating to the latest\n"
+			"%s: version might help as well.\n",
+			dev->name, dev->name, dev->name, dev->name);
+	}
+
+	printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
+		"option:\n", dev->name);
+
+	for (i = 0; i < saa7164_bcount; i++)
+		printk(KERN_ERR "%s:    card=%d -> %s\n",
+		       dev->name, i, saa7164_boards[i].name);
+}
+
+/* TODO: clean this define up into the -cards.c structs */
+#define PCIEBRIDGE_UNITID 2
+
+void saa7164_gpio_setup(struct saa7164_dev *dev)
+{
+
+
+	switch (dev->board) {
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
+		/*
+		GPIO 2: s5h1411 / tda10048-1 demod reset
+		GPIO 3: s5h1411 / tda10048-2 demod reset
+		GPIO 7: IRBlaster Zilog reset
+		 */
+
+		/* Reset parts by going in and out of reset */
+		saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
+		saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
+
+		msleep(10);
+
+		saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
+		saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
+		break;
+	}
+
+}
+
+static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
+{
+	struct tveeprom tv;
+
+	/* TODO: Assumption: eeprom on bus 0 */
+	tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
+		eeprom_data);
+
+	/* Make sure we support the board model */
+	switch (tv.model) {
+	case 88001:
+		/* Development board - Limit circulation */
+		/* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+		 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
+	case 88021:
+		/* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+		 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
+		break;
+	case 88041:
+		/* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+		 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
+		break;
+	case 88061:
+		/* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
+		 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
+		break;
+	case 89519:
+	case 89609:
+		/* WinTV-HVR2200 (PCIe, Retail, full-height)
+		 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
+		break;
+	case 89619:
+		/* WinTV-HVR2200 (PCIe, Retail, half-height)
+		 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
+		break;
+	default:
+		printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
+			dev->name, tv.model);
+		break;
+	}
+
+	printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
+		tv.model);
+}
+
+void saa7164_card_setup(struct saa7164_dev *dev)
+{
+	static u8 eeprom[256];
+
+	if (dev->i2c_bus[0].i2c_rc == 0) {
+		if (saa7164_api_read_eeprom(dev, &eeprom[0],
+			sizeof(eeprom)) < 0)
+			return;
+	}
+
+	switch (dev->board) {
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
+		hauppauge_eeprom(dev, &eeprom[0]);
+		break;
+	}
+}
+
+/* With most other drivers, the kernel expects to communicate with subdrivers
+ * through i2c. This bridge does not allow that, it does not expose any direct
+ * access to I2C. Instead we have to communicate through the device f/w for
+ * register access to 'processing units'. Each unit has a unique
+ * id, regardless of how the physical implementation occurs across
+ * the three physical i2c busses. The being said if we want leverge of
+ * the existing kernel drivers for tuners and demods we have to 'speak i2c',
+ * to this bridge implements 3 virtual i2c buses. This is a helper function
+ * for those.
+ *
+ * Description: Translate the kernels notion of an i2c address and bus into
+ * the appropriate unitid.
+ */
+int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
+{
+	/* For a given bus and i2c device address, return the saa7164 unique
+	 * unitid. < 0 on error */
+
+	struct saa7164_dev *dev = bus->dev;
+	struct saa7164_unit *unit;
+	int i;
+
+	for (i = 0; i < SAA7164_MAX_UNITS; i++) {
+		unit = &saa7164_boards[dev->board].unit[i];
+
+		if (unit->type == SAA7164_UNIT_UNDEFINED)
+			continue;
+		if ((bus->nr == unit->i2c_bus_nr) &&
+			(addr == unit->i2c_bus_addr))
+			return unit->id;
+	}
+
+	return -1;
+}
+
+/* The 7164 API needs to know the i2c register length in advance.
+ * this is a helper function. Based on a specific chip addr and bus return the
+ * reg length.
+ */
+int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
+{
+	/* For a given bus and i2c device address, return the
+	 * saa7164 registry address width. < 0 on error
+	 */
+
+	struct saa7164_dev *dev = bus->dev;
+	struct saa7164_unit *unit;
+	int i;
+
+	for (i = 0; i < SAA7164_MAX_UNITS; i++) {
+		unit = &saa7164_boards[dev->board].unit[i];
+
+		if (unit->type == SAA7164_UNIT_UNDEFINED)
+			continue;
+
+		if ((bus->nr == unit->i2c_bus_nr) &&
+			(addr == unit->i2c_bus_addr))
+			return unit->i2c_reg_len;
+	}
+
+	return -1;
+}
+/* TODO: implement a 'findeeprom' functio like the above and fix any other
+ * eeprom related todo's in -api.c.
+ */
+
+/* Translate a unitid into a x readable device name, for display purposes.  */
+char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
+{
+	char *undefed = "UNDEFINED";
+	char *bridge = "BRIDGE";
+	struct saa7164_unit *unit;
+	int i;
+
+	if (unitid == 0)
+		return bridge;
+
+	for (i = 0; i < SAA7164_MAX_UNITS; i++) {
+		unit = &saa7164_boards[dev->board].unit[i];
+
+		if (unit->type == SAA7164_UNIT_UNDEFINED)
+			continue;
+
+		if (unitid == unit->id)
+				return unit->name;
+	}
+
+	return undefed;
+}
+
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
new file mode 100644
index 0000000..e097f1a
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -0,0 +1,572 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include <linux/wait.h>
+
+#include "saa7164.h"
+
+int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
+{
+	int i, ret = -1;
+
+	mutex_lock(&dev->lock);
+	for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+		if (dev->cmds[i].inuse == 0) {
+			dev->cmds[i].inuse = 1;
+			dev->cmds[i].signalled = 0;
+			dev->cmds[i].timeout = 0;
+			ret = dev->cmds[i].seqno;
+			break;
+		}
+	}
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
+{
+	mutex_lock(&dev->lock);
+	if ((dev->cmds[seqno].inuse == 1) &&
+		(dev->cmds[seqno].seqno == seqno)) {
+		dev->cmds[seqno].inuse = 0;
+		dev->cmds[seqno].signalled = 0;
+		dev->cmds[seqno].timeout = 0;
+	}
+	mutex_unlock(&dev->lock);
+}
+
+void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
+{
+	mutex_lock(&dev->lock);
+	if ((dev->cmds[seqno].inuse == 1) &&
+		(dev->cmds[seqno].seqno == seqno)) {
+		dev->cmds[seqno].timeout = 1;
+	}
+	mutex_unlock(&dev->lock);
+}
+
+u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
+{
+	int ret = 0;
+
+	mutex_lock(&dev->lock);
+	if ((dev->cmds[seqno].inuse == 1) &&
+		(dev->cmds[seqno].seqno == seqno)) {
+		ret = dev->cmds[seqno].timeout;
+	}
+	mutex_unlock(&dev->lock);
+
+	return ret;
+}
+
+/* Commands to the f/w get marshelled to/from this code then onto the PCI
+ * -bus/c running buffer. */
+int saa7164_irq_dequeue(struct saa7164_dev *dev)
+{
+	int ret = SAA_OK;
+	u32 timeout;
+	wait_queue_head_t *q = 0;
+	dprintk(DBGLVL_CMD, "%s()\n", __func__);
+
+	/* While any outstand message on the bus exists... */
+	do {
+
+		/* Peek the msg bus */
+		tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
+		ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
+		if (ret != SAA_OK)
+			break;
+
+		q = &dev->cmds[tRsp.seqno].wait;
+		timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
+		dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
+		if (!timeout) {
+			dprintk(DBGLVL_CMD,
+				"%s() signalled seqno(%d) (for dequeue)\n",
+				__func__, tRsp.seqno);
+			dev->cmds[tRsp.seqno].signalled = 1;
+			wake_up(q);
+		} else {
+			printk(KERN_ERR
+				"%s() found timed out command on the bus\n",
+					__func__);
+		}
+	} while (0);
+
+	return ret;
+}
+
+/* Commands to the f/w get marshelled to/from this code then onto the PCI
+ * -bus/c running buffer. */
+int saa7164_cmd_dequeue(struct saa7164_dev *dev)
+{
+	int loop = 1;
+	int ret;
+	u32 timeout;
+	wait_queue_head_t *q = 0;
+	u8 tmp[512];
+	dprintk(DBGLVL_CMD, "%s()\n", __func__);
+
+	while (loop) {
+
+		tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
+		ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
+		if (ret == SAA_ERR_EMPTY)
+			return SAA_OK;
+
+		if (ret != SAA_OK)
+			return ret;
+
+		q = &dev->cmds[tRsp.seqno].wait;
+		timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
+		dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
+		if (timeout) {
+			printk(KERN_ERR "found timed out command on the bus\n");
+
+			/* Clean the bus */
+			ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
+			printk(KERN_ERR "ret = %x\n", ret);
+			if (ret == SAA_ERR_EMPTY)
+				/* Someone else already fetched the response */
+				return SAA_OK;
+
+			if (ret != SAA_OK)
+				return ret;
+
+			if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
+				printk(KERN_ERR "split response\n");
+			else
+				saa7164_cmd_free_seqno(dev, tRsp.seqno);
+
+			printk(KERN_ERR " timeout continue\n");
+			continue;
+		}
+
+		dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
+			__func__, tRsp.seqno);
+		dev->cmds[tRsp.seqno].signalled = 1;
+		wake_up(q);
+		return SAA_OK;
+	}
+
+	return SAA_OK;
+}
+
+int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
+{
+	tmComResBusInfo_t *bus = &dev->bus;
+	u8 cmd_sent;
+	u16 size, idx;
+	u32 cmds;
+	void *tmp;
+	int ret = -1;
+
+	if (!msg) {
+		printk(KERN_ERR "%s() !msg\n", __func__);
+		return SAA_ERR_BAD_PARAMETER;
+	}
+
+	mutex_lock(&dev->cmds[msg->id].lock);
+
+	size = msg->size;
+	idx = 0;
+	cmds = size / bus->m_wMaxReqSize;
+	if (size % bus->m_wMaxReqSize == 0)
+		cmds -= 1;
+
+	cmd_sent = 0;
+
+	/* Split the request into smaller chunks */
+	for (idx = 0; idx < cmds; idx++) {
+
+		msg->flags |= SAA_CMDFLAG_CONTINUE;
+		msg->size = bus->m_wMaxReqSize;
+		tmp = buf + idx * bus->m_wMaxReqSize;
+
+		ret = saa7164_bus_set(dev, msg, tmp);
+		if (ret != SAA_OK) {
+			printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
+
+			if (cmd_sent) {
+				ret = SAA_ERR_BUSY;
+				goto out;
+			}
+			ret = SAA_ERR_OVERFLOW;
+			goto out;
+		}
+		cmd_sent = 1;
+	}
+
+	/* If not the last command... */
+	if (idx != 0)
+		msg->flags &= ~SAA_CMDFLAG_CONTINUE;
+
+	msg->size = size - idx * bus->m_wMaxReqSize;
+
+	ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
+
+		if (cmd_sent) {
+			ret = SAA_ERR_BUSY;
+			goto out;
+		}
+		ret = SAA_ERR_OVERFLOW;
+		goto out;
+	}
+	ret = SAA_OK;
+
+out:
+	mutex_unlock(&dev->cmds[msg->id].lock);
+	return ret;
+}
+
+/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
+ * the event never occured, or SAA_OK if it was signaled during the wait.
+ */
+int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
+{
+	wait_queue_head_t *q = 0;
+	int ret = SAA_BUS_TIMEOUT;
+	unsigned long stamp;
+	int r;
+
+	if (debug >= 4)
+		saa7164_bus_dump(dev);
+
+	dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
+
+	mutex_lock(&dev->lock);
+	if ((dev->cmds[seqno].inuse == 1) &&
+		(dev->cmds[seqno].seqno == seqno)) {
+		q = &dev->cmds[seqno].wait;
+	}
+	mutex_unlock(&dev->lock);
+
+	if (q) {
+		/* If we haven't been signalled we need to wait */
+		if (dev->cmds[seqno].signalled == 0) {
+			stamp = jiffies;
+			dprintk(DBGLVL_CMD,
+				"%s(seqno=%d) Waiting (signalled=%d)\n",
+				__func__, seqno, dev->cmds[seqno].signalled);
+
+			/* Wait for signalled to be flagged or timeout */
+			/* In a highly stressed system this can easily extend
+			 * into multiple seconds before the deferred worker
+			 * is scheduled, and we're woken up via signal.
+			 * We typically are signalled in < 50ms but it can
+			 * take MUCH longer.
+			 */
+			wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
+			r = time_before(jiffies, stamp + (HZ * waitsecs));
+			if (r)
+				ret = SAA_OK;
+			else
+				saa7164_cmd_timeout_seqno(dev, seqno);
+
+			dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
+				"(signalled=%d)\n", __func__, seqno, r,
+				dev->cmds[seqno].signalled);
+		} else
+			ret = SAA_OK;
+	} else
+		printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
+			__func__, seqno);
+
+	return ret;
+}
+
+void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
+{
+	int i;
+	dprintk(DBGLVL_CMD, "%s()\n", __func__);
+
+	mutex_lock(&dev->lock);
+	for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+		if (dev->cmds[i].inuse == 1) {
+			dprintk(DBGLVL_CMD,
+				"seqno %d inuse, sig = %d, t/out = %d\n",
+				dev->cmds[i].seqno,
+				dev->cmds[i].signalled,
+				dev->cmds[i].timeout);
+		}
+	}
+
+	for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+		if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
+			(dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
+			dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
+				__func__, i);
+			dev->cmds[i].signalled = 1;
+			wake_up(&dev->cmds[i].wait);
+		}
+	}
+	mutex_unlock(&dev->lock);
+}
+
+int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
+	u16 controlselector, u16 size, void *buf)
+{
+	tmComResInfo_t command_t, *pcommand_t;
+	tmComResInfo_t response_t, *presponse_t;
+	u8 errdata[256];
+	u16 resp_dsize;
+	u16 data_recd;
+	u32 loop;
+	int ret;
+	int safety = 0;
+
+	dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
+		"sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
+		command, controlselector);
+
+	if ((size == 0) || (buf == 0)) {
+		printk(KERN_ERR "%s() Invalid param\n", __func__);
+		return SAA_ERR_BAD_PARAMETER;
+	}
+
+	/* Prepare some basic command/response structures */
+	memset(&command_t, 0, sizeof(command_t));
+	memset(&response_t, 0, sizeof(&response_t));
+	pcommand_t = &command_t;
+	presponse_t = &response_t;
+	command_t.id = id;
+	command_t.command = command;
+	command_t.controlselector = controlselector;
+	command_t.size = size;
+
+	/* Allocate a unique sequence number */
+	ret = saa7164_cmd_alloc_seqno(dev);
+	if (ret < 0) {
+		printk(KERN_ERR "%s() No free sequences\n", __func__);
+		ret = SAA_ERR_NO_RESOURCES;
+		goto out;
+	}
+
+	command_t.seqno = (u8)ret;
+
+	/* Send Command */
+	resp_dsize = size;
+	pcommand_t->size = size;
+
+	dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
+		__func__, pcommand_t->seqno);
+
+	dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
+		__func__, pcommand_t->size);
+
+	ret = saa7164_cmd_set(dev, pcommand_t, buf);
+	if (ret != SAA_OK) {
+		printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
+
+		if (ret != SAA_ERR_BUSY)
+			saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
+		else
+			/* Flag a timeout, because at least one
+			 * command was sent */
+			saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
+
+		goto out;
+	}
+
+	/* With split responses we have to collect the msgs piece by piece */
+	data_recd = 0;
+	loop = 1;
+	while (loop) {
+		dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
+
+		ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
+		dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
+
+		/* if power is down and this is not a power command ... */
+
+		if (ret == SAA_BUS_TIMEOUT) {
+			printk(KERN_ERR "Event timed out\n");
+			saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
+			return ret;
+		}
+
+		if (ret != SAA_OK) {
+			printk(KERN_ERR "spurious error\n");
+			return ret;
+		}
+
+		/* Peek response */
+		ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
+		if (ret == SAA_ERR_EMPTY) {
+			dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
+			continue;
+		}
+		if (ret != SAA_OK) {
+			printk(KERN_ERR "peek failed\n");
+			return ret;
+		}
+
+		dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
+			__func__, presponse_t->seqno);
+
+		dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
+			__func__, presponse_t->flags);
+
+		dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
+			__func__, presponse_t->size);
+
+		/* Check if the response was for our command */
+		if (presponse_t->seqno != pcommand_t->seqno) {
+
+			dprintk(DBGLVL_CMD,
+				"wrong event: seqno = %d, "
+				"expected seqno = %d, "
+				"will dequeue regardless\n",
+				presponse_t->seqno, pcommand_t->seqno);
+
+			ret = saa7164_cmd_dequeue(dev);
+			if (ret != SAA_OK) {
+				printk(KERN_ERR "dequeue failed, ret = %d\n",
+					ret);
+				if (safety++ > 16) {
+					printk(KERN_ERR
+					"dequeue exceeded, safety exit\n");
+					return SAA_ERR_BUSY;
+				}
+			}
+
+			continue;
+		}
+
+		if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
+
+			memset(&errdata[0], 0, sizeof(errdata));
+
+			ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
+			if (ret != SAA_OK) {
+				printk(KERN_ERR "get error(2)\n");
+				return ret;
+			}
+
+			saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
+
+			dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
+				__func__, errdata[0], errdata[1], errdata[2],
+				errdata[3]);
+
+			/* Map error codes */
+			dprintk(DBGLVL_CMD, "%s() cmd, error code  = 0x%x\n",
+				__func__, errdata[0]);
+
+			switch (errdata[0]) {
+			case PVC_ERRORCODE_INVALID_COMMAND:
+				dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
+					__func__);
+				ret = SAA_ERR_INVALID_COMMAND;
+				break;
+			case PVC_ERRORCODE_INVALID_DATA:
+				dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
+					__func__);
+				ret = SAA_ERR_BAD_PARAMETER;
+				break;
+			case PVC_ERRORCODE_TIMEOUT:
+				dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
+				ret = SAA_ERR_TIMEOUT;
+				break;
+			case PVC_ERRORCODE_NAK:
+				dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
+				ret = SAA_ERR_NULL_PACKET;
+				break;
+			case PVC_ERRORCODE_UNKNOWN:
+			case PVC_ERRORCODE_INVALID_CONTROL:
+				dprintk(DBGLVL_CMD,
+					"%s() UNKNOWN OR INVALID CONTROL\n",
+					__func__);
+			default:
+				dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
+				ret = SAA_ERR_NOT_SUPPORTED;
+			}
+
+			/* See of other commands are on the bus */
+			if (saa7164_cmd_dequeue(dev) != SAA_OK)
+				printk(KERN_ERR "dequeue(2) failed\n");
+
+			return ret;
+		}
+
+		/* If response is invalid */
+		if ((presponse_t->id != pcommand_t->id) ||
+			(presponse_t->command != pcommand_t->command) ||
+			(presponse_t->controlselector !=
+				pcommand_t->controlselector) ||
+			(((resp_dsize - data_recd) != presponse_t->size) &&
+				!(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
+			((resp_dsize - data_recd) < presponse_t->size)) {
+
+			/* Invalid */
+			dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
+			ret = saa7164_bus_get(dev, presponse_t, 0, 0);
+			if (ret != SAA_OK) {
+				printk(KERN_ERR "get failed\n");
+				return ret;
+			}
+
+			/* See of other commands are on the bus */
+			if (saa7164_cmd_dequeue(dev) != SAA_OK)
+				printk(KERN_ERR "dequeue(3) failed\n");
+			continue;
+		}
+
+		/* OK, now we're actually getting out correct response */
+		ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
+		if (ret != SAA_OK) {
+			printk(KERN_ERR "get failed\n");
+			return ret;
+		}
+
+		data_recd = presponse_t->size + data_recd;
+		if (resp_dsize == data_recd) {
+			dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
+			break;
+		}
+
+		/* See of other commands are on the bus */
+		if (saa7164_cmd_dequeue(dev) != SAA_OK)
+			printk(KERN_ERR "dequeue(3) failed\n");
+
+		continue;
+
+	} /* (loop) */
+
+	/* Release the sequence number allocation */
+	saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
+
+	/* if powerdown signal all pending commands */
+
+	dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
+
+	/* See of other commands are on the bus */
+	if (saa7164_cmd_dequeue(dev) != SAA_OK)
+		printk(KERN_ERR "dequeue(4) failed\n");
+
+	ret = SAA_OK;
+out:
+	return ret;
+}
+
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
new file mode 100644
index 0000000..f0dbead
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -0,0 +1,740 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/div64.h>
+
+#include "saa7164.h"
+
+MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
+MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
+MODULE_LICENSE("GPL");
+
+/*
+  1 Basic
+  2
+  4 i2c
+  8 api
+ 16 cmd
+ 32 bus
+ */
+
+unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
+
+unsigned int waitsecs = 10;
+module_param(waitsecs, int, 0644);
+MODULE_PARM_DESC(debug, "timeout on firmware messages");
+
+static unsigned int card[]  = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
+module_param_array(card,  int, NULL, 0444);
+MODULE_PARM_DESC(card, "card type");
+
+static unsigned int saa7164_devcount;
+
+static DEFINE_MUTEX(devlist);
+LIST_HEAD(saa7164_devlist);
+
+#define INT_SIZE 16
+
+static void saa7164_work_cmdhandler(struct work_struct *w)
+{
+	struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
+
+	/* Wake up any complete commands */
+	saa7164_irq_dequeue(dev);
+}
+
+static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
+{
+	struct saa7164_tsport *port = buf->port;
+
+	/* Feed the transport payload into the kernel demux */
+	dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
+		SAA7164_TS_NUMBER_OF_LINES);
+
+}
+
+static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
+{
+	struct saa7164_dev *dev = port->dev;
+	struct saa7164_buffer *buf;
+	struct list_head *c, *n;
+	int wp, i = 0, rp;
+
+	/* Find the current write point from the hardware */
+	wp = saa7164_readl(port->bufcounter);
+	if (wp > (port->hwcfg.buffercount - 1))
+		BUG();
+
+	/* Find the previous buffer to the current write point */
+	if (wp == 0)
+		rp = 7;
+	else
+		rp = wp - 1;
+
+	/* Lookup the WP in the buffer list */
+	/* TODO: turn this into a worker thread */
+	list_for_each_safe(c, n, &port->dmaqueue.list) {
+		buf = list_entry(c, struct saa7164_buffer, list);
+		if (i++ > port->hwcfg.buffercount)
+			BUG();
+
+		if (buf->nr == rp) {
+			/* Found the buffer, deal with it */
+			dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
+				__func__, wp, rp);
+			saa7164_buffer_deliver(buf);
+			break;
+		}
+
+	}
+	return 0;
+}
+
+/* Primary IRQ handler and dispatch mechanism */
+static irqreturn_t saa7164_irq(int irq, void *dev_id)
+{
+	struct saa7164_dev *dev = dev_id;
+	u32 intid, intstat[INT_SIZE/4];
+	int i, handled = 0, bit;
+
+	if (dev == 0) {
+		printk(KERN_ERR "%s() No device specified\n", __func__);
+		handled = 0;
+		goto out;
+	}
+
+	/* Check that the hardware is accessable. If the status bytes are
+	 * 0xFF then the device is not accessable, the the IRQ belongs
+	 * to another driver.
+	 * 4 x u32 interrupt registers.
+	 */
+	for (i = 0; i < INT_SIZE/4; i++) {
+
+		/* TODO: Convert into saa7164_readl() */
+		/* Read the 4 hardware interrupt registers */
+		intstat[i] = saa7164_readl(dev->int_status + (i * 4));
+
+		if (intstat[i])
+			handled = 1;
+	}
+	if (handled == 0)
+		goto out;
+
+	/* For each of the HW interrupt registers */
+	for (i = 0; i < INT_SIZE/4; i++) {
+
+		if (intstat[i]) {
+			/* Each function of the board has it's own interruptid.
+			 * Find the function that triggered then call
+			 * it's handler.
+			 */
+			for (bit = 0; bit < 32; bit++) {
+
+				if (((intstat[i] >> bit) & 0x00000001) == 0)
+					continue;
+
+				/* Calculate the interrupt id (0x00 to 0x7f) */
+
+				intid = (i * 32) + bit;
+				if (intid == dev->intfdesc.bInterruptId) {
+					/* A response to an cmd/api call */
+					schedule_work(&dev->workcmd);
+				} else if (intid ==
+					dev->ts1.hwcfg.interruptid) {
+
+					/* Transport path 1 */
+					saa7164_irq_ts(&dev->ts1);
+
+				} else if (intid ==
+					dev->ts2.hwcfg.interruptid) {
+
+					/* Transport path 2 */
+					saa7164_irq_ts(&dev->ts2);
+
+				} else {
+					/* Find the function */
+					dprintk(DBGLVL_IRQ,
+						"%s() unhandled interrupt "
+						"reg 0x%x bit 0x%x "
+						"intid = 0x%x\n",
+						__func__, i, bit, intid);
+				}
+			}
+
+			/* Ack it */
+			saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
+
+		}
+	}
+out:
+	return IRQ_RETVAL(handled);
+}
+
+void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
+{
+	struct saa7164_fw_status *s = &dev->fw_status;
+
+	dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
+	dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
+	dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
+	dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
+	dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
+	dev->fw_status.remainheap =
+		saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
+
+	dprintk(1, "Firmware status:\n");
+	dprintk(1, " .status     = 0x%08x\n", s->status);
+	dprintk(1, " .mode       = 0x%08x\n", s->mode);
+	dprintk(1, " .spec       = 0x%08x\n", s->spec);
+	dprintk(1, " .inst       = 0x%08x\n", s->inst);
+	dprintk(1, " .cpuload    = 0x%08x\n", s->cpuload);
+	dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
+}
+
+u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
+{
+	u32 reg;
+
+	reg = saa7164_readl(SAA_DEVICE_VERSION);
+	dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
+		(reg & 0x0000fc00) >> 10,
+		(reg & 0x000003e0) >> 5,
+		(reg & 0x0000001f),
+		(reg & 0xffff0000) >> 16,
+		reg);
+
+	return reg;
+}
+
+/* TODO: Debugging func, remove */
+void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
+{
+	int i;
+
+	printk(KERN_INFO "--------------------> "
+		"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+
+	for (i = 0; i < len; i += 16)
+		printk(KERN_INFO "         [0x%08x] "
+			"%02x %02x %02x %02x %02x %02x %02x %02x "
+			"%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+		*(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
+		*(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
+		*(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
+		*(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
+}
+
+/* TODO: Debugging func, remove */
+void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
+{
+	int i;
+
+	dprintk(1, "--------------------> "
+		"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
+
+	for (i = 0; i < 0x100; i += 16)
+		dprintk(1, "region0[0x%08x] = "
+			"%02x %02x %02x %02x %02x %02x %02x %02x"
+			" %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+			(u8)saa7164_readb(addr + i + 0),
+			(u8)saa7164_readb(addr + i + 1),
+			(u8)saa7164_readb(addr + i + 2),
+			(u8)saa7164_readb(addr + i + 3),
+			(u8)saa7164_readb(addr + i + 4),
+			(u8)saa7164_readb(addr + i + 5),
+			(u8)saa7164_readb(addr + i + 6),
+			(u8)saa7164_readb(addr + i + 7),
+			(u8)saa7164_readb(addr + i + 8),
+			(u8)saa7164_readb(addr + i + 9),
+			(u8)saa7164_readb(addr + i + 10),
+			(u8)saa7164_readb(addr + i + 11),
+			(u8)saa7164_readb(addr + i + 12),
+			(u8)saa7164_readb(addr + i + 13),
+			(u8)saa7164_readb(addr + i + 14),
+			(u8)saa7164_readb(addr + i + 15)
+			);
+}
+
+static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
+{
+	dprintk(1, "@0x%p hwdesc sizeof(tmComResHWDescr_t) = %d bytes\n",
+		&dev->hwdesc, (u32)sizeof(tmComResHWDescr_t));
+
+	dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
+	dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
+	dprintk(1, " .bDescriptorSubtype = 0x%x\n",
+		dev->hwdesc.bDescriptorSubtype);
+
+	dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
+	dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
+	dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
+	dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
+	dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
+		dev->hwdesc.dwDeviceRegistersLocation);
+
+	dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
+		dev->hwdesc.dwHostMemoryRegion);
+
+	dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
+		dev->hwdesc.dwHostMemoryRegionSize);
+
+	dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
+		dev->hwdesc.dwHostHibernatMemRegion);
+
+	dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
+		dev->hwdesc.dwHostHibernatMemRegionSize);
+}
+
+static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
+{
+	dprintk(1, "@0x%p intfdesc "
+		"sizeof(tmComResInterfaceDescr_t) = %d bytes\n",
+		&dev->intfdesc, (u32)sizeof(tmComResInterfaceDescr_t));
+
+	dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
+	dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
+	dprintk(1, " .bDescriptorSubtype = 0x%x\n",
+		dev->intfdesc.bDescriptorSubtype);
+
+	dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
+	dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
+	dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
+	dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
+	dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
+	dprintk(1, " .bDebugInterruptId = 0x%x\n",
+		dev->intfdesc.bDebugInterruptId);
+
+	dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
+}
+
+static void saa7164_dump_busdesc(struct saa7164_dev *dev)
+{
+	dprintk(1, "@0x%p busdesc sizeof(tmComResBusDescr_t) = %d bytes\n",
+		&dev->busdesc, (u32)sizeof(tmComResBusDescr_t));
+
+	dprintk(1, " .CommandRing   = 0x%016Lx\n", dev->busdesc.CommandRing);
+	dprintk(1, " .ResponseRing  = 0x%016Lx\n", dev->busdesc.ResponseRing);
+	dprintk(1, " .CommandWrite  = 0x%x\n", dev->busdesc.CommandWrite);
+	dprintk(1, " .CommandRead   = 0x%x\n", dev->busdesc.CommandRead);
+	dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
+	dprintk(1, " .ResponseRead  = 0x%x\n", dev->busdesc.ResponseRead);
+}
+
+/* Much of the hardware configuration and PCI registers are configured
+ * dynamically depending on firmware. We have to cache some initial
+ * structures then use these to locate other important structures
+ * from PCI space.
+ */
+static void saa7164_get_descriptors(struct saa7164_dev *dev)
+{
+	memcpy(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
+	memcpy(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
+		sizeof(tmComResInterfaceDescr_t));
+	memcpy(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
+		sizeof(tmComResBusDescr_t));
+
+	if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) {
+		printk(KERN_ERR "Structure tmComResHWDescr_t is mangled\n");
+		printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
+			(u32)sizeof(tmComResHWDescr_t));
+	} else
+		saa7164_dump_hwdesc(dev);
+
+	if (dev->intfdesc.bLength != sizeof(tmComResInterfaceDescr_t)) {
+		printk(KERN_ERR "struct tmComResInterfaceDescr_t is mangled\n");
+		printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
+			(u32)sizeof(tmComResInterfaceDescr_t));
+	} else
+		saa7164_dump_intfdesc(dev);
+
+	saa7164_dump_busdesc(dev);
+}
+
+static int saa7164_pci_quirks(struct saa7164_dev *dev)
+{
+	return 0;
+}
+
+static int get_resources(struct saa7164_dev *dev)
+{
+	if (request_mem_region(pci_resource_start(dev->pci, 0),
+		pci_resource_len(dev->pci, 0), dev->name)) {
+
+		if (request_mem_region(pci_resource_start(dev->pci, 2),
+			pci_resource_len(dev->pci, 2), dev->name))
+			return 0;
+	}
+
+	printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
+		dev->name,
+		(u64)pci_resource_start(dev->pci, 0),
+		(u64)pci_resource_start(dev->pci, 2));
+
+	return -EBUSY;
+}
+
+static int saa7164_dev_setup(struct saa7164_dev *dev)
+{
+	int i;
+
+	mutex_init(&dev->lock);
+	atomic_inc(&dev->refcount);
+	dev->nr = saa7164_devcount++;
+
+	sprintf(dev->name, "saa7164[%d]", dev->nr);
+
+	mutex_lock(&devlist);
+	list_add_tail(&dev->devlist, &saa7164_devlist);
+	mutex_unlock(&devlist);
+
+	/* board config */
+	dev->board = UNSET;
+	if (card[dev->nr] < saa7164_bcount)
+		dev->board = card[dev->nr];
+
+	for (i = 0; UNSET == dev->board  &&  i < saa7164_idcount; i++)
+		if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
+			dev->pci->subsystem_device ==
+				saa7164_subids[i].subdevice)
+				dev->board = saa7164_subids[i].card;
+
+	if (UNSET == dev->board) {
+		dev->board = SAA7164_BOARD_UNKNOWN;
+		saa7164_card_list(dev);
+	}
+
+	dev->pci_bus  = dev->pci->bus->number;
+	dev->pci_slot = PCI_SLOT(dev->pci->devfn);
+
+	/* I2C Defaults / setup */
+	dev->i2c_bus[0].dev = dev;
+	dev->i2c_bus[0].nr = 0;
+	dev->i2c_bus[1].dev = dev;
+	dev->i2c_bus[1].nr = 1;
+	dev->i2c_bus[2].dev = dev;
+	dev->i2c_bus[2].nr = 2;
+
+	/* Transport port A Defaults / setup */
+	dev->ts1.dev = dev;
+	dev->ts1.nr = 0;
+	mutex_init(&dev->ts1.dvb.lock);
+	INIT_LIST_HEAD(&dev->ts1.dmaqueue.list);
+	INIT_LIST_HEAD(&dev->ts1.dummy_dmaqueue.list);
+	mutex_init(&dev->ts1.dmaqueue_lock);
+	mutex_init(&dev->ts1.dummy_dmaqueue_lock);
+
+	/* Transport port B Defaults / setup */
+	dev->ts2.dev = dev;
+	dev->ts2.nr = 1;
+	mutex_init(&dev->ts2.dvb.lock);
+	INIT_LIST_HEAD(&dev->ts2.dmaqueue.list);
+	INIT_LIST_HEAD(&dev->ts2.dummy_dmaqueue.list);
+	mutex_init(&dev->ts2.dmaqueue_lock);
+	mutex_init(&dev->ts2.dummy_dmaqueue_lock);
+
+	if (get_resources(dev) < 0) {
+		printk(KERN_ERR "CORE %s No more PCIe resources for "
+		       "subsystem: %04x:%04x\n",
+		       dev->name, dev->pci->subsystem_vendor,
+		       dev->pci->subsystem_device);
+
+		saa7164_devcount--;
+		return -ENODEV;
+	}
+
+	/* PCI/e allocations */
+	dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
+			     pci_resource_len(dev->pci, 0));
+
+	dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
+			     pci_resource_len(dev->pci, 2));
+
+	dev->bmmio = (u8 __iomem *)dev->lmmio;
+	dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
+
+	/* Inerrupt and ack register locations offset of bmmio */
+	dev->int_status = 0x183000 + 0xf80;
+	dev->int_ack = 0x183000 + 0xf90;
+
+	printk(KERN_INFO
+		"CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+	       dev->name, dev->pci->subsystem_vendor,
+	       dev->pci->subsystem_device, saa7164_boards[dev->board].name,
+	       dev->board, card[dev->nr] == dev->board ?
+	       "insmod option" : "autodetected");
+
+	saa7164_pci_quirks(dev);
+
+	return 0;
+}
+
+static void saa7164_dev_unregister(struct saa7164_dev *dev)
+{
+	dprintk(1, "%s()\n", __func__);
+
+	release_mem_region(pci_resource_start(dev->pci, 0),
+		pci_resource_len(dev->pci, 0));
+
+	release_mem_region(pci_resource_start(dev->pci, 2),
+		pci_resource_len(dev->pci, 2));
+
+	if (!atomic_dec_and_test(&dev->refcount))
+		return;
+
+	iounmap(dev->lmmio);
+	iounmap(dev->lmmio2);
+
+	return;
+}
+
+static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
+				     const struct pci_device_id *pci_id)
+{
+	struct saa7164_dev *dev;
+	int err, i;
+	u32 version;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (NULL == dev)
+		return -ENOMEM;
+
+	/* pci init */
+	dev->pci = pci_dev;
+	if (pci_enable_device(pci_dev)) {
+		err = -EIO;
+		goto fail_free;
+	}
+
+	if (saa7164_dev_setup(dev) < 0) {
+		err = -EINVAL;
+		goto fail_free;
+	}
+
+	/* print pci info */
+	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
+	printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
+	       "latency: %d, mmio: 0x%llx\n", dev->name,
+	       pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
+	       dev->pci_lat,
+		(unsigned long long)pci_resource_start(pci_dev, 0));
+
+	pci_set_master(pci_dev);
+	/* TODO */
+	if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+		printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
+		err = -EIO;
+		goto fail_irq;
+	}
+
+	err = request_irq(pci_dev->irq, saa7164_irq,
+		IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+	if (err < 0) {
+		printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
+			pci_dev->irq);
+		err = -EIO;
+		goto fail_irq;
+	}
+
+	pci_set_drvdata(pci_dev, dev);
+
+	/* Init the internal command list */
+	for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
+		dev->cmds[i].seqno = i;
+		dev->cmds[i].inuse = 0;
+		mutex_init(&dev->cmds[i].lock);
+		init_waitqueue_head(&dev->cmds[i].wait);
+	}
+
+	/* We need a deferred interrupt handler for cmd handling */
+	INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
+
+	/* Only load the firmware if we know the board */
+	if (dev->board != SAA7164_BOARD_UNKNOWN) {
+
+		err = saa7164_downloadfirmware(dev);
+		if (err < 0) {
+			printk(KERN_ERR
+				"Failed to boot firmware, no features "
+				"registered\n");
+			goto fail_fw;
+		}
+
+		saa7164_get_descriptors(dev);
+		saa7164_dumpregs(dev, 0);
+		saa7164_getcurrentfirmwareversion(dev);
+		saa7164_getfirmwarestatus(dev);
+		err = saa7164_bus_setup(dev);
+		if (err < 0)
+			printk(KERN_ERR
+				"Failed to setup the bus, will continue\n");
+		saa7164_bus_dump(dev);
+
+		/* Ping the running firmware via the command bus and get the
+		 * firmware version, this checks the bus is running OK.
+		 */
+		version = 0;
+		if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
+			dprintk(1, "Bus is operating correctly using "
+				"version %d.%d.%d.%d (0x%x)\n",
+				(version & 0x0000fc00) >> 10,
+				(version & 0x000003e0) >> 5,
+				(version & 0x0000001f),
+				(version & 0xffff0000) >> 16,
+				version);
+		else
+			printk(KERN_ERR
+				"Failed to communicate with the firmware\n");
+
+		/* Bring up the I2C buses */
+		saa7164_i2c_register(&dev->i2c_bus[0]);
+		saa7164_i2c_register(&dev->i2c_bus[1]);
+		saa7164_i2c_register(&dev->i2c_bus[2]);
+		saa7164_gpio_setup(dev);
+		saa7164_card_setup(dev);
+
+
+		/* Parse the dynamic device configuration, find various
+		 * media endpoints (MPEG, WMV, PS, TS) and cache their
+		 * configuration details into the driver, so we can
+		 * reference them later during simething_register() func,
+		 * interrupt handlers, deferred work handlers etc.
+		 */
+		saa7164_api_enum_subdevs(dev);
+
+		/* Begin to create the video sub-systems and register funcs */
+		if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
+			if (saa7164_dvb_register(&dev->ts1) < 0) {
+				printk(KERN_ERR "%s() Failed to register "
+					"dvb adapters on porta\n",
+					__func__);
+			}
+		}
+
+		if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
+			if (saa7164_dvb_register(&dev->ts2) < 0) {
+				printk(KERN_ERR"%s() Failed to register "
+					"dvb adapters on portb\n",
+					__func__);
+			}
+		}
+
+	} /* != BOARD_UNKNOWN */
+	else
+		printk(KERN_ERR "%s() Unsupported board detected, "
+			"registering without firmware\n", __func__);
+
+	dprintk(1, "%s() parameter debug = %d\n", __func__, debug);
+	dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
+
+fail_fw:
+	return 0;
+
+fail_irq:
+	saa7164_dev_unregister(dev);
+fail_free:
+	kfree(dev);
+	return err;
+}
+
+static void saa7164_shutdown(struct saa7164_dev *dev)
+{
+	dprintk(1, "%s()\n", __func__);
+}
+
+static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
+{
+	struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
+
+	saa7164_shutdown(dev);
+
+	if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
+		saa7164_dvb_unregister(&dev->ts1);
+
+	if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
+		saa7164_dvb_unregister(&dev->ts2);
+
+	saa7164_i2c_unregister(&dev->i2c_bus[0]);
+	saa7164_i2c_unregister(&dev->i2c_bus[1]);
+	saa7164_i2c_unregister(&dev->i2c_bus[2]);
+
+	pci_disable_device(pci_dev);
+
+	/* unregister stuff */
+	free_irq(pci_dev->irq, dev);
+	pci_set_drvdata(pci_dev, NULL);
+
+	mutex_lock(&devlist);
+	list_del(&dev->devlist);
+	mutex_unlock(&devlist);
+
+	saa7164_dev_unregister(dev);
+	kfree(dev);
+}
+
+static struct pci_device_id saa7164_pci_tbl[] = {
+	{
+		/* SAA7164 */
+		.vendor       = 0x1131,
+		.device       = 0x7164,
+		.subvendor    = PCI_ANY_ID,
+		.subdevice    = PCI_ANY_ID,
+	}, {
+		/* --- end of list --- */
+	}
+};
+MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
+
+static struct pci_driver saa7164_pci_driver = {
+	.name     = "saa7164",
+	.id_table = saa7164_pci_tbl,
+	.probe    = saa7164_initdev,
+	.remove   = __devexit_p(saa7164_finidev),
+	/* TODO */
+	.suspend  = NULL,
+	.resume   = NULL,
+};
+
+static int saa7164_init(void)
+{
+	printk(KERN_INFO "saa7164 driver loaded\n");
+	return pci_register_driver(&saa7164_pci_driver);
+}
+
+static void saa7164_fini(void)
+{
+	pci_unregister_driver(&saa7164_pci_driver);
+}
+
+module_init(saa7164_init);
+module_exit(saa7164_fini);
+
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
new file mode 100644
index 0000000..6a2d847
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -0,0 +1,602 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include "saa7164.h"
+
+#include "tda10048.h"
+#include "tda18271.h"
+#include "s5h1411.h"
+
+#define DRIVER_NAME "saa7164"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+/* addr is in the card struct, get it from there */
+static struct tda10048_config hauppauge_hvr2200_1_config = {
+	.demod_address    = 0x10 >> 1,
+	.output_mode      = TDA10048_SERIAL_OUTPUT,
+	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
+	.inversion        = TDA10048_INVERSION_ON,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3500,
+	.dtv8_if_freq_khz = TDA10048_IF_4000,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+};
+static struct tda10048_config hauppauge_hvr2200_2_config = {
+	.demod_address    = 0x12 >> 1,
+	.output_mode      = TDA10048_SERIAL_OUTPUT,
+	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
+	.inversion        = TDA10048_INVERSION_ON,
+	.dtv6_if_freq_khz = TDA10048_IF_3300,
+	.dtv7_if_freq_khz = TDA10048_IF_3500,
+	.dtv8_if_freq_khz = TDA10048_IF_4000,
+	.clk_freq_khz     = TDA10048_CLK_16000,
+};
+
+static struct tda18271_std_map hauppauge_tda18271_std_map = {
+	.atsc_6   = { .if_freq = 3250, .agc_mode = 3, .std = 3,
+		      .if_lvl = 6, .rfagc_top = 0x37 },
+	.qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 0,
+		      .if_lvl = 6, .rfagc_top = 0x37 },
+};
+
+static struct tda18271_config hauppauge_hvr22x0_tuner_config = {
+	.std_map	= &hauppauge_tda18271_std_map,
+	.gate		= TDA18271_GATE_ANALOG,
+	.role		= TDA18271_MASTER,
+};
+
+static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
+	.std_map	= &hauppauge_tda18271_std_map,
+	.gate		= TDA18271_GATE_ANALOG,
+	.role		= TDA18271_SLAVE,
+	.rf_cal_on_startup = 1
+};
+
+static struct s5h1411_config hauppauge_s5h1411_config = {
+	.output_mode   = S5H1411_SERIAL_OUTPUT,
+	.gpio          = S5H1411_GPIO_ON,
+	.qam_if        = S5H1411_IF_4000,
+	.vsb_if        = S5H1411_IF_3250,
+	.inversion     = S5H1411_INVERSION_ON,
+	.status_mode   = S5H1411_DEMODLOCKING,
+	.mpeg_timing   = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
+static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port)
+{
+	struct saa7164_dev *dev = port->dev;
+	int ret;
+
+	ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
+		printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
+			__func__, ret);
+		ret = -EIO;
+	} else {
+		dprintk(DBGLVL_DVB, "%s()    Stopped\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port)
+{
+	struct saa7164_dev *dev = port->dev;
+	int ret;
+
+	ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
+	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
+		printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
+			__func__, ret);
+		ret = -EIO;
+	} else {
+		dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port)
+{
+	struct saa7164_dev *dev = port->dev;
+	int ret;
+
+	ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
+	if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
+		printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
+			__func__, ret);
+		ret = -EIO;
+	} else {
+		dprintk(DBGLVL_DVB, "%s()   Paused\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+/* Firmware is very windows centric, meaning you have to transition
+ * the part through AVStream / KS Windows stages, forwards or backwards.
+ * States are: stopped, acquired (h/w), paused, started.
+ */
+static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port)
+{
+	struct saa7164_dev *dev = port->dev;
+	int ret;
+
+	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+	ret = saa7164_dvb_pause_tsport(port);
+	ret = saa7164_dvb_acquire_tsport(port);
+	ret = saa7164_dvb_stop_tsport(port);
+
+	return ret;
+}
+
+static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port)
+{
+	tmHWStreamParameters_t *params = &port->hw_streamingparams;
+	struct saa7164_dev *dev = port->dev;
+	struct saa7164_buffer *buf;
+	struct list_head *c, *n;
+	int i = 0;
+
+	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+	saa7164_writel(port->pitch, params->pitch);
+	saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
+
+	dprintk(DBGLVL_DVB, " configured:\n");
+	dprintk(DBGLVL_DVB, "   lmmio       0x%p\n", dev->lmmio);
+	dprintk(DBGLVL_DVB, "   bufcounter  0x%x = 0x%x\n", port->bufcounter,
+		saa7164_readl(port->bufcounter));
+
+	dprintk(DBGLVL_DVB, "   pitch       0x%x = %d\n", port->pitch,
+		saa7164_readl(port->pitch));
+
+	dprintk(DBGLVL_DVB, "   bufsize     0x%x = %d\n", port->bufsize,
+		saa7164_readl(port->bufsize));
+
+	dprintk(DBGLVL_DVB, "   buffercount = %d\n", port->hwcfg.buffercount);
+	dprintk(DBGLVL_DVB, "   bufoffset = 0x%x\n", port->bufoffset);
+	dprintk(DBGLVL_DVB, "   bufptr32h = 0x%x\n", port->bufptr32h);
+	dprintk(DBGLVL_DVB, "   bufptr32l = 0x%x\n", port->bufptr32l);
+
+	/* Poke the buffers and offsets into PCI space */
+	mutex_lock(&port->dmaqueue_lock);
+	list_for_each_safe(c, n, &port->dmaqueue.list) {
+		buf = list_entry(c, struct saa7164_buffer, list);
+
+		/* TODO: Review this in light of 32v64 assignments */
+		saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
+		saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i),
+			buf->pt_dma);
+		saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
+
+		dprintk(DBGLVL_DVB,
+			"   buf[%d] offset 0x%llx (0x%x) "
+			"buf 0x%llx/%llx (0x%x/%x)\n",
+			i,
+			(u64)port->bufoffset + (i * sizeof(u32)),
+			saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
+			(u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
+			(u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
+			saa7164_readl(port->bufptr32h + ((sizeof(u32) * i)
+				* 2)),
+			saa7164_readl(port->bufptr32l + ((sizeof(u32) * i)
+				* 2)));
+
+		if (i++ > port->hwcfg.buffercount)
+			BUG();
+
+	}
+	mutex_unlock(&port->dmaqueue_lock);
+
+	return 0;
+}
+
+static int saa7164_dvb_start_tsport(struct saa7164_tsport *port)
+{
+	struct saa7164_dev *dev = port->dev;
+	int ret = 0, result;
+
+	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+	saa7164_dvb_cfg_tsport(port);
+
+	/* Acquire the hardware */
+	result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
+	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+		printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
+			__func__, result);
+
+		/* Stop the hardware, regardless */
+		result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+			printk(KERN_ERR "%s() acquire/forced stop transition "
+				"failed, res = 0x%x\n", __func__, result);
+		}
+		ret = -EIO;
+		goto out;
+	} else
+		dprintk(DBGLVL_DVB, "%s()   Acquired\n", __func__);
+
+	/* Pause the hardware */
+	result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
+	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+		printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
+				__func__, result);
+
+		/* Stop the hardware, regardless */
+		result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+			printk(KERN_ERR "%s() pause/forced stop transition "
+				"failed, res = 0x%x\n", __func__, result);
+		}
+
+		ret = -EIO;
+		goto out;
+	} else
+		dprintk(DBGLVL_DVB, "%s()   Paused\n", __func__);
+
+	/* Start the hardware */
+	result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
+	if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+		printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
+				__func__, result);
+
+		/* Stop the hardware, regardless */
+		result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
+		if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
+			printk(KERN_ERR "%s() run/forced stop transition "
+				"failed, res = 0x%x\n", __func__, result);
+		}
+
+		ret = -EIO;
+	} else
+		dprintk(DBGLVL_DVB, "%s()   Running\n", __func__);
+
+out:
+	return ret;
+}
+
+static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
+{
+	struct dvb_demux *demux = feed->demux;
+	struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
+	struct saa7164_dvb *dvb = &port->dvb;
+	struct saa7164_dev *dev = port->dev;
+	int ret = 0;
+
+	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+	if (!demux->dmx.frontend)
+		return -EINVAL;
+
+	if (dvb) {
+		mutex_lock(&dvb->lock);
+		if (dvb->feeding++ == 0) {
+			/* Start transport */
+			ret = saa7164_dvb_start_tsport(port);
+		}
+		mutex_unlock(&dvb->lock);
+		dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
+			__func__, port->nr, dvb->feeding);
+	}
+
+	return ret;
+}
+
+static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
+{
+	struct dvb_demux *demux = feed->demux;
+	struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
+	struct saa7164_dvb *dvb = &port->dvb;
+	struct saa7164_dev *dev = port->dev;
+	int ret = 0;
+
+	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+	if (dvb) {
+		mutex_lock(&dvb->lock);
+		if (--dvb->feeding == 0) {
+			/* Stop transport */
+			ret = saa7164_dvb_stop_streaming(port);
+		}
+		mutex_unlock(&dvb->lock);
+		dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
+			__func__, port->nr, dvb->feeding);
+	}
+
+	return ret;
+}
+
+static int dvb_register(struct saa7164_tsport *port)
+{
+	struct saa7164_dvb *dvb = &port->dvb;
+	struct saa7164_dev *dev = port->dev;
+	struct saa7164_buffer *buf;
+	int result, i;
+
+	dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
+
+	/* Sanity check that the PCI configuration space is active */
+	if (port->hwcfg.BARLocation == 0) {
+		result = -ENOMEM;
+		printk(KERN_ERR "%s: dvb_register_adapter failed "
+		       "(errno = %d), NO PCI configuration\n",
+			DRIVER_NAME, result);
+		goto fail_adapter;
+	}
+
+	/* Init and establish defaults */
+	port->hw_streamingparams.bitspersample = 8;
+	port->hw_streamingparams.samplesperline = 188;
+	port->hw_streamingparams.numberoflines =
+		(SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
+
+	port->hw_streamingparams.pitch = 188;
+	port->hw_streamingparams.linethreshold = 0;
+	port->hw_streamingparams.pagetablelistvirt = 0;
+	port->hw_streamingparams.pagetablelistphys = 0;
+	port->hw_streamingparams.numpagetables = 2 +
+		((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
+
+	port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
+
+	/* Allocate the PCI resources */
+	for (i = 0; i < port->hwcfg.buffercount; i++) {
+		buf = saa7164_buffer_alloc(port,
+			port->hw_streamingparams.numberoflines *
+			port->hw_streamingparams.pitch);
+
+		if (!buf) {
+			result = -ENOMEM;
+			printk(KERN_ERR "%s: dvb_register_adapter failed "
+			       "(errno = %d), unable to allocate buffers\n",
+				DRIVER_NAME, result);
+			goto fail_adapter;
+		}
+		buf->nr = i;
+
+		mutex_lock(&port->dmaqueue_lock);
+		list_add_tail(&buf->list, &port->dmaqueue.list);
+		mutex_unlock(&port->dmaqueue_lock);
+	}
+
+	/* register adapter */
+	result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
+			&dev->pci->dev, adapter_nr);
+	if (result < 0) {
+		printk(KERN_ERR "%s: dvb_register_adapter failed "
+		       "(errno = %d)\n", DRIVER_NAME, result);
+		goto fail_adapter;
+	}
+	dvb->adapter.priv = port;
+
+	/* register frontend */
+	result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+	if (result < 0) {
+		printk(KERN_ERR "%s: dvb_register_frontend failed "
+		       "(errno = %d)\n", DRIVER_NAME, result);
+		goto fail_frontend;
+	}
+
+	/* register demux stuff */
+	dvb->demux.dmx.capabilities =
+		DMX_TS_FILTERING | DMX_SECTION_FILTERING |
+		DMX_MEMORY_BASED_FILTERING;
+	dvb->demux.priv       = port;
+	dvb->demux.filternum  = 256;
+	dvb->demux.feednum    = 256;
+	dvb->demux.start_feed = saa7164_dvb_start_feed;
+	dvb->demux.stop_feed  = saa7164_dvb_stop_feed;
+	result = dvb_dmx_init(&dvb->demux);
+	if (result < 0) {
+		printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
+		       DRIVER_NAME, result);
+		goto fail_dmx;
+	}
+
+	dvb->dmxdev.filternum    = 256;
+	dvb->dmxdev.demux        = &dvb->demux.dmx;
+	dvb->dmxdev.capabilities = 0;
+	result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
+	if (result < 0) {
+		printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
+		       DRIVER_NAME, result);
+		goto fail_dmxdev;
+	}
+
+	dvb->fe_hw.source = DMX_FRONTEND_0;
+	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	if (result < 0) {
+		printk(KERN_ERR "%s: add_frontend failed "
+		       "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
+		goto fail_fe_hw;
+	}
+
+	dvb->fe_mem.source = DMX_MEMORY_FE;
+	result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+	if (result < 0) {
+		printk(KERN_ERR "%s: add_frontend failed "
+		       "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
+		goto fail_fe_mem;
+	}
+
+	result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	if (result < 0) {
+		printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
+		       DRIVER_NAME, result);
+		goto fail_fe_conn;
+	}
+
+	/* register network adapter */
+	dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+	return 0;
+
+fail_fe_conn:
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+fail_fe_mem:
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+fail_fe_hw:
+	dvb_dmxdev_release(&dvb->dmxdev);
+fail_dmxdev:
+	dvb_dmx_release(&dvb->demux);
+fail_dmx:
+	dvb_unregister_frontend(dvb->frontend);
+fail_frontend:
+	dvb_frontend_detach(dvb->frontend);
+	dvb_unregister_adapter(&dvb->adapter);
+fail_adapter:
+	return result;
+}
+
+int saa7164_dvb_unregister(struct saa7164_tsport *port)
+{
+	struct saa7164_dvb *dvb = &port->dvb;
+	struct saa7164_dev *dev = port->dev;
+	struct saa7164_buffer *b;
+	struct list_head *c, *n;
+
+	dprintk(DBGLVL_DVB, "%s()\n", __func__);
+
+	/* Remove any allocated buffers */
+	mutex_lock(&port->dmaqueue_lock);
+	list_for_each_safe(c, n, &port->dmaqueue.list) {
+		b = list_entry(c, struct saa7164_buffer, list);
+		list_del(c);
+		saa7164_buffer_dealloc(port, b);
+	}
+	mutex_unlock(&port->dmaqueue_lock);
+
+	if (dvb->frontend == NULL)
+		return 0;
+
+	dvb_net_release(&dvb->net);
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
+	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
+	dvb_dmxdev_release(&dvb->dmxdev);
+	dvb_dmx_release(&dvb->demux);
+	dvb_unregister_frontend(dvb->frontend);
+	dvb_frontend_detach(dvb->frontend);
+	dvb_unregister_adapter(&dvb->adapter);
+	return 0;
+}
+
+/* All the DVB attach calls go here, this function get's modified
+ * for each new card.
+ */
+int saa7164_dvb_register(struct saa7164_tsport *port)
+{
+	struct saa7164_dev *dev = port->dev;
+	struct saa7164_dvb *dvb = &port->dvb;
+	struct saa7164_i2c *i2c_bus = NULL;
+	int ret;
+
+	dprintk(DBGLVL_DVB, "%s()\n", __func__);
+
+	/* init frontend */
+	switch (dev->board) {
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
+		i2c_bus = &dev->i2c_bus[port->nr + 1];
+		switch (port->nr) {
+		case 0:
+			port->dvb.frontend = dvb_attach(tda10048_attach,
+				&hauppauge_hvr2200_1_config,
+				&i2c_bus->i2c_adap);
+
+			if (port->dvb.frontend != NULL) {
+				/* TODO: addr is in the card struct */
+				dvb_attach(tda18271_attach, port->dvb.frontend,
+					0xc0 >> 1, &i2c_bus->i2c_adap,
+					&hauppauge_hvr22x0_tuner_config);
+			}
+
+			break;
+		case 1:
+			port->dvb.frontend = dvb_attach(tda10048_attach,
+				&hauppauge_hvr2200_2_config,
+				&i2c_bus->i2c_adap);
+
+			if (port->dvb.frontend != NULL) {
+				/* TODO: addr is in the card struct */
+				dvb_attach(tda18271_attach, port->dvb.frontend,
+					0xc0 >> 1, &i2c_bus->i2c_adap,
+					&hauppauge_hvr22x0s_tuner_config);
+			}
+
+			break;
+		}
+		break;
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
+	case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
+		i2c_bus = &dev->i2c_bus[port->nr + 1];
+
+		port->dvb.frontend = dvb_attach(s5h1411_attach,
+			&hauppauge_s5h1411_config,
+			&i2c_bus->i2c_adap);
+
+		if (port->dvb.frontend != NULL) {
+			if (port->nr == 0) {
+				/* Master TDA18271 */
+				/* TODO: addr is in the card struct */
+				dvb_attach(tda18271_attach, port->dvb.frontend,
+					0xc0 >> 1, &i2c_bus->i2c_adap,
+					&hauppauge_hvr22x0_tuner_config);
+			} else {
+				/* Slave TDA18271 */
+				dvb_attach(tda18271_attach, port->dvb.frontend,
+					0xc0 >> 1, &i2c_bus->i2c_adap,
+					&hauppauge_hvr22x0s_tuner_config);
+			}
+		}
+
+		break;
+	default:
+		printk(KERN_ERR "%s: The frontend isn't supported\n",
+		       dev->name);
+		break;
+	}
+	if (NULL == dvb->frontend) {
+		printk(KERN_ERR "%s() Frontend initialization failed\n",
+		       __func__);
+		return -1;
+	}
+
+	/* Put the analog decoder in standby to keep it quiet */
+
+	/* register everything */
+	ret = dvb_register(port);
+	if (ret < 0) {
+		if (dvb->frontend->ops.release)
+			dvb->frontend->ops.release(dvb->frontend);
+		return ret;
+	}
+
+	return 0;
+}
+
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
new file mode 100644
index 0000000..ee0af35
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -0,0 +1,613 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include <linux/firmware.h>
+
+#include "saa7164.h"
+
+#define SAA7164_REV2_FIRMWARE		"v4l-saa7164-1.0.2.fw"
+#define SAA7164_REV2_FIRMWARE_SIZE	3978608
+
+#define SAA7164_REV3_FIRMWARE		"v4l-saa7164-1.0.3.fw"
+#define SAA7164_REV3_FIRMWARE_SIZE	3978608
+
+struct fw_header {
+	u32	firmwaresize;
+	u32	bslsize;
+	u32	reserved;
+	u32	version;
+};
+
+int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
+{
+	u32 timeout = SAA_DEVICE_TIMEOUT;
+	while ((saa7164_readl(reg) & 0x01) == 0) {
+		timeout -= 10;
+		if (timeout == 0) {
+			printk(KERN_ERR "%s() timeout (no d/l ack)\n",
+				__func__);
+			return -EBUSY;
+		}
+		msleep(100);
+	}
+
+	return 0;
+}
+
+int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
+{
+	u32 timeout = SAA_DEVICE_TIMEOUT;
+	while (saa7164_readl(reg) & 0x01) {
+		timeout -= 10;
+		if (timeout == 0) {
+			printk(KERN_ERR "%s() timeout (no d/l clr)\n",
+				__func__);
+			return -EBUSY;
+		}
+		msleep(100);
+	}
+
+	return 0;
+}
+
+/* TODO: move dlflags into dev-> and change to write/readl/b */
+/* TODO: Excessive levels of debug */
+int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
+	u32 dlflags, u8 *dst, u32 dstsize)
+{
+	u32 reg, timeout, offset;
+	u8 *srcbuf = NULL;
+	int ret;
+
+	u32 dlflag = dlflags;
+	u32 dlflag_ack = dlflag + 4;
+	u32 drflag = dlflag_ack + 4;
+	u32 drflag_ack = drflag + 4;
+	u32 bleflag = drflag_ack + 4;
+
+	dprintk(DBGLVL_FW,
+		"%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
+		__func__, src, srcsize, dlflags, dst, dstsize);
+
+	if ((src == 0) || (dst == 0)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
+	if (NULL == srcbuf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (srcsize > (4*1048576)) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(srcbuf, src, srcsize);
+
+	dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
+	dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
+	dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
+	dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
+	dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);
+
+	reg = saa7164_readl(dlflag);
+	dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
+	if (reg == 1)
+		dprintk(DBGLVL_FW,
+			"%s() Download flag already set, please reboot\n",
+			__func__);
+
+	/* Indicate download start */
+	saa7164_writel(dlflag, 1);
+	ret = saa7164_dl_wait_ack(dev, dlflag_ack);
+	if (ret < 0)
+		goto out;
+
+	/* Ack download start, then wait for wait */
+	saa7164_writel(dlflag, 0);
+	ret = saa7164_dl_wait_clr(dev, dlflag_ack);
+	if (ret < 0)
+		goto out;
+
+	/* Deal with the raw firmware, in the appropriate chunk size */
+	for (offset = 0; srcsize > dstsize;
+		srcsize -= dstsize, offset += dstsize) {
+
+		dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize);
+		memcpy(dst, srcbuf + offset, dstsize);
+
+		/* Flag the data as ready */
+		saa7164_writel(drflag, 1);
+		ret = saa7164_dl_wait_ack(dev, drflag_ack);
+		if (ret < 0)
+			goto out;
+
+		/* Wait for indication data was received */
+		saa7164_writel(drflag, 0);
+		ret = saa7164_dl_wait_clr(dev, drflag_ack);
+		if (ret < 0)
+			goto out;
+
+	}
+
+	dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize);
+	/* Write last block to the device */
+	memcpy(dst, srcbuf+offset, srcsize);
+
+	/* Flag the data as ready */
+	saa7164_writel(drflag, 1);
+	ret = saa7164_dl_wait_ack(dev, drflag_ack);
+	if (ret < 0)
+		goto out;
+
+	saa7164_writel(drflag, 0);
+	timeout = 0;
+	while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) {
+		if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) {
+			printk(KERN_ERR "%s() image corrupt\n", __func__);
+			ret = -EBUSY;
+			goto out;
+		}
+
+		if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) {
+			printk(KERN_ERR "%s() device memory corrupt\n",
+				__func__);
+			ret = -EBUSY;
+			goto out;
+		}
+
+		msleep(10);
+		if (timeout++ > 60)
+			break;
+	}
+
+	printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__);
+
+	ret = saa7164_dl_wait_clr(dev, drflag_ack);
+	if (ret < 0)
+		goto out;
+
+	printk(KERN_INFO "%s() Image booted successfully.\n", __func__);
+	ret = 0;
+
+out:
+	kfree(srcbuf);
+	return ret;
+}
+
+/* TODO: Excessive debug */
+/* Load the firmware. Optionally it can be in ROM or newer versions
+ * can be on disk, saving the expense of the ROM hardware. */
+int saa7164_downloadfirmware(struct saa7164_dev *dev)
+{
+	/* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */
+	u32 tmp, filesize, version, err_flags, first_timeout, fwlength;
+	u32 second_timeout, updatebootloader = 1, bootloadersize = 0;
+	const struct firmware *fw = NULL;
+	struct fw_header *hdr, *boothdr = NULL, *fwhdr;
+	u32 bootloaderversion = 0, fwloadersize;
+	u8 *bootloaderoffset = NULL, *fwloaderoffset;
+	char *fwname;
+	int ret;
+
+	dprintk(DBGLVL_FW, "%s()\n", __func__);
+
+	if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) {
+		fwname = SAA7164_REV2_FIRMWARE;
+		fwlength = SAA7164_REV2_FIRMWARE_SIZE;
+	} else {
+		fwname = SAA7164_REV3_FIRMWARE;
+		fwlength = SAA7164_REV3_FIRMWARE_SIZE;
+	}
+
+	version = saa7164_getcurrentfirmwareversion(dev);
+
+	if (version == 0x00) {
+
+		second_timeout = 100;
+		first_timeout = 100;
+		err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
+		dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
+			__func__, err_flags);
+
+		while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
+			dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
+				__func__, err_flags);
+			msleep(10);
+
+			if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
+				printk(KERN_ERR "%s() firmware corrupt\n",
+					__func__);
+				break;
+			}
+			if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
+				printk(KERN_ERR "%s() device memory corrupt\n",
+					__func__);
+				break;
+			}
+			if (err_flags & SAA_DEVICE_NO_IMAGE) {
+				printk(KERN_ERR "%s() no first image\n",
+				__func__);
+				break;
+			}
+			if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
+				first_timeout -= 10;
+				if (first_timeout == 0) {
+					printk(KERN_ERR
+						"%s() no first image\n",
+						__func__);
+					break;
+				}
+			} else if (err_flags & SAA_DEVICE_IMAGE_LOADING) {
+				second_timeout -= 10;
+				if (second_timeout == 0) {
+					printk(KERN_ERR
+					"%s() FW load time exceeded\n",
+						__func__);
+					break;
+				}
+			} else {
+				second_timeout -= 10;
+				if (second_timeout == 0) {
+					printk(KERN_ERR
+					"%s() Unknown bootloader flags 0x%x\n",
+						__func__, err_flags);
+					break;
+				}
+			}
+
+			err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
+		} /* While != Booting */
+
+		if (err_flags == SAA_DEVICE_IMAGE_BOOTING) {
+			dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n",
+				__func__);
+			first_timeout = SAA_DEVICE_TIMEOUT;
+			second_timeout = 60 * SAA_DEVICE_TIMEOUT;
+			second_timeout = 100;
+
+			err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
+			dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
+				__func__, err_flags);
+			while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
+				dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
+					__func__, err_flags);
+				msleep(10);
+
+				if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
+					printk(KERN_ERR
+						"%s() firmware corrupt\n",
+						__func__);
+					break;
+				}
+				if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
+					printk(KERN_ERR
+						"%s() device memory corrupt\n",
+						__func__);
+					break;
+				}
+				if (err_flags & SAA_DEVICE_NO_IMAGE) {
+					printk(KERN_ERR "%s() no first image\n",
+						__func__);
+					break;
+				}
+				if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
+					first_timeout -= 10;
+					if (first_timeout == 0) {
+						printk(KERN_ERR
+						"%s() no second image\n",
+							__func__);
+						break;
+					}
+				} else if (err_flags &
+					SAA_DEVICE_IMAGE_LOADING) {
+					second_timeout -= 10;
+					if (second_timeout == 0) {
+						printk(KERN_ERR
+						"%s() FW load time exceeded\n",
+							__func__);
+						break;
+					}
+				} else {
+					second_timeout -= 10;
+					if (second_timeout == 0) {
+						printk(KERN_ERR
+					"%s() Unknown bootloader flags 0x%x\n",
+							__func__, err_flags);
+						break;
+					}
+				}
+
+				err_flags =
+				saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
+			} /* err_flags != SAA_DEVICE_IMAGE_BOOTING */
+
+			dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n",
+				__func__,
+				saa7164_readl(SAA_BOOTLOADERERROR_FLAGS),
+				saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS));
+
+		} /* err_flags == SAA_DEVICE_IMAGE_BOOTING */
+
+		/* It's possible for both firmwares to have booted,
+		 * but that doesn't mean they've finished booting yet.
+		 */
+		if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
+			SAA_DEVICE_IMAGE_BOOTING) &&
+			(saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
+			SAA_DEVICE_IMAGE_BOOTING)) {
+
+
+			dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n",
+				__func__);
+
+			first_timeout = SAA_DEVICE_TIMEOUT;
+			while (first_timeout) {
+				msleep(10);
+
+				version =
+					saa7164_getcurrentfirmwareversion(dev);
+				if (version) {
+					dprintk(DBGLVL_FW,
+					"%s() All f/w loaded successfully\n",
+						__func__);
+					break;
+				} else {
+					first_timeout -= 10;
+					if (first_timeout == 0) {
+						printk(KERN_ERR
+						"%s() FW did not boot\n",
+							__func__);
+						break;
+					}
+				}
+			}
+		}
+		version = saa7164_getcurrentfirmwareversion(dev);
+	} /* version == 0 */
+
+	/* Has the firmware really booted? */
+	if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
+		SAA_DEVICE_IMAGE_BOOTING) &&
+		(saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
+		SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) {
+
+		printk(KERN_ERR
+			"%s() The firmware hung, probably bad firmware\n",
+			__func__);
+
+		/* Tell the second stage loader we have a deadlock */
+		saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET,
+			SAA_DEVICE_DEADLOCK_DETECTED);
+
+		saa7164_getfirmwarestatus(dev);
+
+		return -ENOMEM;
+	}
+
+	dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n",
+		(version & 0x0000fc00) >> 10,
+		(version & 0x000003e0) >> 5,
+		(version & 0x0000001f),
+		(version & 0xffff0000) >> 16);
+
+	/* Load the firmwware from the disk if required */
+	if (version == 0) {
+
+		printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n",
+			__func__, fwname);
+
+		ret = request_firmware(&fw, fwname, &dev->pci->dev);
+		if (ret) {
+			printk(KERN_ERR "%s() Upload failed. "
+				"(file not found?)\n", __func__);
+			return -ENOMEM;
+		}
+
+		printk(KERN_INFO "%s() firmware read %Zu bytes.\n",
+			__func__, fw->size);
+
+		if (fw->size != fwlength) {
+			printk(KERN_ERR "xc5000: firmware incorrect size\n");
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		printk(KERN_INFO "%s() firmware loaded.\n", __func__);
+
+		hdr = (struct fw_header *)fw->data;
+		printk(KERN_INFO "Firmware file header part 1:\n");
+		printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize);
+		printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize);
+		printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved);
+		printk(KERN_INFO " .Version = 0x%x\n", hdr->version);
+
+		/* Retreive bootloader if reqd */
+		if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0))
+			/* Second bootloader in the firmware file */
+			filesize = hdr->reserved * 16;
+		else
+			filesize = (hdr->firmwaresize + hdr->bslsize) *
+				16 + sizeof(struct fw_header);
+
+		printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n",
+			__func__, filesize);
+
+		/* Get bootloader (if reqd) and firmware header */
+		if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
+			/* Second boot loader is required */
+
+			/* Get the loader header */
+			boothdr = (struct fw_header *)(fw->data +
+				sizeof(struct fw_header));
+
+			bootloaderversion =
+				saa7164_readl(SAA_DEVICE_2ND_VERSION);
+			dprintk(DBGLVL_FW, "Onboard BootLoader:\n");
+			dprintk(DBGLVL_FW, "->Flag 0x%x\n",
+				saa7164_readl(SAA_BOOTLOADERERROR_FLAGS));
+			dprintk(DBGLVL_FW, "->Ack 0x%x\n",
+				saa7164_readl(SAA_DATAREADY_FLAG_ACK));
+			dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version);
+			dprintk(DBGLVL_FW, "->Loader Version 0x%x\n",
+				bootloaderversion);
+
+			if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
+				0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK)
+				== 0x00) && (version == 0x00)) {
+
+				dprintk(DBGLVL_FW, "BootLoader version in  "
+					"rom %d.%d.%d.%d\n",
+					(bootloaderversion & 0x0000fc00) >> 10,
+					(bootloaderversion & 0x000003e0) >> 5,
+					(bootloaderversion & 0x0000001f),
+					(bootloaderversion & 0xffff0000) >> 16
+					);
+				dprintk(DBGLVL_FW, "BootLoader version "
+					"in file %d.%d.%d.%d\n",
+					(boothdr->version & 0x0000fc00) >> 10,
+					(boothdr->version & 0x000003e0) >> 5,
+					(boothdr->version & 0x0000001f),
+					(boothdr->version & 0xffff0000) >> 16
+					);
+
+				if (bootloaderversion == boothdr->version)
+					updatebootloader = 0;
+			}
+
+			/* Calculate offset to firmware header */
+			tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 +
+				(sizeof(struct fw_header) +
+				sizeof(struct fw_header));
+
+			fwhdr = (struct fw_header *)(fw->data+tmp);
+		} else {
+			/* No second boot loader */
+			fwhdr = hdr;
+		}
+
+		dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n",
+			(fwhdr->version & 0x0000fc00) >> 10,
+			(fwhdr->version & 0x000003e0) >> 5,
+			(fwhdr->version & 0x0000001f),
+			(fwhdr->version & 0xffff0000) >> 16
+			);
+
+		if (version == fwhdr->version) {
+			/* No download, firmware already on board */
+			ret = 0;
+			goto out;
+		}
+
+		if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
+			if (updatebootloader) {
+				/* Get ready to upload the bootloader */
+				bootloadersize = (boothdr->firmwaresize +
+					boothdr->bslsize) * 16 +
+					sizeof(struct fw_header);
+
+				bootloaderoffset = (u8 *)(fw->data +
+					sizeof(struct fw_header));
+
+				dprintk(DBGLVL_FW, "bootloader d/l starts.\n");
+				printk(KERN_INFO "%s() FirmwareSize = 0x%x\n",
+					__func__, boothdr->firmwaresize);
+				printk(KERN_INFO "%s() BSLSize = 0x%x\n",
+					__func__, boothdr->bslsize);
+				printk(KERN_INFO "%s() Reserved = 0x%x\n",
+					__func__, boothdr->reserved);
+				printk(KERN_INFO "%s() Version = 0x%x\n",
+					__func__, boothdr->version);
+				ret = saa7164_downloadimage(
+					dev,
+					bootloaderoffset,
+					bootloadersize,
+					SAA_DOWNLOAD_FLAGS,
+					dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
+					SAA_DEVICE_BUFFERBLOCKSIZE);
+				if (ret < 0) {
+					printk(KERN_ERR
+						"bootloader d/l has failed\n");
+					goto out;
+				}
+				dprintk(DBGLVL_FW,
+					"bootloader download complete.\n");
+
+			}
+
+			printk(KERN_ERR "starting firmware download(2)\n");
+			bootloadersize = (boothdr->firmwaresize +
+				boothdr->bslsize) * 16 +
+				sizeof(struct fw_header);
+
+			bootloaderoffset =
+				(u8 *)(fw->data + sizeof(struct fw_header));
+
+			fwloaderoffset = bootloaderoffset + bootloadersize;
+
+			/* TODO: fix this bounds overrun here with old f/ws */
+			fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) *
+				16 + sizeof(struct fw_header);
+
+			ret = saa7164_downloadimage(
+				dev,
+				fwloaderoffset,
+				fwloadersize,
+				SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET,
+				dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET,
+				SAA_DEVICE_2ND_BUFFERBLOCKSIZE);
+			if (ret < 0) {
+				printk(KERN_ERR "firmware download failed\n");
+				goto out;
+			}
+			printk(KERN_ERR "firmware download complete.\n");
+
+		} else {
+
+			/* No bootloader update reqd, download firmware only */
+			printk(KERN_ERR "starting firmware download(3)\n");
+
+			ret = saa7164_downloadimage(
+				dev,
+				(u8 *)fw->data,
+				fw->size,
+				SAA_DOWNLOAD_FLAGS,
+				dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
+				SAA_DEVICE_BUFFERBLOCKSIZE);
+			if (ret < 0) {
+				printk(KERN_ERR "firmware download failed\n");
+				goto out;
+			}
+			printk(KERN_ERR "firmware download complete.\n");
+		}
+	}
+
+	ret = 0;
+
+out:
+	if (fw)
+		release_firmware(fw);
+
+	return ret;
+}
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
new file mode 100644
index 0000000..e1ae9b0
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-i2c.c
@@ -0,0 +1,141 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include "saa7164.h"
+
+static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
+{
+	struct saa7164_i2c *bus = i2c_adap->algo_data;
+	struct saa7164_dev *dev = bus->dev;
+	int i, retval = 0;
+
+	dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);
+
+	for (i = 0 ; i < num; i++) {
+		dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x  len = 0x%x\n",
+			__func__, num, msgs[i].addr, msgs[i].len);
+		if (msgs[i].flags & I2C_M_RD) {
+			/* Unsupported - Yet*/
+			printk(KERN_ERR "%s() Unsupported - Yet\n", __func__);
+			continue;
+		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
+			   msgs[i].addr == msgs[i + 1].addr) {
+			/* write then read from same address */
+
+			retval = saa7164_api_i2c_read(bus, msgs[i].addr,
+				msgs[i].len, msgs[i].buf,
+				msgs[i+1].len, msgs[i+1].buf
+				);
+
+			i++;
+
+			if (retval < 0)
+				goto err;
+		} else {
+			/* write */
+			retval = saa7164_api_i2c_write(bus, msgs[i].addr,
+				msgs[i].len, msgs[i].buf);
+		}
+		if (retval < 0)
+			goto err;
+	}
+	return num;
+
+ err:
+	return retval;
+}
+
+void saa7164_call_i2c_clients(struct saa7164_i2c *bus, unsigned int cmd,
+	void *arg)
+{
+	if (bus->i2c_rc != 0)
+		return;
+
+	i2c_clients_command(&bus->i2c_adap, cmd, arg);
+}
+
+static u32 saa7164_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm saa7164_i2c_algo_template = {
+	.master_xfer	= i2c_xfer,
+	.functionality	= saa7164_functionality,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_adapter saa7164_i2c_adap_template = {
+	.name              = "saa7164",
+	.owner             = THIS_MODULE,
+	.algo              = &saa7164_i2c_algo_template,
+};
+
+static struct i2c_client saa7164_i2c_client_template = {
+	.name	= "saa7164 internal",
+};
+
+int saa7164_i2c_register(struct saa7164_i2c *bus)
+{
+	struct saa7164_dev *dev = bus->dev;
+
+	dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);
+
+	memcpy(&bus->i2c_adap, &saa7164_i2c_adap_template,
+	       sizeof(bus->i2c_adap));
+
+	memcpy(&bus->i2c_algo, &saa7164_i2c_algo_template,
+	       sizeof(bus->i2c_algo));
+
+	memcpy(&bus->i2c_client, &saa7164_i2c_client_template,
+	       sizeof(bus->i2c_client));
+
+	bus->i2c_adap.dev.parent = &dev->pci->dev;
+
+	strlcpy(bus->i2c_adap.name, bus->dev->name,
+		sizeof(bus->i2c_adap.name));
+
+	bus->i2c_algo.data = bus;
+	bus->i2c_adap.algo_data = bus;
+	i2c_set_adapdata(&bus->i2c_adap, bus);
+	i2c_add_adapter(&bus->i2c_adap);
+
+	bus->i2c_client.adapter = &bus->i2c_adap;
+
+	if (0 != bus->i2c_rc)
+		printk(KERN_ERR "%s: i2c bus %d register FAILED\n",
+			dev->name, bus->nr);
+
+	return bus->i2c_rc;
+}
+
+int saa7164_i2c_unregister(struct saa7164_i2c *bus)
+{
+	i2c_del_adapter(&bus->i2c_adap);
+	return 0;
+}
diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h
new file mode 100644
index 0000000..06be4c1
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-reg.h
@@ -0,0 +1,166 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+/* TODO: Retest the driver with errors expressed as negatives */
+
+/* Result codes */
+#define SAA_OK				0
+#define SAA_ERR_BAD_PARAMETER		0x09
+#define SAA_ERR_NO_RESOURCES		0x0c
+#define SAA_ERR_NOT_SUPPORTED		0x13
+#define SAA_ERR_BUSY			0x15
+#define SAA_ERR_READ			0x17
+#define SAA_ERR_TIMEOUT			0x1f
+#define SAA_ERR_OVERFLOW		0x20
+#define SAA_ERR_EMPTY			0x22
+#define SAA_ERR_NOT_STARTED		0x23
+#define SAA_ERR_ALREADY_STARTED		0x24
+#define SAA_ERR_NOT_STOPPED		0x25
+#define SAA_ERR_ALREADY_STOPPED		0x26
+#define SAA_ERR_INVALID_COMMAND		0x3e
+#define SAA_ERR_NULL_PACKET		0x59
+
+/* Errors and flags from the silicon */
+#define PVC_ERRORCODE_UNKNOWN		0x00
+#define PVC_ERRORCODE_INVALID_COMMAND	0x01
+#define PVC_ERRORCODE_INVALID_CONTROL	0x02
+#define PVC_ERRORCODE_INVALID_DATA	0x03
+#define PVC_ERRORCODE_TIMEOUT		0x04
+#define PVC_ERRORCODE_NAK		0x05
+#define PVC_RESPONSEFLAG_ERROR		0x01
+#define PVC_RESPONSEFLAG_OVERFLOW	0x02
+#define PVC_RESPONSEFLAG_RESET		0x04
+#define PVC_RESPONSEFLAG_INTERFACE	0x08
+#define PVC_RESPONSEFLAG_CONTINUED	0x10
+#define PVC_CMDFLAG_INTERRUPT		0x02
+#define PVC_CMDFLAG_INTERFACE		0x04
+#define PVC_CMDFLAG_SERIALIZE		0x08
+#define PVC_CMDFLAG_CONTINUE		0x10
+
+/* Silicon Commands */
+#define GET_DESCRIPTORS_CONTROL		0x01
+#define GET_STRING_CONTROL		0x03
+#define GET_LANGUAGE_CONTROL		0x05
+#define SET_POWER_CONTROL		0x07
+#define GET_FW_VERSION_CONTROL		0x09
+#define SET_DEBUG_LEVEL_CONTROL		0x0B
+#define GET_DEBUG_DATA_CONTROL		0x0C
+#define GET_PRODUCTION_INFO_CONTROL	0x0D
+
+/* cmd defines */
+#define SAA_CMDFLAG_CONTINUE		0x10
+#define SAA_CMD_MAX_MSG_UNITS		256
+
+/* Some defines */
+#define SAA_BUS_TIMEOUT			50
+#define SAA_DEVICE_TIMEOUT		5000
+#define SAA_DEVICE_MAXREQUESTSIZE	256
+
+/* Register addresses */
+#define SAA_DEVICE_VERSION		0x30
+#define SAA_DOWNLOAD_FLAGS		0x34
+#define SAA_DOWNLOAD_FLAG		0x34
+#define SAA_DOWNLOAD_FLAG_ACK		0x38
+#define SAA_DATAREADY_FLAG		0x3C
+#define SAA_DATAREADY_FLAG_ACK		0x40
+
+/* Boot loader register and bit definitions */
+#define SAA_BOOTLOADERERROR_FLAGS	0x44
+#define SAA_DEVICE_IMAGE_SEARCHING	0x01
+#define SAA_DEVICE_IMAGE_LOADING	0x02
+#define SAA_DEVICE_IMAGE_BOOTING	0x03
+#define SAA_DEVICE_IMAGE_CORRUPT	0x04
+#define SAA_DEVICE_MEMORY_CORRUPT	0x08
+#define SAA_DEVICE_NO_IMAGE		0x10
+
+/* Register addresses */
+#define SAA_DEVICE_2ND_VERSION			0x50
+#define SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET	0x54
+
+/* Register addresses */
+#define SAA_SECONDSTAGEERROR_FLAGS		0x64
+
+/* Bootloader regs and flags */
+#define SAA_DEVICE_DEADLOCK_DETECTED_OFFSET	0x6C
+#define SAA_DEVICE_DEADLOCK_DETECTED		0xDEADDEAD
+
+/* Basic firmware status registers */
+#define SAA_DEVICE_SYSINIT_STATUS_OFFSET	0x70
+#define SAA_DEVICE_SYSINIT_STATUS		0x70
+#define SAA_DEVICE_SYSINIT_MODE			0x74
+#define SAA_DEVICE_SYSINIT_SPEC			0x78
+#define SAA_DEVICE_SYSINIT_INST			0x7C
+#define SAA_DEVICE_SYSINIT_CPULOAD		0x80
+#define SAA_DEVICE_SYSINIT_REMAINHEAP		0x84
+
+#define SAA_DEVICE_DOWNLOAD_OFFSET		0x1000
+#define SAA_DEVICE_BUFFERBLOCKSIZE		0x1000
+
+#define SAA_DEVICE_2ND_BUFFERBLOCKSIZE		0x100000
+#define SAA_DEVICE_2ND_DOWNLOAD_OFFSET		0x200000
+
+/* Descriptors */
+#define CS_INTERFACE	0x24
+
+/* Descriptor subtypes */
+#define VC_INPUT_TERMINAL		0x02
+#define VC_OUTPUT_TERMINAL		0x03
+#define VC_SELECTOR_UNIT		0x04
+#define VC_PROCESSING_UNIT		0x05
+#define FEATURE_UNIT			0x06
+#define TUNER_UNIT			0x09
+#define ENCODER_UNIT			0x0A
+#define EXTENSION_UNIT			0x0B
+#define VC_TUNER_PATH			0xF0
+#define PVC_HARDWARE_DESCRIPTOR		0xF1
+#define PVC_INTERFACE_DESCRIPTOR	0xF2
+#define PVC_INFRARED_UNIT		0xF3
+#define DRM_UNIT			0xF4
+#define GENERAL_REQUEST			0xF5
+
+/* Format Types */
+#define VS_FORMAT_TYPE         0x02
+#define VS_FORMAT_TYPE_I       0x01
+#define VS_FORMAT_UNCOMPRESSED 0x04
+#define VS_FRAME_UNCOMPRESSED  0x05
+#define VS_FORMAT_MPEG2PS      0x09
+#define VS_FORMAT_MPEG2TS      0x0A
+#define VS_FORMAT_MPEG4SL      0x0B
+#define VS_FORMAT_WM9          0x0C
+#define VS_FORMAT_DIVX         0x0D
+#define VS_FORMAT_VBI          0x0E
+#define VS_FORMAT_RDS          0x0F
+
+/* Device extension commands */
+#define EXU_REGISTER_ACCESS_CONTROL	0x00
+#define EXU_GPIO_CONTROL		0x01
+#define EXU_GPIO_GROUP_CONTROL		0x02
+#define EXU_INTERRUPT_CONTROL		0x03
+
+/* State Transition and args */
+#define SAA_STATE_CONTROL	0x03
+#define SAA_DMASTATE_STOP	0x00
+#define SAA_DMASTATE_ACQUIRE	0x01
+#define SAA_DMASTATE_PAUSE	0x02
+#define SAA_DMASTATE_RUN	0x03
+
+/* Hardware registers */
+
diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h
new file mode 100644
index 0000000..99093f2
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-types.h
@@ -0,0 +1,287 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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.
+ */
+
+/* TODO: Cleanup and shorten the namespace */
+
+/* Some structues are passed directly to/from the firmware and
+ * have strict alignment requirements. This is one of them.
+ */
+typedef struct {
+	u8	bLength;
+	u8	bDescriptorType;
+	u8	bDescriptorSubtype;
+	u16	bcdSpecVersion;
+	u32	dwClockFrequency;
+	u32	dwClockUpdateRes;
+	u8	bCapabilities;
+	u32	dwDeviceRegistersLocation;
+	u32	dwHostMemoryRegion;
+	u32	dwHostMemoryRegionSize;
+	u32	dwHostHibernatMemRegion;
+	u32	dwHostHibernatMemRegionSize;
+} __attribute__((packed)) tmComResHWDescr_t;
+
+/* This is DWORD aligned on windows but I can't find the right
+ * gcc syntax to match the binary data from the device.
+ * I've manually padded with Reserved[3] bytes to match the hardware,
+ * but this could break if GCC decies to pack in a different way.
+ */
+typedef struct {
+	u8	bLength;
+	u8	bDescriptorType;
+	u8	bDescriptorSubtype;
+	u8	bFlags;
+	u8	bInterfaceType;
+	u8	bInterfaceId;
+	u8	bBaseInterface;
+	u8	bInterruptId;
+	u8	bDebugInterruptId;
+	u8	BARLocation;
+	u8	Reserved[3];
+} tmComResInterfaceDescr_t;
+
+typedef struct {
+	u64	CommandRing;
+	u64	ResponseRing;
+	u32	CommandWrite;
+	u32	CommandRead;
+	u32	ResponseWrite;
+	u32	ResponseRead;
+} tmComResBusDescr_t;
+
+typedef enum {
+	NONE		= 0,
+	TYPE_BUS_PCI	= 1,
+	TYPE_BUS_PCIe	= 2,
+	TYPE_BUS_USB	= 3,
+	TYPE_BUS_I2C	= 4
+} tmBusType_t;
+
+typedef struct {
+	tmBusType_t Type;
+	u16	m_wMaxReqSize;
+	u8	*m_pdwSetRing;
+	u32	m_dwSizeSetRing;
+	u8	*m_pdwGetRing;
+	u32	m_dwSizeGetRing;
+	u32	*m_pdwSetWritePos;
+	u32	*m_pdwSetReadPos;
+	u32	*m_pdwGetWritePos;
+	u32	*m_pdwGetReadPos;
+
+	/* All access is protected */
+	struct mutex lock;
+
+} tmComResBusInfo_t;
+
+typedef struct {
+	u8	id;
+	u8	flags;
+	u16	size;
+	u32	command;
+	u16	controlselector;
+	u8	seqno;
+} __attribute__((packed)) tmComResInfo_t;
+
+typedef enum {
+	SET_CUR  = 0x01,
+	GET_CUR  = 0x81,
+	GET_MIN  = 0x82,
+	GET_MAX  = 0x83,
+	GET_RES  = 0x84,
+	GET_LEN  = 0x85,
+	GET_INFO = 0x86,
+	GET_DEF  = 0x87
+} tmComResCmd_t;
+
+struct cmd {
+	u8 seqno;
+	u32 inuse;
+	u32 timeout;
+	u32 signalled;
+	struct mutex lock;
+	wait_queue_head_t wait;
+};
+
+typedef struct {
+	u32	pathid;
+	u32	size;
+	void	*descriptor;
+} tmDescriptor_t;
+
+typedef struct {
+	u8	len;
+	u8	type;
+	u8	subtype;
+	u8	unitid;
+} __attribute__((packed)) tmComResDescrHeader_t;
+
+typedef struct {
+	u8	len;
+	u8	type;
+	u8	subtype;
+	u8	unitid;
+	u32	devicetype;
+	u16	deviceid;
+	u32	numgpiopins;
+	u8	numgpiogroups;
+	u8	controlsize;
+} __attribute__((packed)) tmComResExtDevDescrHeader_t;
+
+typedef struct {
+	u32	pin;
+	u8	state;
+} __attribute__((packed)) tmComResGPIO_t;
+
+typedef struct {
+	u8	len;
+	u8	type;
+	u8	subtype;
+	u8	pathid;
+} __attribute__((packed)) tmComResPathDescrHeader_t;
+
+/* terminaltype */
+typedef enum {
+	ITT_ANTENNA              = 0x0203,
+	LINE_CONNECTOR           = 0x0603,
+	SPDIF_CONNECTOR          = 0x0605,
+	COMPOSITE_CONNECTOR      = 0x0401,
+	SVIDEO_CONNECTOR         = 0x0402,
+	COMPONENT_CONNECTOR      = 0x0403,
+	STANDARD_DMA             = 0xF101
+} tmComResTermType_t;
+
+typedef struct {
+	u8	len;
+	u8	type;
+	u8	subtype;
+	u8	terminalid;
+	u16	terminaltype;
+	u8	assocterminal;
+	u8	iterminal;
+	u8	controlsize;
+} __attribute__((packed)) tmComResAntTermDescrHeader_t;
+
+typedef struct {
+	u8	len;
+	u8	type;
+	u8	subtype;
+	u8	unitid;
+	u8	sourceid;
+	u8	iunit;
+	u32	tuningstandards;
+	u8	controlsize;
+	u32	controls;
+} __attribute__((packed)) tmComResTunerDescrHeader_t;
+
+typedef enum {
+	/* the buffer does not contain any valid data */
+	TM_BUFFER_FLAG_EMPTY,
+
+	/* the buffer is filled with valid data */
+	TM_BUFFER_FLAG_DONE,
+
+	/* the buffer is the dummy buffer - TODO??? */
+	TM_BUFFER_FLAG_DUMMY_BUFFER
+} tmBufferFlag_t;
+
+typedef struct {
+	u64		*pagetablevirt;
+	u64		pagetablephys;
+	u16		offset;
+	u8		*context;
+	u64		timestamp;
+	tmBufferFlag_t	BufferFlag_t;
+	u32		lostbuffers;
+	u32		validbuffers;
+	u64		*dummypagevirt;
+	u64		dummypagephys;
+	u64		*addressvirt;
+} tmBuffer_t;
+
+typedef struct {
+	u32	bitspersample;
+	u32	samplesperline;
+	u32	numberoflines;
+	u32	pitch;
+	u32	linethreshold;
+	u64	**pagetablelistvirt;
+	u64	*pagetablelistphys;
+	u32	numpagetables;
+	u32	numpagetableentries;
+} tmHWStreamParameters_t;
+
+typedef struct {
+	tmHWStreamParameters_t		HWStreamParameters_t;
+	u64				qwDummyPageTablePhys;
+	u64				*pDummyPageTableVirt;
+} tmStreamParameters_t;
+
+typedef struct {
+	u8	len;
+	u8	type;
+	u8	subtyle;
+	u8	unitid;
+	u16	terminaltype;
+	u8	assocterminal;
+	u8	sourceid;
+	u8	iterminal;
+	u32	BARLocation;
+	u8	flags;
+	u8	interruptid;
+	u8	buffercount;
+	u8	metadatasize;
+	u8	numformats;
+	u8	controlsize;
+} __attribute__((packed)) tmComResDMATermDescrHeader_t;
+
+/*
+ *
+ * Description:
+ *  This is the transport stream format header.
+ *
+ * Settings:
+ *  bLength                 - The size of this descriptor in bytes.
+ *  bDescriptorType         - CS_INTERFACE.
+ *  bDescriptorSubtype      - VS_FORMAT_MPEG2TS descriptor subtype.
+ *  bFormatIndex            - A non-zero constant that uniquely identifies the
+ *                            format.
+ *  bDataOffset             - Offset to TSP packet within MPEG-2 TS transport
+ *                            stride, in bytes.
+ *  bPacketLength           - Length of TSP packet, in bytes (typically 188).
+ *  bStrideLength           - Length of MPEG-2 TS transport stride.
+ *  guidStrideFormat        - A Globally Unique Identifier indicating the
+ *                            format of the stride data (if any). Set to zeros
+ *                            if there is no Stride Data, or if the Stride
+ *                            Data is to be ignored by the application.
+ *
+ */
+typedef struct {
+	u8	len;
+	u8	type;
+	u8	subtype;
+	u8	bFormatIndex;
+	u8	bDataOffset;
+	u8	bPacketLength;
+	u8	bStrideLength;
+	u8	guidStrideFormat[16];
+} __attribute__((packed)) tmComResTSFormatDescrHeader_t;
+
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
new file mode 100644
index 0000000..6753008
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -0,0 +1,400 @@
+/*
+ *  Driver for the NXP SAA7164 PCIe bridge
+ *
+ *  Copyright (c) 2009 Steven Toth <stoth@kernellabs.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 architecture
+	*******************
+
+	saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c
+		|	: Standard Linux driver framework for creating
+		|	: exposing and managing interfaces to the rest
+		|	: of the kernel or userland. Also uses _fw.c to load
+		|	: firmware direct into the PCIe bus, bypassing layers.
+		V
+	saa7164_api..()	: Translate kernel specific functions/features
+		|	: into command buffers.
+		V
+	saa7164_cmd..()	: Manages the flow of command packets on/off,
+		|	: the bus. Deal with bus errors, timeouts etc.
+		V
+	saa7164_bus..() : Manage a read/write memory ring buffer in the
+		|	: PCIe Address space.
+		|
+		|		saa7164_fw...()	: Load any frimware
+		|			|	: direct into the device
+		V			V
+	<- ----------------- PCIe address space -------------------- ->
+*/
+
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/kdev_t.h>
+
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+#include <media/videobuf-dma-sg.h>
+#include <media/videobuf-dvb.h>
+
+#include "saa7164-reg.h"
+#include "saa7164-types.h"
+
+#include <linux/version.h>
+#include <linux/mutex.h>
+
+#define SAA7164_MAXBOARDS 8
+
+#define UNSET (-1U)
+#define SAA7164_BOARD_NOAUTO			UNSET
+#define SAA7164_BOARD_UNKNOWN			0
+#define SAA7164_BOARD_UNKNOWN_REV2		1
+#define SAA7164_BOARD_UNKNOWN_REV3		2
+#define SAA7164_BOARD_HAUPPAUGE_HVR2250		3
+#define SAA7164_BOARD_HAUPPAUGE_HVR2200		4
+#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2	5
+#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3	6
+#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2	7
+#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3	8
+
+#define SAA7164_MAX_UNITS		8
+#define SAA7164_TS_NUMBER_OF_LINES	312
+#define SAA7164_PT_ENTRIES		16 /* (312 * 188) / 4096 */
+
+#define DBGLVL_FW    4
+#define DBGLVL_DVB   8
+#define DBGLVL_I2C  16
+#define DBGLVL_API  32
+#define DBGLVL_CMD  64
+#define DBGLVL_BUS 128
+#define DBGLVL_IRQ 256
+#define DBGLVL_BUF 512
+
+enum port_t {
+	SAA7164_MPEG_UNDEFINED = 0,
+	SAA7164_MPEG_DVB,
+};
+
+enum saa7164_i2c_bus_nr {
+	SAA7164_I2C_BUS_0 = 0,
+	SAA7164_I2C_BUS_1,
+	SAA7164_I2C_BUS_2,
+};
+
+enum saa7164_buffer_flags {
+	SAA7164_BUFFER_UNDEFINED = 0,
+	SAA7164_BUFFER_FREE,
+	SAA7164_BUFFER_BUSY,
+	SAA7164_BUFFER_FULL
+};
+
+enum saa7164_unit_type {
+	SAA7164_UNIT_UNDEFINED = 0,
+	SAA7164_UNIT_DIGITAL_DEMODULATOR,
+	SAA7164_UNIT_ANALOG_DEMODULATOR,
+	SAA7164_UNIT_TUNER,
+	SAA7164_UNIT_EEPROM,
+	SAA7164_UNIT_ZILOG_IRBLASTER,
+	SAA7164_UNIT_ENCODER,
+};
+
+/* The PCIe bridge doesn't grant direct access to i2c.
+ * Instead, you address i2c devices using a uniqely
+ * allocated 'unitid' value via a messaging API. This
+ * is a problem. The kernel and existing demod/tuner
+ * drivers expect to talk 'i2c', so we have to maintain
+ * a translation layer, and a series of functions to
+ * convert i2c bus + device address into a unit id.
+ */
+struct saa7164_unit {
+	enum saa7164_unit_type type;
+	u8	id;
+	char	*name;
+	enum saa7164_i2c_bus_nr i2c_bus_nr;
+	u8	i2c_bus_addr;
+	u8	i2c_reg_len;
+};
+
+struct saa7164_board {
+	char	*name;
+	enum port_t porta, portb;
+	enum {
+		SAA7164_CHIP_UNDEFINED = 0,
+		SAA7164_CHIP_REV2,
+		SAA7164_CHIP_REV3,
+	} chiprev;
+	struct	saa7164_unit unit[SAA7164_MAX_UNITS];
+};
+
+struct saa7164_subid {
+	u16     subvendor;
+	u16     subdevice;
+	u32     card;
+};
+
+struct saa7164_fw_status {
+
+	/* RISC Core details */
+	u32	status;
+	u32	mode;
+	u32	spec;
+	u32	inst;
+	u32	cpuload;
+	u32	remainheap;
+
+	/* Firmware version */
+	u32	version;
+	u32	major;
+	u32	sub;
+	u32	rel;
+	u32	buildnr;
+};
+
+struct saa7164_dvb {
+	struct mutex lock;
+	struct dvb_adapter adapter;
+	struct dvb_frontend *frontend;
+	struct dvb_demux demux;
+	struct dmxdev dmxdev;
+	struct dmx_frontend fe_hw;
+	struct dmx_frontend fe_mem;
+	struct dvb_net net;
+	int feeding;
+};
+
+struct saa7164_i2c {
+	struct saa7164_dev		*dev;
+
+	enum saa7164_i2c_bus_nr		nr;
+
+	/* I2C I/O */
+	struct i2c_adapter		i2c_adap;
+	struct i2c_algo_bit_data	i2c_algo;
+	struct i2c_client		i2c_client;
+	u32				i2c_rc;
+};
+
+struct saa7164_tsport;
+
+struct saa7164_buffer {
+	struct list_head list;
+
+	u32 nr;
+
+	struct saa7164_tsport *port;
+
+	/* Hardware Specific */
+	/* PCI Memory allocations */
+	enum saa7164_buffer_flags flags; /* Free, Busy, Full */
+
+	/* A block of page align PCI memory */
+	u32 pci_size;	/* PCI allocation size in bytes */
+	u64 *cpu;	/* Virtual address */
+	dma_addr_t dma;	/* Physical address */
+
+	/* A page table that splits the block into a number of entries */
+	u32 pt_size;		/* PCI allocation size in bytes */
+	u64 *pt_cpu;		/* Virtual address */
+	dma_addr_t pt_dma;	/* Physical address */
+};
+
+struct saa7164_tsport {
+
+	struct saa7164_dev *dev;
+	int nr;
+	enum port_t type;
+
+	struct saa7164_dvb dvb;
+
+	/* HW related stream parameters */
+	tmHWStreamParameters_t hw_streamingparams;
+
+	/* DMA configuration values, is seeded during initialization */
+	tmComResDMATermDescrHeader_t hwcfg;
+
+	/* hardware specific registers */
+	u32 bufcounter;
+	u32 pitch;
+	u32 bufsize;
+	u32 bufoffset;
+	u32 bufptr32l;
+	u32 bufptr32h;
+	u64 bufptr64;
+
+	u32 numpte;	/* Number of entries in array, only valid in head */
+	struct mutex dmaqueue_lock;
+	struct mutex dummy_dmaqueue_lock;
+	struct saa7164_buffer dmaqueue;
+	struct saa7164_buffer dummy_dmaqueue;
+
+};
+
+struct saa7164_dev {
+	struct list_head	devlist;
+	atomic_t		refcount;
+
+	/* pci stuff */
+	struct pci_dev	*pci;
+	unsigned char	pci_rev, pci_lat;
+	int		pci_bus, pci_slot;
+	u32		__iomem *lmmio;
+	u8		__iomem *bmmio;
+	u32		__iomem *lmmio2;
+	u8		__iomem *bmmio2;
+	int		pci_irqmask;
+
+	/* board details */
+	int	nr;
+	int	hwrevision;
+	u32	board;
+	char	name[32];
+
+	/* firmware status */
+	struct saa7164_fw_status	fw_status;
+
+	tmComResHWDescr_t		hwdesc;
+	tmComResInterfaceDescr_t	intfdesc;
+	tmComResBusDescr_t		busdesc;
+
+	tmComResBusInfo_t		bus;
+
+	/* Interrupt status and ack registers */
+	u32 int_status;
+	u32 int_ack;
+
+	struct cmd			cmds[SAA_CMD_MAX_MSG_UNITS];
+	struct mutex			lock;
+
+	/* I2c related */
+	struct saa7164_i2c i2c_bus[3];
+
+	/* Transport related */
+	struct saa7164_tsport ts1, ts2;
+
+	/* Deferred command/api interrupts handling */
+	struct work_struct workcmd;
+
+};
+
+extern struct list_head saa7164_devlist;
+extern unsigned int waitsecs;
+
+/* ----------------------------------------------------------- */
+/* saa7164-core.c                                              */
+void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
+void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
+void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
+u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
+
+/* ----------------------------------------------------------- */
+/* saa7164-fw.c                                                */
+int saa7164_downloadfirmware(struct saa7164_dev *dev);
+
+/* ----------------------------------------------------------- */
+/* saa7164-i2c.c                                               */
+extern int saa7164_i2c_register(struct saa7164_i2c *bus);
+extern int saa7164_i2c_unregister(struct saa7164_i2c *bus);
+extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
+	unsigned int cmd, void *arg);
+
+/* ----------------------------------------------------------- */
+/* saa7164-bus.c                                               */
+int saa7164_bus_setup(struct saa7164_dev *dev);
+void saa7164_bus_dump(struct saa7164_dev *dev);
+int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf);
+int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg,
+	void *buf, int peekonly);
+
+/* ----------------------------------------------------------- */
+/* saa7164-cmd.c                                               */
+int saa7164_cmd_send(struct saa7164_dev *dev,
+	u8 id, tmComResCmd_t command, u16 controlselector,
+	u16 size, void *buf);
+void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
+int saa7164_irq_dequeue(struct saa7164_dev *dev);
+
+/* ----------------------------------------------------------- */
+/* saa7164-api.c                                               */
+int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version);
+int saa7164_api_enum_subdevs(struct saa7164_dev *dev);
+int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
+	u32 datalen, u8 *data);
+int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr,
+	u32 datalen, u8 *data);
+int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
+	u32 datalen, u8 *data);
+int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen);
+int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
+int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
+int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode);
+
+/* ----------------------------------------------------------- */
+/* saa7164-cards.c                                             */
+extern struct saa7164_board saa7164_boards[];
+extern const unsigned int saa7164_bcount;
+
+extern struct saa7164_subid saa7164_subids[];
+extern const unsigned int saa7164_idcount;
+
+extern void saa7164_card_list(struct saa7164_dev *dev);
+extern void saa7164_gpio_setup(struct saa7164_dev *dev);
+extern void saa7164_card_setup(struct saa7164_dev *dev);
+
+extern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr);
+extern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr);
+extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid);
+
+/* ----------------------------------------------------------- */
+/* saa7164-dvb.c                                               */
+extern int saa7164_dvb_register(struct saa7164_tsport *port);
+extern int saa7164_dvb_unregister(struct saa7164_tsport *port);
+
+/* ----------------------------------------------------------- */
+/* saa7164-buffer.c                                            */
+extern struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
+	u32 len);
+extern int saa7164_buffer_dealloc(struct saa7164_tsport *port,
+	struct saa7164_buffer *buf);
+
+/* ----------------------------------------------------------- */
+
+extern unsigned int debug;
+#define dprintk(level, fmt, arg...)\
+	do { if (debug & level)\
+		printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
+	} while (0)
+
+#define log_warn(fmt, arg...)\
+	do { \
+		printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\
+	} while (0)
+
+#define log_err(fmt, arg...)\
+	do { \
+		printk(KERN_ERROR "%s: " fmt, dev->name, ## arg);\
+	} while (0)
+
+#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
+#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
+
+
+#define saa7164_readb(reg)             readl(dev->bmmio + (reg))
+#define saa7164_writeb(reg, value)     writel((value), dev->bmmio + (reg))
+
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index e86878d..5ab7c5a 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -30,7 +30,7 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -74,6 +74,13 @@
 #define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
 #define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
 
+#undef DEBUG_GEOMETRY
+#ifdef DEBUG_GEOMETRY
+#define dev_geo	dev_info
+#else
+#define dev_geo	dev_dbg
+#endif
+
 /* per video frame buffer */
 struct sh_mobile_ceu_buffer {
 	struct videobuf_buffer vb; /* v4l buffer must be first */
@@ -86,17 +93,27 @@ struct sh_mobile_ceu_dev {
 
 	unsigned int irq;
 	void __iomem *base;
-	struct clk *clk;
 	unsigned long video_limit;
 
 	/* lock used to protect videobuf */
 	spinlock_t lock;
 	struct list_head capture;
 	struct videobuf_buffer *active;
-	int is_interlaced;
 
 	struct sh_mobile_ceu_info *pdata;
 
+	u32 cflcr;
+
+	unsigned int is_interlaced:1;
+	unsigned int image_mode:1;
+	unsigned int is_16bit:1;
+};
+
+struct sh_mobile_ceu_cam {
+	struct v4l2_rect ceu_rect;
+	unsigned int cam_width;
+	unsigned int cam_height;
+	const struct soc_camera_data_format *extra_fmt;
 	const struct soc_camera_data_format *camera_fmt;
 };
 
@@ -147,7 +164,8 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
 	int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
 
-	*size = PAGE_ALIGN(icd->width * icd->height * bytes_per_pixel);
+	*size = PAGE_ALIGN(icd->user_width * icd->user_height *
+			   bytes_per_pixel);
 
 	if (0 == *count)
 		*count = 2;
@@ -157,7 +175,7 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
 			(*count)--;
 	}
 
-	dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
+	dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
 
 	return 0;
 }
@@ -166,8 +184,9 @@ static void free_buffer(struct videobuf_queue *vq,
 			struct sh_mobile_ceu_buffer *buf)
 {
 	struct soc_camera_device *icd = vq->priv_data;
+	struct device *dev = icd->dev.parent;
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
+	dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
 		&buf->vb, buf->vb.baddr, buf->vb.bsize);
 
 	if (in_interrupt())
@@ -175,7 +194,7 @@ static void free_buffer(struct videobuf_queue *vq,
 
 	videobuf_waiton(&buf->vb, 0, 0);
 	videobuf_dma_contig_free(vq, &buf->vb);
-	dev_dbg(&icd->dev, "%s freed\n", __func__);
+	dev_dbg(dev, "%s freed\n", __func__);
 	buf->vb.state = VIDEOBUF_NEEDS_INIT;
 }
 
@@ -206,7 +225,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 	phys_addr_top = videobuf_to_dma_contig(pcdev->active);
 	ceu_write(pcdev, CDAYR, phys_addr_top);
 	if (pcdev->is_interlaced) {
-		phys_addr_bottom = phys_addr_top + icd->width;
+		phys_addr_bottom = phys_addr_top + icd->user_width;
 		ceu_write(pcdev, CDBYR, phys_addr_bottom);
 	}
 
@@ -215,10 +234,12 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 	case V4L2_PIX_FMT_NV21:
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
-		phys_addr_top += icd->width * icd->height;
+		phys_addr_top += icd->user_width *
+			icd->user_height;
 		ceu_write(pcdev, CDACR, phys_addr_top);
 		if (pcdev->is_interlaced) {
-			phys_addr_bottom = phys_addr_top + icd->width;
+			phys_addr_bottom = phys_addr_top +
+				icd->user_width;
 			ceu_write(pcdev, CDBCR, phys_addr_bottom);
 		}
 	}
@@ -237,7 +258,7 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
 
 	buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	/* Added list head initialization on alloc */
@@ -252,12 +273,12 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
 	BUG_ON(NULL == icd->current_fmt);
 
 	if (buf->fmt	!= icd->current_fmt ||
-	    vb->width	!= icd->width ||
-	    vb->height	!= icd->height ||
+	    vb->width	!= icd->user_width ||
+	    vb->height	!= icd->user_height ||
 	    vb->field	!= field) {
 		buf->fmt	= icd->current_fmt;
-		vb->width	= icd->width;
-		vb->height	= icd->height;
+		vb->width	= icd->user_width;
+		vb->height	= icd->user_height;
 		vb->field	= field;
 		vb->state	= VIDEOBUF_NEEDS_INIT;
 	}
@@ -290,7 +311,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
 
-	dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
+	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
 		vb, vb->baddr, vb->bsize);
 
 	vb->state = VIDEOBUF_QUEUED;
@@ -305,6 +326,27 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
 static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
 					   struct videobuf_buffer *vb)
 {
+	struct soc_camera_device *icd = vq->priv_data;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&pcdev->lock, flags);
+
+	if (pcdev->active == vb) {
+		/* disable capture (release DMA buffer), reset */
+		ceu_write(pcdev, CAPSR, 1 << 16);
+		pcdev->active = NULL;
+	}
+
+	if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
+	    !list_empty(&vb->queue)) {
+		vb->state = VIDEOBUF_ERROR;
+		list_del_init(&vb->queue);
+	}
+
+	spin_unlock_irqrestore(&pcdev->lock, flags);
+
 	free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb));
 }
 
@@ -324,6 +366,10 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
 	spin_lock_irqsave(&pcdev->lock, flags);
 
 	vb = pcdev->active;
+	if (!vb)
+		/* Stale interrupt from a released buffer */
+		goto out;
+
 	list_del_init(&vb->queue);
 
 	if (!list_empty(&pcdev->capture))
@@ -338,6 +384,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
 	do_gettimeofday(&vb->ts);
 	vb->field_count++;
 	wake_up(&vb->done);
+
+out:
 	spin_unlock_irqrestore(&pcdev->lock, flags);
 
 	return IRQ_HANDLED;
@@ -348,19 +396,14 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	int ret = -EBUSY;
 
 	if (pcdev->icd)
-		goto err;
+		return -EBUSY;
 
-	dev_info(&icd->dev,
+	dev_info(icd->dev.parent,
 		 "SuperH Mobile CEU driver attached to camera %d\n",
 		 icd->devnum);
 
-	ret = icd->ops->init(icd);
-	if (ret)
-		goto err;
-
 	clk_enable(pcdev->clk);
 
 	ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
@@ -368,8 +411,8 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
 		msleep(1);
 
 	pcdev->icd = icd;
-err:
-	return ret;
+
+	return 0;
 }
 
 /* Called with .video_lock held */
@@ -397,23 +440,149 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
 
 	clk_disable(pcdev->clk);
 
-	icd->ops->release(icd);
-
-	dev_info(&icd->dev,
+	dev_info(icd->dev.parent,
 		 "SuperH Mobile CEU driver detached from camera %d\n",
 		 icd->devnum);
 
 	pcdev->icd = NULL;
 }
 
+/*
+ * See chapter 29.4.12 "Capture Filter Control Register (CFLCR)"
+ * in SH7722 Hardware Manual
+ */
+static unsigned int size_dst(unsigned int src, unsigned int scale)
+{
+	unsigned int mant_pre = scale >> 12;
+	if (!src || !scale)
+		return src;
+	return ((mant_pre + 2 * (src - 1)) / (2 * mant_pre) - 1) *
+		mant_pre * 4096 / scale + 1;
+}
+
+static u16 calc_scale(unsigned int src, unsigned int *dst)
+{
+	u16 scale;
+
+	if (src == *dst)
+		return 0;
+
+	scale = (src * 4096 / *dst) & ~7;
+
+	while (scale > 4096 && size_dst(src, scale) < *dst)
+		scale -= 8;
+
+	*dst = size_dst(src, scale);
+
+	return scale;
+}
+
+/* rect is guaranteed to not exceed the scaled camera rectangle */
+static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd,
+				   unsigned int out_width,
+				   unsigned int out_height)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct sh_mobile_ceu_cam *cam = icd->host_priv;
+	struct v4l2_rect *rect = &cam->ceu_rect;
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	unsigned int height, width, cdwdr_width, in_width, in_height;
+	unsigned int left_offset, top_offset;
+	u32 camor;
+
+	dev_dbg(icd->dev.parent, "Crop %ux%u@%u:%u\n",
+		rect->width, rect->height, rect->left, rect->top);
+
+	left_offset	= rect->left;
+	top_offset	= rect->top;
+
+	if (pcdev->image_mode) {
+		in_width = rect->width;
+		if (!pcdev->is_16bit) {
+			in_width *= 2;
+			left_offset *= 2;
+		}
+		width = cdwdr_width = out_width;
+	} else {
+		unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3;
+
+		width = out_width * w_factor / 2;
+
+		if (!pcdev->is_16bit)
+			w_factor *= 2;
+
+		in_width = rect->width * w_factor / 2;
+		left_offset = left_offset * w_factor / 2;
+
+		cdwdr_width = width * 2;
+	}
+
+	height = out_height;
+	in_height = rect->height;
+	if (pcdev->is_interlaced) {
+		height /= 2;
+		in_height /= 2;
+		top_offset /= 2;
+		cdwdr_width *= 2;
+	}
+
+	/* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
+	camor = left_offset | (top_offset << 16);
+
+	dev_geo(icd->dev.parent,
+		"CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor,
+		(in_height << 16) | in_width, (height << 16) | width,
+		cdwdr_width);
+
+	ceu_write(pcdev, CAMOR, camor);
+	ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
+	ceu_write(pcdev, CFSZR, (height << 16) | width);
+	ceu_write(pcdev, CDWDR, cdwdr_width);
+}
+
+static u32 capture_save_reset(struct sh_mobile_ceu_dev *pcdev)
+{
+	u32 capsr = ceu_read(pcdev, CAPSR);
+	ceu_write(pcdev, CAPSR, 1 << 16); /* reset, stop capture */
+	return capsr;
+}
+
+static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
+{
+	unsigned long timeout = jiffies + 10 * HZ;
+
+	/*
+	 * Wait until the end of the current frame. It can take a long time,
+	 * but if it has been aborted by a CAPSR reset, it shoule exit sooner.
+	 */
+	while ((ceu_read(pcdev, CSTSR) & 1) && time_before(jiffies, timeout))
+		msleep(1);
+
+	if (time_after(jiffies, timeout)) {
+		dev_err(pcdev->ici.v4l2_dev.dev,
+			"Timeout waiting for frame end! Interface problem?\n");
+		return;
+	}
+
+	/* Wait until reset clears, this shall not hang... */
+	while (ceu_read(pcdev, CAPSR) & (1 << 16))
+		udelay(10);
+
+	/* Anything to restore? */
+	if (capsr & ~(1 << 16))
+		ceu_write(pcdev, CAPSR, capsr);
+}
+
 static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 				       __u32 pixfmt)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	int ret, buswidth, width, height, cfszr_width, cdwdr_width;
+	int ret;
 	unsigned long camera_flags, common_flags, value;
-	int yuv_mode, yuv_lineskip;
+	int yuv_lineskip;
+	struct sh_mobile_ceu_cam *cam = icd->host_priv;
+	u32 capsr = capture_save_reset(pcdev);
 
 	camera_flags = icd->ops->query_bus_param(icd);
 	common_flags = soc_camera_bus_param_compatible(camera_flags,
@@ -427,10 +596,10 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 
 	switch (common_flags & SOCAM_DATAWIDTH_MASK) {
 	case SOCAM_DATAWIDTH_8:
-		buswidth = 8;
+		pcdev->is_16bit = 0;
 		break;
 	case SOCAM_DATAWIDTH_16:
-		buswidth = 16;
+		pcdev->is_16bit = 1;
 		break;
 	default:
 		return -EINVAL;
@@ -440,7 +609,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 	ceu_write(pcdev, CRCMPR, 0);
 
 	value = 0x00000010; /* data fetch by default */
-	yuv_mode = yuv_lineskip = 0;
+	yuv_lineskip = 0;
 
 	switch (icd->current_fmt->fourcc) {
 	case V4L2_PIX_FMT_NV12:
@@ -449,8 +618,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 		/* fall-through */
 	case V4L2_PIX_FMT_NV16:
 	case V4L2_PIX_FMT_NV61:
-		yuv_mode = 1;
-		switch (pcdev->camera_fmt->fourcc) {
+		switch (cam->camera_fmt->fourcc) {
 		case V4L2_PIX_FMT_UYVY:
 			value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
 			break;
@@ -474,36 +642,16 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 
 	value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
 	value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
-	value |= buswidth == 16 ? 1 << 12 : 0;
+	value |= pcdev->is_16bit ? 1 << 12 : 0;
 	ceu_write(pcdev, CAMCR, value);
 
 	ceu_write(pcdev, CAPCR, 0x00300000);
 	ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
 
+	sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height);
 	mdelay(1);
 
-	if (yuv_mode) {
-		width = icd->width * 2;
-		width = buswidth == 16 ? width / 2 : width;
-		cfszr_width = cdwdr_width = icd->width;
-	} else {
-		width = icd->width * ((icd->current_fmt->depth + 7) >> 3);
-		width = buswidth == 16 ? width / 2 : width;
-		cfszr_width = buswidth == 8 ? width / 2 : width;
-		cdwdr_width = buswidth == 16 ? width * 2 : width;
-	}
-
-	height = icd->height;
-	if (pcdev->is_interlaced) {
-		height /= 2;
-		cdwdr_width *= 2;
-	}
-
-	ceu_write(pcdev, CAMOR, 0);
-	ceu_write(pcdev, CAPWR, (height << 16) | width);
-	ceu_write(pcdev, CFLCR, 0); /* no scaling */
-	ceu_write(pcdev, CFSZR, (height << 16) | cfszr_width);
-	ceu_write(pcdev, CLFCR, 0); /* no lowpass filter */
+	ceu_write(pcdev, CFLCR, pcdev->cflcr);
 
 	/* A few words about byte order (observed in Big Endian mode)
 	 *
@@ -522,10 +670,15 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 		value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
 
 	ceu_write(pcdev, CDOCR, value);
-
-	ceu_write(pcdev, CDWDR, cdwdr_width);
 	ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
 
+	dev_dbg(icd->dev.parent, "S_FMT successful for %c%c%c%c %ux%u\n",
+		pixfmt & 0xff, (pixfmt >> 8) & 0xff,
+		(pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
+		icd->user_width, icd->user_height);
+
+	capture_restore(pcdev, capsr);
+
 	/* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
 	return 0;
 }
@@ -575,24 +728,35 @@ static const struct soc_camera_data_format sh_mobile_ceu_formats[] = {
 static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
 				     struct soc_camera_format_xlate *xlate)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct device *dev = icd->dev.parent;
 	int ret, k, n;
 	int formats = 0;
+	struct sh_mobile_ceu_cam *cam;
 
 	ret = sh_mobile_ceu_try_bus_param(icd);
 	if (ret < 0)
 		return 0;
 
+	if (!icd->host_priv) {
+		cam = kzalloc(sizeof(*cam), GFP_KERNEL);
+		if (!cam)
+			return -ENOMEM;
+
+		icd->host_priv = cam;
+	} else {
+		cam = icd->host_priv;
+	}
+
 	/* Beginning of a pass */
 	if (!idx)
-		icd->host_priv = NULL;
+		cam->extra_fmt = NULL;
 
 	switch (icd->formats[idx].fourcc) {
 	case V4L2_PIX_FMT_UYVY:
 	case V4L2_PIX_FMT_VYUY:
 	case V4L2_PIX_FMT_YUYV:
 	case V4L2_PIX_FMT_YVYU:
-		if (icd->host_priv)
+		if (cam->extra_fmt)
 			goto add_single_format;
 
 		/*
@@ -604,7 +768,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
 		 * the host_priv pointer and check whether the format you're
 		 * going to add now is already there.
 		 */
-		icd->host_priv = (void *)sh_mobile_ceu_formats;
+		cam->extra_fmt = (void *)sh_mobile_ceu_formats;
 
 		n = ARRAY_SIZE(sh_mobile_ceu_formats);
 		formats += n;
@@ -613,7 +777,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = icd->formats[idx].depth;
 			xlate++;
-			dev_dbg(ici->dev, "Providing format %s using %s\n",
+			dev_dbg(dev, "Providing format %s using %s\n",
 				sh_mobile_ceu_formats[k].name,
 				icd->formats[idx].name);
 		}
@@ -626,7 +790,7 @@ add_single_format:
 			xlate->cam_fmt = icd->formats + idx;
 			xlate->buswidth = icd->formats[idx].depth;
 			xlate++;
-			dev_dbg(ici->dev,
+			dev_dbg(dev,
 				"Providing format %s in pass-through mode\n",
 				icd->formats[idx].name);
 		}
@@ -635,82 +799,714 @@ add_single_format:
 	return formats;
 }
 
+static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
+{
+	kfree(icd->host_priv);
+	icd->host_priv = NULL;
+}
+
+/* Check if any dimension of r1 is smaller than respective one of r2 */
+static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
+{
+	return r1->width < r2->width || r1->height < r2->height;
+}
+
+/* Check if r1 fails to cover r2 */
+static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
+{
+	return r1->left > r2->left || r1->top > r2->top ||
+		r1->left + r1->width < r2->left + r2->width ||
+		r1->top + r1->height < r2->top + r2->height;
+}
+
+static unsigned int scale_down(unsigned int size, unsigned int scale)
+{
+	return (size * 4096 + scale / 2) / scale;
+}
+
+static unsigned int scale_up(unsigned int size, unsigned int scale)
+{
+	return (size * scale + 2048) / 4096;
+}
+
+static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
+{
+	return (input * 4096 + output / 2) / output;
+}
+
+static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
+{
+	struct v4l2_crop crop;
+	struct v4l2_cropcap cap;
+	int ret;
+
+	crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, g_crop, &crop);
+	if (!ret) {
+		*rect = crop.c;
+		return ret;
+	}
+
+	/* Camera driver doesn't support .g_crop(), assume default rectangle */
+	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (ret < 0)
+		return ret;
+
+	*rect = cap.defrect;
+
+	return ret;
+}
+
+/*
+ * The common for both scaling and cropping iterative approach is:
+ * 1. try if the client can produce exactly what requested by the user
+ * 2. if (1) failed, try to double the client image until we get one big enough
+ * 3. if (2) failed, try to request the maximum image
+ */
+static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
+			 struct v4l2_crop *cam_crop)
+{
+	struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
+	struct device *dev = sd->v4l2_dev->dev;
+	struct v4l2_cropcap cap;
+	int ret;
+	unsigned int width, height;
+
+	v4l2_subdev_call(sd, video, s_crop, crop);
+	ret = client_g_rect(sd, cam_rect);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Now cam_crop contains the current camera input rectangle, and it must
+	 * be within camera cropcap bounds
+	 */
+	if (!memcmp(rect, cam_rect, sizeof(*rect))) {
+		/* Even if camera S_CROP failed, but camera rectangle matches */
+		dev_dbg(dev, "Camera S_CROP successful for %ux%u@%u:%u\n",
+			rect->width, rect->height, rect->left, rect->top);
+		return 0;
+	}
+
+	/* Try to fix cropping, that camera hasn't managed to set */
+	dev_geo(dev, "Fix camera S_CROP for %ux%u@%u:%u to %ux%u@%u:%u\n",
+		cam_rect->width, cam_rect->height,
+		cam_rect->left, cam_rect->top,
+		rect->width, rect->height, rect->left, rect->top);
+
+	/* We need sensor maximum rectangle */
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (ret < 0)
+		return ret;
+
+	soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
+			      cap.bounds.width);
+	soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
+			      cap.bounds.height);
+
+	/*
+	 * Popular special case - some cameras can only handle fixed sizes like
+	 * QVGA, VGA,... Take care to avoid infinite loop.
+	 */
+	width = max(cam_rect->width, 2);
+	height = max(cam_rect->height, 2);
+
+	while (!ret && (is_smaller(cam_rect, rect) ||
+			is_inside(cam_rect, rect)) &&
+	       (cap.bounds.width > width || cap.bounds.height > height)) {
+
+		width *= 2;
+		height *= 2;
+
+		cam_rect->width = width;
+		cam_rect->height = height;
+
+		/*
+		 * We do not know what capabilities the camera has to set up
+		 * left and top borders. We could try to be smarter in iterating
+		 * them, e.g., if camera current left is to the right of the
+		 * target left, set it to the middle point between the current
+		 * left and minimum left. But that would add too much
+		 * complexity: we would have to iterate each border separately.
+		 */
+		if (cam_rect->left > rect->left)
+			cam_rect->left = cap.bounds.left;
+
+		if (cam_rect->left + cam_rect->width < rect->left + rect->width)
+			cam_rect->width = rect->left + rect->width -
+				cam_rect->left;
+
+		if (cam_rect->top > rect->top)
+			cam_rect->top = cap.bounds.top;
+
+		if (cam_rect->top + cam_rect->height < rect->top + rect->height)
+			cam_rect->height = rect->top + rect->height -
+				cam_rect->top;
+
+		v4l2_subdev_call(sd, video, s_crop, cam_crop);
+		ret = client_g_rect(sd, cam_rect);
+		dev_geo(dev, "Camera S_CROP %d for %ux%u@%u:%u\n", ret,
+			cam_rect->width, cam_rect->height,
+			cam_rect->left, cam_rect->top);
+	}
+
+	/* S_CROP must not modify the rectangle */
+	if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
+		/*
+		 * The camera failed to configure a suitable cropping,
+		 * we cannot use the current rectangle, set to max
+		 */
+		*cam_rect = cap.bounds;
+		v4l2_subdev_call(sd, video, s_crop, cam_crop);
+		ret = client_g_rect(sd, cam_rect);
+		dev_geo(dev, "Camera S_CROP %d for max %ux%u@%u:%u\n", ret,
+			cam_rect->width, cam_rect->height,
+			cam_rect->left, cam_rect->top);
+	}
+
+	return ret;
+}
+
+static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect,
+			     unsigned int *scale_h, unsigned int *scale_v)
+{
+	struct v4l2_format f;
+	int ret;
+
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+	if (ret < 0)
+		return ret;
+
+	*scale_h = calc_generic_scale(rect->width, f.fmt.pix.width);
+	*scale_v = calc_generic_scale(rect->height, f.fmt.pix.height);
+
+	return 0;
+}
+
+static int get_camera_subwin(struct soc_camera_device *icd,
+			     struct v4l2_rect *cam_subrect,
+			     unsigned int cam_hscale, unsigned int cam_vscale)
+{
+	struct sh_mobile_ceu_cam *cam = icd->host_priv;
+	struct v4l2_rect *ceu_rect = &cam->ceu_rect;
+
+	if (!ceu_rect->width) {
+		struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+		struct device *dev = icd->dev.parent;
+		struct v4l2_format f;
+		struct v4l2_pix_format *pix = &f.fmt.pix;
+		int ret;
+		/* First time */
+
+		f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+		ret = v4l2_subdev_call(sd, video, g_fmt, &f);
+		if (ret < 0)
+			return ret;
+
+		dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height);
+
+		if (pix->width > 2560) {
+			ceu_rect->width	 = 2560;
+			ceu_rect->left	 = (pix->width - 2560) / 2;
+		} else {
+			ceu_rect->width	 = pix->width;
+			ceu_rect->left	 = 0;
+		}
+
+		if (pix->height > 1920) {
+			ceu_rect->height = 1920;
+			ceu_rect->top	 = (pix->height - 1920) / 2;
+		} else {
+			ceu_rect->height = pix->height;
+			ceu_rect->top	 = 0;
+		}
+
+		dev_geo(dev, "initialised CEU rect %ux%u@%u:%u\n",
+			ceu_rect->width, ceu_rect->height,
+			ceu_rect->left, ceu_rect->top);
+	}
+
+	cam_subrect->width	= scale_up(ceu_rect->width, cam_hscale);
+	cam_subrect->left	= scale_up(ceu_rect->left, cam_hscale);
+	cam_subrect->height	= scale_up(ceu_rect->height, cam_vscale);
+	cam_subrect->top	= scale_up(ceu_rect->top, cam_vscale);
+
+	return 0;
+}
+
+static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f,
+			bool ceu_can_scale)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct device *dev = icd->dev.parent;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h;
+	unsigned int max_width, max_height;
+	struct v4l2_cropcap cap;
+	int ret;
+
+	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = v4l2_subdev_call(sd, video, cropcap, &cap);
+	if (ret < 0)
+		return ret;
+
+	max_width = min(cap.bounds.width, 2560);
+	max_height = min(cap.bounds.height, 1920);
+
+	ret = v4l2_subdev_call(sd, video, s_fmt, f);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height);
+
+	if ((width == pix->width && height == pix->height) || !ceu_can_scale)
+		return 0;
+
+	/* Camera set a format, but geometry is not precise, try to improve */
+	tmp_w = pix->width;
+	tmp_h = pix->height;
+
+	/* width <= max_width && height <= max_height - guaranteed by try_fmt */
+	while ((width > tmp_w || height > tmp_h) &&
+	       tmp_w < max_width && tmp_h < max_height) {
+		tmp_w = min(2 * tmp_w, max_width);
+		tmp_h = min(2 * tmp_h, max_height);
+		pix->width = tmp_w;
+		pix->height = tmp_h;
+		ret = v4l2_subdev_call(sd, video, s_fmt, f);
+		dev_geo(dev, "Camera scaled to %ux%u\n",
+			pix->width, pix->height);
+		if (ret < 0) {
+			/* This shouldn't happen */
+			dev_err(dev, "Client failed to set format: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * @rect	- camera cropped rectangle
+ * @sub_rect	- CEU cropped rectangle, mapped back to camera input area
+ * @ceu_rect	- on output calculated CEU crop rectangle
+ */
+static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect,
+			struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect,
+			struct v4l2_format *f, bool ceu_can_scale)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct sh_mobile_ceu_cam *cam = icd->host_priv;
+	struct device *dev = icd->dev.parent;
+	struct v4l2_format f_tmp = *f;
+	struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix;
+	unsigned int scale_h, scale_v;
+	int ret;
+
+	/* 5. Apply iterative camera S_FMT for camera user window. */
+	ret = client_s_fmt(icd, &f_tmp, ceu_can_scale);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "5: camera scaled to %ux%u\n",
+		pix_tmp->width, pix_tmp->height);
+
+	/* 6. Retrieve camera output window (g_fmt) */
+
+	/* unneeded - it is already in "f_tmp" */
+
+	/* 7. Calculate new camera scales. */
+	ret = get_camera_scales(sd, rect, &scale_h, &scale_v);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v);
+
+	cam->cam_width		= pix_tmp->width;
+	cam->cam_height		= pix_tmp->height;
+	f->fmt.pix.width	= pix_tmp->width;
+	f->fmt.pix.height	= pix_tmp->height;
+
+	/*
+	 * 8. Calculate new CEU crop - apply camera scales to previously
+	 *    calculated "effective" crop.
+	 */
+	ceu_rect->left = scale_down(sub_rect->left, scale_h);
+	ceu_rect->width = scale_down(sub_rect->width, scale_h);
+	ceu_rect->top = scale_down(sub_rect->top, scale_v);
+	ceu_rect->height = scale_down(sub_rect->height, scale_v);
+
+	dev_geo(dev, "8: new CEU rect %ux%u@%u:%u\n",
+		ceu_rect->width, ceu_rect->height,
+		ceu_rect->left, ceu_rect->top);
+
+	return 0;
+}
+
+/* Get combined scales */
+static int get_scales(struct soc_camera_device *icd,
+		      unsigned int *scale_h, unsigned int *scale_v)
+{
+	struct sh_mobile_ceu_cam *cam = icd->host_priv;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct v4l2_crop cam_crop;
+	unsigned int width_in, height_in;
+	int ret;
+
+	cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = client_g_rect(sd, &cam_crop.c);
+	if (ret < 0)
+		return ret;
+
+	ret = get_camera_scales(sd, &cam_crop.c, scale_h, scale_v);
+	if (ret < 0)
+		return ret;
+
+	width_in = scale_up(cam->ceu_rect.width, *scale_h);
+	height_in = scale_up(cam->ceu_rect.height, *scale_v);
+
+	*scale_h = calc_generic_scale(cam->ceu_rect.width, icd->user_width);
+	*scale_v = calc_generic_scale(cam->ceu_rect.height, icd->user_height);
+
+	return 0;
+}
+
+/*
+ * CEU can scale and crop, but we don't want to waste bandwidth and kill the
+ * framerate by always requesting the maximum image from the client. See
+ * Documentation/video4linux/sh_mobile_camera_ceu.txt for a description of
+ * scaling and cropping algorithms and for the meaning of referenced here steps.
+ */
 static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
-				  struct v4l2_rect *rect)
+				  struct v4l2_crop *a)
 {
-	return icd->ops->set_crop(icd, rect);
+	struct v4l2_rect *rect = &a->c;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	struct v4l2_crop cam_crop;
+	struct sh_mobile_ceu_cam *cam = icd->host_priv;
+	struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct device *dev = icd->dev.parent;
+	struct v4l2_format f;
+	struct v4l2_pix_format *pix = &f.fmt.pix;
+	unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v,
+		out_width, out_height;
+	u32 capsr, cflcr;
+	int ret;
+
+	/* 1. Calculate current combined scales. */
+	ret = get_scales(icd, &scale_comb_h, &scale_comb_v);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "1: combined scales %u:%u\n", scale_comb_h, scale_comb_v);
+
+	/* 2. Apply iterative camera S_CROP for new input window. */
+	ret = client_s_crop(sd, a, &cam_crop);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "2: camera cropped to %ux%u@%u:%u\n",
+		cam_rect->width, cam_rect->height,
+		cam_rect->left, cam_rect->top);
+
+	/* On success cam_crop contains current camera crop */
+
+	/*
+	 * 3. If old combined scales applied to new crop produce an impossible
+	 *    user window, adjust scales to produce nearest possible window.
+	 */
+	out_width	= scale_down(rect->width, scale_comb_h);
+	out_height	= scale_down(rect->height, scale_comb_v);
+
+	if (out_width > 2560)
+		out_width = 2560;
+	else if (out_width < 2)
+		out_width = 2;
+
+	if (out_height > 1920)
+		out_height = 1920;
+	else if (out_height < 4)
+		out_height = 4;
+
+	dev_geo(dev, "3: Adjusted output %ux%u\n", out_width, out_height);
+
+	/* 4. Use G_CROP to retrieve actual input window: already in cam_crop */
+
+	/*
+	 * 5. Using actual input window and calculated combined scales calculate
+	 *    camera target output window.
+	 */
+	pix->width		= scale_down(cam_rect->width, scale_comb_h);
+	pix->height		= scale_down(cam_rect->height, scale_comb_v);
+
+	dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height);
+
+	/* 6. - 9. */
+	pix->pixelformat	= cam->camera_fmt->fourcc;
+	pix->colorspace		= cam->camera_fmt->colorspace;
+
+	capsr = capture_save_reset(pcdev);
+	dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
+
+	/* Make relative to camera rectangle */
+	rect->left		-= cam_rect->left;
+	rect->top		-= cam_rect->top;
+
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	ret = client_scale(icd, cam_rect, rect, ceu_rect, &f,
+			   pcdev->image_mode && !pcdev->is_interlaced);
+
+	dev_geo(dev, "6-9: %d\n", ret);
+
+	/* 10. Use CEU cropping to crop to the new window. */
+	sh_mobile_ceu_set_rect(icd, out_width, out_height);
+
+	dev_geo(dev, "10: CEU cropped to %ux%u@%u:%u\n",
+		ceu_rect->width, ceu_rect->height,
+		ceu_rect->left, ceu_rect->top);
+
+	/*
+	 * 11. Calculate CEU scales from camera scales from results of (10) and
+	 *     user window from (3)
+	 */
+	scale_ceu_h = calc_scale(ceu_rect->width, &out_width);
+	scale_ceu_v = calc_scale(ceu_rect->height, &out_height);
+
+	dev_geo(dev, "11: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
+
+	/* 12. Apply CEU scales. */
+	cflcr = scale_ceu_h | (scale_ceu_v << 16);
+	if (cflcr != pcdev->cflcr) {
+		pcdev->cflcr = cflcr;
+		ceu_write(pcdev, CFLCR, cflcr);
+	}
+
+	/* Restore capture */
+	if (pcdev->active)
+		capsr |= 1;
+	capture_restore(pcdev, capsr);
+
+	icd->user_width = out_width;
+	icd->user_height = out_height;
+
+	/* Even if only camera cropping succeeded */
+	return ret;
 }
 
+/* Similar to set_crop multistage iterative algorithm */
 static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
 				 struct v4l2_format *f)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	__u32 pixfmt = f->fmt.pix.pixelformat;
-	const struct soc_camera_format_xlate *xlate;
+	struct sh_mobile_ceu_cam *cam = icd->host_priv;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
 	struct v4l2_format cam_f = *f;
+	struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct device *dev = icd->dev.parent;
+	__u32 pixfmt = pix->pixelformat;
+	const struct soc_camera_format_xlate *xlate;
+	struct v4l2_crop cam_crop;
+	struct v4l2_rect *cam_rect = &cam_crop.c, cam_subrect, ceu_rect;
+	unsigned int scale_cam_h, scale_cam_v;
+	u16 scale_v, scale_h;
 	int ret;
+	bool is_interlaced, image_mode;
+
+	switch (pix->field) {
+	case V4L2_FIELD_INTERLACED:
+		is_interlaced = true;
+		break;
+	case V4L2_FIELD_ANY:
+	default:
+		pix->field = V4L2_FIELD_NONE;
+		/* fall-through */
+	case V4L2_FIELD_NONE:
+		is_interlaced = false;
+		break;
+	}
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(dev, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
-	cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc;
-	ret = icd->ops->set_fmt(icd, &cam_f);
+	/* 1. Calculate current camera scales. */
+	cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
-	if (!ret) {
-		icd->buswidth = xlate->buswidth;
-		icd->current_fmt = xlate->host_fmt;
-		pcdev->camera_fmt = xlate->cam_fmt;
+	ret = client_g_rect(sd, cam_rect);
+	if (ret < 0)
+		return ret;
+
+	ret = get_camera_scales(sd, cam_rect, &scale_cam_h, &scale_cam_v);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "1: camera scales %u:%u\n", scale_cam_h, scale_cam_v);
+
+	/*
+	 * 2. Calculate "effective" input crop (sensor subwindow) - CEU crop
+	 *    scaled back at current camera scales onto input window.
+	 */
+	ret = get_camera_subwin(icd, &cam_subrect, scale_cam_h, scale_cam_v);
+	if (ret < 0)
+		return ret;
+
+	dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
+		cam_subrect.width, cam_subrect.height,
+		cam_subrect.left, cam_subrect.top);
+
+	/*
+	 * 3. Calculate new combined scales from "effective" input window to
+	 *    requested user window.
+	 */
+	scale_h = calc_generic_scale(cam_subrect.width, pix->width);
+	scale_v = calc_generic_scale(cam_subrect.height, pix->height);
+
+	dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
+
+	/*
+	 * 4. Calculate camera output window by applying combined scales to real
+	 *    input window.
+	 */
+	cam_pix->width = scale_down(cam_rect->width, scale_h);
+	cam_pix->height = scale_down(cam_rect->height, scale_v);
+	cam_pix->pixelformat = xlate->cam_fmt->fourcc;
+
+	switch (pixfmt) {
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV16:
+	case V4L2_PIX_FMT_NV61:
+		image_mode = true;
+		break;
+	default:
+		image_mode = false;
 	}
 
-	return ret;
+	dev_geo(dev, "4: camera output %ux%u\n",
+		cam_pix->width, cam_pix->height);
+
+	/* 5. - 9. */
+	ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f,
+			   image_mode && !is_interlaced);
+
+	dev_geo(dev, "5-9: client scale %d\n", ret);
+
+	/* Done with the camera. Now see if we can improve the result */
+
+	dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
+		ret, cam_pix->width, cam_pix->height, pix->width, pix->height);
+	if (ret < 0)
+		return ret;
+
+	/* 10. Use CEU scaling to scale to the requested user window. */
+
+	/* We cannot scale up */
+	if (pix->width > cam_pix->width)
+		pix->width = cam_pix->width;
+	if (pix->width > ceu_rect.width)
+		pix->width = ceu_rect.width;
+
+	if (pix->height > cam_pix->height)
+		pix->height = cam_pix->height;
+	if (pix->height > ceu_rect.height)
+		pix->height = ceu_rect.height;
+
+	/* Let's rock: scale pix->{width x height} down to width x height */
+	scale_h = calc_scale(ceu_rect.width, &pix->width);
+	scale_v = calc_scale(ceu_rect.height, &pix->height);
+
+	dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
+		ceu_rect.width, scale_h, pix->width,
+		ceu_rect.height, scale_v, pix->height);
+
+	pcdev->cflcr = scale_h | (scale_v << 16);
+
+	icd->buswidth = xlate->buswidth;
+	icd->current_fmt = xlate->host_fmt;
+	cam->camera_fmt = xlate->cam_fmt;
+	cam->ceu_rect = ceu_rect;
+
+	pcdev->is_interlaced = is_interlaced;
+	pcdev->image_mode = image_mode;
+
+	return 0;
 }
 
 static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
 				 struct v4l2_format *f)
 {
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	struct sh_mobile_ceu_dev *pcdev = ici->priv;
 	const struct soc_camera_format_xlate *xlate;
-	__u32 pixfmt = f->fmt.pix.pixelformat;
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	__u32 pixfmt = pix->pixelformat;
+	int width, height;
 	int ret;
 
 	xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
 	if (!xlate) {
-		dev_warn(ici->dev, "Format %x not found\n", pixfmt);
+		dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
 		return -EINVAL;
 	}
 
 	/* FIXME: calculate using depth and bus width */
 
-	v4l_bound_align_image(&f->fmt.pix.width, 2, 2560, 1,
-			      &f->fmt.pix.height, 4, 1920, 2, 0);
+	v4l_bound_align_image(&pix->width, 2, 2560, 1,
+			      &pix->height, 4, 1920, 2, 0);
 
-	f->fmt.pix.bytesperline = f->fmt.pix.width *
+	width = pix->width;
+	height = pix->height;
+
+	pix->bytesperline = pix->width *
 		DIV_ROUND_UP(xlate->host_fmt->depth, 8);
-	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+	pix->sizeimage = pix->height * pix->bytesperline;
+
+	pix->pixelformat = xlate->cam_fmt->fourcc;
 
 	/* limit to sensor capabilities */
-	ret = icd->ops->try_fmt(icd, f);
+	ret = v4l2_subdev_call(sd, video, try_fmt, f);
+	pix->pixelformat = pixfmt;
 	if (ret < 0)
 		return ret;
 
-	switch (f->fmt.pix.field) {
-	case V4L2_FIELD_INTERLACED:
-		pcdev->is_interlaced = 1;
-		break;
-	case V4L2_FIELD_ANY:
-		f->fmt.pix.field = V4L2_FIELD_NONE;
-		/* fall-through */
-	case V4L2_FIELD_NONE:
-		pcdev->is_interlaced = 0;
-		break;
-	default:
-		ret = -EINVAL;
-		break;
+	switch (pixfmt) {
+	case V4L2_PIX_FMT_NV12:
+	case V4L2_PIX_FMT_NV21:
+	case V4L2_PIX_FMT_NV16:
+	case V4L2_PIX_FMT_NV61:
+		/* FIXME: check against rect_max after converting soc-camera */
+		/* We can scale precisely, need a bigger image from camera */
+		if (pix->width < width || pix->height < height) {
+			int tmp_w = pix->width, tmp_h = pix->height;
+			pix->width = 2560;
+			pix->height = 1920;
+			ret = v4l2_subdev_call(sd, video, try_fmt, f);
+			if (ret < 0) {
+				/* Shouldn't actually happen... */
+				dev_err(icd->dev.parent,
+					"FIXME: try_fmt() returned %d\n", ret);
+				pix->width = tmp_w;
+				pix->height = tmp_h;
+			}
+		}
+		if (pix->width > width)
+			pix->width = width;
+		if (pix->height > height)
+			pix->height = height;
 	}
 
 	return ret;
@@ -770,7 +1566,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
 
 	videobuf_queue_dma_contig_init(q,
 				       &sh_mobile_ceu_videobuf_ops,
-				       ici->dev, &pcdev->lock,
+				       icd->dev.parent, &pcdev->lock,
 				       V4L2_BUF_TYPE_VIDEO_CAPTURE,
 				       pcdev->is_interlaced ?
 				       V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
@@ -778,27 +1574,80 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
 				       icd);
 }
 
+static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
+				  struct v4l2_control *ctrl)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	u32 val;
+
+	switch (ctrl->id) {
+	case V4L2_CID_SHARPNESS:
+		val = ceu_read(pcdev, CLFCR);
+		ctrl->value = val ^ 1;
+		return 0;
+	}
+	return -ENOIOCTLCMD;
+}
+
+static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
+				  struct v4l2_control *ctrl)
+{
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+
+	switch (ctrl->id) {
+	case V4L2_CID_SHARPNESS:
+		switch (icd->current_fmt->fourcc) {
+		case V4L2_PIX_FMT_NV12:
+		case V4L2_PIX_FMT_NV21:
+		case V4L2_PIX_FMT_NV16:
+		case V4L2_PIX_FMT_NV61:
+			ceu_write(pcdev, CLFCR, !ctrl->value);
+			return 0;
+		}
+		return -EINVAL;
+	}
+	return -ENOIOCTLCMD;
+}
+
+static const struct v4l2_queryctrl sh_mobile_ceu_controls[] = {
+	{
+		.id		= V4L2_CID_SHARPNESS,
+		.type		= V4L2_CTRL_TYPE_BOOLEAN,
+		.name		= "Low-pass filter",
+		.minimum	= 0,
+		.maximum	= 1,
+		.step		= 1,
+		.default_value	= 0,
+	},
+};
+
 static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
 	.owner		= THIS_MODULE,
 	.add		= sh_mobile_ceu_add_device,
 	.remove		= sh_mobile_ceu_remove_device,
 	.get_formats	= sh_mobile_ceu_get_formats,
+	.put_formats	= sh_mobile_ceu_put_formats,
 	.set_crop	= sh_mobile_ceu_set_crop,
 	.set_fmt	= sh_mobile_ceu_set_fmt,
 	.try_fmt	= sh_mobile_ceu_try_fmt,
+	.set_ctrl	= sh_mobile_ceu_set_ctrl,
+	.get_ctrl	= sh_mobile_ceu_get_ctrl,
 	.reqbufs	= sh_mobile_ceu_reqbufs,
 	.poll		= sh_mobile_ceu_poll,
 	.querycap	= sh_mobile_ceu_querycap,
 	.set_bus_param	= sh_mobile_ceu_set_bus_param,
 	.init_videobuf	= sh_mobile_ceu_init_videobuf,
+	.controls	= sh_mobile_ceu_controls,
+	.num_controls	= ARRAY_SIZE(sh_mobile_ceu_controls),
 };
 
-static int sh_mobile_ceu_probe(struct platform_device *pdev)
+static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
 {
 	struct sh_mobile_ceu_dev *pcdev;
 	struct resource *res;
 	void __iomem *base;
-	char clk_name[8];
 	unsigned int irq;
 	int err = 0;
 
@@ -862,28 +1711,22 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
 		goto exit_release_mem;
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "ceu%d", pdev->id);
-	pcdev->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(pcdev->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		err = PTR_ERR(pcdev->clk);
-		goto exit_free_irq;
-	}
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_resume(&pdev->dev);
 
 	pcdev->ici.priv = pcdev;
-	pcdev->ici.dev = &pdev->dev;
+	pcdev->ici.v4l2_dev.dev = &pdev->dev;
 	pcdev->ici.nr = pdev->id;
 	pcdev->ici.drv_name = dev_name(&pdev->dev);
 	pcdev->ici.ops = &sh_mobile_ceu_host_ops;
 
 	err = soc_camera_host_register(&pcdev->ici);
 	if (err)
-		goto exit_free_clk;
+		goto exit_free_irq;
 
 	return 0;
 
-exit_free_clk:
-	clk_put(pcdev->clk);
 exit_free_irq:
 	free_irq(pcdev->irq, pcdev);
 exit_release_mem:
@@ -897,14 +1740,13 @@ exit:
 	return err;
 }
 
-static int sh_mobile_ceu_remove(struct platform_device *pdev)
+static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
 {
 	struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
 	struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
 					struct sh_mobile_ceu_dev, ici);
 
 	soc_camera_host_unregister(soc_host);
-	clk_put(pcdev->clk);
 	free_irq(pcdev->irq, pcdev);
 	if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
 		dma_release_declared_memory(&pdev->dev);
@@ -913,12 +1755,30 @@ static int sh_mobile_ceu_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int sh_mobile_ceu_runtime_nop(struct device *dev)
+{
+	/* Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * This driver re-initializes all registers after
+	 * pm_runtime_get_sync() anyway so there is no need
+	 * to save and restore registers here.
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
+	.runtime_suspend = sh_mobile_ceu_runtime_nop,
+	.runtime_resume = sh_mobile_ceu_runtime_nop,
+};
+
 static struct platform_driver sh_mobile_ceu_driver = {
 	.driver 	= {
 		.name	= "sh_mobile_ceu",
+		.pm	= &sh_mobile_ceu_dev_pm_ops,
 	},
 	.probe		= sh_mobile_ceu_probe,
-	.remove		= sh_mobile_ceu_remove,
+	.remove		= __exit_p(sh_mobile_ceu_remove),
 };
 
 static int __init sh_mobile_ceu_init(void)
@@ -937,3 +1797,4 @@ module_exit(sh_mobile_ceu_exit);
 MODULE_DESCRIPTION("SuperH Mobile CEU driver");
 MODULE_AUTHOR("Magnus Damm");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sh_mobile_ceu");
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 23edfdc..9d84c94 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1954,8 +1954,10 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
 				    (!list_empty(&cam->outqueue)) ||
 				    (cam->state & DEV_DISCONNECTED) ||
 				    (cam->state & DEV_MISCONFIGURED),
-				    cam->module_param.frame_timeout *
-				    1000 * msecs_to_jiffies(1) );
+				    msecs_to_jiffies(
+					cam->module_param.frame_timeout * 1000
+				    )
+				  );
 			if (timeout < 0) {
 				mutex_unlock(&cam->fileop_mutex);
 				return timeout;
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 38a7160..36ee43a 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -123,8 +123,8 @@ static const struct usb_device_id sn9c102_id_table[] = {
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
 #if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
-#endif
 	{ SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
+#endif
 	{ }
 };
 
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 9f5ae81..59aa7a3 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -21,15 +21,15 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/vmalloc.h>
 
 #include <media/soc_camera.h>
 #include <media/v4l2-common.h>
-#include <media/v4l2-dev.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-dev.h>
 #include <media/videobuf-core.h>
 
 /* Default to VGA resolution */
@@ -38,7 +38,7 @@
 
 static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
-static DEFINE_MUTEX(list_lock);
+static DEFINE_MUTEX(list_lock);		/* Protects the list of hosts */
 
 const struct soc_camera_data_format *soc_camera_format_by_fourcc(
 	struct soc_camera_device *icd, unsigned int fourcc)
@@ -152,12 +152,9 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
-	int ret = 0;
-
-	if (icd->ops->set_std)
-		ret = icd->ops->set_std(icd, a);
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-	return ret;
+	return v4l2_subdev_call(sd, core, s_std, *a);
 }
 
 static int soc_camera_reqbufs(struct file *file, void *priv,
@@ -170,8 +167,6 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
 
 	WARN_ON(priv != file->private_data);
 
-	dev_dbg(&icd->dev, "%s: %d\n", __func__, p->memory);
-
 	ret = videobuf_reqbufs(&icf->vb_vidq, p);
 	if (ret < 0)
 		return ret;
@@ -209,10 +204,11 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
 	return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK);
 }
 
+/* Always entered with .video_lock held */
 static int soc_camera_init_user_formats(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	int i, fmts = 0;
+	int i, fmts = 0, ret;
 
 	if (!ici->ops->get_formats)
 		/*
@@ -225,8 +221,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
 		 * First pass - only count formats this host-sensor
 		 * configuration can provide
 		 */
-		for (i = 0; i < icd->num_formats; i++)
-			fmts += ici->ops->get_formats(icd, i, NULL);
+		for (i = 0; i < icd->num_formats; i++) {
+			ret = ici->ops->get_formats(icd, i, NULL);
+			if (ret < 0)
+				return ret;
+			fmts += ret;
+		}
 
 	if (!fmts)
 		return -ENXIO;
@@ -248,20 +248,39 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
 			icd->user_formats[i].cam_fmt = icd->formats + i;
 			icd->user_formats[i].buswidth = icd->formats[i].depth;
 		} else {
-			fmts += ici->ops->get_formats(icd, i,
-						      &icd->user_formats[fmts]);
+			ret = ici->ops->get_formats(icd, i,
+						    &icd->user_formats[fmts]);
+			if (ret < 0)
+				goto egfmt;
+			fmts += ret;
 		}
 
 	icd->current_fmt = icd->user_formats[0].host_fmt;
 
 	return 0;
+
+egfmt:
+	icd->num_user_formats = 0;
+	vfree(icd->user_formats);
+	return ret;
 }
 
+/* Always entered with .video_lock held */
 static void soc_camera_free_user_formats(struct soc_camera_device *icd)
 {
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+
+	if (ici->ops->put_formats)
+		ici->ops->put_formats(icd);
+	icd->current_fmt = NULL;
+	icd->num_user_formats = 0;
 	vfree(icd->user_formats);
+	icd->user_formats = NULL;
 }
 
+#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
+	((x) >> 24) & 0xff
+
 /* Called with .vb_lock held */
 static int soc_camera_set_fmt(struct soc_camera_file *icf,
 			      struct v4l2_format *f)
@@ -271,6 +290,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	int ret;
 
+	dev_dbg(&icd->dev, "S_FMT(%c%c%c%c, %ux%u)\n",
+		pixfmtstr(pix->pixelformat), pix->width, pix->height);
+
 	/* We always call try_fmt() before set_fmt() or set_crop() */
 	ret = ici->ops->try_fmt(icd, f);
 	if (ret < 0)
@@ -281,13 +303,13 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
 		return ret;
 	} else if (!icd->current_fmt ||
 		   icd->current_fmt->fourcc != pix->pixelformat) {
-		dev_err(ici->dev,
+		dev_err(&icd->dev,
 			"Host driver hasn't set up current format correctly!\n");
 		return -EINVAL;
 	}
 
-	icd->width		= pix->width;
-	icd->height		= pix->height;
+	icd->user_width		= pix->width;
+	icd->user_height	= pix->height;
 	icf->vb_vidq.field	=
 		icd->field	= pix->field;
 
@@ -296,7 +318,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
 			 f->type);
 
 	dev_dbg(&icd->dev, "set width: %d height: %d\n",
-		icd->width, icd->height);
+		icd->user_width, icd->user_height);
 
 	/* set physical bus parameters */
 	return ici->ops->set_bus_param(icd, pix->pixelformat);
@@ -304,30 +326,24 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
 
 static int soc_camera_open(struct file *file)
 {
-	struct video_device *vdev;
-	struct soc_camera_device *icd;
+	struct video_device *vdev = video_devdata(file);
+	struct soc_camera_device *icd = container_of(vdev->parent,
+						     struct soc_camera_device,
+						     dev);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	struct soc_camera_host *ici;
 	struct soc_camera_file *icf;
 	int ret;
 
-	icf = vmalloc(sizeof(*icf));
-	if (!icf)
-		return -ENOMEM;
-
-	/*
-	 * It is safe to dereference these pointers now as long as a user has
-	 * the video device open - we are protected by the held cdev reference.
-	 */
+	if (!icd->ops)
+		/* No device driver attached */
+		return -ENODEV;
 
-	vdev = video_devdata(file);
-	icd = container_of(vdev->parent, struct soc_camera_device, dev);
 	ici = to_soc_camera_host(icd->dev.parent);
 
-	if (!try_module_get(icd->ops->owner)) {
-		dev_err(&icd->dev, "Couldn't lock sensor driver.\n");
-		ret = -EINVAL;
-		goto emgd;
-	}
+	icf = vmalloc(sizeof(*icf));
+	if (!icf)
+		return -ENOMEM;
 
 	if (!try_module_get(ici->ops->owner)) {
 		dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
@@ -335,7 +351,10 @@ static int soc_camera_open(struct file *file)
 		goto emgi;
 	}
 
-	/* Protect against icd->remove() until we module_get() both drivers. */
+	/*
+	 * Protect against icd->ops->remove() until we module_get() both
+	 * drivers.
+	 */
 	mutex_lock(&icd->video_lock);
 
 	icf->icd = icd;
@@ -347,14 +366,24 @@ static int soc_camera_open(struct file *file)
 		struct v4l2_format f = {
 			.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
 			.fmt.pix = {
-				.width		= icd->width,
-				.height		= icd->height,
+				.width		= icd->user_width,
+				.height		= icd->user_height,
 				.field		= icd->field,
 				.pixelformat	= icd->current_fmt->fourcc,
 				.colorspace	= icd->current_fmt->colorspace,
 			},
 		};
 
+		if (icl->power) {
+			ret = icl->power(icd->pdev, 1);
+			if (ret < 0)
+				goto epower;
+		}
+
+		/* The camera could have been already on, try to reset */
+		if (icl->reset)
+			icl->reset(icd->pdev);
+
 		ret = ici->ops->add(icd);
 		if (ret < 0) {
 			dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
@@ -367,28 +396,29 @@ static int soc_camera_open(struct file *file)
 			goto esfmt;
 	}
 
-	mutex_unlock(&icd->video_lock);
-
 	file->private_data = icf;
 	dev_dbg(&icd->dev, "camera device open\n");
 
 	ici->ops->init_videobuf(&icf->vb_vidq, icd);
 
+	mutex_unlock(&icd->video_lock);
+
 	return 0;
 
 	/*
-	 * First three errors are entered with the .video_lock held
+	 * First five errors are entered with the .video_lock held
 	 * and use_count == 1
 	 */
 esfmt:
 	ici->ops->remove(icd);
 eiciadd:
+	if (icl->power)
+		icl->power(icd->pdev, 0);
+epower:
 	icd->use_count--;
 	mutex_unlock(&icd->video_lock);
 	module_put(ici->ops->owner);
 emgi:
-	module_put(icd->ops->owner);
-emgd:
 	vfree(icf);
 	return ret;
 }
@@ -398,21 +428,24 @@ static int soc_camera_close(struct file *file)
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	struct video_device *vdev = icd->vdev;
 
 	mutex_lock(&icd->video_lock);
 	icd->use_count--;
-	if (!icd->use_count)
+	if (!icd->use_count) {
+		struct soc_camera_link *icl = to_soc_camera_link(icd);
+
 		ici->ops->remove(icd);
+		if (icl->power)
+			icl->power(icd->pdev, 0);
+	}
 
 	mutex_unlock(&icd->video_lock);
 
-	module_put(icd->ops->owner);
 	module_put(ici->ops->owner);
 
 	vfree(icf);
 
-	dev_dbg(vdev->parent, "camera device close\n");
+	dev_dbg(&icd->dev, "camera device close\n");
 
 	return 0;
 }
@@ -422,10 +455,9 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
-	struct video_device *vdev = icd->vdev;
 	int err = -EINVAL;
 
-	dev_err(vdev->parent, "camera device read not implemented\n");
+	dev_err(&icd->dev, "camera device read not implemented\n");
 
 	return err;
 }
@@ -483,8 +515,8 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
 
 	mutex_lock(&icf->vb_vidq.vb_lock);
 
-	if (videobuf_queue_is_busy(&icf->vb_vidq)) {
-		dev_err(&icd->dev, "S_FMT denied: queue busy\n");
+	if (icf->vb_vidq.bufs[0]) {
+		dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
 		ret = -EBUSY;
 		goto unlock;
 	}
@@ -525,8 +557,8 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
 
 	WARN_ON(priv != file->private_data);
 
-	pix->width		= icd->width;
-	pix->height		= icd->height;
+	pix->width		= icd->user_width;
+	pix->height		= icd->user_height;
 	pix->field		= icf->vb_vidq.field;
 	pix->pixelformat	= icd->current_fmt->fourcc;
 	pix->bytesperline	= pix->width *
@@ -555,18 +587,17 @@ static int soc_camera_streamon(struct file *file, void *priv,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 	int ret;
 
 	WARN_ON(priv != file->private_data);
 
-	dev_dbg(&icd->dev, "%s\n", __func__);
-
 	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
 	mutex_lock(&icd->video_lock);
 
-	icd->ops->start_capture(icd);
+	v4l2_subdev_call(sd, video, s_stream, 1);
 
 	/* This calls buf_queue from host driver's videobuf_queue_ops */
 	ret = videobuf_streamon(&icf->vb_vidq);
@@ -581,11 +612,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
 	WARN_ON(priv != file->private_data);
 
-	dev_dbg(&icd->dev, "%s\n", __func__);
-
 	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
@@ -595,7 +625,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
 	 * remaining buffers. When the last buffer is freed, stop capture */
 	videobuf_streamoff(&icf->vb_vidq);
 
-	icd->ops->stop_capture(icd);
+	v4l2_subdev_call(sd, video, s_stream, 0);
 
 	mutex_unlock(&icd->video_lock);
 
@@ -607,6 +637,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	int i;
 
 	WARN_ON(priv != file->private_data);
@@ -614,6 +645,15 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
 	if (!qc->id)
 		return -EINVAL;
 
+	/* First check host controls */
+	for (i = 0; i < ici->ops->num_controls; i++)
+		if (qc->id == ici->ops->controls[i].id) {
+			memcpy(qc, &(ici->ops->controls[i]),
+				sizeof(*qc));
+			return 0;
+		}
+
+	/* Then device controls */
 	for (i = 0; i < icd->ops->num_controls; i++)
 		if (qc->id == icd->ops->controls[i].id) {
 			memcpy(qc, &(icd->ops->controls[i]),
@@ -629,25 +669,19 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	int ret;
 
 	WARN_ON(priv != file->private_data);
 
-	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
-		if (icd->gain == (unsigned short)~0)
-			return -EINVAL;
-		ctrl->value = icd->gain;
-		return 0;
-	case V4L2_CID_EXPOSURE:
-		if (icd->exposure == (unsigned short)~0)
-			return -EINVAL;
-		ctrl->value = icd->exposure;
-		return 0;
+	if (ici->ops->get_ctrl) {
+		ret = ici->ops->get_ctrl(icd, ctrl);
+		if (ret != -ENOIOCTLCMD)
+			return ret;
 	}
 
-	if (icd->ops->get_control)
-		return icd->ops->get_control(icd, ctrl);
-	return -EINVAL;
+	return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
 }
 
 static int soc_camera_s_ctrl(struct file *file, void *priv,
@@ -655,12 +689,19 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	int ret;
 
 	WARN_ON(priv != file->private_data);
 
-	if (icd->ops->set_control)
-		return icd->ops->set_control(icd, ctrl);
-	return -EINVAL;
+	if (ici->ops->set_ctrl) {
+		ret = ici->ops->set_ctrl(icd, ctrl);
+		if (ret != -ENOIOCTLCMD)
+			return ret;
+	}
+
+	return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
 }
 
 static int soc_camera_cropcap(struct file *file, void *fh,
@@ -668,20 +709,9 @@ static int soc_camera_cropcap(struct file *file, void *fh,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 
-	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	a->bounds.left			= icd->x_min;
-	a->bounds.top			= icd->y_min;
-	a->bounds.width			= icd->width_max;
-	a->bounds.height		= icd->height_max;
-	a->defrect.left			= icd->x_min;
-	a->defrect.top			= icd->y_min;
-	a->defrect.width		= DEFAULT_WIDTH;
-	a->defrect.height		= DEFAULT_HEIGHT;
-	a->pixelaspect.numerator	= 1;
-	a->pixelaspect.denominator	= 1;
-
-	return 0;
+	return ici->ops->cropcap(icd, a);
 }
 
 static int soc_camera_g_crop(struct file *file, void *fh,
@@ -689,36 +719,53 @@ static int soc_camera_g_crop(struct file *file, void *fh,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	int ret;
 
-	a->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
-	a->c.left	= icd->x_current;
-	a->c.top	= icd->y_current;
-	a->c.width	= icd->width;
-	a->c.height	= icd->height;
+	mutex_lock(&icf->vb_vidq.vb_lock);
+	ret = ici->ops->get_crop(icd, a);
+	mutex_unlock(&icf->vb_vidq.vb_lock);
 
-	return 0;
+	return ret;
 }
 
+/*
+ * According to the V4L2 API, drivers shall not update the struct v4l2_crop
+ * argument with the actual geometry, instead, the user shall use G_CROP to
+ * retrieve it. However, we expect camera host and client drivers to update
+ * the argument, which we then use internally, but do not return to the user.
+ */
 static int soc_camera_s_crop(struct file *file, void *fh,
 			     struct v4l2_crop *a)
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct v4l2_rect *rect = &a->c;
+	struct v4l2_crop current_crop;
 	int ret;
 
 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
+	dev_dbg(&icd->dev, "S_CROP(%ux%u@%u:%u)\n",
+		rect->width, rect->height, rect->left, rect->top);
+
 	/* Cropping is allowed during a running capture, guard consistency */
 	mutex_lock(&icf->vb_vidq.vb_lock);
 
-	ret = ici->ops->set_crop(icd, &a->c);
-	if (!ret) {
-		icd->width	= a->c.width;
-		icd->height	= a->c.height;
-		icd->x_current	= a->c.left;
-		icd->y_current	= a->c.top;
+	/* If get_crop fails, we'll let host and / or client drivers decide */
+	ret = ici->ops->get_crop(icd, &current_crop);
+
+	/* Prohibit window size change with initialised buffers */
+	if (icf->vb_vidq.bufs[0] && !ret &&
+	    (a->c.width != current_crop.c.width ||
+	     a->c.height != current_crop.c.height)) {
+		dev_err(&icd->dev,
+			"S_CROP denied: queue initialised and sizes differ\n");
+		ret = -EBUSY;
+	} else {
+		ret = ici->ops->set_crop(icd, a);
 	}
 
 	mutex_unlock(&icf->vb_vidq.vb_lock);
@@ -731,11 +778,9 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-	if (!icd->ops->get_chip_id)
-		return -EINVAL;
-
-	return icd->ops->get_chip_id(icd, id);
+	return v4l2_subdev_call(sd, core, g_chip_ident, id);
 }
 
 #ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -744,11 +789,9 @@ static int soc_camera_g_register(struct file *file, void *fh,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-	if (!icd->ops->get_register)
-		return -EINVAL;
-
-	return icd->ops->get_register(icd, reg);
+	return v4l2_subdev_call(sd, core, g_register, reg);
 }
 
 static int soc_camera_s_register(struct file *file, void *fh,
@@ -756,37 +799,12 @@ static int soc_camera_s_register(struct file *file, void *fh,
 {
 	struct soc_camera_file *icf = file->private_data;
 	struct soc_camera_device *icd = icf->icd;
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
 
-	if (!icd->ops->set_register)
-		return -EINVAL;
-
-	return icd->ops->set_register(icd, reg);
+	return v4l2_subdev_call(sd, core, s_register, reg);
 }
 #endif
 
-static int device_register_link(struct soc_camera_device *icd)
-{
-	int ret = dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
-
-	if (!ret)
-		ret = device_register(&icd->dev);
-
-	if (ret < 0) {
-		/* Prevent calling device_unregister() */
-		icd->dev.parent = NULL;
-		dev_err(&icd->dev, "Cannot register device: %d\n", ret);
-	/* Even if probe() was unsuccessful for all registered drivers,
-	 * device_register() returns 0, and we add the link, just to
-	 * document this camera's control device */
-	} else if (icd->control)
-		/* Have to sysfs_remove_link() before device_unregister()? */
-		if (sysfs_create_link(&icd->dev.kobj, &icd->control->kobj,
-				      "control"))
-			dev_warn(&icd->dev,
-				 "Failed creating the control symlink\n");
-	return ret;
-}
-
 /* So far this function cannot fail */
 static void scan_add_host(struct soc_camera_host *ici)
 {
@@ -796,106 +814,193 @@ static void scan_add_host(struct soc_camera_host *ici)
 
 	list_for_each_entry(icd, &devices, list) {
 		if (icd->iface == ici->nr) {
-			icd->dev.parent = ici->dev;
-			device_register_link(icd);
+			int ret;
+			icd->dev.parent = ici->v4l2_dev.dev;
+			dev_set_name(&icd->dev, "%u-%u", icd->iface,
+				     icd->devnum);
+			ret = device_register(&icd->dev);
+			if (ret < 0) {
+				icd->dev.parent = NULL;
+				dev_err(&icd->dev,
+					"Cannot register device: %d\n", ret);
+			}
 		}
 	}
 
 	mutex_unlock(&list_lock);
 }
 
-/* return: 0 if no match found or a match found and
- * device_register() successful, error code otherwise */
-static int scan_add_device(struct soc_camera_device *icd)
+#ifdef CONFIG_I2C_BOARDINFO
+static int soc_camera_init_i2c(struct soc_camera_device *icd,
+			       struct soc_camera_link *icl)
 {
-	struct soc_camera_host *ici;
-	int ret = 0;
+	struct i2c_client *client;
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
+	struct v4l2_subdev *subdev;
+	int ret;
 
-	mutex_lock(&list_lock);
+	if (!adap) {
+		ret = -ENODEV;
+		dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
+			icl->i2c_adapter_id);
+		goto ei2cga;
+	}
 
-	list_add_tail(&icd->list, &devices);
+	icl->board_info->platform_data = icd;
 
-	/* Watch out for class_for_each_device / class_find_device API by
-	 * Dave Young <hidave.darkstar@gmail.com> */
-	list_for_each_entry(ici, &hosts, list) {
-		if (icd->iface == ici->nr) {
-			ret = 1;
-			icd->dev.parent = ici->dev;
-			break;
-		}
+	subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
+				icl->module_name, icl->board_info, NULL);
+	if (!subdev) {
+		ret = -ENOMEM;
+		goto ei2cnd;
 	}
 
-	mutex_unlock(&list_lock);
+	client = subdev->priv;
 
-	if (ret)
-		ret = device_register_link(icd);
+	/* Use to_i2c_client(dev) to recover the i2c client */
+	dev_set_drvdata(&icd->dev, &client->dev);
 
+	return 0;
+ei2cnd:
+	i2c_put_adapter(adap);
+ei2cga:
 	return ret;
 }
 
+static void soc_camera_free_i2c(struct soc_camera_device *icd)
+{
+	struct i2c_client *client =
+		to_i2c_client(to_soc_camera_control(icd));
+	dev_set_drvdata(&icd->dev, NULL);
+	v4l2_device_unregister_subdev(i2c_get_clientdata(client));
+	i2c_unregister_device(client);
+	i2c_put_adapter(client->adapter);
+}
+#else
+#define soc_camera_init_i2c(icd, icl)	(-ENODEV)
+#define soc_camera_free_i2c(icd)	do {} while (0)
+#endif
+
+static int soc_camera_video_start(struct soc_camera_device *icd);
+static int video_dev_create(struct soc_camera_device *icd);
+/* Called during host-driver probe */
 static int soc_camera_probe(struct device *dev)
 {
 	struct soc_camera_device *icd = to_soc_camera_dev(dev);
-	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct soc_camera_host *ici = to_soc_camera_host(dev->parent);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+	struct device *control = NULL;
+	struct v4l2_subdev *sd;
+	struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
 	int ret;
 
-	/*
-	 * Possible race scenario:
-	 * modprobe <camera-host-driver> triggers __func__
-	 * at this moment respective <camera-sensor-driver> gets rmmod'ed
-	 * to protect take module references.
-	 */
+	dev_info(dev, "Probing %s\n", dev_name(dev));
 
-	if (!try_module_get(icd->ops->owner)) {
-		dev_err(&icd->dev, "Couldn't lock sensor driver.\n");
-		ret = -EINVAL;
-		goto emgd;
+	if (icl->power) {
+		ret = icl->power(icd->pdev, 1);
+		if (ret < 0) {
+			dev_err(dev,
+				"Platform failed to power-on the camera.\n");
+			goto epower;
+		}
 	}
 
-	if (!try_module_get(ici->ops->owner)) {
-		dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
+	/* The camera could have been already on, try to reset */
+	if (icl->reset)
+		icl->reset(icd->pdev);
+
+	ret = ici->ops->add(icd);
+	if (ret < 0)
+		goto eadd;
+
+	/* Must have icd->vdev before registering the device */
+	ret = video_dev_create(icd);
+	if (ret < 0)
+		goto evdc;
+
+	/* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
+	if (icl->board_info) {
+		ret = soc_camera_init_i2c(icd, icl);
+		if (ret < 0)
+			goto eadddev;
+	} else if (!icl->add_device || !icl->del_device) {
 		ret = -EINVAL;
-		goto emgi;
+		goto eadddev;
+	} else {
+		if (icl->module_name)
+			ret = request_module(icl->module_name);
+
+		ret = icl->add_device(icl, &icd->dev);
+		if (ret < 0)
+			goto eadddev;
+
+		/*
+		 * FIXME: this is racy, have to use driver-binding notification,
+		 * when it is available
+		 */
+		control = to_soc_camera_control(icd);
+		if (!control || !control->driver || !dev_get_drvdata(control) ||
+		    !try_module_get(control->driver->owner)) {
+			icl->del_device(icl);
+			goto enodrv;
+		}
 	}
 
+	/* At this point client .probe() should have run already */
+	ret = soc_camera_init_user_formats(icd);
+	if (ret < 0)
+		goto eiufmt;
+
+	icd->field = V4L2_FIELD_ANY;
+
+	/* ..._video_start() will create a device node, so we have to protect */
 	mutex_lock(&icd->video_lock);
 
-	/* We only call ->add() here to activate and probe the camera.
-	 * We shall ->remove() and deactivate it immediately afterwards. */
-	ret = ici->ops->add(icd);
+	ret = soc_camera_video_start(icd);
 	if (ret < 0)
-		goto eiadd;
+		goto evidstart;
+
+	/* Try to improve our guess of a reasonable window format */
+	sd = soc_camera_to_subdev(icd);
+	if (!v4l2_subdev_call(sd, video, g_fmt, &f)) {
+		icd->user_width		= f.fmt.pix.width;
+		icd->user_height	= f.fmt.pix.height;
+	}
 
-	ret = icd->ops->probe(icd);
-	if (ret >= 0) {
-		const struct v4l2_queryctrl *qctrl;
+	/* Do we have to sysfs_remove_link() before device_unregister()? */
+	if (sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
+			      "control"))
+		dev_warn(&icd->dev, "Failed creating the control symlink\n");
 
-		qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN);
-		icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0;
-		qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
-		icd->exposure = qctrl ? qctrl->default_value :
-			(unsigned short)~0;
+	ici->ops->remove(icd);
 
-		ret = soc_camera_init_user_formats(icd);
-		if (ret < 0) {
-			if (icd->ops->remove)
-				icd->ops->remove(icd);
-			goto eiufmt;
-		}
+	if (icl->power)
+		icl->power(icd->pdev, 0);
 
-		icd->height	= DEFAULT_HEIGHT;
-		icd->width	= DEFAULT_WIDTH;
-		icd->field	= V4L2_FIELD_ANY;
-	}
+	mutex_unlock(&icd->video_lock);
 
+	return 0;
+
+evidstart:
+	mutex_unlock(&icd->video_lock);
+	soc_camera_free_user_formats(icd);
 eiufmt:
+	if (icl->board_info) {
+		soc_camera_free_i2c(icd);
+	} else {
+		icl->del_device(icl);
+		module_put(control->driver->owner);
+	}
+enodrv:
+eadddev:
+	video_device_release(icd->vdev);
+evdc:
 	ici->ops->remove(icd);
-eiadd:
-	mutex_unlock(&icd->video_lock);
-	module_put(ici->ops->owner);
-emgi:
-	module_put(icd->ops->owner);
-emgd:
+eadd:
+	if (icl->power)
+		icl->power(icd->pdev, 0);
+epower:
 	return ret;
 }
 
@@ -904,12 +1009,28 @@ emgd:
 static int soc_camera_remove(struct device *dev)
 {
 	struct soc_camera_device *icd = to_soc_camera_dev(dev);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
+	struct video_device *vdev = icd->vdev;
 
-	mutex_lock(&icd->video_lock);
-	if (icd->ops->remove)
-		icd->ops->remove(icd);
-	mutex_unlock(&icd->video_lock);
+	BUG_ON(!dev->parent);
 
+	if (vdev) {
+		mutex_lock(&icd->video_lock);
+		video_unregister_device(vdev);
+		icd->vdev = NULL;
+		mutex_unlock(&icd->video_lock);
+	}
+
+	if (icl->board_info) {
+		soc_camera_free_i2c(icd);
+	} else {
+		struct device_driver *drv = to_soc_camera_control(icd) ?
+			to_soc_camera_control(icd)->driver : NULL;
+		if (drv) {
+			icl->del_device(icl);
+			module_put(drv->owner);
+		}
+	}
 	soc_camera_free_user_formats(icd);
 
 	return 0;
@@ -957,14 +1078,33 @@ static void dummy_release(struct device *dev)
 {
 }
 
+static int default_cropcap(struct soc_camera_device *icd,
+			   struct v4l2_cropcap *a)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	return v4l2_subdev_call(sd, video, cropcap, a);
+}
+
+static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	return v4l2_subdev_call(sd, video, g_crop, a);
+}
+
+static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	return v4l2_subdev_call(sd, video, s_crop, a);
+}
+
 int soc_camera_host_register(struct soc_camera_host *ici)
 {
 	struct soc_camera_host *ix;
+	int ret;
 
 	if (!ici || !ici->ops ||
 	    !ici->ops->try_fmt ||
 	    !ici->ops->set_fmt ||
-	    !ici->ops->set_crop ||
 	    !ici->ops->set_bus_param ||
 	    !ici->ops->querycap ||
 	    !ici->ops->init_videobuf ||
@@ -972,18 +1112,27 @@ int soc_camera_host_register(struct soc_camera_host *ici)
 	    !ici->ops->add ||
 	    !ici->ops->remove ||
 	    !ici->ops->poll ||
-	    !ici->dev)
+	    !ici->v4l2_dev.dev)
 		return -EINVAL;
 
+	if (!ici->ops->set_crop)
+		ici->ops->set_crop = default_s_crop;
+	if (!ici->ops->get_crop)
+		ici->ops->get_crop = default_g_crop;
+	if (!ici->ops->cropcap)
+		ici->ops->cropcap = default_cropcap;
+
 	mutex_lock(&list_lock);
 	list_for_each_entry(ix, &hosts, list) {
 		if (ix->nr == ici->nr) {
-			mutex_unlock(&list_lock);
-			return -EBUSY;
+			ret = -EBUSY;
+			goto edevreg;
 		}
 	}
 
-	dev_set_drvdata(ici->dev, ici);
+	ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
+	if (ret < 0)
+		goto edevreg;
 
 	list_add_tail(&ici->list, &hosts);
 	mutex_unlock(&list_lock);
@@ -991,6 +1140,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
 	scan_add_host(ici);
 
 	return 0;
+
+edevreg:
+	mutex_unlock(&list_lock);
+	return ret;
 }
 EXPORT_SYMBOL(soc_camera_host_register);
 
@@ -1004,42 +1157,34 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
 	list_del(&ici->list);
 
 	list_for_each_entry(icd, &devices, list) {
-		if (icd->dev.parent == ici->dev) {
+		if (icd->iface == ici->nr) {
+			/* The bus->remove will be called */
 			device_unregister(&icd->dev);
 			/* Not before device_unregister(), .remove
 			 * needs parent to call ici->ops->remove() */
 			icd->dev.parent = NULL;
+
+			/* If the host module is loaded again, device_register()
+			 * would complain "already initialised" */
 			memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
 		}
 	}
 
 	mutex_unlock(&list_lock);
 
-	dev_set_drvdata(ici->dev, NULL);
+	v4l2_device_unregister(&ici->v4l2_dev);
 }
 EXPORT_SYMBOL(soc_camera_host_unregister);
 
 /* Image capture device */
-int soc_camera_device_register(struct soc_camera_device *icd)
+static int soc_camera_device_register(struct soc_camera_device *icd)
 {
 	struct soc_camera_device *ix;
 	int num = -1, i;
 
-	if (!icd || !icd->ops ||
-	    !icd->ops->probe ||
-	    !icd->ops->init ||
-	    !icd->ops->release ||
-	    !icd->ops->start_capture ||
-	    !icd->ops->stop_capture ||
-	    !icd->ops->set_crop ||
-	    !icd->ops->set_fmt ||
-	    !icd->ops->try_fmt ||
-	    !icd->ops->query_bus_param ||
-	    !icd->ops->set_bus_param)
-		return -EINVAL;
-
 	for (i = 0; i < 256 && num < 0; i++) {
 		num = i;
+		/* Check if this index is available on this interface */
 		list_for_each_entry(ix, &devices, list) {
 			if (ix->iface == icd->iface && ix->devnum == i) {
 				num = -1;
@@ -1061,21 +1206,15 @@ int soc_camera_device_register(struct soc_camera_device *icd)
 	icd->host_priv		= NULL;
 	mutex_init(&icd->video_lock);
 
-	return scan_add_device(icd);
+	list_add_tail(&icd->list, &devices);
+
+	return 0;
 }
-EXPORT_SYMBOL(soc_camera_device_register);
 
-void soc_camera_device_unregister(struct soc_camera_device *icd)
+static void soc_camera_device_unregister(struct soc_camera_device *icd)
 {
-	mutex_lock(&list_lock);
 	list_del(&icd->list);
-
-	/* The bus->remove will be eventually called */
-	if (icd->dev.parent)
-		device_unregister(&icd->dev);
-	mutex_unlock(&list_lock);
 }
-EXPORT_SYMBOL(soc_camera_device_unregister);
 
 static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
 	.vidioc_querycap	 = soc_camera_querycap,
@@ -1106,23 +1245,13 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
 #endif
 };
 
-/*
- * Usually called from the struct soc_camera_ops .probe() method, i.e., from
- * soc_camera_probe() above with .video_lock held
- */
-int soc_camera_video_start(struct soc_camera_device *icd)
+static int video_dev_create(struct soc_camera_device *icd)
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
-	int err = -ENOMEM;
-	struct video_device *vdev;
+	struct video_device *vdev = video_device_alloc();
 
-	if (!icd->dev.parent)
-		return -ENODEV;
-
-	vdev = video_device_alloc();
 	if (!vdev)
-		goto evidallocd;
-	dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
+		return -ENOMEM;
 
 	strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
 
@@ -1132,87 +1261,93 @@ int soc_camera_video_start(struct soc_camera_device *icd)
 	vdev->ioctl_ops		= &soc_camera_ioctl_ops;
 	vdev->release		= video_device_release;
 	vdev->minor		= -1;
-	vdev->tvnorms		= V4L2_STD_UNKNOWN,
+	vdev->tvnorms		= V4L2_STD_UNKNOWN;
 
-	err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
-	if (err < 0) {
-		dev_err(vdev->parent, "video_register_device failed\n");
-		goto evidregd;
-	}
 	icd->vdev = vdev;
 
 	return 0;
-
-evidregd:
-	video_device_release(vdev);
-evidallocd:
-	return err;
 }
-EXPORT_SYMBOL(soc_camera_video_start);
 
-/* Called from client .remove() methods with .video_lock held */
-void soc_camera_video_stop(struct soc_camera_device *icd)
+/*
+ * Called from soc_camera_probe() above (with .video_lock held???)
+ */
+static int soc_camera_video_start(struct soc_camera_device *icd)
 {
-	struct video_device *vdev = icd->vdev;
+	int ret;
 
-	dev_dbg(&icd->dev, "%s\n", __func__);
+	if (!icd->dev.parent)
+		return -ENODEV;
 
-	if (!icd->dev.parent || !vdev)
-		return;
+	if (!icd->ops ||
+	    !icd->ops->query_bus_param ||
+	    !icd->ops->set_bus_param)
+		return -EINVAL;
+
+	ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
+				    icd->vdev->minor);
+	if (ret < 0) {
+		dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
+		return ret;
+	}
 
-	video_unregister_device(vdev);
-	icd->vdev = NULL;
+	return 0;
 }
-EXPORT_SYMBOL(soc_camera_video_stop);
 
 static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
 {
 	struct soc_camera_link *icl = pdev->dev.platform_data;
-	struct i2c_adapter *adap;
-	struct i2c_client *client;
+	struct soc_camera_device *icd;
+	int ret;
 
 	if (!icl)
 		return -EINVAL;
 
-	adap = i2c_get_adapter(icl->i2c_adapter_id);
-	if (!adap) {
-		dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n",
-			 icl->i2c_adapter_id);
-		/* -ENODEV and -ENXIO do not produce an error on probe()... */
-		return -ENOENT;
-	}
-
-	icl->board_info->platform_data = icl;
-	client = i2c_new_device(adap, icl->board_info);
-	if (!client) {
-		i2c_put_adapter(adap);
+	icd = kzalloc(sizeof(*icd), GFP_KERNEL);
+	if (!icd)
 		return -ENOMEM;
-	}
 
-	platform_set_drvdata(pdev, client);
+	icd->iface = icl->bus_id;
+	icd->pdev = &pdev->dev;
+	platform_set_drvdata(pdev, icd);
+	icd->dev.platform_data = icl;
+
+	ret = soc_camera_device_register(icd);
+	if (ret < 0)
+		goto escdevreg;
+
+	icd->user_width		= DEFAULT_WIDTH;
+	icd->user_height	= DEFAULT_HEIGHT;
 
 	return 0;
+
+escdevreg:
+	kfree(icd);
+
+	return ret;
 }
 
+/* Only called on rmmod for each platform device, since they are not
+ * hot-pluggable. Now we know, that all our users - hosts and devices have
+ * been unloaded already */
 static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
 {
-	struct i2c_client *client = platform_get_drvdata(pdev);
+	struct soc_camera_device *icd = platform_get_drvdata(pdev);
 
-	if (!client)
-		return -ENODEV;
+	if (!icd)
+		return -EINVAL;
 
-	i2c_unregister_device(client);
-	i2c_put_adapter(client->adapter);
+	soc_camera_device_unregister(icd);
+
+	kfree(icd);
 
 	return 0;
 }
 
 static struct platform_driver __refdata soc_camera_pdrv = {
-	.probe	= soc_camera_pdrv_probe,
-	.remove	= __devexit_p(soc_camera_pdrv_remove),
-	.driver	= {
-		.name = "soc-camera-pdrv",
-		.owner = THIS_MODULE,
+	.remove  = __devexit_p(soc_camera_pdrv_remove),
+	.driver  = {
+		.name	= "soc-camera-pdrv",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -1225,7 +1360,7 @@ static int __init soc_camera_init(void)
 	if (ret)
 		goto edrvr;
 
-	ret = platform_driver_register(&soc_camera_pdrv);
+	ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe);
 	if (ret)
 		goto epdr;
 
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index c486763..b6a575c 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -16,54 +16,32 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-subdev.h>
 #include <media/soc_camera.h>
 #include <media/soc_camera_platform.h>
 
 struct soc_camera_platform_priv {
-	struct soc_camera_platform_info *info;
-	struct soc_camera_device icd;
+	struct v4l2_subdev subdev;
 	struct soc_camera_data_format format;
 };
 
-static struct soc_camera_platform_info *
-soc_camera_platform_get_info(struct soc_camera_device *icd)
+static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
 {
-	struct soc_camera_platform_priv *priv;
-	priv = container_of(icd, struct soc_camera_platform_priv, icd);
-	return priv->info;
-}
-
-static int soc_camera_platform_init(struct soc_camera_device *icd)
-{
-	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
-
-	if (p->power)
-		p->power(1);
-
-	return 0;
-}
-
-static int soc_camera_platform_release(struct soc_camera_device *icd)
-{
-	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
-
-	if (p->power)
-		p->power(0);
-
-	return 0;
+	struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
+	return container_of(subdev, struct soc_camera_platform_priv, subdev);
 }
 
-static int soc_camera_platform_start_capture(struct soc_camera_device *icd)
+static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd)
 {
-	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
-	return p->set_capture(p, 1);
+	struct platform_device *pdev =
+		to_platform_device(to_soc_camera_control(icd));
+	return pdev->dev.platform_data;
 }
 
-static int soc_camera_platform_stop_capture(struct soc_camera_device *icd)
+static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
-	return p->set_capture(p, 0);
+	struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
+	return p->set_capture(p, enable);
 }
 
 static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
@@ -75,26 +53,14 @@ static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
 static unsigned long
 soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
 {
-	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+	struct soc_camera_platform_info *p = get_info(icd);
 	return p->bus_param;
 }
 
-static int soc_camera_platform_set_crop(struct soc_camera_device *icd,
-					struct v4l2_rect *rect)
-{
-	return 0;
-}
-
-static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
+static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd,
 				       struct v4l2_format *f)
 {
-	return 0;
-}
-
-static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
-				       struct v4l2_format *f)
-{
-	struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+	struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 
 	pix->width = p->format.width;
@@ -102,82 +68,99 @@ static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int soc_camera_platform_video_probe(struct soc_camera_device *icd)
+static void soc_camera_platform_video_probe(struct soc_camera_device *icd,
+					    struct platform_device *pdev)
 {
-	struct soc_camera_platform_priv *priv;
-	priv = container_of(icd, struct soc_camera_platform_priv, icd);
+	struct soc_camera_platform_priv *priv = get_priv(pdev);
+	struct soc_camera_platform_info *p = pdev->dev.platform_data;
 
-	priv->format.name = priv->info->format_name;
-	priv->format.depth = priv->info->format_depth;
-	priv->format.fourcc = priv->info->format.pixelformat;
-	priv->format.colorspace = priv->info->format.colorspace;
+	priv->format.name = p->format_name;
+	priv->format.depth = p->format_depth;
+	priv->format.fourcc = p->format.pixelformat;
+	priv->format.colorspace = p->format.colorspace;
 
 	icd->formats = &priv->format;
 	icd->num_formats = 1;
-
-	return soc_camera_video_start(icd);
 }
 
-static void soc_camera_platform_video_remove(struct soc_camera_device *icd)
-{
-	soc_camera_video_stop(icd);
-}
+static struct v4l2_subdev_core_ops platform_subdev_core_ops;
+
+static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
+	.s_stream	= soc_camera_platform_s_stream,
+	.try_fmt	= soc_camera_platform_try_fmt,
+};
+
+static struct v4l2_subdev_ops platform_subdev_ops = {
+	.core	= &platform_subdev_core_ops,
+	.video	= &platform_subdev_video_ops,
+};
 
 static struct soc_camera_ops soc_camera_platform_ops = {
-	.owner			= THIS_MODULE,
-	.probe			= soc_camera_platform_video_probe,
-	.remove			= soc_camera_platform_video_remove,
-	.init			= soc_camera_platform_init,
-	.release		= soc_camera_platform_release,
-	.start_capture		= soc_camera_platform_start_capture,
-	.stop_capture		= soc_camera_platform_stop_capture,
-	.set_crop		= soc_camera_platform_set_crop,
-	.set_fmt		= soc_camera_platform_set_fmt,
-	.try_fmt		= soc_camera_platform_try_fmt,
 	.set_bus_param		= soc_camera_platform_set_bus_param,
 	.query_bus_param	= soc_camera_platform_query_bus_param,
 };
 
 static int soc_camera_platform_probe(struct platform_device *pdev)
 {
+	struct soc_camera_host *ici;
 	struct soc_camera_platform_priv *priv;
-	struct soc_camera_platform_info *p;
+	struct soc_camera_platform_info *p = pdev->dev.platform_data;
 	struct soc_camera_device *icd;
 	int ret;
 
-	p = pdev->dev.platform_data;
 	if (!p)
 		return -EINVAL;
 
+	if (!p->dev) {
+		dev_err(&pdev->dev,
+			"Platform has not set soc_camera_device pointer!\n");
+		return -EINVAL;
+	}
+
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	priv->info = p;
-	platform_set_drvdata(pdev, priv);
+	icd = to_soc_camera_dev(p->dev);
+
+	/* soc-camera convention: control's drvdata points to the subdev */
+	platform_set_drvdata(pdev, &priv->subdev);
+	/* Set the control device reference */
+	dev_set_drvdata(&icd->dev, &pdev->dev);
+
+	icd->y_skip_top		= 0;
+	icd->ops		= &soc_camera_platform_ops;
+
+	ici = to_soc_camera_host(icd->dev.parent);
 
-	icd = &priv->icd;
-	icd->ops	= &soc_camera_platform_ops;
-	icd->control	= &pdev->dev;
-	icd->width_min	= 0;
-	icd->width_max	= priv->info->format.width;
-	icd->height_min	= 0;
-	icd->height_max	= priv->info->format.height;
-	icd->y_skip_top	= 0;
-	icd->iface	= priv->info->iface;
+	soc_camera_platform_video_probe(icd, pdev);
 
-	ret = soc_camera_device_register(icd);
+	v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
+	v4l2_set_subdevdata(&priv->subdev, p);
+	strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
+
+	ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
 	if (ret)
-		kfree(priv);
+		goto evdrs;
+
+	return ret;
 
+evdrs:
+	icd->ops = NULL;
+	platform_set_drvdata(pdev, NULL);
+	kfree(priv);
 	return ret;
 }
 
 static int soc_camera_platform_remove(struct platform_device *pdev)
 {
-	struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev);
+	struct soc_camera_platform_priv *priv = get_priv(pdev);
+	struct soc_camera_platform_info *p = pdev->dev.platform_data;
+	struct soc_camera_device *icd = to_soc_camera_dev(p->dev);
 
-	soc_camera_device_unregister(&priv->icd);
+	v4l2_device_unregister_subdev(&priv->subdev);
+	icd->ops = NULL;
+	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
 	return 0;
 }
@@ -185,6 +168,7 @@ static int soc_camera_platform_remove(struct platform_device *pdev)
 static struct platform_driver soc_camera_platform_driver = {
 	.driver 	= {
 		.name	= "soc_camera_platform",
+		.owner	= THIS_MODULE,
 	},
 	.probe		= soc_camera_platform_probe,
 	.remove		= soc_camera_platform_remove,
@@ -206,3 +190,4 @@ module_exit(soc_camera_platform_module_exit);
 MODULE_DESCRIPTION("SoC Camera Platform driver");
 MODULE_AUTHOR("Magnus Damm");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:soc_camera_platform");
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index b154bd9..0b996ea 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -1400,7 +1400,6 @@ static int stk_camera_probe(struct usb_interface *interface,
 	}
 
 	stk_create_sysfs_files(&dev->vdev);
-	usb_autopm_enable(dev->interface);
 
 	return 0;
 
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 8b4e7da..6a91714 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -734,10 +734,6 @@ static int stv680_start_stream (struct usb_stv *stv680)
 	return 0;
 
  nomem_err:
-	for (i = 0; i < STV680_NUMSCRATCH; i++) {
-		kfree(stv680->scratch[i].data);
-		stv680->scratch[i].data = NULL;
-	}
 	for (i = 0; i < STV680_NUMSBUF; i++) {
 		usb_kill_urb(stv680->urb[i]);
 		usb_free_urb(stv680->urb[i]);
@@ -745,6 +741,11 @@ static int stv680_start_stream (struct usb_stv *stv680)
 		kfree(stv680->sbuf[i].data);
 		stv680->sbuf[i].data = NULL;
 	}
+	/* used in irq, free only as all URBs are dead */
+	for (i = 0; i < STV680_NUMSCRATCH; i++) {
+		kfree(stv680->scratch[i].data);
+		stv680->scratch[i].data = NULL;
+	}
 	return -ENOMEM;
 
 }
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 5375942..aba92e2 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -29,6 +29,7 @@
 #include "tuner-simple.h"
 #include "tda9887.h"
 #include "xc5000.h"
+#include "tda18271.h"
 
 #define UNSET (-1U)
 
@@ -420,6 +421,17 @@ static void set_type(struct i2c_client *c, unsigned int type,
 			goto attach_failed;
 		break;
 	}
+	case TUNER_NXP_TDA18271:
+	{
+		struct tda18271_config cfg = {
+			.config = t->config,
+		};
+
+		if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
+				t->i2c->adapter, &cfg))
+			goto attach_failed;
+		break;
+	}
 	default:
 		if (!dvb_attach(simple_tuner_attach, &t->fe,
 				t->i2c->adapter, t->i2c->addr, t->type))
@@ -819,8 +831,8 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 
 		fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
 		f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
-			(abs_freq * 2 + 125/2) / 125 :
-			(abs_freq + 62500/2) / 62500;
+			DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
+			DIV_ROUND_CLOSEST(abs_freq, 62500);
 		return 0;
 	}
 	f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index ac02808..d533ea5 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -646,14 +646,14 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
 		tvee->has_radio = 1;
 	}
 
-	if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
+	if (tuner1 < ARRAY_SIZE(hauppauge_tuner)) {
 		tvee->tuner_type = hauppauge_tuner[tuner1].id;
 		t_name1 = hauppauge_tuner[tuner1].name;
 	} else {
 		t_name1 = "unknown";
 	}
 
-	if (tuner2 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
+	if (tuner2 < ARRAY_SIZE(hauppauge_tuner)) {
 		tvee->tuner2_type = hauppauge_tuner[tuner2].id;
 		t_name2 = hauppauge_tuner[tuner2].name;
 	} else {
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 3750f7f..2443726 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -31,7 +31,10 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-int-device.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
 #include <media/tvp514x.h>
 
 #include "tvp514x_regs.h"
@@ -49,15 +52,11 @@ static int debug;
 module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, "Debug level (0-1)");
 
-#define dump_reg(client, reg, val)				\
-	do {							\
-		val = tvp514x_read_reg(client, reg);		\
-		v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
-	} while (0)
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("TVP514X linux decoder driver");
+MODULE_LICENSE("GPL");
 
-/**
- * enum tvp514x_std - enum for supported standards
- */
+/* enum tvp514x_std - enum for supported standards */
 enum tvp514x_std {
 	STD_NTSC_MJ = 0,
 	STD_PAL_BDGHIN,
@@ -65,14 +64,6 @@ enum tvp514x_std {
 };
 
 /**
- * enum tvp514x_state - enum for different decoder states
- */
-enum tvp514x_state {
-	STATE_NOT_DETECTED,
-	STATE_DETECTED
-};
-
-/**
  * struct tvp514x_std_info - Structure to store standard informations
  * @width: Line width in pixels
  * @height:Number of active lines
@@ -89,33 +80,27 @@ struct tvp514x_std_info {
 static struct tvp514x_reg tvp514x_reg_list_default[0x40];
 /**
  * struct tvp514x_decoder - TVP5146/47 decoder object
- * @v4l2_int_device: Slave handle
- * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device
+ * @sd: Subdevice Slave handle
  * @tvp514x_regs: copy of hw's regs with preset values.
  * @pdata: Board specific
- * @client: I2C client data
- * @id: Entry from I2C table
  * @ver: Chip version
- * @state: TVP5146/47 decoder state - detected or not-detected
+ * @streaming: TVP5146/47 decoder streaming - enabled or disabled.
  * @pix: Current pixel format
  * @num_fmts: Number of formats
  * @fmt_list: Format list
  * @current_std: Current standard
  * @num_stds: Number of standards
  * @std_list: Standards list
- * @route: input and output routing at chip level
+ * @input: Input routing at chip level
+ * @output: Output routing at chip level
  */
 struct tvp514x_decoder {
-	struct v4l2_int_device v4l2_int_device;
-	struct v4l2_int_slave tvp514x_slave;
+	struct v4l2_subdev sd;
 	struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
 	const struct tvp514x_platform_data *pdata;
-	struct i2c_client *client;
-
-	struct i2c_device_id *id;
 
 	int ver;
-	enum tvp514x_state state;
+	int streaming;
 
 	struct v4l2_pix_format pix;
 	int num_fmts;
@@ -124,15 +109,18 @@ struct tvp514x_decoder {
 	enum tvp514x_std current_std;
 	int num_stds;
 	struct tvp514x_std_info *std_list;
-
-	struct v4l2_routing route;
+	/* Input and Output Routing parameters */
+	u32 input;
+	u32 output;
 };
 
 /* TVP514x default register values */
 static struct tvp514x_reg tvp514x_reg_list_default[] = {
-	{TOK_WRITE, REG_INPUT_SEL, 0x05},	/* Composite selected */
+	/* Composite selected */
+	{TOK_WRITE, REG_INPUT_SEL, 0x05},
 	{TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
-	{TOK_WRITE, REG_VIDEO_STD, 0x00},	/* Auto mode */
+	/* Auto mode */
+	{TOK_WRITE, REG_VIDEO_STD, 0x00},
 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
 	{TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
 	{TOK_WRITE, REG_COLOR_KILLER, 0x10},
@@ -145,53 +133,74 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = {
 	{TOK_WRITE, REG_HUE, 0x00},
 	{TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
 	{TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
-	{TOK_SKIP, 0x0F, 0x00},	/* Reserved */
+	/* Reserved */
+	{TOK_SKIP, 0x0F, 0x00},
 	{TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
 	{TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
 	{TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
-	{TOK_SKIP, 0x13, 0x00},	/* Reserved */
+	/* Reserved */
+	{TOK_SKIP, 0x13, 0x00},
 	{TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
-	{TOK_SKIP, 0x15, 0x00},	/* Reserved */
-	{TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},	/* NTSC timing */
+	/* Reserved */
+	{TOK_SKIP, 0x15, 0x00},
+	/* NTSC timing */
+	{TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},
 	{TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
 	{TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
 	{TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
-	{TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},	/* NTSC timing */
+	/* NTSC timing */
+	{TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},
 	{TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
 	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
 	{TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
-	{TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},	/* NTSC timing */
+	/* NTSC timing */
+	{TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},
 	{TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
 	{TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
 	{TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
-	{TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},	/* NTSC timing */
+	/* NTSC timing */
+	{TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},
 	{TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
 	{TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
 	{TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
-	{TOK_SKIP, 0x26, 0x00},	/* Reserved */
-	{TOK_SKIP, 0x27, 0x00},	/* Reserved */
+	/* Reserved */
+	{TOK_SKIP, 0x26, 0x00},
+	/* Reserved */
+	{TOK_SKIP, 0x27, 0x00},
 	{TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
-	{TOK_SKIP, 0x29, 0x00},	/* Reserved */
+	/* Reserved */
+	{TOK_SKIP, 0x29, 0x00},
 	{TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
-	{TOK_SKIP, 0x2B, 0x00},	/* Reserved */
+	/* Reserved */
+	{TOK_SKIP, 0x2B, 0x00},
 	{TOK_SKIP, REG_SCART_DELAY, 0x00},
 	{TOK_SKIP, REG_CTI_DELAY, 0x00},
 	{TOK_SKIP, REG_CTI_CONTROL, 0x00},
-	{TOK_SKIP, 0x2F, 0x00},	/* Reserved */
-	{TOK_SKIP, 0x30, 0x00},	/* Reserved */
-	{TOK_SKIP, 0x31, 0x00},	/* Reserved */
-	{TOK_WRITE, REG_SYNC_CONTROL, 0x00},	/* HS, VS active high */
-	{TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},	/* 10-bit BT.656 */
-	{TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},	/* Enable clk & data */
-	{TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},	/* Enable AVID & FLD */
-	{TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},	/* Enable VS & HS */
+	/* Reserved */
+	{TOK_SKIP, 0x2F, 0x00},
+	/* Reserved */
+	{TOK_SKIP, 0x30, 0x00},
+	/* Reserved */
+	{TOK_SKIP, 0x31, 0x00},
+	/* HS, VS active high */
+	{TOK_WRITE, REG_SYNC_CONTROL, 0x00},
+	/* 10-bit BT.656 */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},
+	/* Enable clk & data */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},
+	/* Enable AVID & FLD */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},
+	/* Enable VS & HS */
+	{TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},
 	{TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
 	{TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
-	{TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},	/* Clear status */
+	/* Clear status */
+	{TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},
 	{TOK_TERM, 0, 0},
 };
 
-/* List of image formats supported by TVP5146/47 decoder
+/**
+ * List of image formats supported by TVP5146/47 decoder
  * Currently we are using 8 bit mode only, but can be
  * extended to 10/20 bit mode.
  */
@@ -205,7 +214,7 @@ static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
 	},
 };
 
-/*
+/**
  * Supported standards -
  *
  * Currently supports two standards only, need to add support for rest of the
@@ -240,35 +249,32 @@ static struct tvp514x_std_info tvp514x_std_list[] = {
 	},
 	/* Standard: need to add for additional standard */
 };
-/*
- * Control structure for Auto Gain
- *     This is temporary data, will get replaced once
- *     v4l2_ctrl_query_fill supports it.
- */
-static const struct v4l2_queryctrl tvp514x_autogain_ctrl = {
-	.id = V4L2_CID_AUTOGAIN,
-	.name = "Gain, Automatic",
-	.type = V4L2_CTRL_TYPE_BOOLEAN,
-	.minimum = 0,
-	.maximum = 1,
-	.step = 1,
-	.default_value = 1,
-};
 
-/*
- * Read a value from a register in an TVP5146/47 decoder device.
+
+static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct tvp514x_decoder, sd);
+}
+
+
+/**
+ * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
+ * @sd: ptr to v4l2_subdev struct
+ * @reg: TVP5146/47 register address
+ *
  * Returns value read if successful, or non-zero (-1) otherwise.
  */
-static int tvp514x_read_reg(struct i2c_client *client, u8 reg)
+static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg)
 {
-	int err;
-	int retry = 0;
+	int err, retry = 0;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 read_again:
 
 	err = i2c_smbus_read_byte_data(client, reg);
 	if (err == -1) {
 		if (retry <= I2C_RETRY_COUNT) {
-			v4l_warn(client, "Read: retry ... %d\n", retry);
+			v4l2_warn(sd, "Read: retry ... %d\n", retry);
 			retry++;
 			msleep_interruptible(10);
 			goto read_again;
@@ -278,20 +284,39 @@ read_again:
 	return err;
 }
 
-/*
+/**
+ * dump_reg() - dump the register content of TVP5146/47.
+ * @sd: ptr to v4l2_subdev struct
+ * @reg: TVP5146/47 register address
+ */
+static void dump_reg(struct v4l2_subdev *sd, u8 reg)
+{
+	u32 val;
+
+	val = tvp514x_read_reg(sd, reg);
+	v4l2_info(sd, "Reg(0x%.2X): 0x%.2X\n", reg, val);
+}
+
+/**
+ * tvp514x_write_reg() - Write a value to a register in TVP5146/47
+ * @sd: ptr to v4l2_subdev struct
+ * @reg: TVP5146/47 register address
+ * @val: value to be written to the register
+ *
  * Write a value to a register in an TVP5146/47 decoder device.
  * Returns zero if successful, or non-zero otherwise.
  */
-static int tvp514x_write_reg(struct i2c_client *client, u8 reg, u8 val)
+static int tvp514x_write_reg(struct v4l2_subdev *sd, u8 reg, u8 val)
 {
-	int err;
-	int retry = 0;
+	int err, retry = 0;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
 write_again:
 
 	err = i2c_smbus_write_byte_data(client, reg, val);
 	if (err) {
 		if (retry <= I2C_RETRY_COUNT) {
-			v4l_warn(client, "Write: retry ... %d\n", retry);
+			v4l2_warn(sd, "Write: retry ... %d\n", retry);
 			retry++;
 			msleep_interruptible(10);
 			goto write_again;
@@ -301,17 +326,19 @@ write_again:
 	return err;
 }
 
-/*
- * tvp514x_write_regs : Initializes a list of TVP5146/47 registers
+/**
+ * tvp514x_write_regs() : Initializes a list of TVP5146/47 registers
+ * @sd: ptr to v4l2_subdev struct
+ * @reglist: list of TVP5146/47 registers and values
+ *
+ * Initializes a list of TVP5146/47 registers:-
  *		if token is TOK_TERM, then entire write operation terminates
  *		if token is TOK_DELAY, then a delay of 'val' msec is introduced
  *		if token is TOK_SKIP, then the register write is skipped
  *		if token is TOK_WRITE, then the register write is performed
- *
- * reglist - list of registers to be written
  * Returns zero if successful, or non-zero otherwise.
  */
-static int tvp514x_write_regs(struct i2c_client *client,
+static int tvp514x_write_regs(struct v4l2_subdev *sd,
 			      const struct tvp514x_reg reglist[])
 {
 	int err;
@@ -326,31 +353,33 @@ static int tvp514x_write_regs(struct i2c_client *client,
 		if (next->token == TOK_SKIP)
 			continue;
 
-		err = tvp514x_write_reg(client, next->reg, (u8) next->val);
+		err = tvp514x_write_reg(sd, next->reg, (u8) next->val);
 		if (err) {
-			v4l_err(client, "Write failed. Err[%d]\n", err);
+			v4l2_err(sd, "Write failed. Err[%d]\n", err);
 			return err;
 		}
 	}
 	return 0;
 }
 
-/*
- * tvp514x_get_current_std:
- * Returns the current standard detected by TVP5146/47
+/**
+ * tvp514x_get_current_std() : Get the current standard detected by TVP5146/47
+ * @sd: ptr to v4l2_subdev struct
+ *
+ * Get current standard detected by TVP5146/47, STD_INVALID if there is no
+ * standard detected.
  */
-static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder
-						*decoder)
+static enum tvp514x_std tvp514x_get_current_std(struct v4l2_subdev *sd)
 {
 	u8 std, std_status;
 
-	std = tvp514x_read_reg(decoder->client, REG_VIDEO_STD);
-	if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) {
+	std = tvp514x_read_reg(sd, REG_VIDEO_STD);
+	if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT)
 		/* use the standard status register */
-		std_status = tvp514x_read_reg(decoder->client,
-				REG_VIDEO_STD_STATUS);
-	} else
-		std_status = std;	/* use the standard register itself */
+		std_status = tvp514x_read_reg(sd, REG_VIDEO_STD_STATUS);
+	else
+		/* use the standard register itself */
+		std_status = std;
 
 	switch (std_status & VIDEO_STD_MASK) {
 	case VIDEO_STD_NTSC_MJ_BIT:
@@ -366,94 +395,99 @@ static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder
 	return STD_INVALID;
 }
 
-/*
- * TVP5146/47 register dump function
- */
-static void tvp514x_reg_dump(struct tvp514x_decoder *decoder)
+/* TVP5146/47 register dump function */
+static void tvp514x_reg_dump(struct v4l2_subdev *sd)
 {
-	u8 value;
-
-	dump_reg(decoder->client, REG_INPUT_SEL, value);
-	dump_reg(decoder->client, REG_AFE_GAIN_CTRL, value);
-	dump_reg(decoder->client, REG_VIDEO_STD, value);
-	dump_reg(decoder->client, REG_OPERATION_MODE, value);
-	dump_reg(decoder->client, REG_COLOR_KILLER, value);
-	dump_reg(decoder->client, REG_LUMA_CONTROL1, value);
-	dump_reg(decoder->client, REG_LUMA_CONTROL2, value);
-	dump_reg(decoder->client, REG_LUMA_CONTROL3, value);
-	dump_reg(decoder->client, REG_BRIGHTNESS, value);
-	dump_reg(decoder->client, REG_CONTRAST, value);
-	dump_reg(decoder->client, REG_SATURATION, value);
-	dump_reg(decoder->client, REG_HUE, value);
-	dump_reg(decoder->client, REG_CHROMA_CONTROL1, value);
-	dump_reg(decoder->client, REG_CHROMA_CONTROL2, value);
-	dump_reg(decoder->client, REG_COMP_PR_SATURATION, value);
-	dump_reg(decoder->client, REG_COMP_Y_CONTRAST, value);
-	dump_reg(decoder->client, REG_COMP_PB_SATURATION, value);
-	dump_reg(decoder->client, REG_COMP_Y_BRIGHTNESS, value);
-	dump_reg(decoder->client, REG_AVID_START_PIXEL_LSB, value);
-	dump_reg(decoder->client, REG_AVID_START_PIXEL_MSB, value);
-	dump_reg(decoder->client, REG_AVID_STOP_PIXEL_LSB, value);
-	dump_reg(decoder->client, REG_AVID_STOP_PIXEL_MSB, value);
-	dump_reg(decoder->client, REG_HSYNC_START_PIXEL_LSB, value);
-	dump_reg(decoder->client, REG_HSYNC_START_PIXEL_MSB, value);
-	dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_LSB, value);
-	dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_MSB, value);
-	dump_reg(decoder->client, REG_VSYNC_START_LINE_LSB, value);
-	dump_reg(decoder->client, REG_VSYNC_START_LINE_MSB, value);
-	dump_reg(decoder->client, REG_VSYNC_STOP_LINE_LSB, value);
-	dump_reg(decoder->client, REG_VSYNC_STOP_LINE_MSB, value);
-	dump_reg(decoder->client, REG_VBLK_START_LINE_LSB, value);
-	dump_reg(decoder->client, REG_VBLK_START_LINE_MSB, value);
-	dump_reg(decoder->client, REG_VBLK_STOP_LINE_LSB, value);
-	dump_reg(decoder->client, REG_VBLK_STOP_LINE_MSB, value);
-	dump_reg(decoder->client, REG_SYNC_CONTROL, value);
-	dump_reg(decoder->client, REG_OUTPUT_FORMATTER1, value);
-	dump_reg(decoder->client, REG_OUTPUT_FORMATTER2, value);
-	dump_reg(decoder->client, REG_OUTPUT_FORMATTER3, value);
-	dump_reg(decoder->client, REG_OUTPUT_FORMATTER4, value);
-	dump_reg(decoder->client, REG_OUTPUT_FORMATTER5, value);
-	dump_reg(decoder->client, REG_OUTPUT_FORMATTER6, value);
-	dump_reg(decoder->client, REG_CLEAR_LOST_LOCK, value);
+	dump_reg(sd, REG_INPUT_SEL);
+	dump_reg(sd, REG_AFE_GAIN_CTRL);
+	dump_reg(sd, REG_VIDEO_STD);
+	dump_reg(sd, REG_OPERATION_MODE);
+	dump_reg(sd, REG_COLOR_KILLER);
+	dump_reg(sd, REG_LUMA_CONTROL1);
+	dump_reg(sd, REG_LUMA_CONTROL2);
+	dump_reg(sd, REG_LUMA_CONTROL3);
+	dump_reg(sd, REG_BRIGHTNESS);
+	dump_reg(sd, REG_CONTRAST);
+	dump_reg(sd, REG_SATURATION);
+	dump_reg(sd, REG_HUE);
+	dump_reg(sd, REG_CHROMA_CONTROL1);
+	dump_reg(sd, REG_CHROMA_CONTROL2);
+	dump_reg(sd, REG_COMP_PR_SATURATION);
+	dump_reg(sd, REG_COMP_Y_CONTRAST);
+	dump_reg(sd, REG_COMP_PB_SATURATION);
+	dump_reg(sd, REG_COMP_Y_BRIGHTNESS);
+	dump_reg(sd, REG_AVID_START_PIXEL_LSB);
+	dump_reg(sd, REG_AVID_START_PIXEL_MSB);
+	dump_reg(sd, REG_AVID_STOP_PIXEL_LSB);
+	dump_reg(sd, REG_AVID_STOP_PIXEL_MSB);
+	dump_reg(sd, REG_HSYNC_START_PIXEL_LSB);
+	dump_reg(sd, REG_HSYNC_START_PIXEL_MSB);
+	dump_reg(sd, REG_HSYNC_STOP_PIXEL_LSB);
+	dump_reg(sd, REG_HSYNC_STOP_PIXEL_MSB);
+	dump_reg(sd, REG_VSYNC_START_LINE_LSB);
+	dump_reg(sd, REG_VSYNC_START_LINE_MSB);
+	dump_reg(sd, REG_VSYNC_STOP_LINE_LSB);
+	dump_reg(sd, REG_VSYNC_STOP_LINE_MSB);
+	dump_reg(sd, REG_VBLK_START_LINE_LSB);
+	dump_reg(sd, REG_VBLK_START_LINE_MSB);
+	dump_reg(sd, REG_VBLK_STOP_LINE_LSB);
+	dump_reg(sd, REG_VBLK_STOP_LINE_MSB);
+	dump_reg(sd, REG_SYNC_CONTROL);
+	dump_reg(sd, REG_OUTPUT_FORMATTER1);
+	dump_reg(sd, REG_OUTPUT_FORMATTER2);
+	dump_reg(sd, REG_OUTPUT_FORMATTER3);
+	dump_reg(sd, REG_OUTPUT_FORMATTER4);
+	dump_reg(sd, REG_OUTPUT_FORMATTER5);
+	dump_reg(sd, REG_OUTPUT_FORMATTER6);
+	dump_reg(sd, REG_CLEAR_LOST_LOCK);
 }
 
-/*
- * Configure the TVP5146/47 with the current register settings
+/**
+ * tvp514x_configure() - Configure the TVP5146/47 registers
+ * @sd: ptr to v4l2_subdev struct
+ * @decoder: ptr to tvp514x_decoder structure
+ *
  * Returns zero if successful, or non-zero otherwise.
  */
-static int tvp514x_configure(struct tvp514x_decoder *decoder)
+static int tvp514x_configure(struct v4l2_subdev *sd,
+		struct tvp514x_decoder *decoder)
 {
 	int err;
 
 	/* common register initialization */
 	err =
-	    tvp514x_write_regs(decoder->client, decoder->tvp514x_regs);
+	    tvp514x_write_regs(sd, decoder->tvp514x_regs);
 	if (err)
 		return err;
 
 	if (debug)
-		tvp514x_reg_dump(decoder);
+		tvp514x_reg_dump(sd);
 
 	return 0;
 }
 
-/*
- * Detect if an tvp514x is present, and if so which revision.
+/**
+ * tvp514x_detect() - Detect if an tvp514x is present, and if so which revision.
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @decoder: pointer to tvp514x_decoder structure
+ *
  * A device is considered to be detected if the chip ID (LSB and MSB)
  * registers match the expected values.
  * Any value of the rom version register is accepted.
  * Returns ENODEV error number if no device is detected, or zero
  * if a device is detected.
  */
-static int tvp514x_detect(struct tvp514x_decoder *decoder)
+static int tvp514x_detect(struct v4l2_subdev *sd,
+		struct tvp514x_decoder *decoder)
 {
 	u8 chip_id_msb, chip_id_lsb, rom_ver;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	chip_id_msb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_MSB);
-	chip_id_lsb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_LSB);
-	rom_ver = tvp514x_read_reg(decoder->client, REG_ROM_VERSION);
+	chip_id_msb = tvp514x_read_reg(sd, REG_CHIP_ID_MSB);
+	chip_id_lsb = tvp514x_read_reg(sd, REG_CHIP_ID_LSB);
+	rom_ver = tvp514x_read_reg(sd, REG_ROM_VERSION);
 
-	v4l_dbg(1, debug, decoder->client,
+	v4l2_dbg(1, debug, sd,
 		 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
 		 chip_id_msb, chip_id_lsb, rom_ver);
 	if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
@@ -462,38 +496,30 @@ static int tvp514x_detect(struct tvp514x_decoder *decoder)
 		/* We didn't read the values we expected, so this must not be
 		 * an TVP5146/47.
 		 */
-		v4l_err(decoder->client,
-			"chip id mismatch msb:0x%x lsb:0x%x\n",
-			chip_id_msb, chip_id_lsb);
+		v4l2_err(sd, "chip id mismatch msb:0x%x lsb:0x%x\n",
+				chip_id_msb, chip_id_lsb);
 		return -ENODEV;
 	}
 
 	decoder->ver = rom_ver;
-	decoder->state = STATE_DETECTED;
 
-	v4l_info(decoder->client,
-			"%s found at 0x%x (%s)\n", decoder->client->name,
-			decoder->client->addr << 1,
-			decoder->client->adapter->name);
+	v4l2_info(sd, "%s (Version - 0x%.2x) found at 0x%x (%s)\n",
+			client->name, decoder->ver,
+			client->addr << 1, client->adapter->name);
 	return 0;
 }
 
-/*
- * Following are decoder interface functions implemented by
- * TVP5146/47 decoder driver.
- */
-
 /**
- * ioctl_querystd - V4L2 decoder interface handler for VIDIOC_QUERYSTD ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_querystd() - V4L2 decoder interface handler for querystd
+ * @sd: pointer to standard V4L2 sub-device structure
  * @std_id: standard V4L2 std_id ioctl enum
  *
  * Returns the current standard detected by TVP5146/47. If no active input is
  * detected, returns -EINVAL
  */
-static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
+static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	enum tvp514x_std current_std;
 	enum tvp514x_input input_sel;
 	u8 sync_lock_status, lock_mask;
@@ -502,11 +528,11 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
 		return -EINVAL;
 
 	/* get the current standard */
-	current_std = tvp514x_get_current_std(decoder);
+	current_std = tvp514x_get_current_std(sd);
 	if (current_std == STD_INVALID)
 		return -EINVAL;
 
-	input_sel = decoder->route.input;
+	input_sel = decoder->input;
 
 	switch (input_sel) {
 	case INPUT_CVBS_VI1A:
@@ -544,42 +570,39 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
 		return -EINVAL;
 	}
 	/* check whether signal is locked */
-	sync_lock_status = tvp514x_read_reg(decoder->client, REG_STATUS1);
+	sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
 	if (lock_mask != (sync_lock_status & lock_mask))
 		return -EINVAL;	/* No input detected */
 
 	decoder->current_std = current_std;
 	*std_id = decoder->std_list[current_std].standard.id;
 
-	v4l_dbg(1, debug, decoder->client, "Current STD: %s",
+	v4l2_dbg(1, debug, sd, "Current STD: %s",
 			decoder->std_list[current_std].standard.name);
 	return 0;
 }
 
 /**
- * ioctl_s_std - V4L2 decoder interface handler for VIDIOC_S_STD ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_s_std() - V4L2 decoder interface handler for s_std
+ * @sd: pointer to standard V4L2 sub-device structure
  * @std_id: standard V4L2 v4l2_std_id ioctl enum
  *
  * If std_id is supported, sets the requested standard. Otherwise, returns
  * -EINVAL
  */
-static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
+static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	int err, i;
 
-	if (std_id == NULL)
-		return -EINVAL;
-
 	for (i = 0; i < decoder->num_stds; i++)
-		if (*std_id & decoder->std_list[i].standard.id)
+		if (std_id & decoder->std_list[i].standard.id)
 			break;
 
 	if ((i == decoder->num_stds) || (i == STD_INVALID))
 		return -EINVAL;
 
-	err = tvp514x_write_reg(decoder->client, REG_VIDEO_STD,
+	err = tvp514x_write_reg(sd, REG_VIDEO_STD,
 				decoder->std_list[i].video_std);
 	if (err)
 		return err;
@@ -588,24 +611,26 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
 	decoder->tvp514x_regs[REG_VIDEO_STD].val =
 		decoder->std_list[i].video_std;
 
-	v4l_dbg(1, debug, decoder->client, "Standard set to: %s",
+	v4l2_dbg(1, debug, sd, "Standard set to: %s",
 			decoder->std_list[i].standard.name);
 	return 0;
 }
 
 /**
- * ioctl_s_routing - V4L2 decoder interface handler for VIDIOC_S_INPUT ioctl
- * @s: pointer to standard V4L2 device structure
- * @index: number of the input
+ * tvp514x_s_routing() - V4L2 decoder interface handler for s_routing
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @input: input selector for routing the signal
+ * @output: output selector for routing the signal
+ * @config: config value. Not used
  *
  * If index is valid, selects the requested input. Otherwise, returns -EINVAL if
  * the input is not supported or there is no active signal present in the
  * selected input.
  */
-static int ioctl_s_routing(struct v4l2_int_device *s,
-				struct v4l2_routing *route)
+static int tvp514x_s_routing(struct v4l2_subdev *sd,
+				u32 input, u32 output, u32 config)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	int err;
 	enum tvp514x_input input_sel;
 	enum tvp514x_output output_sel;
@@ -613,20 +638,21 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
 	u8 sync_lock_status, lock_mask;
 	int try_count = LOCK_RETRY_COUNT;
 
-	if ((!route) || (route->input >= INPUT_INVALID) ||
-			(route->output >= OUTPUT_INVALID))
-		return -EINVAL;	/* Index out of bound */
+	if ((input >= INPUT_INVALID) ||
+			(output >= OUTPUT_INVALID))
+		/* Index out of bound */
+		return -EINVAL;
 
-	input_sel = route->input;
-	output_sel = route->output;
+	input_sel = input;
+	output_sel = output;
 
-	err = tvp514x_write_reg(decoder->client, REG_INPUT_SEL, input_sel);
+	err = tvp514x_write_reg(sd, REG_INPUT_SEL, input_sel);
 	if (err)
 		return err;
 
-	output_sel |= tvp514x_read_reg(decoder->client,
+	output_sel |= tvp514x_read_reg(sd,
 			REG_OUTPUT_FORMATTER1) & 0x7;
-	err = tvp514x_write_reg(decoder->client, REG_OUTPUT_FORMATTER1,
+	err = tvp514x_write_reg(sd, REG_OUTPUT_FORMATTER1,
 			output_sel);
 	if (err)
 		return err;
@@ -637,7 +663,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
 	/* Clear status */
 	msleep(LOCK_RETRY_DELAY);
 	err =
-	    tvp514x_write_reg(decoder->client, REG_CLEAR_LOST_LOCK, 0x01);
+	    tvp514x_write_reg(sd, REG_CLEAR_LOST_LOCK, 0x01);
 	if (err)
 		return err;
 
@@ -672,7 +698,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
 		lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
 			STATUS_VIRT_SYNC_LOCK_BIT;
 		break;
-	/*Need to add other interfaces*/
+	/* Need to add other interfaces*/
 	default:
 		return -EINVAL;
 	}
@@ -682,42 +708,41 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
 		msleep(LOCK_RETRY_DELAY);
 
 		/* get the current standard for future reference */
-		current_std = tvp514x_get_current_std(decoder);
+		current_std = tvp514x_get_current_std(sd);
 		if (current_std == STD_INVALID)
 			continue;
 
-		sync_lock_status = tvp514x_read_reg(decoder->client,
+		sync_lock_status = tvp514x_read_reg(sd,
 				REG_STATUS1);
 		if (lock_mask == (sync_lock_status & lock_mask))
-			break;	/* Input detected */
+			/* Input detected */
+			break;
 	}
 
 	if ((current_std == STD_INVALID) || (try_count < 0))
 		return -EINVAL;
 
 	decoder->current_std = current_std;
-	decoder->route.input = route->input;
-	decoder->route.output = route->output;
+	decoder->input = input;
+	decoder->output = output;
 
-	v4l_dbg(1, debug, decoder->client,
-			"Input set to: %d, std : %d",
+	v4l2_dbg(1, debug, sd, "Input set to: %d, std : %d",
 			input_sel, current_std);
 
 	return 0;
 }
 
 /**
- * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl
+ * @sd: pointer to standard V4L2 sub-device structure
  * @qctrl: standard V4L2 v4l2_queryctrl structure
  *
  * If the requested control is supported, returns the control information.
  * Otherwise, returns -EINVAL if the control is not supported.
  */
 static int
-ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
+tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
 {
-	struct tvp514x_decoder *decoder = s->priv;
 	int err = -EINVAL;
 
 	if (qctrl == NULL)
@@ -725,13 +750,13 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
 
 	switch (qctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
-		/* Brightness supported is (0-255),
-		 */
+		/* Brightness supported is (0-255), */
 		err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
 		break;
 	case V4L2_CID_CONTRAST:
 	case V4L2_CID_SATURATION:
-		/* Saturation and Contrast supported is -
+		/**
+		 * Saturation and Contrast supported is -
 		 *	Contrast: 0 - 255 (Default - 128)
 		 *	Saturation: 0 - 255 (Default - 128)
 		 */
@@ -744,30 +769,27 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
 		err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
 		break;
 	case V4L2_CID_AUTOGAIN:
-		/* Autogain is either 0 or 1*/
-		memcpy(qctrl, &tvp514x_autogain_ctrl,
-				sizeof(struct v4l2_queryctrl));
-		err = 0;
+		/**
+		 * Auto Gain supported is -
+		 * 	0 - 1 (Default - 1)
+		 */
+		err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
 		break;
 	default:
-		v4l_err(decoder->client,
-			"invalid control id %d\n", qctrl->id);
+		v4l2_err(sd, "invalid control id %d\n", qctrl->id);
 		return err;
 	}
 
-	v4l_dbg(1, debug, decoder->client,
-			"Query Control: %s : Min - %d, Max - %d, Def - %d",
-			qctrl->name,
-			qctrl->minimum,
-			qctrl->maximum,
+	v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d",
+			qctrl->name, qctrl->minimum, qctrl->maximum,
 			qctrl->default_value);
 
 	return err;
 }
 
 /**
- * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl
+ * @sd: pointer to standard V4L2 sub-device structure
  * @ctrl: pointer to v4l2_control structure
  *
  * If the requested control is supported, returns the control's current
@@ -775,9 +797,9 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
  * supported.
  */
 static int
-ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
+tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 
 	if (ctrl == NULL)
 		return -EINVAL;
@@ -811,74 +833,70 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
 
 		break;
 	default:
-		v4l_err(decoder->client,
-			"invalid control id %d\n", ctrl->id);
+		v4l2_err(sd, "invalid control id %d\n", ctrl->id);
 		return -EINVAL;
 	}
 
-	v4l_dbg(1, debug, decoder->client,
-			"Get Control: ID - %d - %d",
+	v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d",
 			ctrl->id, ctrl->value);
 	return 0;
 }
 
 /**
- * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
+ * @sd: pointer to standard V4L2 sub-device structure
  * @ctrl: pointer to v4l2_control structure
  *
  * If the requested control is supported, sets the control's current
  * value in HW. Otherwise, returns -EINVAL if the control is not supported.
  */
 static int
-ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
+tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	int err = -EINVAL, value;
 
 	if (ctrl == NULL)
 		return err;
 
-	value = (__s32) ctrl->value;
+	value = ctrl->value;
 
 	switch (ctrl->id) {
 	case V4L2_CID_BRIGHTNESS:
 		if (ctrl->value < 0 || ctrl->value > 255) {
-			v4l_err(decoder->client,
-					"invalid brightness setting %d\n",
+			v4l2_err(sd, "invalid brightness setting %d\n",
 					ctrl->value);
 			return -ERANGE;
 		}
-		err = tvp514x_write_reg(decoder->client, REG_BRIGHTNESS,
+		err = tvp514x_write_reg(sd, REG_BRIGHTNESS,
 				value);
 		if (err)
 			return err;
+
 		decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
 		break;
 	case V4L2_CID_CONTRAST:
 		if (ctrl->value < 0 || ctrl->value > 255) {
-			v4l_err(decoder->client,
-					"invalid contrast setting %d\n",
+			v4l2_err(sd, "invalid contrast setting %d\n",
 					ctrl->value);
 			return -ERANGE;
 		}
-		err = tvp514x_write_reg(decoder->client, REG_CONTRAST,
-				value);
+		err = tvp514x_write_reg(sd, REG_CONTRAST, value);
 		if (err)
 			return err;
+
 		decoder->tvp514x_regs[REG_CONTRAST].val = value;
 		break;
 	case V4L2_CID_SATURATION:
 		if (ctrl->value < 0 || ctrl->value > 255) {
-			v4l_err(decoder->client,
-					"invalid saturation setting %d\n",
+			v4l2_err(sd, "invalid saturation setting %d\n",
 					ctrl->value);
 			return -ERANGE;
 		}
-		err = tvp514x_write_reg(decoder->client, REG_SATURATION,
-				value);
+		err = tvp514x_write_reg(sd, REG_SATURATION, value);
 		if (err)
 			return err;
+
 		decoder->tvp514x_regs[REG_SATURATION].val = value;
 		break;
 	case V4L2_CID_HUE:
@@ -889,15 +907,13 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
 		else if (value == 0)
 			value = 0;
 		else {
-			v4l_err(decoder->client,
-					"invalid hue setting %d\n",
-					ctrl->value);
+			v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
 			return -ERANGE;
 		}
-		err = tvp514x_write_reg(decoder->client, REG_HUE,
-				value);
+		err = tvp514x_write_reg(sd, REG_HUE, value);
 		if (err)
 			return err;
+
 		decoder->tvp514x_regs[REG_HUE].val = value;
 		break;
 	case V4L2_CID_AUTOGAIN:
@@ -906,41 +922,38 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
 		else if (value == 0)
 			value = 0x0C;
 		else {
-			v4l_err(decoder->client,
-					"invalid auto gain setting %d\n",
+			v4l2_err(sd, "invalid auto gain setting %d\n",
 					ctrl->value);
 			return -ERANGE;
 		}
-		err = tvp514x_write_reg(decoder->client, REG_AFE_GAIN_CTRL,
-				value);
+		err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value);
 		if (err)
 			return err;
+
 		decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
 		break;
 	default:
-		v4l_err(decoder->client,
-			"invalid control id %d\n", ctrl->id);
+		v4l2_err(sd, "invalid control id %d\n", ctrl->id);
 		return err;
 	}
 
-	v4l_dbg(1, debug, decoder->client,
-			"Set Control: ID - %d - %d",
+	v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d",
 			ctrl->id, ctrl->value);
 
 	return err;
 }
 
 /**
- * ioctl_enum_fmt_cap - Implement the CAPTURE buffer VIDIOC_ENUM_FMT ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_enum_fmt_cap() - V4L2 decoder interface handler for enum_fmt
+ * @sd: pointer to standard V4L2 sub-device structure
  * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure
  *
  * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats
  */
 static int
-ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
+tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	int index;
 
 	if (fmt == NULL)
@@ -948,24 +961,25 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
 
 	index = fmt->index;
 	if ((index >= decoder->num_fmts) || (index < 0))
-		return -EINVAL;	/* Index out of bound */
+		/* Index out of bound */
+		return -EINVAL;
 
 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;	/* only capture is supported */
+		/* only capture is supported */
+		return -EINVAL;
 
 	memcpy(fmt, &decoder->fmt_list[index],
 		sizeof(struct v4l2_fmtdesc));
 
-	v4l_dbg(1, debug, decoder->client,
-			"Current FMT: index - %d (%s)",
+	v4l2_dbg(1, debug, sd, "Current FMT: index - %d (%s)",
 			decoder->fmt_list[index].index,
 			decoder->fmt_list[index].description);
 	return 0;
 }
 
 /**
- * ioctl_try_fmt_cap - Implement the CAPTURE buffer VIDIOC_TRY_FMT ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_try_fmt_cap() - V4L2 decoder interface handler for try_fmt
+ * @sd: pointer to standard V4L2 sub-device structure
  * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
  *
  * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
@@ -973,9 +987,9 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
  * without actually making it take effect.
  */
 static int
-ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	int ifmt;
 	struct v4l2_pix_format *pix;
 	enum tvp514x_std current_std;
@@ -984,12 +998,13 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
 		return -EINVAL;
 
 	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		/* only capture is supported */
 		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
 	pix = &f->fmt.pix;
 
 	/* Calculate height and width based on current standard */
-	current_std = tvp514x_get_current_std(decoder);
+	current_std = tvp514x_get_current_std(sd);
 	if (current_std == STD_INVALID)
 		return -EINVAL;
 
@@ -1003,7 +1018,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
 			break;
 	}
 	if (ifmt == decoder->num_fmts)
-		ifmt = 0;	/* None of the format matched, select default */
+		/* None of the format matched, select default */
+		ifmt = 0;
 	pix->pixelformat = decoder->fmt_list[ifmt].pixelformat;
 
 	pix->field = V4L2_FIELD_INTERLACED;
@@ -1012,8 +1028,7 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
 	pix->priv = 0;
 
-	v4l_dbg(1, debug, decoder->client,
-			"Try FMT: pixelformat - %s, bytesperline - %d"
+	v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d"
 			"Width - %d, Height - %d",
 			decoder->fmt_list[ifmt].description, pix->bytesperline,
 			pix->width, pix->height);
@@ -1021,8 +1036,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
 }
 
 /**
- * ioctl_s_fmt_cap - V4L2 decoder interface handler for VIDIOC_S_FMT ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_s_fmt_cap() - V4L2 decoder interface handler for s_fmt
+ * @sd: pointer to standard V4L2 sub-device structure
  * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
  *
  * If the requested format is supported, configures the HW to use that
@@ -1030,9 +1045,9 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
  * correctly configured.
  */
 static int
-ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+tvp514x_s_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	struct v4l2_pix_format *pix;
 	int rval;
 
@@ -1040,10 +1055,11 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
 		return -EINVAL;
 
 	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;	/* only capture is supported */
+		/* only capture is supported */
+		return -EINVAL;
 
 	pix = &f->fmt.pix;
-	rval = ioctl_try_fmt_cap(s, f);
+	rval = tvp514x_try_fmt_cap(sd, f);
 	if (rval)
 		return rval;
 
@@ -1053,28 +1069,28 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
 }
 
 /**
- * ioctl_g_fmt_cap - V4L2 decoder interface handler for ioctl_g_fmt_cap
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_g_fmt_cap() - V4L2 decoder interface handler for tvp514x_g_fmt_cap
+ * @sd: pointer to standard V4L2 sub-device structure
  * @f: pointer to standard V4L2 v4l2_format structure
  *
  * Returns the decoder's current pixel format in the v4l2_format
  * parameter.
  */
 static int
-ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 
 	if (f == NULL)
 		return -EINVAL;
 
 	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;	/* only capture is supported */
+		/* only capture is supported */
+		return -EINVAL;
 
 	f->fmt.pix = decoder->pix;
 
-	v4l_dbg(1, debug, decoder->client,
-			"Current FMT: bytesperline - %d"
+	v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
 			"Width - %d, Height - %d",
 			decoder->pix.bytesperline,
 			decoder->pix.width, decoder->pix.height);
@@ -1082,16 +1098,16 @@ ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
 }
 
 /**
- * ioctl_g_parm - V4L2 decoder interface handler for VIDIOC_G_PARM ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm
+ * @sd: pointer to standard V4L2 sub-device structure
  * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
  *
  * Returns the decoder's video CAPTURE parameters.
  */
 static int
-ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	struct v4l2_captureparm *cparm;
 	enum tvp514x_std current_std;
 
@@ -1099,13 +1115,14 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
 		return -EINVAL;
 
 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;	/* only capture is supported */
+		/* only capture is supported */
+		return -EINVAL;
 
 	memset(a, 0, sizeof(*a));
 	a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
 	/* get the current standard */
-	current_std = tvp514x_get_current_std(decoder);
+	current_std = tvp514x_get_current_std(sd);
 	if (current_std == STD_INVALID)
 		return -EINVAL;
 
@@ -1120,17 +1137,17 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
 }
 
 /**
- * ioctl_s_parm - V4L2 decoder interface handler for VIDIOC_S_PARM ioctl
- * @s: pointer to standard V4L2 device structure
+ * tvp514x_s_parm() - V4L2 decoder interface handler for s_parm
+ * @sd: pointer to standard V4L2 sub-device structure
  * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
  *
  * Configures the decoder to use the input parameters, if possible. If
  * not possible, returns the appropriate error code.
  */
 static int
-ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
 {
-	struct tvp514x_decoder *decoder = s->priv;
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 	struct v4l2_fract *timeperframe;
 	enum tvp514x_std current_std;
 
@@ -1138,12 +1155,13 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
 		return -EINVAL;
 
 	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		return -EINVAL;	/* only capture is supported */
+		/* only capture is supported */
+		return -EINVAL;
 
 	timeperframe = &a->parm.capture.timeperframe;
 
 	/* get the current standard */
-	current_std = tvp514x_get_current_std(decoder);
+	current_std = tvp514x_get_current_std(sd);
 	if (current_std == STD_INVALID)
 		return -EINVAL;
 
@@ -1156,111 +1174,58 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
 }
 
 /**
- * ioctl_g_ifparm - V4L2 decoder interface handler for vidioc_int_g_ifparm_num
- * @s: pointer to standard V4L2 device structure
- * @p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure
- *
- * Gets slave interface parameters.
- * Calculates the required xclk value to support the requested
- * clock parameters in p. This value is returned in the p
- * parameter.
- */
-static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
-{
-	struct tvp514x_decoder *decoder = s->priv;
-	int rval;
-
-	if (p == NULL)
-		return -EINVAL;
-
-	if (NULL == decoder->pdata->ifparm)
-		return -EINVAL;
-
-	rval = decoder->pdata->ifparm(p);
-	if (rval) {
-		v4l_err(decoder->client, "g_ifparm.Err[%d]\n", rval);
-		return rval;
-	}
-
-	p->u.bt656.clock_curr = TVP514X_XCLK_BT656;
-
-	return 0;
-}
-
-/**
- * ioctl_g_priv - V4L2 decoder interface handler for vidioc_int_g_priv_num
- * @s: pointer to standard V4L2 device structure
- * @p: void pointer to hold decoder's private data address
- *
- * Returns device's (decoder's) private data area address in p parameter
- */
-static int ioctl_g_priv(struct v4l2_int_device *s, void *p)
-{
-	struct tvp514x_decoder *decoder = s->priv;
-
-	if (NULL == decoder->pdata->priv_data_set)
-		return -EINVAL;
-
-	return decoder->pdata->priv_data_set(p);
-}
-
-/**
- * ioctl_s_power - V4L2 decoder interface handler for vidioc_int_s_power_num
- * @s: pointer to standard V4L2 device structure
- * @on: power state to which device is to be set
+ * tvp514x_s_stream() - V4L2 decoder i/f handler for s_stream
+ * @sd: pointer to standard V4L2 sub-device structure
+ * @enable: streaming enable or disable
  *
- * Sets devices power state to requrested state, if possible.
+ * Sets streaming to enable or disable, if possible.
  */
-static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on)
+static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct tvp514x_decoder *decoder = s->priv;
 	int err = 0;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 
-	switch (on) {
-	case V4L2_POWER_OFF:
-		/* Power Down Sequence */
-		err =
-		    tvp514x_write_reg(decoder->client, REG_OPERATION_MODE,
-					0x01);
-		/* Disable mux for TVP5146/47 decoder data path */
-		if (decoder->pdata->power_set)
-			err |= decoder->pdata->power_set(on);
-		decoder->state = STATE_NOT_DETECTED;
-		break;
+	if (decoder->streaming == enable)
+		return 0;
 
-	case V4L2_POWER_STANDBY:
-		if (decoder->pdata->power_set)
-			err = decoder->pdata->power_set(on);
+	switch (enable) {
+	case 0:
+	{
+		/* Power Down Sequence */
+		err = tvp514x_write_reg(sd, REG_OPERATION_MODE, 0x01);
+		if (err) {
+			v4l2_err(sd, "Unable to turn off decoder\n");
+			return err;
+		}
+		decoder->streaming = enable;
 		break;
+	}
+	case 1:
+	{
+		struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
+				client->driver->id_table->driver_data;
 
-	case V4L2_POWER_ON:
-		/* Enable mux for TVP5146/47 decoder data path */
-		if ((decoder->pdata->power_set) &&
-				(decoder->state == STATE_NOT_DETECTED)) {
-			int i;
-			struct tvp514x_init_seq *int_seq =
-				(struct tvp514x_init_seq *)
-				decoder->id->driver_data;
-
-			err = decoder->pdata->power_set(on);
-
-			/* Power Up Sequence */
-			for (i = 0; i < int_seq->no_regs; i++) {
-				err |= tvp514x_write_reg(decoder->client,
-						int_seq->init_reg_seq[i].reg,
-						int_seq->init_reg_seq[i].val);
-			}
-			/* Detect the sensor is not already detected */
-			err |= tvp514x_detect(decoder);
-			if (err) {
-				v4l_err(decoder->client,
-						"Unable to detect decoder\n");
-				return err;
-			}
+		/* Power Up Sequence */
+		err = tvp514x_write_regs(sd, int_seq);
+		if (err) {
+			v4l2_err(sd, "Unable to turn on decoder\n");
+			return err;
 		}
-		err |= tvp514x_configure(decoder);
+		/* Detect if not already detected */
+		err = tvp514x_detect(sd, decoder);
+		if (err) {
+			v4l2_err(sd, "Unable to detect decoder\n");
+			return err;
+		}
+		err = tvp514x_configure(sd, decoder);
+		if (err) {
+			v4l2_err(sd, "Unable to configure decoder\n");
+			return err;
+		}
+		decoder->streaming = enable;
 		break;
-
+	}
 	default:
 		err = -ENODEV;
 		break;
@@ -1269,93 +1234,38 @@ static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on)
 	return err;
 }
 
-/**
- * ioctl_init - V4L2 decoder interface handler for VIDIOC_INT_INIT
- * @s: pointer to standard V4L2 device structure
- *
- * Initialize the decoder device (calls tvp514x_configure())
- */
-static int ioctl_init(struct v4l2_int_device *s)
-{
-	struct tvp514x_decoder *decoder = s->priv;
-
-	/* Set default standard to auto */
-	decoder->tvp514x_regs[REG_VIDEO_STD].val =
-	    VIDEO_STD_AUTO_SWITCH_BIT;
-
-	return tvp514x_configure(decoder);
-}
-
-/**
- * ioctl_dev_exit - V4L2 decoder interface handler for vidioc_int_dev_exit_num
- * @s: pointer to standard V4L2 device structure
- *
- * Delinitialise the dev. at slave detach. The complement of ioctl_dev_init.
- */
-static int ioctl_dev_exit(struct v4l2_int_device *s)
-{
-	return 0;
-}
-
-/**
- * ioctl_dev_init - V4L2 decoder interface handler for vidioc_int_dev_init_num
- * @s: pointer to standard V4L2 device structure
- *
- * Initialise the device when slave attaches to the master. Returns 0 if
- * TVP5146/47 device could be found, otherwise returns appropriate error.
- */
-static int ioctl_dev_init(struct v4l2_int_device *s)
-{
-	struct tvp514x_decoder *decoder = s->priv;
-	int err;
-
-	err = tvp514x_detect(decoder);
-	if (err < 0) {
-		v4l_err(decoder->client,
-			"Unable to detect decoder\n");
-		return err;
-	}
-
-	v4l_info(decoder->client,
-		 "chip version 0x%.2x detected\n", decoder->ver);
+static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
+	.queryctrl = tvp514x_queryctrl,
+	.g_ctrl = tvp514x_g_ctrl,
+	.s_ctrl = tvp514x_s_ctrl,
+	.s_std = tvp514x_s_std,
+};
 
-	return 0;
-}
+static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
+	.s_routing = tvp514x_s_routing,
+	.querystd = tvp514x_querystd,
+	.enum_fmt = tvp514x_enum_fmt_cap,
+	.g_fmt = tvp514x_g_fmt_cap,
+	.try_fmt = tvp514x_try_fmt_cap,
+	.s_fmt = tvp514x_s_fmt_cap,
+	.g_parm = tvp514x_g_parm,
+	.s_parm = tvp514x_s_parm,
+	.s_stream = tvp514x_s_stream,
+};
 
-static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = {
-	{vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init},
-	{vidioc_int_dev_exit_num, (v4l2_int_ioctl_func*) ioctl_dev_exit},
-	{vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power},
-	{vidioc_int_g_priv_num, (v4l2_int_ioctl_func*) ioctl_g_priv},
-	{vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm},
-	{vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init},
-	{vidioc_int_enum_fmt_cap_num,
-	 (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
-	{vidioc_int_try_fmt_cap_num,
-	 (v4l2_int_ioctl_func *) ioctl_try_fmt_cap},
-	{vidioc_int_g_fmt_cap_num,
-	 (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
-	{vidioc_int_s_fmt_cap_num,
-	 (v4l2_int_ioctl_func *) ioctl_s_fmt_cap},
-	{vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
-	{vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
-	{vidioc_int_queryctrl_num,
-	 (v4l2_int_ioctl_func *) ioctl_queryctrl},
-	{vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
-	{vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
-	{vidioc_int_querystd_num, (v4l2_int_ioctl_func *) ioctl_querystd},
-	{vidioc_int_s_std_num, (v4l2_int_ioctl_func *) ioctl_s_std},
-	{vidioc_int_s_video_routing_num,
-		(v4l2_int_ioctl_func *) ioctl_s_routing},
+static const struct v4l2_subdev_ops tvp514x_ops = {
+	.core = &tvp514x_core_ops,
+	.video = &tvp514x_video_ops,
 };
 
 static struct tvp514x_decoder tvp514x_dev = {
-	.state = STATE_NOT_DETECTED,
+	.streaming = 0,
 
 	.fmt_list = tvp514x_fmt_list,
 	.num_fmts = ARRAY_SIZE(tvp514x_fmt_list),
 
-	.pix = {		/* Default to NTSC 8-bit YUV 422 */
+	.pix = {
+		/* Default to NTSC 8-bit YUV 422 */
 		.width = NTSC_NUM_ACTIVE_PIXELS,
 		.height = NTSC_NUM_ACTIVE_LINES,
 		.pixelformat = V4L2_PIX_FMT_UYVY,
@@ -1369,20 +1279,13 @@ static struct tvp514x_decoder tvp514x_dev = {
 	.current_std = STD_NTSC_MJ,
 	.std_list = tvp514x_std_list,
 	.num_stds = ARRAY_SIZE(tvp514x_std_list),
-	.v4l2_int_device = {
-		.module = THIS_MODULE,
-		.name = TVP514X_MODULE_NAME,
-		.type = v4l2_int_type_slave,
-	},
-	.tvp514x_slave = {
-		.ioctls = tvp514x_ioctl_desc,
-		.num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
-	},
+
 };
 
 /**
- * tvp514x_probe - decoder driver i2c probe handler
+ * tvp514x_probe() - decoder driver i2c probe handler
  * @client: i2c driver client device structure
+ * @id: i2c driver id table
  *
  * Register decoder as an i2c client device and V4L2
  * device.
@@ -1391,88 +1294,71 @@ static int
 tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct tvp514x_decoder *decoder;
-	int err;
+	struct v4l2_subdev *sd;
 
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 
+	if (!client->dev.platform_data) {
+		v4l2_err(client, "No platform data!!\n");
+		return -ENODEV;
+	}
+
 	decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
 	if (!decoder)
 		return -ENOMEM;
 
-	if (!client->dev.platform_data) {
-		v4l_err(client, "No platform data!!\n");
-		err = -ENODEV;
-		goto out_free;
-	}
-
+	/* Initialize the tvp514x_decoder with default configuration */
 	*decoder = tvp514x_dev;
-	decoder->v4l2_int_device.priv = decoder;
-	decoder->pdata = client->dev.platform_data;
-	decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave;
+	/* Copy default register configuration */
 	memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
 			sizeof(tvp514x_reg_list_default));
-	/*
+
+	/* Copy board specific information here */
+	decoder->pdata = client->dev.platform_data;
+
+	/**
 	 * Fetch platform specific data, and configure the
 	 * tvp514x_reg_list[] accordingly. Since this is one
 	 * time configuration, no need to preserve.
 	 */
 	decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
-			(decoder->pdata->clk_polarity << 1);
+		(decoder->pdata->clk_polarity << 1);
 	decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
-			((decoder->pdata->hs_polarity << 2) |
-			(decoder->pdata->vs_polarity << 3));
-	/*
-	 * Save the id data, required for power up sequence
-	 */
-	decoder->id = (struct i2c_device_id *)id;
-	/* Attach to Master */
-	strcpy(decoder->v4l2_int_device.u.slave->attach_to,
-			decoder->pdata->master);
-	decoder->client = client;
-	i2c_set_clientdata(client, decoder);
+		((decoder->pdata->hs_polarity << 2) |
+		 (decoder->pdata->vs_polarity << 3));
+	/* Set default standard to auto */
+	decoder->tvp514x_regs[REG_VIDEO_STD].val =
+		VIDEO_STD_AUTO_SWITCH_BIT;
 
 	/* Register with V4L2 layer as slave device */
-	err = v4l2_int_device_register(&decoder->v4l2_int_device);
-	if (err) {
-		i2c_set_clientdata(client, NULL);
-		v4l_err(client,
-			"Unable to register to v4l2. Err[%d]\n", err);
-		goto out_free;
-
-	} else
-		v4l_info(client, "Registered to v4l2 master %s!!\n",
-				decoder->pdata->master);
+	sd = &decoder->sd;
+	v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
+
+	v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
+
 	return 0;
 
-out_free:
-	kfree(decoder);
-	return err;
 }
 
 /**
- * tvp514x_remove - decoder driver i2c remove handler
+ * tvp514x_remove() - decoder driver i2c remove handler
  * @client: i2c driver client device structure
  *
  * Unregister decoder as an i2c client device and V4L2
  * device. Complement of tvp514x_probe().
  */
-static int __exit tvp514x_remove(struct i2c_client *client)
+static int tvp514x_remove(struct i2c_client *client)
 {
-	struct tvp514x_decoder *decoder = i2c_get_clientdata(client);
-
-	if (!client->adapter)
-		return -ENODEV;	/* our client isn't attached */
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct tvp514x_decoder *decoder = to_decoder(sd);
 
-	v4l2_int_device_unregister(&decoder->v4l2_int_device);
-	i2c_set_clientdata(client, NULL);
+	v4l2_device_unregister_subdev(sd);
 	kfree(decoder);
 	return 0;
 }
-/*
- * TVP5146 Init/Power on Sequence
- */
+/* TVP5146 Init/Power on Sequence */
 static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
@@ -1485,14 +1371,10 @@ static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
 	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+	{TOK_TERM, 0, 0},
 };
-static const struct tvp514x_init_seq tvp5146_init = {
-	.no_regs = ARRAY_SIZE(tvp5146_init_reg_seq),
-	.init_reg_seq = tvp5146_init_reg_seq,
-};
-/*
- * TVP5147 Init/Power on Sequence
- */
+
+/* TVP5147 Init/Power on Sequence */
 static const struct tvp514x_reg tvp5147_init_reg_seq[] =	{
 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
 	{TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
@@ -1512,71 +1394,51 @@ static const struct tvp514x_reg tvp5147_init_reg_seq[] =	{
 	{TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
 	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+	{TOK_TERM, 0, 0},
 };
-static const struct tvp514x_init_seq tvp5147_init = {
-	.no_regs = ARRAY_SIZE(tvp5147_init_reg_seq),
-	.init_reg_seq = tvp5147_init_reg_seq,
-};
-/*
- * TVP5146M2/TVP5147M1 Init/Power on Sequence
- */
+
+/* TVP5146M2/TVP5147M1 Init/Power on Sequence */
 static const struct tvp514x_reg tvp514xm_init_reg_seq[] = {
 	{TOK_WRITE, REG_OPERATION_MODE, 0x01},
 	{TOK_WRITE, REG_OPERATION_MODE, 0x00},
+	{TOK_TERM, 0, 0},
 };
-static const struct tvp514x_init_seq tvp514xm_init = {
-	.no_regs = ARRAY_SIZE(tvp514xm_init_reg_seq),
-	.init_reg_seq = tvp514xm_init_reg_seq,
-};
-/*
+
+/**
  * I2C Device Table -
  *
  * name - Name of the actual device/chip.
  * driver_data - Driver data
  */
 static const struct i2c_device_id tvp514x_id[] = {
-	{"tvp5146", (unsigned long)&tvp5146_init},
-	{"tvp5146m2", (unsigned long)&tvp514xm_init},
-	{"tvp5147", (unsigned long)&tvp5147_init},
-	{"tvp5147m1", (unsigned long)&tvp514xm_init},
+	{"tvp5146", (unsigned long)tvp5146_init_reg_seq},
+	{"tvp5146m2", (unsigned long)tvp514xm_init_reg_seq},
+	{"tvp5147", (unsigned long)tvp5147_init_reg_seq},
+	{"tvp5147m1", (unsigned long)tvp514xm_init_reg_seq},
 	{},
 };
 
 MODULE_DEVICE_TABLE(i2c, tvp514x_id);
 
-static struct i2c_driver tvp514x_i2c_driver = {
+static struct i2c_driver tvp514x_driver = {
 	.driver = {
-		   .name = TVP514X_MODULE_NAME,
-		   .owner = THIS_MODULE,
-		   },
+		.owner = THIS_MODULE,
+		.name = TVP514X_MODULE_NAME,
+	},
 	.probe = tvp514x_probe,
-	.remove = __exit_p(tvp514x_remove),
+	.remove = tvp514x_remove,
 	.id_table = tvp514x_id,
 };
 
-/**
- * tvp514x_init
- *
- * Module init function
- */
 static int __init tvp514x_init(void)
 {
-	return i2c_add_driver(&tvp514x_i2c_driver);
+	return i2c_add_driver(&tvp514x_driver);
 }
 
-/**
- * tvp514x_cleanup
- *
- * Module exit function
- */
-static void __exit tvp514x_cleanup(void)
+static void __exit tvp514x_exit(void)
 {
-	i2c_del_driver(&tvp514x_i2c_driver);
+	i2c_del_driver(&tvp514x_driver);
 }
 
 module_init(tvp514x_init);
-module_exit(tvp514x_cleanup);
-
-MODULE_AUTHOR("Texas Instruments");
-MODULE_DESCRIPTION("TVP514X linux decoder driver");
-MODULE_LICENSE("GPL");
+module_exit(tvp514x_exit);
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/video/tvp514x_regs.h
index 351620a..18f29ad 100644
--- a/drivers/media/video/tvp514x_regs.h
+++ b/drivers/media/video/tvp514x_regs.h
@@ -284,14 +284,4 @@ struct tvp514x_reg {
 	u32 val;
 };
 
-/**
- * struct tvp514x_init_seq - Structure for TVP5146/47/46M2/47M1 power up
- *		Sequence.
- * @ no_regs - Number of registers to write for power up sequence.
- * @ init_reg_seq - Array of registers and respective value to write.
- */
-struct tvp514x_init_seq {
-	unsigned int no_regs;
-	const struct tvp514x_reg *init_reg_seq;
-};
 #endif				/* ifndef _TVP514X_REGS_H */
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index aa5065e..269ab04 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -24,7 +24,7 @@
 #include <linux/delay.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-chip-ident.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-subdev.h>
 #include <media/soc_camera.h>
 #include <media/tw9910.h>
 
@@ -223,9 +223,8 @@ struct tw9910_hsync_ctrl {
 };
 
 struct tw9910_priv {
+	struct v4l2_subdev                subdev;
 	struct tw9910_video_info       *info;
-	struct i2c_client              *client;
-	struct soc_camera_device        icd;
 	const struct tw9910_scale_ctrl *scale;
 };
 
@@ -356,6 +355,12 @@ static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
 /*
  * general function
  */
+static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
+{
+	return container_of(i2c_get_clientdata(client), struct tw9910_priv,
+			    subdev);
+}
+
 static int tw9910_set_scale(struct i2c_client *client,
 			    const struct tw9910_scale_ctrl *scale)
 {
@@ -509,44 +514,20 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
 /*
  * soc_camera_ops function
  */
-static int tw9910_init(struct soc_camera_device *icd)
-{
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
-	int ret = 0;
-
-	if (priv->info->link.power) {
-		ret = priv->info->link.power(&priv->client->dev, 1);
-		if (ret < 0)
-			return ret;
-	}
-
-	if (priv->info->link.reset)
-		ret = priv->info->link.reset(&priv->client->dev);
-
-	return ret;
-}
-
-static int tw9910_release(struct soc_camera_device *icd)
+static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
 {
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
-	int ret = 0;
-
-	if (priv->info->link.power)
-		ret = priv->info->link.power(&priv->client->dev, 0);
-
-	return ret;
-}
+	struct i2c_client *client = sd->priv;
+	struct tw9910_priv *priv = to_tw9910(client);
 
-static int tw9910_start_capture(struct soc_camera_device *icd)
-{
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
+	if (!enable)
+		return 0;
 
 	if (!priv->scale) {
-		dev_err(&icd->dev, "norm select error\n");
+		dev_err(&client->dev, "norm select error\n");
 		return -EPERM;
 	}
 
-	dev_dbg(&icd->dev, "%s %dx%d\n",
+	dev_dbg(&client->dev, "%s %dx%d\n",
 		 priv->scale->name,
 		 priv->scale->width,
 		 priv->scale->height);
@@ -554,11 +535,6 @@ static int tw9910_start_capture(struct soc_camera_device *icd)
 	return 0;
 }
 
-static int tw9910_stop_capture(struct soc_camera_device *icd)
-{
-	return 0;
-}
-
 static int tw9910_set_bus_param(struct soc_camera_device *icd,
 				unsigned long flags)
 {
@@ -567,8 +543,9 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd,
 
 static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
 {
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
-	struct soc_camera_link *icl = priv->client->dev.platform_data;
+	struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
+	struct tw9910_priv *priv = to_tw9910(client);
+	struct soc_camera_link *icl = to_soc_camera_link(icd);
 	unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
 		SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
 		SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -576,21 +553,11 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
 	return soc_camera_apply_sensor_flags(icl, flags);
 }
 
-static int tw9910_get_chip_id(struct soc_camera_device *icd,
-			      struct v4l2_dbg_chip_ident *id)
-{
-	id->ident = V4L2_IDENT_TW9910;
-	id->revision = 0;
-
-	return 0;
-}
-
-static int tw9910_set_std(struct soc_camera_device *icd,
-			  v4l2_std_id *a)
+static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
 {
 	int ret = -EINVAL;
 
-	if (*a & (V4L2_STD_NTSC | V4L2_STD_PAL))
+	if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL))
 		ret = 0;
 
 	return ret;
@@ -606,17 +573,26 @@ static int tw9910_enum_input(struct soc_camera_device *icd,
 	return 0;
 }
 
+static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
+			       struct v4l2_dbg_chip_ident *id)
+{
+	id->ident = V4L2_IDENT_TW9910;
+	id->revision = 0;
+
+	return 0;
+}
+
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-static int tw9910_get_register(struct soc_camera_device *icd,
-			       struct v4l2_dbg_register *reg)
+static int tw9910_g_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
 {
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
+	struct i2c_client *client = sd->priv;
 	int ret;
 
 	if (reg->reg > 0xff)
 		return -EINVAL;
 
-	ret = i2c_smbus_read_byte_data(priv->client, reg->reg);
+	ret = i2c_smbus_read_byte_data(client, reg->reg);
 	if (ret < 0)
 		return ret;
 
@@ -628,23 +604,25 @@ static int tw9910_get_register(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int tw9910_set_register(struct soc_camera_device *icd,
-			       struct v4l2_dbg_register *reg)
+static int tw9910_s_register(struct v4l2_subdev *sd,
+			     struct v4l2_dbg_register *reg)
 {
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
+	struct i2c_client *client = sd->priv;
 
 	if (reg->reg > 0xff ||
 	    reg->val > 0xff)
 		return -EINVAL;
 
-	return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val);
+	return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
 }
 #endif
 
-static int tw9910_set_crop(struct soc_camera_device *icd,
-			   struct v4l2_rect *rect)
+static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
 {
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
+	struct v4l2_rect *rect = &a->c;
+	struct i2c_client *client = sd->priv;
+	struct tw9910_priv *priv = to_tw9910(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 	int                 ret  = -EINVAL;
 	u8                  val;
 
@@ -658,8 +636,8 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
 	/*
 	 * reset hardware
 	 */
-	tw9910_reset(priv->client);
-	ret = tw9910_write_array(priv->client, tw9910_default_regs);
+	tw9910_reset(client);
+	ret = tw9910_write_array(client, tw9910_default_regs);
 	if (ret < 0)
 		goto tw9910_set_fmt_error;
 
@@ -670,7 +648,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
 	if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
 		val = LEN;
 
-	ret = tw9910_mask_set(priv->client, OPFORM, LEN, val);
+	ret = tw9910_mask_set(client, OPFORM, LEN, val);
 	if (ret < 0)
 		goto tw9910_set_fmt_error;
 
@@ -698,52 +676,139 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
 		val = 0;
 	}
 
-	ret = tw9910_mask_set(priv->client, VBICNTL, RTSEL_MASK, val);
+	ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
 	if (ret < 0)
 		goto tw9910_set_fmt_error;
 
 	/*
 	 * set scale
 	 */
-	ret = tw9910_set_scale(priv->client, priv->scale);
+	ret = tw9910_set_scale(client, priv->scale);
 	if (ret < 0)
 		goto tw9910_set_fmt_error;
 
 	/*
 	 * set cropping
 	 */
-	ret = tw9910_set_cropping(priv->client, &tw9910_cropping_ctrl);
+	ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl);
 	if (ret < 0)
 		goto tw9910_set_fmt_error;
 
 	/*
 	 * set hsync
 	 */
-	ret = tw9910_set_hsync(priv->client, &tw9910_hsync_ctrl);
+	ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl);
 	if (ret < 0)
 		goto tw9910_set_fmt_error;
 
+	rect->width = priv->scale->width;
+	rect->height = priv->scale->height;
+	rect->left = 0;
+	rect->top = 0;
+
 	return ret;
 
 tw9910_set_fmt_error:
 
-	tw9910_reset(priv->client);
+	tw9910_reset(client);
 	priv->scale = NULL;
 
 	return ret;
 }
 
-static int tw9910_set_fmt(struct soc_camera_device *icd,
-			  struct v4l2_format *f)
+static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
+{
+	struct i2c_client *client = sd->priv;
+	struct tw9910_priv *priv = to_tw9910(client);
+
+	if (!priv->scale) {
+		int ret;
+		struct v4l2_crop crop = {
+			.c = {
+				.left	= 0,
+				.top	= 0,
+				.width	= 640,
+				.height	= 480,
+			},
+		};
+		ret = tw9910_s_crop(sd, &crop);
+		if (ret < 0)
+			return ret;
+	}
+
+	a->c.left	= 0;
+	a->c.top	= 0;
+	a->c.width	= priv->scale->width;
+	a->c.height	= priv->scale->height;
+	a->type		= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	return 0;
+}
+
+static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
 {
+	a->bounds.left			= 0;
+	a->bounds.top			= 0;
+	a->bounds.width			= 768;
+	a->bounds.height		= 576;
+	a->defrect.left			= 0;
+	a->defrect.top			= 0;
+	a->defrect.width		= 640;
+	a->defrect.height		= 480;
+	a->type				= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	a->pixelaspect.numerator	= 1;
+	a->pixelaspect.denominator	= 1;
+
+	return 0;
+}
+
+static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct tw9910_priv *priv = to_tw9910(client);
+	struct v4l2_pix_format *pix = &f->fmt.pix;
+
+	if (!priv->scale) {
+		int ret;
+		struct v4l2_crop crop = {
+			.c = {
+				.left	= 0,
+				.top	= 0,
+				.width	= 640,
+				.height	= 480,
+			},
+		};
+		ret = tw9910_s_crop(sd, &crop);
+		if (ret < 0)
+			return ret;
+	}
+
+	f->type			= V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+	pix->width		= priv->scale->width;
+	pix->height		= priv->scale->height;
+	pix->pixelformat	= V4L2_PIX_FMT_VYUY;
+	pix->colorspace		= V4L2_COLORSPACE_SMPTE170M;
+	pix->field		= V4L2_FIELD_INTERLACED;
+
+	return 0;
+}
+
+static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+	struct i2c_client *client = sd->priv;
+	struct tw9910_priv *priv = to_tw9910(client);
 	struct v4l2_pix_format *pix = &f->fmt.pix;
-	struct v4l2_rect rect = {
-		.left	= icd->x_current,
-		.top	= icd->y_current,
-		.width	= pix->width,
-		.height	= pix->height,
+	/* See tw9910_s_crop() - no proper cropping support */
+	struct v4l2_crop a = {
+		.c = {
+			.left	= 0,
+			.top	= 0,
+			.width	= pix->width,
+			.height	= pix->height,
+		},
 	};
-	int i;
+	int i, ret;
 
 	/*
 	 * check color format
@@ -755,19 +820,25 @@ static int tw9910_set_fmt(struct soc_camera_device *icd,
 	if (i == ARRAY_SIZE(tw9910_color_fmt))
 		return -EINVAL;
 
-	return tw9910_set_crop(icd, &rect);
+	ret = tw9910_s_crop(sd, &a);
+	if (!ret) {
+		pix->width = priv->scale->width;
+		pix->height = priv->scale->height;
+	}
+	return ret;
 }
 
-static int tw9910_try_fmt(struct soc_camera_device *icd,
-			  struct v4l2_format *f)
+static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
 {
+	struct i2c_client *client = sd->priv;
+	struct soc_camera_device *icd = client->dev.platform_data;
 	struct v4l2_pix_format *pix = &f->fmt.pix;
 	const struct tw9910_scale_ctrl *scale;
 
 	if (V4L2_FIELD_ANY == pix->field) {
 		pix->field = V4L2_FIELD_INTERLACED;
 	} else if (V4L2_FIELD_INTERLACED != pix->field) {
-		dev_err(&icd->dev, "Field type invalid.\n");
+		dev_err(&client->dev, "Field type invalid.\n");
 		return -EINVAL;
 	}
 
@@ -784,11 +855,11 @@ static int tw9910_try_fmt(struct soc_camera_device *icd,
 	return 0;
 }
 
-static int tw9910_video_probe(struct soc_camera_device *icd)
+static int tw9910_video_probe(struct soc_camera_device *icd,
+			      struct i2c_client *client)
 {
-	struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
+	struct tw9910_priv *priv = to_tw9910(client);
 	s32 val;
-	int ret;
 
 	/*
 	 * We must have a parent by now. And it cannot be a wrong one.
@@ -803,7 +874,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
 	 */
 	if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
 	    SOCAM_DATAWIDTH_8  != priv->info->buswidth) {
-		dev_err(&icd->dev, "bus width error\n");
+		dev_err(&client->dev, "bus width error\n");
 		return -ENODEV;
 	}
 
@@ -813,54 +884,54 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
 	/*
 	 * check and show Product ID
 	 */
-	val = i2c_smbus_read_byte_data(priv->client, ID);
+	val = i2c_smbus_read_byte_data(client, ID);
+
 	if (0x0B != GET_ID(val) ||
 	    0x00 != GET_ReV(val)) {
-		dev_err(&icd->dev,
+		dev_err(&client->dev,
 			"Product ID error %x:%x\n", GET_ID(val), GET_ReV(val));
 		return -ENODEV;
 	}
 
-	dev_info(&icd->dev,
+	dev_info(&client->dev,
 		 "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val));
 
-	ret = soc_camera_video_start(icd);
-	if (ret < 0)
-		return ret;
-
 	icd->vdev->tvnorms      = V4L2_STD_NTSC | V4L2_STD_PAL;
 	icd->vdev->current_norm = V4L2_STD_NTSC;
 
-	return ret;
-}
-
-static void tw9910_video_remove(struct soc_camera_device *icd)
-{
-	soc_camera_video_stop(icd);
+	return 0;
 }
 
 static struct soc_camera_ops tw9910_ops = {
-	.owner			= THIS_MODULE,
-	.probe			= tw9910_video_probe,
-	.remove			= tw9910_video_remove,
-	.init			= tw9910_init,
-	.release		= tw9910_release,
-	.start_capture		= tw9910_start_capture,
-	.stop_capture		= tw9910_stop_capture,
-	.set_crop		= tw9910_set_crop,
-	.set_fmt		= tw9910_set_fmt,
-	.try_fmt		= tw9910_try_fmt,
 	.set_bus_param		= tw9910_set_bus_param,
 	.query_bus_param	= tw9910_query_bus_param,
-	.get_chip_id		= tw9910_get_chip_id,
-	.set_std		= tw9910_set_std,
 	.enum_input		= tw9910_enum_input,
+};
+
+static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
+	.g_chip_ident	= tw9910_g_chip_ident,
+	.s_std		= tw9910_s_std,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
-	.get_register		= tw9910_get_register,
-	.set_register		= tw9910_set_register,
+	.g_register	= tw9910_g_register,
+	.s_register	= tw9910_s_register,
 #endif
 };
 
+static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
+	.s_stream	= tw9910_s_stream,
+	.g_fmt		= tw9910_g_fmt,
+	.s_fmt		= tw9910_s_fmt,
+	.try_fmt	= tw9910_try_fmt,
+	.cropcap	= tw9910_cropcap,
+	.g_crop		= tw9910_g_crop,
+	.s_crop		= tw9910_s_crop,
+};
+
+static struct v4l2_subdev_ops tw9910_subdev_ops = {
+	.core	= &tw9910_subdev_core_ops,
+	.video	= &tw9910_subdev_video_ops,
+};
+
 /*
  * i2c_driver function
  */
@@ -871,18 +942,24 @@ static int tw9910_probe(struct i2c_client *client,
 {
 	struct tw9910_priv             *priv;
 	struct tw9910_video_info       *info;
-	struct soc_camera_device       *icd;
-	const struct tw9910_scale_ctrl *scale;
-	int                             i, ret;
+	struct soc_camera_device       *icd = client->dev.platform_data;
+	struct i2c_adapter             *adapter =
+		to_i2c_adapter(client->dev.parent);
+	struct soc_camera_link         *icl;
+	int                             ret;
+
+	if (!icd) {
+		dev_err(&client->dev, "TW9910: missing soc-camera data!\n");
+		return -EINVAL;
+	}
 
-	if (!client->dev.platform_data)
+	icl = to_soc_camera_link(icd);
+	if (!icl)
 		return -EINVAL;
 
-	info = container_of(client->dev.platform_data,
-			    struct tw9910_video_info, link);
+	info = container_of(icl, struct tw9910_video_info, link);
 
-	if (!i2c_check_functionality(to_i2c_adapter(client->dev.parent),
-				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
 		dev_err(&client->dev,
 			"I2C-Adapter doesn't support "
 			"I2C_FUNC_SMBUS_BYTE_DATA\n");
@@ -894,40 +971,15 @@ static int tw9910_probe(struct i2c_client *client,
 		return -ENOMEM;
 
 	priv->info   = info;
-	priv->client = client;
-	i2c_set_clientdata(client, priv);
 
-	icd          = &priv->icd;
+	v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
+
 	icd->ops     = &tw9910_ops;
-	icd->control = &client->dev;
 	icd->iface   = info->link.bus_id;
 
-	/*
-	 * set width and height
-	 */
-	icd->width_max  = tw9910_ntsc_scales[0].width; /* set default */
-	icd->width_min  = tw9910_ntsc_scales[0].width;
-	icd->height_max = tw9910_ntsc_scales[0].height;
-	icd->height_min = tw9910_ntsc_scales[0].height;
-
-	scale = tw9910_ntsc_scales;
-	for (i = 0; i < ARRAY_SIZE(tw9910_ntsc_scales); i++) {
-		icd->width_max  = max(scale[i].width,  icd->width_max);
-		icd->width_min  = min(scale[i].width,  icd->width_min);
-		icd->height_max = max(scale[i].height, icd->height_max);
-		icd->height_min = min(scale[i].height, icd->height_min);
-	}
-	scale = tw9910_pal_scales;
-	for (i = 0; i < ARRAY_SIZE(tw9910_pal_scales); i++) {
-		icd->width_max  = max(scale[i].width,  icd->width_max);
-		icd->width_min  = min(scale[i].width,  icd->width_min);
-		icd->height_max = max(scale[i].height, icd->height_max);
-		icd->height_min = min(scale[i].height, icd->height_min);
-	}
-
-	ret = soc_camera_device_register(icd);
-
+	ret = tw9910_video_probe(icd, client);
 	if (ret) {
+		icd->ops = NULL;
 		i2c_set_clientdata(client, NULL);
 		kfree(priv);
 	}
@@ -937,9 +989,10 @@ static int tw9910_probe(struct i2c_client *client,
 
 static int tw9910_remove(struct i2c_client *client)
 {
-	struct tw9910_priv *priv = i2c_get_clientdata(client);
+	struct tw9910_priv *priv = to_tw9910(client);
+	struct soc_camera_device *icd = client->dev.platform_data;
 
-	soc_camera_device_unregister(&priv->icd);
+	icd->ops = NULL;
 	i2c_set_clientdata(client, NULL);
 	kfree(priv);
 	return 0;
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 1fe5bef..f97fd06 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -246,9 +246,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
 	switch (usbvision_device_data[usbvision->DevModel].Codec) {
 	case CODEC_SAA7113:
 	case CODEC_SAA7111:
-		v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+		v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
 				&usbvision->i2c_adap, "saa7115",
-				"saa7115_auto", saa711x_addrs);
+				"saa7115_auto", 0, saa711x_addrs);
 		break;
 	}
 	if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
@@ -256,16 +256,16 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
 		enum v4l2_i2c_tuner_type type;
 		struct tuner_setup tun_setup;
 
-		sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+		sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
 				&usbvision->i2c_adap, "tuner",
-				"tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+				"tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
 		/* depending on whether we found a demod or not, select
 		   the tuner type. */
 		type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
 
-		sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+		sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
 				&usbvision->i2c_adap, "tuner",
-				"tuner", v4l2_i2c_tuner_addrs(type));
+				"tuner", 0, v4l2_i2c_tuner_addrs(type));
 
 		if (usbvision->tuner_type != -1) {
 			tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 36a6ba9..c3225a5 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -34,7 +34,7 @@
 static struct uvc_control_info uvc_ctrls[] = {
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_BRIGHTNESS_CONTROL,
+		.selector	= UVC_PU_BRIGHTNESS_CONTROL,
 		.index		= 0,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -42,7 +42,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_CONTRAST_CONTROL,
+		.selector	= UVC_PU_CONTRAST_CONTROL,
 		.index		= 1,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -50,7 +50,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_HUE_CONTROL,
+		.selector	= UVC_PU_HUE_CONTROL,
 		.index		= 2,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -58,7 +58,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_SATURATION_CONTROL,
+		.selector	= UVC_PU_SATURATION_CONTROL,
 		.index		= 3,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -66,7 +66,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_SHARPNESS_CONTROL,
+		.selector	= UVC_PU_SHARPNESS_CONTROL,
 		.index		= 4,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -74,7 +74,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_GAMMA_CONTROL,
+		.selector	= UVC_PU_GAMMA_CONTROL,
 		.index		= 5,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -82,7 +82,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
 		.index		= 6,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -90,7 +90,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_COMPONENT_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
 		.index		= 7,
 		.size		= 4,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -98,7 +98,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_BACKLIGHT_COMPENSATION_CONTROL,
+		.selector	= UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
 		.index		= 8,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -106,7 +106,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_GAIN_CONTROL,
+		.selector	= UVC_PU_GAIN_CONTROL,
 		.index		= 9,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -114,7 +114,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_POWER_LINE_FREQUENCY_CONTROL,
+		.selector	= UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
 		.index		= 10,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -122,7 +122,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_HUE_AUTO_CONTROL,
+		.selector	= UVC_PU_HUE_AUTO_CONTROL,
 		.index		= 11,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -130,7 +130,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
 		.index		= 12,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -138,7 +138,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
 		.index		= 13,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -146,7 +146,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_DIGITAL_MULTIPLIER_CONTROL,
+		.selector	= UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
 		.index		= 14,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -154,7 +154,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
+		.selector	= UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
 		.index		= 15,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -162,21 +162,21 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_ANALOG_VIDEO_STANDARD_CONTROL,
+		.selector	= UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
 		.index		= 16,
 		.size		= 1,
 		.flags		= UVC_CONTROL_GET_CUR,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_ANALOG_LOCK_STATUS_CONTROL,
+		.selector	= UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
 		.index		= 17,
 		.size		= 1,
 		.flags		= UVC_CONTROL_GET_CUR,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_SCANNING_MODE_CONTROL,
+		.selector	= UVC_CT_SCANNING_MODE_CONTROL,
 		.index		= 0,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -184,7 +184,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_AE_MODE_CONTROL,
+		.selector	= UVC_CT_AE_MODE_CONTROL,
 		.index		= 1,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -193,7 +193,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_AE_PRIORITY_CONTROL,
+		.selector	= UVC_CT_AE_PRIORITY_CONTROL,
 		.index		= 2,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -201,7 +201,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
 		.index		= 3,
 		.size		= 4,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -209,7 +209,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_EXPOSURE_TIME_RELATIVE_CONTROL,
+		.selector	= UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
 		.index		= 4,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -217,7 +217,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_FOCUS_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_FOCUS_ABSOLUTE_CONTROL,
 		.index		= 5,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -225,7 +225,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_FOCUS_RELATIVE_CONTROL,
+		.selector	= UVC_CT_FOCUS_RELATIVE_CONTROL,
 		.index		= 6,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -233,7 +233,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_IRIS_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_IRIS_ABSOLUTE_CONTROL,
 		.index		= 7,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -241,7 +241,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_IRIS_RELATIVE_CONTROL,
+		.selector	= UVC_CT_IRIS_RELATIVE_CONTROL,
 		.index		= 8,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -249,7 +249,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_ZOOM_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_ZOOM_ABSOLUTE_CONTROL,
 		.index		= 9,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -257,7 +257,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_ZOOM_RELATIVE_CONTROL,
+		.selector	= UVC_CT_ZOOM_RELATIVE_CONTROL,
 		.index		= 10,
 		.size		= 3,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -265,7 +265,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_PANTILT_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_PANTILT_ABSOLUTE_CONTROL,
 		.index		= 11,
 		.size		= 8,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -273,7 +273,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_PANTILT_RELATIVE_CONTROL,
+		.selector	= UVC_CT_PANTILT_RELATIVE_CONTROL,
 		.index		= 12,
 		.size		= 4,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -281,7 +281,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_ROLL_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_ROLL_ABSOLUTE_CONTROL,
 		.index		= 13,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -289,7 +289,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_ROLL_RELATIVE_CONTROL,
+		.selector	= UVC_CT_ROLL_RELATIVE_CONTROL,
 		.index		= 14,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
@@ -297,7 +297,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_FOCUS_AUTO_CONTROL,
+		.selector	= UVC_CT_FOCUS_AUTO_CONTROL,
 		.index		= 17,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -305,7 +305,7 @@ static struct uvc_control_info uvc_ctrls[] = {
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_PRIVACY_CONTROL,
+		.selector	= UVC_CT_PRIVACY_CONTROL,
 		.index		= 18,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
@@ -332,13 +332,13 @@ static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping,
 	__s8 zoom = (__s8)data[0];
 
 	switch (query) {
-	case GET_CUR:
+	case UVC_GET_CUR:
 		return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]);
 
-	case GET_MIN:
-	case GET_MAX:
-	case GET_RES:
-	case GET_DEF:
+	case UVC_GET_MIN:
+	case UVC_GET_MAX:
+	case UVC_GET_RES:
+	case UVC_GET_DEF:
 	default:
 		return data[2];
 	}
@@ -356,7 +356,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_BRIGHTNESS,
 		.name		= "Brightness",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_BRIGHTNESS_CONTROL,
+		.selector	= UVC_PU_BRIGHTNESS_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -366,7 +366,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_CONTRAST,
 		.name		= "Contrast",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_CONTRAST_CONTROL,
+		.selector	= UVC_PU_CONTRAST_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -376,7 +376,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_HUE,
 		.name		= "Hue",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_HUE_CONTROL,
+		.selector	= UVC_PU_HUE_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -386,7 +386,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_SATURATION,
 		.name		= "Saturation",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_SATURATION_CONTROL,
+		.selector	= UVC_PU_SATURATION_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -396,7 +396,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_SHARPNESS,
 		.name		= "Sharpness",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_SHARPNESS_CONTROL,
+		.selector	= UVC_PU_SHARPNESS_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -406,7 +406,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_GAMMA,
 		.name		= "Gamma",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_GAMMA_CONTROL,
+		.selector	= UVC_PU_GAMMA_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -416,7 +416,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_BACKLIGHT_COMPENSATION,
 		.name		= "Backlight Compensation",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_BACKLIGHT_COMPENSATION_CONTROL,
+		.selector	= UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -426,7 +426,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_GAIN,
 		.name		= "Gain",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_GAIN_CONTROL,
+		.selector	= UVC_PU_GAIN_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -436,7 +436,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_POWER_LINE_FREQUENCY,
 		.name		= "Power Line Frequency",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_POWER_LINE_FREQUENCY_CONTROL,
+		.selector	= UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
 		.size		= 2,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_MENU,
@@ -448,7 +448,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_HUE_AUTO,
 		.name		= "Hue, Auto",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_HUE_AUTO_CONTROL,
+		.selector	= UVC_PU_HUE_AUTO_CONTROL,
 		.size		= 1,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,
@@ -458,7 +458,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_EXPOSURE_AUTO,
 		.name		= "Exposure, Auto",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_AE_MODE_CONTROL,
+		.selector	= UVC_CT_AE_MODE_CONTROL,
 		.size		= 4,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_MENU,
@@ -470,7 +470,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_EXPOSURE_AUTO_PRIORITY,
 		.name		= "Exposure, Auto Priority",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_AE_PRIORITY_CONTROL,
+		.selector	= UVC_CT_AE_PRIORITY_CONTROL,
 		.size		= 1,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,
@@ -480,7 +480,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_EXPOSURE_ABSOLUTE,
 		.name		= "Exposure (Absolute)",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
 		.size		= 32,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -490,7 +490,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_AUTO_WHITE_BALANCE,
 		.name		= "White Balance Temperature, Auto",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
 		.size		= 1,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,
@@ -500,7 +500,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_WHITE_BALANCE_TEMPERATURE,
 		.name		= "White Balance Temperature",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -510,7 +510,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_AUTO_WHITE_BALANCE,
 		.name		= "White Balance Component, Auto",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
 		.size		= 1,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,
@@ -520,7 +520,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_BLUE_BALANCE,
 		.name		= "White Balance Blue Component",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_COMPONENT_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -530,7 +530,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_RED_BALANCE,
 		.name		= "White Balance Red Component",
 		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_COMPONENT_CONTROL,
+		.selector	= UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
 		.size		= 16,
 		.offset		= 16,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -540,7 +540,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_FOCUS_ABSOLUTE,
 		.name		= "Focus (absolute)",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_FOCUS_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_FOCUS_ABSOLUTE_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -550,7 +550,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_FOCUS_AUTO,
 		.name		= "Focus, Auto",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_FOCUS_AUTO_CONTROL,
+		.selector	= UVC_CT_FOCUS_AUTO_CONTROL,
 		.size		= 1,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,
@@ -560,7 +560,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_ZOOM_ABSOLUTE,
 		.name		= "Zoom, Absolute",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_ZOOM_ABSOLUTE_CONTROL,
+		.selector	= UVC_CT_ZOOM_ABSOLUTE_CONTROL,
 		.size		= 16,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -570,7 +570,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_ZOOM_CONTINUOUS,
 		.name		= "Zoom, Continuous",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_ZOOM_RELATIVE_CONTROL,
+		.selector	= UVC_CT_ZOOM_RELATIVE_CONTROL,
 		.size		= 0,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,
@@ -582,7 +582,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
 		.id		= V4L2_CID_PRIVACY,
 		.name		= "Privacy",
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_PRIVACY_CONTROL,
+		.selector	= UVC_CT_PRIVACY_CONTROL,
 		.size		= 1,
 		.offset		= 0,
 		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,
@@ -675,16 +675,16 @@ static const __u8 uvc_media_transport_input_guid[16] =
 static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16])
 {
 	switch (UVC_ENTITY_TYPE(entity)) {
-	case ITT_CAMERA:
+	case UVC_ITT_CAMERA:
 		return memcmp(uvc_camera_guid, guid, 16) == 0;
 
-	case ITT_MEDIA_TRANSPORT_INPUT:
+	case UVC_ITT_MEDIA_TRANSPORT_INPUT:
 		return memcmp(uvc_media_transport_input_guid, guid, 16) == 0;
 
-	case VC_PROCESSING_UNIT:
+	case UVC_VC_PROCESSING_UNIT:
 		return memcmp(uvc_processing_guid, guid, 16) == 0;
 
-	case VC_EXTENSION_UNIT:
+	case UVC_VC_EXTENSION_UNIT:
 		return memcmp(entity->extension.guidExtensionCode,
 			      guid, 16) == 0;
 
@@ -729,7 +729,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
 	}
 }
 
-struct uvc_control *uvc_find_control(struct uvc_video_device *video,
+struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
 	__u32 v4l2_id, struct uvc_control_mapping **mapping)
 {
 	struct uvc_control *ctrl = NULL;
@@ -742,17 +742,17 @@ struct uvc_control *uvc_find_control(struct uvc_video_device *video,
 	v4l2_id &= V4L2_CTRL_ID_MASK;
 
 	/* Find the control. */
-	__uvc_find_control(video->processing, v4l2_id, mapping, &ctrl, next);
+	__uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next);
 	if (ctrl && !next)
 		return ctrl;
 
-	list_for_each_entry(entity, &video->iterms, chain) {
+	list_for_each_entry(entity, &chain->iterms, chain) {
 		__uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
 		if (ctrl && !next)
 			return ctrl;
 	}
 
-	list_for_each_entry(entity, &video->extensions, chain) {
+	list_for_each_entry(entity, &chain->extensions, chain) {
 		__uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
 		if (ctrl && !next)
 			return ctrl;
@@ -765,7 +765,7 @@ struct uvc_control *uvc_find_control(struct uvc_video_device *video,
 	return ctrl;
 }
 
-int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
+int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
 	struct v4l2_queryctrl *v4l2_ctrl)
 {
 	struct uvc_control *ctrl;
@@ -775,7 +775,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 	__u8 *data;
 	int ret;
 
-	ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
+	ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
 	if (ctrl == NULL)
 		return -EINVAL;
 
@@ -793,11 +793,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
 	if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
-		if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id,
-				video->dev->intfnum, ctrl->info->selector,
-				data, ctrl->info->size)) < 0)
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     data, ctrl->info->size);
+		if (ret < 0)
 			goto out;
-		v4l2_ctrl->default_value = mapping->get(mapping, GET_DEF, data);
+		v4l2_ctrl->default_value =
+			mapping->get(mapping, UVC_GET_DEF, data);
 	}
 
 	switch (mapping->v4l2_type) {
@@ -829,25 +831,28 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 	}
 
 	if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
-		if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id,
-				video->dev->intfnum, ctrl->info->selector,
-				data, ctrl->info->size)) < 0)
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     data, ctrl->info->size);
+		if (ret < 0)
 			goto out;
-		v4l2_ctrl->minimum = mapping->get(mapping, GET_MIN, data);
+		v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data);
 	}
 	if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
-		if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
-				video->dev->intfnum, ctrl->info->selector,
-				data, ctrl->info->size)) < 0)
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     data, ctrl->info->size);
+		if (ret < 0)
 			goto out;
-		v4l2_ctrl->maximum = mapping->get(mapping, GET_MAX, data);
+		v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data);
 	}
 	if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
-		if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
-				video->dev->intfnum, ctrl->info->selector,
-				data, ctrl->info->size)) < 0)
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
+				     chain->dev->intfnum, ctrl->info->selector,
+				     data, ctrl->info->size);
+		if (ret < 0)
 			goto out;
-		v4l2_ctrl->step = mapping->get(mapping, GET_RES, data);
+		v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data);
 	}
 
 	ret = 0;
@@ -881,9 +886,9 @@ out:
  * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the
  * control lock.
  */
-int uvc_ctrl_begin(struct uvc_video_device *video)
+int uvc_ctrl_begin(struct uvc_video_chain *chain)
 {
-	return mutex_lock_interruptible(&video->ctrl_mutex) ? -ERESTARTSYS : 0;
+	return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
 }
 
 static int uvc_ctrl_commit_entity(struct uvc_device *dev,
@@ -912,7 +917,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
 			continue;
 
 		if (!rollback)
-			ret = uvc_query_ctrl(dev, SET_CUR, ctrl->entity->id,
+			ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id,
 				dev->intfnum, ctrl->info->selector,
 				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
 				ctrl->info->size);
@@ -933,34 +938,34 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
 	return 0;
 }
 
-int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback)
+int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
 {
 	struct uvc_entity *entity;
 	int ret = 0;
 
 	/* Find the control. */
-	ret = uvc_ctrl_commit_entity(video->dev, video->processing, rollback);
+	ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback);
 	if (ret < 0)
 		goto done;
 
-	list_for_each_entry(entity, &video->iterms, chain) {
-		ret = uvc_ctrl_commit_entity(video->dev, entity, rollback);
+	list_for_each_entry(entity, &chain->iterms, chain) {
+		ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
 		if (ret < 0)
 			goto done;
 	}
 
-	list_for_each_entry(entity, &video->extensions, chain) {
-		ret = uvc_ctrl_commit_entity(video->dev, entity, rollback);
+	list_for_each_entry(entity, &chain->extensions, chain) {
+		ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
 		if (ret < 0)
 			goto done;
 	}
 
 done:
-	mutex_unlock(&video->ctrl_mutex);
+	mutex_unlock(&chain->ctrl_mutex);
 	return ret;
 }
 
-int uvc_ctrl_get(struct uvc_video_device *video,
+int uvc_ctrl_get(struct uvc_video_chain *chain,
 	struct v4l2_ext_control *xctrl)
 {
 	struct uvc_control *ctrl;
@@ -969,13 +974,13 @@ int uvc_ctrl_get(struct uvc_video_device *video,
 	unsigned int i;
 	int ret;
 
-	ctrl = uvc_find_control(video, xctrl->id, &mapping);
+	ctrl = uvc_find_control(chain, xctrl->id, &mapping);
 	if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
 		return -EINVAL;
 
 	if (!ctrl->loaded) {
-		ret = uvc_query_ctrl(video->dev, GET_CUR, ctrl->entity->id,
-				video->dev->intfnum, ctrl->info->selector,
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
+				chain->dev->intfnum, ctrl->info->selector,
 				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
 				ctrl->info->size);
 		if (ret < 0)
@@ -984,7 +989,7 @@ int uvc_ctrl_get(struct uvc_video_device *video,
 		ctrl->loaded = 1;
 	}
 
-	xctrl->value = mapping->get(mapping, GET_CUR,
+	xctrl->value = mapping->get(mapping, UVC_GET_CUR,
 		uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
 
 	if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
@@ -1000,7 +1005,7 @@ int uvc_ctrl_get(struct uvc_video_device *video,
 	return 0;
 }
 
-int uvc_ctrl_set(struct uvc_video_device *video,
+int uvc_ctrl_set(struct uvc_video_chain *chain,
 	struct v4l2_ext_control *xctrl)
 {
 	struct uvc_control *ctrl;
@@ -1008,7 +1013,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
 	s32 value = xctrl->value;
 	int ret;
 
-	ctrl = uvc_find_control(video, xctrl->id, &mapping);
+	ctrl = uvc_find_control(chain, xctrl->id, &mapping);
 	if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
 		return -EINVAL;
 
@@ -1023,8 +1028,8 @@ int uvc_ctrl_set(struct uvc_video_device *video,
 			memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
 				0, ctrl->info->size);
 		} else {
-			ret = uvc_query_ctrl(video->dev, GET_CUR,
-				ctrl->entity->id, video->dev->intfnum,
+			ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+				ctrl->entity->id, chain->dev->intfnum,
 				ctrl->info->selector,
 				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
 				ctrl->info->size);
@@ -1053,7 +1058,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
  * Dynamic controls
  */
 
-int uvc_xu_ctrl_query(struct uvc_video_device *video,
+int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
 	struct uvc_xu_control *xctrl, int set)
 {
 	struct uvc_entity *entity;
@@ -1063,7 +1068,7 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
 	int ret;
 
 	/* Find the extension unit. */
-	list_for_each_entry(entity, &video->extensions, chain) {
+	list_for_each_entry(entity, &chain->extensions, chain) {
 		if (entity->id == xctrl->unit)
 			break;
 	}
@@ -1102,7 +1107,7 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
 	    (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR)))
 		return -EINVAL;
 
-	if (mutex_lock_interruptible(&video->ctrl_mutex))
+	if (mutex_lock_interruptible(&chain->ctrl_mutex))
 		return -ERESTARTSYS;
 
 	memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
@@ -1115,9 +1120,9 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
 		goto out;
 	}
 
-	ret = uvc_query_ctrl(video->dev, set ? SET_CUR : GET_CUR, xctrl->unit,
-			     video->dev->intfnum, xctrl->selector, data,
-			     xctrl->size);
+	ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR,
+			     xctrl->unit, chain->dev->intfnum, xctrl->selector,
+			     data, xctrl->size);
 	if (ret < 0)
 		goto out;
 
@@ -1132,7 +1137,7 @@ out:
 		       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
 		       xctrl->size);
 
-	mutex_unlock(&video->ctrl_mutex);
+	mutex_unlock(&chain->ctrl_mutex);
 	return ret;
 }
 
@@ -1211,7 +1216,7 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
 	if (!found)
 		return;
 
-	if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) {
+	if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
 		/* Check if the device control information and length match
 		 * the user supplied information.
 		 */
@@ -1219,8 +1224,9 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
 		__le16 size;
 		__u8 inf;
 
-		if ((ret = uvc_query_ctrl(dev, GET_LEN, ctrl->entity->id,
-			dev->intfnum, info->selector, (__u8 *)&size, 2)) < 0) {
+		ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
+			dev->intfnum, info->selector, (__u8 *)&size, 2);
+		if (ret < 0) {
 			uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on "
 				"control " UVC_GUID_FORMAT "/%u (%d).\n",
 				UVC_GUID_ARGS(info->entity), info->selector,
@@ -1236,8 +1242,9 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
 			return;
 		}
 
-		if ((ret = uvc_query_ctrl(dev, GET_INFO, ctrl->entity->id,
-			dev->intfnum, info->selector, &inf, 1)) < 0) {
+		ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
+			dev->intfnum, info->selector, &inf, 1);
+		if (ret < 0) {
 			uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on "
 				"control " UVC_GUID_FORMAT "/%u (%d).\n",
 				UVC_GUID_ARGS(info->entity), info->selector,
@@ -1391,7 +1398,7 @@ uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity)
 	unsigned int size;
 	unsigned int i;
 
-	if (UVC_ENTITY_TYPE(entity) != VC_PROCESSING_UNIT)
+	if (UVC_ENTITY_TYPE(entity) != UVC_VC_PROCESSING_UNIT)
 		return;
 
 	controls = entity->processing.bmControls;
@@ -1427,13 +1434,13 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
 		unsigned int bControlSize = 0, ncontrols = 0;
 		__u8 *bmControls = NULL;
 
-		if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) {
+		if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
 			bmControls = entity->extension.bmControls;
 			bControlSize = entity->extension.bControlSize;
-		} else if (UVC_ENTITY_TYPE(entity) == VC_PROCESSING_UNIT) {
+		} else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) {
 			bmControls = entity->processing.bmControls;
 			bControlSize = entity->processing.bControlSize;
-		} else if (UVC_ENTITY_TYPE(entity) == ITT_CAMERA) {
+		} else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) {
 			bmControls = entity->camera.bmControls;
 			bControlSize = entity->camera.bControlSize;
 		}
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 04b4783..8756be5 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -249,23 +249,23 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
 
 	list_for_each_entry_continue(entity, &dev->entities, list) {
 		switch (UVC_ENTITY_TYPE(entity)) {
-		case TT_STREAMING:
+		case UVC_TT_STREAMING:
 			if (entity->output.bSourceID == id)
 				return entity;
 			break;
 
-		case VC_PROCESSING_UNIT:
+		case UVC_VC_PROCESSING_UNIT:
 			if (entity->processing.bSourceID == id)
 				return entity;
 			break;
 
-		case VC_SELECTOR_UNIT:
+		case UVC_VC_SELECTOR_UNIT:
 			for (i = 0; i < entity->selector.bNrInPins; ++i)
 				if (entity->selector.baSourceID[i] == id)
 					return entity;
 			break;
 
-		case VC_EXTENSION_UNIT:
+		case UVC_VC_EXTENSION_UNIT:
 			for (i = 0; i < entity->extension.bNrInPins; ++i)
 				if (entity->extension.baSourceID[i] == id)
 					return entity;
@@ -276,8 +276,20 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
 	return NULL;
 }
 
+static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
+{
+	struct uvc_streaming *stream;
+
+	list_for_each_entry(stream, &dev->streams, list) {
+		if (stream->header.bTerminalLink == id)
+			return stream;
+	}
+
+	return NULL;
+}
+
 /* ------------------------------------------------------------------------
- * Descriptors handling
+ * Descriptors parsing
  */
 
 static int uvc_parse_format(struct uvc_device *dev,
@@ -297,9 +309,9 @@ static int uvc_parse_format(struct uvc_device *dev,
 	format->index = buffer[3];
 
 	switch (buffer[2]) {
-	case VS_FORMAT_UNCOMPRESSED:
-	case VS_FORMAT_FRAME_BASED:
-		n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28;
+	case UVC_VS_FORMAT_UNCOMPRESSED:
+	case UVC_VS_FORMAT_FRAME_BASED:
+		n = buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED ? 27 : 28;
 		if (buflen < n) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d FORMAT error\n",
@@ -325,16 +337,16 @@ static int uvc_parse_format(struct uvc_device *dev,
 		}
 
 		format->bpp = buffer[21];
-		if (buffer[2] == VS_FORMAT_UNCOMPRESSED) {
-			ftype = VS_FRAME_UNCOMPRESSED;
+		if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) {
+			ftype = UVC_VS_FRAME_UNCOMPRESSED;
 		} else {
-			ftype = VS_FRAME_FRAME_BASED;
+			ftype = UVC_VS_FRAME_FRAME_BASED;
 			if (buffer[27])
 				format->flags = UVC_FMT_FLAG_COMPRESSED;
 		}
 		break;
 
-	case VS_FORMAT_MJPEG:
+	case UVC_VS_FORMAT_MJPEG:
 		if (buflen < 11) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d FORMAT error\n",
@@ -347,10 +359,10 @@ static int uvc_parse_format(struct uvc_device *dev,
 		format->fcc = V4L2_PIX_FMT_MJPEG;
 		format->flags = UVC_FMT_FLAG_COMPRESSED;
 		format->bpp = 0;
-		ftype = VS_FRAME_MJPEG;
+		ftype = UVC_VS_FRAME_MJPEG;
 		break;
 
-	case VS_FORMAT_DV:
+	case UVC_VS_FORMAT_DV:
 		if (buflen < 9) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d FORMAT error\n",
@@ -395,8 +407,8 @@ static int uvc_parse_format(struct uvc_device *dev,
 		format->nframes = 1;
 		break;
 
-	case VS_FORMAT_MPEG2TS:
-	case VS_FORMAT_STREAM_BASED:
+	case UVC_VS_FORMAT_MPEG2TS:
+	case UVC_VS_FORMAT_STREAM_BASED:
 		/* Not supported yet. */
 	default:
 		uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
@@ -416,7 +428,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 	 */
 	while (buflen > 2 && buffer[2] == ftype) {
 		frame = &format->frame[format->nframes];
-		if (ftype != VS_FRAME_FRAME_BASED)
+		if (ftype != UVC_VS_FRAME_FRAME_BASED)
 			n = buflen > 25 ? buffer[25] : 0;
 		else
 			n = buflen > 21 ? buffer[21] : 0;
@@ -436,7 +448,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 		frame->wHeight = get_unaligned_le16(&buffer[7]);
 		frame->dwMinBitRate = get_unaligned_le32(&buffer[9]);
 		frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]);
-		if (ftype != VS_FRAME_FRAME_BASED) {
+		if (ftype != UVC_VS_FRAME_FRAME_BASED) {
 			frame->dwMaxVideoFrameBufferSize =
 				get_unaligned_le32(&buffer[17]);
 			frame->dwDefaultFrameInterval =
@@ -491,12 +503,12 @@ static int uvc_parse_format(struct uvc_device *dev,
 		buffer += buffer[0];
 	}
 
-	if (buflen > 2 && buffer[2] == VS_STILL_IMAGE_FRAME) {
+	if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
 		buflen -= buffer[0];
 		buffer += buffer[0];
 	}
 
-	if (buflen > 2 && buffer[2] == VS_COLORFORMAT) {
+	if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) {
 		if (buflen < 6) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 			       "interface %d COLORFORMAT error\n",
@@ -530,7 +542,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 	int ret = -EINVAL;
 
 	if (intf->cur_altsetting->desc.bInterfaceSubClass
-		!= SC_VIDEOSTREAMING) {
+		!= UVC_SC_VIDEOSTREAMING) {
 		uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a "
 			"video streaming interface\n", dev->udev->devnum,
 			intf->altsetting[0].desc.bInterfaceNumber);
@@ -551,6 +563,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 	}
 
 	mutex_init(&streaming->mutex);
+	streaming->dev = dev;
 	streaming->intf = usb_get_intf(intf);
 	streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
 
@@ -589,12 +602,12 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 
 	/* Parse the header descriptor. */
 	switch (buffer[2]) {
-	case VS_OUTPUT_HEADER:
+	case UVC_VS_OUTPUT_HEADER:
 		streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
 		size = 9;
 		break;
 
-	case VS_INPUT_HEADER:
+	case UVC_VS_INPUT_HEADER:
 		streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 		size = 13;
 		break;
@@ -618,7 +631,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 
 	streaming->header.bNumFormats = p;
 	streaming->header.bEndpointAddress = buffer[6];
-	if (buffer[2] == VS_INPUT_HEADER) {
+	if (buffer[2] == UVC_VS_INPUT_HEADER) {
 		streaming->header.bmInfo = buffer[7];
 		streaming->header.bTerminalLink = buffer[8];
 		streaming->header.bStillCaptureMethod = buffer[9];
@@ -644,15 +657,15 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 	_buflen = buflen;
 
 	/* Count the format and frame descriptors. */
-	while (_buflen > 2 && _buffer[1] == CS_INTERFACE) {
+	while (_buflen > 2 && _buffer[1] == USB_DT_CS_INTERFACE) {
 		switch (_buffer[2]) {
-		case VS_FORMAT_UNCOMPRESSED:
-		case VS_FORMAT_MJPEG:
-		case VS_FORMAT_FRAME_BASED:
+		case UVC_VS_FORMAT_UNCOMPRESSED:
+		case UVC_VS_FORMAT_MJPEG:
+		case UVC_VS_FORMAT_FRAME_BASED:
 			nformats++;
 			break;
 
-		case VS_FORMAT_DV:
+		case UVC_VS_FORMAT_DV:
 			/* DV format has no frame descriptor. We will create a
 			 * dummy frame descriptor with a dummy frame interval.
 			 */
@@ -661,22 +674,22 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 			nintervals++;
 			break;
 
-		case VS_FORMAT_MPEG2TS:
-		case VS_FORMAT_STREAM_BASED:
+		case UVC_VS_FORMAT_MPEG2TS:
+		case UVC_VS_FORMAT_STREAM_BASED:
 			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
 				"interface %d FORMAT %u is not supported.\n",
 				dev->udev->devnum,
 				alts->desc.bInterfaceNumber, _buffer[2]);
 			break;
 
-		case VS_FRAME_UNCOMPRESSED:
-		case VS_FRAME_MJPEG:
+		case UVC_VS_FRAME_UNCOMPRESSED:
+		case UVC_VS_FRAME_MJPEG:
 			nframes++;
 			if (_buflen > 25)
 				nintervals += _buffer[25] ? _buffer[25] : 3;
 			break;
 
-		case VS_FRAME_FRAME_BASED:
+		case UVC_VS_FRAME_FRAME_BASED:
 			nframes++;
 			if (_buflen > 21)
 				nintervals += _buffer[21] ? _buffer[21] : 3;
@@ -709,12 +722,12 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 	streaming->nformats = nformats;
 
 	/* Parse the format descriptors. */
-	while (buflen > 2 && buffer[1] == CS_INTERFACE) {
+	while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) {
 		switch (buffer[2]) {
-		case VS_FORMAT_UNCOMPRESSED:
-		case VS_FORMAT_MJPEG:
-		case VS_FORMAT_DV:
-		case VS_FORMAT_FRAME_BASED:
+		case UVC_VS_FORMAT_UNCOMPRESSED:
+		case UVC_VS_FORMAT_MJPEG:
+		case UVC_VS_FORMAT_DV:
+		case UVC_VS_FORMAT_FRAME_BASED:
 			format->frame = frame;
 			ret = uvc_parse_format(dev, streaming, format,
 				&interval, buffer, buflen);
@@ -751,7 +764,7 @@ static int uvc_parse_streaming(struct uvc_device *dev,
 			streaming->maxpsize = psize;
 	}
 
-	list_add_tail(&streaming->list, &dev->streaming);
+	list_add_tail(&streaming->list, &dev->streams);
 	return 0;
 
 error:
@@ -819,7 +832,7 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
 			return -ENOMEM;
 
 		unit->id = buffer[3];
-		unit->type = VC_EXTENSION_UNIT;
+		unit->type = UVC_VC_EXTENSION_UNIT;
 		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
 		unit->extension.bNumControls = buffer[20];
 		unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
@@ -856,7 +869,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 	__u16 type;
 
 	switch (buffer[2]) {
-	case VC_HEADER:
+	case UVC_VC_HEADER:
 		n = buflen >= 12 ? buffer[11] : 0;
 
 		if (buflen < 12 || buflen < 12 + n) {
@@ -883,7 +896,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		}
 		break;
 
-	case VC_INPUT_TERMINAL:
+	case UVC_VC_INPUT_TERMINAL:
 		if (buflen < 8) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
 				"interface %d INPUT_TERMINAL error\n",
@@ -908,11 +921,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		p = 0;
 		len = 8;
 
-		if (type == ITT_CAMERA) {
+		if (type == UVC_ITT_CAMERA) {
 			n = buflen >= 15 ? buffer[14] : 0;
 			len = 15;
 
-		} else if (type == ITT_MEDIA_TRANSPORT_INPUT) {
+		} else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {
 			n = buflen >= 9 ? buffer[8] : 0;
 			p = buflen >= 10 + n ? buffer[9+n] : 0;
 			len = 10;
@@ -932,7 +945,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		term->id = buffer[3];
 		term->type = type | UVC_TERM_INPUT;
 
-		if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) {
+		if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
 			term->camera.bControlSize = n;
 			term->camera.bmControls = (__u8 *)term + sizeof *term;
 			term->camera.wObjectiveFocalLengthMin =
@@ -942,7 +955,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 			term->camera.wOcularFocalLength =
 				get_unaligned_le16(&buffer[12]);
 			memcpy(term->camera.bmControls, &buffer[15], n);
-		} else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) {
+		} else if (UVC_ENTITY_TYPE(term) ==
+			   UVC_ITT_MEDIA_TRANSPORT_INPUT) {
 			term->media.bControlSize = n;
 			term->media.bmControls = (__u8 *)term + sizeof *term;
 			term->media.bTransportModeSize = p;
@@ -955,9 +969,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		if (buffer[7] != 0)
 			usb_string(udev, buffer[7], term->name,
 				   sizeof term->name);
-		else if (UVC_ENTITY_TYPE(term) == ITT_CAMERA)
+		else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
 			sprintf(term->name, "Camera %u", buffer[3]);
-		else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT)
+		else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
 			sprintf(term->name, "Media %u", buffer[3]);
 		else
 			sprintf(term->name, "Input %u", buffer[3]);
@@ -965,7 +979,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		list_add_tail(&term->list, &dev->entities);
 		break;
 
-	case VC_OUTPUT_TERMINAL:
+	case UVC_VC_OUTPUT_TERMINAL:
 		if (buflen < 9) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
 				"interface %d OUTPUT_TERMINAL error\n",
@@ -1002,7 +1016,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		list_add_tail(&term->list, &dev->entities);
 		break;
 
-	case VC_SELECTOR_UNIT:
+	case UVC_VC_SELECTOR_UNIT:
 		p = buflen >= 5 ? buffer[4] : 0;
 
 		if (buflen < 5 || buflen < 6 + p) {
@@ -1031,7 +1045,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		list_add_tail(&unit->list, &dev->entities);
 		break;
 
-	case VC_PROCESSING_UNIT:
+	case UVC_VC_PROCESSING_UNIT:
 		n = buflen >= 8 ? buffer[7] : 0;
 		p = dev->uvc_version >= 0x0110 ? 10 : 9;
 
@@ -1066,7 +1080,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
 		list_add_tail(&unit->list, &dev->entities);
 		break;
 
-	case VC_EXTENSION_UNIT:
+	case UVC_VC_EXTENSION_UNIT:
 		p = buflen >= 22 ? buffer[21] : 0;
 		n = buflen >= 24 + p ? buffer[22+p] : 0;
 
@@ -1158,43 +1172,40 @@ next_descriptor:
 }
 
 /* ------------------------------------------------------------------------
- * USB probe and disconnect
+ * UVC device scan
  */
 
 /*
- * Unregister the video devices.
- */
-static void uvc_unregister_video(struct uvc_device *dev)
-{
-	if (dev->video.vdev) {
-		if (dev->video.vdev->minor == -1)
-			video_device_release(dev->video.vdev);
-		else
-			video_unregister_device(dev->video.vdev);
-		dev->video.vdev = NULL;
-	}
-}
-
-/*
  * Scan the UVC descriptors to locate a chain starting at an Output Terminal
  * and containing the following units:
  *
- * - one Output Terminal (USB Streaming or Display)
+ * - one or more Output Terminals (USB Streaming or Display)
  * - zero or one Processing Unit
- * - zero, one or mode single-input Selector Units
+ * - zero, one or more single-input Selector Units
  * - zero or one multiple-input Selector Units, provided all inputs are
  *   connected to input terminals
  * - zero, one or mode single-input Extension Units
  * - one or more Input Terminals (Camera, External or USB Streaming)
  *
- * A side forward scan is made on each detected entity to check for additional
- * extension units.
+ * The terminal and units must match on of the following structures:
+ *
+ * ITT_*(0) -> +---------+    +---------+    +---------+ -> TT_STREAMING(0)
+ * ...         | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} |    ...
+ * ITT_*(n) -> +---------+    +---------+    +---------+ -> TT_STREAMING(n)
+ *
+ *                 +---------+    +---------+ -> OTT_*(0)
+ * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} |    ...
+ *                 +---------+    +---------+ -> OTT_*(n)
+ *
+ * The Processing Unit and Extension Units can be in any order. Additional
+ * Extension Units connected to the main chain as single-unit branches are
+ * also supported. Single-input Selector Units are ignored.
  */
-static int uvc_scan_chain_entity(struct uvc_video_device *video,
+static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
 	struct uvc_entity *entity)
 {
 	switch (UVC_ENTITY_TYPE(entity)) {
-	case VC_EXTENSION_UNIT:
+	case UVC_VC_EXTENSION_UNIT:
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- XU %d", entity->id);
 
@@ -1204,23 +1215,23 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
 			return -1;
 		}
 
-		list_add_tail(&entity->chain, &video->extensions);
+		list_add_tail(&entity->chain, &chain->extensions);
 		break;
 
-	case VC_PROCESSING_UNIT:
+	case UVC_VC_PROCESSING_UNIT:
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- PU %d", entity->id);
 
-		if (video->processing != NULL) {
+		if (chain->processing != NULL) {
 			uvc_trace(UVC_TRACE_DESCR, "Found multiple "
 				"Processing Units in chain.\n");
 			return -1;
 		}
 
-		video->processing = entity;
+		chain->processing = entity;
 		break;
 
-	case VC_SELECTOR_UNIT:
+	case UVC_VC_SELECTOR_UNIT:
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- SU %d", entity->id);
 
@@ -1228,25 +1239,25 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
 		if (entity->selector.bNrInPins == 1)
 			break;
 
-		if (video->selector != NULL) {
+		if (chain->selector != NULL) {
 			uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector "
 				"Units in chain.\n");
 			return -1;
 		}
 
-		video->selector = entity;
+		chain->selector = entity;
 		break;
 
-	case ITT_VENDOR_SPECIFIC:
-	case ITT_CAMERA:
-	case ITT_MEDIA_TRANSPORT_INPUT:
+	case UVC_ITT_VENDOR_SPECIFIC:
+	case UVC_ITT_CAMERA:
+	case UVC_ITT_MEDIA_TRANSPORT_INPUT:
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- IT %d\n", entity->id);
 
-		list_add_tail(&entity->chain, &video->iterms);
+		list_add_tail(&entity->chain, &chain->iterms);
 		break;
 
-	case TT_STREAMING:
+	case UVC_TT_STREAMING:
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- IT %d\n", entity->id);
 
@@ -1256,14 +1267,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
 			return -1;
 		}
 
-		if (video->sterm != NULL) {
-			uvc_trace(UVC_TRACE_DESCR, "Found multiple streaming "
-				"entities in chain.\n");
-			return -1;
-		}
-
-		list_add_tail(&entity->chain, &video->iterms);
-		video->sterm = entity;
+		list_add_tail(&entity->chain, &chain->iterms);
 		break;
 
 	default:
@@ -1275,7 +1279,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
 	return 0;
 }
 
-static int uvc_scan_chain_forward(struct uvc_video_device *video,
+static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
 	struct uvc_entity *entity, struct uvc_entity *prev)
 {
 	struct uvc_entity *forward;
@@ -1286,28 +1290,51 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
 	found = 0;
 
 	while (1) {
-		forward = uvc_entity_by_reference(video->dev, entity->id,
+		forward = uvc_entity_by_reference(chain->dev, entity->id,
 			forward);
 		if (forward == NULL)
 			break;
-
-		if (UVC_ENTITY_TYPE(forward) != VC_EXTENSION_UNIT ||
-		    forward == prev)
+		if (forward == prev)
 			continue;
 
-		if (forward->extension.bNrInPins != 1) {
-			uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has "
-				"more than 1 input pin.\n", entity->id);
-			return -1;
-		}
+		switch (UVC_ENTITY_TYPE(forward)) {
+		case UVC_VC_EXTENSION_UNIT:
+			if (forward->extension.bNrInPins != 1) {
+				uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
+					  "has more than 1 input pin.\n",
+					  entity->id);
+				return -EINVAL;
+			}
+
+			list_add_tail(&forward->chain, &chain->extensions);
+			if (uvc_trace_param & UVC_TRACE_PROBE) {
+				if (!found)
+					printk(" (->");
 
-		list_add_tail(&forward->chain, &video->extensions);
-		if (uvc_trace_param & UVC_TRACE_PROBE) {
-			if (!found)
-				printk(" (-> XU");
+				printk(" XU %d", forward->id);
+				found = 1;
+			}
+			break;
+
+		case UVC_OTT_VENDOR_SPECIFIC:
+		case UVC_OTT_DISPLAY:
+		case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
+		case UVC_TT_STREAMING:
+			if (UVC_ENTITY_IS_ITERM(forward)) {
+				uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
+					"terminal %u.\n", forward->id);
+				return -EINVAL;
+			}
 
-			printk(" %d", forward->id);
-			found = 1;
+			list_add_tail(&forward->chain, &chain->oterms);
+			if (uvc_trace_param & UVC_TRACE_PROBE) {
+				if (!found)
+					printk(" (->");
+
+				printk(" OT %d", forward->id);
+				found = 1;
+			}
+			break;
 		}
 	}
 	if (found)
@@ -1316,22 +1343,22 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
 	return 0;
 }
 
-static int uvc_scan_chain_backward(struct uvc_video_device *video,
+static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
 	struct uvc_entity *entity)
 {
 	struct uvc_entity *term;
 	int id = -1, i;
 
 	switch (UVC_ENTITY_TYPE(entity)) {
-	case VC_EXTENSION_UNIT:
+	case UVC_VC_EXTENSION_UNIT:
 		id = entity->extension.baSourceID[0];
 		break;
 
-	case VC_PROCESSING_UNIT:
+	case UVC_VC_PROCESSING_UNIT:
 		id = entity->processing.bSourceID;
 		break;
 
-	case VC_SELECTOR_UNIT:
+	case UVC_VC_SELECTOR_UNIT:
 		/* Single-input selector units are ignored. */
 		if (entity->selector.bNrInPins == 1) {
 			id = entity->selector.baSourceID[0];
@@ -1341,10 +1368,10 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
 		if (uvc_trace_param & UVC_TRACE_PROBE)
 			printk(" <- IT");
 
-		video->selector = entity;
+		chain->selector = entity;
 		for (i = 0; i < entity->selector.bNrInPins; ++i) {
 			id = entity->selector.baSourceID[i];
-			term = uvc_entity_by_id(video->dev, id);
+			term = uvc_entity_by_id(chain->dev, id);
 			if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
 				uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
 					"input %d isn't connected to an "
@@ -1355,8 +1382,8 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
 			if (uvc_trace_param & UVC_TRACE_PROBE)
 				printk(" %d", term->id);
 
-			list_add_tail(&term->chain, &video->iterms);
-			uvc_scan_chain_forward(video, term, entity);
+			list_add_tail(&term->chain, &chain->iterms);
+			uvc_scan_chain_forward(chain, term, entity);
 		}
 
 		if (uvc_trace_param & UVC_TRACE_PROBE)
@@ -1369,125 +1396,170 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
 	return id;
 }
 
-static int uvc_scan_chain(struct uvc_video_device *video)
+static int uvc_scan_chain(struct uvc_video_chain *chain,
+			  struct uvc_entity *oterm)
 {
 	struct uvc_entity *entity, *prev;
 	int id;
 
-	entity = video->oterm;
+	entity = oterm;
+	list_add_tail(&entity->chain, &chain->oterms);
 	uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
 
-	if (UVC_ENTITY_TYPE(entity) == TT_STREAMING)
-		video->sterm = entity;
-
 	id = entity->output.bSourceID;
 	while (id != 0) {
 		prev = entity;
-		entity = uvc_entity_by_id(video->dev, id);
+		entity = uvc_entity_by_id(chain->dev, id);
 		if (entity == NULL) {
 			uvc_trace(UVC_TRACE_DESCR, "Found reference to "
 				"unknown entity %d.\n", id);
-			return -1;
+			return -EINVAL;
+		}
+
+		if (entity->chain.next || entity->chain.prev) {
+			uvc_trace(UVC_TRACE_DESCR, "Found reference to "
+				"entity %d already in chain.\n", id);
+			return -EINVAL;
 		}
 
 		/* Process entity */
-		if (uvc_scan_chain_entity(video, entity) < 0)
-			return -1;
+		if (uvc_scan_chain_entity(chain, entity) < 0)
+			return -EINVAL;
 
 		/* Forward scan */
-		if (uvc_scan_chain_forward(video, entity, prev) < 0)
-			return -1;
+		if (uvc_scan_chain_forward(chain, entity, prev) < 0)
+			return -EINVAL;
 
 		/* Stop when a terminal is found. */
-		if (!UVC_ENTITY_IS_UNIT(entity))
+		if (UVC_ENTITY_IS_TERM(entity))
 			break;
 
 		/* Backward scan */
-		id = uvc_scan_chain_backward(video, entity);
+		id = uvc_scan_chain_backward(chain, entity);
 		if (id < 0)
 			return id;
 	}
 
-	if (video->sterm == NULL) {
-		uvc_trace(UVC_TRACE_DESCR, "No streaming entity found in "
-			"chain.\n");
-		return -1;
+	return 0;
+}
+
+static unsigned int uvc_print_terms(struct list_head *terms, char *buffer)
+{
+	struct uvc_entity *term;
+	unsigned int nterms = 0;
+	char *p = buffer;
+
+	list_for_each_entry(term, terms, chain) {
+		p += sprintf(p, "%u", term->id);
+		if (term->chain.next != terms) {
+			p += sprintf(p, ",");
+			if (++nterms >= 4) {
+				p += sprintf(p, "...");
+				break;
+			}
+		}
 	}
 
-	return 0;
+	return p - buffer;
+}
+
+static const char *uvc_print_chain(struct uvc_video_chain *chain)
+{
+	static char buffer[43];
+	char *p = buffer;
+
+	p += uvc_print_terms(&chain->iterms, p);
+	p += sprintf(p, " -> ");
+	uvc_print_terms(&chain->oterms, p);
+
+	return buffer;
 }
 
 /*
- * Register the video devices.
- *
- * The driver currently supports a single video device per control interface
- * only. The terminal and units must match the following structure:
+ * Scan the device for video chains and register video devices.
  *
- * ITT_* -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING
- * TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_*
- *
- * The Extension Units, if present, must have a single input pin. The
- * Processing Unit and Extension Units can be in any order. Additional
- * Extension Units connected to the main chain as single-unit branches are
- * also supported.
+ * Chains are scanned starting at their output terminals and walked backwards.
  */
-static int uvc_register_video(struct uvc_device *dev)
+static int uvc_scan_device(struct uvc_device *dev)
 {
-	struct video_device *vdev;
+	struct uvc_video_chain *chain;
 	struct uvc_entity *term;
-	int found = 0, ret;
 
-	/* Check if the control interface matches the structure we expect. */
 	list_for_each_entry(term, &dev->entities, list) {
-		struct uvc_streaming *streaming;
-
-		if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term))
+		if (!UVC_ENTITY_IS_OTERM(term))
 			continue;
 
-		memset(&dev->video, 0, sizeof dev->video);
-		mutex_init(&dev->video.ctrl_mutex);
-		INIT_LIST_HEAD(&dev->video.iterms);
-		INIT_LIST_HEAD(&dev->video.extensions);
-		dev->video.oterm = term;
-		dev->video.dev = dev;
-		if (uvc_scan_chain(&dev->video) < 0)
+		/* If the terminal is already included in a chain, skip it.
+		 * This can happen for chains that have multiple output
+		 * terminals, where all output terminals beside the first one
+		 * will be inserted in the chain in forward scans.
+		 */
+		if (term->chain.next || term->chain.prev)
 			continue;
 
-		list_for_each_entry(streaming, &dev->streaming, list) {
-			if (streaming->header.bTerminalLink ==
-			    dev->video.sterm->id) {
-				dev->video.streaming = streaming;
-				found = 1;
-				break;
-			}
+		chain = kzalloc(sizeof(*chain), GFP_KERNEL);
+		if (chain == NULL)
+			return -ENOMEM;
+
+		INIT_LIST_HEAD(&chain->iterms);
+		INIT_LIST_HEAD(&chain->oterms);
+		INIT_LIST_HEAD(&chain->extensions);
+		mutex_init(&chain->ctrl_mutex);
+		chain->dev = dev;
+
+		if (uvc_scan_chain(chain, term) < 0) {
+			kfree(chain);
+			continue;
 		}
 
-		if (found)
-			break;
+		uvc_trace(UVC_TRACE_PROBE, "Found a valid video chain (%s).\n",
+			  uvc_print_chain(chain));
+
+		list_add_tail(&chain->list, &dev->chains);
 	}
 
-	if (!found) {
+	if (list_empty(&dev->chains)) {
 		uvc_printk(KERN_INFO, "No valid video chain found.\n");
 		return -1;
 	}
 
-	if (uvc_trace_param & UVC_TRACE_PROBE) {
-		uvc_printk(KERN_INFO, "Found a valid video chain (");
-		list_for_each_entry(term, &dev->video.iterms, chain) {
-			printk("%d", term->id);
-			if (term->chain.next != &dev->video.iterms)
-				printk(",");
-		}
-		printk(" -> %d).\n", dev->video.oterm->id);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * Video device registration and unregistration
+ */
+
+/*
+ * Unregister the video devices.
+ */
+static void uvc_unregister_video(struct uvc_device *dev)
+{
+	struct uvc_streaming *stream;
+
+	list_for_each_entry(stream, &dev->streams, list) {
+		if (stream->vdev == NULL)
+			continue;
+
+		if (stream->vdev->minor == -1)
+			video_device_release(stream->vdev);
+		else
+			video_unregister_device(stream->vdev);
+		stream->vdev = NULL;
 	}
+}
 
-	/* Initialize the video buffers queue. */
-	uvc_queue_init(&dev->video.queue, dev->video.streaming->type);
+static int uvc_register_video(struct uvc_device *dev,
+		struct uvc_streaming *stream)
+{
+	struct video_device *vdev;
+	int ret;
 
 	/* Initialize the streaming interface with default streaming
 	 * parameters.
 	 */
-	if ((ret = uvc_video_init(&dev->video)) < 0) {
+	ret = uvc_video_init(stream);
+	if (ret < 0) {
 		uvc_printk(KERN_ERR, "Failed to initialize the device "
 			"(%d).\n", ret);
 		return ret;
@@ -1495,8 +1567,11 @@ static int uvc_register_video(struct uvc_device *dev)
 
 	/* Register the device with V4L. */
 	vdev = video_device_alloc();
-	if (vdev == NULL)
-		return -1;
+	if (vdev == NULL) {
+		uvc_printk(KERN_ERR, "Failed to allocate video device (%d).\n",
+			   ret);
+		return -ENOMEM;
+	}
 
 	/* We already hold a reference to dev->udev. The video device will be
 	 * unregistered before the reference is released, so we don't need to
@@ -1511,19 +1586,74 @@ static int uvc_register_video(struct uvc_device *dev)
 	/* Set the driver data before calling video_register_device, otherwise
 	 * uvc_v4l2_open might race us.
 	 */
-	dev->video.vdev = vdev;
-	video_set_drvdata(vdev, &dev->video);
-
-	if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) {
-		dev->video.vdev = NULL;
+	stream->vdev = vdev;
+	video_set_drvdata(vdev, stream);
+
+	ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+	if (ret < 0) {
+		uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
+			   ret);
+		stream->vdev = NULL;
 		video_device_release(vdev);
-		return -1;
+		return ret;
 	}
 
 	return 0;
 }
 
 /*
+ * Register all video devices in all chains.
+ */
+static int uvc_register_terms(struct uvc_device *dev,
+	struct uvc_video_chain *chain, struct list_head *terms)
+{
+	struct uvc_streaming *stream;
+	struct uvc_entity *term;
+	int ret;
+
+	list_for_each_entry(term, terms, chain) {
+		if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
+			continue;
+
+		stream = uvc_stream_by_id(dev, term->id);
+		if (stream == NULL) {
+			uvc_printk(KERN_INFO, "No streaming interface found "
+				   "for terminal %u.", term->id);
+			continue;
+		}
+
+		stream->chain = chain;
+		ret = uvc_register_video(dev, stream);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int uvc_register_chains(struct uvc_device *dev)
+{
+	struct uvc_video_chain *chain;
+	int ret;
+
+	list_for_each_entry(chain, &dev->chains, list) {
+		ret = uvc_register_terms(dev, chain, &chain->iterms);
+		if (ret < 0)
+			return ret;
+
+		ret = uvc_register_terms(dev, chain, &chain->oterms);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * USB probe, disconnect, suspend and resume
+ */
+
+/*
  * Delete the UVC device.
  *
  * Called by the kernel when the last reference to the uvc_device structure
@@ -1544,7 +1674,7 @@ void uvc_delete(struct kref *kref)
 	struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
 	struct list_head *p, *n;
 
-	/* Unregister the video device. */
+	/* Unregister the video devices. */
 	uvc_unregister_video(dev);
 	usb_put_intf(dev->intf);
 	usb_put_dev(dev->udev);
@@ -1552,13 +1682,19 @@ void uvc_delete(struct kref *kref)
 	uvc_status_cleanup(dev);
 	uvc_ctrl_cleanup_device(dev);
 
+	list_for_each_safe(p, n, &dev->chains) {
+		struct uvc_video_chain *chain;
+		chain = list_entry(p, struct uvc_video_chain, list);
+		kfree(chain);
+	}
+
 	list_for_each_safe(p, n, &dev->entities) {
 		struct uvc_entity *entity;
 		entity = list_entry(p, struct uvc_entity, list);
 		kfree(entity);
 	}
 
-	list_for_each_safe(p, n, &dev->streaming) {
+	list_for_each_safe(p, n, &dev->streams) {
 		struct uvc_streaming *streaming;
 		streaming = list_entry(p, struct uvc_streaming, list);
 		usb_driver_release_interface(&uvc_driver.driver,
@@ -1592,7 +1728,8 @@ static int uvc_probe(struct usb_interface *intf,
 		return -ENOMEM;
 
 	INIT_LIST_HEAD(&dev->entities);
-	INIT_LIST_HEAD(&dev->streaming);
+	INIT_LIST_HEAD(&dev->chains);
+	INIT_LIST_HEAD(&dev->streams);
 	kref_init(&dev->kref);
 	atomic_set(&dev->users, 0);
 
@@ -1633,8 +1770,12 @@ static int uvc_probe(struct usb_interface *intf,
 	if (uvc_ctrl_init_device(dev) < 0)
 		goto error;
 
-	/* Register the video devices. */
-	if (uvc_register_video(dev) < 0)
+	/* Scan the device for video chains. */
+	if (uvc_scan_device(dev) < 0)
+		goto error;
+
+	/* Register video devices. */
+	if (uvc_register_chains(dev) < 0)
 		goto error;
 
 	/* Save our data pointer in the interface data. */
@@ -1664,7 +1805,8 @@ static void uvc_disconnect(struct usb_interface *intf)
 	 */
 	usb_set_intfdata(intf, NULL);
 
-	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING)
+	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
+	    UVC_SC_VIDEOSTREAMING)
 		return;
 
 	/* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide
@@ -1687,31 +1829,36 @@ static void uvc_disconnect(struct usb_interface *intf)
 static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct uvc_device *dev = usb_get_intfdata(intf);
+	struct uvc_streaming *stream;
 
 	uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n",
 		intf->cur_altsetting->desc.bInterfaceNumber);
 
 	/* Controls are cached on the fly so they don't need to be saved. */
-	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL)
+	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
+	    UVC_SC_VIDEOCONTROL)
 		return uvc_status_suspend(dev);
 
-	if (dev->video.streaming->intf != intf) {
-		uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB "
-				"interface mismatch.\n");
-		return -EINVAL;
+	list_for_each_entry(stream, &dev->streams, list) {
+		if (stream->intf == intf)
+			return uvc_video_suspend(stream);
 	}
 
-	return uvc_video_suspend(&dev->video);
+	uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB interface "
+			"mismatch.\n");
+	return -EINVAL;
 }
 
 static int __uvc_resume(struct usb_interface *intf, int reset)
 {
 	struct uvc_device *dev = usb_get_intfdata(intf);
+	struct uvc_streaming *stream;
 
 	uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
 		intf->cur_altsetting->desc.bInterfaceNumber);
 
-	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) {
+	if (intf->cur_altsetting->desc.bInterfaceSubClass ==
+	    UVC_SC_VIDEOCONTROL) {
 		if (reset) {
 			int ret = uvc_ctrl_resume_device(dev);
 
@@ -1722,13 +1869,14 @@ static int __uvc_resume(struct usb_interface *intf, int reset)
 		return uvc_status_resume(dev);
 	}
 
-	if (dev->video.streaming->intf != intf) {
-		uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB "
-				"interface mismatch.\n");
-		return -EINVAL;
+	list_for_each_entry(stream, &dev->streams, list) {
+		if (stream->intf == intf)
+			return uvc_video_resume(stream);
 	}
 
-	return uvc_video_resume(&dev->video);
+	uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface "
+			"mismatch.\n");
+	return -EINVAL;
 }
 
 static int uvc_resume(struct usb_interface *intf)
@@ -1880,7 +2028,8 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
+				| UVC_QUIRK_PROBE_DEF },
 	/* Syntek (HP Spartan) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1943,7 +2092,8 @@ static struct usb_device_id uvc_ids[] = {
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_EXTRAFIELDS },
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
+				| UVC_QUIRK_PROBE_EXTRAFIELDS },
 	/* Ecamm Pico iMage */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c
index 436f462..a9285b5 100644
--- a/drivers/media/video/uvc/uvc_isight.c
+++ b/drivers/media/video/uvc/uvc_isight.c
@@ -99,7 +99,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
 	return 0;
 }
 
-void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
+void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
 		struct uvc_buffer *buf)
 {
 	int ret, i;
@@ -120,7 +120,7 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
 		 * processes the data of the first payload of the new frame.
 		 */
 		do {
-			ret = isight_decode(&video->queue, buf,
+			ret = isight_decode(&stream->queue, buf,
 					urb->transfer_buffer +
 					urb->iso_frame_desc[i].offset,
 					urb->iso_frame_desc[i].actual_length);
@@ -130,7 +130,8 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
 
 			if (buf->state == UVC_BUF_STATE_DONE ||
 			    buf->state == UVC_BUF_STATE_ERROR)
-				buf = uvc_queue_next_buffer(&video->queue, buf);
+				buf = uvc_queue_next_buffer(&stream->queue,
+							buf);
 		} while (ret == -EAGAIN);
 	}
 }
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 5e77cad..9e73515 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -40,7 +40,7 @@
  * table for the controls that can be mapped directly, and handle the others
  * manually.
  */
-static int uvc_v4l2_query_menu(struct uvc_video_device *video,
+static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
 	struct v4l2_querymenu *query_menu)
 {
 	struct uvc_menu_info *menu_info;
@@ -49,7 +49,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
 	u32 index = query_menu->index;
 	u32 id = query_menu->id;
 
-	ctrl = uvc_find_control(video, query_menu->id, &mapping);
+	ctrl = uvc_find_control(chain, query_menu->id, &mapping);
 	if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
 		return -EINVAL;
 
@@ -103,7 +103,7 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
 	return interval;
 }
 
-static int uvc_v4l2_try_format(struct uvc_video_device *video,
+static int uvc_v4l2_try_format(struct uvc_streaming *stream,
 	struct v4l2_format *fmt, struct uvc_streaming_control *probe,
 	struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
 {
@@ -116,7 +116,7 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
 	int ret = 0;
 	__u8 *fcc;
 
-	if (fmt->type != video->streaming->type)
+	if (fmt->type != stream->type)
 		return -EINVAL;
 
 	fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
@@ -126,8 +126,8 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
 			fmt->fmt.pix.width, fmt->fmt.pix.height);
 
 	/* Check if the hardware supports the requested format. */
-	for (i = 0; i < video->streaming->nformats; ++i) {
-		format = &video->streaming->format[i];
+	for (i = 0; i < stream->nformats; ++i) {
+		format = &stream->format[i];
 		if (format->fcc == fmt->fmt.pix.pixelformat)
 			break;
 	}
@@ -191,12 +191,13 @@ static int uvc_v4l2_try_format(struct uvc_video_device *video,
 	 * developers test their webcams with the Linux driver as well as with
 	 * the Windows driver).
 	 */
-	if (video->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
+	if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
 		probe->dwMaxVideoFrameSize =
-			video->streaming->ctrl.dwMaxVideoFrameSize;
+			stream->ctrl.dwMaxVideoFrameSize;
 
 	/* Probe the device. */
-	if ((ret = uvc_probe_video(video, probe)) < 0)
+	ret = uvc_probe_video(stream, probe);
+	if (ret < 0)
 		goto done;
 
 	fmt->fmt.pix.width = frame->wWidth;
@@ -216,13 +217,13 @@ done:
 	return ret;
 }
 
-static int uvc_v4l2_get_format(struct uvc_video_device *video,
+static int uvc_v4l2_get_format(struct uvc_streaming *stream,
 	struct v4l2_format *fmt)
 {
-	struct uvc_format *format = video->streaming->cur_format;
-	struct uvc_frame *frame = video->streaming->cur_frame;
+	struct uvc_format *format = stream->cur_format;
+	struct uvc_frame *frame = stream->cur_frame;
 
-	if (fmt->type != video->streaming->type)
+	if (fmt->type != stream->type)
 		return -EINVAL;
 
 	if (format == NULL || frame == NULL)
@@ -233,14 +234,14 @@ static int uvc_v4l2_get_format(struct uvc_video_device *video,
 	fmt->fmt.pix.height = frame->wHeight;
 	fmt->fmt.pix.field = V4L2_FIELD_NONE;
 	fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
-	fmt->fmt.pix.sizeimage = video->streaming->ctrl.dwMaxVideoFrameSize;
+	fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
 	fmt->fmt.pix.colorspace = format->colorspace;
 	fmt->fmt.pix.priv = 0;
 
 	return 0;
 }
 
-static int uvc_v4l2_set_format(struct uvc_video_device *video,
+static int uvc_v4l2_set_format(struct uvc_streaming *stream,
 	struct v4l2_format *fmt)
 {
 	struct uvc_streaming_control probe;
@@ -248,39 +249,39 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video,
 	struct uvc_frame *frame;
 	int ret;
 
-	if (fmt->type != video->streaming->type)
+	if (fmt->type != stream->type)
 		return -EINVAL;
 
-	if (uvc_queue_allocated(&video->queue))
+	if (uvc_queue_allocated(&stream->queue))
 		return -EBUSY;
 
-	ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame);
+	ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
 	if (ret < 0)
 		return ret;
 
-	memcpy(&video->streaming->ctrl, &probe, sizeof probe);
-	video->streaming->cur_format = format;
-	video->streaming->cur_frame = frame;
+	memcpy(&stream->ctrl, &probe, sizeof probe);
+	stream->cur_format = format;
+	stream->cur_frame = frame;
 
 	return 0;
 }
 
-static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
+static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
 		struct v4l2_streamparm *parm)
 {
 	uint32_t numerator, denominator;
 
-	if (parm->type != video->streaming->type)
+	if (parm->type != stream->type)
 		return -EINVAL;
 
-	numerator = video->streaming->ctrl.dwFrameInterval;
+	numerator = stream->ctrl.dwFrameInterval;
 	denominator = 10000000;
 	uvc_simplify_fraction(&numerator, &denominator, 8, 333);
 
 	memset(parm, 0, sizeof *parm);
-	parm->type = video->streaming->type;
+	parm->type = stream->type;
 
-	if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+	if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 		parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
 		parm->parm.capture.capturemode = 0;
 		parm->parm.capture.timeperframe.numerator = numerator;
@@ -297,19 +298,19 @@ static int uvc_v4l2_get_streamparm(struct uvc_video_device *video,
 	return 0;
 }
 
-static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
+static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
 		struct v4l2_streamparm *parm)
 {
-	struct uvc_frame *frame = video->streaming->cur_frame;
+	struct uvc_frame *frame = stream->cur_frame;
 	struct uvc_streaming_control probe;
 	struct v4l2_fract timeperframe;
 	uint32_t interval;
 	int ret;
 
-	if (parm->type != video->streaming->type)
+	if (parm->type != stream->type)
 		return -EINVAL;
 
-	if (uvc_queue_streaming(&video->queue))
+	if (uvc_queue_streaming(&stream->queue))
 		return -EBUSY;
 
 	if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -317,7 +318,7 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
 	else
 		timeperframe = parm->parm.output.timeperframe;
 
-	memcpy(&probe, &video->streaming->ctrl, sizeof probe);
+	memcpy(&probe, &stream->ctrl, sizeof probe);
 	interval = uvc_fraction_to_interval(timeperframe.numerator,
 		timeperframe.denominator);
 
@@ -326,10 +327,11 @@ static int uvc_v4l2_set_streamparm(struct uvc_video_device *video,
 	probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
 
 	/* Probe the device with the new settings. */
-	if ((ret = uvc_probe_video(video, &probe)) < 0)
+	ret = uvc_probe_video(stream, &probe);
+	if (ret < 0)
 		return ret;
 
-	memcpy(&video->streaming->ctrl, &probe, sizeof probe);
+	memcpy(&stream->ctrl, &probe, sizeof probe);
 
 	/* Return the actual frame period. */
 	timeperframe.numerator = probe.dwFrameInterval;
@@ -382,8 +384,8 @@ static int uvc_acquire_privileges(struct uvc_fh *handle)
 
 	/* Check if the device already has a privileged handle. */
 	mutex_lock(&uvc_driver.open_mutex);
-	if (atomic_inc_return(&handle->device->active) != 1) {
-		atomic_dec(&handle->device->active);
+	if (atomic_inc_return(&handle->stream->active) != 1) {
+		atomic_dec(&handle->stream->active);
 		ret = -EBUSY;
 		goto done;
 	}
@@ -398,7 +400,7 @@ done:
 static void uvc_dismiss_privileges(struct uvc_fh *handle)
 {
 	if (handle->state == UVC_HANDLE_ACTIVE)
-		atomic_dec(&handle->device->active);
+		atomic_dec(&handle->stream->active);
 
 	handle->state = UVC_HANDLE_PASSIVE;
 }
@@ -414,45 +416,47 @@ static int uvc_has_privileges(struct uvc_fh *handle)
 
 static int uvc_v4l2_open(struct file *file)
 {
-	struct uvc_video_device *video;
+	struct uvc_streaming *stream;
 	struct uvc_fh *handle;
 	int ret = 0;
 
 	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
 	mutex_lock(&uvc_driver.open_mutex);
-	video = video_drvdata(file);
+	stream = video_drvdata(file);
 
-	if (video->dev->state & UVC_DEV_DISCONNECTED) {
+	if (stream->dev->state & UVC_DEV_DISCONNECTED) {
 		ret = -ENODEV;
 		goto done;
 	}
 
-	ret = usb_autopm_get_interface(video->dev->intf);
+	ret = usb_autopm_get_interface(stream->dev->intf);
 	if (ret < 0)
 		goto done;
 
 	/* Create the device handle. */
 	handle = kzalloc(sizeof *handle, GFP_KERNEL);
 	if (handle == NULL) {
-		usb_autopm_put_interface(video->dev->intf);
+		usb_autopm_put_interface(stream->dev->intf);
 		ret = -ENOMEM;
 		goto done;
 	}
 
-	if (atomic_inc_return(&video->dev->users) == 1) {
-		if ((ret = uvc_status_start(video->dev)) < 0) {
-			usb_autopm_put_interface(video->dev->intf);
-			atomic_dec(&video->dev->users);
+	if (atomic_inc_return(&stream->dev->users) == 1) {
+		ret = uvc_status_start(stream->dev);
+		if (ret < 0) {
+			usb_autopm_put_interface(stream->dev->intf);
+			atomic_dec(&stream->dev->users);
 			kfree(handle);
 			goto done;
 		}
 	}
 
-	handle->device = video;
+	handle->chain = stream->chain;
+	handle->stream = stream;
 	handle->state = UVC_HANDLE_PASSIVE;
 	file->private_data = handle;
 
-	kref_get(&video->dev->kref);
+	kref_get(&stream->dev->kref);
 
 done:
 	mutex_unlock(&uvc_driver.open_mutex);
@@ -461,20 +465,20 @@ done:
 
 static int uvc_v4l2_release(struct file *file)
 {
-	struct uvc_video_device *video = video_drvdata(file);
 	struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
+	struct uvc_streaming *stream = handle->stream;
 
 	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
 
 	/* Only free resources if this is a privileged handle. */
 	if (uvc_has_privileges(handle)) {
-		uvc_video_enable(video, 0);
+		uvc_video_enable(stream, 0);
 
-		mutex_lock(&video->queue.mutex);
-		if (uvc_free_buffers(&video->queue) < 0)
+		mutex_lock(&stream->queue.mutex);
+		if (uvc_free_buffers(&stream->queue) < 0)
 			uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
 					"free buffers.\n");
-		mutex_unlock(&video->queue.mutex);
+		mutex_unlock(&stream->queue.mutex);
 	}
 
 	/* Release the file handle. */
@@ -482,19 +486,20 @@ static int uvc_v4l2_release(struct file *file)
 	kfree(handle);
 	file->private_data = NULL;
 
-	if (atomic_dec_return(&video->dev->users) == 0)
-		uvc_status_stop(video->dev);
+	if (atomic_dec_return(&stream->dev->users) == 0)
+		uvc_status_stop(stream->dev);
 
-	usb_autopm_put_interface(video->dev->intf);
-	kref_put(&video->dev->kref, uvc_delete);
+	usb_autopm_put_interface(stream->dev->intf);
+	kref_put(&stream->dev->kref, uvc_delete);
 	return 0;
 }
 
 static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 {
 	struct video_device *vdev = video_devdata(file);
-	struct uvc_video_device *video = video_get_drvdata(vdev);
 	struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
+	struct uvc_video_chain *chain = handle->chain;
+	struct uvc_streaming *stream = handle->stream;
 	long ret = 0;
 
 	switch (cmd) {
@@ -506,10 +511,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		memset(cap, 0, sizeof *cap);
 		strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
 		strlcpy(cap->card, vdev->name, sizeof cap->card);
-		usb_make_path(video->dev->udev,
+		usb_make_path(stream->dev->udev,
 			      cap->bus_info, sizeof(cap->bus_info));
 		cap->version = DRIVER_VERSION_NUMBER;
-		if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
 			cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
 					  | V4L2_CAP_STREAMING;
 		else
@@ -520,7 +525,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
 	/* Get, Set & Query control */
 	case VIDIOC_QUERYCTRL:
-		return uvc_query_v4l2_ctrl(video, arg);
+		return uvc_query_v4l2_ctrl(chain, arg);
 
 	case VIDIOC_G_CTRL:
 	{
@@ -530,12 +535,12 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		memset(&xctrl, 0, sizeof xctrl);
 		xctrl.id = ctrl->id;
 
-	       ret = uvc_ctrl_begin(video);
-	       if (ret < 0)
+		ret = uvc_ctrl_begin(chain);
+		if (ret < 0)
 			return ret;
 
-		ret = uvc_ctrl_get(video, &xctrl);
-		uvc_ctrl_rollback(video);
+		ret = uvc_ctrl_get(chain, &xctrl);
+		uvc_ctrl_rollback(chain);
 		if (ret >= 0)
 			ctrl->value = xctrl.value;
 		break;
@@ -550,21 +555,21 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		xctrl.id = ctrl->id;
 		xctrl.value = ctrl->value;
 
-	       ret = uvc_ctrl_begin(video);
-	       if (ret < 0)
+		uvc_ctrl_begin(chain);
+		if (ret < 0)
 			return ret;
 
-		ret = uvc_ctrl_set(video, &xctrl);
+		ret = uvc_ctrl_set(chain, &xctrl);
 		if (ret < 0) {
-			uvc_ctrl_rollback(video);
+			uvc_ctrl_rollback(chain);
 			return ret;
 		}
-		ret = uvc_ctrl_commit(video);
+		ret = uvc_ctrl_commit(chain);
 		break;
 	}
 
 	case VIDIOC_QUERYMENU:
-		return uvc_v4l2_query_menu(video, arg);
+		return uvc_v4l2_query_menu(chain, arg);
 
 	case VIDIOC_G_EXT_CTRLS:
 	{
@@ -572,20 +577,20 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		struct v4l2_ext_control *ctrl = ctrls->controls;
 		unsigned int i;
 
-	       ret = uvc_ctrl_begin(video);
-	       if (ret < 0)
+		ret = uvc_ctrl_begin(chain);
+		if (ret < 0)
 			return ret;
 
 		for (i = 0; i < ctrls->count; ++ctrl, ++i) {
-			ret = uvc_ctrl_get(video, ctrl);
+			ret = uvc_ctrl_get(chain, ctrl);
 			if (ret < 0) {
-				uvc_ctrl_rollback(video);
+				uvc_ctrl_rollback(chain);
 				ctrls->error_idx = i;
 				return ret;
 			}
 		}
 		ctrls->error_idx = 0;
-		ret = uvc_ctrl_rollback(video);
+		ret = uvc_ctrl_rollback(chain);
 		break;
 	}
 
@@ -596,14 +601,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		struct v4l2_ext_control *ctrl = ctrls->controls;
 		unsigned int i;
 
-		ret = uvc_ctrl_begin(video);
+		ret = uvc_ctrl_begin(chain);
 		if (ret < 0)
 			return ret;
 
 		for (i = 0; i < ctrls->count; ++ctrl, ++i) {
-			ret = uvc_ctrl_set(video, ctrl);
+			ret = uvc_ctrl_set(chain, ctrl);
 			if (ret < 0) {
-				uvc_ctrl_rollback(video);
+				uvc_ctrl_rollback(chain);
 				ctrls->error_idx = i;
 				return ret;
 			}
@@ -612,31 +617,31 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		ctrls->error_idx = 0;
 
 		if (cmd == VIDIOC_S_EXT_CTRLS)
-			ret = uvc_ctrl_commit(video);
+			ret = uvc_ctrl_commit(chain);
 		else
-			ret = uvc_ctrl_rollback(video);
+			ret = uvc_ctrl_rollback(chain);
 		break;
 	}
 
 	/* Get, Set & Enum input */
 	case VIDIOC_ENUMINPUT:
 	{
-		const struct uvc_entity *selector = video->selector;
+		const struct uvc_entity *selector = chain->selector;
 		struct v4l2_input *input = arg;
 		struct uvc_entity *iterm = NULL;
 		u32 index = input->index;
 		int pin = 0;
 
 		if (selector == NULL ||
-		    (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
+		    (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
 			if (index != 0)
 				return -EINVAL;
-			iterm = list_first_entry(&video->iterms,
+			iterm = list_first_entry(&chain->iterms,
 					struct uvc_entity, chain);
 			pin = iterm->id;
 		} else if (pin < selector->selector.bNrInPins) {
 			pin = selector->selector.baSourceID[index];
-			list_for_each_entry(iterm, video->iterms.next, chain) {
+			list_for_each_entry(iterm, chain->iterms.next, chain) {
 				if (iterm->id == pin)
 					break;
 			}
@@ -648,7 +653,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		memset(input, 0, sizeof *input);
 		input->index = index;
 		strlcpy(input->name, iterm->name, sizeof input->name);
-		if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA)
+		if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
 			input->type = V4L2_INPUT_TYPE_CAMERA;
 		break;
 	}
@@ -657,15 +662,15 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	{
 		u8 input;
 
-		if (video->selector == NULL ||
-		    (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
+		if (chain->selector == NULL ||
+		    (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
 			*(int *)arg = 0;
 			break;
 		}
 
-		ret = uvc_query_ctrl(video->dev, GET_CUR, video->selector->id,
-			video->dev->intfnum, SU_INPUT_SELECT_CONTROL,
-			&input, 1);
+		ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+			chain->selector->id, chain->dev->intfnum,
+			UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
 		if (ret < 0)
 			return ret;
 
@@ -680,19 +685,19 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		if ((ret = uvc_acquire_privileges(handle)) < 0)
 			return ret;
 
-		if (video->selector == NULL ||
-		    (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
+		if (chain->selector == NULL ||
+		    (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
 			if (input != 1)
 				return -EINVAL;
 			break;
 		}
 
-		if (input == 0 || input > video->selector->selector.bNrInPins)
+		if (input == 0 || input > chain->selector->selector.bNrInPins)
 			return -EINVAL;
 
-		return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id,
-			video->dev->intfnum, SU_INPUT_SELECT_CONTROL,
-			&input, 1);
+		return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
+			chain->selector->id, chain->dev->intfnum,
+			UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
 	}
 
 	/* Try, Get, Set & Enum format */
@@ -703,15 +708,15 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		enum v4l2_buf_type type = fmt->type;
 		__u32 index = fmt->index;
 
-		if (fmt->type != video->streaming->type ||
-		    fmt->index >= video->streaming->nformats)
+		if (fmt->type != stream->type ||
+		    fmt->index >= stream->nformats)
 			return -EINVAL;
 
 		memset(fmt, 0, sizeof(*fmt));
 		fmt->index = index;
 		fmt->type = type;
 
-		format = &video->streaming->format[fmt->index];
+		format = &stream->format[fmt->index];
 		fmt->flags = 0;
 		if (format->flags & UVC_FMT_FLAG_COMPRESSED)
 			fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
@@ -729,17 +734,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		if ((ret = uvc_acquire_privileges(handle)) < 0)
 			return ret;
 
-		return uvc_v4l2_try_format(video, arg, &probe, NULL, NULL);
+		return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
 	}
 
 	case VIDIOC_S_FMT:
 		if ((ret = uvc_acquire_privileges(handle)) < 0)
 			return ret;
 
-		return uvc_v4l2_set_format(video, arg);
+		return uvc_v4l2_set_format(stream, arg);
 
 	case VIDIOC_G_FMT:
-		return uvc_v4l2_get_format(video, arg);
+		return uvc_v4l2_get_format(stream, arg);
 
 	/* Frame size enumeration */
 	case VIDIOC_ENUM_FRAMESIZES:
@@ -750,10 +755,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		int i;
 
 		/* Look for the given pixel format */
-		for (i = 0; i < video->streaming->nformats; i++) {
-			if (video->streaming->format[i].fcc ==
+		for (i = 0; i < stream->nformats; i++) {
+			if (stream->format[i].fcc ==
 					fsize->pixel_format) {
-				format = &video->streaming->format[i];
+				format = &stream->format[i];
 				break;
 			}
 		}
@@ -779,10 +784,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		int i;
 
 		/* Look for the given pixel format and frame size */
-		for (i = 0; i < video->streaming->nformats; i++) {
-			if (video->streaming->format[i].fcc ==
+		for (i = 0; i < stream->nformats; i++) {
+			if (stream->format[i].fcc ==
 					fival->pixel_format) {
-				format = &video->streaming->format[i];
+				format = &stream->format[i];
 				break;
 			}
 		}
@@ -832,21 +837,21 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
 	/* Get & Set streaming parameters */
 	case VIDIOC_G_PARM:
-		return uvc_v4l2_get_streamparm(video, arg);
+		return uvc_v4l2_get_streamparm(stream, arg);
 
 	case VIDIOC_S_PARM:
 		if ((ret = uvc_acquire_privileges(handle)) < 0)
 			return ret;
 
-		return uvc_v4l2_set_streamparm(video, arg);
+		return uvc_v4l2_set_streamparm(stream, arg);
 
 	/* Cropping and scaling */
 	case VIDIOC_CROPCAP:
 	{
 		struct v4l2_cropcap *ccap = arg;
-		struct uvc_frame *frame = video->streaming->cur_frame;
+		struct uvc_frame *frame = stream->cur_frame;
 
-		if (ccap->type != video->streaming->type)
+		if (ccap->type != stream->type)
 			return -EINVAL;
 
 		ccap->bounds.left = 0;
@@ -870,16 +875,16 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	{
 		struct v4l2_requestbuffers *rb = arg;
 		unsigned int bufsize =
-			video->streaming->ctrl.dwMaxVideoFrameSize;
+			stream->ctrl.dwMaxVideoFrameSize;
 
-		if (rb->type != video->streaming->type ||
+		if (rb->type != stream->type ||
 		    rb->memory != V4L2_MEMORY_MMAP)
 			return -EINVAL;
 
 		if ((ret = uvc_acquire_privileges(handle)) < 0)
 			return ret;
 
-		ret = uvc_alloc_buffers(&video->queue, rb->count, bufsize);
+		ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize);
 		if (ret < 0)
 			return ret;
 
@@ -892,39 +897,40 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	{
 		struct v4l2_buffer *buf = arg;
 
-		if (buf->type != video->streaming->type)
+		if (buf->type != stream->type)
 			return -EINVAL;
 
 		if (!uvc_has_privileges(handle))
 			return -EBUSY;
 
-		return uvc_query_buffer(&video->queue, buf);
+		return uvc_query_buffer(&stream->queue, buf);
 	}
 
 	case VIDIOC_QBUF:
 		if (!uvc_has_privileges(handle))
 			return -EBUSY;
 
-		return uvc_queue_buffer(&video->queue, arg);
+		return uvc_queue_buffer(&stream->queue, arg);
 
 	case VIDIOC_DQBUF:
 		if (!uvc_has_privileges(handle))
 			return -EBUSY;
 
-		return uvc_dequeue_buffer(&video->queue, arg,
+		return uvc_dequeue_buffer(&stream->queue, arg,
 			file->f_flags & O_NONBLOCK);
 
 	case VIDIOC_STREAMON:
 	{
 		int *type = arg;
 
-		if (*type != video->streaming->type)
+		if (*type != stream->type)
 			return -EINVAL;
 
 		if (!uvc_has_privileges(handle))
 			return -EBUSY;
 
-		if ((ret = uvc_video_enable(video, 1)) < 0)
+		ret = uvc_video_enable(stream, 1);
+		if (ret < 0)
 			return ret;
 		break;
 	}
@@ -933,13 +939,13 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	{
 		int *type = arg;
 
-		if (*type != video->streaming->type)
+		if (*type != stream->type)
 			return -EINVAL;
 
 		if (!uvc_has_privileges(handle))
 			return -EBUSY;
 
-		return uvc_video_enable(video, 0);
+		return uvc_video_enable(stream, 0);
 	}
 
 	/* Analog video standards make no sense for digital cameras. */
@@ -1013,10 +1019,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 	}
 
 	case UVCIOC_CTRL_GET:
-		return uvc_xu_ctrl_query(video, arg, 0);
+		return uvc_xu_ctrl_query(chain, arg, 0);
 
 	case UVCIOC_CTRL_SET:
-		return uvc_xu_ctrl_query(video, arg, 1);
+		return uvc_xu_ctrl_query(chain, arg, 1);
 
 	default:
 		if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
@@ -1070,7 +1076,9 @@ static struct vm_operations_struct uvc_vm_ops = {
 
 static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	struct uvc_video_device *video = video_drvdata(file);
+	struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
+	struct uvc_streaming *stream = handle->stream;
+	struct uvc_video_queue *queue = &stream->queue;
 	struct uvc_buffer *uninitialized_var(buffer);
 	struct page *page;
 	unsigned long addr, start, size;
@@ -1082,15 +1090,15 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 	start = vma->vm_start;
 	size = vma->vm_end - vma->vm_start;
 
-	mutex_lock(&video->queue.mutex);
+	mutex_lock(&queue->mutex);
 
-	for (i = 0; i < video->queue.count; ++i) {
-		buffer = &video->queue.buffer[i];
+	for (i = 0; i < queue->count; ++i) {
+		buffer = &queue->buffer[i];
 		if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
 			break;
 	}
 
-	if (i == video->queue.count || size != video->queue.buf_size) {
+	if (i == queue->count || size != queue->buf_size) {
 		ret = -EINVAL;
 		goto done;
 	}
@@ -1101,7 +1109,7 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 	 */
 	vma->vm_flags |= VM_IO;
 
-	addr = (unsigned long)video->queue.mem + buffer->buf.m.offset;
+	addr = (unsigned long)queue->mem + buffer->buf.m.offset;
 	while (size > 0) {
 		page = vmalloc_to_page((void *)addr);
 		if ((ret = vm_insert_page(vma, start, page)) < 0)
@@ -1117,17 +1125,18 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
 	uvc_vm_open(vma);
 
 done:
-	mutex_unlock(&video->queue.mutex);
+	mutex_unlock(&queue->mutex);
 	return ret;
 }
 
 static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
 {
-	struct uvc_video_device *video = video_drvdata(file);
+	struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
+	struct uvc_streaming *stream = handle->stream;
 
 	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
 
-	return uvc_queue_poll(&video->queue, file, wait);
+	return uvc_queue_poll(&stream->queue, file, wait);
 }
 
 const struct v4l2_file_operations uvc_fops = {
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 01b633c..f960e8e 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
 	return 0;
 }
 
-static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
+static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
 	struct uvc_streaming_control *ctrl)
 {
 	struct uvc_format *format;
@@ -69,10 +69,10 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
 	unsigned int i;
 
 	if (ctrl->bFormatIndex <= 0 ||
-	    ctrl->bFormatIndex > video->streaming->nformats)
+	    ctrl->bFormatIndex > stream->nformats)
 		return;
 
-	format = &video->streaming->format[ctrl->bFormatIndex - 1];
+	format = &stream->format[ctrl->bFormatIndex - 1];
 
 	for (i = 0; i < format->nframes; ++i) {
 		if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
@@ -86,12 +86,12 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
 
 	if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
 	     (ctrl->dwMaxVideoFrameSize == 0 &&
-	      video->dev->uvc_version < 0x0110))
+	      stream->dev->uvc_version < 0x0110))
 		ctrl->dwMaxVideoFrameSize =
 			frame->dwMaxVideoFrameBufferSize;
 
-	if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
-	    video->streaming->intf->num_altsetting > 1) {
+	if (stream->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
+	    stream->intf->num_altsetting > 1) {
 		u32 interval;
 		u32 bandwidth;
 
@@ -108,7 +108,7 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
 		bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
 		bandwidth *= 10000000 / interval + 1;
 		bandwidth /= 1000;
-		if (video->dev->udev->speed == USB_SPEED_HIGH)
+		if (stream->dev->udev->speed == USB_SPEED_HIGH)
 			bandwidth /= 8;
 		bandwidth += 12;
 
@@ -116,40 +116,44 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
 	}
 }
 
-static int uvc_get_video_ctrl(struct uvc_video_device *video,
+static int uvc_get_video_ctrl(struct uvc_streaming *stream,
 	struct uvc_streaming_control *ctrl, int probe, __u8 query)
 {
 	__u8 *data;
 	__u16 size;
 	int ret;
 
-	size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
+	size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
+	if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
+			query == UVC_GET_DEF)
+		return -EIO;
+
 	data = kmalloc(size, GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 
-	ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
-		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
-		UVC_CTRL_STREAMING_TIMEOUT);
+	ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
+		probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
+		size, UVC_CTRL_STREAMING_TIMEOUT);
 
-	if ((query == GET_MIN || query == GET_MAX) && ret == 2) {
+	if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) {
 		/* Some cameras, mostly based on Bison Electronics chipsets,
 		 * answer a GET_MIN or GET_MAX request with the wCompQuality
 		 * field only.
 		 */
-		uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non "
+		uvc_warn_once(stream->dev, UVC_WARN_MINMAX, "UVC non "
 			"compliance - GET_MIN/MAX(PROBE) incorrectly "
 			"supported. Enabling workaround.\n");
 		memset(ctrl, 0, sizeof ctrl);
 		ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
 		ret = 0;
 		goto out;
-	} else if (query == GET_DEF && probe == 1 && ret != size) {
+	} else if (query == UVC_GET_DEF && probe == 1 && ret != size) {
 		/* Many cameras don't support the GET_DEF request on their
 		 * video probe control. Warn once and return, the caller will
 		 * fall back to GET_CUR.
 		 */
-		uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non "
+		uvc_warn_once(stream->dev, UVC_WARN_PROBE_DEF, "UVC non "
 			"compliance - GET_DEF(PROBE) not supported. "
 			"Enabling workaround.\n");
 		ret = -EIO;
@@ -181,7 +185,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
 		ctrl->bMinVersion = data[32];
 		ctrl->bMaxVersion = data[33];
 	} else {
-		ctrl->dwClockFrequency = video->dev->clock_frequency;
+		ctrl->dwClockFrequency = stream->dev->clock_frequency;
 		ctrl->bmFramingInfo = 0;
 		ctrl->bPreferedVersion = 0;
 		ctrl->bMinVersion = 0;
@@ -192,7 +196,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
 	 * dwMaxPayloadTransferSize fields. Try to get the value from the
 	 * format and frame descriptors.
 	 */
-	uvc_fixup_video_ctrl(video, ctrl);
+	uvc_fixup_video_ctrl(stream, ctrl);
 	ret = 0;
 
 out:
@@ -200,14 +204,14 @@ out:
 	return ret;
 }
 
-static int uvc_set_video_ctrl(struct uvc_video_device *video,
+static int uvc_set_video_ctrl(struct uvc_streaming *stream,
 	struct uvc_streaming_control *ctrl, int probe)
 {
 	__u8 *data;
 	__u16 size;
 	int ret;
 
-	size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
+	size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
 	data = kzalloc(size, GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
@@ -232,10 +236,9 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
 		data[33] = ctrl->bMaxVersion;
 	}
 
-	ret = __uvc_query_ctrl(video->dev, SET_CUR, 0,
-		video->streaming->intfnum,
-		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
-		UVC_CTRL_STREAMING_TIMEOUT);
+	ret = __uvc_query_ctrl(stream->dev, UVC_SET_CUR, 0, stream->intfnum,
+		probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
+		size, UVC_CTRL_STREAMING_TIMEOUT);
 	if (ret != size) {
 		uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
 			"%d (exp. %u).\n", probe ? "probe" : "commit",
@@ -247,7 +250,7 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video,
 	return ret;
 }
 
-int uvc_probe_video(struct uvc_video_device *video,
+int uvc_probe_video(struct uvc_streaming *stream,
 	struct uvc_streaming_control *probe)
 {
 	struct uvc_streaming_control probe_min, probe_max;
@@ -255,7 +258,7 @@ int uvc_probe_video(struct uvc_video_device *video,
 	unsigned int i;
 	int ret;
 
-	mutex_lock(&video->streaming->mutex);
+	mutex_lock(&stream->mutex);
 
 	/* Perform probing. The device should adjust the requested values
 	 * according to its capabilities. However, some devices, namely the
@@ -264,15 +267,16 @@ int uvc_probe_video(struct uvc_video_device *video,
 	 * that reason, if the needed bandwidth exceeds the maximum available
 	 * bandwidth, try to lower the quality.
 	 */
-	if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0)
+	ret = uvc_set_video_ctrl(stream, probe, 1);
+	if (ret < 0)
 		goto done;
 
 	/* Get the minimum and maximum values for compression settings. */
-	if (!(video->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) {
-		ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN);
+	if (!(stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) {
+		ret = uvc_get_video_ctrl(stream, &probe_min, 1, UVC_GET_MIN);
 		if (ret < 0)
 			goto done;
-		ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX);
+		ret = uvc_get_video_ctrl(stream, &probe_max, 1, UVC_GET_MAX);
 		if (ret < 0)
 			goto done;
 
@@ -280,18 +284,21 @@ int uvc_probe_video(struct uvc_video_device *video,
 	}
 
 	for (i = 0; i < 2; ++i) {
-		if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0 ||
-		    (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+		ret = uvc_set_video_ctrl(stream, probe, 1);
+		if (ret < 0)
+			goto done;
+		ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR);
+		if (ret < 0)
 			goto done;
 
-		if (video->streaming->intf->num_altsetting == 1)
+		if (stream->intf->num_altsetting == 1)
 			break;
 
 		bandwidth = probe->dwMaxPayloadTransferSize;
-		if (bandwidth <= video->streaming->maxpsize)
+		if (bandwidth <= stream->maxpsize)
 			break;
 
-		if (video->dev->quirks & UVC_QUIRK_PROBE_MINMAX) {
+		if (stream->dev->quirks & UVC_QUIRK_PROBE_MINMAX) {
 			ret = -ENOSPC;
 			goto done;
 		}
@@ -304,14 +311,14 @@ int uvc_probe_video(struct uvc_video_device *video,
 	}
 
 done:
-	mutex_unlock(&video->streaming->mutex);
+	mutex_unlock(&stream->mutex);
 	return ret;
 }
 
-int uvc_commit_video(struct uvc_video_device *video,
+int uvc_commit_video(struct uvc_streaming *stream,
 	struct uvc_streaming_control *probe)
 {
-	return uvc_set_video_ctrl(video, probe, 0);
+	return uvc_set_video_ctrl(stream, probe, 0);
 }
 
 /* ------------------------------------------------------------------------
@@ -363,7 +370,7 @@ int uvc_commit_video(struct uvc_video_device *video,
  * to be called with a NULL buf parameter. uvc_video_decode_data and
  * uvc_video_decode_end will never be called with a NULL buffer.
  */
-static int uvc_video_decode_start(struct uvc_video_device *video,
+static int uvc_video_decode_start(struct uvc_streaming *stream,
 		struct uvc_buffer *buf, const __u8 *data, int len)
 {
 	__u8 fid;
@@ -389,25 +396,25 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
 	 * NULL.
 	 */
 	if (buf == NULL) {
-		video->last_fid = fid;
+		stream->last_fid = fid;
 		return -ENODATA;
 	}
 
 	/* Synchronize to the input stream by waiting for the FID bit to be
 	 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
-	 * video->last_fid is initialized to -1, so the first isochronous
+	 * stream->last_fid is initialized to -1, so the first isochronous
 	 * frame will always be in sync.
 	 *
-	 * If the device doesn't toggle the FID bit, invert video->last_fid
+	 * If the device doesn't toggle the FID bit, invert stream->last_fid
 	 * when the EOF bit is set to force synchronisation on the next packet.
 	 */
 	if (buf->state != UVC_BUF_STATE_ACTIVE) {
-		if (fid == video->last_fid) {
+		if (fid == stream->last_fid) {
 			uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
 				"sync).\n");
-			if ((video->dev->quirks & UVC_QUIRK_STREAM_NO_FID) &&
+			if ((stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID) &&
 			    (data[1] & UVC_STREAM_EOF))
-				video->last_fid ^= UVC_STREAM_FID;
+				stream->last_fid ^= UVC_STREAM_FID;
 			return -ENODATA;
 		}
 
@@ -422,7 +429,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
 	 * last payload can be lost anyway). We thus must check if the FID has
 	 * been toggled.
 	 *
-	 * video->last_fid is initialized to -1, so the first isochronous
+	 * stream->last_fid is initialized to -1, so the first isochronous
 	 * frame will never trigger an end of frame detection.
 	 *
 	 * Empty buffers (bytesused == 0) don't trigger end of frame detection
@@ -430,22 +437,22 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
 	 * avoids detecting end of frame conditions at FID toggling if the
 	 * previous payload had the EOF bit set.
 	 */
-	if (fid != video->last_fid && buf->buf.bytesused != 0) {
+	if (fid != stream->last_fid && buf->buf.bytesused != 0) {
 		uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
 				"toggled).\n");
 		buf->state = UVC_BUF_STATE_DONE;
 		return -EAGAIN;
 	}
 
-	video->last_fid = fid;
+	stream->last_fid = fid;
 
 	return data[0];
 }
 
-static void uvc_video_decode_data(struct uvc_video_device *video,
+static void uvc_video_decode_data(struct uvc_streaming *stream,
 		struct uvc_buffer *buf, const __u8 *data, int len)
 {
-	struct uvc_video_queue *queue = &video->queue;
+	struct uvc_video_queue *queue = &stream->queue;
 	unsigned int maxlen, nbytes;
 	void *mem;
 
@@ -466,7 +473,7 @@ static void uvc_video_decode_data(struct uvc_video_device *video,
 	}
 }
 
-static void uvc_video_decode_end(struct uvc_video_device *video,
+static void uvc_video_decode_end(struct uvc_streaming *stream,
 		struct uvc_buffer *buf, const __u8 *data, int len)
 {
 	/* Mark the buffer as done if the EOF marker is set. */
@@ -475,8 +482,8 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
 		if (data[0] == len)
 			uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n");
 		buf->state = UVC_BUF_STATE_DONE;
-		if (video->dev->quirks & UVC_QUIRK_STREAM_NO_FID)
-			video->last_fid ^= UVC_STREAM_FID;
+		if (stream->dev->quirks & UVC_QUIRK_STREAM_NO_FID)
+			stream->last_fid ^= UVC_STREAM_FID;
 	}
 }
 
@@ -491,26 +498,26 @@ static void uvc_video_decode_end(struct uvc_video_device *video,
  * uvc_video_encode_data is called for every URB and copies the data from the
  * video buffer to the transfer buffer.
  */
-static int uvc_video_encode_header(struct uvc_video_device *video,
+static int uvc_video_encode_header(struct uvc_streaming *stream,
 		struct uvc_buffer *buf, __u8 *data, int len)
 {
 	data[0] = 2;	/* Header length */
 	data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF
-		| (video->last_fid & UVC_STREAM_FID);
+		| (stream->last_fid & UVC_STREAM_FID);
 	return 2;
 }
 
-static int uvc_video_encode_data(struct uvc_video_device *video,
+static int uvc_video_encode_data(struct uvc_streaming *stream,
 		struct uvc_buffer *buf, __u8 *data, int len)
 {
-	struct uvc_video_queue *queue = &video->queue;
+	struct uvc_video_queue *queue = &stream->queue;
 	unsigned int nbytes;
 	void *mem;
 
 	/* Copy video data to the URB buffer. */
 	mem = queue->mem + buf->buf.m.offset + queue->buf_used;
 	nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used);
-	nbytes = min(video->bulk.max_payload_size - video->bulk.payload_size,
+	nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size,
 			nbytes);
 	memcpy(data, mem, nbytes);
 
@@ -526,8 +533,8 @@ static int uvc_video_encode_data(struct uvc_video_device *video,
 /*
  * Completion handler for video URBs.
  */
-static void uvc_video_decode_isoc(struct urb *urb,
-	struct uvc_video_device *video, struct uvc_buffer *buf)
+static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
+	struct uvc_buffer *buf)
 {
 	u8 *mem;
 	int ret, i;
@@ -542,31 +549,32 @@ static void uvc_video_decode_isoc(struct urb *urb,
 		/* Decode the payload header. */
 		mem = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 		do {
-			ret = uvc_video_decode_start(video, buf, mem,
+			ret = uvc_video_decode_start(stream, buf, mem,
 				urb->iso_frame_desc[i].actual_length);
 			if (ret == -EAGAIN)
-				buf = uvc_queue_next_buffer(&video->queue, buf);
+				buf = uvc_queue_next_buffer(&stream->queue,
+							    buf);
 		} while (ret == -EAGAIN);
 
 		if (ret < 0)
 			continue;
 
 		/* Decode the payload data. */
-		uvc_video_decode_data(video, buf, mem + ret,
+		uvc_video_decode_data(stream, buf, mem + ret,
 			urb->iso_frame_desc[i].actual_length - ret);
 
 		/* Process the header again. */
-		uvc_video_decode_end(video, buf, mem,
+		uvc_video_decode_end(stream, buf, mem,
 			urb->iso_frame_desc[i].actual_length);
 
 		if (buf->state == UVC_BUF_STATE_DONE ||
 		    buf->state == UVC_BUF_STATE_ERROR)
-			buf = uvc_queue_next_buffer(&video->queue, buf);
+			buf = uvc_queue_next_buffer(&stream->queue, buf);
 	}
 }
 
-static void uvc_video_decode_bulk(struct urb *urb,
-	struct uvc_video_device *video, struct uvc_buffer *buf)
+static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
+	struct uvc_buffer *buf)
 {
 	u8 *mem;
 	int len, ret;
@@ -576,24 +584,25 @@ static void uvc_video_decode_bulk(struct urb *urb,
 
 	mem = urb->transfer_buffer;
 	len = urb->actual_length;
-	video->bulk.payload_size += len;
+	stream->bulk.payload_size += len;
 
 	/* If the URB is the first of its payload, decode and save the
 	 * header.
 	 */
-	if (video->bulk.header_size == 0 && !video->bulk.skip_payload) {
+	if (stream->bulk.header_size == 0 && !stream->bulk.skip_payload) {
 		do {
-			ret = uvc_video_decode_start(video, buf, mem, len);
+			ret = uvc_video_decode_start(stream, buf, mem, len);
 			if (ret == -EAGAIN)
-				buf = uvc_queue_next_buffer(&video->queue, buf);
+				buf = uvc_queue_next_buffer(&stream->queue,
+							    buf);
 		} while (ret == -EAGAIN);
 
 		/* If an error occured skip the rest of the payload. */
 		if (ret < 0 || buf == NULL) {
-			video->bulk.skip_payload = 1;
+			stream->bulk.skip_payload = 1;
 		} else {
-			memcpy(video->bulk.header, mem, ret);
-			video->bulk.header_size = ret;
+			memcpy(stream->bulk.header, mem, ret);
+			stream->bulk.header_size = ret;
 
 			mem += ret;
 			len -= ret;
@@ -606,33 +615,34 @@ static void uvc_video_decode_bulk(struct urb *urb,
 	 */
 
 	/* Process video data. */
-	if (!video->bulk.skip_payload && buf != NULL)
-		uvc_video_decode_data(video, buf, mem, len);
+	if (!stream->bulk.skip_payload && buf != NULL)
+		uvc_video_decode_data(stream, buf, mem, len);
 
 	/* Detect the payload end by a URB smaller than the maximum size (or
 	 * a payload size equal to the maximum) and process the header again.
 	 */
 	if (urb->actual_length < urb->transfer_buffer_length ||
-	    video->bulk.payload_size >= video->bulk.max_payload_size) {
-		if (!video->bulk.skip_payload && buf != NULL) {
-			uvc_video_decode_end(video, buf, video->bulk.header,
-				video->bulk.payload_size);
+	    stream->bulk.payload_size >= stream->bulk.max_payload_size) {
+		if (!stream->bulk.skip_payload && buf != NULL) {
+			uvc_video_decode_end(stream, buf, stream->bulk.header,
+				stream->bulk.payload_size);
 			if (buf->state == UVC_BUF_STATE_DONE ||
 			    buf->state == UVC_BUF_STATE_ERROR)
-				buf = uvc_queue_next_buffer(&video->queue, buf);
+				buf = uvc_queue_next_buffer(&stream->queue,
+							    buf);
 		}
 
-		video->bulk.header_size = 0;
-		video->bulk.skip_payload = 0;
-		video->bulk.payload_size = 0;
+		stream->bulk.header_size = 0;
+		stream->bulk.skip_payload = 0;
+		stream->bulk.payload_size = 0;
 	}
 }
 
-static void uvc_video_encode_bulk(struct urb *urb,
-	struct uvc_video_device *video, struct uvc_buffer *buf)
+static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
+	struct uvc_buffer *buf)
 {
 	u8 *mem = urb->transfer_buffer;
-	int len = video->urb_size, ret;
+	int len = stream->urb_size, ret;
 
 	if (buf == NULL) {
 		urb->transfer_buffer_length = 0;
@@ -640,40 +650,40 @@ static void uvc_video_encode_bulk(struct urb *urb,
 	}
 
 	/* If the URB is the first of its payload, add the header. */
-	if (video->bulk.header_size == 0) {
-		ret = uvc_video_encode_header(video, buf, mem, len);
-		video->bulk.header_size = ret;
-		video->bulk.payload_size += ret;
+	if (stream->bulk.header_size == 0) {
+		ret = uvc_video_encode_header(stream, buf, mem, len);
+		stream->bulk.header_size = ret;
+		stream->bulk.payload_size += ret;
 		mem += ret;
 		len -= ret;
 	}
 
 	/* Process video data. */
-	ret = uvc_video_encode_data(video, buf, mem, len);
+	ret = uvc_video_encode_data(stream, buf, mem, len);
 
-	video->bulk.payload_size += ret;
+	stream->bulk.payload_size += ret;
 	len -= ret;
 
-	if (buf->buf.bytesused == video->queue.buf_used ||
-	    video->bulk.payload_size == video->bulk.max_payload_size) {
-		if (buf->buf.bytesused == video->queue.buf_used) {
-			video->queue.buf_used = 0;
+	if (buf->buf.bytesused == stream->queue.buf_used ||
+	    stream->bulk.payload_size == stream->bulk.max_payload_size) {
+		if (buf->buf.bytesused == stream->queue.buf_used) {
+			stream->queue.buf_used = 0;
 			buf->state = UVC_BUF_STATE_DONE;
-			uvc_queue_next_buffer(&video->queue, buf);
-			video->last_fid ^= UVC_STREAM_FID;
+			uvc_queue_next_buffer(&stream->queue, buf);
+			stream->last_fid ^= UVC_STREAM_FID;
 		}
 
-		video->bulk.header_size = 0;
-		video->bulk.payload_size = 0;
+		stream->bulk.header_size = 0;
+		stream->bulk.payload_size = 0;
 	}
 
-	urb->transfer_buffer_length = video->urb_size - len;
+	urb->transfer_buffer_length = stream->urb_size - len;
 }
 
 static void uvc_video_complete(struct urb *urb)
 {
-	struct uvc_video_device *video = urb->context;
-	struct uvc_video_queue *queue = &video->queue;
+	struct uvc_streaming *stream = urb->context;
+	struct uvc_video_queue *queue = &stream->queue;
 	struct uvc_buffer *buf = NULL;
 	unsigned long flags;
 	int ret;
@@ -687,7 +697,7 @@ static void uvc_video_complete(struct urb *urb)
 			"completion handler.\n", urb->status);
 
 	case -ENOENT:		/* usb_kill_urb() called. */
-		if (video->frozen)
+		if (stream->frozen)
 			return;
 
 	case -ECONNRESET:	/* usb_unlink_urb() called. */
@@ -702,7 +712,7 @@ static void uvc_video_complete(struct urb *urb)
 				       queue);
 	spin_unlock_irqrestore(&queue->irqlock, flags);
 
-	video->decode(urb, video, buf);
+	stream->decode(urb, stream, buf);
 
 	if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
 		uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
@@ -713,19 +723,19 @@ static void uvc_video_complete(struct urb *urb)
 /*
  * Free transfer buffers.
  */
-static void uvc_free_urb_buffers(struct uvc_video_device *video)
+static void uvc_free_urb_buffers(struct uvc_streaming *stream)
 {
 	unsigned int i;
 
 	for (i = 0; i < UVC_URBS; ++i) {
-		if (video->urb_buffer[i]) {
-			usb_buffer_free(video->dev->udev, video->urb_size,
-				video->urb_buffer[i], video->urb_dma[i]);
-			video->urb_buffer[i] = NULL;
+		if (stream->urb_buffer[i]) {
+			usb_buffer_free(stream->dev->udev, stream->urb_size,
+				stream->urb_buffer[i], stream->urb_dma[i]);
+			stream->urb_buffer[i] = NULL;
 		}
 	}
 
-	video->urb_size = 0;
+	stream->urb_size = 0;
 }
 
 /*
@@ -739,15 +749,15 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video)
  *
  * Return the number of allocated packets on success or 0 when out of memory.
  */
-static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
+static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
 	unsigned int size, unsigned int psize, gfp_t gfp_flags)
 {
 	unsigned int npackets;
 	unsigned int i;
 
 	/* Buffers are already allocated, bail out. */
-	if (video->urb_size)
-		return video->urb_size / psize;
+	if (stream->urb_size)
+		return stream->urb_size / psize;
 
 	/* Compute the number of packets. Bulk endpoints might transfer UVC
 	 * payloads accross multiple URBs.
@@ -759,17 +769,17 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
 	/* Retry allocations until one succeed. */
 	for (; npackets > 1; npackets /= 2) {
 		for (i = 0; i < UVC_URBS; ++i) {
-			video->urb_buffer[i] = usb_buffer_alloc(
-				video->dev->udev, psize * npackets,
-				gfp_flags | __GFP_NOWARN, &video->urb_dma[i]);
-			if (!video->urb_buffer[i]) {
-				uvc_free_urb_buffers(video);
+			stream->urb_buffer[i] = usb_buffer_alloc(
+				stream->dev->udev, psize * npackets,
+				gfp_flags | __GFP_NOWARN, &stream->urb_dma[i]);
+			if (!stream->urb_buffer[i]) {
+				uvc_free_urb_buffers(stream);
 				break;
 			}
 		}
 
 		if (i == UVC_URBS) {
-			video->urb_size = psize * npackets;
+			stream->urb_size = psize * npackets;
 			return npackets;
 		}
 	}
@@ -780,29 +790,30 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
 /*
  * Uninitialize isochronous/bulk URBs and free transfer buffers.
  */
-static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers)
+static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers)
 {
 	struct urb *urb;
 	unsigned int i;
 
 	for (i = 0; i < UVC_URBS; ++i) {
-		if ((urb = video->urb[i]) == NULL)
+		urb = stream->urb[i];
+		if (urb == NULL)
 			continue;
 
 		usb_kill_urb(urb);
 		usb_free_urb(urb);
-		video->urb[i] = NULL;
+		stream->urb[i] = NULL;
 	}
 
 	if (free_buffers)
-		uvc_free_urb_buffers(video);
+		uvc_free_urb_buffers(stream);
 }
 
 /*
  * Initialize isochronous URBs and allocate transfer buffers. The packet size
  * is given by the endpoint.
  */
-static int uvc_init_video_isoc(struct uvc_video_device *video,
+static int uvc_init_video_isoc(struct uvc_streaming *stream,
 	struct usb_host_endpoint *ep, gfp_t gfp_flags)
 {
 	struct urb *urb;
@@ -812,9 +823,9 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
 
 	psize = le16_to_cpu(ep->desc.wMaxPacketSize);
 	psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-	size = video->streaming->ctrl.dwMaxVideoFrameSize;
+	size = stream->ctrl.dwMaxVideoFrameSize;
 
-	npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+	npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
 	if (npackets == 0)
 		return -ENOMEM;
 
@@ -823,18 +834,18 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
 	for (i = 0; i < UVC_URBS; ++i) {
 		urb = usb_alloc_urb(npackets, gfp_flags);
 		if (urb == NULL) {
-			uvc_uninit_video(video, 1);
+			uvc_uninit_video(stream, 1);
 			return -ENOMEM;
 		}
 
-		urb->dev = video->dev->udev;
-		urb->context = video;
-		urb->pipe = usb_rcvisocpipe(video->dev->udev,
+		urb->dev = stream->dev->udev;
+		urb->context = stream;
+		urb->pipe = usb_rcvisocpipe(stream->dev->udev,
 				ep->desc.bEndpointAddress);
 		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 		urb->interval = ep->desc.bInterval;
-		urb->transfer_buffer = video->urb_buffer[i];
-		urb->transfer_dma = video->urb_dma[i];
+		urb->transfer_buffer = stream->urb_buffer[i];
+		urb->transfer_dma = stream->urb_dma[i];
 		urb->complete = uvc_video_complete;
 		urb->number_of_packets = npackets;
 		urb->transfer_buffer_length = size;
@@ -844,7 +855,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
 			urb->iso_frame_desc[j].length = psize;
 		}
 
-		video->urb[i] = urb;
+		stream->urb[i] = urb;
 	}
 
 	return 0;
@@ -854,7 +865,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
  * Initialize bulk URBs and allocate transfer buffers. The packet size is
  * given by the endpoint.
  */
-static int uvc_init_video_bulk(struct uvc_video_device *video,
+static int uvc_init_video_bulk(struct uvc_streaming *stream,
 	struct usb_host_endpoint *ep, gfp_t gfp_flags)
 {
 	struct urb *urb;
@@ -863,39 +874,39 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
 	u32 size;
 
 	psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
-	size = video->streaming->ctrl.dwMaxPayloadTransferSize;
-	video->bulk.max_payload_size = size;
+	size = stream->ctrl.dwMaxPayloadTransferSize;
+	stream->bulk.max_payload_size = size;
 
-	npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+	npackets = uvc_alloc_urb_buffers(stream, size, psize, gfp_flags);
 	if (npackets == 0)
 		return -ENOMEM;
 
 	size = npackets * psize;
 
 	if (usb_endpoint_dir_in(&ep->desc))
-		pipe = usb_rcvbulkpipe(video->dev->udev,
+		pipe = usb_rcvbulkpipe(stream->dev->udev,
 				       ep->desc.bEndpointAddress);
 	else
-		pipe = usb_sndbulkpipe(video->dev->udev,
+		pipe = usb_sndbulkpipe(stream->dev->udev,
 				       ep->desc.bEndpointAddress);
 
-	if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+	if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
 		size = 0;
 
 	for (i = 0; i < UVC_URBS; ++i) {
 		urb = usb_alloc_urb(0, gfp_flags);
 		if (urb == NULL) {
-			uvc_uninit_video(video, 1);
+			uvc_uninit_video(stream, 1);
 			return -ENOMEM;
 		}
 
-		usb_fill_bulk_urb(urb, video->dev->udev, pipe,
-			video->urb_buffer[i], size, uvc_video_complete,
-			video);
+		usb_fill_bulk_urb(urb, stream->dev->udev, pipe,
+			stream->urb_buffer[i], size, uvc_video_complete,
+			stream);
 		urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
-		urb->transfer_dma = video->urb_dma[i];
+		urb->transfer_dma = stream->urb_dma[i];
 
-		video->urb[i] = urb;
+		stream->urb[i] = urb;
 	}
 
 	return 0;
@@ -904,35 +915,35 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
 /*
  * Initialize isochronous/bulk URBs and allocate transfer buffers.
  */
-static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
+static int uvc_init_video(struct uvc_streaming *stream, gfp_t gfp_flags)
 {
-	struct usb_interface *intf = video->streaming->intf;
+	struct usb_interface *intf = stream->intf;
 	struct usb_host_interface *alts;
 	struct usb_host_endpoint *ep = NULL;
-	int intfnum = video->streaming->intfnum;
+	int intfnum = stream->intfnum;
 	unsigned int bandwidth, psize, i;
 	int ret;
 
-	video->last_fid = -1;
-	video->bulk.header_size = 0;
-	video->bulk.skip_payload = 0;
-	video->bulk.payload_size = 0;
+	stream->last_fid = -1;
+	stream->bulk.header_size = 0;
+	stream->bulk.skip_payload = 0;
+	stream->bulk.payload_size = 0;
 
 	if (intf->num_altsetting > 1) {
 		/* Isochronous endpoint, select the alternate setting. */
-		bandwidth = video->streaming->ctrl.dwMaxPayloadTransferSize;
+		bandwidth = stream->ctrl.dwMaxPayloadTransferSize;
 
 		if (bandwidth == 0) {
 			uvc_printk(KERN_WARNING, "device %s requested null "
 				"bandwidth, defaulting to lowest.\n",
-				video->vdev->name);
+				stream->dev->name);
 			bandwidth = 1;
 		}
 
 		for (i = 0; i < intf->num_altsetting; ++i) {
 			alts = &intf->altsetting[i];
 			ep = uvc_find_endpoint(alts,
-				video->streaming->header.bEndpointAddress);
+				stream->header.bEndpointAddress);
 			if (ep == NULL)
 				continue;
 
@@ -946,18 +957,19 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
 		if (i >= intf->num_altsetting)
 			return -EIO;
 
-		if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0)
+		ret = usb_set_interface(stream->dev->udev, intfnum, i);
+		if (ret < 0)
 			return ret;
 
-		ret = uvc_init_video_isoc(video, ep, gfp_flags);
+		ret = uvc_init_video_isoc(stream, ep, gfp_flags);
 	} else {
 		/* Bulk endpoint, proceed to URB initialization. */
 		ep = uvc_find_endpoint(&intf->altsetting[0],
-				video->streaming->header.bEndpointAddress);
+				stream->header.bEndpointAddress);
 		if (ep == NULL)
 			return -EIO;
 
-		ret = uvc_init_video_bulk(video, ep, gfp_flags);
+		ret = uvc_init_video_bulk(stream, ep, gfp_flags);
 	}
 
 	if (ret < 0)
@@ -965,10 +977,11 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
 
 	/* Submit the URBs. */
 	for (i = 0; i < UVC_URBS; ++i) {
-		if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) {
+		ret = usb_submit_urb(stream->urb[i], gfp_flags);
+		if (ret < 0) {
 			uvc_printk(KERN_ERR, "Failed to submit URB %u "
 					"(%d).\n", i, ret);
-			uvc_uninit_video(video, 1);
+			uvc_uninit_video(stream, 1);
 			return ret;
 		}
 	}
@@ -987,14 +1000,14 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags)
  * video buffers in any way. We mark the device as frozen to make sure the URB
  * completion handler won't try to cancel the queue when we kill the URBs.
  */
-int uvc_video_suspend(struct uvc_video_device *video)
+int uvc_video_suspend(struct uvc_streaming *stream)
 {
-	if (!uvc_queue_streaming(&video->queue))
+	if (!uvc_queue_streaming(&stream->queue))
 		return 0;
 
-	video->frozen = 1;
-	uvc_uninit_video(video, 0);
-	usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
+	stream->frozen = 1;
+	uvc_uninit_video(stream, 0);
+	usb_set_interface(stream->dev->udev, stream->intfnum, 0);
 	return 0;
 }
 
@@ -1006,22 +1019,24 @@ int uvc_video_suspend(struct uvc_video_device *video)
  * buffers, making sure userspace applications are notified of the problem
  * instead of waiting forever.
  */
-int uvc_video_resume(struct uvc_video_device *video)
+int uvc_video_resume(struct uvc_streaming *stream)
 {
 	int ret;
 
-	video->frozen = 0;
+	stream->frozen = 0;
 
-	if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) {
-		uvc_queue_enable(&video->queue, 0);
+	ret = uvc_commit_video(stream, &stream->ctrl);
+	if (ret < 0) {
+		uvc_queue_enable(&stream->queue, 0);
 		return ret;
 	}
 
-	if (!uvc_queue_streaming(&video->queue))
+	if (!uvc_queue_streaming(&stream->queue))
 		return 0;
 
-	if ((ret = uvc_init_video(video, GFP_NOIO)) < 0)
-		uvc_queue_enable(&video->queue, 0);
+	ret = uvc_init_video(stream, GFP_NOIO);
+	if (ret < 0)
+		uvc_queue_enable(&stream->queue, 0);
 
 	return ret;
 }
@@ -1040,47 +1055,53 @@ int uvc_video_resume(struct uvc_video_device *video)
  *
  * This function is called before registering the device with V4L.
  */
-int uvc_video_init(struct uvc_video_device *video)
+int uvc_video_init(struct uvc_streaming *stream)
 {
-	struct uvc_streaming_control *probe = &video->streaming->ctrl;
+	struct uvc_streaming_control *probe = &stream->ctrl;
 	struct uvc_format *format = NULL;
 	struct uvc_frame *frame = NULL;
 	unsigned int i;
 	int ret;
 
-	if (video->streaming->nformats == 0) {
+	if (stream->nformats == 0) {
 		uvc_printk(KERN_INFO, "No supported video formats found.\n");
 		return -EINVAL;
 	}
 
+	atomic_set(&stream->active, 0);
+
+	/* Initialize the video buffers queue. */
+	uvc_queue_init(&stream->queue, stream->type);
+
 	/* Alternate setting 0 should be the default, yet the XBox Live Vision
 	 * Cam (and possibly other devices) crash or otherwise misbehave if
 	 * they don't receive a SET_INTERFACE request before any other video
 	 * control request.
 	 */
-	usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
+	usb_set_interface(stream->dev->udev, stream->intfnum, 0);
 
 	/* Set the streaming probe control with default streaming parameters
 	 * retrieved from the device. Webcams that don't suport GET_DEF
 	 * requests on the probe control will just keep their current streaming
 	 * parameters.
 	 */
-	if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0)
-		uvc_set_video_ctrl(video, probe, 1);
+	if (uvc_get_video_ctrl(stream, probe, 1, UVC_GET_DEF) == 0)
+		uvc_set_video_ctrl(stream, probe, 1);
 
 	/* Initialize the streaming parameters with the probe control current
 	 * value. This makes sure SET_CUR requests on the streaming commit
 	 * control will always use values retrieved from a successful GET_CUR
 	 * request on the probe control, as required by the UVC specification.
 	 */
-	if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+	ret = uvc_get_video_ctrl(stream, probe, 1, UVC_GET_CUR);
+	if (ret < 0)
 		return ret;
 
 	/* Check if the default format descriptor exists. Use the first
 	 * available format otherwise.
 	 */
-	for (i = video->streaming->nformats; i > 0; --i) {
-		format = &video->streaming->format[i-1];
+	for (i = stream->nformats; i > 0; --i) {
+		format = &stream->format[i-1];
 		if (format->index == probe->bFormatIndex)
 			break;
 	}
@@ -1105,21 +1126,20 @@ int uvc_video_init(struct uvc_video_device *video)
 	probe->bFormatIndex = format->index;
 	probe->bFrameIndex = frame->bFrameIndex;
 
-	video->streaming->cur_format = format;
-	video->streaming->cur_frame = frame;
-	atomic_set(&video->active, 0);
+	stream->cur_format = format;
+	stream->cur_frame = frame;
 
 	/* Select the video decoding function */
-	if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		if (video->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
-			video->decode = uvc_video_decode_isight;
-		else if (video->streaming->intf->num_altsetting > 1)
-			video->decode = uvc_video_decode_isoc;
+	if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		if (stream->dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)
+			stream->decode = uvc_video_decode_isight;
+		else if (stream->intf->num_altsetting > 1)
+			stream->decode = uvc_video_decode_isoc;
 		else
-			video->decode = uvc_video_decode_bulk;
+			stream->decode = uvc_video_decode_bulk;
 	} else {
-		if (video->streaming->intf->num_altsetting == 1)
-			video->decode = uvc_video_encode_bulk;
+		if (stream->intf->num_altsetting == 1)
+			stream->decode = uvc_video_encode_bulk;
 		else {
 			uvc_printk(KERN_INFO, "Isochronous endpoints are not "
 				"supported for video output devices.\n");
@@ -1133,31 +1153,32 @@ int uvc_video_init(struct uvc_video_device *video)
 /*
  * Enable or disable the video stream.
  */
-int uvc_video_enable(struct uvc_video_device *video, int enable)
+int uvc_video_enable(struct uvc_streaming *stream, int enable)
 {
 	int ret;
 
 	if (!enable) {
-		uvc_uninit_video(video, 1);
-		usb_set_interface(video->dev->udev,
-			video->streaming->intfnum, 0);
-		uvc_queue_enable(&video->queue, 0);
+		uvc_uninit_video(stream, 1);
+		usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+		uvc_queue_enable(&stream->queue, 0);
 		return 0;
 	}
 
-	if ((video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) ||
+	if ((stream->cur_format->flags & UVC_FMT_FLAG_COMPRESSED) ||
 	    uvc_no_drop_param)
-		video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
+		stream->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
 	else
-		video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE;
+		stream->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE;
 
-	if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
+	ret = uvc_queue_enable(&stream->queue, 1);
+	if (ret < 0)
 		return ret;
 
 	/* Commit the streaming parameters. */
-	if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0)
+	ret = uvc_commit_video(stream, &stream->ctrl);
+	if (ret < 0)
 		return ret;
 
-	return uvc_init_video(video, GFP_KERNEL);
+	return uvc_init_video(stream, GFP_KERNEL);
 }
 
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 3c78d3c..e7958aa 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -67,155 +67,12 @@ struct uvc_xu_control {
 #ifdef __KERNEL__
 
 #include <linux/poll.h>
+#include <linux/usb/video.h>
 
 /* --------------------------------------------------------------------------
  * UVC constants
  */
 
-#define SC_UNDEFINED			0x00
-#define SC_VIDEOCONTROL			0x01
-#define SC_VIDEOSTREAMING		0x02
-#define SC_VIDEO_INTERFACE_COLLECTION	0x03
-
-#define PC_PROTOCOL_UNDEFINED		0x00
-
-#define CS_UNDEFINED			0x20
-#define CS_DEVICE			0x21
-#define CS_CONFIGURATION		0x22
-#define CS_STRING			0x23
-#define CS_INTERFACE			0x24
-#define CS_ENDPOINT			0x25
-
-/* VideoControl class specific interface descriptor */
-#define VC_DESCRIPTOR_UNDEFINED		0x00
-#define VC_HEADER			0x01
-#define VC_INPUT_TERMINAL		0x02
-#define VC_OUTPUT_TERMINAL		0x03
-#define VC_SELECTOR_UNIT		0x04
-#define VC_PROCESSING_UNIT		0x05
-#define VC_EXTENSION_UNIT		0x06
-
-/* VideoStreaming class specific interface descriptor */
-#define VS_UNDEFINED			0x00
-#define VS_INPUT_HEADER			0x01
-#define VS_OUTPUT_HEADER		0x02
-#define VS_STILL_IMAGE_FRAME		0x03
-#define VS_FORMAT_UNCOMPRESSED		0x04
-#define VS_FRAME_UNCOMPRESSED		0x05
-#define VS_FORMAT_MJPEG			0x06
-#define VS_FRAME_MJPEG			0x07
-#define VS_FORMAT_MPEG2TS		0x0a
-#define VS_FORMAT_DV			0x0c
-#define VS_COLORFORMAT			0x0d
-#define VS_FORMAT_FRAME_BASED		0x10
-#define VS_FRAME_FRAME_BASED		0x11
-#define VS_FORMAT_STREAM_BASED		0x12
-
-/* Endpoint type */
-#define EP_UNDEFINED			0x00
-#define EP_GENERAL			0x01
-#define EP_ENDPOINT			0x02
-#define EP_INTERRUPT			0x03
-
-/* Request codes */
-#define RC_UNDEFINED			0x00
-#define SET_CUR				0x01
-#define GET_CUR				0x81
-#define GET_MIN				0x82
-#define GET_MAX				0x83
-#define GET_RES				0x84
-#define GET_LEN				0x85
-#define GET_INFO			0x86
-#define GET_DEF				0x87
-
-/* VideoControl interface controls */
-#define VC_CONTROL_UNDEFINED		0x00
-#define VC_VIDEO_POWER_MODE_CONTROL	0x01
-#define VC_REQUEST_ERROR_CODE_CONTROL	0x02
-
-/* Terminal controls */
-#define TE_CONTROL_UNDEFINED		0x00
-
-/* Selector Unit controls */
-#define SU_CONTROL_UNDEFINED		0x00
-#define SU_INPUT_SELECT_CONTROL		0x01
-
-/* Camera Terminal controls */
-#define CT_CONTROL_UNDEFINED				0x00
-#define CT_SCANNING_MODE_CONTROL			0x01
-#define CT_AE_MODE_CONTROL				0x02
-#define CT_AE_PRIORITY_CONTROL				0x03
-#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL		0x04
-#define CT_EXPOSURE_TIME_RELATIVE_CONTROL		0x05
-#define CT_FOCUS_ABSOLUTE_CONTROL			0x06
-#define CT_FOCUS_RELATIVE_CONTROL			0x07
-#define CT_FOCUS_AUTO_CONTROL				0x08
-#define CT_IRIS_ABSOLUTE_CONTROL			0x09
-#define CT_IRIS_RELATIVE_CONTROL			0x0a
-#define CT_ZOOM_ABSOLUTE_CONTROL			0x0b
-#define CT_ZOOM_RELATIVE_CONTROL			0x0c
-#define CT_PANTILT_ABSOLUTE_CONTROL			0x0d
-#define CT_PANTILT_RELATIVE_CONTROL			0x0e
-#define CT_ROLL_ABSOLUTE_CONTROL			0x0f
-#define CT_ROLL_RELATIVE_CONTROL			0x10
-#define CT_PRIVACY_CONTROL				0x11
-
-/* Processing Unit controls */
-#define PU_CONTROL_UNDEFINED				0x00
-#define PU_BACKLIGHT_COMPENSATION_CONTROL		0x01
-#define PU_BRIGHTNESS_CONTROL				0x02
-#define PU_CONTRAST_CONTROL				0x03
-#define PU_GAIN_CONTROL					0x04
-#define PU_POWER_LINE_FREQUENCY_CONTROL			0x05
-#define PU_HUE_CONTROL					0x06
-#define PU_SATURATION_CONTROL				0x07
-#define PU_SHARPNESS_CONTROL				0x08
-#define PU_GAMMA_CONTROL				0x09
-#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL		0x0a
-#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL	0x0b
-#define PU_WHITE_BALANCE_COMPONENT_CONTROL		0x0c
-#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL		0x0d
-#define PU_DIGITAL_MULTIPLIER_CONTROL			0x0e
-#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL		0x0f
-#define PU_HUE_AUTO_CONTROL				0x10
-#define PU_ANALOG_VIDEO_STANDARD_CONTROL		0x11
-#define PU_ANALOG_LOCK_STATUS_CONTROL			0x12
-
-#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL		0x01
-#define LXU_MOTOR_PANTILT_RESET_CONTROL			0x02
-#define LXU_MOTOR_FOCUS_MOTOR_CONTROL			0x03
-
-/* VideoStreaming interface controls */
-#define VS_CONTROL_UNDEFINED		0x00
-#define VS_PROBE_CONTROL		0x01
-#define VS_COMMIT_CONTROL		0x02
-#define VS_STILL_PROBE_CONTROL		0x03
-#define VS_STILL_COMMIT_CONTROL		0x04
-#define VS_STILL_IMAGE_TRIGGER_CONTROL	0x05
-#define VS_STREAM_ERROR_CODE_CONTROL	0x06
-#define VS_GENERATE_KEY_FRAME_CONTROL	0x07
-#define VS_UPDATE_FRAME_SEGMENT_CONTROL	0x08
-#define VS_SYNC_DELAY_CONTROL		0x09
-
-#define TT_VENDOR_SPECIFIC		0x0100
-#define TT_STREAMING			0x0101
-
-/* Input Terminal types */
-#define ITT_VENDOR_SPECIFIC		0x0200
-#define ITT_CAMERA			0x0201
-#define ITT_MEDIA_TRANSPORT_INPUT	0x0202
-
-/* Output Terminal types */
-#define OTT_VENDOR_SPECIFIC		0x0300
-#define OTT_DISPLAY			0x0301
-#define OTT_MEDIA_TRANSPORT_OUTPUT	0x0302
-
-/* External Terminal types */
-#define EXTERNAL_VENDOR_SPECIFIC	0x0400
-#define COMPOSITE_CONNECTOR		0x0401
-#define SVIDEO_CONNECTOR		0x0402
-#define COMPONENT_CONNECTOR		0x0403
-
 #define UVC_TERM_INPUT			0x0000
 #define UVC_TERM_OUTPUT			0x8000
 
@@ -223,12 +80,12 @@ struct uvc_xu_control {
 #define UVC_ENTITY_IS_UNIT(entity)	(((entity)->type & 0xff00) == 0)
 #define UVC_ENTITY_IS_TERM(entity)	(((entity)->type & 0xff00) != 0)
 #define UVC_ENTITY_IS_ITERM(entity) \
-	(((entity)->type & 0x8000) == UVC_TERM_INPUT)
+	(UVC_ENTITY_IS_TERM(entity) && \
+	((entity)->type & 0x8000) == UVC_TERM_INPUT)
 #define UVC_ENTITY_IS_OTERM(entity) \
-	(((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
+	(UVC_ENTITY_IS_TERM(entity) && \
+	((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
 
-#define UVC_STATUS_TYPE_CONTROL		1
-#define UVC_STATUS_TYPE_STREAMING	2
 
 /* ------------------------------------------------------------------------
  * GUIDs
@@ -249,19 +106,6 @@ struct uvc_xu_control {
 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
 	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
 
-#define UVC_GUID_LOGITECH_DEV_INFO \
-	{0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
-	 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1e}
-#define UVC_GUID_LOGITECH_USER_HW \
-	{0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
-	 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f}
-#define UVC_GUID_LOGITECH_VIDEO \
-	{0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
-	 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x50}
-#define UVC_GUID_LOGITECH_MOTOR \
-	{0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \
-	 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56}
-
 #define UVC_GUID_FORMAT_MJPEG \
 	{ 'M',  'J',  'P',  'G', 0x00, 0x00, 0x10, 0x00, \
 	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
@@ -314,6 +158,7 @@ struct uvc_xu_control {
 #define UVC_QUIRK_STREAM_NO_FID		0x00000010
 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT	0x00000020
 #define UVC_QUIRK_FIX_BANDWIDTH		0x00000080
+#define UVC_QUIRK_PROBE_DEF		0x00000100
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
@@ -518,26 +363,6 @@ struct uvc_streaming_header {
 	__u8 bTriggerUsage;
 };
 
-struct uvc_streaming {
-	struct list_head list;
-
-	struct usb_interface *intf;
-	int intfnum;
-	__u16 maxpsize;
-
-	struct uvc_streaming_header header;
-	enum v4l2_buf_type type;
-
-	unsigned int nformats;
-	struct uvc_format *format;
-
-	struct uvc_streaming_control ctrl;
-	struct uvc_format *cur_format;
-	struct uvc_frame *cur_frame;
-
-	struct mutex mutex;
-};
-
 enum uvc_buffer_state {
 	UVC_BUF_STATE_IDLE	= 0,
 	UVC_BUF_STATE_QUEUED	= 1,
@@ -579,26 +404,45 @@ struct uvc_video_queue {
 	struct list_head irqqueue;
 };
 
-struct uvc_video_device {
+struct uvc_video_chain {
 	struct uvc_device *dev;
-	struct video_device *vdev;
-	atomic_t active;
-	unsigned int frozen : 1;
+	struct list_head list;
 
 	struct list_head iterms;		/* Input terminals */
-	struct uvc_entity *oterm;		/* Output terminal */
-	struct uvc_entity *sterm;		/* USB streaming terminal */
-	struct uvc_entity *processing;
-	struct uvc_entity *selector;
-	struct list_head extensions;
+	struct list_head oterms;		/* Output terminals */
+	struct uvc_entity *processing;		/* Processing unit */
+	struct uvc_entity *selector;		/* Selector unit */
+	struct list_head extensions;		/* Extension units */
+
 	struct mutex ctrl_mutex;
+};
 
-	struct uvc_video_queue queue;
+struct uvc_streaming {
+	struct list_head list;
+	struct uvc_device *dev;
+	struct video_device *vdev;
+	struct uvc_video_chain *chain;
+	atomic_t active;
 
-	/* Video streaming object, must always be non-NULL. */
-	struct uvc_streaming *streaming;
+	struct usb_interface *intf;
+	int intfnum;
+	__u16 maxpsize;
 
-	void (*decode) (struct urb *urb, struct uvc_video_device *video,
+	struct uvc_streaming_header header;
+	enum v4l2_buf_type type;
+
+	unsigned int nformats;
+	struct uvc_format *format;
+
+	struct uvc_streaming_control ctrl;
+	struct uvc_format *cur_format;
+	struct uvc_frame *cur_frame;
+
+	struct mutex mutex;
+
+	unsigned int frozen : 1;
+	struct uvc_video_queue queue;
+	void (*decode) (struct urb *urb, struct uvc_streaming *video,
 			struct uvc_buffer *buf);
 
 	/* Context data used by the bulk completion handler. */
@@ -640,8 +484,10 @@ struct uvc_device {
 	__u32 clock_frequency;
 
 	struct list_head entities;
+	struct list_head chains;
 
-	struct uvc_video_device video;
+	/* Video Streaming interfaces */
+	struct list_head streams;
 
 	/* Status Interrupt Endpoint */
 	struct usb_host_endpoint *int_ep;
@@ -649,9 +495,6 @@ struct uvc_device {
 	__u8 *status;
 	struct input_dev *input;
 	char input_phys[64];
-
-	/* Video Streaming interfaces */
-	struct list_head streaming;
 };
 
 enum uvc_handle_state {
@@ -660,7 +503,8 @@ enum uvc_handle_state {
 };
 
 struct uvc_fh {
-	struct uvc_video_device *device;
+	struct uvc_video_chain *chain;
+	struct uvc_streaming *stream;
 	enum uvc_handle_state state;
 };
 
@@ -757,13 +601,13 @@ static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
 extern const struct v4l2_file_operations uvc_fops;
 
 /* Video */
-extern int uvc_video_init(struct uvc_video_device *video);
-extern int uvc_video_suspend(struct uvc_video_device *video);
-extern int uvc_video_resume(struct uvc_video_device *video);
-extern int uvc_video_enable(struct uvc_video_device *video, int enable);
-extern int uvc_probe_video(struct uvc_video_device *video,
+extern int uvc_video_init(struct uvc_streaming *stream);
+extern int uvc_video_suspend(struct uvc_streaming *stream);
+extern int uvc_video_resume(struct uvc_streaming *stream);
+extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
+extern int uvc_probe_video(struct uvc_streaming *stream,
 		struct uvc_streaming_control *probe);
-extern int uvc_commit_video(struct uvc_video_device *video,
+extern int uvc_commit_video(struct uvc_streaming *stream,
 		struct uvc_streaming_control *ctrl);
 extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
 		__u8 intfnum, __u8 cs, void *data, __u16 size);
@@ -777,9 +621,9 @@ extern int uvc_status_suspend(struct uvc_device *dev);
 extern int uvc_status_resume(struct uvc_device *dev);
 
 /* Controls */
-extern struct uvc_control *uvc_find_control(struct uvc_video_device *video,
+extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
 		__u32 v4l2_id, struct uvc_control_mapping **mapping);
-extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
+extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
 		struct v4l2_queryctrl *v4l2_ctrl);
 
 extern int uvc_ctrl_add_info(struct uvc_control_info *info);
@@ -789,23 +633,23 @@ extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
 extern int uvc_ctrl_resume_device(struct uvc_device *dev);
 extern void uvc_ctrl_init(void);
 
-extern int uvc_ctrl_begin(struct uvc_video_device *video);
-extern int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback);
-static inline int uvc_ctrl_commit(struct uvc_video_device *video)
+extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
+extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback);
+static inline int uvc_ctrl_commit(struct uvc_video_chain *chain)
 {
-	return __uvc_ctrl_commit(video, 0);
+	return __uvc_ctrl_commit(chain, 0);
 }
-static inline int uvc_ctrl_rollback(struct uvc_video_device *video)
+static inline int uvc_ctrl_rollback(struct uvc_video_chain *chain)
 {
-	return __uvc_ctrl_commit(video, 1);
+	return __uvc_ctrl_commit(chain, 1);
 }
 
-extern int uvc_ctrl_get(struct uvc_video_device *video,
+extern int uvc_ctrl_get(struct uvc_video_chain *chain,
 		struct v4l2_ext_control *xctrl);
-extern int uvc_ctrl_set(struct uvc_video_device *video,
+extern int uvc_ctrl_set(struct uvc_video_chain *chain,
 		struct v4l2_ext_control *xctrl);
 
-extern int uvc_xu_ctrl_query(struct uvc_video_device *video,
+extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
 		struct uvc_xu_control *ctrl, int set);
 
 /* Utility functions */
@@ -817,7 +661,7 @@ extern struct usb_host_endpoint *uvc_find_endpoint(
 		struct usb_host_interface *alts, __u8 epaddr);
 
 /* Quirks support */
-void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video,
+void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
 		struct uvc_buffer *buf);
 
 #endif /* __KERNEL__ */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 02f2a6d..0c2105c 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -76,9 +76,8 @@ get_v4l_control(struct file             *file,
 			dprintk("VIDIOC_G_CTRL: %d\n", err);
 			return 0;
 		}
-		return ((ctrl2.value - qctrl2.minimum) * 65535
-			 + (qctrl2.maximum - qctrl2.minimum) / 2)
-			/ (qctrl2.maximum - qctrl2.minimum);
+		return DIV_ROUND_CLOSEST((ctrl2.value-qctrl2.minimum) * 65535,
+					 qctrl2.maximum - qctrl2.minimum);
 	}
 	return 0;
 }
@@ -565,10 +564,9 @@ static noinline long v4l1_compat_get_input_info(
 		break;
 	}
 	chan->norm = 0;
-	err = drv(file, VIDIOC_G_STD, &sid);
-	if (err < 0)
-		dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %ld\n", err);
-	if (err == 0) {
+	/* Note: G_STD might not be present for radio receivers,
+	 * so we should ignore any errors. */
+	if (drv(file, VIDIOC_G_STD, &sid) == 0) {
 		if (sid & V4L2_STD_PAL)
 			chan->norm = VIDEO_MODE_PAL;
 		if (sid & V4L2_STD_NTSC)
@@ -777,10 +775,9 @@ static noinline long v4l1_compat_get_tuner(
 			tun->flags |= VIDEO_TUNER_SECAM;
 	}
 
-	err = drv(file, VIDIOC_G_STD, &sid);
-	if (err < 0)
-		dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %ld\n", err);
-	if (err == 0) {
+	/* Note: G_STD might not be present for radio receivers,
+	 * so we should ignore any errors. */
+	if (drv(file, VIDIOC_G_STD, &sid) == 0) {
 		if (sid & V4L2_STD_PAL)
 			tun->mode = VIDEO_MODE_PAL;
 		if (sid & V4L2_STD_NTSC)
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index b91d66a..f5a93ae 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -156,6 +156,8 @@ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
 		return -EINVAL;
 	if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
 		return -EBUSY;
+	if (qctrl->type == V4L2_CTRL_TYPE_STRING)
+		return 0;
 	if (qctrl->type == V4L2_CTRL_TYPE_BUTTON ||
 	    qctrl->type == V4L2_CTRL_TYPE_INTEGER64 ||
 	    qctrl->type == V4L2_CTRL_TYPE_CTRL_CLASS)
@@ -340,6 +342,12 @@ const char **v4l2_ctrl_get_menu(u32 id)
 		"Sepia",
 		NULL
 	};
+	static const char *tune_preemphasis[] = {
+		"No preemphasis",
+		"50 useconds",
+		"75 useconds",
+		NULL,
+	};
 
 	switch (id) {
 		case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -378,6 +386,8 @@ const char **v4l2_ctrl_get_menu(u32 id)
 			return camera_exposure_auto;
 		case V4L2_CID_COLORFX:
 			return colorfx;
+		case V4L2_CID_TUNE_PREEMPHASIS:
+			return tune_preemphasis;
 		default:
 			return NULL;
 	}
@@ -476,6 +486,28 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_ZOOM_CONTINUOUS:		return "Zoom, Continuous";
 	case V4L2_CID_PRIVACY:			return "Privacy";
 
+	/* FM Radio Modulator control */
+	case V4L2_CID_FM_TX_CLASS:		return "FM Radio Modulator Controls";
+	case V4L2_CID_RDS_TX_DEVIATION:		return "RDS Signal Deviation";
+	case V4L2_CID_RDS_TX_PI:		return "RDS Program ID";
+	case V4L2_CID_RDS_TX_PTY:		return "RDS Program Type";
+	case V4L2_CID_RDS_TX_PS_NAME:		return "RDS PS Name";
+	case V4L2_CID_RDS_TX_RADIO_TEXT:	return "RDS Radio Text";
+	case V4L2_CID_AUDIO_LIMITER_ENABLED:	return "Audio Limiter Feature Enabled";
+	case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
+	case V4L2_CID_AUDIO_LIMITER_DEVIATION:	return "Audio Limiter Deviation";
+	case V4L2_CID_AUDIO_COMPRESSION_ENABLED: return "Audio Compression Feature Enabled";
+	case V4L2_CID_AUDIO_COMPRESSION_GAIN:	return "Audio Compression Gain";
+	case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: return "Audio Compression Threshold";
+	case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: return "Audio Compression Attack Time";
+	case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: return "Audio Compression Release Time";
+	case V4L2_CID_PILOT_TONE_ENABLED:	return "Pilot Tone Feature Enabled";
+	case V4L2_CID_PILOT_TONE_DEVIATION:	return "Pilot Tone Deviation";
+	case V4L2_CID_PILOT_TONE_FREQUENCY:	return "Pilot Tone Frequency";
+	case V4L2_CID_TUNE_PREEMPHASIS:	return "Pre-emphasis settings";
+	case V4L2_CID_TUNE_POWER_LEVEL:		return "Tune Power Level";
+	case V4L2_CID_TUNE_ANTENNA_CAPACITOR:	return "Tune Antenna Capacitor";
+
 	default:
 		return NULL;
 	}
@@ -508,6 +540,9 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
 	case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
 	case V4L2_CID_FOCUS_AUTO:
 	case V4L2_CID_PRIVACY:
+	case V4L2_CID_AUDIO_LIMITER_ENABLED:
+	case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
+	case V4L2_CID_PILOT_TONE_ENABLED:
 		qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
 		min = 0;
 		max = step = 1;
@@ -536,12 +571,18 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
 	case V4L2_CID_MPEG_STREAM_VBI_FMT:
 	case V4L2_CID_EXPOSURE_AUTO:
 	case V4L2_CID_COLORFX:
+	case V4L2_CID_TUNE_PREEMPHASIS:
 		qctrl->type = V4L2_CTRL_TYPE_MENU;
 		step = 1;
 		break;
+	case V4L2_CID_RDS_TX_PS_NAME:
+	case V4L2_CID_RDS_TX_RADIO_TEXT:
+		qctrl->type = V4L2_CTRL_TYPE_STRING;
+		break;
 	case V4L2_CID_USER_CLASS:
 	case V4L2_CID_CAMERA_CLASS:
 	case V4L2_CID_MPEG_CLASS:
+	case V4L2_CID_FM_TX_CLASS:
 		qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
 		qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 		min = max = step = def = 0;
@@ -570,6 +611,17 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
 	case V4L2_CID_BLUE_BALANCE:
 	case V4L2_CID_GAMMA:
 	case V4L2_CID_SHARPNESS:
+	case V4L2_CID_RDS_TX_DEVIATION:
+	case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
+	case V4L2_CID_AUDIO_LIMITER_DEVIATION:
+	case V4L2_CID_AUDIO_COMPRESSION_GAIN:
+	case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
+	case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
+	case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
+	case V4L2_CID_PILOT_TONE_DEVIATION:
+	case V4L2_CID_PILOT_TONE_FREQUENCY:
+	case V4L2_CID_TUNE_POWER_LEVEL:
+	case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
 		qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 		break;
 	case V4L2_CID_PAN_RELATIVE:
@@ -762,139 +814,6 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
 
 
 /* Load an i2c sub-device. */
-struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
-		struct i2c_adapter *adapter,
-		const char *module_name, const char *client_type, u8 addr)
-{
-	struct v4l2_subdev *sd = NULL;
-	struct i2c_client *client;
-	struct i2c_board_info info;
-
-	BUG_ON(!v4l2_dev);
-
-	if (module_name)
-		request_module(module_name);
-
-	/* Setup the i2c board info with the device type and
-	   the device address. */
-	memset(&info, 0, sizeof(info));
-	strlcpy(info.type, client_type, sizeof(info.type));
-	info.addr = addr;
-
-	/* Create the i2c client */
-	client = i2c_new_device(adapter, &info);
-	/* Note: it is possible in the future that
-	   c->driver is NULL if the driver is still being loaded.
-	   We need better support from the kernel so that we
-	   can easily wait for the load to finish. */
-	if (client == NULL || client->driver == NULL)
-		goto error;
-
-	/* Lock the module so we can safely get the v4l2_subdev pointer */
-	if (!try_module_get(client->driver->driver.owner))
-		goto error;
-	sd = i2c_get_clientdata(client);
-
-	/* Register with the v4l2_device which increases the module's
-	   use count as well. */
-	if (v4l2_device_register_subdev(v4l2_dev, sd))
-		sd = NULL;
-	/* Decrease the module use count to match the first try_module_get. */
-	module_put(client->driver->driver.owner);
-
-	if (sd) {
-		/* We return errors from v4l2_subdev_call only if we have the
-		   callback as the .s_config is not mandatory */
-		int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
-
-		if (err && err != -ENOIOCTLCMD) {
-			v4l2_device_unregister_subdev(sd);
-			sd = NULL;
-		}
-	}
-
-error:
-	/* If we have a client but no subdev, then something went wrong and
-	   we must unregister the client. */
-	if (client && sd == NULL)
-		i2c_unregister_device(client);
-	return sd;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
-
-/* Probe and load an i2c sub-device. */
-struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
-	struct i2c_adapter *adapter,
-	const char *module_name, const char *client_type,
-	const unsigned short *addrs)
-{
-	struct v4l2_subdev *sd = NULL;
-	struct i2c_client *client = NULL;
-	struct i2c_board_info info;
-
-	BUG_ON(!v4l2_dev);
-
-	if (module_name)
-		request_module(module_name);
-
-	/* Setup the i2c board info with the device type and
-	   the device address. */
-	memset(&info, 0, sizeof(info));
-	strlcpy(info.type, client_type, sizeof(info.type));
-
-	/* Probe and create the i2c client */
-	client = i2c_new_probed_device(adapter, &info, addrs);
-	/* Note: it is possible in the future that
-	   c->driver is NULL if the driver is still being loaded.
-	   We need better support from the kernel so that we
-	   can easily wait for the load to finish. */
-	if (client == NULL || client->driver == NULL)
-		goto error;
-
-	/* Lock the module so we can safely get the v4l2_subdev pointer */
-	if (!try_module_get(client->driver->driver.owner))
-		goto error;
-	sd = i2c_get_clientdata(client);
-
-	/* Register with the v4l2_device which increases the module's
-	   use count as well. */
-	if (v4l2_device_register_subdev(v4l2_dev, sd))
-		sd = NULL;
-	/* Decrease the module use count to match the first try_module_get. */
-	module_put(client->driver->driver.owner);
-
-	if (sd) {
-		/* We return errors from v4l2_subdev_call only if we have the
-		   callback as the .s_config is not mandatory */
-		int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
-
-		if (err && err != -ENOIOCTLCMD) {
-			v4l2_device_unregister_subdev(sd);
-			sd = NULL;
-		}
-	}
-
-error:
-	/* If we have a client but no subdev, then something went wrong and
-	   we must unregister the client. */
-	if (client && sd == NULL)
-		i2c_unregister_device(client);
-	return sd;
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
-
-struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
-		struct i2c_adapter *adapter,
-		const char *module_name, const char *client_type, u8 addr)
-{
-	unsigned short addrs[2] = { addr, I2C_CLIENT_END };
-
-	return v4l2_i2c_new_probed_subdev(v4l2_dev, adapter,
-			module_name, client_type, addrs);
-}
-EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr);
-
-/* Load an i2c sub-device. */
 struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
 		struct i2c_adapter *adapter, const char *module_name,
 		struct i2c_board_info *info, const unsigned short *probe_addrs)
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 0056b11..997975d 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -600,9 +600,37 @@ struct v4l2_ext_controls32 {
        compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */
 };
 
+struct v4l2_ext_control32 {
+	__u32 id;
+	__u32 size;
+	__u32 reserved2[1];
+	union {
+		__s32 value;
+		__s64 value64;
+		compat_caddr_t string; /* actually char * */
+	};
+} __attribute__ ((packed));
+
+/* The following function really belong in v4l2-common, but that causes
+   a circular dependency between modules. We need to think about this, but
+   for now this will do. */
+
+/* Return non-zero if this control is a pointer type. Currently only
+   type STRING is a pointer type. */
+static inline int ctrl_is_pointer(u32 id)
+{
+	switch (id) {
+	case V4L2_CID_RDS_TX_PS_NAME:
+	case V4L2_CID_RDS_TX_RADIO_TEXT:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
 {
-	struct v4l2_ext_control __user *ucontrols;
+	struct v4l2_ext_control32 __user *ucontrols;
 	struct v4l2_ext_control __user *kcontrols;
 	int n;
 	compat_caddr_t p;
@@ -626,15 +654,17 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
 	kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
 	kp->controls = kcontrols;
 	while (--n >= 0) {
-		if (copy_in_user(&kcontrols->id, &ucontrols->id, sizeof(__u32)))
-			return -EFAULT;
-		if (copy_in_user(&kcontrols->reserved2, &ucontrols->reserved2, sizeof(ucontrols->reserved2)))
-			return -EFAULT;
-		/* Note: if the void * part of the union ever becomes relevant
-		   then we need to know the type of the control in order to do
-		   the right thing here. Luckily, that is not yet an issue. */
-		if (copy_in_user(&kcontrols->value, &ucontrols->value, sizeof(ucontrols->value)))
+		if (copy_in_user(kcontrols, ucontrols, sizeof(*kcontrols)))
 			return -EFAULT;
+		if (ctrl_is_pointer(kcontrols->id)) {
+			void __user *s;
+
+			if (get_user(p, &ucontrols->string))
+				return -EFAULT;
+			s = compat_ptr(p);
+			if (put_user(s, &kcontrols->string))
+				return -EFAULT;
+		}
 		ucontrols++;
 		kcontrols++;
 	}
@@ -643,7 +673,7 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
 
 static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
 {
-	struct v4l2_ext_control __user *ucontrols;
+	struct v4l2_ext_control32 __user *ucontrols;
 	struct v4l2_ext_control __user *kcontrols = kp->controls;
 	int n = kp->count;
 	compat_caddr_t p;
@@ -664,15 +694,14 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
 		return -EFAULT;
 
 	while (--n >= 0) {
-		if (copy_in_user(&ucontrols->id, &kcontrols->id, sizeof(__u32)))
-			return -EFAULT;
-		if (copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2,
-					sizeof(ucontrols->reserved2)))
-			return -EFAULT;
-		/* Note: if the void * part of the union ever becomes relevant
-		   then we need to know the type of the control in order to do
-		   the right thing here. Luckily, that is not yet an issue. */
-		if (copy_in_user(&ucontrols->value, &kcontrols->value, sizeof(ucontrols->value)))
+		unsigned size = sizeof(*ucontrols);
+
+		/* Do not modify the pointer when copying a pointer control.
+		   The contents of the pointer was changed, not the pointer
+		   itself. */
+		if (ctrl_is_pointer(kcontrols->id))
+			size -= sizeof(ucontrols->value64);
+		if (copy_in_user(ucontrols, kcontrols, size))
 			return -EFAULT;
 		ucontrols++;
 		kcontrols++;
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index a7f1b69..500cbe9 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -66,7 +66,49 @@ static struct device_attribute video_device_attrs[] = {
  */
 static struct video_device *video_device[VIDEO_NUM_DEVICES];
 static DEFINE_MUTEX(videodev_lock);
-static DECLARE_BITMAP(video_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
+static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
+
+/* Device node utility functions */
+
+/* Note: these utility functions all assume that vfl_type is in the range
+   [0, VFL_TYPE_MAX-1]. */
+
+#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
+/* Return the bitmap corresponding to vfl_type. */
+static inline unsigned long *devnode_bits(int vfl_type)
+{
+	/* Any types not assigned to fixed minor ranges must be mapped to
+	   one single bitmap for the purposes of finding a free node number
+	   since all those unassigned types use the same minor range. */
+	int idx = (vfl_type > VFL_TYPE_VTX) ? VFL_TYPE_MAX - 1 : vfl_type;
+
+	return devnode_nums[idx];
+}
+#else
+/* Return the bitmap corresponding to vfl_type. */
+static inline unsigned long *devnode_bits(int vfl_type)
+{
+	return devnode_nums[vfl_type];
+}
+#endif
+
+/* Mark device node number vdev->num as used */
+static inline void devnode_set(struct video_device *vdev)
+{
+	set_bit(vdev->num, devnode_bits(vdev->vfl_type));
+}
+
+/* Mark device node number vdev->num as unused */
+static inline void devnode_clear(struct video_device *vdev)
+{
+	clear_bit(vdev->num, devnode_bits(vdev->vfl_type));
+}
+
+/* Try to find a free device node number in the range [from, to> */
+static inline int devnode_find(struct video_device *vdev, int from, int to)
+{
+	return find_next_zero_bit(devnode_bits(vdev->vfl_type), to, from);
+}
 
 struct video_device *video_device_alloc(void)
 {
@@ -119,8 +161,8 @@ static void v4l2_device_release(struct device *cd)
 	   the release() callback. */
 	vdev->cdev = NULL;
 
-	/* Mark minor as free */
-	clear_bit(vdev->num, video_nums[vdev->vfl_type]);
+	/* Mark device node number as free */
+	devnode_clear(vdev);
 
 	mutex_unlock(&videodev_lock);
 
@@ -299,32 +341,28 @@ static const struct file_operations v4l2_fops = {
 };
 
 /**
- * get_index - assign stream number based on parent device
+ * get_index - assign stream index number based on parent device
  * @vdev: video_device to assign index number to, vdev->parent should be assigned
- * @num:  -1 if auto assign, requested number otherwise
  *
  * Note that when this is called the new device has not yet been registered
- * in the video_device array.
+ * in the video_device array, but it was able to obtain a minor number.
+ *
+ * This means that we can always obtain a free stream index number since
+ * the worst case scenario is that there are VIDEO_NUM_DEVICES - 1 slots in
+ * use of the video_device array.
  *
- * Returns -ENFILE if num is already in use, a free index number if
- * successful.
+ * Returns a free index number.
  */
-static int get_index(struct video_device *vdev, int num)
+static int get_index(struct video_device *vdev)
 {
 	/* This can be static since this function is called with the global
 	   videodev_lock held. */
 	static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
 	int i;
 
-	if (num >= VIDEO_NUM_DEVICES) {
-		printk(KERN_ERR "videodev: %s num is too large\n", __func__);
-		return -EINVAL;
-	}
-
-	/* Some drivers do not set the parent. In that case always return
-	   num or 0. */
+	/* Some drivers do not set the parent. In that case always return 0. */
 	if (vdev->parent == NULL)
-		return num >= 0 ? num : 0;
+		return 0;
 
 	bitmap_zero(used, VIDEO_NUM_DEVICES);
 
@@ -335,35 +373,23 @@ static int get_index(struct video_device *vdev, int num)
 		}
 	}
 
-	if (num >= 0) {
-		if (test_bit(num, used))
-			return -ENFILE;
-		return num;
-	}
-
-	i = find_first_zero_bit(used, VIDEO_NUM_DEVICES);
-	return i == VIDEO_NUM_DEVICES ? -ENFILE : i;
+	return find_first_zero_bit(used, VIDEO_NUM_DEVICES);
 }
 
-int video_register_device(struct video_device *vdev, int type, int nr)
-{
-	return video_register_device_index(vdev, type, nr, -1);
-}
-EXPORT_SYMBOL(video_register_device);
-
 /**
- *	video_register_device_index - register video4linux devices
+ *	video_register_device - register video4linux devices
  *	@vdev: video device structure we want to register
  *	@type: type of device to register
- *	@nr:   which device number (0 == /dev/video0, 1 == /dev/video1, ...
+ *	@nr:   which device node number (0 == /dev/video0, 1 == /dev/video1, ...
  *             -1 == first free)
- *	@index: stream number based on parent device;
- *		-1 if auto assign, requested number otherwise
+ *	@warn_if_nr_in_use: warn if the desired device node number
+ *	       was already in use and another number was chosen instead.
  *
- *	The registration code assigns minor numbers based on the type
- *	requested. -ENFILE is returned in all the device slots for this
- *	category are full. If not then the minor field is set and the
- *	driver initialize function is called (if non %NULL).
+ *	The registration code assigns minor numbers and device node numbers
+ *	based on the requested type and registers the new device node with
+ *	the kernel.
+ *	An error is returned if no free minor or device node number could be
+ *	found, or if the registration of the device node failed.
  *
  *	Zero is returned on success.
  *
@@ -377,8 +403,8 @@ EXPORT_SYMBOL(video_register_device);
  *
  *	%VFL_TYPE_RADIO - A radio card
  */
-int video_register_device_index(struct video_device *vdev, int type, int nr,
-					int index)
+static int __video_register_device(struct video_device *vdev, int type, int nr,
+		int warn_if_nr_in_use)
 {
 	int i = 0;
 	int ret;
@@ -421,7 +447,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
 	if (vdev->v4l2_dev && vdev->v4l2_dev->dev)
 		vdev->parent = vdev->v4l2_dev->dev;
 
-	/* Part 2: find a free minor, kernel number and device index. */
+	/* Part 2: find a free minor, device node number and device index. */
 #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
 	/* Keep the ranges for the first four types for historical
 	 * reasons.
@@ -452,21 +478,22 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
 	}
 #endif
 
-	/* Pick a minor number */
+	/* Pick a device node number */
 	mutex_lock(&videodev_lock);
-	nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr);
+	nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
 	if (nr == minor_cnt)
-		nr = find_first_zero_bit(video_nums[type], minor_cnt);
+		nr = devnode_find(vdev, 0, minor_cnt);
 	if (nr == minor_cnt) {
-		printk(KERN_ERR "could not get a free kernel number\n");
+		printk(KERN_ERR "could not get a free device node number\n");
 		mutex_unlock(&videodev_lock);
 		return -ENFILE;
 	}
 #ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
-	/* 1-on-1 mapping of kernel number to minor number */
+	/* 1-on-1 mapping of device node number to minor number */
 	i = nr;
 #else
-	/* The kernel number and minor numbers are independent */
+	/* The device node number and minor numbers are independent, so
+	   we just find the first free minor number. */
 	for (i = 0; i < VIDEO_NUM_DEVICES; i++)
 		if (video_device[i] == NULL)
 			break;
@@ -478,17 +505,13 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
 #endif
 	vdev->minor = i + minor_offset;
 	vdev->num = nr;
-	set_bit(nr, video_nums[type]);
+	devnode_set(vdev);
+
 	/* Should not happen since we thought this minor was free */
 	WARN_ON(video_device[vdev->minor] != NULL);
-	ret = vdev->index = get_index(vdev, index);
+	vdev->index = get_index(vdev);
 	mutex_unlock(&videodev_lock);
 
-	if (ret < 0) {
-		printk(KERN_ERR "%s: get_index failed\n", __func__);
-		goto cleanup;
-	}
-
 	/* Part 3: Initialize the character device */
 	vdev->cdev = cdev_alloc();
 	if (vdev->cdev == NULL) {
@@ -517,7 +540,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
 	vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
 	if (vdev->parent)
 		vdev->dev.parent = vdev->parent;
-	dev_set_name(&vdev->dev, "%s%d", name_base, nr);
+	dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
 	ret = device_register(&vdev->dev);
 	if (ret < 0) {
 		printk(KERN_ERR "%s: device_register failed\n", __func__);
@@ -527,6 +550,10 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
 	   reference to the device goes away. */
 	vdev->dev.release = v4l2_device_release;
 
+	if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
+		printk(KERN_WARNING "%s: requested %s%d, got %s%d\n",
+				__func__, name_base, nr, name_base, vdev->num);
+
 	/* Part 5: Activate this minor. The char device can now be used. */
 	mutex_lock(&videodev_lock);
 	video_device[vdev->minor] = vdev;
@@ -537,13 +564,24 @@ cleanup:
 	mutex_lock(&videodev_lock);
 	if (vdev->cdev)
 		cdev_del(vdev->cdev);
-	clear_bit(vdev->num, video_nums[type]);
+	devnode_clear(vdev);
 	mutex_unlock(&videodev_lock);
 	/* Mark this video device as never having been registered. */
 	vdev->minor = -1;
 	return ret;
 }
-EXPORT_SYMBOL(video_register_device_index);
+
+int video_register_device(struct video_device *vdev, int type, int nr)
+{
+	return __video_register_device(vdev, type, nr, 1);
+}
+EXPORT_SYMBOL(video_register_device);
+
+int video_register_device_no_warn(struct video_device *vdev, int type, int nr)
+{
+	return __video_register_device(vdev, type, nr, 0);
+}
+EXPORT_SYMBOL(video_register_device_no_warn);
 
 /**
  *	video_unregister_device - unregister a video4linux device
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index f2afc4e..30cc334 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -42,6 +42,12 @@
 			printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\
 		} while (0)
 
+#define dbgarg3(fmt, arg...) \
+		do {							\
+		    if (vfd->debug & V4L2_DEBUG_IOCTL_ARG)		\
+			printk(KERN_CONT "%s: " fmt, vfd->name, ## arg);\
+		} while (0)
+
 /* Zero out the end of the struct pointed to by p.  Everthing after, but
  * not including, the specified field is cleared. */
 #define CLEAR_AFTER_FIELD(p, field) \
@@ -507,11 +513,12 @@ static inline void v4l_print_ext_ctrls(unsigned int cmd,
 	dbgarg(cmd, "");
 	printk(KERN_CONT "class=0x%x", c->ctrl_class);
 	for (i = 0; i < c->count; i++) {
-		if (show_vals)
+		if (show_vals && !c->controls[i].size)
 			printk(KERN_CONT " id/val=0x%x/0x%x",
 				c->controls[i].id, c->controls[i].value);
 		else
-			printk(KERN_CONT " id=0x%x", c->controls[i].id);
+			printk(KERN_CONT " id=0x%x,size=%u",
+				c->controls[i].id, c->controls[i].size);
 	}
 	printk(KERN_CONT "\n");
 };
@@ -522,10 +529,9 @@ static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv)
 
 	/* zero the reserved fields */
 	c->reserved[0] = c->reserved[1] = 0;
-	for (i = 0; i < c->count; i++) {
+	for (i = 0; i < c->count; i++)
 		c->controls[i].reserved2[0] = 0;
-		c->controls[i].reserved2[1] = 0;
-	}
+
 	/* V4L2_CID_PRIVATE_BASE cannot be used as control class
 	   when using extended controls.
 	   Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL
@@ -1726,24 +1732,29 @@ static long __video_do_ioctl(struct file *file,
 
 		ret = ops->vidioc_enum_framesizes(file, fh, p);
 		dbgarg(cmd,
-			"index=%d, pixelformat=%d, type=%d ",
-			p->index, p->pixel_format, p->type);
+			"index=%d, pixelformat=%c%c%c%c, type=%d ",
+			p->index,
+			(p->pixel_format & 0xff),
+			(p->pixel_format >>  8) & 0xff,
+			(p->pixel_format >> 16) & 0xff,
+			(p->pixel_format >> 24) & 0xff,
+			p->type);
 		switch (p->type) {
 		case V4L2_FRMSIZE_TYPE_DISCRETE:
-			dbgarg2("width = %d, height=%d\n",
+			dbgarg3("width = %d, height=%d\n",
 				p->discrete.width, p->discrete.height);
 			break;
 		case V4L2_FRMSIZE_TYPE_STEPWISE:
-			dbgarg2("min %dx%d, max %dx%d, step %dx%d\n",
+			dbgarg3("min %dx%d, max %dx%d, step %dx%d\n",
 				p->stepwise.min_width,  p->stepwise.min_height,
 				p->stepwise.step_width, p->stepwise.step_height,
 				p->stepwise.max_width,  p->stepwise.max_height);
 			break;
 		case V4L2_FRMSIZE_TYPE_CONTINUOUS:
-			dbgarg2("continuous\n");
+			dbgarg3("continuous\n");
 			break;
 		default:
-			dbgarg2("- Unknown type!\n");
+			dbgarg3("- Unknown type!\n");
 		}
 
 		break;
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 97b082f..cd6a344 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -1776,7 +1776,6 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
 
 static struct i2c_adapter vino_i2c_adapter = {
 	.name			= "VINO I2C bus",
-	.id			= I2C_HW_SGI_VINO,
 	.algo			= &sgi_algo,
 	.algo_data		= &i2c_sgi_vino_data,
 	.owner 			= THIS_MODULE,
@@ -4334,11 +4333,11 @@ static int __init vino_module_init(void)
 	vino_init_stage++;
 
 	vino_drvdata->decoder =
-		v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev,
-			&vino_i2c_adapter, "saa7191", "saa7191", 0x45);
+		v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
+			       "saa7191", "saa7191", 0, I2C_ADDRS(0x45));
 	vino_drvdata->camera =
-		v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev,
-			&vino_i2c_adapter, "indycam", "indycam", 0x2b);
+		v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
+			       "indycam", "indycam", 0, I2C_ADDRS(0x2b));
 
 	dprintk("init complete!\n");
 
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 6c3f23e..37fcdc4 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -1497,7 +1497,6 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam)
 	};
 
 	static struct i2c_adapter adap = {
-		.id =                I2C_HW_SMBUS_W9968CF,
 		.owner =             THIS_MODULE,
 		.algo =              &algo,
 	};
@@ -3516,9 +3515,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
 	w9968cf_turn_on_led(cam);
 
 	w9968cf_i2c_init(cam);
-	cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->v4l2_dev,
+	cam->sensor_sd = v4l2_i2c_new_subdev(&cam->v4l2_dev,
 			&cam->i2c_adapter,
-			"ovcamchip", "ovcamchip", addrs);
+			"ovcamchip", "ovcamchip", 0, addrs);
 
 	usb_set_intfdata(intf, cam);
 	mutex_unlock(&cam->dev_mutex);
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 9697104..b3c6436 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -819,8 +819,10 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
 			    (!list_empty(&cam->outqueue)) ||
 			    (cam->state & DEV_DISCONNECTED) ||
 			    (cam->state & DEV_MISCONFIGURED),
-			    cam->module_param.frame_timeout *
-			    1000 * msecs_to_jiffies(1) );
+			    msecs_to_jiffies(
+				cam->module_param.frame_timeout * 1000
+			    )
+			  );
 		if (timeout < 0) {
 			mutex_unlock(&cam->fileop_mutex);
 			return timeout;
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 03dc2f3..be70574 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -732,7 +732,6 @@ zoran_register_i2c (struct zoran *zr)
 	memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
 	       sizeof(struct i2c_algo_bit_data));
 	zr->i2c_algo.data = zr;
-	zr->i2c_adapter.id = I2C_HW_B_ZR36067;
 	strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
 		sizeof(zr->i2c_adapter.name));
 	i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
@@ -1169,7 +1168,7 @@ zoran_setup_videocodec (struct zoran *zr,
 	m->type = 0;
 
 	m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
-	strncpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
+	strlcpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
 	m->data = zr;
 
 	switch (type)
@@ -1358,15 +1357,15 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
 		goto zr_free_irq;
 	}
 
-	zr->decoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev,
+	zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
 		&zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder,
-		zr->card.addrs_decoder);
+		0, zr->card.addrs_decoder);
 
 	if (zr->card.mod_encoder)
-		zr->encoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev,
+		zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
 			&zr->i2c_adapter,
 			zr->card.mod_encoder, zr->card.i2c_encoder,
-			zr->card.addrs_encoder);
+			0, zr->card.addrs_encoder);
 
 	dprintk(2,
 		KERN_INFO "%s: Initializing videocodec bus...\n",
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 2622a6e..9aae011 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -1,5 +1,5 @@
 /*
- * Zoran 364xx based USB webcam module version 0.72
+ * Zoran 364xx based USB webcam module version 0.73
  *
  * Allows you to use your USB webcam with V4L2 applications
  * This is still in heavy developpement !
@@ -10,6 +10,8 @@
  * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers
  * V4L2 version inspired by meye.c driver
  *
+ * Some video buffer code by Lamarque based on s2255drv.c and vivi.c drivers.
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -27,6 +29,7 @@
 
 
 #include <linux/module.h>
+#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/usb.h>
 #include <linux/vmalloc.h>
@@ -35,24 +38,40 @@
 #include <linux/highmem.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/videobuf-vmalloc.h>
 
 
 /* Version Information */
-#define DRIVER_VERSION "v0.72"
+#define DRIVER_VERSION "v0.73"
+#define ZR364XX_VERSION_CODE KERNEL_VERSION(0, 7, 3)
 #define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
 #define DRIVER_DESC "Zoran 364xx"
 
 
 /* Camera */
-#define FRAMES 2
-#define MAX_FRAME_SIZE 100000
+#define FRAMES 1
+#define MAX_FRAME_SIZE 200000
 #define BUFFER_SIZE 0x1000
 #define CTRL_TIMEOUT 500
 
+#define ZR364XX_DEF_BUFS	4
+#define ZR364XX_READ_IDLE	0
+#define ZR364XX_READ_FRAME	1
 
 /* Debug macro */
-#define DBG(x...) if (debug) printk(KERN_INFO KBUILD_MODNAME x)
-
+#define DBG(fmt, args...) \
+	do { \
+		if (debug) { \
+			printk(KERN_INFO KBUILD_MODNAME " " fmt, ##args); \
+		} \
+	} while (0)
+
+/*#define FULL_DEBUG 1*/
+#ifdef FULL_DEBUG
+#define _DBG DBG
+#else
+#define _DBG(fmt, args...)
+#endif
 
 /* Init methods, need to find nicer names for these
  * the exact names of the chipsets would be the best if someone finds it */
@@ -101,24 +120,93 @@ static struct usb_device_id device_table[] = {
 
 MODULE_DEVICE_TABLE(usb, device_table);
 
+struct zr364xx_mode {
+	u32 color;	/* output video color format */
+	u32 brightness;	/* brightness */
+};
+
+/* frame structure */
+struct zr364xx_framei {
+	unsigned long ulState;	/* ulState:ZR364XX_READ_IDLE,
+					   ZR364XX_READ_FRAME */
+	void *lpvbits;		/* image data */
+	unsigned long cur_size;	/* current data copied to it */
+};
+
+/* image buffer structure */
+struct zr364xx_bufferi {
+	unsigned long dwFrames;			/* number of frames in buffer */
+	struct zr364xx_framei frame[FRAMES];	/* array of FRAME structures */
+};
+
+struct zr364xx_dmaqueue {
+	struct list_head	active;
+	struct zr364xx_camera	*cam;
+};
+
+struct zr364xx_pipeinfo {
+	u32 transfer_size;
+	u8 *transfer_buffer;
+	u32 state;
+	void *stream_urb;
+	void *cam;	/* back pointer to zr364xx_camera struct */
+	u32 err_count;
+	u32 idx;
+};
+
+struct zr364xx_fmt {
+	char *name;
+	u32 fourcc;
+	int depth;
+};
+
+/* image formats.  */
+static const struct zr364xx_fmt formats[] = {
+	{
+		.name = "JPG",
+		.fourcc = V4L2_PIX_FMT_JPEG,
+		.depth = 24
+	}
+};
 
 /* Camera stuff */
 struct zr364xx_camera {
 	struct usb_device *udev;	/* save off the usb device pointer */
 	struct usb_interface *interface;/* the interface for this device */
 	struct video_device *vdev;	/* v4l video device */
-	u8 *framebuf;
 	int nb;
-	unsigned char *buffer;
+	struct zr364xx_bufferi		buffer;
 	int skip;
-	int brightness;
 	int width;
 	int height;
 	int method;
 	struct mutex lock;
+	struct mutex open_lock;
 	int users;
+
+	spinlock_t		slock;
+	struct zr364xx_dmaqueue	vidq;
+	int			resources;
+	int			last_frame;
+	int			cur_frame;
+	unsigned long		frame_count;
+	int			b_acquire;
+	struct zr364xx_pipeinfo	pipe[1];
+
+	u8			read_endpoint;
+
+	const struct zr364xx_fmt *fmt;
+	struct videobuf_queue	vb_vidq;
+	enum v4l2_buf_type	type;
+	struct zr364xx_mode	mode;
 };
 
+/* buffer for one video frame */
+struct zr364xx_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer vb;
+	const struct zr364xx_fmt *fmt;
+};
 
 /* function used to send initialisation commands to the camera */
 static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
@@ -272,139 +360,116 @@ static unsigned char header2[] = {
 };
 static unsigned char header3;
 
+/* ------------------------------------------------------------------
+   Videobuf operations
+   ------------------------------------------------------------------*/
 
+static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+			unsigned int *size)
+{
+	struct zr364xx_camera *cam = vq->priv_data;
 
-/********************/
-/* V4L2 integration */
-/********************/
+	*size = cam->width * cam->height * (cam->fmt->depth >> 3);
 
-/* this function reads a full JPEG picture synchronously
- * TODO: do it asynchronously... */
-static int read_frame(struct zr364xx_camera *cam, int framenum)
-{
-	int i, n, temp, head, size, actual_length;
-	unsigned char *ptr = NULL, *jpeg;
-
-      redo:
-	/* hardware brightness */
-	n = send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
-	temp = (0x60 << 8) + 127 - cam->brightness;
-	n = send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
-
-	/* during the first loop we are going to insert JPEG header */
-	head = 0;
-	/* this is the place in memory where we are going to build
-	 * the JPEG image */
-	jpeg = cam->framebuf + framenum * MAX_FRAME_SIZE;
-	/* read data... */
-	do {
-		n = usb_bulk_msg(cam->udev,
-				 usb_rcvbulkpipe(cam->udev, 0x81),
-				 cam->buffer, BUFFER_SIZE, &actual_length,
-				 CTRL_TIMEOUT);
-		DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]);
-		DBG("bulk : n=%d size=%d", n, actual_length);
-		if (n < 0) {
-			dev_err(&cam->udev->dev, "error reading bulk msg\n");
-			return 0;
-		}
-		if (actual_length < 0 || actual_length > BUFFER_SIZE) {
-			dev_err(&cam->udev->dev, "wrong number of bytes\n");
-			return 0;
-		}
+	if (*count == 0)
+		*count = ZR364XX_DEF_BUFS;
 
-		/* swap bytes if camera needs it */
-		if (cam->method == METHOD0) {
-			u16 *buf = (u16*)cam->buffer;
-			for (i = 0; i < BUFFER_SIZE/2; i++)
-				swab16s(buf + i);
-		}
+	while (*size * (*count) > ZR364XX_DEF_BUFS * 1024 * 1024)
+		(*count)--;
 
-		/* write the JPEG header */
-		if (!head) {
-			DBG("jpeg header");
-			ptr = jpeg;
-			memcpy(ptr, header1, sizeof(header1));
-			ptr += sizeof(header1);
-			header3 = 0;
-			memcpy(ptr, &header3, 1);
-			ptr++;
-			memcpy(ptr, cam->buffer, 64);
-			ptr += 64;
-			header3 = 1;
-			memcpy(ptr, &header3, 1);
-			ptr++;
-			memcpy(ptr, cam->buffer + 64, 64);
-			ptr += 64;
-			memcpy(ptr, header2, sizeof(header2));
-			ptr += sizeof(header2);
-			memcpy(ptr, cam->buffer + 128,
-			       actual_length - 128);
-			ptr += actual_length - 128;
-			head = 1;
-			DBG("header : %d %d %d %d %d %d %d %d %d",
-			    cam->buffer[0], cam->buffer[1], cam->buffer[2],
-			    cam->buffer[3], cam->buffer[4], cam->buffer[5],
-			    cam->buffer[6], cam->buffer[7], cam->buffer[8]);
-		} else {
-			memcpy(ptr, cam->buffer, actual_length);
-			ptr += actual_length;
-		}
-	}
-	/* ... until there is no more */
-	while (actual_length == BUFFER_SIZE);
+	return 0;
+}
 
-	/* we skip the 2 first frames which are usually buggy */
-	if (cam->skip) {
-		cam->skip--;
-		goto redo;
-	}
+static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf)
+{
+	_DBG("%s\n", __func__);
 
-	/* go back to find the JPEG EOI marker */
-	size = ptr - jpeg;
-	ptr -= 2;
-	while (ptr > jpeg) {
-		if (*ptr == 0xFF && *(ptr + 1) == 0xD9
-		    && *(ptr + 2) == 0xFF)
-			break;
-		ptr--;
-	}
-	if (ptr == jpeg)
-		DBG("No EOI marker");
+	if (in_interrupt())
+		BUG();
 
-	/* Sometimes there is junk data in the middle of the picture,
-	 * we want to skip this bogus frames */
-	while (ptr > jpeg) {
-		if (*ptr == 0xFF && *(ptr + 1) == 0xFF
-		    && *(ptr + 2) == 0xFF)
-			break;
-		ptr--;
+	videobuf_vmalloc_free(&buf->vb);
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+			  enum v4l2_field field)
+{
+	struct zr364xx_camera *cam = vq->priv_data;
+	struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
+						  vb);
+	int rc;
+
+	DBG("%s, field=%d, fmt name = %s\n", __func__, field, cam->fmt != NULL ?
+	    cam->fmt->name : "");
+	if (cam->fmt == NULL)
+		return -EINVAL;
+
+	buf->vb.size = cam->width * cam->height * (cam->fmt->depth >> 3);
+
+	if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) {
+		DBG("invalid buffer prepare\n");
+		return -EINVAL;
 	}
-	if (ptr != jpeg) {
-		DBG("Bogus frame ? %d", cam->nb);
-		goto redo;
+
+	buf->fmt = cam->fmt;
+	buf->vb.width = cam->width;
+	buf->vb.height = cam->height;
+	buf->vb.field = field;
+
+	if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
+		rc = videobuf_iolock(vq, &buf->vb, NULL);
+		if (rc < 0)
+			goto fail;
 	}
 
-	DBG("jpeg : %d %d %d %d %d %d %d %d",
-	    jpeg[0], jpeg[1], jpeg[2], jpeg[3],
-	    jpeg[4], jpeg[5], jpeg[6], jpeg[7]);
+	buf->vb.state = VIDEOBUF_PREPARED;
+	return 0;
+fail:
+	free_buffer(vq, buf);
+	return rc;
+}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
+						  vb);
+	struct zr364xx_camera *cam = vq->priv_data;
+
+	_DBG("%s\n", __func__);
+
+	buf->vb.state = VIDEOBUF_QUEUED;
+	list_add_tail(&buf->vb.queue, &cam->vidq.active);
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+			   struct videobuf_buffer *vb)
+{
+	struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
+						  vb);
 
-	return size;
+	_DBG("%s\n", __func__);
+	free_buffer(vq, buf);
 }
 
+static struct videobuf_queue_ops zr364xx_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+/********************/
+/* V4L2 integration */
+/********************/
+static int zr364xx_vidioc_streamon(struct file *file, void *priv,
+				   enum v4l2_buf_type type);
 
-static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
+static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count,
 			    loff_t * ppos)
 {
-	unsigned long count = cnt;
-	struct video_device *vdev = video_devdata(file);
-	struct zr364xx_camera *cam;
+	struct zr364xx_camera *cam = video_drvdata(file);
 
-	DBG("zr364xx_read: read %d bytes.", (int) count);
-
-	if (vdev == NULL)
-		return -ENODEV;
-	cam = video_get_drvdata(vdev);
+	_DBG("%s\n", __func__);
 
 	if (!buf)
 		return -EINVAL;
@@ -412,21 +477,276 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
 	if (!count)
 		return -EINVAL;
 
-	/* NoMan Sux ! */
-	count = read_frame(cam, 0);
+	if (cam->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+	    zr364xx_vidioc_streamon(file, cam, cam->type) == 0) {
+		DBG("%s: reading %d bytes at pos %d.\n", __func__, (int) count,
+		    (int) *ppos);
+
+		/* NoMan Sux ! */
+		return videobuf_read_one(&cam->vb_vidq, buf, count, ppos,
+					file->f_flags & O_NONBLOCK);
+	}
+
+	return 0;
+}
+
+/* video buffer vmalloc implementation based partly on VIVI driver which is
+ *          Copyright (c) 2006 by
+ *                  Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
+ *                  Ted Walther <ted--a.t--enumera.com>
+ *                  John Sokol <sokol--a.t--videotechnology.com>
+ *                  http://v4l.videotechnology.com/
+ *
+ */
+static void zr364xx_fillbuff(struct zr364xx_camera *cam,
+			     struct zr364xx_buffer *buf,
+			     int jpgsize)
+{
+	int pos = 0;
+	struct timeval ts;
+	const char *tmpbuf;
+	char *vbuf = videobuf_to_vmalloc(&buf->vb);
+	unsigned long last_frame;
+	struct zr364xx_framei *frm;
+
+	if (!vbuf)
+		return;
+
+	last_frame = cam->last_frame;
+	if (last_frame != -1) {
+		frm = &cam->buffer.frame[last_frame];
+		tmpbuf = (const char *)cam->buffer.frame[last_frame].lpvbits;
+		switch (buf->fmt->fourcc) {
+		case V4L2_PIX_FMT_JPEG:
+			buf->vb.size = jpgsize;
+			memcpy(vbuf, tmpbuf, buf->vb.size);
+			break;
+		default:
+			printk(KERN_DEBUG KBUILD_MODNAME ": unknown format?\n");
+		}
+		cam->last_frame = -1;
+	} else {
+		printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n");
+		return;
+	}
+	DBG("%s: Buffer 0x%08lx size= %d\n", __func__,
+		(unsigned long)vbuf, pos);
+	/* tell v4l buffer was filled */
+
+	buf->vb.field_count = cam->frame_count * 2;
+	do_gettimeofday(&ts);
+	buf->vb.ts = ts;
+	buf->vb.state = VIDEOBUF_DONE;
+}
+
+static int zr364xx_got_frame(struct zr364xx_camera *cam, int jpgsize)
+{
+	struct zr364xx_dmaqueue *dma_q = &cam->vidq;
+	struct zr364xx_buffer *buf;
+	unsigned long flags = 0;
+	int rc = 0;
+
+	DBG("wakeup: %p\n", &dma_q);
+	spin_lock_irqsave(&cam->slock, flags);
+
+	if (list_empty(&dma_q->active)) {
+		DBG("No active queue to serve\n");
+		rc = -1;
+		goto unlock;
+	}
+	buf = list_entry(dma_q->active.next,
+			 struct zr364xx_buffer, vb.queue);
+
+	if (!waitqueue_active(&buf->vb.done)) {
+		/* no one active */
+		rc = -1;
+		goto unlock;
+	}
+	list_del(&buf->vb.queue);
+	do_gettimeofday(&buf->vb.ts);
+	DBG("[%p/%d] wakeup\n", buf, buf->vb.i);
+	zr364xx_fillbuff(cam, buf, jpgsize);
+	wake_up(&buf->vb.done);
+	DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
+unlock:
+	spin_unlock_irqrestore(&cam->slock, flags);
+	return 0;
+}
+
+/* this function moves the usb stream read pipe data
+ * into the system buffers.
+ * returns 0 on success, EAGAIN if more data to process (call this
+ * function again).
+ */
+static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
+					struct zr364xx_pipeinfo *pipe_info,
+					struct urb *purb)
+{
+	unsigned char *pdest;
+	unsigned char *psrc;
+	s32 idx = -1;
+	struct zr364xx_framei *frm;
+	int i = 0;
+	unsigned char *ptr = NULL;
+
+	_DBG("buffer to user\n");
+	idx = cam->cur_frame;
+	frm = &cam->buffer.frame[idx];
+
+	/* swap bytes if camera needs it */
+	if (cam->method == METHOD0) {
+		u16 *buf = (u16 *)pipe_info->transfer_buffer;
+		for (i = 0; i < purb->actual_length/2; i++)
+			swab16s(buf + i);
+	}
+
+	/* search done.  now find out if should be acquiring */
+	if (!cam->b_acquire) {
+		/* we found a frame, but this channel is turned off */
+		frm->ulState = ZR364XX_READ_IDLE;
+		return -EINVAL;
+	}
+
+	psrc = (u8 *)pipe_info->transfer_buffer;
+	ptr = pdest = frm->lpvbits;
+
+	if (frm->ulState == ZR364XX_READ_IDLE) {
+		frm->ulState = ZR364XX_READ_FRAME;
+		frm->cur_size = 0;
+
+		_DBG("jpeg header, ");
+		memcpy(ptr, header1, sizeof(header1));
+		ptr += sizeof(header1);
+		header3 = 0;
+		memcpy(ptr, &header3, 1);
+		ptr++;
+		memcpy(ptr, psrc, 64);
+		ptr += 64;
+		header3 = 1;
+		memcpy(ptr, &header3, 1);
+		ptr++;
+		memcpy(ptr, psrc + 64, 64);
+		ptr += 64;
+		memcpy(ptr, header2, sizeof(header2));
+		ptr += sizeof(header2);
+		memcpy(ptr, psrc + 128,
+		       purb->actual_length - 128);
+		ptr += purb->actual_length - 128;
+		_DBG("header : %d %d %d %d %d %d %d %d %d\n",
+		    psrc[0], psrc[1], psrc[2],
+		    psrc[3], psrc[4], psrc[5],
+		    psrc[6], psrc[7], psrc[8]);
+		frm->cur_size = ptr - pdest;
+	} else {
+		if (frm->cur_size + purb->actual_length > MAX_FRAME_SIZE) {
+			dev_info(&cam->udev->dev,
+				 "%s: buffer (%d bytes) too small to hold "
+				 "frame data. Discarding frame data.\n",
+				 __func__, MAX_FRAME_SIZE);
+		} else {
+			pdest += frm->cur_size;
+			memcpy(pdest, psrc, purb->actual_length);
+			frm->cur_size += purb->actual_length;
+		}
+	}
+	/*_DBG("cur_size %lu urb size %d\n", frm->cur_size,
+		purb->actual_length);*/
+
+	if (purb->actual_length < pipe_info->transfer_size) {
+		_DBG("****************Buffer[%d]full*************\n", idx);
+		cam->last_frame = cam->cur_frame;
+		cam->cur_frame++;
+		/* end of system frame ring buffer, start at zero */
+		if (cam->cur_frame == cam->buffer.dwFrames)
+			cam->cur_frame = 0;
+
+		/* frame ready */
+		/* go back to find the JPEG EOI marker */
+		ptr = pdest = frm->lpvbits;
+		ptr += frm->cur_size - 2;
+		while (ptr > pdest) {
+			if (*ptr == 0xFF && *(ptr + 1) == 0xD9
+			    && *(ptr + 2) == 0xFF)
+				break;
+			ptr--;
+		}
+		if (ptr == pdest)
+			DBG("No EOI marker\n");
+
+		/* Sometimes there is junk data in the middle of the picture,
+		 * we want to skip this bogus frames */
+		while (ptr > pdest) {
+			if (*ptr == 0xFF && *(ptr + 1) == 0xFF
+			    && *(ptr + 2) == 0xFF)
+				break;
+			ptr--;
+		}
+		if (ptr != pdest) {
+			DBG("Bogus frame ? %d\n", ++(cam->nb));
+		} else if (cam->b_acquire) {
+			/* we skip the 2 first frames which are usually buggy */
+			if (cam->skip)
+				cam->skip--;
+			else {
+				_DBG("jpeg(%lu): %d %d %d %d %d %d %d %d\n",
+				    frm->cur_size,
+				    pdest[0], pdest[1], pdest[2], pdest[3],
+				    pdest[4], pdest[5], pdest[6], pdest[7]);
+
+				zr364xx_got_frame(cam, frm->cur_size);
+			}
+		}
+		cam->frame_count++;
+		frm->ulState = ZR364XX_READ_IDLE;
+		frm->cur_size = 0;
+	}
+	/* done successfully */
+	return 0;
+}
 
-	if (copy_to_user(buf, cam->framebuf, count))
-		return -EFAULT;
+static int res_get(struct zr364xx_camera *cam)
+{
+	/* is it free? */
+	mutex_lock(&cam->lock);
+	if (cam->resources) {
+		/* no, someone else uses it */
+		mutex_unlock(&cam->lock);
+		return 0;
+	}
+	/* it's free, grab it */
+	cam->resources = 1;
+	_DBG("res: get\n");
+	mutex_unlock(&cam->lock);
+	return 1;
+}
 
-	return count;
+static inline int res_check(struct zr364xx_camera *cam)
+{
+	return cam->resources;
 }
 
+static void res_free(struct zr364xx_camera *cam)
+{
+	mutex_lock(&cam->lock);
+	cam->resources = 0;
+	mutex_unlock(&cam->lock);
+	_DBG("res: put\n");
+}
 
 static int zr364xx_vidioc_querycap(struct file *file, void *priv,
 				   struct v4l2_capability *cap)
 {
-	strcpy(cap->driver, DRIVER_DESC);
-	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
+	struct zr364xx_camera *cam = video_drvdata(file);
+
+	strlcpy(cap->driver, DRIVER_DESC, sizeof(cap->driver));
+	strlcpy(cap->card, cam->udev->product, sizeof(cap->card));
+	strlcpy(cap->bus_info, dev_name(&cam->udev->dev),
+		sizeof(cap->bus_info));
+	cap->version = ZR364XX_VERSION_CODE;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+			    V4L2_CAP_READWRITE |
+			    V4L2_CAP_STREAMING;
+
 	return 0;
 }
 
@@ -458,12 +778,11 @@ static int zr364xx_vidioc_s_input(struct file *file, void *priv,
 static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
 				    struct v4l2_queryctrl *c)
 {
-	struct video_device *vdev = video_devdata(file);
 	struct zr364xx_camera *cam;
 
-	if (vdev == NULL)
+	if (file == NULL)
 		return -ENODEV;
-	cam = video_get_drvdata(vdev);
+	cam = video_drvdata(file);
 
 	switch (c->id) {
 	case V4L2_CID_BRIGHTNESS:
@@ -472,7 +791,7 @@ static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
 		c->minimum = 0;
 		c->maximum = 127;
 		c->step = 1;
-		c->default_value = cam->brightness;
+		c->default_value = cam->mode.brightness;
 		c->flags = 0;
 		break;
 	default:
@@ -484,36 +803,42 @@ static int zr364xx_vidioc_queryctrl(struct file *file, void *priv,
 static int zr364xx_vidioc_s_ctrl(struct file *file, void *priv,
 				 struct v4l2_control *c)
 {
-	struct video_device *vdev = video_devdata(file);
 	struct zr364xx_camera *cam;
+	int temp;
 
-	if (vdev == NULL)
+	if (file == NULL)
 		return -ENODEV;
-	cam = video_get_drvdata(vdev);
+	cam = video_drvdata(file);
 
 	switch (c->id) {
 	case V4L2_CID_BRIGHTNESS:
-		cam->brightness = c->value;
+		cam->mode.brightness = c->value;
+		/* hardware brightness */
+		mutex_lock(&cam->lock);
+		send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
+		temp = (0x60 << 8) + 127 - cam->mode.brightness;
+		send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
+		mutex_unlock(&cam->lock);
 		break;
 	default:
 		return -EINVAL;
 	}
+
 	return 0;
 }
 
 static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv,
 				 struct v4l2_control *c)
 {
-	struct video_device *vdev = video_devdata(file);
 	struct zr364xx_camera *cam;
 
-	if (vdev == NULL)
+	if (file == NULL)
 		return -ENODEV;
-	cam = video_get_drvdata(vdev);
+	cam = video_drvdata(file);
 
 	switch (c->id) {
 	case V4L2_CID_BRIGHTNESS:
-		c->value = cam->brightness;
+		c->value = cam->mode.brightness;
 		break;
 	default:
 		return -EINVAL;
@@ -527,47 +852,63 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
 	if (f->index > 0)
 		return -EINVAL;
 	f->flags = V4L2_FMT_FLAG_COMPRESSED;
-	strcpy(f->description, "JPEG");
-	f->pixelformat = V4L2_PIX_FMT_JPEG;
+	strcpy(f->description, formats[0].name);
+	f->pixelformat = formats[0].fourcc;
 	return 0;
 }
 
+static char *decode_fourcc(__u32 pixelformat, char *buf)
+{
+	buf[0] = pixelformat & 0xff;
+	buf[1] = (pixelformat >> 8) & 0xff;
+	buf[2] = (pixelformat >> 16) & 0xff;
+	buf[3] = (pixelformat >> 24) & 0xff;
+	buf[4] = '\0';
+	return buf;
+}
+
 static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 				      struct v4l2_format *f)
 {
-	struct video_device *vdev = video_devdata(file);
-	struct zr364xx_camera *cam;
+	struct zr364xx_camera *cam = video_drvdata(file);
+	char pixelformat_name[5];
 
-	if (vdev == NULL)
+	if (cam == NULL)
 		return -ENODEV;
-	cam = video_get_drvdata(vdev);
 
-	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
-		return -EINVAL;
-	if (f->fmt.pix.field != V4L2_FIELD_ANY &&
-	    f->fmt.pix.field != V4L2_FIELD_NONE)
+	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) {
+		DBG("%s: unsupported pixelformat V4L2_PIX_FMT_%s\n", __func__,
+		    decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name));
 		return -EINVAL;
+	}
+
+	if (!(f->fmt.pix.width == 160 && f->fmt.pix.height == 120) &&
+	    !(f->fmt.pix.width == 640 && f->fmt.pix.height == 480)) {
+		f->fmt.pix.width = 320;
+		f->fmt.pix.height = 240;
+	}
+
 	f->fmt.pix.field = V4L2_FIELD_NONE;
-	f->fmt.pix.width = cam->width;
-	f->fmt.pix.height = cam->height;
 	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
 	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 	f->fmt.pix.colorspace = 0;
 	f->fmt.pix.priv = 0;
+	DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
+	    decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
+	    f->fmt.pix.field);
 	return 0;
 }
 
 static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 				    struct v4l2_format *f)
 {
-	struct video_device *vdev = video_devdata(file);
 	struct zr364xx_camera *cam;
 
-	if (vdev == NULL)
+	if (file == NULL)
 		return -ENODEV;
-	cam = video_get_drvdata(vdev);
+	cam = video_drvdata(file);
 
-	f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
+	f->fmt.pix.pixelformat = formats[0].fourcc;
 	f->fmt.pix.field = V4L2_FIELD_NONE;
 	f->fmt.pix.width = cam->width;
 	f->fmt.pix.height = cam->height;
@@ -581,38 +922,327 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 				    struct v4l2_format *f)
 {
-	struct video_device *vdev = video_devdata(file);
-	struct zr364xx_camera *cam;
+	struct zr364xx_camera *cam = video_drvdata(file);
+	struct videobuf_queue *q = &cam->vb_vidq;
+	char pixelformat_name[5];
+	int ret = zr364xx_vidioc_try_fmt_vid_cap(file, cam, f);
+	int i;
 
-	if (vdev == NULL)
-		return -ENODEV;
-	cam = video_get_drvdata(vdev);
+	if (ret < 0)
+		return ret;
 
-	if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
-		return -EINVAL;
-	if (f->fmt.pix.field != V4L2_FIELD_ANY &&
-	    f->fmt.pix.field != V4L2_FIELD_NONE)
-		return -EINVAL;
-	f->fmt.pix.field = V4L2_FIELD_NONE;
-	f->fmt.pix.width = cam->width;
-	f->fmt.pix.height = cam->height;
+	mutex_lock(&q->vb_lock);
+
+	if (videobuf_queue_is_busy(&cam->vb_vidq)) {
+		DBG("%s queue busy\n", __func__);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	if (res_check(cam)) {
+		DBG("%s can't change format after started\n", __func__);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	cam->width = f->fmt.pix.width;
+	cam->height = f->fmt.pix.height;
+	dev_info(&cam->udev->dev, "%s: %dx%d mode selected\n", __func__,
+		 cam->width, cam->height);
 	f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
 	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 	f->fmt.pix.colorspace = 0;
 	f->fmt.pix.priv = 0;
-	DBG("ok!");
+	cam->vb_vidq.field = f->fmt.pix.field;
+	cam->mode.color = V4L2_PIX_FMT_JPEG;
+
+	if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
+		mode = 1;
+	else if (f->fmt.pix.width == 640 && f->fmt.pix.height == 480)
+		mode = 2;
+	else
+		mode = 0;
+
+	m0d1[0] = mode;
+	m1[2].value = 0xf000 + mode;
+	m2[1].value = 0xf000 + mode;
+	header2[437] = cam->height / 256;
+	header2[438] = cam->height % 256;
+	header2[439] = cam->width / 256;
+	header2[440] = cam->width % 256;
+
+	for (i = 0; init[cam->method][i].size != -1; i++) {
+		ret =
+		    send_control_msg(cam->udev, 1, init[cam->method][i].value,
+				     0, init[cam->method][i].bytes,
+				     init[cam->method][i].size);
+		if (ret < 0) {
+			dev_err(&cam->udev->dev,
+			   "error during resolution change sequence: %d\n", i);
+			goto out;
+		}
+	}
+
+	/* Added some delay here, since opening/closing the camera quickly,
+	 * like Ekiga does during its startup, can crash the webcam
+	 */
+	mdelay(100);
+	cam->skip = 2;
+	ret = 0;
+
+out:
+	mutex_unlock(&q->vb_lock);
+
+	DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
+	    decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
+	    f->fmt.pix.field);
+	return ret;
+}
+
+static int zr364xx_vidioc_reqbufs(struct file *file, void *priv,
+			  struct v4l2_requestbuffers *p)
+{
+	int rc;
+	struct zr364xx_camera *cam = video_drvdata(file);
+	rc = videobuf_reqbufs(&cam->vb_vidq, p);
+	return rc;
+}
+
+static int zr364xx_vidioc_querybuf(struct file *file,
+				void *priv,
+				struct v4l2_buffer *p)
+{
+	int rc;
+	struct zr364xx_camera *cam = video_drvdata(file);
+	rc = videobuf_querybuf(&cam->vb_vidq, p);
+	return rc;
+}
+
+static int zr364xx_vidioc_qbuf(struct file *file,
+				void *priv,
+				struct v4l2_buffer *p)
+{
+	int rc;
+	struct zr364xx_camera *cam = video_drvdata(file);
+	_DBG("%s\n", __func__);
+	rc = videobuf_qbuf(&cam->vb_vidq, p);
+	return rc;
+}
+
+static int zr364xx_vidioc_dqbuf(struct file *file,
+				void *priv,
+				struct v4l2_buffer *p)
+{
+	int rc;
+	struct zr364xx_camera *cam = video_drvdata(file);
+	_DBG("%s\n", __func__);
+	rc = videobuf_dqbuf(&cam->vb_vidq, p, file->f_flags & O_NONBLOCK);
+	return rc;
+}
+
+static void read_pipe_completion(struct urb *purb)
+{
+	struct zr364xx_pipeinfo *pipe_info;
+	struct zr364xx_camera *cam;
+	int pipe;
+
+	pipe_info = purb->context;
+	_DBG("%s %p, status %d\n", __func__, purb, purb->status);
+	if (pipe_info == NULL) {
+		printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
+		return;
+	}
+
+	cam = pipe_info->cam;
+	if (cam == NULL) {
+		printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
+		return;
+	}
+
+	/* if shutting down, do not resubmit, exit immediately */
+	if (purb->status == -ESHUTDOWN) {
+		DBG("%s, err shutdown\n", __func__);
+		pipe_info->err_count++;
+		return;
+	}
+
+	if (pipe_info->state == 0) {
+		DBG("exiting USB pipe\n");
+		return;
+	}
+
+	if (purb->actual_length < 0 ||
+	    purb->actual_length > pipe_info->transfer_size) {
+		dev_err(&cam->udev->dev, "wrong number of bytes\n");
+		return;
+	}
+
+	if (purb->status == 0)
+		zr364xx_read_video_callback(cam, pipe_info, purb);
+	else {
+		pipe_info->err_count++;
+		DBG("%s: failed URB %d\n", __func__, purb->status);
+	}
+
+	pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
+
+	/* reuse urb */
+	usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
+			  pipe,
+			  pipe_info->transfer_buffer,
+			  pipe_info->transfer_size,
+			  read_pipe_completion, pipe_info);
+
+	if (pipe_info->state != 0) {
+		purb->status = usb_submit_urb(pipe_info->stream_urb,
+					      GFP_ATOMIC);
+
+		if (purb->status)
+			dev_err(&cam->udev->dev,
+				"error submitting urb (error=%i)\n",
+				purb->status);
+	} else
+		DBG("read pipe complete state 0\n");
+}
+
+static int zr364xx_start_readpipe(struct zr364xx_camera *cam)
+{
+	int pipe;
+	int retval;
+	struct zr364xx_pipeinfo *pipe_info = cam->pipe;
+	pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
+	DBG("%s: start pipe IN x%x\n", __func__, cam->read_endpoint);
+
+	pipe_info->state = 1;
+	pipe_info->err_count = 0;
+	pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!pipe_info->stream_urb) {
+		dev_err(&cam->udev->dev, "ReadStream: Unable to alloc URB\n");
+		return -ENOMEM;
+	}
+	/* transfer buffer allocated in board_init */
+	usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
+			  pipe,
+			  pipe_info->transfer_buffer,
+			  pipe_info->transfer_size,
+			  read_pipe_completion, pipe_info);
+
+	DBG("submitting URB %p\n", pipe_info->stream_urb);
+	retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
+	if (retval) {
+		printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n");
+		return retval;
+	}
+
+	return 0;
+}
+
+static void zr364xx_stop_readpipe(struct zr364xx_camera *cam)
+{
+	struct zr364xx_pipeinfo *pipe_info;
+
+	if (cam == NULL) {
+		printk(KERN_ERR KBUILD_MODNAME ": invalid device\n");
+		return;
+	}
+	DBG("stop read pipe\n");
+	pipe_info = cam->pipe;
+	if (pipe_info) {
+		if (pipe_info->state != 0)
+			pipe_info->state = 0;
+
+		if (pipe_info->stream_urb) {
+			/* cancel urb */
+			usb_kill_urb(pipe_info->stream_urb);
+			usb_free_urb(pipe_info->stream_urb);
+			pipe_info->stream_urb = NULL;
+		}
+	}
+	return;
+}
+
+/* starts acquisition process */
+static int zr364xx_start_acquire(struct zr364xx_camera *cam)
+{
+	int j;
+
+	DBG("start acquire\n");
+
+	cam->last_frame = -1;
+	cam->cur_frame = 0;
+	for (j = 0; j < FRAMES; j++) {
+		cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
+		cam->buffer.frame[j].cur_size = 0;
+	}
+	cam->b_acquire = 1;
+	return 0;
+}
+
+static inline int zr364xx_stop_acquire(struct zr364xx_camera *cam)
+{
+	cam->b_acquire = 0;
 	return 0;
 }
 
 static int zr364xx_vidioc_streamon(struct file *file, void *priv,
 				   enum v4l2_buf_type type)
 {
-	return 0;
+	struct zr364xx_camera *cam = video_drvdata(file);
+	int j;
+	int res;
+
+	DBG("%s\n", __func__);
+
+	if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		dev_err(&cam->udev->dev, "invalid fh type0\n");
+		return -EINVAL;
+	}
+	if (cam->type != type) {
+		dev_err(&cam->udev->dev, "invalid fh type1\n");
+		return -EINVAL;
+	}
+
+	if (!res_get(cam)) {
+		dev_err(&cam->udev->dev, "stream busy\n");
+		return -EBUSY;
+	}
+
+	cam->last_frame = -1;
+	cam->cur_frame = 0;
+	cam->frame_count = 0;
+	for (j = 0; j < FRAMES; j++) {
+		cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
+		cam->buffer.frame[j].cur_size = 0;
+	}
+	res = videobuf_streamon(&cam->vb_vidq);
+	if (res == 0) {
+		zr364xx_start_acquire(cam);
+	} else {
+		res_free(cam);
+	}
+	return res;
 }
 
 static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
 				    enum v4l2_buf_type type)
 {
+	int res;
+	struct zr364xx_camera *cam = video_drvdata(file);
+
+	DBG("%s\n", __func__);
+	if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		dev_err(&cam->udev->dev, "invalid fh type0\n");
+		return -EINVAL;
+	}
+	if (cam->type != type) {
+		dev_err(&cam->udev->dev, "invalid fh type1\n");
+		return -EINVAL;
+	}
+	zr364xx_stop_acquire(cam);
+	res = videobuf_streamoff(&cam->vb_vidq);
+	if (res < 0)
+		return res;
+	res_free(cam);
 	return 0;
 }
 
@@ -621,28 +1251,19 @@ static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
 static int zr364xx_open(struct file *file)
 {
 	struct video_device *vdev = video_devdata(file);
-	struct zr364xx_camera *cam = video_get_drvdata(vdev);
+	struct zr364xx_camera *cam = video_drvdata(file);
 	struct usb_device *udev = cam->udev;
 	int i, err;
 
-	DBG("zr364xx_open");
+	DBG("%s\n", __func__);
 
-	mutex_lock(&cam->lock);
+	mutex_lock(&cam->open_lock);
 
 	if (cam->users) {
 		err = -EBUSY;
 		goto out;
 	}
 
-	if (!cam->framebuf) {
-		cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
-		if (!cam->framebuf) {
-			dev_err(&cam->udev->dev, "vmalloc_32 failed!\n");
-			err = -ENOMEM;
-			goto out;
-		}
-	}
-
 	for (i = 0; init[cam->method][i].size != -1; i++) {
 		err =
 		    send_control_msg(udev, 1, init[cam->method][i].value,
@@ -658,6 +1279,14 @@ static int zr364xx_open(struct file *file)
 	cam->skip = 2;
 	cam->users++;
 	file->private_data = vdev;
+	cam->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	cam->fmt = formats;
+
+	videobuf_queue_vmalloc_init(&cam->vb_vidq, &zr364xx_video_qops,
+				    NULL, &cam->slock,
+				    cam->type,
+				    V4L2_FIELD_NONE,
+				    sizeof(struct zr364xx_buffer), cam);
 
 	/* Added some delay here, since opening/closing the camera quickly,
 	 * like Ekiga does during its startup, can crash the webcam
@@ -666,28 +1295,70 @@ static int zr364xx_open(struct file *file)
 	err = 0;
 
 out:
-	mutex_unlock(&cam->lock);
+	mutex_unlock(&cam->open_lock);
+	DBG("%s: %d\n", __func__, err);
 	return err;
 }
 
+static void zr364xx_destroy(struct zr364xx_camera *cam)
+{
+	unsigned long i;
+
+	if (!cam) {
+		printk(KERN_ERR KBUILD_MODNAME ", %s: no device\n", __func__);
+		return;
+	}
+	mutex_lock(&cam->open_lock);
+	if (cam->vdev)
+		video_unregister_device(cam->vdev);
+	cam->vdev = NULL;
+
+	/* stops the read pipe if it is running */
+	if (cam->b_acquire)
+		zr364xx_stop_acquire(cam);
+
+	zr364xx_stop_readpipe(cam);
+
+	/* release sys buffers */
+	for (i = 0; i < FRAMES; i++) {
+		if (cam->buffer.frame[i].lpvbits) {
+			DBG("vfree %p\n", cam->buffer.frame[i].lpvbits);
+			vfree(cam->buffer.frame[i].lpvbits);
+		}
+		cam->buffer.frame[i].lpvbits = NULL;
+	}
+
+	/* release transfer buffer */
+	kfree(cam->pipe->transfer_buffer);
+	cam->pipe->transfer_buffer = NULL;
+	mutex_unlock(&cam->open_lock);
+	kfree(cam);
+	cam = NULL;
+}
 
 /* release the camera */
 static int zr364xx_release(struct file *file)
 {
-	struct video_device *vdev = video_devdata(file);
 	struct zr364xx_camera *cam;
 	struct usb_device *udev;
 	int i, err;
 
-	DBG("zr364xx_release");
+	DBG("%s\n", __func__);
+	cam = video_drvdata(file);
 
-	if (vdev == NULL)
+	if (!cam)
 		return -ENODEV;
-	cam = video_get_drvdata(vdev);
 
+	mutex_lock(&cam->open_lock);
 	udev = cam->udev;
 
-	mutex_lock(&cam->lock);
+	/* turn off stream */
+	if (res_check(cam)) {
+		if (cam->b_acquire)
+			zr364xx_stop_acquire(cam);
+		videobuf_streamoff(&cam->vb_vidq);
+		res_free(cam);
+	}
 
 	cam->users--;
 	file->private_data = NULL;
@@ -710,40 +1381,43 @@ static int zr364xx_release(struct file *file)
 	err = 0;
 
 out:
-	mutex_unlock(&cam->lock);
+	mutex_unlock(&cam->open_lock);
+
 	return err;
 }
 
 
 static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	void *pos;
-	unsigned long start = vma->vm_start;
-	unsigned long size = vma->vm_end - vma->vm_start;
-	struct video_device *vdev = video_devdata(file);
-	struct zr364xx_camera *cam;
-
-	DBG("zr364xx_mmap: %ld\n", size);
+	struct zr364xx_camera *cam = video_drvdata(file);
+	int ret;
 
-	if (vdev == NULL)
+	if (cam == NULL) {
+		DBG("%s: cam == NULL\n", __func__);
 		return -ENODEV;
-	cam = video_get_drvdata(vdev);
-
-	pos = cam->framebuf;
-	while (size > 0) {
-		if (vm_insert_page(vma, start, vmalloc_to_page(pos)))
-			return -EAGAIN;
-		start += PAGE_SIZE;
-		pos += PAGE_SIZE;
-		if (size > PAGE_SIZE)
-			size -= PAGE_SIZE;
-		else
-			size = 0;
 	}
+	DBG("mmap called, vma=0x%08lx\n", (unsigned long)vma);
 
-	return 0;
+	ret = videobuf_mmap_mapper(&cam->vb_vidq, vma);
+
+	DBG("vma start=0x%08lx, size=%ld, ret=%d\n",
+		(unsigned long)vma->vm_start,
+		(unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
+	return ret;
 }
 
+static unsigned int zr364xx_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct zr364xx_camera *cam = video_drvdata(file);
+	struct videobuf_queue *q = &cam->vb_vidq;
+	_DBG("%s\n", __func__);
+
+	if (cam->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return POLLERR;
+
+	return videobuf_poll_stream(file, q, wait);
+}
 
 static const struct v4l2_file_operations zr364xx_fops = {
 	.owner = THIS_MODULE,
@@ -752,6 +1426,7 @@ static const struct v4l2_file_operations zr364xx_fops = {
 	.read = zr364xx_read,
 	.mmap = zr364xx_mmap,
 	.ioctl = video_ioctl2,
+	.poll = zr364xx_poll,
 };
 
 static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
@@ -768,6 +1443,10 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
 	.vidioc_queryctrl	= zr364xx_vidioc_queryctrl,
 	.vidioc_g_ctrl		= zr364xx_vidioc_g_ctrl,
 	.vidioc_s_ctrl		= zr364xx_vidioc_s_ctrl,
+	.vidioc_reqbufs         = zr364xx_vidioc_reqbufs,
+	.vidioc_querybuf        = zr364xx_vidioc_querybuf,
+	.vidioc_qbuf            = zr364xx_vidioc_qbuf,
+	.vidioc_dqbuf           = zr364xx_vidioc_dqbuf,
 };
 
 static struct video_device zr364xx_template = {
@@ -783,15 +1462,76 @@ static struct video_device zr364xx_template = {
 /*******************/
 /* USB integration */
 /*******************/
+static int zr364xx_board_init(struct zr364xx_camera *cam)
+{
+	struct zr364xx_pipeinfo *pipe = cam->pipe;
+	unsigned long i;
+
+	DBG("board init: %p\n", cam);
+	memset(pipe, 0, sizeof(*pipe));
+	pipe->cam = cam;
+	pipe->transfer_size = BUFFER_SIZE;
+
+	pipe->transfer_buffer = kzalloc(pipe->transfer_size,
+					GFP_KERNEL);
+	if (pipe->transfer_buffer == NULL) {
+		DBG("out of memory!\n");
+		return -ENOMEM;
+	}
+
+	cam->b_acquire = 0;
+	cam->frame_count = 0;
+
+	/*** start create system buffers ***/
+	for (i = 0; i < FRAMES; i++) {
+		/* always allocate maximum size for system buffers */
+		cam->buffer.frame[i].lpvbits = vmalloc(MAX_FRAME_SIZE);
+
+		DBG("valloc %p, idx %lu, pdata %p\n",
+			&cam->buffer.frame[i], i,
+			cam->buffer.frame[i].lpvbits);
+		if (cam->buffer.frame[i].lpvbits == NULL) {
+			printk(KERN_INFO KBUILD_MODNAME ": out of memory. "
+			       "Using less frames\n");
+			break;
+		}
+	}
+
+	if (i == 0) {
+		printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n");
+		kfree(cam->pipe->transfer_buffer);
+		cam->pipe->transfer_buffer = NULL;
+		return -ENOMEM;
+	} else
+		cam->buffer.dwFrames = i;
+
+	/* make sure internal states are set */
+	for (i = 0; i < FRAMES; i++) {
+		cam->buffer.frame[i].ulState = ZR364XX_READ_IDLE;
+		cam->buffer.frame[i].cur_size = 0;
+	}
+
+	cam->cur_frame = 0;
+	cam->last_frame = -1;
+	/*** end create system buffers ***/
+
+	/* start read pipe */
+	zr364xx_start_readpipe(cam);
+	DBG(": board initialized\n");
+	return 0;
+}
 
 static int zr364xx_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct zr364xx_camera *cam = NULL;
+	struct usb_host_interface *iface_desc;
+	struct usb_endpoint_descriptor *endpoint;
 	int err;
+	int i;
 
-	DBG("probing...");
+	DBG("probing...\n");
 
 	dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n");
 	dev_info(&intf->dev, "model %04x:%04x detected\n",
@@ -810,22 +1550,17 @@ static int zr364xx_probe(struct usb_interface *intf,
 	if (cam->vdev == NULL) {
 		dev_err(&udev->dev, "cam->vdev: out of memory !\n");
 		kfree(cam);
+		cam = NULL;
 		return -ENOMEM;
 	}
 	memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template));
+	cam->vdev->parent = &intf->dev;
 	video_set_drvdata(cam->vdev, cam);
 	if (debug)
 		cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
 
 	cam->udev = udev;
 
-	if ((cam->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)) == NULL) {
-		dev_info(&udev->dev, "cam->buffer: out of memory !\n");
-		video_device_release(cam->vdev);
-		kfree(cam);
-		return -ENODEV;
-	}
-
 	switch (mode) {
 	case 1:
 		dev_info(&udev->dev, "160x120 mode selected\n");
@@ -852,21 +1587,53 @@ static int zr364xx_probe(struct usb_interface *intf,
 	header2[439] = cam->width / 256;
 	header2[440] = cam->width % 256;
 
+	cam->users = 0;
 	cam->nb = 0;
-	cam->brightness = 64;
+	cam->mode.brightness = 64;
 	mutex_init(&cam->lock);
+	mutex_init(&cam->open_lock);
+
+	DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf);
+
+	/* set up the endpoint information  */
+	iface_desc = intf->cur_altsetting;
+	DBG("num endpoints %d\n", iface_desc->desc.bNumEndpoints);
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		endpoint = &iface_desc->endpoint[i].desc;
+		if (!cam->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
+			/* we found the bulk in endpoint */
+			cam->read_endpoint = endpoint->bEndpointAddress;
+		}
+	}
+
+	if (!cam->read_endpoint) {
+		dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
+		return -ENOMEM;
+	}
 
+	/* v4l */
+	INIT_LIST_HEAD(&cam->vidq.active);
+	cam->vidq.cam = cam;
 	err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1);
 	if (err) {
 		dev_err(&udev->dev, "video_register_device failed\n");
 		video_device_release(cam->vdev);
-		kfree(cam->buffer);
 		kfree(cam);
+		cam = NULL;
 		return err;
 	}
 
 	usb_set_intfdata(intf, cam);
 
+	/* load zr364xx board specific */
+	err = zr364xx_board_init(cam);
+	if (err) {
+		spin_lock_init(&cam->slock);
+		return err;
+	}
+
+	spin_lock_init(&cam->slock);
+
 	dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n",
 		 cam->vdev->num);
 	return 0;
@@ -876,17 +1643,10 @@ static int zr364xx_probe(struct usb_interface *intf,
 static void zr364xx_disconnect(struct usb_interface *intf)
 {
 	struct zr364xx_camera *cam = usb_get_intfdata(intf);
+	videobuf_mmap_free(&cam->vb_vidq);
 	usb_set_intfdata(intf, NULL);
 	dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n");
-	if (cam->vdev)
-		video_unregister_device(cam->vdev);
-	cam->vdev = NULL;
-	kfree(cam->buffer);
-	cam->buffer = NULL;
-	vfree(cam->framebuf);
-	cam->framebuf = NULL;
-	kfree(cam);
-	cam = NULL;
+	zr364xx_destroy(cam);
 }
 
 
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 5d0ba4f..76fa2ee 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1015,9 +1015,9 @@ mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
 {
 	SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
 	pSge->Address.Low = cpu_to_le32
-			(lower_32_bits((unsigned long)(dma_addr)));
+			(lower_32_bits(dma_addr));
 	pSge->Address.High = cpu_to_le32
-			(upper_32_bits((unsigned long)dma_addr));
+			(upper_32_bits(dma_addr));
 	pSge->FlagsLength = cpu_to_le32
 			((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
 }
@@ -1038,8 +1038,8 @@ mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
 	u32 tmp;
 
 	pSge->Address.Low = cpu_to_le32
-			(lower_32_bits((unsigned long)(dma_addr)));
-	tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
+			(lower_32_bits(dma_addr));
+	tmp = (u32)(upper_32_bits(dma_addr));
 
 	/*
 	 * 1078 errata workaround for the 36GB limitation
@@ -1101,7 +1101,7 @@ mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
 		pChain->NextChainOffset = next;
 
 		pChain->Address.Low = cpu_to_le32(tmp);
-		tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
+		tmp = (u32)(upper_32_bits(dma_addr));
 		pChain->Address.High = cpu_to_le32(tmp);
 }
 
@@ -1297,12 +1297,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
 	psge = (char *)&ioc_init->HostPageBufferSGE;
 	flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
 	    MPI_SGE_FLAGS_SYSTEM_ADDRESS |
-	    MPI_SGE_FLAGS_32_BIT_ADDRESSING |
 	    MPI_SGE_FLAGS_HOST_TO_IOC |
 	    MPI_SGE_FLAGS_END_OF_BUFFER;
-	if (sizeof(dma_addr_t) == sizeof(u64)) {
-	    flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
-	}
 	flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
 	flags_length |= ioc->HostPageBuffer_sz;
 	ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
@@ -2224,8 +2220,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 	int	 hard;
 	int	 rc=0;
 	int	 ii;
-	u8	 cb_idx;
-	int	 handlers;
 	int	 ret = 0;
 	int	 reset_alt_ioc_active = 0;
 	int	 irq_allocated = 0;
@@ -2548,34 +2542,6 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 		mpt_get_manufacturing_pg_0(ioc);
 	}
 
-	/*
-	 * Call each currently registered protocol IOC reset handler
-	 * with post-reset indication.
-	 * NOTE: If we're doing _IOC_BRINGUP, there can be no
-	 * MptResetHandlers[] registered yet.
-	 */
-	if (hard_reset_done) {
-		rc = handlers = 0;
-		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
-			if ((ret == 0) && MptResetHandlers[cb_idx]) {
-				dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
-				    "Calling IOC post_reset handler #%d\n",
-				    ioc->name, cb_idx));
-				rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
-				handlers++;
-			}
-
-			if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
-				drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
-				    "Calling IOC post_reset handler #%d\n",
-				    ioc->alt_ioc->name, cb_idx));
-				rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
-				handlers++;
-			}
-		}
-		/* FIXME?  Examine results here? */
-	}
-
  out:
 	if ((ret != 0) && irq_allocated) {
 		free_irq(ioc->pci_irq, ioc);
@@ -3938,6 +3904,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 	int count = 0;
 	u32 diag1val = 0;
 	MpiFwHeader_t *cached_fw;	/* Pointer to FW */
+	u8	 cb_idx;
 
 	/* Clear any existing interrupts */
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
@@ -3956,6 +3923,18 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 		else
 			mdelay(1);
 
+		/*
+		 * Call each currently registered protocol IOC reset handler
+		 * with pre-reset indication.
+		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
+		 * MptResetHandlers[] registered yet.
+		 */
+		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+			if (MptResetHandlers[cb_idx])
+				(*(MptResetHandlers[cb_idx]))(ioc,
+						MPT_IOC_PRE_RESET);
+		}
+
 		for (count = 0; count < 60; count ++) {
 			doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
 			doorbell &= MPI_IOC_STATE_MASK;
@@ -4052,25 +4031,15 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 		 * NOTE: If we're doing _IOC_BRINGUP, there can be no
 		 * MptResetHandlers[] registered yet.
 		 */
-		{
-			u8	 cb_idx;
-			int	 r = 0;
-
-			for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
-				if (MptResetHandlers[cb_idx]) {
-					dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
-						"Calling IOC pre_reset handler #%d\n",
-						ioc->name, cb_idx));
-					r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
-					if (ioc->alt_ioc) {
-						dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
-							"Calling alt-%s pre_reset handler #%d\n",
-							ioc->name, ioc->alt_ioc->name, cb_idx));
-						r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
-					}
+		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+			if (MptResetHandlers[cb_idx]) {
+				mpt_signal_reset(cb_idx,
+					ioc, MPT_IOC_PRE_RESET);
+				if (ioc->alt_ioc) {
+					mpt_signal_reset(cb_idx,
+					ioc->alt_ioc, MPT_IOC_PRE_RESET);
 				}
 			}
-			/* FIXME?  Examine results here? */
 		}
 
 		if (ioc->cached_fw)
@@ -6956,7 +6925,7 @@ EXPORT_SYMBOL(mpt_halt_firmware);
 int
 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
 {
-	int		 rc;
+	int	 rc;
 	u8	 cb_idx;
 	unsigned long	 flags;
 	unsigned long	 time_count;
@@ -6982,8 +6951,6 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
 		ioc->alt_ioc->ioc_reset_in_progress = 1;
 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
 
-	/* FIXME: If do_ioc_recovery fails, repeat....
-	 */
 
 	/* The SCSI driver needs to adjust timeouts on all current
 	 * commands prior to the diagnostic reset being issued.
@@ -7020,6 +6987,15 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
 	}
 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
 
+	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+		if (MptResetHandlers[cb_idx]) {
+			mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
+			if (ioc->alt_ioc)
+				mpt_signal_reset(cb_idx,
+					ioc->alt_ioc, MPT_IOC_POST_RESET);
+		}
+	}
+
 	dtmprintk(ioc,
 	    printk(MYIOC_s_DEBUG_FMT
 		"HardResetHandler: completed (%d seconds): %s\n", ioc->name,
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 1c8514d..8dd4d21 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2008 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.04.10"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.09"
+#define MPT_LINUX_VERSION_COMMON	"3.04.12"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.12"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -157,8 +157,9 @@
 /*
  *	Try to keep these at 2^N-1
  */
-#define MPT_FC_CAN_QUEUE	127
+#define MPT_FC_CAN_QUEUE	1024
 #define MPT_SCSI_CAN_QUEUE	127
+#define MPT_SAS_CAN_QUEUE	127
 
 /*
  * Set the MAX_SGE value based on user input.
@@ -879,23 +880,9 @@ typedef enum {
 
 typedef struct _MPT_SCSI_HOST {
 	MPT_ADAPTER		 *ioc;
-	int			  port;
-	u32			  pad0;
-	MPT_LOCAL_REPLY		 *pLocal;		/* used for internal commands */
-	struct timer_list	  timer;
-		/* Pool of memory for holding SCpnts before doing
-		 * OS callbacks. freeQ is the free pool.
-		 */
-	u8			  negoNvram;		/* DV disabled, nego NVRAM */
-	u8			  pad1;
-	u8			  rsvd[2];
-	MPT_FRAME_HDR		 *cmdPtr;		/* Ptr to nonOS request */
-	struct scsi_cmnd	 *abortSCpnt;
-	MPT_LOCAL_REPLY		  localReply;		/* internal cmd reply struct */
 	ushort			  sel_timeout[MPT_MAX_FC_DEVICES];
 	char 			  *info_kbuf;
 	long			  last_queue_full;
-	u16			  tm_iocstatus;
 	u16			  spi_pending;
 	struct list_head	  target_reset_list;
 } MPT_SCSI_HOST;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index e61df13..ebf6ae0 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -1288,25 +1288,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
 		 ioc->name, ioc->ScsiLookup));
 
-	/* Clear the TM flags
-	 */
-	hd->abortSCpnt = NULL;
-
-	/* Clear the pointer used to store
-	 * single-threaded commands, i.e., those
-	 * issued during a bus scan, dv and
-	 * configuration pages.
-	 */
-	hd->cmdPtr = NULL;
-
-	/* Initialize this SCSI Hosts' timers
-	 * To use, set the timer expires field
-	 * and add_timer
-	 */
-	init_timer(&hd->timer);
-	hd->timer.data = (unsigned long) hd;
-	hd->timer.function = mptscsih_timer_expired;
-
 	hd->last_queue_full = 0;
 
 	sh->transportt = mptfc_transport_template;
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index a9e48e2..bc2ec21 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -795,7 +795,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
 			IOC_AND_NETDEV_NAMES_s_s(dev),
 			le32_to_cpu(pSimple->FlagsLength)));
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 55ff252..83873e3 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -72,6 +72,7 @@
  */
 #define MPTSAS_RAID_CHANNEL	1
 
+#define SAS_CONFIG_PAGE_TIMEOUT		30
 MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
@@ -324,7 +325,6 @@ mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
 {
 	struct fw_event_work *fw_event, *next;
 	struct mptsas_target_reset_event *target_reset_list, *n;
-	u8	flush_q;
 	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);
 
 	/* flush the target_reset_list */
@@ -344,15 +344,10 @@ mptsas_cleanup_fw_event_q(MPT_ADAPTER *ioc)
 	     !ioc->fw_event_q || in_interrupt())
 		return;
 
-	flush_q = 0;
 	list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) {
 		if (cancel_delayed_work(&fw_event->work))
 			mptsas_free_fw_event(ioc, fw_event);
-		else
-			flush_q = 1;
 	}
-	if (flush_q)
-		flush_workqueue(ioc->fw_event_q);
 }
 
 
@@ -661,7 +656,7 @@ mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc,
 	cfg.pageAddr = starget->id;
 	cfg.cfghdr.hdr = &hdr;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	if (mpt_config(ioc, &cfg) != 0)
 		goto out;
@@ -851,7 +846,13 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
 		port_details->num_phys--;
 		port_details->phy_bitmask &= ~ (1 << phy_info->phy_id);
 		memset(&phy_info->attached, 0, sizeof(struct mptsas_devinfo));
-		sas_port_delete_phy(port_details->port, phy_info->phy);
+		if (phy_info->phy) {
+			devtprintk(ioc, dev_printk(KERN_DEBUG,
+				&phy_info->phy->dev, MYIOC_s_FMT
+				"delete phy %d, phy-obj (0x%p)\n", ioc->name,
+				phy_info->phy_id, phy_info->phy));
+			sas_port_delete_phy(port_details->port, phy_info->phy);
+		}
 		phy_info->port_details = NULL;
 	}
 
@@ -1272,7 +1273,6 @@ mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
 		}
 		mptsas_cleanup_fw_event_q(ioc);
 		mptsas_queue_rescan(ioc);
-		mptsas_fw_event_on(ioc);
 		break;
 	default:
 		break;
@@ -1318,7 +1318,7 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
 	cfg.pageAddr = form + form_specific;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;	/* read */
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	error = mpt_config(ioc, &cfg);
 	if (error)
@@ -1592,6 +1592,7 @@ mptsas_firmware_event_work(struct work_struct *work)
 		mptsas_scan_sas_topology(ioc);
 		ioc->in_rescan = 0;
 		mptsas_free_fw_event(ioc, fw_event);
+		mptsas_fw_event_on(ioc);
 		return;
 	}
 
@@ -1891,7 +1892,7 @@ static struct scsi_host_template mptsas_driver_template = {
 	.eh_bus_reset_handler		= mptscsih_bus_reset,
 	.eh_host_reset_handler		= mptscsih_host_reset,
 	.bios_param			= mptscsih_bios_param,
-	.can_queue			= MPT_FC_CAN_QUEUE,
+	.can_queue			= MPT_SAS_CAN_QUEUE,
 	.this_id			= -1,
 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
 	.max_sectors			= 8192,
@@ -1926,7 +1927,7 @@ static int mptsas_get_linkerrors(struct sas_phy *phy)
 	cfg.pageAddr = phy->identify.phy_identifier;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;    /* read */
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	error = mpt_config(ioc, &cfg);
 	if (error)
@@ -2278,7 +2279,7 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
 	cfg.pageAddr = 0;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;	/* read */
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	error = mpt_config(ioc, &cfg);
 	if (error)
@@ -2349,7 +2350,7 @@ mptsas_sas_io_unit_pg1(MPT_ADAPTER *ioc)
 
 	cfg.cfghdr.ehdr = &hdr;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 	cfg.cfghdr.ehdr->PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
 	cfg.cfghdr.ehdr->ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
 	cfg.cfghdr.ehdr->PageVersion = MPI_SASIOUNITPAGE1_PAGEVERSION;
@@ -2411,7 +2412,7 @@ mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
 
 	cfg.cfghdr.ehdr = &hdr;
 	cfg.dir = 0;	/* read */
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	/* Get Phy Pg 0 for each Phy. */
 	cfg.physAddr = -1;
@@ -2479,7 +2480,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
 	cfg.physAddr = -1;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;	/* read */
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	memset(device_info, 0, sizeof(struct mptsas_devinfo));
 	error = mpt_config(ioc, &cfg);
@@ -2554,7 +2555,7 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
 	cfg.pageAddr = form + form_specific;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;	/* read */
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	memset(port_info, 0, sizeof(struct mptsas_portinfo));
 	error = mpt_config(ioc, &cfg);
@@ -2635,7 +2636,7 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
 	cfg.pageAddr = form + form_specific;
 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
 	cfg.dir = 0;	/* read */
-	cfg.timeout = 10;
+	cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
 
 	error = mpt_config(ioc, &cfg);
 	if (error)
@@ -3307,6 +3308,7 @@ mptsas_send_expander_event(struct fw_event_work *fw_event)
 	expander_data = (MpiEventDataSasExpanderStatusChange_t *)
 	    fw_event->event_data;
 	memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64));
+	sas_address = le64_to_cpu(sas_address);
 	port_info = mptsas_find_portinfo_by_sas_address(ioc, sas_address);
 
 	if (expander_data->ReasonCode == MPI_EVENT_SAS_EXP_RC_ADDED) {
@@ -4760,10 +4762,9 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	/* set 16 byte cdb's */
 	sh->max_cmd_len = 16;
-
-	sh->max_id = ioc->pfacts[0].PortSCSIID;
+	sh->can_queue = min_t(int, ioc->req_depth - 10, sh->can_queue);
+	sh->max_id = -1;
 	sh->max_lun = max_lun;
-
 	sh->transportt = mptsas_transport_template;
 
 	/* Required entry.
@@ -4821,25 +4822,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
 		 ioc->name, ioc->ScsiLookup));
 
-	/* Clear the TM flags
-	 */
-	hd->abortSCpnt = NULL;
-
-	/* Clear the pointer used to store
-	 * single-threaded commands, i.e., those
-	 * issued during a bus scan, dv and
-	 * configuration pages.
-	 */
-	hd->cmdPtr = NULL;
-
-	/* Initialize this SCSI Hosts' timers
-	 * To use, set the timer expires field
-	 * and add_timer
-	 */
-	init_timer(&hd->timer);
-	hd->timer.data = (unsigned long) hd;
-	hd->timer.function = mptscsih_timer_expired;
-
 	ioc->sas_data.ptClear = mpt_pt_clear;
 
 	hd->last_queue_full = 0;
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 8440f78..c295786 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -628,6 +628,16 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 		return 1;
 	}
 
+	if (ioc->bus_type == SAS) {
+		VirtDevice *vdevice = sc->device->hostdata;
+
+		if (!vdevice || !vdevice->vtarget ||
+		    vdevice->vtarget->deleted) {
+			sc->result = DID_NO_CONNECT << 16;
+			goto out;
+		}
+	}
+
 	sc->host_scribble = NULL;
 	sc->result = DID_OK << 16;		/* Set default reply as OK */
 	pScsiReq = (SCSIIORequest_t *) mf;
@@ -689,6 +699,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 
 		switch(status) {
 		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
+		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
 			/* CHECKME!
 			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
 			 * But not: DID_BUS_BUSY lest one risk
@@ -872,7 +883,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */
 		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */
 		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */
-		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
 		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
@@ -892,7 +902,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 #endif
 
 	} /* end of address reply case */
-
+out:
 	/* Unmap the DMA buffers, if any. */
 	scsi_dma_unmap(sc);
 
@@ -1729,9 +1739,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 	 */
 	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
 	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
-
-	hd->abortSCpnt = SCpnt;
-
 	retval = mptscsih_IssueTaskMgmt(hd,
 			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
 			 vdevice->vtarget->channel,
@@ -2293,7 +2300,10 @@ mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 		else
 			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
 	} else
-		max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
+		 max_depth = ioc->sh->can_queue;
+
+	if (!sdev->tagged_supported)
+		max_depth = 1;
 
 	if (qdepth > max_depth)
 		qdepth = max_depth;
@@ -2627,50 +2637,6 @@ mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
 	return 1;
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*	mptscsih_timer_expired - Call back for timer process.
- *	Used only for dv functionality.
- *	@data: Pointer to MPT_SCSI_HOST recast as an unsigned long
- *
- */
-void
-mptscsih_timer_expired(unsigned long data)
-{
-	MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
-	MPT_ADAPTER 	*ioc = hd->ioc;
-
-	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired! Cmd %p\n", ioc->name, hd->cmdPtr));
-
-	if (hd->cmdPtr) {
-		MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
-
-		if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
-			/* Desire to issue a task management request here.
-			 * TM requests MUST be single threaded.
-			 * If old eh code and no TM current, issue request.
-			 * If new eh code, do nothing. Wait for OS cmd timeout
-			 *	for bus reset.
-			 */
-		} else {
-			/* Perform a FW reload */
-			if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
-				printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
-			}
-		}
-	} else {
-		/* This should NEVER happen */
-		printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", ioc->name);
-	}
-
-	/* No more processing.
-	 * TM call will generate an interrupt for SCSI TM Management.
-	 * The FW will reply to all outstanding commands, callback will finish cleanup.
-	 * Hard reset clean-up will free all resources.
-	 */
-	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired Complete!\n", ioc->name));
-
-	return;
-}
 
 /**
  *	mptscsih_get_completion_code -
@@ -3265,6 +3231,5 @@ EXPORT_SYMBOL(mptscsih_scandv_complete);
 EXPORT_SYMBOL(mptscsih_event_process);
 EXPORT_SYMBOL(mptscsih_ioc_reset);
 EXPORT_SYMBOL(mptscsih_change_queue_depth);
-EXPORT_SYMBOL(mptscsih_timer_expired);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index eb3f677..e0b33e0 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -129,7 +129,6 @@ extern int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRA
 extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
-extern void mptscsih_timer_expired(unsigned long data);
 extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
 extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
 extern struct device_attribute *mptscsih_host_attrs[];
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index c5b808f..69f4257 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -1472,28 +1472,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
 		 ioc->name, ioc->ScsiLookup));
 
-	/* Clear the TM flags
-	 */
-	hd->abortSCpnt = NULL;
-
-	/* Clear the pointer used to store
-	 * single-threaded commands, i.e., those
-	 * issued during a bus scan, dv and
-	 * configuration pages.
-	 */
-	hd->cmdPtr = NULL;
-
-	/* Initialize this SCSI Hosts' timers
-	 * To use, set the timer expires field
-	 * and add_timer
-	 */
-	init_timer(&hd->timer);
-	hd->timer.data = (unsigned long) hd;
-	hd->timer.function = mptscsih_timer_expired;
-
 	ioc->spi_data.Saf_Te = mpt_saf_te;
-
-	hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
 	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 		"saf_te %x\n",
 		ioc->name,
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 491ac0f..570be13 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -108,6 +108,19 @@ config TWL4030_CORE
 	  high speed USB OTG transceiver, an audio codec (on most
 	  versions) and many other features.
 
+config TWL4030_POWER
+	bool "Support power resources on TWL4030 family chips"
+	depends on TWL4030_CORE && ARM
+	help
+	  Say yes here if you want to use the power resources on the
+	  TWL4030 family chips.  Most of these resources are regulators,
+	  which have a separate driver; some are control signals, such
+	  as clock request handshaking.
+
+	  This driver uses board-specific data to initialize the resources
+	  and load scripts controling which resources are switched off/on
+	  or reset when a sleep, wakeup or warm reset event occurs.
+
 config MFD_TMIO
 	bool
 	default n
@@ -157,6 +170,16 @@ config MFD_WM8400
 	  the device, additional drivers must be enabled in order to use
 	  the functionality of the device.
 
+config MFD_WM831X
+	tristate "Support Wolfson Microelectronics WM831x PMICs"
+	select MFD_CORE
+	depends on I2C
+	help
+	  Support for the Wolfson Microelecronics WM831x PMICs.  This
+	  driver provides common support for accessing the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device.
+
 config MFD_WM8350
 	tristate
 
@@ -228,6 +251,16 @@ config MFD_PCF50633
 	  facilities, and registers devices for the various functions
 	  so that function-specific drivers can bind to them.
 
+config MFD_MC13783
+	tristate "Support Freescale MC13783"
+	depends on SPI_MASTER
+	select MFD_CORE
+	help
+	  Support for the Freescale (Atlas) MC13783 PMIC and audio CODEC.
+	  This driver provides common support for accessing  the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device.
+
 config PCF50633_ADC
 	tristate "Support for NXP PCF50633 ADC"
 	depends on MFD_PCF50633
@@ -256,6 +289,15 @@ config AB3100_CORE
 	  LEDs, vibrator, system power and temperature, power management
 	  and ALSA sound.
 
+config AB3100_OTP
+	tristate "ST-Ericsson AB3100 OTP functions"
+	depends on AB3100_CORE
+	default y if AB3100_CORE
+	help
+	  Select this to enable the AB3100 Mixed Signal IC OTP (one-time
+	  programmable memory) support. This exposes a sysfs file to read
+	  out OTP values.
+
 config EZX_PCAP
 	bool "PCAP Support"
 	depends on GENERIC_HARDIRQS && SPI_MASTER
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 6f8a9a1..f3b277b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -15,6 +15,8 @@ obj-$(CONFIG_MFD_TC6387XB)	+= tc6387xb.o
 obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o
 
 obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
+wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
+obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
 wm8350-objs			:= wm8350-core.o wm8350-regmap.o wm8350-gpio.o
 obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
 obj-$(CONFIG_MFD_WM8350_I2C)	+= wm8350-i2c.o
@@ -23,6 +25,9 @@ obj-$(CONFIG_TPS65010)		+= tps65010.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
 obj-$(CONFIG_TWL4030_CORE)	+= twl4030-core.o twl4030-irq.o
+obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
+
+obj-$(CONFIG_MFD_MC13783)	+= mc13783-core.o
 
 obj-$(CONFIG_MFD_CORE)		+= mfd-core.o
 
@@ -44,3 +49,4 @@ obj-$(CONFIG_MFD_PCF50633)	+= pcf50633-core.o
 obj-$(CONFIG_PCF50633_ADC)	+= pcf50633-adc.o
 obj-$(CONFIG_PCF50633_GPIO)	+= pcf50633-gpio.o
 obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
+obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 13e7d7b..c533f86 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -14,7 +14,6 @@
 #include <linux/platform_device.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
@@ -77,7 +76,7 @@ u8 ab3100_get_chip_type(struct ab3100 *ab3100)
 }
 EXPORT_SYMBOL(ab3100_get_chip_type);
 
-int ab3100_set_register(struct ab3100 *ab3100, u8 reg, u8 regval)
+int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval)
 {
 	u8 regandval[2] = {reg, regval};
 	int err;
@@ -107,9 +106,10 @@ int ab3100_set_register(struct ab3100 *ab3100, u8 reg, u8 regval)
 		err = 0;
 	}
 	mutex_unlock(&ab3100->access_mutex);
-	return 0;
+	return err;
 }
-EXPORT_SYMBOL(ab3100_set_register);
+EXPORT_SYMBOL(ab3100_set_register_interruptible);
+
 
 /*
  * The test registers exist at an I2C bus address up one
@@ -118,7 +118,7 @@ EXPORT_SYMBOL(ab3100_set_register);
  * anyway. It's currently only used from this file so declare
  * it static and do not export.
  */
-static int ab3100_set_test_register(struct ab3100 *ab3100,
+static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100,
 				    u8 reg, u8 regval)
 {
 	u8 regandval[2] = {reg, regval};
@@ -148,7 +148,8 @@ static int ab3100_set_test_register(struct ab3100 *ab3100,
 	return err;
 }
 
-int ab3100_get_register(struct ab3100 *ab3100, u8 reg, u8 *regval)
+
+int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval)
 {
 	int err;
 
@@ -202,9 +203,10 @@ int ab3100_get_register(struct ab3100 *ab3100, u8 reg, u8 *regval)
 	mutex_unlock(&ab3100->access_mutex);
 	return err;
 }
-EXPORT_SYMBOL(ab3100_get_register);
+EXPORT_SYMBOL(ab3100_get_register_interruptible);
 
-int ab3100_get_register_page(struct ab3100 *ab3100,
+
+int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
 			     u8 first_reg, u8 *regvals, u8 numregs)
 {
 	int err;
@@ -258,9 +260,10 @@ int ab3100_get_register_page(struct ab3100 *ab3100,
 	mutex_unlock(&ab3100->access_mutex);
 	return err;
 }
-EXPORT_SYMBOL(ab3100_get_register_page);
+EXPORT_SYMBOL(ab3100_get_register_page_interruptible);
+
 
-int ab3100_mask_and_set_register(struct ab3100 *ab3100,
+int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
 				 u8 reg, u8 andmask, u8 ormask)
 {
 	u8 regandval[2] = {reg, 0};
@@ -328,7 +331,8 @@ int ab3100_mask_and_set_register(struct ab3100 *ab3100,
 	mutex_unlock(&ab3100->access_mutex);
 	return err;
 }
-EXPORT_SYMBOL(ab3100_mask_and_set_register);
+EXPORT_SYMBOL(ab3100_mask_and_set_register_interruptible);
+
 
 /*
  * Register a simple callback for handling any AB3100 events.
@@ -371,7 +375,7 @@ static void ab3100_work(struct work_struct *work)
 	u32 fatevent;
 	int err;
 
-	err = ab3100_get_register_page(ab3100, AB3100_EVENTA1,
+	err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1,
 				       event_regs, 3);
 	if (err)
 		goto err_event_wq;
@@ -417,7 +421,7 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data)
 	 * stuff and we will re-enable the interrupts once th
 	 * worker has finished.
 	 */
-	disable_irq(ab3100->i2c_client->irq);
+	disable_irq_nosync(irq);
 	schedule_work(&ab3100->work);
 	return IRQ_HANDLED;
 }
@@ -435,7 +439,7 @@ static int ab3100_registers_print(struct seq_file *s, void *p)
 	seq_printf(s, "AB3100 registers:\n");
 
 	for (reg = 0; reg < 0xff; reg++) {
-		ab3100_get_register(ab3100, reg, &value);
+		ab3100_get_register_interruptible(ab3100, reg, &value);
 		seq_printf(s, "[0x%x]:  0x%x\n", reg, value);
 	}
 	return 0;
@@ -465,14 +469,14 @@ static int ab3100_get_set_reg_open_file(struct inode *inode, struct file *file)
 	return 0;
 }
 
-static int ab3100_get_set_reg(struct file *file,
-			      const char __user *user_buf,
-			      size_t count, loff_t *ppos)
+static ssize_t ab3100_get_set_reg(struct file *file,
+				  const char __user *user_buf,
+				  size_t count, loff_t *ppos)
 {
 	struct ab3100_get_set_reg_priv *priv = file->private_data;
 	struct ab3100 *ab3100 = priv->ab3100;
 	char buf[32];
-	int buf_size;
+	ssize_t buf_size;
 	int regp;
 	unsigned long user_reg;
 	int err;
@@ -515,7 +519,7 @@ static int ab3100_get_set_reg(struct file *file,
 		u8 reg = (u8) user_reg;
 		u8 regvalue;
 
-		ab3100_get_register(ab3100, reg, &regvalue);
+		ab3100_get_register_interruptible(ab3100, reg, &regvalue);
 
 		dev_info(ab3100->dev,
 			 "debug read AB3100 reg[0x%02x]: 0x%02x\n",
@@ -547,8 +551,8 @@ static int ab3100_get_set_reg(struct file *file,
 			return -EINVAL;
 
 		value = (u8) user_value;
-		ab3100_set_register(ab3100, reg, value);
-		ab3100_get_register(ab3100, reg, &regvalue);
+		ab3100_set_register_interruptible(ab3100, reg, value);
+		ab3100_get_register_interruptible(ab3100, reg, &regvalue);
 
 		dev_info(ab3100->dev,
 			 "debug write reg[0x%02x] with 0x%02x, "
@@ -662,7 +666,7 @@ ab3100_init_settings[] = {
 		.setting = 0x01
 	}, {
 		.abreg = AB3100_IMRB1,
-		.setting = 0xFF
+		.setting = 0xBF
 	}, {
 		.abreg = AB3100_IMRB2,
 		.setting = 0xFF
@@ -696,7 +700,7 @@ static int __init ab3100_setup(struct ab3100 *ab3100)
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(ab3100_init_settings); i++) {
-		err = ab3100_set_register(ab3100,
+		err = ab3100_set_register_interruptible(ab3100,
 					  ab3100_init_settings[i].abreg,
 					  ab3100_init_settings[i].setting);
 		if (err)
@@ -705,14 +709,14 @@ static int __init ab3100_setup(struct ab3100 *ab3100)
 
 	/*
 	 * Special trick to make the AB3100 use the 32kHz clock (RTC)
-	 * bit 3 in test registe 0x02 is a special, undocumented test
+	 * bit 3 in test register 0x02 is a special, undocumented test
 	 * register bit that only exist in AB3100 P1E
 	 */
 	if (ab3100->chip_id == 0xc4) {
 		dev_warn(ab3100->dev,
 			 "AB3100 P1E variant detected, "
 			 "forcing chip to 32KHz\n");
-		err = ab3100_set_test_register(ab3100, 0x02, 0x08);
+		err = ab3100_set_test_register_interruptible(ab3100, 0x02, 0x08);
 	}
 
  exit_no_setup:
@@ -833,6 +837,8 @@ static int __init ab3100_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct ab3100 *ab3100;
+	struct ab3100_platform_data *ab3100_plf_data =
+		client->dev.platform_data;
 	int err;
 	int i;
 
@@ -852,8 +858,8 @@ static int __init ab3100_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, ab3100);
 
 	/* Read chip ID register */
-	err = ab3100_get_register(ab3100, AB3100_CID,
-				  &ab3100->chip_id);
+	err = ab3100_get_register_interruptible(ab3100, AB3100_CID,
+						&ab3100->chip_id);
 	if (err) {
 		dev_err(&client->dev,
 			"could not communicate with the AB3100 analog "
@@ -916,6 +922,8 @@ static int __init ab3100_probe(struct i2c_client *client,
 	for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) {
 		ab3100_platform_devs[i]->dev.parent =
 			&client->dev;
+		ab3100_platform_devs[i]->dev.platform_data =
+			ab3100_plf_data;
 		platform_set_drvdata(ab3100_platform_devs[i], ab3100);
 	}
 
diff --git a/drivers/mfd/ab3100-otp.c b/drivers/mfd/ab3100-otp.c
new file mode 100644
index 0000000..0499b20
--- /dev/null
+++ b/drivers/mfd/ab3100-otp.c
@@ -0,0 +1,268 @@
+/*
+ * drivers/mfd/ab3100_otp.c
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Driver to read out OTP from the AB3100 Mixed-signal circuit
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ab3100.h>
+#include <linux/debugfs.h>
+
+/* The OTP registers */
+#define AB3100_OTP0		0xb0
+#define AB3100_OTP1		0xb1
+#define AB3100_OTP2		0xb2
+#define AB3100_OTP3		0xb3
+#define AB3100_OTP4		0xb4
+#define AB3100_OTP5		0xb5
+#define AB3100_OTP6		0xb6
+#define AB3100_OTP7		0xb7
+#define AB3100_OTPP		0xbf
+
+/**
+ * struct ab3100_otp
+ * @dev containing device
+ * @ab3100 a pointer to the parent ab3100 device struct
+ * @locked whether the OTP is locked, after locking, no more bits
+ *       can be changed but before locking it is still possible
+ *       to change bits from 1->0.
+ * @freq clocking frequency for the OTP, this frequency is either
+ *       32768Hz or 1MHz/30
+ * @paf product activation flag, indicates whether this is a real
+ *       product (paf true) or a lab board etc (paf false)
+ * @imeich if this is set it is possible to override the
+ *       IMEI number found in the tac, fac and svn fields with
+ *       (secured) software
+ * @cid customer ID
+ * @tac type allocation code of the IMEI
+ * @fac final assembly code of the IMEI
+ * @svn software version number of the IMEI
+ * @debugfs a debugfs file used when dumping to file
+ */
+struct ab3100_otp {
+	struct device *dev;
+	struct ab3100 *ab3100;
+	bool locked;
+	u32 freq;
+	bool paf;
+	bool imeich;
+	u16 cid:14;
+	u32 tac:20;
+	u8 fac;
+	u32 svn:20;
+	struct dentry *debugfs;
+};
+
+static int __init ab3100_otp_read(struct ab3100_otp *otp)
+{
+	struct ab3100 *ab = otp->ab3100;
+	u8 otpval[8];
+	u8 otpp;
+	int err;
+
+	err = ab3100_get_register_interruptible(ab, AB3100_OTPP, &otpp);
+	if (err) {
+		dev_err(otp->dev, "unable to read OTPP register\n");
+		return err;
+	}
+
+	err = ab3100_get_register_page_interruptible(ab, AB3100_OTP0,
+						     otpval, 8);
+	if (err) {
+		dev_err(otp->dev, "unable to read OTP register page\n");
+		return err;
+	}
+
+	/* Cache OTP properties, they never change by nature */
+	otp->locked = (otpp & 0x80);
+	otp->freq = (otpp & 0x40) ? 32768 : 34100;
+	otp->paf = (otpval[1] & 0x80);
+	otp->imeich = (otpval[1] & 0x40);
+	otp->cid = ((otpval[1] << 8) | otpval[0]) & 0x3fff;
+	otp->tac = ((otpval[4] & 0x0f) << 16) | (otpval[3] << 8) | otpval[2];
+	otp->fac = ((otpval[5] & 0x0f) << 4) | (otpval[4] >> 4);
+	otp->svn = (otpval[7] << 12) | (otpval[6] << 4) | (otpval[5] >> 4);
+	return 0;
+}
+
+/*
+ * This is a simple debugfs human-readable file that dumps out
+ * the contents of the OTP.
+ */
+#ifdef CONFIG_DEBUGFS
+static int show_otp(struct seq_file *s, void *v)
+{
+	struct ab3100_otp *otp = s->private;
+	int err;
+
+	seq_printf(s, "OTP is %s\n", otp->locked ? "LOCKED" : "UNLOCKED");
+	seq_printf(s, "OTP clock switch startup is %uHz\n", otp->freq);
+	seq_printf(s, "PAF is %s\n", otp->paf ? "SET" : "NOT SET");
+	seq_printf(s, "IMEI is %s\n", otp->imeich ?
+		   "CHANGEABLE" : "NOT CHANGEABLE");
+	seq_printf(s, "CID: 0x%04x (decimal: %d)\n", otp->cid, otp->cid);
+	seq_printf(s, "IMEI: %u-%u-%u\n", otp->tac, otp->fac, otp->svn);
+	return 0;
+}
+
+static int ab3100_otp_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, ab3100_otp_show, inode->i_private);
+}
+
+static const struct file_operations ab3100_otp_operations = {
+	.open		= ab3100_otp_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int __init ab3100_otp_init_debugfs(struct device *dev,
+					  struct ab3100_otp *otp)
+{
+	otp->debugfs = debugfs_create_file("ab3100_otp", S_IFREG | S_IRUGO,
+					   NULL, otp,
+					   &ab3100_otp_operations);
+	if (!otp->debugfs) {
+		dev_err(dev, "AB3100 debugfs OTP file registration failed!\n");
+		return err;
+	}
+}
+
+static void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
+{
+	debugfs_remove_file(otp->debugfs);
+}
+#else
+/* Compile this out if debugfs not selected */
+static inline int __init ab3100_otp_init_debugfs(struct device *dev,
+						 struct ab3100_otp *otp)
+{
+	return 0;
+}
+
+static inline void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
+{
+}
+#endif
+
+#define SHOW_AB3100_ATTR(name) \
+static ssize_t ab3100_otp_##name##_show(struct device *dev, \
+			       struct device_attribute *attr, \
+			       char *buf) \
+{\
+	struct ab3100_otp *otp = dev_get_drvdata(dev); \
+	return sprintf(buf, "%u\n", otp->name); \
+}
+
+SHOW_AB3100_ATTR(locked)
+SHOW_AB3100_ATTR(freq)
+SHOW_AB3100_ATTR(paf)
+SHOW_AB3100_ATTR(imeich)
+SHOW_AB3100_ATTR(cid)
+SHOW_AB3100_ATTR(fac)
+SHOW_AB3100_ATTR(tac)
+SHOW_AB3100_ATTR(svn)
+
+static struct device_attribute ab3100_otp_attrs[] = {
+	__ATTR(locked, S_IRUGO, ab3100_otp_locked_show, NULL),
+	__ATTR(freq, S_IRUGO, ab3100_otp_freq_show, NULL),
+	__ATTR(paf, S_IRUGO, ab3100_otp_paf_show, NULL),
+	__ATTR(imeich, S_IRUGO, ab3100_otp_imeich_show, NULL),
+	__ATTR(cid, S_IRUGO, ab3100_otp_cid_show, NULL),
+	__ATTR(fac, S_IRUGO, ab3100_otp_fac_show, NULL),
+	__ATTR(tac, S_IRUGO, ab3100_otp_tac_show, NULL),
+	__ATTR(svn, S_IRUGO, ab3100_otp_svn_show, NULL),
+};
+
+static int __init ab3100_otp_probe(struct platform_device *pdev)
+{
+	struct ab3100_otp *otp;
+	int err = 0;
+	int i;
+
+	otp = kzalloc(sizeof(struct ab3100_otp), GFP_KERNEL);
+	if (!otp) {
+		dev_err(&pdev->dev, "could not allocate AB3100 OTP device\n");
+		return -ENOMEM;
+	}
+	otp->dev = &pdev->dev;
+
+	/* Replace platform data coming in with a local struct */
+	otp->ab3100 = platform_get_drvdata(pdev);
+	platform_set_drvdata(pdev, otp);
+
+	err = ab3100_otp_read(otp);
+	if (err)
+		return err;
+
+	dev_info(&pdev->dev, "AB3100 OTP readout registered\n");
+
+	/* sysfs entries */
+	for (i = 0; i < ARRAY_SIZE(ab3100_otp_attrs); i++) {
+		err = device_create_file(&pdev->dev,
+					 &ab3100_otp_attrs[i]);
+		if (err)
+			goto out_no_sysfs;
+	}
+
+	/* debugfs entries */
+	err = ab3100_otp_init_debugfs(&pdev->dev, otp);
+	if (err)
+		goto out_no_debugfs;
+
+	return 0;
+
+out_no_sysfs:
+	for (i = 0; i < ARRAY_SIZE(ab3100_otp_attrs); i++)
+		device_remove_file(&pdev->dev,
+				   &ab3100_otp_attrs[i]);
+out_no_debugfs:
+	kfree(otp);
+	return err;
+}
+
+static int __exit ab3100_otp_remove(struct platform_device *pdev)
+{
+	struct ab3100_otp *otp = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ab3100_otp_attrs); i++)
+		device_remove_file(&pdev->dev,
+				   &ab3100_otp_attrs[i]);
+	ab3100_otp_exit_debugfs(otp);
+	kfree(otp);
+	return 0;
+}
+
+static struct platform_driver ab3100_otp_driver = {
+	.driver = {
+		.name = "ab3100-otp",
+		.owner = THIS_MODULE,
+	},
+	.remove	 = __exit_p(ab3100_otp_remove),
+};
+
+static int __init ab3100_otp_init(void)
+{
+	return platform_driver_probe(&ab3100_otp_driver,
+				     ab3100_otp_probe);
+}
+
+static void __exit ab3100_otp_exit(void)
+{
+	platform_driver_unregister(&ab3100_otp_driver);
+}
+
+module_init(ab3100_otp_init);
+module_exit(ab3100_otp_exit);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
+MODULE_DESCRIPTION("AB3100 OTP Readout Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 5b6e58a..3d4a861 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -107,8 +107,16 @@ static const u8 msp_gpios[] = {
 	MSP_GPIO(2, SWITCH1), MSP_GPIO(3, SWITCH1),
 	MSP_GPIO(4, SWITCH1),
 	/* switches on MMC/SD sockets */
-	MSP_GPIO(1, SDMMC), MSP_GPIO(2, SDMMC),	/* mmc0 WP, nCD */
-	MSP_GPIO(3, SDMMC), MSP_GPIO(4, SDMMC),	/* mmc1 WP, nCD */
+	/*
+	 * Note: EVMDM355_ECP_VA4.pdf suggests that Bit 2 and 4 should be
+	 * checked for card detection. However on the EVM bit 1 and 3 gives
+	 * this status, for 0 and 1 instance respectively. The pdf also
+	 * suggests that Bit 1 and 3 should be checked for write protection.
+	 * However on the EVM bit 2 and 4 gives this status,for 0 and 1
+	 * instance respectively.
+	 */
+	MSP_GPIO(2, SDMMC), MSP_GPIO(1, SDMMC),	/* mmc0 WP, nCD */
+	MSP_GPIO(4, SDMMC), MSP_GPIO(3, SDMMC),	/* mmc1 WP, nCD */
 };
 
 #define MSP_GPIO_REG(offset)	(msp_gpios[(offset)] >> 3)
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index c1de4af..016be49 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/mfd/ezx-pcap.h>
 #include <linux/spi/spi.h>
+#include <linux/gpio.h>
 
 #define PCAP_ADC_MAXQ		8
 struct pcap_adc_request {
@@ -106,11 +107,35 @@ int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value)
 }
 EXPORT_SYMBOL_GPL(ezx_pcap_read);
 
+int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val)
+{
+	int ret;
+	u32 tmp = PCAP_REGISTER_READ_OP_BIT |
+		(reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
+
+	mutex_lock(&pcap->io_mutex);
+	ret = ezx_pcap_putget(pcap, &tmp);
+	if (ret)
+		goto out_unlock;
+
+	tmp &= (PCAP_REGISTER_VALUE_MASK & ~mask);
+	tmp |= (val & mask) | PCAP_REGISTER_WRITE_OP_BIT |
+		(reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
+
+	ret = ezx_pcap_putget(pcap, &tmp);
+out_unlock:
+	mutex_unlock(&pcap->io_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(ezx_pcap_set_bits);
+
 /* IRQ */
-static inline unsigned int irq2pcap(struct pcap_chip *pcap, int irq)
+int irq_to_pcap(struct pcap_chip *pcap, int irq)
 {
-	return 1 << (irq - pcap->irq_base);
+	return irq - pcap->irq_base;
 }
+EXPORT_SYMBOL_GPL(irq_to_pcap);
 
 int pcap_to_irq(struct pcap_chip *pcap, int irq)
 {
@@ -122,7 +147,7 @@ static void pcap_mask_irq(unsigned int irq)
 {
 	struct pcap_chip *pcap = get_irq_chip_data(irq);
 
-	pcap->msr |= irq2pcap(pcap, irq);
+	pcap->msr |= 1 << irq_to_pcap(pcap, irq);
 	queue_work(pcap->workqueue, &pcap->msr_work);
 }
 
@@ -130,7 +155,7 @@ static void pcap_unmask_irq(unsigned int irq)
 {
 	struct pcap_chip *pcap = get_irq_chip_data(irq);
 
-	pcap->msr &= ~irq2pcap(pcap, irq);
+	pcap->msr &= ~(1 << irq_to_pcap(pcap, irq));
 	queue_work(pcap->workqueue, &pcap->msr_work);
 }
 
@@ -154,34 +179,38 @@ static void pcap_isr_work(struct work_struct *work)
 	u32 msr, isr, int_sel, service;
 	int irq;
 
-	ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
-	ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
+	do {
+		ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
+		ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
 
-	/* We cant service/ack irqs that are assigned to port 2 */
-	if (!(pdata->config & PCAP_SECOND_PORT)) {
-		ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
-		isr &= ~int_sel;
-	}
-	ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
+		/* We cant service/ack irqs that are assigned to port 2 */
+		if (!(pdata->config & PCAP_SECOND_PORT)) {
+			ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
+			isr &= ~int_sel;
+		}
 
-	local_irq_disable();
-	service = isr & ~msr;
+		ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
+		ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
 
-	for (irq = pcap->irq_base; service; service >>= 1, irq++) {
-		if (service & 1) {
-			struct irq_desc *desc = irq_to_desc(irq);
+		local_irq_disable();
+		service = isr & ~msr;
+		for (irq = pcap->irq_base; service; service >>= 1, irq++) {
+			if (service & 1) {
+				struct irq_desc *desc = irq_to_desc(irq);
 
-			if (WARN(!desc, KERN_WARNING
-					"Invalid PCAP IRQ %d\n", irq))
-				break;
+				if (WARN(!desc, KERN_WARNING
+						"Invalid PCAP IRQ %d\n", irq))
+					break;
 
-			if (desc->status & IRQ_DISABLED)
-				note_interrupt(irq, desc, IRQ_NONE);
-			else
-				desc->handle_irq(irq, desc);
+				if (desc->status & IRQ_DISABLED)
+					note_interrupt(irq, desc, IRQ_NONE);
+				else
+					desc->handle_irq(irq, desc);
+			}
 		}
-	}
-	local_irq_enable();
+		local_irq_enable();
+		ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
+	} while (gpio_get_value(irq_to_gpio(pcap->spi->irq)));
 }
 
 static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
@@ -194,6 +223,19 @@ static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
 }
 
 /* ADC */
+void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits)
+{
+	u32 tmp;
+
+	mutex_lock(&pcap->adc_mutex);
+	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
+	tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
+	tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
+	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
+	mutex_unlock(&pcap->adc_mutex);
+}
+EXPORT_SYMBOL_GPL(pcap_set_ts_bits);
+
 static void pcap_disable_adc(struct pcap_chip *pcap)
 {
 	u32 tmp;
@@ -216,15 +258,16 @@ static void pcap_adc_trigger(struct pcap_chip *pcap)
 		mutex_unlock(&pcap->adc_mutex);
 		return;
 	}
-	mutex_unlock(&pcap->adc_mutex);
-
-	/* start conversion on requested bank */
-	tmp = pcap->adc_queue[head]->flags | PCAP_ADC_ADEN;
+	/* start conversion on requested bank, save TS_M bits */
+	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
+	tmp &= (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
+	tmp |= pcap->adc_queue[head]->flags | PCAP_ADC_ADEN;
 
 	if (pcap->adc_queue[head]->bank == PCAP_ADC_BANK_1)
 		tmp |= PCAP_ADC_AD_SEL1;
 
 	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
+	mutex_unlock(&pcap->adc_mutex);
 	ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
 }
 
@@ -499,7 +542,7 @@ static void __exit ezx_pcap_exit(void)
 	spi_unregister_driver(&ezxpcap_driver);
 }
 
-module_init(ezx_pcap_init);
+subsys_initcall(ezx_pcap_init);
 module_exit(ezx_pcap_exit);
 
 MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/mc13783-core.c b/drivers/mfd/mc13783-core.c
new file mode 100644
index 0000000..e354d29
--- /dev/null
+++ b/drivers/mfd/mc13783-core.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This code is in parts based on wm8350-core.c and pcf50633-core.c
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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.
+ */
+
+#include <linux/mfd/mc13783-private.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/spi/spi.h>
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+
+#define MC13783_MAX_REG_NUM	0x3f
+#define MC13783_FRAME_MASK	0x00ffffff
+#define MC13783_MAX_REG_NUM	0x3f
+#define MC13783_REG_NUM_SHIFT	0x19
+#define MC13783_WRITE_BIT_SHIFT	31
+
+static inline int spi_rw(struct spi_device *spi, u8 * buf, size_t len)
+{
+	struct spi_transfer t = {
+		.tx_buf = (const void *)buf,
+		.rx_buf = buf,
+		.len = len,
+		.cs_change = 0,
+		.delay_usecs = 0,
+	};
+	struct spi_message m;
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	if (spi_sync(spi, &m) != 0 || m.status != 0)
+		return -EINVAL;
+	return len - m.actual_length;
+}
+
+static int mc13783_read(struct mc13783 *mc13783, int reg_num, u32 *reg_val)
+{
+	unsigned int frame = 0;
+	int ret = 0;
+
+	if (reg_num > MC13783_MAX_REG_NUM)
+		return -EINVAL;
+
+	frame |= reg_num << MC13783_REG_NUM_SHIFT;
+
+	ret = spi_rw(mc13783->spi_device, (u8 *)&frame, 4);
+
+	*reg_val = frame & MC13783_FRAME_MASK;
+
+	return ret;
+}
+
+static int mc13783_write(struct mc13783 *mc13783, int reg_num, u32 reg_val)
+{
+	unsigned int frame = 0;
+
+	if (reg_num > MC13783_MAX_REG_NUM)
+		return -EINVAL;
+
+	frame |= (1 << MC13783_WRITE_BIT_SHIFT);
+	frame |= reg_num << MC13783_REG_NUM_SHIFT;
+	frame |= reg_val & MC13783_FRAME_MASK;
+
+	return spi_rw(mc13783->spi_device, (u8 *)&frame, 4);
+}
+
+int mc13783_reg_read(struct mc13783 *mc13783, int reg_num, u32 *reg_val)
+{
+	int ret;
+
+	mutex_lock(&mc13783->io_lock);
+	ret = mc13783_read(mc13783, reg_num, reg_val);
+	mutex_unlock(&mc13783->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mc13783_reg_read);
+
+int mc13783_reg_write(struct mc13783 *mc13783, int reg_num, u32 reg_val)
+{
+	int ret;
+
+	mutex_lock(&mc13783->io_lock);
+	ret = mc13783_write(mc13783, reg_num, reg_val);
+	mutex_unlock(&mc13783->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mc13783_reg_write);
+
+/**
+ * mc13783_set_bits - Bitmask write
+ *
+ * @mc13783: Pointer to mc13783 control structure
+ * @reg:    Register to access
+ * @mask:   Mask of bits to change
+ * @val:    Value to set for masked bits
+ */
+int mc13783_set_bits(struct mc13783 *mc13783, int reg, u32 mask, u32 val)
+{
+	u32 tmp;
+	int ret;
+
+	mutex_lock(&mc13783->io_lock);
+
+	ret = mc13783_read(mc13783, reg, &tmp);
+	tmp = (tmp & ~mask) | val;
+	if (ret == 0)
+		ret = mc13783_write(mc13783, reg, tmp);
+
+	mutex_unlock(&mc13783->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mc13783_set_bits);
+
+int mc13783_register_irq(struct mc13783 *mc13783, int irq,
+		void (*handler) (int, void *), void *data)
+{
+	if (irq < 0 || irq > MC13783_NUM_IRQ || !handler)
+		return -EINVAL;
+
+	if (WARN_ON(mc13783->irq_handler[irq].handler))
+		return -EBUSY;
+
+	mutex_lock(&mc13783->io_lock);
+	mc13783->irq_handler[irq].handler = handler;
+	mc13783->irq_handler[irq].data = data;
+	mutex_unlock(&mc13783->io_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mc13783_register_irq);
+
+int mc13783_free_irq(struct mc13783 *mc13783, int irq)
+{
+	if (irq < 0 || irq > MC13783_NUM_IRQ)
+		return -EINVAL;
+
+	mutex_lock(&mc13783->io_lock);
+	mc13783->irq_handler[irq].handler = NULL;
+	mutex_unlock(&mc13783->io_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mc13783_free_irq);
+
+static void mc13783_irq_work(struct work_struct *work)
+{
+	struct mc13783 *mc13783 = container_of(work, struct mc13783, work);
+	int i;
+	unsigned int adc_sts;
+
+	/* check if the adc has finished any completion */
+	mc13783_reg_read(mc13783, MC13783_REG_INTERRUPT_STATUS_0, &adc_sts);
+	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_0,
+			adc_sts & MC13783_INT_STAT_ADCDONEI);
+
+	if (adc_sts & MC13783_INT_STAT_ADCDONEI)
+		complete_all(&mc13783->adc_done);
+
+	for (i = 0; i < MC13783_NUM_IRQ; i++)
+		if (mc13783->irq_handler[i].handler)
+			mc13783->irq_handler[i].handler(i,
+					mc13783->irq_handler[i].data);
+	enable_irq(mc13783->irq);
+}
+
+static irqreturn_t mc13783_interrupt(int irq, void *dev_id)
+{
+	struct mc13783 *mc13783 = dev_id;
+
+	disable_irq_nosync(irq);
+
+	schedule_work(&mc13783->work);
+	return IRQ_HANDLED;
+}
+
+/* set adc to ts interrupt mode, which generates touchscreen wakeup interrupt */
+static inline void mc13783_adc_set_ts_irq_mode(struct mc13783 *mc13783)
+{
+	unsigned int reg_adc0, reg_adc1;
+
+	reg_adc0 = MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
+			| MC13783_ADC0_TSMOD0;
+	reg_adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN;
+
+	mc13783_reg_write(mc13783, MC13783_REG_ADC_0, reg_adc0);
+	mc13783_reg_write(mc13783, MC13783_REG_ADC_1, reg_adc1);
+}
+
+int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
+		unsigned int channel, unsigned int *sample)
+{
+	unsigned int reg_adc0, reg_adc1;
+	int i;
+
+	mutex_lock(&mc13783->adc_conv_lock);
+
+	/* set up auto incrementing anyway to make quick read */
+	reg_adc0 =  MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
+	/* enable the adc, ignore external triggering and set ASC to trigger
+	 * conversion */
+	reg_adc1 =  MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN
+		| MC13783_ADC1_ASC;
+
+	/* setup channel number */
+	if (channel > 7)
+		reg_adc1 |= MC13783_ADC1_ADSEL;
+
+	switch (mode) {
+	case MC13783_ADC_MODE_TS:
+		/* enables touch screen reference mode and set touchscreen mode
+		 * to position mode */
+		reg_adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_ADREFMODE
+			| MC13783_ADC0_TSMOD0 | MC13783_ADC0_TSMOD1;
+		reg_adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
+		break;
+	case MC13783_ADC_MODE_SINGLE_CHAN:
+		reg_adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
+		reg_adc1 |= MC13783_ADC1_RAND;
+		break;
+	case MC13783_ADC_MODE_MULT_CHAN:
+		reg_adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mc13783_reg_write(mc13783, MC13783_REG_ADC_0, reg_adc0);
+	mc13783_reg_write(mc13783, MC13783_REG_ADC_1, reg_adc1);
+
+	wait_for_completion_interruptible(&mc13783->adc_done);
+
+	for (i = 0; i < 4; i++)
+		mc13783_reg_read(mc13783, MC13783_REG_ADC_2, &sample[i]);
+
+	if (mc13783->ts_active)
+		mc13783_adc_set_ts_irq_mode(mc13783);
+
+	mutex_unlock(&mc13783->adc_conv_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
+
+void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status)
+{
+	mc13783->ts_active = status;
+}
+EXPORT_SYMBOL_GPL(mc13783_adc_set_ts_status);
+
+static int mc13783_check_revision(struct mc13783 *mc13783)
+{
+	u32 rev_id, rev1, rev2, finid, icid;
+
+	mc13783_read(mc13783, MC13783_REG_REVISION, &rev_id);
+
+	rev1 = (rev_id & 0x018) >> 3;
+	rev2 = (rev_id & 0x007);
+	icid = (rev_id & 0x01C0) >> 6;
+	finid = (rev_id & 0x01E00) >> 9;
+
+	/* Ver 0.2 is actually 3.2a.  Report as 3.2 */
+	if ((rev1 == 0) && (rev2 == 2))
+		rev1 = 3;
+
+	if (rev1 == 0 || icid != 2) {
+		dev_err(mc13783->dev, "No MC13783 detected.\n");
+		return -ENODEV;
+	}
+
+	mc13783->revision = ((rev1 * 10) + rev2);
+	dev_info(mc13783->dev, "MC13783 Rev %d.%d FinVer %x detected\n", rev1,
+	       rev2, finid);
+
+	return 0;
+}
+
+/*
+ * Register a client device.  This is non-fatal since there is no need to
+ * fail the entire device init due to a single platform device failing.
+ */
+static void mc13783_client_dev_register(struct mc13783 *mc13783,
+				       const char *name)
+{
+	struct mfd_cell cell = {};
+
+	cell.name = name;
+
+	mfd_add_devices(mc13783->dev, -1, &cell, 1, NULL, 0);
+}
+
+static int __devinit mc13783_probe(struct spi_device *spi)
+{
+	struct mc13783 *mc13783;
+	struct mc13783_platform_data *pdata = spi->dev.platform_data;
+	int ret;
+
+	mc13783 = kzalloc(sizeof(struct mc13783), GFP_KERNEL);
+	if (!mc13783)
+		return -ENOMEM;
+
+	dev_set_drvdata(&spi->dev, mc13783);
+	spi->mode = SPI_MODE_0 | SPI_CS_HIGH;
+	spi->bits_per_word = 32;
+	spi_setup(spi);
+
+	mc13783->spi_device = spi;
+	mc13783->dev = &spi->dev;
+	mc13783->irq = spi->irq;
+
+	INIT_WORK(&mc13783->work, mc13783_irq_work);
+	mutex_init(&mc13783->io_lock);
+	mutex_init(&mc13783->adc_conv_lock);
+	init_completion(&mc13783->adc_done);
+
+	if (pdata) {
+		mc13783->flags = pdata->flags;
+		mc13783->regulators = pdata->regulators;
+		mc13783->num_regulators = pdata->num_regulators;
+	}
+
+	if (mc13783_check_revision(mc13783)) {
+		ret = -ENODEV;
+		goto err_out;
+	}
+
+	/* clear and mask all interrupts */
+	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_0, 0x00ffffff);
+	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_MASK_0, 0x00ffffff);
+	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_STATUS_1, 0x00ffffff);
+	mc13783_reg_write(mc13783, MC13783_REG_INTERRUPT_MASK_1, 0x00ffffff);
+
+	/* unmask adcdone interrupts */
+	mc13783_set_bits(mc13783, MC13783_REG_INTERRUPT_MASK_0,
+			MC13783_INT_MASK_ADCDONEM, 0);
+
+	ret = request_irq(mc13783->irq, mc13783_interrupt,
+			IRQF_DISABLED | IRQF_TRIGGER_HIGH, "mc13783",
+			mc13783);
+	if (ret)
+		goto err_out;
+
+	if (mc13783->flags & MC13783_USE_CODEC)
+		mc13783_client_dev_register(mc13783, "mc13783-codec");
+	if (mc13783->flags & MC13783_USE_ADC)
+		mc13783_client_dev_register(mc13783, "mc13783-adc");
+	if (mc13783->flags & MC13783_USE_RTC)
+		mc13783_client_dev_register(mc13783, "mc13783-rtc");
+	if (mc13783->flags & MC13783_USE_REGULATOR)
+		mc13783_client_dev_register(mc13783, "mc13783-regulator");
+	if (mc13783->flags & MC13783_USE_TOUCHSCREEN)
+		mc13783_client_dev_register(mc13783, "mc13783-ts");
+
+	return 0;
+
+err_out:
+	kfree(mc13783);
+	return ret;
+}
+
+static int __devexit mc13783_remove(struct spi_device *spi)
+{
+	struct mc13783 *mc13783;
+
+	mc13783 = dev_get_drvdata(&spi->dev);
+
+	free_irq(mc13783->irq, mc13783);
+
+	mfd_remove_devices(&spi->dev);
+
+	return 0;
+}
+
+static struct spi_driver pmic_driver = {
+	.driver = {
+		   .name = "mc13783",
+		   .bus = &spi_bus_type,
+		   .owner = THIS_MODULE,
+	},
+	.probe = mc13783_probe,
+	.remove = __devexit_p(mc13783_remove),
+};
+
+static int __init pmic_init(void)
+{
+	return spi_register_driver(&pmic_driver);
+}
+subsys_initcall(pmic_init);
+
+static void __exit pmic_exit(void)
+{
+	spi_unregister_driver(&pmic_driver);
+}
+module_exit(pmic_exit);
+
+MODULE_DESCRIPTION("Core/Protocol driver for Freescale MC13783 PMIC");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 54ddf37..ae15e49 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -25,7 +25,7 @@ static int mfd_add_device(struct device *parent, int id,
 	int ret = -ENOMEM;
 	int r;
 
-	pdev = platform_device_alloc(cell->name, id);
+	pdev = platform_device_alloc(cell->name, id + cell->id);
 	if (!pdev)
 		goto fail_alloc;
 
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
index c2d05be..3d31e97 100644
--- a/drivers/mfd/pcf50633-adc.c
+++ b/drivers/mfd/pcf50633-adc.c
@@ -73,15 +73,10 @@ static void trigger_next_adc_job_if_any(struct pcf50633 *pcf)
 	struct pcf50633_adc *adc = __to_adc(pcf);
 	int head;
 
-	mutex_lock(&adc->queue_mutex);
-
 	head = adc->queue_head;
 
-	if (!adc->queue[head]) {
-		mutex_unlock(&adc->queue_mutex);
+	if (!adc->queue[head])
 		return;
-	}
-	mutex_unlock(&adc->queue_mutex);
 
 	adc_setup(pcf, adc->queue[head]->mux, adc->queue[head]->avg);
 }
@@ -99,16 +94,17 @@ adc_enqueue_request(struct pcf50633 *pcf, struct pcf50633_adc_request *req)
 
 	if (adc->queue[tail]) {
 		mutex_unlock(&adc->queue_mutex);
+		dev_err(pcf->dev, "ADC queue is full, dropping request\n");
 		return -EBUSY;
 	}
 
 	adc->queue[tail] = req;
+	if (head == tail)
+		trigger_next_adc_job_if_any(pcf);
 	adc->queue_tail = (tail + 1) & (PCF50633_MAX_ADC_FIFO_DEPTH - 1);
 
 	mutex_unlock(&adc->queue_mutex);
 
-	trigger_next_adc_job_if_any(pcf);
-
 	return 0;
 }
 
@@ -124,6 +120,7 @@ pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param, int result)
 int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg)
 {
 	struct pcf50633_adc_request *req;
+	int err;
 
 	/* req is freed when the result is ready, in interrupt handler */
 	req = kzalloc(sizeof(*req), GFP_KERNEL);
@@ -136,9 +133,13 @@ int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg)
 	req->callback_param = req;
 
 	init_completion(&req->completion);
-	adc_enqueue_request(pcf, req);
+	err = adc_enqueue_request(pcf, req);
+	if (err)
+		return err;
+
 	wait_for_completion(&req->completion);
 
+	/* FIXME by this time req might be already freed */
 	return req->result;
 }
 EXPORT_SYMBOL_GPL(pcf50633_adc_sync_read);
@@ -159,9 +160,7 @@ int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
 	req->callback = callback;
 	req->callback_param = callback_param;
 
-	adc_enqueue_request(pcf, req);
-
-	return 0;
+	return adc_enqueue_request(pcf, req);
 }
 EXPORT_SYMBOL_GPL(pcf50633_adc_async_read);
 
@@ -184,7 +183,7 @@ static void pcf50633_adc_irq(int irq, void *data)
 	struct pcf50633_adc *adc = data;
 	struct pcf50633 *pcf = adc->pcf;
 	struct pcf50633_adc_request *req;
-	int head;
+	int head, res;
 
 	mutex_lock(&adc->queue_mutex);
 	head = adc->queue_head;
@@ -199,12 +198,13 @@ static void pcf50633_adc_irq(int irq, void *data)
 	adc->queue_head = (head + 1) &
 				      (PCF50633_MAX_ADC_FIFO_DEPTH - 1);
 
+	res = adc_result(pcf);
+	trigger_next_adc_job_if_any(pcf);
+
 	mutex_unlock(&adc->queue_mutex);
 
-	req->callback(pcf, req->callback_param, adc_result(pcf));
+	req->callback(pcf, req->callback_param, res);
 	kfree(req);
-
-	trigger_next_adc_job_if_any(pcf);
 }
 
 static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 8d3c38b..d26d774 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -444,7 +444,7 @@ static irqreturn_t pcf50633_irq(int irq, void *data)
 
 	get_device(pcf->dev);
 	disable_irq_nosync(pcf->irq);
-	schedule_work(&pcf->irq_work);
+	queue_work(pcf->work_queue, &pcf->irq_work);
 
 	return IRQ_HANDLED;
 }
@@ -575,6 +575,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
 	pcf->dev = &client->dev;
 	pcf->i2c_client = client;
 	pcf->irq = client->irq;
+	pcf->work_queue = create_singlethread_workqueue("pcf50633");
 
 	INIT_WORK(&pcf->irq_work, pcf50633_irq_worker);
 
@@ -651,6 +652,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
 	return 0;
 
 err:
+	destroy_workqueue(pcf->work_queue);
 	kfree(pcf);
 	return ret;
 }
@@ -661,6 +663,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
 	int i;
 
 	free_irq(pcf->irq, pcf);
+	destroy_workqueue(pcf->work_queue);
 
 	platform_device_unregister(pcf->input_pdev);
 	platform_device_unregister(pcf->rtc_pdev);
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index ca54996..e424cf6 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -89,6 +89,12 @@
 #define twl_has_madc()	false
 #endif
 
+#ifdef CONFIG_TWL4030_POWER
+#define twl_has_power()        true
+#else
+#define twl_has_power()        false
+#endif
+
 #if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
 #define twl_has_rtc()	true
 #else
@@ -115,6 +121,12 @@
 
 #define TWL4030_NUM_SLAVES		4
 
+#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
+	|| defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE)
+#define twl_has_pwrbutton()	true
+#else
+#define twl_has_pwrbutton()	false
+#endif
 
 /* Base Address defns for twl4030_map[] */
 
@@ -538,6 +550,13 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
 			return PTR_ERR(child);
 	}
 
+	if (twl_has_pwrbutton()) {
+		child = add_child(1, "twl4030_pwrbutton",
+				NULL, 0, true, pdata->irq_base + 8 + 0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
 	if (twl_has_regulator()) {
 		/*
 		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
@@ -788,6 +807,10 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	/* setup clock framework */
 	clocks_init(&client->dev);
 
+	/* load power event scripts */
+	if (twl_has_power() && pdata->power)
+		twl4030_power_init(pdata->power);
+
 	/* Maybe init the T2 Interrupt subsystem */
 	if (client->irq
 			&& pdata->irq_base
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 7d43083..fb194fe 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -424,7 +424,7 @@ static void twl4030_sih_do_edge(struct work_struct *work)
 	/* see what work we have */
 	spin_lock_irq(&sih_agent_lock);
 	edge_change = agent->edge_change;
-	agent->edge_change = 0;;
+	agent->edge_change = 0;
 	sih = edge_change ? agent->sih : NULL;
 	spin_unlock_irq(&sih_agent_lock);
 	if (!sih)
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
new file mode 100644
index 0000000..d423e0c
--- /dev/null
+++ b/drivers/mfd/twl4030-power.c
@@ -0,0 +1,472 @@
+/*
+ * linux/drivers/i2c/chips/twl4030-power.c
+ *
+ * Handle TWL4030 Power initialization
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2006 Texas Instruments, Inc
+ *
+ * Written by 	Kalle Jokiniemi
+ *		Peter De Schrijver <peter.de-schrijver@nokia.com>
+ * Several fixes by Amit Kucheria <amit.kucheria@verdurent.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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/module.h>
+#include <linux/pm.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+static u8 twl4030_start_script_address = 0x2b;
+
+#define PWR_P1_SW_EVENTS	0x10
+#define PWR_DEVOFF	(1<<0)
+
+#define PHY_TO_OFF_PM_MASTER(p)		(p - 0x36)
+#define PHY_TO_OFF_PM_RECEIVER(p)	(p - 0x5b)
+
+/* resource - hfclk */
+#define R_HFCLKOUT_DEV_GRP 	PHY_TO_OFF_PM_RECEIVER(0xe6)
+
+/* PM events */
+#define R_P1_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x46)
+#define R_P2_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x47)
+#define R_P3_SW_EVENTS		PHY_TO_OFF_PM_MASTER(0x48)
+#define R_CFG_P1_TRANSITION	PHY_TO_OFF_PM_MASTER(0x36)
+#define R_CFG_P2_TRANSITION	PHY_TO_OFF_PM_MASTER(0x37)
+#define R_CFG_P3_TRANSITION	PHY_TO_OFF_PM_MASTER(0x38)
+
+#define LVL_WAKEUP	0x08
+
+#define ENABLE_WARMRESET (1<<4)
+
+#define END_OF_SCRIPT		0x3f
+
+#define R_SEQ_ADD_A2S		PHY_TO_OFF_PM_MASTER(0x55)
+#define R_SEQ_ADD_S2A12		PHY_TO_OFF_PM_MASTER(0x56)
+#define	R_SEQ_ADD_S2A3		PHY_TO_OFF_PM_MASTER(0x57)
+#define	R_SEQ_ADD_WARM		PHY_TO_OFF_PM_MASTER(0x58)
+#define R_MEMORY_ADDRESS	PHY_TO_OFF_PM_MASTER(0x59)
+#define R_MEMORY_DATA		PHY_TO_OFF_PM_MASTER(0x5a)
+
+#define R_PROTECT_KEY		0x0E
+#define R_KEY_1			0xC0
+#define R_KEY_2			0x0C
+
+/* resource configuration registers */
+
+#define DEVGROUP_OFFSET		0
+#define TYPE_OFFSET		1
+
+/* Bit positions */
+#define DEVGROUP_SHIFT		5
+#define DEVGROUP_MASK		(7 << DEVGROUP_SHIFT)
+#define TYPE_SHIFT		0
+#define TYPE_MASK		(7 << TYPE_SHIFT)
+#define TYPE2_SHIFT		3
+#define TYPE2_MASK		(3 << TYPE2_SHIFT)
+
+static u8 res_config_addrs[] = {
+	[RES_VAUX1]	= 0x17,
+	[RES_VAUX2]	= 0x1b,
+	[RES_VAUX3]	= 0x1f,
+	[RES_VAUX4]	= 0x23,
+	[RES_VMMC1]	= 0x27,
+	[RES_VMMC2]	= 0x2b,
+	[RES_VPLL1]	= 0x2f,
+	[RES_VPLL2]	= 0x33,
+	[RES_VSIM]	= 0x37,
+	[RES_VDAC]	= 0x3b,
+	[RES_VINTANA1]	= 0x3f,
+	[RES_VINTANA2]	= 0x43,
+	[RES_VINTDIG]	= 0x47,
+	[RES_VIO]	= 0x4b,
+	[RES_VDD1]	= 0x55,
+	[RES_VDD2]	= 0x63,
+	[RES_VUSB_1V5]	= 0x71,
+	[RES_VUSB_1V8]	= 0x74,
+	[RES_VUSB_3V1]	= 0x77,
+	[RES_VUSBCP]	= 0x7a,
+	[RES_REGEN]	= 0x7f,
+	[RES_NRES_PWRON] = 0x82,
+	[RES_CLKEN]	= 0x85,
+	[RES_SYSEN]	= 0x88,
+	[RES_HFCLKOUT]	= 0x8b,
+	[RES_32KCLKOUT]	= 0x8e,
+	[RES_RESET]	= 0x91,
+	[RES_Main_Ref]	= 0x94,
+};
+
+static int __init twl4030_write_script_byte(u8 address, u8 byte)
+{
+	int err;
+
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+				R_MEMORY_ADDRESS);
+	if (err)
+		goto out;
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, byte,
+				R_MEMORY_DATA);
+out:
+	return err;
+}
+
+static int __init twl4030_write_script_ins(u8 address, u16 pmb_message,
+					   u8 delay, u8 next)
+{
+	int err;
+
+	address *= 4;
+	err = twl4030_write_script_byte(address++, pmb_message >> 8);
+	if (err)
+		goto out;
+	err = twl4030_write_script_byte(address++, pmb_message & 0xff);
+	if (err)
+		goto out;
+	err = twl4030_write_script_byte(address++, delay);
+	if (err)
+		goto out;
+	err = twl4030_write_script_byte(address++, next);
+out:
+	return err;
+}
+
+static int __init twl4030_write_script(u8 address, struct twl4030_ins *script,
+				       int len)
+{
+	int err;
+
+	for (; len; len--, address++, script++) {
+		if (len == 1) {
+			err = twl4030_write_script_ins(address,
+						script->pmb_message,
+						script->delay,
+						END_OF_SCRIPT);
+			if (err)
+				break;
+		} else {
+			err = twl4030_write_script_ins(address,
+						script->pmb_message,
+						script->delay,
+						address + 1);
+			if (err)
+				break;
+		}
+	}
+	return err;
+}
+
+static int __init twl4030_config_wakeup3_sequence(u8 address)
+{
+	int err;
+	u8 data;
+
+	/* Set SLEEP to ACTIVE SEQ address for P3 */
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+				R_SEQ_ADD_S2A3);
+	if (err)
+		goto out;
+
+	/* P3 LVL_WAKEUP should be on LEVEL */
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+				R_P3_SW_EVENTS);
+	if (err)
+		goto out;
+	data |= LVL_WAKEUP;
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
+				R_P3_SW_EVENTS);
+out:
+	if (err)
+		pr_err("TWL4030 wakeup sequence for P3 config error\n");
+	return err;
+}
+
+static int __init twl4030_config_wakeup12_sequence(u8 address)
+{
+	int err = 0;
+	u8 data;
+
+	/* Set SLEEP to ACTIVE SEQ address for P1 and P2 */
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+				R_SEQ_ADD_S2A12);
+	if (err)
+		goto out;
+
+	/* P1/P2 LVL_WAKEUP should be on LEVEL */
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+				R_P1_SW_EVENTS);
+	if (err)
+		goto out;
+
+	data |= LVL_WAKEUP;
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
+				R_P1_SW_EVENTS);
+	if (err)
+		goto out;
+
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+				R_P2_SW_EVENTS);
+	if (err)
+		goto out;
+
+	data |= LVL_WAKEUP;
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data,
+				R_P2_SW_EVENTS);
+	if (err)
+		goto out;
+
+	if (machine_is_omap_3430sdp() || machine_is_omap_ldp()) {
+		/* Disabling AC charger effect on sleep-active transitions */
+		err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &data,
+					R_CFG_P1_TRANSITION);
+		if (err)
+			goto out;
+		data &= ~(1<<1);
+		err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, data ,
+					R_CFG_P1_TRANSITION);
+		if (err)
+			goto out;
+	}
+
+out:
+	if (err)
+		pr_err("TWL4030 wakeup sequence for P1 and P2" \
+			"config error\n");
+	return err;
+}
+
+static int __init twl4030_config_sleep_sequence(u8 address)
+{
+	int err;
+
+	/* Set ACTIVE to SLEEP SEQ address in T2 memory*/
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+				R_SEQ_ADD_A2S);
+
+	if (err)
+		pr_err("TWL4030 sleep sequence config error\n");
+
+	return err;
+}
+
+static int __init twl4030_config_warmreset_sequence(u8 address)
+{
+	int err;
+	u8 rd_data;
+
+	/* Set WARM RESET SEQ address for P1 */
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, address,
+				R_SEQ_ADD_WARM);
+	if (err)
+		goto out;
+
+	/* P1/P2/P3 enable WARMRESET */
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
+				R_P1_SW_EVENTS);
+	if (err)
+		goto out;
+
+	rd_data |= ENABLE_WARMRESET;
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
+				R_P1_SW_EVENTS);
+	if (err)
+		goto out;
+
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
+				R_P2_SW_EVENTS);
+	if (err)
+		goto out;
+
+	rd_data |= ENABLE_WARMRESET;
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
+				R_P2_SW_EVENTS);
+	if (err)
+		goto out;
+
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &rd_data,
+				R_P3_SW_EVENTS);
+	if (err)
+		goto out;
+
+	rd_data |= ENABLE_WARMRESET;
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, rd_data,
+				R_P3_SW_EVENTS);
+out:
+	if (err)
+		pr_err("TWL4030 warmreset seq config error\n");
+	return err;
+}
+
+static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig)
+{
+	int rconfig_addr;
+	int err;
+	u8 type;
+	u8 grp;
+
+	if (rconfig->resource > TOTAL_RESOURCES) {
+		pr_err("TWL4030 Resource %d does not exist\n",
+			rconfig->resource);
+		return -EINVAL;
+	}
+
+	rconfig_addr = res_config_addrs[rconfig->resource];
+
+	/* Set resource group */
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp,
+				rconfig_addr + DEVGROUP_OFFSET);
+	if (err) {
+		pr_err("TWL4030 Resource %d group could not be read\n",
+			rconfig->resource);
+		return err;
+	}
+
+	if (rconfig->devgroup >= 0) {
+		grp &= ~DEVGROUP_MASK;
+		grp |= rconfig->devgroup << DEVGROUP_SHIFT;
+		err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+					grp, rconfig_addr + DEVGROUP_OFFSET);
+		if (err < 0) {
+			pr_err("TWL4030 failed to program devgroup\n");
+			return err;
+		}
+	}
+
+	/* Set resource types */
+	err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type,
+				rconfig_addr + TYPE_OFFSET);
+	if (err < 0) {
+		pr_err("TWL4030 Resource %d type could not be read\n",
+			rconfig->resource);
+		return err;
+	}
+
+	if (rconfig->type >= 0) {
+		type &= ~TYPE_MASK;
+		type |= rconfig->type << TYPE_SHIFT;
+	}
+
+	if (rconfig->type2 >= 0) {
+		type &= ~TYPE2_MASK;
+		type |= rconfig->type2 << TYPE2_SHIFT;
+	}
+
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+				type, rconfig_addr + TYPE_OFFSET);
+	if (err < 0) {
+		pr_err("TWL4030 failed to program resource type\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static int __init load_twl4030_script(struct twl4030_script *tscript,
+	       u8 address)
+{
+	int err;
+	static int order;
+
+	/* Make sure the script isn't going beyond last valid address (0x3f) */
+	if ((address + tscript->size) > END_OF_SCRIPT) {
+		pr_err("TWL4030 scripts too big error\n");
+		return -EINVAL;
+	}
+
+	err = twl4030_write_script(address, tscript->script, tscript->size);
+	if (err)
+		goto out;
+
+	if (tscript->flags & TWL4030_WRST_SCRIPT) {
+		err = twl4030_config_warmreset_sequence(address);
+		if (err)
+			goto out;
+	}
+	if (tscript->flags & TWL4030_WAKEUP12_SCRIPT) {
+		err = twl4030_config_wakeup12_sequence(address);
+		if (err)
+			goto out;
+		order = 1;
+	}
+	if (tscript->flags & TWL4030_WAKEUP3_SCRIPT) {
+		err = twl4030_config_wakeup3_sequence(address);
+		if (err)
+			goto out;
+	}
+	if (tscript->flags & TWL4030_SLEEP_SCRIPT)
+		if (order)
+			pr_warning("TWL4030: Bad order of scripts (sleep "\
+					"script before wakeup) Leads to boot"\
+					"failure on some boards\n");
+		err = twl4030_config_sleep_sequence(address);
+out:
+	return err;
+}
+
+void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
+{
+	int err = 0;
+	int i;
+	struct twl4030_resconfig *resconfig;
+	u8 address = twl4030_start_script_address;
+
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_1,
+				R_PROTECT_KEY);
+	if (err)
+		goto unlock;
+
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, R_KEY_2,
+				R_PROTECT_KEY);
+	if (err)
+		goto unlock;
+
+	for (i = 0; i < twl4030_scripts->num; i++) {
+		err = load_twl4030_script(twl4030_scripts->scripts[i], address);
+		if (err)
+			goto load;
+		address += twl4030_scripts->scripts[i]->size;
+	}
+
+	resconfig = twl4030_scripts->resource_config;
+	if (resconfig) {
+		while (resconfig->resource) {
+			err = twl4030_configure_resource(resconfig);
+			if (err)
+				goto resource;
+			resconfig++;
+
+		}
+	}
+
+	err = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, R_PROTECT_KEY);
+	if (err)
+		pr_err("TWL4030 Unable to relock registers\n");
+	return;
+
+unlock:
+	if (err)
+		pr_err("TWL4030 Unable to unlock registers\n");
+	return;
+load:
+	if (err)
+		pr_err("TWL4030 failed to load scripts\n");
+	return;
+resource:
+	if (err)
+		pr_err("TWL4030 failed to configure resource\n");
+	return;
+}
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
new file mode 100644
index 0000000..49b7885
--- /dev/null
+++ b/drivers/mfd/wm831x-core.c
@@ -0,0 +1,1549 @@
+/*
+ * wm831x-core.c  --  Device access for Wolfson WM831x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/i2c.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
+#include <linux/mfd/wm831x/auxadc.h>
+#include <linux/mfd/wm831x/otp.h>
+#include <linux/mfd/wm831x/regulator.h>
+
+/* Current settings - values are 2*2^(reg_val/4) microamps.  These are
+ * exported since they are used by multiple drivers.
+ */
+int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL] = {
+	2,
+	2,
+	3,
+	3,
+	4,
+	5,
+	6,
+	7,
+	8,
+	10,
+	11,
+	13,
+	16,
+	19,
+	23,
+	27,
+	32,
+	38,
+	45,
+	54,
+	64,
+	76,
+	91,
+	108,
+	128,
+	152,
+	181,
+	215,
+	256,
+	304,
+	362,
+	431,
+	512,
+	609,
+	724,
+	861,
+	1024,
+	1218,
+	1448,
+	1722,
+	2048,
+	2435,
+	2896,
+	3444,
+	4096,
+	4871,
+	5793,
+	6889,
+	8192,
+	9742,
+	11585,
+	13777,
+	16384,
+	19484,
+	23170,
+	27554,
+};
+EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
+
+enum wm831x_parent {
+	WM8310 = 0,
+	WM8311 = 1,
+	WM8312 = 2,
+};
+
+static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
+{
+	if (!wm831x->locked)
+		return 0;
+
+	switch (reg) {
+	case WM831X_WATCHDOG:
+	case WM831X_DC4_CONTROL:
+	case WM831X_ON_PIN_CONTROL:
+	case WM831X_BACKUP_CHARGER_CONTROL:
+	case WM831X_CHARGER_CONTROL_1:
+	case WM831X_CHARGER_CONTROL_2:
+		return 1;
+
+	default:
+		return 0;
+	}
+}
+
+/**
+ * wm831x_reg_unlock: Unlock user keyed registers
+ *
+ * The WM831x has a user key preventing writes to particularly
+ * critical registers.  This function locks those registers,
+ * allowing writes to them.
+ */
+void wm831x_reg_lock(struct wm831x *wm831x)
+{
+	int ret;
+
+	ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
+	if (ret == 0) {
+		dev_vdbg(wm831x->dev, "Registers locked\n");
+
+		mutex_lock(&wm831x->io_lock);
+		WARN_ON(wm831x->locked);
+		wm831x->locked = 1;
+		mutex_unlock(&wm831x->io_lock);
+	} else {
+		dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret);
+	}
+
+}
+EXPORT_SYMBOL_GPL(wm831x_reg_lock);
+
+/**
+ * wm831x_reg_unlock: Unlock user keyed registers
+ *
+ * The WM831x has a user key preventing writes to particularly
+ * critical registers.  This function locks those registers,
+ * preventing spurious writes.
+ */
+int wm831x_reg_unlock(struct wm831x *wm831x)
+{
+	int ret;
+
+	/* 0x9716 is the value required to unlock the registers */
+	ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716);
+	if (ret == 0) {
+		dev_vdbg(wm831x->dev, "Registers unlocked\n");
+
+		mutex_lock(&wm831x->io_lock);
+		WARN_ON(!wm831x->locked);
+		wm831x->locked = 0;
+		mutex_unlock(&wm831x->io_lock);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
+
+static int wm831x_read(struct wm831x *wm831x, unsigned short reg,
+		       int bytes, void *dest)
+{
+	int ret, i;
+	u16 *buf = dest;
+
+	BUG_ON(bytes % 2);
+	BUG_ON(bytes <= 0);
+
+	ret = wm831x->read_dev(wm831x, reg, bytes, dest);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < bytes / 2; i++) {
+		buf[i] = be16_to_cpu(buf[i]);
+
+		dev_vdbg(wm831x->dev, "Read %04x from R%d(0x%x)\n",
+			 buf[i], reg + i, reg + i);
+	}
+
+	return 0;
+}
+
+/**
+ * wm831x_reg_read: Read a single WM831x register.
+ *
+ * @wm831x: Device to read from.
+ * @reg: Register to read.
+ */
+int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
+{
+	unsigned short val;
+	int ret;
+
+	mutex_lock(&wm831x->io_lock);
+
+	ret = wm831x_read(wm831x, reg, 2, &val);
+
+	mutex_unlock(&wm831x->io_lock);
+
+	if (ret < 0)
+		return ret;
+	else
+		return val;
+}
+EXPORT_SYMBOL_GPL(wm831x_reg_read);
+
+/**
+ * wm831x_bulk_read: Read multiple WM831x registers
+ *
+ * @wm831x: Device to read from
+ * @reg: First register
+ * @count: Number of registers
+ * @buf: Buffer to fill.
+ */
+int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
+		     int count, u16 *buf)
+{
+	int ret;
+
+	mutex_lock(&wm831x->io_lock);
+
+	ret = wm831x_read(wm831x, reg, count * 2, buf);
+
+	mutex_unlock(&wm831x->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_bulk_read);
+
+static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
+			int bytes, void *src)
+{
+	u16 *buf = src;
+	int i;
+
+	BUG_ON(bytes % 2);
+	BUG_ON(bytes <= 0);
+
+	for (i = 0; i < bytes / 2; i++) {
+		if (wm831x_reg_locked(wm831x, reg))
+			return -EPERM;
+
+		dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
+			 buf[i], reg + i, reg + i);
+
+		buf[i] = cpu_to_be16(buf[i]);
+	}
+
+	return wm831x->write_dev(wm831x, reg, bytes, src);
+}
+
+/**
+ * wm831x_reg_write: Write a single WM831x register.
+ *
+ * @wm831x: Device to write to.
+ * @reg: Register to write to.
+ * @val: Value to write.
+ */
+int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
+		     unsigned short val)
+{
+	int ret;
+
+	mutex_lock(&wm831x->io_lock);
+
+	ret = wm831x_write(wm831x, reg, 2, &val);
+
+	mutex_unlock(&wm831x->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_reg_write);
+
+/**
+ * wm831x_set_bits: Set the value of a bitfield in a WM831x register
+ *
+ * @wm831x: Device to write to.
+ * @reg: Register to write to.
+ * @mask: Mask of bits to set.
+ * @val: Value to set (unshifted)
+ */
+int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
+		    unsigned short mask, unsigned short val)
+{
+	int ret;
+	u16 r;
+
+	mutex_lock(&wm831x->io_lock);
+
+	ret = wm831x_read(wm831x, reg, 2, &r);
+	if (ret < 0)
+		goto out;
+
+	r &= ~mask;
+	r |= val;
+
+	ret = wm831x_write(wm831x, reg, 2, &r);
+
+out:
+	mutex_unlock(&wm831x->io_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_set_bits);
+
+/**
+ * wm831x_auxadc_read: Read a value from the WM831x AUXADC
+ *
+ * @wm831x: Device to read from.
+ * @input: AUXADC input to read.
+ */
+int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input)
+{
+	int tries = 10;
+	int ret, src;
+
+	mutex_lock(&wm831x->auxadc_lock);
+
+	ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
+			      WM831X_AUX_ENA, WM831X_AUX_ENA);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to enable AUXADC: %d\n", ret);
+		goto out;
+	}
+
+	/* We force a single source at present */
+	src = input;
+	ret = wm831x_reg_write(wm831x, WM831X_AUXADC_SOURCE,
+			       1 << src);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to set AUXADC source: %d\n", ret);
+		goto out;
+	}
+
+	ret = wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL,
+			      WM831X_AUX_CVT_ENA, WM831X_AUX_CVT_ENA);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to start AUXADC: %d\n", ret);
+		goto disable;
+	}
+
+	do {
+		msleep(1);
+
+		ret = wm831x_reg_read(wm831x, WM831X_AUXADC_CONTROL);
+		if (ret < 0)
+			ret = WM831X_AUX_CVT_ENA;
+	} while ((ret & WM831X_AUX_CVT_ENA) && --tries);
+
+	if (ret & WM831X_AUX_CVT_ENA) {
+		dev_err(wm831x->dev, "Timed out reading AUXADC\n");
+		ret = -EBUSY;
+		goto disable;
+	}
+
+	ret = wm831x_reg_read(wm831x, WM831X_AUXADC_DATA);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read AUXADC data: %d\n", ret);
+	} else {
+		src = ((ret & WM831X_AUX_DATA_SRC_MASK)
+		       >> WM831X_AUX_DATA_SRC_SHIFT) - 1;
+
+		if (src == 14)
+			src = WM831X_AUX_CAL;
+
+		if (src != input) {
+			dev_err(wm831x->dev, "Data from source %d not %d\n",
+				src, input);
+			ret = -EINVAL;
+		} else {
+			ret &= WM831X_AUX_DATA_MASK;
+		}
+	}
+
+disable:
+	wm831x_set_bits(wm831x, WM831X_AUXADC_CONTROL, WM831X_AUX_ENA, 0);
+out:
+	mutex_unlock(&wm831x->auxadc_lock);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_auxadc_read);
+
+/**
+ * wm831x_auxadc_read_uv: Read a voltage from the WM831x AUXADC
+ *
+ * @wm831x: Device to read from.
+ * @input: AUXADC input to read.
+ */
+int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input)
+{
+	int ret;
+
+	ret = wm831x_auxadc_read(wm831x, input);
+	if (ret < 0)
+		return ret;
+
+	ret *= 1465;
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_auxadc_read_uv);
+
+static struct resource wm831x_dcdc1_resources[] = {
+	{
+		.start = WM831X_DC1_CONTROL_1,
+		.end   = WM831X_DC1_DVS_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_DC1,
+		.end   = WM831X_IRQ_UV_DC1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name  = "HC",
+		.start = WM831X_IRQ_HC_DC1,
+		.end   = WM831X_IRQ_HC_DC1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+
+static struct resource wm831x_dcdc2_resources[] = {
+	{
+		.start = WM831X_DC2_CONTROL_1,
+		.end   = WM831X_DC2_DVS_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_DC2,
+		.end   = WM831X_IRQ_UV_DC2,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name  = "HC",
+		.start = WM831X_IRQ_HC_DC2,
+		.end   = WM831X_IRQ_HC_DC2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_dcdc3_resources[] = {
+	{
+		.start = WM831X_DC3_CONTROL_1,
+		.end   = WM831X_DC3_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_DC3,
+		.end   = WM831X_IRQ_UV_DC3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_dcdc4_resources[] = {
+	{
+		.start = WM831X_DC4_CONTROL,
+		.end   = WM831X_DC4_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_DC4,
+		.end   = WM831X_IRQ_UV_DC4,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_gpio_resources[] = {
+	{
+		.start = WM831X_IRQ_GPIO_1,
+		.end   = WM831X_IRQ_GPIO_16,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_isink1_resources[] = {
+	{
+		.start = WM831X_CURRENT_SINK_1,
+		.end   = WM831X_CURRENT_SINK_1,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.start = WM831X_IRQ_CS1,
+		.end   = WM831X_IRQ_CS1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_isink2_resources[] = {
+	{
+		.start = WM831X_CURRENT_SINK_2,
+		.end   = WM831X_CURRENT_SINK_2,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.start = WM831X_IRQ_CS2,
+		.end   = WM831X_IRQ_CS2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo1_resources[] = {
+	{
+		.start = WM831X_LDO1_CONTROL,
+		.end   = WM831X_LDO1_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO1,
+		.end   = WM831X_IRQ_UV_LDO1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo2_resources[] = {
+	{
+		.start = WM831X_LDO2_CONTROL,
+		.end   = WM831X_LDO2_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO2,
+		.end   = WM831X_IRQ_UV_LDO2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo3_resources[] = {
+	{
+		.start = WM831X_LDO3_CONTROL,
+		.end   = WM831X_LDO3_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO3,
+		.end   = WM831X_IRQ_UV_LDO3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo4_resources[] = {
+	{
+		.start = WM831X_LDO4_CONTROL,
+		.end   = WM831X_LDO4_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO4,
+		.end   = WM831X_IRQ_UV_LDO4,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo5_resources[] = {
+	{
+		.start = WM831X_LDO5_CONTROL,
+		.end   = WM831X_LDO5_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO5,
+		.end   = WM831X_IRQ_UV_LDO5,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo6_resources[] = {
+	{
+		.start = WM831X_LDO6_CONTROL,
+		.end   = WM831X_LDO6_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO6,
+		.end   = WM831X_IRQ_UV_LDO6,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo7_resources[] = {
+	{
+		.start = WM831X_LDO7_CONTROL,
+		.end   = WM831X_LDO7_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO7,
+		.end   = WM831X_IRQ_UV_LDO7,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo8_resources[] = {
+	{
+		.start = WM831X_LDO8_CONTROL,
+		.end   = WM831X_LDO8_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO8,
+		.end   = WM831X_IRQ_UV_LDO8,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo9_resources[] = {
+	{
+		.start = WM831X_LDO9_CONTROL,
+		.end   = WM831X_LDO9_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO9,
+		.end   = WM831X_IRQ_UV_LDO9,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo10_resources[] = {
+	{
+		.start = WM831X_LDO10_CONTROL,
+		.end   = WM831X_LDO10_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+	{
+		.name  = "UV",
+		.start = WM831X_IRQ_UV_LDO10,
+		.end   = WM831X_IRQ_UV_LDO10,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_ldo11_resources[] = {
+	{
+		.start = WM831X_LDO11_ON_CONTROL,
+		.end   = WM831X_LDO11_SLEEP_CONTROL,
+		.flags = IORESOURCE_IO,
+	},
+};
+
+static struct resource wm831x_on_resources[] = {
+	{
+		.start = WM831X_IRQ_ON,
+		.end   = WM831X_IRQ_ON,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+
+static struct resource wm831x_power_resources[] = {
+	{
+		.name = "SYSLO",
+		.start = WM831X_IRQ_PPM_SYSLO,
+		.end   = WM831X_IRQ_PPM_SYSLO,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "PWR SRC",
+		.start = WM831X_IRQ_PPM_PWR_SRC,
+		.end   = WM831X_IRQ_PPM_PWR_SRC,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "USB CURR",
+		.start = WM831X_IRQ_PPM_USB_CURR,
+		.end   = WM831X_IRQ_PPM_USB_CURR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "BATT HOT",
+		.start = WM831X_IRQ_CHG_BATT_HOT,
+		.end   = WM831X_IRQ_CHG_BATT_HOT,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "BATT COLD",
+		.start = WM831X_IRQ_CHG_BATT_COLD,
+		.end   = WM831X_IRQ_CHG_BATT_COLD,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "BATT FAIL",
+		.start = WM831X_IRQ_CHG_BATT_FAIL,
+		.end   = WM831X_IRQ_CHG_BATT_FAIL,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "OV",
+		.start = WM831X_IRQ_CHG_OV,
+		.end   = WM831X_IRQ_CHG_OV,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "END",
+		.start = WM831X_IRQ_CHG_END,
+		.end   = WM831X_IRQ_CHG_END,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "TO",
+		.start = WM831X_IRQ_CHG_TO,
+		.end   = WM831X_IRQ_CHG_TO,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "MODE",
+		.start = WM831X_IRQ_CHG_MODE,
+		.end   = WM831X_IRQ_CHG_MODE,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "START",
+		.start = WM831X_IRQ_CHG_START,
+		.end   = WM831X_IRQ_CHG_START,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_rtc_resources[] = {
+	{
+		.name = "PER",
+		.start = WM831X_IRQ_RTC_PER,
+		.end   = WM831X_IRQ_RTC_PER,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "ALM",
+		.start = WM831X_IRQ_RTC_ALM,
+		.end   = WM831X_IRQ_RTC_ALM,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_status1_resources[] = {
+	{
+		.start = WM831X_STATUS_LED_1,
+		.end   = WM831X_STATUS_LED_1,
+		.flags = IORESOURCE_IO,
+	},
+};
+
+static struct resource wm831x_status2_resources[] = {
+	{
+		.start = WM831X_STATUS_LED_2,
+		.end   = WM831X_STATUS_LED_2,
+		.flags = IORESOURCE_IO,
+	},
+};
+
+static struct resource wm831x_touch_resources[] = {
+	{
+		.name = "TCHPD",
+		.start = WM831X_IRQ_TCHPD,
+		.end   = WM831X_IRQ_TCHPD,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "TCHDATA",
+		.start = WM831X_IRQ_TCHDATA,
+		.end   = WM831X_IRQ_TCHDATA,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource wm831x_wdt_resources[] = {
+	{
+		.start = WM831X_IRQ_WDOG_TO,
+		.end   = WM831X_IRQ_WDOG_TO,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell wm8310_devs[] = {
+	{
+		.name = "wm831x-buckv",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
+		.resources = wm831x_dcdc1_resources,
+	},
+	{
+		.name = "wm831x-buckv",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
+		.resources = wm831x_dcdc2_resources,
+	},
+	{
+		.name = "wm831x-buckp",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
+		.resources = wm831x_dcdc3_resources,
+	},
+	{
+		.name = "wm831x-boostp",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
+		.resources = wm831x_dcdc4_resources,
+	},
+	{
+		.name = "wm831x-epe",
+		.id = 1,
+	},
+	{
+		.name = "wm831x-epe",
+		.id = 2,
+	},
+	{
+		.name = "wm831x-gpio",
+		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
+		.resources = wm831x_gpio_resources,
+	},
+	{
+		.name = "wm831x-hwmon",
+	},
+	{
+		.name = "wm831x-isink",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
+		.resources = wm831x_isink1_resources,
+	},
+	{
+		.name = "wm831x-isink",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
+		.resources = wm831x_isink2_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
+		.resources = wm831x_ldo1_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
+		.resources = wm831x_ldo2_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
+		.resources = wm831x_ldo3_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
+		.resources = wm831x_ldo4_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
+		.resources = wm831x_ldo5_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 6,
+		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
+		.resources = wm831x_ldo6_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 7,
+		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
+		.resources = wm831x_ldo7_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 8,
+		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
+		.resources = wm831x_ldo8_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 9,
+		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
+		.resources = wm831x_ldo9_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 10,
+		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
+		.resources = wm831x_ldo10_resources,
+	},
+	{
+		.name = "wm831x-alive-ldo",
+		.id = 11,
+		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
+		.resources = wm831x_ldo11_resources,
+	},
+	{
+		.name = "wm831x-on",
+		.num_resources = ARRAY_SIZE(wm831x_on_resources),
+		.resources = wm831x_on_resources,
+	},
+	{
+		.name = "wm831x-power",
+		.num_resources = ARRAY_SIZE(wm831x_power_resources),
+		.resources = wm831x_power_resources,
+	},
+	{
+		.name = "wm831x-rtc",
+		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
+		.resources = wm831x_rtc_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
+		.resources = wm831x_status1_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
+		.resources = wm831x_status2_resources,
+	},
+	{
+		.name = "wm831x-watchdog",
+		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
+		.resources = wm831x_wdt_resources,
+	},
+};
+
+static struct mfd_cell wm8311_devs[] = {
+	{
+		.name = "wm831x-buckv",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
+		.resources = wm831x_dcdc1_resources,
+	},
+	{
+		.name = "wm831x-buckv",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
+		.resources = wm831x_dcdc2_resources,
+	},
+	{
+		.name = "wm831x-buckp",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
+		.resources = wm831x_dcdc3_resources,
+	},
+	{
+		.name = "wm831x-boostp",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
+		.resources = wm831x_dcdc4_resources,
+	},
+	{
+		.name = "wm831x-epe",
+		.id = 1,
+	},
+	{
+		.name = "wm831x-epe",
+		.id = 2,
+	},
+	{
+		.name = "wm831x-gpio",
+		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
+		.resources = wm831x_gpio_resources,
+	},
+	{
+		.name = "wm831x-hwmon",
+	},
+	{
+		.name = "wm831x-isink",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
+		.resources = wm831x_isink1_resources,
+	},
+	{
+		.name = "wm831x-isink",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
+		.resources = wm831x_isink2_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
+		.resources = wm831x_ldo1_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
+		.resources = wm831x_ldo2_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
+		.resources = wm831x_ldo3_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
+		.resources = wm831x_ldo4_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
+		.resources = wm831x_ldo5_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 7,
+		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
+		.resources = wm831x_ldo7_resources,
+	},
+	{
+		.name = "wm831x-alive-ldo",
+		.id = 11,
+		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
+		.resources = wm831x_ldo11_resources,
+	},
+	{
+		.name = "wm831x-on",
+		.num_resources = ARRAY_SIZE(wm831x_on_resources),
+		.resources = wm831x_on_resources,
+	},
+	{
+		.name = "wm831x-power",
+		.num_resources = ARRAY_SIZE(wm831x_power_resources),
+		.resources = wm831x_power_resources,
+	},
+	{
+		.name = "wm831x-rtc",
+		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
+		.resources = wm831x_rtc_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
+		.resources = wm831x_status1_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
+		.resources = wm831x_status2_resources,
+	},
+	{
+		.name = "wm831x-touch",
+		.num_resources = ARRAY_SIZE(wm831x_touch_resources),
+		.resources = wm831x_touch_resources,
+	},
+	{
+		.name = "wm831x-watchdog",
+		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
+		.resources = wm831x_wdt_resources,
+	},
+};
+
+static struct mfd_cell wm8312_devs[] = {
+	{
+		.name = "wm831x-buckv",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
+		.resources = wm831x_dcdc1_resources,
+	},
+	{
+		.name = "wm831x-buckv",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
+		.resources = wm831x_dcdc2_resources,
+	},
+	{
+		.name = "wm831x-buckp",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
+		.resources = wm831x_dcdc3_resources,
+	},
+	{
+		.name = "wm831x-boostp",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
+		.resources = wm831x_dcdc4_resources,
+	},
+	{
+		.name = "wm831x-epe",
+		.id = 1,
+	},
+	{
+		.name = "wm831x-epe",
+		.id = 2,
+	},
+	{
+		.name = "wm831x-gpio",
+		.num_resources = ARRAY_SIZE(wm831x_gpio_resources),
+		.resources = wm831x_gpio_resources,
+	},
+	{
+		.name = "wm831x-hwmon",
+	},
+	{
+		.name = "wm831x-isink",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_isink1_resources),
+		.resources = wm831x_isink1_resources,
+	},
+	{
+		.name = "wm831x-isink",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_isink2_resources),
+		.resources = wm831x_isink2_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
+		.resources = wm831x_ldo1_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
+		.resources = wm831x_ldo2_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
+		.resources = wm831x_ldo3_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
+		.resources = wm831x_ldo4_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
+		.resources = wm831x_ldo5_resources,
+	},
+	{
+		.name = "wm831x-ldo",
+		.id = 6,
+		.num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
+		.resources = wm831x_ldo6_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 7,
+		.num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
+		.resources = wm831x_ldo7_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 8,
+		.num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
+		.resources = wm831x_ldo8_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 9,
+		.num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
+		.resources = wm831x_ldo9_resources,
+	},
+	{
+		.name = "wm831x-aldo",
+		.id = 10,
+		.num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
+		.resources = wm831x_ldo10_resources,
+	},
+	{
+		.name = "wm831x-alive-ldo",
+		.id = 11,
+		.num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
+		.resources = wm831x_ldo11_resources,
+	},
+	{
+		.name = "wm831x-on",
+		.num_resources = ARRAY_SIZE(wm831x_on_resources),
+		.resources = wm831x_on_resources,
+	},
+	{
+		.name = "wm831x-power",
+		.num_resources = ARRAY_SIZE(wm831x_power_resources),
+		.resources = wm831x_power_resources,
+	},
+	{
+		.name = "wm831x-rtc",
+		.num_resources = ARRAY_SIZE(wm831x_rtc_resources),
+		.resources = wm831x_rtc_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(wm831x_status1_resources),
+		.resources = wm831x_status1_resources,
+	},
+	{
+		.name = "wm831x-status",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(wm831x_status2_resources),
+		.resources = wm831x_status2_resources,
+	},
+	{
+		.name = "wm831x-touch",
+		.num_resources = ARRAY_SIZE(wm831x_touch_resources),
+		.resources = wm831x_touch_resources,
+	},
+	{
+		.name = "wm831x-watchdog",
+		.num_resources = ARRAY_SIZE(wm831x_wdt_resources),
+		.resources = wm831x_wdt_resources,
+	},
+};
+
+static struct mfd_cell backlight_devs[] = {
+	{
+		.name = "wm831x-backlight",
+	},
+};
+
+/*
+ * Instantiate the generic non-control parts of the device.
+ */
+static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
+{
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int rev;
+	enum wm831x_parent parent;
+	int ret;
+
+	mutex_init(&wm831x->io_lock);
+	mutex_init(&wm831x->key_lock);
+	mutex_init(&wm831x->auxadc_lock);
+	dev_set_drvdata(wm831x->dev, wm831x);
+
+	ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
+		goto err;
+	}
+	if (ret != 0x6204) {
+		dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = wm831x_reg_read(wm831x, WM831X_REVISION);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
+		goto err;
+	}
+	rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
+
+	ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
+		goto err;
+	}
+
+	switch (ret) {
+	case 0x8310:
+		parent = WM8310;
+		switch (rev) {
+		case 0:
+			dev_info(wm831x->dev, "WM8310 revision %c\n",
+				 'A' + rev);
+			break;
+		}
+		break;
+
+	case 0x8311:
+		parent = WM8311;
+		switch (rev) {
+		case 0:
+			dev_info(wm831x->dev, "WM8311 revision %c\n",
+				 'A' + rev);
+			break;
+		}
+		break;
+
+	case 0x8312:
+		parent = WM8312;
+		switch (rev) {
+		case 0:
+			dev_info(wm831x->dev, "WM8312 revision %c\n",
+				 'A' + rev);
+			break;
+		}
+		break;
+
+	case 0:
+		/* Some engineering samples do not have the ID set,
+		 * rely on the device being registered correctly.
+		 * This will need revisiting for future devices with
+		 * multiple dies.
+		 */
+		parent = id;
+		switch (rev) {
+		case 0:
+			dev_info(wm831x->dev, "WM831%d ES revision %c\n",
+				 parent, 'A' + rev);
+			break;
+		}
+		break;
+
+	default:
+		dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* This will need revisiting in future but is OK for all
+	 * current parts.
+	 */
+	if (parent != id)
+		dev_warn(wm831x->dev, "Device was registered as a WM831%lu\n",
+			 id);
+
+	/* Bootstrap the user key */
+	ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
+		goto err;
+	}
+	if (ret != 0) {
+		dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
+			 ret);
+		wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
+	}
+	wm831x->locked = 1;
+
+	if (pdata && pdata->pre_init) {
+		ret = pdata->pre_init(wm831x);
+		if (ret != 0) {
+			dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
+			goto err;
+		}
+	}
+
+	ret = wm831x_irq_init(wm831x, irq);
+	if (ret != 0)
+		goto err;
+
+	/* The core device is up, instantiate the subdevices. */
+	switch (parent) {
+	case WM8310:
+		ret = mfd_add_devices(wm831x->dev, -1,
+				      wm8310_devs, ARRAY_SIZE(wm8310_devs),
+				      NULL, 0);
+		break;
+
+	case WM8311:
+		ret = mfd_add_devices(wm831x->dev, -1,
+				      wm8311_devs, ARRAY_SIZE(wm8311_devs),
+				      NULL, 0);
+		break;
+
+	case WM8312:
+		ret = mfd_add_devices(wm831x->dev, -1,
+				      wm8312_devs, ARRAY_SIZE(wm8312_devs),
+				      NULL, 0);
+		break;
+
+	default:
+		/* If this happens the bus probe function is buggy */
+		BUG();
+	}
+
+	if (ret != 0) {
+		dev_err(wm831x->dev, "Failed to add children\n");
+		goto err_irq;
+	}
+
+	if (pdata && pdata->backlight) {
+		/* Treat errors as non-critical */
+		ret = mfd_add_devices(wm831x->dev, -1, backlight_devs,
+				      ARRAY_SIZE(backlight_devs), NULL, 0);
+		if (ret < 0)
+			dev_err(wm831x->dev, "Failed to add backlight: %d\n",
+				ret);
+	}
+
+	wm831x_otp_init(wm831x);
+
+	if (pdata && pdata->post_init) {
+		ret = pdata->post_init(wm831x);
+		if (ret != 0) {
+			dev_err(wm831x->dev, "post_init() failed: %d\n", ret);
+			goto err_irq;
+		}
+	}
+
+	return 0;
+
+err_irq:
+	wm831x_irq_exit(wm831x);
+err:
+	mfd_remove_devices(wm831x->dev);
+	kfree(wm831x);
+	return ret;
+}
+
+static void wm831x_device_exit(struct wm831x *wm831x)
+{
+	wm831x_otp_exit(wm831x);
+	mfd_remove_devices(wm831x->dev);
+	wm831x_irq_exit(wm831x);
+	kfree(wm831x);
+}
+
+static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
+				  int bytes, void *dest)
+{
+	struct i2c_client *i2c = wm831x->control_data;
+	int ret;
+	u16 r = cpu_to_be16(reg);
+
+	ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
+	if (ret < 0)
+		return ret;
+	if (ret != 2)
+		return -EIO;
+
+	ret = i2c_master_recv(i2c, dest, bytes);
+	if (ret < 0)
+		return ret;
+	if (ret != bytes)
+		return -EIO;
+	return 0;
+}
+
+/* Currently we allocate the write buffer on the stack; this is OK for
+ * small writes - if we need to do large writes this will need to be
+ * revised.
+ */
+static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
+				   int bytes, void *src)
+{
+	struct i2c_client *i2c = wm831x->control_data;
+	unsigned char msg[bytes + 2];
+	int ret;
+
+	reg = cpu_to_be16(reg);
+	memcpy(&msg[0], &reg, 2);
+	memcpy(&msg[2], src, bytes);
+
+	ret = i2c_master_send(i2c, msg, bytes + 2);
+	if (ret < 0)
+		return ret;
+	if (ret < bytes + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int wm831x_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct wm831x *wm831x;
+
+	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
+	if (wm831x == NULL) {
+		kfree(i2c);
+		return -ENOMEM;
+	}
+
+	i2c_set_clientdata(i2c, wm831x);
+	wm831x->dev = &i2c->dev;
+	wm831x->control_data = i2c;
+	wm831x->read_dev = wm831x_i2c_read_device;
+	wm831x->write_dev = wm831x_i2c_write_device;
+
+	return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
+}
+
+static int wm831x_i2c_remove(struct i2c_client *i2c)
+{
+	struct wm831x *wm831x = i2c_get_clientdata(i2c);
+
+	wm831x_device_exit(wm831x);
+
+	return 0;
+}
+
+static const struct i2c_device_id wm831x_i2c_id[] = {
+	{ "wm8310", WM8310 },
+	{ "wm8311", WM8311 },
+	{ "wm8312", WM8312 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
+
+
+static struct i2c_driver wm831x_i2c_driver = {
+	.driver = {
+		   .name = "wm831x",
+		   .owner = THIS_MODULE,
+	},
+	.probe = wm831x_i2c_probe,
+	.remove = wm831x_i2c_remove,
+	.id_table = wm831x_i2c_id,
+};
+
+static int __init wm831x_i2c_init(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&wm831x_i2c_driver);
+	if (ret != 0)
+		pr_err("Failed to register wm831x I2C driver: %d\n", ret);
+
+	return ret;
+}
+subsys_initcall(wm831x_i2c_init);
+
+static void __exit wm831x_i2c_exit(void)
+{
+	i2c_del_driver(&wm831x_i2c_driver);
+}
+module_exit(wm831x_i2c_exit);
+
+MODULE_DESCRIPTION("I2C support for the WM831X AudioPlus PMIC");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Brown");
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
new file mode 100644
index 0000000..d3015df
--- /dev/null
+++ b/drivers/mfd/wm831x-irq.c
@@ -0,0 +1,559 @@
+/*
+ * wm831x-irq.c  --  Interrupt controller support for Wolfson WM831x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/interrupt.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/irq.h>
+
+#include <linux/delay.h>
+
+/*
+ * Since generic IRQs don't currently support interrupt controllers on
+ * interrupt driven buses we don't use genirq but instead provide an
+ * interface that looks very much like the standard ones.  This leads
+ * to some bodges, including storing interrupt handler information in
+ * the static irq_data table we use to look up the data for individual
+ * interrupts, but hopefully won't last too long.
+ */
+
+struct wm831x_irq_data {
+	int primary;
+	int reg;
+	int mask;
+	irq_handler_t handler;
+	void *handler_data;
+};
+
+static struct wm831x_irq_data wm831x_irqs[] = {
+	[WM831X_IRQ_TEMP_THW] = {
+		.primary = WM831X_TEMP_INT,
+		.reg = 1,
+		.mask = WM831X_TEMP_THW_EINT,
+	},
+	[WM831X_IRQ_GPIO_1] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP1_EINT,
+	},
+	[WM831X_IRQ_GPIO_2] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP2_EINT,
+	},
+	[WM831X_IRQ_GPIO_3] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP3_EINT,
+	},
+	[WM831X_IRQ_GPIO_4] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP4_EINT,
+	},
+	[WM831X_IRQ_GPIO_5] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP5_EINT,
+	},
+	[WM831X_IRQ_GPIO_6] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP6_EINT,
+	},
+	[WM831X_IRQ_GPIO_7] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP7_EINT,
+	},
+	[WM831X_IRQ_GPIO_8] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP8_EINT,
+	},
+	[WM831X_IRQ_GPIO_9] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP9_EINT,
+	},
+	[WM831X_IRQ_GPIO_10] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP10_EINT,
+	},
+	[WM831X_IRQ_GPIO_11] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP11_EINT,
+	},
+	[WM831X_IRQ_GPIO_12] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP12_EINT,
+	},
+	[WM831X_IRQ_GPIO_13] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP13_EINT,
+	},
+	[WM831X_IRQ_GPIO_14] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP14_EINT,
+	},
+	[WM831X_IRQ_GPIO_15] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP15_EINT,
+	},
+	[WM831X_IRQ_GPIO_16] = {
+		.primary = WM831X_GP_INT,
+		.reg = 5,
+		.mask = WM831X_GP16_EINT,
+	},
+	[WM831X_IRQ_ON] = {
+		.primary = WM831X_ON_PIN_INT,
+		.reg = 1,
+		.mask = WM831X_ON_PIN_EINT,
+	},
+	[WM831X_IRQ_PPM_SYSLO] = {
+		.primary = WM831X_PPM_INT,
+		.reg = 1,
+		.mask = WM831X_PPM_SYSLO_EINT,
+	},
+	[WM831X_IRQ_PPM_PWR_SRC] = {
+		.primary = WM831X_PPM_INT,
+		.reg = 1,
+		.mask = WM831X_PPM_PWR_SRC_EINT,
+	},
+	[WM831X_IRQ_PPM_USB_CURR] = {
+		.primary = WM831X_PPM_INT,
+		.reg = 1,
+		.mask = WM831X_PPM_USB_CURR_EINT,
+	},
+	[WM831X_IRQ_WDOG_TO] = {
+		.primary = WM831X_WDOG_INT,
+		.reg = 1,
+		.mask = WM831X_WDOG_TO_EINT,
+	},
+	[WM831X_IRQ_RTC_PER] = {
+		.primary = WM831X_RTC_INT,
+		.reg = 1,
+		.mask = WM831X_RTC_PER_EINT,
+	},
+	[WM831X_IRQ_RTC_ALM] = {
+		.primary = WM831X_RTC_INT,
+		.reg = 1,
+		.mask = WM831X_RTC_ALM_EINT,
+	},
+	[WM831X_IRQ_CHG_BATT_HOT] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_BATT_HOT_EINT,
+	},
+	[WM831X_IRQ_CHG_BATT_COLD] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_BATT_COLD_EINT,
+	},
+	[WM831X_IRQ_CHG_BATT_FAIL] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_BATT_FAIL_EINT,
+	},
+	[WM831X_IRQ_CHG_OV] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_OV_EINT,
+	},
+	[WM831X_IRQ_CHG_END] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_END_EINT,
+	},
+	[WM831X_IRQ_CHG_TO] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_TO_EINT,
+	},
+	[WM831X_IRQ_CHG_MODE] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_MODE_EINT,
+	},
+	[WM831X_IRQ_CHG_START] = {
+		.primary = WM831X_CHG_INT,
+		.reg = 2,
+		.mask = WM831X_CHG_START_EINT,
+	},
+	[WM831X_IRQ_TCHDATA] = {
+		.primary = WM831X_TCHDATA_INT,
+		.reg = 1,
+		.mask = WM831X_TCHDATA_EINT,
+	},
+	[WM831X_IRQ_TCHPD] = {
+		.primary = WM831X_TCHPD_INT,
+		.reg = 1,
+		.mask = WM831X_TCHPD_EINT,
+	},
+	[WM831X_IRQ_AUXADC_DATA] = {
+		.primary = WM831X_AUXADC_INT,
+		.reg = 1,
+		.mask = WM831X_AUXADC_DATA_EINT,
+	},
+	[WM831X_IRQ_AUXADC_DCOMP1] = {
+		.primary = WM831X_AUXADC_INT,
+		.reg = 1,
+		.mask = WM831X_AUXADC_DCOMP1_EINT,
+	},
+	[WM831X_IRQ_AUXADC_DCOMP2] = {
+		.primary = WM831X_AUXADC_INT,
+		.reg = 1,
+		.mask = WM831X_AUXADC_DCOMP2_EINT,
+	},
+	[WM831X_IRQ_AUXADC_DCOMP3] = {
+		.primary = WM831X_AUXADC_INT,
+		.reg = 1,
+		.mask = WM831X_AUXADC_DCOMP3_EINT,
+	},
+	[WM831X_IRQ_AUXADC_DCOMP4] = {
+		.primary = WM831X_AUXADC_INT,
+		.reg = 1,
+		.mask = WM831X_AUXADC_DCOMP4_EINT,
+	},
+	[WM831X_IRQ_CS1] = {
+		.primary = WM831X_CS_INT,
+		.reg = 2,
+		.mask = WM831X_CS1_EINT,
+	},
+	[WM831X_IRQ_CS2] = {
+		.primary = WM831X_CS_INT,
+		.reg = 2,
+		.mask = WM831X_CS2_EINT,
+	},
+	[WM831X_IRQ_HC_DC1] = {
+		.primary = WM831X_HC_INT,
+		.reg = 4,
+		.mask = WM831X_HC_DC1_EINT,
+	},
+	[WM831X_IRQ_HC_DC2] = {
+		.primary = WM831X_HC_INT,
+		.reg = 4,
+		.mask = WM831X_HC_DC2_EINT,
+	},
+	[WM831X_IRQ_UV_LDO1] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO1_EINT,
+	},
+	[WM831X_IRQ_UV_LDO2] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO2_EINT,
+	},
+	[WM831X_IRQ_UV_LDO3] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO3_EINT,
+	},
+	[WM831X_IRQ_UV_LDO4] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO4_EINT,
+	},
+	[WM831X_IRQ_UV_LDO5] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO5_EINT,
+	},
+	[WM831X_IRQ_UV_LDO6] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO6_EINT,
+	},
+	[WM831X_IRQ_UV_LDO7] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO7_EINT,
+	},
+	[WM831X_IRQ_UV_LDO8] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO8_EINT,
+	},
+	[WM831X_IRQ_UV_LDO9] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO9_EINT,
+	},
+	[WM831X_IRQ_UV_LDO10] = {
+		.primary = WM831X_UV_INT,
+		.reg = 3,
+		.mask = WM831X_UV_LDO10_EINT,
+	},
+	[WM831X_IRQ_UV_DC1] = {
+		.primary = WM831X_UV_INT,
+		.reg = 4,
+		.mask = WM831X_UV_DC1_EINT,
+	},
+	[WM831X_IRQ_UV_DC2] = {
+		.primary = WM831X_UV_INT,
+		.reg = 4,
+		.mask = WM831X_UV_DC2_EINT,
+	},
+	[WM831X_IRQ_UV_DC3] = {
+		.primary = WM831X_UV_INT,
+		.reg = 4,
+		.mask = WM831X_UV_DC3_EINT,
+	},
+	[WM831X_IRQ_UV_DC4] = {
+		.primary = WM831X_UV_INT,
+		.reg = 4,
+		.mask = WM831X_UV_DC4_EINT,
+	},
+};
+
+static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data)
+{
+	return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg;
+}
+
+static inline int irq_data_to_mask_reg(struct wm831x_irq_data *irq_data)
+{
+	return WM831X_INTERRUPT_STATUS_1_MASK - 1 + irq_data->reg;
+}
+
+static void __wm831x_enable_irq(struct wm831x *wm831x, int irq)
+{
+	struct wm831x_irq_data *irq_data = &wm831x_irqs[irq];
+
+	wm831x->irq_masks[irq_data->reg - 1] &= ~irq_data->mask;
+	wm831x_reg_write(wm831x, irq_data_to_mask_reg(irq_data),
+			 wm831x->irq_masks[irq_data->reg - 1]);
+}
+
+void wm831x_enable_irq(struct wm831x *wm831x, int irq)
+{
+	mutex_lock(&wm831x->irq_lock);
+	__wm831x_enable_irq(wm831x, irq);
+	mutex_unlock(&wm831x->irq_lock);
+}
+EXPORT_SYMBOL_GPL(wm831x_enable_irq);
+
+static void __wm831x_disable_irq(struct wm831x *wm831x, int irq)
+{
+	struct wm831x_irq_data *irq_data = &wm831x_irqs[irq];
+
+	wm831x->irq_masks[irq_data->reg - 1] |= irq_data->mask;
+	wm831x_reg_write(wm831x, irq_data_to_mask_reg(irq_data),
+			 wm831x->irq_masks[irq_data->reg - 1]);
+}
+
+void wm831x_disable_irq(struct wm831x *wm831x, int irq)
+{
+	mutex_lock(&wm831x->irq_lock);
+	__wm831x_disable_irq(wm831x, irq);
+	mutex_unlock(&wm831x->irq_lock);
+}
+EXPORT_SYMBOL_GPL(wm831x_disable_irq);
+
+int wm831x_request_irq(struct wm831x *wm831x,
+		       unsigned int irq, irq_handler_t handler,
+		       unsigned long flags, const char *name,
+		       void *dev)
+{
+	int ret = 0;
+
+	if (irq < 0 || irq >= WM831X_NUM_IRQS)
+		return -EINVAL;
+
+	mutex_lock(&wm831x->irq_lock);
+
+	if (wm831x_irqs[irq].handler) {
+		dev_err(wm831x->dev, "Already have handler for IRQ %d\n", irq);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	wm831x_irqs[irq].handler = handler;
+	wm831x_irqs[irq].handler_data = dev;
+
+	__wm831x_enable_irq(wm831x, irq);
+
+out:
+	mutex_unlock(&wm831x->irq_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wm831x_request_irq);
+
+void wm831x_free_irq(struct wm831x *wm831x, unsigned int irq, void *data)
+{
+	if (irq < 0 || irq >= WM831X_NUM_IRQS)
+		return;
+
+	mutex_lock(&wm831x->irq_lock);
+
+	wm831x_irqs[irq].handler = NULL;
+	wm831x_irqs[irq].handler_data = NULL;
+
+	__wm831x_disable_irq(wm831x, irq);
+
+	mutex_unlock(&wm831x->irq_lock);
+}
+EXPORT_SYMBOL_GPL(wm831x_free_irq);
+
+
+static void wm831x_handle_irq(struct wm831x *wm831x, int irq, int status)
+{
+	struct wm831x_irq_data *irq_data = &wm831x_irqs[irq];
+
+	if (irq_data->handler) {
+		irq_data->handler(irq, irq_data->handler_data);
+		wm831x_reg_write(wm831x, irq_data_to_status_reg(irq_data),
+				 irq_data->mask);
+	} else {
+		dev_err(wm831x->dev, "Unhandled IRQ %d, masking\n", irq);
+		__wm831x_disable_irq(wm831x, irq);
+	}
+}
+
+/* Main interrupt handling occurs in a workqueue since we need
+ * interrupts enabled to interact with the chip. */
+static void wm831x_irq_worker(struct work_struct *work)
+{
+	struct wm831x *wm831x = container_of(work, struct wm831x, irq_work);
+	unsigned int i;
+	int primary;
+	int status_regs[5];
+	int read[5] = { 0 };
+	int *status;
+
+	primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS);
+	if (primary < 0) {
+		dev_err(wm831x->dev, "Failed to read system interrupt: %d\n",
+			primary);
+		goto out;
+	}
+
+	mutex_lock(&wm831x->irq_lock);
+
+	for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
+		int offset = wm831x_irqs[i].reg - 1;
+
+		if (!(primary & wm831x_irqs[i].primary))
+			continue;
+
+		status = &status_regs[offset];
+
+		/* Hopefully there should only be one register to read
+		 * each time otherwise we ought to do a block read. */
+		if (!read[offset]) {
+			*status = wm831x_reg_read(wm831x,
+				     irq_data_to_status_reg(&wm831x_irqs[i]));
+			if (*status < 0) {
+				dev_err(wm831x->dev,
+					"Failed to read IRQ status: %d\n",
+					*status);
+				goto out_lock;
+			}
+
+			/* Mask out the disabled IRQs */
+			*status &= ~wm831x->irq_masks[offset];
+			read[offset] = 1;
+		}
+
+		if (*status & wm831x_irqs[i].mask)
+			wm831x_handle_irq(wm831x, i, *status);
+	}
+
+out_lock:
+	mutex_unlock(&wm831x->irq_lock);
+out:
+	enable_irq(wm831x->irq);
+}
+
+
+static irqreturn_t wm831x_cpu_irq(int irq, void *data)
+{
+	struct wm831x *wm831x = data;
+
+	/* Shut the interrupt to the CPU up and schedule the actual
+	 * handler; we can't check that the IRQ is asserted. */
+	disable_irq_nosync(irq);
+
+	queue_work(wm831x->irq_wq, &wm831x->irq_work);
+
+	return IRQ_HANDLED;
+}
+
+int wm831x_irq_init(struct wm831x *wm831x, int irq)
+{
+	int i, ret;
+
+	if (!irq) {
+		dev_warn(wm831x->dev,
+			 "No interrupt specified - functionality limited\n");
+		return 0;
+	}
+
+
+	wm831x->irq_wq = create_singlethread_workqueue("wm831x-irq");
+	if (!wm831x->irq_wq) {
+		dev_err(wm831x->dev, "Failed to allocate IRQ worker\n");
+		return -ESRCH;
+	}
+
+	wm831x->irq = irq;
+	mutex_init(&wm831x->irq_lock);
+	INIT_WORK(&wm831x->irq_work, wm831x_irq_worker);
+
+	/* Mask the individual interrupt sources */
+	for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks); i++) {
+		wm831x->irq_masks[i] = 0xffff;
+		wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i,
+				 0xffff);
+	}
+
+	/* Enable top level interrupts, we mask at secondary level */
+	wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
+
+	/* We're good to go.  We set IRQF_SHARED since there's a
+	 * chance the driver will interoperate with another driver but
+	 * the need to disable the IRQ while handing via I2C/SPI means
+	 * that this may break and performance will be impacted.  If
+	 * this does happen it's a hardware design issue and the only
+	 * other alternative would be polling.
+	 */
+	ret = request_irq(irq, wm831x_cpu_irq, IRQF_TRIGGER_LOW | IRQF_SHARED,
+			  "wm831x", wm831x);
+	if (ret != 0) {
+		dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
+			irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void wm831x_irq_exit(struct wm831x *wm831x)
+{
+	if (wm831x->irq)
+		free_irq(wm831x->irq, wm831x);
+}
diff --git a/drivers/mfd/wm831x-otp.c b/drivers/mfd/wm831x-otp.c
new file mode 100644
index 0000000..f742745
--- /dev/null
+++ b/drivers/mfd/wm831x-otp.c
@@ -0,0 +1,83 @@
+/*
+ * wm831x-otp.c  --  OTP for Wolfson WM831x PMICs
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/i2c.h>
+#include <linux/bcd.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/otp.h>
+
+/* In bytes */
+#define WM831X_UNIQUE_ID_LEN 16
+
+/* Read the unique ID from the chip into id */
+static int wm831x_unique_id_read(struct wm831x *wm831x, char *id)
+{
+	int i, val;
+
+	for (i = 0; i < WM831X_UNIQUE_ID_LEN / 2; i++) {
+		val = wm831x_reg_read(wm831x, WM831X_UNIQUE_ID_1 + i);
+		if (val < 0)
+			return val;
+
+		id[i * 2]       = (val >> 8) & 0xff;
+		id[(i * 2) + 1] = val & 0xff;
+	}
+
+	return 0;
+}
+
+static ssize_t wm831x_unique_id_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct wm831x *wm831x = dev_get_drvdata(dev);
+	int i, rval;
+	char id[WM831X_UNIQUE_ID_LEN];
+	ssize_t ret = 0;
+
+	rval = wm831x_unique_id_read(wm831x, id);
+	if (rval < 0)
+		return 0;
+
+	for (i = 0; i < WM831X_UNIQUE_ID_LEN; i++)
+		ret += sprintf(&buf[ret], "%02x", buf[i]);
+
+	ret += sprintf(&buf[ret], "\n");
+
+	return ret;
+}
+
+static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL);
+
+int wm831x_otp_init(struct wm831x *wm831x)
+{
+	int ret;
+
+	ret = device_create_file(wm831x->dev, &dev_attr_unique_id);
+	if (ret != 0)
+		dev_err(wm831x->dev, "Unique ID attribute not created: %d\n",
+			ret);
+
+	return ret;
+}
+
+void wm831x_otp_exit(struct wm831x *wm831x)
+{
+	device_remove_file(wm831x->dev, &dev_attr_unique_id);
+}
+
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index fe24079..ba27c9d 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -353,15 +353,15 @@ static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
 }
 
 /*
- * wm8350_irq_worker actually handles the interrupts.  Since all
+ * This is a threaded IRQ handler so can access I2C/SPI.  Since all
  * interrupts are clear on read the IRQ line will be reasserted and
  * the physical IRQ will be handled again if another interrupt is
  * asserted while we run - in the normal course of events this is a
  * rare occurrence so we save I2C/SPI reads.
  */
-static void wm8350_irq_worker(struct work_struct *work)
+static irqreturn_t wm8350_irq(int irq, void *data)
 {
-	struct wm8350 *wm8350 = container_of(work, struct wm8350, irq_work);
+	struct wm8350 *wm8350 = data;
 	u16 level_one, status1, status2, comp;
 
 	/* TODO: Use block reads to improve performance? */
@@ -552,16 +552,6 @@ static void wm8350_irq_worker(struct work_struct *work)
 		}
 	}
 
-	enable_irq(wm8350->chip_irq);
-}
-
-static irqreturn_t wm8350_irq(int irq, void *data)
-{
-	struct wm8350 *wm8350 = data;
-
-	disable_irq_nosync(irq);
-	schedule_work(&wm8350->irq_work);
-
 	return IRQ_HANDLED;
 }
 
@@ -1428,9 +1418,8 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
 
 	mutex_init(&wm8350->auxadc_mutex);
 	mutex_init(&wm8350->irq_mutex);
-	INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
 	if (irq) {
-		int flags = 0;
+		int flags = IRQF_ONESHOT;
 
 		if (pdata && pdata->irq_high) {
 			flags |= IRQF_TRIGGER_HIGH;
@@ -1444,8 +1433,8 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
 					  WM8350_IRQ_POL);
 		}
 
-		ret = request_irq(irq, wm8350_irq, flags,
-				  "wm8350", wm8350);
+		ret = request_threaded_irq(irq, NULL, wm8350_irq, flags,
+					   "wm8350", wm8350);
 		if (ret != 0) {
 			dev_err(wm8350->dev, "Failed to request IRQ: %d\n",
 				ret);
@@ -1472,6 +1461,8 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
 				   &(wm8350->codec.pdev));
 	wm8350_client_dev_register(wm8350, "wm8350-gpio",
 				   &(wm8350->gpio.pdev));
+	wm8350_client_dev_register(wm8350, "wm8350-hwmon",
+				   &(wm8350->hwmon.pdev));
 	wm8350_client_dev_register(wm8350, "wm8350-power",
 				   &(wm8350->power.pdev));
 	wm8350_client_dev_register(wm8350, "wm8350-rtc", &(wm8350->rtc.pdev));
@@ -1498,11 +1489,11 @@ void wm8350_device_exit(struct wm8350 *wm8350)
 	platform_device_unregister(wm8350->wdt.pdev);
 	platform_device_unregister(wm8350->rtc.pdev);
 	platform_device_unregister(wm8350->power.pdev);
+	platform_device_unregister(wm8350->hwmon.pdev);
 	platform_device_unregister(wm8350->gpio.pdev);
 	platform_device_unregister(wm8350->codec.pdev);
 
 	free_irq(wm8350->chip_irq, wm8350);
-	flush_work(&wm8350->irq_work);
 	kfree(wm8350->reg_cache);
 }
 EXPORT_SYMBOL_GPL(wm8350_device_exit);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 68ab39d..df1f86b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -233,6 +233,19 @@ config ISL29003
 	  This driver can also be built as a module.  If so, the module
 	  will be called isl29003.
 
+config EP93XX_PWM
+	tristate "EP93xx PWM support"
+	depends on ARCH_EP93XX
+	help
+	  This option enables device driver support for the PWM channels
+	  on the Cirrus EP93xx processors.  The EP9307 chip only has one
+	  PWM channel all the others have two, the second channel is an
+	  alternate function of the EGPIO14 pin.  A sysfs interface is
+	  provided to control the PWM channels.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called ep93xx_pwm.
+
 source "drivers/misc/c2port/Kconfig"
 source "drivers/misc/eeprom/Kconfig"
 source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 36f733c..f982d2e 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SGI_XP)		+= sgi-xp/
 obj-$(CONFIG_SGI_GRU)		+= sgi-gru/
 obj-$(CONFIG_HP_ILO)		+= hpilo.o
 obj-$(CONFIG_ISL29003)		+= isl29003.o
+obj-$(CONFIG_EP93XX_PWM)	+= ep93xx_pwm.o
 obj-$(CONFIG_C2PORT)		+= c2port/
 obj-y				+= eeprom/
 obj-y				+= cb710/
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 348443b..e9eae4a 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -33,24 +33,44 @@ static DEFINE_MUTEX(container_list_lock);
 static struct class enclosure_class;
 
 /**
- * enclosure_find - find an enclosure given a device
- * @dev:	the device to find for
+ * enclosure_find - find an enclosure given a parent device
+ * @dev:	the parent to match against
+ * @start:	Optional enclosure device to start from (NULL if none)
  *
- * Looks through the list of registered enclosures to see
- * if it can find a match for a device.  Returns NULL if no
- * enclosure is found. Obtains a reference to the enclosure class
- * device which must be released with device_put().
+ * Looks through the list of registered enclosures to find all those
+ * with @dev as a parent.  Returns NULL if no enclosure is
+ * found. @start can be used as a starting point to obtain multiple
+ * enclosures per parent (should begin with NULL and then be set to
+ * each returned enclosure device). Obtains a reference to the
+ * enclosure class device which must be released with device_put().
+ * If @start is not NULL, a reference must be taken on it which is
+ * released before returning (this allows a loop through all
+ * enclosures to exit with only the reference on the enclosure of
+ * interest held).  Note that the @dev may correspond to the actual
+ * device housing the enclosure, in which case no iteration via @start
+ * is required.
  */
-struct enclosure_device *enclosure_find(struct device *dev)
+struct enclosure_device *enclosure_find(struct device *dev,
+					struct enclosure_device *start)
 {
 	struct enclosure_device *edev;
 
 	mutex_lock(&container_list_lock);
-	list_for_each_entry(edev, &container_list, node) {
-		if (edev->edev.parent == dev) {
-			get_device(&edev->edev);
-			mutex_unlock(&container_list_lock);
-			return edev;
+	edev = list_prepare_entry(start, &container_list, node);
+	if (start)
+		put_device(&start->edev);
+
+	list_for_each_entry_continue(edev, &container_list, node) {
+		struct device *parent = edev->edev.parent;
+		/* parent might not be immediate, so iterate up to
+		 * the root of the tree if necessary */
+		while (parent) {
+			if (parent == dev) {
+				get_device(&edev->edev);
+				mutex_unlock(&container_list_lock);
+				return edev;
+			}
+			parent = parent->parent;
 		}
 	}
 	mutex_unlock(&container_list_lock);
@@ -218,7 +238,7 @@ static void enclosure_component_release(struct device *dev)
 	put_device(dev->parent);
 }
 
-static struct attribute_group *enclosure_groups[];
+static const struct attribute_group *enclosure_groups[];
 
 /**
  * enclosure_component_register - add a particular component to an enclosure
@@ -295,6 +315,9 @@ int enclosure_add_device(struct enclosure_device *edev, int component,
 
 	cdev = &edev->component[component];
 
+	if (cdev->dev == dev)
+		return -EEXIST;
+
 	if (cdev->dev)
 		enclosure_remove_links(cdev);
 
@@ -312,19 +335,25 @@ EXPORT_SYMBOL_GPL(enclosure_add_device);
  * Returns zero on success or an error.
  *
  */
-int enclosure_remove_device(struct enclosure_device *edev, int component)
+int enclosure_remove_device(struct enclosure_device *edev, struct device *dev)
 {
 	struct enclosure_component *cdev;
+	int i;
 
-	if (!edev || component >= edev->components)
+	if (!edev || !dev)
 		return -EINVAL;
 
-	cdev = &edev->component[component];
-
-	device_del(&cdev->cdev);
-	put_device(cdev->dev);
-	cdev->dev = NULL;
-	return device_add(&cdev->cdev);
+	for (i = 0; i < edev->components; i++) {
+		cdev = &edev->component[i];
+		if (cdev->dev == dev) {
+			enclosure_remove_links(cdev);
+			device_del(&cdev->cdev);
+			put_device(dev);
+			cdev->dev = NULL;
+			return device_add(&cdev->cdev);
+		}
+	}
+	return -ENODEV;
 }
 EXPORT_SYMBOL_GPL(enclosure_remove_device);
 
@@ -507,7 +536,7 @@ static struct attribute_group enclosure_group = {
 	.attrs = enclosure_component_attrs,
 };
 
-static struct attribute_group *enclosure_groups[] = {
+static const struct attribute_group *enclosure_groups[] = {
 	&enclosure_group,
 	NULL
 };
diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c
new file mode 100644
index 0000000..ba46941
--- /dev/null
+++ b/drivers/misc/ep93xx_pwm.c
@@ -0,0 +1,384 @@
+/*
+ *  Simple PWM driver for EP93XX
+ *
+ *	(c) Copyright 2009  Matthieu Crapet <mcrapet@gmail.com>
+ *	(c) Copyright 2009  H Hartley Sweeten <hsweeten@visionengravers.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.
+ *
+ *  EP9307 has only one channel:
+ *    - PWMOUT
+ *
+ *  EP9301/02/12/15 have two channels:
+ *    - PWMOUT
+ *    - PWMOUT1 (alternate function for EGPIO14)
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/platform.h>
+
+#define EP93XX_PWMx_TERM_COUNT	0x00
+#define EP93XX_PWMx_DUTY_CYCLE	0x04
+#define EP93XX_PWMx_ENABLE	0x08
+#define EP93XX_PWMx_INVERT	0x0C
+
+#define EP93XX_PWM_MAX_COUNT	0xFFFF
+
+struct ep93xx_pwm {
+	void __iomem	*mmio_base;
+	struct clk	*clk;
+	u32		duty_percent;
+};
+
+static inline void ep93xx_pwm_writel(struct ep93xx_pwm *pwm,
+		unsigned int val, unsigned int off)
+{
+	__raw_writel(val, pwm->mmio_base + off);
+}
+
+static inline unsigned int ep93xx_pwm_readl(struct ep93xx_pwm *pwm,
+		unsigned int off)
+{
+	return __raw_readl(pwm->mmio_base + off);
+}
+
+static inline void ep93xx_pwm_write_tc(struct ep93xx_pwm *pwm, u16 value)
+{
+	ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_TERM_COUNT);
+}
+
+static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm)
+{
+	return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT);
+}
+
+static inline void ep93xx_pwm_write_dc(struct ep93xx_pwm *pwm, u16 value)
+{
+	ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_DUTY_CYCLE);
+}
+
+static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm)
+{
+	ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE);
+}
+
+static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm)
+{
+	ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE);
+}
+
+static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm)
+{
+	return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1;
+}
+
+static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm)
+{
+	ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT);
+}
+
+static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm)
+{
+	ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT);
+}
+
+static inline int ep93xx_pwm_is_inverted(struct ep93xx_pwm *pwm)
+{
+	return ep93xx_pwm_readl(pwm, EP93XX_PWMx_INVERT) & 0x1;
+}
+
+/*
+ * /sys/devices/platform/ep93xx-pwm.N
+ *   /min_freq      read-only   minimum pwm output frequency
+ *   /max_req       read-only   maximum pwm output frequency
+ *   /freq          read-write  pwm output frequency (0 = disable output)
+ *   /duty_percent  read-write  pwm duty cycle percent (1..99)
+ *   /invert        read-write  invert pwm output
+ */
+
+static ssize_t ep93xx_pwm_get_min_freq(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+	unsigned long rate = clk_get_rate(pwm->clk);
+
+	return sprintf(buf, "%ld\n", rate / (EP93XX_PWM_MAX_COUNT + 1));
+}
+
+static ssize_t ep93xx_pwm_get_max_freq(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+	unsigned long rate = clk_get_rate(pwm->clk);
+
+	return sprintf(buf, "%ld\n", rate / 2);
+}
+
+static ssize_t ep93xx_pwm_get_freq(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+
+	if (ep93xx_pwm_is_enabled(pwm)) {
+		unsigned long rate = clk_get_rate(pwm->clk);
+		u16 term = ep93xx_pwm_read_tc(pwm);
+
+		return sprintf(buf, "%ld\n", rate / (term + 1));
+	} else {
+		return sprintf(buf, "disabled\n");
+	}
+}
+
+static ssize_t ep93xx_pwm_set_freq(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+	long val;
+	int err;
+
+	err = strict_strtol(buf, 10, &val);
+	if (err)
+		return -EINVAL;
+
+	if (val == 0) {
+		ep93xx_pwm_disable(pwm);
+	} else if (val <= (clk_get_rate(pwm->clk) / 2)) {
+		u32 term, duty;
+
+		val = (clk_get_rate(pwm->clk) / val) - 1;
+		if (val > EP93XX_PWM_MAX_COUNT)
+			val = EP93XX_PWM_MAX_COUNT;
+		if (val < 1)
+			val = 1;
+
+		term = ep93xx_pwm_read_tc(pwm);
+		duty = ((val + 1) * pwm->duty_percent / 100) - 1;
+
+		/* If pwm is running, order is important */
+		if (val > term) {
+			ep93xx_pwm_write_tc(pwm, val);
+			ep93xx_pwm_write_dc(pwm, duty);
+		} else {
+			ep93xx_pwm_write_dc(pwm, duty);
+			ep93xx_pwm_write_tc(pwm, val);
+		}
+
+		if (!ep93xx_pwm_is_enabled(pwm))
+			ep93xx_pwm_enable(pwm);
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static ssize_t ep93xx_pwm_get_duty_percent(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+
+	return sprintf(buf, "%d\n", pwm->duty_percent);
+}
+
+static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+	long val;
+	int err;
+
+	err = strict_strtol(buf, 10, &val);
+	if (err)
+		return -EINVAL;
+
+	if (val > 0 && val < 100) {
+		u32 term = ep93xx_pwm_read_tc(pwm);
+		ep93xx_pwm_write_dc(pwm, ((term + 1) * val / 100) - 1);
+		pwm->duty_percent = val;
+		return count;
+	}
+
+	return -EINVAL;
+}
+
+static ssize_t ep93xx_pwm_get_invert(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+
+	return sprintf(buf, "%d\n", ep93xx_pwm_is_inverted(pwm));
+}
+
+static ssize_t ep93xx_pwm_set_invert(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+	long val;
+	int err;
+
+	err = strict_strtol(buf, 10, &val);
+	if (err)
+		return -EINVAL;
+
+	if (val == 0)
+		ep93xx_pwm_normal(pwm);
+	else if (val == 1)
+		ep93xx_pwm_invert(pwm);
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL);
+static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL);
+static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO,
+		   ep93xx_pwm_get_freq, ep93xx_pwm_set_freq);
+static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO,
+		   ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent);
+static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO,
+		   ep93xx_pwm_get_invert, ep93xx_pwm_set_invert);
+
+static struct attribute *ep93xx_pwm_attrs[] = {
+	&dev_attr_min_freq.attr,
+	&dev_attr_max_freq.attr,
+	&dev_attr_freq.attr,
+	&dev_attr_duty_percent.attr,
+	&dev_attr_invert.attr,
+	NULL
+};
+
+static const struct attribute_group ep93xx_pwm_sysfs_files = {
+	.attrs	= ep93xx_pwm_attrs,
+};
+
+static int __init ep93xx_pwm_probe(struct platform_device *pdev)
+{
+	struct ep93xx_pwm *pwm;
+	struct resource *res;
+	int err;
+
+	err = ep93xx_pwm_acquire_gpio(pdev);
+	if (err)
+		return err;
+
+	pwm = kzalloc(sizeof(struct ep93xx_pwm), GFP_KERNEL);
+	if (!pwm) {
+		err = -ENOMEM;
+		goto fail_no_mem;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		err = -ENXIO;
+		goto fail_no_mem_resource;
+	}
+
+	res = request_mem_region(res->start, resource_size(res), pdev->name);
+	if (res == NULL) {
+		err = -EBUSY;
+		goto fail_no_mem_resource;
+	}
+
+	pwm->mmio_base = ioremap(res->start, resource_size(res));
+	if (pwm->mmio_base == NULL) {
+		err = -ENXIO;
+		goto fail_no_ioremap;
+	}
+
+	err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
+	if (err)
+		goto fail_no_sysfs;
+
+	pwm->clk = clk_get(&pdev->dev, "pwm_clk");
+	if (IS_ERR(pwm->clk)) {
+		err = PTR_ERR(pwm->clk);
+		goto fail_no_clk;
+	}
+
+	pwm->duty_percent = 50;
+
+	platform_set_drvdata(pdev, pwm);
+
+	/* disable pwm at startup. Avoids zero value. */
+	ep93xx_pwm_disable(pwm);
+	ep93xx_pwm_write_tc(pwm, EP93XX_PWM_MAX_COUNT);
+	ep93xx_pwm_write_dc(pwm, EP93XX_PWM_MAX_COUNT / 2);
+
+	clk_enable(pwm->clk);
+
+	return 0;
+
+fail_no_clk:
+	sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
+fail_no_sysfs:
+	iounmap(pwm->mmio_base);
+fail_no_ioremap:
+	release_mem_region(res->start, resource_size(res));
+fail_no_mem_resource:
+	kfree(pwm);
+fail_no_mem:
+	ep93xx_pwm_release_gpio(pdev);
+	return err;
+}
+
+static int __exit ep93xx_pwm_remove(struct platform_device *pdev)
+{
+	struct ep93xx_pwm *pwm = platform_get_drvdata(pdev);
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	ep93xx_pwm_disable(pwm);
+	clk_disable(pwm->clk);
+	clk_put(pwm->clk);
+	platform_set_drvdata(pdev, NULL);
+	sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
+	iounmap(pwm->mmio_base);
+	release_mem_region(res->start, resource_size(res));
+	kfree(pwm);
+	ep93xx_pwm_release_gpio(pdev);
+
+	return 0;
+}
+
+static struct platform_driver ep93xx_pwm_driver = {
+	.driver		= {
+		.name	= "ep93xx-pwm",
+		.owner	= THIS_MODULE,
+	},
+	.remove		= __exit_p(ep93xx_pwm_remove),
+};
+
+static int __init ep93xx_pwm_init(void)
+{
+	return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe);
+}
+
+static void __exit ep93xx_pwm_exit(void)
+{
+	platform_driver_unregister(&ep93xx_pwm_driver);
+}
+
+module_init(ep93xx_pwm_init);
+module_exit(ep93xx_pwm_exit);
+
+MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, "
+	      "H Hartley Sweeten <hsweeten@visionengravers.com>");
+MODULE_DESCRIPTION("EP93xx PWM driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ep93xx-pwm");
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 880ccf3..1ad27c6 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/file.h>
@@ -21,6 +22,8 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
 #include "hpilo.h"
 
 static struct class *ilo_class;
@@ -61,9 +64,10 @@ static inline int desc_mem_sz(int nr_entry)
 static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry)
 {
 	struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
+	unsigned long flags;
 	int ret = 0;
 
-	spin_lock(&hw->fifo_lock);
+	spin_lock_irqsave(&hw->fifo_lock, flags);
 	if (!(fifo_q->fifobar[(fifo_q->tail + 1) & fifo_q->imask]
 	      & ENTRY_MASK_O)) {
 		fifo_q->fifobar[fifo_q->tail & fifo_q->imask] |=
@@ -71,7 +75,7 @@ static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry)
 		fifo_q->tail += 1;
 		ret = 1;
 	}
-	spin_unlock(&hw->fifo_lock);
+	spin_unlock_irqrestore(&hw->fifo_lock, flags);
 
 	return ret;
 }
@@ -79,10 +83,11 @@ static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry)
 static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry)
 {
 	struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
+	unsigned long flags;
 	int ret = 0;
 	u64 c;
 
-	spin_lock(&hw->fifo_lock);
+	spin_lock_irqsave(&hw->fifo_lock, flags);
 	c = fifo_q->fifobar[fifo_q->head & fifo_q->imask];
 	if (c & ENTRY_MASK_C) {
 		if (entry)
@@ -93,7 +98,23 @@ static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry)
 		fifo_q->head += 1;
 		ret = 1;
 	}
-	spin_unlock(&hw->fifo_lock);
+	spin_unlock_irqrestore(&hw->fifo_lock, flags);
+
+	return ret;
+}
+
+static int fifo_check_recv(struct ilo_hwinfo *hw, char *fifobar)
+{
+	struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
+	unsigned long flags;
+	int ret = 0;
+	u64 c;
+
+	spin_lock_irqsave(&hw->fifo_lock, flags);
+	c = fifo_q->fifobar[fifo_q->head & fifo_q->imask];
+	if (c & ENTRY_MASK_C)
+		ret = 1;
+	spin_unlock_irqrestore(&hw->fifo_lock, flags);
 
 	return ret;
 }
@@ -142,6 +163,13 @@ static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb,
 	return ret;
 }
 
+static int ilo_pkt_recv(struct ilo_hwinfo *hw, struct ccb *ccb)
+{
+	char *fifobar = ccb->ccb_u3.recv_fifobar;
+
+	return fifo_check_recv(hw, fifobar);
+}
+
 static inline void doorbell_set(struct ccb *ccb)
 {
 	iowrite8(1, ccb->ccb_u5.db_base);
@@ -151,6 +179,7 @@ static inline void doorbell_clr(struct ccb *ccb)
 {
 	iowrite8(2, ccb->ccb_u5.db_base);
 }
+
 static inline int ctrl_set(int l2sz, int idxmask, int desclim)
 {
 	int active = 0, go = 1;
@@ -160,6 +189,7 @@ static inline int ctrl_set(int l2sz, int idxmask, int desclim)
 	       active << CTRL_BITPOS_A |
 	       go << CTRL_BITPOS_G;
 }
+
 static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz)
 {
 	/* for simplicity, use the same parameters for send and recv ctrls */
@@ -192,13 +222,10 @@ static void fifo_setup(void *base_addr, int nr_entry)
 
 static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
 {
-	struct ccb *driver_ccb;
-	struct ccb __iomem *device_ccb;
+	struct ccb *driver_ccb = &data->driver_ccb;
+	struct ccb __iomem *device_ccb = data->mapped_ccb;
 	int retries;
 
-	driver_ccb = &data->driver_ccb;
-	device_ccb = data->mapped_ccb;
-
 	/* complicated dance to tell the hw we are stopping */
 	doorbell_clr(driver_ccb);
 	iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G),
@@ -225,26 +252,22 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
 	pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
 }
 
-static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
+static int ilo_ccb_setup(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
 {
 	char *dma_va, *dma_pa;
-	int pkt_id, pkt_sz, i, error;
 	struct ccb *driver_ccb, *ilo_ccb;
-	struct pci_dev *pdev;
 
 	driver_ccb = &data->driver_ccb;
 	ilo_ccb = &data->ilo_ccb;
-	pdev = hw->ilo_dev;
 
 	data->dma_size = 2 * fifo_sz(NR_QENTRY) +
 			 2 * desc_mem_sz(NR_QENTRY) +
 			 ILO_START_ALIGN + ILO_CACHE_SZ;
 
-	error = -ENOMEM;
-	data->dma_va = pci_alloc_consistent(pdev, data->dma_size,
+	data->dma_va = pci_alloc_consistent(hw->ilo_dev, data->dma_size,
 					    &data->dma_pa);
 	if (!data->dma_va)
-		goto out;
+		return -ENOMEM;
 
 	dma_va = (char *)data->dma_va;
 	dma_pa = (char *)data->dma_pa;
@@ -290,10 +313,18 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
 	driver_ccb->ccb_u5.db_base = hw->db_vaddr + (slot << L2_DB_SIZE);
 	ilo_ccb->ccb_u5.db_base = NULL; /* hw ccb's doorbell is not used */
 
+	return 0;
+}
+
+static void ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
+{
+	int pkt_id, pkt_sz;
+	struct ccb *driver_ccb = &data->driver_ccb;
+
 	/* copy the ccb with physical addrs to device memory */
 	data->mapped_ccb = (struct ccb __iomem *)
 				(hw->ram_vaddr + (slot * ILOHW_CCB_SZ));
-	memcpy_toio(data->mapped_ccb, ilo_ccb, sizeof(struct ccb));
+	memcpy_toio(data->mapped_ccb, &data->ilo_ccb, sizeof(struct ccb));
 
 	/* put packets on the send and receive queues */
 	pkt_sz = 0;
@@ -306,7 +337,14 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
 	for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++)
 		ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz);
 
+	/* the ccb is ready to use */
 	doorbell_clr(driver_ccb);
+}
+
+static int ilo_ccb_verify(struct ilo_hwinfo *hw, struct ccb_data *data)
+{
+	int pkt_id, i;
+	struct ccb *driver_ccb = &data->driver_ccb;
 
 	/* make sure iLO is really handling requests */
 	for (i = MAX_WAIT; i > 0; i--) {
@@ -315,20 +353,14 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
 		udelay(WAIT_TIME);
 	}
 
-	if (i) {
-		ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0);
-		doorbell_set(driver_ccb);
-	} else {
-		dev_err(&pdev->dev, "Open could not dequeue a packet\n");
-		error = -EBUSY;
-		goto free;
+	if (i == 0) {
+		dev_err(&hw->ilo_dev->dev, "Open could not dequeue a packet\n");
+		return -EBUSY;
 	}
 
+	ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0);
+	doorbell_set(driver_ccb);
 	return 0;
-free:
-	ilo_ccb_close(pdev, data);
-out:
-	return error;
 }
 
 static inline int is_channel_reset(struct ccb *ccb)
@@ -343,19 +375,45 @@ static inline void set_channel_reset(struct ccb *ccb)
 	FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1;
 }
 
+static inline int get_device_outbound(struct ilo_hwinfo *hw)
+{
+	return ioread32(&hw->mmio_vaddr[DB_OUT]);
+}
+
+static inline int is_db_reset(int db_out)
+{
+	return db_out & (1 << DB_RESET);
+}
+
 static inline int is_device_reset(struct ilo_hwinfo *hw)
 {
 	/* check for global reset condition */
-	return ioread32(&hw->mmio_vaddr[DB_OUT]) & (1 << DB_RESET);
+	return is_db_reset(get_device_outbound(hw));
+}
+
+static inline void clear_pending_db(struct ilo_hwinfo *hw, int clr)
+{
+	iowrite32(clr, &hw->mmio_vaddr[DB_OUT]);
 }
 
 static inline void clear_device(struct ilo_hwinfo *hw)
 {
 	/* clear the device (reset bits, pending channel entries) */
-	iowrite32(-1, &hw->mmio_vaddr[DB_OUT]);
+	clear_pending_db(hw, -1);
+}
+
+static inline void ilo_enable_interrupts(struct ilo_hwinfo *hw)
+{
+	iowrite8(ioread8(&hw->mmio_vaddr[DB_IRQ]) | 1, &hw->mmio_vaddr[DB_IRQ]);
 }
 
-static void ilo_locked_reset(struct ilo_hwinfo *hw)
+static inline void ilo_disable_interrupts(struct ilo_hwinfo *hw)
+{
+	iowrite8(ioread8(&hw->mmio_vaddr[DB_IRQ]) & ~1,
+		 &hw->mmio_vaddr[DB_IRQ]);
+}
+
+static void ilo_set_reset(struct ilo_hwinfo *hw)
 {
 	int slot;
 
@@ -368,40 +426,22 @@ static void ilo_locked_reset(struct ilo_hwinfo *hw)
 			continue;
 		set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb);
 	}
-
-	clear_device(hw);
-}
-
-static void ilo_reset(struct ilo_hwinfo *hw)
-{
-	spin_lock(&hw->alloc_lock);
-
-	/* reset might have been handled after lock was taken */
-	if (is_device_reset(hw))
-		ilo_locked_reset(hw);
-
-	spin_unlock(&hw->alloc_lock);
 }
 
 static ssize_t ilo_read(struct file *fp, char __user *buf,
 			size_t len, loff_t *off)
 {
 	int err, found, cnt, pkt_id, pkt_len;
-	struct ccb_data *data;
-	struct ccb *driver_ccb;
-	struct ilo_hwinfo *hw;
+	struct ccb_data *data = fp->private_data;
+	struct ccb *driver_ccb = &data->driver_ccb;
+	struct ilo_hwinfo *hw = data->ilo_hw;
 	void *pkt;
 
-	data = fp->private_data;
-	driver_ccb = &data->driver_ccb;
-	hw = data->ilo_hw;
-
-	if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
+	if (is_channel_reset(driver_ccb)) {
 		/*
 		 * If the device has been reset, applications
 		 * need to close and reopen all ccbs.
 		 */
-		ilo_reset(hw);
 		return -ENODEV;
 	}
 
@@ -442,23 +482,13 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf,
 			 size_t len, loff_t *off)
 {
 	int err, pkt_id, pkt_len;
-	struct ccb_data *data;
-	struct ccb *driver_ccb;
-	struct ilo_hwinfo *hw;
+	struct ccb_data *data = fp->private_data;
+	struct ccb *driver_ccb = &data->driver_ccb;
+	struct ilo_hwinfo *hw = data->ilo_hw;
 	void *pkt;
 
-	data = fp->private_data;
-	driver_ccb = &data->driver_ccb;
-	hw = data->ilo_hw;
-
-	if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
-		/*
-		 * If the device has been reset, applications
-		 * need to close and reopen all ccbs.
-		 */
-		ilo_reset(hw);
+	if (is_channel_reset(driver_ccb))
 		return -ENODEV;
-	}
 
 	/* get a packet to send the user command */
 	if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt))
@@ -480,32 +510,48 @@ static ssize_t ilo_write(struct file *fp, const char __user *buf,
 	return err ? -EFAULT : len;
 }
 
+static unsigned int ilo_poll(struct file *fp, poll_table *wait)
+{
+	struct ccb_data *data = fp->private_data;
+	struct ccb *driver_ccb = &data->driver_ccb;
+
+	poll_wait(fp, &data->ccb_waitq, wait);
+
+	if (is_channel_reset(driver_ccb))
+		return POLLERR;
+	else if (ilo_pkt_recv(data->ilo_hw, driver_ccb))
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
 static int ilo_close(struct inode *ip, struct file *fp)
 {
 	int slot;
 	struct ccb_data *data;
 	struct ilo_hwinfo *hw;
+	unsigned long flags;
 
 	slot = iminor(ip) % MAX_CCB;
 	hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
 
-	spin_lock(&hw->alloc_lock);
-
-	if (is_device_reset(hw))
-		ilo_locked_reset(hw);
+	spin_lock(&hw->open_lock);
 
 	if (hw->ccb_alloc[slot]->ccb_cnt == 1) {
 
 		data = fp->private_data;
 
+		spin_lock_irqsave(&hw->alloc_lock, flags);
+		hw->ccb_alloc[slot] = NULL;
+		spin_unlock_irqrestore(&hw->alloc_lock, flags);
+
 		ilo_ccb_close(hw->ilo_dev, data);
 
 		kfree(data);
-		hw->ccb_alloc[slot] = NULL;
 	} else
 		hw->ccb_alloc[slot]->ccb_cnt--;
 
-	spin_unlock(&hw->alloc_lock);
+	spin_unlock(&hw->open_lock);
 
 	return 0;
 }
@@ -515,6 +561,7 @@ static int ilo_open(struct inode *ip, struct file *fp)
 	int slot, error;
 	struct ccb_data *data;
 	struct ilo_hwinfo *hw;
+	unsigned long flags;
 
 	slot = iminor(ip) % MAX_CCB;
 	hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
@@ -524,22 +571,42 @@ static int ilo_open(struct inode *ip, struct file *fp)
 	if (!data)
 		return -ENOMEM;
 
-	spin_lock(&hw->alloc_lock);
-
-	if (is_device_reset(hw))
-		ilo_locked_reset(hw);
+	spin_lock(&hw->open_lock);
 
 	/* each fd private_data holds sw/hw view of ccb */
 	if (hw->ccb_alloc[slot] == NULL) {
 		/* create a channel control block for this minor */
-		error = ilo_ccb_open(hw, data, slot);
-		if (!error) {
-			hw->ccb_alloc[slot] = data;
-			hw->ccb_alloc[slot]->ccb_cnt = 1;
-			hw->ccb_alloc[slot]->ccb_excl = fp->f_flags & O_EXCL;
-			hw->ccb_alloc[slot]->ilo_hw = hw;
-		} else
+		error = ilo_ccb_setup(hw, data, slot);
+		if (error) {
 			kfree(data);
+			goto out;
+		}
+
+		data->ccb_cnt = 1;
+		data->ccb_excl = fp->f_flags & O_EXCL;
+		data->ilo_hw = hw;
+		init_waitqueue_head(&data->ccb_waitq);
+
+		/* write the ccb to hw */
+		spin_lock_irqsave(&hw->alloc_lock, flags);
+		ilo_ccb_open(hw, data, slot);
+		hw->ccb_alloc[slot] = data;
+		spin_unlock_irqrestore(&hw->alloc_lock, flags);
+
+		/* make sure the channel is functional */
+		error = ilo_ccb_verify(hw, data);
+		if (error) {
+
+			spin_lock_irqsave(&hw->alloc_lock, flags);
+			hw->ccb_alloc[slot] = NULL;
+			spin_unlock_irqrestore(&hw->alloc_lock, flags);
+
+			ilo_ccb_close(hw->ilo_dev, data);
+
+			kfree(data);
+			goto out;
+		}
+
 	} else {
 		kfree(data);
 		if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) {
@@ -554,7 +621,8 @@ static int ilo_open(struct inode *ip, struct file *fp)
 			error = 0;
 		}
 	}
-	spin_unlock(&hw->alloc_lock);
+out:
+	spin_unlock(&hw->open_lock);
 
 	if (!error)
 		fp->private_data = hw->ccb_alloc[slot];
@@ -566,10 +634,46 @@ static const struct file_operations ilo_fops = {
 	.owner		= THIS_MODULE,
 	.read		= ilo_read,
 	.write		= ilo_write,
+	.poll		= ilo_poll,
 	.open 		= ilo_open,
 	.release 	= ilo_close,
 };
 
+static irqreturn_t ilo_isr(int irq, void *data)
+{
+	struct ilo_hwinfo *hw = data;
+	int pending, i;
+
+	spin_lock(&hw->alloc_lock);
+
+	/* check for ccbs which have data */
+	pending = get_device_outbound(hw);
+	if (!pending) {
+		spin_unlock(&hw->alloc_lock);
+		return IRQ_NONE;
+	}
+
+	if (is_db_reset(pending)) {
+		/* wake up all ccbs if the device was reset */
+		pending = -1;
+		ilo_set_reset(hw);
+	}
+
+	for (i = 0; i < MAX_CCB; i++) {
+		if (!hw->ccb_alloc[i])
+			continue;
+		if (pending & (1 << i))
+			wake_up_interruptible(&hw->ccb_alloc[i]->ccb_waitq);
+	}
+
+	/* clear the device of the channels that have been handled */
+	clear_pending_db(hw, pending);
+
+	spin_unlock(&hw->alloc_lock);
+
+	return IRQ_HANDLED;
+}
+
 static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
 {
 	pci_iounmap(pdev, hw->db_vaddr);
@@ -623,6 +727,8 @@ static void ilo_remove(struct pci_dev *pdev)
 		device_destroy(ilo_class, MKDEV(ilo_major, i));
 
 	cdev_del(&ilo_hw->cdev);
+	ilo_disable_interrupts(ilo_hw);
+	free_irq(pdev->irq, ilo_hw);
 	ilo_unmap_device(pdev, ilo_hw);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
@@ -658,6 +764,7 @@ static int __devinit ilo_probe(struct pci_dev *pdev,
 	ilo_hw->ilo_dev = pdev;
 	spin_lock_init(&ilo_hw->alloc_lock);
 	spin_lock_init(&ilo_hw->fifo_lock);
+	spin_lock_init(&ilo_hw->open_lock);
 
 	error = pci_enable_device(pdev);
 	if (error)
@@ -676,13 +783,19 @@ static int __devinit ilo_probe(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, ilo_hw);
 	clear_device(ilo_hw);
 
+	error = request_irq(pdev->irq, ilo_isr, IRQF_SHARED, "hpilo", ilo_hw);
+	if (error)
+		goto unmap;
+
+	ilo_enable_interrupts(ilo_hw);
+
 	cdev_init(&ilo_hw->cdev, &ilo_fops);
 	ilo_hw->cdev.owner = THIS_MODULE;
 	start = devnum * MAX_CCB;
 	error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB);
 	if (error) {
 		dev_err(&pdev->dev, "Could not add cdev\n");
-		goto unmap;
+		goto remove_isr;
 	}
 
 	for (minor = 0 ; minor < MAX_CCB; minor++) {
@@ -695,6 +808,9 @@ static int __devinit ilo_probe(struct pci_dev *pdev,
 	}
 
 	return 0;
+remove_isr:
+	ilo_disable_interrupts(ilo_hw);
+	free_irq(pdev->irq, ilo_hw);
 unmap:
 	ilo_unmap_device(pdev, ilo_hw);
 free_regions:
@@ -759,7 +875,7 @@ static void __exit ilo_exit(void)
 	class_destroy(ilo_class);
 }
 
-MODULE_VERSION("1.1");
+MODULE_VERSION("1.2");
 MODULE_ALIAS(ILO_NAME);
 MODULE_DESCRIPTION(ILO_NAME);
 MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index 03a14c8..3857605 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -46,11 +46,14 @@ struct ilo_hwinfo {
 
 	spinlock_t alloc_lock;
 	spinlock_t fifo_lock;
+	spinlock_t open_lock;
 
 	struct cdev cdev;
 };
 
-/* offset from mmio_vaddr */
+/* offset from mmio_vaddr for enabling doorbell interrupts */
+#define DB_IRQ		0xB2
+/* offset from mmio_vaddr for outbound communications */
 #define DB_OUT		0xD4
 /* DB_OUT reset bit */
 #define DB_RESET	26
@@ -131,6 +134,9 @@ struct ccb_data {
 	/* pointer to hardware device info */
 	struct ilo_hwinfo *ilo_hw;
 
+	/* queue for this ccb to wait for recv data */
+	wait_queue_head_t ccb_waitq;
+
 	/* usage count, to allow for shared ccb's */
 	int	    ccb_cnt;
 
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 915a3b4..8b70e03 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -279,7 +279,7 @@ xpc_check_for_sent_chctl_flags_sn2(struct xpc_partition *part)
 	spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
 
 	dev_dbg(xpc_chan, "received notify IRQ from partid=%d, chctl.all_flags="
-		"0x%lx\n", XPC_PARTID(part), chctl.all_flags);
+		"0x%llx\n", XPC_PARTID(part), chctl.all_flags);
 
 	xpc_wakeup_channel_mgr(part);
 }
@@ -615,7 +615,8 @@ xpc_get_partition_rsvd_page_pa_sn2(void *buf, u64 *cookie, unsigned long *rp_pa,
 	s64 status;
 	enum xp_retval ret;
 
-	status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len);
+	status = sn_partition_reserved_page_pa((u64)buf, cookie,
+			(u64 *)rp_pa, (u64 *)len);
 	if (status == SALRET_OK)
 		ret = xpSuccess;
 	else if (status == SALRET_MORE_PASSES)
@@ -777,8 +778,8 @@ xpc_get_remote_heartbeat_sn2(struct xpc_partition *part)
 	if (ret != xpSuccess)
 		return ret;
 
-	dev_dbg(xpc_part, "partid=%d, heartbeat=%ld, last_heartbeat=%ld, "
-		"heartbeat_offline=%ld, HB_mask[0]=0x%lx\n", XPC_PARTID(part),
+	dev_dbg(xpc_part, "partid=%d, heartbeat=%lld, last_heartbeat=%lld, "
+		"heartbeat_offline=%lld, HB_mask[0]=0x%lx\n", XPC_PARTID(part),
 		remote_vars->heartbeat, part->last_heartbeat,
 		remote_vars->heartbeat_offline,
 		remote_vars->heartbeating_to_mask[0]);
@@ -940,7 +941,7 @@ xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version,
 		part_sn2->remote_vars_pa);
 
 	part->last_heartbeat = remote_vars->heartbeat - 1;
-	dev_dbg(xpc_part, "  last_heartbeat = 0x%016lx\n",
+	dev_dbg(xpc_part, "  last_heartbeat = 0x%016llx\n",
 		part->last_heartbeat);
 
 	part_sn2->remote_vars_part_pa = remote_vars->vars_part_pa;
@@ -1029,7 +1030,8 @@ xpc_identify_activate_IRQ_req_sn2(int nasid)
 	part->activate_IRQ_rcvd++;
 
 	dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = "
-		"%ld:0x%lx\n", (int)nasid, (int)partid, part->activate_IRQ_rcvd,
+		"%lld:0x%lx\n", (int)nasid, (int)partid,
+		part->activate_IRQ_rcvd,
 		remote_vars->heartbeat, remote_vars->heartbeating_to_mask[0]);
 
 	if (xpc_partition_disengaged(part) &&
@@ -1129,7 +1131,7 @@ xpc_identify_activate_IRQ_sender_sn2(void)
 		do {
 			n_IRQs_detected++;
 			nasid = (l * BITS_PER_LONG + b) * 2;
-			dev_dbg(xpc_part, "interrupt from nasid %ld\n", nasid);
+			dev_dbg(xpc_part, "interrupt from nasid %lld\n", nasid);
 			xpc_identify_activate_IRQ_req_sn2(nasid);
 
 			b = find_next_bit(&nasid_mask_long, BITS_PER_LONG,
@@ -1386,7 +1388,7 @@ xpc_pull_remote_vars_part_sn2(struct xpc_partition *part)
 
 		if (pulled_entry->magic != 0) {
 			dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
-				"partition %d has bad magic value (=0x%lx)\n",
+				"partition %d has bad magic value (=0x%llx)\n",
 				partid, sn_partition_id, pulled_entry->magic);
 			return xpBadMagic;
 		}
@@ -1730,14 +1732,14 @@ xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put)
 
 		if (notify->func != NULL) {
 			dev_dbg(xpc_chan, "notify->func() called, notify=0x%p "
-				"msg_number=%ld partid=%d channel=%d\n",
+				"msg_number=%lld partid=%d channel=%d\n",
 				(void *)notify, get, ch->partid, ch->number);
 
 			notify->func(reason, ch->partid, ch->number,
 				     notify->key);
 
 			dev_dbg(xpc_chan, "notify->func() returned, notify=0x%p"
-				" msg_number=%ld partid=%d channel=%d\n",
+				" msg_number=%lld partid=%d channel=%d\n",
 				(void *)notify, get, ch->partid, ch->number);
 		}
 	}
@@ -1858,7 +1860,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
 
 		ch_sn2->w_remote_GP.get = ch_sn2->remote_GP.get;
 
-		dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
+		dev_dbg(xpc_chan, "w_remote_GP.get changed to %lld, partid=%d, "
 			"channel=%d\n", ch_sn2->w_remote_GP.get, ch->partid,
 			ch->number);
 
@@ -1885,7 +1887,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
 		smp_wmb(); /* ensure flags have been cleared before bte_copy */
 		ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put;
 
-		dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
+		dev_dbg(xpc_chan, "w_remote_GP.put changed to %lld, partid=%d, "
 			"channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid,
 			ch->number);
 
@@ -1943,7 +1945,7 @@ xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get)
 		if (ret != xpSuccess) {
 
 			dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
-				" msg %ld from partition %d, channel=%d, "
+				" msg %lld from partition %d, channel=%d, "
 				"ret=%d\n", nmsgs, ch_sn2->next_msg_to_pull,
 				ch->partid, ch->number, ret);
 
@@ -1995,7 +1997,7 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
 		if (cmpxchg(&ch_sn2->w_local_GP.get, get, get + 1) == get) {
 			/* we got the entry referenced by get */
 
-			dev_dbg(xpc_chan, "w_local_GP.get changed to %ld, "
+			dev_dbg(xpc_chan, "w_local_GP.get changed to %lld, "
 				"partid=%d, channel=%d\n", get + 1,
 				ch->partid, ch->number);
 
@@ -2062,7 +2064,7 @@ xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
 
 		/* we just set the new value of local_GP->put */
 
-		dev_dbg(xpc_chan, "local_GP->put changed to %ld, partid=%d, "
+		dev_dbg(xpc_chan, "local_GP->put changed to %lld, partid=%d, "
 			"channel=%d\n", put, ch->partid, ch->number);
 
 		send_msgrequest = 1;
@@ -2147,8 +2149,8 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
 	DBUG_ON(msg->flags != 0);
 	msg->number = put;
 
-	dev_dbg(xpc_chan, "w_local_GP.put changed to %ld; msg=0x%p, "
-		"msg_number=%ld, partid=%d, channel=%d\n", put + 1,
+	dev_dbg(xpc_chan, "w_local_GP.put changed to %lld; msg=0x%p, "
+		"msg_number=%lld, partid=%d, channel=%d\n", put + 1,
 		(void *)msg, msg->number, ch->partid, ch->number);
 
 	*address_of_msg = msg;
@@ -2296,7 +2298,7 @@ xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
 
 		/* we just set the new value of local_GP->get */
 
-		dev_dbg(xpc_chan, "local_GP->get changed to %ld, partid=%d, "
+		dev_dbg(xpc_chan, "local_GP->get changed to %lld, partid=%d, "
 			"channel=%d\n", get, ch->partid, ch->number);
 
 		send_msgrequest = (msg_flags & XPC_M_SN2_INTERRUPT);
@@ -2323,7 +2325,7 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
 	msg = container_of(payload, struct xpc_msg_sn2, payload);
 	msg_number = msg->number;
 
-	dev_dbg(xpc_chan, "msg=0x%p, msg_number=%ld, partid=%d, channel=%d\n",
+	dev_dbg(xpc_chan, "msg=0x%p, msg_number=%lld, partid=%d, channel=%d\n",
 		(void *)msg, msg_number, ch->partid, ch->number);
 
 	DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) !=
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 5d778ec..16f0abd 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -240,7 +240,6 @@ xpnet_receive(short partid, int channel, struct xpnet_message *msg)
 		(void *)skb->head, (void *)skb->data, skb_tail_pointer(skb),
 		skb_end_pointer(skb), skb->len);
 
-	xpnet_device->last_rx = jiffies;
 	xpnet_device->stats.rx_packets++;
 	xpnet_device->stats.rx_bytes += skb->len + ETH_HLEN;
 
@@ -436,7 +435,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (skb->data[0] == 0x33) {
 		dev_kfree_skb(skb);
-		return 0;	/* nothing needed to be done */
+		return NETDEV_TX_OK;	/* nothing needed to be done */
 	}
 
 	/*
@@ -503,7 +502,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 06084db..2fb9d5f 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -276,7 +276,7 @@ static struct attribute_group mmc_std_attr_group = {
 	.attrs = mmc_std_attrs,
 };
 
-static struct attribute_group *mmc_attr_groups[] = {
+static const struct attribute_group *mmc_attr_groups[] = {
 	&mmc_std_attr_group,
 	NULL,
 };
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index cd81c39..7ad646f 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -314,7 +314,7 @@ static struct attribute_group sd_std_attr_group = {
 	.attrs = sd_std_attrs,
 };
 
-static struct attribute_group *sd_attr_groups[] = {
+static const struct attribute_group *sd_attr_groups[] = {
 	&sd_std_attr_group,
 	NULL,
 };
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index e1aa847..8741d0f 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -21,6 +21,7 @@
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
+#include <linux/gpio.h>
 
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
@@ -430,7 +431,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 				clk = 255;
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
-		if (host->hw_designer == 0x80)
+		if (host->hw_designer == AMBA_VENDOR_ST)
 			clk |= MCI_FCEN; /* Bug fix in ST IP block */
 		clk |= MCI_CLK_ENABLE;
 	}
@@ -443,7 +444,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		break;
 	case MMC_POWER_UP:
 		/* The ST version does not have this, fall through to POWER_ON */
-		if (host->hw_designer != 0x80) {
+		if (host->hw_designer != AMBA_VENDOR_ST) {
 			pwr |= MCI_PWR_UP;
 			break;
 		}
@@ -453,7 +454,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	}
 
 	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
-		if (host->hw_designer != 0x80)
+		if (host->hw_designer != AMBA_VENDOR_ST)
 			pwr |= MCI_ROD;
 		else {
 			/*
@@ -472,17 +473,41 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	}
 }
 
+static int mmci_get_ro(struct mmc_host *mmc)
+{
+	struct mmci_host *host = mmc_priv(mmc);
+
+	if (host->gpio_wp == -ENOSYS)
+		return -ENOSYS;
+
+	return gpio_get_value(host->gpio_wp);
+}
+
+static int mmci_get_cd(struct mmc_host *mmc)
+{
+	struct mmci_host *host = mmc_priv(mmc);
+	unsigned int status;
+
+	if (host->gpio_cd == -ENOSYS)
+		status = host->plat->status(mmc_dev(host->mmc));
+	else
+		status = gpio_get_value(host->gpio_cd);
+
+	return !status;
+}
+
 static const struct mmc_host_ops mmci_ops = {
 	.request	= mmci_request,
 	.set_ios	= mmci_set_ios,
+	.get_ro		= mmci_get_ro,
+	.get_cd		= mmci_get_cd,
 };
 
 static void mmci_check_status(unsigned long data)
 {
 	struct mmci_host *host = (struct mmci_host *)data;
-	unsigned int status;
+	unsigned int status = mmci_get_cd(host->mmc);
 
-	status = host->plat->status(mmc_dev(host->mmc));
 	if (status ^ host->oldstat)
 		mmc_detect_change(host->mmc, 0);
 
@@ -515,12 +540,15 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
-	/* Bits 12 thru 19 is the designer */
-	host->hw_designer = (dev->periphid >> 12) & 0xff;
-	/* Bits 20 thru 23 is the revison */
-	host->hw_revision = (dev->periphid >> 20) & 0xf;
+
+	host->gpio_wp = -ENOSYS;
+	host->gpio_cd = -ENOSYS;
+
+	host->hw_designer = amba_manf(dev);
+	host->hw_revision = amba_rev(dev);
 	DBG(host, "designer ID = 0x%02x\n", host->hw_designer);
 	DBG(host, "revision = 0x%01x\n", host->hw_revision);
+
 	host->clk = clk_get(&dev->dev, NULL);
 	if (IS_ERR(host->clk)) {
 		ret = PTR_ERR(host->clk);
@@ -591,6 +619,27 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 	writel(0, host->base + MMCIMASK1);
 	writel(0xfff, host->base + MMCICLEAR);
 
+#ifdef CONFIG_GPIOLIB
+	if (gpio_is_valid(plat->gpio_cd)) {
+		ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
+		if (ret == 0)
+			ret = gpio_direction_input(plat->gpio_cd);
+		if (ret == 0)
+			host->gpio_cd = plat->gpio_cd;
+		else if (ret != -ENOSYS)
+			goto err_gpio_cd;
+	}
+	if (gpio_is_valid(plat->gpio_wp)) {
+		ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
+		if (ret == 0)
+			ret = gpio_direction_input(plat->gpio_wp);
+		if (ret == 0)
+			host->gpio_wp = plat->gpio_wp;
+		else if (ret != -ENOSYS)
+			goto err_gpio_wp;
+	}
+#endif
+
 	ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
 	if (ret)
 		goto unmap;
@@ -602,6 +651,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
 	writel(MCI_IRQENABLE, host->base + MMCIMASK0);
 
 	amba_set_drvdata(dev, mmc);
+	host->oldstat = mmci_get_cd(host->mmc);
 
 	mmc_add_host(mmc);
 
@@ -620,6 +670,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
  irq0_free:
 	free_irq(dev->irq[0], host);
  unmap:
+	if (host->gpio_wp != -ENOSYS)
+		gpio_free(host->gpio_wp);
+ err_gpio_wp:
+	if (host->gpio_cd != -ENOSYS)
+		gpio_free(host->gpio_cd);
+ err_gpio_cd:
 	iounmap(host->base);
  clk_disable:
 	clk_disable(host->clk);
@@ -655,6 +711,11 @@ static int __devexit mmci_remove(struct amba_device *dev)
 		free_irq(dev->irq[0], host);
 		free_irq(dev->irq[1], host);
 
+		if (host->gpio_wp != -ENOSYS)
+			gpio_free(host->gpio_wp);
+		if (host->gpio_cd != -ENOSYS)
+			gpio_free(host->gpio_cd);
+
 		iounmap(host->base);
 		clk_disable(host->clk);
 		clk_put(host->clk);
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h
index 0441bac..839f264 100644
--- a/drivers/mmc/host/mmci.h
+++ b/drivers/mmc/host/mmci.h
@@ -151,6 +151,8 @@ struct mmci_host {
 	struct mmc_data		*data;
 	struct mmc_host		*mmc;
 	struct clk		*clk;
+	int			gpio_cd;
+	int			gpio_wp;
 
 	unsigned int		data_xfered;
 
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 8664fee..e7563a9 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -5,7 +5,7 @@
  * (C) 2000 Red Hat. GPL'd
  *
  *
- * 10/10/2000	Nicolas Pitre <nico@cam.org>
+ * 10/10/2000	Nicolas Pitre <nico@fluxnic.net>
  * 	- completely revamped method functions so they are aware and
  * 	  independent of the flash geometry (buswidth, interleave, etc.)
  * 	- scalability vs code size is completely set at compile-time
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index 6c740f3..0667a67 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * 10/10/2000	Nicolas Pitre <nico@cam.org>
+ * 10/10/2000	Nicolas Pitre <nico@fluxnic.net>
  * 	- completely revamped method functions so they are aware and
  * 	  independent of the flash geometry (buswidth, interleave, etc.)
  * 	- scalability vs code size is completely set at compile-time
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c
index 365c77b..a7c808b 100644
--- a/drivers/mtd/maps/bfin-async-flash.c
+++ b/drivers/mtd/maps/bfin-async-flash.c
@@ -6,7 +6,7 @@
  * for example.  All board-specific configuration goes in your
  * board resources file.
  *
- * Copyright 2000 Nicolas Pitre <nico@cam.org>
+ * Copyright 2000 Nicolas Pitre <nico@fluxnic.net>
  * Copyright 2005-2008 Analog Devices Inc.
  *
  * Enter bugs at http://blackfin.uclinux.org/
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
index 60e68bd..d41f347 100644
--- a/drivers/mtd/maps/ceiva.c
+++ b/drivers/mtd/maps/ceiva.c
@@ -9,7 +9,7 @@
  * Based on: sa1100-flash.c, which has the following copyright:
  * Flash memory access on SA11x0 based devices
  *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
+ * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
  *
  */
 
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
index 42969fe..b3cb3a1 100644
--- a/drivers/mtd/maps/dc21285.c
+++ b/drivers/mtd/maps/dc21285.c
@@ -1,7 +1,7 @@
 /*
  * MTD map driver for flash on the DC21285 (the StrongARM-110 companion chip)
  *
- * (C) 2000  Nicolas Pitre <nico@cam.org>
+ * (C) 2000  Nicolas Pitre <nico@fluxnic.net>
  *
  * This code is GPL
  */
@@ -249,5 +249,5 @@ module_exit(cleanup_dc21285);
 
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net>");
 MODULE_DESCRIPTION("MTD map driver for DC21285 boards");
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 748c85f..76708e7 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -1,7 +1,7 @@
 /*
  * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
  *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
+ * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
  * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
  * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
  */
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 643aa06..74fa075 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -175,5 +175,5 @@ module_init(init_pxa2xx_flash);
 module_exit(cleanup_pxa2xx_flash);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
+MODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net>");
 MODULE_DESCRIPTION("MTD map driver for Intel XScale PXA2xx");
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index c6210f5..fdb97f3 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -1,7 +1,7 @@
 /*
  * Flash memory access on SA11x0 based devices
  *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
+ * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
  */
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 77db5ce..2d70295 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,7 +1,7 @@
 /*
  * Direct MTD block device access
  *
- * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
+ * (C) 2000-2003 Nicolas Pitre <nico@fluxnic.net>
  * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
  */
 
@@ -403,5 +403,5 @@ module_exit(cleanup_mtdblock);
 
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Nicolas Pitre <nico@cam.org> et al.");
+MODULE_AUTHOR("Nicolas Pitre <nico@fluxnic.net> et al.");
 MODULE_DESCRIPTION("Caching read/erase/writeback block device emulation access to MTD devices");
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 00ebf7a..69007a6 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -217,7 +217,7 @@ struct attribute_group mtd_group = {
 	.attrs		= mtd_attrs,
 };
 
-struct attribute_group *mtd_groups[] = {
+const struct attribute_group *mtd_groups[] = {
 	&mtd_group,
 	NULL,
 };
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 349fcbe..742504e 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -1,7 +1,7 @@
 /*
  * Simple MTD partitioning layer
  *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
+ * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
  *
  * This code is GPL
  *
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index 782994e..005b91f 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -63,7 +63,7 @@ static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte)
 {
 	struct nand_chip *this = mtd->priv;
 
-	omap_writew(0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
+	omap_writew(0, (OMAP1_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
 	omap_writew(byte, this->IO_ADDR_W);
 	ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0);
 	ndelay(40);
@@ -78,7 +78,7 @@ static u_char ams_delta_read_byte(struct mtd_info *mtd)
 
 	ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0);
 	ndelay(40);
-	omap_writew(~0, (OMAP_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
+	omap_writew(~0, (OMAP1_MPUIO_BASE + OMAP_MPUIO_IO_CNTL));
 	res = omap_readw(this->IO_ADDR_R);
 	ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE,
 			       AMS_DELTA_LATCH2_NAND_NRE);
@@ -178,8 +178,8 @@ static int __init ams_delta_init(void)
 	ams_delta_mtd->priv = this;
 
 	/* Set address of NAND IO lines */
-	this->IO_ADDR_R = (OMAP_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH);
-	this->IO_ADDR_W = (OMAP_MPUIO_BASE + OMAP_MPUIO_OUTPUT);
+	this->IO_ADDR_R = (OMAP1_MPUIO_BASE + OMAP_MPUIO_INPUT_LATCH);
+	this->IO_ADDR_W = (OMAP1_MPUIO_BASE + OMAP_MPUIO_OUTPUT);
 	this->read_byte = ams_delta_read_byte;
 	this->write_buf = ams_delta_write_buf;
 	this->read_buf = ams_delta_read_buf;
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c
index 2c410a0..0f5562a 100644
--- a/drivers/mtd/nand/ts7250.c
+++ b/drivers/mtd/nand/ts7250.c
@@ -24,8 +24,11 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
-#include <asm/io.h>
+#include <linux/io.h>
+
 #include <mach/hardware.h>
+#include <mach/ts72xx.h>
+
 #include <asm/sizes.h>
 #include <asm/mach-types.h>
 
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c
index 54b0186..4876977 100644
--- a/drivers/mtd/ubi/debug.c
+++ b/drivers/mtd/ubi/debug.c
@@ -196,4 +196,36 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)
 	printk(KERN_DEBUG "\t1st 16 characters of name: %s\n", nm);
 }
 
+/**
+ * ubi_dbg_dump_flash - dump a region of flash.
+ * @ubi: UBI device description object
+ * @pnum: the physical eraseblock number to dump
+ * @offset: the starting offset within the physical eraseblock to dump
+ * @len: the length of the region to dump
+ */
+void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len)
+{
+	int err;
+	size_t read;
+	void *buf;
+	loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
+
+	buf = vmalloc(len);
+	if (!buf)
+		return;
+	err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
+	if (err && err != -EUCLEAN) {
+		ubi_err("error %d while reading %d bytes from PEB %d:%d, "
+			"read %zd bytes", err, len, pnum, offset, read);
+		goto out;
+	}
+
+	dbg_msg("dumping %d bytes of data from PEB %d, offset %d",
+		len, pnum, offset);
+	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1);
+out:
+	vfree(buf);
+	return;
+}
+
 #endif /* CONFIG_MTD_UBI_DEBUG */
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h
index a4da7a0..f30bcb3 100644
--- a/drivers/mtd/ubi/debug.h
+++ b/drivers/mtd/ubi/debug.h
@@ -55,6 +55,7 @@ void ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx);
 void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv);
 void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb, int type);
 void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
+void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
 
 #ifdef CONFIG_MTD_UBI_DEBUG_MSG
 /* General debugging messages */
@@ -167,6 +168,7 @@ static inline int ubi_dbg_is_erase_failure(void)
 #define ubi_dbg_dump_sv(sv)              ({})
 #define ubi_dbg_dump_seb(seb, type)      ({})
 #define ubi_dbg_dump_mkvol_req(req)      ({})
+#define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({})
 
 #define UBI_IO_DEBUG               0
 #define DBG_DISABLE_BGT            0
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 4cb6992..8aa51e7 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -269,6 +269,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
 		ubi_err("error %d while writing %d bytes to PEB %d:%d, written "
 			"%zd bytes", err, len, pnum, offset, written);
 		ubi_dbg_dump_stack();
+		ubi_dbg_dump_flash(ubi, pnum, offset, len);
 	} else
 		ubi_assert(written == len);
 
@@ -475,30 +476,46 @@ out:
  */
 static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 {
-	int err;
+	int err, err1;
 	size_t written;
 	loff_t addr;
 	uint32_t data = 0;
+	struct ubi_vid_hdr vid_hdr;
 
-	addr = (loff_t)pnum * ubi->peb_size;
+	addr = (loff_t)pnum * ubi->peb_size + ubi->vid_hdr_aloffset;
 	err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
-	if (err) {
-		ubi_err("error %d while writing 4 bytes to PEB %d:%d, written "
-			"%zd bytes", err, pnum, 0, written);
-		ubi_dbg_dump_stack();
-		return err;
+	if (!err) {
+		addr -= ubi->vid_hdr_aloffset;
+		err = ubi->mtd->write(ubi->mtd, addr, 4, &written,
+				      (void *)&data);
+		if (!err)
+			return 0;
 	}
 
-	addr += ubi->vid_hdr_aloffset;
-	err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data);
-	if (err) {
-		ubi_err("error %d while writing 4 bytes to PEB %d:%d, written "
-			"%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written);
-		ubi_dbg_dump_stack();
-		return err;
-	}
+	/*
+	 * We failed to write to the media. This was observed with Spansion
+	 * S29GL512N NOR flash. Most probably the eraseblock erasure was
+	 * interrupted at a very inappropriate moment, so it became unwritable.
+	 * In this case we probably anyway have garbage in this PEB.
+	 */
+	err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
+	if (err1 == UBI_IO_BAD_VID_HDR)
+		/*
+		 * The VID header is corrupted, so we can safely erase this
+		 * PEB and not afraid that it will be treated as a valid PEB in
+		 * case of an unclean reboot.
+		 */
+		return 0;
 
-	return 0;
+	/*
+	 * The PEB contains a valid VID header, but we cannot invalidate it.
+	 * Supposedly the flash media or the driver is screwed up, so return an
+	 * error.
+	 */
+	ubi_err("cannot invalidate PEB %d, write returned %d read returned %d",
+		pnum, err, err1);
+	ubi_dbg_dump_flash(ubi, pnum, 0, ubi->peb_size);
+	return -EIO;
 }
 
 /**
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index b847745..e7161ad 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -75,9 +75,10 @@ static int add_to_list(struct ubi_scan_info *si, int pnum, int ec,
 		dbg_bld("add to free: PEB %d, EC %d", pnum, ec);
 	else if (list == &si->erase)
 		dbg_bld("add to erase: PEB %d, EC %d", pnum, ec);
-	else if (list == &si->corr)
+	else if (list == &si->corr) {
 		dbg_bld("add to corrupted: PEB %d, EC %d", pnum, ec);
-	else if (list == &si->alien)
+		si->corr_count += 1;
+	} else if (list == &si->alien)
 		dbg_bld("add to alien: PEB %d, EC %d", pnum, ec);
 	else
 		BUG();
@@ -864,7 +865,9 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si,
 		}
 	}
 
-	/* Both UBI headers seem to be fine */
+	if (ec_corr)
+		ubi_warn("valid VID header but corrupted EC header at PEB %d",
+			 pnum);
 	err = ubi_scan_add_used(ubi, si, pnum, ec, vidh, bitflips);
 	if (err)
 		return err;
@@ -936,6 +939,19 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi)
 		ubi_msg("empty MTD device detected");
 
 	/*
+	 * Few corrupted PEBs are not a problem and may be just a result of
+	 * unclean reboots. However, many of them may indicate some problems
+	 * with the flash HW or driver. Print a warning in this case.
+	 */
+	if (si->corr_count >= 8 || si->corr_count >= ubi->peb_count / 4) {
+		ubi_warn("%d PEBs are corrupted", si->corr_count);
+		printk(KERN_WARNING "corrupted PEBs are:");
+		list_for_each_entry(seb, &si->corr, u.list)
+			printk(KERN_CONT " %d", seb->pnum);
+		printk(KERN_CONT "\n");
+	}
+
+	/*
 	 * In case of unknown erase counter we use the mean erase counter
 	 * value.
 	 */
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h
index 1017cf1..bab3169 100644
--- a/drivers/mtd/ubi/scan.h
+++ b/drivers/mtd/ubi/scan.h
@@ -102,6 +102,7 @@ struct ubi_scan_volume {
  * @mean_ec: mean erase counter value
  * @ec_sum: a temporary variable used when calculating @mean_ec
  * @ec_count: a temporary variable used when calculating @mean_ec
+ * @corr_count: count of corrupted PEBs
  * @image_seq_set: indicates @ubi->image_seq is known
  *
  * This data structure contains the result of scanning and may be used by other
@@ -125,6 +126,7 @@ struct ubi_scan_info {
 	int mean_ec;
 	uint64_t ec_sum;
 	int ec_count;
+	int corr_count;
 	int image_seq_set;
 };
 
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 6a5fe96..c290f51 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -579,7 +579,8 @@ void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
 	for (rb = rb_first(root),                                            \
 	     pos = (rb ? container_of(rb, typeof(*pos), member) : NULL);     \
 	     rb;                                                             \
-	     rb = rb_next(rb), pos = container_of(rb, typeof(*pos), member))
+	     rb = rb_next(rb),                                               \
+	     pos = (rb ? container_of(rb, typeof(*pos), member) : NULL))
 
 /**
  * ubi_zalloc_vid_hdr - allocate a volume identifier header object.
diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c
index 367bec6..f603091 100644
--- a/drivers/net/3c501.c
+++ b/drivers/net/3c501.c
@@ -409,7 +409,7 @@ static void el_timeout(struct net_device *dev)
  * no real choice.
  */
 
-static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
@@ -485,7 +485,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			if (el_debug > 2)
 				pr_debug(" queued xmit.\n");
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 		/* A receive upset our load, despite our best efforts */
 		if (el_debug > 2)
diff --git a/drivers/net/3c501.h b/drivers/net/3c501.h
index f40b049..183fd55 100644
--- a/drivers/net/3c501.h
+++ b/drivers/net/3c501.h
@@ -6,7 +6,7 @@
 static int  el1_probe1(struct net_device *dev, int ioaddr);
 static int  el_open(struct net_device *dev);
 static void el_timeout(struct net_device *dev);
-static int  el_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t el_interrupt(int irq, void *dev_id);
 static void el_receive(struct net_device *dev);
 static void el_reset(struct net_device *dev);
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 134638a..c71e12d 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -383,7 +383,7 @@ out:
 static int
 el2_open(struct net_device *dev)
 {
-    int retval = -EAGAIN;
+    int retval;
 
     if (dev->irq < 2) {
 	int irqlist[] = {5, 9, 3, 4, 0};
@@ -391,7 +391,8 @@ el2_open(struct net_device *dev)
 
 	outb(EGACFR_NORM, E33G_GACFR);	/* Enable RAM and interrupts. */
 	do {
-	    if (request_irq (*irqp, NULL, 0, "bogus", dev) != -EBUSY) {
+	    retval = request_irq(*irqp, NULL, 0, "bogus", dev);
+	    if (retval >= 0) {
 		/* Twinkle the interrupt, and check if it's seen. */
 		unsigned long cookie = probe_irq_on();
 		outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
@@ -400,11 +401,14 @@ el2_open(struct net_device *dev)
 		    && ((retval = request_irq(dev->irq = *irqp,
 		    eip_interrupt, 0, dev->name, dev)) == 0))
 		    break;
+	    } else {
+		    if (retval != -EBUSY)
+			    return retval;
 	    }
 	} while (*++irqp);
 	if (*irqp == 0) {
 	    outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */
-	    return retval;
+	    return -EAGAIN;
 	}
     } else {
 	if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index f71b354..a21c9d1 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -976,7 +976,7 @@ static int elp_open(struct net_device *dev)
  *
  ******************************************************/
 
-static bool send_packet(struct net_device *dev, struct sk_buff *skb)
+static netdev_tx_t send_packet(struct net_device *dev, struct sk_buff *skb)
 {
 	elp_device *adapter = netdev_priv(dev);
 	unsigned long target;
@@ -1067,7 +1067,7 @@ static void elp_timeout(struct net_device *dev)
  *
  ******************************************************/
 
-static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	unsigned long flags;
 	elp_device *adapter = netdev_priv(dev);
@@ -1101,7 +1101,7 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	prime_rx(dev);
 	spin_unlock_irqrestore(&adapter->lock, flags);
 	netif_start_queue(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /******************************************************
diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c
index 96b8665..a6dc8bc 100644
--- a/drivers/net/3c507.c
+++ b/drivers/net/3c507.c
@@ -284,7 +284,8 @@ static unsigned short init_words[] = {
 
 static int	el16_probe1(struct net_device *dev, int ioaddr);
 static int	el16_open(struct net_device *dev);
-static int	el16_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t el16_send_packet(struct sk_buff *skb,
+				    struct net_device *dev);
 static irqreturn_t el16_interrupt(int irq, void *dev_id);
 static void el16_rx(struct net_device *dev);
 static int	el16_close(struct net_device *dev);
@@ -509,7 +510,8 @@ static void el16_tx_timeout (struct net_device *dev)
 }
 
 
-static int el16_send_packet (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t el16_send_packet (struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
@@ -537,7 +539,7 @@ static int el16_send_packet (struct sk_buff *skb, struct net_device *dev)
 
 	/* You might need to clean up and record Tx statistics here. */
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*	The typical workload of the driver:
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index d2137ef..3b00a4e 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -191,7 +191,7 @@ static void el3_common_remove(struct net_device *dev);
 static ushort id_read_eeprom(int index);
 static ushort read_eeprom(int ioaddr, int index);
 static int el3_open(struct net_device *dev);
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t el3_interrupt(int irq, void *dev_id);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
@@ -816,7 +816,7 @@ el3_tx_timeout (struct net_device *dev)
 }
 
 
-static int
+static netdev_tx_t
 el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
@@ -892,7 +892,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
 		}
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The EL3 interrupt handler. */
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
index 4a7c328..4adcb95 100644
--- a/drivers/net/3c515.c
+++ b/drivers/net/3c515.c
@@ -369,8 +369,8 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
 			    struct pnp_dev *idev, int card_number);
 static int corkscrew_open(struct net_device *dev);
 static void corkscrew_timer(unsigned long arg);
-static int corkscrew_start_xmit(struct sk_buff *skb,
-				struct net_device *dev);
+static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static int corkscrew_rx(struct net_device *dev);
 static void corkscrew_timeout(struct net_device *dev);
 static int boomerang_rx(struct net_device *dev);
@@ -998,8 +998,8 @@ static void corkscrew_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int corkscrew_start_xmit(struct sk_buff *skb,
-				struct net_device *dev)
+static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
 	struct corkscrew_private *vp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
@@ -1056,7 +1056,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
 			netif_wake_queue(dev);
 		}
 		dev->trans_start = jiffies;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	/* Put out the doubleword header... */
 	outl(skb->len, ioaddr + TX_FIFO);
@@ -1119,7 +1119,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
 			outb(0x00, ioaddr + TxStatus);	/* Pop the status stack. */
 		}
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index cdd955c..cb0b730 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -183,7 +183,7 @@ sizeof(nop_cmd) = 8;
 static irqreturn_t elmc_interrupt(int irq, void *dev_id);
 static int elmc_open(struct net_device *dev);
 static int elmc_close(struct net_device *dev);
-static int elmc_send_packet(struct sk_buff *, struct net_device *);
+static netdev_tx_t elmc_send_packet(struct sk_buff *, struct net_device *);
 static struct net_device_stats *elmc_get_stats(struct net_device *dev);
 static void elmc_timeout(struct net_device *dev);
 #ifdef ELMC_MULTICAST
@@ -1129,7 +1129,7 @@ static void elmc_timeout(struct net_device *dev)
  * send frame
  */
 
-static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	int len;
 	int i;
@@ -1198,7 +1198,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
 		netif_wake_queue(dev);
 	dev_kfree_skb(skb);
 #endif
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*******************************************
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index aaa8a9f..6021e6d 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -213,7 +213,8 @@ static int	mc32_probe1(struct net_device *dev, int ioaddr);
 static int      mc32_command(struct net_device *dev, u16 cmd, void *data, int len);
 static int	mc32_open(struct net_device *dev);
 static void	mc32_timeout(struct net_device *dev);
-static int	mc32_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mc32_send_packet(struct sk_buff *skb,
+				    struct net_device *dev);
 static irqreturn_t mc32_interrupt(int irq, void *dev_id);
 static int	mc32_close(struct net_device *dev);
 static struct	net_device_stats *mc32_get_stats(struct net_device *dev);
@@ -1020,7 +1021,8 @@ static void mc32_timeout(struct net_device *dev)
  *
  */
 
-static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mc32_send_packet(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct mc32_local *lp = netdev_priv(dev);
 	u32 head = atomic_read(&lp->tx_ring_head);
@@ -1035,7 +1037,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	if (skb_padto(skb, ETH_ZLEN)) {
 		netif_wake_queue(dev);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	atomic_dec(&lp->tx_count);
@@ -1066,7 +1068,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
 	p->control     &= ~CONTROL_EOL;
 
 	netif_wake_queue(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 4567588..7adff4d 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -716,8 +716,10 @@ static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
 static void vortex_timer(unsigned long arg);
 static void rx_oom_timer(unsigned long arg);
-static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t vortex_start_xmit(struct sk_buff *skb,
+				     struct net_device *dev);
+static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static int vortex_rx(struct net_device *dev);
 static int boomerang_rx(struct net_device *dev);
 static irqreturn_t vortex_interrupt(int irq, void *dev_id);
@@ -2035,7 +2037,7 @@ vortex_error(struct net_device *dev, int status)
 	}
 }
 
-static int
+static netdev_tx_t
 vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
@@ -2087,10 +2089,10 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
 		}
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
-static int
+static netdev_tx_t
 boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
@@ -2177,7 +2179,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	spin_unlock_irqrestore(&vp->lock, flags);
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
diff --git a/drivers/net/7990.c b/drivers/net/7990.c
index 69f5b7d..b1e5764 100644
--- a/drivers/net/7990.c
+++ b/drivers/net/7990.c
@@ -585,7 +585,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
 		lp->tx_full = 1;
 	spin_unlock_irqrestore (&lp->devlock, flags);
 
-        return 0;
+        return NETDEV_TX_OK;
 }
 EXPORT_SYMBOL_GPL(lance_start_xmit);
 
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index d0dbbf3..462d9f5 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -736,7 +736,8 @@ static void cp_tx (struct cp_private *cp)
 		netif_wake_queue(cp->dev);
 }
 
-static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
+					struct net_device *dev)
 {
 	struct cp_private *cp = netdev_priv(dev);
 	unsigned entry;
@@ -890,7 +891,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
 	cpw8(TxPoll, NormalTxPoll);
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* Set or clear the multicast filter for this adaptor.
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 0e2ba21..4a36287 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -628,8 +628,8 @@ static void mdio_write (struct net_device *dev, int phy_id, int location,
 static void rtl8139_start_thread(struct rtl8139_private *tp);
 static void rtl8139_tx_timeout (struct net_device *dev);
 static void rtl8139_init_ring (struct net_device *dev);
-static int rtl8139_start_xmit (struct sk_buff *skb,
-			       struct net_device *dev);
+static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
+				       struct net_device *dev);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void rtl8139_poll_controller(struct net_device *dev);
 #endif
@@ -1687,7 +1687,8 @@ static void rtl8139_tx_timeout (struct net_device *dev)
 	}
 }
 
-static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
+					     struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -1707,7 +1708,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 	} else {
 		dev_kfree_skb(skb);
 		dev->stats.tx_dropped++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	spin_lock_irqsave(&tp->lock, flags);
@@ -1732,7 +1733,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 		pr_debug("%s: Queued Tx packet size %u to slot %d.\n",
 			dev->name, len, entry);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index 7754754..ea6b139 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -356,7 +356,7 @@ static char init_setup[] =
 	0x7f /*  *multi IA */ };
 
 static int i596_open(struct net_device *dev);
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t i596_interrupt(int irq, void *dev_id);
 static int i596_close(struct net_device *dev);
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
@@ -1054,8 +1054,7 @@ static void i596_tx_timeout (struct net_device *dev)
 	netif_wake_queue (dev);
 }
 
-
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct i596_private *lp = dev->ml_priv;
 	struct tx_cmd *tx_cmd;
@@ -1068,7 +1067,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (skb->len < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 	netif_stop_queue(dev);
@@ -1110,7 +1109,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	netif_start_queue(dev);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void print_eth(unsigned char *add, char *str)
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index 21153de..7c7518b 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -17,7 +17,7 @@ int ei_close(struct net_device *dev)
 }
 EXPORT_SYMBOL(ei_close);
 
-int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	return __ei_start_xmit(skb, dev);
 }
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 3c61d6d..3d9e8fb 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -40,7 +40,7 @@ extern int ei_open(struct net_device *dev);
 extern int ei_close(struct net_device *dev);
 extern irqreturn_t ei_interrupt(int irq, void *dev_id);
 extern void ei_tx_timeout(struct net_device *dev);
-extern int ei_start_xmit(struct sk_buff *skb, struct net_device *dev);
+extern netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev);
 extern void ei_set_multicast_list(struct net_device *dev);
 extern struct net_device_stats *ei_get_stats(struct net_device *dev);
 
@@ -58,7 +58,7 @@ extern int eip_open(struct net_device *dev);
 extern int eip_close(struct net_device *dev);
 extern irqreturn_t eip_interrupt(int irq, void *dev_id);
 extern void eip_tx_timeout(struct net_device *dev);
-extern int eip_start_xmit(struct sk_buff *skb, struct net_device *dev);
+extern netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev);
 extern void eip_set_multicast_list(struct net_device *dev);
 extern struct net_device_stats *eip_get_stats(struct net_device *dev);
 
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
index d225c29..a2a64ea 100644
--- a/drivers/net/8390p.c
+++ b/drivers/net/8390p.c
@@ -22,7 +22,7 @@ int eip_close(struct net_device *dev)
 }
 EXPORT_SYMBOL(eip_close);
 
-int eip_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	return __ei_start_xmit(skb, dev);
 }
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5ce7cba..ed5741b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -209,7 +209,7 @@ config MII
 
 config MACB
 	tristate "Atmel MACB support"
-	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9
+	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9
 	select PHYLIB
 	help
 	  The Atmel MACB ethernet interface is found on many AT32 and AT91
@@ -1776,7 +1776,7 @@ config SC92031
 
 config CPMAC
 	tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
-	depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN
+	depends on NET_ETHERNET && EXPERIMENTAL && AR7
 	select PHYLIB
 	help
 	  TI AR7 CPMAC Ethernet support
@@ -1928,6 +1928,21 @@ config ATL2
 	  To compile this driver as a module, choose M here.  The module
 	  will be called atl2.
 
+config XILINX_EMACLITE
+	tristate "Xilinx 10/100 Ethernet Lite support"
+	depends on PPC32 || MICROBLAZE
+	help
+	  This driver supports the 10/100 Ethernet Lite from Xilinx.
+
+config BCM63XX_ENET
+	tristate "Broadcom 63xx internal mac support"
+	depends on BCM63XX
+	select MII
+	select PHYLIB
+	help
+	  This driver supports the ethernet MACs in the Broadcom 63xx
+	  MIPS chipset family (BCM63XX).
+
 source "drivers/net/fs_enet/Kconfig"
 
 endif # NET_ETHERNET
@@ -2369,10 +2384,6 @@ config UCC_GETH
 	  This driver supports the Gigabit Ethernet mode of the QUICC Engine,
 	  which is available on some Freescale SOCs.
 
-config UGETH_MAGIC_PACKET
-	bool "Magic Packet detection support"
-	depends on UCC_GETH
-
 config UGETH_TX_ON_DEMAND
 	bool "Transmit on Demand support"
 	depends on UCC_GETH
@@ -2724,6 +2735,7 @@ config BNX2X
 	select FW_LOADER
 	select ZLIB_INFLATE
 	select LIBCRC32C
+	select MDIO
 	help
 	  This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
 	  To compile this driver as a module, choose M here: the module
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ead8cab..ae8cd30 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -137,11 +137,13 @@ obj-$(CONFIG_B44) += b44.o
 obj-$(CONFIG_FORCEDETH) += forcedeth.o
 obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o
 obj-$(CONFIG_AX88796) += ax88796.o
+obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
 
 obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
 obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
 ll_temac-objs := ll_temac_main.o ll_temac_mdio.o
 obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o
+obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
 obj-$(CONFIG_QLA3XXX) += qla3xxx.o
 obj-$(CONFIG_QLGE) += qlge/
 
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index 08787f5..b7ec036 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -547,17 +547,18 @@ static void lance_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lance_start_xmit (struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct lance_private *lp = netdev_priv(dev);
 	volatile struct lance_regs *ll = lp->ll;
 	volatile struct lance_init_block *ib = lp->init_block;
 	int entry, skblen;
-	int status = 0;
+	int status = NETDEV_TX_OK;
 	unsigned long flags;
 
 	if (skb_padto(skb, ETH_ZLEN))
-		return 0;
+		return NETDEV_TX_OK;
 	skblen = max_t(unsigned, skb->len, ETH_ZLEN);
 
 	local_irq_save(flags);
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 08419ee..5f0b05c 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -2464,7 +2464,8 @@ ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr,
 }
 
 
-static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ace_start_xmit(struct sk_buff *skb,
+				  struct net_device *dev)
 {
 	struct ace_private *ap = netdev_priv(dev);
 	struct ace_regs __iomem *regs = ap->regs;
diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h
index c987c9b..17079b9 100644
--- a/drivers/net/acenic.h
+++ b/drivers/net/acenic.h
@@ -775,7 +775,8 @@ static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs);
 static irqreturn_t ace_interrupt(int irq, void *dev_id);
 static int ace_load_firmware(struct net_device *dev);
 static int ace_open(struct net_device *dev);
-static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ace_start_xmit(struct sk_buff *skb,
+				  struct net_device *dev);
 static int ace_close(struct net_device *dev);
 static void ace_tasklet(unsigned long dev);
 static void ace_dump_trace(struct ace_private *ap);
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 19831bd..4e6359f 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1300,7 +1300,8 @@ static int amd8111e_tx_queue_avail(struct amd8111e_priv* lp )
 This function will queue the transmit packets to the descriptors and will trigger the send operation. It also initializes the transmit descriptors with buffer physical address, byte count, ownership to hardware etc.
 */
 
-static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev)
+static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
+				       struct net_device * dev)
 {
 	struct amd8111e_priv *lp = netdev_priv(dev);
 	int tx_index;
@@ -1346,7 +1347,7 @@ static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev)
 		netif_stop_queue(dev);
 	}
 	spin_unlock_irqrestore(&lp->lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 /*
 This function returns all the memory mapped registers of the device.
@@ -1523,9 +1524,6 @@ static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd)
 	int err;
 	u32 mii_regval;
 
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
 	switch(cmd) {
 	case SIOCGMIIPHY:
 		data->phy_id = lp->ext_phy_addr;
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 7f83254..b5dc7f5 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -192,7 +192,8 @@ static irqreturn_t cops_interrupt (int irq, void *dev_id);
 static void cops_poll (unsigned long ltdev);
 static void cops_timeout(struct net_device *dev);
 static void cops_rx (struct net_device *dev);
-static int  cops_send_packet (struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t  cops_send_packet (struct sk_buff *skb,
+					    struct net_device *dev);
 static void set_multicast_list (struct net_device *dev);
 static int  cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 static int  cops_close (struct net_device *dev);
@@ -875,7 +876,8 @@ static void cops_timeout(struct net_device *dev)
  *	Make the card transmit a LocalTalk packet.
  */
 
-static int cops_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t cops_send_packet(struct sk_buff *skb,
+					  struct net_device *dev)
 {
         struct cops_local *lp = netdev_priv(dev);
         int ioaddr = dev->base_addr;
@@ -920,7 +922,7 @@ static int cops_send_packet(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_bytes += skb->len;
 	dev->trans_start = jiffies;
 	dev_kfree_skb (skb);
-        return 0;
+        return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c
index 78cea5e..aaf14d3 100644
--- a/drivers/net/appletalk/ipddp.c
+++ b/drivers/net/appletalk/ipddp.c
@@ -48,7 +48,8 @@ static int ipddp_mode = IPDDP_DECAP;
 #endif
 
 /* Index to functions, as function prototypes. */
-static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ipddp_xmit(struct sk_buff *skb,
+				    struct net_device *dev);
 static int ipddp_create(struct ipddp_route *new_rt);
 static int ipddp_delete(struct ipddp_route *rt);
 static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt);
@@ -113,7 +114,7 @@ static struct net_device * __init ipddp_init(void)
 /*
  * Transmit LLAP/ELAP frame using aarp_send_ddp.
  */
-static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	__be32 paddr = skb_rtable(skb)->rt_gateway;
         struct ddpehdr *ddp;
@@ -132,7 +133,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
         }
         if(rt == NULL) {
 		spin_unlock(&ipddp_route_lock);
-                return 0;
+                return NETDEV_TX_OK;
 	}
 
         our_addr = atalk_find_dev_addr(rt->dev);
@@ -176,12 +177,11 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 
-        if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0)
-                dev_kfree_skb(skb);
+	aarp_send_ddp(rt->dev, skb, &rt->at, NULL);
 
 	spin_unlock(&ipddp_route_lock);
 
-        return 0;
+        return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c
index b642647..08760ba 100644
--- a/drivers/net/appletalk/ltpc.c
+++ b/drivers/net/appletalk/ltpc.c
@@ -697,7 +697,7 @@ static int do_read(struct net_device *dev, void *cbuf, int cbuflen,
 
 static struct timer_list ltpc_timer;
 
-static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev);
 
 static int read_30 ( struct net_device *dev)
 {
@@ -895,7 +895,7 @@ static void ltpc_poll(unsigned long l)
 
 /* DDP to LLAP translation */
 
-static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	/* in kernel 1.3.xx, on entry skb->data points to ddp header,
 	 * and skb->len is the length of the ddp data + ddp header
@@ -932,7 +932,7 @@ static int ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_bytes += skb->len;
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* initialization stuff */
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 7d227cd..75a5725 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -591,7 +591,8 @@ static int arcnet_rebuild_header(struct sk_buff *skb)
 
 
 /* Called by the kernel in order to transmit a packet. */
-int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct arcnet_local *lp = netdev_priv(dev);
 	struct archdr *pkt;
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 58e8d52..c35af3e 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -115,7 +115,8 @@ struct lancedata {
 
 static int ariadne_open(struct net_device *dev);
 static void ariadne_init_ring(struct net_device *dev);
-static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev);
 static void ariadne_tx_timeout(struct net_device *dev);
 static int ariadne_rx(struct net_device *dev);
 static void ariadne_reset(struct net_device *dev);
@@ -589,7 +590,8 @@ static void ariadne_tx_timeout(struct net_device *dev)
 }
 
 
-static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ariadne_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
     struct ariadne_private *priv = netdev_priv(dev);
     volatile struct Am79C960 *lance = (struct Am79C960*)dev->base_addr;
@@ -610,7 +612,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
     if (skb->len < ETH_ZLEN)
     {
     	if (skb_padto(skb, ETH_ZLEN))
-    	    return 0;
+    	    return NETDEV_TX_OK;
     	len = ETH_ZLEN;
     }
 
@@ -685,7 +687,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev)
     }
     local_irq_restore(flags);
 
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 627bc75..164b37e 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -482,7 +482,7 @@ am79c961_sendpacket(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 5041d10..c8bc60a 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -834,7 +834,7 @@ static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
 				we free and return(0) or don't free and return 1 */
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index fbf4645..2be49c8 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -762,7 +762,7 @@ static u32 ep93xx_get_link(struct net_device *dev)
 	return mii_link_ok(&ep->mii);
 }
 
-static struct ethtool_ops ep93xx_ethtool_ops = {
+static const struct ethtool_ops ep93xx_ethtool_ops = {
 	.get_drvinfo		= ep93xx_get_drvinfo,
 	.get_settings		= ep93xx_get_settings,
 	.set_settings		= ep93xx_set_settings,
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c
index edf770f..e47c0d9 100644
--- a/drivers/net/arm/ether1.c
+++ b/drivers/net/arm/ether1.c
@@ -748,7 +748,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 
  out:
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index 4550371..1f7a69c 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -511,7 +511,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 		dev_kfree_skb(skb);
 		priv(dev)->stats.tx_dropped ++;
 		netif_start_queue(dev);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	length = (length + 1) & ~1;
@@ -562,7 +562,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 
  out:
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static irqreturn_t
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 3fe0987..691b81e 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -802,7 +802,7 @@ static int ixp4xx_nway_reset(struct net_device *dev)
 	return phy_start_aneg(port->phydev);
 }
 
-static struct ethtool_ops ixp4xx_ethtool_ops = {
+static const struct ethtool_ops ixp4xx_ethtool_ops = {
 	.get_drvinfo = ixp4xx_get_drvinfo,
 	.get_settings = ixp4xx_get_settings,
 	.set_settings = ixp4xx_set_settings,
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 35cd264..2a7b774 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -467,7 +467,6 @@ ks8695_rx_irq(int irq, void *dev_id)
 			netif_rx(skb);
 
 			/* Record stats */
-			ndev->last_rx = jiffies;
 			ndev->stats.rx_packets++;
 			ndev->stats.rx_bytes += pktlen;
 			goto rx_finished;
@@ -1063,7 +1062,7 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
 		sizeof(info->bus_info));
 }
 
-static struct ethtool_ops ks8695_ethtool_ops = {
+static const struct ethtool_ops ks8695_ethtool_ops = {
 	.get_msglevel	= ks8695_get_msglevel,
 	.set_msglevel	= ks8695_set_msglevel,
 	.get_settings	= ks8695_get_settings,
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c
index ddd231c..25e2627 100644
--- a/drivers/net/arm/w90p910_ether.c
+++ b/drivers/net/arm/w90p910_ether.c
@@ -143,16 +143,17 @@ struct recv_pdesc {
 
 struct tran_pdesc {
 	struct w90p910_txbd desclist[TX_DESC_SIZE];
-	char tran_buf[RX_DESC_SIZE][MAX_TBUFF_SZ];
+	char tran_buf[TX_DESC_SIZE][MAX_TBUFF_SZ];
 };
 
 struct  w90p910_ether {
 	struct recv_pdesc *rdesc;
-	struct recv_pdesc *rdesc_phys;
 	struct tran_pdesc *tdesc;
-	struct tran_pdesc *tdesc_phys;
+	dma_addr_t rdesc_phys;
+	dma_addr_t tdesc_phys;
 	struct net_device_stats stats;
 	struct platform_device *pdev;
+	struct resource *res;
 	struct sk_buff *skb;
 	struct clk *clk;
 	struct clk *rmiiclk;
@@ -169,7 +170,6 @@ struct  w90p910_ether {
 	unsigned int start_tx_ptr;
 	unsigned int start_rx_ptr;
 	unsigned int linkflag;
-	spinlock_t lock;
 };
 
 static void update_linkspeed_register(struct net_device *dev,
@@ -275,59 +275,75 @@ static void w90p910_write_cam(struct net_device *dev,
 	__raw_writel(msw, ether->reg + REG_CAMM_BASE + x * CAM_ENTRY_SIZE);
 }
 
-static void w90p910_init_desc(struct net_device *dev)
+static int w90p910_init_desc(struct net_device *dev)
 {
 	struct w90p910_ether *ether;
-	struct w90p910_txbd  *tdesc, *tdesc_phys;
-	struct w90p910_rxbd  *rdesc, *rdesc_phys;
-	unsigned int i, j;
+	struct w90p910_txbd  *tdesc;
+	struct w90p910_rxbd  *rdesc;
+	struct platform_device *pdev;
+	unsigned int i;
 
 	ether = netdev_priv(dev);
+	pdev = ether->pdev;
 
 	ether->tdesc = (struct tran_pdesc *)
-			dma_alloc_coherent(NULL, sizeof(struct tran_pdesc),
-				(dma_addr_t *) &ether->tdesc_phys, GFP_KERNEL);
+		dma_alloc_coherent(&pdev->dev, sizeof(struct tran_pdesc),
+					&ether->tdesc_phys, GFP_KERNEL);
+
+	if (!ether->tdesc) {
+		dev_err(&pdev->dev, "Failed to allocate memory for tx desc\n");
+		return -ENOMEM;
+	}
 
 	ether->rdesc = (struct recv_pdesc *)
-			dma_alloc_coherent(NULL, sizeof(struct recv_pdesc),
-				(dma_addr_t *) &ether->rdesc_phys, GFP_KERNEL);
+		dma_alloc_coherent(&pdev->dev, sizeof(struct recv_pdesc),
+					&ether->rdesc_phys, GFP_KERNEL);
+
+	if (!ether->rdesc) {
+		dev_err(&pdev->dev, "Failed to allocate memory for rx desc\n");
+		dma_free_coherent(&pdev->dev, sizeof(struct tran_pdesc),
+					ether->tdesc, ether->tdesc_phys);
+		return -ENOMEM;
+	}
 
 	for (i = 0; i < TX_DESC_SIZE; i++) {
-		tdesc = &(ether->tdesc->desclist[i]);
+		unsigned int offset;
 
-		j = ((i + 1) / TX_DESC_SIZE);
+		tdesc = &(ether->tdesc->desclist[i]);
 
-		if (j != 0) {
-			tdesc_phys = &(ether->tdesc_phys->desclist[0]);
-			ether->start_tx_ptr = (unsigned int)tdesc_phys;
-			tdesc->next = (unsigned int)ether->start_tx_ptr;
-		} else {
-			tdesc_phys = &(ether->tdesc_phys->desclist[i+1]);
-			tdesc->next = (unsigned int)tdesc_phys;
-		}
+		if (i == TX_DESC_SIZE - 1)
+			offset = offsetof(struct tran_pdesc, desclist[0]);
+		else
+			offset = offsetof(struct tran_pdesc, desclist[i + 1]);
 
-		tdesc->buffer = (unsigned int)ether->tdesc_phys->tran_buf[i];
+		tdesc->next = ether->tdesc_phys + offset;
+		tdesc->buffer = ether->tdesc_phys +
+			offsetof(struct tran_pdesc, tran_buf[i]);
 		tdesc->sl = 0;
 		tdesc->mode = 0;
 	}
 
+	ether->start_tx_ptr = ether->tdesc_phys;
+
 	for (i = 0; i < RX_DESC_SIZE; i++) {
-		rdesc = &(ether->rdesc->desclist[i]);
+		unsigned int offset;
 
-		j = ((i + 1) / RX_DESC_SIZE);
+		rdesc = &(ether->rdesc->desclist[i]);
 
-		if (j != 0) {
-			rdesc_phys = &(ether->rdesc_phys->desclist[0]);
-			ether->start_rx_ptr = (unsigned int)rdesc_phys;
-			rdesc->next = (unsigned int)ether->start_rx_ptr;
-		} else {
-			rdesc_phys = &(ether->rdesc_phys->desclist[i+1]);
-			rdesc->next = (unsigned int)rdesc_phys;
-		}
+		if (i == RX_DESC_SIZE - 1)
+			offset = offsetof(struct recv_pdesc, desclist[0]);
+		else
+			offset = offsetof(struct recv_pdesc, desclist[i + 1]);
 
+		rdesc->next = ether->rdesc_phys + offset;
 		rdesc->sl = RX_OWEN_DMA;
-		rdesc->buffer = (unsigned int)ether->rdesc_phys->recv_buf[i];
+		rdesc->buffer = ether->rdesc_phys +
+			offsetof(struct recv_pdesc, recv_buf[i]);
 	  }
+
+	ether->start_rx_ptr = ether->rdesc_phys;
+
+	return 0;
 }
 
 static void w90p910_set_fifo_threshold(struct net_device *dev)
@@ -456,8 +472,6 @@ static void w90p910_reset_mac(struct net_device *dev)
 {
 	struct w90p910_ether *ether = netdev_priv(dev);
 
-	spin_lock(&ether->lock);
-
 	w90p910_enable_tx(dev, 0);
 	w90p910_enable_rx(dev, 0);
 	w90p910_set_fifo_threshold(dev);
@@ -486,8 +500,6 @@ static void w90p910_reset_mac(struct net_device *dev)
 
 	if (netif_queue_stopped(dev))
 		netif_wake_queue(dev);
-
-	spin_unlock(&ether->lock);
 }
 
 static void w90p910_mdio_write(struct net_device *dev,
@@ -541,7 +553,7 @@ static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg)
 	return data;
 }
 
-static int set_mac_address(struct net_device *dev, void *addr)
+static int w90p910_set_mac_address(struct net_device *dev, void *addr)
 {
 	struct sockaddr *address = addr;
 
@@ -557,11 +569,14 @@ static int set_mac_address(struct net_device *dev, void *addr)
 static int w90p910_ether_close(struct net_device *dev)
 {
 	struct w90p910_ether *ether = netdev_priv(dev);
+	struct platform_device *pdev;
 
-	dma_free_writecombine(NULL, sizeof(struct w90p910_rxbd),
-				ether->rdesc, (dma_addr_t)ether->rdesc_phys);
-	dma_free_writecombine(NULL, sizeof(struct w90p910_txbd),
-				ether->tdesc, (dma_addr_t)ether->tdesc_phys);
+	pdev = ether->pdev;
+
+	dma_free_coherent(&pdev->dev, sizeof(struct recv_pdesc),
+					ether->rdesc, ether->rdesc_phys);
+	dma_free_coherent(&pdev->dev, sizeof(struct tran_pdesc),
+					ether->tdesc, ether->tdesc_phys);
 
 	netif_stop_queue(dev);
 
@@ -597,6 +612,7 @@ static int w90p910_send_frame(struct net_device *dev,
 
 	txbd = &ether->tdesc->desclist[ether->cur_tx];
 	buffer = ether->tdesc->tran_buf[ether->cur_tx];
+
 	if (length > 1514) {
 		dev_err(&pdev->dev, "send data %d bytes, check it\n", length);
 		length = 1514;
@@ -612,7 +628,9 @@ static int w90p910_send_frame(struct net_device *dev,
 
 	w90p910_trigger_tx(dev);
 
-	ether->cur_tx = (ether->cur_tx+1) % TX_DESC_SIZE;
+	if (++ether->cur_tx >= TX_DESC_SIZE)
+		ether->cur_tx = 0;
+
 	txbd = &ether->tdesc->desclist[ether->cur_tx];
 
 	dev->trans_start = jiffies;
@@ -632,7 +650,7 @@ static int w90p910_ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		dev_kfree_skb_irq(skb);
 		return 0;
 	}
-	return -1;
+	return -EAGAIN;
 }
 
 static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)
@@ -640,27 +658,25 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)
 	struct w90p910_ether *ether;
 	struct w90p910_txbd  *txbd;
 	struct platform_device *pdev;
-	struct tran_pdesc *tran_pdesc;
 	struct net_device *dev;
 	unsigned int cur_entry, entry, status;
 
-	dev = (struct net_device *)dev_id;
+	dev = dev_id;
 	ether = netdev_priv(dev);
 	pdev = ether->pdev;
 
-	spin_lock(&ether->lock);
-
 	w90p910_get_and_clear_int(dev, &status);
 
 	cur_entry = __raw_readl(ether->reg + REG_CTXDSA);
 
-	tran_pdesc = ether->tdesc_phys;
-	entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]);
+	entry = ether->tdesc_phys +
+		offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
 
 	while (entry != cur_entry) {
 		txbd = &ether->tdesc->desclist[ether->finish_tx];
 
-		ether->finish_tx = (ether->finish_tx + 1) % TX_DESC_SIZE;
+		if (++ether->finish_tx >= TX_DESC_SIZE)
+			ether->finish_tx = 0;
 
 		if (txbd->sl & TXDS_TXCP) {
 			ether->stats.tx_packets++;
@@ -675,20 +691,19 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)
 		if (netif_queue_stopped(dev))
 			netif_wake_queue(dev);
 
-		entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]);
+		entry = ether->tdesc_phys +
+			offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
 	}
 
 	if (status & MISTA_EXDEF) {
 		dev_err(&pdev->dev, "emc defer exceed interrupt\n");
 	} else if (status & MISTA_TXBERR) {
-			dev_err(&pdev->dev, "emc bus error interrupt\n");
-			w90p910_reset_mac(dev);
-		} else if (status & MISTA_TDU) {
-				if (netif_queue_stopped(dev))
-					netif_wake_queue(dev);
-			}
-
-	spin_unlock(&ether->lock);
+		dev_err(&pdev->dev, "emc bus error interrupt\n");
+		w90p910_reset_mac(dev);
+	} else if (status & MISTA_TDU) {
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -698,20 +713,20 @@ static void netdev_rx(struct net_device *dev)
 	struct w90p910_ether *ether;
 	struct w90p910_rxbd *rxbd;
 	struct platform_device *pdev;
-	struct recv_pdesc *rdesc_phys;
 	struct sk_buff *skb;
 	unsigned char *data;
 	unsigned int length, status, val, entry;
 
 	ether = netdev_priv(dev);
 	pdev = ether->pdev;
-	rdesc_phys = ether->rdesc_phys;
 
 	rxbd = &ether->rdesc->desclist[ether->cur_rx];
 
 	do {
 		val = __raw_readl(ether->reg + REG_CRXDSA);
-		entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx];
+
+		entry = ether->rdesc_phys +
+			offsetof(struct recv_pdesc, desclist[ether->cur_rx]);
 
 		if (val == entry)
 			break;
@@ -743,25 +758,25 @@ static void netdev_rx(struct net_device *dev)
 				dev_err(&pdev->dev, "rx runt err\n");
 				ether->stats.rx_length_errors++;
 			} else if (status & RXDS_CRCE) {
-					dev_err(&pdev->dev, "rx crc err\n");
-					ether->stats.rx_crc_errors++;
-				}
-
-			if (status & RXDS_ALIE) {
+				dev_err(&pdev->dev, "rx crc err\n");
+				ether->stats.rx_crc_errors++;
+			} else if (status & RXDS_ALIE) {
 				dev_err(&pdev->dev, "rx aligment err\n");
 				ether->stats.rx_frame_errors++;
 			} else if (status & RXDS_PTLE) {
-					dev_err(&pdev->dev, "rx longer err\n");
-					ether->stats.rx_over_errors++;
-				}
+				dev_err(&pdev->dev, "rx longer err\n");
+				ether->stats.rx_over_errors++;
 			}
+		}
 
 		rxbd->sl = RX_OWEN_DMA;
 		rxbd->reserved = 0x0;
-		ether->cur_rx = (ether->cur_rx+1) % RX_DESC_SIZE;
+
+		if (++ether->cur_rx >= RX_DESC_SIZE)
+			ether->cur_rx = 0;
+
 		rxbd = &ether->rdesc->desclist[ether->cur_rx];
 
-		dev->last_rx = jiffies;
 	} while (1);
 }
 
@@ -772,28 +787,23 @@ static irqreturn_t w90p910_rx_interrupt(int irq, void *dev_id)
 	struct platform_device *pdev;
 	unsigned int status;
 
-	dev = (struct net_device *)dev_id;
+	dev = dev_id;
 	ether = netdev_priv(dev);
 	pdev = ether->pdev;
 
-	spin_lock(&ether->lock);
-
 	w90p910_get_and_clear_int(dev, &status);
 
 	if (status & MISTA_RDU) {
 		netdev_rx(dev);
-
 		w90p910_trigger_rx(dev);
 
-		spin_unlock(&ether->lock);
 		return IRQ_HANDLED;
 	} else if (status & MISTA_RXBERR) {
-			dev_err(&pdev->dev, "emc rx bus error\n");
-			w90p910_reset_mac(dev);
-		}
+		dev_err(&pdev->dev, "emc rx bus error\n");
+		w90p910_reset_mac(dev);
+	}
 
 	netdev_rx(dev);
-	spin_unlock(&ether->lock);
 	return IRQ_HANDLED;
 }
 
@@ -826,6 +836,7 @@ static int w90p910_ether_open(struct net_device *dev)
 	if (request_irq(ether->rxirq, w90p910_rx_interrupt,
 						0x0, pdev->name, dev)) {
 		dev_err(&pdev->dev, "register irq rx failed\n");
+		free_irq(ether->txirq, dev);
 		return -EAGAIN;
 	}
 
@@ -908,7 +919,7 @@ static const struct net_device_ops w90p910_ether_netdev_ops = {
 	.ndo_start_xmit		= w90p910_ether_start_xmit,
 	.ndo_get_stats		= w90p910_ether_stats,
 	.ndo_set_multicast_list	= w90p910_ether_set_multicast_list,
-	.ndo_set_mac_address	= set_mac_address,
+	.ndo_set_mac_address	= w90p910_set_mac_address,
 	.ndo_do_ioctl		= w90p910_ether_ioctl,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= eth_change_mtu,
@@ -949,8 +960,6 @@ static int w90p910_ether_setup(struct net_device *dev)
 
 	get_mac_address(dev);
 
-	spin_lock_init(&ether->lock);
-
 	ether->cur_tx = 0x0;
 	ether->cur_rx = 0x0;
 	ether->finish_tx = 0x0;
@@ -972,30 +981,29 @@ static int __devinit w90p910_ether_probe(struct platform_device *pdev)
 {
 	struct w90p910_ether *ether;
 	struct net_device *dev;
-	struct resource *res;
 	int error;
 
 	dev = alloc_etherdev(sizeof(struct w90p910_ether));
 	if (!dev)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
+	ether = netdev_priv(dev);
+
+	ether->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (ether->res == NULL) {
 		dev_err(&pdev->dev, "failed to get I/O memory\n");
 		error = -ENXIO;
 		goto failed_free;
 	}
 
-	res = request_mem_region(res->start, resource_size(res), pdev->name);
-	if (res == NULL) {
+	if (!request_mem_region(ether->res->start,
+				resource_size(ether->res), pdev->name)) {
 		dev_err(&pdev->dev, "failed to request I/O memory\n");
 		error = -EBUSY;
 		goto failed_free;
 	}
 
-	ether = netdev_priv(dev);
-
-	ether->reg = ioremap(res->start, resource_size(res));
+	ether->reg = ioremap(ether->res->start, resource_size(ether->res));
 	if (ether->reg == NULL) {
 		dev_err(&pdev->dev, "failed to remap I/O memory\n");
 		error = -ENXIO;
@@ -1056,7 +1064,7 @@ failed_free_txirq:
 failed_free_io:
 	iounmap(ether->reg);
 failed_free_mem:
-	release_mem_region(res->start, resource_size(res));
+	release_mem_region(ether->res->start, resource_size(ether->res));
 failed_free:
 	free_netdev(dev);
 	return error;
@@ -1068,10 +1076,19 @@ static int __devexit w90p910_ether_remove(struct platform_device *pdev)
 	struct w90p910_ether *ether = netdev_priv(dev);
 
 	unregister_netdev(dev);
+
 	clk_put(ether->rmiiclk);
 	clk_put(ether->clk);
+
+	iounmap(ether->reg);
+	release_mem_region(ether->res->start, resource_size(ether->res));
+
+	free_irq(ether->txirq, dev);
+	free_irq(ether->rxirq, dev);
+
 	del_timer_sync(&ether->check_timer);
 	platform_set_drvdata(pdev, NULL);
+
 	free_netdev(dev);
 	return 0;
 }
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index cf30e27..544d5af 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -159,7 +159,8 @@ struct net_local {
 static int at1700_probe1(struct net_device *dev, int ioaddr);
 static int read_eeprom(long ioaddr, int location);
 static int net_open(struct net_device *dev);
-static int	net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t net_send_packet(struct sk_buff *skb,
+				   struct net_device *dev);
 static irqreturn_t net_interrupt(int irq, void *dev_id);
 static void net_rx(struct net_device *dev);
 static int net_close(struct net_device *dev);
@@ -595,7 +596,8 @@ static void net_tx_timeout (struct net_device *dev)
 }
 
 
-static int net_send_packet (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t net_send_packet (struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
@@ -643,7 +645,7 @@ static int net_send_packet (struct sk_buff *skb, struct net_device *dev)
 		netif_start_queue (dev);
 	dev_kfree_skb (skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The typical workload of the driver:
diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c
index 5425ab0..0c0dece 100644
--- a/drivers/net/atarilance.c
+++ b/drivers/net/atarilance.c
@@ -796,7 +796,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
 	if (len > skb->len) {
 		if (skb_padto(skb, len))
-			return 0;
+			return NETDEV_TX_OK;
 	}
 
 	netif_stop_queue (dev);
@@ -846,7 +846,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 		lp->tx_full = 1;
 	spin_unlock_irqrestore (&lp->devlock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The LANCE interrupt handler. */
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c
index 00d11b4..9b1e0ea 100644
--- a/drivers/net/atl1c/atl1c_ethtool.c
+++ b/drivers/net/atl1c/atl1c_ethtool.c
@@ -294,7 +294,7 @@ static int atl1c_nway_reset(struct net_device *netdev)
 	return 0;
 }
 
-static struct ethtool_ops atl1c_ethtool_ops = {
+static const struct ethtool_ops atl1c_ethtool_ops = {
 	.get_settings           = atl1c_get_settings,
 	.set_settings           = atl1c_set_settings,
 	.get_drvinfo            = atl1c_get_drvinfo,
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c
index a383122..be2c6cf 100644
--- a/drivers/net/atl1c/atl1c_main.c
+++ b/drivers/net/atl1c/atl1c_main.c
@@ -534,10 +534,6 @@ static int atl1c_mii_ioctl(struct net_device *netdev,
 		break;
 
 	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN)) {
-			retval = -EPERM;
-			goto out;
-		}
 		if (atl1c_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
 				    &data->val_out)) {
 			retval = -EIO;
@@ -546,10 +542,6 @@ static int atl1c_mii_ioctl(struct net_device *netdev,
 		break;
 
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN)) {
-			retval = -EPERM;
-			goto out;
-		}
 		if (data->reg_num & ~(0x1F)) {
 			retval = -EFAULT;
 			goto out;
@@ -1740,7 +1732,6 @@ rrs_checked:
 		} else
 			netif_receive_skb(skb);
 
-		netdev->last_rx = jiffies;
 		(*work_done)++;
 		count++;
 	}
@@ -2055,7 +2046,8 @@ static void atl1c_tx_queue(struct atl1c_adapter *adapter, struct sk_buff *skb,
 	AT_WRITE_REG(&adapter->hw, REG_MB_PRIO_PROD_IDX, prod_data);
 }
 
-static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
+					  struct net_device *netdev)
 {
 	struct atl1c_adapter *adapter = netdev_priv(netdev);
 	unsigned long flags;
@@ -2678,6 +2670,9 @@ static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev,
 
 	netif_device_detach(netdev);
 
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	if (netif_running(netdev))
 		atl1c_down(adapter);
 
diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
index ba48220..490d3b3 100644
--- a/drivers/net/atl1e/atl1e.h
+++ b/drivers/net/atl1e/atl1e.h
@@ -377,10 +377,19 @@ struct atl1e_hw {
  */
 struct atl1e_tx_buffer {
 	struct sk_buff *skb;
+	u16 flags;
+#define ATL1E_TX_PCIMAP_SINGLE		0x0001
+#define ATL1E_TX_PCIMAP_PAGE		0x0002
+#define ATL1E_TX_PCIMAP_TYPE_MASK	0x0003
 	u16 length;
 	dma_addr_t dma;
 };
 
+#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do {		\
+	((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK;	\
+	((tx_buff)->flags) |= (type);				\
+	} while (0)
+
 struct atl1e_rx_page {
 	dma_addr_t	dma;    /* receive rage DMA address */
 	u8		*addr;   /* receive rage virtual address */
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index 4003955..60edb9f 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -378,7 +378,7 @@ static int atl1e_nway_reset(struct net_device *netdev)
 	return 0;
 }
 
-static struct ethtool_ops atl1e_ethtool_ops = {
+static const struct ethtool_ops atl1e_ethtool_ops = {
 	.get_settings           = atl1e_get_settings,
 	.set_settings           = atl1e_set_settings,
 	.get_drvinfo            = atl1e_get_drvinfo,
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 9fc6d6d..955da73 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -453,10 +453,6 @@ static int atl1e_mii_ioctl(struct net_device *netdev,
 		break;
 
 	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN)) {
-			retval = -EPERM;
-			goto out;
-		}
 		if (atl1e_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
 				    &data->val_out)) {
 			retval = -EIO;
@@ -465,10 +461,6 @@ static int atl1e_mii_ioctl(struct net_device *netdev,
 		break;
 
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN)) {
-			retval = -EPERM;
-			goto out;
-		}
 		if (data->reg_num & ~(0x1F)) {
 			retval = -EFAULT;
 			goto out;
@@ -643,7 +635,11 @@ static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
 	for (index = 0; index < ring_count; index++) {
 		tx_buffer = &tx_ring->tx_buffer[index];
 		if (tx_buffer->dma) {
-			pci_unmap_page(pdev, tx_buffer->dma,
+			if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+				pci_unmap_single(pdev, tx_buffer->dma,
+					tx_buffer->length, PCI_DMA_TODEVICE);
+			else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+				pci_unmap_page(pdev, tx_buffer->dma,
 					tx_buffer->length, PCI_DMA_TODEVICE);
 			tx_buffer->dma = 0;
 		}
@@ -1228,7 +1224,11 @@ static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
 	while (next_to_clean != hw_next_to_clean) {
 		tx_buffer = &tx_ring->tx_buffer[next_to_clean];
 		if (tx_buffer->dma) {
-			pci_unmap_page(adapter->pdev, tx_buffer->dma,
+			if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+				pci_unmap_single(adapter->pdev, tx_buffer->dma,
+					tx_buffer->length, PCI_DMA_TODEVICE);
+			else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+				pci_unmap_page(adapter->pdev, tx_buffer->dma,
 					tx_buffer->length, PCI_DMA_TODEVICE);
 			tx_buffer->dma = 0;
 		}
@@ -1749,6 +1749,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
 		tx_buffer->length = map_len;
 		tx_buffer->dma = pci_map_single(adapter->pdev,
 					skb->data, hdr_len, PCI_DMA_TODEVICE);
+		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 		use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1774,6 +1775,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
 		tx_buffer->dma =
 			pci_map_single(adapter->pdev, skb->data + mapped_len,
 					map_len, PCI_DMA_TODEVICE);
+		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len  += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 		use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1809,6 +1811,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
 						(i * MAX_TX_BUF_LEN),
 						tx_buffer->length,
 						PCI_DMA_TODEVICE);
+			ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
 			use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 			use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
 					((cpu_to_le32(tx_buffer->length) &
@@ -1839,7 +1842,8 @@ static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count,
 	AT_WRITE_REG(&adapter->hw, REG_MB_TPD_PROD_IDX, tx_ring->next_to_use);
 }
 
-static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb,
+					  struct net_device *netdev)
 {
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
 	unsigned long flags;
@@ -2497,6 +2501,9 @@ atl1e_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
 
 	netif_device_detach(netdev);
 
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	if (netif_running(netdev))
 		atl1e_down(adapter);
 
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 8bca12f..00569dc 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2349,7 +2349,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
 	atomic_set(&tpd_ring->next_to_use, next_to_use);
 }
 
-static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
+					 struct net_device *netdev)
 {
 	struct atl1_adapter *adapter = netdev_priv(netdev);
 	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index 204db96..ab68886 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -821,7 +821,8 @@ static inline int TxdFreeBytes(struct atl2_adapter *adapter)
 		(int) (txd_read_ptr - adapter->txd_write_ptr - 1);
 }
 
-static int atl2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb,
+					 struct net_device *netdev)
 {
 	struct atl2_adapter *adapter = netdev_priv(netdev);
 	struct tx_pkt_header *txph;
@@ -965,8 +966,6 @@ static int atl2_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 		data->phy_id = 0;
 		break;
 	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		spin_lock_irqsave(&adapter->stats_lock, flags);
 		if (atl2_read_phy_reg(&adapter->hw,
 			data->reg_num & 0x1F, &data->val_out)) {
@@ -976,8 +975,6 @@ static int atl2_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 		spin_unlock_irqrestore(&adapter->stats_lock, flags);
 		break;
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if (data->reg_num & ~(0x1F))
 			return -EFAULT;
 		spin_lock_irqsave(&adapter->stats_lock, flags);
@@ -2093,7 +2090,7 @@ static int atl2_nway_reset(struct net_device *netdev)
 	return 0;
 }
 
-static struct ethtool_ops atl2_ethtool_ops = {
+static const struct ethtool_ops atl2_ethtool_ops = {
 	.get_settings		= atl2_get_settings,
 	.set_settings		= atl2_set_settings,
 	.get_drvinfo		= atl2_get_drvinfo,
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index 4317b3e..9043294 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -199,7 +199,8 @@ static int net_open(struct net_device *dev);
 static void hardware_init(struct net_device *dev);
 static void write_packet(long ioaddr, int length, unsigned char *packet, int pad, int mode);
 static void trigger_send(long ioaddr, int length);
-static int	atp_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t atp_send_packet(struct sk_buff *skb,
+				   struct net_device *dev);
 static irqreturn_t atp_interrupt(int irq, void *dev_id);
 static void net_rx(struct net_device *dev);
 static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode);
@@ -552,7 +553,8 @@ static void tx_timeout(struct net_device *dev)
 	dev->stats.tx_errors++;
 }
 
-static int atp_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t atp_send_packet(struct sk_buff *skb,
+				   struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
@@ -587,7 +589,7 @@ static int atp_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 	dev_kfree_skb (skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index d3c734f..fdf5937 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -937,7 +937,7 @@ static int au1000_close(struct net_device *dev)
 /*
  * Au1000 transmit routine.
  */
-static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct au1000_private *aup = netdev_priv(dev);
 	struct net_device_stats *ps = &dev->stats;
@@ -988,7 +988,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb(skb);
 	aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -1157,6 +1157,9 @@ static struct net_device * au1000_probe(int port_num)
 	aup->mii_bus->name = "au1000_eth_mii";
 	snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id);
 	aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+	if (aup->mii_bus->irq == NULL)
+		goto err_out;
+
 	for(i = 0; i < PHY_MAX_ADDR; ++i)
 		aup->mii_bus->irq[i] = PHY_POLL;
 
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index bafca67..e046943 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -847,23 +847,22 @@ static int b44_poll(struct napi_struct *napi, int budget)
 {
 	struct b44 *bp = container_of(napi, struct b44, napi);
 	int work_done;
+	unsigned long flags;
 
-	spin_lock_irq(&bp->lock);
+	spin_lock_irqsave(&bp->lock, flags);
 
 	if (bp->istat & (ISTAT_TX | ISTAT_TO)) {
 		/* spin_lock(&bp->tx_lock); */
 		b44_tx(bp);
 		/* spin_unlock(&bp->tx_lock); */
 	}
-	spin_unlock_irq(&bp->lock);
+	spin_unlock_irqrestore(&bp->lock, flags);
 
 	work_done = 0;
 	if (bp->istat & ISTAT_RX)
 		work_done += b44_rx(bp, budget);
 
 	if (bp->istat & ISTAT_ERRORS) {
-		unsigned long flags;
-
 		spin_lock_irqsave(&bp->lock, flags);
 		b44_halt(bp);
 		b44_init_rings(bp);
@@ -946,7 +945,7 @@ static void b44_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct b44 *bp = netdev_priv(dev);
 	int rc = NETDEV_TX_OK;
@@ -1298,14 +1297,18 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
 	switch (sdev->bus->bustype) {
 	case SSB_BUSTYPE_SSB:
 		bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
-		     (((ssb_clockspeed(sdev->bus) + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
+		     (DIV_ROUND_CLOSEST(ssb_clockspeed(sdev->bus),
+					B44_MDC_RATIO)
 		     & MDIO_CTRL_MAXF_MASK)));
 		break;
 	case SSB_BUSTYPE_PCI:
-	case SSB_BUSTYPE_PCMCIA:
 		bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
 		     (0x0d & MDIO_CTRL_MAXF_MASK)));
 		break;
+	case SSB_BUSTYPE_PCMCIA:
+	case SSB_BUSTYPE_SDIO:
+		WARN_ON(1); /* A device with this bus does not exist. */
+		break;
 	}
 
 	br32(bp, B44_MDIO_CTRL);
@@ -1757,15 +1760,18 @@ static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *inf
 	struct b44 *bp = netdev_priv(dev);
 	struct ssb_bus *bus = bp->sdev->bus;
 
-	strncpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
-	strncpy(info->version, DRV_MODULE_VERSION, sizeof(info->driver));
+	strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
+	strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
 	switch (bus->bustype) {
 	case SSB_BUSTYPE_PCI:
-		strncpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info));
+		strlcpy(info->bus_info, pci_name(bus->host_pci), sizeof(info->bus_info));
 		break;
-	case SSB_BUSTYPE_PCMCIA:
 	case SSB_BUSTYPE_SSB:
-		strncpy(info->bus_info, "SSB", sizeof(info->bus_info));
+		strlcpy(info->bus_info, "SSB", sizeof(info->bus_info));
+		break;
+	case SSB_BUSTYPE_PCMCIA:
+	case SSB_BUSTYPE_SDIO:
+		WARN_ON(1); /* A device with this bus does not exist. */
 		break;
 	}
 }
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
new file mode 100644
index 0000000..09d2709
--- /dev/null
+++ b/drivers/net/bcm63xx_enet.c
@@ -0,0 +1,1971 @@
+/*
+ * Driver for BCM963xx builtin Ethernet mac
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.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.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/if_vlan.h>
+
+#include <bcm63xx_dev_enet.h>
+#include "bcm63xx_enet.h"
+
+static char bcm_enet_driver_name[] = "bcm63xx_enet";
+static char bcm_enet_driver_version[] = "1.0";
+
+static int copybreak __read_mostly = 128;
+module_param(copybreak, int, 0);
+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+
+/* io memory shared between all devices */
+static void __iomem *bcm_enet_shared_base;
+
+/*
+ * io helpers to access mac registers
+ */
+static inline u32 enet_readl(struct bcm_enet_priv *priv, u32 off)
+{
+	return bcm_readl(priv->base + off);
+}
+
+static inline void enet_writel(struct bcm_enet_priv *priv,
+			       u32 val, u32 off)
+{
+	bcm_writel(val, priv->base + off);
+}
+
+/*
+ * io helpers to access shared registers
+ */
+static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off)
+{
+	return bcm_readl(bcm_enet_shared_base + off);
+}
+
+static inline void enet_dma_writel(struct bcm_enet_priv *priv,
+				       u32 val, u32 off)
+{
+	bcm_writel(val, bcm_enet_shared_base + off);
+}
+
+/*
+ * write given data into mii register and wait for transfer to end
+ * with timeout (average measured transfer time is 25us)
+ */
+static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data)
+{
+	int limit;
+
+	/* make sure mii interrupt status is cleared */
+	enet_writel(priv, ENET_IR_MII, ENET_IR_REG);
+
+	enet_writel(priv, data, ENET_MIIDATA_REG);
+	wmb();
+
+	/* busy wait on mii interrupt bit, with timeout */
+	limit = 1000;
+	do {
+		if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
+			break;
+		udelay(1);
+	} while (limit-- >= 0);
+
+	return (limit < 0) ? 1 : 0;
+}
+
+/*
+ * MII internal read callback
+ */
+static int bcm_enet_mdio_read(struct bcm_enet_priv *priv, int mii_id,
+			      int regnum)
+{
+	u32 tmp, val;
+
+	tmp = regnum << ENET_MIIDATA_REG_SHIFT;
+	tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+	tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+	tmp |= ENET_MIIDATA_OP_READ_MASK;
+
+	if (do_mdio_op(priv, tmp))
+		return -1;
+
+	val = enet_readl(priv, ENET_MIIDATA_REG);
+	val &= 0xffff;
+	return val;
+}
+
+/*
+ * MII internal write callback
+ */
+static int bcm_enet_mdio_write(struct bcm_enet_priv *priv, int mii_id,
+			       int regnum, u16 value)
+{
+	u32 tmp;
+
+	tmp = (value & 0xffff) << ENET_MIIDATA_DATA_SHIFT;
+	tmp |= 0x2 << ENET_MIIDATA_TA_SHIFT;
+	tmp |= regnum << ENET_MIIDATA_REG_SHIFT;
+	tmp |= mii_id << ENET_MIIDATA_PHYID_SHIFT;
+	tmp |= ENET_MIIDATA_OP_WRITE_MASK;
+
+	(void)do_mdio_op(priv, tmp);
+	return 0;
+}
+
+/*
+ * MII read callback from phylib
+ */
+static int bcm_enet_mdio_read_phylib(struct mii_bus *bus, int mii_id,
+				     int regnum)
+{
+	return bcm_enet_mdio_read(bus->priv, mii_id, regnum);
+}
+
+/*
+ * MII write callback from phylib
+ */
+static int bcm_enet_mdio_write_phylib(struct mii_bus *bus, int mii_id,
+				      int regnum, u16 value)
+{
+	return bcm_enet_mdio_write(bus->priv, mii_id, regnum, value);
+}
+
+/*
+ * MII read callback from mii core
+ */
+static int bcm_enet_mdio_read_mii(struct net_device *dev, int mii_id,
+				  int regnum)
+{
+	return bcm_enet_mdio_read(netdev_priv(dev), mii_id, regnum);
+}
+
+/*
+ * MII write callback from mii core
+ */
+static void bcm_enet_mdio_write_mii(struct net_device *dev, int mii_id,
+				    int regnum, int value)
+{
+	bcm_enet_mdio_write(netdev_priv(dev), mii_id, regnum, value);
+}
+
+/*
+ * refill rx queue
+ */
+static int bcm_enet_refill_rx(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+
+	while (priv->rx_desc_count < priv->rx_ring_size) {
+		struct bcm_enet_desc *desc;
+		struct sk_buff *skb;
+		dma_addr_t p;
+		int desc_idx;
+		u32 len_stat;
+
+		desc_idx = priv->rx_dirty_desc;
+		desc = &priv->rx_desc_cpu[desc_idx];
+
+		if (!priv->rx_skb[desc_idx]) {
+			skb = netdev_alloc_skb(dev, priv->rx_skb_size);
+			if (!skb)
+				break;
+			priv->rx_skb[desc_idx] = skb;
+
+			p = dma_map_single(&priv->pdev->dev, skb->data,
+					   priv->rx_skb_size,
+					   DMA_FROM_DEVICE);
+			desc->address = p;
+		}
+
+		len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
+		len_stat |= DMADESC_OWNER_MASK;
+		if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
+			len_stat |= DMADESC_WRAP_MASK;
+			priv->rx_dirty_desc = 0;
+		} else {
+			priv->rx_dirty_desc++;
+		}
+		wmb();
+		desc->len_stat = len_stat;
+
+		priv->rx_desc_count++;
+
+		/* tell dma engine we allocated one buffer */
+		enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+	}
+
+	/* If rx ring is still empty, set a timer to try allocating
+	 * again at a later time. */
+	if (priv->rx_desc_count == 0 && netif_running(dev)) {
+		dev_warn(&priv->pdev->dev, "unable to refill rx ring\n");
+		priv->rx_timeout.expires = jiffies + HZ;
+		add_timer(&priv->rx_timeout);
+	}
+
+	return 0;
+}
+
+/*
+ * timer callback to defer refill rx queue in case we're OOM
+ */
+static void bcm_enet_refill_rx_timer(unsigned long data)
+{
+	struct net_device *dev;
+	struct bcm_enet_priv *priv;
+
+	dev = (struct net_device *)data;
+	priv = netdev_priv(dev);
+
+	spin_lock(&priv->rx_lock);
+	bcm_enet_refill_rx((struct net_device *)data);
+	spin_unlock(&priv->rx_lock);
+}
+
+/*
+ * extract packet from rx queue
+ */
+static int bcm_enet_receive_queue(struct net_device *dev, int budget)
+{
+	struct bcm_enet_priv *priv;
+	struct device *kdev;
+	int processed;
+
+	priv = netdev_priv(dev);
+	kdev = &priv->pdev->dev;
+	processed = 0;
+
+	/* don't scan ring further than number of refilled
+	 * descriptor */
+	if (budget > priv->rx_desc_count)
+		budget = priv->rx_desc_count;
+
+	do {
+		struct bcm_enet_desc *desc;
+		struct sk_buff *skb;
+		int desc_idx;
+		u32 len_stat;
+		unsigned int len;
+
+		desc_idx = priv->rx_curr_desc;
+		desc = &priv->rx_desc_cpu[desc_idx];
+
+		/* make sure we actually read the descriptor status at
+		 * each loop */
+		rmb();
+
+		len_stat = desc->len_stat;
+
+		/* break if dma ownership belongs to hw */
+		if (len_stat & DMADESC_OWNER_MASK)
+			break;
+
+		processed++;
+		priv->rx_curr_desc++;
+		if (priv->rx_curr_desc == priv->rx_ring_size)
+			priv->rx_curr_desc = 0;
+		priv->rx_desc_count--;
+
+		/* if the packet does not have start of packet _and_
+		 * end of packet flag set, then just recycle it */
+		if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) {
+			priv->stats.rx_dropped++;
+			continue;
+		}
+
+		/* recycle packet if it's marked as bad */
+		if (unlikely(len_stat & DMADESC_ERR_MASK)) {
+			priv->stats.rx_errors++;
+
+			if (len_stat & DMADESC_OVSIZE_MASK)
+				priv->stats.rx_length_errors++;
+			if (len_stat & DMADESC_CRC_MASK)
+				priv->stats.rx_crc_errors++;
+			if (len_stat & DMADESC_UNDER_MASK)
+				priv->stats.rx_frame_errors++;
+			if (len_stat & DMADESC_OV_MASK)
+				priv->stats.rx_fifo_errors++;
+			continue;
+		}
+
+		/* valid packet */
+		skb = priv->rx_skb[desc_idx];
+		len = (len_stat & DMADESC_LENGTH_MASK) >> DMADESC_LENGTH_SHIFT;
+		/* don't include FCS */
+		len -= 4;
+
+		if (len < copybreak) {
+			struct sk_buff *nskb;
+
+			nskb = netdev_alloc_skb(dev, len + NET_IP_ALIGN);
+			if (!nskb) {
+				/* forget packet, just rearm desc */
+				priv->stats.rx_dropped++;
+				continue;
+			}
+
+			/* since we're copying the data, we can align
+			 * them properly */
+			skb_reserve(nskb, NET_IP_ALIGN);
+			dma_sync_single_for_cpu(kdev, desc->address,
+						len, DMA_FROM_DEVICE);
+			memcpy(nskb->data, skb->data, len);
+			dma_sync_single_for_device(kdev, desc->address,
+						   len, DMA_FROM_DEVICE);
+			skb = nskb;
+		} else {
+			dma_unmap_single(&priv->pdev->dev, desc->address,
+					 priv->rx_skb_size, DMA_FROM_DEVICE);
+			priv->rx_skb[desc_idx] = NULL;
+		}
+
+		skb_put(skb, len);
+		skb->dev = dev;
+		skb->protocol = eth_type_trans(skb, dev);
+		priv->stats.rx_packets++;
+		priv->stats.rx_bytes += len;
+		dev->last_rx = jiffies;
+		netif_receive_skb(skb);
+
+	} while (--budget > 0);
+
+	if (processed || !priv->rx_desc_count) {
+		bcm_enet_refill_rx(dev);
+
+		/* kick rx dma */
+		enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+				ENETDMA_CHANCFG_REG(priv->rx_chan));
+	}
+
+	return processed;
+}
+
+
+/*
+ * try to or force reclaim of transmitted buffers
+ */
+static int bcm_enet_tx_reclaim(struct net_device *dev, int force)
+{
+	struct bcm_enet_priv *priv;
+	int released;
+
+	priv = netdev_priv(dev);
+	released = 0;
+
+	while (priv->tx_desc_count < priv->tx_ring_size) {
+		struct bcm_enet_desc *desc;
+		struct sk_buff *skb;
+
+		/* We run in a bh and fight against start_xmit, which
+		 * is called with bh disabled  */
+		spin_lock(&priv->tx_lock);
+
+		desc = &priv->tx_desc_cpu[priv->tx_dirty_desc];
+
+		if (!force && (desc->len_stat & DMADESC_OWNER_MASK)) {
+			spin_unlock(&priv->tx_lock);
+			break;
+		}
+
+		/* ensure other field of the descriptor were not read
+		 * before we checked ownership */
+		rmb();
+
+		skb = priv->tx_skb[priv->tx_dirty_desc];
+		priv->tx_skb[priv->tx_dirty_desc] = NULL;
+		dma_unmap_single(&priv->pdev->dev, desc->address, skb->len,
+				 DMA_TO_DEVICE);
+
+		priv->tx_dirty_desc++;
+		if (priv->tx_dirty_desc == priv->tx_ring_size)
+			priv->tx_dirty_desc = 0;
+		priv->tx_desc_count++;
+
+		spin_unlock(&priv->tx_lock);
+
+		if (desc->len_stat & DMADESC_UNDER_MASK)
+			priv->stats.tx_errors++;
+
+		dev_kfree_skb(skb);
+		released++;
+	}
+
+	if (netif_queue_stopped(dev) && released)
+		netif_wake_queue(dev);
+
+	return released;
+}
+
+/*
+ * poll func, called by network core
+ */
+static int bcm_enet_poll(struct napi_struct *napi, int budget)
+{
+	struct bcm_enet_priv *priv;
+	struct net_device *dev;
+	int tx_work_done, rx_work_done;
+
+	priv = container_of(napi, struct bcm_enet_priv, napi);
+	dev = priv->net_dev;
+
+	/* ack interrupts */
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IR_REG(priv->rx_chan));
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IR_REG(priv->tx_chan));
+
+	/* reclaim sent skb */
+	tx_work_done = bcm_enet_tx_reclaim(dev, 0);
+
+	spin_lock(&priv->rx_lock);
+	rx_work_done = bcm_enet_receive_queue(dev, budget);
+	spin_unlock(&priv->rx_lock);
+
+	if (rx_work_done >= budget || tx_work_done > 0) {
+		/* rx/tx queue is not yet empty/clean */
+		return rx_work_done;
+	}
+
+	/* no more packet in rx/tx queue, remove device from poll
+	 * queue */
+	napi_complete(napi);
+
+	/* restore rx/tx interrupt */
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IRMASK_REG(priv->rx_chan));
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IRMASK_REG(priv->tx_chan));
+
+	return rx_work_done;
+}
+
+/*
+ * mac interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_mac(int irq, void *dev_id)
+{
+	struct net_device *dev;
+	struct bcm_enet_priv *priv;
+	u32 stat;
+
+	dev = dev_id;
+	priv = netdev_priv(dev);
+
+	stat = enet_readl(priv, ENET_IR_REG);
+	if (!(stat & ENET_IR_MIB))
+		return IRQ_NONE;
+
+	/* clear & mask interrupt */
+	enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+	enet_writel(priv, 0, ENET_IRMASK_REG);
+
+	/* read mib registers in workqueue */
+	schedule_work(&priv->mib_update_task);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * rx/tx dma interrupt handler
+ */
+static irqreturn_t bcm_enet_isr_dma(int irq, void *dev_id)
+{
+	struct net_device *dev;
+	struct bcm_enet_priv *priv;
+
+	dev = dev_id;
+	priv = netdev_priv(dev);
+
+	/* mask rx/tx interrupts */
+	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+	napi_schedule(&priv->napi);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * tx request callback
+ */
+static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+	struct bcm_enet_desc *desc;
+	u32 len_stat;
+	int ret;
+
+	priv = netdev_priv(dev);
+
+	/* lock against tx reclaim */
+	spin_lock(&priv->tx_lock);
+
+	/* make sure  the tx hw queue  is not full,  should not happen
+	 * since we stop queue before it's the case */
+	if (unlikely(!priv->tx_desc_count)) {
+		netif_stop_queue(dev);
+		dev_err(&priv->pdev->dev, "xmit called with no tx desc "
+			"available?\n");
+		ret = NETDEV_TX_BUSY;
+		goto out_unlock;
+	}
+
+	/* point to the next available desc */
+	desc = &priv->tx_desc_cpu[priv->tx_curr_desc];
+	priv->tx_skb[priv->tx_curr_desc] = skb;
+
+	/* fill descriptor */
+	desc->address = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
+				       DMA_TO_DEVICE);
+
+	len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK;
+	len_stat |= DMADESC_ESOP_MASK |
+		DMADESC_APPEND_CRC |
+		DMADESC_OWNER_MASK;
+
+	priv->tx_curr_desc++;
+	if (priv->tx_curr_desc == priv->tx_ring_size) {
+		priv->tx_curr_desc = 0;
+		len_stat |= DMADESC_WRAP_MASK;
+	}
+	priv->tx_desc_count--;
+
+	/* dma might be already polling, make sure we update desc
+	 * fields in correct order */
+	wmb();
+	desc->len_stat = len_stat;
+	wmb();
+
+	/* kick tx dma */
+	enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+			ENETDMA_CHANCFG_REG(priv->tx_chan));
+
+	/* stop queue if no more desc available */
+	if (!priv->tx_desc_count)
+		netif_stop_queue(dev);
+
+	priv->stats.tx_bytes += skb->len;
+	priv->stats.tx_packets++;
+	dev->trans_start = jiffies;
+	ret = NETDEV_TX_OK;
+
+out_unlock:
+	spin_unlock(&priv->tx_lock);
+	return ret;
+}
+
+/*
+ * Change the interface's mac address.
+ */
+static int bcm_enet_set_mac_address(struct net_device *dev, void *p)
+{
+	struct bcm_enet_priv *priv;
+	struct sockaddr *addr = p;
+	u32 val;
+
+	priv = netdev_priv(dev);
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+	/* use perfect match register 0 to store my mac address */
+	val = (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) |
+		(dev->dev_addr[4] << 8) | dev->dev_addr[5];
+	enet_writel(priv, val, ENET_PML_REG(0));
+
+	val = (dev->dev_addr[0] << 8 | dev->dev_addr[1]);
+	val |= ENET_PMH_DATAVALID_MASK;
+	enet_writel(priv, val, ENET_PMH_REG(0));
+
+	return 0;
+}
+
+/*
+ * Change rx mode (promiscous/allmulti) and update multicast list
+ */
+static void bcm_enet_set_multicast_list(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+	struct dev_mc_list *mc_list;
+	u32 val;
+	int i;
+
+	priv = netdev_priv(dev);
+
+	val = enet_readl(priv, ENET_RXCFG_REG);
+
+	if (dev->flags & IFF_PROMISC)
+		val |= ENET_RXCFG_PROMISC_MASK;
+	else
+		val &= ~ENET_RXCFG_PROMISC_MASK;
+
+	/* only 3 perfect match registers left, first one is used for
+	 * own mac address */
+	if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 3)
+		val |= ENET_RXCFG_ALLMCAST_MASK;
+	else
+		val &= ~ENET_RXCFG_ALLMCAST_MASK;
+
+	/* no need to set perfect match registers if we catch all
+	 * multicast */
+	if (val & ENET_RXCFG_ALLMCAST_MASK) {
+		enet_writel(priv, val, ENET_RXCFG_REG);
+		return;
+	}
+
+	for (i = 0, mc_list = dev->mc_list;
+	     (mc_list != NULL) && (i < dev->mc_count) && (i < 3);
+	     i++, mc_list = mc_list->next) {
+		u8 *dmi_addr;
+		u32 tmp;
+
+		/* filter non ethernet address */
+		if (mc_list->dmi_addrlen != 6)
+			continue;
+
+		/* update perfect match registers */
+		dmi_addr = mc_list->dmi_addr;
+		tmp = (dmi_addr[2] << 24) | (dmi_addr[3] << 16) |
+			(dmi_addr[4] << 8) | dmi_addr[5];
+		enet_writel(priv, tmp, ENET_PML_REG(i + 1));
+
+		tmp = (dmi_addr[0] << 8 | dmi_addr[1]);
+		tmp |= ENET_PMH_DATAVALID_MASK;
+		enet_writel(priv, tmp, ENET_PMH_REG(i + 1));
+	}
+
+	for (; i < 3; i++) {
+		enet_writel(priv, 0, ENET_PML_REG(i + 1));
+		enet_writel(priv, 0, ENET_PMH_REG(i + 1));
+	}
+
+	enet_writel(priv, val, ENET_RXCFG_REG);
+}
+
+/*
+ * set mac duplex parameters
+ */
+static void bcm_enet_set_duplex(struct bcm_enet_priv *priv, int fullduplex)
+{
+	u32 val;
+
+	val = enet_readl(priv, ENET_TXCTL_REG);
+	if (fullduplex)
+		val |= ENET_TXCTL_FD_MASK;
+	else
+		val &= ~ENET_TXCTL_FD_MASK;
+	enet_writel(priv, val, ENET_TXCTL_REG);
+}
+
+/*
+ * set mac flow control parameters
+ */
+static void bcm_enet_set_flow(struct bcm_enet_priv *priv, int rx_en, int tx_en)
+{
+	u32 val;
+
+	/* rx flow control (pause frame handling) */
+	val = enet_readl(priv, ENET_RXCFG_REG);
+	if (rx_en)
+		val |= ENET_RXCFG_ENFLOW_MASK;
+	else
+		val &= ~ENET_RXCFG_ENFLOW_MASK;
+	enet_writel(priv, val, ENET_RXCFG_REG);
+
+	/* tx flow control (pause frame generation) */
+	val = enet_dma_readl(priv, ENETDMA_CFG_REG);
+	if (tx_en)
+		val |= ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+	else
+		val &= ~ENETDMA_CFG_FLOWCH_MASK(priv->rx_chan);
+	enet_dma_writel(priv, val, ENETDMA_CFG_REG);
+}
+
+/*
+ * link changed callback (from phylib)
+ */
+static void bcm_enet_adjust_phy_link(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+	struct phy_device *phydev;
+	int status_changed;
+
+	priv = netdev_priv(dev);
+	phydev = priv->phydev;
+	status_changed = 0;
+
+	if (priv->old_link != phydev->link) {
+		status_changed = 1;
+		priv->old_link = phydev->link;
+	}
+
+	/* reflect duplex change in mac configuration */
+	if (phydev->link && phydev->duplex != priv->old_duplex) {
+		bcm_enet_set_duplex(priv,
+				    (phydev->duplex == DUPLEX_FULL) ? 1 : 0);
+		status_changed = 1;
+		priv->old_duplex = phydev->duplex;
+	}
+
+	/* enable flow control if remote advertise it (trust phylib to
+	 * check that duplex is full */
+	if (phydev->link && phydev->pause != priv->old_pause) {
+		int rx_pause_en, tx_pause_en;
+
+		if (phydev->pause) {
+			/* pause was advertised by lpa and us */
+			rx_pause_en = 1;
+			tx_pause_en = 1;
+		} else if (!priv->pause_auto) {
+			/* pause setting overrided by user */
+			rx_pause_en = priv->pause_rx;
+			tx_pause_en = priv->pause_tx;
+		} else {
+			rx_pause_en = 0;
+			tx_pause_en = 0;
+		}
+
+		bcm_enet_set_flow(priv, rx_pause_en, tx_pause_en);
+		status_changed = 1;
+		priv->old_pause = phydev->pause;
+	}
+
+	if (status_changed) {
+		pr_info("%s: link %s", dev->name, phydev->link ?
+			"UP" : "DOWN");
+		if (phydev->link)
+			pr_cont(" - %d/%s - flow control %s", phydev->speed,
+			       DUPLEX_FULL == phydev->duplex ? "full" : "half",
+			       phydev->pause == 1 ? "rx&tx" : "off");
+
+		pr_cont("\n");
+	}
+}
+
+/*
+ * link changed callback (if phylib is not used)
+ */
+static void bcm_enet_adjust_link(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	bcm_enet_set_duplex(priv, priv->force_duplex_full);
+	bcm_enet_set_flow(priv, priv->pause_rx, priv->pause_tx);
+	netif_carrier_on(dev);
+
+	pr_info("%s: link forced UP - %d/%s - flow control %s/%s\n",
+		dev->name,
+		priv->force_speed_100 ? 100 : 10,
+		priv->force_duplex_full ? "full" : "half",
+		priv->pause_rx ? "rx" : "off",
+		priv->pause_tx ? "tx" : "off");
+}
+
+/*
+ * open callback, allocate dma rings & buffers and start rx operation
+ */
+static int bcm_enet_open(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+	struct sockaddr addr;
+	struct device *kdev;
+	struct phy_device *phydev;
+	int i, ret;
+	unsigned int size;
+	char phy_id[MII_BUS_ID_SIZE + 3];
+	void *p;
+	u32 val;
+
+	priv = netdev_priv(dev);
+	kdev = &priv->pdev->dev;
+
+	if (priv->has_phy) {
+		/* connect to PHY */
+		snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
+			 priv->mac_id ? "1" : "0", priv->phy_id);
+
+		phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0,
+				     PHY_INTERFACE_MODE_MII);
+
+		if (IS_ERR(phydev)) {
+			dev_err(kdev, "could not attach to PHY\n");
+			return PTR_ERR(phydev);
+		}
+
+		/* mask with MAC supported features */
+		phydev->supported &= (SUPPORTED_10baseT_Half |
+				      SUPPORTED_10baseT_Full |
+				      SUPPORTED_100baseT_Half |
+				      SUPPORTED_100baseT_Full |
+				      SUPPORTED_Autoneg |
+				      SUPPORTED_Pause |
+				      SUPPORTED_MII);
+		phydev->advertising = phydev->supported;
+
+		if (priv->pause_auto && priv->pause_rx && priv->pause_tx)
+			phydev->advertising |= SUPPORTED_Pause;
+		else
+			phydev->advertising &= ~SUPPORTED_Pause;
+
+		dev_info(kdev, "attached PHY at address %d [%s]\n",
+			 phydev->addr, phydev->drv->name);
+
+		priv->old_link = 0;
+		priv->old_duplex = -1;
+		priv->old_pause = -1;
+		priv->phydev = phydev;
+	}
+
+	/* mask all interrupts and request them */
+	enet_writel(priv, 0, ENET_IRMASK_REG);
+	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+	ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
+	if (ret)
+		goto out_phy_disconnect;
+
+	ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
+			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev);
+	if (ret)
+		goto out_freeirq;
+
+	ret = request_irq(priv->irq_tx, bcm_enet_isr_dma,
+			  IRQF_DISABLED, dev->name, dev);
+	if (ret)
+		goto out_freeirq_rx;
+
+	/* initialize perfect match registers */
+	for (i = 0; i < 4; i++) {
+		enet_writel(priv, 0, ENET_PML_REG(i));
+		enet_writel(priv, 0, ENET_PMH_REG(i));
+	}
+
+	/* write device mac address */
+	memcpy(addr.sa_data, dev->dev_addr, ETH_ALEN);
+	bcm_enet_set_mac_address(dev, &addr);
+
+	/* allocate rx dma ring */
+	size = priv->rx_ring_size * sizeof(struct bcm_enet_desc);
+	p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL);
+	if (!p) {
+		dev_err(kdev, "cannot allocate rx ring %u\n", size);
+		ret = -ENOMEM;
+		goto out_freeirq_tx;
+	}
+
+	memset(p, 0, size);
+	priv->rx_desc_alloc_size = size;
+	priv->rx_desc_cpu = p;
+
+	/* allocate tx dma ring */
+	size = priv->tx_ring_size * sizeof(struct bcm_enet_desc);
+	p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL);
+	if (!p) {
+		dev_err(kdev, "cannot allocate tx ring\n");
+		ret = -ENOMEM;
+		goto out_free_rx_ring;
+	}
+
+	memset(p, 0, size);
+	priv->tx_desc_alloc_size = size;
+	priv->tx_desc_cpu = p;
+
+	priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size,
+			       GFP_KERNEL);
+	if (!priv->tx_skb) {
+		dev_err(kdev, "cannot allocate rx skb queue\n");
+		ret = -ENOMEM;
+		goto out_free_tx_ring;
+	}
+
+	priv->tx_desc_count = priv->tx_ring_size;
+	priv->tx_dirty_desc = 0;
+	priv->tx_curr_desc = 0;
+	spin_lock_init(&priv->tx_lock);
+
+	/* init & fill rx ring with skbs */
+	priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size,
+			       GFP_KERNEL);
+	if (!priv->rx_skb) {
+		dev_err(kdev, "cannot allocate rx skb queue\n");
+		ret = -ENOMEM;
+		goto out_free_tx_skb;
+	}
+
+	priv->rx_desc_count = 0;
+	priv->rx_dirty_desc = 0;
+	priv->rx_curr_desc = 0;
+
+	/* initialize flow control buffer allocation */
+	enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+			ENETDMA_BUFALLOC_REG(priv->rx_chan));
+
+	if (bcm_enet_refill_rx(dev)) {
+		dev_err(kdev, "cannot allocate rx skb queue\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* write rx & tx ring addresses */
+	enet_dma_writel(priv, priv->rx_desc_dma,
+			ENETDMA_RSTART_REG(priv->rx_chan));
+	enet_dma_writel(priv, priv->tx_desc_dma,
+			ENETDMA_RSTART_REG(priv->tx_chan));
+
+	/* clear remaining state ram for rx & tx channel */
+	enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan));
+
+	/* set max rx/tx length */
+	enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG);
+	enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG);
+
+	/* set dma maximum burst len */
+	enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
+			ENETDMA_MAXBURST_REG(priv->rx_chan));
+	enet_dma_writel(priv, BCMENET_DMA_MAXBURST,
+			ENETDMA_MAXBURST_REG(priv->tx_chan));
+
+	/* set correct transmit fifo watermark */
+	enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG);
+
+	/* set flow control low/high threshold to 1/3 / 2/3 */
+	val = priv->rx_ring_size / 3;
+	enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan));
+	val = (priv->rx_ring_size * 2) / 3;
+	enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan));
+
+	/* all set, enable mac and interrupts, start dma engine and
+	 * kick rx dma channel */
+	wmb();
+	enet_writel(priv, ENET_CTL_ENABLE_MASK, ENET_CTL_REG);
+	enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG);
+	enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK,
+			ENETDMA_CHANCFG_REG(priv->rx_chan));
+
+	/* watch "mib counters about to overflow" interrupt */
+	enet_writel(priv, ENET_IR_MIB, ENET_IR_REG);
+	enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+
+	/* watch "packet transferred" interrupt in rx and tx */
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IR_REG(priv->rx_chan));
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IR_REG(priv->tx_chan));
+
+	/* make sure we enable napi before rx interrupt  */
+	napi_enable(&priv->napi);
+
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IRMASK_REG(priv->rx_chan));
+	enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK,
+			ENETDMA_IRMASK_REG(priv->tx_chan));
+
+	if (priv->has_phy)
+		phy_start(priv->phydev);
+	else
+		bcm_enet_adjust_link(dev);
+
+	netif_start_queue(dev);
+	return 0;
+
+out:
+	for (i = 0; i < priv->rx_ring_size; i++) {
+		struct bcm_enet_desc *desc;
+
+		if (!priv->rx_skb[i])
+			continue;
+
+		desc = &priv->rx_desc_cpu[i];
+		dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+				 DMA_FROM_DEVICE);
+		kfree_skb(priv->rx_skb[i]);
+	}
+	kfree(priv->rx_skb);
+
+out_free_tx_skb:
+	kfree(priv->tx_skb);
+
+out_free_tx_ring:
+	dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+			  priv->tx_desc_cpu, priv->tx_desc_dma);
+
+out_free_rx_ring:
+	dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+			  priv->rx_desc_cpu, priv->rx_desc_dma);
+
+out_freeirq_tx:
+	free_irq(priv->irq_tx, dev);
+
+out_freeirq_rx:
+	free_irq(priv->irq_rx, dev);
+
+out_freeirq:
+	free_irq(dev->irq, dev);
+
+out_phy_disconnect:
+	phy_disconnect(priv->phydev);
+
+	return ret;
+}
+
+/*
+ * disable mac
+ */
+static void bcm_enet_disable_mac(struct bcm_enet_priv *priv)
+{
+	int limit;
+	u32 val;
+
+	val = enet_readl(priv, ENET_CTL_REG);
+	val |= ENET_CTL_DISABLE_MASK;
+	enet_writel(priv, val, ENET_CTL_REG);
+
+	limit = 1000;
+	do {
+		u32 val;
+
+		val = enet_readl(priv, ENET_CTL_REG);
+		if (!(val & ENET_CTL_DISABLE_MASK))
+			break;
+		udelay(1);
+	} while (limit--);
+}
+
+/*
+ * disable dma in given channel
+ */
+static void bcm_enet_disable_dma(struct bcm_enet_priv *priv, int chan)
+{
+	int limit;
+
+	enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan));
+
+	limit = 1000;
+	do {
+		u32 val;
+
+		val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan));
+		if (!(val & ENETDMA_CHANCFG_EN_MASK))
+			break;
+		udelay(1);
+	} while (limit--);
+}
+
+/*
+ * stop callback
+ */
+static int bcm_enet_stop(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+	struct device *kdev;
+	int i;
+
+	priv = netdev_priv(dev);
+	kdev = &priv->pdev->dev;
+
+	netif_stop_queue(dev);
+	napi_disable(&priv->napi);
+	if (priv->has_phy)
+		phy_stop(priv->phydev);
+	del_timer_sync(&priv->rx_timeout);
+
+	/* mask all interrupts */
+	enet_writel(priv, 0, ENET_IRMASK_REG);
+	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan));
+	enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan));
+
+	/* make sure no mib update is scheduled */
+	flush_scheduled_work();
+
+	/* disable dma & mac */
+	bcm_enet_disable_dma(priv, priv->tx_chan);
+	bcm_enet_disable_dma(priv, priv->rx_chan);
+	bcm_enet_disable_mac(priv);
+
+	/* force reclaim of all tx buffers */
+	bcm_enet_tx_reclaim(dev, 1);
+
+	/* free the rx skb ring */
+	for (i = 0; i < priv->rx_ring_size; i++) {
+		struct bcm_enet_desc *desc;
+
+		if (!priv->rx_skb[i])
+			continue;
+
+		desc = &priv->rx_desc_cpu[i];
+		dma_unmap_single(kdev, desc->address, priv->rx_skb_size,
+				 DMA_FROM_DEVICE);
+		kfree_skb(priv->rx_skb[i]);
+	}
+
+	/* free remaining allocated memory */
+	kfree(priv->rx_skb);
+	kfree(priv->tx_skb);
+	dma_free_coherent(kdev, priv->rx_desc_alloc_size,
+			  priv->rx_desc_cpu, priv->rx_desc_dma);
+	dma_free_coherent(kdev, priv->tx_desc_alloc_size,
+			  priv->tx_desc_cpu, priv->tx_desc_dma);
+	free_irq(priv->irq_tx, dev);
+	free_irq(priv->irq_rx, dev);
+	free_irq(dev->irq, dev);
+
+	/* release phy */
+	if (priv->has_phy) {
+		phy_disconnect(priv->phydev);
+		priv->phydev = NULL;
+	}
+
+	return 0;
+}
+
+/*
+ * core request to return device rx/tx stats
+ */
+static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	return &priv->stats;
+}
+
+/*
+ * ethtool callbacks
+ */
+struct bcm_enet_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+	int mib_reg;
+};
+
+#define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m),		\
+		     offsetof(struct bcm_enet_priv, m)
+
+static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = {
+	{ "rx_packets", GEN_STAT(stats.rx_packets), -1 },
+	{ "tx_packets",	GEN_STAT(stats.tx_packets), -1 },
+	{ "rx_bytes", GEN_STAT(stats.rx_bytes), -1 },
+	{ "tx_bytes", GEN_STAT(stats.tx_bytes), -1 },
+	{ "rx_errors", GEN_STAT(stats.rx_errors), -1 },
+	{ "tx_errors", GEN_STAT(stats.tx_errors), -1 },
+	{ "rx_dropped",	GEN_STAT(stats.rx_dropped), -1 },
+	{ "tx_dropped",	GEN_STAT(stats.tx_dropped), -1 },
+
+	{ "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS},
+	{ "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS },
+	{ "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETH_MIB_RX_BRDCAST },
+	{ "rx_multicast", GEN_STAT(mib.rx_mult), ETH_MIB_RX_MULT },
+	{ "rx_64_octets", GEN_STAT(mib.rx_64), ETH_MIB_RX_64 },
+	{ "rx_65_127_oct", GEN_STAT(mib.rx_65_127), ETH_MIB_RX_65_127 },
+	{ "rx_128_255_oct", GEN_STAT(mib.rx_128_255), ETH_MIB_RX_128_255 },
+	{ "rx_256_511_oct", GEN_STAT(mib.rx_256_511), ETH_MIB_RX_256_511 },
+	{ "rx_512_1023_oct", GEN_STAT(mib.rx_512_1023), ETH_MIB_RX_512_1023 },
+	{ "rx_1024_max_oct", GEN_STAT(mib.rx_1024_max), ETH_MIB_RX_1024_MAX },
+	{ "rx_jabber", GEN_STAT(mib.rx_jab), ETH_MIB_RX_JAB },
+	{ "rx_oversize", GEN_STAT(mib.rx_ovr), ETH_MIB_RX_OVR },
+	{ "rx_fragment", GEN_STAT(mib.rx_frag), ETH_MIB_RX_FRAG },
+	{ "rx_dropped",	GEN_STAT(mib.rx_drop), ETH_MIB_RX_DROP },
+	{ "rx_crc_align", GEN_STAT(mib.rx_crc_align), ETH_MIB_RX_CRC_ALIGN },
+	{ "rx_undersize", GEN_STAT(mib.rx_und), ETH_MIB_RX_UND },
+	{ "rx_crc", GEN_STAT(mib.rx_crc), ETH_MIB_RX_CRC },
+	{ "rx_align", GEN_STAT(mib.rx_align), ETH_MIB_RX_ALIGN },
+	{ "rx_symbol_error", GEN_STAT(mib.rx_sym), ETH_MIB_RX_SYM },
+	{ "rx_pause", GEN_STAT(mib.rx_pause), ETH_MIB_RX_PAUSE },
+	{ "rx_control", GEN_STAT(mib.rx_cntrl), ETH_MIB_RX_CNTRL },
+
+	{ "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETH_MIB_TX_GD_OCTETS },
+	{ "tx_good_pkts", GEN_STAT(mib.tx_gd_pkts), ETH_MIB_TX_GD_PKTS },
+	{ "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETH_MIB_TX_BRDCAST },
+	{ "tx_multicast", GEN_STAT(mib.tx_mult), ETH_MIB_TX_MULT },
+	{ "tx_64_oct", GEN_STAT(mib.tx_64), ETH_MIB_TX_64 },
+	{ "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETH_MIB_TX_65_127 },
+	{ "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETH_MIB_TX_128_255 },
+	{ "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETH_MIB_TX_256_511 },
+	{ "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETH_MIB_TX_512_1023},
+	{ "tx_1024_max_oct", GEN_STAT(mib.tx_1024_max), ETH_MIB_TX_1024_MAX },
+	{ "tx_jabber", GEN_STAT(mib.tx_jab), ETH_MIB_TX_JAB },
+	{ "tx_oversize", GEN_STAT(mib.tx_ovr), ETH_MIB_TX_OVR },
+	{ "tx_fragment", GEN_STAT(mib.tx_frag), ETH_MIB_TX_FRAG },
+	{ "tx_underrun", GEN_STAT(mib.tx_underrun), ETH_MIB_TX_UNDERRUN },
+	{ "tx_collisions", GEN_STAT(mib.tx_col), ETH_MIB_TX_COL },
+	{ "tx_single_collision", GEN_STAT(mib.tx_1_col), ETH_MIB_TX_1_COL },
+	{ "tx_multiple_collision", GEN_STAT(mib.tx_m_col), ETH_MIB_TX_M_COL },
+	{ "tx_excess_collision", GEN_STAT(mib.tx_ex_col), ETH_MIB_TX_EX_COL },
+	{ "tx_late_collision", GEN_STAT(mib.tx_late), ETH_MIB_TX_LATE },
+	{ "tx_deferred", GEN_STAT(mib.tx_def), ETH_MIB_TX_DEF },
+	{ "tx_carrier_sense", GEN_STAT(mib.tx_crs), ETH_MIB_TX_CRS },
+	{ "tx_pause", GEN_STAT(mib.tx_pause), ETH_MIB_TX_PAUSE },
+
+};
+
+#define BCM_ENET_STATS_LEN	\
+	(sizeof(bcm_enet_gstrings_stats) / sizeof(struct bcm_enet_stats))
+
+static const u32 unused_mib_regs[] = {
+	ETH_MIB_TX_ALL_OCTETS,
+	ETH_MIB_TX_ALL_PKTS,
+	ETH_MIB_RX_ALL_OCTETS,
+	ETH_MIB_RX_ALL_PKTS,
+};
+
+
+static void bcm_enet_get_drvinfo(struct net_device *netdev,
+				 struct ethtool_drvinfo *drvinfo)
+{
+	strncpy(drvinfo->driver, bcm_enet_driver_name, 32);
+	strncpy(drvinfo->version, bcm_enet_driver_version, 32);
+	strncpy(drvinfo->fw_version, "N/A", 32);
+	strncpy(drvinfo->bus_info, "bcm63xx", 32);
+	drvinfo->n_stats = BCM_ENET_STATS_LEN;
+}
+
+static int bcm_enet_get_stats_count(struct net_device *netdev)
+{
+	return BCM_ENET_STATS_LEN;
+}
+
+static void bcm_enet_get_strings(struct net_device *netdev,
+				 u32 stringset, u8 *data)
+{
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN,
+			       bcm_enet_gstrings_stats[i].stat_string,
+			       ETH_GSTRING_LEN);
+		}
+		break;
+	}
+}
+
+static void update_mib_counters(struct bcm_enet_priv *priv)
+{
+	int i;
+
+	for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+		const struct bcm_enet_stats *s;
+		u32 val;
+		char *p;
+
+		s = &bcm_enet_gstrings_stats[i];
+		if (s->mib_reg == -1)
+			continue;
+
+		val = enet_readl(priv, ENET_MIB_REG(s->mib_reg));
+		p = (char *)priv + s->stat_offset;
+
+		if (s->sizeof_stat == sizeof(u64))
+			*(u64 *)p += val;
+		else
+			*(u32 *)p += val;
+	}
+
+	/* also empty unused mib counters to make sure mib counter
+	 * overflow interrupt is cleared */
+	for (i = 0; i < ARRAY_SIZE(unused_mib_regs); i++)
+		(void)enet_readl(priv, ENET_MIB_REG(unused_mib_regs[i]));
+}
+
+static void bcm_enet_update_mib_counters_defer(struct work_struct *t)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = container_of(t, struct bcm_enet_priv, mib_update_task);
+	mutex_lock(&priv->mib_update_lock);
+	update_mib_counters(priv);
+	mutex_unlock(&priv->mib_update_lock);
+
+	/* reenable mib interrupt */
+	if (netif_running(priv->net_dev))
+		enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG);
+}
+
+static void bcm_enet_get_ethtool_stats(struct net_device *netdev,
+				       struct ethtool_stats *stats,
+				       u64 *data)
+{
+	struct bcm_enet_priv *priv;
+	int i;
+
+	priv = netdev_priv(netdev);
+
+	mutex_lock(&priv->mib_update_lock);
+	update_mib_counters(priv);
+
+	for (i = 0; i < BCM_ENET_STATS_LEN; i++) {
+		const struct bcm_enet_stats *s;
+		char *p;
+
+		s = &bcm_enet_gstrings_stats[i];
+		p = (char *)priv + s->stat_offset;
+		data[i] = (s->sizeof_stat == sizeof(u64)) ?
+			*(u64 *)p : *(u32 *)p;
+	}
+	mutex_unlock(&priv->mib_update_lock);
+}
+
+static int bcm_enet_get_settings(struct net_device *dev,
+				 struct ethtool_cmd *cmd)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+
+	cmd->maxrxpkt = 0;
+	cmd->maxtxpkt = 0;
+
+	if (priv->has_phy) {
+		if (!priv->phydev)
+			return -ENODEV;
+		return phy_ethtool_gset(priv->phydev, cmd);
+	} else {
+		cmd->autoneg = 0;
+		cmd->speed = (priv->force_speed_100) ? SPEED_100 : SPEED_10;
+		cmd->duplex = (priv->force_duplex_full) ?
+			DUPLEX_FULL : DUPLEX_HALF;
+		cmd->supported = ADVERTISED_10baseT_Half  |
+			ADVERTISED_10baseT_Full |
+			ADVERTISED_100baseT_Half |
+			ADVERTISED_100baseT_Full;
+		cmd->advertising = 0;
+		cmd->port = PORT_MII;
+		cmd->transceiver = XCVR_EXTERNAL;
+	}
+	return 0;
+}
+
+static int bcm_enet_set_settings(struct net_device *dev,
+				 struct ethtool_cmd *cmd)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	if (priv->has_phy) {
+		if (!priv->phydev)
+			return -ENODEV;
+		return phy_ethtool_sset(priv->phydev, cmd);
+	} else {
+
+		if (cmd->autoneg ||
+		    (cmd->speed != SPEED_100 && cmd->speed != SPEED_10) ||
+		    cmd->port != PORT_MII)
+			return -EINVAL;
+
+		priv->force_speed_100 = (cmd->speed == SPEED_100) ? 1 : 0;
+		priv->force_duplex_full = (cmd->duplex == DUPLEX_FULL) ? 1 : 0;
+
+		if (netif_running(dev))
+			bcm_enet_adjust_link(dev);
+		return 0;
+	}
+}
+
+static void bcm_enet_get_ringparam(struct net_device *dev,
+				   struct ethtool_ringparam *ering)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+
+	/* rx/tx ring is actually only limited by memory */
+	ering->rx_max_pending = 8192;
+	ering->tx_max_pending = 8192;
+	ering->rx_mini_max_pending = 0;
+	ering->rx_jumbo_max_pending = 0;
+	ering->rx_pending = priv->rx_ring_size;
+	ering->tx_pending = priv->tx_ring_size;
+}
+
+static int bcm_enet_set_ringparam(struct net_device *dev,
+				  struct ethtool_ringparam *ering)
+{
+	struct bcm_enet_priv *priv;
+	int was_running;
+
+	priv = netdev_priv(dev);
+
+	was_running = 0;
+	if (netif_running(dev)) {
+		bcm_enet_stop(dev);
+		was_running = 1;
+	}
+
+	priv->rx_ring_size = ering->rx_pending;
+	priv->tx_ring_size = ering->tx_pending;
+
+	if (was_running) {
+		int err;
+
+		err = bcm_enet_open(dev);
+		if (err)
+			dev_close(dev);
+		else
+			bcm_enet_set_multicast_list(dev);
+	}
+	return 0;
+}
+
+static void bcm_enet_get_pauseparam(struct net_device *dev,
+				    struct ethtool_pauseparam *ecmd)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	ecmd->autoneg = priv->pause_auto;
+	ecmd->rx_pause = priv->pause_rx;
+	ecmd->tx_pause = priv->pause_tx;
+}
+
+static int bcm_enet_set_pauseparam(struct net_device *dev,
+				   struct ethtool_pauseparam *ecmd)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+
+	if (priv->has_phy) {
+		if (ecmd->autoneg && (ecmd->rx_pause != ecmd->tx_pause)) {
+			/* asymetric pause mode not supported,
+			 * actually possible but integrated PHY has RO
+			 * asym_pause bit */
+			return -EINVAL;
+		}
+	} else {
+		/* no pause autoneg on direct mii connection */
+		if (ecmd->autoneg)
+			return -EINVAL;
+	}
+
+	priv->pause_auto = ecmd->autoneg;
+	priv->pause_rx = ecmd->rx_pause;
+	priv->pause_tx = ecmd->tx_pause;
+
+	return 0;
+}
+
+static struct ethtool_ops bcm_enet_ethtool_ops = {
+	.get_strings		= bcm_enet_get_strings,
+	.get_stats_count	= bcm_enet_get_stats_count,
+	.get_ethtool_stats      = bcm_enet_get_ethtool_stats,
+	.get_settings		= bcm_enet_get_settings,
+	.set_settings		= bcm_enet_set_settings,
+	.get_drvinfo		= bcm_enet_get_drvinfo,
+	.get_link		= ethtool_op_get_link,
+	.get_ringparam		= bcm_enet_get_ringparam,
+	.set_ringparam		= bcm_enet_set_ringparam,
+	.get_pauseparam		= bcm_enet_get_pauseparam,
+	.set_pauseparam		= bcm_enet_set_pauseparam,
+};
+
+static int bcm_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct bcm_enet_priv *priv;
+
+	priv = netdev_priv(dev);
+	if (priv->has_phy) {
+		if (!priv->phydev)
+			return -ENODEV;
+		return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+	} else {
+		struct mii_if_info mii;
+
+		mii.dev = dev;
+		mii.mdio_read = bcm_enet_mdio_read_mii;
+		mii.mdio_write = bcm_enet_mdio_write_mii;
+		mii.phy_id = 0;
+		mii.phy_id_mask = 0x3f;
+		mii.reg_num_mask = 0x1f;
+		return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL);
+	}
+}
+
+/*
+ * calculate actual hardware mtu
+ */
+static int compute_hw_mtu(struct bcm_enet_priv *priv, int mtu)
+{
+	int actual_mtu;
+
+	actual_mtu = mtu;
+
+	/* add ethernet header + vlan tag size */
+	actual_mtu += VLAN_ETH_HLEN;
+
+	if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU)
+		return -EINVAL;
+
+	/*
+	 * setup maximum size before we get overflow mark in
+	 * descriptor, note that this will not prevent reception of
+	 * big frames, they will be split into multiple buffers
+	 * anyway
+	 */
+	priv->hw_mtu = actual_mtu;
+
+	/*
+	 * align rx buffer size to dma burst len, account FCS since
+	 * it's appended
+	 */
+	priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN,
+				  BCMENET_DMA_MAXBURST * 4);
+	return 0;
+}
+
+/*
+ * adjust mtu, can't be called while device is running
+ */
+static int bcm_enet_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int ret;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	ret = compute_hw_mtu(netdev_priv(dev), new_mtu);
+	if (ret)
+		return ret;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+/*
+ * preinit hardware to allow mii operation while device is down
+ */
+static void bcm_enet_hw_preinit(struct bcm_enet_priv *priv)
+{
+	u32 val;
+	int limit;
+
+	/* make sure mac is disabled */
+	bcm_enet_disable_mac(priv);
+
+	/* soft reset mac */
+	val = ENET_CTL_SRESET_MASK;
+	enet_writel(priv, val, ENET_CTL_REG);
+	wmb();
+
+	limit = 1000;
+	do {
+		val = enet_readl(priv, ENET_CTL_REG);
+		if (!(val & ENET_CTL_SRESET_MASK))
+			break;
+		udelay(1);
+	} while (limit--);
+
+	/* select correct mii interface */
+	val = enet_readl(priv, ENET_CTL_REG);
+	if (priv->use_external_mii)
+		val |= ENET_CTL_EPHYSEL_MASK;
+	else
+		val &= ~ENET_CTL_EPHYSEL_MASK;
+	enet_writel(priv, val, ENET_CTL_REG);
+
+	/* turn on mdc clock */
+	enet_writel(priv, (0x1f << ENET_MIISC_MDCFREQDIV_SHIFT) |
+		    ENET_MIISC_PREAMBLEEN_MASK, ENET_MIISC_REG);
+
+	/* set mib counters to self-clear when read */
+	val = enet_readl(priv, ENET_MIBCTL_REG);
+	val |= ENET_MIBCTL_RDCLEAR_MASK;
+	enet_writel(priv, val, ENET_MIBCTL_REG);
+}
+
+static const struct net_device_ops bcm_enet_ops = {
+	.ndo_open		= bcm_enet_open,
+	.ndo_stop		= bcm_enet_stop,
+	.ndo_start_xmit		= bcm_enet_start_xmit,
+	.ndo_get_stats		= bcm_enet_get_stats,
+	.ndo_set_mac_address	= bcm_enet_set_mac_address,
+	.ndo_set_multicast_list = bcm_enet_set_multicast_list,
+	.ndo_do_ioctl		= bcm_enet_ioctl,
+	.ndo_change_mtu		= bcm_enet_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller = bcm_enet_netpoll,
+#endif
+};
+
+/*
+ * allocate netdevice, request register memory and register device.
+ */
+static int __devinit bcm_enet_probe(struct platform_device *pdev)
+{
+	struct bcm_enet_priv *priv;
+	struct net_device *dev;
+	struct bcm63xx_enet_platform_data *pd;
+	struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx;
+	struct mii_bus *bus;
+	const char *clk_name;
+	unsigned int iomem_size;
+	int i, ret;
+
+	/* stop if shared driver failed, assume driver->probe will be
+	 * called in the same order we register devices (correct ?) */
+	if (!bcm_enet_shared_base)
+		return -ENODEV;
+
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	res_irq_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+	res_irq_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
+	if (!res_mem || !res_irq || !res_irq_rx || !res_irq_tx)
+		return -ENODEV;
+
+	ret = 0;
+	dev = alloc_etherdev(sizeof(*priv));
+	if (!dev)
+		return -ENOMEM;
+	priv = netdev_priv(dev);
+	memset(priv, 0, sizeof(*priv));
+
+	ret = compute_hw_mtu(priv, dev->mtu);
+	if (ret)
+		goto out;
+
+	iomem_size = res_mem->end - res_mem->start + 1;
+	if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	priv->base = ioremap(res_mem->start, iomem_size);
+	if (priv->base == NULL) {
+		ret = -ENOMEM;
+		goto out_release_mem;
+	}
+	dev->irq = priv->irq = res_irq->start;
+	priv->irq_rx = res_irq_rx->start;
+	priv->irq_tx = res_irq_tx->start;
+	priv->mac_id = pdev->id;
+
+	/* get rx & tx dma channel id for this mac */
+	if (priv->mac_id == 0) {
+		priv->rx_chan = 0;
+		priv->tx_chan = 1;
+		clk_name = "enet0";
+	} else {
+		priv->rx_chan = 2;
+		priv->tx_chan = 3;
+		clk_name = "enet1";
+	}
+
+	priv->mac_clk = clk_get(&pdev->dev, clk_name);
+	if (IS_ERR(priv->mac_clk)) {
+		ret = PTR_ERR(priv->mac_clk);
+		goto out_unmap;
+	}
+	clk_enable(priv->mac_clk);
+
+	/* initialize default and fetch platform data */
+	priv->rx_ring_size = BCMENET_DEF_RX_DESC;
+	priv->tx_ring_size = BCMENET_DEF_TX_DESC;
+
+	pd = pdev->dev.platform_data;
+	if (pd) {
+		memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN);
+		priv->has_phy = pd->has_phy;
+		priv->phy_id = pd->phy_id;
+		priv->has_phy_interrupt = pd->has_phy_interrupt;
+		priv->phy_interrupt = pd->phy_interrupt;
+		priv->use_external_mii = !pd->use_internal_phy;
+		priv->pause_auto = pd->pause_auto;
+		priv->pause_rx = pd->pause_rx;
+		priv->pause_tx = pd->pause_tx;
+		priv->force_duplex_full = pd->force_duplex_full;
+		priv->force_speed_100 = pd->force_speed_100;
+	}
+
+	if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) {
+		/* using internal PHY, enable clock */
+		priv->phy_clk = clk_get(&pdev->dev, "ephy");
+		if (IS_ERR(priv->phy_clk)) {
+			ret = PTR_ERR(priv->phy_clk);
+			priv->phy_clk = NULL;
+			goto out_put_clk_mac;
+		}
+		clk_enable(priv->phy_clk);
+	}
+
+	/* do minimal hardware init to be able to probe mii bus */
+	bcm_enet_hw_preinit(priv);
+
+	/* MII bus registration */
+	if (priv->has_phy) {
+
+		priv->mii_bus = mdiobus_alloc();
+		if (!priv->mii_bus) {
+			ret = -ENOMEM;
+			goto out_uninit_hw;
+		}
+
+		bus = priv->mii_bus;
+		bus->name = "bcm63xx_enet MII bus";
+		bus->parent = &pdev->dev;
+		bus->priv = priv;
+		bus->read = bcm_enet_mdio_read_phylib;
+		bus->write = bcm_enet_mdio_write_phylib;
+		sprintf(bus->id, "%d", priv->mac_id);
+
+		/* only probe bus where we think the PHY is, because
+		 * the mdio read operation return 0 instead of 0xffff
+		 * if a slave is not present on hw */
+		bus->phy_mask = ~(1 << priv->phy_id);
+
+		bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+		if (!bus->irq) {
+			ret = -ENOMEM;
+			goto out_free_mdio;
+		}
+
+		if (priv->has_phy_interrupt)
+			bus->irq[priv->phy_id] = priv->phy_interrupt;
+		else
+			bus->irq[priv->phy_id] = PHY_POLL;
+
+		ret = mdiobus_register(bus);
+		if (ret) {
+			dev_err(&pdev->dev, "unable to register mdio bus\n");
+			goto out_free_mdio;
+		}
+	} else {
+
+		/* run platform code to initialize PHY device */
+		if (pd->mii_config &&
+		    pd->mii_config(dev, 1, bcm_enet_mdio_read_mii,
+				   bcm_enet_mdio_write_mii)) {
+			dev_err(&pdev->dev, "unable to configure mdio bus\n");
+			goto out_uninit_hw;
+		}
+	}
+
+	spin_lock_init(&priv->rx_lock);
+
+	/* init rx timeout (used for oom) */
+	init_timer(&priv->rx_timeout);
+	priv->rx_timeout.function = bcm_enet_refill_rx_timer;
+	priv->rx_timeout.data = (unsigned long)dev;
+
+	/* init the mib update lock&work */
+	mutex_init(&priv->mib_update_lock);
+	INIT_WORK(&priv->mib_update_task, bcm_enet_update_mib_counters_defer);
+
+	/* zero mib counters */
+	for (i = 0; i < ENET_MIB_REG_COUNT; i++)
+		enet_writel(priv, 0, ENET_MIB_REG(i));
+
+	/* register netdevice */
+	dev->netdev_ops = &bcm_enet_ops;
+	netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16);
+
+	SET_ETHTOOL_OPS(dev, &bcm_enet_ethtool_ops);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	ret = register_netdev(dev);
+	if (ret)
+		goto out_unregister_mdio;
+
+	netif_carrier_off(dev);
+	platform_set_drvdata(pdev, dev);
+	priv->pdev = pdev;
+	priv->net_dev = dev;
+
+	return 0;
+
+out_unregister_mdio:
+	if (priv->mii_bus) {
+		mdiobus_unregister(priv->mii_bus);
+		kfree(priv->mii_bus->irq);
+	}
+
+out_free_mdio:
+	if (priv->mii_bus)
+		mdiobus_free(priv->mii_bus);
+
+out_uninit_hw:
+	/* turn off mdc clock */
+	enet_writel(priv, 0, ENET_MIISC_REG);
+	if (priv->phy_clk) {
+		clk_disable(priv->phy_clk);
+		clk_put(priv->phy_clk);
+	}
+
+out_put_clk_mac:
+	clk_disable(priv->mac_clk);
+	clk_put(priv->mac_clk);
+
+out_unmap:
+	iounmap(priv->base);
+
+out_release_mem:
+	release_mem_region(res_mem->start, iomem_size);
+out:
+	free_netdev(dev);
+	return ret;
+}
+
+
+/*
+ * exit func, stops hardware and unregisters netdevice
+ */
+static int __devexit bcm_enet_remove(struct platform_device *pdev)
+{
+	struct bcm_enet_priv *priv;
+	struct net_device *dev;
+	struct resource *res;
+
+	/* stop netdevice */
+	dev = platform_get_drvdata(pdev);
+	priv = netdev_priv(dev);
+	unregister_netdev(dev);
+
+	/* turn off mdc clock */
+	enet_writel(priv, 0, ENET_MIISC_REG);
+
+	if (priv->has_phy) {
+		mdiobus_unregister(priv->mii_bus);
+		kfree(priv->mii_bus->irq);
+		mdiobus_free(priv->mii_bus);
+	} else {
+		struct bcm63xx_enet_platform_data *pd;
+
+		pd = pdev->dev.platform_data;
+		if (pd && pd->mii_config)
+			pd->mii_config(dev, 0, bcm_enet_mdio_read_mii,
+				       bcm_enet_mdio_write_mii);
+	}
+
+	/* release device resources */
+	iounmap(priv->base);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, res->end - res->start + 1);
+
+	/* disable hw block clocks */
+	if (priv->phy_clk) {
+		clk_disable(priv->phy_clk);
+		clk_put(priv->phy_clk);
+	}
+	clk_disable(priv->mac_clk);
+	clk_put(priv->mac_clk);
+
+	platform_set_drvdata(pdev, NULL);
+	free_netdev(dev);
+	return 0;
+}
+
+struct platform_driver bcm63xx_enet_driver = {
+	.probe	= bcm_enet_probe,
+	.remove	= __devexit_p(bcm_enet_remove),
+	.driver	= {
+		.name	= "bcm63xx_enet",
+		.owner  = THIS_MODULE,
+	},
+};
+
+/*
+ * reserve & remap memory space shared between all macs
+ */
+static int __devinit bcm_enet_shared_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	unsigned int iomem_size;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	iomem_size = res->end - res->start + 1;
+	if (!request_mem_region(res->start, iomem_size, "bcm63xx_enet_dma"))
+		return -EBUSY;
+
+	bcm_enet_shared_base = ioremap(res->start, iomem_size);
+	if (!bcm_enet_shared_base) {
+		release_mem_region(res->start, iomem_size);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int __devexit bcm_enet_shared_remove(struct platform_device *pdev)
+{
+	struct resource *res;
+
+	iounmap(bcm_enet_shared_base);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_mem_region(res->start, res->end - res->start + 1);
+	return 0;
+}
+
+/*
+ * this "shared" driver is needed because both macs share a single
+ * address space
+ */
+struct platform_driver bcm63xx_enet_shared_driver = {
+	.probe	= bcm_enet_shared_probe,
+	.remove	= __devexit_p(bcm_enet_shared_remove),
+	.driver	= {
+		.name	= "bcm63xx_enet_shared",
+		.owner  = THIS_MODULE,
+	},
+};
+
+/*
+ * entry point
+ */
+static int __init bcm_enet_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&bcm63xx_enet_shared_driver);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&bcm63xx_enet_driver);
+	if (ret)
+		platform_driver_unregister(&bcm63xx_enet_shared_driver);
+
+	return ret;
+}
+
+static void __exit bcm_enet_exit(void)
+{
+	platform_driver_unregister(&bcm63xx_enet_driver);
+	platform_driver_unregister(&bcm63xx_enet_shared_driver);
+}
+
+
+module_init(bcm_enet_init);
+module_exit(bcm_enet_exit);
+
+MODULE_DESCRIPTION("BCM63xx internal ethernet mac driver");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h
new file mode 100644
index 0000000..bd3684d
--- /dev/null
+++ b/drivers/net/bcm63xx_enet.h
@@ -0,0 +1,303 @@
+#ifndef BCM63XX_ENET_H_
+#define BCM63XX_ENET_H_
+
+#include <linux/types.h>
+#include <linux/mii.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_regs.h>
+#include <bcm63xx_irq.h>
+#include <bcm63xx_io.h>
+
+/* default number of descriptor */
+#define BCMENET_DEF_RX_DESC	64
+#define BCMENET_DEF_TX_DESC	32
+
+/* maximum burst len for dma (4 bytes unit) */
+#define BCMENET_DMA_MAXBURST	16
+
+/* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value
+ * must be low enough so that a DMA transfer of above burst length can
+ * not overflow the fifo  */
+#define BCMENET_TX_FIFO_TRESH	32
+
+/*
+ * hardware maximum rx/tx packet size including FCS, max mtu is
+ * actually 2047, but if we set max rx size register to 2047 we won't
+ * get overflow information if packet size is 2048 or above
+ */
+#define BCMENET_MAX_MTU		2046
+
+/*
+ * rx/tx dma descriptor
+ */
+struct bcm_enet_desc {
+	u32 len_stat;
+	u32 address;
+};
+
+#define DMADESC_LENGTH_SHIFT	16
+#define DMADESC_LENGTH_MASK	(0xfff << DMADESC_LENGTH_SHIFT)
+#define DMADESC_OWNER_MASK	(1 << 15)
+#define DMADESC_EOP_MASK	(1 << 14)
+#define DMADESC_SOP_MASK	(1 << 13)
+#define DMADESC_ESOP_MASK	(DMADESC_EOP_MASK | DMADESC_SOP_MASK)
+#define DMADESC_WRAP_MASK	(1 << 12)
+
+#define DMADESC_UNDER_MASK	(1 << 9)
+#define DMADESC_APPEND_CRC	(1 << 8)
+#define DMADESC_OVSIZE_MASK	(1 << 4)
+#define DMADESC_RXER_MASK	(1 << 2)
+#define DMADESC_CRC_MASK	(1 << 1)
+#define DMADESC_OV_MASK		(1 << 0)
+#define DMADESC_ERR_MASK	(DMADESC_UNDER_MASK | \
+				DMADESC_OVSIZE_MASK | \
+				DMADESC_RXER_MASK | \
+				DMADESC_CRC_MASK | \
+				DMADESC_OV_MASK)
+
+
+/*
+ * MIB Counters register definitions
+*/
+#define ETH_MIB_TX_GD_OCTETS			0
+#define ETH_MIB_TX_GD_PKTS			1
+#define ETH_MIB_TX_ALL_OCTETS			2
+#define ETH_MIB_TX_ALL_PKTS			3
+#define ETH_MIB_TX_BRDCAST			4
+#define ETH_MIB_TX_MULT				5
+#define ETH_MIB_TX_64				6
+#define ETH_MIB_TX_65_127			7
+#define ETH_MIB_TX_128_255			8
+#define ETH_MIB_TX_256_511			9
+#define ETH_MIB_TX_512_1023			10
+#define ETH_MIB_TX_1024_MAX			11
+#define ETH_MIB_TX_JAB				12
+#define ETH_MIB_TX_OVR				13
+#define ETH_MIB_TX_FRAG				14
+#define ETH_MIB_TX_UNDERRUN			15
+#define ETH_MIB_TX_COL				16
+#define ETH_MIB_TX_1_COL			17
+#define ETH_MIB_TX_M_COL			18
+#define ETH_MIB_TX_EX_COL			19
+#define ETH_MIB_TX_LATE				20
+#define ETH_MIB_TX_DEF				21
+#define ETH_MIB_TX_CRS				22
+#define ETH_MIB_TX_PAUSE			23
+
+#define ETH_MIB_RX_GD_OCTETS			32
+#define ETH_MIB_RX_GD_PKTS			33
+#define ETH_MIB_RX_ALL_OCTETS			34
+#define ETH_MIB_RX_ALL_PKTS			35
+#define ETH_MIB_RX_BRDCAST			36
+#define ETH_MIB_RX_MULT				37
+#define ETH_MIB_RX_64				38
+#define ETH_MIB_RX_65_127			39
+#define ETH_MIB_RX_128_255			40
+#define ETH_MIB_RX_256_511			41
+#define ETH_MIB_RX_512_1023			42
+#define ETH_MIB_RX_1024_MAX			43
+#define ETH_MIB_RX_JAB				44
+#define ETH_MIB_RX_OVR				45
+#define ETH_MIB_RX_FRAG				46
+#define ETH_MIB_RX_DROP				47
+#define ETH_MIB_RX_CRC_ALIGN			48
+#define ETH_MIB_RX_UND				49
+#define ETH_MIB_RX_CRC				50
+#define ETH_MIB_RX_ALIGN			51
+#define ETH_MIB_RX_SYM				52
+#define ETH_MIB_RX_PAUSE			53
+#define ETH_MIB_RX_CNTRL			54
+
+
+struct bcm_enet_mib_counters {
+	u64 tx_gd_octets;
+	u32 tx_gd_pkts;
+	u32 tx_all_octets;
+	u32 tx_all_pkts;
+	u32 tx_brdcast;
+	u32 tx_mult;
+	u32 tx_64;
+	u32 tx_65_127;
+	u32 tx_128_255;
+	u32 tx_256_511;
+	u32 tx_512_1023;
+	u32 tx_1024_max;
+	u32 tx_jab;
+	u32 tx_ovr;
+	u32 tx_frag;
+	u32 tx_underrun;
+	u32 tx_col;
+	u32 tx_1_col;
+	u32 tx_m_col;
+	u32 tx_ex_col;
+	u32 tx_late;
+	u32 tx_def;
+	u32 tx_crs;
+	u32 tx_pause;
+	u64 rx_gd_octets;
+	u32 rx_gd_pkts;
+	u32 rx_all_octets;
+	u32 rx_all_pkts;
+	u32 rx_brdcast;
+	u32 rx_mult;
+	u32 rx_64;
+	u32 rx_65_127;
+	u32 rx_128_255;
+	u32 rx_256_511;
+	u32 rx_512_1023;
+	u32 rx_1024_max;
+	u32 rx_jab;
+	u32 rx_ovr;
+	u32 rx_frag;
+	u32 rx_drop;
+	u32 rx_crc_align;
+	u32 rx_und;
+	u32 rx_crc;
+	u32 rx_align;
+	u32 rx_sym;
+	u32 rx_pause;
+	u32 rx_cntrl;
+};
+
+
+struct bcm_enet_priv {
+
+	/* mac id (from platform device id) */
+	int mac_id;
+
+	/* base remapped address of device */
+	void __iomem *base;
+
+	/* mac irq, rx_dma irq, tx_dma irq */
+	int irq;
+	int irq_rx;
+	int irq_tx;
+
+	/* hw view of rx & tx dma ring */
+	dma_addr_t rx_desc_dma;
+	dma_addr_t tx_desc_dma;
+
+	/* allocated size (in bytes) for rx & tx dma ring */
+	unsigned int rx_desc_alloc_size;
+	unsigned int tx_desc_alloc_size;
+
+
+	struct napi_struct napi;
+
+	/* dma channel id for rx */
+	int rx_chan;
+
+	/* number of dma desc in rx ring */
+	int rx_ring_size;
+
+	/* cpu view of rx dma ring */
+	struct bcm_enet_desc *rx_desc_cpu;
+
+	/* current number of armed descriptor given to hardware for rx */
+	int rx_desc_count;
+
+	/* next rx descriptor to fetch from hardware */
+	int rx_curr_desc;
+
+	/* next dirty rx descriptor to refill */
+	int rx_dirty_desc;
+
+	/* size of allocated rx skbs */
+	unsigned int rx_skb_size;
+
+	/* list of skb given to hw for rx */
+	struct sk_buff **rx_skb;
+
+	/* used when rx skb allocation failed, so we defer rx queue
+	 * refill */
+	struct timer_list rx_timeout;
+
+	/* lock rx_timeout against rx normal operation */
+	spinlock_t rx_lock;
+
+
+	/* dma channel id for tx */
+	int tx_chan;
+
+	/* number of dma desc in tx ring */
+	int tx_ring_size;
+
+	/* cpu view of rx dma ring */
+	struct bcm_enet_desc *tx_desc_cpu;
+
+	/* number of available descriptor for tx */
+	int tx_desc_count;
+
+	/* next tx descriptor avaiable */
+	int tx_curr_desc;
+
+	/* next dirty tx descriptor to reclaim */
+	int tx_dirty_desc;
+
+	/* list of skb given to hw for tx */
+	struct sk_buff **tx_skb;
+
+	/* lock used by tx reclaim and xmit */
+	spinlock_t tx_lock;
+
+
+	/* set if internal phy is ignored and external mii interface
+	 * is selected */
+	int use_external_mii;
+
+	/* set if a phy is connected, phy address must be known,
+	 * probing is not possible */
+	int has_phy;
+	int phy_id;
+
+	/* set if connected phy has an associated irq */
+	int has_phy_interrupt;
+	int phy_interrupt;
+
+	/* used when a phy is connected (phylib used) */
+	struct mii_bus *mii_bus;
+	struct phy_device *phydev;
+	int old_link;
+	int old_duplex;
+	int old_pause;
+
+	/* used when no phy is connected */
+	int force_speed_100;
+	int force_duplex_full;
+
+	/* pause parameters */
+	int pause_auto;
+	int pause_rx;
+	int pause_tx;
+
+	/* stats */
+	struct net_device_stats stats;
+	struct bcm_enet_mib_counters mib;
+
+	/* after mib interrupt, mib registers update is done in this
+	 * work queue */
+	struct work_struct mib_update_task;
+
+	/* lock mib update between userspace request and workqueue */
+	struct mutex mib_update_lock;
+
+	/* mac clock */
+	struct clk *mac_clk;
+
+	/* phy clock if internal phy is used */
+	struct clk *phy_clk;
+
+	/* network device reference */
+	struct net_device *net_dev;
+
+	/* platform device reference */
+	struct platform_device *pdev;
+
+	/* maximum hardware transmit/receive size */
+	unsigned int hw_mtu;
+};
+
+#endif /* ! BCM63XX_ENET_H_ */
diff --git a/drivers/net/benet/Kconfig b/drivers/net/benet/Kconfig
index c6934f1..fdb6e81 100644
--- a/drivers/net/benet/Kconfig
+++ b/drivers/net/benet/Kconfig
@@ -1,7 +1,6 @@
 config BE2NET
 	tristate "ServerEngines' 10Gbps NIC - BladeEngine 2"
 	depends on PCI && INET
-	select INET_LRO
 	help
 	This driver implements the NIC functionality for ServerEngines'
 	10Gbps network adapter - BladeEngine 2.
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 5b4bf3d..684c6fe 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -28,11 +28,11 @@
 #include <linux/if_vlan.h>
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
-#include <linux/inet_lro.h>
+#include <linux/firmware.h>
 
 #include "be_hw.h"
 
-#define DRV_VER			"2.0.348"
+#define DRV_VER			"2.101.205"
 #define DRV_NAME		"be2net"
 #define BE_NAME			"ServerEngines BladeEngine2 10Gbps NIC"
 #define OC_NAME			"Emulex OneConnect 10Gbps NIC"
@@ -72,8 +72,7 @@ static inline char *nic_name(struct pci_dev *pdev)
 #define MAX_RX_POST 		BE_NAPI_WEIGHT /* Frags posted at a time */
 #define RX_FRAGS_REFILL_WM	(RX_Q_LEN - MAX_RX_POST)
 
-#define BE_MAX_LRO_DESCRIPTORS  16
-#define BE_MAX_FRAGS_PER_FRAME  (min((u32) 16, (u32) MAX_SKB_FRAGS))
+#define FW_VER_LEN		32
 
 struct be_dma_mem {
 	void *va;
@@ -127,7 +126,6 @@ static inline void queue_tail_inc(struct be_queue_info *q)
 	index_inc(&q->tail, q->len);
 }
 
-
 struct be_eq_obj {
 	struct be_queue_info q;
 	char desc[32];
@@ -146,31 +144,6 @@ struct be_mcc_obj {
 	struct be_queue_info cq;
 };
 
-struct be_ctrl_info {
-	u8 __iomem *csr;
-	u8 __iomem *db;		/* Door Bell */
-	u8 __iomem *pcicfg;	/* PCI config space */
-	int pci_func;
-
-	/* Mbox used for cmd request/response */
-	spinlock_t mbox_lock;	/* For serializing mbox cmds to BE card */
-	struct be_dma_mem mbox_mem;
-	/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
-	 * is stored for freeing purpose */
-	struct be_dma_mem mbox_mem_alloced;
-
-	/* MCC Rings */
-	struct be_mcc_obj mcc_obj;
-	spinlock_t mcc_lock;	/* For serializing mcc cmds to BE card */
-	spinlock_t mcc_cq_lock;
-
-	/* MCC Async callback */
-	void (*async_cb)(void *adapter, bool link_up);
-	void *adapter_ctxt;
-};
-
-#include "be_cmds.h"
-
 struct be_drvr_stats {
 	u32 be_tx_reqs;		/* number of TX requests initiated */
 	u32 be_tx_stops;	/* number of times TX Q was stopped */
@@ -189,8 +162,6 @@ struct be_drvr_stats {
 	u32 be_polls;		/* number of times NAPI called poll function */
 	u32 be_rx_events;	/* number of ucast rx completion events  */
 	u32 be_rx_compl;	/* number of rx completion entries processed */
-	u32 be_lro_hgram_data[8];	/* histogram of LRO data packets */
-	u32 be_lro_hgram_ack[8];	/* histogram of LRO ACKs */
 	ulong be_rx_jiffies;
 	u64 be_rx_bytes;
 	u64 be_rx_bytes_prev;
@@ -233,8 +204,6 @@ struct be_rx_obj {
 	struct be_queue_info q;
 	struct be_queue_info cq;
 	struct be_rx_page_info page_info_tbl[RX_Q_LEN];
-	struct net_lro_mgr lro_mgr;
-	struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS];
 };
 
 #define BE_NUM_MSIX_VECTORS		2	/* 1 each for Tx and Rx */
@@ -242,8 +211,19 @@ struct be_adapter {
 	struct pci_dev *pdev;
 	struct net_device *netdev;
 
-	/* Mbox, pci config, csr address information */
-	struct be_ctrl_info ctrl;
+	u8 __iomem *csr;
+	u8 __iomem *db;		/* Door Bell */
+	u8 __iomem *pcicfg;	/* PCI config space */
+
+	spinlock_t mbox_lock;	/* For serializing mbox cmds to BE card */
+	struct be_dma_mem mbox_mem;
+	/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
+	 * is stored for freeing purpose */
+	struct be_dma_mem mbox_mem_alloced;
+
+	struct be_mcc_obj mcc_obj;
+	spinlock_t mcc_lock;	/* For serializing mcc cmds to BE card */
+	spinlock_t mcc_cq_lock;
 
 	struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS];
 	bool msix_enabled;
@@ -271,7 +251,6 @@ struct be_adapter {
 
 	/* Ethtool knobs and info */
 	bool rx_csum; 		/* BE card must perform rx-checksumming */
-	u32 max_rx_coal;
 	char fw_ver[FW_VER_LEN];
 	u32 if_handle;		/* Used to configure filtering */
 	u32 pmac_id;		/* MAC addr handle used by BE card */
@@ -281,10 +260,15 @@ struct be_adapter {
 	bool promiscuous;
 };
 
-extern struct ethtool_ops be_ethtool_ops;
+extern const struct ethtool_ops be_ethtool_ops;
 
 #define drvr_stats(adapter)		(&adapter->stats.drvr_stats)
 
+static inline unsigned int be_pci_func(struct be_adapter *adapter)
+{
+	return PCI_FUNC(adapter->pdev->devfn);
+}
+
 #define BE_SET_NETDEV_OPS(netdev, ops)	(netdev->netdev_ops = ops)
 
 #define PAGE_SHIFT_4K		12
@@ -375,6 +359,9 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
 	return val;
 }
 
-extern void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
+extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
 		u16 num_popped);
+extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
+extern void netdev_stats_update(struct be_adapter *adapter);
+extern int be_load_fw(struct be_adapter *adapter, u8 *func);
 #endif				/* BE_H */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 583517e..3dd76c4 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -16,21 +16,22 @@
  */
 
 #include "be.h"
+#include "be_cmds.h"
 
-static void be_mcc_notify(struct be_ctrl_info *ctrl)
+static void be_mcc_notify(struct be_adapter *adapter)
 {
-	struct be_queue_info *mccq = &ctrl->mcc_obj.q;
+	struct be_queue_info *mccq = &adapter->mcc_obj.q;
 	u32 val = 0;
 
 	val |= mccq->id & DB_MCCQ_RING_ID_MASK;
 	val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
-	iowrite32(val, ctrl->db + DB_MCCQ_OFFSET);
+	iowrite32(val, adapter->db + DB_MCCQ_OFFSET);
 }
 
 /* To check if valid bit is set, check the entire word as we don't know
  * the endianness of the data (old entry is host endian while a new entry is
  * little endian) */
-static inline bool be_mcc_compl_is_new(struct be_mcc_cq_entry *compl)
+static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
 	if (compl->flags != 0) {
 		compl->flags = le32_to_cpu(compl->flags);
@@ -42,13 +43,13 @@ static inline bool be_mcc_compl_is_new(struct be_mcc_cq_entry *compl)
 }
 
 /* Need to reset the entire word that houses the valid bit */
-static inline void be_mcc_compl_use(struct be_mcc_cq_entry *compl)
+static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
 {
 	compl->flags = 0;
 }
 
-static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
-	struct be_mcc_cq_entry *compl)
+static int be_mcc_compl_process(struct be_adapter *adapter,
+	struct be_mcc_compl *compl)
 {
 	u16 compl_status, extd_status;
 
@@ -58,23 +59,30 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
 
 	compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
 				CQE_STATUS_COMPL_MASK;
-	if (compl_status != MCC_STATUS_SUCCESS) {
+	if (compl_status == MCC_STATUS_SUCCESS) {
+		if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
+			struct be_cmd_resp_get_stats *resp =
+						adapter->stats.cmd.va;
+			be_dws_le_to_cpu(&resp->hw_stats,
+						sizeof(resp->hw_stats));
+			netdev_stats_update(adapter);
+		}
+	} else if (compl_status != MCC_STATUS_NOT_SUPPORTED) {
 		extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
 				CQE_STATUS_EXTD_MASK;
-		printk(KERN_WARNING DRV_NAME
-			" error in cmd completion: status(compl/extd)=%d/%d\n",
+		dev_warn(&adapter->pdev->dev,
+			"Error in cmd completion: status(compl/extd)=%d/%d\n",
 			compl_status, extd_status);
-		return -1;
 	}
-	return 0;
+	return compl_status;
 }
 
 /* Link state evt is a string of bytes; no need for endian swapping */
-static void be_async_link_state_process(struct be_ctrl_info *ctrl,
+static void be_async_link_state_process(struct be_adapter *adapter,
 		struct be_async_event_link_state *evt)
 {
-	ctrl->async_cb(ctrl->adapter_ctxt,
-		evt->port_link_status == ASYNC_EVENT_LINK_UP ? true : false);
+	be_link_status_update(adapter,
+		evt->port_link_status == ASYNC_EVENT_LINK_UP);
 }
 
 static inline bool is_link_state_evt(u32 trailer)
@@ -84,10 +92,10 @@ static inline bool is_link_state_evt(u32 trailer)
 				ASYNC_EVENT_CODE_LINK_STATE);
 }
 
-static struct be_mcc_cq_entry *be_mcc_compl_get(struct be_ctrl_info *ctrl)
+static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
 {
-	struct be_queue_info *mcc_cq = &ctrl->mcc_obj.cq;
-	struct be_mcc_cq_entry *compl = queue_tail_node(mcc_cq);
+	struct be_queue_info *mcc_cq = &adapter->mcc_obj.cq;
+	struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
 
 	if (be_mcc_compl_is_new(compl)) {
 		queue_tail_inc(mcc_cq);
@@ -96,55 +104,64 @@ static struct be_mcc_cq_entry *be_mcc_compl_get(struct be_ctrl_info *ctrl)
 	return NULL;
 }
 
-void be_process_mcc(struct be_ctrl_info *ctrl)
+int be_process_mcc(struct be_adapter *adapter)
 {
-	struct be_mcc_cq_entry *compl;
-	int num = 0;
+	struct be_mcc_compl *compl;
+	int num = 0, status = 0;
 
-	spin_lock_bh(&ctrl->mcc_cq_lock);
-	while ((compl = be_mcc_compl_get(ctrl))) {
+	spin_lock_bh(&adapter->mcc_cq_lock);
+	while ((compl = be_mcc_compl_get(adapter))) {
 		if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
 			/* Interpret flags as an async trailer */
 			BUG_ON(!is_link_state_evt(compl->flags));
 
 			/* Interpret compl as a async link evt */
-			be_async_link_state_process(ctrl,
+			be_async_link_state_process(adapter,
 				(struct be_async_event_link_state *) compl);
-		} else {
-			be_mcc_compl_process(ctrl, compl);
-			atomic_dec(&ctrl->mcc_obj.q.used);
+		} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
+				status = be_mcc_compl_process(adapter, compl);
+				atomic_dec(&adapter->mcc_obj.q.used);
 		}
 		be_mcc_compl_use(compl);
 		num++;
 	}
+
 	if (num)
-		be_cq_notify(ctrl, ctrl->mcc_obj.cq.id, true, num);
-	spin_unlock_bh(&ctrl->mcc_cq_lock);
+		be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num);
+
+	spin_unlock_bh(&adapter->mcc_cq_lock);
+	return status;
 }
 
 /* Wait till no more pending mcc requests are present */
-static void be_mcc_wait_compl(struct be_ctrl_info *ctrl)
+static int be_mcc_wait_compl(struct be_adapter *adapter)
 {
-#define mcc_timeout		50000 /* 5s timeout */
-	int i;
+#define mcc_timeout		120000 /* 12s timeout */
+	int i, status;
 	for (i = 0; i < mcc_timeout; i++) {
-		be_process_mcc(ctrl);
-		if (atomic_read(&ctrl->mcc_obj.q.used) == 0)
+		status = be_process_mcc(adapter);
+		if (status)
+			return status;
+
+		if (atomic_read(&adapter->mcc_obj.q.used) == 0)
 			break;
 		udelay(100);
 	}
-	if (i == mcc_timeout)
-		printk(KERN_WARNING DRV_NAME "mcc poll timed out\n");
+	if (i == mcc_timeout) {
+		dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
+		return -1;
+	}
+	return 0;
 }
 
 /* Notify MCC requests and wait for completion */
-static void be_mcc_notify_wait(struct be_ctrl_info *ctrl)
+static int be_mcc_notify_wait(struct be_adapter *adapter)
 {
-	be_mcc_notify(ctrl);
-	be_mcc_wait_compl(ctrl);
+	be_mcc_notify(adapter);
+	return be_mcc_wait_compl(adapter);
 }
 
-static int be_mbox_db_ready_wait(void __iomem *db)
+static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
 {
 	int cnt = 0, wait = 5;
 	u32 ready;
@@ -154,9 +171,8 @@ static int be_mbox_db_ready_wait(void __iomem *db)
 		if (ready)
 			break;
 
-		if (cnt > 200000) {
-			printk(KERN_WARNING DRV_NAME
-				": mbox_db poll timed out\n");
+		if (cnt > 4000000) {
+			dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
 			return -1;
 		}
 
@@ -173,55 +189,50 @@ static int be_mbox_db_ready_wait(void __iomem *db)
  * Insert the mailbox address into the doorbell in two steps
  * Polls on the mbox doorbell till a command completion (or a timeout) occurs
  */
-static int be_mbox_db_ring(struct be_ctrl_info *ctrl)
+static int be_mbox_notify_wait(struct be_adapter *adapter)
 {
 	int status;
 	u32 val = 0;
-	void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
-	struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
+	void __iomem *db = adapter->db + MPU_MAILBOX_DB_OFFSET;
+	struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
 	struct be_mcc_mailbox *mbox = mbox_mem->va;
-	struct be_mcc_cq_entry *cqe = &mbox->cqe;
-
-	memset(cqe, 0, sizeof(*cqe));
+	struct be_mcc_compl *compl = &mbox->compl;
 
-	val &= ~MPU_MAILBOX_DB_RDY_MASK;
 	val |= MPU_MAILBOX_DB_HI_MASK;
 	/* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
 	val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
 	iowrite32(val, db);
 
 	/* wait for ready to be set */
-	status = be_mbox_db_ready_wait(db);
+	status = be_mbox_db_ready_wait(adapter, db);
 	if (status != 0)
 		return status;
 
 	val = 0;
-	val &= ~MPU_MAILBOX_DB_RDY_MASK;
-	val &= ~MPU_MAILBOX_DB_HI_MASK;
 	/* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
 	val |= (u32)(mbox_mem->dma >> 4) << 2;
 	iowrite32(val, db);
 
-	status = be_mbox_db_ready_wait(db);
+	status = be_mbox_db_ready_wait(adapter, db);
 	if (status != 0)
 		return status;
 
 	/* A cq entry has been made now */
-	if (be_mcc_compl_is_new(cqe)) {
-		status = be_mcc_compl_process(ctrl, &mbox->cqe);
-		be_mcc_compl_use(cqe);
+	if (be_mcc_compl_is_new(compl)) {
+		status = be_mcc_compl_process(adapter, &mbox->compl);
+		be_mcc_compl_use(compl);
 		if (status)
 			return status;
 	} else {
-		printk(KERN_WARNING DRV_NAME "invalid mailbox completion\n");
+		dev_err(&adapter->pdev->dev, "invalid mailbox completion\n");
 		return -1;
 	}
 	return 0;
 }
 
-static int be_POST_stage_get(struct be_ctrl_info *ctrl, u16 *stage)
+static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
 {
-	u32 sem = ioread32(ctrl->csr + MPU_EP_SEMAPHORE_OFFSET);
+	u32 sem = ioread32(adapter->csr + MPU_EP_SEMAPHORE_OFFSET);
 
 	*stage = sem & EP_SEMAPHORE_POST_STAGE_MASK;
 	if ((sem >> EP_SEMAPHORE_POST_ERR_SHIFT) & EP_SEMAPHORE_POST_ERR_MASK)
@@ -230,54 +241,17 @@ static int be_POST_stage_get(struct be_ctrl_info *ctrl, u16 *stage)
 		return 0;
 }
 
-static int be_POST_stage_poll(struct be_ctrl_info *ctrl, u16 poll_stage)
-{
-	u16 stage, cnt, error;
-	for (cnt = 0; cnt < 5000; cnt++) {
-		error = be_POST_stage_get(ctrl, &stage);
-		if (error)
-			return -1;
-
-		if (stage == poll_stage)
-			break;
-		udelay(1000);
-	}
-	if (stage != poll_stage)
-		return -1;
-	return 0;
-}
-
-
-int be_cmd_POST(struct be_ctrl_info *ctrl)
+int be_cmd_POST(struct be_adapter *adapter)
 {
 	u16 stage, error;
 
-	error = be_POST_stage_get(ctrl, &stage);
-	if (error)
-		goto err;
-
-	if (stage == POST_STAGE_ARMFW_RDY)
-		return 0;
-
-	if (stage != POST_STAGE_AWAITING_HOST_RDY)
-		goto err;
-
-	/* On awaiting host rdy, reset and again poll on awaiting host rdy */
-	iowrite32(POST_STAGE_BE_RESET, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET);
-	error = be_POST_stage_poll(ctrl, POST_STAGE_AWAITING_HOST_RDY);
-	if (error)
-		goto err;
-
-	/* Now kickoff POST and poll on armfw ready */
-	iowrite32(POST_STAGE_HOST_RDY, ctrl->csr + MPU_EP_SEMAPHORE_OFFSET);
-	error = be_POST_stage_poll(ctrl, POST_STAGE_ARMFW_RDY);
-	if (error)
-		goto err;
+	error = be_POST_stage_get(adapter, &stage);
+	if (error || stage != POST_STAGE_ARMFW_RDY) {
+		dev_err(&adapter->pdev->dev, "POST failed.\n");
+		return -1;
+	}
 
 	return 0;
-err:
-	printk(KERN_WARNING DRV_NAME ": ERROR, stage=%d\n", stage);
-	return -1;
 }
 
 static inline void *embedded_payload(struct be_mcc_wrb *wrb)
@@ -350,34 +324,40 @@ static u32 eq_delay_to_mult(u32 usec_delay)
 	return multiplier;
 }
 
-static inline struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
+static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
 {
-	return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
+	struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
+	struct be_mcc_wrb *wrb
+		= &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
+	memset(wrb, 0, sizeof(*wrb));
+	return wrb;
 }
 
-static inline struct be_mcc_wrb *wrb_from_mcc(struct be_queue_info *mccq)
+static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter)
 {
-	struct be_mcc_wrb *wrb = NULL;
-	if (atomic_read(&mccq->used) < mccq->len) {
-		wrb = queue_head_node(mccq);
-		queue_head_inc(mccq);
-		atomic_inc(&mccq->used);
-		memset(wrb, 0, sizeof(*wrb));
-	}
+	struct be_queue_info *mccq = &adapter->mcc_obj.q;
+	struct be_mcc_wrb *wrb;
+
+	BUG_ON(atomic_read(&mccq->used) >= mccq->len);
+	wrb = queue_head_node(mccq);
+	queue_head_inc(mccq);
+	atomic_inc(&mccq->used);
+	memset(wrb, 0, sizeof(*wrb));
 	return wrb;
 }
 
-int be_cmd_eq_create(struct be_ctrl_info *ctrl,
+int be_cmd_eq_create(struct be_adapter *adapter,
 		struct be_queue_info *eq, int eq_delay)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_eq_create *req = embedded_payload(wrb);
-	struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_eq_create *req;
 	struct be_dma_mem *q_mem = &eq->dma_mem;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -387,7 +367,7 @@ int be_cmd_eq_create(struct be_ctrl_info *ctrl,
 	req->num_pages =  cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 
 	AMAP_SET_BITS(struct amap_eq_context, func, req->context,
-			ctrl->pci_func);
+			be_pci_func(adapter));
 	AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
 	/* 4byte eqe*/
 	AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
@@ -399,25 +379,29 @@ int be_cmd_eq_create(struct be_ctrl_info *ctrl,
 
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
+		struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
 		eq->id = le16_to_cpu(resp->eq_id);
 		eq->created = true;
 	}
-	spin_unlock(&ctrl->mbox_lock);
+
+	spin_unlock(&adapter->mbox_lock);
 	return status;
 }
 
-int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr,
+/* Uses mbox */
+int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
 			u8 type, bool permanent, u32 if_handle)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_mac_query *req = embedded_payload(wrb);
-	struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_mac_query *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -428,27 +412,32 @@ int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr,
 	if (permanent) {
 		req->permanent = 1;
 	} else {
-		req->if_id = cpu_to_le16((u16)if_handle);
+		req->if_id = cpu_to_le16((u16) if_handle);
 		req->permanent = 0;
 	}
 
-	status = be_mbox_db_ring(ctrl);
-	if (!status)
+	status = be_mbox_notify_wait(adapter);
+	if (!status) {
+		struct be_cmd_resp_mac_query *resp = embedded_payload(wrb);
 		memcpy(mac_addr, resp->mac.addr, ETH_ALEN);
+	}
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock(&adapter->mbox_lock);
 	return status;
 }
 
-int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr,
+/* Uses synchronous MCCQ */
+int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
 		u32 if_id, u32 *pmac_id)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_pmac_add *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_pmac_add *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -458,24 +447,27 @@ int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr,
 	req->if_id = cpu_to_le32(if_id);
 	memcpy(req->mac_address, mac_addr, ETH_ALEN);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mcc_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_pmac_add *resp = embedded_payload(wrb);
 		*pmac_id = le32_to_cpu(resp->pmac_id);
 	}
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
 
-int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id)
+/* Uses synchronous MCCQ */
+int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_pmac_del *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_pmac_del *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -485,25 +477,29 @@ int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id)
 	req->if_id = cpu_to_le32(if_id);
 	req->pmac_id = cpu_to_le32(pmac_id);
 
-	status = be_mbox_db_ring(ctrl);
-	spin_unlock(&ctrl->mbox_lock);
+	status = be_mcc_notify_wait(adapter);
+
+	spin_unlock_bh(&adapter->mcc_lock);
 
 	return status;
 }
 
-int be_cmd_cq_create(struct be_ctrl_info *ctrl,
+/* Uses Mbox */
+int be_cmd_cq_create(struct be_adapter *adapter,
 		struct be_queue_info *cq, struct be_queue_info *eq,
 		bool sol_evts, bool no_delay, int coalesce_wm)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_cq_create *req = embedded_payload(wrb);
-	struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_cq_create *req;
 	struct be_dma_mem *q_mem = &cq->dma_mem;
-	void *ctxt = &req->context;
+	void *ctxt;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
+	ctxt = &req->context;
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -521,17 +517,19 @@ int be_cmd_cq_create(struct be_ctrl_info *ctrl,
 	AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
 	AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
 	AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
-	AMAP_SET_BITS(struct amap_cq_context, func, ctxt, ctrl->pci_func);
+	AMAP_SET_BITS(struct amap_cq_context, func, ctxt, be_pci_func(adapter));
 	be_dws_cpu_to_le(ctxt, sizeof(req->context));
 
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
+		struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
 		cq->id = le16_to_cpu(resp->cq_id);
 		cq->created = true;
 	}
-	spin_unlock(&ctrl->mbox_lock);
+
+	spin_unlock(&adapter->mbox_lock);
 
 	return status;
 }
@@ -544,18 +542,21 @@ static u32 be_encoded_q_len(int q_len)
 	return len_encoded;
 }
 
-int be_cmd_mccq_create(struct be_ctrl_info *ctrl,
+int be_cmd_mccq_create(struct be_adapter *adapter,
 			struct be_queue_info *mccq,
 			struct be_queue_info *cq)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_mcc_create *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_mcc_create *req;
 	struct be_dma_mem *q_mem = &mccq->dma_mem;
-	void *ctxt = &req->context;
+	void *ctxt;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
+	ctxt = &req->context;
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -564,7 +565,7 @@ int be_cmd_mccq_create(struct be_ctrl_info *ctrl,
 
 	req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
 
-	AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, ctrl->pci_func);
+	AMAP_SET_BITS(struct amap_mcc_context, fid, ctxt, be_pci_func(adapter));
 	AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
 	AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
 		be_encoded_q_len(mccq->len));
@@ -574,30 +575,32 @@ int be_cmd_mccq_create(struct be_ctrl_info *ctrl,
 
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
 		mccq->id = le16_to_cpu(resp->id);
 		mccq->created = true;
 	}
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock(&adapter->mbox_lock);
 
 	return status;
 }
 
-int be_cmd_txq_create(struct be_ctrl_info *ctrl,
+int be_cmd_txq_create(struct be_adapter *adapter,
 			struct be_queue_info *txq,
 			struct be_queue_info *cq)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_eth_tx_create *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_eth_tx_create *req;
 	struct be_dma_mem *q_mem = &txq->dma_mem;
-	void *ctxt = &req->context;
+	void *ctxt;
 	int status;
-	u32 len_encoded;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
+	ctxt = &req->context;
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -608,12 +611,10 @@ int be_cmd_txq_create(struct be_ctrl_info *ctrl,
 	req->ulp_num = BE_ULP1_NUM;
 	req->type = BE_ETH_TX_RING_TYPE_STANDARD;
 
-	len_encoded = fls(txq->len); /* log2(len) + 1 */
-	if (len_encoded == 16)
-		len_encoded = 0;
-	AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt, len_encoded);
+	AMAP_SET_BITS(struct amap_tx_context, tx_ring_size, ctxt,
+		be_encoded_q_len(txq->len));
 	AMAP_SET_BITS(struct amap_tx_context, pci_func_id, ctxt,
-			ctrl->pci_func);
+			be_pci_func(adapter));
 	AMAP_SET_BITS(struct amap_tx_context, ctx_valid, ctxt, 1);
 	AMAP_SET_BITS(struct amap_tx_context, cq_id_send, ctxt, cq->id);
 
@@ -621,28 +622,32 @@ int be_cmd_txq_create(struct be_ctrl_info *ctrl,
 
 	be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_eth_tx_create *resp = embedded_payload(wrb);
 		txq->id = le16_to_cpu(resp->cid);
 		txq->created = true;
 	}
-	spin_unlock(&ctrl->mbox_lock);
+
+	spin_unlock(&adapter->mbox_lock);
 
 	return status;
 }
 
-int be_cmd_rxq_create(struct be_ctrl_info *ctrl,
+/* Uses mbox */
+int be_cmd_rxq_create(struct be_adapter *adapter,
 		struct be_queue_info *rxq, u16 cq_id, u16 frag_size,
 		u16 max_frame_size, u32 if_id, u32 rss)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_eth_rx_create *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_eth_rx_create *req;
 	struct be_dma_mem *q_mem = &rxq->dma_mem;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -657,29 +662,34 @@ int be_cmd_rxq_create(struct be_ctrl_info *ctrl,
 	req->max_frame_size = cpu_to_le16(max_frame_size);
 	req->rss_queue = cpu_to_le32(rss);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb);
 		rxq->id = le16_to_cpu(resp->id);
 		rxq->created = true;
 	}
-	spin_unlock(&ctrl->mbox_lock);
+
+	spin_unlock(&adapter->mbox_lock);
 
 	return status;
 }
 
-/* Generic destroyer function for all types of queues */
-int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
+/* Generic destroyer function for all types of queues
+ * Uses Mbox
+ */
+int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 		int queue_type)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_q_destroy *req;
 	u8 subsys = 0, opcode = 0;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
-	memset(wrb, 0, sizeof(*wrb));
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
 	switch (queue_type) {
@@ -704,30 +714,32 @@ int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
 		opcode = OPCODE_COMMON_MCC_DESTROY;
 		break;
 	default:
-		printk(KERN_WARNING DRV_NAME ":bad Q type in Q destroy cmd\n");
-		status = -1;
-		goto err;
+		BUG();
 	}
 	be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
 	req->id = cpu_to_le16(q->id);
 
-	status = be_mbox_db_ring(ctrl);
-err:
-	spin_unlock(&ctrl->mbox_lock);
+	status = be_mbox_notify_wait(adapter);
+
+	spin_unlock(&adapter->mbox_lock);
 
 	return status;
 }
 
-/* Create an rx filtering policy configuration on an i/f */
-int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac,
+/* Create an rx filtering policy configuration on an i/f
+ * Uses mbox
+ */
+int be_cmd_if_create(struct be_adapter *adapter, u32 flags, u8 *mac,
 		bool pmac_invalid, u32 *if_handle, u32 *pmac_id)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_if_create *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_if_create *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -736,10 +748,11 @@ int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac,
 
 	req->capability_flags = cpu_to_le32(flags);
 	req->enable_flags = cpu_to_le32(flags);
+	req->pmac_invalid = pmac_invalid;
 	if (!pmac_invalid)
 		memcpy(req->mac_addr, mac, ETH_ALEN);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_if_create *resp = embedded_payload(wrb);
 		*if_handle = le32_to_cpu(resp->interface_id);
@@ -747,18 +760,21 @@ int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 flags, u8 *mac,
 			*pmac_id = le32_to_cpu(resp->pmac_id);
 	}
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock(&adapter->mbox_lock);
 	return status;
 }
 
-int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 interface_id)
+/* Uses mbox */
+int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_if_destroy *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_if_destroy *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -766,29 +782,32 @@ int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 interface_id)
 		OPCODE_COMMON_NTWK_INTERFACE_DESTROY, sizeof(*req));
 
 	req->interface_id = cpu_to_le32(interface_id);
-	status = be_mbox_db_ring(ctrl);
 
-	spin_unlock(&ctrl->mbox_lock);
+	status = be_mbox_notify_wait(adapter);
+
+	spin_unlock(&adapter->mbox_lock);
 
 	return status;
 }
 
 /* Get stats is a non embedded command: the request is not embedded inside
  * WRB but is a separate dma memory block
+ * Uses asynchronous MCC
  */
-int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd)
+int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_get_stats *req = nonemb_cmd->va;
-	struct be_sge *sge = nonembedded_sgl(wrb);
-	int status;
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_stats *req;
+	struct be_sge *sge;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock_bh(&adapter->mcc_lock);
 
-	memset(req, 0, sizeof(*req));
+	wrb = wrb_from_mccq(adapter);
+	req = nonemb_cmd->va;
+	sge = nonembedded_sgl(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
+	wrb->tag0 = OPCODE_ETH_GET_STATISTICS;
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
 		OPCODE_ETH_GET_STATISTICS, sizeof(*req));
@@ -796,77 +815,82 @@ int be_cmd_get_stats(struct be_ctrl_info *ctrl, struct be_dma_mem *nonemb_cmd)
 	sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF);
 	sge->len = cpu_to_le32(nonemb_cmd->size);
 
-	status = be_mbox_db_ring(ctrl);
-	if (!status) {
-		struct be_cmd_resp_get_stats *resp = nonemb_cmd->va;
-		be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats));
-	}
+	be_mcc_notify(adapter);
 
-	spin_unlock(&ctrl->mbox_lock);
-	return status;
+	spin_unlock_bh(&adapter->mcc_lock);
+	return 0;
 }
 
-int be_cmd_link_status_query(struct be_ctrl_info *ctrl,
+/* Uses synchronous mcc */
+int be_cmd_link_status_query(struct be_adapter *adapter,
 			bool *link_up)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_link_status *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_link_status *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
 
 	*link_up = false;
-	memset(wrb, 0, sizeof(*wrb));
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_NTWK_LINK_STATUS_QUERY, sizeof(*req));
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mcc_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
 		if (resp->mac_speed != PHY_LINK_SPEED_ZERO)
 			*link_up = true;
 	}
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
 
-int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver)
+/* Uses Mbox */
+int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_get_fw_version *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_fw_version *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_GET_FW_VERSION, sizeof(*req));
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
 		strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN);
 	}
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock(&adapter->mbox_lock);
 	return status;
 }
 
-/* set the EQ delay interval of an EQ to specified value */
-int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd)
+/* set the EQ delay interval of an EQ to specified value
+ * Uses async mcc
+ */
+int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_modify_eq_delay *req = embedded_payload(wrb);
-	int status;
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_modify_eq_delay *req;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -878,21 +902,24 @@ int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd)
 	req->delay[0].phase = 0;
 	req->delay[0].delay_multiplier = cpu_to_le32(eqd);
 
-	status = be_mbox_db_ring(ctrl);
+	be_mcc_notify(adapter);
 
-	spin_unlock(&ctrl->mbox_lock);
-	return status;
+	spin_unlock_bh(&adapter->mcc_lock);
+	return 0;
 }
 
-int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array,
+/* Uses sycnhronous mcc */
+int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
 			u32 num, bool untagged, bool promiscuous)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_vlan_config *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_vlan_config *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
-	memset(wrb, 0, sizeof(*wrb));
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -908,23 +935,24 @@ int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, u16 *vtag_array,
 			req->num_vlan * sizeof(vtag_array[0]));
 	}
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mcc_notify_wait(adapter);
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
 
-/* Use MCC for this command as it may be called in BH context */
-int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en)
+/* Uses MCC for this command as it may be called in BH context
+ * Uses synchronous mcc
+ */
+int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_promiscuous_config *req;
+	int status;
 
-	spin_lock_bh(&ctrl->mcc_lock);
-
-	wrb = wrb_from_mcc(&ctrl->mcc_obj.q);
-	BUG_ON(!wrb);
+	spin_lock_bh(&adapter->mcc_lock);
 
+	wrb = wrb_from_mccq(adapter);
 	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -937,28 +965,26 @@ int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en)
 	else
 		req->port0_promiscuous = en;
 
-	be_mcc_notify_wait(ctrl);
+	status = be_mcc_notify_wait(adapter);
 
-	spin_unlock_bh(&ctrl->mcc_lock);
-	return 0;
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
 }
 
 /*
- * Use MCC for this command as it may be called in BH context
+ * Uses MCC for this command as it may be called in BH context
  * (mc == NULL) => multicast promiscous
  */
-int be_cmd_multicast_set(struct be_ctrl_info *ctrl, u32 if_id,
+int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 		struct dev_mc_list *mc_list, u32 mc_count)
 {
 #define BE_MAX_MC		32 /* set mcast promisc if > 32 */
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_mcast_mac_config *req;
 
-	spin_lock_bh(&ctrl->mcc_lock);
-
-	wrb = wrb_from_mcc(&ctrl->mcc_obj.q);
-	BUG_ON(!wrb);
+	spin_lock_bh(&adapter->mcc_lock);
 
+	wrb = wrb_from_mccq(adapter);
 	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -979,22 +1005,24 @@ int be_cmd_multicast_set(struct be_ctrl_info *ctrl, u32 if_id,
 		req->promiscuous = 1;
 	}
 
-	be_mcc_notify_wait(ctrl);
+	be_mcc_notify_wait(adapter);
 
-	spin_unlock_bh(&ctrl->mcc_lock);
+	spin_unlock_bh(&adapter->mcc_lock);
 
 	return 0;
 }
 
-int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc)
+/* Uses synchrounous mcc */
+int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_set_flow_control *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_set_flow_control *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
+	spin_lock_bh(&adapter->mcc_lock);
 
-	memset(wrb, 0, sizeof(*wrb));
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
@@ -1004,28 +1032,30 @@ int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, u32 tx_fc, u32 rx_fc)
 	req->tx_flow_control = cpu_to_le16((u16)tx_fc);
 	req->rx_flow_control = cpu_to_le16((u16)rx_fc);
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mcc_notify_wait(adapter);
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
 
-int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, u32 *tx_fc, u32 *rx_fc)
+/* Uses sycn mcc */
+int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_get_flow_control *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_flow_control *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
+	spin_lock_bh(&adapter->mcc_lock);
 
-	memset(wrb, 0, sizeof(*wrb));
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_GET_FLOW_CONTROL, sizeof(*req));
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mcc_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_get_flow_control *resp =
 						embedded_payload(wrb);
@@ -1033,31 +1063,88 @@ int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, u32 *tx_fc, u32 *rx_fc)
 		*rx_fc = le16_to_cpu(resp->rx_flow_control);
 	}
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
 
-int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num)
+/* Uses mbox */
+int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
 {
-	struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
-	struct be_cmd_req_query_fw_cfg *req = embedded_payload(wrb);
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_query_fw_cfg *req;
 	int status;
 
-	spin_lock(&ctrl->mbox_lock);
+	spin_lock(&adapter->mbox_lock);
 
-	memset(wrb, 0, sizeof(*wrb));
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
 
 	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
 
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
 		OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
 
-	status = be_mbox_db_ring(ctrl);
+	status = be_mbox_notify_wait(adapter);
 	if (!status) {
 		struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
 		*port_num = le32_to_cpu(resp->phys_port);
 	}
 
-	spin_unlock(&ctrl->mbox_lock);
+	spin_unlock(&adapter->mbox_lock);
+	return status;
+}
+
+/* Uses mbox */
+int be_cmd_reset_function(struct be_adapter *adapter)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_hdr *req;
+	int status;
+
+	spin_lock(&adapter->mbox_lock);
+
+	wrb = wrb_from_mbox(adapter);
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
+
+	be_cmd_hdr_prepare(req, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
+
+	status = be_mbox_notify_wait(adapter);
+
+	spin_unlock(&adapter->mbox_lock);
+	return status;
+}
+
+int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
+			u32 flash_type, u32 flash_opcode, u32 buf_size)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_write_flashrom *req = cmd->va;
+	struct be_sge *sge;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	req = embedded_payload(wrb);
+	sge = nonembedded_sgl(wrb);
+
+	be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_WRITE_FLASHROM, cmd->size);
+	sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma));
+	sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(cmd->size);
+
+	req->params.op_type = cpu_to_le32(flash_type);
+	req->params.op_code = cpu_to_le32(flash_opcode);
+	req->params.data_buf_size = cpu_to_le32(buf_size);
+
+	status = be_mcc_notify_wait(adapter);
+
+	spin_unlock_bh(&adapter->mcc_lock);
 	return status;
 }
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 747626d..93e432f 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -61,7 +61,8 @@ enum {
 /* The command is completing because the queue was getting flushed */
 	MCC_STATUS_QUEUE_FLUSHING = 0x4,
 /* The command is completing with a DMA error */
-	MCC_STATUS_DMA_FAILED = 0x5
+	MCC_STATUS_DMA_FAILED = 0x5,
+	MCC_STATUS_NOT_SUPPORTED = 0x66
 };
 
 #define CQE_STATUS_COMPL_MASK		0xFFFF
@@ -69,7 +70,7 @@ enum {
 #define CQE_STATUS_EXTD_MASK		0xFFFF
 #define CQE_STATUS_EXTD_SHIFT		0	/* bits 0 - 15 */
 
-struct be_mcc_cq_entry {
+struct be_mcc_compl {
 	u32 status;		/* dword 0 */
 	u32 tag0;		/* dword 1 */
 	u32 tag1;		/* dword 2 */
@@ -106,7 +107,7 @@ struct be_async_event_link_state {
 
 struct be_mcc_mailbox {
 	struct be_mcc_wrb wrb;
-	struct be_mcc_cq_entry cqe;
+	struct be_mcc_compl compl;
 };
 
 #define CMD_SUBSYSTEM_COMMON	0x1
@@ -117,6 +118,7 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_NTWK_MULTICAST_SET		3
 #define OPCODE_COMMON_NTWK_VLAN_CONFIG  		4
 #define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY		5
+#define OPCODE_COMMON_WRITE_FLASHROM			7
 #define OPCODE_COMMON_CQ_CREATE				12
 #define OPCODE_COMMON_EQ_CREATE				13
 #define OPCODE_COMMON_MCC_CREATE        		21
@@ -135,6 +137,7 @@ struct be_mcc_mailbox {
 #define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG		58
 #define OPCODE_COMMON_NTWK_PMAC_ADD			59
 #define OPCODE_COMMON_NTWK_PMAC_DEL			60
+#define OPCODE_COMMON_FUNCTION_RESET			61
 
 #define OPCODE_ETH_ACPI_CONFIG				2
 #define OPCODE_ETH_PROMISCUOUS				3
@@ -634,7 +637,6 @@ struct be_cmd_resp_link_status {
 } __packed;
 
 /******************** Get FW Version *******************/
-#define FW_VER_LEN			32
 struct be_cmd_req_get_fw_version {
 	struct be_cmd_req_hdr hdr;
 	u8 rsvd0[FW_VER_LEN];
@@ -693,56 +695,74 @@ struct be_cmd_resp_query_fw_cfg {
 	u32 be_config_number;
 	u32 asic_revision;
 	u32 phys_port;
-	u32 function_mode;
+	u32 function_cap;
 	u32 rsvd[26];
 };
 
-extern int be_pci_fnum_get(struct be_ctrl_info *ctrl);
-extern int be_cmd_POST(struct be_ctrl_info *ctrl);
-extern int be_cmd_mac_addr_query(struct be_ctrl_info *ctrl, u8 *mac_addr,
+/****************** Firmware Flash ******************/
+struct flashrom_params {
+	u32 op_code;
+	u32 op_type;
+	u32 data_buf_size;
+	u32 offset;
+	u8 data_buf[4];
+};
+
+struct be_cmd_write_flashrom {
+	struct be_cmd_req_hdr hdr;
+	struct flashrom_params params;
+};
+
+extern int be_pci_fnum_get(struct be_adapter *adapter);
+extern int be_cmd_POST(struct be_adapter *adapter);
+extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
 			u8 type, bool permanent, u32 if_handle);
-extern int be_cmd_pmac_add(struct be_ctrl_info *ctrl, u8 *mac_addr,
+extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
 			u32 if_id, u32 *pmac_id);
-extern int be_cmd_pmac_del(struct be_ctrl_info *ctrl, u32 if_id, u32 pmac_id);
-extern int be_cmd_if_create(struct be_ctrl_info *ctrl, u32 if_flags, u8 *mac,
+extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id);
+extern int be_cmd_if_create(struct be_adapter *adapter, u32 if_flags, u8 *mac,
 			bool pmac_invalid, u32 *if_handle, u32 *pmac_id);
-extern int be_cmd_if_destroy(struct be_ctrl_info *ctrl, u32 if_handle);
-extern int be_cmd_eq_create(struct be_ctrl_info *ctrl,
+extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle);
+extern int be_cmd_eq_create(struct be_adapter *adapter,
 			struct be_queue_info *eq, int eq_delay);
-extern int be_cmd_cq_create(struct be_ctrl_info *ctrl,
+extern int be_cmd_cq_create(struct be_adapter *adapter,
 			struct be_queue_info *cq, struct be_queue_info *eq,
 			bool sol_evts, bool no_delay,
 			int num_cqe_dma_coalesce);
-extern int be_cmd_mccq_create(struct be_ctrl_info *ctrl,
+extern int be_cmd_mccq_create(struct be_adapter *adapter,
 			struct be_queue_info *mccq,
 			struct be_queue_info *cq);
-extern int be_cmd_txq_create(struct be_ctrl_info *ctrl,
+extern int be_cmd_txq_create(struct be_adapter *adapter,
 			struct be_queue_info *txq,
 			struct be_queue_info *cq);
-extern int be_cmd_rxq_create(struct be_ctrl_info *ctrl,
+extern int be_cmd_rxq_create(struct be_adapter *adapter,
 			struct be_queue_info *rxq, u16 cq_id,
 			u16 frag_size, u16 max_frame_size, u32 if_id,
 			u32 rss);
-extern int be_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
+extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 			int type);
-extern int be_cmd_link_status_query(struct be_ctrl_info *ctrl,
+extern int be_cmd_link_status_query(struct be_adapter *adapter,
 			bool *link_up);
-extern int be_cmd_reset(struct be_ctrl_info *ctrl);
-extern int be_cmd_get_stats(struct be_ctrl_info *ctrl,
+extern int be_cmd_reset(struct be_adapter *adapter);
+extern int be_cmd_get_stats(struct be_adapter *adapter,
 			struct be_dma_mem *nonemb_cmd);
-extern int be_cmd_get_fw_ver(struct be_ctrl_info *ctrl, char *fw_ver);
+extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver);
 
-extern int be_cmd_modify_eqd(struct be_ctrl_info *ctrl, u32 eq_id, u32 eqd);
-extern int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id,
+extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
+extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
 			u16 *vtag_array, u32 num, bool untagged,
 			bool promiscuous);
-extern int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl,
+extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
 			u8 port_num, bool en);
-extern int be_cmd_multicast_set(struct be_ctrl_info *ctrl, u32 if_id,
+extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 			struct dev_mc_list *mc_list, u32 mc_count);
-extern int be_cmd_set_flow_control(struct be_ctrl_info *ctrl,
+extern int be_cmd_set_flow_control(struct be_adapter *adapter,
 			u32 tx_fc, u32 rx_fc);
-extern int be_cmd_get_flow_control(struct be_ctrl_info *ctrl,
+extern int be_cmd_get_flow_control(struct be_adapter *adapter,
 			u32 *tx_fc, u32 *rx_fc);
-extern int be_cmd_query_fw_cfg(struct be_ctrl_info *ctrl, u32 *port_num);
-extern void be_process_mcc(struct be_ctrl_info *ctrl);
+extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num);
+extern int be_cmd_reset_function(struct be_adapter *adapter);
+extern int be_process_mcc(struct be_adapter *adapter);
+extern int be_cmd_write_flashrom(struct be_adapter *adapter,
+			struct be_dma_mem *cmd, u32 flash_oper,
+			u32 flash_opcode, u32 buf_size);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index cccc541..11445df 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -16,6 +16,7 @@
  */
 
 #include "be.h"
+#include "be_cmds.h"
 #include <linux/ethtool.h>
 
 struct be_ethtool_stat {
@@ -127,8 +128,6 @@ be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 	struct be_eq_obj *rx_eq = &adapter->rx_eq;
 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
 
-	coalesce->rx_max_coalesced_frames = adapter->max_rx_coal;
-
 	coalesce->rx_coalesce_usecs = rx_eq->cur_eqd;
 	coalesce->rx_coalesce_usecs_high = rx_eq->max_eqd;
 	coalesce->rx_coalesce_usecs_low = rx_eq->min_eqd;
@@ -144,14 +143,12 @@ be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 }
 
 /*
- * This routine is used to set interrup coalescing delay *as well as*
- * the number of pkts to coalesce for LRO.
+ * This routine is used to set interrup coalescing delay
  */
 static int
 be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 	struct be_eq_obj *rx_eq = &adapter->rx_eq;
 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
 	u32 tx_max, tx_min, tx_cur;
@@ -161,10 +158,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 	if (coalesce->use_adaptive_tx_coalesce == 1)
 		return -EINVAL;
 
-	adapter->max_rx_coal = coalesce->rx_max_coalesced_frames;
-	if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME)
-		adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME;
-
 	/* if AIC is being turned on now, start with an EQD of 0 */
 	if (rx_eq->enable_aic == 0 &&
 		coalesce->use_adaptive_rx_coalesce == 1) {
@@ -183,7 +176,7 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 	if (tx_cur > BE_MAX_EQD)
 		tx_cur = BE_MAX_EQD;
 	if (tx_eq->cur_eqd != tx_cur) {
-		status = be_cmd_modify_eqd(ctrl, tx_eq->q.id, tx_cur);
+		status = be_cmd_modify_eqd(adapter, tx_eq->q.id, tx_cur);
 		if (!status)
 			tx_eq->cur_eqd = tx_cur;
 	}
@@ -203,7 +196,8 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 		if (rx_cur > BE_MAX_EQD)
 			rx_cur = BE_MAX_EQD;
 		if (rx_eq->cur_eqd != rx_cur) {
-			status = be_cmd_modify_eqd(ctrl, rx_eq->q.id, rx_cur);
+			status = be_cmd_modify_eqd(adapter, rx_eq->q.id,
+					rx_cur);
 			if (!status)
 				rx_eq->cur_eqd = rx_cur;
 		}
@@ -317,8 +311,7 @@ be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 
-	be_cmd_get_flow_control(&adapter->ctrl, &ecmd->tx_pause,
-		&ecmd->rx_pause);
+	be_cmd_get_flow_control(adapter, &ecmd->tx_pause, &ecmd->rx_pause);
 	ecmd->autoneg = 0;
 }
 
@@ -331,7 +324,7 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 	if (ecmd->autoneg != 0)
 		return -EINVAL;
 
-	status = be_cmd_set_flow_control(&adapter->ctrl, ecmd->tx_pause,
+	status = be_cmd_set_flow_control(adapter, ecmd->tx_pause,
 			ecmd->rx_pause);
 	if (!status)
 		dev_warn(&adapter->pdev->dev, "Pause param set failed.\n");
@@ -339,7 +332,21 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
 	return status;
 }
 
-struct ethtool_ops be_ethtool_ops = {
+static int
+be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	char file_name[ETHTOOL_FLASH_MAX_FILENAME];
+	u32 region;
+
+	file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
+	strcpy(file_name, efl->data);
+	region = efl->region;
+
+	return be_load_fw(adapter, file_name);
+}
+
+const struct ethtool_ops be_ethtool_ops = {
 	.get_settings = be_get_settings,
 	.get_drvinfo = be_get_drvinfo,
 	.get_link = ethtool_op_get_link,
@@ -359,4 +366,5 @@ struct ethtool_ops be_ethtool_ops = {
 	.get_strings = be_get_stat_strings,
 	.get_stats_count = be_get_stats_count,
 	.get_ethtool_stats = be_get_ethtool_stats,
+	.flash_device = be_do_flash,
 };
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index 29c33c7..a3394b4 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -51,9 +51,6 @@
  * with the OS.
  */
 #define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK	(1 << 29) /* bit 29 */
-/* PCI physical function number */
-#define MEMBAR_CTRL_INT_CTRL_PFUNC_MASK  	0x7 	/* bits 26 - 28 */
-#define MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT	26
 
 /********* ISR0 Register offset **********/
 #define CEV_ISR0_OFFSET 			0xC18
@@ -207,7 +204,7 @@ struct amap_eth_rx_compl {
 	u8 numfrags[3];		/* dword 1 */
 	u8 rss_flush;		/* dword 2 */
 	u8 cast_enc[2];		/* dword 2 */
-	u8 qnq;			/* dword 2 */
+	u8 vtm;			/* dword 2 */
 	u8 rss_bank;		/* dword 2 */
 	u8 rsvd1[23];		/* dword 2 */
 	u8 lro_pkt;		/* dword 2 */
@@ -219,3 +216,86 @@ struct amap_eth_rx_compl {
 struct be_eth_rx_compl {
 	u32 dw[4];
 };
+
+/* Flashrom related descriptors */
+#define IMAGE_TYPE_FIRMWARE		160
+#define IMAGE_TYPE_BOOTCODE		224
+#define IMAGE_TYPE_OPTIONROM		32
+
+#define NUM_FLASHDIR_ENTRIES		32
+
+#define FLASHROM_TYPE_ISCSI_ACTIVE	0
+#define FLASHROM_TYPE_BIOS		2
+#define FLASHROM_TYPE_PXE_BIOS		3
+#define FLASHROM_TYPE_FCOE_BIOS		8
+#define FLASHROM_TYPE_ISCSI_BACKUP	9
+#define FLASHROM_TYPE_FCOE_FW_ACTIVE	10
+#define FLASHROM_TYPE_FCOE_FW_BACKUP 	11
+
+#define FLASHROM_OPER_FLASH		1
+#define FLASHROM_OPER_SAVE		2
+
+#define FLASH_IMAGE_MAX_SIZE            (1310720) /* Max firmware image size */
+#define FLASH_BIOS_IMAGE_MAX_SIZE       (262144)  /* Max OPTION ROM image sz */
+
+/* Offsets for components on Flash. */
+#define FLASH_iSCSI_PRIMARY_IMAGE_START (1048576)
+#define FLASH_iSCSI_BACKUP_IMAGE_START  (2359296)
+#define FLASH_FCoE_PRIMARY_IMAGE_START  (3670016)
+#define FLASH_FCoE_BACKUP_IMAGE_START   (4980736)
+#define FLASH_iSCSI_BIOS_START          (7340032)
+#define FLASH_PXE_BIOS_START            (7864320)
+#define FLASH_FCoE_BIOS_START           (524288)
+
+struct controller_id {
+	u32 vendor;
+	u32 device;
+	u32 subvendor;
+	u32 subdevice;
+};
+
+struct flash_file_hdr {
+	u8 sign[32];
+	u32 cksum;
+	u32 antidote;
+	struct controller_id cont_id;
+	u32 file_len;
+	u32 chunk_num;
+	u32 total_chunks;
+	u32 num_imgs;
+	u8 build[24];
+};
+
+struct flash_section_hdr {
+	u32 format_rev;
+	u32 cksum;
+	u32 antidote;
+	u32 build_no;
+	u8 id_string[64];
+	u32 active_entry_mask;
+	u32 valid_entry_mask;
+	u32 org_content_mask;
+	u32 rsvd0;
+	u32 rsvd1;
+	u32 rsvd2;
+	u32 rsvd3;
+	u32 rsvd4;
+};
+
+struct flash_section_entry {
+	u32 type;
+	u32 offset;
+	u32 pad_size;
+	u32 image_size;
+	u32 cksum;
+	u32 entry_point;
+	u32 rsvd0;
+	u32 rsvd1;
+	u8 ver_data[32];
+};
+
+struct flash_section_info {
+	u8 cookie[32];
+	struct flash_section_hdr fsec_hdr;
+	struct flash_section_entry fsec_entry[32];
+};
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index dea3155..409cf05 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -16,6 +16,7 @@
  */
 
 #include "be.h"
+#include "be_cmds.h"
 #include <asm/div64.h>
 
 MODULE_VERSION(DRV_VER);
@@ -60,40 +61,39 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
 	return 0;
 }
 
-static void be_intr_set(struct be_ctrl_info *ctrl, bool enable)
+static void be_intr_set(struct be_adapter *adapter, bool enable)
 {
-	u8 __iomem *addr = ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET;
+	u8 __iomem *addr = adapter->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET;
 	u32 reg = ioread32(addr);
 	u32 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
-	if (!enabled && enable) {
+
+	if (!enabled && enable)
 		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
-	} else if (enabled && !enable) {
+	else if (enabled && !enable)
 		reg &= ~MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
-	} else {
-		printk(KERN_WARNING DRV_NAME
-			": bad value in membar_int_ctrl reg=0x%x\n", reg);
+	else
 		return;
-	}
+
 	iowrite32(reg, addr);
 }
 
-static void be_rxq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted)
+static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
 {
 	u32 val = 0;
 	val |= qid & DB_RQ_RING_ID_MASK;
 	val |= posted << DB_RQ_NUM_POSTED_SHIFT;
-	iowrite32(val, ctrl->db + DB_RQ_OFFSET);
+	iowrite32(val, adapter->db + DB_RQ_OFFSET);
 }
 
-static void be_txq_notify(struct be_ctrl_info *ctrl, u16 qid, u16 posted)
+static void be_txq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
 {
 	u32 val = 0;
 	val |= qid & DB_TXULP_RING_ID_MASK;
 	val |= (posted & DB_TXULP_NUM_POSTED_MASK) << DB_TXULP_NUM_POSTED_SHIFT;
-	iowrite32(val, ctrl->db + DB_TXULP1_OFFSET);
+	iowrite32(val, adapter->db + DB_TXULP1_OFFSET);
 }
 
-static void be_eq_notify(struct be_ctrl_info *ctrl, u16 qid,
+static void be_eq_notify(struct be_adapter *adapter, u16 qid,
 		bool arm, bool clear_int, u16 num_popped)
 {
 	u32 val = 0;
@@ -104,44 +104,38 @@ static void be_eq_notify(struct be_ctrl_info *ctrl, u16 qid,
 		val |= 1 << DB_EQ_CLR_SHIFT;
 	val |= 1 << DB_EQ_EVNT_SHIFT;
 	val |= num_popped << DB_EQ_NUM_POPPED_SHIFT;
-	iowrite32(val, ctrl->db + DB_EQ_OFFSET);
+	iowrite32(val, adapter->db + DB_EQ_OFFSET);
 }
 
-void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid,
-		bool arm, u16 num_popped)
+void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
 {
 	u32 val = 0;
 	val |= qid & DB_CQ_RING_ID_MASK;
 	if (arm)
 		val |= 1 << DB_CQ_REARM_SHIFT;
 	val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
-	iowrite32(val, ctrl->db + DB_CQ_OFFSET);
+	iowrite32(val, adapter->db + DB_CQ_OFFSET);
 }
 
-
 static int be_mac_addr_set(struct net_device *netdev, void *p)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 	struct sockaddr *addr = p;
 	int status = 0;
 
-	if (netif_running(netdev)) {
-		status = be_cmd_pmac_del(&adapter->ctrl, adapter->if_handle,
-				adapter->pmac_id);
-		if (status)
-			return status;
-
-		status = be_cmd_pmac_add(&adapter->ctrl, (u8 *)addr->sa_data,
-				adapter->if_handle, &adapter->pmac_id);
-	}
+	status = be_cmd_pmac_del(adapter, adapter->if_handle, adapter->pmac_id);
+	if (status)
+		return status;
 
+	status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
+			adapter->if_handle, &adapter->pmac_id);
 	if (!status)
 		memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 
 	return status;
 }
 
-static void netdev_stats_update(struct be_adapter *adapter)
+void netdev_stats_update(struct be_adapter *adapter)
 {
 	struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va);
 	struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
@@ -214,9 +208,8 @@ static void netdev_stats_update(struct be_adapter *adapter)
 	dev_stats->tx_window_errors = 0;
 }
 
-void be_link_status_update(void *ctxt, bool link_up)
+void be_link_status_update(struct be_adapter *adapter, bool link_up)
 {
-	struct be_adapter *adapter = ctxt;
 	struct net_device *netdev = adapter->netdev;
 
 	/* If link came up or went down */
@@ -237,7 +230,6 @@ void be_link_status_update(void *ctxt, bool link_up)
 /* Update the EQ delay n BE based on the RX frags consumed / sec */
 static void be_rx_eqd_update(struct be_adapter *adapter)
 {
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 	struct be_eq_obj *rx_eq = &adapter->rx_eq;
 	struct be_drvr_stats *stats = &adapter->stats.drvr_stats;
 	ulong now = jiffies;
@@ -270,7 +262,7 @@ static void be_rx_eqd_update(struct be_adapter *adapter)
 	if (eqd < 10)
 		eqd = 0;
 	if (eqd != rx_eq->cur_eqd)
-		be_cmd_modify_eqd(ctrl, rx_eq->q.id, eqd);
+		be_cmd_modify_eqd(adapter, rx_eq->q.id, eqd);
 
 	rx_eq->cur_eqd = eqd;
 }
@@ -393,15 +385,19 @@ static int make_tx_wrbs(struct be_adapter *adapter,
 	struct be_eth_wrb *wrb;
 	struct be_eth_hdr_wrb *hdr;
 
-	atomic_add(wrb_cnt, &txq->used);
 	hdr = queue_head_node(txq);
+	atomic_add(wrb_cnt, &txq->used);
 	queue_head_inc(txq);
 
+	if (skb_dma_map(&pdev->dev, skb, DMA_TO_DEVICE)) {
+		dev_err(&pdev->dev, "TX DMA mapping failed\n");
+		return 0;
+	}
+
 	if (skb->len > skb->data_len) {
 		int len = skb->len - skb->data_len;
-		busaddr = pci_map_single(pdev, skb->data, len,
-					 PCI_DMA_TODEVICE);
 		wrb = queue_head_node(txq);
+		busaddr = skb_shinfo(skb)->dma_head;
 		wrb_fill(wrb, busaddr, len);
 		be_dws_cpu_to_le(wrb, sizeof(*wrb));
 		queue_head_inc(txq);
@@ -411,9 +407,8 @@ static int make_tx_wrbs(struct be_adapter *adapter,
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		struct skb_frag_struct *frag =
 			&skb_shinfo(skb)->frags[i];
-		busaddr = pci_map_page(pdev, frag->page,
-				       frag->page_offset,
-				       frag->size, PCI_DMA_TODEVICE);
+
+		busaddr = skb_shinfo(skb)->dma_maps[i];
 		wrb = queue_head_node(txq);
 		wrb_fill(wrb, busaddr, frag->size);
 		be_dws_cpu_to_le(wrb, sizeof(*wrb));
@@ -435,7 +430,8 @@ static int make_tx_wrbs(struct be_adapter *adapter,
 	return copied;
 }
 
-static int be_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t be_xmit(struct sk_buff *skb,
+			struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 	struct be_tx_obj *tx_obj = &adapter->tx_obj;
@@ -447,23 +443,28 @@ static int be_xmit(struct sk_buff *skb, struct net_device *netdev)
 	wrb_cnt = wrb_cnt_for_skb(skb, &dummy_wrb);
 
 	copied = make_tx_wrbs(adapter, skb, wrb_cnt, dummy_wrb);
+	if (copied) {
+		/* record the sent skb in the sent_skb table */
+		BUG_ON(tx_obj->sent_skb_list[start]);
+		tx_obj->sent_skb_list[start] = skb;
+
+		/* Ensure txq has space for the next skb; Else stop the queue
+		 * *BEFORE* ringing the tx doorbell, so that we serialze the
+		 * tx compls of the current transmit which'll wake up the queue
+		 */
+		if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >=
+								txq->len) {
+			netif_stop_queue(netdev);
+			stopped = true;
+		}
 
-	/* record the sent skb in the sent_skb table */
-	BUG_ON(tx_obj->sent_skb_list[start]);
-	tx_obj->sent_skb_list[start] = skb;
+		be_txq_notify(adapter, txq->id, wrb_cnt);
 
-	/* Ensure that txq has space for the next skb; Else stop the queue
-	 * *BEFORE* ringing the tx doorbell, so that we serialze the
-	 * tx compls of the current transmit which'll wake up the queue
-	 */
-	if ((BE_MAX_TX_FRAG_COUNT + atomic_read(&txq->used)) >= txq->len) {
-		netif_stop_queue(netdev);
-		stopped = true;
+		be_tx_stats_update(adapter, wrb_cnt, copied, stopped);
+	} else {
+		txq->head = start;
+		dev_kfree_skb_any(skb);
 	}
-
-	be_txq_notify(&adapter->ctrl, txq->id, wrb_cnt);
-
-	be_tx_stats_update(adapter, wrb_cnt, copied, stopped);
 	return NETDEV_TX_OK;
 }
 
@@ -488,11 +489,11 @@ static int be_change_mtu(struct net_device *netdev, int new_mtu)
  * program them in BE.  If more than BE_NUM_VLANS_SUPPORTED are configured,
  * set the BE in promiscuous VLAN mode.
  */
-static void be_vid_config(struct net_device *netdev)
+static int be_vid_config(struct be_adapter *adapter)
 {
-	struct be_adapter *adapter = netdev_priv(netdev);
 	u16 vtag[BE_NUM_VLANS_SUPPORTED];
 	u16 ntags = 0, i;
+	int status;
 
 	if (adapter->num_vlans <= BE_NUM_VLANS_SUPPORTED)  {
 		/* Construct VLAN Table to give to HW */
@@ -502,12 +503,13 @@ static void be_vid_config(struct net_device *netdev)
 				ntags++;
 			}
 		}
-		be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle,
-			vtag, ntags, 1, 0);
+		status = be_cmd_vlan_config(adapter, adapter->if_handle,
+					vtag, ntags, 1, 0);
 	} else {
-		be_cmd_vlan_config(&adapter->ctrl, adapter->if_handle,
-			NULL, 0, 1, 1);
+		status = be_cmd_vlan_config(adapter, adapter->if_handle,
+					NULL, 0, 1, 1);
 	}
+	return status;
 }
 
 static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
@@ -515,13 +517,12 @@ static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp)
 	struct be_adapter *adapter = netdev_priv(netdev);
 	struct be_eq_obj *rx_eq = &adapter->rx_eq;
 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 
-	be_eq_notify(ctrl, rx_eq->q.id, false, false, 0);
-	be_eq_notify(ctrl, tx_eq->q.id, false, false, 0);
+	be_eq_notify(adapter, rx_eq->q.id, false, false, 0);
+	be_eq_notify(adapter, tx_eq->q.id, false, false, 0);
 	adapter->vlan_grp = grp;
-	be_eq_notify(ctrl, rx_eq->q.id, true, false, 0);
-	be_eq_notify(ctrl, tx_eq->q.id, true, false, 0);
+	be_eq_notify(adapter, rx_eq->q.id, true, false, 0);
+	be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
 }
 
 static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
@@ -531,7 +532,7 @@ static void be_vlan_add_vid(struct net_device *netdev, u16 vid)
 	adapter->num_vlans++;
 	adapter->vlan_tag[vid] = 1;
 
-	be_vid_config(netdev);
+	be_vid_config(adapter);
 }
 
 static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
@@ -542,16 +543,15 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
 	adapter->vlan_tag[vid] = 0;
 
 	vlan_group_set_device(adapter->vlan_grp, vid, NULL);
-	be_vid_config(netdev);
+	be_vid_config(adapter);
 }
 
 static void be_set_multicast_list(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 
 	if (netdev->flags & IFF_PROMISC) {
-		be_cmd_promiscuous_config(ctrl, adapter->port_num, 1);
+		be_cmd_promiscuous_config(adapter, adapter->port_num, 1);
 		adapter->promiscuous = true;
 		goto done;
 	}
@@ -559,15 +559,15 @@ static void be_set_multicast_list(struct net_device *netdev)
 	/* BE was previously in promiscous mode; disable it */
 	if (adapter->promiscuous) {
 		adapter->promiscuous = false;
-		be_cmd_promiscuous_config(ctrl, adapter->port_num, 0);
+		be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
 	}
 
 	if (netdev->flags & IFF_ALLMULTI) {
-		be_cmd_multicast_set(ctrl, adapter->if_handle, NULL, 0);
+		be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0);
 		goto done;
 	}
 
-	be_cmd_multicast_set(ctrl, adapter->if_handle, netdev->mc_list,
+	be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list,
 		netdev->mc_count);
 done:
 	return;
@@ -742,7 +742,7 @@ done:
 	return;
 }
 
-/* Process the RX completion indicated by rxcp when LRO is disabled */
+/* Process the RX completion indicated by rxcp when GRO is disabled */
 static void be_rx_compl_process(struct be_adapter *adapter,
 			struct be_eth_rx_compl *rxcp)
 {
@@ -784,18 +784,17 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 		netif_receive_skb(skb);
 	}
 
-	adapter->netdev->last_rx = jiffies;
-
 	return;
 }
 
-/* Process the RX completion indicated by rxcp when LRO is enabled */
-static void be_rx_compl_process_lro(struct be_adapter *adapter,
+/* Process the RX completion indicated by rxcp when GRO is enabled */
+static void be_rx_compl_process_gro(struct be_adapter *adapter,
 			struct be_eth_rx_compl *rxcp)
 {
 	struct be_rx_page_info *page_info;
-	struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME];
+	struct sk_buff *skb = NULL;
 	struct be_queue_info *rxq = &adapter->rx_obj.q;
+	struct be_eq_obj *eq_obj =  &adapter->rx_eq;
 	u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
 	u16 i, rxq_idx = 0, vid, j;
 
@@ -804,6 +803,12 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter,
 	vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
 	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
 
+	skb = napi_get_frags(&eq_obj->napi);
+	if (!skb) {
+		be_rx_compl_discard(adapter, rxcp);
+		return;
+	}
+
 	remaining = pkt_size;
 	for (i = 0, j = -1; i < num_rcvd; i++) {
 		page_info = get_rx_page_info(adapter, rxq_idx);
@@ -814,13 +819,14 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter,
 		if (i == 0 || page_info->page_offset == 0) {
 			/* First frag or Fresh page */
 			j++;
-			rx_frags[j].page = page_info->page;
-			rx_frags[j].page_offset = page_info->page_offset;
-			rx_frags[j].size = 0;
+			skb_shinfo(skb)->frags[j].page = page_info->page;
+			skb_shinfo(skb)->frags[j].page_offset =
+							page_info->page_offset;
+			skb_shinfo(skb)->frags[j].size = 0;
 		} else {
 			put_page(page_info->page);
 		}
-		rx_frags[j].size += curr_frag_len;
+		skb_shinfo(skb)->frags[j].size += curr_frag_len;
 
 		remaining -= curr_frag_len;
 		index_inc(&rxq_idx, rxq->len);
@@ -828,9 +834,14 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter,
 	}
 	BUG_ON(j > MAX_SKB_FRAGS);
 
+	skb_shinfo(skb)->nr_frags = j + 1;
+	skb->len = pkt_size;
+	skb->data_len = pkt_size;
+	skb->truesize += pkt_size;
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+
 	if (likely(!vlanf)) {
-		lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size,
-				pkt_size, NULL, 0);
+		napi_gro_frags(&eq_obj->napi);
 	} else {
 		vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp);
 		vid = be16_to_cpu(vid);
@@ -838,9 +849,7 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter,
 		if (!adapter->vlan_grp || adapter->num_vlans == 0)
 			return;
 
-		lro_vlan_hwaccel_receive_frags(&adapter->rx_obj.lro_mgr,
-			rx_frags, pkt_size, pkt_size, adapter->vlan_grp,
-			vid, NULL, 0);
+		vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid);
 	}
 
 	be_rx_stats_update(adapter, pkt_size, num_rcvd);
@@ -931,7 +940,7 @@ static void be_post_rx_frags(struct be_adapter *adapter)
 
 	if (posted) {
 		atomic_add(posted, &rxq->used);
-		be_rxq_notify(&adapter->ctrl, rxq->id, posted);
+		be_rxq_notify(adapter, rxq->id, posted);
 	} else if (atomic_read(&rxq->used) == 0) {
 		/* Let be_worker replenish when memory is available */
 		adapter->rx_post_starved = true;
@@ -958,10 +967,8 @@ static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
 static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
 {
 	struct be_queue_info *txq = &adapter->tx_obj.q;
-	struct be_eth_wrb *wrb;
 	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
 	struct sk_buff *sent_skb;
-	u64 busaddr;
 	u16 cur_index, num_wrbs = 0;
 
 	cur_index = txq->tail;
@@ -971,22 +978,65 @@ static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
 
 	do {
 		cur_index = txq->tail;
-		wrb = queue_tail_node(txq);
-		be_dws_le_to_cpu(wrb, sizeof(*wrb));
-		busaddr = ((u64)wrb->frag_pa_hi << 32) | (u64)wrb->frag_pa_lo;
-		if (busaddr != 0) {
-			pci_unmap_single(adapter->pdev, busaddr,
-				wrb->frag_len, PCI_DMA_TODEVICE);
-		}
 		num_wrbs++;
 		queue_tail_inc(txq);
 	} while (cur_index != last_index);
 
 	atomic_sub(num_wrbs, &txq->used);
-
+	skb_dma_unmap(&adapter->pdev->dev, sent_skb, DMA_TO_DEVICE);
 	kfree_skb(sent_skb);
 }
 
+static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
+{
+	struct be_eq_entry *eqe = queue_tail_node(&eq_obj->q);
+
+	if (!eqe->evt)
+		return NULL;
+
+	eqe->evt = le32_to_cpu(eqe->evt);
+	queue_tail_inc(&eq_obj->q);
+	return eqe;
+}
+
+static int event_handle(struct be_adapter *adapter,
+			struct be_eq_obj *eq_obj)
+{
+	struct be_eq_entry *eqe;
+	u16 num = 0;
+
+	while ((eqe = event_get(eq_obj)) != NULL) {
+		eqe->evt = 0;
+		num++;
+	}
+
+	/* Deal with any spurious interrupts that come
+	 * without events
+	 */
+	be_eq_notify(adapter, eq_obj->q.id, true, true, num);
+	if (num)
+		napi_schedule(&eq_obj->napi);
+
+	return num;
+}
+
+/* Just read and notify events without processing them.
+ * Used at the time of destroying event queues */
+static void be_eq_clean(struct be_adapter *adapter,
+			struct be_eq_obj *eq_obj)
+{
+	struct be_eq_entry *eqe;
+	u16 num = 0;
+
+	while ((eqe = event_get(eq_obj)) != NULL) {
+		eqe->evt = 0;
+		num++;
+	}
+
+	if (num)
+		be_eq_notify(adapter, eq_obj->q.id, false, true, num);
+}
+
 static void be_rx_q_clean(struct be_adapter *adapter)
 {
 	struct be_rx_page_info *page_info;
@@ -999,12 +1049,12 @@ static void be_rx_q_clean(struct be_adapter *adapter)
 	while ((rxcp = be_rx_compl_get(adapter)) != NULL) {
 		be_rx_compl_discard(adapter, rxcp);
 		be_rx_compl_reset(rxcp);
-		be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1);
+		be_cq_notify(adapter, rx_cq->id, true, 1);
 	}
 
 	/* Then free posted rx buffer that were not used */
 	tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
-	for (; tail != rxq->head; index_inc(&tail, rxq->len)) {
+	for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
 		page_info = get_rx_page_info(adapter, tail);
 		put_page(page_info->page);
 		memset(page_info, 0, sizeof(*page_info));
@@ -1012,36 +1062,49 @@ static void be_rx_q_clean(struct be_adapter *adapter)
 	BUG_ON(atomic_read(&rxq->used));
 }
 
-static void be_tx_q_clean(struct be_adapter *adapter)
+static void be_tx_compl_clean(struct be_adapter *adapter)
 {
-	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
-	struct sk_buff *sent_skb;
+	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
 	struct be_queue_info *txq = &adapter->tx_obj.q;
-	u16 last_index;
-	bool dummy_wrb;
-
-	while (atomic_read(&txq->used)) {
-		sent_skb = sent_skbs[txq->tail];
-		last_index = txq->tail;
-		index_adv(&last_index,
-			wrb_cnt_for_skb(sent_skb, &dummy_wrb) - 1, txq->len);
-		be_tx_compl_process(adapter, last_index);
-	}
+	struct be_eth_tx_compl *txcp;
+	u16 end_idx, cmpl = 0, timeo = 0;
+
+	/* Wait for a max of 200ms for all the tx-completions to arrive. */
+	do {
+		while ((txcp = be_tx_compl_get(tx_cq))) {
+			end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
+					wrb_index, txcp);
+			be_tx_compl_process(adapter, end_idx);
+			cmpl++;
+		}
+		if (cmpl) {
+			be_cq_notify(adapter, tx_cq->id, false, cmpl);
+			cmpl = 0;
+		}
+
+		if (atomic_read(&txq->used) == 0 || ++timeo > 200)
+			break;
+
+		mdelay(1);
+	} while (true);
+
+	if (atomic_read(&txq->used))
+		dev_err(&adapter->pdev->dev, "%d pending tx-completions\n",
+			atomic_read(&txq->used));
 }
 
 static void be_mcc_queues_destroy(struct be_adapter *adapter)
 {
 	struct be_queue_info *q;
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 
-	q = &ctrl->mcc_obj.q;
+	q = &adapter->mcc_obj.q;
 	if (q->created)
-		be_cmd_q_destroy(ctrl, q, QTYPE_MCCQ);
+		be_cmd_q_destroy(adapter, q, QTYPE_MCCQ);
 	be_queue_free(adapter, q);
 
-	q = &ctrl->mcc_obj.cq;
+	q = &adapter->mcc_obj.cq;
 	if (q->created)
-		be_cmd_q_destroy(ctrl, q, QTYPE_CQ);
+		be_cmd_q_destroy(adapter, q, QTYPE_CQ);
 	be_queue_free(adapter, q);
 }
 
@@ -1049,25 +1112,24 @@ static void be_mcc_queues_destroy(struct be_adapter *adapter)
 static int be_mcc_queues_create(struct be_adapter *adapter)
 {
 	struct be_queue_info *q, *cq;
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 
 	/* Alloc MCC compl queue */
-	cq = &ctrl->mcc_obj.cq;
+	cq = &adapter->mcc_obj.cq;
 	if (be_queue_alloc(adapter, cq, MCC_CQ_LEN,
-			sizeof(struct be_mcc_cq_entry)))
+			sizeof(struct be_mcc_compl)))
 		goto err;
 
 	/* Ask BE to create MCC compl queue; share TX's eq */
-	if (be_cmd_cq_create(ctrl, cq, &adapter->tx_eq.q, false, true, 0))
+	if (be_cmd_cq_create(adapter, cq, &adapter->tx_eq.q, false, true, 0))
 		goto mcc_cq_free;
 
 	/* Alloc MCC queue */
-	q = &ctrl->mcc_obj.q;
+	q = &adapter->mcc_obj.q;
 	if (be_queue_alloc(adapter, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
 		goto mcc_cq_destroy;
 
 	/* Ask BE to create MCC queue */
-	if (be_cmd_mccq_create(ctrl, q, cq))
+	if (be_cmd_mccq_create(adapter, q, cq))
 		goto mcc_q_free;
 
 	return 0;
@@ -1075,7 +1137,7 @@ static int be_mcc_queues_create(struct be_adapter *adapter)
 mcc_q_free:
 	be_queue_free(adapter, q);
 mcc_cq_destroy:
-	be_cmd_q_destroy(ctrl, cq, QTYPE_CQ);
+	be_cmd_q_destroy(adapter, cq, QTYPE_CQ);
 mcc_cq_free:
 	be_queue_free(adapter, cq);
 err:
@@ -1087,23 +1149,21 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
 	struct be_queue_info *q;
 
 	q = &adapter->tx_obj.q;
-	if (q->created) {
-		be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ);
-
-		/* No more tx completions can be rcvd now; clean up if there
-		 * are any pending completions or pending tx requests */
-		be_tx_q_clean(adapter);
-	}
+	if (q->created)
+		be_cmd_q_destroy(adapter, q, QTYPE_TXQ);
 	be_queue_free(adapter, q);
 
 	q = &adapter->tx_obj.cq;
 	if (q->created)
-		be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ);
+		be_cmd_q_destroy(adapter, q, QTYPE_CQ);
 	be_queue_free(adapter, q);
 
+	/* Clear any residual events */
+	be_eq_clean(adapter, &adapter->tx_eq);
+
 	q = &adapter->tx_eq.q;
 	if (q->created)
-		be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ);
+		be_cmd_q_destroy(adapter, q, QTYPE_EQ);
 	be_queue_free(adapter, q);
 }
 
@@ -1121,7 +1181,7 @@ static int be_tx_queues_create(struct be_adapter *adapter)
 		return -1;
 
 	/* Ask BE to create Tx Event queue */
-	if (be_cmd_eq_create(&adapter->ctrl, eq, adapter->tx_eq.cur_eqd))
+	if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
 		goto tx_eq_free;
 	/* Alloc TX eth compl queue */
 	cq = &adapter->tx_obj.cq;
@@ -1130,7 +1190,7 @@ static int be_tx_queues_create(struct be_adapter *adapter)
 		goto tx_eq_destroy;
 
 	/* Ask BE to create Tx eth compl queue */
-	if (be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3))
+	if (be_cmd_cq_create(adapter, cq, eq, false, false, 3))
 		goto tx_cq_free;
 
 	/* Alloc TX eth queue */
@@ -1139,18 +1199,18 @@ static int be_tx_queues_create(struct be_adapter *adapter)
 		goto tx_cq_destroy;
 
 	/* Ask BE to create Tx eth queue */
-	if (be_cmd_txq_create(&adapter->ctrl, q, cq))
+	if (be_cmd_txq_create(adapter, q, cq))
 		goto tx_q_free;
 	return 0;
 
 tx_q_free:
 	be_queue_free(adapter, q);
 tx_cq_destroy:
-	be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ);
+	be_cmd_q_destroy(adapter, cq, QTYPE_CQ);
 tx_cq_free:
 	be_queue_free(adapter, cq);
 tx_eq_destroy:
-	be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ);
+	be_cmd_q_destroy(adapter, eq, QTYPE_EQ);
 tx_eq_free:
 	be_queue_free(adapter, eq);
 	return -1;
@@ -1162,19 +1222,22 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
 
 	q = &adapter->rx_obj.q;
 	if (q->created) {
-		be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_RXQ);
+		be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
 		be_rx_q_clean(adapter);
 	}
 	be_queue_free(adapter, q);
 
 	q = &adapter->rx_obj.cq;
 	if (q->created)
-		be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ);
+		be_cmd_q_destroy(adapter, q, QTYPE_CQ);
 	be_queue_free(adapter, q);
 
+	/* Clear any residual events */
+	be_eq_clean(adapter, &adapter->rx_eq);
+
 	q = &adapter->rx_eq.q;
 	if (q->created)
-		be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ);
+		be_cmd_q_destroy(adapter, q, QTYPE_EQ);
 	be_queue_free(adapter, q);
 }
 
@@ -1183,7 +1246,6 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 	struct be_queue_info *eq, *q, *cq;
 	int rc;
 
-	adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME;
 	adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
 	adapter->rx_eq.max_eqd = BE_MAX_EQD;
 	adapter->rx_eq.min_eqd = 0;
@@ -1198,7 +1260,7 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 		return rc;
 
 	/* Ask BE to create Rx Event queue */
-	rc = be_cmd_eq_create(&adapter->ctrl, eq, adapter->rx_eq.cur_eqd);
+	rc = be_cmd_eq_create(adapter, eq, adapter->rx_eq.cur_eqd);
 	if (rc)
 		goto rx_eq_free;
 
@@ -1210,7 +1272,7 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 		goto rx_eq_destroy;
 
 	/* Ask BE to create Rx eth compl queue */
-	rc = be_cmd_cq_create(&adapter->ctrl, cq, eq, false, false, 3);
+	rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3);
 	if (rc)
 		goto rx_cq_free;
 
@@ -1221,7 +1283,7 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 		goto rx_cq_destroy;
 
 	/* Ask BE to create Rx eth queue */
-	rc = be_cmd_rxq_create(&adapter->ctrl, q, cq->id, rx_frag_size,
+	rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size,
 		BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false);
 	if (rc)
 		goto rx_q_free;
@@ -1230,68 +1292,43 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 rx_q_free:
 	be_queue_free(adapter, q);
 rx_cq_destroy:
-	be_cmd_q_destroy(&adapter->ctrl, cq, QTYPE_CQ);
+	be_cmd_q_destroy(adapter, cq, QTYPE_CQ);
 rx_cq_free:
 	be_queue_free(adapter, cq);
 rx_eq_destroy:
-	be_cmd_q_destroy(&adapter->ctrl, eq, QTYPE_EQ);
+	be_cmd_q_destroy(adapter, eq, QTYPE_EQ);
 rx_eq_free:
 	be_queue_free(adapter, eq);
 	return rc;
 }
-static bool event_get(struct be_eq_obj *eq_obj, u16 *rid)
-{
-	struct be_eq_entry *entry = queue_tail_node(&eq_obj->q);
-	u32 evt = entry->evt;
-
-	if (!evt)
-		return false;
-
-	evt = le32_to_cpu(evt);
-	*rid = (evt >> EQ_ENTRY_RES_ID_SHIFT) & EQ_ENTRY_RES_ID_MASK;
-	entry->evt = 0;
-	queue_tail_inc(&eq_obj->q);
-	return true;
-}
 
-static int event_handle(struct be_ctrl_info *ctrl,
-			struct be_eq_obj *eq_obj)
+/* There are 8 evt ids per func. Retruns the evt id's bit number */
+static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id)
 {
-	u16 rid = 0, num = 0;
-
-	while (event_get(eq_obj, &rid))
-		num++;
-
-	/* We can see an interrupt and no event */
-	be_eq_notify(ctrl, eq_obj->q.id, true, true, num);
-	if (num)
-		napi_schedule(&eq_obj->napi);
-
-	return num;
+	return eq_id - 8 * be_pci_func(adapter);
 }
 
 static irqreturn_t be_intx(int irq, void *dev)
 {
 	struct be_adapter *adapter = dev;
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
-        int isr;
+	int isr;
 
-	isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
-                      ctrl->pci_func * CEV_ISR_SIZE);
+	isr = ioread32(adapter->csr + CEV_ISR0_OFFSET +
+			be_pci_func(adapter) * CEV_ISR_SIZE);
 	if (!isr)
-                return IRQ_NONE;
+		return IRQ_NONE;
 
-        event_handle(ctrl, &adapter->tx_eq);
-        event_handle(ctrl, &adapter->rx_eq);
+	event_handle(adapter, &adapter->tx_eq);
+	event_handle(adapter, &adapter->rx_eq);
 
-        return IRQ_HANDLED;
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t be_msix_rx(int irq, void *dev)
 {
 	struct be_adapter *adapter = dev;
 
-	event_handle(&adapter->ctrl, &adapter->rx_eq);
+	event_handle(adapter, &adapter->rx_eq);
 
 	return IRQ_HANDLED;
 }
@@ -1300,12 +1337,12 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
 {
 	struct be_adapter *adapter = dev;
 
-	event_handle(&adapter->ctrl, &adapter->tx_eq);
+	event_handle(adapter, &adapter->tx_eq);
 
 	return IRQ_HANDLED;
 }
 
-static inline bool do_lro(struct be_adapter *adapter,
+static inline bool do_gro(struct be_adapter *adapter,
 			struct be_eth_rx_compl *rxcp)
 {
 	int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp);
@@ -1314,8 +1351,7 @@ static inline bool do_lro(struct be_adapter *adapter,
 	if (err)
 		drvr_stats(adapter)->be_rxcp_err++;
 
-	return (!tcp_frame || err || (adapter->max_rx_coal <= 1)) ?
-		false : true;
+	return (tcp_frame && !err) ? true : false;
 }
 
 int be_poll_rx(struct napi_struct *napi, int budget)
@@ -1332,16 +1368,14 @@ int be_poll_rx(struct napi_struct *napi, int budget)
 		if (!rxcp)
 			break;
 
-		if (do_lro(adapter, rxcp))
-			be_rx_compl_process_lro(adapter, rxcp);
+		if (do_gro(adapter, rxcp))
+			be_rx_compl_process_gro(adapter, rxcp);
 		else
 			be_rx_compl_process(adapter, rxcp);
 
 		be_rx_compl_reset(rxcp);
 	}
 
-	lro_flush_all(&adapter->rx_obj.lro_mgr);
-
 	/* Refill the queue */
 	if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM)
 		be_post_rx_frags(adapter);
@@ -1349,10 +1383,10 @@ int be_poll_rx(struct napi_struct *napi, int budget)
 	/* All consumed */
 	if (work_done < budget) {
 		napi_complete(napi);
-		be_cq_notify(&adapter->ctrl, rx_cq->id, true, work_done);
+		be_cq_notify(adapter, rx_cq->id, true, work_done);
 	} else {
 		/* More to be consumed; continue with interrupts disabled */
-		be_cq_notify(&adapter->ctrl, rx_cq->id, false, work_done);
+		be_cq_notify(adapter, rx_cq->id, false, work_done);
 	}
 	return work_done;
 }
@@ -1373,7 +1407,7 @@ void be_process_tx(struct be_adapter *adapter)
 	}
 
 	if (num_cmpl) {
-		be_cq_notify(&adapter->ctrl, tx_cq->id, true, num_cmpl);
+		be_cq_notify(adapter, tx_cq->id, true, num_cmpl);
 
 		/* As Tx wrbs have been freed up, wake up netdev queue if
 		 * it was stopped due to lack of tx wrbs.
@@ -1401,7 +1435,7 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
 
 	be_process_tx(adapter);
 
-	be_process_mcc(&adapter->ctrl);
+	be_process_mcc(adapter);
 
 	return 1;
 }
@@ -1410,12 +1444,8 @@ static void be_worker(struct work_struct *work)
 {
 	struct be_adapter *adapter =
 		container_of(work, struct be_adapter, work.work);
-	int status;
 
-	/* Get Stats */
-	status = be_cmd_get_stats(&adapter->ctrl, &adapter->stats.cmd);
-	if (!status)
-		netdev_stats_update(adapter);
+	be_cmd_get_stats(adapter, &adapter->stats.cmd);
 
 	/* Set EQ delay */
 	be_rx_eqd_update(adapter);
@@ -1447,32 +1477,44 @@ static void be_msix_enable(struct be_adapter *adapter)
 
 static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id)
 {
-	return adapter->msix_entries[eq_id -
-			8 * adapter->ctrl.pci_func].vector;
+	return adapter->msix_entries[
+			be_evt_bit_get(adapter, eq_id)].vector;
 }
 
-static int be_msix_register(struct be_adapter *adapter)
+static int be_request_irq(struct be_adapter *adapter,
+		struct be_eq_obj *eq_obj,
+		void *handler, char *desc)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct be_eq_obj *tx_eq = &adapter->tx_eq;
-	struct be_eq_obj *rx_eq = &adapter->rx_eq;
-	int status, vec;
+	int vec;
+
+	sprintf(eq_obj->desc, "%s-%s", netdev->name, desc);
+	vec = be_msix_vec_get(adapter, eq_obj->q.id);
+	return request_irq(vec, handler, 0, eq_obj->desc, adapter);
+}
+
+static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj)
+{
+	int vec = be_msix_vec_get(adapter, eq_obj->q.id);
+	free_irq(vec, adapter);
+}
 
-	sprintf(tx_eq->desc, "%s-tx", netdev->name);
-	vec = be_msix_vec_get(adapter, tx_eq->q.id);
-	status = request_irq(vec, be_msix_tx_mcc, 0, tx_eq->desc, adapter);
+static int be_msix_register(struct be_adapter *adapter)
+{
+	int status;
+
+	status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx");
 	if (status)
 		goto err;
 
-	sprintf(rx_eq->desc, "%s-rx", netdev->name);
-	vec = be_msix_vec_get(adapter, rx_eq->q.id);
-	status = request_irq(vec, be_msix_rx, 0, rx_eq->desc, adapter);
-	if (status) { /* Free TX IRQ */
-		vec = be_msix_vec_get(adapter, tx_eq->q.id);
-		free_irq(vec, adapter);
-		goto err;
-	}
+	status = be_request_irq(adapter, &adapter->rx_eq, be_msix_rx, "rx");
+	if (status)
+		goto free_tx_irq;
+
 	return 0;
+
+free_tx_irq:
+	be_free_irq(adapter, &adapter->tx_eq);
 err:
 	dev_warn(&adapter->pdev->dev,
 		"MSIX Request IRQ failed - err %d\n", status);
@@ -1509,7 +1551,6 @@ done:
 static void be_irq_unregister(struct be_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	int vec;
 
 	if (!adapter->isr_registered)
 		return;
@@ -1521,10 +1562,8 @@ static void be_irq_unregister(struct be_adapter *adapter)
 	}
 
 	/* MSIx */
-	vec = be_msix_vec_get(adapter, adapter->tx_eq.q.id);
-	free_irq(vec, adapter);
-	vec = be_msix_vec_get(adapter, adapter->rx_eq.q.id);
-	free_irq(vec, adapter);
+	be_free_irq(adapter, &adapter->tx_eq);
+	be_free_irq(adapter, &adapter->rx_eq);
 done:
 	adapter->isr_registered = false;
 	return;
@@ -1533,7 +1572,6 @@ done:
 static int be_open(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 	struct be_eq_obj *rx_eq = &adapter->rx_eq;
 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
 	bool link_up;
@@ -1547,16 +1585,16 @@ static int be_open(struct net_device *netdev)
 
 	be_irq_register(adapter);
 
-	be_intr_set(ctrl, true);
+	be_intr_set(adapter, true);
 
 	/* The evt queues are created in unarmed state; arm them */
-	be_eq_notify(ctrl, rx_eq->q.id, true, false, 0);
-	be_eq_notify(ctrl, tx_eq->q.id, true, false, 0);
+	be_eq_notify(adapter, rx_eq->q.id, true, false, 0);
+	be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
 
 	/* Rx compl queue may be in unarmed state; rearm it */
-	be_cq_notify(ctrl, adapter->rx_obj.cq.id, true, 0);
+	be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
 
-	status = be_cmd_link_status_query(ctrl, &link_up);
+	status = be_cmd_link_status_query(adapter, &link_up);
 	if (status)
 		return status;
 	be_link_status_update(adapter, link_up);
@@ -1567,7 +1605,6 @@ static int be_open(struct net_device *netdev)
 
 static int be_setup(struct be_adapter *adapter)
 {
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 	struct net_device *netdev = adapter->netdev;
 	u32 if_flags;
 	int status;
@@ -1575,17 +1612,12 @@ static int be_setup(struct be_adapter *adapter)
 	if_flags = BE_IF_FLAGS_BROADCAST | BE_IF_FLAGS_PROMISCUOUS |
 		BE_IF_FLAGS_MCAST_PROMISCUOUS | BE_IF_FLAGS_UNTAGGED |
 		BE_IF_FLAGS_PASS_L3L4_ERRORS;
-	status = be_cmd_if_create(ctrl, if_flags, netdev->dev_addr,
+	status = be_cmd_if_create(adapter, if_flags, netdev->dev_addr,
 			false/* pmac_invalid */, &adapter->if_handle,
 			&adapter->pmac_id);
 	if (status != 0)
 		goto do_none;
 
-	be_vid_config(netdev);
-
-	status = be_cmd_set_flow_control(ctrl, true, true);
-	if (status != 0)
-		goto if_destroy;
 
 	status = be_tx_queues_create(adapter);
 	if (status != 0)
@@ -1599,35 +1631,41 @@ static int be_setup(struct be_adapter *adapter)
 	if (status != 0)
 		goto rx_qs_destroy;
 
+	status = be_vid_config(adapter);
+	if (status != 0)
+		goto mccqs_destroy;
+
+	status = be_cmd_set_flow_control(adapter, true, true);
+	if (status != 0)
+		goto mccqs_destroy;
 	return 0;
 
+mccqs_destroy:
+	be_mcc_queues_destroy(adapter);
 rx_qs_destroy:
 	be_rx_queues_destroy(adapter);
 tx_qs_destroy:
 	be_tx_queues_destroy(adapter);
 if_destroy:
-	be_cmd_if_destroy(ctrl, adapter->if_handle);
+	be_cmd_if_destroy(adapter, adapter->if_handle);
 do_none:
 	return status;
 }
 
 static int be_clear(struct be_adapter *adapter)
 {
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
-
+	be_mcc_queues_destroy(adapter);
 	be_rx_queues_destroy(adapter);
 	be_tx_queues_destroy(adapter);
 
-	be_cmd_if_destroy(ctrl, adapter->if_handle);
+	be_cmd_if_destroy(adapter, adapter->if_handle);
 
-	be_mcc_queues_destroy(adapter);
 	return 0;
 }
 
 static int be_close(struct net_device *netdev)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 	struct be_eq_obj *rx_eq = &adapter->rx_eq;
 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
 	int vec;
@@ -1638,7 +1676,7 @@ static int be_close(struct net_device *netdev)
 	netif_carrier_off(netdev);
 	adapter->link_up = false;
 
-	be_intr_set(ctrl, false);
+	be_intr_set(adapter, false);
 
 	if (adapter->msix_enabled) {
 		vec = be_msix_vec_get(adapter, tx_eq->q.id);
@@ -1653,58 +1691,179 @@ static int be_close(struct net_device *netdev)
 	napi_disable(&rx_eq->napi);
 	napi_disable(&tx_eq->napi);
 
+	/* Wait for all pending tx completions to arrive so that
+	 * all tx skbs are freed.
+	 */
+	be_tx_compl_clean(adapter);
+
 	return 0;
 }
 
-static int be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
-				void **ip_hdr, void **tcpudp_hdr,
-				u64 *hdr_flags, void *priv)
+#define FW_FILE_HDR_SIGN 	"ServerEngines Corp. "
+char flash_cookie[2][16] =	{"*** SE FLAS",
+				"H DIRECTORY *** "};
+static int be_flash_image(struct be_adapter *adapter,
+			const struct firmware *fw,
+			struct be_dma_mem *flash_cmd, u32 flash_type)
 {
-	struct ethhdr *eh;
-	struct vlan_ethhdr *veh;
-	struct iphdr *iph;
-	u8 *va = page_address(frag->page) + frag->page_offset;
-	unsigned long ll_hlen;
+	int status;
+	u32 flash_op, image_offset = 0, total_bytes, image_size = 0;
+	int num_bytes;
+	const u8 *p = fw->data;
+	struct be_cmd_write_flashrom *req = flash_cmd->va;
+
+	switch (flash_type) {
+	case FLASHROM_TYPE_ISCSI_ACTIVE:
+		image_offset = FLASH_iSCSI_PRIMARY_IMAGE_START;
+		image_size = FLASH_IMAGE_MAX_SIZE;
+		break;
+	case FLASHROM_TYPE_ISCSI_BACKUP:
+		image_offset = FLASH_iSCSI_BACKUP_IMAGE_START;
+		image_size = FLASH_IMAGE_MAX_SIZE;
+		break;
+	case FLASHROM_TYPE_FCOE_FW_ACTIVE:
+		image_offset = FLASH_FCoE_PRIMARY_IMAGE_START;
+		image_size = FLASH_IMAGE_MAX_SIZE;
+		break;
+	case FLASHROM_TYPE_FCOE_FW_BACKUP:
+		image_offset = FLASH_FCoE_BACKUP_IMAGE_START;
+		image_size = FLASH_IMAGE_MAX_SIZE;
+		break;
+	case FLASHROM_TYPE_BIOS:
+		image_offset = FLASH_iSCSI_BIOS_START;
+		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
+		break;
+	case FLASHROM_TYPE_FCOE_BIOS:
+		image_offset = FLASH_FCoE_BIOS_START;
+		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
+		break;
+	case FLASHROM_TYPE_PXE_BIOS:
+		image_offset = FLASH_PXE_BIOS_START;
+		image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
+		break;
+	default:
+		return 0;
+	}
 
-	prefetch(va);
-	eh = (struct ethhdr *)va;
-	*mac_hdr = eh;
-	ll_hlen = ETH_HLEN;
-	if (eh->h_proto != htons(ETH_P_IP)) {
-		if (eh->h_proto == htons(ETH_P_8021Q)) {
-			veh = (struct vlan_ethhdr *)va;
-			if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
-				return -1;
+	p += sizeof(struct flash_file_hdr) + image_offset;
+	if (p + image_size > fw->data + fw->size)
+		return -1;
 
-			ll_hlen += VLAN_HLEN;
-		} else {
+	total_bytes = image_size;
+
+	while (total_bytes) {
+		if (total_bytes > 32*1024)
+			num_bytes = 32*1024;
+		else
+			num_bytes = total_bytes;
+		total_bytes -= num_bytes;
+
+		if (!total_bytes)
+			flash_op = FLASHROM_OPER_FLASH;
+		else
+			flash_op = FLASHROM_OPER_SAVE;
+		memcpy(req->params.data_buf, p, num_bytes);
+		p += num_bytes;
+		status = be_cmd_write_flashrom(adapter, flash_cmd,
+				flash_type, flash_op, num_bytes);
+		if (status) {
+			dev_err(&adapter->pdev->dev,
+			"cmd to write to flash rom failed. type/op %d/%d\n",
+			flash_type, flash_op);
 			return -1;
 		}
+		yield();
 	}
-	*hdr_flags = LRO_IPV4;
-	iph = (struct iphdr *)(va + ll_hlen);
-	*ip_hdr = iph;
-	if (iph->protocol != IPPROTO_TCP)
-		return -1;
-	*hdr_flags |= LRO_TCP;
-	*tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
 
 	return 0;
 }
 
-static void be_lro_init(struct be_adapter *adapter, struct net_device *netdev)
+int be_load_fw(struct be_adapter *adapter, u8 *func)
 {
-	struct net_lro_mgr *lro_mgr;
+	char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
+	const struct firmware *fw;
+	struct flash_file_hdr *fhdr;
+	struct flash_section_info *fsec = NULL;
+	struct be_dma_mem flash_cmd;
+	int status;
+	const u8 *p;
+	bool entry_found = false;
+	int flash_type;
+	char fw_ver[FW_VER_LEN];
+	char fw_cfg;
+
+	status = be_cmd_get_fw_ver(adapter, fw_ver);
+	if (status)
+		return status;
+
+	fw_cfg = *(fw_ver + 2);
+	if (fw_cfg == '0')
+		fw_cfg = '1';
+	strcpy(fw_file, func);
 
-	lro_mgr = &adapter->rx_obj.lro_mgr;
-	lro_mgr->dev = netdev;
-	lro_mgr->features = LRO_F_NAPI;
-	lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
-	lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
-	lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS;
-	lro_mgr->lro_arr = adapter->rx_obj.lro_desc;
-	lro_mgr->get_frag_header = be_get_frag_header;
-	lro_mgr->max_aggr = BE_MAX_FRAGS_PER_FRAME;
+	status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
+	if (status)
+		goto fw_exit;
+
+	p = fw->data;
+	fhdr = (struct flash_file_hdr *) p;
+	if (memcmp(fhdr->sign, FW_FILE_HDR_SIGN, strlen(FW_FILE_HDR_SIGN))) {
+		dev_err(&adapter->pdev->dev,
+			"Firmware(%s) load error (signature did not match)\n",
+				fw_file);
+		status = -1;
+		goto fw_exit;
+	}
+
+	dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
+
+	p += sizeof(struct flash_file_hdr);
+	while (p < (fw->data + fw->size)) {
+		fsec = (struct flash_section_info *)p;
+		if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie))) {
+			entry_found = true;
+			break;
+		}
+		p += 32;
+	}
+
+	if (!entry_found) {
+		status = -1;
+		dev_err(&adapter->pdev->dev,
+			"Flash cookie not found in firmware image\n");
+		goto fw_exit;
+	}
+
+	flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
+	flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size,
+					&flash_cmd.dma);
+	if (!flash_cmd.va) {
+		status = -ENOMEM;
+		dev_err(&adapter->pdev->dev,
+			"Memory allocation failure while flashing\n");
+		goto fw_exit;
+	}
+
+	for (flash_type = FLASHROM_TYPE_ISCSI_ACTIVE;
+		flash_type <= FLASHROM_TYPE_FCOE_FW_BACKUP; flash_type++) {
+		status = be_flash_image(adapter, fw, &flash_cmd,
+				flash_type);
+		if (status)
+			break;
+	}
+
+	pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va,
+				flash_cmd.dma);
+	if (status) {
+		dev_err(&adapter->pdev->dev, "Firmware load error\n");
+		goto fw_exit;
+	}
+
+	dev_info(&adapter->pdev->dev, "Firmware flashed succesfully\n");
+
+fw_exit:
+	release_firmware(fw);
+	return status;
 }
 
 static struct net_device_ops be_netdev_ops = {
@@ -1727,18 +1886,18 @@ static void be_netdev_init(struct net_device *netdev)
 
 	netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
 		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM |
-		NETIF_F_IPV6_CSUM;
+		NETIF_F_IPV6_CSUM | NETIF_F_GRO;
 
 	netdev->flags |= IFF_MULTICAST;
 
 	adapter->rx_csum = true;
 
+	netif_set_gso_max_size(netdev, 65535);
+
 	BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
 
 	SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
 
-	be_lro_init(adapter, netdev);
-
 	netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx,
 		BE_NAPI_WEIGHT);
 	netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
@@ -1750,13 +1909,12 @@ static void be_netdev_init(struct net_device *netdev)
 
 static void be_unmap_pci_bars(struct be_adapter *adapter)
 {
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
-	if (ctrl->csr)
-		iounmap(ctrl->csr);
-	if (ctrl->db)
-		iounmap(ctrl->db);
-	if (ctrl->pcicfg)
-		iounmap(ctrl->pcicfg);
+	if (adapter->csr)
+		iounmap(adapter->csr);
+	if (adapter->db)
+		iounmap(adapter->db);
+	if (adapter->pcicfg)
+		iounmap(adapter->pcicfg);
 }
 
 static int be_map_pci_bars(struct be_adapter *adapter)
@@ -1767,19 +1925,19 @@ static int be_map_pci_bars(struct be_adapter *adapter)
 			pci_resource_len(adapter->pdev, 2));
 	if (addr == NULL)
 		return -ENOMEM;
-	adapter->ctrl.csr = addr;
+	adapter->csr = addr;
 
 	addr = ioremap_nocache(pci_resource_start(adapter->pdev, 4),
 			128 * 1024);
 	if (addr == NULL)
 		goto pci_map_err;
-	adapter->ctrl.db = addr;
+	adapter->db = addr;
 
 	addr = ioremap_nocache(pci_resource_start(adapter->pdev, 1),
 			pci_resource_len(adapter->pdev, 1));
 	if (addr == NULL)
 		goto pci_map_err;
-	adapter->ctrl.pcicfg = addr;
+	adapter->pcicfg = addr;
 
 	return 0;
 pci_map_err:
@@ -1790,7 +1948,7 @@ pci_map_err:
 
 static void be_ctrl_cleanup(struct be_adapter *adapter)
 {
-	struct be_dma_mem *mem = &adapter->ctrl.mbox_mem_alloced;
+	struct be_dma_mem *mem = &adapter->mbox_mem_alloced;
 
 	be_unmap_pci_bars(adapter);
 
@@ -1799,14 +1957,11 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
 			mem->va, mem->dma);
 }
 
-/* Initialize the mbox required to send cmds to BE */
 static int be_ctrl_init(struct be_adapter *adapter)
 {
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
-	struct be_dma_mem *mbox_mem_alloc = &ctrl->mbox_mem_alloced;
-	struct be_dma_mem *mbox_mem_align = &ctrl->mbox_mem;
+	struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
+	struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
 	int status;
-	u32 val;
 
 	status = be_map_pci_bars(adapter);
 	if (status)
@@ -1823,16 +1978,10 @@ static int be_ctrl_init(struct be_adapter *adapter)
 	mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
 	mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
 	memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
-	spin_lock_init(&ctrl->mbox_lock);
-	spin_lock_init(&ctrl->mcc_lock);
-	spin_lock_init(&ctrl->mcc_cq_lock);
-
-	ctrl->async_cb = be_link_status_update;
-	ctrl->adapter_ctxt = adapter;
+	spin_lock_init(&adapter->mbox_lock);
+	spin_lock_init(&adapter->mcc_lock);
+	spin_lock_init(&adapter->mcc_cq_lock);
 
-	val = ioread32(ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
-	ctrl->pci_func = (val >> MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT) &
-					MEMBAR_CTRL_INT_CTRL_PFUNC_MASK;
 	return 0;
 }
 
@@ -1886,18 +2035,17 @@ static void __devexit be_remove(struct pci_dev *pdev)
 
 static int be_hw_up(struct be_adapter *adapter)
 {
-	struct be_ctrl_info *ctrl = &adapter->ctrl;
 	int status;
 
-	status = be_cmd_POST(ctrl);
+	status = be_cmd_POST(adapter);
 	if (status)
 		return status;
 
-	status = be_cmd_get_fw_ver(ctrl, adapter->fw_ver);
+	status = be_cmd_get_fw_ver(adapter, adapter->fw_ver);
 	if (status)
 		return status;
 
-	status = be_cmd_query_fw_cfg(ctrl, &adapter->port_num);
+	status = be_cmd_query_fw_cfg(adapter, &adapter->port_num);
 	return status;
 }
 
@@ -1907,7 +2055,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
 	int status = 0;
 	struct be_adapter *adapter;
 	struct net_device *netdev;
-	struct be_ctrl_info *ctrl;
 	u8 mac[ETH_ALEN];
 
 	status = pci_enable_device(pdev);
@@ -1942,11 +2089,14 @@ static int __devinit be_probe(struct pci_dev *pdev,
 		}
 	}
 
-	ctrl = &adapter->ctrl;
 	status = be_ctrl_init(adapter);
 	if (status)
 		goto free_netdev;
 
+	status = be_cmd_reset_function(adapter);
+	if (status)
+		goto ctrl_clean;
+
 	status = be_stats_init(adapter);
 	if (status)
 		goto ctrl_clean;
@@ -1955,7 +2105,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
 	if (status)
 		goto stats_clean;
 
-	status = be_cmd_mac_addr_query(ctrl, mac, MAC_ADDRESS_TYPE_NETWORK,
+	status = be_cmd_mac_addr_query(adapter, mac, MAC_ADDRESS_TYPE_NETWORK,
 			true /* permanent */, 0);
 	if (status)
 		goto stats_clean;
@@ -2001,9 +2151,9 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
 	if (netif_running(netdev)) {
 		rtnl_lock();
 		be_close(netdev);
-		be_clear(adapter);
 		rtnl_unlock();
 	}
+	be_clear(adapter);
 
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
@@ -2026,9 +2176,9 @@ static int be_resume(struct pci_dev *pdev)
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
 
+	be_setup(adapter);
 	if (netif_running(netdev)) {
 		rtnl_lock();
-		be_setup(adapter);
 		be_open(netdev);
 		rtnl_unlock();
 	}
@@ -2054,12 +2204,6 @@ static int __init be_init_module(void)
 			" Using 2048\n");
 		rx_frag_size = 2048;
 	}
-	/* Ensure rx_frag_size is aligned to chache line */
-	if (SKB_DATA_ALIGN(rx_frag_size) != rx_frag_size) {
-		printk(KERN_WARNING DRV_NAME
-			" : Bad module param rx_frag_size. Using 2048\n");
-		rx_frag_size = 2048;
-	}
 
 	return pci_register_driver(&be_driver);
 }
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index c15fc28..14bd380 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -491,7 +491,7 @@ static void bfin_mac_ethtool_getdrvinfo(struct net_device *dev,
 	strcpy(info->bus_info, dev_name(&dev->dev));
 }
 
-static struct ethtool_ops bfin_mac_ethtool_ops = {
+static const struct ethtool_ops bfin_mac_ethtool_ops = {
 	.get_settings = bfin_mac_ethtool_getsettings,
 	.set_settings = bfin_mac_ethtool_setsettings,
 	.get_link = ethtool_op_get_link,
@@ -656,7 +656,7 @@ out:
 	dev->trans_start = jiffies;
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += (skb->len);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void bfin_mac_rx(struct net_device *dev)
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 206144f..406f064 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1489,7 +1489,7 @@ bmac_output(struct sk_buff *skb, struct net_device *dev)
 	struct bmac_data *bp = netdev_priv(dev);
 	skb_queue_tail(bp->queue, skb);
 	bmac_start(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void bmac_tx_timeout(unsigned long data)
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 06b9011..08cddb6 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -59,12 +59,13 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"2.0.1"
-#define DRV_MODULE_RELDATE	"May 6, 2009"
-#define FW_MIPS_FILE_06		"bnx2/bnx2-mips-06-4.6.16.fw"
-#define FW_RV2P_FILE_06		"bnx2/bnx2-rv2p-06-4.6.16.fw"
-#define FW_MIPS_FILE_09		"bnx2/bnx2-mips-09-4.6.17.fw"
-#define FW_RV2P_FILE_09		"bnx2/bnx2-rv2p-09-4.6.15.fw"
+#define DRV_MODULE_VERSION	"2.0.2"
+#define DRV_MODULE_RELDATE	"Aug 21, 2009"
+#define FW_MIPS_FILE_06		"bnx2/bnx2-mips-06-5.0.0.j3.fw"
+#define FW_RV2P_FILE_06		"bnx2/bnx2-rv2p-06-5.0.0.j3.fw"
+#define FW_MIPS_FILE_09		"bnx2/bnx2-mips-09-5.0.0.j3.fw"
+#define FW_RV2P_FILE_09_Ax	"bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw"
+#define FW_RV2P_FILE_09		"bnx2/bnx2-rv2p-09-5.0.0.j3.fw"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -82,6 +83,7 @@ MODULE_FIRMWARE(FW_MIPS_FILE_06);
 MODULE_FIRMWARE(FW_RV2P_FILE_06);
 MODULE_FIRMWARE(FW_MIPS_FILE_09);
 MODULE_FIRMWARE(FW_RV2P_FILE_09);
+MODULE_FIRMWARE(FW_RV2P_FILE_09_Ax);
 
 static int disable_msi = 0;
 
@@ -145,7 +147,7 @@ static DEFINE_PCI_DEVICE_TABLE(bnx2_pci_tbl) = {
 	{ 0, }
 };
 
-static struct flash_spec flash_table[] =
+static const struct flash_spec flash_table[] =
 {
 #define BUFFERED_FLAGS		(BNX2_NV_BUFFERED | BNX2_NV_TRANSLATE)
 #define NONBUFFERED_FLAGS	(BNX2_NV_WREN)
@@ -234,7 +236,7 @@ static struct flash_spec flash_table[] =
 	 "Buffered flash (256kB)"},
 };
 
-static struct flash_spec flash_5709 = {
+static const struct flash_spec flash_5709 = {
 	.flags		= BNX2_NV_BUFFERED,
 	.page_bits	= BCM5709_FLASH_PAGE_BITS,
 	.page_size	= BCM5709_FLASH_PAGE_SIZE,
@@ -621,6 +623,9 @@ bnx2_disable_int_sync(struct bnx2 *bp)
 	int i;
 
 	atomic_inc(&bp->intr_sem);
+	if (!netif_running(bp->dev))
+		return;
+
 	bnx2_disable_int(bp);
 	for (i = 0; i < bp->irq_nvecs; i++)
 		synchronize_irq(bp->irq_tbl[i].vector);
@@ -3620,7 +3625,11 @@ bnx2_request_firmware(struct bnx2 *bp)
 
 	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 		mips_fw_file = FW_MIPS_FILE_09;
-		rv2p_fw_file = FW_RV2P_FILE_09;
+		if ((CHIP_ID(bp) == CHIP_ID_5709_A0) ||
+		    (CHIP_ID(bp) == CHIP_ID_5709_A1))
+			rv2p_fw_file = FW_RV2P_FILE_09_Ax;
+		else
+			rv2p_fw_file = FW_RV2P_FILE_09;
 	} else {
 		mips_fw_file = FW_MIPS_FILE_06;
 		rv2p_fw_file = FW_RV2P_FILE_06;
@@ -4226,7 +4235,7 @@ bnx2_init_nvram(struct bnx2 *bp)
 {
 	u32 val;
 	int j, entry_count, rc = 0;
-	struct flash_spec *flash;
+	const struct flash_spec *flash;
 
 	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 		bp->flash_info = &flash_5709;
@@ -4860,6 +4869,7 @@ bnx2_init_chip(struct bnx2 *bp)
 	bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG2, BNX2_RBUF_CONFIG2_VAL(mtu));
 	bnx2_reg_wr_ind(bp, BNX2_RBUF_CONFIG3, BNX2_RBUF_CONFIG3_VAL(mtu));
 
+	memset(bp->bnx2_napi[0].status_blk.msi, 0, bp->status_stats_size);
 	for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
 		bp->bnx2_napi[i].last_status_idx = 0;
 
@@ -4898,7 +4908,7 @@ bnx2_init_chip(struct bnx2 *bp)
 	REG_WR(bp, BNX2_HC_CMD_TICKS,
 	       (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
 
-	if (CHIP_NUM(bp) == CHIP_NUM_5708)
+	if (bp->flags & BNX2_FLAG_BROKEN_STATS)
 		REG_WR(bp, BNX2_HC_STATS_TICKS, 0);
 	else
 		REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks);
@@ -4919,7 +4929,7 @@ bnx2_init_chip(struct bnx2 *bp)
 	}
 
 	if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
-		val |= BNX2_HC_CONFIG_ONE_SHOT;
+		val |= BNX2_HC_CONFIG_ONE_SHOT | BNX2_HC_CONFIG_USE_INT_PARAM;
 
 	REG_WR(bp, BNX2_HC_CONFIG, val);
 
@@ -6023,7 +6033,7 @@ bnx2_timer(unsigned long data)
 		bnx2_reg_rd_ind(bp, BNX2_FW_RX_DROP_COUNT);
 
 	/* workaround occasional corrupted counters */
-	if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks)
+	if ((bp->flags & BNX2_FLAG_BROKEN_STATS) && bp->stats_ticks)
 		REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
 					    BNX2_HC_COMMAND_STATS_NOW);
 
@@ -6255,9 +6265,14 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
 {
 	struct bnx2 *bp = netdev_priv(dev);
 
-	bnx2_netif_stop(bp);
+	if (netif_running(dev))
+		bnx2_netif_stop(bp);
 
 	bp->vlgrp = vlgrp;
+
+	if (!netif_running(dev))
+		return;
+
 	bnx2_set_rx_mode(dev);
 	if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
 		bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
@@ -6270,7 +6285,7 @@ bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp)
  * bnx2_tx_int() runs without netif_tx_lock unless it needs to call
  * netif_wake_queue().
  */
-static int
+static netdev_tx_t
 bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bnx2 *bp = netdev_priv(dev);
@@ -6478,7 +6493,8 @@ bnx2_get_stats(struct net_device *dev)
 		stats_blk->stat_EtherStatsOverrsizePkts);
 
 	net_stats->rx_over_errors =
-		(unsigned long) stats_blk->stat_IfInMBUFDiscards;
+		(unsigned long) (stats_blk->stat_IfInFTQDiscards +
+		stats_blk->stat_IfInMBUFDiscards);
 
 	net_stats->rx_frame_errors =
 		(unsigned long) stats_blk->stat_Dot3StatsAlignmentErrors;
@@ -6511,8 +6527,8 @@ bnx2_get_stats(struct net_device *dev)
 		net_stats->tx_carrier_errors;
 
 	net_stats->rx_missed_errors =
-		(unsigned long) (stats_blk->stat_IfInMBUFDiscards +
-		stats_blk->stat_FwRxDrop);
+		(unsigned long) (stats_blk->stat_IfInFTQDiscards +
+		stats_blk->stat_IfInMBUFDiscards + stats_blk->stat_FwRxDrop);
 
 	return net_stats;
 }
@@ -6934,7 +6950,7 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal)
 		0xff;
 
 	bp->stats_ticks = coal->stats_block_coalesce_usecs;
-	if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+	if (bp->flags & BNX2_FLAG_BROKEN_STATS) {
 		if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC)
 			bp->stats_ticks = USEC_PER_SEC;
 	}
@@ -6985,9 +7001,14 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
 		int rc;
 
 		rc = bnx2_alloc_mem(bp);
-		if (rc)
+		if (!rc)
+			rc = bnx2_init_nic(bp, 0);
+
+		if (rc) {
+			bnx2_napi_enable(bp);
+			dev_close(bp->dev);
 			return rc;
-		bnx2_init_nic(bp, 0);
+		}
 		bnx2_netif_start(bp);
 	}
 	return 0;
@@ -7078,11 +7099,9 @@ bnx2_set_tso(struct net_device *dev, u32 data)
 	return 0;
 }
 
-#define BNX2_NUM_STATS 46
-
 static struct {
 	char string[ETH_GSTRING_LEN];
-} bnx2_stats_str_arr[BNX2_NUM_STATS] = {
+} bnx2_stats_str_arr[] = {
 	{ "rx_bytes" },
 	{ "rx_error_bytes" },
 	{ "tx_bytes" },
@@ -7127,10 +7146,14 @@ static struct {
 	{ "tx_xoff_frames" },
 	{ "rx_mac_ctrl_frames" },
 	{ "rx_filtered_packets" },
+	{ "rx_ftq_discards" },
 	{ "rx_discards" },
 	{ "rx_fw_discards" },
 };
 
+#define BNX2_NUM_STATS (sizeof(bnx2_stats_str_arr)/\
+			sizeof(bnx2_stats_str_arr[0]))
+
 #define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4)
 
 static const unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
@@ -7178,6 +7201,7 @@ static const unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
     STATS_OFFSET32(stat_OutXoffSent),
     STATS_OFFSET32(stat_MacControlFramesReceived),
     STATS_OFFSET32(stat_IfInFramesL2FilterDiscards),
+    STATS_OFFSET32(stat_IfInFTQDiscards),
     STATS_OFFSET32(stat_IfInMBUFDiscards),
     STATS_OFFSET32(stat_FwRxDrop),
 };
@@ -7190,7 +7214,7 @@ static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
 	4,0,4,4,4,4,4,4,4,4,
 	4,4,4,4,4,4,4,4,4,4,
 	4,4,4,4,4,4,4,4,4,4,
-	4,4,4,4,4,4,
+	4,4,4,4,4,4,4,
 };
 
 static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
@@ -7198,7 +7222,7 @@ static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
 	4,4,4,4,4,4,4,4,4,4,
 	4,4,4,4,4,4,4,4,4,4,
 	4,4,4,4,4,4,4,4,4,4,
-	4,4,4,4,4,4,
+	4,4,4,4,4,4,4,
 };
 
 #define BNX2_NUM_TESTS 6
@@ -7456,9 +7480,6 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	}
 
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
 			return -EOPNOTSUPP;
 
@@ -7713,6 +7734,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 			rc = -EIO;
 			goto err_out_unmap;
 		}
+		bp->flags |= BNX2_FLAG_BROKEN_STATS;
 	}
 
 	if (CHIP_NUM(bp) == CHIP_NUM_5709 && CHIP_REV(bp) != CHIP_REV_Ax) {
@@ -7844,13 +7866,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 
 	bp->rx_csum = 1;
 
-	bp->tx_quick_cons_trip_int = 20;
+	bp->tx_quick_cons_trip_int = 2;
 	bp->tx_quick_cons_trip = 20;
-	bp->tx_ticks_int = 80;
+	bp->tx_ticks_int = 18;
 	bp->tx_ticks = 80;
 
-	bp->rx_quick_cons_trip_int = 6;
-	bp->rx_quick_cons_trip = 6;
+	bp->rx_quick_cons_trip_int = 2;
+	bp->rx_quick_cons_trip = 12;
 	bp->rx_ticks_int = 18;
 	bp->rx_ticks = 18;
 
@@ -8028,6 +8050,13 @@ static const struct net_device_ops bnx2_netdev_ops = {
 #endif
 };
 
+static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
+{
+#ifdef BCM_VLAN
+	dev->vlan_features |= flags;
+#endif
+}
+
 static int __devinit
 bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -8069,16 +8098,20 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	memcpy(dev->perm_addr, bp->mac_addr, 6);
 
 	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-	if (CHIP_NUM(bp) == CHIP_NUM_5709)
+	vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG);
+	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 		dev->features |= NETIF_F_IPV6_CSUM;
-
+		vlan_features_add(dev, NETIF_F_IPV6_CSUM);
+	}
 #ifdef BCM_VLAN
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 #endif
 	dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
-	if (CHIP_NUM(bp) == CHIP_NUM_5709)
+	vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN);
+	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
 		dev->features |= NETIF_F_TSO6;
-
+		vlan_features_add(dev, NETIF_F_TSO6);
+	}
 	if ((rc = register_netdev(dev))) {
 		dev_err(&pdev->dev, "Cannot register net device\n");
 		goto error;
@@ -8193,6 +8226,11 @@ static pci_ers_result_t bnx2_io_error_detected(struct pci_dev *pdev,
 	rtnl_lock();
 	netif_device_detach(dev);
 
+	if (state == pci_channel_io_perm_failure) {
+		rtnl_unlock();
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
 	if (netif_running(dev)) {
 		bnx2_netif_stop(bp);
 		del_timer_sync(&bp->timer);
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index a4f12fd..6c7f795 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -6718,6 +6718,7 @@ struct bnx2 {
 					 BNX2_FLAG_USING_MSIX)
 #define BNX2_FLAG_JUMBO_BROKEN		0x00000800
 #define BNX2_FLAG_CAN_KEEP_VLAN		0x00001000
+#define BNX2_FLAG_BROKEN_STATS		0x00002000
 
 	struct bnx2_napi	bnx2_napi[BNX2_MAX_MSIX_VEC];
 
@@ -6888,7 +6889,7 @@ struct bnx2 {
 	int			pm_cap;
 	int			pcix_cap;
 
-	struct flash_spec	*flash_info;
+	const struct flash_spec	*flash_info;
 	u32			flash_size;
 
 	int			status_stats_size;
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index 85a737c..bbf8422 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -30,6 +30,8 @@
 #define BNX2X_NEW_NAPI
 
 
+
+#include <linux/mdio.h>
 #include "bnx2x_reg.h"
 #include "bnx2x_fw_defs.h"
 #include "bnx2x_hsi.h"
@@ -87,6 +89,7 @@
 	} while (0)
 #else
 #define bnx2x_panic() do { \
+		bp->panic = 1; \
 		BNX2X_ERR("driver assert\n"); \
 		bnx2x_panic_dump(bp); \
 	} while (0)
@@ -113,21 +116,32 @@
 #define REG_RD_DMAE(bp, offset, valp, len32) \
 	do { \
 		bnx2x_read_dmae(bp, offset, len32);\
-		memcpy(valp, bnx2x_sp(bp, wb_data[0]), len32 * 4); \
+		memcpy(valp, bnx2x_sp(bp, wb_data[0]), (len32) * 4); \
 	} while (0)
 
 #define REG_WR_DMAE(bp, offset, valp, len32) \
 	do { \
-		memcpy(bnx2x_sp(bp, wb_data[0]), valp, len32 * 4); \
+		memcpy(bnx2x_sp(bp, wb_data[0]), valp, (len32) * 4); \
 		bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \
 				 offset, len32); \
 	} while (0)
 
+#define VIRT_WR_DMAE_LEN(bp, data, addr, len32) \
+	do { \
+		memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \
+		bnx2x_write_big_buf_wb(bp, addr, len32); \
+	} while (0)
+
 #define SHMEM_ADDR(bp, field)		(bp->common.shmem_base + \
 					 offsetof(struct shmem_region, field))
 #define SHMEM_RD(bp, field)		REG_RD(bp, SHMEM_ADDR(bp, field))
 #define SHMEM_WR(bp, field, val)	REG_WR(bp, SHMEM_ADDR(bp, field), val)
 
+#define SHMEM2_ADDR(bp, field)		(bp->common.shmem2_base + \
+					 offsetof(struct shmem2_region, field))
+#define SHMEM2_RD(bp, field)		REG_RD(bp, SHMEM2_ADDR(bp, field))
+#define SHMEM2_WR(bp, field, val)	REG_WR(bp, SHMEM2_ADDR(bp, field), val)
+
 #define EMAC_RD(bp, reg)		REG_RD(bp, emac_base + reg)
 #define EMAC_WR(bp, reg, val)		REG_WR(bp, emac_base + reg, val)
 
@@ -142,6 +156,9 @@ struct sw_rx_bd {
 struct sw_tx_bd {
 	struct sk_buff	*skb;
 	u16		first_bd;
+	u8		flags;
+/* Set on the first BD descriptor when there is a split BD */
+#define BNX2X_TSO_SPLIT_BD		(1<<0)
 };
 
 struct sw_rx_page {
@@ -149,6 +166,11 @@ struct sw_rx_page {
 	DECLARE_PCI_UNMAP_ADDR(mapping)
 };
 
+union db_prod {
+	struct doorbell_set_prod data;
+	u32		raw;
+};
+
 
 /* MC hsi */
 #define BCM_PAGE_SHIFT			12
@@ -160,7 +182,7 @@ struct sw_rx_page {
 #define PAGES_PER_SGE			(1 << PAGES_PER_SGE_SHIFT)
 #define SGE_PAGE_SIZE			PAGE_SIZE
 #define SGE_PAGE_SHIFT			PAGE_SHIFT
-#define SGE_PAGE_ALIGN(addr)		PAGE_ALIGN((typeof(PAGE_SIZE))addr)
+#define SGE_PAGE_ALIGN(addr)		PAGE_ALIGN((typeof(PAGE_SIZE))(addr))
 
 /* SGE ring related macros */
 #define NUM_RX_SGE_PAGES		2
@@ -234,15 +256,14 @@ struct bnx2x_fastpath {
 
 	struct napi_struct	napi;
 
+	u8			is_rx_queue;
+
 	struct host_status_block *status_blk;
 	dma_addr_t		status_blk_mapping;
 
-	struct eth_tx_db_data	*hw_tx_prods;
-	dma_addr_t		tx_prods_mapping;
-
 	struct sw_tx_bd		*tx_buf_ring;
 
-	struct eth_tx_bd	*tx_desc_ring;
+	union eth_tx_bd_types	*tx_desc_ring;
 	dma_addr_t		tx_desc_mapping;
 
 	struct sw_rx_bd		*rx_buf_ring;	/* BDs mappings ring */
@@ -272,6 +293,8 @@ struct bnx2x_fastpath {
 	u8			cl_id;	/* eth client id */
 	u8			sb_id;	/* status block number in HW */
 
+	union db_prod		tx_db;
+
 	u16			tx_pkt_prod;
 	u16			tx_pkt_cons;
 	u16			tx_bd_prod;
@@ -291,9 +314,11 @@ struct bnx2x_fastpath {
 	__le16			*rx_cons_sb;
 	__le16			*rx_bd_cons_sb;
 
+
 	unsigned long		tx_pkt,
 				rx_pkt,
 				rx_calls;
+
 	/* TPA related */
 	struct sw_rx_bd		tpa_pool[ETH_MAX_AGGREGATION_QUEUES_E1H];
 	u8			tpa_state[ETH_MAX_AGGREGATION_QUEUES_E1H];
@@ -309,21 +334,24 @@ struct bnx2x_fastpath {
 	struct xstorm_per_client_stats old_xclient;
 	struct bnx2x_eth_q_stats eth_q_stats;
 
-	char			name[IFNAMSIZ];
+	/* The size is calculated using the following:
+	     sizeof name field from netdev structure +
+	     4 ('-Xx-' string) +
+	     4 (for the digits and to make it DWORD aligned) */
+#define FP_NAME_SIZE		(sizeof(((struct net_device *)0)->name) + 8)
+	char			name[FP_NAME_SIZE];
 	struct bnx2x		*bp; /* parent */
 };
 
 #define bnx2x_fp(bp, nr, var)		(bp->fp[nr].var)
 
-#define BNX2X_HAS_WORK(fp)	(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))
-
 
 /* MC hsi */
 #define MAX_FETCH_BD			13	/* HW max BDs per packet */
 #define RX_COPY_THRESH			92
 
 #define NUM_TX_RINGS			16
-#define TX_DESC_CNT		(BCM_PAGE_SIZE / sizeof(struct eth_tx_bd))
+#define TX_DESC_CNT		(BCM_PAGE_SIZE / sizeof(union eth_tx_bd_types))
 #define MAX_TX_DESC_CNT			(TX_DESC_CNT - 1)
 #define NUM_TX_BD			(TX_DESC_CNT * NUM_TX_RINGS)
 #define MAX_TX_BD			(NUM_TX_BD - 1)
@@ -395,7 +423,7 @@ struct bnx2x_fastpath {
 #define DPM_TRIGER_TYPE			0x40
 #define DOORBELL(bp, cid, val) \
 	do { \
-		writel((u32)val, (bp)->doorbells + (BCM_PAGE_SIZE * cid) + \
+		writel((u32)(val), bp->doorbells + (BCM_PAGE_SIZE * (cid)) + \
 		       DPM_TRIGER_TYPE); \
 	} while (0)
 
@@ -523,6 +551,7 @@ struct bnx2x_common {
 #define NVRAM_PAGE_SIZE			256
 
 	u32			shmem_base;
+	u32			shmem2_base;
 
 	u32			hw_config;
 
@@ -757,6 +786,7 @@ struct bnx2x_slowpath {
 	struct nig_stats		nig_stats;
 	struct host_port_stats		port_stats;
 	struct host_func_stats		func_stats;
+	struct host_func_stats		func_stats_base;
 
 	u32				wb_comp;
 	u32				wb_data[4];
@@ -877,6 +907,7 @@ struct bnx2x {
 
 	struct link_params	link_params;
 	struct link_vars	link_vars;
+	struct mdio_if_info	mdio;
 
 	struct bnx2x_common	common;
 	struct bnx2x_port	port;
@@ -902,8 +933,6 @@ struct bnx2x {
 	u16			rx_quick_cons_trip;
 	u16			rx_ticks_int;
 	u16			rx_ticks;
-/* Maximal coalescing timeout in us */
-#define BNX2X_MAX_COALESCE_TOUT		(0xf0*12)
 
 	u32			lin_cnt;
 
@@ -947,10 +976,11 @@ struct bnx2x {
 	dma_addr_t      	qm_mapping;
 #endif
 
+	int			dropless_fc;
+
 	int			dmae_ready;
 	/* used to synchronize dmae accesses */
 	struct mutex		dmae_mutex;
-	struct dmae_command	init_dmae;
 
 	/* used to synchronize stats collecting */
 	int			stats_state;
@@ -966,38 +996,54 @@ struct bnx2x {
 	dma_addr_t		gunzip_mapping;
 	int			gunzip_outlen;
 #define FW_BUF_SIZE			0x8000
+#define GUNZIP_BUF(bp)			(bp->gunzip_buf)
+#define GUNZIP_PHYS(bp)			(bp->gunzip_mapping)
+#define GUNZIP_OUTLEN(bp)		(bp->gunzip_outlen)
 
-	struct raw_op          *init_ops;
+	struct raw_op		*init_ops;
 	/* Init blocks offsets inside init_ops */
-	u16                    *init_ops_offsets;
+	u16			*init_ops_offsets;
 	/* Data blob - has 32 bit granularity */
-	u32                    *init_data;
+	u32			*init_data;
 	/* Zipped PRAM blobs - raw data */
-	const u8               *tsem_int_table_data;
-	const u8               *tsem_pram_data;
-	const u8               *usem_int_table_data;
-	const u8               *usem_pram_data;
-	const u8               *xsem_int_table_data;
-	const u8               *xsem_pram_data;
-	const u8               *csem_int_table_data;
-	const u8               *csem_pram_data;
-        const struct firmware  *firmware;
+	const u8		*tsem_int_table_data;
+	const u8		*tsem_pram_data;
+	const u8		*usem_int_table_data;
+	const u8		*usem_pram_data;
+	const u8		*xsem_int_table_data;
+	const u8		*xsem_pram_data;
+	const u8		*csem_int_table_data;
+	const u8		*csem_pram_data;
+#define INIT_OPS(bp)			(bp->init_ops)
+#define INIT_OPS_OFFSETS(bp)		(bp->init_ops_offsets)
+#define INIT_DATA(bp)			(bp->init_data)
+#define INIT_TSEM_INT_TABLE_DATA(bp)	(bp->tsem_int_table_data)
+#define INIT_TSEM_PRAM_DATA(bp)		(bp->tsem_pram_data)
+#define INIT_USEM_INT_TABLE_DATA(bp)	(bp->usem_int_table_data)
+#define INIT_USEM_PRAM_DATA(bp)		(bp->usem_pram_data)
+#define INIT_XSEM_INT_TABLE_DATA(bp)	(bp->xsem_int_table_data)
+#define INIT_XSEM_PRAM_DATA(bp)		(bp->xsem_pram_data)
+#define INIT_CSEM_INT_TABLE_DATA(bp)	(bp->csem_int_table_data)
+#define INIT_CSEM_PRAM_DATA(bp)		(bp->csem_pram_data)
+
+	const struct firmware	*firmware;
 };
 
 
-#define BNX2X_MAX_QUEUES(bp)	(IS_E1HMF(bp) ? (MAX_CONTEXT / E1HVN_MAX) : \
-						 MAX_CONTEXT)
-#define BNX2X_NUM_QUEUES(bp)	max(bp->num_rx_queues, bp->num_tx_queues)
-#define is_multi(bp)		(BNX2X_NUM_QUEUES(bp) > 1)
+#define BNX2X_MAX_QUEUES(bp)	(IS_E1HMF(bp) ? (MAX_CONTEXT/(2 * E1HVN_MAX)) \
+					      : (MAX_CONTEXT/2))
+#define BNX2X_NUM_QUEUES(bp)	(bp->num_rx_queues + bp->num_tx_queues)
+#define is_multi(bp)		(BNX2X_NUM_QUEUES(bp) > 2)
 
 #define for_each_rx_queue(bp, var) \
 			for (var = 0; var < bp->num_rx_queues; var++)
 #define for_each_tx_queue(bp, var) \
-			for (var = 0; var < bp->num_tx_queues; var++)
+			for (var = bp->num_rx_queues; \
+			     var < BNX2X_NUM_QUEUES(bp); var++)
 #define for_each_queue(bp, var) \
 			for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++)
 #define for_each_nondefault_queue(bp, var) \
-			for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++)
+			for (var = 1; var < bp->num_rx_queues; var++)
 
 
 void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
@@ -1006,6 +1052,10 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
 int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
 int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
+u32 bnx2x_fw_command(struct bnx2x *bp, u32 command);
+void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
+void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
+			       u32 addr, u32 len);
 
 static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 			   int wait)
@@ -1063,9 +1113,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 #define DMAE_COMP_VAL			0xe0d0d0ae
 
 #define MAX_DMAE_C_PER_PORT		8
-#define INIT_DMAE_C(bp)			(BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
+#define INIT_DMAE_C(bp)			(BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
 					 BP_E1HVN(bp))
-#define PMF_DMAE_C(bp)			(BP_PORT(bp)*MAX_DMAE_C_PER_PORT + \
+#define PMF_DMAE_C(bp)			(BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
 					 E1HVN_MAX)
 
 
@@ -1090,7 +1140,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 
 
 /* must be used on a CID before placing it on a HW ring */
-#define HW_CID(bp, x)		((BP_PORT(bp) << 23) | (BP_E1HVN(bp) << 17) | x)
+#define HW_CID(bp, x)			((BP_PORT(bp) << 23) | \
+					 (BP_E1HVN(bp) << 17) | (x))
 
 #define SP_DESC_CNT		(BCM_PAGE_SIZE / sizeof(struct eth_spe))
 #define MAX_SP_DESC_CNT			(SP_DESC_CNT - 1)
@@ -1178,8 +1229,8 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 				 AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \
 				 AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \
 				 AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \
-				AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\
-			    AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\
+				 AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\
+			     AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\
 				 AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR | \
 				 AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR | \
 				 AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR | \
@@ -1207,7 +1258,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
 		 TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
 		 (bp->multi_mode << \
 		  TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT))
-
 #define MULTI_MASK			0x7f
 
 
diff --git a/drivers/net/bnx2x_dump.h b/drivers/net/bnx2x_dump.h
index 78c6b03..3bb9a91 100644
--- a/drivers/net/bnx2x_dump.h
+++ b/drivers/net/bnx2x_dump.h
@@ -13,31 +13,35 @@
  * The signature is time stamp, diag version and grc_dump version
  */
 
+#ifndef BNX2X_DUMP_H
+#define BNX2X_DUMP_H
+
+
 struct dump_sign {
 	u32 time_stamp;
 	u32 diag_ver;
 	u32 grc_dump_ver;
 };
 
-#define TSTORM_WAITP_ADDR	0x1b8a80
-#define CSTORM_WAITP_ADDR	0x238a80
-#define XSTORM_WAITP_ADDR	0x2b8a80
-#define USTORM_WAITP_ADDR	0x338a80
-#define TSTORM_CAM_MODE		0x1b1440
+#define TSTORM_WAITP_ADDR		0x1b8a80
+#define CSTORM_WAITP_ADDR		0x238a80
+#define XSTORM_WAITP_ADDR		0x2b8a80
+#define USTORM_WAITP_ADDR		0x338a80
+#define TSTORM_CAM_MODE			0x1b1440
 
-#define RI_E1			0x1
-#define RI_E1H			0x2
-#define RI_ONLINE		0x100
+#define RI_E1				0x1
+#define RI_E1H				0x2
+#define RI_ONLINE			0x100
 
-#define RI_E1_OFFLINE		(RI_E1)
-#define RI_E1_ONLINE		(RI_E1 | RI_ONLINE)
-#define RI_E1H_OFFLINE		(RI_E1H)
-#define RI_E1H_ONLINE		(RI_E1H | RI_ONLINE)
-#define RI_ALL_OFFLINE		(RI_E1 | RI_E1H)
-#define RI_ALL_ONLINE		(RI_E1 | RI_E1H | RI_ONLINE)
+#define RI_E1_OFFLINE			(RI_E1)
+#define RI_E1_ONLINE			(RI_E1 | RI_ONLINE)
+#define RI_E1H_OFFLINE			(RI_E1H)
+#define RI_E1H_ONLINE			(RI_E1H | RI_ONLINE)
+#define RI_ALL_OFFLINE			(RI_E1 | RI_E1H)
+#define RI_ALL_ONLINE			(RI_E1 | RI_E1H | RI_ONLINE)
 
-#define MAX_TIMER_PENDING	200
-#define TIMER_SCAN_DONT_CARE	0xFF
+#define MAX_TIMER_PENDING		200
+#define TIMER_SCAN_DONT_CARE		0xFF
 
 
 struct dump_hdr {
@@ -67,443 +71,444 @@ struct wreg_addr {
 };
 
 
-#define REGS_COUNT		558
+#define REGS_COUNT			558
 static const struct reg_addr reg_addrs[REGS_COUNT] = {
-	{ 0x2000, 341, RI_ALL_ONLINE}, { 0x2800, 103, RI_ALL_ONLINE},
-	{ 0x3000, 287, RI_ALL_ONLINE}, { 0x3800, 331, RI_ALL_ONLINE},
-	{ 0x8800, 6, RI_E1_ONLINE}, { 0xa000, 223, RI_ALL_ONLINE},
-	{ 0xa388, 1, RI_ALL_ONLINE}, { 0xa398, 1, RI_ALL_ONLINE},
-	{ 0xa39c, 7, RI_E1H_ONLINE}, { 0xa3c0, 3, RI_E1H_ONLINE},
-	{ 0xa3d0, 1, RI_E1H_ONLINE}, { 0xa3d8, 1, RI_E1H_ONLINE},
-	{ 0xa3e0, 1, RI_E1H_ONLINE}, { 0xa3e8, 1, RI_E1H_ONLINE},
-	{ 0xa3f0, 1, RI_E1H_ONLINE}, { 0xa3f8, 1, RI_E1H_ONLINE},
-	{ 0xa400, 69, RI_ALL_ONLINE}, { 0xa518, 1, RI_ALL_ONLINE},
-	{ 0xa520, 1, RI_ALL_ONLINE}, { 0xa528, 1, RI_ALL_ONLINE},
-	{ 0xa530, 1, RI_ALL_ONLINE}, { 0xa538, 1, RI_ALL_ONLINE},
-	{ 0xa540, 1, RI_ALL_ONLINE}, { 0xa548, 1, RI_ALL_ONLINE},
-	{ 0xa550, 1, RI_ALL_ONLINE}, { 0xa558, 1, RI_ALL_ONLINE},
-	{ 0xa560, 1, RI_ALL_ONLINE}, { 0xa568, 1, RI_ALL_ONLINE},
-	{ 0xa570, 1, RI_ALL_ONLINE}, { 0xa580, 1, RI_ALL_ONLINE},
-	{ 0xa590, 1, RI_ALL_ONLINE}, { 0xa5a0, 1, RI_ALL_ONLINE},
-	{ 0xa5c0, 1, RI_ALL_ONLINE}, { 0xa5e0, 1, RI_E1H_ONLINE},
-	{ 0xa5e8, 1, RI_E1H_ONLINE}, { 0xa5f0, 1, RI_E1H_ONLINE},
-	{ 0xa5f8, 10, RI_E1H_ONLINE}, { 0x10000, 236, RI_ALL_ONLINE},
-	{ 0x103bc, 1, RI_ALL_ONLINE}, { 0x103cc, 1, RI_ALL_ONLINE},
-	{ 0x103dc, 1, RI_ALL_ONLINE}, { 0x10400, 57, RI_ALL_ONLINE},
-	{ 0x104e8, 2, RI_ALL_ONLINE}, { 0x104f4, 2, RI_ALL_ONLINE},
-	{ 0x10500, 146, RI_ALL_ONLINE}, { 0x10750, 2, RI_ALL_ONLINE},
-	{ 0x10760, 2, RI_ALL_ONLINE}, { 0x10770, 2, RI_ALL_ONLINE},
-	{ 0x10780, 2, RI_ALL_ONLINE}, { 0x10790, 2, RI_ALL_ONLINE},
-	{ 0x107a0, 2, RI_ALL_ONLINE}, { 0x107b0, 2, RI_ALL_ONLINE},
-	{ 0x107c0, 2, RI_ALL_ONLINE}, { 0x107d0, 2, RI_ALL_ONLINE},
-	{ 0x107e0, 2, RI_ALL_ONLINE}, { 0x10880, 2, RI_ALL_ONLINE},
-	{ 0x10900, 2, RI_ALL_ONLINE}, { 0x12000, 1, RI_ALL_ONLINE},
-	{ 0x14000, 1, RI_ALL_ONLINE}, { 0x16000, 26, RI_E1H_ONLINE},
-	{ 0x16070, 18, RI_E1H_ONLINE}, { 0x160c0, 27, RI_E1H_ONLINE},
-	{ 0x16140, 1, RI_E1H_ONLINE}, { 0x16160, 1, RI_E1H_ONLINE},
-	{ 0x16180, 2, RI_E1H_ONLINE}, { 0x161c0, 2, RI_E1H_ONLINE},
-	{ 0x16204, 5, RI_E1H_ONLINE}, { 0x18000, 1, RI_E1H_ONLINE},
-	{ 0x18008, 1, RI_E1H_ONLINE}, { 0x20000, 24, RI_ALL_ONLINE},
-	{ 0x20060, 8, RI_ALL_ONLINE}, { 0x20080, 138, RI_ALL_ONLINE},
-	{ 0x202b4, 1, RI_ALL_ONLINE}, { 0x202c4, 1, RI_ALL_ONLINE},
-	{ 0x20400, 2, RI_ALL_ONLINE}, { 0x2040c, 8, RI_ALL_ONLINE},
-	{ 0x2042c, 18, RI_E1H_ONLINE}, { 0x20480, 1, RI_ALL_ONLINE},
-	{ 0x20500, 1, RI_ALL_ONLINE}, { 0x20600, 1, RI_ALL_ONLINE},
-	{ 0x28000, 1, RI_ALL_ONLINE}, { 0x28004, 8191, RI_ALL_OFFLINE},
-	{ 0x30000, 1, RI_ALL_ONLINE}, { 0x30004, 16383, RI_ALL_OFFLINE},
-	{ 0x40000, 98, RI_ALL_ONLINE}, { 0x40194, 1, RI_ALL_ONLINE},
-	{ 0x401a4, 1, RI_ALL_ONLINE}, { 0x401a8, 11, RI_E1H_ONLINE},
-	{ 0x40200, 4, RI_ALL_ONLINE}, { 0x40400, 43, RI_ALL_ONLINE},
-	{ 0x404b8, 1, RI_ALL_ONLINE}, { 0x404c8, 1, RI_ALL_ONLINE},
-	{ 0x404cc, 3, RI_E1H_ONLINE}, { 0x40500, 2, RI_ALL_ONLINE},
-	{ 0x40510, 2, RI_ALL_ONLINE}, { 0x40520, 2, RI_ALL_ONLINE},
-	{ 0x40530, 2, RI_ALL_ONLINE}, { 0x40540, 2, RI_ALL_ONLINE},
-	{ 0x42000, 164, RI_ALL_ONLINE}, { 0x4229c, 1, RI_ALL_ONLINE},
-	{ 0x422ac, 1, RI_ALL_ONLINE}, { 0x422bc, 1, RI_ALL_ONLINE},
-	{ 0x422d4, 5, RI_E1H_ONLINE}, { 0x42400, 49, RI_ALL_ONLINE},
-	{ 0x424c8, 38, RI_ALL_ONLINE}, { 0x42568, 2, RI_ALL_ONLINE},
-	{ 0x42800, 1, RI_ALL_ONLINE}, { 0x50000, 20, RI_ALL_ONLINE},
-	{ 0x50050, 8, RI_ALL_ONLINE}, { 0x50070, 88, RI_ALL_ONLINE},
-	{ 0x501dc, 1, RI_ALL_ONLINE}, { 0x501ec, 1, RI_ALL_ONLINE},
-	{ 0x501f0, 4, RI_E1H_ONLINE}, { 0x50200, 2, RI_ALL_ONLINE},
-	{ 0x5020c, 7, RI_ALL_ONLINE}, { 0x50228, 6, RI_E1H_ONLINE},
-	{ 0x50240, 1, RI_ALL_ONLINE}, { 0x50280, 1, RI_ALL_ONLINE},
-	{ 0x52000, 1, RI_ALL_ONLINE}, { 0x54000, 1, RI_ALL_ONLINE},
-	{ 0x54004, 3327, RI_ALL_OFFLINE}, { 0x58000, 1, RI_ALL_ONLINE},
-	{ 0x58004, 8191, RI_ALL_OFFLINE}, { 0x60000, 71, RI_ALL_ONLINE},
-	{ 0x60128, 1, RI_ALL_ONLINE}, { 0x60138, 1, RI_ALL_ONLINE},
-	{ 0x6013c, 24, RI_E1H_ONLINE}, { 0x60200, 1, RI_ALL_ONLINE},
-	{ 0x61000, 1, RI_ALL_ONLINE}, { 0x61004, 511, RI_ALL_OFFLINE},
-	{ 0x70000, 8, RI_ALL_ONLINE}, { 0x70020, 21496, RI_ALL_OFFLINE},
-	{ 0x85000, 3, RI_ALL_ONLINE}, { 0x8500c, 4, RI_ALL_OFFLINE},
-	{ 0x8501c, 7, RI_ALL_ONLINE}, { 0x85038, 4, RI_ALL_OFFLINE},
-	{ 0x85048, 1, RI_ALL_ONLINE}, { 0x8504c, 109, RI_ALL_OFFLINE},
-	{ 0x85200, 32, RI_ALL_ONLINE}, { 0x85280, 11104, RI_ALL_OFFLINE},
-	{ 0xa0000, 16384, RI_ALL_ONLINE}, { 0xb0000, 16384, RI_E1H_ONLINE},
-	{ 0xc1000, 7, RI_ALL_ONLINE}, { 0xc1028, 1, RI_ALL_ONLINE},
-	{ 0xc1038, 1, RI_ALL_ONLINE}, { 0xc1800, 2, RI_ALL_ONLINE},
-	{ 0xc2000, 164, RI_ALL_ONLINE}, { 0xc229c, 1, RI_ALL_ONLINE},
-	{ 0xc22ac, 1, RI_ALL_ONLINE}, { 0xc22bc, 1, RI_ALL_ONLINE},
-	{ 0xc2400, 49, RI_ALL_ONLINE}, { 0xc24c8, 38, RI_ALL_ONLINE},
-	{ 0xc2568, 2, RI_ALL_ONLINE}, { 0xc2600, 1, RI_ALL_ONLINE},
-	{ 0xc4000, 165, RI_ALL_ONLINE}, { 0xc42a0, 1, RI_ALL_ONLINE},
-	{ 0xc42b0, 1, RI_ALL_ONLINE}, { 0xc42c0, 1, RI_ALL_ONLINE},
-	{ 0xc42e0, 7, RI_E1H_ONLINE}, { 0xc4400, 51, RI_ALL_ONLINE},
-	{ 0xc44d0, 38, RI_ALL_ONLINE}, { 0xc4570, 2, RI_ALL_ONLINE},
-	{ 0xc4600, 1, RI_ALL_ONLINE}, { 0xd0000, 19, RI_ALL_ONLINE},
-	{ 0xd004c, 8, RI_ALL_ONLINE}, { 0xd006c, 91, RI_ALL_ONLINE},
-	{ 0xd01e4, 1, RI_ALL_ONLINE}, { 0xd01f4, 1, RI_ALL_ONLINE},
-	{ 0xd0200, 2, RI_ALL_ONLINE}, { 0xd020c, 7, RI_ALL_ONLINE},
-	{ 0xd0228, 18, RI_E1H_ONLINE}, { 0xd0280, 1, RI_ALL_ONLINE},
-	{ 0xd0300, 1, RI_ALL_ONLINE}, { 0xd0400, 1, RI_ALL_ONLINE},
-	{ 0xd4000, 1, RI_ALL_ONLINE}, { 0xd4004, 2559, RI_ALL_OFFLINE},
-	{ 0xd8000, 1, RI_ALL_ONLINE}, { 0xd8004, 8191, RI_ALL_OFFLINE},
-	{ 0xe0000, 21, RI_ALL_ONLINE}, { 0xe0054, 8, RI_ALL_ONLINE},
-	{ 0xe0074, 85, RI_ALL_ONLINE}, { 0xe01d4, 1, RI_ALL_ONLINE},
-	{ 0xe01e4, 1, RI_ALL_ONLINE}, { 0xe0200, 2, RI_ALL_ONLINE},
-	{ 0xe020c, 8, RI_ALL_ONLINE}, { 0xe022c, 18, RI_E1H_ONLINE},
-	{ 0xe0280, 1, RI_ALL_ONLINE}, { 0xe0300, 1, RI_ALL_ONLINE},
-	{ 0xe1000, 1, RI_ALL_ONLINE}, { 0xe2000, 1, RI_ALL_ONLINE},
-	{ 0xe2004, 2047, RI_ALL_OFFLINE}, { 0xf0000, 1, RI_ALL_ONLINE},
-	{ 0xf0004, 16383, RI_ALL_OFFLINE}, { 0x101000, 12, RI_ALL_ONLINE},
-	{ 0x10103c, 1, RI_ALL_ONLINE}, { 0x10104c, 1, RI_ALL_ONLINE},
-	{ 0x101050, 1, RI_E1H_ONLINE}, { 0x101100, 1, RI_ALL_ONLINE},
-	{ 0x101800, 8, RI_ALL_ONLINE}, { 0x102000, 18, RI_ALL_ONLINE},
-	{ 0x102054, 1, RI_ALL_ONLINE}, { 0x102064, 1, RI_ALL_ONLINE},
-	{ 0x102080, 17, RI_ALL_ONLINE}, { 0x1020c8, 8, RI_E1H_ONLINE},
-	{ 0x102400, 1, RI_ALL_ONLINE}, { 0x103000, 26, RI_ALL_ONLINE},
-	{ 0x103074, 1, RI_ALL_ONLINE}, { 0x103084, 1, RI_ALL_ONLINE},
-	{ 0x103094, 1, RI_ALL_ONLINE}, { 0x103098, 5, RI_E1H_ONLINE},
-	{ 0x103800, 8, RI_ALL_ONLINE}, { 0x104000, 63, RI_ALL_ONLINE},
-	{ 0x104108, 1, RI_ALL_ONLINE}, { 0x104118, 1, RI_ALL_ONLINE},
-	{ 0x104200, 17, RI_ALL_ONLINE}, { 0x104400, 64, RI_ALL_ONLINE},
-	{ 0x104500, 192, RI_ALL_OFFLINE}, { 0x104800, 64, RI_ALL_ONLINE},
-	{ 0x104900, 192, RI_ALL_OFFLINE}, { 0x105000, 7, RI_ALL_ONLINE},
-	{ 0x10501c, 1, RI_ALL_OFFLINE}, { 0x105020, 3, RI_ALL_ONLINE},
-	{ 0x10502c, 1, RI_ALL_OFFLINE}, { 0x105030, 3, RI_ALL_ONLINE},
-	{ 0x10503c, 1, RI_ALL_OFFLINE}, { 0x105040, 3, RI_ALL_ONLINE},
-	{ 0x10504c, 1, RI_ALL_OFFLINE}, { 0x105050, 3, RI_ALL_ONLINE},
-	{ 0x10505c, 1, RI_ALL_OFFLINE}, { 0x105060, 3, RI_ALL_ONLINE},
-	{ 0x10506c, 1, RI_ALL_OFFLINE}, { 0x105070, 3, RI_ALL_ONLINE},
-	{ 0x10507c, 1, RI_ALL_OFFLINE}, { 0x105080, 3, RI_ALL_ONLINE},
-	{ 0x10508c, 1, RI_ALL_OFFLINE}, { 0x105090, 3, RI_ALL_ONLINE},
-	{ 0x10509c, 1, RI_ALL_OFFLINE}, { 0x1050a0, 3, RI_ALL_ONLINE},
-	{ 0x1050ac, 1, RI_ALL_OFFLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
-	{ 0x1050bc, 1, RI_ALL_OFFLINE}, { 0x1050c0, 3, RI_ALL_ONLINE},
-	{ 0x1050cc, 1, RI_ALL_OFFLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
-	{ 0x1050dc, 1, RI_ALL_OFFLINE}, { 0x1050e0, 3, RI_ALL_ONLINE},
-	{ 0x1050ec, 1, RI_ALL_OFFLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
-	{ 0x1050fc, 1, RI_ALL_OFFLINE}, { 0x105100, 3, RI_ALL_ONLINE},
-	{ 0x10510c, 1, RI_ALL_OFFLINE}, { 0x105110, 3, RI_ALL_ONLINE},
-	{ 0x10511c, 1, RI_ALL_OFFLINE}, { 0x105120, 3, RI_ALL_ONLINE},
-	{ 0x10512c, 1, RI_ALL_OFFLINE}, { 0x105130, 3, RI_ALL_ONLINE},
-	{ 0x10513c, 1, RI_ALL_OFFLINE}, { 0x105140, 3, RI_ALL_ONLINE},
-	{ 0x10514c, 1, RI_ALL_OFFLINE}, { 0x105150, 3, RI_ALL_ONLINE},
-	{ 0x10515c, 1, RI_ALL_OFFLINE}, { 0x105160, 3, RI_ALL_ONLINE},
-	{ 0x10516c, 1, RI_ALL_OFFLINE}, { 0x105170, 3, RI_ALL_ONLINE},
-	{ 0x10517c, 1, RI_ALL_OFFLINE}, { 0x105180, 3, RI_ALL_ONLINE},
-	{ 0x10518c, 1, RI_ALL_OFFLINE}, { 0x105190, 3, RI_ALL_ONLINE},
-	{ 0x10519c, 1, RI_ALL_OFFLINE}, { 0x1051a0, 3, RI_ALL_ONLINE},
-	{ 0x1051ac, 1, RI_ALL_OFFLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
-	{ 0x1051bc, 1, RI_ALL_OFFLINE}, { 0x1051c0, 3, RI_ALL_ONLINE},
-	{ 0x1051cc, 1, RI_ALL_OFFLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
-	{ 0x1051dc, 1, RI_ALL_OFFLINE}, { 0x1051e0, 3, RI_ALL_ONLINE},
-	{ 0x1051ec, 1, RI_ALL_OFFLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
-	{ 0x1051fc, 1, RI_ALL_OFFLINE}, { 0x105200, 3, RI_ALL_ONLINE},
-	{ 0x10520c, 1, RI_ALL_OFFLINE}, { 0x105210, 3, RI_ALL_ONLINE},
-	{ 0x10521c, 1, RI_ALL_OFFLINE}, { 0x105220, 3, RI_ALL_ONLINE},
-	{ 0x10522c, 1, RI_ALL_OFFLINE}, { 0x105230, 3, RI_ALL_ONLINE},
-	{ 0x10523c, 1, RI_ALL_OFFLINE}, { 0x105240, 3, RI_ALL_ONLINE},
-	{ 0x10524c, 1, RI_ALL_OFFLINE}, { 0x105250, 3, RI_ALL_ONLINE},
-	{ 0x10525c, 1, RI_ALL_OFFLINE}, { 0x105260, 3, RI_ALL_ONLINE},
-	{ 0x10526c, 1, RI_ALL_OFFLINE}, { 0x105270, 3, RI_ALL_ONLINE},
-	{ 0x10527c, 1, RI_ALL_OFFLINE}, { 0x105280, 3, RI_ALL_ONLINE},
-	{ 0x10528c, 1, RI_ALL_OFFLINE}, { 0x105290, 3, RI_ALL_ONLINE},
-	{ 0x10529c, 1, RI_ALL_OFFLINE}, { 0x1052a0, 3, RI_ALL_ONLINE},
-	{ 0x1052ac, 1, RI_ALL_OFFLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
-	{ 0x1052bc, 1, RI_ALL_OFFLINE}, { 0x1052c0, 3, RI_ALL_ONLINE},
-	{ 0x1052cc, 1, RI_ALL_OFFLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
-	{ 0x1052dc, 1, RI_ALL_OFFLINE}, { 0x1052e0, 3, RI_ALL_ONLINE},
-	{ 0x1052ec, 1, RI_ALL_OFFLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
-	{ 0x1052fc, 1, RI_ALL_OFFLINE}, { 0x105300, 3, RI_ALL_ONLINE},
-	{ 0x10530c, 1, RI_ALL_OFFLINE}, { 0x105310, 3, RI_ALL_ONLINE},
-	{ 0x10531c, 1, RI_ALL_OFFLINE}, { 0x105320, 3, RI_ALL_ONLINE},
-	{ 0x10532c, 1, RI_ALL_OFFLINE}, { 0x105330, 3, RI_ALL_ONLINE},
-	{ 0x10533c, 1, RI_ALL_OFFLINE}, { 0x105340, 3, RI_ALL_ONLINE},
-	{ 0x10534c, 1, RI_ALL_OFFLINE}, { 0x105350, 3, RI_ALL_ONLINE},
-	{ 0x10535c, 1, RI_ALL_OFFLINE}, { 0x105360, 3, RI_ALL_ONLINE},
-	{ 0x10536c, 1, RI_ALL_OFFLINE}, { 0x105370, 3, RI_ALL_ONLINE},
-	{ 0x10537c, 1, RI_ALL_OFFLINE}, { 0x105380, 3, RI_ALL_ONLINE},
-	{ 0x10538c, 1, RI_ALL_OFFLINE}, { 0x105390, 3, RI_ALL_ONLINE},
-	{ 0x10539c, 1, RI_ALL_OFFLINE}, { 0x1053a0, 3, RI_ALL_ONLINE},
-	{ 0x1053ac, 1, RI_ALL_OFFLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
-	{ 0x1053bc, 1, RI_ALL_OFFLINE}, { 0x1053c0, 3, RI_ALL_ONLINE},
-	{ 0x1053cc, 1, RI_ALL_OFFLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
-	{ 0x1053dc, 1, RI_ALL_OFFLINE}, { 0x1053e0, 3, RI_ALL_ONLINE},
-	{ 0x1053ec, 1, RI_ALL_OFFLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
-	{ 0x1053fc, 769, RI_ALL_OFFLINE}, { 0x108000, 33, RI_ALL_ONLINE},
-	{ 0x108090, 1, RI_ALL_ONLINE}, { 0x1080a0, 1, RI_ALL_ONLINE},
-	{ 0x1080ac, 5, RI_E1H_ONLINE}, { 0x108100, 5, RI_ALL_ONLINE},
-	{ 0x108120, 5, RI_ALL_ONLINE}, { 0x108200, 74, RI_ALL_ONLINE},
-	{ 0x108400, 74, RI_ALL_ONLINE}, { 0x108800, 152, RI_ALL_ONLINE},
-	{ 0x109000, 1, RI_ALL_ONLINE}, { 0x120000, 347, RI_ALL_ONLINE},
-	{ 0x120578, 1, RI_ALL_ONLINE}, { 0x120588, 1, RI_ALL_ONLINE},
-	{ 0x120598, 1, RI_ALL_ONLINE}, { 0x12059c, 23, RI_E1H_ONLINE},
-	{ 0x120614, 1, RI_E1H_ONLINE}, { 0x12061c, 30, RI_E1H_ONLINE},
-	{ 0x12080c, 65, RI_ALL_ONLINE}, { 0x120a00, 2, RI_ALL_ONLINE},
-	{ 0x122000, 2, RI_ALL_ONLINE}, { 0x128000, 2, RI_E1H_ONLINE},
-	{ 0x140000, 114, RI_ALL_ONLINE}, { 0x1401d4, 1, RI_ALL_ONLINE},
-	{ 0x1401e4, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
-	{ 0x144000, 4, RI_ALL_ONLINE}, { 0x148000, 4, RI_ALL_ONLINE},
-	{ 0x14c000, 4, RI_ALL_ONLINE}, { 0x150000, 4, RI_ALL_ONLINE},
-	{ 0x154000, 4, RI_ALL_ONLINE}, { 0x158000, 4, RI_ALL_ONLINE},
-	{ 0x15c000, 7, RI_E1H_ONLINE}, { 0x161000, 7, RI_ALL_ONLINE},
-	{ 0x161028, 1, RI_ALL_ONLINE}, { 0x161038, 1, RI_ALL_ONLINE},
-	{ 0x161800, 2, RI_ALL_ONLINE}, { 0x164000, 60, RI_ALL_ONLINE},
-	{ 0x1640fc, 1, RI_ALL_ONLINE}, { 0x16410c, 1, RI_ALL_ONLINE},
-	{ 0x164110, 2, RI_E1H_ONLINE}, { 0x164200, 1, RI_ALL_ONLINE},
-	{ 0x164208, 1, RI_ALL_ONLINE}, { 0x164210, 1, RI_ALL_ONLINE},
-	{ 0x164218, 1, RI_ALL_ONLINE}, { 0x164220, 1, RI_ALL_ONLINE},
-	{ 0x164228, 1, RI_ALL_ONLINE}, { 0x164230, 1, RI_ALL_ONLINE},
-	{ 0x164238, 1, RI_ALL_ONLINE}, { 0x164240, 1, RI_ALL_ONLINE},
-	{ 0x164248, 1, RI_ALL_ONLINE}, { 0x164250, 1, RI_ALL_ONLINE},
-	{ 0x164258, 1, RI_ALL_ONLINE}, { 0x164260, 1, RI_ALL_ONLINE},
-	{ 0x164270, 2, RI_ALL_ONLINE}, { 0x164280, 2, RI_ALL_ONLINE},
-	{ 0x164800, 2, RI_ALL_ONLINE}, { 0x165000, 2, RI_ALL_ONLINE},
-	{ 0x166000, 164, RI_ALL_ONLINE}, { 0x16629c, 1, RI_ALL_ONLINE},
-	{ 0x1662ac, 1, RI_ALL_ONLINE}, { 0x1662bc, 1, RI_ALL_ONLINE},
-	{ 0x166400, 49, RI_ALL_ONLINE}, { 0x1664c8, 38, RI_ALL_ONLINE},
-	{ 0x166568, 2, RI_ALL_ONLINE}, { 0x166800, 1, RI_ALL_ONLINE},
-	{ 0x168000, 270, RI_ALL_ONLINE}, { 0x168444, 1, RI_ALL_ONLINE},
-	{ 0x168454, 1, RI_ALL_ONLINE}, { 0x168800, 19, RI_ALL_ONLINE},
-	{ 0x168900, 1, RI_ALL_ONLINE}, { 0x168a00, 128, RI_ALL_ONLINE},
-	{ 0x16a000, 1, RI_ALL_ONLINE}, { 0x16a004, 1535, RI_ALL_OFFLINE},
-	{ 0x16c000, 1, RI_ALL_ONLINE}, { 0x16c004, 1535, RI_ALL_OFFLINE},
-	{ 0x16e000, 16, RI_E1H_ONLINE}, { 0x16e100, 1, RI_E1H_ONLINE},
-	{ 0x16e200, 2, RI_E1H_ONLINE}, { 0x16e400, 183, RI_E1H_ONLINE},
-	{ 0x170000, 93, RI_ALL_ONLINE}, { 0x170180, 1, RI_ALL_ONLINE},
-	{ 0x170190, 1, RI_ALL_ONLINE}, { 0x170200, 4, RI_ALL_ONLINE},
-	{ 0x170214, 1, RI_ALL_ONLINE}, { 0x178000, 1, RI_ALL_ONLINE},
-	{ 0x180000, 61, RI_ALL_ONLINE}, { 0x180100, 1, RI_ALL_ONLINE},
-	{ 0x180110, 1, RI_ALL_ONLINE}, { 0x180120, 1, RI_ALL_ONLINE},
-	{ 0x180130, 1, RI_ALL_ONLINE}, { 0x18013c, 2, RI_E1H_ONLINE},
-	{ 0x180200, 58, RI_ALL_ONLINE}, { 0x180340, 4, RI_ALL_ONLINE},
-	{ 0x180400, 1, RI_ALL_ONLINE}, { 0x180404, 255, RI_ALL_OFFLINE},
-	{ 0x181000, 4, RI_ALL_ONLINE}, { 0x181010, 1020, RI_ALL_OFFLINE},
-	{ 0x1a0000, 1, RI_ALL_ONLINE}, { 0x1a0004, 1023, RI_ALL_OFFLINE},
-	{ 0x1a1000, 1, RI_ALL_ONLINE}, { 0x1a1004, 4607, RI_ALL_OFFLINE},
-	{ 0x1a5800, 2560, RI_E1H_OFFLINE}, { 0x1a8000, 64, RI_ALL_OFFLINE},
-	{ 0x1a8100, 1984, RI_E1H_OFFLINE}, { 0x1aa000, 1, RI_E1H_ONLINE},
-	{ 0x1aa004, 6655, RI_E1H_OFFLINE}, { 0x1b1800, 128, RI_ALL_OFFLINE},
-	{ 0x1b1c00, 128, RI_ALL_OFFLINE}, { 0x1b2000, 1, RI_ALL_OFFLINE},
-	{ 0x1b2400, 64, RI_E1H_OFFLINE}, { 0x1b8200, 1, RI_ALL_ONLINE},
-	{ 0x1b8240, 1, RI_ALL_ONLINE}, { 0x1b8280, 1, RI_ALL_ONLINE},
-	{ 0x1b82c0, 1, RI_ALL_ONLINE}, { 0x1b8a00, 1, RI_ALL_ONLINE},
-	{ 0x1b8a80, 1, RI_ALL_ONLINE}, { 0x1c0000, 2, RI_ALL_ONLINE},
-	{ 0x200000, 65, RI_ALL_ONLINE}, { 0x200110, 1, RI_ALL_ONLINE},
-	{ 0x200120, 1, RI_ALL_ONLINE}, { 0x200130, 1, RI_ALL_ONLINE},
-	{ 0x200140, 1, RI_ALL_ONLINE}, { 0x20014c, 2, RI_E1H_ONLINE},
-	{ 0x200200, 58, RI_ALL_ONLINE}, { 0x200340, 4, RI_ALL_ONLINE},
-	{ 0x200400, 1, RI_ALL_ONLINE}, { 0x200404, 255, RI_ALL_OFFLINE},
-	{ 0x202000, 4, RI_ALL_ONLINE}, { 0x202010, 2044, RI_ALL_OFFLINE},
-	{ 0x220000, 1, RI_ALL_ONLINE}, { 0x220004, 1023, RI_ALL_OFFLINE},
-	{ 0x221000, 1, RI_ALL_ONLINE}, { 0x221004, 4607, RI_ALL_OFFLINE},
-	{ 0x225800, 1536, RI_E1H_OFFLINE}, { 0x227000, 1, RI_E1H_ONLINE},
-	{ 0x227004, 1023, RI_E1H_OFFLINE}, { 0x228000, 64, RI_ALL_OFFLINE},
-	{ 0x228100, 8640, RI_E1H_OFFLINE}, { 0x231800, 128, RI_ALL_OFFLINE},
-	{ 0x231c00, 128, RI_ALL_OFFLINE}, { 0x232000, 1, RI_ALL_OFFLINE},
-	{ 0x232400, 64, RI_E1H_OFFLINE}, { 0x238200, 1, RI_ALL_ONLINE},
-	{ 0x238240, 1, RI_ALL_ONLINE}, { 0x238280, 1, RI_ALL_ONLINE},
-	{ 0x2382c0, 1, RI_ALL_ONLINE}, { 0x238a00, 1, RI_ALL_ONLINE},
-	{ 0x238a80, 1, RI_ALL_ONLINE}, { 0x240000, 2, RI_ALL_ONLINE},
-	{ 0x280000, 65, RI_ALL_ONLINE}, { 0x280110, 1, RI_ALL_ONLINE},
-	{ 0x280120, 1, RI_ALL_ONLINE}, { 0x280130, 1, RI_ALL_ONLINE},
-	{ 0x280140, 1, RI_ALL_ONLINE}, { 0x28014c, 2, RI_E1H_ONLINE},
-	{ 0x280200, 58, RI_ALL_ONLINE}, { 0x280340, 4, RI_ALL_ONLINE},
-	{ 0x280400, 1, RI_ALL_ONLINE}, { 0x280404, 255, RI_ALL_OFFLINE},
-	{ 0x282000, 4, RI_ALL_ONLINE}, { 0x282010, 2044, RI_ALL_OFFLINE},
-	{ 0x2a0000, 1, RI_ALL_ONLINE}, { 0x2a0004, 1023, RI_ALL_OFFLINE},
-	{ 0x2a1000, 1, RI_ALL_ONLINE}, { 0x2a1004, 4607, RI_ALL_OFFLINE},
-	{ 0x2a5800, 2560, RI_E1H_OFFLINE}, { 0x2a8000, 64, RI_ALL_OFFLINE},
-	{ 0x2a8100, 960, RI_E1H_OFFLINE}, { 0x2a9000, 1, RI_E1H_ONLINE},
-	{ 0x2a9004, 7679, RI_E1H_OFFLINE}, { 0x2b1800, 128, RI_ALL_OFFLINE},
-	{ 0x2b1c00, 128, RI_ALL_OFFLINE}, { 0x2b2000, 1, RI_ALL_OFFLINE},
-	{ 0x2b2400, 64, RI_E1H_OFFLINE}, { 0x2b8200, 1, RI_ALL_ONLINE},
-	{ 0x2b8240, 1, RI_ALL_ONLINE}, { 0x2b8280, 1, RI_ALL_ONLINE},
-	{ 0x2b82c0, 1, RI_ALL_ONLINE}, { 0x2b8a00, 1, RI_ALL_ONLINE},
-	{ 0x2b8a80, 1, RI_ALL_ONLINE}, { 0x2c0000, 2, RI_ALL_ONLINE},
-	{ 0x300000, 65, RI_ALL_ONLINE}, { 0x300110, 1, RI_ALL_ONLINE},
-	{ 0x300120, 1, RI_ALL_ONLINE}, { 0x300130, 1, RI_ALL_ONLINE},
-	{ 0x300140, 1, RI_ALL_ONLINE}, { 0x30014c, 2, RI_E1H_ONLINE},
-	{ 0x300200, 58, RI_ALL_ONLINE}, { 0x300340, 4, RI_ALL_ONLINE},
-	{ 0x300400, 1, RI_ALL_ONLINE}, { 0x300404, 255, RI_ALL_OFFLINE},
-	{ 0x302000, 4, RI_ALL_ONLINE}, { 0x302010, 2044, RI_ALL_OFFLINE},
-	{ 0x320000, 1, RI_ALL_ONLINE}, { 0x320004, 1023, RI_ALL_OFFLINE},
-	{ 0x321000, 1, RI_ALL_ONLINE}, { 0x321004, 4607, RI_ALL_OFFLINE},
-	{ 0x325800, 2560, RI_E1H_OFFLINE}, { 0x328000, 64, RI_ALL_OFFLINE},
-	{ 0x328100, 536, RI_E1H_OFFLINE}, { 0x328960, 1, RI_E1H_ONLINE},
-	{ 0x328964, 8103, RI_E1H_OFFLINE}, { 0x331800, 128, RI_ALL_OFFLINE},
-	{ 0x331c00, 128, RI_ALL_OFFLINE}, { 0x332000, 1, RI_ALL_OFFLINE},
-	{ 0x332400, 64, RI_E1H_OFFLINE}, { 0x338200, 1, RI_ALL_ONLINE},
-	{ 0x338240, 1, RI_ALL_ONLINE}, { 0x338280, 1, RI_ALL_ONLINE},
-	{ 0x3382c0, 1, RI_ALL_ONLINE}, { 0x338a00, 1, RI_ALL_ONLINE},
-	{ 0x338a80, 1, RI_ALL_ONLINE}, { 0x340000, 2, RI_ALL_ONLINE}
+	{ 0x2000, 341, RI_ALL_ONLINE }, { 0x2800, 103, RI_ALL_ONLINE },
+	{ 0x3000, 287, RI_ALL_ONLINE }, { 0x3800, 331, RI_ALL_ONLINE },
+	{ 0x8800, 6, RI_E1_ONLINE }, { 0xa000, 223, RI_ALL_ONLINE },
+	{ 0xa388, 1, RI_ALL_ONLINE }, { 0xa398, 1, RI_ALL_ONLINE },
+	{ 0xa39c, 7, RI_E1H_ONLINE }, { 0xa3c0, 3, RI_E1H_ONLINE },
+	{ 0xa3d0, 1, RI_E1H_ONLINE }, { 0xa3d8, 1, RI_E1H_ONLINE },
+	{ 0xa3e0, 1, RI_E1H_ONLINE }, { 0xa3e8, 1, RI_E1H_ONLINE },
+	{ 0xa3f0, 1, RI_E1H_ONLINE }, { 0xa3f8, 1, RI_E1H_ONLINE },
+	{ 0xa400, 69, RI_ALL_ONLINE }, { 0xa518, 1, RI_ALL_ONLINE },
+	{ 0xa520, 1, RI_ALL_ONLINE }, { 0xa528, 1, RI_ALL_ONLINE },
+	{ 0xa530, 1, RI_ALL_ONLINE }, { 0xa538, 1, RI_ALL_ONLINE },
+	{ 0xa540, 1, RI_ALL_ONLINE }, { 0xa548, 1, RI_ALL_ONLINE },
+	{ 0xa550, 1, RI_ALL_ONLINE }, { 0xa558, 1, RI_ALL_ONLINE },
+	{ 0xa560, 1, RI_ALL_ONLINE }, { 0xa568, 1, RI_ALL_ONLINE },
+	{ 0xa570, 1, RI_ALL_ONLINE }, { 0xa580, 1, RI_ALL_ONLINE },
+	{ 0xa590, 1, RI_ALL_ONLINE }, { 0xa5a0, 1, RI_ALL_ONLINE },
+	{ 0xa5c0, 1, RI_ALL_ONLINE }, { 0xa5e0, 1, RI_E1H_ONLINE },
+	{ 0xa5e8, 1, RI_E1H_ONLINE }, { 0xa5f0, 1, RI_E1H_ONLINE },
+	{ 0xa5f8, 10, RI_E1H_ONLINE }, { 0x10000, 236, RI_ALL_ONLINE },
+	{ 0x103bc, 1, RI_ALL_ONLINE }, { 0x103cc, 1, RI_ALL_ONLINE },
+	{ 0x103dc, 1, RI_ALL_ONLINE }, { 0x10400, 57, RI_ALL_ONLINE },
+	{ 0x104e8, 2, RI_ALL_ONLINE }, { 0x104f4, 2, RI_ALL_ONLINE },
+	{ 0x10500, 146, RI_ALL_ONLINE }, { 0x10750, 2, RI_ALL_ONLINE },
+	{ 0x10760, 2, RI_ALL_ONLINE }, { 0x10770, 2, RI_ALL_ONLINE },
+	{ 0x10780, 2, RI_ALL_ONLINE }, { 0x10790, 2, RI_ALL_ONLINE },
+	{ 0x107a0, 2, RI_ALL_ONLINE }, { 0x107b0, 2, RI_ALL_ONLINE },
+	{ 0x107c0, 2, RI_ALL_ONLINE }, { 0x107d0, 2, RI_ALL_ONLINE },
+	{ 0x107e0, 2, RI_ALL_ONLINE }, { 0x10880, 2, RI_ALL_ONLINE },
+	{ 0x10900, 2, RI_ALL_ONLINE }, { 0x12000, 1, RI_ALL_ONLINE },
+	{ 0x14000, 1, RI_ALL_ONLINE }, { 0x16000, 26, RI_E1H_ONLINE },
+	{ 0x16070, 18, RI_E1H_ONLINE }, { 0x160c0, 27, RI_E1H_ONLINE },
+	{ 0x16140, 1, RI_E1H_ONLINE }, { 0x16160, 1, RI_E1H_ONLINE },
+	{ 0x16180, 2, RI_E1H_ONLINE }, { 0x161c0, 2, RI_E1H_ONLINE },
+	{ 0x16204, 5, RI_E1H_ONLINE }, { 0x18000, 1, RI_E1H_ONLINE },
+	{ 0x18008, 1, RI_E1H_ONLINE }, { 0x20000, 24, RI_ALL_ONLINE },
+	{ 0x20060, 8, RI_ALL_ONLINE }, { 0x20080, 138, RI_ALL_ONLINE },
+	{ 0x202b4, 1, RI_ALL_ONLINE }, { 0x202c4, 1, RI_ALL_ONLINE },
+	{ 0x20400, 2, RI_ALL_ONLINE }, { 0x2040c, 8, RI_ALL_ONLINE },
+	{ 0x2042c, 18, RI_E1H_ONLINE }, { 0x20480, 1, RI_ALL_ONLINE },
+	{ 0x20500, 1, RI_ALL_ONLINE }, { 0x20600, 1, RI_ALL_ONLINE },
+	{ 0x28000, 1, RI_ALL_ONLINE }, { 0x28004, 8191, RI_ALL_OFFLINE },
+	{ 0x30000, 1, RI_ALL_ONLINE }, { 0x30004, 16383, RI_ALL_OFFLINE },
+	{ 0x40000, 98, RI_ALL_ONLINE }, { 0x40194, 1, RI_ALL_ONLINE },
+	{ 0x401a4, 1, RI_ALL_ONLINE }, { 0x401a8, 11, RI_E1H_ONLINE },
+	{ 0x40200, 4, RI_ALL_ONLINE }, { 0x40400, 43, RI_ALL_ONLINE },
+	{ 0x404b8, 1, RI_ALL_ONLINE }, { 0x404c8, 1, RI_ALL_ONLINE },
+	{ 0x404cc, 3, RI_E1H_ONLINE }, { 0x40500, 2, RI_ALL_ONLINE },
+	{ 0x40510, 2, RI_ALL_ONLINE }, { 0x40520, 2, RI_ALL_ONLINE },
+	{ 0x40530, 2, RI_ALL_ONLINE }, { 0x40540, 2, RI_ALL_ONLINE },
+	{ 0x42000, 164, RI_ALL_ONLINE }, { 0x4229c, 1, RI_ALL_ONLINE },
+	{ 0x422ac, 1, RI_ALL_ONLINE }, { 0x422bc, 1, RI_ALL_ONLINE },
+	{ 0x422d4, 5, RI_E1H_ONLINE }, { 0x42400, 49, RI_ALL_ONLINE },
+	{ 0x424c8, 38, RI_ALL_ONLINE }, { 0x42568, 2, RI_ALL_ONLINE },
+	{ 0x42800, 1, RI_ALL_ONLINE }, { 0x50000, 20, RI_ALL_ONLINE },
+	{ 0x50050, 8, RI_ALL_ONLINE }, { 0x50070, 88, RI_ALL_ONLINE },
+	{ 0x501dc, 1, RI_ALL_ONLINE }, { 0x501ec, 1, RI_ALL_ONLINE },
+	{ 0x501f0, 4, RI_E1H_ONLINE }, { 0x50200, 2, RI_ALL_ONLINE },
+	{ 0x5020c, 7, RI_ALL_ONLINE }, { 0x50228, 6, RI_E1H_ONLINE },
+	{ 0x50240, 1, RI_ALL_ONLINE }, { 0x50280, 1, RI_ALL_ONLINE },
+	{ 0x52000, 1, RI_ALL_ONLINE }, { 0x54000, 1, RI_ALL_ONLINE },
+	{ 0x54004, 3327, RI_ALL_OFFLINE }, { 0x58000, 1, RI_ALL_ONLINE },
+	{ 0x58004, 8191, RI_ALL_OFFLINE }, { 0x60000, 71, RI_ALL_ONLINE },
+	{ 0x60128, 1, RI_ALL_ONLINE }, { 0x60138, 1, RI_ALL_ONLINE },
+	{ 0x6013c, 24, RI_E1H_ONLINE }, { 0x60200, 1, RI_ALL_ONLINE },
+	{ 0x61000, 1, RI_ALL_ONLINE }, { 0x61004, 511, RI_ALL_OFFLINE },
+	{ 0x70000, 8, RI_ALL_ONLINE }, { 0x70020, 21496, RI_ALL_OFFLINE },
+	{ 0x85000, 3, RI_ALL_ONLINE }, { 0x8500c, 4, RI_ALL_OFFLINE },
+	{ 0x8501c, 7, RI_ALL_ONLINE }, { 0x85038, 4, RI_ALL_OFFLINE },
+	{ 0x85048, 1, RI_ALL_ONLINE }, { 0x8504c, 109, RI_ALL_OFFLINE },
+	{ 0x85200, 32, RI_ALL_ONLINE }, { 0x85280, 11104, RI_ALL_OFFLINE },
+	{ 0xa0000, 16384, RI_ALL_ONLINE }, { 0xb0000, 16384, RI_E1H_ONLINE },
+	{ 0xc1000, 7, RI_ALL_ONLINE }, { 0xc1028, 1, RI_ALL_ONLINE },
+	{ 0xc1038, 1, RI_ALL_ONLINE }, { 0xc1800, 2, RI_ALL_ONLINE },
+	{ 0xc2000, 164, RI_ALL_ONLINE }, { 0xc229c, 1, RI_ALL_ONLINE },
+	{ 0xc22ac, 1, RI_ALL_ONLINE }, { 0xc22bc, 1, RI_ALL_ONLINE },
+	{ 0xc2400, 49, RI_ALL_ONLINE }, { 0xc24c8, 38, RI_ALL_ONLINE },
+	{ 0xc2568, 2, RI_ALL_ONLINE }, { 0xc2600, 1, RI_ALL_ONLINE },
+	{ 0xc4000, 165, RI_ALL_ONLINE }, { 0xc42a0, 1, RI_ALL_ONLINE },
+	{ 0xc42b0, 1, RI_ALL_ONLINE }, { 0xc42c0, 1, RI_ALL_ONLINE },
+	{ 0xc42e0, 7, RI_E1H_ONLINE }, { 0xc4400, 51, RI_ALL_ONLINE },
+	{ 0xc44d0, 38, RI_ALL_ONLINE }, { 0xc4570, 2, RI_ALL_ONLINE },
+	{ 0xc4600, 1, RI_ALL_ONLINE }, { 0xd0000, 19, RI_ALL_ONLINE },
+	{ 0xd004c, 8, RI_ALL_ONLINE }, { 0xd006c, 91, RI_ALL_ONLINE },
+	{ 0xd01e4, 1, RI_ALL_ONLINE }, { 0xd01f4, 1, RI_ALL_ONLINE },
+	{ 0xd0200, 2, RI_ALL_ONLINE }, { 0xd020c, 7, RI_ALL_ONLINE },
+	{ 0xd0228, 18, RI_E1H_ONLINE }, { 0xd0280, 1, RI_ALL_ONLINE },
+	{ 0xd0300, 1, RI_ALL_ONLINE }, { 0xd0400, 1, RI_ALL_ONLINE },
+	{ 0xd4000, 1, RI_ALL_ONLINE }, { 0xd4004, 2559, RI_ALL_OFFLINE },
+	{ 0xd8000, 1, RI_ALL_ONLINE }, { 0xd8004, 8191, RI_ALL_OFFLINE },
+	{ 0xe0000, 21, RI_ALL_ONLINE }, { 0xe0054, 8, RI_ALL_ONLINE },
+	{ 0xe0074, 85, RI_ALL_ONLINE }, { 0xe01d4, 1, RI_ALL_ONLINE },
+	{ 0xe01e4, 1, RI_ALL_ONLINE }, { 0xe0200, 2, RI_ALL_ONLINE },
+	{ 0xe020c, 8, RI_ALL_ONLINE }, { 0xe022c, 18, RI_E1H_ONLINE },
+	{ 0xe0280, 1, RI_ALL_ONLINE }, { 0xe0300, 1, RI_ALL_ONLINE },
+	{ 0xe1000, 1, RI_ALL_ONLINE }, { 0xe2000, 1, RI_ALL_ONLINE },
+	{ 0xe2004, 2047, RI_ALL_OFFLINE }, { 0xf0000, 1, RI_ALL_ONLINE },
+	{ 0xf0004, 16383, RI_ALL_OFFLINE }, { 0x101000, 12, RI_ALL_ONLINE },
+	{ 0x10103c, 1, RI_ALL_ONLINE }, { 0x10104c, 1, RI_ALL_ONLINE },
+	{ 0x101050, 1, RI_E1H_ONLINE }, { 0x101100, 1, RI_ALL_ONLINE },
+	{ 0x101800, 8, RI_ALL_ONLINE }, { 0x102000, 18, RI_ALL_ONLINE },
+	{ 0x102054, 1, RI_ALL_ONLINE }, { 0x102064, 1, RI_ALL_ONLINE },
+	{ 0x102080, 17, RI_ALL_ONLINE }, { 0x1020c8, 8, RI_E1H_ONLINE },
+	{ 0x102400, 1, RI_ALL_ONLINE }, { 0x103000, 26, RI_ALL_ONLINE },
+	{ 0x103074, 1, RI_ALL_ONLINE }, { 0x103084, 1, RI_ALL_ONLINE },
+	{ 0x103094, 1, RI_ALL_ONLINE }, { 0x103098, 5, RI_E1H_ONLINE },
+	{ 0x103800, 8, RI_ALL_ONLINE }, { 0x104000, 63, RI_ALL_ONLINE },
+	{ 0x104108, 1, RI_ALL_ONLINE }, { 0x104118, 1, RI_ALL_ONLINE },
+	{ 0x104200, 17, RI_ALL_ONLINE }, { 0x104400, 64, RI_ALL_ONLINE },
+	{ 0x104500, 192, RI_ALL_OFFLINE }, { 0x104800, 64, RI_ALL_ONLINE },
+	{ 0x104900, 192, RI_ALL_OFFLINE }, { 0x105000, 7, RI_ALL_ONLINE },
+	{ 0x10501c, 1, RI_ALL_OFFLINE }, { 0x105020, 3, RI_ALL_ONLINE },
+	{ 0x10502c, 1, RI_ALL_OFFLINE }, { 0x105030, 3, RI_ALL_ONLINE },
+	{ 0x10503c, 1, RI_ALL_OFFLINE }, { 0x105040, 3, RI_ALL_ONLINE },
+	{ 0x10504c, 1, RI_ALL_OFFLINE }, { 0x105050, 3, RI_ALL_ONLINE },
+	{ 0x10505c, 1, RI_ALL_OFFLINE }, { 0x105060, 3, RI_ALL_ONLINE },
+	{ 0x10506c, 1, RI_ALL_OFFLINE }, { 0x105070, 3, RI_ALL_ONLINE },
+	{ 0x10507c, 1, RI_ALL_OFFLINE }, { 0x105080, 3, RI_ALL_ONLINE },
+	{ 0x10508c, 1, RI_ALL_OFFLINE }, { 0x105090, 3, RI_ALL_ONLINE },
+	{ 0x10509c, 1, RI_ALL_OFFLINE }, { 0x1050a0, 3, RI_ALL_ONLINE },
+	{ 0x1050ac, 1, RI_ALL_OFFLINE }, { 0x1050b0, 3, RI_ALL_ONLINE },
+	{ 0x1050bc, 1, RI_ALL_OFFLINE }, { 0x1050c0, 3, RI_ALL_ONLINE },
+	{ 0x1050cc, 1, RI_ALL_OFFLINE }, { 0x1050d0, 3, RI_ALL_ONLINE },
+	{ 0x1050dc, 1, RI_ALL_OFFLINE }, { 0x1050e0, 3, RI_ALL_ONLINE },
+	{ 0x1050ec, 1, RI_ALL_OFFLINE }, { 0x1050f0, 3, RI_ALL_ONLINE },
+	{ 0x1050fc, 1, RI_ALL_OFFLINE }, { 0x105100, 3, RI_ALL_ONLINE },
+	{ 0x10510c, 1, RI_ALL_OFFLINE }, { 0x105110, 3, RI_ALL_ONLINE },
+	{ 0x10511c, 1, RI_ALL_OFFLINE }, { 0x105120, 3, RI_ALL_ONLINE },
+	{ 0x10512c, 1, RI_ALL_OFFLINE }, { 0x105130, 3, RI_ALL_ONLINE },
+	{ 0x10513c, 1, RI_ALL_OFFLINE }, { 0x105140, 3, RI_ALL_ONLINE },
+	{ 0x10514c, 1, RI_ALL_OFFLINE }, { 0x105150, 3, RI_ALL_ONLINE },
+	{ 0x10515c, 1, RI_ALL_OFFLINE }, { 0x105160, 3, RI_ALL_ONLINE },
+	{ 0x10516c, 1, RI_ALL_OFFLINE }, { 0x105170, 3, RI_ALL_ONLINE },
+	{ 0x10517c, 1, RI_ALL_OFFLINE }, { 0x105180, 3, RI_ALL_ONLINE },
+	{ 0x10518c, 1, RI_ALL_OFFLINE }, { 0x105190, 3, RI_ALL_ONLINE },
+	{ 0x10519c, 1, RI_ALL_OFFLINE }, { 0x1051a0, 3, RI_ALL_ONLINE },
+	{ 0x1051ac, 1, RI_ALL_OFFLINE }, { 0x1051b0, 3, RI_ALL_ONLINE },
+	{ 0x1051bc, 1, RI_ALL_OFFLINE }, { 0x1051c0, 3, RI_ALL_ONLINE },
+	{ 0x1051cc, 1, RI_ALL_OFFLINE }, { 0x1051d0, 3, RI_ALL_ONLINE },
+	{ 0x1051dc, 1, RI_ALL_OFFLINE }, { 0x1051e0, 3, RI_ALL_ONLINE },
+	{ 0x1051ec, 1, RI_ALL_OFFLINE }, { 0x1051f0, 3, RI_ALL_ONLINE },
+	{ 0x1051fc, 1, RI_ALL_OFFLINE }, { 0x105200, 3, RI_ALL_ONLINE },
+	{ 0x10520c, 1, RI_ALL_OFFLINE }, { 0x105210, 3, RI_ALL_ONLINE },
+	{ 0x10521c, 1, RI_ALL_OFFLINE }, { 0x105220, 3, RI_ALL_ONLINE },
+	{ 0x10522c, 1, RI_ALL_OFFLINE }, { 0x105230, 3, RI_ALL_ONLINE },
+	{ 0x10523c, 1, RI_ALL_OFFLINE }, { 0x105240, 3, RI_ALL_ONLINE },
+	{ 0x10524c, 1, RI_ALL_OFFLINE }, { 0x105250, 3, RI_ALL_ONLINE },
+	{ 0x10525c, 1, RI_ALL_OFFLINE }, { 0x105260, 3, RI_ALL_ONLINE },
+	{ 0x10526c, 1, RI_ALL_OFFLINE }, { 0x105270, 3, RI_ALL_ONLINE },
+	{ 0x10527c, 1, RI_ALL_OFFLINE }, { 0x105280, 3, RI_ALL_ONLINE },
+	{ 0x10528c, 1, RI_ALL_OFFLINE }, { 0x105290, 3, RI_ALL_ONLINE },
+	{ 0x10529c, 1, RI_ALL_OFFLINE }, { 0x1052a0, 3, RI_ALL_ONLINE },
+	{ 0x1052ac, 1, RI_ALL_OFFLINE }, { 0x1052b0, 3, RI_ALL_ONLINE },
+	{ 0x1052bc, 1, RI_ALL_OFFLINE }, { 0x1052c0, 3, RI_ALL_ONLINE },
+	{ 0x1052cc, 1, RI_ALL_OFFLINE }, { 0x1052d0, 3, RI_ALL_ONLINE },
+	{ 0x1052dc, 1, RI_ALL_OFFLINE }, { 0x1052e0, 3, RI_ALL_ONLINE },
+	{ 0x1052ec, 1, RI_ALL_OFFLINE }, { 0x1052f0, 3, RI_ALL_ONLINE },
+	{ 0x1052fc, 1, RI_ALL_OFFLINE }, { 0x105300, 3, RI_ALL_ONLINE },
+	{ 0x10530c, 1, RI_ALL_OFFLINE }, { 0x105310, 3, RI_ALL_ONLINE },
+	{ 0x10531c, 1, RI_ALL_OFFLINE }, { 0x105320, 3, RI_ALL_ONLINE },
+	{ 0x10532c, 1, RI_ALL_OFFLINE }, { 0x105330, 3, RI_ALL_ONLINE },
+	{ 0x10533c, 1, RI_ALL_OFFLINE }, { 0x105340, 3, RI_ALL_ONLINE },
+	{ 0x10534c, 1, RI_ALL_OFFLINE }, { 0x105350, 3, RI_ALL_ONLINE },
+	{ 0x10535c, 1, RI_ALL_OFFLINE }, { 0x105360, 3, RI_ALL_ONLINE },
+	{ 0x10536c, 1, RI_ALL_OFFLINE }, { 0x105370, 3, RI_ALL_ONLINE },
+	{ 0x10537c, 1, RI_ALL_OFFLINE }, { 0x105380, 3, RI_ALL_ONLINE },
+	{ 0x10538c, 1, RI_ALL_OFFLINE }, { 0x105390, 3, RI_ALL_ONLINE },
+	{ 0x10539c, 1, RI_ALL_OFFLINE }, { 0x1053a0, 3, RI_ALL_ONLINE },
+	{ 0x1053ac, 1, RI_ALL_OFFLINE }, { 0x1053b0, 3, RI_ALL_ONLINE },
+	{ 0x1053bc, 1, RI_ALL_OFFLINE }, { 0x1053c0, 3, RI_ALL_ONLINE },
+	{ 0x1053cc, 1, RI_ALL_OFFLINE }, { 0x1053d0, 3, RI_ALL_ONLINE },
+	{ 0x1053dc, 1, RI_ALL_OFFLINE }, { 0x1053e0, 3, RI_ALL_ONLINE },
+	{ 0x1053ec, 1, RI_ALL_OFFLINE }, { 0x1053f0, 3, RI_ALL_ONLINE },
+	{ 0x1053fc, 769, RI_ALL_OFFLINE }, { 0x108000, 33, RI_ALL_ONLINE },
+	{ 0x108090, 1, RI_ALL_ONLINE }, { 0x1080a0, 1, RI_ALL_ONLINE },
+	{ 0x1080ac, 5, RI_E1H_ONLINE }, { 0x108100, 5, RI_ALL_ONLINE },
+	{ 0x108120, 5, RI_ALL_ONLINE }, { 0x108200, 74, RI_ALL_ONLINE },
+	{ 0x108400, 74, RI_ALL_ONLINE }, { 0x108800, 152, RI_ALL_ONLINE },
+	{ 0x109000, 1, RI_ALL_ONLINE }, { 0x120000, 347, RI_ALL_ONLINE },
+	{ 0x120578, 1, RI_ALL_ONLINE }, { 0x120588, 1, RI_ALL_ONLINE },
+	{ 0x120598, 1, RI_ALL_ONLINE }, { 0x12059c, 23, RI_E1H_ONLINE },
+	{ 0x120614, 1, RI_E1H_ONLINE }, { 0x12061c, 30, RI_E1H_ONLINE },
+	{ 0x12080c, 65, RI_ALL_ONLINE }, { 0x120a00, 2, RI_ALL_ONLINE },
+	{ 0x122000, 2, RI_ALL_ONLINE }, { 0x128000, 2, RI_E1H_ONLINE },
+	{ 0x140000, 114, RI_ALL_ONLINE }, { 0x1401d4, 1, RI_ALL_ONLINE },
+	{ 0x1401e4, 1, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE },
+	{ 0x144000, 4, RI_ALL_ONLINE }, { 0x148000, 4, RI_ALL_ONLINE },
+	{ 0x14c000, 4, RI_ALL_ONLINE }, { 0x150000, 4, RI_ALL_ONLINE },
+	{ 0x154000, 4, RI_ALL_ONLINE }, { 0x158000, 4, RI_ALL_ONLINE },
+	{ 0x15c000, 7, RI_E1H_ONLINE }, { 0x161000, 7, RI_ALL_ONLINE },
+	{ 0x161028, 1, RI_ALL_ONLINE }, { 0x161038, 1, RI_ALL_ONLINE },
+	{ 0x161800, 2, RI_ALL_ONLINE }, { 0x164000, 60, RI_ALL_ONLINE },
+	{ 0x1640fc, 1, RI_ALL_ONLINE }, { 0x16410c, 1, RI_ALL_ONLINE },
+	{ 0x164110, 2, RI_E1H_ONLINE }, { 0x164200, 1, RI_ALL_ONLINE },
+	{ 0x164208, 1, RI_ALL_ONLINE }, { 0x164210, 1, RI_ALL_ONLINE },
+	{ 0x164218, 1, RI_ALL_ONLINE }, { 0x164220, 1, RI_ALL_ONLINE },
+	{ 0x164228, 1, RI_ALL_ONLINE }, { 0x164230, 1, RI_ALL_ONLINE },
+	{ 0x164238, 1, RI_ALL_ONLINE }, { 0x164240, 1, RI_ALL_ONLINE },
+	{ 0x164248, 1, RI_ALL_ONLINE }, { 0x164250, 1, RI_ALL_ONLINE },
+	{ 0x164258, 1, RI_ALL_ONLINE }, { 0x164260, 1, RI_ALL_ONLINE },
+	{ 0x164270, 2, RI_ALL_ONLINE }, { 0x164280, 2, RI_ALL_ONLINE },
+	{ 0x164800, 2, RI_ALL_ONLINE }, { 0x165000, 2, RI_ALL_ONLINE },
+	{ 0x166000, 164, RI_ALL_ONLINE }, { 0x16629c, 1, RI_ALL_ONLINE },
+	{ 0x1662ac, 1, RI_ALL_ONLINE }, { 0x1662bc, 1, RI_ALL_ONLINE },
+	{ 0x166400, 49, RI_ALL_ONLINE }, { 0x1664c8, 38, RI_ALL_ONLINE },
+	{ 0x166568, 2, RI_ALL_ONLINE }, { 0x166800, 1, RI_ALL_ONLINE },
+	{ 0x168000, 270, RI_ALL_ONLINE }, { 0x168444, 1, RI_ALL_ONLINE },
+	{ 0x168454, 1, RI_ALL_ONLINE }, { 0x168800, 19, RI_ALL_ONLINE },
+	{ 0x168900, 1, RI_ALL_ONLINE }, { 0x168a00, 128, RI_ALL_ONLINE },
+	{ 0x16a000, 1, RI_ALL_ONLINE }, { 0x16a004, 1535, RI_ALL_OFFLINE },
+	{ 0x16c000, 1, RI_ALL_ONLINE }, { 0x16c004, 1535, RI_ALL_OFFLINE },
+	{ 0x16e000, 16, RI_E1H_ONLINE }, { 0x16e100, 1, RI_E1H_ONLINE },
+	{ 0x16e200, 2, RI_E1H_ONLINE }, { 0x16e400, 183, RI_E1H_ONLINE },
+	{ 0x170000, 93, RI_ALL_ONLINE }, { 0x170180, 1, RI_ALL_ONLINE },
+	{ 0x170190, 1, RI_ALL_ONLINE }, { 0x170200, 4, RI_ALL_ONLINE },
+	{ 0x170214, 1, RI_ALL_ONLINE }, { 0x178000, 1, RI_ALL_ONLINE },
+	{ 0x180000, 61, RI_ALL_ONLINE }, { 0x180100, 1, RI_ALL_ONLINE },
+	{ 0x180110, 1, RI_ALL_ONLINE }, { 0x180120, 1, RI_ALL_ONLINE },
+	{ 0x180130, 1, RI_ALL_ONLINE }, { 0x18013c, 2, RI_E1H_ONLINE },
+	{ 0x180200, 58, RI_ALL_ONLINE }, { 0x180340, 4, RI_ALL_ONLINE },
+	{ 0x180400, 1, RI_ALL_ONLINE }, { 0x180404, 255, RI_ALL_OFFLINE },
+	{ 0x181000, 4, RI_ALL_ONLINE }, { 0x181010, 1020, RI_ALL_OFFLINE },
+	{ 0x1a0000, 1, RI_ALL_ONLINE }, { 0x1a0004, 1023, RI_ALL_OFFLINE },
+	{ 0x1a1000, 1, RI_ALL_ONLINE }, { 0x1a1004, 4607, RI_ALL_OFFLINE },
+	{ 0x1a5800, 2560, RI_E1H_OFFLINE }, { 0x1a8000, 64, RI_ALL_OFFLINE },
+	{ 0x1a8100, 1984, RI_E1H_OFFLINE }, { 0x1aa000, 1, RI_E1H_ONLINE },
+	{ 0x1aa004, 6655, RI_E1H_OFFLINE }, { 0x1b1800, 128, RI_ALL_OFFLINE },
+	{ 0x1b1c00, 128, RI_ALL_OFFLINE }, { 0x1b2000, 1, RI_ALL_OFFLINE },
+	{ 0x1b2400, 64, RI_E1H_OFFLINE }, { 0x1b8200, 1, RI_ALL_ONLINE },
+	{ 0x1b8240, 1, RI_ALL_ONLINE }, { 0x1b8280, 1, RI_ALL_ONLINE },
+	{ 0x1b82c0, 1, RI_ALL_ONLINE }, { 0x1b8a00, 1, RI_ALL_ONLINE },
+	{ 0x1b8a80, 1, RI_ALL_ONLINE }, { 0x1c0000, 2, RI_ALL_ONLINE },
+	{ 0x200000, 65, RI_ALL_ONLINE }, { 0x200110, 1, RI_ALL_ONLINE },
+	{ 0x200120, 1, RI_ALL_ONLINE }, { 0x200130, 1, RI_ALL_ONLINE },
+	{ 0x200140, 1, RI_ALL_ONLINE }, { 0x20014c, 2, RI_E1H_ONLINE },
+	{ 0x200200, 58, RI_ALL_ONLINE }, { 0x200340, 4, RI_ALL_ONLINE },
+	{ 0x200400, 1, RI_ALL_ONLINE }, { 0x200404, 255, RI_ALL_OFFLINE },
+	{ 0x202000, 4, RI_ALL_ONLINE }, { 0x202010, 2044, RI_ALL_OFFLINE },
+	{ 0x220000, 1, RI_ALL_ONLINE }, { 0x220004, 1023, RI_ALL_OFFLINE },
+	{ 0x221000, 1, RI_ALL_ONLINE }, { 0x221004, 4607, RI_ALL_OFFLINE },
+	{ 0x225800, 1536, RI_E1H_OFFLINE }, { 0x227000, 1, RI_E1H_ONLINE },
+	{ 0x227004, 1023, RI_E1H_OFFLINE }, { 0x228000, 64, RI_ALL_OFFLINE },
+	{ 0x228100, 8640, RI_E1H_OFFLINE }, { 0x231800, 128, RI_ALL_OFFLINE },
+	{ 0x231c00, 128, RI_ALL_OFFLINE }, { 0x232000, 1, RI_ALL_OFFLINE },
+	{ 0x232400, 64, RI_E1H_OFFLINE }, { 0x238200, 1, RI_ALL_ONLINE },
+	{ 0x238240, 1, RI_ALL_ONLINE }, { 0x238280, 1, RI_ALL_ONLINE },
+	{ 0x2382c0, 1, RI_ALL_ONLINE }, { 0x238a00, 1, RI_ALL_ONLINE },
+	{ 0x238a80, 1, RI_ALL_ONLINE }, { 0x240000, 2, RI_ALL_ONLINE },
+	{ 0x280000, 65, RI_ALL_ONLINE }, { 0x280110, 1, RI_ALL_ONLINE },
+	{ 0x280120, 1, RI_ALL_ONLINE }, { 0x280130, 1, RI_ALL_ONLINE },
+	{ 0x280140, 1, RI_ALL_ONLINE }, { 0x28014c, 2, RI_E1H_ONLINE },
+	{ 0x280200, 58, RI_ALL_ONLINE }, { 0x280340, 4, RI_ALL_ONLINE },
+	{ 0x280400, 1, RI_ALL_ONLINE }, { 0x280404, 255, RI_ALL_OFFLINE },
+	{ 0x282000, 4, RI_ALL_ONLINE }, { 0x282010, 2044, RI_ALL_OFFLINE },
+	{ 0x2a0000, 1, RI_ALL_ONLINE }, { 0x2a0004, 1023, RI_ALL_OFFLINE },
+	{ 0x2a1000, 1, RI_ALL_ONLINE }, { 0x2a1004, 4607, RI_ALL_OFFLINE },
+	{ 0x2a5800, 2560, RI_E1H_OFFLINE }, { 0x2a8000, 64, RI_ALL_OFFLINE },
+	{ 0x2a8100, 960, RI_E1H_OFFLINE }, { 0x2a9000, 1, RI_E1H_ONLINE },
+	{ 0x2a9004, 7679, RI_E1H_OFFLINE }, { 0x2b1800, 128, RI_ALL_OFFLINE },
+	{ 0x2b1c00, 128, RI_ALL_OFFLINE }, { 0x2b2000, 1, RI_ALL_OFFLINE },
+	{ 0x2b2400, 64, RI_E1H_OFFLINE }, { 0x2b8200, 1, RI_ALL_ONLINE },
+	{ 0x2b8240, 1, RI_ALL_ONLINE }, { 0x2b8280, 1, RI_ALL_ONLINE },
+	{ 0x2b82c0, 1, RI_ALL_ONLINE }, { 0x2b8a00, 1, RI_ALL_ONLINE },
+	{ 0x2b8a80, 1, RI_ALL_ONLINE }, { 0x2c0000, 2, RI_ALL_ONLINE },
+	{ 0x300000, 65, RI_ALL_ONLINE }, { 0x300110, 1, RI_ALL_ONLINE },
+	{ 0x300120, 1, RI_ALL_ONLINE }, { 0x300130, 1, RI_ALL_ONLINE },
+	{ 0x300140, 1, RI_ALL_ONLINE }, { 0x30014c, 2, RI_E1H_ONLINE },
+	{ 0x300200, 58, RI_ALL_ONLINE }, { 0x300340, 4, RI_ALL_ONLINE },
+	{ 0x300400, 1, RI_ALL_ONLINE }, { 0x300404, 255, RI_ALL_OFFLINE },
+	{ 0x302000, 4, RI_ALL_ONLINE }, { 0x302010, 2044, RI_ALL_OFFLINE },
+	{ 0x320000, 1, RI_ALL_ONLINE }, { 0x320004, 1023, RI_ALL_OFFLINE },
+	{ 0x321000, 1, RI_ALL_ONLINE }, { 0x321004, 4607, RI_ALL_OFFLINE },
+	{ 0x325800, 2560, RI_E1H_OFFLINE }, { 0x328000, 64, RI_ALL_OFFLINE },
+	{ 0x328100, 536, RI_E1H_OFFLINE }, { 0x328960, 1, RI_E1H_ONLINE },
+	{ 0x328964, 8103, RI_E1H_OFFLINE }, { 0x331800, 128, RI_ALL_OFFLINE },
+	{ 0x331c00, 128, RI_ALL_OFFLINE }, { 0x332000, 1, RI_ALL_OFFLINE },
+	{ 0x332400, 64, RI_E1H_OFFLINE }, { 0x338200, 1, RI_ALL_ONLINE },
+	{ 0x338240, 1, RI_ALL_ONLINE }, { 0x338280, 1, RI_ALL_ONLINE },
+	{ 0x3382c0, 1, RI_ALL_ONLINE }, { 0x338a00, 1, RI_ALL_ONLINE },
+	{ 0x338a80, 1, RI_ALL_ONLINE }, { 0x340000, 2, RI_ALL_ONLINE }
 };
 
 
-#define IDLEREGS_COUNT		277
-static const struct reg_addr idle_addrs[IDLEREGS_COUNT] = {
-	{ 0x2114, 1, RI_ALL_ONLINE}, { 0x2120, 1, RI_ALL_ONLINE},
-	{ 0x212c, 4, RI_ALL_ONLINE}, { 0x2814, 1, RI_ALL_ONLINE},
-	{ 0x281c, 2, RI_ALL_ONLINE}, { 0xa38c, 1, RI_ALL_ONLINE},
-	{ 0xa408, 1, RI_ALL_ONLINE}, { 0xa42c, 12, RI_ALL_ONLINE},
-	{ 0xa600, 5, RI_E1H_ONLINE}, { 0xa618, 1, RI_E1H_ONLINE},
-	{ 0xc09c, 1, RI_ALL_ONLINE}, { 0x103b0, 1, RI_ALL_ONLINE},
-	{ 0x103c0, 1, RI_ALL_ONLINE}, { 0x103d0, 1, RI_E1H_ONLINE},
-	{ 0x2021c, 11, RI_ALL_ONLINE}, { 0x202a8, 1, RI_ALL_ONLINE},
-	{ 0x202b8, 1, RI_ALL_ONLINE}, { 0x20404, 1, RI_ALL_ONLINE},
-	{ 0x2040c, 2, RI_ALL_ONLINE}, { 0x2041c, 2, RI_ALL_ONLINE},
-	{ 0x40154, 14, RI_ALL_ONLINE}, { 0x40198, 1, RI_ALL_ONLINE},
-	{ 0x404ac, 1, RI_ALL_ONLINE}, { 0x404bc, 1, RI_ALL_ONLINE},
-	{ 0x42290, 1, RI_ALL_ONLINE}, { 0x422a0, 1, RI_ALL_ONLINE},
-	{ 0x422b0, 1, RI_ALL_ONLINE}, { 0x42548, 1, RI_ALL_ONLINE},
-	{ 0x42550, 1, RI_ALL_ONLINE}, { 0x42558, 1, RI_ALL_ONLINE},
-	{ 0x50160, 8, RI_ALL_ONLINE}, { 0x501d0, 1, RI_ALL_ONLINE},
-	{ 0x501e0, 1, RI_ALL_ONLINE}, { 0x50204, 1, RI_ALL_ONLINE},
-	{ 0x5020c, 2, RI_ALL_ONLINE}, { 0x5021c, 1, RI_ALL_ONLINE},
-	{ 0x60090, 1, RI_ALL_ONLINE}, { 0x6011c, 1, RI_ALL_ONLINE},
-	{ 0x6012c, 1, RI_ALL_ONLINE}, { 0xc101c, 1, RI_ALL_ONLINE},
-	{ 0xc102c, 1, RI_ALL_ONLINE}, { 0xc2290, 1, RI_ALL_ONLINE},
-	{ 0xc22a0, 1, RI_ALL_ONLINE}, { 0xc22b0, 1, RI_ALL_ONLINE},
-	{ 0xc2548, 1, RI_ALL_ONLINE}, { 0xc2550, 1, RI_ALL_ONLINE},
-	{ 0xc2558, 1, RI_ALL_ONLINE}, { 0xc4294, 1, RI_ALL_ONLINE},
-	{ 0xc42a4, 1, RI_ALL_ONLINE}, { 0xc42b4, 1, RI_ALL_ONLINE},
-	{ 0xc4550, 1, RI_ALL_ONLINE}, { 0xc4558, 1, RI_ALL_ONLINE},
-	{ 0xc4560, 1, RI_ALL_ONLINE}, { 0xd016c, 8, RI_ALL_ONLINE},
-	{ 0xd01d8, 1, RI_ALL_ONLINE}, { 0xd01e8, 1, RI_ALL_ONLINE},
-	{ 0xd0204, 1, RI_ALL_ONLINE}, { 0xd020c, 3, RI_ALL_ONLINE},
-	{ 0xe0154, 8, RI_ALL_ONLINE}, { 0xe01c8, 1, RI_ALL_ONLINE},
-	{ 0xe01d8, 1, RI_ALL_ONLINE}, { 0xe0204, 1, RI_ALL_ONLINE},
-	{ 0xe020c, 2, RI_ALL_ONLINE}, { 0xe021c, 2, RI_ALL_ONLINE},
-	{ 0x101014, 1, RI_ALL_ONLINE}, { 0x101030, 1, RI_ALL_ONLINE},
-	{ 0x101040, 1, RI_ALL_ONLINE}, { 0x102058, 1, RI_ALL_ONLINE},
-	{ 0x102080, 16, RI_ALL_ONLINE}, { 0x103004, 2, RI_ALL_ONLINE},
-	{ 0x103068, 1, RI_ALL_ONLINE}, { 0x103078, 1, RI_ALL_ONLINE},
-	{ 0x103088, 1, RI_ALL_ONLINE}, { 0x10309c, 2, RI_E1H_ONLINE},
-	{ 0x104004, 1, RI_ALL_ONLINE}, { 0x104018, 1, RI_ALL_ONLINE},
-	{ 0x104020, 1, RI_ALL_ONLINE}, { 0x10403c, 1, RI_ALL_ONLINE},
-	{ 0x1040fc, 1, RI_ALL_ONLINE}, { 0x10410c, 1, RI_ALL_ONLINE},
-	{ 0x104400, 64, RI_ALL_ONLINE}, { 0x104800, 64, RI_ALL_ONLINE},
-	{ 0x105000, 3, RI_ALL_ONLINE}, { 0x105010, 3, RI_ALL_ONLINE},
-	{ 0x105020, 3, RI_ALL_ONLINE}, { 0x105030, 3, RI_ALL_ONLINE},
-	{ 0x105040, 3, RI_ALL_ONLINE}, { 0x105050, 3, RI_ALL_ONLINE},
-	{ 0x105060, 3, RI_ALL_ONLINE}, { 0x105070, 3, RI_ALL_ONLINE},
-	{ 0x105080, 3, RI_ALL_ONLINE}, { 0x105090, 3, RI_ALL_ONLINE},
-	{ 0x1050a0, 3, RI_ALL_ONLINE}, { 0x1050b0, 3, RI_ALL_ONLINE},
-	{ 0x1050c0, 3, RI_ALL_ONLINE}, { 0x1050d0, 3, RI_ALL_ONLINE},
-	{ 0x1050e0, 3, RI_ALL_ONLINE}, { 0x1050f0, 3, RI_ALL_ONLINE},
-	{ 0x105100, 3, RI_ALL_ONLINE}, { 0x105110, 3, RI_ALL_ONLINE},
-	{ 0x105120, 3, RI_ALL_ONLINE}, { 0x105130, 3, RI_ALL_ONLINE},
-	{ 0x105140, 3, RI_ALL_ONLINE}, { 0x105150, 3, RI_ALL_ONLINE},
-	{ 0x105160, 3, RI_ALL_ONLINE}, { 0x105170, 3, RI_ALL_ONLINE},
-	{ 0x105180, 3, RI_ALL_ONLINE}, { 0x105190, 3, RI_ALL_ONLINE},
-	{ 0x1051a0, 3, RI_ALL_ONLINE}, { 0x1051b0, 3, RI_ALL_ONLINE},
-	{ 0x1051c0, 3, RI_ALL_ONLINE}, { 0x1051d0, 3, RI_ALL_ONLINE},
-	{ 0x1051e0, 3, RI_ALL_ONLINE}, { 0x1051f0, 3, RI_ALL_ONLINE},
-	{ 0x105200, 3, RI_ALL_ONLINE}, { 0x105210, 3, RI_ALL_ONLINE},
-	{ 0x105220, 3, RI_ALL_ONLINE}, { 0x105230, 3, RI_ALL_ONLINE},
-	{ 0x105240, 3, RI_ALL_ONLINE}, { 0x105250, 3, RI_ALL_ONLINE},
-	{ 0x105260, 3, RI_ALL_ONLINE}, { 0x105270, 3, RI_ALL_ONLINE},
-	{ 0x105280, 3, RI_ALL_ONLINE}, { 0x105290, 3, RI_ALL_ONLINE},
-	{ 0x1052a0, 3, RI_ALL_ONLINE}, { 0x1052b0, 3, RI_ALL_ONLINE},
-	{ 0x1052c0, 3, RI_ALL_ONLINE}, { 0x1052d0, 3, RI_ALL_ONLINE},
-	{ 0x1052e0, 3, RI_ALL_ONLINE}, { 0x1052f0, 3, RI_ALL_ONLINE},
-	{ 0x105300, 3, RI_ALL_ONLINE}, { 0x105310, 3, RI_ALL_ONLINE},
-	{ 0x105320, 3, RI_ALL_ONLINE}, { 0x105330, 3, RI_ALL_ONLINE},
-	{ 0x105340, 3, RI_ALL_ONLINE}, { 0x105350, 3, RI_ALL_ONLINE},
-	{ 0x105360, 3, RI_ALL_ONLINE}, { 0x105370, 3, RI_ALL_ONLINE},
-	{ 0x105380, 3, RI_ALL_ONLINE}, { 0x105390, 3, RI_ALL_ONLINE},
-	{ 0x1053a0, 3, RI_ALL_ONLINE}, { 0x1053b0, 3, RI_ALL_ONLINE},
-	{ 0x1053c0, 3, RI_ALL_ONLINE}, { 0x1053d0, 3, RI_ALL_ONLINE},
-	{ 0x1053e0, 3, RI_ALL_ONLINE}, { 0x1053f0, 3, RI_ALL_ONLINE},
-	{ 0x108094, 1, RI_ALL_ONLINE}, { 0x1201b0, 2, RI_ALL_ONLINE},
-	{ 0x12032c, 1, RI_ALL_ONLINE}, { 0x12036c, 3, RI_ALL_ONLINE},
-	{ 0x120408, 2, RI_ALL_ONLINE}, { 0x120414, 15, RI_ALL_ONLINE},
-	{ 0x120478, 2, RI_ALL_ONLINE}, { 0x12052c, 1, RI_ALL_ONLINE},
-	{ 0x120564, 3, RI_ALL_ONLINE}, { 0x12057c, 1, RI_ALL_ONLINE},
-	{ 0x12058c, 1, RI_ALL_ONLINE}, { 0x120608, 1, RI_E1H_ONLINE},
-	{ 0x120808, 1, RI_E1_ONLINE}, { 0x12080c, 2, RI_ALL_ONLINE},
-	{ 0x120818, 1, RI_ALL_ONLINE}, { 0x120820, 1, RI_ALL_ONLINE},
-	{ 0x120828, 1, RI_ALL_ONLINE}, { 0x120830, 1, RI_ALL_ONLINE},
-	{ 0x120838, 1, RI_ALL_ONLINE}, { 0x120840, 1, RI_ALL_ONLINE},
-	{ 0x120848, 1, RI_ALL_ONLINE}, { 0x120850, 1, RI_ALL_ONLINE},
-	{ 0x120858, 1, RI_ALL_ONLINE}, { 0x120860, 1, RI_ALL_ONLINE},
-	{ 0x120868, 1, RI_ALL_ONLINE}, { 0x120870, 1, RI_ALL_ONLINE},
-	{ 0x120878, 1, RI_ALL_ONLINE}, { 0x120880, 1, RI_ALL_ONLINE},
-	{ 0x120888, 1, RI_ALL_ONLINE}, { 0x120890, 1, RI_ALL_ONLINE},
-	{ 0x120898, 1, RI_ALL_ONLINE}, { 0x1208a0, 1, RI_ALL_ONLINE},
-	{ 0x1208a8, 1, RI_ALL_ONLINE}, { 0x1208b0, 1, RI_ALL_ONLINE},
-	{ 0x1208b8, 1, RI_ALL_ONLINE}, { 0x1208c0, 1, RI_ALL_ONLINE},
-	{ 0x1208c8, 1, RI_ALL_ONLINE}, { 0x1208d0, 1, RI_ALL_ONLINE},
-	{ 0x1208d8, 1, RI_ALL_ONLINE}, { 0x1208e0, 1, RI_ALL_ONLINE},
-	{ 0x1208e8, 1, RI_ALL_ONLINE}, { 0x1208f0, 1, RI_ALL_ONLINE},
-	{ 0x1208f8, 1, RI_ALL_ONLINE}, { 0x120900, 1, RI_ALL_ONLINE},
-	{ 0x120908, 1, RI_ALL_ONLINE}, { 0x14005c, 2, RI_ALL_ONLINE},
-	{ 0x1400d0, 2, RI_ALL_ONLINE}, { 0x1400e0, 1, RI_ALL_ONLINE},
-	{ 0x1401c8, 1, RI_ALL_ONLINE}, { 0x140200, 6, RI_ALL_ONLINE},
-	{ 0x16101c, 1, RI_ALL_ONLINE}, { 0x16102c, 1, RI_ALL_ONLINE},
-	{ 0x164014, 2, RI_ALL_ONLINE}, { 0x1640f0, 1, RI_ALL_ONLINE},
-	{ 0x166290, 1, RI_ALL_ONLINE}, { 0x1662a0, 1, RI_ALL_ONLINE},
-	{ 0x1662b0, 1, RI_ALL_ONLINE}, { 0x166548, 1, RI_ALL_ONLINE},
-	{ 0x166550, 1, RI_ALL_ONLINE}, { 0x166558, 1, RI_ALL_ONLINE},
-	{ 0x168000, 1, RI_ALL_ONLINE}, { 0x168008, 1, RI_ALL_ONLINE},
-	{ 0x168010, 1, RI_ALL_ONLINE}, { 0x168018, 1, RI_ALL_ONLINE},
-	{ 0x168028, 2, RI_ALL_ONLINE}, { 0x168058, 4, RI_ALL_ONLINE},
-	{ 0x168070, 1, RI_ALL_ONLINE}, { 0x168238, 1, RI_ALL_ONLINE},
-	{ 0x1682d0, 2, RI_ALL_ONLINE}, { 0x1682e0, 1, RI_ALL_ONLINE},
-	{ 0x168300, 67, RI_ALL_ONLINE}, { 0x168410, 2, RI_ALL_ONLINE},
-	{ 0x168438, 1, RI_ALL_ONLINE}, { 0x168448, 1, RI_ALL_ONLINE},
-	{ 0x168a00, 128, RI_ALL_ONLINE}, { 0x16e200, 128, RI_E1H_ONLINE},
-	{ 0x16e404, 2, RI_E1H_ONLINE}, { 0x16e584, 70, RI_E1H_ONLINE},
-	{ 0x1700a4, 1, RI_ALL_ONLINE}, { 0x1700ac, 2, RI_ALL_ONLINE},
-	{ 0x1700c0, 1, RI_ALL_ONLINE}, { 0x170174, 1, RI_ALL_ONLINE},
-	{ 0x170184, 1, RI_ALL_ONLINE}, { 0x1800f4, 1, RI_ALL_ONLINE},
-	{ 0x180104, 1, RI_ALL_ONLINE}, { 0x180114, 1, RI_ALL_ONLINE},
-	{ 0x180124, 1, RI_ALL_ONLINE}, { 0x18026c, 1, RI_ALL_ONLINE},
-	{ 0x1802a0, 1, RI_ALL_ONLINE}, { 0x1a1000, 1, RI_ALL_ONLINE},
-	{ 0x1aa000, 1, RI_E1H_ONLINE}, { 0x1b8000, 1, RI_ALL_ONLINE},
-	{ 0x1b8040, 1, RI_ALL_ONLINE}, { 0x1b8080, 1, RI_ALL_ONLINE},
-	{ 0x1b80c0, 1, RI_ALL_ONLINE}, { 0x200104, 1, RI_ALL_ONLINE},
-	{ 0x200114, 1, RI_ALL_ONLINE}, { 0x200124, 1, RI_ALL_ONLINE},
-	{ 0x200134, 1, RI_ALL_ONLINE}, { 0x20026c, 1, RI_ALL_ONLINE},
-	{ 0x2002a0, 1, RI_ALL_ONLINE}, { 0x221000, 1, RI_ALL_ONLINE},
-	{ 0x227000, 1, RI_E1H_ONLINE}, { 0x238000, 1, RI_ALL_ONLINE},
-	{ 0x238040, 1, RI_ALL_ONLINE}, { 0x238080, 1, RI_ALL_ONLINE},
-	{ 0x2380c0, 1, RI_ALL_ONLINE}, { 0x280104, 1, RI_ALL_ONLINE},
-	{ 0x280114, 1, RI_ALL_ONLINE}, { 0x280124, 1, RI_ALL_ONLINE},
-	{ 0x280134, 1, RI_ALL_ONLINE}, { 0x28026c, 1, RI_ALL_ONLINE},
-	{ 0x2802a0, 1, RI_ALL_ONLINE}, { 0x2a1000, 1, RI_ALL_ONLINE},
-	{ 0x2a9000, 1, RI_E1H_ONLINE}, { 0x2b8000, 1, RI_ALL_ONLINE},
-	{ 0x2b8040, 1, RI_ALL_ONLINE}, { 0x2b8080, 1, RI_ALL_ONLINE},
-	{ 0x2b80c0, 1, RI_ALL_ONLINE}, { 0x300104, 1, RI_ALL_ONLINE},
-	{ 0x300114, 1, RI_ALL_ONLINE}, { 0x300124, 1, RI_ALL_ONLINE},
-	{ 0x300134, 1, RI_ALL_ONLINE}, { 0x30026c, 1, RI_ALL_ONLINE},
-	{ 0x3002a0, 1, RI_ALL_ONLINE}, { 0x321000, 1, RI_ALL_ONLINE},
-	{ 0x328960, 1, RI_E1H_ONLINE}, { 0x338000, 1, RI_ALL_ONLINE},
-	{ 0x338040, 1, RI_ALL_ONLINE}, { 0x338080, 1, RI_ALL_ONLINE},
-	{ 0x3380c0, 1, RI_ALL_ONLINE}
+#define IDLE_REGS_COUNT			277
+static const struct reg_addr idle_addrs[IDLE_REGS_COUNT] = {
+	{ 0x2114, 1, RI_ALL_ONLINE }, { 0x2120, 1, RI_ALL_ONLINE },
+	{ 0x212c, 4, RI_ALL_ONLINE }, { 0x2814, 1, RI_ALL_ONLINE },
+	{ 0x281c, 2, RI_ALL_ONLINE }, { 0xa38c, 1, RI_ALL_ONLINE },
+	{ 0xa408, 1, RI_ALL_ONLINE }, { 0xa42c, 12, RI_ALL_ONLINE },
+	{ 0xa600, 5, RI_E1H_ONLINE }, { 0xa618, 1, RI_E1H_ONLINE },
+	{ 0xc09c, 1, RI_ALL_ONLINE }, { 0x103b0, 1, RI_ALL_ONLINE },
+	{ 0x103c0, 1, RI_ALL_ONLINE }, { 0x103d0, 1, RI_E1H_ONLINE },
+	{ 0x2021c, 11, RI_ALL_ONLINE }, { 0x202a8, 1, RI_ALL_ONLINE },
+	{ 0x202b8, 1, RI_ALL_ONLINE }, { 0x20404, 1, RI_ALL_ONLINE },
+	{ 0x2040c, 2, RI_ALL_ONLINE }, { 0x2041c, 2, RI_ALL_ONLINE },
+	{ 0x40154, 14, RI_ALL_ONLINE }, { 0x40198, 1, RI_ALL_ONLINE },
+	{ 0x404ac, 1, RI_ALL_ONLINE }, { 0x404bc, 1, RI_ALL_ONLINE },
+	{ 0x42290, 1, RI_ALL_ONLINE }, { 0x422a0, 1, RI_ALL_ONLINE },
+	{ 0x422b0, 1, RI_ALL_ONLINE }, { 0x42548, 1, RI_ALL_ONLINE },
+	{ 0x42550, 1, RI_ALL_ONLINE }, { 0x42558, 1, RI_ALL_ONLINE },
+	{ 0x50160, 8, RI_ALL_ONLINE }, { 0x501d0, 1, RI_ALL_ONLINE },
+	{ 0x501e0, 1, RI_ALL_ONLINE }, { 0x50204, 1, RI_ALL_ONLINE },
+	{ 0x5020c, 2, RI_ALL_ONLINE }, { 0x5021c, 1, RI_ALL_ONLINE },
+	{ 0x60090, 1, RI_ALL_ONLINE }, { 0x6011c, 1, RI_ALL_ONLINE },
+	{ 0x6012c, 1, RI_ALL_ONLINE }, { 0xc101c, 1, RI_ALL_ONLINE },
+	{ 0xc102c, 1, RI_ALL_ONLINE }, { 0xc2290, 1, RI_ALL_ONLINE },
+	{ 0xc22a0, 1, RI_ALL_ONLINE }, { 0xc22b0, 1, RI_ALL_ONLINE },
+	{ 0xc2548, 1, RI_ALL_ONLINE }, { 0xc2550, 1, RI_ALL_ONLINE },
+	{ 0xc2558, 1, RI_ALL_ONLINE }, { 0xc4294, 1, RI_ALL_ONLINE },
+	{ 0xc42a4, 1, RI_ALL_ONLINE }, { 0xc42b4, 1, RI_ALL_ONLINE },
+	{ 0xc4550, 1, RI_ALL_ONLINE }, { 0xc4558, 1, RI_ALL_ONLINE },
+	{ 0xc4560, 1, RI_ALL_ONLINE }, { 0xd016c, 8, RI_ALL_ONLINE },
+	{ 0xd01d8, 1, RI_ALL_ONLINE }, { 0xd01e8, 1, RI_ALL_ONLINE },
+	{ 0xd0204, 1, RI_ALL_ONLINE }, { 0xd020c, 3, RI_ALL_ONLINE },
+	{ 0xe0154, 8, RI_ALL_ONLINE }, { 0xe01c8, 1, RI_ALL_ONLINE },
+	{ 0xe01d8, 1, RI_ALL_ONLINE }, { 0xe0204, 1, RI_ALL_ONLINE },
+	{ 0xe020c, 2, RI_ALL_ONLINE }, { 0xe021c, 2, RI_ALL_ONLINE },
+	{ 0x101014, 1, RI_ALL_ONLINE }, { 0x101030, 1, RI_ALL_ONLINE },
+	{ 0x101040, 1, RI_ALL_ONLINE }, { 0x102058, 1, RI_ALL_ONLINE },
+	{ 0x102080, 16, RI_ALL_ONLINE }, { 0x103004, 2, RI_ALL_ONLINE },
+	{ 0x103068, 1, RI_ALL_ONLINE }, { 0x103078, 1, RI_ALL_ONLINE },
+	{ 0x103088, 1, RI_ALL_ONLINE }, { 0x10309c, 2, RI_E1H_ONLINE },
+	{ 0x104004, 1, RI_ALL_ONLINE }, { 0x104018, 1, RI_ALL_ONLINE },
+	{ 0x104020, 1, RI_ALL_ONLINE }, { 0x10403c, 1, RI_ALL_ONLINE },
+	{ 0x1040fc, 1, RI_ALL_ONLINE }, { 0x10410c, 1, RI_ALL_ONLINE },
+	{ 0x104400, 64, RI_ALL_ONLINE }, { 0x104800, 64, RI_ALL_ONLINE },
+	{ 0x105000, 3, RI_ALL_ONLINE }, { 0x105010, 3, RI_ALL_ONLINE },
+	{ 0x105020, 3, RI_ALL_ONLINE }, { 0x105030, 3, RI_ALL_ONLINE },
+	{ 0x105040, 3, RI_ALL_ONLINE }, { 0x105050, 3, RI_ALL_ONLINE },
+	{ 0x105060, 3, RI_ALL_ONLINE }, { 0x105070, 3, RI_ALL_ONLINE },
+	{ 0x105080, 3, RI_ALL_ONLINE }, { 0x105090, 3, RI_ALL_ONLINE },
+	{ 0x1050a0, 3, RI_ALL_ONLINE }, { 0x1050b0, 3, RI_ALL_ONLINE },
+	{ 0x1050c0, 3, RI_ALL_ONLINE }, { 0x1050d0, 3, RI_ALL_ONLINE },
+	{ 0x1050e0, 3, RI_ALL_ONLINE }, { 0x1050f0, 3, RI_ALL_ONLINE },
+	{ 0x105100, 3, RI_ALL_ONLINE }, { 0x105110, 3, RI_ALL_ONLINE },
+	{ 0x105120, 3, RI_ALL_ONLINE }, { 0x105130, 3, RI_ALL_ONLINE },
+	{ 0x105140, 3, RI_ALL_ONLINE }, { 0x105150, 3, RI_ALL_ONLINE },
+	{ 0x105160, 3, RI_ALL_ONLINE }, { 0x105170, 3, RI_ALL_ONLINE },
+	{ 0x105180, 3, RI_ALL_ONLINE }, { 0x105190, 3, RI_ALL_ONLINE },
+	{ 0x1051a0, 3, RI_ALL_ONLINE }, { 0x1051b0, 3, RI_ALL_ONLINE },
+	{ 0x1051c0, 3, RI_ALL_ONLINE }, { 0x1051d0, 3, RI_ALL_ONLINE },
+	{ 0x1051e0, 3, RI_ALL_ONLINE }, { 0x1051f0, 3, RI_ALL_ONLINE },
+	{ 0x105200, 3, RI_ALL_ONLINE }, { 0x105210, 3, RI_ALL_ONLINE },
+	{ 0x105220, 3, RI_ALL_ONLINE }, { 0x105230, 3, RI_ALL_ONLINE },
+	{ 0x105240, 3, RI_ALL_ONLINE }, { 0x105250, 3, RI_ALL_ONLINE },
+	{ 0x105260, 3, RI_ALL_ONLINE }, { 0x105270, 3, RI_ALL_ONLINE },
+	{ 0x105280, 3, RI_ALL_ONLINE }, { 0x105290, 3, RI_ALL_ONLINE },
+	{ 0x1052a0, 3, RI_ALL_ONLINE }, { 0x1052b0, 3, RI_ALL_ONLINE },
+	{ 0x1052c0, 3, RI_ALL_ONLINE }, { 0x1052d0, 3, RI_ALL_ONLINE },
+	{ 0x1052e0, 3, RI_ALL_ONLINE }, { 0x1052f0, 3, RI_ALL_ONLINE },
+	{ 0x105300, 3, RI_ALL_ONLINE }, { 0x105310, 3, RI_ALL_ONLINE },
+	{ 0x105320, 3, RI_ALL_ONLINE }, { 0x105330, 3, RI_ALL_ONLINE },
+	{ 0x105340, 3, RI_ALL_ONLINE }, { 0x105350, 3, RI_ALL_ONLINE },
+	{ 0x105360, 3, RI_ALL_ONLINE }, { 0x105370, 3, RI_ALL_ONLINE },
+	{ 0x105380, 3, RI_ALL_ONLINE }, { 0x105390, 3, RI_ALL_ONLINE },
+	{ 0x1053a0, 3, RI_ALL_ONLINE }, { 0x1053b0, 3, RI_ALL_ONLINE },
+	{ 0x1053c0, 3, RI_ALL_ONLINE }, { 0x1053d0, 3, RI_ALL_ONLINE },
+	{ 0x1053e0, 3, RI_ALL_ONLINE }, { 0x1053f0, 3, RI_ALL_ONLINE },
+	{ 0x108094, 1, RI_ALL_ONLINE }, { 0x1201b0, 2, RI_ALL_ONLINE },
+	{ 0x12032c, 1, RI_ALL_ONLINE }, { 0x12036c, 3, RI_ALL_ONLINE },
+	{ 0x120408, 2, RI_ALL_ONLINE }, { 0x120414, 15, RI_ALL_ONLINE },
+	{ 0x120478, 2, RI_ALL_ONLINE }, { 0x12052c, 1, RI_ALL_ONLINE },
+	{ 0x120564, 3, RI_ALL_ONLINE }, { 0x12057c, 1, RI_ALL_ONLINE },
+	{ 0x12058c, 1, RI_ALL_ONLINE }, { 0x120608, 1, RI_E1H_ONLINE },
+	{ 0x120808, 1, RI_E1_ONLINE }, { 0x12080c, 2, RI_ALL_ONLINE },
+	{ 0x120818, 1, RI_ALL_ONLINE }, { 0x120820, 1, RI_ALL_ONLINE },
+	{ 0x120828, 1, RI_ALL_ONLINE }, { 0x120830, 1, RI_ALL_ONLINE },
+	{ 0x120838, 1, RI_ALL_ONLINE }, { 0x120840, 1, RI_ALL_ONLINE },
+	{ 0x120848, 1, RI_ALL_ONLINE }, { 0x120850, 1, RI_ALL_ONLINE },
+	{ 0x120858, 1, RI_ALL_ONLINE }, { 0x120860, 1, RI_ALL_ONLINE },
+	{ 0x120868, 1, RI_ALL_ONLINE }, { 0x120870, 1, RI_ALL_ONLINE },
+	{ 0x120878, 1, RI_ALL_ONLINE }, { 0x120880, 1, RI_ALL_ONLINE },
+	{ 0x120888, 1, RI_ALL_ONLINE }, { 0x120890, 1, RI_ALL_ONLINE },
+	{ 0x120898, 1, RI_ALL_ONLINE }, { 0x1208a0, 1, RI_ALL_ONLINE },
+	{ 0x1208a8, 1, RI_ALL_ONLINE }, { 0x1208b0, 1, RI_ALL_ONLINE },
+	{ 0x1208b8, 1, RI_ALL_ONLINE }, { 0x1208c0, 1, RI_ALL_ONLINE },
+	{ 0x1208c8, 1, RI_ALL_ONLINE }, { 0x1208d0, 1, RI_ALL_ONLINE },
+	{ 0x1208d8, 1, RI_ALL_ONLINE }, { 0x1208e0, 1, RI_ALL_ONLINE },
+	{ 0x1208e8, 1, RI_ALL_ONLINE }, { 0x1208f0, 1, RI_ALL_ONLINE },
+	{ 0x1208f8, 1, RI_ALL_ONLINE }, { 0x120900, 1, RI_ALL_ONLINE },
+	{ 0x120908, 1, RI_ALL_ONLINE }, { 0x14005c, 2, RI_ALL_ONLINE },
+	{ 0x1400d0, 2, RI_ALL_ONLINE }, { 0x1400e0, 1, RI_ALL_ONLINE },
+	{ 0x1401c8, 1, RI_ALL_ONLINE }, { 0x140200, 6, RI_ALL_ONLINE },
+	{ 0x16101c, 1, RI_ALL_ONLINE }, { 0x16102c, 1, RI_ALL_ONLINE },
+	{ 0x164014, 2, RI_ALL_ONLINE }, { 0x1640f0, 1, RI_ALL_ONLINE },
+	{ 0x166290, 1, RI_ALL_ONLINE }, { 0x1662a0, 1, RI_ALL_ONLINE },
+	{ 0x1662b0, 1, RI_ALL_ONLINE }, { 0x166548, 1, RI_ALL_ONLINE },
+	{ 0x166550, 1, RI_ALL_ONLINE }, { 0x166558, 1, RI_ALL_ONLINE },
+	{ 0x168000, 1, RI_ALL_ONLINE }, { 0x168008, 1, RI_ALL_ONLINE },
+	{ 0x168010, 1, RI_ALL_ONLINE }, { 0x168018, 1, RI_ALL_ONLINE },
+	{ 0x168028, 2, RI_ALL_ONLINE }, { 0x168058, 4, RI_ALL_ONLINE },
+	{ 0x168070, 1, RI_ALL_ONLINE }, { 0x168238, 1, RI_ALL_ONLINE },
+	{ 0x1682d0, 2, RI_ALL_ONLINE }, { 0x1682e0, 1, RI_ALL_ONLINE },
+	{ 0x168300, 67, RI_ALL_ONLINE }, { 0x168410, 2, RI_ALL_ONLINE },
+	{ 0x168438, 1, RI_ALL_ONLINE }, { 0x168448, 1, RI_ALL_ONLINE },
+	{ 0x168a00, 128, RI_ALL_ONLINE }, { 0x16e200, 128, RI_E1H_ONLINE },
+	{ 0x16e404, 2, RI_E1H_ONLINE }, { 0x16e584, 70, RI_E1H_ONLINE },
+	{ 0x1700a4, 1, RI_ALL_ONLINE }, { 0x1700ac, 2, RI_ALL_ONLINE },
+	{ 0x1700c0, 1, RI_ALL_ONLINE }, { 0x170174, 1, RI_ALL_ONLINE },
+	{ 0x170184, 1, RI_ALL_ONLINE }, { 0x1800f4, 1, RI_ALL_ONLINE },
+	{ 0x180104, 1, RI_ALL_ONLINE }, { 0x180114, 1, RI_ALL_ONLINE },
+	{ 0x180124, 1, RI_ALL_ONLINE }, { 0x18026c, 1, RI_ALL_ONLINE },
+	{ 0x1802a0, 1, RI_ALL_ONLINE }, { 0x1a1000, 1, RI_ALL_ONLINE },
+	{ 0x1aa000, 1, RI_E1H_ONLINE }, { 0x1b8000, 1, RI_ALL_ONLINE },
+	{ 0x1b8040, 1, RI_ALL_ONLINE }, { 0x1b8080, 1, RI_ALL_ONLINE },
+	{ 0x1b80c0, 1, RI_ALL_ONLINE }, { 0x200104, 1, RI_ALL_ONLINE },
+	{ 0x200114, 1, RI_ALL_ONLINE }, { 0x200124, 1, RI_ALL_ONLINE },
+	{ 0x200134, 1, RI_ALL_ONLINE }, { 0x20026c, 1, RI_ALL_ONLINE },
+	{ 0x2002a0, 1, RI_ALL_ONLINE }, { 0x221000, 1, RI_ALL_ONLINE },
+	{ 0x227000, 1, RI_E1H_ONLINE }, { 0x238000, 1, RI_ALL_ONLINE },
+	{ 0x238040, 1, RI_ALL_ONLINE }, { 0x238080, 1, RI_ALL_ONLINE },
+	{ 0x2380c0, 1, RI_ALL_ONLINE }, { 0x280104, 1, RI_ALL_ONLINE },
+	{ 0x280114, 1, RI_ALL_ONLINE }, { 0x280124, 1, RI_ALL_ONLINE },
+	{ 0x280134, 1, RI_ALL_ONLINE }, { 0x28026c, 1, RI_ALL_ONLINE },
+	{ 0x2802a0, 1, RI_ALL_ONLINE }, { 0x2a1000, 1, RI_ALL_ONLINE },
+	{ 0x2a9000, 1, RI_E1H_ONLINE }, { 0x2b8000, 1, RI_ALL_ONLINE },
+	{ 0x2b8040, 1, RI_ALL_ONLINE }, { 0x2b8080, 1, RI_ALL_ONLINE },
+	{ 0x2b80c0, 1, RI_ALL_ONLINE }, { 0x300104, 1, RI_ALL_ONLINE },
+	{ 0x300114, 1, RI_ALL_ONLINE }, { 0x300124, 1, RI_ALL_ONLINE },
+	{ 0x300134, 1, RI_ALL_ONLINE }, { 0x30026c, 1, RI_ALL_ONLINE },
+	{ 0x3002a0, 1, RI_ALL_ONLINE }, { 0x321000, 1, RI_ALL_ONLINE },
+	{ 0x328960, 1, RI_E1H_ONLINE }, { 0x338000, 1, RI_ALL_ONLINE },
+	{ 0x338040, 1, RI_ALL_ONLINE }, { 0x338080, 1, RI_ALL_ONLINE },
+	{ 0x3380c0, 1, RI_ALL_ONLINE }
 };
 
+#define WREGS_COUNT_E1			1
 static const u32 read_reg_e1_0[] = { 0x1b1000 };
 
-#define WREGS_COUNT_E1		1
 static const struct wreg_addr wreg_addrs_e1[WREGS_COUNT_E1] = {
 	{ 0x1b0c00, 192, 1, read_reg_e1_0, RI_E1_OFFLINE }
 };
 
+
+#define WREGS_COUNT_E1H			1
 static const u32 read_reg_e1h_0[] = { 0x1b1040, 0x1b1000 };
 
-#define WREGS_COUNT_E1H		1
 static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = {
 	{ 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE }
 };
@@ -512,15 +517,18 @@ static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = {
 static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 };
 
 
-#define TIMER_REGS_COUNT_E1	2
+#define TIMER_REGS_COUNT_E1		2
 static const u32 timer_status_regs_e1[TIMER_REGS_COUNT_E1] =
 	{ 0x164014, 0x164018 };
 static const u32 timer_scan_regs_e1[TIMER_REGS_COUNT_E1] =
 	{ 0x1640d0, 0x1640d4 };
 
-#define TIMER_REGS_COUNT_E1H	2
+
+#define TIMER_REGS_COUNT_E1H		2
 static const u32 timer_status_regs_e1h[TIMER_REGS_COUNT_E1H] =
 	{ 0x164014, 0x164018 };
 static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] =
 	{ 0x1640d0, 0x1640d4 };
 
+
+#endif /* BNX2X_DUMP_H */
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
index e2df238..931dcac 100644
--- a/drivers/net/bnx2x_fw_defs.h
+++ b/drivers/net/bnx2x_fw_defs.h
@@ -12,48 +12,117 @@
 	(IS_E1H_OFFSET ? 0x7000 : 0x1000)
 #define CSTORM_ASSERT_LIST_OFFSET(idx) \
 	(IS_E1H_OFFSET ? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
-#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
-	(IS_E1H_OFFSET ? (0x8522 + ((function>>1) * 0x40) + \
-	((function&1) * 0x100) + (index * 0x4)) : (0x1922 + (function * \
+#define CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(function, index) \
+	(IS_E1H_OFFSET ? (0x8622 + ((function>>1) * 0x40) + \
+	((function&1) * 0x100) + (index * 0x4)) : (0x3562 + (function * \
 	0x40) + (index * 0x4)))
-#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x8500 + ((function>>1) * 0x40) + \
-	((function&1) * 0x100)) : (0x1900 + (function * 0x40)))
-#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x8508 + ((function>>1) * 0x40) + \
-	((function&1) * 0x100)) : (0x1908 + (function * 0x40)))
+#define CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(function, index) \
+	(IS_E1H_OFFSET ? (0x8822 + ((function>>1) * 0x80) + \
+	((function&1) * 0x200) + (index * 0x4)) : (0x35e2 + (function * \
+	0x80) + (index * 0x4)))
+#define CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8600 + ((function>>1) * 0x40) + \
+	((function&1) * 0x100)) : (0x3540 + (function * 0x40)))
+#define CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8800 + ((function>>1) * 0x80) + \
+	((function&1) * 0x200)) : (0x35c0 + (function * 0x80)))
+#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8608 + ((function>>1) * 0x40) + \
+	((function&1) * 0x100)) : (0x3548 + (function * 0x40)))
+#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8808 + ((function>>1) * 0x80) + \
+	((function&1) * 0x200)) : (0x35c8 + (function * 0x80)))
 #define CSTORM_FUNCTION_MODE_OFFSET \
 	(IS_E1H_OFFSET ? 0x11e8 : 0xffffffff)
-#define CSTORM_HC_BTR_OFFSET(port) \
-	(IS_E1H_OFFSET ? (0x8704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
-#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
-	(IS_E1H_OFFSET ? (0x801a + (port * 0x280) + (cpu_id * 0x28) + \
-	(index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
+#define CSTORM_HC_BTR_C_OFFSET(port) \
+	(IS_E1H_OFFSET ? (0x8c04 + (port * 0xf0)) : (0x36c4 + (port * 0xc0)))
+#define CSTORM_HC_BTR_U_OFFSET(port) \
+	(IS_E1H_OFFSET ? (0x8de4 + (port * 0xf0)) : (0x3844 + (port * 0xc0)))
+#define CSTORM_ISCSI_CQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6680 + (function * 0x8)) : (0x25a0 + \
+	(function * 0x8)))
+#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x66c0 + (function * 0x8)) : (0x25b0 + \
+	(function * 0x8)))
+#define CSTORM_ISCSI_EQ_CONS_OFFSET(function, eqIdx) \
+	(IS_E1H_OFFSET ? (0x6040 + (function * 0xc0) + (eqIdx * 0x18)) : \
+	(0x2410 + (function * 0xc0) + (eqIdx * 0x18)))
+#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(function, eqIdx) \
+	(IS_E1H_OFFSET ? (0x6044 + (function * 0xc0) + (eqIdx * 0x18)) : \
+	(0x2414 + (function * 0xc0) + (eqIdx * 0x18)))
+#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(function, eqIdx) \
+	(IS_E1H_OFFSET ? (0x604c + (function * 0xc0) + (eqIdx * 0x18)) : \
+	(0x241c + (function * 0xc0) + (eqIdx * 0x18)))
+#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(function, eqIdx) \
+	(IS_E1H_OFFSET ? (0x6057 + (function * 0xc0) + (eqIdx * 0x18)) : \
+	(0x2427 + (function * 0xc0) + (eqIdx * 0x18)))
+#define CSTORM_ISCSI_EQ_PROD_OFFSET(function, eqIdx) \
+	(IS_E1H_OFFSET ? (0x6042 + (function * 0xc0) + (eqIdx * 0x18)) : \
+	(0x2412 + (function * 0xc0) + (eqIdx * 0x18)))
+#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(function, eqIdx) \
+	(IS_E1H_OFFSET ? (0x6056 + (function * 0xc0) + (eqIdx * 0x18)) : \
+	(0x2426 + (function * 0xc0) + (eqIdx * 0x18)))
+#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(function, eqIdx) \
+	(IS_E1H_OFFSET ? (0x6054 + (function * 0xc0) + (eqIdx * 0x18)) : \
+	(0x2424 + (function * 0xc0) + (eqIdx * 0x18)))
+#define CSTORM_ISCSI_HQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6640 + (function * 0x8)) : (0x2590 + \
+	(function * 0x8)))
+#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x2404 + \
+	(function * 0x8)))
+#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x2402 + \
+	(function * 0x8)))
+#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x2400 + \
+	(function * 0x8)))
+#define CSTORM_SB_HC_DISABLE_C_OFFSET(port, cpu_id, index) \
+	(IS_E1H_OFFSET ? (0x811a + (port * 0x280) + (cpu_id * 0x28) + \
+	(index * 0x4)) : (0x305a + (port * 0x280) + (cpu_id * 0x28) + \
+	(index * 0x4)))
+#define CSTORM_SB_HC_DISABLE_U_OFFSET(port, cpu_id, index) \
+	(IS_E1H_OFFSET ? (0xb01a + (port * 0x800) + (cpu_id * 0x80) + \
+	(index * 0x4)) : (0x401a + (port * 0x800) + (cpu_id * 0x80) + \
 	(index * 0x4)))
-#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
-	(IS_E1H_OFFSET ? (0x8018 + (port * 0x280) + (cpu_id * 0x28) + \
-	(index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
+#define CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, cpu_id, index) \
+	(IS_E1H_OFFSET ? (0x8118 + (port * 0x280) + (cpu_id * 0x28) + \
+	(index * 0x4)) : (0x3058 + (port * 0x280) + (cpu_id * 0x28) + \
 	(index * 0x4)))
-#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
-	(IS_E1H_OFFSET ? (0x8000 + (port * 0x280) + (cpu_id * 0x28)) : \
-	(0x1400 + (port * 0x280) + (cpu_id * 0x28)))
-#define CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
-	(IS_E1H_OFFSET ? (0x8008 + (port * 0x280) + (cpu_id * 0x28)) : \
-	(0x1408 + (port * 0x280) + (cpu_id * 0x28)))
+#define CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, cpu_id, index) \
+	(IS_E1H_OFFSET ? (0xb018 + (port * 0x800) + (cpu_id * 0x80) + \
+	(index * 0x4)) : (0x4018 + (port * 0x800) + (cpu_id * 0x80) + \
+	(index * 0x4)))
+#define CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, cpu_id) \
+	(IS_E1H_OFFSET ? (0x8100 + (port * 0x280) + (cpu_id * 0x28)) : \
+	(0x3040 + (port * 0x280) + (cpu_id * 0x28)))
+#define CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, cpu_id) \
+	(IS_E1H_OFFSET ? (0xb000 + (port * 0x800) + (cpu_id * 0x80)) : \
+	(0x4000 + (port * 0x800) + (cpu_id * 0x80)))
+#define CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, cpu_id) \
+	(IS_E1H_OFFSET ? (0x8108 + (port * 0x280) + (cpu_id * 0x28)) : \
+	(0x3048 + (port * 0x280) + (cpu_id * 0x28)))
+#define CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, cpu_id) \
+	(IS_E1H_OFFSET ? (0xb008 + (port * 0x800) + (cpu_id * 0x80)) : \
+	(0x4008 + (port * 0x800) + (cpu_id * 0x80)))
+#define CSTORM_SB_STATUS_BLOCK_C_SIZE 0x10
+#define CSTORM_SB_STATUS_BLOCK_U_SIZE 0x60
 #define CSTORM_STATS_FLAGS_OFFSET(function) \
 	(IS_E1H_OFFSET ? (0x1108 + (function * 0x8)) : (0x5108 + \
 	(function * 0x8)))
 #define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x31c0 + (function * 0x20)) : 0xffffffff)
+	(IS_E1H_OFFSET ? (0x3200 + (function * 0x20)) : 0xffffffff)
 #define TSTORM_ASSERT_LIST_INDEX_OFFSET \
 	(IS_E1H_OFFSET ? 0xa000 : 0x1000)
 #define TSTORM_ASSERT_LIST_OFFSET(idx) \
 	(IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
 #define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \
-	(IS_E1H_OFFSET ? (0x3350 + (port * 0x190) + (client_id * 0x10)) \
-	: (0x9c0 + (port * 0x130) + (client_id * 0x10)))
+	(IS_E1H_OFFSET ? (0x33a0 + (port * 0x1a0) + (client_id * 0x10)) \
+	: (0x9c0 + (port * 0x120) + (client_id * 0x10)))
 #define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \
-	(IS_E1H_OFFSET ? 0x1ad8 : 0xffffffff)
+	(IS_E1H_OFFSET ? 0x1ed8 : 0xffffffff)
+#define TSTORM_COMMON_SAFC_WORKAROUND_TIMEOUT_10USEC_OFFSET \
+	(IS_E1H_OFFSET ? 0x1eda : 0xffffffff)
 #define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
 	(IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \
 	((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -65,95 +134,133 @@
 	(IS_E1H_OFFSET ? (0xb008 + ((function>>1) * 0x28) + \
 	((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
 #define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2b80 + (function * 0x8)) : (0x4b68 + \
+	(IS_E1H_OFFSET ? (0x2940 + (function * 0x8)) : (0x4928 + \
 	(function * 0x8)))
 #define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x3000 + (function * 0x38)) : (0x1500 + \
-	(function * 0x38)))
+	(IS_E1H_OFFSET ? (0x3000 + (function * 0x40)) : (0x1500 + \
+	(function * 0x40)))
 #define TSTORM_FUNCTION_MODE_OFFSET \
-	(IS_E1H_OFFSET ? 0x1ad0 : 0xffffffff)
+	(IS_E1H_OFFSET ? 0x1ed0 : 0xffffffff)
 #define TSTORM_HC_BTR_OFFSET(port) \
 	(IS_E1H_OFFSET ? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
 #define TSTORM_INDIRECTION_TABLE_OFFSET(function) \
 	(IS_E1H_OFFSET ? (0x12c8 + (function * 0x80)) : (0x22c8 + \
 	(function * 0x80)))
 #define TSTORM_INDIRECTION_TABLE_SIZE 0x80
+#define TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(function, pblEntry) \
+	(IS_E1H_OFFSET ? (0x60c0 + (function * 0x40) + (pblEntry * 0x8)) \
+	: (0x4c30 + (function * 0x40) + (pblEntry * 0x8)))
+#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6340 + (function * 0x8)) : (0x4cd0 + \
+	(function * 0x8)))
+#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x4c04 + \
+	(function * 0x8)))
+#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x4c02 + \
+	(function * 0x8)))
+#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x4c00 + \
+	(function * 0x8)))
+#define TSTORM_ISCSI_RQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6080 + (function * 0x8)) : (0x4c20 + \
+	(function * 0x8)))
+#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6040 + (function * 0x8)) : (0x4c10 + \
+	(function * 0x8)))
+#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6042 + (function * 0x8)) : (0x4c12 + \
+	(function * 0x8)))
+#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x6044 + (function * 0x8)) : (0x4c14 + \
+	(function * 0x8)))
 #define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x3008 + (function * 0x38)) : (0x1508 + \
-	(function * 0x38)))
+	(IS_E1H_OFFSET ? (0x3008 + (function * 0x40)) : (0x1508 + \
+	(function * 0x40)))
 #define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
-	(IS_E1H_OFFSET ? (0x2010 + (port * 0x5b0) + (stats_counter_id * \
-	0x50)) : (0x4080 + (port * 0x5b0) + (stats_counter_id * 0x50)))
+	(IS_E1H_OFFSET ? (0x2010 + (port * 0x490) + (stats_counter_id * \
+	0x40)) : (0x4010 + (port * 0x490) + (stats_counter_id * 0x40)))
 #define TSTORM_STATS_FLAGS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2c00 + (function * 0x8)) : (0x4b88 + \
+	(IS_E1H_OFFSET ? (0x29c0 + (function * 0x8)) : (0x4948 + \
 	(function * 0x8)))
-#define TSTORM_TPA_EXIST_OFFSET (IS_E1H_OFFSET ? 0x3680 : 0x1c20)
-#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa040 : 0x2c10)
-#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2440 : 0x1200)
+#define TSTORM_TCP_MAX_CWND_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x4004 + (function * 0x8)) : (0x1fb4 + \
+	(function * 0x8)))
+#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa000 : 0x3000)
+#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2000 : 0x1000)
 #define USTORM_ASSERT_LIST_INDEX_OFFSET \
-	(IS_E1H_OFFSET ? 0x8960 : 0x1000)
+	(IS_E1H_OFFSET ? 0x8000 : 0x1000)
 #define USTORM_ASSERT_LIST_OFFSET(idx) \
-	(IS_E1H_OFFSET ? (0x8980 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
+	(IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
 #define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \
-	(IS_E1H_OFFSET ? (0x8018 + (port * 0x4b0) + (clientId * 0x30)) : \
-	(0x5330 + (port * 0x260) + (clientId * 0x20)))
-#define USTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
-	(IS_E1H_OFFSET ? (0x9522 + ((function>>1) * 0x40) + \
-	((function&1) * 0x100) + (index * 0x4)) : (0x1922 + (function * \
-	0x40) + (index * 0x4)))
-#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x9500 + ((function>>1) * 0x40) + \
-	((function&1) * 0x100)) : (0x1900 + (function * 0x40)))
-#define USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x9508 + ((function>>1) * 0x40) + \
-	((function&1) * 0x100)) : (0x1908 + (function * 0x40)))
+	(IS_E1H_OFFSET ? (0x1010 + (port * 0x680) + (clientId * 0x40)) : \
+	(0x4010 + (port * 0x360) + (clientId * 0x30)))
+#define USTORM_CQE_PAGE_NEXT_OFFSET(port, clientId) \
+	(IS_E1H_OFFSET ? (0x1028 + (port * 0x680) + (clientId * 0x40)) : \
+	(0x4028 + (port * 0x360) + (clientId * 0x30)))
+#define USTORM_ETH_PAUSE_ENABLED_OFFSET(port) \
+	(IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff)
 #define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \
-	(IS_E1H_OFFSET ? (0x8020 + (port * 0x4b0) + (clientId * 0x30)) : \
+	(IS_E1H_OFFSET ? (0x1030 + (port * 0x680) + (clientId * 0x40)) : \
 	0xffffffff)
 #define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1d98 + \
+	(IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1dd0 + \
 	(function * 0x8)))
 #define USTORM_FUNCTION_MODE_OFFSET \
 	(IS_E1H_OFFSET ? 0x2448 : 0xffffffff)
-#define USTORM_HC_BTR_OFFSET(port) \
-	(IS_E1H_OFFSET ? (0x9704 + (port * 0xf0)) : (0x1984 + (port * 0xc0)))
+#define USTORM_ISCSI_CQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7044 + (function * 0x8)) : (0x2414 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7046 + (function * 0x8)) : (0x2416 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7688 + (function * 0x8)) : (0x29c8 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7648 + (function * 0x8)) : (0x29b8 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7004 + (function * 0x8)) : (0x2404 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7002 + (function * 0x8)) : (0x2402 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7000 + (function * 0x8)) : (0x2400 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7040 + (function * 0x8)) : (0x2410 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7080 + (function * 0x8)) : (0x2420 + \
+	(function * 0x8)))
+#define USTORM_ISCSI_RQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x7084 + (function * 0x8)) : (0x2424 + \
+	(function * 0x8)))
 #define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \
-	(IS_E1H_OFFSET ? (0x8010 + (port * 0x4b0) + (clientId * 0x30)) : \
-	(0x5328 + (port * 0x260) + (clientId * 0x20)))
+	(IS_E1H_OFFSET ? (0x1018 + (port * 0x680) + (clientId * 0x40)) : \
+	(0x4018 + (port * 0x360) + (clientId * 0x30)))
 #define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x5308 + \
+	(IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x1da8 + \
 	(function * 0x8)))
-#define USTORM_PAUSE_ENABLED_OFFSET(port) \
-	(IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff)
 #define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
 	(IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \
-	0x28)) : (0x4740 + (port * 0x2d0) + (stats_counter_id * 0x28)))
+	0x28)) : (0x1500 + (port * 0x2d0) + (stats_counter_id * 0x28)))
 #define USTORM_RX_PRODS_OFFSET(port, client_id) \
-	(IS_E1H_OFFSET ? (0x8000 + (port * 0x4b0) + (client_id * 0x30)) \
-	: (0x5318 + (port * 0x260) + (client_id * 0x20)))
-#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index) \
-	(IS_E1H_OFFSET ? (0x901a + (port * 0x280) + (cpu_id * 0x28) + \
-	(index * 0x4)) : (0x141a + (port * 0x280) + (cpu_id * 0x28) + \
-	(index * 0x4)))
-#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index) \
-	(IS_E1H_OFFSET ? (0x9018 + (port * 0x280) + (cpu_id * 0x28) + \
-	(index * 0x4)) : (0x1418 + (port * 0x280) + (cpu_id * 0x28) + \
-	(index * 0x4)))
-#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id) \
-	(IS_E1H_OFFSET ? (0x9000 + (port * 0x280) + (cpu_id * 0x28)) : \
-	(0x1400 + (port * 0x280) + (cpu_id * 0x28)))
-#define USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, cpu_id) \
-	(IS_E1H_OFFSET ? (0x9008 + (port * 0x280) + (cpu_id * 0x28)) : \
-	(0x1408 + (port * 0x280) + (cpu_id * 0x28)))
+	(IS_E1H_OFFSET ? (0x1000 + (port * 0x680) + (client_id * 0x40)) \
+	: (0x4000 + (port * 0x360) + (client_id * 0x30)))
 #define USTORM_STATS_FLAGS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1d80 + \
+	(IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1db8 + \
 	(function * 0x8)))
+#define USTORM_TPA_BTR_OFFSET (IS_E1H_OFFSET ? 0x3da5 : 0x5095)
+#define USTORM_TPA_BTR_SIZE 0x1
 #define XSTORM_ASSERT_LIST_INDEX_OFFSET \
 	(IS_E1H_OFFSET ? 0x9000 : 0x1000)
 #define XSTORM_ASSERT_LIST_OFFSET(idx) \
 	(IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10)))
 #define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \
-	(IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3ba0 + (port * 0x50)))
+	(IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3a80 + (port * 0x50)))
 #define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \
 	(IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \
 	((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \
@@ -165,22 +272,73 @@
 	(IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \
 	((function&1) * 0xa0)) : (0x1408 + (function * 0x28)))
 #define XSTORM_E1HOV_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2c10 + (function * 0x2)) : 0xffffffff)
+	(IS_E1H_OFFSET ? (0x2c10 + (function * 0x8)) : 0xffffffff)
 #define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3b70 + \
+	(IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3a50 + \
 	(function * 0x8)))
 #define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3c80 + \
+	(IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3b60 + \
 	(function * 0x90)))
 #define XSTORM_FUNCTION_MODE_OFFSET \
-	(IS_E1H_OFFSET ? 0x2c20 : 0xffffffff)
+	(IS_E1H_OFFSET ? 0x2c50 : 0xffffffff)
 #define XSTORM_HC_BTR_OFFSET(port) \
 	(IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18)))
+#define XSTORM_ISCSI_HQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x80c0 + (function * 0x8)) : (0x1c30 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8080 + (function * 0x8)) : (0x1c20 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8081 + (function * 0x8)) : (0x1c21 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8082 + (function * 0x8)) : (0x1c22 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8083 + (function * 0x8)) : (0x1c23 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8084 + (function * 0x8)) : (0x1c24 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8085 + (function * 0x8)) : (0x1c25 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8086 + (function * 0x8)) : (0x1c26 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8004 + (function * 0x8)) : (0x1c04 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8002 + (function * 0x8)) : (0x1c02 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8000 + (function * 0x8)) : (0x1c00 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x80c4 + (function * 0x8)) : (0x1c34 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_SQ_SIZE_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x80c2 + (function * 0x8)) : (0x1c32 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8043 + (function * 0x8)) : (0x1c13 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8042 + (function * 0x8)) : (0x1c12 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8041 + (function * 0x8)) : (0x1c11 + \
+	(function * 0x8)))
+#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x8040 + (function * 0x8)) : (0x1c10 + \
+	(function * 0x8)))
 #define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \
-	(IS_E1H_OFFSET ? (0xc000 + (port * 0x3f0) + (stats_counter_id * \
-	0x38)) : (0x3378 + (port * 0x3f0) + (stats_counter_id * 0x38)))
+	(IS_E1H_OFFSET ? (0xc000 + (port * 0x360) + (stats_counter_id * \
+	0x30)) : (0x3378 + (port * 0x360) + (stats_counter_id * 0x30)))
 #define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3c40 + \
+	(IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3b20 + \
 	(function * 0x90)))
 #define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \
 	(IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \
@@ -189,8 +347,15 @@
 	(IS_E1H_OFFSET ? (0x2008 + (function * 0x10)) : (0x3330 + \
 	(function * 0x10)))
 #define XSTORM_STATS_FLAGS_OFFSET(function) \
-	(IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3b60 + \
+	(IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3a40 + \
 	(function * 0x8)))
+#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port) \
+	(IS_E1H_OFFSET ? (0x4000 + (port * 0x8)) : (0x1960 + (port * 0x8)))
+#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port) \
+	(IS_E1H_OFFSET ? (0x4001 + (port * 0x8)) : (0x1961 + (port * 0x8)))
+#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(function) \
+	(IS_E1H_OFFSET ? (0x4060 + ((function>>1) * 0x8) + ((function&1) \
+	* 0x4)) : (0x1978 + (function * 0x4)))
 #define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
 
 /**
@@ -211,6 +376,9 @@
 #define TCP_IPV4_HASH_TYPE 2
 #define IPV6_HASH_TYPE 3
 #define TCP_IPV6_HASH_TYPE 4
+#define VLAN_PRI_HASH_TYPE 5
+#define E1HOV_PRI_HASH_TYPE 6
+#define DSCP_HASH_TYPE 7
 
 
 /* Ethernet Ring parameters */
@@ -218,30 +386,26 @@
 #define FIRST_BD_IN_PKT 0
 #define PARSE_BD_INDEX 1
 #define NUM_OF_ETH_BDS_IN_PAGE ((PAGE_SIZE)/(STRUCT_SIZE(eth_tx_bd)/8))
-
+#define U_ETH_NUM_OF_SGES_TO_FETCH 8
+#define U_ETH_MAX_SGES_FOR_PACKET 3
 
 /* Rx ring params */
-#define U_ETH_LOCAL_BD_RING_SIZE 16
-#define U_ETH_LOCAL_SGE_RING_SIZE 12
+#define U_ETH_LOCAL_BD_RING_SIZE 8
+#define U_ETH_LOCAL_SGE_RING_SIZE 10
 #define U_ETH_SGL_SIZE 8
 
 
-#define U_ETH_BDS_PER_PAGE_MASK \
-	((PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))-1)
-#define U_ETH_CQE_PER_PAGE_MASK \
-	((PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe)/8))-1)
-#define U_ETH_SGES_PER_PAGE_MASK \
-	((PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8))-1)
-
 #define U_ETH_SGES_PER_PAGE_INVERSE_MASK \
 	(0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1))
 
-
-#define TU_ETH_CQES_PER_PAGE \
-	(PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe_next_page)/8))
+#define TU_ETH_CQES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_cqe)/8))
 #define U_ETH_BDS_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_bd)/8))
 #define U_ETH_SGES_PER_PAGE (PAGE_SIZE/(STRUCT_SIZE(eth_rx_sge)/8))
 
+#define U_ETH_BDS_PER_PAGE_MASK (U_ETH_BDS_PER_PAGE-1)
+#define U_ETH_CQE_PER_PAGE_MASK (TU_ETH_CQES_PER_PAGE-1)
+#define U_ETH_SGES_PER_PAGE_MASK (U_ETH_SGES_PER_PAGE-1)
+
 #define U_ETH_UNDEFINED_Q 0xFF
 
 /* values of command IDs in the ramrod message */
@@ -266,8 +430,8 @@
 #define T_ETH_CRC32_HASH_SEED 0x00000000
 
 /* Maximal L2 clients supported */
-#define ETH_MAX_RX_CLIENTS_E1 19
-#define ETH_MAX_RX_CLIENTS_E1H 25
+#define ETH_MAX_RX_CLIENTS_E1 18
+#define ETH_MAX_RX_CLIENTS_E1H 26
 
 /* Maximal aggregation queues supported */
 #define ETH_MAX_AGGREGATION_QUEUES_E1 32
@@ -276,6 +440,9 @@
 /* ETH RSS modes */
 #define ETH_RSS_MODE_DISABLED 0
 #define ETH_RSS_MODE_REGULAR 1
+#define ETH_RSS_MODE_VLAN_PRI 2
+#define ETH_RSS_MODE_E1HOV_PRI 3
+#define ETH_RSS_MODE_IP_DSCP 4
 
 
 /**
@@ -332,12 +499,14 @@
 #define HC_INDEX_DEF_C_ETH_SLOW_PATH 3
 #define HC_INDEX_DEF_C_ETH_RDMA_CQ_CONS 4
 #define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5
+#define HC_INDEX_DEF_C_ETH_FCOE_CQ_CONS 6
 
 #define HC_INDEX_DEF_U_ETH_RDMA_RX_CQ_CONS 0
 #define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1
 #define HC_INDEX_DEF_U_ETH_RDMA_RX_BD_CONS 2
 #define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3
-
+#define HC_INDEX_DEF_U_ETH_FCOE_RX_CQ_CONS 4
+#define HC_INDEX_DEF_U_ETH_FCOE_RX_BD_CONS 5
 
 /* used by the driver to get the SB offset */
 #define USTORM_ID 0
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index 03c6242..8e2261f 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -91,6 +91,21 @@ struct shared_hw_cfg {					 /* NVRAM Offset */
 
 #define SHARED_HW_CFG_HIDE_PORT1		    0x00002000
 
+	/*  The fan failure mechanism is usually related to the PHY type
+	  since the power consumption of the board is determined by the PHY.
+	  Currently, fan is required for most designs with SFX7101, BCM8727
+	  and BCM8481. If a fan is not required for a board which uses one
+	  of those PHYs, this field should be set to "Disabled". If a fan is
+	  required for a different PHY type, this option should be set to
+	  "Enabled".
+	  The fan failure indication is expected on
+	  SPIO5 */
+#define SHARED_HW_CFG_FAN_FAILURE_MASK			      0x00180000
+#define SHARED_HW_CFG_FAN_FAILURE_SHIFT 		      19
+#define SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE		      0x00000000
+#define SHARED_HW_CFG_FAN_FAILURE_DISABLED		      0x00080000
+#define SHARED_HW_CFG_FAN_FAILURE_ENABLED		      0x00100000
+
 	u32 power_dissipated;					/* 0x11c */
 #define SHARED_HW_CFG_POWER_DIS_CMN_MASK	    0xff000000
 #define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT	    24
@@ -233,6 +248,8 @@ struct port_hw_cfg {			    /* port 0: 0x12c  port 1: 0x2bc */
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726	    0x00000600
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481	    0x00000700
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101	    0x00000800
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727	    0x00000900
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC   0x00000a00
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE	    0x0000fd00
 #define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN	    0x0000ff00
 
@@ -343,10 +360,16 @@ struct port_feat_cfg {			    /* port 0: 0x454  port 1: 0x4c8 */
 #define PORT_FEATURE_MBA_ENABLED		    0x02000000
 #define PORT_FEATURE_MFW_ENABLED		    0x04000000
 
-	/*  Check the optic vendor via i2c before allowing it to be used by
-	  SW */
-#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLED 	      0x00000000
-#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED		      0x08000000
+	/* Reserved bits: 28-29 */
+	/*  Check the optic vendor via i2c against a list of approved modules
+	  in a separate nvram image */
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK		      0xE0000000
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_SHIFT		      29
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT	      0x00000000
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER       0x20000000
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG	      0x40000000
+#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN	      0x60000000
+
 
 	u32 wol_config;
 	/* Default is used when driver sets to "auto" mode */
@@ -635,6 +658,8 @@ struct drv_func_mb {
 #define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 		0x20010000
 #define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 		0x20020000
 #define DRV_MSG_CODE_UNLOAD_DONE			0x21000000
+#define DRV_MSG_CODE_DCC_OK				0x30000000
+#define DRV_MSG_CODE_DCC_FAILURE			0x31000000
 #define DRV_MSG_CODE_DIAG_ENTER_REQ			0x50000000
 #define DRV_MSG_CODE_DIAG_EXIT_REQ			0x60000000
 #define DRV_MSG_CODE_VALIDATE_KEY			0x70000000
@@ -642,6 +667,12 @@ struct drv_func_mb {
 #define DRV_MSG_CODE_GET_UPGRADE_KEY			0x81000000
 #define DRV_MSG_CODE_GET_MANUF_KEY			0x82000000
 #define DRV_MSG_CODE_LOAD_L2B_PRAM			0x90000000
+	/*
+	 * The optic module verification commands requris bootcode
+	 * v5.0.6 or later
+	 */
+#define DRV_MSG_CODE_VRFY_OPT_MDL			0xa0000000
+#define REQ_BC_VER_4_VRFY_OPT_MDL			0x00050006
 
 #define BIOS_MSG_CODE_LIC_CHALLENGE			0xff010000
 #define BIOS_MSG_CODE_LIC_RESPONSE			0xff020000
@@ -663,6 +694,7 @@ struct drv_func_mb {
 #define FW_MSG_CODE_DRV_UNLOAD_PORT			0x20110000
 #define FW_MSG_CODE_DRV_UNLOAD_FUNCTION 		0x20120000
 #define FW_MSG_CODE_DRV_UNLOAD_DONE			0x21100000
+#define FW_MSG_CODE_DCC_DONE				0x30100000
 #define FW_MSG_CODE_DIAG_ENTER_DONE			0x50100000
 #define FW_MSG_CODE_DIAG_REFUSE 			0x50200000
 #define FW_MSG_CODE_DIAG_EXIT_DONE			0x60100000
@@ -676,6 +708,9 @@ struct drv_func_mb {
 #define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE		0x90220000
 #define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE		0x90230000
 #define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE		0x90240000
+#define FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS		0xa0100000
+#define FW_MSG_CODE_VRFY_OPT_MDL_INVLD_IMG		0xa0200000
+#define FW_MSG_CODE_VRFY_OPT_MDL_UNAPPROVED		0xa0300000
 
 #define FW_MSG_CODE_LIC_CHALLENGE			0xff010000
 #define FW_MSG_CODE_LIC_RESPONSE			0xff020000
@@ -710,6 +745,14 @@ struct drv_func_mb {
 	u32 drv_status;
 #define DRV_STATUS_PMF					0x00000001
 
+#define DRV_STATUS_DCC_EVENT_MASK			0x0000ff00
+#define DRV_STATUS_DCC_DISABLE_ENABLE_PF		0x00000100
+#define DRV_STATUS_DCC_BANDWIDTH_ALLOCATION		0x00000200
+#define DRV_STATUS_DCC_CHANGE_MAC_ADDRESS		0x00000400
+#define DRV_STATUS_DCC_RESERVED1			0x00000800
+#define DRV_STATUS_DCC_SET_PROTOCOL			0x00001000
+#define DRV_STATUS_DCC_SET_PRIORITY			0x00002000
+
 	u32 virt_mac_upper;
 #define VIRT_MAC_SIGN_MASK				0xffff0000
 #define VIRT_MAC_SIGNATURE				0x564d0000
@@ -746,10 +789,9 @@ struct shared_mf_cfg {
 struct port_mf_cfg {
 
 	u32 dynamic_cfg;	/* device control channel */
-#define PORT_MF_CFG_OUTER_VLAN_TAG_MASK 	    0x0000ffff
-#define PORT_MF_CFG_OUTER_VLAN_TAG_SHIFT	    0
-#define PORT_MF_CFG_DYNAMIC_CFG_ENABLED 	    0x00010000
-#define PORT_MF_CFG_DYNAMIC_CFG_DEFAULT 	    0x00000000
+#define PORT_MF_CFG_E1HOV_TAG_MASK		    0x0000ffff
+#define PORT_MF_CFG_E1HOV_TAG_SHIFT		    0
+#define PORT_MF_CFG_E1HOV_TAG_DEFAULT		    PORT_MF_CFG_E1HOV_TAG_MASK
 
 	u32 reserved[3];
 
@@ -853,6 +895,22 @@ struct shmem_region {			       /*   SharedMem Offset (size) */
 };						       /* 0x6dc */
 
 
+struct shmem2_region {
+
+	u32			size;
+
+	u32			dcc_support;
+#define SHMEM_DCC_SUPPORT_NONE			    0x00000000
+#define SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV     0x00000001
+#define SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV  0x00000004
+#define SHMEM_DCC_SUPPORT_CHANGE_MAC_ADDRESS_TLV    0x00000008
+#define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV	    0x00000040
+#define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV	    0x00000080
+#define SHMEM_DCC_SUPPORT_DEFAULT		    SHMEM_DCC_SUPPORT_NONE
+
+};
+
+
 struct emac_stats {
     u32     rx_stat_ifhcinoctets;
     u32     rx_stat_ifhcinbadoctets;
@@ -1186,9 +1244,9 @@ struct host_func_stats {
 };
 
 
-#define BCM_5710_FW_MAJOR_VERSION			4
-#define BCM_5710_FW_MINOR_VERSION			8
-#define BCM_5710_FW_REVISION_VERSION			53
+#define BCM_5710_FW_MAJOR_VERSION			5
+#define BCM_5710_FW_MINOR_VERSION			0
+#define BCM_5710_FW_REVISION_VERSION			21
 #define BCM_5710_FW_ENGINEERING_VERSION 		0
 #define BCM_5710_FW_COMPILE_FLAGS			1
 
@@ -1238,6 +1296,22 @@ struct doorbell {
 
 
 /*
+ * doorbell message sent to the chip
+ */
+struct doorbell_set_prod {
+#if defined(__BIG_ENDIAN)
+	u16 prod;
+	u8 zero_fill1;
+	struct doorbell_hdr header;
+#elif defined(__LITTLE_ENDIAN)
+	struct doorbell_hdr header;
+	u8 zero_fill1;
+	u16 prod;
+#endif
+};
+
+
+/*
  * IGU driver acknowledgement register
  */
 struct igu_ack_register {
@@ -1272,6 +1346,62 @@ struct igu_ack_register {
 
 
 /*
+ * IGU driver acknowledgement register
+ */
+struct igu_backward_compatible {
+	u32 sb_id_and_flags;
+#define IGU_BACKWARD_COMPATIBLE_SB_INDEX (0xFFFF<<0)
+#define IGU_BACKWARD_COMPATIBLE_SB_INDEX_SHIFT 0
+#define IGU_BACKWARD_COMPATIBLE_SB_SELECT (0x1F<<16)
+#define IGU_BACKWARD_COMPATIBLE_SB_SELECT_SHIFT 16
+#define IGU_BACKWARD_COMPATIBLE_SEGMENT_ACCESS (0x7<<21)
+#define IGU_BACKWARD_COMPATIBLE_SEGMENT_ACCESS_SHIFT 21
+#define IGU_BACKWARD_COMPATIBLE_BUPDATE (0x1<<24)
+#define IGU_BACKWARD_COMPATIBLE_BUPDATE_SHIFT 24
+#define IGU_BACKWARD_COMPATIBLE_ENABLE_INT (0x3<<25)
+#define IGU_BACKWARD_COMPATIBLE_ENABLE_INT_SHIFT 25
+#define IGU_BACKWARD_COMPATIBLE_RESERVED_0 (0x1F<<27)
+#define IGU_BACKWARD_COMPATIBLE_RESERVED_0_SHIFT 27
+	u32 reserved_2;
+};
+
+
+/*
+ * IGU driver acknowledgement register
+ */
+struct igu_regular {
+	u32 sb_id_and_flags;
+#define IGU_REGULAR_SB_INDEX (0xFFFFF<<0)
+#define IGU_REGULAR_SB_INDEX_SHIFT 0
+#define IGU_REGULAR_RESERVED0 (0x1<<20)
+#define IGU_REGULAR_RESERVED0_SHIFT 20
+#define IGU_REGULAR_SEGMENT_ACCESS (0x7<<21)
+#define IGU_REGULAR_SEGMENT_ACCESS_SHIFT 21
+#define IGU_REGULAR_BUPDATE (0x1<<24)
+#define IGU_REGULAR_BUPDATE_SHIFT 24
+#define IGU_REGULAR_ENABLE_INT (0x3<<25)
+#define IGU_REGULAR_ENABLE_INT_SHIFT 25
+#define IGU_REGULAR_RESERVED_1 (0x1<<27)
+#define IGU_REGULAR_RESERVED_1_SHIFT 27
+#define IGU_REGULAR_CLEANUP_TYPE (0x3<<28)
+#define IGU_REGULAR_CLEANUP_TYPE_SHIFT 28
+#define IGU_REGULAR_CLEANUP_SET (0x1<<30)
+#define IGU_REGULAR_CLEANUP_SET_SHIFT 30
+#define IGU_REGULAR_BCLEANUP (0x1<<31)
+#define IGU_REGULAR_BCLEANUP_SHIFT 31
+	u32 reserved_2;
+};
+
+/*
+ * IGU driver acknowledgement register
+ */
+union igu_consprod_reg {
+	struct igu_regular regular;
+	struct igu_backward_compatible backward_compatible;
+};
+
+
+/*
  * Parser parsing flags field
  */
 struct parsing_flags {
@@ -1402,12 +1532,10 @@ struct ustorm_eth_st_context_config {
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
 	u8 status_block_id;
 	u8 clientId;
 	u8 sb_index_numbers;
@@ -1430,12 +1558,10 @@ struct ustorm_eth_st_context_config {
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2)
 #define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING (0x1<<3)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<4)
-#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 4
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0x7<<5)
-#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 5
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3)
+#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4)
+#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4
 #endif
 #if defined(__BIG_ENDIAN)
 	u16 bd_buff_size;
@@ -1455,11 +1581,36 @@ struct ustorm_eth_st_context_config {
 	u8 __local_bd_prod;
 	u8 __local_sge_prod;
 #endif
-	u32 reserved;
+#if defined(__BIG_ENDIAN)
+	u16 __sdm_bd_expected_counter;
+	u8 cstorm_agg_int;
+	u8 __expected_bds_on_ram;
+#elif defined(__LITTLE_ENDIAN)
+	u8 __expected_bds_on_ram;
+	u8 cstorm_agg_int;
+	u16 __sdm_bd_expected_counter;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __ring_data_ram_addr;
+	u16 __hc_cstorm_ram_addr;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __hc_cstorm_ram_addr;
+	u16 __ring_data_ram_addr;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 reserved1;
+	u8 max_sges_for_packet;
+	u16 __bd_ring_ram_addr;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __bd_ring_ram_addr;
+	u8 max_sges_for_packet;
+	u8 reserved1;
+#endif
 	u32 bd_page_base_lo;
 	u32 bd_page_base_hi;
 	u32 sge_page_base_lo;
 	u32 sge_page_base_hi;
+	struct regpair reserved2;
 };
 
 /*
@@ -1482,8 +1633,8 @@ struct eth_rx_sge {
  * Local BDs and SGEs rings (in ETH)
  */
 struct eth_local_rx_rings {
-	struct eth_rx_bd __local_bd_ring[16];
-	struct eth_rx_sge __local_sge_ring[12];
+	struct eth_rx_bd __local_bd_ring[8];
+	struct eth_rx_sge __local_sge_ring[10];
 };
 
 /*
@@ -1575,13 +1726,13 @@ struct xstorm_eth_extra_ag_context_section {
  */
 struct xstorm_eth_ag_context {
 #if defined(__BIG_ENDIAN)
-	u16 __bd_prod;
+	u16 agg_val1;
 	u8 __agg_vars1;
 	u8 __state;
 #elif defined(__LITTLE_ENDIAN)
 	u8 __state;
 	u8 __agg_vars1;
-	u16 __bd_prod;
+	u16 agg_val1;
 #endif
 #if defined(__BIG_ENDIAN)
 	u8 cdu_reserved;
@@ -1594,7 +1745,7 @@ struct xstorm_eth_ag_context {
 	u8 __agg_vars4;
 	u8 cdu_reserved;
 #endif
-	u32 __more_packets_to_send;
+	u32 __bd_prod;
 #if defined(__BIG_ENDIAN)
 	u16 __agg_vars5;
 	u16 __agg_val4_th;
@@ -1860,8 +2011,8 @@ struct eth_tx_bd_flags {
 #define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT 0
 #define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<1)
 #define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 1
-#define ETH_TX_BD_FLAGS_TCP_CSUM (0x1<<2)
-#define ETH_TX_BD_FLAGS_TCP_CSUM_SHIFT 2
+#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<2)
+#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 2
 #define ETH_TX_BD_FLAGS_END_BD (0x1<<3)
 #define ETH_TX_BD_FLAGS_END_BD_SHIFT 3
 #define ETH_TX_BD_FLAGS_START_BD (0x1<<4)
@@ -1877,7 +2028,7 @@ struct eth_tx_bd_flags {
 /*
  * The eth Tx Buffer Descriptor
  */
-struct eth_tx_bd {
+struct eth_tx_start_bd {
 	__le32 addr_lo;
 	__le32 addr_hi;
 	__le16 nbd;
@@ -1885,10 +2036,21 @@ struct eth_tx_bd {
 	__le16 vlan;
 	struct eth_tx_bd_flags bd_flags;
 	u8 general_data;
-#define ETH_TX_BD_HDR_NBDS (0x3F<<0)
-#define ETH_TX_BD_HDR_NBDS_SHIFT 0
-#define ETH_TX_BD_ETH_ADDR_TYPE (0x3<<6)
-#define ETH_TX_BD_ETH_ADDR_TYPE_SHIFT 6
+#define ETH_TX_START_BD_HDR_NBDS (0x3F<<0)
+#define ETH_TX_START_BD_HDR_NBDS_SHIFT 0
+#define ETH_TX_START_BD_ETH_ADDR_TYPE (0x3<<6)
+#define ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT 6
+};
+
+/*
+ * Tx regular BD structure
+ */
+struct eth_tx_bd {
+	u32 addr_lo;
+	u32 addr_hi;
+	u16 total_pkt_bytes;
+	u16 nbytes;
+	u8 reserved[4];
 };
 
 /*
@@ -1898,8 +2060,8 @@ struct eth_tx_parse_bd {
 	u8 global_data;
 #define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET (0xF<<0)
 #define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET_SHIFT 0
-#define ETH_TX_PARSE_BD_CS_ANY_FLG (0x1<<4)
-#define ETH_TX_PARSE_BD_CS_ANY_FLG_SHIFT 4
+#define ETH_TX_PARSE_BD_UDP_CS_FLG (0x1<<4)
+#define ETH_TX_PARSE_BD_UDP_CS_FLG_SHIFT 4
 #define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN (0x1<<5)
 #define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN_SHIFT 5
 #define ETH_TX_PARSE_BD_LLC_SNAP_EN (0x1<<6)
@@ -1924,10 +2086,10 @@ struct eth_tx_parse_bd {
 #define ETH_TX_PARSE_BD_CWR_FLG (0x1<<7)
 #define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7
 	u8 ip_hlen;
-	s8 cs_offset;
+	s8 reserved;
 	__le16 total_hlen;
-	__le16 lso_mss;
 	__le16 tcp_pseudo_csum;
+	__le16 lso_mss;
 	__le16 ip_id;
 	__le32 tcp_send_seq;
 };
@@ -1936,15 +2098,16 @@ struct eth_tx_parse_bd {
  * The last BD in the BD memory will hold a pointer to the next BD memory
  */
 struct eth_tx_next_bd {
-	u32 addr_lo;
-	u32 addr_hi;
+	__le32 addr_lo;
+	__le32 addr_hi;
 	u8 reserved[8];
 };
 
 /*
- * union for 3 Bd types
+ * union for 4 Bd types
  */
 union eth_tx_bd_types {
+	struct eth_tx_start_bd start_bd;
 	struct eth_tx_bd reg_bd;
 	struct eth_tx_parse_bd parse_bd;
 	struct eth_tx_next_bd next_bd;
@@ -1973,11 +2136,35 @@ struct xstorm_eth_st_context {
 #define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7
 	u16 tx_bd_cons;
 #endif
-	u32 db_data_addr_lo;
-	u32 db_data_addr_hi;
-	u32 __pkt_cons;
-	u32 __gso_next;
-	u32 is_eth_conn_1b;
+	u32 __reserved1;
+	u32 __reserved2;
+#if defined(__BIG_ENDIAN)
+	u8 __ram_cache_index;
+	u8 __double_buffer_client;
+	u16 __pkt_cons;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __pkt_cons;
+	u8 __double_buffer_client;
+	u8 __ram_cache_index;
+#endif
+#if defined(__BIG_ENDIAN)
+	u16 __statistics_address;
+	u16 __gso_next;
+#elif defined(__LITTLE_ENDIAN)
+	u16 __gso_next;
+	u16 __statistics_address;
+#endif
+#if defined(__BIG_ENDIAN)
+	u8 __local_tx_bd_cons;
+	u8 safc_group_num;
+	u8 safc_group_en;
+	u8 __is_eth_conn;
+#elif defined(__LITTLE_ENDIAN)
+	u8 __is_eth_conn;
+	u8 safc_group_en;
+	u8 safc_group_num;
+	u8 __local_tx_bd_cons;
+#endif
 	union eth_tx_bd_types __bds[13];
 };
 
@@ -2042,9 +2229,9 @@ struct eth_tx_doorbell {
 
 
 /*
- * ustorm status block
+ * cstorm default status block, generated by ustorm
  */
-struct ustorm_def_status_block {
+struct cstorm_def_status_block_u {
 	__le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
 	__le16 status_block_index;
 	u8 func;
@@ -2053,9 +2240,9 @@ struct ustorm_def_status_block {
 };
 
 /*
- * cstorm status block
+ * cstorm default status block, generated by cstorm
  */
-struct cstorm_def_status_block {
+struct cstorm_def_status_block_c {
 	__le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
 	__le16 status_block_index;
 	u8 func;
@@ -2090,17 +2277,17 @@ struct tstorm_def_status_block {
  */
 struct host_def_status_block {
 	struct atten_def_status_block atten_status_block;
-	struct ustorm_def_status_block u_def_status_block;
-	struct cstorm_def_status_block c_def_status_block;
+	struct cstorm_def_status_block_u u_def_status_block;
+	struct cstorm_def_status_block_c c_def_status_block;
 	struct xstorm_def_status_block x_def_status_block;
 	struct tstorm_def_status_block t_def_status_block;
 };
 
 
 /*
- * ustorm status block
+ * cstorm status block, generated by ustorm
  */
-struct ustorm_status_block {
+struct cstorm_status_block_u {
 	__le16 index_values[HC_USTORM_SB_NUM_INDICES];
 	__le16 status_block_index;
 	u8 func;
@@ -2109,9 +2296,9 @@ struct ustorm_status_block {
 };
 
 /*
- * cstorm status block
+ * cstorm status block, generated by cstorm
  */
-struct cstorm_status_block {
+struct cstorm_status_block_c {
 	__le16 index_values[HC_CSTORM_SB_NUM_INDICES];
 	__le16 status_block_index;
 	u8 func;
@@ -2123,8 +2310,8 @@ struct cstorm_status_block {
  * host status block
  */
 struct host_status_block {
-	struct ustorm_status_block u_status_block;
-	struct cstorm_status_block c_status_block;
+	struct cstorm_status_block_u u_status_block;
+	struct cstorm_status_block_c c_status_block;
 };
 
 
@@ -2140,15 +2327,6 @@ struct eth_client_setup_ramrod_data {
 
 
 /*
- * L2 dynamic host coalescing init parameters
- */
-struct eth_dynamic_hc_config {
-	u32 threshold[3];
-	u8 hc_timeout[4];
-};
-
-
-/*
  * regular eth FP CQE parameters struct
  */
 struct eth_fast_path_rx_cqe {
@@ -2312,12 +2490,10 @@ struct eth_spe {
 
 
 /*
- * doorbell data in host memory
+ * array of 13 bds as appears in the eth xstorm context
  */
-struct eth_tx_db_data {
-	__le32 packets_prod;
-	__le16 bds_prod;
-	__le16 reserved;
+struct eth_tx_bds_array {
+	union eth_tx_bd_types bds[13];
 };
 
 
@@ -2345,8 +2521,10 @@ struct tstorm_eth_function_common_config {
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11
 #elif defined(__LITTLE_ENDIAN)
 	u16 config_flags;
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
@@ -2365,8 +2543,10 @@ struct tstorm_eth_function_common_config {
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9)
 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3F<<10)
-#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 10
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11
 	u8 rss_result_mask;
 	u8 leading_client_id;
 #endif
@@ -2374,11 +2554,38 @@ struct tstorm_eth_function_common_config {
 };
 
 /*
+ * RSS idirection table update configuration
+ */
+struct rss_update_config {
+#if defined(__BIG_ENDIAN)
+	u16 toe_rss_bitmap;
+	u16 flags;
+#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE (0x1<<0)
+#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE_SHIFT 0
+#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE (0x1<<1)
+#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE_SHIFT 1
+#define __RSS_UPDATE_CONFIG_RESERVED0 (0x3FFF<<2)
+#define __RSS_UPDATE_CONFIG_RESERVED0_SHIFT 2
+#elif defined(__LITTLE_ENDIAN)
+	u16 flags;
+#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE (0x1<<0)
+#define RSS_UPDATE_CONFIG_ETH_UPDATE_ENABLE_SHIFT 0
+#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE (0x1<<1)
+#define RSS_UPDATE_CONFIG_TOE_UPDATE_ENABLE_SHIFT 1
+#define __RSS_UPDATE_CONFIG_RESERVED0 (0x3FFF<<2)
+#define __RSS_UPDATE_CONFIG_RESERVED0_SHIFT 2
+	u16 toe_rss_bitmap;
+#endif
+	u32 reserved1;
+};
+
+/*
  * parameters for eth update ramrod
  */
 struct eth_update_ramrod_data {
 	struct tstorm_eth_function_common_config func_config;
 	u8 indirectionTable[128];
+	struct rss_update_config rss_config;
 };
 
 
@@ -2423,8 +2630,9 @@ struct tstorm_cam_target_table_entry {
 #define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC_SHIFT 3
 #define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0 (0xF<<4)
 #define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0_SHIFT 4
-	u8 client_id;
+	u8 reserved1;
 	u16 vlan_id;
+	u32 clients_bit_vector;
 };
 
 /*
@@ -2453,7 +2661,7 @@ struct mac_configuration_entry_e1h {
 	__le16 msb_mac_addr;
 	__le16 vlan_id;
 	__le16 e1hov_id;
-	u8 client_id;
+	u8 reserved0;
 	u8 flags;
 #define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0)
 #define MAC_CONFIGURATION_ENTRY_E1H_PORT_SHIFT 0
@@ -2461,8 +2669,9 @@ struct mac_configuration_entry_e1h {
 #define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE_SHIFT 1
 #define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC (0x1<<2)
 #define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC_SHIFT 2
-#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED0 (0x1F<<3)
-#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED0_SHIFT 3
+#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1 (0x1F<<3)
+#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1_SHIFT 3
+	u32 clients_bit_vector;
 };
 
 /*
@@ -2487,13 +2696,13 @@ struct tstorm_eth_approximate_match_multicast_filtering {
  */
 struct tstorm_eth_client_config {
 #if defined(__BIG_ENDIAN)
-	u8 max_sges_for_packet;
+	u8 reserved0;
 	u8 statistics_counter_id;
 	u16 mtu;
 #elif defined(__LITTLE_ENDIAN)
 	u16 mtu;
 	u8 statistics_counter_id;
-	u8 max_sges_for_packet;
+	u8 reserved0;
 #endif
 #if defined(__BIG_ENDIAN)
 	u16 drop_flags;
@@ -2505,8 +2714,8 @@ struct tstorm_eth_client_config {
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4
 	u16 config_flags;
 #define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
 #define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0
@@ -2514,10 +2723,8 @@ struct tstorm_eth_client_config {
 #define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
 #define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
 #define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3
 #elif defined(__LITTLE_ENDIAN)
 	u16 config_flags;
 #define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0)
@@ -2526,10 +2733,8 @@ struct tstorm_eth_client_config {
 #define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1
 #define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2)
 #define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING (0x1<<3)
-#define TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 4
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3
 	u16 drop_flags;
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
@@ -2539,8 +2744,8 @@ struct tstorm_eth_client_config {
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3)
 #define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0xFFF<<4)
-#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 4
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4
 #endif
 };
 
@@ -2663,7 +2868,6 @@ struct rate_shaping_vars_per_port {
 	u32 rs_threshold;
 };
 
-
 /*
  * per-port fairness variables
  */
@@ -2673,7 +2877,6 @@ struct fairness_vars_per_port {
 	u32 fairness_timeout;
 };
 
-
 /*
  * per-port SAFC variables
  */
@@ -2690,7 +2893,6 @@ struct safc_struct_per_port {
 	u16 cos_to_pause_mask[NUM_OF_SAFC_BITS];
 };
 
-
 /*
  * Per-port congestion management variables
  */
@@ -2703,11 +2905,23 @@ struct cmng_struct_per_port {
 
 
 /*
+ * Dynamic host coalescing init parameters
+ */
+struct dynamic_hc_config {
+	u32 threshold[3];
+	u8 shift_per_protocol[HC_USTORM_SB_NUM_INDICES];
+	u8 hc_timeout0[HC_USTORM_SB_NUM_INDICES];
+	u8 hc_timeout1[HC_USTORM_SB_NUM_INDICES];
+	u8 hc_timeout2[HC_USTORM_SB_NUM_INDICES];
+	u8 hc_timeout3[HC_USTORM_SB_NUM_INDICES];
+};
+
+
+/*
  * Protocol-common statistics collected by the Xstorm (per client)
  */
 struct xstorm_per_client_stats {
-	struct regpair total_sent_bytes;
-	__le32 total_sent_pkts;
+	__le32 reserved0;
 	__le32 unicast_pkts_sent;
 	struct regpair unicast_bytes_sent;
 	struct regpair multicast_bytes_sent;
@@ -2715,11 +2929,10 @@ struct xstorm_per_client_stats {
 	__le32 broadcast_pkts_sent;
 	struct regpair broadcast_bytes_sent;
 	__le16 stats_counter;
-	__le16 reserved0;
-	__le32 reserved1;
+	__le16 reserved1;
+	__le32 reserved2;
 };
 
-
 /*
  * Common statistics collected by the Xstorm (per port)
  */
@@ -2727,7 +2940,6 @@ struct xstorm_common_stats {
  struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID];
 };
 
-
 /*
  * Protocol-common statistics collected by the Tstorm (per port)
  */
@@ -2738,19 +2950,16 @@ struct tstorm_per_port_stats {
 	__le32 mac_discard;
 };
 
-
 /*
  * Protocol-common statistics collected by the Tstorm (per client)
  */
 struct tstorm_per_client_stats {
-	struct regpair total_rcv_bytes;
 	struct regpair rcv_unicast_bytes;
 	struct regpair rcv_broadcast_bytes;
 	struct regpair rcv_multicast_bytes;
 	struct regpair rcv_error_bytes;
 	__le32 checksum_discard;
 	__le32 packets_too_big_discard;
-	__le32 total_rcv_pkts;
 	__le32 rcv_unicast_pkts;
 	__le32 rcv_broadcast_pkts;
 	__le32 rcv_multicast_pkts;
@@ -2758,7 +2967,6 @@ struct tstorm_per_client_stats {
 	__le32 ttl0_discard;
 	__le16 stats_counter;
 	__le16 reserved0;
-	__le32 reserved1;
 };
 
 /*
@@ -2861,6 +3069,15 @@ struct pram_fw_version {
 
 
 /*
+ * The send queue element
+ */
+struct protocol_common_spe {
+	struct spe_hdr hdr;
+	struct regpair phy_address;
+};
+
+
+/*
  * a single rate shaping counter. can be used as protocol or vnic counter
  */
 struct rate_shaping_counter {
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 3ba4d88..65b26cb 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -15,24 +15,11 @@
 #ifndef BNX2X_INIT_H
 #define BNX2X_INIT_H
 
-#define COMMON				0x1
-#define PORT0				0x2
-#define PORT1				0x4
-
-#define INIT_EMULATION			0x1
-#define INIT_FPGA			0x2
-#define INIT_ASIC			0x4
-#define INIT_HARDWARE			0x7
-
-#define TSTORM_INTMEM_ADDR		TSEM_REG_FAST_MEMORY
-#define CSTORM_INTMEM_ADDR		CSEM_REG_FAST_MEMORY
-#define XSTORM_INTMEM_ADDR		XSEM_REG_FAST_MEMORY
-#define USTORM_INTMEM_ADDR		USEM_REG_FAST_MEMORY
 /* RAM0 size in bytes */
 #define STORM_INTMEM_SIZE_E1		0x5800
 #define STORM_INTMEM_SIZE_E1H		0x10000
-#define STORM_INTMEM_SIZE(bp)	((CHIP_IS_E1H(bp) ? STORM_INTMEM_SIZE_E1H : \
-						    STORM_INTMEM_SIZE_E1) / 4)
+#define STORM_INTMEM_SIZE(bp) ((CHIP_IS_E1(bp) ? STORM_INTMEM_SIZE_E1 : \
+						    STORM_INTMEM_SIZE_E1H) / 4)
 
 
 /* Init operation types and structures */
@@ -53,65 +40,68 @@
 #define OP_WR_ASIC		0xc /* write single register on ASIC */
 
 /* Init stages */
-#define COMMON_STAGE            0
-#define PORT0_STAGE     	1
-#define PORT1_STAGE     	2
-/* Never reorder FUNCx stages !!! */
-#define FUNC0_STAGE     	3
-#define FUNC1_STAGE     	4
-#define FUNC2_STAGE     	5
-#define FUNC3_STAGE     	6
-#define FUNC4_STAGE     	7
-#define FUNC5_STAGE     	8
-#define FUNC6_STAGE     	9
-#define FUNC7_STAGE     	10
-#define STAGE_IDX_MAX   	11
-
-#define STAGE_START     	0
-#define STAGE_END       	1
+/* Never reorder stages !!! */
+#define COMMON_STAGE		0
+#define PORT0_STAGE		1
+#define PORT1_STAGE		2
+#define FUNC0_STAGE		3
+#define FUNC1_STAGE		4
+#define FUNC2_STAGE		5
+#define FUNC3_STAGE		6
+#define FUNC4_STAGE		7
+#define FUNC5_STAGE		8
+#define FUNC6_STAGE		9
+#define FUNC7_STAGE		10
+#define STAGE_IDX_MAX		11
+
+#define STAGE_START		0
+#define STAGE_END		1
 
 
 /* Indices of blocks */
-#define PRS_BLOCK               0
-#define SRCH_BLOCK              1
-#define TSDM_BLOCK              2
-#define TCM_BLOCK               3
-#define BRB1_BLOCK              4
-#define TSEM_BLOCK              5
-#define PXPCS_BLOCK             6
-#define EMAC0_BLOCK             7
-#define EMAC1_BLOCK             8
-#define DBU_BLOCK               9
-#define MISC_BLOCK              10
-#define DBG_BLOCK               11
-#define NIG_BLOCK               12
-#define MCP_BLOCK               13
-#define UPB_BLOCK               14
-#define CSDM_BLOCK              15
-#define USDM_BLOCK              16
-#define CCM_BLOCK               17
-#define UCM_BLOCK               18
-#define USEM_BLOCK              19
-#define CSEM_BLOCK              20
-#define XPB_BLOCK               21
-#define DQ_BLOCK                22
-#define TIMERS_BLOCK            23
-#define XSDM_BLOCK              24
-#define QM_BLOCK                25
-#define PBF_BLOCK               26
-#define XCM_BLOCK               27
-#define XSEM_BLOCK              28
-#define CDU_BLOCK               29
-#define DMAE_BLOCK              30
-#define PXP_BLOCK               31
-#define CFC_BLOCK               32
-#define HC_BLOCK                33
-#define PXP2_BLOCK              34
-#define MISC_AEU_BLOCK          35
+#define PRS_BLOCK		0
+#define SRCH_BLOCK		1
+#define TSDM_BLOCK		2
+#define TCM_BLOCK		3
+#define BRB1_BLOCK		4
+#define TSEM_BLOCK		5
+#define PXPCS_BLOCK		6
+#define EMAC0_BLOCK		7
+#define EMAC1_BLOCK		8
+#define DBU_BLOCK		9
+#define MISC_BLOCK		10
+#define DBG_BLOCK		11
+#define NIG_BLOCK		12
+#define MCP_BLOCK		13
+#define UPB_BLOCK		14
+#define CSDM_BLOCK		15
+#define USDM_BLOCK		16
+#define CCM_BLOCK		17
+#define UCM_BLOCK		18
+#define USEM_BLOCK		19
+#define CSEM_BLOCK		20
+#define XPB_BLOCK		21
+#define DQ_BLOCK		22
+#define TIMERS_BLOCK		23
+#define XSDM_BLOCK		24
+#define QM_BLOCK		25
+#define PBF_BLOCK		26
+#define XCM_BLOCK		27
+#define XSEM_BLOCK		28
+#define CDU_BLOCK		29
+#define DMAE_BLOCK		30
+#define PXP_BLOCK		31
+#define CFC_BLOCK		32
+#define HC_BLOCK		33
+#define PXP2_BLOCK		34
+#define MISC_AEU_BLOCK		35
+#define PGLUE_B_BLOCK		36
+#define IGU_BLOCK		37
+
 
 /* Returns the index of start or end of a specific block stage in ops array*/
 #define BLOCK_OPS_IDX(block, stage, end) \
-       (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
+			(2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
 
 
 struct raw_op {
@@ -158,199 +148,5 @@ union init_op {
 	struct raw_op		raw;
 };
 
-/****************************************************************************
-* PXP
-****************************************************************************/
-/*
- * This code configures the PCI read/write arbiter
- * which implements a weighted round robin
- * between the virtual queues in the chip.
- *
- * The values were derived for each PCI max payload and max request size.
- * since max payload and max request size are only known at run time,
- * this is done as a separate init stage.
- */
-
-#define NUM_WR_Q			13
-#define NUM_RD_Q			29
-#define MAX_RD_ORD			3
-#define MAX_WR_ORD			2
-
-/* configuration for one arbiter queue */
-struct arb_line {
-	int l;
-	int add;
-	int ubound;
-};
-
-/* derived configuration for each read queue for each max request size */
-static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
-/* 1 */	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
-	{ {4, 8,  4},  {4,  8,  4},  {4,  8,  4},  {4,  8,  4}  },
-	{ {4, 3,  3},  {4,  3,  3},  {4,  3,  3},  {4,  3,  3}  },
-	{ {8, 3,  6},  {16, 3,  11}, {16, 3,  11}, {16, 3,  11} },
-	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
-/* 10 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-/* 20 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
-	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
-};
-
-/* derived configuration for each write queue for each max request size */
-static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
-/* 1 */	{ {4, 6,  3},  {4,  6,  3},  {4,  6,  3} },
-	{ {4, 2,  3},  {4,  2,  3},  {4,  2,  3} },
-	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
-	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
-	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
-	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
-	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
-	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
-	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
-/* 10 */{ {8, 9,  6},  {16, 9,  11}, {32, 9,  21} },
-	{ {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
-	{ {8, 9,  6},  {16, 9,  11}, {16, 9,  11} },
-	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
-};
-
-/* register addresses for read queues */
-static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
-/* 1 */	{PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
-		PXP2_REG_RQ_BW_RD_UBOUND0},
-	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
-		PXP2_REG_PSWRQ_BW_UB1},
-	{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
-		PXP2_REG_PSWRQ_BW_UB2},
-	{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
-		PXP2_REG_PSWRQ_BW_UB3},
-	{PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
-		PXP2_REG_RQ_BW_RD_UBOUND4},
-	{PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
-		PXP2_REG_RQ_BW_RD_UBOUND5},
-	{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
-		PXP2_REG_PSWRQ_BW_UB6},
-	{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
-		PXP2_REG_PSWRQ_BW_UB7},
-	{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
-		PXP2_REG_PSWRQ_BW_UB8},
-/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
-		PXP2_REG_PSWRQ_BW_UB9},
-	{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
-		PXP2_REG_PSWRQ_BW_UB10},
-	{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
-		PXP2_REG_PSWRQ_BW_UB11},
-	{PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
-		PXP2_REG_RQ_BW_RD_UBOUND12},
-	{PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
-		PXP2_REG_RQ_BW_RD_UBOUND13},
-	{PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
-		PXP2_REG_RQ_BW_RD_UBOUND14},
-	{PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
-		PXP2_REG_RQ_BW_RD_UBOUND15},
-	{PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
-		PXP2_REG_RQ_BW_RD_UBOUND16},
-	{PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
-		PXP2_REG_RQ_BW_RD_UBOUND17},
-	{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
-		PXP2_REG_RQ_BW_RD_UBOUND18},
-/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
-		PXP2_REG_RQ_BW_RD_UBOUND19},
-	{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
-		PXP2_REG_RQ_BW_RD_UBOUND20},
-	{PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
-		PXP2_REG_RQ_BW_RD_UBOUND22},
-	{PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
-		PXP2_REG_RQ_BW_RD_UBOUND23},
-	{PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
-		PXP2_REG_RQ_BW_RD_UBOUND24},
-	{PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
-		PXP2_REG_RQ_BW_RD_UBOUND25},
-	{PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
-		PXP2_REG_RQ_BW_RD_UBOUND26},
-	{PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
-		PXP2_REG_RQ_BW_RD_UBOUND27},
-	{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
-		PXP2_REG_PSWRQ_BW_UB28}
-};
-
-/* register addresses for write queues */
-static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
-/* 1 */	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
-		PXP2_REG_PSWRQ_BW_UB1},
-	{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
-		PXP2_REG_PSWRQ_BW_UB2},
-	{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
-		PXP2_REG_PSWRQ_BW_UB3},
-	{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
-		PXP2_REG_PSWRQ_BW_UB6},
-	{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
-		PXP2_REG_PSWRQ_BW_UB7},
-	{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
-		PXP2_REG_PSWRQ_BW_UB8},
-	{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
-		PXP2_REG_PSWRQ_BW_UB9},
-	{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
-		PXP2_REG_PSWRQ_BW_UB10},
-	{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
-		PXP2_REG_PSWRQ_BW_UB11},
-/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
-		PXP2_REG_PSWRQ_BW_UB28},
-	{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
-		PXP2_REG_RQ_BW_WR_UBOUND29},
-	{PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
-		PXP2_REG_RQ_BW_WR_UBOUND30}
-};
-
-
-/****************************************************************************
-* CDU
-****************************************************************************/
-
-#define CDU_REGION_NUMBER_XCM_AG	2
-#define CDU_REGION_NUMBER_UCM_AG	4
-
-/**
- * String-to-compress [31:8] = CID (all 24 bits)
- * String-to-compress [7:4] = Region
- * String-to-compress [3:0] = Type
- */
-#define CDU_VALID_DATA(_cid, _region, _type) \
-		(((_cid) << 8) | (((_region) & 0xf) << 4) | (((_type) & 0xf)))
-#define CDU_CRC8(_cid, _region, _type) \
-			calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff)
-#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type) \
-			(0x80 | (CDU_CRC8(_cid, _region, _type) & 0x7f))
-#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type) \
-	(0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
-#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val)	((_val) & ~0x80)
-
-
-/* registers addresses are not in order
-   so these arrays help simplify the code */
-static const int cm_blocks[9] = {
-	MISC_BLOCK, TCM_BLOCK,  UCM_BLOCK,  CCM_BLOCK, XCM_BLOCK,
-	TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK
-};
-
 #endif /* BNX2X_INIT_H */
 
diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h
index 32552b9..38b970a 100644
--- a/drivers/net/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x_init_ops.h
@@ -11,85 +11,68 @@
  * Maintained by: Eilon Greenstein <eilong@broadcom.com>
  * Written by: Vladislav Zolotarov <vladz@broadcom.com>
  */
+
 #ifndef BNX2X_INIT_OPS_H
 #define BNX2X_INIT_OPS_H
 
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
 static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
 
+
 static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
 			      u32 len)
 {
-	int i;
+	u32 i;
 
-	for (i = 0; i < len; i++) {
+	for (i = 0; i < len; i++)
 		REG_WR(bp, addr + i*4, data[i]);
-		if (!(i % 10000)) {
-			touch_softlockup_watchdog();
-			cpu_relax();
-		}
-	}
 }
 
 static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
-			      u16 len)
+			      u32 len)
 {
-	int i;
+	u32 i;
 
-	for (i = 0; i < len; i++) {
+	for (i = 0; i < len; i++)
 		REG_WR_IND(bp, addr + i*4, data[i]);
-		if (!(i % 10000)) {
-			touch_softlockup_watchdog();
-			cpu_relax();
-		}
-	}
 }
 
 static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
 {
-	int offset = 0;
-
-	if (bp->dmae_ready) {
-		while (len > DMAE_LEN32_WR_MAX) {
-			bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-					 addr + offset, DMAE_LEN32_WR_MAX);
-			offset += DMAE_LEN32_WR_MAX * 4;
-			len -= DMAE_LEN32_WR_MAX;
-		}
-		bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-				 addr + offset, len);
-	} else
-		bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
+	if (bp->dmae_ready)
+		bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
+	else
+		bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
 }
 
 static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
 {
-	u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
-	u32 buf_len32 = buf_len / 4;
-	int i;
+	u32 buf_len = (((len*4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len*4));
+	u32 buf_len32 = buf_len/4;
+	u32 i;
 
-	memset(bp->gunzip_buf, fill, buf_len);
+	memset(GUNZIP_BUF(bp), (u8)fill, buf_len);
 
 	for (i = 0; i < len; i += buf_len32) {
 		u32 cur_len = min(buf_len32, len - i);
 
-		bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+		bnx2x_write_big_buf(bp, addr + i*4, cur_len);
 	}
 }
 
 static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
 			     u32 len64)
 {
-	u32 buf_len32 = FW_BUF_SIZE / 4;
-	u32 len = len64 * 2;
+	u32 buf_len32 = FW_BUF_SIZE/4;
+	u32 len = len64*2;
 	u64 data64 = 0;
-	int i;
+	u32 i;
 
 	/* 64 bit value is in a blob: first low DWORD, then high DWORD */
 	data64 = HILO_U64((*(data + 1)), (*data));
+
 	len64 = min((u32)(FW_BUF_SIZE/8), len64);
 	for (i = 0; i < len64; i++) {
-		u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
+		u64 *pdata = ((u64 *)(GUNZIP_BUF(bp))) + i;
 
 		*pdata = data64;
 	}
@@ -97,7 +80,7 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
 	for (i = 0; i < len; i += buf_len32) {
 		u32 cur_len = min(buf_len32, len - i);
 
-		bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+		bnx2x_write_big_buf(bp, addr + i*4, cur_len);
 	}
 }
 
@@ -118,97 +101,81 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
 static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
 {
 	IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
-		data = bp->tsem_int_table_data;
-	else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
-		data = bp->csem_int_table_data;
-	else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
-		data = bp->usem_int_table_data;
-	else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
-		data = bp->xsem_int_table_data;
-	else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
-		data = bp->tsem_pram_data;
-	else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
-		data = bp->csem_pram_data;
-	else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
-		data = bp->usem_pram_data;
-	else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
-		data = bp->xsem_pram_data;
+		data = INIT_TSEM_INT_TABLE_DATA(bp);
+	else
+		IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
+			data = INIT_CSEM_INT_TABLE_DATA(bp);
+	else
+		IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
+			data = INIT_USEM_INT_TABLE_DATA(bp);
+	else
+		IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
+			data = INIT_XSEM_INT_TABLE_DATA(bp);
+	else
+		IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
+			data = INIT_TSEM_PRAM_DATA(bp);
+	else
+		IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
+			data = INIT_CSEM_PRAM_DATA(bp);
+	else
+		IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
+			data = INIT_USEM_PRAM_DATA(bp);
+	else
+		IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
+			data = INIT_XSEM_PRAM_DATA(bp);
 
 	return data;
 }
 
 static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
 {
-	int offset = 0;
-
-	if (bp->dmae_ready) {
-		while (len > DMAE_LEN32_WR_MAX) {
-			bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-					 addr + offset, DMAE_LEN32_WR_MAX);
-			offset += DMAE_LEN32_WR_MAX * 4;
-			len -= DMAE_LEN32_WR_MAX;
-		}
-		bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-				 addr + offset, len);
-	} else
-		bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
+	if (bp->dmae_ready)
+		bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
+	else
+		bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
 }
 
 static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
 			     u32 len)
 {
-	/* This is needed for NO_ZIP mode, currently supported
-	   in little endian mode only */
-	data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
+	data = (const u32 *)bnx2x_sel_blob(bp, addr, (const u8 *)data);
 
-	if ((len * 4) > FW_BUF_SIZE) {
-		BNX2X_ERR("LARGE DMAE OPERATION ! "
-			  "addr 0x%x  len 0x%x\n", addr, len*4);
-		return;
-	}
-	memcpy(bp->gunzip_buf, data, len * 4);
-
-	bnx2x_write_big_buf_wb(bp, addr, len);
+	if (bp->dmae_ready)
+		VIRT_WR_DMAE_LEN(bp, data, addr, len);
+	else
+		bnx2x_init_ind_wr(bp, addr, data, len);
 }
 
-static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr,
-			     u32 len, u32 blob_off)
+static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off)
 {
-	int rc, i;
-        const u8 *data = NULL;
+	const u8 *data = NULL;
+	int rc;
+	u32 i;
 
-	data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off;
-
-	if (data == NULL) {
-		panic("Blob not found for addr 0x%x\n", addr);
-		return;
-	}
+	data = bnx2x_sel_blob(bp, addr, data) + blob_off*4;
 
 	rc = bnx2x_gunzip(bp, data, len);
-	if (rc) {
-		BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc);
-		BNX2X_ERR("blob_offset=0x%x\n", blob_off);
+	if (rc)
 		return;
-	}
 
 	/* gunzip_outlen is in dwords */
-	len = bp->gunzip_outlen;
+	len = GUNZIP_OUTLEN(bp);
 	for (i = 0; i < len; i++)
-		((u32 *)bp->gunzip_buf)[i] =
-			cpu_to_le32(((u32 *)bp->gunzip_buf)[i]);
+		((u32 *)GUNZIP_BUF(bp))[i] =
+				cpu_to_le32(((u32 *)GUNZIP_BUF(bp))[i]);
 
 	bnx2x_write_big_buf_wb(bp, addr, len);
 }
 
 static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
 {
-	int hw_wr, i;
 	u16 op_start =
-		bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)];
+		INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_START)];
 	u16 op_end =
-		bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)];
+		INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_END)];
 	union init_op *op;
-	u32 op_type, addr, len;
+	int hw_wr;
+	u32 i, op_type, addr, len;
 	const u32 *data, *data_base;
 
 	/* If empty block */
@@ -222,11 +189,11 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
 	else
 		hw_wr = OP_WR_ASIC;
 
-	data_base = bp->init_data;
+	data_base = INIT_DATA(bp);
 
 	for (i = op_start; i < op_end; i++) {
 
-		op = (union init_op *)&(bp->init_ops[i]);
+		op = (union init_op *)&(INIT_OPS(bp)[i]);
 
 		op_type = op->str_wr.op;
 		addr = op->str_wr.offset;
@@ -234,7 +201,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
 		data = data_base + op->str_wr.data_off;
 
 		/* HW/EMUL specific */
-		if (unlikely((op_type > OP_WB) && (op_type == hw_wr)))
+		if ((op_type > OP_WB) && (op_type == hw_wr))
 			op_type = OP_WR;
 
 		switch (op_type) {
@@ -265,35 +232,179 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
 			break;
 		default:
 			/* happens whenever an op is of a diff HW */
-#if 0
-			DP(NETIF_MSG_HW, "skipping init operation  "
-			   "index %d[%d:%d]: type %d  addr 0x%x  "
-			   "len %d(0x%x)\n",
-			   i, op_start, op_end, op_type, addr, len, len);
-#endif
 			break;
 		}
 	}
 }
 
-/* PXP */
-static void bnx2x_init_pxp(struct bnx2x *bp)
+
+/****************************************************************************
+* PXP Arbiter
+****************************************************************************/
+/*
+ * This code configures the PCI read/write arbiter
+ * which implements a weighted round robin
+ * between the virtual queues in the chip.
+ *
+ * The values were derived for each PCI max payload and max request size.
+ * since max payload and max request size are only known at run time,
+ * this is done as a separate init stage.
+ */
+
+#define NUM_WR_Q			13
+#define NUM_RD_Q			29
+#define MAX_RD_ORD			3
+#define MAX_WR_ORD			2
+
+/* configuration for one arbiter queue */
+struct arb_line {
+	int l;
+	int add;
+	int ubound;
+};
+
+/* derived configuration for each read queue for each max request size */
+static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
+/* 1 */	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+	{ {4, 8,  4},  {4,  8,  4},  {4,  8,  4},  {4,  8,  4}  },
+	{ {4, 3,  3},  {4,  3,  3},  {4,  3,  3},  {4,  3,  3}  },
+	{ {8, 3,  6},  {16, 3,  11}, {16, 3,  11}, {16, 3,  11} },
+	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
+/* 10 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 64, 6},  {16, 64, 11}, {32, 64, 21}, {32, 64, 21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+/* 20 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
+	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
+};
+
+/* derived configuration for each write queue for each max request size */
+static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
+/* 1 */	{ {4, 6,  3},  {4,  6,  3},  {4,  6,  3} },
+	{ {4, 2,  3},  {4,  2,  3},  {4,  2,  3} },
+	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
+	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
+	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
+	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
+	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
+	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
+	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
+/* 10 */{ {8, 9,  6},  {16, 9,  11}, {32, 9,  21} },
+	{ {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
+	{ {8, 9,  6},  {16, 9,  11}, {16, 9,  11} },
+	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
+};
+
+/* register addresses for read queues */
+static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
+/* 1 */	{PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
+		PXP2_REG_RQ_BW_RD_UBOUND0},
+	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
+		PXP2_REG_PSWRQ_BW_UB1},
+	{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
+		PXP2_REG_PSWRQ_BW_UB2},
+	{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
+		PXP2_REG_PSWRQ_BW_UB3},
+	{PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
+		PXP2_REG_RQ_BW_RD_UBOUND4},
+	{PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
+		PXP2_REG_RQ_BW_RD_UBOUND5},
+	{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
+		PXP2_REG_PSWRQ_BW_UB6},
+	{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
+		PXP2_REG_PSWRQ_BW_UB7},
+	{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
+		PXP2_REG_PSWRQ_BW_UB8},
+/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
+		PXP2_REG_PSWRQ_BW_UB9},
+	{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
+		PXP2_REG_PSWRQ_BW_UB10},
+	{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
+		PXP2_REG_PSWRQ_BW_UB11},
+	{PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
+		PXP2_REG_RQ_BW_RD_UBOUND12},
+	{PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
+		PXP2_REG_RQ_BW_RD_UBOUND13},
+	{PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
+		PXP2_REG_RQ_BW_RD_UBOUND14},
+	{PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
+		PXP2_REG_RQ_BW_RD_UBOUND15},
+	{PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
+		PXP2_REG_RQ_BW_RD_UBOUND16},
+	{PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
+		PXP2_REG_RQ_BW_RD_UBOUND17},
+	{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
+		PXP2_REG_RQ_BW_RD_UBOUND18},
+/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
+		PXP2_REG_RQ_BW_RD_UBOUND19},
+	{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
+		PXP2_REG_RQ_BW_RD_UBOUND20},
+	{PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
+		PXP2_REG_RQ_BW_RD_UBOUND22},
+	{PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
+		PXP2_REG_RQ_BW_RD_UBOUND23},
+	{PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
+		PXP2_REG_RQ_BW_RD_UBOUND24},
+	{PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
+		PXP2_REG_RQ_BW_RD_UBOUND25},
+	{PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
+		PXP2_REG_RQ_BW_RD_UBOUND26},
+	{PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
+		PXP2_REG_RQ_BW_RD_UBOUND27},
+	{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
+		PXP2_REG_PSWRQ_BW_UB28}
+};
+
+/* register addresses for write queues */
+static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
+/* 1 */	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
+		PXP2_REG_PSWRQ_BW_UB1},
+	{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
+		PXP2_REG_PSWRQ_BW_UB2},
+	{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
+		PXP2_REG_PSWRQ_BW_UB3},
+	{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
+		PXP2_REG_PSWRQ_BW_UB6},
+	{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
+		PXP2_REG_PSWRQ_BW_UB7},
+	{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
+		PXP2_REG_PSWRQ_BW_UB8},
+	{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
+		PXP2_REG_PSWRQ_BW_UB9},
+	{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
+		PXP2_REG_PSWRQ_BW_UB10},
+	{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
+		PXP2_REG_PSWRQ_BW_UB11},
+/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
+		PXP2_REG_PSWRQ_BW_UB28},
+	{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
+		PXP2_REG_RQ_BW_WR_UBOUND29},
+	{PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
+		PXP2_REG_RQ_BW_WR_UBOUND30}
+};
+
+static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order)
 {
-	u16 devctl;
-	int r_order, w_order;
 	u32 val, i;
 
-	pci_read_config_word(bp->pdev,
-			     bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
-	DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
-	w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
-	if (bp->mrrs == -1)
-		r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
-	else {
-		DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
-		r_order = bp->mrrs;
-	}
-
 	if (r_order > MAX_RD_ORD) {
 		DP(NETIF_MSG_HW, "read order of %d  order adjusted to %d\n",
 		   r_order, MAX_RD_ORD);
@@ -367,6 +478,11 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
 	REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
 
 	if (CHIP_IS_E1H(bp)) {
+		/*    MPS      w_order     optimal TH      presently TH
+		 *    128         0             0               2
+		 *    256         1             1               3
+		 *    >=512       2             2               3
+		 */
 		val = ((w_order == 0) ? 2 : 3);
 		REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
 		REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
@@ -382,61 +498,4 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
 	}
 }
 
-/*****************************************************************************
- * Description:
- *         Calculates crc 8 on a word value: polynomial 0-1-2-8
- *         Code was translated from Verilog.
- ****************************************************************************/
-static u8 calc_crc8(u32 data, u8 crc)
-{
-	u8 D[32];
-	u8 NewCRC[8];
-	u8 C[8];
-	u8 crc_res;
-	u8 i;
-
-	/* split the data into 31 bits */
-	for (i = 0; i < 32; i++) {
-		D[i] = data & 1;
-		data = data >> 1;
-	}
-
-	/* split the crc into 8 bits */
-	for (i = 0; i < 8; i++) {
-		C[i] = crc & 1;
-		crc = crc >> 1;
-	}
-
-	NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
-		D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
-		C[6] ^ C[7];
-	NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
-		D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
-		D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
-	NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
-		D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
-		C[0] ^ C[1] ^ C[4] ^ C[5];
-	NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
-		D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
-		C[1] ^ C[2] ^ C[5] ^ C[6];
-	NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
-		D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
-		C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
-	NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
-		D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
-		C[3] ^ C[4] ^ C[7];
-	NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
-		D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
-		C[5];
-	NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
-		D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
-		C[6];
-
-	crc_res = 0;
-	for (i = 0; i < 8; i++)
-		crc_res |= (NewCRC[i] << i);
-
-	return crc_res;
-}
-
 #endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index 2ee581a..e32d337 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -37,6 +37,10 @@
 /*			Shortcut definitions		   */
 /***********************************************************/
 
+#define NIG_LATCH_BC_ENABLE_MI_INT 0
+
+#define NIG_STATUS_EMAC0_MI_INT \
+		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
 #define NIG_STATUS_XGXS0_LINK10G \
 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
 #define NIG_STATUS_XGXS0_LINK_STATUS \
@@ -139,21 +143,26 @@
 	#define SFP_EEPROM_CON_TYPE_VAL_LC 		0x7
 	#define SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
 
+
+#define SFP_EEPROM_COMP_CODE_ADDR		0x3
+	#define SFP_EEPROM_COMP_CODE_SR_MASK	(1<<4)
+	#define SFP_EEPROM_COMP_CODE_LR_MASK	(1<<5)
+	#define SFP_EEPROM_COMP_CODE_LRM_MASK	(1<<6)
+
 #define SFP_EEPROM_FC_TX_TECH_ADDR		0x8
 	#define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
 	#define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE	 0x8
-#define SFP_EEPROM_VENDOR_NAME_ADDR		0x14
-#define SFP_EEPROM_VENDOR_NAME_SIZE 	16
+
 #define SFP_EEPROM_OPTIONS_ADDR 		0x40
 	#define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
 #define SFP_EEPROM_OPTIONS_SIZE 		2
 
-#define SFP_MODULE_TYPE_UNKNOWN 			0x0
-#define SFP_MODULE_TYPE_LC   			0x1
-#define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE		0x2
-#define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE	0x3
+#define EDC_MODE_LINEAR	 			0x0022
+#define EDC_MODE_LIMITING	 			0x0044
+#define EDC_MODE_PASSIVE_DAC 			0x0055
+
+
 
-#define SFP_LIMITING_MODE_VALUE 			0x0044
 /**********************************************************/
 /*                     INTERFACE                          */
 /**********************************************************/
@@ -173,6 +182,7 @@ static void bnx2x_set_serdes_access(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
 	u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
 	/* Set Clause 22 */
 	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
 	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
@@ -185,6 +195,7 @@ static void bnx2x_set_serdes_access(struct link_params *params)
 static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
 {
 	struct bnx2x *bp = params->bp;
+
 	if (phy_flags & PHY_XGXS_FLAG) {
 		REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
 			   params->port*0x18, 0);
@@ -388,7 +399,8 @@ static u8 bnx2x_emac_enable(struct link_params *params,
 
 		/* enable access for bmac registers */
 		REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
-	}
+	} else
+		REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
 
 	vars->mac_type = MAC_TYPE_EMAC;
 	return 0;
@@ -455,7 +467,6 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
 		    wb_data, 2);
 
-
 	/* set rx mtu */
 	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
 	wb_data[1] = 0;
@@ -674,6 +685,7 @@ void bnx2x_link_status_update(struct link_params *params,
 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
 {
 	struct bnx2x *bp = params->bp;
+
 	REG_WR(bp, params->shmem_base +
 		   offsetof(struct shmem_region,
 			    port_mb[params->port].link_status),
@@ -770,7 +782,6 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
 			DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
 				  line_speed);
 			return -EINVAL;
-			break;
 		}
 	}
 	REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
@@ -790,9 +801,11 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
 {
 	u32 emac_base;
+
 	switch (ext_phy_type) {
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
 		/* All MDC/MDIO is directed through single EMAC */
 		if (REG_RD(bp, NIG_REG_PORT_SWAP))
 			emac_base = GRCBASE_EMAC0;
@@ -894,7 +907,7 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
 	val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
 			     EMAC_MDIO_MODE_CLOCK_CNT));
 	val |= (EMAC_MDIO_MODE_CLAUSE_45 |
-		(49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
+		(49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
 	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
 	REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
 	udelay(40);
@@ -1011,8 +1024,8 @@ static u8 bnx2x_reset_unicore(struct link_params *params)
 			      MDIO_COMBO_IEEE0_MII_CONTROL,
 			      (mii_control |
 			       MDIO_COMBO_IEEO_MII_CONTROL_RESET));
-
-	bnx2x_set_serdes_access(params);
+	if (params->switch_cfg == SWITCH_CFG_1G)
+		bnx2x_set_serdes_access(params);
 
 	/* wait for the reset to self clear */
 	for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
@@ -1141,7 +1154,8 @@ static void bnx2x_set_parallel_detection(struct link_params *params,
 }
 
 static void bnx2x_set_autoneg(struct link_params *params,
-			    struct link_vars   *vars)
+			    struct link_vars *vars,
+			    u8 enable_cl73)
 {
 	struct bnx2x *bp = params->bp;
 	u16 reg_val;
@@ -1171,7 +1185,9 @@ static void bnx2x_set_autoneg(struct link_params *params,
 			      params->phy_addr,
 			      MDIO_REG_BANK_SERDES_DIGITAL,
 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
-	reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
+	reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
+		    MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
+	reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
 	if (vars->line_speed == SPEED_AUTO_NEG)
 		reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
 	else
@@ -1203,8 +1219,51 @@ static void bnx2x_set_autoneg(struct link_params *params,
 			      MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
 			      reg_val);
 
-	/* CL73 Autoneg Disabled */
-	reg_val = 0;
+	if (enable_cl73) {
+		/* Enable Cl73 FSM status bits */
+		CL45_WR_OVER_CL22(bp, params->port,
+				      params->phy_addr,
+				      MDIO_REG_BANK_CL73_USERB0,
+				    MDIO_CL73_USERB0_CL73_UCTRL,
+				    MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL);
+
+		/* Enable BAM Station Manager*/
+		CL45_WR_OVER_CL22(bp, params->port,
+			params->phy_addr,
+			MDIO_REG_BANK_CL73_USERB0,
+			MDIO_CL73_USERB0_CL73_BAM_CTRL1,
+			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
+			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
+			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
+
+		/* Merge CL73 and CL37 aneg resolution */
+		CL45_RD_OVER_CL22(bp, params->port,
+				      params->phy_addr,
+				      MDIO_REG_BANK_CL73_USERB0,
+				      MDIO_CL73_USERB0_CL73_BAM_CTRL3,
+				      &reg_val);
+
+		if (params->speed_cap_mask &
+		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
+			/* Set the CL73 AN speed */
+			CL45_RD_OVER_CL22(bp, params->port,
+					      params->phy_addr,
+					      MDIO_REG_BANK_CL73_IEEEB1,
+					      MDIO_CL73_IEEEB1_AN_ADV2,
+					      &reg_val);
+
+			CL45_WR_OVER_CL22(bp, params->port,
+					      params->phy_addr,
+					      MDIO_REG_BANK_CL73_IEEEB1,
+					      MDIO_CL73_IEEEB1_AN_ADV2,
+			  reg_val | MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4);
+
+		}
+		/* CL73 Autoneg Enabled */
+		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
+
+	} else /* CL73 Autoneg Disabled */
+		reg_val = 0;
 
 	CL45_WR_OVER_CL22(bp, params->port,
 			      params->phy_addr,
@@ -1219,14 +1278,14 @@ static void bnx2x_program_serdes(struct link_params *params,
 	struct bnx2x *bp = params->bp;
 	u16 reg_val;
 
-	/* program duplex, disable autoneg */
-
+	/* program duplex, disable autoneg and sgmii*/
 	CL45_RD_OVER_CL22(bp, params->port,
 			      params->phy_addr,
 			      MDIO_REG_BANK_COMBO_IEEE0,
 			      MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
 	reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
-		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
+		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+		     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
 	if (params->req_duplex == DUPLEX_FULL)
 		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
 	CL45_WR_OVER_CL22(bp, params->port,
@@ -1287,10 +1346,10 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
 	CL45_WR_OVER_CL22(bp, params->port,
 			      params->phy_addr,
 			      MDIO_REG_BANK_OVER_1G,
-			      MDIO_OVER_1G_UP3, 0);
+			      MDIO_OVER_1G_UP3, 0x400);
 }
 
-static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
+static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
 {
 	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
 	/* resolve pause mode and advertisement
@@ -1324,7 +1383,7 @@ static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
 }
 
 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
-					   u32 ieee_fc)
+					   u16 ieee_fc)
 {
 	struct bnx2x *bp = params->bp;
 	/* for AN, we are always publishing full duplex */
@@ -1332,31 +1391,49 @@ static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
 	CL45_WR_OVER_CL22(bp, params->port,
 			      params->phy_addr,
 			      MDIO_REG_BANK_COMBO_IEEE0,
-			      MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
+			      MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
 }
 
-static void bnx2x_restart_autoneg(struct link_params *params)
+static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
 {
 	struct bnx2x *bp = params->bp;
 	u16 mii_control;
+
 	DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
 	/* Enable and restart BAM/CL37 aneg */
 
-	CL45_RD_OVER_CL22(bp, params->port,
-			      params->phy_addr,
-			      MDIO_REG_BANK_COMBO_IEEE0,
-			      MDIO_COMBO_IEEE0_MII_CONTROL,
-			      &mii_control);
-	DP(NETIF_MSG_LINK,
-		 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
-		 mii_control);
-	CL45_WR_OVER_CL22(bp, params->port,
-			      params->phy_addr,
-			      MDIO_REG_BANK_COMBO_IEEE0,
-			      MDIO_COMBO_IEEE0_MII_CONTROL,
-			      (mii_control |
-			       MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
-			       MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
+	if (enable_cl73) {
+		CL45_RD_OVER_CL22(bp, params->port,
+				      params->phy_addr,
+				      MDIO_REG_BANK_CL73_IEEEB0,
+				      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+				      &mii_control);
+
+		CL45_WR_OVER_CL22(bp, params->port,
+				params->phy_addr,
+				MDIO_REG_BANK_CL73_IEEEB0,
+				MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+				(mii_control |
+				MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
+				MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
+	} else {
+
+		CL45_RD_OVER_CL22(bp, params->port,
+				      params->phy_addr,
+				      MDIO_REG_BANK_COMBO_IEEE0,
+				      MDIO_COMBO_IEEE0_MII_CONTROL,
+				      &mii_control);
+		DP(NETIF_MSG_LINK,
+			 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
+			 mii_control);
+		CL45_WR_OVER_CL22(bp, params->port,
+				      params->phy_addr,
+				      MDIO_REG_BANK_COMBO_IEEE0,
+				      MDIO_COMBO_IEEE0_MII_CONTROL,
+				      (mii_control |
+				       MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+				       MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
+	}
 }
 
 static void bnx2x_initialize_sgmii_process(struct link_params *params,
@@ -1428,7 +1505,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
 
 	} else { /* AN mode */
 		/* enable and restart AN */
-		bnx2x_restart_autoneg(params);
+		bnx2x_restart_autoneg(params, 0);
 	}
 }
 
@@ -1460,22 +1537,19 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
 	}
 }
 
-static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
+static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
 				  struct link_vars *vars)
 {
 	struct bnx2x *bp = params->bp;
 	u8 ext_phy_addr;
-	u16 ld_pause;	/* local */
-	u16 lp_pause;	/* link partner */
-	u16 an_complete; /* AN complete */
+	u16 ld_pause;		/* local */
+	u16 lp_pause;		/* link partner */
+	u16 an_complete;	/* AN complete */
 	u16 pause_result;
 	u8 ret = 0;
 	u32 ext_phy_type;
 	u8 port = params->port;
-	ext_phy_addr = ((params->ext_phy_config &
-			 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
+	ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 	/* read twice */
 
@@ -1570,7 +1644,7 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
 		DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
 		bnx2x_pause_resolve(vars, pause_result);
 	} else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
-		   (bnx2x_ext_phy_resove_fc(params, vars))) {
+		   (bnx2x_ext_phy_resolve_fc(params, vars))) {
 		return;
 	} else {
 		if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
@@ -1581,10 +1655,77 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
 	DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
 }
 
-
+static void bnx2x_check_fallback_to_cl37(struct link_params *params)
+{
+	struct bnx2x *bp = params->bp;
+	u16 rx_status, ustat_val, cl37_fsm_recieved;
+	DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
+	/* Step 1: Make sure signal is detected */
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_RX0,
+			      MDIO_RX0_RX_STATUS,
+			      &rx_status);
+	if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
+	    (MDIO_RX0_RX_STATUS_SIGDET)) {
+		DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
+			     "rx_status(0x80b0) = 0x%x\n", rx_status);
+		CL45_WR_OVER_CL22(bp, params->port,
+				      params->phy_addr,
+				      MDIO_REG_BANK_CL73_IEEEB0,
+				      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+				      MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
+		return;
+	}
+	/* Step 2: Check CL73 state machine */
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_CL73_USERB0,
+			      MDIO_CL73_USERB0_CL73_USTAT1,
+			      &ustat_val);
+	if ((ustat_val &
+	     (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
+	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
+	    (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
+	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
+		DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
+			     "ustat_val(0x8371) = 0x%x\n", ustat_val);
+		return;
+	}
+	/* Step 3: Check CL37 Message Pages received to indicate LP
+	supports only CL37 */
+	CL45_RD_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_REMOTE_PHY,
+			      MDIO_REMOTE_PHY_MISC_RX_STATUS,
+			      &cl37_fsm_recieved);
+	if ((cl37_fsm_recieved &
+	     (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
+	     MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
+	    (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
+	      MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
+		DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
+			     "misc_rx_status(0x8330) = 0x%x\n",
+			 cl37_fsm_recieved);
+		return;
+	}
+	/* The combined cl37/cl73 fsm state information indicating that we are
+	connected to a device which does not support cl73, but does support
+	cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
+	/* Disable CL73 */
+	CL45_WR_OVER_CL22(bp, params->port,
+			      params->phy_addr,
+			      MDIO_REG_BANK_CL73_IEEEB0,
+			      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+			      0);
+	/* Restart CL37 autoneg */
+	bnx2x_restart_autoneg(params, 0);
+	DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
+}
 static u8 bnx2x_link_settings_status(struct link_params *params,
-				      struct link_vars *vars,
-				      u32 gp_status)
+				   struct link_vars *vars,
+				   u32 gp_status,
+				   u8 ext_phy_link_up)
 {
 	struct bnx2x *bp = params->bp;
 	u16 new_line_speed;
@@ -1645,7 +1786,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 				 "link speed unsupported  gp_status 0x%x\n",
 				  gp_status);
 			return -EINVAL;
-			break;
+
 		case GP_STATUS_10G_KX4:
 		case GP_STATUS_10G_HIG:
 		case GP_STATUS_10G_CX4:
@@ -1682,14 +1823,23 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 			DP(NETIF_MSG_LINK,
 				  "link speed unsupported gp_status 0x%x\n",
 				  gp_status);
-		return -EINVAL;
-			break;
+			return -EINVAL;
 		}
 
 		/* Upon link speed change set the NIG into drain mode.
 		Comes to deals with possible FIFO glitch due to clk change
 		when speed is decreased without link down indicator */
 		if (new_line_speed != vars->line_speed) {
+			if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) !=
+			     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT &&
+			    ext_phy_link_up) {
+				DP(NETIF_MSG_LINK, "Internal link speed %d is"
+					    " different than the external"
+					    " link speed %d\n", new_line_speed,
+					  vars->line_speed);
+				vars->phy_link_up = 0;
+				return 0;
+			}
 			REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
 				    + params->port*4, 0);
 			msleep(1);
@@ -1703,9 +1853,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
 		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
 		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
-		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
-		     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
-		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
 			vars->autoneg = AUTO_NEG_ENABLED;
 
 			if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
@@ -1736,6 +1884,13 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
 		vars->autoneg = AUTO_NEG_DISABLED;
 		vars->mac_type = MAC_TYPE_NONE;
+
+		if ((params->req_line_speed == SPEED_AUTO_NEG) &&
+		    ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
+		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) {
+			/* Check signal is detected */
+			bnx2x_check_fallback_to_cl37(params);
+		}
 	}
 
 	DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
@@ -1840,7 +1995,7 @@ static u8 bnx2x_emac_program(struct link_params *params,
 /*****************************************************************************/
 /*      		     External Phy section       		     */
 /*****************************************************************************/
-static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
+void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
 {
 	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
@@ -1854,9 +2009,8 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 {
 	struct bnx2x *bp = params->bp;
 	u32 ext_phy_type;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+
 	DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 	/* The PHY reset is controled by GPIO 1
@@ -1879,7 +2033,7 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 					  params->port);
 
 			/* HW reset */
-			bnx2x_hw_reset(bp, params->port);
+			bnx2x_ext_phy_hw_reset(bp, params->port);
 
 			bnx2x_cl45_write(bp, params->port,
 				       ext_phy_type,
@@ -1887,6 +2041,10 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 				       MDIO_PMA_DEVAD,
 				       MDIO_PMA_REG_CTRL, 0xa040);
 			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+			break;
+
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
 
 			/* Restore normal power mode*/
@@ -1904,16 +2062,17 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 				       MDIO_PMA_DEVAD,
 				       MDIO_PMA_REG_CTRL,
 				       1<<15);
-
 			break;
+
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
+			DP(NETIF_MSG_LINK, "XGXS 8072\n");
+
 			/* Unset Low Power Mode and SW reset */
 			/* Restore normal power mode*/
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
 					  params->port);
 
-			DP(NETIF_MSG_LINK, "XGXS 8072\n");
 			bnx2x_cl45_write(bp, params->port,
 				       ext_phy_type,
 				       ext_phy_addr,
@@ -1921,8 +2080,9 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 				       MDIO_PMA_REG_CTRL,
 				       1<<15);
 			break;
+
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
-			{
+			DP(NETIF_MSG_LINK, "XGXS 8073\n");
 
 			/* Restore normal power mode*/
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
@@ -1932,9 +2092,6 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
 					  params->port);
-
-			DP(NETIF_MSG_LINK, "XGXS 8073\n");
-			}
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
@@ -1946,19 +2103,17 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 					  params->port);
 
 			/* HW reset */
-			bnx2x_hw_reset(bp, params->port);
-
+			bnx2x_ext_phy_hw_reset(bp, params->port);
 			break;
 
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
-
 			/* Restore normal power mode*/
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
 					  params->port);
 
 			/* HW reset */
-			bnx2x_hw_reset(bp, params->port);
+			bnx2x_ext_phy_hw_reset(bp, params->port);
 
 			bnx2x_cl45_write(bp, params->port,
 				       ext_phy_type,
@@ -1986,24 +2141,22 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
 
 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
 			DP(NETIF_MSG_LINK, "SerDes 5482\n");
-			bnx2x_hw_reset(bp, params->port);
+			bnx2x_ext_phy_hw_reset(bp, params->port);
 			break;
 
 		default:
-			DP(NETIF_MSG_LINK,
-				 "BAD SerDes ext_phy_config 0x%x\n",
+			DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
 				 params->ext_phy_config);
 			break;
 		}
 	}
 }
 
-
 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
 				    u32 shmem_base, u32 spirom_ver)
 {
-	DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
-		 (u16)(spirom_ver>>16), (u16)spirom_ver);
+	DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
+		 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
 	REG_WR(bp, shmem_base +
 		   offsetof(struct shmem_region,
 			    port_mb[port].ext_phy_fw_version),
@@ -2015,6 +2168,7 @@ static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
 				    u32 shmem_base)
 {
 	u16 fw_ver1, fw_ver2;
+
 	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
 		      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
 	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
@@ -2023,13 +2177,116 @@ static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
 				(u32)(fw_ver1<<16 | fw_ver2));
 }
 
+
+static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port,
+					 u8 ext_phy_addr, u32 shmem_base)
+{
+	u16 val, fw_ver1, fw_ver2, cnt;
+	/* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/
+	/* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr, MDIO_PMA_DEVAD,
+		       0xA819, 0x0014);
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       0xA81A,
+		       0xc200);
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       0xA81B,
+		       0x0000);
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       0xA81C,
+		       0x0300);
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       0xA817,
+		       0x0009);
+
+	for (cnt = 0; cnt < 100; cnt++) {
+		bnx2x_cl45_read(bp, port,
+			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      0xA818,
+			      &val);
+		if (val & 1)
+			break;
+		udelay(5);
+	}
+	if (cnt == 100) {
+		DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n");
+		bnx2x_save_spirom_version(bp, port,
+					shmem_base, 0);
+		return;
+	}
+
+
+	/* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr, MDIO_PMA_DEVAD,
+		       0xA819, 0x0000);
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr, MDIO_PMA_DEVAD,
+		       0xA81A, 0xc200);
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		       ext_phy_addr, MDIO_PMA_DEVAD,
+		       0xA817, 0x000A);
+	for (cnt = 0; cnt < 100; cnt++) {
+		bnx2x_cl45_read(bp, port,
+			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      0xA818,
+			      &val);
+		if (val & 1)
+			break;
+		udelay(5);
+	}
+	if (cnt == 100) {
+		DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n");
+		bnx2x_save_spirom_version(bp, port,
+					shmem_base, 0);
+		return;
+	}
+
+	/* lower 16 bits of the register SPI_FW_STATUS */
+	bnx2x_cl45_read(bp, port,
+		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      0xA81B,
+		      &fw_ver1);
+	/* upper 16 bits of register SPI_FW_STATUS */
+	bnx2x_cl45_read(bp, port,
+		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      0xA81C,
+		      &fw_ver2);
+
+	bnx2x_save_spirom_version(bp, port,
+				shmem_base, (fw_ver2<<16) | fw_ver1);
+}
+
 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 	/* Need to wait 200ms after reset */
@@ -2077,9 +2334,7 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
 	/* This is only required for 8073A1, version 102 only */
 
 	struct bnx2x *bp = params->bp;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u16 val;
 
 	/* Read 8073 HW revision*/
@@ -2110,9 +2365,7 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u16 val, cnt, cnt1 ;
 
 	bnx2x_cl45_read(bp, params->port,
@@ -2168,16 +2421,17 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
 	}
 	DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
 	return -EINVAL;
-
 }
 
-static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
-					  u8 ext_phy_addr, u32 shmem_base)
+static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
+						  u8 ext_phy_addr,
+						  u32 ext_phy_type,
+						  u32 shmem_base)
 {
 	/* Boot port from external ROM  */
 	/* EDC grst */
 	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_GEN_CTRL,
@@ -2185,21 +2439,21 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
 
 	/* ucode reboot and rst */
 	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_GEN_CTRL,
 		       0x008c);
 
 	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
 
 	/* Reset internal microprocessor */
 	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_GEN_CTRL,
@@ -2207,7 +2461,7 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
 
 	/* Release srst bit */
 	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_GEN_CTRL,
@@ -2218,24 +2472,41 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
 
 	/* Clear ser_boot_ctl bit */
 	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
 
 	bnx2x_save_bcm_spirom_ver(bp, port,
-				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+				ext_phy_type,
 				ext_phy_addr,
 				shmem_base);
 }
 
+static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
+					  u8 ext_phy_addr,
+					  u32 shmem_base)
+{
+	bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
+					 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
+					 shmem_base);
+}
+
+static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
+					  u8 ext_phy_addr,
+					  u32 shmem_base)
+{
+	bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
+					 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+					 shmem_base);
+
+}
+
 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 	/* Need to wait 100ms after reset */
@@ -2258,9 +2529,10 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
 		       MDIO_PMA_REG_GEN_CTRL,
 		       MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
 
+	/* Set PLL register value to be same like in P13 ver */
 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
 		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_GEN_CTRL2,
+		       MDIO_PMA_REG_PLL_CTRL,
 		       0x73A0);
 
 	/* Clear soft reset.
@@ -2285,15 +2557,17 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
 				params->shmem_base);
 }
 
-static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
-					u8 ext_phy_addr, u8 tx_en)
+static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
+				    u32 ext_phy_type, u8 ext_phy_addr,
+				    u8 tx_en)
 {
 	u16 val;
+
 	DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
 		 tx_en, port);
 	/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
 	bnx2x_cl45_read(bp, port,
-		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+		      ext_phy_type,
 		      ext_phy_addr,
 		      MDIO_PMA_DEVAD,
 		      MDIO_PMA_REG_PHY_IDENTIFIER,
@@ -2305,23 +2579,23 @@ static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
 		val |= (1<<15);
 
 	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
+		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_PHY_IDENTIFIER,
 		       val);
 }
 
-
-static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
-				     u8 byte_cnt, u8 *o_buf) {
+static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
+					  u16 addr, u8 byte_cnt, u8 *o_buf)
+{
 	struct bnx2x *bp = params->bp;
-	u16 val, i;
+	u16 val = 0;
+	u16 i;
 	u8 port = params->port;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
 	if (byte_cnt > 16) {
 		DP(NETIF_MSG_LINK, "Reading from eeprom is"
 			    " is limited to 0xf\n");
@@ -2332,7 +2606,7 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
 		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
+		       MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
 		       (byte_cnt | 0xa000));
 
 	/* Set the read command address */
@@ -2340,7 +2614,7 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
 		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
+		       MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
 		       addr);
 
 	/* Activate read command */
@@ -2348,7 +2622,7 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
 		       ext_phy_type,
 		       ext_phy_addr,
 		       MDIO_PMA_DEVAD,
-		       MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
+		       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
 		       0x2c0f);
 
 	/* Wait up to 500us for command complete status */
@@ -2357,18 +2631,18 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
 			      ext_phy_type,
 			      ext_phy_addr,
 			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
-		if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
-		    MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
+			      MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
+		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
+		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
 			break;
 		udelay(5);
 	}
 
-	if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
-		    MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
+	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
+		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
 		DP(NETIF_MSG_LINK,
 			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
-			 (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
+			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
 		return -EINVAL;
 	}
 
@@ -2387,29 +2661,145 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
 			      ext_phy_type,
 			      ext_phy_addr,
 			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
-		if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
-		    MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
+			      MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
+		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
+		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
 			return 0;;
 		msleep(1);
 	}
 	return -EINVAL;
 }
 
+static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
+					  u16 addr, u8 byte_cnt, u8 *o_buf)
+{
+	struct bnx2x *bp = params->bp;
+	u16 val, i;
+	u8 port = params->port;
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
-static u8 bnx2x_get_sfp_module_type(struct link_params *params,
-				  u8 *module_type)
+	if (byte_cnt > 16) {
+		DP(NETIF_MSG_LINK, "Reading from eeprom is"
+			    " is limited to 0xf\n");
+		return -EINVAL;
+	}
+
+	/* Need to read from 1.8000 to clear it */
+	bnx2x_cl45_read(bp, port,
+		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
+		      &val);
+
+	/* Set the read command byte count */
+	bnx2x_cl45_write(bp, port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
+		       ((byte_cnt < 2) ? 2 : byte_cnt));
+
+	/* Set the read command address */
+	bnx2x_cl45_write(bp, port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
+		       addr);
+	/* Set the destination address */
+	bnx2x_cl45_write(bp, port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       0x8004,
+		       MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
+
+	/* Activate read command */
+	bnx2x_cl45_write(bp, port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
+		       0x8002);
+	/* Wait appropriate time for two-wire command to finish before
+	polling the status register */
+	msleep(1);
+
+	/* Wait up to 500us for command complete status */
+	for (i = 0; i < 100; i++) {
+		bnx2x_cl45_read(bp, port,
+			      ext_phy_type,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
+		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
+		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
+			break;
+		udelay(5);
+	}
+
+	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
+		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
+		DP(NETIF_MSG_LINK,
+			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
+			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
+		return -EINVAL;
+	}
+
+	/* Read the buffer */
+	for (i = 0; i < byte_cnt; i++) {
+		bnx2x_cl45_read(bp, port,
+			      ext_phy_type,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
+		o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
+	}
+
+	for (i = 0; i < 100; i++) {
+		bnx2x_cl45_read(bp, port,
+			      ext_phy_type,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
+		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
+		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
+			return 0;;
+		msleep(1);
+	}
+
+	return -EINVAL;
+}
+
+u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+				     u8 byte_cnt, u8 *o_buf)
+{
+	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
+	if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
+		return bnx2x_8726_read_sfp_module_eeprom(params, addr,
+						       byte_cnt, o_buf);
+	else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
+		return bnx2x_8727_read_sfp_module_eeprom(params, addr,
+						       byte_cnt, o_buf);
+	return -EINVAL;
+}
+
+static u8 bnx2x_get_edc_mode(struct link_params *params,
+				  u16 *edc_mode)
 {
 	struct bnx2x *bp = params->bp;
-	u8 val;
-	*module_type = SFP_MODULE_TYPE_UNKNOWN;
+	u8 val, check_limiting_mode = 0;
+	*edc_mode = EDC_MODE_LIMITING;
 
 	/* First check for copper cable */
 	if (bnx2x_read_sfp_module_eeprom(params,
 				       SFP_EEPROM_CON_TYPE_ADDR,
 				       1,
 				       &val) != 0) {
-		DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
+		DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
 		return -EINVAL;
 	}
 
@@ -2417,6 +2807,7 @@ static u8 bnx2x_get_sfp_module_type(struct link_params *params,
 	case SFP_EEPROM_CON_TYPE_VAL_COPPER:
 	{
 		u8 copper_module_type;
+
 		/* Check if its active cable( includes SFP+ module)
 		of passive cable*/
 		if (bnx2x_read_sfp_module_eeprom(params,
@@ -2433,13 +2824,13 @@ static u8 bnx2x_get_sfp_module_type(struct link_params *params,
 		if (copper_module_type &
 		    SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
 			DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
-			*module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
+			check_limiting_mode = 1;
 		} else if (copper_module_type &
 			SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
 				DP(NETIF_MSG_LINK, "Passive Copper"
 					    " cable detected\n");
-				*module_type =
-				      SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
+				*edc_mode =
+				      EDC_MODE_PASSIVE_DAC;
 		} else {
 			DP(NETIF_MSG_LINK, "Unknown copper-cable-"
 				     "type 0x%x !!!\n", copper_module_type);
@@ -2449,97 +2840,97 @@ static u8 bnx2x_get_sfp_module_type(struct link_params *params,
 	}
 	case SFP_EEPROM_CON_TYPE_VAL_LC:
 		DP(NETIF_MSG_LINK, "Optic module detected\n");
-		*module_type = SFP_MODULE_TYPE_LC;
+		check_limiting_mode = 1;
 		break;
-
 	default:
 		DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
 			 val);
 		return -EINVAL;
 	}
+
+	if (check_limiting_mode) {
+		u8 options[SFP_EEPROM_OPTIONS_SIZE];
+		if (bnx2x_read_sfp_module_eeprom(params,
+					       SFP_EEPROM_OPTIONS_ADDR,
+					       SFP_EEPROM_OPTIONS_SIZE,
+					       options) != 0) {
+			DP(NETIF_MSG_LINK, "Failed to read Option"
+				" field from module EEPROM\n");
+			return -EINVAL;
+		}
+		if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
+			*edc_mode = EDC_MODE_LINEAR;
+		else
+			*edc_mode = EDC_MODE_LIMITING;
+	}
+	DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
 	return 0;
 }
 
-
 /* This function read the relevant field from the module ( SFP+ ),
 	and verify it is compliant with this board */
-static u8 bnx2x_verify_sfp_module(struct link_params *params,
-				u8 module_type)
+static u8 bnx2x_verify_sfp_module(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
-	u8 *str_p, *tmp_buf;
-	u16 i;
-
-#define COMPLIANCE_STR_CNT 6
-	u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
-		"FINISAR CORP.   ", "Amphenol"};
-	u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
-	/* Passive Copper cables are allowed to participate,
-	since the module is hardwired to the copper cable */
-
-	if (!(params->feature_config_flags &
-	     FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
+	u32 val;
+	u32 fw_resp;
+	char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
+	char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
+
+	val = REG_RD(bp, params->shmem_base +
+			 offsetof(struct shmem_region, dev_info.
+				  port_feature_config[params->port].config));
+	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
+	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
 		DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
 		return 0;
 	}
 
-	if (module_type != SFP_MODULE_TYPE_LC) {
-		DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
+	/* Ask the FW to validate the module */
+	if (!(params->feature_config_flags &
+	      FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
+		DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
+			    "verification\n");
+		return -EINVAL;
+	}
+
+	fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
+	if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
+		DP(NETIF_MSG_LINK, "Approved module\n");
 		return 0;
 	}
 
-	/* In case of non copper cable or Active copper cable,
-		verify that the SFP+ module is compliant with this board*/
+	/* format the warning message */
 	if (bnx2x_read_sfp_module_eeprom(params,
 				       SFP_EEPROM_VENDOR_NAME_ADDR,
 				       SFP_EEPROM_VENDOR_NAME_SIZE,
-				       buf) != 0) {
-		DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
-			    " module EEPROM\n");
-		return -EINVAL;
-	}
-	for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
-		str_p = compliance_str[i];
-		tmp_buf = buf;
-		while (*str_p) {
-			if ((u8)(*tmp_buf) != (u8)(*str_p))
-				break;
-			str_p++;
-			tmp_buf++;
-		}
+				       (u8 *)vendor_name))
+		vendor_name[0] = '\0';
+	else
+		vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
+	if (bnx2x_read_sfp_module_eeprom(params,
+				       SFP_EEPROM_PART_NO_ADDR,
+				       SFP_EEPROM_PART_NO_SIZE,
+				       (u8 *)vendor_pn))
+		vendor_pn[0] = '\0';
+	else
+		vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
 
-		if (!(*str_p)) {
-			DP(NETIF_MSG_LINK, "SFP+ Module verified, "
-				     "index=%x\n", i);
-			return 0;
-		}
-	}
-	DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
+	printk(KERN_INFO PFX  "Warning: "
+			 "Unqualified SFP+ module "
+			 "detected on %s, Port %d from %s part number %s\n"
+			, bp->dev->name, params->port,
+			vendor_name, vendor_pn);
 	return -EINVAL;
 }
 
-
 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
-					u8 module_type)
+					u16 edc_mode)
 {
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
-	u8 options[SFP_EEPROM_OPTIONS_SIZE];
-	u8 limiting_mode;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u16 cur_limiting_mode;
-	if (bnx2x_read_sfp_module_eeprom(params,
-				       SFP_EEPROM_OPTIONS_ADDR,
-				       SFP_EEPROM_OPTIONS_SIZE,
-				       options) != 0) {
-		DP(NETIF_MSG_LINK, "Failed to read Option field from"
-			    " module EEPROM\n");
-		return -EINVAL;
-	}
-	limiting_mode = !(options[0] &
-			  SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
 
 	bnx2x_cl45_read(bp, port,
 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
@@ -2550,26 +2941,23 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
 	DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
 		 cur_limiting_mode);
 
-	if (limiting_mode &&
-	    (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
+	if (edc_mode == EDC_MODE_LIMITING) {
 		DP(NETIF_MSG_LINK,
-			 "Module options = 0x%x.Setting LIMITING MODE\n",
-			 options[0]);
+			 "Setting LIMITING MODE\n");
 		bnx2x_cl45_write(bp, port,
 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
 			       ext_phy_addr,
 			       MDIO_PMA_DEVAD,
 			       MDIO_PMA_REG_ROM_VER2,
-			       SFP_LIMITING_MODE_VALUE);
+			       EDC_MODE_LIMITING);
 	} else { /* LRM mode ( default )*/
 
-		DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
-			 options[0]);
+		DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
 
 		/* Changing to LRM mode takes quite few seconds.
 		So do it only if current mode is limiting
 		( default is LRM )*/
-		if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
+		if (cur_limiting_mode != EDC_MODE_LIMITING)
 			return 0;
 
 		bnx2x_cl45_write(bp, port,
@@ -2600,6 +2988,54 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
 	return 0;
 }
 
+static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
+					u16 edc_mode)
+{
+	struct bnx2x *bp = params->bp;
+	u8 port = params->port;
+	u16 phy_identifier;
+	u16 rom_ver2_val;
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+
+	bnx2x_cl45_read(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_PHY_IDENTIFIER,
+		       &phy_identifier);
+
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_PHY_IDENTIFIER,
+		       (phy_identifier & ~(1<<9)));
+
+	bnx2x_cl45_read(bp, port,
+		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_ROM_VER2,
+		      &rom_ver2_val);
+	/* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_ROM_VER2,
+		       (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
+
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_PHY_IDENTIFIER,
+		       (phy_identifier | (1<<9)));
+
+	return 0;
+}
+
+
 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
 {
 	u8 val;
@@ -2619,61 +3055,112 @@ static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
 	return -EINVAL;
 }
 
+static void bnx2x_8727_power_module(struct bnx2x *bp,
+				  struct link_params *params,
+				  u8 ext_phy_addr, u8 is_power_up) {
+	/* Make sure GPIOs are not using for LED mode */
+	u16 val;
+	u8 port = params->port;
+	/*
+	 * In the GPIO register, bit 4 is use to detemine if the GPIOs are
+	 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
+	 * output
+	 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
+	 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
+	 * where the 1st bit is the over-current(only input), and 2nd bit is
+	 * for power( only output )
+	*/
+
+	/*
+	 * In case of NOC feature is disabled and power is up, set GPIO control
+	 *  as input to enable listening of over-current indication
+	 */
+
+	if (!(params->feature_config_flags &
+	      FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
+		val = (1<<4);
+	else
+		/*
+		 * Set GPIO control to OUTPUT, and set the power bit
+		 * to according to the is_power_up
+		 */
+		val = ((!(is_power_up)) << 1);
+
+	bnx2x_cl45_write(bp, port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8727_GPIO_CTRL,
+		       val);
+}
+
 static u8 bnx2x_sfp_module_detection(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
-	u8 module_type;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u16 edc_mode;
+	u8 rc = 0;
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
-
-	if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
-		DP(NETIF_MSG_LINK, "Module detection is not required "
-			    "for this phy\n");
-		return 0;
-	}
+	u32 val = REG_RD(bp, params->shmem_base +
+			     offsetof(struct shmem_region, dev_info.
+				     port_feature_config[params->port].config));
 
 	DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
 		 params->port);
 
-	if (bnx2x_get_sfp_module_type(params,
-				    &module_type) != 0) {
+	if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
 		DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
-		if (!(params->feature_config_flags &
-		      FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
-			/* In case module detection is disabled, it trys to
-			link up. The issue that can happen here is LRM /
-			LIMITING mode which set according to the module-type*/
-			DP(NETIF_MSG_LINK, "Unable to read module-type."
-				    "Probably due to Bit Stretching."
-				    " Proceeding...\n");
-		} else {
-			return -EINVAL;
-		}
-	} else if (bnx2x_verify_sfp_module(params, module_type) !=
+		return -EINVAL;
+	} else if (bnx2x_verify_sfp_module(params) !=
 		   0) {
 		/* check SFP+ module compatibility */
 		DP(NETIF_MSG_LINK, "Module verification failed!!\n");
+		rc = -EINVAL;
 		/* Turn on fault module-detected led */
 		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
 				  MISC_REGISTERS_GPIO_HIGH,
 				  params->port);
-		return -EINVAL;
+		if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
+		    ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
+		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
+			/* Shutdown SFP+ module */
+			DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
+			bnx2x_8727_power_module(bp, params,
+					      ext_phy_addr, 0);
+			return rc;
+		}
+	} else {
+		/* Turn off fault module-detected led */
+		DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
+		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+					  MISC_REGISTERS_GPIO_LOW,
+					  params->port);
 	}
 
-	/* Turn off fault module-detected led */
-	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
-			  MISC_REGISTERS_GPIO_LOW,
-			  params->port);
+	/* power up the SFP module */
+	if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
+		bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
 
-	/* Check and set limiting mode / LRM mode */
-	bnx2x_bcm8726_set_limiting_mode(params, module_type);
+	/* Check and set limiting mode / LRM mode on 8726.
+	On 8727 it is done automatically */
+	if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
+		bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
+	else
+		bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
+	/*
+	 * Enable transmit for this module if the module is approved, or
+	 * if unapproved modules should also enable the Tx laser
+	 */
+	if (rc == 0 ||
+	    (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
+	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
+		bnx2x_sfp_set_transmitter(bp, params->port,
+					ext_phy_type, ext_phy_addr, 1);
+	else
+		bnx2x_sfp_set_transmitter(bp, params->port,
+					ext_phy_type, ext_phy_addr, 0);
 
-	/* Enable transmit for this module */
-	bnx2x_bcm8726_set_transmitter(bp, params->port,
-				    ext_phy_addr, 1);
-	return 0;
+	return rc;
 }
 
 void bnx2x_handle_module_detect_int(struct link_params *params)
@@ -2681,6 +3168,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
 	struct bnx2x *bp = params->bp;
 	u32 gpio_val;
 	u8 port = params->port;
+
 	/* Set valid module led off */
 	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
 			  MISC_REGISTERS_GPIO_HIGH,
@@ -2696,22 +3184,30 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
 				      MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
 				      port);
 
-		if (bnx2x_wait_for_sfp_module_initialized(params)
-		    == 0)
+		if (bnx2x_wait_for_sfp_module_initialized(params) ==
+		    0)
 			bnx2x_sfp_module_detection(params);
 		else
 			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
 	} else {
-		u8 ext_phy_addr = ((params->ext_phy_config &
-				    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+		u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+
+		u32 ext_phy_type =
+			XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+		u32 val = REG_RD(bp, params->shmem_base +
+				     offsetof(struct shmem_region, dev_info.
+					      port_feature_config[params->port].
+					      config));
+
 		bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
 				      MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
 				      port);
 		/* Module was plugged out. */
 		/* Disable transmit for this module */
-		bnx2x_bcm8726_set_transmitter(bp, params->port,
-					    ext_phy_addr, 0);
+		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
+		    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
+			bnx2x_sfp_set_transmitter(bp, params->port,
+						ext_phy_type, ext_phy_addr, 0);
 	}
 }
 
@@ -2719,9 +3215,7 @@ static void bnx2x_bcm807x_force_10G(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 	/* Force KR or KX */
@@ -2742,14 +3236,13 @@ static void bnx2x_bcm807x_force_10G(struct link_params *params)
 		       MDIO_AN_REG_CTRL,
 		       0x0000);
 }
+
 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
 {
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
 	u16 val;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 	bnx2x_cl45_read(bp, params->port,
@@ -2811,12 +3304,9 @@ static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
 				  struct link_vars *vars)
 {
-
 	struct bnx2x *bp = params->bp;
 	u16 cl37_val;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 	bnx2x_cl45_read(bp, params->port,
@@ -2859,9 +3349,7 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params,
 {
 	struct bnx2x *bp = params->bp;
 	u16 val;
-	u8 ext_phy_addr = ((params->ext_phy_config &
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 	/* read modify write pause advertizing */
@@ -2918,10 +3406,136 @@ static void bnx2x_set_preemphasis(struct link_params *params)
 	}
 }
 
+
+static void bnx2x_8481_set_led4(struct link_params *params,
+			      u32 ext_phy_type, u8 ext_phy_addr)
+{
+	struct bnx2x *bp = params->bp;
+
+	/* PHYC_CTL_LED_CTL */
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
+
+	/* Unmask LED4 for 10G link */
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
+	/* 'Interrupt Mask' */
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_AN_DEVAD,
+		       0xFFFB, 0xFFFD);
+}
+static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
+					 u32 ext_phy_type, u8 ext_phy_addr)
+{
+	struct bnx2x *bp = params->bp;
+
+	/* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
+	/* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_AN_DEVAD,
+		       MDIO_AN_REG_8481_LEGACY_SHADOW,
+		       (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
+}
+
+static void bnx2x_8481_set_10G_led_mode(struct link_params *params,
+				      u32 ext_phy_type, u8 ext_phy_addr)
+{
+	struct bnx2x *bp = params->bp;
+	u16 val1;
+
+	/* LED1 (10G Link) */
+	/* Enable continuse based on source 7(10G-link) */
+	bnx2x_cl45_read(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_LINK_SIGNAL,
+		       &val1);
+	/* Set bit 2 to 0, and bits [1:0] to 10 */
+	val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/
+	val1 |= (1<<1); /* Set bit 1 */
+
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_LINK_SIGNAL,
+		       val1);
+
+	/* Unmask LED1 for 10G link */
+	bnx2x_cl45_read(bp, params->port,
+		      ext_phy_type,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_8481_LED1_MASK,
+		      &val1);
+	/* Set bit 2 to 0, and bits [1:0] to 10 */
+	val1 |= (1<<7);
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_LED1_MASK,
+		       val1);
+
+	/* LED2 (1G/100/10G Link) */
+	/* Mask LED2 for 10G link */
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_LED2_MASK,
+		       0);
+
+	/* LED3 (10G/1G/100/10G Activity) */
+	bnx2x_cl45_read(bp, params->port,
+		      ext_phy_type,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_8481_LINK_SIGNAL,
+		      &val1);
+	/* Enable blink based on source 4(Activity) */
+	val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */
+	val1 |= (1<<6); /* Set only bit 6 */
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_LINK_SIGNAL,
+		       val1);
+
+	bnx2x_cl45_read(bp, params->port,
+		      ext_phy_type,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_8481_LED3_MASK,
+		      &val1);
+	val1 |= (1<<4); /* Unmask LED3 for 10G link */
+	bnx2x_cl45_write(bp, params->port,
+		       ext_phy_type,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_8481_LED3_MASK,
+		       val1);
+}
+
+
 static void bnx2x_init_internal_phy(struct link_params *params,
-				struct link_vars *vars)
+				  struct link_vars *vars,
+				  u8 enable_cl73)
 {
 	struct bnx2x *bp = params->bp;
+
 	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
 		if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
 		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
@@ -2934,7 +3548,7 @@ static void bnx2x_init_internal_phy(struct link_params *params,
 			DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
 
 			/* disable autoneg */
-			bnx2x_set_autoneg(params, vars);
+			bnx2x_set_autoneg(params, vars, 0);
 
 			/* program speed and duplex */
 			bnx2x_program_serdes(params, vars);
@@ -2950,10 +3564,10 @@ static void bnx2x_init_internal_phy(struct link_params *params,
 						       vars->ieee_fc);
 
 			/* enable autoneg */
-			bnx2x_set_autoneg(params, vars);
+			bnx2x_set_autoneg(params, vars, enable_cl73);
 
 			/* enable and restart AN */
-			bnx2x_restart_autoneg(params);
+			bnx2x_restart_autoneg(params, enable_cl73);
 		}
 
 	} else { /* SGMII mode */
@@ -2972,10 +3586,9 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 	u16 ctrl = 0;
 	u16 val = 0;
 	u8 rc = 0;
+
 	if (vars->phy_flags & PHY_XGXS_FLAG) {
-		ext_phy_addr = ((params->ext_phy_config &
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+		ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 
 		ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 		/* Make sure that the soft reset is off (expect for the 8072:
@@ -3160,6 +3773,9 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 			driver is loaded, it reset all registers, including the
 			transmitter */
 			bnx2x_sfp_module_detection(params);
+
+			/* Set Flow control */
+			bnx2x_ext_phy_set_pause(params, vars);
 			if (params->req_line_speed == SPEED_1000) {
 				DP(NETIF_MSG_LINK, "Setting 1G force\n");
 				bnx2x_cl45_write(bp, params->port, ext_phy_type,
@@ -3267,14 +3883,12 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 			bnx2x_8073_set_pause_cl37(params, vars);
 
 			if (ext_phy_type ==
-			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
+			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
 				bnx2x_bcm8072_external_rom_boot(params);
-			} else {
-
+			else
 				/* In case of 8073 with long xaui lines,
 				don't set the 8073 xaui low power*/
 				bnx2x_bcm8073_set_xaui_low_power_mode(params);
-			}
 
 			bnx2x_cl45_read(bp, params->port,
 				      ext_phy_type,
@@ -3339,10 +3953,8 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 				       ext_phy_addr,
 				       MDIO_AN_DEVAD,
 				       MDIO_AN_REG_ADV, val);
-
 			if (ext_phy_type ==
 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
-
 				bnx2x_cl45_read(bp, params->port,
 					      ext_phy_type,
 					      ext_phy_addr,
@@ -3450,6 +4062,187 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 			   ((val & (1<<7)) > 0));
 			break;
 		}
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+		{
+			u16 tmp1;
+			u16 rx_alarm_ctrl_val;
+			u16 lasi_ctrl_val;
+
+			/* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
+
+			u16 mod_abs;
+			rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
+			lasi_ctrl_val = 0x0004;
+
+			DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
+			/* enable LASI */
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_RX_ALARM_CTRL,
+				       rx_alarm_ctrl_val);
+
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_LASI_CTRL,
+				       lasi_ctrl_val);
+
+			/* Initially configure  MOD_ABS to interrupt when
+			module is presence( bit 8) */
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
+			/* Set EDC off by setting OPTXLOS signal input to low
+			(bit 9).
+			When the EDC is off it locks onto a reference clock and
+			avoids becoming 'lost'.*/
+			mod_abs &= ~((1<<8) | (1<<9));
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
+
+			/* Make MOD_ABS give interrupt on change */
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+				      &val);
+			val |= (1<<12);
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+				       val);
+
+			/* Set 8727 GPIOs to input to allow reading from the
+			8727 GPIO0 status which reflect SFP+ module
+			over-current */
+
+			bnx2x_cl45_read(bp, params->port,
+				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+				       &val);
+			val &= 0xff8f; /* Reset bits 4-6 */
+			bnx2x_cl45_write(bp, params->port,
+				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
+				       val);
+
+			bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
+			bnx2x_bcm8073_set_xaui_low_power_mode(params);
+
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_M8051_MSGOUT_REG,
+				      &tmp1);
+
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_RX_ALARM, &tmp1);
+
+			/* Set option 1G speed */
+			if (params->req_line_speed == SPEED_1000) {
+
+				DP(NETIF_MSG_LINK, "Setting 1G force\n");
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_CTRL, 0x40);
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_10G_CTRL2, 0xD);
+				bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_10G_CTRL2, &tmp1);
+				DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
+
+			} else if ((params->req_line_speed ==
+				    SPEED_AUTO_NEG) &&
+				   ((params->speed_cap_mask &
+				     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
+
+				DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_PMA_REG_8727_MISC_CTRL, 0);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_AN_REG_CL37_AN, 0x1300);
+			} else {
+				/* Since the 8727 has only single reset pin,
+				need to set the 10G registers although it is
+				default */
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       MDIO_AN_REG_CTRL, 0x0020);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_AN_DEVAD,
+					       0x7, 0x0100);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_CTRL, 0x2040);
+				bnx2x_cl45_write(bp, params->port, ext_phy_type,
+					       ext_phy_addr, MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_10G_CTRL2, 0x0008);
+			}
+
+			/* Set 2-wire transfer rate to 400Khz since 100Khz
+			is not operational */
+			bnx2x_cl45_write(bp, params->port,
+				       ext_phy_type,
+				       ext_phy_addr,
+				       MDIO_PMA_DEVAD,
+				       MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
+				       0xa101);
+
+			/* Set TX PreEmphasis if needed */
+			if ((params->feature_config_flags &
+			     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
+				DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
+					 "TX_CTRL2 0x%x\n",
+					 params->xgxs_config_tx[0],
+					 params->xgxs_config_tx[1]);
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_8727_TX_CTRL1,
+					       params->xgxs_config_tx[0]);
+
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_8727_TX_CTRL2,
+					       params->xgxs_config_tx[1]);
+			}
+
+			break;
+		}
+
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
 		{
 			u16 fw_ver1, fw_ver2;
@@ -3495,20 +4288,112 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 			bnx2x_save_spirom_version(params->bp, params->port,
 						params->shmem_base,
 						(u32)(fw_ver1<<16 | fw_ver2));
-
 			break;
 		}
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
-			DP(NETIF_MSG_LINK,
-				"Setting the BCM8481 LASI control\n");
+			/* This phy uses the NIG latch mechanism since link
+				indication arrives through its LED4 and not via
+				its LASI signal, so we get steady signal
+				instead of clear on read */
+			bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
+				    1 << NIG_LATCH_BC_ENABLE_MI_INT);
+
+			bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
+			if (params->req_line_speed == SPEED_AUTO_NEG) {
+
+				u16 autoneg_val, an_1000_val, an_10_100_val;
+				/* set 1000 speed advertisement */
+				bnx2x_cl45_read(bp, params->port,
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_8481_1000T_CTRL,
+					      &an_1000_val);
 
-			bnx2x_cl45_write(bp, params->port,
-				       ext_phy_type,
-				       ext_phy_addr,
-				       MDIO_PMA_DEVAD,
-				       MDIO_PMA_REG_LASI_CTRL, 0x1);
+				if (params->speed_cap_mask &
+				    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
+					an_1000_val |= (1<<8);
+					if (params->req_duplex == DUPLEX_FULL)
+						an_1000_val |= (1<<9);
+					DP(NETIF_MSG_LINK, "Advertising 1G\n");
+				} else
+					an_1000_val &= ~((1<<8) | (1<<9));
 
-			/* Restart autoneg */
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_AN_DEVAD,
+					       MDIO_AN_REG_8481_1000T_CTRL,
+					       an_1000_val);
+
+				/* set 100 speed advertisement */
+				bnx2x_cl45_read(bp, params->port,
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_8481_LEGACY_AN_ADV,
+					      &an_10_100_val);
+
+				if (params->speed_cap_mask &
+				 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
+				  PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
+					an_10_100_val |= (1<<7);
+					if (params->req_duplex == DUPLEX_FULL)
+						an_10_100_val |= (1<<8);
+					DP(NETIF_MSG_LINK,
+						"Advertising 100M\n");
+				} else
+					an_10_100_val &= ~((1<<7) | (1<<8));
+
+				/* set 10 speed advertisement */
+				if (params->speed_cap_mask &
+				  (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
+				   PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
+					an_10_100_val |= (1<<5);
+					if (params->req_duplex == DUPLEX_FULL)
+						an_10_100_val |= (1<<6);
+					DP(NETIF_MSG_LINK, "Advertising 10M\n");
+				     }
+				else
+					an_10_100_val &= ~((1<<5) | (1<<6));
+
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_AN_DEVAD,
+					       MDIO_AN_REG_8481_LEGACY_AN_ADV,
+					       an_10_100_val);
+
+				bnx2x_cl45_read(bp, params->port,
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+					      &autoneg_val);
+
+				/* Disable forced speed */
+				autoneg_val &= ~(1<<6|1<<13);
+
+				/* Enable autoneg and restart autoneg
+				for legacy speeds */
+				autoneg_val |= (1<<9|1<<12);
+
+				if (params->req_duplex == DUPLEX_FULL)
+					autoneg_val |= (1<<8);
+				else
+					autoneg_val &= ~(1<<8);
+
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_AN_DEVAD,
+					       MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+					       autoneg_val);
+
+				if (params->speed_cap_mask &
+				    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
+					DP(NETIF_MSG_LINK, "Advertising 10G\n");
+					/* Restart autoneg for 10G*/
 			bnx2x_cl45_read(bp, params->port,
 				      ext_phy_type,
 				      ext_phy_addr,
@@ -3520,12 +4405,81 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 				       ext_phy_addr,
 				       MDIO_AN_DEVAD,
 				       MDIO_AN_REG_CTRL, val);
+				}
+			} else {
+				/* Force speed */
+				u16 autoneg_ctrl, pma_ctrl;
+				bnx2x_cl45_read(bp, params->port,
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_AN_DEVAD,
+					      MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+					      &autoneg_ctrl);
 
-			bnx2x_save_bcm_spirom_ver(bp, params->port,
-						ext_phy_type,
-						ext_phy_addr,
-						params->shmem_base);
+				/* Disable autoneg */
+				autoneg_ctrl &= ~(1<<12);
+
+				/* Set 1000 force */
+				switch (params->req_line_speed) {
+				case SPEED_10000:
+					DP(NETIF_MSG_LINK,
+						"Unable to set 10G force !\n");
+					break;
+				case SPEED_1000:
+					bnx2x_cl45_read(bp, params->port,
+						      ext_phy_type,
+						      ext_phy_addr,
+						      MDIO_PMA_DEVAD,
+						      MDIO_PMA_REG_CTRL,
+						      &pma_ctrl);
+					autoneg_ctrl &= ~(1<<13);
+					autoneg_ctrl |= (1<<6);
+					pma_ctrl &= ~(1<<13);
+					pma_ctrl |= (1<<6);
+					DP(NETIF_MSG_LINK,
+						"Setting 1000M force\n");
+					bnx2x_cl45_write(bp, params->port,
+						       ext_phy_type,
+						       ext_phy_addr,
+						       MDIO_PMA_DEVAD,
+						       MDIO_PMA_REG_CTRL,
+						       pma_ctrl);
+					break;
+				case SPEED_100:
+					autoneg_ctrl |= (1<<13);
+					autoneg_ctrl &= ~(1<<6);
+					DP(NETIF_MSG_LINK,
+						"Setting 100M force\n");
+					break;
+				case SPEED_10:
+					autoneg_ctrl &= ~(1<<13);
+					autoneg_ctrl &= ~(1<<6);
+					DP(NETIF_MSG_LINK,
+						"Setting 10M force\n");
+					break;
+				}
+
+				/* Duplex mode */
+				if (params->req_duplex == DUPLEX_FULL) {
+					autoneg_ctrl |= (1<<8);
+					DP(NETIF_MSG_LINK,
+						"Setting full duplex\n");
+				} else
+					autoneg_ctrl &= ~(1<<8);
+
+				/* Update autoneg ctrl and pma ctrl */
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_AN_DEVAD,
+					       MDIO_AN_REG_8481_LEGACY_MII_CTRL,
+					       autoneg_ctrl);
+			}
 
+			/* Save spirom version */
+			bnx2x_save_8481_spirom_version(bp, params->port,
+						     ext_phy_addr,
+						     params->shmem_base);
 			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
 			DP(NETIF_MSG_LINK,
@@ -3561,9 +4515,101 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
 	return rc;
 }
 
+static void bnx2x_8727_handle_mod_abs(struct link_params *params)
+{
+	struct bnx2x *bp = params->bp;
+	u16 mod_abs, rx_alarm_status;
+	u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+	u32 val = REG_RD(bp, params->shmem_base +
+			     offsetof(struct shmem_region, dev_info.
+				      port_feature_config[params->port].
+				      config));
+	bnx2x_cl45_read(bp, params->port,
+		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		      ext_phy_addr,
+		      MDIO_PMA_DEVAD,
+		      MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
+	if (mod_abs & (1<<8)) {
+
+		/* Module is absent */
+		DP(NETIF_MSG_LINK, "MOD_ABS indication "
+			    "show module is absent\n");
+
+		/* 1. Set mod_abs to detect next module
+		presence event
+		   2. Set EDC off by setting OPTXLOS signal input to low
+			(bit 9).
+			When the EDC is off it locks onto a reference clock and
+			avoids becoming 'lost'.*/
+		mod_abs &= ~((1<<8)|(1<<9));
+		bnx2x_cl45_write(bp, params->port,
+			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+			       ext_phy_addr,
+			       MDIO_PMA_DEVAD,
+			       MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
+
+		/* Clear RX alarm since it stays up as long as
+		the mod_abs wasn't changed */
+		bnx2x_cl45_read(bp, params->port,
+			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+
+	} else {
+		/* Module is present */
+		DP(NETIF_MSG_LINK, "MOD_ABS indication "
+			    "show module is present\n");
+		/* First thing, disable transmitter,
+		and if the module is ok, the
+		module_detection will enable it*/
+
+		/* 1. Set mod_abs to detect next module
+		absent event ( bit 8)
+		   2. Restore the default polarity of the OPRXLOS signal and
+		this signal will then correctly indicate the presence or
+		absence of the Rx signal. (bit 9) */
+		mod_abs |= ((1<<8)|(1<<9));
+		bnx2x_cl45_write(bp, params->port,
+		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+		       ext_phy_addr,
+		       MDIO_PMA_DEVAD,
+		       MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
+
+		/* Clear RX alarm since it stays up as long as
+		the mod_abs wasn't changed. This is need to be done
+		before calling the module detection, otherwise it will clear
+		the link update alarm */
+		bnx2x_cl45_read(bp, params->port,
+			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+			      ext_phy_addr,
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+
+
+		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
+		    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
+			bnx2x_sfp_set_transmitter(bp, params->port,
+					PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+					ext_phy_addr, 0);
+
+		if (bnx2x_wait_for_sfp_module_initialized(params)
+		    == 0)
+			bnx2x_sfp_module_detection(params);
+		else
+			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
+	}
+
+	DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
+		 rx_alarm_status);
+	/* No need to check link status in case of
+	module plugged in/out */
+}
+
 
 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
-				 struct link_vars *vars)
+				 struct link_vars *vars,
+				 u8 is_mi_int)
 {
 	struct bnx2x *bp = params->bp;
 	u32 ext_phy_type;
@@ -3572,11 +4618,9 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
 	u16 rx_sd, pcs_status;
 	u8 ext_phy_link_up = 0;
 	u8 port = params->port;
-	if (vars->phy_flags & PHY_XGXS_FLAG) {
-		ext_phy_addr = ((params->ext_phy_config &
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
 
+	if (vars->phy_flags & PHY_XGXS_FLAG) {
+		ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 		ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 		switch (ext_phy_type) {
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
@@ -3602,8 +4646,19 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
 				      ext_phy_addr,
 				      MDIO_PMA_DEVAD,
 				      MDIO_PMA_REG_RX_SD, &rx_sd);
-			DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
-			ext_phy_link_up = (rx_sd & 0x1);
+
+			bnx2x_cl45_read(bp, params->port, ext_phy_type,
+				      ext_phy_addr,
+				      1,
+				      0xc809, &val1);
+			bnx2x_cl45_read(bp, params->port, ext_phy_type,
+				      ext_phy_addr,
+				      1,
+				      0xc809, &val1);
+
+			DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
+			ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9))
+					   && ((val1 & (1<<8)) == 0));
 			if (ext_phy_link_up)
 				vars->line_speed = SPEED_10000;
 			break;
@@ -3672,19 +4727,172 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
 						break;
 					}
 				}
-
 				if (val2 & (1<<1))
 					vars->line_speed = SPEED_1000;
 				else
 					vars->line_speed = SPEED_10000;
 			}
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+		{
+			u16 link_status = 0;
+			u16 rx_alarm_status;
+			/* Check the LASI */
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
+
+			DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
+				 rx_alarm_status);
+
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_LASI_STATUS, &val1);
+
+			DP(NETIF_MSG_LINK,
+				 "8727 LASI status 0x%x\n",
+				 val1);
+
+			/* Clear MSG-OUT */
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_M8051_MSGOUT_REG,
+				      &val1);
+
+			/*
+			 * If a module is present and there is need to check
+			 * for over current
+			 */
+			if (!(params->feature_config_flags &
+			      FEATURE_CONFIG_BCM8727_NOC) &&
+			    !(rx_alarm_status & (1<<5))) {
+				/* Check over-current using 8727 GPIO0 input*/
+				bnx2x_cl45_read(bp, params->port,
+					      ext_phy_type,
+					      ext_phy_addr,
+					      MDIO_PMA_DEVAD,
+					      MDIO_PMA_REG_8727_GPIO_CTRL,
+					      &val1);
+
+				if ((val1 & (1<<8)) == 0) {
+					DP(NETIF_MSG_LINK, "8727 Power fault"
+						     " has been detected on "
+						     "port %d\n",
+						 params->port);
+					printk(KERN_ERR PFX  "Error:  Power"
+						 " fault on %s Port %d has"
+						 " been detected and the"
+						 " power to that SFP+ module"
+						 " has been removed to prevent"
+						 " failure of the card. Please"
+						 " remove the SFP+ module and"
+						 " restart the system to clear"
+						 " this error.\n"
+			, bp->dev->name, params->port);
+					/*
+					 * Disable all RX_ALARMs except for
+					 * mod_abs
+					 */
+					bnx2x_cl45_write(bp, params->port,
+						     ext_phy_type,
+						     ext_phy_addr,
+						     MDIO_PMA_DEVAD,
+						     MDIO_PMA_REG_RX_ALARM_CTRL,
+						     (1<<5));
+
+					bnx2x_cl45_read(bp, params->port,
+						    ext_phy_type,
+						    ext_phy_addr,
+						    MDIO_PMA_DEVAD,
+						    MDIO_PMA_REG_PHY_IDENTIFIER,
+						    &val1);
+					/* Wait for module_absent_event */
+					val1 |= (1<<8);
+					bnx2x_cl45_write(bp, params->port,
+						    ext_phy_type,
+						    ext_phy_addr,
+						    MDIO_PMA_DEVAD,
+						    MDIO_PMA_REG_PHY_IDENTIFIER,
+						    val1);
+					/* Clear RX alarm */
+					bnx2x_cl45_read(bp, params->port,
+						      ext_phy_type,
+						      ext_phy_addr,
+						      MDIO_PMA_DEVAD,
+						      MDIO_PMA_REG_RX_ALARM,
+						      &rx_alarm_status);
+					break;
+				}
+			} /* Over current check */
+
+			/* When module absent bit is set, check module */
+			if (rx_alarm_status & (1<<5)) {
+				bnx2x_8727_handle_mod_abs(params);
+				/* Enable all mod_abs and link detection bits */
+				bnx2x_cl45_write(bp, params->port,
+					       ext_phy_type,
+					       ext_phy_addr,
+					       MDIO_PMA_DEVAD,
+					       MDIO_PMA_REG_RX_ALARM_CTRL,
+					       ((1<<5) | (1<<2)));
+			}
+
+			/* If transmitter is disabled,
+			ignore false link up indication */
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_PHY_IDENTIFIER,
+				      &val1);
+			if (val1 & (1<<15)) {
+				DP(NETIF_MSG_LINK, "Tx is disabled\n");
+				ext_phy_link_up = 0;
+				break;
+			}
 
+			bnx2x_cl45_read(bp, params->port,
+				      ext_phy_type,
+				      ext_phy_addr,
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
+				      &link_status);
+
+			/* Bits 0..2 --> speed detected,
+			   bits 13..15--> link is down */
+			if ((link_status & (1<<2)) &&
+			    (!(link_status & (1<<15)))) {
+				ext_phy_link_up = 1;
+				vars->line_speed = SPEED_10000;
+			} else if ((link_status & (1<<0)) &&
+				   (!(link_status & (1<<13)))) {
+				ext_phy_link_up = 1;
+				vars->line_speed = SPEED_1000;
+				DP(NETIF_MSG_LINK,
+					 "port %x: External link"
+					 " up in 1G\n", params->port);
+			} else {
+				ext_phy_link_up = 0;
+				DP(NETIF_MSG_LINK,
+					 "port %x: External link"
+					 " is down\n", params->port);
+			}
 			break;
+		}
+
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 		{
 			u16 link_status = 0;
 			u16 an1000_status = 0;
+
 			if (ext_phy_type ==
 			     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
 				bnx2x_cl45_read(bp, params->port,
@@ -3700,7 +4908,6 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
 			DP(NETIF_MSG_LINK,
 				 "870x LASI status 0x%x->0x%x\n",
 				  val1, val2);
-
 			} else {
 				/* In 8073, port1 is directed through emac0 and
 				 * port0 is directed through emac1
@@ -3830,8 +5037,6 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
 						    MDIO_PMA_DEVAD,
 						    MDIO_PMA_REG_CDR_BANDWIDTH,
 						    0x0333);
-
-
 				}
 				bnx2x_cl45_read(bp, params->port,
 					   ext_phy_type,
@@ -3943,51 +5148,79 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
 			}
 			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
-			/* Clear LASI interrupt */
-			bnx2x_cl45_read(bp, params->port,
-				      ext_phy_type,
-				      ext_phy_addr,
-				      MDIO_PMA_DEVAD,
-				      MDIO_PMA_REG_LASI_STATUS, &val1);
-			DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
-				 val1);
-
 			/* Check 10G-BaseT link status */
-			/* Check Global PMD signal ok */
+			/* Check PMD signal ok */
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
-				      ext_phy_addr,
-				      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
-				      &rx_sd);
-			/* Check PCS block lock */
+						      ext_phy_addr,
+						      MDIO_AN_DEVAD,
+						      0xFFFA,
+						      &val1);
 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
 				      ext_phy_addr,
-				      MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
-				      &pcs_status);
-			DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
-				 rx_sd, pcs_status);
-			if (rx_sd & pcs_status & 0x1) {
+				      MDIO_PMA_DEVAD,
+				      MDIO_PMA_REG_8481_PMD_SIGNAL,
+				      &val2);
+			DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
+
+			/* Check link 10G */
+			if (val2 & (1<<11)) {
 				vars->line_speed = SPEED_10000;
 				ext_phy_link_up = 1;
-			} else {
-
-				/* Check 1000-BaseT link status */
-				bnx2x_cl45_read(bp, params->port, ext_phy_type,
-					      ext_phy_addr,
-					      MDIO_AN_DEVAD, 0xFFE1,
-					      &val1);
+				bnx2x_8481_set_10G_led_mode(params,
+							  ext_phy_type,
+							  ext_phy_addr);
+			} else { /* Check Legacy speed link */
+				u16 legacy_status, legacy_speed;
+
+				/* Enable expansion register 0x42
+				(Operation mode status) */
+				bnx2x_cl45_write(bp, params->port,
+					 ext_phy_type,
+					 ext_phy_addr,
+					 MDIO_AN_DEVAD,
+					 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
+					 0xf42);
 
-				bnx2x_cl45_read(bp, params->port, ext_phy_type,
-					      ext_phy_addr,
-					      MDIO_AN_DEVAD, 0xFFE1,
-					      &val2);
-				DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
-					     "0x%x-->0x%x\n", val1, val2);
-				if (val2 & (1<<2)) {
-					vars->line_speed = SPEED_1000;
-					ext_phy_link_up = 1;
+				/* Get legacy speed operation status */
+				bnx2x_cl45_read(bp, params->port,
+					  ext_phy_type,
+					  ext_phy_addr,
+					  MDIO_AN_DEVAD,
+					  MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
+					  &legacy_status);
+
+				DP(NETIF_MSG_LINK, "Legacy speed status"
+					     " = 0x%x\n", legacy_status);
+				ext_phy_link_up = ((legacy_status & (1<<11))
+						   == (1<<11));
+				if (ext_phy_link_up) {
+					legacy_speed = (legacy_status & (3<<9));
+					if (legacy_speed == (0<<9))
+						vars->line_speed = SPEED_10;
+					else if (legacy_speed == (1<<9))
+						vars->line_speed =
+							SPEED_100;
+					else if (legacy_speed == (2<<9))
+						vars->line_speed =
+							SPEED_1000;
+					else /* Should not happen */
+						vars->line_speed = 0;
+
+					if (legacy_status & (1<<8))
+						vars->duplex = DUPLEX_FULL;
+					else
+						vars->duplex = DUPLEX_HALF;
+
+					DP(NETIF_MSG_LINK, "Link is up "
+						     "in %dMbps, is_duplex_full"
+						     "= %d\n",
+						vars->line_speed,
+						(vars->duplex == DUPLEX_FULL));
+					bnx2x_8481_set_legacy_led_mode(params,
+								 ext_phy_type,
+								 ext_phy_addr);
 				}
 			}
-
 			break;
 		default:
 			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
@@ -3995,6 +5228,13 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
 			ext_phy_link_up = 0;
 			break;
 		}
+		/* Set SGMII mode for external phy */
+		if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
+			if (vars->line_speed < SPEED_1000)
+				vars->phy_flags |= PHY_SGMII_FLAG;
+			else
+				vars->phy_flags &= ~PHY_SGMII_FLAG;
+		}
 
 	} else { /* SerDes */
 		ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
@@ -4027,6 +5267,7 @@ static void bnx2x_link_int_enable(struct link_params *params)
 	u32 ext_phy_type;
 	u32 mask;
 	struct bnx2x *bp = params->bp;
+
 	/* setting the status to report on link up
 	   for either XGXS or SerDes */
 
@@ -4058,10 +5299,10 @@ static void bnx2x_link_int_enable(struct link_params *params)
 	bnx2x_bits_en(bp,
 		      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
 		      mask);
-	DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
+
+	DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
 		 (params->switch_cfg == SWITCH_CFG_10G),
 		 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
-
 	DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
 		 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
 		 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
@@ -4071,12 +5312,47 @@ static void bnx2x_link_int_enable(struct link_params *params)
 	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
 }
 
-
+static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
+					u8 is_mi_int)
+{
+	u32 latch_status = 0, is_mi_int_status;
+	/* Disable the MI INT ( external phy int )
+	 * by writing 1 to the status register. Link down indication
+	 * is high-active-signal, so in this case we need to write the
+	 * status to clear the XOR
+	 */
+	/* Read Latched signals */
+	latch_status = REG_RD(bp,
+				  NIG_REG_LATCH_STATUS_0 + port*8);
+	is_mi_int_status = REG_RD(bp,
+				  NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
+	DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
+		     "latch_status = 0x%x\n",
+		 is_mi_int, is_mi_int_status, latch_status);
+	/* Handle only those with latched-signal=up.*/
+	if (latch_status & 1) {
+		/* For all latched-signal=up,Write original_signal to status */
+		if (is_mi_int)
+			bnx2x_bits_en(bp,
+				    NIG_REG_STATUS_INTERRUPT_PORT0
+				    + port*4,
+				    NIG_STATUS_EMAC0_MI_INT);
+		else
+			bnx2x_bits_dis(bp,
+				     NIG_REG_STATUS_INTERRUPT_PORT0
+				     + port*4,
+				     NIG_STATUS_EMAC0_MI_INT);
+		/* For all latched-signal=up : Re-Arm Latch signals */
+		REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
+			   (latch_status & 0xfffe) | (latch_status & 1));
+	}
+}
 /*
  * link management
  */
 static void bnx2x_link_int_ack(struct link_params *params,
-			     struct link_vars *vars, u8 is_10g)
+			     struct link_vars *vars, u8 is_10g,
+			     u8 is_mi_int)
 {
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
@@ -4087,6 +5363,10 @@ static void bnx2x_link_int_ack(struct link_params *params,
 		     (NIG_STATUS_XGXS0_LINK10G |
 		      NIG_STATUS_XGXS0_LINK_STATUS |
 		      NIG_STATUS_SERDES0_LINK_STATUS));
+	if (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
+	    == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) {
+		bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
+	}
 	if (vars->phy_link_up) {
 		if (is_10g) {
 			/* Disable the 10G link interrupt
@@ -4106,7 +5386,8 @@ static void bnx2x_link_int_ack(struct link_params *params,
 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
 
-			DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
+			DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
+				 vars->line_speed);
 			bnx2x_bits_en(bp,
 				      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
 				      ((1 << ser_lane) <<
@@ -4156,66 +5437,13 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
 	return 0;
 }
 
-
-static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
-			   u32 ext_phy_type)
-{
-	u32 cnt = 0;
-	u16 ctrl = 0;
-	/* Enable EMAC0 in to enable MDIO */
-	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
-	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
-	msleep(5);
-
-	/* take ext phy out of reset */
-	bnx2x_set_gpio(bp,
-			  MISC_REGISTERS_GPIO_2,
-			  MISC_REGISTERS_GPIO_HIGH,
-			  port);
-
-	bnx2x_set_gpio(bp,
-			  MISC_REGISTERS_GPIO_1,
-			  MISC_REGISTERS_GPIO_HIGH,
-			  port);
-
-	/* wait for 5ms */
-	msleep(5);
-
-	for (cnt = 0; cnt < 1000; cnt++) {
-		msleep(1);
-		bnx2x_cl45_read(bp, port,
-			      ext_phy_type,
-			      ext_phy_addr,
-			      MDIO_PMA_DEVAD,
-			      MDIO_PMA_REG_CTRL,
-			      &ctrl);
-		if (!(ctrl & (1<<15))) {
-			DP(NETIF_MSG_LINK, "Reset completed\n\n");
-				break;
-		}
-	}
-}
-
-static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
-{
-	/* put sf to reset */
-	bnx2x_set_gpio(bp,
-			  MISC_REGISTERS_GPIO_1,
-			  MISC_REGISTERS_GPIO_LOW,
-			  port);
-	bnx2x_set_gpio(bp,
-			  MISC_REGISTERS_GPIO_2,
-			  MISC_REGISTERS_GPIO_LOW,
-			  port);
-}
-
 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
 			      u8 *version, u16 len)
 {
 	struct bnx2x *bp;
 	u32 ext_phy_type = 0;
 	u32 spirom_ver = 0;
-	u8 status = 0 ;
+	u8 status;
 
 	if (version == NULL || params == NULL)
 		return -EINVAL;
@@ -4225,6 +5453,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
 		   offsetof(struct shmem_region,
 			    port_mb[params->port].ext_phy_fw_version));
 
+	status = 0;
 	/* reset the returned value to zero */
 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 	switch (ext_phy_type) {
@@ -4242,13 +5471,19 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
 		break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+		status = bnx2x_format_ver(spirom_ver, version, len);
+		break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
+		spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
+			(spirom_ver & 0x7F);
 		status = bnx2x_format_ver(spirom_ver, version, len);
 		break;
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+		version[0] = '\0';
 		break;
 
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
@@ -4331,10 +5566,8 @@ static void bnx2x_ext_phy_loopback(struct link_params *params)
 
 	if (params->switch_cfg == SWITCH_CFG_10G) {
 		ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+		ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 		/* CL37 Autoneg Enabled */
-		ext_phy_addr = ((params->ext_phy_config &
-					PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-					PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
 		switch (ext_phy_type) {
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
@@ -4501,6 +5734,7 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
 	u8 rc = 0;
 	u32 tmp;
 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
 	DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
 	DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
 		 speed, hw_led_mode);
@@ -4565,7 +5799,7 @@ u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
 			      &gp_status);
 	/* link is up only if both local phy and external phy are up */
 	if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
-	    bnx2x_ext_phy_is_link_up(params, vars))
+	    bnx2x_ext_phy_is_link_up(params, vars, 1))
 		return 0;
 
 	return -ESRCH;
@@ -4579,6 +5813,7 @@ static u8 bnx2x_link_initialize(struct link_params *params,
 	u8 rc = 0;
 	u8 non_ext_phy;
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
+
 	/* Activate the external PHY */
 	bnx2x_ext_phy_reset(params, vars);
 
@@ -4630,11 +5865,10 @@ static u8 bnx2x_link_initialize(struct link_params *params,
 	if (non_ext_phy ||
 	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
 	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
-	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
 	    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
 		if (params->req_line_speed == SPEED_AUTO_NEG)
 			bnx2x_set_parallel_detection(params, vars->phy_flags);
-		bnx2x_init_internal_phy(params, vars);
+		bnx2x_init_internal_phy(params, vars, non_ext_phy);
 	}
 
 	if (!non_ext_phy)
@@ -4653,11 +5887,11 @@ static u8 bnx2x_link_initialize(struct link_params *params,
 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 {
 	struct bnx2x *bp = params->bp;
-
 	u32 val;
-	DP(NETIF_MSG_LINK, "Phy Initialization started \n");
-	DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
-		  params->req_line_speed, params->req_flow_ctrl);
+
+	DP(NETIF_MSG_LINK, "Phy Initialization started\n");
+	DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
+		 params->req_line_speed, params->req_flow_ctrl);
 	vars->link_status = 0;
 	vars->phy_link_up = 0;
 	vars->link_up = 0;
@@ -4671,7 +5905,6 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 	else
 		vars->phy_flags = PHY_XGXS_FLAG;
 
-
 	/* disable attentions */
 	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
 		       (NIG_MASK_XGXS0_LINK_STATUS |
@@ -4682,6 +5915,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 	bnx2x_emac_init(params, vars);
 
 	if (CHIP_REV_IS_FPGA(bp)) {
+
 		vars->link_up = 1;
 		vars->line_speed = SPEED_10000;
 		vars->duplex = DUPLEX_FULL;
@@ -4690,7 +5924,8 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 		/* enable on E1.5 FPGA */
 		if (CHIP_IS_E1H(bp)) {
 			vars->flow_ctrl |=
-				(BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
+					(BNX2X_FLOW_CTRL_TX |
+					 BNX2X_FLOW_CTRL_RX);
 			vars->link_status |=
 					(LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
 					 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
@@ -4699,8 +5934,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 		bnx2x_emac_enable(params, vars, 0);
 		bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
 		/* disable drain */
-		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
-				    + params->port*4, 0);
+		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
 
 		/* update shared memory */
 		bnx2x_update_mng(params, vars->link_status);
@@ -4730,6 +5964,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 
 	} else
 	if (params->loopback_mode == LOOPBACK_BMAC) {
+
 		vars->link_up = 1;
 		vars->line_speed = SPEED_10000;
 		vars->duplex = DUPLEX_FULL;
@@ -4744,7 +5979,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 
 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
 		    params->port*4, 0);
+
 	} else if (params->loopback_mode == LOOPBACK_EMAC) {
+
 		vars->link_up = 1;
 		vars->line_speed = SPEED_1000;
 		vars->duplex = DUPLEX_FULL;
@@ -4760,8 +5997,10 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 					      vars->duplex);
 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
 		    params->port*4, 0);
+
 	} else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
-		  (params->loopback_mode == LOOPBACK_EXT_PHY)) {
+		   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
+
 		vars->link_up = 1;
 		vars->line_speed = SPEED_10000;
 		vars->duplex = DUPLEX_FULL;
@@ -4790,10 +6029,14 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 		}
 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
 			    params->port*4, 0);
+
+		bnx2x_set_led(bp, params->port, LED_MODE_OPER,
+			    vars->line_speed, params->hw_led_mode,
+			    params->chip_id);
+
 	} else
 	/* No loopback */
 	{
-
 		bnx2x_phy_deassert(params, vars->phy_flags);
 		switch (params->switch_cfg) {
 		case SWITCH_CFG_1G:
@@ -4801,8 +6044,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 			if ((params->ext_phy_config &
 			     PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
 			     PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
-				vars->phy_flags |=
-					PHY_SGMII_FLAG;
+				vars->phy_flags |= PHY_SGMII_FLAG;
 			}
 
 			val = REG_RD(bp,
@@ -4823,7 +6065,6 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
 		default:
 			DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
 			return -EINVAL;
-			break;
 		}
 		DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
 
@@ -4843,24 +6084,23 @@ static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
 		       MDIO_PMA_DEVAD,
 		       MDIO_PMA_REG_GEN_CTRL, 0x0001);
-
-	/* Disable Transmitter */
-	bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
-
 }
 
 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
 		  u8 reset_ext_phy)
 {
-
 	struct bnx2x *bp = params->bp;
 	u32 ext_phy_config = params->ext_phy_config;
 	u16 hw_led_mode = params->hw_led_mode;
 	u32 chip_id = params->chip_id;
 	u8 port = params->port;
 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
-	/* disable attentions */
+	u32 val = REG_RD(bp, params->shmem_base +
+			     offsetof(struct shmem_region, dev_info.
+				      port_feature_config[params->port].
+				      config));
 
+	/* disable attentions */
 	vars->link_status = 0;
 	bnx2x_update_mng(params, vars->link_status);
 	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
@@ -4893,6 +6133,20 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+		{
+
+			/* Disable Transmitter */
+			u8 ext_phy_addr =
+				XGXS_EXT_PHY_ADDR(params->ext_phy_config);
+			if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
+			    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
+				bnx2x_sfp_set_transmitter(bp, port,
+					PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+					ext_phy_addr, 0);
+			break;
+		}
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 			DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
 				 "low power mode\n",
@@ -4903,9 +6157,8 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
 			break;
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
 		{
-			u8 ext_phy_addr = ((params->ext_phy_config &
-					 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-					 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+			u8 ext_phy_addr =
+				XGXS_EXT_PHY_ADDR(params->ext_phy_config);
 			/* Set soft reset */
 			bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
 			break;
@@ -4943,6 +6196,7 @@ static u8 bnx2x_update_link_down(struct link_params *params,
 {
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
+
 	DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
 	bnx2x_set_led(bp, port, LED_MODE_OFF,
 		    0, params->hw_led_mode,
@@ -4979,6 +6233,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
 	struct bnx2x *bp = params->bp;
 	u8 port = params->port;
 	u8 rc = 0;
+
 	vars->link_status |= LINK_STATUS_LINK_UP;
 	if (link_10g) {
 		bnx2x_bmac_enable(params, vars, 0);
@@ -5032,16 +6287,19 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
 	u8 link_10g;
 	u8 ext_phy_link_up, rc = 0;
 	u32 ext_phy_type;
+	u8 is_mi_int = 0;
 
 	DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
-	 port,
-	(vars->phy_flags & PHY_XGXS_FLAG),
-	 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
+		 port, (vars->phy_flags & PHY_XGXS_FLAG),
+		 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
 
+	is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
+				    port*0x18) > 0);
 	DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
-	REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
-	REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
-	REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
+		 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
+		 is_mi_int,
+		 REG_RD(bp,
+			    NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
 
 	DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
 	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
@@ -5053,7 +6311,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
 
 	/* Check external link change only for non-direct */
-	ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
+	ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
 
 	/* Read gp_status */
 	CL45_RD_OVER_CL22(bp, port, params->phy_addr,
@@ -5061,7 +6319,8 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
 			      MDIO_GP_STATUS_TOP_AN_STATUS1,
 			      &gp_status);
 
-	rc = bnx2x_link_settings_status(params, vars, gp_status);
+	rc = bnx2x_link_settings_status(params, vars, gp_status,
+				      ext_phy_link_up);
 	if (rc != 0)
 		return rc;
 
@@ -5073,7 +6332,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
 		    (vars->line_speed == SPEED_15000) ||
 		    (vars->line_speed == SPEED_16000));
 
-	bnx2x_link_int_ack(params, vars, link_10g);
+	bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
 
 	/* In case external phy link is up, and internal link is down
 	( not initialized yet probably after link initialization, it needs
@@ -5086,7 +6345,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
 	    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
 	    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
 	    (ext_phy_link_up && !vars->phy_link_up))
-		bnx2x_init_internal_phy(params, vars);
+		bnx2x_init_internal_phy(params, vars, 0);
 
 	/* link is up only if both local phy and external phy are up */
 	vars->link_up = (ext_phy_link_up && vars->phy_link_up);
@@ -5119,10 +6378,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 			      NIG_MASK_SERDES0_LINK_STATUS |
 			      NIG_MASK_MI_INT));
 
-		ext_phy_addr[port] =
-			((ext_phy_config &
-			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+		ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
 
 		/* Need to take the phy out of low power mode in order
 			to write to access its registers */
@@ -5217,12 +6473,81 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 
 }
 
+static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
+{
+	u8 ext_phy_addr[PORT_MAX];
+	s8 port, first_port, i;
+	u32 swap_val, swap_override;
+	DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
+	swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
+	swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
+
+	bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
+	msleep(5);
+
+	if (swap_val && swap_override)
+		first_port = PORT_0;
+	else
+		first_port = PORT_1;
+
+	/* PART1 - Reset both phys */
+	for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
+		/* Extract the ext phy address for the port */
+		u32 ext_phy_config = REG_RD(bp, shmem_base +
+					offsetof(struct shmem_region,
+		   dev_info.port_hw_config[port].external_phy_config));
+
+		/* disable attentions */
+		bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+			     (NIG_MASK_XGXS0_LINK_STATUS |
+			      NIG_MASK_XGXS0_LINK10G |
+			      NIG_MASK_SERDES0_LINK_STATUS |
+			      NIG_MASK_MI_INT));
+
+		ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
+
+		/* Reset the phy */
+		bnx2x_cl45_write(bp, port,
+			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+			       ext_phy_addr[port],
+			       MDIO_PMA_DEVAD,
+			       MDIO_PMA_REG_CTRL,
+			       1<<15);
+	}
+
+	/* Add delay of 150ms after reset */
+	msleep(150);
+
+	/* PART2 - Download firmware to both phys */
+	for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
+		u16 fw_ver1;
+
+		bnx2x_bcm8727_external_rom_boot(bp, port,
+					      ext_phy_addr[port], shmem_base);
+
+		bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
+			      ext_phy_addr[port],
+			      MDIO_PMA_DEVAD,
+			      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
+		if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
+			DP(NETIF_MSG_LINK,
+				 "bnx2x_8727_common_init_phy port %x:"
+				 "Download failed. fw version = 0x%x\n",
+				 port, fw_ver1);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 
 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 {
 	u8 ext_phy_addr;
 	u32 val;
 	s8 port;
+
 	/* Use port1 because of the static port-swap */
 	/* Enable the module detection interrupt */
 	val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
@@ -5230,7 +6555,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 		(1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
 	REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
 
-	bnx2x_hw_reset(bp, 1);
+	bnx2x_ext_phy_hw_reset(bp, 1);
 	msleep(5);
 	for (port = 0; port < PORT_MAX; port++) {
 		/* Extract the ext phy address for the port */
@@ -5238,10 +6563,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 					offsetof(struct shmem_region,
 			dev_info.port_hw_config[port].external_phy_config));
 
-		ext_phy_addr =
-			((ext_phy_config &
-			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+		ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
 		DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
 			 ext_phy_addr);
 
@@ -5275,6 +6597,12 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 		rc = bnx2x_8073_common_init_phy(bp, shmem_base);
 		break;
 	}
+
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
+		rc = bnx2x_8727_common_init_phy(bp, shmem_base);
+		break;
+
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
 		/* GPIO1 affects both ports, so there's need to pull
 		it for single port alone */
@@ -5291,9 +6619,7 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
 	return rc;
 }
 
-
-
-static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
+void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
 {
 	u16 val, cnt;
 
@@ -5323,377 +6649,3 @@ static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
 			break;
 	}
 }
-#define RESERVED_SIZE 256
-/* max application is 160K bytes - data at end of RAM */
-#define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
-
-/* Header is 14 bytes */
-#define HEADER_SIZE 14
-#define DATA_OFFSET HEADER_SIZE
-
-#define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
-	bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
-			ext_phy_addr, \
-			MDIO_PCS_DEVAD, \
-			MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
-
-/* Programs an image to DSP's flash via the SPI port*/
-static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
-				     u8 ext_phy_addr,
-				     char data[], u32 size)
-{
-	const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
-	/* Doesn't include last trans!*/
-	const u16 last_trans_size = size%4; /* Num bytes on last trans */
-	u16 trans_cnt, byte_cnt;
-	u32 data_index;
-	u16 tmp;
-	u16 code_started = 0;
-	u16 image_revision1, image_revision2;
-	u16 cnt;
-
-	DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
-	/* Going to flash*/
-	if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
-		/* This very often will be the case, because the image is built
-		with 160Kbytes size whereas the total image size must actually
-		be 160Kbytes-RESERVED_SIZE */
-		DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
-			 "truncated to %d bytes\n", size, MAX_APP_SIZE);
-		size = MAX_APP_SIZE+HEADER_SIZE;
-	}
-	DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
-	DP(NETIF_MSG_LINK, "  	      %c%c\n", data[0x150], data[0x151]);
-	/* Put the DSP in download mode by setting FLASH_CFG[2] to 1
-	   and issuing a reset.*/
-
-	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
-			  MISC_REGISTERS_GPIO_HIGH, port);
-
-	bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
-
-	/* wait 0.5 sec */
-	for (cnt = 0; cnt < 100; cnt++)
-		msleep(5);
-
-	/* Make sure we can access the DSP
-	   And it's in the correct mode (waiting for download) */
-
-	bnx2x_cl45_read(bp, port,
-		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		      ext_phy_addr,
-		      MDIO_PCS_DEVAD,
-		      MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
-
-	if (tmp != 0x000A) {
-		DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
-			 "Expected 0x000A, read 0x%04X\n", tmp);
-		DP(NETIF_MSG_LINK, "Download failed\n");
-		return -EINVAL;
-	}
-
-	/* Mux the SPI interface away from the internal processor */
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_MUX, 1);
-
-	/* Reset the SPI port */
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
-		       (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
-
-	/* Erase the flash */
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
-		       1);
-
-	SPI_START_TRANSFER(bp, port, ext_phy_addr);
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
-
-	bnx2x_cl45_write(bp, port,
-		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		       ext_phy_addr,
-		       MDIO_PCS_DEVAD,
-		       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
-		       1);
-	SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
-	/* Wait 10 seconds, the maximum time for the erase to complete */
-	DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
-	for (cnt = 0; cnt < 1000; cnt++)
-		msleep(10);
-
-	DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
-	data_index = 0;
-	for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			     ext_phy_addr,
-			     MDIO_PCS_DEVAD,
-			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
-			       1);
-		SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
-
-		/* Bits 23-16 of address */
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			       (data_index>>16));
-		/* Bits 15-8 of address */
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			       (data_index>>8));
-
-		/* Bits 7-0 of address */
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			       ((u16)data_index));
-
-		byte_cnt = 0;
-		while (byte_cnt < 4 && data_index < size) {
-			bnx2x_cl45_write(bp, port,
-				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-				       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			       data[data_index++]);
-			byte_cnt++;
-		}
-
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
-			       byte_cnt+4);
-
-		SPI_START_TRANSFER(bp, port, ext_phy_addr);
-		msleep(5); /* Wait 5 ms minimum between transs */
-
-		/* Let the user know something's going on.*/
-		/* a pacifier ever 4K */
-		if ((data_index % 1023) == 0)
-			DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
-	}
-
-	DP(NETIF_MSG_LINK, "\n");
-	/* Transfer the last block if there is data remaining */
-	if (last_trans_size) {
-		bnx2x_cl45_write(bp, port,
-			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			ext_phy_addr,
-			MDIO_PCS_DEVAD,
-			MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
-
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
-			       1);
-
-		SPI_START_TRANSFER(bp, port, ext_phy_addr);
-
-		bnx2x_cl45_write(bp, port,
-			     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			     ext_phy_addr,
-			     MDIO_PCS_DEVAD,
-			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
-
-		/* Bits 23-16 of address */
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			       (data_index>>16));
-		/* Bits 15-8 of address */
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			       (data_index>>8));
-
-		/* Bits 7-0 of address */
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-			       ((u16)data_index));
-
-		byte_cnt = 0;
-		while (byte_cnt < last_trans_size && data_index < size) {
-			/* Bits 7-0 of address */
-			bnx2x_cl45_write(bp, port,
-				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-				ext_phy_addr,
-				MDIO_PCS_DEVAD,
-				MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
-				data[data_index++]);
-			byte_cnt++;
-		}
-
-		bnx2x_cl45_write(bp, port,
-			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-			       ext_phy_addr,
-			       MDIO_PCS_DEVAD,
-			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
-			       byte_cnt+4);
-
-		SPI_START_TRANSFER(bp, port, ext_phy_addr);
-	}
-
-	/* DSP Remove Download Mode */
-	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
-			  MISC_REGISTERS_GPIO_LOW, port);
-
-	bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
-
-	/* wait 0.5 sec to allow it to run */
-	for (cnt = 0; cnt < 100; cnt++)
-		msleep(5);
-
-	bnx2x_hw_reset(bp, port);
-
-	for (cnt = 0; cnt < 100; cnt++)
-		msleep(5);
-
-	/* Check that the code is started. In case the download
-	checksum failed, the code won't be started. */
-	bnx2x_cl45_read(bp, port,
-		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		      ext_phy_addr,
-		      MDIO_PCS_DEVAD,
-		      MDIO_PCS_REG_7101_DSP_ACCESS,
-		      &tmp);
-
-	code_started = (tmp & (1<<4));
-	if (!code_started) {
-		DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
-		return -EINVAL;
-	}
-
-	/* Verify that the file revision is now equal to the image
-	revision within the DSP */
-	bnx2x_cl45_read(bp, port,
-		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		      ext_phy_addr,
-		      MDIO_PMA_DEVAD,
-		      MDIO_PMA_REG_7101_VER1,
-		      &image_revision1);
-
-	bnx2x_cl45_read(bp, port,
-		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
-		      ext_phy_addr,
-		      MDIO_PMA_DEVAD,
-		      MDIO_PMA_REG_7101_VER2,
-		      &image_revision2);
-
-	if (data[0x14e] != (image_revision2&0xFF) ||
-	    data[0x14f] != ((image_revision2&0xFF00)>>8) ||
-	    data[0x150] != (image_revision1&0xFF) ||
-	    data[0x151] != ((image_revision1&0xFF00)>>8)) {
-		DP(NETIF_MSG_LINK, "Download failed.\n");
-		return -EINVAL;
-	}
-	DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
-	return 0;
-}
-
-u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
-		      u8 driver_loaded, char data[], u32 size)
-{
-	u8 rc = 0;
-	u32 ext_phy_type;
-	u8 ext_phy_addr;
-	ext_phy_addr = ((ext_phy_config &
-			PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
-			PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
-
-	ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
-
-	switch (ext_phy_type) {
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
-		DP(NETIF_MSG_LINK,
-			"Flash download not supported for this ext phy\n");
-		rc = -EINVAL;
-		break;
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
-		/* Take ext phy out of reset */
-		if (!driver_loaded)
-			bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
-		rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
-						data, size);
-		if (!driver_loaded)
-			bnx2x_turn_off_sf(bp, port);
-		break;
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
-	default:
-		DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
-		rc = -EINVAL;
-		break;
-	}
-	return rc;
-}
-
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h
index 19a866d..f3e2522 100644
--- a/drivers/net/bnx2x_link.h
+++ b/drivers/net/bnx2x_link.h
@@ -39,7 +39,13 @@
 #define SPEED_15000		15000
 #define SPEED_16000		16000
 
-
+#define SFP_EEPROM_VENDOR_NAME_ADDR		0x14
+#define SFP_EEPROM_VENDOR_NAME_SIZE		16
+#define SFP_EEPROM_VENDOR_OUI_ADDR		0x25
+#define SFP_EEPROM_VENDOR_OUI_SIZE		3
+#define SFP_EEPROM_PART_NO_ADDR 		0x28
+#define SFP_EEPROM_PART_NO_SIZE		16
+#define PWR_FLT_ERR_MSG_LEN			250
 /***********************************************************/
 /*                         Structs                         */
 /***********************************************************/
@@ -75,47 +81,59 @@ struct link_params {
 #define SWITCH_CFG_AUTO_DETECT	PORT_FEATURE_CON_SWITCH_AUTO_DETECT
 
 	u16 hw_led_mode; /* part of the hw_config read from the shmem */
+
+	/* phy_addr populated by the phy_init function */
+	u8 phy_addr;
+	/*u8 reserved1;*/
+
 	u32 lane_config;
 	u32 ext_phy_config;
-#define XGXS_EXT_PHY_TYPE(ext_phy_config)	(ext_phy_config & \
-					PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
-#define SERDES_EXT_PHY_TYPE(ext_phy_config)	(ext_phy_config & \
-					PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
+#define XGXS_EXT_PHY_TYPE(ext_phy_config) \
+		((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
+#define XGXS_EXT_PHY_ADDR(ext_phy_config) \
+		(((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \
+		 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT)
+#define SERDES_EXT_PHY_TYPE(ext_phy_config) \
+		((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
+
 	/* Phy register parameter */
 	u32 chip_id;
 
-	/* phy_addr populated by the CLC */
-	u8 phy_addr;
 	u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */
-
 	u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */
+
 	u32 feature_config_flags;
 #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
-#define FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED	(2<<0)
+#define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY	(1<<2)
+#define FEATURE_CONFIG_BCM8727_NOC			(1<<3)
+
 	/* Device pointer passed to all callback functions */
 	struct bnx2x *bp;
 };
 
 /* Output parameters */
 struct link_vars {
+	u8 phy_flags;
+
+	u8 mac_type;
+#define MAC_TYPE_NONE		0
+#define MAC_TYPE_EMAC		1
+#define MAC_TYPE_BMAC		2
+
 	u8 phy_link_up; /* internal phy link indication */
 	u8 link_up;
+
+	u16 line_speed;
 	u16 duplex;
+
 	u16 flow_ctrl;
-	u32 ieee_fc;
-	u8 mac_type;
+	u16 ieee_fc;
 
-#define MAC_TYPE_NONE	0
-#define MAC_TYPE_EMAC	1
-#define MAC_TYPE_BMAC	2
-	u16 line_speed;
 	u32 autoneg;
 #define AUTO_NEG_DISABLED			0x0
 #define AUTO_NEG_ENABLED			0x1
 #define AUTO_NEG_COMPLETE			0x2
-#define AUTO_NEG_PARALLEL_DETECTION_USED 	0x3
-
-	u8 phy_flags;
+#define AUTO_NEG_PARALLEL_DETECTION_USED	0x3
 
 	/* The same definitions as the shmem parameter */
 	u32 link_status;
@@ -167,8 +185,6 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
 
 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
 
-u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
-		      u8 driver_loaded, char data[], u32 size);
 /* bnx2x_handle_module_detect_int should be called upon module detection
    interrupt */
 void bnx2x_handle_module_detect_int(struct link_params *params);
@@ -180,5 +196,12 @@ u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
 /* One-time initialization for external phy after power up */
 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base);
 
+/* Reset the external PHY using GPIO */
+void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port);
+
+void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr);
+
+u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
+			      u8 byte_cnt, u8 *o_buf);
 
 #endif /* BNX2X_LINK_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index c36a5f3..20f0ed9 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -10,7 +10,7 @@
  * Written by: Eliezer Tamir
  * Based on code from Michael Chan's bnx2 driver
  * UDP CSUM errata workaround by Arik Gendelman
- * Slowpath rework by Vladislav Zolotarov
+ * Slowpath and fastpath rework by Vladislav Zolotarov
  * Statistics and Link management by Yitchak Gertner
  *
  */
@@ -56,15 +56,15 @@
 #include "bnx2x_init_ops.h"
 #include "bnx2x_dump.h"
 
-#define DRV_MODULE_VERSION	"1.48.105-1"
-#define DRV_MODULE_RELDATE	"2009/04/22"
+#define DRV_MODULE_VERSION	"1.52.1"
+#define DRV_MODULE_RELDATE	"2009/08/12"
 #define BNX2X_BC_VER		0x040200
 
 #include <linux/firmware.h>
 #include "bnx2x_fw_file_hdr.h"
 /* FW files */
-#define FW_FILE_PREFIX_E1		"bnx2x-e1-"
-#define FW_FILE_PREFIX_E1H		"bnx2x-e1h-"
+#define FW_FILE_PREFIX_E1	"bnx2x-e1-"
+#define FW_FILE_PREFIX_E1H	"bnx2x-e1h-"
 
 /* Time in jiffies before concluding the transmitter is hung */
 #define TX_TIMEOUT		(5*HZ)
@@ -80,7 +80,18 @@ MODULE_VERSION(DRV_MODULE_VERSION);
 
 static int multi_mode = 1;
 module_param(multi_mode, int, 0);
-MODULE_PARM_DESC(multi_mode, " Use per-CPU queues");
+MODULE_PARM_DESC(multi_mode, " Multi queue mode "
+			     "(0 Disable; 1 Enable (default))");
+
+static int num_rx_queues;
+module_param(num_rx_queues, int, 0);
+MODULE_PARM_DESC(num_rx_queues, " Number of Rx queues for multi_mode=1"
+				" (default is half number of CPUs)");
+
+static int num_tx_queues;
+module_param(num_tx_queues, int, 0);
+MODULE_PARM_DESC(num_tx_queues, " Number of Tx queues for multi_mode=1"
+				" (default is half number of CPUs)");
 
 static int disable_tpa;
 module_param(disable_tpa, int, 0);
@@ -90,6 +101,10 @@ static int int_mode;
 module_param(int_mode, int, 0);
 MODULE_PARM_DESC(int_mode, " Force interrupt mode (1 INT#x; 2 MSI)");
 
+static int dropless_fc;
+module_param(dropless_fc, int, 0);
+MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring");
+
 static int poll;
 module_param(poll, int, 0);
 MODULE_PARM_DESC(poll, " Use polling (for debug)");
@@ -123,12 +138,9 @@ static struct {
 
 
 static const struct pci_device_id bnx2x_pci_tbl[] = {
-	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 },
-	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711 },
-	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57711E,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57711E },
+	{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 },
+	{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 },
+	{ PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E },
 	{ 0 }
 };
 
@@ -141,7 +153,7 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
 /* used only at init
  * locking is done by mcp
  */
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
+void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
 {
 	pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
 	pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val);
@@ -188,7 +200,7 @@ static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
 void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 		      u32 len32)
 {
-	struct dmae_command *dmae = &bp->init_dmae;
+	struct dmae_command dmae;
 	u32 *wb_comp = bnx2x_sp(bp, wb_comp);
 	int cnt = 200;
 
@@ -201,43 +213,43 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 		return;
 	}
 
-	mutex_lock(&bp->dmae_mutex);
-
-	memset(dmae, 0, sizeof(struct dmae_command));
+	memset(&dmae, 0, sizeof(struct dmae_command));
 
-	dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
-			DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
-			DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+	dmae.opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+		       DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+		       DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
 #ifdef __BIG_ENDIAN
-			DMAE_CMD_ENDIANITY_B_DW_SWAP |
+		       DMAE_CMD_ENDIANITY_B_DW_SWAP |
 #else
-			DMAE_CMD_ENDIANITY_DW_SWAP |
+		       DMAE_CMD_ENDIANITY_DW_SWAP |
 #endif
-			(BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
-			(BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
-	dmae->src_addr_lo = U64_LO(dma_addr);
-	dmae->src_addr_hi = U64_HI(dma_addr);
-	dmae->dst_addr_lo = dst_addr >> 2;
-	dmae->dst_addr_hi = 0;
-	dmae->len = len32;
-	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
-	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
-	dmae->comp_val = DMAE_COMP_VAL;
+		       (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+		       (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+	dmae.src_addr_lo = U64_LO(dma_addr);
+	dmae.src_addr_hi = U64_HI(dma_addr);
+	dmae.dst_addr_lo = dst_addr >> 2;
+	dmae.dst_addr_hi = 0;
+	dmae.len = len32;
+	dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+	dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+	dmae.comp_val = DMAE_COMP_VAL;
 
 	DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
 	   DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
 		    "dst_addr [%x:%08x (%08x)]\n"
 	   DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
-	   dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
-	   dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
-	   dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+	   dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo,
+	   dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, dst_addr,
+	   dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val);
 	DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
 	   bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
 	   bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
 
+	mutex_lock(&bp->dmae_mutex);
+
 	*wb_comp = 0;
 
-	bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+	bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp));
 
 	udelay(5);
 
@@ -261,7 +273,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
 
 void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 {
-	struct dmae_command *dmae = &bp->init_dmae;
+	struct dmae_command dmae;
 	u32 *wb_comp = bnx2x_sp(bp, wb_comp);
 	int cnt = 200;
 
@@ -276,41 +288,41 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 		return;
 	}
 
-	mutex_lock(&bp->dmae_mutex);
+	memset(&dmae, 0, sizeof(struct dmae_command));
 
-	memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
-	memset(dmae, 0, sizeof(struct dmae_command));
-
-	dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
-			DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
-			DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+	dmae.opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+		       DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+		       DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
 #ifdef __BIG_ENDIAN
-			DMAE_CMD_ENDIANITY_B_DW_SWAP |
+		       DMAE_CMD_ENDIANITY_B_DW_SWAP |
 #else
-			DMAE_CMD_ENDIANITY_DW_SWAP |
+		       DMAE_CMD_ENDIANITY_DW_SWAP |
 #endif
-			(BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
-			(BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
-	dmae->src_addr_lo = src_addr >> 2;
-	dmae->src_addr_hi = 0;
-	dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
-	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
-	dmae->len = len32;
-	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
-	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
-	dmae->comp_val = DMAE_COMP_VAL;
+		       (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+		       (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+	dmae.src_addr_lo = src_addr >> 2;
+	dmae.src_addr_hi = 0;
+	dmae.dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
+	dmae.dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
+	dmae.len = len32;
+	dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+	dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+	dmae.comp_val = DMAE_COMP_VAL;
 
 	DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n"
 	   DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
 		    "dst_addr [%x:%08x (%08x)]\n"
 	   DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
-	   dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
-	   dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
-	   dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+	   dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo,
+	   dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, src_addr,
+	   dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val);
+
+	mutex_lock(&bp->dmae_mutex);
 
+	memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
 	*wb_comp = 0;
 
-	bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp));
+	bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp));
 
 	udelay(5);
 
@@ -334,6 +346,21 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
 	mutex_unlock(&bp->dmae_mutex);
 }
 
+void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
+			       u32 addr, u32 len)
+{
+	int offset = 0;
+
+	while (len > DMAE_LEN32_WR_MAX) {
+		bnx2x_write_dmae(bp, phys_addr + offset,
+				 addr + offset, DMAE_LEN32_WR_MAX);
+		offset += DMAE_LEN32_WR_MAX * 4;
+		len -= DMAE_LEN32_WR_MAX;
+	}
+
+	bnx2x_write_dmae(bp, phys_addr + offset, addr + offset, len);
+}
+
 /* used only for slowpath so not inlined */
 static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
 {
@@ -542,16 +569,15 @@ static void bnx2x_panic_dump(struct bnx2x *bp)
 	/* Tx */
 	for_each_tx_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
-		struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
 
 		BNX2X_ERR("fp%d: tx_pkt_prod(%x)  tx_pkt_cons(%x)"
 			  "  tx_bd_prod(%x)  tx_bd_cons(%x)  *tx_cons_sb(%x)\n",
 			  i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
 			  fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb));
 		BNX2X_ERR("      fp_c_idx(%x)  *sb_c_idx(%x)"
-			  "  bd data(%x,%x)\n", le16_to_cpu(fp->fp_c_idx),
+			  "  tx_db_prod(%x)\n", le16_to_cpu(fp->fp_c_idx),
 			  fp->status_blk->c_status_block.status_block_index,
-			  hw_prods->packets_prod, hw_prods->bds_prod);
+			  fp->tx_db.data.prod);
 	}
 
 	/* Rings */
@@ -653,6 +679,11 @@ static void bnx2x_int_enable(struct bnx2x *bp)
 	   val, port, addr, (msix ? "MSI-X" : (msi ? "MSI" : "INTx")));
 
 	REG_WR(bp, addr, val);
+	/*
+	 * Ensure that HC_CONFIG is written before leading/trailing edge config
+	 */
+	mmiowb();
+	barrier();
 
 	if (CHIP_IS_E1H(bp)) {
 		/* init leading/trailing edge */
@@ -667,6 +698,9 @@ static void bnx2x_int_enable(struct bnx2x *bp)
 		REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val);
 		REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val);
 	}
+
+	/* Make sure that interrupts are indeed enabled from here on */
+	mmiowb();
 }
 
 static void bnx2x_int_disable(struct bnx2x *bp)
@@ -689,7 +723,6 @@ static void bnx2x_int_disable(struct bnx2x *bp)
 	REG_WR(bp, addr, val);
 	if (REG_RD(bp, addr) != val)
 		BNX2X_ERR("BUG! proper val not read from IGU!\n");
-
 }
 
 static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
@@ -699,6 +732,8 @@ static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
 
 	/* disable interrupt handling */
 	atomic_inc(&bp->intr_sem);
+	smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */
+
 	if (disable_hw)
 		/* prevent the HW from sending interrupts */
 		bnx2x_int_disable(bp);
@@ -740,6 +775,10 @@ static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
 	DP(BNX2X_MSG_OFF, "write 0x%08x to HC addr 0x%x\n",
 	   (*(u32 *)&igu_ack), hc_addr);
 	REG_WR(bp, hc_addr, (*(u32 *)&igu_ack));
+
+	/* Make sure that ACK is written */
+	mmiowb();
+	barrier();
 }
 
 static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
@@ -776,16 +815,6 @@ static u16 bnx2x_ack_int(struct bnx2x *bp)
  * fast path service functions
  */
 
-static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
-{
-	u16 tx_cons_sb;
-
-	/* Tell compiler that status block fields can change */
-	barrier();
-	tx_cons_sb = le16_to_cpu(*fp->tx_cons_sb);
-	return (fp->tx_pkt_cons != tx_cons_sb);
-}
-
 static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
 {
 	/* Tell compiler that consumer and producer can change */
@@ -800,7 +829,8 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 			     u16 idx)
 {
 	struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx];
-	struct eth_tx_bd *tx_bd;
+	struct eth_tx_start_bd *tx_start_bd;
+	struct eth_tx_bd *tx_data_bd;
 	struct sk_buff *skb = tx_buf->skb;
 	u16 bd_idx = TX_BD(tx_buf->first_bd), new_cons;
 	int nbd;
@@ -810,51 +840,46 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 
 	/* unmap first bd */
 	DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx);
-	tx_bd = &fp->tx_desc_ring[bd_idx];
-	pci_unmap_single(bp->pdev, BD_UNMAP_ADDR(tx_bd),
-			 BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
+	tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd;
+	pci_unmap_single(bp->pdev, BD_UNMAP_ADDR(tx_start_bd),
+			 BD_UNMAP_LEN(tx_start_bd), PCI_DMA_TODEVICE);
 
-	nbd = le16_to_cpu(tx_bd->nbd) - 1;
-	new_cons = nbd + tx_buf->first_bd;
+	nbd = le16_to_cpu(tx_start_bd->nbd) - 1;
 #ifdef BNX2X_STOP_ON_ERROR
-	if (nbd > (MAX_SKB_FRAGS + 2)) {
+	if ((nbd - 1) > (MAX_SKB_FRAGS + 2)) {
 		BNX2X_ERR("BAD nbd!\n");
 		bnx2x_panic();
 	}
 #endif
+	new_cons = nbd + tx_buf->first_bd;
 
-	/* Skip a parse bd and the TSO split header bd
-	   since they have no mapping */
-	if (nbd)
-		bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+	/* Get the next bd */
+	bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
 
-	if (tx_bd->bd_flags.as_bitfield & (ETH_TX_BD_FLAGS_IP_CSUM |
-					   ETH_TX_BD_FLAGS_TCP_CSUM |
-					   ETH_TX_BD_FLAGS_SW_LSO)) {
-		if (--nbd)
-			bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
-		tx_bd = &fp->tx_desc_ring[bd_idx];
-		/* is this a TSO split header bd? */
-		if (tx_bd->bd_flags.as_bitfield & ETH_TX_BD_FLAGS_SW_LSO) {
-			if (--nbd)
-				bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
-		}
+	/* Skip a parse bd... */
+	--nbd;
+	bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+
+	/* ...and the TSO split header bd since they have no mapping */
+	if (tx_buf->flags & BNX2X_TSO_SPLIT_BD) {
+		--nbd;
+		bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
 	}
 
 	/* now free frags */
 	while (nbd > 0) {
 
 		DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx);
-		tx_bd = &fp->tx_desc_ring[bd_idx];
-		pci_unmap_page(bp->pdev, BD_UNMAP_ADDR(tx_bd),
-			       BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
+		tx_data_bd = &fp->tx_desc_ring[bd_idx].reg_bd;
+		pci_unmap_page(bp->pdev, BD_UNMAP_ADDR(tx_data_bd),
+			       BD_UNMAP_LEN(tx_data_bd), PCI_DMA_TODEVICE);
 		if (--nbd)
 			bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
 	}
 
 	/* release skb */
 	WARN_ON(!skb);
-	dev_kfree_skb(skb);
+	dev_kfree_skb_any(skb);
 	tx_buf->first_bd = 0;
 	tx_buf->skb = NULL;
 
@@ -896,7 +921,7 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
 		return;
 #endif
 
-	txq = netdev_get_tx_queue(bp->dev, fp->index);
+	txq = netdev_get_tx_queue(bp->dev, fp->index - bp->num_rx_queues);
 	hw_cons = le16_to_cpu(*fp->tx_cons_sb);
 	sw_cons = fp->tx_pkt_cons;
 
@@ -926,8 +951,6 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
 	/* TBD need a thresh? */
 	if (unlikely(netif_tx_queue_stopped(txq))) {
 
-		__netif_tx_lock(txq, smp_processor_id());
-
 		/* Need to make the tx_bd_cons update visible to start_xmit()
 		 * before checking for netif_tx_queue_stopped().  Without the
 		 * memory barrier, there is a small possibility that
@@ -940,8 +963,6 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp)
 		    (bp->state == BNX2X_STATE_OPEN) &&
 		    (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
 			netif_tx_wake_queue(txq);
-
-		__netif_tx_unlock(txq);
 	}
 }
 
@@ -1009,6 +1030,7 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
 		break;
 
 	case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT):
+	case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DISABLED):
 		DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n");
 		break;
 
@@ -1491,6 +1513,13 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
 		bd_prod = RX_BD(bd_prod);
 		bd_cons = RX_BD(bd_cons);
 
+		/* Prefetch the page containing the BD descriptor
+		   at producer's index. It will be needed when new skb is
+		   allocated */
+		prefetch((void *)(PAGE_ALIGN((unsigned long)
+					     (&fp->rx_desc_ring[bd_prod])) -
+				  PAGE_SIZE + 1));
+
 		cqe = &fp->rx_comp_ring[comp_ring_cons];
 		cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
 
@@ -1599,7 +1628,8 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
 
 				skb = new_skb;
 
-			} else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) {
+			} else
+			if (likely(bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0)) {
 				pci_unmap_single(bp->pdev,
 					pci_unmap_addr(rx_buf, mapping),
 						 bp->rx_buf_size,
@@ -1629,6 +1659,7 @@ reuse_rx:
 		}
 
 		skb_record_rx_queue(skb, fp->index);
+
 #ifdef BCM_VLAN
 		if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) &&
 		    (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) &
@@ -1674,7 +1705,6 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
 {
 	struct bnx2x_fastpath *fp = fp_cookie;
 	struct bnx2x *bp = fp->bp;
-	int index = fp->index;
 
 	/* Return here if interrupt is disabled */
 	if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
@@ -1683,20 +1713,34 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
 	}
 
 	DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n",
-	   index, fp->sb_id);
+	   fp->index, fp->sb_id);
 	bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0);
 
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
 		return IRQ_HANDLED;
 #endif
+	/* Handle Rx or Tx according to MSI-X vector */
+	if (fp->is_rx_queue) {
+		prefetch(fp->rx_cons_sb);
+		prefetch(&fp->status_blk->u_status_block.status_block_index);
 
-	prefetch(fp->rx_cons_sb);
-	prefetch(fp->tx_cons_sb);
-	prefetch(&fp->status_blk->c_status_block.status_block_index);
-	prefetch(&fp->status_blk->u_status_block.status_block_index);
+		napi_schedule(&bnx2x_fp(bp, fp->index, napi));
 
-	napi_schedule(&bnx2x_fp(bp, index, napi));
+	} else {
+		prefetch(fp->tx_cons_sb);
+		prefetch(&fp->status_blk->c_status_block.status_block_index);
+
+		bnx2x_update_fpsb_idx(fp);
+		rmb();
+		bnx2x_tx_int(fp);
+
+		/* Re-enable interrupts */
+		bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
+			     le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
+		bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
+			     le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -1706,6 +1750,7 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
 	struct bnx2x *bp = netdev_priv(dev_instance);
 	u16 status = bnx2x_ack_int(bp);
 	u16 mask;
+	int i;
 
 	/* Return here if interrupt is shared and it's not for us */
 	if (unlikely(status == 0)) {
@@ -1725,18 +1770,38 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
 		return IRQ_HANDLED;
 #endif
 
-	mask = 0x2 << bp->fp[0].sb_id;
-	if (status & mask) {
-		struct bnx2x_fastpath *fp = &bp->fp[0];
+	for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
 
-		prefetch(fp->rx_cons_sb);
-		prefetch(fp->tx_cons_sb);
-		prefetch(&fp->status_blk->c_status_block.status_block_index);
-		prefetch(&fp->status_blk->u_status_block.status_block_index);
+		mask = 0x2 << fp->sb_id;
+		if (status & mask) {
+			/* Handle Rx or Tx according to SB id */
+			if (fp->is_rx_queue) {
+				prefetch(fp->rx_cons_sb);
+				prefetch(&fp->status_blk->u_status_block.
+							status_block_index);
 
-		napi_schedule(&bnx2x_fp(bp, 0, napi));
+				napi_schedule(&bnx2x_fp(bp, fp->index, napi));
 
-		status &= ~mask;
+			} else {
+				prefetch(fp->tx_cons_sb);
+				prefetch(&fp->status_blk->c_status_block.
+							status_block_index);
+
+				bnx2x_update_fpsb_idx(fp);
+				rmb();
+				bnx2x_tx_int(fp);
+
+				/* Re-enable interrupts */
+				bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID,
+					     le16_to_cpu(fp->fp_u_idx),
+					     IGU_INT_NOP, 1);
+				bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID,
+					     le16_to_cpu(fp->fp_c_idx),
+					     IGU_INT_ENABLE, 1);
+			}
+			status &= ~mask;
+		}
 	}
 
 
@@ -2063,6 +2128,12 @@ static void bnx2x_calc_fc_adv(struct bnx2x *bp)
 
 static void bnx2x_link_report(struct bnx2x *bp)
 {
+	if (bp->state == BNX2X_STATE_DISABLED) {
+		netif_carrier_off(bp->dev);
+		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
+		return;
+	}
+
 	if (bp->link_vars.link_up) {
 		if (bp->state == BNX2X_STATE_OPEN)
 			netif_carrier_on(bp->dev);
@@ -2102,9 +2173,7 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
 		/* Initialize link parameters structure variables */
 		/* It is recommended to turn off RX FC for jumbo frames
 		   for better performance */
-		if (IS_E1HMF(bp))
-			bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
-		else if (bp->dev->mtu > 5000)
+		if (bp->dev->mtu > 5000)
 			bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX;
 		else
 			bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH;
@@ -2199,6 +2268,46 @@ static void bnx2x_init_port_minmax(struct bnx2x *bp)
 	bp->cmng.fair_vars.fairness_timeout = fair_periodic_timeout_usec / 4;
 }
 
+/* Calculates the sum of vn_min_rates.
+   It's needed for further normalizing of the min_rates.
+   Returns:
+     sum of vn_min_rates.
+       or
+     0 - if all the min_rates are 0.
+     In the later case fainess algorithm should be deactivated.
+     If not all min_rates are zero then those that are zeroes will be set to 1.
+ */
+static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
+{
+	int all_zero = 1;
+	int port = BP_PORT(bp);
+	int vn;
+
+	bp->vn_weight_sum = 0;
+	for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+		int func = 2*vn + port;
+		u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+		u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
+				   FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
+
+		/* Skip hidden vns */
+		if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
+			continue;
+
+		/* If min rate is zero - set it to 1 */
+		if (!vn_min_rate)
+			vn_min_rate = DEF_MIN_RATE;
+		else
+			all_zero = 0;
+
+		bp->vn_weight_sum += vn_min_rate;
+	}
+
+	/* ... only if all min rates are zeros - disable fairness */
+	if (all_zero)
+		bp->vn_weight_sum = 0;
+}
+
 static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func)
 {
 	struct rate_shaping_vars_per_vn m_rs_vn;
@@ -2276,7 +2385,7 @@ static void bnx2x_link_attn(struct bnx2x *bp)
 	if (bp->link_vars.link_up) {
 
 		/* dropless flow control */
-		if (CHIP_IS_E1H(bp)) {
+		if (CHIP_IS_E1H(bp) && bp->dropless_fc) {
 			int port = BP_PORT(bp);
 			u32 pause_enabled = 0;
 
@@ -2284,7 +2393,7 @@ static void bnx2x_link_attn(struct bnx2x *bp)
 				pause_enabled = 1;
 
 			REG_WR(bp, BAR_USTRORM_INTMEM +
-			       USTORM_PAUSE_ENABLED_OFFSET(port),
+			       USTORM_ETH_PAUSE_ENABLED_OFFSET(port),
 			       pause_enabled);
 		}
 
@@ -2309,14 +2418,12 @@ static void bnx2x_link_attn(struct bnx2x *bp)
 		int func;
 		int vn;
 
+		/* Set the attention towards other drivers on the same port */
 		for (vn = VN_0; vn < E1HVN_MAX; vn++) {
 			if (vn == BP_E1HVN(bp))
 				continue;
 
 			func = ((vn << 1) | port);
-
-			/* Set the attention towards other drivers
-			   on the same port */
 			REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
 			       (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
 		}
@@ -2342,6 +2449,8 @@ static void bnx2x_link_attn(struct bnx2x *bp)
 
 static void bnx2x__link_status_update(struct bnx2x *bp)
 {
+	int func = BP_FUNC(bp);
+
 	if (bp->state != BNX2X_STATE_OPEN)
 		return;
 
@@ -2352,6 +2461,9 @@ static void bnx2x__link_status_update(struct bnx2x *bp)
 	else
 		bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
+	bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+	bnx2x_calc_vn_weight_sum(bp);
+
 	/* indicate link status */
 	bnx2x_link_report(bp);
 }
@@ -2380,6 +2492,152 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
  * General service functions
  */
 
+/* send the MCP a request, block until there is a reply */
+u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
+{
+	int func = BP_FUNC(bp);
+	u32 seq = ++bp->fw_seq;
+	u32 rc = 0;
+	u32 cnt = 1;
+	u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
+
+	SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
+	DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
+
+	do {
+		/* let the FW do it's magic ... */
+		msleep(delay);
+
+		rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
+
+		/* Give the FW up to 2 second (200*10ms) */
+	} while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 200));
+
+	DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n",
+	   cnt*delay, rc, seq);
+
+	/* is this a reply to our command? */
+	if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK))
+		rc &= FW_MSG_CODE_MASK;
+	else {
+		/* FW BUG! */
+		BNX2X_ERR("FW failed to respond!\n");
+		bnx2x_fw_dump(bp);
+		rc = 0;
+	}
+
+	return rc;
+}
+
+static void bnx2x_set_storm_rx_mode(struct bnx2x *bp);
+static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set);
+static void bnx2x_set_rx_mode(struct net_device *dev);
+
+static void bnx2x_e1h_disable(struct bnx2x *bp)
+{
+	int port = BP_PORT(bp);
+	int i;
+
+	bp->rx_mode = BNX2X_RX_MODE_NONE;
+	bnx2x_set_storm_rx_mode(bp);
+
+	netif_tx_disable(bp->dev);
+	bp->dev->trans_start = jiffies;	/* prevent tx timeout */
+
+	REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
+
+	bnx2x_set_mac_addr_e1h(bp, 0);
+
+	for (i = 0; i < MC_HASH_SIZE; i++)
+		REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
+
+	netif_carrier_off(bp->dev);
+}
+
+static void bnx2x_e1h_enable(struct bnx2x *bp)
+{
+	int port = BP_PORT(bp);
+
+	REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
+
+	bnx2x_set_mac_addr_e1h(bp, 1);
+
+	/* Tx queue should be only reenabled */
+	netif_tx_wake_all_queues(bp->dev);
+
+	/* Initialize the receive filter. */
+	bnx2x_set_rx_mode(bp->dev);
+}
+
+static void bnx2x_update_min_max(struct bnx2x *bp)
+{
+	int port = BP_PORT(bp);
+	int vn, i;
+
+	/* Init rate shaping and fairness contexts */
+	bnx2x_init_port_minmax(bp);
+
+	bnx2x_calc_vn_weight_sum(bp);
+
+	for (vn = VN_0; vn < E1HVN_MAX; vn++)
+		bnx2x_init_vn_minmax(bp, 2*vn + port);
+
+	if (bp->port.pmf) {
+		int func;
+
+		/* Set the attention towards other drivers on the same port */
+		for (vn = VN_0; vn < E1HVN_MAX; vn++) {
+			if (vn == BP_E1HVN(bp))
+				continue;
+
+			func = ((vn << 1) | port);
+			REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 +
+			       (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1);
+		}
+
+		/* Store it to internal memory */
+		for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++)
+			REG_WR(bp, BAR_XSTRORM_INTMEM +
+			       XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4,
+			       ((u32 *)(&bp->cmng))[i]);
+	}
+}
+
+static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
+{
+	int func = BP_FUNC(bp);
+
+	DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event);
+	bp->mf_config = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
+
+	if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
+
+		if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) {
+			DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n");
+			bp->state = BNX2X_STATE_DISABLED;
+
+			bnx2x_e1h_disable(bp);
+		} else {
+			DP(NETIF_MSG_IFUP, "mf_cfg function enabled\n");
+			bp->state = BNX2X_STATE_OPEN;
+
+			bnx2x_e1h_enable(bp);
+		}
+		dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF;
+	}
+	if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) {
+
+		bnx2x_update_min_max(bp);
+		dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION;
+	}
+
+	/* Report results to MCP */
+	if (dcc_event)
+		bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE);
+	else
+		bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK);
+}
+
 /* the slow path queue is odd since completions arrive on the fastpath ring */
 static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
 			 u32 data_hi, u32 data_lo, int common)
@@ -2430,9 +2688,14 @@ static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
 		bp->spq_prod_idx++;
 	}
 
+	/* Make sure that BD data is updated before writing the producer */
+	wmb();
+
 	REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func),
 	       bp->spq_prod_idx);
 
+	mmiowb();
+
 	spin_unlock_bh(&bp->spq_lock);
 	return 0;
 }
@@ -2599,11 +2862,28 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
 	}
 }
 
+static inline void bnx2x_fan_failure(struct bnx2x *bp)
+{
+	int port = BP_PORT(bp);
+
+	/* mark the failure */
+	bp->link_params.ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+	bp->link_params.ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
+	SHMEM_WR(bp, dev_info.port_hw_config[port].external_phy_config,
+		 bp->link_params.ext_phy_config);
+
+	/* log the failure */
+	printk(KERN_ERR PFX "Fan Failure on Network Controller %s has caused"
+	       " the driver to shutdown the card to prevent permanent"
+	       " damage.  Please contact Dell Support for assistance\n",
+	       bp->dev->name);
+}
+
 static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
 {
 	int port = BP_PORT(bp);
 	int reg_offset;
-	u32 val;
+	u32 val, swap_val, swap_override;
 
 	reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
 			     MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
@@ -2616,36 +2896,32 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
 
 		BNX2X_ERR("SPIO5 hw attention\n");
 
+		/* Fan failure attention */
 		switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
-			/* Fan failure attention */
-
+			/* Low power mode is controlled by GPIO 2 */
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+				       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
 			/* The PHY reset is controlled by GPIO 1 */
 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
 				       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
-			/* Low power mode is controlled by GPIO 2 */
-			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
+			break;
+
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+			/* The PHY reset is controlled by GPIO 1 */
+			/* fake the port number to cancel the swap done in
+			   set_gpio() */
+			swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
+			swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
+			port = (swap_val && swap_override) ^ 1;
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
 				       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
-			/* mark the failure */
-			bp->link_params.ext_phy_config &=
-					~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
-			bp->link_params.ext_phy_config |=
-					PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE;
-			SHMEM_WR(bp,
-				 dev_info.port_hw_config[port].
-							external_phy_config,
-				 bp->link_params.ext_phy_config);
-			/* log the failure */
-			printk(KERN_ERR PFX "Fan Failure on Network"
-			       " Controller %s has caused the driver to"
-			       " shutdown the card to prevent permanent"
-			       " damage.  Please contact Dell Support for"
-			       " assistance\n", bp->dev->name);
 			break;
 
 		default:
 			break;
 		}
+		bnx2x_fan_failure(bp);
 	}
 
 	if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 |
@@ -2662,7 +2938,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
 		REG_WR(bp, reg_offset, val);
 
 		BNX2X_ERR("FATAL HW block attention set0 0x%x\n",
-			  (attn & HW_INTERRUT_ASSERT_SET_0));
+			  (u32)(attn & HW_INTERRUT_ASSERT_SET_0));
 		bnx2x_panic();
 	}
 }
@@ -2693,7 +2969,7 @@ static inline void bnx2x_attn_int_deasserted1(struct bnx2x *bp, u32 attn)
 		REG_WR(bp, reg_offset, val);
 
 		BNX2X_ERR("FATAL HW block attention set1 0x%x\n",
-			  (attn & HW_INTERRUT_ASSERT_SET_1));
+			  (u32)(attn & HW_INTERRUT_ASSERT_SET_1));
 		bnx2x_panic();
 	}
 }
@@ -2733,7 +3009,7 @@ static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn)
 		REG_WR(bp, reg_offset, val);
 
 		BNX2X_ERR("FATAL HW block attention set2 0x%x\n",
-			  (attn & HW_INTERRUT_ASSERT_SET_2));
+			  (u32)(attn & HW_INTERRUT_ASSERT_SET_2));
 		bnx2x_panic();
 	}
 }
@@ -2748,9 +3024,12 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
 			int func = BP_FUNC(bp);
 
 			REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0);
+			val = SHMEM_RD(bp, func_mb[func].drv_status);
+			if (val & DRV_STATUS_DCC_EVENT_MASK)
+				bnx2x_dcc_event(bp,
+					    (val & DRV_STATUS_DCC_EVENT_MASK));
 			bnx2x__link_status_update(bp);
-			if (SHMEM_RD(bp, func_mb[func].drv_status) &
-							DRV_STATUS_PMF)
+			if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF))
 				bnx2x_pmf_update(bp);
 
 		} else if (attn & BNX2X_MC_ASSERT_BITS) {
@@ -3109,53 +3388,6 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
 	}
 }
 
-static void bnx2x_stats_init(struct bnx2x *bp)
-{
-	int port = BP_PORT(bp);
-	int i;
-
-	bp->stats_pending = 0;
-	bp->executer_idx = 0;
-	bp->stats_counter = 0;
-
-	/* port stats */
-	if (!BP_NOMCP(bp))
-		bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
-	else
-		bp->port.port_stx = 0;
-	DP(BNX2X_MSG_STATS, "port_stx 0x%x\n", bp->port.port_stx);
-
-	memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
-	bp->port.old_nig_stats.brb_discard =
-			REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
-	bp->port.old_nig_stats.brb_truncate =
-			REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
-	REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
-		    &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
-	REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
-		    &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
-
-	/* function stats */
-	for_each_queue(bp, i) {
-		struct bnx2x_fastpath *fp = &bp->fp[i];
-
-		memset(&fp->old_tclient, 0,
-		       sizeof(struct tstorm_per_client_stats));
-		memset(&fp->old_uclient, 0,
-		       sizeof(struct ustorm_per_client_stats));
-		memset(&fp->old_xclient, 0,
-		       sizeof(struct xstorm_per_client_stats));
-		memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
-	}
-
-	memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
-	memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
-
-	bp->stats_state = STATS_STATE_DISABLED;
-	if (IS_E1HMF(bp) && bp->port.pmf && bp->port.port_stx)
-		bnx2x_stats_handle(bp, STATS_EVENT_PMF);
-}
-
 static void bnx2x_hw_stats_post(struct bnx2x *bp)
 {
 	struct dmae_command *dmae = &bp->stats_dmae;
@@ -3716,7 +3948,8 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 	struct bnx2x_eth_stats *estats = &bp->eth_stats;
 	int i;
 
-	memset(&(fstats->total_bytes_received_hi), 0,
+	memcpy(&(fstats->total_bytes_received_hi),
+	       &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi),
 	       sizeof(struct host_func_stats) - 2*sizeof(u32));
 	estats->error_bytes_received_hi = 0;
 	estats->error_bytes_received_lo = 0;
@@ -3725,7 +3958,7 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 	estats->no_buff_discard_hi = 0;
 	estats->no_buff_discard_lo = 0;
 
-	for_each_queue(bp, i) {
+	for_each_rx_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 		int cl_id = fp->cl_id;
 		struct tstorm_per_client_stats *tclient =
@@ -3764,11 +3997,24 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 		}
 
 		qstats->total_bytes_received_hi =
-		qstats->valid_bytes_received_hi =
-				le32_to_cpu(tclient->total_rcv_bytes.hi);
+			le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
 		qstats->total_bytes_received_lo =
+			le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
+
+		ADD_64(qstats->total_bytes_received_hi,
+		       le32_to_cpu(tclient->rcv_multicast_bytes.hi),
+		       qstats->total_bytes_received_lo,
+		       le32_to_cpu(tclient->rcv_multicast_bytes.lo));
+
+		ADD_64(qstats->total_bytes_received_hi,
+		       le32_to_cpu(tclient->rcv_unicast_bytes.hi),
+		       qstats->total_bytes_received_lo,
+		       le32_to_cpu(tclient->rcv_unicast_bytes.lo));
+
+		qstats->valid_bytes_received_hi =
+					qstats->total_bytes_received_hi;
 		qstats->valid_bytes_received_lo =
-				le32_to_cpu(tclient->total_rcv_bytes.lo);
+					qstats->total_bytes_received_lo;
 
 		qstats->error_bytes_received_hi =
 				le32_to_cpu(tclient->rcv_error_bytes.hi);
@@ -3801,9 +4047,19 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
 		UPDATE_EXTEND_USTAT(bcast_no_buff_pkts, no_buff_discard);
 
 		qstats->total_bytes_transmitted_hi =
-				le32_to_cpu(xclient->total_sent_bytes.hi);
+				le32_to_cpu(xclient->unicast_bytes_sent.hi);
 		qstats->total_bytes_transmitted_lo =
-				le32_to_cpu(xclient->total_sent_bytes.lo);
+				le32_to_cpu(xclient->unicast_bytes_sent.lo);
+
+		ADD_64(qstats->total_bytes_transmitted_hi,
+		       le32_to_cpu(xclient->multicast_bytes_sent.hi),
+		       qstats->total_bytes_transmitted_lo,
+		       le32_to_cpu(xclient->multicast_bytes_sent.lo));
+
+		ADD_64(qstats->total_bytes_transmitted_hi,
+		       le32_to_cpu(xclient->broadcast_bytes_sent.hi),
+		       qstats->total_bytes_transmitted_lo,
+		       le32_to_cpu(xclient->broadcast_bytes_sent.lo));
 
 		UPDATE_EXTEND_XSTAT(unicast_pkts_sent,
 					total_unicast_packets_transmitted);
@@ -3919,7 +4175,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp)
 	nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi);
 
 	nstats->rx_dropped = estats->mac_discard;
-	for_each_queue(bp, i)
+	for_each_rx_queue(bp, i)
 		nstats->rx_dropped +=
 			le32_to_cpu(bp->fp[i].old_tclient.checksum_discard);
 
@@ -3973,7 +4229,7 @@ static void bnx2x_drv_stats_update(struct bnx2x *bp)
 	estats->rx_err_discard_pkt = 0;
 	estats->rx_skb_alloc_failed = 0;
 	estats->hw_csum_err = 0;
-	for_each_queue(bp, i) {
+	for_each_rx_queue(bp, i) {
 		struct bnx2x_eth_q_stats *qstats = &bp->fp[i].eth_q_stats;
 
 		estats->driver_xoff += qstats->driver_xoff;
@@ -4003,6 +4259,8 @@ static void bnx2x_stats_update(struct bnx2x *bp)
 	bnx2x_drv_stats_update(bp);
 
 	if (bp->msglevel & NETIF_MSG_TIMER) {
+		struct bnx2x_fastpath *fp0_rx = bp->fp;
+		struct bnx2x_fastpath *fp0_tx = &(bp->fp[bp->num_rx_queues]);
 		struct tstorm_per_client_stats *old_tclient =
 							&bp->fp->old_tclient;
 		struct bnx2x_eth_q_stats *qstats = &bp->fp->eth_q_stats;
@@ -4013,13 +4271,13 @@ static void bnx2x_stats_update(struct bnx2x *bp)
 		printk(KERN_DEBUG "%s:\n", bp->dev->name);
 		printk(KERN_DEBUG "  tx avail (%4x)  tx hc idx (%x)"
 				  "  tx pkt (%lx)\n",
-		       bnx2x_tx_avail(bp->fp),
-		       le16_to_cpu(*bp->fp->tx_cons_sb), nstats->tx_packets);
+		       bnx2x_tx_avail(fp0_tx),
+		       le16_to_cpu(*fp0_tx->tx_cons_sb), nstats->tx_packets);
 		printk(KERN_DEBUG "  rx usage (%4x)  rx hc idx (%x)"
 				  "  rx pkt (%lx)\n",
-		       (u16)(le16_to_cpu(*bp->fp->rx_cons_sb) -
-			     bp->fp->rx_comp_cons),
-		       le16_to_cpu(*bp->fp->rx_cons_sb), nstats->rx_packets);
+		       (u16)(le16_to_cpu(*fp0_rx->rx_cons_sb) -
+			     fp0_rx->rx_comp_cons),
+		       le16_to_cpu(*fp0_rx->rx_cons_sb), nstats->rx_packets);
 		printk(KERN_DEBUG "  %s (Xoff events %u)  brb drops %u  "
 				  "brb truncate %u\n",
 		       (netif_queue_stopped(bp->dev) ? "Xoff" : "Xon"),
@@ -4165,11 +4423,181 @@ static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
 	bnx2x_stats_stm[state][event].action(bp);
 	bp->stats_state = bnx2x_stats_stm[state][event].next_state;
 
+	/* Make sure the state has been "changed" */
+	smp_wmb();
+
 	if ((event != STATS_EVENT_UPDATE) || (bp->msglevel & NETIF_MSG_TIMER))
 		DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
 		   state, event, bp->stats_state);
 }
 
+static void bnx2x_port_stats_base_init(struct bnx2x *bp)
+{
+	struct dmae_command *dmae;
+	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+
+	/* sanity */
+	if (!bp->port.pmf || !bp->port.port_stx) {
+		BNX2X_ERR("BUG!\n");
+		return;
+	}
+
+	bp->executer_idx = 0;
+
+	dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+	dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+			DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+			DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+			DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+			DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+			(BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+			(BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+	dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats));
+	dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats));
+	dmae->dst_addr_lo = bp->port.port_stx >> 2;
+	dmae->dst_addr_hi = 0;
+	dmae->len = sizeof(struct host_port_stats) >> 2;
+	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
+	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
+	dmae->comp_val = DMAE_COMP_VAL;
+
+	*stats_comp = 0;
+	bnx2x_hw_stats_post(bp);
+	bnx2x_stats_comp(bp);
+}
+
+static void bnx2x_func_stats_base_init(struct bnx2x *bp)
+{
+	int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX;
+	int port = BP_PORT(bp);
+	int func;
+	u32 func_stx;
+
+	/* sanity */
+	if (!bp->port.pmf || !bp->func_stx) {
+		BNX2X_ERR("BUG!\n");
+		return;
+	}
+
+	/* save our func_stx */
+	func_stx = bp->func_stx;
+
+	for (vn = VN_0; vn < vn_max; vn++) {
+		func = 2*vn + port;
+
+		bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
+		bnx2x_func_stats_init(bp);
+		bnx2x_hw_stats_post(bp);
+		bnx2x_stats_comp(bp);
+	}
+
+	/* restore our func_stx */
+	bp->func_stx = func_stx;
+}
+
+static void bnx2x_func_stats_base_update(struct bnx2x *bp)
+{
+	struct dmae_command *dmae = &bp->stats_dmae;
+	u32 *stats_comp = bnx2x_sp(bp, stats_comp);
+
+	/* sanity */
+	if (!bp->func_stx) {
+		BNX2X_ERR("BUG!\n");
+		return;
+	}
+
+	bp->executer_idx = 0;
+	memset(dmae, 0, sizeof(struct dmae_command));
+
+	dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+			DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+			DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+			DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+			DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+			(BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) |
+			(BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT));
+	dmae->src_addr_lo = bp->func_stx >> 2;
+	dmae->src_addr_hi = 0;
+	dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base));
+	dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats_base));
+	dmae->len = sizeof(struct host_func_stats) >> 2;
+	dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, stats_comp));
+	dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, stats_comp));
+	dmae->comp_val = DMAE_COMP_VAL;
+
+	*stats_comp = 0;
+	bnx2x_hw_stats_post(bp);
+	bnx2x_stats_comp(bp);
+}
+
+static void bnx2x_stats_init(struct bnx2x *bp)
+{
+	int port = BP_PORT(bp);
+	int func = BP_FUNC(bp);
+	int i;
+
+	bp->stats_pending = 0;
+	bp->executer_idx = 0;
+	bp->stats_counter = 0;
+
+	/* port and func stats for management */
+	if (!BP_NOMCP(bp)) {
+		bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx);
+		bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
+
+	} else {
+		bp->port.port_stx = 0;
+		bp->func_stx = 0;
+	}
+	DP(BNX2X_MSG_STATS, "port_stx 0x%x  func_stx 0x%x\n",
+	   bp->port.port_stx, bp->func_stx);
+
+	/* port stats */
+	memset(&(bp->port.old_nig_stats), 0, sizeof(struct nig_stats));
+	bp->port.old_nig_stats.brb_discard =
+			REG_RD(bp, NIG_REG_STAT0_BRB_DISCARD + port*0x38);
+	bp->port.old_nig_stats.brb_truncate =
+			REG_RD(bp, NIG_REG_STAT0_BRB_TRUNCATE + port*0x38);
+	REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT0 + port*0x50,
+		    &(bp->port.old_nig_stats.egress_mac_pkt0_lo), 2);
+	REG_RD_DMAE(bp, NIG_REG_STAT0_EGRESS_MAC_PKT1 + port*0x50,
+		    &(bp->port.old_nig_stats.egress_mac_pkt1_lo), 2);
+
+	/* function stats */
+	for_each_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+
+		memset(&fp->old_tclient, 0,
+		       sizeof(struct tstorm_per_client_stats));
+		memset(&fp->old_uclient, 0,
+		       sizeof(struct ustorm_per_client_stats));
+		memset(&fp->old_xclient, 0,
+		       sizeof(struct xstorm_per_client_stats));
+		memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats));
+	}
+
+	memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
+	memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats));
+
+	bp->stats_state = STATS_STATE_DISABLED;
+
+	if (bp->port.pmf) {
+		if (bp->port.port_stx)
+			bnx2x_port_stats_base_init(bp);
+
+		if (bp->func_stx)
+			bnx2x_func_stats_base_init(bp);
+
+	} else if (bp->func_stx)
+		bnx2x_func_stats_base_update(bp);
+}
+
 static void bnx2x_timer(unsigned long data)
 {
 	struct bnx2x *bp = (struct bnx2x *) data;
@@ -4232,12 +4660,13 @@ static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id)
 {
 	int port = BP_PORT(bp);
 
-	bnx2x_init_fill(bp, USTORM_INTMEM_ADDR +
-			USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
-			sizeof(struct ustorm_status_block)/4);
-	bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR +
-			CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), 0,
-			sizeof(struct cstorm_status_block)/4);
+	/* "CSTORM" */
+	bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
+			CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), 0,
+			CSTORM_SB_STATUS_BLOCK_U_SIZE / 4);
+	bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
+			CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), 0,
+			CSTORM_SB_STATUS_BLOCK_C_SIZE / 4);
 }
 
 static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
@@ -4253,17 +4682,17 @@ static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
 					    u_status_block);
 	sb->u_status_block.status_block_id = sb_id;
 
-	REG_WR(bp, BAR_USTRORM_INTMEM +
-	       USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id), U64_LO(section));
-	REG_WR(bp, BAR_USTRORM_INTMEM +
-	       ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
+	REG_WR(bp, BAR_CSTRORM_INTMEM +
+	       CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id), U64_LO(section));
+	REG_WR(bp, BAR_CSTRORM_INTMEM +
+	       ((CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id)) + 4),
 	       U64_HI(section));
-	REG_WR8(bp, BAR_USTRORM_INTMEM + FP_USB_FUNC_OFF +
-		USTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
+	REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_USB_FUNC_OFF +
+		CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), func);
 
 	for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
-		REG_WR16(bp, BAR_USTRORM_INTMEM +
-			 USTORM_SB_HC_DISABLE_OFFSET(port, sb_id, index), 1);
+		REG_WR16(bp, BAR_CSTRORM_INTMEM +
+			 CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, index), 1);
 
 	/* CSTORM */
 	section = ((u64)mapping) + offsetof(struct host_status_block,
@@ -4271,16 +4700,16 @@ static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
 	sb->c_status_block.status_block_id = sb_id;
 
 	REG_WR(bp, BAR_CSTRORM_INTMEM +
-	       CSTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id), U64_LO(section));
+	       CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id), U64_LO(section));
 	REG_WR(bp, BAR_CSTRORM_INTMEM +
-	       ((CSTORM_SB_HOST_SB_ADDR_OFFSET(port, sb_id)) + 4),
+	       ((CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id)) + 4),
 	       U64_HI(section));
 	REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF +
-		CSTORM_SB_HOST_STATUS_BLOCK_OFFSET(port, sb_id), func);
+		CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), func);
 
 	for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++)
 		REG_WR16(bp, BAR_CSTRORM_INTMEM +
-			 CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id, index), 1);
+			 CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, index), 1);
 
 	bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
 }
@@ -4289,16 +4718,16 @@ static void bnx2x_zero_def_sb(struct bnx2x *bp)
 {
 	int func = BP_FUNC(bp);
 
-	bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR +
+	bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY +
 			TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
 			sizeof(struct tstorm_def_status_block)/4);
-	bnx2x_init_fill(bp, USTORM_INTMEM_ADDR +
-			USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
-			sizeof(struct ustorm_def_status_block)/4);
-	bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR +
-			CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
-			sizeof(struct cstorm_def_status_block)/4);
-	bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR +
+	bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
+			CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), 0,
+			sizeof(struct cstorm_def_status_block_u)/4);
+	bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY +
+			CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), 0,
+			sizeof(struct cstorm_def_status_block_c)/4);
+	bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY +
 			XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0,
 			sizeof(struct xstorm_def_status_block)/4);
 }
@@ -4350,17 +4779,17 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
 					    u_def_status_block);
 	def_sb->u_def_status_block.status_block_id = sb_id;
 
-	REG_WR(bp, BAR_USTRORM_INTMEM +
-	       USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
-	REG_WR(bp, BAR_USTRORM_INTMEM +
-	       ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
+	REG_WR(bp, BAR_CSTRORM_INTMEM +
+	       CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func), U64_LO(section));
+	REG_WR(bp, BAR_CSTRORM_INTMEM +
+	       ((CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func)) + 4),
 	       U64_HI(section));
-	REG_WR8(bp, BAR_USTRORM_INTMEM + DEF_USB_FUNC_OFF +
-		USTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
+	REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_USB_FUNC_OFF +
+		CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), func);
 
 	for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++)
-		REG_WR16(bp, BAR_USTRORM_INTMEM +
-			 USTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+		REG_WR16(bp, BAR_CSTRORM_INTMEM +
+			 CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(func, index), 1);
 
 	/* CSTORM */
 	section = ((u64)mapping) + offsetof(struct host_def_status_block,
@@ -4368,16 +4797,16 @@ static void bnx2x_init_def_sb(struct bnx2x *bp,
 	def_sb->c_def_status_block.status_block_id = sb_id;
 
 	REG_WR(bp, BAR_CSTRORM_INTMEM +
-	       CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section));
+	       CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func), U64_LO(section));
 	REG_WR(bp, BAR_CSTRORM_INTMEM +
-	       ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4),
+	       ((CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func)) + 4),
 	       U64_HI(section));
 	REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF +
-		CSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func);
+		CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), func);
 
 	for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++)
 		REG_WR16(bp, BAR_CSTRORM_INTMEM +
-			 CSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1);
+			 CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(func, index), 1);
 
 	/* TSTORM */
 	section = ((u64)mapping) + offsetof(struct host_def_status_block,
@@ -4428,23 +4857,23 @@ static void bnx2x_update_coalesce(struct bnx2x *bp)
 		int sb_id = bp->fp[i].sb_id;
 
 		/* HC_INDEX_U_ETH_RX_CQ_CONS */
-		REG_WR8(bp, BAR_USTRORM_INTMEM +
-			USTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
-						    U_SB_ETH_RX_CQ_INDEX),
+		REG_WR8(bp, BAR_CSTRORM_INTMEM +
+			CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id,
+						      U_SB_ETH_RX_CQ_INDEX),
 			bp->rx_ticks/12);
-		REG_WR16(bp, BAR_USTRORM_INTMEM +
-			 USTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
-						     U_SB_ETH_RX_CQ_INDEX),
+		REG_WR16(bp, BAR_CSTRORM_INTMEM +
+			 CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id,
+						       U_SB_ETH_RX_CQ_INDEX),
 			 (bp->rx_ticks/12) ? 0 : 1);
 
 		/* HC_INDEX_C_ETH_TX_CQ_CONS */
 		REG_WR8(bp, BAR_CSTRORM_INTMEM +
-			CSTORM_SB_HC_TIMEOUT_OFFSET(port, sb_id,
-						    C_SB_ETH_TX_CQ_INDEX),
+			CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id,
+						      C_SB_ETH_TX_CQ_INDEX),
 			bp->tx_ticks/12);
 		REG_WR16(bp, BAR_CSTRORM_INTMEM +
-			 CSTORM_SB_HC_DISABLE_OFFSET(port, sb_id,
-						     C_SB_ETH_TX_CQ_INDEX),
+			 CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id,
+						       C_SB_ETH_TX_CQ_INDEX),
 			 (bp->tx_ticks/12) ? 0 : 1);
 	}
 }
@@ -4517,6 +4946,9 @@ static void bnx2x_init_rx_rings(struct bnx2x *bp)
 		fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
 		fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX;
 
+		/* Mark queue as Rx */
+		fp->is_rx_queue = 1;
+
 		/* "next page" elements initialization */
 		/* SGE ring */
 		for (i = 1; i <= NUM_RX_SGE_PAGES; i++) {
@@ -4626,17 +5058,21 @@ static void bnx2x_init_tx_ring(struct bnx2x *bp)
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
 		for (i = 1; i <= NUM_TX_RINGS; i++) {
-			struct eth_tx_bd *tx_bd =
-				&fp->tx_desc_ring[TX_DESC_CNT * i - 1];
+			struct eth_tx_next_bd *tx_next_bd =
+				&fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd;
 
-			tx_bd->addr_hi =
+			tx_next_bd->addr_hi =
 				cpu_to_le32(U64_HI(fp->tx_desc_mapping +
 					    BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
-			tx_bd->addr_lo =
+			tx_next_bd->addr_lo =
 				cpu_to_le32(U64_LO(fp->tx_desc_mapping +
 					    BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
 		}
 
+		fp->tx_db.data.header.header = DOORBELL_HDR_DB_TYPE;
+		fp->tx_db.data.zero_fill1 = 0;
+		fp->tx_db.data.prod = 0;
+
 		fp->tx_pkt_prod = 0;
 		fp->tx_pkt_cons = 0;
 		fp->tx_bd_prod = 0;
@@ -4644,6 +5080,10 @@ static void bnx2x_init_tx_ring(struct bnx2x *bp)
 		fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
 		fp->tx_pkt = 0;
 	}
+
+	/* clean tx statistics */
+	for_each_rx_queue(bp, i)
+		bnx2x_fp(bp, i, tx_pkt) = 0;
 }
 
 static void bnx2x_init_sp_ring(struct bnx2x *bp)
@@ -4672,16 +5112,15 @@ static void bnx2x_init_context(struct bnx2x *bp)
 {
 	int i;
 
-	for_each_queue(bp, i) {
+	for_each_rx_queue(bp, i) {
 		struct eth_context *context = bnx2x_sp(bp, context[i].eth);
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 		u8 cl_id = fp->cl_id;
-		u8 sb_id = fp->sb_id;
 
 		context->ustorm_st_context.common.sb_index_numbers =
 						BNX2X_RX_SB_INDEX_NUM;
 		context->ustorm_st_context.common.clientId = cl_id;
-		context->ustorm_st_context.common.status_block_id = sb_id;
+		context->ustorm_st_context.common.status_block_id = fp->sb_id;
 		context->ustorm_st_context.common.flags =
 			(USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT |
 			 USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS);
@@ -4697,8 +5136,7 @@ static void bnx2x_init_context(struct bnx2x *bp)
 						U64_LO(fp->rx_desc_mapping);
 		if (!fp->disable_tpa) {
 			context->ustorm_st_context.common.flags |=
-				(USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA |
-				 USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_SGE_RING);
+				USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA;
 			context->ustorm_st_context.common.sge_buff_size =
 				(u16)min((u32)SGE_PAGE_SIZE*PAGES_PER_SGE,
 					 (u32)0xffff);
@@ -4706,6 +5144,13 @@ static void bnx2x_init_context(struct bnx2x *bp)
 						U64_HI(fp->rx_sge_mapping);
 			context->ustorm_st_context.common.sge_page_base_lo =
 						U64_LO(fp->rx_sge_mapping);
+
+			context->ustorm_st_context.common.max_sges_for_packet =
+				SGE_PAGE_ALIGN(bp->dev->mtu) >> SGE_PAGE_SHIFT;
+			context->ustorm_st_context.common.max_sges_for_packet =
+				((context->ustorm_st_context.common.
+				  max_sges_for_packet + PAGES_PER_SGE - 1) &
+				 (~(PAGES_PER_SGE - 1))) >> PAGES_PER_SGE_SHIFT;
 		}
 
 		context->ustorm_ag_context.cdu_usage =
@@ -4713,24 +5158,27 @@ static void bnx2x_init_context(struct bnx2x *bp)
 					       CDU_REGION_NUMBER_UCM_AG,
 					       ETH_CONNECTION_TYPE);
 
+		context->xstorm_ag_context.cdu_reserved =
+			CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+					       CDU_REGION_NUMBER_XCM_AG,
+					       ETH_CONNECTION_TYPE);
+	}
+
+	for_each_tx_queue(bp, i) {
+		struct bnx2x_fastpath *fp = &bp->fp[i];
+		struct eth_context *context =
+			bnx2x_sp(bp, context[i - bp->num_rx_queues].eth);
+
+		context->cstorm_st_context.sb_index_number =
+						C_SB_ETH_TX_CQ_INDEX;
+		context->cstorm_st_context.status_block_id = fp->sb_id;
+
 		context->xstorm_st_context.tx_bd_page_base_hi =
 						U64_HI(fp->tx_desc_mapping);
 		context->xstorm_st_context.tx_bd_page_base_lo =
 						U64_LO(fp->tx_desc_mapping);
-		context->xstorm_st_context.db_data_addr_hi =
-						U64_HI(fp->tx_prods_mapping);
-		context->xstorm_st_context.db_data_addr_lo =
-						U64_LO(fp->tx_prods_mapping);
-		context->xstorm_st_context.statistics_data = (cl_id |
+		context->xstorm_st_context.statistics_data = (fp->cl_id |
 				XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE);
-		context->cstorm_st_context.sb_index_number =
-						C_SB_ETH_TX_CQ_INDEX;
-		context->cstorm_st_context.status_block_id = sb_id;
-
-		context->xstorm_ag_context.cdu_reserved =
-			CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
-					       CDU_REGION_NUMBER_XCM_AG,
-					       ETH_CONNECTION_TYPE);
 	}
 }
 
@@ -4768,18 +5216,6 @@ static void bnx2x_set_client_config(struct bnx2x *bp)
 	}
 #endif
 
-	if (bp->flags & TPA_ENABLE_FLAG) {
-		tstorm_client.max_sges_for_packet =
-			SGE_PAGE_ALIGN(tstorm_client.mtu) >> SGE_PAGE_SHIFT;
-		tstorm_client.max_sges_for_packet =
-			((tstorm_client.max_sges_for_packet +
-			  PAGES_PER_SGE - 1) & (~(PAGES_PER_SGE - 1))) >>
-			PAGES_PER_SGE_SHIFT;
-
-		tstorm_client.config_flags |=
-				TSTORM_ETH_CLIENT_CONFIG_ENABLE_SGE_RING;
-	}
-
 	for_each_queue(bp, i) {
 		tstorm_client.statistics_counter_id = bp->fp[i].cl_id;
 
@@ -4801,7 +5237,14 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
 	int mode = bp->rx_mode;
 	int mask = (1 << BP_L_ID(bp));
 	int func = BP_FUNC(bp);
+	int port = BP_PORT(bp);
 	int i;
+	/* All but management unicast packets should pass to the host as well */
+	u32 llh_mask =
+		NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST |
+		NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST |
+		NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN |
+		NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN;
 
 	DP(NETIF_MSG_IFUP, "rx mode %d  mask 0x%x\n", mode, mask);
 
@@ -4825,6 +5268,8 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
 		tstorm_mac_filter.ucast_accept_all = mask;
 		tstorm_mac_filter.mcast_accept_all = mask;
 		tstorm_mac_filter.bcast_accept_all = mask;
+		/* pass management unicast packets as well */
+		llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST;
 		break;
 
 	default:
@@ -4832,6 +5277,10 @@ static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
 		break;
 	}
 
+	REG_WR(bp,
+	       (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK),
+	       llh_mask);
+
 	for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) {
 		REG_WR(bp, BAR_TSTRORM_INTMEM +
 		       TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4,
@@ -4849,17 +5298,6 @@ static void bnx2x_init_internal_common(struct bnx2x *bp)
 {
 	int i;
 
-	if (bp->flags & TPA_ENABLE_FLAG) {
-		struct tstorm_eth_tpa_exist tpa = {0};
-
-		tpa.tpa_exist = 1;
-
-		REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_TPA_EXIST_OFFSET,
-		       ((u32 *)&tpa)[0]);
-		REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_TPA_EXIST_OFFSET + 4,
-		       ((u32 *)&tpa)[1]);
-	}
-
 	/* Zero this manually as its initialization is
 	   currently missing in the initTool */
 	for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++)
@@ -4871,53 +5309,14 @@ static void bnx2x_init_internal_port(struct bnx2x *bp)
 {
 	int port = BP_PORT(bp);
 
-	REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
-	REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
+	REG_WR(bp,
+	       BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_U_OFFSET(port), BNX2X_BTR);
+	REG_WR(bp,
+	       BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_C_OFFSET(port), BNX2X_BTR);
 	REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
 	REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR);
 }
 
-/* Calculates the sum of vn_min_rates.
-   It's needed for further normalizing of the min_rates.
-   Returns:
-     sum of vn_min_rates.
-       or
-     0 - if all the min_rates are 0.
-     In the later case fainess algorithm should be deactivated.
-     If not all min_rates are zero then those that are zeroes will be set to 1.
- */
-static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp)
-{
-	int all_zero = 1;
-	int port = BP_PORT(bp);
-	int vn;
-
-	bp->vn_weight_sum = 0;
-	for (vn = VN_0; vn < E1HVN_MAX; vn++) {
-		int func = 2*vn + port;
-		u32 vn_cfg =
-			SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
-		u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
-				   FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
-
-		/* Skip hidden vns */
-		if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE)
-			continue;
-
-		/* If min rate is zero - set it to 1 */
-		if (!vn_min_rate)
-			vn_min_rate = DEF_MIN_RATE;
-		else
-			all_zero = 0;
-
-		bp->vn_weight_sum += vn_min_rate;
-	}
-
-	/* ... only if all min rates are zeros - disable fairness */
-	if (all_zero)
-		bp->vn_weight_sum = 0;
-}
-
 static void bnx2x_init_internal_func(struct bnx2x *bp)
 {
 	struct tstorm_eth_function_common_config tstorm_config = {0};
@@ -4932,6 +5331,12 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
 		tstorm_config.config_flags = MULTI_FLAGS(bp);
 		tstorm_config.rss_result_mask = MULTI_MASK;
 	}
+
+	/* Enable TPA if needed */
+	if (bp->flags & TPA_ENABLE_FLAG)
+		tstorm_config.config_flags |=
+			TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA;
+
 	if (IS_E1HMF(bp))
 		tstorm_config.config_flags |=
 				TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM;
@@ -5043,6 +5448,14 @@ static void bnx2x_init_internal_func(struct bnx2x *bp)
 		       USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4,
 		       U64_HI(fp->rx_comp_mapping));
 
+		/* Next page */
+		REG_WR(bp, BAR_USTRORM_INTMEM +
+		       USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id),
+		       U64_LO(fp->rx_comp_mapping + BCM_PAGE_SIZE));
+		REG_WR(bp, BAR_USTRORM_INTMEM +
+		       USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id) + 4,
+		       U64_HI(fp->rx_comp_mapping + BCM_PAGE_SIZE));
+
 		REG_WR16(bp, BAR_USTRORM_INTMEM +
 			 USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id),
 			 max_agg_size);
@@ -5153,6 +5566,9 @@ static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
 		fp->index = i;
 		fp->cl_id = BP_L_ID(bp) + i;
 		fp->sb_id = fp->cl_id;
+		/* Suitable Rx and Tx SBs are served by the same client */
+		if (i >= bp->num_rx_queues)
+			fp->cl_id -= bp->num_rx_queues;
 		DP(NETIF_MSG_IFUP,
 		   "queue[%d]:  bnx2x_init_sb(%p,%p)  cl_id %d  sb %d\n",
 		   i, bp, fp->status_blk, fp->cl_id, fp->sb_id);
@@ -5185,6 +5601,11 @@ static void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
 	mmiowb();
 
 	bnx2x_int_enable(bp);
+
+	/* Check for SPIO5 */
+	bnx2x_attn_int_deasserted0(bp,
+		REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + BP_PORT(bp)*4) &
+				   AEU_INPUTS_ATTN_BITS_SPIO5);
 }
 
 /* end of nic init */
@@ -5510,6 +5931,78 @@ static void bnx2x_reset_common(struct bnx2x *bp)
 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
 }
 
+static void bnx2x_init_pxp(struct bnx2x *bp)
+{
+	u16 devctl;
+	int r_order, w_order;
+
+	pci_read_config_word(bp->pdev,
+			     bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
+	DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
+	w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+	if (bp->mrrs == -1)
+		r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+	else {
+		DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
+		r_order = bp->mrrs;
+	}
+
+	bnx2x_init_pxp_arb(bp, r_order, w_order);
+}
+
+static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
+{
+	u32 val;
+	u8 port;
+	u8 is_required = 0;
+
+	val = SHMEM_RD(bp, dev_info.shared_hw_config.config2) &
+	      SHARED_HW_CFG_FAN_FAILURE_MASK;
+
+	if (val == SHARED_HW_CFG_FAN_FAILURE_ENABLED)
+		is_required = 1;
+
+	/*
+	 * The fan failure mechanism is usually related to the PHY type since
+	 * the power consumption of the board is affected by the PHY. Currently,
+	 * fan is required for most designs with SFX7101, BCM8727 and BCM8481.
+	 */
+	else if (val == SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE)
+		for (port = PORT_0; port < PORT_MAX; port++) {
+			u32 phy_type =
+				SHMEM_RD(bp, dev_info.port_hw_config[port].
+					 external_phy_config) &
+				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+			is_required |=
+				((phy_type ==
+				  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) ||
+				 (phy_type ==
+				  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
+				 (phy_type ==
+				  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481));
+		}
+
+	DP(NETIF_MSG_HW, "fan detection setting: %d\n", is_required);
+
+	if (is_required == 0)
+		return;
+
+	/* Fan failure is indicated by SPIO 5 */
+	bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
+		       MISC_REGISTERS_SPIO_INPUT_HI_Z);
+
+	/* set to active low mode */
+	val = REG_RD(bp, MISC_REG_SPIO_INT);
+	val |= ((1 << MISC_REGISTERS_SPIO_5) <<
+				MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
+	REG_WR(bp, MISC_REG_SPIO_INT, val);
+
+	/* enable interrupt to signal the IGU */
+	val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
+	val |= (1 << MISC_REGISTERS_SPIO_5);
+	REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
+}
+
 static int bnx2x_init_common(struct bnx2x *bp)
 {
 	u32 val, i;
@@ -5626,10 +6119,10 @@ static int bnx2x_init_common(struct bnx2x *bp)
 	bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE);
 	bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE);
 
-	bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
-	bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
-	bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
-	bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
+	bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp));
+	bnx2x_init_fill(bp, USEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp));
+	bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp));
+	bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY, 0, STORM_INTMEM_SIZE(bp));
 
 	bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE);
 	bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE);
@@ -5662,11 +6155,6 @@ static int bnx2x_init_common(struct bnx2x *bp)
 	bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE);
 	val = (4 << 24) + (0 << 12) + 1024;
 	REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
-	if (CHIP_IS_E1(bp)) {
-		/* !!! fix pxp client crdit until excel update */
-		REG_WR(bp, CDU_REG_CDU_DEBUG, 0x264);
-		REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
-	}
 
 	bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE);
 	REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
@@ -5679,19 +6167,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
 	bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE);
 	bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE);
 
-	/* PXPCS COMMON comes here */
 	bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE);
 	/* Reset PCIE errors for debug */
 	REG_WR(bp, 0x2814, 0xffffffff);
 	REG_WR(bp, 0x3820, 0xffffffff);
 
-	/* EMAC0 COMMON comes here */
 	bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE);
-	/* EMAC1 COMMON comes here */
 	bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE);
-	/* DBU COMMON comes here */
 	bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE);
-	/* DBG COMMON comes here */
 	bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE);
 
 	bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
@@ -5736,30 +6219,16 @@ static int bnx2x_init_common(struct bnx2x *bp)
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
 		bp->port.need_hw_lock = 1;
 		break;
 
-	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
-		/* Fan failure is indicated by SPIO 5 */
-		bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5,
-			       MISC_REGISTERS_SPIO_INPUT_HI_Z);
-
-		/* set to active low mode */
-		val = REG_RD(bp, MISC_REG_SPIO_INT);
-		val |= ((1 << MISC_REGISTERS_SPIO_5) <<
-					MISC_REGISTERS_SPIO_INT_OLD_SET_POS);
-		REG_WR(bp, MISC_REG_SPIO_INT, val);
-
-		/* enable interrupt to signal the IGU */
-		val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN);
-		val |= (1 << MISC_REGISTERS_SPIO_5);
-		REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val);
-		break;
-
 	default:
 		break;
 	}
 
+	bnx2x_setup_fan_failure_detection(bp);
+
 	/* clear PXP2 attentions */
 	REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR_0);
 
@@ -5786,10 +6255,12 @@ static int bnx2x_init_port(struct bnx2x *bp)
 
 	REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
 
-	/* Port PXP comes here */
 	bnx2x_init_block(bp, PXP_BLOCK, init_stage);
-	/* Port PXP2 comes here */
 	bnx2x_init_block(bp, PXP2_BLOCK, init_stage);
+
+	bnx2x_init_block(bp, TCM_BLOCK, init_stage);
+	bnx2x_init_block(bp, UCM_BLOCK, init_stage);
+	bnx2x_init_block(bp, CCM_BLOCK, init_stage);
 #ifdef BCM_ISCSI
 	/* Port0  1
 	 * Port1  385 */
@@ -5815,17 +6286,14 @@ static int bnx2x_init_port(struct bnx2x *bp)
 	REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
 	REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
 #endif
-	/* Port CMs come here */
 	bnx2x_init_block(bp, XCM_BLOCK, init_stage);
 
-	/* Port QM comes here */
 #ifdef BCM_ISCSI
 	REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
 	REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
 
 	bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
 #endif
-	/* Port DQ comes here */
 	bnx2x_init_block(bp, DQ_BLOCK, init_stage);
 
 	bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
@@ -5852,15 +6320,11 @@ static int bnx2x_init_port(struct bnx2x *bp)
 	REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high);
 
 
-	/* Port PRS comes here */
 	bnx2x_init_block(bp, PRS_BLOCK, init_stage);
-	/* Port TSDM comes here */
+
 	bnx2x_init_block(bp, TSDM_BLOCK, init_stage);
-	/* Port CSDM comes here */
 	bnx2x_init_block(bp, CSDM_BLOCK, init_stage);
-	/* Port USDM comes here */
 	bnx2x_init_block(bp, USDM_BLOCK, init_stage);
-	/* Port XSDM comes here */
 	bnx2x_init_block(bp, XSDM_BLOCK, init_stage);
 
 	bnx2x_init_block(bp, TSEM_BLOCK, init_stage);
@@ -5868,9 +6332,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
 	bnx2x_init_block(bp, CSEM_BLOCK, init_stage);
 	bnx2x_init_block(bp, XSEM_BLOCK, init_stage);
 
-	/* Port UPB comes here */
 	bnx2x_init_block(bp, UPB_BLOCK, init_stage);
-	/* Port XPB comes here */
 	bnx2x_init_block(bp, XPB_BLOCK, init_stage);
 
 	bnx2x_init_block(bp, PBF_BLOCK, init_stage);
@@ -5900,11 +6362,8 @@ static int bnx2x_init_port(struct bnx2x *bp)
 	REG_WR_DMAE(bp, SRC_REG_LASTFREE0 + func*4, wb_write, 2);
 
 	REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + func*4, 10);
-	/* Port SRCH comes here */
 #endif
-	/* Port CDU comes here */
 	bnx2x_init_block(bp, CDU_BLOCK, init_stage);
-	/* Port CFC comes here */
 	bnx2x_init_block(bp, CFC_BLOCK, init_stage);
 
 	if (CHIP_IS_E1(bp)) {
@@ -5921,15 +6380,10 @@ static int bnx2x_init_port(struct bnx2x *bp)
 	REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4,
 	       (IS_E1HMF(bp) ? 0xF7 : 0x7));
 
-	/* Port PXPCS comes here */
 	bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
-	/* Port EMAC0 comes here */
 	bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
-	/* Port EMAC1 comes here */
 	bnx2x_init_block(bp, EMAC1_BLOCK, init_stage);
-	/* Port DBU comes here */
 	bnx2x_init_block(bp, DBU_BLOCK, init_stage);
-	/* Port DBG comes here */
 	bnx2x_init_block(bp, DBG_BLOCK, init_stage);
 
 	bnx2x_init_block(bp, NIG_BLOCK, init_stage);
@@ -5941,9 +6395,6 @@ static int bnx2x_init_port(struct bnx2x *bp)
 		REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4,
 		       (IS_E1HMF(bp) ? 0x1 : 0x2));
 
-		/* support pause requests from USDM, TSDM and BRB */
-		REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0 + port*4, 0x7);
-
 		{
 			REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0);
 			REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0);
@@ -5951,9 +6402,7 @@ static int bnx2x_init_port(struct bnx2x *bp)
 		}
 	}
 
-	/* Port MCP comes here */
 	bnx2x_init_block(bp, MCP_BLOCK, init_stage);
-	/* Port DMAE comes here */
 	bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
 
 	switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
@@ -5989,10 +6438,15 @@ static int bnx2x_init_port(struct bnx2x *bp)
 		break;
 
 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
+	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
 		/* add SPIO 5 to group 0 */
-		val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+		{
+		u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
+				       MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+		val = REG_RD(bp, reg_addr);
 		val |= AEU_INPUTS_ATTN_BITS_SPIO5;
-		REG_WR(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, val);
+		REG_WR(bp, reg_addr, val);
+		}
 		break;
 
 	default:
@@ -6057,9 +6511,15 @@ static int bnx2x_init_func(struct bnx2x *bp)
 
 
 	if (CHIP_IS_E1H(bp)) {
-		for (i = 0; i < 9; i++)
-			bnx2x_init_block(bp,
-					 cm_blocks[i], FUNC0_STAGE + func);
+		bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func);
+		bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func);
 
 		REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
 		REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
@@ -6090,7 +6550,9 @@ static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
 
 	bp->dmae_ready = 0;
 	mutex_init(&bp->dmae_mutex);
-	bnx2x_gunzip_init(bp);
+	rc = bnx2x_gunzip_init(bp);
+	if (rc)
+		return rc;
 
 	switch (load_code) {
 	case FW_MSG_CODE_DRV_LOAD_COMMON:
@@ -6124,11 +6586,8 @@ static int bnx2x_init_hw(struct bnx2x *bp, u32 load_code)
 		bp->fw_drv_pulse_wr_seq =
 				(SHMEM_RD(bp, func_mb[func].drv_pulse_mb) &
 				 DRV_PULSE_SEQ_MASK);
-		bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param);
-		DP(BNX2X_MSG_MCP, "drv_pulse 0x%x  func_stx 0x%x\n",
-		   bp->fw_drv_pulse_wr_seq, bp->func_stx);
-	} else
-		bp->func_stx = 0;
+		DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq);
+	}
 
 	/* this needs to be done before gunzip end */
 	bnx2x_zero_def_sb(bp);
@@ -6141,44 +6600,6 @@ init_hw_err:
 	return rc;
 }
 
-/* send the MCP a request, block until there is a reply */
-static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
-{
-	int func = BP_FUNC(bp);
-	u32 seq = ++bp->fw_seq;
-	u32 rc = 0;
-	u32 cnt = 1;
-	u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
-
-	SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
-	DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
-
-	do {
-		/* let the FW do it's magic ... */
-		msleep(delay);
-
-		rc = SHMEM_RD(bp, func_mb[func].fw_mb_header);
-
-		/* Give the FW up to 2 second (200*10ms) */
-	} while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 200));
-
-	DP(BNX2X_MSG_MCP, "[after %d ms] read (%x) seq is (%x) from FW MB\n",
-	   cnt*delay, rc, seq);
-
-	/* is this a reply to our command? */
-	if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
-		rc &= FW_MSG_CODE_MASK;
-
-	} else {
-		/* FW BUG! */
-		BNX2X_ERR("FW failed to respond!\n");
-		bnx2x_fw_dump(bp);
-		rc = 0;
-	}
-
-	return rc;
-}
-
 static void bnx2x_free_mem(struct bnx2x *bp)
 {
 
@@ -6208,8 +6629,7 @@ static void bnx2x_free_mem(struct bnx2x *bp)
 		/* status blocks */
 		BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
 			       bnx2x_fp(bp, i, status_blk_mapping),
-			       sizeof(struct host_status_block) +
-			       sizeof(struct eth_tx_db_data));
+			       sizeof(struct host_status_block));
 	}
 	/* Rx */
 	for_each_rx_queue(bp, i) {
@@ -6238,7 +6658,7 @@ static void bnx2x_free_mem(struct bnx2x *bp)
 		BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
 		BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
 			       bnx2x_fp(bp, i, tx_desc_mapping),
-			       sizeof(struct eth_tx_bd) * NUM_TX_BD);
+			       sizeof(union eth_tx_bd_types) * NUM_TX_BD);
 	}
 	/* end of fastpath */
 
@@ -6289,8 +6709,7 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
 		/* status blocks */
 		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
 				&bnx2x_fp(bp, i, status_blk_mapping),
-				sizeof(struct host_status_block) +
-				sizeof(struct eth_tx_db_data));
+				sizeof(struct host_status_block));
 	}
 	/* Rx */
 	for_each_rx_queue(bp, i) {
@@ -6317,19 +6736,12 @@ static int bnx2x_alloc_mem(struct bnx2x *bp)
 	/* Tx */
 	for_each_tx_queue(bp, i) {
 
-		bnx2x_fp(bp, i, hw_tx_prods) =
-				(void *)(bnx2x_fp(bp, i, status_blk) + 1);
-
-		bnx2x_fp(bp, i, tx_prods_mapping) =
-				bnx2x_fp(bp, i, status_blk_mapping) +
-				sizeof(struct host_status_block);
-
 		/* fastpath tx rings: tx_buf tx_desc */
 		BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
 				sizeof(struct sw_tx_bd) * NUM_TX_BD);
 		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
 				&bnx2x_fp(bp, i, tx_desc_mapping),
-				sizeof(struct eth_tx_bd) * NUM_TX_BD);
+				sizeof(union eth_tx_bd_types) * NUM_TX_BD);
 	}
 	/* end of fastpath */
 
@@ -6506,7 +6918,12 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
 	for_each_queue(bp, i) {
 		struct bnx2x_fastpath *fp = &bp->fp[i];
 
-		sprintf(fp->name, "%s.fp%d", bp->dev->name, i);
+		if (i < bp->num_rx_queues)
+			sprintf(fp->name, "%s-rx-%d", bp->dev->name, i);
+		else
+			sprintf(fp->name, "%s-tx-%d",
+				bp->dev->name, i - bp->num_rx_queues);
+
 		rc = request_irq(bp->msix_table[i + offset].vector,
 				 bnx2x_msix_fp_int, 0, fp->name, fp);
 		if (rc) {
@@ -6519,16 +6936,11 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp)
 	}
 
 	i = BNX2X_NUM_QUEUES(bp);
-	if (is_multi(bp))
-		printk(KERN_INFO PFX
-		       "%s: using MSI-X  IRQs: sp %d  fp %d - %d\n",
-		       bp->dev->name, bp->msix_table[0].vector,
-		       bp->msix_table[offset].vector,
-		       bp->msix_table[offset + i - 1].vector);
-	else
-		printk(KERN_INFO PFX "%s: using MSI-X  IRQs: sp %d  fp %d\n",
-		       bp->dev->name, bp->msix_table[0].vector,
-		       bp->msix_table[offset + i - 1].vector);
+	printk(KERN_INFO PFX "%s: using MSI-X  IRQs: sp %d  fp[%d] %d"
+	       " ... fp[%d] %d\n",
+	       bp->dev->name, bp->msix_table[0].vector,
+	       0, bp->msix_table[offset].vector,
+	       i - 1, bp->msix_table[offset + i - 1].vector);
 
 	return 0;
 }
@@ -6583,7 +6995,12 @@ static void bnx2x_napi_disable(struct bnx2x *bp)
 
 static void bnx2x_netif_start(struct bnx2x *bp)
 {
-	if (atomic_dec_and_test(&bp->intr_sem)) {
+	int intr_sem;
+
+	intr_sem = atomic_dec_and_test(&bp->intr_sem);
+	smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */
+
+	if (intr_sem) {
 		if (netif_running(bp->dev)) {
 			bnx2x_napi_enable(bp);
 			bnx2x_int_enable(bp);
@@ -6631,7 +7048,8 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
 		config->config_table[0].target_table_entry.flags = 0;
 	else
 		CAM_INVALIDATE(config->config_table[0]);
-	config->config_table[0].target_table_entry.client_id = 0;
+	config->config_table[0].target_table_entry.clients_bit_vector =
+						cpu_to_le32(1 << BP_L_ID(bp));
 	config->config_table[0].target_table_entry.vlan_id = 0;
 
 	DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n",
@@ -6650,7 +7068,8 @@ static void bnx2x_set_mac_addr_e1(struct bnx2x *bp, int set)
 				TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
 	else
 		CAM_INVALIDATE(config->config_table[1]);
-	config->config_table[1].target_table_entry.client_id = 0;
+	config->config_table[1].target_table_entry.clients_bit_vector =
+						cpu_to_le32(1 << BP_L_ID(bp));
 	config->config_table[1].target_table_entry.vlan_id = 0;
 
 	bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
@@ -6663,11 +7082,6 @@ static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
 	struct mac_configuration_cmd_e1h *config =
 		(struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config);
 
-	if (set && (bp->state != BNX2X_STATE_OPEN)) {
-		DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
-		return;
-	}
-
 	/* CAM allocation for E1H
 	 * unicasts: by func number
 	 * multicast: 20+FUNC*20, 20 each
@@ -6684,7 +7098,8 @@ static void bnx2x_set_mac_addr_e1h(struct bnx2x *bp, int set)
 					swab16(*(u16 *)&bp->dev->dev_addr[2]);
 	config->config_table[0].lsb_mac_addr =
 					swab16(*(u16 *)&bp->dev->dev_addr[4]);
-	config->config_table[0].client_id = BP_L_ID(bp);
+	config->config_table[0].clients_bit_vector =
+					cpu_to_le32(1 << BP_L_ID(bp));
 	config->config_table[0].vlan_id = 0;
 	config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov);
 	if (set)
@@ -6734,6 +7149,9 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
 		}
 
 		msleep(1);
+
+		if (bp->panic)
+			return -EIO;
 	}
 
 	/* timeout! */
@@ -6781,67 +7199,111 @@ static int bnx2x_setup_multi(struct bnx2x *bp, int index)
 
 static int bnx2x_poll(struct napi_struct *napi, int budget);
 
-static void bnx2x_set_int_mode(struct bnx2x *bp)
+static void bnx2x_set_int_mode_msix(struct bnx2x *bp, int *num_rx_queues_out,
+				    int *num_tx_queues_out)
+{
+	int _num_rx_queues = 0, _num_tx_queues = 0;
+
+	switch (bp->multi_mode) {
+	case ETH_RSS_MODE_DISABLED:
+		_num_rx_queues = 1;
+		_num_tx_queues = 1;
+		break;
+
+	case ETH_RSS_MODE_REGULAR:
+		if (num_rx_queues)
+			_num_rx_queues = min_t(u32, num_rx_queues,
+					       BNX2X_MAX_QUEUES(bp));
+		else
+			_num_rx_queues = min_t(u32, num_online_cpus(),
+					       BNX2X_MAX_QUEUES(bp));
+
+		if (num_tx_queues)
+			_num_tx_queues = min_t(u32, num_tx_queues,
+					       BNX2X_MAX_QUEUES(bp));
+		else
+			_num_tx_queues = min_t(u32, num_online_cpus(),
+					       BNX2X_MAX_QUEUES(bp));
+
+		/* There must be not more Tx queues than Rx queues */
+		if (_num_tx_queues > _num_rx_queues) {
+			BNX2X_ERR("number of tx queues (%d) > "
+				  "number of rx queues (%d)"
+				  "  defaulting to %d\n",
+				  _num_tx_queues, _num_rx_queues,
+				  _num_rx_queues);
+			_num_tx_queues = _num_rx_queues;
+		}
+		break;
+
+
+	default:
+		_num_rx_queues = 1;
+		_num_tx_queues = 1;
+		break;
+	}
+
+	*num_rx_queues_out = _num_rx_queues;
+	*num_tx_queues_out = _num_tx_queues;
+}
+
+static int bnx2x_set_int_mode(struct bnx2x *bp)
 {
-	int num_queues;
+	int rc = 0;
 
 	switch (int_mode) {
 	case INT_MODE_INTx:
 	case INT_MODE_MSI:
-		num_queues = 1;
-		bp->num_rx_queues = num_queues;
-		bp->num_tx_queues = num_queues;
-		DP(NETIF_MSG_IFUP,
-		   "set number of queues to %d\n", num_queues);
+		bp->num_rx_queues = 1;
+		bp->num_tx_queues = 1;
+		DP(NETIF_MSG_IFUP, "set number of queues to 1\n");
 		break;
 
 	case INT_MODE_MSIX:
 	default:
-		if (bp->multi_mode == ETH_RSS_MODE_REGULAR)
-			num_queues = min_t(u32, num_online_cpus(),
-					   BNX2X_MAX_QUEUES(bp));
-		else
-			num_queues = 1;
-		bp->num_rx_queues = num_queues;
-		bp->num_tx_queues = num_queues;
-		DP(NETIF_MSG_IFUP, "set number of rx queues to %d"
-		   "  number of tx queues to %d\n",
+		/* Set interrupt mode according to bp->multi_mode value */
+		bnx2x_set_int_mode_msix(bp, &bp->num_rx_queues,
+					&bp->num_tx_queues);
+
+		DP(NETIF_MSG_IFUP, "set number of queues to: rx %d tx %d\n",
 		   bp->num_rx_queues, bp->num_tx_queues);
+
 		/* if we can't use MSI-X we only need one fp,
 		 * so try to enable MSI-X with the requested number of fp's
 		 * and fallback to MSI or legacy INTx with one fp
 		 */
-		if (bnx2x_enable_msix(bp)) {
+		rc = bnx2x_enable_msix(bp);
+		if (rc) {
 			/* failed to enable MSI-X */
-			num_queues = 1;
-			bp->num_rx_queues = num_queues;
-			bp->num_tx_queues = num_queues;
 			if (bp->multi_mode)
 				BNX2X_ERR("Multi requested but failed to "
-					  "enable MSI-X  set number of "
-					  "queues to %d\n", num_queues);
+					  "enable MSI-X (rx %d tx %d), "
+					  "set number of queues to 1\n",
+					  bp->num_rx_queues, bp->num_tx_queues);
+			bp->num_rx_queues = 1;
+			bp->num_tx_queues = 1;
 		}
 		break;
 	}
 	bp->dev->real_num_tx_queues = bp->num_tx_queues;
+	return rc;
 }
 
-static void bnx2x_set_rx_mode(struct net_device *dev);
 
 /* must be called with rtnl_lock */
 static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 {
 	u32 load_code;
-	int i, rc = 0;
+	int i, rc;
+
 #ifdef BNX2X_STOP_ON_ERROR
-	DP(NETIF_MSG_IFUP, "enter  load_mode %d\n", load_mode);
 	if (unlikely(bp->panic))
 		return -EPERM;
 #endif
 
 	bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 
-	bnx2x_set_int_mode(bp);
+	rc = bnx2x_set_int_mode(bp);
 
 	if (bnx2x_alloc_mem(bp))
 		return -ENOMEM;
@@ -6854,17 +7316,6 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 		netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
 			       bnx2x_poll, 128);
 
-#ifdef BNX2X_STOP_ON_ERROR
-	for_each_rx_queue(bp, i) {
-		struct bnx2x_fastpath *fp = &bp->fp[i];
-
-		fp->poll_no_work = 0;
-		fp->poll_calls = 0;
-		fp->poll_max_calls = 0;
-		fp->poll_complete = 0;
-		fp->poll_exit = 0;
-	}
-#endif
 	bnx2x_napi_enable(bp);
 
 	if (bp->flags & USING_MSIX_FLAG) {
@@ -6874,6 +7325,8 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 			goto load_error1;
 		}
 	} else {
+		/* Fall to INTx if failed to enable MSI-X due to lack of
+		   memory (in bnx2x_set_int_mode()) */
 		if ((rc != -ENOMEM) && (int_mode != INT_MODE_INTx))
 			bnx2x_enable_msi(bp);
 		bnx2x_ack_int(bp);
@@ -6942,6 +7395,12 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 	/* Setup NIC internals and enable interrupts */
 	bnx2x_nic_init(bp, load_code);
 
+	if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) &&
+	    (bp->common.shmem2_base))
+		SHMEM2_WR(bp, dcc_support,
+			  (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV |
+			   SHMEM_DCC_SUPPORT_BANDWIDTH_ALLOCATION_TLV));
+
 	/* Send LOAD_DONE command to MCP */
 	if (!BP_NOMCP(bp)) {
 		load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
@@ -6957,7 +7416,12 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 	rc = bnx2x_setup_leading(bp);
 	if (rc) {
 		BNX2X_ERR("Setup leading failed!\n");
+#ifndef BNX2X_STOP_ON_ERROR
 		goto load_error3;
+#else
+		bp->panic = 1;
+		return -EBUSY;
+#endif
 	}
 
 	if (CHIP_IS_E1H(bp))
@@ -6966,17 +7430,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 			bp->state = BNX2X_STATE_DISABLED;
 		}
 
-	if (bp->state == BNX2X_STATE_OPEN)
+	if (bp->state == BNX2X_STATE_OPEN) {
 		for_each_nondefault_queue(bp, i) {
 			rc = bnx2x_setup_multi(bp, i);
 			if (rc)
 				goto load_error3;
 		}
 
-	if (CHIP_IS_E1(bp))
-		bnx2x_set_mac_addr_e1(bp, 1);
-	else
-		bnx2x_set_mac_addr_e1h(bp, 1);
+		if (CHIP_IS_E1(bp))
+			bnx2x_set_mac_addr_e1(bp, 1);
+		else
+			bnx2x_set_mac_addr_e1h(bp, 1);
+	}
 
 	if (bp->port.pmf)
 		bnx2x_initial_phy_init(bp, load_mode);
@@ -6984,14 +7449,18 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
 	/* Start fast path */
 	switch (load_mode) {
 	case LOAD_NORMAL:
-		/* Tx queue should be only reenabled */
-		netif_tx_wake_all_queues(bp->dev);
+		if (bp->state == BNX2X_STATE_OPEN) {
+			/* Tx queue should be only reenabled */
+			netif_tx_wake_all_queues(bp->dev);
+		}
 		/* Initialize the receive filter. */
 		bnx2x_set_rx_mode(bp->dev);
 		break;
 
 	case LOAD_OPEN:
 		netif_tx_start_all_queues(bp->dev);
+		if (bp->state != BNX2X_STATE_OPEN)
+			netif_tx_disable(bp->dev);
 		/* Initialize the receive filter. */
 		bnx2x_set_rx_mode(bp->dev);
 		break;
@@ -7190,9 +7659,11 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 
 	bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
 
+	/* Set "drop all" */
 	bp->rx_mode = BNX2X_RX_MODE_NONE;
 	bnx2x_set_storm_rx_mode(bp);
 
+	/* Disable HW interrupts, NAPI and Tx */
 	bnx2x_netif_stop(bp, 1);
 
 	del_timer_sync(&bp->timer);
@@ -7256,17 +7727,17 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
 
 		for (i = 0; i < MC_HASH_SIZE; i++)
 			REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
+
+		REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
 	}
 
 	if (unload_mode == UNLOAD_NORMAL)
 		reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
 
-	else if (bp->flags & NO_WOL_FLAG) {
+	else if (bp->flags & NO_WOL_FLAG)
 		reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
-		if (CHIP_IS_E1H(bp))
-			REG_WR(bp, MISC_REG_E1HMF_MODE, 0);
 
-	} else if (bp->wol) {
+	else if (bp->wol) {
 		u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
 		u8 *mac_addr = bp->dev->dev_addr;
 		u32 val;
@@ -7569,8 +8040,10 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
 		       bp->common.flash_size, bp->common.flash_size);
 
 	bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
+	bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0);
 	bp->link_params.shmem_base = bp->common.shmem_base;
-	BNX2X_DEV_INFO("shmem offset is 0x%x\n", bp->common.shmem_base);
+	BNX2X_DEV_INFO("shmem offset 0x%x  shmem2 offset 0x%x\n",
+		       bp->common.shmem_base, bp->common.shmem2_base);
 
 	if (!bp->common.shmem_base ||
 	    (bp->common.shmem_base < 0xA0000) ||
@@ -7610,6 +8083,9 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
 		BNX2X_ERR("This driver needs bc_ver %X but found %X,"
 			  " please upgrade BC\n", BNX2X_BC_VER, val);
 	}
+	bp->link_params.feature_config_flags |=
+		(val >= REQ_BC_VER_4_VRFY_OPT_MDL) ?
+		FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0;
 
 	if (BP_E1HVN(bp) == 0) {
 		pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
@@ -7770,6 +8246,18 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
 					       SUPPORTED_Asym_Pause);
 			break;
 
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
+			BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n",
+				       ext_phy_type);
+
+			bp->port.supported |= (SUPPORTED_10000baseT_Full |
+					       SUPPORTED_1000baseT_Full |
+					       SUPPORTED_Autoneg |
+					       SUPPORTED_FIBRE |
+					       SUPPORTED_Pause |
+					       SUPPORTED_Asym_Pause);
+			break;
+
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
 			BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n",
 				       ext_phy_type);
@@ -8024,6 +8512,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
 	u32 val, val2;
 	u32 config;
 	u16 i;
+	u32 ext_phy_type;
 
 	bp->link_params.bp = bp;
 	bp->link_params.port = port;
@@ -8033,6 +8522,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
 	bp->link_params.ext_phy_config =
 		SHMEM_RD(bp,
 			 dev_info.port_hw_config[port].external_phy_config);
+	/* BCM8727_NOC => BCM8727 no over current */
+	if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
+	    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) {
+		bp->link_params.ext_phy_config &=
+			~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK;
+		bp->link_params.ext_phy_config |=
+			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727;
+		bp->link_params.feature_config_flags |=
+			FEATURE_CONFIG_BCM8727_NOC;
+	}
+
 	bp->link_params.speed_cap_mask =
 		SHMEM_RD(bp,
 			 dev_info.port_hw_config[port].speed_capability_mask);
@@ -8053,17 +8553,10 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
 		bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff);
 	}
 
-	config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
-	if (config & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED)
-		bp->link_params.feature_config_flags |=
-				FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
-	else
-		bp->link_params.feature_config_flags &=
-				~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
-
 	/* If the device is capable of WoL, set the default state according
 	 * to the HW
 	 */
+	config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
 	bp->wol = (!(bp->flags & NO_WOL_FLAG) &&
 		   (config & PORT_FEATURE_WOL_ENABLED));
 
@@ -8073,12 +8566,25 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
 		       bp->link_params.ext_phy_config,
 		       bp->link_params.speed_cap_mask, bp->port.link_config);
 
-	bp->link_params.switch_cfg = (bp->port.link_config &
-				      PORT_FEATURE_CONNECTED_SWITCH_MASK);
+	bp->link_params.switch_cfg |= (bp->port.link_config &
+				       PORT_FEATURE_CONNECTED_SWITCH_MASK);
 	bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg);
 
 	bnx2x_link_settings_requested(bp);
 
+	/*
+	 * If connected directly, work with the internal PHY, otherwise, work
+	 * with the external PHY
+	 */
+	ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+	if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
+		bp->mdio.prtad = bp->link_params.phy_addr;
+
+	else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
+		 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
+		bp->mdio.prtad =
+			XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
+
 	val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
 	val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
 	bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
@@ -8105,22 +8611,33 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
 		bp->mf_config =
 			SHMEM_RD(bp, mf_cfg.func_mf_config[func].config);
 
-		val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func].e1hov_tag) &
+		val = (SHMEM_RD(bp, mf_cfg.func_mf_config[FUNC_0].e1hov_tag) &
 		       FUNC_MF_CFG_E1HOV_TAG_MASK);
-		if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
-
-			bp->e1hov = val;
+		if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT)
 			bp->e1hmf = 1;
-			BNX2X_DEV_INFO("MF mode  E1HOV for func %d is %d "
-				       "(0x%04x)\n",
-				       func, bp->e1hov, bp->e1hov);
-		} else {
-			BNX2X_DEV_INFO("single function mode\n");
-			if (BP_E1HVN(bp)) {
+		BNX2X_DEV_INFO("%s function mode\n",
+			       IS_E1HMF(bp) ? "multi" : "single");
+
+		if (IS_E1HMF(bp)) {
+			val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func].
+								e1hov_tag) &
+			       FUNC_MF_CFG_E1HOV_TAG_MASK);
+			if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
+				bp->e1hov = val;
+				BNX2X_DEV_INFO("E1HOV for func %d is %d "
+					       "(0x%04x)\n",
+					       func, bp->e1hov, bp->e1hov);
+			} else {
 				BNX2X_ERR("!!!  No valid E1HOV for func %d,"
 					  "  aborting\n", func);
 				rc = -EPERM;
 			}
+		} else {
+			if (BP_E1HVN(bp)) {
+				BNX2X_ERR("!!!  VN %d in single function mode,"
+					  "  aborting\n", BP_E1HVN(bp));
+				rc = -EPERM;
+			}
 		}
 	}
 
@@ -8170,6 +8687,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
 
 	/* Disable interrupt handling until HW is initialized */
 	atomic_set(&bp->intr_sem, 1);
+	smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */
 
 	mutex_init(&bp->port.phy_mutex);
 
@@ -8208,6 +8726,11 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
 		bp->dev->features |= NETIF_F_LRO;
 	}
 
+	if (CHIP_IS_E1(bp))
+		bp->dropless_fc = 0;
+	else
+		bp->dropless_fc = dropless_fc;
+
 	bp->mrrs = mrrs;
 
 	bp->tx_ring_size = MAX_TX_AVAIL;
@@ -8269,6 +8792,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
+		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
 			cmd->port = PORT_FIBRE;
 			break;
 
@@ -8290,7 +8814,7 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	} else
 		cmd->port = PORT_TP;
 
-	cmd->phy_address = bp->port.phy_addr;
+	cmd->phy_address = bp->mdio.prtad;
 	cmd->transceiver = XCVR_INTERNAL;
 
 	if (bp->link_params.req_line_speed == SPEED_AUTO_NEG)
@@ -8463,50 +8987,15 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	return 0;
 }
 
-#define PHY_FW_VER_LEN			10
-
-static void bnx2x_get_drvinfo(struct net_device *dev,
-			      struct ethtool_drvinfo *info)
-{
-	struct bnx2x *bp = netdev_priv(dev);
-	u8 phy_fw_ver[PHY_FW_VER_LEN];
-
-	strcpy(info->driver, DRV_MODULE_NAME);
-	strcpy(info->version, DRV_MODULE_VERSION);
-
-	phy_fw_ver[0] = '\0';
-	if (bp->port.pmf) {
-		bnx2x_acquire_phy_lock(bp);
-		bnx2x_get_ext_phy_fw_version(&bp->link_params,
-					     (bp->state != BNX2X_STATE_CLOSED),
-					     phy_fw_ver, PHY_FW_VER_LEN);
-		bnx2x_release_phy_lock(bp);
-	}
-
-	snprintf(info->fw_version, 32, "BC:%d.%d.%d%s%s",
-		 (bp->common.bc_ver & 0xff0000) >> 16,
-		 (bp->common.bc_ver & 0xff00) >> 8,
-		 (bp->common.bc_ver & 0xff),
-		 ((phy_fw_ver[0] != '\0') ? " PHY:" : ""), phy_fw_ver);
-	strcpy(info->bus_info, pci_name(bp->pdev));
-	info->n_stats = BNX2X_NUM_STATS;
-	info->testinfo_len = BNX2X_NUM_TESTS;
-	info->eedump_len = bp->common.flash_size;
-	info->regdump_len = 0;
-}
-
 #define IS_E1_ONLINE(info)	(((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
 #define IS_E1H_ONLINE(info)	(((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
 
 static int bnx2x_get_regs_len(struct net_device *dev)
 {
-	static u32 regdump_len;
 	struct bnx2x *bp = netdev_priv(dev);
+	int regdump_len = 0;
 	int i;
 
-	if (regdump_len)
-		return regdump_len;
-
 	if (CHIP_IS_E1(bp)) {
 		for (i = 0; i < REGS_COUNT; i++)
 			if (IS_E1_ONLINE(reg_addrs[i].info))
@@ -8573,6 +9062,38 @@ static void bnx2x_get_regs(struct net_device *dev,
 	}
 }
 
+#define PHY_FW_VER_LEN			10
+
+static void bnx2x_get_drvinfo(struct net_device *dev,
+			      struct ethtool_drvinfo *info)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	u8 phy_fw_ver[PHY_FW_VER_LEN];
+
+	strcpy(info->driver, DRV_MODULE_NAME);
+	strcpy(info->version, DRV_MODULE_VERSION);
+
+	phy_fw_ver[0] = '\0';
+	if (bp->port.pmf) {
+		bnx2x_acquire_phy_lock(bp);
+		bnx2x_get_ext_phy_fw_version(&bp->link_params,
+					     (bp->state != BNX2X_STATE_CLOSED),
+					     phy_fw_ver, PHY_FW_VER_LEN);
+		bnx2x_release_phy_lock(bp);
+	}
+
+	snprintf(info->fw_version, 32, "BC:%d.%d.%d%s%s",
+		 (bp->common.bc_ver & 0xff0000) >> 16,
+		 (bp->common.bc_ver & 0xff00) >> 8,
+		 (bp->common.bc_ver & 0xff),
+		 ((phy_fw_ver[0] != '\0') ? " PHY:" : ""), phy_fw_ver);
+	strcpy(info->bus_info, pci_name(bp->pdev));
+	info->n_stats = BNX2X_NUM_STATS;
+	info->testinfo_len = BNX2X_NUM_TESTS;
+	info->eedump_len = bp->common.flash_size;
+	info->regdump_len = bnx2x_get_regs_len(dev);
+}
+
 static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct bnx2x *bp = netdev_priv(dev);
@@ -8638,8 +9159,7 @@ static int bnx2x_nway_reset(struct net_device *dev)
 	return 0;
 }
 
-static u32
-bnx2x_get_link(struct net_device *dev)
+static u32 bnx2x_get_link(struct net_device *dev)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
@@ -9013,7 +9533,8 @@ static int bnx2x_set_eeprom(struct net_device *dev,
 			    struct ethtool_eeprom *eeprom, u8 *eebuf)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	int rc;
+	int port = BP_PORT(bp);
+	int rc = 0;
 
 	if (!netif_running(dev))
 		return -EAGAIN;
@@ -9025,27 +9546,60 @@ static int bnx2x_set_eeprom(struct net_device *dev,
 
 	/* parameters already validated in ethtool_set_eeprom */
 
-	/* If the magic number is PHY (0x00504859) upgrade the PHY FW */
-	if (eeprom->magic == 0x00504859)
-		if (bp->port.pmf) {
+	/* PHY eeprom can be accessed only by the PMF */
+	if ((eeprom->magic >= 0x50485900) && (eeprom->magic <= 0x504859FF) &&
+	    !bp->port.pmf)
+		return -EINVAL;
 
+	if (eeprom->magic == 0x50485950) {
+		/* 'PHYP' (0x50485950): prepare phy for FW upgrade */
+		bnx2x_stats_handle(bp, STATS_EVENT_STOP);
+
+		bnx2x_acquire_phy_lock(bp);
+		rc |= bnx2x_link_reset(&bp->link_params,
+				       &bp->link_vars, 0);
+		if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
+					PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101)
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+				       MISC_REGISTERS_GPIO_HIGH, port);
+		bnx2x_release_phy_lock(bp);
+		bnx2x_link_report(bp);
+
+	} else if (eeprom->magic == 0x50485952) {
+		/* 'PHYR' (0x50485952): re-init link after FW upgrade */
+		if ((bp->state == BNX2X_STATE_OPEN) ||
+		    (bp->state == BNX2X_STATE_DISABLED)) {
 			bnx2x_acquire_phy_lock(bp);
-			rc = bnx2x_flash_download(bp, BP_PORT(bp),
-					     bp->link_params.ext_phy_config,
-					     (bp->state != BNX2X_STATE_CLOSED),
-					     eebuf, eeprom->len);
-			if ((bp->state == BNX2X_STATE_OPEN) ||
-			    (bp->state == BNX2X_STATE_DISABLED)) {
-				rc |= bnx2x_link_reset(&bp->link_params,
-						       &bp->link_vars, 1);
-				rc |= bnx2x_phy_init(&bp->link_params,
-						     &bp->link_vars);
-			}
+			rc |= bnx2x_link_reset(&bp->link_params,
+					       &bp->link_vars, 1);
+
+			rc |= bnx2x_phy_init(&bp->link_params,
+					     &bp->link_vars);
 			bnx2x_release_phy_lock(bp);
+			bnx2x_calc_fc_adv(bp);
+		}
+	} else if (eeprom->magic == 0x53985943) {
+		/* 'PHYC' (0x53985943): PHY FW upgrade completed */
+		if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) ==
+				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) {
+			u8 ext_phy_addr =
+			     XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config);
 
-		} else /* Only the PMF can access the PHY */
-			return -EINVAL;
-	else
+			/* DSP Remove Download Mode */
+			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
+				       MISC_REGISTERS_GPIO_LOW, port);
+
+			bnx2x_acquire_phy_lock(bp);
+
+			bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
+
+			/* wait 0.5 sec to allow it to run */
+			msleep(500);
+			bnx2x_ext_phy_hw_reset(bp, port);
+			msleep(500);
+			bnx2x_release_phy_lock(bp);
+		}
+	} else
 		rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
 
 	return rc;
@@ -9064,18 +9618,19 @@ static int bnx2x_get_coalesce(struct net_device *dev,
 	return 0;
 }
 
+#define BNX2X_MAX_COALES_TOUT  (0xf0*12) /* Maximal coalescing timeout in us */
 static int bnx2x_set_coalesce(struct net_device *dev,
 			      struct ethtool_coalesce *coal)
 {
 	struct bnx2x *bp = netdev_priv(dev);
 
 	bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
-	if (bp->rx_ticks > BNX2X_MAX_COALESCE_TOUT)
-		bp->rx_ticks = BNX2X_MAX_COALESCE_TOUT;
+	if (bp->rx_ticks > BNX2X_MAX_COALES_TOUT)
+		bp->rx_ticks = BNX2X_MAX_COALES_TOUT;
 
 	bp->tx_ticks = (u16) coal->tx_coalesce_usecs;
-	if (bp->tx_ticks > BNX2X_MAX_COALESCE_TOUT)
-		bp->tx_ticks = BNX2X_MAX_COALESCE_TOUT;
+	if (bp->tx_ticks > BNX2X_MAX_COALES_TOUT)
+		bp->tx_ticks = BNX2X_MAX_COALES_TOUT;
 
 	if (netif_running(dev))
 		bnx2x_update_coalesce(bp);
@@ -9296,10 +9851,9 @@ static int bnx2x_test_registers(struct bnx2x *bp)
 		{ XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 4, 0x00000001 },
 		{ XCM_REG_WU_DA_CNT_CMD00,             4, 0x00000003 },
 		{ XCM_REG_GLB_DEL_ACK_MAX_CNT_0,       4, 0x000000ff },
-		{ NIG_REG_EGRESS_MNG0_FIFO,           20, 0xffffffff },
 		{ NIG_REG_LLH0_T_BIT,                  4, 0x00000001 },
-/* 20 */	{ NIG_REG_EMAC0_IN_EN,                 4, 0x00000001 },
-		{ NIG_REG_BMAC0_IN_EN,                 4, 0x00000001 },
+		{ NIG_REG_EMAC0_IN_EN,                 4, 0x00000001 },
+/* 20 */	{ NIG_REG_BMAC0_IN_EN,                 4, 0x00000001 },
 		{ NIG_REG_XCM0_OUT_EN,                 4, 0x00000001 },
 		{ NIG_REG_BRB0_OUT_EN,                 4, 0x00000001 },
 		{ NIG_REG_LLH0_XCM_MASK,               4, 0x00000007 },
@@ -9308,8 +9862,8 @@ static int bnx2x_test_registers(struct bnx2x *bp)
 		{ NIG_REG_LLH0_DEST_MAC_0_0,         160, 0xffffffff },
 		{ NIG_REG_LLH0_DEST_IP_0_1,          160, 0xffffffff },
 		{ NIG_REG_LLH0_IPV4_IPV6_0,          160, 0x00000001 },
-/* 30 */	{ NIG_REG_LLH0_DEST_UDP_0,           160, 0x0000ffff },
-		{ NIG_REG_LLH0_DEST_TCP_0,           160, 0x0000ffff },
+		{ NIG_REG_LLH0_DEST_UDP_0,           160, 0x0000ffff },
+/* 30 */	{ NIG_REG_LLH0_DEST_TCP_0,           160, 0x0000ffff },
 		{ NIG_REG_LLH0_VLAN_ID_0,            160, 0x00000fff },
 		{ NIG_REG_XGXS_SERDES0_MODE_SEL,       4, 0x00000001 },
 		{ NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0, 4, 0x00000001 },
@@ -9435,12 +9989,14 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
 	unsigned int pkt_size, num_pkts, i;
 	struct sk_buff *skb;
 	unsigned char *packet;
-	struct bnx2x_fastpath *fp = &bp->fp[0];
+	struct bnx2x_fastpath *fp_rx = &bp->fp[0];
+	struct bnx2x_fastpath *fp_tx = &bp->fp[bp->num_rx_queues];
 	u16 tx_start_idx, tx_idx;
 	u16 rx_start_idx, rx_idx;
-	u16 pkt_prod;
+	u16 pkt_prod, bd_prod;
 	struct sw_tx_bd *tx_buf;
-	struct eth_tx_bd *tx_bd;
+	struct eth_tx_start_bd *tx_start_bd;
+	struct eth_tx_parse_bd *pbd = NULL;
 	dma_addr_t mapping;
 	union eth_rx_cqe *cqe;
 	u8 cqe_fp_flags;
@@ -9472,57 +10028,64 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
 	}
 	packet = skb_put(skb, pkt_size);
 	memcpy(packet, bp->dev->dev_addr, ETH_ALEN);
-	memset(packet + ETH_ALEN, 0, (ETH_HLEN - ETH_ALEN));
+	memset(packet + ETH_ALEN, 0, ETH_ALEN);
+	memset(packet + 2*ETH_ALEN, 0x77, (ETH_HLEN - 2*ETH_ALEN));
 	for (i = ETH_HLEN; i < pkt_size; i++)
 		packet[i] = (unsigned char) (i & 0xff);
 
 	/* send the loopback packet */
 	num_pkts = 0;
-	tx_start_idx = le16_to_cpu(*fp->tx_cons_sb);
-	rx_start_idx = le16_to_cpu(*fp->rx_cons_sb);
+	tx_start_idx = le16_to_cpu(*fp_tx->tx_cons_sb);
+	rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
 
-	pkt_prod = fp->tx_pkt_prod++;
-	tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
-	tx_buf->first_bd = fp->tx_bd_prod;
+	pkt_prod = fp_tx->tx_pkt_prod++;
+	tx_buf = &fp_tx->tx_buf_ring[TX_BD(pkt_prod)];
+	tx_buf->first_bd = fp_tx->tx_bd_prod;
 	tx_buf->skb = skb;
+	tx_buf->flags = 0;
 
-	tx_bd = &fp->tx_desc_ring[TX_BD(fp->tx_bd_prod)];
+	bd_prod = TX_BD(fp_tx->tx_bd_prod);
+	tx_start_bd = &fp_tx->tx_desc_ring[bd_prod].start_bd;
 	mapping = pci_map_single(bp->pdev, skb->data,
 				 skb_headlen(skb), PCI_DMA_TODEVICE);
-	tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
-	tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
-	tx_bd->nbd = cpu_to_le16(1);
-	tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
-	tx_bd->vlan = cpu_to_le16(pkt_prod);
-	tx_bd->bd_flags.as_bitfield = (ETH_TX_BD_FLAGS_START_BD |
-				       ETH_TX_BD_FLAGS_END_BD);
-	tx_bd->general_data = ((UNICAST_ADDRESS <<
-				ETH_TX_BD_ETH_ADDR_TYPE_SHIFT) | 1);
+	tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+	tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+	tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */
+	tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+	tx_start_bd->vlan = cpu_to_le16(pkt_prod);
+	tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
+	tx_start_bd->general_data = ((UNICAST_ADDRESS <<
+				ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1);
+
+	/* turn on parsing and get a BD */
+	bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+	pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd;
+
+	memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
 
 	wmb();
 
-	le16_add_cpu(&fp->hw_tx_prods->bds_prod, 1);
-	mb(); /* FW restriction: must not reorder writing nbd and packets */
-	le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
-	DOORBELL(bp, fp->index, 0);
+	fp_tx->tx_db.data.prod += 2;
+	barrier();
+	DOORBELL(bp, fp_tx->index - bp->num_rx_queues, fp_tx->tx_db.raw);
 
 	mmiowb();
 
 	num_pkts++;
-	fp->tx_bd_prod++;
+	fp_tx->tx_bd_prod += 2; /* start + pbd */
 	bp->dev->trans_start = jiffies;
 
 	udelay(100);
 
-	tx_idx = le16_to_cpu(*fp->tx_cons_sb);
+	tx_idx = le16_to_cpu(*fp_tx->tx_cons_sb);
 	if (tx_idx != tx_start_idx + num_pkts)
 		goto test_loopback_exit;
 
-	rx_idx = le16_to_cpu(*fp->rx_cons_sb);
+	rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
 	if (rx_idx != rx_start_idx + num_pkts)
 		goto test_loopback_exit;
 
-	cqe = &fp->rx_comp_ring[RCQ_BD(fp->rx_comp_cons)];
+	cqe = &fp_rx->rx_comp_ring[RCQ_BD(fp_rx->rx_comp_cons)];
 	cqe_fp_flags = cqe->fast_path_cqe.type_error_flags;
 	if (CQE_TYPE(cqe_fp_flags) || (cqe_fp_flags & ETH_RX_ERROR_FALGS))
 		goto test_loopback_rx_exit;
@@ -9531,7 +10094,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
 	if (len != pkt_size)
 		goto test_loopback_rx_exit;
 
-	rx_buf = &fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)];
+	rx_buf = &fp_rx->rx_buf_ring[RX_BD(fp_rx->rx_bd_cons)];
 	skb = rx_buf->skb;
 	skb_reserve(skb, cqe->fast_path_cqe.placement_offset);
 	for (i = ETH_HLEN; i < pkt_size; i++)
@@ -9542,14 +10105,14 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
 
 test_loopback_rx_exit:
 
-	fp->rx_bd_cons = NEXT_RX_IDX(fp->rx_bd_cons);
-	fp->rx_bd_prod = NEXT_RX_IDX(fp->rx_bd_prod);
-	fp->rx_comp_cons = NEXT_RCQ_IDX(fp->rx_comp_cons);
-	fp->rx_comp_prod = NEXT_RCQ_IDX(fp->rx_comp_prod);
+	fp_rx->rx_bd_cons = NEXT_RX_IDX(fp_rx->rx_bd_cons);
+	fp_rx->rx_bd_prod = NEXT_RX_IDX(fp_rx->rx_bd_prod);
+	fp_rx->rx_comp_cons = NEXT_RCQ_IDX(fp_rx->rx_comp_cons);
+	fp_rx->rx_comp_prod = NEXT_RCQ_IDX(fp_rx->rx_comp_prod);
 
 	/* Update producers */
-	bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
-			     fp->rx_sge_prod);
+	bnx2x_update_rx_prod(bp, fp_rx, fp_rx->rx_bd_prod, fp_rx->rx_comp_prod,
+			     fp_rx->rx_sge_prod);
 
 test_loopback_exit:
 	bp->link_params.loopback_mode = LOOPBACK_NONE;
@@ -9606,7 +10169,7 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
 	__be32 buf[0x350 / 4];
 	u8 *data = (u8 *)buf;
 	int i, rc;
-	u32 magic, csum;
+	u32 magic, crc;
 
 	rc = bnx2x_nvram_read(bp, 0, data, 4);
 	if (rc) {
@@ -9631,10 +10194,10 @@ static int bnx2x_test_nvram(struct bnx2x *bp)
 			goto test_nvram_exit;
 		}
 
-		csum = ether_crc_le(nvram_tbl[i].size, data);
-		if (csum != CRC32_RESIDUAL) {
+		crc = ether_crc_le(nvram_tbl[i].size, data);
+		if (crc != CRC32_RESIDUAL) {
 			DP(NETIF_MSG_PROBE,
-			   "nvram_tbl[%d] csum value (0x%08x)\n", i, csum);
+			   "nvram_tbl[%d] crc value (0x%08x)\n", i, crc);
 			rc = -ENODEV;
 			goto test_nvram_exit;
 		}
@@ -9692,8 +10255,15 @@ static void bnx2x_self_test(struct net_device *dev,
 		etest->flags &= ~ETH_TEST_FL_OFFLINE;
 
 	if (etest->flags & ETH_TEST_FL_OFFLINE) {
+		int port = BP_PORT(bp);
+		u32 val;
 		u8 link_up;
 
+		/* save current value of input enable for TX port IF */
+		val = REG_RD(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4);
+		/* disable input for TX port IF */
+		REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0);
+
 		link_up = bp->link_vars.link_up;
 		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
 		bnx2x_nic_load(bp, LOAD_DIAG);
@@ -9713,6 +10283,10 @@ static void bnx2x_self_test(struct net_device *dev,
 			etest->flags |= ETH_TEST_FL_FAILED;
 
 		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+
+		/* restore input for TX port IF */
+		REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, val);
+
 		bnx2x_nic_load(bp, LOAD_NORMAL);
 		/* wait until link state is restored */
 		bnx2x_wait_for_link(bp, link_up);
@@ -9871,7 +10445,7 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 	case ETH_SS_STATS:
 		if (is_multi(bp)) {
 			k = 0;
-			for_each_queue(bp, i) {
+			for_each_rx_queue(bp, i) {
 				for (j = 0; j < BNX2X_NUM_Q_STATS; j++)
 					sprintf(buf + (k + j)*ETH_GSTRING_LEN,
 						bnx2x_q_stats_arr[j].string, i);
@@ -9905,7 +10479,7 @@ static int bnx2x_get_stats_count(struct net_device *dev)
 	int i, num_stats;
 
 	if (is_multi(bp)) {
-		num_stats = BNX2X_NUM_Q_STATS * BNX2X_NUM_QUEUES(bp);
+		num_stats = BNX2X_NUM_Q_STATS * bp->num_rx_queues;
 		if (!IS_E1HMF_MODE_STAT(bp))
 			num_stats += BNX2X_NUM_STATS;
 	} else {
@@ -9930,7 +10504,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev,
 
 	if (is_multi(bp)) {
 		k = 0;
-		for_each_queue(bp, i) {
+		for_each_rx_queue(bp, i) {
 			hw_stats = (u32 *)&bp->fp[i].eth_q_stats;
 			for (j = 0; j < BNX2X_NUM_Q_STATS; j++) {
 				if (bnx2x_q_stats_arr[j].size == 0) {
@@ -10032,7 +10606,7 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
 	return 0;
 }
 
-static struct ethtool_ops bnx2x_ethtool_ops = {
+static const struct ethtool_ops bnx2x_ethtool_ops = {
 	.get_settings		= bnx2x_get_settings,
 	.set_settings		= bnx2x_set_settings,
 	.get_drvinfo		= bnx2x_get_drvinfo,
@@ -10143,15 +10717,11 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
 		goto poll_panic;
 #endif
 
-	prefetch(fp->tx_buf_ring[TX_BD(fp->tx_pkt_cons)].skb);
 	prefetch(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb);
 	prefetch((char *)(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb) + 256);
 
 	bnx2x_update_fpsb_idx(fp);
 
-	if (bnx2x_has_tx_work(fp))
-		bnx2x_tx_int(fp);
-
 	if (bnx2x_has_rx_work(fp)) {
 		work_done = bnx2x_rx_int(fp, budget);
 
@@ -10160,11 +10730,11 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
 			goto poll_again;
 	}
 
-	/* BNX2X_HAS_WORK() reads the status block, thus we need to
+	/* bnx2x_has_rx_work() reads the status block, thus we need to
 	 * ensure that status block indices have been actually read
-	 * (bnx2x_update_fpsb_idx) prior to this check (BNX2X_HAS_WORK)
+	 * (bnx2x_update_fpsb_idx) prior to this check (bnx2x_has_rx_work)
 	 * so that we won't write the "newer" value of the status block to IGU
-	 * (if there was a DMA right after BNX2X_HAS_WORK and
+	 * (if there was a DMA right after bnx2x_has_rx_work and
 	 * if there is no rmb, the memory reading (bnx2x_update_fpsb_idx)
 	 * may be postponed to right before bnx2x_ack_sb). In this case
 	 * there will never be another interrupt until there is another update
@@ -10172,7 +10742,7 @@ static int bnx2x_poll(struct napi_struct *napi, int budget)
 	 */
 	rmb();
 
-	if (!BNX2X_HAS_WORK(fp)) {
+	if (!bnx2x_has_rx_work(fp)) {
 #ifdef BNX2X_STOP_ON_ERROR
 poll_panic:
 #endif
@@ -10197,10 +10767,11 @@ poll_again:
  */
 static noinline u16 bnx2x_tx_split(struct bnx2x *bp,
 				   struct bnx2x_fastpath *fp,
-				   struct eth_tx_bd **tx_bd, u16 hlen,
+				   struct sw_tx_bd *tx_buf,
+				   struct eth_tx_start_bd **tx_bd, u16 hlen,
 				   u16 bd_prod, int nbd)
 {
-	struct eth_tx_bd *h_tx_bd = *tx_bd;
+	struct eth_tx_start_bd *h_tx_bd = *tx_bd;
 	struct eth_tx_bd *d_tx_bd;
 	dma_addr_t mapping;
 	int old_len = le16_to_cpu(h_tx_bd->nbytes);
@@ -10216,7 +10787,7 @@ static noinline u16 bnx2x_tx_split(struct bnx2x *bp,
 	/* now get a new data BD
 	 * (after the pbd) and fill it */
 	bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
-	d_tx_bd = &fp->tx_desc_ring[bd_prod];
+	d_tx_bd = &fp->tx_desc_ring[bd_prod].reg_bd;
 
 	mapping = HILO_U64(le32_to_cpu(h_tx_bd->addr_hi),
 			   le32_to_cpu(h_tx_bd->addr_lo)) + hlen;
@@ -10224,17 +10795,16 @@ static noinline u16 bnx2x_tx_split(struct bnx2x *bp,
 	d_tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
 	d_tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
 	d_tx_bd->nbytes = cpu_to_le16(old_len - hlen);
-	d_tx_bd->vlan = 0;
-	/* this marks the BD as one that has no individual mapping
-	 * the FW ignores this flag in a BD not marked start
-	 */
-	d_tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO;
+
+	/* this marks the BD as one that has no individual mapping */
+	tx_buf->flags |= BNX2X_TSO_SPLIT_BD;
+
 	DP(NETIF_MSG_TX_QUEUED,
 	   "TSO split data size is %d (%x:%x)\n",
 	   d_tx_bd->nbytes, d_tx_bd->addr_hi, d_tx_bd->addr_lo);
 
-	/* update tx_bd for marking the last BD flag */
-	*tx_bd = d_tx_bd;
+	/* update tx_bd */
+	*tx_bd = (struct eth_tx_start_bd *)d_tx_bd;
 
 	return bd_prod;
 }
@@ -10366,21 +10936,22 @@ exit_lbl:
  * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
  * netif_wake_queue()
  */
-static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	struct bnx2x_fastpath *fp;
+	struct bnx2x_fastpath *fp, *fp_stat;
 	struct netdev_queue *txq;
 	struct sw_tx_bd *tx_buf;
-	struct eth_tx_bd *tx_bd;
+	struct eth_tx_start_bd *tx_start_bd;
+	struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL;
 	struct eth_tx_parse_bd *pbd = NULL;
 	u16 pkt_prod, bd_prod;
 	int nbd, fp_index;
 	dma_addr_t mapping;
 	u32 xmit_type = bnx2x_xmit_type(bp, skb);
-	int vlan_off = (bp->e1hov ? 4 : 0);
 	int i;
 	u8 hlen = 0;
+	__le16 pkt_size = 0;
 
 #ifdef BNX2X_STOP_ON_ERROR
 	if (unlikely(bp->panic))
@@ -10390,10 +10961,11 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	fp_index = skb_get_queue_mapping(skb);
 	txq = netdev_get_tx_queue(dev, fp_index);
 
-	fp = &bp->fp[fp_index];
+	fp = &bp->fp[fp_index + bp->num_rx_queues];
+	fp_stat = &bp->fp[fp_index];
 
 	if (unlikely(bnx2x_tx_avail(fp) < (skb_shinfo(skb)->nr_frags + 3))) {
-		fp->eth_q_stats.driver_xoff++,
+		fp_stat->eth_q_stats.driver_xoff++;
 		netif_tx_stop_queue(txq);
 		BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
 		return NETDEV_TX_BUSY;
@@ -10422,7 +10994,7 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/*
 	Please read carefully. First we use one BD which we mark as start,
-	then for TSO or xsum we have a parsing info BD,
+	then we have a parsing info BD (used for TSO or xsum),
 	and only then we have the rest of the TSO BDs.
 	(don't forget to mark the last one as last,
 	and to unmap only AFTER you write to the BD ...)
@@ -10434,42 +11006,40 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* get a tx_buf and first BD */
 	tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
-	tx_bd = &fp->tx_desc_ring[bd_prod];
+	tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd;
 
-	tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
-	tx_bd->general_data = (UNICAST_ADDRESS <<
-			       ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
+	tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
+	tx_start_bd->general_data = (UNICAST_ADDRESS <<
+				     ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT);
 	/* header nbd */
-	tx_bd->general_data |= (1 << ETH_TX_BD_HDR_NBDS_SHIFT);
+	tx_start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT);
 
 	/* remember the first BD of the packet */
 	tx_buf->first_bd = fp->tx_bd_prod;
 	tx_buf->skb = skb;
+	tx_buf->flags = 0;
 
 	DP(NETIF_MSG_TX_QUEUED,
 	   "sending pkt %u @%p  next_idx %u  bd %u @%p\n",
-	   pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd);
+	   pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd);
 
 #ifdef BCM_VLAN
 	if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) &&
 	    (bp->flags & HW_VLAN_TX_FLAG)) {
-		tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
-		tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
-		vlan_off += 4;
+		tx_start_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
+		tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
 	} else
 #endif
-		tx_bd->vlan = cpu_to_le16(pkt_prod);
+		tx_start_bd->vlan = cpu_to_le16(pkt_prod);
 
-	if (xmit_type) {
-		/* turn on parsing and get a BD */
-		bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
-		pbd = (void *)&fp->tx_desc_ring[bd_prod];
+	/* turn on parsing and get a BD */
+	bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+	pbd = &fp->tx_desc_ring[bd_prod].parse_bd;
 
-		memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
-	}
+	memset(pbd, 0, sizeof(struct eth_tx_parse_bd));
 
 	if (xmit_type & XMIT_CSUM) {
-		hlen = (skb_network_header(skb) - skb->data + vlan_off) / 2;
+		hlen = (skb_network_header(skb) - skb->data) / 2;
 
 		/* for now NS flag is not used in Linux */
 		pbd->global_data =
@@ -10482,15 +11052,16 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2;
 
 		pbd->total_hlen = cpu_to_le16(hlen);
-		hlen = hlen*2 - vlan_off;
+		hlen = hlen*2;
 
-		tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_TCP_CSUM;
+		tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM;
 
 		if (xmit_type & XMIT_CSUM_V4)
-			tx_bd->bd_flags.as_bitfield |=
+			tx_start_bd->bd_flags.as_bitfield |=
 						ETH_TX_BD_FLAGS_IP_CSUM;
 		else
-			tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IPV6;
+			tx_start_bd->bd_flags.as_bitfield |=
+						ETH_TX_BD_FLAGS_IPV6;
 
 		if (xmit_type & XMIT_CSUM_TCP) {
 			pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check);
@@ -10498,13 +11069,11 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		} else {
 			s8 fix = SKB_CS_OFF(skb); /* signed! */
 
-			pbd->global_data |= ETH_TX_PARSE_BD_CS_ANY_FLG;
-			pbd->cs_offset = fix / 2;
+			pbd->global_data |= ETH_TX_PARSE_BD_UDP_CS_FLG;
 
 			DP(NETIF_MSG_TX_QUEUED,
-			   "hlen %d  offset %d  fix %d  csum before fix %x\n",
-			   le16_to_cpu(pbd->total_hlen), pbd->cs_offset, fix,
-			   SKB_CS(skb));
+			   "hlen %d  fix %d  csum before fix %x\n",
+			   le16_to_cpu(pbd->total_hlen), fix, SKB_CS(skb));
 
 			/* HW bug: fixup the CSUM */
 			pbd->tcp_pseudo_csum =
@@ -10519,17 +11088,18 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	mapping = pci_map_single(bp->pdev, skb->data,
 				 skb_headlen(skb), PCI_DMA_TODEVICE);
 
-	tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
-	tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
-	nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL) ? 1 : 2);
-	tx_bd->nbd = cpu_to_le16(nbd);
-	tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+	tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+	tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+	nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */
+	tx_start_bd->nbd = cpu_to_le16(nbd);
+	tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+	pkt_size = tx_start_bd->nbytes;
 
 	DP(NETIF_MSG_TX_QUEUED, "first bd @%p  addr (%x:%x)  nbd %d"
 	   "  nbytes %d  flags %x  vlan %x\n",
-	   tx_bd, tx_bd->addr_hi, tx_bd->addr_lo, le16_to_cpu(tx_bd->nbd),
-	   le16_to_cpu(tx_bd->nbytes), tx_bd->bd_flags.as_bitfield,
-	   le16_to_cpu(tx_bd->vlan));
+	   tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo,
+	   le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes),
+	   tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan));
 
 	if (xmit_type & XMIT_GSO) {
 
@@ -10538,11 +11108,11 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		   skb->len, hlen, skb_headlen(skb),
 		   skb_shinfo(skb)->gso_size);
 
-		tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO;
+		tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO;
 
 		if (unlikely(skb_headlen(skb) > hlen))
-			bd_prod = bnx2x_tx_split(bp, fp, &tx_bd, hlen,
-						 bd_prod, ++nbd);
+			bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd,
+						 hlen, bd_prod, ++nbd);
 
 		pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
 		pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq);
@@ -10563,33 +11133,31 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN;
 	}
+	tx_data_bd = (struct eth_tx_bd *)tx_start_bd;
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 		bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
-		tx_bd = &fp->tx_desc_ring[bd_prod];
+		tx_data_bd = &fp->tx_desc_ring[bd_prod].reg_bd;
+		if (total_pkt_bd == NULL)
+			total_pkt_bd = &fp->tx_desc_ring[bd_prod].reg_bd;
 
 		mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset,
 				       frag->size, PCI_DMA_TODEVICE);
 
-		tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
-		tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
-		tx_bd->nbytes = cpu_to_le16(frag->size);
-		tx_bd->vlan = cpu_to_le16(pkt_prod);
-		tx_bd->bd_flags.as_bitfield = 0;
+		tx_data_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+		tx_data_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+		tx_data_bd->nbytes = cpu_to_le16(frag->size);
+		le16_add_cpu(&pkt_size, frag->size);
 
 		DP(NETIF_MSG_TX_QUEUED,
-		   "frag %d  bd @%p  addr (%x:%x)  nbytes %d  flags %x\n",
-		   i, tx_bd, tx_bd->addr_hi, tx_bd->addr_lo,
-		   le16_to_cpu(tx_bd->nbytes), tx_bd->bd_flags.as_bitfield);
+		   "frag %d  bd @%p  addr (%x:%x)  nbytes %d\n",
+		   i, tx_data_bd, tx_data_bd->addr_hi, tx_data_bd->addr_lo,
+		   le16_to_cpu(tx_data_bd->nbytes));
 	}
 
-	/* now at last mark the BD as the last BD */
-	tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_END_BD;
-
-	DP(NETIF_MSG_TX_QUEUED, "last bd @%p  flags %x\n",
-	   tx_bd, tx_bd->bd_flags.as_bitfield);
+	DP(NETIF_MSG_TX_QUEUED, "last bd @%p\n", tx_data_bd);
 
 	bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
 
@@ -10599,6 +11167,9 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (TX_BD_POFF(bd_prod) < nbd)
 		nbd++;
 
+	if (total_pkt_bd != NULL)
+		total_pkt_bd->total_pkt_bytes = pkt_size;
+
 	if (pbd)
 		DP(NETIF_MSG_TX_QUEUED,
 		   "PBD @%p  ip_data %x  ip_hlen %u  ip_id %u  lso_mss %u"
@@ -10618,25 +11189,24 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	 */
 	wmb();
 
-	le16_add_cpu(&fp->hw_tx_prods->bds_prod, nbd);
-	mb(); /* FW restriction: must not reorder writing nbd and packets */
-	le32_add_cpu(&fp->hw_tx_prods->packets_prod, 1);
-	DOORBELL(bp, fp->index, 0);
+	fp->tx_db.data.prod += nbd;
+	barrier();
+	DOORBELL(bp, fp->index - bp->num_rx_queues, fp->tx_db.raw);
 
 	mmiowb();
 
 	fp->tx_bd_prod += nbd;
 
 	if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
+		netif_tx_stop_queue(txq);
 		/* We want bnx2x_tx_int to "see" the updated tx_bd_prod
 		   if we put Tx into XOFF state. */
 		smp_mb();
-		netif_tx_stop_queue(txq);
-		fp->eth_q_stats.driver_xoff++;
+		fp_stat->eth_q_stats.driver_xoff++;
 		if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
 			netif_tx_wake_queue(txq);
 	}
-	fp->tx_pkt++;
+	fp_stat->tx_pkt++;
 
 	return NETDEV_TX_OK;
 }
@@ -10712,8 +11282,9 @@ static void bnx2x_set_rx_mode(struct net_device *dev)
 							cpu_to_le16(port);
 				config->config_table[i].
 					target_table_entry.flags = 0;
-				config->config_table[i].
-					target_table_entry.client_id = 0;
+				config->config_table[i].target_table_entry.
+					clients_bit_vector =
+						cpu_to_le32(1 << BP_L_ID(bp));
 				config->config_table[i].
 					target_table_entry.vlan_id = 0;
 
@@ -10808,54 +11379,77 @@ static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
 }
 
 /* called with rtnl_lock */
-static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int bnx2x_mdio_read(struct net_device *netdev, int prtad,
+			   int devad, u16 addr)
 {
-	struct mii_ioctl_data *data = if_mii(ifr);
-	struct bnx2x *bp = netdev_priv(dev);
-	int port = BP_PORT(bp);
-	int err;
+	struct bnx2x *bp = netdev_priv(netdev);
+	u16 value;
+	int rc;
+	u32 phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
 
-	switch (cmd) {
-	case SIOCGMIIPHY:
-		data->phy_id = bp->port.phy_addr;
+	DP(NETIF_MSG_LINK, "mdio_read: prtad 0x%x, devad 0x%x, addr 0x%x\n",
+	   prtad, devad, addr);
 
-		/* fallthrough */
+	if (prtad != bp->mdio.prtad) {
+		DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
+		   prtad, bp->mdio.prtad);
+		return -EINVAL;
+	}
 
-	case SIOCGMIIREG: {
-		u16 mii_regval;
+	/* The HW expects different devad if CL22 is used */
+	devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
 
-		if (!netif_running(dev))
-			return -EAGAIN;
+	bnx2x_acquire_phy_lock(bp);
+	rc = bnx2x_cl45_read(bp, BP_PORT(bp), phy_type, prtad,
+			     devad, addr, &value);
+	bnx2x_release_phy_lock(bp);
+	DP(NETIF_MSG_LINK, "mdio_read_val 0x%x rc = 0x%x\n", value, rc);
 
-		mutex_lock(&bp->port.phy_mutex);
-		err = bnx2x_cl45_read(bp, port, 0, bp->port.phy_addr,
-				      DEFAULT_PHY_DEV_ADDR,
-				      (data->reg_num & 0x1f), &mii_regval);
-		data->val_out = mii_regval;
-		mutex_unlock(&bp->port.phy_mutex);
-		return err;
+	if (!rc)
+		rc = value;
+	return rc;
+}
+
+/* called with rtnl_lock */
+static int bnx2x_mdio_write(struct net_device *netdev, int prtad, int devad,
+			    u16 addr, u16 value)
+{
+	struct bnx2x *bp = netdev_priv(netdev);
+	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config);
+	int rc;
+
+	DP(NETIF_MSG_LINK, "mdio_write: prtad 0x%x, devad 0x%x, addr 0x%x,"
+			   " value 0x%x\n", prtad, devad, addr, value);
+
+	if (prtad != bp->mdio.prtad) {
+		DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n",
+		   prtad, bp->mdio.prtad);
+		return -EINVAL;
 	}
 
-	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
+	/* The HW expects different devad if CL22 is used */
+	devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad;
 
-		if (!netif_running(dev))
-			return -EAGAIN;
+	bnx2x_acquire_phy_lock(bp);
+	rc = bnx2x_cl45_write(bp, BP_PORT(bp), ext_phy_type, prtad,
+			      devad, addr, value);
+	bnx2x_release_phy_lock(bp);
+	return rc;
+}
 
-		mutex_lock(&bp->port.phy_mutex);
-		err = bnx2x_cl45_write(bp, port, 0, bp->port.phy_addr,
-				       DEFAULT_PHY_DEV_ADDR,
-				       (data->reg_num & 0x1f), data->val_in);
-		mutex_unlock(&bp->port.phy_mutex);
-		return err;
+/* called with rtnl_lock */
+static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	struct mii_ioctl_data *mdio = if_mii(ifr);
 
-	default:
-		/* do nothing */
-		break;
-	}
+	DP(NETIF_MSG_LINK, "ioctl: phy id 0x%x, reg 0x%x, val_in 0x%x\n",
+	   mdio->phy_id, mdio->reg_num, mdio->val_in);
+
+	if (!netif_running(dev))
+		return -EAGAIN;
 
-	return -EOPNOTSUPP;
+	return mdio_mii_ioctl(&bp->mdio, mdio, cmd);
 }
 
 /* called with rtnl_lock */
@@ -11065,12 +11659,27 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
 	dev->features |= NETIF_F_HW_CSUM;
 	if (bp->flags & USING_DAC_FLAG)
 		dev->features |= NETIF_F_HIGHDMA;
+	dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
+	dev->features |= NETIF_F_TSO6;
 #ifdef BCM_VLAN
 	dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
 	bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG);
+
+	dev->vlan_features |= NETIF_F_SG;
+	dev->vlan_features |= NETIF_F_HW_CSUM;
+	if (bp->flags & USING_DAC_FLAG)
+		dev->vlan_features |= NETIF_F_HIGHDMA;
+	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
+	dev->vlan_features |= NETIF_F_TSO6;
 #endif
-	dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
-	dev->features |= NETIF_F_TSO6;
+
+	/* get_port_hwinfo() will set prtad and mmds properly */
+	bp->mdio.prtad = MDIO_PRTAD_NONE;
+	bp->mdio.mmds = 0;
+	bp->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+	bp->mdio.dev = dev;
+	bp->mdio.mdio_read = bnx2x_mdio_read;
+	bp->mdio.mdio_write = bnx2x_mdio_write;
 
 	return 0;
 
@@ -11096,31 +11705,26 @@ err_out:
 	return rc;
 }
 
-static int __devinit bnx2x_get_pcie_width(struct bnx2x *bp)
+static void __devinit bnx2x_get_pcie_width_speed(struct bnx2x *bp,
+						 int *width, int *speed)
 {
 	u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
 
-	val = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
-	return val;
-}
+	*width = (val & PCICFG_LINK_WIDTH) >> PCICFG_LINK_WIDTH_SHIFT;
 
-/* return value of 1=2.5GHz 2=5GHz */
-static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
-{
-	u32 val = REG_RD(bp, PCICFG_OFFSET + PCICFG_LINK_CONTROL);
-
-	val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
-	return val;
+	/* return value of 1=2.5GHz 2=5GHz */
+	*speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
 }
+
 static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
 {
+	const struct firmware *firmware = bp->firmware;
 	struct bnx2x_fw_file_hdr *fw_hdr;
 	struct bnx2x_fw_file_section *sections;
-	u16 *ops_offsets;
 	u32 offset, len, num_ops;
+	u16 *ops_offsets;
 	int i;
-	const struct firmware *firmware = bp->firmware;
-	const u8 * fw_ver;
+	const u8 *fw_ver;
 
 	if (firmware->size < sizeof(struct bnx2x_fw_file_hdr))
 		return -EINVAL;
@@ -11134,7 +11738,8 @@ static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
 		offset = be32_to_cpu(sections[i].offset);
 		len = be32_to_cpu(sections[i].len);
 		if (offset + len > firmware->size) {
-			printk(KERN_ERR PFX "Section %d length is out of bounds\n", i);
+			printk(KERN_ERR PFX "Section %d length is out of "
+					    "bounds\n", i);
 			return -EINVAL;
 		}
 	}
@@ -11146,7 +11751,8 @@ static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
 
 	for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) {
 		if (be16_to_cpu(ops_offsets[i]) > num_ops) {
-			printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i);
+			printk(KERN_ERR PFX "Section offset %d is out of "
+					    "bounds\n", i);
 			return -EINVAL;
 		}
 	}
@@ -11165,17 +11771,17 @@ static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
 		       BCM_5710_FW_MINOR_VERSION,
 		       BCM_5710_FW_REVISION_VERSION,
 		       BCM_5710_FW_ENGINEERING_VERSION);
-                return -EINVAL;
+		return -EINVAL;
 	}
 
 	return 0;
 }
 
-static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+static inline void be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
 {
+	const __be32 *source = (const __be32 *)_source;
+	u32 *target = (u32 *)_target;
 	u32 i;
-	const __be32 *source = (const __be32*)_source;
-	u32 *target = (u32*)_target;
 
 	for (i = 0; i < n/4; i++)
 		target[i] = be32_to_cpu(source[i]);
@@ -11185,66 +11791,67 @@ static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
    Ops array is stored in the following format:
    {op(8bit), offset(24bit, big endian), data(32bit, big endian)}
  */
-static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
+static inline void bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
 {
+	const __be32 *source = (const __be32 *)_source;
+	struct raw_op *target = (struct raw_op *)_target;
 	u32 i, j, tmp;
-	const __be32 *source = (const __be32*)_source;
-	struct raw_op *target = (struct raw_op*)_target;
 
-	for (i = 0, j = 0; i < n/8; i++, j+=2) {
+	for (i = 0, j = 0; i < n/8; i++, j += 2) {
 		tmp = be32_to_cpu(source[j]);
 		target[i].op = (tmp >> 24) & 0xff;
 		target[i].offset =  tmp & 0xffffff;
 		target[i].raw_data = be32_to_cpu(source[j+1]);
 	}
 }
-static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+
+static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
 {
+	const __be16 *source = (const __be16 *)_source;
+	u16 *target = (u16 *)_target;
 	u32 i;
-	u16 *target = (u16*)_target;
-	const __be16 *source = (const __be16*)_source;
 
 	for (i = 0; i < n/2; i++)
 		target[i] = be16_to_cpu(source[i]);
 }
 
 #define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
-	do {   \
-		u32 len = be32_to_cpu(fw_hdr->arr.len);   \
-		bp->arr = kmalloc(len, GFP_KERNEL);  \
+	do { \
+		u32 len = be32_to_cpu(fw_hdr->arr.len); \
+		bp->arr = kmalloc(len, GFP_KERNEL); \
 		if (!bp->arr) { \
-			printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \
+			printk(KERN_ERR PFX "Failed to allocate %d bytes " \
+					    "for "#arr"\n", len); \
 			goto lbl; \
 		} \
-		func(bp->firmware->data + \
-			be32_to_cpu(fw_hdr->arr.offset), \
-			(u8*)bp->arr, len); \
+		func(bp->firmware->data + be32_to_cpu(fw_hdr->arr.offset), \
+		     (u8 *)bp->arr, len); \
 	} while (0)
 
-
 static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
 {
 	char fw_file_name[40] = {0};
-        int rc, offset;
 	struct bnx2x_fw_file_hdr *fw_hdr;
+	int rc, offset;
 
 	/* Create a FW file name */
 	if (CHIP_IS_E1(bp))
-                offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
+		offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
 	else
 		offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
 
 	sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw",
 		BCM_5710_FW_MAJOR_VERSION,
-                BCM_5710_FW_MINOR_VERSION,
-                BCM_5710_FW_REVISION_VERSION,
-                BCM_5710_FW_ENGINEERING_VERSION);
+		BCM_5710_FW_MINOR_VERSION,
+		BCM_5710_FW_REVISION_VERSION,
+		BCM_5710_FW_ENGINEERING_VERSION);
 
 	printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
 
 	rc = request_firmware(&bp->firmware, fw_file_name, dev);
 	if (rc) {
-		printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name);
+		printk(KERN_ERR PFX "Can't load firmware file %s\n",
+		       fw_file_name);
 		goto request_firmware_exit;
 	}
 
@@ -11264,27 +11871,29 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
 	BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops);
 
 	/* Offsets */
-	BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
+	BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err,
+			    be16_to_cpu_n);
 
 	/* STORMs firmware */
-	bp->tsem_int_table_data = bp->firmware->data +
-		be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
-	bp->tsem_pram_data      = bp->firmware->data +
-		be32_to_cpu(fw_hdr->tsem_pram_data.offset);
-	bp->usem_int_table_data = bp->firmware->data +
-		be32_to_cpu(fw_hdr->usem_int_table_data.offset);
-	bp->usem_pram_data      = bp->firmware->data +
-		be32_to_cpu(fw_hdr->usem_pram_data.offset);
-	bp->xsem_int_table_data = bp->firmware->data +
-		be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
-	bp->xsem_pram_data      = bp->firmware->data +
-		be32_to_cpu(fw_hdr->xsem_pram_data.offset);
-	bp->csem_int_table_data = bp->firmware->data +
-		be32_to_cpu(fw_hdr->csem_int_table_data.offset);
-	bp->csem_pram_data      = bp->firmware->data +
-		be32_to_cpu(fw_hdr->csem_pram_data.offset);
+	INIT_TSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+			be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
+	INIT_TSEM_PRAM_DATA(bp)      = bp->firmware->data +
+			be32_to_cpu(fw_hdr->tsem_pram_data.offset);
+	INIT_USEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+			be32_to_cpu(fw_hdr->usem_int_table_data.offset);
+	INIT_USEM_PRAM_DATA(bp)      = bp->firmware->data +
+			be32_to_cpu(fw_hdr->usem_pram_data.offset);
+	INIT_XSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+			be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
+	INIT_XSEM_PRAM_DATA(bp)      = bp->firmware->data +
+			be32_to_cpu(fw_hdr->xsem_pram_data.offset);
+	INIT_CSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
+			be32_to_cpu(fw_hdr->csem_int_table_data.offset);
+	INIT_CSEM_PRAM_DATA(bp)      = bp->firmware->data +
+			be32_to_cpu(fw_hdr->csem_pram_data.offset);
 
 	return 0;
+
 init_offsets_alloc_err:
 	kfree(bp->init_ops);
 init_ops_alloc_err:
@@ -11296,18 +11905,14 @@ request_firmware_exit:
 }
 
 
-
 static int __devinit bnx2x_init_one(struct pci_dev *pdev,
 				    const struct pci_device_id *ent)
 {
-	static int version_printed;
 	struct net_device *dev = NULL;
 	struct bnx2x *bp;
+	int pcie_width, pcie_speed;
 	int rc;
 
-	if (version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
-
 	/* dev zeroed in init_etherdev */
 	dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT);
 	if (!dev) {
@@ -11318,14 +11923,14 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
 	bp = netdev_priv(dev);
 	bp->msglevel = debug;
 
+	pci_set_drvdata(pdev, dev);
+
 	rc = bnx2x_init_dev(pdev, dev);
 	if (rc < 0) {
 		free_netdev(dev);
 		return rc;
 	}
 
-	pci_set_drvdata(pdev, dev);
-
 	rc = bnx2x_init_bp(bp);
 	if (rc)
 		goto init_one_exit;
@@ -11343,11 +11948,11 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
 		goto init_one_exit;
 	}
 
+	bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed);
 	printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
 	       " IRQ %d, ", dev->name, board_info[ent->driver_data].name,
 	       (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4),
-	       bnx2x_get_pcie_width(bp),
-	       (bnx2x_get_pcie_speed(bp) == 2) ? "5GHz (Gen2)" : "2.5GHz",
+	       pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz",
 	       dev->base_addr, bp->pdev->irq);
 	printk(KERN_CONT "node addr %pM\n", dev->dev_addr);
 
@@ -11554,6 +12159,11 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
 
 	netif_device_detach(dev);
 
+	if (state == pci_channel_io_perm_failure) {
+		rtnl_unlock();
+		return PCI_ERS_RESULT_DISCONNECT;
+	}
+
 	if (netif_running(dev))
 		bnx2x_eeh_nic_unload(bp);
 
@@ -11640,6 +12250,8 @@ static int __init bnx2x_init(void)
 {
 	int ret;
 
+	printk(KERN_INFO "%s", version);
+
 	bnx2x_wq = create_singlethread_workqueue("bnx2x");
 	if (bnx2x_wq == NULL) {
 		printk(KERN_ERR PFX "Cannot create workqueue\n");
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index b8ce6fc..0695be1 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -190,12 +190,6 @@
    _(0..15) stands for the connection type (one of 16). */
 #define CCM_REG_N_SM_CTX_LD_0					 0xd004c
 #define CCM_REG_N_SM_CTX_LD_1					 0xd0050
-#define CCM_REG_N_SM_CTX_LD_10					 0xd0074
-#define CCM_REG_N_SM_CTX_LD_11					 0xd0078
-#define CCM_REG_N_SM_CTX_LD_12					 0xd007c
-#define CCM_REG_N_SM_CTX_LD_13					 0xd0080
-#define CCM_REG_N_SM_CTX_LD_14					 0xd0084
-#define CCM_REG_N_SM_CTX_LD_15					 0xd0088
 #define CCM_REG_N_SM_CTX_LD_2					 0xd0054
 #define CCM_REG_N_SM_CTX_LD_3					 0xd0058
 #define CCM_REG_N_SM_CTX_LD_4					 0xd005c
@@ -370,7 +364,6 @@
 #define CFC_REG_NUM_LCIDS_LEAVING				 0x104018
 /* [RW 8] The event id for aggregated interrupt 0 */
 #define CSDM_REG_AGG_INT_EVENT_0				 0xc2038
-#define CSDM_REG_AGG_INT_EVENT_1				 0xc203c
 #define CSDM_REG_AGG_INT_EVENT_10				 0xc2060
 #define CSDM_REG_AGG_INT_EVENT_11				 0xc2064
 #define CSDM_REG_AGG_INT_EVENT_12				 0xc2068
@@ -378,37 +371,27 @@
 #define CSDM_REG_AGG_INT_EVENT_14				 0xc2070
 #define CSDM_REG_AGG_INT_EVENT_15				 0xc2074
 #define CSDM_REG_AGG_INT_EVENT_16				 0xc2078
-#define CSDM_REG_AGG_INT_EVENT_17				 0xc207c
-#define CSDM_REG_AGG_INT_EVENT_18				 0xc2080
-#define CSDM_REG_AGG_INT_EVENT_19				 0xc2084
 #define CSDM_REG_AGG_INT_EVENT_2				 0xc2040
-#define CSDM_REG_AGG_INT_EVENT_20				 0xc2088
-#define CSDM_REG_AGG_INT_EVENT_21				 0xc208c
-#define CSDM_REG_AGG_INT_EVENT_22				 0xc2090
-#define CSDM_REG_AGG_INT_EVENT_23				 0xc2094
-#define CSDM_REG_AGG_INT_EVENT_24				 0xc2098
-#define CSDM_REG_AGG_INT_EVENT_25				 0xc209c
-#define CSDM_REG_AGG_INT_EVENT_26				 0xc20a0
-#define CSDM_REG_AGG_INT_EVENT_27				 0xc20a4
-#define CSDM_REG_AGG_INT_EVENT_28				 0xc20a8
-#define CSDM_REG_AGG_INT_EVENT_29				 0xc20ac
 #define CSDM_REG_AGG_INT_EVENT_3				 0xc2044
-#define CSDM_REG_AGG_INT_EVENT_30				 0xc20b0
-#define CSDM_REG_AGG_INT_EVENT_31				 0xc20b4
 #define CSDM_REG_AGG_INT_EVENT_4				 0xc2048
-/* [RW 1] The T bit for aggregated interrupt 0 */
-#define CSDM_REG_AGG_INT_T_0					 0xc20b8
-#define CSDM_REG_AGG_INT_T_1					 0xc20bc
-#define CSDM_REG_AGG_INT_T_10					 0xc20e0
-#define CSDM_REG_AGG_INT_T_11					 0xc20e4
-#define CSDM_REG_AGG_INT_T_12					 0xc20e8
-#define CSDM_REG_AGG_INT_T_13					 0xc20ec
-#define CSDM_REG_AGG_INT_T_14					 0xc20f0
-#define CSDM_REG_AGG_INT_T_15					 0xc20f4
-#define CSDM_REG_AGG_INT_T_16					 0xc20f8
-#define CSDM_REG_AGG_INT_T_17					 0xc20fc
-#define CSDM_REG_AGG_INT_T_18					 0xc2100
-#define CSDM_REG_AGG_INT_T_19					 0xc2104
+#define CSDM_REG_AGG_INT_EVENT_5				 0xc204c
+#define CSDM_REG_AGG_INT_EVENT_6				 0xc2050
+#define CSDM_REG_AGG_INT_EVENT_7				 0xc2054
+#define CSDM_REG_AGG_INT_EVENT_8				 0xc2058
+#define CSDM_REG_AGG_INT_EVENT_9				 0xc205c
+/* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
+   or auto-mask-mode (1) */
+#define CSDM_REG_AGG_INT_MODE_10				 0xc21e0
+#define CSDM_REG_AGG_INT_MODE_11				 0xc21e4
+#define CSDM_REG_AGG_INT_MODE_12				 0xc21e8
+#define CSDM_REG_AGG_INT_MODE_13				 0xc21ec
+#define CSDM_REG_AGG_INT_MODE_14				 0xc21f0
+#define CSDM_REG_AGG_INT_MODE_15				 0xc21f4
+#define CSDM_REG_AGG_INT_MODE_16				 0xc21f8
+#define CSDM_REG_AGG_INT_MODE_6 				 0xc21d0
+#define CSDM_REG_AGG_INT_MODE_7 				 0xc21d4
+#define CSDM_REG_AGG_INT_MODE_8 				 0xc21d8
+#define CSDM_REG_AGG_INT_MODE_9 				 0xc21dc
 /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
 #define CSDM_REG_CFC_RSP_START_ADDR				 0xc2008
 /* [RW 16] The maximum value of the competion counter #0 */
@@ -633,24 +616,6 @@
 #define DMAE_REG_GO_C1						 0x102084
 /* [RW 1] Command 10 go. */
 #define DMAE_REG_GO_C10 					 0x102088
-#define DMAE_REG_GO_C10_SIZE					 1
-/* [RW 1] Command 11 go. */
-#define DMAE_REG_GO_C11 					 0x10208c
-#define DMAE_REG_GO_C11_SIZE					 1
-/* [RW 1] Command 12 go. */
-#define DMAE_REG_GO_C12 					 0x102090
-#define DMAE_REG_GO_C12_SIZE					 1
-/* [RW 1] Command 13 go. */
-#define DMAE_REG_GO_C13 					 0x102094
-#define DMAE_REG_GO_C13_SIZE					 1
-/* [RW 1] Command 14 go. */
-#define DMAE_REG_GO_C14 					 0x102098
-#define DMAE_REG_GO_C14_SIZE					 1
-/* [RW 1] Command 15 go. */
-#define DMAE_REG_GO_C15 					 0x10209c
-#define DMAE_REG_GO_C15_SIZE					 1
-/* [RW 1] Command 10 go. */
-#define DMAE_REG_GO_C10 					 0x102088
 /* [RW 1] Command 11 go. */
 #define DMAE_REG_GO_C11 					 0x10208c
 /* [RW 1] Command 12 go. */
@@ -800,7 +765,6 @@
 #define MCP_REG_MCPR_NVM_READ					 0x86410
 #define MCP_REG_MCPR_NVM_SW_ARB 				 0x86420
 #define MCP_REG_MCPR_NVM_WRITE					 0x86408
-#define MCP_REG_MCPR_NVM_WRITE1 				 0x86428
 #define MCP_REG_MCPR_SCRATCH					 0xa0000
 /* [R 32] read first 32 bit after inversion of function 0. mapped as
    follows: [0] NIG attention for function0; [1] NIG attention for
@@ -1186,19 +1150,7 @@
 #define MISC_REG_AEU_GENERAL_ATTN_10				 0xa028
 #define MISC_REG_AEU_GENERAL_ATTN_11				 0xa02c
 #define MISC_REG_AEU_GENERAL_ATTN_12				 0xa030
-#define MISC_REG_AEU_GENERAL_ATTN_13				 0xa034
-#define MISC_REG_AEU_GENERAL_ATTN_14				 0xa038
-#define MISC_REG_AEU_GENERAL_ATTN_15				 0xa03c
-#define MISC_REG_AEU_GENERAL_ATTN_16				 0xa040
-#define MISC_REG_AEU_GENERAL_ATTN_17				 0xa044
-#define MISC_REG_AEU_GENERAL_ATTN_18				 0xa048
-#define MISC_REG_AEU_GENERAL_ATTN_19				 0xa04c
-#define MISC_REG_AEU_GENERAL_ATTN_10				 0xa028
-#define MISC_REG_AEU_GENERAL_ATTN_11				 0xa02c
-#define MISC_REG_AEU_GENERAL_ATTN_12				 0xa030
 #define MISC_REG_AEU_GENERAL_ATTN_2				 0xa008
-#define MISC_REG_AEU_GENERAL_ATTN_20				 0xa050
-#define MISC_REG_AEU_GENERAL_ATTN_21				 0xa054
 #define MISC_REG_AEU_GENERAL_ATTN_3				 0xa00c
 #define MISC_REG_AEU_GENERAL_ATTN_4				 0xa010
 #define MISC_REG_AEU_GENERAL_ATTN_5				 0xa014
@@ -1290,137 +1242,13 @@
    set. if the appropriate bit is clear (the driver request to free a client
    it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
    be asserted). */
-#define MISC_REG_DRIVER_CONTROL_10				 0xa3e0
-#define MISC_REG_DRIVER_CONTROL_10_SIZE 			 2
-/* [RW 32] The following driver registers(1...16) represent 16 drivers and
-   32 clients. Each client can be controlled by one driver only. One in each
-   bit represent that this driver control the appropriate client (Ex: bit 5
-   is set means this driver control client number 5). addr1 = set; addr0 =
-   clear; read from both addresses will give the same result = status. write
-   to address 1 will set a request to control all the clients that their
-   appropriate bit (in the write command) is set. if the client is free (the
-   appropriate bit in all the other drivers is clear) one will be written to
-   that driver register; if the client isn't free the bit will remain zero.
-   if the appropriate bit is set (the driver request to gain control on a
-   client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
-   interrupt will be asserted). write to address 0 will set a request to
-   free all the clients that their appropriate bit (in the write command) is
-   set. if the appropriate bit is clear (the driver request to free a client
-   it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
-   be asserted). */
-#define MISC_REG_DRIVER_CONTROL_11				 0xa3e8
-#define MISC_REG_DRIVER_CONTROL_11_SIZE 			 2
-/* [RW 32] The following driver registers(1...16) represent 16 drivers and
-   32 clients. Each client can be controlled by one driver only. One in each
-   bit represent that this driver control the appropriate client (Ex: bit 5
-   is set means this driver control client number 5). addr1 = set; addr0 =
-   clear; read from both addresses will give the same result = status. write
-   to address 1 will set a request to control all the clients that their
-   appropriate bit (in the write command) is set. if the client is free (the
-   appropriate bit in all the other drivers is clear) one will be written to
-   that driver register; if the client isn't free the bit will remain zero.
-   if the appropriate bit is set (the driver request to gain control on a
-   client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
-   interrupt will be asserted). write to address 0 will set a request to
-   free all the clients that their appropriate bit (in the write command) is
-   set. if the appropriate bit is clear (the driver request to free a client
-   it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
-   be asserted). */
-#define MISC_REG_DRIVER_CONTROL_12				 0xa3f0
-#define MISC_REG_DRIVER_CONTROL_12_SIZE 			 2
-/* [RW 32] The following driver registers(1...16) represent 16 drivers and
-   32 clients. Each client can be controlled by one driver only. One in each
-   bit represent that this driver control the appropriate client (Ex: bit 5
-   is set means this driver control client number 5). addr1 = set; addr0 =
-   clear; read from both addresses will give the same result = status. write
-   to address 1 will set a request to control all the clients that their
-   appropriate bit (in the write command) is set. if the client is free (the
-   appropriate bit in all the other drivers is clear) one will be written to
-   that driver register; if the client isn't free the bit will remain zero.
-   if the appropriate bit is set (the driver request to gain control on a
-   client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
-   interrupt will be asserted). write to address 0 will set a request to
-   free all the clients that their appropriate bit (in the write command) is
-   set. if the appropriate bit is clear (the driver request to free a client
-   it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
-   be asserted). */
-#define MISC_REG_DRIVER_CONTROL_13				 0xa3f8
-#define MISC_REG_DRIVER_CONTROL_13_SIZE 			 2
-/* [RW 32] The following driver registers(1...16) represent 16 drivers and
-   32 clients. Each client can be controlled by one driver only. One in each
-   bit represent that this driver control the appropriate client (Ex: bit 5
-   is set means this driver control client number 5). addr1 = set; addr0 =
-   clear; read from both addresses will give the same result = status. write
-   to address 1 will set a request to control all the clients that their
-   appropriate bit (in the write command) is set. if the client is free (the
-   appropriate bit in all the other drivers is clear) one will be written to
-   that driver register; if the client isn't free the bit will remain zero.
-   if the appropriate bit is set (the driver request to gain control on a
-   client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
-   interrupt will be asserted). write to address 0 will set a request to
-   free all the clients that their appropriate bit (in the write command) is
-   set. if the appropriate bit is clear (the driver request to free a client
-   it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
-   be asserted). */
 #define MISC_REG_DRIVER_CONTROL_1				 0xa510
-#define MISC_REG_DRIVER_CONTROL_14				 0xa5e0
-#define MISC_REG_DRIVER_CONTROL_14_SIZE 			 2
-/* [RW 32] The following driver registers(1...16) represent 16 drivers and
-   32 clients. Each client can be controlled by one driver only. One in each
-   bit represent that this driver control the appropriate client (Ex: bit 5
-   is set means this driver control client number 5). addr1 = set; addr0 =
-   clear; read from both addresses will give the same result = status. write
-   to address 1 will set a request to control all the clients that their
-   appropriate bit (in the write command) is set. if the client is free (the
-   appropriate bit in all the other drivers is clear) one will be written to
-   that driver register; if the client isn't free the bit will remain zero.
-   if the appropriate bit is set (the driver request to gain control on a
-   client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
-   interrupt will be asserted). write to address 0 will set a request to
-   free all the clients that their appropriate bit (in the write command) is
-   set. if the appropriate bit is clear (the driver request to free a client
-   it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
-   be asserted). */
-#define MISC_REG_DRIVER_CONTROL_15				 0xa5e8
-#define MISC_REG_DRIVER_CONTROL_15_SIZE 			 2
-/* [RW 32] The following driver registers(1...16) represent 16 drivers and
-   32 clients. Each client can be controlled by one driver only. One in each
-   bit represent that this driver control the appropriate client (Ex: bit 5
-   is set means this driver control client number 5). addr1 = set; addr0 =
-   clear; read from both addresses will give the same result = status. write
-   to address 1 will set a request to control all the clients that their
-   appropriate bit (in the write command) is set. if the client is free (the
-   appropriate bit in all the other drivers is clear) one will be written to
-   that driver register; if the client isn't free the bit will remain zero.
-   if the appropriate bit is set (the driver request to gain control on a
-   client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
-   interrupt will be asserted). write to address 0 will set a request to
-   free all the clients that their appropriate bit (in the write command) is
-   set. if the appropriate bit is clear (the driver request to free a client
-   it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
-   be asserted). */
-#define MISC_REG_DRIVER_CONTROL_16				 0xa5f0
-#define MISC_REG_DRIVER_CONTROL_16_SIZE 			 2
-/* [RW 32] The following driver registers(1...16) represent 16 drivers and
-   32 clients. Each client can be controlled by one driver only. One in each
-   bit represent that this driver control the appropriate client (Ex: bit 5
-   is set means this driver control client number 5). addr1 = set; addr0 =
-   clear; read from both addresses will give the same result = status. write
-   to address 1 will set a request to control all the clients that their
-   appropriate bit (in the write command) is set. if the client is free (the
-   appropriate bit in all the other drivers is clear) one will be written to
-   that driver register; if the client isn't free the bit will remain zero.
-   if the appropriate bit is set (the driver request to gain control on a
-   client it already controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW
-   interrupt will be asserted). write to address 0 will set a request to
-   free all the clients that their appropriate bit (in the write command) is
-   set. if the appropriate bit is clear (the driver request to free a client
-   it doesn't controls the ~MISC_REGISTERS_INT_STS.GENERIC_SW interrupt will
-   be asserted). */
 #define MISC_REG_DRIVER_CONTROL_7				 0xa3c8
 /* [RW 1] e1hmf for WOL. If clr WOL signal o the PXP will be send on bit 0
    only. */
 #define MISC_REG_E1HMF_MODE					 0xa5f8
+/* [RW 32] Debug only: spare RW register reset by core reset */
+#define MISC_REG_GENERIC_CR_0					 0xa460
 /* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of
    these bits is written as a '1'; the corresponding SPIO bit will turn off
    it's drivers and become an input. This is the reset state of all GPIO
@@ -1616,6 +1444,11 @@
 /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are
    loaded; 0-prepare; -unprepare */
 #define MISC_REG_UNPREPARED					 0xa424
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST	 (0x1<<0)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_MLCST	 (0x1<<1)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN	 (0x1<<4)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST	 (0x1<<2)
+#define NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN	 (0x1<<3)
 #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT	 (0x1<<0)
 #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS	 (0x1<<9)
 #define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G 	 (0x1<<15)
@@ -1654,12 +1487,12 @@
 /* [RW 1] MAC configuration for packets of port0. If 1 - all packet outputs
    to emac for port0; other way to bmac for port0 */
 #define NIG_REG_EGRESS_EMAC0_PORT				 0x10058
-/* [RW 32] TX_MNG_FIFO in NIG_TX_PORT0; data[31:0] written in FIFO order. */
-#define NIG_REG_EGRESS_MNG0_FIFO				 0x1045c
 /* [RW 1] Input enable for TX PBF user packet port0 IF */
 #define NIG_REG_EGRESS_PBF0_IN_EN				 0x100cc
 /* [RW 1] Input enable for TX PBF user packet port1 IF */
 #define NIG_REG_EGRESS_PBF1_IN_EN				 0x100d0
+/* [RW 1] Input enable for TX UMP management packet port0 IF */
+#define NIG_REG_EGRESS_UMP0_IN_EN				 0x100d4
 /* [RW 1] Input enable for RX_EMAC0 IF */
 #define NIG_REG_EMAC0_IN_EN					 0x100a4
 /* [RW 1] output enable for TX EMAC pause port 0 IF */
@@ -1683,6 +1516,24 @@
 /* [RW 17] Debug only. RX_EOP_DSCR_lb_FIFO in NIG_RX_EOP. Data
    packet_length[13:0]; mac_error[14]; trunc_error[15]; parity[16] */
 #define NIG_REG_INGRESS_EOP_LB_FIFO				 0x104e4
+/* [RW 27] 0 - must be active for Everest A0; 1- for Everest B0 when latch
+   logic for interrupts must be used. Enable per bit of interrupt of
+   ~latch_status.latch_status */
+#define NIG_REG_LATCH_BC_0					 0x16210
+/* [RW 27] Latch for each interrupt from Unicore.b[0]
+   status_emac0_misc_mi_int; b[1] status_emac0_misc_mi_complete;
+   b[2]status_emac0_misc_cfg_change; b[3]status_emac0_misc_link_status;
+   b[4]status_emac0_misc_link_change; b[5]status_emac0_misc_attn;
+   b[6]status_serdes0_mac_crs; b[7]status_serdes0_autoneg_complete;
+   b[8]status_serdes0_fiber_rxact; b[9]status_serdes0_link_status;
+   b[10]status_serdes0_mr_page_rx; b[11]status_serdes0_cl73_an_complete;
+   b[12]status_serdes0_cl73_mr_page_rx; b[13]status_serdes0_rx_sigdet;
+   b[14]status_xgxs0_remotemdioreq; b[15]status_xgxs0_link10g;
+   b[16]status_xgxs0_autoneg_complete; b[17]status_xgxs0_fiber_rxact;
+   b[21:18]status_xgxs0_link_status; b[22]status_xgxs0_mr_page_rx;
+   b[23]status_xgxs0_cl73_an_complete; b[24]status_xgxs0_cl73_mr_page_rx;
+   b[25]status_xgxs0_rx_sigdet; b[26]status_xgxs0_mac_crs */
+#define NIG_REG_LATCH_STATUS_0					 0x18000
 /* [RW 1] led 10g for port 0 */
 #define NIG_REG_LED_10G_P0					 0x10320
 /* [RW 1] led 10g for port 1 */
@@ -1722,6 +1573,7 @@
 /* [RW 3] for port0 enable for llfc ppp and pause. b0 - brb1 enable; b1-
    tsdm enable; b2- usdm enable */
 #define NIG_REG_LLFC_EGRESS_SRC_ENABLE_0			 0x16070
+#define NIG_REG_LLFC_EGRESS_SRC_ENABLE_1			 0x16074
 /* [RW 1] SAFC enable for port0. This register may get 1 only when
    ~ppp_enable.ppp_enable = 0 and pause_enable.pause_enable =0 for the same
    port */
@@ -1872,6 +1724,7 @@
 #define NIG_REG_XGXS_LANE_SEL_P0				 0x102e8
 /* [RW 1] selection for port0 for NIG_MUX block : 0 = SerDes; 1 = XGXS */
 #define NIG_REG_XGXS_SERDES0_MODE_SEL				 0x102e0
+#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT  (0x1<<0)
 #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS (0x1<<9)
 #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G	 (0x1<<15)
 #define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS  (0xf<<18)
@@ -2072,6 +1925,7 @@
 #define PXP2_REG_PGL_ADDR_94_F0 				 0x120540
 #define PXP2_REG_PGL_CONTROL0					 0x120490
 #define PXP2_REG_PGL_CONTROL1					 0x120514
+#define PXP2_REG_PGL_DEBUG					 0x120520
 /* [RW 32] third dword data of expansion rom request. this register is
    special. reading from it provides a vector outstanding read requests. if
    a bit is zero it means that a read request on the corresponding tag did
@@ -2142,11 +1996,8 @@
 #define PXP2_REG_PSWRQ_BW_ADD1					 0x1201c0
 #define PXP2_REG_PSWRQ_BW_ADD10 				 0x1201e4
 #define PXP2_REG_PSWRQ_BW_ADD11 				 0x1201e8
-#define PXP2_REG_PSWRQ_BW_ADD10 				 0x1201e4
-#define PXP2_REG_PSWRQ_BW_ADD11 				 0x1201e8
 #define PXP2_REG_PSWRQ_BW_ADD2					 0x1201c4
 #define PXP2_REG_PSWRQ_BW_ADD28 				 0x120228
-#define PXP2_REG_PSWRQ_BW_ADD28 				 0x120228
 #define PXP2_REG_PSWRQ_BW_ADD3					 0x1201c8
 #define PXP2_REG_PSWRQ_BW_ADD6					 0x1201d4
 #define PXP2_REG_PSWRQ_BW_ADD7					 0x1201d8
@@ -2156,11 +2007,8 @@
 #define PXP2_REG_PSWRQ_BW_L1					 0x1202b0
 #define PXP2_REG_PSWRQ_BW_L10					 0x1202d4
 #define PXP2_REG_PSWRQ_BW_L11					 0x1202d8
-#define PXP2_REG_PSWRQ_BW_L10					 0x1202d4
-#define PXP2_REG_PSWRQ_BW_L11					 0x1202d8
 #define PXP2_REG_PSWRQ_BW_L2					 0x1202b4
 #define PXP2_REG_PSWRQ_BW_L28					 0x120318
-#define PXP2_REG_PSWRQ_BW_L28					 0x120318
 #define PXP2_REG_PSWRQ_BW_L3					 0x1202b8
 #define PXP2_REG_PSWRQ_BW_L6					 0x1202c4
 #define PXP2_REG_PSWRQ_BW_L7					 0x1202c8
@@ -2170,11 +2018,8 @@
 #define PXP2_REG_PSWRQ_BW_UB1					 0x120238
 #define PXP2_REG_PSWRQ_BW_UB10					 0x12025c
 #define PXP2_REG_PSWRQ_BW_UB11					 0x120260
-#define PXP2_REG_PSWRQ_BW_UB10					 0x12025c
-#define PXP2_REG_PSWRQ_BW_UB11					 0x120260
 #define PXP2_REG_PSWRQ_BW_UB2					 0x12023c
 #define PXP2_REG_PSWRQ_BW_UB28					 0x1202a0
-#define PXP2_REG_PSWRQ_BW_UB28					 0x1202a0
 #define PXP2_REG_PSWRQ_BW_UB3					 0x120240
 #define PXP2_REG_PSWRQ_BW_UB6					 0x12024c
 #define PXP2_REG_PSWRQ_BW_UB7					 0x120250
@@ -2232,6 +2077,9 @@
    allocated for vq22 */
 #define PXP2_REG_RD_MAX_BLKS_VQ22				 0x1203d0
 /* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq25 */
+#define PXP2_REG_RD_MAX_BLKS_VQ25				 0x1203dc
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
    allocated for vq6 */
 #define PXP2_REG_RD_MAX_BLKS_VQ6				 0x120390
 /* [RW 8] The maximum number of blocks in Tetris Buffer that can be
@@ -2762,16 +2610,6 @@
 #define QM_REG_QVOQIDX_107					 0x16e4b8
 #define QM_REG_QVOQIDX_108					 0x16e4bc
 #define QM_REG_QVOQIDX_109					 0x16e4c0
-#define QM_REG_QVOQIDX_100					 0x16e49c
-#define QM_REG_QVOQIDX_101					 0x16e4a0
-#define QM_REG_QVOQIDX_102					 0x16e4a4
-#define QM_REG_QVOQIDX_103					 0x16e4a8
-#define QM_REG_QVOQIDX_104					 0x16e4ac
-#define QM_REG_QVOQIDX_105					 0x16e4b0
-#define QM_REG_QVOQIDX_106					 0x16e4b4
-#define QM_REG_QVOQIDX_107					 0x16e4b8
-#define QM_REG_QVOQIDX_108					 0x16e4bc
-#define QM_REG_QVOQIDX_109					 0x16e4c0
 #define QM_REG_QVOQIDX_11					 0x168120
 #define QM_REG_QVOQIDX_110					 0x16e4c4
 #define QM_REG_QVOQIDX_111					 0x16e4c8
@@ -2783,16 +2621,6 @@
 #define QM_REG_QVOQIDX_117					 0x16e4e0
 #define QM_REG_QVOQIDX_118					 0x16e4e4
 #define QM_REG_QVOQIDX_119					 0x16e4e8
-#define QM_REG_QVOQIDX_110					 0x16e4c4
-#define QM_REG_QVOQIDX_111					 0x16e4c8
-#define QM_REG_QVOQIDX_112					 0x16e4cc
-#define QM_REG_QVOQIDX_113					 0x16e4d0
-#define QM_REG_QVOQIDX_114					 0x16e4d4
-#define QM_REG_QVOQIDX_115					 0x16e4d8
-#define QM_REG_QVOQIDX_116					 0x16e4dc
-#define QM_REG_QVOQIDX_117					 0x16e4e0
-#define QM_REG_QVOQIDX_118					 0x16e4e4
-#define QM_REG_QVOQIDX_119					 0x16e4e8
 #define QM_REG_QVOQIDX_12					 0x168124
 #define QM_REG_QVOQIDX_120					 0x16e4ec
 #define QM_REG_QVOQIDX_121					 0x16e4f0
@@ -2802,14 +2630,6 @@
 #define QM_REG_QVOQIDX_125					 0x16e500
 #define QM_REG_QVOQIDX_126					 0x16e504
 #define QM_REG_QVOQIDX_127					 0x16e508
-#define QM_REG_QVOQIDX_120					 0x16e4ec
-#define QM_REG_QVOQIDX_121					 0x16e4f0
-#define QM_REG_QVOQIDX_122					 0x16e4f4
-#define QM_REG_QVOQIDX_123					 0x16e4f8
-#define QM_REG_QVOQIDX_124					 0x16e4fc
-#define QM_REG_QVOQIDX_125					 0x16e500
-#define QM_REG_QVOQIDX_126					 0x16e504
-#define QM_REG_QVOQIDX_127					 0x16e508
 #define QM_REG_QVOQIDX_13					 0x168128
 #define QM_REG_QVOQIDX_14					 0x16812c
 #define QM_REG_QVOQIDX_15					 0x168130
@@ -2855,16 +2675,6 @@
 #define QM_REG_QVOQIDX_57					 0x1681d8
 #define QM_REG_QVOQIDX_58					 0x1681dc
 #define QM_REG_QVOQIDX_59					 0x1681e0
-#define QM_REG_QVOQIDX_50					 0x1681bc
-#define QM_REG_QVOQIDX_51					 0x1681c0
-#define QM_REG_QVOQIDX_52					 0x1681c4
-#define QM_REG_QVOQIDX_53					 0x1681c8
-#define QM_REG_QVOQIDX_54					 0x1681cc
-#define QM_REG_QVOQIDX_55					 0x1681d0
-#define QM_REG_QVOQIDX_56					 0x1681d4
-#define QM_REG_QVOQIDX_57					 0x1681d8
-#define QM_REG_QVOQIDX_58					 0x1681dc
-#define QM_REG_QVOQIDX_59					 0x1681e0
 #define QM_REG_QVOQIDX_6					 0x16810c
 #define QM_REG_QVOQIDX_60					 0x1681e4
 #define QM_REG_QVOQIDX_61					 0x1681e8
@@ -2872,16 +2682,6 @@
 #define QM_REG_QVOQIDX_63					 0x1681f0
 #define QM_REG_QVOQIDX_64					 0x16e40c
 #define QM_REG_QVOQIDX_65					 0x16e410
-#define QM_REG_QVOQIDX_66					 0x16e414
-#define QM_REG_QVOQIDX_67					 0x16e418
-#define QM_REG_QVOQIDX_68					 0x16e41c
-#define QM_REG_QVOQIDX_69					 0x16e420
-#define QM_REG_QVOQIDX_60					 0x1681e4
-#define QM_REG_QVOQIDX_61					 0x1681e8
-#define QM_REG_QVOQIDX_62					 0x1681ec
-#define QM_REG_QVOQIDX_63					 0x1681f0
-#define QM_REG_QVOQIDX_64					 0x16e40c
-#define QM_REG_QVOQIDX_65					 0x16e410
 #define QM_REG_QVOQIDX_69					 0x16e420
 #define QM_REG_QVOQIDX_7					 0x168110
 #define QM_REG_QVOQIDX_70					 0x16e424
@@ -2894,29 +2694,9 @@
 #define QM_REG_QVOQIDX_77					 0x16e440
 #define QM_REG_QVOQIDX_78					 0x16e444
 #define QM_REG_QVOQIDX_79					 0x16e448
-#define QM_REG_QVOQIDX_70					 0x16e424
-#define QM_REG_QVOQIDX_71					 0x16e428
-#define QM_REG_QVOQIDX_72					 0x16e42c
-#define QM_REG_QVOQIDX_73					 0x16e430
-#define QM_REG_QVOQIDX_74					 0x16e434
-#define QM_REG_QVOQIDX_75					 0x16e438
-#define QM_REG_QVOQIDX_76					 0x16e43c
-#define QM_REG_QVOQIDX_77					 0x16e440
-#define QM_REG_QVOQIDX_78					 0x16e444
-#define QM_REG_QVOQIDX_79					 0x16e448
 #define QM_REG_QVOQIDX_8					 0x168114
 #define QM_REG_QVOQIDX_80					 0x16e44c
 #define QM_REG_QVOQIDX_81					 0x16e450
-#define QM_REG_QVOQIDX_82					 0x16e454
-#define QM_REG_QVOQIDX_83					 0x16e458
-#define QM_REG_QVOQIDX_84					 0x16e45c
-#define QM_REG_QVOQIDX_85					 0x16e460
-#define QM_REG_QVOQIDX_86					 0x16e464
-#define QM_REG_QVOQIDX_87					 0x16e468
-#define QM_REG_QVOQIDX_88					 0x16e46c
-#define QM_REG_QVOQIDX_89					 0x16e470
-#define QM_REG_QVOQIDX_80					 0x16e44c
-#define QM_REG_QVOQIDX_81					 0x16e450
 #define QM_REG_QVOQIDX_85					 0x16e460
 #define QM_REG_QVOQIDX_86					 0x16e464
 #define QM_REG_QVOQIDX_87					 0x16e468
@@ -2933,23 +2713,11 @@
 #define QM_REG_QVOQIDX_97					 0x16e490
 #define QM_REG_QVOQIDX_98					 0x16e494
 #define QM_REG_QVOQIDX_99					 0x16e498
-#define QM_REG_QVOQIDX_90					 0x16e474
-#define QM_REG_QVOQIDX_91					 0x16e478
-#define QM_REG_QVOQIDX_92					 0x16e47c
-#define QM_REG_QVOQIDX_93					 0x16e480
-#define QM_REG_QVOQIDX_94					 0x16e484
-#define QM_REG_QVOQIDX_95					 0x16e488
-#define QM_REG_QVOQIDX_96					 0x16e48c
-#define QM_REG_QVOQIDX_97					 0x16e490
-#define QM_REG_QVOQIDX_98					 0x16e494
-#define QM_REG_QVOQIDX_99					 0x16e498
 /* [RW 1] Initialization bit command */
 #define QM_REG_SOFT_RESET					 0x168428
 /* [RW 8] The credit cost per every task in the QM. A value per each VOQ */
 #define QM_REG_TASKCRDCOST_0					 0x16809c
 #define QM_REG_TASKCRDCOST_1					 0x1680a0
-#define QM_REG_TASKCRDCOST_10					 0x1680c4
-#define QM_REG_TASKCRDCOST_11					 0x1680c8
 #define QM_REG_TASKCRDCOST_2					 0x1680a4
 #define QM_REG_TASKCRDCOST_4					 0x1680ac
 #define QM_REG_TASKCRDCOST_5					 0x1680b0
@@ -2962,24 +2730,18 @@
 /* [R 16] The credit value for each VOQ */
 #define QM_REG_VOQCREDIT_0					 0x1682d0
 #define QM_REG_VOQCREDIT_1					 0x1682d4
-#define QM_REG_VOQCREDIT_10					 0x1682f8
-#define QM_REG_VOQCREDIT_11					 0x1682fc
 #define QM_REG_VOQCREDIT_4					 0x1682e0
 /* [RW 16] The credit value that if above the QM is considered almost full */
 #define QM_REG_VOQCREDITAFULLTHR				 0x168090
 /* [RW 16] The init and maximum credit for each VoQ */
 #define QM_REG_VOQINITCREDIT_0					 0x168060
 #define QM_REG_VOQINITCREDIT_1					 0x168064
-#define QM_REG_VOQINITCREDIT_10 				 0x168088
-#define QM_REG_VOQINITCREDIT_11 				 0x16808c
 #define QM_REG_VOQINITCREDIT_2					 0x168068
 #define QM_REG_VOQINITCREDIT_4					 0x168070
 #define QM_REG_VOQINITCREDIT_5					 0x168074
 /* [RW 1] The port of which VOQ belongs */
 #define QM_REG_VOQPORT_0					 0x1682a0
 #define QM_REG_VOQPORT_1					 0x1682a4
-#define QM_REG_VOQPORT_10					 0x1682c8
-#define QM_REG_VOQPORT_11					 0x1682cc
 #define QM_REG_VOQPORT_2					 0x1682a8
 /* [RW 32] The physical queue number associated with each VOQ; queues 31-0 */
 #define QM_REG_VOQQMASK_0_LSB					 0x168240
@@ -3077,36 +2839,6 @@
 #define QM_REG_WRRWEIGHTS_0					 0x16880c
 #define QM_REG_WRRWEIGHTS_1					 0x168810
 #define QM_REG_WRRWEIGHTS_10					 0x168814
-#define QM_REG_WRRWEIGHTS_10_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_11					 0x168818
-#define QM_REG_WRRWEIGHTS_11_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_12					 0x16881c
-#define QM_REG_WRRWEIGHTS_12_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_13					 0x168820
-#define QM_REG_WRRWEIGHTS_13_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_14					 0x168824
-#define QM_REG_WRRWEIGHTS_14_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_15					 0x168828
-#define QM_REG_WRRWEIGHTS_15_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_16					 0x16e000
-#define QM_REG_WRRWEIGHTS_16_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_17					 0x16e004
-#define QM_REG_WRRWEIGHTS_17_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_18					 0x16e008
-#define QM_REG_WRRWEIGHTS_18_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_19					 0x16e00c
-#define QM_REG_WRRWEIGHTS_19_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_10					 0x168814
 #define QM_REG_WRRWEIGHTS_11					 0x168818
 #define QM_REG_WRRWEIGHTS_12					 0x16881c
 #define QM_REG_WRRWEIGHTS_13					 0x168820
@@ -3118,36 +2850,6 @@
 #define QM_REG_WRRWEIGHTS_19					 0x16e00c
 #define QM_REG_WRRWEIGHTS_2					 0x16882c
 #define QM_REG_WRRWEIGHTS_20					 0x16e010
-#define QM_REG_WRRWEIGHTS_20_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_21					 0x16e014
-#define QM_REG_WRRWEIGHTS_21_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_22					 0x16e018
-#define QM_REG_WRRWEIGHTS_22_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_23					 0x16e01c
-#define QM_REG_WRRWEIGHTS_23_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_24					 0x16e020
-#define QM_REG_WRRWEIGHTS_24_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_25					 0x16e024
-#define QM_REG_WRRWEIGHTS_25_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_26					 0x16e028
-#define QM_REG_WRRWEIGHTS_26_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_27					 0x16e02c
-#define QM_REG_WRRWEIGHTS_27_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_28					 0x16e030
-#define QM_REG_WRRWEIGHTS_28_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_29					 0x16e034
-#define QM_REG_WRRWEIGHTS_29_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_20					 0x16e010
 #define QM_REG_WRRWEIGHTS_21					 0x16e014
 #define QM_REG_WRRWEIGHTS_22					 0x16e018
 #define QM_REG_WRRWEIGHTS_23					 0x16e01c
@@ -3159,12 +2861,6 @@
 #define QM_REG_WRRWEIGHTS_29					 0x16e034
 #define QM_REG_WRRWEIGHTS_3					 0x168830
 #define QM_REG_WRRWEIGHTS_30					 0x16e038
-#define QM_REG_WRRWEIGHTS_30_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_31					 0x16e03c
-#define QM_REG_WRRWEIGHTS_31_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_30					 0x16e038
 #define QM_REG_WRRWEIGHTS_31					 0x16e03c
 #define QM_REG_WRRWEIGHTS_4					 0x168834
 #define QM_REG_WRRWEIGHTS_5					 0x168838
@@ -3174,362 +2870,6 @@
 #define QM_REG_WRRWEIGHTS_9					 0x168848
 /* [R 6] Keep the fill level of the fifo from write client 1 */
 #define QM_REG_XQM_WRC_FIFOLVL					 0x168000
-#define BRB1_BRB1_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define BRB1_BRB1_INT_STS_REG_ADDRESS_ERROR_SIZE		 0
-#define BRB1_BRB1_INT_STS_CLR_REG_ADDRESS_ERROR 		 (0x1<<0)
-#define BRB1_BRB1_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define BRB1_BRB1_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define BRB1_BRB1_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define BRB1_BRB1_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define BRB1_BRB1_INT_MASK_REG_ADDRESS_ERROR_SIZE		 0
-#define CCM_CCM_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CCM_CCM_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define CCM_CCM_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CCM_CCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define CCM_CCM_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CCM_CCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define CCM_CCM_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CCM_CCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define CDU_CDU_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CDU_CDU_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define CDU_CDU_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CDU_CDU_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define CDU_CDU_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CDU_CDU_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define CDU_CDU_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CDU_CDU_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define CFC_CFC_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CFC_CFC_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define CFC_CFC_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CFC_CFC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define CFC_CFC_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CFC_CFC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define CFC_CFC_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CFC_CFC_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define CSDM_CSDM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CSDM_CSDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CSDM_CSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define CSDM_CSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CSDM_CSDM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define CSDM_CSDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CSDM_CSDM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CSDM_CSDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CSEM_CSEM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CSEM_CSEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CSEM_CSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define CSEM_CSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CSEM_CSEM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define CSEM_CSEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CSEM_CSEM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define CSEM_CSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define DBG_DBG_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DBG_DBG_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define DBG_DBG_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DBG_DBG_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define DBG_DBG_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DBG_DBG_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define DBG_DBG_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DBG_DBG_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define DMAE_DMAE_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DMAE_DMAE_INT_STS_REG_ADDRESS_ERROR_SIZE		 0
-#define DMAE_DMAE_INT_STS_CLR_REG_ADDRESS_ERROR 		 (0x1<<0)
-#define DMAE_DMAE_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define DMAE_DMAE_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DMAE_DMAE_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define DMAE_DMAE_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DMAE_DMAE_INT_MASK_REG_ADDRESS_ERROR_SIZE		 0
-#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR_SIZE		 0
-#define DORQ_DORQ_INT_STS_CLR_REG_ADDRESS_ERROR 		 (0x1<<0)
-#define DORQ_DORQ_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define DORQ_DORQ_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DORQ_DORQ_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR_SIZE		 0
-#define HC_HC_INT_STS_REG_ADDRESS_ERROR 			 (0x1<<0)
-#define HC_HC_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define HC_HC_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define HC_HC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define HC_HC_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define HC_HC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 		 0
-#define HC_HC_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define HC_HC_INT_MASK_REG_ADDRESS_ERROR_SIZE			 0
-#define MISC_MISC_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define MISC_MISC_INT_STS_REG_ADDRESS_ERROR_SIZE		 0
-#define MISC_MISC_INT_STS_CLR_REG_ADDRESS_ERROR 		 (0x1<<0)
-#define MISC_MISC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define MISC_MISC_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define MISC_MISC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define MISC_MISC_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define MISC_MISC_INT_MASK_REG_ADDRESS_ERROR_SIZE		 0
-#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define NIG_NIG_INT_STS_CLR_0_REG_ADDRESS_ERROR 		 (0x1<<0)
-#define NIG_NIG_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define NIG_NIG_INT_STS_WR_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define NIG_NIG_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PBF_PBF_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PBF_PBF_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define PBF_PBF_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PBF_PBF_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define PBF_PBF_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PBF_PBF_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define PBF_PBF_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PBF_PBF_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define PB_PB_INT_STS_REG_ADDRESS_ERROR 			 (0x1<<0)
-#define PB_PB_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define PB_PB_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PB_PB_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define PB_PB_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PB_PB_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 		 0
-#define PB_PB_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PB_PB_INT_MASK_REG_ADDRESS_ERROR_SIZE			 0
-#define PRS_PRS_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PRS_PRS_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define PRS_PRS_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PRS_PRS_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define PRS_PRS_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PRS_PRS_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define PRS_PRS_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PRS_PRS_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define PXP2_PXP2_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PXP2_PXP2_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PXP2_PXP2_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define PXP2_PXP2_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PXP2_PXP2_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define PXP2_PXP2_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PXP2_PXP2_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PXP2_PXP2_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PXP_PXP_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PXP_PXP_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PXP_PXP_INT_STS_CLR_0_REG_ADDRESS_ERROR 		 (0x1<<0)
-#define PXP_PXP_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PXP_PXP_INT_STS_WR_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PXP_PXP_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define PXP_PXP_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define PXP_PXP_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define QM_QM_INT_STS_REG_ADDRESS_ERROR 			 (0x1<<0)
-#define QM_QM_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define QM_QM_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define QM_QM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define QM_QM_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define QM_QM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 		 0
-#define QM_QM_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define QM_QM_INT_MASK_REG_ADDRESS_ERROR_SIZE			 0
-#define SEM_FAST_SEM_FAST_INT_STS_REG_ADDRESS_ERROR		 (0x1<<0)
-#define SEM_FAST_SEM_FAST_INT_STS_REG_ADDRESS_ERROR_SIZE	 0
-#define SEM_FAST_SEM_FAST_INT_STS_CLR_REG_ADDRESS_ERROR 	 (0x1<<0)
-#define SEM_FAST_SEM_FAST_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE	 0
-#define SEM_FAST_SEM_FAST_INT_STS_WR_REG_ADDRESS_ERROR		 (0x1<<0)
-#define SEM_FAST_SEM_FAST_INT_STS_WR_REG_ADDRESS_ERROR_SIZE	 0
-#define SEM_FAST_SEM_FAST_INT_MASK_REG_ADDRESS_ERROR		 (0x1<<0)
-#define SEM_FAST_SEM_FAST_INT_MASK_REG_ADDRESS_ERROR_SIZE	 0
-#define SRC_SRC_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define SRC_SRC_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define SRC_SRC_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define SRC_SRC_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define SRC_SRC_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define SRC_SRC_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define SRC_SRC_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define SRC_SRC_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define TCM_TCM_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TCM_TCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define TCM_TCM_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TCM_TCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define TM_TM_INT_STS_REG_ADDRESS_ERROR 			 (0x1<<0)
-#define TM_TM_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define TM_TM_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TM_TM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define TM_TM_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TM_TM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 		 0
-#define TM_TM_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TM_TM_INT_MASK_REG_ADDRESS_ERROR_SIZE			 0
-#define TSDM_TSDM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TSDM_TSDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define TSDM_TSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define TSDM_TSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define TSDM_TSDM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define TSDM_TSDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define TSDM_TSDM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TSDM_TSDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define TSEM_TSEM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TSEM_TSEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define TSEM_TSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define TSEM_TSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define TSEM_TSEM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define TSEM_TSEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define TSEM_TSEM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define TSEM_TSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define UCM_UCM_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define UCM_UCM_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define UCM_UCM_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define UCM_UCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define UCM_UCM_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define UCM_UCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define UCM_UCM_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define UCM_UCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define USDM_USDM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define USDM_USDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define USDM_USDM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define USDM_USDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define USDM_USDM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define USDM_USDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define USDM_USDM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define USDM_USDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define USEM_USEM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define USEM_USEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define USEM_USEM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define USEM_USEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define USEM_USEM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define USEM_USEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define USEM_USEM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define USEM_USEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XCM_XCM_INT_STS_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XCM_XCM_INT_STS_REG_ADDRESS_ERROR_SIZE			 0
-#define XCM_XCM_INT_STS_CLR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XCM_XCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE		 0
-#define XCM_XCM_INT_STS_WR_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XCM_XCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE		 0
-#define XCM_XCM_INT_MASK_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XCM_XCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 		 0
-#define XSDM_XSDM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XSDM_XSDM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XSDM_XSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define XSDM_XSDM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XSDM_XSDM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define XSDM_XSDM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XSDM_XSDM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XSDM_XSDM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XSEM_XSEM_INT_STS_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XSEM_XSEM_INT_STS_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XSEM_XSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define XSEM_XSEM_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XSEM_XSEM_INT_STS_WR_0_REG_ADDRESS_ERROR		 (0x1<<0)
-#define XSEM_XSEM_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE		 0
-#define XSEM_XSEM_INT_MASK_0_REG_ADDRESS_ERROR			 (0x1<<0)
-#define XSEM_XSEM_INT_MASK_0_REG_ADDRESS_ERROR_SIZE		 0
-#define CFC_DEBUG1_REG_WRITE_AC 				 (0x1<<4)
-#define CFC_DEBUG1_REG_WRITE_AC_SIZE				 4
-/* [R 1] debug only: This bit indicates whether indicates that external
-   buffer was wrapped (oldest data was thrown); Relevant only when
-   ~dbg_registers_debug_target=2 (PCI) & ~dbg_registers_full_mode=1 (wrap); */
-#define DBG_REG_WRAP_ON_EXT_BUFFER				 0xc124
-#define DBG_REG_WRAP_ON_EXT_BUFFER_SIZE 			 1
-/* [R 1] debug only: This bit indicates whether the internal buffer was
-   wrapped (oldest data was thrown) Relevant only when
-   ~dbg_registers_debug_target=0 (internal buffer) */
-#define DBG_REG_WRAP_ON_INT_BUFFER				 0xc128
-#define DBG_REG_WRAP_ON_INT_BUFFER_SIZE 			 1
-#define QM_QM_PRTY_STS_REG_WRBUFF				 (0x1<<8)
-#define QM_QM_PRTY_STS_REG_WRBUFF_SIZE				 8
-#define QM_QM_PRTY_STS_CLR_REG_WRBUFF				 (0x1<<8)
-#define QM_QM_PRTY_STS_CLR_REG_WRBUFF_SIZE			 8
-#define QM_QM_PRTY_STS_WR_REG_WRBUFF				 (0x1<<8)
-#define QM_QM_PRTY_STS_WR_REG_WRBUFF_SIZE			 8
-#define QM_QM_PRTY_MASK_REG_WRBUFF				 (0x1<<8)
-#define QM_QM_PRTY_MASK_REG_WRBUFF_SIZE 			 8
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_0					 0x16880c
-#define QM_REG_WRRWEIGHTS_0_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_1					 0x168810
-#define QM_REG_WRRWEIGHTS_1_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_10					 0x168814
-#define QM_REG_WRRWEIGHTS_10_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_11					 0x168818
-#define QM_REG_WRRWEIGHTS_11_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_12					 0x16881c
-#define QM_REG_WRRWEIGHTS_12_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_13					 0x168820
-#define QM_REG_WRRWEIGHTS_13_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_14					 0x168824
-#define QM_REG_WRRWEIGHTS_14_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_15					 0x168828
-#define QM_REG_WRRWEIGHTS_15_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_2					 0x16882c
-#define QM_REG_WRRWEIGHTS_2_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_3					 0x168830
-#define QM_REG_WRRWEIGHTS_3_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_4					 0x168834
-#define QM_REG_WRRWEIGHTS_4_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_5					 0x168838
-#define QM_REG_WRRWEIGHTS_5_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_6					 0x16883c
-#define QM_REG_WRRWEIGHTS_6_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_7					 0x168840
-#define QM_REG_WRRWEIGHTS_7_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_8					 0x168844
-#define QM_REG_WRRWEIGHTS_8_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_9					 0x168848
-#define QM_REG_WRRWEIGHTS_9_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_16					 0x16e000
-#define QM_REG_WRRWEIGHTS_16_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_17					 0x16e004
-#define QM_REG_WRRWEIGHTS_17_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_18					 0x16e008
-#define QM_REG_WRRWEIGHTS_18_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_19					 0x16e00c
-#define QM_REG_WRRWEIGHTS_19_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_20					 0x16e010
-#define QM_REG_WRRWEIGHTS_20_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_21					 0x16e014
-#define QM_REG_WRRWEIGHTS_21_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_22					 0x16e018
-#define QM_REG_WRRWEIGHTS_22_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_23					 0x16e01c
-#define QM_REG_WRRWEIGHTS_23_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_24					 0x16e020
-#define QM_REG_WRRWEIGHTS_24_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_25					 0x16e024
-#define QM_REG_WRRWEIGHTS_25_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_26					 0x16e028
-#define QM_REG_WRRWEIGHTS_26_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_27					 0x16e02c
-#define QM_REG_WRRWEIGHTS_27_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_28					 0x16e030
-#define QM_REG_WRRWEIGHTS_28_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_29					 0x16e034
-#define QM_REG_WRRWEIGHTS_29_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_30					 0x16e038
-#define QM_REG_WRRWEIGHTS_30_SIZE				 1
-/* [RW 32] Wrr weights */
-#define QM_REG_WRRWEIGHTS_31					 0x16e03c
-#define QM_REG_WRRWEIGHTS_31_SIZE				 1
 #define SRC_REG_COUNTFREE0					 0x40500
 /* [RW 1] If clr the searcher is compatible to E1 A0 - support only two
    ports. If set the searcher support 8 functions. */
@@ -3629,12 +2969,6 @@
    type (one of 16). */
 #define TCM_REG_N_SM_CTX_LD_0					 0x50050
 #define TCM_REG_N_SM_CTX_LD_1					 0x50054
-#define TCM_REG_N_SM_CTX_LD_10					 0x50078
-#define TCM_REG_N_SM_CTX_LD_11					 0x5007c
-#define TCM_REG_N_SM_CTX_LD_12					 0x50080
-#define TCM_REG_N_SM_CTX_LD_13					 0x50084
-#define TCM_REG_N_SM_CTX_LD_14					 0x50088
-#define TCM_REG_N_SM_CTX_LD_15					 0x5008c
 #define TCM_REG_N_SM_CTX_LD_2					 0x50058
 #define TCM_REG_N_SM_CTX_LD_3					 0x5005c
 #define TCM_REG_N_SM_CTX_LD_4					 0x50060
@@ -3828,6 +3162,7 @@
 #define TM_REG_LIN0_PHY_ADDR					 0x164270
 /* [RW 1] Linear0 physical address valid. */
 #define TM_REG_LIN0_PHY_ADDR_VALID				 0x164248
+#define TM_REG_LIN0_SCAN_ON					 0x1640d0
 /* [RW 24] Linear0 array scan timeout. */
 #define TM_REG_LIN0_SCAN_TIME					 0x16403c
 /* [RW 32] Linear1 logic address. */
@@ -3840,8 +3175,6 @@
 #define TM_REG_LIN_SETCLR_FIFO_ALFULL_THR			 0x164070
 /* [RW 2] Load value for pci arbiter credit cnt. */
 #define TM_REG_PCIARB_CRDCNT_VAL				 0x164260
-/* [RW 1] Timer software reset - active high. */
-#define TM_REG_TIMER_SOFT_RST					 0x164004
 /* [RW 20] The amount of hardware cycles for each timer tick. */
 #define TM_REG_TIMER_TICK_SIZE					 0x16401c
 /* [RW 8] Timers Context region. */
@@ -3853,44 +3186,12 @@
 /* [RW 8] The event id for aggregated interrupt 0 */
 #define TSDM_REG_AGG_INT_EVENT_0				 0x42038
 #define TSDM_REG_AGG_INT_EVENT_1				 0x4203c
-#define TSDM_REG_AGG_INT_EVENT_10				 0x42060
-#define TSDM_REG_AGG_INT_EVENT_11				 0x42064
-#define TSDM_REG_AGG_INT_EVENT_12				 0x42068
-#define TSDM_REG_AGG_INT_EVENT_13				 0x4206c
-#define TSDM_REG_AGG_INT_EVENT_14				 0x42070
-#define TSDM_REG_AGG_INT_EVENT_15				 0x42074
-#define TSDM_REG_AGG_INT_EVENT_16				 0x42078
-#define TSDM_REG_AGG_INT_EVENT_17				 0x4207c
-#define TSDM_REG_AGG_INT_EVENT_18				 0x42080
-#define TSDM_REG_AGG_INT_EVENT_19				 0x42084
 #define TSDM_REG_AGG_INT_EVENT_2				 0x42040
-#define TSDM_REG_AGG_INT_EVENT_20				 0x42088
-#define TSDM_REG_AGG_INT_EVENT_21				 0x4208c
-#define TSDM_REG_AGG_INT_EVENT_22				 0x42090
-#define TSDM_REG_AGG_INT_EVENT_23				 0x42094
-#define TSDM_REG_AGG_INT_EVENT_24				 0x42098
-#define TSDM_REG_AGG_INT_EVENT_25				 0x4209c
-#define TSDM_REG_AGG_INT_EVENT_26				 0x420a0
-#define TSDM_REG_AGG_INT_EVENT_27				 0x420a4
-#define TSDM_REG_AGG_INT_EVENT_28				 0x420a8
-#define TSDM_REG_AGG_INT_EVENT_29				 0x420ac
 #define TSDM_REG_AGG_INT_EVENT_3				 0x42044
-#define TSDM_REG_AGG_INT_EVENT_30				 0x420b0
-#define TSDM_REG_AGG_INT_EVENT_31				 0x420b4
 #define TSDM_REG_AGG_INT_EVENT_4				 0x42048
 /* [RW 1] The T bit for aggregated interrupt 0 */
 #define TSDM_REG_AGG_INT_T_0					 0x420b8
 #define TSDM_REG_AGG_INT_T_1					 0x420bc
-#define TSDM_REG_AGG_INT_T_10					 0x420e0
-#define TSDM_REG_AGG_INT_T_11					 0x420e4
-#define TSDM_REG_AGG_INT_T_12					 0x420e8
-#define TSDM_REG_AGG_INT_T_13					 0x420ec
-#define TSDM_REG_AGG_INT_T_14					 0x420f0
-#define TSDM_REG_AGG_INT_T_15					 0x420f4
-#define TSDM_REG_AGG_INT_T_16					 0x420f8
-#define TSDM_REG_AGG_INT_T_17					 0x420fc
-#define TSDM_REG_AGG_INT_T_18					 0x42100
-#define TSDM_REG_AGG_INT_T_19					 0x42104
 /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
 #define TSDM_REG_CFC_RSP_START_ADDR				 0x42008
 /* [RW 16] The maximum value of the competion counter #0 */
@@ -4175,12 +3476,6 @@
    connection type (one of 16). */
 #define UCM_REG_N_SM_CTX_LD_0					 0xe0054
 #define UCM_REG_N_SM_CTX_LD_1					 0xe0058
-#define UCM_REG_N_SM_CTX_LD_10					 0xe007c
-#define UCM_REG_N_SM_CTX_LD_11					 0xe0080
-#define UCM_REG_N_SM_CTX_LD_12					 0xe0084
-#define UCM_REG_N_SM_CTX_LD_13					 0xe0088
-#define UCM_REG_N_SM_CTX_LD_14					 0xe008c
-#define UCM_REG_N_SM_CTX_LD_15					 0xe0090
 #define UCM_REG_N_SM_CTX_LD_2					 0xe005c
 #define UCM_REG_N_SM_CTX_LD_3					 0xe0060
 #define UCM_REG_N_SM_CTX_LD_4					 0xe0064
@@ -4330,48 +3625,20 @@
 /* [RW 8] The event id for aggregated interrupt 0 */
 #define USDM_REG_AGG_INT_EVENT_0				 0xc4038
 #define USDM_REG_AGG_INT_EVENT_1				 0xc403c
-#define USDM_REG_AGG_INT_EVENT_10				 0xc4060
-#define USDM_REG_AGG_INT_EVENT_11				 0xc4064
-#define USDM_REG_AGG_INT_EVENT_12				 0xc4068
-#define USDM_REG_AGG_INT_EVENT_13				 0xc406c
-#define USDM_REG_AGG_INT_EVENT_14				 0xc4070
-#define USDM_REG_AGG_INT_EVENT_15				 0xc4074
-#define USDM_REG_AGG_INT_EVENT_16				 0xc4078
-#define USDM_REG_AGG_INT_EVENT_17				 0xc407c
-#define USDM_REG_AGG_INT_EVENT_18				 0xc4080
-#define USDM_REG_AGG_INT_EVENT_19				 0xc4084
 #define USDM_REG_AGG_INT_EVENT_2				 0xc4040
-#define USDM_REG_AGG_INT_EVENT_20				 0xc4088
-#define USDM_REG_AGG_INT_EVENT_21				 0xc408c
-#define USDM_REG_AGG_INT_EVENT_22				 0xc4090
-#define USDM_REG_AGG_INT_EVENT_23				 0xc4094
-#define USDM_REG_AGG_INT_EVENT_24				 0xc4098
-#define USDM_REG_AGG_INT_EVENT_25				 0xc409c
-#define USDM_REG_AGG_INT_EVENT_26				 0xc40a0
-#define USDM_REG_AGG_INT_EVENT_27				 0xc40a4
-#define USDM_REG_AGG_INT_EVENT_28				 0xc40a8
-#define USDM_REG_AGG_INT_EVENT_29				 0xc40ac
-#define USDM_REG_AGG_INT_EVENT_3				 0xc4044
-#define USDM_REG_AGG_INT_EVENT_30				 0xc40b0
-#define USDM_REG_AGG_INT_EVENT_31				 0xc40b4
 #define USDM_REG_AGG_INT_EVENT_4				 0xc4048
 #define USDM_REG_AGG_INT_EVENT_5				 0xc404c
+#define USDM_REG_AGG_INT_EVENT_6				 0xc4050
 /* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
    or auto-mask-mode (1) */
 #define USDM_REG_AGG_INT_MODE_0 				 0xc41b8
 #define USDM_REG_AGG_INT_MODE_1 				 0xc41bc
-#define USDM_REG_AGG_INT_MODE_10				 0xc41e0
-#define USDM_REG_AGG_INT_MODE_11				 0xc41e4
-#define USDM_REG_AGG_INT_MODE_12				 0xc41e8
-#define USDM_REG_AGG_INT_MODE_13				 0xc41ec
-#define USDM_REG_AGG_INT_MODE_14				 0xc41f0
-#define USDM_REG_AGG_INT_MODE_15				 0xc41f4
-#define USDM_REG_AGG_INT_MODE_16				 0xc41f8
-#define USDM_REG_AGG_INT_MODE_17				 0xc41fc
-#define USDM_REG_AGG_INT_MODE_18				 0xc4200
-#define USDM_REG_AGG_INT_MODE_19				 0xc4204
 #define USDM_REG_AGG_INT_MODE_4 				 0xc41c8
 #define USDM_REG_AGG_INT_MODE_5 				 0xc41cc
+#define USDM_REG_AGG_INT_MODE_6 				 0xc41d0
+/* [RW 1] The T bit for aggregated interrupt 5 */
+#define USDM_REG_AGG_INT_T_5					 0xc40cc
+#define USDM_REG_AGG_INT_T_6					 0xc40d0
 /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
 #define USDM_REG_CFC_RSP_START_ADDR				 0xc4008
 /* [RW 16] The maximum value of the competion counter #0 */
@@ -4675,10 +3942,6 @@
 /* [RC 1] Set at message length mismatch (relative to last indication) at
    the nig1 interface. */
 #define XCM_REG_NIG1_LENGTH_MIS 				 0x2023c
-/* [RW 3] The weight of the input nig1 in the WRR mechanism. 0 stands for
-   weight 8 (the most prioritised); 1 stands for weight 1(least
-   prioritised); 2 stands for weight 2; tc. */
-#define XCM_REG_NIG1_WEIGHT					 0x200d8
 /* [RW 5] The number of double REG-pairs; loaded from the STORM context and
    sent to STORM; for a specific connection type. The double REG-pairs are
    used in order to align to STORM context row size of 128 bits. The offset
@@ -4686,12 +3949,6 @@
    connection type (one of 16). */
 #define XCM_REG_N_SM_CTX_LD_0					 0x20060
 #define XCM_REG_N_SM_CTX_LD_1					 0x20064
-#define XCM_REG_N_SM_CTX_LD_10					 0x20088
-#define XCM_REG_N_SM_CTX_LD_11					 0x2008c
-#define XCM_REG_N_SM_CTX_LD_12					 0x20090
-#define XCM_REG_N_SM_CTX_LD_13					 0x20094
-#define XCM_REG_N_SM_CTX_LD_14					 0x20098
-#define XCM_REG_N_SM_CTX_LD_15					 0x2009c
 #define XCM_REG_N_SM_CTX_LD_2					 0x20068
 #define XCM_REG_N_SM_CTX_LD_3					 0x2006c
 #define XCM_REG_N_SM_CTX_LD_4					 0x20070
@@ -4868,30 +4125,8 @@
 #define XSDM_REG_AGG_INT_EVENT_12				 0x166068
 #define XSDM_REG_AGG_INT_EVENT_13				 0x16606c
 #define XSDM_REG_AGG_INT_EVENT_14				 0x166070
-#define XSDM_REG_AGG_INT_EVENT_15				 0x166074
-#define XSDM_REG_AGG_INT_EVENT_16				 0x166078
-#define XSDM_REG_AGG_INT_EVENT_17				 0x16607c
-#define XSDM_REG_AGG_INT_EVENT_18				 0x166080
-#define XSDM_REG_AGG_INT_EVENT_19				 0x166084
-#define XSDM_REG_AGG_INT_EVENT_10				 0x166060
-#define XSDM_REG_AGG_INT_EVENT_11				 0x166064
-#define XSDM_REG_AGG_INT_EVENT_12				 0x166068
-#define XSDM_REG_AGG_INT_EVENT_13				 0x16606c
-#define XSDM_REG_AGG_INT_EVENT_14				 0x166070
 #define XSDM_REG_AGG_INT_EVENT_2				 0x166040
-#define XSDM_REG_AGG_INT_EVENT_20				 0x166088
-#define XSDM_REG_AGG_INT_EVENT_21				 0x16608c
-#define XSDM_REG_AGG_INT_EVENT_22				 0x166090
-#define XSDM_REG_AGG_INT_EVENT_23				 0x166094
-#define XSDM_REG_AGG_INT_EVENT_24				 0x166098
-#define XSDM_REG_AGG_INT_EVENT_25				 0x16609c
-#define XSDM_REG_AGG_INT_EVENT_26				 0x1660a0
-#define XSDM_REG_AGG_INT_EVENT_27				 0x1660a4
-#define XSDM_REG_AGG_INT_EVENT_28				 0x1660a8
-#define XSDM_REG_AGG_INT_EVENT_29				 0x1660ac
 #define XSDM_REG_AGG_INT_EVENT_3				 0x166044
-#define XSDM_REG_AGG_INT_EVENT_30				 0x1660b0
-#define XSDM_REG_AGG_INT_EVENT_31				 0x1660b4
 #define XSDM_REG_AGG_INT_EVENT_4				 0x166048
 #define XSDM_REG_AGG_INT_EVENT_5				 0x16604c
 #define XSDM_REG_AGG_INT_EVENT_6				 0x166050
@@ -4902,16 +4137,6 @@
    or auto-mask-mode (1) */
 #define XSDM_REG_AGG_INT_MODE_0 				 0x1661b8
 #define XSDM_REG_AGG_INT_MODE_1 				 0x1661bc
-#define XSDM_REG_AGG_INT_MODE_10				 0x1661e0
-#define XSDM_REG_AGG_INT_MODE_11				 0x1661e4
-#define XSDM_REG_AGG_INT_MODE_12				 0x1661e8
-#define XSDM_REG_AGG_INT_MODE_13				 0x1661ec
-#define XSDM_REG_AGG_INT_MODE_14				 0x1661f0
-#define XSDM_REG_AGG_INT_MODE_15				 0x1661f4
-#define XSDM_REG_AGG_INT_MODE_16				 0x1661f8
-#define XSDM_REG_AGG_INT_MODE_17				 0x1661fc
-#define XSDM_REG_AGG_INT_MODE_18				 0x166200
-#define XSDM_REG_AGG_INT_MODE_19				 0x166204
 /* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
 #define XSDM_REG_CFC_RSP_START_ADDR				 0x166008
 /* [RW 16] The maximum value of the competion counter #0 */
@@ -5119,10 +4344,6 @@
 #define MCPR_NVM_COMMAND_FIRST					 (1L<<7)
 #define MCPR_NVM_COMMAND_LAST					 (1L<<8)
 #define MCPR_NVM_COMMAND_WR					 (1L<<5)
-#define MCPR_NVM_COMMAND_WREN					 (1L<<16)
-#define MCPR_NVM_COMMAND_WREN_BITSHIFT				 16
-#define MCPR_NVM_COMMAND_WRDI					 (1L<<17)
-#define MCPR_NVM_COMMAND_WRDI_BITSHIFT				 17
 #define MCPR_NVM_SW_ARB_ARB_ARB1				 (1L<<9)
 #define MCPR_NVM_SW_ARB_ARB_REQ_CLR1				 (1L<<5)
 #define MCPR_NVM_SW_ARB_ARB_REQ_SET1				 (1L<<1)
@@ -5223,10 +4444,6 @@
 #define MISC_REGISTERS_SPIO_7					 7
 #define MISC_REGISTERS_SPIO_CLR_POS				 16
 #define MISC_REGISTERS_SPIO_FLOAT				 (0xffL<<24)
-#define GRC_MISC_REGISTERS_SPIO_FLOAT7				 0x80000000
-#define GRC_MISC_REGISTERS_SPIO_FLOAT6				 0x40000000
-#define GRC_MISC_REGISTERS_SPIO_FLOAT5				 0x20000000
-#define GRC_MISC_REGISTERS_SPIO_FLOAT4				 0x10000000
 #define MISC_REGISTERS_SPIO_FLOAT_POS				 24
 #define MISC_REGISTERS_SPIO_INPUT_HI_Z				 2
 #define MISC_REGISTERS_SPIO_INT_OLD_SET_POS			 16
@@ -5344,7 +4561,8 @@
 #define LATCHED_ATTN_SCPAD_PARITY_MCP		33
 
 #define GENERAL_ATTEN_WORD(atten_name)	       ((94 + atten_name) / 32)
-#define GENERAL_ATTEN_OFFSET(atten_name)       (1 << ((94 + atten_name) % 32))
+#define GENERAL_ATTEN_OFFSET(atten_name)\
+	(1UL << ((94 + atten_name) % 32))
 /*
  * This file defines GRC base address for every block.
  * This file is included by chipsim, asm microcode and cpp microcode.
@@ -5568,6 +4786,9 @@
 #define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR		0x0080
 
 #define MDIO_REG_BANK_RX0				0x80b0
+#define MDIO_RX0_RX_STATUS				0x10
+#define MDIO_RX0_RX_STATUS_SIGDET			0x8000
+#define MDIO_RX0_RX_STATUS_RX_SEQ_DONE			0x1000
 #define MDIO_RX0_RX_EQ_BOOST				0x1c
 #define MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK	0x7
 #define MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL		0x10
@@ -5761,12 +4982,22 @@
 #define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT				7
 #define MDIO_OVER_1G_LP_UP3						0x1E
 
+#define MDIO_REG_BANK_REMOTE_PHY			0x8330
+#define MDIO_REMOTE_PHY_MISC_RX_STATUS				0x10
+#define MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG	0x0010
+#define MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG	0x0600
+
 #define MDIO_REG_BANK_BAM_NEXT_PAGE			0x8350
 #define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL			0x10
 #define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE			0x0001
 #define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN			0x0002
 
 #define MDIO_REG_BANK_CL73_USERB0		0x8370
+#define MDIO_CL73_USERB0_CL73_UCTRL				0x10
+#define MDIO_CL73_USERB0_CL73_UCTRL_USTAT1_MUXSEL			0x0002
+#define MDIO_CL73_USERB0_CL73_USTAT1				0x11
+#define MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK			0x0100
+#define MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37		0x0400
 #define MDIO_CL73_USERB0_CL73_BAM_CTRL1 			0x12
 #define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN				0x8000
 #define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN		0x4000
@@ -5843,25 +5074,33 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_PMA_REG_ROM_VER2		0xca1a
 #define MDIO_PMA_REG_EDC_FFE_MAIN	0xca1b
 #define MDIO_PMA_REG_PLL_BANDWIDTH	0xca1d
-#define MDIO_PMA_REG_GEN_CTRL2		0xca1e
+#define MDIO_PMA_REG_PLL_CTRL		0xca1e
 #define MDIO_PMA_REG_MISC_CTRL0 	0xca23
 #define MDIO_PMA_REG_LRM_MODE		0xca3f
 #define MDIO_PMA_REG_CDR_BANDWIDTH	0xca46
 #define MDIO_PMA_REG_MISC_CTRL1 	0xca85
 
-#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL 	0x8000
-#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK	0x000c
-#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE		0x0000
-#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE	0x0004
-#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IN_PROGRESS	0x0008
-#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_FAILED	0x000c
-#define MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT	0x8002
-#define MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR	0x8003
+#define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL		0x8000
+#define MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK	0x000c
+#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE		0x0000
+#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE	0x0004
+#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IN_PROGRESS	0x0008
+#define MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_FAILED 	0x000c
+#define MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT	0x8002
+#define MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR	0x8003
 #define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF	0xc820
 #define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
 #define MDIO_PMA_REG_8726_TX_CTRL1		0xca01
 #define MDIO_PMA_REG_8726_TX_CTRL2		0xca05
 
+#define MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR	0x8005
+#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF	0x8007
+#define MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK 0xff
+#define MDIO_PMA_REG_8727_MISC_CTRL		0x8309
+#define MDIO_PMA_REG_8727_TX_CTRL1		0xca02
+#define MDIO_PMA_REG_8727_TX_CTRL2		0xca05
+#define MDIO_PMA_REG_8727_PCS_OPT_CTRL		0xc808
+#define MDIO_PMA_REG_8727_GPIO_CTRL		0xc80e
 
 #define MDIO_PMA_REG_8073_CHIP_REV			0xc801
 #define MDIO_PMA_REG_8073_SPEED_LINK_STATUS		0xc820
@@ -5872,6 +5111,13 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_PMA_REG_7101_VER1		0xc026
 #define MDIO_PMA_REG_7101_VER2		0xc027
 
+#define MDIO_PMA_REG_8481_PMD_SIGNAL	0xa811
+#define MDIO_PMA_REG_8481_LED1_MASK	0xa82c
+#define MDIO_PMA_REG_8481_LED2_MASK	0xa82f
+#define MDIO_PMA_REG_8481_LED3_MASK	0xa832
+#define MDIO_PMA_REG_8481_SIGNAL_MASK	0xa835
+#define MDIO_PMA_REG_8481_LINK_SIGNAL	0xa83b
+
 
 #define MDIO_WIS_DEVAD			0x2
 /*bcm*/
@@ -5925,6 +5171,12 @@ Theotherbitsarereservedandshouldbezero*/
 
 #define MDIO_AN_REG_8073_2_5G		0x8329
 
+#define MDIO_AN_REG_8481_LEGACY_MII_CTRL	0xffe0
+#define MDIO_AN_REG_8481_LEGACY_AN_ADV		0xffe4
+#define MDIO_AN_REG_8481_1000T_CTRL		0xffe9
+#define MDIO_AN_REG_8481_EXPANSION_REG_RD_RW	0xfff5
+#define MDIO_AN_REG_8481_EXPANSION_REG_ACCESS	0xfff7
+#define MDIO_AN_REG_8481_LEGACY_SHADOW		0xfffc
 
 #define IGU_FUNC_BASE			0x0400
 
@@ -5957,3 +5209,116 @@ Theotherbitsarereservedandshouldbezero*/
 #define COMMAND_REG_SIMD_NOMASK     0x1c
 
 
+#define IGU_MEM_BASE						0x0000
+
+#define IGU_MEM_MSIX_BASE					0x0000
+#define IGU_MEM_MSIX_UPPER					0x007f
+#define IGU_MEM_MSIX_RESERVED_UPPER			0x01ff
+
+#define IGU_MEM_PBA_MSIX_BASE				0x0200
+#define IGU_MEM_PBA_MSIX_UPPER				0x0200
+
+#define IGU_CMD_BACKWARD_COMP_PROD_UPD		0x0201
+#define IGU_MEM_PBA_MSIX_RESERVED_UPPER 	0x03ff
+
+#define IGU_CMD_INT_ACK_BASE				0x0400
+#define IGU_CMD_INT_ACK_UPPER\
+	(IGU_CMD_INT_ACK_BASE + MAX_SB_PER_PORT * NUM_OF_PORTS_PER_PATH - 1)
+#define IGU_CMD_INT_ACK_RESERVED_UPPER		0x04ff
+
+#define IGU_CMD_E2_PROD_UPD_BASE			0x0500
+#define IGU_CMD_E2_PROD_UPD_UPPER\
+	(IGU_CMD_E2_PROD_UPD_BASE + MAX_SB_PER_PORT * NUM_OF_PORTS_PER_PATH - 1)
+#define IGU_CMD_E2_PROD_UPD_RESERVED_UPPER	0x059f
+
+#define IGU_CMD_ATTN_BIT_UPD_UPPER			0x05a0
+#define IGU_CMD_ATTN_BIT_SET_UPPER			0x05a1
+#define IGU_CMD_ATTN_BIT_CLR_UPPER			0x05a2
+
+#define IGU_REG_SISR_MDPC_WMASK_UPPER		0x05a3
+#define IGU_REG_SISR_MDPC_WMASK_LSB_UPPER	0x05a4
+#define IGU_REG_SISR_MDPC_WMASK_MSB_UPPER	0x05a5
+#define IGU_REG_SISR_MDPC_WOMASK_UPPER		0x05a6
+
+#define IGU_REG_RESERVED_UPPER				0x05ff
+
+
+#define CDU_REGION_NUMBER_XCM_AG 2
+#define CDU_REGION_NUMBER_UCM_AG 4
+
+
+/**
+ * String-to-compress [31:8] = CID (all 24 bits)
+ * String-to-compress [7:4] = Region
+ * String-to-compress [3:0] = Type
+ */
+#define CDU_VALID_DATA(_cid, _region, _type)\
+	(((_cid) << 8) | (((_region)&0xf)<<4) | (((_type)&0xf)))
+#define CDU_CRC8(_cid, _region, _type)\
+	(calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff))
+#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type)\
+	(0x80 | ((CDU_CRC8(_cid, _region, _type)) & 0x7f))
+#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type)\
+	(0x80 | ((_type)&0xf << 3) | ((CDU_CRC8(_cid, _region, _type)) & 0x7))
+#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
+
+/******************************************************************************
+ * Description:
+ *	   Calculates crc 8 on a word value: polynomial 0-1-2-8
+ *	   Code was translated from Verilog.
+ * Return:
+ *****************************************************************************/
+static inline u8 calc_crc8(u32 data, u8 crc)
+{
+	u8 D[32];
+	u8 NewCRC[8];
+	u8 C[8];
+	u8 crc_res;
+	u8 i;
+
+	/* split the data into 31 bits */
+	for (i = 0; i < 32; i++) {
+		D[i] = (u8)(data & 1);
+		data = data >> 1;
+	}
+
+	/* split the crc into 8 bits */
+	for (i = 0; i < 8; i++) {
+		C[i] = crc & 1;
+		crc = crc >> 1;
+	}
+
+	NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
+		    D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
+		    C[6] ^ C[7];
+	NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
+		    D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
+		    D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^
+		    C[6];
+	NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
+		    D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
+		    C[0] ^ C[1] ^ C[4] ^ C[5];
+	NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
+		    D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
+		    C[1] ^ C[2] ^ C[5] ^ C[6];
+	NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
+		    D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
+		    C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
+	NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
+		    D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
+		    C[3] ^ C[4] ^ C[7];
+	NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
+		    D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
+		    C[5];
+	NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
+		    D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
+		    C[6];
+
+	crc_res = 0;
+	for (i = 0; i < 8; i++)
+		crc_res |= (NewCRC[i] << i);
+
+	return crc_res;
+}
+
+
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index d4b5708..cea5cfe 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -1109,7 +1109,8 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 			//mux machine in case of EXPIRED even if LINK_DOWN didn't arrive for the port.
 			port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION;
 			port->sm_vars &= ~AD_PORT_MATCHED;
-			port->partner_oper.port_state |= AD_SHORT_TIMEOUT;
+			port->partner_oper.port_state |=
+				AD_STATE_LACP_ACTIVITY;
 			port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT));
 			port->actor_oper_port_state |= AD_STATE_EXPIRED;
 			break;
@@ -1123,7 +1124,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
 			// detect loopback situation
 			if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
 				// INFO_RECEIVED_LOOPBACK_FRAMES
-				printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
+				pr_err(DRV_NAME ": %s: An illegal loopback occurred on "
 				       "adapter (%s). Check the configuration to verify that all "
 				       "Adapters are connected to 802.3ad compliant switch ports\n",
 				       port->slave->dev->master->name, port->slave->dev->name);
@@ -1305,11 +1306,13 @@ static void ad_port_selection_logic(struct port *port)
 			}
 		}
 		if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
-			printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
-			       "related to aggregator %d but was not on its port list\n",
-			       port->slave->dev->master->name,
-			       port->actor_port_number, port->slave->dev->name,
-			       port->aggregator->aggregator_identifier);
+			pr_warning(DRV_NAME ": %s: Warning: Port %d (on %s) "
+				   "was related to aggregator %d but was not "
+				   "on its port list\n",
+				   port->slave->dev->master->name,
+				   port->actor_port_number,
+				   port->slave->dev->name,
+				   port->aggregator->aggregator_identifier);
 		}
 	}
 	// search on all aggregators for a suitable aggregator for this port
@@ -1378,7 +1381,8 @@ static void ad_port_selection_logic(struct port *port)
 
 			pr_debug("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
 		} else {
-			printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
+			pr_err(DRV_NAME ": %s: Port %d (on %s) did not find "
+			       "a suitable aggregator\n",
 			       port->slave->dev->master->name,
 			       port->actor_port_number, port->slave->dev->name);
 		}
@@ -1455,10 +1459,10 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best,
 		break;
 
 	default:
-		printk(KERN_WARNING DRV_NAME
-		       ": %s: Impossible agg select mode %d\n",
-		       curr->slave->dev->master->name,
-		       __get_agg_selection_mode(curr->lag_ports));
+		pr_warning(DRV_NAME
+			   ": %s: Impossible agg select mode %d\n",
+			   curr->slave->dev->master->name,
+			   __get_agg_selection_mode(curr->lag_ports));
 		break;
 	}
 
@@ -1561,7 +1565,7 @@ static void ad_agg_selection_logic(struct aggregator *agg)
 
 		// check if any partner replys
 		if (best->is_individual) {
-			printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad"
+			pr_warning(DRV_NAME ": %s: Warning: No 802.3ad"
 			       " response from the link partner for any"
 			       " adapters in the bond\n",
 			       best->slave->dev->master->name);
@@ -1884,7 +1888,8 @@ int bond_3ad_bind_slave(struct slave *slave)
 	struct aggregator *aggregator;
 
 	if (bond == NULL) {
-		printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
+		pr_err(DRV_NAME ": %s: The slave %s is not attached to "
+		       "its bond\n",
 		       slave->dev->master->name, slave->dev->name);
 		return -1;
 	}
@@ -1960,9 +1965,9 @@ void bond_3ad_unbind_slave(struct slave *slave)
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
-		       "unbind an uninitialized port on %s\n",
-		       slave->dev->master->name, slave->dev->name);
+		pr_warning(DRV_NAME ": Warning: %s: Trying to "
+			   "unbind an uninitialized port on %s\n",
+			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -1993,8 +1998,8 @@ void bond_3ad_unbind_slave(struct slave *slave)
 				pr_debug("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
 
 				if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
-					printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
-					       aggregator->slave->dev->master->name);
+					pr_info(DRV_NAME ": %s: Removing an active aggregator\n",
+						aggregator->slave->dev->master->name);
 					// select new active aggregator
 					 select_new_active_agg = 1;
 				}
@@ -2024,17 +2029,17 @@ void bond_3ad_unbind_slave(struct slave *slave)
 					ad_agg_selection_logic(__get_first_agg(port));
 				}
 			} else {
-				printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
-				       "and could not find a new aggregator for its ports\n",
-				       slave->dev->master->name);
+				pr_warning(DRV_NAME ": %s: Warning: unbinding aggregator, "
+					   "and could not find a new aggregator for its ports\n",
+					   slave->dev->master->name);
 			}
 		} else { // in case that the only port related to this aggregator is the one we want to remove
 			select_new_active_agg = aggregator->is_active;
 			// clear the aggregator
 			ad_clear_agg(aggregator);
 			if (select_new_active_agg) {
-				printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
-				       slave->dev->master->name);
+				pr_info(DRV_NAME ": %s: Removing an active aggregator\n",
+					slave->dev->master->name);
 				// select new active aggregator
 				ad_agg_selection_logic(__get_first_agg(port));
 			}
@@ -2060,8 +2065,8 @@ void bond_3ad_unbind_slave(struct slave *slave)
 					// clear the aggregator
 					ad_clear_agg(temp_aggregator);
 					if (select_new_active_agg) {
-						printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
-						       slave->dev->master->name);
+						pr_info(DRV_NAME ": %s: Removing an active aggregator\n",
+							slave->dev->master->name);
 						// select new active aggregator
 						ad_agg_selection_logic(__get_first_agg(port));
 					}
@@ -2109,8 +2114,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
 		// select the active aggregator for the bond
 		if ((port = __get_first_port(bond))) {
 			if (!port->slave) {
-				printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
-				       "uninitialized\n", bond->dev->name);
+				pr_warning(DRV_NAME ": %s: Warning: bond's first port is "
+					   "uninitialized\n", bond->dev->name);
 				goto re_arm;
 			}
 
@@ -2123,8 +2128,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
 	// for each port run the state machines
 	for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
 		if (!port->slave) {
-			printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
-			       "port\n", bond->dev->name);
+			pr_warning(DRV_NAME ": %s: Warning: Found an uninitialized "
+				   "port\n", bond->dev->name);
 			goto re_arm;
 		}
 
@@ -2165,8 +2170,9 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
 		port = &(SLAVE_AD_INFO(slave).port);
 
 		if (!port->slave) {
-			printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
-			       "uninitialized\n", slave->dev->name, slave->dev->master->name);
+			pr_warning(DRV_NAME ": %s: Warning: port of slave %s "
+				   "is uninitialized\n",
+				   slave->dev->name, slave->dev->master->name);
 			return;
 		}
 
@@ -2211,9 +2217,9 @@ void bond_3ad_adapter_speed_changed(struct slave *slave)
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
-		       "changed for uninitialized port on %s\n",
-		       slave->dev->master->name, slave->dev->name);
+		pr_warning(DRV_NAME ": Warning: %s: speed "
+			   "changed for uninitialized port on %s\n",
+			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2239,9 +2245,9 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave)
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
-		       "for uninitialized port on %s\n",
-		       slave->dev->master->name, slave->dev->name);
+		pr_warning(DRV_NAME ": %s: Warning: duplex changed "
+			   "for uninitialized port on %s\n",
+			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2268,9 +2274,9 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
-		       "uninitialized port on %s\n",
-			slave->dev->master->name, slave->dev->name);
+		pr_warning(DRV_NAME ": Warning: %s: link status changed for "
+			   "uninitialized port on %s\n",
+			   slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2374,8 +2380,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
-		printk(KERN_DEBUG DRV_NAME ": %s: Error: "
-		       "bond_3ad_get_active_agg_info failed\n", dev->name);
+		pr_debug(DRV_NAME ": %s: Error: "
+			 "bond_3ad_get_active_agg_info failed\n", dev->name);
 		goto out;
 	}
 
@@ -2384,9 +2390,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 
 	if (slaves_in_agg == 0) {
 		/*the aggregator is empty*/
-		printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
-		       "aggregator is empty\n",
-		       dev->name);
+		pr_debug(DRV_NAME ": %s: Error: active aggregator is empty\n",
+			 dev->name);
 		goto out;
 	}
 
@@ -2404,7 +2409,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	if (slave_agg_no >= 0) {
-		printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
+		pr_err(DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
 		       "for aggregator ID %d\n", dev->name, agg_id);
 		goto out;
 	}
@@ -2431,7 +2436,7 @@ out:
 		dev_kfree_skb(skb);
 	}
 	read_unlock(&bond->lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 46d312b..9b5936f 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -79,8 +79,15 @@
  */
 #define RLB_PROMISC_TIMEOUT	10*ALB_TIMER_TICKS_PER_SEC
 
-static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
-static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01};
+#ifndef __long_aligned
+#define __long_aligned __attribute__((aligned((sizeof(long)))))
+#endif
+static const u8 mac_bcast[ETH_ALEN] __long_aligned = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+static const u8 mac_v6_allmcast[ETH_ALEN] __long_aligned = {
+	0x33, 0x33, 0x00, 0x00, 0x00, 0x01
+};
 static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
 
 #pragma pack(1)
@@ -194,7 +201,7 @@ static int tlb_initialize(struct bonding *bond)
 
 	new_hashtbl = kzalloc(size, GFP_KERNEL);
 	if (!new_hashtbl) {
-		printk(KERN_ERR DRV_NAME
+		pr_err(DRV_NAME
 		       ": %s: Error: Failed to allocate TLB hash table\n",
 		       bond->dev->name);
 		return -1;
@@ -460,8 +467,8 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
 
 			if (assigned_slave) {
 				rx_hash_table[index].slave = assigned_slave;
-				if (memcmp(rx_hash_table[index].mac_dst,
-					   mac_bcast, ETH_ALEN)) {
+				if (compare_ether_addr_64bits(rx_hash_table[index].mac_dst,
+							      mac_bcast)) {
 					bond_info->rx_hashtbl[index].ntt = 1;
 					bond_info->rx_ntt = 1;
 					/* A slave has been removed from the
@@ -510,7 +517,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
 				 client_info->slave->dev->dev_addr,
 				 client_info->mac_dst);
 		if (!skb) {
-			printk(KERN_ERR DRV_NAME
+			pr_err(DRV_NAME
 			       ": %s: Error: failed to create an ARP packet\n",
 			       client_info->slave->dev->master->name);
 			continue;
@@ -521,7 +528,7 @@ static void rlb_update_client(struct rlb_client_info *client_info)
 		if (client_info->tag) {
 			skb = vlan_put_tag(skb, client_info->vlan_id);
 			if (!skb) {
-				printk(KERN_ERR DRV_NAME
+				pr_err(DRV_NAME
 				       ": %s: Error: failed to insert VLAN tag\n",
 				       client_info->slave->dev->master->name);
 				continue;
@@ -575,7 +582,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla
 		client_info = &(bond_info->rx_hashtbl[hash_index]);
 
 		if ((client_info->slave == slave) &&
-		    memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+		    compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
 			client_info->ntt = 1;
 			ntt = 1;
 		}
@@ -605,7 +612,7 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
 		client_info = &(bond_info->rx_hashtbl[hash_index]);
 
 		if (!client_info->slave) {
-			printk(KERN_ERR DRV_NAME
+			pr_err(DRV_NAME
 			       ": %s: Error: found a client with no channel in "
 			       "the client's hash table\n",
 			       bond->dev->name);
@@ -616,9 +623,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
 		 * unicast mac address.
 		 */
 		if ((client_info->ip_src == src_ip) &&
-		    memcmp(client_info->slave->dev->dev_addr,
-			   bond->dev->dev_addr, ETH_ALEN) &&
-		    memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+		    compare_ether_addr_64bits(client_info->slave->dev->dev_addr,
+			   bond->dev->dev_addr) &&
+		    compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
 			client_info->ntt = 1;
 			bond_info->rx_ntt = 1;
 		}
@@ -645,7 +652,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
 		if ((client_info->ip_src == arp->ip_src) &&
 		    (client_info->ip_dst == arp->ip_dst)) {
 			/* the entry is already assigned to this client */
-			if (memcmp(arp->mac_dst, mac_bcast, ETH_ALEN)) {
+			if (compare_ether_addr_64bits(arp->mac_dst, mac_bcast)) {
 				/* update mac address from arp */
 				memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
 			}
@@ -680,7 +687,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
 		memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
 		client_info->slave = assigned_slave;
 
-		if (memcmp(client_info->mac_dst, mac_bcast, ETH_ALEN)) {
+		if (compare_ether_addr_64bits(client_info->mac_dst, mac_bcast)) {
 			client_info->ntt = 1;
 			bond->alb_info.rx_ntt = 1;
 		} else {
@@ -802,7 +809,7 @@ static int rlb_initialize(struct bonding *bond)
 
 	new_hashtbl = kmalloc(size, GFP_KERNEL);
 	if (!new_hashtbl) {
-		printk(KERN_ERR DRV_NAME
+		pr_err(DRV_NAME
 		       ": %s: Error: Failed to allocate RLB hash table\n",
 		       bond->dev->name);
 		return -1;
@@ -924,7 +931,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
 
 			skb = vlan_put_tag(skb, vlan->vlan_id);
 			if (!skb) {
-				printk(KERN_ERR DRV_NAME
+				pr_err(DRV_NAME
 				       ": %s: Error: failed to insert VLAN tag\n",
 				       bond->dev->name);
 				continue;
@@ -954,7 +961,7 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
 	memcpy(s_addr.sa_data, addr, dev->addr_len);
 	s_addr.sa_family = dev->type;
 	if (dev_set_mac_address(dev, &s_addr)) {
-		printk(KERN_ERR DRV_NAME
+		pr_err(DRV_NAME
 		       ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
 		       "mode requires that the base driver support setting "
 		       "the hw address also when the network device's "
@@ -1046,21 +1053,18 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
 	int perm_curr_diff;
 	int perm_bond_diff;
 
-	perm_curr_diff = memcmp(slave->perm_hwaddr,
-				slave->dev->dev_addr,
-				ETH_ALEN);
-	perm_bond_diff = memcmp(slave->perm_hwaddr,
-				bond->dev->dev_addr,
-				ETH_ALEN);
+	perm_curr_diff = compare_ether_addr_64bits(slave->perm_hwaddr,
+						   slave->dev->dev_addr);
+	perm_bond_diff = compare_ether_addr_64bits(slave->perm_hwaddr,
+						   bond->dev->dev_addr);
 
 	if (perm_curr_diff && perm_bond_diff) {
 		struct slave *tmp_slave;
 		int i, found = 0;
 
 		bond_for_each_slave(bond, tmp_slave, i) {
-			if (!memcmp(slave->perm_hwaddr,
-				    tmp_slave->dev->dev_addr,
-				    ETH_ALEN)) {
+			if (!compare_ether_addr_64bits(slave->perm_hwaddr,
+						       tmp_slave->dev->dev_addr)) {
 				found = 1;
 				break;
 			}
@@ -1114,10 +1118,10 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
 	 * check uniqueness of slave's mac address against the other
 	 * slaves in the bond.
 	 */
-	if (memcmp(slave->perm_hwaddr, bond->dev->dev_addr, ETH_ALEN)) {
+	if (compare_ether_addr_64bits(slave->perm_hwaddr, bond->dev->dev_addr)) {
 		bond_for_each_slave(bond, tmp_slave1, i) {
-			if (!memcmp(tmp_slave1->dev->dev_addr, slave->dev->dev_addr,
-				    ETH_ALEN)) {
+			if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr,
+						       slave->dev->dev_addr)) {
 				found = 1;
 				break;
 			}
@@ -1140,9 +1144,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
 	bond_for_each_slave(bond, tmp_slave1, i) {
 		found = 0;
 		bond_for_each_slave(bond, tmp_slave2, j) {
-			if (!memcmp(tmp_slave1->perm_hwaddr,
-				    tmp_slave2->dev->dev_addr,
-				    ETH_ALEN)) {
+			if (!compare_ether_addr_64bits(tmp_slave1->perm_hwaddr,
+						       tmp_slave2->dev->dev_addr)) {
 				found = 1;
 				break;
 			}
@@ -1157,9 +1160,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
 		}
 
 		if (!has_bond_addr) {
-			if (!memcmp(tmp_slave1->dev->dev_addr,
-				    bond->dev->dev_addr,
-				    ETH_ALEN)) {
+			if (!compare_ether_addr_64bits(tmp_slave1->dev->dev_addr,
+						       bond->dev->dev_addr)) {
 
 				has_bond_addr = tmp_slave1;
 			}
@@ -1170,13 +1172,15 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
 		alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
 				       bond->alb_info.rlb_enabled);
 
-		printk(KERN_WARNING DRV_NAME
-		       ": %s: Warning: the hw address of slave %s is in use by "
-		       "the bond; giving it the hw address of %s\n",
-		       bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
+		pr_warning(DRV_NAME
+			   ": %s: Warning: the hw address of slave %s is "
+			   "in use by the bond; giving it the hw address "
+			   "of %s\n",
+			   bond->dev->name, slave->dev->name,
+			   free_mac_slave->dev->name);
 
 	} else if (has_bond_addr) {
-		printk(KERN_ERR DRV_NAME
+		pr_err(DRV_NAME
 		       ": %s: Error: the hw address of slave %s is in use by the "
 		       "bond; couldn't find a slave with a free hw address to "
 		       "give it (this should not have happened)\n",
@@ -1311,7 +1315,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
 	case ETH_P_IP: {
 		const struct iphdr *iph = ip_hdr(skb);
 
-		if ((memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) ||
+		if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast) ||
 		    (iph->daddr == ip_bcast) ||
 		    (iph->protocol == IPPROTO_IGMP)) {
 			do_tx_balance = 0;
@@ -1325,7 +1329,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
 		/* IPv6 doesn't really use broadcast mac address, but leave
 		 * that here just in case.
 		 */
-		if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
+		if (!compare_ether_addr_64bits(eth_data->h_dest, mac_bcast)) {
 			do_tx_balance = 0;
 			break;
 		}
@@ -1333,7 +1337,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
 		/* IPv6 uses all-nodes multicast as an equivalent to
 		 * broadcasts in IPv4.
 		 */
-		if (memcmp(eth_data->h_dest, mac_v6_allmcast, ETH_ALEN) == 0) {
+		if (!compare_ether_addr_64bits(eth_data->h_dest, mac_v6_allmcast)) {
 			do_tx_balance = 0;
 			break;
 		}
@@ -1413,7 +1417,7 @@ out:
 	}
 	read_unlock(&bond->curr_slave_lock);
 	read_unlock(&bond->lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 void bond_alb_monitor(struct work_struct *work)
@@ -1658,8 +1662,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
 		struct slave *tmp_slave;
 		/* find slave that is holding the bond's mac address */
 		bond_for_each_slave(bond, tmp_slave, i) {
-			if (!memcmp(tmp_slave->dev->dev_addr,
-				    bond->dev->dev_addr, ETH_ALEN)) {
+			if (!compare_ether_addr_64bits(tmp_slave->dev->dev_addr,
+						       bond->dev->dev_addr)) {
 				swap_slave = tmp_slave;
 				break;
 			}
@@ -1737,7 +1741,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
 	swap_slave = NULL;
 
 	bond_for_each_slave(bond, slave, i) {
-		if (!memcmp(slave->dev->dev_addr, bond_dev->dev_addr, ETH_ALEN)) {
+		if (!compare_ether_addr_64bits(slave->dev->dev_addr,
+					       bond_dev->dev_addr)) {
 			swap_slave = slave;
 			break;
 		}
diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c
index 0d73bf5..83921ab 100644
--- a/drivers/net/bonding/bond_ipv6.c
+++ b/drivers/net/bonding/bond_ipv6.c
@@ -79,14 +79,14 @@ static void bond_na_send(struct net_device *slave_dev,
 			      ND_OPT_TARGET_LL_ADDR);
 
 	if (!skb) {
-		printk(KERN_ERR DRV_NAME ": NA packet allocation failed\n");
+		pr_err(DRV_NAME ": NA packet allocation failed\n");
 		return;
 	}
 
 	if (vlan_id) {
 		skb = vlan_put_tag(skb, vlan_id);
 		if (!skb) {
-			printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n");
+			pr_err(DRV_NAME ": failed to insert VLAN tag\n");
 			return;
 		}
 	}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index aa1be1f..69c5b15 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -695,6 +695,9 @@ static int bond_check_dev_link(struct bonding *bond,
 	struct ifreq ifr;
 	struct mii_ioctl_data *mii;
 
+	if (!reporting && !netif_running(slave_dev))
+		return 0;
+
 	if (bond->params.use_carrier)
 		return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
 
@@ -1090,15 +1093,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
 			return NULL; /* still no slave, return NULL */
 	}
 
-	/*
-	 * first try the primary link; if arping, a link must tx/rx
-	 * traffic before it can be considered the curr_active_slave.
-	 * also, we would skip slaves between the curr_active_slave
-	 * and primary_slave that may be up and able to arp
-	 */
 	if ((bond->primary_slave) &&
-	    (!bond->params.arp_interval) &&
-	    (IS_UP(bond->primary_slave->dev))) {
+	    bond->primary_slave->link == BOND_LINK_UP) {
 		new_active = bond->primary_slave;
 	}
 
@@ -1106,15 +1102,14 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
 	old_active = new_active;
 
 	bond_for_each_slave_from(bond, new_active, i, old_active) {
-		if (IS_UP(new_active->dev)) {
-			if (new_active->link == BOND_LINK_UP) {
-				return new_active;
-			} else if (new_active->link == BOND_LINK_BACK) {
-				/* link up, but waiting for stabilization */
-				if (new_active->delay < mintime) {
-					mintime = new_active->delay;
-					bestslave = new_active;
-				}
+		if (new_active->link == BOND_LINK_UP) {
+			return new_active;
+		} else if (new_active->link == BOND_LINK_BACK &&
+			   IS_UP(new_active->dev)) {
+			/* link up, but waiting for stabilization */
+			if (new_active->delay < mintime) {
+				mintime = new_active->delay;
+				bestslave = new_active;
 			}
 		}
 	}
@@ -1208,7 +1203,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 			write_unlock_bh(&bond->curr_slave_lock);
 			read_unlock(&bond->lock);
 
-			netdev_bonding_change(bond->dev);
+			netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER);
 
 			read_lock(&bond->lock);
 			write_lock_bh(&bond->curr_slave_lock);
@@ -1331,6 +1326,7 @@ static int bond_compute_features(struct bonding *bond)
 	struct slave *slave;
 	struct net_device *bond_dev = bond->dev;
 	unsigned long features = bond_dev->features;
+	unsigned long vlan_features = 0;
 	unsigned short max_hard_header_len = max((u16)ETH_HLEN,
 						bond_dev->hard_header_len);
 	int i;
@@ -1343,10 +1339,14 @@ static int bond_compute_features(struct bonding *bond)
 
 	features &= ~NETIF_F_ONE_FOR_ALL;
 
+	vlan_features = bond->first_slave->dev->vlan_features;
 	bond_for_each_slave(bond, slave, i) {
 		features = netdev_increment_features(features,
 						     slave->dev->features,
 						     NETIF_F_ONE_FOR_ALL);
+		vlan_features = netdev_increment_features(vlan_features,
+							slave->dev->vlan_features,
+							NETIF_F_ONE_FOR_ALL);
 		if (slave->dev->hard_header_len > max_hard_header_len)
 			max_hard_header_len = slave->dev->hard_header_len;
 	}
@@ -1354,6 +1354,7 @@ static int bond_compute_features(struct bonding *bond)
 done:
 	features |= (bond_dev->features & BOND_VLAN_FEATURES);
 	bond_dev->features = netdev_fix_features(features, NULL);
+	bond_dev->vlan_features = netdev_fix_features(vlan_features, NULL);
 	bond_dev->hard_header_len = max_hard_header_len;
 
 	return 0;
@@ -1460,14 +1461,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	 */
 	if (bond->slave_cnt == 0) {
 		if (bond_dev->type != slave_dev->type) {
-			dev_close(bond_dev);
 			pr_debug("%s: change device type from %d to %d\n",
 				bond_dev->name, bond_dev->type, slave_dev->type);
+
+			netdev_bonding_change(bond_dev, NETDEV_BONDING_OLDTYPE);
+
 			if (slave_dev->type != ARPHRD_ETHER)
 				bond_setup_by_slave(bond_dev, slave_dev);
 			else
 				ether_setup(bond_dev);
-			dev_open(bond_dev);
+
+			netdev_bonding_change(bond_dev, NETDEV_BONDING_NEWTYPE);
 		}
 	} else if (bond_dev->type != slave_dev->type) {
 		pr_err(DRV_NAME ": %s ether type (%d) is different "
@@ -1790,7 +1794,6 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave, *oldcurrent;
 	struct sockaddr addr;
-	int mac_addr_differ;
 
 	/* slave is not a slave or master is not master of this slave */
 	if (!(slave_dev->flags & IFF_SLAVE) ||
@@ -1814,9 +1817,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	}
 
 	if (!bond->params.fail_over_mac) {
-		mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
-					 ETH_ALEN);
-		if (!mac_addr_differ && (bond->slave_cnt > 1))
+		if (!compare_ether_addr(bond_dev->dev_addr, slave->perm_hwaddr)
+		    && bond->slave_cnt > 1)
 			pr_warning(DRV_NAME
 			       ": %s: Warning: the permanent HWaddr of %s - "
 			       "%pM - is still in use by %s. "
@@ -2922,18 +2924,6 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
 		}
 	}
 
-	read_lock(&bond->curr_slave_lock);
-
-	/*
-	 * Trigger a commit if the primary option setting has changed.
-	 */
-	if (bond->primary_slave &&
-	    (bond->primary_slave != bond->curr_active_slave) &&
-	    (bond->primary_slave->link == BOND_LINK_UP))
-		commit++;
-
-	read_unlock(&bond->curr_slave_lock);
-
 	return commit;
 }
 
@@ -2954,90 +2944,58 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
 			continue;
 
 		case BOND_LINK_UP:
-			write_lock_bh(&bond->curr_slave_lock);
-
-			if (!bond->curr_active_slave &&
-			    time_before_eq(jiffies, dev_trans_start(slave->dev) +
-					   delta_in_ticks)) {
+			if ((!bond->curr_active_slave &&
+			     time_before_eq(jiffies,
+					    dev_trans_start(slave->dev) +
+					    delta_in_ticks)) ||
+			    bond->curr_active_slave != slave) {
 				slave->link = BOND_LINK_UP;
-				bond_change_active_slave(bond, slave);
 				bond->current_arp_slave = NULL;
 
 				pr_info(DRV_NAME
-				       ": %s: %s is up and now the "
-				       "active interface\n",
-				       bond->dev->name, slave->dev->name);
-
-			} else if (bond->curr_active_slave != slave) {
-				/* this slave has just come up but we
-				 * already have a current slave; this can
-				 * also happen if bond_enslave adds a new
-				 * slave that is up while we are searching
-				 * for a new slave
-				 */
-				slave->link = BOND_LINK_UP;
-				bond_set_slave_inactive_flags(slave);
-				bond->current_arp_slave = NULL;
+					": %s: link status definitely "
+					"up for interface %s.\n",
+					bond->dev->name, slave->dev->name);
 
-				pr_info(DRV_NAME
-				       ": %s: backup interface %s is now up\n",
-				       bond->dev->name, slave->dev->name);
-			}
+				if (!bond->curr_active_slave ||
+				    (slave == bond->primary_slave))
+					goto do_failover;
 
-			write_unlock_bh(&bond->curr_slave_lock);
+			}
 
-			break;
+			continue;
 
 		case BOND_LINK_DOWN:
 			if (slave->link_failure_count < UINT_MAX)
 				slave->link_failure_count++;
 
 			slave->link = BOND_LINK_DOWN;
+			bond_set_slave_inactive_flags(slave);
 
-			if (slave == bond->curr_active_slave) {
-				pr_info(DRV_NAME
-				       ": %s: link status down for active "
-				       "interface %s, disabling it\n",
-				       bond->dev->name, slave->dev->name);
-
-				bond_set_slave_inactive_flags(slave);
-
-				write_lock_bh(&bond->curr_slave_lock);
-
-				bond_select_active_slave(bond);
-				if (bond->curr_active_slave)
-					bond->curr_active_slave->jiffies =
-						jiffies;
-
-				write_unlock_bh(&bond->curr_slave_lock);
+			pr_info(DRV_NAME
+				": %s: link status definitely down for "
+				"interface %s, disabling it\n",
+				bond->dev->name, slave->dev->name);
 
+			if (slave == bond->curr_active_slave) {
 				bond->current_arp_slave = NULL;
-
-			} else if (slave->state == BOND_STATE_BACKUP) {
-				pr_info(DRV_NAME
-				       ": %s: backup interface %s is now down\n",
-				       bond->dev->name, slave->dev->name);
-
-				bond_set_slave_inactive_flags(slave);
+				goto do_failover;
 			}
-			break;
+
+			continue;
 
 		default:
 			pr_err(DRV_NAME
 			       ": %s: impossible: new_link %d on slave %s\n",
 			       bond->dev->name, slave->new_link,
 			       slave->dev->name);
+			continue;
 		}
-	}
 
-	/*
-	 * No race with changes to primary via sysfs, as we hold rtnl.
-	 */
-	if (bond->primary_slave &&
-	    (bond->primary_slave != bond->curr_active_slave) &&
-	    (bond->primary_slave->link == BOND_LINK_UP)) {
+do_failover:
+		ASSERT_RTNL();
 		write_lock_bh(&bond->curr_slave_lock);
-		bond_change_active_slave(bond, bond->primary_slave);
+		bond_select_active_slave(bond);
 		write_unlock_bh(&bond->curr_slave_lock);
 	}
 
@@ -4285,7 +4243,7 @@ out:
 		dev_kfree_skb(skb);
 	}
 	read_unlock(&bond->lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
@@ -4316,7 +4274,7 @@ out:
 
 	read_unlock(&bond->curr_slave_lock);
 	read_unlock(&bond->lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -4362,7 +4320,7 @@ out:
 		dev_kfree_skb(skb);
 	}
 	read_unlock(&bond->lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -4422,7 +4380,7 @@ out:
 
 	/* frame sent to all suitable interfaces */
 	read_unlock(&bond->lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*------------------------- Device initialization ---------------------------*/
@@ -4443,7 +4401,7 @@ static void bond_set_xmit_hash_policy(struct bonding *bond)
 	}
 }
 
-static int bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	const struct bonding *bond = netdev_priv(dev);
 
@@ -4755,7 +4713,7 @@ static int bond_check_params(struct bond_params *params)
 		params->ad_select = BOND_AD_STABLE;
 	}
 
-	if (max_bonds < 0 || max_bonds > INT_MAX) {
+	if (max_bonds < 0) {
 		pr_warning(DRV_NAME
 		       ": Warning: max_bonds (%d) not in range %d-%d, so it "
 		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
@@ -4837,7 +4795,7 @@ static int bond_check_params(struct bond_params *params)
 	}
 
 	if (bond_mode == BOND_MODE_ALB) {
-		printk(KERN_NOTICE DRV_NAME
+		pr_notice(DRV_NAME
 		       ": In ALB mode you might experience client "
 		       "disconnections upon reconnection of a link if the "
 		       "bonding module updelay parameter (%d msec) is "
@@ -4961,9 +4919,9 @@ static int bond_check_params(struct bond_params *params)
 		       arp_ip_count);
 
 		for (i = 0; i < arp_ip_count; i++)
-			printk(" %s", arp_ip_target[i]);
+			pr_info(" %s", arp_ip_target[i]);
 
-		printk("\n");
+		pr_info("\n");
 
 	} else if (max_bonds) {
 		/* miimon and arp_interval not set, we need one so things
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 55bf34f..6044e12 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -218,9 +218,8 @@ static ssize_t bonding_store_slaves(struct device *d,
 
 	/* Quick sanity check -- is the bond interface up? */
 	if (!(bond->dev->flags & IFF_UP)) {
-		printk(KERN_WARNING DRV_NAME
-		       ": %s: doing slave updates when interface is down.\n",
-		       bond->dev->name);
+		pr_warning(DRV_NAME ": %s: doing slave updates when "
+			   "interface is down.\n", bond->dev->name);
 	}
 
 	/* Note:  We can't hold bond->lock here, as bond_create grabs it. */
@@ -778,12 +777,14 @@ static ssize_t bonding_store_downdelay(struct device *d,
 		goto out;
 	} else {
 		if ((new_value % bond->params.miimon) != 0) {
-			printk(KERN_WARNING DRV_NAME
-			       ": %s: Warning: down delay (%d) is not a multiple "
-			       "of miimon (%d), delay rounded to %d ms\n",
-			       bond->dev->name, new_value, bond->params.miimon,
-			       (new_value / bond->params.miimon) *
-			       bond->params.miimon);
+			pr_warning(DRV_NAME
+				   ": %s: Warning: down delay (%d) is not a "
+				   "multiple of miimon (%d), delay rounded "
+				   "to %d ms\n",
+				   bond->dev->name, new_value,
+				   bond->params.miimon,
+				   (new_value / bond->params.miimon) *
+				   bond->params.miimon);
 		}
 		bond->params.downdelay = new_value / bond->params.miimon;
 		pr_info(DRV_NAME ": %s: Setting down delay to %d.\n",
@@ -838,12 +839,14 @@ static ssize_t bonding_store_updelay(struct device *d,
 		goto out;
 	} else {
 		if ((new_value % bond->params.miimon) != 0) {
-			printk(KERN_WARNING DRV_NAME
-			       ": %s: Warning: up delay (%d) is not a multiple "
-			       "of miimon (%d), updelay rounded to %d ms\n",
-			       bond->dev->name, new_value, bond->params.miimon,
-			       (new_value / bond->params.miimon) *
-			       bond->params.miimon);
+			pr_warning(DRV_NAME
+				   ": %s: Warning: up delay (%d) is not a "
+				   "multiple of miimon (%d), updelay rounded "
+				   "to %d ms\n",
+				   bond->dev->name, new_value,
+				   bond->params.miimon,
+				   (new_value / bond->params.miimon) *
+				   bond->params.miimon);
 		}
 		bond->params.updelay = new_value / bond->params.miimon;
 		pr_info(DRV_NAME ": %s: Setting up delay to %d.\n",
@@ -1299,9 +1302,9 @@ static ssize_t bonding_store_active_slave(struct device *d,
         			new_active = slave;
         			if (new_active == old_active) {
 					/* do nothing */
-					printk(KERN_INFO DRV_NAME
-				       	       ": %s: %s is already the current active slave.\n",
-				               bond->dev->name, slave->dev->name);
+					pr_info(DRV_NAME
+						": %s: %s is already the current active slave.\n",
+						bond->dev->name, slave->dev->name);
 					goto out;
 				}
 				else {
@@ -1309,17 +1312,17 @@ static ssize_t bonding_store_active_slave(struct device *d,
             				    (old_active) &&
 				            (new_active->link == BOND_LINK_UP) &&
 				            IS_UP(new_active->dev)) {
-						printk(KERN_INFO DRV_NAME
-				       	              ": %s: Setting %s as active slave.\n",
-				                      bond->dev->name, slave->dev->name);
-                				bond_change_active_slave(bond, new_active);
+						pr_info(DRV_NAME
+							": %s: Setting %s as active slave.\n",
+							bond->dev->name, slave->dev->name);
+							bond_change_active_slave(bond, new_active);
         				}
 					else {
-						printk(KERN_INFO DRV_NAME
-				       	              ": %s: Could not set %s as active slave; "
-						      "either %s is down or the link is down.\n",
-				                      bond->dev->name, slave->dev->name,
-						      slave->dev->name);
+						pr_info(DRV_NAME
+							": %s: Could not set %s as active slave; "
+							"either %s is down or the link is down.\n",
+							bond->dev->name, slave->dev->name,
+							slave->dev->name);
 					}
 					goto out;
 				}
@@ -1537,8 +1540,8 @@ int bond_create_sysfs(void)
 		/* Is someone being kinky and naming a device bonding_master? */
 		if (__dev_get_by_name(&init_net,
 				      class_attr_bonding_masters.attr.name))
-			printk(KERN_ERR
-			       "network device named %s already exists in sysfs",
+			pr_err("network device named %s already "
+			       "exists in sysfs",
 			       class_attr_bonding_masters.attr.name);
 		ret = 0;
 	}
@@ -1566,7 +1569,7 @@ int bond_create_sysfs_entry(struct bonding *bond)
 
 	err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
 	if (err)
-		printk(KERN_EMERG "eek! didn't create group!\n");
+		pr_emerg("eek! didn't create group!\n");
 
 	return err;
 }
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 6290a50..6824771 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -163,9 +163,9 @@ struct slave {
 	u32    original_flags;
 	u32    original_mtu;
 	u32    link_failure_count;
+	u8     perm_hwaddr[ETH_ALEN];
 	u16    speed;
 	u8     duplex;
-	u8     perm_hwaddr[ETH_ALEN];
 	struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
 	struct tlb_slave_info tlb_info;
 };
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 33821a8..0900743 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -41,6 +41,13 @@ config CAN_SJA1000
 	---help---
 	  Driver for the SJA1000 CAN controllers from Philips or NXP
 
+config CAN_SJA1000_ISA
+	depends on CAN_SJA1000 && ISA
+	tristate "ISA Bus based legacy SJA1000 driver"
+	---help---
+	  This driver adds legacy support for SJA1000 chips connected to
+	  the ISA bus using I/O port, memory mapped or indirect access.
+
 config CAN_SJA1000_PLATFORM
 	depends on CAN_SJA1000
 	tristate "Generic Platform Bus based SJA1000 driver"
@@ -61,11 +68,12 @@ config CAN_SJA1000_OF_PLATFORM
 	  you may want to enable this option.
 
 config CAN_EMS_PCI
-	tristate "EMS CPC-PCI and CPC-PCIe Card"
+	tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
 	depends on PCI && CAN_SJA1000
 	---help---
-	  This driver is for the one or two channel CPC-PCI and CPC-PCIe
-	  cards from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+	  This driver is for the one, two or four channel CPC-PCI,
+	  CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
+	  (http://www.ems-wuensche.de).
 
 config CAN_KVASER_PCI
 	tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index e1a4f82..f0b9a1e 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -315,7 +315,7 @@ void can_get_echo_skb(struct net_device *dev, int idx)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
-	if ((dev->flags & IFF_ECHO) && priv->echo_skb[idx]) {
+	if (priv->echo_skb[idx]) {
 		netif_rx(priv->echo_skb[idx]);
 		priv->echo_skb[idx] = NULL;
 	}
@@ -323,6 +323,22 @@ void can_get_echo_skb(struct net_device *dev, int idx)
 EXPORT_SYMBOL_GPL(can_get_echo_skb);
 
 /*
+  * Remove the skb from the stack and free it.
+  *
+  * The function is typically called when TX failed.
+  */
+void can_free_echo_skb(struct net_device *dev, int idx)
+{
+	struct can_priv *priv = netdev_priv(dev);
+
+	if (priv->echo_skb[idx]) {
+		kfree_skb(priv->echo_skb[idx]);
+		priv->echo_skb[idx] = NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(can_free_echo_skb);
+
+/*
  * CAN device restart for bus-off recovery
  */
 void can_restart(unsigned long data)
@@ -357,7 +373,6 @@ void can_restart(unsigned long data)
 
 	netif_rx(skb);
 
-	dev->last_rx = jiffies;
 	stats->rx_packets++;
 	stats->rx_bytes += cf->can_dlc;
 
diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile
index 9d0c08d..9d245ac 100644
--- a/drivers/net/can/sja1000/Makefile
+++ b/drivers/net/can/sja1000/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_CAN_SJA1000) += sja1000.o
+obj-$(CONFIG_CAN_SJA1000_ISA) += sja1000_isa.o
 obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
 obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
 obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c
index 121b641..7d84b8a 100644
--- a/drivers/net/can/sja1000/ems_pci.c
+++ b/drivers/net/can/sja1000/ems_pci.c
@@ -32,13 +32,16 @@
 #define DRV_NAME  "ems_pci"
 
 MODULE_AUTHOR("Sebastian Haas <haas@ems-wuenche.com>");
-MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe CAN cards");
-MODULE_SUPPORTED_DEVICE("EMS CPC-PCI/PCIe CAN card");
+MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe/104P CAN cards");
+MODULE_SUPPORTED_DEVICE("EMS CPC-PCI/PCIe/104P CAN card");
 MODULE_LICENSE("GPL v2");
 
-#define EMS_PCI_MAX_CHAN 2
+#define EMS_PCI_V1_MAX_CHAN 2
+#define EMS_PCI_V2_MAX_CHAN 4
+#define EMS_PCI_MAX_CHAN    EMS_PCI_V2_MAX_CHAN
 
 struct ems_pci_card {
+	int version;
 	int channels;
 
 	struct pci_dev *pci_dev;
@@ -63,12 +66,22 @@ struct ems_pci_card {
 #define PITA2_MISC_CONFIG   0x04000000	/* Multiplexed parallel interface */
 
 /*
+ * Register definitions for the PLX 9030
+ */
+#define PLX_ICSR            0x4c   /* Interrupt Control/Status register */
+#define PLX_ICSR_LINTI1_ENA 0x0001 /* LINTi1 Enable */
+#define PLX_ICSR_PCIINT_ENA 0x0040 /* PCI Interrupt Enable */
+#define PLX_ICSR_LINTI1_CLR 0x0400 /* Local Edge Triggerable Interrupt Clear */
+#define PLX_ICSR_ENA_CLR    (PLX_ICSR_LINTI1_ENA | PLX_ICSR_PCIINT_ENA | \
+			     PLX_ICSR_LINTI1_CLR)
+
+/*
  * The board configuration is probably following:
  * RX1 is connected to ground.
  * TX1 is not connected.
  * CLKO is not connected.
  * Setting the OCR register to 0xDA is a good idea.
- * This means  normal output mode , push-pull and the correct polarity.
+ * This means normal output mode, push-pull and the correct polarity.
  */
 #define EMS_PCI_OCR         (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
 
@@ -79,17 +92,21 @@ struct ems_pci_card {
  * is driven by the first one CLKOUT output.
  */
 #define EMS_PCI_CDR             (CDR_CBP | CDR_CLKOUT_MASK)
-#define EMS_PCI_MEM_SIZE        4096  /* Size of the remapped io-memory */
+
+#define EMS_PCI_V1_BASE_BAR     1
+#define EMS_PCI_V1_MEM_SIZE     4096
+#define EMS_PCI_V2_BASE_BAR     2
+#define EMS_PCI_V2_MEM_SIZE     128
 #define EMS_PCI_CAN_BASE_OFFSET 0x400 /* offset where the controllers starts */
 #define EMS_PCI_CAN_CTRL_SIZE   0x200 /* memory size for each controller */
 
-#define EMS_PCI_PORT_BYTES  0x4     /* Each register occupies 4 bytes */
-
-#define EMS_PCI_VENDOR_ID   0x110a  /* PCI device and vendor ID */
-#define EMS_PCI_DEVICE_ID   0x2104
-
 static struct pci_device_id ems_pci_tbl[] = {
-	{EMS_PCI_VENDOR_ID, EMS_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	/* CPC-PCI v1 */
+	{PCI_VENDOR_ID_SIEMENS, 0x2104, PCI_ANY_ID, PCI_ANY_ID,},
+	/* CPC-PCI v2 */
+	{PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_PLX, 0x4000},
+	/* CPC-104P v2 */
+	{PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_PLX, 0x4002},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, ems_pci_tbl);
@@ -97,28 +114,47 @@ MODULE_DEVICE_TABLE(pci, ems_pci_tbl);
 /*
  * Helper to read internal registers from card logic (not CAN)
  */
-static u8 ems_pci_readb(struct ems_pci_card *card, unsigned int port)
+static u8 ems_pci_v1_readb(struct ems_pci_card *card, unsigned int port)
 {
-	return readb(card->base_addr + (port * EMS_PCI_PORT_BYTES));
+	return readb(card->base_addr + (port * 4));
 }
 
-static u8 ems_pci_read_reg(const struct sja1000_priv *priv, int port)
+static u8 ems_pci_v1_read_reg(const struct sja1000_priv *priv, int port)
 {
-	return readb(priv->reg_base + (port * EMS_PCI_PORT_BYTES));
+	return readb(priv->reg_base + (port * 4));
 }
 
-static void ems_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val)
+static void ems_pci_v1_write_reg(const struct sja1000_priv *priv,
+				 int port, u8 val)
 {
-	writeb(val, priv->reg_base + (port * EMS_PCI_PORT_BYTES));
+	writeb(val, priv->reg_base + (port * 4));
 }
 
-static void ems_pci_post_irq(const struct sja1000_priv *priv)
+static void ems_pci_v1_post_irq(const struct sja1000_priv *priv)
 {
 	struct ems_pci_card *card = (struct ems_pci_card *)priv->priv;
 
 	/* reset int flag of pita */
-	writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0, card->conf_addr
-		+ PITA2_ICR);
+	writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0,
+	       card->conf_addr + PITA2_ICR);
+}
+
+static u8 ems_pci_v2_read_reg(const struct sja1000_priv *priv, int port)
+{
+	return readb(priv->reg_base + port);
+}
+
+static void ems_pci_v2_write_reg(const struct sja1000_priv *priv,
+				 int port, u8 val)
+{
+	writeb(val, priv->reg_base + port);
+}
+
+static void ems_pci_v2_post_irq(const struct sja1000_priv *priv)
+{
+	struct ems_pci_card *card = (struct ems_pci_card *)priv->priv;
+
+	writel(PLX_ICSR_ENA_CLR, card->conf_addr + PLX_ICSR);
 }
 
 /*
@@ -130,12 +166,12 @@ static inline int ems_pci_check_chan(const struct sja1000_priv *priv)
 	unsigned char res;
 
 	/* Make sure SJA1000 is in reset mode */
-	ems_pci_write_reg(priv, REG_MOD, 1);
+	priv->write_reg(priv, REG_MOD, 1);
 
-	ems_pci_write_reg(priv, REG_CDR, CDR_PELICAN);
+	priv->write_reg(priv, REG_CDR, CDR_PELICAN);
 
 	/* read reset-values */
-	res = ems_pci_read_reg(priv, REG_CDR);
+	res = priv->read_reg(priv, REG_CDR);
 
 	if (res == CDR_PELICAN)
 		return 1;
@@ -188,6 +224,7 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev,
 	struct sja1000_priv *priv;
 	struct net_device *dev;
 	struct ems_pci_card *card;
+	int max_chan, mem_size, base_bar;
 	int err, i;
 
 	/* Enabling PCI device */
@@ -210,37 +247,52 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev,
 
 	card->channels = 0;
 
-	/* Remap PITA configuration space, and controller memory area */
-	card->conf_addr = pci_iomap(pdev, 0, EMS_PCI_MEM_SIZE);
+	if (pdev->vendor == PCI_VENDOR_ID_PLX) {
+		card->version = 2; /* CPC-PCI v2 */
+		max_chan = EMS_PCI_V2_MAX_CHAN;
+		base_bar = EMS_PCI_V2_BASE_BAR;
+		mem_size = EMS_PCI_V2_MEM_SIZE;
+	} else {
+		card->version = 1; /* CPC-PCI v1 */
+		max_chan = EMS_PCI_V1_MAX_CHAN;
+		base_bar = EMS_PCI_V1_BASE_BAR;
+		mem_size = EMS_PCI_V1_MEM_SIZE;
+	}
+
+	/* Remap configuration space and controller memory area */
+	card->conf_addr = pci_iomap(pdev, 0, mem_size);
 	if (card->conf_addr == NULL) {
 		err = -ENOMEM;
 		goto failure_cleanup;
 	}
 
-	card->base_addr = pci_iomap(pdev, 1, EMS_PCI_MEM_SIZE);
+	card->base_addr = pci_iomap(pdev, base_bar, mem_size);
 	if (card->base_addr == NULL) {
 		err = -ENOMEM;
 		goto failure_cleanup;
 	}
 
-	/* Configure PITA-2 parallel interface (enable MUX) */
-	writel(PITA2_MISC_CONFIG, card->conf_addr + PITA2_MISC);
-
-	/* Check for unique EMS CAN signature */
-	if (ems_pci_readb(card, 0) != 0x55 ||
-	    ems_pci_readb(card, 1) != 0xAA ||
-	    ems_pci_readb(card, 2) != 0x01 ||
-	    ems_pci_readb(card, 3) != 0xCB ||
-	    ems_pci_readb(card, 4) != 0x11) {
-		dev_err(&pdev->dev, "Not EMS Dr. Thomas Wuensche interface\n");
-		err = -ENODEV;
-		goto failure_cleanup;
+	if (card->version == 1) {
+		/* Configure PITA-2 parallel interface (enable MUX) */
+		writel(PITA2_MISC_CONFIG, card->conf_addr + PITA2_MISC);
+
+		/* Check for unique EMS CAN signature */
+		if (ems_pci_v1_readb(card, 0) != 0x55 ||
+		    ems_pci_v1_readb(card, 1) != 0xAA ||
+		    ems_pci_v1_readb(card, 2) != 0x01 ||
+		    ems_pci_v1_readb(card, 3) != 0xCB ||
+		    ems_pci_v1_readb(card, 4) != 0x11) {
+			dev_err(&pdev->dev,
+				"Not EMS Dr. Thomas Wuensche interface\n");
+			err = -ENODEV;
+			goto failure_cleanup;
+		}
 	}
 
 	ems_pci_card_reset(card);
 
 	/* Detect available channels */
-	for (i = 0; i < EMS_PCI_MAX_CHAN; i++) {
+	for (i = 0; i < max_chan; i++) {
 		dev = alloc_sja1000dev(0);
 		if (dev == NULL) {
 			err = -ENOMEM;
@@ -255,20 +307,32 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev,
 		dev->irq = pdev->irq;
 		priv->reg_base = card->base_addr + EMS_PCI_CAN_BASE_OFFSET
 					+ (i * EMS_PCI_CAN_CTRL_SIZE);
+		if (card->version == 1) {
+			priv->read_reg  = ems_pci_v1_read_reg;
+			priv->write_reg = ems_pci_v1_write_reg;
+			priv->post_irq  = ems_pci_v1_post_irq;
+		} else {
+			priv->read_reg  = ems_pci_v2_read_reg;
+			priv->write_reg = ems_pci_v2_write_reg;
+			priv->post_irq  = ems_pci_v2_post_irq;
+		}
 
 		/* Check if channel is present */
 		if (ems_pci_check_chan(priv)) {
-			priv->read_reg  = ems_pci_read_reg;
-			priv->write_reg = ems_pci_write_reg;
-			priv->post_irq  = ems_pci_post_irq;
 			priv->can.clock.freq = EMS_PCI_CAN_CLOCK;
 			priv->ocr = EMS_PCI_OCR;
 			priv->cdr = EMS_PCI_CDR;
 
 			SET_NETDEV_DEV(dev, &pdev->dev);
 
-			/* Enable interrupts from card */
-			writel(PITA2_ICR_INT0_EN, card->conf_addr + PITA2_ICR);
+			if (card->version == 1)
+				/* reset int flag of pita */
+				writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0,
+				       card->conf_addr + PITA2_ICR);
+			else
+				/* enable IRQ in PLX 9030 */
+				writel(PLX_ICSR_ENA_CLR,
+				       card->conf_addr + PLX_ICSR);
 
 			/* Register SJA1000 device */
 			err = register_sja1000dev(dev);
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 08ebee7..16d2ecd 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -238,10 +238,10 @@ static void chipset_init(struct net_device *dev)
  * xx xx xx xx	 ff	 ll   00 11 22 33 44 55 66 77
  * [  can-id ] [flags] [len] [can data (up to 8 bytes]
  */
-static int sja1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	struct sja1000_priv *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	struct can_frame *cf = (struct can_frame *)skb->data;
 	uint8_t fi;
 	uint8_t dlc;
@@ -275,14 +275,13 @@ static int sja1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	for (i = 0; i < dlc; i++)
 		priv->write_reg(priv, dreg++, cf->data[i]);
 
-	stats->tx_bytes += dlc;
 	dev->trans_start = jiffies;
 
 	can_put_echo_skb(skb, dev, 0);
 
 	priv->write_reg(priv, REG_CMR, CMD_TR);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void sja1000_rx(struct net_device *dev)
@@ -339,7 +338,6 @@ static void sja1000_rx(struct net_device *dev)
 
 	netif_rx(skb);
 
-	dev->last_rx = jiffies;
 	stats->rx_packets++;
 	stats->rx_bytes += dlc;
 }
@@ -427,7 +425,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 		dev_dbg(dev->dev.parent, "arbitration lost interrupt\n");
 		alc = priv->read_reg(priv, REG_ALC);
 		priv->can.can_stats.arbitration_lost++;
-		stats->rx_errors++;
+		stats->tx_errors++;
 		cf->can_id |= CAN_ERR_LOSTARB;
 		cf->data[0] = alc & 0x1f;
 	}
@@ -454,7 +452,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 
 	netif_rx(skb);
 
-	dev->last_rx = jiffies;
 	stats->rx_packets++;
 	stats->rx_bytes += cf->can_dlc;
 
@@ -485,6 +482,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
 
 		if (isrc & IRQ_TI) {
 			/* transmission complete interrupt */
+			stats->tx_bytes += priv->read_reg(priv, REG_FI) & 0xf;
 			stats->tx_packets++;
 			can_get_echo_skb(dev, 0);
 			netif_wake_queue(dev);
diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c
new file mode 100644
index 0000000..a6a51f1
--- /dev/null
+++ b/drivers/net/can/sja1000/sja1000_isa.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * 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  02111-1307  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/isa.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_isa"
+
+#define MAXDEV 8
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the ISA bus");
+MODULE_LICENSE("GPL v2");
+
+#define CLK_DEFAULT	16000000	/* 16 MHz */
+#define CDR_DEFAULT	(CDR_CBP | CDR_CLK_OFF)
+#define OCR_DEFAULT	OCR_TX0_PUSHPULL
+
+static unsigned long port[MAXDEV];
+static unsigned long mem[MAXDEV];
+static int __devinitdata irq[MAXDEV];
+static int __devinitdata clk[MAXDEV];
+static char __devinitdata cdr[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
+static char __devinitdata ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
+static char __devinitdata indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
+
+module_param_array(port, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(port, "I/O port number");
+
+module_param_array(mem, ulong, NULL, S_IRUGO);
+MODULE_PARM_DESC(mem, "I/O memory address");
+
+module_param_array(indirect, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(indirect, "Indirect access via address and data port");
+
+module_param_array(irq, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(irq, "IRQ number");
+
+module_param_array(clk, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(clk, "External oscillator clock frequency "
+		 "(default=16000000 [16 MHz])");
+
+module_param_array(cdr, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(cdr, "Clock divider register "
+		 "(default=0x48 [CDR_CBP | CDR_CLK_OFF])");
+
+module_param_array(ocr, byte, NULL, S_IRUGO);
+MODULE_PARM_DESC(ocr, "Output control register "
+		 "(default=0x18 [OCR_TX0_PUSHPULL])");
+
+#define SJA1000_IOSIZE          0x20
+#define SJA1000_IOSIZE_INDIRECT 0x02
+
+static u8 sja1000_isa_mem_read_reg(const struct sja1000_priv *priv, int reg)
+{
+	return readb(priv->reg_base + reg);
+}
+
+static void sja1000_isa_mem_write_reg(const struct sja1000_priv *priv,
+				      int reg, u8 val)
+{
+	writeb(val, priv->reg_base + reg);
+}
+
+static u8 sja1000_isa_port_read_reg(const struct sja1000_priv *priv, int reg)
+{
+	return inb((unsigned long)priv->reg_base + reg);
+}
+
+static void sja1000_isa_port_write_reg(const struct sja1000_priv *priv,
+				       int reg, u8 val)
+{
+	outb(val, (unsigned long)priv->reg_base + reg);
+}
+
+static u8 sja1000_isa_port_read_reg_indirect(const struct sja1000_priv *priv,
+					     int reg)
+{
+	unsigned long base = (unsigned long)priv->reg_base;
+
+	outb(reg, base);
+	return inb(base + 1);
+}
+
+static void sja1000_isa_port_write_reg_indirect(const struct sja1000_priv *priv,
+						int reg, u8 val)
+{
+	unsigned long base = (unsigned long)priv->reg_base;
+
+	outb(reg, base);
+	outb(val, base + 1);
+}
+
+static int __devinit sja1000_isa_match(struct device *pdev, unsigned int idx)
+{
+	if (port[idx] || mem[idx]) {
+		if (irq[idx])
+			return 1;
+	} else if (idx)
+		return 0;
+
+	dev_err(pdev, "insufficient parameters supplied\n");
+	return 0;
+}
+
+static int __devinit sja1000_isa_probe(struct device *pdev, unsigned int idx)
+{
+	struct net_device *dev;
+	struct sja1000_priv *priv;
+	void __iomem *base = NULL;
+	int iosize = SJA1000_IOSIZE;
+	int err;
+
+	if (mem[idx]) {
+		if (!request_mem_region(mem[idx], iosize, DRV_NAME)) {
+			err = -EBUSY;
+			goto exit;
+		}
+		base = ioremap_nocache(mem[idx], iosize);
+		if (!base) {
+			err = -ENOMEM;
+			goto exit_release;
+		}
+	} else {
+		if (indirect[idx] > 0 ||
+		    (indirect[idx] == -1 && indirect[0] > 0))
+			iosize = SJA1000_IOSIZE_INDIRECT;
+		if (!request_region(port[idx], iosize, DRV_NAME)) {
+			err = -EBUSY;
+			goto exit;
+		}
+	}
+
+	dev = alloc_sja1000dev(0);
+	if (!dev) {
+		err = -ENOMEM;
+		goto exit_unmap;
+	}
+	priv = netdev_priv(dev);
+
+	dev->irq = irq[idx];
+	priv->irq_flags = IRQF_SHARED;
+	if (mem[idx]) {
+		priv->reg_base = base;
+		dev->base_addr = mem[idx];
+		priv->read_reg = sja1000_isa_mem_read_reg;
+		priv->write_reg = sja1000_isa_mem_write_reg;
+	} else {
+		priv->reg_base = (void __iomem *)port[idx];
+		dev->base_addr = port[idx];
+
+		if (iosize == SJA1000_IOSIZE_INDIRECT) {
+			priv->read_reg = sja1000_isa_port_read_reg_indirect;
+			priv->write_reg = sja1000_isa_port_write_reg_indirect;
+		} else {
+			priv->read_reg = sja1000_isa_port_read_reg;
+			priv->write_reg = sja1000_isa_port_write_reg;
+		}
+	}
+
+	if (clk[idx])
+		priv->can.clock.freq = clk[idx] / 2;
+	else if (clk[0])
+		priv->can.clock.freq = clk[0] / 2;
+	else
+		priv->can.clock.freq = CLK_DEFAULT / 2;
+
+	if (ocr[idx] != -1)
+		priv->ocr = ocr[idx] & 0xff;
+	else if (ocr[0] != -1)
+		priv->ocr = ocr[0] & 0xff;
+	else
+		priv->ocr = OCR_DEFAULT;
+
+	if (cdr[idx] != -1)
+		priv->cdr = cdr[idx] & 0xff;
+	else if (cdr[0] != -1)
+		priv->cdr = cdr[0] & 0xff;
+	else
+		priv->cdr = CDR_DEFAULT;
+
+	dev_set_drvdata(pdev, dev);
+	SET_NETDEV_DEV(dev, pdev);
+
+	err = register_sja1000dev(dev);
+	if (err) {
+		dev_err(pdev, "registering %s failed (err=%d)\n",
+			DRV_NAME, err);
+		goto exit_unmap;
+	}
+
+	dev_info(pdev, "%s device registered (reg_base=0x%p, irq=%d)\n",
+		 DRV_NAME, priv->reg_base, dev->irq);
+	return 0;
+
+ exit_unmap:
+	if (mem[idx])
+		iounmap(base);
+ exit_release:
+	if (mem[idx])
+		release_mem_region(mem[idx], iosize);
+	else
+		release_region(port[idx], iosize);
+ exit:
+	return err;
+}
+
+static int __devexit sja1000_isa_remove(struct device *pdev, unsigned int idx)
+{
+	struct net_device *dev = dev_get_drvdata(pdev);
+	struct sja1000_priv *priv = netdev_priv(dev);
+
+	unregister_sja1000dev(dev);
+	dev_set_drvdata(pdev, NULL);
+
+	if (mem[idx]) {
+		iounmap(priv->reg_base);
+		release_mem_region(mem[idx], SJA1000_IOSIZE);
+	} else {
+		if (priv->read_reg == sja1000_isa_port_read_reg_indirect)
+			release_region(port[idx], SJA1000_IOSIZE_INDIRECT);
+		else
+			release_region(port[idx], SJA1000_IOSIZE);
+	}
+	free_sja1000dev(dev);
+
+	return 0;
+}
+
+static struct isa_driver sja1000_isa_driver = {
+	.match = sja1000_isa_match,
+	.probe = sja1000_isa_probe,
+	.remove = __devexit_p(sja1000_isa_remove),
+	.driver = {
+		.name = DRV_NAME,
+	},
+};
+
+static int __init sja1000_isa_init(void)
+{
+	int err = isa_register_driver(&sja1000_isa_driver, MAXDEV);
+
+	if (!err)
+		printk(KERN_INFO
+		       "Legacy %s driver for max. %d devices registered\n",
+		       DRV_NAME, MAXDEV);
+	return err;
+}
+
+static void __exit sja1000_isa_exit(void)
+{
+	isa_unregister_driver(&sja1000_isa_driver);
+}
+
+module_init(sja1000_isa_init);
+module_exit(sja1000_isa_exit);
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index a10c1d7..80ac563 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -80,10 +80,10 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 	skb->dev       = dev;
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-	netif_rx(skb);
+	netif_rx_ni(skb);
 }
 
-static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_device_stats *stats = &dev->stats;
 	int loop;
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index eb06667..05916aa 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -2918,7 +2918,7 @@ static inline int cas_xmit_tx_ringN(struct cas *cp, int ring,
 	return 0;
 }
 
-static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct cas *cp = netdev_priv(dev);
 
@@ -2928,7 +2928,7 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	static int ring;
 
 	if (skb_padto(skb, cp->min_frame_size))
-		return 0;
+		return NETDEV_TX_OK;
 
 	/* XXX: we need some higher-level QoS hooks to steer packets to
 	 *      individual queues.
@@ -2936,7 +2936,7 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb))
 		return NETDEV_TX_BUSY;
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void cas_init_tx_dma(struct cas *cp)
@@ -4875,10 +4875,6 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		break;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable(CAP_NET_ADMIN)) {
-			rc = -EPERM;
-			break;
-		}
 		spin_lock_irqsave(&cp->lock, flags);
 		cas_mif_poll(cp, 0);
 		rc = cas_phy_write(cp, data->reg_num & 0x1f, data->val_in);
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 3711d64..8c658cf 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1776,7 +1776,7 @@ static inline int eth_hdr_len(const void *data)
 /*
  * Adds the CPL header to the sk_buff and passes it to t1_sge_tx.
  */
-int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct adapter *adapter = dev->ml_priv;
 	struct sge *sge = adapter->sge;
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h
index 8c94051..00cc37f 100644
--- a/drivers/net/chelsio/sge.h
+++ b/drivers/net/chelsio/sge.h
@@ -78,7 +78,7 @@ void t1_sge_destroy(struct sge *);
 irqreturn_t t1_interrupt(int irq, void *cookie);
 int t1_poll(struct napi_struct *, int);
 
-int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void t1_set_vlan_accel(struct adapter *adapter, int on_off);
 void t1_sge_start(struct sge *);
 void t1_sge_stop(struct sge *);
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 74c3429..d45eacb 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -774,42 +774,34 @@ static int cnic_alloc_context(struct cnic_dev *dev)
 	return 0;
 }
 
-static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
+static int cnic_alloc_l2_rings(struct cnic_dev *dev, int pages)
 {
 	struct cnic_local *cp = dev->cnic_priv;
-	struct uio_info *uinfo;
-	int ret;
-
-	ret = cnic_alloc_dma(dev, &cp->kwq_info, KWQ_PAGE_CNT, 1);
-	if (ret)
-		goto error;
-	cp->kwq = (struct kwqe **) cp->kwq_info.pg_arr;
-
-	ret = cnic_alloc_dma(dev, &cp->kcq_info, KCQ_PAGE_CNT, 1);
-	if (ret)
-		goto error;
-	cp->kcq = (struct kcqe **) cp->kcq_info.pg_arr;
-
-	ret = cnic_alloc_context(dev);
-	if (ret)
-		goto error;
 
-	cp->l2_ring_size = 2 * BCM_PAGE_SIZE;
+	cp->l2_ring_size = pages * BCM_PAGE_SIZE;
 	cp->l2_ring = pci_alloc_consistent(dev->pcidev, cp->l2_ring_size,
 					   &cp->l2_ring_map);
 	if (!cp->l2_ring)
-		goto error;
+		return -ENOMEM;
 
 	cp->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
 	cp->l2_buf_size = PAGE_ALIGN(cp->l2_buf_size);
 	cp->l2_buf = pci_alloc_consistent(dev->pcidev, cp->l2_buf_size,
 					   &cp->l2_buf_map);
 	if (!cp->l2_buf)
-		goto error;
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int cnic_alloc_uio(struct cnic_dev *dev) {
+	struct cnic_local *cp = dev->cnic_priv;
+	struct uio_info *uinfo;
+	int ret;
 
 	uinfo = kzalloc(sizeof(*uinfo), GFP_ATOMIC);
 	if (!uinfo)
-		goto error;
+		return -ENOMEM;
 
 	uinfo->mem[0].addr = dev->netdev->base_addr;
 	uinfo->mem[0].internal_addr = dev->regview;
@@ -817,10 +809,15 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
 	uinfo->mem[0].memtype = UIO_MEM_PHYS;
 
 	uinfo->mem[1].addr = (unsigned long) cp->status_blk & PAGE_MASK;
-	if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX)
-		uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9;
-	else
-		uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE;
+	if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) {
+		if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX)
+			uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9;
+		else
+			uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE;
+
+		uinfo->name = "bnx2_cnic";
+	}
+
 	uinfo->mem[1].memtype = UIO_MEM_LOGICAL;
 
 	uinfo->mem[2].addr = (unsigned long) cp->l2_ring;
@@ -831,7 +828,6 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
 	uinfo->mem[3].size = cp->l2_buf_size;
 	uinfo->mem[3].memtype = UIO_MEM_LOGICAL;
 
-	uinfo->name = "bnx2_cnic";
 	uinfo->version = CNIC_MODULE_VERSION;
 	uinfo->irq = UIO_IRQ_CUSTOM;
 
@@ -843,10 +839,39 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
 	ret = uio_register_device(&dev->pcidev->dev, uinfo);
 	if (ret) {
 		kfree(uinfo);
-		goto error;
+		return ret;
 	}
 
 	cp->cnic_uinfo = uinfo;
+	return 0;
+}
+
+static int cnic_alloc_bnx2_resc(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	int ret;
+
+	ret = cnic_alloc_dma(dev, &cp->kwq_info, KWQ_PAGE_CNT, 1);
+	if (ret)
+		goto error;
+	cp->kwq = (struct kwqe **) cp->kwq_info.pg_arr;
+
+	ret = cnic_alloc_dma(dev, &cp->kcq_info, KCQ_PAGE_CNT, 1);
+	if (ret)
+		goto error;
+	cp->kcq = (struct kcqe **) cp->kcq_info.pg_arr;
+
+	ret = cnic_alloc_context(dev);
+	if (ret)
+		goto error;
+
+	ret = cnic_alloc_l2_rings(dev, 2);
+	if (ret)
+		goto error;
+
+	ret = cnic_alloc_uio(dev);
+	if (ret)
+		goto error;
 
 	return 0;
 
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index fd5e32c..3e3fab8 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -54,7 +54,7 @@ module_param(dumb_switch, int, 0444);
 MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
 MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
 
-#define CPMAC_VERSION "0.5.0"
+#define CPMAC_VERSION "0.5.1"
 /* frame size + 802.1q tag */
 #define CPMAC_SKB_SIZE		(ETH_FRAME_LEN + 4)
 #define CPMAC_QUEUES	8
@@ -1109,7 +1109,7 @@ static int external_switch;
 static int __devinit cpmac_probe(struct platform_device *pdev)
 {
 	int rc, phy_id;
-	char *mdio_bus_id = "0";
+	char mdio_bus_id[BUS_ID_SIZE];
 	struct resource *mem;
 	struct cpmac_priv *priv;
 	struct net_device *dev;
@@ -1117,22 +1117,23 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 
 	pdata = pdev->dev.platform_data;
 
-	for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
-		if (!(pdata->phy_mask & (1 << phy_id)))
-			continue;
-		if (!cpmac_mii->phy_map[phy_id])
-			continue;
-		break;
+	if (external_switch || dumb_switch) {
+		strncpy(mdio_bus_id, "0", BUS_ID_SIZE); /* fixed phys bus */
+		phy_id = pdev->id;
+	} else {
+		for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
+			if (!(pdata->phy_mask & (1 << phy_id)))
+				continue;
+			if (!cpmac_mii->phy_map[phy_id])
+				continue;
+			strncpy(mdio_bus_id, cpmac_mii->id, BUS_ID_SIZE);
+			break;
+		}
 	}
 
 	if (phy_id == PHY_MAX_ADDR) {
-		if (external_switch || dumb_switch) {
-			mdio_bus_id = 0; /* fixed phys bus */
-			phy_id = pdev->id;
-		} else {
-			dev_err(&pdev->dev, "no PHY present\n");
-			return -ENODEV;
-		}
+		dev_err(&pdev->dev, "no PHY present\n");
+		return -ENODEV;
 	}
 
 	dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
@@ -1166,8 +1167,11 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 	priv->msg_enable = netif_msg_init(debug_level, 0xff);
 	memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
 
-	priv->phy = phy_connect(dev, dev_name(&cpmac_mii->phy_map[phy_id]->dev),
-				&cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+	snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
+
+	priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
+						PHY_INTERFACE_MODE_MII);
+
 	if (IS_ERR(priv->phy)) {
 		if (netif_msg_drv(priv))
 			printk(KERN_ERR "%s: Could not attach to PHY\n",
@@ -1241,11 +1245,11 @@ int __devinit cpmac_init(void)
 
 	cpmac_mii->reset(cpmac_mii);
 
-	for (i = 0; i < 300000; i++)
+	for (i = 0; i < 300; i++)
 		if ((mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE)))
 			break;
 		else
-			cpu_relax();
+			msleep(10);
 
 	mask &= 0x7fffffff;
 	if (mask & (mask - 1)) {
@@ -1254,7 +1258,7 @@ int __devinit cpmac_init(void)
 	}
 
 	cpmac_mii->phy_mask = ~(mask | 0x80000000);
-	snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "0");
+	snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "1");
 
 	res = mdiobus_register(cpmac_mii);
 	if (res)
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 7a18dc7..15c0195 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -1108,7 +1108,7 @@ e100_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irqrestore(&np->lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index 55445f9..0c54219 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -177,13 +177,10 @@ static unsigned int cs8900_irq_map[] = {1,0,0,0};
 #elif defined(CONFIG_MACH_IXDP2351)
 static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
-#include <asm/irq.h>
 #elif defined(CONFIG_ARCH_IXDP2X01)
-#include <asm/irq.h>
 static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
 #elif defined(CONFIG_ARCH_PNX010X)
-#include <asm/irq.h>
 #include <mach/gpio.h>
 #define CIRRUS_DEFAULT_BASE	IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000)	/* = Physical address 0x48200000 */
 #define CIRRUS_DEFAULT_IRQ	VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
@@ -249,7 +246,7 @@ struct net_local {
 
 static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
 static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t net_interrupt(int irq, void *dev_id);
 static void set_multicast_list(struct net_device *dev);
 static void net_timeout(struct net_device *dev);
@@ -1367,7 +1364,7 @@ net_open(struct net_device *dev)
 			spin_lock_irqsave(&lp->lock, flags);
 			disable_dma(dev->dma);
 			clear_dma_ff(dev->dma);
-			set_dma_mode(dev->dma, 0x14); /* auto_init as well */
+			set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */
 			set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
 			set_dma_count(dev->dma, lp->dmasize*1024);
 			enable_dma(dev->dma);
@@ -1521,7 +1518,7 @@ static void net_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t net_send_packet(struct sk_buff *skb,struct net_device *dev)
 {
 	struct net_local *lp = netdev_priv(dev);
 	unsigned long flags;
@@ -1572,7 +1569,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
 	 * to restart the netdevice layer
 	 */
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The typical workload of the driver:
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 1694fad..2b1aea6 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -276,6 +276,14 @@ static inline struct port_info *adap2pinfo(struct adapter *adap, int idx)
 	return netdev_priv(adap->port[idx]);
 }
 
+static inline int phy2portid(struct cphy *phy)
+{
+	struct adapter *adap = phy->adapter;
+	struct port_info *port0 = adap2pinfo(adap, 0);
+
+	return &port0->phy == phy ? 0 : 1;
+}
+
 #define OFFLOAD_DEVMAP_BIT 15
 
 #define tdev2adap(d) container_of(d, struct adapter, tdev)
@@ -301,7 +309,7 @@ void t3_stop_sge_timers(struct adapter *adap);
 void t3_free_sge_resources(struct adapter *adap);
 void t3_sge_err_intr_handler(struct adapter *adapter);
 irq_handler_t t3_intr_handler(struct adapter *adap, int polling);
-int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev);
 int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb);
 void t3_update_qset_coalesce(struct sge_qset *qs, const struct qset_params *p);
 int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
@@ -312,4 +320,6 @@ int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx,
 		unsigned char *data);
 irqreturn_t t3_sge_intr_msix(int irq, void *cookie);
 
+int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size);
+
 #endif				/* __T3_ADAPTER_H__ */
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index 9fe008e..5248f9e 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -224,12 +224,6 @@ static int ael1006_reset(struct cphy *phy, int wait)
 	return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait);
 }
 
-static int ael1006_power_down(struct cphy *phy, int enable)
-{
-	return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD,
-			     MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable);
-}
-
 static struct cphy_ops ael1006_ops = {
 	.reset = ael1006_reset,
 	.intr_enable = t3_phy_lasi_intr_enable,
@@ -237,7 +231,7 @@ static struct cphy_ops ael1006_ops = {
 	.intr_clear = t3_phy_lasi_intr_clear,
 	.intr_handler = t3_phy_lasi_intr_handler,
 	.get_link_status = get_link_status_r,
-	.power_down = ael1006_power_down,
+	.power_down = ael1002_power_down,
 	.mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
 };
 
@@ -304,279 +298,7 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
 		{ MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
 		{ 0, 0, 0, 0 }
 	};
-	static u16 sr_edc[] = {
-		0xcc00, 0x2ff4,
-		0xcc01, 0x3cd4,
-		0xcc02, 0x2015,
-		0xcc03, 0x3105,
-		0xcc04, 0x6524,
-		0xcc05, 0x27ff,
-		0xcc06, 0x300f,
-		0xcc07, 0x2c8b,
-		0xcc08, 0x300b,
-		0xcc09, 0x4009,
-		0xcc0a, 0x400e,
-		0xcc0b, 0x2f72,
-		0xcc0c, 0x3002,
-		0xcc0d, 0x1002,
-		0xcc0e, 0x2172,
-		0xcc0f, 0x3012,
-		0xcc10, 0x1002,
-		0xcc11, 0x25d2,
-		0xcc12, 0x3012,
-		0xcc13, 0x1002,
-		0xcc14, 0xd01e,
-		0xcc15, 0x27d2,
-		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, 0x2862,
-		0xcc27, 0x3012,
-		0xcc28, 0x1002,
-		0xcc29, 0x2092,
-		0xcc2a, 0x3012,
-		0xcc2b, 0x1002,
-		0xcc2c, 0x5cc3,
-		0xcc2d, 0x314,
-		0xcc2e, 0x2942,
-		0xcc2f, 0x3002,
-		0xcc30, 0x1002,
-		0xcc31, 0xd019,
-		0xcc32, 0x2032,
-		0xcc33, 0x3012,
-		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, 0x2862,
-		0xcc41, 0x3012,
-		0xcc42, 0x1002,
-		0xcc43, 0x2032,
-		0xcc44, 0x3012,
-		0xcc45, 0x1002,
-		0xcc46, 0x2fb4,
-		0xcc47, 0x3cd4,
-		0xcc48, 0x6624,
-		0xcc49, 0x5563,
-		0xcc4a, 0x2d42,
-		0xcc4b, 0x3002,
-		0xcc4c, 0x13d2,
-		0xcc4d, 0x2ed2,
-		0xcc4e, 0x3002,
-		0xcc4f, 0x1002,
-		0xcc50, 0x2fd2,
-		0xcc51, 0x3002,
-		0xcc52, 0x1002,
-		0xcc53, 0x004,
-		0xcc54, 0x2942,
-		0xcc55, 0x3002,
-		0xcc56, 0x1002,
-		0xcc57, 0x2092,
-		0xcc58, 0x3012,
-		0xcc59, 0x1002,
-		0xcc5a, 0x5cc3,
-		0xcc5b, 0x317,
-		0xcc5c, 0x2f72,
-		0xcc5d, 0x3002,
-		0xcc5e, 0x1002,
-		0xcc5f, 0x2942,
-		0xcc60, 0x3002,
-		0xcc61, 0x1002,
-		0xcc62, 0x22cd,
-		0xcc63, 0x301d,
-		0xcc64, 0x2862,
-		0xcc65, 0x3012,
-		0xcc66, 0x1002,
-		0xcc67, 0x2ed2,
-		0xcc68, 0x3002,
-		0xcc69, 0x1002,
-		0xcc6a, 0x2d72,
-		0xcc6b, 0x3002,
-		0xcc6c, 0x1002,
-		0xcc6d, 0x628f,
-		0xcc6e, 0x2112,
-		0xcc6f, 0x3012,
-		0xcc70, 0x1002,
-		0xcc71, 0x5aa3,
-		0xcc72, 0x2dc2,
-		0xcc73, 0x3002,
-		0xcc74, 0x1312,
-		0xcc75, 0x6f72,
-		0xcc76, 0x1002,
-		0xcc77, 0x2807,
-		0xcc78, 0x31a7,
-		0xcc79, 0x20c4,
-		0xcc7a, 0x3c24,
-		0xcc7b, 0x6724,
-		0xcc7c, 0x1002,
-		0xcc7d, 0x2807,
-		0xcc7e, 0x3187,
-		0xcc7f, 0x20c4,
-		0xcc80, 0x3c24,
-		0xcc81, 0x6724,
-		0xcc82, 0x1002,
-		0xcc83, 0x2514,
-		0xcc84, 0x3c64,
-		0xcc85, 0x6436,
-		0xcc86, 0xdff4,
-		0xcc87, 0x6436,
-		0xcc88, 0x1002,
-		0xcc89, 0x40a4,
-		0xcc8a, 0x643c,
-		0xcc8b, 0x4016,
-		0xcc8c, 0x8c6c,
-		0xcc8d, 0x2b24,
-		0xcc8e, 0x3c24,
-		0xcc8f, 0x6435,
-		0xcc90, 0x1002,
-		0xcc91, 0x2b24,
-		0xcc92, 0x3c24,
-		0xcc93, 0x643a,
-		0xcc94, 0x4025,
-		0xcc95, 0x8a5a,
-		0xcc96, 0x1002,
-		0xcc97, 0x2731,
-		0xcc98, 0x3011,
-		0xcc99, 0x1001,
-		0xcc9a, 0xc7a0,
-		0xcc9b, 0x100,
-		0xcc9c, 0xc502,
-		0xcc9d, 0x53ac,
-		0xcc9e, 0xc503,
-		0xcc9f, 0xd5d5,
-		0xcca0, 0xc600,
-		0xcca1, 0x2a6d,
-		0xcca2, 0xc601,
-		0xcca3, 0x2a4c,
-		0xcca4, 0xc602,
-		0xcca5, 0x111,
-		0xcca6, 0xc60c,
-		0xcca7, 0x5900,
-		0xcca8, 0xc710,
-		0xcca9, 0x700,
-		0xccaa, 0xc718,
-		0xccab, 0x700,
-		0xccac, 0xc720,
-		0xccad, 0x4700,
-		0xccae, 0xc801,
-		0xccaf, 0x7f50,
-		0xccb0, 0xc802,
-		0xccb1, 0x7760,
-		0xccb2, 0xc803,
-		0xccb3, 0x7fce,
-		0xccb4, 0xc804,
-		0xccb5, 0x5700,
-		0xccb6, 0xc805,
-		0xccb7, 0x5f11,
-		0xccb8, 0xc806,
-		0xccb9, 0x4751,
-		0xccba, 0xc807,
-		0xccbb, 0x57e1,
-		0xccbc, 0xc808,
-		0xccbd, 0x2700,
-		0xccbe, 0xc809,
-		0xccbf, 0x000,
-		0xccc0, 0xc821,
-		0xccc1, 0x002,
-		0xccc2, 0xc822,
-		0xccc3, 0x014,
-		0xccc4, 0xc832,
-		0xccc5, 0x1186,
-		0xccc6, 0xc847,
-		0xccc7, 0x1e02,
-		0xccc8, 0xc013,
-		0xccc9, 0xf341,
-		0xccca, 0xc01a,
-		0xcccb, 0x446,
-		0xcccc, 0xc024,
-		0xcccd, 0x1000,
-		0xccce, 0xc025,
-		0xcccf, 0xa00,
-		0xccd0, 0xc026,
-		0xccd1, 0xc0c,
-		0xccd2, 0xc027,
-		0xccd3, 0xc0c,
-		0xccd4, 0xc029,
-		0xccd5, 0x0a0,
-		0xccd6, 0xc030,
-		0xccd7, 0xa00,
-		0xccd8, 0xc03c,
-		0xccd9, 0x01c,
-		0xccda, 0xc005,
-		0xccdb, 0x7a06,
-		0xccdc, 0x000,
-		0xccdd, 0x2731,
-		0xccde, 0x3011,
-		0xccdf, 0x1001,
-		0xcce0, 0xc620,
-		0xcce1, 0x000,
-		0xcce2, 0xc621,
-		0xcce3, 0x03f,
-		0xcce4, 0xc622,
-		0xcce5, 0x000,
-		0xcce6, 0xc623,
-		0xcce7, 0x000,
-		0xcce8, 0xc624,
-		0xcce9, 0x000,
-		0xccea, 0xc625,
-		0xcceb, 0x000,
-		0xccec, 0xc627,
-		0xcced, 0x000,
-		0xccee, 0xc628,
-		0xccef, 0x000,
-		0xccf0, 0xc62c,
-		0xccf1, 0x000,
-		0xccf2, 0x000,
-		0xccf3, 0x2806,
-		0xccf4, 0x3cb6,
-		0xccf5, 0xc161,
-		0xccf6, 0x6134,
-		0xccf7, 0x6135,
-		0xccf8, 0x5443,
-		0xccf9, 0x303,
-		0xccfa, 0x6524,
-		0xccfb, 0x00b,
-		0xccfc, 0x1002,
-		0xccfd, 0x2104,
-		0xccfe, 0x3c24,
-		0xccff, 0x2105,
-		0xcd00, 0x3805,
-		0xcd01, 0x6524,
-		0xcd02, 0xdff4,
-		0xcd03, 0x4005,
-		0xcd04, 0x6524,
-		0xcd05, 0x1002,
-		0xcd06, 0x5dd3,
-		0xcd07, 0x306,
-		0xcd08, 0x2ff7,
-		0xcd09, 0x38f7,
-		0xcd0a, 0x60b7,
-		0xcd0b, 0xdffd,
-		0xcd0c, 0x00a,
-		0xcd0d, 0x1002,
-		0xcd0e, 0
-	};
+
 	int i, err;
 
 	err = set_phy_regs(phy, regs);
@@ -585,9 +307,16 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
 
 	msleep(50);
 
-	for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
-		err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i],
-				    sr_edc[i + 1]);
+	if (phy->priv != edc_sr)
+		err = t3_get_edc_fw(phy, EDC_OPT_AEL2005,
+				    EDC_OPT_AEL2005_SIZE);
+	if (err)
+		return err;
+
+	for (i = 0; i <  EDC_OPT_AEL2005_SIZE / sizeof(u16) && !err; i += 2)
+		err = t3_mdio_write(phy, MDIO_MMD_PMAPMD,
+				    phy->phy_cache[i],
+				    phy->phy_cache[i + 1]);
 	if (!err)
 		phy->priv = edc_sr;
 	return err;
@@ -604,374 +333,6 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
 		{ MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
 		{ 0, 0, 0, 0 }
 	};
-	static u16 twinax_edc[] = {
-		0xcc00, 0x4009,
-		0xcc01, 0x27ff,
-		0xcc02, 0x300f,
-		0xcc03, 0x40aa,
-		0xcc04, 0x401c,
-		0xcc05, 0x401e,
-		0xcc06, 0x2ff4,
-		0xcc07, 0x3cd4,
-		0xcc08, 0x2035,
-		0xcc09, 0x3145,
-		0xcc0a, 0x6524,
-		0xcc0b, 0x26a2,
-		0xcc0c, 0x3012,
-		0xcc0d, 0x1002,
-		0xcc0e, 0x29c2,
-		0xcc0f, 0x3002,
-		0xcc10, 0x1002,
-		0xcc11, 0x2072,
-		0xcc12, 0x3012,
-		0xcc13, 0x1002,
-		0xcc14, 0x22cd,
-		0xcc15, 0x301d,
-		0xcc16, 0x2e52,
-		0xcc17, 0x3012,
-		0xcc18, 0x1002,
-		0xcc19, 0x28e2,
-		0xcc1a, 0x3002,
-		0xcc1b, 0x1002,
-		0xcc1c, 0x628f,
-		0xcc1d, 0x2ac2,
-		0xcc1e, 0x3012,
-		0xcc1f, 0x1002,
-		0xcc20, 0x5553,
-		0xcc21, 0x2ae2,
-		0xcc22, 0x3002,
-		0xcc23, 0x1302,
-		0xcc24, 0x401e,
-		0xcc25, 0x2be2,
-		0xcc26, 0x3012,
-		0xcc27, 0x1002,
-		0xcc28, 0x2da2,
-		0xcc29, 0x3012,
-		0xcc2a, 0x1002,
-		0xcc2b, 0x2ba2,
-		0xcc2c, 0x3002,
-		0xcc2d, 0x1002,
-		0xcc2e, 0x5ee3,
-		0xcc2f, 0x305,
-		0xcc30, 0x400e,
-		0xcc31, 0x2bc2,
-		0xcc32, 0x3002,
-		0xcc33, 0x1002,
-		0xcc34, 0x2b82,
-		0xcc35, 0x3012,
-		0xcc36, 0x1002,
-		0xcc37, 0x5663,
-		0xcc38, 0x302,
-		0xcc39, 0x401e,
-		0xcc3a, 0x6f72,
-		0xcc3b, 0x1002,
-		0xcc3c, 0x628f,
-		0xcc3d, 0x2be2,
-		0xcc3e, 0x3012,
-		0xcc3f, 0x1002,
-		0xcc40, 0x22cd,
-		0xcc41, 0x301d,
-		0xcc42, 0x2e52,
-		0xcc43, 0x3012,
-		0xcc44, 0x1002,
-		0xcc45, 0x2522,
-		0xcc46, 0x3012,
-		0xcc47, 0x1002,
-		0xcc48, 0x2da2,
-		0xcc49, 0x3012,
-		0xcc4a, 0x1002,
-		0xcc4b, 0x2ca2,
-		0xcc4c, 0x3012,
-		0xcc4d, 0x1002,
-		0xcc4e, 0x2fa4,
-		0xcc4f, 0x3cd4,
-		0xcc50, 0x6624,
-		0xcc51, 0x410b,
-		0xcc52, 0x56b3,
-		0xcc53, 0x3c4,
-		0xcc54, 0x2fb2,
-		0xcc55, 0x3002,
-		0xcc56, 0x1002,
-		0xcc57, 0x220b,
-		0xcc58, 0x303b,
-		0xcc59, 0x56b3,
-		0xcc5a, 0x3c3,
-		0xcc5b, 0x866b,
-		0xcc5c, 0x400c,
-		0xcc5d, 0x23a2,
-		0xcc5e, 0x3012,
-		0xcc5f, 0x1002,
-		0xcc60, 0x2da2,
-		0xcc61, 0x3012,
-		0xcc62, 0x1002,
-		0xcc63, 0x2ca2,
-		0xcc64, 0x3012,
-		0xcc65, 0x1002,
-		0xcc66, 0x2fb4,
-		0xcc67, 0x3cd4,
-		0xcc68, 0x6624,
-		0xcc69, 0x56b3,
-		0xcc6a, 0x3c3,
-		0xcc6b, 0x866b,
-		0xcc6c, 0x401c,
-		0xcc6d, 0x2205,
-		0xcc6e, 0x3035,
-		0xcc6f, 0x5b53,
-		0xcc70, 0x2c52,
-		0xcc71, 0x3002,
-		0xcc72, 0x13c2,
-		0xcc73, 0x5cc3,
-		0xcc74, 0x317,
-		0xcc75, 0x2522,
-		0xcc76, 0x3012,
-		0xcc77, 0x1002,
-		0xcc78, 0x2da2,
-		0xcc79, 0x3012,
-		0xcc7a, 0x1002,
-		0xcc7b, 0x2b82,
-		0xcc7c, 0x3012,
-		0xcc7d, 0x1002,
-		0xcc7e, 0x5663,
-		0xcc7f, 0x303,
-		0xcc80, 0x401e,
-		0xcc81, 0x004,
-		0xcc82, 0x2c42,
-		0xcc83, 0x3012,
-		0xcc84, 0x1002,
-		0xcc85, 0x6f72,
-		0xcc86, 0x1002,
-		0xcc87, 0x628f,
-		0xcc88, 0x2304,
-		0xcc89, 0x3c84,
-		0xcc8a, 0x6436,
-		0xcc8b, 0xdff4,
-		0xcc8c, 0x6436,
-		0xcc8d, 0x2ff5,
-		0xcc8e, 0x3005,
-		0xcc8f, 0x8656,
-		0xcc90, 0xdfba,
-		0xcc91, 0x56a3,
-		0xcc92, 0xd05a,
-		0xcc93, 0x21c2,
-		0xcc94, 0x3012,
-		0xcc95, 0x1392,
-		0xcc96, 0xd05a,
-		0xcc97, 0x56a3,
-		0xcc98, 0xdfba,
-		0xcc99, 0x383,
-		0xcc9a, 0x6f72,
-		0xcc9b, 0x1002,
-		0xcc9c, 0x28c5,
-		0xcc9d, 0x3005,
-		0xcc9e, 0x4178,
-		0xcc9f, 0x5653,
-		0xcca0, 0x384,
-		0xcca1, 0x22b2,
-		0xcca2, 0x3012,
-		0xcca3, 0x1002,
-		0xcca4, 0x2be5,
-		0xcca5, 0x3005,
-		0xcca6, 0x41e8,
-		0xcca7, 0x5653,
-		0xcca8, 0x382,
-		0xcca9, 0x002,
-		0xccaa, 0x4258,
-		0xccab, 0x2474,
-		0xccac, 0x3c84,
-		0xccad, 0x6437,
-		0xccae, 0xdff4,
-		0xccaf, 0x6437,
-		0xccb0, 0x2ff5,
-		0xccb1, 0x3c05,
-		0xccb2, 0x8757,
-		0xccb3, 0xb888,
-		0xccb4, 0x9787,
-		0xccb5, 0xdff4,
-		0xccb6, 0x6724,
-		0xccb7, 0x866a,
-		0xccb8, 0x6f72,
-		0xccb9, 0x1002,
-		0xccba, 0x2d01,
-		0xccbb, 0x3011,
-		0xccbc, 0x1001,
-		0xccbd, 0xc620,
-		0xccbe, 0x14e5,
-		0xccbf, 0xc621,
-		0xccc0, 0xc53d,
-		0xccc1, 0xc622,
-		0xccc2, 0x3cbe,
-		0xccc3, 0xc623,
-		0xccc4, 0x4452,
-		0xccc5, 0xc624,
-		0xccc6, 0xc5c5,
-		0xccc7, 0xc625,
-		0xccc8, 0xe01e,
-		0xccc9, 0xc627,
-		0xccca, 0x000,
-		0xcccb, 0xc628,
-		0xcccc, 0x000,
-		0xcccd, 0xc62b,
-		0xccce, 0x000,
-		0xcccf, 0xc62c,
-		0xccd0, 0x000,
-		0xccd1, 0x000,
-		0xccd2, 0x2d01,
-		0xccd3, 0x3011,
-		0xccd4, 0x1001,
-		0xccd5, 0xc620,
-		0xccd6, 0x000,
-		0xccd7, 0xc621,
-		0xccd8, 0x000,
-		0xccd9, 0xc622,
-		0xccda, 0x0ce,
-		0xccdb, 0xc623,
-		0xccdc, 0x07f,
-		0xccdd, 0xc624,
-		0xccde, 0x032,
-		0xccdf, 0xc625,
-		0xcce0, 0x000,
-		0xcce1, 0xc627,
-		0xcce2, 0x000,
-		0xcce3, 0xc628,
-		0xcce4, 0x000,
-		0xcce5, 0xc62b,
-		0xcce6, 0x000,
-		0xcce7, 0xc62c,
-		0xcce8, 0x000,
-		0xcce9, 0x000,
-		0xccea, 0x2d01,
-		0xcceb, 0x3011,
-		0xccec, 0x1001,
-		0xcced, 0xc502,
-		0xccee, 0x609f,
-		0xccef, 0xc600,
-		0xccf0, 0x2a6e,
-		0xccf1, 0xc601,
-		0xccf2, 0x2a2c,
-		0xccf3, 0xc60c,
-		0xccf4, 0x5400,
-		0xccf5, 0xc710,
-		0xccf6, 0x700,
-		0xccf7, 0xc718,
-		0xccf8, 0x700,
-		0xccf9, 0xc720,
-		0xccfa, 0x4700,
-		0xccfb, 0xc728,
-		0xccfc, 0x700,
-		0xccfd, 0xc729,
-		0xccfe, 0x1207,
-		0xccff, 0xc801,
-		0xcd00, 0x7f50,
-		0xcd01, 0xc802,
-		0xcd02, 0x7760,
-		0xcd03, 0xc803,
-		0xcd04, 0x7fce,
-		0xcd05, 0xc804,
-		0xcd06, 0x520e,
-		0xcd07, 0xc805,
-		0xcd08, 0x5c11,
-		0xcd09, 0xc806,
-		0xcd0a, 0x3c51,
-		0xcd0b, 0xc807,
-		0xcd0c, 0x4061,
-		0xcd0d, 0xc808,
-		0xcd0e, 0x49c1,
-		0xcd0f, 0xc809,
-		0xcd10, 0x3840,
-		0xcd11, 0xc80a,
-		0xcd12, 0x000,
-		0xcd13, 0xc821,
-		0xcd14, 0x002,
-		0xcd15, 0xc822,
-		0xcd16, 0x046,
-		0xcd17, 0xc844,
-		0xcd18, 0x182f,
-		0xcd19, 0xc013,
-		0xcd1a, 0xf341,
-		0xcd1b, 0xc01a,
-		0xcd1c, 0x446,
-		0xcd1d, 0xc024,
-		0xcd1e, 0x1000,
-		0xcd1f, 0xc025,
-		0xcd20, 0xa00,
-		0xcd21, 0xc026,
-		0xcd22, 0xc0c,
-		0xcd23, 0xc027,
-		0xcd24, 0xc0c,
-		0xcd25, 0xc029,
-		0xcd26, 0x0a0,
-		0xcd27, 0xc030,
-		0xcd28, 0xa00,
-		0xcd29, 0xc03c,
-		0xcd2a, 0x01c,
-		0xcd2b, 0x000,
-		0xcd2c, 0x2b84,
-		0xcd2d, 0x3c74,
-		0xcd2e, 0x6435,
-		0xcd2f, 0xdff4,
-		0xcd30, 0x6435,
-		0xcd31, 0x2806,
-		0xcd32, 0x3006,
-		0xcd33, 0x8565,
-		0xcd34, 0x2b24,
-		0xcd35, 0x3c24,
-		0xcd36, 0x6436,
-		0xcd37, 0x1002,
-		0xcd38, 0x2b24,
-		0xcd39, 0x3c24,
-		0xcd3a, 0x6436,
-		0xcd3b, 0x4045,
-		0xcd3c, 0x8656,
-		0xcd3d, 0x1002,
-		0xcd3e, 0x2807,
-		0xcd3f, 0x31a7,
-		0xcd40, 0x20c4,
-		0xcd41, 0x3c24,
-		0xcd42, 0x6724,
-		0xcd43, 0x1002,
-		0xcd44, 0x2807,
-		0xcd45, 0x3187,
-		0xcd46, 0x20c4,
-		0xcd47, 0x3c24,
-		0xcd48, 0x6724,
-		0xcd49, 0x1002,
-		0xcd4a, 0x2514,
-		0xcd4b, 0x3c64,
-		0xcd4c, 0x6436,
-		0xcd4d, 0xdff4,
-		0xcd4e, 0x6436,
-		0xcd4f, 0x1002,
-		0xcd50, 0x2806,
-		0xcd51, 0x3cb6,
-		0xcd52, 0xc161,
-		0xcd53, 0x6134,
-		0xcd54, 0x6135,
-		0xcd55, 0x5443,
-		0xcd56, 0x303,
-		0xcd57, 0x6524,
-		0xcd58, 0x00b,
-		0xcd59, 0x1002,
-		0xcd5a, 0xd019,
-		0xcd5b, 0x2104,
-		0xcd5c, 0x3c24,
-		0xcd5d, 0x2105,
-		0xcd5e, 0x3805,
-		0xcd5f, 0x6524,
-		0xcd60, 0xdff4,
-		0xcd61, 0x4005,
-		0xcd62, 0x6524,
-		0xcd63, 0x2e8d,
-		0xcd64, 0x303d,
-		0xcd65, 0x5dd3,
-		0xcd66, 0x306,
-		0xcd67, 0x2ff7,
-		0xcd68, 0x38f7,
-		0xcd69, 0x60b7,
-		0xcd6a, 0xdffd,
-		0xcd6b, 0x00a,
-		0xcd6c, 0x1002,
-		0xcd6d, 0
-	};
 	int i, err;
 
 	err = set_phy_regs(phy, regs);
@@ -982,9 +343,16 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
 
 	msleep(50);
 
-	for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
-		err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
-				    twinax_edc[i + 1]);
+	if (phy->priv != edc_twinax)
+		err = t3_get_edc_fw(phy, EDC_TWX_AEL2005,
+				    EDC_TWX_AEL2005_SIZE);
+	if (err)
+		return err;
+
+	for (i = 0; i <  EDC_TWX_AEL2005_SIZE / sizeof(u16) && !err; i += 2)
+		err = t3_mdio_write(phy, MDIO_MMD_PMAPMD,
+				    phy->phy_cache[i],
+				    phy->phy_cache[i + 1]);
 	if (!err)
 		phy->priv = edc_twinax;
 	return err;
@@ -1201,405 +569,6 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
 		{ MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 },
 		{ 0, 0, 0, 0 }
 	};
-
-	/* TWINAX EDC firmware */
-	static u16 twinax_edc[] = {
-		0xd800, 0x4009,
-		0xd801, 0x2fff,
-		0xd802, 0x300f,
-		0xd803, 0x40aa,
-		0xd804, 0x401c,
-		0xd805, 0x401e,
-		0xd806, 0x2ff4,
-		0xd807, 0x3dc4,
-		0xd808, 0x2035,
-		0xd809, 0x3035,
-		0xd80a, 0x6524,
-		0xd80b, 0x2cb2,
-		0xd80c, 0x3012,
-		0xd80d, 0x1002,
-		0xd80e, 0x26e2,
-		0xd80f, 0x3022,
-		0xd810, 0x1002,
-		0xd811, 0x27d2,
-		0xd812, 0x3022,
-		0xd813, 0x1002,
-		0xd814, 0x2822,
-		0xd815, 0x3012,
-		0xd816, 0x1002,
-		0xd817, 0x2492,
-		0xd818, 0x3022,
-		0xd819, 0x1002,
-		0xd81a, 0x2772,
-		0xd81b, 0x3012,
-		0xd81c, 0x1002,
-		0xd81d, 0x23d2,
-		0xd81e, 0x3022,
-		0xd81f, 0x1002,
-		0xd820, 0x22cd,
-		0xd821, 0x301d,
-		0xd822, 0x27f2,
-		0xd823, 0x3022,
-		0xd824, 0x1002,
-		0xd825, 0x5553,
-		0xd826, 0x0307,
-		0xd827, 0x2522,
-		0xd828, 0x3022,
-		0xd829, 0x1002,
-		0xd82a, 0x2142,
-		0xd82b, 0x3012,
-		0xd82c, 0x1002,
-		0xd82d, 0x4016,
-		0xd82e, 0x5e63,
-		0xd82f, 0x0344,
-		0xd830, 0x2142,
-		0xd831, 0x3012,
-		0xd832, 0x1002,
-		0xd833, 0x400e,
-		0xd834, 0x2522,
-		0xd835, 0x3022,
-		0xd836, 0x1002,
-		0xd837, 0x2b52,
-		0xd838, 0x3012,
-		0xd839, 0x1002,
-		0xd83a, 0x2742,
-		0xd83b, 0x3022,
-		0xd83c, 0x1002,
-		0xd83d, 0x25e2,
-		0xd83e, 0x3022,
-		0xd83f, 0x1002,
-		0xd840, 0x2fa4,
-		0xd841, 0x3dc4,
-		0xd842, 0x6624,
-		0xd843, 0x414b,
-		0xd844, 0x56b3,
-		0xd845, 0x03c6,
-		0xd846, 0x866b,
-		0xd847, 0x400c,
-		0xd848, 0x2712,
-		0xd849, 0x3012,
-		0xd84a, 0x1002,
-		0xd84b, 0x2c4b,
-		0xd84c, 0x309b,
-		0xd84d, 0x56b3,
-		0xd84e, 0x03c3,
-		0xd84f, 0x866b,
-		0xd850, 0x400c,
-		0xd851, 0x2272,
-		0xd852, 0x3022,
-		0xd853, 0x1002,
-		0xd854, 0x2742,
-		0xd855, 0x3022,
-		0xd856, 0x1002,
-		0xd857, 0x25e2,
-		0xd858, 0x3022,
-		0xd859, 0x1002,
-		0xd85a, 0x2fb4,
-		0xd85b, 0x3dc4,
-		0xd85c, 0x6624,
-		0xd85d, 0x56b3,
-		0xd85e, 0x03c3,
-		0xd85f, 0x866b,
-		0xd860, 0x401c,
-		0xd861, 0x2c45,
-		0xd862, 0x3095,
-		0xd863, 0x5b53,
-		0xd864, 0x2372,
-		0xd865, 0x3012,
-		0xd866, 0x13c2,
-		0xd867, 0x5cc3,
-		0xd868, 0x2712,
-		0xd869, 0x3012,
-		0xd86a, 0x1312,
-		0xd86b, 0x2b52,
-		0xd86c, 0x3012,
-		0xd86d, 0x1002,
-		0xd86e, 0x2742,
-		0xd86f, 0x3022,
-		0xd870, 0x1002,
-		0xd871, 0x2582,
-		0xd872, 0x3022,
-		0xd873, 0x1002,
-		0xd874, 0x2142,
-		0xd875, 0x3012,
-		0xd876, 0x1002,
-		0xd877, 0x628f,
-		0xd878, 0x2985,
-		0xd879, 0x33a5,
-		0xd87a, 0x25e2,
-		0xd87b, 0x3022,
-		0xd87c, 0x1002,
-		0xd87d, 0x5653,
-		0xd87e, 0x03d2,
-		0xd87f, 0x401e,
-		0xd880, 0x6f72,
-		0xd881, 0x1002,
-		0xd882, 0x628f,
-		0xd883, 0x2304,
-		0xd884, 0x3c84,
-		0xd885, 0x6436,
-		0xd886, 0xdff4,
-		0xd887, 0x6436,
-		0xd888, 0x2ff5,
-		0xd889, 0x3005,
-		0xd88a, 0x8656,
-		0xd88b, 0xdfba,
-		0xd88c, 0x56a3,
-		0xd88d, 0xd05a,
-		0xd88e, 0x2972,
-		0xd88f, 0x3012,
-		0xd890, 0x1392,
-		0xd891, 0xd05a,
-		0xd892, 0x56a3,
-		0xd893, 0xdfba,
-		0xd894, 0x0383,
-		0xd895, 0x6f72,
-		0xd896, 0x1002,
-		0xd897, 0x2b45,
-		0xd898, 0x3005,
-		0xd899, 0x4178,
-		0xd89a, 0x5653,
-		0xd89b, 0x0384,
-		0xd89c, 0x2a62,
-		0xd89d, 0x3012,
-		0xd89e, 0x1002,
-		0xd89f, 0x2f05,
-		0xd8a0, 0x3005,
-		0xd8a1, 0x41c8,
-		0xd8a2, 0x5653,
-		0xd8a3, 0x0382,
-		0xd8a4, 0x0002,
-		0xd8a5, 0x4218,
-		0xd8a6, 0x2474,
-		0xd8a7, 0x3c84,
-		0xd8a8, 0x6437,
-		0xd8a9, 0xdff4,
-		0xd8aa, 0x6437,
-		0xd8ab, 0x2ff5,
-		0xd8ac, 0x3c05,
-		0xd8ad, 0x8757,
-		0xd8ae, 0xb888,
-		0xd8af, 0x9787,
-		0xd8b0, 0xdff4,
-		0xd8b1, 0x6724,
-		0xd8b2, 0x866a,
-		0xd8b3, 0x6f72,
-		0xd8b4, 0x1002,
-		0xd8b5, 0x2641,
-		0xd8b6, 0x3021,
-		0xd8b7, 0x1001,
-		0xd8b8, 0xc620,
-		0xd8b9, 0x0000,
-		0xd8ba, 0xc621,
-		0xd8bb, 0x0000,
-		0xd8bc, 0xc622,
-		0xd8bd, 0x00ce,
-		0xd8be, 0xc623,
-		0xd8bf, 0x007f,
-		0xd8c0, 0xc624,
-		0xd8c1, 0x0032,
-		0xd8c2, 0xc625,
-		0xd8c3, 0x0000,
-		0xd8c4, 0xc627,
-		0xd8c5, 0x0000,
-		0xd8c6, 0xc628,
-		0xd8c7, 0x0000,
-		0xd8c8, 0xc62c,
-		0xd8c9, 0x0000,
-		0xd8ca, 0x0000,
-		0xd8cb, 0x2641,
-		0xd8cc, 0x3021,
-		0xd8cd, 0x1001,
-		0xd8ce, 0xc502,
-		0xd8cf, 0x53ac,
-		0xd8d0, 0xc503,
-		0xd8d1, 0x2cd3,
-		0xd8d2, 0xc600,
-		0xd8d3, 0x2a6e,
-		0xd8d4, 0xc601,
-		0xd8d5, 0x2a2c,
-		0xd8d6, 0xc605,
-		0xd8d7, 0x5557,
-		0xd8d8, 0xc60c,
-		0xd8d9, 0x5400,
-		0xd8da, 0xc710,
-		0xd8db, 0x0700,
-		0xd8dc, 0xc711,
-		0xd8dd, 0x0f06,
-		0xd8de, 0xc718,
-		0xd8df, 0x0700,
-		0xd8e0, 0xc719,
-		0xd8e1, 0x0f06,
-		0xd8e2, 0xc720,
-		0xd8e3, 0x4700,
-		0xd8e4, 0xc721,
-		0xd8e5, 0x0f06,
-		0xd8e6, 0xc728,
-		0xd8e7, 0x0700,
-		0xd8e8, 0xc729,
-		0xd8e9, 0x1207,
-		0xd8ea, 0xc801,
-		0xd8eb, 0x7f50,
-		0xd8ec, 0xc802,
-		0xd8ed, 0x7760,
-		0xd8ee, 0xc803,
-		0xd8ef, 0x7fce,
-		0xd8f0, 0xc804,
-		0xd8f1, 0x520e,
-		0xd8f2, 0xc805,
-		0xd8f3, 0x5c11,
-		0xd8f4, 0xc806,
-		0xd8f5, 0x3c51,
-		0xd8f6, 0xc807,
-		0xd8f7, 0x4061,
-		0xd8f8, 0xc808,
-		0xd8f9, 0x49c1,
-		0xd8fa, 0xc809,
-		0xd8fb, 0x3840,
-		0xd8fc, 0xc80a,
-		0xd8fd, 0x0000,
-		0xd8fe, 0xc821,
-		0xd8ff, 0x0002,
-		0xd900, 0xc822,
-		0xd901, 0x0046,
-		0xd902, 0xc844,
-		0xd903, 0x182f,
-		0xd904, 0xc013,
-		0xd905, 0xf341,
-		0xd906, 0xc084,
-		0xd907, 0x0030,
-		0xd908, 0xc904,
-		0xd909, 0x1401,
-		0xd90a, 0xcb0c,
-		0xd90b, 0x0004,
-		0xd90c, 0xcb0e,
-		0xd90d, 0xa00a,
-		0xd90e, 0xcb0f,
-		0xd90f, 0xc0c0,
-		0xd910, 0xcb10,
-		0xd911, 0xc0c0,
-		0xd912, 0xcb11,
-		0xd913, 0x00a0,
-		0xd914, 0xcb12,
-		0xd915, 0x0007,
-		0xd916, 0xc241,
-		0xd917, 0xa000,
-		0xd918, 0xc243,
-		0xd919, 0x7fe0,
-		0xd91a, 0xc604,
-		0xd91b, 0x000e,
-		0xd91c, 0xc609,
-		0xd91d, 0x00f5,
-		0xd91e, 0xc611,
-		0xd91f, 0x000e,
-		0xd920, 0xc660,
-		0xd921, 0x9600,
-		0xd922, 0xc687,
-		0xd923, 0x0004,
-		0xd924, 0xc60a,
-		0xd925, 0x04f5,
-		0xd926, 0x0000,
-		0xd927, 0x2641,
-		0xd928, 0x3021,
-		0xd929, 0x1001,
-		0xd92a, 0xc620,
-		0xd92b, 0x14e5,
-		0xd92c, 0xc621,
-		0xd92d, 0xc53d,
-		0xd92e, 0xc622,
-		0xd92f, 0x3cbe,
-		0xd930, 0xc623,
-		0xd931, 0x4452,
-		0xd932, 0xc624,
-		0xd933, 0xc5c5,
-		0xd934, 0xc625,
-		0xd935, 0xe01e,
-		0xd936, 0xc627,
-		0xd937, 0x0000,
-		0xd938, 0xc628,
-		0xd939, 0x0000,
-		0xd93a, 0xc62c,
-		0xd93b, 0x0000,
-		0xd93c, 0x0000,
-		0xd93d, 0x2b84,
-		0xd93e, 0x3c74,
-		0xd93f, 0x6435,
-		0xd940, 0xdff4,
-		0xd941, 0x6435,
-		0xd942, 0x2806,
-		0xd943, 0x3006,
-		0xd944, 0x8565,
-		0xd945, 0x2b24,
-		0xd946, 0x3c24,
-		0xd947, 0x6436,
-		0xd948, 0x1002,
-		0xd949, 0x2b24,
-		0xd94a, 0x3c24,
-		0xd94b, 0x6436,
-		0xd94c, 0x4045,
-		0xd94d, 0x8656,
-		0xd94e, 0x5663,
-		0xd94f, 0x0302,
-		0xd950, 0x401e,
-		0xd951, 0x1002,
-		0xd952, 0x2807,
-		0xd953, 0x31a7,
-		0xd954, 0x20c4,
-		0xd955, 0x3c24,
-		0xd956, 0x6724,
-		0xd957, 0x1002,
-		0xd958, 0x2807,
-		0xd959, 0x3187,
-		0xd95a, 0x20c4,
-		0xd95b, 0x3c24,
-		0xd95c, 0x6724,
-		0xd95d, 0x1002,
-		0xd95e, 0x24f4,
-		0xd95f, 0x3c64,
-		0xd960, 0x6436,
-		0xd961, 0xdff4,
-		0xd962, 0x6436,
-		0xd963, 0x1002,
-		0xd964, 0x2006,
-		0xd965, 0x3d76,
-		0xd966, 0xc161,
-		0xd967, 0x6134,
-		0xd968, 0x6135,
-		0xd969, 0x5443,
-		0xd96a, 0x0303,
-		0xd96b, 0x6524,
-		0xd96c, 0x00fb,
-		0xd96d, 0x1002,
-		0xd96e, 0x20d4,
-		0xd96f, 0x3c24,
-		0xd970, 0x2025,
-		0xd971, 0x3005,
-		0xd972, 0x6524,
-		0xd973, 0x1002,
-		0xd974, 0xd019,
-		0xd975, 0x2104,
-		0xd976, 0x3c24,
-		0xd977, 0x2105,
-		0xd978, 0x3805,
-		0xd979, 0x6524,
-		0xd97a, 0xdff4,
-		0xd97b, 0x4005,
-		0xd97c, 0x6524,
-		0xd97d, 0x2e8d,
-		0xd97e, 0x303d,
-		0xd97f, 0x2408,
-		0xd980, 0x35d8,
-		0xd981, 0x5dd3,
-		0xd982, 0x0307,
-		0xd983, 0x8887,
-		0xd984, 0x63a7,
-		0xd985, 0x8887,
-		0xd986, 0x63a7,
-		0xd987, 0xdffd,
-		0xd988, 0x00f9,
-		0xd989, 0x1002,
-		0xd98a, 0x0000,
-	};
 	int i, err;
 
 	/* set uC clock and activate it */
@@ -1612,10 +581,16 @@ static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
 	if (err)
 		return err;
 
-	/* write TWINAX EDC firmware into PHY */
-	for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
-		err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
-				    twinax_edc[i + 1]);
+	if (phy->priv != edc_twinax)
+		err = t3_get_edc_fw(phy, EDC_TWX_AEL2020,
+				    EDC_TWX_AEL2020_SIZE);
+	if (err)
+		return err;
+
+	for (i = 0; i <  EDC_TWX_AEL2020_SIZE / sizeof(u16) && !err; i += 2)
+		err = t3_mdio_write(phy, MDIO_MMD_PMAPMD,
+				    phy->phy_cache[i],
+				    phy->phy_cache[i + 1]);
 	/* activate uC */
 	err = set_phy_regs(phy, uCactivate);
 	if (!err)
@@ -1649,9 +624,39 @@ static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
  */
 static int ael2020_intr_enable(struct cphy *phy)
 {
-	int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
-				0x2 << (AEL2020_GPIO_MODDET*4));
-	return err ? err : t3_phy_lasi_intr_enable(phy);
+	struct reg_val regs[] = {
+		/* output Module's Loss Of Signal (LOS) to LED */
+		{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
+			0xffff, 0x4 },
+		{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+			0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
+
+		 /* enable module detect status change interrupts */
+		{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+			0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) },
+
+		/* end */
+		{ 0, 0, 0, 0 }
+	};
+	int err, link_ok = 0;
+
+	/* set up "link status" LED and enable module change interrupts */
+	err = set_phy_regs(phy, regs);
+	if (err)
+		return err;
+
+	err = get_link_status_r(phy, &link_ok, NULL, NULL, NULL);
+	if (err)
+		return err;
+	if (link_ok)
+		t3_link_changed(phy->adapter,
+				phy2portid(phy));
+
+	err = t3_phy_lasi_intr_enable(phy);
+	if (err)
+		return err;
+
+	return 0;
 }
 
 /*
@@ -1659,9 +664,26 @@ static int ael2020_intr_enable(struct cphy *phy)
  */
 static int ael2020_intr_disable(struct cphy *phy)
 {
-	int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
-				0x1 << (AEL2020_GPIO_MODDET*4));
-	return err ? err : t3_phy_lasi_intr_disable(phy);
+	struct reg_val regs[] = {
+		/* reset "link status" LED to "off" */
+		{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+			0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) },
+
+		/* disable module detect status change interrupts */
+		{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+			0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) },
+
+		/* end */
+		{ 0, 0, 0, 0 }
+	};
+	int err;
+
+	/* turn off "link status" LED and disable module change interrupts */
+	err = set_phy_regs(phy, regs);
+	if (err)
+		return err;
+
+	return t3_phy_lasi_intr_disable(phy);
 }
 
 /*
@@ -1679,31 +701,26 @@ static int ael2020_intr_clear(struct cphy *phy)
 	return err ? err : t3_phy_lasi_intr_clear(phy);
 }
 
+static struct reg_val ael2020_reset_regs[] = {
+	/* Erratum #2: CDRLOL asserted, causing PMA link down status */
+	{ MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 },
+
+	/* force XAUI to send LF when RX_LOS is asserted */
+	{ MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 },
+
+	/* allow writes to transceiver module EEPROM on i2c bus */
+	{ MDIO_MMD_PMAPMD, 0xff02, 0xffff, 0x0023 },
+	{ MDIO_MMD_PMAPMD, 0xff03, 0xffff, 0x0000 },
+	{ MDIO_MMD_PMAPMD, 0xff04, 0xffff, 0x0000 },
+
+	/* end */
+	{ 0, 0, 0, 0 }
+};
 /*
  * Reset the PHY and put it into a canonical operating state.
  */
 static int ael2020_reset(struct cphy *phy, int wait)
 {
-	static struct reg_val regs0[] = {
-		/* Erratum #2: CDRLOL asserted, causing PMA link down status */
-		{ MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 },
-
-		/* force XAUI to send LF when RX_LOS is asserted */
-		{ MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 },
-
-		/* RX_LOS pin is active high */
-		{ MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS,
-			0x0020, 0x0020 },
-
-		/* output Module's Loss Of Signal (LOS) to LED */
-		{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
-			0xffff, 0x0004 },
-		{ MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
-			0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
-
-		/* end */
-		{ 0, 0, 0, 0 }
-	};
 	int err;
 	unsigned int lasi_ctrl;
 
@@ -1720,7 +737,7 @@ static int ael2020_reset(struct cphy *phy, int wait)
 
 	/* basic initialization for all module types */
 	phy->priv = edc_none;
-	err = set_phy_regs(phy, regs0);
+	err = set_phy_regs(phy, ael2020_reset_regs);
 	if (err)
 		return err;
 
@@ -1798,10 +815,16 @@ static struct cphy_ops ael2020_ops = {
 int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
 			const struct mdio_ops *mdio_ops)
 {
+	int err;
+
 	cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops,
 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
 		  SUPPORTED_IRQ, "10GBASE-R");
 	msleep(125);
+
+	err = set_phy_regs(phy, ael2020_reset_regs);
+	if (err)
+		return err;
 	return 0;
 }
 
@@ -1840,7 +863,7 @@ static struct cphy_ops qt2045_ops = {
 	.intr_clear = t3_phy_lasi_intr_clear,
 	.intr_handler = t3_phy_lasi_intr_handler,
 	.get_link_status = get_link_status_x,
-	.power_down = ael1006_power_down,
+	.power_down = ael1002_power_down,
 	.mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
 };
 
diff --git a/drivers/net/cxgb3/aq100x.c b/drivers/net/cxgb3/aq100x.c
index b1fd5bf..341b7ef 100644
--- a/drivers/net/cxgb3/aq100x.c
+++ b/drivers/net/cxgb3/aq100x.c
@@ -271,7 +271,8 @@ int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
 
 	cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
 		  SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
-		  SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T");
+		  SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI,
+		  "1000/10GBASE-T");
 
 	/*
 	 * The PHY has been out of reset ever since the system powered up.  So
@@ -316,11 +317,9 @@ int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
 
 	/* Firmware version check. */
 	t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
-	if (v != 30) {
+	if (v != 101)
 		CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
 			phy_addr, v);
-		return 0; /* allow t3_prep_adapter to succeed */
-	}
 
 	/*
 	 * The PHY should start in really-low-power mode.  Prepare it for normal
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index d21b705..1b2c305 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -566,6 +566,15 @@ struct cphy_ops {
 
 	u32 mmds;
 };
+enum {
+	EDC_OPT_AEL2005 = 0,
+	EDC_OPT_AEL2005_SIZE = 1084,
+	EDC_TWX_AEL2005 = 1,
+	EDC_TWX_AEL2005_SIZE = 1464,
+	EDC_TWX_AEL2020 = 2,
+	EDC_TWX_AEL2020_SIZE = 1628,
+	EDC_MAX_SIZE = EDC_TWX_AEL2020_SIZE, /* Max cache size */
+};
 
 /* A PHY instance */
 struct cphy {
@@ -577,6 +586,7 @@ struct cphy {
 	unsigned long fifo_errors;	/* FIFO over/under-flows */
 	const struct cphy_ops *ops;	/* PHY operations */
 	struct mdio_if_info mdio;
+	u16 phy_cache[EDC_MAX_SIZE];	/* EDC cache */
 };
 
 /* Convenience MDIO read/write wrappers */
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index c97ab82..34e776c 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -172,6 +172,23 @@ static void link_report(struct net_device *dev)
 	}
 }
 
+static void enable_tx_fifo_drain(struct adapter *adapter,
+				 struct port_info *pi)
+{
+	t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset, 0,
+			 F_ENDROPPKT);
+	t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, 0);
+	t3_write_reg(adapter, A_XGM_TX_CTRL + pi->mac.offset, F_TXEN);
+	t3_write_reg(adapter, A_XGM_RX_CTRL + pi->mac.offset, F_RXEN);
+}
+
+static void disable_tx_fifo_drain(struct adapter *adapter,
+				  struct port_info *pi)
+{
+	t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + pi->mac.offset,
+			 F_ENDROPPKT, 0);
+}
+
 void t3_os_link_fault(struct adapter *adap, int port_id, int state)
 {
 	struct net_device *dev = adap->port[port_id];
@@ -185,6 +202,8 @@ void t3_os_link_fault(struct adapter *adap, int port_id, int state)
 
 		netif_carrier_on(dev);
 
+		disable_tx_fifo_drain(adap, pi);
+
 		/* Clear local faults */
 		t3_xgm_intr_disable(adap, pi->port_id);
 		t3_read_reg(adap, A_XGM_INT_STATUS +
@@ -200,9 +219,12 @@ void t3_os_link_fault(struct adapter *adap, int port_id, int state)
 		t3_xgm_intr_enable(adap, pi->port_id);
 
 		t3_mac_enable(mac, MAC_DIRECTION_TX);
-	} else
+	} else {
 		netif_carrier_off(dev);
 
+		/* Flush TX FIFO */
+		enable_tx_fifo_drain(adap, pi);
+	}
 	link_report(dev);
 }
 
@@ -232,6 +254,8 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
 
 	if (link_stat != netif_carrier_ok(dev)) {
 		if (link_stat) {
+			disable_tx_fifo_drain(adapter, pi);
+
 			t3_mac_enable(mac, MAC_DIRECTION_RX);
 
 			/* Clear local faults */
@@ -263,6 +287,9 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
 			t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset);
 			t3_mac_disable(mac, MAC_DIRECTION_RX);
 			t3_link_start(&pi->phy, mac, &pi->link_config);
+
+			/* Flush TX FIFO */
+			enable_tx_fifo_drain(adapter, pi);
 		}
 
 		link_report(dev);
@@ -443,6 +470,7 @@ static int init_tp_parity(struct adapter *adap)
 		memset(req, 0, sizeof(*req));
 		req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
 		OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
+		req->mtu_idx = NMTUS - 1;
 		req->iff = i;
 		t3_mgmt_tx(adap, skb);
 		if (skb == adap->nofail_skb) {
@@ -963,6 +991,75 @@ static int bind_qsets(struct adapter *adap)
 
 #define FW_FNAME "cxgb3/t3fw-%d.%d.%d.bin"
 #define TPSRAM_NAME "cxgb3/t3%c_psram-%d.%d.%d.bin"
+#define AEL2005_OPT_EDC_NAME "cxgb3/ael2005_opt_edc.bin"
+#define AEL2005_TWX_EDC_NAME "cxgb3/ael2005_twx_edc.bin"
+#define AEL2020_TWX_EDC_NAME "cxgb3/ael2020_twx_edc.bin"
+
+static inline const char *get_edc_fw_name(int edc_idx)
+{
+	const char *fw_name = NULL;
+
+	switch (edc_idx) {
+	case EDC_OPT_AEL2005:
+		fw_name = AEL2005_OPT_EDC_NAME;
+		break;
+	case EDC_TWX_AEL2005:
+		fw_name = AEL2005_TWX_EDC_NAME;
+		break;
+	case EDC_TWX_AEL2020:
+		fw_name = AEL2020_TWX_EDC_NAME;
+		break;
+	}
+	return fw_name;
+}
+
+int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size)
+{
+	struct adapter *adapter = phy->adapter;
+	const struct firmware *fw;
+	char buf[64];
+	u32 csum;
+	const __be32 *p;
+	u16 *cache = phy->phy_cache;
+	int i, ret;
+
+	snprintf(buf, sizeof(buf), get_edc_fw_name(edc_idx));
+
+	ret = request_firmware(&fw, buf, &adapter->pdev->dev);
+	if (ret < 0) {
+		dev_err(&adapter->pdev->dev,
+			"could not upgrade firmware: unable to load %s\n",
+			buf);
+		return ret;
+	}
+
+	/* check size, take checksum in account */
+	if (fw->size > size + 4) {
+		CH_ERR(adapter, "firmware image too large %u, expected %d\n",
+		       (unsigned int)fw->size, size + 4);
+		ret = -EINVAL;
+	}
+
+	/* compute checksum */
+	p = (const __be32 *)fw->data;
+	for (csum = 0, i = 0; i < fw->size / sizeof(csum); i++)
+		csum += ntohl(p[i]);
+
+	if (csum != 0xffffffff) {
+		CH_ERR(adapter, "corrupted firmware image, checksum %u\n",
+		       csum);
+		ret = -EINVAL;
+	}
+
+	for (i = 0; i < size / 4 ; i++) {
+		*cache++ = (be32_to_cpu(p[i]) & 0xffff0000) >> 16;
+		*cache++ = be32_to_cpu(p[i]) & 0xffff;
+	}
+
+	release_firmware(fw);
+
+	return ret;
+}
 
 static int upgrade_fw(struct adapter *adap)
 {
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 29c79eb..f866128 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1216,7 +1216,7 @@ static inline void t3_stop_tx_queue(struct netdev_queue *txq,
  *
  *	Add a packet to an SGE Tx queue.  Runs with softirqs disabled.
  */
-int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	int qidx;
 	unsigned int ndesc, pidx, credits, gen, compl;
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 870d449..032cfe0 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -3465,7 +3465,7 @@ static void config_pcie(struct adapter *adap)
 		{201, 321, 258, 450, 834, 1602}
 	};
 
-	u16 val;
+	u16 val, devid;
 	unsigned int log2_width, pldsize;
 	unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt;
 
@@ -3473,6 +3473,17 @@ static void config_pcie(struct adapter *adap)
 			     adap->params.pci.pcie_cap_addr + PCI_EXP_DEVCTL,
 			     &val);
 	pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
+
+	pci_read_config_word(adap->pdev, 0x2, &devid);
+	if (devid == 0x37) {
+		pci_write_config_word(adap->pdev,
+				      adap->params.pci.pcie_cap_addr +
+				      PCI_EXP_DEVCTL,
+				      val & ~PCI_EXP_DEVCTL_READRQ &
+				      ~PCI_EXP_DEVCTL_PAYLOAD);
+		pldsize = 0;
+	}
+
 	pci_read_config_word(adap->pdev,
 			     adap->params.pci.pcie_cap_addr + PCI_EXP_LNKCTL,
 			     &val);
@@ -3681,7 +3692,13 @@ static void mc7_prep(struct adapter *adapter, struct mc7 *mc7,
 
 void mac_prep(struct cmac *mac, struct adapter *adapter, int index)
 {
+	u16 devid;
+
 	mac->adapter = adapter;
+	pci_read_config_word(adapter->pdev, 0x2, &devid);
+
+	if (devid == 0x37 && !adapter->params.vpd.xauicfg[1])
+		index = 0;
 	mac->offset = (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR) * index;
 	mac->nucast = 1;
 
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index f87f943..0109ee4 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -447,11 +447,12 @@ int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc)
 
 	val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft);
 	val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM);
-	if (fc & PAUSE_TX)
-		val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(
-						t3_read_reg(adap,
-						A_XGM_RX_MAX_PKT_SIZE
-						+ oft)) / 8);
+	if (fc & PAUSE_TX) {
+		u32 rx_max_pkt_size =
+		    G_RXMAXPKTSIZE(t3_read_reg(adap,
+					       A_XGM_RX_MAX_PKT_SIZE + oft));
+		val |= V_RXFIFOPAUSEHWM(rx_fifo_hwm(rx_max_pkt_size) / 8);
+	}
 	t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val);
 
 	t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN,
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 12fd446..d465eaa 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -1920,7 +1920,6 @@ static int emac_net_rx_cb(struct emac_priv *priv,
 	skb_put(p_skb, net_pkt_list->pkt_length);
 	EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len);
 	p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
-	p_skb->dev->last_rx = jiffies;
 	netif_receive_skb(p_skb);
 	priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
 	priv->net_dev_stats.rx_packets++;
@@ -2817,7 +2816,7 @@ static int __init davinci_emac_init(void)
 {
 	return platform_driver_register(&davinci_emac_driver);
 }
-module_init(davinci_emac_init);
+late_initcall(davinci_emac_init);
 
 /**
  * davinci_emac_exit: EMAC driver module exit
diff --git a/drivers/net/de600.c b/drivers/net/de600.c
index e1af089..6b13f4f 100644
--- a/drivers/net/de600.c
+++ b/drivers/net/de600.c
@@ -226,7 +226,7 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	spin_unlock_irqrestore(&de600_lock, flags);
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
index 55d2bb6..45794f6 100644
--- a/drivers/net/de620.c
+++ b/drivers/net/de620.c
@@ -542,7 +542,7 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_packets++;
 	spin_unlock_irqrestore(&de620_lock, flags);
 	dev_kfree_skb (skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*****************************************************
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 2b22e58..a31696a 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -902,7 +902,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (len < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		len = ETH_ZLEN;
 	}
 
@@ -933,7 +933,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 	dev_kfree_skb(skb);
 
- 	return 0;
+ 	return NETDEV_TX_OK;
 }
 
 static void lance_load_multicast(struct net_device *dev)
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 102b8d4..6a6ea03 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -300,7 +300,8 @@ static int		dfx_rcv_init(DFX_board_t *bp, int get_buffers);
 static void		dfx_rcv_queue_process(DFX_board_t *bp);
 static void		dfx_rcv_flush(DFX_board_t *bp);
 
-static int		dfx_xmt_queue_pkt(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb,
+				     struct net_device *dev);
 static int		dfx_xmt_done(DFX_board_t *bp);
 static void		dfx_xmt_flush(DFX_board_t *bp);
 
@@ -3188,11 +3189,8 @@ static void dfx_rcv_queue_process(
  *   None
  */
 
-static int dfx_xmt_queue_pkt(
-	struct sk_buff	*skb,
-	struct net_device	*dev
-	)
-
+static netdev_tx_t dfx_xmt_queue_pkt(struct sk_buff *skb,
+				     struct net_device *dev)
 	{
 	DFX_board_t		*bp = netdev_priv(dev);
 	u8			prod;				/* local transmit producer index */
@@ -3218,7 +3216,7 @@ static int dfx_xmt_queue_pkt(
 		bp->xmt_length_errors++;		/* bump error counter */
 		netif_wake_queue(dev);
 		dev_kfree_skb(skb);
-		return(0);				/* return "success" */
+		return NETDEV_TX_OK;			/* return "success" */
 	}
 	/*
 	 * See if adapter link is available, if not, free buffer
@@ -3241,7 +3239,7 @@ static int dfx_xmt_queue_pkt(
 			bp->xmt_discards++;					/* bump error counter */
 			dev_kfree_skb(skb);		/* free sk_buff now */
 			netif_wake_queue(dev);
-			return(0);							/* return "success" */
+			return NETDEV_TX_OK;		/* return "success" */
 			}
 		}
 
@@ -3345,7 +3343,7 @@ static int dfx_xmt_queue_pkt(
 	dfx_port_write_long(bp, PI_PDQ_K_REG_TYPE_2_PROD, bp->rcv_xmt_reg.lword);
 	spin_unlock_irqrestore(&bp->lock, flags);
 	netif_wake_queue(dev);
-	return(0);							/* packet queued to adapter */
+	return NETDEV_TX_OK;	/* packet queued to adapter */
 	}
 
 
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 97ea2d6..9686c1f 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -516,7 +516,8 @@ struct depca_private {
 ** Public Functions
 */
 static int depca_open(struct net_device *dev);
-static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t depca_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev);
 static irqreturn_t depca_interrupt(int irq, void *dev_id);
 static int depca_close(struct net_device *dev);
 static int depca_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -928,7 +929,8 @@ static void depca_tx_timeout(struct net_device *dev)
 /*
 ** Writes a socket buffer to TX descriptor ring and starts transmission
 */
-static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t depca_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct depca_private *lp = netdev_priv(dev);
 	u_long ioaddr = dev->base_addr;
@@ -1793,7 +1795,7 @@ static int __init get_hw_addr(struct net_device *dev)
 static int load_packet(struct net_device *dev, struct sk_buff *skb)
 {
 	struct depca_private *lp = netdev_priv(dev);
-	int i, entry, end, len, status = 0;
+	int i, entry, end, len, status = NETDEV_TX_OK;
 
 	entry = lp->tx_new;	/* Ring around buffer number. */
 	end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index 4b6a219..7fa7a90 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -59,7 +59,7 @@ static int rio_open (struct net_device *dev);
 static void rio_timer (unsigned long data);
 static void rio_tx_timeout (struct net_device *dev);
 static void alloc_list (struct net_device *dev);
-static int start_xmit (struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t start_xmit (struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rio_interrupt (int irq, void *dev_instance);
 static void rio_free_tx (struct net_device *dev, int irq);
 static void tx_error (struct net_device *dev, int tx_status);
@@ -600,7 +600,7 @@ alloc_list (struct net_device *dev)
 	return;
 }
 
-static int
+static netdev_tx_t
 start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index dd771de..31b8bef 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -92,6 +92,7 @@ typedef struct board_info {
 	u16		tx_pkt_cnt;
 	u16		queue_pkt_len;
 	u16		queue_start_addr;
+	u16		queue_ip_summed;
 	u16		dbug_cnt;
 	u8		io_mode;		/* 0:word, 2:byte */
 	u8		phy_addr;
@@ -124,6 +125,10 @@ typedef struct board_info {
 
 	struct mii_if_info mii;
 	u32		msg_enable;
+
+	int		rx_csum;
+	int		can_csum;
+	int		ip_summed;
 } board_info_t;
 
 /* debug code */
@@ -460,6 +465,40 @@ static int dm9000_nway_reset(struct net_device *dev)
 	return mii_nway_restart(&dm->mii);
 }
 
+static uint32_t dm9000_get_rx_csum(struct net_device *dev)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	return dm->rx_csum;
+}
+
+static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	unsigned long flags;
+
+	if (dm->can_csum) {
+		dm->rx_csum = data;
+
+		spin_lock_irqsave(&dm->lock, flags);
+		iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0);
+		spin_unlock_irqrestore(&dm->lock, flags);
+
+		return 0;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	int ret = -EOPNOTSUPP;
+
+	if (dm->can_csum)
+		ret = ethtool_op_set_tx_csum(dev, data);
+	return ret;
+}
+
 static u32 dm9000_get_link(struct net_device *dev)
 {
 	board_info_t *dm = to_dm9000_board(dev);
@@ -540,6 +579,10 @@ static const struct ethtool_ops dm9000_ethtool_ops = {
  	.get_eeprom_len		= dm9000_get_eeprom_len,
  	.get_eeprom		= dm9000_get_eeprom,
  	.set_eeprom		= dm9000_set_eeprom,
+	.get_rx_csum		= dm9000_get_rx_csum,
+	.set_rx_csum		= dm9000_set_rx_csum,
+	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.set_tx_csum		= dm9000_set_tx_csum,
 };
 
 static void dm9000_show_carrier(board_info_t *db,
@@ -685,6 +728,9 @@ dm9000_init_dm9000(struct net_device *dev)
 	/* I/O mode */
 	db->io_mode = ior(db, DM9000_ISR) >> 6;	/* ISR bit7:6 keeps I/O mode */
 
+	/* Checksum mode */
+	dm9000_set_rx_csum(dev, db->rx_csum);
+
 	/* GPIO0 on pre-activate PHY */
 	iow(db, DM9000_GPR, 0);	/* REG_1F bit0 activate phyxcer */
 	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
@@ -743,6 +789,29 @@ static void dm9000_timeout(struct net_device *dev)
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
+static void dm9000_send_packet(struct net_device *dev,
+			       int ip_summed,
+			       u16 pkt_len)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	/* The DM9000 is not smart enough to leave fragmented packets alone. */
+	if (dm->ip_summed != ip_summed) {
+		if (ip_summed == CHECKSUM_NONE)
+			iow(dm, DM9000_TCCR, 0);
+		else
+			iow(dm, DM9000_TCCR, TCCR_IP | TCCR_UDP | TCCR_TCP);
+		dm->ip_summed = ip_summed;
+	}
+
+	/* Set TX length to DM9000 */
+	iow(dm, DM9000_TXPLL, pkt_len);
+	iow(dm, DM9000_TXPLH, pkt_len >> 8);
+
+	/* Issue TX polling command */
+	iow(dm, DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */
+}
+
 /*
  *  Hardware start transmission.
  *  Send a packet to media from the upper layer.
@@ -769,17 +838,11 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	db->tx_pkt_cnt++;
 	/* TX control: First packet immediately send, second packet queue */
 	if (db->tx_pkt_cnt == 1) {
-		/* Set TX length to DM9000 */
-		iow(db, DM9000_TXPLL, skb->len);
-		iow(db, DM9000_TXPLH, skb->len >> 8);
-
-		/* Issue TX polling command */
-		iow(db, DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */
-
-		dev->trans_start = jiffies;	/* save the time stamp */
+		dm9000_send_packet(dev, skb->ip_summed, skb->len);
 	} else {
 		/* Second packet */
 		db->queue_pkt_len = skb->len;
+		db->queue_ip_summed = skb->ip_summed;
 		netif_stop_queue(dev);
 	}
 
@@ -788,7 +851,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* free this SKB */
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -809,12 +872,9 @@ static void dm9000_tx_done(struct net_device *dev, board_info_t *db)
 			dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
 
 		/* Queue packet check & send */
-		if (db->tx_pkt_cnt > 0) {
-			iow(db, DM9000_TXPLL, db->queue_pkt_len);
-			iow(db, DM9000_TXPLH, db->queue_pkt_len >> 8);
-			iow(db, DM9000_TCR, TCR_TXREQ);
-			dev->trans_start = jiffies;
-		}
+		if (db->tx_pkt_cnt > 0)
+			dm9000_send_packet(dev, db->queue_ip_summed,
+					   db->queue_pkt_len);
 		netif_wake_queue(dev);
 	}
 }
@@ -846,14 +906,14 @@ dm9000_rx(struct net_device *dev)
 		rxbyte = readb(db->io_data);
 
 		/* Status check: this byte must be 0 or 1 */
-		if (rxbyte > DM9000_PKT_RDY) {
+		if (rxbyte & DM9000_PKT_ERR) {
 			dev_warn(db->dev, "status check fail: %d\n", rxbyte);
 			iow(db, DM9000_RCR, 0x00);	/* Stop Device */
 			iow(db, DM9000_ISR, IMR_PAR);	/* Stop INT request */
 			return;
 		}
 
-		if (rxbyte != DM9000_PKT_RDY)
+		if (!(rxbyte & DM9000_PKT_RDY))
 			return;
 
 		/* A packet ready now  & Get status/length */
@@ -914,6 +974,12 @@ dm9000_rx(struct net_device *dev)
 
 			/* Pass to upper layer */
 			skb->protocol = eth_type_trans(skb, dev);
+			if (db->rx_csum) {
+				if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)
+					skb->ip_summed = CHECKSUM_UNNECESSARY;
+				else
+					skb->ip_summed = CHECKSUM_NONE;
+			}
 			netif_rx(skb);
 			dev->stats.rx_packets++;
 
@@ -922,7 +988,7 @@ dm9000_rx(struct net_device *dev)
 
 			(db->dumpblk)(db->io_data, RxLen);
 		}
-	} while (rxbyte == DM9000_PKT_RDY);
+	} while (rxbyte & DM9000_PKT_RDY);
 }
 
 static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
@@ -1185,8 +1251,6 @@ static const struct net_device_ops dm9000_netdev_ops = {
 #endif
 };
 
-#define res_size(_r) (((_r)->end - (_r)->start) + 1)
-
 /*
  * Search DM9000 board, allocate space and register it
  */
@@ -1215,7 +1279,6 @@ dm9000_probe(struct platform_device *pdev)
 
 	/* setup board info structure */
 	db = netdev_priv(ndev);
-	memset(db, 0, sizeof(*db));
 
 	db->dev = &pdev->dev;
 	db->ndev = ndev;
@@ -1236,7 +1299,7 @@ dm9000_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	iosize = res_size(db->addr_res);
+	iosize = resource_size(db->addr_res);
 	db->addr_req = request_mem_region(db->addr_res->start, iosize,
 					  pdev->name);
 
@@ -1254,7 +1317,7 @@ dm9000_probe(struct platform_device *pdev)
 		goto out;
 	}
 
-	iosize = res_size(db->data_res);
+	iosize = resource_size(db->data_res);
 	db->data_req = request_mem_region(db->data_res->start, iosize,
 					  pdev->name);
 
@@ -1349,6 +1412,13 @@ dm9000_probe(struct platform_device *pdev)
 		db->type = TYPE_DM9000E;
 	}
 
+	/* dm9000a/b are capable of hardware checksum offload */
+	if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {
+		db->can_csum = 1;
+		db->rx_csum = 1;
+		ndev->features |= NETIF_F_IP_CSUM;
+	}
+
 	/* from this point we assume that we have found a DM9000 */
 
 	/* driver system function */
@@ -1410,9 +1480,10 @@ out:
 }
 
 static int
-dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
+dm9000_drv_suspend(struct device *dev)
 {
-	struct net_device *ndev = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 	board_info_t *db;
 
 	if (ndev) {
@@ -1428,9 +1499,10 @@ dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
 }
 
 static int
-dm9000_drv_resume(struct platform_device *dev)
+dm9000_drv_resume(struct device *dev)
 {
-	struct net_device *ndev = platform_get_drvdata(dev);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct net_device *ndev = platform_get_drvdata(pdev);
 	board_info_t *db = netdev_priv(ndev);
 
 	if (ndev) {
@@ -1447,6 +1519,11 @@ dm9000_drv_resume(struct platform_device *dev)
 	return 0;
 }
 
+static struct dev_pm_ops dm9000_drv_pm_ops = {
+	.suspend	= dm9000_drv_suspend,
+	.resume		= dm9000_drv_resume,
+};
+
 static int __devexit
 dm9000_drv_remove(struct platform_device *pdev)
 {
@@ -1466,11 +1543,10 @@ static struct platform_driver dm9000_driver = {
 	.driver	= {
 		.name    = "dm9000",
 		.owner	 = THIS_MODULE,
+		.pm	 = &dm9000_drv_pm_ops,
 	},
 	.probe   = dm9000_probe,
 	.remove  = __devexit_p(dm9000_drv_remove),
-	.suspend = dm9000_drv_suspend,
-	.resume  = dm9000_drv_resume,
 };
 
 static int __init
diff --git a/drivers/net/dm9000.h b/drivers/net/dm9000.h
index ba25cf5..80817c2 100644
--- a/drivers/net/dm9000.h
+++ b/drivers/net/dm9000.h
@@ -45,6 +45,10 @@
 #define DM9000_CHIPR           0x2C
 #define DM9000_SMCR            0x2F
 
+#define DM9000_ETXCSR          0x30
+#define DM9000_TCCR	       0x31
+#define DM9000_RCSR	       0x32
+
 #define CHIPR_DM9000A	       0x19
 #define CHIPR_DM9000B	       0x1B
 
@@ -131,7 +135,21 @@
 
 #define GPCR_GEP_CNTL       (1<<0)
 
+#define TCCR_IP		    (1<<0)
+#define TCCR_TCP	    (1<<1)
+#define TCCR_UDP	    (1<<2)
+
+#define RCSR_UDP_BAD	    (1<<7)
+#define RCSR_TCP_BAD	    (1<<6)
+#define RCSR_IP_BAD	    (1<<5)
+#define RCSR_UDP	    (1<<4)
+#define RCSR_TCP	    (1<<3)
+#define RCSR_IP		    (1<<2)
+#define RCSR_CSUM	    (1<<1)
+#define RCSR_DISCARD	    (1<<0)
+
 #define DM9000_PKT_RDY		0x01	/* Packet ready to receive */
+#define DM9000_PKT_ERR		0x02
 #define DM9000_PKT_MAX		1536	/* Received packet max size */
 
 /* DM9000A / DM9000B definitions */
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index 33fa9ee..2346852 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -541,7 +541,7 @@ static inline void dnet_print_skb(struct sk_buff *skb)
 #define dnet_print_skb(skb)	do {} while (0)
 #endif
 
-static int dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 
 	struct dnet *bp = netdev_priv(dev);
@@ -596,7 +596,7 @@ static int dnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void dnet_reset_hw(struct dnet *bp)
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 8ebd7d7..37dcfdc 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -39,8 +39,6 @@
 
 static int numdummies = 1;
 
-static int dummy_xmit(struct sk_buff *skb, struct net_device *dev);
-
 static int dummy_set_address(struct net_device *dev, void *p)
 {
 	struct sockaddr *sa = p;
@@ -57,6 +55,16 @@ static void set_multicast_list(struct net_device *dev)
 {
 }
 
+
+static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
+
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
 static const struct net_device_ops dummy_netdev_ops = {
 	.ndo_start_xmit		= dummy_xmit,
 	.ndo_validate_addr	= eth_validate_addr,
@@ -78,16 +86,6 @@ static void dummy_setup(struct net_device *dev)
 	dev->flags &= ~IFF_MULTICAST;
 	random_ether_addr(dev->dev_addr);
 }
-
-static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	dev->stats.tx_packets++;
-	dev->stats.tx_bytes += skb->len;
-
-	dev_kfree_skb(skb);
-	return 0;
-}
-
 static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
 {
 	if (tb[IFLA_ADDRESS]) {
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 3a6735d..679965c 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1690,7 +1690,8 @@ static void e100_xmit_prepare(struct nic *nic, struct cb *cb,
 	cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
 }
 
-static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t e100_xmit_frame(struct sk_buff *skb,
+				   struct net_device *netdev)
 {
 	struct nic *nic = netdev_priv(netdev);
 	int err;
@@ -1720,7 +1721,7 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	netdev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int e100_tx_clean(struct nic *nic)
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index e9a416f..1a4f89c 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -111,6 +111,9 @@ do {									\
 #define E1000_MIN_RXD                       80
 #define E1000_MAX_82544_RXD               4096
 
+#define E1000_MIN_ITR_USECS		10 /* 100000 irq/sec */
+#define E1000_MAX_ITR_USECS		10000 /* 100    irq/sec */
+
 /* this is the size past which hardware will drop packets when setting LPE=0 */
 #define MAXIMUM_ETHERNET_VLAN_SIZE 1522
 
@@ -137,7 +140,7 @@ do {									\
 #define E1000_FC_HIGH_DIFF 0x1638  /* High: 5688 bytes below Rx FIFO size */
 #define E1000_FC_LOW_DIFF 0x1640   /* Low:  5696 bytes below Rx FIFO size */
 
-#define E1000_FC_PAUSE_TIME 0x0680 /* 858 usec */
+#define E1000_FC_PAUSE_TIME 0xFFFF /* pause for the max or until send xon */
 
 /* How many Tx Descriptors do we need to call netif_wake_queue ? */
 #define E1000_TX_QUEUE_WAKE	16
@@ -161,6 +164,7 @@ do {									\
 struct e1000_buffer {
 	struct sk_buff *skb;
 	dma_addr_t dma;
+	struct page *page;
 	unsigned long time_stamp;
 	u16 length;
 	u16 next_to_watch;
@@ -202,6 +206,7 @@ struct e1000_rx_ring {
 	unsigned int next_to_clean;
 	/* array of buffer information structs */
 	struct e1000_buffer *buffer_info;
+	struct sk_buff *rx_skb_top;
 
 	/* cpu for rx queue */
 	int cpu;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index c854c96..27f996a 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1904,6 +1904,53 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
 	return 0;
 }
 
+static int e1000_get_coalesce(struct net_device *netdev,
+			      struct ethtool_coalesce *ec)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+
+	if (adapter->hw.mac_type < e1000_82545)
+		return -EOPNOTSUPP;
+
+	if (adapter->itr_setting <= 3)
+		ec->rx_coalesce_usecs = adapter->itr_setting;
+	else
+		ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
+
+	return 0;
+}
+
+static int e1000_set_coalesce(struct net_device *netdev,
+			      struct ethtool_coalesce *ec)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (hw->mac_type < e1000_82545)
+		return -EOPNOTSUPP;
+
+	if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) ||
+	    ((ec->rx_coalesce_usecs > 3) &&
+	     (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) ||
+	    (ec->rx_coalesce_usecs == 2))
+		return -EINVAL;
+
+	if (ec->rx_coalesce_usecs <= 3) {
+		adapter->itr = 20000;
+		adapter->itr_setting = ec->rx_coalesce_usecs;
+	} else {
+		adapter->itr = (1000000 / ec->rx_coalesce_usecs);
+		adapter->itr_setting = adapter->itr & ~3;
+	}
+
+	if (adapter->itr_setting != 0)
+		ew32(ITR, 1000000000 / (adapter->itr * 256));
+	else
+		ew32(ITR, 0);
+
+	return 0;
+}
+
 static int e1000_nway_reset(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -1978,7 +2025,9 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.get_strings            = e1000_get_strings,
 	.phys_id                = e1000_phys_id,
 	.get_ethtool_stats      = e1000_get_ethtool_stats,
-	.get_sset_count		= e1000_get_sset_count,
+	.get_sset_count         = e1000_get_sset_count,
+	.get_coalesce           = e1000_get_coalesce,
+	.set_coalesce           = e1000_set_coalesce,
 };
 
 void e1000_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index e1a3fc1..cda6b39 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -1955,7 +1955,7 @@ static s32 e1000_setup_copper_link(struct e1000_hw *hw)
     s32 ret_val;
     u16 i;
     u16 phy_data;
-    u16 reg_data;
+    u16 reg_data = 0;
 
     DEBUGFUNC("e1000_setup_copper_link");
 
@@ -5759,52 +5759,6 @@ u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
 }
 
 /******************************************************************************
- * Sets the bit in the multicast table corresponding to the hash value.
- *
- * hw - Struct containing variables accessed by shared code
- * hash_value - Multicast address hash value
- *****************************************************************************/
-void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
-{
-    u32 hash_bit, hash_reg;
-    u32 mta;
-    u32 temp;
-
-    /* The MTA is a register array of 128 32-bit registers.
-     * It is treated like an array of 4096 bits.  We want to set
-     * bit BitArray[hash_value]. So we figure out what register
-     * the bit is in, read it, OR in the new bit, then write
-     * back the new value.  The register is determined by the
-     * upper 7 bits of the hash value and the bit within that
-     * register are determined by the lower 5 bits of the value.
-     */
-    hash_reg = (hash_value >> 5) & 0x7F;
-    if (hw->mac_type == e1000_ich8lan)
-        hash_reg &= 0x1F;
-
-    hash_bit = hash_value & 0x1F;
-
-    mta = E1000_READ_REG_ARRAY(hw, MTA, hash_reg);
-
-    mta |= (1 << hash_bit);
-
-    /* If we are on an 82544 and we are trying to write an odd offset
-     * in the MTA, save off the previous entry before writing and
-     * restore the old value after writing.
-     */
-    if ((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) {
-        temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1));
-        E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
-        E1000_WRITE_FLUSH();
-        E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp);
-        E1000_WRITE_FLUSH();
-    } else {
-        E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
-        E1000_WRITE_FLUSH();
-    }
-}
-
-/******************************************************************************
  * Puts an ethernet address into a receive address register.
  *
  * hw - Struct containing variables accessed by shared code
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 99fce2c..a8866bd 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -523,11 +523,8 @@ s32 e1000_check_phy_reset_block(struct e1000_hw *hw);
 
 /* The sizes (in bytes) of a ethernet packet */
 #define ENET_HEADER_SIZE             14
-#define MAXIMUM_ETHERNET_FRAME_SIZE  1518 /* With FCS */
 #define MINIMUM_ETHERNET_FRAME_SIZE  64   /* With FCS */
 #define ETHERNET_FCS_SIZE            4
-#define MAXIMUM_ETHERNET_PACKET_SIZE \
-    (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
 #define MINIMUM_ETHERNET_PACKET_SIZE \
     (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
 #define CRC_LENGTH                   ETHERNET_FCS_SIZE
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 5b8cbdb..c66dd4f 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -125,7 +125,8 @@ static void e1000_set_rx_mode(struct net_device *netdev);
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
 static void e1000_82547_tx_fifo_stall(unsigned long data);
-static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
+				    struct net_device *netdev);
 static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
 static int e1000_set_mac(struct net_device *netdev, void *p);
@@ -137,9 +138,15 @@ static int e1000_clean(struct napi_struct *napi, int budget);
 static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 			       struct e1000_rx_ring *rx_ring,
 			       int *work_done, int work_to_do);
+static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
+				     struct e1000_rx_ring *rx_ring,
+				     int *work_done, int work_to_do);
 static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
-                                   struct e1000_rx_ring *rx_ring,
+				   struct e1000_rx_ring *rx_ring,
 				   int cleaned_count);
+static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
+					 struct e1000_rx_ring *rx_ring,
+					 int cleaned_count);
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 			   int cmd);
@@ -635,8 +642,8 @@ void e1000_reset(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
-	u16 fc_high_water_mark = E1000_FC_HIGH_DIFF;
 	bool legacy_pba_adjust = false;
+	u16 hwm;
 
 	/* Repartition Pba for greater than 9k mtu
 	 * To take effect CTRL.RST is required.
@@ -680,7 +687,7 @@ void e1000_reset(struct e1000_adapter *adapter)
 	}
 
 	if (legacy_pba_adjust) {
-		if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
+		if (hw->max_frame_size > E1000_RXBUFFER_8192)
 			pba -= 8; /* allocate more FIFO for Tx */
 
 		if (hw->mac_type == e1000_82547) {
@@ -690,14 +697,14 @@ void e1000_reset(struct e1000_adapter *adapter)
 				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
 			atomic_set(&adapter->tx_fifo_stall, 0);
 		}
-	} else if (hw->max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
+	} else if (hw->max_frame_size >  ETH_FRAME_LEN + ETH_FCS_LEN) {
 		/* adjust PBA for jumbo frames */
 		ew32(PBA, pba);
 
 		/* To maintain wire speed transmits, the Tx FIFO should be
-		 * large enough to accomodate two full transmit packets,
+		 * large enough to accommodate two full transmit packets,
 		 * rounded up to the next 1KB and expressed in KB.  Likewise,
-		 * the Rx FIFO should be large enough to accomodate at least
+		 * the Rx FIFO should be large enough to accommodate at least
 		 * one full receive packet and is similarly rounded up and
 		 * expressed in KB. */
 		pba = er32(PBA);
@@ -705,13 +712,17 @@ void e1000_reset(struct e1000_adapter *adapter)
 		tx_space = pba >> 16;
 		/* lower 16 bits has Rx packet buffer allocation size in KB */
 		pba &= 0xffff;
-		/* don't include ethernet FCS because hardware appends/strips */
-		min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
-		               VLAN_TAG_SIZE;
-		min_tx_space = min_rx_space;
-		min_tx_space *= 2;
+		/*
+		 * the tx fifo also stores 16 bytes of information about the tx
+		 * but don't include ethernet FCS because hardware appends it
+		 */
+		min_tx_space = (hw->max_frame_size +
+		                sizeof(struct e1000_tx_desc) -
+		                ETH_FCS_LEN) * 2;
 		min_tx_space = ALIGN(min_tx_space, 1024);
 		min_tx_space >>= 10;
+		/* software strips receive CRC, so leave room for it */
+		min_rx_space = hw->max_frame_size;
 		min_rx_space = ALIGN(min_rx_space, 1024);
 		min_rx_space >>= 10;
 
@@ -748,23 +759,22 @@ void e1000_reset(struct e1000_adapter *adapter)
 
 	ew32(PBA, pba);
 
-	/* flow control settings */
-	/* Set the FC high water mark to 90% of the FIFO size.
-	 * Required to clear last 3 LSB */
-	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
-	/* We can't use 90% on small FIFOs because the remainder
-	 * would be less than 1 full frame.  In this case, we size
-	 * it to allow at least a full frame above the high water
-	 *  mark. */
-	if (pba < E1000_PBA_16K)
-		fc_high_water_mark = (pba * 1024) - 1600;
-
-	hw->fc_high_water = fc_high_water_mark;
-	hw->fc_low_water = fc_high_water_mark - 8;
-	if (hw->mac_type == e1000_80003es2lan)
-		hw->fc_pause_time = 0xFFFF;
-	else
-		hw->fc_pause_time = E1000_FC_PAUSE_TIME;
+	/*
+	 * flow control settings:
+	 * The high water mark must be low enough to fit one full frame
+	 * (or the size used for early receive) above it in the Rx FIFO.
+	 * Set it to the lower of:
+	 * - 90% of the Rx FIFO size, and
+	 * - the full Rx FIFO size minus the early receive size (for parts
+	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
+	 * - the full Rx FIFO size minus one full frame
+	 */
+	hwm = min(((pba << 10) * 9 / 10),
+		  ((pba << 10) - hw->max_frame_size));
+
+	hw->fc_high_water = hwm & 0xFFF8;	/* 8-byte granularity */
+	hw->fc_low_water = hw->fc_high_water - 8;
+	hw->fc_pause_time = E1000_FC_PAUSE_TIME;
 	hw->fc_send_xon = 1;
 	hw->fc = hw->original_fc;
 
@@ -1862,6 +1872,7 @@ setup_rx_desc_die:
 
 	rxdr->next_to_clean = 0;
 	rxdr->next_to_use = 0;
+	rxdr->rx_skb_top = NULL;
 
 	return 0;
 }
@@ -1968,10 +1979,17 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rdlen, rctl, rxcsum, ctrl_ext;
 
-	rdlen = adapter->rx_ring[0].count *
-		sizeof(struct e1000_rx_desc);
-	adapter->clean_rx = e1000_clean_rx_irq;
-	adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
+	if (adapter->netdev->mtu > ETH_DATA_LEN) {
+		rdlen = adapter->rx_ring[0].count *
+		        sizeof(struct e1000_rx_desc);
+		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
+		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
+	} else {
+		rdlen = adapter->rx_ring[0].count *
+		        sizeof(struct e1000_rx_desc);
+		adapter->clean_rx = e1000_clean_rx_irq;
+		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
+	}
 
 	/* disable receives while setting up the descriptors */
 	rctl = er32(RCTL);
@@ -2185,26 +2203,39 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
 	/* Free all the Rx ring sk_buffs */
 	for (i = 0; i < rx_ring->count; i++) {
 		buffer_info = &rx_ring->buffer_info[i];
-		if (buffer_info->dma) {
-			pci_unmap_single(pdev,
-					 buffer_info->dma,
-					 buffer_info->length,
-					 PCI_DMA_FROMDEVICE);
+		if (buffer_info->dma &&
+		    adapter->clean_rx == e1000_clean_rx_irq) {
+			pci_unmap_single(pdev, buffer_info->dma,
+			                 buffer_info->length,
+			                 PCI_DMA_FROMDEVICE);
+		} else if (buffer_info->dma &&
+		           adapter->clean_rx == e1000_clean_jumbo_rx_irq) {
+			pci_unmap_page(pdev, buffer_info->dma,
+			               buffer_info->length,
+			               PCI_DMA_FROMDEVICE);
 		}
 
 		buffer_info->dma = 0;
-
+		if (buffer_info->page) {
+			put_page(buffer_info->page);
+			buffer_info->page = NULL;
+		}
 		if (buffer_info->skb) {
 			dev_kfree_skb(buffer_info->skb);
 			buffer_info->skb = NULL;
 		}
 	}
 
+	/* there also may be some cached data from a chained receive */
+	if (rx_ring->rx_skb_top) {
+		dev_kfree_skb(rx_ring->rx_skb_top);
+		rx_ring->rx_skb_top = NULL;
+	}
+
 	size = sizeof(struct e1000_buffer) * rx_ring->count;
 	memset(rx_ring->buffer_info, 0, size);
 
 	/* Zero out the descriptor ring */
-
 	memset(rx_ring->desc, 0, rx_ring->size);
 
 	rx_ring->next_to_clean = 0;
@@ -2371,7 +2402,9 @@ static void e1000_set_rx_mode(struct net_device *netdev)
 			rctl &= ~E1000_RCTL_MPE;
 		}
 		if (adapter->hw.mac_type != e1000_ich8lan)
-			rctl |= E1000_RCTL_VFE;
+			/* Enable VLAN filter if there is a VLAN */
+			if (adapter->vlgrp)
+				rctl |= E1000_RCTL_VFE;
 	}
 
 	if (netdev->uc.count > rar_entries - 1) {
@@ -3219,7 +3252,8 @@ static int e1000_maybe_stop_tx(struct net_device *netdev,
 }
 
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
-static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
+				    struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
@@ -3450,7 +3484,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	switch (hw->mac_type) {
 	case e1000_undefined ... e1000_82542_rev2_1:
 	case e1000_ich8lan:
-		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
+		if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
 			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
 			return -EINVAL;
 		}
@@ -3463,7 +3497,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 		                  &eeprom_data);
 		if ((hw->device_id != E1000_DEV_ID_82573L) ||
 		    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
-			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
+			if (max_frame > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
 				DPRINTK(PROBE, ERR,
 			            	"Jumbo Frames not supported.\n");
 				return -EINVAL;
@@ -3489,8 +3523,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 
 	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
 	 * means we reserve 2 more, this pushes us to allocate from the next
-	 * larger slab size
-	 * i.e. RXBUFFER_2048 --> size-4096 slab */
+	 * larger slab size.
+	 * i.e. RXBUFFER_2048 --> size-4096 slab
+	 *  however with the new *_jumbo_rx* routines, jumbo receives will use
+	 *  fragmented skbs */
 
 	if (max_frame <= E1000_RXBUFFER_256)
 		adapter->rx_buffer_len = E1000_RXBUFFER_256;
@@ -3500,16 +3536,16 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
 	else if (max_frame <= E1000_RXBUFFER_2048)
 		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
-	else if (max_frame <= E1000_RXBUFFER_4096)
-		adapter->rx_buffer_len = E1000_RXBUFFER_4096;
-	else if (max_frame <= E1000_RXBUFFER_8192)
-		adapter->rx_buffer_len = E1000_RXBUFFER_8192;
-	else if (max_frame <= E1000_RXBUFFER_16384)
+	else
+#if (PAGE_SIZE >= E1000_RXBUFFER_16384)
 		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
+#elif (PAGE_SIZE >= E1000_RXBUFFER_4096)
+		adapter->rx_buffer_len = PAGE_SIZE;
+#endif
 
 	/* adjust allocation if LPE protects us, and we aren't using SBP */
 	if (!hw->tbi_compatibility_on &&
-	    ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
+	    ((max_frame == (ETH_FRAME_LEN + ETH_FCS_LEN)) ||
 	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
 		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
 
@@ -3987,9 +4023,227 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
 }
 
 /**
+ * e1000_consume_page - helper function
+ **/
+static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
+                               u16 length)
+{
+	bi->page = NULL;
+	skb->len += length;
+	skb->data_len += length;
+	skb->truesize += length;
+}
+
+/**
+ * e1000_receive_skb - helper function to handle rx indications
+ * @adapter: board private structure
+ * @status: descriptor status field as written by hardware
+ * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @skb: pointer to sk_buff to be indicated to stack
+ */
+static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status,
+			      __le16 vlan, struct sk_buff *skb)
+{
+	if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) {
+		vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+		                         le16_to_cpu(vlan) &
+		                         E1000_RXD_SPC_VLAN_MASK);
+	} else {
+		netif_receive_skb(skb);
+	}
+}
+
+/**
+ * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
+ * @adapter: board private structure
+ * @rx_ring: ring to clean
+ * @work_done: amount of napi work completed this call
+ * @work_to_do: max amount of work allowed for this call to do
+ *
+ * the return value indicates whether actual cleaning was done, there
+ * is no guarantee that everything was cleaned
+ */
+static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
+				     struct e1000_rx_ring *rx_ring,
+				     int *work_done, int work_to_do)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct e1000_rx_desc *rx_desc, *next_rxd;
+	struct e1000_buffer *buffer_info, *next_buffer;
+	unsigned long irq_flags;
+	u32 length;
+	unsigned int i;
+	int cleaned_count = 0;
+	bool cleaned = false;
+	unsigned int total_rx_bytes=0, total_rx_packets=0;
+
+	i = rx_ring->next_to_clean;
+	rx_desc = E1000_RX_DESC(*rx_ring, i);
+	buffer_info = &rx_ring->buffer_info[i];
+
+	while (rx_desc->status & E1000_RXD_STAT_DD) {
+		struct sk_buff *skb;
+		u8 status;
+
+		if (*work_done >= work_to_do)
+			break;
+		(*work_done)++;
+
+		status = rx_desc->status;
+		skb = buffer_info->skb;
+		buffer_info->skb = NULL;
+
+		if (++i == rx_ring->count) i = 0;
+		next_rxd = E1000_RX_DESC(*rx_ring, i);
+		prefetch(next_rxd);
+
+		next_buffer = &rx_ring->buffer_info[i];
+
+		cleaned = true;
+		cleaned_count++;
+		pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
+		               PCI_DMA_FROMDEVICE);
+		buffer_info->dma = 0;
+
+		length = le16_to_cpu(rx_desc->length);
+
+		/* errors is only valid for DD + EOP descriptors */
+		if (unlikely((status & E1000_RXD_STAT_EOP) &&
+		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
+			u8 last_byte = *(skb->data + length - 1);
+			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
+				       last_byte)) {
+				spin_lock_irqsave(&adapter->stats_lock,
+				                  irq_flags);
+				e1000_tbi_adjust_stats(hw, &adapter->stats,
+				                       length, skb->data);
+				spin_unlock_irqrestore(&adapter->stats_lock,
+				                       irq_flags);
+				length--;
+			} else {
+				/* recycle both page and skb */
+				buffer_info->skb = skb;
+				/* an error means any chain goes out the window
+				 * too */
+				if (rx_ring->rx_skb_top)
+					dev_kfree_skb(rx_ring->rx_skb_top);
+				rx_ring->rx_skb_top = NULL;
+				goto next_desc;
+			}
+		}
+
+#define rxtop rx_ring->rx_skb_top
+		if (!(status & E1000_RXD_STAT_EOP)) {
+			/* this descriptor is only the beginning (or middle) */
+			if (!rxtop) {
+				/* this is the beginning of a chain */
+				rxtop = skb;
+				skb_fill_page_desc(rxtop, 0, buffer_info->page,
+				                   0, length);
+			} else {
+				/* this is the middle of a chain */
+				skb_fill_page_desc(rxtop,
+				    skb_shinfo(rxtop)->nr_frags,
+				    buffer_info->page, 0, length);
+				/* re-use the skb, only consumed the page */
+				buffer_info->skb = skb;
+			}
+			e1000_consume_page(buffer_info, rxtop, length);
+			goto next_desc;
+		} else {
+			if (rxtop) {
+				/* end of the chain */
+				skb_fill_page_desc(rxtop,
+				    skb_shinfo(rxtop)->nr_frags,
+				    buffer_info->page, 0, length);
+				/* re-use the current skb, we only consumed the
+				 * page */
+				buffer_info->skb = skb;
+				skb = rxtop;
+				rxtop = NULL;
+				e1000_consume_page(buffer_info, skb, length);
+			} else {
+				/* no chain, got EOP, this buf is the packet
+				 * copybreak to save the put_page/alloc_page */
+				if (length <= copybreak &&
+				    skb_tailroom(skb) >= length) {
+					u8 *vaddr;
+					vaddr = kmap_atomic(buffer_info->page,
+					                    KM_SKB_DATA_SOFTIRQ);
+					memcpy(skb_tail_pointer(skb), vaddr, length);
+					kunmap_atomic(vaddr,
+					              KM_SKB_DATA_SOFTIRQ);
+					/* re-use the page, so don't erase
+					 * buffer_info->page */
+					skb_put(skb, length);
+				} else {
+					skb_fill_page_desc(skb, 0,
+					                   buffer_info->page, 0,
+				                           length);
+					e1000_consume_page(buffer_info, skb,
+					                   length);
+				}
+			}
+		}
+
+		/* Receive Checksum Offload XXX recompute due to CRC strip? */
+		e1000_rx_checksum(adapter,
+		                  (u32)(status) |
+		                  ((u32)(rx_desc->errors) << 24),
+		                  le16_to_cpu(rx_desc->csum), skb);
+
+		pskb_trim(skb, skb->len - 4);
+
+		/* probably a little skewed due to removing CRC */
+		total_rx_bytes += skb->len;
+		total_rx_packets++;
+
+		/* eth type trans needs skb->data to point to something */
+		if (!pskb_may_pull(skb, ETH_HLEN)) {
+			DPRINTK(DRV, ERR, "pskb_may_pull failed.\n");
+			dev_kfree_skb(skb);
+			goto next_desc;
+		}
+
+		skb->protocol = eth_type_trans(skb, netdev);
+
+		e1000_receive_skb(adapter, status, rx_desc->special, skb);
+
+next_desc:
+		rx_desc->status = 0;
+
+		/* return some buffers to hardware, one at a time is too slow */
+		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
+			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
+			cleaned_count = 0;
+		}
+
+		/* use prefetched values */
+		rx_desc = next_rxd;
+		buffer_info = next_buffer;
+	}
+	rx_ring->next_to_clean = i;
+
+	cleaned_count = E1000_DESC_UNUSED(rx_ring);
+	if (cleaned_count)
+		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
+
+	adapter->total_rx_packets += total_rx_packets;
+	adapter->total_rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
+	return cleaned;
+}
+
+/**
  * e1000_clean_rx_irq - Send received data up the network stack; legacy
  * @adapter: board private structure
- **/
+ * @rx_ring: ring to clean
+ * @work_done: amount of napi work completed this call
+ * @work_to_do: max amount of work allowed for this call to do
+ */
 static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 			       struct e1000_rx_ring *rx_ring,
 			       int *work_done, int work_to_do)
@@ -4001,7 +4255,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 	struct e1000_buffer *buffer_info, *next_buffer;
 	unsigned long flags;
 	u32 length;
-	u8 last_byte;
 	unsigned int i;
 	int cleaned_count = 0;
 	bool cleaned = false;
@@ -4033,9 +4286,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 
 		cleaned = true;
 		cleaned_count++;
-		pci_unmap_single(pdev,
-		                 buffer_info->dma,
-		                 buffer_info->length,
+		pci_unmap_single(pdev, buffer_info->dma, buffer_info->length,
 		                 PCI_DMA_FROMDEVICE);
 		buffer_info->dma = 0;
 
@@ -4052,7 +4303,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 		}
 
 		if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
-			last_byte = *(skb->data + length - 1);
+			u8 last_byte = *(skb->data + length - 1);
 			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
 				       last_byte)) {
 				spin_lock_irqsave(&adapter->stats_lock, flags);
@@ -4107,13 +4358,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 
 		skb->protocol = eth_type_trans(skb, netdev);
 
-		if (unlikely(adapter->vlgrp &&
-			    (status & E1000_RXD_STAT_VP))) {
-			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-						 le16_to_cpu(rx_desc->special));
-		} else {
-			netif_receive_skb(skb);
-		}
+		e1000_receive_skb(adapter, status, rx_desc->special, skb);
 
 next_desc:
 		rx_desc->status = 0;
@@ -4142,6 +4387,114 @@ next_desc:
 }
 
 /**
+ * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
+ * @adapter: address of board private structure
+ * @rx_ring: pointer to receive ring structure
+ * @cleaned_count: number of buffers to allocate this pass
+ **/
+
+static void
+e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
+                             struct e1000_rx_ring *rx_ring, int cleaned_count)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct e1000_rx_desc *rx_desc;
+	struct e1000_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	unsigned int bufsz = 256 -
+	                     16 /*for skb_reserve */ -
+	                     NET_IP_ALIGN;
+
+	i = rx_ring->next_to_use;
+	buffer_info = &rx_ring->buffer_info[i];
+
+	while (cleaned_count--) {
+		skb = buffer_info->skb;
+		if (skb) {
+			skb_trim(skb, 0);
+			goto check_page;
+		}
+
+		skb = netdev_alloc_skb(netdev, bufsz);
+		if (unlikely(!skb)) {
+			/* Better luck next round */
+			adapter->alloc_rx_buff_failed++;
+			break;
+		}
+
+		/* Fix for errata 23, can't cross 64kB boundary */
+		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
+			struct sk_buff *oldskb = skb;
+			DPRINTK(PROBE, ERR, "skb align check failed: %u bytes "
+					     "at %p\n", bufsz, skb->data);
+			/* Try again, without freeing the previous */
+			skb = netdev_alloc_skb(netdev, bufsz);
+			/* Failed allocation, critical failure */
+			if (!skb) {
+				dev_kfree_skb(oldskb);
+				adapter->alloc_rx_buff_failed++;
+				break;
+			}
+
+			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
+				/* give up */
+				dev_kfree_skb(skb);
+				dev_kfree_skb(oldskb);
+				break; /* while (cleaned_count--) */
+			}
+
+			/* Use new allocation */
+			dev_kfree_skb(oldskb);
+		}
+		/* Make buffer alignment 2 beyond a 16 byte boundary
+		 * this will result in a 16 byte aligned IP header after
+		 * the 14 byte MAC header is removed
+		 */
+		skb_reserve(skb, NET_IP_ALIGN);
+
+		buffer_info->skb = skb;
+		buffer_info->length = adapter->rx_buffer_len;
+check_page:
+		/* allocate a new page if necessary */
+		if (!buffer_info->page) {
+			buffer_info->page = alloc_page(GFP_ATOMIC);
+			if (unlikely(!buffer_info->page)) {
+				adapter->alloc_rx_buff_failed++;
+				break;
+			}
+		}
+
+		if (!buffer_info->dma)
+			buffer_info->dma = pci_map_page(pdev,
+			                                buffer_info->page, 0,
+			                                buffer_info->length,
+			                                PCI_DMA_FROMDEVICE);
+
+		rx_desc = E1000_RX_DESC(*rx_ring, i);
+		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+
+		if (unlikely(++i == rx_ring->count))
+			i = 0;
+		buffer_info = &rx_ring->buffer_info[i];
+	}
+
+	if (likely(rx_ring->next_to_use != i)) {
+		rx_ring->next_to_use = i;
+		if (unlikely(i-- == 0))
+			i = (rx_ring->count - 1);
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64). */
+		wmb();
+		writel(i, adapter->hw.hw_addr + rx_ring->rdt);
+	}
+}
+
+/**
  * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
  * @adapter: address of board private structure
  **/
@@ -4186,6 +4539,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
 			/* Failed allocation, critical failure */
 			if (!skb) {
 				dev_kfree_skb(oldskb);
+				adapter->alloc_rx_buff_failed++;
 				break;
 			}
 
@@ -4193,6 +4547,7 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
 				/* give up */
 				dev_kfree_skb(skb);
 				dev_kfree_skb(oldskb);
+				adapter->alloc_rx_buff_failed++;
 				break; /* while !buffer_info->skb */
 			}
 
@@ -4210,9 +4565,14 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
 map_skb:
 		buffer_info->dma = pci_map_single(pdev,
 						  skb->data,
-						  adapter->rx_buffer_len,
+						  buffer_info->length,
 						  PCI_DMA_FROMDEVICE);
 
+		/*
+		 * XXX if it was allocated cleanly it will never map to a
+		 * boundary crossing
+		 */
+
 		/* Fix for errata 23, can't cross 64kB boundary */
 		if (!e1000_check_64k_bound(adapter,
 					(void *)(unsigned long)buffer_info->dma,
@@ -4229,6 +4589,7 @@ map_skb:
 					 PCI_DMA_FROMDEVICE);
 			buffer_info->dma = 0;
 
+			adapter->alloc_rx_buff_failed++;
 			break; /* while !buffer_info->skb */
 		}
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
@@ -4353,8 +4714,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 		data->phy_id = hw->phy_addr;
 		break;
 	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		spin_lock_irqsave(&adapter->stats_lock, flags);
 		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
 				   &data->val_out)) {
@@ -4364,8 +4723,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 		spin_unlock_irqrestore(&adapter->stats_lock, flags);
 		break;
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if (data->reg_num & ~(0x1F))
 			return -EFAULT;
 		mii_reg = data->val_in;
@@ -4497,6 +4854,8 @@ static void e1000_vlan_rx_register(struct net_device *netdev,
 			/* enable VLAN receive filtering */
 			rctl = er32(RCTL);
 			rctl &= ~E1000_RCTL_CFIEN;
+	                if (!(netdev->flags & IFF_PROMISC))
+				rctl |= E1000_RCTL_VFE;
 			ew32(RCTL, rctl);
 			e1000_update_mng_vlan(adapter);
 		}
@@ -4507,6 +4866,11 @@ static void e1000_vlan_rx_register(struct net_device *netdev,
 		ew32(CTRL, ctrl);
 
 		if (adapter->hw.mac_type != e1000_ich8lan) {
+			/* disable VLAN receive filtering */
+			rctl = er32(RCTL);
+			rctl &= ~E1000_RCTL_VFE;
+			ew32(RCTL, rctl);
+
 			if (adapter->mng_vlan_id !=
 			    (u16)E1000_MNG_VLAN_NONE) {
 				e1000_vlan_rx_kill_vid(netdev,
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index fa92a68..16c193a 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4097,7 +4097,8 @@ static int e1000_maybe_stop_tx(struct net_device *netdev, int size)
 }
 
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
-static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
+				    struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_ring *tx_ring = adapter->tx_ring;
@@ -4345,8 +4346,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 		data->phy_id = adapter->hw.phy.addr;
 		break;
 	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		switch (data->reg_num & 0x1F) {
 		case MII_BMCR:
 			data->val_out = adapter->phy_regs.bmcr;
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 4f70034..1e93416 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -309,7 +309,8 @@ struct eepro_local {
 
 static int	eepro_probe1(struct net_device *dev, int autoprobe);
 static int	eepro_open(struct net_device *dev);
-static int	eepro_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t eepro_send_packet(struct sk_buff *skb,
+				     struct net_device *dev);
 static irqreturn_t eepro_interrupt(int irq, void *dev_id);
 static void 	eepro_rx(struct net_device *dev);
 static void 	eepro_transmit_interrupt(struct net_device *dev);
@@ -1133,7 +1134,8 @@ static void eepro_tx_timeout (struct net_device *dev)
 }
 
 
-static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t eepro_send_packet(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct eepro_local *lp = netdev_priv(dev);
 	unsigned long flags;
@@ -1145,7 +1147,7 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 	netif_stop_queue (dev);
@@ -1178,7 +1180,7 @@ static int eepro_send_packet(struct sk_buff *skb, struct net_device *dev)
 	eepro_en_int(ioaddr);
 	spin_unlock_irqrestore(&lp->lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 1f016d6..592de8f 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -246,7 +246,8 @@ static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 };
 static int eexp_open(struct net_device *dev);
 static int eexp_close(struct net_device *dev);
 static void eexp_timeout(struct net_device *dev);
-static int eexp_xmit(struct sk_buff *buf, struct net_device *dev);
+static netdev_tx_t eexp_xmit(struct sk_buff *buf,
+			     struct net_device *dev);
 
 static irqreturn_t eexp_irq(int irq, void *dev_addr);
 static void eexp_set_multicast(struct net_device *dev);
@@ -650,7 +651,7 @@ static void eexp_timeout(struct net_device *dev)
  * Called to transmit a packet, or to allow us to right ourselves
  * if the kernel thinks we've died.
  */
-static int eexp_xmit(struct sk_buff *buf, struct net_device *dev)
+static netdev_tx_t eexp_xmit(struct sk_buff *buf, struct net_device *dev)
 {
 	short length = buf->len;
 #ifdef CONFIG_SMP
@@ -664,7 +665,7 @@ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev)
 
 	if (buf->len < ETH_ZLEN) {
 		if (skb_padto(buf, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 
@@ -691,7 +692,7 @@ static int eexp_xmit(struct sk_buff *buf, struct net_device *dev)
 	spin_unlock_irqrestore(&lp->lock, flags);
 #endif
 	enable_irq(dev->irq);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index fc6cc03..117fc6c 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -1276,7 +1276,8 @@ static void enc28j60_hw_tx(struct enc28j60_net *priv)
 	locked_reg_bfset(priv, ECON1, ECON1_TXRTS);
 }
 
-static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t enc28j60_send_packet(struct sk_buff *skb,
+					struct net_device *dev)
 {
 	struct enc28j60_net *priv = netdev_priv(dev);
 
@@ -1299,7 +1300,7 @@ static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev)
 	priv->tx_skb = skb;
 	schedule_work(&priv->tx_work);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void enc28j60_tx_work_handler(struct work_struct *work)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index c26cea0..e1c2076 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -29,28 +29,34 @@
 #include "vnic_cq.h"
 #include "vnic_intr.h"
 #include "vnic_stats.h"
+#include "vnic_nic.h"
 #include "vnic_rss.h"
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco 10G Ethernet Driver"
-#define DRV_VERSION		"1.0.0.933"
-#define DRV_COPYRIGHT		"Copyright 2008 Cisco Systems, Inc"
+#define DRV_VERSION		"1.1.0.100"
+#define DRV_COPYRIGHT		"Copyright 2008-2009 Cisco Systems, Inc"
 #define PFX			DRV_NAME ": "
 
 #define ENIC_LRO_MAX_DESC	8
 #define ENIC_LRO_MAX_AGGR	64
 
+#define ENIC_BARS_MAX		6
+
+#define ENIC_WQ_MAX		8
+#define ENIC_RQ_MAX		8
+#define ENIC_CQ_MAX		(ENIC_WQ_MAX + ENIC_RQ_MAX)
+#define ENIC_INTR_MAX		(ENIC_CQ_MAX + 2)
+
 enum enic_cq_index {
 	ENIC_CQ_RQ,
 	ENIC_CQ_WQ,
-	ENIC_CQ_MAX,
 };
 
 enum enic_intx_intr_index {
 	ENIC_INTX_WQ_RQ,
 	ENIC_INTX_ERR,
 	ENIC_INTX_NOTIFY,
-	ENIC_INTX_MAX,
 };
 
 enum enic_msix_intr_index {
@@ -73,7 +79,7 @@ struct enic {
 	struct net_device *netdev;
 	struct pci_dev *pdev;
 	struct vnic_enet_config config;
-	struct vnic_dev_bar bar0;
+	struct vnic_dev_bar bar[ENIC_BARS_MAX];
 	struct vnic_dev *vdev;
 	struct timer_list notify_timer;
 	struct work_struct reset;
@@ -88,22 +94,23 @@ struct enic {
 	u32 port_mtu;
 
 	/* work queue cache line section */
-	____cacheline_aligned struct vnic_wq wq[1];
-	spinlock_t wq_lock[1];
+	____cacheline_aligned struct vnic_wq wq[ENIC_WQ_MAX];
+	spinlock_t wq_lock[ENIC_WQ_MAX];
 	unsigned int wq_count;
 	struct vlan_group *vlan_group;
 
 	/* receive queue cache line section */
-	____cacheline_aligned struct vnic_rq rq[1];
+	____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX];
 	unsigned int rq_count;
 	int (*rq_alloc_buf)(struct vnic_rq *rq);
+	u64 rq_truncated_pkts;
 	u64 rq_bad_fcs;
 	struct napi_struct napi;
 	struct net_lro_mgr lro_mgr;
 	struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC];
 
 	/* interrupt resource cache line section */
-	____cacheline_aligned struct vnic_intr intr[ENIC_MSIX_MAX];
+	____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
 	unsigned int intr_count;
 	u32 __iomem *legacy_pba;		/* memory-mapped */
 
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 8005b60..d69d52e 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -44,10 +44,15 @@
 #include "enic.h"
 
 #define ENIC_NOTIFY_TIMER_PERIOD	(2 * HZ)
+#define WQ_ENET_MAX_DESC_LEN		(1 << WQ_ENET_LEN_BITS)
+#define MAX_TSO				(1 << 16)
+#define ENIC_DESC_MAX_SPLITS		(MAX_TSO / WQ_ENET_MAX_DESC_LEN + 1)
+
+#define PCI_DEVICE_ID_CISCO_VIC_ENET         0x0043  /* ethernet vnic */
 
 /* Supported devices */
 static struct pci_device_id enic_id_table[] = {
-	{ PCI_VDEVICE(CISCO, 0x0043) },
+	{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET) },
 	{ 0, }	/* end of table */
 };
 
@@ -256,7 +261,7 @@ static void enic_set_msglevel(struct net_device *netdev, u32 value)
 	enic->msg_enable = value;
 }
 
-static struct ethtool_ops enic_ethtool_ops = {
+static const struct ethtool_ops enic_ethtool_ops = {
 	.get_settings = enic_get_settings,
 	.get_drvinfo = enic_get_drvinfo,
 	.get_msglevel = enic_get_msglevel,
@@ -310,7 +315,8 @@ static int enic_wq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
 		opaque);
 
 	if (netif_queue_stopped(enic->netdev) &&
-	    vnic_wq_desc_avail(&enic->wq[q_number]) >= MAX_SKB_FRAGS + 1)
+	    vnic_wq_desc_avail(&enic->wq[q_number]) >=
+	    (MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS))
 		netif_wake_queue(enic->netdev);
 
 	spin_unlock(&enic->wq_lock[q_number]);
@@ -356,7 +362,7 @@ static void enic_mtu_check(struct enic *enic)
 {
 	u32 mtu = vnic_dev_mtu(enic->vdev);
 
-	if (mtu != enic->port_mtu) {
+	if (mtu && mtu != enic->port_mtu) {
 		if (mtu < enic->netdev->mtu)
 			printk(KERN_WARNING PFX
 				"%s: interface MTU (%d) set higher "
@@ -525,7 +531,11 @@ static inline void enic_queue_wq_skb_vlan(struct enic *enic,
 	unsigned int len_left = skb->len - head_len;
 	int eop = (len_left == 0);
 
-	/* Queue the main skb fragment */
+	/* Queue the main skb fragment. The fragments are no larger
+	 * than max MTU(9000)+ETH_HDR_LEN(14) bytes, which is less
+	 * than WQ_ENET_MAX_DESC_LEN length. So only one descriptor
+	 * per fragment is queued.
+	 */
 	enic_queue_wq_desc(wq, skb,
 		pci_map_single(enic->pdev, skb->data,
 			head_len, PCI_DMA_TODEVICE),
@@ -547,7 +557,11 @@ static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
 	unsigned int csum_offset = hdr_len + skb->csum_offset;
 	int eop = (len_left == 0);
 
-	/* Queue the main skb fragment */
+	/* Queue the main skb fragment. The fragments are no larger
+	 * than max MTU(9000)+ETH_HDR_LEN(14) bytes, which is less
+	 * than WQ_ENET_MAX_DESC_LEN length. So only one descriptor
+	 * per fragment is queued.
+	 */
 	enic_queue_wq_desc_csum_l4(wq, skb,
 		pci_map_single(enic->pdev, skb->data,
 			head_len, PCI_DMA_TODEVICE),
@@ -565,10 +579,14 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
 	struct vnic_wq *wq, struct sk_buff *skb, unsigned int mss,
 	int vlan_tag_insert, unsigned int vlan_tag)
 {
-	unsigned int head_len = skb_headlen(skb);
-	unsigned int len_left = skb->len - head_len;
+	unsigned int frag_len_left = skb_headlen(skb);
+	unsigned int len_left = skb->len - frag_len_left;
 	unsigned int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 	int eop = (len_left == 0);
+	unsigned int len;
+	dma_addr_t dma_addr;
+	unsigned int offset = 0;
+	skb_frag_t *frag;
 
 	/* Preload TCP csum field with IP pseudo hdr calculated
 	 * with IP length set to zero.  HW will later add in length
@@ -584,17 +602,49 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
 			&ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0);
 	}
 
-	/* Queue the main skb fragment */
-	enic_queue_wq_desc_tso(wq, skb,
-		pci_map_single(enic->pdev, skb->data,
-			head_len, PCI_DMA_TODEVICE),
-		head_len,
-		mss, hdr_len,
-		vlan_tag_insert, vlan_tag,
-		eop);
+	/* Queue WQ_ENET_MAX_DESC_LEN length descriptors
+	 * for the main skb fragment
+	 */
+	while (frag_len_left) {
+		len = min(frag_len_left, (unsigned int)WQ_ENET_MAX_DESC_LEN);
+		dma_addr = pci_map_single(enic->pdev, skb->data + offset,
+				len, PCI_DMA_TODEVICE);
+		enic_queue_wq_desc_tso(wq, skb,
+			dma_addr,
+			len,
+			mss, hdr_len,
+			vlan_tag_insert, vlan_tag,
+			eop && (len == frag_len_left));
+		frag_len_left -= len;
+		offset += len;
+	}
 
-	if (!eop)
-		enic_queue_wq_skb_cont(enic, wq, skb, len_left);
+	if (eop)
+		return;
+
+	/* Queue WQ_ENET_MAX_DESC_LEN length descriptors
+	 * for additional data fragments
+	 */
+	for (frag = skb_shinfo(skb)->frags; len_left; frag++) {
+		len_left -= frag->size;
+		frag_len_left = frag->size;
+		offset = frag->page_offset;
+
+		while (frag_len_left) {
+			len = min(frag_len_left,
+				(unsigned int)WQ_ENET_MAX_DESC_LEN);
+			dma_addr = pci_map_page(enic->pdev, frag->page,
+				offset, len,
+				PCI_DMA_TODEVICE);
+			enic_queue_wq_desc_cont(wq, skb,
+				dma_addr,
+				len,
+				(len_left == 0) &&
+				(len == frag_len_left));	/* EOP? */
+			frag_len_left -= len;
+			offset += len;
+		}
+	}
 }
 
 static inline void enic_queue_wq_skb(struct enic *enic,
@@ -622,7 +672,8 @@ static inline void enic_queue_wq_skb(struct enic *enic,
 }
 
 /* netif_tx_lock held, process context with BHs disabled, or BH */
-static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
+					      struct net_device *netdev)
 {
 	struct enic *enic = netdev_priv(netdev);
 	struct vnic_wq *wq = &enic->wq[0];
@@ -647,7 +698,8 @@ static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	spin_lock_irqsave(&enic->wq_lock[0], flags);
 
-	if (vnic_wq_desc_avail(wq) < skb_shinfo(skb)->nr_frags + 1) {
+	if (vnic_wq_desc_avail(wq) <
+	    skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) {
 		netif_stop_queue(netdev);
 		/* This is a hard error, log it */
 		printk(KERN_ERR PFX "%s: BUG! Tx ring full when "
@@ -658,7 +710,7 @@ static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	enic_queue_wq_skb(enic, wq, skb);
 
-	if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + 1)
+	if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS)
 		netif_stop_queue(netdev);
 
 	spin_unlock_irqrestore(&enic->wq_lock[0], flags);
@@ -686,8 +738,9 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev)
 	net_stats->rx_bytes = stats->rx.rx_bytes_ok;
 	net_stats->rx_errors = stats->rx.rx_errors;
 	net_stats->multicast = stats->rx.rx_multicast_frames_ok;
+	net_stats->rx_over_errors = enic->rq_truncated_pkts;
 	net_stats->rx_crc_errors = enic->rq_bad_fcs;
-	net_stats->rx_dropped = stats->rx.rx_no_bufs;
+	net_stats->rx_dropped = stats->rx.rx_no_bufs + stats->rx.rx_drop;
 
 	return net_stats;
 }
@@ -817,11 +870,12 @@ static void enic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf)
 	dev_kfree_skb_any(buf->os_buf);
 }
 
-static inline struct sk_buff *enic_rq_alloc_skb(unsigned int size)
+static inline struct sk_buff *enic_rq_alloc_skb(struct net_device *netdev,
+	unsigned int size)
 {
 	struct sk_buff *skb;
 
-	skb = dev_alloc_skb(size + NET_IP_ALIGN);
+	skb = netdev_alloc_skb(netdev, size + NET_IP_ALIGN);
 
 	if (skb)
 		skb_reserve(skb, NET_IP_ALIGN);
@@ -832,12 +886,13 @@ static inline struct sk_buff *enic_rq_alloc_skb(unsigned int size)
 static int enic_rq_alloc_buf(struct vnic_rq *rq)
 {
 	struct enic *enic = vnic_dev_priv(rq->vdev);
+	struct net_device *netdev = enic->netdev;
 	struct sk_buff *skb;
-	unsigned int len = enic->netdev->mtu + ETH_HLEN;
+	unsigned int len = netdev->mtu + ETH_HLEN;
 	unsigned int os_buf_index = 0;
 	dma_addr_t dma_addr;
 
-	skb = enic_rq_alloc_skb(len);
+	skb = enic_rq_alloc_skb(netdev, len);
 	if (!skb)
 		return -ENOMEM;
 
@@ -850,6 +905,50 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
 	return 0;
 }
 
+static int enic_rq_alloc_buf_a1(struct vnic_rq *rq)
+{
+	struct rq_enet_desc *desc = vnic_rq_next_desc(rq);
+
+	if (vnic_rq_posting_soon(rq)) {
+
+		/* SW workaround for A0 HW erratum: if we're just about
+		 * to write posted_index, insert a dummy desc
+		 * of type resvd
+		 */
+
+		rq_enet_desc_enc(desc, 0, RQ_ENET_TYPE_RESV2, 0);
+		vnic_rq_post(rq, 0, 0, 0, 0);
+	} else {
+		return enic_rq_alloc_buf(rq);
+	}
+
+	return 0;
+}
+
+static int enic_set_rq_alloc_buf(struct enic *enic)
+{
+	enum vnic_dev_hw_version hw_ver;
+	int err;
+
+	err = vnic_dev_hw_version(enic->vdev, &hw_ver);
+	if (err)
+		return err;
+
+	switch (hw_ver) {
+	case VNIC_DEV_HW_VER_A1:
+		enic->rq_alloc_buf = enic_rq_alloc_buf_a1;
+		break;
+	case VNIC_DEV_HW_VER_A2:
+	case VNIC_DEV_HW_VER_UNKNOWN:
+		enic->rq_alloc_buf = enic_rq_alloc_buf;
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
 static int enic_get_skb_header(struct sk_buff *skb, void **iphdr,
 	void **tcph, u64 *hdr_flags, void *priv)
 {
@@ -931,8 +1030,12 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
 
 	if (packet_error) {
 
-		if (bytes_written > 0 && !fcs_ok)
-			enic->rq_bad_fcs++;
+		if (!fcs_ok) {
+			if (bytes_written > 0)
+				enic->rq_bad_fcs++;
+			else if (bytes_written == 0)
+				enic->rq_truncated_pkts++;
+		}
 
 		dev_kfree_skb_any(skb);
 
@@ -1057,7 +1160,7 @@ static int enic_poll(struct napi_struct *napi, int budget)
 		/* Replenish RQ
 		 */
 
-		vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
+		vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
 
 	} else {
 
@@ -1092,7 +1195,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
 		/* Replenish RQ
 		 */
 
-		vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
+		vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf);
 
 		/* Return intr event credits for this polling
 		 * cycle.  An intr event is the completion of a
@@ -1218,6 +1321,7 @@ static int enic_notify_set(struct enic *enic)
 {
 	int err;
 
+	spin_lock(&enic->devcmd_lock);
 	switch (vnic_dev_get_intr_mode(enic->vdev)) {
 	case VNIC_DEV_INTR_MODE_INTX:
 		err = vnic_dev_notify_set(enic->vdev, ENIC_INTX_NOTIFY);
@@ -1229,6 +1333,7 @@ static int enic_notify_set(struct enic *enic)
 		err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */);
 		break;
 	}
+	spin_unlock(&enic->devcmd_lock);
 
 	return err;
 }
@@ -1268,7 +1373,7 @@ static int enic_open(struct net_device *netdev)
 	}
 
 	for (i = 0; i < enic->rq_count; i++) {
-		err = vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf);
+		err = vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf);
 		if (err) {
 			printk(KERN_ERR PFX
 				"%s: Unable to alloc receive buffers.\n",
@@ -1282,12 +1387,16 @@ static int enic_open(struct net_device *netdev)
 	for (i = 0; i < enic->rq_count; i++)
 		vnic_rq_enable(&enic->rq[i]);
 
+	spin_lock(&enic->devcmd_lock);
 	enic_add_station_addr(enic);
+	spin_unlock(&enic->devcmd_lock);
 	enic_set_multicast_list(netdev);
 
 	netif_wake_queue(netdev);
 	napi_enable(&enic->napi);
+	spin_lock(&enic->devcmd_lock);
 	vnic_dev_enable(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
 
 	for (i = 0; i < enic->intr_count; i++)
 		vnic_intr_unmask(&enic->intr[i]);
@@ -1297,7 +1406,9 @@ static int enic_open(struct net_device *netdev)
 	return 0;
 
 err_out_notify_unset:
+	spin_lock(&enic->devcmd_lock);
 	vnic_dev_notify_unset(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
 err_out_free_intr:
 	enic_free_intr(enic);
 
@@ -1313,7 +1424,9 @@ static int enic_stop(struct net_device *netdev)
 
 	del_timer_sync(&enic->notify_timer);
 
+	spin_lock(&enic->devcmd_lock);
 	vnic_dev_disable(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
 	napi_disable(&enic->napi);
 	netif_stop_queue(netdev);
 
@@ -1331,7 +1444,9 @@ static int enic_stop(struct net_device *netdev)
 			return err;
 	}
 
+	spin_lock(&enic->devcmd_lock);
 	vnic_dev_notify_unset(enic->vdev);
+	spin_unlock(&enic->devcmd_lock);
 	enic_free_intr(enic);
 
 	(void)vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
@@ -1471,7 +1586,7 @@ static int enic_set_niccfg(struct enic *enic)
 	const u8 ig_vlan_strip_en = 1;
 
 	/* Enable VLAN tag stripping.  RSS not enabled (yet).
-	*/
+	 */
 
 	return enic_set_nic_cfg(enic,
 		rss_default_cpu, rss_hash_type,
@@ -1506,8 +1621,8 @@ static void enic_reset(struct work_struct *work)
 
 static int enic_set_intr_mode(struct enic *enic)
 {
-	unsigned int n = ARRAY_SIZE(enic->rq);
-	unsigned int m = ARRAY_SIZE(enic->wq);
+	unsigned int n = 1;
+	unsigned int m = 1;
 	unsigned int i;
 
 	/* Set interrupt mode (INTx, MSI, MSI-X) depending
@@ -1608,12 +1723,6 @@ static void enic_clear_intr_mode(struct enic *enic)
 	vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_UNKNOWN);
 }
 
-static void enic_iounmap(struct enic *enic)
-{
-	if (enic->bar0.vaddr)
-		iounmap(enic->bar0.vaddr);
-}
-
 static const struct net_device_ops enic_netdev_ops = {
 	.ndo_open		= enic_open,
 	.ndo_stop		= enic_stop,
@@ -1632,6 +1741,97 @@ static const struct net_device_ops enic_netdev_ops = {
 #endif
 };
 
+void enic_dev_deinit(struct enic *enic)
+{
+	netif_napi_del(&enic->napi);
+	enic_free_vnic_resources(enic);
+	enic_clear_intr_mode(enic);
+}
+
+int enic_dev_init(struct enic *enic)
+{
+	struct net_device *netdev = enic->netdev;
+	int err;
+
+	/* Get vNIC configuration
+	 */
+
+	err = enic_get_vnic_config(enic);
+	if (err) {
+		printk(KERN_ERR PFX
+			"Get vNIC configuration failed, aborting.\n");
+		return err;
+	}
+
+	/* Get available resource counts
+	 */
+
+	enic_get_res_counts(enic);
+
+	/* Set interrupt mode based on resource counts and system
+	 * capabilities
+	 */
+
+	err = enic_set_intr_mode(enic);
+	if (err) {
+		printk(KERN_ERR PFX
+			"Failed to set intr mode, aborting.\n");
+		return err;
+	}
+
+	/* Allocate and configure vNIC resources
+	 */
+
+	err = enic_alloc_vnic_resources(enic);
+	if (err) {
+		printk(KERN_ERR PFX
+			"Failed to alloc vNIC resources, aborting.\n");
+		goto err_out_free_vnic_resources;
+	}
+
+	enic_init_vnic_resources(enic);
+
+	err = enic_set_rq_alloc_buf(enic);
+	if (err) {
+		printk(KERN_ERR PFX
+			"Failed to set RQ buffer allocator, aborting.\n");
+		goto err_out_free_vnic_resources;
+	}
+
+	err = enic_set_niccfg(enic);
+	if (err) {
+		printk(KERN_ERR PFX
+			"Failed to config nic, aborting.\n");
+		goto err_out_free_vnic_resources;
+	}
+
+	switch (vnic_dev_get_intr_mode(enic->vdev)) {
+	default:
+		netif_napi_add(netdev, &enic->napi, enic_poll, 64);
+		break;
+	case VNIC_DEV_INTR_MODE_MSIX:
+		netif_napi_add(netdev, &enic->napi, enic_poll_msix, 64);
+		break;
+	}
+
+	return 0;
+
+err_out_free_vnic_resources:
+	enic_clear_intr_mode(enic);
+	enic_free_vnic_resources(enic);
+
+	return err;
+}
+
+static void enic_iounmap(struct enic *enic)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(enic->bar); i++)
+		if (enic->bar[i].vaddr)
+			iounmap(enic->bar[i].vaddr);
+}
+
 static int __devinit enic_probe(struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
@@ -1709,31 +1909,28 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 		using_dac = 1;
 	}
 
-	/* Map vNIC resources from BAR0
+	/* Map vNIC resources from BAR0-5
 	 */
 
-	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-		printk(KERN_ERR PFX
-			"BAR0 not memory-map'able, aborting.\n");
-		err = -ENODEV;
-		goto err_out_release_regions;
-	}
-
-	enic->bar0.vaddr = pci_iomap(pdev, 0, enic->bar0.len);
-	enic->bar0.bus_addr = pci_resource_start(pdev, 0);
-	enic->bar0.len = pci_resource_len(pdev, 0);
-
-	if (!enic->bar0.vaddr) {
-		printk(KERN_ERR PFX
-			"Cannot memory-map BAR0 res hdr, aborting.\n");
-		err = -ENODEV;
-		goto err_out_release_regions;
+	for (i = 0; i < ARRAY_SIZE(enic->bar); i++) {
+		if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM))
+			continue;
+		enic->bar[i].len = pci_resource_len(pdev, i);
+		enic->bar[i].vaddr = pci_iomap(pdev, i, enic->bar[i].len);
+		if (!enic->bar[i].vaddr) {
+			printk(KERN_ERR PFX
+				"Cannot memory-map BAR %d, aborting.\n", i);
+			err = -ENODEV;
+			goto err_out_iounmap;
+		}
+		enic->bar[i].bus_addr = pci_resource_start(pdev, i);
 	}
 
 	/* Register vNIC device
 	 */
 
-	enic->vdev = vnic_dev_register(NULL, enic, pdev, &enic->bar0);
+	enic->vdev = vnic_dev_register(NULL, enic, pdev, enic->bar,
+		ARRAY_SIZE(enic->bar));
 	if (!enic->vdev) {
 		printk(KERN_ERR PFX
 			"vNIC registration failed, aborting.\n");
@@ -1768,51 +1965,13 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 		goto err_out_dev_close;
 	}
 
-	/* Get vNIC configuration
-	 */
-
-	err = enic_get_vnic_config(enic);
-	if (err) {
-		printk(KERN_ERR PFX
-			"Get vNIC configuration failed, aborting.\n");
-		goto err_out_dev_close;
-	}
-
-	/* Get available resource counts
-	 */
-
-	enic_get_res_counts(enic);
-
-	/* Set interrupt mode based on resource counts and system
-	 * capabilities
-	 */
-
-	err = enic_set_intr_mode(enic);
+	err = enic_dev_init(enic);
 	if (err) {
 		printk(KERN_ERR PFX
-			"Failed to set intr mode, aborting.\n");
+			"Device initialization failed, aborting.\n");
 		goto err_out_dev_close;
 	}
 
-	/* Allocate and configure vNIC resources
-	 */
-
-	err = enic_alloc_vnic_resources(enic);
-	if (err) {
-		printk(KERN_ERR PFX
-			"Failed to alloc vNIC resources, aborting.\n");
-		goto err_out_free_vnic_resources;
-	}
-
-	enic_init_vnic_resources(enic);
-
-	err = enic_set_niccfg(enic);
-	if (err) {
-		printk(KERN_ERR PFX
-			"Failed to config nic, aborting.\n");
-		goto err_out_free_vnic_resources;
-	}
-
 	/* Setup notification timer, HW reset task, and locks
 	 */
 
@@ -1837,23 +1996,15 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	if (err) {
 		printk(KERN_ERR PFX
 			"Invalid MAC address, aborting.\n");
-		goto err_out_free_vnic_resources;
+		goto err_out_dev_deinit;
 	}
 
 	netdev->netdev_ops = &enic_netdev_ops;
 	netdev->watchdog_timeo = 2 * HZ;
 	netdev->ethtool_ops = &enic_ethtool_ops;
 
-	switch (vnic_dev_get_intr_mode(enic->vdev)) {
-	default:
-		netif_napi_add(netdev, &enic->napi, enic_poll, 64);
-		break;
-	case VNIC_DEV_INTR_MODE_MSIX:
-		netif_napi_add(netdev, &enic->napi, enic_poll_msix, 64);
-		break;
-	}
-
-	netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	netdev->features |= NETIF_F_HW_VLAN_TX |
+		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
 	if (ENIC_SETTING(enic, TXCSUM))
 		netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 	if (ENIC_SETTING(enic, TSO))
@@ -1879,17 +2030,16 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 	if (err) {
 		printk(KERN_ERR PFX
 			"Cannot register net device, aborting.\n");
-		goto err_out_free_vnic_resources;
+		goto err_out_dev_deinit;
 	}
 
 	return 0;
 
-err_out_free_vnic_resources:
-	enic_free_vnic_resources(enic);
+err_out_dev_deinit:
+	enic_dev_deinit(enic);
 err_out_dev_close:
 	vnic_dev_close(enic->vdev);
 err_out_vnic_unregister:
-	enic_clear_intr_mode(enic);
 	vnic_dev_unregister(enic->vdev);
 err_out_iounmap:
 	enic_iounmap(enic);
@@ -1913,9 +2063,8 @@ static void __devexit enic_remove(struct pci_dev *pdev)
 
 		flush_scheduled_work();
 		unregister_netdev(netdev);
-		enic_free_vnic_resources(enic);
+		enic_dev_deinit(enic);
 		vnic_dev_close(enic->vdev);
-		enic_clear_intr_mode(enic);
 		vnic_dev_unregister(enic->vdev);
 		enic_iounmap(enic);
 		pci_release_regions(pdev);
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index e5fc938..3211114 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -156,6 +156,22 @@ int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
 	return vnic_dev_cmd(enic->vdev, CMD_NIC_CFG, &a0, &a1, wait);
 }
 
+int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len)
+{
+	u64 a0 = (u64)key_pa, a1 = len;
+	int wait = 1000;
+
+	return vnic_dev_cmd(enic->vdev, CMD_RSS_KEY, &a0, &a1, wait);
+}
+
+int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len)
+{
+	u64 a0 = (u64)cpu_pa, a1 = len;
+	int wait = 1000;
+
+	return vnic_dev_cmd(enic->vdev, CMD_RSS_CPU, &a0, &a1, wait);
+}
+
 void enic_free_vnic_resources(struct enic *enic)
 {
 	unsigned int i;
@@ -172,11 +188,18 @@ void enic_free_vnic_resources(struct enic *enic)
 
 void enic_get_res_counts(struct enic *enic)
 {
-	enic->wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ);
-	enic->rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ);
-	enic->cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ);
-	enic->intr_count = vnic_dev_get_res_count(enic->vdev,
-		RES_TYPE_INTR_CTRL);
+	enic->wq_count = min_t(int,
+		vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ),
+		ENIC_WQ_MAX);
+	enic->rq_count = min_t(int,
+		vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ),
+		ENIC_RQ_MAX);
+	enic->cq_count = min_t(int,
+		vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ),
+		ENIC_CQ_MAX);
+	enic->intr_count = min_t(int,
+		vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL),
+		ENIC_INTR_MAX);
 
 	printk(KERN_INFO PFX "vNIC resources avail: "
 		"wq %d rq %d cq %d intr %d\n",
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 7bf272f..abc1974 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -139,6 +139,8 @@ void enic_del_vlan(struct enic *enic, u16 vlanid);
 int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
 	u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en,
 	u8 ig_vlan_strip_en);
+int enic_set_rss_key(struct enic *enic, dma_addr_t key_pa, u64 len);
+int enic_set_rss_cpu(struct enic *enic, dma_addr_t cpu_pa, u64 len);
 void enic_get_res_counts(struct enic *enic);
 void enic_init_vnic_resources(struct enic *enic);
 int enic_alloc_vnic_resources(struct enic *);
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index e21b9d6..29a48e8 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -31,6 +31,7 @@
 
 struct vnic_res {
 	void __iomem *vaddr;
+	dma_addr_t bus_addr;
 	unsigned int count;
 };
 
@@ -67,12 +68,15 @@ void *vnic_dev_priv(struct vnic_dev *vdev)
 }
 
 static int vnic_dev_discover_res(struct vnic_dev *vdev,
-	struct vnic_dev_bar *bar)
+	struct vnic_dev_bar *bar, unsigned int num_bars)
 {
 	struct vnic_resource_header __iomem *rh;
 	struct vnic_resource __iomem *r;
 	u8 type;
 
+	if (num_bars == 0)
+		return -EINVAL;
+
 	if (bar->len < VNIC_MAX_RES_HDR_SIZE) {
 		printk(KERN_ERR "vNIC BAR0 res hdr length error\n");
 		return -EINVAL;
@@ -104,7 +108,10 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
 
 		r++;
 
-		if (bar_num != 0)  /* only mapping in BAR0 resources */
+		if (bar_num >= num_bars)
+			continue;
+
+		if (!bar[bar_num].len || !bar[bar_num].vaddr)
 			continue;
 
 		switch (type) {
@@ -114,13 +121,13 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
 		case RES_TYPE_INTR_CTRL:
 			/* each count is stride bytes long */
 			len = count * VNIC_RES_STRIDE;
-			if (len + bar_offset > bar->len) {
+			if (len + bar_offset > bar[bar_num].len) {
 				printk(KERN_ERR "vNIC BAR0 resource %d "
 					"out-of-bounds, offset 0x%x + "
 					"size 0x%x > bar len 0x%lx\n",
 					type, bar_offset,
 					len,
-					bar->len);
+					bar[bar_num].len);
 				return -EINVAL;
 			}
 			break;
@@ -133,7 +140,9 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
 		}
 
 		vdev->res[type].count = count;
-		vdev->res[type].vaddr = (char __iomem *)bar->vaddr + bar_offset;
+		vdev->res[type].vaddr = (char __iomem *)bar[bar_num].vaddr +
+			bar_offset;
+		vdev->res[type].bus_addr = bar[bar_num].bus_addr + bar_offset;
 	}
 
 	return 0;
@@ -163,6 +172,21 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
 	}
 }
 
+dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev,
+	enum vnic_res_type type, unsigned int index)
+{
+	switch (type) {
+	case RES_TYPE_WQ:
+	case RES_TYPE_RQ:
+	case RES_TYPE_CQ:
+	case RES_TYPE_INTR_CTRL:
+		return vdev->res[type].bus_addr +
+			index * VNIC_RES_STRIDE;
+	default:
+		return vdev->res[type].bus_addr;
+	}
+}
+
 unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
 	unsigned int desc_count, unsigned int desc_size)
 {
@@ -257,7 +281,7 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	iowrite32(cmd, &devcmd->cmd);
 
 	if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT))
-			return 0;
+		return 0;
 
 	for (delay = 0; delay < wait; delay++) {
 
@@ -325,6 +349,25 @@ int vnic_dev_fw_info(struct vnic_dev *vdev,
 	return err;
 }
 
+int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver)
+{
+	struct vnic_devcmd_fw_info *fw_info;
+	int err;
+
+	err = vnic_dev_fw_info(vdev, &fw_info);
+	if (err)
+		return err;
+
+	if (strncmp(fw_info->hw_version, "A1", sizeof("A1")) == 0)
+		*hw_ver = VNIC_DEV_HW_VER_A1;
+	else if (strncmp(fw_info->hw_version, "A2", sizeof("A2")) == 0)
+		*hw_ver = VNIC_DEV_HW_VER_A2;
+	else
+		*hw_ver = VNIC_DEV_HW_VER_UNKNOWN;
+
+	return 0;
+}
+
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
 	void *value)
 {
@@ -517,6 +560,20 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
 		printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
 }
 
+int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
+{
+	u64 a0 = intr, a1 = 0;
+	int wait = 1000;
+	int err;
+
+	err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait);
+	if (err)
+		printk(KERN_ERR "Failed to raise INTR[%d], err %d\n",
+			intr, err);
+
+	return err;
+}
+
 int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
 {
 	u64 a0, a1;
@@ -684,7 +741,8 @@ void vnic_dev_unregister(struct vnic_dev *vdev)
 }
 
 struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
-	void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar)
+	void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
+	unsigned int num_bars)
 {
 	if (!vdev) {
 		vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC);
@@ -695,7 +753,7 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
 	vdev->priv = priv;
 	vdev->pdev = pdev;
 
-	if (vnic_dev_discover_res(vdev, bar))
+	if (vnic_dev_discover_res(vdev, bar, num_bars))
 		goto err_out;
 
 	vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0);
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 8aa8db2..fc5e3eb 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -41,6 +41,12 @@ static inline void writeq(u64 val, void __iomem *reg)
 }
 #endif
 
+enum vnic_dev_hw_version {
+	VNIC_DEV_HW_VER_UNKNOWN,
+	VNIC_DEV_HW_VER_A1,
+	VNIC_DEV_HW_VER_A2,
+};
+
 enum vnic_dev_intr_mode {
 	VNIC_DEV_INTR_MODE_UNKNOWN,
 	VNIC_DEV_INTR_MODE_INTX,
@@ -75,6 +81,8 @@ unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,
 	enum vnic_res_type type);
 void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
 	unsigned int index);
+dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev,
+	enum vnic_res_type type, unsigned int index);
 unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
 	unsigned int desc_count, unsigned int desc_size);
 void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring);
@@ -86,6 +94,8 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
 	u64 *a0, u64 *a1, int wait);
 int vnic_dev_fw_info(struct vnic_dev *vdev,
 	struct vnic_devcmd_fw_info **fw_info);
+int vnic_dev_hw_version(struct vnic_dev *vdev,
+	enum vnic_dev_hw_version *hw_ver);
 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
 	void *value);
 int vnic_dev_stats_clear(struct vnic_dev *vdev);
@@ -96,6 +106,7 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
 void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr);
 void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr);
 int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
+int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr);
 int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr);
 void vnic_dev_notify_unset(struct vnic_dev *vdev);
 int vnic_dev_link_status(struct vnic_dev *vdev);
@@ -117,6 +128,7 @@ void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
 enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
 void vnic_dev_unregister(struct vnic_dev *vdev);
 struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
-	void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar);
+	void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
+	unsigned int num_bars);
 
 #endif /* _VNIC_DEV_H_ */
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index 2587f34..d78bbcc 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -105,14 +105,6 @@ enum vnic_devcmd_cmd {
 	CMD_MAC_ADDR            = _CMDC(_CMD_DIR_READ,
 					_CMD_VTYPE_ENET | _CMD_VTYPE_FC, 9),
 
-	/* disable/enable promisc mode: (u8)a0=0/1 */
-/***** XXX DEPRECATED *****/
-	CMD_PROMISC_MODE        = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 10),
-
-	/* disable/enable all-multi mode: (u8)a0=0/1 */
-/***** XXX DEPRECATED *****/
-	CMD_ALLMULTI_MODE       = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 11),
-
 	/* add addr from (u48)a0 */
 	CMD_ADDR_ADD            = _CMDCNW(_CMD_DIR_WRITE,
 					_CMD_VTYPE_ENET | _CMD_VTYPE_FC, 12),
@@ -182,7 +174,9 @@ enum vnic_devcmd_cmd {
 	/* disable virtual link */
 	CMD_DISABLE		= _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 29),
 
-	/* stats dump all vnics on uplink in mem: (u64)a0=paddr (u32)a1=uif */
+	/* stats dump sum of all vnic stats on same uplink in mem:
+	 *     (u64)a0=paddr
+	 *     (u16)a1=sizeof stats area */
 	CMD_STATS_DUMP_ALL	= _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 30),
 
 	/* init status:
@@ -211,7 +205,12 @@ enum vnic_devcmd_cmd {
 	/* persistent binding info
 	 * in:  (u64)a0=paddr of arg
 	 *      (u32)a1=CMD_PERBI_XXX */
-	CMD_PERBI               = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 37),
+	CMD_PERBI		= _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 37),
+
+	/* Interrupt Assert Register functionality
+	 * in: (u16)a0=interrupt number to assert
+	 */
+	CMD_IAR			= _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38),
 };
 
 /* flags for CMD_OPEN */
@@ -244,6 +243,7 @@ enum vnic_devcmd_error {
 	ERR_ENOMEM = 7,
 	ERR_ETIMEDOUT = 8,
 	ERR_ELINKDOWN = 9,
+	ERR_EMAXRES = 10,
 };
 
 struct vnic_devcmd_fw_info {
diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c
index ddc38f8..1f8786d 100644
--- a/drivers/net/enic/vnic_intr.c
+++ b/drivers/net/enic/vnic_intr.c
@@ -60,3 +60,8 @@ void vnic_intr_clean(struct vnic_intr *intr)
 {
 	iowrite32(0, &intr->ctrl->int_credits);
 }
+
+void vnic_intr_raise(struct vnic_intr *intr)
+{
+	vnic_dev_raise_intr(intr->vdev, (u16)intr->index);
+}
diff --git a/drivers/net/enic/vnic_nic.h b/drivers/net/enic/vnic_nic.h
index dadf26f..eeaf329 100644
--- a/drivers/net/enic/vnic_nic.h
+++ b/drivers/net/enic/vnic_nic.h
@@ -41,6 +41,13 @@
 #define NIC_CFG_IG_VLAN_STRIP_EN_MASK_FIELD	1UL
 #define NIC_CFG_IG_VLAN_STRIP_EN_SHIFT		24
 
+#define NIC_CFG_RSS_HASH_TYPE_IPV4		(1 << 0)
+#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV4		(1 << 1)
+#define NIC_CFG_RSS_HASH_TYPE_IPV6		(1 << 2)
+#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6		(1 << 3)
+#define NIC_CFG_RSS_HASH_TYPE_IPV6_EX		(1 << 4)
+#define NIC_CFG_RSS_HASH_TYPE_TCP_IPV6_EX	(1 << 5)
+
 static inline void vnic_set_nic_cfg(u32 *nic_cfg,
 	u8 rss_default_cpu, u8 rss_hash_type,
 	u8 rss_hash_bits, u8 rss_base_cpu,
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index 9365e63..7558397 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -62,7 +62,6 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
 	}
 
 	rq->to_use = rq->to_clean = rq->bufs[0];
-	rq->buf_index = 0;
 
 	return 0;
 }
@@ -113,12 +112,12 @@ int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
 	return 0;
 }
 
-void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
+void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
+	unsigned int fetch_index, unsigned int posted_index,
 	unsigned int error_interrupt_enable,
 	unsigned int error_interrupt_offset)
 {
 	u64 paddr;
-	u32 fetch_index;
 
 	paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET;
 	writeq(paddr, &rq->ctrl->ring_base);
@@ -128,15 +127,27 @@ void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
 	iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset);
 	iowrite32(0, &rq->ctrl->dropped_packet_count);
 	iowrite32(0, &rq->ctrl->error_status);
+	iowrite32(fetch_index, &rq->ctrl->fetch_index);
+	iowrite32(posted_index, &rq->ctrl->posted_index);
 
-	/* Use current fetch_index as the ring starting point */
-	fetch_index = ioread32(&rq->ctrl->fetch_index);
 	rq->to_use = rq->to_clean =
 		&rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES]
 			[fetch_index % VNIC_RQ_BUF_BLK_ENTRIES];
-	iowrite32(fetch_index, &rq->ctrl->posted_index);
+}
+
+void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
+	unsigned int error_interrupt_enable,
+	unsigned int error_interrupt_offset)
+{
+	u32 fetch_index;
 
-	rq->buf_index = 0;
+	/* Use current fetch_index as the ring starting point */
+	fetch_index = ioread32(&rq->ctrl->fetch_index);
+
+	vnic_rq_init_start(rq, cq_index,
+		fetch_index, fetch_index,
+		error_interrupt_enable,
+		error_interrupt_offset);
 }
 
 unsigned int vnic_rq_error_status(struct vnic_rq *rq)
@@ -192,8 +203,6 @@ void vnic_rq_clean(struct vnic_rq *rq,
 			[fetch_index % VNIC_RQ_BUF_BLK_ENTRIES];
 	iowrite32(fetch_index, &rq->ctrl->posted_index);
 
-	rq->buf_index = 0;
-
 	vnic_dev_clear_desc_ring(&rq->ring);
 }
 
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h
index fd0ef66..35e736c 100644
--- a/drivers/net/enic/vnic_rq.h
+++ b/drivers/net/enic/vnic_rq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
+ * Copyright 2008, 2009 Cisco Systems, Inc.  All rights reserved.
  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
  *
  * This program is free software; you may redistribute it and/or modify
@@ -79,7 +79,6 @@ struct vnic_rq {
 	struct vnic_rq_buf *to_use;
 	struct vnic_rq_buf *to_clean;
 	void *os_buf_head;
-	unsigned int buf_index;
 	unsigned int pkts_outstanding;
 };
 
@@ -105,11 +104,6 @@ static inline unsigned int vnic_rq_next_index(struct vnic_rq *rq)
 	return rq->to_use->index;
 }
 
-static inline unsigned int vnic_rq_next_buf_index(struct vnic_rq *rq)
-{
-	return rq->buf_index++;
-}
-
 static inline void vnic_rq_post(struct vnic_rq *rq,
 	void *os_buf, unsigned int os_buf_index,
 	dma_addr_t dma_addr, unsigned int len)
@@ -143,6 +137,11 @@ static inline void vnic_rq_post(struct vnic_rq *rq,
 	}
 }
 
+static inline int vnic_rq_posting_soon(struct vnic_rq *rq)
+{
+	return ((rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0);
+}
+
 static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count)
 {
 	rq->ring.desc_avail += count;
@@ -186,7 +185,7 @@ static inline int vnic_rq_fill(struct vnic_rq *rq,
 {
 	int err;
 
-	while (vnic_rq_desc_avail(rq) > 1) {
+	while (vnic_rq_desc_avail(rq) > 0) {
 
 		err = (*buf_fill)(rq);
 		if (err)
@@ -199,6 +198,10 @@ static inline int vnic_rq_fill(struct vnic_rq *rq,
 void vnic_rq_free(struct vnic_rq *rq);
 int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
 	unsigned int desc_count, unsigned int desc_size);
+void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
+	unsigned int fetch_index, unsigned int posted_index,
+	unsigned int error_interrupt_enable,
+	unsigned int error_interrupt_offset);
 void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
 	unsigned int error_interrupt_enable,
 	unsigned int error_interrupt_offset);
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index a576d04..d2e00e5 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -112,7 +112,8 @@ int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
 	return 0;
 }
 
-void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
+void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
+	unsigned int fetch_index, unsigned int posted_index,
 	unsigned int error_interrupt_enable,
 	unsigned int error_interrupt_offset)
 {
@@ -121,12 +122,25 @@ void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
 	paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET;
 	writeq(paddr, &wq->ctrl->ring_base);
 	iowrite32(wq->ring.desc_count, &wq->ctrl->ring_size);
-	iowrite32(0, &wq->ctrl->fetch_index);
-	iowrite32(0, &wq->ctrl->posted_index);
+	iowrite32(fetch_index, &wq->ctrl->fetch_index);
+	iowrite32(posted_index, &wq->ctrl->posted_index);
 	iowrite32(cq_index, &wq->ctrl->cq_index);
 	iowrite32(error_interrupt_enable, &wq->ctrl->error_interrupt_enable);
 	iowrite32(error_interrupt_offset, &wq->ctrl->error_interrupt_offset);
 	iowrite32(0, &wq->ctrl->error_status);
+
+	wq->to_use = wq->to_clean =
+		&wq->bufs[fetch_index / VNIC_WQ_BUF_BLK_ENTRIES]
+			[fetch_index % VNIC_WQ_BUF_BLK_ENTRIES];
+}
+
+void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
+	unsigned int error_interrupt_enable,
+	unsigned int error_interrupt_offset)
+{
+	vnic_wq_init_start(wq, cq_index, 0, 0,
+		error_interrupt_enable,
+		error_interrupt_offset);
 }
 
 unsigned int vnic_wq_error_status(struct vnic_wq *wq)
diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h
index c826137..9c34d41 100644
--- a/drivers/net/enic/vnic_wq.h
+++ b/drivers/net/enic/vnic_wq.h
@@ -149,6 +149,10 @@ static inline void vnic_wq_service(struct vnic_wq *wq,
 void vnic_wq_free(struct vnic_wq *wq);
 int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
 	unsigned int desc_count, unsigned int desc_size);
+void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
+	unsigned int fetch_index, unsigned int posted_index,
+	unsigned int error_interrupt_enable,
+	unsigned int error_interrupt_offset);
 void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
 	unsigned int error_interrupt_enable,
 	unsigned int error_interrupt_offset);
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 88d7ebf..641a10d 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -298,7 +298,8 @@ static void epic_restart(struct net_device *dev);
 static void epic_timer(unsigned long data);
 static void epic_tx_timeout(struct net_device *dev);
 static void epic_init_ring(struct net_device *dev);
-static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t epic_start_xmit(struct sk_buff *skb,
+				   struct net_device *dev);
 static int epic_rx(struct net_device *dev, int budget);
 static int epic_poll(struct napi_struct *napi, int budget);
 static irqreturn_t epic_interrupt(int irq, void *dev_instance);
@@ -961,7 +962,7 @@ static void epic_init_ring(struct net_device *dev)
 	return;
 }
 
-static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct epic_private *ep = netdev_priv(dev);
 	int entry, free_count;
@@ -969,7 +970,7 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	unsigned long flags;
 
 	if (skb_padto(skb, ETH_ZLEN))
-		return 0;
+		return NETDEV_TX_OK;
 
 	/* Caution: the write order is important here, set the field with the
 	   "ownership" bit last. */
@@ -1013,7 +1014,7 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			   dev->name, (int)skb->len, entry, ctrl_word,
 			   (int)inl(dev->base_addr + TxSTAT));
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void epic_tx_error(struct net_device *dev, struct epic_private *ep,
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index 19b7dd9..d4d9a3e 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -127,7 +127,7 @@
 static int eql_open(struct net_device *dev);
 static int eql_close(struct net_device *dev);
 static int eql_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t eql_slave_xmit(struct sk_buff *skb, struct net_device *dev);
 
 #define eql_is_slave(dev)	((dev->flags & IFF_SLAVE) == IFF_SLAVE)
 #define eql_is_master(dev)	((dev->flags & IFF_MASTER) == IFF_MASTER)
@@ -325,7 +325,7 @@ static slave_t *__eql_schedule_slaves(slave_queue_t *queue)
 	return best_slave;
 }
 
-static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	equalizer_t *eql = netdev_priv(dev);
 	slave_t *slave;
@@ -348,7 +348,7 @@ static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock(&eql->queue.lock);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index 0d8b6da..71bfeec 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -405,7 +405,7 @@ static int     eth16i_read_eeprom_word(int ioaddr);
 static void    eth16i_eeprom_cmd(int ioaddr, unsigned char command);
 static int     eth16i_open(struct net_device *dev);
 static int     eth16i_close(struct net_device *dev);
-static int     eth16i_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t eth16i_tx(struct sk_buff *skb, struct net_device *dev);
 static void    eth16i_rx(struct net_device *dev);
 static void    eth16i_timeout(struct net_device *dev);
 static irqreturn_t eth16i_interrupt(int irq, void *dev_id);
@@ -1053,7 +1053,7 @@ static void eth16i_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int eth16i_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t eth16i_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct eth16i_local *lp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
@@ -1064,7 +1064,7 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev)
 
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 	buf = skb->data;
@@ -1126,7 +1126,7 @@ static int eth16i_tx(struct sk_buff *skb, struct net_device *dev)
 	/* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
 	status = 0;
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void eth16i_rx(struct net_device *dev)
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index ceb6a9c..b7311bc 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -404,7 +404,6 @@ static int ethoc_rx(struct net_device *dev, int limit)
 				void *src = priv->membase + bd.addr;
 				memcpy_fromio(skb_put(skb, size), src, size);
 				skb->protocol = eth_type_trans(skb, dev);
-				dev->last_rx = jiffies;
 				priv->stats.rx_packets++;
 				priv->stats.rx_bytes += size;
 				netif_receive_skb(skb);
@@ -802,7 +801,7 @@ static struct net_device_stats *ethoc_stats(struct net_device *dev)
 	return &priv->stats;
 }
 
-static int ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ethoc *priv = netdev_priv(dev);
 	struct ethoc_bd bd;
@@ -894,7 +893,7 @@ static int ethoc_probe(struct platform_device *pdev)
 
 	mmio = devm_request_mem_region(&pdev->dev, res->start,
 			res->end - res->start + 1, res->name);
-	if (!res) {
+	if (!mmio) {
 		dev_err(&pdev->dev, "cannot request I/O memory space\n");
 		ret = -ENXIO;
 		goto free;
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index 1e97232..b2a5ec8 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -298,7 +298,7 @@ struct ewrk3_private {
    ** Public Functions
  */
 static int ewrk3_open(struct net_device *dev);
-static int ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t ewrk3_interrupt(int irq, void *dev_id);
 static int ewrk3_close(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
@@ -764,7 +764,7 @@ static void ewrk3_timeout(struct net_device *dev)
 /*
    ** Writes a socket buffer to the free page queue
  */
-static int ewrk3_queue_pkt (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ewrk3_queue_pkt(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ewrk3_private *lp = netdev_priv(dev);
 	u_long iobase = dev->base_addr;
@@ -868,7 +868,7 @@ static int ewrk3_queue_pkt (struct sk_buff *skb, struct net_device *dev)
 	if (inb (EWRK3_FMQC) == 0)
 		netif_stop_queue (dev);
 
-	return 0;
+	return NETDEV_TX_OK;
 
 err_out:
 	ENABLE_IRQs;
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 160655d..18d5fbb 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -433,7 +433,7 @@ static void netdev_timer(unsigned long data);
 static void reset_timer(unsigned long data);
 static void fealnx_tx_timeout(struct net_device *dev);
 static void init_ring(struct net_device *dev);
-static int start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t intr_handler(int irq, void *dev_instance);
 static int netdev_rx(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
@@ -1305,7 +1305,7 @@ static void init_ring(struct net_device *dev)
 }
 
 
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
 	unsigned long flags;
@@ -1378,7 +1378,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 
 	spin_unlock_irqrestore(&np->lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index c9fd82d..2923438 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -367,7 +367,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irqrestore(&fep->hw_lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void
@@ -427,7 +427,7 @@ fec_enet_tx(struct net_device *dev)
 	struct	sk_buff	*skb;
 
 	fep = netdev_priv(dev);
-	spin_lock_irq(&fep->hw_lock);
+	spin_lock(&fep->hw_lock);
 	bdp = fep->dirty_tx;
 
 	while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
@@ -486,7 +486,7 @@ fec_enet_tx(struct net_device *dev)
 		}
 	}
 	fep->dirty_tx = bdp;
-	spin_unlock_irq(&fep->hw_lock);
+	spin_unlock(&fep->hw_lock);
 }
 
 
@@ -509,7 +509,7 @@ fec_enet_rx(struct net_device *dev)
 	flush_cache_all();
 #endif
 
-	spin_lock_irq(&fep->hw_lock);
+	spin_lock(&fep->hw_lock);
 
 	/* First, grab all of the stats for the incoming packet.
 	 * These get messed up if we get called due to a busy condition.
@@ -604,7 +604,7 @@ rx_processing_done:
 	}
 	fep->cur_rx = bdp;
 
-	spin_unlock_irq(&fep->hw_lock);
+	spin_unlock(&fep->hw_lock);
 }
 
 /* called from interrupt context */
@@ -615,7 +615,7 @@ fec_enet_mii(struct net_device *dev)
 	mii_list_t	*mip;
 
 	fep = netdev_priv(dev);
-	spin_lock_irq(&fep->mii_lock);
+	spin_lock(&fep->mii_lock);
 
 	if ((mip = mii_head) == NULL) {
 		printk("MII and no head!\n");
@@ -633,20 +633,19 @@ fec_enet_mii(struct net_device *dev)
 		writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
 
 unlock:
-	spin_unlock_irq(&fep->mii_lock);
+	spin_unlock(&fep->mii_lock);
 }
 
 static int
-mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_device *))
+mii_queue_unlocked(struct net_device *dev, int regval,
+		void (*func)(uint, struct net_device *))
 {
 	struct fec_enet_private *fep;
-	unsigned long	flags;
 	mii_list_t	*mip;
 	int		retval;
 
 	/* Add PHY address to register command */
 	fep = netdev_priv(dev);
-	spin_lock_irqsave(&fep->mii_lock, flags);
 
 	regval |= fep->phy_addr << 23;
 	retval = 0;
@@ -667,6 +666,19 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
 		retval = 1;
 	}
 
+	return retval;
+}
+
+static int
+mii_queue(struct net_device *dev, int regval,
+		void (*func)(uint, struct net_device *))
+{
+	struct fec_enet_private *fep;
+	unsigned long   flags;
+	int             retval;
+	fep = netdev_priv(dev);
+	spin_lock_irqsave(&fep->mii_lock, flags);
+	retval = mii_queue_unlocked(dev, regval, func);
 	spin_unlock_irqrestore(&fep->mii_lock, flags);
 	return retval;
 }
@@ -1142,19 +1154,9 @@ static void __inline__ fec_request_mii_intr(struct net_device *dev)
 		printk("FEC: Could not allocate fec(MII) IRQ(66)!\n");
 }
 
-static void __inline__ fec_disable_phy_intr(void)
+static void __inline__ fec_disable_phy_intr(struct net_device *dev)
 {
-	volatile unsigned long *icrp;
-	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-	*icrp = 0x08000000;
-}
-
-static void __inline__ fec_phy_ack_intr(void)
-{
-	volatile unsigned long *icrp;
-	/* Acknowledge the interrupt */
-	icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR1);
-	*icrp = 0x0d000000;
+	free_irq(66, dev);
 }
 #endif
 
@@ -1373,11 +1375,11 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
 
 			/* Got first part of ID, now get remainder */
 			fep->phy_id = phytype << 16;
-			mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
+			mii_queue_unlocked(dev, mk_mii_read(MII_REG_PHYIR2),
 							mii_discover_phy3);
 		} else {
 			fep->phy_addr++;
-			mii_queue(dev, mk_mii_read(MII_REG_PHYIR1),
+			mii_queue_unlocked(dev, mk_mii_read(MII_REG_PHYIR1),
 							mii_discover_phy);
 		}
 	} else {
@@ -1386,7 +1388,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
 		writel(0, fep->hwp + FEC_MII_SPEED);
 		fep->phy_speed = 0;
 #ifdef HAVE_mii_link_interrupt
-		fec_disable_phy_intr();
+		fec_disable_phy_intr(dev);
 #endif
 	}
 }
@@ -1399,8 +1401,6 @@ mii_link_interrupt(int irq, void * dev_id)
 	struct	net_device *dev = dev_id;
 	struct fec_enet_private *fep = netdev_priv(dev);
 
-	fec_phy_ack_intr();
-
 	mii_do_cmd(dev, fep->phy->ack_int);
 	mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
 
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 3b4e076..0a1c2bb 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2137,7 +2137,7 @@ static void nv_gear_backoff_reseed(struct net_device *dev)
  * nv_start_xmit: dev->hard_start_xmit function
  * Called with netif_tx_lock held.
  */
-static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u32 tx_flags = 0;
@@ -2257,7 +2257,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	return NETDEV_TX_OK;
 }
 
-static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
+					   struct net_device *dev)
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u32 tx_flags = 0;
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 75a0999..a2d69c1 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -36,6 +36,7 @@
 #include <asm/pgtable.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
+#include <asm/mpc5xxx.h>
 
 #include "fs_enet.h"
 #include "fec.h"
@@ -103,11 +104,11 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
 static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
                                         const struct of_device_id *match)
 {
-	struct device_node *np = NULL;
 	struct resource res;
 	struct mii_bus *new_bus;
 	struct fec_info *fec;
-	int ret = -ENOMEM, i;
+	int (*get_bus_freq)(struct device_node *) = match->data;
+	int ret = -ENOMEM, clock, speed;
 
 	new_bus = mdiobus_alloc();
 	if (!new_bus)
@@ -133,13 +134,35 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 	if (!fec->fecp)
 		goto out_fec;
 
-	fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1;
+	if (get_bus_freq) {
+		clock = get_bus_freq(ofdev->node);
+		if (!clock) {
+			/* Use maximum divider if clock is unknown */
+			dev_warn(&ofdev->dev, "could not determine IPS clock\n");
+			clock = 0x3F * 5000000;
+		}
+	} else
+		clock = ppc_proc_freq;
+
+	/*
+	 * Scale for a MII clock <= 2.5 MHz
+	 * Note that only 6 bits (25:30) are available for MII speed.
+	 */
+	speed = (clock + 4999999) / 5000000;
+	if (speed > 0x3F) {
+		speed = 0x3F;
+		dev_err(&ofdev->dev,
+			"MII clock (%d Hz) exceeds max (2.5 MHz)\n",
+			clock / speed);
+	}
+
+	fec->mii_speed = speed << 1;
 
 	setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
 	setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX |
 	                                  FEC_ECNTRL_ETHER_EN);
 	out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII);
-	out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed);
+	clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed);
 
 	new_bus->phy_mask = ~0;
 	new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
@@ -188,6 +211,12 @@ static struct of_device_id fs_enet_mdio_fec_match[] = {
 	{
 		.compatible = "fsl,pq1-fec-mdio",
 	},
+#if defined(CONFIG_PPC_MPC512x)
+	{
+		.compatible = "fsl,mpc5121-fec-mdio",
+		.data = mpc5xxx_get_bus_frequency,
+	},
+#endif
 	{},
 };
 
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index a00ec63..1e5289f 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -297,7 +297,6 @@ static int gfar_probe(struct of_device *ofdev,
 	u32 tempval;
 	struct net_device *dev = NULL;
 	struct gfar_private *priv = NULL;
-	DECLARE_MAC_BUF(mac);
 	int err = 0;
 	int len_devname;
 
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index d62378c..1d5064a 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -557,7 +557,8 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void hamachi_timer(unsigned long data);
 static void hamachi_tx_timeout(struct net_device *dev);
 static void hamachi_init_ring(struct net_device *dev);
-static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t hamachi_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev);
 static irqreturn_t hamachi_interrupt(int irq, void *dev_instance);
 static int hamachi_rx(struct net_device *dev);
 static inline int hamachi_tx(struct net_device *dev);
@@ -1263,7 +1264,8 @@ do { \
 } while (0)
 #endif
 
-static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hamachi_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct hamachi_private *hmp = netdev_priv(dev);
 	unsigned entry;
@@ -1372,7 +1374,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: Hamachi transmit frame #%d queued in slot %d.\n",
 			   dev->name, hmp->cur_tx, entry);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 981ab53..fb58830 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -242,7 +242,7 @@ out_drop:
 
 /* Encapsulate an IP datagram and kick it into a TTY queue. */
 
-static int sp_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sp_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct sixpack *sp = netdev_priv(dev);
 
@@ -255,7 +255,7 @@ static int sp_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int sp_open_dev(struct net_device *dev)
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 3527032..7bcaf7c 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -774,18 +774,18 @@ static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
 	if (skb->data[0] != 0) {
 		do_kiss_params(bc, skb->data, skb->len);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (bc->skb)
 		return NETDEV_TX_LOCKED;
 	/* strip KISS byte */
 	if (skb->len >= HDLCDRV_MAXFLEN+1 || skb->len < 3) {
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	netif_stop_queue(dev);
 	bc->skb = skb;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index abcd19a..fe893c9 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -247,9 +247,8 @@ drop:
 /*
  * 	Send an AX.25 frame via an ethernet interface
  */
-static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct sk_buff *newskb;
 	unsigned char *ptr;
 	struct bpqdev *bpq;
 	int size;
@@ -263,28 +262,23 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_OK;
 	}
 
-	skb_pull(skb, 1);
+	skb_pull(skb, 1);			/* Drop KISS byte */
 	size = skb->len;
 
 	/*
-	 * The AX.25 code leaves enough room for the ethernet header, but
-	 * sendto() does not.
+	 * We're about to mess with the skb which may still shared with the
+	 * generic networking code so unshare and ensure it's got enough
+	 * space for the BPQ headers.
 	 */
-	if (skb_headroom(skb) < AX25_BPQ_HEADER_LEN) {	/* Ough! */
-		if ((newskb = skb_realloc_headroom(skb, AX25_BPQ_HEADER_LEN)) == NULL) {
-			printk(KERN_WARNING "bpqether: out of memory\n");
-			kfree_skb(skb);
-			return NETDEV_TX_OK;
-		}
-
-		if (skb->sk != NULL)
-			skb_set_owner_w(newskb, skb->sk);
-
+	if (skb_cow(skb, AX25_BPQ_HEADER_LEN)) {
+		if (net_ratelimit())
+			pr_err("bpqether: out of memory\n");
 		kfree_skb(skb);
-		skb = newskb;
+
+		return NETDEV_TX_OK;
 	}
 
-	ptr = skb_push(skb, 2);
+	ptr = skb_push(skb, 2);			/* Make space for length */
 
 	*ptr++ = (size + 5) % 256;
 	*ptr++ = (size + 5) / 256;
@@ -305,7 +299,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
   
 	dev_queue_xmit(skb);
 	netif_wake_queue(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 7459b3a..950f3bb 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -959,7 +959,7 @@ static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irqrestore(&priv->ring_lock, flags);
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index d034f8c..0013c40 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -399,20 +399,21 @@ void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
  * ===================== network driver interface =========================
  */
 
-static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hdlcdrv_send_packet(struct sk_buff *skb,
+				       struct net_device *dev)
 {
 	struct hdlcdrv_state *sm = netdev_priv(dev);
 
 	if (skb->data[0] != 0) {
 		do_kiss_params(sm, skb->data, skb->len);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (sm->skb)
 		return NETDEV_TX_LOCKED;
 	netif_stop_queue(dev);
 	sm->skb = skb;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* --------------------------------------------------------------------- */
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index fda2fc8..33b55f7 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -525,7 +525,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
 }
 
 /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
-static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ax_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mkiss *ax = netdev_priv(dev);
 
@@ -560,7 +560,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
 		kfree_skb(skb);
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int ax_open_dev(struct net_device *dev)
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index d712e7a..35c9361 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -209,7 +209,8 @@ static void scc_net_setup(struct net_device *dev);
 static int scc_net_open(struct net_device *dev);
 static int scc_net_close(struct net_device *dev);
 static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb);
-static int scc_net_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t scc_net_tx(struct sk_buff *skb,
+			      struct net_device *dev);
 static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static int scc_net_set_mac_address(struct net_device *dev, void *addr);
 static struct net_device_stats * scc_net_get_stats(struct net_device *dev);
@@ -1634,7 +1635,7 @@ static void scc_net_rx(struct scc_channel *scc, struct sk_buff *skb)
 
 /* ----> transmit frame <---- */
 
-static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t scc_net_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct scc_channel *scc = (struct scc_channel *) dev->ml_priv;
 	unsigned long flags;
@@ -1643,7 +1644,7 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
 	if (skb->len > scc->stat.bufsize || skb->len < 2) {
 		scc->dev_stat.tx_dropped++;	/* bogus frame */
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	
 	scc->dev_stat.tx_packets++;
@@ -1656,7 +1657,7 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
 	if (kisscmd) {
 		scc_set_param(scc, kisscmd, *skb->data);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	spin_lock_irqsave(&scc->lock, flags);
@@ -1684,7 +1685,7 @@ static int scc_net_tx(struct sk_buff *skb, struct net_device *dev)
 			__scc_start_tx_timer(scc, t_dwait, 0);
 	}
 	spin_unlock_irqrestore(&scc->lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* ----> ioctl functions <---- */
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index b066919..694132e 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -594,13 +594,14 @@ static void ptt_off(struct net_device *dev)
 	outb(PTT_OFF, MCR(dev->base_addr));
 }
 
-static int yam_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t yam_send_packet(struct sk_buff *skb,
+					 struct net_device *dev)
 {
 	struct yam_port *yp = netdev_priv(dev);
 
 	skb_queue_tail(&yp->send_queue, skb);
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void yam_start_tx(struct net_device *dev, struct yam_port *yp)
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index 1d3429a..a9a1a99 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -240,9 +240,10 @@ static int hp100_probe1(struct net_device *dev, int ioaddr, u_char bus,
 
 static int hp100_open(struct net_device *dev);
 static int hp100_close(struct net_device *dev);
-static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int hp100_start_xmit_bm(struct sk_buff *skb,
-			       struct net_device *dev);
+static netdev_tx_t hp100_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev);
+static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
+				       struct net_device *dev);
 static void hp100_rx(struct net_device *dev);
 static struct net_device_stats *hp100_get_stats(struct net_device *dev);
 static void hp100_misc_interrupt(struct net_device *dev);
@@ -1483,7 +1484,8 @@ static int hp100_check_lan(struct net_device *dev)
  */
 
 /* tx function for busmaster mode */
-static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
+				       struct net_device *dev)
 {
 	unsigned long flags;
 	int i, ok_flag;
@@ -1499,7 +1501,7 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
 		goto drop;
 
 	if (lp->chip == HP100_CHIPID_SHASTA && skb_padto(skb, ETH_ZLEN))
-		return 0;
+		return NETDEV_TX_OK;
 
 	/* Get Tx ring tail pointer */
 	if (lp->txrtail->next == lp->txrhead) {
@@ -1585,7 +1587,7 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev)
 	lp->stats.tx_bytes += skb->len;
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 
 drop:
 	dev_kfree_skb(skb);
@@ -1635,7 +1637,8 @@ static void hp100_clean_txring(struct net_device *dev)
 }
 
 /* tx function for slave modes */
-static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hp100_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	unsigned long flags;
 	int i, ok_flag;
@@ -1752,7 +1755,7 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	printk("hp100: %s: start_xmit: end\n", dev->name);
 #endif
 
-	return 0;
+	return NETDEV_TX_OK;
 
 drop:
 	dev_kfree_skb(skb);
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index 8ac0930..d496b6f 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -173,9 +173,9 @@ static int __devinit hydra_init(struct zorro_dev *z)
 
     zorro_set_drvdata(z, dev);
 
-    printk(KERN_INFO "%s: Hydra at 0x%08lx, address "
+    printk(KERN_INFO "%s: Hydra at 0x%08llx, address "
 	   "%pM (hydra.c " HYDRA_VERSION ")\n",
-	   dev->name, z->resource.start, dev->dev_addr);
+	   dev->name, (unsigned long long)z->resource.start, dev->dev_addr);
 
     return 0;
 }
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index f0f8908..1d7d7fe 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -1344,7 +1344,7 @@ static inline int emac_xmit_finish(struct emac_instance *dev, int len)
 	++dev->stats.tx_packets;
 	dev->stats.tx_bytes += len;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* Tx lock BH */
@@ -2209,7 +2209,7 @@ static const struct ethtool_ops emac_ethtool_ops = {
 static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
 	struct emac_instance *dev = netdev_priv(ndev);
-	uint16_t *data = (uint16_t *) & rq->ifr_ifru;
+	struct mii_ioctl_data *data = if_mii(rq);
 
 	DBG(dev, "ioctl %08x" NL, cmd);
 
@@ -2218,19 +2218,16 @@ static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 
 	switch (cmd) {
 	case SIOCGMIIPHY:
-	case SIOCDEVPRIVATE:
-		data[0] = dev->phy.address;
+		data->phy_id = dev->phy.address;
 		/* Fall through */
 	case SIOCGMIIREG:
-	case SIOCDEVPRIVATE + 1:
-		data[3] = emac_mdio_read(ndev, dev->phy.address, data[1]);
+		data->val_out = emac_mdio_read(ndev, dev->phy.address,
+					       data->reg_num);
 		return 0;
 
 	case SIOCSMIIREG:
-	case SIOCDEVPRIVATE + 2:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		emac_mdio_write(ndev, dev->phy.address, data[1], data[2]);
+		emac_mdio_write(ndev, dev->phy.address, data->reg_num,
+				data->val_in);
 		return 0;
 	default:
 		return -EOPNOTSUPP;
diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
index 448098d..090a6d3 100644
--- a/drivers/net/ibmlana.c
+++ b/drivers/net/ibmlana.c
@@ -812,7 +812,7 @@ static int ibmlana_close(struct net_device *dev)
 
 /* transmit a block. */
 
-static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	ibmlana_priv *priv = netdev_priv(dev);
 	int tmplen, addr;
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 0995c43..5862282 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -887,7 +887,8 @@ static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 #define page_offset(v) ((unsigned long)(v) & ((1 << 12) - 1))
 
-static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb,
+				      struct net_device *netdev)
 {
 	struct ibmveth_adapter *adapter = netdev_priv(netdev);
 	union ibmveth_buf_desc desc;
@@ -971,7 +972,7 @@ out:	spin_lock_irqsave(&adapter->stats_lock, flags);
 	spin_unlock_irqrestore(&adapter->stats_lock, flags);
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int ibmveth_poll(struct napi_struct *napi, int budget)
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 96713ef..801f088 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -59,7 +59,7 @@ struct ifb_private {
 static int numifbs = 2;
 
 static void ri_tasklet(unsigned long dev);
-static int ifb_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev);
 static int ifb_open(struct net_device *dev);
 static int ifb_close(struct net_device *dev);
 
@@ -160,11 +160,10 @@ static void ifb_setup(struct net_device *dev)
 	random_ether_addr(dev->dev_addr);
 }
 
-static int ifb_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ifb_private *dp = netdev_priv(dev);
 	struct net_device_stats *stats = &dev->stats;
-	int ret = 0;
 	u32 from = G_TC_FROM(skb->tc_verd);
 
 	stats->rx_packets++;
@@ -173,7 +172,7 @@ static int ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (!(from & (AT_INGRESS|AT_EGRESS)) || !skb->iif) {
 		dev_kfree_skb(skb);
 		stats->rx_dropped++;
-		return ret;
+		return NETDEV_TX_OK;
 	}
 
 	if (skb_queue_len(&dp->rq) >= dev->tx_queue_len) {
@@ -187,7 +186,7 @@ static int ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 		tasklet_schedule(&dp->ifb_tasklet);
 	}
 
-	return ret;
+	return NETDEV_TX_OK;
 }
 
 static int ifb_close(struct net_device *dev)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index ac28dd5..f8f5772 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -49,11 +49,10 @@ static s32  igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
 static s32  igb_reset_hw_82575(struct e1000_hw *);
 static s32  igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
 static s32  igb_setup_copper_link_82575(struct e1000_hw *);
-static s32  igb_setup_fiber_serdes_link_82575(struct e1000_hw *);
+static s32  igb_setup_serdes_link_82575(struct e1000_hw *);
 static s32  igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16);
 static void igb_clear_hw_cntrs_82575(struct e1000_hw *);
 static s32  igb_acquire_swfw_sync_82575(struct e1000_hw *, u16);
-static s32  igb_configure_pcs_link_82575(struct e1000_hw *);
 static s32  igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *, u16 *,
 						 u16 *);
 static s32  igb_get_phy_id_82575(struct e1000_hw *);
@@ -61,6 +60,7 @@ static void igb_release_swfw_sync_82575(struct e1000_hw *, u16);
 static bool igb_sgmii_active_82575(struct e1000_hw *);
 static s32  igb_reset_init_script_82575(struct e1000_hw *);
 static s32  igb_read_mac_addr_82575(struct e1000_hw *);
+static s32  igb_set_pcie_completion_timeout(struct e1000_hw *hw);
 
 static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 {
@@ -84,6 +84,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 	case E1000_DEV_ID_82576_FIBER:
 	case E1000_DEV_ID_82576_SERDES:
 	case E1000_DEV_ID_82576_QUAD_COPPER:
+	case E1000_DEV_ID_82576_SERDES_QUAD:
 		mac->type = e1000_82576;
 		break;
 	default:
@@ -103,16 +104,20 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 	dev_spec->sgmii_active = false;
 
 	ctrl_ext = rd32(E1000_CTRL_EXT);
-	if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) ==
-	    E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES) {
-		hw->phy.media_type = e1000_media_type_internal_serdes;
-		ctrl_ext |= E1000_CTRL_I2C_ENA;
-	} else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) {
+	switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
+	case E1000_CTRL_EXT_LINK_MODE_SGMII:
 		dev_spec->sgmii_active = true;
 		ctrl_ext |= E1000_CTRL_I2C_ENA;
-	} else {
+		break;
+	case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
+		hw->phy.media_type = e1000_media_type_internal_serdes;
+		ctrl_ext |= E1000_CTRL_I2C_ENA;
+		break;
+	default:
 		ctrl_ext &= ~E1000_CTRL_I2C_ENA;
+		break;
 	}
+
 	wr32(E1000_CTRL_EXT, ctrl_ext);
 
 	/* Set mta register count */
@@ -132,7 +137,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 	mac->ops.setup_physical_interface =
 		(hw->phy.media_type == e1000_media_type_copper)
 			? igb_setup_copper_link_82575
-			: igb_setup_fiber_serdes_link_82575;
+			: igb_setup_serdes_link_82575;
 
 	/* NVM initialization */
 	eecd = rd32(E1000_EECD);
@@ -170,6 +175,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 		size = 14;
 	nvm->word_size = 1 << size;
 
+	/* if 82576 then initialize mailbox parameters */
+	if (mac->type == e1000_82576)
+		igb_init_mbx_params_pf(hw);
+
 	/* setup PHY parameters */
 	if (phy->media_type != e1000_media_type_copper) {
 		phy->type = e1000_phy_none;
@@ -219,10 +228,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 		return -E1000_ERR_PHY;
 	}
 
-	/* if 82576 then initialize mailbox parameters */
-	if (mac->type == e1000_82576)
-		igb_init_mbx_params_pf(hw);
-
 	return 0;
 }
 
@@ -377,6 +382,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
 	struct e1000_phy_info *phy = &hw->phy;
 	s32  ret_val = 0;
 	u16 phy_id;
+	u32 ctrl_ext;
 
 	/*
 	 * For SGMII PHYs, we try the list of possible addresses until
@@ -391,6 +397,12 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
 		goto out;
 	}
 
+	/* Power on sgmii phy if it is disabled */
+	ctrl_ext = rd32(E1000_CTRL_EXT);
+	wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA);
+	wrfl();
+	msleep(300);
+
 	/*
 	 * The address field in the I2CCMD register is 3 bits and 0 is invalid.
 	 * Therefore, we need to test 1-7
@@ -416,9 +428,12 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
 		phy->addr = 0;
 		ret_val = -E1000_ERR_PHY;
 		goto out;
+	} else {
+		ret_val = igb_get_phy_id(hw);
 	}
 
-	ret_val = igb_get_phy_id(hw);
+	/* restore previous sfp cage power state */
+	wr32(E1000_CTRL_EXT, ctrl_ext);
 
 out:
 	return ret_val;
@@ -764,111 +779,18 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
 }
 
 /**
- *  igb_init_rx_addrs_82575 - Initialize receive address's
- *  @hw: pointer to the HW structure
- *  @rar_count: receive address registers
- *
- *  Setups the receive address registers by setting the base receive address
- *  register to the devices MAC address and clearing all the other receive
- *  address registers to 0.
- **/
-static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
-{
-	u32 i;
-	u8 addr[6] = {0,0,0,0,0,0};
-	/*
-	 * This function is essentially the same as that of
-	 * e1000_init_rx_addrs_generic. However it also takes care
-	 * of the special case where the register offset of the
-	 * second set of RARs begins elsewhere. This is implicitly taken care by
-	 * function e1000_rar_set_generic.
-	 */
-
-	hw_dbg("e1000_init_rx_addrs_82575");
-
-	/* Setup the receive address */
-	hw_dbg("Programming MAC Address into RAR[0]\n");
-	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
-
-	/* Zero out the other (rar_entry_count - 1) receive addresses */
-	hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
-	for (i = 1; i < rar_count; i++)
-	    hw->mac.ops.rar_set(hw, addr, i);
-}
-
-/**
- *  igb_update_mc_addr_list - Update Multicast addresses
- *  @hw: pointer to the HW structure
- *  @mc_addr_list: array of multicast addresses to program
- *  @mc_addr_count: number of multicast addresses to program
- *  @rar_used_count: the first RAR register free to program
- *  @rar_count: total number of supported Receive Address Registers
- *
- *  Updates the Receive Address Registers and Multicast Table Array.
- *  The caller must have a packed mc_addr_list of multicast addresses.
- *  The parameter rar_count will usually be hw->mac.rar_entry_count
- *  unless there are workarounds that change this.
- **/
-void igb_update_mc_addr_list(struct e1000_hw *hw,
-                             u8 *mc_addr_list, u32 mc_addr_count,
-                             u32 rar_used_count, u32 rar_count)
-{
-	u32 hash_value;
-	u32 i;
-	u8 addr[6] = {0,0,0,0,0,0};
-	/*
-	 * This function is essentially the same as that of 
-	 * igb_update_mc_addr_list_generic. However it also takes care 
-	 * of the special case where the register offset of the 
-	 * second set of RARs begins elsewhere. This is implicitly taken care by 
-	 * function e1000_rar_set_generic.
-	 */
-
-	/*
-	 * Load the first set of multicast addresses into the exact
-	 * filters (RAR).  If there are not enough to fill the RAR
-	 * array, clear the filters.
-	 */
-	for (i = rar_used_count; i < rar_count; i++) {
-		if (mc_addr_count) {
-			igb_rar_set(hw, mc_addr_list, i);
-			mc_addr_count--;
-			mc_addr_list += ETH_ALEN;
-		} else {
-			igb_rar_set(hw, addr, i);
-		}
-	}
-
-	/* Clear the old settings from the MTA */
-	hw_dbg("Clearing MTA\n");
-	for (i = 0; i < hw->mac.mta_reg_count; i++) {
-		array_wr32(E1000_MTA, i, 0);
-		wrfl();
-	}
-
-	/* Load any remaining multicast addresses into the hash table. */
-	for (; mc_addr_count > 0; mc_addr_count--) {
-		hash_value = igb_hash_mc_addr(hw, mc_addr_list);
-		hw_dbg("Hash value = 0x%03X\n", hash_value);
-		igb_mta_set(hw, hash_value);
-		mc_addr_list += ETH_ALEN;
-	}
-}
-
-/**
- *  igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
+ *  igb_shutdown_serdes_link_82575 - Remove link during power down
  *  @hw: pointer to the HW structure
  *
  *  In the case of fiber serdes, shut down optics and PCS on driver unload
  *  when management pass thru is not enabled.
  **/
-void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
+void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
 {
 	u32 reg;
 
-	if (hw->mac.type != e1000_82576 ||
-	    (hw->phy.media_type != e1000_media_type_fiber &&
-	     hw->phy.media_type != e1000_media_type_internal_serdes))
+	if (hw->phy.media_type != e1000_media_type_internal_serdes ||
+	    igb_sgmii_active_82575(hw))
 		return;
 
 	/* if the management interface is not enabled, then power down */
@@ -880,7 +802,7 @@ void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
 
 		/* shutdown the laser */
 		reg = rd32(E1000_CTRL_EXT);
-		reg |= E1000_CTRL_EXT_SDP7_DATA;
+		reg |= E1000_CTRL_EXT_SDP3_DATA;
 		wr32(E1000_CTRL_EXT, reg);
 
 		/* flush the write to verify completion */
@@ -911,6 +833,12 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
 	if (ret_val)
 		hw_dbg("PCI-E Master disable polling has failed.\n");
 
+	/* set the completion timeout for interface */
+	ret_val = igb_set_pcie_completion_timeout(hw);
+	if (ret_val) {
+		hw_dbg("PCI-E Set completion timeout has failed.\n");
+	}
+
 	hw_dbg("Masking off all interrupts\n");
 	wr32(E1000_IMC, 0xffffffff);
 
@@ -943,7 +871,8 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
 	wr32(E1000_IMC, 0xffffffff);
 	icr = rd32(E1000_ICR);
 
-	igb_check_alt_mac_addr(hw);
+	/* Install any alternate MAC address into RAR0 */
+	ret_val = igb_check_alt_mac_addr(hw);
 
 	return ret_val;
 }
@@ -972,7 +901,8 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
 	igb_clear_vfta(hw);
 
 	/* Setup the receive address */
-	igb_init_rx_addrs_82575(hw, rar_count);
+	igb_init_rx_addrs(hw, rar_count);
+
 	/* Zero out the Multicast HASH table */
 	hw_dbg("Zeroing the MTA\n");
 	for (i = 0; i < mac->mta_reg_count; i++)
@@ -1002,7 +932,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
  **/
 static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
 {
-	u32 ctrl, led_ctrl;
+	u32 ctrl;
 	s32  ret_val;
 	bool link;
 
@@ -1011,17 +941,23 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
 	wr32(E1000_CTRL, ctrl);
 
+	ret_val = igb_setup_serdes_link_82575(hw);
+	if (ret_val)
+		goto out;
+
+	if (igb_sgmii_active_82575(hw) && !hw->phy.reset_disable) {
+		ret_val = hw->phy.ops.reset(hw);
+		if (ret_val) {
+			hw_dbg("Error resetting the PHY.\n");
+			goto out;
+		}
+	}
 	switch (hw->phy.type) {
 	case e1000_phy_m88:
 		ret_val = igb_copper_link_setup_m88(hw);
 		break;
 	case e1000_phy_igp_3:
 		ret_val = igb_copper_link_setup_igp(hw);
-		/* Setup activity LED */
-		led_ctrl = rd32(E1000_LEDCTL);
-		led_ctrl &= IGP_ACTIVITY_LED_MASK;
-		led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-		wr32(E1000_LEDCTL, led_ctrl);
 		break;
 	default:
 		ret_val = -E1000_ERR_PHY;
@@ -1052,10 +988,6 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
 		}
 	}
 
-	ret_val = igb_configure_pcs_link_82575(hw);
-	if (ret_val)
-		goto out;
-
 	/*
 	 * Check link status. Wait up to 100 microseconds for link to become
 	 * valid.
@@ -1078,14 +1010,18 @@ out:
 }
 
 /**
- *  igb_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes
+ *  igb_setup_serdes_link_82575 - Setup link for fiber/serdes
  *  @hw: pointer to the HW structure
  *
  *  Configures speed and duplex for fiber and serdes links.
  **/
-static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
+static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
 {
-	u32 reg;
+	u32 ctrl_reg, reg;
+
+	if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
+	    !igb_sgmii_active_82575(hw))
+		return 0;
 
 	/*
 	 * On the 82575, SerDes loopback mode persists until it is
@@ -1095,26 +1031,38 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
 	 */
 	wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
 
-	/* Force link up, set 1gb, set both sw defined pins */
-	reg = rd32(E1000_CTRL);
-	reg |= E1000_CTRL_SLU |
-	       E1000_CTRL_SPD_1000 |
-	       E1000_CTRL_FRCSPD |
-	       E1000_CTRL_SWDPIN0 |
-	       E1000_CTRL_SWDPIN1;
-	wr32(E1000_CTRL, reg);
-
-	/* Power on phy for 82576 fiber adapters */
-	if (hw->mac.type == e1000_82576) {
-		reg = rd32(E1000_CTRL_EXT);
-		reg &= ~E1000_CTRL_EXT_SDP7_DATA;
-		wr32(E1000_CTRL_EXT, reg);
+	/* power on the sfp cage if present */
+	reg = rd32(E1000_CTRL_EXT);
+	reg &= ~E1000_CTRL_EXT_SDP3_DATA;
+	wr32(E1000_CTRL_EXT, reg);
+
+	ctrl_reg = rd32(E1000_CTRL);
+	ctrl_reg |= E1000_CTRL_SLU;
+
+	if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) {
+		/* set both sw defined pins */
+		ctrl_reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
+
+		/* Set switch control to serdes energy detect */
+		reg = rd32(E1000_CONNSW);
+		reg |= E1000_CONNSW_ENRGSRC;
+		wr32(E1000_CONNSW, reg);
+	}
+
+	reg = rd32(E1000_PCS_LCTL);
+
+	if (igb_sgmii_active_82575(hw)) {
+		/* allow time for SFP cage to power up phy */
+		msleep(300);
+
+		/* AN time out should be disabled for SGMII mode */
+		reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
+	} else {
+		ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
+		            E1000_CTRL_FD | E1000_CTRL_FRCDPX;
 	}
 
-	/* Set switch control to serdes energy detect */
-	reg = rd32(E1000_CONNSW);
-	reg |= E1000_CONNSW_ENRGSRC;
-	wr32(E1000_CONNSW, reg);
+	wr32(E1000_CTRL, ctrl_reg);
 
 	/*
 	 * New SerDes mode allows for forcing speed or autonegotiating speed
@@ -1122,12 +1070,21 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
 	 * mode that will be compatible with older link partners and switches.
 	 * However, both are supported by the hardware and some drivers/tools.
 	 */
-	reg = rd32(E1000_PCS_LCTL);
 
 	reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
 		E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
 
-	if (hw->mac.autoneg) {
+	/*
+	 * We force flow control to prevent the CTRL register values from being
+	 * overwritten by the autonegotiated flow control values
+	 */
+	reg |= E1000_PCS_LCTL_FORCE_FCTRL;
+
+	/*
+	 * we always set sgmii to autoneg since it is the phy that will be
+	 * forcing the link and the serdes is just a go-between
+	 */
+	if (hw->mac.autoneg || igb_sgmii_active_82575(hw)) {
 		/* Set PCS register for autoneg */
 		reg |= E1000_PCS_LCTL_FSV_1000 |      /* Force 1000    */
 		       E1000_PCS_LCTL_FDV_FULL |      /* SerDes Full duplex */
@@ -1144,77 +1101,11 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
 		hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
 	}
 
-	if (hw->mac.type == e1000_82576) {
-		reg |= E1000_PCS_LCTL_FORCE_FCTRL;
-		igb_force_mac_fc(hw);
-	}
-
 	wr32(E1000_PCS_LCTL, reg);
 
-	return 0;
-}
-
-/**
- *  igb_configure_pcs_link_82575 - Configure PCS link
- *  @hw: pointer to the HW structure
- *
- *  Configure the physical coding sub-layer (PCS) link.  The PCS link is
- *  only used on copper connections where the serialized gigabit media
- *  independent interface (sgmii) is being used.  Configures the link
- *  for auto-negotiation or forces speed/duplex.
- **/
-static s32 igb_configure_pcs_link_82575(struct e1000_hw *hw)
-{
-	struct e1000_mac_info *mac = &hw->mac;
-	u32 reg = 0;
-
-	if (hw->phy.media_type != e1000_media_type_copper ||
-	    !(igb_sgmii_active_82575(hw)))
-		goto out;
-
-	/* For SGMII, we need to issue a PCS autoneg restart */
-	reg = rd32(E1000_PCS_LCTL);
-
-	/* AN time out should be disabled for SGMII mode */
-	reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
-
-	if (mac->autoneg) {
-		/* Make sure forced speed and force link are not set */
-		reg &= ~(E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
-
-		/*
-		 * The PHY should be setup prior to calling this function.
-		 * All we need to do is restart autoneg and enable autoneg.
-		 */
-		reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE;
-	} else {
-		/* Set PCS register for forced speed */
-
-		/* Turn off bits for full duplex, speed, and autoneg */
-		reg &= ~(E1000_PCS_LCTL_FSV_1000 |
-			 E1000_PCS_LCTL_FSV_100 |
-			 E1000_PCS_LCTL_FDV_FULL |
-			 E1000_PCS_LCTL_AN_ENABLE);
-
-		/* Check for duplex first */
-		if (mac->forced_speed_duplex & E1000_ALL_FULL_DUPLEX)
-			reg |= E1000_PCS_LCTL_FDV_FULL;
-
-		/* Now set speed */
-		if (mac->forced_speed_duplex & E1000_ALL_100_SPEED)
-			reg |= E1000_PCS_LCTL_FSV_100;
-
-		/* Force speed and force link */
-		reg |= E1000_PCS_LCTL_FSD |
-		       E1000_PCS_LCTL_FORCE_LINK |
-		       E1000_PCS_LCTL_FLV_LINK_UP;
-
-		hw_dbg("Wrote 0x%08X to PCS_LCTL to configure forced link\n",
-		       reg);
-	}
-	wr32(E1000_PCS_LCTL, reg);
+	if (!igb_sgmii_active_82575(hw))
+		igb_force_mac_fc(hw);
 
-out:
 	return 0;
 }
 
@@ -1229,10 +1120,6 @@ out:
 static bool igb_sgmii_active_82575(struct e1000_hw *hw)
 {
 	struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
-
-	if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
-		return false;
-
 	return dev_spec->sgmii_active;
 }
 
@@ -1346,7 +1233,8 @@ static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
 	temp = rd32(E1000_LENERRS);
 
 	/* This register should not be read in copper configurations */
-	if (hw->phy.media_type == e1000_media_type_internal_serdes)
+	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
+	    igb_sgmii_active_82575(hw))
 		temp = rd32(E1000_SCVPC);
 }
 
@@ -1424,6 +1312,57 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
 }
 
 /**
+ *  igb_set_pcie_completion_timeout - set pci-e completion timeout
+ *  @hw: pointer to the HW structure
+ *
+ *  The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
+ *  however the hardware default for these parts is 500us to 1ms which is less
+ *  than the 10ms recommended by the pci-e spec.  To address this we need to
+ *  increase the value to either 10ms to 200ms for capability version 1 config,
+ *  or 16ms to 55ms for version 2.
+ **/
+static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw)
+{
+	u32 gcr = rd32(E1000_GCR);
+	s32 ret_val = 0;
+	u16 pcie_devctl2;
+
+	/* only take action if timeout value is defaulted to 0 */
+	if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
+		goto out;
+
+	/*
+	 * if capababilities version is type 1 we can write the
+	 * timeout of 10ms to 200ms through the GCR register
+	 */
+	if (!(gcr & E1000_GCR_CAP_VER2)) {
+		gcr |= E1000_GCR_CMPL_TMOUT_10ms;
+		goto out;
+	}
+
+	/*
+	 * for version 2 capabilities we need to write the config space
+	 * directly in order to set the completion timeout value for
+	 * 16ms to 55ms
+	 */
+	ret_val = igb_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+	                                &pcie_devctl2);
+	if (ret_val)
+		goto out;
+
+	pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
+
+	ret_val = igb_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
+	                                 &pcie_devctl2);
+out:
+	/* disable completion timeout resend */
+	gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
+
+	wr32(E1000_GCR, gcr);
+	return ret_val;
+}
+
+/**
  *  igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
  *  @hw: pointer to the hardware struct
  *  @enable: state to enter, either enabled or disabled
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index 0f16aba..ebd146f 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -28,10 +28,14 @@
 #ifndef _E1000_82575_H_
 #define _E1000_82575_H_
 
-void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
-extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
+extern void igb_shutdown_serdes_link_82575(struct e1000_hw *hw);
 extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
 
+#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
+                                     (ID_LED_DEF1_DEF2 <<  8) | \
+                                     (ID_LED_DEF1_DEF2 <<  4) | \
+                                     (ID_LED_OFF1_ON2))
+
 #define E1000_RAR_ENTRIES_82575   16
 #define E1000_RAR_ENTRIES_82576   24
 
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 3bda3db..cb91683 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -44,7 +44,7 @@
 #define E1000_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
 
 /* Extended Device Control */
-#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Defineable Pin 3 */
 /* Physical Func Reset Done Indication */
 #define E1000_CTRL_EXT_PFRSTD    0x00004000
 #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
@@ -435,6 +435,12 @@
 /* Flow Control */
 #define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
 
+/* PCI Express Control */
+#define E1000_GCR_CMPL_TMOUT_MASK       0x0000F000
+#define E1000_GCR_CMPL_TMOUT_10ms       0x00001000
+#define E1000_GCR_CMPL_TMOUT_RESEND     0x00010000
+#define E1000_GCR_CAP_VER2              0x00040000
+
 /* PHY Control Register */
 #define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
 #define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
@@ -569,9 +575,11 @@
 
 /* PCI/PCI-X/PCI-EX Config space */
 #define PCIE_LINK_STATUS             0x12
+#define PCIE_DEVICE_CONTROL2         0x28
 
 #define PCIE_LINK_WIDTH_MASK         0x3F0
 #define PCIE_LINK_WIDTH_SHIFT        4
+#define PCIE_DEVICE_CONTROL2_16ms    0x0005
 
 #define PHY_REVISION_MASK      0xFFFFFFF0
 #define MAX_PHY_REG_ADDRESS    0x1F  /* 5 bit address bus (0-0x1F) */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 68aac20..119869b 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -42,6 +42,7 @@ struct e1000_hw;
 #define E1000_DEV_ID_82576_SERDES             0x10E7
 #define E1000_DEV_ID_82576_QUAD_COPPER        0x10E8
 #define E1000_DEV_ID_82576_NS                 0x150A
+#define E1000_DEV_ID_82576_SERDES_QUAD        0x150D
 #define E1000_DEV_ID_82575EB_COPPER           0x10A7
 #define E1000_DEV_ID_82575EB_FIBER_SERDES     0x10A9
 #define E1000_DEV_ID_82575GB_QUAD_COPPER      0x10D6
@@ -61,8 +62,7 @@ enum e1000_mac_type {
 enum e1000_media_type {
 	e1000_media_type_unknown = 0,
 	e1000_media_type_copper = 1,
-	e1000_media_type_fiber = 2,
-	e1000_media_type_internal_serdes = 3,
+	e1000_media_type_internal_serdes = 2,
 	e1000_num_media_types
 };
 
@@ -137,7 +137,7 @@ enum e1000_rev_polarity {
 	e1000_rev_polarity_undefined = 0xFF
 };
 
-enum e1000_fc_type {
+enum e1000_fc_mode {
 	e1000_fc_none = 0,
 	e1000_fc_rx_pause,
 	e1000_fc_tx_pause,
@@ -339,6 +339,10 @@ struct e1000_mac_info {
 	u16 ifs_ratio;
 	u16 ifs_step_size;
 	u16 mta_reg_count;
+
+	/* Maximum size of the MTA register table in all supported adapters */
+	#define MAX_MTA_REG 128
+	u32 mta_shadow[MAX_MTA_REG];
 	u16 rar_entry_count;
 
 	u8  forced_speed_duplex;
@@ -425,8 +429,8 @@ struct e1000_fc_info {
 	u16 pause_time;     /* Flow control pause timer */
 	bool send_xon;      /* Flow control send XON */
 	bool strict_ieee;   /* Strict IEEE mode */
-	enum e1000_fc_type type; /* Type of flow control */
-	enum e1000_fc_type original_type;
+	enum e1000_fc_mode current_mode; /* Type of flow control */
+	enum e1000_fc_mode requested_mode;
 };
 
 struct e1000_mbx_operations {
@@ -495,5 +499,7 @@ extern char *igb_get_hw_dev_name(struct e1000_hw *hw);
 #else
 #define hw_dbg(format, arg...)
 #endif
-
 #endif
+/* These functions must be implemented by drivers */
+s32  igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
+s32  igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 472f3f1..a0231cd 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -37,20 +37,6 @@
 static s32 igb_set_default_fc(struct e1000_hw *hw);
 static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
 
-static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
-{
-	struct igb_adapter *adapter = hw->back;
-	u16 cap_offset;
-
-	cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
-	if (!cap_offset)
-		return -E1000_ERR_CONFIG;
-
-	pci_read_config_word(adapter->pdev, cap_offset + reg, value);
-
-	return 0;
-}
-
 /**
  *  igb_get_bus_info_pcie - Get PCIe bus information
  *  @hw: pointer to the HW structure
@@ -118,6 +104,31 @@ static void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
 }
 
 /**
+ *  igb_init_rx_addrs - Initialize receive address's
+ *  @hw: pointer to the HW structure
+ *  @rar_count: receive address registers
+ *
+ *  Setups the receive address registers by setting the base receive address
+ *  register to the devices MAC address and clearing all the other receive
+ *  address registers to 0.
+ **/
+void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
+{
+	u32 i;
+	u8 mac_addr[ETH_ALEN] = {0};
+
+	/* Setup the receive address */
+	hw_dbg("Programming MAC Address into RAR[0]\n");
+
+	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+	/* Zero out the other (rar_entry_count - 1) receive addresses */
+	hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
+	for (i = 1; i < rar_count; i++)
+		hw->mac.ops.rar_set(hw, mac_addr, i);
+}
+
+/**
  *  igb_vfta_set - enable or disable vlan in VLAN filter table
  *  @hw: pointer to the HW structure
  *  @vid: VLAN id to add or remove
@@ -275,6 +286,41 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
 }
 
 /**
+ *  igb_update_mc_addr_list - Update Multicast addresses
+ *  @hw: pointer to the HW structure
+ *  @mc_addr_list: array of multicast addresses to program
+ *  @mc_addr_count: number of multicast addresses to program
+ *
+ *  Updates entire Multicast Table Array.
+ *  The caller must have a packed mc_addr_list of multicast addresses.
+ **/
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+                             u8 *mc_addr_list, u32 mc_addr_count)
+{
+	u32 hash_value, hash_bit, hash_reg;
+	int i;
+
+	/* clear mta_shadow */
+	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
+
+	/* update mta_shadow from mc_addr_list */
+	for (i = 0; (u32) i < mc_addr_count; i++) {
+		hash_value = igb_hash_mc_addr(hw, mc_addr_list);
+
+		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+		hash_bit = hash_value & 0x1F;
+
+		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
+		mc_addr_list += (ETH_ALEN);
+	}
+
+	/* replace the entire MTA table */
+	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
+		array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
+	wrfl();
+}
+
+/**
  *  igb_hash_mc_addr - Generate a multicast hash value
  *  @hw: pointer to the HW structure
  *  @mc_addr: pointer to a multicast address
@@ -490,18 +536,24 @@ s32 igb_setup_link(struct e1000_hw *hw)
 	if (igb_check_reset_block(hw))
 		goto out;
 
-	ret_val = igb_set_default_fc(hw);
-	if (ret_val)
-		goto out;
+	/*
+	 * If requested flow control is set to default, set flow control
+	 * based on the EEPROM flow control settings.
+	 */
+	if (hw->fc.requested_mode == e1000_fc_default) {
+		ret_val = igb_set_default_fc(hw);
+		if (ret_val)
+			goto out;
+	}
 
 	/*
 	 * We want to save off the original Flow Control configuration just
 	 * in case we get disconnected and then reconnected into a different
 	 * hub or switch with different Flow Control capabilities.
 	 */
-	hw->fc.original_type = hw->fc.type;
+	hw->fc.current_mode = hw->fc.requested_mode;
 
-	hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.type);
+	hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
 
 	/* Call the necessary media_type subroutine to configure the link. */
 	ret_val = hw->mac.ops.setup_physical_interface(hw);
@@ -568,7 +620,7 @@ static s32 igb_set_fc_watermarks(struct e1000_hw *hw)
 	 * ability to transmit pause frames is not enabled, then these
 	 * registers will be set to 0.
 	 */
-	if (hw->fc.type & e1000_fc_tx_pause) {
+	if (hw->fc.current_mode & e1000_fc_tx_pause) {
 		/*
 		 * We need to set up the Receive Threshold high and low water
 		 * marks as well as (optionally) enabling the transmission of
@@ -615,12 +667,12 @@ static s32 igb_set_default_fc(struct e1000_hw *hw)
 	}
 
 	if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
-		hw->fc.type = e1000_fc_none;
+		hw->fc.requested_mode = e1000_fc_none;
 	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
 		 NVM_WORD0F_ASM_DIR)
-		hw->fc.type = e1000_fc_tx_pause;
+		hw->fc.requested_mode = e1000_fc_tx_pause;
 	else
-		hw->fc.type = e1000_fc_full;
+		hw->fc.requested_mode = e1000_fc_full;
 
 out:
 	return ret_val;
@@ -650,7 +702,7 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
 	 * receive flow control.
 	 *
 	 * The "Case" statement below enables/disable flow control
-	 * according to the "hw->fc.type" parameter.
+	 * according to the "hw->fc.current_mode" parameter.
 	 *
 	 * The possible values of the "fc" parameter are:
 	 *      0:  Flow control is completely disabled
@@ -661,9 +713,9 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
 	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
 	 *  other:  No other values should be possible at this point.
 	 */
-	hw_dbg("hw->fc.type = %u\n", hw->fc.type);
+	hw_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
 
-	switch (hw->fc.type) {
+	switch (hw->fc.current_mode) {
 	case e1000_fc_none:
 		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
 		break;
@@ -713,8 +765,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 	 * configuration of the MAC to match the "fc" parameter.
 	 */
 	if (mac->autoneg_failed) {
-		if (hw->phy.media_type == e1000_media_type_fiber ||
-		    hw->phy.media_type == e1000_media_type_internal_serdes)
+		if (hw->phy.media_type == e1000_media_type_internal_serdes)
 			ret_val = igb_force_mac_fc(hw);
 	} else {
 		if (hw->phy.media_type == e1000_media_type_copper)
@@ -812,11 +863,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 			 * ONLY. Hence, we must now check to see if we need to
 			 * turn OFF  the TRANSMISSION of PAUSE frames.
 			 */
-			if (hw->fc.original_type == e1000_fc_full) {
-				hw->fc.type = e1000_fc_full;
+			if (hw->fc.requested_mode == e1000_fc_full) {
+				hw->fc.current_mode = e1000_fc_full;
 				hw_dbg("Flow Control = FULL.\r\n");
 			} else {
-				hw->fc.type = e1000_fc_rx_pause;
+				hw->fc.current_mode = e1000_fc_rx_pause;
 				hw_dbg("Flow Control = "
 				       "RX PAUSE frames only.\r\n");
 			}
@@ -833,7 +884,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			hw->fc.type = e1000_fc_tx_pause;
+			hw->fc.current_mode = e1000_fc_tx_pause;
 			hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
 		}
 		/*
@@ -848,7 +899,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			hw->fc.type = e1000_fc_rx_pause;
+			hw->fc.current_mode = e1000_fc_rx_pause;
 			hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
 		}
 		/*
@@ -872,13 +923,13 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 		 * be asked to delay transmission of packets than asking
 		 * our link partner to pause transmission of frames.
 		 */
-		else if ((hw->fc.original_type == e1000_fc_none ||
-			  hw->fc.original_type == e1000_fc_tx_pause) ||
+		else if ((hw->fc.requested_mode == e1000_fc_none ||
+			  hw->fc.requested_mode == e1000_fc_tx_pause) ||
 			 hw->fc.strict_ieee) {
-			hw->fc.type = e1000_fc_none;
+			hw->fc.current_mode = e1000_fc_none;
 			hw_dbg("Flow Control = NONE.\r\n");
 		} else {
-			hw->fc.type = e1000_fc_rx_pause;
+			hw->fc.current_mode = e1000_fc_rx_pause;
 			hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
 		}
 
@@ -894,7 +945,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
 		}
 
 		if (duplex == HALF_DUPLEX)
-			hw->fc.type = e1000_fc_none;
+			hw->fc.current_mode = e1000_fc_none;
 
 		/*
 		 * Now we call a subroutine to actually force the MAC
@@ -1065,9 +1116,17 @@ static s32 igb_valid_led_default(struct e1000_hw *hw, u16 *data)
 		goto out;
 	}
 
-	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
-		*data = ID_LED_DEFAULT;
-
+	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
+		switch(hw->phy.media_type) {
+		case e1000_media_type_internal_serdes:
+			*data = ID_LED_DEFAULT_82575_SERDES;
+			break;
+		case e1000_media_type_copper:
+		default:
+			*data = ID_LED_DEFAULT;
+			break;
+		}
+	}
 out:
 	return ret_val;
 }
@@ -1161,22 +1220,16 @@ s32 igb_blink_led(struct e1000_hw *hw)
 	u32 ledctl_blink = 0;
 	u32 i;
 
-	if (hw->phy.media_type == e1000_media_type_fiber) {
-		/* always blink LED0 for PCI-E fiber */
-		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
-		     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
-	} else {
-		/*
-		 * set the blink bit for each LED that's "on" (0x0E)
-		 * in ledctl_mode2
-		 */
-		ledctl_blink = hw->mac.ledctl_mode2;
-		for (i = 0; i < 4; i++)
-			if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
-			    E1000_LEDCTL_MODE_LED_ON)
-				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
-						 (i * 8));
-	}
+	/*
+	 * set the blink bit for each LED that's "on" (0x0E)
+	 * in ledctl_mode2
+	 */
+	ledctl_blink = hw->mac.ledctl_mode2;
+	for (i = 0; i < 4; i++)
+		if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
+		    E1000_LEDCTL_MODE_LED_ON)
+			ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
+					 (i * 8));
 
 	wr32(E1000_LEDCTL, ledctl_blink);
 
@@ -1191,15 +1244,7 @@ s32 igb_blink_led(struct e1000_hw *hw)
  **/
 s32 igb_led_off(struct e1000_hw *hw)
 {
-	u32 ctrl;
-
 	switch (hw->phy.media_type) {
-	case e1000_media_type_fiber:
-		ctrl = rd32(E1000_CTRL);
-		ctrl |= E1000_CTRL_SWDPIN0;
-		ctrl |= E1000_CTRL_SWDPIO0;
-		wr32(E1000_CTRL, ctrl);
-		break;
 	case e1000_media_type_copper:
 		wr32(E1000_LEDCTL, hw->mac.ledctl_mode1);
 		break;
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index 1d690b4..7518af8 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -51,6 +51,8 @@ s32  igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
 				       u16 *duplex);
 s32  igb_id_led_init(struct e1000_hw *hw);
 s32  igb_led_off(struct e1000_hw *hw);
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+	                     u8 *mc_addr_list, u32 mc_addr_count);
 s32  igb_setup_link(struct e1000_hw *hw);
 s32  igb_validate_mdi_setting(struct e1000_hw *hw);
 s32  igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
@@ -60,6 +62,7 @@ void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
 void igb_clear_vfta(struct e1000_hw *hw);
 s32  igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
 void igb_config_collision_dist(struct e1000_hw *hw);
+void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
 void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
 void igb_put_hw_semaphore(struct e1000_hw *hw);
 void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index f50fac2..ee46060 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -735,7 +735,7 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
 	 *  other:  No software override.  The flow control configuration
 	 *          in the EEPROM is used.
 	 */
-	switch (hw->fc.type) {
+	switch (hw->fc.current_mode) {
 	case e1000_fc_none:
 		/*
 		 * Flow control (RX & TX) is completely disabled by a
@@ -992,7 +992,7 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
 	u32 ctrl;
 
 	/* Turn off flow control when forcing speed/duplex */
-	hw->fc.type = e1000_fc_none;
+	hw->fc.current_mode = e1000_fc_none;
 
 	/* Force speed/duplex on the mac */
 	ctrl = rd32(E1000_CTRL);
@@ -1565,9 +1565,12 @@ out:
  **/
 s32 igb_phy_sw_reset(struct e1000_hw *hw)
 {
-	s32 ret_val;
+	s32 ret_val = 0;
 	u16 phy_ctrl;
 
+	if (!(hw->phy.ops.read_reg))
+		goto out;
+
 	ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
 	if (ret_val)
 		goto out;
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index 6e59245..345d144 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -305,6 +305,7 @@ enum {
 #define E1000_CCMCTL      0x05B48 /* CCM Control Register */
 #define E1000_GIOCTL      0x05B44 /* GIO Analog Control Register */
 #define E1000_SCCTL       0x05B4C /* PCIc PLL Configuration Register */
+#define E1000_GCR         0x05B00 /* PCI-Ex Control */
 #define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
 #define E1000_SWSM      0x05B50 /* SW Semaphore */
 #define E1000_FWSM      0x05B54 /* FW Semaphore */
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index b2c98de..7126fea 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -70,6 +70,7 @@ struct vf_data_storage {
 	unsigned char vf_mac_addresses[ETH_ALEN];
 	u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
 	u16 num_vf_mc_hashes;
+	u16 vlans_enabled;
 	bool clear_to_send;
 };
 
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 9598ac0..d004c35 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -168,8 +168,7 @@ static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 		ecmd->duplex = -1;
 	}
 
-	ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
-			 hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+	ecmd->autoneg = hw->mac.autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 	return 0;
 }
 
@@ -191,23 +190,20 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		hw->mac.autoneg = 1;
-		if (hw->phy.media_type == e1000_media_type_fiber)
-			hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full |
-						     ADVERTISED_FIBRE |
-						     ADVERTISED_Autoneg;
-		else
-			hw->phy.autoneg_advertised = ecmd->advertising |
-						     ADVERTISED_TP |
-						     ADVERTISED_Autoneg;
+		hw->phy.autoneg_advertised = ecmd->advertising |
+					     ADVERTISED_TP |
+					     ADVERTISED_Autoneg;
 		ecmd->advertising = hw->phy.autoneg_advertised;
-	} else
+		if (adapter->fc_autoneg)
+			hw->fc.requested_mode = e1000_fc_default;
+	} else {
 		if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
 			clear_bit(__IGB_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
+	}
 
 	/* reset the link */
-
 	if (netif_running(adapter->netdev)) {
 		igb_down(adapter);
 		igb_up(adapter);
@@ -227,11 +223,11 @@ static void igb_get_pauseparam(struct net_device *netdev,
 	pause->autoneg =
 		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
 
-	if (hw->fc.type == e1000_fc_rx_pause)
+	if (hw->fc.current_mode == e1000_fc_rx_pause)
 		pause->rx_pause = 1;
-	else if (hw->fc.type == e1000_fc_tx_pause)
+	else if (hw->fc.current_mode == e1000_fc_tx_pause)
 		pause->tx_pause = 1;
-	else if (hw->fc.type == e1000_fc_full) {
+	else if (hw->fc.current_mode == e1000_fc_full) {
 		pause->rx_pause = 1;
 		pause->tx_pause = 1;
 	}
@@ -249,26 +245,28 @@ static int igb_set_pauseparam(struct net_device *netdev,
 	while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
 		msleep(1);
 
-	if (pause->rx_pause && pause->tx_pause)
-		hw->fc.type = e1000_fc_full;
-	else if (pause->rx_pause && !pause->tx_pause)
-		hw->fc.type = e1000_fc_rx_pause;
-	else if (!pause->rx_pause && pause->tx_pause)
-		hw->fc.type = e1000_fc_tx_pause;
-	else if (!pause->rx_pause && !pause->tx_pause)
-		hw->fc.type = e1000_fc_none;
-
-	hw->fc.original_type = hw->fc.type;
-
 	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
+		hw->fc.requested_mode = e1000_fc_default;
 		if (netif_running(adapter->netdev)) {
 			igb_down(adapter);
 			igb_up(adapter);
 		} else
 			igb_reset(adapter);
-	} else
-		retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
-			  igb_setup_link(hw) : igb_force_mac_fc(hw));
+	} else {
+		if (pause->rx_pause && pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_full;
+		else if (pause->rx_pause && !pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_rx_pause;
+		else if (!pause->rx_pause && pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_tx_pause;
+		else if (!pause->rx_pause && !pause->tx_pause)
+			hw->fc.requested_mode = e1000_fc_none;
+
+		hw->fc.current_mode = hw->fc.requested_mode;
+
+		retval = ((hw->phy.media_type == e1000_media_type_copper) ?
+			  igb_force_mac_fc(hw) : igb_setup_link(hw));
+	}
 
 	clear_bit(__IGB_RESETTING, &adapter->state);
 	return retval;
@@ -1483,8 +1481,7 @@ static int igb_setup_loopback_test(struct igb_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	u32 reg;
 
-	if (hw->phy.media_type == e1000_media_type_fiber ||
-	    hw->phy.media_type == e1000_media_type_internal_serdes) {
+	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
 		reg = rd32(E1000_RCTL);
 		reg |= E1000_RCTL_LBM_TCVR;
 		wr32(E1000_RCTL, reg);
@@ -1843,7 +1840,6 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
 
 	if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
 		return -EOPNOTSUPP;
@@ -1852,11 +1848,6 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 	    !device_can_wakeup(&adapter->pdev->dev))
 		return wol->wolopts ? -EOPNOTSUPP : 0;
 
-	switch (hw->device_id) {
-	default:
-		break;
-	}
-
 	/* these settings will always override what we currently have */
 	adapter->wol = 0;
 
@@ -2025,7 +2016,7 @@ static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 	}
 }
 
-static struct ethtool_ops igb_ethtool_ops = {
+static const struct ethtool_ops igb_ethtool_ops = {
 	.get_settings           = igb_get_settings,
 	.set_settings           = igb_set_settings,
 	.get_drvinfo            = igb_get_drvinfo,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index adb09d3..d2639c4 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -65,6 +65,7 @@ static struct pci_device_id igb_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
@@ -93,13 +94,15 @@ static void igb_clean_all_tx_rings(struct igb_adapter *);
 static void igb_clean_all_rx_rings(struct igb_adapter *);
 static void igb_clean_tx_ring(struct igb_ring *);
 static void igb_clean_rx_ring(struct igb_ring *);
-static void igb_set_multi(struct net_device *);
+static void igb_set_rx_mode(struct net_device *);
 static void igb_update_phy_info(unsigned long);
 static void igb_watchdog(unsigned long);
 static void igb_watchdog_task(struct work_struct *);
-static int igb_xmit_frame_ring_adv(struct sk_buff *, struct net_device *,
-				  struct igb_ring *);
-static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *);
+static netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *,
+					   struct net_device *,
+					   struct igb_ring *);
+static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb,
+				      struct net_device *);
 static struct net_device_stats *igb_get_stats(struct net_device *);
 static int igb_change_mtu(struct net_device *, int);
 static int igb_set_mac(struct net_device *, void *);
@@ -127,7 +130,7 @@ static void igb_restore_vlan(struct igb_adapter *);
 static void igb_ping_all_vfs(struct igb_adapter *);
 static void igb_msg_task(struct igb_adapter *);
 static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
-static void igb_set_mc_list_pools(struct igb_adapter *, int, u16);
+static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
 static void igb_vmm_control(struct igb_adapter *);
 static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
 static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
@@ -151,6 +154,12 @@ static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
 	struct e1000_hw *hw = &adapter->hw;
 	u32 vmolr;
 
+	/* if it isn't the PF check to see if VFs are enabled and
+	 * increase the size to support vlan tags */
+	if (vfn < adapter->vfs_allocated_count &&
+	    adapter->vf_data[vfn].vlans_enabled)
+		size += VLAN_TAG_SIZE;
+
 	vmolr = rd32(E1000_VMOLR(vfn));
 	vmolr &= ~E1000_VMOLR_RLPML_MASK;
 	vmolr |= size | E1000_VMOLR_LPE;
@@ -818,9 +827,11 @@ static void igb_irq_disable(struct igb_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 
 	if (adapter->msix_entries) {
-		wr32(E1000_EIAM, 0);
-		wr32(E1000_EIMC, ~0);
-		wr32(E1000_EIAC, 0);
+		u32 regval = rd32(E1000_EIAM);
+		wr32(E1000_EIAM, regval & ~adapter->eims_enable_mask);
+		wr32(E1000_EIMC, adapter->eims_enable_mask);
+		regval = rd32(E1000_EIAC);
+		wr32(E1000_EIAC, regval & ~adapter->eims_enable_mask);
 	}
 
 	wr32(E1000_IAM, 0);
@@ -838,8 +849,10 @@ static void igb_irq_enable(struct igb_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 
 	if (adapter->msix_entries) {
-		wr32(E1000_EIAC, adapter->eims_enable_mask);
-		wr32(E1000_EIAM, adapter->eims_enable_mask);
+		u32 regval = rd32(E1000_EIAC);
+		wr32(E1000_EIAC, regval | adapter->eims_enable_mask);
+		regval = rd32(E1000_EIAM);
+		wr32(E1000_EIAM, regval | adapter->eims_enable_mask);
 		wr32(E1000_EIMS, adapter->eims_enable_mask);
 		if (adapter->vfs_allocated_count)
 			wr32(E1000_MBVFIMR, 0xFF);
@@ -925,7 +938,7 @@ static void igb_configure(struct igb_adapter *adapter)
 	int i;
 
 	igb_get_hw_control(adapter);
-	igb_set_multi(netdev);
+	igb_set_rx_mode(netdev);
 
 	igb_restore_vlan(adapter);
 
@@ -1129,7 +1142,7 @@ void igb_reset(struct igb_adapter *adapter)
 	}
 	fc->pause_time = 0xFFFF;
 	fc->send_xon = 1;
-	fc->type = fc->original_type;
+	fc->current_mode = fc->requested_mode;
 
 	/* disable receive for all VFs and wait one second */
 	if (adapter->vfs_allocated_count) {
@@ -1166,7 +1179,8 @@ static const struct net_device_ops igb_netdev_ops = {
 	.ndo_stop		= igb_close,
 	.ndo_start_xmit		= igb_xmit_frame_adv,
 	.ndo_get_stats		= igb_get_stats,
-	.ndo_set_multicast_list	= igb_set_multi,
+	.ndo_set_rx_mode	= igb_set_rx_mode,
+	.ndo_set_multicast_list	= igb_set_rx_mode,
 	.ndo_set_mac_address	= igb_set_mac,
 	.ndo_change_mtu		= igb_change_mtu,
 	.ndo_do_ioctl		= igb_ioctl,
@@ -1379,6 +1393,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
 	netdev->vlan_features |= NETIF_F_IP_CSUM;
+	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
 	if (pci_using_dac)
@@ -1426,8 +1441,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 	hw->mac.autoneg = true;
 	hw->phy.autoneg_advertised = 0x2f;
 
-	hw->fc.original_type = e1000_fc_default;
-	hw->fc.type = e1000_fc_default;
+	hw->fc.requested_mode = e1000_fc_default;
+	hw->fc.current_mode = e1000_fc_default;
 
 	adapter->itr_setting = IGB_DEFAULT_ITR;
 	adapter->itr = IGB_START_ITR;
@@ -2515,75 +2530,94 @@ static int igb_set_mac(struct net_device *netdev, void *p)
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
 	memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
 
-	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
-
+	igb_rar_set(hw, hw->mac.addr, 0);
 	igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
 
 	return 0;
 }
 
 /**
- * igb_set_multi - Multicast and Promiscuous mode set
+ * igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
  * @netdev: network interface device structure
  *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated.  This routine is
- * responsible for configuring the hardware for proper multicast,
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated.  This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
  * promiscuous mode, and all-multi behavior.
  **/
-static void igb_set_multi(struct net_device *netdev)
+static void igb_set_rx_mode(struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	struct e1000_mac_info *mac = &hw->mac;
-	struct dev_mc_list *mc_ptr;
+	unsigned int rar_entries = hw->mac.rar_entry_count -
+	                           (adapter->vfs_allocated_count + 1);
+	struct dev_mc_list *mc_ptr = netdev->mc_list;
 	u8  *mta_list = NULL;
 	u32 rctl;
 	int i;
 
 	/* Check for Promiscuous and All Multicast modes */
-
 	rctl = rd32(E1000_RCTL);
 
 	if (netdev->flags & IFF_PROMISC) {
 		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 		rctl &= ~E1000_RCTL_VFE;
 	} else {
-		if (netdev->flags & IFF_ALLMULTI) {
+		if (netdev->flags & IFF_ALLMULTI)
 			rctl |= E1000_RCTL_MPE;
+		else
+			rctl &= ~E1000_RCTL_MPE;
+
+		if (netdev->uc.count > rar_entries)
+			rctl |= E1000_RCTL_UPE;
+		else
 			rctl &= ~E1000_RCTL_UPE;
-		} else
-			rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
 		rctl |= E1000_RCTL_VFE;
 	}
 	wr32(E1000_RCTL, rctl);
 
-	if (netdev->mc_count) {
-		mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
-		if (!mta_list) {
-			dev_err(&adapter->pdev->dev,
-			        "failed to allocate multicast filter list\n");
-			return;
+	if (netdev->uc.count && rar_entries) {
+		struct netdev_hw_addr *ha;
+		list_for_each_entry(ha, &netdev->uc.list, list) {
+			if (!rar_entries)
+				break;
+			igb_rar_set(hw, ha->addr, rar_entries);
+			igb_set_rah_pool(hw, adapter->vfs_allocated_count,
+			                 rar_entries);
+			rar_entries--;
 		}
 	}
+	/* write the addresses in reverse order to avoid write combining */
+	for (; rar_entries > 0 ; rar_entries--) {
+		wr32(E1000_RAH(rar_entries), 0);
+		wr32(E1000_RAL(rar_entries), 0);
+	}
+	wrfl();
 
-	/* The shared function expects a packed array of only addresses. */
-	mc_ptr = netdev->mc_list;
+	if (!netdev->mc_count) {
+		/* nothing to program, so clear mc list */
+		igb_update_mc_addr_list(hw, NULL, 0);
+		igb_restore_vf_multicasts(adapter);
+		return;
+	}
+
+	mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+	if (!mta_list) {
+		dev_err(&adapter->pdev->dev,
+		        "failed to allocate multicast filter list\n");
+		return;
+	}
 
+	/* The shared function expects a packed array of only addresses. */
 	for (i = 0; i < netdev->mc_count; i++) {
 		if (!mc_ptr)
 			break;
 		memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
 		mc_ptr = mc_ptr->next;
 	}
-	igb_update_mc_addr_list(hw, mta_list, i,
-	                        adapter->vfs_allocated_count + 1,
-	                        mac->rar_entry_count);
-
-	igb_set_mc_list_pools(adapter, i, mac->rar_entry_count);
-	igb_restore_vf_multicasts(adapter);
-
+	igb_update_mc_addr_list(hw, mta_list, i);
 	kfree(mta_list);
+	igb_restore_vf_multicasts(adapter);
 }
 
 /* Need to wait a few seconds after link up to get diagnostic information from
@@ -2618,10 +2652,6 @@ static bool igb_has_link(struct igb_adapter *adapter)
 			link_active = true;
 		}
 		break;
-	case e1000_media_type_fiber:
-		ret_val = hw->mac.ops.check_for_link(hw);
-		link_active = !!(rd32(E1000_STATUS) & E1000_STATUS_LU);
-		break;
 	case e1000_media_type_internal_serdes:
 		ret_val = hw->mac.ops.check_for_link(hw);
 		link_active = hw->mac.serdes_has_link;
@@ -3298,9 +3328,9 @@ static int igb_maybe_stop_tx(struct net_device *netdev,
 	return __igb_maybe_stop_tx(netdev, tx_ring, size);
 }
 
-static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
-				   struct net_device *netdev,
-				   struct igb_ring *tx_ring)
+static netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
+					   struct net_device *netdev,
+					   struct igb_ring *tx_ring)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	unsigned int first;
@@ -3388,7 +3418,8 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
-static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb,
+				      struct net_device *netdev)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct igb_ring *tx_ring;
@@ -3401,7 +3432,7 @@ static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
 	 * to a flow.  Right now, performance is impacted slightly negatively
 	 * if using multiple tx queues.  If the stack breaks away from a
 	 * single qdisc implementation, we can look at this again. */
-	return (igb_xmit_frame_ring_adv(skb, netdev, tx_ring));
+	return igb_xmit_frame_ring_adv(skb, netdev, tx_ring);
 }
 
 /**
@@ -3938,7 +3969,7 @@ static int igb_set_vf_multicasts(struct igb_adapter *adapter,
 		vf_data->vf_mc_hashes[i] = hash_list[i];;
 
 	/* Flush and reset the mta with the new values */
-	igb_set_multi(adapter->netdev);
+	igb_set_rx_mode(adapter->netdev);
 
 	return 0;
 }
@@ -3981,6 +4012,8 @@ static void igb_clear_vf_vfta(struct igb_adapter *adapter, u32 vf)
 
 		wr32(E1000_VLVF(i), reg);
 	}
+
+	adapter->vf_data[vf].vlans_enabled = 0;
 }
 
 static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
@@ -4029,6 +4062,22 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
 			reg |= vid;
 
 			wr32(E1000_VLVF(i), reg);
+
+			/* do not modify RLPML for PF devices */
+			if (vf >= adapter->vfs_allocated_count)
+				return 0;
+
+			if (!adapter->vf_data[vf].vlans_enabled) {
+				u32 size;
+				reg = rd32(E1000_VMOLR(vf));
+				size = reg & E1000_VMOLR_RLPML_MASK;
+				size += 4;
+				reg &= ~E1000_VMOLR_RLPML_MASK;
+				reg |= size;
+				wr32(E1000_VMOLR(vf), reg);
+			}
+			adapter->vf_data[vf].vlans_enabled++;
+
 			return 0;
 		}
 	} else {
@@ -4041,6 +4090,21 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
 				igb_vfta_set(hw, vid, false);
 			}
 			wr32(E1000_VLVF(i), reg);
+
+			/* do not modify RLPML for PF devices */
+			if (vf >= adapter->vfs_allocated_count)
+				return 0;
+
+			adapter->vf_data[vf].vlans_enabled--;
+			if (!adapter->vf_data[vf].vlans_enabled) {
+				u32 size;
+				reg = rd32(E1000_VMOLR(vf));
+				size = reg & E1000_VMOLR_RLPML_MASK;
+				size -= 4;
+				reg &= ~E1000_VMOLR_RLPML_MASK;
+				reg |= size;
+				wr32(E1000_VMOLR(vf), reg);
+			}
 			return 0;
 		}
 	}
@@ -4072,13 +4136,14 @@ static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
 	adapter->vf_data[vf].num_vf_mc_hashes = 0;
 
 	/* Flush and reset the mta with the new values */
-	igb_set_multi(adapter->netdev);
+	igb_set_rx_mode(adapter->netdev);
 }
 
 static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
+	int rar_entry = hw->mac.rar_entry_count - (vf + 1);
 	u32 reg, msgbuf[3];
 	u8 *addr = (u8 *)(&msgbuf[1]);
 
@@ -4086,8 +4151,8 @@ static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
 	igb_vf_reset_event(adapter, vf);
 
 	/* set vf mac address */
-	igb_rar_set(hw, vf_mac, vf + 1);
-	igb_set_rah_pool(hw, vf, vf + 1);
+	igb_rar_set(hw, vf_mac, rar_entry);
+	igb_set_rah_pool(hw, vf, rar_entry);
 
 	/* enable transmit and receive for vf */
 	reg = rd32(E1000_VFTE);
@@ -4542,6 +4607,20 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
 	adapter->hw_csum_good++;
 }
 
+static inline u16 igb_get_hlen(struct igb_adapter *adapter,
+                               union e1000_adv_rx_desc *rx_desc)
+{
+	/* HW will not DMA in data larger than the given buffer, even if it
+	 * parses the (NFS, of course) header to be larger.  In that case, it
+	 * fills the header buffer and spills the rest into the page.
+	 */
+	u16 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
+	           E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
+	if (hlen > adapter->rx_ps_hdr_size)
+		hlen = adapter->rx_ps_hdr_size;
+	return hlen;
+}
+
 static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
 				 int *work_done, int budget)
 {
@@ -4556,7 +4635,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
 	int cleaned_count = 0;
 	unsigned int total_bytes = 0, total_packets = 0;
 	unsigned int i;
-	u32 length, hlen, staterr;
+	u32 staterr;
+	u16 length;
 
 	i = rx_ring->next_to_clean;
 	buffer_info = &rx_ring->buffer_info[i];
@@ -4593,17 +4673,8 @@ static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
 			goto send_up;
 		}
 
-		/* HW will not DMA in data larger than the given buffer, even
-		 * if it parses the (NFS, of course) header to be larger.  In
-		 * that case, it fills the header buffer and spills the rest
-		 * into the page.
-		 */
-		hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
-		  E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
-		if (hlen > adapter->rx_ps_hdr_size)
-			hlen = adapter->rx_ps_hdr_size;
-
-		if (!skb_shinfo(skb)->nr_frags) {
+		if (buffer_info->dma) {
+			u16 hlen = igb_get_hlen(adapter, rx_desc);
 			pci_unmap_single(pdev, buffer_info->dma,
 					 adapter->rx_ps_hdr_size,
 					 PCI_DMA_FROMDEVICE);
@@ -4843,8 +4914,6 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 		data->phy_id = adapter->hw.phy.addr;
 		break;
 	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
 		                     &data->val_out))
 			return -EIO;
@@ -5033,6 +5102,34 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 	}
 }
 
+s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+	struct igb_adapter *adapter = hw->back;
+	u16 cap_offset;
+
+	cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+	if (!cap_offset)
+		return -E1000_ERR_CONFIG;
+
+	pci_read_config_word(adapter->pdev, cap_offset + reg, value);
+
+	return 0;
+}
+
+s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+	struct igb_adapter *adapter = hw->back;
+	u16 cap_offset;
+
+	cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+	if (!cap_offset)
+		return -E1000_ERR_CONFIG;
+
+	pci_write_config_word(adapter->pdev, cap_offset + reg, *value);
+
+	return 0;
+}
+
 static void igb_vlan_rx_register(struct net_device *netdev,
 				 struct vlan_group *grp)
 {
@@ -5136,14 +5233,6 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
 
 	mac->autoneg = 0;
 
-	/* Fiber NICs only allow 1000 gbps Full duplex */
-	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		dev_err(&adapter->pdev->dev,
-			"Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
-	}
-
 	switch (spddplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		mac->forced_speed_duplex = ADVERTISE_10_HALF;
@@ -5202,7 +5291,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
 
 	if (wufc) {
 		igb_setup_rctl(adapter);
-		igb_set_multi(netdev);
+		igb_set_rx_mode(netdev);
 
 		/* turn on all-multi mode if wake on multicast is enabled */
 		if (wufc & E1000_WUFC_MC) {
@@ -5231,7 +5320,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
 
 	*enable_wake = wufc || adapter->en_mng_pt;
 	if (!*enable_wake)
-		igb_shutdown_fiber_serdes_link_82575(hw);
+		igb_shutdown_serdes_link_82575(hw);
 
 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant. */
@@ -5452,29 +5541,17 @@ static void igb_io_resume(struct pci_dev *pdev)
 	igb_get_hw_control(adapter);
 }
 
-static void igb_set_mc_list_pools(struct igb_adapter *adapter,
-				  int entry_count, u16 total_rar_filters)
-{
-	struct e1000_hw *hw = &adapter->hw;
-	int i = adapter->vfs_allocated_count + 1;
-
-	if ((i + entry_count) < total_rar_filters)
-		total_rar_filters = i + entry_count;
-
-	for (; i < total_rar_filters; i++)
-		igb_set_rah_pool(hw, adapter->vfs_allocated_count, i);
-}
-
 static int igb_set_vf_mac(struct igb_adapter *adapter,
                           int vf, unsigned char *mac_addr)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	int rar_entry = vf + 1; /* VF MAC addresses start at entry 1 */
-
-	igb_rar_set(hw, mac_addr, rar_entry);
+	/* VF MAC addresses start at end of receive addresses and moves
+	 * torwards the first, as a result a collision should not be possible */
+	int rar_entry = hw->mac.rar_entry_count - (vf + 1);
 
 	memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
 
+	igb_rar_set(hw, mac_addr, rar_entry);
 	igb_set_rah_pool(hw, vf, rar_entry);
 
 	return 0;
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 2bc9d63..91024a3 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -96,8 +96,6 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter,
 		                         E1000_RXD_SPC_VLAN_MASK);
 	else
 		netif_receive_skb(skb);
-
-	netdev->last_rx = jiffies;
 }
 
 static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
@@ -149,7 +147,6 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
 		bufsz = adapter->rx_ps_hdr_size;
 	else
 		bufsz = adapter->rx_buffer_len;
-	bufsz += NET_IP_ALIGN;
 
 	while (cleaned_count--) {
 		rx_desc = IGBVF_RX_DESC_ADV(*rx_ring, i);
@@ -173,7 +170,7 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
 		}
 
 		if (!buffer_info->skb) {
-			skb = netdev_alloc_skb(netdev, bufsz);
+			skb = netdev_alloc_skb(netdev, bufsz + NET_IP_ALIGN);
 			if (!skb) {
 				adapter->alloc_rx_buff_failed++;
 				goto no_buffers;
@@ -286,7 +283,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
 
 		if (!skb_shinfo(skb)->nr_frags) {
 			pci_unmap_single(pdev, buffer_info->dma,
-			                 adapter->rx_ps_hdr_size + NET_IP_ALIGN,
+			                 adapter->rx_ps_hdr_size,
 			                 PCI_DMA_FROMDEVICE);
 			skb_put(skb, hlen);
 		}
@@ -343,8 +340,6 @@ send_up:
 		igbvf_receive_skb(adapter, netdev, skb, staterr,
 		                  rx_desc->wb.upper.vlan);
 
-		netdev->last_rx = jiffies;
-
 next_desc:
 		rx_desc->wb.upper.status_error = 0;
 
@@ -2205,9 +2200,9 @@ static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
 	mmiowb();
 }
 
-static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
-                                   struct net_device *netdev,
-                                   struct igbvf_ring *tx_ring)
+static netdev_tx_t igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
+					     struct net_device *netdev,
+					     struct igbvf_ring *tx_ring)
 {
 	struct igbvf_adapter *adapter = netdev_priv(netdev);
 	unsigned int first, tx_flags = 0;
@@ -2280,11 +2275,11 @@ static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
 	return NETDEV_TX_OK;
 }
 
-static int igbvf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t igbvf_xmit_frame(struct sk_buff *skb,
+				    struct net_device *netdev)
 {
 	struct igbvf_adapter *adapter = netdev_priv(netdev);
 	struct igbvf_ring *tx_ring;
-	int retval;
 
 	if (test_bit(__IGBVF_DOWN, &adapter->state)) {
 		dev_kfree_skb_any(skb);
@@ -2293,9 +2288,7 @@ static int igbvf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 	tx_ring = &adapter->tx_ring[0];
 
-	retval = igbvf_xmit_frame_ring_adv(skb, netdev, tx_ring);
-
-	return retval;
+	return igbvf_xmit_frame_ring_adv(skb, netdev, tx_ring);
 }
 
 /**
@@ -2512,6 +2505,9 @@ static pci_ers_result_t igbvf_io_error_detected(struct pci_dev *pdev,
 
 	netif_device_detach(netdev);
 
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	if (netif_running(netdev))
 		igbvf_down(adapter);
 	pci_disable_device(pdev);
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index e3cfefa..8ec15ab 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -1515,7 +1515,7 @@ static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irq(&ip->ioc3_lock);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void ioc3_timeout(struct net_device *dev)
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 4301946..9f7b5d4 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -1858,7 +1858,8 @@ static int ipg_nic_stop(struct net_device *dev)
 	return 0;
 }
 
-static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ipg_nic_hard_start_xmit(struct sk_buff *skb,
+					   struct net_device *dev)
 {
 	struct ipg_nic_private *sp = netdev_priv(dev);
 	void __iomem *ioaddr = sp->ioaddr;
@@ -2185,7 +2186,7 @@ static int ipg_nway_reset(struct net_device *dev)
 	return rc;
 }
 
-static struct ethtool_ops ipg_ethtool_ops = {
+static const struct ethtool_ops ipg_ethtool_ops = {
 	.get_settings = ipg_get_settings,
 	.set_settings = ipg_set_settings,
 	.nway_reset   = ipg_nway_reset,
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index ad17955..12c7b00 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -111,7 +111,8 @@ static int  ali_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd
 static void ali_ircc_change_speed(struct ali_ircc_cb *self, __u32 baud);
 
 /* SIR function */
-static int  ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ali_ircc_sir_hard_xmit(struct sk_buff *skb,
+						struct net_device *dev);
 static irqreturn_t ali_ircc_sir_interrupt(struct ali_ircc_cb *self);
 static void ali_ircc_sir_receive(struct ali_ircc_cb *self);
 static void ali_ircc_sir_write_wakeup(struct ali_ircc_cb *self);
@@ -119,7 +120,8 @@ static int  ali_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len);
 static void ali_ircc_sir_change_speed(struct ali_ircc_cb *priv, __u32 speed);
 
 /* FIR function */
-static int  ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t  ali_ircc_fir_hard_xmit(struct sk_buff *skb,
+						 struct net_device *dev);
 static void ali_ircc_fir_change_speed(struct ali_ircc_cb *priv, __u32 speed);
 static irqreturn_t ali_ircc_fir_interrupt(struct ali_ircc_cb *self);
 static int  ali_ircc_dma_receive(struct ali_ircc_cb *self); 
@@ -1435,7 +1437,8 @@ static int ali_ircc_net_close(struct net_device *dev)
  *    Transmit the frame
  *
  */
-static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ali_ircc_fir_hard_xmit(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	struct ali_ircc_cb *self;
 	unsigned long flags;
@@ -1466,7 +1469,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 			dev->trans_start = jiffies;
 			spin_unlock_irqrestore(&self->lock, flags);
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else
 			self->new_speed = speed;
 	}
@@ -1577,7 +1580,7 @@ static int ali_ircc_fir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb(skb);
 
 	IRDA_DEBUG(1, "%s(), ----------------- End ------------------\n", __func__ );
-	return 0;	
+	return NETDEV_TX_OK;	
 }
 
 
@@ -1957,7 +1960,8 @@ static int  ali_ircc_dma_receive_complete(struct ali_ircc_cb *self)
  *    Transmit the frame!
  *
  */
-static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ali_ircc_sir_hard_xmit(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	struct ali_ircc_cb *self;
 	unsigned long flags;
@@ -1966,10 +1970,10 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 	
 	IRDA_DEBUG(2, "%s(), ---------------- Start ----------------\n", __func__ );
 	
-	IRDA_ASSERT(dev != NULL, return 0;);
+	IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;);
 	
 	self = netdev_priv(dev);
-	IRDA_ASSERT(self != NULL, return 0;);
+	IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;);
 
 	iobase = self->io.sir_base;
 
@@ -1991,7 +1995,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 			dev->trans_start = jiffies;
 			spin_unlock_irqrestore(&self->lock, flags);
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else
 			self->new_speed = speed;
 	}
@@ -2015,7 +2019,7 @@ static int ali_ircc_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 	
 	IRDA_DEBUG(2, "%s(), ----------------- End ------------------\n", __func__ );
 	
-	return 0;	
+	return NETDEV_TX_OK;	
 }
 
 
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index ee1cff5..eb42468 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -498,7 +498,7 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 			aup->newspeed = 0;
 		}
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	ptxd = aup->tx_ring[aup->tx_head];
@@ -551,7 +551,7 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb(skb);
 	aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1);
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 9a0346e..2d7b5c1 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -970,7 +970,7 @@ toshoboe_probe (struct toshoboe_cb *self)
 /* Netdev style code */
 
 /* Transmit something */
-static int
+static netdev_tx_t
 toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
 {
   struct toshoboe_cb *self;
@@ -981,7 +981,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
 
   self = netdev_priv(dev);
 
-  IRDA_ASSERT (self != NULL, return 0; );
+  IRDA_ASSERT (self != NULL, return NETDEV_TX_OK; );
 
   IRDA_DEBUG (1, "%s.tx:%x(%x)%x\n", __func__
       ,skb->len,self->txpending,INB (OBOE_ENABLEH));
@@ -1021,7 +1021,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
             {
 	      spin_unlock_irqrestore(&self->spinlock, flags);
               dev_kfree_skb (skb);
-              return 0;
+              return NETDEV_TX_OK;
             }
           /* True packet, go on, but */
           /* do not accept anything before change speed execution */
@@ -1036,7 +1036,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
           toshoboe_setbaud (self);
 	  spin_unlock_irqrestore(&self->spinlock, flags);
           dev_kfree_skb (skb);
-          return 0;
+          return NETDEV_TX_OK;
         }
 
     }
@@ -1143,7 +1143,7 @@ dumpbufs(skb->data,skb->len,'>');
   spin_unlock_irqrestore(&self->spinlock, flags);
   dev_kfree_skb (skb);
 
-  return 0;
+  return NETDEV_TX_OK;
 }
 
 /*interrupt handler */
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 0c0831c..215adf6 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -111,7 +111,8 @@ static void irda_usb_init_qos(struct irda_usb_cb *self) ;
 static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf);
 static void irda_usb_disconnect(struct usb_interface *intf);
 static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
-static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb,
+					    struct net_device *dev);
 static int irda_usb_open(struct irda_usb_cb *self);
 static void irda_usb_close(struct irda_usb_cb *self);
 static void speed_bulk_callback(struct urb *urb);
@@ -381,7 +382,8 @@ static void speed_bulk_callback(struct urb *urb)
 /*
  * Send an IrDA frame to the USB dongle (for transmission)
  */
-static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb,
+					    struct net_device *netdev)
 {
 	struct irda_usb_cb *self = netdev_priv(netdev);
 	struct urb *urb = self->tx_urb;
@@ -534,7 +536,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
 	}
 	spin_unlock_irqrestore(&self->lock, flags);
 	
-	return 0;
+	return NETDEV_TX_OK;
 
 drop:
 	/* Drop silently the skb and exit */
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index c3e4e2c..2fc30b4 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -150,7 +150,8 @@ static void kingsun_send_irq(struct urb *urb)
 /*
  * Called from net/core when new frame is available.
  */
-static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t kingsun_hard_xmit(struct sk_buff *skb,
+					   struct net_device *netdev)
 {
 	struct kingsun_cb *kingsun;
 	int wraplen;
@@ -416,7 +417,7 @@ static int kingsun_net_ioctl(struct net_device *netdev, struct ifreq *rq,
 }
 
 static const struct net_device_ops kingsun_ops = {
-	.ndo_start_xmit = kingsun_hard_xmit,
+	.ndo_start_xmit	     = kingsun_hard_xmit,
 	.ndo_open            = kingsun_net_open,
 	.ndo_stop            = kingsun_net_close,
 	.ndo_do_ioctl        = kingsun_net_ioctl,
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index d73b8b6..f4d13fc 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -385,7 +385,8 @@ static void ks959_send_irq(struct urb *urb)
 /*
  * Called from net/core when new frame is available.
  */
-static int ks959_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t ks959_hard_xmit(struct sk_buff *skb,
+					 struct net_device *netdev)
 {
 	struct ks959_cb *kingsun;
 	unsigned int wraplen;
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c
index 1ef45ec..5f9d733 100644
--- a/drivers/net/irda/ksdazzle-sir.c
+++ b/drivers/net/irda/ksdazzle-sir.c
@@ -298,7 +298,8 @@ static void ksdazzle_send_irq(struct urb *urb)
 /*
  * Called from net/core when new frame is available.
  */
-static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t ksdazzle_hard_xmit(struct sk_buff *skb,
+					    struct net_device *netdev)
 {
 	struct ksdazzle_cb *kingsun;
 	unsigned int wraplen;
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index f4df100..b3d30bc 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -817,7 +817,8 @@ static void mcs_send_irq(struct urb *urb)
 }
 
 /* Transmit callback funtion.  */
-static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t mcs_hard_xmit(struct sk_buff *skb,
+				       struct net_device *ndev)
 {
 	unsigned long flags;
 	struct mcs_cb *mcs;
diff --git a/drivers/net/irda/mcs7780.h b/drivers/net/irda/mcs7780.h
index 6bdc621..b10689b 100644
--- a/drivers/net/irda/mcs7780.h
+++ b/drivers/net/irda/mcs7780.h
@@ -156,7 +156,8 @@ static int mcs_net_open(struct net_device *netdev);
 
 static void mcs_receive_irq(struct urb *urb);
 static void mcs_send_irq(struct urb *urb);
-static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *netdev);
+static netdev_tx_t mcs_hard_xmit(struct sk_buff *skb,
+				       struct net_device *netdev);
 
 static int mcs_probe(struct usb_interface *intf,
 		     const struct usb_device_id *id);
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 45fd9c1..2413295 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -173,8 +173,10 @@ static int  nsc_ircc_setup(chipio_t *info);
 static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self);
 static int  nsc_ircc_dma_receive(struct nsc_ircc_cb *self); 
 static int  nsc_ircc_dma_receive_complete(struct nsc_ircc_cb *self, int iobase);
-static int  nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev);
-static int  nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t  nsc_ircc_hard_xmit_sir(struct sk_buff *skb,
+						 struct net_device *dev);
+static netdev_tx_t  nsc_ircc_hard_xmit_fir(struct sk_buff *skb,
+						 struct net_device *dev);
 static int  nsc_ircc_pio_write(int iobase, __u8 *buf, int len, int fifo_size);
 static void nsc_ircc_dma_xmit(struct nsc_ircc_cb *self, int iobase);
 static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 baud);
@@ -1355,7 +1357,8 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed)
  *    Transmit the frame!
  *
  */
-static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nsc_ircc_hard_xmit_sir(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	struct nsc_ircc_cb *self;
 	unsigned long flags;
@@ -1365,7 +1368,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
 	
 	self = netdev_priv(dev);
 
-	IRDA_ASSERT(self != NULL, return 0;);
+	IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;);
 
 	iobase = self->io.fir_base;
 
@@ -1397,7 +1400,7 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
 			dev->trans_start = jiffies;
 			spin_unlock_irqrestore(&self->lock, flags);
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else
 			self->new_speed = speed;
 	}
@@ -1424,10 +1427,11 @@ static int nsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
-static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nsc_ircc_hard_xmit_fir(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	struct nsc_ircc_cb *self;
 	unsigned long flags;
@@ -1467,7 +1471,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
 			dev->trans_start = jiffies;
 			spin_unlock_irqrestore(&self->lock, flags);
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else {
 			/* Change speed after current frame */
 			self->new_speed = speed;
@@ -1554,7 +1558,7 @@ static int nsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irqrestore(&self->lock, flags);
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 77d10ed..1445e58 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -504,7 +504,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 			pxa_irda_set_speed(si, speed);
 		}
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	netif_stop_queue(dev);
@@ -539,7 +539,7 @@ static int pxa_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int pxa_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index b039cb0..38bf7cf 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -666,7 +666,7 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 			sa1100_irda_set_speed(si, speed);
 		}
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (!IS_FIR(si)) {
@@ -714,7 +714,7 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index fd0796c..4b2a1a9 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -582,7 +582,8 @@ EXPORT_SYMBOL(sirdev_receive);
 
 /* callbacks from network layer */
 
-static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t sirdev_hard_xmit(struct sk_buff *skb,
+					  struct net_device *ndev)
 {
 	struct sir_dev *dev = netdev_priv(ndev);
 	unsigned long flags;
@@ -590,7 +591,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 	int err;
 	s32 speed;
 
-	IRDA_ASSERT(dev != NULL, return 0;);
+	IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;);
 
 	netif_stop_queue(ndev);
 
@@ -621,7 +622,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 			 */
 
 			dev_kfree_skb_any(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else
 			dev->new_speed = speed;
 	}
@@ -668,7 +669,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 	}
 	spin_unlock_irqrestore(&dev->tx_lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* called from network layer with rtnl hold */
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index d0797ad..1e8dd8c 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -194,8 +194,10 @@ static int __exit smsc_ircc_close(struct smsc_ircc_cb *self);
 static int  smsc_ircc_dma_receive(struct smsc_ircc_cb *self);
 static void smsc_ircc_dma_receive_complete(struct smsc_ircc_cb *self);
 static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self);
-static int  smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev);
-static int  smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t  smsc_ircc_hard_xmit_sir(struct sk_buff *skb,
+						  struct net_device *dev);
+static netdev_tx_t  smsc_ircc_hard_xmit_fir(struct sk_buff *skb,
+						  struct net_device *dev);
 static void smsc_ircc_dma_xmit(struct smsc_ircc_cb *self, int bofs);
 static void smsc_ircc_dma_xmit_complete(struct smsc_ircc_cb *self);
 static void smsc_ircc_change_speed(struct smsc_ircc_cb *self, u32 speed);
@@ -486,7 +488,8 @@ static int __init smsc_ircc_init(void)
 	return ret;
 }
 
-static int smsc_ircc_net_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t smsc_ircc_net_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	struct smsc_ircc_cb *self = netdev_priv(dev);
 
@@ -878,7 +881,8 @@ static void smsc_ircc_timeout(struct net_device *dev)
  *    waits until the next transmit interrupt, and continues until the
  *    frame is transmitted.
  */
-static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t smsc_ircc_hard_xmit_sir(struct sk_buff *skb,
+						 struct net_device *dev)
 {
 	struct smsc_ircc_cb *self;
 	unsigned long flags;
@@ -886,10 +890,10 @@ static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
 
 	IRDA_DEBUG(1, "%s\n", __func__);
 
-	IRDA_ASSERT(dev != NULL, return 0;);
+	IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;);
 
 	self = netdev_priv(dev);
-	IRDA_ASSERT(self != NULL, return 0;);
+	IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;);
 
 	netif_stop_queue(dev);
 
@@ -914,7 +918,7 @@ static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
 			smsc_ircc_change_speed(self, speed);
 			spin_unlock_irqrestore(&self->lock, flags);
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 		self->new_speed = speed;
 	}
@@ -935,7 +939,7 @@ static int smsc_ircc_hard_xmit_sir(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -1183,16 +1187,17 @@ static void smsc_ircc_set_sir_speed(struct smsc_ircc_cb *self, __u32 speed)
  *    Transmit the frame!
  *
  */
-static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t smsc_ircc_hard_xmit_fir(struct sk_buff *skb,
+						 struct net_device *dev)
 {
 	struct smsc_ircc_cb *self;
 	unsigned long flags;
 	s32 speed;
 	int mtt;
 
-	IRDA_ASSERT(dev != NULL, return 0;);
+	IRDA_ASSERT(dev != NULL, return NETDEV_TX_OK;);
 	self = netdev_priv(dev);
-	IRDA_ASSERT(self != NULL, return 0;);
+	IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;);
 
 	netif_stop_queue(dev);
 
@@ -1210,7 +1215,7 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
 			smsc_ircc_change_speed(self, speed);
 			spin_unlock_irqrestore(&self->lock, flags);
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 
 		self->new_speed = speed;
@@ -1242,7 +1247,7 @@ static int smsc_ircc_hard_xmit_fir(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irqrestore(&self->lock, flags);
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 8e5e45c..528767d 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -560,7 +560,8 @@ static int change_speed(struct stir_cb *stir, unsigned speed)
 /*
  * Called from net/core when new frame is available.
  */
-static int stir_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t stir_hard_xmit(struct sk_buff *skb,
+					struct net_device *netdev)
 {
 	struct stir_cb *stir = netdev_priv(netdev);
 
@@ -578,7 +579,7 @@ static int stir_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
 		dev_kfree_skb(skb);
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 8647985..a5ca71c 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -87,10 +87,10 @@ static int via_ircc_close(struct via_ircc_cb *self);
 static int via_ircc_dma_receive(struct via_ircc_cb *self);
 static int via_ircc_dma_receive_complete(struct via_ircc_cb *self,
 					 int iobase);
-static int via_ircc_hard_xmit_sir(struct sk_buff *skb,
-				  struct net_device *dev);
-static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
-				  struct net_device *dev);
+static netdev_tx_t via_ircc_hard_xmit_sir(struct sk_buff *skb,
+						struct net_device *dev);
+static netdev_tx_t via_ircc_hard_xmit_fir(struct sk_buff *skb,
+						struct net_device *dev);
 static void via_hw_init(struct via_ircc_cb *self);
 static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 baud);
 static irqreturn_t via_ircc_interrupt(int irq, void *dev_id);
@@ -823,8 +823,8 @@ static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 speed)
  *    Transmit the frame!
  *
  */
-static int via_ircc_hard_xmit_sir(struct sk_buff *skb,
-				  struct net_device *dev)
+static netdev_tx_t via_ircc_hard_xmit_sir(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	struct via_ircc_cb *self;
 	unsigned long flags;
@@ -832,7 +832,7 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb,
 	__u32 speed;
 
 	self = netdev_priv(dev);
-	IRDA_ASSERT(self != NULL, return 0;);
+	IRDA_ASSERT(self != NULL, return NETDEV_TX_OK;);
 	iobase = self->io.fir_base;
 
 	netif_stop_queue(dev);
@@ -844,7 +844,7 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb,
 			via_ircc_change_speed(self, speed);
 			dev->trans_start = jiffies;
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else
 			self->new_speed = speed;
 	}
@@ -892,11 +892,11 @@ static int via_ircc_hard_xmit_sir(struct sk_buff *skb,
 	dev->trans_start = jiffies;
 	spin_unlock_irqrestore(&self->lock, flags);
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
-static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
-				  struct net_device *dev)
+static netdev_tx_t via_ircc_hard_xmit_fir(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	struct via_ircc_cb *self;
 	u16 iobase;
@@ -907,7 +907,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
 	iobase = self->io.fir_base;
 
 	if (self->st_fifo.len)
-		return 0;
+		return NETDEV_TX_OK;
 	if (self->chip_id == 0x3076)
 		iodelay(1500);
 	else
@@ -919,7 +919,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
 			via_ircc_change_speed(self, speed);
 			dev->trans_start = jiffies;
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else
 			self->new_speed = speed;
 	}
@@ -940,7 +940,7 @@ static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
 	dev->trans_start = jiffies;
 	dev_kfree_skb(skb);
 	spin_unlock_irqrestore(&self->lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 
 }
 
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index ac0e4b6..7cfb8b6 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -854,7 +854,8 @@ static int vlsi_set_baud(vlsi_irda_dev_t *idev, unsigned iobase)
 	return ret;
 }
 
-static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t vlsi_hard_start_xmit(struct sk_buff *skb,
+					      struct net_device *ndev)
 {
 	vlsi_irda_dev_t *idev = netdev_priv(ndev);
 	struct vlsi_ring	*r = idev->tx_ring;
@@ -915,7 +916,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 			 */
 		spin_unlock_irqrestore(&idev->lock, flags);
 		dev_kfree_skb_any(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* sanity checks - simply drop the packet */
@@ -1044,7 +1045,7 @@ static int vlsi_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	}
 	spin_unlock_irqrestore(&idev->lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 
 drop_unlock:
 	spin_unlock_irqrestore(&idev->lock, flags);
@@ -1058,7 +1059,7 @@ drop:
 	 * packet for later retry of transmission - which isn't exactly
 	 * what we want after we've just called dev_kfree_skb_any ;-)
 	 */
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void vlsi_tx_interrupt(struct net_device *ndev)
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
index fe4f2b2..551810f 100644
--- a/drivers/net/irda/w83977af_ir.c
+++ b/drivers/net/irda/w83977af_ir.c
@@ -93,7 +93,8 @@ static int  w83977af_close(struct w83977af_ir *self);
 static int  w83977af_probe(int iobase, int irq, int dma);
 static int  w83977af_dma_receive(struct w83977af_ir *self); 
 static int  w83977af_dma_receive_complete(struct w83977af_ir *self);
-static int  w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t  w83977af_hard_xmit(struct sk_buff *skb,
+					     struct net_device *dev);
 static int  w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size);
 static void w83977af_dma_write(struct w83977af_ir *self, int iobase);
 static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed);
@@ -490,7 +491,8 @@ static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
  *    Sets up a DMA transfer to send the current frame.
  *
  */
-static int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	struct w83977af_ir *self;
 	__s32 speed;
@@ -516,7 +518,7 @@ static int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 			w83977af_change_speed(self, speed); 
 			dev->trans_start = jiffies;
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else
 			self->new_speed = speed;
 	}
@@ -576,7 +578,7 @@ static int w83977af_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Restore set register */
 	outb(set, iobase+SSR);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c
index d12377b..9706e64 100644
--- a/drivers/net/isa-skeleton.c
+++ b/drivers/net/isa-skeleton.c
@@ -468,7 +468,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb (skb);
 #endif
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 #if TX_RING
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index e44215c..e36e951 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -1205,7 +1205,7 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		if ( ! ((1 << rlp) & port->lpar_map) ) {
 			dev_kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 
 		lpmask = 1 << rlp;
@@ -1217,7 +1217,7 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* You must hold the connection's lock when you call this function. */
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 9c897cf..8aa44dc 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -81,7 +81,8 @@ static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter);
 static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter);
 static void ixgb_set_multi(struct net_device *netdev);
 static void ixgb_watchdog(unsigned long data);
-static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+static netdev_tx_t ixgb_xmit_frame(struct sk_buff *skb,
+				   struct net_device *netdev);
 static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);
 static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
 static int ixgb_set_mac(struct net_device *netdev, void *p);
@@ -1442,7 +1443,7 @@ static int ixgb_maybe_stop_tx(struct net_device *netdev,
 	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1 /* for context */ \
 	+ 1 /* one more needed for sentinel TSO workaround */
 
-static int
+static netdev_tx_t
 ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
@@ -1459,7 +1460,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 	if (skb->len <= 0) {
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring,
@@ -2227,6 +2228,11 @@ static pci_ers_result_t ixgb_io_error_detected(struct pci_dev *pdev,
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
 
+	netif_device_detach(netdev);
+
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	if (netif_running(netdev))
 		ixgb_down(adapter, true);
 
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 2c4dc82..dd688d4 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -233,10 +233,6 @@ struct ixgbe_q_vector {
 #define IXGBE_TX_CTXTDESC_ADV(R, i)	    \
 	(&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i]))
 
-#define IXGBE_GET_DESC(R, i, type)	(&(((struct type *)((R).desc))[i]))
-#define IXGBE_TX_DESC(R, i)	IXGBE_GET_DESC(R, i, ixgbe_legacy_tx_desc)
-#define IXGBE_RX_DESC(R, i)	IXGBE_GET_DESC(R, i, ixgbe_legacy_rx_desc)
-
 #define IXGBE_MAX_JUMBO_FRAME_SIZE        16128
 #ifdef IXGBE_FCOE
 /* Use 3K as the baby jumbo frame size for FCoE */
@@ -428,55 +424,20 @@ extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
 extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
                                                  struct ixgbe_atr_input *input,
                                                  u8 queue);
-extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
-                                               struct ixgbe_atr_input *input,
-                                               u16 soft_id,
-                                               u8 queue);
-extern u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key);
 extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input,
                                        u16 vlan_id);
 extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input,
                                         u32 src_addr);
 extern s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input,
                                         u32 dst_addr);
-extern s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
-                                        u32 src_addr_1, u32 src_addr_2,
-                                        u32 src_addr_3, u32 src_addr_4);
-extern s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
-                                        u32 dst_addr_1, u32 dst_addr_2,
-                                        u32 dst_addr_3, u32 dst_addr_4);
 extern s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input,
                                         u16 src_port);
 extern s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input,
                                         u16 dst_port);
 extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input,
                                          u16 flex_byte);
-extern s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input,
-                                       u8 vm_pool);
 extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input,
                                       u8 l4type);
-extern s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input,
-                                       u16 *vlan_id);
-extern s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input,
-                                        u32 *src_addr);
-extern s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input,
-                                        u32 *dst_addr);
-extern s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
-                                        u32 *src_addr_1, u32 *src_addr_2,
-                                        u32 *src_addr_3, u32 *src_addr_4);
-extern s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
-                                        u32 *dst_addr_1, u32 *dst_addr_2,
-                                        u32 *dst_addr_3, u32 *dst_addr_4);
-extern s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input,
-                                        u16 *src_port);
-extern s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input,
-                                        u16 *dst_port);
-extern s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input,
-                                         u16 *flex_byte);
-extern s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input,
-                                       u8 *vm_pool);
-extern s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input,
-                                      u8 *l4type);
 #ifdef IXGBE_FCOE
 extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
 extern int ixgbe_fso(struct ixgbe_adapter *adapter,
@@ -489,6 +450,12 @@ extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
 extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
                               struct scatterlist *sgl, unsigned int sgc);
 extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid);
+extern int ixgbe_fcoe_enable(struct net_device *netdev);
+extern int ixgbe_fcoe_disable(struct net_device *netdev);
+#ifdef CONFIG_IXGBE_DCB
+extern u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter);
+extern u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up);
+#endif /* CONFIG_IXGBE_DCB */
 #endif /* IXGBE_FCOE */
 
 #endif /* _IXGBE_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 522c03b..56b12f3 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -41,8 +41,7 @@
 static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
                                              ixgbe_link_speed *speed,
                                              bool *autoneg);
-static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
                                                ixgbe_link_speed speed,
                                                bool autoneg,
                                                bool autoneg_wait_to_complete);
@@ -59,7 +58,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
  *  increase the value to either 10ms to 250ms for capability version 1 config,
  *  or 16ms to 55ms for version 2.
  **/
-void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
+static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
 {
 	struct ixgbe_adapter *adapter = hw->back;
 	u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
@@ -143,7 +142,7 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
  *  not known.  Perform the SFP init if necessary.
  *
  **/
-s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
+static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
 {
 	struct ixgbe_mac_info *mac = &hw->mac;
 	struct ixgbe_phy_info *phy = &hw->phy;
@@ -156,8 +155,6 @@ s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
 	/* Overwrite the link function pointers if copper PHY */
 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
 		mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
-		mac->ops.setup_link_speed =
-		                     &ixgbe_setup_copper_link_speed_82598;
 		mac->ops.get_link_capabilities =
 		                  &ixgbe_get_copper_link_capabilities_82598;
 	}
@@ -204,7 +201,7 @@ out:
  *  Starts the hardware using the generic start_hw function.
  *  Then set pcie completion timeout
  **/
-s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
+static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
 {
 	s32 ret_val = 0;
 
@@ -325,15 +322,18 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
 		break;
 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
-	case IXGBE_DEV_ID_82598EB_CX4:
-	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
 	case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
 	case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
 	case IXGBE_DEV_ID_82598EB_XF_LR:
 	case IXGBE_DEV_ID_82598EB_SFP_LOM:
 		media_type = ixgbe_media_type_fiber;
 		break;
+	case IXGBE_DEV_ID_82598EB_CX4:
+	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+		media_type = ixgbe_media_type_cx4;
+		break;
 	case IXGBE_DEV_ID_82598AT:
+	case IXGBE_DEV_ID_82598AT2:
 		media_type = ixgbe_media_type_copper;
 		break;
 	default:
@@ -464,13 +464,14 @@ out:
 }
 
 /**
- *  ixgbe_setup_mac_link_82598 - Configures MAC link settings
+ *  ixgbe_start_mac_link_82598 - Configures MAC link settings
  *  @hw: pointer to hardware structure
  *
  *  Configures link settings based on values in the ixgbe_hw struct.
  *  Restarts the link.  Performs autonegotiation if needed.
  **/
-static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
+static s32 ixgbe_start_mac_link_82598(struct ixgbe_hw *hw,
+                                      bool autoneg_wait_to_complete)
 {
 	u32 autoc_reg;
 	u32 links_reg;
@@ -483,7 +484,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
 
 	/* Only poll for autoneg to complete if specified to do so */
-	if (hw->phy.autoneg_wait_to_complete) {
+	if (autoneg_wait_to_complete) {
 		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
 		     IXGBE_AUTOC_LMS_KX4_AN ||
 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
@@ -599,7 +600,7 @@ out:
 
 
 /**
- *  ixgbe_setup_mac_link_speed_82598 - Set MAC link speed
+ *  ixgbe_setup_mac_link_82598 - Set MAC link speed
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
  *  @autoneg: true if auto-negotiation enabled
@@ -607,7 +608,7 @@ out:
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
-static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
+static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
                                            ixgbe_link_speed speed, bool autoneg,
                                            bool autoneg_wait_to_complete)
 {
@@ -637,14 +638,12 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
 	}
 
 	if (status == 0) {
-		hw->phy.autoneg_wait_to_complete = autoneg_wait_to_complete;
-
 		/*
 		 * Setup and restart the link based on the new values in
 		 * ixgbe_hw This will write the AUTOC register based on the new
 		 * stored values
 		 */
-		status = ixgbe_setup_mac_link_82598(hw);
+		status = ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
 	}
 
 	return status;
@@ -652,29 +651,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
 
 
 /**
- *  ixgbe_setup_copper_link_82598 - Setup copper link settings
- *  @hw: pointer to hardware structure
- *
- *  Configures link settings based on values in the ixgbe_hw struct.
- *  Restarts the link.  Performs autonegotiation if needed.  Restart
- *  phy and wait for autonegotiate to finish.  Then synchronize the
- *  MAC and PHY.
- **/
-static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
-{
-	s32 status;
-
-	/* Restart autonegotiation on PHY */
-	status = hw->phy.ops.setup_link(hw);
-
-	/* Set up MAC */
-	ixgbe_setup_mac_link_82598(hw);
-
-	return status;
-}
-
-/**
- *  ixgbe_setup_copper_link_speed_82598 - Set the PHY autoneg advertised field
+ *  ixgbe_setup_copper_link_82598 - Set the PHY autoneg advertised field
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
  *  @autoneg: true if autonegotiation enabled
@@ -682,7 +659,7 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
  *
  *  Sets the link speed in the AUTOC register in the MAC and restarts link.
  **/
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
                                                ixgbe_link_speed speed,
                                                bool autoneg,
                                                bool autoneg_wait_to_complete)
@@ -694,7 +671,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
 	                                      autoneg_wait_to_complete);
 
 	/* Set up MAC */
-	ixgbe_setup_mac_link_82598(hw);
+	ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
 
 	return status;
 }
@@ -1162,7 +1139,6 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
 	.read_analog_reg8	= &ixgbe_read_analog_reg8_82598,
 	.write_analog_reg8	= &ixgbe_write_analog_reg8_82598,
 	.setup_link		= &ixgbe_setup_mac_link_82598,
-	.setup_link_speed	= &ixgbe_setup_mac_link_speed_82598,
 	.check_link		= &ixgbe_check_mac_link_82598,
 	.get_link_capabilities	= &ixgbe_get_link_capabilities_82598,
 	.led_on			= &ixgbe_led_on_generic,
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 1984cab..2ec58dc 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -38,62 +38,37 @@
 #define IXGBE_82599_MC_TBL_SIZE   128
 #define IXGBE_82599_VFT_TBL_SIZE  128
 
-s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
-                                      ixgbe_link_speed *speed,
-                                      bool *autoneg);
-enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw);
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw);
-s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
-                                     ixgbe_link_speed speed, bool autoneg,
-                                     bool autoneg_wait_to_complete);
-s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw);
-s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw,
-                               ixgbe_link_speed *speed,
-                               bool *link_up, bool link_up_wait_to_complete);
-s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
-                                     ixgbe_link_speed speed,
-                                     bool autoneg,
-                                     bool autoneg_wait_to_complete);
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+                                          ixgbe_link_speed speed,
+                                          bool autoneg,
+                                          bool autoneg_wait_to_complete);
+s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
+                               bool autoneg_wait_to_complete);
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
+                               ixgbe_link_speed speed,
+                               bool autoneg,
+                               bool autoneg_wait_to_complete);
 static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
                                              ixgbe_link_speed *speed,
                                              bool *autoneg);
-static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
-                                               ixgbe_link_speed speed,
-                                               bool autoneg,
-                                               bool autoneg_wait_to_complete);
-s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw);
-s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
-s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan,
-                         u32 vind, bool vlan_on);
-s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
-s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw);
-s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
-s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw);
-u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
+                                         ixgbe_link_speed speed,
+                                         bool autoneg,
+                                         bool autoneg_wait_to_complete);
 static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
 
-void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
+static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
 {
 	struct ixgbe_mac_info *mac = &hw->mac;
 	if (hw->phy.multispeed_fiber) {
 		/* Set up dual speed SFP+ support */
-		mac->ops.setup_link =
-		          &ixgbe_setup_mac_link_multispeed_fiber;
-		mac->ops.setup_link_speed =
-		          &ixgbe_setup_mac_link_speed_multispeed_fiber;
+		mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
 	} else {
-		mac->ops.setup_link =
-		          &ixgbe_setup_mac_link_82599;
-		mac->ops.setup_link_speed =
-		          &ixgbe_setup_mac_link_speed_82599;
+		mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
 	}
 }
 
-s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 {
 	s32 ret_val = 0;
 	u16 list_offset, data_offset, data_value;
@@ -143,7 +118,7 @@ setup_sfp_out:
  *  Read PCIe configuration space, and get the MSI-X vector count from
  *  the capabilities table.
  **/
-u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
+static u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
 {
 	struct ixgbe_adapter *adapter = hw->back;
 	u16 msix_count;
@@ -182,7 +157,7 @@ static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
  *  not known.  Perform the SFP init if necessary.
  *
  **/
-s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
 {
 	struct ixgbe_mac_info *mac = &hw->mac;
 	struct ixgbe_phy_info *phy = &hw->phy;
@@ -197,8 +172,6 @@ s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
 	/* If copper media, overwrite with copper function pointers */
 	if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
 		mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
-		mac->ops.setup_link_speed =
-		                     &ixgbe_setup_copper_link_speed_82599;
 		mac->ops.get_link_capabilities =
 		                  &ixgbe_get_copper_link_capabilities_82599;
 	}
@@ -225,9 +198,9 @@ s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
  *
  *  Determines the link capabilities by reading the AUTOC register.
  **/
-s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
-                                      ixgbe_link_speed *speed,
-                                      bool *negotiation)
+static s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
+                                             ixgbe_link_speed *speed,
+                                             bool *negotiation)
 {
 	s32 status = 0;
 	u32 autoc = 0;
@@ -344,7 +317,7 @@ static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
  *
  *  Returns the media type (fiber, copper, backplane)
  **/
-enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
+static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
 {
 	enum ixgbe_media_type media_type;
 
@@ -364,6 +337,9 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
 	case IXGBE_DEV_ID_82599_SFP:
 		media_type = ixgbe_media_type_fiber;
 		break;
+	case IXGBE_DEV_ID_82599_CX4:
+		media_type = ixgbe_media_type_cx4;
+		break;
 	default:
 		media_type = ixgbe_media_type_unknown;
 		break;
@@ -373,13 +349,15 @@ out:
 }
 
 /**
- *  ixgbe_setup_mac_link_82599 - Setup MAC link settings
+ *  ixgbe_start_mac_link_82599 - Setup MAC link settings
  *  @hw: pointer to hardware structure
+ *  @autoneg_wait_to_complete: true when waiting for completion is needed
  *
  *  Configures link settings based on values in the ixgbe_hw struct.
  *  Restarts the link.  Performs autonegotiation if needed.
  **/
-s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
+s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
+                               bool autoneg_wait_to_complete)
 {
 	u32 autoc_reg;
 	u32 links_reg;
@@ -392,7 +370,7 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
 	IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
 
 	/* Only poll for autoneg to complete if specified to do so */
-	if (hw->phy.autoneg_wait_to_complete) {
+	if (autoneg_wait_to_complete) {
 		if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
 		     IXGBE_AUTOC_LMS_KX4_KX_KR ||
 		    (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
@@ -420,25 +398,7 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_setup_mac_link_multispeed_fiber - Setup MAC link settings
- *  @hw: pointer to hardware structure
- *
- *  Configures link settings based on values in the ixgbe_hw struct.
- *  Restarts the link for multi-speed fiber at 1G speed, if link
- *  fails at 10G.
- *  Performs autonegotiation if needed.
- **/
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw)
-{
-	s32 status = 0;
-	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_82599_AUTONEG;
-	status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw, link_speed,
-	                                                     true, true);
-	return status;
-}
-
-/**
- *  ixgbe_setup_mac_link_speed_multispeed_fiber - Set MAC link speed
+ *  ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
  *  @autoneg: true if autonegotiation enabled
@@ -446,10 +406,10 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw)
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
-s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
-                                                ixgbe_link_speed speed,
-                                                bool autoneg,
-                                                bool autoneg_wait_to_complete)
+s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+                                          ixgbe_link_speed speed,
+                                          bool autoneg,
+                                          bool autoneg_wait_to_complete)
 {
 	s32 status = 0;
 	ixgbe_link_speed phy_link_speed;
@@ -464,15 +424,6 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
 	hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
 	speed &= phy_link_speed;
 
-	 /* Set autoneg_advertised value based on input link speed */
-	hw->phy.autoneg_advertised = 0;
-
-	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
-		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
-
-	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
-		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
-
 	/*
 	 * When the driver changes the link speeds that it can support,
 	 * it sets autotry_restart to true to indicate that we need to
@@ -504,12 +455,12 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
 		/* Allow module to change analog characteristics (1G->10G) */
 		msleep(40);
 
-		status = ixgbe_setup_mac_link_speed_82599(hw,
-		                                     IXGBE_LINK_SPEED_10GB_FULL,
-		                                     autoneg,
-		                                     autoneg_wait_to_complete);
+		status = ixgbe_setup_mac_link_82599(hw,
+		                               IXGBE_LINK_SPEED_10GB_FULL,
+		                               autoneg,
+		                               autoneg_wait_to_complete);
 		if (status != 0)
-			goto out;
+			return status;
 
 		/* Flap the tx laser if it has not already been done */
 		if (hw->mac.autotry_restart) {
@@ -558,12 +509,12 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
 		/* Allow module to change analog characteristics (10G->1G) */
 		msleep(40);
 
-		status = ixgbe_setup_mac_link_speed_82599(hw,
+		status = ixgbe_setup_mac_link_82599(hw,
 		                                      IXGBE_LINK_SPEED_1GB_FULL,
 		                                      autoneg,
 		                                      autoneg_wait_to_complete);
 		if (status != 0)
-			goto out;
+			return status;
 
 		/* Flap the tx laser if it has not already been done */
 		if (hw->mac.autotry_restart) {
@@ -595,12 +546,21 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
 	 * single highest speed that the user requested.
 	 */
 	if (speedcnt > 1)
-		status = ixgbe_setup_mac_link_speed_multispeed_fiber(hw,
-		                                     highest_link_speed,
-		                                     autoneg,
-		                                     autoneg_wait_to_complete);
+		status = ixgbe_setup_mac_link_multispeed_fiber(hw,
+		                                               highest_link_speed,
+		                                               autoneg,
+		                                               autoneg_wait_to_complete);
 
 out:
+	/* Set autoneg_advertised value based on input link speed */
+	hw->phy.autoneg_advertised = 0;
+
+	if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+	if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+		hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
 	return status;
 }
 
@@ -613,8 +573,10 @@ out:
  *
  *  Reads the links register to determine if link is up and the current speed
  **/
-s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
-                               bool *link_up, bool link_up_wait_to_complete)
+static s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw,
+                                      ixgbe_link_speed *speed,
+                                      bool *link_up,
+                                      bool link_up_wait_to_complete)
 {
 	u32 links_reg;
 	u32 i;
@@ -657,7 +619,7 @@ s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
 }
 
 /**
- *  ixgbe_setup_mac_link_speed_82599 - Set MAC link speed
+ *  ixgbe_setup_mac_link_82599 - Set MAC link speed
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
  *  @autoneg: true if autonegotiation enabled
@@ -665,9 +627,9 @@ s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
-s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
-                                     ixgbe_link_speed speed, bool autoneg,
-                                     bool autoneg_wait_to_complete)
+s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
+                               ixgbe_link_speed speed, bool autoneg,
+                               bool autoneg_wait_to_complete)
 {
 	s32 status = 0;
 	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
@@ -767,26 +729,7 @@ out:
 }
 
 /**
- *  ixgbe_setup_copper_link_82599 - Setup copper link settings
- *  @hw: pointer to hardware structure
- *
- *  Restarts the link on PHY and then MAC. Performs autonegotiation if needed.
- **/
-static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw)
-{
-	s32 status;
-
-	/* Restart autonegotiation on PHY */
-	status = hw->phy.ops.setup_link(hw);
-
-	/* Set up MAC */
-	ixgbe_setup_mac_link_82599(hw);
-
-	return status;
-}
-
-/**
- *  ixgbe_setup_copper_link_speed_82599 - Set the PHY autoneg advertised field
+ *  ixgbe_setup_copper_link_82599 - Set the PHY autoneg advertised field
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
  *  @autoneg: true if autonegotiation enabled
@@ -794,10 +737,10 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw)
  *
  *  Restarts link on PHY and MAC based on settings passed in.
  **/
-static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
-                                               ixgbe_link_speed speed,
-                                               bool autoneg,
-                                               bool autoneg_wait_to_complete)
+static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
+                                         ixgbe_link_speed speed,
+                                         bool autoneg,
+                                         bool autoneg_wait_to_complete)
 {
 	s32 status;
 
@@ -805,7 +748,7 @@ static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
 	status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
 	                                      autoneg_wait_to_complete);
 	/* Set up MAC */
-	ixgbe_setup_mac_link_82599(hw);
+	ixgbe_start_mac_link_82599(hw, autoneg_wait_to_complete);
 
 	return status;
 }
@@ -818,7 +761,7 @@ static s32 ixgbe_setup_copper_link_speed_82599(struct ixgbe_hw *hw,
  *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)
  *  reset.
  **/
-s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
 {
 	s32 status = 0;
 	u32 ctrl, ctrl_ext;
@@ -943,7 +886,7 @@ reset_hw_out:
  *  @rar: receive address register index to disassociate
  *  @vmdq: VMDq pool index to remove from the rar
  **/
-s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+static s32 ixgbe_clear_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 {
 	u32 mpsar_lo, mpsar_hi;
 	u32 rar_entries = hw->mac.num_rar_entries;
@@ -989,7 +932,7 @@ done:
  *  @rar: receive address register index to associate with a VMDq index
  *  @vmdq: VMDq pool index
  **/
-s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+static s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
 {
 	u32 mpsar;
 	u32 rar_entries = hw->mac.num_rar_entries;
@@ -1019,8 +962,8 @@ s32 ixgbe_set_vmdq_82599(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
  *
  *  Turn on/off specified VLAN in the VLAN filter table.
  **/
-s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-                         bool vlan_on)
+static s32 ixgbe_set_vfta_82599(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+                                bool vlan_on)
 {
 	u32 regindex;
 	u32 bitindex;
@@ -1133,7 +1076,7 @@ out:
  *
  *  Clears the VLAN filer table, and the VMDq index associated with the filter
  **/
-s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
 {
 	u32 offset;
 
@@ -1153,7 +1096,7 @@ s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw)
  *  ixgbe_init_uta_tables_82599 - Initialize the Unicast Table Array
  *  @hw: pointer to hardware structure
  **/
-s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
 {
 	int i;
 	hw_dbg(hw, " Clearing UTA\n");
@@ -1430,7 +1373,8 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
  *  @stream: input bitstream to compute the hash on
  *  @key: 32-bit hash key
  **/
-u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key)
+static u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input,
+                                        u32 key)
 {
 	/*
 	 * The algorithm is as follows:
@@ -1602,8 +1546,8 @@ s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr)
  *  @src_addr_4: the fourth 4 bytes of the IP address to load
  **/
 s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
-                                 u32 src_addr_1, u32 src_addr_2,
-                                 u32 src_addr_3, u32 src_addr_4)
+                                        u32 src_addr_1, u32 src_addr_2,
+                                        u32 src_addr_3, u32 src_addr_4)
 {
 	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff;
 	input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] =
@@ -1645,8 +1589,8 @@ s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
  *  @dst_addr_4: the fourth 4 bytes of the IP address to load
  **/
 s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
-                                 u32 dst_addr_1, u32 dst_addr_2,
-                                 u32 dst_addr_3, u32 dst_addr_4)
+                                        u32 dst_addr_1, u32 dst_addr_2,
+                                        u32 dst_addr_3, u32 dst_addr_4)
 {
 	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff;
 	input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] =
@@ -1723,7 +1667,8 @@ s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte)
  *  @input: input stream to modify
  *  @vm_pool: the Virtual Machine pool to load
  **/
-s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool)
+s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input,
+                                       u8 vm_pool)
 {
 	input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool;
 
@@ -1747,7 +1692,8 @@ s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type)
  *  @input: input stream to search
  *  @vlan: the VLAN id to load
  **/
-s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan)
+static s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input,
+                                       u16 *vlan)
 {
 	*vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET];
 	*vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8;
@@ -1760,7 +1706,8 @@ s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan)
  *  @input: input stream to search
  *  @src_addr: the IP address to load
  **/
-s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr)
+static s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input,
+                                        u32 *src_addr)
 {
 	*src_addr = input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET];
 	*src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] << 8;
@@ -1775,7 +1722,8 @@ s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr)
  *  @input: input stream to search
  *  @dst_addr: the IP address to load
  **/
-s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr)
+static s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input,
+                                        u32 *dst_addr)
 {
 	*dst_addr = input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET];
 	*dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] << 8;
@@ -1793,9 +1741,9 @@ s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr)
  *  @src_addr_3: the third 4 bytes of the IP address to load
  *  @src_addr_4: the fourth 4 bytes of the IP address to load
  **/
-s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
-                                 u32 *src_addr_1, u32 *src_addr_2,
-                                 u32 *src_addr_3, u32 *src_addr_4)
+static s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
+                                        u32 *src_addr_1, u32 *src_addr_2,
+                                        u32 *src_addr_3, u32 *src_addr_4)
 {
 	*src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12];
 	*src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] << 8;
@@ -1829,8 +1777,8 @@ s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
  *  @dst_addr_4: the fourth 4 bytes of the IP address to load
  **/
 s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
-                                 u32 *dst_addr_1, u32 *dst_addr_2,
-                                 u32 *dst_addr_3, u32 *dst_addr_4)
+                                        u32 *dst_addr_1, u32 *dst_addr_2,
+                                        u32 *dst_addr_3, u32 *dst_addr_4)
 {
 	*dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12];
 	*dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8;
@@ -1865,7 +1813,8 @@ s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
  *  endianness when retrieving the data.  This can be confusing since the
  *  internal hash engine expects it to be big-endian.
  **/
-s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port)
+static s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input,
+                                        u16 *src_port)
 {
 	*src_port = input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] << 8;
 	*src_port |= input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1];
@@ -1883,7 +1832,8 @@ s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port)
  *  endianness when retrieving the data.  This can be confusing since the
  *  internal hash engine expects it to be big-endian.
  **/
-s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port)
+static s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input,
+                                        u16 *dst_port)
 {
 	*dst_port = input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] << 8;
 	*dst_port |= input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1];
@@ -1896,7 +1846,8 @@ s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port)
  *  @input: input stream to modify
  *  @flex_bytes: the flexible bytes to load
  **/
-s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte)
+static s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input,
+                                         u16 *flex_byte)
 {
 	*flex_byte = input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET];
 	*flex_byte |= input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] << 8;
@@ -1909,7 +1860,8 @@ s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte)
  *  @input: input stream to modify
  *  @vm_pool: the Virtual Machine pool to load
  **/
-s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool)
+s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input,
+                                       u8 *vm_pool)
 {
 	*vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET];
 
@@ -1921,7 +1873,8 @@ s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool)
  *  @input: input stream to modify
  *  @l4type: the layer 4 type value to load
  **/
-s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type)
+static s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input,
+                                      u8 *l4type)
 {
 	*l4type = input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET];
 
@@ -2002,9 +1955,9 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
  *  hardware writes must be protected from one another.
  **/
 s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
-                                        struct ixgbe_atr_input *input,
-                                        u16 soft_id,
-                                        u8 queue)
+                                               struct ixgbe_atr_input *input,
+                                               u16 soft_id,
+                                               u8 queue)
 {
 	u32 fdircmd = 0;
 	u32 fdirhash;
@@ -2097,7 +2050,7 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
  *
  *  Performs read operation to Omer analog register specified.
  **/
-s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
+static s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
 {
 	u32  core_ctl;
 
@@ -2119,7 +2072,7 @@ s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
  *
  *  Performs write operation to Omer analog register specified.
  **/
-s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
+static s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
 {
 	u32  core_ctl;
 
@@ -2139,7 +2092,7 @@ s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
  *  Then performs device-specific:
  *  Clears the rate limiter registers.
  **/
-s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
 {
 	u32 q_num;
 	s32 ret_val;
@@ -2168,7 +2121,7 @@ s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
  *
  *  Determines the physical layer module found on the current adapter.
  **/
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
 {
 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
 	status = ixgbe_identify_phy_generic(hw);
@@ -2183,7 +2136,7 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
  *
  *  Determines physical layer capabilities of the current configuration.
  **/
-u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
+static u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
 {
 	u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
 	u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
@@ -2290,7 +2243,7 @@ out:
  *
  *  Enables the Rx DMA unit for 82599
  **/
-s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
+static s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
 {
 #define IXGBE_MAX_SECRX_POLL 30
 	int i;
@@ -2335,7 +2288,7 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
  *  This function will read the EEPROM location for the device capabilities,
  *  and return the word through device_caps.
  **/
-s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
+static s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
 {
 	hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
 
@@ -2351,8 +2304,8 @@ s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
  *  pointer, and returns the value at that location.  This is used in both
  *  get and set mac_addr routines.
  **/
-s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw,
-                                        u16 *san_mac_offset)
+static s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw,
+                                               u16 *san_mac_offset)
 {
 	/*
 	 * First read the EEPROM pointer to see if the MAC addresses are
@@ -2373,7 +2326,7 @@ s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw,
  *  set_lan_id() is called by identify_sfp(), but this cannot be relied
  *  upon for non-SFP connections, so we must call it here.
  **/
-s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr)
+static s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr)
 {
 	u16 san_mac_data, san_mac_offset;
 	u8 i;
@@ -2476,7 +2429,6 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
 	.read_analog_reg8       = &ixgbe_read_analog_reg8_82599,
 	.write_analog_reg8      = &ixgbe_write_analog_reg8_82599,
 	.setup_link             = &ixgbe_setup_mac_link_82599,
-	.setup_link_speed       = &ixgbe_setup_mac_link_speed_82599,
 	.check_link             = &ixgbe_check_mac_link_82599,
 	.get_link_capabilities  = &ixgbe_get_link_capabilities_82599,
 	.led_on                 = &ixgbe_led_on_generic,
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 96a1859..6621e17 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -53,6 +53,7 @@ static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
 static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
 static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
 static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
+static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
 
 /**
  *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
@@ -1815,7 +1816,7 @@ out:
  *
  *  Called at init time to set up flow control.
  **/
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
+static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
 {
 	s32 ret_val = 0;
 	u32 reg;
diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h
index 0d34d4d..27f3214 100644
--- a/drivers/net/ixgbe/ixgbe_common.h
+++ b/drivers/net/ixgbe/ixgbe_common.h
@@ -64,7 +64,6 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
 s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
 s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num);
 s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
index 589f62c..ec8a252 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -145,8 +145,12 @@ s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
 	u32    credit_max    = 0;
 	u8     i             = 0;
 
-	/* Disable the arbiter before changing parameters */
-	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, IXGBE_RTRPCS_ARBDIS);
+	/*
+	 * Disable the arbiter before changing parameters
+	 * (always enable recycle mode; WSP)
+	 */
+	reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC | IXGBE_RTRPCS_ARBDIS;
+	IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
 
 	/* Map all traffic classes to their UP, 1 to 1 */
 	reg = 0;
@@ -194,9 +198,6 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
 	u32    reg, max_credits;
 	u8     i;
 
-	/* Disable the arbiter before changing parameters */
-	IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, IXGBE_RTTDCS_ARBDIS);
-
 	/* Clear the per-Tx queue credits; we use per-TC instead */
 	for (i = 0; i < 128; i++) {
 		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
@@ -244,8 +245,14 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
 	u32 reg;
 	u8 i;
 
-	/* Disable the arbiter before changing parameters */
-	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, IXGBE_RTTPCS_ARBDIS);
+	/*
+	 * Disable the arbiter before changing parameters
+	 * (always enable recycle mode; SP; arb delay)
+	 */
+	reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
+	      (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT) |
+	      IXGBE_RTTPCS_ARBDIS;
+	IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
 
 	/* Map all traffic classes to their UP, 1 to 1 */
 	reg = 0;
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index 1c72657..a6bc1ef 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -36,6 +36,7 @@
 #define BIT_PFC		0x02
 #define BIT_PG_RX	0x04
 #define BIT_PG_TX	0x08
+#define BIT_APP_UPCHG	0x10
 #define BIT_RESETLINK   0x40
 #define BIT_LINKSPEED   0x80
 
@@ -139,18 +140,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 			adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
 		}
 		adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
-#ifdef IXGBE_FCOE
-		/* Turn on FCoE offload */
-		if ((adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) &&
-		    (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))) {
-			adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;
-			adapter->ring_feature[RING_F_FCOE].indices =
-				IXGBE_FCRETA_SIZE;
-			netdev->features |= NETIF_F_FCOE_CRC;
-			netdev->features |= NETIF_F_FSO;
-			netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
-		}
-#endif /* IXGBE_FCOE */
 		ixgbe_init_interrupt_scheme(adapter);
 		if (netif_running(netdev))
 			netdev->netdev_ops->ndo_open(netdev);
@@ -169,17 +158,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 			if (adapter->hw.mac.type == ixgbe_mac_82599EB)
 				adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
 
-#ifdef IXGBE_FCOE
-			/* Turn off FCoE offload */
-			if (adapter->flags & (IXGBE_FLAG_FCOE_CAPABLE |
-			     IXGBE_FLAG_FCOE_ENABLED)) {
-				adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
-				adapter->ring_feature[RING_F_FCOE].indices = 0;
-				netdev->features &= ~NETIF_F_FCOE_CRC;
-				netdev->features &= ~NETIF_F_FSO;
-				netdev->fcoe_ddp_xid = 0;
-			}
-#endif /* IXGBE_FCOE */
 			ixgbe_init_interrupt_scheme(adapter);
 			if (netif_running(netdev))
 				netdev->netdev_ops->ndo_open(netdev);
@@ -371,8 +349,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
 		while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
 			msleep(1);
 
-		if (netif_running(netdev))
-			ixgbe_down(adapter);
+		if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
+			if (netif_running(netdev))
+				netdev->netdev_ops->ndo_stop(netdev);
+			ixgbe_clear_interrupt_scheme(adapter);
+		} else {
+			if (netif_running(netdev))
+				ixgbe_down(adapter);
+		}
 	}
 
 	ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
@@ -396,8 +380,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
 	}
 
 	if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
-		if (netif_running(netdev))
-			ixgbe_up(adapter);
+		if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
+			ixgbe_init_interrupt_scheme(adapter);
+			if (netif_running(netdev))
+				netdev->netdev_ops->ndo_open(netdev);
+		} else {
+			if (netif_running(netdev))
+				ixgbe_up(adapter);
+		}
 		ret = DCB_HW_CHG_RST;
 	} else if (adapter->dcb_set_bitmap & BIT_PFC) {
 		if (adapter->hw.mac.type == ixgbe_mac_82598EB)
@@ -503,6 +493,76 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
 	return;
 }
 
+/**
+ * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority
+ * @netdev : the corresponding netdev
+ * @idtype : identifies the id as ether type or TCP/UDP port number
+ * @id: id is either ether type or TCP/UDP port number
+ *
+ * Returns : on success, returns a non-zero 802.1p user priority bitmap
+ * otherwise returns 0 as the invalid user priority bitmap to indicate an
+ * error.
+ */
+static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
+{
+	u8 rval = 0;
+
+	switch (idtype) {
+	case DCB_APP_IDTYPE_ETHTYPE:
+#ifdef IXGBE_FCOE
+		if (id == ETH_P_FCOE)
+			rval = ixgbe_fcoe_getapp(netdev_priv(netdev));
+#endif
+		break;
+	case DCB_APP_IDTYPE_PORTNUM:
+		break;
+	default:
+		break;
+	}
+	return rval;
+}
+
+/**
+ * ixgbe_dcbnl_setapp - set the DCBX application user priority
+ * @netdev : the corresponding netdev
+ * @idtype : identifies the id as ether type or TCP/UDP port number
+ * @id: id is either ether type or TCP/UDP port number
+ * @up: the 802.1p user priority bitmap
+ *
+ * Returns : 0 on success or 1 on error
+ */
+static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
+                             u8 idtype, u16 id, u8 up)
+{
+	u8 rval = 1;
+
+	switch (idtype) {
+	case DCB_APP_IDTYPE_ETHTYPE:
+#ifdef IXGBE_FCOE
+		if (id == ETH_P_FCOE) {
+			u8 tc;
+			struct ixgbe_adapter *adapter;
+
+			adapter = netdev_priv(netdev);
+			tc = adapter->fcoe.tc;
+			rval = ixgbe_fcoe_setapp(adapter, up);
+			if ((!rval) && (tc != adapter->fcoe.tc) &&
+			    (adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
+			    (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) {
+				adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+				adapter->dcb_set_bitmap |= BIT_RESETLINK;
+			}
+		}
+#endif
+		break;
+	case DCB_APP_IDTYPE_PORTNUM:
+		break;
+	default:
+		break;
+	}
+	return rval;
+}
+
 struct dcbnl_rtnl_ops dcbnl_ops = {
 	.getstate	= ixgbe_dcbnl_get_state,
 	.setstate	= ixgbe_dcbnl_set_state,
@@ -523,5 +583,7 @@ struct dcbnl_rtnl_ops dcbnl_ops = {
 	.setnumtcs	= ixgbe_dcbnl_setnumtcs,
 	.getpfcstate	= ixgbe_dcbnl_getpfcstate,
 	.setpfcstate	= ixgbe_dcbnl_setpfcstate,
+	.getapp		= ixgbe_dcbnl_getapp,
+	.setapp		= ixgbe_dcbnl_setapp,
 };
 
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index dff8dfa..026e94a 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -169,23 +169,20 @@ static int ixgbe_get_settings(struct net_device *netdev,
 		}
 	} else if (hw->phy.media_type == ixgbe_media_type_backplane) {
 		/* Set as FIBRE until SERDES defined in kernel */
-		switch (hw->device_id) {
-		case IXGBE_DEV_ID_82598:
-			ecmd->supported |= (SUPPORTED_1000baseT_Full |
-				SUPPORTED_FIBRE);
-			ecmd->advertising = (ADVERTISED_10000baseT_Full |
-				ADVERTISED_1000baseT_Full |
-				ADVERTISED_FIBRE);
-			ecmd->port = PORT_FIBRE;
-			break;
-		case IXGBE_DEV_ID_82598_BX:
+		if (hw->device_id == IXGBE_DEV_ID_82598_BX) {
 			ecmd->supported = (SUPPORTED_1000baseT_Full |
 					   SUPPORTED_FIBRE);
 			ecmd->advertising = (ADVERTISED_1000baseT_Full |
 					     ADVERTISED_FIBRE);
 			ecmd->port = PORT_FIBRE;
 			ecmd->autoneg = AUTONEG_DISABLE;
-			break;
+		} else {
+			ecmd->supported |= (SUPPORTED_1000baseT_Full |
+					    SUPPORTED_FIBRE);
+			ecmd->advertising = (ADVERTISED_10000baseT_Full |
+					     ADVERTISED_1000baseT_Full |
+					     ADVERTISED_FIBRE);
+			ecmd->port = PORT_FIBRE;
 		}
 	} else {
 		ecmd->supported |= SUPPORTED_FIBRE;
@@ -236,11 +233,11 @@ static int ixgbe_set_settings(struct net_device *netdev,
 			return err;
 		/* this sets the link speed and restarts auto-neg */
 		hw->mac.autotry_restart = true;
-		err = hw->mac.ops.setup_link_speed(hw, advertised, true, true);
+		err = hw->mac.ops.setup_link(hw, advertised, true, true);
 		if (err) {
 			DPRINTK(PROBE, INFO,
 			        "setup link failed with code %d\n", err);
-			hw->mac.ops.setup_link_speed(hw, old, true, true);
+			hw->mac.ops.setup_link(hw, old, true, true);
 		}
 	} else {
 		/* in this case we currently only support 10Gb/FULL */
@@ -1440,7 +1437,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 		goto err_nomem;
 	}
 
-	tx_ring->size = tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc);
+	tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
 	tx_ring->size = ALIGN(tx_ring->size, 4096);
 	if (!(tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
 						   &tx_ring->dma))) {
@@ -1454,7 +1451,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0),
 			((u64) tx_ring->dma >> 32));
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0),
-			tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc));
+			tx_ring->count * sizeof(union ixgbe_adv_tx_desc));
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0);
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0);
 
@@ -1472,7 +1469,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data);
 
 	for (i = 0; i < tx_ring->count; i++) {
-		struct ixgbe_legacy_tx_desc *desc = IXGBE_TX_DESC(*tx_ring, i);
+		union ixgbe_adv_tx_desc *desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
 		struct sk_buff *skb;
 		unsigned int size = 1024;
 
@@ -1486,13 +1483,18 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 		tx_ring->tx_buffer_info[i].length = skb->len;
 		tx_ring->tx_buffer_info[i].dma =
 			pci_map_single(pdev, skb->data, skb->len,
-					PCI_DMA_TODEVICE);
-		desc->buffer_addr = cpu_to_le64(tx_ring->tx_buffer_info[i].dma);
-		desc->lower.data = cpu_to_le32(skb->len);
-		desc->lower.data |= cpu_to_le32(IXGBE_TXD_CMD_EOP |
-		                                IXGBE_TXD_CMD_IFCS |
-		                                IXGBE_TXD_CMD_RS);
-		desc->upper.data = 0;
+			               PCI_DMA_TODEVICE);
+		desc->read.buffer_addr =
+		                    cpu_to_le64(tx_ring->tx_buffer_info[i].dma);
+		desc->read.cmd_type_len = cpu_to_le32(skb->len);
+		desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD_EOP |
+		                                       IXGBE_TXD_CMD_IFCS |
+		                                       IXGBE_TXD_CMD_RS);
+		desc->read.olinfo_status = 0;
+		if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+			desc->read.olinfo_status |=
+			                (skb->len << IXGBE_ADVTXD_PAYLEN_SHIFT);
+
 	}
 
 	/* Setup Rx Descriptor ring and Rx buffers */
@@ -1508,7 +1510,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 		goto err_nomem;
 	}
 
-	rx_ring->size = rx_ring->count * sizeof(struct ixgbe_legacy_rx_desc);
+	rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
 	rx_ring->size = ALIGN(rx_ring->size, 4096);
 	if (!(rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
 						   &rx_ring->dma))) {
@@ -1566,8 +1568,8 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl);
 
 	for (i = 0; i < rx_ring->count; i++) {
-		struct ixgbe_legacy_rx_desc *rx_desc =
-					IXGBE_RX_DESC(*rx_ring, i);
+		union ixgbe_adv_rx_desc *rx_desc =
+		                                 IXGBE_RX_DESC_ADV(*rx_ring, i);
 		struct sk_buff *skb;
 
 		skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
@@ -1580,7 +1582,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 		rx_ring->rx_buffer_info[i].dma =
 			pci_map_single(pdev, skb->data, IXGBE_RXBUFFER_2048,
 			               PCI_DMA_FROMDEVICE);
-		rx_desc->buffer_addr =
+		rx_desc->read.pkt_addr =
 				cpu_to_le64(rx_ring->rx_buffer_info[i].dma);
 		memset(skb->data, 0x00, skb->len);
 	}
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 28cf104..a3c9f99 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -27,6 +27,9 @@
 
 
 #include "ixgbe.h"
+#ifdef CONFIG_IXGBE_DCB
+#include "ixgbe_dcb_82599.h"
+#endif /* CONFIG_IXGBE_DCB */
 #include <linux/if_ether.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -289,6 +292,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
 		   struct sk_buff *skb)
 {
 	u16 xid;
+	u32 fctl;
 	u32 sterr, fceofe, fcerr, fcstat;
 	int rc = -EINVAL;
 	struct ixgbe_fcoe *fcoe;
@@ -309,7 +313,12 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
 	skb_set_transport_header(skb, skb_network_offset(skb) +
 				 sizeof(struct fcoe_hdr));
 	fh = (struct fc_frame_header *)skb_transport_header(skb);
-	xid =  be16_to_cpu(fh->fh_ox_id);
+	fctl = ntoh24(fh->fh_f_ctl);
+	if (fctl & FC_FC_EX_CTX)
+		xid =  be16_to_cpu(fh->fh_ox_id);
+	else
+		xid =  be16_to_cpu(fh->fh_rx_id);
+
 	if (xid >= IXGBE_FCOE_DDP_MAX)
 		goto ddp_out;
 
@@ -554,3 +563,158 @@ void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter)
 		fcoe->pool = NULL;
 	}
 }
+
+/**
+ * ixgbe_fcoe_enable - turn on FCoE offload feature
+ * @netdev: the corresponding netdev
+ *
+ * Turns on FCoE offload feature in 82599.
+ *
+ * Returns : 0 indicates success or -EINVAL on failure
+ */
+int ixgbe_fcoe_enable(struct net_device *netdev)
+{
+	int rc = -EINVAL;
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+
+	if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
+		goto out_enable;
+
+	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+		goto out_enable;
+
+	DPRINTK(DRV, INFO, "Enabling FCoE offload features.\n");
+	if (netif_running(netdev))
+		netdev->netdev_ops->ndo_stop(netdev);
+
+	ixgbe_clear_interrupt_scheme(adapter);
+
+	adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;
+	adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE;
+	netdev->features |= NETIF_F_FCOE_CRC;
+	netdev->features |= NETIF_F_FSO;
+	netdev->features |= NETIF_F_FCOE_MTU;
+	netdev->vlan_features |= NETIF_F_FCOE_CRC;
+	netdev->vlan_features |= NETIF_F_FSO;
+	netdev->vlan_features |= NETIF_F_FCOE_MTU;
+	netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
+	netdev_features_change(netdev);
+
+	ixgbe_init_interrupt_scheme(adapter);
+
+	if (netif_running(netdev))
+		netdev->netdev_ops->ndo_open(netdev);
+	rc = 0;
+
+out_enable:
+	return rc;
+}
+
+/**
+ * ixgbe_fcoe_disable - turn off FCoE offload feature
+ * @netdev: the corresponding netdev
+ *
+ * Turns off FCoE offload feature in 82599.
+ *
+ * Returns : 0 indicates success or -EINVAL on failure
+ */
+int ixgbe_fcoe_disable(struct net_device *netdev)
+{
+	int rc = -EINVAL;
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+	if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
+		goto out_disable;
+
+	if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
+		goto out_disable;
+
+	DPRINTK(DRV, INFO, "Disabling FCoE offload features.\n");
+	if (netif_running(netdev))
+		netdev->netdev_ops->ndo_stop(netdev);
+
+	ixgbe_clear_interrupt_scheme(adapter);
+
+	adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
+	adapter->ring_feature[RING_F_FCOE].indices = 0;
+	netdev->features &= ~NETIF_F_FCOE_CRC;
+	netdev->features &= ~NETIF_F_FSO;
+	netdev->features &= ~NETIF_F_FCOE_MTU;
+	netdev->vlan_features &= ~NETIF_F_FCOE_CRC;
+	netdev->vlan_features &= ~NETIF_F_FSO;
+	netdev->vlan_features &= ~NETIF_F_FCOE_MTU;
+	netdev->fcoe_ddp_xid = 0;
+	netdev_features_change(netdev);
+
+	ixgbe_cleanup_fcoe(adapter);
+
+	ixgbe_init_interrupt_scheme(adapter);
+	if (netif_running(netdev))
+		netdev->netdev_ops->ndo_open(netdev);
+	rc = 0;
+
+out_disable:
+	return rc;
+}
+
+#ifdef CONFIG_IXGBE_DCB
+/**
+ * ixgbe_fcoe_getapp - retrieves current user priority bitmap for FCoE
+ * @adapter : ixgbe adapter
+ *
+ * Finds out the corresponding user priority bitmap from the current
+ * traffic class that FCoE belongs to. Returns 0 as the invalid user
+ * priority bitmap to indicate an error.
+ *
+ * Returns : 802.1p user priority bitmap for FCoE
+ */
+u8 ixgbe_fcoe_getapp(struct ixgbe_adapter *adapter)
+{
+	int i;
+	u8 tc;
+	u32 up2tc;
+
+	up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC);
+	for (i = 0; i < MAX_USER_PRIORITY; i++) {
+		tc = (u8)(up2tc >> (i * IXGBE_RTTUP2TC_UP_SHIFT));
+		tc &= (MAX_TRAFFIC_CLASS - 1);
+		if (adapter->fcoe.tc == tc)
+			return 1 << i;
+	}
+
+	return 0;
+}
+
+/**
+ * ixgbe_fcoe_setapp - sets the user priority bitmap for FCoE
+ * @adapter : ixgbe adapter
+ * @up : 802.1p user priority bitmap
+ *
+ * Finds out the traffic class from the input user priority
+ * bitmap for FCoE.
+ *
+ * Returns : 0 on success otherwise returns 1 on error
+ */
+u8 ixgbe_fcoe_setapp(struct ixgbe_adapter *adapter, u8 up)
+{
+	int i;
+	u32 up2tc;
+
+	/* valid user priority bitmap must not be 0 */
+	if (up) {
+		/* from user priority to the corresponding traffic class */
+		up2tc = IXGBE_READ_REG(&adapter->hw, IXGBE_RTTUP2TC);
+		for (i = 0; i < MAX_USER_PRIORITY; i++) {
+			if (up & (1 << i)) {
+				up2tc >>= (i * IXGBE_RTTUP2TC_UP_SHIFT);
+				up2tc &= (MAX_TRAFFIC_CLASS - 1);
+				adapter->fcoe.tc = (u8)up2tc;
+				return 0;
+			}
+		}
+	}
+
+	return 1;
+}
+#endif /* CONFIG_IXGBE_DCB */
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h
index c5b5002..b5dee7b 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ixgbe/ixgbe_fcoe.h
@@ -46,6 +46,9 @@
 #define IXGBE_FCBUFF_MIN	4096	/* 4KB min */
 #define IXGBE_FCOE_DDP_MAX	512	/* 9 bits xid */
 
+/* Default traffic class to use for FCoE */
+#define IXGBE_FCOE_DEFTC	3
+
 /* fcerr */
 #define IXGBE_FCERR_BADCRC       0x00100000
 
@@ -59,6 +62,7 @@ struct ixgbe_fcoe_ddp {
 };
 
 struct ixgbe_fcoe {
+	u8 tc;
 	spinlock_t lock;
 	struct pci_pool *pool;
 	struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 77b0381..59ad959 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -49,7 +49,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                               "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "2.0.34-k2"
+#define DRV_VERSION "2.0.37-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
 
@@ -75,6 +75,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
 	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT),
 	 board_82598 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT2),
+	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
 	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
@@ -95,6 +97,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
 	 board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
 	 board_82599 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4),
+	 board_82599 },
 
 	/* required last entry */
 	{0, }
@@ -2024,7 +2028,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 	else
 		hlreg0 |= IXGBE_HLREG0_JUMBOEN;
 #ifdef IXGBE_FCOE
-	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+	if (netdev->features & NETIF_F_FCOE_MTU)
 		hlreg0 |= IXGBE_HLREG0_JUMBOEN;
 #endif
 	IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
@@ -2053,9 +2057,11 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 
 		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
 			rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED;
+		else
+			rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
 
 #ifdef IXGBE_FCOE
-		if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+		if (netdev->features & NETIF_F_FCOE_MTU) {
 			struct ixgbe_ring_feature *f;
 			f = &adapter->ring_feature[RING_F_FCOE];
 			if ((i >= f->mask) && (i < f->mask + f->indices)) {
@@ -2514,7 +2520,7 @@ static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
 static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
 {
 	u32 autoneg;
-	bool link_up = false;
+	bool negotiation, link_up = false;
 	u32 ret = IXGBE_ERR_LINK_SETUP;
 
 	if (hw->mac.ops.check_link)
@@ -2524,13 +2530,12 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
 		goto link_cfg_out;
 
 	if (hw->mac.ops.get_link_capabilities)
-		ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
-		                                        &hw->mac.autoneg);
+		ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
 	if (ret)
 		goto link_cfg_out;
 
-	if (hw->mac.ops.setup_link_speed)
-		ret = hw->mac.ops.setup_link_speed(hw, autoneg, true, link_up);
+	if (hw->mac.ops.setup_link)
+		ret = hw->mac.ops.setup_link(hw, autoneg, negotiation, link_up);
 link_cfg_out:
 	return ret;
 }
@@ -2607,7 +2612,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 
 #ifdef IXGBE_FCOE
 	/* adjust max frame to be able to do baby jumbo for FCoE */
-	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+	if ((netdev->features & NETIF_F_FCOE_MTU) &&
 	    (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
 		max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
 
@@ -3112,14 +3117,16 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
 
 	f->indices = min((int)num_online_cpus(), f->indices);
 	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+		adapter->num_rx_queues = 1;
+		adapter->num_tx_queues = 1;
 #ifdef CONFIG_IXGBE_DCB
 		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-			DPRINTK(PROBE, INFO, "FCOE enabled with DCB \n");
+			DPRINTK(PROBE, INFO, "FCoE enabled with DCB \n");
 			ixgbe_set_dcb_queues(adapter);
 		}
 #endif
 		if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
-			DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n");
+			DPRINTK(PROBE, INFO, "FCoE enabled with RSS \n");
 			if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
 			    (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
 				ixgbe_set_fdir_queues(adapter);
@@ -3129,8 +3136,7 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
 		/* adding FCoE rx rings to the end */
 		f->mask = adapter->num_rx_queues;
 		adapter->num_rx_queues += f->indices;
-		if (adapter->num_tx_queues == 0)
-			adapter->num_tx_queues = f->indices;
+		adapter->num_tx_queues += f->indices;
 
 		ret = true;
 	}
@@ -3370,15 +3376,36 @@ static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
  */
 static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter)
 {
-	int i, fcoe_i = 0;
+	int i, fcoe_rx_i = 0, fcoe_tx_i = 0;
 	bool ret = false;
 	struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
 
 	if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
 #ifdef CONFIG_IXGBE_DCB
 		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+			struct ixgbe_fcoe *fcoe = &adapter->fcoe;
+
 			ixgbe_cache_ring_dcb(adapter);
-			fcoe_i = adapter->rx_ring[0].reg_idx + 1;
+			/* find out queues in TC for FCoE */
+			fcoe_rx_i = adapter->rx_ring[fcoe->tc].reg_idx + 1;
+			fcoe_tx_i = adapter->tx_ring[fcoe->tc].reg_idx + 1;
+			/*
+			 * In 82599, the number of Tx queues for each traffic
+			 * class for both 8-TC and 4-TC modes are:
+			 * TCs  : TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7
+			 * 8 TCs:  32  32  16  16   8   8   8   8
+			 * 4 TCs:  64  64  32  32
+			 * We have max 8 queues for FCoE, where 8 the is
+			 * FCoE redirection table size. If TC for FCoE is
+			 * less than or equal to TC3, we have enough queues
+			 * to add max of 8 queues for FCoE, so we start FCoE
+			 * tx descriptor from the next one, i.e., reg_idx + 1.
+			 * If TC for FCoE is above TC3, implying 8 TC mode,
+			 * and we need 8 for FCoE, we have to take all queues
+			 * in that traffic class for FCoE.
+			 */
+			if ((f->indices == IXGBE_FCRETA_SIZE) && (fcoe->tc > 3))
+				fcoe_tx_i--;
 		}
 #endif /* CONFIG_IXGBE_DCB */
 		if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
@@ -3388,10 +3415,13 @@ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter)
 			else
 				ixgbe_cache_ring_rss(adapter);
 
-			fcoe_i = f->mask;
+			fcoe_rx_i = f->mask;
+			fcoe_tx_i = f->mask;
+		}
+		for (i = 0; i < f->indices; i++, fcoe_rx_i++, fcoe_tx_i++) {
+			adapter->rx_ring[f->mask + i].reg_idx = fcoe_rx_i;
+			adapter->tx_ring[f->mask + i].reg_idx = fcoe_tx_i;
 		}
-		for (i = 0; i < f->indices; i++, fcoe_i++)
-			adapter->rx_ring[f->mask + i].reg_idx = fcoe_i;
 		ret = true;
 	}
 	return ret;
@@ -3613,7 +3643,7 @@ static void ixgbe_free_q_vectors(struct ixgbe_adapter *adapter)
 	}
 }
 
-void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
+static void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
 {
 	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
 		adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
@@ -3799,6 +3829,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
 		adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE;
 		adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
 		adapter->ring_feature[RING_F_FCOE].indices = 0;
+		/* Default traffic class to use for FCoE */
+		adapter->fcoe.tc = IXGBE_FCOE_DEFTC;
 #endif /* IXGBE_FCOE */
 	}
 
@@ -4513,14 +4545,14 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work)
 	                                             multispeed_fiber_task);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 autoneg;
+	bool negotiation;
 
 	adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK;
 	autoneg = hw->phy.autoneg_advertised;
 	if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
-		hw->mac.ops.get_link_capabilities(hw, &autoneg,
-		                                  &hw->mac.autoneg);
-	if (hw->mac.ops.setup_link_speed)
-		hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
+		hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+	if (hw->mac.ops.setup_link)
+		hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
 	adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
 	adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
 }
@@ -4634,13 +4666,13 @@ static void ixgbe_watchdog_task(struct work_struct *work)
 			if (hw->mac.type == ixgbe_mac_82599EB) {
 				u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
 				u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
-				flow_rx = (mflcn & IXGBE_MFLCN_RFCE);
-				flow_tx = (fccfg & IXGBE_FCCFG_TFCE_802_3X);
+				flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
+				flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
 			} else {
 				u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
 				u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
-				flow_rx = (frctl & IXGBE_FCTRL_RFCE);
-				flow_tx = (rmcs & IXGBE_RMCS_TFCE_802_3X);
+				flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
+				flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
 			}
 
 			printk(KERN_INFO "ixgbe: %s NIC Link is Up %s, "
@@ -5100,12 +5132,13 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
 		return smp_processor_id();
 
 	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
-		return 0;  /* All traffic should default to class 0 */
+		return (skb->vlan_tci & IXGBE_TX_FLAGS_VLAN_PRIO_MASK) >> 13;
 
 	return skb_tx_hash(dev, skb);
 }
 
-static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
+				    struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_ring *tx_ring;
@@ -5139,9 +5172,15 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	tx_ring = &adapter->tx_ring[r_idx];
 
 	if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
-	    (skb->protocol == htons(ETH_P_FCOE)))
+	    (skb->protocol == htons(ETH_P_FCOE))) {
 		tx_flags |= IXGBE_TX_FLAGS_FCOE;
-
+#ifdef IXGBE_FCOE
+		r_idx = smp_processor_id();
+		r_idx &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
+		r_idx += adapter->ring_feature[RING_F_FCOE].mask;
+		tx_ring = &adapter->tx_ring[r_idx];
+#endif
+	}
 	/* four things can cause us to need a context descriptor */
 	if (skb_is_gso(skb) ||
 	    (skb->ip_summed == CHECKSUM_PARTIAL) ||
@@ -5374,6 +5413,8 @@ static const struct net_device_ops ixgbe_netdev_ops = {
 #ifdef IXGBE_FCOE
 	.ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
 	.ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
+	.ndo_fcoe_enable = ixgbe_fcoe_enable,
+	.ndo_fcoe_disable = ixgbe_fcoe_disable,
 #endif /* IXGBE_FCOE */
 };
 
@@ -5573,6 +5614,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
 	netdev->vlan_features |= NETIF_F_IP_CSUM;
+	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
 	if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index be90eb4..8761d78 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -42,12 +42,14 @@
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
 #define IXGBE_DEV_ID_82598EB_SFP_LOM     0x10DB
 #define IXGBE_DEV_ID_82598AT             0x10C8
+#define IXGBE_DEV_ID_82598AT2            0x150B
 #define IXGBE_DEV_ID_82598EB_CX4         0x10DD
 #define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
 #define IXGBE_DEV_ID_82598_DA_DUAL_PORT  0x10F1
 #define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM      0x10E1
 #define IXGBE_DEV_ID_82598EB_XF_LR       0x10F4
 #define IXGBE_DEV_ID_82599_KX4           0x10F7
+#define IXGBE_DEV_ID_82599_CX4           0x10F9
 #define IXGBE_DEV_ID_82599_SFP           0x10FB
 #define IXGBE_DEV_ID_82599_XAUI_LOM      0x10FC
 
@@ -1901,27 +1903,6 @@ enum ixgbe_fdir_pballoc_type {
 #define IXGBE_FDIR_INIT_DONE_POLL               10
 #define IXGBE_FDIRCMD_CMD_POLL                  10
 
-/* Transmit Descriptor - Legacy */
-struct ixgbe_legacy_tx_desc {
-	u64 buffer_addr;       /* Address of the descriptor's data buffer */
-	union {
-		__le32 data;
-		struct {
-			__le16 length;    /* Data buffer length */
-			u8 cso;           /* Checksum offset */
-			u8 cmd;           /* Descriptor control */
-		} flags;
-	} lower;
-	union {
-		__le32 data;
-		struct {
-			u8 status;        /* Descriptor status */
-			u8 css;           /* Checksum start */
-			__le16 vlan;
-		} fields;
-	} upper;
-};
-
 /* Transmit Descriptor - Advanced */
 union ixgbe_adv_tx_desc {
 	struct {
@@ -1936,16 +1917,6 @@ union ixgbe_adv_tx_desc {
 	} wb;
 };
 
-/* Receive Descriptor - Legacy */
-struct ixgbe_legacy_rx_desc {
-	__le64 buffer_addr; /* Address of the descriptor's data buffer */
-	__le16 length;      /* Length of data DMAed into data buffer */
-	__le16 csum;        /* Packet checksum */
-	u8 status;          /* Descriptor status */
-	u8 errors;          /* Descriptor Errors */
-	__le16 vlan;
-};
-
 /* Receive Descriptor - Advanced */
 union ixgbe_adv_rx_desc {
 	struct {
@@ -2173,6 +2144,7 @@ enum ixgbe_media_type {
 	ixgbe_media_type_fiber,
 	ixgbe_media_type_copper,
 	ixgbe_media_type_backplane,
+	ixgbe_media_type_cx4,
 	ixgbe_media_type_virtual
 };
 
@@ -2362,9 +2334,7 @@ struct ixgbe_mac_operations {
 	s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
 
 	/* Link */
-	s32 (*setup_link)(struct ixgbe_hw *);
-	s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
-	                        bool);
+	s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool);
 	s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
 	s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
 	                             bool *);
@@ -2436,8 +2406,6 @@ struct ixgbe_mac_info {
 	u32                             orig_autoc;
 	u32                             orig_autoc2;
 	bool                            orig_link_settings_stored;
-	bool                            autoneg;
-	bool                            autoneg_succeeded;
 	bool                            autotry_restart;
 };
 
@@ -2452,7 +2420,6 @@ struct ixgbe_phy_info {
 	enum ixgbe_media_type           media_type;
 	bool                            reset_disable;
 	ixgbe_autoneg_advertised        autoneg_advertised;
-	bool                            autoneg_wait_to_complete;
 	bool                            multispeed_fiber;
 };
 
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 92fb823..1272434 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -46,7 +46,7 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (unlikely(skb->len > PAGE_SIZE)) {
 		/* @@@ Count drops.  */
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	entry = tx_pointer;
@@ -70,7 +70,7 @@ static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 	local_irq_restore(flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 2f28609..6e5b3f3 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -108,7 +108,7 @@ static const struct net_device_ops sonic_netdev_ops = {
 	.ndo_set_mac_address	= eth_mac_addr,
 };
 
-static int __init sonic_probe1(struct net_device *dev)
+static int __devinit sonic_probe1(struct net_device *dev)
 {
 	static unsigned version_printed;
 	unsigned int silicon_revision;
@@ -203,7 +203,7 @@ static int __init sonic_probe1(struct net_device *dev)
 
 	return 0;
 out:
-	release_region(dev->base_addr, SONIC_MEM_SIZE);
+	release_mem_region(dev->base_addr, SONIC_MEM_SIZE);
 	return err;
 }
 
@@ -211,7 +211,7 @@ out:
  * Probe for a SONIC ethernet controller on a Mips Jazz board.
  * Actually probing is superfluous but we're paranoid.
  */
-static int __init jazz_sonic_probe(struct platform_device *pdev)
+static int __devinit jazz_sonic_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
 	struct sonic_local *lp;
@@ -247,7 +247,7 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
 	return 0;
 
 out1:
-	release_region(dev->base_addr, SONIC_MEM_SIZE);
+	release_mem_region(dev->base_addr, SONIC_MEM_SIZE);
 out:
 	free_netdev(dev);
 
@@ -269,7 +269,7 @@ static int __devexit jazz_sonic_device_remove (struct platform_device *pdev)
 	unregister_netdev(dev);
 	dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
 	                  lp->descriptors, lp->descriptors_laddr);
-	release_region (dev->base_addr, SONIC_MEM_SIZE);
+	release_mem_region(dev->base_addr, SONIC_MEM_SIZE);
 	free_netdev(dev);
 
 	return 0;
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index 1e3c63d..1d2a325 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -322,20 +322,6 @@ jme_stop_irq(struct jme_adapter *jme)
 	jwrite32f(jme, JME_IENC, INTR_ENABLE);
 }
 
-static inline void
-jme_enable_shadow(struct jme_adapter *jme)
-{
-	jwrite32(jme,
-		 JME_SHBA_LO,
-		 ((u32)jme->shadow_dma & ~((u32)0x1F)) | SHBA_POSTEN);
-}
-
-static inline void
-jme_disable_shadow(struct jme_adapter *jme)
-{
-	jwrite32(jme, JME_SHBA_LO, 0x0);
-}
-
 static u32
 jme_linkstat_from_phy(struct jme_adapter *jme)
 {
@@ -522,12 +508,8 @@ jme_setup_tx_resources(struct jme_adapter *jme)
 				   &(txring->dmaalloc),
 				   GFP_ATOMIC);
 
-	if (!txring->alloc) {
-		txring->desc = NULL;
-		txring->dmaalloc = 0;
-		txring->dma = 0;
-		return -ENOMEM;
-	}
+	if (!txring->alloc)
+		goto err_set_null;
 
 	/*
 	 * 16 Bytes align
@@ -539,6 +521,11 @@ jme_setup_tx_resources(struct jme_adapter *jme)
 	atomic_set(&txring->next_to_clean, 0);
 	atomic_set(&txring->nr_free, jme->tx_ring_size);
 
+	txring->bufinf		= kmalloc(sizeof(struct jme_buffer_info) *
+					jme->tx_ring_size, GFP_ATOMIC);
+	if (unlikely(!(txring->bufinf)))
+		goto err_free_txring;
+
 	/*
 	 * Initialize Transmit Descriptors
 	 */
@@ -547,6 +534,20 @@ jme_setup_tx_resources(struct jme_adapter *jme)
 		sizeof(struct jme_buffer_info) * jme->tx_ring_size);
 
 	return 0;
+
+err_free_txring:
+	dma_free_coherent(&(jme->pdev->dev),
+			  TX_RING_ALLOC_SIZE(jme->tx_ring_size),
+			  txring->alloc,
+			  txring->dmaalloc);
+
+err_set_null:
+	txring->desc = NULL;
+	txring->dmaalloc = 0;
+	txring->dma = 0;
+	txring->bufinf = NULL;
+
+	return -ENOMEM;
 }
 
 static void
@@ -554,19 +555,22 @@ jme_free_tx_resources(struct jme_adapter *jme)
 {
 	int i;
 	struct jme_ring *txring = &(jme->txring[0]);
-	struct jme_buffer_info *txbi = txring->bufinf;
+	struct jme_buffer_info *txbi;
 
 	if (txring->alloc) {
-		for (i = 0 ; i < jme->tx_ring_size ; ++i) {
-			txbi = txring->bufinf + i;
-			if (txbi->skb) {
-				dev_kfree_skb(txbi->skb);
-				txbi->skb = NULL;
+		if (txring->bufinf) {
+			for (i = 0 ; i < jme->tx_ring_size ; ++i) {
+				txbi = txring->bufinf + i;
+				if (txbi->skb) {
+					dev_kfree_skb(txbi->skb);
+					txbi->skb = NULL;
+				}
+				txbi->mapping		= 0;
+				txbi->len		= 0;
+				txbi->nr_desc		= 0;
+				txbi->start_xmit	= 0;
 			}
-			txbi->mapping		= 0;
-			txbi->len		= 0;
-			txbi->nr_desc		= 0;
-			txbi->start_xmit	= 0;
+			kfree(txring->bufinf);
 		}
 
 		dma_free_coherent(&(jme->pdev->dev),
@@ -578,11 +582,11 @@ jme_free_tx_resources(struct jme_adapter *jme)
 		txring->desc		= NULL;
 		txring->dmaalloc	= 0;
 		txring->dma		= 0;
+		txring->bufinf		= NULL;
 	}
 	txring->next_to_use	= 0;
 	atomic_set(&txring->next_to_clean, 0);
 	atomic_set(&txring->nr_free, 0);
-
 }
 
 static inline void
@@ -653,7 +657,7 @@ jme_disable_tx_engine(struct jme_adapter *jme)
 static void
 jme_set_clean_rxdesc(struct jme_adapter *jme, int i)
 {
-	struct jme_ring *rxring = jme->rxring;
+	struct jme_ring *rxring = &(jme->rxring[0]);
 	register struct rxdesc *rxdesc = rxring->desc;
 	struct jme_buffer_info *rxbi = rxring->bufinf;
 	rxdesc += i;
@@ -720,8 +724,11 @@ jme_free_rx_resources(struct jme_adapter *jme)
 	struct jme_ring *rxring = &(jme->rxring[0]);
 
 	if (rxring->alloc) {
-		for (i = 0 ; i < jme->rx_ring_size ; ++i)
-			jme_free_rx_buf(jme, i);
+		if (rxring->bufinf) {
+			for (i = 0 ; i < jme->rx_ring_size ; ++i)
+				jme_free_rx_buf(jme, i);
+			kfree(rxring->bufinf);
+		}
 
 		dma_free_coherent(&(jme->pdev->dev),
 				  RX_RING_ALLOC_SIZE(jme->rx_ring_size),
@@ -731,6 +738,7 @@ jme_free_rx_resources(struct jme_adapter *jme)
 		rxring->desc     = NULL;
 		rxring->dmaalloc = 0;
 		rxring->dma      = 0;
+		rxring->bufinf   = NULL;
 	}
 	rxring->next_to_use   = 0;
 	atomic_set(&rxring->next_to_clean, 0);
@@ -746,12 +754,8 @@ jme_setup_rx_resources(struct jme_adapter *jme)
 				   RX_RING_ALLOC_SIZE(jme->rx_ring_size),
 				   &(rxring->dmaalloc),
 				   GFP_ATOMIC);
-	if (!rxring->alloc) {
-		rxring->desc = NULL;
-		rxring->dmaalloc = 0;
-		rxring->dma = 0;
-		return -ENOMEM;
-	}
+	if (!rxring->alloc)
+		goto err_set_null;
 
 	/*
 	 * 16 Bytes align
@@ -762,9 +766,16 @@ jme_setup_rx_resources(struct jme_adapter *jme)
 	rxring->next_to_use	= 0;
 	atomic_set(&rxring->next_to_clean, 0);
 
+	rxring->bufinf		= kmalloc(sizeof(struct jme_buffer_info) *
+					jme->rx_ring_size, GFP_ATOMIC);
+	if (unlikely(!(rxring->bufinf)))
+		goto err_free_rxring;
+
 	/*
 	 * Initiallize Receive Descriptors
 	 */
+	memset(rxring->bufinf, 0,
+		sizeof(struct jme_buffer_info) * jme->rx_ring_size);
 	for (i = 0 ; i < jme->rx_ring_size ; ++i) {
 		if (unlikely(jme_make_new_rx_buf(jme, i))) {
 			jme_free_rx_resources(jme);
@@ -775,6 +786,19 @@ jme_setup_rx_resources(struct jme_adapter *jme)
 	}
 
 	return 0;
+
+err_free_rxring:
+	dma_free_coherent(&(jme->pdev->dev),
+			  RX_RING_ALLOC_SIZE(jme->rx_ring_size),
+			  rxring->alloc,
+			  rxring->dmaalloc);
+err_set_null:
+	rxring->desc = NULL;
+	rxring->dmaalloc = 0;
+	rxring->dma = 0;
+	rxring->bufinf = NULL;
+
+	return -ENOMEM;
 }
 
 static inline void
@@ -790,9 +814,9 @@ jme_enable_rx_engine(struct jme_adapter *jme)
 	/*
 	 * Setup RX DMA Bass Address
 	 */
-	jwrite32(jme, JME_RXDBA_LO, (__u64)jme->rxring[0].dma & 0xFFFFFFFFUL);
+	jwrite32(jme, JME_RXDBA_LO, (__u64)(jme->rxring[0].dma) & 0xFFFFFFFFUL);
 	jwrite32(jme, JME_RXDBA_HI, (__u64)(jme->rxring[0].dma) >> 32);
-	jwrite32(jme, JME_RXNDA, (__u64)jme->rxring[0].dma & 0xFFFFFFFFUL);
+	jwrite32(jme, JME_RXNDA, (__u64)(jme->rxring[0].dma) & 0xFFFFFFFFUL);
 
 	/*
 	 * Setup RX Descriptor Count
@@ -856,27 +880,27 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags)
 	if (!(flags & (RXWBFLAG_TCPON | RXWBFLAG_UDPON | RXWBFLAG_IPV4)))
 		return false;
 
-	if (unlikely(!(flags & RXWBFLAG_MF) &&
-	(flags & RXWBFLAG_TCPON) && !(flags & RXWBFLAG_TCPCS))) {
-		msg_rx_err(jme, "TCP Checksum error.\n");
-		goto out_sumerr;
+	if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_TCPON | RXWBFLAG_TCPCS))
+			== RXWBFLAG_TCPON)) {
+		if (flags & RXWBFLAG_IPV4)
+			msg_rx_err(jme, "TCP Checksum error\n");
+		return false;
 	}
 
-	if (unlikely(!(flags & RXWBFLAG_MF) &&
-	(flags & RXWBFLAG_UDPON) && !(flags & RXWBFLAG_UDPCS))) {
-		msg_rx_err(jme, "UDP Checksum error.\n");
-		goto out_sumerr;
+	if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS))
+			== RXWBFLAG_UDPON)) {
+		if (flags & RXWBFLAG_IPV4)
+			msg_rx_err(jme, "UDP Checksum error.\n");
+		return false;
 	}
 
-	if (unlikely((flags & RXWBFLAG_IPV4) && !(flags & RXWBFLAG_IPCS))) {
+	if (unlikely((flags & (RXWBFLAG_IPV4 | RXWBFLAG_IPCS))
+			== RXWBFLAG_IPV4)) {
 		msg_rx_err(jme, "IPv4 Checksum error.\n");
-		goto out_sumerr;
+		return false;
 	}
 
 	return true;
-
-out_sumerr:
-	return false;
 }
 
 static void
@@ -1296,7 +1320,7 @@ jme_rx_empty_tasklet(unsigned long arg)
 static void
 jme_wake_queue_if_stopped(struct jme_adapter *jme)
 {
-	struct jme_ring *txring = jme->txring;
+	struct jme_ring *txring = &(jme->txring[0]);
 
 	smp_wmb();
 	if (unlikely(netif_queue_stopped(jme->dev) &&
@@ -1483,12 +1507,7 @@ jme_msi(int irq, void *dev_id)
 	struct jme_adapter *jme = netdev_priv(netdev);
 	u32 intrstat;
 
-	pci_dma_sync_single_for_cpu(jme->pdev,
-				    jme->shadow_dma,
-				    sizeof(u32) * SHADOW_REG_NR,
-				    PCI_DMA_FROMDEVICE);
-	intrstat = jme->shadow_regs[SHADOW_IEVE];
-	jme->shadow_regs[SHADOW_IEVE] = 0;
+	intrstat = jread32(jme, JME_IEVE);
 
 	jme_intr_msi(jme, intrstat);
 
@@ -1566,6 +1585,7 @@ jme_open(struct net_device *netdev)
 	jme_clear_pm(jme);
 	JME_NAPI_ENABLE(jme);
 
+	tasklet_enable(&jme->linkch_task);
 	tasklet_enable(&jme->txclean_task);
 	tasklet_hi_enable(&jme->rxclean_task);
 	tasklet_hi_enable(&jme->rxempty_task);
@@ -1574,7 +1594,6 @@ jme_open(struct net_device *netdev)
 	if (rc)
 		goto err_out;
 
-	jme_enable_shadow(jme);
 	jme_start_irq(jme);
 
 	if (test_bit(JME_FLAG_SSET, &jme->flags))
@@ -1642,15 +1661,14 @@ jme_close(struct net_device *netdev)
 	netif_carrier_off(netdev);
 
 	jme_stop_irq(jme);
-	jme_disable_shadow(jme);
 	jme_free_irq(jme);
 
 	JME_NAPI_DISABLE(jme);
 
-	tasklet_kill(&jme->linkch_task);
-	tasklet_kill(&jme->txclean_task);
-	tasklet_kill(&jme->rxclean_task);
-	tasklet_kill(&jme->rxempty_task);
+	tasklet_disable(&jme->linkch_task);
+	tasklet_disable(&jme->txclean_task);
+	tasklet_disable(&jme->rxclean_task);
+	tasklet_disable(&jme->rxempty_task);
 
 	jme_reset_ghc_speed(jme);
 	jme_disable_rx_engine(jme);
@@ -1668,7 +1686,7 @@ static int
 jme_alloc_txdesc(struct jme_adapter *jme,
 			struct sk_buff *skb)
 {
-	struct jme_ring *txring = jme->txring;
+	struct jme_ring *txring = &(jme->txring[0]);
 	int idx, nr_alloc, mask = jme->tx_ring_mask;
 
 	idx = txring->next_to_use;
@@ -1722,7 +1740,7 @@ jme_fill_tx_map(struct pci_dev *pdev,
 static void
 jme_map_tx_skb(struct jme_adapter *jme, struct sk_buff *skb, int idx)
 {
-	struct jme_ring *txring = jme->txring;
+	struct jme_ring *txring = &(jme->txring[0]);
 	struct txdesc *txdesc = txring->desc, *ctxdesc;
 	struct jme_buffer_info *txbi = txring->bufinf, *ctxbi;
 	u8 hidma = jme->dev->features & NETIF_F_HIGHDMA;
@@ -1835,7 +1853,7 @@ jme_tx_vlan(struct sk_buff *skb, __le16 *vlan, u8 *flags)
 static int
 jme_fill_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
 {
-	struct jme_ring *txring = jme->txring;
+	struct jme_ring *txring = &(jme->txring[0]);
 	struct txdesc *txdesc;
 	struct jme_buffer_info *txbi;
 	u8 flags;
@@ -1883,7 +1901,7 @@ jme_fill_tx_desc(struct jme_adapter *jme, struct sk_buff *skb, int idx)
 static void
 jme_stop_queue_if_full(struct jme_adapter *jme)
 {
-	struct jme_ring *txring = jme->txring;
+	struct jme_ring *txring = &(jme->txring[0]);
 	struct jme_buffer_info *txbi = txring->bufinf;
 	int idx = atomic_read(&txring->next_to_clean);
 
@@ -1913,7 +1931,7 @@ jme_stop_queue_if_full(struct jme_adapter *jme)
  * This function is already protected by netif_tx_lock()
  */
 
-static int
+static netdev_tx_t
 jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct jme_adapter *jme = netdev_priv(netdev);
@@ -2725,14 +2743,6 @@ jme_init_one(struct pci_dev *pdev,
 		rc = -ENOMEM;
 		goto err_out_free_netdev;
 	}
-	jme->shadow_regs = pci_alloc_consistent(pdev,
-						sizeof(u32) * SHADOW_REG_NR,
-						&(jme->shadow_dma));
-	if (!(jme->shadow_regs)) {
-		jeprintk(pdev, "Allocating shadow register mapping error.\n");
-		rc = -ENOMEM;
-		goto err_out_unmap;
-	}
 
 	if (no_pseudohp) {
 		apmc = jread32(jme, JME_APMC) & ~JME_APMC_PSEUDO_HP_EN;
@@ -2768,6 +2778,7 @@ jme_init_one(struct pci_dev *pdev,
 	tasklet_init(&jme->rxempty_task,
 		     &jme_rx_empty_tasklet,
 		     (unsigned long) jme);
+	tasklet_disable_nosync(&jme->linkch_task);
 	tasklet_disable_nosync(&jme->txclean_task);
 	tasklet_disable_nosync(&jme->rxclean_task);
 	tasklet_disable_nosync(&jme->rxempty_task);
@@ -2817,7 +2828,7 @@ jme_init_one(struct pci_dev *pdev,
 		if (!jme->mii_if.phy_id) {
 			rc = -EIO;
 			jeprintk(pdev, "Can not find phy_id.\n");
-			 goto err_out_free_shadow;
+			 goto err_out_unmap;
 		}
 
 		jme->reg_ghc |= GHC_LINK_POLL;
@@ -2846,7 +2857,7 @@ jme_init_one(struct pci_dev *pdev,
 	if (rc) {
 		jeprintk(pdev,
 			"Reload eeprom for reading MAC Address error.\n");
-		goto err_out_free_shadow;
+		goto err_out_unmap;
 	}
 	jme_load_macaddr(netdev);
 
@@ -2862,7 +2873,7 @@ jme_init_one(struct pci_dev *pdev,
 	rc = register_netdev(netdev);
 	if (rc) {
 		jeprintk(pdev, "Cannot register net device.\n");
-		goto err_out_free_shadow;
+		goto err_out_unmap;
 	}
 
 	msg_probe(jme, "%s%s ver:%x rev:%x macaddr:%pM\n",
@@ -2876,11 +2887,6 @@ jme_init_one(struct pci_dev *pdev,
 
 	return 0;
 
-err_out_free_shadow:
-	pci_free_consistent(pdev,
-			    sizeof(u32) * SHADOW_REG_NR,
-			    jme->shadow_regs,
-			    jme->shadow_dma);
 err_out_unmap:
 	iounmap(jme->regs);
 err_out_free_netdev:
@@ -2901,10 +2907,6 @@ jme_remove_one(struct pci_dev *pdev)
 	struct jme_adapter *jme = netdev_priv(netdev);
 
 	unregister_netdev(netdev);
-	pci_free_consistent(pdev,
-			    sizeof(u32) * SHADOW_REG_NR,
-			    jme->shadow_regs,
-			    jme->shadow_dma);
 	iounmap(jme->regs);
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(netdev);
@@ -2930,8 +2932,6 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
 	tasklet_disable(&jme->rxclean_task);
 	tasklet_disable(&jme->rxempty_task);
 
-	jme_disable_shadow(jme);
-
 	if (netif_carrier_ok(netdev)) {
 		if (test_bit(JME_FLAG_POLL, &jme->flags))
 			jme_polling_mode(jme);
@@ -2983,7 +2983,6 @@ jme_resume(struct pci_dev *pdev)
 	else
 		jme_reset_phy_processor(jme);
 
-	jme_enable_shadow(jme);
 	jme_start_irq(jme);
 	netif_device_attach(netdev);
 
diff --git a/drivers/net/jme.h b/drivers/net/jme.h
index 0996a06..251abed 100644
--- a/drivers/net/jme.h
+++ b/drivers/net/jme.h
@@ -25,7 +25,7 @@
 #define __JME_H_INCLUDED__
 
 #define DRV_NAME	"jme"
-#define DRV_VERSION	"1.0.4"
+#define DRV_VERSION	"1.0.5"
 #define PFX		DRV_NAME ": "
 
 #define PCI_DEVICE_ID_JMICRON_JMC250	0x0250
@@ -247,7 +247,7 @@ enum jme_txdesc_flags_bits {
 };
 
 #define TXDESC_MSS_SHIFT	2
-enum jme_rxdescwb_flags_bits {
+enum jme_txwbdesc_flags_bits {
 	TXWBFLAG_OWN	= 0x80,
 	TXWBFLAG_INT	= 0x40,
 	TXWBFLAG_TMOUT	= 0x20,
@@ -372,7 +372,6 @@ struct jme_buffer_info {
 /*
  * The structure holding buffer information and ring descriptors all together.
  */
-#define MAX_RING_DESC_NR	1024
 struct jme_ring {
 	void *alloc;		/* pointer to allocated memory */
 	void *desc;		/* pointer to ring memory  */
@@ -380,7 +379,7 @@ struct jme_ring {
 	dma_addr_t dma;		/* phys address for ring dma */
 
 	/* Buffer information corresponding to each descriptor */
-	struct jme_buffer_info bufinf[MAX_RING_DESC_NR];
+	struct jme_buffer_info *bufinf;
 
 	int next_to_use;
 	atomic_t next_to_clean;
@@ -411,13 +410,10 @@ struct jme_ring {
 /*
  * Jmac Adapter Private data
  */
-#define SHADOW_REG_NR 8
 struct jme_adapter {
 	struct pci_dev          *pdev;
 	struct net_device       *dev;
 	void __iomem            *regs;
-	dma_addr_t		shadow_dma;
-	u32			*shadow_regs;
 	struct mii_if_info	mii_if;
 	struct jme_ring		rxring[RX_RING_NR];
 	struct jme_ring		txring[TX_RING_NR];
@@ -464,10 +460,6 @@ struct jme_adapter {
 	DECLARE_NET_DEVICE_STATS
 };
 
-enum shadow_reg_val {
-	SHADOW_IEVE = 0,
-};
-
 enum jme_flags_bits {
 	JME_FLAG_MSI		= 1,
 	JME_FLAG_SSET		= 2,
@@ -1104,13 +1096,6 @@ enum jme_chipmode_shifts {
 };
 
 /*
- * Shadow base address register bits
- */
-enum jme_shadow_base_address_bits {
-	SHBA_POSTEN	= 0x1,
-};
-
-/*
  * Aggressive Power Mode Control
  */
 enum jme_apmc_bits {
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index b4cf602..03199fa 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -338,7 +338,7 @@ static irqreturn_t korina_rx_dma_interrupt(int irq, void *dev_id)
 		napi_schedule(&lp->napi);
 
 		if (dmas & DMA_STAT_ERR)
-			printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name);
+			printk(KERN_ERR "%s: DMA error\n", dev->name);
 
 		retval = IRQ_HANDLED;
 	} else
@@ -555,7 +555,7 @@ static void korina_tx(struct net_device *dev)
 			dev->stats.tx_dropped++;
 
 			/* Should never happen */
-			printk(KERN_ERR DRV_NAME "%s: split tx ignored\n",
+			printk(KERN_ERR "%s: split tx ignored\n",
 							dev->name);
 		} else if (devcs & ETH_TX_TOK) {
 			dev->stats.tx_packets++;
@@ -641,7 +641,7 @@ korina_tx_dma_interrupt(int irq, void *dev_id)
 			dev->trans_start = jiffies;
 		}
 		if (dmas & DMA_STAT_ERR)
-			printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name);
+			printk(KERN_ERR "%s: DMA error\n", dev->name);
 
 		retval = IRQ_HANDLED;
 	} else
@@ -743,14 +743,14 @@ static u32 netdev_get_link(struct net_device *dev)
 	return mii_link_ok(&lp->mii_if);
 }
 
-static struct ethtool_ops netdev_ethtool_ops = {
+static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_drvinfo            = netdev_get_drvinfo,
 	.get_settings           = netdev_get_settings,
 	.set_settings           = netdev_set_settings,
 	.get_link               = netdev_get_link,
 };
 
-static void korina_alloc_ring(struct net_device *dev)
+static int korina_alloc_ring(struct net_device *dev)
 {
 	struct korina_private *lp = netdev_priv(dev);
 	struct sk_buff *skb;
@@ -771,7 +771,7 @@ static void korina_alloc_ring(struct net_device *dev)
 	for (i = 0; i < KORINA_NUM_RDS; i++) {
 		skb = dev_alloc_skb(KORINA_RBSIZE + 2);
 		if (!skb)
-			break;
+			return -ENOMEM;
 		skb_reserve(skb, 2);
 		lp->rx_skb[i] = skb;
 		lp->rd_ring[i].control = DMA_DESC_IOD |
@@ -790,6 +790,8 @@ static void korina_alloc_ring(struct net_device *dev)
 	lp->rx_chain_head = 0;
 	lp->rx_chain_tail = 0;
 	lp->rx_chain_status = desc_empty;
+
+	return 0;
 }
 
 static void korina_free_ring(struct net_device *dev)
@@ -832,7 +834,11 @@ static int korina_init(struct net_device *dev)
 	writel(ETH_INT_FC_EN, &lp->eth_regs->ethintfc);
 
 	/* Allocate rings */
-	korina_alloc_ring(dev);
+	if (korina_alloc_ring(dev)) {
+		printk(KERN_ERR "%s: descriptor allocation failed\n", dev->name);
+		korina_free_ring(dev);
+		return -ENOMEM;
+	}
 
 	writel(0, &lp->rx_dma_regs->dmas);
 	/* Start Rx DMA */
@@ -917,8 +923,7 @@ static int korina_restart(struct net_device *dev)
 
 	ret = korina_init(dev);
 	if (ret < 0) {
-		printk(KERN_ERR DRV_NAME "%s: cannot restart device\n",
-								dev->name);
+		printk(KERN_ERR "%s: cannot restart device\n", dev->name);
 		return ret;
 	}
 	korina_multicast_list(dev);
@@ -1005,7 +1010,7 @@ static int korina_open(struct net_device *dev)
 	/* Initialize */
 	ret = korina_init(dev);
 	if (ret < 0) {
-		printk(KERN_ERR DRV_NAME "%s: cannot open device\n", dev->name);
+		printk(KERN_ERR "%s: cannot open device\n", dev->name);
 		goto out;
 	}
 
@@ -1015,14 +1020,14 @@ static int korina_open(struct net_device *dev)
 	ret = request_irq(lp->rx_irq, &korina_rx_dma_interrupt,
 			IRQF_DISABLED, "Korina ethernet Rx", dev);
 	if (ret < 0) {
-		printk(KERN_ERR DRV_NAME "%s: unable to get Rx DMA IRQ %d\n",
+		printk(KERN_ERR "%s: unable to get Rx DMA IRQ %d\n",
 		    dev->name, lp->rx_irq);
 		goto err_release;
 	}
 	ret = request_irq(lp->tx_irq, &korina_tx_dma_interrupt,
 			IRQF_DISABLED, "Korina ethernet Tx", dev);
 	if (ret < 0) {
-		printk(KERN_ERR DRV_NAME "%s: unable to get Tx DMA IRQ %d\n",
+		printk(KERN_ERR "%s: unable to get Tx DMA IRQ %d\n",
 		    dev->name, lp->tx_irq);
 		goto err_free_rx_irq;
 	}
@@ -1031,7 +1036,7 @@ static int korina_open(struct net_device *dev)
 	ret = request_irq(lp->ovr_irq, &korina_ovr_interrupt,
 			IRQF_DISABLED, "Ethernet Overflow", dev);
 	if (ret < 0) {
-		printk(KERN_ERR DRV_NAME"%s: unable to get OVR IRQ %d\n",
+		printk(KERN_ERR "%s: unable to get OVR IRQ %d\n",
 		    dev->name, lp->ovr_irq);
 		goto err_free_tx_irq;
 	}
@@ -1040,7 +1045,7 @@ static int korina_open(struct net_device *dev)
 	ret = request_irq(lp->und_irq, &korina_und_interrupt,
 			IRQF_DISABLED, "Ethernet Underflow", dev);
 	if (ret < 0) {
-		printk(KERN_ERR DRV_NAME "%s: unable to get UND IRQ %d\n",
+		printk(KERN_ERR "%s: unable to get UND IRQ %d\n",
 		    dev->name, lp->und_irq);
 		goto err_free_ovr_irq;
 	}
@@ -1137,7 +1142,7 @@ static int korina_probe(struct platform_device *pdev)
 	dev->base_addr = r->start;
 	lp->eth_regs = ioremap_nocache(r->start, r->end - r->start);
 	if (!lp->eth_regs) {
-		printk(KERN_ERR DRV_NAME "cannot remap registers\n");
+		printk(KERN_ERR DRV_NAME ": cannot remap registers\n");
 		rc = -ENXIO;
 		goto probe_err_out;
 	}
@@ -1145,7 +1150,7 @@ static int korina_probe(struct platform_device *pdev)
 	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_rx");
 	lp->rx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
 	if (!lp->rx_dma_regs) {
-		printk(KERN_ERR DRV_NAME "cannot remap Rx DMA registers\n");
+		printk(KERN_ERR DRV_NAME ": cannot remap Rx DMA registers\n");
 		rc = -ENXIO;
 		goto probe_err_dma_rx;
 	}
@@ -1153,14 +1158,14 @@ static int korina_probe(struct platform_device *pdev)
 	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "korina_dma_tx");
 	lp->tx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
 	if (!lp->tx_dma_regs) {
-		printk(KERN_ERR DRV_NAME "cannot remap Tx DMA registers\n");
+		printk(KERN_ERR DRV_NAME ": cannot remap Tx DMA registers\n");
 		rc = -ENXIO;
 		goto probe_err_dma_tx;
 	}
 
 	lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
 	if (!lp->td_ring) {
-		printk(KERN_ERR DRV_NAME "cannot allocate descriptors\n");
+		printk(KERN_ERR DRV_NAME ": cannot allocate descriptors\n");
 		rc = -ENXIO;
 		goto probe_err_td_ring;
 	}
@@ -1193,10 +1198,13 @@ static int korina_probe(struct platform_device *pdev)
 	rc = register_netdev(dev);
 	if (rc < 0) {
 		printk(KERN_ERR DRV_NAME
-			": cannot register net device %d\n", rc);
+			": cannot register net device: %d\n", rc);
 		goto probe_err_register;
 	}
 	setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev);
+
+	printk(KERN_INFO "%s: " DRV_NAME "-" DRV_VERSION " " DRV_RELDATE "\n",
+			dev->name);
 out:
 	return rc;
 
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c
index 39b0aea..99e9541 100644
--- a/drivers/net/ks8842.c
+++ b/drivers/net/ks8842.c
@@ -551,7 +551,8 @@ static int ks8842_close(struct net_device *netdev)
 	return 0;
 }
 
-static int ks8842_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t ks8842_xmit_frame(struct sk_buff *skb,
+				     struct net_device *netdev)
 {
 	int ret;
 	struct ks8842_adapter *adapter = netdev_priv(netdev);
@@ -618,7 +619,7 @@ static const struct net_device_ops ks8842_netdev_ops = {
 	.ndo_validate_addr	= eth_validate_addr
 };
 
-static struct ethtool_ops ks8842_ethtool_ops = {
+static const struct ethtool_ops ks8842_ethtool_ops = {
 	.get_link		= ethtool_op_get_link,
 };
 
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c
index 9a1dea6..547ac7c 100644
--- a/drivers/net/ks8851.c
+++ b/drivers/net/ks8851.c
@@ -868,11 +868,12 @@ static int ks8851_net_stop(struct net_device *dev)
  * and secondly so we can round up more than one packet to transmit which
  * means we can try and avoid generating too many transmit done interrupts.
  */
-static int ks8851_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ks8851_start_xmit(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct ks8851_net *ks = netdev_priv(dev);
 	unsigned needed = calc_txlen(skb->len);
-	int ret = NETDEV_TX_OK;
+	netdev_tx_t ret = NETDEV_TX_OK;
 
 	if (netif_msg_tx_queued(ks))
 		ks_dbg(ks, "%s: skb %p, %d@%p\n", __func__,
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 633808d..dcda303 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -300,7 +300,8 @@ static unsigned char lance_need_isa_bounce_buffers = 1;
 
 static int lance_open(struct net_device *dev);
 static void lance_init_ring(struct net_device *dev, gfp_t mode);
-static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev);
 static int lance_rx(struct net_device *dev);
 static irqreturn_t lance_interrupt(int irq, void *dev_id);
 static int lance_close(struct net_device *dev);
@@ -949,7 +950,8 @@ static void lance_tx_timeout (struct net_device *dev)
 }
 
 
-static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct lance_private *lp = dev->ml_priv;
 	int ioaddr = dev->base_addr;
@@ -1016,7 +1018,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 out:
 	spin_unlock_irqrestore(&lp->devlock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The LANCE interrupt handler. */
diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c
index 070fa45..51e11c3 100644
--- a/drivers/net/lib82596.c
+++ b/drivers/net/lib82596.c
@@ -983,7 +983,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 
@@ -1028,7 +1028,7 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	netif_start_queue(dev);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void print_eth(unsigned char *add, char *str)
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index f28c233..2561198 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -299,7 +299,8 @@ static void __ei_tx_timeout(struct net_device *dev)
  * Sends a packet to an 8390 network device.
  */
 
-static int __ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t __ei_start_xmit(struct sk_buff *skb,
+				   struct net_device *dev)
 {
 	unsigned long e8390_base = dev->base_addr;
 	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
@@ -414,7 +415,7 @@ static int __ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb (skb);
 	dev->stats.tx_bytes += send_length;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
index 96e7248..da8d0a0 100644
--- a/drivers/net/ll_temac_main.c
+++ b/drivers/net/ll_temac_main.c
@@ -591,7 +591,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	/* Kick off the transfer */
 	temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index da472c6..1bc654a 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -69,7 +69,8 @@ struct pcpu_lstats {
  * The higher levels take care of making this non-reentrant (it's
  * called with bh's disabled).
  */
-static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t loopback_xmit(struct sk_buff *skb,
+				 struct net_device *dev)
 {
 	struct pcpu_lstats *pcpu_lstats, *lb_stats;
 	int len;
@@ -89,7 +90,7 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 	} else
 		lb_stats->drops++;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static struct net_device_stats *loopback_get_stats(struct net_device *dev)
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index d44bddb..cc3ed9c 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -377,7 +377,7 @@ static char init_setup[14] = {
 };
 
 static int i596_open(struct net_device *dev);
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t i596_interrupt(int irq, void *dev_id);
 static int i596_close(struct net_device *dev);
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
@@ -863,7 +863,7 @@ static int i596_open(struct net_device *dev)
 	return 0;			/* Always succeed */
 }
 
-static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
+static netdev_tx_t i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
 	struct tx_cmd *tx_cmd;
 	short length;
 
@@ -871,7 +871,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
 
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 
@@ -906,7 +906,7 @@ static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) {
 		dev->stats.tx_packets++;
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index dab4533..149e0ed 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -411,7 +411,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 	dev_kfree_skb (skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The typical workload of the driver:
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index e3601cf..fb65b42 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -679,7 +679,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void macb_free_consistent(struct macb *bp)
@@ -1079,7 +1079,7 @@ static void macb_get_drvinfo(struct net_device *dev,
 	strcpy(info->bus_info, dev_name(&bp->pdev->dev));
 }
 
-static struct ethtool_ops macb_ethtool_ops = {
+static const struct ethtool_ops macb_ethtool_ops = {
 	.get_settings		= macb_get_settings,
 	.set_settings		= macb_set_settings,
 	.get_drvinfo		= macb_get_drvinfo,
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 1427755..7d7577b 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -581,7 +581,7 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 	netif_stop_queue(dev);
     spin_unlock_irqrestore(&mp->lock, flags);
 
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 static void mace_set_multicast(struct net_device *dev)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 99eed9f..3aabfd9 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -54,7 +54,7 @@ static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
 	struct hlist_node *n;
 
 	hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[addr[5]], hlist) {
-		if (!compare_ether_addr(vlan->dev->dev_addr, addr))
+		if (!compare_ether_addr_64bits(vlan->dev->dev_addr, addr))
 			return vlan;
 	}
 	return NULL;
@@ -92,7 +92,7 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
 	 * currently in use by the underlying device or
 	 * another macvlan.
 	 */
-	if (memcmp(port->dev->dev_addr, addr, ETH_ALEN) == 0)
+	if (!compare_ether_addr_64bits(port->dev->dev_addr, addr))
 		return 1;
 
 	if (macvlan_hash_lookup(port, addr))
@@ -130,7 +130,7 @@ static void macvlan_broadcast(struct sk_buff *skb,
 			dev->stats.multicast++;
 
 			nskb->dev = dev;
-			if (!compare_ether_addr(eth->h_dest, dev->broadcast))
+			if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast))
 				nskb->pkt_type = PACKET_BROADCAST;
 			else
 				nskb->pkt_type = PACKET_MULTICAST;
@@ -184,8 +184,11 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
 	return NULL;
 }
 
-static int macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
+	int i = skb_get_queue_mapping(skb);
+	struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
 	const struct macvlan_dev *vlan = netdev_priv(dev);
 	unsigned int len = skb->len;
 	int ret;
@@ -194,12 +197,11 @@ static int macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	ret = dev_queue_xmit(skb);
 
 	if (likely(ret == NET_XMIT_SUCCESS)) {
-		dev->stats.tx_packets++;
-		dev->stats.tx_bytes += len;
-	} else {
-		dev->stats.tx_errors++;
-		dev->stats.tx_aborted_errors++;
-	}
+		txq->tx_packets++;
+		txq->tx_bytes += len;
+	} else
+		txq->tx_dropped++;
+
 	return NETDEV_TX_OK;
 }
 
@@ -483,6 +485,25 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
 	return 0;
 }
 
+static int macvlan_get_tx_queues(struct net *net,
+				 struct nlattr *tb[],
+				 unsigned int *num_tx_queues,
+				 unsigned int *real_num_tx_queues)
+{
+	struct net_device *real_dev;
+
+	if (!tb[IFLA_LINK])
+		return -EINVAL;
+
+	real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
+	if (!real_dev)
+		return -ENODEV;
+
+	*num_tx_queues      = real_dev->num_tx_queues;
+	*real_num_tx_queues = real_dev->real_num_tx_queues;
+	return 0;
+}
+
 static int macvlan_newlink(struct net_device *dev,
 			   struct nlattr *tb[], struct nlattr *data[])
 {
@@ -549,6 +570,7 @@ static void macvlan_dellink(struct net_device *dev)
 static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
 	.kind		= "macvlan",
 	.priv_size	= sizeof(struct macvlan_dev),
+	.get_tx_queues  = macvlan_get_tx_queues,
 	.setup		= macvlan_setup,
 	.validate	= macvlan_validate,
 	.newlink	= macvlan_newlink,
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
index 6851bdb..21f8754 100644
--- a/drivers/net/mdio.c
+++ b/drivers/net/mdio.c
@@ -109,13 +109,20 @@ int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmd_mask)
 		if (mmd_mask & (1 << devad)) {
 			mmd_mask &= ~(1 << devad);
 
-			/* Read twice because link state is latched and a
-			 * read moves the current state into the register */
+			/* Reset the latched status and fault flags */
 			mdio->mdio_read(mdio->dev, mdio->prtad,
 					devad, MDIO_STAT1);
+			if (devad == MDIO_MMD_PMAPMD || devad == MDIO_MMD_PCS ||
+			    devad == MDIO_MMD_PHYXS || devad == MDIO_MMD_DTEXS)
+				mdio->mdio_read(mdio->dev, mdio->prtad,
+						devad, MDIO_STAT2);
+
+			/* Check the current status and fault flags */
 			reg = mdio->mdio_read(mdio->dev, mdio->prtad,
 					      devad, MDIO_STAT1);
-			if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
+			if (reg < 0 ||
+			    (reg & (MDIO_STAT1_FAULT | MDIO_STAT1_LSTATUS)) !=
+			    MDIO_STAT1_LSTATUS)
 				return false;
 		}
 	}
@@ -373,10 +380,7 @@ int mdio_mii_ioctl(const struct mdio_if_info *mdio,
 		cmd = SIOCGMIIREG;
 		break;
 	case SIOCGMIIREG:
-		break;
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		break;
 	default:
 		return -EOPNOTSUPP;
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 5d04d94..92ceb68 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -715,7 +715,7 @@ static int meth_tx(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irqrestore(&priv->meth_lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -784,7 +784,7 @@ static const struct net_device_ops meth_netdev_ops = {
 /*
  * The init function.
  */
-static int __init meth_probe(struct platform_device *pdev)
+static int __devinit meth_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
 	struct meth_private *priv;
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index d81a5d2..210b2b1 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -433,9 +433,6 @@ int generic_mii_ioctl(struct mii_if_info *mii_if,
 	case SIOCSMIIREG: {
 		u16 val = mii_data->val_in;
 
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		if (mii_data->phy_id == mii_if->phy_id) {
 			switch(mii_data->reg_num) {
 			case MII_BMCR: {
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index b3b9a14..8ea98bd 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -141,7 +141,7 @@ static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
 	netif_stop_queue(dev);
 	mipsnet_put_todevice(dev, skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t len)
diff --git a/drivers/net/mlx4/catas.c b/drivers/net/mlx4/catas.c
index aa9674b..f599294 100644
--- a/drivers/net/mlx4/catas.c
+++ b/drivers/net/mlx4/catas.c
@@ -96,12 +96,17 @@ static void catas_reset(struct work_struct *work)
 	spin_unlock_irq(&catas_lock);
 
 	list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list) {
+		struct pci_dev *pdev = priv->dev.pdev;
+
 		ret = mlx4_restart_one(priv->dev.pdev);
-		dev = &priv->dev;
+		/* 'priv' now is not valid */
 		if (ret)
-			mlx4_err(dev, "Reset failed (%d)\n", ret);
-		else
+			printk(KERN_ERR "mlx4 %s: Reset failed (%d)\n",
+				pci_name(pdev), ret);
+		else {
+			dev  = pci_get_drvdata(pdev);
 			mlx4_dbg(dev, "Reset succeeded\n");
+		}
 	}
 }
 
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 9ed4a15..507e11f 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -218,8 +218,9 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
 	mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
 		mlx4_info(mdev, "Using %d tx rings for port:%d\n",
 			  mdev->profile.prof[i].tx_ring_num, i);
-		mdev->profile.prof[i].rx_ring_num =
-			min_t(int, dev->caps.num_comp_vectors, MAX_RX_RINGS);
+		mdev->profile.prof[i].rx_ring_num = min_t(int,
+			roundup_pow_of_two(dev->caps.num_comp_vectors),
+			MAX_RX_RINGS);
 		mlx4_info(mdev, "Defaulting to %d rx rings for port:%d\n",
 			  mdev->profile.prof[i].rx_ring_num, i);
 	}
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 93f4abd..c48b0f4 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -414,6 +414,7 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
 	unsigned long avg_pkt_size;
 	unsigned long rx_packets;
 	unsigned long rx_bytes;
+	unsigned long rx_byte_diff;
 	unsigned long tx_packets;
 	unsigned long tx_pkt_diff;
 	unsigned long rx_pkt_diff;
@@ -437,6 +438,8 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
 	rx_pkt_diff = ((unsigned long) (rx_packets -
 					priv->last_moder_packets));
 	packets = max(tx_pkt_diff, rx_pkt_diff);
+	rx_byte_diff = rx_bytes - priv->last_moder_bytes;
+	rx_byte_diff = rx_byte_diff ? rx_byte_diff : 1;
 	rate = packets * HZ / period;
 	avg_pkt_size = packets ? ((unsigned long) (rx_bytes -
 				 priv->last_moder_bytes)) / packets : 0;
@@ -447,10 +450,13 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
 		/* If tx and rx packet rates are not balanced, assume that
 		 * traffic is mainly BW bound and apply maximum moderation.
 		 * Otherwise, moderate according to packet rate */
-		if (2 * tx_pkt_diff > 3 * rx_pkt_diff ||
-		    2 * rx_pkt_diff > 3 * tx_pkt_diff) {
+		if (2 * tx_pkt_diff > 3 * rx_pkt_diff &&
+		    rx_pkt_diff / rx_byte_diff <
+		    MLX4_EN_SMALL_PKT_SIZE)
+			moder_time = priv->rx_usecs_low;
+		else if (2 * rx_pkt_diff > 3 * tx_pkt_diff)
 			moder_time = priv->rx_usecs_high;
-		} else {
+		else {
 			if (rate < priv->pkt_rate_low)
 				moder_time = priv->rx_usecs_low;
 			else if (rate > priv->pkt_rate_high)
@@ -616,8 +622,7 @@ int mlx4_en_start_port(struct net_device *dev)
 
 		/* Configure ring */
 		tx_ring = &priv->tx_ring[i];
-		err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
-					       priv->rx_ring[0].srq.srqn);
+		err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn);
 		if (err) {
 			en_err(priv, "Failed allocating Tx ring\n");
 			mlx4_en_deactivate_cq(priv, cq);
@@ -1005,9 +1010,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
 	if (err)
 		goto out;
 
-	/* Populate Rx default RSS mappings */
-	mlx4_en_set_default_rss_map(priv, &priv->rss_map, priv->rx_ring_num *
-						RSS_FACTOR, priv->rx_ring_num);
 	/* Allocate page for receive rings */
 	err = mlx4_alloc_hwq_res(mdev->dev, &priv->res,
 				MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE);
diff --git a/drivers/net/mlx4/en_resources.c b/drivers/net/mlx4/en_resources.c
index 65ca706..1625678 100644
--- a/drivers/net/mlx4/en_resources.c
+++ b/drivers/net/mlx4/en_resources.c
@@ -37,7 +37,7 @@
 #include "mlx4_en.h"
 
 void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
-			     int is_tx, int rss, int qpn, int cqn, int srqn,
+			     int is_tx, int rss, int qpn, int cqn,
 			     struct mlx4_qp_context *context)
 {
 	struct mlx4_en_dev *mdev = priv->mdev;
@@ -46,11 +46,12 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
 	context->flags = cpu_to_be32(7 << 16 | rss << 13);
 	context->pd = cpu_to_be32(mdev->priv_pdn);
 	context->mtu_msgmax = 0xff;
-	context->rq_size_stride = 0;
+	if (!is_tx && !rss)
+		context->rq_size_stride = ilog2(size) << 3 | (ilog2(stride) - 4);
 	if (is_tx)
 		context->sq_size_stride = ilog2(size) << 3 | (ilog2(stride) - 4);
 	else
-		context->sq_size_stride = 1;
+		context->sq_size_stride = ilog2(TXBB_SIZE) - 4;
 	context->usr_page = cpu_to_be32(mdev->priv_uar.index);
 	context->local_qpn = cpu_to_be32(qpn);
 	context->pri_path.ackto = 1 & 0x07;
@@ -59,8 +60,6 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
 	context->cqn_send = cpu_to_be32(cqn);
 	context->cqn_recv = cpu_to_be32(cqn);
 	context->db_rec_addr = cpu_to_be64(priv->res.db.dma << 2);
-	if (!rss)
-		context->srqn = cpu_to_be32(MLX4_EN_USE_SRQ | srqn);
 }
 
 
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 3ac0404..03b781a 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -40,16 +40,6 @@
 
 #include "mlx4_en.h"
 
-static void *get_wqe(struct mlx4_en_rx_ring *ring, int n)
-{
-	int offset = n << ring->srq.wqe_shift;
-	return ring->buf + offset;
-}
-
-static void mlx4_en_srq_event(struct mlx4_srq *srq, enum mlx4_event type)
-{
-	return;
-}
 
 static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr,
 				   void **ip_hdr, void **tcpudp_hdr,
@@ -154,9 +144,6 @@ static void mlx4_en_init_rx_desc(struct mlx4_en_priv *priv,
 	int possible_frags;
 	int i;
 
-	/* Pre-link descriptor */
-	rx_desc->next.next_wqe_index = cpu_to_be16((index + 1) & ring->size_mask);
-
 	/* Set size and memtype fields */
 	for (i = 0; i < priv->num_frags; i++) {
 		skb_frags[i].size = priv->frag_info[i].frag_size;
@@ -294,9 +281,6 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
 	int err;
 	int tmp;
 
-	/* Sanity check SRQ size before proceeding */
-	if (size >= mdev->dev->caps.max_srq_wqes)
-		return -EINVAL;
 
 	ring->prod = 0;
 	ring->cons = 0;
@@ -304,7 +288,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
 	ring->size_mask = size - 1;
 	ring->stride = stride;
 	ring->log_stride = ffs(ring->stride) - 1;
-	ring->buf_size = ring->size * ring->stride;
+	ring->buf_size = ring->size * ring->stride + TXBB_SIZE;
 
 	tmp = size * roundup_pow_of_two(MLX4_EN_MAX_RX_FRAGS *
 					sizeof(struct skb_frag_struct));
@@ -360,15 +344,12 @@ err_ring:
 
 int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
 {
-	struct mlx4_en_dev *mdev = priv->mdev;
-	struct mlx4_wqe_srq_next_seg *next;
 	struct mlx4_en_rx_ring *ring;
 	int i;
 	int ring_ind;
 	int err;
 	int stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
 					DS_SIZE * priv->num_frags);
-	int max_gs = (stride - sizeof(struct mlx4_wqe_srq_next_seg)) / DS_SIZE;
 
 	for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
 		ring = &priv->rx_ring[ring_ind];
@@ -379,6 +360,9 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
 		ring->cqn = priv->rx_cq[ring_ind].mcq.cqn;
 
 		ring->stride = stride;
+		if (ring->stride <= TXBB_SIZE)
+			ring->buf += TXBB_SIZE;
+
 		ring->log_stride = ffs(ring->stride) - 1;
 		ring->buf_size = ring->size * ring->stride;
 
@@ -405,37 +389,10 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
 		ring = &priv->rx_ring[ring_ind];
 
 		mlx4_en_update_rx_prod_db(ring);
-
-		/* Configure SRQ representing the ring */
-		ring->srq.max    = ring->actual_size;
-		ring->srq.max_gs = max_gs;
-		ring->srq.wqe_shift = ilog2(ring->stride);
-
-		for (i = 0; i < ring->srq.max; ++i) {
-			next = get_wqe(ring, i);
-			next->next_wqe_index =
-			cpu_to_be16((i + 1) & (ring->srq.max - 1));
-		}
-
-		err = mlx4_srq_alloc(mdev->dev, mdev->priv_pdn, &ring->wqres.mtt,
-				     ring->wqres.db.dma, &ring->srq);
-		if (err){
-			en_err(priv, "Failed to allocate srq\n");
-			ring_ind--;
-			goto err_srq;
-		}
-		ring->srq.event = mlx4_en_srq_event;
 	}
 
 	return 0;
 
-err_srq:
-	while (ring_ind >= 0) {
-		ring = &priv->rx_ring[ring_ind];
-		mlx4_srq_free(mdev->dev, &ring->srq);
-		ring_ind--;
-	}
-
 err_buffers:
 	for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++)
 		mlx4_en_free_rx_buf(priv, &priv->rx_ring[ring_ind]);
@@ -456,7 +413,7 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
 
 	kfree(ring->lro.lro_arr);
 	mlx4_en_unmap_buffer(&ring->wqres.buf);
-	mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size);
+	mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE);
 	vfree(ring->rx_info);
 	ring->rx_info = NULL;
 }
@@ -464,10 +421,9 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv,
 void mlx4_en_deactivate_rx_ring(struct mlx4_en_priv *priv,
 				struct mlx4_en_rx_ring *ring)
 {
-	struct mlx4_en_dev *mdev = priv->mdev;
-
-	mlx4_srq_free(mdev->dev, &ring->srq);
 	mlx4_en_free_rx_buf(priv, ring);
+	if (ring->stride <= TXBB_SIZE)
+		ring->buf -= TXBB_SIZE;
 	mlx4_en_destroy_allocator(priv, ring);
 }
 
@@ -836,25 +792,8 @@ void mlx4_en_calc_rx_buf(struct net_device *dev)
 
 /* RSS related functions */
 
-/* Calculate rss size and map each entry in rss table to rx ring */
-void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
-				 struct mlx4_en_rss_map *rss_map,
-				 int num_entries, int num_rings)
-{
-	int i;
-
-	rss_map->size = roundup_pow_of_two(num_entries);
-	en_dbg(DRV, priv, "Setting default RSS map of %d entires\n",
-	       rss_map->size);
-
-	for (i = 0; i < rss_map->size; i++) {
-		rss_map->map[i] = i % num_rings;
-		en_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]);
-	}
-}
-
-static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
-				 int qpn, int srqn, int cqn,
+static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn,
+				 struct mlx4_en_rx_ring *ring,
 				 enum mlx4_qp_state *state,
 				 struct mlx4_qp *qp)
 {
@@ -876,13 +815,16 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
 	qp->event = mlx4_en_sqp_event;
 
 	memset(context, 0, sizeof *context);
-	mlx4_en_fill_qp_context(priv, 0, 0, 0, 0, qpn, cqn, srqn, context);
+	mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 0, 0,
+				qpn, ring->cqn, context);
+	context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma);
 
-	err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, context, qp, state);
+	err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, context, qp, state);
 	if (err) {
 		mlx4_qp_remove(mdev->dev, qp);
 		mlx4_qp_free(mdev->dev, qp);
 	}
+	mlx4_en_update_rx_prod_db(ring);
 out:
 	kfree(context);
 	return err;
@@ -898,23 +840,22 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
 	void *ptr;
 	int rss_xor = mdev->profile.rss_xor;
 	u8 rss_mask = mdev->profile.rss_mask;
-	int i, srqn, qpn, cqn;
+	int i, qpn;
 	int err = 0;
 	int good_qps = 0;
 
 	en_dbg(DRV, priv, "Configuring rss steering\n");
-	err = mlx4_qp_reserve_range(mdev->dev, rss_map->size,
-				    rss_map->size, &rss_map->base_qpn);
+	err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num,
+				    priv->rx_ring_num,
+				    &rss_map->base_qpn);
 	if (err) {
-		en_err(priv, "Failed reserving %d qps\n", rss_map->size);
+		en_err(priv, "Failed reserving %d qps\n", priv->rx_ring_num);
 		return err;
 	}
 
-	for (i = 0; i < rss_map->size; i++) {
-		cqn = priv->rx_ring[rss_map->map[i]].cqn;
-		srqn = priv->rx_ring[rss_map->map[i]].srq.srqn;
+	for (i = 0; i < priv->rx_ring_num; i++) {
 		qpn = rss_map->base_qpn + i;
-		err = mlx4_en_config_rss_qp(priv, qpn, srqn, cqn,
+		err = mlx4_en_config_rss_qp(priv, qpn, &priv->rx_ring[i],
 					    &rss_map->state[i],
 					    &rss_map->qps[i]);
 		if (err)
@@ -937,11 +878,11 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
 	}
 	rss_map->indir_qp.event = mlx4_en_sqp_event;
 	mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
-				priv->rx_ring[0].cqn, 0, &context);
+				priv->rx_ring[0].cqn, &context);
 
 	ptr = ((void *) &context) + 0x3c;
 	rss_context = (struct mlx4_en_rss_context *) ptr;
-	rss_context->base_qpn = cpu_to_be32(ilog2(rss_map->size) << 24 |
+	rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 |
 					    (rss_map->base_qpn));
 	rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn);
 	rss_context->hash_fn = rss_xor & 0x3;
@@ -968,7 +909,7 @@ rss_err:
 		mlx4_qp_remove(mdev->dev, &rss_map->qps[i]);
 		mlx4_qp_free(mdev->dev, &rss_map->qps[i]);
 	}
-	mlx4_qp_release_range(mdev->dev, rss_map->base_qpn, rss_map->size);
+	mlx4_qp_release_range(mdev->dev, rss_map->base_qpn, priv->rx_ring_num);
 	return err;
 }
 
@@ -984,13 +925,13 @@ void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv)
 	mlx4_qp_free(mdev->dev, &rss_map->indir_qp);
 	mlx4_qp_release_range(mdev->dev, priv->base_qpn, 1);
 
-	for (i = 0; i < rss_map->size; i++) {
+	for (i = 0; i < priv->rx_ring_num; i++) {
 		mlx4_qp_modify(mdev->dev, NULL, rss_map->state[i],
 			       MLX4_QP_STATE_RST, NULL, 0, 0, &rss_map->qps[i]);
 		mlx4_qp_remove(mdev->dev, &rss_map->qps[i]);
 		mlx4_qp_free(mdev->dev, &rss_map->qps[i]);
 	}
-	mlx4_qp_release_range(mdev->dev, rss_map->base_qpn, rss_map->size);
+	mlx4_qp_release_range(mdev->dev, rss_map->base_qpn, priv->rx_ring_num);
 }
 
 
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 6220840..8c72799 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -150,7 +150,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
 
 int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
 			     struct mlx4_en_tx_ring *ring,
-			     int cq, int srqn)
+			     int cq)
 {
 	struct mlx4_en_dev *mdev = priv->mdev;
 	int err;
@@ -168,7 +168,7 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
 	ring->doorbell_qpn = swab32(ring->qp.qpn << 8);
 
 	mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
-				ring->cqn, srqn, &ring->context);
+				ring->cqn, &ring->context);
 
 	err = mlx4_qp_to_ready(mdev->dev, &ring->wqres.mtt, &ring->context,
 			       &ring->qp, &ring->qp_state);
@@ -589,7 +589,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
 	return skb_tx_hash(dev, skb);
 }
 
-int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct mlx4_en_priv *priv = netdev_priv(dev);
 	struct mlx4_en_dev *mdev = priv->mdev;
@@ -766,7 +766,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Poll CQ here */
 	mlx4_en_xmit_poll(priv, tx_ind);
 
-	return 0;
+	return NETDEV_TX_OK;
 
 tx_drop:
 	dev_kfree_skb_any(skb);
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index c7c5e86..4376147 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -95,8 +95,6 @@
 #define MLX4_EN_PAGE_SIZE	(1 << MLX4_EN_PAGE_SHIFT)
 #define MAX_TX_RINGS		16
 #define MAX_RX_RINGS		16
-#define MAX_RSS_MAP_SIZE	64
-#define RSS_FACTOR		2
 #define TXBB_SIZE		64
 #define HEADROOM		(2048 / TXBB_SIZE + 1)
 #define STAMP_STRIDE		64
@@ -276,13 +274,11 @@ struct mlx4_en_tx_ring {
 };
 
 struct mlx4_en_rx_desc {
-	struct mlx4_wqe_srq_next_seg next;
 	/* actual number of entries depends on rx ring stride */
 	struct mlx4_wqe_data_seg data[0];
 };
 
 struct mlx4_en_rx_ring {
-	struct mlx4_srq srq;
 	struct mlx4_hwq_resources wqres;
 	struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS];
 	struct net_lro_mgr lro;
@@ -377,11 +373,9 @@ struct mlx4_en_dev {
 
 
 struct mlx4_en_rss_map {
-	int size;
 	int base_qpn;
-	u16 map[MAX_RSS_MAP_SIZE];
-	struct mlx4_qp qps[MAX_RSS_MAP_SIZE];
-	enum mlx4_qp_state state[MAX_RSS_MAP_SIZE];
+	struct mlx4_qp qps[MAX_RX_RINGS];
+	enum mlx4_qp_state state[MAX_RX_RINGS];
 	struct mlx4_qp indir_qp;
 	enum mlx4_qp_state indir_state;
 };
@@ -524,14 +518,14 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
 void mlx4_en_poll_tx_cq(unsigned long data);
 void mlx4_en_tx_irq(struct mlx4_cq *mcq);
 u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb);
-int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
 
 int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring,
 			   u32 size, u16 stride);
 void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring);
 int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
 			     struct mlx4_en_tx_ring *ring,
-			     int cq, int srqn);
+			     int cq);
 void mlx4_en_deactivate_tx_ring(struct mlx4_en_priv *priv,
 				struct mlx4_en_tx_ring *ring);
 
@@ -548,16 +542,13 @@ int mlx4_en_process_rx_cq(struct net_device *dev,
 			  int budget);
 int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
 void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
-			     int is_tx, int rss, int qpn, int cqn, int srqn,
+			     int is_tx, int rss, int qpn, int cqn,
 			     struct mlx4_qp_context *context);
 void mlx4_en_sqp_event(struct mlx4_qp *qp, enum mlx4_event event);
 int mlx4_en_map_buffer(struct mlx4_buf *buf);
 void mlx4_en_unmap_buffer(struct mlx4_buf *buf);
 
 void mlx4_en_calc_rx_buf(struct net_device *dev);
-void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
-				 struct mlx4_en_rss_map *rss_map,
-				 int num_entries, int num_rings);
 int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv);
 void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv);
 int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring);
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 0f32db3..b62e61d 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1066,40 +1066,6 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)
 	}
 }
 
-static void txq_set_wrr(struct tx_queue *txq, int weight)
-{
-	struct mv643xx_eth_private *mp = txq_to_mp(txq);
-	int off;
-	u32 val;
-
-	/*
-	 * Turn off fixed priority mode.
-	 */
-	off = 0;
-	switch (mp->shared->tx_bw_control) {
-	case TX_BW_CONTROL_OLD_LAYOUT:
-		off = TXQ_FIX_PRIO_CONF;
-		break;
-	case TX_BW_CONTROL_NEW_LAYOUT:
-		off = TXQ_FIX_PRIO_CONF_MOVED;
-		break;
-	}
-
-	if (off) {
-		val = rdlp(mp, off);
-		val &= ~(1 << txq->index);
-		wrlp(mp, off, val);
-
-		/*
-		 * Configure WRR weight for this queue.
-		 */
-
-		val = rdlp(mp, off);
-		val = (val & ~0xff) | (weight & 0xff);
-		wrlp(mp, TXQ_BW_WRR_CONF(txq->index), val);
-	}
-}
-
 
 /* mii management interface *************************************************/
 static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 1f6e36e..6930c87 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.5.0-1.418"
+#define MYRI10GE_VERSION_STR "1.5.0-1.432"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -188,6 +188,7 @@ struct myri10ge_slice_state {
 	dma_addr_t fw_stats_bus;
 	int watchdog_tx_done;
 	int watchdog_tx_req;
+	int watchdog_rx_done;
 #ifdef CONFIG_MYRI10GE_DCA
 	int cached_dca_tag;
 	int cpu;
@@ -256,6 +257,7 @@ struct myri10ge_priv {
 	u32 link_changes;
 	u32 msg_enable;
 	unsigned int board_number;
+	int rebooted;
 };
 
 static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
@@ -358,7 +360,8 @@ MODULE_PARM_DESC(myri10ge_dca, "Enable DCA if possible");
 #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
 
 static void myri10ge_set_multicast_list(struct net_device *dev);
-static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t myri10ge_sw_tso(struct sk_buff *skb,
+					 struct net_device *dev);
 
 static inline void put_be32(__be32 val, __be32 __iomem * p)
 {
@@ -2552,17 +2555,22 @@ static int myri10ge_close(struct net_device *dev)
 	netif_carrier_off(dev);
 
 	netif_tx_stop_all_queues(dev);
-	old_down_cnt = mgp->down_cnt;
-	mb();
-	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_DOWN, &cmd, 0);
-	if (status)
-		printk(KERN_ERR "myri10ge: %s: Couldn't bring down link\n",
-		       dev->name);
-
-	wait_event_timeout(mgp->down_wq, old_down_cnt != mgp->down_cnt, HZ);
-	if (old_down_cnt == mgp->down_cnt)
-		printk(KERN_ERR "myri10ge: %s never got down irq\n", dev->name);
+	if (mgp->rebooted == 0) {
+		old_down_cnt = mgp->down_cnt;
+		mb();
+		status =
+		    myri10ge_send_cmd(mgp, MXGEFW_CMD_ETHERNET_DOWN, &cmd, 0);
+		if (status)
+			printk(KERN_ERR
+			       "myri10ge: %s: Couldn't bring down link\n",
+			       dev->name);
 
+		wait_event_timeout(mgp->down_wq, old_down_cnt != mgp->down_cnt,
+				   HZ);
+		if (old_down_cnt == mgp->down_cnt)
+			printk(KERN_ERR "myri10ge: %s never got down irq\n",
+			       dev->name);
+	}
 	netif_tx_disable(dev);
 	myri10ge_free_irq(mgp);
 	for (i = 0; i < mgp->num_slices; i++)
@@ -2649,7 +2657,8 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
  * it and try again.
  */
 
-static int myri10ge_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t myri10ge_xmit(struct sk_buff *skb,
+				       struct net_device *dev)
 {
 	struct myri10ge_priv *mgp = netdev_priv(dev);
 	struct myri10ge_slice_state *ss;
@@ -2748,7 +2757,7 @@ again:
 				/* The packet is gone, so we must
 				 * return 0 */
 				ss->stats.tx_dropped += 1;
-				return 0;
+				return NETDEV_TX_OK;
 			}
 			/* adjust the len to account for the zero pad
 			 * so that the nic can know how long it is */
@@ -2892,7 +2901,7 @@ again:
 		tx->stop_queue++;
 		netif_tx_stop_queue(netdev_queue);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 
 abort_linearize:
 	/* Free any DMA resources we've alloced and clear out the skb
@@ -2936,16 +2945,17 @@ abort_linearize:
 drop:
 	dev_kfree_skb_any(skb);
 	ss->stats.tx_dropped += 1;
-	return 0;
+	return NETDEV_TX_OK;
 
 }
 
-static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t myri10ge_sw_tso(struct sk_buff *skb,
+					 struct net_device *dev)
 {
 	struct sk_buff *segs, *curr;
 	struct myri10ge_priv *mgp = netdev_priv(dev);
 	struct myri10ge_slice_state *ss;
-	int status;
+	netdev_tx_t status;
 
 	segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6);
 	if (IS_ERR(segs))
@@ -2968,13 +2978,13 @@ static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 	dev_kfree_skb_any(skb);
-	return 0;
+	return NETDEV_TX_OK;
 
 drop:
 	ss = &mgp->ss[skb_get_queue_mapping(skb)];
 	dev_kfree_skb_any(skb);
 	ss->stats.tx_dropped += 1;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
@@ -3427,12 +3437,13 @@ static void myri10ge_watchdog(struct work_struct *work)
 	    container_of(work, struct myri10ge_priv, watchdog_work);
 	struct myri10ge_tx_buf *tx;
 	u32 reboot;
-	int status;
+	int status, rebooted;
 	int i;
 	u16 cmd, vendor;
 
 	mgp->watchdog_resets++;
 	pci_read_config_word(mgp->pdev, PCI_COMMAND, &cmd);
+	rebooted = 0;
 	if ((cmd & PCI_COMMAND_MASTER) == 0) {
 		/* Bus master DMA disabled?  Check to see
 		 * if the card rebooted due to a parity error
@@ -3444,9 +3455,12 @@ static void myri10ge_watchdog(struct work_struct *work)
 		       myri10ge_reset_recover ? " " : " not");
 		if (myri10ge_reset_recover == 0)
 			return;
-
+		rtnl_lock();
+		mgp->rebooted = 1;
+		rebooted = 1;
+		myri10ge_close(mgp->dev);
 		myri10ge_reset_recover--;
-
+		mgp->rebooted = 0;
 		/*
 		 * A rebooted nic will come back with config space as
 		 * it was after power was applied to PCIe bus.
@@ -3494,8 +3508,10 @@ static void myri10ge_watchdog(struct work_struct *work)
 		}
 	}
 
-	rtnl_lock();
-	myri10ge_close(mgp->dev);
+	if (!rebooted) {
+		rtnl_lock();
+		myri10ge_close(mgp->dev);
+	}
 	status = myri10ge_load_firmware(mgp, 1);
 	if (status != 0)
 		printk(KERN_ERR "myri10ge: %s: failed to load firmware\n",
@@ -3516,12 +3532,14 @@ static void myri10ge_watchdog_timer(unsigned long arg)
 {
 	struct myri10ge_priv *mgp;
 	struct myri10ge_slice_state *ss;
-	int i, reset_needed;
+	int i, reset_needed, busy_slice_cnt;
 	u32 rx_pause_cnt;
+	u16 cmd;
 
 	mgp = (struct myri10ge_priv *)arg;
 
 	rx_pause_cnt = ntohl(mgp->ss[0].fw_stats->dropped_pause);
+	busy_slice_cnt = 0;
 	for (i = 0, reset_needed = 0;
 	     i < mgp->num_slices && reset_needed == 0; ++i) {
 
@@ -3559,8 +3577,22 @@ static void myri10ge_watchdog_timer(unsigned long arg)
 				reset_needed = 1;
 			}
 		}
+		if (ss->watchdog_tx_done != ss->tx.done ||
+		    ss->watchdog_rx_done != ss->rx_done.cnt) {
+			busy_slice_cnt++;
+		}
 		ss->watchdog_tx_done = ss->tx.done;
 		ss->watchdog_tx_req = ss->tx.req;
+		ss->watchdog_rx_done = ss->rx_done.cnt;
+	}
+	/* if we've sent or received no traffic, poll the NIC to
+	 * ensure it is still there.  Otherwise, we risk not noticing
+	 * an error in a timely fashion */
+	if (busy_slice_cnt == 0) {
+		pci_read_config_word(mgp->pdev, PCI_COMMAND, &cmd);
+		if ((cmd & PCI_COMMAND_MASTER) == 0) {
+			reset_needed = 1;
+		}
 	}
 	mgp->watchdog_pause = rx_pause_cnt;
 
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 5f0758b..29ebebc 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -692,7 +692,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	DTX(("tbusy=0, returning 0\n"));
 	netif_start_queue(dev);
 	spin_unlock_irqrestore(&mp->irq_lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* Create the MyriNet MAC header for an arbitrary protocol layer
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 78c0883..b2722c4 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -621,7 +621,7 @@ static void drain_ring(struct net_device *dev);
 static void free_ring(struct net_device *dev);
 static void reinit_ring(struct net_device *dev);
 static void init_registers(struct net_device *dev);
-static int start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void netdev_error(struct net_device *dev, int intr_status);
 static int natsemi_poll(struct napi_struct *napi, int budget);
@@ -2079,7 +2079,7 @@ static void reinit_ring(struct net_device *dev)
 	reinit_rx(dev);
 }
 
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
 	void __iomem * ioaddr = ns_ioaddr(dev);
@@ -2125,7 +2125,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
 			dev->name, np->cur_tx, entry);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void netdev_tx_done(struct net_device *dev)
@@ -3053,12 +3053,10 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 	switch(cmd) {
 	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
-	case SIOCDEVPRIVATE:		/* for binary compat, remove in 2.5 */
 		data->phy_id = np->phy_addr_external;
 		/* Fall Through */
 
 	case SIOCGMIIREG:		/* Read MII PHY register. */
-	case SIOCDEVPRIVATE+1:		/* for binary compat, remove in 2.5 */
 		/* The phy_id is not enough to uniquely identify
 		 * the intended target. Therefore the command is sent to
 		 * the given mii on the current port.
@@ -3077,9 +3075,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		return 0;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-	case SIOCDEVPRIVATE+2:		/* for binary compat, remove in 2.5 */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if (dev->if_port == PORT_TP) {
 			if ((data->phy_id & 0x1f) == np->phy_addr_external) {
  				if ((data->reg_num & 0x1f) == MII_ADVERTISE)
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index 946366d..9f42354 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -134,7 +134,7 @@ netx_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	spin_unlock_irq(&priv->lock);
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void netx_eth_receive(struct net_device *ndev)
diff --git a/drivers/net/netxen/Makefile b/drivers/net/netxen/Makefile
index cf01a91..11d94e2 100644
--- a/drivers/net/netxen/Makefile
+++ b/drivers/net/netxen/Makefile
@@ -1,4 +1,5 @@
 # Copyright (C) 2003 - 2009 NetXen, Inc.
+# Copyright (C) 2009 - QLogic Corporation.
 # All rights reserved.
 # 
 # This program is free software; you can redistribute it and/or
@@ -19,16 +20,10 @@
 # The full GNU General Public License is included in this distribution
 # in the file called LICENSE.
 # 
-# Contact Information:
-#    info@netxen.com
-# NetXen Inc,
-# 18922 Forge Drive
-# Cupertino, CA 95014-0701
-#
 #
 
 
 obj-$(CONFIG_NETXEN_NIC) := netxen_nic.o
 
 netxen_nic-y := netxen_nic_hw.o netxen_nic_main.o netxen_nic_init.o \
-	netxen_nic_ethtool.o netxen_nic_niu.o netxen_nic_ctx.o
+	netxen_nic_ethtool.o netxen_nic_ctx.o
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index a9c1fcc..7384f59 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #ifndef _NETXEN_NIC_H_
@@ -53,12 +48,13 @@
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
+#include "netxen_nic_hdr.h"
 #include "netxen_nic_hw.h"
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 30
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.30"
+#define _NETXEN_NIC_LINUX_SUBVERSION 50
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.50"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 24) + ((b) << 16) + (c))
 #define _major(v)	(((v) >> 24) & 0xff)
@@ -143,18 +139,14 @@
 #define NX_ETHERMTU                    1500
 #define NX_MAX_ETHERHDR                32 /* This contains some padding */
 
-#define NX_RX_NORMAL_BUF_MAX_LEN       (NX_MAX_ETHERHDR + NX_ETHERMTU)
+#define NX_P2_RX_BUF_MAX_LEN           1760
+#define NX_P3_RX_BUF_MAX_LEN           (NX_MAX_ETHERHDR + NX_ETHERMTU)
 #define NX_P2_RX_JUMBO_BUF_MAX_LEN     (NX_MAX_ETHERHDR + P2_MAX_MTU)
 #define NX_P3_RX_JUMBO_BUF_MAX_LEN     (NX_MAX_ETHERHDR + P3_MAX_MTU)
 #define NX_CT_DEFAULT_RX_BUF_LEN	2048
+#define NX_LRO_BUFFER_EXTRA		2048
 
-#define MAX_RX_BUFFER_LENGTH		1760
-#define MAX_RX_JUMBO_BUFFER_LENGTH 	8062
-#define MAX_RX_LRO_BUFFER_LENGTH	(8062)
-#define RX_DMA_MAP_LEN			(MAX_RX_BUFFER_LENGTH - 2)
-#define RX_JUMBO_DMA_MAP_LEN	\
-	(MAX_RX_JUMBO_BUFFER_LENGTH - 2)
-#define RX_LRO_DMA_MAP_LEN		(MAX_RX_LRO_BUFFER_LENGTH - 2)
+#define NX_RX_LRO_BUFFER_LENGTH		(8060)
 
 /*
  * Maximum number of ring contexts
@@ -181,6 +173,7 @@
 
 #define MAX_BUFFERS_PER_CMD	32
 #define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + 4)
+#define NX_MAX_TX_TIMEOUTS	2
 
 /*
  * Following are the states of the Phantom. Phantom will set them and
@@ -200,13 +193,20 @@
 #define RCV_RING_JUMBO	1
 #define RCV_RING_LRO	2
 
-#define MAX_CMD_DESCRIPTORS		4096
-#define MAX_RCV_DESCRIPTORS		16384
-#define MAX_CMD_DESCRIPTORS_HOST	1024
-#define MAX_RCV_DESCRIPTORS_1G		2048
-#define MAX_RCV_DESCRIPTORS_10G		4096
-#define MAX_JUMBO_RCV_DESCRIPTORS	1024
+#define MIN_CMD_DESCRIPTORS		64
+#define MIN_RCV_DESCRIPTORS		64
+#define MIN_JUMBO_DESCRIPTORS		32
+
+#define MAX_CMD_DESCRIPTORS		1024
+#define MAX_RCV_DESCRIPTORS_1G		4096
+#define MAX_RCV_DESCRIPTORS_10G		8192
+#define MAX_JUMBO_RCV_DESCRIPTORS_1G	512
+#define MAX_JUMBO_RCV_DESCRIPTORS_10G	1024
 #define MAX_LRO_RCV_DESCRIPTORS		8
+
+#define DEFAULT_RCV_DESCRIPTORS_1G	2048
+#define DEFAULT_RCV_DESCRIPTORS_10G	4096
+
 #define NETXEN_CTX_SIGNATURE	0xdee0
 #define NETXEN_CTX_SIGNATURE_V2	0x0002dee0
 #define NETXEN_CTX_RESET	0xbad0
@@ -225,7 +225,7 @@
 #define MPORT_SINGLE_FUNCTION_MODE 0x1111
 #define MPORT_MULTI_FUNCTION_MODE 0x2222
 
-#include "netxen_nic_phan_reg.h"
+#define NX_MAX_PCI_FUNC		8
 
 /*
  * NetXen host-peg signal message structure
@@ -302,6 +302,10 @@ struct netxen_ring_ctx {
 #define FLAGS_IPSEC_SA_ADD	0x04
 #define FLAGS_IPSEC_SA_DELETE	0x08
 #define FLAGS_VLAN_TAGGED	0x10
+#define FLAGS_VLAN_OOB		0x40
+
+#define netxen_set_tx_vlan_tci(cmd_desc, v)	\
+	(cmd_desc)->vlan_TCI = cpu_to_le16(v);
 
 #define netxen_set_cmd_desc_port(cmd_desc, var)	\
 	((cmd_desc)->port_ctxid |= ((var) & 0x0F))
@@ -316,58 +320,33 @@ struct netxen_ring_ctx {
 	cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7))
 
 #define netxen_set_tx_frags_len(_desc, _frags, _len) \
-	(_desc)->num_of_buffers_total_length = \
+	(_desc)->nfrags__length = \
 	cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8))
 
 struct cmd_desc_type0 {
 	u8 tcp_hdr_offset;	/* For LSO only */
 	u8 ip_hdr_offset;	/* For LSO only */
-	/* Bit pattern: 0-6 flags, 7-12 opcode, 13-15 unused */
-	__le16 flags_opcode;
-	/* Bit pattern: 0-7 total number of segments,
-	   8-31 Total size of the packet */
-	__le32 num_of_buffers_total_length;
-	union {
-		struct {
-			__le32 addr_low_part2;
-			__le32 addr_high_part2;
-		};
-		__le64 addr_buffer2;
-	};
+	__le16 flags_opcode;	/* 15:13 unused, 12:7 opcode, 6:0 flags */
+	__le32 nfrags__length;	/* 31:8 total len, 7:0 frag count */
 
-	__le16 reference_handle;	/* changed to u16 to add mss */
-	__le16 mss;		/* passed by NDIS_PACKET for LSO */
-	/* Bit pattern 0-3 port, 0-3 ctx id */
-	u8 port_ctxid;
+	__le64 addr_buffer2;
+
+	__le16 reference_handle;
+	__le16 mss;
+	u8 port_ctxid;		/* 7:4 ctxid 3:0 port */
 	u8 total_hdr_length;	/* LSO only : MAC+IP+TCP Hdr size */
 	__le16 conn_id;		/* IPSec offoad only */
 
-	union {
-		struct {
-			__le32 addr_low_part3;
-			__le32 addr_high_part3;
-		};
-		__le64 addr_buffer3;
-	};
-	union {
-		struct {
-			__le32 addr_low_part1;
-			__le32 addr_high_part1;
-		};
-		__le64 addr_buffer1;
-	};
+	__le64 addr_buffer3;
+	__le64 addr_buffer1;
 
 	__le16 buffer_length[4];
 
-	union {
-		struct {
-			__le32 addr_low_part4;
-			__le32 addr_high_part4;
-		};
-		__le64 addr_buffer4;
-	};
+	__le64 addr_buffer4;
 
-	__le64 unused;
+	__le32 reserved2;
+	__le16 reserved;
+	__le16 vlan_TCI;
 
 } __attribute__ ((aligned(64)));
 
@@ -380,9 +359,11 @@ struct rcv_desc {
 };
 
 /* opcode field in status_desc */
+#define NETXEN_NIC_SYN_OFFLOAD  0x03
 #define NETXEN_NIC_RXPKT_DESC  0x04
 #define NETXEN_OLD_RXPKT_DESC  0x3f
 #define NETXEN_NIC_RESPONSE_DESC 0x05
+#define NETXEN_NIC_LRO_DESC  	0x12
 
 /* for status field in status_desc */
 #define STATUS_NEED_CKSUM	(1)
@@ -416,6 +397,24 @@ struct rcv_desc {
 #define netxen_get_sts_opcode(sts_data)	\
 	(((sts_data) >> 58) & 0x03F)
 
+#define netxen_get_lro_sts_refhandle(sts_data) 	\
+	((sts_data) & 0x0FFFF)
+#define netxen_get_lro_sts_length(sts_data)	\
+	(((sts_data) >> 16) & 0x0FFFF)
+#define netxen_get_lro_sts_l2_hdr_offset(sts_data)	\
+	(((sts_data) >> 32) & 0x0FF)
+#define netxen_get_lro_sts_l4_hdr_offset(sts_data)	\
+	(((sts_data) >> 40) & 0x0FF)
+#define netxen_get_lro_sts_timestamp(sts_data)	\
+	(((sts_data) >> 48) & 0x1)
+#define netxen_get_lro_sts_type(sts_data)	\
+	(((sts_data) >> 49) & 0x7)
+#define netxen_get_lro_sts_push_flag(sts_data)		\
+	(((sts_data) >> 52) & 0x1)
+#define netxen_get_lro_sts_seq_number(sts_data)		\
+	((sts_data) & 0x0FFFFFFFF)
+
+
 struct status_desc {
 	__le64 status_desc_data[2];
 } __attribute__ ((aligned(16)));
@@ -459,154 +458,6 @@ struct status_desc {
 #define NETXEN_BRDTYPE_P3_10G_XFP	0x0032
 #define NETXEN_BRDTYPE_P3_10G_TP	0x0080
 
-struct netxen_board_info {
-	u32 header_version;
-
-	u32 board_mfg;
-	u32 board_type;
-	u32 board_num;
-	u32 chip_id;
-	u32 chip_minor;
-	u32 chip_major;
-	u32 chip_pkg;
-	u32 chip_lot;
-
-	u32 port_mask;		/* available niu ports */
-	u32 peg_mask;		/* available pegs */
-	u32 icache_ok;		/* can we run with icache? */
-	u32 dcache_ok;		/* can we run with dcache? */
-	u32 casper_ok;
-
-	u32 mac_addr_lo_0;
-	u32 mac_addr_lo_1;
-	u32 mac_addr_lo_2;
-	u32 mac_addr_lo_3;
-
-	/* MN-related config */
-	u32 mn_sync_mode;	/* enable/ sync shift cclk/ sync shift mclk */
-	u32 mn_sync_shift_cclk;
-	u32 mn_sync_shift_mclk;
-	u32 mn_wb_en;
-	u32 mn_crystal_freq;	/* in MHz */
-	u32 mn_speed;		/* in MHz */
-	u32 mn_org;
-	u32 mn_depth;
-	u32 mn_ranks_0;		/* ranks per slot */
-	u32 mn_ranks_1;		/* ranks per slot */
-	u32 mn_rd_latency_0;
-	u32 mn_rd_latency_1;
-	u32 mn_rd_latency_2;
-	u32 mn_rd_latency_3;
-	u32 mn_rd_latency_4;
-	u32 mn_rd_latency_5;
-	u32 mn_rd_latency_6;
-	u32 mn_rd_latency_7;
-	u32 mn_rd_latency_8;
-	u32 mn_dll_val[18];
-	u32 mn_mode_reg;	/* MIU DDR Mode Register */
-	u32 mn_ext_mode_reg;	/* MIU DDR Extended Mode Register */
-	u32 mn_timing_0;	/* MIU Memory Control Timing Rgister */
-	u32 mn_timing_1;	/* MIU Extended Memory Ctrl Timing Register */
-	u32 mn_timing_2;	/* MIU Extended Memory Ctrl Timing2 Register */
-
-	/* SN-related config */
-	u32 sn_sync_mode;	/* enable/ sync shift cclk / sync shift mclk */
-	u32 sn_pt_mode;		/* pass through mode */
-	u32 sn_ecc_en;
-	u32 sn_wb_en;
-	u32 sn_crystal_freq;
-	u32 sn_speed;
-	u32 sn_org;
-	u32 sn_depth;
-	u32 sn_dll_tap;
-	u32 sn_rd_latency;
-
-	u32 mac_addr_hi_0;
-	u32 mac_addr_hi_1;
-	u32 mac_addr_hi_2;
-	u32 mac_addr_hi_3;
-
-	u32 magic;		/* indicates flash has been initialized */
-
-	u32 mn_rdimm;
-	u32 mn_dll_override;
-
-};
-
-#define FLASH_NUM_PORTS		(4)
-
-struct netxen_flash_mac_addr {
-	u32 flash_addr[32];
-};
-
-struct netxen_user_old_info {
-	u8 flash_md5[16];
-	u8 crbinit_md5[16];
-	u8 brdcfg_md5[16];
-	/* bootloader */
-	u32 bootld_version;
-	u32 bootld_size;
-	u8 bootld_md5[16];
-	/* image */
-	u32 image_version;
-	u32 image_size;
-	u8 image_md5[16];
-	/* primary image status */
-	u32 primary_status;
-	u32 secondary_present;
-
-	/* MAC address , 4 ports */
-	struct netxen_flash_mac_addr mac_addr[FLASH_NUM_PORTS];
-};
-#define FLASH_NUM_MAC_PER_PORT	32
-struct netxen_user_info {
-	u8 flash_md5[16 * 64];
-	/* bootloader */
-	u32 bootld_version;
-	u32 bootld_size;
-	/* image */
-	u32 image_version;
-	u32 image_size;
-	/* primary image status */
-	u32 primary_status;
-	u32 secondary_present;
-
-	/* MAC address , 4 ports, 32 address per port */
-	u64 mac_addr[FLASH_NUM_PORTS * FLASH_NUM_MAC_PER_PORT];
-	u32 sub_sys_id;
-	u8 serial_num[32];
-
-	/* Any user defined data */
-};
-
-/*
- * Flash Layout - new format.
- */
-struct netxen_new_user_info {
-	u8 flash_md5[16 * 64];
-	/* bootloader */
-	u32 bootld_version;
-	u32 bootld_size;
-	/* image */
-	u32 image_version;
-	u32 image_size;
-	/* primary image status */
-	u32 primary_status;
-	u32 secondary_present;
-
-	/* MAC address , 4 ports, 32 address per port */
-	u64 mac_addr[FLASH_NUM_PORTS * FLASH_NUM_MAC_PER_PORT];
-	u32 sub_sys_id;
-	u8 serial_num[32];
-
-	/* Any user defined data */
-};
-
-#define SECONDARY_IMAGE_PRESENT 0xb3b4b5b6
-#define SECONDARY_IMAGE_ABSENT	0xffffffff
-#define PRIMARY_IMAGE_GOOD	0x5a5a5a5a
-#define PRIMARY_IMAGE_BAD	0xffffffff
-
 /* Flash memory map */
 #define NETXEN_CRBINIT_START	0	/* crbinit section */
 #define NETXEN_BRDCFG_START	0x4000	/* board config */
@@ -617,28 +468,25 @@ struct netxen_new_user_info {
 #define NETXEN_PXE_START	0x3E0000	/* PXE boot rom */
 #define NETXEN_USER_START	0x3E8000	/* Firmare info */
 #define NETXEN_FIXED_START	0x3F0000	/* backup of crbinit */
+#define NETXEN_USER_START_OLD	NETXEN_PXE_START /* very old flash */
 
+#define NX_OLD_MAC_ADDR_OFFSET	(NETXEN_USER_START)
 #define NX_FW_VERSION_OFFSET	(NETXEN_USER_START+0x408)
 #define NX_FW_SIZE_OFFSET	(NETXEN_USER_START+0x40c)
+#define NX_FW_MAC_ADDR_OFFSET	(NETXEN_USER_START+0x418)
+#define NX_FW_SERIAL_NUM_OFFSET	(NETXEN_USER_START+0x81c)
 #define NX_BIOS_VERSION_OFFSET	(NETXEN_USER_START+0x83c)
+
+#define NX_HDR_VERSION_OFFSET	(NETXEN_BRDCFG_START)
+#define NX_BRDTYPE_OFFSET	(NETXEN_BRDCFG_START+0x8)
 #define NX_FW_MAGIC_OFFSET	(NETXEN_BRDCFG_START+0x128)
+
 #define NX_FW_MIN_SIZE		(0x3fffff)
 #define NX_P2_MN_ROMIMAGE	0
 #define NX_P3_CT_ROMIMAGE	1
 #define NX_P3_MN_ROMIMAGE	2
 #define NX_FLASH_ROMIMAGE	3
 
-#define NETXEN_USER_START_OLD NETXEN_PXE_START	/* for backward compatibility */
-
-#define NETXEN_FLASH_START		(NETXEN_CRBINIT_START)
-#define NETXEN_INIT_SECTOR		(0)
-#define NETXEN_PRIMARY_START 		(NETXEN_BOOTLD_START)
-#define NETXEN_FLASH_CRBINIT_SIZE 	(0x4000)
-#define NETXEN_FLASH_BRDCFG_SIZE 	(sizeof(struct netxen_board_info))
-#define NETXEN_FLASH_USER_SIZE		(sizeof(struct netxen_user_info)/sizeof(u32))
-#define NETXEN_FLASH_SECONDARY_SIZE 	(NETXEN_USER_START-NETXEN_SECONDARY_START)
-#define NETXEN_NUM_PRIMARY_SECTORS	(0x20)
-#define NETXEN_NUM_CONFIG_SECTORS 	(1)
 extern char netxen_nic_driver_name[];
 
 /* Number of status descriptors to handle per interrupt */
@@ -653,17 +501,11 @@ struct netxen_skb_frag {
 	u64 length;
 };
 
-#define _netxen_set_bits(config_word, start, bits, val)	{\
-	unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));\
-	unsigned long long __tvalue = (val);    \
-	(config_word) &= ~__tmask;      \
-	(config_word) |= (((__tvalue) << (start)) & __tmask); \
-}
-
-#define _netxen_clear_bits(config_word, start, bits) {\
-	unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));  \
-	(config_word) &= ~__tmask; \
-}
+struct netxen_recv_crb {
+	u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
+	u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
+	u32 sw_int_mask[NUM_STS_DESC_RINGS];
+};
 
 /*    Following defines are for the state of the buffers    */
 #define	NETXEN_BUFFER_FREE	0
@@ -706,8 +548,8 @@ struct netxen_hardware_context {
 
 	int qdr_sn_window;
 	int ddr_mn_window;
-	unsigned long mn_win_crb;
-	unsigned long ms_win_crb;
+	u32 mn_win_crb;
+	u32 ms_win_crb;
 
 	u8 cut_through;
 	u8 revision_id;
@@ -726,7 +568,8 @@ struct netxen_adapter_stats {
 	u64  rxdropped;
 	u64  txdropped;
 	u64  csummed;
-	u64  no_rcv;
+	u64  rx_pkts;
+	u64  lro_pkts;
 	u64  rxbytes;
 	u64  txbytes;
 };
@@ -737,11 +580,11 @@ struct netxen_adapter_stats {
  */
 struct nx_host_rds_ring {
 	u32 producer;
-	u32 crb_rcv_producer;
 	u32 num_desc;
 	u32 dma_size;
 	u32 skb_size;
 	u32 flags;
+	void __iomem *crb_rcv_producer;
 	struct rcv_desc *desc_head;
 	struct netxen_rx_buffer *rx_buf_arr;
 	struct list_head free_list;
@@ -751,9 +594,9 @@ struct nx_host_rds_ring {
 
 struct nx_host_sds_ring {
 	u32 consumer;
-	u32 crb_sts_consumer;
-	u32 crb_intr_mask;
 	u32 num_desc;
+	void __iomem *crb_sts_consumer;
+	void __iomem *crb_intr_mask;
 
 	struct status_desc *desc_head;
 	struct netxen_adapter *adapter;
@@ -770,8 +613,8 @@ struct nx_host_tx_ring {
 	u32 producer;
 	__le32 *hw_consumer;
 	u32 sw_consumer;
-	u32 crb_cmd_producer;
-	u32 crb_cmd_consumer;
+	void __iomem *crb_cmd_producer;
+	void __iomem *crb_cmd_consumer;
 	u32 num_desc;
 
 	struct netdev_queue *txq;
@@ -840,7 +683,19 @@ struct netxen_recv_context {
 #define NX_CDRP_CMD_GET_STATISTICS          0x0000000f
 #define NX_CDRP_CMD_DELETE_STATISTICS       0x00000010
 #define NX_CDRP_CMD_SET_MTU                 0x00000012
-#define NX_CDRP_CMD_MAX                     0x00000013
+#define NX_CDRP_CMD_READ_PHY			0x00000013
+#define NX_CDRP_CMD_WRITE_PHY			0x00000014
+#define NX_CDRP_CMD_READ_HW_REG			0x00000015
+#define NX_CDRP_CMD_GET_FLOW_CTL		0x00000016
+#define NX_CDRP_CMD_SET_FLOW_CTL		0x00000017
+#define NX_CDRP_CMD_READ_MAX_MTU		0x00000018
+#define NX_CDRP_CMD_READ_MAX_LRO		0x00000019
+#define NX_CDRP_CMD_CONFIGURE_TOE		0x0000001a
+#define NX_CDRP_CMD_FUNC_ATTRIB			0x0000001b
+#define NX_CDRP_CMD_READ_PEXQ_PARAMETERS	0x0000001c
+#define NX_CDRP_CMD_GET_LIC_CAPABILITIES	0x0000001d
+#define NX_CDRP_CMD_READ_MAX_LRO_PER_BOARD	0x0000001e
+#define NX_CDRP_CMD_MAX				0x0000001f
 
 #define NX_RCODE_SUCCESS		0
 #define NX_RCODE_NO_HOST_MEM		1
@@ -881,6 +736,7 @@ struct netxen_recv_context {
 #define NX_CAP0_LSO			NX_CAP_BIT(0, 6)
 #define NX_CAP0_JUMBO_CONTIGUOUS	NX_CAP_BIT(0, 7)
 #define NX_CAP0_LRO_CONTIGUOUS		NX_CAP_BIT(0, 8)
+#define NX_CAP0_HW_LRO			NX_CAP_BIT(0, 10)
 
 /*
  * Context state
@@ -1078,6 +934,9 @@ typedef struct {
 
 #define NX_MAC_EVENT		0x1
 
+#define NX_IP_UP		2
+#define NX_IP_DOWN		3
+
 /*
  * Driver --> Firmware
  */
@@ -1104,7 +963,9 @@ typedef struct {
 #define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE		20
 #define NX_NIC_H2C_OPCODE_GET_LINKEVENT			21
 #define NX_NIC_C2C_OPCODE				22
-#define NX_NIC_H2C_OPCODE_LAST				23
+#define NX_NIC_H2C_OPCODE_CONFIG_BRIDGING               23
+#define NX_NIC_H2C_OPCODE_CONFIG_HW_LRO			24
+#define NX_NIC_H2C_OPCODE_LAST				25
 
 /*
  * Firmware --> Driver
@@ -1130,8 +991,25 @@ typedef struct {
 #define VPORT_MISS_MODE_ACCEPT_ALL	1 /* accept all packets */
 #define VPORT_MISS_MODE_ACCEPT_MULTI	2 /* accept unmatched multicast */
 
+#define NX_NIC_LRO_REQUEST_FIRST		0
+#define NX_NIC_LRO_REQUEST_ADD_FLOW		1
+#define NX_NIC_LRO_REQUEST_DELETE_FLOW		2
+#define NX_NIC_LRO_REQUEST_TIMER		3
+#define NX_NIC_LRO_REQUEST_CLEANUP		4
+#define NX_NIC_LRO_REQUEST_ADD_FLOW_SCHEDULED	5
+#define NX_TOE_LRO_REQUEST_ADD_FLOW		6
+#define NX_TOE_LRO_REQUEST_ADD_FLOW_RESPONSE	7
+#define NX_TOE_LRO_REQUEST_DELETE_FLOW		8
+#define NX_TOE_LRO_REQUEST_DELETE_FLOW_RESPONSE	9
+#define NX_TOE_LRO_REQUEST_TIMER		10
+#define NX_NIC_LRO_REQUEST_LAST			11
+
 #define NX_FW_CAPABILITY_LINK_NOTIFICATION	(1 << 5)
 #define NX_FW_CAPABILITY_SWITCHING		(1 << 6)
+#define NX_FW_CAPABILITY_PEXQ			(1 << 7)
+#define NX_FW_CAPABILITY_BDG			(1 << 8)
+#define NX_FW_CAPABILITY_FVLANTX		(1 << 9)
+#define NX_FW_CAPABILITY_HW_LRO			(1 << 10)
 
 /* module types */
 #define LINKEVENT_MODULE_NOT_PRESENT			1
@@ -1206,6 +1084,8 @@ typedef struct {
 
 #define NETXEN_NIC_MSI_ENABLED		0x02
 #define NETXEN_NIC_MSIX_ENABLED		0x04
+#define NETXEN_NIC_LRO_ENABLED		0x08
+#define NETXEN_NIC_BRIDGE_ENABLED       0X10
 #define NETXEN_IS_MSI_FAMILY(adapter) \
 	((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
 
@@ -1219,6 +1099,10 @@ typedef struct {
 #define NETXEN_ADAPTER_UP_MAGIC 777
 #define NETXEN_NIC_PEG_TUNE 0
 
+#define __NX_FW_ATTACHED		0
+#define __NX_DEV_UP			1
+#define __NX_RESETTING			2
+
 struct netxen_dummy_dma {
 	void *addr;
 	dma_addr_t phys_addr;
@@ -1255,7 +1139,10 @@ struct netxen_adapter {
 	u8 max_mc_count;
 	u8 rss_supported;
 	u8 link_changed;
-	u32 resv3;
+	u8 fw_wait_cnt;
+	u8 fw_fail_cnt;
+	u8 tx_timeo_cnt;
+	u8 need_fw_reset;
 
 	u8 has_link_events;
 	u8 fw_type;
@@ -1273,79 +1160,64 @@ struct netxen_adapter {
 	u32 irq;
 	u32 temp;
 
-	u32 msi_tgt_status;
-	u32 resv4;
+	u32 int_vec_bit;
+	u32 heartbit;
 
 	struct netxen_adapter_stats stats;
 
 	struct netxen_recv_context recv_ctx;
 	struct nx_host_tx_ring *tx_ring;
 
-	int (*enable_phy_interrupts) (struct netxen_adapter *);
-	int (*disable_phy_interrupts) (struct netxen_adapter *);
 	int (*macaddr_set) (struct netxen_adapter *, u8 *);
 	int (*set_mtu) (struct netxen_adapter *, int);
 	int (*set_promisc) (struct netxen_adapter *, u32);
 	void (*set_multi) (struct net_device *);
-	int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
-	int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
+	int (*phy_read) (struct netxen_adapter *, u32 reg, u32 *);
+	int (*phy_write) (struct netxen_adapter *, u32 reg, u32 val);
 	int (*init_port) (struct netxen_adapter *, int);
 	int (*stop_port) (struct netxen_adapter *);
 
-	u32 (*hw_read_wx)(struct netxen_adapter *, ulong);
-	int (*hw_write_wx)(struct netxen_adapter *, ulong, u32);
+	u32 (*crb_read)(struct netxen_adapter *, ulong);
+	int (*crb_write)(struct netxen_adapter *, ulong, u32);
+
 	int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
 	int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
-	int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
-	u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
+
 	unsigned long (*pci_set_window)(struct netxen_adapter *,
 			unsigned long long);
 
-	struct netxen_legacy_intr_set legacy_intr;
+	u32 (*io_read)(struct netxen_adapter *, void __iomem *);
+	void (*io_write)(struct netxen_adapter *, void __iomem *, u32);
+
+	void __iomem	*tgt_mask_reg;
+	void __iomem	*pci_int_reg;
+	void __iomem	*tgt_status_reg;
+	void __iomem	*crb_int_state_reg;
+	void __iomem	*isr_int_vec;
 
 	struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
 
 	struct netxen_dummy_dma dummy_dma;
 
-	struct work_struct watchdog_task;
-	struct timer_list watchdog_timer;
+	struct delayed_work fw_work;
+
 	struct work_struct  tx_timeout_task;
 
 	struct net_device_stats net_stats;
 
 	nx_nic_intr_coalesce_t coal;
 
-	u32 fw_major;
+	unsigned long state;
+	u32 resv5;
 	u32 fw_version;
 	const struct firmware *fw;
 };
 
-/*
- * NetXen dma watchdog control structure
- *
- *	Bit 0		: enabled => R/O: 1 watchdog active, 0 inactive
- *	Bit 1		: disable_request => 1 req disable dma watchdog
- *	Bit 2		: enable_request =>  1 req enable dma watchdog
- *	Bit 3-31	: unused
- */
+int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port);
+int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
 
-#define netxen_set_dma_watchdog_disable_req(config_word) \
-	_netxen_set_bits(config_word, 1, 1, 1)
-#define netxen_set_dma_watchdog_enable_req(config_word) \
-	_netxen_set_bits(config_word, 2, 1, 1)
-#define netxen_get_dma_watchdog_enabled(config_word) \
-	((config_word) & 0x1)
-#define netxen_get_dma_watchdog_disabled(config_word) \
-	(((config_word) >> 1) & 0x1)
-
-int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
-			    __u32 * readval);
-int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
-			     long reg, __u32 val);
+int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val);
+int nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val);
 
 /* Functions available from netxen_nic_hw.c */
 int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
@@ -1355,51 +1227,45 @@ int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
 int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
 
 #define NXRD32(adapter, off) \
-	(adapter->hw_read_wx(adapter, off))
+	(adapter->crb_read(adapter, off))
 #define NXWR32(adapter, off, val) \
-	(adapter->hw_write_wx(adapter, off, val))
+	(adapter->crb_write(adapter, off, val))
+#define NXRDIO(adapter, addr) \
+	(adapter->io_read(adapter, addr))
+#define NXWRIO(adapter, addr, val) \
+	(adapter->io_write(adapter, addr, val))
+
+int netxen_pcie_sem_lock(struct netxen_adapter *, int, u32);
+void netxen_pcie_sem_unlock(struct netxen_adapter *, int);
+
+#define netxen_rom_lock(a)	\
+	netxen_pcie_sem_lock((a), 2, NETXEN_ROM_LOCK_ID)
+#define netxen_rom_unlock(a)	\
+	netxen_pcie_sem_unlock((a), 2)
+#define netxen_phy_lock(a)	\
+	netxen_pcie_sem_lock((a), 3, NETXEN_PHY_LOCK_ID)
+#define netxen_phy_unlock(a)	\
+	netxen_pcie_sem_unlock((a), 3)
+#define netxen_api_lock(a)	\
+	netxen_pcie_sem_lock((a), 5, 0)
+#define netxen_api_unlock(a)	\
+	netxen_pcie_sem_unlock((a), 5)
+#define netxen_sw_lock(a)	\
+	netxen_pcie_sem_lock((a), 6, 0)
+#define netxen_sw_unlock(a)	\
+	netxen_pcie_sem_unlock((a), 6)
+#define crb_win_lock(a)	\
+	netxen_pcie_sem_lock((a), 7, NETXEN_CRB_WIN_LOCK_ID)
+#define crb_win_unlock(a)	\
+	netxen_pcie_sem_unlock((a), 7)
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter);
-void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
 int netxen_nic_wol_supported(struct netxen_adapter *adapter);
 
-u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off);
-int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
-		ulong off, u32 data);
-int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off);
-unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
-		unsigned long long addr);
-void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
-		u32 wndw);
-
-u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off);
-int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
-		ulong off, u32 data);
-int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
-		u64 off, void *data, int size);
-int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
-		u64 off, u32 data);
-u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off);
-unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
-		unsigned long long addr);
-
 /* Functions from netxen_nic_init.c */
-void netxen_free_adapter_offload(struct netxen_adapter *adapter);
-int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
+int netxen_init_dummy_dma(struct netxen_adapter *adapter);
+void netxen_free_dummy_dma(struct netxen_adapter *adapter);
+
 int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
 int netxen_load_firmware(struct netxen_adapter *adapter);
 int netxen_need_fw_reset(struct netxen_adapter *adapter);
@@ -1423,13 +1289,15 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr);
 int netxen_alloc_sw_resources(struct netxen_adapter *adapter);
 void netxen_free_sw_resources(struct netxen_adapter *adapter);
 
+void netxen_setup_hwops(struct netxen_adapter *adapter);
+void __iomem *netxen_get_ioaddr(struct netxen_adapter *, u32);
+
 int netxen_alloc_hw_resources(struct netxen_adapter *adapter);
 void netxen_free_hw_resources(struct netxen_adapter *adapter);
 
 void netxen_release_rx_buffers(struct netxen_adapter *adapter);
 void netxen_release_tx_buffers(struct netxen_adapter *adapter);
 
-void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
 int netxen_init_firmware(struct netxen_adapter *adapter);
 void netxen_nic_clear_stats(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
@@ -1440,14 +1308,19 @@ int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
 void netxen_p2_nic_set_multi(struct net_device *netdev);
 void netxen_p3_nic_set_multi(struct net_device *netdev);
 void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
+int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode);
 int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
 int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
 int netxen_config_rss(struct netxen_adapter *adapter, int enable);
+int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd);
 int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
 void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
 
 int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
+int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable);
+int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable);
+int netxen_send_lro_cleanup(struct netxen_adapter *adapter);
 
 int netxen_nic_set_mac(struct net_device *netdev, void *p);
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
@@ -1455,6 +1328,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
 void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
 		struct nx_host_tx_ring *tx_ring);
 
+/* Functions from netxen_nic_main.c */
+int netxen_nic_reset_context(struct netxen_adapter *);
+
 /*
  * NetXen Board information
  */
@@ -1505,56 +1381,6 @@ static inline void get_brd_name_by_type(u32 type, char *name)
 		name = "Unknown";
 }
 
-static inline int
-dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
-{
-	u32 ctrl;
-
-	/* check if already inactive */
-	ctrl = adapter->hw_read_wx(adapter,
-			NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
-
-	if (netxen_get_dma_watchdog_enabled(ctrl) == 0)
-		return 1;
-
-	/* Send the disable request */
-	netxen_set_dma_watchdog_disable_req(ctrl);
-	NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
-
-	return 0;
-}
-
-static inline int
-dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
-{
-	u32 ctrl;
-
-	ctrl = adapter->hw_read_wx(adapter,
-			NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
-
-	return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
-}
-
-static inline int
-dma_watchdog_wakeup(struct netxen_adapter *adapter)
-{
-	u32 ctrl;
-
-	ctrl = adapter->hw_read_wx(adapter,
-			NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
-
-	if (netxen_get_dma_watchdog_enabled(ctrl))
-		return 1;
-
-	/* send the wakeup request */
-	netxen_set_dma_watchdog_enable_req(ctrl);
-
-	NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
-
-	return 0;
-}
-
-
 static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring)
 {
 	smp_mb();
@@ -1569,6 +1395,6 @@ extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
 				int *valp);
 
-extern struct ethtool_ops netxen_nic_ethtool_ops;
+extern const struct ethtool_ops netxen_nic_ethtool_ops;
 
 #endif				/* __NETXEN_NIC_H_ */
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 9f8ae47..9cb8f68 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,55 +21,13 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #include "netxen_nic_hw.h"
 #include "netxen_nic.h"
-#include "netxen_nic_phan_reg.h"
 
 #define NXHAL_VERSION	1
 
-static int
-netxen_api_lock(struct netxen_adapter *adapter)
-{
-	u32 done = 0, timeout = 0;
-
-	for (;;) {
-		/* Acquire PCIE HW semaphore5 */
-		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK));
-
-		if (done == 1)
-			break;
-
-		if (++timeout >= NX_OS_CRB_RETRY_COUNT) {
-			printk(KERN_ERR "%s: lock timeout.\n", __func__);
-			return -1;
-		}
-
-		msleep(1);
-	}
-
-#if 0
-	NXWR32(adapter,
-		NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
-#endif
-	return 0;
-}
-
-static int
-netxen_api_unlock(struct netxen_adapter *adapter)
-{
-	/* Release PCIE HW semaphore5 */
-	NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK));
-	return 0;
-}
-
 static u32
 netxen_poll_rsp(struct netxen_adapter *adapter)
 {
@@ -265,7 +224,8 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 		rds_ring = &recv_ctx->rds_rings[i];
 
 		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
-		rds_ring->crb_rcv_producer = NETXEN_NIC_REG(reg - 0x200);
+		rds_ring->crb_rcv_producer = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(reg - 0x200));
 	}
 
 	prsp_sds = ((nx_cardrsp_sds_ring_t *)
@@ -275,10 +235,12 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 		sds_ring = &recv_ctx->sds_rings[i];
 
 		reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
-		sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+		sds_ring->crb_sts_consumer = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(reg - 0x200));
 
 		reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
-		sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+		sds_ring->crb_intr_mask = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(reg - 0x200));
 	}
 
 	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
@@ -378,7 +340,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 
 	if (err == NX_RCODE_SUCCESS) {
 		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
-		tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
+		tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
+				NETXEN_NIC_REG(temp - 0x200));
 #if 0
 		adapter->tx_state =
 			le32_to_cpu(prsp->host_ctx_state);
@@ -416,6 +379,44 @@ nx_fw_cmd_destroy_tx_ctx(struct netxen_adapter *adapter)
 	}
 }
 
+int
+nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val)
+{
+	u32 rcode;
+
+	rcode = netxen_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			NXHAL_VERSION,
+			reg,
+			0,
+			0,
+			NX_CDRP_CMD_READ_PHY);
+
+	if (rcode != NX_RCODE_SUCCESS)
+		return -EIO;
+
+	return NXRD32(adapter, NX_ARG1_CRB_OFFSET);
+}
+
+int
+nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val)
+{
+	u32 rcode;
+
+	rcode = netxen_issue_cmd(adapter,
+			adapter->ahw.pci_func,
+			NXHAL_VERSION,
+			reg,
+			val,
+			0,
+			NX_CDRP_CMD_WRITE_PHY);
+
+	if (rcode != NX_RCODE_SUCCESS)
+		return -EIO;
+
+	return 0;
+}
+
 static u64 ctx_addr_sig_regs[][3] = {
 	{NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
 	{NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
@@ -647,9 +648,10 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 		}
 		rds_ring->desc_head = (struct rcv_desc *)addr;
 
-		if (adapter->fw_major < 4)
+		if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
 			rds_ring->crb_rcv_producer =
-				recv_crb_registers[port].crb_rcv_producer[ring];
+				netxen_get_ioaddr(adapter,
+			recv_crb_registers[port].crb_rcv_producer[ring]);
 	}
 
 	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -668,14 +670,19 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 		sds_ring->desc_head = (struct status_desc *)addr;
 
 		sds_ring->crb_sts_consumer =
-			recv_crb_registers[port].crb_sts_consumer[ring];
+			netxen_get_ioaddr(adapter,
+			recv_crb_registers[port].crb_sts_consumer[ring]);
 
 		sds_ring->crb_intr_mask =
-			recv_crb_registers[port].sw_int_mask[ring];
+			netxen_get_ioaddr(adapter,
+			recv_crb_registers[port].sw_int_mask[ring]);
 	}
 
 
-	if (adapter->fw_major >= 4) {
+	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		if (test_and_set_bit(__NX_FW_ATTACHED, &adapter->state))
+			goto done;
+
 		err = nx_fw_cmd_create_rx_ctx(adapter);
 		if (err)
 			goto err_out_free;
@@ -688,6 +695,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 			goto err_out_free;
 	}
 
+done:
 	return 0;
 
 err_out_free:
@@ -705,7 +713,10 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
 
 	int port = adapter->portnum;
 
-	if (adapter->fw_major >= 4) {
+	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		if (!test_and_clear_bit(__NX_FW_ATTACHED, &adapter->state))
+			goto done;
+
 		nx_fw_cmd_destroy_rx_ctx(adapter);
 		nx_fw_cmd_destroy_tx_ctx(adapter);
 	} else {
@@ -718,6 +729,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
 	/* Allow dma queues to drain after context reset */
 	msleep(20);
 
+done:
 	recv_ctx = &adapter->recv_ctx;
 
 	if (recv_ctx->hwctx != NULL) {
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index e16ea46..714f387 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #include <linux/types.h>
@@ -37,7 +32,6 @@
 
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
-#include "netxen_nic_phan_reg.h"
 
 struct netxen_nic_stats {
 	char stat_string[ETH_GSTRING_LEN];
@@ -57,7 +51,8 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
 	{"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
 	{"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
 	{"csummed", NETXEN_NIC_STAT(stats.csummed)},
-	{"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
+	{"rx_pkts", NETXEN_NIC_STAT(stats.rx_pkts)},
+	{"lro_pkts", NETXEN_NIC_STAT(stats.lro_pkts)},
 	{"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
 	{"tx_bytes", NETXEN_NIC_STAT(stats.txbytes)},
 };
@@ -84,18 +79,17 @@ static void
 netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
-	unsigned long flags;
 	u32 fw_major = 0;
 	u32 fw_minor = 0;
 	u32 fw_build = 0;
 
 	strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
 	strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
-	write_lock_irqsave(&adapter->adapter_lock, flags);
+	read_lock(&adapter->adapter_lock);
 	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
 	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
 	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-	write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	read_unlock(&adapter->adapter_lock);
 	sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
 
 	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
@@ -490,28 +484,86 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 }
 
 static void
-netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
+netxen_nic_get_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
 
-	ring->rx_pending = 0;
-	ring->rx_jumbo_pending = 0;
-	ring->rx_pending += adapter->recv_ctx.
-		rds_rings[RCV_RING_NORMAL].num_desc;
-	ring->rx_jumbo_pending += adapter->recv_ctx.
-		rds_rings[RCV_RING_JUMBO].num_desc;
+	ring->rx_pending = adapter->num_rxd;
+	ring->rx_jumbo_pending = adapter->num_jumbo_rxd;
+	ring->rx_jumbo_pending += adapter->num_lro_rxd;
 	ring->tx_pending = adapter->num_txd;
 
-	if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
 		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
-	else
+		ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+	} else {
 		ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G;
-	ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST;
-	ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS;
+		ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	}
+
+	ring->tx_max_pending = MAX_CMD_DESCRIPTORS;
+
 	ring->rx_mini_max_pending = 0;
 	ring->rx_mini_pending = 0;
 }
 
+static u32
+netxen_validate_ringparam(u32 val, u32 min, u32 max, char *r_name)
+{
+	u32 num_desc;
+	num_desc = max(val, min);
+	num_desc = min(num_desc, max);
+	num_desc = roundup_pow_of_two(num_desc);
+
+	if (val != num_desc) {
+		printk(KERN_INFO "%s: setting %s ring size %d instead of %d\n",
+		       netxen_nic_driver_name, r_name, num_desc, val);
+	}
+
+	return num_desc;
+}
+
+static int
+netxen_nic_set_ringparam(struct net_device *dev,
+		struct ethtool_ringparam *ring)
+{
+	struct netxen_adapter *adapter = netdev_priv(dev);
+	u16 max_rcv_desc = MAX_RCV_DESCRIPTORS_10G;
+	u16 max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	u16 num_rxd, num_jumbo_rxd, num_txd;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return -EOPNOTSUPP;
+
+	if (ring->rx_mini_pending)
+		return -EOPNOTSUPP;
+
+	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
+		max_rcv_desc = MAX_RCV_DESCRIPTORS_1G;
+		max_jumbo_desc = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	}
+
+	num_rxd = netxen_validate_ringparam(ring->rx_pending,
+			MIN_RCV_DESCRIPTORS, max_rcv_desc, "rx");
+
+	num_jumbo_rxd = netxen_validate_ringparam(ring->rx_jumbo_pending,
+			MIN_JUMBO_DESCRIPTORS, max_jumbo_desc, "rx jumbo");
+
+	num_txd = netxen_validate_ringparam(ring->tx_pending,
+			MIN_CMD_DESCRIPTORS, MAX_CMD_DESCRIPTORS, "tx");
+
+	if (num_rxd == adapter->num_rxd && num_txd == adapter->num_txd &&
+			num_jumbo_rxd == adapter->num_jumbo_rxd)
+		return 0;
+
+	adapter->num_rxd = num_rxd;
+	adapter->num_jumbo_rxd = num_jumbo_rxd;
+	adapter->num_txd = num_txd;
+
+	return netxen_nic_reset_context(adapter);
+}
+
 static void
 netxen_nic_get_pauseparam(struct net_device *dev,
 			  struct ethtool_pauseparam *pause)
@@ -883,7 +935,29 @@ static int netxen_get_intr_coalesce(struct net_device *netdev,
 	return 0;
 }
 
-struct ethtool_ops netxen_nic_ethtool_ops = {
+static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
+{
+	struct netxen_adapter *adapter = netdev_priv(netdev);
+	int hw_lro;
+
+	if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
+		return -EINVAL;
+
+	ethtool_op_set_flags(netdev, data);
+
+	hw_lro = (data & ETH_FLAG_LRO) ? NETXEN_NIC_LRO_ENABLED : 0;
+
+	if (netxen_config_hw_lro(adapter, hw_lro))
+		return -EIO;
+
+	if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter))
+		return -EIO;
+
+
+	return 0;
+}
+
+const struct ethtool_ops netxen_nic_ethtool_ops = {
 	.get_settings = netxen_nic_get_settings,
 	.set_settings = netxen_nic_set_settings,
 	.get_drvinfo = netxen_nic_get_drvinfo,
@@ -893,6 +967,7 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
 	.get_eeprom_len = netxen_nic_get_eeprom_len,
 	.get_eeprom = netxen_nic_get_eeprom,
 	.get_ringparam = netxen_nic_get_ringparam,
+	.set_ringparam = netxen_nic_set_ringparam,
 	.get_pauseparam = netxen_nic_get_pauseparam,
 	.set_pauseparam = netxen_nic_set_pauseparam,
 	.set_tx_csum = ethtool_op_set_tx_csum,
@@ -909,4 +984,6 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
 	.set_rx_csum = netxen_nic_set_rx_csum,
 	.get_coalesce = netxen_get_intr_coalesce,
 	.set_coalesce = netxen_set_intr_coalesce,
+	.get_flags = ethtool_op_get_flags,
+	.set_flags = netxen_nic_set_flags,
 };
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 8241036..7a71774 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #ifndef __NETXEN_NIC_HDR_H_
@@ -433,6 +428,7 @@ enum {
 #define NETXEN_CRB_PEG_NET_1	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN1)
 #define NETXEN_CRB_PEG_NET_2	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN2)
 #define NETXEN_CRB_PEG_NET_3	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGN3)
+#define NETXEN_CRB_PEG_NET_4	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_SQS2)
 #define NETXEN_CRB_PEG_NET_D	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGND)
 #define NETXEN_CRB_PEG_NET_I	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_PGNI)
 #define NETXEN_CRB_DDR_NET	NETXEN_PCI_CRB_WINDOW(NETXEN_HW_PX_MAP_CRB_MN)
@@ -723,9 +719,92 @@ enum {
 #define NETXEN_FW_VERSION_MINOR (NETXEN_CAM_RAM(0x154))
 #define NETXEN_FW_VERSION_SUB	(NETXEN_CAM_RAM(0x158))
 #define NETXEN_ROM_LOCK_ID	(NETXEN_CAM_RAM(0x100))
+#define NETXEN_PHY_LOCK_ID	(NETXEN_CAM_RAM(0x120))
 #define NETXEN_CRB_WIN_LOCK_ID	(NETXEN_CAM_RAM(0x124))
 
-#define NETXEN_PHY_LOCK_ID	(NETXEN_CAM_RAM(0x120))
+#define NIC_CRB_BASE		(NETXEN_CAM_RAM(0x200))
+#define NIC_CRB_BASE_2		(NETXEN_CAM_RAM(0x700))
+#define NETXEN_NIC_REG(X)	(NIC_CRB_BASE+(X))
+#define NETXEN_NIC_REG_2(X)	(NIC_CRB_BASE_2+(X))
+
+#define NX_CDRP_CRB_OFFSET		(NETXEN_NIC_REG(0x18))
+#define NX_ARG1_CRB_OFFSET		(NETXEN_NIC_REG(0x1c))
+#define NX_ARG2_CRB_OFFSET		(NETXEN_NIC_REG(0x20))
+#define NX_ARG3_CRB_OFFSET		(NETXEN_NIC_REG(0x24))
+#define NX_SIGN_CRB_OFFSET		(NETXEN_NIC_REG(0x28))
+
+#define CRB_HOST_DUMMY_BUF_ADDR_HI	(NETXEN_NIC_REG(0x3c))
+#define CRB_HOST_DUMMY_BUF_ADDR_LO	(NETXEN_NIC_REG(0x40))
+
+#define CRB_CMDPEG_STATE		(NETXEN_NIC_REG(0x50))
+#define CRB_RCVPEG_STATE		(NETXEN_NIC_REG(0x13c))
+
+#define CRB_XG_STATE			(NETXEN_NIC_REG(0x94))
+#define CRB_XG_STATE_P3			(NETXEN_NIC_REG(0x98))
+#define CRB_PF_LINK_SPEED_1		(NETXEN_NIC_REG(0xe8))
+#define CRB_PF_LINK_SPEED_2		(NETXEN_NIC_REG(0xec))
+
+#define CRB_MPORT_MODE			(NETXEN_NIC_REG(0xc4))
+#define CRB_DMA_SHIFT			(NETXEN_NIC_REG(0xcc))
+#define CRB_INT_VECTOR			(NETXEN_NIC_REG(0xd4))
+
+#define CRB_CMD_PRODUCER_OFFSET		(NETXEN_NIC_REG(0x08))
+#define CRB_CMD_CONSUMER_OFFSET		(NETXEN_NIC_REG(0x0c))
+#define CRB_CMD_PRODUCER_OFFSET_1   	(NETXEN_NIC_REG(0x1ac))
+#define CRB_CMD_CONSUMER_OFFSET_1	(NETXEN_NIC_REG(0x1b0))
+#define CRB_CMD_PRODUCER_OFFSET_2	(NETXEN_NIC_REG(0x1b8))
+#define CRB_CMD_CONSUMER_OFFSET_2	(NETXEN_NIC_REG(0x1bc))
+#define CRB_CMD_PRODUCER_OFFSET_3	(NETXEN_NIC_REG(0x1d0))
+#define CRB_CMD_CONSUMER_OFFSET_3	(NETXEN_NIC_REG(0x1d4))
+#define CRB_TEMP_STATE			(NETXEN_NIC_REG(0x1b4))
+
+#define CRB_V2P_0			(NETXEN_NIC_REG(0x290))
+#define CRB_V2P(port)			(CRB_V2P_0+((port)*4))
+#define CRB_DRIVER_VERSION		(NETXEN_NIC_REG(0x2a0))
+
+#define CRB_SW_INT_MASK_0		(NETXEN_NIC_REG(0x1d8))
+#define CRB_SW_INT_MASK_1		(NETXEN_NIC_REG(0x1e0))
+#define CRB_SW_INT_MASK_2		(NETXEN_NIC_REG(0x1e4))
+#define CRB_SW_INT_MASK_3		(NETXEN_NIC_REG(0x1e8))
+
+#define CRB_FW_CAPABILITIES_1		(NETXEN_CAM_RAM(0x128))
+#define CRB_MAC_BLOCK_START		(NETXEN_CAM_RAM(0x1c0))
+
+/*
+ * capabilities register, can be used to selectively enable/disable features
+ * for backward compability
+ */
+#define CRB_NIC_CAPABILITIES_HOST	NETXEN_NIC_REG(0x1a8)
+#define CRB_NIC_CAPABILITIES_FW	  	NETXEN_NIC_REG(0x1dc)
+#define CRB_NIC_MSI_MODE_HOST		NETXEN_NIC_REG(0x270)
+#define CRB_NIC_MSI_MODE_FW	  	NETXEN_NIC_REG(0x274)
+
+#define INTR_SCHEME_PERPORT	      	0x1
+#define MSI_MODE_MULTIFUNC	      	0x1
+
+/* used for ethtool tests */
+#define CRB_SCRATCHPAD_TEST	    NETXEN_NIC_REG(0x280)
+
+/*
+ * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
+ * which can be read by the Phantom host to get producer/consumer indexes from
+ * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
+ * registers will be used for the addresses of the ring's shared memory
+ * on the Phantom.
+ */
+
+#define nx_get_temp_val(x)		((x) >> 16)
+#define nx_get_temp_state(x)		((x) & 0xffff)
+#define nx_encode_temp(val, state)	(((val) << 16) | (state))
+
+/*
+ * Temperature control.
+ */
+enum {
+	NX_TEMP_NORMAL = 0x1,	/* Normal operating range */
+	NX_TEMP_WARN,		/* Sound alert, temperature getting high */
+	NX_TEMP_PANIC		/* Fatal error, hardware has shut down. */
+};
 
 /* Lock IDs for PHY lock */
 #define PHY_LOCK_DRIVER		0x44524956
@@ -816,16 +895,24 @@ enum {
 
 #define PCIE_DCR		0x00d8
 
+#define PCIE_SEM0_LOCK		(0x1c000)
+#define PCIE_SEM0_UNLOCK	(0x1c004)
+#define PCIE_SEM1_LOCK		(0x1c008)
+#define PCIE_SEM1_UNLOCK	(0x1c00c)
 #define PCIE_SEM2_LOCK		(0x1c010)	/* Flash lock   */
 #define PCIE_SEM2_UNLOCK	(0x1c014)	/* Flash unlock */
 #define PCIE_SEM3_LOCK	  	(0x1c018)	/* Phy lock     */
 #define PCIE_SEM3_UNLOCK	(0x1c01c)	/* Phy unlock   */
+#define PCIE_SEM4_LOCK	  	(0x1c020)
+#define PCIE_SEM4_UNLOCK	(0x1c024)
 #define PCIE_SEM5_LOCK		(0x1c028)	/* API lock     */
 #define PCIE_SEM5_UNLOCK	(0x1c02c)	/* API unlock   */
 #define PCIE_SEM6_LOCK		(0x1c030)	/* sw lock      */
 #define PCIE_SEM6_UNLOCK	(0x1c034)	/* sw unlock    */
 #define PCIE_SEM7_LOCK		(0x1c038)	/* crb win lock */
 #define PCIE_SEM7_UNLOCK	(0x1c03c)	/* crbwin unlock*/
+#define PCIE_SEM_LOCK(N)	(PCIE_SEM0_LOCK + 8*(N))
+#define PCIE_SEM_UNLOCK(N)	(PCIE_SEM0_UNLOCK + 8*(N))
 
 #define PCIE_SETUP_FUNCTION	(0x12040)
 #define PCIE_SETUP_FUNCTION2	(0x12048)
@@ -852,8 +939,30 @@ enum {
 #define NX_PEG_TUNE_MN_PRESENT		0x1
 #define NX_PEG_TUNE_CAPABILITY		(NETXEN_CAM_RAM(0x02c))
 
-#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL		(0x14)
+#define NETXEN_DMA_WATCHDOG_CTRL	(NETXEN_CAM_RAM(0x14))
 #define NETXEN_PEG_ALIVE_COUNTER	(NETXEN_CAM_RAM(0xb0))
+#define NETXEN_PEG_HALT_STATUS1 	(NETXEN_CAM_RAM(0xa8))
+#define NETXEN_PEG_HALT_STATUS2 	(NETXEN_CAM_RAM(0xac))
+#define NX_CRB_DEV_REF_COUNT		(NETXEN_CAM_RAM(0x138))
+#define NX_CRB_DEV_STATE		(NETXEN_CAM_RAM(0x140))
+
+/* Device State */
+#define NX_DEV_COLD		1
+#define NX_DEV_INITALIZING	2
+#define NX_DEV_READY		3
+#define NX_DEV_NEED_RESET	4
+#define NX_DEV_NEED_QUISCENT	5
+#define NX_DEV_FAILED		6
+
+#define NX_RCODE_DRIVER_INFO		0x20000000
+#define NX_RCODE_DRIVER_CAN_RELOAD	0x40000000
+#define NX_RCODE_FATAL_ERROR		0x80000000
+#define NX_FWERROR_PEGNUM(code)		((code) & 0xff)
+#define NX_FWERROR_CODE(code)		((code >> 8) & 0xfffff)
+
+#define FW_POLL_DELAY			(2 * HZ)
+#define FW_FAIL_THRESH			3
+#define FW_POLL_THRESH			10
 
 #define	ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
 #define ISR_LEGACY_INT_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index b9123d4..3231400 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,17 +21,10 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
-#include "netxen_nic_phan_reg.h"
 
 #include <net/ip.h>
 
@@ -87,7 +81,6 @@ static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
 	return NULL;
 }
 
-#define CRB_WIN_LOCK_TIMEOUT 100000000
 static crb_128M_2M_block_map_t
 crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
     {{{0, 0,         0,         0} } },		/* 0: PCI */
@@ -321,6 +314,64 @@ static unsigned crb_hub_agt[64] =
 
 #define NETXEN_WINDOW_ONE 	0x2000000 /*CRB Window: bit 25 of CRB address */
 
+#define NETXEN_PCIE_SEM_TIMEOUT	10000
+
+int
+netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
+{
+	int done = 0, timeout = 0;
+
+	while (!done) {
+		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_LOCK(sem)));
+		if (done == 1)
+			break;
+		if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT)
+			return -1;
+		msleep(1);
+	}
+
+	if (id_reg)
+		NXWR32(adapter, id_reg, adapter->portnum);
+
+	return 0;
+}
+
+void
+netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
+{
+	int val;
+	val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
+}
+
+int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
+{
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
+		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
+	}
+
+	return 0;
+}
+
+/* Disable an XG interface */
+int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
+{
+	__u32 mac_cfg;
+	u32 port = adapter->physical_port;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		return 0;
+
+	if (port > NETXEN_NIU_MAX_XG_PORTS)
+		return -EINVAL;
+
+	mac_cfg = 0;
+	if (NXWR32(adapter,
+			NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
+		return -EIO;
+	return 0;
+}
+
 #define NETXEN_UNICAST_ADDR(port, index) \
 	(NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
 #define NETXEN_MCAST_ADDR(port, index) \
@@ -330,6 +381,56 @@ static unsigned crb_hub_agt[64] =
 #define MAC_LO(addr) \
 	((addr[5] << 16) | (addr[4] << 8) | (addr[3]))
 
+int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
+{
+	__u32 reg;
+	u32 port = adapter->physical_port;
+
+	if (port > NETXEN_NIU_MAX_XG_PORTS)
+		return -EINVAL;
+
+	reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
+	if (mode == NETXEN_NIU_PROMISC_MODE)
+		reg = (reg | 0x2000UL);
+	else
+		reg = (reg & ~0x2000UL);
+
+	if (mode == NETXEN_NIU_ALLMULTI_MODE)
+		reg = (reg | 0x1000UL);
+	else
+		reg = (reg & ~0x1000UL);
+
+	NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+
+	return 0;
+}
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+	u32 mac_hi, mac_lo;
+	u32 reg_hi, reg_lo;
+
+	u8 phy = adapter->physical_port;
+
+	if (phy >= NETXEN_NIU_MAX_XG_PORTS)
+		return -EINVAL;
+
+	mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
+	mac_hi = addr[2] | ((u32)addr[3] << 8) |
+		((u32)addr[4] << 16) | ((u32)addr[5] << 24);
+
+	reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
+	reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
+
+	/* write twice to flush */
+	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+		return -EIO;
+	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+		return -EIO;
+
+	return 0;
+}
+
 static int
 netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
 {
@@ -460,6 +561,9 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
 
 	i = 0;
 
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return -EIO;
+
 	tx_ring = adapter->tx_ring;
 	__netif_tx_lock_bh(tx_ring->txq);
 
@@ -643,7 +747,7 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
 
-	req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
+	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
 
 	word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
 	req.req_hdr = cpu_to_le64(word);
@@ -659,6 +763,66 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
 	return rv;
 }
 
+int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
+{
+	nx_nic_req_t req;
+	u64 word;
+	int rv = 0;
+
+	if ((adapter->flags & NETXEN_NIC_LRO_ENABLED) == enable)
+		return 0;
+
+	memset(&req, 0, sizeof(nx_nic_req_t));
+
+	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+	word = NX_NIC_H2C_OPCODE_CONFIG_HW_LRO | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64(enable);
+
+	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0) {
+		printk(KERN_ERR "ERROR. Could not send "
+			"configure hw lro request\n");
+	}
+
+	adapter->flags ^= NETXEN_NIC_LRO_ENABLED;
+
+	return rv;
+}
+
+int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable)
+{
+	nx_nic_req_t req;
+	u64 word;
+	int rv = 0;
+
+	if (!!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED) == enable)
+		return rv;
+
+	memset(&req, 0, sizeof(nx_nic_req_t));
+
+	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+	word = NX_NIC_H2C_OPCODE_CONFIG_BRIDGING |
+		((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64(enable);
+
+	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0) {
+		printk(KERN_ERR "ERROR. Could not send "
+				"configure bridge mode request\n");
+	}
+
+	adapter->flags ^= NETXEN_NIC_BRIDGE_ENABLED;
+
+	return rv;
+}
+
+
 #define RSS_HASHTYPE_IP_TCP	0x3
 
 int netxen_config_rss(struct netxen_adapter *adapter, int enable)
@@ -706,6 +870,30 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
 	return rv;
 }
 
+int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd)
+{
+	nx_nic_req_t req;
+	u64 word;
+	int rv;
+
+	memset(&req, 0, sizeof(nx_nic_req_t));
+	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+	word = NX_NIC_H2C_OPCODE_CONFIG_IPADDR | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	req.words[0] = cpu_to_le64(cmd);
+	req.words[1] = cpu_to_le64(ip);
+
+	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0) {
+		printk(KERN_ERR "%s: could not notify %s IP 0x%x reuqest\n",
+				adapter->netdev->name,
+				(cmd == NX_IP_UP) ? "Add" : "Remove", ip);
+	}
+	return rv;
+}
+
 int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
 {
 	nx_nic_req_t req;
@@ -728,6 +916,29 @@ int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
 	return rv;
 }
 
+int netxen_send_lro_cleanup(struct netxen_adapter *adapter)
+{
+	nx_nic_req_t req;
+	u64 word;
+	int rv;
+
+	memset(&req, 0, sizeof(nx_nic_req_t));
+	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+	word = NX_NIC_H2C_OPCODE_LRO_REQUEST |
+		((u64)adapter->portnum << 16) |
+		((u64)NX_NIC_LRO_REQUEST_CLEANUP << 56) ;
+
+	req.req_hdr = cpu_to_le64(word);
+
+	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+	if (rv != 0) {
+		printk(KERN_ERR "%s: could not cleanup lro flows\n",
+				adapter->netdev->name);
+	}
+	return rv;
+}
+
 /*
  * netxen_nic_change_mtu - Change the Maximum Transfer Unit
  * @returns 0 on success, negative on failure
@@ -792,18 +1003,15 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
 	__le32 *pmac = (__le32 *) mac;
 	u32 offset;
 
-	offset = NETXEN_USER_START +
-		offsetof(struct netxen_new_user_info, mac_addr) +
-		adapter->portnum * sizeof(u64);
+	offset = NX_FW_MAC_ADDR_OFFSET + (adapter->portnum * sizeof(u64));
 
 	if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
 		return -1;
 
 	if (*mac == cpu_to_le64(~0ULL)) {
 
-		offset = NETXEN_USER_START_OLD +
-			offsetof(struct netxen_user_old_info, mac_addr) +
-			adapter->portnum * sizeof(u64);
+		offset = NX_OLD_MAC_ADDR_OFFSET +
+			(adapter->portnum * sizeof(u64));
 
 		if (netxen_get_flash_block(adapter,
 					offset, sizeof(u64), pmac) == -1)
@@ -834,37 +1042,10 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
 	return 0;
 }
 
-#define CRB_WIN_LOCK_TIMEOUT 100000000
-
-static int crb_win_lock(struct netxen_adapter *adapter)
-{
-	int done = 0, timeout = 0;
-
-	while (!done) {
-		/* acquire semaphore3 from PCI HW block */
-		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
-		if (done == 1)
-			break;
-		if (timeout >= CRB_WIN_LOCK_TIMEOUT)
-			return -1;
-		timeout++;
-		udelay(1);
-	}
-	NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
-	return 0;
-}
-
-static void crb_win_unlock(struct netxen_adapter *adapter)
-{
-	int val;
-
-	val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
-}
-
 /*
  * Changes the CRB window to the specified window.
  */
-void
+static void
 netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
 {
 	void __iomem *offset;
@@ -977,61 +1158,68 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
 		(ulong)adapter->ahw.pci_base0;
 }
 
-int
+static int
 netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
+	unsigned long flags;
 	void __iomem *addr;
 
-	if (ADDR_IN_WINDOW1(off)) {
+	if (ADDR_IN_WINDOW1(off))
 		addr = NETXEN_CRB_NORMALIZE(adapter, off);
+	else
+		addr = pci_base_offset(adapter, off);
+
+	BUG_ON(!addr);
+
+	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+		read_lock(&adapter->adapter_lock);
+		writel(data, addr);
+		read_unlock(&adapter->adapter_lock);
 	} else {		/* Window 0 */
+		write_lock_irqsave(&adapter->adapter_lock, flags);
 		addr = pci_base_offset(adapter, off);
 		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-	}
-
-	if (!addr) {
+		writel(data, addr);
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-		return 1;
+		write_unlock_irqrestore(&adapter->adapter_lock, flags);
 	}
 
-	writel(data, addr);
-
-	if (!ADDR_IN_WINDOW1(off))
-		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-
 	return 0;
 }
 
-u32
+static u32
 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
 {
+	unsigned long flags;
 	void __iomem *addr;
 	u32 data;
 
-	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+	if (ADDR_IN_WINDOW1(off))
 		addr = NETXEN_CRB_NORMALIZE(adapter, off);
-	} else {		/* Window 0 */
+	else
 		addr = pci_base_offset(adapter, off);
-		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
-	}
-
-	if (!addr) {
-		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
-		return 1;
-	}
 
-	data = readl(addr);
+	BUG_ON(!addr);
 
-	if (!ADDR_IN_WINDOW1(off))
+	if (ADDR_IN_WINDOW1(off)) {	/* Window 1 */
+		read_lock(&adapter->adapter_lock);
+		data = readl(addr);
+		read_unlock(&adapter->adapter_lock);
+	} else {		/* Window 0 */
+		write_lock_irqsave(&adapter->adapter_lock, flags);
+		netxen_nic_pci_change_crbwindow_128M(adapter, 0);
+		data = readl(addr);
 		netxen_nic_pci_change_crbwindow_128M(adapter, 1);
+		write_unlock_irqrestore(&adapter->adapter_lock, flags);
+	}
 
 	return data;
 }
 
-int
+static int
 netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 	int rv;
 
 	rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
@@ -1057,10 +1245,10 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
 	return 0;
 }
 
-u32
+static u32
 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
 {
-	unsigned long flags = 0;
+	unsigned long flags;
 	int rv;
 	u32 data;
 
@@ -1086,28 +1274,9 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
 	return data;
 }
 
-/*
- * check memory access boundary.
- * used by test agent. support ddr access only for now
- */
-static unsigned long
-netxen_nic_pci_mem_bound_check(struct netxen_adapter *adapter,
-		unsigned long long addr, int size)
-{
-	if (!ADDR_IN_RANGE(addr,
-			NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
-		!ADDR_IN_RANGE(addr+size-1,
-			NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX) ||
-		((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
-		return 0;
-	}
-
-	return 1;
-}
-
 static int netxen_pci_set_window_warning_count;
 
-unsigned long
+static unsigned long
 netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
 		unsigned long long addr)
 {
@@ -1171,22 +1340,56 @@ netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
 	return addr;
 }
 
-/*
- * Note : only 32-bit writes!
- */
-int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter,
-		u64 off, u32 data)
+/* window 1 registers only */
+static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
+		void __iomem *addr, u32 data)
 {
-	writel(data, (void __iomem *)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
-	return 0;
+	read_lock(&adapter->adapter_lock);
+	writel(data, addr);
+	read_unlock(&adapter->adapter_lock);
 }
 
-u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
+static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
+		void __iomem *addr)
 {
-	return readl((void __iomem *)(pci_base_offset(adapter, off)));
+	u32 val;
+
+	read_lock(&adapter->adapter_lock);
+	val = readl(addr);
+	read_unlock(&adapter->adapter_lock);
+
+	return val;
 }
 
-unsigned long
+static void netxen_nic_io_write_2M(struct netxen_adapter *adapter,
+		void __iomem *addr, u32 data)
+{
+	writel(data, addr);
+}
+
+static u32 netxen_nic_io_read_2M(struct netxen_adapter *adapter,
+		void __iomem *addr)
+{
+	return readl(addr);
+}
+
+void __iomem *
+netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
+{
+	ulong off = offset;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		if (offset < NETXEN_CRB_PCIX_HOST2 &&
+				offset > NETXEN_CRB_PCIX_HOST)
+			return PCI_OFFSET_SECOND_RANGE(adapter, offset);
+		return NETXEN_CRB_NORMALIZE(adapter, offset);
+	}
+
+	BUG_ON(netxen_nic_pci_get_crb_addr_2M(adapter, &off));
+	return (void __iomem *)off;
+}
+
+static unsigned long
 netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 		unsigned long long addr)
 {
@@ -1197,10 +1400,8 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 		/* DDR network side */
 		window = MN_WIN(addr);
 		adapter->ahw.ddr_mn_window = window;
-		NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-				window);
-		win_read = NXRD32(adapter,
-				adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
+		NXWR32(adapter, adapter->ahw.mn_win_crb, window);
+		win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
 		if ((win_read << 17) != window) {
 			printk(KERN_INFO "Written MNwin (0x%x) != "
 				"Read MNwin (0x%x)\n", window, win_read);
@@ -1215,10 +1416,8 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 
 		window = OCM_WIN(addr);
 		adapter->ahw.ddr_mn_window = window;
-		NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-				window);
-		win_read = NXRD32(adapter,
-				adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
+		NXWR32(adapter, adapter->ahw.mn_win_crb, window);
+		win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
 		if ((win_read >> 7) != window) {
 			printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
 					"Read OCMwin (0x%x)\n",
@@ -1231,10 +1430,8 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 		/* QDR network side */
 		window = MS_WIN(addr);
 		adapter->ahw.qdr_sn_window = window;
-		NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
-				window);
-		win_read = NXRD32(adapter,
-				adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
+		NXWR32(adapter, adapter->ahw.ms_win_crb, window);
+		win_read = NXRD32(adapter, adapter->ahw.ms_win_crb);
 		if (win_read != window) {
 			printk(KERN_INFO "%s: Written MSwin (0x%x) != "
 					"Read MSwin (0x%x)\n",
@@ -1257,180 +1454,9 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 	return addr;
 }
 
-static int netxen_nic_pci_is_same_window(struct netxen_adapter *adapter,
-				      unsigned long long addr)
-{
-	int window;
-	unsigned long long qdr_max;
-
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
-	else
-		qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
-
-	if (ADDR_IN_RANGE(addr,
-			NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
-		/* DDR network side */
-		BUG();	/* MN access can not come here */
-	} else if (ADDR_IN_RANGE(addr,
-			NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
-		return 1;
-	} else if (ADDR_IN_RANGE(addr,
-				NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
-		return 1;
-	} else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
-		/* QDR network side */
-		window = ((addr - NETXEN_ADDR_QDR_NET) >> 22) & 0x3f;
-		if (adapter->ahw.qdr_sn_window == window)
-			return 1;
-	}
-
-	return 0;
-}
-
-static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
-			u64 off, void *data, int size)
-{
-	unsigned long flags;
-	void __iomem *addr, *mem_ptr = NULL;
-	int ret = 0;
-	u64 start;
-	unsigned long mem_base;
-	unsigned long mem_page;
-
-	write_lock_irqsave(&adapter->adapter_lock, flags);
-
-	/*
-	 * If attempting to access unknown address or straddle hw windows,
-	 * do not access.
-	 */
-	start = adapter->pci_set_window(adapter, off);
-	if ((start == -1UL) ||
-		(netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-		printk(KERN_ERR "%s out of bound pci memory access. "
-			"offset is 0x%llx\n", netxen_nic_driver_name,
-			(unsigned long long)off);
-		return -1;
-	}
-
-	addr = pci_base_offset(adapter, start);
-	if (!addr) {
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-		mem_base = pci_resource_start(adapter->pdev, 0);
-		mem_page = start & PAGE_MASK;
-		/* Map two pages whenever user tries to access addresses in two
-		consecutive pages.
-		*/
-		if (mem_page != ((start + size - 1) & PAGE_MASK))
-			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
-		else
-			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
-		if (mem_ptr == NULL) {
-			*(uint8_t  *)data = 0;
-			return -1;
-		}
-		addr = mem_ptr;
-		addr += start & (PAGE_SIZE - 1);
-		write_lock_irqsave(&adapter->adapter_lock, flags);
-	}
-
-	switch (size) {
-	case 1:
-		*(uint8_t  *)data = readb(addr);
-		break;
-	case 2:
-		*(uint16_t *)data = readw(addr);
-		break;
-	case 4:
-		*(uint32_t *)data = readl(addr);
-		break;
-	case 8:
-		*(uint64_t *)data = readq(addr);
-		break;
-	default:
-		ret = -1;
-		break;
-	}
-	write_unlock_irqrestore(&adapter->adapter_lock, flags);
-
-	if (mem_ptr)
-		iounmap(mem_ptr);
-	return ret;
-}
-
-static int
-netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
-		void *data, int size)
-{
-	unsigned long flags;
-	void __iomem *addr, *mem_ptr = NULL;
-	int ret = 0;
-	u64 start;
-	unsigned long mem_base;
-	unsigned long mem_page;
-
-	write_lock_irqsave(&adapter->adapter_lock, flags);
-
-	/*
-	 * If attempting to access unknown address or straddle hw windows,
-	 * do not access.
-	 */
-	start = adapter->pci_set_window(adapter, off);
-	if ((start == -1UL) ||
-		(netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-		printk(KERN_ERR "%s out of bound pci memory access. "
-			"offset is 0x%llx\n", netxen_nic_driver_name,
-			(unsigned long long)off);
-		return -1;
-	}
-
-	addr = pci_base_offset(adapter, start);
-	if (!addr) {
-		write_unlock_irqrestore(&adapter->adapter_lock, flags);
-		mem_base = pci_resource_start(adapter->pdev, 0);
-		mem_page = start & PAGE_MASK;
-		/* Map two pages whenever user tries to access addresses in two
-		 * consecutive pages.
-		 */
-		if (mem_page != ((start + size - 1) & PAGE_MASK))
-			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
-		else
-			mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
-		if (mem_ptr == NULL)
-			return -1;
-		addr = mem_ptr;
-		addr += start & (PAGE_SIZE - 1);
-		write_lock_irqsave(&adapter->adapter_lock, flags);
-	}
-
-	switch (size) {
-	case 1:
-		writeb(*(uint8_t *)data, addr);
-		break;
-	case 2:
-		writew(*(uint16_t *)data, addr);
-		break;
-	case 4:
-		writel(*(uint32_t *)data, addr);
-		break;
-	case 8:
-		writeq(*(uint64_t *)data, addr);
-		break;
-	default:
-		ret = -1;
-		break;
-	}
-	write_unlock_irqrestore(&adapter->adapter_lock, flags);
-	if (mem_ptr)
-		iounmap(mem_ptr);
-	return ret;
-}
-
 #define MAX_CTL_CHECK   1000
 
-int
+static int
 netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
@@ -1440,19 +1466,28 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
 	uint64_t      off8, tmpw, word[2] = {0, 0};
 	void __iomem *mem_crb;
 
-	/*
-	 * If not MN, go check for MS or invalid.
-	 */
-	if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
-		return netxen_nic_pci_mem_write_direct(adapter,
-				off, data, size);
+	if (size != 8)
+		return -EIO;
 
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+				NETXEN_ADDR_QDR_NET_MAX_P2)) {
+		mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+		goto correct;
+	}
+
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+		mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+		goto correct;
+	}
+
+	return -EIO;
+
+correct:
 	off8 = off & 0xfffffff8;
 	off0 = off & 0x7;
 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
 	sz[1] = size - sz[0];
 	loop = ((off0 + size - 1) >> 3) + 1;
-	mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
 
 	if ((size != 8) || (off0 != 0))  {
 		for (i = 0; i < loop; i++) {
@@ -1523,7 +1558,7 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
 	return ret;
 }
 
-int
+static int
 netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
@@ -1533,20 +1568,29 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
 	uint64_t      off8, val, word[2] = {0, 0};
 	void __iomem *mem_crb;
 
+	if (size != 8)
+		return -EIO;
 
-	/*
-	 * If not MN, go check for MS or invalid.
-	 */
-	if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
-		return netxen_nic_pci_mem_read_direct(adapter, off, data, size);
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+				NETXEN_ADDR_QDR_NET_MAX_P2)) {
+		mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET);
+		goto correct;
+	}
+
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+		mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
+		goto correct;
+	}
+
+	return -EIO;
 
+correct:
 	off8 = off & 0xfffffff8;
 	off0[0] = off & 0x7;
 	off0[1] = 0;
 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
 	sz[1] = size - sz[0];
 	loop = ((off0[0] + size - 1) >> 3) + 1;
-	mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET);
 
 	write_lock_irqsave(&adapter->adapter_lock, flags);
 	netxen_nic_pci_change_crbwindow_128M(adapter, 0);
@@ -1614,26 +1658,32 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
 	return 0;
 }
 
-int
+static int
 netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
 	int i, j, ret = 0, loop, sz[2], off0;
 	uint32_t temp;
-	uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};
+	uint64_t off8, tmpw, word[2] = {0, 0};
+	void __iomem *mem_crb;
 
-	/*
-	 * If not MN, go check for MS or invalid.
-	 */
-	if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
-		mem_crb = NETXEN_CRB_QDR_NET;
-	else {
-		mem_crb = NETXEN_CRB_DDR_NET;
-		if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
-			return netxen_nic_pci_mem_write_direct(adapter,
-					off, data, size);
+	if (size != 8)
+		return -EIO;
+
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+				NETXEN_ADDR_QDR_NET_MAX_P3)) {
+		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+		goto correct;
 	}
 
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+		goto correct;
+	}
+
+	return -EIO;
+
+correct:
 	off8 = off & 0xfffffff8;
 	off0 = off & 0x7;
 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
@@ -1642,8 +1692,8 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 
 	if ((size != 8) || (off0 != 0)) {
 		for (i = 0; i < loop; i++) {
-			if (adapter->pci_mem_read(adapter, off8 + (i << 3),
-						&word[i], 8))
+			if (adapter->pci_mem_read(adapter,
+					off8 + (i << 3), &word[i], 8))
 				return -1;
 		}
 	}
@@ -1679,21 +1729,18 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 	 */
 
 	for (i = 0; i < loop; i++) {
-		temp = off8 + (i << 3);
-		NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
-		temp = 0;
-		NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
-		temp = word[i] & 0xffffffff;
-		NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
-		temp = (word[i] >> 32) & 0xffffffff;
-		NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
-		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
-		NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
-		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
-		NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
+		writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO);
+		writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI);
+		writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO);
+		writel((word[i] >> 32) & 0xffffffff,
+				mem_crb+MIU_TEST_AGT_WRDATA_HI);
+		writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE),
+				mem_crb+MIU_TEST_AGT_CTRL);
+		writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE,
+				mem_crb+MIU_TEST_AGT_CTRL);
 
 		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
+			temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
 			if ((temp & MIU_TA_CTL_BUSY) == 0)
 				break;
 		}
@@ -1714,27 +1761,32 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 	return ret;
 }
 
-int
+static int
 netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 		u64 off, void *data, int size)
 {
 	int i, j = 0, k, start, end, loop, sz[2], off0[2];
 	uint32_t      temp;
-	uint64_t      off8, val, mem_crb, word[2] = {0, 0};
+	uint64_t      off8, val, word[2] = {0, 0};
+	void __iomem *mem_crb;
 
-	/*
-	 * If not MN, go check for MS or invalid.
-	 */
+	if (size != 8)
+		return -EIO;
 
-	if (off >= NETXEN_ADDR_QDR_NET && off <= NETXEN_ADDR_QDR_NET_MAX_P3)
-		mem_crb = NETXEN_CRB_QDR_NET;
-	else {
-		mem_crb = NETXEN_CRB_DDR_NET;
-		if (netxen_nic_pci_mem_bound_check(adapter, off, size) == 0)
-			return netxen_nic_pci_mem_read_direct(adapter,
-					off, data, size);
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
+				NETXEN_ADDR_QDR_NET_MAX_P3)) {
+		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET);
+		goto correct;
 	}
 
+	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+		mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET);
+		goto correct;
+	}
+
+	return -EIO;
+
+correct:
 	off8 = off & 0xfffffff8;
 	off0[0] = off & 0x7;
 	off0[1] = 0;
@@ -1749,17 +1801,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 	 */
 
 	for (i = 0; i < loop; i++) {
-		temp = off8 + (i << 3);
-		NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
-		temp = 0;
-		NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
-		temp = MIU_TA_CTL_ENABLE;
-		NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
-		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
-		NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
+		writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO);
+		writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI);
+		writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL);
+		writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE,
+				mem_crb + MIU_TEST_AGT_CTRL);
 
 		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
+			temp = readl(mem_crb + MIU_TEST_AGT_CTRL);
 			if ((temp & MIU_TA_CTL_BUSY) == 0)
 				break;
 		}
@@ -1774,8 +1823,7 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 		start = off0[i] >> 2;
 		end   = (off0[i] + sz[i] - 1) >> 2;
 		for (k = start; k <= end; k++) {
-			temp = NXRD32(adapter,
-				mem_crb + MIU_TEST_AGT_RDDATA(k));
+			temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k));
 			word[i] |= ((uint64_t)temp << (32 * k));
 		}
 	}
@@ -1812,20 +1860,43 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 	return 0;
 }
 
-/*
- * Note : only 32-bit writes!
- */
-int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
-		u64 off, u32 data)
+void
+netxen_setup_hwops(struct netxen_adapter *adapter)
 {
-	NXWR32(adapter, off, data);
+	adapter->init_port = netxen_niu_xg_init_port;
+	adapter->stop_port = netxen_niu_disable_xg_port;
 
-	return 0;
-}
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		adapter->crb_read = netxen_nic_hw_read_wx_128M,
+		adapter->crb_write = netxen_nic_hw_write_wx_128M,
+		adapter->pci_set_window = netxen_nic_pci_set_window_128M,
+		adapter->pci_mem_read = netxen_nic_pci_mem_read_128M,
+		adapter->pci_mem_write = netxen_nic_pci_mem_write_128M,
+		adapter->io_read = netxen_nic_io_read_128M,
+		adapter->io_write = netxen_nic_io_write_128M,
+
+		adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
+		adapter->set_multi = netxen_p2_nic_set_multi;
+		adapter->set_mtu = netxen_nic_set_mtu_xgb;
+		adapter->set_promisc = netxen_p2_nic_set_promisc;
 
-u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
-{
-	return NXRD32(adapter, off);
+	} else {
+		adapter->crb_read = netxen_nic_hw_read_wx_2M,
+		adapter->crb_write = netxen_nic_hw_write_wx_2M,
+		adapter->pci_set_window = netxen_nic_pci_set_window_2M,
+		adapter->pci_mem_read = netxen_nic_pci_mem_read_2M,
+		adapter->pci_mem_write = netxen_nic_pci_mem_write_2M,
+		adapter->io_read = netxen_nic_io_read_2M,
+		adapter->io_write = netxen_nic_io_write_2M,
+
+		adapter->set_mtu = nx_fw_cmd_set_mtu;
+		adapter->set_promisc = netxen_p3_nic_set_promisc;
+		adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
+		adapter->set_multi = netxen_p3_nic_set_multi;
+
+		adapter->phy_read = nx_fw_cmd_query_phy;
+		adapter->phy_write = nx_fw_cmd_set_phy;
+	}
 }
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
@@ -1833,13 +1904,11 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 	int offset, board_type, magic, header_version;
 	struct pci_dev *pdev = adapter->pdev;
 
-	offset = NETXEN_BRDCFG_START +
-		offsetof(struct netxen_board_info, magic);
+	offset = NX_FW_MAGIC_OFFSET;
 	if (netxen_rom_fast_read(adapter, offset, &magic))
 		return -EIO;
 
-	offset = NETXEN_BRDCFG_START +
-		offsetof(struct netxen_board_info, header_version);
+	offset = NX_HDR_VERSION_OFFSET;
 	if (netxen_rom_fast_read(adapter, offset, &header_version))
 		return -EIO;
 
@@ -1851,8 +1920,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 		return -EIO;
 	}
 
-	offset = NETXEN_BRDCFG_START +
-		offsetof(struct netxen_board_info, board_type);
+	offset = NX_BRDTYPE_OFFSET;
 	if (netxen_rom_fast_read(adapter, offset, &board_type))
 		return -EIO;
 
@@ -1993,62 +2061,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 	}
 }
 
-void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
-{
-	u32 fw_major, fw_minor, fw_build;
-	char brd_name[NETXEN_MAX_SHORT_NAME];
-	char serial_num[32];
-	int i, addr, val;
-	int *ptr32;
-	struct pci_dev *pdev = adapter->pdev;
-
-	adapter->driver_mismatch = 0;
-
-	ptr32 = (int *)&serial_num;
-	addr = NETXEN_USER_START +
-	       offsetof(struct netxen_new_user_info, serial_num);
-	for (i = 0; i < 8; i++) {
-		if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
-			dev_err(&pdev->dev, "error reading board info\n");
-			adapter->driver_mismatch = 1;
-			return;
-		}
-		ptr32[i] = cpu_to_le32(val);
-		addr += sizeof(u32);
-	}
-
-	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
-	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
-	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
-
-	adapter->fw_major = fw_major;
-	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
-
-	if (adapter->portnum == 0) {
-		get_brd_name_by_type(adapter->ahw.board_type, brd_name);
-
-		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
-				brd_name, serial_num, adapter->ahw.revision_id);
-	}
-
-	if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
-		adapter->driver_mismatch = 1;
-		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
-				fw_major, fw_minor, fw_build);
-		return;
-	}
-
-	dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
-			fw_major, fw_minor, fw_build);
-
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-		i = NXRD32(adapter, NETXEN_SRE_MISC);
-		adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
-		dev_info(&pdev->dev, "firmware running in %s mode\n",
-		adapter->ahw.cut_through ? "cut-through" : "legacy");
-	}
-}
-
 int
 netxen_nic_wol_supported(struct netxen_adapter *adapter)
 {
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index d4e8333..3fd1dcb 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,19 +21,11 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #ifndef __NETXEN_NIC_HW_H_
 #define __NETXEN_NIC_HW_H_
 
-#include "netxen_nic_hdr.h"
-
 /* Hardware memory size of 128 meg */
 #define NETXEN_MEMADDR_MAX (128 * 1024 * 1024)
 
@@ -63,10 +56,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
  *	Bit 31: soft_reset => 1:reset the MAC and the SERDES, 0:no-op
  */
 
-#define netxen_gb_enable_tx(config_word)	\
-	((config_word) |= 1 << 0)
-#define netxen_gb_enable_rx(config_word)	\
-	((config_word) |= 1 << 2)
 #define netxen_gb_tx_flowctl(config_word)	\
 	((config_word) |= 1 << 4)
 #define netxen_gb_rx_flowctl(config_word)	\
@@ -79,8 +68,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
 	((config_word) |= 1 << 18)
 #define netxen_gb_rx_reset_mac(config_word)	\
 	((config_word) |= 1 << 19)
-#define netxen_gb_soft_reset(config_word)	\
-	((config_word) |= 1 << 31)
 
 #define netxen_gb_unset_tx_flowctl(config_word)	\
 	((config_word) &= ~(1 << 4))
@@ -242,7 +229,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
  * Bits 14-15 : speed => 0:10Mb/s, 1:100Mb/s, 2:1000Mb/s, 3:rsvd
  */
 
-#define netxen_get_phy_cablelen(config_word) (((config_word) >> 7) & 0x07)
 #define netxen_get_phy_speed(config_word) (((config_word) >> 14) & 0x03)
 
 #define netxen_set_phy_speed(config_word, val)	\
@@ -252,85 +238,12 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
 #define netxen_clear_phy_duplex(config_word)	\
 		((config_word) &= ~(1 << 13))
 
-#define netxen_get_phy_jabber(config_word)	\
-		_netxen_crb_get_bit(config_word, 0)
-#define netxen_get_phy_polarity(config_word)	\
-		_netxen_crb_get_bit(config_word, 1)
-#define netxen_get_phy_recvpause(config_word)	\
-		_netxen_crb_get_bit(config_word, 2)
-#define netxen_get_phy_xmitpause(config_word)	\
-		_netxen_crb_get_bit(config_word, 3)
-#define netxen_get_phy_energydetect(config_word) \
-		_netxen_crb_get_bit(config_word, 4)
-#define netxen_get_phy_downshift(config_word)	\
-		_netxen_crb_get_bit(config_word, 5)
-#define netxen_get_phy_crossover(config_word)	\
-		_netxen_crb_get_bit(config_word, 6)
 #define netxen_get_phy_link(config_word)	\
 		_netxen_crb_get_bit(config_word, 10)
-#define netxen_get_phy_resolved(config_word)	\
-		_netxen_crb_get_bit(config_word, 11)
-#define netxen_get_phy_pagercvd(config_word)	\
-		_netxen_crb_get_bit(config_word, 12)
 #define netxen_get_phy_duplex(config_word)	\
 		_netxen_crb_get_bit(config_word, 13)
 
 /*
- * Interrupt Register definition
- * This definition applies to registers 18 and 19 (int enable and int status).
- * Bit 0 : jabber
- * Bit 1 : polarity_changed
- * Bit 4 : energy_detect
- * Bit 5 : downshift
- * Bit 6 : mdi_xover_changed
- * Bit 7 : fifo_over_underflow
- * Bit 8 : false_carrier
- * Bit 9 : symbol_error
- * Bit 10: link_status_changed
- * Bit 11: autoneg_completed
- * Bit 12: page_received
- * Bit 13: duplex_changed
- * Bit 14: speed_changed
- * Bit 15: autoneg_error
- */
-
-#define netxen_get_phy_int_jabber(config_word)	\
-		_netxen_crb_get_bit(config_word, 0)
-#define netxen_get_phy_int_polarity_changed(config_word)	\
-		_netxen_crb_get_bit(config_word, 1)
-#define netxen_get_phy_int_energy_detect(config_word)	\
-		_netxen_crb_get_bit(config_word, 4)
-#define netxen_get_phy_int_downshift(config_word)	\
-		_netxen_crb_get_bit(config_word, 5)
-#define netxen_get_phy_int_mdi_xover_changed(config_word)	\
-		_netxen_crb_get_bit(config_word, 6)
-#define netxen_get_phy_int_fifo_over_underflow(config_word)	\
-		_netxen_crb_get_bit(config_word, 7)
-#define netxen_get_phy_int_false_carrier(config_word)	\
-		_netxen_crb_get_bit(config_word, 8)
-#define netxen_get_phy_int_symbol_error(config_word)	\
-		_netxen_crb_get_bit(config_word, 9)
-#define netxen_get_phy_int_link_status_changed(config_word)	\
-		_netxen_crb_get_bit(config_word, 10)
-#define netxen_get_phy_int_autoneg_completed(config_word)	\
-		_netxen_crb_get_bit(config_word, 11)
-#define netxen_get_phy_int_page_received(config_word)	\
-		_netxen_crb_get_bit(config_word, 12)
-#define netxen_get_phy_int_duplex_changed(config_word)	\
-		_netxen_crb_get_bit(config_word, 13)
-#define netxen_get_phy_int_speed_changed(config_word)	\
-		_netxen_crb_get_bit(config_word, 14)
-#define netxen_get_phy_int_autoneg_error(config_word)	\
-		_netxen_crb_get_bit(config_word, 15)
-
-#define netxen_set_phy_int_link_status_changed(config_word)	\
-		((config_word) |= 1 << 10)
-#define netxen_set_phy_int_autoneg_completed(config_word)	\
-		((config_word) |= 1 << 11)
-#define netxen_set_phy_int_speed_changed(config_word)	\
-		((config_word) |= 1 << 14)
-
-/*
  * NIU Mode Register.
  * Bit 0 : enable FibreChannel
  * Bit 1 : enable 10/100/1000 Ethernet
@@ -345,33 +258,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
 #define NETXEN_NIU_ALLMULTI_MODE	2
 
 /*
- * NIU GB Drop CRC Register
- *
- * Bit 0 : drop_gb0 => 1:drop pkts with bad CRCs, 0:pass them on
- * Bit 1 : drop_gb1 => 1:drop pkts with bad CRCs, 0:pass them on
- * Bit 2 : drop_gb2 => 1:drop pkts with bad CRCs, 0:pass them on
- * Bit 3 : drop_gb3 => 1:drop pkts with bad CRCs, 0:pass them on
- */
-
-#define netxen_set_gb_drop_gb0(config_word)	\
-		((config_word) |= 1 << 0)
-#define netxen_set_gb_drop_gb1(config_word)	\
-		((config_word) |= 1 << 1)
-#define netxen_set_gb_drop_gb2(config_word)	\
-		((config_word) |= 1 << 2)
-#define netxen_set_gb_drop_gb3(config_word)	\
-		((config_word) |= 1 << 3)
-
-#define netxen_clear_gb_drop_gb0(config_word)	\
-		((config_word) &= ~(1 << 0))
-#define netxen_clear_gb_drop_gb1(config_word)	\
-		((config_word) &= ~(1 << 1))
-#define netxen_clear_gb_drop_gb2(config_word)	\
-		((config_word) &= ~(1 << 2))
-#define netxen_clear_gb_drop_gb3(config_word)	\
-		((config_word) &= ~(1 << 3))
-
-/*
  * NIU XG MAC Config Register
  *
  * Bit 0 : tx_enable => 1:enable frame xmit, 0:disable
@@ -387,22 +273,6 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
 #define netxen_xg_soft_reset(config_word)	\
 		((config_word) |= 1 << 4)
 
-/* Set promiscuous mode for a GbE interface */
-int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
-				    u32 mode);
-int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
-				       u32 mode);
-
-/* Generic enable for GbE ports. Will detect the speed of the link. */
-int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port);
-
-int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port);
-
-/* Disable a GbE interface */
-int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter);
-
-int netxen_niu_disable_xg_port(struct netxen_adapter *adapter);
-
 typedef struct {
 	unsigned valid;
 	unsigned start_128M;
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 5d3343e..91c2bc6 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,19 +21,12 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #include <linux/netdevice.h>
 #include <linux/delay.h>
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
-#include "netxen_nic_phan_reg.h"
 
 struct crb_addr_pair {
 	u32 addr;
@@ -247,9 +241,14 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 				rds_ring->skb_size =
 					NX_CT_DEFAULT_RX_BUF_LEN;
 			} else {
-				rds_ring->dma_size = RX_DMA_MAP_LEN;
+				if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+					rds_ring->dma_size =
+						NX_P3_RX_BUF_MAX_LEN;
+				else
+					rds_ring->dma_size =
+						NX_P2_RX_BUF_MAX_LEN;
 				rds_ring->skb_size =
-					MAX_RX_BUFFER_LENGTH;
+					rds_ring->dma_size + NET_IP_ALIGN;
 			}
 			break;
 
@@ -261,14 +260,18 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 			else
 				rds_ring->dma_size =
 					NX_P2_RX_JUMBO_BUF_MAX_LEN;
+
+			if (adapter->capabilities & NX_CAP0_HW_LRO)
+				rds_ring->dma_size += NX_LRO_BUFFER_EXTRA;
+
 			rds_ring->skb_size =
 				rds_ring->dma_size + NET_IP_ALIGN;
 			break;
 
 		case RCV_RING_LRO:
 			rds_ring->num_desc = adapter->num_lro_rxd;
-			rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
-			rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+			rds_ring->dma_size = NX_RX_LRO_BUFFER_LENGTH;
+			rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN;
 			break;
 
 		}
@@ -315,48 +318,6 @@ err_out:
 	return -ENOMEM;
 }
 
-void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
-{
-	adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
-	adapter->set_multi = netxen_p2_nic_set_multi;
-
-	switch (adapter->ahw.port_type) {
-	case NETXEN_NIC_GBE:
-		adapter->enable_phy_interrupts =
-		    netxen_niu_gbe_enable_phy_interrupts;
-		adapter->disable_phy_interrupts =
-		    netxen_niu_gbe_disable_phy_interrupts;
-		adapter->set_mtu = netxen_nic_set_mtu_gb;
-		adapter->set_promisc = netxen_niu_set_promiscuous_mode;
-		adapter->phy_read = netxen_niu_gbe_phy_read;
-		adapter->phy_write = netxen_niu_gbe_phy_write;
-		adapter->init_port = netxen_niu_gbe_init_port;
-		adapter->stop_port = netxen_niu_disable_gbe_port;
-		break;
-
-	case NETXEN_NIC_XGBE:
-		adapter->enable_phy_interrupts =
-		    netxen_niu_xgbe_enable_phy_interrupts;
-		adapter->disable_phy_interrupts =
-		    netxen_niu_xgbe_disable_phy_interrupts;
-		adapter->set_mtu = netxen_nic_set_mtu_xgb;
-		adapter->init_port = netxen_niu_xg_init_port;
-		adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
-		adapter->stop_port = netxen_niu_disable_xg_port;
-		break;
-
-	default:
-		break;
-	}
-
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-		adapter->set_mtu = nx_fw_cmd_set_mtu;
-		adapter->set_promisc = netxen_p3_nic_set_promisc;
-		adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
-		adapter->set_multi = netxen_p3_nic_set_multi;
-	}
-}
-
 /*
  * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB
  * address to external PCI CRB address.
@@ -384,37 +345,7 @@ static u32 netxen_decode_crb_addr(u32 addr)
 		return (pci_base + offset);
 }
 
-static long rom_max_timeout = 100;
-static long rom_lock_timeout = 10000;
-
-static int rom_lock(struct netxen_adapter *adapter)
-{
-	int iter;
-	u32 done = 0;
-	int timeout = 0;
-
-	while (!done) {
-		/* acquire semaphore2 from PCI HW block */
-		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK));
-		if (done == 1)
-			break;
-		if (timeout >= rom_lock_timeout)
-			return -EIO;
-
-		timeout++;
-		/*
-		 * Yield CPU
-		 */
-		if (!in_atomic())
-			schedule();
-		else {
-			for (iter = 0; iter < 20; iter++)
-				cpu_relax();	/*This a nop instr on i386 */
-		}
-	}
-	NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
-	return 0;
-}
+#define NETXEN_MAX_ROM_WAIT_USEC	100
 
 static int netxen_wait_rom_done(struct netxen_adapter *adapter)
 {
@@ -426,22 +357,16 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
 	while (done == 0) {
 		done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS);
 		done &= 2;
-		timeout++;
-		if (timeout >= rom_max_timeout) {
-			printk("Timeout reached  waiting for rom done");
+		if (++timeout >= NETXEN_MAX_ROM_WAIT_USEC) {
+			dev_err(&adapter->pdev->dev,
+				"Timeout reached  waiting for rom done");
 			return -EIO;
 		}
+		udelay(1);
 	}
 	return 0;
 }
 
-static void netxen_rom_unlock(struct netxen_adapter *adapter)
-{
-	/* release semaphore2 */
-	NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK));
-
-}
-
 static int do_rom_fast_read(struct netxen_adapter *adapter,
 			    int addr, int *valp)
 {
@@ -486,7 +411,7 @@ netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
 {
 	int ret;
 
-	ret = rom_lock(adapter);
+	ret = netxen_rom_lock(adapter);
 	if (ret < 0)
 		return ret;
 
@@ -500,7 +425,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
 {
 	int ret;
 
-	if (rom_lock(adapter) != 0)
+	if (netxen_rom_lock(adapter) != 0)
 		return -EIO;
 
 	ret = do_rom_fast_read(adapter, addr, valp);
@@ -521,7 +446,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 	u32 off;
 
 	/* resetall */
-	rom_lock(adapter);
+	netxen_rom_lock(adapter);
 	NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
 	netxen_rom_unlock(adapter);
 
@@ -797,21 +722,28 @@ netxen_load_firmware(struct netxen_adapter *adapter)
 			flashaddr += 8;
 		}
 	} else {
-		u32 data;
+		u64 data;
+		u32 hi, lo;
 
-		size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
+		size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
 		flashaddr = NETXEN_BOOTLD_START;
 
 		for (i = 0; i < size; i++) {
 			if (netxen_rom_fast_read(adapter,
-					flashaddr, (int *)&data) != 0)
+					flashaddr, &lo) != 0)
+				return -EIO;
+			if (netxen_rom_fast_read(adapter,
+					flashaddr + 4, &hi) != 0)
 				return -EIO;
 
+			/* hi, lo are already in host endian byteorder */
+			data = (((u64)hi << 32) | lo);
+
 			if (adapter->pci_mem_write(adapter,
-						flashaddr, &data, 4))
+						flashaddr, &data, 8))
 				return -EIO;
 
-			flashaddr += 4;
+			flashaddr += 8;
 		}
 	}
 	msleep(1);
@@ -880,22 +812,10 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
 	return 0;
 }
 
-void netxen_request_firmware(struct netxen_adapter *adapter)
+static int
+netxen_p3_has_mn(struct netxen_adapter *adapter)
 {
 	u32 capability, flashed_ver;
-	u8 fw_type;
-	struct pci_dev *pdev = adapter->pdev;
-	int rc = 0;
-
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		fw_type = NX_P2_MN_ROMIMAGE;
-		goto request_fw;
-	} else {
-		fw_type = NX_P3_CT_ROMIMAGE;
-		goto request_fw;
-	}
-
-request_mn:
 	capability = 0;
 
 	netxen_rom_fast_read(adapter,
@@ -903,23 +823,35 @@ request_mn:
 	flashed_ver = NETXEN_DECODE_VERSION(flashed_ver);
 
 	if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
+
 		capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
-		if (capability & NX_PEG_TUNE_MN_PRESENT) {
-			fw_type = NX_P3_MN_ROMIMAGE;
-			goto request_fw;
-		}
+		if (capability & NX_PEG_TUNE_MN_PRESENT)
+			return 1;
 	}
+	return 0;
+}
 
-	fw_type = NX_FLASH_ROMIMAGE;
-	adapter->fw = NULL;
-	goto done;
+void netxen_request_firmware(struct netxen_adapter *adapter)
+{
+	u8 fw_type;
+	struct pci_dev *pdev = adapter->pdev;
+	int rc = 0;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		fw_type = NX_P2_MN_ROMIMAGE;
+		goto request_fw;
+	}
+
+	fw_type = netxen_p3_has_mn(adapter) ?
+		NX_P3_MN_ROMIMAGE : NX_P3_CT_ROMIMAGE;
 
 request_fw:
 	rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
 	if (rc != 0) {
-		if (fw_type == NX_P3_CT_ROMIMAGE) {
+		if (fw_type == NX_P3_MN_ROMIMAGE) {
 			msleep(1);
-			goto request_mn;
+			fw_type = NX_P3_CT_ROMIMAGE;
+			goto request_fw;
 		}
 
 		fw_type = NX_FLASH_ROMIMAGE;
@@ -931,9 +863,10 @@ request_fw:
 	if (rc != 0) {
 		release_firmware(adapter->fw);
 
-		if (fw_type == NX_P3_CT_ROMIMAGE) {
+		if (fw_type == NX_P3_MN_ROMIMAGE) {
 			msleep(1);
-			goto request_mn;
+			fw_type = NX_P3_CT_ROMIMAGE;
+			goto request_fw;
 		}
 
 		fw_type = NX_FLASH_ROMIMAGE;
@@ -951,21 +884,23 @@ netxen_release_firmware(struct netxen_adapter *adapter)
 {
 	if (adapter->fw)
 		release_firmware(adapter->fw);
+	adapter->fw = NULL;
 }
 
-int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
+int netxen_init_dummy_dma(struct netxen_adapter *adapter)
 {
-	uint64_t addr;
-	uint32_t hi;
-	uint32_t lo;
+	u64 addr;
+	u32 hi, lo;
+
+	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return 0;
 
-	adapter->dummy_dma.addr =
-	    pci_alloc_consistent(adapter->pdev,
+	adapter->dummy_dma.addr = pci_alloc_consistent(adapter->pdev,
 				 NETXEN_HOST_DUMMY_DMA_SIZE,
 				 &adapter->dummy_dma.phys_addr);
 	if (adapter->dummy_dma.addr == NULL) {
-		printk("%s: ERROR: Could not allocate dummy DMA memory\n",
-		       __func__);
+		dev_err(&adapter->pdev->dev,
+			"ERROR: Could not allocate dummy DMA memory\n");
 		return -ENOMEM;
 	}
 
@@ -976,29 +911,41 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
 	NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
 	NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
 
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-		uint32_t temp = 0;
-		NXWR32(adapter, CRB_HOST_DUMMY_BUF, temp);
-	}
-
 	return 0;
 }
 
-void netxen_free_adapter_offload(struct netxen_adapter *adapter)
+/*
+ * NetXen DMA watchdog control:
+ *
+ *	Bit 0		: enabled => R/O: 1 watchdog active, 0 inactive
+ *	Bit 1		: disable_request => 1 req disable dma watchdog
+ *	Bit 2		: enable_request =>  1 req enable dma watchdog
+ *	Bit 3-31	: unused
+ */
+void netxen_free_dummy_dma(struct netxen_adapter *adapter)
 {
 	int i = 100;
+	u32 ctrl;
+
+	if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return;
 
 	if (!adapter->dummy_dma.addr)
 		return;
 
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		do {
-			if (dma_watchdog_shutdown_request(adapter) == 1)
-				break;
+	ctrl = NXRD32(adapter, NETXEN_DMA_WATCHDOG_CTRL);
+	if ((ctrl & 0x1) != 0) {
+		NXWR32(adapter, NETXEN_DMA_WATCHDOG_CTRL, (ctrl | 0x2));
+
+		while ((ctrl & 0x1) != 0) {
+
 			msleep(50);
-			if (dma_watchdog_shutdown_poll_result(adapter) == 1)
+
+			ctrl = NXRD32(adapter, NETXEN_DMA_WATCHDOG_CTRL);
+
+			if (--i == 0)
 				break;
-		} while (--i);
+		};
 	}
 
 	if (i) {
@@ -1007,10 +954,8 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 			    adapter->dummy_dma.addr,
 			    adapter->dummy_dma.phys_addr);
 		adapter->dummy_dma.addr = NULL;
-	} else {
-		printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
-				adapter->netdev->name);
-	}
+	} else
+		dev_err(&adapter->pdev->dev, "dma_watchdog_shutdown failed\n");
 }
 
 int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
@@ -1083,10 +1028,6 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
 	NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
 	NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
 
-	if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) {
-		adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
-	}
-
 	return err;
 }
 
@@ -1222,20 +1163,31 @@ no_skb:
 
 static struct netxen_rx_buffer *
 netxen_process_rcv(struct netxen_adapter *adapter,
-		int ring, int index, int length, int cksum, int pkt_offset,
-		struct nx_host_sds_ring *sds_ring)
+		struct nx_host_sds_ring *sds_ring,
+		int ring, u64 sts_data0)
 {
 	struct net_device *netdev = adapter->netdev;
 	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 	struct netxen_rx_buffer *buffer;
 	struct sk_buff *skb;
-	struct nx_host_rds_ring *rds_ring = &recv_ctx->rds_rings[ring];
+	struct nx_host_rds_ring *rds_ring;
+	int index, length, cksum, pkt_offset;
 
-	if (unlikely(index > rds_ring->num_desc))
+	if (unlikely(ring >= adapter->max_rds_rings))
+		return NULL;
+
+	rds_ring = &recv_ctx->rds_rings[ring];
+
+	index = netxen_get_sts_refhandle(sts_data0);
+	if (unlikely(index >= rds_ring->num_desc))
 		return NULL;
 
 	buffer = &rds_ring->rx_buf_arr[index];
 
+	length = netxen_get_sts_totallength(sts_data0);
+	cksum  = netxen_get_sts_status(sts_data0);
+	pkt_offset = netxen_get_sts_pkt_offset(sts_data0);
+
 	skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
 	if (!skb)
 		return buffer;
@@ -1249,11 +1201,88 @@ netxen_process_rcv(struct netxen_adapter *adapter,
 	if (pkt_offset)
 		skb_pull(skb, pkt_offset);
 
+	skb->truesize = skb->len + sizeof(struct sk_buff);
 	skb->protocol = eth_type_trans(skb, netdev);
 
 	napi_gro_receive(&sds_ring->napi, skb);
 
-	adapter->stats.no_rcv++;
+	adapter->stats.rx_pkts++;
+	adapter->stats.rxbytes += length;
+
+	return buffer;
+}
+
+#define TCP_HDR_SIZE            20
+#define TCP_TS_OPTION_SIZE      12
+#define TCP_TS_HDR_SIZE         (TCP_HDR_SIZE + TCP_TS_OPTION_SIZE)
+
+static struct netxen_rx_buffer *
+netxen_process_lro(struct netxen_adapter *adapter,
+		struct nx_host_sds_ring *sds_ring,
+		int ring, u64 sts_data0, u64 sts_data1)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct netxen_rx_buffer *buffer;
+	struct sk_buff *skb;
+	struct nx_host_rds_ring *rds_ring;
+	struct iphdr *iph;
+	struct tcphdr *th;
+	bool push, timestamp;
+	int l2_hdr_offset, l4_hdr_offset;
+	int index;
+	u16 lro_length, length, data_offset;
+	u32 seq_number;
+
+	if (unlikely(ring > adapter->max_rds_rings))
+		return NULL;
+
+	rds_ring = &recv_ctx->rds_rings[ring];
+
+	index = netxen_get_lro_sts_refhandle(sts_data0);
+	if (unlikely(index > rds_ring->num_desc))
+		return NULL;
+
+	buffer = &rds_ring->rx_buf_arr[index];
+
+	timestamp = netxen_get_lro_sts_timestamp(sts_data0);
+	lro_length = netxen_get_lro_sts_length(sts_data0);
+	l2_hdr_offset = netxen_get_lro_sts_l2_hdr_offset(sts_data0);
+	l4_hdr_offset = netxen_get_lro_sts_l4_hdr_offset(sts_data0);
+	push = netxen_get_lro_sts_push_flag(sts_data0);
+	seq_number = netxen_get_lro_sts_seq_number(sts_data1);
+
+	skb = netxen_process_rxbuf(adapter, rds_ring, index, STATUS_CKSUM_OK);
+	if (!skb)
+		return buffer;
+
+	if (timestamp)
+		data_offset = l4_hdr_offset + TCP_TS_HDR_SIZE;
+	else
+		data_offset = l4_hdr_offset + TCP_HDR_SIZE;
+
+	skb_put(skb, lro_length + data_offset);
+
+	skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb);
+
+	skb_pull(skb, l2_hdr_offset);
+	skb->protocol = eth_type_trans(skb, netdev);
+
+	iph = (struct iphdr *)skb->data;
+	th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+
+	length = (iph->ihl << 2) + (th->doff << 2) + lro_length;
+	iph->tot_len = htons(length);
+	iph->check = 0;
+	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+	th->psh = push;
+	th->seq = htonl(seq_number);
+
+	length = skb->len;
+
+	netif_receive_skb(skb);
+
+	adapter->stats.lro_pkts++;
 	adapter->stats.rxbytes += length;
 
 	return buffer;
@@ -1275,27 +1304,33 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 	u32 consumer = sds_ring->consumer;
 
 	int count = 0;
-	u64 sts_data;
-	int opcode, ring, index, length, cksum, pkt_offset, desc_cnt;
+	u64 sts_data0, sts_data1;
+	int opcode, ring = 0, desc_cnt;
 
 	while (count < max) {
 		desc = &sds_ring->desc_head[consumer];
-		sts_data = le64_to_cpu(desc->status_desc_data[0]);
+		sts_data0 = le64_to_cpu(desc->status_desc_data[0]);
 
-		if (!(sts_data & STATUS_OWNER_HOST))
+		if (!(sts_data0 & STATUS_OWNER_HOST))
 			break;
 
-		desc_cnt = netxen_get_sts_desc_cnt(sts_data);
-		ring   = netxen_get_sts_type(sts_data);
-
-		if (ring > RCV_RING_JUMBO)
-			goto skip;
+		desc_cnt = netxen_get_sts_desc_cnt(sts_data0);
 
-		opcode = netxen_get_sts_opcode(sts_data);
+		opcode = netxen_get_sts_opcode(sts_data0);
 
 		switch (opcode) {
 		case NETXEN_NIC_RXPKT_DESC:
 		case NETXEN_OLD_RXPKT_DESC:
+		case NETXEN_NIC_SYN_OFFLOAD:
+			ring = netxen_get_sts_type(sts_data0);
+			rxbuf = netxen_process_rcv(adapter, sds_ring,
+					ring, sts_data0);
+			break;
+		case NETXEN_NIC_LRO_DESC:
+			ring = netxen_get_lro_sts_type(sts_data0);
+			sts_data1 = le64_to_cpu(desc->status_desc_data[1]);
+			rxbuf = netxen_process_lro(adapter, sds_ring,
+					ring, sts_data0, sts_data1);
 			break;
 		case NETXEN_NIC_RESPONSE_DESC:
 			netxen_handle_fw_message(desc_cnt, consumer, sds_ring);
@@ -1305,14 +1340,6 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 
 		WARN_ON(desc_cnt > 1);
 
-		index  = netxen_get_sts_refhandle(sts_data);
-		length = netxen_get_sts_totallength(sts_data);
-		cksum  = netxen_get_sts_status(sts_data);
-		pkt_offset = netxen_get_sts_pkt_offset(sts_data);
-
-		rxbuf = netxen_process_rcv(adapter, ring, index,
-				length, cksum, pkt_offset, sds_ring);
-
 		if (rxbuf)
 			list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
 
@@ -1347,7 +1374,7 @@ skip:
 
 	if (count) {
 		sds_ring->consumer = consumer;
-		NXWR32(adapter, sds_ring->crb_sts_consumer, consumer);
+		NXWRIO(adapter, sds_ring->crb_sts_consumer, consumer);
 	}
 
 	return count;
@@ -1402,8 +1429,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
 
 		if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
 			__netif_tx_lock(tx_ring->txq, smp_processor_id());
-			if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
+			if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) {
 				netif_wake_queue(netdev);
+				adapter->tx_timeo_cnt = 0;
+			}
 			__netif_tx_unlock(tx_ring->txq);
 		}
 	}
@@ -1465,10 +1494,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 
 	if (count) {
 		rds_ring->producer = producer;
-		NXWR32(adapter, rds_ring->crb_rcv_producer,
+		NXWRIO(adapter, rds_ring->crb_rcv_producer,
 				(producer-1) & (rds_ring->num_desc-1));
 
-		if (adapter->fw_major < 4) {
+		if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 			/*
 			 * Write a doorbell msg to tell phanmon of change in
 			 * receive ring producer
@@ -1481,9 +1510,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 					      (rds_ring->num_desc - 1)));
 			netxen_set_msg_ctxid(msg, adapter->portnum);
 			netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
-			writel(msg,
-			       DB_NORMALIZE(adapter,
+			read_lock(&adapter->adapter_lock);
+			writel(msg, DB_NORMALIZE(adapter,
 					    NETXEN_RCV_PRODUCER_OFFSET));
+			read_unlock(&adapter->adapter_lock);
 		}
 	}
 }
@@ -1525,7 +1555,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
 
 	if (count) {
 		rds_ring->producer = producer;
-		NXWR32(adapter, rds_ring->crb_rcv_producer,
+		NXWRIO(adapter, rds_ring->crb_rcv_producer,
 				(producer - 1) & (rds_ring->num_desc - 1));
 	}
 	spin_unlock(&rds_ring->lock);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 28f270f..f7bdde1 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2003 - 2009 NetXen, Inc.
+ * Copyright (C) 2009 - QLogic Corporation.
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -20,12 +21,6 @@
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
  *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
  */
 
 #include <linux/vmalloc.h>
@@ -33,12 +28,12 @@
 #include "netxen_nic_hw.h"
 
 #include "netxen_nic.h"
-#include "netxen_nic_phan_reg.h"
 
 #include <linux/dma-mapping.h>
 #include <linux/if_vlan.h>
 #include <net/ip.h>
 #include <linux/ipv6.h>
+#include <linux/inetdevice.h>
 
 MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
 MODULE_LICENSE("GPL");
@@ -63,18 +58,31 @@ static int __devinit netxen_nic_probe(struct pci_dev *pdev,
 static void __devexit netxen_nic_remove(struct pci_dev *pdev);
 static int netxen_nic_open(struct net_device *netdev);
 static int netxen_nic_close(struct net_device *netdev);
-static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *);
+static netdev_tx_t netxen_nic_xmit_frame(struct sk_buff *,
+					       struct net_device *);
 static void netxen_tx_timeout(struct net_device *netdev);
 static void netxen_tx_timeout_task(struct work_struct *work);
-static void netxen_watchdog(unsigned long);
+static void netxen_fw_poll_work(struct work_struct *work);
+static void netxen_schedule_work(struct netxen_adapter *adapter,
+		work_func_t func, int delay);
+static void netxen_cancel_fw_work(struct netxen_adapter *adapter);
 static int netxen_nic_poll(struct napi_struct *napi, int budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void netxen_nic_poll_controller(struct net_device *netdev);
 #endif
+
+static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
+static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
+
+static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
+static int netxen_can_start_firmware(struct netxen_adapter *adapter);
+
 static irqreturn_t netxen_intr(int irq, void *data);
 static irqreturn_t netxen_msi_intr(int irq, void *data);
 static irqreturn_t netxen_msix_intr(int irq, void *data);
 
+static void netxen_config_indev_addr(struct net_device *dev, unsigned long);
+
 /*  PCI Device ID Table  */
 #define ENTRY(device) \
 	{PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
@@ -94,8 +102,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
 
-static void netxen_watchdog(unsigned long);
-
 static uint32_t crb_cmd_producer[4] = {
 	CRB_CMD_PRODUCER_OFFSET, CRB_CMD_PRODUCER_OFFSET_1,
 	CRB_CMD_PRODUCER_OFFSET_2, CRB_CMD_PRODUCER_OFFSET_3
@@ -105,7 +111,7 @@ void
 netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
 		struct nx_host_tx_ring *tx_ring)
 {
-	NXWR32(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
+	NXWRIO(adapter, tx_ring->crb_cmd_producer, tx_ring->producer);
 
 	if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) {
 		netif_stop_queue(adapter->netdev);
@@ -122,7 +128,7 @@ static inline void
 netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
 		struct nx_host_tx_ring *tx_ring)
 {
-	NXWR32(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
+	NXWRIO(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer);
 }
 
 static uint32_t msi_tgt_status[8] = {
@@ -138,18 +144,17 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
 {
 	struct netxen_adapter *adapter = sds_ring->adapter;
 
-	NXWR32(adapter, sds_ring->crb_intr_mask, 0);
+	NXWRIO(adapter, sds_ring->crb_intr_mask, 0);
 }
 
 static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
 {
 	struct netxen_adapter *adapter = sds_ring->adapter;
 
-	NXWR32(adapter, sds_ring->crb_intr_mask, 0x1);
+	NXWRIO(adapter, sds_ring->crb_intr_mask, 0x1);
 
 	if (!NETXEN_IS_MSI_FAMILY(adapter))
-		adapter->pci_write_immediate(adapter,
-				adapter->legacy_intr.tgt_mask_reg, 0xfbff);
+		NXWRIO(adapter, adapter->tgt_mask_reg, 0xfbff);
 }
 
 static int
@@ -179,7 +184,7 @@ netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
 	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
 	if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
-		return 1;
+		return -ENOMEM;
 
 	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 		sds_ring = &recv_ctx->sds_rings[ring];
@@ -308,36 +313,6 @@ err_out:
 	return err;
 }
 
-static void netxen_check_options(struct netxen_adapter *adapter)
-{
-	if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
-		adapter->num_rxd = MAX_RCV_DESCRIPTORS_10G;
-	else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
-		adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
-
-	adapter->msix_supported = 0;
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-		adapter->msix_supported = !!use_msi_x;
-		adapter->rss_supported = !!use_msi_x;
-	} else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
-		switch (adapter->ahw.board_type) {
-		case NETXEN_BRDTYPE_P2_SB31_10G:
-		case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
-			adapter->msix_supported = !!use_msi_x;
-			adapter->rss_supported = !!use_msi_x;
-			break;
-		default:
-			break;
-		}
-	}
-
-	adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
-	adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
-	adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
-
-	return;
-}
-
 static int
 netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
 {
@@ -537,10 +512,22 @@ netxen_setup_intr(struct netxen_adapter *adapter)
 		legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
 	else
 		legacy_intrp = &legacy_intr[0];
-	adapter->legacy_intr.int_vec_bit = legacy_intrp->int_vec_bit;
-	adapter->legacy_intr.tgt_status_reg = legacy_intrp->tgt_status_reg;
-	adapter->legacy_intr.tgt_mask_reg = legacy_intrp->tgt_mask_reg;
-	adapter->legacy_intr.pci_int_reg = legacy_intrp->pci_int_reg;
+
+	adapter->int_vec_bit = legacy_intrp->int_vec_bit;
+	adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
+			legacy_intrp->tgt_status_reg);
+	adapter->tgt_mask_reg = netxen_get_ioaddr(adapter,
+			legacy_intrp->tgt_mask_reg);
+	adapter->pci_int_reg = netxen_get_ioaddr(adapter,
+			legacy_intrp->pci_int_reg);
+	adapter->isr_int_vec = netxen_get_ioaddr(adapter, ISR_INT_VECTOR);
+
+	if (adapter->ahw.revision_id >= NX_P3_B1)
+		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
+			ISR_INT_STATE_REG);
+	else
+		adapter->crb_int_state_reg = netxen_get_ioaddr(adapter,
+			CRB_INT_VECTOR);
 
 	netxen_set_msix_bit(pdev, 0);
 
@@ -567,8 +554,8 @@ netxen_setup_intr(struct netxen_adapter *adapter)
 
 	if (use_msi && !pci_enable_msi(pdev)) {
 		adapter->flags |= NETXEN_NIC_MSI_ENABLED;
-		adapter->msi_tgt_status =
-			msi_tgt_status[adapter->ahw.pci_func];
+		adapter->tgt_status_reg = netxen_get_ioaddr(adapter,
+				msi_tgt_status[adapter->ahw.pci_func]);
 		dev_info(&pdev->dev, "using msi interrupts\n");
 		adapter->msix_entries[0].vector = pdev->irq;
 		return;
@@ -628,14 +615,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 	mem_len = pci_resource_len(pdev, 0);
 	pci_len0 = 0;
 
-	adapter->hw_write_wx = netxen_nic_hw_write_wx_128M;
-	adapter->hw_read_wx = netxen_nic_hw_read_wx_128M;
-	adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M;
-	adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M;
-	adapter->pci_set_window = netxen_nic_pci_set_window_128M;
-	adapter->pci_mem_read = netxen_nic_pci_mem_read_128M;
-	adapter->pci_mem_write = netxen_nic_pci_mem_write_128M;
-
 	/* 128 Meg of memory */
 	if (mem_len == NETXEN_PCI_128MB_SIZE) {
 		mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE);
@@ -648,14 +627,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 		mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START -
 			SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE);
 	} else if (mem_len == NETXEN_PCI_2MB_SIZE) {
-		adapter->hw_write_wx = netxen_nic_hw_write_wx_2M;
-		adapter->hw_read_wx = netxen_nic_hw_read_wx_2M;
-		adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M;
-		adapter->pci_write_immediate =
-			netxen_nic_pci_write_immediate_2M;
-		adapter->pci_set_window = netxen_nic_pci_set_window_2M;
-		adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
-		adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
 
 		mem_ptr0 = pci_ioremap_bar(pdev, 0);
 		if (mem_ptr0 == NULL) {
@@ -667,9 +638,10 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 		adapter->ahw.ddr_mn_window = 0;
 		adapter->ahw.qdr_sn_window = 0;
 
-		adapter->ahw.mn_win_crb = 0x100000 + PCIX_MN_WINDOW +
-			(pci_func * 0x20);
-		adapter->ahw.ms_win_crb = 0x100000 + PCIX_SN_WINDOW;
+		adapter->ahw.mn_win_crb = NETXEN_PCI_CRBSPACE +
+			0x100000 + PCIX_MN_WINDOW + (pci_func * 0x20);
+		adapter->ahw.ms_win_crb = NETXEN_PCI_CRBSPACE +
+			0x100000 + PCIX_SN_WINDOW;
 		if (pci_func < 4)
 			adapter->ahw.ms_win_crb += (pci_func * 0x20);
 		else
@@ -679,6 +651,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
 		return -EIO;
 	}
 
+	netxen_setup_hwops(adapter);
+
 	dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20));
 
 	adapter->ahw.pci_base0 = mem_ptr0;
@@ -717,20 +691,111 @@ err_out:
 	return err;
 }
 
+static void
+netxen_check_options(struct netxen_adapter *adapter)
+{
+	u32 fw_major, fw_minor, fw_build;
+	char brd_name[NETXEN_MAX_SHORT_NAME];
+	char serial_num[32];
+	int i, offset, val;
+	int *ptr32;
+	struct pci_dev *pdev = adapter->pdev;
+
+	adapter->driver_mismatch = 0;
+
+	ptr32 = (int *)&serial_num;
+	offset = NX_FW_SERIAL_NUM_OFFSET;
+	for (i = 0; i < 8; i++) {
+		if (netxen_rom_fast_read(adapter, offset, &val) == -1) {
+			dev_err(&pdev->dev, "error reading board info\n");
+			adapter->driver_mismatch = 1;
+			return;
+		}
+		ptr32[i] = cpu_to_le32(val);
+		offset += sizeof(u32);
+	}
+
+	fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+	fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+	fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
+
+	adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
+
+	if (adapter->portnum == 0) {
+		get_brd_name_by_type(adapter->ahw.board_type, brd_name);
+
+		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
+				brd_name, serial_num, adapter->ahw.revision_id);
+	}
+
+	if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
+		adapter->driver_mismatch = 1;
+		dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
+				fw_major, fw_minor, fw_build);
+		return;
+	}
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		i = NXRD32(adapter, NETXEN_SRE_MISC);
+		adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0;
+	}
+
+	dev_info(&pdev->dev, "firmware v%d.%d.%d [%s]\n",
+			fw_major, fw_minor, fw_build,
+			adapter->ahw.cut_through ? "cut-through" : "legacy");
+
+	if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
+		adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+
+	adapter->flags &= ~NETXEN_NIC_LRO_ENABLED;
+
+	if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
+		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
+	} else if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
+		adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
+		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
+	}
+
+	adapter->msix_supported = 0;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		adapter->msix_supported = !!use_msi_x;
+		adapter->rss_supported = !!use_msi_x;
+	} else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
+		switch (adapter->ahw.board_type) {
+		case NETXEN_BRDTYPE_P2_SB31_10G:
+		case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+			adapter->msix_supported = !!use_msi_x;
+			adapter->rss_supported = !!use_msi_x;
+			break;
+		default:
+			break;
+		}
+	}
+
+	adapter->num_txd = MAX_CMD_DESCRIPTORS;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
+		adapter->max_rds_rings = 3;
+	} else {
+		adapter->num_lro_rxd = 0;
+		adapter->max_rds_rings = 2;
+	}
+}
+
 static int
-netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
+netxen_start_firmware(struct netxen_adapter *adapter)
 {
 	int val, err, first_boot;
 	struct pci_dev *pdev = adapter->pdev;
 
-	int first_driver = 0;
-
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-		first_driver = (adapter->portnum == 0);
-	else
-		first_driver = (adapter->ahw.pci_func == 0);
+	/* required for NX2031 dummy dma */
+	err = nx_set_dma_mask(adapter);
+	if (err)
+		return err;
 
-	if (!first_driver)
+	if (!netxen_can_start_firmware(adapter))
 		goto wait_init;
 
 	first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
@@ -741,12 +806,13 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 		return err;
 	}
 
-	if (request_fw)
-		netxen_request_firmware(adapter);
+	netxen_request_firmware(adapter);
 
 	err = netxen_need_fw_reset(adapter);
-	if (err <= 0)
-		return err;
+	if (err < 0)
+		goto err_out;
+	if (err == 0)
+		goto ready;
 
 	if (first_boot != 0x55555555) {
 		NXWR32(adapter, CRB_CMDPEG_STATE, 0);
@@ -755,10 +821,17 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 	}
 
 	NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
+	NXWR32(adapter, NETXEN_PEG_HALT_STATUS1, 0);
+	NXWR32(adapter, NETXEN_PEG_HALT_STATUS2, 0);
+
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		netxen_set_port_mode(adapter);
 
-	netxen_load_firmware(adapter);
+	err = netxen_load_firmware(adapter);
+	if (err)
+		goto err_out;
+
+	netxen_release_firmware(adapter);
 
 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 
@@ -770,9 +843,9 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 
 	}
 
-	err = netxen_initialize_adapter_offload(adapter);
+	err = netxen_init_dummy_dma(adapter);
 	if (err)
-		return err;
+		goto err_out;
 
 	/*
 	 * Tell the hardware our version number.
@@ -782,15 +855,28 @@ netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 		| (_NETXEN_NIC_LINUX_SUBVERSION);
 	NXWR32(adapter, CRB_DRIVER_VERSION, val);
 
+ready:
+	NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY);
+
 wait_init:
 	/* Handshake with the card before we register the devices. */
 	err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
 	if (err) {
-		netxen_free_adapter_offload(adapter);
-		return err;
+		netxen_free_dummy_dma(adapter);
+		goto err_out;
 	}
 
-	return 0;
+	nx_update_dma_mask(adapter);
+
+	netxen_check_options(adapter);
+
+	adapter->need_fw_reset = 0;
+
+	/* fall through and release firmware */
+
+err_out:
+	netxen_release_firmware(adapter);
+	return err;
 }
 
 static int
@@ -840,11 +926,28 @@ netxen_nic_free_irq(struct netxen_adapter *adapter)
 	}
 }
 
+static void
+netxen_nic_init_coalesce_defaults(struct netxen_adapter *adapter)
+{
+	adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT;
+	adapter->coal.normal.data.rx_time_us =
+		NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US;
+	adapter->coal.normal.data.rx_packets =
+		NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS;
+	adapter->coal.normal.data.tx_time_us =
+		NETXEN_DEFAULT_INTR_COALESCE_TX_TIME_US;
+	adapter->coal.normal.data.tx_packets =
+		NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS;
+}
+
 static int
 netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
 {
 	int err;
 
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return -EIO;
+
 	err = adapter->init_port(adapter, adapter->physical_port);
 	if (err) {
 		printk(KERN_ERR "%s: Failed to initialize port %d\n",
@@ -862,6 +965,12 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
 	if (adapter->max_sds_rings > 1)
 		netxen_config_rss(adapter, 1);
 
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		netxen_config_intr_coalesce(adapter);
+
+	if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
+		netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED);
+
 	netxen_napi_enable(adapter);
 
 	if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
@@ -869,14 +978,18 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
 	else
 		netxen_nic_set_link_parameters(adapter);
 
-	mod_timer(&adapter->watchdog_timer, jiffies);
-
+	set_bit(__NX_DEV_UP, &adapter->state);
 	return 0;
 }
 
 static void
 netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
 {
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return;
+
+	clear_bit(__NX_DEV_UP, &adapter->state);
+
 	spin_lock(&adapter->tx_clean_lock);
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
@@ -887,12 +1000,12 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		netxen_p3_free_mac_list(adapter);
 
+	adapter->set_promisc(adapter, NETXEN_NIU_NON_PROMISC_MODE);
+
 	netxen_napi_disable(adapter);
 
 	netxen_release_tx_buffers(adapter);
 	spin_unlock(&adapter->tx_clean_lock);
-
-	del_timer_sync(&adapter->watchdog_timer);
 }
 
 
@@ -905,6 +1018,9 @@ netxen_nic_attach(struct netxen_adapter *adapter)
 	struct nx_host_rds_ring *rds_ring;
 	struct nx_host_tx_ring *tx_ring;
 
+	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
+		return 0;
+
 	err = netxen_init_firmware(adapter);
 	if (err)
 		return err;
@@ -913,11 +1029,6 @@ netxen_nic_attach(struct netxen_adapter *adapter)
 	if (err)
 		return err;
 
-	if (adapter->fw_major < 4)
-		adapter->max_rds_rings = 3;
-	else
-		adapter->max_rds_rings = 2;
-
 	err = netxen_alloc_sw_resources(adapter);
 	if (err) {
 		printk(KERN_ERR "%s: Error in setting sw resources\n",
@@ -925,8 +1036,6 @@ netxen_nic_attach(struct netxen_adapter *adapter)
 		return err;
 	}
 
-	netxen_nic_clear_stats(adapter);
-
 	err = netxen_alloc_hw_resources(adapter);
 	if (err) {
 		printk(KERN_ERR "%s: Error in setting hw resources\n",
@@ -934,10 +1043,12 @@ netxen_nic_attach(struct netxen_adapter *adapter)
 		goto err_out_free_sw;
 	}
 
-	if (adapter->fw_major < 4) {
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 		tx_ring = adapter->tx_ring;
-		tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
-		tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
+		tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
+				crb_cmd_producer[adapter->portnum]);
+		tx_ring->crb_cmd_consumer = netxen_get_ioaddr(adapter,
+				crb_cmd_consumer[adapter->portnum]);
 
 		tx_ring->producer = 0;
 		tx_ring->sw_consumer = 0;
@@ -958,6 +1069,11 @@ netxen_nic_attach(struct netxen_adapter *adapter)
 		goto err_out_free_rxbuf;
 	}
 
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		netxen_nic_init_coalesce_defaults(adapter);
+
+	netxen_create_sysfs_entries(adapter);
+
 	adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
 	return 0;
 
@@ -972,6 +1088,11 @@ err_out_free_sw:
 static void
 netxen_nic_detach(struct netxen_adapter *adapter)
 {
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		return;
+
+	netxen_remove_sysfs_entries(adapter);
+
 	netxen_free_hw_resources(adapter);
 	netxen_release_rx_buffers(adapter);
 	netxen_nic_free_irq(adapter);
@@ -981,6 +1102,101 @@ netxen_nic_detach(struct netxen_adapter *adapter)
 	adapter->is_up = 0;
 }
 
+int
+netxen_nic_reset_context(struct netxen_adapter *adapter)
+{
+	int err = 0;
+	struct net_device *netdev = adapter->netdev;
+
+	if (test_and_set_bit(__NX_RESETTING, &adapter->state))
+		return -EBUSY;
+
+	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
+
+		netif_device_detach(netdev);
+
+		if (netif_running(netdev))
+			netxen_nic_down(adapter, netdev);
+
+		netxen_nic_detach(adapter);
+
+		if (netif_running(netdev)) {
+			err = netxen_nic_attach(adapter);
+			if (!err)
+				err = netxen_nic_up(adapter, netdev);
+
+			if (err)
+				goto done;
+		}
+
+		netif_device_attach(netdev);
+	}
+
+done:
+	clear_bit(__NX_RESETTING, &adapter->state);
+	return err;
+}
+
+static int
+netxen_setup_netdev(struct netxen_adapter *adapter,
+		struct net_device *netdev)
+{
+	int err = 0;
+	struct pci_dev *pdev = adapter->pdev;
+
+	adapter->rx_csum = 1;
+	adapter->mc_enabled = 0;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		adapter->max_mc_count = 38;
+	else
+		adapter->max_mc_count = 16;
+
+	netdev->netdev_ops	   = &netxen_netdev_ops;
+	netdev->watchdog_timeo     = 2*HZ;
+
+	netxen_nic_change_mtu(netdev, netdev->mtu);
+
+	SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
+
+	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+	netdev->features |= (NETIF_F_GRO);
+	netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+		netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
+	}
+
+	if (adapter->pci_using_dac) {
+		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
+
+	if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
+		netdev->features |= (NETIF_F_HW_VLAN_TX);
+
+	if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
+		netdev->features |= NETIF_F_LRO;
+
+	netdev->irq = adapter->msix_entries[0].vector;
+
+	INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
+
+	if (netxen_read_mac_addr(adapter))
+		dev_warn(&pdev->dev, "failed to read mac addr\n");
+
+	netif_carrier_off(netdev);
+	netif_stop_queue(netdev);
+
+	err = register_netdev(netdev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to register net device\n");
+		return err;
+	}
+
+	return 0;
+}
+
 static int __devinit
 netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1018,9 +1234,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netdev = alloc_etherdev(sizeof(struct netxen_adapter));
 	if(!netdev) {
-		printk(KERN_ERR"%s: Failed to allocate memory for the "
-				"device block.Check system memory resource"
-				" usage.\n", netxen_nic_driver_name);
+		dev_err(&pdev->dev, "failed to allocate net_device\n");
+		err = -ENOMEM;
 		goto err_out_free_res;
 	}
 
@@ -1034,10 +1249,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	revision_id = pdev->revision;
 	adapter->ahw.revision_id = revision_id;
 
-	err = nx_set_dma_mask(adapter);
-	if (err)
-		goto err_out_free_netdev;
-
 	rwlock_init(&adapter->adapter_lock);
 	spin_lock_init(&adapter->tx_clean_lock);
 	INIT_LIST_HEAD(&adapter->mac_list);
@@ -1048,43 +1259,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	/* This will be reset for mezz cards  */
 	adapter->portnum = pci_func_id;
-	adapter->rx_csum = 1;
-	adapter->mc_enabled = 0;
-	if (NX_IS_REVISION_P3(revision_id))
-		adapter->max_mc_count = 38;
-	else
-		adapter->max_mc_count = 16;
-
-	netdev->netdev_ops	   = &netxen_netdev_ops;
-	netdev->watchdog_timeo     = 2*HZ;
-
-	netxen_nic_change_mtu(netdev, netdev->mtu);
 
-	SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
-
-	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
-	netdev->features |= (NETIF_F_GRO);
-	netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
-
-	if (NX_IS_REVISION_P3(revision_id)) {
-		netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
-		netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
-	}
-
-	if (adapter->pci_using_dac) {
-		netdev->features |= NETIF_F_HIGHDMA;
-		netdev->vlan_features |= NETIF_F_HIGHDMA;
-	}
-
-	if (netxen_nic_get_board_info(adapter) != 0) {
-		printk("%s: Error getting board config info.\n",
-				netxen_nic_driver_name);
-		err = -EIO;
+	err = netxen_nic_get_board_info(adapter);
+	if (err) {
+		dev_err(&pdev->dev, "Error getting board config info.\n");
 		goto err_out_iounmap;
 	}
 
-	netxen_initialize_adapter_ops(adapter);
-
 	/* Mezz cards have PCI function 0,2,3 enabled */
 	switch (adapter->ahw.board_type) {
 	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -1096,53 +1277,32 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		break;
 	}
 
-	err = netxen_start_firmware(adapter, 1);
+	err = netxen_start_firmware(adapter);
 	if (err)
 		goto err_out_iounmap;
 
-	nx_update_dma_mask(adapter);
-
-	netxen_nic_get_firmware_info(adapter);
-
 	/*
 	 * See if the firmware gave us a virtual-physical port mapping.
 	 */
 	adapter->physical_port = adapter->portnum;
-	if (adapter->fw_major < 4) {
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 		i = NXRD32(adapter, CRB_V2P(adapter->portnum));
 		if (i != 0x55555555)
 			adapter->physical_port = i;
 	}
 
-	netxen_check_options(adapter);
+	netxen_nic_clear_stats(adapter);
 
 	netxen_setup_intr(adapter);
 
-	netdev->irq = adapter->msix_entries[0].vector;
-
-	init_timer(&adapter->watchdog_timer);
-	adapter->watchdog_timer.function = &netxen_watchdog;
-	adapter->watchdog_timer.data = (unsigned long)adapter;
-	INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
-	INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
-
-	err = netxen_read_mac_addr(adapter);
+	err = netxen_setup_netdev(adapter, netdev);
 	if (err)
-		dev_warn(&pdev->dev, "failed to read mac addr\n");
-
-	netif_carrier_off(netdev);
-	netif_stop_queue(netdev);
-
-	if ((err = register_netdev(netdev))) {
-		printk(KERN_ERR "%s: register_netdev failed port #%d"
-			       " aborting\n", netxen_nic_driver_name,
-			       adapter->portnum);
-		err = -EIO;
 		goto err_out_disable_msi;
-	}
 
 	pci_set_drvdata(pdev, adapter);
 
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+
 	switch (adapter->ahw.port_type) {
 	case NETXEN_NIC_GBE:
 		dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
@@ -1159,7 +1319,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 err_out_disable_msi:
 	netxen_teardown_intr(adapter);
 
-	netxen_free_adapter_offload(adapter);
+	netxen_free_dummy_dma(adapter);
+
+	nx_decr_dev_ref_cnt(adapter);
 
 err_out_iounmap:
 	netxen_cleanup_pci_map(adapter);
@@ -1187,17 +1349,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 	netdev = adapter->netdev;
 
+	netxen_cancel_fw_work(adapter);
+
 	unregister_netdev(netdev);
 
-	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->tx_timeout_task);
 
-	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
-		netxen_nic_detach(adapter);
-	}
+	netxen_nic_detach(adapter);
+
+	nx_decr_dev_ref_cnt(adapter);
 
 	if (adapter->portnum == 0)
-		netxen_free_adapter_offload(adapter);
+		netxen_free_dummy_dma(adapter);
+
+	clear_bit(__NX_RESETTING, &adapter->state);
 
 	netxen_teardown_intr(adapter);
 
@@ -1211,27 +1376,33 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 	free_netdev(netdev);
 }
-
-#ifdef CONFIG_PM
-static int
-netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+static int __netxen_nic_shutdown(struct pci_dev *pdev)
 {
-
 	struct netxen_adapter *adapter = pci_get_drvdata(pdev);
 	struct net_device *netdev = adapter->netdev;
+	int retval;
 
 	netif_device_detach(netdev);
 
+	netxen_cancel_fw_work(adapter);
+
 	if (netif_running(netdev))
 		netxen_nic_down(adapter, netdev);
 
-	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->tx_timeout_task);
 
-	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
-		netxen_nic_detach(adapter);
+	netxen_nic_detach(adapter);
+
+	if (adapter->portnum == 0)
+		netxen_free_dummy_dma(adapter);
+
+	nx_decr_dev_ref_cnt(adapter);
 
-	pci_save_state(pdev);
+	clear_bit(__NX_RESETTING, &adapter->state);
+
+	retval = pci_save_state(pdev);
+	if (retval)
+		return retval;
 
 	if (netxen_nic_wol_supported(adapter)) {
 		pci_enable_wake(pdev, PCI_D3cold, 1);
@@ -1239,10 +1410,27 @@ netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
 	}
 
 	pci_disable_device(pdev);
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
 }
+static void netxen_nic_shutdown(struct pci_dev *pdev)
+{
+	if (__netxen_nic_shutdown(pdev))
+		return;
+}
+#ifdef CONFIG_PM
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	int retval;
+
+	retval = __netxen_nic_shutdown(pdev);
+	if (retval)
+		return retval;
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
+}
 
 static int
 netxen_nic_resume(struct pci_dev *pdev)
@@ -1260,7 +1448,7 @@ netxen_nic_resume(struct pci_dev *pdev)
 
 	adapter->curr_window = 255;
 
-	err = netxen_start_firmware(adapter, 0);
+	err = netxen_start_firmware(adapter);
 	if (err) {
 		dev_err(&pdev->dev, "failed to start firmware\n");
 		return err;
@@ -1269,16 +1457,24 @@ netxen_nic_resume(struct pci_dev *pdev)
 	if (netif_running(netdev)) {
 		err = netxen_nic_attach(adapter);
 		if (err)
-			return err;
+			goto err_out;
 
 		err = netxen_nic_up(adapter, netdev);
 		if (err)
-			return err;
+			goto err_out_detach;
 
 		netif_device_attach(netdev);
+
+		netxen_config_indev_addr(netdev, NETDEV_UP);
 	}
 
-	return 0;
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+
+err_out_detach:
+	netxen_nic_detach(adapter);
+err_out:
+	nx_decr_dev_ref_cnt(adapter);
+	return err;
 }
 #endif
 
@@ -1290,11 +1486,9 @@ static int netxen_nic_open(struct net_device *netdev)
 	if (adapter->driver_mismatch)
 		return -EIO;
 
-	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
-		err = netxen_nic_attach(adapter);
-		if (err)
-			return err;
-	}
+	err = netxen_nic_attach(adapter);
+	if (err)
+		return err;
 
 	err = netxen_nic_up(adapter, netdev);
 	if (err)
@@ -1320,30 +1514,52 @@ static int netxen_nic_close(struct net_device *netdev)
 	return 0;
 }
 
-static bool netxen_tso_check(struct net_device *netdev,
-		      struct cmd_desc_type0 *desc, struct sk_buff *skb)
+static void
+netxen_tso_check(struct net_device *netdev,
+		struct nx_host_tx_ring *tx_ring,
+		struct cmd_desc_type0 *first_desc,
+		struct sk_buff *skb)
 {
-	bool tso = false;
 	u8 opcode = TX_ETHER_PKT;
 	__be16 protocol = skb->protocol;
-	u16 flags = 0;
+	u16 flags = 0, vid = 0;
+	u32 producer;
+	int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
+	struct cmd_desc_type0 *hwdesc;
+	struct vlan_ethhdr *vh;
 
 	if (protocol == cpu_to_be16(ETH_P_8021Q)) {
-		struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data;
+
+		vh = (struct vlan_ethhdr *)skb->data;
 		protocol = vh->h_vlan_encapsulated_proto;
 		flags = FLAGS_VLAN_TAGGED;
+
+	} else if (vlan_tx_tag_present(skb)) {
+
+		flags = FLAGS_VLAN_OOB;
+		vid = vlan_tx_tag_get(skb);
+		netxen_set_tx_vlan_tci(first_desc, vid);
+		vlan_oob = 1;
 	}
 
 	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
 			skb_shinfo(skb)->gso_size > 0) {
 
-		desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
-		desc->total_hdr_length =
-			skb_transport_offset(skb) + tcp_hdrlen(skb);
+		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+
+		first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+		first_desc->total_hdr_length = hdr_len;
+		if (vlan_oob) {
+			first_desc->total_hdr_length += VLAN_HLEN;
+			first_desc->tcp_hdr_offset = VLAN_HLEN;
+			first_desc->ip_hdr_offset = VLAN_HLEN;
+			/* Only in case of TSO on vlan device */
+			flags |= FLAGS_VLAN_TAGGED;
+		}
 
 		opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
 				TX_TCP_LSO6 : TX_TCP_LSO;
-		tso = true;
+		tso = 1;
 
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 l4proto;
@@ -1364,55 +1580,133 @@ static bool netxen_tso_check(struct net_device *netdev,
 				opcode = TX_UDPV6_PKT;
 		}
 	}
-	desc->tcp_hdr_offset = skb_transport_offset(skb);
-	desc->ip_hdr_offset = skb_network_offset(skb);
-	netxen_set_tx_flags_opcode(desc, flags, opcode);
-	return tso;
+
+	first_desc->tcp_hdr_offset += skb_transport_offset(skb);
+	first_desc->ip_hdr_offset += skb_network_offset(skb);
+	netxen_set_tx_flags_opcode(first_desc, flags, opcode);
+
+	if (!tso)
+		return;
+
+	/* For LSO, we need to copy the MAC/IP/TCP headers into
+	 * the descriptor ring
+	 */
+	producer = tx_ring->producer;
+	copied = 0;
+	offset = 2;
+
+	if (vlan_oob) {
+		/* Create a TSO vlan header template for firmware */
+
+		hwdesc = &tx_ring->desc_head[producer];
+		tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+		copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
+				hdr_len + VLAN_HLEN);
+
+		vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
+		skb_copy_from_linear_data(skb, vh, 12);
+		vh->h_vlan_proto = htons(ETH_P_8021Q);
+		vh->h_vlan_TCI = htons(vid);
+		skb_copy_from_linear_data_offset(skb, 12,
+				(char *)vh + 16, copy_len - 16);
+
+		copied = copy_len - VLAN_HLEN;
+		offset = 0;
+
+		producer = get_next_index(producer, tx_ring->num_desc);
+	}
+
+	while (copied < hdr_len) {
+
+		copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
+				(hdr_len - copied));
+
+		hwdesc = &tx_ring->desc_head[producer];
+		tx_ring->cmd_buf_arr[producer].skb = NULL;
+
+		skb_copy_from_linear_data_offset(skb, copied,
+				 (char *)hwdesc + offset, copy_len);
+
+		copied += copy_len;
+		offset = 0;
+
+		producer = get_next_index(producer, tx_ring->num_desc);
+	}
+
+	tx_ring->producer = producer;
+	barrier();
 }
 
-static void
-netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
-		struct netxen_cmd_buffer *pbuf, int last)
+static int
+netxen_map_tx_skb(struct pci_dev *pdev,
+		struct sk_buff *skb, struct netxen_cmd_buffer *pbuf)
 {
-	int k;
-	struct netxen_skb_frag *buffrag;
+	struct netxen_skb_frag *nf;
+	struct skb_frag_struct *frag;
+	int i, nr_frags;
+	dma_addr_t map;
+
+	nr_frags = skb_shinfo(skb)->nr_frags;
+	nf = &pbuf->frag_array[0];
 
-	buffrag = &pbuf->frag_array[0];
-	pci_unmap_single(pdev, buffrag->dma,
-			buffrag->length, PCI_DMA_TODEVICE);
+	map = pci_map_single(pdev, skb->data,
+			skb_headlen(skb), PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(pdev, map))
+		goto out_err;
 
-	for (k = 1; k < last; k++) {
-		buffrag = &pbuf->frag_array[k];
-		pci_unmap_page(pdev, buffrag->dma,
-			buffrag->length, PCI_DMA_TODEVICE);
+	nf->dma = map;
+	nf->length = skb_headlen(skb);
+
+	for (i = 0; i < nr_frags; i++) {
+		frag = &skb_shinfo(skb)->frags[i];
+		nf = &pbuf->frag_array[i+1];
+
+		map = pci_map_page(pdev, frag->page, frag->page_offset,
+				frag->size, PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, map))
+			goto unwind;
+
+		nf->dma = map;
+		nf->length = frag->size;
 	}
+
+	return 0;
+
+unwind:
+	while (--i >= 0) {
+		nf = &pbuf->frag_array[i+1];
+		pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
+	}
+
+	nf = &pbuf->frag_array[0];
+	pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
+
+out_err:
+	return -ENOMEM;
 }
 
 static inline void
 netxen_clear_cmddesc(u64 *desc)
 {
-	int i;
-	for (i = 0; i < 8; i++)
-		desc[i] = 0ULL;
+	desc[0] = 0ULL;
+	desc[2] = 0ULL;
 }
 
-static int
+static netdev_tx_t
 netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 	struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
-	unsigned int first_seg_len = skb->len - skb->data_len;
 	struct netxen_cmd_buffer *pbuf;
 	struct netxen_skb_frag *buffrag;
-	struct cmd_desc_type0 *hwdesc;
-	struct pci_dev *pdev = adapter->pdev;
-	dma_addr_t temp_dma;
+	struct cmd_desc_type0 *hwdesc, *first_desc;
+	struct pci_dev *pdev;
 	int i, k;
 
 	u32 producer;
 	int frag_count, no_of_desc;
 	u32 num_txd = tx_ring->num_desc;
-	bool is_tso = false;
 
 	frag_count = skb_shinfo(skb)->nr_frags + 1;
 
@@ -1425,121 +1719,60 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	producer = tx_ring->producer;
-
-	hwdesc = &tx_ring->desc_head[producer];
-	netxen_clear_cmddesc((u64 *)hwdesc);
 	pbuf = &tx_ring->cmd_buf_arr[producer];
 
-	is_tso = netxen_tso_check(netdev, hwdesc, skb);
+	pdev = adapter->pdev;
+
+	if (netxen_map_tx_skb(pdev, skb, pbuf))
+		goto drop_packet;
 
 	pbuf->skb = skb;
 	pbuf->frag_count = frag_count;
-	buffrag = &pbuf->frag_array[0];
-	temp_dma = pci_map_single(pdev, skb->data, first_seg_len,
-				      PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(pdev, temp_dma))
-		goto drop_packet;
 
-	buffrag->dma = temp_dma;
-	buffrag->length = first_seg_len;
-	netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
-	netxen_set_tx_port(hwdesc, adapter->portnum);
+	first_desc = hwdesc = &tx_ring->desc_head[producer];
+	netxen_clear_cmddesc((u64 *)hwdesc);
+
+	netxen_set_tx_frags_len(first_desc, frag_count, skb->len);
+	netxen_set_tx_port(first_desc, adapter->portnum);
 
-	hwdesc->buffer_length[0] = cpu_to_le16(first_seg_len);
-	hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
+	for (i = 0; i < frag_count; i++) {
 
-	for (i = 1, k = 1; i < frag_count; i++, k++) {
-		struct skb_frag_struct *frag;
-		int len, temp_len;
-		unsigned long offset;
+		k = i % 4;
 
-		/* move to next desc. if there is a need */
-		if ((i & 0x3) == 0) {
-			k = 0;
+		if ((k == 0) && (i > 0)) {
+			/* move to next desc.*/
 			producer = get_next_index(producer, num_txd);
 			hwdesc = &tx_ring->desc_head[producer];
 			netxen_clear_cmddesc((u64 *)hwdesc);
-			pbuf = &tx_ring->cmd_buf_arr[producer];
-			pbuf->skb = NULL;
-		}
-		frag = &skb_shinfo(skb)->frags[i - 1];
-		len = frag->size;
-		offset = frag->page_offset;
-
-		temp_len = len;
-		temp_dma = pci_map_page(pdev, frag->page, offset,
-					len, PCI_DMA_TODEVICE);
-		if (pci_dma_mapping_error(pdev, temp_dma)) {
-			netxen_clean_tx_dma_mapping(pdev, pbuf, i);
-			goto drop_packet;
+			tx_ring->cmd_buf_arr[producer].skb = NULL;
 		}
 
-		buffrag++;
-		buffrag->dma = temp_dma;
-		buffrag->length = temp_len;
+		buffrag = &pbuf->frag_array[i];
 
-		hwdesc->buffer_length[k] = cpu_to_le16(temp_len);
+		hwdesc->buffer_length[k] = cpu_to_le16(buffrag->length);
 		switch (k) {
 		case 0:
-			hwdesc->addr_buffer1 = cpu_to_le64(temp_dma);
+			hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
 			break;
 		case 1:
-			hwdesc->addr_buffer2 = cpu_to_le64(temp_dma);
+			hwdesc->addr_buffer2 = cpu_to_le64(buffrag->dma);
 			break;
 		case 2:
-			hwdesc->addr_buffer3 = cpu_to_le64(temp_dma);
+			hwdesc->addr_buffer3 = cpu_to_le64(buffrag->dma);
 			break;
 		case 3:
-			hwdesc->addr_buffer4 = cpu_to_le64(temp_dma);
+			hwdesc->addr_buffer4 = cpu_to_le64(buffrag->dma);
 			break;
 		}
-		frag++;
 	}
-	producer = get_next_index(producer, num_txd);
 
-	/* For LSO, we need to copy the MAC/IP/TCP headers into
-	 * the descriptor ring
-	 */
-	if (is_tso) {
-		int hdr_len, first_hdr_len, more_hdr;
-		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-		if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) {
-			first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
-			more_hdr = 1;
-		} else {
-			first_hdr_len = hdr_len;
-			more_hdr = 0;
-		}
-		/* copy the MAC/IP/TCP headers to the cmd descriptor list */
-		hwdesc = &tx_ring->desc_head[producer];
-		pbuf = &tx_ring->cmd_buf_arr[producer];
-		pbuf->skb = NULL;
-
-		/* copy the first 64 bytes */
-		memcpy(((void *)hwdesc) + 2,
-		       (void *)(skb->data), first_hdr_len);
-		producer = get_next_index(producer, num_txd);
-
-		if (more_hdr) {
-			hwdesc = &tx_ring->desc_head[producer];
-			pbuf = &tx_ring->cmd_buf_arr[producer];
-			pbuf->skb = NULL;
-			/* copy the next 64 bytes - should be enough except
-			 * for pathological case
-			 */
-			skb_copy_from_linear_data_offset(skb, first_hdr_len,
-							 hwdesc,
-							 (hdr_len -
-							  first_hdr_len));
-			producer = get_next_index(producer, num_txd);
-		}
-	}
+	tx_ring->producer = get_next_index(producer, num_txd);
 
-	tx_ring->producer = producer;
-	adapter->stats.txbytes += skb->len;
+	netxen_tso_check(netdev, tx_ring, first_desc, skb);
 
 	netxen_nic_update_cmd_producer(adapter, tx_ring);
 
+	adapter->stats.txbytes += skb->len;
 	adapter->stats.xmitcalled++;
 
 	return NETDEV_TX_OK;
@@ -1635,58 +1868,14 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
 	netxen_advert_link_change(adapter, linkup);
 }
 
-static void netxen_nic_thermal_shutdown(struct netxen_adapter *adapter)
-{
-	struct net_device *netdev = adapter->netdev;
-
-	netif_device_detach(netdev);
-	netxen_nic_down(adapter, netdev);
-	netxen_nic_detach(adapter);
-}
-
-static void netxen_watchdog(unsigned long v)
-{
-	struct netxen_adapter *adapter = (struct netxen_adapter *)v;
-
-	if (netxen_nic_check_temp(adapter))
-		goto do_sched;
-
-	if (!adapter->has_link_events) {
-		netxen_nic_handle_phy_intr(adapter);
-
-		if (adapter->link_changed)
-			goto do_sched;
-	}
-
-	if (netif_running(adapter->netdev))
-		mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-
-	return;
-
-do_sched:
-	schedule_work(&adapter->watchdog_task);
-}
-
-void netxen_watchdog_task(struct work_struct *work)
+static void netxen_tx_timeout(struct net_device *netdev)
 {
-	struct netxen_adapter *adapter =
-		container_of(work, struct netxen_adapter, watchdog_task);
+	struct netxen_adapter *adapter = netdev_priv(netdev);
 
-	if (adapter->temp == NX_TEMP_PANIC) {
-		netxen_nic_thermal_shutdown(adapter);
+	if (test_bit(__NX_RESETTING, &adapter->state))
 		return;
-	}
-
-	if (adapter->link_changed)
-		netxen_nic_set_link_parameters(adapter);
-
-	if (netif_running(adapter->netdev))
-		mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-}
 
-static void netxen_tx_timeout(struct net_device *netdev)
-{
-	struct netxen_adapter *adapter = netdev_priv(netdev);
+	dev_err(&netdev->dev, "transmit timeout, resetting.\n");
 	schedule_work(&adapter->tx_timeout_task);
 }
 
@@ -1698,15 +1887,37 @@ static void netxen_tx_timeout_task(struct work_struct *work)
 	if (!netif_running(adapter->netdev))
 		return;
 
-	printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
-	       netxen_nic_driver_name, adapter->netdev->name);
+	if (test_and_set_bit(__NX_RESETTING, &adapter->state))
+		return;
 
-	netxen_napi_disable(adapter);
+	if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS)
+		goto request_reset;
 
-	adapter->netdev->trans_start = jiffies;
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+		/* try to scrub interrupt */
+		netxen_napi_disable(adapter);
 
-	netxen_napi_enable(adapter);
-	netif_wake_queue(adapter->netdev);
+		adapter->netdev->trans_start = jiffies;
+
+		netxen_napi_enable(adapter);
+
+		netif_wake_queue(adapter->netdev);
+
+		goto done;
+
+	} else {
+		if (!netxen_nic_reset_context(adapter)) {
+			adapter->netdev->trans_start = jiffies;
+			goto done;
+		}
+
+		/* context reset failed, fall through for fw reset */
+	}
+
+request_reset:
+	adapter->need_fw_reset = 1;
+done:
+	clear_bit(__NX_RESETTING, &adapter->state);
 }
 
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
@@ -1716,7 +1927,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 
 	memset(stats, 0, sizeof(*stats));
 
-	stats->rx_packets = adapter->stats.no_rcv;
+	stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts;
 	stats->tx_packets = adapter->stats.xmitfinished;
 	stats->rx_bytes = adapter->stats.rxbytes;
 	stats->tx_bytes = adapter->stats.txbytes;
@@ -1732,41 +1943,37 @@ static irqreturn_t netxen_intr(int irq, void *data)
 	struct netxen_adapter *adapter = sds_ring->adapter;
 	u32 status = 0;
 
-	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+	status = readl(adapter->isr_int_vec);
 
-	if (!(status & adapter->legacy_intr.int_vec_bit))
+	if (!(status & adapter->int_vec_bit))
 		return IRQ_NONE;
 
-	if (adapter->ahw.revision_id >= NX_P3_B1) {
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
 		/* check interrupt state machine, to be sure */
-		status = adapter->pci_read_immediate(adapter,
-				ISR_INT_STATE_REG);
+		status = readl(adapter->crb_int_state_reg);
 		if (!ISR_LEGACY_INT_TRIGGERED(status))
 			return IRQ_NONE;
 
 	} else {
 		unsigned long our_int = 0;
 
-		our_int = NXRD32(adapter, CRB_INT_VECTOR);
+		our_int = readl(adapter->crb_int_state_reg);
 
 		/* not our interrupt */
 		if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
 			return IRQ_NONE;
 
 		/* claim interrupt */
-		NXWR32(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff));
-	}
+		writel((our_int & 0xffffffff), adapter->crb_int_state_reg);
 
-	/* clear interrupt */
-	if (adapter->fw_major < 4)
+		/* clear interrupt */
 		netxen_nic_disable_int(sds_ring);
+	}
 
-	adapter->pci_write_immediate(adapter,
-			adapter->legacy_intr.tgt_status_reg,
-			0xffffffff);
+	writel(0xffffffff, adapter->tgt_status_reg);
 	/* read twice to ensure write is flushed */
-	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
-	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+	readl(adapter->isr_int_vec);
+	readl(adapter->isr_int_vec);
 
 	napi_schedule(&sds_ring->napi);
 
@@ -1779,8 +1986,7 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
 	struct netxen_adapter *adapter = sds_ring->adapter;
 
 	/* clear interrupt */
-	adapter->pci_write_immediate(adapter,
-			adapter->msi_tgt_status, 0xffffffff);
+	writel(0xffffffff, adapter->tgt_status_reg);
 
 	napi_schedule(&sds_ring->napi);
 	return IRQ_HANDLED;
@@ -1827,6 +2033,473 @@ static void netxen_nic_poll_controller(struct net_device *netdev)
 }
 #endif
 
+static int
+nx_incr_dev_ref_cnt(struct netxen_adapter *adapter)
+{
+	int count;
+	if (netxen_api_lock(adapter))
+		return -EIO;
+
+	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+
+	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);
+
+	netxen_api_unlock(adapter);
+	return count;
+}
+
+static int
+nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
+{
+	int count;
+	if (netxen_api_lock(adapter))
+		return -EIO;
+
+	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+	WARN_ON(count == 0);
+
+	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, --count);
+
+	if (count == 0)
+		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_COLD);
+
+	netxen_api_unlock(adapter);
+	return count;
+}
+
+static void
+nx_dev_request_reset(struct netxen_adapter *adapter)
+{
+	u32 state;
+
+	if (netxen_api_lock(adapter))
+		return;
+
+	state = NXRD32(adapter, NX_CRB_DEV_STATE);
+
+	if (state != NX_DEV_INITALIZING)
+		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET);
+
+	netxen_api_unlock(adapter);
+}
+
+static int
+netxen_can_start_firmware(struct netxen_adapter *adapter)
+{
+	int count;
+	int can_start = 0;
+
+	if (netxen_api_lock(adapter))
+		return 0;
+
+	count = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
+
+	if ((count < 0) || (count >= NX_MAX_PCI_FUNC))
+		count = 0;
+
+	if (count == 0) {
+		can_start = 1;
+		NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_INITALIZING);
+	}
+
+	NXWR32(adapter, NX_CRB_DEV_REF_COUNT, ++count);
+
+	netxen_api_unlock(adapter);
+
+	return can_start;
+}
+
+static void
+netxen_schedule_work(struct netxen_adapter *adapter,
+		work_func_t func, int delay)
+{
+	INIT_DELAYED_WORK(&adapter->fw_work, func);
+	schedule_delayed_work(&adapter->fw_work, delay);
+}
+
+static void
+netxen_cancel_fw_work(struct netxen_adapter *adapter)
+{
+	while (test_and_set_bit(__NX_RESETTING, &adapter->state))
+		msleep(10);
+
+	cancel_delayed_work_sync(&adapter->fw_work);
+}
+
+static void
+netxen_attach_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+	struct net_device *netdev = adapter->netdev;
+	int err = 0;
+
+	if (netif_running(netdev)) {
+		err = netxen_nic_attach(adapter);
+		if (err)
+			goto done;
+
+		err = netxen_nic_up(adapter, netdev);
+		if (err) {
+			netxen_nic_detach(adapter);
+			goto done;
+		}
+
+		netxen_config_indev_addr(netdev, NETDEV_UP);
+	}
+
+	netif_device_attach(netdev);
+
+done:
+	adapter->fw_fail_cnt = 0;
+	clear_bit(__NX_RESETTING, &adapter->state);
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+}
+
+static void
+netxen_fwinit_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+	int dev_state;
+
+	dev_state = NXRD32(adapter, NX_CRB_DEV_STATE);
+
+	switch (dev_state) {
+	case NX_DEV_COLD:
+	case NX_DEV_READY:
+		if (!netxen_start_firmware(adapter)) {
+			netxen_schedule_work(adapter, netxen_attach_work, 0);
+			return;
+		}
+		break;
+
+	case NX_DEV_INITALIZING:
+		if (++adapter->fw_wait_cnt < FW_POLL_THRESH) {
+			netxen_schedule_work(adapter,
+					netxen_fwinit_work, 2 * FW_POLL_DELAY);
+			return;
+		}
+		break;
+
+	case NX_DEV_FAILED:
+	default:
+		break;
+	}
+
+	nx_incr_dev_ref_cnt(adapter);
+	clear_bit(__NX_RESETTING, &adapter->state);
+}
+
+static void
+netxen_detach_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+	struct net_device *netdev = adapter->netdev;
+	int ref_cnt, delay;
+	u32 status;
+
+	netif_device_detach(netdev);
+
+	if (netif_running(netdev))
+		netxen_nic_down(adapter, netdev);
+
+	netxen_nic_detach(adapter);
+
+	status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1);
+
+	ref_cnt = nx_decr_dev_ref_cnt(adapter);
+
+	if (status & NX_RCODE_FATAL_ERROR)
+		return;
+
+	if (adapter->temp == NX_TEMP_PANIC)
+		return;
+
+	delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY);
+
+	adapter->fw_wait_cnt = 0;
+	netxen_schedule_work(adapter, netxen_fwinit_work, delay);
+}
+
+static int
+netxen_check_health(struct netxen_adapter *adapter)
+{
+	u32 state, heartbit;
+	struct net_device *netdev = adapter->netdev;
+
+	if (netxen_nic_check_temp(adapter))
+		goto detach;
+
+	if (adapter->need_fw_reset) {
+		nx_dev_request_reset(adapter);
+		goto detach;
+	}
+
+	state = NXRD32(adapter, NX_CRB_DEV_STATE);
+	if (state == NX_DEV_NEED_RESET)
+		goto detach;
+
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return 0;
+
+	heartbit = NXRD32(adapter, NETXEN_PEG_ALIVE_COUNTER);
+	if (heartbit != adapter->heartbit) {
+		adapter->heartbit = heartbit;
+		adapter->fw_fail_cnt = 0;
+		return 0;
+	}
+
+	if (++adapter->fw_fail_cnt < FW_FAIL_THRESH)
+		return 0;
+
+	clear_bit(__NX_FW_ATTACHED, &adapter->state);
+
+	dev_info(&netdev->dev, "firmware hang detected\n");
+
+detach:
+	if (!test_and_set_bit(__NX_RESETTING, &adapter->state))
+		netxen_schedule_work(adapter, netxen_detach_work, 0);
+	return 1;
+}
+
+static void
+netxen_fw_poll_work(struct work_struct *work)
+{
+	struct netxen_adapter *adapter = container_of(work,
+				struct netxen_adapter, fw_work.work);
+
+	if (test_bit(__NX_RESETTING, &adapter->state))
+		goto reschedule;
+
+	if (test_bit(__NX_DEV_UP, &adapter->state)) {
+		if (!adapter->has_link_events) {
+
+			netxen_nic_handle_phy_intr(adapter);
+
+			if (adapter->link_changed)
+				netxen_nic_set_link_parameters(adapter);
+		}
+	}
+
+	if (netxen_check_health(adapter))
+		return;
+
+reschedule:
+	netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
+}
+
+static ssize_t
+netxen_store_bridged_mode(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct net_device *net = to_net_dev(dev);
+	struct netxen_adapter *adapter = netdev_priv(net);
+	unsigned long new;
+	int ret = -EINVAL;
+
+	if (!(adapter->capabilities & NX_FW_CAPABILITY_BDG))
+		goto err_out;
+
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		goto err_out;
+
+	if (strict_strtoul(buf, 2, &new))
+		goto err_out;
+
+	if (!netxen_config_bridged_mode(adapter, !!new))
+		ret = len;
+
+err_out:
+	return ret;
+}
+
+static ssize_t
+netxen_show_bridged_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct net_device *net = to_net_dev(dev);
+	struct netxen_adapter *adapter;
+	int bridged_mode = 0;
+
+	adapter = netdev_priv(net);
+
+	if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
+		bridged_mode = !!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED);
+
+	return sprintf(buf, "%d\n", bridged_mode);
+}
+
+static struct device_attribute dev_attr_bridged_mode = {
+       .attr = {.name = "bridged_mode", .mode = (S_IRUGO | S_IWUSR)},
+       .show = netxen_show_bridged_mode,
+       .store = netxen_store_bridged_mode,
+};
+
+static void
+netxen_create_sysfs_entries(struct netxen_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct device *dev = &netdev->dev;
+
+	if (adapter->capabilities & NX_FW_CAPABILITY_BDG) {
+		/* bridged_mode control */
+		if (device_create_file(dev, &dev_attr_bridged_mode)) {
+			dev_warn(&netdev->dev,
+				"failed to create bridged_mode sysfs entry\n");
+		}
+	}
+}
+
+static void
+netxen_remove_sysfs_entries(struct netxen_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct device *dev = &netdev->dev;
+
+	if (adapter->capabilities & NX_FW_CAPABILITY_BDG)
+		device_remove_file(dev, &dev_attr_bridged_mode);
+}
+
+#ifdef CONFIG_INET
+
+#define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops)
+
+static int
+netxen_destip_supported(struct netxen_adapter *adapter)
+{
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+		return 0;
+
+	if (adapter->ahw.cut_through)
+		return 0;
+
+	return 1;
+}
+
+static void
+netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+{
+	struct in_device *indev;
+	struct netxen_adapter *adapter = netdev_priv(dev);
+
+	if (!netxen_destip_supported(adapter))
+		return;
+
+	indev = in_dev_get(dev);
+	if (!indev)
+		return;
+
+	for_ifa(indev) {
+		switch (event) {
+		case NETDEV_UP:
+			netxen_config_ipaddr(adapter,
+					ifa->ifa_address, NX_IP_UP);
+			break;
+		case NETDEV_DOWN:
+			netxen_config_ipaddr(adapter,
+					ifa->ifa_address, NX_IP_DOWN);
+			break;
+		default:
+			break;
+		}
+	} endfor_ifa(indev);
+
+	in_dev_put(indev);
+	return;
+}
+
+static int netxen_netdev_event(struct notifier_block *this,
+				 unsigned long event, void *ptr)
+{
+	struct netxen_adapter *adapter;
+	struct net_device *dev = (struct net_device *)ptr;
+
+recheck:
+	if (dev == NULL)
+		goto done;
+
+	if (dev->priv_flags & IFF_802_1Q_VLAN) {
+		dev = vlan_dev_real_dev(dev);
+		goto recheck;
+	}
+
+	if (!is_netxen_netdev(dev))
+		goto done;
+
+	adapter = netdev_priv(dev);
+
+	if (!adapter)
+		goto done;
+
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		goto done;
+
+	netxen_config_indev_addr(dev, event);
+done:
+	return NOTIFY_DONE;
+}
+
+static int
+netxen_inetaddr_event(struct notifier_block *this,
+		unsigned long event, void *ptr)
+{
+	struct netxen_adapter *adapter;
+	struct net_device *dev;
+
+	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+
+	dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL;
+
+recheck:
+	if (dev == NULL || !netif_running(dev))
+		goto done;
+
+	if (dev->priv_flags & IFF_802_1Q_VLAN) {
+		dev = vlan_dev_real_dev(dev);
+		goto recheck;
+	}
+
+	if (!is_netxen_netdev(dev))
+		goto done;
+
+	adapter = netdev_priv(dev);
+
+	if (!adapter || !netxen_destip_supported(adapter))
+		goto done;
+
+	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
+		goto done;
+
+	switch (event) {
+	case NETDEV_UP:
+		netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_UP);
+		break;
+	case NETDEV_DOWN:
+		netxen_config_ipaddr(adapter, ifa->ifa_address, NX_IP_DOWN);
+		break;
+	default:
+		break;
+	}
+
+done:
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block	netxen_netdev_cb = {
+	.notifier_call = netxen_netdev_event,
+};
+
+static struct notifier_block netxen_inetaddr_cb = {
+	.notifier_call = netxen_inetaddr_event,
+};
+#else
+static void
+netxen_config_indev_addr(struct net_device *dev, unsigned long event)
+{ }
+#endif
+
 static struct pci_driver netxen_driver = {
 	.name = netxen_nic_driver_name,
 	.id_table = netxen_pci_tbl,
@@ -1834,16 +2507,20 @@ static struct pci_driver netxen_driver = {
 	.remove = __devexit_p(netxen_nic_remove),
 #ifdef CONFIG_PM
 	.suspend = netxen_nic_suspend,
-	.resume = netxen_nic_resume
+	.resume = netxen_nic_resume,
 #endif
+	.shutdown = netxen_nic_shutdown
 };
 
-/* Driver Registration on NetXen card    */
-
 static int __init netxen_init_module(void)
 {
 	printk(KERN_INFO "%s\n", netxen_nic_driver_string);
 
+#ifdef CONFIG_INET
+	register_netdevice_notifier(&netxen_netdev_cb);
+	register_inetaddr_notifier(&netxen_inetaddr_cb);
+#endif
+
 	return pci_register_driver(&netxen_driver);
 }
 
@@ -1852,6 +2529,11 @@ module_init(netxen_init_module);
 static void __exit netxen_exit_module(void)
 {
 	pci_unregister_driver(&netxen_driver);
+
+#ifdef CONFIG_INET
+	unregister_inetaddr_notifier(&netxen_inetaddr_cb);
+	unregister_netdevice_notifier(&netxen_netdev_cb);
+#endif
 }
 
 module_exit(netxen_exit_module);
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
deleted file mode 100644
index 5941c79..0000000
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Copyright (C) 2003 - 2009 NetXen, 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; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
- *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
- */
-
-#include "netxen_nic.h"
-
-#define NETXEN_GB_MAC_SOFT_RESET	0x80000000
-#define NETXEN_GB_MAC_RESET_PROT_BLK   0x000F0000
-#define NETXEN_GB_MAC_ENABLE_TX_RX     0x00000005
-#define NETXEN_GB_MAC_PAUSED_FRMS      0x00000020
-
-static long phy_lock_timeout = 100000000;
-
-static int phy_lock(struct netxen_adapter *adapter)
-{
-	int i;
-	int done = 0, timeout = 0;
-
-	while (!done) {
-		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
-		if (done == 1)
-			break;
-		if (timeout >= phy_lock_timeout) {
-			return -1;
-		}
-		timeout++;
-		if (!in_atomic())
-			schedule();
-		else {
-			for (i = 0; i < 20; i++)
-				cpu_relax();
-		}
-	}
-
-	NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
-	return 0;
-}
-
-static int phy_unlock(struct netxen_adapter *adapter)
-{
-	adapter->pci_read_immediate(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK));
-
-	return 0;
-}
-
-/*
- * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
- * mii management interface.
- *
- * Note: The MII management interface goes through port 0.
- *	Individual phys are addressed as follows:
- * @param phy  [15:8]  phy id
- * @param reg  [7:0]   register number
- *
- * @returns  0 on success
- *	  -1 on error
- *
- */
-int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
-				__u32 * readval)
-{
-	long timeout = 0;
-	long result = 0;
-	long restore = 0;
-	long phy = adapter->physical_port;
-	__u32 address;
-	__u32 command;
-	__u32 status;
-	__u32 mac_cfg0;
-
-	if (phy_lock(adapter) != 0) {
-		return -1;
-	}
-
-	/*
-	 * MII mgmt all goes through port 0 MAC interface,
-	 * so it cannot be in reset
-	 */
-
-	mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
-	if (netxen_gb_get_soft_reset(mac_cfg0)) {
-		__u32 temp;
-		temp = 0;
-		netxen_gb_tx_reset_pb(temp);
-		netxen_gb_rx_reset_pb(temp);
-		netxen_gb_tx_reset_mac(temp);
-		netxen_gb_rx_reset_mac(temp);
-		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
-			return -EIO;
-		restore = 1;
-	}
-
-	address = 0;
-	netxen_gb_mii_mgmt_reg_addr(address, reg);
-	netxen_gb_mii_mgmt_phy_addr(address, phy);
-	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
-		return -EIO;
-	command = 0;		/* turn off any prior activity */
-	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
-		return -EIO;
-	/* send read command */
-	netxen_gb_mii_mgmt_set_read_cycle(command);
-	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
-		return -EIO;
-
-	status = 0;
-	do {
-		status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
-		timeout++;
-	} while ((netxen_get_gb_mii_mgmt_busy(status)
-		  || netxen_get_gb_mii_mgmt_notvalid(status))
-		 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
-
-	if (timeout < NETXEN_NIU_PHY_WAITMAX) {
-		*readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
-		result = 0;
-	} else
-		result = -1;
-
-	if (restore)
-		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
-			return -EIO;
-	phy_unlock(adapter);
-	return result;
-}
-
-/*
- * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
- * mii management interface.
- *
- * Note: The MII management interface goes through port 0.
- *	Individual phys are addressed as follows:
- * @param phy      [15:8]  phy id
- * @param reg      [7:0]   register number
- *
- * @returns  0 on success
- *	  -1 on error
- *
- */
-int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
-				__u32 val)
-{
-	long timeout = 0;
-	long result = 0;
-	long restore = 0;
-	long phy = adapter->physical_port;
-	__u32 address;
-	__u32 command;
-	__u32 status;
-	__u32 mac_cfg0;
-
-	/*
-	 * MII mgmt all goes through port 0 MAC interface, so it
-	 * cannot be in reset
-	 */
-
-	mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
-	if (netxen_gb_get_soft_reset(mac_cfg0)) {
-		__u32 temp;
-		temp = 0;
-		netxen_gb_tx_reset_pb(temp);
-		netxen_gb_rx_reset_pb(temp);
-		netxen_gb_tx_reset_mac(temp);
-		netxen_gb_rx_reset_mac(temp);
-
-		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
-			return -EIO;
-		restore = 1;
-	}
-
-	command = 0;		/* turn off any prior activity */
-	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
-		return -EIO;
-
-	address = 0;
-	netxen_gb_mii_mgmt_reg_addr(address, reg);
-	netxen_gb_mii_mgmt_phy_addr(address, phy);
-	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
-		return -EIO;
-
-	if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
-		return -EIO;
-
-	status = 0;
-	do {
-		status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
-		timeout++;
-	} while ((netxen_get_gb_mii_mgmt_busy(status))
-		 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
-
-	if (timeout < NETXEN_NIU_PHY_WAITMAX)
-		result = 0;
-	else
-		result = -EIO;
-
-	/* restore the state of port 0 MAC in case we tampered with it */
-	if (restore)
-		if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
-			return -EIO;
-
-	return result;
-}
-
-int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
-{
-	NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x3f);
-	return 0;
-}
-
-int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
-{
-	int result = 0;
-	__u32 enable = 0;
-	netxen_set_phy_int_link_status_changed(enable);
-	netxen_set_phy_int_autoneg_completed(enable);
-	netxen_set_phy_int_speed_changed(enable);
-
-	if (0 !=
-	    netxen_niu_gbe_phy_write(adapter,
-				     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
-				     enable))
-		result = -EIO;
-
-	return result;
-}
-
-int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
-{
-	NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x7f);
-	return 0;
-}
-
-int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
-{
-	int result = 0;
-	if (0 !=
-	    netxen_niu_gbe_phy_write(adapter,
-				     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, 0))
-		result = -EIO;
-
-	return result;
-}
-
-static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
-{
-	int result = 0;
-	if (0 !=
-	    netxen_niu_gbe_phy_write(adapter,
-				     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
-				     -EIO))
-		result = -EIO;
-
-	return result;
-}
-
-/*
- * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
- *
- */
-static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
-					int port, long enable)
-{
-	NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
-	NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
-	NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
-	NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf1ff);
-	NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
-	NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
-	NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
-	NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
-
-	if (enable) {
-		/*
-		 * Do NOT enable flow control until a suitable solution for
-		 *  shutting down pause frames is found.
-		 */
-		NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
-	}
-
-	if (netxen_niu_gbe_enable_phy_interrupts(adapter))
-		printk(KERN_ERR "ERROR enabling PHY interrupts\n");
-	if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-		printk(KERN_ERR "ERROR clearing PHY interrupts\n");
-}
-
-/*
- * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
- */
-static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
-					 int port, long enable)
-{
-	NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
-	NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
-	NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
-	NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf2ff);
-	NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
-	NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
-	NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
-	NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
-
-	if (enable) {
-		/*
-		 * Do NOT enable flow control until a suitable solution for
-		 *  shutting down pause frames is found.
-		 */
-		NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
-	}
-
-	if (netxen_niu_gbe_enable_phy_interrupts(adapter))
-		printk(KERN_ERR "ERROR enabling PHY interrupts\n");
-	if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-		printk(KERN_ERR "ERROR clearing PHY interrupts\n");
-}
-
-int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
-{
-	int result = 0;
-	__u32 status;
-
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		return 0;
-
-	if (adapter->disable_phy_interrupts)
-		adapter->disable_phy_interrupts(adapter);
-	mdelay(2);
-
-	if (0 == netxen_niu_gbe_phy_read(adapter,
-			NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status)) {
-		if (netxen_get_phy_link(status)) {
-			if (netxen_get_phy_speed(status) == 2) {
-				netxen_niu_gbe_set_gmii_mode(adapter, port, 1);
-			} else if ((netxen_get_phy_speed(status) == 1)
-				   || (netxen_get_phy_speed(status) == 0)) {
-				netxen_niu_gbe_set_mii_mode(adapter, port, 1);
-			} else {
-				result = -1;
-			}
-
-		} else {
-			/*
-			 * We don't have link. Cable  must be unconnected.
-			 * Enable phy interrupts so we take action when
-			 * plugged in.
-			 */
-
-			NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-						    NETXEN_GB_MAC_SOFT_RESET);
-			NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-					    NETXEN_GB_MAC_RESET_PROT_BLK |
-					    NETXEN_GB_MAC_ENABLE_TX_RX |
-					    NETXEN_GB_MAC_PAUSED_FRMS);
-			if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-				printk(KERN_ERR
-				       "ERROR clearing PHY interrupts\n");
-			if (netxen_niu_gbe_enable_phy_interrupts(adapter))
-				printk(KERN_ERR
-				       "ERROR enabling PHY interrupts\n");
-			if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-				printk(KERN_ERR
-				       "ERROR clearing PHY interrupts\n");
-			result = -1;
-		}
-	} else {
-		result = -EIO;
-	}
-	return result;
-}
-
-int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
-{
-	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
-		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
-	}
-
-	return 0;
-}
-
-/* Disable a GbE interface */
-int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
-{
-	__u32 mac_cfg0;
-	u32 port = adapter->physical_port;
-
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		return 0;
-
-	if (port > NETXEN_NIU_MAX_GBE_PORTS)
-		return -EINVAL;
-	mac_cfg0 = 0;
-	netxen_gb_soft_reset(mac_cfg0);
-	if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0))
-		return -EIO;
-	return 0;
-}
-
-/* Disable an XG interface */
-int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
-{
-	__u32 mac_cfg;
-	u32 port = adapter->physical_port;
-
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		return 0;
-
-	if (port > NETXEN_NIU_MAX_XG_PORTS)
-		return -EINVAL;
-
-	mac_cfg = 0;
-	if (NXWR32(adapter,
-			NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
-		return -EIO;
-	return 0;
-}
-
-/* Set promiscuous mode for a GbE interface */
-int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
-		u32 mode)
-{
-	__u32 reg;
-	u32 port = adapter->physical_port;
-
-	if (port > NETXEN_NIU_MAX_GBE_PORTS)
-		return -EINVAL;
-
-	/* save previous contents */
-	reg = NXRD32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR);
-	if (mode == NETXEN_NIU_PROMISC_MODE) {
-		switch (port) {
-		case 0:
-			netxen_clear_gb_drop_gb0(reg);
-			break;
-		case 1:
-			netxen_clear_gb_drop_gb1(reg);
-			break;
-		case 2:
-			netxen_clear_gb_drop_gb2(reg);
-			break;
-		case 3:
-			netxen_clear_gb_drop_gb3(reg);
-			break;
-		default:
-			return -EIO;
-		}
-	} else {
-		switch (port) {
-		case 0:
-			netxen_set_gb_drop_gb0(reg);
-			break;
-		case 1:
-			netxen_set_gb_drop_gb1(reg);
-			break;
-		case 2:
-			netxen_set_gb_drop_gb2(reg);
-			break;
-		case 3:
-			netxen_set_gb_drop_gb3(reg);
-			break;
-		default:
-			return -EIO;
-		}
-	}
-	if (NXWR32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg))
-		return -EIO;
-	return 0;
-}
-
-int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
-		u32 mode)
-{
-	__u32 reg;
-	u32 port = adapter->physical_port;
-
-	if (port > NETXEN_NIU_MAX_XG_PORTS)
-		return -EINVAL;
-
-	reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
-	if (mode == NETXEN_NIU_PROMISC_MODE)
-		reg = (reg | 0x2000UL);
-	else
-		reg = (reg & ~0x2000UL);
-
-	if (mode == NETXEN_NIU_ALLMULTI_MODE)
-		reg = (reg | 0x1000UL);
-	else
-		reg = (reg & ~0x1000UL);
-
-	NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
-
-	return 0;
-}
-
-int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
-{
-	u32 mac_hi, mac_lo;
-	u32 reg_hi, reg_lo;
-
-	u8 phy = adapter->physical_port;
-	u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
-		NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
-
-	if (phy >= phy_count)
-		return -EINVAL;
-
-	mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
-	mac_hi = addr[2] | ((u32)addr[3] << 8) |
-		((u32)addr[4] << 16) | ((u32)addr[5] << 24);
-
-	if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
-		reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
-		reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
-	} else {
-		reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
-		reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
-	}
-
-	/* write twice to flush */
-	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
-		return -EIO;
-	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
-		return -EIO;
-
-	return 0;
-}
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
deleted file mode 100644
index b73a62c..0000000
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2003 - 2009 NetXen, 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; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.
- *
- * Contact Information:
- *    info@netxen.com
- * NetXen Inc,
- * 18922 Forge Drive
- * Cupertino, CA 95014-0701
- *
- */
-
-#ifndef __NIC_PHAN_REG_H_
-#define __NIC_PHAN_REG_H_
-
-/*
- * CRB Registers or queue message done only at initialization time.
- */
-#define NIC_CRB_BASE               NETXEN_CAM_RAM(0x200)
-#define NETXEN_NIC_REG(X)             (NIC_CRB_BASE+(X))
-#define NIC_CRB_BASE_2             NETXEN_CAM_RAM(0x700)
-#define NETXEN_NIC_REG_2(X)         (NIC_CRB_BASE_2+(X))
-
-#define CRB_PHAN_CNTRL_LO_OFFSET    NETXEN_NIC_REG(0x00)
-#define CRB_PHAN_CNTRL_HI_OFFSET    NETXEN_NIC_REG(0x04)
-#define CRB_CMD_PRODUCER_OFFSET     NETXEN_NIC_REG(0x08)
-#define CRB_CMD_CONSUMER_OFFSET     NETXEN_NIC_REG(0x0c)
-#define CRB_PAUSE_ADDR_LO           NETXEN_NIC_REG(0x10)
-#define CRB_PAUSE_ADDR_HI           NETXEN_NIC_REG(0x14)
-#define NX_CDRP_CRB_OFFSET          NETXEN_NIC_REG(0x18)
-#define NX_ARG1_CRB_OFFSET          NETXEN_NIC_REG(0x1c)
-#define NX_ARG2_CRB_OFFSET          NETXEN_NIC_REG(0x20)
-#define NX_ARG3_CRB_OFFSET          NETXEN_NIC_REG(0x24)
-#define NX_SIGN_CRB_OFFSET          NETXEN_NIC_REG(0x28)
-#define CRB_CMD_INTR_LOOP           NETXEN_NIC_REG(0x20)
-#define CRB_CMD_DMA_LOOP            NETXEN_NIC_REG(0x24)
-#define CRB_RCV_INTR_LOOP           NETXEN_NIC_REG(0x28)
-#define CRB_RCV_DMA_LOOP            NETXEN_NIC_REG(0x2c)
-#define CRB_ENABLE_TX_INTR          NETXEN_NIC_REG(0x30)
-#define CRB_MMAP_ADDR_3             NETXEN_NIC_REG(0x34)
-#define CRB_CMDPEG_CMDRING          NETXEN_NIC_REG(0x38)
-#define CRB_HOST_DUMMY_BUF_ADDR_HI  NETXEN_NIC_REG(0x3c)
-#define CRB_HOST_DUMMY_BUF_ADDR_LO  NETXEN_NIC_REG(0x40)
-#define CRB_MMAP_ADDR_0             NETXEN_NIC_REG(0x44)
-#define CRB_MMAP_ADDR_1             NETXEN_NIC_REG(0x48)
-#define CRB_MMAP_ADDR_2             NETXEN_NIC_REG(0x4c)
-#define CRB_CMDPEG_STATE            NETXEN_NIC_REG(0x50)
-#define CRB_MMAP_SIZE_0             NETXEN_NIC_REG(0x54)
-#define CRB_MMAP_SIZE_1             NETXEN_NIC_REG(0x58)
-#define CRB_MMAP_SIZE_2             NETXEN_NIC_REG(0x5c)
-#define CRB_MMAP_SIZE_3             NETXEN_NIC_REG(0x60)
-#define CRB_GLOBAL_INT_COAL         NETXEN_NIC_REG(0x64)
-#define CRB_INT_COAL_MODE           NETXEN_NIC_REG(0x68)
-#define CRB_MAX_RCV_BUFS            NETXEN_NIC_REG(0x6c)
-#define CRB_TX_INT_THRESHOLD        NETXEN_NIC_REG(0x70)
-#define CRB_RX_PKT_TIMER            NETXEN_NIC_REG(0x74)
-#define CRB_TX_PKT_TIMER            NETXEN_NIC_REG(0x78)
-#define CRB_RX_PKT_CNT              NETXEN_NIC_REG(0x7c)
-#define CRB_RX_TMR_CNT              NETXEN_NIC_REG(0x80)
-#define CRB_RX_LRO_TIMER            NETXEN_NIC_REG(0x84)
-#define CRB_RX_LRO_MID_TIMER        NETXEN_NIC_REG(0x88)
-#define CRB_DMA_MAX_RCV_BUFS        NETXEN_NIC_REG(0x8c)
-#define CRB_MAX_DMA_ENTRIES         NETXEN_NIC_REG(0x90)
-#define CRB_XG_STATE                NETXEN_NIC_REG(0x94) /* XG Link status */
-#define CRB_XG_STATE_P3             NETXEN_NIC_REG(0x98) /* XG PF Link status */
-#define CRB_AGENT_TX_SIZE           NETXEN_NIC_REG(0x9c)
-#define CRB_AGENT_TX_TYPE           NETXEN_NIC_REG(0xa0)
-#define CRB_AGENT_TX_ADDR           NETXEN_NIC_REG(0xa4)
-#define CRB_AGENT_TX_MSS            NETXEN_NIC_REG(0xa8)
-#define CRB_TX_STATE                NETXEN_NIC_REG(0xac)
-#define CRB_TX_COUNT                NETXEN_NIC_REG(0xb0)
-#define CRB_RX_STATE                NETXEN_NIC_REG(0xb4)
-#define CRB_RX_PERF_DEBUG_1         NETXEN_NIC_REG(0xb8)
-#define CRB_RX_LRO_CONTROL          NETXEN_NIC_REG(0xbc)
-#define CRB_RX_LRO_START_NUM        NETXEN_NIC_REG(0xc0)
-#define CRB_MPORT_MODE              NETXEN_NIC_REG(0xc4)
-#define CRB_CMD_RING_SIZE           NETXEN_NIC_REG(0xc8)
-#define CRB_DMA_SHIFT               NETXEN_NIC_REG(0xcc)
-#define CRB_INT_VECTOR              NETXEN_NIC_REG(0xd4)
-#define CRB_CTX_RESET               NETXEN_NIC_REG(0xd8)
-#define CRB_HOST_STS_PROD           NETXEN_NIC_REG(0xdc)
-#define CRB_HOST_STS_CONS           NETXEN_NIC_REG(0xe0)
-#define CRB_PEG_CMD_PROD            NETXEN_NIC_REG(0xe4)
-#define CRB_PF_LINK_SPEED_1         NETXEN_NIC_REG(0xe8)
-#define CRB_PF_LINK_SPEED_2         NETXEN_NIC_REG(0xec)
-#define CRB_HOST_BUFFER_CONS        NETXEN_NIC_REG(0xf0)
-#define CRB_JUMBO_BUFFER_PROD       NETXEN_NIC_REG(0xf4)
-#define CRB_JUMBO_BUFFER_CONS       NETXEN_NIC_REG(0xf8)
-#define CRB_HOST_DUMMY_BUF          NETXEN_NIC_REG(0xfc)
-
-#define CRB_RCVPEG_STATE            NETXEN_NIC_REG(0x13c)
-#define CRB_CMD_PRODUCER_OFFSET_1   NETXEN_NIC_REG(0x1ac)
-#define CRB_CMD_CONSUMER_OFFSET_1   NETXEN_NIC_REG(0x1b0)
-#define CRB_CMD_PRODUCER_OFFSET_2   NETXEN_NIC_REG(0x1b8)
-#define CRB_CMD_CONSUMER_OFFSET_2   NETXEN_NIC_REG(0x1bc)
-#define CRB_CMD_PRODUCER_OFFSET_3   NETXEN_NIC_REG(0x1d0)
-#define CRB_CMD_CONSUMER_OFFSET_3   NETXEN_NIC_REG(0x1d4)
-#define CRB_TEMP_STATE              NETXEN_NIC_REG(0x1b4)
-
-#define CRB_V2P_0		    NETXEN_NIC_REG(0x290)
-#define CRB_V2P_1		    NETXEN_NIC_REG(0x294)
-#define CRB_V2P_2		    NETXEN_NIC_REG(0x298)
-#define CRB_V2P_3		    NETXEN_NIC_REG(0x29c)
-#define CRB_V2P(port)		    (CRB_V2P_0+((port)*4))
-#define CRB_DRIVER_VERSION	   NETXEN_NIC_REG(0x2a0)
-#define CRB_SW_INT_MASK_0	   NETXEN_NIC_REG(0x1d8)
-#define CRB_SW_INT_MASK_1	   NETXEN_NIC_REG(0x1e0)
-#define CRB_SW_INT_MASK_2	   NETXEN_NIC_REG(0x1e4)
-#define CRB_SW_INT_MASK_3	   NETXEN_NIC_REG(0x1e8)
-
-#define CRB_FW_CAPABILITIES_1      NETXEN_CAM_RAM(0x128)
-#define CRB_MAC_BLOCK_START        NETXEN_CAM_RAM(0x1c0)
-
-/*
- * capabilities register, can be used to selectively enable/disable features
- * for backward compability
- */
-#define CRB_NIC_CAPABILITIES_HOST	NETXEN_NIC_REG(0x1a8)
-#define CRB_NIC_CAPABILITIES_FW	  	NETXEN_NIC_REG(0x1dc)
-#define CRB_NIC_MSI_MODE_HOST		NETXEN_NIC_REG(0x270)
-#define CRB_NIC_MSI_MODE_FW	  	NETXEN_NIC_REG(0x274)
-
-#define INTR_SCHEME_PERPORT	      	0x1
-#define MSI_MODE_MULTIFUNC	      	0x1
-
-/* used for ethtool tests */
-#define CRB_SCRATCHPAD_TEST	    NETXEN_NIC_REG(0x280)
-
-/*
- * CrbPortPhanCntrHi/Lo is used to pass the address of HostPhantomIndex address
- * which can be read by the Phantom host to get producer/consumer indexes from
- * Phantom/Casper. If it is not HOST_SHARED_MEMORY, then the following
- * registers will be used for the addresses of the ring's shared memory
- * on the Phantom.
- */
-
-#define nx_get_temp_val(x)		((x) >> 16)
-#define nx_get_temp_state(x)		((x) & 0xffff)
-#define nx_encode_temp(val, state)	(((val) << 16) | (state))
-
-/*
- * CRB registers used by the receive peg logic.
- */
-
-struct netxen_recv_crb {
-	u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
-	u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
-	u32 sw_int_mask[NUM_STS_DESC_RINGS];
-};
-
-/*
- * Temperature control.
- */
-enum {
-	NX_TEMP_NORMAL = 0x1,	/* Normal operating range */
-	NX_TEMP_WARN,		/* Sound alert, temperature getting high */
-	NX_TEMP_PANIC		/* Fatal error, hardware has shut down. */
-};
-
-#endif				/* __NIC_PHAN_REG_H_ */
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index 2a8da47..462d20f 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -463,7 +463,7 @@ static int ni5010_send_packet(struct sk_buff *skb, struct net_device *dev)
 	hardware_send_packet(dev, (unsigned char *)skb->data, skb->len, length-skb->len);
 	dev->trans_start = jiffies;
 	dev_kfree_skb (skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 77d44a0..bd0ac69 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -170,7 +170,7 @@ static int     ni52_probe1(struct net_device *dev, int ioaddr);
 static irqreturn_t ni52_interrupt(int irq, void *dev_id);
 static int     ni52_open(struct net_device *dev);
 static int     ni52_close(struct net_device *dev);
-static int     ni52_send_packet(struct sk_buff *, struct net_device *);
+static netdev_tx_t ni52_send_packet(struct sk_buff *, struct net_device *);
 static struct  net_device_stats *ni52_get_stats(struct net_device *dev);
 static void    set_multicast_list(struct net_device *dev);
 static void    ni52_timeout(struct net_device *dev);
@@ -1173,7 +1173,8 @@ static void ni52_timeout(struct net_device *dev)
  * send frame
  */
 
-static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ni52_send_packet(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	int len, i;
 #ifndef NO_NOPCOMMANDS
@@ -1183,7 +1184,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	if (skb->len > XMIT_BUFF_SIZE) {
 		printk(KERN_ERR "%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n", dev->name, XMIT_BUFF_SIZE, skb->len);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	netif_stop_queue(dev);
@@ -1267,7 +1268,7 @@ static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
 	}
 	dev_kfree_skb(skb);
 #endif
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*******************************************
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 1f10ed6..752c2e4 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -252,7 +252,8 @@ static void ni65_xmit_intr(struct net_device *dev,int);
 static int  ni65_open(struct net_device *dev);
 static int  ni65_lance_reinit(struct net_device *dev);
 static void ni65_init_lance(struct priv *p,unsigned char*,int,int);
-static int  ni65_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ni65_send_packet(struct sk_buff *skb,
+				    struct net_device *dev);
 static void  ni65_timeout(struct net_device *dev);
 static int  ni65_close(struct net_device *dev);
 static int  ni65_alloc_buffer(struct net_device *dev);
@@ -1157,7 +1158,8 @@ static void ni65_timeout(struct net_device *dev)
  *	Send a packet
  */
 
-static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ni65_send_packet(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct priv *p = dev->ml_priv;
 
@@ -1216,7 +1218,7 @@ static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
 		spin_unlock_irqrestore(&p->ring_lock, flags);
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void set_multicast_list(struct net_device *dev)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index d2146d4..76cc261 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -4015,7 +4015,7 @@ static void niu_xmac_interrupt(struct niu *np)
 		mp->rx_hist_cnt6 += RXMAC_HIST_CNT6_COUNT;
 	if (val & XRXMAC_STATUS_RXHIST7_CNT_EXP)
 		mp->rx_hist_cnt7 += RXMAC_HIST_CNT7_COUNT;
-	if (val & XRXMAC_STAT_MSK_RXOCTET_CNT_EXP)
+	if (val & XRXMAC_STATUS_RXOCTET_CNT_EXP)
 		mp->rx_octets += RXMAC_BT_CNT_COUNT;
 	if (val & XRXMAC_STATUS_CVIOLERR_CNT_EXP)
 		mp->rx_code_violations += RXMAC_CD_VIO_CNT_COUNT;
@@ -6657,7 +6657,8 @@ static u64 niu_compute_tx_flags(struct sk_buff *skb, struct ethhdr *ehdr,
 	return ret;
 }
 
-static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t niu_start_xmit(struct sk_buff *skb,
+				  struct net_device *dev)
 {
 	struct niu *np = netdev_priv(dev);
 	unsigned long align, headroom;
@@ -10144,11 +10145,6 @@ static const struct niu_ops niu_phys_ops = {
 	.unmap_single	= niu_phys_unmap_single,
 };
 
-static unsigned long res_size(struct resource *r)
-{
-	return r->end - r->start + 1UL;
-}
-
 static int __devinit niu_of_probe(struct of_device *op,
 				  const struct of_device_id *match)
 {
@@ -10188,7 +10184,7 @@ static int __devinit niu_of_probe(struct of_device *op,
 	dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM);
 
 	np->regs = of_ioremap(&op->resource[1], 0,
-			      res_size(&op->resource[1]),
+			      resource_size(&op->resource[1]),
 			      "niu regs");
 	if (!np->regs) {
 		dev_err(&op->dev, PFX "Cannot map device registers, "
@@ -10198,7 +10194,7 @@ static int __devinit niu_of_probe(struct of_device *op,
 	}
 
 	np->vir_regs_1 = of_ioremap(&op->resource[2], 0,
-				    res_size(&op->resource[2]),
+				    resource_size(&op->resource[2]),
 				    "niu vregs-1");
 	if (!np->vir_regs_1) {
 		dev_err(&op->dev, PFX "Cannot map device vir registers 1, "
@@ -10208,7 +10204,7 @@ static int __devinit niu_of_probe(struct of_device *op,
 	}
 
 	np->vir_regs_2 = of_ioremap(&op->resource[3], 0,
-				    res_size(&op->resource[3]),
+				    resource_size(&op->resource[3]),
 				    "niu vregs-2");
 	if (!np->vir_regs_2) {
 		dev_err(&op->dev, PFX "Cannot map device vir registers 2, "
@@ -10243,19 +10239,19 @@ static int __devinit niu_of_probe(struct of_device *op,
 err_out_iounmap:
 	if (np->vir_regs_1) {
 		of_iounmap(&op->resource[2], np->vir_regs_1,
-			   res_size(&op->resource[2]));
+			   resource_size(&op->resource[2]));
 		np->vir_regs_1 = NULL;
 	}
 
 	if (np->vir_regs_2) {
 		of_iounmap(&op->resource[3], np->vir_regs_2,
-			   res_size(&op->resource[3]));
+			   resource_size(&op->resource[3]));
 		np->vir_regs_2 = NULL;
 	}
 
 	if (np->regs) {
 		of_iounmap(&op->resource[1], np->regs,
-			   res_size(&op->resource[1]));
+			   resource_size(&op->resource[1]));
 		np->regs = NULL;
 	}
 
@@ -10280,19 +10276,19 @@ static int __devexit niu_of_remove(struct of_device *op)
 
 		if (np->vir_regs_1) {
 			of_iounmap(&op->resource[2], np->vir_regs_1,
-				   res_size(&op->resource[2]));
+				   resource_size(&op->resource[2]));
 			np->vir_regs_1 = NULL;
 		}
 
 		if (np->vir_regs_2) {
 			of_iounmap(&op->resource[3], np->vir_regs_2,
-				   res_size(&op->resource[3]));
+				   resource_size(&op->resource[3]));
 			np->vir_regs_2 = NULL;
 		}
 
 		if (np->regs) {
 			of_iounmap(&op->resource[1], np->regs,
-				   res_size(&op->resource[1]));
+				   resource_size(&op->resource[1]));
 			np->regs = NULL;
 		}
 
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 1576ac0..c594e19 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1077,7 +1077,8 @@ static void ns83820_cleanup_tx(struct ns83820 *dev)
  * while trying to track down a bug in either the zero copy code or
  * the tx fifo (hence the MAX_FRAG_LEN).
  */
-static int ns83820_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t ns83820_hard_start_xmit(struct sk_buff *skb,
+					   struct net_device *ndev)
 {
 	struct ns83820 *dev = PRIV(ndev);
 	u32 free_idx, cmdsts, extsts;
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
index 89f7b2a..0c44b48 100644
--- a/drivers/net/pci-skeleton.c
+++ b/drivers/net/pci-skeleton.c
@@ -1356,7 +1356,7 @@ static int netdrv_start_xmit (struct sk_buff *skb, struct net_device *dev)
 	DPRINTK ("%s: Queued Tx packet at %p size %u to slot %d.\n",
 		 dev->name, skb->data, skb->len, entry);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
@@ -1784,11 +1784,6 @@ static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 		break;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable (CAP_NET_ADMIN)) {
-			rc = -EPERM;
-			break;
-		}
-
 		spin_lock_irqsave (&tp->lock, flags);
 		mdio_write (dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
 		spin_unlock_irqrestore (&tp->lock, flags);
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index f35c609..ee8ad3e 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -85,6 +85,7 @@ earlier 3Com products.
 #include <linux/ioport.h>
 #include <linux/ethtool.h>
 #include <linux/bitops.h>
+#include <linux/mii.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -239,7 +240,8 @@ static void tc574_wait_for_completion(struct net_device *dev, int cmd);
 static void tc574_reset(struct net_device *dev);
 static void media_check(unsigned long arg);
 static int el3_open(struct net_device *dev);
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static irqreturn_t el3_interrupt(int irq, void *dev_id);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
@@ -778,7 +780,8 @@ static void pop_tx_status(struct net_device *dev)
 	}
 }
 
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
 	unsigned int ioaddr = dev->base_addr;
 	struct el3_private *lp = netdev_priv(dev);
@@ -806,7 +809,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	pop_tx_status(dev);
 	spin_unlock_irqrestore(&lp->window_lock, flags);
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The EL3 interrupt handler. */
@@ -1094,16 +1097,16 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct el3_private *lp = netdev_priv(dev);
 	unsigned int ioaddr = dev->base_addr;
-	u16 *data = (u16 *)&rq->ifr_ifru;
+	struct mii_ioctl_data *data = if_mii(rq);
 	int phy = lp->phys & 0x1f;
 
 	DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
 		  dev->name, rq->ifr_ifrn.ifrn_name, cmd,
-		  data[0], data[1], data[2], data[3]);
+		  data->phy_id, data->reg_num, data->val_in, data->val_out);
 
 	switch(cmd) {
 	case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
-		data[0] = phy;
+		data->phy_id = phy;
 	case SIOCGMIIREG:		/* Read the specified MII register. */
 		{
 			int saved_window;
@@ -1112,7 +1115,8 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 			spin_lock_irqsave(&lp->window_lock, flags);
 			saved_window = inw(ioaddr + EL3_CMD) >> 13;
 			EL3WINDOW(4);
-			data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
+			data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f,
+						  data->reg_num & 0x1f);
 			EL3WINDOW(saved_window);
 			spin_unlock_irqrestore(&lp->window_lock, flags);
 			return 0;
@@ -1122,12 +1126,11 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 			int saved_window;
                        unsigned long flags;
 
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
 			spin_lock_irqsave(&lp->window_lock, flags);
 			saved_window = inw(ioaddr + EL3_CMD) >> 13;
 			EL3WINDOW(4);
-			mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+			mdio_write(ioaddr, data->phy_id & 0x1f,
+				   data->reg_num & 0x1f, data->val_in);
 			EL3WINDOW(saved_window);
 			spin_unlock_irqrestore(&lp->window_lock, flags);
 			return 0;
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index 690b9c7..569fb06 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -149,7 +149,8 @@ static void tc589_reset(struct net_device *dev);
 static void media_check(unsigned long arg);
 static int el3_config(struct net_device *dev, struct ifmap *map);
 static int el3_open(struct net_device *dev);
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static irqreturn_t el3_interrupt(int irq, void *dev_id);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
@@ -604,7 +605,8 @@ static void pop_tx_status(struct net_device *dev)
     }
 }
 
-static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
     unsigned int ioaddr = dev->base_addr;
     struct el3_private *priv = netdev_priv(dev);
@@ -635,7 +637,7 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
     spin_unlock_irqrestore(&priv->lock, flags);    
     dev_kfree_skb(skb);
     
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 /* The EL3 interrupt handler. */
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 0e38d80..3131a59 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -37,6 +37,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/crc32.h>
+#include <linux/mii.h>
 #include "../8390.h"
 
 #include <pcmcia/cs_types.h>
@@ -92,7 +93,8 @@ static void axnet_release(struct pcmcia_device *link);
 static int axnet_open(struct net_device *dev);
 static int axnet_close(struct net_device *dev);
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
+					  struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
 static void axnet_tx_timeout(struct net_device *dev);
@@ -696,18 +698,16 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     axnet_dev_t *info = PRIV(dev);
-    u16 *data = (u16 *)&rq->ifr_ifru;
+    struct mii_ioctl_data *data = if_mii(rq);
     unsigned int mii_addr = dev->base_addr + AXNET_MII_EEP;
     switch (cmd) {
     case SIOCGMIIPHY:
-	data[0] = info->phy_id;
+	data->phy_id = info->phy_id;
     case SIOCGMIIREG:		/* Read MII PHY register. */
-	data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f);
+	data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f);
 	return 0;
     case SIOCSMIIREG:		/* Write MII PHY register. */
-	if (!capable(CAP_NET_ADMIN))
-	    return -EPERM;
-	mdio_write(mii_addr, data[0], data[1] & 0x1f, data[2]);
+	mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in);
 	return 0;
     }
     return -EOPNOTSUPP;
@@ -893,8 +893,6 @@ static const char version_8390[] = KERN_INFO \
 #include <linux/in.h>
 #include <linux/interrupt.h>
 
-#include <linux/etherdevice.h>
-
 #define BUG_83C690
 
 /* These are the operational function interfaces to board-specific
@@ -1065,7 +1063,8 @@ static void axnet_tx_timeout(struct net_device *dev)
  * Sends a packet to an 8390 network device.
  */
  
-static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t axnet_start_xmit(struct sk_buff *skb,
+					  struct net_device *dev)
 {
 	long e8390_base = dev->base_addr;
 	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
@@ -1179,7 +1178,7 @@ static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb (skb);
 	dev->stats.tx_bytes += send_length;
     
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 479d5b4..7e01fbd 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -96,7 +96,8 @@ static void fmvj18x_detach(struct pcmcia_device *p_dev);
 static int fjn_config(struct net_device *dev, struct ifmap *map);
 static int fjn_open(struct net_device *dev);
 static int fjn_close(struct net_device *dev);
-static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static irqreturn_t fjn_interrupt(int irq, void *dev_id);
 static void fjn_rx(struct net_device *dev);
 static void fjn_reset(struct net_device *dev);
@@ -856,7 +857,8 @@ static void fjn_tx_timeout(struct net_device *dev)
     netif_wake_queue(dev);
 }
 
-static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
     struct local_info_t *lp = netdev_priv(dev);
     unsigned int ioaddr = dev->base_addr;
@@ -865,7 +867,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
     if (length < ETH_ZLEN)
     {
     	if (skb_padto(skb, ETH_ZLEN))
-    		return 0;
+    		return NETDEV_TX_OK;
     	length = ETH_ZLEN;
     }
 
@@ -924,7 +926,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
     }
     dev_kfree_skb (skb);
 
-    return 0;
+    return NETDEV_TX_OK;
 } /* fjn_start_xmit */
 
 /*====================================================================*/
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 36de91b..5ed6339 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -424,7 +424,8 @@ static void nmclan_reset(struct net_device *dev);
 static int mace_config(struct net_device *dev, struct ifmap *map);
 static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
-static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
+					 struct net_device *dev);
 static void mace_tx_timeout(struct net_device *dev);
 static irqreturn_t mace_interrupt(int irq, void *dev_id);
 static struct net_device_stats *mace_get_stats(struct net_device *dev);
@@ -937,7 +938,8 @@ static void mace_tx_timeout(struct net_device *dev)
   netif_wake_queue(dev);
 }
 
-static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
+					 struct net_device *dev)
 {
   mace_private *lp = netdev_priv(dev);
   unsigned int ioaddr = dev->base_addr;
@@ -990,7 +992,7 @@ static int mace_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
   dev_kfree_skb(skb);
 
-  return 0;
+  return NETDEV_TX_OK;
 } /* mace_start_xmit */
 
 /* ----------------------------------------------------------------------------
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 9ef1c1b..97db1c7 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -40,6 +40,7 @@
 #include <linux/netdevice.h>
 #include <linux/log2.h>
 #include <linux/etherdevice.h>
+#include <linux/mii.h>
 #include "../8390.h"
 
 #include <pcmcia/cs_types.h>
@@ -1191,7 +1192,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     pcnet_dev_t *info = PRIV(dev);
-    u16 *data = (u16 *)&rq->ifr_ifru;
+    struct mii_ioctl_data *data = if_mii(rq);
     unsigned int mii_addr = dev->base_addr + DLINK_GPIO;
 
     if (!(info->flags & (IS_DL10019|IS_DL10022)))
@@ -1199,14 +1200,12 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
     switch (cmd) {
     case SIOCGMIIPHY:
-	data[0] = info->phy_id;
+	data->phy_id = info->phy_id;
     case SIOCGMIIREG:		/* Read MII PHY register. */
-	data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f);
+	data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f);
 	return 0;
     case SIOCSMIIREG:		/* Write MII PHY register. */
-	if (!capable(CAP_NET_ADMIN))
-	    return -EPERM;
-	mdio_write(mii_addr, data[0], data[1] & 0x1f, data[2]);
+	mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in);
 	return 0;
     }
     return -EOPNOTSUPP;
@@ -1751,11 +1750,11 @@ static struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078),
 	/* too generic! */
 	/* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"),
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 37e05d3..7bde2cd 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -288,7 +288,8 @@ static int smc_open(struct net_device *dev);
 static int smc_close(struct net_device *dev);
 static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void smc_tx_timeout(struct net_device *dev);
-static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static irqreturn_t smc_interrupt(int irq, void *dev_id);
 static void smc_rx(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
@@ -1370,7 +1371,8 @@ static void smc_tx_timeout(struct net_device *dev)
     netif_wake_queue(dev);
 }
 
-static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
     struct smc_private *smc = netdev_priv(dev);
     unsigned int ioaddr = dev->base_addr;
@@ -1399,7 +1401,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb (skb);
 	smc->saved_skb = NULL;
 	dev->stats.tx_dropped++;
-	return 0;		/* Do not re-queue this packet. */
+	return NETDEV_TX_OK;		/* Do not re-queue this packet. */
     }
     /* A packet is now waiting. */
     smc->packets_waiting++;
@@ -1422,7 +1424,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	    outw((ir&0xff00) | IM_ALLOC_INT, ioaddr + INTERRUPT);
 	    smc_hardware_send_packet(dev);	/* Send the packet now.. */
 	    spin_unlock_irqrestore(&smc->lock, flags);
-	    return 0;
+	    return NETDEV_TX_OK;
 	}
     }
 
@@ -1431,7 +1433,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
     outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
     spin_unlock_irqrestore(&smc->lock, flags);
 
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 /*======================================================================
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index ef37d22..cf84231 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -80,6 +80,7 @@
 #include <linux/if_arp.h>
 #include <linux/ioport.h>
 #include <linux/bitops.h>
+#include <linux/mii.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -352,7 +353,8 @@ typedef struct local_info_t {
 /****************
  * Some more prototypes
  */
-static int do_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t do_start_xmit(struct sk_buff *skb,
+				       struct net_device *dev);
 static void xirc_tx_timeout(struct net_device *dev);
 static void xirc2ps_tx_timeout_task(struct work_struct *work);
 static void set_addresses(struct net_device *dev);
@@ -1361,7 +1363,7 @@ xirc_tx_timeout(struct net_device *dev)
     schedule_work(&lp->tx_timeout_task);
 }
 
-static int
+static netdev_tx_t
 do_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
     local_info_t *lp = netdev_priv(dev);
@@ -1384,7 +1386,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
     if (pktlen < ETH_ZLEN)
     {
         if (skb_padto(skb, ETH_ZLEN))
-        	return 0;
+        	return NETDEV_TX_OK;
 	pktlen = ETH_ZLEN;
     }
 
@@ -1414,7 +1416,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
     dev->trans_start = jiffies;
     dev->stats.tx_bytes += pktlen;
     netif_start_queue(dev);
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 /****************
@@ -1557,26 +1559,26 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
     local_info_t *local = netdev_priv(dev);
     unsigned int ioaddr = dev->base_addr;
-    u16 *data = (u16 *)&rq->ifr_ifru;
+    struct mii_ioctl_data *data = if_mii(rq);
 
     DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
 	  dev->name, rq->ifr_ifrn.ifrn_name, cmd,
-	  data[0], data[1], data[2], data[3]);
+	  data->phy_id, data->reg_num, data->val_in, data->val_out);
 
     if (!local->mohawk)
 	return -EOPNOTSUPP;
 
     switch(cmd) {
       case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
-	data[0] = 0;		/* we have only this address */
+	data->phy_id = 0;	/* we have only this address */
 	/* fall through */
       case SIOCGMIIREG:		/* Read the specified MII register. */
-	data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
+	data->val_out = mii_rd(ioaddr, data->phy_id & 0x1f,
+			       data->reg_num & 0x1f);
 	break;
       case SIOCSMIIREG:		/* Write the specified MII register */
-	if (!capable(CAP_NET_ADMIN))
-	    return -EPERM;
-	mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16);
+	mii_wr(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in,
+	       16);
 	break;
       default:
 	return -EOPNOTSUPP;
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 23e1a07..6d28b18 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -303,7 +303,8 @@ static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
 static int pcnet32_probe1(unsigned long, int, struct pci_dev *);
 static int pcnet32_open(struct net_device *);
 static int pcnet32_init_ring(struct net_device *);
-static int pcnet32_start_xmit(struct sk_buff *, struct net_device *);
+static netdev_tx_t pcnet32_start_xmit(struct sk_buff *,
+				      struct net_device *);
 static void pcnet32_tx_timeout(struct net_device *dev);
 static irqreturn_t pcnet32_interrupt(int, void *);
 static int pcnet32_close(struct net_device *);
@@ -2481,7 +2482,8 @@ static void pcnet32_tx_timeout(struct net_device *dev)
 	spin_unlock_irqrestore(&lp->lock, flags);
 }
 
-static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t pcnet32_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct pcnet32_private *lp = netdev_priv(dev);
 	unsigned long ioaddr = dev->base_addr;
@@ -2534,7 +2536,7 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 	}
 	spin_unlock_irqrestore(&lp->lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The PCNET32 interrupt handler. */
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index de9cf51..d5d8e1c 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -56,6 +56,12 @@ config BROADCOM_PHY
 	  Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481
 	  and BCM5482 PHYs.
 
+config BCM63XX_PHY
+	tristate "Drivers for Broadcom 63xx SOCs internal PHY"
+	depends on BCM63XX
+	---help---
+	  Currently supports the 6348 and 6358 PHYs.
+
 config ICPLUS_PHY
 	tristate "Drivers for ICPlus PHYs"
 	---help---
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 3a1bfef..edfaac4 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_QSEMI_PHY)		+= qsemi.o
 obj-$(CONFIG_SMSC_PHY)		+= smsc.o
 obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
 obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
+obj-$(CONFIG_BCM63XX_PHY)	+= bcm63xx.o
 obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
 obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
 obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
new file mode 100644
index 0000000..4fed95e
--- /dev/null
+++ b/drivers/net/phy/bcm63xx.c
@@ -0,0 +1,132 @@
+/*
+ *	Driver for Broadcom 63xx SOCs integrated PHYs
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the 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/phy.h>
+
+#define MII_BCM63XX_IR		0x1a	/* interrupt register */
+#define MII_BCM63XX_IR_EN	0x4000	/* global interrupt enable */
+#define MII_BCM63XX_IR_DUPLEX	0x0800	/* duplex changed */
+#define MII_BCM63XX_IR_SPEED	0x0400	/* speed changed */
+#define MII_BCM63XX_IR_LINK	0x0200	/* link changed */
+#define MII_BCM63XX_IR_GMASK	0x0100	/* global interrupt mask */
+
+MODULE_DESCRIPTION("Broadcom 63xx internal PHY driver");
+MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
+MODULE_LICENSE("GPL");
+
+static int bcm63xx_config_init(struct phy_device *phydev)
+{
+	int reg, err;
+
+	reg = phy_read(phydev, MII_BCM63XX_IR);
+	if (reg < 0)
+		return reg;
+
+	/* Mask interrupts globally.  */
+	reg |= MII_BCM63XX_IR_GMASK;
+	err = phy_write(phydev, MII_BCM63XX_IR, reg);
+	if (err < 0)
+		return err;
+
+	/* Unmask events we are interested in  */
+	reg = ~(MII_BCM63XX_IR_DUPLEX |
+		MII_BCM63XX_IR_SPEED |
+		MII_BCM63XX_IR_LINK) |
+		MII_BCM63XX_IR_EN;
+	err = phy_write(phydev, MII_BCM63XX_IR, reg);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+static int bcm63xx_ack_interrupt(struct phy_device *phydev)
+{
+	int reg;
+
+	/* Clear pending interrupts.  */
+	reg = phy_read(phydev, MII_BCM63XX_IR);
+	if (reg < 0)
+		return reg;
+
+	return 0;
+}
+
+static int bcm63xx_config_intr(struct phy_device *phydev)
+{
+	int reg, err;
+
+	reg = phy_read(phydev, MII_BCM63XX_IR);
+	if (reg < 0)
+		return reg;
+
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+		reg &= ~MII_BCM63XX_IR_GMASK;
+	else
+		reg |= MII_BCM63XX_IR_GMASK;
+
+	err = phy_write(phydev, MII_BCM63XX_IR, reg);
+	return err;
+}
+
+static struct phy_driver bcm63xx_1_driver = {
+	.phy_id		= 0x00406000,
+	.phy_id_mask	= 0xfffffc00,
+	.name		= "Broadcom BCM63XX (1)",
+	/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */
+	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_init	= bcm63xx_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.ack_interrupt	= bcm63xx_ack_interrupt,
+	.config_intr	= bcm63xx_config_intr,
+	.driver		= { .owner = THIS_MODULE },
+};
+
+/* same phy as above, with just a different OUI */
+static struct phy_driver bcm63xx_2_driver = {
+	.phy_id		= 0x002bdc00,
+	.phy_id_mask	= 0xfffffc00,
+	.name		= "Broadcom BCM63XX (2)",
+	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_init	= bcm63xx_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.ack_interrupt	= bcm63xx_ack_interrupt,
+	.config_intr	= bcm63xx_config_intr,
+	.driver		= { .owner = THIS_MODULE },
+};
+
+static int __init bcm63xx_phy_init(void)
+{
+	int ret;
+
+	ret = phy_driver_register(&bcm63xx_1_driver);
+	if (ret)
+		goto out_63xx_1;
+	ret = phy_driver_register(&bcm63xx_2_driver);
+	if (ret)
+		goto out_63xx_2;
+	return ret;
+
+out_63xx_2:
+	phy_driver_unregister(&bcm63xx_1_driver);
+out_63xx_1:
+	return ret;
+}
+
+static void __exit bcm63xx_phy_exit(void)
+{
+	phy_driver_unregister(&bcm63xx_1_driver);
+	phy_driver_unregister(&bcm63xx_2_driver);
+}
+
+module_init(bcm63xx_phy_init);
+module_exit(bcm63xx_phy_exit);
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 190efc3..f81e532 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -18,6 +18,12 @@
 #include <linux/phy.h>
 
 #define PHY_ID_BCM50610		0x0143bd60
+#define PHY_ID_BCM50610M	0x0143bd70
+#define PHY_ID_BCM57780		0x03625d90
+
+#define BRCM_PHY_MODEL(phydev) \
+	((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
+
 
 #define MII_BCM54XX_ECR		0x10	/* BCM54xx extended control register */
 #define MII_BCM54XX_ECR_IM	0x1000	/* Interrupt mask */
@@ -117,6 +123,7 @@
 #define  MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE	0x0200
 #define MII_BCM54XX_EXP_EXP75			0x0f75
 #define  MII_BCM54XX_EXP_EXP75_VDACCTRL		0x003c
+#define  MII_BCM54XX_EXP_EXP75_CM_OSC		0x0001
 #define MII_BCM54XX_EXP_EXP96			0x0f96
 #define  MII_BCM54XX_EXP_EXP96_MYST		0x0010
 #define MII_BCM54XX_EXP_EXP97			0x0f97
@@ -141,6 +148,35 @@
 #define PHY_BCM_FLAGS_MODE_1000BX	0x00000002
 #define PHY_BCM_FLAGS_MODE_COPPER	0x00000001
 
+
+/*****************************************************************************/
+/* Fast Ethernet Transceiver definitions. */
+/*****************************************************************************/
+
+#define MII_BRCM_FET_INTREG		0x1a	/* Interrupt register */
+#define MII_BRCM_FET_IR_MASK		0x0100	/* Mask all interrupts */
+#define MII_BRCM_FET_IR_LINK_EN		0x0200	/* Link status change enable */
+#define MII_BRCM_FET_IR_SPEED_EN	0x0400	/* Link speed change enable */
+#define MII_BRCM_FET_IR_DUPLEX_EN	0x0800	/* Duplex mode change enable */
+#define MII_BRCM_FET_IR_ENABLE		0x4000	/* Interrupt enable */
+
+#define MII_BRCM_FET_BRCMTEST		0x1f	/* Brcm test register */
+#define MII_BRCM_FET_BT_SRE		0x0080	/* Shadow register enable */
+
+
+/*** Shadow register definitions ***/
+
+#define MII_BRCM_FET_SHDW_MISCCTRL	0x10	/* Shadow misc ctrl */
+#define MII_BRCM_FET_SHDW_MC_FAME	0x4000	/* Force Auto MDIX enable */
+
+#define MII_BRCM_FET_SHDW_AUXMODE4	0x1a	/* Auxiliary mode 4 */
+#define MII_BRCM_FET_SHDW_AM4_LED_MASK	0x0003
+#define MII_BRCM_FET_SHDW_AM4_LED_MODE1 0x0001
+
+#define MII_BRCM_FET_SHDW_AUXSTAT2	0x1b	/* Auxiliary status 2 */
+#define MII_BRCM_FET_SHDW_AS2_APDE	0x0020	/* Auto power down enable */
+
+
 MODULE_DESCRIPTION("Broadcom PHY driver");
 MODULE_AUTHOR("Maciej W. Rozycki");
 MODULE_LICENSE("GPL");
@@ -164,7 +200,7 @@ static int bcm54xx_shadow_write(struct phy_device *phydev, u16 shadow, u16 val)
 }
 
 /* Indirect register access functions for the Expansion Registers */
-static int bcm54xx_exp_read(struct phy_device *phydev, u8 regnum)
+static int bcm54xx_exp_read(struct phy_device *phydev, u16 regnum)
 {
 	int val;
 
@@ -278,6 +314,33 @@ static int bcm54xx_config_init(struct phy_device *phydev)
 			return err;
 	}
 
+	if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
+		int err2;
+
+		err = bcm54xx_auxctl_write(phydev,
+					   MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+					   MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
+					   MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+		if (err < 0)
+			return err;
+
+		reg = bcm54xx_exp_read(phydev, MII_BCM54XX_EXP_EXP75);
+		if (reg < 0)
+			goto error;
+
+		reg |= MII_BCM54XX_EXP_EXP75_CM_OSC;
+		err = bcm54xx_exp_write(phydev, MII_BCM54XX_EXP_EXP75, reg);
+
+error:
+		err2 = bcm54xx_auxctl_write(phydev,
+					    MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
+					    MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
+		if (err)
+			return err;
+		if (err2)
+			return err2;
+	}
+
 	return 0;
 }
 
@@ -435,6 +498,114 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
 	return ret;
 }
 
+static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
+{
+	int val;
+
+	val = phy_read(phydev, reg);
+	if (val < 0)
+		return val;
+
+	return phy_write(phydev, reg, val | set);
+}
+
+static int brcm_fet_config_init(struct phy_device *phydev)
+{
+	int reg, err, err2, brcmtest;
+
+	/* Reset the PHY to bring it to a known state. */
+	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
+	if (err < 0)
+		return err;
+
+	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
+	if (reg < 0)
+		return reg;
+
+	/* Unmask events we are interested in and mask interrupts globally. */
+	reg = MII_BRCM_FET_IR_DUPLEX_EN |
+	      MII_BRCM_FET_IR_SPEED_EN |
+	      MII_BRCM_FET_IR_LINK_EN |
+	      MII_BRCM_FET_IR_ENABLE |
+	      MII_BRCM_FET_IR_MASK;
+
+	err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
+	if (err < 0)
+		return err;
+
+	/* Enable shadow register access */
+	brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
+	if (brcmtest < 0)
+		return brcmtest;
+
+	reg = brcmtest | MII_BRCM_FET_BT_SRE;
+
+	err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
+	if (err < 0)
+		return err;
+
+	/* Set the LED mode */
+	reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
+	if (reg < 0) {
+		err = reg;
+		goto done;
+	}
+
+	reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK;
+	reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1;
+
+	err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
+	if (err < 0)
+		goto done;
+
+	/* Enable auto MDIX */
+	err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
+				       MII_BRCM_FET_SHDW_MC_FAME);
+	if (err < 0)
+		goto done;
+
+	/* Enable auto power down */
+	err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
+				       MII_BRCM_FET_SHDW_AS2_APDE);
+
+done:
+	/* Disable shadow register access */
+	err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
+	if (!err)
+		err = err2;
+
+	return err;
+}
+
+static int brcm_fet_ack_interrupt(struct phy_device *phydev)
+{
+	int reg;
+
+	/* Clear pending interrupts.  */
+	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
+	if (reg < 0)
+		return reg;
+
+	return 0;
+}
+
+static int brcm_fet_config_intr(struct phy_device *phydev)
+{
+	int reg, err;
+
+	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
+	if (reg < 0)
+		return reg;
+
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+		reg &= ~MII_BRCM_FET_IR_MASK;
+	else
+		reg |= MII_BRCM_FET_IR_MASK;
+
+	err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
+	return err;
+}
+
 static struct phy_driver bcm5411_driver = {
 	.phy_id		= 0x00206070,
 	.phy_id_mask	= 0xfffffff0,
@@ -447,7 +618,7 @@ static struct phy_driver bcm5411_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static struct phy_driver bcm5421_driver = {
@@ -462,7 +633,7 @@ static struct phy_driver bcm5421_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static struct phy_driver bcm5461_driver = {
@@ -477,7 +648,7 @@ static struct phy_driver bcm5461_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static struct phy_driver bcm5464_driver = {
@@ -492,7 +663,7 @@ static struct phy_driver bcm5464_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static struct phy_driver bcm5481_driver = {
@@ -507,7 +678,7 @@ static struct phy_driver bcm5481_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static struct phy_driver bcm5482_driver = {
@@ -522,7 +693,7 @@ static struct phy_driver bcm5482_driver = {
 	.read_status	= bcm5482_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static struct phy_driver bcm50610_driver = {
@@ -537,11 +708,26 @@ static struct phy_driver bcm50610_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
+};
+
+static struct phy_driver bcm50610m_driver = {
+	.phy_id		= PHY_ID_BCM50610M,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "Broadcom BCM50610M",
+	.features	= PHY_GBIT_FEATURES |
+			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+	.config_init	= bcm54xx_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.ack_interrupt	= bcm54xx_ack_interrupt,
+	.config_intr	= bcm54xx_config_intr,
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static struct phy_driver bcm57780_driver = {
-	.phy_id		= 0x03625d90,
+	.phy_id		= PHY_ID_BCM57780,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM57780",
 	.features	= PHY_GBIT_FEATURES |
@@ -552,7 +738,22 @@ static struct phy_driver bcm57780_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE },
+	.driver		= { .owner = THIS_MODULE },
+};
+
+static struct phy_driver bcmac131_driver = {
+	.phy_id		= 0x0143bc70,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "Broadcom BCMAC131",
+	.features	= PHY_BASIC_FEATURES |
+			  SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+	.config_init	= brcm_fet_config_init,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.ack_interrupt	= brcm_fet_ack_interrupt,
+	.config_intr	= brcm_fet_config_intr,
+	.driver		= { .owner = THIS_MODULE },
 };
 
 static int __init broadcom_init(void)
@@ -580,12 +781,22 @@ static int __init broadcom_init(void)
 	ret = phy_driver_register(&bcm50610_driver);
 	if (ret)
 		goto out_50610;
+	ret = phy_driver_register(&bcm50610m_driver);
+	if (ret)
+		goto out_50610m;
 	ret = phy_driver_register(&bcm57780_driver);
 	if (ret)
 		goto out_57780;
+	ret = phy_driver_register(&bcmac131_driver);
+	if (ret)
+		goto out_ac131;
 	return ret;
 
+out_ac131:
+	phy_driver_unregister(&bcm57780_driver);
 out_57780:
+	phy_driver_unregister(&bcm50610m_driver);
+out_50610m:
 	phy_driver_unregister(&bcm50610_driver);
 out_50610:
 	phy_driver_unregister(&bcm5482_driver);
@@ -605,7 +816,9 @@ out_5411:
 
 static void __exit broadcom_exit(void)
 {
+	phy_driver_unregister(&bcmac131_driver);
 	phy_driver_unregister(&bcm57780_driver);
+	phy_driver_unregister(&bcm50610m_driver);
 	phy_driver_unregister(&bcm50610_driver);
 	phy_driver_unregister(&bcm5482_driver);
 	phy_driver_unregister(&bcm5481_driver);
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index dd6f54d..6f69b9b 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -155,8 +155,27 @@ static int marvell_config_aneg(struct phy_device *phydev)
 		return err;
 
 	err = genphy_config_aneg(phydev);
+	if (err < 0)
+		return err;
 
-	return err;
+	if (phydev->autoneg != AUTONEG_ENABLE) {
+		int bmcr;
+
+		/*
+		 * A write to speed/duplex bits (that is performed by
+		 * genphy_config_aneg() call above) must be followed by
+		 * a software reset. Otherwise, the write has no effect.
+		 */
+		bmcr = phy_read(phydev, MII_BMCR);
+		if (bmcr < 0)
+			return bmcr;
+
+		err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
 }
 
 static int m88e1121_config_aneg(struct phy_device *phydev)
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 22cdd45..250e10f 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -211,7 +211,7 @@ static int __devinit mdio_ofgpio_probe(struct of_device *ofdev,
 
 	new_bus = mdio_gpio_bus_init(&ofdev->dev, pdata, pdata->mdc);
 	if (!new_bus)
-		return -ENODEV;
+		goto out_free;
 
 	ret = of_mdiobus_register(new_bus, ofdev->node);
 	if (ret)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index eda94fc..6b71b00 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -324,9 +324,6 @@ int phy_mii_ioctl(struct phy_device *phydev,
 		break;
 
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		if (mii_data->phy_id == phydev->addr) {
 			switch(mii_data->reg_num) {
 			case MII_BMCR:
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index 2ca8b0d..00487f5 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -990,7 +990,7 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
 	schedule_work(&nl->immediate);
 	spin_unlock_irq(&nl->lock);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index cd37d73..9bf2a6b 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -951,7 +951,7 @@ out:
 /*
  * Network interface unit routines.
  */
-static int
+static netdev_tx_t
 ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ppp *ppp = netdev_priv(dev);
@@ -988,12 +988,12 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	netif_stop_queue(dev);
 	skb_queue_tail(&ppp->file.xq, skb);
 	ppp_xmit_process(ppp);
-	return 0;
+	return NETDEV_TX_OK;
 
  outf:
 	kfree_skb(skb);
 	++dev->stats.tx_dropped;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int
@@ -1431,6 +1431,7 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 		*otherwise divide it according to the speed
 		*of the channel we are going to transmit on
 		*/
+		flen = len;
 		if (nfree > 0) {
 			if (pch->speed == 0) {
 				flen = totlen/nfree	;
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 5f20902..7cbf6f9 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -1185,17 +1185,17 @@ static int __init pppoe_init(void)
 {
 	int err;
 
-	err = proto_register(&pppoe_sk_proto, 0);
+	err = register_pernet_gen_device(&pppoe_net_id, &pppoe_net_ops);
 	if (err)
 		goto out;
 
-	err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
+	err = proto_register(&pppoe_sk_proto, 0);
 	if (err)
-		goto out_unregister_pppoe_proto;
+		goto out_unregister_net_ops;
 
-	err = register_pernet_gen_device(&pppoe_net_id, &pppoe_net_ops);
+	err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
 	if (err)
-		goto out_unregister_pppox_proto;
+		goto out_unregister_pppoe_proto;
 
 	dev_add_pack(&pppoes_ptype);
 	dev_add_pack(&pppoed_ptype);
@@ -1203,22 +1203,22 @@ static int __init pppoe_init(void)
 
 	return 0;
 
-out_unregister_pppox_proto:
-	unregister_pppox_proto(PX_PROTO_OE);
 out_unregister_pppoe_proto:
 	proto_unregister(&pppoe_sk_proto);
+out_unregister_net_ops:
+	unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
 out:
 	return err;
 }
 
 static void __exit pppoe_exit(void)
 {
-	unregister_pppox_proto(PX_PROTO_OE);
-	dev_remove_pack(&pppoes_ptype);
-	dev_remove_pack(&pppoed_ptype);
 	unregister_netdevice_notifier(&pppoe_notifier);
-	unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
+	dev_remove_pack(&pppoed_ptype);
+	dev_remove_pack(&pppoes_ptype);
+	unregister_pppox_proto(PX_PROTO_OE);
 	proto_unregister(&pppoe_sk_proto);
+	unregister_pernet_gen_device(pppoe_net_id, &pppoe_net_ops);
 }
 
 module_init(pppoe_init);
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index e0f9219..cc394d0 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -229,7 +229,7 @@ static void pppol2tp_tunnel_free(struct pppol2tp_tunnel *tunnel);
 static atomic_t pppol2tp_tunnel_count;
 static atomic_t pppol2tp_session_count;
 static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL };
-static struct proto_ops pppol2tp_ops;
+static const struct proto_ops pppol2tp_ops;
 
 /* per-net private data for this module */
 static int pppol2tp_net_id;
@@ -2574,7 +2574,7 @@ static const struct file_operations pppol2tp_proc_fops = {
  * Init and cleanup
  *****************************************************************************/
 
-static struct proto_ops pppol2tp_ops = {
+static const struct proto_ops pppol2tp_ops = {
 	.family		= AF_PPPOX,
 	.owner		= THIS_MODULE,
 	.release	= pppol2tp_release,
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index a3932c9..b211613 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -1346,7 +1346,7 @@ done:
 	return status;
 }
 
-static struct ethtool_ops gelic_ether_ethtool_ops = {
+static const struct ethtool_ops gelic_ether_ethtool_ops = {
 	.get_drvinfo	= gelic_net_get_drvinfo,
 	.get_settings	= gelic_ether_get_settings,
 	.get_link	= ethtool_op_get_link,
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 6932b08..227b141 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2714,7 +2714,7 @@ static const struct net_device_ops gelic_wl_netdevice_ops = {
 #endif
 };
 
-static struct ethtool_ops gelic_wl_ethtool_ops = {
+static const struct ethtool_ops gelic_wl_ethtool_ops = {
 	.get_drvinfo	= gelic_net_get_drvinfo,
 	.get_link	= gelic_wl_get_link,
 	.get_tx_csum	= ethtool_op_get_tx_csum,
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index 3e4b67a..4c61051 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -2572,7 +2572,8 @@ map_error:
  * The IOCB is always the top of the chain followed by one or more
  * OALs (when necessary).
  */
-static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t ql3xxx_send(struct sk_buff *skb,
+			       struct net_device *ndev)
 {
 	struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
 	struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers;
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 6ed5317..a9845a2 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1287,12 +1287,11 @@ struct rx_ring {
 	u32 sbq_free_cnt;	/* free buffer desc cnt */
 
 	/* Misc. handler elements. */
-	u32 type;		/* Type of queue, tx, rx, or default. */
+	u32 type;		/* Type of queue, tx, rx. */
 	u32 irq;		/* Which vector this ring is assigned. */
 	u32 cpu;		/* Which CPU this should run on. */
 	char name[IFNAMSIZ + 5];
 	struct napi_struct napi;
-	struct delayed_work rx_work;
 	u8 reserved;
 	struct ql_adapter *qdev;
 };
@@ -1366,6 +1365,7 @@ struct nic_stats {
 struct intr_context {
 	struct ql_adapter *qdev;
 	u32 intr;
+	u32 irq_mask;		/* Mask of which rings the vector services. */
 	u32 hooked;
 	u32 intr_en_mask;	/* value/mask used to enable this intr */
 	u32 intr_dis_mask;	/* value/mask used to disable this intr */
@@ -1486,13 +1486,11 @@ struct ql_adapter {
 	struct intr_context intr_context[MAX_RX_RINGS];
 
 	int tx_ring_count;	/* One per online CPU. */
-	u32 rss_ring_first_cq_id;/* index of first inbound (rss) rx_ring */
-	u32 rss_ring_count;	/* One per online CPU.  */
+	u32 rss_ring_count;	/* One per irq vector.  */
 	/*
 	 * rx_ring_count =
-	 *  one default queue +
 	 *  (CPU count * outbound completion rx_ring) +
-	 *  (CPU count * inbound (RSS) completion rx_ring)
+	 *  (irq_vector_cnt * inbound (RSS) completion rx_ring)
 	 */
 	int rx_ring_count;
 	int ring_mem_size;
@@ -1519,7 +1517,6 @@ struct ql_adapter {
 	union flash_params flash;
 
 	struct net_device_stats stats;
-	struct workqueue_struct *q_workqueue;
 	struct workqueue_struct *workqueue;
 	struct delayed_work asic_reset_work;
 	struct delayed_work mpi_reset_work;
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 40a70c3..aa88cb3 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -418,8 +418,6 @@ void ql_dump_qdev(struct ql_adapter *qdev)
 	printk(KERN_ERR PFX "qdev->intr_count 	= %d.\n", qdev->intr_count);
 	printk(KERN_ERR PFX "qdev->tx_ring		= %p.\n",
 	       qdev->tx_ring);
-	printk(KERN_ERR PFX "qdev->rss_ring_first_cq_id 	= %d.\n",
-	       qdev->rss_ring_first_cq_id);
 	printk(KERN_ERR PFX "qdev->rss_ring_count 	= %d.\n",
 	       qdev->rss_ring_count);
 	printk(KERN_ERR PFX "qdev->rx_ring	= %p.\n", qdev->rx_ring);
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index eb6a9ee..68f9bd2 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -49,10 +49,11 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
 	/* Skip the default queue, and update the outbound handler
 	 * queues if they changed.
 	 */
-	cqicb = (struct cqicb *)&qdev->rx_ring[1];
+	cqicb = (struct cqicb *)&qdev->rx_ring[qdev->rss_ring_count];
 	if (le16_to_cpu(cqicb->irq_delay) != qdev->tx_coalesce_usecs ||
-	    le16_to_cpu(cqicb->pkt_delay) != qdev->tx_max_coalesced_frames) {
-		for (i = 1; i < qdev->rss_ring_first_cq_id; i++, rx_ring++) {
+		le16_to_cpu(cqicb->pkt_delay) !=
+				qdev->tx_max_coalesced_frames) {
+		for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) {
 			rx_ring = &qdev->rx_ring[i];
 			cqicb = (struct cqicb *)rx_ring;
 			cqicb->irq_delay = cpu_to_le16(qdev->tx_coalesce_usecs);
@@ -70,12 +71,11 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
 	}
 
 	/* Update the inbound (RSS) handler queues if they changed. */
-	cqicb = (struct cqicb *)&qdev->rx_ring[qdev->rss_ring_first_cq_id];
+	cqicb = (struct cqicb *)&qdev->rx_ring[0];
 	if (le16_to_cpu(cqicb->irq_delay) != qdev->rx_coalesce_usecs ||
-	    le16_to_cpu(cqicb->pkt_delay) != qdev->rx_max_coalesced_frames) {
-		for (i = qdev->rss_ring_first_cq_id;
-		     i <= qdev->rss_ring_first_cq_id + qdev->rss_ring_count;
-		     i++) {
+		le16_to_cpu(cqicb->pkt_delay) !=
+					qdev->rx_max_coalesced_frames) {
+		for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) {
 			rx_ring = &qdev->rx_ring[i];
 			cqicb = (struct cqicb *)rx_ring;
 			cqicb->irq_delay = cpu_to_le16(qdev->rx_coalesce_usecs);
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 5768af1..2205292 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -370,9 +370,7 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
 				cam_output = (CAM_OUT_ROUTE_NIC |
 					      (qdev->
 					       func << CAM_OUT_FUNC_SHIFT) |
-					      (qdev->
-					       rss_ring_first_cq_id <<
-					       CAM_OUT_CQ_ID_SHIFT));
+						(0 << CAM_OUT_CQ_ID_SHIFT));
 				if (qdev->vlgrp)
 					cam_output |= CAM_OUT_RV;
 				/* route to NIC core */
@@ -1649,8 +1647,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
 
 	qdev->stats.rx_packets++;
 	qdev->stats.rx_bytes += skb->len;
-	skb_record_rx_queue(skb,
-		rx_ring->cq_id - qdev->rss_ring_first_cq_id);
+	skb_record_rx_queue(skb, rx_ring->cq_id);
 	if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
 		if (qdev->vlgrp &&
 			(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_V) &&
@@ -1862,11 +1859,41 @@ static int ql_napi_poll_msix(struct napi_struct *napi, int budget)
 {
 	struct rx_ring *rx_ring = container_of(napi, struct rx_ring, napi);
 	struct ql_adapter *qdev = rx_ring->qdev;
-	int work_done = ql_clean_inbound_rx_ring(rx_ring, budget);
+	struct rx_ring *trx_ring;
+	int i, work_done = 0;
+	struct intr_context *ctx = &qdev->intr_context[rx_ring->cq_id];
 
 	QPRINTK(qdev, RX_STATUS, DEBUG, "Enter, NAPI POLL cq_id = %d.\n",
 		rx_ring->cq_id);
 
+	/* Service the TX rings first.  They start
+	 * right after the RSS rings. */
+	for (i = qdev->rss_ring_count; i < qdev->rx_ring_count; i++) {
+		trx_ring = &qdev->rx_ring[i];
+		/* If this TX completion ring belongs to this vector and
+		 * it's not empty then service it.
+		 */
+		if ((ctx->irq_mask & (1 << trx_ring->cq_id)) &&
+			(ql_read_sh_reg(trx_ring->prod_idx_sh_reg) !=
+					trx_ring->cnsmr_idx)) {
+			QPRINTK(qdev, INTR, DEBUG,
+				"%s: Servicing TX completion ring %d.\n",
+				__func__, trx_ring->cq_id);
+			ql_clean_outbound_rx_ring(trx_ring);
+		}
+	}
+
+	/*
+	 * Now service the RSS ring if it's active.
+	 */
+	if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) !=
+					rx_ring->cnsmr_idx) {
+		QPRINTK(qdev, INTR, DEBUG,
+			"%s: Servicing RX completion ring %d.\n",
+			__func__, rx_ring->cq_id);
+		work_done = ql_clean_inbound_rx_ring(rx_ring, budget);
+	}
+
 	if (work_done < budget) {
 		napi_complete(napi);
 		ql_enable_completion_interrupt(qdev, rx_ring->irq);
@@ -1928,38 +1955,6 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
 
 }
 
-/* Worker thread to process a given rx_ring that is dedicated
- * to outbound completions.
- */
-static void ql_tx_clean(struct work_struct *work)
-{
-	struct rx_ring *rx_ring =
-	    container_of(work, struct rx_ring, rx_work.work);
-	ql_clean_outbound_rx_ring(rx_ring);
-	ql_enable_completion_interrupt(rx_ring->qdev, rx_ring->irq);
-
-}
-
-/* Worker thread to process a given rx_ring that is dedicated
- * to inbound completions.
- */
-static void ql_rx_clean(struct work_struct *work)
-{
-	struct rx_ring *rx_ring =
-	    container_of(work, struct rx_ring, rx_work.work);
-	ql_clean_inbound_rx_ring(rx_ring, 64);
-	ql_enable_completion_interrupt(rx_ring->qdev, rx_ring->irq);
-}
-
-/* MSI-X Multiple Vector Interrupt Handler for outbound completions. */
-static irqreturn_t qlge_msix_tx_isr(int irq, void *dev_id)
-{
-	struct rx_ring *rx_ring = dev_id;
-	queue_delayed_work_on(rx_ring->cpu, rx_ring->qdev->q_workqueue,
-			      &rx_ring->rx_work, 0);
-	return IRQ_HANDLED;
-}
-
 /* MSI-X Multiple Vector Interrupt Handler for inbound completions. */
 static irqreturn_t qlge_msix_rx_isr(int irq, void *dev_id)
 {
@@ -1979,7 +1974,6 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
 	struct ql_adapter *qdev = rx_ring->qdev;
 	struct intr_context *intr_context = &qdev->intr_context[0];
 	u32 var;
-	int i;
 	int work_done = 0;
 
 	spin_lock(&qdev->hw_lock);
@@ -2020,41 +2014,18 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
 	}
 
 	/*
-	 * Check the default queue and wake handler if active.
+	 * Get the bit-mask that shows the active queues for this
+	 * pass.  Compare it to the queues that this irq services
+	 * and call napi if there's a match.
 	 */
-	rx_ring = &qdev->rx_ring[0];
-	if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) {
-		QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n");
-		ql_disable_completion_interrupt(qdev, intr_context->intr);
-		queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue,
-				      &rx_ring->rx_work, 0);
-		work_done++;
-	}
-
-	if (!test_bit(QL_MSIX_ENABLED, &qdev->flags)) {
-		/*
-		 * Start the DPC for each active queue.
-		 */
-		for (i = 1; i < qdev->rx_ring_count; i++) {
-			rx_ring = &qdev->rx_ring[i];
-			if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) !=
-			    rx_ring->cnsmr_idx) {
+	var = ql_read32(qdev, ISR1);
+	if (var & intr_context->irq_mask) {
 				QPRINTK(qdev, INTR, INFO,
-					"Waking handler for rx_ring[%d].\n", i);
-				ql_disable_completion_interrupt(qdev,
-								intr_context->
-								intr);
-				if (i < qdev->rss_ring_first_cq_id)
-					queue_delayed_work_on(rx_ring->cpu,
-							      qdev->q_workqueue,
-							      &rx_ring->rx_work,
-							      0);
-				else
+			"Waking handler for rx_ring[0].\n");
+		ql_disable_completion_interrupt(qdev, intr_context->intr);
 					napi_schedule(&rx_ring->napi);
 				work_done++;
 			}
-		}
-	}
 	ql_enable_completion_interrupt(qdev, intr_context->intr);
 	return work_done ? IRQ_HANDLED : IRQ_NONE;
 }
@@ -2132,7 +2103,7 @@ static void ql_hw_csum_setup(struct sk_buff *skb,
 				    iph->daddr, len, iph->protocol, 0);
 }
 
-static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
 {
 	struct tx_ring_desc *tx_ring_desc;
 	struct ob_mac_iocb_req *mac_iocb_ptr;
@@ -2706,35 +2677,9 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 	}
 	switch (rx_ring->type) {
 	case TX_Q:
-		/* If there's only one interrupt, then we use
-		 * worker threads to process the outbound
-		 * completion handling rx_rings. We do this so
-		 * they can be run on multiple CPUs. There is
-		 * room to play with this more where we would only
-		 * run in a worker if there are more than x number
-		 * of outbound completions on the queue and more
-		 * than one queue active.  Some threshold that
-		 * would indicate a benefit in spite of the cost
-		 * of a context switch.
-		 * If there's more than one interrupt, then the
-		 * outbound completions are processed in the ISR.
-		 */
-		if (!test_bit(QL_MSIX_ENABLED, &qdev->flags))
-			INIT_DELAYED_WORK(&rx_ring->rx_work, ql_tx_clean);
-		else {
-			/* With all debug warnings on we see a WARN_ON message
-			 * when we free the skb in the interrupt context.
-			 */
-			INIT_DELAYED_WORK(&rx_ring->rx_work, ql_tx_clean);
-		}
 		cqicb->irq_delay = cpu_to_le16(qdev->tx_coalesce_usecs);
 		cqicb->pkt_delay = cpu_to_le16(qdev->tx_max_coalesced_frames);
 		break;
-	case DEFAULT_Q:
-		INIT_DELAYED_WORK(&rx_ring->rx_work, ql_rx_clean);
-		cqicb->irq_delay = 0;
-		cqicb->pkt_delay = 0;
-		break;
 	case RX_Q:
 		/* Inbound completion handling rx_rings run in
 		 * separate NAPI contexts.
@@ -2818,17 +2763,20 @@ static void ql_disable_msix(struct ql_adapter *qdev)
 	}
 }
 
+/* We start by trying to get the number of vectors
+ * stored in qdev->intr_count. If we don't get that
+ * many then we reduce the count and try again.
+ */
 static void ql_enable_msix(struct ql_adapter *qdev)
 {
-	int i;
+	int i, err;
 
-	qdev->intr_count = 1;
 	/* Get the MSIX vectors. */
 	if (irq_type == MSIX_IRQ) {
 		/* Try to alloc space for the msix struct,
 		 * if it fails then go to MSI/legacy.
 		 */
-		qdev->msi_x_entry = kcalloc(qdev->rx_ring_count,
+		qdev->msi_x_entry = kcalloc(qdev->intr_count,
 					    sizeof(struct msix_entry),
 					    GFP_KERNEL);
 		if (!qdev->msi_x_entry) {
@@ -2836,26 +2784,36 @@ static void ql_enable_msix(struct ql_adapter *qdev)
 			goto msi;
 		}
 
-		for (i = 0; i < qdev->rx_ring_count; i++)
+		for (i = 0; i < qdev->intr_count; i++)
 			qdev->msi_x_entry[i].entry = i;
 
-		if (!pci_enable_msix
-		    (qdev->pdev, qdev->msi_x_entry, qdev->rx_ring_count)) {
-			set_bit(QL_MSIX_ENABLED, &qdev->flags);
-			qdev->intr_count = qdev->rx_ring_count;
-			QPRINTK(qdev, IFUP, DEBUG,
-				"MSI-X Enabled, got %d vectors.\n",
-				qdev->intr_count);
-			return;
-		} else {
+		/* Loop to get our vectors.  We start with
+		 * what we want and settle for what we get.
+		 */
+		do {
+			err = pci_enable_msix(qdev->pdev,
+				qdev->msi_x_entry, qdev->intr_count);
+			if (err > 0)
+				qdev->intr_count = err;
+		} while (err > 0);
+
+		if (err < 0) {
 			kfree(qdev->msi_x_entry);
 			qdev->msi_x_entry = NULL;
 			QPRINTK(qdev, IFUP, WARNING,
 				"MSI-X Enable failed, trying MSI.\n");
+			qdev->intr_count = 1;
 			irq_type = MSI_IRQ;
+		} else if (err == 0) {
+			set_bit(QL_MSIX_ENABLED, &qdev->flags);
+			QPRINTK(qdev, IFUP, INFO,
+				"MSI-X Enabled, got %d vectors.\n",
+				qdev->intr_count);
+			return;
 		}
 	}
 msi:
+	qdev->intr_count = 1;
 	if (irq_type == MSI_IRQ) {
 		if (!pci_enable_msi(qdev->pdev)) {
 			set_bit(QL_MSI_ENABLED, &qdev->flags);
@@ -2868,6 +2826,71 @@ msi:
 	QPRINTK(qdev, IFUP, DEBUG, "Running with legacy interrupts.\n");
 }
 
+/* Each vector services 1 RSS ring and and 1 or more
+ * TX completion rings.  This function loops through
+ * the TX completion rings and assigns the vector that
+ * will service it.  An example would be if there are
+ * 2 vectors (so 2 RSS rings) and 8 TX completion rings.
+ * This would mean that vector 0 would service RSS ring 0
+ * and TX competion rings 0,1,2 and 3.  Vector 1 would
+ * service RSS ring 1 and TX completion rings 4,5,6 and 7.
+ */
+static void ql_set_tx_vect(struct ql_adapter *qdev)
+{
+	int i, j, vect;
+	u32 tx_rings_per_vector = qdev->tx_ring_count / qdev->intr_count;
+
+	if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) {
+		/* Assign irq vectors to TX rx_rings.*/
+		for (vect = 0, j = 0, i = qdev->rss_ring_count;
+					 i < qdev->rx_ring_count; i++) {
+			if (j == tx_rings_per_vector) {
+				vect++;
+				j = 0;
+			}
+			qdev->rx_ring[i].irq = vect;
+			j++;
+		}
+	} else {
+		/* For single vector all rings have an irq
+		 * of zero.
+		 */
+		for (i = 0; i < qdev->rx_ring_count; i++)
+			qdev->rx_ring[i].irq = 0;
+	}
+}
+
+/* Set the interrupt mask for this vector.  Each vector
+ * will service 1 RSS ring and 1 or more TX completion
+ * rings.  This function sets up a bit mask per vector
+ * that indicates which rings it services.
+ */
+static void ql_set_irq_mask(struct ql_adapter *qdev, struct intr_context *ctx)
+{
+	int j, vect = ctx->intr;
+	u32 tx_rings_per_vector = qdev->tx_ring_count / qdev->intr_count;
+
+	if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) {
+		/* Add the RSS ring serviced by this vector
+		 * to the mask.
+		 */
+		ctx->irq_mask = (1 << qdev->rx_ring[vect].cq_id);
+		/* Add the TX ring(s) serviced by this vector
+		 * to the mask. */
+		for (j = 0; j < tx_rings_per_vector; j++) {
+			ctx->irq_mask |=
+			(1 << qdev->rx_ring[qdev->rss_ring_count +
+			(vect * tx_rings_per_vector) + j].cq_id);
+		}
+	} else {
+		/* For single vector we just shift each queue's
+		 * ID into the mask.
+		 */
+		for (j = 0; j < qdev->rx_ring_count; j++)
+			ctx->irq_mask |= (1 << qdev->rx_ring[j].cq_id);
+	}
+}
+
 /*
  * Here we build the intr_context structures based on
  * our rx_ring count and intr vector count.
@@ -2879,18 +2902,19 @@ static void ql_resolve_queues_to_irqs(struct ql_adapter *qdev)
 	int i = 0;
 	struct intr_context *intr_context = &qdev->intr_context[0];
 
-	ql_enable_msix(qdev);
-
 	if (likely(test_bit(QL_MSIX_ENABLED, &qdev->flags))) {
 		/* Each rx_ring has it's
 		 * own intr_context since we have separate
 		 * vectors for each queue.
-		 * This only true when MSI-X is enabled.
 		 */
 		for (i = 0; i < qdev->intr_count; i++, intr_context++) {
 			qdev->rx_ring[i].irq = i;
 			intr_context->intr = i;
 			intr_context->qdev = qdev;
+			/* Set up this vector's bit-mask that indicates
+			 * which queues it services.
+			 */
+			ql_set_irq_mask(qdev, intr_context);
 			/*
 			 * We set up each vectors enable/disable/read bits so
 			 * there's no bit/mask calculations in the critical path.
@@ -2907,21 +2931,14 @@ static void ql_resolve_queues_to_irqs(struct ql_adapter *qdev)
 			    INTR_EN_TYPE_MASK | INTR_EN_INTR_MASK |
 			    INTR_EN_TYPE_READ | INTR_EN_IHD_MASK | INTR_EN_IHD |
 			    i;
-
 			if (i == 0) {
-				/*
-				 * Default queue handles bcast/mcast plus
-				 * async events.  Needs buffers.
+				/* The first vector/queue handles
+				 * broadcast/multicast, fatal errors,
+				 * and firmware events.  This in addition
+				 * to normal inbound NAPI processing.
 				 */
 				intr_context->handler = qlge_isr;
-				sprintf(intr_context->name, "%s-default-queue",
-					qdev->ndev->name);
-			} else if (i < qdev->rss_ring_first_cq_id) {
-				/*
-				 * Outbound queue is for outbound completions only.
-				 */
-				intr_context->handler = qlge_msix_tx_isr;
-				sprintf(intr_context->name, "%s-tx-%d",
+				sprintf(intr_context->name, "%s-rx-%d",
 					qdev->ndev->name, i);
 			} else {
 				/*
@@ -2955,9 +2972,17 @@ static void ql_resolve_queues_to_irqs(struct ql_adapter *qdev)
 		 */
 		intr_context->handler = qlge_isr;
 		sprintf(intr_context->name, "%s-single_irq", qdev->ndev->name);
-		for (i = 0; i < qdev->rx_ring_count; i++)
-			qdev->rx_ring[i].irq = 0;
+		/* Set up this vector's bit-mask that indicates
+		 * which queues it services. In this case there is
+		 * a single vector so it will service all RSS and
+		 * TX completion rings.
+		 */
+		ql_set_irq_mask(qdev, intr_context);
 	}
+	/* Tell the TX completion rings which MSIx vector
+	 * they will be using.
+	 */
+	ql_set_tx_vect(qdev);
 }
 
 static void ql_free_irq(struct ql_adapter *qdev)
@@ -3062,7 +3087,7 @@ static int ql_start_rss(struct ql_adapter *qdev)
 
 	memset((void *)ricb, 0, sizeof(*ricb));
 
-	ricb->base_cq = qdev->rss_ring_first_cq_id | RSS_L4K;
+	ricb->base_cq = RSS_L4K;
 	ricb->flags =
 	    (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 |
 	     RSS_RT6);
@@ -3264,7 +3289,7 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
 	}
 
 	/* Start NAPI for the RSS queues. */
-	for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++) {
+	for (i = 0; i < qdev->rss_ring_count; i++) {
 		QPRINTK(qdev, IFUP, DEBUG, "Enabling NAPI for rx_ring[%d].\n",
 			i);
 		napi_enable(&qdev->rx_ring[i].napi);
@@ -3326,7 +3351,6 @@ static void ql_display_dev_info(struct net_device *ndev)
 static int ql_adapter_down(struct ql_adapter *qdev)
 {
 	int i, status = 0;
-	struct rx_ring *rx_ring;
 
 	ql_link_off(qdev);
 
@@ -3340,27 +3364,8 @@ static int ql_adapter_down(struct ql_adapter *qdev)
 	cancel_delayed_work_sync(&qdev->mpi_idc_work);
 	cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
 
-	/* The default queue at index 0 is always processed in
-	 * a workqueue.
-	 */
-	cancel_delayed_work_sync(&qdev->rx_ring[0].rx_work);
-
-	/* The rest of the rx_rings are processed in
-	 * a workqueue only if it's a single interrupt
-	 * environment (MSI/Legacy).
-	 */
-	for (i = 1; i < qdev->rx_ring_count; i++) {
-		rx_ring = &qdev->rx_ring[i];
-		/* Only the RSS rings use NAPI on multi irq
-		 * environment.  Outbound completion processing
-		 * is done in interrupt context.
-		 */
-		if (i >= qdev->rss_ring_first_cq_id) {
-			napi_disable(&rx_ring->napi);
-		} else {
-			cancel_delayed_work_sync(&rx_ring->rx_work);
-		}
-	}
+	for (i = 0; i < qdev->rss_ring_count; i++)
+		napi_disable(&qdev->rx_ring[i].napi);
 
 	clear_bit(QL_ADAPTER_UP, &qdev->flags);
 
@@ -3370,7 +3375,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)
 
 	/* Call netif_napi_del() from common point.
 	 */
-	for (i = qdev->rss_ring_first_cq_id; i < qdev->rx_ring_count; i++)
+	for (i = 0; i < qdev->rss_ring_count; i++)
 		netif_napi_del(&qdev->rx_ring[i].napi);
 
 	ql_free_rx_buffers(qdev);
@@ -3449,43 +3454,21 @@ static int ql_configure_rings(struct ql_adapter *qdev)
 	int i;
 	struct rx_ring *rx_ring;
 	struct tx_ring *tx_ring;
-	int cpu_cnt = num_online_cpus();
-
-	/*
-	 * For each processor present we allocate one
-	 * rx_ring for outbound completions, and one
-	 * rx_ring for inbound completions.  Plus there is
-	 * always the one default queue.  For the CPU
-	 * counts we end up with the following rx_rings:
-	 * rx_ring count =
-	 *  one default queue +
-	 *  (CPU count * outbound completion rx_ring) +
-	 *  (CPU count * inbound (RSS) completion rx_ring)
-	 * To keep it simple we limit the total number of
-	 * queues to < 32, so we truncate CPU to 8.
-	 * This limitation can be removed when requested.
+	int cpu_cnt = min(MAX_CPUS, (int)num_online_cpus());
+
+	/* In a perfect world we have one RSS ring for each CPU
+	 * and each has it's own vector.  To do that we ask for
+	 * cpu_cnt vectors.  ql_enable_msix() will adjust the
+	 * vector count to what we actually get.  We then
+	 * allocate an RSS ring for each.
+	 * Essentially, we are doing min(cpu_count, msix_vector_count).
 	 */
-
-	if (cpu_cnt > MAX_CPUS)
-		cpu_cnt = MAX_CPUS;
-
-	/*
-	 * rx_ring[0] is always the default queue.
-	 */
-	/* Allocate outbound completion ring for each CPU. */
+	qdev->intr_count = cpu_cnt;
+	ql_enable_msix(qdev);
+	/* Adjust the RSS ring count to the actual vector count. */
+	qdev->rss_ring_count = qdev->intr_count;
 	qdev->tx_ring_count = cpu_cnt;
-	/* Allocate inbound completion (RSS) ring for each CPU. */
-	qdev->rss_ring_count = cpu_cnt;
-	/* cq_id for the first inbound ring handler. */
-	qdev->rss_ring_first_cq_id = cpu_cnt + 1;
-	/*
-	 * qdev->rx_ring_count:
-	 * Total number of rx_rings.  This includes the one
-	 * default queue, a number of outbound completion
-	 * handler rx_rings, and the number of inbound
-	 * completion handler rx_rings.
-	 */
-	qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1;
+	qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count;
 
 	for (i = 0; i < qdev->tx_ring_count; i++) {
 		tx_ring = &qdev->tx_ring[i];
@@ -3498,9 +3481,9 @@ static int ql_configure_rings(struct ql_adapter *qdev)
 
 		/*
 		 * The completion queue ID for the tx rings start
-		 * immediately after the default Q ID, which is zero.
+		 * immediately after the rss rings.
 		 */
-		tx_ring->cq_id = i + 1;
+		tx_ring->cq_id = qdev->rss_ring_count + i;
 	}
 
 	for (i = 0; i < qdev->rx_ring_count; i++) {
@@ -3509,10 +3492,9 @@ static int ql_configure_rings(struct ql_adapter *qdev)
 		rx_ring->qdev = qdev;
 		rx_ring->cq_id = i;
 		rx_ring->cpu = i % cpu_cnt;	/* CPU to run handler on. */
-		if (i == 0) {	/* Default queue at index 0. */
+		if (i < qdev->rss_ring_count) {
 			/*
-			 * Default queue handles bcast/mcast plus
-			 * async events.  Needs buffers.
+			 * Inbound (RSS) queues.
 			 */
 			rx_ring->cq_len = qdev->rx_ring_size;
 			rx_ring->cq_size =
@@ -3525,8 +3507,8 @@ static int ql_configure_rings(struct ql_adapter *qdev)
 			rx_ring->sbq_size =
 			    rx_ring->sbq_len * sizeof(__le64);
 			rx_ring->sbq_buf_size = SMALL_BUFFER_SIZE * 2;
-			rx_ring->type = DEFAULT_Q;
-		} else if (i < qdev->rss_ring_first_cq_id) {
+			rx_ring->type = RX_Q;
+		} else {
 			/*
 			 * Outbound queue handles outbound completions only.
 			 */
@@ -3541,22 +3523,6 @@ static int ql_configure_rings(struct ql_adapter *qdev)
 			rx_ring->sbq_size = 0;
 			rx_ring->sbq_buf_size = 0;
 			rx_ring->type = TX_Q;
-		} else {	/* Inbound completions (RSS) queues */
-			/*
-			 * Inbound queues handle unicast frames only.
-			 */
-			rx_ring->cq_len = qdev->rx_ring_size;
-			rx_ring->cq_size =
-			    rx_ring->cq_len * sizeof(struct ql_net_rsp_iocb);
-			rx_ring->lbq_len = NUM_LARGE_BUFFERS;
-			rx_ring->lbq_size =
-			    rx_ring->lbq_len * sizeof(__le64);
-			rx_ring->lbq_buf_size = LARGE_BUFFER_SIZE;
-			rx_ring->sbq_len = NUM_SMALL_BUFFERS;
-			rx_ring->sbq_size =
-			    rx_ring->sbq_len * sizeof(__le64);
-			rx_ring->sbq_buf_size = SMALL_BUFFER_SIZE * 2;
-			rx_ring->type = RX_Q;
 		}
 	}
 	return 0;
@@ -3845,10 +3811,7 @@ static void ql_release_all(struct pci_dev *pdev)
 		destroy_workqueue(qdev->workqueue);
 		qdev->workqueue = NULL;
 	}
-	if (qdev->q_workqueue) {
-		destroy_workqueue(qdev->q_workqueue);
-		qdev->q_workqueue = NULL;
-	}
+
 	if (qdev->reg_base)
 		iounmap(qdev->reg_base);
 	if (qdev->doorbell_area)
@@ -3961,8 +3924,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
 	 * Set up the operating parameters.
 	 */
 	qdev->rx_csum = 1;
-
-	qdev->q_workqueue = create_workqueue(ndev->name);
 	qdev->workqueue = create_singlethread_workqueue(ndev->name);
 	INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
 	INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
@@ -4076,6 +4037,11 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
 	struct net_device *ndev = pci_get_drvdata(pdev);
 	struct ql_adapter *qdev = netdev_priv(ndev);
 
+	netif_device_detach(ndev);
+
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	if (netif_running(ndev))
 		ql_adapter_down(qdev);
 
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 961b539..7dfcb58 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,8 +49,8 @@
 #include <asm/processor.h>
 
 #define DRV_NAME	"r6040"
-#define DRV_VERSION	"0.24"
-#define DRV_RELDATE	"08Jul2009"
+#define DRV_VERSION	"0.25"
+#define DRV_RELDATE	"20Aug2009"
 
 /* PHY CHIP Address */
 #define PHY1_ADDR	1	/* For MAC1 */
@@ -750,14 +750,6 @@ static int r6040_up(struct net_device *dev)
 	struct r6040_private *lp = netdev_priv(dev);
 	void __iomem *ioaddr = lp->base;
 	int ret;
-	u16 val;
-
-	/* Check presence of a second PHY */
-	val = r6040_phy_read(ioaddr, lp->phy_addr, 2);
-	if (val == 0xFFFF) {
-		printk(KERN_ERR DRV_NAME " no second PHY attached\n");
-		return -EIO;
-	}
 
 	/* Initialise and alloc RX/TX buffers */
 	r6040_init_txbufs(dev);
@@ -891,13 +883,13 @@ static int r6040_open(struct net_device *dev)
 	return 0;
 }
 
-static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t r6040_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct r6040_private *lp = netdev_priv(dev);
 	struct r6040_descriptor *descptr;
 	void __iomem *ioaddr = lp->base;
 	unsigned long flags;
-	int ret = NETDEV_TX_OK;
 
 	/* Critical Section */
 	spin_lock_irqsave(&lp->lock, flags);
@@ -907,8 +899,7 @@ static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		spin_unlock_irqrestore(&lp->lock, flags);
 		netif_stop_queue(dev);
 		printk(KERN_ERR DRV_NAME ": no tx descriptor\n");
-		ret = NETDEV_TX_BUSY;
-		return ret;
+		return NETDEV_TX_BUSY;
 	}
 
 	/* Statistic Counter */
@@ -936,7 +927,8 @@ static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 	spin_unlock_irqrestore(&lp->lock, flags);
-	return ret;
+
+	return NETDEV_TX_OK;
 }
 
 static void r6040_multicast_list(struct net_device *dev)
@@ -1091,7 +1083,6 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 	int err, io_size = R6040_IO_SIZE;
 	static int card_idx = -1;
 	int bar = 0;
-	long pioaddr;
 	u16 *adrp;
 
 	printk(KERN_INFO "%s\n", version);
@@ -1115,13 +1106,12 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 	}
 
 	/* IO Size check */
-	if (pci_resource_len(pdev, 0) < io_size) {
+	if (pci_resource_len(pdev, bar) < io_size) {
 		printk(KERN_ERR DRV_NAME ": Insufficient PCI resources, aborting\n");
 		err = -EIO;
 		goto err_out;
 	}
 
-	pioaddr = pci_resource_start(pdev, 0);	/* IO map base address */
 	pci_set_master(pdev);
 
 	dev = alloc_etherdev(sizeof(struct r6040_private));
@@ -1196,6 +1186,13 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
 	lp->mii_if.phy_id_mask = 0x1f;
 	lp->mii_if.reg_num_mask = 0x1f;
 
+	/* Check the vendor ID on the PHY, if 0xffff assume none attached */
+	if (r6040_phy_read(ioaddr, lp->phy_addr, 2) == 0xffff) {
+		printk(KERN_ERR DRV_NAME ": Failed to detect an attached PHY\n");
+		err = -ENODEV;
+		goto err_out_unmap;
+	}
+
 	/* Register net device. After this dev->name assign */
 	err = register_netdev(dev);
 	if (err) {
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index b82780d..50c6a3c 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -507,7 +507,8 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(RTL8169_VERSION);
 
 static int rtl8169_open(struct net_device *dev);
-static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev);
 static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance);
 static int rtl8169_init_ring(struct net_device *dev);
 static void rtl_hw_start(struct net_device *dev);
@@ -1222,17 +1223,6 @@ static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
 };
 
-static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg,
-				       int bitnum, int bitval)
-{
-	int val;
-
-	val = mdio_read(ioaddr, reg);
-	val = (bitval == 1) ?
-		val | (bitval << bitnum) :  val & ~(0x0001 << bitnum);
-	mdio_write(ioaddr, reg, val & 0xffff);
-}
-
 static void rtl8169_get_mac_version(struct rtl8169_private *tp,
 				    void __iomem *ioaddr)
 {
@@ -1328,54 +1318,69 @@ static void rtl_phy_write(void __iomem *ioaddr, struct phy_reg *regs, int len)
 
 static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
 {
-	struct {
-		u16 regs[5]; /* Beware of bit-sign propagation */
-	} phy_magic[5] = { {
-		{ 0x0000,	//w 4 15 12 0
-		  0x00a1,	//w 3 15 0 00a1
-		  0x0008,	//w 2 15 0 0008
-		  0x1020,	//w 1 15 0 1020
-		  0x1000 } },{	//w 0 15 0 1000
-		{ 0x7000,	//w 4 15 12 7
-		  0xff41,	//w 3 15 0 ff41
-		  0xde60,	//w 2 15 0 de60
-		  0x0140,	//w 1 15 0 0140
-		  0x0077 } },{	//w 0 15 0 0077
-		{ 0xa000,	//w 4 15 12 a
-		  0xdf01,	//w 3 15 0 df01
-		  0xdf20,	//w 2 15 0 df20
-		  0xff95,	//w 1 15 0 ff95
-		  0xfa00 } },{	//w 0 15 0 fa00
-		{ 0xb000,	//w 4 15 12 b
-		  0xff41,	//w 3 15 0 ff41
-		  0xde20,	//w 2 15 0 de20
-		  0x0140,	//w 1 15 0 0140
-		  0x00bb } },{	//w 0 15 0 00bb
-		{ 0xf000,	//w 4 15 12 f
-		  0xdf01,	//w 3 15 0 df01
-		  0xdf20,	//w 2 15 0 df20
-		  0xff95,	//w 1 15 0 ff95
-		  0xbf00 }	//w 0 15 0 bf00
-		}
-	}, *p = phy_magic;
-	unsigned int i;
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0001 },
+		{ 0x06, 0x006e },
+		{ 0x08, 0x0708 },
+		{ 0x15, 0x4000 },
+		{ 0x18, 0x65c7 },
+
+		{ 0x1f, 0x0001 },
+		{ 0x03, 0x00a1 },
+		{ 0x02, 0x0008 },
+		{ 0x01, 0x0120 },
+		{ 0x00, 0x1000 },
+		{ 0x04, 0x0800 },
+		{ 0x04, 0x0000 },
+
+		{ 0x03, 0xff41 },
+		{ 0x02, 0xdf60 },
+		{ 0x01, 0x0140 },
+		{ 0x00, 0x0077 },
+		{ 0x04, 0x7800 },
+		{ 0x04, 0x7000 },
 
-	mdio_write(ioaddr, 0x1f, 0x0001);		//w 31 2 0 1
-	mdio_write(ioaddr, 0x15, 0x1000);		//w 21 15 0 1000
-	mdio_write(ioaddr, 0x18, 0x65c7);		//w 24 15 0 65c7
-	rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0);	//w 4 11 11 0
+		{ 0x03, 0x802f },
+		{ 0x02, 0x4f02 },
+		{ 0x01, 0x0409 },
+		{ 0x00, 0xf0f9 },
+		{ 0x04, 0x9800 },
+		{ 0x04, 0x9000 },
 
-	for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) {
-		int val, pos = 4;
+		{ 0x03, 0xdf01 },
+		{ 0x02, 0xdf20 },
+		{ 0x01, 0xff95 },
+		{ 0x00, 0xba00 },
+		{ 0x04, 0xa800 },
+		{ 0x04, 0xa000 },
+
+		{ 0x03, 0xff41 },
+		{ 0x02, 0xdf20 },
+		{ 0x01, 0x0140 },
+		{ 0x00, 0x00bb },
+		{ 0x04, 0xb800 },
+		{ 0x04, 0xb000 },
+
+		{ 0x03, 0xdf41 },
+		{ 0x02, 0xdc60 },
+		{ 0x01, 0x6340 },
+		{ 0x00, 0x007d },
+		{ 0x04, 0xd800 },
+		{ 0x04, 0xd000 },
+
+		{ 0x03, 0xdf01 },
+		{ 0x02, 0xdf20 },
+		{ 0x01, 0x100a },
+		{ 0x00, 0xa0ff },
+		{ 0x04, 0xf800 },
+		{ 0x04, 0xf000 },
 
-		val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff);
-		mdio_write(ioaddr, pos, val);
-		while (--pos >= 0)
-			mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff);
-		rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1
-		rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0
-	}
-	mdio_write(ioaddr, 0x1f, 0x0000); //w 31 2 0 0
+		{ 0x1f, 0x0000 },
+		{ 0x0b, 0x0000 },
+		{ 0x00, 0x9200 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
 
 static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
@@ -1389,6 +1394,124 @@ static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
 	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
 
+static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp,
+					   void __iomem *ioaddr)
+{
+	struct pci_dev *pdev = tp->pci_dev;
+	u16 vendor_id, device_id;
+
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &vendor_id);
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &device_id);
+
+	if ((vendor_id != PCI_VENDOR_ID_GIGABYTE) || (device_id != 0xe000))
+		return;
+
+	mdio_write(ioaddr, 0x1f, 0x0001);
+	mdio_write(ioaddr, 0x10, 0xf01b);
+	mdio_write(ioaddr, 0x1f, 0x0000);
+}
+
+static void rtl8169scd_hw_phy_config(struct rtl8169_private *tp,
+				     void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0001 },
+		{ 0x04, 0x0000 },
+		{ 0x03, 0x00a1 },
+		{ 0x02, 0x0008 },
+		{ 0x01, 0x0120 },
+		{ 0x00, 0x1000 },
+		{ 0x04, 0x0800 },
+		{ 0x04, 0x9000 },
+		{ 0x03, 0x802f },
+		{ 0x02, 0x4f02 },
+		{ 0x01, 0x0409 },
+		{ 0x00, 0xf099 },
+		{ 0x04, 0x9800 },
+		{ 0x04, 0xa000 },
+		{ 0x03, 0xdf01 },
+		{ 0x02, 0xdf20 },
+		{ 0x01, 0xff95 },
+		{ 0x00, 0xba00 },
+		{ 0x04, 0xa800 },
+		{ 0x04, 0xf000 },
+		{ 0x03, 0xdf01 },
+		{ 0x02, 0xdf20 },
+		{ 0x01, 0x101a },
+		{ 0x00, 0xa0ff },
+		{ 0x04, 0xf800 },
+		{ 0x04, 0x0000 },
+		{ 0x1f, 0x0000 },
+
+		{ 0x1f, 0x0001 },
+		{ 0x10, 0xf41b },
+		{ 0x14, 0xfb54 },
+		{ 0x18, 0xf5c7 },
+		{ 0x1f, 0x0000 },
+
+		{ 0x1f, 0x0001 },
+		{ 0x17, 0x0cc0 },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+	rtl8169scd_hw_phy_config_quirk(tp, ioaddr);
+}
+
+static void rtl8169sce_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0001 },
+		{ 0x04, 0x0000 },
+		{ 0x03, 0x00a1 },
+		{ 0x02, 0x0008 },
+		{ 0x01, 0x0120 },
+		{ 0x00, 0x1000 },
+		{ 0x04, 0x0800 },
+		{ 0x04, 0x9000 },
+		{ 0x03, 0x802f },
+		{ 0x02, 0x4f02 },
+		{ 0x01, 0x0409 },
+		{ 0x00, 0xf099 },
+		{ 0x04, 0x9800 },
+		{ 0x04, 0xa000 },
+		{ 0x03, 0xdf01 },
+		{ 0x02, 0xdf20 },
+		{ 0x01, 0xff95 },
+		{ 0x00, 0xba00 },
+		{ 0x04, 0xa800 },
+		{ 0x04, 0xf000 },
+		{ 0x03, 0xdf01 },
+		{ 0x02, 0xdf20 },
+		{ 0x01, 0x101a },
+		{ 0x00, 0xa0ff },
+		{ 0x04, 0xf800 },
+		{ 0x04, 0x0000 },
+		{ 0x1f, 0x0000 },
+
+		{ 0x1f, 0x0001 },
+		{ 0x0b, 0x8480 },
+		{ 0x1f, 0x0000 },
+
+		{ 0x1f, 0x0001 },
+		{ 0x18, 0x67c7 },
+		{ 0x04, 0x2000 },
+		{ 0x03, 0x002f },
+		{ 0x02, 0x4360 },
+		{ 0x01, 0x0109 },
+		{ 0x00, 0x3022 },
+		{ 0x04, 0x2800 },
+		{ 0x1f, 0x0000 },
+
+		{ 0x1f, 0x0001 },
+		{ 0x17, 0x0cc0 },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
 static void rtl8168bb_hw_phy_config(void __iomem *ioaddr)
 {
 	struct phy_reg phy_reg_init[] = {
@@ -1607,6 +1730,7 @@ static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
 	mdio_write(ioaddr, 0x1f, 0x0000);
 	mdio_patch(ioaddr, 0x11, 1 << 12);
 	mdio_patch(ioaddr, 0x19, 1 << 13);
+	mdio_patch(ioaddr, 0x10, 1 << 15);
 
 	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
@@ -1628,6 +1752,12 @@ static void rtl_hw_phy_config(struct net_device *dev)
 	case RTL_GIGA_MAC_VER_04:
 		rtl8169sb_hw_phy_config(ioaddr);
 		break;
+	case RTL_GIGA_MAC_VER_05:
+		rtl8169scd_hw_phy_config(tp, ioaddr);
+		break;
+	case RTL_GIGA_MAC_VER_06:
+		rtl8169sce_hw_phy_config(ioaddr);
+		break;
 	case RTL_GIGA_MAC_VER_07:
 	case RTL_GIGA_MAC_VER_08:
 	case RTL_GIGA_MAC_VER_09:
@@ -1861,8 +1991,6 @@ static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *dat
 		return 0;
 
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		mdio_write(tp->mmio_addr, data->reg_num & 0x1f, data->val_in);
 		return 0;
 	}
@@ -2180,7 +2308,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	pci_set_drvdata(pdev, dev);
 
 	if (netif_msg_probe(tp)) {
-		u32 xid = RTL_R32(TxConfig) & 0x7cf0f8ff;
+		u32 xid = RTL_R32(TxConfig) & 0x9cf0f8ff;
 
 		printk(KERN_INFO "%s: %s at 0x%lx, "
 		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
@@ -2757,7 +2885,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
 	EnableBist | \
 	Mac_dbgo_oe | \
 	Force_half_dup | \
-	Force_half_dup | \
+	Force_rxflow_en | \
 	Force_txflow_en | \
 	Cxpl_dbg_sel | \
 	ASF | \
@@ -3228,7 +3356,8 @@ static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
 	return 0;
 }
 
-static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC;
@@ -3237,7 +3366,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dma_addr_t mapping;
 	u32 status, len;
 	u32 opts1;
-	int ret = NETDEV_TX_OK;
 
 	if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
 		if (netif_msg_drv(tp)) {
@@ -3288,14 +3416,12 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			netif_wake_queue(dev);
 	}
 
-out:
-	return ret;
+	return NETDEV_TX_OK;
 
 err_stop:
 	netif_stop_queue(dev);
-	ret = NETDEV_TX_BUSY;
 	dev->stats.tx_dropped++;
-	goto out;
+	return NETDEV_TX_BUSY;
 }
 
 static void rtl8169_pcierr_interrupt(struct net_device *dev)
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 8702e7a..bc98e7f 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -114,11 +114,6 @@ static int rionet_rx_clean(struct net_device *ndev)
 
 		if (error == NET_RX_DROP) {
 			ndev->stats.rx_dropped++;
-		} else if (error == NET_RX_BAD) {
-			if (netif_msg_rx_err(rnet))
-				printk(KERN_WARNING "%s: bad rx packet\n",
-				       DRV_NAME);
-			ndev->stats.rx_errors++;
 		} else {
 			ndev->stats.rx_packets++;
 			ndev->stats.rx_bytes += RIO_MAX_MSG_SIZE;
@@ -208,7 +203,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	spin_unlock_irqrestore(&rnet->tx_lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index 81dbcbb..20a7174 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1401,7 +1401,8 @@ static int rr_close(struct net_device *dev)
 }
 
 
-static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t rr_start_xmit(struct sk_buff *skb,
+				 struct net_device *dev)
 {
 	struct rr_private *rrpriv = netdev_priv(dev);
 	struct rr_regs __iomem *regs = rrpriv->regs;
@@ -1466,7 +1467,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irqrestore(&rrpriv->lock, flags);
 
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/rrunner.h b/drivers/net/rrunner.h
index 6173f11..2816904 100644
--- a/drivers/net/rrunner.h
+++ b/drivers/net/rrunner.h
@@ -831,7 +831,8 @@ static int rr_init1(struct net_device *dev);
 static irqreturn_t rr_interrupt(int irq, void *dev_id);
 
 static int rr_open(struct net_device *dev);
-static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t rr_start_xmit(struct sk_buff *skb,
+				 struct net_device *dev);
 static int rr_close(struct net_device *dev);
 static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static unsigned int rr_read_eeprom(struct rr_private *rrpriv,
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 458daa0..ddccf5f 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1,7 +1,7 @@
 /************************************************************************
  * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
  * Copyright(c) 2002-2007 Neterion Inc.
-
+ *
  * This software may be used and distributed according to the terms of
  * the GNU General Public License (GPL), incorporated herein by reference.
  * Drivers based on or derived from this code fall under the GPL and must
@@ -25,7 +25,7 @@
  * Christopher Hellwig	: Some more 2.6 specific issues in the driver.
  *
  * The module loadable parameters that are supported by the driver and a brief
- * explaination of all the variables.
+ * explanation of all the variables.
  *
  * rx_ring_num : This can be used to program the number of receive rings used
  * in the driver.
@@ -54,6 +54,8 @@
  *      Possible values '1' for enable and '0' for disable. Default is '0'
  ************************************************************************/
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -75,11 +77,11 @@
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
 #include <net/tcp.h>
 
 #include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
 #include <asm/div64.h>
 #include <asm/irq.h>
 
@@ -93,15 +95,15 @@
 static char s2io_driver_name[] = "Neterion";
 static char s2io_driver_version[] = DRV_VERSION;
 
-static int rxd_size[2] = {32,48};
-static int rxd_count[2] = {127,85};
+static int rxd_size[2] = {32, 48};
+static int rxd_count[2] = {127, 85};
 
 static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
 {
 	int ret;
 
 	ret = ((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
-		(GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK));
+	       (GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK));
 
 	return ret;
 }
@@ -111,21 +113,21 @@ static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
  * problem, 600B, 600C, 600D, 640B, 640C and 640D.
  * macro below identifies these cards given the subsystem_id.
  */
-#define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) \
-	(dev_type == XFRAME_I_DEVICE) ?			\
-		((((subid >= 0x600B) && (subid <= 0x600D)) || \
-		 ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0
+#define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid)		\
+	(dev_type == XFRAME_I_DEVICE) ?					\
+	((((subid >= 0x600B) && (subid <= 0x600D)) ||			\
+	  ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0
 
 #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \
 				      ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
 
-static inline int is_s2io_card_up(const struct s2io_nic * sp)
+static inline int is_s2io_card_up(const struct s2io_nic *sp)
 {
 	return test_bit(__S2IO_STATE_CARD_UP, &sp->state);
 }
 
 /* Ethtool related variables and Macros. */
-static char s2io_gstrings[][ETH_GSTRING_LEN] = {
+static const char s2io_gstrings[][ETH_GSTRING_LEN] = {
 	"Register test\t(offline)",
 	"Eeprom test\t(offline)",
 	"Link test\t(online)",
@@ -133,7 +135,7 @@ static char s2io_gstrings[][ETH_GSTRING_LEN] = {
 	"BIST Test\t(offline)"
 };
 
-static char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = {
+static const char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = {
 	{"tmac_frms"},
 	{"tmac_data_octets"},
 	{"tmac_drop_frms"},
@@ -230,7 +232,7 @@ static char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = {
 	{"rxf_wr_cnt"}
 };
 
-static char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = {
+static const char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = {
 	{"rmac_ttl_1519_4095_frms"},
 	{"rmac_ttl_4096_8191_frms"},
 	{"rmac_ttl_8192_max_frms"},
@@ -249,7 +251,7 @@ static char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = {
 	{"link_fault_cnt"}
 };
 
-static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
+static const char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
 	{"\n DRIVER STATISTICS"},
 	{"single_bit_ecc_errs"},
 	{"double_bit_ecc_errs"},
@@ -328,20 +330,20 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
 #define S2IO_ENHANCED_STAT_LEN	ARRAY_SIZE(ethtool_enhanced_stats_keys)
 #define S2IO_DRIVER_STAT_LEN	ARRAY_SIZE(ethtool_driver_stats_keys)
 
-#define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN )
-#define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN )
+#define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN)
+#define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN)
 
-#define XFRAME_I_STAT_STRINGS_LEN ( XFRAME_I_STAT_LEN * ETH_GSTRING_LEN )
-#define XFRAME_II_STAT_STRINGS_LEN ( XFRAME_II_STAT_LEN * ETH_GSTRING_LEN )
+#define XFRAME_I_STAT_STRINGS_LEN (XFRAME_I_STAT_LEN * ETH_GSTRING_LEN)
+#define XFRAME_II_STAT_STRINGS_LEN (XFRAME_II_STAT_LEN * ETH_GSTRING_LEN)
 
 #define S2IO_TEST_LEN	ARRAY_SIZE(s2io_gstrings)
-#define S2IO_STRINGS_LEN	S2IO_TEST_LEN * ETH_GSTRING_LEN
+#define S2IO_STRINGS_LEN	(S2IO_TEST_LEN * ETH_GSTRING_LEN)
 
-#define S2IO_TIMER_CONF(timer, handle, arg, exp)		\
-			init_timer(&timer);			\
-			timer.function = handle;		\
-			timer.data = (unsigned long) arg;	\
-			mod_timer(&timer, (jiffies + exp))	\
+#define S2IO_TIMER_CONF(timer, handle, arg, exp)	\
+	init_timer(&timer);				\
+	timer.function = handle;			\
+	timer.data = (unsigned long)arg;		\
+	mod_timer(&timer, (jiffies + exp))		\
 
 /* copy mac addr to def_mac_addr array */
 static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr)
@@ -361,16 +363,22 @@ static void s2io_vlan_rx_register(struct net_device *dev,
 	int i;
 	struct s2io_nic *nic = netdev_priv(dev);
 	unsigned long flags[MAX_TX_FIFOS];
-	struct mac_info *mac_control = &nic->mac_control;
 	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
 
-	for (i = 0; i < config->tx_fifo_num; i++)
-		spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags[i]);
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		struct fifo_info *fifo = &mac_control->fifos[i];
+
+		spin_lock_irqsave(&fifo->tx_lock, flags[i]);
+	}
 
 	nic->vlgrp = grp;
-	for (i = config->tx_fifo_num - 1; i >= 0; i--)
-		spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock,
-				flags[i]);
+
+	for (i = config->tx_fifo_num - 1; i >= 0; i--) {
+		struct fifo_info *fifo = &mac_control->fifos[i];
+
+		spin_unlock_irqrestore(&fifo->tx_lock, flags[i]);
+	}
 }
 
 /* Unregister the vlan */
@@ -379,18 +387,23 @@ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 	int i;
 	struct s2io_nic *nic = netdev_priv(dev);
 	unsigned long flags[MAX_TX_FIFOS];
-	struct mac_info *mac_control = &nic->mac_control;
 	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
 
-	for (i = 0; i < config->tx_fifo_num; i++)
-		spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags[i]);
+	for (i = 0; i < config->tx_fifo_num; i++) {
+		struct fifo_info *fifo = &mac_control->fifos[i];
+
+		spin_lock_irqsave(&fifo->tx_lock, flags[i]);
+	}
 
 	if (nic->vlgrp)
 		vlan_group_set_device(nic->vlgrp, vid, NULL);
 
-	for (i = config->tx_fifo_num - 1; i >= 0; i--)
-		spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock,
-			flags[i]);
+	for (i = config->tx_fifo_num - 1; i >= 0; i--) {
+		struct fifo_info *fifo = &mac_control->fifos[i];
+
+		spin_unlock_irqrestore(&fifo->tx_lock, flags[i]);
+	}
 }
 
 /*
@@ -496,11 +509,11 @@ S2IO_PARM_INT(ufo, 0);
 S2IO_PARM_INT(vlan_tag_strip, NO_STRIP_IN_PROMISC);
 
 static unsigned int tx_fifo_len[MAX_TX_FIFOS] =
-    {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN};
+{DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN};
 static unsigned int rx_ring_sz[MAX_RX_RINGS] =
-    {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT};
+{[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT};
 static unsigned int rts_frm_len[MAX_RX_RINGS] =
-    {[0 ...(MAX_RX_RINGS - 1)] = 0 };
+{[0 ...(MAX_RX_RINGS - 1)] = 0 };
 
 module_param_array(tx_fifo_len, uint, NULL, 0);
 module_param_array(rx_ring_sz, uint, NULL, 0);
@@ -516,9 +529,9 @@ static struct pci_device_id s2io_tbl[] __devinitdata = {
 	{PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI,
 	 PCI_ANY_ID, PCI_ANY_ID},
 	{PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_WIN,
-         PCI_ANY_ID, PCI_ANY_ID},
-        {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI,
-         PCI_ANY_ID, PCI_ANY_ID},
+	 PCI_ANY_ID, PCI_ANY_ID},
+	{PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI,
+	 PCI_ANY_ID, PCI_ANY_ID},
 	{0,}
 };
 
@@ -531,11 +544,11 @@ static struct pci_error_handlers s2io_err_handler = {
 };
 
 static struct pci_driver s2io_driver = {
-      .name = "S2IO",
-      .id_table = s2io_tbl,
-      .probe = s2io_init_nic,
-      .remove = __devexit_p(s2io_rem_nic),
-      .err_handler = &s2io_err_handler,
+	.name = "S2IO",
+	.id_table = s2io_tbl,
+	.probe = s2io_init_nic,
+	.remove = __devexit_p(s2io_rem_nic),
+	.err_handler = &s2io_err_handler,
 };
 
 /* A simplifier macro used both by init and free shared_mem Fns(). */
@@ -627,37 +640,36 @@ static int init_shared_mem(struct s2io_nic *nic)
 	struct net_device *dev = nic->dev;
 	unsigned long tmp;
 	struct buffAdd *ba;
-
-	struct mac_info *mac_control;
-	struct config_param *config;
+	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
 	unsigned long long mem_allocated = 0;
 
-	mac_control = &nic->mac_control;
-	config = &nic->config;
-
-
-	/* Allocation and initialization of TXDLs in FIOFs */
+	/* Allocation and initialization of TXDLs in FIFOs */
 	size = 0;
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		size += config->tx_cfg[i].fifo_len;
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		size += tx_cfg->fifo_len;
 	}
 	if (size > MAX_AVAILABLE_TXDS) {
-		DBG_PRINT(ERR_DBG, "s2io: Requested TxDs too high, ");
-		DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size);
+		DBG_PRINT(ERR_DBG,
+			  "Too many TxDs requested: %d, max supported: %d\n",
+			  size, MAX_AVAILABLE_TXDS);
 		return -EINVAL;
 	}
 
 	size = 0;
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		size = config->tx_cfg[i].fifo_len;
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		size = tx_cfg->fifo_len;
 		/*
 		 * Legal values are from 2 to 8192
 		 */
 		if (size < 2) {
-			DBG_PRINT(ERR_DBG, "s2io: Invalid fifo len (%d)", size);
-			DBG_PRINT(ERR_DBG, "for fifo %d\n", i);
-			DBG_PRINT(ERR_DBG, "s2io: Legal values for fifo len"
-				"are 2 to 8192\n");
+			DBG_PRINT(ERR_DBG, "Fifo %d: Invalid length (%d) - "
+				  "Valid lengths are 2 through 8192\n",
+				  i, size);
 			return -EINVAL;
 		}
 	}
@@ -666,13 +678,14 @@ static int init_shared_mem(struct s2io_nic *nic)
 	lst_per_page = PAGE_SIZE / lst_size;
 
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		int fifo_len = config->tx_cfg[i].fifo_len;
+		struct fifo_info *fifo = &mac_control->fifos[i];
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+		int fifo_len = tx_cfg->fifo_len;
 		int list_holder_size = fifo_len * sizeof(struct list_info_hold);
-		mac_control->fifos[i].list_info = kzalloc(list_holder_size,
-							  GFP_KERNEL);
-		if (!mac_control->fifos[i].list_info) {
-			DBG_PRINT(INFO_DBG,
-				  "Malloc failed for list_info\n");
+
+		fifo->list_info = kzalloc(list_holder_size, GFP_KERNEL);
+		if (!fifo->list_info) {
+			DBG_PRINT(INFO_DBG, "Malloc failed for list_info\n");
 			return -ENOMEM;
 		}
 		mem_allocated += list_holder_size;
@@ -680,16 +693,17 @@ static int init_shared_mem(struct s2io_nic *nic)
 	for (i = 0; i < config->tx_fifo_num; i++) {
 		int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
 						lst_per_page);
-		mac_control->fifos[i].tx_curr_put_info.offset = 0;
-		mac_control->fifos[i].tx_curr_put_info.fifo_len =
-		    config->tx_cfg[i].fifo_len - 1;
-		mac_control->fifos[i].tx_curr_get_info.offset = 0;
-		mac_control->fifos[i].tx_curr_get_info.fifo_len =
-		    config->tx_cfg[i].fifo_len - 1;
-		mac_control->fifos[i].fifo_no = i;
-		mac_control->fifos[i].nic = nic;
-		mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2;
-		mac_control->fifos[i].dev = dev;
+		struct fifo_info *fifo = &mac_control->fifos[i];
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		fifo->tx_curr_put_info.offset = 0;
+		fifo->tx_curr_put_info.fifo_len = tx_cfg->fifo_len - 1;
+		fifo->tx_curr_get_info.offset = 0;
+		fifo->tx_curr_get_info.fifo_len = tx_cfg->fifo_len - 1;
+		fifo->fifo_no = i;
+		fifo->nic = nic;
+		fifo->max_txds = MAX_SKB_FRAGS + 2;
+		fifo->dev = dev;
 
 		for (j = 0; j < page_num; j++) {
 			int k = 0;
@@ -699,8 +713,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 						     PAGE_SIZE, &tmp_p);
 			if (!tmp_v) {
 				DBG_PRINT(INFO_DBG,
-					  "pci_alloc_consistent ");
-				DBG_PRINT(INFO_DBG, "failed for TxDL\n");
+					  "pci_alloc_consistent failed for TxDL\n");
 				return -ENOMEM;
 			}
 			/* If we got a zero DMA address(can happen on
@@ -711,37 +724,38 @@ static int init_shared_mem(struct s2io_nic *nic)
 			if (!tmp_p) {
 				mac_control->zerodma_virt_addr = tmp_v;
 				DBG_PRINT(INIT_DBG,
-				"%s: Zero DMA address for TxDL. ", dev->name);
-				DBG_PRINT(INIT_DBG,
-				"Virtual address %p\n", tmp_v);
+					  "%s: Zero DMA address for TxDL. "
+					  "Virtual address %p\n",
+					  dev->name, tmp_v);
 				tmp_v = pci_alloc_consistent(nic->pdev,
-						     PAGE_SIZE, &tmp_p);
+							     PAGE_SIZE, &tmp_p);
 				if (!tmp_v) {
 					DBG_PRINT(INFO_DBG,
-					  "pci_alloc_consistent ");
-					DBG_PRINT(INFO_DBG, "failed for TxDL\n");
+						  "pci_alloc_consistent failed for TxDL\n");
 					return -ENOMEM;
 				}
 				mem_allocated += PAGE_SIZE;
 			}
 			while (k < lst_per_page) {
 				int l = (j * lst_per_page) + k;
-				if (l == config->tx_cfg[i].fifo_len)
+				if (l == tx_cfg->fifo_len)
 					break;
-				mac_control->fifos[i].list_info[l].list_virt_addr =
-				    tmp_v + (k * lst_size);
-				mac_control->fifos[i].list_info[l].list_phy_addr =
-				    tmp_p + (k * lst_size);
+				fifo->list_info[l].list_virt_addr =
+					tmp_v + (k * lst_size);
+				fifo->list_info[l].list_phy_addr =
+					tmp_p + (k * lst_size);
 				k++;
 			}
 		}
 	}
 
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		size = config->tx_cfg[i].fifo_len;
-		mac_control->fifos[i].ufo_in_band_v
-			= kcalloc(size, sizeof(u64), GFP_KERNEL);
-		if (!mac_control->fifos[i].ufo_in_band_v)
+		struct fifo_info *fifo = &mac_control->fifos[i];
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		size = tx_cfg->fifo_len;
+		fifo->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL);
+		if (!fifo->ufo_in_band_v)
 			return -ENOMEM;
 		mem_allocated += (size * sizeof(u64));
 	}
@@ -749,20 +763,19 @@ static int init_shared_mem(struct s2io_nic *nic)
 	/* Allocation and initialization of RXDs in Rings */
 	size = 0;
 	for (i = 0; i < config->rx_ring_num; i++) {
-		if (config->rx_cfg[i].num_rxd %
-		    (rxd_count[nic->rxd_mode] + 1)) {
-			DBG_PRINT(ERR_DBG, "%s: RxD count of ", dev->name);
-			DBG_PRINT(ERR_DBG, "Ring%d is not a multiple of ",
-				  i);
-			DBG_PRINT(ERR_DBG, "RxDs per Block");
+		struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+		struct ring_info *ring = &mac_control->rings[i];
+
+		if (rx_cfg->num_rxd % (rxd_count[nic->rxd_mode] + 1)) {
+			DBG_PRINT(ERR_DBG, "%s: Ring%d RxD count is not a "
+				  "multiple of RxDs per Block\n",
+				  dev->name, i);
 			return FAILURE;
 		}
-		size += config->rx_cfg[i].num_rxd;
-		mac_control->rings[i].block_count =
-			config->rx_cfg[i].num_rxd /
-			(rxd_count[nic->rxd_mode] + 1 );
-		mac_control->rings[i].pkt_cnt = config->rx_cfg[i].num_rxd -
-			mac_control->rings[i].block_count;
+		size += rx_cfg->num_rxd;
+		ring->block_count = rx_cfg->num_rxd /
+			(rxd_count[nic->rxd_mode] + 1);
+		ring->pkt_cnt = rx_cfg->num_rxd - ring->block_count;
 	}
 	if (nic->rxd_mode == RXD_MODE_1)
 		size = (size * (sizeof(struct RxD1)));
@@ -770,27 +783,27 @@ static int init_shared_mem(struct s2io_nic *nic)
 		size = (size * (sizeof(struct RxD3)));
 
 	for (i = 0; i < config->rx_ring_num; i++) {
-		mac_control->rings[i].rx_curr_get_info.block_index = 0;
-		mac_control->rings[i].rx_curr_get_info.offset = 0;
-		mac_control->rings[i].rx_curr_get_info.ring_len =
-		    config->rx_cfg[i].num_rxd - 1;
-		mac_control->rings[i].rx_curr_put_info.block_index = 0;
-		mac_control->rings[i].rx_curr_put_info.offset = 0;
-		mac_control->rings[i].rx_curr_put_info.ring_len =
-		    config->rx_cfg[i].num_rxd - 1;
-		mac_control->rings[i].nic = nic;
-		mac_control->rings[i].ring_no = i;
-		mac_control->rings[i].lro = lro_enable;
-
-		blk_cnt = config->rx_cfg[i].num_rxd /
-				(rxd_count[nic->rxd_mode] + 1);
+		struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+		struct ring_info *ring = &mac_control->rings[i];
+
+		ring->rx_curr_get_info.block_index = 0;
+		ring->rx_curr_get_info.offset = 0;
+		ring->rx_curr_get_info.ring_len = rx_cfg->num_rxd - 1;
+		ring->rx_curr_put_info.block_index = 0;
+		ring->rx_curr_put_info.offset = 0;
+		ring->rx_curr_put_info.ring_len = rx_cfg->num_rxd - 1;
+		ring->nic = nic;
+		ring->ring_no = i;
+		ring->lro = lro_enable;
+
+		blk_cnt = rx_cfg->num_rxd / (rxd_count[nic->rxd_mode] + 1);
 		/*  Allocating all the Rx blocks */
 		for (j = 0; j < blk_cnt; j++) {
 			struct rx_block_info *rx_blocks;
 			int l;
 
-			rx_blocks = &mac_control->rings[i].rx_blocks[j];
-			size = SIZE_OF_BLOCK; //size is always page size
+			rx_blocks = &ring->rx_blocks[j];
+			size = SIZE_OF_BLOCK;	/* size is always page size */
 			tmp_v_addr = pci_alloc_consistent(nic->pdev, size,
 							  &tmp_p_addr);
 			if (tmp_v_addr == NULL) {
@@ -805,16 +818,16 @@ static int init_shared_mem(struct s2io_nic *nic)
 			}
 			mem_allocated += size;
 			memset(tmp_v_addr, 0, size);
+
+			size = sizeof(struct rxd_info) *
+				rxd_count[nic->rxd_mode];
 			rx_blocks->block_virt_addr = tmp_v_addr;
 			rx_blocks->block_dma_addr = tmp_p_addr;
-			rx_blocks->rxds = kmalloc(sizeof(struct rxd_info)*
-						  rxd_count[nic->rxd_mode],
-						  GFP_KERNEL);
+			rx_blocks->rxds = kmalloc(size,  GFP_KERNEL);
 			if (!rx_blocks->rxds)
 				return -ENOMEM;
-			mem_allocated +=
-			(sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
-			for (l=0; l<rxd_count[nic->rxd_mode];l++) {
+			mem_allocated += size;
+			for (l = 0; l < rxd_count[nic->rxd_mode]; l++) {
 				rx_blocks->rxds[l].virt_addr =
 					rx_blocks->block_virt_addr +
 					(rxd_size[nic->rxd_mode] * l);
@@ -825,22 +838,17 @@ static int init_shared_mem(struct s2io_nic *nic)
 		}
 		/* Interlinking all Rx Blocks */
 		for (j = 0; j < blk_cnt; j++) {
-			tmp_v_addr =
-				mac_control->rings[i].rx_blocks[j].block_virt_addr;
-			tmp_v_addr_next =
-				mac_control->rings[i].rx_blocks[(j + 1) %
-					      blk_cnt].block_virt_addr;
-			tmp_p_addr =
-				mac_control->rings[i].rx_blocks[j].block_dma_addr;
-			tmp_p_addr_next =
-				mac_control->rings[i].rx_blocks[(j + 1) %
-					      blk_cnt].block_dma_addr;
-
-			pre_rxd_blk = (struct RxD_block *) tmp_v_addr;
+			int next = (j + 1) % blk_cnt;
+			tmp_v_addr = ring->rx_blocks[j].block_virt_addr;
+			tmp_v_addr_next = ring->rx_blocks[next].block_virt_addr;
+			tmp_p_addr = ring->rx_blocks[j].block_dma_addr;
+			tmp_p_addr_next = ring->rx_blocks[next].block_dma_addr;
+
+			pre_rxd_blk = (struct RxD_block *)tmp_v_addr;
 			pre_rxd_blk->reserved_2_pNext_RxD_block =
-			    (unsigned long) tmp_v_addr_next;
+				(unsigned long)tmp_v_addr_next;
 			pre_rxd_blk->pNext_RxD_Blk_physical =
-			    (u64) tmp_p_addr_next;
+				(u64)tmp_p_addr_next;
 		}
 	}
 	if (nic->rxd_mode == RXD_MODE_3B) {
@@ -849,48 +857,46 @@ static int init_shared_mem(struct s2io_nic *nic)
 		 * and the buffers as well.
 		 */
 		for (i = 0; i < config->rx_ring_num; i++) {
-			blk_cnt = config->rx_cfg[i].num_rxd /
-			   (rxd_count[nic->rxd_mode]+ 1);
-			mac_control->rings[i].ba =
-				kmalloc((sizeof(struct buffAdd *) * blk_cnt),
-				     GFP_KERNEL);
-			if (!mac_control->rings[i].ba)
+			struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+			struct ring_info *ring = &mac_control->rings[i];
+
+			blk_cnt = rx_cfg->num_rxd /
+				(rxd_count[nic->rxd_mode] + 1);
+			size = sizeof(struct buffAdd *) * blk_cnt;
+			ring->ba = kmalloc(size, GFP_KERNEL);
+			if (!ring->ba)
 				return -ENOMEM;
-			mem_allocated +=(sizeof(struct buffAdd *) * blk_cnt);
+			mem_allocated += size;
 			for (j = 0; j < blk_cnt; j++) {
 				int k = 0;
-				mac_control->rings[i].ba[j] =
-					kmalloc((sizeof(struct buffAdd) *
-						(rxd_count[nic->rxd_mode] + 1)),
-						GFP_KERNEL);
-				if (!mac_control->rings[i].ba[j])
+
+				size = sizeof(struct buffAdd) *
+					(rxd_count[nic->rxd_mode] + 1);
+				ring->ba[j] = kmalloc(size, GFP_KERNEL);
+				if (!ring->ba[j])
 					return -ENOMEM;
-				mem_allocated += (sizeof(struct buffAdd) *  \
-					(rxd_count[nic->rxd_mode] + 1));
+				mem_allocated += size;
 				while (k != rxd_count[nic->rxd_mode]) {
-					ba = &mac_control->rings[i].ba[j][k];
-
-					ba->ba_0_org = (void *) kmalloc
-					    (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
+					ba = &ring->ba[j][k];
+					size = BUF0_LEN + ALIGN_SIZE;
+					ba->ba_0_org = kmalloc(size, GFP_KERNEL);
 					if (!ba->ba_0_org)
 						return -ENOMEM;
-					mem_allocated +=
-						(BUF0_LEN + ALIGN_SIZE);
+					mem_allocated += size;
 					tmp = (unsigned long)ba->ba_0_org;
 					tmp += ALIGN_SIZE;
-					tmp &= ~((unsigned long) ALIGN_SIZE);
-					ba->ba_0 = (void *) tmp;
+					tmp &= ~((unsigned long)ALIGN_SIZE);
+					ba->ba_0 = (void *)tmp;
 
-					ba->ba_1_org = (void *) kmalloc
-					    (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
+					size = BUF1_LEN + ALIGN_SIZE;
+					ba->ba_1_org = kmalloc(size, GFP_KERNEL);
 					if (!ba->ba_1_org)
 						return -ENOMEM;
-					mem_allocated
-						+= (BUF1_LEN + ALIGN_SIZE);
-					tmp = (unsigned long) ba->ba_1_org;
+					mem_allocated += size;
+					tmp = (unsigned long)ba->ba_1_org;
 					tmp += ALIGN_SIZE;
-					tmp &= ~((unsigned long) ALIGN_SIZE);
-					ba->ba_1 = (void *) tmp;
+					tmp &= ~((unsigned long)ALIGN_SIZE);
+					ba->ba_1 = (void *)tmp;
 					k++;
 				}
 			}
@@ -899,8 +905,9 @@ static int init_shared_mem(struct s2io_nic *nic)
 
 	/* Allocation and initialization of Statistics block */
 	size = sizeof(struct stat_block);
-	mac_control->stats_mem = pci_alloc_consistent
-	    (nic->pdev, size, &mac_control->stats_mem_phy);
+	mac_control->stats_mem =
+		pci_alloc_consistent(nic->pdev, size,
+				     &mac_control->stats_mem_phy);
 
 	if (!mac_control->stats_mem) {
 		/*
@@ -914,10 +921,10 @@ static int init_shared_mem(struct s2io_nic *nic)
 	mac_control->stats_mem_sz = size;
 
 	tmp_v_addr = mac_control->stats_mem;
-	mac_control->stats_info = (struct stat_block *) tmp_v_addr;
+	mac_control->stats_info = (struct stat_block *)tmp_v_addr;
 	memset(tmp_v_addr, 0, size);
-	DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name,
-		  (unsigned long long) tmp_p_addr);
+	DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", dev->name,
+		  (unsigned long long)tmp_p_addr);
 	mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
 	return SUCCESS;
 }
@@ -934,42 +941,46 @@ static void free_shared_mem(struct s2io_nic *nic)
 	int i, j, blk_cnt, size;
 	void *tmp_v_addr;
 	dma_addr_t tmp_p_addr;
-	struct mac_info *mac_control;
-	struct config_param *config;
 	int lst_size, lst_per_page;
 	struct net_device *dev;
 	int page_num = 0;
+	struct config_param *config;
+	struct mac_info *mac_control;
+	struct stat_block *stats;
+	struct swStat *swstats;
 
 	if (!nic)
 		return;
 
 	dev = nic->dev;
 
-	mac_control = &nic->mac_control;
 	config = &nic->config;
+	mac_control = &nic->mac_control;
+	stats = mac_control->stats_info;
+	swstats = &stats->sw_stat;
 
-	lst_size = (sizeof(struct TxD) * config->max_txds);
+	lst_size = sizeof(struct TxD) * config->max_txds;
 	lst_per_page = PAGE_SIZE / lst_size;
 
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
-							lst_per_page);
+		struct fifo_info *fifo = &mac_control->fifos[i];
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		page_num = TXD_MEM_PAGE_CNT(tx_cfg->fifo_len, lst_per_page);
 		for (j = 0; j < page_num; j++) {
 			int mem_blks = (j * lst_per_page);
-			if (!mac_control->fifos[i].list_info)
+			struct list_info_hold *fli;
+
+			if (!fifo->list_info)
 				return;
-			if (!mac_control->fifos[i].list_info[mem_blks].
-				 list_virt_addr)
+
+			fli = &fifo->list_info[mem_blks];
+			if (!fli->list_virt_addr)
 				break;
 			pci_free_consistent(nic->pdev, PAGE_SIZE,
-					    mac_control->fifos[i].
-					    list_info[mem_blks].
-					    list_virt_addr,
-					    mac_control->fifos[i].
-					    list_info[mem_blks].
-					    list_phy_addr);
-			nic->mac_control.stats_info->sw_stat.mem_freed
-						+= PAGE_SIZE;
+					    fli->list_virt_addr,
+					    fli->list_phy_addr);
+			swstats->mem_freed += PAGE_SIZE;
 		}
 		/* If we got a zero DMA address during allocation,
 		 * free the page now
@@ -979,79 +990,80 @@ static void free_shared_mem(struct s2io_nic *nic)
 					    mac_control->zerodma_virt_addr,
 					    (dma_addr_t)0);
 			DBG_PRINT(INIT_DBG,
-			  	"%s: Freeing TxDL with zero DMA addr. ",
-				dev->name);
-			DBG_PRINT(INIT_DBG, "Virtual address %p\n",
-				mac_control->zerodma_virt_addr);
-			nic->mac_control.stats_info->sw_stat.mem_freed
-						+= PAGE_SIZE;
+				  "%s: Freeing TxDL with zero DMA address. "
+				  "Virtual address %p\n",
+				  dev->name, mac_control->zerodma_virt_addr);
+			swstats->mem_freed += PAGE_SIZE;
 		}
-		kfree(mac_control->fifos[i].list_info);
-		nic->mac_control.stats_info->sw_stat.mem_freed +=
-		(nic->config.tx_cfg[i].fifo_len *sizeof(struct list_info_hold));
+		kfree(fifo->list_info);
+		swstats->mem_freed += tx_cfg->fifo_len *
+			sizeof(struct list_info_hold);
 	}
 
 	size = SIZE_OF_BLOCK;
 	for (i = 0; i < config->rx_ring_num; i++) {
-		blk_cnt = mac_control->rings[i].block_count;
+		struct ring_info *ring = &mac_control->rings[i];
+
+		blk_cnt = ring->block_count;
 		for (j = 0; j < blk_cnt; j++) {
-			tmp_v_addr = mac_control->rings[i].rx_blocks[j].
-				block_virt_addr;
-			tmp_p_addr = mac_control->rings[i].rx_blocks[j].
-				block_dma_addr;
+			tmp_v_addr = ring->rx_blocks[j].block_virt_addr;
+			tmp_p_addr = ring->rx_blocks[j].block_dma_addr;
 			if (tmp_v_addr == NULL)
 				break;
 			pci_free_consistent(nic->pdev, size,
 					    tmp_v_addr, tmp_p_addr);
-			nic->mac_control.stats_info->sw_stat.mem_freed += size;
-			kfree(mac_control->rings[i].rx_blocks[j].rxds);
-			nic->mac_control.stats_info->sw_stat.mem_freed +=
-			( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
+			swstats->mem_freed += size;
+			kfree(ring->rx_blocks[j].rxds);
+			swstats->mem_freed += sizeof(struct rxd_info) *
+				rxd_count[nic->rxd_mode];
 		}
 	}
 
 	if (nic->rxd_mode == RXD_MODE_3B) {
 		/* Freeing buffer storage addresses in 2BUFF mode. */
 		for (i = 0; i < config->rx_ring_num; i++) {
-			blk_cnt = config->rx_cfg[i].num_rxd /
-			    (rxd_count[nic->rxd_mode] + 1);
+			struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+			struct ring_info *ring = &mac_control->rings[i];
+
+			blk_cnt = rx_cfg->num_rxd /
+				(rxd_count[nic->rxd_mode] + 1);
 			for (j = 0; j < blk_cnt; j++) {
 				int k = 0;
-				if (!mac_control->rings[i].ba[j])
+				if (!ring->ba[j])
 					continue;
 				while (k != rxd_count[nic->rxd_mode]) {
-					struct buffAdd *ba =
-						&mac_control->rings[i].ba[j][k];
+					struct buffAdd *ba = &ring->ba[j][k];
 					kfree(ba->ba_0_org);
-					nic->mac_control.stats_info->sw_stat.\
-					mem_freed += (BUF0_LEN + ALIGN_SIZE);
+					swstats->mem_freed +=
+						BUF0_LEN + ALIGN_SIZE;
 					kfree(ba->ba_1_org);
-					nic->mac_control.stats_info->sw_stat.\
-					mem_freed += (BUF1_LEN + ALIGN_SIZE);
+					swstats->mem_freed +=
+						BUF1_LEN + ALIGN_SIZE;
 					k++;
 				}
-				kfree(mac_control->rings[i].ba[j]);
-				nic->mac_control.stats_info->sw_stat.mem_freed +=
-					(sizeof(struct buffAdd) *
-					(rxd_count[nic->rxd_mode] + 1));
+				kfree(ring->ba[j]);
+				swstats->mem_freed += sizeof(struct buffAdd) *
+					(rxd_count[nic->rxd_mode] + 1);
 			}
-			kfree(mac_control->rings[i].ba);
-			nic->mac_control.stats_info->sw_stat.mem_freed +=
-			(sizeof(struct buffAdd *) * blk_cnt);
+			kfree(ring->ba);
+			swstats->mem_freed += sizeof(struct buffAdd *) *
+				blk_cnt;
 		}
 	}
 
 	for (i = 0; i < nic->config.tx_fifo_num; i++) {
-		if (mac_control->fifos[i].ufo_in_band_v) {
-			nic->mac_control.stats_info->sw_stat.mem_freed
-				+= (config->tx_cfg[i].fifo_len * sizeof(u64));
-			kfree(mac_control->fifos[i].ufo_in_band_v);
+		struct fifo_info *fifo = &mac_control->fifos[i];
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		if (fifo->ufo_in_band_v) {
+			swstats->mem_freed += tx_cfg->fifo_len *
+				sizeof(u64);
+			kfree(fifo->ufo_in_band_v);
 		}
 	}
 
 	if (mac_control->stats_mem) {
-		nic->mac_control.stats_info->sw_stat.mem_freed +=
-			mac_control->stats_mem_sz;
+		swstats->mem_freed += mac_control->stats_mem_sz;
 		pci_free_consistent(nic->pdev,
 				    mac_control->stats_mem_sz,
 				    mac_control->stats_mem,
@@ -1072,7 +1084,7 @@ static int s2io_verify_pci_mode(struct s2io_nic *nic)
 	val64 = readq(&bar0->pci_mode);
 	mode = (u8)GET_PCI_MODE(val64);
 
-	if ( val64 & PCI_MODE_UNKNOWN_MODE)
+	if (val64 & PCI_MODE_UNKNOWN_MODE)
 		return -1;      /* Unknown PCI mode */
 	return mode;
 }
@@ -1103,55 +1115,54 @@ static int s2io_print_pci_mode(struct s2io_nic *nic)
 	register u64 val64 = 0;
 	int	mode;
 	struct config_param *config = &nic->config;
+	const char *pcimode;
 
 	val64 = readq(&bar0->pci_mode);
 	mode = (u8)GET_PCI_MODE(val64);
 
-	if ( val64 & PCI_MODE_UNKNOWN_MODE)
+	if (val64 & PCI_MODE_UNKNOWN_MODE)
 		return -1;	/* Unknown PCI mode */
 
 	config->bus_speed = bus_speed[mode];
 
 	if (s2io_on_nec_bridge(nic->pdev)) {
 		DBG_PRINT(ERR_DBG, "%s: Device is on PCI-E bus\n",
-							nic->dev->name);
+			  nic->dev->name);
 		return mode;
 	}
 
-	if (val64 & PCI_MODE_32_BITS) {
-		DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name);
-	} else {
-		DBG_PRINT(ERR_DBG, "%s: Device is on 64 bit ", nic->dev->name);
+	switch (mode) {
+	case PCI_MODE_PCI_33:
+		pcimode = "33MHz PCI bus";
+		break;
+	case PCI_MODE_PCI_66:
+		pcimode = "66MHz PCI bus";
+		break;
+	case PCI_MODE_PCIX_M1_66:
+		pcimode = "66MHz PCIX(M1) bus";
+		break;
+	case PCI_MODE_PCIX_M1_100:
+		pcimode = "100MHz PCIX(M1) bus";
+		break;
+	case PCI_MODE_PCIX_M1_133:
+		pcimode = "133MHz PCIX(M1) bus";
+		break;
+	case PCI_MODE_PCIX_M2_66:
+		pcimode = "133MHz PCIX(M2) bus";
+		break;
+	case PCI_MODE_PCIX_M2_100:
+		pcimode = "200MHz PCIX(M2) bus";
+		break;
+	case PCI_MODE_PCIX_M2_133:
+		pcimode = "266MHz PCIX(M2) bus";
+		break;
+	default:
+		pcimode = "unsupported bus!";
+		mode = -1;
 	}
 
-	switch(mode) {
-		case PCI_MODE_PCI_33:
-			DBG_PRINT(ERR_DBG, "33MHz PCI bus\n");
-			break;
-		case PCI_MODE_PCI_66:
-			DBG_PRINT(ERR_DBG, "66MHz PCI bus\n");
-			break;
-		case PCI_MODE_PCIX_M1_66:
-			DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n");
-			break;
-		case PCI_MODE_PCIX_M1_100:
-			DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n");
-			break;
-		case PCI_MODE_PCIX_M1_133:
-			DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n");
-			break;
-		case PCI_MODE_PCIX_M2_66:
-			DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n");
-			break;
-		case PCI_MODE_PCIX_M2_100:
-			DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n");
-			break;
-		case PCI_MODE_PCIX_M2_133:
-			DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n");
-			break;
-		default:
-			return -1;	/* Unsupported bus speed */
-	}
+	DBG_PRINT(ERR_DBG, "%s: Device is on %d bit %s\n",
+		  nic->dev->name, val64 & PCI_MODE_32_BITS ? 32 : 64, pcimode);
 
 	return mode;
 }
@@ -1171,9 +1182,7 @@ static int init_tti(struct s2io_nic *nic, int link)
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0;
 	int i;
-	struct config_param *config;
-
-	config = &nic->config;
+	struct config_param *config = &nic->config;
 
 	for (i = 0; i < config->tx_fifo_num; i++) {
 		/*
@@ -1188,9 +1197,9 @@ static int init_tti(struct s2io_nic *nic, int link)
 			val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078);
 
 		val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) |
-				TTI_DATA1_MEM_TX_URNG_B(0x10) |
-				TTI_DATA1_MEM_TX_URNG_C(0x30) |
-				TTI_DATA1_MEM_TX_TIMER_AC_EN;
+			TTI_DATA1_MEM_TX_URNG_B(0x10) |
+			TTI_DATA1_MEM_TX_URNG_C(0x30) |
+			TTI_DATA1_MEM_TX_TIMER_AC_EN;
 		if (i == 0)
 			if (use_continuous_tx_intrs && (link == LINK_UP))
 				val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
@@ -1203,11 +1212,11 @@ static int init_tti(struct s2io_nic *nic, int link)
 				TTI_DATA2_MEM_TX_UFC_D(0x300);
 		} else {
 			if ((nic->config.tx_steering_type ==
-				TX_DEFAULT_STEERING) &&
-				(config->tx_fifo_num > 1) &&
-				(i >= nic->udp_fifo_idx) &&
-				(i < (nic->udp_fifo_idx +
-				nic->total_udp_fifos)))
+			     TX_DEFAULT_STEERING) &&
+			    (config->tx_fifo_num > 1) &&
+			    (i >= nic->udp_fifo_idx) &&
+			    (i < (nic->udp_fifo_idx +
+				  nic->total_udp_fifos)))
 				val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) |
 					TTI_DATA2_MEM_TX_UFC_B(0x80) |
 					TTI_DATA2_MEM_TX_UFC_C(0x100) |
@@ -1221,12 +1230,14 @@ static int init_tti(struct s2io_nic *nic, int link)
 
 		writeq(val64, &bar0->tti_data2_mem);
 
-		val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD |
-				TTI_CMD_MEM_OFFSET(i);
+		val64 = TTI_CMD_MEM_WE |
+			TTI_CMD_MEM_STROBE_NEW_CMD |
+			TTI_CMD_MEM_OFFSET(i);
 		writeq(val64, &bar0->tti_command_mem);
 
 		if (wait_for_cmd_complete(&bar0->tti_command_mem,
-			TTI_CMD_MEM_STROBE_NEW_CMD, S2IO_BIT_RESET) != SUCCESS)
+					  TTI_CMD_MEM_STROBE_NEW_CMD,
+					  S2IO_BIT_RESET) != SUCCESS)
 			return FAILURE;
 	}
 
@@ -1250,18 +1261,15 @@ static int init_nic(struct s2io_nic *nic)
 	void __iomem *add;
 	u32 time;
 	int i, j;
-	struct mac_info *mac_control;
-	struct config_param *config;
 	int dtx_cnt = 0;
 	unsigned long long mem_share;
 	int mem_size;
-
-	mac_control = &nic->mac_control;
-	config = &nic->config;
+	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
 
 	/* to set the swapper controle on the card */
-	if(s2io_set_swapper(nic)) {
-		DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n");
+	if (s2io_set_swapper(nic)) {
+		DBG_PRINT(ERR_DBG, "ERROR: Setting Swapper failed\n");
 		return -EIO;
 	}
 
@@ -1300,7 +1308,7 @@ static int init_nic(struct s2io_nic *nic)
 	val64 = readq(&bar0->mac_cfg);
 	val64 |= MAC_RMAC_BCAST_ENABLE;
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
-	writel((u32) val64, add);
+	writel((u32)val64, add);
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
 	writel((u32) (val64 >> 32), (add + 4));
 
@@ -1337,12 +1345,11 @@ static int init_nic(struct s2io_nic *nic)
 	writeq(val64, &bar0->tx_fifo_partition_2);
 	writeq(val64, &bar0->tx_fifo_partition_3);
 
-
 	for (i = 0, j = 0; i < config->tx_fifo_num; i++) {
-		val64 |=
-		    vBIT(config->tx_cfg[i].fifo_len - 1, ((j * 32) + 19),
-			 13) | vBIT(config->tx_cfg[i].fifo_priority,
-				    ((j * 32) + 5), 3);
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		val64 |= vBIT(tx_cfg->fifo_len - 1, ((j * 32) + 19), 13) |
+			vBIT(tx_cfg->fifo_priority, ((j * 32) + 5), 3);
 
 		if (i == (config->tx_fifo_num - 1)) {
 			if (i % 2 == 0)
@@ -1380,29 +1387,30 @@ static int init_nic(struct s2io_nic *nic)
 	 * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug
 	 * SXE-008 TRANSMIT DMA ARBITRATION ISSUE.
 	 */
-	if ((nic->device_type == XFRAME_I_DEVICE) &&
-		(nic->pdev->revision < 4))
+	if ((nic->device_type == XFRAME_I_DEVICE) && (nic->pdev->revision < 4))
 		writeq(PCC_ENABLE_FOUR, &bar0->pcc_enable);
 
 	val64 = readq(&bar0->tx_fifo_partition_0);
 	DBG_PRINT(INIT_DBG, "Fifo partition at: 0x%p is: 0x%llx\n",
-		  &bar0->tx_fifo_partition_0, (unsigned long long) val64);
+		  &bar0->tx_fifo_partition_0, (unsigned long long)val64);
 
 	/*
 	 * Initialization of Tx_PA_CONFIG register to ignore packet
 	 * integrity checking.
 	 */
 	val64 = readq(&bar0->tx_pa_cfg);
-	val64 |= TX_PA_CFG_IGNORE_FRM_ERR | TX_PA_CFG_IGNORE_SNAP_OUI |
-	    TX_PA_CFG_IGNORE_LLC_CTRL | TX_PA_CFG_IGNORE_L2_ERR;
+	val64 |= TX_PA_CFG_IGNORE_FRM_ERR |
+		TX_PA_CFG_IGNORE_SNAP_OUI |
+		TX_PA_CFG_IGNORE_LLC_CTRL |
+		TX_PA_CFG_IGNORE_L2_ERR;
 	writeq(val64, &bar0->tx_pa_cfg);
 
 	/* Rx DMA intialization. */
 	val64 = 0;
 	for (i = 0; i < config->rx_ring_num; i++) {
-		val64 |=
-		    vBIT(config->rx_cfg[i].ring_priority, (5 + (i * 8)),
-			 3);
+		struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+
+		val64 |= vBIT(rx_cfg->ring_priority, (5 + (i * 8)), 3);
 	}
 	writeq(val64, &bar0->rx_queue_priority);
 
@@ -1686,16 +1694,16 @@ static int init_nic(struct s2io_nic *nic)
 		 */
 		if (rts_frm_len[i] != 0) {
 			writeq(MAC_RTS_FRM_LEN_SET(rts_frm_len[i]),
-				&bar0->rts_frm_len_n[i]);
+			       &bar0->rts_frm_len_n[i]);
 		}
 	}
 
 	/* Disable differentiated services steering logic */
 	for (i = 0; i < 64; i++) {
 		if (rts_ds_steer(nic, i, 0) == FAILURE) {
-			DBG_PRINT(ERR_DBG, "%s: failed rts ds steering",
-				dev->name);
-			DBG_PRINT(ERR_DBG, "set on codepoint %d\n", i);
+			DBG_PRINT(ERR_DBG,
+				  "%s: rts_ds_steer failed on codepoint %d\n",
+				  dev->name, i);
 			return -ENODEV;
 		}
 	}
@@ -1713,7 +1721,7 @@ static int init_nic(struct s2io_nic *nic)
 	 * bandwidth utilization.
 	 */
 	val64 = MAC_TX_LINK_UTIL_VAL(tmac_util_period) |
-	    MAC_RX_LINK_UTIL_VAL(rmac_util_period);
+		MAC_RX_LINK_UTIL_VAL(rmac_util_period);
 	writeq(val64, &bar0->mac_link_util);
 
 	/*
@@ -1736,24 +1744,26 @@ static int init_nic(struct s2io_nic *nic)
 	} else
 		val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF);
 	val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) |
-		 RTI_DATA1_MEM_RX_URNG_B(0x10) |
-		 RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN;
+		RTI_DATA1_MEM_RX_URNG_B(0x10) |
+		RTI_DATA1_MEM_RX_URNG_C(0x30) |
+		RTI_DATA1_MEM_RX_TIMER_AC_EN;
 
 	writeq(val64, &bar0->rti_data1_mem);
 
 	val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
 		RTI_DATA2_MEM_RX_UFC_B(0x2) ;
 	if (nic->config.intr_type == MSI_X)
-	    val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
-			RTI_DATA2_MEM_RX_UFC_D(0x40));
+		val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) |
+			  RTI_DATA2_MEM_RX_UFC_D(0x40));
 	else
-	    val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \
-			RTI_DATA2_MEM_RX_UFC_D(0x80));
+		val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) |
+			  RTI_DATA2_MEM_RX_UFC_D(0x80));
 	writeq(val64, &bar0->rti_data2_mem);
 
 	for (i = 0; i < config->rx_ring_num; i++) {
-		val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD
-				| RTI_CMD_MEM_OFFSET(i);
+		val64 = RTI_CMD_MEM_WE |
+			RTI_CMD_MEM_STROBE_NEW_CMD |
+			RTI_CMD_MEM_OFFSET(i);
 		writeq(val64, &bar0->rti_command_mem);
 
 		/*
@@ -1770,7 +1780,7 @@ static int init_nic(struct s2io_nic *nic)
 				break;
 
 			if (time > 10) {
-				DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n",
+				DBG_PRINT(ERR_DBG, "%s: RTI init failed\n",
 					  dev->name);
 				return -ENODEV;
 			}
@@ -1826,19 +1836,17 @@ static int init_nic(struct s2io_nic *nic)
 	 */
 	val64 = 0;
 	for (i = 0; i < 4; i++) {
-		val64 |=
-		    (((u64) 0xFF00 | nic->mac_control.
-		      mc_pause_threshold_q0q3)
-		     << (i * 2 * 8));
+		val64 |= (((u64)0xFF00 |
+			   nic->mac_control.mc_pause_threshold_q0q3)
+			  << (i * 2 * 8));
 	}
 	writeq(val64, &bar0->mc_pause_thresh_q0q3);
 
 	val64 = 0;
 	for (i = 0; i < 4; i++) {
-		val64 |=
-		    (((u64) 0xFF00 | nic->mac_control.
-		      mc_pause_threshold_q4q7)
-		     << (i * 2 * 8));
+		val64 |= (((u64)0xFF00 |
+			   nic->mac_control.mc_pause_threshold_q4q7)
+			  << (i * 2 * 8));
 	}
 	writeq(val64, &bar0->mc_pause_thresh_q4q7);
 
@@ -1901,10 +1909,10 @@ static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr)
 
 	temp64 = readq(addr);
 
-	if(flag == ENABLE_INTRS)
-		temp64 &= ~((u64) value);
+	if (flag == ENABLE_INTRS)
+		temp64 &= ~((u64)value);
 	else
-		temp64 |= ((u64) value);
+		temp64 |= ((u64)value);
 	writeq(temp64, addr);
 }
 
@@ -1916,124 +1924,125 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
 
 	writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask);
 	if (mask & TX_DMA_INTR) {
-
 		gen_int_mask |= TXDMA_INT_M;
 
 		do_s2io_write_bits(TXDMA_TDA_INT | TXDMA_PFC_INT |
-				TXDMA_PCC_INT | TXDMA_TTI_INT |
-				TXDMA_LSO_INT | TXDMA_TPA_INT |
-				TXDMA_SM_INT, flag, &bar0->txdma_int_mask);
+				   TXDMA_PCC_INT | TXDMA_TTI_INT |
+				   TXDMA_LSO_INT | TXDMA_TPA_INT |
+				   TXDMA_SM_INT, flag, &bar0->txdma_int_mask);
 
 		do_s2io_write_bits(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM |
-				PFC_MISC_0_ERR | PFC_MISC_1_ERR |
-				PFC_PCIX_ERR | PFC_ECC_SG_ERR, flag,
-				&bar0->pfc_err_mask);
+				   PFC_MISC_0_ERR | PFC_MISC_1_ERR |
+				   PFC_PCIX_ERR | PFC_ECC_SG_ERR, flag,
+				   &bar0->pfc_err_mask);
 
 		do_s2io_write_bits(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM |
-				TDA_SM1_ERR_ALARM | TDA_Fn_ECC_SG_ERR |
-				TDA_PCIX_ERR, flag, &bar0->tda_err_mask);
+				   TDA_SM1_ERR_ALARM | TDA_Fn_ECC_SG_ERR |
+				   TDA_PCIX_ERR, flag, &bar0->tda_err_mask);
 
 		do_s2io_write_bits(PCC_FB_ECC_DB_ERR | PCC_TXB_ECC_DB_ERR |
-				PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM |
-				PCC_N_SERR | PCC_6_COF_OV_ERR |
-				PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR |
-				PCC_7_LSO_OV_ERR | PCC_FB_ECC_SG_ERR |
-				PCC_TXB_ECC_SG_ERR, flag, &bar0->pcc_err_mask);
+				   PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM |
+				   PCC_N_SERR | PCC_6_COF_OV_ERR |
+				   PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR |
+				   PCC_7_LSO_OV_ERR | PCC_FB_ECC_SG_ERR |
+				   PCC_TXB_ECC_SG_ERR,
+				   flag, &bar0->pcc_err_mask);
 
 		do_s2io_write_bits(TTI_SM_ERR_ALARM | TTI_ECC_SG_ERR |
-				TTI_ECC_DB_ERR, flag, &bar0->tti_err_mask);
+				   TTI_ECC_DB_ERR, flag, &bar0->tti_err_mask);
 
 		do_s2io_write_bits(LSO6_ABORT | LSO7_ABORT |
-				LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM |
-				LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
-				flag, &bar0->lso_err_mask);
+				   LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM |
+				   LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
+				   flag, &bar0->lso_err_mask);
 
 		do_s2io_write_bits(TPA_SM_ERR_ALARM | TPA_TX_FRM_DROP,
-				flag, &bar0->tpa_err_mask);
+				   flag, &bar0->tpa_err_mask);
 
 		do_s2io_write_bits(SM_SM_ERR_ALARM, flag, &bar0->sm_err_mask);
-
 	}
 
 	if (mask & TX_MAC_INTR) {
 		gen_int_mask |= TXMAC_INT_M;
 		do_s2io_write_bits(MAC_INT_STATUS_TMAC_INT, flag,
-				&bar0->mac_int_mask);
+				   &bar0->mac_int_mask);
 		do_s2io_write_bits(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR |
-				TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR |
-				TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
-				flag, &bar0->mac_tmac_err_mask);
+				   TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR |
+				   TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
+				   flag, &bar0->mac_tmac_err_mask);
 	}
 
 	if (mask & TX_XGXS_INTR) {
 		gen_int_mask |= TXXGXS_INT_M;
 		do_s2io_write_bits(XGXS_INT_STATUS_TXGXS, flag,
-				&bar0->xgxs_int_mask);
+				   &bar0->xgxs_int_mask);
 		do_s2io_write_bits(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR |
-				TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
-				flag, &bar0->xgxs_txgxs_err_mask);
+				   TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
+				   flag, &bar0->xgxs_txgxs_err_mask);
 	}
 
 	if (mask & RX_DMA_INTR) {
 		gen_int_mask |= RXDMA_INT_M;
 		do_s2io_write_bits(RXDMA_INT_RC_INT_M | RXDMA_INT_RPA_INT_M |
-				RXDMA_INT_RDA_INT_M | RXDMA_INT_RTI_INT_M,
-				flag, &bar0->rxdma_int_mask);
+				   RXDMA_INT_RDA_INT_M | RXDMA_INT_RTI_INT_M,
+				   flag, &bar0->rxdma_int_mask);
 		do_s2io_write_bits(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR |
-				RC_PRCn_SM_ERR_ALARM | RC_FTC_SM_ERR_ALARM |
-				RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR |
-				RC_RDA_FAIL_WR_Rn, flag, &bar0->rc_err_mask);
+				   RC_PRCn_SM_ERR_ALARM | RC_FTC_SM_ERR_ALARM |
+				   RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR |
+				   RC_RDA_FAIL_WR_Rn, flag, &bar0->rc_err_mask);
 		do_s2io_write_bits(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn |
-				PRC_PCI_AB_F_WR_Rn | PRC_PCI_DP_RD_Rn |
-				PRC_PCI_DP_WR_Rn | PRC_PCI_DP_F_WR_Rn, flag,
-				&bar0->prc_pcix_err_mask);
+				   PRC_PCI_AB_F_WR_Rn | PRC_PCI_DP_RD_Rn |
+				   PRC_PCI_DP_WR_Rn | PRC_PCI_DP_F_WR_Rn, flag,
+				   &bar0->prc_pcix_err_mask);
 		do_s2io_write_bits(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR |
-				RPA_ECC_SG_ERR | RPA_ECC_DB_ERR, flag,
-				&bar0->rpa_err_mask);
+				   RPA_ECC_SG_ERR | RPA_ECC_DB_ERR, flag,
+				   &bar0->rpa_err_mask);
 		do_s2io_write_bits(RDA_RXDn_ECC_DB_ERR | RDA_FRM_ECC_DB_N_AERR |
-				RDA_SM1_ERR_ALARM | RDA_SM0_ERR_ALARM |
-				RDA_RXD_ECC_DB_SERR | RDA_RXDn_ECC_SG_ERR |
-				RDA_FRM_ECC_SG_ERR | RDA_MISC_ERR|RDA_PCIX_ERR,
-				flag, &bar0->rda_err_mask);
+				   RDA_SM1_ERR_ALARM | RDA_SM0_ERR_ALARM |
+				   RDA_RXD_ECC_DB_SERR | RDA_RXDn_ECC_SG_ERR |
+				   RDA_FRM_ECC_SG_ERR |
+				   RDA_MISC_ERR|RDA_PCIX_ERR,
+				   flag, &bar0->rda_err_mask);
 		do_s2io_write_bits(RTI_SM_ERR_ALARM |
-				RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
-				flag, &bar0->rti_err_mask);
+				   RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
+				   flag, &bar0->rti_err_mask);
 	}
 
 	if (mask & RX_MAC_INTR) {
 		gen_int_mask |= RXMAC_INT_M;
 		do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
-				&bar0->mac_int_mask);
-		interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
-				RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
-				RMAC_DOUBLE_ECC_ERR;
+				   &bar0->mac_int_mask);
+		interruptible = (RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
+				 RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
+				 RMAC_DOUBLE_ECC_ERR);
 		if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER)
 			interruptible |= RMAC_LINK_STATE_CHANGE_INT;
 		do_s2io_write_bits(interruptible,
-				flag, &bar0->mac_rmac_err_mask);
+				   flag, &bar0->mac_rmac_err_mask);
 	}
 
-	if (mask & RX_XGXS_INTR)
-	{
+	if (mask & RX_XGXS_INTR) {
 		gen_int_mask |= RXXGXS_INT_M;
 		do_s2io_write_bits(XGXS_INT_STATUS_RXGXS, flag,
-				&bar0->xgxs_int_mask);
+				   &bar0->xgxs_int_mask);
 		do_s2io_write_bits(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR, flag,
-				&bar0->xgxs_rxgxs_err_mask);
+				   &bar0->xgxs_rxgxs_err_mask);
 	}
 
 	if (mask & MC_INTR) {
 		gen_int_mask |= MC_INT_M;
-		do_s2io_write_bits(MC_INT_MASK_MC_INT, flag, &bar0->mc_int_mask);
+		do_s2io_write_bits(MC_INT_MASK_MC_INT,
+				   flag, &bar0->mc_int_mask);
 		do_s2io_write_bits(MC_ERR_REG_SM_ERR | MC_ERR_REG_ECC_ALL_SNG |
-				MC_ERR_REG_ECC_ALL_DBL | PLL_LOCK_N, flag,
-				&bar0->mc_err_mask);
+				   MC_ERR_REG_ECC_ALL_DBL | PLL_LOCK_N, flag,
+				   &bar0->mc_err_mask);
 	}
 	nic->general_int_mask = gen_int_mask;
 
 	/* Remove this line when alarm interrupts are enabled */
 	nic->general_int_mask = 0;
 }
+
 /**
  *  en_dis_able_nic_intrs - Enable or Disable the interrupts
  *  @nic: device private variable,
@@ -2065,11 +2074,11 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
 			 * TODO
 			 */
 			if (s2io_link_fault_indication(nic) ==
-					LINK_UP_DOWN_INTERRUPT ) {
+			    LINK_UP_DOWN_INTERRUPT) {
 				do_s2io_write_bits(PIC_INT_GPIO, flag,
-						&bar0->pic_int_mask);
+						   &bar0->pic_int_mask);
 				do_s2io_write_bits(GPIO_INT_MASK_LINK_UP, flag,
-						&bar0->gpio_int_mask);
+						   &bar0->gpio_int_mask);
 			} else
 				writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
 		} else if (flag == DISABLE_INTRS) {
@@ -2116,7 +2125,7 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
 
 	temp64 = readq(&bar0->general_int_mask);
 	if (flag == ENABLE_INTRS)
-		temp64 &= ~((u64) intr_mask);
+		temp64 &= ~((u64)intr_mask);
 	else
 		temp64 = DISABLE_ALL_INTRS;
 	writeq(temp64, &bar0->general_int_mask);
@@ -2177,35 +2186,35 @@ static int verify_xena_quiescence(struct s2io_nic *sp)
 	mode = s2io_verify_pci_mode(sp);
 
 	if (!(val64 & ADAPTER_STATUS_TDMA_READY)) {
-		DBG_PRINT(ERR_DBG, "%s", "TDMA is not ready!");
+		DBG_PRINT(ERR_DBG, "TDMA is not ready!\n");
 		return 0;
 	}
 	if (!(val64 & ADAPTER_STATUS_RDMA_READY)) {
-	DBG_PRINT(ERR_DBG, "%s", "RDMA is not ready!");
+		DBG_PRINT(ERR_DBG, "RDMA is not ready!\n");
 		return 0;
 	}
 	if (!(val64 & ADAPTER_STATUS_PFC_READY)) {
-		DBG_PRINT(ERR_DBG, "%s", "PFC is not ready!");
+		DBG_PRINT(ERR_DBG, "PFC is not ready!\n");
 		return 0;
 	}
 	if (!(val64 & ADAPTER_STATUS_TMAC_BUF_EMPTY)) {
-		DBG_PRINT(ERR_DBG, "%s", "TMAC BUF is not empty!");
+		DBG_PRINT(ERR_DBG, "TMAC BUF is not empty!\n");
 		return 0;
 	}
 	if (!(val64 & ADAPTER_STATUS_PIC_QUIESCENT)) {
-		DBG_PRINT(ERR_DBG, "%s", "PIC is not QUIESCENT!");
+		DBG_PRINT(ERR_DBG, "PIC is not QUIESCENT!\n");
 		return 0;
 	}
 	if (!(val64 & ADAPTER_STATUS_MC_DRAM_READY)) {
-		DBG_PRINT(ERR_DBG, "%s", "MC_DRAM is not ready!");
+		DBG_PRINT(ERR_DBG, "MC_DRAM is not ready!\n");
 		return 0;
 	}
 	if (!(val64 & ADAPTER_STATUS_MC_QUEUES_READY)) {
-		DBG_PRINT(ERR_DBG, "%s", "MC_QUEUES is not ready!");
+		DBG_PRINT(ERR_DBG, "MC_QUEUES is not ready!\n");
 		return 0;
 	}
 	if (!(val64 & ADAPTER_STATUS_M_PLL_LOCK)) {
-		DBG_PRINT(ERR_DBG, "%s", "M_PLL is not locked!");
+		DBG_PRINT(ERR_DBG, "M_PLL is not locked!\n");
 		return 0;
 	}
 
@@ -2215,14 +2224,14 @@ static int verify_xena_quiescence(struct s2io_nic *sp)
 	 * not be asserted.
 	 */
 	if (!(val64 & ADAPTER_STATUS_P_PLL_LOCK) &&
-		sp->device_type == XFRAME_II_DEVICE && mode !=
-		PCI_MODE_PCI_33) {
-		DBG_PRINT(ERR_DBG, "%s", "P_PLL is not locked!");
+	    sp->device_type == XFRAME_II_DEVICE &&
+	    mode != PCI_MODE_PCI_33) {
+		DBG_PRINT(ERR_DBG, "P_PLL is not locked!\n");
 		return 0;
 	}
 	if (!((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
-			ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
-		DBG_PRINT(ERR_DBG, "%s", "RC_PRC is not QUIESCENT!");
+	      ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
+		DBG_PRINT(ERR_DBG, "RC_PRC is not QUIESCENT!\n");
 		return 0;
 	}
 	return 1;
@@ -2236,7 +2245,7 @@ static int verify_xena_quiescence(struct s2io_nic *sp)
  *
  */
 
-static void fix_mac_address(struct s2io_nic * sp)
+static void fix_mac_address(struct s2io_nic *sp)
 {
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	u64 val64;
@@ -2268,15 +2277,14 @@ static int start_nic(struct s2io_nic *nic)
 	struct net_device *dev = nic->dev;
 	register u64 val64 = 0;
 	u16 subid, i;
-	struct mac_info *mac_control;
-	struct config_param *config;
-
-	mac_control = &nic->mac_control;
-	config = &nic->config;
+	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
 
 	/*  PRC Initialization and configuration */
 	for (i = 0; i < config->rx_ring_num; i++) {
-		writeq((u64) mac_control->rings[i].rx_blocks[0].block_dma_addr,
+		struct ring_info *ring = &mac_control->rings[i];
+
+		writeq((u64)ring->rx_blocks[0].block_dma_addr,
 		       &bar0->prc_rxd0_n[i]);
 
 		val64 = readq(&bar0->prc_ctrl_n[i]);
@@ -2328,9 +2336,9 @@ static int start_nic(struct s2io_nic *nic)
 	 */
 	val64 = readq(&bar0->adapter_status);
 	if (!verify_xena_quiescence(nic)) {
-		DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name);
-		DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n",
-			  (unsigned long long) val64);
+		DBG_PRINT(ERR_DBG, "%s: device is not ready, "
+			  "Adapter status reads: 0x%llx\n",
+			  dev->name, (unsigned long long)val64);
 		return FAILURE;
 	}
 
@@ -2370,8 +2378,8 @@ static int start_nic(struct s2io_nic *nic)
 /**
  * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb
  */
-static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \
-					TxD *txdlp, int get_off)
+static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data,
+					struct TxD *txdlp, int get_off)
 {
 	struct s2io_nic *nic = fifo_data->nic;
 	struct sk_buff *skb;
@@ -2380,22 +2388,18 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \
 
 	txds = txdlp;
 	if (txds->Host_Control == (u64)(long)fifo_data->ufo_in_band_v) {
-		pci_unmap_single(nic->pdev, (dma_addr_t)
-			txds->Buffer_Pointer, sizeof(u64),
-			PCI_DMA_TODEVICE);
+		pci_unmap_single(nic->pdev, (dma_addr_t)txds->Buffer_Pointer,
+				 sizeof(u64), PCI_DMA_TODEVICE);
 		txds++;
 	}
 
-	skb = (struct sk_buff *) ((unsigned long)
-			txds->Host_Control);
+	skb = (struct sk_buff *)((unsigned long)txds->Host_Control);
 	if (!skb) {
 		memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds));
 		return NULL;
 	}
-	pci_unmap_single(nic->pdev, (dma_addr_t)
-			 txds->Buffer_Pointer,
-			 skb->len - skb->data_len,
-			 PCI_DMA_TODEVICE);
+	pci_unmap_single(nic->pdev, (dma_addr_t)txds->Buffer_Pointer,
+			 skb->len - skb->data_len, PCI_DMA_TODEVICE);
 	frg_cnt = skb_shinfo(skb)->nr_frags;
 	if (frg_cnt) {
 		txds++;
@@ -2403,13 +2407,13 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[j];
 			if (!txds->Buffer_Pointer)
 				break;
-			pci_unmap_page(nic->pdev, (dma_addr_t)
-					txds->Buffer_Pointer,
+			pci_unmap_page(nic->pdev,
+				       (dma_addr_t)txds->Buffer_Pointer,
 				       frag->size, PCI_DMA_TODEVICE);
 		}
 	}
-	memset(txdlp,0, (sizeof(struct TxD) * fifo_data->max_txds));
-	return(skb);
+	memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds));
+	return skb;
 }
 
 /**
@@ -2418,7 +2422,7 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \
  *  Description:
  *  Free all queued Tx buffers.
  *  Return Value: void
-*/
+ */
 
 static void free_tx_buffers(struct s2io_nic *nic)
 {
@@ -2426,33 +2430,33 @@ static void free_tx_buffers(struct s2io_nic *nic)
 	struct sk_buff *skb;
 	struct TxD *txdp;
 	int i, j;
-	struct mac_info *mac_control;
-	struct config_param *config;
 	int cnt = 0;
-
-	mac_control = &nic->mac_control;
-	config = &nic->config;
+	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
+	struct stat_block *stats = mac_control->stats_info;
+	struct swStat *swstats = &stats->sw_stat;
 
 	for (i = 0; i < config->tx_fifo_num; i++) {
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+		struct fifo_info *fifo = &mac_control->fifos[i];
 		unsigned long flags;
-		spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags);
-		for (j = 0; j < config->tx_cfg[i].fifo_len; j++) {
-			txdp = (struct TxD *) \
-			mac_control->fifos[i].list_info[j].list_virt_addr;
+
+		spin_lock_irqsave(&fifo->tx_lock, flags);
+		for (j = 0; j < tx_cfg->fifo_len; j++) {
+			txdp = (struct TxD *)fifo->list_info[j].list_virt_addr;
 			skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
 			if (skb) {
-				nic->mac_control.stats_info->sw_stat.mem_freed
-					+= skb->truesize;
+				swstats->mem_freed += skb->truesize;
 				dev_kfree_skb(skb);
 				cnt++;
 			}
 		}
 		DBG_PRINT(INTR_DBG,
-			  "%s:forcibly freeing %d skbs on FIFO%d\n",
+			  "%s: forcibly freeing %d skbs on FIFO%d\n",
 			  dev->name, cnt, i);
-		mac_control->fifos[i].tx_curr_get_info.offset = 0;
-		mac_control->fifos[i].tx_curr_put_info.offset = 0;
-		spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock, flags);
+		fifo->tx_curr_get_info.offset = 0;
+		fifo->tx_curr_put_info.offset = 0;
+		spin_unlock_irqrestore(&fifo->tx_lock, flags);
 	}
 }
 
@@ -2471,11 +2475,6 @@ static void stop_nic(struct s2io_nic *nic)
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0;
 	u16 interruptible;
-	struct mac_info *mac_control;
-	struct config_param *config;
-
-	mac_control = &nic->mac_control;
-	config = &nic->config;
 
 	/*  Disable all interrupts */
 	en_dis_err_alarms(nic, ENA_ALL_INTRS, DISABLE_INTRS);
@@ -2512,7 +2511,7 @@ static void stop_nic(struct s2io_nic *nic)
  *  SUCCESS on success or an appropriate -ve value on failure.
  */
 static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
-				int from_card_up)
+			   int from_card_up)
 {
 	struct sk_buff *skb;
 	struct RxD_t *rxdp;
@@ -2526,7 +2525,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 	int rxd_index = 0;
 	struct RxD1 *rxdp1;
 	struct RxD3 *rxdp3;
-	struct swStat *stats = &ring->nic->mac_control.stats_info->sw_stat;
+	struct swStat *swstats = &ring->nic->mac_control.stats_info->sw_stat;
 
 	alloc_cnt = ring->pkt_cnt - ring->rx_bufs_left;
 
@@ -2543,17 +2542,16 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 			rxd_index += (block_no * ring->rxd_count);
 
 		if ((block_no == block_no1) &&
-			(off == ring->rx_curr_get_info.offset) &&
-			(rxdp->Host_Control)) {
-			DBG_PRINT(INTR_DBG, "%s: Get and Put",
-				ring->dev->name);
-			DBG_PRINT(INTR_DBG, " info equated\n");
+		    (off == ring->rx_curr_get_info.offset) &&
+		    (rxdp->Host_Control)) {
+			DBG_PRINT(INTR_DBG, "%s: Get and Put info equated\n",
+				  ring->dev->name);
 			goto end;
 		}
 		if (off && (off == ring->rxd_count)) {
 			ring->rx_curr_put_info.block_index++;
 			if (ring->rx_curr_put_info.block_index ==
-							ring->block_count)
+			    ring->block_count)
 				ring->rx_curr_put_info.block_index = 0;
 			block_no = ring->rx_curr_put_info.block_index;
 			off = 0;
@@ -2565,14 +2563,15 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 		}
 
 		if ((rxdp->Control_1 & RXD_OWN_XENA) &&
-			((ring->rxd_mode == RXD_MODE_3B) &&
-				(rxdp->Control_2 & s2BIT(0)))) {
+		    ((ring->rxd_mode == RXD_MODE_3B) &&
+		     (rxdp->Control_2 & s2BIT(0)))) {
 			ring->rx_curr_put_info.offset = off;
 			goto end;
 		}
 		/* calculate size of skb based on ring mode */
-		size = ring->mtu + HEADER_ETHERNET_II_802_3_SIZE +
-				HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
+		size = ring->mtu +
+			HEADER_ETHERNET_II_802_3_SIZE +
+			HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
 		if (ring->rxd_mode == RXD_MODE_1)
 			size += NET_IP_ALIGN;
 		else
@@ -2580,34 +2579,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 
 		/* allocate skb */
 		skb = dev_alloc_skb(size);
-		if(!skb) {
-			DBG_PRINT(INFO_DBG, "%s: Out of ", ring->dev->name);
-			DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
+		if (!skb) {
+			DBG_PRINT(INFO_DBG, "%s: Could not allocate skb\n",
+				  ring->dev->name);
 			if (first_rxdp) {
 				wmb();
 				first_rxdp->Control_1 |= RXD_OWN_XENA;
 			}
-			stats->mem_alloc_fail_cnt++;
+			swstats->mem_alloc_fail_cnt++;
 
 			return -ENOMEM ;
 		}
-		stats->mem_allocated += skb->truesize;
+		swstats->mem_allocated += skb->truesize;
 
 		if (ring->rxd_mode == RXD_MODE_1) {
 			/* 1 buffer mode - normal operation mode */
-			rxdp1 = (struct RxD1*)rxdp;
+			rxdp1 = (struct RxD1 *)rxdp;
 			memset(rxdp, 0, sizeof(struct RxD1));
 			skb_reserve(skb, NET_IP_ALIGN);
-			rxdp1->Buffer0_ptr = pci_map_single
-			    (ring->pdev, skb->data, size - NET_IP_ALIGN,
-				PCI_DMA_FROMDEVICE);
+			rxdp1->Buffer0_ptr =
+				pci_map_single(ring->pdev, skb->data,
+					       size - NET_IP_ALIGN,
+					       PCI_DMA_FROMDEVICE);
 			if (pci_dma_mapping_error(nic->pdev,
-						rxdp1->Buffer0_ptr))
+						  rxdp1->Buffer0_ptr))
 				goto pci_map_failed;
 
 			rxdp->Control_2 =
 				SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
-			rxdp->Host_Control = (unsigned long) (skb);
+			rxdp->Host_Control = (unsigned long)skb;
 		} else if (ring->rxd_mode == RXD_MODE_3B) {
 			/*
 			 * 2 buffer mode -
@@ -2615,7 +2615,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 			 * byte aligned receive buffers.
 			 */
 
-			rxdp3 = (struct RxD3*)rxdp;
+			rxdp3 = (struct RxD3 *)rxdp;
 			/* save buffer pointers to avoid frequent dma mapping */
 			Buffer0_ptr = rxdp3->Buffer0_ptr;
 			Buffer1_ptr = rxdp3->Buffer1_ptr;
@@ -2626,7 +2626,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 
 			ba = &ring->ba[block_no][off];
 			skb_reserve(skb, BUF0_LEN);
-			tmp = (u64)(unsigned long) skb->data;
+			tmp = (u64)(unsigned long)skb->data;
 			tmp += ALIGN_SIZE;
 			tmp &= ~ALIGN_SIZE;
 			skb->data = (void *) (unsigned long)tmp;
@@ -2634,15 +2634,17 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 
 			if (from_card_up) {
 				rxdp3->Buffer0_ptr =
-				   pci_map_single(ring->pdev, ba->ba_0,
-					BUF0_LEN, PCI_DMA_FROMDEVICE);
-			if (pci_dma_mapping_error(nic->pdev,
-						rxdp3->Buffer0_ptr))
+					pci_map_single(ring->pdev, ba->ba_0,
+						       BUF0_LEN,
+						       PCI_DMA_FROMDEVICE);
+				if (pci_dma_mapping_error(nic->pdev,
+							  rxdp3->Buffer0_ptr))
 					goto pci_map_failed;
 			} else
 				pci_dma_sync_single_for_device(ring->pdev,
-				(dma_addr_t) rxdp3->Buffer0_ptr,
-				    BUF0_LEN, PCI_DMA_FROMDEVICE);
+							       (dma_addr_t)rxdp3->Buffer0_ptr,
+							       BUF0_LEN,
+							       PCI_DMA_FROMDEVICE);
 
 			rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
 			if (ring->rxd_mode == RXD_MODE_3B) {
@@ -2652,34 +2654,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 				 * Buffer2 will have L3/L4 header plus
 				 * L4 payload
 				 */
-				rxdp3->Buffer2_ptr = pci_map_single
-				(ring->pdev, skb->data, ring->mtu + 4,
-						PCI_DMA_FROMDEVICE);
+				rxdp3->Buffer2_ptr = pci_map_single(ring->pdev,
+								    skb->data,
+								    ring->mtu + 4,
+								    PCI_DMA_FROMDEVICE);
 
 				if (pci_dma_mapping_error(nic->pdev,
-							rxdp3->Buffer2_ptr))
+							  rxdp3->Buffer2_ptr))
 					goto pci_map_failed;
 
 				if (from_card_up) {
 					rxdp3->Buffer1_ptr =
 						pci_map_single(ring->pdev,
-						ba->ba_1, BUF1_LEN,
-						PCI_DMA_FROMDEVICE);
+							       ba->ba_1,
+							       BUF1_LEN,
+							       PCI_DMA_FROMDEVICE);
 
 					if (pci_dma_mapping_error(nic->pdev,
-						rxdp3->Buffer1_ptr)) {
-						pci_unmap_single
-							(ring->pdev,
-						    (dma_addr_t)(unsigned long)
-							skb->data,
-							ring->mtu + 4,
-							PCI_DMA_FROMDEVICE);
+								  rxdp3->Buffer1_ptr)) {
+						pci_unmap_single(ring->pdev,
+								 (dma_addr_t)(unsigned long)
+								 skb->data,
+								 ring->mtu + 4,
+								 PCI_DMA_FROMDEVICE);
 						goto pci_map_failed;
 					}
 				}
 				rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
 				rxdp->Control_2 |= SET_BUFFER2_SIZE_3
-								(ring->mtu + 4);
+					(ring->mtu + 4);
 			}
 			rxdp->Control_2 |= s2BIT(0);
 			rxdp->Host_Control = (unsigned long) (skb);
@@ -2703,7 +2706,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 		alloc_tab++;
 	}
 
-      end:
+end:
 	/* Transfer ownership of first descriptor to adapter just before
 	 * exiting. Before that, use memory barrier so that ownership
 	 * and other fields are seen by adapter correctly.
@@ -2714,9 +2717,10 @@ static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
 	}
 
 	return SUCCESS;
+
 pci_map_failed:
-	stats->pci_map_fail_cnt++;
-	stats->mem_freed += skb->truesize;
+	swstats->pci_map_fail_cnt++;
+	swstats->mem_freed += skb->truesize;
 	dev_kfree_skb_irq(skb);
 	return -ENOMEM;
 }
@@ -2727,49 +2731,46 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
 	int j;
 	struct sk_buff *skb;
 	struct RxD_t *rxdp;
-	struct mac_info *mac_control;
 	struct buffAdd *ba;
 	struct RxD1 *rxdp1;
 	struct RxD3 *rxdp3;
+	struct mac_info *mac_control = &sp->mac_control;
+	struct stat_block *stats = mac_control->stats_info;
+	struct swStat *swstats = &stats->sw_stat;
 
-	mac_control = &sp->mac_control;
 	for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) {
 		rxdp = mac_control->rings[ring_no].
-                                rx_blocks[blk].rxds[j].virt_addr;
-		skb = (struct sk_buff *)
-			((unsigned long) rxdp->Host_Control);
-		if (!skb) {
+			rx_blocks[blk].rxds[j].virt_addr;
+		skb = (struct sk_buff *)((unsigned long)rxdp->Host_Control);
+		if (!skb)
 			continue;
-		}
 		if (sp->rxd_mode == RXD_MODE_1) {
-			rxdp1 = (struct RxD1*)rxdp;
-			pci_unmap_single(sp->pdev, (dma_addr_t)
-				rxdp1->Buffer0_ptr,
-				dev->mtu +
-				HEADER_ETHERNET_II_802_3_SIZE
-				+ HEADER_802_2_SIZE +
-				HEADER_SNAP_SIZE,
-				PCI_DMA_FROMDEVICE);
+			rxdp1 = (struct RxD1 *)rxdp;
+			pci_unmap_single(sp->pdev,
+					 (dma_addr_t)rxdp1->Buffer0_ptr,
+					 dev->mtu +
+					 HEADER_ETHERNET_II_802_3_SIZE +
+					 HEADER_802_2_SIZE + HEADER_SNAP_SIZE,
+					 PCI_DMA_FROMDEVICE);
 			memset(rxdp, 0, sizeof(struct RxD1));
-		} else if(sp->rxd_mode == RXD_MODE_3B) {
-			rxdp3 = (struct RxD3*)rxdp;
-			ba = &mac_control->rings[ring_no].
-				ba[blk][j];
-			pci_unmap_single(sp->pdev, (dma_addr_t)
-				rxdp3->Buffer0_ptr,
-				BUF0_LEN,
-				PCI_DMA_FROMDEVICE);
-			pci_unmap_single(sp->pdev, (dma_addr_t)
-				rxdp3->Buffer1_ptr,
-				BUF1_LEN,
-				PCI_DMA_FROMDEVICE);
-			pci_unmap_single(sp->pdev, (dma_addr_t)
-				rxdp3->Buffer2_ptr,
-				dev->mtu + 4,
-				PCI_DMA_FROMDEVICE);
+		} else if (sp->rxd_mode == RXD_MODE_3B) {
+			rxdp3 = (struct RxD3 *)rxdp;
+			ba = &mac_control->rings[ring_no].ba[blk][j];
+			pci_unmap_single(sp->pdev,
+					 (dma_addr_t)rxdp3->Buffer0_ptr,
+					 BUF0_LEN,
+					 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(sp->pdev,
+					 (dma_addr_t)rxdp3->Buffer1_ptr,
+					 BUF1_LEN,
+					 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(sp->pdev,
+					 (dma_addr_t)rxdp3->Buffer2_ptr,
+					 dev->mtu + 4,
+					 PCI_DMA_FROMDEVICE);
 			memset(rxdp, 0, sizeof(struct RxD3));
 		}
-		sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
+		swstats->mem_freed += skb->truesize;
 		dev_kfree_skb(skb);
 		mac_control->rings[ring_no].rx_bufs_left -= 1;
 	}
@@ -2788,22 +2789,21 @@ static void free_rx_buffers(struct s2io_nic *sp)
 {
 	struct net_device *dev = sp->dev;
 	int i, blk = 0, buf_cnt = 0;
-	struct mac_info *mac_control;
-	struct config_param *config;
-
-	mac_control = &sp->mac_control;
-	config = &sp->config;
+	struct config_param *config = &sp->config;
+	struct mac_info *mac_control = &sp->mac_control;
 
 	for (i = 0; i < config->rx_ring_num; i++) {
+		struct ring_info *ring = &mac_control->rings[i];
+
 		for (blk = 0; blk < rx_ring_sz[i]; blk++)
-			free_rxd_blk(sp,i,blk);
-
-		mac_control->rings[i].rx_curr_put_info.block_index = 0;
-		mac_control->rings[i].rx_curr_get_info.block_index = 0;
-		mac_control->rings[i].rx_curr_put_info.offset = 0;
-		mac_control->rings[i].rx_curr_get_info.offset = 0;
-		mac_control->rings[i].rx_bufs_left = 0;
-		DBG_PRINT(INIT_DBG, "%s:Freed 0x%x Rx Buffers on ring%d\n",
+			free_rxd_blk(sp, i, blk);
+
+		ring->rx_curr_put_info.block_index = 0;
+		ring->rx_curr_get_info.block_index = 0;
+		ring->rx_curr_put_info.offset = 0;
+		ring->rx_curr_get_info.offset = 0;
+		ring->rx_bufs_left = 0;
+		DBG_PRINT(INIT_DBG, "%s: Freed 0x%x Rx Buffers on ring%d\n",
 			  dev->name, buf_cnt, i);
 	}
 }
@@ -2811,8 +2811,8 @@ static void free_rx_buffers(struct s2io_nic *sp)
 static int s2io_chk_rx_buffers(struct s2io_nic *nic, struct ring_info *ring)
 {
 	if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) {
-		DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name);
-		DBG_PRINT(INFO_DBG, " in Rx Intr!!\n");
+		DBG_PRINT(INFO_DBG, "%s: Out of memory in Rx Intr!!\n",
+			  ring->dev->name);
 	}
 	return 0;
 }
@@ -2834,8 +2834,6 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
 {
 	struct ring_info *ring = container_of(napi, struct ring_info, napi);
 	struct net_device *dev = ring->dev;
-	struct config_param *config;
-	struct mac_info *mac_control;
 	int pkts_processed = 0;
 	u8 __iomem *addr = NULL;
 	u8 val8 = 0;
@@ -2843,9 +2841,6 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	int budget_org = budget;
 
-	config = &nic->config;
-	mac_control = &nic->mac_control;
-
 	if (unlikely(!is_s2io_card_up(nic)))
 		return 0;
 
@@ -2863,25 +2858,22 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget)
 	}
 	return pkts_processed;
 }
+
 static int s2io_poll_inta(struct napi_struct *napi, int budget)
 {
 	struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi);
-	struct ring_info *ring;
-	struct config_param *config;
-	struct mac_info *mac_control;
 	int pkts_processed = 0;
 	int ring_pkts_processed, i;
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	int budget_org = budget;
-
-	config = &nic->config;
-	mac_control = &nic->mac_control;
+	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
 
 	if (unlikely(!is_s2io_card_up(nic)))
 		return 0;
 
 	for (i = 0; i < config->rx_ring_num; i++) {
-		ring = &mac_control->rings[i];
+		struct ring_info *ring = &mac_control->rings[i];
 		ring_pkts_processed = rx_intr_handler(ring, budget);
 		s2io_chk_rx_buffers(nic, ring);
 		pkts_processed += ring_pkts_processed;
@@ -2911,20 +2903,17 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget)
 static void s2io_netpoll(struct net_device *dev)
 {
 	struct s2io_nic *nic = netdev_priv(dev);
-	struct mac_info *mac_control;
-	struct config_param *config;
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
 	int i;
+	struct config_param *config = &nic->config;
+	struct mac_info *mac_control = &nic->mac_control;
 
 	if (pci_channel_offline(nic->pdev))
 		return;
 
 	disable_irq(dev->irq);
 
-	mac_control = &nic->mac_control;
-	config = &nic->config;
-
 	writeq(val64, &bar0->rx_traffic_int);
 	writeq(val64, &bar0->tx_traffic_int);
 
@@ -2936,14 +2925,19 @@ static void s2io_netpoll(struct net_device *dev)
 		tx_intr_handler(&mac_control->fifos[i]);
 
 	/* check for received packet and indicate up to network */
-	for (i = 0; i < config->rx_ring_num; i++)
-		rx_intr_handler(&mac_control->rings[i], 0);
+	for (i = 0; i < config->rx_ring_num; i++) {
+		struct ring_info *ring = &mac_control->rings[i];
+
+		rx_intr_handler(ring, 0);
+	}
 
 	for (i = 0; i < config->rx_ring_num; i++) {
-		if (fill_rx_buffers(nic, &mac_control->rings[i], 0) ==
-				-ENOMEM) {
-			DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
-			DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n");
+		struct ring_info *ring = &mac_control->rings[i];
+
+		if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) {
+			DBG_PRINT(INFO_DBG,
+				  "%s: Out of memory in Rx Netpoll!!\n",
+				  dev->name);
 			break;
 		}
 	}
@@ -2973,8 +2967,8 @@ static int rx_intr_handler(struct ring_info *ring_data, int budget)
 	struct sk_buff *skb;
 	int pkt_cnt = 0, napi_pkts = 0;
 	int i;
-	struct RxD1* rxdp1;
-	struct RxD3* rxdp3;
+	struct RxD1 *rxdp1;
+	struct RxD3 *rxdp3;
 
 	get_info = ring_data->rx_curr_get_info;
 	get_block = get_info.block_index;
@@ -2990,41 +2984,41 @@ static int rx_intr_handler(struct ring_info *ring_data, int budget)
 		if ((get_block == put_block) &&
 		    (get_info.offset + 1) == put_info.offset) {
 			DBG_PRINT(INTR_DBG, "%s: Ring Full\n",
-				ring_data->dev->name);
+				  ring_data->dev->name);
 			break;
 		}
-		skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control);
+		skb = (struct sk_buff *)((unsigned long)rxdp->Host_Control);
 		if (skb == NULL) {
-			DBG_PRINT(ERR_DBG, "%s: The skb is ",
+			DBG_PRINT(ERR_DBG, "%s: NULL skb in Rx Intr\n",
 				  ring_data->dev->name);
-			DBG_PRINT(ERR_DBG, "Null in Rx Intr\n");
 			return 0;
 		}
 		if (ring_data->rxd_mode == RXD_MODE_1) {
-			rxdp1 = (struct RxD1*)rxdp;
+			rxdp1 = (struct RxD1 *)rxdp;
 			pci_unmap_single(ring_data->pdev, (dma_addr_t)
-				rxdp1->Buffer0_ptr,
-				ring_data->mtu +
-				HEADER_ETHERNET_II_802_3_SIZE +
-				HEADER_802_2_SIZE +
-				HEADER_SNAP_SIZE,
-				PCI_DMA_FROMDEVICE);
+					 rxdp1->Buffer0_ptr,
+					 ring_data->mtu +
+					 HEADER_ETHERNET_II_802_3_SIZE +
+					 HEADER_802_2_SIZE +
+					 HEADER_SNAP_SIZE,
+					 PCI_DMA_FROMDEVICE);
 		} else if (ring_data->rxd_mode == RXD_MODE_3B) {
-			rxdp3 = (struct RxD3*)rxdp;
-			pci_dma_sync_single_for_cpu(ring_data->pdev, (dma_addr_t)
-				rxdp3->Buffer0_ptr,
-				BUF0_LEN, PCI_DMA_FROMDEVICE);
-			pci_unmap_single(ring_data->pdev, (dma_addr_t)
-				rxdp3->Buffer2_ptr,
-				ring_data->mtu + 4,
-				PCI_DMA_FROMDEVICE);
+			rxdp3 = (struct RxD3 *)rxdp;
+			pci_dma_sync_single_for_cpu(ring_data->pdev,
+						    (dma_addr_t)rxdp3->Buffer0_ptr,
+						    BUF0_LEN,
+						    PCI_DMA_FROMDEVICE);
+			pci_unmap_single(ring_data->pdev,
+					 (dma_addr_t)rxdp3->Buffer2_ptr,
+					 ring_data->mtu + 4,
+					 PCI_DMA_FROMDEVICE);
 		}
 		prefetch(skb->data);
 		rx_osm_handler(ring_data, rxdp);
 		get_info.offset++;
 		ring_data->rx_curr_get_info.offset = get_info.offset;
 		rxdp = ring_data->rx_blocks[get_block].
-				rxds[get_info.offset].virt_addr;
+			rxds[get_info.offset].virt_addr;
 		if (get_info.offset == rxd_count[ring_data->rxd_mode]) {
 			get_info.offset = 0;
 			ring_data->rx_curr_get_info.offset = get_info.offset;
@@ -3047,7 +3041,7 @@ static int rx_intr_handler(struct ring_info *ring_data, int budget)
 	}
 	if (ring_data->lro) {
 		/* Clear all LRO sessions before exiting */
-		for (i=0; i<MAX_LRO_SESSIONS; i++) {
+		for (i = 0; i < MAX_LRO_SESSIONS; i++) {
 			struct lro *lro = &ring_data->lro0_n[i];
 			if (lro->in_use) {
 				update_L3L4_header(ring_data->nic, lro);
@@ -3056,7 +3050,7 @@ static int rx_intr_handler(struct ring_info *ring_data, int budget)
 			}
 		}
 	}
-	return(napi_pkts);
+	return napi_pkts;
 }
 
 /**
@@ -3080,14 +3074,16 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 	int pkt_cnt = 0;
 	unsigned long flags = 0;
 	u8 err_mask;
+	struct stat_block *stats = nic->mac_control.stats_info;
+	struct swStat *swstats = &stats->sw_stat;
 
 	if (!spin_trylock_irqsave(&fifo_data->tx_lock, flags))
-			return;
+		return;
 
 	get_info = fifo_data->tx_curr_get_info;
 	memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info));
-	txdlp = (struct TxD *) fifo_data->list_info[get_info.offset].
-	    list_virt_addr;
+	txdlp = (struct TxD *)
+		fifo_data->list_info[get_info.offset].list_virt_addr;
 	while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) &&
 	       (get_info.offset != put_info.offset) &&
 	       (txdlp->Host_Control)) {
@@ -3096,62 +3092,54 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 			unsigned long long err;
 			err = txdlp->Control_1 & TXD_T_CODE;
 			if (err & 0x1) {
-				nic->mac_control.stats_info->sw_stat.
-						parity_err_cnt++;
+				swstats->parity_err_cnt++;
 			}
 
 			/* update t_code statistics */
 			err_mask = err >> 48;
-			switch(err_mask) {
-				case 2:
-					nic->mac_control.stats_info->sw_stat.
-							tx_buf_abort_cnt++;
+			switch (err_mask) {
+			case 2:
+				swstats->tx_buf_abort_cnt++;
 				break;
 
-				case 3:
-					nic->mac_control.stats_info->sw_stat.
-							tx_desc_abort_cnt++;
+			case 3:
+				swstats->tx_desc_abort_cnt++;
 				break;
 
-				case 7:
-					nic->mac_control.stats_info->sw_stat.
-							tx_parity_err_cnt++;
+			case 7:
+				swstats->tx_parity_err_cnt++;
 				break;
 
-				case 10:
-					nic->mac_control.stats_info->sw_stat.
-							tx_link_loss_cnt++;
+			case 10:
+				swstats->tx_link_loss_cnt++;
 				break;
 
-				case 15:
-					nic->mac_control.stats_info->sw_stat.
-							tx_list_proc_err_cnt++;
+			case 15:
+				swstats->tx_list_proc_err_cnt++;
 				break;
-                        }
+			}
 		}
 
 		skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
 		if (skb == NULL) {
 			spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
-			DBG_PRINT(ERR_DBG, "%s: Null skb ",
-			__func__);
-			DBG_PRINT(ERR_DBG, "in Tx Free Intr\n");
+			DBG_PRINT(ERR_DBG, "%s: NULL skb in Tx Free Intr\n",
+				  __func__);
 			return;
 		}
 		pkt_cnt++;
 
 		/* Updating the statistics block */
 		nic->dev->stats.tx_bytes += skb->len;
-		nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
+		swstats->mem_freed += skb->truesize;
 		dev_kfree_skb_irq(skb);
 
 		get_info.offset++;
 		if (get_info.offset == get_info.fifo_len + 1)
 			get_info.offset = 0;
-		txdlp = (struct TxD *) fifo_data->list_info
-		    [get_info.offset].list_virt_addr;
-		fifo_data->tx_curr_get_info.offset =
-		    get_info.offset;
+		txdlp = (struct TxD *)
+			fifo_data->list_info[get_info.offset].list_virt_addr;
+		fifo_data->tx_curr_get_info.offset = get_info.offset;
 	}
 
 	s2io_wake_tx_queue(fifo_data, pkt_cnt, nic->config.multiq);
@@ -3169,43 +3157,41 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
  *  This function is used to write values to the MDIO registers
  *  NONE
  */
-static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device *dev)
+static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value,
+			    struct net_device *dev)
 {
-	u64 val64 = 0x0;
+	u64 val64;
 	struct s2io_nic *sp = netdev_priv(dev);
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
-	//address transaction
-	val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
-			| MDIO_MMD_DEV_ADDR(mmd_type)
-			| MDIO_MMS_PRT_ADDR(0x0);
+	/* address transaction */
+	val64 = MDIO_MMD_INDX_ADDR(addr) |
+		MDIO_MMD_DEV_ADDR(mmd_type) |
+		MDIO_MMS_PRT_ADDR(0x0);
 	writeq(val64, &bar0->mdio_control);
 	val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
 	writeq(val64, &bar0->mdio_control);
 	udelay(100);
 
-	//Data transaction
-	val64 = 0x0;
-	val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
-			| MDIO_MMD_DEV_ADDR(mmd_type)
-			| MDIO_MMS_PRT_ADDR(0x0)
-			| MDIO_MDIO_DATA(value)
-			| MDIO_OP(MDIO_OP_WRITE_TRANS);
+	/* Data transaction */
+	val64 = MDIO_MMD_INDX_ADDR(addr) |
+		MDIO_MMD_DEV_ADDR(mmd_type) |
+		MDIO_MMS_PRT_ADDR(0x0) |
+		MDIO_MDIO_DATA(value) |
+		MDIO_OP(MDIO_OP_WRITE_TRANS);
 	writeq(val64, &bar0->mdio_control);
 	val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
 	writeq(val64, &bar0->mdio_control);
 	udelay(100);
 
-	val64 = 0x0;
-	val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
-	| MDIO_MMD_DEV_ADDR(mmd_type)
-	| MDIO_MMS_PRT_ADDR(0x0)
-	| MDIO_OP(MDIO_OP_READ_TRANS);
+	val64 = MDIO_MMD_INDX_ADDR(addr) |
+		MDIO_MMD_DEV_ADDR(mmd_type) |
+		MDIO_MMS_PRT_ADDR(0x0) |
+		MDIO_OP(MDIO_OP_READ_TRANS);
 	writeq(val64, &bar0->mdio_control);
 	val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
 	writeq(val64, &bar0->mdio_control);
 	udelay(100);
-
 }
 
 /**
@@ -3225,20 +3211,19 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev)
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
 	/* address transaction */
-	val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
-			| MDIO_MMD_DEV_ADDR(mmd_type)
-			| MDIO_MMS_PRT_ADDR(0x0);
+	val64 = val64 | (MDIO_MMD_INDX_ADDR(addr)
+			 | MDIO_MMD_DEV_ADDR(mmd_type)
+			 | MDIO_MMS_PRT_ADDR(0x0));
 	writeq(val64, &bar0->mdio_control);
 	val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
 	writeq(val64, &bar0->mdio_control);
 	udelay(100);
 
 	/* Data transaction */
-	val64 = 0x0;
-	val64 = val64 | MDIO_MMD_INDX_ADDR(addr)
-			| MDIO_MMD_DEV_ADDR(mmd_type)
-			| MDIO_MMS_PRT_ADDR(0x0)
-			| MDIO_OP(MDIO_OP_READ_TRANS);
+	val64 = MDIO_MMD_INDX_ADDR(addr) |
+		MDIO_MMD_DEV_ADDR(mmd_type) |
+		MDIO_MMS_PRT_ADDR(0x0) |
+		MDIO_OP(MDIO_OP_READ_TRANS);
 	writeq(val64, &bar0->mdio_control);
 	val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
 	writeq(val64, &bar0->mdio_control);
@@ -3250,6 +3235,7 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev)
 	rval64 = rval64 >> 16;
 	return rval64;
 }
+
 /**
  *  s2io_chk_xpak_counter - Function to check the status of the xpak counters
  *  @counter      : couter value to be updated
@@ -3260,45 +3246,43 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev)
  *  NONE
  */
 
-static void s2io_chk_xpak_counter(u64 *counter, u64 * regs_stat, u32 index, u16 flag, u16 type)
+static void s2io_chk_xpak_counter(u64 *counter, u64 * regs_stat, u32 index,
+				  u16 flag, u16 type)
 {
 	u64 mask = 0x3;
 	u64 val64;
 	int i;
-	for(i = 0; i <index; i++)
+	for (i = 0; i < index; i++)
 		mask = mask << 0x2;
 
-	if(flag > 0)
-	{
+	if (flag > 0) {
 		*counter = *counter + 1;
 		val64 = *regs_stat & mask;
 		val64 = val64 >> (index * 0x2);
 		val64 = val64 + 1;
-		if(val64 == 3)
-		{
-			switch(type)
-			{
+		if (val64 == 3) {
+			switch (type) {
 			case 1:
-				DBG_PRINT(ERR_DBG, "Take Xframe NIC out of "
-					  "service. Excessive temperatures may "
-					  "result in premature transceiver "
-					  "failure \n");
-			break;
+				DBG_PRINT(ERR_DBG,
+					  "Take Xframe NIC out of service.\n");
+				DBG_PRINT(ERR_DBG,
+"Excessive temperatures may result in premature transceiver failure.\n");
+				break;
 			case 2:
-				DBG_PRINT(ERR_DBG, "Take Xframe NIC out of "
-					  "service Excessive bias currents may "
-					  "indicate imminent laser diode "
-					  "failure \n");
-			break;
+				DBG_PRINT(ERR_DBG,
+					  "Take Xframe NIC out of service.\n");
+				DBG_PRINT(ERR_DBG,
+"Excessive bias currents may indicate imminent laser diode failure.\n");
+				break;
 			case 3:
-				DBG_PRINT(ERR_DBG, "Take Xframe NIC out of "
-					  "service Excessive laser output "
-					  "power may saturate far-end "
-					  "receiver\n");
-			break;
+				DBG_PRINT(ERR_DBG,
+					  "Take Xframe NIC out of service.\n");
+				DBG_PRINT(ERR_DBG,
+"Excessive laser output power may saturate far-end receiver.\n");
+				break;
 			default:
-				DBG_PRINT(ERR_DBG, "Incorrect XPAK Alarm "
-					  "type \n");
+				DBG_PRINT(ERR_DBG,
+					  "Incorrect XPAK Alarm type\n");
 			}
 			val64 = 0x0;
 		}
@@ -3326,24 +3310,24 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
 	u64 addr  = 0x0;
 
 	struct s2io_nic *sp = netdev_priv(dev);
-	struct stat_block *stat_info = sp->mac_control.stats_info;
+	struct stat_block *stats = sp->mac_control.stats_info;
+	struct xpakStat *xstats = &stats->xpak_stat;
 
 	/* Check the communication with the MDIO slave */
 	addr = MDIO_CTRL1;
 	val64 = 0x0;
 	val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
-	if((val64 == 0xFFFF) || (val64 == 0x0000))
-	{
-		DBG_PRINT(ERR_DBG, "ERR: MDIO slave access failed - "
-			  "Returned %llx\n", (unsigned long long)val64);
+	if ((val64 == 0xFFFF) || (val64 == 0x0000)) {
+		DBG_PRINT(ERR_DBG,
+			  "ERR: MDIO slave access failed - Returned %llx\n",
+			  (unsigned long long)val64);
 		return;
 	}
 
 	/* Check for the expected value of control reg 1 */
-	if(val64 != MDIO_CTRL1_SPEED10G)
-	{
-		DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - ");
-		DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x%x\n",
+	if (val64 != MDIO_CTRL1_SPEED10G) {
+		DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - "
+			  "Returned: %llx- Expected: 0x%x\n",
 			  (unsigned long long)val64, MDIO_CTRL1_SPEED10G);
 		return;
 	}
@@ -3360,53 +3344,53 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
 
 	flag = CHECKBIT(val64, 0x7);
 	type = 1;
-	s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_transceiver_temp_high,
-				&stat_info->xpak_stat.xpak_regs_stat,
-				0x0, flag, type);
+	s2io_chk_xpak_counter(&xstats->alarm_transceiver_temp_high,
+			      &xstats->xpak_regs_stat,
+			      0x0, flag, type);
 
-	if(CHECKBIT(val64, 0x6))
-		stat_info->xpak_stat.alarm_transceiver_temp_low++;
+	if (CHECKBIT(val64, 0x6))
+		xstats->alarm_transceiver_temp_low++;
 
 	flag = CHECKBIT(val64, 0x3);
 	type = 2;
-	s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_laser_bias_current_high,
-				&stat_info->xpak_stat.xpak_regs_stat,
-				0x2, flag, type);
+	s2io_chk_xpak_counter(&xstats->alarm_laser_bias_current_high,
+			      &xstats->xpak_regs_stat,
+			      0x2, flag, type);
 
-	if(CHECKBIT(val64, 0x2))
-		stat_info->xpak_stat.alarm_laser_bias_current_low++;
+	if (CHECKBIT(val64, 0x2))
+		xstats->alarm_laser_bias_current_low++;
 
 	flag = CHECKBIT(val64, 0x1);
 	type = 3;
-	s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_laser_output_power_high,
-				&stat_info->xpak_stat.xpak_regs_stat,
-				0x4, flag, type);
+	s2io_chk_xpak_counter(&xstats->alarm_laser_output_power_high,
+			      &xstats->xpak_regs_stat,
+			      0x4, flag, type);
 
-	if(CHECKBIT(val64, 0x0))
-		stat_info->xpak_stat.alarm_laser_output_power_low++;
+	if (CHECKBIT(val64, 0x0))
+		xstats->alarm_laser_output_power_low++;
 
 	/* Reading the Warning flags */
 	addr = 0xA074;
 	val64 = 0x0;
 	val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
 
-	if(CHECKBIT(val64, 0x7))
-		stat_info->xpak_stat.warn_transceiver_temp_high++;
+	if (CHECKBIT(val64, 0x7))
+		xstats->warn_transceiver_temp_high++;
 
-	if(CHECKBIT(val64, 0x6))
-		stat_info->xpak_stat.warn_transceiver_temp_low++;
+	if (CHECKBIT(val64, 0x6))
+		xstats->warn_transceiver_temp_low++;
 
-	if(CHECKBIT(val64, 0x3))
-		stat_info->xpak_stat.warn_laser_bias_current_high++;
+	if (CHECKBIT(val64, 0x3))
+		xstats->warn_laser_bias_current_high++;
 
-	if(CHECKBIT(val64, 0x2))
-		stat_info->xpak_stat.warn_laser_bias_current_low++;
+	if (CHECKBIT(val64, 0x2))
+		xstats->warn_laser_bias_current_low++;
 
-	if(CHECKBIT(val64, 0x1))
-		stat_info->xpak_stat.warn_laser_output_power_high++;
+	if (CHECKBIT(val64, 0x1))
+		xstats->warn_laser_output_power_high++;
 
-	if(CHECKBIT(val64, 0x0))
-		stat_info->xpak_stat.warn_laser_output_power_low++;
+	if (CHECKBIT(val64, 0x0))
+		xstats->warn_laser_output_power_low++;
 }
 
 /**
@@ -3421,7 +3405,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
  */
 
 static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
-				int bit_state)
+				 int bit_state)
 {
 	int ret = FAILURE, cnt = 0, delay = 1;
 	u64 val64;
@@ -3443,7 +3427,7 @@ static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
 			}
 		}
 
-		if(in_interrupt())
+		if (in_interrupt())
 			mdelay(delay);
 		else
 			msleep(delay);
@@ -3483,7 +3467,7 @@ static u16 check_pci_device_id(u16 id)
  *  void.
  */
 
-static void s2io_reset(struct s2io_nic * sp)
+static void s2io_reset(struct s2io_nic *sp)
 {
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	u64 val64;
@@ -3492,18 +3476,19 @@ static void s2io_reset(struct s2io_nic * sp)
 	u16 val16;
 	unsigned long long up_cnt, down_cnt, up_time, down_time, reset_cnt;
 	unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
+	struct stat_block *stats;
+	struct swStat *swstats;
 
-	DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
-			__func__, sp->dev->name);
+	DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n",
+		  __func__, sp->dev->name);
 
 	/* Back up  the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
 	pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
 
 	val64 = SW_RESET_ALL;
 	writeq(val64, &bar0->sw_reset);
-	if (strstr(sp->product_name, "CX4")) {
+	if (strstr(sp->product_name, "CX4"))
 		msleep(750);
-	}
 	msleep(250);
 	for (i = 0; i < S2IO_MAX_PCI_CONFIG_SPACE_REINIT; i++) {
 
@@ -3515,9 +3500,8 @@ static void s2io_reset(struct s2io_nic * sp)
 		msleep(200);
 	}
 
-	if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) {
-		DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __func__);
-	}
+	if (check_pci_device_id(val16) == (u16)PCI_ANY_ID)
+		DBG_PRINT(ERR_DBG, "%s SW_Reset failed!\n", __func__);
 
 	pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd);
 
@@ -3545,27 +3529,32 @@ static void s2io_reset(struct s2io_nic * sp)
 	}
 
 	/* Reset device statistics maintained by OS */
-	memset(&sp->stats, 0, sizeof (struct net_device_stats));
-
-	up_cnt = sp->mac_control.stats_info->sw_stat.link_up_cnt;
-	down_cnt = sp->mac_control.stats_info->sw_stat.link_down_cnt;
-	up_time = sp->mac_control.stats_info->sw_stat.link_up_time;
-	down_time = sp->mac_control.stats_info->sw_stat.link_down_time;
-	reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt;
-	mem_alloc_cnt = sp->mac_control.stats_info->sw_stat.mem_allocated;
-	mem_free_cnt = sp->mac_control.stats_info->sw_stat.mem_freed;
-	watchdog_cnt = sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt;
+	memset(&sp->stats, 0, sizeof(struct net_device_stats));
+
+	stats = sp->mac_control.stats_info;
+	swstats = &stats->sw_stat;
+
 	/* save link up/down time/cnt, reset/memory/watchdog cnt */
-	memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
+	up_cnt = swstats->link_up_cnt;
+	down_cnt = swstats->link_down_cnt;
+	up_time = swstats->link_up_time;
+	down_time = swstats->link_down_time;
+	reset_cnt = swstats->soft_reset_cnt;
+	mem_alloc_cnt = swstats->mem_allocated;
+	mem_free_cnt = swstats->mem_freed;
+	watchdog_cnt = swstats->watchdog_timer_cnt;
+
+	memset(stats, 0, sizeof(struct stat_block));
+
 	/* restore link up/down time/cnt, reset/memory/watchdog cnt */
-	sp->mac_control.stats_info->sw_stat.link_up_cnt = up_cnt;
-	sp->mac_control.stats_info->sw_stat.link_down_cnt = down_cnt;
-	sp->mac_control.stats_info->sw_stat.link_up_time = up_time;
-	sp->mac_control.stats_info->sw_stat.link_down_time = down_time;
-	sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt;
-	sp->mac_control.stats_info->sw_stat.mem_allocated = mem_alloc_cnt;
-	sp->mac_control.stats_info->sw_stat.mem_freed = mem_free_cnt;
-	sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt = watchdog_cnt;
+	swstats->link_up_cnt = up_cnt;
+	swstats->link_down_cnt = down_cnt;
+	swstats->link_up_time = up_time;
+	swstats->link_down_time = down_time;
+	swstats->soft_reset_cnt = reset_cnt;
+	swstats->mem_allocated = mem_alloc_cnt;
+	swstats->mem_freed = mem_free_cnt;
+	swstats->watchdog_timer_cnt = watchdog_cnt;
 
 	/* SXE-002: Configure link and activity LED to turn it off */
 	subid = sp->pdev->subsystem_device;
@@ -3600,7 +3589,7 @@ static void s2io_reset(struct s2io_nic * sp)
  *  SUCCESS on success and FAILURE on failure.
  */
 
-static int s2io_set_swapper(struct s2io_nic * sp)
+static int s2io_set_swapper(struct s2io_nic *sp)
 {
 	struct net_device *dev = sp->dev;
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
@@ -3619,7 +3608,7 @@ static int s2io_set_swapper(struct s2io_nic * sp)
 				0x4200004242000042ULL,  /* FE=0, SE=1 */
 				0};                     /* FE=0, SE=0 */
 
-		while(i<4) {
+		while (i < 4) {
 			writeq(value[i], &bar0->swapper_ctrl);
 			val64 = readq(&bar0->pif_rd_swapper_fb);
 			if (val64 == 0x0123456789ABCDEFULL)
@@ -3627,10 +3616,9 @@ static int s2io_set_swapper(struct s2io_nic * sp)
 			i++;
 		}
 		if (i == 4) {
-			DBG_PRINT(ERR_DBG, "%s: Endian settings are wrong, ",
-				dev->name);
-			DBG_PRINT(ERR_DBG, "feedback read %llx\n",
-				(unsigned long long) val64);
+			DBG_PRINT(ERR_DBG, "%s: Endian settings are wrong, "
+				  "feedback read %llx\n",
+				  dev->name, (unsigned long long)val64);
 			return FAILURE;
 		}
 		valr = value[i];
@@ -3642,46 +3630,47 @@ static int s2io_set_swapper(struct s2io_nic * sp)
 	writeq(valt, &bar0->xmsi_address);
 	val64 = readq(&bar0->xmsi_address);
 
-	if(val64 != valt) {
+	if (val64 != valt) {
 		int i = 0;
 		u64 value[] = { 0x00C3C30000C3C300ULL,  /* FE=1, SE=1 */
 				0x0081810000818100ULL,  /* FE=1, SE=0 */
 				0x0042420000424200ULL,  /* FE=0, SE=1 */
 				0};                     /* FE=0, SE=0 */
 
-		while(i<4) {
+		while (i < 4) {
 			writeq((value[i] | valr), &bar0->swapper_ctrl);
 			writeq(valt, &bar0->xmsi_address);
 			val64 = readq(&bar0->xmsi_address);
-			if(val64 == valt)
+			if (val64 == valt)
 				break;
 			i++;
 		}
-		if(i == 4) {
+		if (i == 4) {
 			unsigned long long x = val64;
-			DBG_PRINT(ERR_DBG, "Write failed, Xmsi_addr ");
-			DBG_PRINT(ERR_DBG, "reads:0x%llx\n", x);
+			DBG_PRINT(ERR_DBG,
+				  "Write failed, Xmsi_addr reads:0x%llx\n", x);
 			return FAILURE;
 		}
 	}
 	val64 = readq(&bar0->swapper_ctrl);
 	val64 &= 0xFFFF000000000000ULL;
 
-#ifdef  __BIG_ENDIAN
+#ifdef __BIG_ENDIAN
 	/*
 	 * The device by default set to a big endian format, so a
 	 * big endian driver need not set anything.
 	 */
 	val64 |= (SWAPPER_CTRL_TXP_FE |
-		 SWAPPER_CTRL_TXP_SE |
-		 SWAPPER_CTRL_TXD_R_FE |
-		 SWAPPER_CTRL_TXD_W_FE |
-		 SWAPPER_CTRL_TXF_R_FE |
-		 SWAPPER_CTRL_RXD_R_FE |
-		 SWAPPER_CTRL_RXD_W_FE |
-		 SWAPPER_CTRL_RXF_W_FE |
-		 SWAPPER_CTRL_XMSI_FE |
-		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+		  SWAPPER_CTRL_TXP_SE |
+		  SWAPPER_CTRL_TXD_R_FE |
+		  SWAPPER_CTRL_TXD_W_FE |
+		  SWAPPER_CTRL_TXF_R_FE |
+		  SWAPPER_CTRL_RXD_R_FE |
+		  SWAPPER_CTRL_RXD_W_FE |
+		  SWAPPER_CTRL_RXF_W_FE |
+		  SWAPPER_CTRL_XMSI_FE |
+		  SWAPPER_CTRL_STATS_FE |
+		  SWAPPER_CTRL_STATS_SE);
 	if (sp->config.intr_type == INTA)
 		val64 |= SWAPPER_CTRL_XMSI_SE;
 	writeq(val64, &bar0->swapper_ctrl);
@@ -3692,19 +3681,20 @@ static int s2io_set_swapper(struct s2io_nic * sp)
 	 * we want to set.
 	 */
 	val64 |= (SWAPPER_CTRL_TXP_FE |
-		 SWAPPER_CTRL_TXP_SE |
-		 SWAPPER_CTRL_TXD_R_FE |
-		 SWAPPER_CTRL_TXD_R_SE |
-		 SWAPPER_CTRL_TXD_W_FE |
-		 SWAPPER_CTRL_TXD_W_SE |
-		 SWAPPER_CTRL_TXF_R_FE |
-		 SWAPPER_CTRL_RXD_R_FE |
-		 SWAPPER_CTRL_RXD_R_SE |
-		 SWAPPER_CTRL_RXD_W_FE |
-		 SWAPPER_CTRL_RXD_W_SE |
-		 SWAPPER_CTRL_RXF_W_FE |
-		 SWAPPER_CTRL_XMSI_FE |
-		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+		  SWAPPER_CTRL_TXP_SE |
+		  SWAPPER_CTRL_TXD_R_FE |
+		  SWAPPER_CTRL_TXD_R_SE |
+		  SWAPPER_CTRL_TXD_W_FE |
+		  SWAPPER_CTRL_TXD_W_SE |
+		  SWAPPER_CTRL_TXF_R_FE |
+		  SWAPPER_CTRL_RXD_R_FE |
+		  SWAPPER_CTRL_RXD_R_SE |
+		  SWAPPER_CTRL_RXD_W_FE |
+		  SWAPPER_CTRL_RXD_W_SE |
+		  SWAPPER_CTRL_RXF_W_FE |
+		  SWAPPER_CTRL_XMSI_FE |
+		  SWAPPER_CTRL_STATS_FE |
+		  SWAPPER_CTRL_STATS_SE);
 	if (sp->config.intr_type == INTA)
 		val64 |= SWAPPER_CTRL_XMSI_SE;
 	writeq(val64, &bar0->swapper_ctrl);
@@ -3718,10 +3708,9 @@ static int s2io_set_swapper(struct s2io_nic * sp)
 	val64 = readq(&bar0->pif_rd_swapper_fb);
 	if (val64 != 0x0123456789ABCDEFULL) {
 		/* Endian settings are incorrect, calls for another dekko. */
-		DBG_PRINT(ERR_DBG, "%s: Endian settings are wrong, ",
-			  dev->name);
-		DBG_PRINT(ERR_DBG, "feedback read %llx\n",
-			  (unsigned long long) val64);
+		DBG_PRINT(ERR_DBG,
+			  "%s: Endian settings are wrong, feedback read %llx\n",
+			  dev->name, (unsigned long long)val64);
 		return FAILURE;
 	}
 
@@ -3740,7 +3729,7 @@ static int wait_for_msix_trans(struct s2io_nic *nic, int i)
 			break;
 		mdelay(1);
 		cnt++;
-	} while(cnt < 5);
+	} while (cnt < 5);
 	if (cnt == 5) {
 		DBG_PRINT(ERR_DBG, "XMSI # %d Access failed\n", i);
 		ret = 1;
@@ -3755,18 +3744,18 @@ static void restore_xmsi_data(struct s2io_nic *nic)
 	u64 val64;
 	int i, msix_index;
 
-
 	if (nic->device_type == XFRAME_I_DEVICE)
 		return;
 
-	for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
-		msix_index = (i) ? ((i-1) * 8 + 1): 0;
+	for (i = 0; i < MAX_REQUESTED_MSI_X; i++) {
+		msix_index = (i) ? ((i-1) * 8 + 1) : 0;
 		writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
 		writeq(nic->msix_info[i].data, &bar0->xmsi_data);
 		val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6));
 		writeq(val64, &bar0->xmsi_access);
 		if (wait_for_msix_trans(nic, msix_index)) {
-			DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
+			DBG_PRINT(ERR_DBG, "%s: index: %d failed\n",
+				  __func__, msix_index);
 			continue;
 		}
 	}
@@ -3782,12 +3771,13 @@ static void store_xmsi_data(struct s2io_nic *nic)
 		return;
 
 	/* Store and display */
-	for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
-		msix_index = (i) ? ((i-1) * 8 + 1): 0;
+	for (i = 0; i < MAX_REQUESTED_MSI_X; i++) {
+		msix_index = (i) ? ((i-1) * 8 + 1) : 0;
 		val64 = (s2BIT(15) | vBIT(msix_index, 26, 6));
 		writeq(val64, &bar0->xmsi_access);
 		if (wait_for_msix_trans(nic, msix_index)) {
-			DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
+			DBG_PRINT(ERR_DBG, "%s: index: %d failed\n",
+				  __func__, msix_index);
 			continue;
 		}
 		addr = readq(&bar0->xmsi_address);
@@ -3805,36 +3795,32 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
 	u64 rx_mat;
 	u16 msi_control; /* Temp variable */
 	int ret, i, j, msix_indx = 1;
+	int size;
+	struct stat_block *stats = nic->mac_control.stats_info;
+	struct swStat *swstats = &stats->sw_stat;
 
-	nic->entries = kmalloc(nic->num_entries * sizeof(struct msix_entry),
-			       GFP_KERNEL);
+	size = nic->num_entries * sizeof(struct msix_entry);
+	nic->entries = kzalloc(size, GFP_KERNEL);
 	if (!nic->entries) {
-		DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
-			__func__);
-		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
+		DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
+			  __func__);
+		swstats->mem_alloc_fail_cnt++;
 		return -ENOMEM;
 	}
-	nic->mac_control.stats_info->sw_stat.mem_allocated
-		+= (nic->num_entries * sizeof(struct msix_entry));
+	swstats->mem_allocated += size;
 
-	memset(nic->entries, 0, nic->num_entries * sizeof(struct msix_entry));
-
-	nic->s2io_entries =
-		kmalloc(nic->num_entries * sizeof(struct s2io_msix_entry),
-				   GFP_KERNEL);
+	size = nic->num_entries * sizeof(struct s2io_msix_entry);
+	nic->s2io_entries = kzalloc(size, GFP_KERNEL);
 	if (!nic->s2io_entries) {
 		DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
-			__func__);
-		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
+			  __func__);
+		swstats->mem_alloc_fail_cnt++;
 		kfree(nic->entries);
-		nic->mac_control.stats_info->sw_stat.mem_freed
+		swstats->mem_freed
 			+= (nic->num_entries * sizeof(struct msix_entry));
 		return -ENOMEM;
 	}
-	 nic->mac_control.stats_info->sw_stat.mem_allocated
-		+= (nic->num_entries * sizeof(struct s2io_msix_entry));
-	memset(nic->s2io_entries, 0,
-		nic->num_entries * sizeof(struct s2io_msix_entry));
+	swstats->mem_allocated += size;
 
 	nic->entries[0].entry = 0;
 	nic->s2io_entries[0].entry = 0;
@@ -3863,13 +3849,13 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
 	ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries);
 	/* We fail init if error or we get less vectors than min required */
 	if (ret) {
-		DBG_PRINT(ERR_DBG, "s2io: Enabling MSI-X failed\n");
+		DBG_PRINT(ERR_DBG, "Enabling MSI-X failed\n");
 		kfree(nic->entries);
-		nic->mac_control.stats_info->sw_stat.mem_freed
-			+= (nic->num_entries * sizeof(struct msix_entry));
+		swstats->mem_freed += nic->num_entries *
+			sizeof(struct msix_entry);
 		kfree(nic->s2io_entries);
-		nic->mac_control.stats_info->sw_stat.mem_freed
-			+= (nic->num_entries * sizeof(struct s2io_msix_entry));
+		swstats->mem_freed += nic->num_entries *
+			sizeof(struct s2io_msix_entry);
 		nic->entries = NULL;
 		nic->s2io_entries = NULL;
 		return -ENOMEM;
@@ -3906,14 +3892,14 @@ static int s2io_test_msi(struct s2io_nic *sp)
 	u64 val64, saved64;
 
 	err = request_irq(sp->entries[1].vector, s2io_test_intr, 0,
-			sp->name, sp);
+			  sp->name, sp);
 	if (err) {
 		DBG_PRINT(ERR_DBG, "%s: PCI %s: cannot assign irq %d\n",
-		       sp->dev->name, pci_name(pdev), pdev->irq);
+			  sp->dev->name, pci_name(pdev), pdev->irq);
 		return err;
 	}
 
-	init_waitqueue_head (&sp->msi_wait);
+	init_waitqueue_head(&sp->msi_wait);
 	sp->msi_detected = 0;
 
 	saved64 = val64 = readq(&bar0->scheduled_int_ctrl);
@@ -3927,8 +3913,8 @@ static int s2io_test_msi(struct s2io_nic *sp)
 	if (!sp->msi_detected) {
 		/* MSI(X) test failed, go back to INTx mode */
 		DBG_PRINT(ERR_DBG, "%s: PCI %s: No interrupt was generated "
-			"using MSI(X) during test\n", sp->dev->name,
-			pci_name(pdev));
+			  "using MSI(X) during test\n",
+			  sp->dev->name, pci_name(pdev));
 
 		err = -EOPNOTSUPP;
 	}
@@ -3946,8 +3932,7 @@ static void remove_msix_isr(struct s2io_nic *sp)
 	u16 msi_control;
 
 	for (i = 0; i < sp->num_entries; i++) {
-		if (sp->s2io_entries[i].in_use ==
-			MSIX_REGISTERED_SUCCESS) {
+		if (sp->s2io_entries[i].in_use == MSIX_REGISTERED_SUCCESS) {
 			int vector = sp->entries[i].vector;
 			void *arg = sp->s2io_entries[i].arg;
 			free_irq(vector, arg);
@@ -3992,6 +3977,7 @@ static void remove_inta_isr(struct s2io_nic *sp)
 static int s2io_open(struct net_device *dev)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
+	struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
 	int err = 0;
 
 	/*
@@ -4022,13 +4008,13 @@ hw_init_failed:
 	if (sp->config.intr_type == MSI_X) {
 		if (sp->entries) {
 			kfree(sp->entries);
-			sp->mac_control.stats_info->sw_stat.mem_freed
-			+= (sp->num_entries * sizeof(struct msix_entry));
+			swstats->mem_freed += sp->num_entries *
+				sizeof(struct msix_entry);
 		}
 		if (sp->s2io_entries) {
 			kfree(sp->s2io_entries);
-			sp->mac_control.stats_info->sw_stat.mem_freed
-			+= (sp->num_entries * sizeof(struct s2io_msix_entry));
+			swstats->mem_freed += sp->num_entries *
+				sizeof(struct s2io_msix_entry);
 		}
 	}
 	return err;
@@ -4055,8 +4041,8 @@ static int s2io_close(struct net_device *dev)
 	int offset;
 
 	/* Return if the device is already closed               *
-	*  Can happen when s2io_card_up failed in change_mtu    *
-	*/
+	 *  Can happen when s2io_card_up failed in change_mtu    *
+	 */
 	if (!is_s2io_card_up(sp))
 		return 0;
 
@@ -4086,7 +4072,7 @@ static int s2io_close(struct net_device *dev)
  *  0 on success & 1 on failure.
  */
 
-static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
 	u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -4096,29 +4082,27 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 	unsigned long flags = 0;
 	u16 vlan_tag = 0;
 	struct fifo_info *fifo = NULL;
-	struct mac_info *mac_control;
-	struct config_param *config;
 	int do_spin_lock = 1;
 	int offload_type;
 	int enable_per_list_interrupt = 0;
-	struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
-
-	mac_control = &sp->mac_control;
-	config = &sp->config;
+	struct config_param *config = &sp->config;
+	struct mac_info *mac_control = &sp->mac_control;
+	struct stat_block *stats = mac_control->stats_info;
+	struct swStat *swstats = &stats->sw_stat;
 
 	DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name);
 
 	if (unlikely(skb->len <= 0)) {
-		DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
+		DBG_PRINT(TX_DBG, "%s: Buffer has no data..\n", dev->name);
 		dev_kfree_skb_any(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (!is_s2io_card_up(sp)) {
 		DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
 			  dev->name);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	queue = 0;
@@ -4132,20 +4116,20 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 
 			if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) {
 				th = (struct tcphdr *)(((unsigned char *)ip) +
-						ip->ihl*4);
+						       ip->ihl*4);
 
 				if (ip->protocol == IPPROTO_TCP) {
 					queue_len = sp->total_tcp_fifos;
 					queue = (ntohs(th->source) +
-							ntohs(th->dest)) &
-					    sp->fifo_selector[queue_len - 1];
+						 ntohs(th->dest)) &
+						sp->fifo_selector[queue_len - 1];
 					if (queue >= queue_len)
 						queue = queue_len - 1;
 				} else if (ip->protocol == IPPROTO_UDP) {
 					queue_len = sp->total_udp_fifos;
 					queue = (ntohs(th->source) +
-							ntohs(th->dest)) &
-					    sp->fifo_selector[queue_len - 1];
+						 ntohs(th->dest)) &
+						sp->fifo_selector[queue_len - 1];
 					if (queue >= queue_len)
 						queue = queue_len - 1;
 					queue += sp->udp_fifo_idx;
@@ -4158,7 +4142,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 	} else if (sp->config.tx_steering_type == TX_PRIORITY_STEERING)
 		/* get fifo number based on skb->priority value */
 		queue = config->fifo_mapping
-					[skb->priority & (MAX_TX_FIFOS - 1)];
+			[skb->priority & (MAX_TX_FIFOS - 1)];
 	fifo = &mac_control->fifos[queue];
 
 	if (do_spin_lock)
@@ -4180,19 +4164,19 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
-	put_off = (u16) fifo->tx_curr_put_info.offset;
-	get_off = (u16) fifo->tx_curr_get_info.offset;
-	txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr;
+	put_off = (u16)fifo->tx_curr_put_info.offset;
+	get_off = (u16)fifo->tx_curr_get_info.offset;
+	txdp = (struct TxD *)fifo->list_info[put_off].list_virt_addr;
 
 	queue_len = fifo->tx_curr_put_info.fifo_len + 1;
 	/* Avoid "put" pointer going beyond "get" pointer */
 	if (txdp->Host_Control ||
-		   ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
+	    ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
 		DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n");
 		s2io_stop_tx_queue(sp, fifo->fifo_no);
 		dev_kfree_skb(skb);
 		spin_unlock_irqrestore(&fifo->tx_lock, flags);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	offload_type = s2io_offload_type(skb);
@@ -4201,9 +4185,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 		txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb));
 	}
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		txdp->Control_2 |=
-		    (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN |
-		     TXD_TX_CKO_UDP_EN);
+		txdp->Control_2 |= (TXD_TX_CKO_IPV4_EN |
+				    TXD_TX_CKO_TCP_EN |
+				    TXD_TX_CKO_UDP_EN);
 	}
 	txdp->Control_1 |= TXD_GATHER_CODE_FIRST;
 	txdp->Control_1 |= TXD_LIST_OWN_XENA;
@@ -4228,26 +4212,27 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 #ifdef __BIG_ENDIAN
 		/* both variants do cpu_to_be64(be32_to_cpu(...)) */
 		fifo->ufo_in_band_v[put_off] =
-				(__force u64)skb_shinfo(skb)->ip6_frag_id;
+			(__force u64)skb_shinfo(skb)->ip6_frag_id;
 #else
 		fifo->ufo_in_band_v[put_off] =
-				(__force u64)skb_shinfo(skb)->ip6_frag_id << 32;
+			(__force u64)skb_shinfo(skb)->ip6_frag_id << 32;
 #endif
 		txdp->Host_Control = (unsigned long)fifo->ufo_in_band_v;
 		txdp->Buffer_Pointer = pci_map_single(sp->pdev,
-					fifo->ufo_in_band_v,
-					sizeof(u64), PCI_DMA_TODEVICE);
+						      fifo->ufo_in_band_v,
+						      sizeof(u64),
+						      PCI_DMA_TODEVICE);
 		if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer))
 			goto pci_map_failed;
 		txdp++;
 	}
 
-	txdp->Buffer_Pointer = pci_map_single
-	    (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
+	txdp->Buffer_Pointer = pci_map_single(sp->pdev, skb->data,
+					      frg_len, PCI_DMA_TODEVICE);
 	if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer))
 		goto pci_map_failed;
 
-	txdp->Host_Control = (unsigned long) skb;
+	txdp->Host_Control = (unsigned long)skb;
 	txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
 	if (offload_type == SKB_GSO_UDP)
 		txdp->Control_1 |= TXD_UFO_EN;
@@ -4260,9 +4245,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 		if (!frag->size)
 			continue;
 		txdp++;
-		txdp->Buffer_Pointer = (u64) pci_map_page
-		    (sp->pdev, frag->page, frag->page_offset,
-		     frag->size, PCI_DMA_TODEVICE);
+		txdp->Buffer_Pointer = (u64)pci_map_page(sp->pdev, frag->page,
+							 frag->page_offset,
+							 frag->size,
+							 PCI_DMA_TODEVICE);
 		txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size);
 		if (offload_type == SKB_GSO_UDP)
 			txdp->Control_1 |= TXD_UFO_EN;
@@ -4292,26 +4278,27 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* Avoid "put" pointer going beyond "get" pointer */
 	if (((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
-		sp->mac_control.stats_info->sw_stat.fifo_full_cnt++;
+		swstats->fifo_full_cnt++;
 		DBG_PRINT(TX_DBG,
 			  "No free TxDs for xmit, Put: 0x%x Get:0x%x\n",
 			  put_off, get_off);
 		s2io_stop_tx_queue(sp, fifo->fifo_no);
 	}
-	mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
+	swstats->mem_allocated += skb->truesize;
 	spin_unlock_irqrestore(&fifo->tx_lock, flags);
 
 	if (sp->config.intr_type == MSI_X)
 		tx_intr_handler(fifo);
 
-	return 0;
+	return NETDEV_TX_OK;
+
 pci_map_failed:
-	stats->pci_map_fail_cnt++;
+	swstats->pci_map_fail_cnt++;
 	s2io_stop_tx_queue(sp, fifo->fifo_no);
-	stats->mem_freed += skb->truesize;
+	swstats->mem_freed += skb->truesize;
 	dev_kfree_skb(skb);
 	spin_unlock_irqrestore(&fifo->tx_lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void
@@ -4402,17 +4389,16 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
 			 * This is unstable state so clear both up/down
 			 * interrupt and adapter to re-evaluate the link state.
 			 */
-			val64 |=  GPIO_INT_REG_LINK_DOWN;
+			val64 |= GPIO_INT_REG_LINK_DOWN;
 			val64 |= GPIO_INT_REG_LINK_UP;
 			writeq(val64, &bar0->gpio_int_reg);
 			val64 = readq(&bar0->gpio_int_mask);
 			val64 &= ~(GPIO_INT_MASK_LINK_UP |
 				   GPIO_INT_MASK_LINK_DOWN);
 			writeq(val64, &bar0->gpio_int_mask);
-		}
-		else if (val64 & GPIO_INT_REG_LINK_UP) {
+		} else if (val64 & GPIO_INT_REG_LINK_UP) {
 			val64 = readq(&bar0->adapter_status);
-				/* Enable Adapter */
+			/* Enable Adapter */
 			val64 = readq(&bar0->adapter_control);
 			val64 |= ADAPTER_CNTL_EN;
 			writeq(val64, &bar0->adapter_control);
@@ -4431,7 +4417,7 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
 			val64 |= GPIO_INT_MASK_LINK_UP;
 			writeq(val64, &bar0->gpio_int_mask);
 
-		}else if (val64 & GPIO_INT_REG_LINK_DOWN) {
+		} else if (val64 & GPIO_INT_REG_LINK_DOWN) {
 			val64 = readq(&bar0->adapter_status);
 			s2io_link(sp, LINK_DOWN);
 			/* Link is down so unmaks link up interrupt */
@@ -4442,7 +4428,7 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
 
 			/* turn off LED */
 			val64 = readq(&bar0->adapter_control);
-			val64 = val64 &(~ADAPTER_LED_ON);
+			val64 = val64 & (~ADAPTER_LED_ON);
 			writeq(val64, &bar0->adapter_control);
 		}
 	}
@@ -4459,12 +4445,12 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
  *  1 - if alarm bit set
  *  0 - if alarm bit is not set
  */
-static int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
-			  unsigned long long *cnt)
+static int do_s2io_chk_alarm_bit(u64 value, void __iomem *addr,
+				 unsigned long long *cnt)
 {
 	u64 val64;
 	val64 = readq(addr);
-	if ( val64 & value ) {
+	if (val64 & value) {
 		writeq(val64, addr);
 		(*cnt)++;
 		return 1;
@@ -4481,12 +4467,12 @@ static int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
  *  Return Value:
  *  NONE
  */
-static void s2io_handle_errors(void * dev_id)
+static void s2io_handle_errors(void *dev_id)
 {
-	struct net_device *dev = (struct net_device *) dev_id;
+	struct net_device *dev = (struct net_device *)dev_id;
 	struct s2io_nic *sp = netdev_priv(dev);
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
-	u64 temp64 = 0,val64=0;
+	u64 temp64 = 0, val64 = 0;
 	int i = 0;
 
 	struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat;
@@ -4499,10 +4485,10 @@ static void s2io_handle_errors(void * dev_id)
 		return;
 
 	memset(&sw_stat->ring_full_cnt, 0,
-		sizeof(sw_stat->ring_full_cnt));
+	       sizeof(sw_stat->ring_full_cnt));
 
 	/* Handling the XPAK counters update */
-	if(stats->xpak_timer_count < 72000) {
+	if (stats->xpak_timer_count < 72000) {
 		/* waiting for an hour */
 		stats->xpak_timer_count++;
 	} else {
@@ -4521,191 +4507,227 @@ static void s2io_handle_errors(void * dev_id)
 
 	/* In case of a serious error, the device will be Reset. */
 	if (do_s2io_chk_alarm_bit(SERR_SOURCE_ANY, &bar0->serr_source,
-				&sw_stat->serious_err_cnt))
+				  &sw_stat->serious_err_cnt))
 		goto reset;
 
 	/* Check for data parity error */
 	if (do_s2io_chk_alarm_bit(GPIO_INT_REG_DP_ERR_INT, &bar0->gpio_int_reg,
-				&sw_stat->parity_err_cnt))
+				  &sw_stat->parity_err_cnt))
 		goto reset;
 
 	/* Check for ring full counter */
 	if (sp->device_type == XFRAME_II_DEVICE) {
 		val64 = readq(&bar0->ring_bump_counter1);
-		for (i=0; i<4; i++) {
-			temp64 = ( val64 & vBIT(0xFFFF,(i*16),16));
+		for (i = 0; i < 4; i++) {
+			temp64 = (val64 & vBIT(0xFFFF, (i*16), 16));
 			temp64 >>= 64 - ((i+1)*16);
 			sw_stat->ring_full_cnt[i] += temp64;
 		}
 
 		val64 = readq(&bar0->ring_bump_counter2);
-		for (i=0; i<4; i++) {
-			temp64 = ( val64 & vBIT(0xFFFF,(i*16),16));
+		for (i = 0; i < 4; i++) {
+			temp64 = (val64 & vBIT(0xFFFF, (i*16), 16));
 			temp64 >>= 64 - ((i+1)*16);
-			 sw_stat->ring_full_cnt[i+4] += temp64;
+			sw_stat->ring_full_cnt[i+4] += temp64;
 		}
 	}
 
 	val64 = readq(&bar0->txdma_int_status);
 	/*check for pfc_err*/
 	if (val64 & TXDMA_PFC_INT) {
-		if (do_s2io_chk_alarm_bit(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM|
-				PFC_MISC_0_ERR | PFC_MISC_1_ERR|
-				PFC_PCIX_ERR, &bar0->pfc_err_reg,
-				&sw_stat->pfc_err_cnt))
+		if (do_s2io_chk_alarm_bit(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM |
+					  PFC_MISC_0_ERR | PFC_MISC_1_ERR |
+					  PFC_PCIX_ERR,
+					  &bar0->pfc_err_reg,
+					  &sw_stat->pfc_err_cnt))
 			goto reset;
-		do_s2io_chk_alarm_bit(PFC_ECC_SG_ERR, &bar0->pfc_err_reg,
-				&sw_stat->pfc_err_cnt);
+		do_s2io_chk_alarm_bit(PFC_ECC_SG_ERR,
+				      &bar0->pfc_err_reg,
+				      &sw_stat->pfc_err_cnt);
 	}
 
 	/*check for tda_err*/
 	if (val64 & TXDMA_TDA_INT) {
-		if(do_s2io_chk_alarm_bit(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM |
-				TDA_SM1_ERR_ALARM, &bar0->tda_err_reg,
-				&sw_stat->tda_err_cnt))
+		if (do_s2io_chk_alarm_bit(TDA_Fn_ECC_DB_ERR |
+					  TDA_SM0_ERR_ALARM |
+					  TDA_SM1_ERR_ALARM,
+					  &bar0->tda_err_reg,
+					  &sw_stat->tda_err_cnt))
 			goto reset;
 		do_s2io_chk_alarm_bit(TDA_Fn_ECC_SG_ERR | TDA_PCIX_ERR,
-				&bar0->tda_err_reg, &sw_stat->tda_err_cnt);
+				      &bar0->tda_err_reg,
+				      &sw_stat->tda_err_cnt);
 	}
 	/*check for pcc_err*/
 	if (val64 & TXDMA_PCC_INT) {
-		if (do_s2io_chk_alarm_bit(PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM
-				| PCC_N_SERR | PCC_6_COF_OV_ERR
-				| PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR
-				| PCC_7_LSO_OV_ERR | PCC_FB_ECC_DB_ERR
-				| PCC_TXB_ECC_DB_ERR, &bar0->pcc_err_reg,
-				&sw_stat->pcc_err_cnt))
+		if (do_s2io_chk_alarm_bit(PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM |
+					  PCC_N_SERR | PCC_6_COF_OV_ERR |
+					  PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR |
+					  PCC_7_LSO_OV_ERR | PCC_FB_ECC_DB_ERR |
+					  PCC_TXB_ECC_DB_ERR,
+					  &bar0->pcc_err_reg,
+					  &sw_stat->pcc_err_cnt))
 			goto reset;
 		do_s2io_chk_alarm_bit(PCC_FB_ECC_SG_ERR | PCC_TXB_ECC_SG_ERR,
-				&bar0->pcc_err_reg, &sw_stat->pcc_err_cnt);
+				      &bar0->pcc_err_reg,
+				      &sw_stat->pcc_err_cnt);
 	}
 
 	/*check for tti_err*/
 	if (val64 & TXDMA_TTI_INT) {
-		if (do_s2io_chk_alarm_bit(TTI_SM_ERR_ALARM, &bar0->tti_err_reg,
-				&sw_stat->tti_err_cnt))
+		if (do_s2io_chk_alarm_bit(TTI_SM_ERR_ALARM,
+					  &bar0->tti_err_reg,
+					  &sw_stat->tti_err_cnt))
 			goto reset;
 		do_s2io_chk_alarm_bit(TTI_ECC_SG_ERR | TTI_ECC_DB_ERR,
-				&bar0->tti_err_reg, &sw_stat->tti_err_cnt);
+				      &bar0->tti_err_reg,
+				      &sw_stat->tti_err_cnt);
 	}
 
 	/*check for lso_err*/
 	if (val64 & TXDMA_LSO_INT) {
-		if (do_s2io_chk_alarm_bit(LSO6_ABORT | LSO7_ABORT
-				| LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM,
-				&bar0->lso_err_reg, &sw_stat->lso_err_cnt))
+		if (do_s2io_chk_alarm_bit(LSO6_ABORT | LSO7_ABORT |
+					  LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM,
+					  &bar0->lso_err_reg,
+					  &sw_stat->lso_err_cnt))
 			goto reset;
 		do_s2io_chk_alarm_bit(LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
-				&bar0->lso_err_reg, &sw_stat->lso_err_cnt);
+				      &bar0->lso_err_reg,
+				      &sw_stat->lso_err_cnt);
 	}
 
 	/*check for tpa_err*/
 	if (val64 & TXDMA_TPA_INT) {
-		if (do_s2io_chk_alarm_bit(TPA_SM_ERR_ALARM, &bar0->tpa_err_reg,
-			&sw_stat->tpa_err_cnt))
+		if (do_s2io_chk_alarm_bit(TPA_SM_ERR_ALARM,
+					  &bar0->tpa_err_reg,
+					  &sw_stat->tpa_err_cnt))
 			goto reset;
-		do_s2io_chk_alarm_bit(TPA_TX_FRM_DROP, &bar0->tpa_err_reg,
-			&sw_stat->tpa_err_cnt);
+		do_s2io_chk_alarm_bit(TPA_TX_FRM_DROP,
+				      &bar0->tpa_err_reg,
+				      &sw_stat->tpa_err_cnt);
 	}
 
 	/*check for sm_err*/
 	if (val64 & TXDMA_SM_INT) {
-		if (do_s2io_chk_alarm_bit(SM_SM_ERR_ALARM, &bar0->sm_err_reg,
-			&sw_stat->sm_err_cnt))
+		if (do_s2io_chk_alarm_bit(SM_SM_ERR_ALARM,
+					  &bar0->sm_err_reg,
+					  &sw_stat->sm_err_cnt))
 			goto reset;
 	}
 
 	val64 = readq(&bar0->mac_int_status);
 	if (val64 & MAC_INT_STATUS_TMAC_INT) {
 		if (do_s2io_chk_alarm_bit(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR,
-				&bar0->mac_tmac_err_reg,
-				&sw_stat->mac_tmac_err_cnt))
+					  &bar0->mac_tmac_err_reg,
+					  &sw_stat->mac_tmac_err_cnt))
 			goto reset;
-		do_s2io_chk_alarm_bit(TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR
-				| TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
-				&bar0->mac_tmac_err_reg,
-				&sw_stat->mac_tmac_err_cnt);
+		do_s2io_chk_alarm_bit(TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR |
+				      TMAC_DESC_ECC_SG_ERR |
+				      TMAC_DESC_ECC_DB_ERR,
+				      &bar0->mac_tmac_err_reg,
+				      &sw_stat->mac_tmac_err_cnt);
 	}
 
 	val64 = readq(&bar0->xgxs_int_status);
 	if (val64 & XGXS_INT_STATUS_TXGXS) {
 		if (do_s2io_chk_alarm_bit(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR,
-				&bar0->xgxs_txgxs_err_reg,
-				&sw_stat->xgxs_txgxs_err_cnt))
+					  &bar0->xgxs_txgxs_err_reg,
+					  &sw_stat->xgxs_txgxs_err_cnt))
 			goto reset;
 		do_s2io_chk_alarm_bit(TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
-				&bar0->xgxs_txgxs_err_reg,
-				&sw_stat->xgxs_txgxs_err_cnt);
+				      &bar0->xgxs_txgxs_err_reg,
+				      &sw_stat->xgxs_txgxs_err_cnt);
 	}
 
 	val64 = readq(&bar0->rxdma_int_status);
 	if (val64 & RXDMA_INT_RC_INT_M) {
-		if (do_s2io_chk_alarm_bit(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR
-				| RC_PRCn_SM_ERR_ALARM |RC_FTC_SM_ERR_ALARM,
-				&bar0->rc_err_reg, &sw_stat->rc_err_cnt))
+		if (do_s2io_chk_alarm_bit(RC_PRCn_ECC_DB_ERR |
+					  RC_FTC_ECC_DB_ERR |
+					  RC_PRCn_SM_ERR_ALARM |
+					  RC_FTC_SM_ERR_ALARM,
+					  &bar0->rc_err_reg,
+					  &sw_stat->rc_err_cnt))
 			goto reset;
-		do_s2io_chk_alarm_bit(RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR
-				| RC_RDA_FAIL_WR_Rn, &bar0->rc_err_reg,
-				&sw_stat->rc_err_cnt);
-		if (do_s2io_chk_alarm_bit(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn
-				| PRC_PCI_AB_F_WR_Rn, &bar0->prc_pcix_err_reg,
-				&sw_stat->prc_pcix_err_cnt))
+		do_s2io_chk_alarm_bit(RC_PRCn_ECC_SG_ERR |
+				      RC_FTC_ECC_SG_ERR |
+				      RC_RDA_FAIL_WR_Rn, &bar0->rc_err_reg,
+				      &sw_stat->rc_err_cnt);
+		if (do_s2io_chk_alarm_bit(PRC_PCI_AB_RD_Rn |
+					  PRC_PCI_AB_WR_Rn |
+					  PRC_PCI_AB_F_WR_Rn,
+					  &bar0->prc_pcix_err_reg,
+					  &sw_stat->prc_pcix_err_cnt))
 			goto reset;
-		do_s2io_chk_alarm_bit(PRC_PCI_DP_RD_Rn | PRC_PCI_DP_WR_Rn
-				| PRC_PCI_DP_F_WR_Rn, &bar0->prc_pcix_err_reg,
-				&sw_stat->prc_pcix_err_cnt);
+		do_s2io_chk_alarm_bit(PRC_PCI_DP_RD_Rn |
+				      PRC_PCI_DP_WR_Rn |
+				      PRC_PCI_DP_F_WR_Rn,
+				      &bar0->prc_pcix_err_reg,
+				      &sw_stat->prc_pcix_err_cnt);
 	}
 
 	if (val64 & RXDMA_INT_RPA_INT_M) {
 		if (do_s2io_chk_alarm_bit(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR,
-				&bar0->rpa_err_reg, &sw_stat->rpa_err_cnt))
+					  &bar0->rpa_err_reg,
+					  &sw_stat->rpa_err_cnt))
 			goto reset;
 		do_s2io_chk_alarm_bit(RPA_ECC_SG_ERR | RPA_ECC_DB_ERR,
-				&bar0->rpa_err_reg, &sw_stat->rpa_err_cnt);
+				      &bar0->rpa_err_reg,
+				      &sw_stat->rpa_err_cnt);
 	}
 
 	if (val64 & RXDMA_INT_RDA_INT_M) {
-		if (do_s2io_chk_alarm_bit(RDA_RXDn_ECC_DB_ERR
-				| RDA_FRM_ECC_DB_N_AERR | RDA_SM1_ERR_ALARM
-				| RDA_SM0_ERR_ALARM | RDA_RXD_ECC_DB_SERR,
-				&bar0->rda_err_reg, &sw_stat->rda_err_cnt))
+		if (do_s2io_chk_alarm_bit(RDA_RXDn_ECC_DB_ERR |
+					  RDA_FRM_ECC_DB_N_AERR |
+					  RDA_SM1_ERR_ALARM |
+					  RDA_SM0_ERR_ALARM |
+					  RDA_RXD_ECC_DB_SERR,
+					  &bar0->rda_err_reg,
+					  &sw_stat->rda_err_cnt))
 			goto reset;
-		do_s2io_chk_alarm_bit(RDA_RXDn_ECC_SG_ERR | RDA_FRM_ECC_SG_ERR
-				| RDA_MISC_ERR | RDA_PCIX_ERR,
-				&bar0->rda_err_reg, &sw_stat->rda_err_cnt);
+		do_s2io_chk_alarm_bit(RDA_RXDn_ECC_SG_ERR |
+				      RDA_FRM_ECC_SG_ERR |
+				      RDA_MISC_ERR |
+				      RDA_PCIX_ERR,
+				      &bar0->rda_err_reg,
+				      &sw_stat->rda_err_cnt);
 	}
 
 	if (val64 & RXDMA_INT_RTI_INT_M) {
-		if (do_s2io_chk_alarm_bit(RTI_SM_ERR_ALARM, &bar0->rti_err_reg,
-				&sw_stat->rti_err_cnt))
+		if (do_s2io_chk_alarm_bit(RTI_SM_ERR_ALARM,
+					  &bar0->rti_err_reg,
+					  &sw_stat->rti_err_cnt))
 			goto reset;
 		do_s2io_chk_alarm_bit(RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
-				&bar0->rti_err_reg, &sw_stat->rti_err_cnt);
+				      &bar0->rti_err_reg,
+				      &sw_stat->rti_err_cnt);
 	}
 
 	val64 = readq(&bar0->mac_int_status);
 	if (val64 & MAC_INT_STATUS_RMAC_INT) {
 		if (do_s2io_chk_alarm_bit(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR,
-				&bar0->mac_rmac_err_reg,
-				&sw_stat->mac_rmac_err_cnt))
+					  &bar0->mac_rmac_err_reg,
+					  &sw_stat->mac_rmac_err_cnt))
 			goto reset;
-		do_s2io_chk_alarm_bit(RMAC_UNUSED_INT|RMAC_SINGLE_ECC_ERR|
-				RMAC_DOUBLE_ECC_ERR, &bar0->mac_rmac_err_reg,
-				&sw_stat->mac_rmac_err_cnt);
+		do_s2io_chk_alarm_bit(RMAC_UNUSED_INT |
+				      RMAC_SINGLE_ECC_ERR |
+				      RMAC_DOUBLE_ECC_ERR,
+				      &bar0->mac_rmac_err_reg,
+				      &sw_stat->mac_rmac_err_cnt);
 	}
 
 	val64 = readq(&bar0->xgxs_int_status);
 	if (val64 & XGXS_INT_STATUS_RXGXS) {
 		if (do_s2io_chk_alarm_bit(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR,
-				&bar0->xgxs_rxgxs_err_reg,
-				&sw_stat->xgxs_rxgxs_err_cnt))
+					  &bar0->xgxs_rxgxs_err_reg,
+					  &sw_stat->xgxs_rxgxs_err_cnt))
 			goto reset;
 	}
 
 	val64 = readq(&bar0->mc_int_status);
-	if(val64 & MC_INT_STATUS_MC_INT) {
-		if (do_s2io_chk_alarm_bit(MC_ERR_REG_SM_ERR, &bar0->mc_err_reg,
-				&sw_stat->mc_err_cnt))
+	if (val64 & MC_INT_STATUS_MC_INT) {
+		if (do_s2io_chk_alarm_bit(MC_ERR_REG_SM_ERR,
+					  &bar0->mc_err_reg,
+					  &sw_stat->mc_err_cnt))
 			goto reset;
 
 		/* Handling Ecc errors */
@@ -4718,10 +4740,10 @@ static void s2io_handle_errors(void * dev_id)
 					 * Reset XframeI only if critical error
 					 */
 					if (val64 &
-						(MC_ERR_REG_MIRI_ECC_DB_ERR_0 |
-						MC_ERR_REG_MIRI_ECC_DB_ERR_1))
-								goto reset;
-					}
+					    (MC_ERR_REG_MIRI_ECC_DB_ERR_0 |
+					     MC_ERR_REG_MIRI_ECC_DB_ERR_1))
+						goto reset;
+				}
 			} else
 				sw_stat->single_ecc_errs++;
 		}
@@ -4750,7 +4772,7 @@ reset:
  */
 static irqreturn_t s2io_isr(int irq, void *dev_id)
 {
-	struct net_device *dev = (struct net_device *) dev_id;
+	struct net_device *dev = (struct net_device *)dev_id;
 	struct s2io_nic *sp = netdev_priv(dev);
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	int i;
@@ -4765,8 +4787,8 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 	if (!is_s2io_card_up(sp))
 		return IRQ_NONE;
 
-	mac_control = &sp->mac_control;
 	config = &sp->config;
+	mac_control = &sp->mac_control;
 
 	/*
 	 * Identify the cause for interrupt and call the appropriate
@@ -4777,14 +4799,11 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 	 */
 	reason = readq(&bar0->general_int_status);
 
-	if (unlikely(reason == S2IO_MINUS_ONE) ) {
-		/* Nothing much can be done. Get out */
-		return IRQ_HANDLED;
-	}
+	if (unlikely(reason == S2IO_MINUS_ONE))
+		return IRQ_HANDLED;	/* Nothing much can be done. Get out */
 
-	if (reason & (GEN_INTR_RXTRAFFIC |
-		GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC))
-	{
+	if (reason &
+	    (GEN_INTR_RXTRAFFIC | GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC)) {
 		writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
 
 		if (config->napi) {
@@ -4803,8 +4822,11 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 			if (reason & GEN_INTR_RXTRAFFIC)
 				writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
 
-			for (i = 0; i < config->rx_ring_num; i++)
-				rx_intr_handler(&mac_control->rings[i], 0);
+			for (i = 0; i < config->rx_ring_num; i++) {
+				struct ring_info *ring = &mac_control->rings[i];
+
+				rx_intr_handler(ring, 0);
+			}
 		}
 
 		/*
@@ -4825,16 +4847,18 @@ static irqreturn_t s2io_isr(int irq, void *dev_id)
 		 * Reallocate the buffers from the interrupt handler itself.
 		 */
 		if (!config->napi) {
-			for (i = 0; i < config->rx_ring_num; i++)
-				s2io_chk_rx_buffers(sp, &mac_control->rings[i]);
+			for (i = 0; i < config->rx_ring_num; i++) {
+				struct ring_info *ring = &mac_control->rings[i];
+
+				s2io_chk_rx_buffers(sp, ring);
+			}
 		}
 		writeq(sp->general_int_mask, &bar0->general_int_mask);
 		readl(&bar0->general_int_status);
 
 		return IRQ_HANDLED;
 
-	}
-	else if (!reason) {
+	} else if (!reason) {
 		/* The interrupt was not raised by us */
 		return IRQ_NONE;
 	}
@@ -4864,7 +4888,7 @@ static void s2io_updt_stats(struct s2io_nic *sp)
 			cnt++;
 			if (cnt == 5)
 				break; /* Updt failed */
-		} while(1);
+		} while (1);
 	}
 }
 
@@ -4881,53 +4905,46 @@ static void s2io_updt_stats(struct s2io_nic *sp)
 static struct net_device_stats *s2io_get_stats(struct net_device *dev)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
-	struct mac_info *mac_control;
-	struct config_param *config;
+	struct config_param *config = &sp->config;
+	struct mac_info *mac_control = &sp->mac_control;
+	struct stat_block *stats = mac_control->stats_info;
 	int i;
 
-
-	mac_control = &sp->mac_control;
-	config = &sp->config;
-
 	/* Configure Stats for immediate updt */
 	s2io_updt_stats(sp);
 
 	/* Using sp->stats as a staging area, because reset (due to mtu
 	   change, for example) will clear some hardware counters */
-	dev->stats.tx_packets +=
-		le32_to_cpu(mac_control->stats_info->tmac_frms) - 
+	dev->stats.tx_packets += le32_to_cpu(stats->tmac_frms) -
 		sp->stats.tx_packets;
-	sp->stats.tx_packets =
-		le32_to_cpu(mac_control->stats_info->tmac_frms);
-	dev->stats.tx_errors +=
-		le32_to_cpu(mac_control->stats_info->tmac_any_err_frms) -
+	sp->stats.tx_packets = le32_to_cpu(stats->tmac_frms);
+
+	dev->stats.tx_errors += le32_to_cpu(stats->tmac_any_err_frms) -
 		sp->stats.tx_errors;
-	sp->stats.tx_errors =
-		le32_to_cpu(mac_control->stats_info->tmac_any_err_frms);
-	dev->stats.rx_errors +=
-		le64_to_cpu(mac_control->stats_info->rmac_drop_frms) -
+	sp->stats.tx_errors = le32_to_cpu(stats->tmac_any_err_frms);
+
+	dev->stats.rx_errors += le64_to_cpu(stats->rmac_drop_frms) -
 		sp->stats.rx_errors;
-	sp->stats.rx_errors =
-		le64_to_cpu(mac_control->stats_info->rmac_drop_frms);
-	dev->stats.multicast =
-		le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms) - 
+	sp->stats.rx_errors = le64_to_cpu(stats->rmac_drop_frms);
+
+	dev->stats.multicast = le32_to_cpu(stats->rmac_vld_mcst_frms) -
 		sp->stats.multicast;
-	sp->stats.multicast =
-		le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms);
-	dev->stats.rx_length_errors =
-		le64_to_cpu(mac_control->stats_info->rmac_long_frms) - 
+	sp->stats.multicast = le32_to_cpu(stats->rmac_vld_mcst_frms);
+
+	dev->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms) -
 		sp->stats.rx_length_errors;
-	sp->stats.rx_length_errors =
-		le64_to_cpu(mac_control->stats_info->rmac_long_frms);
+	sp->stats.rx_length_errors = le64_to_cpu(stats->rmac_long_frms);
 
 	/* collect per-ring rx_packets and rx_bytes */
 	dev->stats.rx_packets = dev->stats.rx_bytes = 0;
 	for (i = 0; i < config->rx_ring_num; i++) {
-		dev->stats.rx_packets += mac_control->rings[i].rx_packets;
-		dev->stats.rx_bytes += mac_control->rings[i].rx_bytes;
+		struct ring_info *ring = &mac_control->rings[i];
+
+		dev->stats.rx_packets += ring->rx_packets;
+		dev->stats.rx_bytes += ring->rx_bytes;
 	}
 
-	return (&dev->stats);
+	return &dev->stats;
 }
 
 /**
@@ -4950,7 +4967,7 @@ static void s2io_set_multicast(struct net_device *dev)
 	struct s2io_nic *sp = netdev_priv(dev);
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
-	    0xfeffffffffffULL;
+		0xfeffffffffffULL;
 	u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, mac_addr = 0;
 	void __iomem *add;
 	struct config_param *config = &sp->config;
@@ -4962,13 +4979,13 @@ static void s2io_set_multicast(struct net_device *dev)
 		writeq(RMAC_ADDR_DATA1_MEM_MASK(mask),
 		       &bar0->rmac_addr_data1_mem);
 		val64 = RMAC_ADDR_CMD_MEM_WE |
-		    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-		    RMAC_ADDR_CMD_MEM_OFFSET(config->max_mc_addr - 1);
+			RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+			RMAC_ADDR_CMD_MEM_OFFSET(config->max_mc_addr - 1);
 		writeq(val64, &bar0->rmac_addr_cmd_mem);
 		/* Wait till command completes */
 		wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-					RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-					S2IO_BIT_RESET);
+				      RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+				      S2IO_BIT_RESET);
 
 		sp->m_cast_flg = 1;
 		sp->all_multi_pos = config->max_mc_addr - 1;
@@ -4979,13 +4996,13 @@ static void s2io_set_multicast(struct net_device *dev)
 		writeq(RMAC_ADDR_DATA1_MEM_MASK(0x0),
 		       &bar0->rmac_addr_data1_mem);
 		val64 = RMAC_ADDR_CMD_MEM_WE |
-		    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-		    RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos);
+			RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+			RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos);
 		writeq(val64, &bar0->rmac_addr_cmd_mem);
 		/* Wait till command completes */
 		wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-					RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-					S2IO_BIT_RESET);
+				      RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+				      S2IO_BIT_RESET);
 
 		sp->m_cast_flg = 0;
 		sp->all_multi_pos = 0;
@@ -4998,7 +5015,7 @@ static void s2io_set_multicast(struct net_device *dev)
 		val64 |= MAC_CFG_RMAC_PROM_ENABLE;
 
 		writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
-		writel((u32) val64, add);
+		writel((u32)val64, add);
 		writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
 		writel((u32) (val64 >> 32), (add + 4));
 
@@ -5020,7 +5037,7 @@ static void s2io_set_multicast(struct net_device *dev)
 		val64 &= ~MAC_CFG_RMAC_PROM_ENABLE;
 
 		writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
-		writel((u32) val64, add);
+		writel((u32)val64, add);
 		writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
 		writel((u32) (val64 >> 32), (add + 4));
 
@@ -5033,18 +5050,17 @@ static void s2io_set_multicast(struct net_device *dev)
 
 		val64 = readq(&bar0->mac_cfg);
 		sp->promisc_flg = 0;
-		DBG_PRINT(INFO_DBG, "%s: left promiscuous mode\n",
-			  dev->name);
+		DBG_PRINT(INFO_DBG, "%s: left promiscuous mode\n", dev->name);
 	}
 
 	/*  Update individual M_CAST address list */
 	if ((!sp->m_cast_flg) && dev->mc_count) {
 		if (dev->mc_count >
 		    (config->max_mc_addr - config->max_mac_addr)) {
-			DBG_PRINT(ERR_DBG, "%s: No more Rx filters ",
+			DBG_PRINT(ERR_DBG,
+				  "%s: No more Rx filters can be added - "
+				  "please enable ALL_MULTI instead\n",
 				  dev->name);
-			DBG_PRINT(ERR_DBG, "can be added, please enable ");
-			DBG_PRINT(ERR_DBG, "ALL_MULTI instead\n");
 			return;
 		}
 
@@ -5056,20 +5072,20 @@ static void s2io_set_multicast(struct net_device *dev)
 			writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr),
 			       &bar0->rmac_addr_data0_mem);
 			writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL),
-				&bar0->rmac_addr_data1_mem);
+			       &bar0->rmac_addr_data1_mem);
 			val64 = RMAC_ADDR_CMD_MEM_WE |
-			    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-			    RMAC_ADDR_CMD_MEM_OFFSET
-			    (config->mc_start_offset + i);
+				RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+				RMAC_ADDR_CMD_MEM_OFFSET
+				(config->mc_start_offset + i);
 			writeq(val64, &bar0->rmac_addr_cmd_mem);
 
 			/* Wait for command completes */
 			if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-					RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-					S2IO_BIT_RESET)) {
-				DBG_PRINT(ERR_DBG, "%s: Adding ",
+						  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+						  S2IO_BIT_RESET)) {
+				DBG_PRINT(ERR_DBG,
+					  "%s: Adding Multicasts failed\n",
 					  dev->name);
-				DBG_PRINT(ERR_DBG, "Multicasts failed\n");
 				return;
 			}
 		}
@@ -5088,20 +5104,20 @@ static void s2io_set_multicast(struct net_device *dev)
 			writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr),
 			       &bar0->rmac_addr_data0_mem);
 			writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL),
-				&bar0->rmac_addr_data1_mem);
+			       &bar0->rmac_addr_data1_mem);
 			val64 = RMAC_ADDR_CMD_MEM_WE |
-			    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-			    RMAC_ADDR_CMD_MEM_OFFSET
-			    (i + config->mc_start_offset);
+				RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+				RMAC_ADDR_CMD_MEM_OFFSET
+				(i + config->mc_start_offset);
 			writeq(val64, &bar0->rmac_addr_cmd_mem);
 
 			/* Wait for command completes */
 			if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-					RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-					S2IO_BIT_RESET)) {
-				DBG_PRINT(ERR_DBG, "%s: Adding ",
+						  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+						  S2IO_BIT_RESET)) {
+				DBG_PRINT(ERR_DBG,
+					  "%s: Adding Multicasts failed\n",
 					  dev->name);
-				DBG_PRINT(ERR_DBG, "Multicasts failed\n");
 				return;
 			}
 		}
@@ -5135,11 +5151,11 @@ static void do_s2io_restore_unicast_mc(struct s2io_nic *sp)
 	/* restore unicast mac address */
 	for (offset = 0; offset < config->max_mac_addr; offset++)
 		do_s2io_prog_unicast(sp->dev,
-			sp->def_mac_addr[offset].mac_addr);
+				     sp->def_mac_addr[offset].mac_addr);
 
 	/* restore multicast mac address */
 	for (offset = config->mc_start_offset;
-		offset < config->max_mc_addr; offset++)
+	     offset < config->max_mc_addr; offset++)
 		do_s2io_add_mc(sp, sp->def_mac_addr[offset].mac_addr);
 }
 
@@ -5169,13 +5185,13 @@ static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr)
 	}
 	if (i == config->max_mc_addr) {
 		DBG_PRINT(ERR_DBG,
-			"CAM full no space left for multicast MAC\n");
+			  "CAM full no space left for multicast MAC\n");
 		return FAILURE;
 	}
 	/* Update the internal structure with this new mac address */
 	do_s2io_copy_mac_addr(sp, i, mac_addr);
 
-	return (do_s2io_add_mac(sp, mac_addr, i));
+	return do_s2io_add_mac(sp, mac_addr, i);
 }
 
 /* add MAC address to CAM */
@@ -5185,17 +5201,16 @@ static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off)
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
 	writeq(RMAC_ADDR_DATA0_MEM_ADDR(addr),
-		&bar0->rmac_addr_data0_mem);
+	       &bar0->rmac_addr_data0_mem);
 
-	val64 =
-		RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+	val64 =	RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
 		RMAC_ADDR_CMD_MEM_OFFSET(off);
 	writeq(val64, &bar0->rmac_addr_cmd_mem);
 
 	/* Wait till command completes */
 	if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-		RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-		S2IO_BIT_RESET)) {
+				  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+				  S2IO_BIT_RESET)) {
 		DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n");
 		return FAILURE;
 	}
@@ -5209,7 +5224,7 @@ static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr)
 	struct config_param *config = &sp->config;
 
 	for (offset = 1;
-		offset < config->max_mc_addr; offset++) {
+	     offset < config->max_mc_addr; offset++) {
 		tmp64 = do_s2io_read_unicast_mc(sp, offset);
 		if (tmp64 == addr) {
 			/* disable the entry by writing  0xffffffffffffULL */
@@ -5221,7 +5236,7 @@ static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr)
 		}
 	}
 	DBG_PRINT(ERR_DBG, "MAC address 0x%llx not found in CAM\n",
-			(unsigned long long)addr);
+		  (unsigned long long)addr);
 	return FAILURE;
 }
 
@@ -5232,20 +5247,20 @@ static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset)
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
 	/* read mac addr */
-	val64 =
-		RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+	val64 =	RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
 		RMAC_ADDR_CMD_MEM_OFFSET(offset);
 	writeq(val64, &bar0->rmac_addr_cmd_mem);
 
 	/* Wait till command completes */
 	if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-		RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-		S2IO_BIT_RESET)) {
+				  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+				  S2IO_BIT_RESET)) {
 		DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n");
 		return FAILURE;
 	}
 	tmp64 = readq(&bar0->rmac_addr_data0_mem);
-	return (tmp64 >> 16);
+
+	return tmp64 >> 16;
 }
 
 /**
@@ -5262,7 +5277,7 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p)
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
 	/* store the MAC address in CAM */
-	return (do_s2io_prog_unicast(dev, dev->dev_addr));
+	return do_s2io_prog_unicast(dev, dev->dev_addr);
 }
 /**
  *  do_s2io_prog_unicast - Programs the Xframe mac address
@@ -5283,10 +5298,10 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
 	struct config_param *config = &sp->config;
 
 	/*
-	* Set the new MAC address as the new unicast filter and reflect this
-	* change on the device address registered with the OS. It will be
-	* at offset 0.
-	*/
+	 * Set the new MAC address as the new unicast filter and reflect this
+	 * change on the device address registered with the OS. It will be
+	 * at offset 0.
+	 */
 	for (i = 0; i < ETH_ALEN; i++) {
 		mac_addr <<= 8;
 		mac_addr |= addr[i];
@@ -5306,8 +5321,8 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
 
 		if (tmp64 == mac_addr) {
 			DBG_PRINT(INFO_DBG,
-			"MAC addr:0x%llx already present in CAM\n",
-			(unsigned long long)mac_addr);
+				  "MAC addr:0x%llx already present in CAM\n",
+				  (unsigned long long)mac_addr);
 			return SUCCESS;
 		}
 	}
@@ -5317,7 +5332,8 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
 	}
 	/* Update the internal structure with this new mac address */
 	do_s2io_copy_mac_addr(sp, i, mac_addr);
-	return (do_s2io_add_mac(sp, mac_addr, i));
+
+	return do_s2io_add_mac(sp, mac_addr, i);
 }
 
 /**
@@ -5330,14 +5346,15 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
  * the NIC.
  * Return value:
  * 0 on success.
-*/
+ */
 
 static int s2io_ethtool_sset(struct net_device *dev,
 			     struct ethtool_cmd *info)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
 	if ((info->autoneg == AUTONEG_ENABLE) ||
-	    (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL))
+	    (info->speed != SPEED_10000) ||
+	    (info->duplex != DUPLEX_FULL))
 		return -EINVAL;
 	else {
 		s2io_close(sp->dev);
@@ -5418,14 +5435,14 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev,
  *  buffer area.
  * Return value :
  * void .
-*/
+ */
 
 static void s2io_ethtool_gregs(struct net_device *dev,
 			       struct ethtool_regs *regs, void *space)
 {
 	int i;
 	u64 reg;
-	u8 *reg_space = (u8 *) space;
+	u8 *reg_space = (u8 *)space;
 	struct s2io_nic *sp = netdev_priv(dev);
 
 	regs->len = XENA_REG_SPACE;
@@ -5445,17 +5462,17 @@ static void s2io_ethtool_gregs(struct net_device *dev,
  * adapter LED bit of the adapter control bit to set/reset every time on
  * invocation. The timer is set for 1/2 a second, hence tha NIC blinks
  *  once every second.
-*/
+ */
 static void s2io_phy_id(unsigned long data)
 {
-	struct s2io_nic *sp = (struct s2io_nic *) data;
+	struct s2io_nic *sp = (struct s2io_nic *)data;
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	u64 val64 = 0;
 	u16 subid;
 
 	subid = sp->pdev->subsystem_device;
 	if ((sp->device_type == XFRAME_II_DEVICE) ||
-		   ((subid & 0xFF) >= 0x07)) {
+	    ((subid & 0xFF) >= 0x07)) {
 		val64 = readq(&bar0->gpio_control);
 		val64 ^= GPIO_CTRL_GPIO_0;
 		writeq(val64, &bar0->gpio_control);
@@ -5492,19 +5509,17 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 
 	subid = sp->pdev->subsystem_device;
 	last_gpio_ctrl_val = readq(&bar0->gpio_control);
-	if ((sp->device_type == XFRAME_I_DEVICE) &&
-		((subid & 0xFF) < 0x07)) {
+	if ((sp->device_type == XFRAME_I_DEVICE) && ((subid & 0xFF) < 0x07)) {
 		val64 = readq(&bar0->adapter_control);
 		if (!(val64 & ADAPTER_CNTL_EN)) {
-			printk(KERN_ERR
-			       "Adapter Link down, cannot blink LED\n");
+			pr_err("Adapter Link down, cannot blink LED\n");
 			return -EFAULT;
 		}
 	}
 	if (sp->id_timer.function == NULL) {
 		init_timer(&sp->id_timer);
 		sp->id_timer.function = s2io_phy_id;
-		sp->id_timer.data = (unsigned long) sp;
+		sp->id_timer.data = (unsigned long)sp;
 	}
 	mod_timer(&sp->id_timer, jiffies);
 	if (data)
@@ -5522,10 +5537,10 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 }
 
 static void s2io_ethtool_gringparam(struct net_device *dev,
-                                    struct ethtool_ringparam *ering)
+				    struct ethtool_ringparam *ering)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
-	int i,tx_desc_count=0,rx_desc_count=0;
+	int i, tx_desc_count = 0, rx_desc_count = 0;
 
 	if (sp->rxd_mode == RXD_MODE_1)
 		ering->rx_max_pending = MAX_RX_DESC_1;
@@ -5536,7 +5551,7 @@ static void s2io_ethtool_gringparam(struct net_device *dev,
 	for (i = 0 ; i < sp->config.tx_fifo_num ; i++)
 		tx_desc_count += sp->config.tx_cfg[i].fifo_len;
 
-	DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
+	DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds);
 	ering->tx_pending = tx_desc_count;
 	rx_desc_count = 0;
 	for (i = 0 ; i < sp->config.rx_ring_num ; i++)
@@ -5546,7 +5561,7 @@ static void s2io_ethtool_gringparam(struct net_device *dev,
 
 	ering->rx_mini_max_pending = 0;
 	ering->rx_mini_pending = 0;
-	if(sp->rxd_mode == RXD_MODE_1)
+	if (sp->rxd_mode == RXD_MODE_1)
 		ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
 	else if (sp->rxd_mode == RXD_MODE_3B)
 		ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
@@ -5591,7 +5606,7 @@ static void s2io_ethtool_getpause_data(struct net_device *dev,
  */
 
 static int s2io_ethtool_setpause_data(struct net_device *dev,
-			       struct ethtool_pauseparam *ep)
+				      struct ethtool_pauseparam *ep)
 {
 	u64 val64;
 	struct s2io_nic *sp = netdev_priv(dev);
@@ -5627,7 +5642,7 @@ static int s2io_ethtool_setpause_data(struct net_device *dev,
  */
 
 #define S2IO_DEV_ID		5
-static int read_eeprom(struct s2io_nic * sp, int off, u64 * data)
+static int read_eeprom(struct s2io_nic *sp, int off, u64 *data)
 {
 	int ret = -1;
 	u32 exit_cnt = 0;
@@ -5635,9 +5650,11 @@ static int read_eeprom(struct s2io_nic * sp, int off, u64 * data)
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
 	if (sp->device_type == XFRAME_I_DEVICE) {
-		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
-		    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
-		    I2C_CONTROL_CNTL_START;
+		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) |
+			I2C_CONTROL_ADDR(off) |
+			I2C_CONTROL_BYTE_CNT(0x3) |
+			I2C_CONTROL_READ |
+			I2C_CONTROL_CNTL_START;
 		SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 		while (exit_cnt < 5) {
@@ -5692,16 +5709,18 @@ static int read_eeprom(struct s2io_nic * sp, int off, u64 * data)
  *  0 on success, -1 on failure.
  */
 
-static int write_eeprom(struct s2io_nic * sp, int off, u64 data, int cnt)
+static int write_eeprom(struct s2io_nic *sp, int off, u64 data, int cnt)
 {
 	int exit_cnt = 0, ret = -1;
 	u64 val64;
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 
 	if (sp->device_type == XFRAME_I_DEVICE) {
-		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
-		    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA((u32)data) |
-		    I2C_CONTROL_CNTL_START;
+		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) |
+			I2C_CONTROL_ADDR(off) |
+			I2C_CONTROL_BYTE_CNT(cnt) |
+			I2C_CONTROL_SET_DATA((u32)data) |
+			I2C_CONTROL_CNTL_START;
 		SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
 
 		while (exit_cnt < 5) {
@@ -5718,7 +5737,7 @@ static int write_eeprom(struct s2io_nic * sp, int off, u64 data, int cnt)
 
 	if (sp->device_type == XFRAME_II_DEVICE) {
 		int write_cnt = (cnt == 8) ? 0 : cnt;
-		writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data);
+		writeq(SPI_DATA_WRITE(data, (cnt << 3)), &bar0->spi_data);
 
 		val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
 			SPI_CONTROL_BYTECNT(write_cnt) |
@@ -5745,14 +5764,14 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 {
 	u8 *vpd_data;
 	u8 data;
-	int i=0, cnt, fail = 0;
+	int i = 0, cnt, fail = 0;
 	int vpd_addr = 0x80;
+	struct swStat *swstats = &nic->mac_control.stats_info->sw_stat;
 
 	if (nic->device_type == XFRAME_II_DEVICE) {
 		strcpy(nic->product_name, "Xframe II 10GbE network adapter");
 		vpd_addr = 0x80;
-	}
-	else {
+	} else {
 		strcpy(nic->product_name, "Xframe I 10GbE network adapter");
 		vpd_addr = 0x50;
 	}
@@ -5760,16 +5779,16 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 
 	vpd_data = kmalloc(256, GFP_KERNEL);
 	if (!vpd_data) {
-		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
+		swstats->mem_alloc_fail_cnt++;
 		return;
 	}
-	nic->mac_control.stats_info->sw_stat.mem_allocated += 256;
+	swstats->mem_allocated += 256;
 
-	for (i = 0; i < 256; i +=4 ) {
+	for (i = 0; i < 256; i += 4) {
 		pci_write_config_byte(nic->pdev, (vpd_addr + 2), i);
 		pci_read_config_byte(nic->pdev,  (vpd_addr + 2), &data);
 		pci_write_config_byte(nic->pdev, (vpd_addr + 3), 0);
-		for (cnt = 0; cnt <5; cnt++) {
+		for (cnt = 0; cnt < 5; cnt++) {
 			msleep(2);
 			pci_read_config_byte(nic->pdev, (vpd_addr + 3), &data);
 			if (data == 0x80)
@@ -5784,15 +5803,15 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 				      (u32 *)&vpd_data[i]);
 	}
 
-	if(!fail) {
+	if (!fail) {
 		/* read serial number of adapter */
 		for (cnt = 0; cnt < 256; cnt++) {
-		if ((vpd_data[cnt] == 'S') &&
-			(vpd_data[cnt+1] == 'N') &&
-			(vpd_data[cnt+2] < VPD_STRING_LEN)) {
+			if ((vpd_data[cnt] == 'S') &&
+			    (vpd_data[cnt+1] == 'N') &&
+			    (vpd_data[cnt+2] < VPD_STRING_LEN)) {
 				memset(nic->serial_num, 0, VPD_STRING_LEN);
 				memcpy(nic->serial_num, &vpd_data[cnt + 3],
-					vpd_data[cnt+2]);
+				       vpd_data[cnt+2]);
 				break;
 			}
 		}
@@ -5803,7 +5822,7 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 		memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
 	}
 	kfree(vpd_data);
-	nic->mac_control.stats_info->sw_stat.mem_freed += 256;
+	swstats->mem_freed += 256;
 }
 
 /**
@@ -5820,7 +5839,7 @@ static void s2io_vpd_read(struct s2io_nic *nic)
  */
 
 static int s2io_ethtool_geeprom(struct net_device *dev,
-			 struct ethtool_eeprom *eeprom, u8 * data_buf)
+				struct ethtool_eeprom *eeprom, u8 * data_buf)
 {
 	u32 i, valid;
 	u64 data;
@@ -5858,7 +5877,7 @@ static int s2io_ethtool_geeprom(struct net_device *dev,
 
 static int s2io_ethtool_seeprom(struct net_device *dev,
 				struct ethtool_eeprom *eeprom,
-				u8 * data_buf)
+				u8 *data_buf)
 {
 	int len = eeprom->len, cnt = 0;
 	u64 valid = 0, data;
@@ -5866,24 +5885,24 @@ static int s2io_ethtool_seeprom(struct net_device *dev,
 
 	if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) {
 		DBG_PRINT(ERR_DBG,
-			  "ETHTOOL_WRITE_EEPROM Err: Magic value ");
-		DBG_PRINT(ERR_DBG, "is wrong, Its not 0x%x\n",
+			  "ETHTOOL_WRITE_EEPROM Err: "
+			  "Magic value is wrong, it is 0x%x should be 0x%x\n",
+			  (sp->pdev->vendor | (sp->pdev->device << 16)),
 			  eeprom->magic);
 		return -EFAULT;
 	}
 
 	while (len) {
-		data = (u32) data_buf[cnt] & 0x000000FF;
-		if (data) {
-			valid = (u32) (data << 24);
-		} else
+		data = (u32)data_buf[cnt] & 0x000000FF;
+		if (data)
+			valid = (u32)(data << 24);
+		else
 			valid = data;
 
 		if (write_eeprom(sp, (eeprom->offset + cnt), valid, 0)) {
 			DBG_PRINT(ERR_DBG,
-				  "ETHTOOL_WRITE_EEPROM Err: Cannot ");
-			DBG_PRINT(ERR_DBG,
-				  "write into the specified offset\n");
+				  "ETHTOOL_WRITE_EEPROM Err: "
+				  "Cannot write into the specified offset\n");
 			return -EFAULT;
 		}
 		cnt++;
@@ -5906,7 +5925,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev,
  * 0 on success.
  */
 
-static int s2io_register_test(struct s2io_nic * sp, uint64_t * data)
+static int s2io_register_test(struct s2io_nic *sp, uint64_t *data)
 {
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	u64 val64 = 0, exp_val;
@@ -5915,13 +5934,13 @@ static int s2io_register_test(struct s2io_nic * sp, uint64_t * data)
 	val64 = readq(&bar0->pif_rd_swapper_fb);
 	if (val64 != 0x123456789abcdefULL) {
 		fail = 1;
-		DBG_PRINT(INFO_DBG, "Read Test level 1 fails\n");
+		DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 1);
 	}
 
 	val64 = readq(&bar0->rmac_pause_cfg);
 	if (val64 != 0xc000ffff00000000ULL) {
 		fail = 1;
-		DBG_PRINT(INFO_DBG, "Read Test level 2 fails\n");
+		DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 2);
 	}
 
 	val64 = readq(&bar0->rx_queue_cfg);
@@ -5931,13 +5950,13 @@ static int s2io_register_test(struct s2io_nic * sp, uint64_t * data)
 		exp_val = 0x0808080808080808ULL;
 	if (val64 != exp_val) {
 		fail = 1;
-		DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n");
+		DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 3);
 	}
 
 	val64 = readq(&bar0->xgxs_efifo_cfg);
 	if (val64 != 0x000000001923141EULL) {
 		fail = 1;
-		DBG_PRINT(INFO_DBG, "Read Test level 4 fails\n");
+		DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 4);
 	}
 
 	val64 = 0x5A5A5A5A5A5A5A5AULL;
@@ -5945,7 +5964,7 @@ static int s2io_register_test(struct s2io_nic * sp, uint64_t * data)
 	val64 = readq(&bar0->xmsi_data);
 	if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
 		fail = 1;
-		DBG_PRINT(ERR_DBG, "Write Test level 1 fails\n");
+		DBG_PRINT(ERR_DBG, "Write Test level %d fails\n", 1);
 	}
 
 	val64 = 0xA5A5A5A5A5A5A5A5ULL;
@@ -5953,7 +5972,7 @@ static int s2io_register_test(struct s2io_nic * sp, uint64_t * data)
 	val64 = readq(&bar0->xmsi_data);
 	if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
 		fail = 1;
-		DBG_PRINT(ERR_DBG, "Write Test level 2 fails\n");
+		DBG_PRINT(ERR_DBG, "Write Test level %d fails\n", 2);
 	}
 
 	*data = fail;
@@ -5973,7 +5992,7 @@ static int s2io_register_test(struct s2io_nic * sp, uint64_t * data)
  * 0 on success.
  */
 
-static int s2io_eeprom_test(struct s2io_nic * sp, uint64_t * data)
+static int s2io_eeprom_test(struct s2io_nic *sp, uint64_t *data)
 {
 	int fail = 0;
 	u64 ret_data, org_4F0, org_7F0;
@@ -6002,9 +6021,9 @@ static int s2io_eeprom_test(struct s2io_nic * sp, uint64_t * data)
 
 	if (ret_data != 0x012345) {
 		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. "
-			"Data written %llx Data read %llx\n",
-			dev->name, (unsigned long long)0x12345,
-			(unsigned long long)ret_data);
+			  "Data written %llx Data read %llx\n",
+			  dev->name, (unsigned long long)0x12345,
+			  (unsigned long long)ret_data);
 		fail = 1;
 	}
 
@@ -6024,9 +6043,9 @@ static int s2io_eeprom_test(struct s2io_nic * sp, uint64_t * data)
 
 	if (ret_data != 0x012345) {
 		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. "
-			"Data written %llx Data read %llx\n",
-			dev->name, (unsigned long long)0x12345,
-			(unsigned long long)ret_data);
+			  "Data written %llx Data read %llx\n",
+			  dev->name, (unsigned long long)0x12345,
+			  (unsigned long long)ret_data);
 		fail = 1;
 	}
 
@@ -6075,7 +6094,7 @@ static int s2io_eeprom_test(struct s2io_nic * sp, uint64_t * data)
  * 0 on success and -1 on failure.
  */
 
-static int s2io_bist_test(struct s2io_nic * sp, uint64_t * data)
+static int s2io_bist_test(struct s2io_nic *sp, uint64_t *data)
 {
 	u8 bist = 0;
 	int cnt = 0, ret = -1;
@@ -6111,13 +6130,13 @@ static int s2io_bist_test(struct s2io_nic * sp, uint64_t * data)
  * 0 on success.
  */
 
-static int s2io_link_test(struct s2io_nic * sp, uint64_t * data)
+static int s2io_link_test(struct s2io_nic *sp, uint64_t *data)
 {
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	u64 val64;
 
 	val64 = readq(&bar0->adapter_status);
-	if(!(LINK_IS_UP(val64)))
+	if (!(LINK_IS_UP(val64)))
 		*data = 1;
 	else
 		*data = 0;
@@ -6138,7 +6157,7 @@ static int s2io_link_test(struct s2io_nic * sp, uint64_t * data)
  *  0 on success.
  */
 
-static int s2io_rldram_test(struct s2io_nic * sp, uint64_t * data)
+static int s2io_rldram_test(struct s2io_nic *sp, uint64_t *data)
 {
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
 	u64 val64;
@@ -6161,28 +6180,26 @@ static int s2io_rldram_test(struct s2io_nic * sp, uint64_t * data)
 
 	while (iteration < 2) {
 		val64 = 0x55555555aaaa0000ULL;
-		if (iteration == 1) {
+		if (iteration == 1)
 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
-		}
 		writeq(val64, &bar0->mc_rldram_test_d0);
 
 		val64 = 0xaaaa5a5555550000ULL;
-		if (iteration == 1) {
+		if (iteration == 1)
 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
-		}
 		writeq(val64, &bar0->mc_rldram_test_d1);
 
 		val64 = 0x55aaaaaaaa5a0000ULL;
-		if (iteration == 1) {
+		if (iteration == 1)
 			val64 ^= 0xFFFFFFFFFFFF0000ULL;
-		}
 		writeq(val64, &bar0->mc_rldram_test_d2);
 
 		val64 = (u64) (0x0000003ffffe0100ULL);
 		writeq(val64, &bar0->mc_rldram_test_add);
 
-		val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
-		    	MC_RLDRAM_TEST_GO;
+		val64 = MC_RLDRAM_TEST_MODE |
+			MC_RLDRAM_TEST_WRITE |
+			MC_RLDRAM_TEST_GO;
 		SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
 
 		for (cnt = 0; cnt < 5; cnt++) {
@@ -6240,7 +6257,7 @@ static int s2io_rldram_test(struct s2io_nic * sp, uint64_t * data)
 
 static void s2io_ethtool_test(struct net_device *dev,
 			      struct ethtool_test *ethtest,
-			      uint64_t * data)
+			      uint64_t *data)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
 	int orig_state = netif_running(sp->dev);
@@ -6273,8 +6290,7 @@ static void s2io_ethtool_test(struct net_device *dev,
 	} else {
 		/* Online Tests. */
 		if (!orig_state) {
-			DBG_PRINT(ERR_DBG,
-				  "%s: is not up, cannot run test\n",
+			DBG_PRINT(ERR_DBG, "%s: is not up, cannot run test\n",
 				  dev->name);
 			data[0] = -1;
 			data[1] = -1;
@@ -6295,291 +6311,292 @@ static void s2io_ethtool_test(struct net_device *dev,
 
 static void s2io_get_ethtool_stats(struct net_device *dev,
 				   struct ethtool_stats *estats,
-				   u64 * tmp_stats)
+				   u64 *tmp_stats)
 {
 	int i = 0, k;
 	struct s2io_nic *sp = netdev_priv(dev);
-	struct stat_block *stat_info = sp->mac_control.stats_info;
+	struct stat_block *stats = sp->mac_control.stats_info;
+	struct swStat *swstats = &stats->sw_stat;
+	struct xpakStat *xstats = &stats->xpak_stat;
 
 	s2io_updt_stats(sp);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_frms_oflow) << 32  |
-		le32_to_cpu(stat_info->tmac_frms);
+		(u64)le32_to_cpu(stats->tmac_frms_oflow) << 32  |
+		le32_to_cpu(stats->tmac_frms);
+	tmp_stats[i++] =
+		(u64)le32_to_cpu(stats->tmac_data_octets_oflow) << 32 |
+		le32_to_cpu(stats->tmac_data_octets);
+	tmp_stats[i++] = le64_to_cpu(stats->tmac_drop_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_data_octets_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_data_octets);
-	tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms);
+		(u64)le32_to_cpu(stats->tmac_mcst_frms_oflow) << 32 |
+		le32_to_cpu(stats->tmac_mcst_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_mcst_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_mcst_frms);
+		(u64)le32_to_cpu(stats->tmac_bcst_frms_oflow) << 32 |
+		le32_to_cpu(stats->tmac_bcst_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->tmac_pause_ctrl_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_bcst_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_bcst_frms);
-	tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms);
-        tmp_stats[i++] =
-                (u64)le32_to_cpu(stat_info->tmac_ttl_octets_oflow) << 32 |
-                le32_to_cpu(stat_info->tmac_ttl_octets);
+		(u64)le32_to_cpu(stats->tmac_ttl_octets_oflow) << 32 |
+		le32_to_cpu(stats->tmac_ttl_octets);
 	tmp_stats[i++] =
-                (u64)le32_to_cpu(stat_info->tmac_ucst_frms_oflow) << 32 |
-                le32_to_cpu(stat_info->tmac_ucst_frms);
+		(u64)le32_to_cpu(stats->tmac_ucst_frms_oflow) << 32 |
+		le32_to_cpu(stats->tmac_ucst_frms);
 	tmp_stats[i++] =
-                (u64)le32_to_cpu(stat_info->tmac_nucst_frms_oflow) << 32 |
-                le32_to_cpu(stat_info->tmac_nucst_frms);
+		(u64)le32_to_cpu(stats->tmac_nucst_frms_oflow) << 32 |
+		le32_to_cpu(stats->tmac_nucst_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_any_err_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_any_err_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->tmac_ttl_less_fb_octets);
-	tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets);
+		(u64)le32_to_cpu(stats->tmac_any_err_frms_oflow) << 32 |
+		le32_to_cpu(stats->tmac_any_err_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->tmac_ttl_less_fb_octets);
+	tmp_stats[i++] = le64_to_cpu(stats->tmac_vld_ip_octets);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_vld_ip_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_vld_ip);
+		(u64)le32_to_cpu(stats->tmac_vld_ip_oflow) << 32 |
+		le32_to_cpu(stats->tmac_vld_ip);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_drop_ip_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_drop_ip);
+		(u64)le32_to_cpu(stats->tmac_drop_ip_oflow) << 32 |
+		le32_to_cpu(stats->tmac_drop_ip);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_icmp_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_icmp);
+		(u64)le32_to_cpu(stats->tmac_icmp_oflow) << 32 |
+		le32_to_cpu(stats->tmac_icmp);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->tmac_rst_tcp_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_rst_tcp);
-	tmp_stats[i++] = le64_to_cpu(stat_info->tmac_tcp);
-	tmp_stats[i++] = (u64)le32_to_cpu(stat_info->tmac_udp_oflow) << 32 |
-		le32_to_cpu(stat_info->tmac_udp);
+		(u64)le32_to_cpu(stats->tmac_rst_tcp_oflow) << 32 |
+		le32_to_cpu(stats->tmac_rst_tcp);
+	tmp_stats[i++] = le64_to_cpu(stats->tmac_tcp);
+	tmp_stats[i++] = (u64)le32_to_cpu(stats->tmac_udp_oflow) << 32 |
+		le32_to_cpu(stats->tmac_udp);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_vld_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_vld_frms);
+		(u64)le32_to_cpu(stats->rmac_vld_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_vld_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_data_octets_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_data_octets);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_fcs_err_frms);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_drop_frms);
+		(u64)le32_to_cpu(stats->rmac_data_octets_oflow) << 32 |
+		le32_to_cpu(stats->rmac_data_octets);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_fcs_err_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_drop_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_vld_mcst_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_vld_mcst_frms);
+		(u64)le32_to_cpu(stats->rmac_vld_mcst_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_vld_mcst_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_vld_bcst_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_vld_bcst_frms);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rmac_out_rng_len_err_frms);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_unsup_ctrl_frms);
-        tmp_stats[i++] =
-                (u64)le32_to_cpu(stat_info->rmac_ttl_octets_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_ttl_octets);
-        tmp_stats[i++] =
-                (u64)le32_to_cpu(stat_info->rmac_accepted_ucst_frms_oflow)
-		<< 32 | le32_to_cpu(stat_info->rmac_accepted_ucst_frms);
+		(u64)le32_to_cpu(stats->rmac_vld_bcst_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_vld_bcst_frms);
+	tmp_stats[i++] = le32_to_cpu(stats->rmac_in_rng_len_err_frms);
+	tmp_stats[i++] = le32_to_cpu(stats->rmac_out_rng_len_err_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_long_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_pause_ctrl_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_unsup_ctrl_frms);
 	tmp_stats[i++] =
-                (u64)le32_to_cpu(stat_info->rmac_accepted_nucst_frms_oflow)
-                 << 32 | le32_to_cpu(stat_info->rmac_accepted_nucst_frms);
+		(u64)le32_to_cpu(stats->rmac_ttl_octets_oflow) << 32 |
+		le32_to_cpu(stats->rmac_ttl_octets);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_discarded_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_discarded_frms);
-        tmp_stats[i++] =
-                (u64)le32_to_cpu(stat_info->rmac_drop_events_oflow)
-                 << 32 | le32_to_cpu(stat_info->rmac_drop_events);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_less_fb_octets);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_frms);
+		(u64)le32_to_cpu(stats->rmac_accepted_ucst_frms_oflow) << 32
+		| le32_to_cpu(stats->rmac_accepted_ucst_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_usized_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_usized_frms);
+		(u64)le32_to_cpu(stats->rmac_accepted_nucst_frms_oflow)
+		<< 32 | le32_to_cpu(stats->rmac_accepted_nucst_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_osized_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_osized_frms);
+		(u64)le32_to_cpu(stats->rmac_discarded_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_discarded_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_frag_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_frag_frms);
+		(u64)le32_to_cpu(stats->rmac_drop_events_oflow)
+		<< 32 | le32_to_cpu(stats->rmac_drop_events);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_less_fb_octets);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_jabber_frms_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_jabber_frms);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_64_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_65_127_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_128_255_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_256_511_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_512_1023_frms);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_1024_1518_frms);
+		(u64)le32_to_cpu(stats->rmac_usized_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_usized_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_ip);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip);
+		(u64)le32_to_cpu(stats->rmac_osized_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_osized_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_drop_ip);
+		(u64)le32_to_cpu(stats->rmac_frag_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_frag_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_icmp);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp);
+		(u64)le32_to_cpu(stats->rmac_jabber_frms_oflow) << 32 |
+		le32_to_cpu(stats->rmac_jabber_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_64_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_65_127_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_128_255_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_256_511_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_512_1023_frms);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_1024_1518_frms);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_udp);
+		(u64)le32_to_cpu(stats->rmac_ip_oflow) << 32 |
+		le32_to_cpu(stats->rmac_ip);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_ip_octets);
+	tmp_stats[i++] = le32_to_cpu(stats->rmac_hdr_err_ip);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_err_drp_udp_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_err_drp_udp);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_err_sym);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q0);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q1);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q2);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q3);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q4);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q5);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q6);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q7);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q0);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q1);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q2);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q3);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q4);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q5);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q6);
-        tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q7);
+		(u64)le32_to_cpu(stats->rmac_drop_ip_oflow) << 32 |
+		le32_to_cpu(stats->rmac_drop_ip);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_pause_cnt_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_pause_cnt);
-	tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_data_err_cnt);
-        tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_ctrl_err_cnt);
+		(u64)le32_to_cpu(stats->rmac_icmp_oflow) << 32 |
+		le32_to_cpu(stats->rmac_icmp);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_tcp);
 	tmp_stats[i++] =
-		(u64)le32_to_cpu(stat_info->rmac_accepted_ip_oflow) << 32 |
-		le32_to_cpu(stat_info->rmac_accepted_ip);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rd_req_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->new_rd_req_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->new_rd_req_rtry_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rd_rtry_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->wr_rtry_rd_ack_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->wr_req_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->new_wr_req_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->new_wr_req_rtry_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->wr_rtry_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->wr_disc_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rd_rtry_wr_ack_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->txp_wr_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->txd_rd_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->txd_wr_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rxd_rd_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rxd_wr_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->txf_rd_cnt);
-	tmp_stats[i++] = le32_to_cpu(stat_info->rxf_wr_cnt);
+		(u64)le32_to_cpu(stats->rmac_udp_oflow) << 32 |
+		le32_to_cpu(stats->rmac_udp);
+	tmp_stats[i++] =
+		(u64)le32_to_cpu(stats->rmac_err_drp_udp_oflow) << 32 |
+		le32_to_cpu(stats->rmac_err_drp_udp);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_xgmii_err_sym);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q0);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q1);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q2);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q3);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q4);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q5);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q6);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q7);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q0);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q1);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q2);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q3);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q4);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q5);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q6);
+	tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q7);
+	tmp_stats[i++] =
+		(u64)le32_to_cpu(stats->rmac_pause_cnt_oflow) << 32 |
+		le32_to_cpu(stats->rmac_pause_cnt);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_xgmii_data_err_cnt);
+	tmp_stats[i++] = le64_to_cpu(stats->rmac_xgmii_ctrl_err_cnt);
+	tmp_stats[i++] =
+		(u64)le32_to_cpu(stats->rmac_accepted_ip_oflow) << 32 |
+		le32_to_cpu(stats->rmac_accepted_ip);
+	tmp_stats[i++] = le32_to_cpu(stats->rmac_err_tcp);
+	tmp_stats[i++] = le32_to_cpu(stats->rd_req_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->new_rd_req_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->new_rd_req_rtry_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->rd_rtry_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->wr_rtry_rd_ack_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->wr_req_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->new_wr_req_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->new_wr_req_rtry_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->wr_rtry_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->wr_disc_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->rd_rtry_wr_ack_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->txp_wr_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->txd_rd_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->txd_wr_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->rxd_rd_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->rxd_wr_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->txf_rd_cnt);
+	tmp_stats[i++] = le32_to_cpu(stats->rxf_wr_cnt);
 
 	/* Enhanced statistics exist only for Hercules */
-	if(sp->device_type == XFRAME_II_DEVICE) {
+	if (sp->device_type == XFRAME_II_DEVICE) {
 		tmp_stats[i++] =
-				le64_to_cpu(stat_info->rmac_ttl_1519_4095_frms);
+			le64_to_cpu(stats->rmac_ttl_1519_4095_frms);
 		tmp_stats[i++] =
-				le64_to_cpu(stat_info->rmac_ttl_4096_8191_frms);
+			le64_to_cpu(stats->rmac_ttl_4096_8191_frms);
 		tmp_stats[i++] =
-				le64_to_cpu(stat_info->rmac_ttl_8192_max_frms);
-		tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_gt_max_frms);
-		tmp_stats[i++] = le64_to_cpu(stat_info->rmac_osized_alt_frms);
-		tmp_stats[i++] = le64_to_cpu(stat_info->rmac_jabber_alt_frms);
-		tmp_stats[i++] = le64_to_cpu(stat_info->rmac_gt_max_alt_frms);
-		tmp_stats[i++] = le64_to_cpu(stat_info->rmac_vlan_frms);
-		tmp_stats[i++] = le32_to_cpu(stat_info->rmac_len_discard);
-		tmp_stats[i++] = le32_to_cpu(stat_info->rmac_fcs_discard);
-		tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pf_discard);
-		tmp_stats[i++] = le32_to_cpu(stat_info->rmac_da_discard);
-		tmp_stats[i++] = le32_to_cpu(stat_info->rmac_red_discard);
-		tmp_stats[i++] = le32_to_cpu(stat_info->rmac_rts_discard);
-		tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ingm_full_discard);
-		tmp_stats[i++] = le32_to_cpu(stat_info->link_fault_cnt);
+			le64_to_cpu(stats->rmac_ttl_8192_max_frms);
+		tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_gt_max_frms);
+		tmp_stats[i++] = le64_to_cpu(stats->rmac_osized_alt_frms);
+		tmp_stats[i++] = le64_to_cpu(stats->rmac_jabber_alt_frms);
+		tmp_stats[i++] = le64_to_cpu(stats->rmac_gt_max_alt_frms);
+		tmp_stats[i++] = le64_to_cpu(stats->rmac_vlan_frms);
+		tmp_stats[i++] = le32_to_cpu(stats->rmac_len_discard);
+		tmp_stats[i++] = le32_to_cpu(stats->rmac_fcs_discard);
+		tmp_stats[i++] = le32_to_cpu(stats->rmac_pf_discard);
+		tmp_stats[i++] = le32_to_cpu(stats->rmac_da_discard);
+		tmp_stats[i++] = le32_to_cpu(stats->rmac_red_discard);
+		tmp_stats[i++] = le32_to_cpu(stats->rmac_rts_discard);
+		tmp_stats[i++] = le32_to_cpu(stats->rmac_ingm_full_discard);
+		tmp_stats[i++] = le32_to_cpu(stats->link_fault_cnt);
 	}
 
 	tmp_stats[i++] = 0;
-	tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs;
-	tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
-	tmp_stats[i++] = stat_info->sw_stat.parity_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.serious_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.soft_reset_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.fifo_full_cnt;
+	tmp_stats[i++] = swstats->single_ecc_errs;
+	tmp_stats[i++] = swstats->double_ecc_errs;
+	tmp_stats[i++] = swstats->parity_err_cnt;
+	tmp_stats[i++] = swstats->serious_err_cnt;
+	tmp_stats[i++] = swstats->soft_reset_cnt;
+	tmp_stats[i++] = swstats->fifo_full_cnt;
 	for (k = 0; k < MAX_RX_RINGS; k++)
-		tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt[k];
-	tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_high;
-	tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_low;
-	tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_high;
-	tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_low;
-	tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_output_power_high;
-	tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_output_power_low;
-	tmp_stats[i++] = stat_info->xpak_stat.warn_transceiver_temp_high;
-	tmp_stats[i++] = stat_info->xpak_stat.warn_transceiver_temp_low;
-	tmp_stats[i++] = stat_info->xpak_stat.warn_laser_bias_current_high;
-	tmp_stats[i++] = stat_info->xpak_stat.warn_laser_bias_current_low;
-	tmp_stats[i++] = stat_info->xpak_stat.warn_laser_output_power_high;
-	tmp_stats[i++] = stat_info->xpak_stat.warn_laser_output_power_low;
-	tmp_stats[i++] = stat_info->sw_stat.clubbed_frms_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.sending_both;
-	tmp_stats[i++] = stat_info->sw_stat.outof_sequence_pkts;
-	tmp_stats[i++] = stat_info->sw_stat.flush_max_pkts;
-	if (stat_info->sw_stat.num_aggregations) {
-		u64 tmp = stat_info->sw_stat.sum_avg_pkts_aggregated;
+		tmp_stats[i++] = swstats->ring_full_cnt[k];
+	tmp_stats[i++] = xstats->alarm_transceiver_temp_high;
+	tmp_stats[i++] = xstats->alarm_transceiver_temp_low;
+	tmp_stats[i++] = xstats->alarm_laser_bias_current_high;
+	tmp_stats[i++] = xstats->alarm_laser_bias_current_low;
+	tmp_stats[i++] = xstats->alarm_laser_output_power_high;
+	tmp_stats[i++] = xstats->alarm_laser_output_power_low;
+	tmp_stats[i++] = xstats->warn_transceiver_temp_high;
+	tmp_stats[i++] = xstats->warn_transceiver_temp_low;
+	tmp_stats[i++] = xstats->warn_laser_bias_current_high;
+	tmp_stats[i++] = xstats->warn_laser_bias_current_low;
+	tmp_stats[i++] = xstats->warn_laser_output_power_high;
+	tmp_stats[i++] = xstats->warn_laser_output_power_low;
+	tmp_stats[i++] = swstats->clubbed_frms_cnt;
+	tmp_stats[i++] = swstats->sending_both;
+	tmp_stats[i++] = swstats->outof_sequence_pkts;
+	tmp_stats[i++] = swstats->flush_max_pkts;
+	if (swstats->num_aggregations) {
+		u64 tmp = swstats->sum_avg_pkts_aggregated;
 		int count = 0;
 		/*
 		 * Since 64-bit divide does not work on all platforms,
 		 * do repeated subtraction.
 		 */
-		while (tmp >= stat_info->sw_stat.num_aggregations) {
-			tmp -= stat_info->sw_stat.num_aggregations;
+		while (tmp >= swstats->num_aggregations) {
+			tmp -= swstats->num_aggregations;
 			count++;
 		}
 		tmp_stats[i++] = count;
-	}
-	else
+	} else
 		tmp_stats[i++] = 0;
-	tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.pci_map_fail_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.mem_allocated;
-	tmp_stats[i++] = stat_info->sw_stat.mem_freed;
-	tmp_stats[i++] = stat_info->sw_stat.link_up_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.link_down_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.link_up_time;
-	tmp_stats[i++] = stat_info->sw_stat.link_down_time;
-
-	tmp_stats[i++] = stat_info->sw_stat.tx_buf_abort_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.tx_desc_abort_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.tx_parity_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.tx_link_loss_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.tx_list_proc_err_cnt;
-
-	tmp_stats[i++] = stat_info->sw_stat.rx_parity_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_abort_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_parity_abort_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_rda_fail_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_unkn_prot_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_fcs_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.tda_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.pfc_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.pcc_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.tti_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.tpa_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.sm_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.lso_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.mac_tmac_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.mac_rmac_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.xgxs_txgxs_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.xgxs_rxgxs_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rc_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.prc_pcix_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rpa_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rda_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.rti_err_cnt;
-	tmp_stats[i++] = stat_info->sw_stat.mc_err_cnt;
+	tmp_stats[i++] = swstats->mem_alloc_fail_cnt;
+	tmp_stats[i++] = swstats->pci_map_fail_cnt;
+	tmp_stats[i++] = swstats->watchdog_timer_cnt;
+	tmp_stats[i++] = swstats->mem_allocated;
+	tmp_stats[i++] = swstats->mem_freed;
+	tmp_stats[i++] = swstats->link_up_cnt;
+	tmp_stats[i++] = swstats->link_down_cnt;
+	tmp_stats[i++] = swstats->link_up_time;
+	tmp_stats[i++] = swstats->link_down_time;
+
+	tmp_stats[i++] = swstats->tx_buf_abort_cnt;
+	tmp_stats[i++] = swstats->tx_desc_abort_cnt;
+	tmp_stats[i++] = swstats->tx_parity_err_cnt;
+	tmp_stats[i++] = swstats->tx_link_loss_cnt;
+	tmp_stats[i++] = swstats->tx_list_proc_err_cnt;
+
+	tmp_stats[i++] = swstats->rx_parity_err_cnt;
+	tmp_stats[i++] = swstats->rx_abort_cnt;
+	tmp_stats[i++] = swstats->rx_parity_abort_cnt;
+	tmp_stats[i++] = swstats->rx_rda_fail_cnt;
+	tmp_stats[i++] = swstats->rx_unkn_prot_cnt;
+	tmp_stats[i++] = swstats->rx_fcs_err_cnt;
+	tmp_stats[i++] = swstats->rx_buf_size_err_cnt;
+	tmp_stats[i++] = swstats->rx_rxd_corrupt_cnt;
+	tmp_stats[i++] = swstats->rx_unkn_err_cnt;
+	tmp_stats[i++] = swstats->tda_err_cnt;
+	tmp_stats[i++] = swstats->pfc_err_cnt;
+	tmp_stats[i++] = swstats->pcc_err_cnt;
+	tmp_stats[i++] = swstats->tti_err_cnt;
+	tmp_stats[i++] = swstats->tpa_err_cnt;
+	tmp_stats[i++] = swstats->sm_err_cnt;
+	tmp_stats[i++] = swstats->lso_err_cnt;
+	tmp_stats[i++] = swstats->mac_tmac_err_cnt;
+	tmp_stats[i++] = swstats->mac_rmac_err_cnt;
+	tmp_stats[i++] = swstats->xgxs_txgxs_err_cnt;
+	tmp_stats[i++] = swstats->xgxs_rxgxs_err_cnt;
+	tmp_stats[i++] = swstats->rc_err_cnt;
+	tmp_stats[i++] = swstats->prc_pcix_err_cnt;
+	tmp_stats[i++] = swstats->rpa_err_cnt;
+	tmp_stats[i++] = swstats->rda_err_cnt;
+	tmp_stats[i++] = swstats->rti_err_cnt;
+	tmp_stats[i++] = swstats->mc_err_cnt;
 }
 
 static int s2io_ethtool_get_regs_len(struct net_device *dev)
 {
-	return (XENA_REG_SPACE);
+	return XENA_REG_SPACE;
 }
 
 
-static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
+static u32 s2io_ethtool_get_rx_csum(struct net_device *dev)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
 
-	return (sp->rx_csum);
+	return sp->rx_csum;
 }
 
 static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
@@ -6596,7 +6613,7 @@ static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
 
 static int s2io_get_eeprom_len(struct net_device *dev)
 {
-	return (XENA_EEPROM_SPACE);
+	return XENA_EEPROM_SPACE;
 }
 
 static int s2io_get_sset_count(struct net_device *dev, int sset)
@@ -6607,7 +6624,7 @@ static int s2io_get_sset_count(struct net_device *dev, int sset)
 	case ETH_SS_TEST:
 		return S2IO_TEST_LEN;
 	case ETH_SS_STATS:
-		switch(sp->device_type) {
+		switch (sp->device_type) {
 		case XFRAME_I_DEVICE:
 			return XFRAME_I_STAT_LEN;
 		case XFRAME_II_DEVICE:
@@ -6621,7 +6638,7 @@ static int s2io_get_sset_count(struct net_device *dev, int sset)
 }
 
 static void s2io_ethtool_get_strings(struct net_device *dev,
-				     u32 stringset, u8 * data)
+				     u32 stringset, u8 *data)
 {
 	int stat_size = 0;
 	struct s2io_nic *sp = netdev_priv(dev);
@@ -6632,16 +6649,16 @@ static void s2io_ethtool_get_strings(struct net_device *dev,
 		break;
 	case ETH_SS_STATS:
 		stat_size = sizeof(ethtool_xena_stats_keys);
-		memcpy(data, &ethtool_xena_stats_keys,stat_size);
-		if(sp->device_type == XFRAME_II_DEVICE) {
+		memcpy(data, &ethtool_xena_stats_keys, stat_size);
+		if (sp->device_type == XFRAME_II_DEVICE) {
 			memcpy(data + stat_size,
-				&ethtool_enhanced_stats_keys,
-				sizeof(ethtool_enhanced_stats_keys));
+			       &ethtool_enhanced_stats_keys,
+			       sizeof(ethtool_enhanced_stats_keys));
 			stat_size += sizeof(ethtool_enhanced_stats_keys);
 		}
 
 		memcpy(data + stat_size, &ethtool_driver_stats_keys,
-			sizeof(ethtool_driver_stats_keys));
+		       sizeof(ethtool_driver_stats_keys));
 	}
 }
 
@@ -6730,8 +6747,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu)
 	int ret = 0;
 
 	if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) {
-		DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n",
-			  dev->name);
+		DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", dev->name);
 		return -EPERM;
 	}
 
@@ -6764,7 +6780,8 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu)
 
 static void s2io_set_link(struct work_struct *work)
 {
-	struct s2io_nic *nic = container_of(work, struct s2io_nic, set_link_task);
+	struct s2io_nic *nic = container_of(work, struct s2io_nic,
+					    set_link_task);
 	struct net_device *dev = nic->dev;
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	register u64 val64;
@@ -6797,7 +6814,7 @@ static void s2io_set_link(struct work_struct *work)
 				val64 |= ADAPTER_CNTL_EN;
 				writeq(val64, &bar0->adapter_control);
 				if (CARDS_WITH_FAULTY_LINK_INDICATORS(
-					nic->device_type, subid)) {
+					    nic->device_type, subid)) {
 					val64 = readq(&bar0->gpio_control);
 					val64 |= GPIO_CTRL_GPIO_0;
 					writeq(val64, &bar0->gpio_control);
@@ -6808,8 +6825,9 @@ static void s2io_set_link(struct work_struct *work)
 				}
 				nic->device_enabled_once = true;
 			} else {
-				DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name);
-				DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
+				DBG_PRINT(ERR_DBG,
+					  "%s: Error: device is not Quiescent\n",
+					  dev->name);
 				s2io_stop_all_tx_queue(nic);
 			}
 		}
@@ -6827,7 +6845,7 @@ static void s2io_set_link(struct work_struct *work)
 		}
 		/* turn off LED */
 		val64 = readq(&bar0->adapter_control);
-		val64 = val64 &(~ADAPTER_LED_ON);
+		val64 = val64 & (~ADAPTER_LED_ON);
 		writeq(val64, &bar0->adapter_control);
 		s2io_link(nic, LINK_DOWN);
 	}
@@ -6838,9 +6856,9 @@ out_unlock:
 }
 
 static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
-				struct buffAdd *ba,
-				struct sk_buff **skb, u64 *temp0, u64 *temp1,
-				u64 *temp2, int size)
+				  struct buffAdd *ba,
+				  struct sk_buff **skb, u64 *temp0, u64 *temp1,
+				  u64 *temp2, int size)
 {
 	struct net_device *dev = sp->dev;
 	struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
@@ -6859,23 +6877,21 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 		} else {
 			*skb = dev_alloc_skb(size);
 			if (!(*skb)) {
-				DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
-				DBG_PRINT(INFO_DBG, "memory to allocate ");
-				DBG_PRINT(INFO_DBG, "1 buf mode SKBs\n");
-				sp->mac_control.stats_info->sw_stat. \
-					mem_alloc_fail_cnt++;
+				DBG_PRINT(INFO_DBG,
+					  "%s: Out of memory to allocate %s\n",
+					  dev->name, "1 buf mode SKBs");
+				stats->mem_alloc_fail_cnt++;
 				return -ENOMEM ;
 			}
-			sp->mac_control.stats_info->sw_stat.mem_allocated
-				+= (*skb)->truesize;
+			stats->mem_allocated += (*skb)->truesize;
 			/* storing the mapped addr in a temp variable
 			 * such it will be used for next rxd whose
 			 * Host Control is NULL
 			 */
 			rxdp1->Buffer0_ptr = *temp0 =
-				pci_map_single( sp->pdev, (*skb)->data,
-					size - NET_IP_ALIGN,
-					PCI_DMA_FROMDEVICE);
+				pci_map_single(sp->pdev, (*skb)->data,
+					       size - NET_IP_ALIGN,
+					       PCI_DMA_FROMDEVICE);
 			if (pci_dma_mapping_error(sp->pdev, rxdp1->Buffer0_ptr))
 				goto memalloc_failed;
 			rxdp->Host_Control = (unsigned long) (*skb);
@@ -6890,15 +6906,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 		} else {
 			*skb = dev_alloc_skb(size);
 			if (!(*skb)) {
-				DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
-				DBG_PRINT(INFO_DBG, "memory to allocate ");
-				DBG_PRINT(INFO_DBG, "2 buf mode SKBs\n");
-				sp->mac_control.stats_info->sw_stat. \
-					mem_alloc_fail_cnt++;
+				DBG_PRINT(INFO_DBG,
+					  "%s: Out of memory to allocate %s\n",
+					  dev->name,
+					  "2 buf mode SKBs");
+				stats->mem_alloc_fail_cnt++;
 				return -ENOMEM;
 			}
-			sp->mac_control.stats_info->sw_stat.mem_allocated
-				+= (*skb)->truesize;
+			stats->mem_allocated += (*skb)->truesize;
 			rxdp3->Buffer2_ptr = *temp2 =
 				pci_map_single(sp->pdev, (*skb)->data,
 					       dev->mtu + 4,
@@ -6906,13 +6921,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 			if (pci_dma_mapping_error(sp->pdev, rxdp3->Buffer2_ptr))
 				goto memalloc_failed;
 			rxdp3->Buffer0_ptr = *temp0 =
-				pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN,
-						PCI_DMA_FROMDEVICE);
+				pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
+					       PCI_DMA_FROMDEVICE);
 			if (pci_dma_mapping_error(sp->pdev,
-						rxdp3->Buffer0_ptr)) {
-				pci_unmap_single (sp->pdev,
-					(dma_addr_t)rxdp3->Buffer2_ptr,
-					dev->mtu + 4, PCI_DMA_FROMDEVICE);
+						  rxdp3->Buffer0_ptr)) {
+				pci_unmap_single(sp->pdev,
+						 (dma_addr_t)rxdp3->Buffer2_ptr,
+						 dev->mtu + 4,
+						 PCI_DMA_FROMDEVICE);
 				goto memalloc_failed;
 			}
 			rxdp->Host_Control = (unsigned long) (*skb);
@@ -6920,25 +6936,27 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 			/* Buffer-1 will be dummy buffer not used */
 			rxdp3->Buffer1_ptr = *temp1 =
 				pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
-						PCI_DMA_FROMDEVICE);
+					       PCI_DMA_FROMDEVICE);
 			if (pci_dma_mapping_error(sp->pdev,
-						rxdp3->Buffer1_ptr)) {
-				pci_unmap_single (sp->pdev,
-					(dma_addr_t)rxdp3->Buffer0_ptr,
-					BUF0_LEN, PCI_DMA_FROMDEVICE);
-				pci_unmap_single (sp->pdev,
-					(dma_addr_t)rxdp3->Buffer2_ptr,
-					dev->mtu + 4, PCI_DMA_FROMDEVICE);
+						  rxdp3->Buffer1_ptr)) {
+				pci_unmap_single(sp->pdev,
+						 (dma_addr_t)rxdp3->Buffer0_ptr,
+						 BUF0_LEN, PCI_DMA_FROMDEVICE);
+				pci_unmap_single(sp->pdev,
+						 (dma_addr_t)rxdp3->Buffer2_ptr,
+						 dev->mtu + 4,
+						 PCI_DMA_FROMDEVICE);
 				goto memalloc_failed;
 			}
 		}
 	}
 	return 0;
-	memalloc_failed:
-		stats->pci_map_fail_cnt++;
-		stats->mem_freed += (*skb)->truesize;
-		dev_kfree_skb(*skb);
-		return -ENOMEM;
+
+memalloc_failed:
+	stats->pci_map_fail_cnt++;
+	stats->mem_freed += (*skb)->truesize;
+	dev_kfree_skb(*skb);
+	return -ENOMEM;
 }
 
 static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
@@ -6946,19 +6964,19 @@ static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
 {
 	struct net_device *dev = sp->dev;
 	if (sp->rxd_mode == RXD_MODE_1) {
-		rxdp->Control_2 = SET_BUFFER0_SIZE_1( size - NET_IP_ALIGN);
+		rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
 	} else if (sp->rxd_mode == RXD_MODE_3B) {
 		rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
 		rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
-		rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4);
+		rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu + 4);
 	}
 }
 
 static  int rxd_owner_bit_reset(struct s2io_nic *sp)
 {
 	int i, j, k, blk_cnt = 0, size;
-	struct mac_info * mac_control = &sp->mac_control;
 	struct config_param *config = &sp->config;
+	struct mac_info *mac_control = &sp->mac_control;
 	struct net_device *dev = sp->dev;
 	struct RxD_t *rxdp = NULL;
 	struct sk_buff *skb = NULL;
@@ -6974,20 +6992,21 @@ static  int rxd_owner_bit_reset(struct s2io_nic *sp)
 		size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
 
 	for (i = 0; i < config->rx_ring_num; i++) {
-		blk_cnt = config->rx_cfg[i].num_rxd /
-			(rxd_count[sp->rxd_mode] +1);
+		struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+		struct ring_info *ring = &mac_control->rings[i];
+
+		blk_cnt = rx_cfg->num_rxd / (rxd_count[sp->rxd_mode] + 1);
 
 		for (j = 0; j < blk_cnt; j++) {
 			for (k = 0; k < rxd_count[sp->rxd_mode]; k++) {
-				rxdp = mac_control->rings[i].
-					rx_blocks[j].rxds[k].virt_addr;
-				if(sp->rxd_mode == RXD_MODE_3B)
-					ba = &mac_control->rings[i].ba[j][k];
-				if (set_rxd_buffer_pointer(sp, rxdp, ba,
-						       &skb,(u64 *)&temp0_64,
-						       (u64 *)&temp1_64,
-						       (u64 *)&temp2_64,
-							size) == -ENOMEM) {
+				rxdp = ring->rx_blocks[j].rxds[k].virt_addr;
+				if (sp->rxd_mode == RXD_MODE_3B)
+					ba = &ring->ba[j][k];
+				if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb,
+							   (u64 *)&temp0_64,
+							   (u64 *)&temp1_64,
+							   (u64 *)&temp2_64,
+							   size) == -ENOMEM) {
 					return 0;
 				}
 
@@ -7002,7 +7021,7 @@ static  int rxd_owner_bit_reset(struct s2io_nic *sp)
 
 }
 
-static int s2io_add_isr(struct s2io_nic * sp)
+static int s2io_add_isr(struct s2io_nic *sp)
 {
 	int ret = 0;
 	struct net_device *dev = sp->dev;
@@ -7015,7 +7034,10 @@ static int s2io_add_isr(struct s2io_nic * sp)
 		sp->config.intr_type = INTA;
 	}
 
-	/* Store the values of the MSIX table in the struct s2io_nic structure */
+	/*
+	 * Store the values of the MSIX table in
+	 * the struct s2io_nic structure
+	 */
 	store_xmsi_data(sp);
 
 	/* After proper initialization of H/W, register ISR */
@@ -7025,45 +7047,47 @@ static int s2io_add_isr(struct s2io_nic * sp)
 		for (i = 0; i < sp->num_entries; i++) {
 			if (sp->s2io_entries[i].in_use == MSIX_FLG) {
 				if (sp->s2io_entries[i].type ==
-					MSIX_RING_TYPE) {
+				    MSIX_RING_TYPE) {
 					sprintf(sp->desc[i], "%s:MSI-X-%d-RX",
 						dev->name, i);
 					err = request_irq(sp->entries[i].vector,
-						s2io_msix_ring_handle, 0,
-						sp->desc[i],
-						sp->s2io_entries[i].arg);
+							  s2io_msix_ring_handle,
+							  0,
+							  sp->desc[i],
+							  sp->s2io_entries[i].arg);
 				} else if (sp->s2io_entries[i].type ==
-					MSIX_ALARM_TYPE) {
+					   MSIX_ALARM_TYPE) {
 					sprintf(sp->desc[i], "%s:MSI-X-%d-TX",
-					dev->name, i);
+						dev->name, i);
 					err = request_irq(sp->entries[i].vector,
-						s2io_msix_fifo_handle, 0,
-						sp->desc[i],
-						sp->s2io_entries[i].arg);
+							  s2io_msix_fifo_handle,
+							  0,
+							  sp->desc[i],
+							  sp->s2io_entries[i].arg);
 
 				}
 				/* if either data or addr is zero print it. */
 				if (!(sp->msix_info[i].addr &&
-					sp->msix_info[i].data)) {
+				      sp->msix_info[i].data)) {
 					DBG_PRINT(ERR_DBG,
-						"%s @Addr:0x%llx Data:0x%llx\n",
-						sp->desc[i],
-						(unsigned long long)
-						sp->msix_info[i].addr,
-						(unsigned long long)
-						ntohl(sp->msix_info[i].data));
+						  "%s @Addr:0x%llx Data:0x%llx\n",
+						  sp->desc[i],
+						  (unsigned long long)
+						  sp->msix_info[i].addr,
+						  (unsigned long long)
+						  ntohl(sp->msix_info[i].data));
 				} else
 					msix_rx_cnt++;
 				if (err) {
 					remove_msix_isr(sp);
 
 					DBG_PRINT(ERR_DBG,
-						"%s:MSI-X-%d registration "
-						"failed\n", dev->name, i);
+						  "%s:MSI-X-%d registration "
+						  "failed\n", dev->name, i);
 
 					DBG_PRINT(ERR_DBG,
-						"%s: Defaulting to INTA\n",
-						dev->name);
+						  "%s: Defaulting to INTA\n",
+						  dev->name);
 					sp->config.intr_type = INTA;
 					break;
 				}
@@ -7072,15 +7096,14 @@ static int s2io_add_isr(struct s2io_nic * sp)
 			}
 		}
 		if (!err) {
-			printk(KERN_INFO "MSI-X-RX %d entries enabled\n",
-				--msix_rx_cnt);
-			DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled"
-						" through alarm vector\n");
+			pr_info("MSI-X-RX %d entries enabled\n", --msix_rx_cnt);
+			DBG_PRINT(INFO_DBG,
+				  "MSI-X-TX entries enabled through alarm vector\n");
 		}
 	}
 	if (sp->config.intr_type == INTA) {
-		err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED,
-				sp->name, dev);
+		err = request_irq((int)sp->pdev->irq, s2io_isr, IRQF_SHARED,
+				  sp->name, dev);
 		if (err) {
 			DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
 				  dev->name);
@@ -7089,7 +7112,8 @@ static int s2io_add_isr(struct s2io_nic * sp)
 	}
 	return 0;
 }
-static void s2io_rem_isr(struct s2io_nic * sp)
+
+static void s2io_rem_isr(struct s2io_nic *sp)
 {
 	if (sp->config.intr_type == MSI_X)
 		remove_msix_isr(sp);
@@ -7097,7 +7121,7 @@ static void s2io_rem_isr(struct s2io_nic * sp)
 		remove_inta_isr(sp);
 }
 
-static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
+static void do_s2io_card_down(struct s2io_nic *sp, int do_io)
 {
 	int cnt = 0;
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
@@ -7110,9 +7134,8 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 
 	del_timer_sync(&sp->alarm_timer);
 	/* If s2io_set_link task is executing, wait till it completes. */
-	while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state))) {
+	while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state)))
 		msleep(50);
-	}
 	clear_bit(__S2IO_STATE_CARD_UP, &sp->state);
 
 	/* Disable napi */
@@ -7121,7 +7144,7 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 		if (config->intr_type ==  MSI_X) {
 			for (; off < sp->config.rx_ring_num; off++)
 				napi_disable(&sp->mac_control.rings[off].napi);
-			}
+		}
 		else
 			napi_disable(&sp->napi);
 	}
@@ -7136,7 +7159,7 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 	s2io_link(sp, LINK_DOWN);
 
 	/* Check if the device is Quiescent and then Reset the NIC */
-	while(do_io) {
+	while (do_io) {
 		/* As per the HW requirement we need to replenish the
 		 * receive buffer to avoid the ring bump. Since there is
 		 * no intention of processing the Rx frame at this pointwe are
@@ -7148,17 +7171,16 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 
 		val64 = readq(&bar0->adapter_status);
 		if (verify_xena_quiescence(sp)) {
-			if(verify_pcc_quiescent(sp, sp->device_enabled_once))
-			break;
+			if (verify_pcc_quiescent(sp, sp->device_enabled_once))
+				break;
 		}
 
 		msleep(50);
 		cnt++;
 		if (cnt == 10) {
-			DBG_PRINT(ERR_DBG,
-				  "s2io_close:Device not Quiescent ");
-			DBG_PRINT(ERR_DBG, "adaper status reads 0x%llx\n",
-				  (unsigned long long) val64);
+			DBG_PRINT(ERR_DBG, "Device not Quiescent - "
+				  "adapter status reads 0x%llx\n",
+				  (unsigned long long)val64);
 			break;
 		}
 	}
@@ -7174,17 +7196,17 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 	clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state));
 }
 
-static void s2io_card_down(struct s2io_nic * sp)
+static void s2io_card_down(struct s2io_nic *sp)
 {
 	do_s2io_card_down(sp, 1);
 }
 
-static int s2io_card_up(struct s2io_nic * sp)
+static int s2io_card_up(struct s2io_nic *sp)
 {
 	int i, ret = 0;
-	struct mac_info *mac_control;
 	struct config_param *config;
-	struct net_device *dev = (struct net_device *) sp->dev;
+	struct mac_info *mac_control;
+	struct net_device *dev = (struct net_device *)sp->dev;
 	u16 interruptible;
 
 	/* Initialize the H/W I/O registers */
@@ -7201,12 +7223,14 @@ static int s2io_card_up(struct s2io_nic * sp)
 	 * Initializing the Rx buffers. For now we are considering only 1
 	 * Rx ring and initializing buffers into 30 Rx blocks
 	 */
-	mac_control = &sp->mac_control;
 	config = &sp->config;
+	mac_control = &sp->mac_control;
 
 	for (i = 0; i < config->rx_ring_num; i++) {
-		mac_control->rings[i].mtu = dev->mtu;
-		ret = fill_rx_buffers(sp, &mac_control->rings[i], 1);
+		struct ring_info *ring = &mac_control->rings[i];
+
+		ring->mtu = dev->mtu;
+		ret = fill_rx_buffers(sp, ring, 1);
 		if (ret) {
 			DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
 				  dev->name);
@@ -7215,7 +7239,7 @@ static int s2io_card_up(struct s2io_nic * sp)
 			return -ENOMEM;
 		}
 		DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
-			  mac_control->rings[i].rx_bufs_left);
+			  ring->rx_bufs_left);
 	}
 
 	/* Initialise napi */
@@ -7233,7 +7257,7 @@ static int s2io_card_up(struct s2io_nic * sp)
 		sp->promisc_flg = 0;
 	if (sp->m_cast_flg) {
 		sp->m_cast_flg = 0;
-		sp->all_multi_pos= 0;
+		sp->all_multi_pos = 0;
 	}
 
 	/* Setting its receive mode */
@@ -7242,7 +7266,7 @@ static int s2io_card_up(struct s2io_nic * sp)
 	if (sp->lro) {
 		/* Initialize max aggregatable pkts per session based on MTU */
 		sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu;
-		/* Check if we can use(if specified) user provided value */
+		/* Check if we can use (if specified) user provided value */
 		if (lro_max_pkts < sp->lro_max_aggr_per_sess)
 			sp->lro_max_aggr_per_sess = lro_max_pkts;
 	}
@@ -7304,12 +7328,10 @@ static void s2io_restart_nic(struct work_struct *work)
 
 	s2io_card_down(sp);
 	if (s2io_card_up(sp)) {
-		DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
-			  dev->name);
+		DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", dev->name);
 	}
 	s2io_wake_all_tx_queue(sp);
-	DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n",
-		  dev->name);
+	DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", dev->name);
 out_unlock:
 	rtnl_unlock();
 }
@@ -7330,11 +7352,12 @@ out_unlock:
 static void s2io_tx_watchdog(struct net_device *dev)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
+	struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
 
 	if (netif_carrier_ok(dev)) {
-		sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt++;
+		swstats->watchdog_timer_cnt++;
 		schedule_work(&sp->rst_timer_task);
-		sp->mac_control.stats_info->sw_stat.soft_reset_cnt++;
+		swstats->soft_reset_cnt++;
 	}
 }
 
@@ -7358,81 +7381,73 @@ static void s2io_tx_watchdog(struct net_device *dev)
 static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 {
 	struct s2io_nic *sp = ring_data->nic;
-	struct net_device *dev = (struct net_device *) ring_data->dev;
+	struct net_device *dev = (struct net_device *)ring_data->dev;
 	struct sk_buff *skb = (struct sk_buff *)
-		((unsigned long) rxdp->Host_Control);
+		((unsigned long)rxdp->Host_Control);
 	int ring_no = ring_data->ring_no;
 	u16 l3_csum, l4_csum;
 	unsigned long long err = rxdp->Control_1 & RXD_T_CODE;
 	struct lro *uninitialized_var(lro);
 	u8 err_mask;
+	struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
 
 	skb->dev = dev;
 
 	if (err) {
 		/* Check for parity error */
-		if (err & 0x1) {
-			sp->mac_control.stats_info->sw_stat.parity_err_cnt++;
-		}
+		if (err & 0x1)
+			swstats->parity_err_cnt++;
+
 		err_mask = err >> 48;
-		switch(err_mask) {
-			case 1:
-				sp->mac_control.stats_info->sw_stat.
-				rx_parity_err_cnt++;
+		switch (err_mask) {
+		case 1:
+			swstats->rx_parity_err_cnt++;
 			break;
 
-			case 2:
-				sp->mac_control.stats_info->sw_stat.
-				rx_abort_cnt++;
+		case 2:
+			swstats->rx_abort_cnt++;
 			break;
 
-			case 3:
-				sp->mac_control.stats_info->sw_stat.
-				rx_parity_abort_cnt++;
+		case 3:
+			swstats->rx_parity_abort_cnt++;
 			break;
 
-			case 4:
-				sp->mac_control.stats_info->sw_stat.
-				rx_rda_fail_cnt++;
+		case 4:
+			swstats->rx_rda_fail_cnt++;
 			break;
 
-			case 5:
-				sp->mac_control.stats_info->sw_stat.
-				rx_unkn_prot_cnt++;
+		case 5:
+			swstats->rx_unkn_prot_cnt++;
 			break;
 
-			case 6:
-				sp->mac_control.stats_info->sw_stat.
-				rx_fcs_err_cnt++;
+		case 6:
+			swstats->rx_fcs_err_cnt++;
 			break;
 
-			case 7:
-				sp->mac_control.stats_info->sw_stat.
-				rx_buf_size_err_cnt++;
+		case 7:
+			swstats->rx_buf_size_err_cnt++;
 			break;
 
-			case 8:
-				sp->mac_control.stats_info->sw_stat.
-				rx_rxd_corrupt_cnt++;
+		case 8:
+			swstats->rx_rxd_corrupt_cnt++;
 			break;
 
-			case 15:
-				sp->mac_control.stats_info->sw_stat.
-				rx_unkn_err_cnt++;
+		case 15:
+			swstats->rx_unkn_err_cnt++;
 			break;
 		}
 		/*
-		* Drop the packet if bad transfer code. Exception being
-		* 0x5, which could be due to unsupported IPv6 extension header.
-		* In this case, we let stack handle the packet.
-		* Note that in this case, since checksum will be incorrect,
-		* stack will validate the same.
-		*/
+		 * Drop the packet if bad transfer code. Exception being
+		 * 0x5, which could be due to unsupported IPv6 extension header.
+		 * In this case, we let stack handle the packet.
+		 * Note that in this case, since checksum will be incorrect,
+		 * stack will validate the same.
+		 */
 		if (err_mask != 0x5) {
 			DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%x\n",
-				dev->name, err_mask);
+				  dev->name, err_mask);
 			dev->stats.rx_crc_errors++;
-			sp->mac_control.stats_info->sw_stat.mem_freed
+			swstats->mem_freed
 				+= skb->truesize;
 			dev_kfree_skb(skb);
 			ring_data->rx_bufs_left -= 1;
@@ -7463,8 +7478,9 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 		skb_put(skb, buf2_len);
 	}
 
-	if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && ((!ring_data->lro) ||
-	    (ring_data->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) &&
+	if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
+	    ((!ring_data->lro) ||
+	     (ring_data->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) &&
 	    (sp->rx_csum)) {
 		l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
 		l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1);
@@ -7481,52 +7497,42 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 				int ret = 0;
 
 				ret = s2io_club_tcp_session(ring_data,
-					skb->data, &tcp, &tcp_len, &lro,
-					rxdp, sp);
+							    skb->data, &tcp,
+							    &tcp_len, &lro,
+							    rxdp, sp);
 				switch (ret) {
-					case 3: /* Begin anew */
-						lro->parent = skb;
-						goto aggregate;
-					case 1: /* Aggregate */
-					{
-						lro_append_pkt(sp, lro,
-							skb, tcp_len);
-						goto aggregate;
-					}
-					case 4: /* Flush session */
-					{
-						lro_append_pkt(sp, lro,
-							skb, tcp_len);
-						queue_rx_frame(lro->parent,
-							lro->vlan_tag);
-						clear_lro_session(lro);
-						sp->mac_control.stats_info->
-						    sw_stat.flush_max_pkts++;
-						goto aggregate;
-					}
-					case 2: /* Flush both */
-						lro->parent->data_len =
-							lro->frags_len;
-						sp->mac_control.stats_info->
-						     sw_stat.sending_both++;
-						queue_rx_frame(lro->parent,
-							lro->vlan_tag);
-						clear_lro_session(lro);
-						goto send_up;
-					case 0: /* sessions exceeded */
-					case -1: /* non-TCP or not
-						  * L2 aggregatable
-						  */
-					case 5: /*
-						 * First pkt in session not
-						 * L3/L4 aggregatable
-						 */
-						break;
-					default:
-						DBG_PRINT(ERR_DBG,
-							"%s: Samadhana!!\n",
-							 __func__);
-						BUG();
+				case 3: /* Begin anew */
+					lro->parent = skb;
+					goto aggregate;
+				case 1: /* Aggregate */
+					lro_append_pkt(sp, lro, skb, tcp_len);
+					goto aggregate;
+				case 4: /* Flush session */
+					lro_append_pkt(sp, lro, skb, tcp_len);
+					queue_rx_frame(lro->parent,
+						       lro->vlan_tag);
+					clear_lro_session(lro);
+					swstats->flush_max_pkts++;
+					goto aggregate;
+				case 2: /* Flush both */
+					lro->parent->data_len = lro->frags_len;
+					swstats->sending_both++;
+					queue_rx_frame(lro->parent,
+						       lro->vlan_tag);
+					clear_lro_session(lro);
+					goto send_up;
+				case 0: /* sessions exceeded */
+				case -1: /* non-TCP or not L2 aggregatable */
+				case 5: /*
+					 * First pkt in session not
+					 * L3/L4 aggregatable
+					 */
+					break;
+				default:
+					DBG_PRINT(ERR_DBG,
+						  "%s: Samadhana!!\n",
+						  __func__);
+					BUG();
 				}
 			}
 		} else {
@@ -7539,7 +7545,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 	} else
 		skb->ip_summed = CHECKSUM_NONE;
 
-	sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
+	swstats->mem_freed += skb->truesize;
 send_up:
 	skb_record_rx_queue(skb, ring_no);
 	queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
@@ -7561,9 +7567,10 @@ aggregate:
  *  void.
  */
 
-static void s2io_link(struct s2io_nic * sp, int link)
+static void s2io_link(struct s2io_nic *sp, int link)
 {
-	struct net_device *dev = (struct net_device *) sp->dev;
+	struct net_device *dev = (struct net_device *)sp->dev;
+	struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
 
 	if (link != sp->last_link_state) {
 		init_tti(sp, link);
@@ -7571,16 +7578,16 @@ static void s2io_link(struct s2io_nic * sp, int link)
 			DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
 			s2io_stop_all_tx_queue(sp);
 			netif_carrier_off(dev);
-			if(sp->mac_control.stats_info->sw_stat.link_up_cnt)
-			sp->mac_control.stats_info->sw_stat.link_up_time =
-				jiffies - sp->start_time;
-			sp->mac_control.stats_info->sw_stat.link_down_cnt++;
+			if (swstats->link_up_cnt)
+				swstats->link_up_time =
+					jiffies - sp->start_time;
+			swstats->link_down_cnt++;
 		} else {
 			DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
-			if (sp->mac_control.stats_info->sw_stat.link_down_cnt)
-			sp->mac_control.stats_info->sw_stat.link_down_time =
-				jiffies - sp->start_time;
-			sp->mac_control.stats_info->sw_stat.link_up_cnt++;
+			if (swstats->link_down_cnt)
+				swstats->link_down_time =
+					jiffies - sp->start_time;
+			swstats->link_up_cnt++;
 			netif_carrier_on(dev);
 			s2io_wake_all_tx_queue(sp);
 		}
@@ -7600,7 +7607,7 @@ static void s2io_link(struct s2io_nic * sp, int link)
  *  void
  */
 
-static void s2io_init_pci(struct s2io_nic * sp)
+static void s2io_init_pci(struct s2io_nic *sp)
 {
 	u16 pci_cmd = 0, pcix_cmd = 0;
 
@@ -7620,20 +7627,18 @@ static void s2io_init_pci(struct s2io_nic * sp)
 }
 
 static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
-	u8 *dev_multiq)
+			    u8 *dev_multiq)
 {
-	if ((tx_fifo_num > MAX_TX_FIFOS) ||
-		(tx_fifo_num < 1)) {
-		DBG_PRINT(ERR_DBG, "s2io: Requested number of tx fifos "
-			"(%d) not supported\n", tx_fifo_num);
+	if ((tx_fifo_num > MAX_TX_FIFOS) || (tx_fifo_num < 1)) {
+		DBG_PRINT(ERR_DBG, "Requested number of tx fifos "
+			  "(%d) not supported\n", tx_fifo_num);
 
 		if (tx_fifo_num < 1)
 			tx_fifo_num = 1;
 		else
 			tx_fifo_num = MAX_TX_FIFOS;
 
-		DBG_PRINT(ERR_DBG, "s2io: Default to %d ", tx_fifo_num);
-		DBG_PRINT(ERR_DBG, "tx fifos\n");
+		DBG_PRINT(ERR_DBG, "Default to %d tx fifos\n", tx_fifo_num);
 	}
 
 	if (multiq)
@@ -7642,44 +7647,44 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
 	if (tx_steering_type && (1 == tx_fifo_num)) {
 		if (tx_steering_type != TX_DEFAULT_STEERING)
 			DBG_PRINT(ERR_DBG,
-				"s2io: Tx steering is not supported with "
-				"one fifo. Disabling Tx steering.\n");
+				  "Tx steering is not supported with "
+				  "one fifo. Disabling Tx steering.\n");
 		tx_steering_type = NO_STEERING;
 	}
 
 	if ((tx_steering_type < NO_STEERING) ||
-		(tx_steering_type > TX_DEFAULT_STEERING)) {
-		DBG_PRINT(ERR_DBG, "s2io: Requested transmit steering not "
-			 "supported\n");
-		DBG_PRINT(ERR_DBG, "s2io: Disabling transmit steering\n");
+	    (tx_steering_type > TX_DEFAULT_STEERING)) {
+		DBG_PRINT(ERR_DBG,
+			  "Requested transmit steering not supported\n");
+		DBG_PRINT(ERR_DBG, "Disabling transmit steering\n");
 		tx_steering_type = NO_STEERING;
 	}
 
 	if (rx_ring_num > MAX_RX_RINGS) {
-		DBG_PRINT(ERR_DBG, "s2io: Requested number of rx rings not "
-			 "supported\n");
-		DBG_PRINT(ERR_DBG, "s2io: Default to %d rx rings\n",
-			MAX_RX_RINGS);
+		DBG_PRINT(ERR_DBG,
+			  "Requested number of rx rings not supported\n");
+		DBG_PRINT(ERR_DBG, "Default to %d rx rings\n",
+			  MAX_RX_RINGS);
 		rx_ring_num = MAX_RX_RINGS;
 	}
 
 	if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
-		DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. "
+		DBG_PRINT(ERR_DBG, "Wrong intr_type requested. "
 			  "Defaulting to INTA\n");
 		*dev_intr_type = INTA;
 	}
 
 	if ((*dev_intr_type == MSI_X) &&
-			((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
-			(pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
-		DBG_PRINT(ERR_DBG, "s2io: Xframe I does not support MSI_X. "
-					"Defaulting to INTA\n");
+	    ((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
+	     (pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
+		DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. "
+			  "Defaulting to INTA\n");
 		*dev_intr_type = INTA;
 	}
 
 	if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) {
-		DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n");
-		DBG_PRINT(ERR_DBG, "s2io: Defaulting to 1-buffer mode\n");
+		DBG_PRINT(ERR_DBG, "Requested ring mode not supported\n");
+		DBG_PRINT(ERR_DBG, "Defaulting to 1-buffer mode\n");
 		rx_ring_mode = 1;
 	}
 	return SUCCESS;
@@ -7712,8 +7717,8 @@ static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring)
 	writeq(val64, &bar0->rts_ds_mem_ctrl);
 
 	return wait_for_cmd_complete(&bar0->rts_ds_mem_ctrl,
-				RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
-				S2IO_BIT_RESET);
+				     RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
+				     S2IO_BIT_RESET);
 }
 
 static const struct net_device_ops s2io_netdev_ops = {
@@ -7759,8 +7764,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	u64 val64 = 0, tmp64 = 0;
 	struct XENA_dev_config __iomem *bar0 = NULL;
 	u16 subid;
-	struct mac_info *mac_control;
 	struct config_param *config;
+	struct mac_info *mac_control;
 	int mode;
 	u8 dev_intr_type = intr_type;
 	u8 dev_multiq = 0;
@@ -7769,31 +7774,33 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	if (ret)
 		return ret;
 
-	if ((ret = pci_enable_device(pdev))) {
+	ret = pci_enable_device(pdev);
+	if (ret) {
 		DBG_PRINT(ERR_DBG,
-			  "s2io_init_nic: pci_enable_device failed\n");
+			  "%s: pci_enable_device failed\n", __func__);
 		return ret;
 	}
 
 	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-		DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n");
+		DBG_PRINT(INIT_DBG, "%s: Using 64bit DMA\n", __func__);
 		dma_flag = true;
-		if (pci_set_consistent_dma_mask
-		    (pdev, DMA_BIT_MASK(64))) {
+		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
 			DBG_PRINT(ERR_DBG,
-				  "Unable to obtain 64bit DMA for \
-					consistent allocations\n");
+				  "Unable to obtain 64bit DMA "
+				  "for consistent allocations\n");
 			pci_disable_device(pdev);
 			return -ENOMEM;
 		}
 	} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 32bit DMA\n");
+		DBG_PRINT(INIT_DBG, "%s: Using 32bit DMA\n", __func__);
 	} else {
 		pci_disable_device(pdev);
 		return -ENOMEM;
 	}
-	if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
-		DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __func__, ret);
+	ret = pci_request_regions(pdev, s2io_driver_name);
+	if (ret) {
+		DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x\n",
+			  __func__, ret);
 		pci_disable_device(pdev);
 		return -ENODEV;
 	}
@@ -7827,7 +7834,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	sp->config.intr_type = dev_intr_type;
 
 	if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
-		(pdev->device == PCI_DEVICE_ID_HERC_UNI))
+	    (pdev->device == PCI_DEVICE_ID_HERC_UNI))
 		sp->device_type = XFRAME_II_DEVICE;
 	else
 		sp->device_type = XFRAME_I_DEVICE;
@@ -7844,8 +7851,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	 * these parameters are not not specified during load time, they
 	 * are initialized with default values.
 	 */
-	mac_control = &sp->mac_control;
 	config = &sp->config;
+	mac_control = &sp->mac_control;
 
 	config->napi = napi;
 	config->tx_steering_type = tx_steering_type;
@@ -7858,16 +7865,16 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	/* Initialize the fifos used for tx steering */
 	if (config->tx_fifo_num < 5) {
-			if (config->tx_fifo_num  == 1)
-				sp->total_tcp_fifos = 1;
-			else
-				sp->total_tcp_fifos = config->tx_fifo_num - 1;
-			sp->udp_fifo_idx = config->tx_fifo_num - 1;
-			sp->total_udp_fifos = 1;
-			sp->other_fifo_idx = sp->total_tcp_fifos - 1;
+		if (config->tx_fifo_num  == 1)
+			sp->total_tcp_fifos = 1;
+		else
+			sp->total_tcp_fifos = config->tx_fifo_num - 1;
+		sp->udp_fifo_idx = config->tx_fifo_num - 1;
+		sp->total_udp_fifos = 1;
+		sp->other_fifo_idx = sp->total_tcp_fifos - 1;
 	} else {
 		sp->total_tcp_fifos = (tx_fifo_num - FIFO_UDP_MAX_NUM -
-						FIFO_OTHER_MAX_NUM);
+				       FIFO_OTHER_MAX_NUM);
 		sp->udp_fifo_idx = sp->total_tcp_fifos;
 		sp->total_udp_fifos = FIFO_UDP_MAX_NUM;
 		sp->other_fifo_idx = sp->udp_fifo_idx + FIFO_UDP_MAX_NUM;
@@ -7875,8 +7882,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	config->multiq = dev_multiq;
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		config->tx_cfg[i].fifo_len = tx_fifo_len[i];
-		config->tx_cfg[i].fifo_priority = i;
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		tx_cfg->fifo_len = tx_fifo_len[i];
+		tx_cfg->fifo_priority = i;
 	}
 
 	/* mapping the QoS priority to the configured fifos */
@@ -7890,9 +7899,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	config->tx_intr_type = TXD_INT_TYPE_UTILZ;
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		config->tx_cfg[i].f_no_snoop =
-		    (NO_SNOOP_TXD | NO_SNOOP_TXD_BUFFER);
-		if (config->tx_cfg[i].fifo_len < 65) {
+		struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
+
+		tx_cfg->f_no_snoop = (NO_SNOOP_TXD | NO_SNOOP_TXD_BUFFER);
+		if (tx_cfg->fifo_len < 65) {
 			config->tx_intr_type = TXD_INT_TYPE_PER_LIST;
 			break;
 		}
@@ -7903,20 +7913,23 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	/* Rx side parameters. */
 	config->rx_ring_num = rx_ring_num;
 	for (i = 0; i < config->rx_ring_num; i++) {
-		config->rx_cfg[i].num_rxd = rx_ring_sz[i] *
-		    (rxd_count[sp->rxd_mode] + 1);
-		config->rx_cfg[i].ring_priority = i;
-		mac_control->rings[i].rx_bufs_left = 0;
-		mac_control->rings[i].rxd_mode = sp->rxd_mode;
-		mac_control->rings[i].rxd_count = rxd_count[sp->rxd_mode];
-		mac_control->rings[i].pdev = sp->pdev;
-		mac_control->rings[i].dev = sp->dev;
+		struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+		struct ring_info *ring = &mac_control->rings[i];
+
+		rx_cfg->num_rxd = rx_ring_sz[i] * (rxd_count[sp->rxd_mode] + 1);
+		rx_cfg->ring_priority = i;
+		ring->rx_bufs_left = 0;
+		ring->rxd_mode = sp->rxd_mode;
+		ring->rxd_count = rxd_count[sp->rxd_mode];
+		ring->pdev = sp->pdev;
+		ring->dev = sp->dev;
 	}
 
 	for (i = 0; i < rx_ring_num; i++) {
-		config->rx_cfg[i].ring_org = RING_ORG_BUFF1;
-		config->rx_cfg[i].f_no_snoop =
-		    (NO_SNOOP_RXD | NO_SNOOP_RXD_BUFFER);
+		struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
+
+		rx_cfg->ring_org = RING_ORG_BUFF1;
+		rx_cfg->f_no_snoop = (NO_SNOOP_RXD | NO_SNOOP_RXD_BUFFER);
 	}
 
 	/*  Setting Mac Control parameters */
@@ -7927,8 +7940,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	/*  initialize the shared memory used by the NIC and the host */
 	if (init_shared_mem(sp)) {
-		DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n",
-			  dev->name);
+		DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", dev->name);
 		ret = -ENOMEM;
 		goto mem_alloc_failed;
 	}
@@ -7950,12 +7962,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	}
 
 	dev->irq = pdev->irq;
-	dev->base_addr = (unsigned long) sp->bar0;
+	dev->base_addr = (unsigned long)sp->bar0;
 
 	/* Initializing the BAR1 address as the start of the FIFO pointer. */
 	for (j = 0; j < MAX_TX_FIFOS; j++) {
-		mac_control->tx_FIFO_start[j] = (struct TxFIFO_element __iomem *)
-		    (sp->bar1 + (j * 0x00020000));
+		mac_control->tx_FIFO_start[j] =
+			(struct TxFIFO_element __iomem *)
+			(sp->bar1 + (j * 0x00020000));
 	}
 
 	/*  Driver entry points */
@@ -7980,7 +7993,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	/* Setting swapper control on the NIC, for proper reset operation */
 	if (s2io_set_swapper(sp)) {
-		DBG_PRINT(ERR_DBG, "%s:swapper settings are wrong\n",
+		DBG_PRINT(ERR_DBG, "%s: swapper settings are wrong\n",
 			  dev->name);
 		ret = -EAGAIN;
 		goto set_swap_failed;
@@ -7990,8 +8003,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	if (sp->device_type & XFRAME_II_DEVICE) {
 		mode = s2io_verify_pci_mode(sp);
 		if (mode < 0) {
-			DBG_PRINT(ERR_DBG, "%s: ", __func__);
-			DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n");
+			DBG_PRINT(ERR_DBG, "%s: Unsupported PCI bus mode\n",
+				  __func__);
 			ret = -EBADSLT;
 			goto set_swap_failed;
 		}
@@ -8009,15 +8022,17 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 		if (ret) {
 
 			DBG_PRINT(ERR_DBG,
-			  "s2io: MSI-X requested but failed to enable\n");
+				  "MSI-X requested but failed to enable\n");
 			sp->config.intr_type = INTA;
 		}
 	}
 
 	if (config->intr_type ==  MSI_X) {
-		for (i = 0; i < config->rx_ring_num ; i++)
-			netif_napi_add(dev, &mac_control->rings[i].napi,
-				s2io_poll_msix, 64);
+		for (i = 0; i < config->rx_ring_num ; i++) {
+			struct ring_info *ring = &mac_control->rings[i];
+
+			netif_napi_add(dev, &ring->napi, s2io_poll_msix, 64);
+		}
 	} else {
 		netif_napi_add(dev, &sp->napi, s2io_poll_inta, 64);
 	}
@@ -8038,12 +8053,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	 */
 	bar0 = sp->bar0;
 	val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-	    RMAC_ADDR_CMD_MEM_OFFSET(0 + S2IO_MAC_ADDR_START_OFFSET);
+		RMAC_ADDR_CMD_MEM_OFFSET(0 + S2IO_MAC_ADDR_START_OFFSET);
 	writeq(val64, &bar0->rmac_addr_cmd_mem);
 	wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
-		      RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET);
+			      RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+			      S2IO_BIT_RESET);
 	tmp64 = readq(&bar0->rmac_addr_data0_mem);
-	mac_down = (u32) tmp64;
+	mac_down = (u32)tmp64;
 	mac_up = (u32) (tmp64 >> 32);
 
 	sp->def_mac_addr[0].mac_addr[3] = (u8) (mac_up);
@@ -8074,10 +8090,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	/* Configure MSIX vector for number of rings configured plus one */
 	if ((sp->device_type == XFRAME_II_DEVICE) &&
-		(config->intr_type == MSI_X))
+	    (config->intr_type == MSI_X))
 		sp->num_entries = config->rx_ring_num + 1;
 
-	 /* Store the values of the MSIX table in the s2io_nic structure */
+	/* Store the values of the MSIX table in the s2io_nic structure */
 	store_xmsi_data(sp);
 	/* reset Nic and bring it to known state */
 	s2io_reset(sp);
@@ -8089,8 +8105,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	sp->state = 0;
 
 	/* Initialize spinlocks */
-	for (i = 0; i < sp->config.tx_fifo_num; i++)
-		spin_lock_init(&mac_control->fifos[i].tx_lock);
+	for (i = 0; i < sp->config.tx_fifo_num; i++) {
+		struct fifo_info *fifo = &mac_control->fifos[i];
+
+		spin_lock_init(&fifo->tx_lock);
+	}
 
 	/*
 	 * SXE-002: Configure link and activity LED to init state
@@ -8102,7 +8121,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void __iomem *) bar0 + 0x2700);
+		writeq(val64, (void __iomem *)bar0 + 0x2700);
 		val64 = readq(&bar0->gpio_control);
 	}
 
@@ -8115,30 +8134,29 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	}
 	s2io_vpd_read(sp);
 	DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2007 Neterion Inc.\n");
-	DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name,
+	DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n", dev->name,
 		  sp->product_name, pdev->revision);
 	DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
 		  s2io_driver_version);
-	DBG_PRINT(ERR_DBG, "%s: MAC ADDR: %pM\n", dev->name, dev->dev_addr);
-	DBG_PRINT(ERR_DBG, "SERIAL NUMBER: %s\n", sp->serial_num);
+	DBG_PRINT(ERR_DBG, "%s: MAC Address: %pM\n", dev->name, dev->dev_addr);
+	DBG_PRINT(ERR_DBG, "Serial number: %s\n", sp->serial_num);
 	if (sp->device_type & XFRAME_II_DEVICE) {
 		mode = s2io_print_pci_mode(sp);
 		if (mode < 0) {
-			DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n");
 			ret = -EBADSLT;
 			unregister_netdev(dev);
 			goto set_swap_failed;
 		}
 	}
-	switch(sp->rxd_mode) {
-		case RXD_MODE_1:
-		    DBG_PRINT(ERR_DBG, "%s: 1-Buffer receive mode enabled\n",
-						dev->name);
-		    break;
-		case RXD_MODE_3B:
-		    DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n",
-						dev->name);
-		    break;
+	switch (sp->rxd_mode) {
+	case RXD_MODE_1:
+		DBG_PRINT(ERR_DBG, "%s: 1-Buffer receive mode enabled\n",
+			  dev->name);
+		break;
+	case RXD_MODE_3B:
+		DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n",
+			  dev->name);
+		break;
 	}
 
 	switch (sp->config.napi) {
@@ -8151,48 +8169,54 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	}
 
 	DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name,
-		sp->config.tx_fifo_num);
+		  sp->config.tx_fifo_num);
 
 	DBG_PRINT(ERR_DBG, "%s: Using %d Rx ring(s)\n", dev->name,
 		  sp->config.rx_ring_num);
 
-	switch(sp->config.intr_type) {
-		case INTA:
-		    DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
-		    break;
-		case MSI_X:
-		    DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
-		    break;
+	switch (sp->config.intr_type) {
+	case INTA:
+		DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
+		break;
+	case MSI_X:
+		DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
+		break;
 	}
 	if (sp->config.multiq) {
-		for (i = 0; i < sp->config.tx_fifo_num; i++)
-			mac_control->fifos[i].multiq = config->multiq;
+		for (i = 0; i < sp->config.tx_fifo_num; i++) {
+			struct fifo_info *fifo = &mac_control->fifos[i];
+
+			fifo->multiq = config->multiq;
+		}
 		DBG_PRINT(ERR_DBG, "%s: Multiqueue support enabled\n",
-			dev->name);
+			  dev->name);
 	} else
 		DBG_PRINT(ERR_DBG, "%s: Multiqueue support disabled\n",
-			dev->name);
+			  dev->name);
 
 	switch (sp->config.tx_steering_type) {
 	case NO_STEERING:
-		DBG_PRINT(ERR_DBG, "%s: No steering enabled for"
-			" transmit\n", dev->name);
-			break;
+		DBG_PRINT(ERR_DBG, "%s: No steering enabled for transmit\n",
+			  dev->name);
+		break;
 	case TX_PRIORITY_STEERING:
-		DBG_PRINT(ERR_DBG, "%s: Priority steering enabled for"
-			" transmit\n", dev->name);
+		DBG_PRINT(ERR_DBG,
+			  "%s: Priority steering enabled for transmit\n",
+			  dev->name);
 		break;
 	case TX_DEFAULT_STEERING:
-		DBG_PRINT(ERR_DBG, "%s: Default steering enabled for"
-			" transmit\n", dev->name);
+		DBG_PRINT(ERR_DBG,
+			  "%s: Default steering enabled for transmit\n",
+			  dev->name);
 	}
 
 	if (sp->lro)
 		DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
 			  dev->name);
 	if (ufo)
-		DBG_PRINT(ERR_DBG, "%s: UDP Fragmentation Offload(UFO)"
-					" enabled\n", dev->name);
+		DBG_PRINT(ERR_DBG,
+			  "%s: UDP Fragmentation Offload(UFO) enabled\n",
+			  dev->name);
 	/* Initialize device name */
 	sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name);
 
@@ -8210,13 +8234,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	return 0;
 
-      register_failed:
-      set_swap_failed:
+register_failed:
+set_swap_failed:
 	iounmap(sp->bar1);
-      bar1_remap_failed:
+bar1_remap_failed:
 	iounmap(sp->bar0);
-      bar0_remap_failed:
-      mem_alloc_failed:
+bar0_remap_failed:
+mem_alloc_failed:
 	free_shared_mem(sp);
 	pci_disable_device(pdev);
 	pci_release_regions(pdev);
@@ -8238,7 +8262,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 static void __devexit s2io_rem_nic(struct pci_dev *pdev)
 {
 	struct net_device *dev =
-	    (struct net_device *) pci_get_drvdata(pdev);
+		(struct net_device *)pci_get_drvdata(pdev);
 	struct s2io_nic *sp;
 
 	if (dev == NULL) {
@@ -8286,28 +8310,28 @@ module_init(s2io_starter);
 module_exit(s2io_closer);
 
 static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
-		struct tcphdr **tcp, struct RxD_t *rxdp,
-		struct s2io_nic *sp)
+				struct tcphdr **tcp, struct RxD_t *rxdp,
+				struct s2io_nic *sp)
 {
 	int ip_off;
 	u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len;
 
 	if (!(rxdp->Control_1 & RXD_FRAME_PROTO_TCP)) {
-		DBG_PRINT(INIT_DBG,"%s: Non-TCP frames not supported for LRO\n",
+		DBG_PRINT(INIT_DBG,
+			  "%s: Non-TCP frames not supported for LRO\n",
 			  __func__);
 		return -1;
 	}
 
 	/* Checking for DIX type or DIX type with VLAN */
-	if ((l2_type == 0)
-		|| (l2_type == 4)) {
+	if ((l2_type == 0) || (l2_type == 4)) {
 		ip_off = HEADER_ETHERNET_II_802_3_SIZE;
 		/*
 		 * If vlan stripping is disabled and the frame is VLAN tagged,
 		 * shift the offset by the VLAN header size bytes.
 		 */
 		if ((!sp->vlan_strip_flag) &&
-			(rxdp->Control_1 & RXD_FRAME_VLAN_TAG))
+		    (rxdp->Control_1 & RXD_FRAME_VLAN_TAG))
 			ip_off += HEADER_VLAN_SIZE;
 	} else {
 		/* LLC, SNAP etc are considered non-mergeable */
@@ -8325,22 +8349,25 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
 static int check_for_socket_match(struct lro *lro, struct iphdr *ip,
 				  struct tcphdr *tcp)
 {
-	DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
-	if ((lro->iph->saddr != ip->saddr) || (lro->iph->daddr != ip->daddr) ||
-	   (lro->tcph->source != tcp->source) || (lro->tcph->dest != tcp->dest))
+	DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
+	if ((lro->iph->saddr != ip->saddr) ||
+	    (lro->iph->daddr != ip->daddr) ||
+	    (lro->tcph->source != tcp->source) ||
+	    (lro->tcph->dest != tcp->dest))
 		return -1;
 	return 0;
 }
 
 static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp)
 {
-	return(ntohs(ip->tot_len) - (ip->ihl << 2) - (tcp->doff << 2));
+	return ntohs(ip->tot_len) - (ip->ihl << 2) - (tcp->doff << 2);
 }
 
 static void initiate_new_session(struct lro *lro, u8 *l2h,
-	struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag)
+				 struct iphdr *ip, struct tcphdr *tcp,
+				 u32 tcp_pyld_len, u16 vlan_tag)
 {
-	DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
+	DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
 	lro->l2h = l2h;
 	lro->iph = ip;
 	lro->tcph = tcp;
@@ -8351,9 +8378,9 @@ static void initiate_new_session(struct lro *lro, u8 *l2h,
 	lro->frags_len = 0;
 	lro->vlan_tag = vlan_tag;
 	/*
-	 * check if we saw TCP timestamp. Other consistency checks have
-	 * already been done.
- 	 */
+	 * Check if we saw TCP timestamp.
+	 * Other consistency checks have already been done.
+	 */
 	if (tcp->doff == 8) {
 		__be32 *ptr;
 		ptr = (__be32 *)(tcp+1);
@@ -8369,8 +8396,9 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
 	struct iphdr *ip = lro->iph;
 	struct tcphdr *tcp = lro->tcph;
 	__sum16 nchk;
-	struct stat_block *statinfo = sp->mac_control.stats_info;
-	DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
+	struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
+
+	DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
 
 	/* Update L3 header */
 	ip->tot_len = htons(lro->total_len);
@@ -8391,14 +8419,14 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
 	/* Update counters required for calculation of
 	 * average no. of packets aggregated.
 	 */
-	statinfo->sw_stat.sum_avg_pkts_aggregated += lro->sg_num;
-	statinfo->sw_stat.num_aggregations++;
+	swstats->sum_avg_pkts_aggregated += lro->sg_num;
+	swstats->num_aggregations++;
 }
 
 static void aggregate_new_rx(struct lro *lro, struct iphdr *ip,
-		struct tcphdr *tcp, u32 l4_pyld)
+			     struct tcphdr *tcp, u32 l4_pyld)
 {
-	DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
+	DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
 	lro->total_len += l4_pyld;
 	lro->frags_len += l4_pyld;
 	lro->tcp_next_seq += l4_pyld;
@@ -8422,7 +8450,7 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip,
 {
 	u8 *ptr;
 
-	DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
+	DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
 
 	if (!tcp_pyld_len) {
 		/* Runt frame or a pure ack */
@@ -8437,8 +8465,9 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip,
 		return -1;
 
 	/* If we see ECE or CWR flags in TCP header, packet is not mergeable */
-	if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin ||
-				    tcp->ece || tcp->cwr || !tcp->ack) {
+	if (tcp->urg || tcp->psh || tcp->rst ||
+	    tcp->syn || tcp->fin ||
+	    tcp->ece || tcp->cwr || !tcp->ack) {
 		/*
 		 * Currently recognize only the ack control word and
 		 * any other control field being set would result in
@@ -8474,27 +8503,27 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip,
 	return 0;
 }
 
-static int
-s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
-	u32 *tcp_len, struct lro **lro, struct RxD_t *rxdp,
-	struct s2io_nic *sp)
+static int s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer,
+				 u8 **tcp, u32 *tcp_len, struct lro **lro,
+				 struct RxD_t *rxdp, struct s2io_nic *sp)
 {
 	struct iphdr *ip;
 	struct tcphdr *tcph;
 	int ret = 0, i;
 	u16 vlan_tag = 0;
+	struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
 
-	if (!(ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp,
-					 rxdp, sp))) {
-		DBG_PRINT(INFO_DBG,"IP Saddr: %x Daddr: %x\n",
-			  ip->saddr, ip->daddr);
-	} else
+	ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp,
+				   rxdp, sp);
+	if (ret)
 		return ret;
 
+	DBG_PRINT(INFO_DBG, "IP Saddr: %x Daddr: %x\n", ip->saddr, ip->daddr);
+
 	vlan_tag = RXD_GET_VLAN_TAG(rxdp->Control_2);
 	tcph = (struct tcphdr *)*tcp;
 	*tcp_len = get_l4_pyld_length(ip, tcph);
-	for (i=0; i<MAX_LRO_SESSIONS; i++) {
+	for (i = 0; i < MAX_LRO_SESSIONS; i++) {
 		struct lro *l_lro = &ring_data->lro0_n[i];
 		if (l_lro->in_use) {
 			if (check_for_socket_match(l_lro, ip, tcph))
@@ -8503,18 +8532,19 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
 			*lro = l_lro;
 
 			if ((*lro)->tcp_next_seq != ntohl(tcph->seq)) {
-				DBG_PRINT(INFO_DBG, "%s:Out of order. expected "
-					  "0x%x, actual 0x%x\n", __func__,
+				DBG_PRINT(INFO_DBG, "%s: Out of sequence. "
+					  "expected 0x%x, actual 0x%x\n",
+					  __func__,
 					  (*lro)->tcp_next_seq,
 					  ntohl(tcph->seq));
 
-				sp->mac_control.stats_info->
-				   sw_stat.outof_sequence_pkts++;
+				swstats->outof_sequence_pkts++;
 				ret = 2;
 				break;
 			}
 
-			if (!verify_l3_l4_lro_capable(l_lro, ip, tcph,*tcp_len))
+			if (!verify_l3_l4_lro_capable(l_lro, ip, tcph,
+						      *tcp_len))
 				ret = 1; /* Aggregate */
 			else
 				ret = 2; /* Flush both */
@@ -8528,11 +8558,10 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
 		 * don't create new LRO session. Just send this
 		 * packet up.
 		 */
-		if (verify_l3_l4_lro_capable(NULL, ip, tcph, *tcp_len)) {
+		if (verify_l3_l4_lro_capable(NULL, ip, tcph, *tcp_len))
 			return 5;
-		}
 
-		for (i=0; i<MAX_LRO_SESSIONS; i++) {
+		for (i = 0; i < MAX_LRO_SESSIONS; i++) {
 			struct lro *l_lro = &ring_data->lro0_n[i];
 			if (!(l_lro->in_use)) {
 				*lro = l_lro;
@@ -8543,31 +8572,30 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
 	}
 
 	if (ret == 0) { /* sessions exceeded */
-		DBG_PRINT(INFO_DBG,"%s:All LRO sessions already in use\n",
+		DBG_PRINT(INFO_DBG, "%s: All LRO sessions already in use\n",
 			  __func__);
 		*lro = NULL;
 		return ret;
 	}
 
 	switch (ret) {
-		case 3:
-			initiate_new_session(*lro, buffer, ip, tcph, *tcp_len,
-								vlan_tag);
-			break;
-		case 2:
+	case 3:
+		initiate_new_session(*lro, buffer, ip, tcph, *tcp_len,
+				     vlan_tag);
+		break;
+	case 2:
+		update_L3L4_header(sp, *lro);
+		break;
+	case 1:
+		aggregate_new_rx(*lro, ip, tcph, *tcp_len);
+		if ((*lro)->sg_num == sp->lro_max_aggr_per_sess) {
 			update_L3L4_header(sp, *lro);
-			break;
-		case 1:
-			aggregate_new_rx(*lro, ip, tcph, *tcp_len);
-			if ((*lro)->sg_num == sp->lro_max_aggr_per_sess) {
-				update_L3L4_header(sp, *lro);
-				ret = 4; /* Flush the LRO */
-			}
-			break;
-		default:
-			DBG_PRINT(ERR_DBG,"%s:Dont know, can't say!!\n",
-				__func__);
-			break;
+			ret = 4; /* Flush the LRO */
+		}
+		break;
+	default:
+		DBG_PRINT(ERR_DBG, "%s: Don't know, can't say!!\n", __func__);
+		break;
 	}
 
 	return ret;
@@ -8586,8 +8614,7 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
 	struct s2io_nic *sp = netdev_priv(dev);
 
 	skb->protocol = eth_type_trans(skb, dev);
-	if (sp->vlgrp && vlan_tag
-		&& (sp->vlan_strip_flag)) {
+	if (sp->vlgrp && vlan_tag && (sp->vlan_strip_flag)) {
 		/* Queueing the vlan frame to the upper layer */
 		if (sp->config.napi)
 			vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag);
@@ -8602,10 +8629,10 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
 }
 
 static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
-			   struct sk_buff *skb,
-			   u32 tcp_len)
+			   struct sk_buff *skb, u32 tcp_len)
 {
 	struct sk_buff *first = lro->parent;
+	struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
 
 	first->len += tcp_len;
 	first->data_len = lro->frags_len;
@@ -8616,7 +8643,7 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
 		skb_shinfo(first)->frag_list = skb;
 	first->truesize += skb->truesize;
 	lro->last_frag = skb;
-	sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++;
+	swstats->clubbed_frms_cnt++;
 	return;
 }
 
@@ -8629,13 +8656,16 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
  * this device has been detected.
  */
 static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
-                                               pci_channel_state_t state)
+					       pci_channel_state_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct s2io_nic *sp = netdev_priv(netdev);
 
 	netif_device_detach(netdev);
 
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	if (netif_running(netdev)) {
 		/* Bring down the card, while avoiding PCI I/O */
 		do_s2io_card_down(sp, 0);
@@ -8660,8 +8690,7 @@ static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev)
 	struct s2io_nic *sp = netdev_priv(netdev);
 
 	if (pci_enable_device(pdev)) {
-		printk(KERN_ERR "s2io: "
-		       "Cannot re-enable PCI device after reset.\n");
+		pr_err("Cannot re-enable PCI device after reset.\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
@@ -8685,15 +8714,13 @@ static void s2io_io_resume(struct pci_dev *pdev)
 
 	if (netif_running(netdev)) {
 		if (s2io_card_up(sp)) {
-			printk(KERN_ERR "s2io: "
-			       "Can't bring device back up after reset.\n");
+			pr_err("Can't bring device back up after reset.\n");
 			return;
 		}
 
 		if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) {
 			s2io_card_down(sp);
-			printk(KERN_ERR "s2io: "
-			       "Can't resetore mac addr after reset.\n");
+			pr_err("Can't restore mac addr after reset.\n");
 			return;
 		}
 	}
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index d5c5be6..47c36e0 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -64,7 +64,10 @@ enum {
 static int debug_level = ERR_DBG;
 
 /* DEBUG message print. */
-#define DBG_PRINT(dbg_level, args...)  if(!(debug_level<dbg_level)) printk(args)
+#define DBG_PRINT(dbg_level, fmt, args...) do {			\
+	if (dbg_level >= debug_level)				\
+		pr_info(fmt, ##args);				\
+	} while (0)
 
 /* Protocol assist features of the NIC */
 #define L3_CKSUM_OK 0xFFFF
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index fc0e38b..ee366c5 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -82,7 +82,8 @@ struct sb1000_private {
 extern int sb1000_probe(struct net_device *dev);
 static int sb1000_open(struct net_device *dev);
 static int sb1000_dev_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
-static int sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t sb1000_start_xmit(struct sk_buff *skb,
+				     struct net_device *dev);
 static irqreturn_t sb1000_interrupt(int irq, void *dev_id);
 static int sb1000_close(struct net_device *dev);
 
@@ -1080,13 +1081,13 @@ static int sb1000_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 }
 
 /* transmit function: do nothing since SB1000 can't send anything out */
-static int
+static netdev_tx_t
 sb1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	printk(KERN_WARNING "%s: trying to transmit!!!\n", dev->name);
 	/* sb1000 can't xmit datagrams */
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* SB1000 interrupt handler. */
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index d8c9cf1..508551f 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2091,7 +2091,7 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irqrestore(&sc->sbm_lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**********************************************************************
@@ -2688,7 +2688,7 @@ static int sbmac_poll(struct napi_struct *napi, int budget)
 }
 
 
-static int __init sbmac_probe(struct platform_device *pldev)
+static int __devinit sbmac_probe(struct platform_device *pldev)
 {
 	struct net_device *dev;
 	struct sbmac_softc *sc;
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index e3156c9..8d60300 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -941,7 +941,8 @@ static struct net_device_stats *sc92031_get_stats(struct net_device *dev)
 	return &dev->stats;
 }
 
-static int sc92031_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sc92031_start_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct sc92031_priv *priv = netdev_priv(dev);
 	void __iomem *port_base = priv->port_base;
diff --git a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
index ebbbe09..39246d4 100644
--- a/drivers/net/seeq8005.c
+++ b/drivers/net/seeq8005.c
@@ -81,7 +81,8 @@ struct net_local {
 static int seeq8005_probe1(struct net_device *dev, int ioaddr);
 static int seeq8005_open(struct net_device *dev);
 static void seeq8005_timeout(struct net_device *dev);
-static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
+					struct net_device *dev);
 static irqreturn_t seeq8005_interrupt(int irq, void *dev_id);
 static void seeq8005_rx(struct net_device *dev);
 static int seeq8005_close(struct net_device *dev);
@@ -394,14 +395,15 @@ static void seeq8005_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
+					struct net_device *dev)
 {
 	short length = skb->len;
 	unsigned char *buf;
 
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 	buf = skb->data;
@@ -415,7 +417,7 @@ static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb (skb);
 	/* You might need to clean up and record Tx statistics here. */
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 343e8da..07a7e4b 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1179,6 +1179,8 @@ static void efx_stop_all(struct efx_nic *efx)
 
 	/* Isolate the MAC from the TX and RX engines, so that queue
 	 * flushes will complete in a timely fashion. */
+	falcon_deconfigure_mac_wrapper(efx);
+	msleep(10); /* Let the Rx FIFO drain */
 	falcon_drain_tx_fifo(efx);
 
 	/* Stop the kernel transmit interface late, so the watchdog
@@ -1614,21 +1616,24 @@ static int efx_register_netdev(struct efx_nic *efx)
 	SET_NETDEV_DEV(net_dev, &efx->pci_dev->dev);
 	SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops);
 
-	/* Always start with carrier off; PHY events will detect the link */
-	netif_carrier_off(efx->net_dev);
-
 	/* Clear MAC statistics */
 	efx->mac_op->update_stats(efx);
 	memset(&efx->mac_stats, 0, sizeof(efx->mac_stats));
 
-	rc = register_netdev(net_dev);
-	if (rc) {
-		EFX_ERR(efx, "could not register net dev\n");
-		return rc;
-	}
-
 	rtnl_lock();
+
+	rc = dev_alloc_name(net_dev, net_dev->name);
+	if (rc < 0)
+		goto fail_locked;
 	efx_update_name(efx);
+
+	rc = register_netdevice(net_dev);
+	if (rc)
+		goto fail_locked;
+
+	/* Always start with carrier off; PHY events will detect the link */
+	netif_carrier_off(efx->net_dev);
+
 	rtnl_unlock();
 
 	rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_type);
@@ -1639,6 +1644,11 @@ static int efx_register_netdev(struct efx_nic *efx)
 
 	return 0;
 
+fail_locked:
+	rtnl_unlock();
+	EFX_ERR(efx, "could not register net dev\n");
+	return rc;
+
 fail_registered:
 	unregister_netdev(net_dev);
 	return rc;
diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index da157aa..aecaf62 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -20,8 +20,9 @@
 #define FALCON_B_P_DEVID        0x0710
 
 /* TX */
-extern int efx_xmit(struct efx_nic *efx,
-		    struct efx_tx_queue *tx_queue, struct sk_buff *skb);
+extern netdev_tx_t efx_xmit(struct efx_nic *efx,
+				  struct efx_tx_queue *tx_queue,
+				  struct sk_buff *skb);
 extern void efx_stop_queue(struct efx_nic *efx);
 extern void efx_wake_queue(struct efx_nic *efx);
 
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 997ea2a..45018f2 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -731,7 +731,7 @@ static void efx_ethtool_get_pauseparam(struct net_device *net_dev,
 }
 
 
-struct ethtool_ops efx_ethtool_ops = {
+const struct ethtool_ops efx_ethtool_ops = {
 	.get_settings		= efx_ethtool_get_settings,
 	.set_settings		= efx_ethtool_set_settings,
 	.get_drvinfo		= efx_ethtool_get_drvinfo,
diff --git a/drivers/net/sfc/ethtool.h b/drivers/net/sfc/ethtool.h
index 3628e43..295ead4 100644
--- a/drivers/net/sfc/ethtool.h
+++ b/drivers/net/sfc/ethtool.h
@@ -22,6 +22,6 @@ extern int efx_ethtool_get_settings(struct net_device *net_dev,
 extern int efx_ethtool_set_settings(struct net_device *net_dev,
 				    struct ethtool_cmd *ecmd);
 
-extern struct ethtool_ops efx_ethtool_ops;
+extern const struct ethtool_ops efx_ethtool_ops;
 
 #endif /* EFX_ETHTOOL_H */
diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h
index 375e2a5..2d22611 100644
--- a/drivers/net/sfc/falcon_hwdefs.h
+++ b/drivers/net/sfc/falcon_hwdefs.h
@@ -700,6 +700,8 @@
 /* XGXS/XAUI powerdown/reset register */
 #define XX_PWR_RST_REG 0x1300
 
+#define XX_SD_RST_ACT_LBN 16
+#define XX_SD_RST_ACT_WIDTH 1
 #define XX_PWRDND_EN_LBN 15
 #define XX_PWRDND_EN_WIDTH 1
 #define XX_PWRDNC_EN_LBN 14
diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c
index 2b3269c..bec52ca 100644
--- a/drivers/net/sfc/falcon_xmac.c
+++ b/drivers/net/sfc/falcon_xmac.c
@@ -64,13 +64,15 @@ int falcon_reset_xaui(struct efx_nic *efx)
 	efx_oword_t reg;
 	int count;
 
+	/* Start reset sequence */
 	EFX_POPULATE_DWORD_1(reg, XX_RST_XX_EN, 1);
 	falcon_write(efx, &reg, XX_PWR_RST_REG);
 
-	/* Give some time for the link to establish */
-	for (count = 0; count < 1000; count++) { /* wait upto 10ms */
+	/* Wait up to 10 ms for completion, then reinitialise */
+	for (count = 0; count < 1000; count++) {
 		falcon_read(efx, &reg, XX_PWR_RST_REG);
-		if (EFX_OWORD_FIELD(reg, XX_RST_XX_EN) == 0) {
+		if (EFX_OWORD_FIELD(reg, XX_RST_XX_EN) == 0 &&
+		    EFX_OWORD_FIELD(reg, XX_SD_RST_ACT) == 0) {
 			falcon_setup_xaui(efx);
 			return 0;
 		}
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h
index 5eabede..298566d 100644
--- a/drivers/net/sfc/net_driver.h
+++ b/drivers/net/sfc/net_driver.h
@@ -984,9 +984,14 @@ static inline void clear_bit_le(unsigned nr, unsigned char *addr)
  *
  * The 10G MAC used in Falcon requires 8-byte alignment on the frame
  * length, so we round up to the nearest 8.
+ *
+ * Re-clocking by the XGXS on RX can reduce an IPG to 32 bits (half an
+ * XGMII cycle).  If the frame length reaches the maximum value in the
+ * same cycle, the XMAC can miss the IPG altogether.  We work around
+ * this by adding a further 16 bytes.
  */
 #define EFX_MAX_FRAME_LEN(mtu) \
-	((((mtu) + ETH_HLEN + VLAN_HLEN + 4/* FCS */) + 7) & ~7)
+	((((mtu) + ETH_HLEN + VLAN_HLEN + 4/* FCS */ + 7) & ~7) + 16)
 
 
 #endif /* EFX_NET_DRIVER_H */
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c
index b67ccca..817c7ef 100644
--- a/drivers/net/sfc/selftest.c
+++ b/drivers/net/sfc/selftest.c
@@ -400,7 +400,8 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
 	struct efx_loopback_state *state = efx->loopback_selftest;
 	struct efx_loopback_payload *payload;
 	struct sk_buff *skb;
-	int i, rc;
+	int i;
+	netdev_tx_t rc;
 
 	/* Transmit N copies of buffer */
 	for (i = 0; i < state->packet_count; i++) {
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index 14a1478..489c4de 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -138,8 +138,8 @@ static void efx_tsoh_free(struct efx_tx_queue *tx_queue,
  * Returns NETDEV_TX_OK or NETDEV_TX_BUSY
  * You must hold netif_tx_lock() to call this function.
  */
-static int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
-			   struct sk_buff *skb)
+static netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue,
+					 struct sk_buff *skb)
 {
 	struct efx_nic *efx = tx_queue->efx;
 	struct pci_dev *pci_dev = efx->pci_dev;
@@ -152,7 +152,7 @@ static int efx_enqueue_skb(struct efx_tx_queue *tx_queue,
 	unsigned int dma_len;
 	bool unmap_single;
 	int q_space, i = 0;
-	int rc = NETDEV_TX_OK;
+	netdev_tx_t rc = NETDEV_TX_OK;
 
 	EFX_BUG_ON_PARANOID(tx_queue->write_count != tx_queue->insert_count);
 
@@ -353,14 +353,11 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
  *
  * Context: netif_tx_lock held
  */
-inline int efx_xmit(struct efx_nic *efx,
-		    struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+inline netdev_tx_t efx_xmit(struct efx_nic *efx,
+			   struct efx_tx_queue *tx_queue, struct sk_buff *skb)
 {
-	int rc;
-
 	/* Map fragments for DMA and add to TX queue */
-	rc = efx_enqueue_skb(tx_queue, skb);
-	return rc;
+	return efx_enqueue_skb(tx_queue, skb);
 }
 
 /* Initiate a packet transmission.  We use one channel per CPU
@@ -372,7 +369,8 @@ inline int efx_xmit(struct efx_nic *efx,
  * Note that returning anything other than NETDEV_TX_OK will cause the
  * OS to free the skb.
  */
-int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
+netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
+				      struct net_device *net_dev)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
 	struct efx_tx_queue *tx_queue;
diff --git a/drivers/net/sfc/tx.h b/drivers/net/sfc/tx.h
index 5e1cc23..e367896 100644
--- a/drivers/net/sfc/tx.h
+++ b/drivers/net/sfc/tx.h
@@ -18,7 +18,8 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue);
 void efx_init_tx_queue(struct efx_tx_queue *tx_queue);
 void efx_fini_tx_queue(struct efx_tx_queue *tx_queue);
 
-int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
+netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
+				      struct net_device *net_dev);
 void efx_release_tx_buffers(struct efx_tx_queue *tx_queue);
 
 #endif /* EFX_TX_H */
diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c
index bb2e6af..e6b3d5e 100644
--- a/drivers/net/sfc/xfp_phy.c
+++ b/drivers/net/sfc/xfp_phy.c
@@ -97,23 +97,24 @@ static int qt2025c_wait_reset(struct efx_nic *efx)
 	return 0;
 }
 
-/* Reset the PHYXS MMD. This is documented (for the Quake PHYs) as doing
- * a complete soft reset.
- */
 static int xfp_reset_phy(struct efx_nic *efx)
 {
 	int rc;
 
-	rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
-				XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
-				XFP_RESET_WAIT);
-	if (rc < 0)
-		goto fail;
-
 	if (efx->phy_type == PHY_TYPE_QT2025C) {
+		/* Wait for the reset triggered by falcon_reset_hw()
+		 * to complete */
 		rc = qt2025c_wait_reset(efx);
 		if (rc < 0)
 			goto fail;
+	} else {
+		/* Reset the PHYXS MMD. This is documented as doing
+		 * a complete soft reset. */
+		rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
+					XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
+					XFP_RESET_WAIT);
+		if (rc < 0)
+			goto fail;
 	}
 
 	/* Wait 250ms for the PHY to complete bootup */
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 5fb88ca..ecf3279 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -594,7 +594,7 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	len = skb->len;
 	if (len < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		len = ETH_ZLEN;
 	}
 
@@ -642,7 +642,7 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 	spin_unlock_irqrestore(&sp->tx_lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void timeout(struct net_device *dev)
@@ -720,7 +720,7 @@ static const struct net_device_ops sgiseeq_netdev_ops = {
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
-static int __init sgiseeq_probe(struct platform_device *pdev)
+static int __devinit sgiseeq_probe(struct platform_device *pdev)
 {
 	struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
 	struct hpc3_regs *hpcregs = pd->hpc;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index a2d82dd..f49d080 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -772,13 +772,15 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 			mdp->stats.tx_carrier_errors++;
 		if (felic_stat & ECSR_LCHNG) {
 			/* Link Changed */
-			if (mdp->cd->no_psr) {
+			if (mdp->cd->no_psr || mdp->no_ether_link) {
 				if (mdp->link == PHY_DOWN)
 					link_stat = 0;
 				else
 					link_stat = PHY_ST_LINK;
 			} else {
 				link_stat = (ctrl_inl(ioaddr + PSR));
+				if (mdp->ether_link_active_low)
+					link_stat = ~link_stat;
 			}
 			if (!(link_stat & PHY_ST_LINK)) {
 				/* Link Down : disable tx and rx */
@@ -1133,7 +1135,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	ndev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* device close function */
@@ -1410,6 +1412,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	mdp->phy_id = pd->phy;
 	/* EDMAC endian */
 	mdp->edmac_endian = pd->edmac_endian;
+	mdp->no_ether_link = pd->no_ether_link;
+	mdp->ether_link_active_low = pd->ether_link_active_low;
 
 	/* set cpu data */
 	mdp->cd = &sh_eth_my_cpu_data;
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 9afe5b4..ba151f8 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -729,6 +729,9 @@ struct sh_eth_private {
 	char post_rx;		/* POST receive */
 	char post_fw;		/* POST forward */
 	struct net_device_stats tsu_stats;	/* TSU forward status */
+
+	unsigned no_ether_link:1;
+	unsigned ether_link_active_low:1;
 };
 
 static inline void sh_eth_soft_swap(char *src, int len)
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 1f040e8..7cc9898 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1168,7 +1168,8 @@ static int sis190_close(struct net_device *dev)
 	return 0;
 }
 
-static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sis190_start_xmit(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct sis190_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index a9a897b..97949d0 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -214,7 +214,8 @@ static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_p
 static void sis900_tx_timeout(struct net_device *net_dev);
 static void sis900_init_tx_ring(struct net_device *net_dev);
 static void sis900_init_rx_ring(struct net_device *net_dev);
-static int sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
+static netdev_tx_t sis900_start_xmit(struct sk_buff *skb,
+				     struct net_device *net_dev);
 static int sis900_rx(struct net_device *net_dev);
 static void sis900_finish_xmit (struct net_device *net_dev);
 static irqreturn_t sis900_interrupt(int irq, void *dev_instance);
@@ -1571,7 +1572,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
  *	tell upper layer if the buffer is full
  */
 
-static int
+static netdev_tx_t
 sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 {
 	struct sis900_private *sis_priv = netdev_priv(net_dev);
@@ -1628,7 +1629,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 		       "to slot %d.\n",
 		       net_dev->name, skb->data, (int)skb->len, entry);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /**
@@ -2127,8 +2128,6 @@ static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
 		return 0;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		mdio_write(net_dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
 		return 0;
 	default:
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 088fe26..38a508b 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -107,7 +107,8 @@ static void skfp_ctl_set_multicast_list(struct net_device *dev);
 static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev);
 static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr);
 static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t skfp_send_pkt(struct sk_buff *skb,
+				       struct net_device *dev);
 static void send_queued_packets(struct s_smc *smc);
 static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr);
 static void ResetAdapter(struct s_smc *smc);
@@ -1056,7 +1057,8 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  * Side Effects:
  *   None
  */
-static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t skfp_send_pkt(struct sk_buff *skb,
+				       struct net_device *dev)
 {
 	struct s_smc *smc = netdev_priv(dev);
 	skfddi_priv *bp = &smc->os;
@@ -1077,7 +1079,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
 		// dequeue packets from xmt queue and send them
 		netif_start_queue(dev);
 		dev_kfree_skb(skb);
-		return (0);	/* return "success" */
+		return NETDEV_TX_OK;	/* return "success" */
 	}
 	if (bp->QueueSkb == 0) {	// return with tbusy set: queue full
 
@@ -1091,7 +1093,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 	}
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 
 }				// skfp_send_pkt
 
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 543af20..62e852e 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2496,9 +2496,6 @@ static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	}
 
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		spin_lock_bh(&hw->phy_lock);
 		if (hw->chip_id == CHIP_ID_GENESIS)
 			err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
@@ -2746,7 +2743,8 @@ static inline int skge_avail(const struct skge_ring *ring)
 		+ (ring->to_clean - ring->to_use) - 1;
 }
 
-static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
+				   struct net_device *dev)
 {
 	struct skge_port *skge = netdev_priv(dev);
 	struct skge_hw *hw = skge->hw;
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 0a551d8..4bb52e9 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -50,7 +50,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.23"
+#define DRV_VERSION		"1.25"
 #define PFX			DRV_NAME " "
 
 /*
@@ -64,10 +64,12 @@
 #define RX_MAX_PENDING		(RX_LE_SIZE/6 - 2)
 #define RX_DEF_PENDING		RX_MAX_PENDING
 
-#define TX_RING_SIZE		512
-#define TX_DEF_PENDING		128
-#define MAX_SKB_TX_LE		(4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS)
+/* This is the worst case number of transmit list elements for a single skb:
+   VLAN:GSO + CKSUM + Data + skb_frags * DMA */
+#define MAX_SKB_TX_LE	(2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1))
 #define TX_MIN_PENDING		(MAX_SKB_TX_LE+1)
+#define TX_MAX_PENDING		4096
+#define TX_DEF_PENDING		127
 
 #define STATUS_RING_SIZE	2048	/* 2 ports * (TX + 2*RX) */
 #define STATUS_LE_BYTES		(STATUS_RING_SIZE*sizeof(struct sky2_status_le))
@@ -254,6 +256,9 @@ static void sky2_power_on(struct sky2_hw *hw)
 
 		sky2_read32(hw, B2_GP_IO);
 	}
+
+	/* Turn on "driver loaded" LED */
+	sky2_write16(hw, B0_CTST, Y2_LED_STAT_ON);
 }
 
 static void sky2_power_aux(struct sky2_hw *hw)
@@ -267,11 +272,15 @@ static void sky2_power_aux(struct sky2_hw *hw)
 			    Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
 			    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
 
-	/* switch power to VAUX */
-	if (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL)
+	/* switch power to VAUX if supported and PME from D3cold */
+	if ( (sky2_read32(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+	     pci_pme_capable(hw->pdev, PCI_D3cold))
 		sky2_write8(hw, B0_POWER_CTRL,
 			    (PC_VAUX_ENA | PC_VCC_ENA |
 			     PC_VAUX_ON | PC_VCC_OFF));
+
+	/* turn off "driver loaded LED" */
+	sky2_write16(hw, B0_CTST, Y2_LED_STAT_OFF);
 }
 
 static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
@@ -321,7 +330,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
 	u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg;
 
-	if (sky2->autoneg == AUTONEG_ENABLE &&
+	if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) &&
 	    !(hw->flags & SKY2_HW_NEWER_PHY)) {
 		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
 
@@ -363,7 +372,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
 
 			/* downshift on PHY 88E1112 and 88E1149 is changed */
-			if (sky2->autoneg == AUTONEG_ENABLE
+			if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED)
 			    && (hw->flags & SKY2_HW_NEWER_PHY)) {
 				/* set downshift counter to 3x and enable downshift */
 				ctrl &= ~PHY_M_PC_DSC_MSK;
@@ -408,7 +417,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 	adv = PHY_AN_CSMA;
 	reg = 0;
 
-	if (sky2->autoneg == AUTONEG_ENABLE) {
+	if (sky2->flags & SKY2_FLAG_AUTO_SPEED) {
 		if (sky2_is_copper(hw)) {
 			if (sky2->advertising & ADVERTISED_1000baseT_Full)
 				ct1000 |= PHY_M_1000C_AFD;
@@ -423,14 +432,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 			if (sky2->advertising & ADVERTISED_10baseT_Half)
 				adv |= PHY_M_AN_10_HD;
 
-			adv |= copper_fc_adv[sky2->flow_mode];
 		} else {	/* special defines for FIBER (88E1040S only) */
 			if (sky2->advertising & ADVERTISED_1000baseT_Full)
 				adv |= PHY_M_AN_1000X_AFD;
 			if (sky2->advertising & ADVERTISED_1000baseT_Half)
 				adv |= PHY_M_AN_1000X_AHD;
-
-			adv |= fiber_fc_adv[sky2->flow_mode];
 		}
 
 		/* Restart Auto-negotiation */
@@ -439,8 +445,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 		/* forced speed/duplex settings */
 		ct1000 = PHY_M_1000C_MSE;
 
-		/* Disable auto update for duplex flow control and speed */
-		reg |= GM_GPCR_AU_ALL_DIS;
+		/* Disable auto update for duplex flow control and duplex */
+		reg |= GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_SPD_DIS;
 
 		switch (sky2->speed) {
 		case SPEED_1000:
@@ -458,8 +464,15 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 			ctrl |= PHY_CT_DUP_MD;
 		} else if (sky2->speed < SPEED_1000)
 			sky2->flow_mode = FC_NONE;
+	}
 
-
+	if (sky2->flags & SKY2_FLAG_AUTO_PAUSE) {
+		if (sky2_is_copper(hw))
+			adv |= copper_fc_adv[sky2->flow_mode];
+		else
+			adv |= fiber_fc_adv[sky2->flow_mode];
+	} else {
+		reg |= GM_GPCR_AU_FCT_DIS;
  		reg |= gm_fc_disable[sky2->flow_mode];
 
 		/* Forward pause packets to GMAC? */
@@ -594,7 +607,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 		/* no effect on Yukon-XL */
 		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
 
-		if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
+		if ( !(sky2->flags & SKY2_FLAG_AUTO_SPEED)
+		     || sky2->speed == SPEED_100) {
 			/* turn on 100 Mbps LED (LED_LINK100) */
 			ledover |= PHY_M_LED_MO_100(MO_LED_ON);
 		}
@@ -605,7 +619,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 	}
 
 	/* Enable phy interrupt on auto-negotiation complete (or link up) */
-	if (sky2->autoneg == AUTONEG_ENABLE)
+	if (sky2->flags & SKY2_FLAG_AUTO_SPEED)
 		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
 	else
 		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
@@ -661,7 +675,9 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
 
 	/* setup General Purpose Control Register */
 	gma_write16(hw, port, GM_GP_CTRL,
-		    GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS);
+		    GM_GPCR_FL_PASS | GM_GPCR_SPEED_100 |
+		    GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |
+		    GM_GPCR_AU_SPD_DIS);
 
 	if (hw->chip_id != CHIP_ID_YUKON_EC) {
 		if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
@@ -977,23 +993,26 @@ static void sky2_qset(struct sky2_hw *hw, u16 q)
  * hardware and driver list elements
  */
 static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
-				      u64 addr, u32 last)
+			       dma_addr_t addr, u32 last)
 {
 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
-	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), addr >> 32);
-	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32) addr);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), upper_32_bits(addr));
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), lower_32_bits(addr));
 	sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
 
 	sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
 }
 
-static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
+static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2, u16 *slot)
 {
-	struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
+	struct sky2_tx_le *le = sky2->tx_le + *slot;
+	struct tx_ring_info *re = sky2->tx_ring + *slot;
 
-	sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
+	*slot = RING_NEXT(*slot, sky2->tx_ring_size);
+	re->flags = 0;
+	re->skb = NULL;
 	le->ctrl = 0;
 	return le;
 }
@@ -1006,15 +1025,10 @@ static void tx_init(struct sky2_port *sky2)
 	sky2->tx_tcpsum = 0;
 	sky2->tx_last_mss = 0;
 
-	le = get_tx_le(sky2);
+	le = get_tx_le(sky2, &sky2->tx_prod);
 	le->addr = 0;
 	le->opcode = OP_ADDR64 | HW_OWNER;
-}
-
-static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
-					    struct sky2_tx_le *le)
-{
-	return sky2->tx_ring + (le - sky2->tx_le);
+	sky2->tx_last_upper = 0;
 }
 
 /* Update chip's next pointer */
@@ -1050,7 +1064,7 @@ static void sky2_rx_add(struct sky2_port *sky2,  u8 op,
 	}
 
 	le = sky2_next_rx(sky2);
-	le->addr = cpu_to_le32((u32) map);
+	le->addr = cpu_to_le32(lower_32_bits(map));
 	le->length = cpu_to_le16(len);
 	le->opcode = op | HW_OWNER;
 }
@@ -1117,7 +1131,8 @@ static void rx_set_checksum(struct sky2_port *sky2)
 
 	sky2_write32(sky2->hw,
 		     Q_ADDR(rxqaddr[sky2->port], Q_CSR),
-		     sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+		     (sky2->flags & SKY2_FLAG_RX_CHECKSUM)
+		     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
 }
 
 /*
@@ -1169,7 +1184,6 @@ static void sky2_rx_clean(struct sky2_port *sky2)
 			re->skb = NULL;
 		}
 	}
-	skb_queue_purge(&sky2->rx_recycle);
 }
 
 /* Basic MII support */
@@ -1200,9 +1214,6 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	}
 
 	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		spin_lock_bh(&sky2->phy_lock);
 		err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
 				   data->val_in);
@@ -1261,10 +1272,8 @@ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
 	struct sk_buff *skb;
 	int i;
 
-	skb = __skb_dequeue(&sky2->rx_recycle);
-	if (!skb)
-		skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size
-				       + sky2_rx_pad(sky2->hw));
+	skb = netdev_alloc_skb(sky2->netdev,
+			       sky2->rx_data_size + sky2_rx_pad(sky2->hw));
 	if (!skb)
 		goto nomem;
 
@@ -1356,8 +1365,6 @@ static int sky2_rx_start(struct sky2_port *sky2)
 
 	sky2->rx_data_size = size;
 
-	skb_queue_head_init(&sky2->rx_recycle);
-
 	/* Fill Rx ring */
 	for (i = 0; i < sky2->rx_pending; i++) {
 		re = sky2->rx_ring + i;
@@ -1396,6 +1403,61 @@ nomem:
 	return -ENOMEM;
 }
 
+static int sky2_alloc_buffers(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+
+	/* must be power of 2 */
+	sky2->tx_le = pci_alloc_consistent(hw->pdev,
+					   sky2->tx_ring_size *
+					   sizeof(struct sky2_tx_le),
+					   &sky2->tx_le_map);
+	if (!sky2->tx_le)
+		goto nomem;
+
+	sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info),
+				GFP_KERNEL);
+	if (!sky2->tx_ring)
+		goto nomem;
+
+	sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+					   &sky2->rx_le_map);
+	if (!sky2->rx_le)
+		goto nomem;
+	memset(sky2->rx_le, 0, RX_LE_BYTES);
+
+	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
+				GFP_KERNEL);
+	if (!sky2->rx_ring)
+		goto nomem;
+
+	return 0;
+nomem:
+	return -ENOMEM;
+}
+
+static void sky2_free_buffers(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+
+	if (sky2->rx_le) {
+		pci_free_consistent(hw->pdev, RX_LE_BYTES,
+				    sky2->rx_le, sky2->rx_le_map);
+		sky2->rx_le = NULL;
+	}
+	if (sky2->tx_le) {
+		pci_free_consistent(hw->pdev,
+				    sky2->tx_ring_size * sizeof(struct sky2_tx_le),
+				    sky2->tx_le, sky2->tx_le_map);
+		sky2->tx_le = NULL;
+	}
+	kfree(sky2->tx_ring);
+	kfree(sky2->rx_ring);
+
+	sky2->tx_ring = NULL;
+	sky2->rx_ring = NULL;
+}
+
 /* Bring up network interface. */
 static int sky2_up(struct net_device *dev)
 {
@@ -1403,7 +1465,7 @@ static int sky2_up(struct net_device *dev)
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
 	u32 imask, ramsize;
-	int cap, err = -ENOMEM;
+	int cap, err;
 	struct net_device *otherdev = hw->dev[sky2->port^1];
 
 	/*
@@ -1422,32 +1484,12 @@ static int sky2_up(struct net_device *dev)
 
 	netif_carrier_off(dev);
 
-	/* must be power of 2 */
-	sky2->tx_le = pci_alloc_consistent(hw->pdev,
-					   TX_RING_SIZE *
-					   sizeof(struct sky2_tx_le),
-					   &sky2->tx_le_map);
-	if (!sky2->tx_le)
-		goto err_out;
-
-	sky2->tx_ring = kcalloc(TX_RING_SIZE, sizeof(struct tx_ring_info),
-				GFP_KERNEL);
-	if (!sky2->tx_ring)
+	err = sky2_alloc_buffers(sky2);
+	if (err)
 		goto err_out;
 
 	tx_init(sky2);
 
-	sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
-					   &sky2->rx_le_map);
-	if (!sky2->rx_le)
-		goto err_out;
-	memset(sky2->rx_le, 0, RX_LE_BYTES);
-
-	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info),
-				GFP_KERNEL);
-	if (!sky2->rx_ring)
-		goto err_out;
-
 	sky2_mac_init(hw, port);
 
 	/* Register is number of 4K blocks on internal RAM buffer. */
@@ -1482,14 +1524,12 @@ static int sky2_up(struct net_device *dev)
 		sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
 
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
-			   TX_RING_SIZE - 1);
+			   sky2->tx_ring_size - 1);
 
 #ifdef SKY2_VLAN_TAG_USED
 	sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL);
 #endif
 
-	sky2->restarting = 0;
-
 	err = sky2_rx_start(sky2);
 	if (err)
 		goto err_out;
@@ -1500,47 +1540,26 @@ static int sky2_up(struct net_device *dev)
 	sky2_write32(hw, B0_IMSK, imask);
 	sky2_read32(hw, B0_IMSK);
 
-	sky2_set_multicast(dev);
-
-	/* wake queue incase we are restarting */
-	netif_wake_queue(dev);
-
 	if (netif_msg_ifup(sky2))
 		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+
 	return 0;
 
 err_out:
-	if (sky2->rx_le) {
-		pci_free_consistent(hw->pdev, RX_LE_BYTES,
-				    sky2->rx_le, sky2->rx_le_map);
-		sky2->rx_le = NULL;
-	}
-	if (sky2->tx_le) {
-		pci_free_consistent(hw->pdev,
-				    TX_RING_SIZE * sizeof(struct sky2_tx_le),
-				    sky2->tx_le, sky2->tx_le_map);
-		sky2->tx_le = NULL;
-	}
-	kfree(sky2->tx_ring);
-	kfree(sky2->rx_ring);
-
-	sky2->tx_ring = NULL;
-	sky2->rx_ring = NULL;
+	sky2_free_buffers(sky2);
 	return err;
 }
 
 /* Modular subtraction in ring */
-static inline int tx_dist(unsigned tail, unsigned head)
+static inline int tx_inuse(const struct sky2_port *sky2)
 {
-	return (head - tail) & (TX_RING_SIZE - 1);
+	return (sky2->tx_prod - sky2->tx_cons) & (sky2->tx_ring_size - 1);
 }
 
 /* Number of list elements available for next tx */
 static inline int tx_avail(const struct sky2_port *sky2)
 {
-	if (unlikely(sky2->restarting))
-		return 0;
-	return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod);
+	return sky2->tx_pending - tx_inuse(sky2);
 }
 
 /* Estimate of number of transmit list elements required */
@@ -1548,11 +1567,13 @@ static unsigned tx_le_req(const struct sk_buff *skb)
 {
 	unsigned count;
 
-	count = sizeof(dma_addr_t) / sizeof(u32);
-	count += skb_shinfo(skb)->nr_frags * count;
+	count = (skb_shinfo(skb)->nr_frags + 1)
+		* (sizeof(dma_addr_t) / sizeof(u32));
 
 	if (skb_is_gso(skb))
 		++count;
+	else if (sizeof(dma_addr_t) == sizeof(u32))
+		++count;	/* possible vlan */
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
 		++count;
@@ -1560,20 +1581,36 @@ static unsigned tx_le_req(const struct sk_buff *skb)
 	return count;
 }
 
+static void sky2_tx_unmap(struct pci_dev *pdev,
+			  const struct tx_ring_info *re)
+{
+	if (re->flags & TX_MAP_SINGLE)
+		pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
+				 pci_unmap_len(re, maplen),
+				 PCI_DMA_TODEVICE);
+	else if (re->flags & TX_MAP_PAGE)
+		pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
+			       pci_unmap_len(re, maplen),
+			       PCI_DMA_TODEVICE);
+}
+
 /*
  * Put one packet in ring for transmit.
  * A single packet can generate multiple list elements, and
  * the number of ring elements will probably be less than the number
  * of list elements used.
  */
-static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
+				   struct net_device *dev)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 	struct sky2_tx_le *le = NULL;
 	struct tx_ring_info *re;
-	unsigned i, len, first_slot;
+	unsigned i, len;
 	dma_addr_t mapping;
+	u32 upper;
+	u16 slot;
 	u16 mss;
 	u8 ctrl;
 
@@ -1586,15 +1623,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 	if (pci_dma_mapping_error(hw->pdev, mapping))
 		goto mapping_error;
 
-	first_slot = sky2->tx_prod;
+	slot = sky2->tx_prod;
 	if (unlikely(netif_msg_tx_queued(sky2)))
 		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
-		       dev->name, first_slot, skb->len);
+		       dev->name, slot, skb->len);
 
 	/* Send high bits if needed */
-	if (sizeof(dma_addr_t) > sizeof(u32)) {
-		le = get_tx_le(sky2);
-		le->addr = cpu_to_le32(upper_32_bits(mapping));
+	upper = upper_32_bits(mapping);
+	if (upper != sky2->tx_last_upper) {
+		le = get_tx_le(sky2, &slot);
+		le->addr = cpu_to_le32(upper);
+		sky2->tx_last_upper = upper;
 		le->opcode = OP_ADDR64 | HW_OWNER;
 	}
 
@@ -1606,7 +1645,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 			mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
 
   		if (mss != sky2->tx_last_mss) {
-  			le = get_tx_le(sky2);
+			le = get_tx_le(sky2, &slot);
   			le->addr = cpu_to_le32(mss);
 
 			if (hw->flags & SKY2_HW_NEW_LE)
@@ -1622,7 +1661,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 	/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
 	if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
 		if (!le) {
-			le = get_tx_le(sky2);
+			le = get_tx_le(sky2, &slot);
 			le->addr = 0;
 			le->opcode = OP_VLAN|HW_OWNER;
 		} else
@@ -1651,7 +1690,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 			if (tcpsum != sky2->tx_tcpsum) {
 				sky2->tx_tcpsum = tcpsum;
 
-				le = get_tx_le(sky2);
+				le = get_tx_le(sky2, &slot);
 				le->addr = cpu_to_le32(tcpsum);
 				le->length = 0;	/* initial checksum value */
 				le->ctrl = 1;	/* one packet */
@@ -1660,16 +1699,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
-	le = get_tx_le(sky2);
-	le->addr = cpu_to_le32((u32) mapping);
+	re = sky2->tx_ring + slot;
+	re->flags = TX_MAP_SINGLE;
+	pci_unmap_addr_set(re, mapaddr, mapping);
+	pci_unmap_len_set(re, maplen, len);
+
+	le = get_tx_le(sky2, &slot);
+	le->addr = cpu_to_le32(lower_32_bits(mapping));
 	le->length = cpu_to_le16(len);
 	le->ctrl = ctrl;
 	le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
 
-	re = tx_le_re(sky2, le);
-	re->skb = skb;
-	pci_unmap_addr_set(re, mapaddr, mapping);
-	pci_unmap_len_set(re, maplen, len);
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -1680,27 +1720,31 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 		if (pci_dma_mapping_error(hw->pdev, mapping))
 			goto mapping_unwind;
 
-		if (sizeof(dma_addr_t) > sizeof(u32)) {
-			le = get_tx_le(sky2);
-			le->addr = cpu_to_le32(upper_32_bits(mapping));
-			le->ctrl = 0;
+		upper = upper_32_bits(mapping);
+		if (upper != sky2->tx_last_upper) {
+			le = get_tx_le(sky2, &slot);
+			le->addr = cpu_to_le32(upper);
+			sky2->tx_last_upper = upper;
 			le->opcode = OP_ADDR64 | HW_OWNER;
 		}
 
-		le = get_tx_le(sky2);
-		le->addr = cpu_to_le32((u32) mapping);
+		re = sky2->tx_ring + slot;
+		re->flags = TX_MAP_PAGE;
+		pci_unmap_addr_set(re, mapaddr, mapping);
+		pci_unmap_len_set(re, maplen, frag->size);
+
+		le = get_tx_le(sky2, &slot);
+		le->addr = cpu_to_le32(lower_32_bits(mapping));
 		le->length = cpu_to_le16(frag->size);
 		le->ctrl = ctrl;
 		le->opcode = OP_BUFFER | HW_OWNER;
-
-		re = tx_le_re(sky2, le);
-		re->skb = skb;
-		pci_unmap_addr_set(re, mapaddr, mapping);
-		pci_unmap_len_set(re, maplen, frag->size);
 	}
 
+	re->skb = skb;
 	le->ctrl |= EOP;
 
+	sky2->tx_prod = slot;
+
 	if (tx_avail(sky2) <= MAX_SKB_TX_LE)
 		netif_stop_queue(dev);
 
@@ -1709,27 +1753,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 	return NETDEV_TX_OK;
 
 mapping_unwind:
-	for (i = first_slot; i != sky2->tx_prod; i = RING_NEXT(i, TX_RING_SIZE)) {
-		le = sky2->tx_le + i;
+	for (i = sky2->tx_prod; i != slot; i = RING_NEXT(i, sky2->tx_ring_size)) {
 		re = sky2->tx_ring + i;
 
-		switch(le->opcode & ~HW_OWNER) {
-		case OP_LARGESEND:
-		case OP_PACKET:
-			pci_unmap_single(hw->pdev,
-					 pci_unmap_addr(re, mapaddr),
-					 pci_unmap_len(re, maplen),
-					 PCI_DMA_TODEVICE);
-			break;
-		case OP_BUFFER:
-			pci_unmap_page(hw->pdev, pci_unmap_addr(re, mapaddr),
-				       pci_unmap_len(re, maplen),
-				       PCI_DMA_TODEVICE);
-			break;
-		}
+		sky2_tx_unmap(hw->pdev, re);
 	}
 
-	sky2->tx_prod = first_slot;
 mapping_error:
 	if (net_ratelimit())
 		dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
@@ -1740,40 +1769,28 @@ mapping_error:
 /*
  * Free ring elements from starting at tx_cons until "done"
  *
- * NB: the hardware will tell us about partial completion of multi-part
+ * NB:
+ *  1. The hardware will tell us about partial completion of multi-part
  *     buffers so make sure not to free skb to early.
+ *  2. This may run in parallel start_xmit because the it only
+ *     looks at the tail of the queue of FIFO (tx_cons), not
+ *     the head (tx_prod)
  */
 static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 {
 	struct net_device *dev = sky2->netdev;
-	struct pci_dev *pdev = sky2->hw->pdev;
 	unsigned idx;
 
-	BUG_ON(done >= TX_RING_SIZE);
+	BUG_ON(done >= sky2->tx_ring_size);
 
 	for (idx = sky2->tx_cons; idx != done;
-	     idx = RING_NEXT(idx, TX_RING_SIZE)) {
-		struct sky2_tx_le *le = sky2->tx_le + idx;
+	     idx = RING_NEXT(idx, sky2->tx_ring_size)) {
 		struct tx_ring_info *re = sky2->tx_ring + idx;
+		struct sk_buff *skb = re->skb;
 
-		switch(le->opcode & ~HW_OWNER) {
-		case OP_LARGESEND:
-		case OP_PACKET:
-			pci_unmap_single(pdev,
-					 pci_unmap_addr(re, mapaddr),
-					 pci_unmap_len(re, maplen),
-					 PCI_DMA_TODEVICE);
-			break;
-		case OP_BUFFER:
-			pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr),
-				       pci_unmap_len(re, maplen),
-				       PCI_DMA_TODEVICE);
-			break;
-		}
-
-		if (le->ctrl & EOP) {
-			struct sk_buff *skb = re->skb;
+		sky2_tx_unmap(sky2->hw->pdev, re);
 
+		if (skb) {
 			if (unlikely(netif_msg_tx_done(sky2)))
 				printk(KERN_DEBUG "%s: tx done %u\n",
 				       dev->name, idx);
@@ -1781,14 +1798,9 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 			dev->stats.tx_packets++;
 			dev->stats.tx_bytes += skb->len;
 
-			if (skb_queue_len(&sky2->rx_recycle) < sky2->rx_pending
-			    && skb_recycle_check(skb, sky2->rx_data_size
-						 + sky2_rx_pad(sky2->hw)))
-				__skb_queue_head(&sky2->rx_recycle, skb);
-			else
-				dev_kfree_skb_any(skb);
+			dev_kfree_skb_any(skb);
 
-			sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE);
+			sky2->tx_next = RING_NEXT(idx, sky2->tx_ring_size);
 		}
 	}
 
@@ -1799,14 +1811,26 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 		netif_wake_queue(dev);
 }
 
-/* Cleanup all untransmitted buffers, assume transmitter not running */
-static void sky2_tx_clean(struct net_device *dev)
+static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)
 {
-	struct sky2_port *sky2 = netdev_priv(dev);
+	/* Disable Force Sync bit and Enable Alloc bit */
+	sky2_write8(hw, SK_REG(port, TXA_CTRL),
+		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
 
-	netif_tx_lock_bh(dev);
-	sky2_tx_complete(sky2, sky2->tx_prod);
-	netif_tx_unlock_bh(dev);
+	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
+	sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
+	sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
+
+	/* Reset the PCI FIFO of the async Tx queue */
+	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
+		     BMU_RST_SET | BMU_FIFO_RST);
+
+	/* Reset the Tx prefetch units */
+	sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
+		     PREF_UNIT_RST_SET);
+
+	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
+	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
 }
 
 /* Network shutdown */
@@ -1825,10 +1849,6 @@ static int sky2_down(struct net_device *dev)
 	if (netif_msg_ifdown(sky2))
 		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
-	/* explicitly shut off tx incase we're restarting */
-	sky2->restarting = 1;
-	netif_tx_disable(dev);
-
 	/* Force flow control off */
 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
 
@@ -1850,26 +1870,7 @@ static int sky2_down(struct net_device *dev)
 	      && port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
 		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
 
-	/* Disable Force Sync bit and Enable Alloc bit */
-	sky2_write8(hw, SK_REG(port, TXA_CTRL),
-		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
-
-	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
-	sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
-	sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
-
-	/* Reset the PCI FIFO of the async Tx queue */
-	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
-		     BMU_RST_SET | BMU_FIFO_RST);
-
-	/* Reset the Tx prefetch units */
-	sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
-		     PREF_UNIT_RST_SET);
-
-	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
-
 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
-	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
 
 	/* Force any delayed status interrrupt and NAPI */
 	sky2_write32(hw, STAT_LEV_TIMER_CNT, 0);
@@ -1888,28 +1889,18 @@ static int sky2_down(struct net_device *dev)
 	synchronize_irq(hw->pdev->irq);
 	napi_synchronize(&hw->napi);
 
+	spin_lock_bh(&sky2->phy_lock);
 	sky2_phy_power_down(hw, port);
+	spin_unlock_bh(&sky2->phy_lock);
 
-	/* turn off LED's */
-	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
-
-	sky2_tx_clean(dev);
-	sky2_rx_clean(sky2);
-
-	pci_free_consistent(hw->pdev, RX_LE_BYTES,
-			    sky2->rx_le, sky2->rx_le_map);
-	kfree(sky2->rx_ring);
+	sky2_tx_reset(hw, port);
 
-	pci_free_consistent(hw->pdev,
-			    TX_RING_SIZE * sizeof(struct sky2_tx_le),
-			    sky2->tx_le, sky2->tx_le_map);
-	kfree(sky2->tx_ring);
+	/* Free any pending frames stuck in HW queue */
+	sky2_tx_complete(sky2, sky2->tx_prod);
 
-	sky2->tx_le = NULL;
-	sky2->rx_le = NULL;
+	sky2_rx_clean(sky2);
 
-	sky2->rx_ring = NULL;
-	sky2->tx_ring = NULL;
+	sky2_free_buffers(sky2);
 
 	return 0;
 }
@@ -2083,7 +2074,7 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
 		printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
 		       sky2->netdev->name, istatus, phystat);
 
-	if (sky2->autoneg == AUTONEG_ENABLE && (istatus & PHY_M_IS_AN_COMPL)) {
+	if (istatus & PHY_M_IS_AN_COMPL) {
 		if (sky2_autoneg_done(sky2, phystat) == 0)
 			sky2_link_up(sky2);
 		goto out;
@@ -2370,11 +2361,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	if (likely(netif_running(dev) && !sky2->restarting)) {
-		netif_tx_lock(dev);
+	if (netif_running(dev))
 		sky2_tx_complete(sky2, last);
-		netif_tx_unlock(dev);
-	}
 }
 
 static inline void sky2_skb_rx(const struct sky2_port *sky2,
@@ -2452,7 +2440,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
 
 			/* This chip reports checksum status differently */
 			if (hw->flags & SKY2_HW_NEW_LE) {
-				if (sky2->rx_csum &&
+				if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) &&
 				    (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
 				    (le->css & CSS_TCPUDPCSOK))
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2479,7 +2467,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
 			/* fall through */
 #endif
 		case OP_RXCHKS:
-			if (!sky2->rx_csum)
+			if (!(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
 				break;
 
 			/* If this happens then driver assuming wrong format */
@@ -2504,7 +2492,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
 				printk(KERN_NOTICE PFX "%s: hardware receive "
 				       "checksum problem (status = %#x)\n",
 				       dev->name, status);
-				sky2->rx_csum = 0;
+				sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
+
 				sky2_write32(sky2->hw,
 					     Q_ADDR(rxqaddr[port], Q_CSR),
 					     BMU_DIS_RX_CHKSUM);
@@ -2513,7 +2502,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx)
 
 		case OP_TXINDEXLE:
 			/* TX index reports status for both ports */
-			BUILD_BUG_ON(TX_RING_SIZE > 0x1000);
 			sky2_tx_done(hw->dev[0], status & 0xfff);
 			if (hw->dev[1])
 				sky2_tx_done(hw->dev[1],
@@ -2657,19 +2645,15 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
 }
 
 /* This should never happen it is a bug. */
-static void sky2_le_error(struct sky2_hw *hw, unsigned port,
-			  u16 q, unsigned ring_size)
+static void sky2_le_error(struct sky2_hw *hw, unsigned port, u16 q)
 {
 	struct net_device *dev = hw->dev[port];
-	struct sky2_port *sky2 = netdev_priv(dev);
-	unsigned idx;
-	const u64 *le = (q == Q_R1 || q == Q_R2)
-		? (u64 *) sky2->rx_le : (u64 *) sky2->tx_le;
+	u16 idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
 
-	idx = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
-	printk(KERN_ERR PFX "%s: descriptor error q=%#x get=%u [%llx] put=%u\n",
-	       dev->name, (unsigned) q, idx, (unsigned long long) le[idx],
-	       (unsigned) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)));
+	dev_err(&hw->pdev->dev, PFX
+		"%s: descriptor error q=%#x get=%u put=%u\n",
+		dev->name, (unsigned) q, (unsigned) idx,
+		(unsigned) sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX)));
 
 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
 }
@@ -2755,16 +2739,16 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status)
 		sky2_mac_intr(hw, 1);
 
 	if (status & Y2_IS_CHK_RX1)
-		sky2_le_error(hw, 0, Q_R1, RX_LE_SIZE);
+		sky2_le_error(hw, 0, Q_R1);
 
 	if (status & Y2_IS_CHK_RX2)
-		sky2_le_error(hw, 1, Q_R2, RX_LE_SIZE);
+		sky2_le_error(hw, 1, Q_R2);
 
 	if (status & Y2_IS_CHK_TXA1)
-		sky2_le_error(hw, 0, Q_XA1, TX_RING_SIZE);
+		sky2_le_error(hw, 0, Q_XA1);
 
 	if (status & Y2_IS_CHK_TXA2)
-		sky2_le_error(hw, 1, Q_XA2, TX_RING_SIZE);
+		sky2_le_error(hw, 1, Q_XA2);
 }
 
 static int sky2_poll(struct napi_struct *napi, int work_limit)
@@ -3009,8 +2993,6 @@ static void sky2_reset(struct sky2_hw *hw)
 	sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
 	sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
 
-	sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
-
 	/* Turn off descriptor polling */
 	sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
 
@@ -3078,18 +3060,46 @@ static void sky2_reset(struct sky2_hw *hw)
 	sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
 }
 
+/* Take device down (offline).
+ * Equivalent to doing dev_stop() but this does not
+ * inform upper layers of the transistion.
+ */
+static void sky2_detach(struct net_device *dev)
+{
+	if (netif_running(dev)) {
+		netif_device_detach(dev);	/* stop txq */
+		sky2_down(dev);
+	}
+}
+
+/* Bring device back after doing sky2_detach */
+static int sky2_reattach(struct net_device *dev)
+{
+	int err = 0;
+
+	if (netif_running(dev)) {
+		err = sky2_up(dev);
+		if (err) {
+			printk(KERN_INFO PFX "%s: could not restart %d\n",
+			       dev->name, err);
+			dev_close(dev);
+		} else {
+			netif_device_attach(dev);
+			sky2_set_multicast(dev);
+		}
+	}
+
+	return err;
+}
+
 static void sky2_restart(struct work_struct *work)
 {
 	struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work);
-	struct net_device *dev;
-	int i, err;
+	int i;
 
 	rtnl_lock();
-	for (i = 0; i < hw->ports; i++) {
-		dev = hw->dev[i];
-		if (netif_running(dev))
-			sky2_down(dev);
-	}
+	for (i = 0; i < hw->ports; i++)
+		sky2_detach(hw->dev[i]);
 
 	napi_disable(&hw->napi);
 	sky2_write32(hw, B0_IMSK, 0);
@@ -3097,17 +3107,8 @@ static void sky2_restart(struct work_struct *work)
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
 	napi_enable(&hw->napi);
 
-	for (i = 0; i < hw->ports; i++) {
-		dev = hw->dev[i];
-		if (netif_running(dev)) {
-			err = sky2_up(dev);
-			if (err) {
-				printk(KERN_INFO PFX "%s: could not restart %d\n",
-				       dev->name, err);
-				dev_close(dev);
-			}
-		}
-	}
+	for (i = 0; i < hw->ports; i++)
+		sky2_reattach(hw->dev[i]);
 
 	rtnl_unlock();
 }
@@ -3186,7 +3187,8 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	}
 
 	ecmd->advertising = sky2->advertising;
-	ecmd->autoneg = sky2->autoneg;
+	ecmd->autoneg = (sky2->flags & SKY2_FLAG_AUTO_SPEED)
+		? AUTONEG_ENABLE : AUTONEG_DISABLE;
 	ecmd->duplex = sky2->duplex;
 	return 0;
 }
@@ -3198,6 +3200,7 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	u32 supported = sky2_supported_modes(hw);
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
+		sky2->flags |= SKY2_FLAG_AUTO_SPEED;
 		ecmd->advertising = supported;
 		sky2->duplex = -1;
 		sky2->speed = -1;
@@ -3239,9 +3242,9 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
 		sky2->speed = ecmd->speed;
 		sky2->duplex = ecmd->duplex;
+		sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
 	}
 
-	sky2->autoneg = ecmd->autoneg;
 	sky2->advertising = ecmd->advertising;
 
 	if (netif_running(dev)) {
@@ -3311,14 +3314,17 @@ static u32 sky2_get_rx_csum(struct net_device *dev)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	return sky2->rx_csum;
+	return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM);
 }
 
 static int sky2_set_rx_csum(struct net_device *dev, u32 data)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	sky2->rx_csum = data;
+	if (data)
+		sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
+	else
+		sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
 
 	sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
 		     data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
@@ -3336,7 +3342,7 @@ static int sky2_nway_reset(struct net_device *dev)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	if (!netif_running(dev) || sky2->autoneg != AUTONEG_ENABLE)
+	if (!netif_running(dev) || !(sky2->flags & SKY2_FLAG_AUTO_SPEED))
 		return -EINVAL;
 
 	sky2_phy_reinit(sky2);
@@ -3576,7 +3582,8 @@ static void sky2_get_pauseparam(struct net_device *dev,
 		ecmd->tx_pause = ecmd->rx_pause = 1;
 	}
 
-	ecmd->autoneg = sky2->autoneg;
+	ecmd->autoneg = (sky2->flags & SKY2_FLAG_AUTO_PAUSE)
+		? AUTONEG_ENABLE : AUTONEG_DISABLE;
 }
 
 static int sky2_set_pauseparam(struct net_device *dev,
@@ -3584,7 +3591,11 @@ static int sky2_set_pauseparam(struct net_device *dev,
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 
-	sky2->autoneg = ecmd->autoneg;
+	if (ecmd->autoneg == AUTONEG_ENABLE)
+		sky2->flags |= SKY2_FLAG_AUTO_PAUSE;
+	else
+		sky2->flags &= ~SKY2_FLAG_AUTO_PAUSE;
+
 	sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause);
 
 	if (netif_running(dev))
@@ -3640,7 +3651,7 @@ static int sky2_set_coalesce(struct net_device *dev,
 	    ecmd->rx_coalesce_usecs_irq > tmax)
 		return -EINVAL;
 
-	if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1)
+	if (ecmd->tx_max_coalesced_frames >= sky2->tx_ring_size-1)
 		return -EINVAL;
 	if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING)
 		return -EINVAL;
@@ -3684,7 +3695,7 @@ static void sky2_get_ringparam(struct net_device *dev,
 	ering->rx_max_pending = RX_MAX_PENDING;
 	ering->rx_mini_max_pending = 0;
 	ering->rx_jumbo_max_pending = 0;
-	ering->tx_max_pending = TX_RING_SIZE - 1;
+	ering->tx_max_pending = TX_MAX_PENDING;
 
 	ering->rx_pending = sky2->rx_pending;
 	ering->rx_mini_pending = 0;
@@ -3696,27 +3707,20 @@ static int sky2_set_ringparam(struct net_device *dev,
 			      struct ethtool_ringparam *ering)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
-	int err = 0;
 
 	if (ering->rx_pending > RX_MAX_PENDING ||
 	    ering->rx_pending < 8 ||
-	    ering->tx_pending < MAX_SKB_TX_LE ||
-	    ering->tx_pending > TX_RING_SIZE - 1)
+	    ering->tx_pending < TX_MIN_PENDING ||
+	    ering->tx_pending > TX_MAX_PENDING)
 		return -EINVAL;
 
-	if (netif_running(dev))
-		sky2_down(dev);
+	sky2_detach(dev);
 
 	sky2->rx_pending = ering->rx_pending;
 	sky2->tx_pending = ering->tx_pending;
+	sky2->tx_ring_size = roundup_pow_of_two(sky2->tx_pending+1);
 
-	if (netif_running(dev)) {
-		err = sky2_up(dev);
-		if (err)
-			dev_close(dev);
-	}
-
-	return err;
+	return sky2_reattach(dev);
 }
 
 static int sky2_get_regs_len(struct net_device *dev)
@@ -4084,8 +4088,8 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
 
 	/* Dump contents of tx ring */
 	sop = 1;
-	for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE;
-	     idx = RING_NEXT(idx, TX_RING_SIZE)) {
+	for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < sky2->tx_ring_size;
+	     idx = RING_NEXT(idx, sky2->tx_ring_size)) {
 		const struct sky2_tx_le *le = sky2->tx_le + idx;
 		u32 a = le32_to_cpu(le->addr);
 
@@ -4128,7 +4132,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v)
 
 	seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n",
 		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)),
-		   last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
+		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
 		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
 
 	sky2_read32(hw, B0_Y2_SP_LISR);
@@ -4282,19 +4286,22 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
 	sky2->msg_enable = netif_msg_init(debug, default_msg);
 
 	/* Auto speed and flow control */
-	sky2->autoneg = AUTONEG_ENABLE;
+	sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
+	if (hw->chip_id != CHIP_ID_YUKON_XL)
+		sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
+
 	sky2->flow_mode = FC_BOTH;
 
 	sky2->duplex = -1;
 	sky2->speed = -1;
 	sky2->advertising = sky2_supported_modes(hw);
-	sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
 	sky2->wol = wol;
 
 	spin_lock_init(&sky2->phy_lock);
+
 	sky2->tx_pending = TX_DEF_PENDING;
+	sky2->tx_ring_size = roundup_pow_of_two(TX_DEF_PENDING+1);
 	sky2->rx_pending = RX_DEF_PENDING;
-	sky2->restarting = 0;
 
 	hw->dev[port] = dev;
 
@@ -4543,16 +4550,18 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 	if (hw->ports > 1) {
 		struct net_device *dev1;
 
+		err = -ENOMEM;
 		dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default);
-		if (!dev1)
-			dev_warn(&pdev->dev, "allocation for second device failed\n");
-		else if ((err = register_netdev(dev1))) {
+		if (dev1 && (err = register_netdev(dev1)) == 0)
+			sky2_show_addr(dev1);
+		else {
 			dev_warn(&pdev->dev,
 				 "register of second port failed (%d)\n", err);
 			hw->dev[1] = NULL;
-			free_netdev(dev1);
-		} else
-			sky2_show_addr(dev1);
+			hw->ports = 1;
+			if (dev1)
+				free_netdev(dev1);
+		}
 	}
 
 	setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw);
@@ -4602,7 +4611,6 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
 
 	sky2_power_aux(hw);
 
-	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
 	sky2_write8(hw, B0_CTST, CS_RST_SET);
 	sky2_read8(hw, B0_CTST);
 
@@ -4634,13 +4642,12 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
 	del_timer_sync(&hw->watchdog_timer);
 	cancel_work_sync(&hw->restart_work);
 
+	rtnl_lock();
 	for (i = 0; i < hw->ports; i++) {
 		struct net_device *dev = hw->dev[i];
 		struct sky2_port *sky2 = netdev_priv(dev);
 
-		netif_device_detach(dev);
-		if (netif_running(dev))
-			sky2_down(dev);
+		sky2_detach(dev);
 
 		if (sky2->wol)
 			sky2_wol_init(sky2);
@@ -4651,6 +4658,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
 	sky2_write32(hw, B0_IMSK, 0);
 	napi_disable(&hw->napi);
 	sky2_power_aux(hw);
+	rtnl_unlock();
 
 	pci_save_state(pdev);
 	pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
@@ -4687,25 +4695,18 @@ static int sky2_resume(struct pci_dev *pdev)
 	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
 	napi_enable(&hw->napi);
 
+	rtnl_lock();
 	for (i = 0; i < hw->ports; i++) {
-		struct net_device *dev = hw->dev[i];
-
-		netif_device_attach(dev);
-		if (netif_running(dev)) {
-			err = sky2_up(dev);
-			if (err) {
-				printk(KERN_ERR PFX "%s: could not up: %d\n",
-				       dev->name, err);
-				rtnl_lock();
-				dev_close(dev);
-				rtnl_unlock();
-				goto out;
-			}
-		}
+		err = sky2_reattach(hw->dev[i]);
+		if (err)
+			goto out;
 	}
+	rtnl_unlock();
 
 	return 0;
 out:
+	rtnl_unlock();
+
 	dev_err(&pdev->dev, "resume failed (%d)\n", err);
 	pci_disable_device(pdev);
 	return err;
@@ -4720,6 +4721,7 @@ static void sky2_shutdown(struct pci_dev *pdev)
 	if (!hw)
 		return;
 
+	rtnl_lock();
 	del_timer_sync(&hw->watchdog_timer);
 
 	for (i = 0; i < hw->ports; i++) {
@@ -4734,6 +4736,7 @@ static void sky2_shutdown(struct pci_dev *pdev)
 
 	if (wol)
 		sky2_power_aux(hw);
+	rtnl_unlock();
 
 	pci_enable_wake(pdev, PCI_D3hot, wol);
 	pci_enable_wake(pdev, PCI_D3cold, wol);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 4486b06..e0f23a1 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -155,7 +155,7 @@ enum pci_cfg_reg1 {
 enum csr_regs {
 	B0_RAP		= 0x0000,
 	B0_CTST		= 0x0004,
-	B0_Y2LED	= 0x0005,
+
 	B0_POWER_CTRL	= 0x0007,
 	B0_ISRC		= 0x0008,
 	B0_IMSK		= 0x000c,
@@ -260,7 +260,7 @@ enum csr_regs {
 	Y2_CFG_AER      = 0x1d00,	/* PCI Advanced Error Report region */
 };
 
-/*	B0_CTST			16 bit	Control/Status register */
+/*	B0_CTST			24 bit	Control/Status register */
 enum {
 	Y2_VMAIN_AVAIL	= 1<<17,/* VMAIN available (YUKON-2 only) */
 	Y2_VAUX_AVAIL	= 1<<16,/* VAUX available (YUKON-2 only) */
@@ -283,13 +283,6 @@ enum {
 	CS_RST_SET	= 1,	/* Set   Software reset	*/
 };
 
-/*	B0_LED			 8 Bit	LED register */
-enum {
-/* Bit  7.. 2:	reserved */
-	LED_STAT_ON	= 1<<1,	/* Status LED on	*/
-	LED_STAT_OFF	= 1,	/* Status LED off	*/
-};
-
 /*	B0_POWER_CTRL	 8 Bit	Power Control reg (YUKON only) */
 enum {
 	PC_VAUX_ENA	= 1<<7,	/* Switch VAUX Enable  */
@@ -1583,7 +1576,6 @@ enum {
 };
 
 #define GM_GPCR_SPEED_1000	(GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
-#define GM_GPCR_AU_ALL_DIS	(GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
 
 /*	GM_TX_CTRL			16 bit r/w	Transmit Control Register */
 enum {
@@ -1985,6 +1977,9 @@ struct sky2_status_le {
 
 struct tx_ring_info {
 	struct sk_buff	*skb;
+	unsigned long flags;
+#define TX_MAP_SINGLE   0x0001
+#define TX_MAP_PAGE     000002
 	DECLARE_PCI_UNMAP_ADDR(mapaddr);
 	DECLARE_PCI_UNMAP_LEN(maplen);
 };
@@ -2012,12 +2007,14 @@ struct sky2_port {
 
 	struct tx_ring_info  *tx_ring;
 	struct sky2_tx_le    *tx_le;
+	u16		     tx_ring_size;
 	u16		     tx_cons;		/* next le to check */
 	u16		     tx_prod;		/* next le to use */
 	u16		     tx_next;		/* debug only */
 
 	u16		     tx_pending;
 	u16		     tx_last_mss;
+	u32		     tx_last_upper;
 	u32		     tx_tcpsum;
 
 	struct rx_ring_info  *rx_ring ____cacheline_aligned_in_smp;
@@ -2028,7 +2025,6 @@ struct sky2_port {
 	u16		     rx_pending;
 	u16		     rx_data_size;
 	u16		     rx_nfrags;
-	struct sk_buff_head  rx_recycle;
 
 #ifdef SKY2_VLAN_TAG_USED
 	u16		     rx_tag;
@@ -2042,16 +2038,18 @@ struct sky2_port {
 		u8	fifo_lev;
 	} check;
 
-
 	dma_addr_t	     rx_le_map;
 	dma_addr_t	     tx_le_map;
+
 	u16		     advertising;	/* ADVERTISED_ bits */
-	u16		     speed;	/* SPEED_1000, SPEED_100, ... */
-	u8		     autoneg;	/* AUTONEG_ENABLE, AUTONEG_DISABLE */
-	u8		     duplex;	/* DUPLEX_HALF, DUPLEX_FULL */
-	u8		     rx_csum;
-	u8		     wol;
-	u8		     restarting;
+	u16		     speed;		/* SPEED_1000, SPEED_100, ... */
+	u8		     wol;		/* WAKE_ bits */
+	u8		     duplex;		/* DUPLEX_HALF, DUPLEX_FULL */
+	u16		     flags;
+#define SKY2_FLAG_RX_CHECKSUM		0x0001
+#define SKY2_FLAG_AUTO_SPEED		0x0002
+#define SKY2_FLAG_AUTO_PAUSE		0x0004
+
  	enum flow_control    flow_mode;
  	enum flow_control    flow_status;
 
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 5c61d5f..e17c535 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -474,7 +474,7 @@ out:
 
 
 /* Encapsulate an IP datagram and kick it into a TTY queue. */
-static int
+static netdev_tx_t
 sl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct slip *sl = netdev_priv(dev);
@@ -484,12 +484,12 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev)
 		spin_unlock(&sl->lock);
 		printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (sl->tty == NULL) {
 		spin_unlock(&sl->lock);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	sl_lock(sl);
@@ -498,7 +498,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock(&sl->lock);
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
@@ -616,6 +616,14 @@ static void sl_uninit(struct net_device *dev)
 	sl_free_bufs(sl);
 }
 
+/* Hook the destructor so we can free slip devices at the right point in time */
+static void sl_free_netdev(struct net_device *dev)
+{
+	int i = dev->base_addr;
+	free_netdev(dev);
+	slip_devs[i] = NULL;
+}
+
 static const struct net_device_ops sl_netdev_ops = {
 	.ndo_init		= sl_init,
 	.ndo_uninit	  	= sl_uninit,
@@ -634,7 +642,7 @@ static const struct net_device_ops sl_netdev_ops = {
 static void sl_setup(struct net_device *dev)
 {
 	dev->netdev_ops		= &sl_netdev_ops;
-	dev->destructor		= free_netdev;
+	dev->destructor		= sl_free_netdev;
 
 	dev->hard_header_len	= 0;
 	dev->addr_len		= 0;
@@ -712,8 +720,6 @@ static void sl_sync(void)
 static struct slip *sl_alloc(dev_t line)
 {
 	int i;
-	int sel = -1;
-	int score = -1;
 	struct net_device *dev = NULL;
 	struct slip       *sl;
 
@@ -724,55 +730,7 @@ static struct slip *sl_alloc(dev_t line)
 		dev = slip_devs[i];
 		if (dev == NULL)
 			break;
-
-		sl = netdev_priv(dev);
-		if (sl->leased) {
-			if (sl->line != line)
-				continue;
-			if (sl->tty)
-				return NULL;
-
-			/* Clear ESCAPE & ERROR flags */
-			sl->flags &= (1 << SLF_INUSE);
-			return sl;
-		}
-
-		if (sl->tty)
-			continue;
-
-		if (current->pid == sl->pid) {
-			if (sl->line == line && score < 3) {
-				sel = i;
-				score = 3;
-				continue;
-			}
-			if (score < 2) {
-				sel = i;
-				score = 2;
-			}
-			continue;
-		}
-		if (sl->line == line && score < 1) {
-			sel = i;
-			score = 1;
-			continue;
-		}
-		if (score < 0) {
-			sel = i;
-			score = 0;
-		}
-	}
-
-	if (sel >= 0) {
-		i = sel;
-		dev = slip_devs[i];
-		if (score > 1) {
-			sl = netdev_priv(dev);
-			sl->flags &= (1 << SLF_INUSE);
-			return sl;
-		}
 	}
-
 	/* Sorry, too many, all slots in use */
 	if (i >= slip_maxdev)
 		return NULL;
@@ -909,30 +867,13 @@ err_exit:
 }
 
 /*
-
-  FIXME: 1,2 are fixed 3 was never true anyway.
-
-   Let me to blame a bit.
-   1. TTY module calls this funstion on soft interrupt.
-   2. TTY module calls this function WITH MASKED INTERRUPTS!
-   3. TTY module does not notify us about line discipline
-      shutdown,
-
-   Seems, now it is clean. The solution is to consider netdevice and
-   line discipline sides as two independent threads.
-
-   By-product (not desired): sl? does not feel hangups and remains open.
-   It is supposed, that user level program (dip, diald, slattach...)
-   will catch SIGHUP and make the rest of work.
-
-   I see no way to make more with current tty code. --ANK
- */
-
-/*
  * Close down a SLIP channel.
  * This means flushing out any pending queues, and then returning. This
  * call is serialized against other ldisc functions.
+ *
+ * We also use this method fo a hangup event
  */
+
 static void slip_close(struct tty_struct *tty)
 {
 	struct slip *sl = tty->disc_data;
@@ -951,10 +892,16 @@ static void slip_close(struct tty_struct *tty)
 	del_timer_sync(&sl->keepalive_timer);
 	del_timer_sync(&sl->outfill_timer);
 #endif
-
-	/* Count references from TTY module */
+	/* Flush network side */
+	unregister_netdev(sl->dev);
+	/* This will complete via sl_free_netdev */
 }
 
+static int slip_hangup(struct tty_struct *tty)
+{
+	slip_close(tty);
+	return 0;
+}
  /************************************************************************
   *			STANDARD SLIP ENCAPSULATION		  	 *
   ************************************************************************/
@@ -1311,6 +1258,7 @@ static struct tty_ldisc_ops sl_ldisc = {
 	.name 		= "slip",
 	.open 		= slip_open,
 	.close	 	= slip_close,
+	.hangup	 	= slip_hangup,
 	.ioctl		= slip_ioctl,
 	.receive_buf	= slip_receive_buf,
 	.write_wakeup	= slip_write_wakeup,
@@ -1384,6 +1332,8 @@ static void __exit slip_exit(void)
 		}
 	} while (busy && time_before(jiffies, timeout));
 
+	/* FIXME: hangup is async so we should wait when doing this second
+	   phase */
 
 	for (i = 0; i < slip_maxdev; i++) {
 		dev = slip_devs[i];
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index bc4976a..2a6b6de 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -553,7 +553,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		dev->stats.tx_dropped++;
 		spin_unlock_irqrestore(&lp->lock, flags);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 #ifdef SMC_USE_DMA
@@ -566,7 +566,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			lp->pending_tx_skb = skb;
 			netif_stop_queue(dev);
 			spin_unlock_irqrestore(&lp->lock, flags);
-			return 0;
+			return NETDEV_TX_OK;
 		} else {
 			DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: Activating Tx DMA\n", dev->name);
 			lp->txdma_active = 1;
@@ -577,7 +577,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	smc911x_hardware_send_pkt(dev);
 	spin_unlock_irqrestore(&lp->lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 8140f7c..05adb6a 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -236,7 +236,6 @@ static inline void SMC_outsl(struct smc911x_local *lp, int reg,
  * Use a DMA for RX and TX packets.
  */
 #include <linux/dma-mapping.h>
-#include <mach/dma.h>
 
 static dma_addr_t rx_dmabuf, tx_dmabuf;
 static int rx_dmalen, tx_dmalen;
diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c
index e02471b..934a120 100644
--- a/drivers/net/smc9194.c
+++ b/drivers/net/smc9194.c
@@ -299,7 +299,8 @@ static void smc_hardware_send_packet( struct net_device * dev );
  . to store the packet, I call this routine, which either sends it
  . now, or generates an interrupt when the card is ready for the
  . packet */
-static int  smc_wait_to_send_packet( struct sk_buff * skb, struct net_device *dev );
+static netdev_tx_t  smc_wait_to_send_packet( struct sk_buff * skb,
+					     struct net_device *dev );
 
 /* this does a soft reset on the device */
 static void smc_reset( int ioaddr );
@@ -487,7 +488,8 @@ static void smc_setmulticast( int ioaddr, int count, struct dev_mc_list * addrs
  . o 	(NO): Enable interrupts and let the interrupt handler deal with it.
  . o	(YES):Send it now.
 */
-static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
+static netdev_tx_t smc_wait_to_send_packet(struct sk_buff *skb,
+					   struct net_device *dev)
 {
 	struct smc_local *lp = netdev_priv(dev);
 	unsigned int ioaddr 	= dev->base_addr;
@@ -512,7 +514,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN)) {
 			netif_wake_queue(dev);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 		length = ETH_ZLEN;
 	}
@@ -534,7 +536,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de
 		lp->saved_skb = NULL;
 		/* this IS an error, but, i don't want the skb saved */
 		netif_wake_queue(dev);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	/* either way, a packet is waiting now */
 	lp->packets_waiting++;
@@ -571,12 +573,12 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de
 		SMC_ENABLE_INT( IM_ALLOC_INT );
       		PRINTK2((CARDNAME": memory allocation deferred. \n"));
 		/* it's deferred, but I'll handle it later */
-      		return 0;
+      		return NETDEV_TX_OK;
    	}
 	/* or YES! I can send the packet now.. */
 	smc_hardware_send_packet(dev);
 	netif_wake_queue(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 7567f51..05c91ee 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -35,7 +35,7 @@
  *
  * contributors:
  * 	Daris A Nevil <dnevil@snmc.com>
- *      Nicolas Pitre <nico@cam.org>
+ *      Nicolas Pitre <nico@fluxnic.net>
  *	Russell King <rmk@arm.linux.org.uk>
  *
  * History:
@@ -58,7 +58,7 @@
  *   22/09/04  Nicolas Pitre      big update (see commit log for details)
  */
 static const char version[] =
-	"smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@cam.org>\n";
+	"smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@fluxnic.net>\n";
 
 /* Debugging level */
 #ifndef SMC_DEBUG
@@ -659,7 +659,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		dev->stats.tx_errors++;
 		dev->stats.tx_dropped++;
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	smc_special_lock(&lp->lock, flags);
@@ -696,7 +696,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		smc_hardware_send_pkt((unsigned long)dev);
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 57a159f..3911be7 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -28,7 +28,7 @@
  . Authors
  .	Erik Stahlman		<erik@vt.edu>
  .	Daris A Nevil		<dnevil@snmc.com>
- .	Nicolas Pitre 		<nico@cam.org>
+ .	Nicolas Pitre 		<nico@fluxnic.net>
  .
  ---------------------------------------------------------------------------*/
 #ifndef _SMC91X_H_
@@ -83,34 +83,6 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 	}
 }
 
-#elif defined(CONFIG_BLACKFIN)
-
-#define SMC_IRQ_FLAGS		IRQF_TRIGGER_HIGH
-#define RPC_LSA_DEFAULT		RPC_LED_100_10
-#define RPC_LSB_DEFAULT		RPC_LED_TX_RX
-
-#define SMC_CAN_USE_8BIT	0
-#define SMC_CAN_USE_16BIT	1
-# if defined(CONFIG_BF561)
-#define SMC_CAN_USE_32BIT	1
-# else
-#define SMC_CAN_USE_32BIT	0
-# endif
-#define SMC_IO_SHIFT		0
-#define SMC_NOWAIT      	1
-#define SMC_USE_BFIN_DMA	0
-
-#define SMC_inw(a, r)		readw((a) + (r))
-#define SMC_outw(v, a, r)	writew(v, (a) + (r))
-#define SMC_insw(a, r, p, l)	readsw((a) + (r), p, l)
-#define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
-# if SMC_CAN_USE_32BIT
-#define SMC_inl(a, r)		readl((a) + (r))
-#define SMC_outl(v, a, r)	writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
-# endif
-
 #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6)
 
 /* We can only do 16-bit reads and writes in the static memory space. */
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 94b6d26..ccdd196 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -50,6 +50,7 @@
 #include <linux/swab.h>
 #include <linux/phy.h>
 #include <linux/smsc911x.h>
+#include <linux/device.h>
 #include "smsc911x.h"
 
 #define SMSC_CHIPNAME		"smsc911x"
@@ -1046,7 +1047,6 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
 		/* Update counters */
 		dev->stats.rx_packets++;
 		dev->stats.rx_bytes += (pktlength - 4);
-		dev->last_rx = jiffies;
 	}
 
 	/* Return total received packets */
@@ -2114,10 +2114,12 @@ out_0:
 /* This implementation assumes the devices remains powered on its VDDVARIO
  * pins during suspend. */
 
-static int smsc911x_suspend(struct platform_device *pdev, pm_message_t state)
+/* TODO: implement freeze/thaw callbacks for hibernation.*/
+
+static int smsc911x_suspend(struct device *dev)
 {
-	struct net_device *dev = platform_get_drvdata(pdev);
-	struct smsc911x_data *pdata = netdev_priv(dev);
+	struct net_device *ndev = dev_get_drvdata(dev);
+	struct smsc911x_data *pdata = netdev_priv(ndev);
 
 	/* enable wake on LAN, energy detection and the external PME
 	 * signal. */
@@ -2128,10 +2130,10 @@ static int smsc911x_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int smsc911x_resume(struct platform_device *pdev)
+static int smsc911x_resume(struct device *dev)
 {
-	struct net_device *dev = platform_get_drvdata(pdev);
-	struct smsc911x_data *pdata = netdev_priv(dev);
+	struct net_device *ndev = dev_get_drvdata(dev);
+	struct smsc911x_data *pdata = netdev_priv(ndev);
 	unsigned int to = 100;
 
 	/* Note 3.11 from the datasheet:
@@ -2149,19 +2151,25 @@ static int smsc911x_resume(struct platform_device *pdev)
 	return (to == 0) ? -EIO : 0;
 }
 
+static struct dev_pm_ops smsc911x_pm_ops = {
+	.suspend	= smsc911x_suspend,
+	.resume		= smsc911x_resume,
+};
+
+#define SMSC911X_PM_OPS (&smsc911x_pm_ops)
+
 #else
-#define smsc911x_suspend	NULL
-#define smsc911x_resume		NULL
+#define SMSC911X_PM_OPS NULL
 #endif
 
 static struct platform_driver smsc911x_driver = {
 	.probe = smsc911x_drv_probe,
 	.remove = __devexit_p(smsc911x_drv_remove),
 	.driver = {
-		.name = SMSC_CHIPNAME,
+		.name	= SMSC_CHIPNAME,
+		.owner	= THIS_MODULE,
+		.pm	= SMSC911X_PM_OPS,
 	},
-	.suspend = smsc911x_suspend,
-	.resume = smsc911x_resume,
 };
 
 /* Entry point for loading the module */
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 60abdb1..b4909a2 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -817,7 +817,6 @@ static void smsc9420_rx_handoff(struct smsc9420_pdata *pd, const int index,
 	skb->protocol = eth_type_trans(skb, dev);
 
 	netif_receive_skb(skb);
-	dev->last_rx = jiffies;
 }
 
 static int smsc9420_alloc_rx_buffer(struct smsc9420_pdata *pd, int index)
@@ -968,7 +967,8 @@ static void smsc9420_complete_tx(struct net_device *dev)
 	}
 }
 
-static int smsc9420_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t smsc9420_hard_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	struct smsc9420_pdata *pd = netdev_priv(dev);
 	dma_addr_t mapping;
diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c
index 753a1fb..9599ce7 100644
--- a/drivers/net/sonic.c
+++ b/drivers/net/sonic.c
@@ -211,7 +211,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
 	length = skb->len;
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 
@@ -265,7 +265,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 669253c..a36e2b5 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -595,7 +595,7 @@ static int	netdev_open(struct net_device *dev);
 static void	check_duplex(struct net_device *dev);
 static void	tx_timeout(struct net_device *dev);
 static void	init_ring(struct net_device *dev);
-static int	start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void	netdev_error(struct net_device *dev, int intr_status);
 static int	__netdev_rx(struct net_device *dev, int *quota);
@@ -1223,7 +1223,7 @@ static void init_ring(struct net_device *dev)
 }
 
 
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
 	unsigned int entry;
@@ -1311,7 +1311,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index 7bb2742..2f1eaaf 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -1015,7 +1015,7 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
 	if(skb->len > XMIT_BUFF_SIZE)
 	{
 		printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	netif_stop_queue(dev);
@@ -1110,7 +1110,7 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
 		dev_kfree_skb(skb);
 #endif
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*******************************************
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index 534dfe3..0ca4241 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -562,7 +562,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 		netif_start_queue(dev);
 		dev->trans_start = jiffies;
 
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 
@@ -648,7 +648,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
 	local_irq_restore(flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The LANCE interrupt handler. */
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 5017d7f..536cf7e 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -984,7 +984,7 @@ static int bigmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static struct net_device_stats *bigmac_get_stats(struct net_device *dev)
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index d1521c3..e13685a 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -415,7 +415,7 @@ static void check_duplex(struct net_device *dev);
 static void netdev_timer(unsigned long data);
 static void tx_timeout(struct net_device *dev);
 static void init_ring(struct net_device *dev);
-static int  start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
 static int reset_tx (struct net_device *dev);
 static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void rx_poll(unsigned long data);
@@ -1053,7 +1053,7 @@ static void tx_poll (unsigned long data)
 	return;
 }
 
-static int
+static netdev_tx_t
 start_tx (struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
@@ -1091,7 +1091,7 @@ start_tx (struct sk_buff *skb, struct net_device *dev)
 			"%s: Transmit frame #%d queued in slot %d.\n",
 			dev->name, np->cur_tx, entry);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* Reset hardware tx and free all of tx buffers */
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index d2dfe0a..305ec3d 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -1015,7 +1015,8 @@ static __inline__ int gem_intme(int entry)
 	return 0;
 }
 
-static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t gem_start_xmit(struct sk_buff *skb,
+				  struct net_device *dev)
 {
 	struct gem *gp = netdev_priv(dev);
 	int entry;
@@ -2851,9 +2852,7 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		break;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable(CAP_NET_ADMIN))
-			rc = -EPERM;
-		else if (!gp->running)
+		if (!gp->running)
 			rc = -EAGAIN;
 		else {
 			__phy_write(gp, data->phy_id & 0x1f, data->reg_num & 0x1f,
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 4ef7291..37d721b 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2252,7 +2252,8 @@ static void happy_meal_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t happy_meal_start_xmit(struct sk_buff *skb,
+					 struct net_device *dev)
 {
 	struct happy_meal *hp = netdev_priv(dev);
  	int entry;
@@ -2338,7 +2339,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 
 	tx_add_log(hp, TXLOG_ACTION_TXMIT, 0);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static struct net_device_stats *happy_meal_get_stats(struct net_device *dev)
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index afc7b35..9d6fd47 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1163,7 +1163,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* taken from the depca driver */
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index c6ec61e..dcefb60 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -621,7 +621,7 @@ static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void qe_set_multicast(struct net_device *dev)
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index d737f6b..d1298e5 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -23,9 +23,9 @@
  */
 
 #ifdef TC35815_NAPI
-#define DRV_VERSION	"1.37-NAPI"
+#define DRV_VERSION	"1.38-NAPI"
 #else
-#define DRV_VERSION	"1.37"
+#define DRV_VERSION	"1.38"
 #endif
 static const char *version = "tc35815.c:v" DRV_VERSION "\n";
 #define MODNAME			"tc35815"
@@ -341,8 +341,9 @@ struct BDesc {
 	Tx_EnExColl | Tx_EnLCarr | Tx_EnExDefer | Tx_EnUnder | \
 	Tx_En)	/* maybe  0x7b01 */
 #endif
+/* Do not use Rx_StripCRC -- it causes trouble on BLEx/FDAEx condition */
 #define RX_CTL_CMD	(Rx_EnGood | Rx_EnRxPar | Rx_EnLongErr | Rx_EnOver \
-	| Rx_EnCRCErr | Rx_EnAlign | Rx_StripCRC | Rx_RxEn) /* maybe 0x6f11 */
+	| Rx_EnCRCErr | Rx_EnAlign | Rx_RxEn) /* maybe 0x6f01 */
 #define INT_EN_CMD  (Int_NRAbtEn | \
 	Int_DmParErrEn | Int_DParDEn | Int_DParErrEn | \
 	Int_SSysErrEn  | Int_RMasAbtEn | Int_RTargAbtEn | \
@@ -593,9 +594,10 @@ static int tc_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 	struct net_device *dev = bus->priv;
 	struct tc35815_regs __iomem *tr =
 		(struct tc35815_regs __iomem *)dev->base_addr;
-	unsigned long timeout = jiffies + 10;
+	unsigned long timeout = jiffies + HZ;
 
 	tc_writel(MD_CA_Busy | (mii_id << 5) | (regnum & 0x1f), &tr->MD_CA);
+	udelay(12); /* it takes 32 x 400ns at least */
 	while (tc_readl(&tr->MD_CA) & MD_CA_Busy) {
 		if (time_after(jiffies, timeout))
 			return -EIO;
@@ -609,11 +611,12 @@ static int tc_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 val)
 	struct net_device *dev = bus->priv;
 	struct tc35815_regs __iomem *tr =
 		(struct tc35815_regs __iomem *)dev->base_addr;
-	unsigned long timeout = jiffies + 10;
+	unsigned long timeout = jiffies + HZ;
 
 	tc_writel(val, &tr->MD_Data);
 	tc_writel(MD_CA_Busy | MD_CA_Wr | (mii_id << 5) | (regnum & 0x1f),
 		  &tr->MD_CA);
+	udelay(12); /* it takes 32 x 400ns at least */
 	while (tc_readl(&tr->MD_CA) & MD_CA_Busy) {
 		if (time_after(jiffies, timeout))
 			return -EIO;
@@ -1509,7 +1512,7 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev)
 	 */
 
 	spin_unlock_irqrestore(&lp->lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 #define FATAL_ERROR_INT \
@@ -1540,8 +1543,6 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status)
 #endif
 {
 	struct tc35815_local *lp = netdev_priv(dev);
-	struct tc35815_regs __iomem *tr =
-		(struct tc35815_regs __iomem *)dev->base_addr;
 	int ret = -1;
 
 	/* Fatal errors... */
@@ -1551,27 +1552,26 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status)
 	}
 	/* recoverable errors */
 	if (status & Int_IntFDAEx) {
-		/* disable FDAEx int. (until we make rooms...) */
-		tc_writel(tc_readl(&tr->Int_En) & ~Int_FDAExEn, &tr->Int_En);
-		printk(KERN_WARNING
-		       "%s: Free Descriptor Area Exhausted (%#x).\n",
-		       dev->name, status);
+		if (netif_msg_rx_err(lp))
+			dev_warn(&dev->dev,
+				 "Free Descriptor Area Exhausted (%#x).\n",
+				 status);
 		dev->stats.rx_dropped++;
 		ret = 0;
 	}
 	if (status & Int_IntBLEx) {
-		/* disable BLEx int. (until we make rooms...) */
-		tc_writel(tc_readl(&tr->Int_En) & ~Int_BLExEn, &tr->Int_En);
-		printk(KERN_WARNING
-		       "%s: Buffer List Exhausted (%#x).\n",
-		       dev->name, status);
+		if (netif_msg_rx_err(lp))
+			dev_warn(&dev->dev,
+				 "Buffer List Exhausted (%#x).\n",
+				 status);
 		dev->stats.rx_dropped++;
 		ret = 0;
 	}
 	if (status & Int_IntExBD) {
-		printk(KERN_WARNING
-		       "%s: Excessive Buffer Descriptiors (%#x).\n",
-		       dev->name, status);
+		if (netif_msg_rx_err(lp))
+			dev_warn(&dev->dev,
+				 "Excessive Buffer Descriptiors (%#x).\n",
+				 status);
 		dev->stats.rx_length_errors++;
 		ret = 0;
 	}
@@ -1630,8 +1630,12 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
 
 	spin_lock(&lp->lock);
 	status = tc_readl(&tr->Int_Src);
-	tc_writel(status, &tr->Int_Src);	/* write to clear */
+	/* BLEx, FDAEx will be cleared later */
+	tc_writel(status & ~(Int_BLEx | Int_FDAEx),
+		  &tr->Int_Src);	/* write to clear */
 	handled = tc35815_do_interrupt(dev, status);
+	if (status & (Int_BLEx | Int_FDAEx))
+		tc_writel(status & (Int_BLEx | Int_FDAEx), &tr->Int_Src);
 	(void)tc_readl(&tr->Int_Src);	/* flush */
 	spin_unlock(&lp->lock);
 	return IRQ_RETVAL(handled >= 0);
@@ -1659,8 +1663,6 @@ tc35815_rx(struct net_device *dev)
 	struct tc35815_local *lp = netdev_priv(dev);
 	unsigned int fdctl;
 	int i;
-	int buf_free_count = 0;
-	int fd_free_count = 0;
 #ifdef TC35815_NAPI
 	int received = 0;
 #endif
@@ -1769,8 +1771,9 @@ tc35815_rx(struct net_device *dev)
 			dev->stats.rx_bytes += pkt_len;
 		} else {
 			dev->stats.rx_errors++;
-			printk(KERN_DEBUG "%s: Rx error (status %x)\n",
-			       dev->name, status & Rx_Stat_Mask);
+			if (netif_msg_rx_err(lp))
+				dev_info(&dev->dev, "Rx error (status %x)\n",
+					 status & Rx_Stat_Mask);
 			/* WORKAROUND: LongErr and CRCErr means Overflow. */
 			if ((status & Rx_LongErr) && (status & Rx_CRCErr)) {
 				status &= ~(Rx_LongErr|Rx_CRCErr);
@@ -1848,7 +1851,6 @@ tc35815_rx(struct net_device *dev)
 #else
 				lp->fbl_count++;
 #endif
-				buf_free_count++;
 			}
 		}
 
@@ -1870,7 +1872,6 @@ tc35815_rx(struct net_device *dev)
 #endif
 			lp->rfd_cur->fd.FDCtl = cpu_to_le32(FD_CownsFD);
 			lp->rfd_cur++;
-			fd_free_count++;
 		}
 		if (lp->rfd_cur > lp->rfd_limit)
 			lp->rfd_cur = lp->rfd_base;
@@ -1881,17 +1882,6 @@ tc35815_rx(struct net_device *dev)
 #endif
 	}
 
-	/* re-enable BL/FDA Exhaust interrupts. */
-	if (fd_free_count) {
-		struct tc35815_regs __iomem *tr =
-			(struct tc35815_regs __iomem *)dev->base_addr;
-		u32 en, en_old = tc_readl(&tr->Int_En);
-		en = en_old | Int_FDAExEn;
-		if (buf_free_count)
-			en |= Int_BLExEn;
-		if (en != en_old)
-			tc_writel(en, &tr->Int_En);
-	}
 #ifdef TC35815_NAPI
 	return received;
 #endif
@@ -1910,9 +1900,14 @@ static int tc35815_poll(struct napi_struct *napi, int budget)
 	spin_lock(&lp->lock);
 	status = tc_readl(&tr->Int_Src);
 	do {
-		tc_writel(status, &tr->Int_Src);	/* write to clear */
+		/* BLEx, FDAEx will be cleared later */
+		tc_writel(status & ~(Int_BLEx | Int_FDAEx),
+			  &tr->Int_Src);	/* write to clear */
 
 		handled = tc35815_do_interrupt(dev, status, budget - received);
+		if (status & (Int_BLEx | Int_FDAEx))
+			tc_writel(status & (Int_BLEx | Int_FDAEx),
+				  &tr->Int_Src);
 		if (handled >= 0) {
 			received += handled;
 			if (received >= budget)
@@ -2144,7 +2139,7 @@ static struct net_device_stats *tc35815_get_stats(struct net_device *dev)
 		(struct tc35815_regs __iomem *)dev->base_addr;
 	if (netif_running(dev))
 		/* Update the statistics from the device registers. */
-		dev->stats.rx_missed_errors = tc_readl(&tr->Miss_Cnt);
+		dev->stats.rx_missed_errors += tc_readl(&tr->Miss_Cnt);
 
 	return &dev->stats;
 }
@@ -2399,8 +2394,6 @@ static void tc35815_chip_init(struct net_device *dev)
 		tc_writel(DMA_BURST_SIZE, &tr->DMA_Ctl);
 #ifdef TC35815_USE_PACKEDBUFFER
 	tc_writel(RxFrag_EnPack | ETH_ZLEN, &tr->RxFragSize);	/* Packing */
-#else
-	tc_writel(ETH_ZLEN, &tr->RxFragSize);
 #endif
 	tc_writel(0, &tr->TxPollCtr);	/* Batch mode */
 	tc_writel(TX_THRESHOLD, &tr->TxThrsh);
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 3c2679c..ec9dfb2 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -1622,7 +1622,8 @@ static inline int bdx_tx_space(struct bdx_priv *priv)
  *   the driver. Note: the driver must NOT put the skb in its DMA ring.
  * o NETDEV_TX_LOCKED Locking failed, please retry quickly.
  */
-static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb,
+				   struct net_device *ndev)
 {
 	struct bdx_priv *priv = netdev_priv(ndev);
 	struct txd_fifo *f = &priv->txd_fifo0;
@@ -2427,7 +2428,7 @@ static void bdx_get_ethtool_stats(struct net_device *netdev,
  */
 static void bdx_ethtool_ops(struct net_device *netdev)
 {
-	static struct ethtool_ops bdx_ethtool_ops = {
+	static const struct ethtool_ops bdx_ethtool_ops = {
 		.get_settings = bdx_get_settings,
 		.get_drvinfo = bdx_get_drvinfo,
 		.get_link = ethtool_op_get_link,
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 46a3f86..f09bc5d 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.99"
-#define DRV_MODULE_RELDATE	"April 20, 2009"
+#define DRV_MODULE_VERSION	"3.102"
+#define DRV_MODULE_RELDATE	"September 1, 2009"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -92,7 +92,7 @@
 /* hardware minimum and maximum for a single frame's data payload */
 #define TG3_MIN_MTU			60
 #define TG3_MAX_MTU(tp)	\
-	((tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) ? 9000 : 1500)
+	((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ? 9000 : 1500)
 
 /* These numbers seem to be hard coded in the NIC firmware somehow.
  * You can't change the ring sizes, but you can change where you place
@@ -102,6 +102,7 @@
 #define TG3_DEF_RX_RING_PENDING		200
 #define TG3_RX_JUMBO_RING_SIZE		256
 #define TG3_DEF_RX_JUMBO_RING_PENDING	100
+#define TG3_RSS_INDIR_TBL_SIZE 128
 
 /* Do not place this n-ring entries value into the tp struct itself,
  * we really want to expose these constants to GCC so that modulo et
@@ -110,26 +111,34 @@
  * replace things like '% foo' with '& (foo - 1)'.
  */
 #define TG3_RX_RCB_RING_SIZE(tp)	\
-	((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ?  512 : 1024)
+	(((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && \
+	  !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) ? 1024 : 512)
 
 #define TG3_TX_RING_SIZE		512
 #define TG3_DEF_TX_RING_PENDING		(TG3_TX_RING_SIZE - 1)
 
 #define TG3_RX_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * \
 				 TG3_RX_RING_SIZE)
-#define TG3_RX_JUMBO_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * \
-			         TG3_RX_JUMBO_RING_SIZE)
+#define TG3_RX_JUMBO_RING_BYTES	(sizeof(struct tg3_ext_rx_buffer_desc) * \
+				 TG3_RX_JUMBO_RING_SIZE)
 #define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \
-			           TG3_RX_RCB_RING_SIZE(tp))
+				 TG3_RX_RCB_RING_SIZE(tp))
 #define TG3_TX_RING_BYTES	(sizeof(struct tg3_tx_buffer_desc) * \
 				 TG3_TX_RING_SIZE)
 #define NEXT_TX(N)		(((N) + 1) & (TG3_TX_RING_SIZE - 1))
 
-#define RX_PKT_BUF_SZ		(1536 + tp->rx_offset + 64)
-#define RX_JUMBO_PKT_BUF_SZ	(9046 + tp->rx_offset + 64)
+#define TG3_DMA_BYTE_ENAB		64
+
+#define TG3_RX_STD_DMA_SZ		1536
+#define TG3_RX_JMB_DMA_SZ		9046
+
+#define TG3_RX_DMA_TO_MAP_SZ(x)		((x) + TG3_DMA_BYTE_ENAB)
+
+#define TG3_RX_STD_MAP_SZ		TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
+#define TG3_RX_JMB_MAP_SZ		TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)
 
 /* minimum number of free TX descriptors required to wake up TX process */
-#define TG3_TX_WAKEUP_THRESH(tp)		((tp)->tx_pending / 4)
+#define TG3_TX_WAKEUP_THRESH(tnapi)		((tnapi)->tx_pending / 4)
 
 #define TG3_RAW_IP_ALIGN 2
 
@@ -153,6 +162,7 @@ MODULE_FIRMWARE(FIRMWARE_TG3);
 MODULE_FIRMWARE(FIRMWARE_TG3TSO);
 MODULE_FIRMWARE(FIRMWARE_TG3TSO5);
 
+#define TG3_RSS_MIN_NUM_MSIX_VECS	2
 
 static int tg3_debug = -1;	/* -1 == use TG3_DEF_MSG_ENABLE as value */
 module_param(tg3_debug, int, 0);
@@ -219,11 +229,12 @@ static struct pci_device_id tg3_pci_tbl[] = {
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761S)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5761SE)},
-	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_G)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5785_F)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57780)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57760)},
 	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57790)},
-	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57720)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
 	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@ -605,39 +616,47 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
 
 static void tg3_disable_ints(struct tg3 *tp)
 {
+	int i;
+
 	tw32(TG3PCI_MISC_HOST_CTRL,
 	     (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
-	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
-}
-
-static inline void tg3_cond_int(struct tg3 *tp)
-{
-	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
-	    (tp->hw_status->status & SD_STATUS_UPDATED))
-		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
-	else
-		tw32(HOSTCC_MODE, tp->coalesce_mode |
-		     (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
+	for (i = 0; i < tp->irq_max; i++)
+		tw32_mailbox_f(tp->napi[i].int_mbox, 0x00000001);
 }
 
 static void tg3_enable_ints(struct tg3 *tp)
 {
+	int i;
+	u32 coal_now = 0;
+
 	tp->irq_sync = 0;
 	wmb();
 
 	tw32(TG3PCI_MISC_HOST_CTRL,
 	     (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
-	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-		       (tp->last_tag << 24));
-	if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
-		tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-			       (tp->last_tag << 24));
-	tg3_cond_int(tp);
+
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+		tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
+		if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+			tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
+
+		coal_now |= tnapi->coal_now;
+	}
+
+	/* Force an initial interrupt */
+	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
+	    (tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
+		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
+	else
+		tw32(HOSTCC_MODE, tp->coalesce_mode |
+		     HOSTCC_MODE_ENABLE | coal_now);
 }
 
-static inline unsigned int tg3_has_work(struct tg3 *tp)
+static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
 {
-	struct tg3_hw_status *sblk = tp->hw_status;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 	unsigned int work_exists = 0;
 
 	/* check for phy events */
@@ -648,22 +667,23 @@ static inline unsigned int tg3_has_work(struct tg3 *tp)
 			work_exists = 1;
 	}
 	/* check for RX/TX work to do */
-	if (sblk->idx[0].tx_consumer != tp->tx_cons ||
-	    sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
+	if (sblk->idx[0].tx_consumer != tnapi->tx_cons ||
+	    *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
 		work_exists = 1;
 
 	return work_exists;
 }
 
-/* tg3_restart_ints
+/* tg3_int_reenable
  *  similar to tg3_enable_ints, but it accurately determines whether there
  *  is new work pending and can return without flushing the PIO write
  *  which reenables interrupts
  */
-static void tg3_restart_ints(struct tg3 *tp)
+static void tg3_int_reenable(struct tg3_napi *tnapi)
 {
-	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
-		     tp->last_tag << 24);
+	struct tg3 *tp = tnapi->tp;
+
+	tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
 	mmiowb();
 
 	/* When doing tagged status, this work check is unnecessary.
@@ -671,39 +691,58 @@ static void tg3_restart_ints(struct tg3 *tp)
 	 * work we've completed.
 	 */
 	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
-	    tg3_has_work(tp))
+	    tg3_has_work(tnapi))
 		tw32(HOSTCC_MODE, tp->coalesce_mode |
-		     (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
+		     HOSTCC_MODE_ENABLE | tnapi->coal_now);
+}
+
+static void tg3_napi_disable(struct tg3 *tp)
+{
+	int i;
+
+	for (i = tp->irq_cnt - 1; i >= 0; i--)
+		napi_disable(&tp->napi[i].napi);
+}
+
+static void tg3_napi_enable(struct tg3 *tp)
+{
+	int i;
+
+	for (i = 0; i < tp->irq_cnt; i++)
+		napi_enable(&tp->napi[i].napi);
 }
 
 static inline void tg3_netif_stop(struct tg3 *tp)
 {
 	tp->dev->trans_start = jiffies;	/* prevent tx timeout */
-	napi_disable(&tp->napi);
+	tg3_napi_disable(tp);
 	netif_tx_disable(tp->dev);
 }
 
 static inline void tg3_netif_start(struct tg3 *tp)
 {
-	netif_wake_queue(tp->dev);
-	/* NOTE: unconditional netif_wake_queue is only appropriate
-	 * so long as all callers are assured to have free tx slots
-	 * (such as after tg3_init_hw)
+	/* NOTE: unconditional netif_tx_wake_all_queues is only
+	 * appropriate so long as all callers are assured to
+	 * have free tx slots (such as after tg3_init_hw)
 	 */
-	napi_enable(&tp->napi);
-	tp->hw_status->status |= SD_STATUS_UPDATED;
+	netif_tx_wake_all_queues(tp->dev);
+
+	tg3_napi_enable(tp);
+	tp->napi[0].hw_status->status |= SD_STATUS_UPDATED;
 	tg3_enable_ints(tp);
 }
 
 static void tg3_switch_clocks(struct tg3 *tp)
 {
-	u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
+	u32 clock_ctrl;
 	u32 orig_clock_ctrl;
 
 	if ((tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
 	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
 		return;
 
+	clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
+
 	orig_clock_ctrl = clock_ctrl;
 	clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN |
 		       CLOCK_CTRL_CLKRUN_OENABLE |
@@ -743,7 +782,7 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
 
 	*val = 0x0;
 
-	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+	frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
 		      MI_COM_PHY_ADDR_MASK);
 	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
 		      MI_COM_REG_ADDR_MASK);
@@ -784,7 +823,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
 	unsigned int loops;
 	int ret;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
+	if ((tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
 	    (reg == MII_TG3_CTRL || reg == MII_TG3_AUX_CTRL))
 		return 0;
 
@@ -794,7 +833,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
 		udelay(80);
 	}
 
-	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+	frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
 		      MI_COM_PHY_ADDR_MASK);
 	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
 		      MI_COM_REG_ADDR_MASK);
@@ -917,7 +956,9 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
 		tw32(MAC_PHYCFG2, val);
 
 		val = tr32(MAC_PHYCFG1);
-		val &= ~MAC_PHYCFG1_RGMII_INT;
+		val &= ~(MAC_PHYCFG1_RGMII_INT |
+			 MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK);
+		val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT;
 		tw32(MAC_PHYCFG1, val);
 
 		return;
@@ -933,15 +974,18 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
 
 	tw32(MAC_PHYCFG2, val);
 
-	val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC |
-				    MAC_PHYCFG1_RGMII_SND_STAT_EN);
-	if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
+	val = tr32(MAC_PHYCFG1);
+	val &= ~(MAC_PHYCFG1_RXCLK_TO_MASK | MAC_PHYCFG1_TXCLK_TO_MASK |
+		 MAC_PHYCFG1_RGMII_EXT_RX_DEC | MAC_PHYCFG1_RGMII_SND_STAT_EN);
+	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)) {
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
 			val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
 		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
 			val |= MAC_PHYCFG1_RGMII_SND_STAT_EN;
 	}
-	tw32(MAC_PHYCFG1, val | MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV);
+	val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT |
+	       MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV;
+	tw32(MAC_PHYCFG1, val);
 
 	val = tr32(MAC_EXT_RGMII_MODE);
 	val &= ~(MAC_RGMII_MODE_RX_INT_B |
@@ -977,6 +1021,21 @@ static void tg3_mdio_start(struct tg3 *tp)
 	tw32_f(MAC_MI_MODE, tp->mi_mode);
 	udelay(80);
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+		u32 funcnum, is_serdes;
+
+		funcnum = tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC;
+		if (funcnum)
+			tp->phy_addr = 2;
+		else
+			tp->phy_addr = 1;
+
+		is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
+		if (is_serdes)
+			tp->phy_addr += 7;
+	} else
+		tp->phy_addr = PHY_ADDR;
+
 	if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
 		tg3_mdio_config_5785(tp);
@@ -1064,6 +1123,7 @@ static int tg3_mdio_init(struct tg3 *tp)
 	case TG3_PHY_ID_RTL8201E:
 	case TG3_PHY_ID_BCMAC131:
 		phydev->interface = PHY_INTERFACE_MODE_MII;
+		tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
 		break;
 	}
 
@@ -1469,14 +1529,38 @@ static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
 	tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
 }
 
+static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable)
+{
+	u32 phytest;
+
+	if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) {
+		u32 phy;
+
+		tg3_writephy(tp, MII_TG3_FET_TEST,
+			     phytest | MII_TG3_FET_SHADOW_EN);
+		if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXSTAT2, &phy)) {
+			if (enable)
+				phy |= MII_TG3_FET_SHDW_AUXSTAT2_APD;
+			else
+				phy &= ~MII_TG3_FET_SHDW_AUXSTAT2_APD;
+			tg3_writephy(tp, MII_TG3_FET_SHDW_AUXSTAT2, phy);
+		}
+		tg3_writephy(tp, MII_TG3_FET_TEST, phytest);
+	}
+}
+
 static void tg3_phy_toggle_apd(struct tg3 *tp, bool enable)
 {
 	u32 reg;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
 		return;
 
+	if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+		tg3_phy_fet_toggle_apd(tp, enable);
+		return;
+	}
+
 	reg = MII_TG3_MISC_SHDW_WREN |
 	      MII_TG3_MISC_SHDW_SCR5_SEL |
 	      MII_TG3_MISC_SHDW_SCR5_LPED |
@@ -1506,20 +1590,22 @@ static void tg3_phy_toggle_automdix(struct tg3 *tp, int enable)
 	    (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
 		return;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+	if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
 		u32 ephy;
 
-		if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &ephy)) {
-			tg3_writephy(tp, MII_TG3_EPHY_TEST,
-				     ephy | MII_TG3_EPHY_SHADOW_EN);
-			if (!tg3_readphy(tp, MII_TG3_EPHYTST_MISCCTRL, &phy)) {
+		if (!tg3_readphy(tp, MII_TG3_FET_TEST, &ephy)) {
+			u32 reg = MII_TG3_FET_SHDW_MISCCTRL;
+
+			tg3_writephy(tp, MII_TG3_FET_TEST,
+				     ephy | MII_TG3_FET_SHADOW_EN);
+			if (!tg3_readphy(tp, reg, &phy)) {
 				if (enable)
-					phy |= MII_TG3_EPHYTST_MISCCTRL_MDIX;
+					phy |= MII_TG3_FET_SHDW_MISCCTRL_MDIX;
 				else
-					phy &= ~MII_TG3_EPHYTST_MISCCTRL_MDIX;
-				tg3_writephy(tp, MII_TG3_EPHYTST_MISCCTRL, phy);
+					phy &= ~MII_TG3_FET_SHDW_MISCCTRL_MDIX;
+				tg3_writephy(tp, reg, phy);
 			}
-			tg3_writephy(tp, MII_TG3_EPHY_TEST, ephy);
+			tg3_writephy(tp, MII_TG3_FET_TEST, ephy);
 		}
 	} else {
 		phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
@@ -1888,7 +1974,7 @@ out:
 	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
 		/* Cannot do read-modify-write on 5401 */
 		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
-	} else if (tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) {
+	} else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
 		u32 phy_reg;
 
 		/* Set bit 14 with read-modify-write to preserve other bits */
@@ -1900,7 +1986,7 @@ out:
 	/* Set phy register 0x10 bit 0 to high fifo elasticity to support
 	 * jumbo frames transmission.
 	 */
-	if (tp->tg3_flags2 & TG3_FLG2_JUMBO_CAPABLE) {
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
 		u32 phy_reg;
 
 		if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg))
@@ -1910,7 +1996,7 @@ out:
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 		/* adjust output voltage */
-		tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x12);
+		tg3_writephy(tp, MII_TG3_FET_PTEST, 0x12);
 	}
 
 	tg3_phy_toggle_automdix(tp, 1);
@@ -1925,8 +2011,9 @@ static void tg3_frob_aux_power(struct tg3 *tp)
 	if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0)
 		return;
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
 		struct net_device *dev_peer;
 
 		dev_peer = pci_get_drvdata(tp->pdev_peer);
@@ -2655,7 +2742,7 @@ static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8
 		break;
 
 	default:
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
+		if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
 			*speed = (val & MII_TG3_AUX_STAT_100) ? SPEED_100 :
 				 SPEED_10;
 			*duplex = (val & MII_TG3_AUX_STAT_FULL) ? DUPLEX_FULL :
@@ -2990,7 +3077,7 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
 
 	if (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT)
 		tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG);
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
+	else if (!(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET))
 		tg3_writephy(tp, MII_TG3_IMASK, ~0);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -3100,7 +3187,9 @@ relink:
 			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
 		else
 			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
-	} else
+	} else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)
+		tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+	else
 		tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
 
 	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
@@ -3167,6 +3256,15 @@ relink:
 			pci_write_config_word(tp->pdev,
 					      tp->pcie_cap + PCI_EXP_LNKCTL,
 					      newlnkctl);
+	} else if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+		u32 newreg, oldreg = tr32(TG3_PCIE_LNKCTL);
+		if (tp->link_config.active_speed == SPEED_100 ||
+		    tp->link_config.active_speed == SPEED_10)
+			newreg = oldreg & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+		else
+			newreg = oldreg | TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+		if (newreg != oldreg)
+			tw32(TG3_PCIE_LNKCTL, newreg);
 	}
 
 	if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -3848,9 +3946,9 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
 	else
 		current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
 
-	tp->hw_status->status =
+	tp->napi[0].hw_status->status =
 		(SD_STATUS_UPDATED |
-		 (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
+		 (tp->napi[0].hw_status->status & ~SD_STATUS_LINK_CHG));
 
 	for (i = 0; i < 100; i++) {
 		tw32_f(MAC_STATUS, (MAC_STATUS_SYNC_CHANGED |
@@ -4216,24 +4314,32 @@ static void tg3_tx_recover(struct tg3 *tp)
 	spin_unlock(&tp->lock);
 }
 
-static inline u32 tg3_tx_avail(struct tg3 *tp)
+static inline u32 tg3_tx_avail(struct tg3_napi *tnapi)
 {
 	smp_mb();
-	return (tp->tx_pending -
-		((tp->tx_prod - tp->tx_cons) & (TG3_TX_RING_SIZE - 1)));
+	return tnapi->tx_pending -
+	       ((tnapi->tx_prod - tnapi->tx_cons) & (TG3_TX_RING_SIZE - 1));
 }
 
 /* Tigon3 never reports partial packet sends.  So we do not
  * need special logic to handle SKBs that have not had all
  * of their frags sent yet, like SunGEM does.
  */
-static void tg3_tx(struct tg3 *tp)
+static void tg3_tx(struct tg3_napi *tnapi)
 {
-	u32 hw_idx = tp->hw_status->idx[0].tx_consumer;
-	u32 sw_idx = tp->tx_cons;
+	struct tg3 *tp = tnapi->tp;
+	u32 hw_idx = tnapi->hw_status->idx[0].tx_consumer;
+	u32 sw_idx = tnapi->tx_cons;
+	struct netdev_queue *txq;
+	int index = tnapi - tp->napi;
+
+	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+		index--;
+
+	txq = netdev_get_tx_queue(tp->dev, index);
 
 	while (sw_idx != hw_idx) {
-		struct tx_ring_info *ri = &tp->tx_buffers[sw_idx];
+		struct tx_ring_info *ri = &tnapi->tx_buffers[sw_idx];
 		struct sk_buff *skb = ri->skb;
 		int i, tx_bug = 0;
 
@@ -4249,7 +4355,7 @@ static void tg3_tx(struct tg3 *tp)
 		sw_idx = NEXT_TX(sw_idx);
 
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			ri = &tp->tx_buffers[sw_idx];
+			ri = &tnapi->tx_buffers[sw_idx];
 			if (unlikely(ri->skb != NULL || sw_idx == hw_idx))
 				tx_bug = 1;
 			sw_idx = NEXT_TX(sw_idx);
@@ -4263,7 +4369,7 @@ static void tg3_tx(struct tg3 *tp)
 		}
 	}
 
-	tp->tx_cons = sw_idx;
+	tnapi->tx_cons = sw_idx;
 
 	/* Need to make the tx_cons update visible to tg3_start_xmit()
 	 * before checking for netif_queue_stopped().  Without the
@@ -4272,13 +4378,13 @@ static void tg3_tx(struct tg3 *tp)
 	 */
 	smp_mb();
 
-	if (unlikely(netif_queue_stopped(tp->dev) &&
-		     (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))) {
-		netif_tx_lock(tp->dev);
-		if (netif_queue_stopped(tp->dev) &&
-		    (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp)))
-			netif_wake_queue(tp->dev);
-		netif_tx_unlock(tp->dev);
+	if (unlikely(netif_tx_queue_stopped(txq) &&
+		     (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))) {
+		__netif_tx_lock(txq, smp_processor_id());
+		if (netif_tx_queue_stopped(txq) &&
+		    (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi)))
+			netif_tx_wake_queue(txq);
+		__netif_tx_unlock(txq);
 	}
 }
 
@@ -4293,33 +4399,35 @@ static void tg3_tx(struct tg3 *tp)
  * buffers the cpu only reads the last cacheline of the RX descriptor
  * (to fetch the error flags, vlan tag, checksum, and opaque cookie).
  */
-static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
+static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
 			    int src_idx, u32 dest_idx_unmasked)
 {
+	struct tg3 *tp = tnapi->tp;
 	struct tg3_rx_buffer_desc *desc;
 	struct ring_info *map, *src_map;
 	struct sk_buff *skb;
 	dma_addr_t mapping;
 	int skb_size, dest_idx;
+	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
 	src_map = NULL;
 	switch (opaque_key) {
 	case RXD_OPAQUE_RING_STD:
 		dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
-		desc = &tp->rx_std[dest_idx];
-		map = &tp->rx_std_buffers[dest_idx];
+		desc = &tpr->rx_std[dest_idx];
+		map = &tpr->rx_std_buffers[dest_idx];
 		if (src_idx >= 0)
-			src_map = &tp->rx_std_buffers[src_idx];
-		skb_size = tp->rx_pkt_buf_sz;
+			src_map = &tpr->rx_std_buffers[src_idx];
+		skb_size = tp->rx_pkt_map_sz;
 		break;
 
 	case RXD_OPAQUE_RING_JUMBO:
 		dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
-		desc = &tp->rx_jumbo[dest_idx];
-		map = &tp->rx_jumbo_buffers[dest_idx];
+		desc = &tpr->rx_jmb[dest_idx].std;
+		map = &tpr->rx_jmb_buffers[dest_idx];
 		if (src_idx >= 0)
-			src_map = &tp->rx_jumbo_buffers[src_idx];
-		skb_size = RX_JUMBO_PKT_BUF_SZ;
+			src_map = &tpr->rx_jmb_buffers[src_idx];
+		skb_size = TG3_RX_JMB_MAP_SZ;
 		break;
 
 	default:
@@ -4332,14 +4440,13 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
 	 * Callers depend upon this behavior and assume that
 	 * we leave everything unchanged if we fail.
 	 */
-	skb = netdev_alloc_skb(tp->dev, skb_size);
+	skb = netdev_alloc_skb(tp->dev, skb_size + tp->rx_offset);
 	if (skb == NULL)
 		return -ENOMEM;
 
 	skb_reserve(skb, tp->rx_offset);
 
-	mapping = pci_map_single(tp->pdev, skb->data,
-				 skb_size - tp->rx_offset,
+	mapping = pci_map_single(tp->pdev, skb->data, skb_size,
 				 PCI_DMA_FROMDEVICE);
 
 	map->skb = skb;
@@ -4358,28 +4465,30 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key,
  * members of the RX descriptor are invariant.  See notes above
  * tg3_alloc_rx_skb for full details.
  */
-static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
+static void tg3_recycle_rx(struct tg3_napi *tnapi, u32 opaque_key,
 			   int src_idx, u32 dest_idx_unmasked)
 {
+	struct tg3 *tp = tnapi->tp;
 	struct tg3_rx_buffer_desc *src_desc, *dest_desc;
 	struct ring_info *src_map, *dest_map;
 	int dest_idx;
+	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
 	switch (opaque_key) {
 	case RXD_OPAQUE_RING_STD:
 		dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE;
-		dest_desc = &tp->rx_std[dest_idx];
-		dest_map = &tp->rx_std_buffers[dest_idx];
-		src_desc = &tp->rx_std[src_idx];
-		src_map = &tp->rx_std_buffers[src_idx];
+		dest_desc = &tpr->rx_std[dest_idx];
+		dest_map = &tpr->rx_std_buffers[dest_idx];
+		src_desc = &tpr->rx_std[src_idx];
+		src_map = &tpr->rx_std_buffers[src_idx];
 		break;
 
 	case RXD_OPAQUE_RING_JUMBO:
 		dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE;
-		dest_desc = &tp->rx_jumbo[dest_idx];
-		dest_map = &tp->rx_jumbo_buffers[dest_idx];
-		src_desc = &tp->rx_jumbo[src_idx];
-		src_map = &tp->rx_jumbo_buffers[src_idx];
+		dest_desc = &tpr->rx_jmb[dest_idx].std;
+		dest_map = &tpr->rx_jmb_buffers[dest_idx];
+		src_desc = &tpr->rx_jmb[src_idx].std;
+		src_map = &tpr->rx_jmb_buffers[src_idx];
 		break;
 
 	default:
@@ -4395,13 +4504,6 @@ static void tg3_recycle_rx(struct tg3 *tp, u32 opaque_key,
 	src_map->skb = NULL;
 }
 
-#if TG3_VLAN_TAG_USED
-static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
-{
-	return vlan_gro_receive(&tp->napi, tp->vlgrp, vlan_tag, skb);
-}
-#endif
-
 /* The RX ring scheme is composed of multiple rings which post fresh
  * buffers to the chip, and one special ring the chip uses to report
  * status back to the host.
@@ -4426,14 +4528,16 @@ static int tg3_vlan_rx(struct tg3 *tp, struct sk_buff *skb, u16 vlan_tag)
  * If both the host and chip were to write into the same ring, cache line
  * eviction could occur since both entities want it in an exclusive state.
  */
-static int tg3_rx(struct tg3 *tp, int budget)
+static int tg3_rx(struct tg3_napi *tnapi, int budget)
 {
+	struct tg3 *tp = tnapi->tp;
 	u32 work_mask, rx_std_posted = 0;
-	u32 sw_idx = tp->rx_rcb_ptr;
+	u32 sw_idx = tnapi->rx_rcb_ptr;
 	u16 hw_idx;
 	int received;
+	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
-	hw_idx = tp->hw_status->idx[0].rx_producer;
+	hw_idx = *(tnapi->rx_rcb_prod_idx);
 	/*
 	 * We need to order the read of hw_idx and the read of
 	 * the opaque cookie.
@@ -4442,7 +4546,7 @@ static int tg3_rx(struct tg3 *tp, int budget)
 	work_mask = 0;
 	received = 0;
 	while (sw_idx != hw_idx && budget > 0) {
-		struct tg3_rx_buffer_desc *desc = &tp->rx_rcb[sw_idx];
+		struct tg3_rx_buffer_desc *desc = &tnapi->rx_rcb[sw_idx];
 		unsigned int len;
 		struct sk_buff *skb;
 		dma_addr_t dma_addr;
@@ -4451,27 +4555,25 @@ static int tg3_rx(struct tg3 *tp, int budget)
 		desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
 		opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
 		if (opaque_key == RXD_OPAQUE_RING_STD) {
-			dma_addr = pci_unmap_addr(&tp->rx_std_buffers[desc_idx],
-						  mapping);
-			skb = tp->rx_std_buffers[desc_idx].skb;
-			post_ptr = &tp->rx_std_ptr;
+			struct ring_info *ri = &tpr->rx_std_buffers[desc_idx];
+			dma_addr = pci_unmap_addr(ri, mapping);
+			skb = ri->skb;
+			post_ptr = &tpr->rx_std_ptr;
 			rx_std_posted++;
 		} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
-			dma_addr = pci_unmap_addr(&tp->rx_jumbo_buffers[desc_idx],
-						  mapping);
-			skb = tp->rx_jumbo_buffers[desc_idx].skb;
-			post_ptr = &tp->rx_jumbo_ptr;
-		}
-		else {
+			struct ring_info *ri = &tpr->rx_jmb_buffers[desc_idx];
+			dma_addr = pci_unmap_addr(ri, mapping);
+			skb = ri->skb;
+			post_ptr = &tpr->rx_jmb_ptr;
+		} else
 			goto next_pkt_nopost;
-		}
 
 		work_mask |= opaque_key;
 
 		if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
 		    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) {
 		drop_it:
-			tg3_recycle_rx(tp, opaque_key,
+			tg3_recycle_rx(tnapi, opaque_key,
 				       desc_idx, *post_ptr);
 		drop_it_no_recycle:
 			/* Other statistics kept track of by card. */
@@ -4491,20 +4593,19 @@ static int tg3_rx(struct tg3 *tp, int budget)
 		) {
 			int skb_size;
 
-			skb_size = tg3_alloc_rx_skb(tp, opaque_key,
+			skb_size = tg3_alloc_rx_skb(tnapi, opaque_key,
 						    desc_idx, *post_ptr);
 			if (skb_size < 0)
 				goto drop_it;
 
-			pci_unmap_single(tp->pdev, dma_addr,
-					 skb_size - tp->rx_offset,
+			pci_unmap_single(tp->pdev, dma_addr, skb_size,
 					 PCI_DMA_FROMDEVICE);
 
 			skb_put(skb, len);
 		} else {
 			struct sk_buff *copy_skb;
 
-			tg3_recycle_rx(tp, opaque_key,
+			tg3_recycle_rx(tnapi, opaque_key,
 				       desc_idx, *post_ptr);
 
 			copy_skb = netdev_alloc_skb(tp->dev,
@@ -4541,11 +4642,11 @@ static int tg3_rx(struct tg3 *tp, int budget)
 #if TG3_VLAN_TAG_USED
 		if (tp->vlgrp != NULL &&
 		    desc->type_flags & RXD_FLAG_VLAN) {
-			tg3_vlan_rx(tp, skb,
-				    desc->err_vlan & RXD_VLAN_MASK);
+			vlan_gro_receive(&tnapi->napi, tp->vlgrp,
+					 desc->err_vlan & RXD_VLAN_MASK, skb);
 		} else
 #endif
-			napi_gro_receive(&tp->napi, skb);
+			napi_gro_receive(&tnapi->napi, skb);
 
 		received++;
 		budget--;
@@ -4567,23 +4668,23 @@ next_pkt_nopost:
 
 		/* Refresh hw_idx to see if there is new work */
 		if (sw_idx == hw_idx) {
-			hw_idx = tp->hw_status->idx[0].rx_producer;
+			hw_idx = *(tnapi->rx_rcb_prod_idx);
 			rmb();
 		}
 	}
 
 	/* ACK the status ring. */
-	tp->rx_rcb_ptr = sw_idx;
-	tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, sw_idx);
+	tnapi->rx_rcb_ptr = sw_idx;
+	tw32_rx_mbox(tnapi->consmbox, sw_idx);
 
 	/* Refill RX ring(s). */
 	if (work_mask & RXD_OPAQUE_RING_STD) {
-		sw_idx = tp->rx_std_ptr % TG3_RX_RING_SIZE;
+		sw_idx = tpr->rx_std_ptr % TG3_RX_RING_SIZE;
 		tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
 			     sw_idx);
 	}
 	if (work_mask & RXD_OPAQUE_RING_JUMBO) {
-		sw_idx = tp->rx_jumbo_ptr % TG3_RX_JUMBO_RING_SIZE;
+		sw_idx = tpr->rx_jmb_ptr % TG3_RX_JUMBO_RING_SIZE;
 		tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
 			     sw_idx);
 	}
@@ -4592,9 +4693,10 @@ next_pkt_nopost:
 	return received;
 }
 
-static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
+static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
 {
-	struct tg3_hw_status *sblk = tp->hw_status;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 
 	/* handle link change and other phy events */
 	if (!(tp->tg3_flags &
@@ -4618,8 +4720,8 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
 	}
 
 	/* run TX completion thread */
-	if (sblk->idx[0].tx_consumer != tp->tx_cons) {
-		tg3_tx(tp);
+	if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
+		tg3_tx(tnapi);
 		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
 			return work_done;
 	}
@@ -4628,20 +4730,21 @@ static int tg3_poll_work(struct tg3 *tp, int work_done, int budget)
 	 * All RX "locking" is done by ensuring outside
 	 * code synchronizes with tg3->napi.poll()
 	 */
-	if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr)
-		work_done += tg3_rx(tp, budget - work_done);
+	if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
+		work_done += tg3_rx(tnapi, budget - work_done);
 
 	return work_done;
 }
 
 static int tg3_poll(struct napi_struct *napi, int budget)
 {
-	struct tg3 *tp = container_of(napi, struct tg3, napi);
+	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
+	struct tg3 *tp = tnapi->tp;
 	int work_done = 0;
-	struct tg3_hw_status *sblk = tp->hw_status;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 
 	while (1) {
-		work_done = tg3_poll_work(tp, work_done, budget);
+		work_done = tg3_poll_work(tnapi, work_done, budget);
 
 		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
 			goto tx_recovery;
@@ -4650,19 +4753,19 @@ static int tg3_poll(struct napi_struct *napi, int budget)
 			break;
 
 		if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
-			/* tp->last_tag is used in tg3_restart_ints() below
+			/* tp->last_tag is used in tg3_int_reenable() below
 			 * to tell the hw how much work has been processed,
 			 * so we must read it before checking for more work.
 			 */
-			tp->last_tag = sblk->status_tag;
-			tp->last_irq_tag = tp->last_tag;
+			tnapi->last_tag = sblk->status_tag;
+			tnapi->last_irq_tag = tnapi->last_tag;
 			rmb();
 		} else
 			sblk->status &= ~SD_STATUS_UPDATED;
 
-		if (likely(!tg3_has_work(tp))) {
+		if (likely(!tg3_has_work(tnapi))) {
 			napi_complete(napi);
-			tg3_restart_ints(tp);
+			tg3_int_reenable(tnapi);
 			break;
 		}
 	}
@@ -4678,12 +4781,15 @@ tx_recovery:
 
 static void tg3_irq_quiesce(struct tg3 *tp)
 {
+	int i;
+
 	BUG_ON(tp->irq_sync);
 
 	tp->irq_sync = 1;
 	smp_mb();
 
-	synchronize_irq(tp->pdev->irq);
+	for (i = 0; i < tp->irq_cnt; i++)
+		synchronize_irq(tp->napi[i].irq_vec);
 }
 
 static inline int tg3_irq_sync(struct tg3 *tp)
@@ -4713,14 +4819,15 @@ static inline void tg3_full_unlock(struct tg3 *tp)
  */
 static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct tg3 *tp = netdev_priv(dev);
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
 
-	prefetch(tp->hw_status);
-	prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+	prefetch(tnapi->hw_status);
+	if (tnapi->rx_rcb)
+		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
 
 	if (likely(!tg3_irq_sync(tp)))
-		napi_schedule(&tp->napi);
+		napi_schedule(&tnapi->napi);
 
 	return IRQ_HANDLED;
 }
@@ -4731,11 +4838,12 @@ static irqreturn_t tg3_msi_1shot(int irq, void *dev_id)
  */
 static irqreturn_t tg3_msi(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct tg3 *tp = netdev_priv(dev);
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
 
-	prefetch(tp->hw_status);
-	prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+	prefetch(tnapi->hw_status);
+	if (tnapi->rx_rcb)
+		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
 	/*
 	 * Writing any value to intr-mbox-0 clears PCI INTA# and
 	 * chip-internal interrupt pending events.
@@ -4745,16 +4853,16 @@ static irqreturn_t tg3_msi(int irq, void *dev_id)
 	 */
 	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
 	if (likely(!tg3_irq_sync(tp)))
-		napi_schedule(&tp->napi);
+		napi_schedule(&tnapi->napi);
 
 	return IRQ_RETVAL(1);
 }
 
 static irqreturn_t tg3_interrupt(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct tg3 *tp = netdev_priv(dev);
-	struct tg3_hw_status *sblk = tp->hw_status;
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 	unsigned int handled = 1;
 
 	/* In INTx mode, it is possible for the interrupt to arrive at
@@ -4785,9 +4893,9 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id)
 	if (tg3_irq_sync(tp))
 		goto out;
 	sblk->status &= ~SD_STATUS_UPDATED;
-	if (likely(tg3_has_work(tp))) {
-		prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-		napi_schedule(&tp->napi);
+	if (likely(tg3_has_work(tnapi))) {
+		prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
+		napi_schedule(&tnapi->napi);
 	} else {
 		/* No work, shared interrupt perhaps?  re-enable
 		 * interrupts, and flush that PCI write
@@ -4801,9 +4909,9 @@ out:
 
 static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct tg3 *tp = netdev_priv(dev);
-	struct tg3_hw_status *sblk = tp->hw_status;
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 	unsigned int handled = 1;
 
 	/* In INTx mode, it is possible for the interrupt to arrive at
@@ -4811,7 +4919,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
 	 * Reading the PCI State register will confirm whether the
 	 * interrupt is ours and will flush the status block.
 	 */
-	if (unlikely(sblk->status_tag == tp->last_irq_tag)) {
+	if (unlikely(sblk->status_tag == tnapi->last_irq_tag)) {
 		if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
 		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
 			handled = 0;
@@ -4838,14 +4946,14 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
 	 * so that the above check can report that the screaming interrupts
 	 * are unhandled.  Eventually they will be silenced.
 	 */
-	tp->last_irq_tag = sblk->status_tag;
+	tnapi->last_irq_tag = sblk->status_tag;
 
 	if (tg3_irq_sync(tp))
 		goto out;
 
-	prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+	prefetch(&tnapi->rx_rcb[tnapi->rx_rcb_ptr]);
 
-	napi_schedule(&tp->napi);
+	napi_schedule(&tnapi->napi);
 
 out:
 	return IRQ_RETVAL(handled);
@@ -4854,9 +4962,9 @@ out:
 /* ISR for interrupt test */
 static irqreturn_t tg3_test_isr(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct tg3 *tp = netdev_priv(dev);
-	struct tg3_hw_status *sblk = tp->hw_status;
+	struct tg3_napi *tnapi = dev_id;
+	struct tg3 *tp = tnapi->tp;
+	struct tg3_hw_status *sblk = tnapi->hw_status;
 
 	if ((sblk->status & SD_STATUS_UPDATED) ||
 	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
@@ -4886,7 +4994,7 @@ static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
 		tg3_full_unlock(tp);
 		del_timer_sync(&tp->timer);
 		tp->irq_sync = 0;
-		napi_enable(&tp->napi);
+		tg3_napi_enable(tp);
 		dev_close(tp->dev);
 		tg3_full_lock(tp, 0);
 	}
@@ -4896,9 +5004,11 @@ static int tg3_restart_hw(struct tg3 *tp, int reset_phy)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void tg3_poll_controller(struct net_device *dev)
 {
+	int i;
 	struct tg3 *tp = netdev_priv(dev);
 
-	tg3_interrupt(tp->pdev->irq, dev);
+	for (i = 0; i < tp->irq_cnt; i++)
+		tg3_interrupt(tp->napi[i].irq_vec, dev);
 }
 #endif
 
@@ -4993,13 +5103,14 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
 #endif
 }
 
-static void tg3_set_txd(struct tg3 *, int, dma_addr_t, int, u32, u32);
+static void tg3_set_txd(struct tg3_napi *, int, dma_addr_t, int, u32, u32);
 
 /* Workaround 4GB and 40-bit hardware DMA bugs. */
 static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
 				       u32 last_plus_one, u32 *start,
 				       u32 base_flags, u32 mss)
 {
+	struct tg3_napi *tnapi = &tp->napi[0];
 	struct sk_buff *new_skb;
 	dma_addr_t new_addr = 0;
 	u32 entry = *start;
@@ -5034,7 +5145,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
 			dev_kfree_skb(new_skb);
 			new_skb = NULL;
 		} else {
-			tg3_set_txd(tp, entry, new_addr, new_skb->len,
+			tg3_set_txd(tnapi, entry, new_addr, new_skb->len,
 				    base_flags, 1 | (mss << 1));
 			*start = NEXT_TX(entry);
 		}
@@ -5043,11 +5154,10 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
 	/* Now clean up the sw ring entries. */
 	i = 0;
 	while (entry != last_plus_one) {
-		if (i == 0) {
-			tp->tx_buffers[entry].skb = new_skb;
-		} else {
-			tp->tx_buffers[entry].skb = NULL;
-		}
+		if (i == 0)
+			tnapi->tx_buffers[entry].skb = new_skb;
+		else
+			tnapi->tx_buffers[entry].skb = NULL;
 		entry = NEXT_TX(entry);
 		i++;
 	}
@@ -5058,11 +5168,11 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
 	return ret;
 }
 
-static void tg3_set_txd(struct tg3 *tp, int entry,
+static void tg3_set_txd(struct tg3_napi *tnapi, int entry,
 			dma_addr_t mapping, int len, u32 flags,
 			u32 mss_and_is_end)
 {
-	struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry];
+	struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry];
 	int is_end = (mss_and_is_end & 0x1);
 	u32 mss = (mss_and_is_end >> 1);
 	u32 vlan_tag = 0;
@@ -5084,23 +5194,29 @@ static void tg3_set_txd(struct tg3 *tp, int entry,
 /* hard_start_xmit for devices that don't have any bugs and
  * support TG3_FLG2_HW_TSO_2 only.
  */
-static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
+				  struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
 	u32 len, entry, base_flags, mss;
 	struct skb_shared_info *sp;
 	dma_addr_t mapping;
+	struct tg3_napi *tnapi;
+	struct netdev_queue *txq;
 
-	len = skb_headlen(skb);
+	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
+	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+		tnapi++;
 
 	/* We are running in BH disabled context with netif_tx_lock
 	 * and TX reclaim runs via tp->napi.poll inside of a software
 	 * interrupt.  Furthermore, IRQ processing runs lockless so we have
 	 * no IRQ context deadlocks to worry about either.  Rejoice!
 	 */
-	if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
-		if (!netif_queue_stopped(dev)) {
-			netif_stop_queue(dev);
+	if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
+		if (!netif_tx_queue_stopped(txq)) {
+			netif_tx_stop_queue(txq);
 
 			/* This is a hard error, log it. */
 			printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
@@ -5109,11 +5225,12 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 
-	entry = tp->tx_prod;
+	entry = tnapi->tx_prod;
 	base_flags = 0;
 	mss = 0;
 	if ((mss = skb_shinfo(skb)->gso_size) != 0) {
 		int tcp_opt_len, ip_tcp_len;
+		u32 hdrlen;
 
 		if (skb_header_cloned(skb) &&
 		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -5122,7 +5239,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 
 		if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
-			mss |= (skb_headlen(skb) - ETH_HLEN) << 9;
+			hdrlen = skb_headlen(skb) - ETH_HLEN;
 		else {
 			struct iphdr *iph = ip_hdr(skb);
 
@@ -5131,9 +5248,17 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 			iph->check = 0;
 			iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
-			mss |= (ip_tcp_len + tcp_opt_len) << 9;
+			hdrlen = ip_tcp_len + tcp_opt_len;
 		}
 
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+			mss |= (hdrlen & 0xc) << 12;
+			if (hdrlen & 0x10)
+				base_flags |= 0x00000010;
+			base_flags |= (hdrlen & 0x3e0) << 5;
+		} else
+			mss |= hdrlen << 9;
+
 		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
 			       TXD_FLAG_CPU_POST_DMA);
 
@@ -5157,9 +5282,15 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	mapping = sp->dma_head;
 
-	tp->tx_buffers[entry].skb = skb;
+	tnapi->tx_buffers[entry].skb = skb;
+
+	len = skb_headlen(skb);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+	    !mss && skb->len > ETH_DATA_LEN)
+		base_flags |= TXD_FLAG_JMB_PKT;
 
-	tg3_set_txd(tp, entry, mapping, len, base_flags,
+	tg3_set_txd(tnapi, entry, mapping, len, base_flags,
 		    (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
 
 	entry = NEXT_TX(entry);
@@ -5174,9 +5305,9 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 			len = frag->size;
 			mapping = sp->dma_maps[i];
-			tp->tx_buffers[entry].skb = NULL;
+			tnapi->tx_buffers[entry].skb = NULL;
 
-			tg3_set_txd(tp, entry, mapping, len,
+			tg3_set_txd(tnapi, entry, mapping, len,
 				    base_flags, (i == last) | (mss << 1));
 
 			entry = NEXT_TX(entry);
@@ -5184,13 +5315,13 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* Packets are ready, update Tx producer idx local and on card. */
-	tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
+	tw32_tx_mbox(tnapi->prodmbox, entry);
 
-	tp->tx_prod = entry;
-	if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
-		netif_stop_queue(dev);
-		if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))
-			netif_wake_queue(tp->dev);
+	tnapi->tx_prod = entry;
+	if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
+		netif_tx_stop_queue(txq);
+		if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
+			netif_tx_wake_queue(txq);
 	}
 
 out_unlock:
@@ -5199,7 +5330,8 @@ out_unlock:
 	return NETDEV_TX_OK;
 }
 
-static int tg3_start_xmit_dma_bug(struct sk_buff *, struct net_device *);
+static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *,
+					  struct net_device *);
 
 /* Use GSO to workaround a rare TSO bug that may be triggered when the
  * TSO header is greater than 80 bytes.
@@ -5207,11 +5339,12 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *, struct net_device *);
 static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
 {
 	struct sk_buff *segs, *nskb;
+	u32 frag_cnt_est = skb_shinfo(skb)->gso_segs * 3;
 
 	/* Estimate the number of fragments in the worst case */
-	if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) {
+	if (unlikely(tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)) {
 		netif_stop_queue(tp->dev);
-		if (tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))
+		if (tg3_tx_avail(&tp->napi[0]) <= frag_cnt_est)
 			return NETDEV_TX_BUSY;
 
 		netif_wake_queue(tp->dev);
@@ -5237,13 +5370,15 @@ tg3_tso_bug_end:
 /* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
  * support TG3_FLG2_HW_TSO_1 or firmware TSO only.
  */
-static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
+					  struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
 	u32 len, entry, base_flags, mss;
 	struct skb_shared_info *sp;
 	int would_hit_hwbug;
 	dma_addr_t mapping;
+	struct tg3_napi *tnapi = &tp->napi[0];
 
 	len = skb_headlen(skb);
 
@@ -5252,7 +5387,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 	 * interrupt.  Furthermore, IRQ processing runs lockless so we have
 	 * no IRQ context deadlocks to worry about either.  Rejoice!
 	 */
-	if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
+	if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
 		if (!netif_queue_stopped(dev)) {
 			netif_stop_queue(dev);
 
@@ -5263,7 +5398,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 
-	entry = tp->tx_prod;
+	entry = tnapi->tx_prod;
 	base_flags = 0;
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
 		base_flags |= TXD_FLAG_TCPUDP_CSUM;
@@ -5333,7 +5468,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 
 	mapping = sp->dma_head;
 
-	tp->tx_buffers[entry].skb = skb;
+	tnapi->tx_buffers[entry].skb = skb;
 
 	would_hit_hwbug = 0;
 
@@ -5342,7 +5477,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 	else if (tg3_4g_overflow_test(mapping, len))
 		would_hit_hwbug = 1;
 
-	tg3_set_txd(tp, entry, mapping, len, base_flags,
+	tg3_set_txd(tnapi, entry, mapping, len, base_flags,
 		    (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
 
 	entry = NEXT_TX(entry);
@@ -5358,7 +5493,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 			len = frag->size;
 			mapping = sp->dma_maps[i];
 
-			tp->tx_buffers[entry].skb = NULL;
+			tnapi->tx_buffers[entry].skb = NULL;
 
 			if (tg3_4g_overflow_test(mapping, len))
 				would_hit_hwbug = 1;
@@ -5367,10 +5502,10 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 				would_hit_hwbug = 1;
 
 			if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
-				tg3_set_txd(tp, entry, mapping, len,
+				tg3_set_txd(tnapi, entry, mapping, len,
 					    base_flags, (i == last)|(mss << 1));
 			else
-				tg3_set_txd(tp, entry, mapping, len,
+				tg3_set_txd(tnapi, entry, mapping, len,
 					    base_flags, (i == last));
 
 			entry = NEXT_TX(entry);
@@ -5395,12 +5530,12 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* Packets are ready, update Tx producer idx local and on card. */
-	tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
+	tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, entry);
 
-	tp->tx_prod = entry;
-	if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) {
+	tnapi->tx_prod = entry;
+	if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
 		netif_stop_queue(dev);
-		if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH(tp))
+		if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
 			netif_wake_queue(tp->dev);
 	}
 
@@ -5468,63 +5603,40 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
 	return err;
 }
 
-/* Free up pending packets in all rx/tx rings.
- *
- * The chip has been shut down and the driver detached from
- * the networking, so no interrupts or new tx packets will
- * end up in the driver.  tp->{tx,}lock is not held and we are not
- * in an interrupt context and thus may sleep.
- */
-static void tg3_free_rings(struct tg3 *tp)
+static void tg3_rx_prodring_free(struct tg3 *tp,
+				 struct tg3_rx_prodring_set *tpr)
 {
-	struct ring_info *rxp;
 	int i;
+	struct ring_info *rxp;
 
 	for (i = 0; i < TG3_RX_RING_SIZE; i++) {
-		rxp = &tp->rx_std_buffers[i];
+		rxp = &tpr->rx_std_buffers[i];
 
 		if (rxp->skb == NULL)
 			continue;
-		pci_unmap_single(tp->pdev,
-				 pci_unmap_addr(rxp, mapping),
-				 tp->rx_pkt_buf_sz - tp->rx_offset,
-				 PCI_DMA_FROMDEVICE);
-		dev_kfree_skb_any(rxp->skb);
-		rxp->skb = NULL;
-	}
-
-	for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
-		rxp = &tp->rx_jumbo_buffers[i];
 
-		if (rxp->skb == NULL)
-			continue;
 		pci_unmap_single(tp->pdev,
 				 pci_unmap_addr(rxp, mapping),
-				 RX_JUMBO_PKT_BUF_SZ - tp->rx_offset,
+				 tp->rx_pkt_map_sz,
 				 PCI_DMA_FROMDEVICE);
 		dev_kfree_skb_any(rxp->skb);
 		rxp->skb = NULL;
 	}
 
-	for (i = 0; i < TG3_TX_RING_SIZE; ) {
-		struct tx_ring_info *txp;
-		struct sk_buff *skb;
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+			rxp = &tpr->rx_jmb_buffers[i];
 
-		txp = &tp->tx_buffers[i];
-		skb = txp->skb;
+			if (rxp->skb == NULL)
+				continue;
 
-		if (skb == NULL) {
-			i++;
-			continue;
+			pci_unmap_single(tp->pdev,
+					 pci_unmap_addr(rxp, mapping),
+					 TG3_RX_JMB_MAP_SZ,
+					 PCI_DMA_FROMDEVICE);
+			dev_kfree_skb_any(rxp->skb);
+			rxp->skb = NULL;
 		}
-
-		skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
-
-		txp->skb = NULL;
-
-		i += skb_shinfo(skb)->nr_frags + 1;
-
-		dev_kfree_skb_any(skb);
 	}
 }
 
@@ -5535,23 +5647,20 @@ static void tg3_free_rings(struct tg3 *tp)
  * end up in the driver.  tp->{tx,}lock are held and thus
  * we may not sleep.
  */
-static int tg3_init_rings(struct tg3 *tp)
+static int tg3_rx_prodring_alloc(struct tg3 *tp,
+				 struct tg3_rx_prodring_set *tpr)
 {
-	u32 i;
-
-	/* Free up all the SKBs. */
-	tg3_free_rings(tp);
+	u32 i, rx_pkt_dma_sz;
+	struct tg3_napi *tnapi = &tp->napi[0];
 
 	/* Zero out all descriptors. */
-	memset(tp->rx_std, 0, TG3_RX_RING_BYTES);
-	memset(tp->rx_jumbo, 0, TG3_RX_JUMBO_RING_BYTES);
-	memset(tp->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
-	memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
+	memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);
 
-	tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ;
+	rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
 	if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
-	    (tp->dev->mtu > ETH_DATA_LEN))
-		tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ;
+	    tp->dev->mtu > ETH_DATA_LEN)
+		rx_pkt_dma_sz = TG3_RX_JMB_DMA_SZ;
+	tp->rx_pkt_map_sz = TG3_RX_DMA_TO_MAP_SZ(rx_pkt_dma_sz);
 
 	/* Initialize invariants of the rings, we only set this
 	 * stuff once.  This works because the card does not
@@ -5560,102 +5669,242 @@ static int tg3_init_rings(struct tg3 *tp)
 	for (i = 0; i < TG3_RX_RING_SIZE; i++) {
 		struct tg3_rx_buffer_desc *rxd;
 
-		rxd = &tp->rx_std[i];
-		rxd->idx_len = (tp->rx_pkt_buf_sz - tp->rx_offset - 64)
-			<< RXD_LEN_SHIFT;
+		rxd = &tpr->rx_std[i];
+		rxd->idx_len = rx_pkt_dma_sz << RXD_LEN_SHIFT;
 		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
 		rxd->opaque = (RXD_OPAQUE_RING_STD |
 			       (i << RXD_OPAQUE_INDEX_SHIFT));
 	}
 
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
-		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
-			struct tg3_rx_buffer_desc *rxd;
-
-			rxd = &tp->rx_jumbo[i];
-			rxd->idx_len = (RX_JUMBO_PKT_BUF_SZ - tp->rx_offset - 64)
-				<< RXD_LEN_SHIFT;
-			rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
-				RXD_FLAG_JUMBO;
-			rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
-			       (i << RXD_OPAQUE_INDEX_SHIFT));
-		}
-	}
-
 	/* Now allocate fresh SKBs for each rx ring. */
 	for (i = 0; i < tp->rx_pending; i++) {
-		if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) {
+		if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_STD, -1, i) < 0) {
 			printk(KERN_WARNING PFX
 			       "%s: Using a smaller RX standard ring, "
 			       "only %d out of %d buffers were allocated "
 			       "successfully.\n",
 			       tp->dev->name, i, tp->rx_pending);
 			if (i == 0)
-				return -ENOMEM;
+				goto initfail;
 			tp->rx_pending = i;
 			break;
 		}
 	}
 
+	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE))
+		goto done;
+
+	memset(tpr->rx_jmb, 0, TG3_RX_JUMBO_RING_BYTES);
+
 	if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
+		for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
+			struct tg3_rx_buffer_desc *rxd;
+
+			rxd = &tpr->rx_jmb[i].std;
+			rxd->idx_len = TG3_RX_JMB_DMA_SZ << RXD_LEN_SHIFT;
+			rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT) |
+				RXD_FLAG_JUMBO;
+			rxd->opaque = (RXD_OPAQUE_RING_JUMBO |
+			       (i << RXD_OPAQUE_INDEX_SHIFT));
+		}
+
 		for (i = 0; i < tp->rx_jumbo_pending; i++) {
-			if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO,
+			if (tg3_alloc_rx_skb(tnapi, RXD_OPAQUE_RING_JUMBO,
 					     -1, i) < 0) {
 				printk(KERN_WARNING PFX
 				       "%s: Using a smaller RX jumbo ring, "
 				       "only %d out of %d buffers were "
 				       "allocated successfully.\n",
 				       tp->dev->name, i, tp->rx_jumbo_pending);
-				if (i == 0) {
-					tg3_free_rings(tp);
-					return -ENOMEM;
-				}
+				if (i == 0)
+					goto initfail;
 				tp->rx_jumbo_pending = i;
 				break;
 			}
 		}
 	}
+
+done:
 	return 0;
+
+initfail:
+	tg3_rx_prodring_free(tp, tpr);
+	return -ENOMEM;
 }
 
-/*
- * Must not be invoked with interrupt sources disabled and
- * the hardware shutdown down.
- */
-static void tg3_free_consistent(struct tg3 *tp)
+static void tg3_rx_prodring_fini(struct tg3 *tp,
+				 struct tg3_rx_prodring_set *tpr)
 {
-	kfree(tp->rx_std_buffers);
-	tp->rx_std_buffers = NULL;
-	if (tp->rx_std) {
+	kfree(tpr->rx_std_buffers);
+	tpr->rx_std_buffers = NULL;
+	kfree(tpr->rx_jmb_buffers);
+	tpr->rx_jmb_buffers = NULL;
+	if (tpr->rx_std) {
 		pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
-				    tp->rx_std, tp->rx_std_mapping);
-		tp->rx_std = NULL;
+				    tpr->rx_std, tpr->rx_std_mapping);
+		tpr->rx_std = NULL;
 	}
-	if (tp->rx_jumbo) {
+	if (tpr->rx_jmb) {
 		pci_free_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
-				    tp->rx_jumbo, tp->rx_jumbo_mapping);
-		tp->rx_jumbo = NULL;
+				    tpr->rx_jmb, tpr->rx_jmb_mapping);
+		tpr->rx_jmb = NULL;
+	}
+}
+
+static int tg3_rx_prodring_init(struct tg3 *tp,
+				struct tg3_rx_prodring_set *tpr)
+{
+	tpr->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
+				      TG3_RX_RING_SIZE, GFP_KERNEL);
+	if (!tpr->rx_std_buffers)
+		return -ENOMEM;
+
+	tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
+					   &tpr->rx_std_mapping);
+	if (!tpr->rx_std)
+		goto err_out;
+
+	if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+		tpr->rx_jmb_buffers = kzalloc(sizeof(struct ring_info) *
+					      TG3_RX_JUMBO_RING_SIZE,
+					      GFP_KERNEL);
+		if (!tpr->rx_jmb_buffers)
+			goto err_out;
+
+		tpr->rx_jmb = pci_alloc_consistent(tp->pdev,
+						   TG3_RX_JUMBO_RING_BYTES,
+						   &tpr->rx_jmb_mapping);
+		if (!tpr->rx_jmb)
+			goto err_out;
 	}
-	if (tp->rx_rcb) {
-		pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
-				    tp->rx_rcb, tp->rx_rcb_mapping);
-		tp->rx_rcb = NULL;
+
+	return 0;
+
+err_out:
+	tg3_rx_prodring_fini(tp, tpr);
+	return -ENOMEM;
+}
+
+/* Free up pending packets in all rx/tx rings.
+ *
+ * The chip has been shut down and the driver detached from
+ * the networking, so no interrupts or new tx packets will
+ * end up in the driver.  tp->{tx,}lock is not held and we are not
+ * in an interrupt context and thus may sleep.
+ */
+static void tg3_free_rings(struct tg3 *tp)
+{
+	int i, j;
+
+	for (j = 0; j < tp->irq_cnt; j++) {
+		struct tg3_napi *tnapi = &tp->napi[j];
+
+		if (!tnapi->tx_buffers)
+			continue;
+
+		for (i = 0; i < TG3_TX_RING_SIZE; ) {
+			struct tx_ring_info *txp;
+			struct sk_buff *skb;
+
+			txp = &tnapi->tx_buffers[i];
+			skb = txp->skb;
+
+			if (skb == NULL) {
+				i++;
+				continue;
+			}
+
+			skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
+
+			txp->skb = NULL;
+
+			i += skb_shinfo(skb)->nr_frags + 1;
+
+			dev_kfree_skb_any(skb);
+		}
 	}
-	if (tp->tx_ring) {
-		pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
-			tp->tx_ring, tp->tx_desc_mapping);
-		tp->tx_ring = NULL;
+
+	tg3_rx_prodring_free(tp, &tp->prodring[0]);
+}
+
+/* Initialize tx/rx rings for packet processing.
+ *
+ * The chip has been shut down and the driver detached from
+ * the networking, so no interrupts or new tx packets will
+ * end up in the driver.  tp->{tx,}lock are held and thus
+ * we may not sleep.
+ */
+static int tg3_init_rings(struct tg3 *tp)
+{
+	int i;
+
+	/* Free up all the SKBs. */
+	tg3_free_rings(tp);
+
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+
+		tnapi->last_tag = 0;
+		tnapi->last_irq_tag = 0;
+		tnapi->hw_status->status = 0;
+		tnapi->hw_status->status_tag = 0;
+		memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+		tnapi->tx_prod = 0;
+		tnapi->tx_cons = 0;
+		if (tnapi->tx_ring)
+			memset(tnapi->tx_ring, 0, TG3_TX_RING_BYTES);
+
+		tnapi->rx_rcb_ptr = 0;
+		if (tnapi->rx_rcb)
+			memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
 	}
-	if (tp->hw_status) {
-		pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
-				    tp->hw_status, tp->status_mapping);
-		tp->hw_status = NULL;
+
+	return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
+}
+
+/*
+ * Must not be invoked with interrupt sources disabled and
+ * the hardware shutdown down.
+ */
+static void tg3_free_consistent(struct tg3 *tp)
+{
+	int i;
+
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+
+		if (tnapi->tx_ring) {
+			pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
+				tnapi->tx_ring, tnapi->tx_desc_mapping);
+			tnapi->tx_ring = NULL;
+		}
+
+		kfree(tnapi->tx_buffers);
+		tnapi->tx_buffers = NULL;
+
+		if (tnapi->rx_rcb) {
+			pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
+					    tnapi->rx_rcb,
+					    tnapi->rx_rcb_mapping);
+			tnapi->rx_rcb = NULL;
+		}
+
+		if (tnapi->hw_status) {
+			pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
+					    tnapi->hw_status,
+					    tnapi->status_mapping);
+			tnapi->hw_status = NULL;
+		}
 	}
+
 	if (tp->hw_stats) {
 		pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats),
 				    tp->hw_stats, tp->stats_mapping);
 		tp->hw_stats = NULL;
 	}
+
+	tg3_rx_prodring_fini(tp, &tp->prodring[0]);
 }
 
 /*
@@ -5664,54 +5913,79 @@ static void tg3_free_consistent(struct tg3 *tp)
  */
 static int tg3_alloc_consistent(struct tg3 *tp)
 {
-	tp->rx_std_buffers = kzalloc((sizeof(struct ring_info) *
-				      (TG3_RX_RING_SIZE +
-				       TG3_RX_JUMBO_RING_SIZE)) +
-				     (sizeof(struct tx_ring_info) *
-				      TG3_TX_RING_SIZE),
-				     GFP_KERNEL);
-	if (!tp->rx_std_buffers)
-		return -ENOMEM;
+	int i;
 
-	tp->rx_jumbo_buffers = &tp->rx_std_buffers[TG3_RX_RING_SIZE];
-	tp->tx_buffers = (struct tx_ring_info *)
-		&tp->rx_jumbo_buffers[TG3_RX_JUMBO_RING_SIZE];
+	if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
+		return -ENOMEM;
 
-	tp->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES,
-					  &tp->rx_std_mapping);
-	if (!tp->rx_std)
+	tp->hw_stats = pci_alloc_consistent(tp->pdev,
+					    sizeof(struct tg3_hw_stats),
+					    &tp->stats_mapping);
+	if (!tp->hw_stats)
 		goto err_out;
 
-	tp->rx_jumbo = pci_alloc_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES,
-					    &tp->rx_jumbo_mapping);
+	memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
 
-	if (!tp->rx_jumbo)
-		goto err_out;
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+		struct tg3_hw_status *sblk;
 
-	tp->rx_rcb = pci_alloc_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
-					  &tp->rx_rcb_mapping);
-	if (!tp->rx_rcb)
-		goto err_out;
+		tnapi->hw_status = pci_alloc_consistent(tp->pdev,
+							TG3_HW_STATUS_SIZE,
+							&tnapi->status_mapping);
+		if (!tnapi->hw_status)
+			goto err_out;
 
-	tp->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES,
-					   &tp->tx_desc_mapping);
-	if (!tp->tx_ring)
-		goto err_out;
+		memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+		sblk = tnapi->hw_status;
 
-	tp->hw_status = pci_alloc_consistent(tp->pdev,
-					     TG3_HW_STATUS_SIZE,
-					     &tp->status_mapping);
-	if (!tp->hw_status)
-		goto err_out;
+		/*
+		 * When RSS is enabled, the status block format changes
+		 * slightly.  The "rx_jumbo_consumer", "reserved",
+		 * and "rx_mini_consumer" members get mapped to the
+		 * other three rx return ring producer indexes.
+		 */
+		switch (i) {
+		default:
+			tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer;
+			break;
+		case 2:
+			tnapi->rx_rcb_prod_idx = &sblk->rx_jumbo_consumer;
+			break;
+		case 3:
+			tnapi->rx_rcb_prod_idx = &sblk->reserved;
+			break;
+		case 4:
+			tnapi->rx_rcb_prod_idx = &sblk->rx_mini_consumer;
+			break;
+		}
 
-	tp->hw_stats = pci_alloc_consistent(tp->pdev,
-					    sizeof(struct tg3_hw_stats),
-					    &tp->stats_mapping);
-	if (!tp->hw_stats)
-		goto err_out;
+		/*
+		 * If multivector RSS is enabled, vector 0 does not handle
+		 * rx or tx interrupts.  Don't allocate any resources for it.
+		 */
+		if (!i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS))
+			continue;
 
-	memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
-	memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
+		tnapi->rx_rcb = pci_alloc_consistent(tp->pdev,
+						     TG3_RX_RCB_RING_BYTES(tp),
+						     &tnapi->rx_rcb_mapping);
+		if (!tnapi->rx_rcb)
+			goto err_out;
+
+		memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
+
+		tnapi->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
+					    TG3_TX_RING_SIZE, GFP_KERNEL);
+		if (!tnapi->tx_buffers)
+			goto err_out;
+
+		tnapi->tx_ring = pci_alloc_consistent(tp->pdev,
+						      TG3_TX_RING_BYTES,
+						      &tnapi->tx_desc_mapping);
+		if (!tnapi->tx_ring)
+			goto err_out;
+	}
 
 	return 0;
 
@@ -5823,8 +6097,11 @@ static int tg3_abort_hw(struct tg3 *tp, int silent)
 	err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
 	err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);
 
-	if (tp->hw_status)
-		memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+		if (tnapi->hw_status)
+			memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+	}
 	if (tp->hw_stats)
 		memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
 
@@ -6111,7 +6388,7 @@ static int tg3_chip_reset(struct tg3 *tp)
 {
 	u32 val;
 	void (*write_op)(struct tg3 *, u32, u32);
-	int err;
+	int i, err;
 
 	tg3_nvram_lock(tp);
 
@@ -6151,14 +6428,24 @@ static int tg3_chip_reset(struct tg3 *tp)
 	 * sharing or irqpoll.
 	 */
 	tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
-	if (tp->hw_status) {
-		tp->hw_status->status = 0;
-		tp->hw_status->status_tag = 0;
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+		if (tnapi->hw_status) {
+			tnapi->hw_status->status = 0;
+			tnapi->hw_status->status_tag = 0;
+		}
+		tnapi->last_tag = 0;
+		tnapi->last_irq_tag = 0;
 	}
-	tp->last_tag = 0;
-	tp->last_irq_tag = 0;
 	smp_mb();
-	synchronize_irq(tp->pdev->irq);
+
+	for (i = 0; i < tp->irq_cnt; i++)
+		synchronize_irq(tp->napi[i].irq_vec);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+		val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+		tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
+	}
 
 	/* do the reset */
 	val = GRC_MISC_CFG_CORECLK_RESET;
@@ -6212,6 +6499,8 @@ static int tg3_chip_reset(struct tg3 *tp)
 	udelay(120);
 
 	if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pcie_cap) {
+		u16 val16;
+
 		if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
 			int i;
 			u32 cfg_val;
@@ -6225,12 +6514,22 @@ static int tg3_chip_reset(struct tg3 *tp)
 					       cfg_val | (1 << 15));
 		}
 
-		/* Set PCIE max payload size to 128 bytes and
-		 * clear the "no snoop" and "relaxed ordering" bits.
+		/* Clear the "no snoop" and "relaxed ordering" bits. */
+		pci_read_config_word(tp->pdev,
+				     tp->pcie_cap + PCI_EXP_DEVCTL,
+				     &val16);
+		val16 &= ~(PCI_EXP_DEVCTL_RELAX_EN |
+			   PCI_EXP_DEVCTL_NOSNOOP_EN);
+		/*
+		 * Older PCIe devices only support the 128 byte
+		 * MPS setting.  Enforce the restriction.
 		 */
+		if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
+		    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784))
+			val16 &= ~PCI_EXP_DEVCTL_PAYLOAD;
 		pci_write_config_word(tp->pdev,
 				      tp->pcie_cap + PCI_EXP_DEVCTL,
-				      0);
+				      val16);
 
 		pcie_set_readrq(tp->pdev, 4096);
 
@@ -6288,16 +6587,18 @@ static int tg3_chip_reset(struct tg3 *tp)
 		tw32_f(MAC_MODE, 0);
 	udelay(40);
 
-	tg3_mdio_start(tp);
-
 	tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
 
 	err = tg3_poll_fw(tp);
 	if (err)
 		return err;
 
+	tg3_mdio_start(tp);
+
 	if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
-	    tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
+	    tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
 		val = tr32(0x7c00);
 
 		tw32(0x7c00, val | (1 << 25));
@@ -6647,24 +6948,175 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr,
 static void __tg3_set_rx_mode(struct net_device *);
 static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
 {
-	tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
-	tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
-	tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
-	tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-		tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
-		tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
+	int i;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+		tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
+		tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
+		tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
+
+		tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
+		tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
+		tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
+	} else {
+		tw32(HOSTCC_TXCOL_TICKS, 0);
+		tw32(HOSTCC_TXMAX_FRAMES, 0);
+		tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
+
+		tw32(HOSTCC_RXCOL_TICKS, 0);
+		tw32(HOSTCC_RXMAX_FRAMES, 0);
+		tw32(HOSTCC_RXCOAL_MAXF_INT, 0);
 	}
-	tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
-	tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
+
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
 		u32 val = ec->stats_block_coalesce_usecs;
 
+		tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
+		tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq);
+
 		if (!netif_carrier_ok(tp->dev))
 			val = 0;
 
 		tw32(HOSTCC_STAT_COAL_TICKS, val);
 	}
+
+	for (i = 0; i < tp->irq_cnt - 1; i++) {
+		u32 reg;
+
+		reg = HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18;
+		tw32(reg, ec->rx_coalesce_usecs);
+		reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
+		tw32(reg, ec->tx_coalesce_usecs);
+		reg = HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18;
+		tw32(reg, ec->rx_max_coalesced_frames);
+		reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
+		tw32(reg, ec->tx_max_coalesced_frames);
+		reg = HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18;
+		tw32(reg, ec->rx_max_coalesced_frames_irq);
+		reg = HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18;
+		tw32(reg, ec->tx_max_coalesced_frames_irq);
+	}
+
+	for (; i < tp->irq_max - 1; i++) {
+		tw32(HOSTCC_RXCOL_TICKS_VEC1 + i * 0x18, 0);
+		tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
+		tw32(HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18, 0);
+		tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
+		tw32(HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
+		tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
+	}
+}
+
+/* tp->lock is held. */
+static void tg3_rings_reset(struct tg3 *tp)
+{
+	int i;
+	u32 stblk, txrcb, rxrcb, limit;
+	struct tg3_napi *tnapi = &tp->napi[0];
+
+	/* Disable all transmit rings but the first. */
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
+	else
+		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
+
+	for (txrcb = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE;
+	     txrcb < limit; txrcb += TG3_BDINFO_SIZE)
+		tg3_write_mem(tp, txrcb + TG3_BDINFO_MAXLEN_FLAGS,
+			      BDINFO_FLAGS_DISABLED);
+
+
+	/* Disable all receive return rings but the first. */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17;
+	else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
+		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 4;
+	else
+		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE;
+
+	for (rxrcb = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE;
+	     rxrcb < limit; rxrcb += TG3_BDINFO_SIZE)
+		tg3_write_mem(tp, rxrcb + TG3_BDINFO_MAXLEN_FLAGS,
+			      BDINFO_FLAGS_DISABLED);
+
+	/* Disable interrupts */
+	tw32_mailbox_f(tp->napi[0].int_mbox, 1);
+
+	/* Zero mailbox registers. */
+	if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
+		for (i = 1; i < TG3_IRQ_MAX_VECS; i++) {
+			tp->napi[i].tx_prod = 0;
+			tp->napi[i].tx_cons = 0;
+			tw32_mailbox(tp->napi[i].prodmbox, 0);
+			tw32_rx_mbox(tp->napi[i].consmbox, 0);
+			tw32_mailbox_f(tp->napi[i].int_mbox, 1);
+		}
+	} else {
+		tp->napi[0].tx_prod = 0;
+		tp->napi[0].tx_cons = 0;
+		tw32_mailbox(tp->napi[0].prodmbox, 0);
+		tw32_rx_mbox(tp->napi[0].consmbox, 0);
+	}
+
+	/* Make sure the NIC-based send BD rings are disabled. */
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+		u32 mbox = MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+		for (i = 0; i < 16; i++)
+			tw32_tx_mbox(mbox + i * 8, 0);
+	}
+
+	txrcb = NIC_SRAM_SEND_RCB;
+	rxrcb = NIC_SRAM_RCV_RET_RCB;
+
+	/* Clear status block in ram. */
+	memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+	/* Set status block DMA address */
+	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
+	     ((u64) tnapi->status_mapping >> 32));
+	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
+	     ((u64) tnapi->status_mapping & 0xffffffff));
+
+	if (tnapi->tx_ring) {
+		tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
+			       (TG3_TX_RING_SIZE <<
+				BDINFO_FLAGS_MAXLEN_SHIFT),
+			       NIC_SRAM_TX_BUFFER_DESC);
+		txrcb += TG3_BDINFO_SIZE;
+	}
+
+	if (tnapi->rx_rcb) {
+		tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
+			       (TG3_RX_RCB_RING_SIZE(tp) <<
+				BDINFO_FLAGS_MAXLEN_SHIFT), 0);
+		rxrcb += TG3_BDINFO_SIZE;
+	}
+
+	stblk = HOSTCC_STATBLCK_RING1;
+
+	for (i = 1, tnapi++; i < tp->irq_cnt; i++, tnapi++) {
+		u64 mapping = (u64)tnapi->status_mapping;
+		tw32(stblk + TG3_64BIT_REG_HIGH, mapping >> 32);
+		tw32(stblk + TG3_64BIT_REG_LOW, mapping & 0xffffffff);
+
+		/* Clear status block in ram. */
+		memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+		tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
+			       (TG3_TX_RING_SIZE <<
+				BDINFO_FLAGS_MAXLEN_SHIFT),
+			       NIC_SRAM_TX_BUFFER_DESC);
+
+		tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
+			       (TG3_RX_RCB_RING_SIZE(tp) <<
+				BDINFO_FLAGS_MAXLEN_SHIFT), 0);
+
+		stblk += 8;
+		txrcb += TG3_BDINFO_SIZE;
+		rxrcb += TG3_BDINFO_SIZE;
+	}
 }
 
 /* tp->lock is held. */
@@ -6672,6 +7124,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
 	u32 val, rdmac_mode;
 	int i, err, limit;
+	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
 
 	tg3_disable_ints(tp);
 
@@ -6719,6 +7172,20 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 		val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN |
 		       PCIE_PWR_MGMT_L1_THRESH_4MS;
 		tw32(PCIE_PWR_MGMT_THRESH, val);
+
+		val = tr32(TG3_PCIE_EIDLE_DELAY) & ~TG3_PCIE_EIDLE_DELAY_MASK;
+		tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS);
+
+		tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
+	}
+
+	if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
+		val = tr32(TG3_PCIE_LNKCTL);
+		if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG)
+			val |= TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+		else
+			val &= ~TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
+		tw32(TG3_PCIE_LNKCTL, val);
 	}
 
 	/* This works around an issue with Athlon chipsets on
@@ -6766,7 +7233,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 		return err;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
 		/* This value is determined during the probe time DMA
 		 * engine test, tg3_test_dma.
 		 */
@@ -6886,35 +7354,33 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	 * configurable.
 	 */
 	tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
-	     ((u64) tp->rx_std_mapping >> 32));
+	     ((u64) tpr->rx_std_mapping >> 32));
 	tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
-	     ((u64) tp->rx_std_mapping & 0xffffffff));
+	     ((u64) tpr->rx_std_mapping & 0xffffffff));
 	tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
 	     NIC_SRAM_RX_BUFFER_DESC);
 
-	/* Don't even try to program the JUMBO/MINI buffer descriptor
-	 * configs on 5705.
-	 */
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
-		tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
-		     RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT);
-	} else {
-		tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
-		     RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
-
+	/* Disable the mini ring */
+	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
 		tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
 		     BDINFO_FLAGS_DISABLED);
 
+	/* Program the jumbo buffer descriptor ring control
+	 * blocks on those devices that have them.
+	 */
+	if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
+	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
 		/* Setup replenish threshold. */
 		tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
 
 		if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
-			     ((u64) tp->rx_jumbo_mapping >> 32));
+			     ((u64) tpr->rx_jmb_mapping >> 32));
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
-			     ((u64) tp->rx_jumbo_mapping & 0xffffffff));
+			     ((u64) tpr->rx_jmb_mapping & 0xffffffff));
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
-			     RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT);
+			     (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
+			     BDINFO_FLAGS_USE_EXT_RECV);
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
 			     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
 		} else {
@@ -6922,57 +7388,31 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 			     BDINFO_FLAGS_DISABLED);
 		}
 
-	}
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+			val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) |
+			      (RX_STD_MAX_SIZE << 2);
+		else
+			val = RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT;
+	} else
+		val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
 
-	/* There is only one send ring on 5705/5750, no need to explicitly
-	 * disable the others.
-	 */
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-		/* Clear out send RCB ring in SRAM. */
-		for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE)
-			tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS,
-				      BDINFO_FLAGS_DISABLED);
-	}
+	tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
 
-	tp->tx_prod = 0;
-	tp->tx_cons = 0;
-	tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
-	tw32_tx_mbox(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+	tpr->rx_std_ptr = tp->rx_pending;
+	tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
+		     tpr->rx_std_ptr);
 
-	tg3_set_bdinfo(tp, NIC_SRAM_SEND_RCB,
-		       tp->tx_desc_mapping,
-		       (TG3_TX_RING_SIZE <<
-			BDINFO_FLAGS_MAXLEN_SHIFT),
-		       NIC_SRAM_TX_BUFFER_DESC);
+	tpr->rx_jmb_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
+			  tp->rx_jumbo_pending : 0;
+	tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
+		     tpr->rx_jmb_ptr);
 
-	/* There is only one receive return ring on 5705/5750, no need
-	 * to explicitly disable the others.
-	 */
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
-		for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK;
-		     i += TG3_BDINFO_SIZE) {
-			tg3_write_mem(tp, i + TG3_BDINFO_MAXLEN_FLAGS,
-				      BDINFO_FLAGS_DISABLED);
-		}
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+		tw32(STD_REPLENISH_LWM, 32);
+		tw32(JMB_REPLENISH_LWM, 16);
 	}
 
-	tp->rx_rcb_ptr = 0;
-	tw32_rx_mbox(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0);
-
-	tg3_set_bdinfo(tp, NIC_SRAM_RCV_RET_RCB,
-		       tp->rx_rcb_mapping,
-		       (TG3_RX_RCB_RING_SIZE(tp) <<
-			BDINFO_FLAGS_MAXLEN_SHIFT),
-		       0);
-
-	tp->rx_std_ptr = tp->rx_pending;
-	tw32_rx_mbox(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
-		     tp->rx_std_ptr);
-
-	tp->rx_jumbo_ptr = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
-						tp->rx_jumbo_pending : 0;
-	tw32_rx_mbox(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW,
-		     tp->rx_jumbo_ptr);
+	tg3_rings_reset(tp);
 
 	/* Initialize MAC address and backoff seed. */
 	__tg3_set_mac_addr(tp, 0);
@@ -7061,12 +7501,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 
 	__tg3_set_coalesce(tp, &tp->coal);
 
-	/* set status block DMA address */
-	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH,
-	     ((u64) tp->status_mapping >> 32));
-	tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
-	     ((u64) tp->status_mapping & 0xffffffff));
-
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
 		/* Status/statistics block address.  See tg3_timer,
 		 * the tg3_periodic_fetch_stats call there, and
@@ -7077,7 +7511,16 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 		tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
 		     ((u64) tp->stats_mapping & 0xffffffff));
 		tw32(HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK);
+
 		tw32(HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK);
+
+		/* Clear statistics and status block memory areas */
+		for (i = NIC_SRAM_STATS_BLK;
+		     i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
+		     i += sizeof(u32)) {
+			tg3_write_mem(tp, i, 0);
+			udelay(40);
+		}
 	}
 
 	tw32(HOSTCC_MODE, HOSTCC_MODE_ENABLE | tp->coalesce_mode);
@@ -7087,15 +7530,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
 		tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE);
 
-	/* Clear statistics/status block in chip, and status block in ram. */
-	for (i = NIC_SRAM_STATS_BLK;
-	     i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
-	     i += sizeof(u32)) {
-		tg3_write_mem(tp, i, 0);
-		udelay(40);
-	}
-	memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
-
 	if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
 		tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
 		/* reset to prevent losing 1st rx packet intermittently */
@@ -7147,7 +7581,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
 	udelay(100);
 
-	tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
+	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) {
+		val = tr32(MSGINT_MODE);
+		val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
+		tw32(MSGINT_MODE, val);
+	}
 
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
 		tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -7164,7 +7602,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
 	     tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
-		if ((tp->tg3_flags & TG3_FLG2_TSO_CAPABLE) &&
+		if ((tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
 		    (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 ||
 		     tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) {
 			/* nothing */
@@ -7217,7 +7655,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
 	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
 		tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
-	tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE);
+	val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE;
+	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+		val |= SNDBDI_MODE_MULTI_TXQ_EN;
+	tw32(SNDBDI_MODE, val);
 	tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
 
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
@@ -7236,10 +7677,46 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 	tw32_f(MAC_TX_MODE, tp->tx_mode);
 	udelay(100);
 
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) {
+		u32 reg = MAC_RSS_INDIR_TBL_0;
+		u8 *ent = (u8 *)&val;
+
+		/* Setup the indirection table */
+		for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) {
+			int idx = i % sizeof(val);
+
+			ent[idx] = i % (tp->irq_cnt - 1);
+			if (idx == sizeof(val) - 1) {
+				tw32(reg, val);
+				reg += 4;
+			}
+		}
+
+		/* Setup the "secret" hash key. */
+		tw32(MAC_RSS_HASH_KEY_0, 0x5f865437);
+		tw32(MAC_RSS_HASH_KEY_1, 0xe4ac62cc);
+		tw32(MAC_RSS_HASH_KEY_2, 0x50103a45);
+		tw32(MAC_RSS_HASH_KEY_3, 0x36621985);
+		tw32(MAC_RSS_HASH_KEY_4, 0xbf14c0e8);
+		tw32(MAC_RSS_HASH_KEY_5, 0x1bc27a1e);
+		tw32(MAC_RSS_HASH_KEY_6, 0x84f4b556);
+		tw32(MAC_RSS_HASH_KEY_7, 0x094ea6fe);
+		tw32(MAC_RSS_HASH_KEY_8, 0x7dda01e7);
+		tw32(MAC_RSS_HASH_KEY_9, 0xc04d7481);
+	}
+
 	tp->rx_mode = RX_MODE_ENABLE;
 	if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
 		tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
 
+	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+		tp->rx_mode |= RX_MODE_RSS_ENABLE |
+			       RX_MODE_RSS_ITBL_HASH_BITS_7 |
+			       RX_MODE_RSS_IPV6_HASH_EN |
+			       RX_MODE_RSS_TCP_IPV6_HASH_EN |
+			       RX_MODE_RSS_IPV4_HASH_EN |
+			       RX_MODE_RSS_TCP_IPV4_HASH_EN;
+
 	tw32_f(MAC_RX_MODE, tp->rx_mode);
 	udelay(10);
 
@@ -7302,7 +7779,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 			return err;
 
 		if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
-		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
+		    !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET)) {
 			u32 tmp;
 
 			/* Clear CRC stats. */
@@ -7449,12 +7926,12 @@ static void tg3_timer(unsigned long __opaque)
 		 * IRQ status the mailbox/status_block protocol the chip
 		 * uses with the cpu is race prone.
 		 */
-		if (tp->hw_status->status & SD_STATUS_UPDATED) {
+		if (tp->napi[0].hw_status->status & SD_STATUS_UPDATED) {
 			tw32(GRC_LOCAL_CTRL,
 			     tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
 		} else {
 			tw32(HOSTCC_MODE, tp->coalesce_mode |
-			     (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW));
+			     HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW);
 		}
 
 		if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
@@ -7555,13 +8032,22 @@ restart_timer:
 	add_timer(&tp->timer);
 }
 
-static int tg3_request_irq(struct tg3 *tp)
+static int tg3_request_irq(struct tg3 *tp, int irq_num)
 {
 	irq_handler_t fn;
 	unsigned long flags;
-	struct net_device *dev = tp->dev;
+	char *name;
+	struct tg3_napi *tnapi = &tp->napi[irq_num];
 
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+	if (tp->irq_cnt == 1)
+		name = tp->dev->name;
+	else {
+		name = &tnapi->irq_lbl[0];
+		snprintf(name, IFNAMSIZ, "%s-%d", tp->dev->name, irq_num);
+		name[IFNAMSIZ-1] = 0;
+	}
+
+	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
 		fn = tg3_msi;
 		if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
 			fn = tg3_msi_1shot;
@@ -7572,37 +8058,49 @@ static int tg3_request_irq(struct tg3 *tp)
 			fn = tg3_interrupt_tagged;
 		flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
 	}
-	return (request_irq(tp->pdev->irq, fn, flags, dev->name, dev));
+
+	return request_irq(tnapi->irq_vec, fn, flags, name, tnapi);
 }
 
 static int tg3_test_interrupt(struct tg3 *tp)
 {
+	struct tg3_napi *tnapi = &tp->napi[0];
 	struct net_device *dev = tp->dev;
 	int err, i, intr_ok = 0;
+	u32 val;
 
 	if (!netif_running(dev))
 		return -ENODEV;
 
 	tg3_disable_ints(tp);
 
-	free_irq(tp->pdev->irq, dev);
+	free_irq(tnapi->irq_vec, tnapi);
 
-	err = request_irq(tp->pdev->irq, tg3_test_isr,
-			  IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
+	/*
+	 * Turn off MSI one shot mode.  Otherwise this test has no
+	 * observable way to know whether the interrupt was delivered.
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+	    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+		val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
+		tw32(MSGINT_MODE, val);
+	}
+
+	err = request_irq(tnapi->irq_vec, tg3_test_isr,
+			  IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, tnapi);
 	if (err)
 		return err;
 
-	tp->hw_status->status &= ~SD_STATUS_UPDATED;
+	tnapi->hw_status->status &= ~SD_STATUS_UPDATED;
 	tg3_enable_ints(tp);
 
 	tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
-	       HOSTCC_MODE_NOW);
+	       tnapi->coal_now);
 
 	for (i = 0; i < 5; i++) {
 		u32 int_mbox, misc_host_ctrl;
 
-		int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 +
-					TG3_64BIT_REG_LOW);
+		int_mbox = tr32_mailbox(tnapi->int_mbox);
 		misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL);
 
 		if ((int_mbox != 0) ||
@@ -7616,15 +8114,22 @@ static int tg3_test_interrupt(struct tg3 *tp)
 
 	tg3_disable_ints(tp);
 
-	free_irq(tp->pdev->irq, dev);
+	free_irq(tnapi->irq_vec, tnapi);
 
-	err = tg3_request_irq(tp);
+	err = tg3_request_irq(tp, 0);
 
 	if (err)
 		return err;
 
-	if (intr_ok)
+	if (intr_ok) {
+		/* Reenable MSI one shot mode. */
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 &&
+		    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+			val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
+			tw32(MSGINT_MODE, val);
+		}
 		return 0;
+	}
 
 	return -EIO;
 }
@@ -7634,7 +8139,6 @@ static int tg3_test_interrupt(struct tg3 *tp)
  */
 static int tg3_test_msi(struct tg3 *tp)
 {
-	struct net_device *dev = tp->dev;
 	int err;
 	u16 pci_cmd;
 
@@ -7665,12 +8169,13 @@ static int tg3_test_msi(struct tg3 *tp)
 	       "the PCI maintainer and include system chipset information.\n",
 		       tp->dev->name);
 
-	free_irq(tp->pdev->irq, dev);
+	free_irq(tp->napi[0].irq_vec, &tp->napi[0]);
+
 	pci_disable_msi(tp->pdev);
 
 	tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
 
-	err = tg3_request_irq(tp);
+	err = tg3_request_irq(tp, 0);
 	if (err)
 		return err;
 
@@ -7685,7 +8190,7 @@ static int tg3_test_msi(struct tg3 *tp)
 	tg3_full_unlock(tp);
 
 	if (err)
-		free_irq(tp->pdev->irq, dev);
+		free_irq(tp->napi[0].irq_vec, &tp->napi[0]);
 
 	return err;
 }
@@ -7721,10 +8226,95 @@ static int tg3_request_firmware(struct tg3 *tp)
 	return 0;
 }
 
+static bool tg3_enable_msix(struct tg3 *tp)
+{
+	int i, rc, cpus = num_online_cpus();
+	struct msix_entry msix_ent[tp->irq_max];
+
+	if (cpus == 1)
+		/* Just fallback to the simpler MSI mode. */
+		return false;
+
+	/*
+	 * We want as many rx rings enabled as there are cpus.
+	 * The first MSIX vector only deals with link interrupts, etc,
+	 * so we add one to the number of vectors we are requesting.
+	 */
+	tp->irq_cnt = min_t(unsigned, cpus + 1, tp->irq_max);
+
+	for (i = 0; i < tp->irq_max; i++) {
+		msix_ent[i].entry  = i;
+		msix_ent[i].vector = 0;
+	}
+
+	rc = pci_enable_msix(tp->pdev, msix_ent, tp->irq_cnt);
+	if (rc != 0) {
+		if (rc < TG3_RSS_MIN_NUM_MSIX_VECS)
+			return false;
+		if (pci_enable_msix(tp->pdev, msix_ent, rc))
+			return false;
+		printk(KERN_NOTICE
+		       "%s: Requested %d MSI-X vectors, received %d\n",
+		       tp->dev->name, tp->irq_cnt, rc);
+		tp->irq_cnt = rc;
+	}
+
+	tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
+
+	for (i = 0; i < tp->irq_max; i++)
+		tp->napi[i].irq_vec = msix_ent[i].vector;
+
+	tp->dev->real_num_tx_queues = tp->irq_cnt - 1;
+
+	return true;
+}
+
+static void tg3_ints_init(struct tg3 *tp)
+{
+	if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI_OR_MSIX) &&
+	    !(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+		/* All MSI supporting chips should support tagged
+		 * status.  Assert that this is the case.
+		 */
+		printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
+		       "Not using MSI.\n", tp->dev->name);
+		goto defcfg;
+	}
+
+	if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) && tg3_enable_msix(tp))
+		tp->tg3_flags2 |= TG3_FLG2_USING_MSIX;
+	else if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) &&
+		 pci_enable_msi(tp->pdev) == 0)
+		tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
+
+	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
+		u32 msi_mode = tr32(MSGINT_MODE);
+		if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+			msi_mode |= MSGINT_MODE_MULTIVEC_EN;
+		tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
+	}
+defcfg:
+	if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+		tp->irq_cnt = 1;
+		tp->napi[0].irq_vec = tp->pdev->irq;
+		tp->dev->real_num_tx_queues = 1;
+	}
+}
+
+static void tg3_ints_fini(struct tg3 *tp)
+{
+	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+		pci_disable_msix(tp->pdev);
+	else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
+		pci_disable_msi(tp->pdev);
+	tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX;
+	tp->tg3_flags3 &= ~TG3_FLG3_ENABLE_RSS;
+}
+
 static int tg3_open(struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
-	int err;
+	int i, err;
 
 	if (tp->fw_needed) {
 		err = tg3_request_firmware(tp);
@@ -7755,40 +8345,33 @@ static int tg3_open(struct net_device *dev)
 
 	tg3_full_unlock(tp);
 
+	/*
+	 * Setup interrupts first so we know how
+	 * many NAPI resources to allocate
+	 */
+	tg3_ints_init(tp);
+
 	/* The placement of this call is tied
 	 * to the setup and use of Host TX descriptors.
 	 */
 	err = tg3_alloc_consistent(tp);
 	if (err)
-		return err;
-
-	if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) {
-		/* All MSI supporting chips should support tagged
-		 * status.  Assert that this is the case.
-		 */
-		if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
-			printk(KERN_WARNING PFX "%s: MSI without TAGGED? "
-			       "Not using MSI.\n", tp->dev->name);
-		} else if (pci_enable_msi(tp->pdev) == 0) {
-			u32 msi_mode;
+		goto err_out1;
 
-			msi_mode = tr32(MSGINT_MODE);
-			tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
-			tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
-		}
-	}
-	err = tg3_request_irq(tp);
+	tg3_napi_enable(tp);
 
-	if (err) {
-		if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
-			pci_disable_msi(tp->pdev);
-			tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+		err = tg3_request_irq(tp, i);
+		if (err) {
+			for (i--; i >= 0; i--)
+				free_irq(tnapi->irq_vec, tnapi);
+			break;
 		}
-		tg3_free_consistent(tp);
-		return err;
 	}
 
-	napi_enable(&tp->napi);
+	if (err)
+		goto err_out2;
 
 	tg3_full_lock(tp, 0);
 
@@ -7816,45 +8399,28 @@ static int tg3_open(struct net_device *dev)
 
 	tg3_full_unlock(tp);
 
-	if (err) {
-		napi_disable(&tp->napi);
-		free_irq(tp->pdev->irq, dev);
-		if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
-			pci_disable_msi(tp->pdev);
-			tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
-		}
-		tg3_free_consistent(tp);
-		return err;
-	}
+	if (err)
+		goto err_out3;
 
 	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
 		err = tg3_test_msi(tp);
 
 		if (err) {
 			tg3_full_lock(tp, 0);
-
-			if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
-				pci_disable_msi(tp->pdev);
-				tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
-			}
 			tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 			tg3_free_rings(tp);
-			tg3_free_consistent(tp);
-
 			tg3_full_unlock(tp);
 
-			napi_disable(&tp->napi);
-
-			return err;
+			goto err_out2;
 		}
 
-		if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
-			if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) {
-				u32 val = tr32(PCIE_TRANSACTION_CFG);
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+		    (tp->tg3_flags2 & TG3_FLG2_USING_MSI) &&
+		    (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)) {
+			u32 val = tr32(PCIE_TRANSACTION_CFG);
 
-				tw32(PCIE_TRANSACTION_CFG,
-				     val | PCIE_TRANS_CFG_1SHOT_MSI);
-			}
+			tw32(PCIE_TRANSACTION_CFG,
+			     val | PCIE_TRANS_CFG_1SHOT_MSI);
 		}
 	}
 
@@ -7868,9 +8434,23 @@ static int tg3_open(struct net_device *dev)
 
 	tg3_full_unlock(tp);
 
-	netif_start_queue(dev);
+	netif_tx_start_all_queues(dev);
 
 	return 0;
+
+err_out3:
+	for (i = tp->irq_cnt - 1; i >= 0; i--) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+		free_irq(tnapi->irq_vec, tnapi);
+	}
+
+err_out2:
+	tg3_napi_disable(tp);
+	tg3_free_consistent(tp);
+
+err_out1:
+	tg3_ints_fini(tp);
+	return err;
 }
 
 #if 0
@@ -7879,6 +8459,7 @@ static int tg3_open(struct net_device *dev)
 	u32 val32, val32_2, val32_3, val32_4, val32_5;
 	u16 val16;
 	int i;
+	struct tg3_hw_status *sblk = tp->napi[0]->hw_status;
 
 	pci_read_config_word(tp->pdev, PCI_STATUS, &val16);
 	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, &val32);
@@ -8031,14 +8612,15 @@ static int tg3_open(struct net_device *dev)
 	       val32, val32_2, val32_3, val32_4, val32_5);
 
 	/* SW status block */
-	printk("DEBUG: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
-	       tp->hw_status->status,
-	       tp->hw_status->status_tag,
-	       tp->hw_status->rx_jumbo_consumer,
-	       tp->hw_status->rx_consumer,
-	       tp->hw_status->rx_mini_consumer,
-	       tp->hw_status->idx[0].rx_producer,
-	       tp->hw_status->idx[0].tx_consumer);
+	printk(KERN_DEBUG
+	 "Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
+	       sblk->status,
+	       sblk->status_tag,
+	       sblk->rx_jumbo_consumer,
+	       sblk->rx_consumer,
+	       sblk->rx_mini_consumer,
+	       sblk->idx[0].rx_producer,
+	       sblk->idx[0].tx_consumer);
 
 	/* SW statistics block */
 	printk("DEBUG: Host statistics block [%08x:%08x:%08x:%08x]\n",
@@ -8106,12 +8688,13 @@ static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *);
 
 static int tg3_close(struct net_device *dev)
 {
+	int i;
 	struct tg3 *tp = netdev_priv(dev);
 
-	napi_disable(&tp->napi);
+	tg3_napi_disable(tp);
 	cancel_work_sync(&tp->reset_task);
 
-	netif_stop_queue(dev);
+	netif_tx_stop_all_queues(dev);
 
 	del_timer_sync(&tp->timer);
 
@@ -8128,12 +8711,13 @@ static int tg3_close(struct net_device *dev)
 
 	tg3_full_unlock(tp);
 
-	free_irq(tp->pdev->irq, dev);
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
-		pci_disable_msi(tp->pdev);
-		tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+	for (i = tp->irq_cnt - 1; i >= 0; i--) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+		free_irq(tnapi->irq_vec, tnapi);
 	}
 
+	tg3_ints_fini(tp);
+
 	memcpy(&tp->net_stats_prev, tg3_get_stats(tp->dev),
 	       sizeof(tp->net_stats_prev));
 	memcpy(&tp->estats_prev, tg3_get_estats(tp),
@@ -8697,7 +9281,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 		cmd->speed = tp->link_config.active_speed;
 		cmd->duplex = tp->link_config.active_duplex;
 	}
-	cmd->phy_address = PHY_ADDR;
+	cmd->phy_address = tp->phy_addr;
 	cmd->transceiver = XCVR_INTERNAL;
 	cmd->autoneg = tp->link_config.autoneg;
 	cmd->maxtxpkt = 0;
@@ -8872,7 +9456,8 @@ static int tg3_set_tso(struct net_device *dev, u32 value)
 			    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
 			     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
 			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
 				dev->features |= NETIF_F_TSO_ECN;
 		} else
 			dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
@@ -8934,13 +9519,13 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
 	else
 		ering->rx_jumbo_pending = 0;
 
-	ering->tx_pending = tp->tx_pending;
+	ering->tx_pending = tp->napi[0].tx_pending;
 }
 
 static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
 	struct tg3 *tp = netdev_priv(dev);
-	int irq_sync = 0, err = 0;
+	int i, irq_sync = 0, err = 0;
 
 	if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
 	    (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
@@ -8964,7 +9549,9 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
 	    tp->rx_pending > 63)
 		tp->rx_pending = 63;
 	tp->rx_jumbo_pending = ering->rx_jumbo_pending;
-	tp->tx_pending = ering->tx_pending;
+
+	for (i = 0; i < TG3_IRQ_MAX_VECS; i++)
+		tp->napi[i].tx_pending = ering->tx_pending;
 
 	if (netif_running(dev)) {
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -9672,12 +10259,23 @@ static int tg3_test_memory(struct tg3 *tp)
 static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 {
 	u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key;
-	u32 desc_idx;
+	u32 desc_idx, coal_now;
 	struct sk_buff *skb, *rx_skb;
 	u8 *tx_data;
 	dma_addr_t map;
 	int num_pkts, tx_len, rx_len, i, err;
 	struct tg3_rx_buffer_desc *desc;
+	struct tg3_napi *tnapi, *rnapi;
+	struct tg3_rx_prodring_set *tpr = &tp->prodring[0];
+
+	if (tp->irq_cnt > 1) {
+		tnapi = &tp->napi[1];
+		rnapi = &tp->napi[1];
+	} else {
+		tnapi = &tp->napi[0];
+		rnapi = &tp->napi[0];
+	}
+	coal_now = tnapi->coal_now | rnapi->coal_now;
 
 	if (loopback_mode == TG3_MAC_LOOPBACK) {
 		/* HW errata - mac loopback fails in some cases on 5780.
@@ -9699,18 +10297,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 	} else if (loopback_mode == TG3_PHY_LOOPBACK) {
 		u32 val;
 
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-			u32 phytest;
-
-			if (!tg3_readphy(tp, MII_TG3_EPHY_TEST, &phytest)) {
-				u32 phy;
-
-				tg3_writephy(tp, MII_TG3_EPHY_TEST,
-					     phytest | MII_TG3_EPHY_SHADOW_EN);
-				if (!tg3_readphy(tp, 0x1b, &phy))
-					tg3_writephy(tp, 0x1b, phy & ~0x20);
-				tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest);
-			}
+		if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+			tg3_phy_fet_toggle_apd(tp, false);
 			val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
 		} else
 			val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000;
@@ -9721,8 +10309,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 		udelay(40);
 
 		mac_mode = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-			tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800);
+		if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+				tg3_writephy(tp, MII_TG3_FET_PTEST, 0x1800);
 			mac_mode |= MAC_MODE_PORT_MODE_MII;
 		} else
 			mac_mode |= MAC_MODE_PORT_MODE_GMII;
@@ -9765,35 +10354,34 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 	map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
 
 	tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
-	     HOSTCC_MODE_NOW);
+	       rnapi->coal_now);
 
 	udelay(10);
 
-	rx_start_idx = tp->hw_status->idx[0].rx_producer;
+	rx_start_idx = rnapi->hw_status->idx[0].rx_producer;
 
 	num_pkts = 0;
 
-	tg3_set_txd(tp, tp->tx_prod, map, tx_len, 0, 1);
+	tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, 0, 1);
 
-	tp->tx_prod++;
+	tnapi->tx_prod++;
 	num_pkts++;
 
-	tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW,
-		     tp->tx_prod);
-	tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
+	tw32_tx_mbox(tnapi->prodmbox, tnapi->tx_prod);
+	tr32_mailbox(tnapi->prodmbox);
 
 	udelay(10);
 
 	/* 250 usec to allow enough time on some 10/100 Mbps devices.  */
 	for (i = 0; i < 25; i++) {
 		tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
-		       HOSTCC_MODE_NOW);
+		       coal_now);
 
 		udelay(10);
 
-		tx_idx = tp->hw_status->idx[0].tx_consumer;
-		rx_idx = tp->hw_status->idx[0].rx_producer;
-		if ((tx_idx == tp->tx_prod) &&
+		tx_idx = tnapi->hw_status->idx[0].tx_consumer;
+		rx_idx = rnapi->hw_status->idx[0].rx_producer;
+		if ((tx_idx == tnapi->tx_prod) &&
 		    (rx_idx == (rx_start_idx + num_pkts)))
 			break;
 	}
@@ -9801,13 +10389,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 	pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE);
 	dev_kfree_skb(skb);
 
-	if (tx_idx != tp->tx_prod)
+	if (tx_idx != tnapi->tx_prod)
 		goto out;
 
 	if (rx_idx != rx_start_idx + num_pkts)
 		goto out;
 
-	desc = &tp->rx_rcb[rx_start_idx];
+	desc = &rnapi->rx_rcb[rx_start_idx];
 	desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
 	opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
 	if (opaque_key != RXD_OPAQUE_RING_STD)
@@ -9821,9 +10409,9 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 	if (rx_len != tx_len)
 		goto out;
 
-	rx_skb = tp->rx_std_buffers[desc_idx].skb;
+	rx_skb = tpr->rx_std_buffers[desc_idx].skb;
 
-	map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping);
+	map = pci_unmap_addr(&tpr->rx_std_buffers[desc_idx], mapping);
 	pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE);
 
 	for (i = 14; i < tx_len; i++) {
@@ -9997,7 +10585,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 	switch(cmd) {
 	case SIOCGMIIPHY:
-		data->phy_id = PHY_ADDR;
+		data->phy_id = tp->phy_addr;
 
 		/* fallthru */
 	case SIOCGMIIREG: {
@@ -10022,9 +10610,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
 			break;			/* We have no PHY */
 
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
 		if (tp->link_config.phy_is_low_power)
 			return -EAGAIN;
 
@@ -10236,8 +10821,7 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
 	nvcfg1 = tr32(NVRAM_CFG1);
 	if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
 		tp->tg3_flags2 |= TG3_FLG2_FLASH;
-	}
-	else {
+	} else {
 		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
 		tw32(NVRAM_CFG1, nvcfg1);
 	}
@@ -10245,43 +10829,69 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp)
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
 	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
 		switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
-			case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
-				tp->nvram_jedecnum = JEDEC_ATMEL;
-				tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
-				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-				break;
-			case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
-				tp->nvram_jedecnum = JEDEC_ATMEL;
-                         	tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
-				break;
-			case FLASH_VENDOR_ATMEL_EEPROM:
-				tp->nvram_jedecnum = JEDEC_ATMEL;
-                         	tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
-				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-				break;
-			case FLASH_VENDOR_ST:
-				tp->nvram_jedecnum = JEDEC_ST;
-				tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
-				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-				break;
-			case FLASH_VENDOR_SAIFUN:
-				tp->nvram_jedecnum = JEDEC_SAIFUN;
-				tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
-				break;
-			case FLASH_VENDOR_SST_SMALL:
-			case FLASH_VENDOR_SST_LARGE:
-				tp->nvram_jedecnum = JEDEC_SST;
-				tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
-				break;
+		case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
+			tp->nvram_jedecnum = JEDEC_ATMEL;
+			tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
+			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+			break;
+		case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
+			tp->nvram_jedecnum = JEDEC_ATMEL;
+			tp->nvram_pagesize = ATMEL_AT25F512_PAGE_SIZE;
+			break;
+		case FLASH_VENDOR_ATMEL_EEPROM:
+			tp->nvram_jedecnum = JEDEC_ATMEL;
+			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+			break;
+		case FLASH_VENDOR_ST:
+			tp->nvram_jedecnum = JEDEC_ST;
+			tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
+			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+			break;
+		case FLASH_VENDOR_SAIFUN:
+			tp->nvram_jedecnum = JEDEC_SAIFUN;
+			tp->nvram_pagesize = SAIFUN_SA25F0XX_PAGE_SIZE;
+			break;
+		case FLASH_VENDOR_SST_SMALL:
+		case FLASH_VENDOR_SST_LARGE:
+			tp->nvram_jedecnum = JEDEC_SST;
+			tp->nvram_pagesize = SST_25VF0X0_PAGE_SIZE;
+			break;
 		}
-	}
-	else {
+	} else {
 		tp->nvram_jedecnum = JEDEC_ATMEL;
 		tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
 		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
 	}
 }
 
+static void __devinit tg3_nvram_get_pagesize(struct tg3 *tp, u32 nvmcfg1)
+{
+	switch (nvmcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
+	case FLASH_5752PAGE_SIZE_256:
+		tp->nvram_pagesize = 256;
+		break;
+	case FLASH_5752PAGE_SIZE_512:
+		tp->nvram_pagesize = 512;
+		break;
+	case FLASH_5752PAGE_SIZE_1K:
+		tp->nvram_pagesize = 1024;
+		break;
+	case FLASH_5752PAGE_SIZE_2K:
+		tp->nvram_pagesize = 2048;
+		break;
+	case FLASH_5752PAGE_SIZE_4K:
+		tp->nvram_pagesize = 4096;
+		break;
+	case FLASH_5752PAGE_SIZE_264:
+		tp->nvram_pagesize = 264;
+		break;
+	case FLASH_5752PAGE_SIZE_528:
+		tp->nvram_pagesize = 528;
+		break;
+	}
+}
+
 static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
 {
 	u32 nvcfg1;
@@ -10293,48 +10903,28 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp)
 		tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM;
 
 	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-		case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
-		case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			break;
-		case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			break;
-		case FLASH_5752VENDOR_ST_M45PE10:
-		case FLASH_5752VENDOR_ST_M45PE20:
-		case FLASH_5752VENDOR_ST_M45PE40:
-			tp->nvram_jedecnum = JEDEC_ST;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			break;
+	case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
+	case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		break;
+	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		break;
+	case FLASH_5752VENDOR_ST_M45PE10:
+	case FLASH_5752VENDOR_ST_M45PE20:
+	case FLASH_5752VENDOR_ST_M45PE40:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		break;
 	}
 
 	if (tp->tg3_flags2 & TG3_FLG2_FLASH) {
-		switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
-			case FLASH_5752PAGE_SIZE_256:
-				tp->nvram_pagesize = 256;
-				break;
-			case FLASH_5752PAGE_SIZE_512:
-				tp->nvram_pagesize = 512;
-				break;
-			case FLASH_5752PAGE_SIZE_1K:
-				tp->nvram_pagesize = 1024;
-				break;
-			case FLASH_5752PAGE_SIZE_2K:
-				tp->nvram_pagesize = 2048;
-				break;
-			case FLASH_5752PAGE_SIZE_4K:
-				tp->nvram_pagesize = 4096;
-				break;
-			case FLASH_5752PAGE_SIZE_264:
-				tp->nvram_pagesize = 264;
-				break;
-		}
-	}
-	else {
+		tg3_nvram_get_pagesize(tp, nvcfg1);
+	} else {
 		/* For eeprom, set pagesize to maximum eeprom size */
 		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
@@ -10357,45 +10947,45 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp)
 
 	nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
 	switch (nvcfg1) {
-		case FLASH_5755VENDOR_ATMEL_FLASH_1:
-		case FLASH_5755VENDOR_ATMEL_FLASH_2:
-		case FLASH_5755VENDOR_ATMEL_FLASH_3:
-		case FLASH_5755VENDOR_ATMEL_FLASH_5:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			tp->nvram_pagesize = 264;
-			if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
-			    nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
-				tp->nvram_size = (protect ? 0x3e200 :
-						  TG3_NVRAM_SIZE_512KB);
-			else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
-				tp->nvram_size = (protect ? 0x1f200 :
-						  TG3_NVRAM_SIZE_256KB);
-			else
-				tp->nvram_size = (protect ? 0x1f200 :
-						  TG3_NVRAM_SIZE_128KB);
-			break;
-		case FLASH_5752VENDOR_ST_M45PE10:
-		case FLASH_5752VENDOR_ST_M45PE20:
-		case FLASH_5752VENDOR_ST_M45PE40:
-			tp->nvram_jedecnum = JEDEC_ST;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			tp->nvram_pagesize = 256;
-			if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
-				tp->nvram_size = (protect ?
-						  TG3_NVRAM_SIZE_64KB :
-						  TG3_NVRAM_SIZE_128KB);
-			else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
-				tp->nvram_size = (protect ?
-						  TG3_NVRAM_SIZE_64KB :
-						  TG3_NVRAM_SIZE_256KB);
-			else
-				tp->nvram_size = (protect ?
-						  TG3_NVRAM_SIZE_128KB :
-						  TG3_NVRAM_SIZE_512KB);
-			break;
+	case FLASH_5755VENDOR_ATMEL_FLASH_1:
+	case FLASH_5755VENDOR_ATMEL_FLASH_2:
+	case FLASH_5755VENDOR_ATMEL_FLASH_3:
+	case FLASH_5755VENDOR_ATMEL_FLASH_5:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tp->nvram_pagesize = 264;
+		if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
+		    nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
+			tp->nvram_size = (protect ? 0x3e200 :
+					  TG3_NVRAM_SIZE_512KB);
+		else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2)
+			tp->nvram_size = (protect ? 0x1f200 :
+					  TG3_NVRAM_SIZE_256KB);
+		else
+			tp->nvram_size = (protect ? 0x1f200 :
+					  TG3_NVRAM_SIZE_128KB);
+		break;
+	case FLASH_5752VENDOR_ST_M45PE10:
+	case FLASH_5752VENDOR_ST_M45PE20:
+	case FLASH_5752VENDOR_ST_M45PE40:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tp->nvram_pagesize = 256;
+		if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
+			tp->nvram_size = (protect ?
+					  TG3_NVRAM_SIZE_64KB :
+					  TG3_NVRAM_SIZE_128KB);
+		else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20)
+			tp->nvram_size = (protect ?
+					  TG3_NVRAM_SIZE_64KB :
+					  TG3_NVRAM_SIZE_256KB);
+		else
+			tp->nvram_size = (protect ?
+					  TG3_NVRAM_SIZE_128KB :
+					  TG3_NVRAM_SIZE_512KB);
+		break;
 	}
 }
 
@@ -10406,34 +10996,34 @@ static void __devinit tg3_get_5787_nvram_info(struct tg3 *tp)
 	nvcfg1 = tr32(NVRAM_CFG1);
 
 	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
-		case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
-		case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
-		case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
-		case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+	case FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ:
+	case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
+	case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
+	case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
-			nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
-			tw32(NVRAM_CFG1, nvcfg1);
-			break;
-		case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
-		case FLASH_5755VENDOR_ATMEL_FLASH_1:
-		case FLASH_5755VENDOR_ATMEL_FLASH_2:
-		case FLASH_5755VENDOR_ATMEL_FLASH_3:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			tp->nvram_pagesize = 264;
-			break;
-		case FLASH_5752VENDOR_ST_M45PE10:
-		case FLASH_5752VENDOR_ST_M45PE20:
-		case FLASH_5752VENDOR_ST_M45PE40:
-			tp->nvram_jedecnum = JEDEC_ST;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			tp->nvram_pagesize = 256;
-			break;
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+		break;
+	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
+	case FLASH_5755VENDOR_ATMEL_FLASH_1:
+	case FLASH_5755VENDOR_ATMEL_FLASH_2:
+	case FLASH_5755VENDOR_ATMEL_FLASH_3:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tp->nvram_pagesize = 264;
+		break;
+	case FLASH_5752VENDOR_ST_M45PE10:
+	case FLASH_5752VENDOR_ST_M45PE20:
+	case FLASH_5752VENDOR_ST_M45PE40:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tp->nvram_pagesize = 256;
+		break;
 	}
 }
 
@@ -10451,63 +11041,63 @@ static void __devinit tg3_get_5761_nvram_info(struct tg3 *tp)
 
 	nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK;
 	switch (nvcfg1) {
-		case FLASH_5761VENDOR_ATMEL_ADB021D:
-		case FLASH_5761VENDOR_ATMEL_ADB041D:
-		case FLASH_5761VENDOR_ATMEL_ADB081D:
-		case FLASH_5761VENDOR_ATMEL_ADB161D:
-		case FLASH_5761VENDOR_ATMEL_MDB021D:
-		case FLASH_5761VENDOR_ATMEL_MDB041D:
-		case FLASH_5761VENDOR_ATMEL_MDB081D:
-		case FLASH_5761VENDOR_ATMEL_MDB161D:
-			tp->nvram_jedecnum = JEDEC_ATMEL;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-			tp->nvram_pagesize = 256;
-			break;
-		case FLASH_5761VENDOR_ST_A_M45PE20:
-		case FLASH_5761VENDOR_ST_A_M45PE40:
-		case FLASH_5761VENDOR_ST_A_M45PE80:
-		case FLASH_5761VENDOR_ST_A_M45PE16:
-		case FLASH_5761VENDOR_ST_M_M45PE20:
-		case FLASH_5761VENDOR_ST_M_M45PE40:
-		case FLASH_5761VENDOR_ST_M_M45PE80:
-		case FLASH_5761VENDOR_ST_M_M45PE16:
-			tp->nvram_jedecnum = JEDEC_ST;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-			tp->tg3_flags2 |= TG3_FLG2_FLASH;
-			tp->nvram_pagesize = 256;
-			break;
+	case FLASH_5761VENDOR_ATMEL_ADB021D:
+	case FLASH_5761VENDOR_ATMEL_ADB041D:
+	case FLASH_5761VENDOR_ATMEL_ADB081D:
+	case FLASH_5761VENDOR_ATMEL_ADB161D:
+	case FLASH_5761VENDOR_ATMEL_MDB021D:
+	case FLASH_5761VENDOR_ATMEL_MDB041D:
+	case FLASH_5761VENDOR_ATMEL_MDB081D:
+	case FLASH_5761VENDOR_ATMEL_MDB161D:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+		tp->nvram_pagesize = 256;
+		break;
+	case FLASH_5761VENDOR_ST_A_M45PE20:
+	case FLASH_5761VENDOR_ST_A_M45PE40:
+	case FLASH_5761VENDOR_ST_A_M45PE80:
+	case FLASH_5761VENDOR_ST_A_M45PE16:
+	case FLASH_5761VENDOR_ST_M_M45PE20:
+	case FLASH_5761VENDOR_ST_M_M45PE40:
+	case FLASH_5761VENDOR_ST_M_M45PE80:
+	case FLASH_5761VENDOR_ST_M_M45PE16:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tp->nvram_pagesize = 256;
+		break;
 	}
 
 	if (protect) {
 		tp->nvram_size = tr32(NVRAM_ADDR_LOCKOUT);
 	} else {
 		switch (nvcfg1) {
-			case FLASH_5761VENDOR_ATMEL_ADB161D:
-			case FLASH_5761VENDOR_ATMEL_MDB161D:
-			case FLASH_5761VENDOR_ST_A_M45PE16:
-			case FLASH_5761VENDOR_ST_M_M45PE16:
-				tp->nvram_size = TG3_NVRAM_SIZE_2MB;
-				break;
-			case FLASH_5761VENDOR_ATMEL_ADB081D:
-			case FLASH_5761VENDOR_ATMEL_MDB081D:
-			case FLASH_5761VENDOR_ST_A_M45PE80:
-			case FLASH_5761VENDOR_ST_M_M45PE80:
-				tp->nvram_size = TG3_NVRAM_SIZE_1MB;
-				break;
-			case FLASH_5761VENDOR_ATMEL_ADB041D:
-			case FLASH_5761VENDOR_ATMEL_MDB041D:
-			case FLASH_5761VENDOR_ST_A_M45PE40:
-			case FLASH_5761VENDOR_ST_M_M45PE40:
-				tp->nvram_size = TG3_NVRAM_SIZE_512KB;
-				break;
-			case FLASH_5761VENDOR_ATMEL_ADB021D:
-			case FLASH_5761VENDOR_ATMEL_MDB021D:
-			case FLASH_5761VENDOR_ST_A_M45PE20:
-			case FLASH_5761VENDOR_ST_M_M45PE20:
-				tp->nvram_size = TG3_NVRAM_SIZE_256KB;
-				break;
+		case FLASH_5761VENDOR_ATMEL_ADB161D:
+		case FLASH_5761VENDOR_ATMEL_MDB161D:
+		case FLASH_5761VENDOR_ST_A_M45PE16:
+		case FLASH_5761VENDOR_ST_M_M45PE16:
+			tp->nvram_size = TG3_NVRAM_SIZE_2MB;
+			break;
+		case FLASH_5761VENDOR_ATMEL_ADB081D:
+		case FLASH_5761VENDOR_ATMEL_MDB081D:
+		case FLASH_5761VENDOR_ST_A_M45PE80:
+		case FLASH_5761VENDOR_ST_M_M45PE80:
+			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+			break;
+		case FLASH_5761VENDOR_ATMEL_ADB041D:
+		case FLASH_5761VENDOR_ATMEL_MDB041D:
+		case FLASH_5761VENDOR_ST_A_M45PE40:
+		case FLASH_5761VENDOR_ST_M_M45PE40:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+			break;
+		case FLASH_5761VENDOR_ATMEL_ADB021D:
+		case FLASH_5761VENDOR_ATMEL_MDB021D:
+		case FLASH_5761VENDOR_ST_A_M45PE20:
+		case FLASH_5761VENDOR_ST_M_M45PE20:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
 		}
 	}
 }
@@ -10586,34 +11176,84 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
 		return;
 	}
 
-	switch (nvcfg1 & NVRAM_CFG1_5752PAGE_SIZE_MASK) {
-	case FLASH_5752PAGE_SIZE_256:
+	tg3_nvram_get_pagesize(tp, nvcfg1);
+	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
 		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-		tp->nvram_pagesize = 256;
-		break;
-	case FLASH_5752PAGE_SIZE_512:
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-		tp->nvram_pagesize = 512;
-		break;
-	case FLASH_5752PAGE_SIZE_1K:
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-		tp->nvram_pagesize = 1024;
-		break;
-	case FLASH_5752PAGE_SIZE_2K:
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-		tp->nvram_pagesize = 2048;
-		break;
-	case FLASH_5752PAGE_SIZE_4K:
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
-		tp->nvram_pagesize = 4096;
-		break;
-	case FLASH_5752PAGE_SIZE_264:
-		tp->nvram_pagesize = 264;
+}
+
+
+static void __devinit tg3_get_5717_nvram_info(struct tg3 *tp)
+{
+	u32 nvcfg1;
+
+	nvcfg1 = tr32(NVRAM_CFG1);
+
+	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+	case FLASH_5717VENDOR_ATMEL_EEPROM:
+	case FLASH_5717VENDOR_MICRO_EEPROM:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+		return;
+	case FLASH_5717VENDOR_ATMEL_MDB011D:
+	case FLASH_5717VENDOR_ATMEL_ADB011B:
+	case FLASH_5717VENDOR_ATMEL_ADB011D:
+	case FLASH_5717VENDOR_ATMEL_MDB021D:
+	case FLASH_5717VENDOR_ATMEL_ADB021B:
+	case FLASH_5717VENDOR_ATMEL_ADB021D:
+	case FLASH_5717VENDOR_ATMEL_45USPT:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+		case FLASH_5717VENDOR_ATMEL_MDB021D:
+		case FLASH_5717VENDOR_ATMEL_ADB021B:
+		case FLASH_5717VENDOR_ATMEL_ADB021D:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
+		}
 		break;
-	case FLASH_5752PAGE_SIZE_528:
-		tp->nvram_pagesize = 528;
+	case FLASH_5717VENDOR_ST_M_M25PE10:
+	case FLASH_5717VENDOR_ST_A_M25PE10:
+	case FLASH_5717VENDOR_ST_M_M45PE10:
+	case FLASH_5717VENDOR_ST_A_M45PE10:
+	case FLASH_5717VENDOR_ST_M_M25PE20:
+	case FLASH_5717VENDOR_ST_A_M25PE20:
+	case FLASH_5717VENDOR_ST_M_M45PE20:
+	case FLASH_5717VENDOR_ST_A_M45PE20:
+	case FLASH_5717VENDOR_ST_25USPT:
+	case FLASH_5717VENDOR_ST_45USPT:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+
+		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
+		case FLASH_5717VENDOR_ST_M_M25PE20:
+		case FLASH_5717VENDOR_ST_A_M25PE20:
+		case FLASH_5717VENDOR_ST_M_M45PE20:
+		case FLASH_5717VENDOR_ST_A_M45PE20:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
+		}
 		break;
+	default:
+		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
+		return;
 	}
+
+	tg3_nvram_get_pagesize(tp, nvcfg1);
+	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
+		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
 }
 
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -10658,6 +11298,8 @@ static void __devinit tg3_nvram_init(struct tg3 *tp)
 			tg3_get_5906_nvram_info(tp);
 		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 			tg3_get_57780_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+			tg3_get_5717_nvram_info(tp);
 		else
 			tg3_get_nvram_info(tp);
 
@@ -11485,6 +12127,9 @@ out_not_found:
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
 		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
 		strcpy(tp->board_part_number, "BCM57790");
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+		 tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788)
+		strcpy(tp->board_part_number, "BCM57788");
 	else
 		strcpy(tp->board_part_number, "none");
 }
@@ -11768,8 +12413,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_USE_PROD_ID_REG) {
 		u32 prod_id_asic_rev;
 
-		pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
-				      &prod_id_asic_rev);
+		if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717C ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717S ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718C ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718S)
+			pci_read_config_dword(tp->pdev,
+					      TG3PCI_GEN2_PRODID_ASICREV,
+					      &prod_id_asic_rev);
+		else
+			pci_read_config_dword(tp->pdev, TG3PCI_PRODID_ASICREV,
+					      &prod_id_asic_rev);
+
 		tp->pci_chip_rev_id = prod_id_asic_rev;
 	}
 
@@ -11907,8 +12561,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
 			       tp->misc_host_ctrl);
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714))
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
 		tp->pdev_peer = tg3_find_peer(tp);
 
 	/* Intentionally exclude ASIC_REV_5906 */
@@ -11917,7 +12572,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
 		tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
@@ -11965,9 +12621,19 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 		}
 	}
 
+	tp->irq_max = 1;
+
+#ifdef TG3_NAPI
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+		tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
+		tp->irq_max = TG3_IRQ_MAX_VECS;
+	}
+#endif
+
 	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-	     (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
-		tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
+	     (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+		tp->tg3_flags |= TG3_FLAG_JUMBO_CAPABLE;
 
 	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
 			      &pci_state_reg);
@@ -12100,7 +12766,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 		tp->write32 = tg3_write_flush_reg32;
 	}
 
-
 	if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) ||
 	    (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) {
 		tp->write32_tx_mbox = tg3_write32_tx_mbox;
@@ -12159,7 +12824,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
 		tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
 
 	/* Set up tp->grc_local_ctrl before calling tg3_set_power_state().
@@ -12216,12 +12882,15 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 		tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB;
 	}
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+		tp->tg3_flags3 |= TG3_FLG3_PHY_IS_FET;
+
 	/* A few boards don't want Ethernet@WireSpeed phy feature */
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
 	    ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
 	     (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
 	     (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) ||
+	    (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) ||
 	    (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
 		tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
 
@@ -12232,9 +12901,10 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 		tp->tg3_flags2 |= TG3_FLG2_PHY_5704_A0_BUG;
 
 	if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
+	    !(tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780) {
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -12269,6 +12939,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 		tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
 
+	if ((tp->pci_chip_rev_id == CHIPREV_ID_57780_A1 &&
+	     tr32(RCVLPC_STATS_ENABLE) & RCVLPC_STATSENAB_ASF_FIX) ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_57780_A0)
+		tp->tg3_flags3 |= TG3_FLG3_TOGGLE_10_100_L1PLLPD;
+
 	err = tg3_mdio_init(tp);
 	if (err)
 		return err;
@@ -12352,7 +13027,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 	      tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F ||
 	      tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) ||
 	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+	    (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET))
 		tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
 
 	err = tg3_phy_probe(tp);
@@ -12471,8 +13146,10 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
 			tw32_f(NVRAM_CMD, NVRAM_CMD_RESET);
 		else
 			tg3_nvram_unlock(tp);
-	}
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+		if (tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC)
+			mac_offset = 0xcc;
+	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
 		mac_offset = 0x10;
 
 	/* First try to get it from MAC address mailbox. */
@@ -12953,7 +13630,8 @@ static void __devinit tg3_init_link_config(struct tg3 *tp)
 
 static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
 {
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717) {
 		tp->bufmgr_config.mbuf_read_dma_low_water =
 			DEFAULT_MB_RDMA_LOW_WATER_5705;
 		tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -13158,7 +13836,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 	static int tg3_version_printed = 0;
 	struct net_device *dev;
 	struct tg3 *tp;
-	int err, pm_cap;
+	int i, err, pm_cap;
+	u32 sndmbx, rcvmbx, intmbx;
 	char str[40];
 	u64 dma_mask, persist_dma_mask;
 
@@ -13190,7 +13869,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 		goto err_out_free_res;
 	}
 
-	dev = alloc_etherdev(sizeof(*tp));
+	dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS);
 	if (!dev) {
 		printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
 		err = -ENOMEM;
@@ -13252,9 +13931,52 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
 	tp->rx_pending = TG3_DEF_RX_RING_PENDING;
 	tp->rx_jumbo_pending = TG3_DEF_RX_JUMBO_RING_PENDING;
-	tp->tx_pending = TG3_DEF_TX_RING_PENDING;
 
-	netif_napi_add(dev, &tp->napi, tg3_poll, 64);
+	intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
+	rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
+	sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
+	for (i = 0; i < TG3_IRQ_MAX_VECS; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+
+		tnapi->tp = tp;
+		tnapi->tx_pending = TG3_DEF_TX_RING_PENDING;
+
+		tnapi->int_mbox = intmbx;
+		if (i < 4)
+			intmbx += 0x8;
+		else
+			intmbx += 0x4;
+
+		tnapi->consmbox = rcvmbx;
+		tnapi->prodmbox = sndmbx;
+
+		if (i)
+			tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
+		else
+			tnapi->coal_now = HOSTCC_MODE_NOW;
+
+		if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
+			break;
+
+		/*
+		 * If we support MSIX, we'll be using RSS.  If we're using
+		 * RSS, the first vector only handles link interrupts and the
+		 * remaining vectors handle rx and tx interrupts.  Reuse the
+		 * mailbox values for the next iteration.  The values we setup
+		 * above are still useful for the single vectored mode.
+		 */
+		if (!i)
+			continue;
+
+		rcvmbx += 0x8;
+
+		if (sndmbx & 0x4)
+			sndmbx -= 0x4;
+		else
+			sndmbx += 0xc;
+	}
+
+	netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
 	dev->ethtool_ops = &tg3_ethtool_ops;
 	dev->watchdog_timeo = TG3_TX_TIMEOUT;
 	dev->irq = pdev->irq;
@@ -13348,7 +14070,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 		    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
 		     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
 			GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
 			dev->features |= NETIF_F_TSO_ECN;
 	}
 
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index b3347c4..82b45d8 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -43,7 +43,13 @@
 #define  TG3PCI_DEVICE_TIGON3_57780	 0x1692
 #define  TG3PCI_DEVICE_TIGON3_57760	 0x1690
 #define  TG3PCI_DEVICE_TIGON3_57790	 0x1694
-#define  TG3PCI_DEVICE_TIGON3_57720	 0x168c
+#define  TG3PCI_DEVICE_TIGON3_57788	 0x1691
+#define  TG3PCI_DEVICE_TIGON3_5785_G	 0x1699 /* GPHY */
+#define  TG3PCI_DEVICE_TIGON3_5785_F	 0x16a0 /* 10/100 only */
+#define  TG3PCI_DEVICE_TIGON3_5717C	 0x1655
+#define  TG3PCI_DEVICE_TIGON3_5717S	 0x1656
+#define  TG3PCI_DEVICE_TIGON3_5718C	 0x1665
+#define  TG3PCI_DEVICE_TIGON3_5718S	 0x1666
 /* 0x04 --> 0x64 unused */
 #define TG3PCI_MSI_DATA			0x00000064
 /* 0x66 --> 0x68 unused */
@@ -115,6 +121,7 @@
 #define   ASIC_REV_5761			 0x5761
 #define   ASIC_REV_5785			 0x5785
 #define   ASIC_REV_57780		 0x57780
+#define   ASIC_REV_5717			 0x5717
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -201,22 +208,24 @@
 #define TG3PCI_MEM_WIN_BASE_ADDR	0x0000007c
 #define TG3PCI_REG_DATA			0x00000080
 #define TG3PCI_MEM_WIN_DATA		0x00000084
-#define TG3PCI_MODE_CTRL		0x00000088
-#define TG3PCI_MISC_CFG			0x0000008c
 #define TG3PCI_MISC_LOCAL_CTRL		0x00000090
 /* 0x94 --> 0x98 unused */
 #define TG3PCI_STD_RING_PROD_IDX	0x00000098 /* 64-bit */
 #define TG3PCI_RCV_RET_RING_CON_IDX	0x000000a0 /* 64-bit */
-#define TG3PCI_SND_PROD_IDX		0x000000a8 /* 64-bit */
-/* 0xb0 --> 0xb8 unused */
+/* 0xa0 --> 0xb8 unused */
 #define TG3PCI_DUAL_MAC_CTRL		0x000000b8
 #define  DUAL_MAC_CTRL_CH_MASK		 0x00000003
 #define  DUAL_MAC_CTRL_ID		 0x00000004
 #define TG3PCI_PRODID_ASICREV		0x000000bc
 #define  PROD_ID_ASIC_REV_MASK		 0x0fffffff
-/* 0xc0 --> 0x100 unused */
+/* 0xc0 --> 0xf4 unused */
 
-/* 0x100 --> 0x200 unused */
+#define TG3PCI_GEN2_PRODID_ASICREV	0x000000f4
+/* 0xf8 --> 0x200 unused */
+
+#define TG3_CORR_ERR_STAT		0x00000110
+#define  TG3_CORR_ERR_STAT_CLEAR	0xffffffff
+/* 0x114 --> 0x200 unused */
 
 /* Mailbox registers */
 #define MAILBOX_INTERRUPT_0		0x00000200 /* 64-bit */
@@ -442,6 +451,12 @@
 #define  RX_MODE_PROMISC		 0x00000100
 #define  RX_MODE_NO_CRC_CHECK		 0x00000200
 #define  RX_MODE_KEEP_VLAN_TAG		 0x00000400
+#define  RX_MODE_RSS_IPV4_HASH_EN	 0x00010000
+#define  RX_MODE_RSS_TCP_IPV4_HASH_EN	 0x00020000
+#define  RX_MODE_RSS_IPV6_HASH_EN	 0x00040000
+#define  RX_MODE_RSS_TCP_IPV6_HASH_EN	 0x00080000
+#define  RX_MODE_RSS_ITBL_HASH_BITS_7	 0x00700000
+#define  RX_MODE_RSS_ENABLE		 0x00800000
 #define  RX_MODE_IPV6_CSUM_ENABLE	 0x01000000
 #define MAC_RX_STATUS			0x0000046c
 #define  RX_STATUS_REMOTE_TX_XOFFED	 0x00000001
@@ -522,6 +537,10 @@
 /* 0x598 --> 0x5a0 unused */
 #define MAC_PHYCFG1			0x000005a0
 #define  MAC_PHYCFG1_RGMII_INT		 0x00000001
+#define  MAC_PHYCFG1_RXCLK_TO_MASK	 0x00001ff0
+#define  MAC_PHYCFG1_RXCLK_TIMEOUT	 0x00001000
+#define  MAC_PHYCFG1_TXCLK_TO_MASK	 0x01ff0000
+#define  MAC_PHYCFG1_TXCLK_TIMEOUT	 0x01000000
 #define  MAC_PHYCFG1_RGMII_EXT_RX_DEC	 0x02000000
 #define  MAC_PHYCFG1_RGMII_SND_STAT_EN	 0x04000000
 #define  MAC_PHYCFG1_TXC_DRV		 0x20000000
@@ -675,6 +694,7 @@
 #define  SG_DIG_PARTNER_FULL_DUPLEX	 0x00020000 /* If !MRADV_CRC16_SELECT */
 #define  SG_DIG_PARTNER_NEXT_PAGE	 0x00010000 /* If !MRADV_CRC16_SELECT */
 #define  SG_DIG_AUTONEG_STATE_MASK	 0x00000ff0
+#define  SG_DIG_IS_SERDES		 0x00000100
 #define  SG_DIG_COMMA_DETECTOR		 0x00000008
 #define  SG_DIG_MAC_ACK_STATUS		 0x00000004
 #define  SG_DIG_AUTONEG_COMPLETE	 0x00000002
@@ -682,7 +702,22 @@
 /* 0x5b8 --> 0x600 unused */
 #define MAC_TX_MAC_STATE_BASE		0x00000600 /* 16 bytes */
 #define MAC_RX_MAC_STATE_BASE		0x00000610 /* 20 bytes */
-/* 0x624 --> 0x800 unused */
+/* 0x624 --> 0x670 unused */
+
+#define MAC_RSS_INDIR_TBL_0		0x00000630
+
+#define MAC_RSS_HASH_KEY_0		0x00000670
+#define MAC_RSS_HASH_KEY_1		0x00000674
+#define MAC_RSS_HASH_KEY_2		0x00000678
+#define MAC_RSS_HASH_KEY_3		0x0000067c
+#define MAC_RSS_HASH_KEY_4		0x00000680
+#define MAC_RSS_HASH_KEY_5		0x00000684
+#define MAC_RSS_HASH_KEY_6		0x00000688
+#define MAC_RSS_HASH_KEY_7		0x0000068c
+#define MAC_RSS_HASH_KEY_8		0x00000690
+#define MAC_RSS_HASH_KEY_9		0x00000694
+/* 0x698 --> 0x800 unused */
+
 #define MAC_TX_STATS_OCTETS		0x00000800
 #define MAC_TX_STATS_RESV1		0x00000804
 #define MAC_TX_STATS_COLLISIONS		0x00000808
@@ -814,6 +849,7 @@
 #define  SNDBDI_MODE_RESET		 0x00000001
 #define  SNDBDI_MODE_ENABLE		 0x00000002
 #define  SNDBDI_MODE_ATTN_ENABLE	 0x00000004
+#define  SNDBDI_MODE_MULTI_TXQ_EN	 0x00000020
 #define SNDBDI_STATUS			0x00001804
 #define  SNDBDI_STATUS_ERROR_ATTN	 0x00000004
 #define SNDBDI_IN_PROD_IDX_0		0x00001808
@@ -864,6 +900,7 @@
 #define  RCVLPC_STATSCTRL_ENABLE	 0x00000001
 #define  RCVLPC_STATSCTRL_FASTUPD	 0x00000002
 #define RCVLPC_STATS_ENABLE		0x00002018
+#define  RCVLPC_STATSENAB_ASF_FIX	 0x00000002
 #define  RCVLPC_STATSENAB_DACK_FIX	 0x00040000
 #define  RCVLPC_STATSENAB_LNGBRST_RFIX	 0x00400000
 #define RCVLPC_STATS_INCMASK		0x0000201c
@@ -941,7 +978,11 @@
 #define RCVBDI_MINI_THRESH		0x00002c14
 #define RCVBDI_STD_THRESH		0x00002c18
 #define RCVBDI_JUMBO_THRESH		0x00002c1c
-/* 0x2c20 --> 0x3000 unused */
+/* 0x2c20 --> 0x2d00 unused */
+
+#define STD_REPLENISH_LWM		0x00002d00
+#define JMB_REPLENISH_LWM		0x00002d04
+/* 0x2d08 --> 0x3000 unused */
 
 /* Receive BD Completion Control Registers */
 #define RCVCC_MODE			0x00003000
@@ -987,8 +1028,10 @@
 #define TG3_CPMU_HST_ACC		0x0000361c
 #define  CPMU_HST_ACC_MACCLK_MASK	 0x001f0000
 #define  CPMU_HST_ACC_MACCLK_6_25	 0x00130000
-/* 0x3620 --> 0x3630 unused */
+/* 0x3620 --> 0x362c unused */
 
+#define TG3_CPMU_STATUS			0x0000362c
+#define  TG3_CPMU_STATUS_PCIE_FUNC	 0x20000000
 #define TG3_CPMU_CLCK_STAT		0x00003630
 #define  CPMU_CLCK_STAT_MAC_CLCK_MASK	 0x001f0000
 #define  CPMU_CLCK_STAT_MAC_CLCK_62_5	 0x00000000
@@ -1022,6 +1065,7 @@
 #define  HOSTCC_MODE_CLRTICK_TXBD	 0x00000400
 #define  HOSTCC_MODE_NOINT_ON_NOW	 0x00000800
 #define  HOSTCC_MODE_NOINT_ON_FORCE	 0x00001000
+#define  HOSTCC_MODE_COAL_VEC1_NOW	 0x00002000
 #define HOSTCC_STATUS			0x00003c04
 #define  HOSTCC_STATUS_ERROR_ATTN	 0x00000004
 #define HOSTCC_RXCOL_TICKS		0x00003c08
@@ -1107,7 +1151,16 @@
 #define HOSTCC_SND_CON_IDX_13		0x00003cf4
 #define HOSTCC_SND_CON_IDX_14		0x00003cf8
 #define HOSTCC_SND_CON_IDX_15		0x00003cfc
-/* 0x3d00 --> 0x4000 unused */
+#define HOSTCC_STATBLCK_RING1		0x00003d00
+/* 0x3d00 --> 0x3d80 unused */
+
+#define HOSTCC_RXCOL_TICKS_VEC1		0x00003d80
+#define HOSTCC_TXCOL_TICKS_VEC1		0x00003d84
+#define HOSTCC_RXMAX_FRAMES_VEC1	0x00003d88
+#define HOSTCC_TXMAX_FRAMES_VEC1	0x00003d8c
+#define HOSTCC_RXCOAL_MAXF_INT_VEC1	0x00003d90
+#define HOSTCC_TXCOAL_MAXF_INT_VEC1	0x00003d94
+/* 0x3d98 --> 0x4000 unused */
 
 /* Memory arbiter control registers */
 #define MEMARB_MODE			0x00004000
@@ -1445,6 +1498,8 @@
 #define MSGINT_MODE			0x00006000
 #define  MSGINT_MODE_RESET		 0x00000001
 #define  MSGINT_MODE_ENABLE		 0x00000002
+#define  MSGINT_MODE_ONE_SHOT_DISABLE	 0x00000020
+#define  MSGINT_MODE_MULTIVEC_EN	 0x00000080
 #define MSGINT_STATUS			0x00006004
 #define MSGINT_FIFO			0x00006008
 /* 0x600c --> 0x6400 unused */
@@ -1640,6 +1695,25 @@
 #define  FLASH_57780VENDOR_ATMEL_AT45DB021B 0x03400002
 #define  FLASH_57780VENDOR_ATMEL_AT45DB041D 0x00400001
 #define  FLASH_57780VENDOR_ATMEL_AT45DB041B 0x03400001
+#define  FLASH_5717VENDOR_ATMEL_EEPROM	 0x02000001
+#define  FLASH_5717VENDOR_MICRO_EEPROM	 0x02000003
+#define  FLASH_5717VENDOR_ATMEL_MDB011D	 0x01000001
+#define  FLASH_5717VENDOR_ATMEL_MDB021D	 0x01000003
+#define  FLASH_5717VENDOR_ST_M_M25PE10	 0x02000000
+#define  FLASH_5717VENDOR_ST_M_M25PE20	 0x02000002
+#define  FLASH_5717VENDOR_ST_M_M45PE10	 0x00000001
+#define  FLASH_5717VENDOR_ST_M_M45PE20	 0x00000003
+#define  FLASH_5717VENDOR_ATMEL_ADB011B	 0x01400000
+#define  FLASH_5717VENDOR_ATMEL_ADB021B	 0x01400002
+#define  FLASH_5717VENDOR_ATMEL_ADB011D	 0x01400001
+#define  FLASH_5717VENDOR_ATMEL_ADB021D	 0x01400003
+#define  FLASH_5717VENDOR_ST_A_M25PE10	 0x02400000
+#define  FLASH_5717VENDOR_ST_A_M25PE20	 0x02400002
+#define  FLASH_5717VENDOR_ST_A_M45PE10	 0x02400001
+#define  FLASH_5717VENDOR_ST_A_M45PE20	 0x02400003
+#define  FLASH_5717VENDOR_ATMEL_45USPT	 0x03400000
+#define  FLASH_5717VENDOR_ST_25USPT	 0x03400002
+#define  FLASH_5717VENDOR_ST_45USPT	 0x03400001
 #define  NVRAM_CFG1_5752PAGE_SIZE_MASK	 0x70000000
 #define  FLASH_5752PAGE_SIZE_256	 0x00000000
 #define  FLASH_5752PAGE_SIZE_512	 0x10000000
@@ -1696,11 +1770,23 @@
 #define PCIE_TRANSACTION_CFG		0x00007c04
 #define PCIE_TRANS_CFG_1SHOT_MSI	 0x20000000
 #define PCIE_TRANS_CFG_LOM		 0x00000020
+/* 0x7c08 --> 0x7d28 unused */
 
 #define PCIE_PWR_MGMT_THRESH		0x00007d28
 #define PCIE_PWR_MGMT_L1_THRESH_MSK	 0x0000ff00
 #define PCIE_PWR_MGMT_L1_THRESH_4MS	 0x0000ff00
 #define PCIE_PWR_MGMT_EXT_ASPM_TMR_EN	 0x01000000
+/* 0x7d2c --> 0x7d54 unused */
+
+#define TG3_PCIE_LNKCTL			0x00007d54
+#define  TG3_PCIE_LNKCTL_L1_PLL_PD_EN	 0x00000008
+#define  TG3_PCIE_LNKCTL_L1_PLL_PD_DIS	 0x00000080
+/* 0x7d58 --> 0x7e70 unused */
+
+#define TG3_PCIE_EIDLE_DELAY		0x00007e70
+#define  TG3_PCIE_EIDLE_DELAY_MASK	 0x0000001f
+#define  TG3_PCIE_EIDLE_DELAY_13_CLKS	 0x0000000c
+/* 0x7e74 --> 0x8000 unused */
 
 
 /* OTP bit definitions */
@@ -1890,7 +1976,6 @@
 
 #define MII_TG3_DSP_RW_PORT		0x15 /* DSP coefficient read/write port */
 
-#define MII_TG3_EPHY_PTEST		0x17 /* 5906 PHY register */
 #define MII_TG3_DSP_ADDRESS		0x17 /* DSP address register */
 
 #define MII_TG3_DSP_TAP1		0x0001
@@ -1957,17 +2042,23 @@
 #define MII_TG3_MISC_SHDW_SCR5_LPED	0x0010
 #define MII_TG3_MISC_SHDW_SCR5_SEL	0x1400
 
-
-#define MII_TG3_EPHY_TEST		0x1f /* 5906 PHY register */
-#define MII_TG3_EPHY_SHADOW_EN		0x80
-
-#define MII_TG3_EPHYTST_MISCCTRL	0x10 /* 5906 EPHY misc ctrl shadow register */
-#define MII_TG3_EPHYTST_MISCCTRL_MDIX	0x4000
-
 #define MII_TG3_TEST1			0x1e
 #define MII_TG3_TEST1_TRIM_EN		0x0010
 #define MII_TG3_TEST1_CRC_EN		0x8000
 
+
+/* Fast Ethernet Tranceiver definitions */
+#define MII_TG3_FET_PTEST		0x17
+#define MII_TG3_FET_TEST		0x1f
+#define  MII_TG3_FET_SHADOW_EN		0x0080
+
+#define MII_TG3_FET_SHDW_MISCCTRL	0x10
+#define  MII_TG3_FET_SHDW_MISCCTRL_MDIX	0x4000
+
+#define MII_TG3_FET_SHDW_AUXSTAT2	0x1b
+#define  MII_TG3_FET_SHDW_AUXSTAT2_APD	0x0020
+
+
 /* APE registers.  Accessible through BAR1 */
 #define TG3_APE_EVENT			0x000c
 #define  APE_EVENT_1			 0x00000001
@@ -2065,6 +2156,7 @@ struct tg3_tx_buffer_desc {
 #define TXD_FLAG_IP_CSUM		0x0002
 #define TXD_FLAG_END			0x0004
 #define TXD_FLAG_IP_FRAG		0x0008
+#define TXD_FLAG_JMB_PKT		0x0008
 #define TXD_FLAG_IP_FRAG_END		0x0010
 #define TXD_FLAG_VLAN			0x0040
 #define TXD_FLAG_COAL_NOW		0x0080
@@ -2450,6 +2542,49 @@ struct tg3_ethtool_stats {
 	u64		nic_tx_threshold_hit;
 };
 
+struct tg3_rx_prodring_set {
+	u32				rx_std_ptr;
+	u32				rx_jmb_ptr;
+	struct tg3_rx_buffer_desc	*rx_std;
+	struct tg3_ext_rx_buffer_desc	*rx_jmb;
+	struct ring_info		*rx_std_buffers;
+	struct ring_info		*rx_jmb_buffers;
+	dma_addr_t			rx_std_mapping;
+	dma_addr_t			rx_jmb_mapping;
+};
+
+#define TG3_IRQ_MAX_VECS 5
+
+struct tg3_napi {
+	struct napi_struct		napi	____cacheline_aligned;
+	struct tg3			*tp;
+	struct tg3_hw_status		*hw_status;
+
+	u32				last_tag;
+	u32				last_irq_tag;
+	u32				int_mbox;
+	u32				coal_now;
+	u32				tx_prod;
+	u32				tx_cons;
+	u32				tx_pending;
+	u32				prodmbox;
+
+	u32				consmbox;
+	u32				rx_rcb_ptr;
+	u16				*rx_rcb_prod_idx;
+
+	struct tg3_rx_buffer_desc	*rx_rcb;
+	struct tg3_tx_buffer_desc	*tx_ring;
+	struct tx_ring_info		*tx_buffers;
+
+	dma_addr_t			status_mapping;
+	dma_addr_t			rx_rcb_mapping;
+	dma_addr_t			tx_desc_mapping;
+
+	char				irq_lbl[IFNAMSIZ];
+	unsigned int			irq_vec;
+};
+
 struct tg3 {
 	/* begin "general, frequently-used members" cacheline section */
 
@@ -2502,50 +2637,26 @@ struct tg3 {
 	struct net_device		*dev;
 	struct pci_dev			*pdev;
 
-	struct tg3_hw_status		*hw_status;
-	dma_addr_t			status_mapping;
-	u32				last_tag;
-	u32				last_irq_tag;
-
 	u32				msg_enable;
 
 	/* begin "tx thread" cacheline section */
 	void				(*write32_tx_mbox) (struct tg3 *, u32,
 							    u32);
-	u32				tx_prod;
-	u32				tx_cons;
-	u32				tx_pending;
-
-	struct tg3_tx_buffer_desc	*tx_ring;
-	struct tx_ring_info		*tx_buffers;
-	dma_addr_t			tx_desc_mapping;
 
 	/* begin "rx thread" cacheline section */
-	struct napi_struct		napi;
+	struct tg3_napi			napi[TG3_IRQ_MAX_VECS];
 	void				(*write32_rx_mbox) (struct tg3 *, u32,
 							    u32);
-	u32				rx_rcb_ptr;
-	u32				rx_std_ptr;
-	u32				rx_jumbo_ptr;
 	u32				rx_pending;
 	u32				rx_jumbo_pending;
+	u32				rx_std_max_post;
+	u32				rx_pkt_map_sz;
 #if TG3_VLAN_TAG_USED
 	struct vlan_group		*vlgrp;
 #endif
 
-	struct tg3_rx_buffer_desc	*rx_std;
-	struct ring_info		*rx_std_buffers;
-	dma_addr_t			rx_std_mapping;
-	u32				rx_std_max_post;
-
-	struct tg3_rx_buffer_desc	*rx_jumbo;
-	struct ring_info		*rx_jumbo_buffers;
-	dma_addr_t			rx_jumbo_mapping;
-
-	struct tg3_rx_buffer_desc	*rx_rcb;
-	dma_addr_t			rx_rcb_mapping;
+	struct tg3_rx_prodring_set	prodring[1];
 
-	u32				rx_pkt_buf_sz;
 
 	/* begin "everything else" cacheline(s) section */
 	struct net_device_stats		net_stats;
@@ -2575,6 +2686,10 @@ struct tg3 {
 #define TG3_FLAG_EEPROM_WRITE_PROT	0x00001000
 #define TG3_FLAG_NVRAM			0x00002000
 #define TG3_FLAG_NVRAM_BUFFERED		0x00004000
+#define TG3_FLAG_SUPPORT_MSI		0x00008000
+#define TG3_FLAG_SUPPORT_MSIX		0x00010000
+#define TG3_FLAG_SUPPORT_MSI_OR_MSIX	(TG3_FLAG_SUPPORT_MSI | \
+					 TG3_FLAG_SUPPORT_MSIX)
 #define TG3_FLAG_PCIX_MODE		0x00020000
 #define TG3_FLAG_PCI_HIGH_SPEED		0x00040000
 #define TG3_FLAG_PCI_32BIT		0x00080000
@@ -2587,7 +2702,7 @@ struct tg3 {
 #define TG3_FLAG_CPMU_PRESENT		0x04000000
 #define TG3_FLAG_40BIT_DMA_BUG		0x08000000
 #define TG3_FLAG_BROKEN_CHECKSUMS	0x10000000
-#define TG3_FLAG_SUPPORT_MSI		0x20000000
+#define TG3_FLAG_JUMBO_CAPABLE		0x20000000
 #define TG3_FLAG_CHIP_RESETTING		0x40000000
 #define TG3_FLAG_INIT_COMPLETE		0x80000000
 	u32				tg3_flags2;
@@ -2613,7 +2728,9 @@ struct tg3 {
 #define TG3_FLG2_5750_PLUS		0x00080000
 #define TG3_FLG2_PROTECTED_NVRAM	0x00100000
 #define TG3_FLG2_USING_MSI		0x00200000
-#define TG3_FLG2_JUMBO_CAPABLE		0x00400000
+#define TG3_FLG2_USING_MSIX		0x00400000
+#define TG3_FLG2_USING_MSI_OR_MSIX	(TG3_FLG2_USING_MSI | \
+					TG3_FLG2_USING_MSIX)
 #define TG3_FLG2_MII_SERDES		0x00800000
 #define TG3_FLG2_ANY_SERDES		(TG3_FLG2_PHY_SERDES |	\
 					TG3_FLG2_MII_SERDES)
@@ -2641,6 +2758,9 @@ struct tg3 {
 #define TG3_FLG3_PHY_ENABLE_APD		0x00001000
 #define TG3_FLG3_5755_PLUS		0x00002000
 #define TG3_FLG3_NO_NVRAM		0x00004000
+#define TG3_FLG3_TOGGLE_10_100_L1PLLPD	0x00008000
+#define TG3_FLG3_PHY_IS_FET		0x00010000
+#define TG3_FLG3_ENABLE_RSS		0x00020000
 
 	struct timer_list		timer;
 	u16				timer_counter;
@@ -2686,6 +2806,8 @@ struct tg3 {
 	struct mii_bus			*mdio_bus;
 	int				mdio_irq[PHY_MAX_ADDR];
 
+	u8				phy_addr;
+
 	/* PHY info */
 	u32				phy_id;
 #define PHY_ID_MASK			0xfffffff0
@@ -2785,6 +2907,9 @@ struct tg3 {
 
 #define SST_25VF0X0_PAGE_SIZE		4098
 
+	unsigned int			irq_max;
+	unsigned int			irq_cnt;
+
 	struct ethtool_coalesce		coal;
 
 	/* firmware info */
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 384cb5e..3d31b47 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -289,7 +289,7 @@ static void	TLan_EisaProbe( void );
 static void	TLan_Eisa_Cleanup( void );
 static int      TLan_Init( struct net_device * );
 static int	TLan_Open( struct net_device *dev );
-static int	TLan_StartTx( struct sk_buff *, struct net_device *);
+static netdev_tx_t TLan_StartTx( struct sk_buff *, struct net_device *);
 static irqreturn_t TLan_HandleInterrupt( int, void *);
 static int	TLan_Close( struct net_device *);
 static struct	net_device_stats *TLan_GetStats( struct net_device *);
@@ -1004,8 +1004,6 @@ static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
 			TLan_MiiWriteReg(dev, data->phy_id & 0x1f,
 					 data->reg_num & 0x1f, data->val_in);
 			return 0;
@@ -1083,7 +1081,7 @@ static void TLan_tx_timeout_work(struct work_struct *work)
 	 *
 	 **************************************************************/
 
-static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
+static netdev_tx_t TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
 {
 	TLanPrivateInfo *priv = netdev_priv(dev);
 	dma_addr_t	tail_list_phys;
@@ -1095,11 +1093,11 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
 		TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  %s PHY is not ready\n",
 			  dev->name );
 		dev_kfree_skb_any(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
-		return 0;
+		return NETDEV_TX_OK;
 	txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
 
 	tail_list = priv->txList + priv->txTail;
@@ -1150,7 +1148,7 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
 	CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
 
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 
 } /* TLan_StartTx */
 
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index b40b6de..7241589 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -128,7 +128,7 @@ static int xl_init(struct net_device *dev);
 static int xl_open(struct net_device *dev);
 static int xl_open_hw(struct net_device *dev) ;  
 static int xl_hw_reset(struct net_device *dev); 
-static int xl_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev);
 static void xl_dn_comp(struct net_device *dev); 
 static int xl_close(struct net_device *dev);
 static void xl_set_rx_mode(struct net_device *dev);
@@ -1193,7 +1193,7 @@ static irqreturn_t xl_interrupt(int irq, void *dev_id)
  *	Tx - Polling configuration
  */
 	
-static int xl_xmit(struct sk_buff *skb, struct net_device *dev) 
+static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct xl_private *xl_priv=netdev_priv(dev);
 	struct xl_tx_desc *txd ; 
@@ -1240,7 +1240,7 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
  
-		return 0;
+		return NETDEV_TX_OK;
 	} else {
 		spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
 		return NETDEV_TX_BUSY;
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 08a6c41..525bbc5 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -191,7 +191,8 @@ static int 	tok_init_card(struct net_device *dev);
 static void	tok_open_adapter(unsigned long dev_addr);
 static void 	open_sap(unsigned char type, struct net_device *dev);
 static void 	tok_set_multicast_list(struct net_device *dev);
-static int 	tok_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t tok_send_packet(struct sk_buff *skb,
+					 struct net_device *dev);
 static int 	tok_close(struct net_device *dev);
 static irqreturn_t tok_interrupt(int irq, void *dev_id);
 static void 	initial_tok_int(struct net_device *dev);
@@ -1022,7 +1023,8 @@ static void tok_set_multicast_list(struct net_device *dev)
 
 #define STATION_ID_OFST 4
 
-static int tok_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tok_send_packet(struct sk_buff *skb,
+					 struct net_device *dev)
 {
 	struct tok_info *ti;
 	unsigned long flags;
@@ -1041,7 +1043,7 @@ static int tok_send_packet(struct sk_buff *skb, struct net_device *dev)
 	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 	spin_unlock_irqrestore(&(ti->lock), flags);
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*****************************************************************************/
diff --git a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
index b3715ef..26dca2b 100644
--- a/drivers/net/tokenring/lanstreamer.c
+++ b/drivers/net/tokenring/lanstreamer.c
@@ -203,7 +203,8 @@ static int streamer_ioctl(struct net_device *, struct ifreq *, int);
 
 static int streamer_reset(struct net_device *dev);
 static int streamer_open(struct net_device *dev);
-static int streamer_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t streamer_xmit(struct sk_buff *skb,
+				       struct net_device *dev);
 static int streamer_close(struct net_device *dev);
 static void streamer_set_rx_mode(struct net_device *dev);
 static irqreturn_t streamer_interrupt(int irq, void *dev_id);
@@ -1141,7 +1142,8 @@ static irqreturn_t streamer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int streamer_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t streamer_xmit(struct sk_buff *skb,
+				       struct net_device *dev)
 {
 	struct streamer_private *streamer_priv =
 	    netdev_priv(dev);
@@ -1183,7 +1185,7 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1);
 		spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
-		return 0;
+		return NETDEV_TX_OK;
 	} else {
 	        netif_stop_queue(dev);
 	        spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 451b541..d9ec7f0 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -182,7 +182,8 @@ MODULE_DEVICE_TABLE(pci,olympic_pci_tbl) ;
 static int olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 
 static int olympic_init(struct net_device *dev);
 static int olympic_open(struct net_device *dev);
-static int olympic_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t olympic_xmit(struct sk_buff *skb,
+				      struct net_device *dev);
 static int olympic_close(struct net_device *dev);
 static void olympic_set_rx_mode(struct net_device *dev);
 static void olympic_freemem(struct net_device *dev) ;  
@@ -1030,7 +1031,8 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }	
 
-static int olympic_xmit(struct sk_buff *skb, struct net_device *dev) 
+static netdev_tx_t olympic_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct olympic_private *olympic_priv=netdev_priv(dev);
 	u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
@@ -1052,7 +1054,7 @@ static int olympic_xmit(struct sk_buff *skb, struct net_device *dev)
 		writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
 		netif_wake_queue(dev);
 		spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
-		return 0;
+		return NETDEV_TX_OK;
 	} else {
 		spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
 		return NETDEV_TX_BUSY;
diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c
index 54ad4ed..ebda61b 100644
--- a/drivers/net/tokenring/smctr.c
+++ b/drivers/net/tokenring/smctr.c
@@ -234,7 +234,8 @@ static int smctr_rx_frame(struct net_device *dev);
 
 /* S */
 static int smctr_send_dat(struct net_device *dev);
-static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t smctr_send_packet(struct sk_buff *skb,
+					   struct net_device *dev);
 static int smctr_send_lobe_media_test(struct net_device *dev);
 static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf,
         __u16 correlator);
@@ -3091,11 +3092,7 @@ static int smctr_lobe_media_test(struct net_device *dev)
         /* Setup the lobe media test. */
         smctr_lobe_media_test_cmd(dev);
         if(smctr_wait_cmd(dev))
-        {
-                smctr_reset_adapter(dev);
-                tp->status = CLOSED;
-                return (LOBE_MEDIA_TEST_FAILED);
-        }
+		goto err;
 
         /* Tx lobe media test frames. */
         for(i = 0; i < 1500; ++i)
@@ -3103,20 +3100,12 @@ static int smctr_lobe_media_test(struct net_device *dev)
                 if(smctr_send_lobe_media_test(dev))
                 {
                         if(perror)
-                        {
-                                smctr_reset_adapter(dev);
-                                tp->state = CLOSED;
-                                return (LOBE_MEDIA_TEST_FAILED);
-                        }
+				goto err;
                         else
                         {
                                 perror = 1;
                                 if(smctr_lobe_media_test_cmd(dev))
-                                {
-                                        smctr_reset_adapter(dev);
-                                        tp->state = CLOSED;
-                                        return (LOBE_MEDIA_TEST_FAILED);
-                                }
+					goto err;
                         }
                 }
         }
@@ -3124,28 +3113,24 @@ static int smctr_lobe_media_test(struct net_device *dev)
         if(smctr_send_dat(dev))
         {
                 if(smctr_send_dat(dev))
-                {
-                        smctr_reset_adapter(dev);
-                        tp->state = CLOSED;
-                        return (LOBE_MEDIA_TEST_FAILED);
-                }
+			goto err;
         }
 
         /* Check if any frames received during test. */
         if((tp->rx_fcb_curr[MAC_QUEUE]->frame_status)
                 || (tp->rx_fcb_curr[NON_MAC_QUEUE]->frame_status))
-        {
-                smctr_reset_adapter(dev);
-                tp->state = CLOSED;
-                return (LOBE_MEDIA_TEST_FAILED);
-        }
+			goto err;
 
         /* Set receive mask to "Promisc" mode. */
         tp->receive_mask = saved_rcv_mask;
 
         smctr_chg_rx_mask(dev);
 
-        return (0);
+	 return 0;
+err:
+	smctr_reset_adapter(dev);
+	tp->status = CLOSED;
+	return LOBE_MEDIA_TEST_FAILED;
 }
 
 static int smctr_lobe_media_test_cmd(struct net_device *dev)
@@ -4587,7 +4572,8 @@ static void smctr_timeout(struct net_device *dev)
 /*
  * Gets skb from system, queues it and checks if it can be sent
  */
-static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t smctr_send_packet(struct sk_buff *skb,
+					   struct net_device *dev)
 {
         struct net_local *tp = netdev_priv(dev);
 
@@ -4609,7 +4595,7 @@ static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev)
         if(tp->QueueSkb > 0)
 		netif_wake_queue(dev);
 		
-        return (0);
+        return NETDEV_TX_OK;
 }
 
 static int smctr_send_lobe_media_test(struct net_device *dev)
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index a2eab72..a7b6888 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -144,8 +144,8 @@ static void 	tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValu
 /* "G" */
 static struct net_device_stats *tms380tr_get_stats(struct net_device *dev);
 /* "H" */
-static int 	tms380tr_hardware_send_packet(struct sk_buff *skb,
-			struct net_device *dev);
+static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb,
+						       struct net_device *dev);
 /* "I" */
 static int 	tms380tr_init_adapter(struct net_device *dev);
 static void 	tms380tr_init_ipb(struct net_local *tp);
@@ -165,7 +165,8 @@ static int 	tms380tr_reset_adapter(struct net_device *dev);
 static void 	tms380tr_reset_interrupt(struct net_device *dev);
 static void 	tms380tr_ring_status_irq(struct net_device *dev);
 /* "S" */
-static int 	tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb,
+					      struct net_device *dev);
 static void 	tms380tr_set_multicast_list(struct net_device *dev);
 static int	tms380tr_set_mac_address(struct net_device *dev, void *addr);
 /* "T" */
@@ -599,21 +600,23 @@ static void tms380tr_timeout(struct net_device *dev)
 /*
  * Gets skb from system, queues it and checks if it can be sent
  */
-static int tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tms380tr_send_packet(struct sk_buff *skb,
+					      struct net_device *dev)
 {
 	struct net_local *tp = netdev_priv(dev);
-	int err;
+	netdev_tx_t rc;
 
-	err = tms380tr_hardware_send_packet(skb, dev);
+	rc = tms380tr_hardware_send_packet(skb, dev);
 	if(tp->TplFree->NextTPLPtr->BusyFlag)
 		netif_stop_queue(dev);
-	return (err);
+	return rc;
 }
 
 /*
  * Move frames into adapter tx queue
  */
-static int tms380tr_hardware_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tms380tr_hardware_send_packet(struct sk_buff *skb,
+						       struct net_device *dev)
 {
 	TPL *tpl;
 	short length;
@@ -682,7 +685,7 @@ static int tms380tr_hardware_send_packet(struct sk_buff *skb, struct net_device
 	tms380tr_exec_sifcmd(dev, CMD_TX_VALID);
 	spin_unlock_irqrestore(&tp->lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index ef49744..74e5ba4 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -599,7 +599,8 @@ next:
 		netif_wake_queue(de->dev);
 }
 
-static int de_start_xmit (struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t de_start_xmit (struct sk_buff *skb,
+					struct net_device *dev)
 {
 	struct de_private *de = netdev_priv(dev);
 	unsigned int entry, tx_free;
@@ -651,7 +652,7 @@ static int de_start_xmit (struct sk_buff *skb, struct net_device *dev)
 	dw32(TxPoll, NormalTxPoll);
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* Set or clear the multicast filter for this adaptor.
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index acfdccd..a8349b7 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -895,7 +895,8 @@ static struct {
 ** Public Functions
 */
 static int     de4x5_open(struct net_device *dev);
-static int     de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t de4x5_queue_pkt(struct sk_buff *skb,
+					 struct net_device *dev);
 static irqreturn_t de4x5_interrupt(int irq, void *dev_id);
 static int     de4x5_close(struct net_device *dev);
 static struct  net_device_stats *de4x5_get_stats(struct net_device *dev);
@@ -1456,18 +1457,16 @@ de4x5_sw_reset(struct net_device *dev)
 /*
 ** Writes a socket buffer address to the next available transmit descriptor.
 */
-static int
+static netdev_tx_t
 de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
 {
     struct de4x5_private *lp = netdev_priv(dev);
     u_long iobase = dev->base_addr;
-    int status = NETDEV_TX_OK;
     u_long flags = 0;
 
     netif_stop_queue(dev);
-    if (!lp->tx_enable) {                   /* Cannot send for now */
+    if (!lp->tx_enable)                   /* Cannot send for now */
 	return NETDEV_TX_LOCKED;
-    }
 
     /*
     ** Clean out the TX ring asynchronously to interrupts - sometimes the
@@ -1521,7 +1520,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
 
     lp->cache.lock = 0;
 
-    return status;
+    return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 8e78f00..a45ded0 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -311,7 +311,7 @@ static u8 SF_mode;		/* Special Function: 1:VLAN, 2:RX Flow Control
 
 /* function declaration ------------------------------------- */
 static int dmfe_open(struct DEVICE *);
-static int dmfe_start_xmit(struct sk_buff *, struct DEVICE *);
+static netdev_tx_t dmfe_start_xmit(struct sk_buff *, struct DEVICE *);
 static int dmfe_stop(struct DEVICE *);
 static void dmfe_set_filter_mode(struct DEVICE *);
 static const struct ethtool_ops netdev_ethtool_ops;
@@ -661,7 +661,8 @@ static void dmfe_init_dm910x(struct DEVICE *dev)
  *	Send a packet to media from the upper layer.
  */
 
-static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev)
+static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb,
+					 struct DEVICE *dev)
 {
 	struct dmfe_board_info *db = netdev_priv(dev);
 	struct tx_desc *txptr;
@@ -676,7 +677,7 @@ static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev)
 	if (skb->len > MAX_PACKET_SIZE) {
 		printk(KERN_ERR DRV_NAME ": big packet = %d\n", (u16)skb->len);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	spin_lock_irqsave(&db->lock, flags);
@@ -722,7 +723,7 @@ static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev)
 	/* free this SKB */
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 4cf9a65..6b2330e 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -256,7 +256,8 @@ const char tulip_media_cap[32] =
 static void tulip_tx_timeout(struct net_device *dev);
 static void tulip_init_ring(struct net_device *dev);
 static void tulip_free_ring(struct net_device *dev);
-static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t tulip_start_xmit(struct sk_buff *skb,
+					  struct net_device *dev);
 static int tulip_open(struct net_device *dev);
 static int tulip_close(struct net_device *dev);
 static void tulip_up(struct net_device *dev);
@@ -645,7 +646,7 @@ static void tulip_init_ring(struct net_device *dev)
 	tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma);
 }
 
-static int
+static netdev_tx_t
 tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct tulip_private *tp = netdev_priv(dev);
@@ -693,7 +694,7 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void tulip_clean_tx_ring(struct tulip_private *tp)
@@ -922,8 +923,6 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 		return 0;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable (CAP_NET_ADMIN))
-			return -EPERM;
 		if (regnum & ~0x1f)
 			return -EINVAL;
 		if (data->phy_id == phy) {
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 9277ce8..c457a0c 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -215,7 +215,8 @@ static int mode = 8;
 
 /* function declaration ------------------------------------- */
 static int uli526x_open(struct net_device *);
-static int uli526x_start_xmit(struct sk_buff *, struct net_device *);
+static netdev_tx_t uli526x_start_xmit(struct sk_buff *,
+					    struct net_device *);
 static int uli526x_stop(struct net_device *);
 static void uli526x_set_filter_mode(struct net_device *);
 static const struct ethtool_ops netdev_ethtool_ops;
@@ -567,7 +568,8 @@ static void uli526x_init(struct net_device *dev)
  *	Send a packet to media from the upper layer.
  */
 
-static int uli526x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t uli526x_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	struct uli526x_board_info *db = netdev_priv(dev);
 	struct tx_desc *txptr;
@@ -582,7 +584,7 @@ static int uli526x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (skb->len > MAX_PACKET_SIZE) {
 		printk(KERN_ERR DRV_NAME ": big packet = %d\n", (u16)skb->len);
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	spin_lock_irqsave(&db->lock, flags);
@@ -624,7 +626,7 @@ static int uli526x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* free this SKB */
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 0f15773..b38d3b7 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -333,7 +333,7 @@ static void init_registers(struct net_device *dev);
 static void tx_timeout(struct net_device *dev);
 static int alloc_ringdesc(struct net_device *dev);
 static void free_ringdesc(struct netdev_private *np);
-static int  start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void netdev_error(struct net_device *dev, int intr_status);
 static int  netdev_rx(struct net_device *dev);
@@ -997,7 +997,7 @@ static void free_ringdesc(struct netdev_private *np)
 
 }
 
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
 	unsigned entry;
@@ -1058,7 +1058,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
 			   dev->name, np->cur_tx, entry);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void netdev_tx_done(struct net_device *dev)
@@ -1470,8 +1470,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		return 0;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		spin_lock_irq(&np->lock);
 		mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
 		spin_unlock_irq(&np->lock);
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index c2ca9f4..0f2ca59 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -113,7 +113,8 @@ struct xircom_private {
 static int xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id);
 static void xircom_remove(struct pci_dev *pdev);
 static irqreturn_t xircom_interrupt(int irq, void *dev_instance);
-static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t xircom_start_xmit(struct sk_buff *skb,
+					   struct net_device *dev);
 static int xircom_open(struct net_device *dev);
 static int xircom_close(struct net_device *dev);
 static void xircom_up(struct xircom_private *card);
@@ -384,7 +385,8 @@ static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
 	return IRQ_HANDLED;
 }
 
-static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t xircom_start_xmit(struct sk_buff *skb,
+					   struct net_device *dev)
 {
 	struct xircom_private *card;
 	unsigned long flags;
@@ -434,7 +436,7 @@ static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			card->transmit_used = nextdescriptor;
 			leave("xircom-start_xmit - sent");
 			spin_unlock_irqrestore(&card->lock,flags);
-			return 0;
+			return NETDEV_TX_OK;
 	}
 
 
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 87214a2..d3ee199 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -103,13 +103,10 @@ struct tun_struct {
 	uid_t			owner;
 	gid_t			group;
 
-	struct sk_buff_head	readq;
-
 	struct net_device	*dev;
 	struct fasync_struct	*fasync;
 
 	struct tap_filter       txflt;
-	struct sock		*sk;
 	struct socket		socket;
 
 #ifdef TUN_DEBUG
@@ -148,7 +145,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
 	tfile->tun = tun;
 	tun->tfile = tfile;
 	dev_hold(tun->dev);
-	sock_hold(tun->sk);
+	sock_hold(tun->socket.sk);
 	atomic_inc(&tfile->count);
 
 out:
@@ -164,7 +161,7 @@ static void __tun_detach(struct tun_struct *tun)
 	netif_tx_unlock_bh(tun->dev);
 
 	/* Drop read queue */
-	skb_queue_purge(&tun->readq);
+	skb_queue_purge(&tun->socket.sk->sk_receive_queue);
 
 	/* Drop the extra count on the net device */
 	dev_put(tun->dev);
@@ -333,7 +330,7 @@ static void tun_free_netdev(struct net_device *dev)
 {
 	struct tun_struct *tun = netdev_priv(dev);
 
-	sock_put(tun->sk);
+	sock_put(tun->socket.sk);
 }
 
 /* Net device open. */
@@ -351,7 +348,7 @@ static int tun_net_close(struct net_device *dev)
 }
 
 /* Net device start xmit */
-static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct tun_struct *tun = netdev_priv(dev);
 
@@ -367,7 +364,7 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (!check_filter(&tun->txflt, skb))
 		goto drop;
 
-	if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
+	if (skb_queue_len(&tun->socket.sk->sk_receive_queue) >= dev->tx_queue_len) {
 		if (!(tun->flags & TUN_ONE_QUEUE)) {
 			/* Normal queueing mode. */
 			/* Packet scheduler handles dropping of further packets. */
@@ -384,19 +381,19 @@ static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* Enqueue packet */
-	skb_queue_tail(&tun->readq, skb);
+	skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
 	dev->trans_start = jiffies;
 
 	/* Notify and wake up reader process */
 	if (tun->flags & TUN_FASYNC)
 		kill_fasync(&tun->fasync, SIGIO, POLL_IN);
 	wake_up_interruptible(&tun->socket.wait);
-	return 0;
+	return NETDEV_TX_OK;
 
 drop:
 	dev->stats.tx_dropped++;
 	kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void tun_net_mclist(struct net_device *dev)
@@ -485,13 +482,13 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
 	if (!tun)
 		return POLLERR;
 
-	sk = tun->sk;
+	sk = tun->socket.sk;
 
 	DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
 
 	poll_wait(file, &tun->socket.wait, wait);
 
-	if (!skb_queue_empty(&tun->readq))
+	if (!skb_queue_empty(&sk->sk_receive_queue))
 		mask |= POLLIN | POLLRDNORM;
 
 	if (sock_writeable(sk) ||
@@ -512,7 +509,7 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
 					    size_t prepad, size_t len,
 					    size_t linear, int noblock)
 {
-	struct sock *sk = tun->sk;
+	struct sock *sk = tun->socket.sk;
 	struct sk_buff *skb;
 	int err;
 
@@ -634,6 +631,9 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
 		case VIRTIO_NET_HDR_GSO_TCPV6:
 			skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
 			break;
+		case VIRTIO_NET_HDR_GSO_UDP:
+			skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+			break;
 		default:
 			tun->dev->stats.rx_frame_errors++;
 			kfree_skb(skb);
@@ -719,6 +719,8 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
 			else if (sinfo->gso_type & SKB_GSO_TCPV6)
 				gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+			else if (sinfo->gso_type & SKB_GSO_UDP)
+				gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
 			else
 				BUG();
 			if (sinfo->gso_type & SKB_GSO_TCP_ECN)
@@ -775,7 +777,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
 		current->state = TASK_INTERRUPTIBLE;
 
 		/* Read frames from the queue */
-		if (!(skb=skb_dequeue(&tun->readq))) {
+		if (!(skb=skb_dequeue(&tun->socket.sk->sk_receive_queue))) {
 			if (file->f_flags & O_NONBLOCK) {
 				ret = -EAGAIN;
 				break;
@@ -812,8 +814,6 @@ static void tun_setup(struct net_device *dev)
 {
 	struct tun_struct *tun = netdev_priv(dev);
 
-	skb_queue_head_init(&tun->readq);
-
 	tun->owner = -1;
 	tun->group = -1;
 
@@ -934,7 +934,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		     (tun->group != -1 && !in_egroup_p(tun->group))) &&
 		    !capable(CAP_NET_ADMIN))
 			return -EPERM;
-		err = security_tun_dev_attach(tun->sk);
+		err = security_tun_dev_attach(tun->socket.sk);
 		if (err < 0)
 			return err;
 
@@ -992,7 +992,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 		sk->sk_write_space = tun_sock_write_space;
 		sk->sk_sndbuf = INT_MAX;
 
-		tun->sk = sk;
 		container_of(sk, struct tun_sock, sk)->tun = tun;
 
 		security_tun_dev_post_create(sk);
@@ -1005,7 +1004,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 				goto err_free_sk;
 		}
 
-		err = -EINVAL;
 		err = register_netdevice(tun->dev);
 		if (err < 0)
 			goto err_free_sk;
@@ -1077,7 +1075,8 @@ static int set_offload(struct net_device *dev, unsigned long arg)
 	old_features = dev->features;
 	/* Unset features, set them as we chew on the arg. */
 	features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST
-				    |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6));
+				    |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6
+				    |NETIF_F_UFO));
 
 	if (arg & TUN_F_CSUM) {
 		features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
@@ -1094,6 +1093,11 @@ static int set_offload(struct net_device *dev, unsigned long arg)
 				features |= NETIF_F_TSO6;
 			arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
 		}
+
+		if (arg & TUN_F_UFO) {
+			features |= NETIF_F_UFO;
+			arg &= ~TUN_F_UFO;
+		}
 	}
 
 	/* This gives the user a way to test for new features in future by
@@ -1247,7 +1251,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd,
 		break;
 
 	case TUNGETSNDBUF:
-		sndbuf = tun->sk->sk_sndbuf;
+		sndbuf = tun->socket.sk->sk_sndbuf;
 		if (copy_to_user(argp, &sndbuf, sizeof(sndbuf)))
 			ret = -EFAULT;
 		break;
@@ -1258,7 +1262,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd,
 			break;
 		}
 
-		tun->sk->sk_sndbuf = sndbuf;
+		tun->socket.sk->sk_sndbuf = sndbuf;
 		break;
 
 	default:
@@ -1341,7 +1345,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
 
 	tun = tfile->tun;
 	if (tun)
-		sock_put(tun->sk);
+		sock_put(tun->socket.sk);
 
 	put_net(tfile->net);
 	kfree(tfile);
@@ -1366,7 +1370,7 @@ static const struct file_operations tun_fops = {
 static struct miscdevice tun_miscdev = {
 	.minor = TUN_MINOR,
 	.name = "tun",
-	.devnode = "net/tun",
+	.nodename = "net/tun",
 	.fops = &tun_fops,
 };
 
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index cf25eb4..d6d3452 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -762,7 +762,7 @@ typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
 	tcpd->status = 0;
 }
 
-static int
+static netdev_tx_t
 typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct typhoon *tp = netdev_priv(dev);
@@ -909,7 +909,7 @@ typhoon_start_tx(struct sk_buff *skb, struct net_device *dev)
 			netif_wake_queue(dev);
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 8a7b8c7..4469f24 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -209,9 +209,10 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
 {
 	struct sk_buff *skb = NULL;
 
-	skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length +
-				  UCC_GETH_RX_DATA_BUF_ALIGNMENT);
-
+	skb = __skb_dequeue(&ugeth->rx_recycle);
+	if (!skb)
+		skb = dev_alloc_skb(ugeth->ug_info->uf_info.max_rx_buf_length +
+				    UCC_GETH_RX_DATA_BUF_ALIGNMENT);
 	if (skb == NULL)
 		return NULL;
 
@@ -437,38 +438,6 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
 		     QE_CR_PROTOCOL_ETHERNET, 0);
 }
 
-#ifdef CONFIG_UGETH_MAGIC_PACKET
-static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
-{
-	struct ucc_fast_private *uccf;
-	struct ucc_geth __iomem *ug_regs;
-
-	uccf = ugeth->uccf;
-	ug_regs = ugeth->ug_regs;
-
-	/* Enable interrupts for magic packet detection */
-	setbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD);
-
-	/* Enable magic packet detection */
-	setbits32(&ug_regs->maccfg2, MACCFG2_MPE);
-}
-
-static void magic_packet_detection_disable(struct ucc_geth_private *ugeth)
-{
-	struct ucc_fast_private *uccf;
-	struct ucc_geth __iomem *ug_regs;
-
-	uccf = ugeth->uccf;
-	ug_regs = ugeth->ug_regs;
-
-	/* Disable interrupts for magic packet detection */
-	clrbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD);
-
-	/* Disable magic packet detection */
-	clrbits32(&ug_regs->maccfg2, MACCFG2_MPE);
-}
-#endif /* MAGIC_PACKET */
-
 static inline int compare_addr(u8 **addr1, u8 **addr2)
 {
 	return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS);
@@ -1443,6 +1412,174 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 	return 0;
 }
 
+static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
+{
+	struct ucc_fast_private *uccf;
+	u32 cecr_subblock;
+	u32 temp;
+	int i = 10;
+
+	uccf = ugeth->uccf;
+
+	/* Mask GRACEFUL STOP TX interrupt bit and clear it */
+	clrbits32(uccf->p_uccm, UCC_GETH_UCCE_GRA);
+	out_be32(uccf->p_ucce, UCC_GETH_UCCE_GRA);  /* clear by writing 1 */
+
+	/* Issue host command */
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+	qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
+		     QE_CR_PROTOCOL_ETHERNET, 0);
+
+	/* Wait for command to complete */
+	do {
+		msleep(10);
+		temp = in_be32(uccf->p_ucce);
+	} while (!(temp & UCC_GETH_UCCE_GRA) && --i);
+
+	uccf->stopped_tx = 1;
+
+	return 0;
+}
+
+static int ugeth_graceful_stop_rx(struct ucc_geth_private *ugeth)
+{
+	struct ucc_fast_private *uccf;
+	u32 cecr_subblock;
+	u8 temp;
+	int i = 10;
+
+	uccf = ugeth->uccf;
+
+	/* Clear acknowledge bit */
+	temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
+	temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX;
+	out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp);
+
+	/* Keep issuing command and checking acknowledge bit until
+	it is asserted, according to spec */
+	do {
+		/* Issue host command */
+		cecr_subblock =
+		    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.
+						ucc_num);
+		qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
+			     QE_CR_PROTOCOL_ETHERNET, 0);
+		msleep(10);
+		temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
+	} while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX) && --i);
+
+	uccf->stopped_rx = 1;
+
+	return 0;
+}
+
+static int ugeth_restart_tx(struct ucc_geth_private *ugeth)
+{
+	struct ucc_fast_private *uccf;
+	u32 cecr_subblock;
+
+	uccf = ugeth->uccf;
+
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+	qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0);
+	uccf->stopped_tx = 0;
+
+	return 0;
+}
+
+static int ugeth_restart_rx(struct ucc_geth_private *ugeth)
+{
+	struct ucc_fast_private *uccf;
+	u32 cecr_subblock;
+
+	uccf = ugeth->uccf;
+
+	cecr_subblock =
+	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
+	qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
+		     0);
+	uccf->stopped_rx = 0;
+
+	return 0;
+}
+
+static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
+{
+	struct ucc_fast_private *uccf;
+	int enabled_tx, enabled_rx;
+
+	uccf = ugeth->uccf;
+
+	/* check if the UCC number is in range. */
+	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: ucc_num out of range.", __func__);
+		return -EINVAL;
+	}
+
+	enabled_tx = uccf->enabled_tx;
+	enabled_rx = uccf->enabled_rx;
+
+	/* Get Tx and Rx going again, in case this channel was actively
+	disabled. */
+	if ((mode & COMM_DIR_TX) && (!enabled_tx) && uccf->stopped_tx)
+		ugeth_restart_tx(ugeth);
+	if ((mode & COMM_DIR_RX) && (!enabled_rx) && uccf->stopped_rx)
+		ugeth_restart_rx(ugeth);
+
+	ucc_fast_enable(uccf, mode);	/* OK to do even if not disabled */
+
+	return 0;
+
+}
+
+static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode)
+{
+	struct ucc_fast_private *uccf;
+
+	uccf = ugeth->uccf;
+
+	/* check if the UCC number is in range. */
+	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: ucc_num out of range.", __func__);
+		return -EINVAL;
+	}
+
+	/* Stop any transmissions */
+	if ((mode & COMM_DIR_TX) && uccf->enabled_tx && !uccf->stopped_tx)
+		ugeth_graceful_stop_tx(ugeth);
+
+	/* Stop any receptions */
+	if ((mode & COMM_DIR_RX) && uccf->enabled_rx && !uccf->stopped_rx)
+		ugeth_graceful_stop_rx(ugeth);
+
+	ucc_fast_disable(ugeth->uccf, mode); /* OK to do even if not enabled */
+
+	return 0;
+}
+
+static void ugeth_quiesce(struct ucc_geth_private *ugeth)
+{
+	/* Wait for and prevent any further xmits. */
+	netif_tx_disable(ugeth->ndev);
+
+	/* Disable the interrupt to avoid NAPI rescheduling. */
+	disable_irq(ugeth->ug_info->uf_info.irq);
+
+	/* Stop NAPI, and possibly wait for its completion. */
+	napi_disable(&ugeth->napi);
+}
+
+static void ugeth_activate(struct ucc_geth_private *ugeth)
+{
+	napi_enable(&ugeth->napi);
+	enable_irq(ugeth->ug_info->uf_info.irq);
+	netif_tx_wake_all_queues(ugeth->ndev);
+}
+
 /* Called every time the controller might need to be made
  * aware of new link state.  The PHY code conveys this
  * information through variables in the ugeth structure, and this
@@ -1456,14 +1593,11 @@ static void adjust_link(struct net_device *dev)
 	struct ucc_geth __iomem *ug_regs;
 	struct ucc_fast __iomem *uf_regs;
 	struct phy_device *phydev = ugeth->phydev;
-	unsigned long flags;
 	int new_state = 0;
 
 	ug_regs = ugeth->ug_regs;
 	uf_regs = ugeth->uccf->uf_regs;
 
-	spin_lock_irqsave(&ugeth->lock, flags);
-
 	if (phydev->link) {
 		u32 tempval = in_be32(&ug_regs->maccfg2);
 		u32 upsmr = in_be32(&uf_regs->upsmr);
@@ -1514,9 +1648,21 @@ static void adjust_link(struct net_device *dev)
 			ugeth->oldspeed = phydev->speed;
 		}
 
+		/*
+		 * To change the MAC configuration we need to disable the
+		 * controller. To do so, we have to either grab ugeth->lock,
+		 * which is a bad idea since 'graceful stop' commands might
+		 * take quite a while, or we can quiesce driver's activity.
+		 */
+		ugeth_quiesce(ugeth);
+		ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
+
 		out_be32(&ug_regs->maccfg2, tempval);
 		out_be32(&uf_regs->upsmr, upsmr);
 
+		ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+		ugeth_activate(ugeth);
+
 		if (!ugeth->oldlink) {
 			new_state = 1;
 			ugeth->oldlink = 1;
@@ -1530,8 +1676,6 @@ static void adjust_link(struct net_device *dev)
 
 	if (new_state && netif_msg_link(ugeth))
 		phy_print_status(phydev);
-
-	spin_unlock_irqrestore(&ugeth->lock, flags);
 }
 
 /* Initialize TBI PHY interface for communicating with the
@@ -1618,157 +1762,6 @@ static int init_phy(struct net_device *dev)
 	return 0;
 }
 
-
-
-static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
-{
-	struct ucc_fast_private *uccf;
-	u32 cecr_subblock;
-	u32 temp;
-	int i = 10;
-
-	uccf = ugeth->uccf;
-
-	/* Mask GRACEFUL STOP TX interrupt bit and clear it */
-	clrbits32(uccf->p_uccm, UCC_GETH_UCCE_GRA);
-	out_be32(uccf->p_ucce, UCC_GETH_UCCE_GRA);  /* clear by writing 1 */
-
-	/* Issue host command */
-	cecr_subblock =
-	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-	qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
-		     QE_CR_PROTOCOL_ETHERNET, 0);
-
-	/* Wait for command to complete */
-	do {
-		msleep(10);
-		temp = in_be32(uccf->p_ucce);
-	} while (!(temp & UCC_GETH_UCCE_GRA) && --i);
-
-	uccf->stopped_tx = 1;
-
-	return 0;
-}
-
-static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
-{
-	struct ucc_fast_private *uccf;
-	u32 cecr_subblock;
-	u8 temp;
-	int i = 10;
-
-	uccf = ugeth->uccf;
-
-	/* Clear acknowledge bit */
-	temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
-	temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX;
-	out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp);
-
-	/* Keep issuing command and checking acknowledge bit until
-	it is asserted, according to spec */
-	do {
-		/* Issue host command */
-		cecr_subblock =
-		    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.
-						ucc_num);
-		qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
-			     QE_CR_PROTOCOL_ETHERNET, 0);
-		msleep(10);
-		temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
-	} while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX) && --i);
-
-	uccf->stopped_rx = 1;
-
-	return 0;
-}
-
-static int ugeth_restart_tx(struct ucc_geth_private *ugeth)
-{
-	struct ucc_fast_private *uccf;
-	u32 cecr_subblock;
-
-	uccf = ugeth->uccf;
-
-	cecr_subblock =
-	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-	qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0);
-	uccf->stopped_tx = 0;
-
-	return 0;
-}
-
-static int ugeth_restart_rx(struct ucc_geth_private *ugeth)
-{
-	struct ucc_fast_private *uccf;
-	u32 cecr_subblock;
-
-	uccf = ugeth->uccf;
-
-	cecr_subblock =
-	    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-	qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
-		     0);
-	uccf->stopped_rx = 0;
-
-	return 0;
-}
-
-static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
-{
-	struct ucc_fast_private *uccf;
-	int enabled_tx, enabled_rx;
-
-	uccf = ugeth->uccf;
-
-	/* check if the UCC number is in range. */
-	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
-		if (netif_msg_probe(ugeth))
-			ugeth_err("%s: ucc_num out of range.", __func__);
-		return -EINVAL;
-	}
-
-	enabled_tx = uccf->enabled_tx;
-	enabled_rx = uccf->enabled_rx;
-
-	/* Get Tx and Rx going again, in case this channel was actively
-	disabled. */
-	if ((mode & COMM_DIR_TX) && (!enabled_tx) && uccf->stopped_tx)
-		ugeth_restart_tx(ugeth);
-	if ((mode & COMM_DIR_RX) && (!enabled_rx) && uccf->stopped_rx)
-		ugeth_restart_rx(ugeth);
-
-	ucc_fast_enable(uccf, mode);	/* OK to do even if not disabled */
-
-	return 0;
-
-}
-
-static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
-{
-	struct ucc_fast_private *uccf;
-
-	uccf = ugeth->uccf;
-
-	/* check if the UCC number is in range. */
-	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
-		if (netif_msg_probe(ugeth))
-			ugeth_err("%s: ucc_num out of range.", __func__);
-		return -EINVAL;
-	}
-
-	/* Stop any transmissions */
-	if ((mode & COMM_DIR_TX) && uccf->enabled_tx && !uccf->stopped_tx)
-		ugeth_graceful_stop_tx(ugeth);
-
-	/* Stop any receptions */
-	if ((mode & COMM_DIR_RX) && uccf->enabled_rx && !uccf->stopped_rx)
-		ugeth_graceful_stop_rx(ugeth);
-
-	ucc_fast_disable(ugeth->uccf, mode); /* OK to do even if not enabled */
-
-	return 0;
-}
-
 static void ugeth_dump_regs(struct ucc_geth_private *ugeth)
 {
 #ifdef DEBUG
@@ -1986,6 +1979,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 		iounmap(ugeth->ug_regs);
 		ugeth->ug_regs = NULL;
 	}
+
+	skb_queue_purge(&ugeth->rx_recycle);
 }
 
 static void ucc_geth_set_multi(struct net_device *dev)
@@ -2202,6 +2197,8 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 		return -ENOMEM;
 	}
 
+	skb_queue_head_init(&ugeth->rx_recycle);
+
 	return 0;
 }
 
@@ -3174,7 +3171,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
 	spin_unlock_irqrestore(&ugeth->lock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
@@ -3209,8 +3206,10 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
 			if (netif_msg_rx_err(ugeth))
 				ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
 					   __func__, __LINE__, (u32) skb);
-			if (skb)
-				dev_kfree_skb_any(skb);
+			if (skb) {
+				skb->data = skb->head + NET_SKB_PAD;
+				__skb_queue_head(&ugeth->rx_recycle, skb);
+			}
 
 			ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL;
 			dev->stats.rx_dropped++;
@@ -3268,6 +3267,8 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 
 	/* Normal processing. */
 	while ((bd_status & T_R) == 0) {
+		struct sk_buff *skb;
+
 		/* BD contains already transmitted buffer.   */
 		/* Handle the transmitted buffer and release */
 		/* the BD to be used with the current frame  */
@@ -3277,9 +3278,16 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 
 		dev->stats.tx_packets++;
 
-		/* Free the sk buffer associated with this TxBD */
-		dev_kfree_skb(ugeth->
-				  tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
+		skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]];
+
+		if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
+			     skb_recycle_check(skb,
+				    ugeth->ug_info->uf_info.max_rx_buf_length +
+				    UCC_GETH_RX_DATA_BUF_ALIGNMENT))
+			__skb_queue_head(&ugeth->rx_recycle, skb);
+		else
+			dev_kfree_skb(skb);
+
 		ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
 		ugeth->skb_dirtytx[txQ] =
 		    (ugeth->skb_dirtytx[txQ] +
@@ -3308,16 +3316,16 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
 
 	ug_info = ugeth->ug_info;
 
-	howmany = 0;
-	for (i = 0; i < ug_info->numQueuesRx; i++)
-		howmany += ucc_geth_rx(ugeth, i, budget - howmany);
-
 	/* Tx event processing */
 	spin_lock(&ugeth->lock);
 	for (i = 0; i < ug_info->numQueuesTx; i++)
 		ucc_geth_tx(ugeth->ndev, i);
 	spin_unlock(&ugeth->lock);
 
+	howmany = 0;
+	for (i = 0; i < ug_info->numQueuesRx; i++)
+		howmany += ucc_geth_rx(ugeth, i, budget - howmany);
+
 	if (howmany < budget) {
 		napi_complete(napi);
 		setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS);
@@ -3414,46 +3422,25 @@ static int ucc_geth_set_mac_addr(struct net_device *dev, void *p)
 	return 0;
 }
 
-/* Called when something needs to use the ethernet device */
-/* Returns 0 for success. */
-static int ucc_geth_open(struct net_device *dev)
+static int ucc_geth_init_mac(struct ucc_geth_private *ugeth)
 {
-	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	struct net_device *dev = ugeth->ndev;
 	int err;
 
-	ugeth_vdbg("%s: IN", __func__);
-
-	/* Test station address */
-	if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
-		if (netif_msg_ifup(ugeth))
-			ugeth_err("%s: Multicast address used for station address"
-				  " - is this what you wanted?", __func__);
-		return -EINVAL;
-	}
-
-	err = init_phy(dev);
-	if (err) {
-		if (netif_msg_ifup(ugeth))
-			ugeth_err("%s: Cannot initialize PHY, aborting.",
-				  dev->name);
-		return err;
-	}
-
 	err = ucc_struct_init(ugeth);
 	if (err) {
 		if (netif_msg_ifup(ugeth))
-			ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
-		goto out_err_stop;
+			ugeth_err("%s: Cannot configure internal struct, "
+				  "aborting.", dev->name);
+		goto err;
 	}
 
-	napi_enable(&ugeth->napi);
-
 	err = ucc_geth_startup(ugeth);
 	if (err) {
 		if (netif_msg_ifup(ugeth))
 			ugeth_err("%s: Cannot configure net device, aborting.",
 				  dev->name);
-		goto out_err;
+		goto err;
 	}
 
 	err = adjust_enet_interface(ugeth);
@@ -3461,7 +3448,7 @@ static int ucc_geth_open(struct net_device *dev)
 		if (netif_msg_ifup(ugeth))
 			ugeth_err("%s: Cannot configure net device, aborting.",
 				  dev->name);
-		goto out_err;
+		goto err;
 	}
 
 	/*       Set MACSTNADDR1, MACSTNADDR2                */
@@ -3475,13 +3462,51 @@ static int ucc_geth_open(struct net_device *dev)
 				   &ugeth->ug_regs->macstnaddr1,
 				   &ugeth->ug_regs->macstnaddr2);
 
-	phy_start(ugeth->phydev);
-
 	err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
 	if (err) {
 		if (netif_msg_ifup(ugeth))
 			ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
-		goto out_err;
+		goto err;
+	}
+
+	return 0;
+err:
+	ucc_geth_stop(ugeth);
+	return err;
+}
+
+/* Called when something needs to use the ethernet device */
+/* Returns 0 for success. */
+static int ucc_geth_open(struct net_device *dev)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(dev);
+	int err;
+
+	ugeth_vdbg("%s: IN", __func__);
+
+	/* Test station address */
+	if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Multicast address used for station "
+				  "address - is this what you wanted?",
+				  __func__);
+		return -EINVAL;
+	}
+
+	err = init_phy(dev);
+	if (err) {
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot initialize PHY, aborting.",
+				  dev->name);
+		return err;
+	}
+
+	err = ucc_geth_init_mac(ugeth);
+	if (err) {
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot initialize MAC, aborting.",
+				  dev->name);
+		goto err;
 	}
 
 	err = request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler,
@@ -3490,16 +3515,20 @@ static int ucc_geth_open(struct net_device *dev)
 		if (netif_msg_ifup(ugeth))
 			ugeth_err("%s: Cannot get IRQ for net device, aborting.",
 				  dev->name);
-		goto out_err;
+		goto err;
 	}
 
+	phy_start(ugeth->phydev);
+	napi_enable(&ugeth->napi);
 	netif_start_queue(dev);
 
+	device_set_wakeup_capable(&dev->dev,
+			qe_alive_during_sleep() || ugeth->phydev->irq);
+	device_set_wakeup_enable(&dev->dev, ugeth->wol_en);
+
 	return err;
 
-out_err:
-	napi_disable(&ugeth->napi);
-out_err_stop:
+err:
 	ucc_geth_stop(ugeth);
 	return err;
 }
@@ -3561,6 +3590,85 @@ static void ucc_geth_timeout(struct net_device *dev)
 	schedule_work(&ugeth->timeout_work);
 }
 
+
+#ifdef CONFIG_PM
+
+static int ucc_geth_suspend(struct of_device *ofdev, pm_message_t state)
+{
+	struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+	struct ucc_geth_private *ugeth = netdev_priv(ndev);
+
+	if (!netif_running(ndev))
+		return 0;
+
+	napi_disable(&ugeth->napi);
+
+	/*
+	 * Disable the controller, otherwise we'll wakeup on any network
+	 * activity.
+	 */
+	ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
+
+	if (ugeth->wol_en & WAKE_MAGIC) {
+		setbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD);
+		setbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE);
+		ucc_fast_enable(ugeth->uccf, COMM_DIR_RX_AND_TX);
+	} else if (!(ugeth->wol_en & WAKE_PHY)) {
+		phy_stop(ugeth->phydev);
+	}
+
+	return 0;
+}
+
+static int ucc_geth_resume(struct of_device *ofdev)
+{
+	struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+	struct ucc_geth_private *ugeth = netdev_priv(ndev);
+	int err;
+
+	if (!netif_running(ndev))
+		return 0;
+
+	if (qe_alive_during_sleep()) {
+		if (ugeth->wol_en & WAKE_MAGIC) {
+			ucc_fast_disable(ugeth->uccf, COMM_DIR_RX_AND_TX);
+			clrbits32(&ugeth->ug_regs->maccfg2, MACCFG2_MPE);
+			clrbits32(ugeth->uccf->p_uccm, UCC_GETH_UCCE_MPD);
+		}
+		ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+	} else {
+		/*
+		 * Full reinitialization is required if QE shuts down
+		 * during sleep.
+		 */
+		ucc_geth_memclean(ugeth);
+
+		err = ucc_geth_init_mac(ugeth);
+		if (err) {
+			ugeth_err("%s: Cannot initialize MAC, aborting.",
+				  ndev->name);
+			return err;
+		}
+	}
+
+	ugeth->oldlink = 0;
+	ugeth->oldspeed = 0;
+	ugeth->oldduplex = -1;
+
+	phy_stop(ugeth->phydev);
+	phy_start(ugeth->phydev);
+
+	napi_enable(&ugeth->napi);
+	netif_start_queue(ndev);
+
+	return 0;
+}
+
+#else
+#define ucc_geth_suspend NULL
+#define ucc_geth_resume NULL
+#endif
+
 static phy_interface_t to_phy_interface(const char *phy_connection_type)
 {
 	if (strcasecmp(phy_connection_type, "mii") == 0)
@@ -3852,6 +3960,8 @@ static struct of_platform_driver ucc_geth_driver = {
 	.match_table	= ucc_geth_match,
 	.probe		= ucc_geth_probe,
 	.remove		= ucc_geth_remove,
+	.suspend	= ucc_geth_suspend,
+	.resume		= ucc_geth_resume,
 };
 
 static int __init ucc_geth_init(void)
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 195ab26..03a6ca0 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -1212,6 +1212,8 @@ struct ucc_geth_private {
 	/* index of the first skb which hasn't been transmitted yet. */
 	u16 skb_dirtytx[NUM_TX_QUEUES];
 
+	struct sk_buff_head rx_recycle;
+
 	struct ugeth_mii_info *mii_info;
 	struct phy_device *phydev;
 	phy_interface_t phy_interface;
@@ -1220,6 +1222,7 @@ struct ucc_geth_private {
 	int oldspeed;
 	int oldduplex;
 	int oldlink;
+	int wol_en;
 
 	struct device_node *node;
 };
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 61fe80d..7075f26 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -319,9 +319,13 @@ static void uec_get_ethtool_stats(struct net_device *netdev,
 	int i, j = 0;
 
 	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
-		base = (u32 __iomem *)&ugeth->ug_regs->tx64;
+		if (ugeth->ug_regs)
+			base = (u32 __iomem *)&ugeth->ug_regs->tx64;
+		else
+			base = NULL;
+
 		for (i = 0; i < UEC_HW_STATS_LEN; i++)
-			data[j++] = in_be32(&base[i]);
+			data[j++] = base ? in_be32(&base[i]) : 0;
 	}
 	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
 		base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram;
@@ -355,6 +359,44 @@ uec_get_drvinfo(struct net_device *netdev,
 	drvinfo->regdump_len = uec_get_regs_len(netdev);
 }
 
+#ifdef CONFIG_PM
+
+static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	struct phy_device *phydev = ugeth->phydev;
+
+	if (phydev && phydev->irq)
+		wol->supported |= WAKE_PHY;
+	if (qe_alive_during_sleep())
+		wol->supported |= WAKE_MAGIC;
+
+	wol->wolopts = ugeth->wol_en;
+}
+
+static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	struct phy_device *phydev = ugeth->phydev;
+
+	if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
+		return -EINVAL;
+	else if (wol->wolopts & WAKE_PHY && (!phydev || !phydev->irq))
+		return -EINVAL;
+	else if (wol->wolopts & WAKE_MAGIC && !qe_alive_during_sleep())
+		return -EINVAL;
+
+	ugeth->wol_en = wol->wolopts;
+	device_set_wakeup_enable(&netdev->dev, ugeth->wol_en);
+
+	return 0;
+}
+
+#else
+#define uec_get_wol NULL
+#define uec_set_wol NULL
+#endif /* CONFIG_PM */
+
 static const struct ethtool_ops uec_ethtool_ops = {
 	.get_settings           = uec_get_settings,
 	.set_settings           = uec_set_settings,
@@ -373,6 +415,8 @@ static const struct ethtool_ops uec_ethtool_ops = {
 	.get_sset_count		= uec_get_sset_count,
 	.get_strings            = uec_get_strings,
 	.get_ethtool_stats      = uec_get_ethtool_stats,
+	.get_wol		= uec_get_wol,
+	.set_wol		= uec_set_wol,
 };
 
 void uec_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
index 87b4a02..6ce7f77 100644
--- a/drivers/net/usb/asix.c
+++ b/drivers/net/usb/asix.c
@@ -731,7 +731,7 @@ static int asix_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
 /* We need to override some ethtool_ops so we require our
    own structure so we don't interfere with other usbnet
    devices that may be connected at the same time. */
-static struct ethtool_ops ax88172_ethtool_ops = {
+static const struct ethtool_ops ax88172_ethtool_ops = {
 	.get_drvinfo		= asix_get_drvinfo,
 	.get_link		= asix_get_link,
 	.get_msglevel		= usbnet_get_msglevel,
@@ -873,7 +873,7 @@ out:
 	return ret;
 }
 
-static struct ethtool_ops ax88772_ethtool_ops = {
+static const struct ethtool_ops ax88772_ethtool_ops = {
 	.get_drvinfo		= asix_get_drvinfo,
 	.get_link		= asix_get_link,
 	.get_msglevel		= usbnet_get_msglevel,
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index b9dd425..2bed6b0 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -411,7 +411,8 @@ static void catc_tx_done(struct urb *urb)
 	spin_unlock_irqrestore(&catc->tx_lock, flags);
 }
 
-static int catc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t catc_start_xmit(struct sk_buff *skb,
+					 struct net_device *netdev)
 {
 	struct catc *catc = netdev_priv(netdev);
 	unsigned long flags;
@@ -448,7 +449,7 @@ static int catc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void catc_tx_timeout(struct net_device *netdev)
@@ -697,7 +698,7 @@ static int catc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 	return 0;
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
 	.get_drvinfo = catc_get_drvinfo,
 	.get_settings = catc_get_settings,
 	.get_link = ethtool_op_get_link
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c
index 792af72..33d5c57 100644
--- a/drivers/net/usb/cdc-phonet.c
+++ b/drivers/net/usb/cdc-phonet.c
@@ -27,6 +27,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/if_phonet.h>
+#include <linux/phonet.h>
 
 #define PN_MEDIA_USB	0x1B
 
@@ -55,7 +56,7 @@ static void rx_complete(struct urb *req);
 /*
  * Network device callbacks
  */
-static int usbpn_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t usbpn_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct usbpn_dev *pnd = netdev_priv(dev);
 	struct urb *req = NULL;
@@ -82,12 +83,12 @@ static int usbpn_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (pnd->tx_queue >= dev->tx_queue_len)
 		netif_stop_queue(dev);
 	spin_unlock_irqrestore(&pnd->tx_lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 
 drop:
 	dev_kfree_skb(skb);
 	dev->stats.tx_dropped++;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void tx_complete(struct urb *req)
@@ -256,6 +257,18 @@ static int usbpn_close(struct net_device *dev)
 	return usb_set_interface(pnd->usb, num, !pnd->active_setting);
 }
 
+static int usbpn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct if_phonet_req *req = (struct if_phonet_req *)ifr;
+
+	switch (cmd) {
+	case SIOCPNGAUTOCONF:
+		req->ifr_phonet_autoconf.device = PN_DEV_PC;
+		return 0;
+	}
+	return -ENOIOCTLCMD;
+}
+
 static int usbpn_set_mtu(struct net_device *dev, int new_mtu)
 {
 	if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU))
@@ -269,6 +282,7 @@ static const struct net_device_ops usbpn_ops = {
 	.ndo_open	= usbpn_open,
 	.ndo_stop	= usbpn_close,
 	.ndo_start_xmit = usbpn_xmit,
+	.ndo_do_ioctl	= usbpn_ioctl,
 	.ndo_change_mtu = usbpn_set_mtu,
 };
 
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 1d3730d..72470f7 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -356,7 +356,7 @@ static int dm9601_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 	return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
 }
 
-static struct ethtool_ops dm9601_ethtool_ops = {
+static const struct ethtool_ops dm9601_ethtool_ops = {
 	.get_drvinfo	= dm9601_get_drvinfo,
 	.get_link	= dm9601_get_link,
 	.get_msglevel	= usbnet_get_msglevel,
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index f8c6d7e..fa4e581 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -771,7 +771,8 @@ static void write_bulk_callback(struct urb *urb)
 }
 
 /* called by kernel when we need to transmit a packet */
-static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
+					    struct net_device *net)
 {
 	struct hso_net *odev = netdev_priv(net);
 	int result;
@@ -780,7 +781,7 @@ static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
 	netif_stop_queue(net);
 	if (hso_get_activity(odev->parent) == -EAGAIN) {
 		odev->skb_tx_buf = skb;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* log if asked */
@@ -828,7 +829,7 @@ static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info
 	usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info);
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
 	.get_drvinfo = hso_get_drvinfo,
 	.get_link = ethtool_op_get_link
 };
@@ -2534,6 +2535,10 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
 	}
 }
 
+static struct device_type hso_type = {
+	.name	= "wwan",
+};
+
 /* Creates our network device */
 static struct hso_device *hso_create_net_device(struct usb_interface *interface,
 						int port_spec)
@@ -2574,6 +2579,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface,
 		goto exit;
 	}
 	SET_NETDEV_DEV(net, &interface->dev);
+	SET_NETDEV_DEVTYPE(net, &hso_type);
 
 	/* registering our net device */
 	result = register_netdev(net);
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index 1f9ec29..e2a39b9 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -778,7 +778,7 @@ static u32 kaweth_get_link(struct net_device *dev)
 	return kaweth->linkstate;
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
 	.get_drvinfo	= kaweth_get_drvinfo,
 	.get_link	= kaweth_get_link
 };
@@ -803,7 +803,8 @@ static void kaweth_usb_transmit_complete(struct urb *urb)
 /****************************************************************
  *     kaweth_start_xmit
  ****************************************************************/
-static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t kaweth_start_xmit(struct sk_buff *skb,
+					   struct net_device *net)
 {
 	struct kaweth_device *kaweth = netdev_priv(net);
 	__le16 *private_header;
@@ -829,7 +830,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
 			kaweth->stats.tx_errors++;
 			netif_start_queue(net);
 			spin_unlock_irq(&kaweth->device_lock);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 	}
 
@@ -864,7 +865,7 @@ skip:
 
 	spin_unlock_irq(&kaweth->device_lock);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /****************************************************************
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index 7ae9afe..10873d9 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -449,7 +449,7 @@ static void mcs7830_get_regs(struct net_device *net, struct ethtool_regs *regs,
 	mcs7830_get_reg(dev, 0, regs->len, data);
 }
 
-static struct ethtool_ops mcs7830_ethtool_ops = {
+static const struct ethtool_ops mcs7830_ethtool_ops = {
 	.get_drvinfo		= mcs7830_get_drvinfo,
 	.get_regs_len		= mcs7830_get_regs_len,
 	.get_regs		= mcs7830_get_regs,
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 631d269..6fdaba8 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -876,7 +876,8 @@ static void pegasus_tx_timeout(struct net_device *net)
 	pegasus->stats.tx_errors++;
 }
 
-static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t pegasus_start_xmit(struct sk_buff *skb,
+					    struct net_device *net)
 {
 	pegasus_t *pegasus = netdev_priv(net);
 	int count = ((skb->len + 2) & 0x3f) ? skb->len + 2 : skb->len + 3;
@@ -914,7 +915,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
 	}
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
@@ -1173,7 +1174,7 @@ static void pegasus_set_msglevel(struct net_device *dev, u32 v)
 	pegasus->msg_enable = v;
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
 	.get_drvinfo = pegasus_get_drvinfo,
 	.get_settings = pegasus_get_settings,
 	.set_settings = pegasus_set_settings,
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 2232232..d032bba 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -65,6 +65,32 @@ void rndis_status(struct usbnet *dev, struct urb *urb)
 EXPORT_SYMBOL_GPL(rndis_status);
 
 /*
+ * RNDIS indicate messages.
+ */
+static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
+				int buflen)
+{
+	struct cdc_state *info = (void *)&dev->data;
+	struct device *udev = &info->control->dev;
+
+	if (dev->driver_info->indication) {
+		dev->driver_info->indication(dev, msg, buflen);
+	} else {
+		switch (msg->status) {
+		case RNDIS_STATUS_MEDIA_CONNECT:
+			dev_info(udev, "rndis media connect\n");
+			break;
+		case RNDIS_STATUS_MEDIA_DISCONNECT:
+			dev_info(udev, "rndis media disconnect\n");
+			break;
+		default:
+			dev_info(udev, "rndis indication: 0x%08x\n",
+					le32_to_cpu(msg->status));
+		}
+	}
+}
+
+/*
  * RPC done RNDIS-style.  Caller guarantees:
  * - message is properly byteswapped
  * - there's no other request pending
@@ -143,27 +169,9 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
 					request_id, xid);
 				/* then likely retry */
 			} else switch (buf->msg_type) {
-			case RNDIS_MSG_INDICATE: {	/* fault/event */
-				struct rndis_indicate *msg = (void *)buf;
-				int state = 0;
-
-				switch (msg->status) {
-				case RNDIS_STATUS_MEDIA_CONNECT:
-					state = 1;
-				case RNDIS_STATUS_MEDIA_DISCONNECT:
-					dev_info(&info->control->dev,
-						"rndis media %sconnect\n",
-						!state?"dis":"");
-					if (dev->driver_info->link_change)
-						dev->driver_info->link_change(
-							dev, state);
-					break;
-				default:
-					dev_info(&info->control->dev,
-						"rndis indication: 0x%08x\n",
-						le32_to_cpu(msg->status));
-				}
-				}
+			case RNDIS_MSG_INDICATE:	/* fault/event */
+				rndis_msg_indicate(dev, (void *)buf, buflen);
+
 				break;
 			case RNDIS_MSG_KEEPALIVE: {	/* ping */
 				struct rndis_keepalive_c *msg = (void *)buf;
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index fcc6fa0..b091e20 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -727,7 +727,8 @@ static void rtl8150_set_multicast(struct net_device *netdev)
 	netif_wake_queue(netdev);
 }
 
-static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+static netdev_tx_t rtl8150_start_xmit(struct sk_buff *skb,
+					    struct net_device *netdev)
 {
 	rtl8150_t *dev = netdev_priv(netdev);
 	int count, res;
@@ -753,7 +754,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 		netdev->trans_start = jiffies;
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
@@ -864,7 +865,7 @@ static int rtl8150_get_settings(struct net_device *netdev, struct ethtool_cmd *e
 	return 0;
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
 	.get_drvinfo = rtl8150_get_drvinfo,
 	.get_settings = rtl8150_get_settings,
 	.get_link = ethtool_op_get_link
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index fe04589..938fb35 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -220,11 +220,6 @@ static int smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev)
 	do {
 		smsc95xx_read_reg(dev, E2P_CMD, &val);
 
-		if (!(val & E2P_CMD_LOADED_)) {
-			devwarn(dev, "No EEPROM present");
-			return -EIO;
-		}
-
 		if (!(val & E2P_CMD_BUSY_))
 			return 0;
 
@@ -630,7 +625,7 @@ static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val)
 	return smsc95xx_set_csums(dev);
 }
 
-static struct ethtool_ops smsc95xx_ethtool_ops = {
+static const struct ethtool_ops smsc95xx_ethtool_ops = {
 	.get_link	= usbnet_get_link,
 	.nway_reset	= usbnet_nway_reset,
 	.get_drvinfo	= usbnet_get_drvinfo,
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index edfd9e1..24b36f7 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -233,6 +233,11 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
 {
 	int	status;
 
+	if (test_bit(EVENT_RX_PAUSED, &dev->flags)) {
+		skb_queue_tail(&dev->rxq_pause, skb);
+		return;
+	}
+
 	skb->protocol = eth_type_trans (skb, dev->net);
 	dev->net->stats.rx_packets++;
 	dev->net->stats.rx_bytes += skb->len;
@@ -526,6 +531,41 @@ static void intr_complete (struct urb *urb)
 }
 
 /*-------------------------------------------------------------------------*/
+void usbnet_pause_rx(struct usbnet *dev)
+{
+	set_bit(EVENT_RX_PAUSED, &dev->flags);
+
+	if (netif_msg_rx_status(dev))
+		devdbg(dev, "paused rx queue enabled");
+}
+EXPORT_SYMBOL_GPL(usbnet_pause_rx);
+
+void usbnet_resume_rx(struct usbnet *dev)
+{
+	struct sk_buff *skb;
+	int num = 0;
+
+	clear_bit(EVENT_RX_PAUSED, &dev->flags);
+
+	while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) {
+		usbnet_skb_return(dev, skb);
+		num++;
+	}
+
+	tasklet_schedule(&dev->bh);
+
+	if (netif_msg_rx_status(dev))
+		devdbg(dev, "paused rx queue disabled, %d skbs requeued", num);
+}
+EXPORT_SYMBOL_GPL(usbnet_resume_rx);
+
+void usbnet_purge_paused_rxq(struct usbnet *dev)
+{
+	skb_queue_purge(&dev->rxq_pause);
+}
+EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq);
+
+/*-------------------------------------------------------------------------*/
 
 // unlink pending rx/tx; completion handlers do all other cleanup
 
@@ -575,7 +615,9 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
 int usbnet_stop (struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
+	struct driver_info	*info = dev->driver_info;
 	int			temp;
+	int			retval;
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
 	DECLARE_WAITQUEUE (wait, current);
 
@@ -587,24 +629,42 @@ int usbnet_stop (struct net_device *net)
 			net->stats.rx_errors, net->stats.tx_errors
 			);
 
-	// ensure there are no more active urbs
-	add_wait_queue (&unlink_wakeup, &wait);
-	dev->wait = &unlink_wakeup;
-	temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq);
+	/* allow minidriver to stop correctly (wireless devices to turn off
+	 * radio etc) */
+	if (info->stop) {
+		retval = info->stop(dev);
+		if (retval < 0 && netif_msg_ifdown(dev))
+			devinfo(dev,
+				"stop fail (%d) usbnet usb-%s-%s, %s",
+				retval,
+				dev->udev->bus->bus_name, dev->udev->devpath,
+				info->description);
+	}
 
-	// maybe wait for deletions to finish.
-	while (!skb_queue_empty(&dev->rxq)
-			&& !skb_queue_empty(&dev->txq)
-			&& !skb_queue_empty(&dev->done)) {
-		msleep(UNLINK_TIMEOUT_MS);
-		if (netif_msg_ifdown (dev))
-			devdbg (dev, "waited for %d urb completions", temp);
+	if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) {
+		/* ensure there are no more active urbs */
+		add_wait_queue(&unlink_wakeup, &wait);
+		dev->wait = &unlink_wakeup;
+		temp = unlink_urbs(dev, &dev->txq) +
+			unlink_urbs(dev, &dev->rxq);
+
+		/* maybe wait for deletions to finish. */
+		while (!skb_queue_empty(&dev->rxq)
+				&& !skb_queue_empty(&dev->txq)
+				&& !skb_queue_empty(&dev->done)) {
+			msleep(UNLINK_TIMEOUT_MS);
+			if (netif_msg_ifdown(dev))
+				devdbg(dev, "waited for %d urb completions",
+					temp);
+		}
+		dev->wait = NULL;
+		remove_wait_queue(&unlink_wakeup, &wait);
 	}
-	dev->wait = NULL;
-	remove_wait_queue (&unlink_wakeup, &wait);
 
 	usb_kill_urb(dev->interrupt);
 
+	usbnet_purge_paused_rxq(dev);
+
 	/* deferred work (task, timer, softirq) must also stop.
 	 * can't flush_scheduled_work() until we drop rtnl (later),
 	 * else workers could deadlock; so make workers a NOP.
@@ -794,7 +854,7 @@ void usbnet_set_msglevel (struct net_device *net, u32 level)
 EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
 
 /* drivers may override default ethtool_ops in their bind() routine */
-static struct ethtool_ops usbnet_ethtool_ops = {
+static const struct ethtool_ops usbnet_ethtool_ops = {
 	.get_settings		= usbnet_get_settings,
 	.set_settings		= usbnet_set_settings,
 	.get_link		= usbnet_get_link,
@@ -947,15 +1007,16 @@ EXPORT_SYMBOL_GPL(usbnet_tx_timeout);
 
 /*-------------------------------------------------------------------------*/
 
-int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
+netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
+				     struct net_device *net)
 {
 	struct usbnet		*dev = netdev_priv(net);
 	int			length;
-	int			retval = NET_XMIT_SUCCESS;
 	struct urb		*urb = NULL;
 	struct skb_data		*entry;
 	struct driver_info	*info = dev->driver_info;
 	unsigned long		flags;
+	int retval;
 
 	// some devices want funky USB-level framing, for
 	// win32 driver (usually) and/or hardware quirks
@@ -1019,7 +1080,6 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
 		if (netif_msg_tx_err (dev))
 			devdbg (dev, "drop, code %d", retval);
 drop:
-		retval = NET_XMIT_SUCCESS;
 		dev->net->stats.tx_dropped++;
 		if (skb)
 			dev_kfree_skb_any (skb);
@@ -1028,7 +1088,7 @@ drop:
 		devdbg (dev, "> tx, len %d, type 0x%x",
 			length, skb->protocol);
 	}
-	return retval;
+	return NETDEV_TX_OK;
 }
 EXPORT_SYMBOL_GPL(usbnet_start_xmit);
 
@@ -1095,7 +1155,6 @@ static void usbnet_bh (unsigned long param)
 }
 
 
-
 /*-------------------------------------------------------------------------
  *
  * USB Device Driver support
@@ -1192,6 +1251,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 	skb_queue_head_init (&dev->rxq);
 	skb_queue_head_init (&dev->txq);
 	skb_queue_head_init (&dev->done);
+	skb_queue_head_init(&dev->rxq_pause);
 	dev->bh.func = usbnet_bh;
 	dev->bh.data = (unsigned long) dev;
 	INIT_WORK (&dev->kevent, kevent);
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 1097c72..ade5b34 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -129,7 +129,7 @@ static int veth_set_tx_csum(struct net_device *dev, u32 data)
 	return 0;
 }
 
-static struct ethtool_ops veth_ethtool_ops = {
+static const struct ethtool_ops veth_ethtool_ops = {
 	.get_settings		= veth_get_settings,
 	.get_drvinfo		= veth_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
@@ -148,7 +148,7 @@ static struct ethtool_ops veth_ethtool_ops = {
  * xmit
  */
 
-static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_device *rcv = NULL;
 	struct veth_priv *priv, *rcv_priv;
@@ -171,6 +171,7 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (skb->len > (rcv->mtu + MTU_PAD))
 		goto rx_drop;
 
+        skb->tstamp.tv64 = 0;
 	skb->pkt_type = PACKET_HOST;
 	skb->protocol = eth_type_trans(skb, rcv);
 	if (dev->features & NETIF_F_NO_CSUM)
@@ -189,17 +190,17 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
 	rcv_stats->rx_packets++;
 
 	netif_rx(skb);
-	return 0;
+	return NETDEV_TX_OK;
 
 tx_drop:
 	kfree_skb(skb);
 	stats->tx_dropped++;
-	return 0;
+	return NETDEV_TX_OK;
 
 rx_drop:
 	kfree_skb(skb);
 	rcv_stats->rx_dropped++;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index 934f767..1fd7058 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -408,7 +408,8 @@ static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  rhine_open(struct net_device *dev);
 static void rhine_tx_timeout(struct net_device *dev);
-static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
+				  struct net_device *dev);
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
 static void rhine_tx(struct net_device *dev);
 static int rhine_rx(struct net_device *dev, int limit);
@@ -1213,7 +1214,8 @@ static void rhine_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
+				  struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
@@ -1227,7 +1229,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
 	entry = rp->cur_tx % TX_RING_SIZE;
 
 	if (skb_padto(skb, ETH_ZLEN))
-		return 0;
+		return NETDEV_TX_OK;
 
 	rp->tx_skbuff[entry] = skb;
 
@@ -1239,7 +1241,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
 			dev_kfree_skb(skb);
 			rp->tx_skbuff[entry] = NULL;
 			dev->stats.tx_dropped++;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 
 		/* Padding is not copied and so must be redone. */
@@ -1287,7 +1289,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
 		       dev->name, rp->cur_tx-1, entry);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index cee08a1..e04e5be 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -61,9 +61,9 @@
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/wait.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/if.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/proc_fs.h>
 #include <linux/inetdevice.h>
 #include <linux/reboot.h>
@@ -81,7 +81,7 @@
 #include "via-velocity.h"
 
 
-static int velocity_nics = 0;
+static int velocity_nics;
 static int msglevel = MSG_LEVEL_INFO;
 
 /**
@@ -92,8 +92,7 @@ static int msglevel = MSG_LEVEL_INFO;
  *	Fetch the mask bits of the selected CAM and store them into the
  *	provided mask buffer.
  */
-
-static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+static void mac_get_cam_mask(struct mac_regs __iomem *regs, u8 *mask)
 {
 	int i;
 
@@ -111,7 +110,6 @@ static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
 
 	/* Select mar */
 	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-
 }
 
 
@@ -122,8 +120,7 @@ static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
  *
  *	Store a new mask into a CAM
  */
-
-static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+static void mac_set_cam_mask(struct mac_regs __iomem *regs, u8 *mask)
 {
 	int i;
 	/* Select CAM mask */
@@ -131,9 +128,9 @@ static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
 
 	writeb(CAMADDR_CAMEN, &regs->CAMADDR);
 
-	for (i = 0; i < 8; i++) {
+	for (i = 0; i < 8; i++)
 		writeb(*mask++, &(regs->MARCAM[i]));
-	}
+
 	/* disable CAMEN */
 	writeb(0, &regs->CAMADDR);
 
@@ -141,7 +138,7 @@ static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
 	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
 }
 
-static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+static void mac_set_vlan_cam_mask(struct mac_regs __iomem *regs, u8 *mask)
 {
 	int i;
 	/* Select CAM mask */
@@ -149,9 +146,9 @@ static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
 
 	writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
 
-	for (i = 0; i < 8; i++) {
+	for (i = 0; i < 8; i++)
 		writeb(*mask++, &(regs->MARCAM[i]));
-	}
+
 	/* disable CAMEN */
 	writeb(0, &regs->CAMADDR);
 
@@ -167,8 +164,7 @@ static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
  *
  *	Load an address or vlan tag into a CAM
  */
-
-static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
+static void mac_set_cam(struct mac_regs __iomem *regs, int idx, const u8 *addr)
 {
 	int i;
 
@@ -179,9 +175,9 @@ static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
 
 	writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
 
-	for (i = 0; i < 6; i++) {
+	for (i = 0; i < 6; i++)
 		writeb(*addr++, &(regs->MARCAM[i]));
-	}
+
 	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
 
 	udelay(10);
@@ -192,7 +188,7 @@ static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
 	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
 }
 
-static void mac_set_vlan_cam(struct mac_regs __iomem * regs, int idx,
+static void mac_set_vlan_cam(struct mac_regs __iomem *regs, int idx,
 			     const u8 *addr)
 {
 
@@ -223,8 +219,7 @@ static void mac_set_vlan_cam(struct mac_regs __iomem * regs, int idx,
  *	reset the Wake on lan features. This function doesn't restore
  *	the rest of the logic from the result of sleep/wakeup
  */
-
-static void mac_wol_reset(struct mac_regs __iomem * regs)
+static void mac_wol_reset(struct mac_regs __iomem *regs)
 {
 
 	/* Turn off SWPTAG right after leaving power mode */
@@ -242,7 +237,6 @@ static void mac_wol_reset(struct mac_regs __iomem * regs)
 	writew(0xFFFF, &regs->WOLSRClr);
 }
 
-static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static const struct ethtool_ops velocity_ethtool_ops;
 
 /*
@@ -253,10 +247,10 @@ MODULE_AUTHOR("VIA Networking Technologies, Inc.");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver");
 
-#define VELOCITY_PARAM(N,D) \
-        static int N[MAX_UNITS]=OPTION_DEFAULT;\
+#define VELOCITY_PARAM(N, D) \
+	static int N[MAX_UNITS] = OPTION_DEFAULT;\
 	module_param_array(N, int, NULL, 0); \
-        MODULE_PARM_DESC(N, D);
+	MODULE_PARM_DESC(N, D);
 
 #define RX_DESC_MIN     64
 #define RX_DESC_MAX     255
@@ -336,8 +330,8 @@ VELOCITY_PARAM(flow_control, "Enable flow control ability");
    4: indicate 10Mbps full duplex mode
 
    Note:
-        if EEPROM have been set to the force mode, this option is ignored
-            by driver.
+   if EEPROM have been set to the force mode, this option is ignored
+   by driver.
 */
 VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode");
 
@@ -370,76 +364,14 @@ static int rx_copybreak = 200;
 module_param(rx_copybreak, int, 0644);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 
-static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr,
-			       const struct velocity_info_tbl *info);
-static int velocity_get_pci_info(struct velocity_info *, struct pci_dev *pdev);
-static void velocity_print_info(struct velocity_info *vptr);
-static int velocity_open(struct net_device *dev);
-static int velocity_change_mtu(struct net_device *dev, int mtu);
-static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t velocity_intr(int irq, void *dev_instance);
-static void velocity_set_multi(struct net_device *dev);
-static struct net_device_stats *velocity_get_stats(struct net_device *dev);
-static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int velocity_close(struct net_device *dev);
-static int velocity_receive_frame(struct velocity_info *, int idx);
-static int velocity_alloc_rx_buf(struct velocity_info *, int idx);
-static void velocity_free_rd_ring(struct velocity_info *vptr);
-static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *);
-static int velocity_soft_reset(struct velocity_info *vptr);
-static void mii_init(struct velocity_info *vptr, u32 mii_status);
-static u32 velocity_get_link(struct net_device *dev);
-static u32 velocity_get_opt_media_mode(struct velocity_info *vptr);
-static void velocity_print_link_status(struct velocity_info *vptr);
-static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs);
-static void velocity_shutdown(struct velocity_info *vptr);
-static void enable_flow_control_ability(struct velocity_info *vptr);
-static void enable_mii_autopoll(struct mac_regs __iomem * regs);
-static int velocity_mii_read(struct mac_regs __iomem *, u8 byIdx, u16 * pdata);
-static int velocity_mii_write(struct mac_regs __iomem *, u8 byMiiAddr, u16 data);
-static u32 mii_check_media_mode(struct mac_regs __iomem * regs);
-static u32 check_connection_type(struct mac_regs __iomem * regs);
-static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status);
-
 #ifdef CONFIG_PM
-
-static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
-static int velocity_resume(struct pci_dev *pdev);
-
 static DEFINE_SPINLOCK(velocity_dev_list_lock);
 static LIST_HEAD(velocity_dev_list);
-
-#endif
-
-#if defined(CONFIG_PM) && defined(CONFIG_INET)
-
-static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
-
-static struct notifier_block velocity_inetaddr_notifier = {
-      .notifier_call	= velocity_netdev_event,
-};
-
-static void velocity_register_notifier(void)
-{
-	register_inetaddr_notifier(&velocity_inetaddr_notifier);
-}
-
-static void velocity_unregister_notifier(void)
-{
-	unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
-}
-
-#else
-
-#define velocity_register_notifier()	do {} while (0)
-#define velocity_unregister_notifier()	do {} while (0)
-
 #endif
 
 /*
  *	Internal board variants. At the moment we have only one
  */
-
 static struct velocity_info_tbl chip_info_table[] = {
 	{CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 1, 0x00FFFFFFUL},
 	{ }
@@ -449,7 +381,6 @@ static struct velocity_info_tbl chip_info_table[] = {
  *	Describe the PCI device identifiers that we support in this
  *	device driver. Used for hotplug autoloading.
  */
-
 static const struct pci_device_id velocity_id_table[] __devinitdata = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) },
 	{ }
@@ -464,7 +395,6 @@ MODULE_DEVICE_TABLE(pci, velocity_id_table);
  *	Given a chip identifier return a suitable description. Returns
  *	a pointer a static string valid while the driver is loaded.
  */
-
 static const char __devinit *get_chip_name(enum chip_type chip_id)
 {
 	int i;
@@ -482,7 +412,6 @@ static const char __devinit *get_chip_name(enum chip_type chip_id)
  *	unload for each active device that is present. Disconnects
  *	the device from the network layer and frees all the resources
  */
-
 static void __devexit velocity_remove1(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
@@ -520,7 +449,6 @@ static void __devexit velocity_remove1(struct pci_dev *pdev)
  *	all the verification and checking as well as reporting so that
  *	we don't duplicate code for each option.
  */
-
 static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, const char *devname)
 {
 	if (val == -1)
@@ -549,8 +477,7 @@ static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max,
  *	all the verification and checking as well as reporting so that
  *	we don't duplicate code for each option.
  */
-
-static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag, char *name, const char *devname)
+static void __devinit velocity_set_bool_opt(u32 *opt, int val, int def, u32 flag, char *name, const char *devname)
 {
 	(*opt) &= (~flag);
 	if (val == -1)
@@ -575,7 +502,6 @@ static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 fla
  *	Turn the module and command options into a single structure
  *	for the current device
  */
-
 static void __devinit velocity_get_options(struct velocity_opt *opts, int index, const char *devname)
 {
 
@@ -601,10 +527,9 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index,
  *	Initialize the content addressable memory used for filters. Load
  *	appropriately according to the presence of VLAN
  */
-
 static void velocity_init_cam_filter(struct velocity_info *vptr)
 {
-	struct mac_regs __iomem * regs = vptr->mac_regs;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
 
 	/* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
 	WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
@@ -647,19 +572,19 @@ static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 
-        spin_lock_irq(&vptr->lock);
+	spin_lock_irq(&vptr->lock);
 	velocity_init_cam_filter(vptr);
-        spin_unlock_irq(&vptr->lock);
+	spin_unlock_irq(&vptr->lock);
 }
 
 static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 
-        spin_lock_irq(&vptr->lock);
+	spin_lock_irq(&vptr->lock);
 	vlan_group_set_device(vptr->vlgrp, vid, NULL);
 	velocity_init_cam_filter(vptr);
-        spin_unlock_irq(&vptr->lock);
+	spin_unlock_irq(&vptr->lock);
 }
 
 static void velocity_init_rx_ring_indexes(struct velocity_info *vptr)
@@ -674,11 +599,10 @@ static void velocity_init_rx_ring_indexes(struct velocity_info *vptr)
  *	Reset the ownership and status for the receive ring side.
  *	Hand all the receive queue to the NIC.
  */
-
 static void velocity_rx_reset(struct velocity_info *vptr)
 {
 
-	struct mac_regs __iomem * regs = vptr->mac_regs;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
 	int i;
 
 	velocity_init_rx_ring_indexes(vptr);
@@ -696,6 +620,647 @@ static void velocity_rx_reset(struct velocity_info *vptr)
 }
 
 /**
+ *	velocity_get_opt_media_mode	-	get media selection
+ *	@vptr: velocity adapter
+ *
+ *	Get the media mode stored in EEPROM or module options and load
+ *	mii_status accordingly. The requested link state information
+ *	is also returned.
+ */
+static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
+{
+	u32 status = 0;
+
+	switch (vptr->options.spd_dpx) {
+	case SPD_DPX_AUTO:
+		status = VELOCITY_AUTONEG_ENABLE;
+		break;
+	case SPD_DPX_100_FULL:
+		status = VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL;
+		break;
+	case SPD_DPX_10_FULL:
+		status = VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL;
+		break;
+	case SPD_DPX_100_HALF:
+		status = VELOCITY_SPEED_100;
+		break;
+	case SPD_DPX_10_HALF:
+		status = VELOCITY_SPEED_10;
+		break;
+	}
+	vptr->mii_status = status;
+	return status;
+}
+
+/**
+ *	safe_disable_mii_autopoll	-	autopoll off
+ *	@regs: velocity registers
+ *
+ *	Turn off the autopoll and wait for it to disable on the chip
+ */
+static void safe_disable_mii_autopoll(struct mac_regs __iomem *regs)
+{
+	u16 ww;
+
+	/*  turn off MAUTO */
+	writeb(0, &regs->MIICR);
+	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+		udelay(1);
+		if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
+			break;
+	}
+}
+
+/**
+ *	enable_mii_autopoll	-	turn on autopolling
+ *	@regs: velocity registers
+ *
+ *	Enable the MII link status autopoll feature on the Velocity
+ *	hardware. Wait for it to enable.
+ */
+static void enable_mii_autopoll(struct mac_regs __iomem *regs)
+{
+	int ii;
+
+	writeb(0, &(regs->MIICR));
+	writeb(MIIADR_SWMPL, &regs->MIIADR);
+
+	for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
+		udelay(1);
+		if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
+			break;
+	}
+
+	writeb(MIICR_MAUTO, &regs->MIICR);
+
+	for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
+		udelay(1);
+		if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
+			break;
+	}
+
+}
+
+/**
+ *	velocity_mii_read	-	read MII data
+ *	@regs: velocity registers
+ *	@index: MII register index
+ *	@data: buffer for received data
+ *
+ *	Perform a single read of an MII 16bit register. Returns zero
+ *	on success or -ETIMEDOUT if the PHY did not respond.
+ */
+static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
+{
+	u16 ww;
+
+	/*
+	 *	Disable MIICR_MAUTO, so that mii addr can be set normally
+	 */
+	safe_disable_mii_autopoll(regs);
+
+	writeb(index, &regs->MIIADR);
+
+	BYTE_REG_BITS_ON(MIICR_RCMD, &regs->MIICR);
+
+	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+		if (!(readb(&regs->MIICR) & MIICR_RCMD))
+			break;
+	}
+
+	*data = readw(&regs->MIIDATA);
+
+	enable_mii_autopoll(regs);
+	if (ww == W_MAX_TIMEOUT)
+		return -ETIMEDOUT;
+	return 0;
+}
+
+
+/**
+ *	mii_check_media_mode	-	check media state
+ *	@regs: velocity registers
+ *
+ *	Check the current MII status and determine the link status
+ *	accordingly
+ */
+static u32 mii_check_media_mode(struct mac_regs __iomem *regs)
+{
+	u32 status = 0;
+	u16 ANAR;
+
+	if (!MII_REG_BITS_IS_ON(BMSR_LNK, MII_REG_BMSR, regs))
+		status |= VELOCITY_LINK_FAIL;
+
+	if (MII_REG_BITS_IS_ON(G1000CR_1000FD, MII_REG_G1000CR, regs))
+		status |= VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
+	else if (MII_REG_BITS_IS_ON(G1000CR_1000, MII_REG_G1000CR, regs))
+		status |= (VELOCITY_SPEED_1000);
+	else {
+		velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
+		if (ANAR & ANAR_TXFD)
+			status |= (VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL);
+		else if (ANAR & ANAR_TX)
+			status |= VELOCITY_SPEED_100;
+		else if (ANAR & ANAR_10FD)
+			status |= (VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL);
+		else
+			status |= (VELOCITY_SPEED_10);
+	}
+
+	if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
+		velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
+		if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
+		    == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
+			if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs))
+				status |= VELOCITY_AUTONEG_ENABLE;
+		}
+	}
+
+	return status;
+}
+
+/**
+ *	velocity_mii_write	-	write MII data
+ *	@regs: velocity registers
+ *	@index: MII register index
+ *	@data: 16bit data for the MII register
+ *
+ *	Perform a single write to an MII 16bit register. Returns zero
+ *	on success or -ETIMEDOUT if the PHY did not respond.
+ */
+static int velocity_mii_write(struct mac_regs __iomem *regs, u8 mii_addr, u16 data)
+{
+	u16 ww;
+
+	/*
+	 *	Disable MIICR_MAUTO, so that mii addr can be set normally
+	 */
+	safe_disable_mii_autopoll(regs);
+
+	/* MII reg offset */
+	writeb(mii_addr, &regs->MIIADR);
+	/* set MII data */
+	writew(data, &regs->MIIDATA);
+
+	/* turn on MIICR_WCMD */
+	BYTE_REG_BITS_ON(MIICR_WCMD, &regs->MIICR);
+
+	/* W_MAX_TIMEOUT is the timeout period */
+	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
+		udelay(5);
+		if (!(readb(&regs->MIICR) & MIICR_WCMD))
+			break;
+	}
+	enable_mii_autopoll(regs);
+
+	if (ww == W_MAX_TIMEOUT)
+		return -ETIMEDOUT;
+	return 0;
+}
+
+/**
+ *	set_mii_flow_control	-	flow control setup
+ *	@vptr: velocity interface
+ *
+ *	Set up the flow control on this interface according to
+ *	the supplied user/eeprom options.
+ */
+static void set_mii_flow_control(struct velocity_info *vptr)
+{
+	/*Enable or Disable PAUSE in ANAR */
+	switch (vptr->options.flow_cntl) {
+	case FLOW_CNTL_TX:
+		MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+		MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+		break;
+
+	case FLOW_CNTL_RX:
+		MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+		MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+		break;
+
+	case FLOW_CNTL_TX_RX:
+		MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+		MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+		break;
+
+	case FLOW_CNTL_DISABLE:
+		MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
+		MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+		break;
+	default:
+		break;
+	}
+}
+
+/**
+ *	mii_set_auto_on		-	autonegotiate on
+ *	@vptr: velocity
+ *
+ *	Enable autonegotation on this interface
+ */
+static void mii_set_auto_on(struct velocity_info *vptr)
+{
+	if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
+		MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
+	else
+		MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
+}
+
+static u32 check_connection_type(struct mac_regs __iomem *regs)
+{
+	u32 status = 0;
+	u8 PHYSR0;
+	u16 ANAR;
+	PHYSR0 = readb(&regs->PHYSR0);
+
+	/*
+	   if (!(PHYSR0 & PHYSR0_LINKGD))
+	   status|=VELOCITY_LINK_FAIL;
+	 */
+
+	if (PHYSR0 & PHYSR0_FDPX)
+		status |= VELOCITY_DUPLEX_FULL;
+
+	if (PHYSR0 & PHYSR0_SPDG)
+		status |= VELOCITY_SPEED_1000;
+	else if (PHYSR0 & PHYSR0_SPD10)
+		status |= VELOCITY_SPEED_10;
+	else
+		status |= VELOCITY_SPEED_100;
+
+	if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
+		velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
+		if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
+		    == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
+			if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs))
+				status |= VELOCITY_AUTONEG_ENABLE;
+		}
+	}
+
+	return status;
+}
+
+
+
+/**
+ *	velocity_set_media_mode		-	set media mode
+ *	@mii_status: old MII link state
+ *
+ *	Check the media link state and configure the flow control
+ *	PHY and also velocity hardware setup accordingly. In particular
+ *	we need to set up CD polling and frame bursting.
+ */
+static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
+{
+	u32 curr_status;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+
+	vptr->mii_status = mii_check_media_mode(vptr->mac_regs);
+	curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL);
+
+	/* Set mii link status */
+	set_mii_flow_control(vptr);
+
+	/*
+	   Check if new status is consisent with current status
+	   if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE)
+	   || (mii_status==curr_status)) {
+	   vptr->mii_status=mii_check_media_mode(vptr->mac_regs);
+	   vptr->mii_status=check_connection_type(vptr->mac_regs);
+	   VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n");
+	   return 0;
+	   }
+	 */
+
+	if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201)
+		MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs);
+
+	/*
+	 *	If connection type is AUTO
+	 */
+	if (mii_status & VELOCITY_AUTONEG_ENABLE) {
+		VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity is AUTO mode\n");
+		/* clear force MAC mode bit */
+		BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
+		/* set duplex mode of MAC according to duplex mode of MII */
+		MII_REG_BITS_ON(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10, MII_REG_ANAR, vptr->mac_regs);
+		MII_REG_BITS_ON(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
+		MII_REG_BITS_ON(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs);
+
+		/* enable AUTO-NEGO mode */
+		mii_set_auto_on(vptr);
+	} else {
+		u16 ANAR;
+		u8 CHIPGCR;
+
+		/*
+		 * 1. if it's 3119, disable frame bursting in halfduplex mode
+		 *    and enable it in fullduplex mode
+		 * 2. set correct MII/GMII and half/full duplex mode in CHIPGCR
+		 * 3. only enable CD heart beat counter in 10HD mode
+		 */
+
+		/* set force MAC mode bit */
+		BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
+
+		CHIPGCR = readb(&regs->CHIPGCR);
+		CHIPGCR &= ~CHIPGCR_FCGMII;
+
+		if (mii_status & VELOCITY_DUPLEX_FULL) {
+			CHIPGCR |= CHIPGCR_FCFDX;
+			writeb(CHIPGCR, &regs->CHIPGCR);
+			VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced full mode\n");
+			if (vptr->rev_id < REV_ID_VT3216_A0)
+				BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
+		} else {
+			CHIPGCR &= ~CHIPGCR_FCFDX;
+			VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced half mode\n");
+			writeb(CHIPGCR, &regs->CHIPGCR);
+			if (vptr->rev_id < REV_ID_VT3216_A0)
+				BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
+		}
+
+		MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
+
+		if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10))
+			BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
+		else
+			BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
+
+		/* MII_REG_BITS_OFF(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs); */
+		velocity_mii_read(vptr->mac_regs, MII_REG_ANAR, &ANAR);
+		ANAR &= (~(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10));
+		if (mii_status & VELOCITY_SPEED_100) {
+			if (mii_status & VELOCITY_DUPLEX_FULL)
+				ANAR |= ANAR_TXFD;
+			else
+				ANAR |= ANAR_TX;
+		} else {
+			if (mii_status & VELOCITY_DUPLEX_FULL)
+				ANAR |= ANAR_10FD;
+			else
+				ANAR |= ANAR_10;
+		}
+		velocity_mii_write(vptr->mac_regs, MII_REG_ANAR, ANAR);
+		/* enable AUTO-NEGO mode */
+		mii_set_auto_on(vptr);
+		/* MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs); */
+	}
+	/* vptr->mii_status=mii_check_media_mode(vptr->mac_regs); */
+	/* vptr->mii_status=check_connection_type(vptr->mac_regs); */
+	return VELOCITY_LINK_CHANGE;
+}
+
+/**
+ *	velocity_print_link_status	-	link status reporting
+ *	@vptr: velocity to report on
+ *
+ *	Turn the link status of the velocity card into a kernel log
+ *	description of the new link state, detailing speed and duplex
+ *	status
+ */
+static void velocity_print_link_status(struct velocity_info *vptr)
+{
+
+	if (vptr->mii_status & VELOCITY_LINK_FAIL) {
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
+	} else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
+
+		if (vptr->mii_status & VELOCITY_SPEED_1000)
+			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
+		else if (vptr->mii_status & VELOCITY_SPEED_100)
+			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps");
+		else
+			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps");
+
+		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+			VELOCITY_PRT(MSG_LEVEL_INFO, " full duplex\n");
+		else
+			VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n");
+	} else {
+		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name);
+		switch (vptr->options.spd_dpx) {
+		case SPD_DPX_100_HALF:
+			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n");
+			break;
+		case SPD_DPX_100_FULL:
+			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps full duplex\n");
+			break;
+		case SPD_DPX_10_HALF:
+			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps half duplex\n");
+			break;
+		case SPD_DPX_10_FULL:
+			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps full duplex\n");
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+/**
+ *	enable_flow_control_ability	-	flow control
+ *	@vptr: veloity to configure
+ *
+ *	Set up flow control according to the flow control options
+ *	determined by the eeprom/configuration.
+ */
+static void enable_flow_control_ability(struct velocity_info *vptr)
+{
+
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+
+	switch (vptr->options.flow_cntl) {
+
+	case FLOW_CNTL_DEFAULT:
+		if (BYTE_REG_BITS_IS_ON(PHYSR0_RXFLC, &regs->PHYSR0))
+			writel(CR0_FDXRFCEN, &regs->CR0Set);
+		else
+			writel(CR0_FDXRFCEN, &regs->CR0Clr);
+
+		if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, &regs->PHYSR0))
+			writel(CR0_FDXTFCEN, &regs->CR0Set);
+		else
+			writel(CR0_FDXTFCEN, &regs->CR0Clr);
+		break;
+
+	case FLOW_CNTL_TX:
+		writel(CR0_FDXTFCEN, &regs->CR0Set);
+		writel(CR0_FDXRFCEN, &regs->CR0Clr);
+		break;
+
+	case FLOW_CNTL_RX:
+		writel(CR0_FDXRFCEN, &regs->CR0Set);
+		writel(CR0_FDXTFCEN, &regs->CR0Clr);
+		break;
+
+	case FLOW_CNTL_TX_RX:
+		writel(CR0_FDXTFCEN, &regs->CR0Set);
+		writel(CR0_FDXRFCEN, &regs->CR0Set);
+		break;
+
+	case FLOW_CNTL_DISABLE:
+		writel(CR0_FDXRFCEN, &regs->CR0Clr);
+		writel(CR0_FDXTFCEN, &regs->CR0Clr);
+		break;
+
+	default:
+		break;
+	}
+
+}
+
+/**
+ *	velocity_soft_reset	-	soft reset
+ *	@vptr: velocity to reset
+ *
+ *	Kick off a soft reset of the velocity adapter and then poll
+ *	until the reset sequence has completed before returning.
+ */
+static int velocity_soft_reset(struct velocity_info *vptr)
+{
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	int i = 0;
+
+	writel(CR0_SFRST, &regs->CR0Set);
+
+	for (i = 0; i < W_MAX_TIMEOUT; i++) {
+		udelay(5);
+		if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, &regs->CR0Set))
+			break;
+	}
+
+	if (i == W_MAX_TIMEOUT) {
+		writel(CR0_FORSRST, &regs->CR0Set);
+		/* FIXME: PCI POSTING */
+		/* delay 2ms */
+		mdelay(2);
+	}
+	return 0;
+}
+
+/**
+ *	velocity_set_multi	-	filter list change callback
+ *	@dev: network device
+ *
+ *	Called by the network layer when the filter lists need to change
+ *	for a velocity adapter. Reload the CAMs with the new address
+ *	filter ruleset.
+ */
+static void velocity_set_multi(struct net_device *dev)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	u8 rx_mode;
+	int i;
+	struct dev_mc_list *mclist;
+
+	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
+		writel(0xffffffff, &regs->MARCAM[0]);
+		writel(0xffffffff, &regs->MARCAM[4]);
+		rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
+	} else if ((dev->mc_count > vptr->multicast_limit)
+		   || (dev->flags & IFF_ALLMULTI)) {
+		writel(0xffffffff, &regs->MARCAM[0]);
+		writel(0xffffffff, &regs->MARCAM[4]);
+		rx_mode = (RCR_AM | RCR_AB);
+	} else {
+		int offset = MCAM_SIZE - vptr->multicast_limit;
+		mac_get_cam_mask(regs, vptr->mCAMmask);
+
+		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+			mac_set_cam(regs, i + offset, mclist->dmi_addr);
+			vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
+		}
+
+		mac_set_cam_mask(regs, vptr->mCAMmask);
+		rx_mode = RCR_AM | RCR_AB | RCR_AP;
+	}
+	if (dev->mtu > 1500)
+		rx_mode |= RCR_AL;
+
+	BYTE_REG_BITS_ON(rx_mode, &regs->RCR);
+
+}
+
+/*
+ * MII access , media link mode setting functions
+ */
+
+/**
+ *	mii_init	-	set up MII
+ *	@vptr: velocity adapter
+ *	@mii_status:  links tatus
+ *
+ *	Set up the PHY for the current link state.
+ */
+static void mii_init(struct velocity_info *vptr, u32 mii_status)
+{
+	u16 BMCR;
+
+	switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
+	case PHYID_CICADA_CS8201:
+		/*
+		 *	Reset to hardware default
+		 */
+		MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+		/*
+		 *	Turn on ECHODIS bit in NWay-forced full mode and turn it
+		 *	off it in NWay-forced half mode for NWay-forced v.s.
+		 *	legacy-forced issue.
+		 */
+		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+			MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+		else
+			MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+		/*
+		 *	Turn on Link/Activity LED enable bit for CIS8201
+		 */
+		MII_REG_BITS_ON(PLED_LALBE, MII_REG_PLED, vptr->mac_regs);
+		break;
+	case PHYID_VT3216_32BIT:
+	case PHYID_VT3216_64BIT:
+		/*
+		 *	Reset to hardware default
+		 */
+		MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+		/*
+		 *	Turn on ECHODIS bit in NWay-forced full mode and turn it
+		 *	off it in NWay-forced half mode for NWay-forced v.s.
+		 *	legacy-forced issue
+		 */
+		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+			MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+		else
+			MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
+		break;
+
+	case PHYID_MARVELL_1000:
+	case PHYID_MARVELL_1000S:
+		/*
+		 *	Assert CRS on Transmit
+		 */
+		MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
+		/*
+		 *	Reset to hardware default
+		 */
+		MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
+		break;
+	default:
+		;
+	}
+	velocity_mii_read(vptr->mac_regs, MII_REG_BMCR, &BMCR);
+	if (BMCR & BMCR_ISO) {
+		BMCR &= ~BMCR_ISO;
+		velocity_mii_write(vptr->mac_regs, MII_REG_BMCR, BMCR);
+	}
+}
+
+
+/**
  *	velocity_init_registers	-	initialise MAC registers
  *	@vptr: velocity to init
  *	@type: type of initialisation (hot or cold)
@@ -703,11 +1268,10 @@ static void velocity_rx_reset(struct velocity_info *vptr)
  *	Initialise the MAC on a reset or on first set up on the
  *	hardware.
  */
-
 static void velocity_init_registers(struct velocity_info *vptr,
 				    enum velocity_init_type type)
 {
-	struct mac_regs __iomem * regs = vptr->mac_regs;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
 	int i, mii_status;
 
 	mac_wol_reset(regs);
@@ -750,9 +1314,9 @@ static void velocity_init_registers(struct velocity_info *vptr,
 		mdelay(5);
 
 		mac_eeprom_reload(regs);
-		for (i = 0; i < 6; i++) {
+		for (i = 0; i < 6; i++)
 			writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
-		}
+
 		/*
 		 *	clear Pre_ACPI bit.
 		 */
@@ -819,291 +1383,29 @@ static void velocity_init_registers(struct velocity_info *vptr,
 	}
 }
 
-/**
- *	velocity_soft_reset	-	soft reset
- *	@vptr: velocity to reset
- *
- *	Kick off a soft reset of the velocity adapter and then poll
- *	until the reset sequence has completed before returning.
- */
-
-static int velocity_soft_reset(struct velocity_info *vptr)
-{
-	struct mac_regs __iomem * regs = vptr->mac_regs;
-	int i = 0;
-
-	writel(CR0_SFRST, &regs->CR0Set);
-
-	for (i = 0; i < W_MAX_TIMEOUT; i++) {
-		udelay(5);
-		if (!DWORD_REG_BITS_IS_ON(CR0_SFRST, &regs->CR0Set))
-			break;
-	}
-
-	if (i == W_MAX_TIMEOUT) {
-		writel(CR0_FORSRST, &regs->CR0Set);
-		/* FIXME: PCI POSTING */
-		/* delay 2ms */
-		mdelay(2);
-	}
-	return 0;
-}
-
-static const struct net_device_ops velocity_netdev_ops = {
-	.ndo_open		= velocity_open,
-	.ndo_stop		= velocity_close,
-	.ndo_start_xmit		= velocity_xmit,
-	.ndo_get_stats		= velocity_get_stats,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_set_multicast_list	= velocity_set_multi,
-	.ndo_change_mtu		= velocity_change_mtu,
-	.ndo_do_ioctl		= velocity_ioctl,
-	.ndo_vlan_rx_add_vid	= velocity_vlan_rx_add_vid,
-	.ndo_vlan_rx_kill_vid	= velocity_vlan_rx_kill_vid,
-	.ndo_vlan_rx_register	= velocity_vlan_rx_register,
-};
-
-/**
- *	velocity_found1		-	set up discovered velocity card
- *	@pdev: PCI device
- *	@ent: PCI device table entry that matched
- *
- *	Configure a discovered adapter from scratch. Return a negative
- *	errno error code on failure paths.
- */
-
-static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_device_id *ent)
+static void velocity_give_many_rx_descs(struct velocity_info *vptr)
 {
-	static int first = 1;
-	struct net_device *dev;
-	int i;
-	const char *drv_string;
-	const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data];
-	struct velocity_info *vptr;
-	struct mac_regs __iomem * regs;
-	int ret = -ENOMEM;
-
-	/* FIXME: this driver, like almost all other ethernet drivers,
-	 * can support more than MAX_UNITS.
-	 */
-	if (velocity_nics >= MAX_UNITS) {
-		dev_notice(&pdev->dev, "already found %d NICs.\n",
-			   velocity_nics);
-		return -ENODEV;
-	}
-
-	dev = alloc_etherdev(sizeof(struct velocity_info));
-	if (!dev) {
-		dev_err(&pdev->dev, "allocate net device failed.\n");
-		goto out;
-	}
-
-	/* Chain it all together */
-
-	SET_NETDEV_DEV(dev, &pdev->dev);
-	vptr = netdev_priv(dev);
-
-
-	if (first) {
-		printk(KERN_INFO "%s Ver. %s\n",
-			VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
-		printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
-		printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
-		first = 0;
-	}
-
-	velocity_init_info(pdev, vptr, info);
-
-	vptr->dev = dev;
-
-	dev->irq = pdev->irq;
-
-	ret = pci_enable_device(pdev);
-	if (ret < 0)
-		goto err_free_dev;
-
-	ret = velocity_get_pci_info(vptr, pdev);
-	if (ret < 0) {
-		/* error message already printed */
-		goto err_disable;
-	}
-
-	ret = pci_request_regions(pdev, VELOCITY_NAME);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "No PCI resources.\n");
-		goto err_disable;
-	}
-
-	regs = ioremap(vptr->memaddr, VELOCITY_IO_SIZE);
-	if (regs == NULL) {
-		ret = -EIO;
-		goto err_release_res;
-	}
-
-	vptr->mac_regs = regs;
-
-	mac_wol_reset(regs);
-
-	dev->base_addr = vptr->ioaddr;
-
-	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(&regs->PAR[i]);
-
-
-	drv_string = dev_driver_string(&pdev->dev);
-
-	velocity_get_options(&vptr->options, velocity_nics, drv_string);
-
-	/*
-	 *	Mask out the options cannot be set to the chip
-	 */
-
-	vptr->options.flags &= info->flags;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	int avail, dirty, unusable;
 
 	/*
-	 *	Enable the chip specified capbilities
+	 * RD number must be equal to 4X per hardware spec
+	 * (programming guide rev 1.20, p.13)
 	 */
+	if (vptr->rx.filled < 4)
+		return;
 
-	vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
-
-	vptr->wol_opts = vptr->options.wol_opts;
-	vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
-
-	vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
-
-	dev->irq = pdev->irq;
-	dev->netdev_ops = &velocity_netdev_ops;
-	dev->ethtool_ops = &velocity_ethtool_ops;
-
-#ifdef  VELOCITY_ZERO_COPY_SUPPORT
-	dev->features |= NETIF_F_SG;
-#endif
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
-		NETIF_F_HW_VLAN_RX;
-
-	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-		dev->features |= NETIF_F_IP_CSUM;
-
-	ret = register_netdev(dev);
-	if (ret < 0)
-		goto err_iounmap;
-
-	if (!velocity_get_link(dev)) {
-		netif_carrier_off(dev);
-		vptr->mii_status |= VELOCITY_LINK_FAIL;
-	}
-
-	velocity_print_info(vptr);
-	pci_set_drvdata(pdev, dev);
-
-	/* and leave the chip powered down */
-
-	pci_set_power_state(pdev, PCI_D3hot);
-#ifdef CONFIG_PM
-	{
-		unsigned long flags;
-
-		spin_lock_irqsave(&velocity_dev_list_lock, flags);
-		list_add(&vptr->list, &velocity_dev_list);
-		spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
-	}
-#endif
-	velocity_nics++;
-out:
-	return ret;
-
-err_iounmap:
-	iounmap(regs);
-err_release_res:
-	pci_release_regions(pdev);
-err_disable:
-	pci_disable_device(pdev);
-err_free_dev:
-	free_netdev(dev);
-	goto out;
-}
-
-/**
- *	velocity_print_info	-	per driver data
- *	@vptr: velocity
- *
- *	Print per driver data as the kernel driver finds Velocity
- *	hardware
- */
-
-static void __devinit velocity_print_info(struct velocity_info *vptr)
-{
-	struct net_device *dev = vptr->dev;
-
-	printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
-	printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-		dev->name,
-		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-}
-
-/**
- *	velocity_init_info	-	init private data
- *	@pdev: PCI device
- *	@vptr: Velocity info
- *	@info: Board type
- *
- *	Set up the initial velocity_info struct for the device that has been
- *	discovered.
- */
-
-static void __devinit velocity_init_info(struct pci_dev *pdev,
-					 struct velocity_info *vptr,
-					 const struct velocity_info_tbl *info)
-{
-	memset(vptr, 0, sizeof(struct velocity_info));
-
-	vptr->pdev = pdev;
-	vptr->chip_id = info->chip_id;
-	vptr->tx.numq = info->txqueue;
-	vptr->multicast_limit = MCAM_SIZE;
-	spin_lock_init(&vptr->lock);
-	INIT_LIST_HEAD(&vptr->list);
-}
-
-/**
- *	velocity_get_pci_info	-	retrieve PCI info for device
- *	@vptr: velocity device
- *	@pdev: PCI device it matches
- *
- *	Retrieve the PCI configuration space data that interests us from
- *	the kernel PCI layer
- */
-
-static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
-{
-	vptr->rev_id = pdev->revision;
-
-	pci_set_master(pdev);
-
-	vptr->ioaddr = pci_resource_start(pdev, 0);
-	vptr->memaddr = pci_resource_start(pdev, 1);
-
-	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
-		dev_err(&pdev->dev,
-			   "region #0 is not an I/O resource, aborting.\n");
-		return -EINVAL;
-	}
-
-	if ((pci_resource_flags(pdev, 1) & IORESOURCE_IO)) {
-		dev_err(&pdev->dev,
-			   "region #1 is an I/O resource, aborting.\n");
-		return -EINVAL;
-	}
+	wmb();
 
-	if (pci_resource_len(pdev, 1) < VELOCITY_IO_SIZE) {
-		dev_err(&pdev->dev, "region #1 is too small.\n");
-		return -EINVAL;
+	unusable = vptr->rx.filled & 0x0003;
+	dirty = vptr->rx.dirty - unusable;
+	for (avail = vptr->rx.filled & 0xfffc; avail; avail--) {
+		dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
+		vptr->rx.ring[dirty].rdesc0.len |= OWNED_BY_NIC;
 	}
-	vptr->pdev = pdev;
 
-	return 0;
+	writew(vptr->rx.filled & 0xfffc, &regs->RBRDU);
+	vptr->rx.filled = unusable;
 }
 
 /**
@@ -1113,7 +1415,6 @@ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pc
  *	Allocate PCI mapped DMA rings for the receive and transmit layer
  *	to use.
  */
-
 static int velocity_init_dma_rings(struct velocity_info *vptr)
 {
 	struct velocity_opt *opt = &vptr->options;
@@ -1154,46 +1455,50 @@ static int velocity_init_dma_rings(struct velocity_info *vptr)
 	return 0;
 }
 
+static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu)
+{
+	vptr->rx.buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
+}
+
 /**
- *	velocity_free_dma_rings	-	free PCI ring pointers
- *	@vptr: Velocity to free from
+ *	velocity_alloc_rx_buf	-	allocate aligned receive buffer
+ *	@vptr: velocity
+ *	@idx: ring index
  *
- *	Clean up the PCI ring buffers allocated to this velocity.
+ *	Allocate a new full sized buffer for the reception of a frame and
+ *	map it into PCI space for the hardware to use. The hardware
+ *	requires *64* byte alignment of the buffer which makes life
+ *	less fun than would be ideal.
  */
-
-static void velocity_free_dma_rings(struct velocity_info *vptr)
+static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
 {
-	const int size = vptr->options.numrx * sizeof(struct rx_desc) +
-		vptr->options.numtx * sizeof(struct tx_desc) * vptr->tx.numq;
-
-	pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
-}
+	struct rx_desc *rd = &(vptr->rx.ring[idx]);
+	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 
-static void velocity_give_many_rx_descs(struct velocity_info *vptr)
-{
-	struct mac_regs __iomem *regs = vptr->mac_regs;
-	int avail, dirty, unusable;
+	rd_info->skb = dev_alloc_skb(vptr->rx.buf_sz + 64);
+	if (rd_info->skb == NULL)
+		return -ENOMEM;
 
 	/*
-	 * RD number must be equal to 4X per hardware spec
-	 * (programming guide rev 1.20, p.13)
+	 *	Do the gymnastics to get the buffer head for data at
+	 *	64byte alignment.
 	 */
-	if (vptr->rx.filled < 4)
-		return;
-
-	wmb();
+	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
+	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data,
+					vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
 
-	unusable = vptr->rx.filled & 0x0003;
-	dirty = vptr->rx.dirty - unusable;
-	for (avail = vptr->rx.filled & 0xfffc; avail; avail--) {
-		dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
-		vptr->rx.ring[dirty].rdesc0.len |= OWNED_BY_NIC;
-	}
+	/*
+	 *	Fill in the descriptor to match
+	 */
 
-	writew(vptr->rx.filled & 0xfffc, &regs->RBRDU);
-	vptr->rx.filled = unusable;
+	*((u32 *) & (rd->rdesc0)) = 0;
+	rd->size = cpu_to_le16(vptr->rx.buf_sz) | RX_INTEN;
+	rd->pa_low = cpu_to_le32(rd_info->skb_dma);
+	rd->pa_high = 0;
+	return 0;
 }
 
+
 static int velocity_rx_refill(struct velocity_info *vptr)
 {
 	int dirty = vptr->rx.dirty, done = 0;
@@ -1221,42 +1526,6 @@ static int velocity_rx_refill(struct velocity_info *vptr)
 	return done;
 }
 
-static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu)
-{
-	vptr->rx.buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
-}
-
-/**
- *	velocity_init_rd_ring	-	set up receive ring
- *	@vptr: velocity to configure
- *
- *	Allocate and set up the receive buffers for each ring slot and
- *	assign them to the network adapter.
- */
-
-static int velocity_init_rd_ring(struct velocity_info *vptr)
-{
-	int ret = -ENOMEM;
-
-	vptr->rx.info = kcalloc(vptr->options.numrx,
-				sizeof(struct velocity_rd_info), GFP_KERNEL);
-	if (!vptr->rx.info)
-		goto out;
-
-	velocity_init_rx_ring_indexes(vptr);
-
-	if (velocity_rx_refill(vptr) != vptr->options.numrx) {
-		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
-			"%s: failed to allocate RX buffer.\n", vptr->dev->name);
-		velocity_free_rd_ring(vptr);
-		goto out;
-	}
-
-	ret = 0;
-out:
-	return ret;
-}
-
 /**
  *	velocity_free_rd_ring	-	free receive ring
  *	@vptr: velocity to clean up
@@ -1264,7 +1533,6 @@ out:
  *	Free the receive buffers for each ring slot and any
  *	attached socket buffers that need to go away.
  */
-
 static void velocity_free_rd_ring(struct velocity_info *vptr)
 {
 	int i;
@@ -1292,6 +1560,38 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
 	vptr->rx.info = NULL;
 }
 
+
+
+/**
+ *	velocity_init_rd_ring	-	set up receive ring
+ *	@vptr: velocity to configure
+ *
+ *	Allocate and set up the receive buffers for each ring slot and
+ *	assign them to the network adapter.
+ */
+static int velocity_init_rd_ring(struct velocity_info *vptr)
+{
+	int ret = -ENOMEM;
+
+	vptr->rx.info = kcalloc(vptr->options.numrx,
+				sizeof(struct velocity_rd_info), GFP_KERNEL);
+	if (!vptr->rx.info)
+		goto out;
+
+	velocity_init_rx_ring_indexes(vptr);
+
+	if (velocity_rx_refill(vptr) != vptr->options.numrx) {
+		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
+			"%s: failed to allocate RX buffer.\n", vptr->dev->name);
+		velocity_free_rd_ring(vptr);
+		goto out;
+	}
+
+	ret = 0;
+out:
+	return ret;
+}
+
 /**
  *	velocity_init_td_ring	-	set up transmit ring
  *	@vptr:	velocity
@@ -1300,7 +1600,6 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
  *	Returns zero on success or a negative posix errno code for
  *	failure.
  */
-
 static int velocity_init_td_ring(struct velocity_info *vptr)
 {
 	dma_addr_t curr;
@@ -1314,7 +1613,7 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
 					    sizeof(struct velocity_td_info),
 					    GFP_KERNEL);
 		if (!vptr->tx.infos[j])	{
-			while(--j >= 0)
+			while (--j >= 0)
 				kfree(vptr->tx.infos[j]);
 			return -ENOMEM;
 		}
@@ -1324,22 +1623,92 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
 	return 0;
 }
 
+/**
+ *	velocity_free_dma_rings	-	free PCI ring pointers
+ *	@vptr: Velocity to free from
+ *
+ *	Clean up the PCI ring buffers allocated to this velocity.
+ */
+static void velocity_free_dma_rings(struct velocity_info *vptr)
+{
+	const int size = vptr->options.numrx * sizeof(struct rx_desc) +
+		vptr->options.numtx * sizeof(struct tx_desc) * vptr->tx.numq;
+
+	pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
+}
+
+
+static int velocity_init_rings(struct velocity_info *vptr, int mtu)
+{
+	int ret;
+
+	velocity_set_rxbufsize(vptr, mtu);
+
+	ret = velocity_init_dma_rings(vptr);
+	if (ret < 0)
+		goto out;
+
+	ret = velocity_init_rd_ring(vptr);
+	if (ret < 0)
+		goto err_free_dma_rings_0;
+
+	ret = velocity_init_td_ring(vptr);
+	if (ret < 0)
+		goto err_free_rd_ring_1;
+out:
+	return ret;
+
+err_free_rd_ring_1:
+	velocity_free_rd_ring(vptr);
+err_free_dma_rings_0:
+	velocity_free_dma_rings(vptr);
+	goto out;
+}
+
+/**
+ *	velocity_free_tx_buf	-	free transmit buffer
+ *	@vptr: velocity
+ *	@tdinfo: buffer
+ *
+ *	Release an transmit buffer. If the buffer was preallocated then
+ *	recycle it, if not then unmap the buffer.
+ */
+static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
+{
+	struct sk_buff *skb = tdinfo->skb;
+	int i;
+	int pktlen;
+
+	/*
+	 *	Don't unmap the pre-allocated tx_bufs
+	 */
+	if (tdinfo->skb_dma) {
+
+		pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
+		for (i = 0; i < tdinfo->nskb_dma; i++) {
+			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], pktlen, PCI_DMA_TODEVICE);
+			tdinfo->skb_dma[i] = 0;
+		}
+	}
+	dev_kfree_skb_irq(skb);
+	tdinfo->skb = NULL;
+}
+
+
 /*
  *	FIXME: could we merge this with velocity_free_tx_buf ?
  */
-
 static void velocity_free_td_ring_entry(struct velocity_info *vptr,
 							 int q, int n)
 {
-	struct velocity_td_info * td_info = &(vptr->tx.infos[q][n]);
+	struct velocity_td_info *td_info = &(vptr->tx.infos[q][n]);
 	int i;
 
 	if (td_info == NULL)
 		return;
 
 	if (td_info->skb) {
-		for (i = 0; i < td_info->nskb_dma; i++)
-		{
+		for (i = 0; i < td_info->nskb_dma; i++) {
 			if (td_info->skb_dma[i]) {
 				pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
 					td_info->skb->len, PCI_DMA_TODEVICE);
@@ -1358,7 +1727,6 @@ static void velocity_free_td_ring_entry(struct velocity_info *vptr,
  *	Free up the transmit ring for this particular velocity adapter.
  *	We free the ring contents but not the ring itself.
  */
-
 static void velocity_free_td_ring(struct velocity_info *vptr)
 {
 	int i, j;
@@ -1366,70 +1734,175 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
 	for (j = 0; j < vptr->tx.numq; j++) {
 		if (vptr->tx.infos[j] == NULL)
 			continue;
-		for (i = 0; i < vptr->options.numtx; i++) {
+		for (i = 0; i < vptr->options.numtx; i++)
 			velocity_free_td_ring_entry(vptr, j, i);
 
-		}
 		kfree(vptr->tx.infos[j]);
 		vptr->tx.infos[j] = NULL;
 	}
 }
 
+
+static void velocity_free_rings(struct velocity_info *vptr)
+{
+	velocity_free_td_ring(vptr);
+	velocity_free_rd_ring(vptr);
+	velocity_free_dma_rings(vptr);
+}
+
 /**
- *	velocity_rx_srv		-	service RX interrupt
+ *	velocity_error	-	handle error from controller
  *	@vptr: velocity
- *	@status: adapter status (unused)
+ *	@status: card status
+ *
+ *	Process an error report from the hardware and attempt to recover
+ *	the card itself. At the moment we cannot recover from some
+ *	theoretically impossible errors but this could be fixed using
+ *	the pci_device_failed logic to bounce the hardware
  *
- *	Walk the receive ring of the velocity adapter and remove
- *	any received packets from the receive queue. Hand the ring
- *	slots back to the adapter for reuse.
  */
-
-static int velocity_rx_srv(struct velocity_info *vptr, int status)
+static void velocity_error(struct velocity_info *vptr, int status)
 {
-	struct net_device_stats *stats = &vptr->dev->stats;
-	int rd_curr = vptr->rx.curr;
-	int works = 0;
 
-	do {
-		struct rx_desc *rd = vptr->rx.ring + rd_curr;
+	if (status & ISR_TXSTLI) {
+		struct mac_regs __iomem *regs = vptr->mac_regs;
 
-		if (!vptr->rx.info[rd_curr].skb)
-			break;
+		printk(KERN_ERR "TD structure error TDindex=%hx\n", readw(&regs->TDIdx[0]));
+		BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
+		writew(TRDCSR_RUN, &regs->TDCSRClr);
+		netif_stop_queue(vptr->dev);
 
-		if (rd->rdesc0.len & OWNED_BY_NIC)
-			break;
+		/* FIXME: port over the pci_device_failed code and use it
+		   here */
+	}
 
-		rmb();
+	if (status & ISR_SRCI) {
+		struct mac_regs __iomem *regs = vptr->mac_regs;
+		int linked;
 
+		if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
+			vptr->mii_status = check_connection_type(regs);
+
+			/*
+			 *	If it is a 3119, disable frame bursting in
+			 *	halfduplex mode and enable it in fullduplex
+			 *	 mode
+			 */
+			if (vptr->rev_id < REV_ID_VT3216_A0) {
+				if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
+					BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
+				else
+					BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
+			}
+			/*
+			 *	Only enable CD heart beat counter in 10HD mode
+			 */
+			if (!(vptr->mii_status & VELOCITY_DUPLEX_FULL) && (vptr->mii_status & VELOCITY_SPEED_10))
+				BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
+			else
+				BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
+		}
 		/*
-		 *	Don't drop CE or RL error frame although RXOK is off
+		 *	Get link status from PHYSR0
 		 */
-		if (rd->rdesc0.RSR & (RSR_RXOK | RSR_CE | RSR_RL)) {
-			if (velocity_receive_frame(vptr, rd_curr) < 0)
-				stats->rx_dropped++;
-		} else {
-			if (rd->rdesc0.RSR & RSR_CRC)
-				stats->rx_crc_errors++;
-			if (rd->rdesc0.RSR & RSR_FAE)
-				stats->rx_frame_errors++;
+		linked = readb(&regs->PHYSR0) & PHYSR0_LINKGD;
 
-			stats->rx_dropped++;
+		if (linked) {
+			vptr->mii_status &= ~VELOCITY_LINK_FAIL;
+			netif_carrier_on(vptr->dev);
+		} else {
+			vptr->mii_status |= VELOCITY_LINK_FAIL;
+			netif_carrier_off(vptr->dev);
 		}
 
-		rd->size |= RX_INTEN;
+		velocity_print_link_status(vptr);
+		enable_flow_control_ability(vptr);
 
-		rd_curr++;
-		if (rd_curr >= vptr->options.numrx)
-			rd_curr = 0;
-	} while (++works <= 15);
+		/*
+		 *	Re-enable auto-polling because SRCI will disable
+		 *	auto-polling
+		 */
 
-	vptr->rx.curr = rd_curr;
+		enable_mii_autopoll(regs);
 
-	if ((works > 0) && (velocity_rx_refill(vptr) > 0))
-		velocity_give_many_rx_descs(vptr);
+		if (vptr->mii_status & VELOCITY_LINK_FAIL)
+			netif_stop_queue(vptr->dev);
+		else
+			netif_wake_queue(vptr->dev);
 
-	VAR_USED(stats);
+	};
+	if (status & ISR_MIBFI)
+		velocity_update_hw_mibs(vptr);
+	if (status & ISR_LSTEI)
+		mac_rx_queue_wake(vptr->mac_regs);
+}
+
+/**
+ *	tx_srv		-	transmit interrupt service
+ *	@vptr; Velocity
+ *	@status:
+ *
+ *	Scan the queues looking for transmitted packets that
+ *	we can complete and clean up. Update any statistics as
+ *	necessary/
+ */
+static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
+{
+	struct tx_desc *td;
+	int qnum;
+	int full = 0;
+	int idx;
+	int works = 0;
+	struct velocity_td_info *tdinfo;
+	struct net_device_stats *stats = &vptr->dev->stats;
+
+	for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
+		for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
+			idx = (idx + 1) % vptr->options.numtx) {
+
+			/*
+			 *	Get Tx Descriptor
+			 */
+			td = &(vptr->tx.rings[qnum][idx]);
+			tdinfo = &(vptr->tx.infos[qnum][idx]);
+
+			if (td->tdesc0.len & OWNED_BY_NIC)
+				break;
+
+			if ((works++ > 15))
+				break;
+
+			if (td->tdesc0.TSR & TSR0_TERR) {
+				stats->tx_errors++;
+				stats->tx_dropped++;
+				if (td->tdesc0.TSR & TSR0_CDH)
+					stats->tx_heartbeat_errors++;
+				if (td->tdesc0.TSR & TSR0_CRS)
+					stats->tx_carrier_errors++;
+				if (td->tdesc0.TSR & TSR0_ABT)
+					stats->tx_aborted_errors++;
+				if (td->tdesc0.TSR & TSR0_OWC)
+					stats->tx_window_errors++;
+			} else {
+				stats->tx_packets++;
+				stats->tx_bytes += tdinfo->skb->len;
+			}
+			velocity_free_tx_buf(vptr, tdinfo);
+			vptr->tx.used[qnum]--;
+		}
+		vptr->tx.tail[qnum] = idx;
+
+		if (AVAIL_TD(vptr, qnum) < 1)
+			full = 1;
+	}
+	/*
+	 *	Look to see if we should kick the transmit network
+	 *	layer for more work.
+	 */
+	if (netif_queue_stopped(vptr->dev) && (full == 0)
+	    && (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
+		netif_wake_queue(vptr->dev);
+	}
 	return works;
 }
 
@@ -1441,7 +1914,6 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
  *	Process the status bits for the received packet and determine
  *	if the checksum was computed and verified by the hardware
  */
-
 static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
 {
 	skb->ip_summed = CHECKSUM_NONE;
@@ -1450,9 +1922,8 @@ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
 		if (rd->rdesc1.CSM & CSM_IPOK) {
 			if ((rd->rdesc1.CSM & CSM_TCPKT) ||
 					(rd->rdesc1.CSM & CSM_UDPKT)) {
-				if (!(rd->rdesc1.CSM & CSM_TUPOK)) {
+				if (!(rd->rdesc1.CSM & CSM_TUPOK))
 					return;
-				}
 			}
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		}
@@ -1509,6 +1980,7 @@ static inline void velocity_iph_realign(struct velocity_info *vptr,
 	}
 }
 
+
 /**
  *	velocity_receive_frame	-	received packet processor
  *	@vptr: velocity we are handling
@@ -1517,7 +1989,6 @@ static inline void velocity_iph_realign(struct velocity_info *vptr,
  *	A packet has arrived. We process the packet and if appropriate
  *	pass the frame up the network stack
  */
-
 static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 {
 	void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
@@ -1579,320 +2050,118 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 	return 0;
 }
 
-/**
- *	velocity_alloc_rx_buf	-	allocate aligned receive buffer
- *	@vptr: velocity
- *	@idx: ring index
- *
- *	Allocate a new full sized buffer for the reception of a frame and
- *	map it into PCI space for the hardware to use. The hardware
- *	requires *64* byte alignment of the buffer which makes life
- *	less fun than would be ideal.
- */
-
-static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
-{
-	struct rx_desc *rd = &(vptr->rx.ring[idx]);
-	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
-
-	rd_info->skb = dev_alloc_skb(vptr->rx.buf_sz + 64);
-	if (rd_info->skb == NULL)
-		return -ENOMEM;
-
-	/*
-	 *	Do the gymnastics to get the buffer head for data at
-	 *	64byte alignment.
-	 */
-	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
-	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data,
-					vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
-
-	/*
-	 *	Fill in the descriptor to match
-	 */
-
-	*((u32 *) & (rd->rdesc0)) = 0;
-	rd->size = cpu_to_le16(vptr->rx.buf_sz) | RX_INTEN;
-	rd->pa_low = cpu_to_le32(rd_info->skb_dma);
-	rd->pa_high = 0;
-	return 0;
-}
 
 /**
- *	tx_srv		-	transmit interrupt service
- *	@vptr; Velocity
- *	@status:
+ *	velocity_rx_srv		-	service RX interrupt
+ *	@vptr: velocity
+ *	@status: adapter status (unused)
  *
- *	Scan the queues looking for transmitted packets that
- *	we can complete and clean up. Update any statistics as
- *	necessary/
+ *	Walk the receive ring of the velocity adapter and remove
+ *	any received packets from the receive queue. Hand the ring
+ *	slots back to the adapter for reuse.
  */
-
-static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
+static int velocity_rx_srv(struct velocity_info *vptr, int status)
 {
-	struct tx_desc *td;
-	int qnum;
-	int full = 0;
-	int idx;
-	int works = 0;
-	struct velocity_td_info *tdinfo;
 	struct net_device_stats *stats = &vptr->dev->stats;
+	int rd_curr = vptr->rx.curr;
+	int works = 0;
 
-	for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
-		for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
-			idx = (idx + 1) % vptr->options.numtx) {
+	do {
+		struct rx_desc *rd = vptr->rx.ring + rd_curr;
 
-			/*
-			 *	Get Tx Descriptor
-			 */
-			td = &(vptr->tx.rings[qnum][idx]);
-			tdinfo = &(vptr->tx.infos[qnum][idx]);
+		if (!vptr->rx.info[rd_curr].skb)
+			break;
 
-			if (td->tdesc0.len & OWNED_BY_NIC)
-				break;
+		if (rd->rdesc0.len & OWNED_BY_NIC)
+			break;
 
-			if ((works++ > 15))
-				break;
+		rmb();
 
-			if (td->tdesc0.TSR & TSR0_TERR) {
-				stats->tx_errors++;
-				stats->tx_dropped++;
-				if (td->tdesc0.TSR & TSR0_CDH)
-					stats->tx_heartbeat_errors++;
-				if (td->tdesc0.TSR & TSR0_CRS)
-					stats->tx_carrier_errors++;
-				if (td->tdesc0.TSR & TSR0_ABT)
-					stats->tx_aborted_errors++;
-				if (td->tdesc0.TSR & TSR0_OWC)
-					stats->tx_window_errors++;
-			} else {
-				stats->tx_packets++;
-				stats->tx_bytes += tdinfo->skb->len;
-			}
-			velocity_free_tx_buf(vptr, tdinfo);
-			vptr->tx.used[qnum]--;
-		}
-		vptr->tx.tail[qnum] = idx;
+		/*
+		 *	Don't drop CE or RL error frame although RXOK is off
+		 */
+		if (rd->rdesc0.RSR & (RSR_RXOK | RSR_CE | RSR_RL)) {
+			if (velocity_receive_frame(vptr, rd_curr) < 0)
+				stats->rx_dropped++;
+		} else {
+			if (rd->rdesc0.RSR & RSR_CRC)
+				stats->rx_crc_errors++;
+			if (rd->rdesc0.RSR & RSR_FAE)
+				stats->rx_frame_errors++;
 
-		if (AVAIL_TD(vptr, qnum) < 1) {
-			full = 1;
+			stats->rx_dropped++;
 		}
-	}
-	/*
-	 *	Look to see if we should kick the transmit network
-	 *	layer for more work.
-	 */
-	if (netif_queue_stopped(vptr->dev) && (full == 0)
-	    && (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
-		netif_wake_queue(vptr->dev);
-	}
-	return works;
-}
 
-/**
- *	velocity_print_link_status	-	link status reporting
- *	@vptr: velocity to report on
- *
- *	Turn the link status of the velocity card into a kernel log
- *	description of the new link state, detailing speed and duplex
- *	status
- */
+		rd->size |= RX_INTEN;
 
-static void velocity_print_link_status(struct velocity_info *vptr)
-{
+		rd_curr++;
+		if (rd_curr >= vptr->options.numrx)
+			rd_curr = 0;
+	} while (++works <= 15);
 
-	if (vptr->mii_status & VELOCITY_LINK_FAIL) {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name);
-	} else if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name);
+	vptr->rx.curr = rd_curr;
 
-		if (vptr->mii_status & VELOCITY_SPEED_1000)
-			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps");
-		else if (vptr->mii_status & VELOCITY_SPEED_100)
-			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps");
-		else
-			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps");
+	if ((works > 0) && (velocity_rx_refill(vptr) > 0))
+		velocity_give_many_rx_descs(vptr);
 
-		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-			VELOCITY_PRT(MSG_LEVEL_INFO, " full duplex\n");
-		else
-			VELOCITY_PRT(MSG_LEVEL_INFO, " half duplex\n");
-	} else {
-		VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name);
-		switch (vptr->options.spd_dpx) {
-		case SPD_DPX_100_HALF:
-			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n");
-			break;
-		case SPD_DPX_100_FULL:
-			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps full duplex\n");
-			break;
-		case SPD_DPX_10_HALF:
-			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps half duplex\n");
-			break;
-		case SPD_DPX_10_FULL:
-			VELOCITY_PRT(MSG_LEVEL_INFO, " speed 10M bps full duplex\n");
-			break;
-		default:
-			break;
-		}
-	}
+	VAR_USED(stats);
+	return works;
 }
 
+
 /**
- *	velocity_error	-	handle error from controller
- *	@vptr: velocity
- *	@status: card status
- *
- *	Process an error report from the hardware and attempt to recover
- *	the card itself. At the moment we cannot recover from some
- *	theoretically impossible errors but this could be fixed using
- *	the pci_device_failed logic to bounce the hardware
+ *	velocity_intr		-	interrupt callback
+ *	@irq: interrupt number
+ *	@dev_instance: interrupting device
  *
+ *	Called whenever an interrupt is generated by the velocity
+ *	adapter IRQ line. We may not be the source of the interrupt
+ *	and need to identify initially if we are, and if not exit as
+ *	efficiently as possible.
  */
-
-static void velocity_error(struct velocity_info *vptr, int status)
+static irqreturn_t velocity_intr(int irq, void *dev_instance)
 {
+	struct net_device *dev = dev_instance;
+	struct velocity_info *vptr = netdev_priv(dev);
+	u32 isr_status;
+	int max_count = 0;
 
-	if (status & ISR_TXSTLI) {
-		struct mac_regs __iomem * regs = vptr->mac_regs;
 
-		printk(KERN_ERR "TD structure error TDindex=%hx\n", readw(&regs->TDIdx[0]));
-		BYTE_REG_BITS_ON(TXESR_TDSTR, &regs->TXESR);
-		writew(TRDCSR_RUN, &regs->TDCSRClr);
-		netif_stop_queue(vptr->dev);
+	spin_lock(&vptr->lock);
+	isr_status = mac_read_isr(vptr->mac_regs);
 
-		/* FIXME: port over the pci_device_failed code and use it
-		   here */
+	/* Not us ? */
+	if (isr_status == 0) {
+		spin_unlock(&vptr->lock);
+		return IRQ_NONE;
 	}
 
-	if (status & ISR_SRCI) {
-		struct mac_regs __iomem * regs = vptr->mac_regs;
-		int linked;
-
-		if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
-			vptr->mii_status = check_connection_type(regs);
-
-			/*
-			 *	If it is a 3119, disable frame bursting in
-			 *	halfduplex mode and enable it in fullduplex
-			 *	 mode
-			 */
-			if (vptr->rev_id < REV_ID_VT3216_A0) {
-				if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-					BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
-				else
-					BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
-			}
-			/*
-			 *	Only enable CD heart beat counter in 10HD mode
-			 */
-			if (!(vptr->mii_status & VELOCITY_DUPLEX_FULL) && (vptr->mii_status & VELOCITY_SPEED_10)) {
-				BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
-			} else {
-				BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
-			}
-		}
-		/*
-		 *	Get link status from PHYSR0
-		 */
-		linked = readb(&regs->PHYSR0) & PHYSR0_LINKGD;
-
-		if (linked) {
-			vptr->mii_status &= ~VELOCITY_LINK_FAIL;
-			netif_carrier_on(vptr->dev);
-		} else {
-			vptr->mii_status |= VELOCITY_LINK_FAIL;
-			netif_carrier_off(vptr->dev);
-		}
-
-		velocity_print_link_status(vptr);
-		enable_flow_control_ability(vptr);
-
-		/*
-		 *	Re-enable auto-polling because SRCI will disable
-		 *	auto-polling
-		 */
-
-		enable_mii_autopoll(regs);
-
-		if (vptr->mii_status & VELOCITY_LINK_FAIL)
-			netif_stop_queue(vptr->dev);
-		else
-			netif_wake_queue(vptr->dev);
-
-	};
-	if (status & ISR_MIBFI)
-		velocity_update_hw_mibs(vptr);
-	if (status & ISR_LSTEI)
-		mac_rx_queue_wake(vptr->mac_regs);
-}
-
-/**
- *	velocity_free_tx_buf	-	free transmit buffer
- *	@vptr: velocity
- *	@tdinfo: buffer
- *
- *	Release an transmit buffer. If the buffer was preallocated then
- *	recycle it, if not then unmap the buffer.
- */
-
-static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
-{
-	struct sk_buff *skb = tdinfo->skb;
-	int i;
-	int pktlen;
+	mac_disable_int(vptr->mac_regs);
 
 	/*
-	 *	Don't unmap the pre-allocated tx_bufs
+	 *	Keep processing the ISR until we have completed
+	 *	processing and the isr_status becomes zero
 	 */
-	if (tdinfo->skb_dma) {
 
-		pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
-		for (i = 0; i < tdinfo->nskb_dma; i++) {
-#ifdef VELOCITY_ZERO_COPY_SUPPORT
-			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], le16_to_cpu(td->tdesc1.len), PCI_DMA_TODEVICE);
-#else
-			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], pktlen, PCI_DMA_TODEVICE);
-#endif
-			tdinfo->skb_dma[i] = 0;
+	while (isr_status != 0) {
+		mac_write_isr(vptr->mac_regs, isr_status);
+		if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
+			velocity_error(vptr, isr_status);
+		if (isr_status & (ISR_PRXI | ISR_PPRXI))
+			max_count += velocity_rx_srv(vptr, isr_status);
+		if (isr_status & (ISR_PTXI | ISR_PPTXI))
+			max_count += velocity_tx_srv(vptr, isr_status);
+		isr_status = mac_read_isr(vptr->mac_regs);
+		if (max_count > vptr->options.int_works) {
+			printk(KERN_WARNING "%s: excessive work at interrupt.\n",
+				dev->name);
+			max_count = 0;
 		}
 	}
-	dev_kfree_skb_irq(skb);
-	tdinfo->skb = NULL;
-}
-
-static int velocity_init_rings(struct velocity_info *vptr, int mtu)
-{
-	int ret;
-
-	velocity_set_rxbufsize(vptr, mtu);
-
-	ret = velocity_init_dma_rings(vptr);
-	if (ret < 0)
-		goto out;
-
-	ret = velocity_init_rd_ring(vptr);
-	if (ret < 0)
-		goto err_free_dma_rings_0;
-
-	ret = velocity_init_td_ring(vptr);
-	if (ret < 0)
-		goto err_free_rd_ring_1;
-out:
-	return ret;
-
-err_free_rd_ring_1:
-	velocity_free_rd_ring(vptr);
-err_free_dma_rings_0:
-	velocity_free_dma_rings(vptr);
-	goto out;
-}
+	spin_unlock(&vptr->lock);
+	mac_enable_int(vptr->mac_regs);
+	return IRQ_HANDLED;
 
-static void velocity_free_rings(struct velocity_info *vptr)
-{
-	velocity_free_td_ring(vptr);
-	velocity_free_rd_ring(vptr);
-	velocity_free_dma_rings(vptr);
 }
 
 /**
@@ -1905,7 +2174,6 @@ static void velocity_free_rings(struct velocity_info *vptr)
  *	All the ring allocation and set up is done on open for this
  *	adapter to minimise memory usage when inactive
  */
-
 static int velocity_open(struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
@@ -1939,6 +2207,24 @@ out:
 }
 
 /**
+ *	velocity_shutdown	-	shut down the chip
+ *	@vptr: velocity to deactivate
+ *
+ *	Shuts down the internal operations of the velocity and
+ *	disables interrupts, autopolling, transmit and receive
+ */
+static void velocity_shutdown(struct velocity_info *vptr)
+{
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	mac_disable_int(regs);
+	writel(CR0_STOP, &regs->CR0Set);
+	writew(0xFFFF, &regs->TDCSRClr);
+	writeb(0xFF, &regs->RDCSRClr);
+	safe_disable_mii_autopoll(regs);
+	mac_clear_isr(regs);
+}
+
+/**
  *	velocity_change_mtu	-	MTU change callback
  *	@dev: network device
  *	@new_mtu: desired MTU
@@ -1947,7 +2233,6 @@ out:
  *	this interface. It gets called on a change by the network layer.
  *	Return zero for success or negative posix error code.
  */
-
 static int velocity_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
@@ -2021,22 +2306,123 @@ out_0:
 }
 
 /**
- *	velocity_shutdown	-	shut down the chip
- *	@vptr: velocity to deactivate
+ *	velocity_mii_ioctl		-	MII ioctl handler
+ *	@dev: network device
+ *	@ifr: the ifreq block for the ioctl
+ *	@cmd: the command
  *
- *	Shuts down the internal operations of the velocity and
- *	disables interrupts, autopolling, transmit and receive
+ *	Process MII requests made via ioctl from the network layer. These
+ *	are used by tools like kudzu to interrogate the link state of the
+ *	hardware
  */
+static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	unsigned long flags;
+	struct mii_ioctl_data *miidata = if_mii(ifr);
+	int err;
 
-static void velocity_shutdown(struct velocity_info *vptr)
+	switch (cmd) {
+	case SIOCGMIIPHY:
+		miidata->phy_id = readb(&regs->MIIADR) & 0x1f;
+		break;
+	case SIOCGMIIREG:
+		if (velocity_mii_read(vptr->mac_regs, miidata->reg_num & 0x1f, &(miidata->val_out)) < 0)
+			return -ETIMEDOUT;
+		break;
+	case SIOCSMIIREG:
+		spin_lock_irqsave(&vptr->lock, flags);
+		err = velocity_mii_write(vptr->mac_regs, miidata->reg_num & 0x1f, miidata->val_in);
+		spin_unlock_irqrestore(&vptr->lock, flags);
+		check_connection_type(vptr->mac_regs);
+		if (err)
+			return err;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+
+/**
+ *	velocity_ioctl		-	ioctl entry point
+ *	@dev: network device
+ *	@rq: interface request ioctl
+ *	@cmd: command code
+ *
+ *	Called when the user issues an ioctl request to the network
+ *	device in question. The velocity interface supports MII.
+ */
+static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct mac_regs __iomem * regs = vptr->mac_regs;
-	mac_disable_int(regs);
-	writel(CR0_STOP, &regs->CR0Set);
-	writew(0xFFFF, &regs->TDCSRClr);
-	writeb(0xFF, &regs->RDCSRClr);
-	safe_disable_mii_autopoll(regs);
-	mac_clear_isr(regs);
+	struct velocity_info *vptr = netdev_priv(dev);
+	int ret;
+
+	/* If we are asked for information and the device is power
+	   saving then we need to bring the device back up to talk to it */
+
+	if (!netif_running(dev))
+		pci_set_power_state(vptr->pdev, PCI_D0);
+
+	switch (cmd) {
+	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
+	case SIOCGMIIREG:	/* Read MII PHY register. */
+	case SIOCSMIIREG:	/* Write to MII PHY register. */
+		ret = velocity_mii_ioctl(dev, rq, cmd);
+		break;
+
+	default:
+		ret = -EOPNOTSUPP;
+	}
+	if (!netif_running(dev))
+		pci_set_power_state(vptr->pdev, PCI_D3hot);
+
+
+	return ret;
+}
+
+/**
+ *	velocity_get_status	-	statistics callback
+ *	@dev: network device
+ *
+ *	Callback from the network layer to allow driver statistics
+ *	to be resynchronized with hardware collected state. In the
+ *	case of the velocity we need to pull the MIB counters from
+ *	the hardware into the counters before letting the network
+ *	layer display them.
+ */
+static struct net_device_stats *velocity_get_stats(struct net_device *dev)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+
+	/* If the hardware is down, don't touch MII */
+	if (!netif_running(dev))
+		return &dev->stats;
+
+	spin_lock_irq(&vptr->lock);
+	velocity_update_hw_mibs(vptr);
+	spin_unlock_irq(&vptr->lock);
+
+	dev->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
+	dev->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
+	dev->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
+
+//  unsigned long   rx_dropped;     /* no space in linux buffers    */
+	dev->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
+	/* detailed rx_errors: */
+//  unsigned long   rx_length_errors;
+//  unsigned long   rx_over_errors;     /* receiver ring buff overflow  */
+	dev->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
+//  unsigned long   rx_frame_errors;    /* recv'd frame alignment error */
+//  unsigned long   rx_fifo_errors;     /* recv'r fifo overrun      */
+//  unsigned long   rx_missed_errors;   /* receiver missed packet   */
+
+	/* detailed tx_errors */
+//  unsigned long   tx_fifo_errors;
+
+	return &dev->stats;
 }
 
 /**
@@ -2046,7 +2432,6 @@ static void velocity_shutdown(struct velocity_info *vptr)
  *	Callback from the network layer when the velocity is being
  *	deactivated by the network layer
  */
-
 static int velocity_close(struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
@@ -2076,8 +2461,8 @@ static int velocity_close(struct net_device *dev)
  *	Called by the networ layer to request a packet is queued to
  *	the velocity. Returns zero on success.
  */
-
-static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t velocity_xmit(struct sk_buff *skb,
+				 struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 	int qnum = 0;
@@ -2088,20 +2473,12 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 	__le16 len;
 	int index;
 
-
 	if (skb_padto(skb, ETH_ZLEN))
 		goto out;
 	pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
 
 	len = cpu_to_le16(pktlen);
 
-#ifdef VELOCITY_ZERO_COPY_SUPPORT
-	if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
-		kfree_skb(skb);
-		return 0;
-	}
-#endif
-
 	spin_lock_irqsave(&vptr->lock, flags);
 
 	index = vptr->tx.curr[qnum];
@@ -2111,59 +2488,18 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 	td_ptr->tdesc1.TCR = TCR0_TIC;
 	td_ptr->td_buf[0].size &= ~TD_QUEUE;
 
-#ifdef VELOCITY_ZERO_COPY_SUPPORT
-	if (skb_shinfo(skb)->nr_frags > 0) {
-		int nfrags = skb_shinfo(skb)->nr_frags;
-		tdinfo->skb = skb;
-		if (nfrags > 6) {
-			skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
-			tdinfo->skb_dma[0] = tdinfo->buf_dma;
-			td_ptr->tdesc0.len = len;
-			td_ptr->tx.buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
-			td_ptr->tx.buf[0].pa_high = 0;
-			td_ptr->tx.buf[0].size = len;	/* queue is 0 anyway */
-			tdinfo->nskb_dma = 1;
-		} else {
-			int i = 0;
-			tdinfo->nskb_dma = 0;
-			tdinfo->skb_dma[i] = pci_map_single(vptr->pdev, skb->data,
-						skb_headlen(skb), PCI_DMA_TODEVICE);
-
-			td_ptr->tdesc0.len = len;
-
-			/* FIXME: support 48bit DMA later */
-			td_ptr->tx.buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
-			td_ptr->tx.buf[i].pa_high = 0;
-			td_ptr->tx.buf[i].size = cpu_to_le16(skb_headlen(skb));
-
-			for (i = 0; i < nfrags; i++) {
-				skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-				void *addr = (void *)page_address(frag->page) + frag->page_offset;
-
-				tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE);
-
-				td_ptr->tx.buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
-				td_ptr->tx.buf[i + 1].pa_high = 0;
-				td_ptr->tx.buf[i + 1].size = cpu_to_le16(frag->size);
-			}
-			tdinfo->nskb_dma = i - 1;
-		}
+	/*
+	 *	Map the linear network buffer into PCI space and
+	 *	add it to the transmit ring.
+	 */
+	tdinfo->skb = skb;
+	tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
+	td_ptr->tdesc0.len = len;
+	td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+	td_ptr->td_buf[0].pa_high = 0;
+	td_ptr->td_buf[0].size = len;
+	tdinfo->nskb_dma = 1;
 
-	} else
-#endif
-	{
-		/*
-		 *	Map the linear network buffer into PCI space and
-		 *	add it to the transmit ring.
-		 */
-		tdinfo->skb = skb;
-		tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
-		td_ptr->tdesc0.len = len;
-		td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
-		td_ptr->td_buf[0].pa_high = 0;
-		td_ptr->td_buf[0].size = len;
-		tdinfo->nskb_dma = 1;
-	}
 	td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16;
 
 	if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
@@ -2206,782 +2542,533 @@ out:
 	return NETDEV_TX_OK;
 }
 
+
+static const struct net_device_ops velocity_netdev_ops = {
+	.ndo_open		= velocity_open,
+	.ndo_stop		= velocity_close,
+	.ndo_start_xmit		= velocity_xmit,
+	.ndo_get_stats		= velocity_get_stats,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_set_mac_address 	= eth_mac_addr,
+	.ndo_set_multicast_list	= velocity_set_multi,
+	.ndo_change_mtu		= velocity_change_mtu,
+	.ndo_do_ioctl		= velocity_ioctl,
+	.ndo_vlan_rx_add_vid	= velocity_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	= velocity_vlan_rx_kill_vid,
+	.ndo_vlan_rx_register	= velocity_vlan_rx_register,
+};
+
 /**
- *	velocity_intr		-	interrupt callback
- *	@irq: interrupt number
- *	@dev_instance: interrupting device
+ *	velocity_init_info	-	init private data
+ *	@pdev: PCI device
+ *	@vptr: Velocity info
+ *	@info: Board type
  *
- *	Called whenever an interrupt is generated by the velocity
- *	adapter IRQ line. We may not be the source of the interrupt
- *	and need to identify initially if we are, and if not exit as
- *	efficiently as possible.
+ *	Set up the initial velocity_info struct for the device that has been
+ *	discovered.
  */
-
-static irqreturn_t velocity_intr(int irq, void *dev_instance)
+static void __devinit velocity_init_info(struct pci_dev *pdev,
+					 struct velocity_info *vptr,
+					 const struct velocity_info_tbl *info)
 {
-	struct net_device *dev = dev_instance;
-	struct velocity_info *vptr = netdev_priv(dev);
-	u32 isr_status;
-	int max_count = 0;
-
-
-	spin_lock(&vptr->lock);
-	isr_status = mac_read_isr(vptr->mac_regs);
-
-	/* Not us ? */
-	if (isr_status == 0) {
-		spin_unlock(&vptr->lock);
-		return IRQ_NONE;
-	}
-
-	mac_disable_int(vptr->mac_regs);
-
-	/*
-	 *	Keep processing the ISR until we have completed
-	 *	processing and the isr_status becomes zero
-	 */
-
-	while (isr_status != 0) {
-		mac_write_isr(vptr->mac_regs, isr_status);
-		if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
-			velocity_error(vptr, isr_status);
-		if (isr_status & (ISR_PRXI | ISR_PPRXI))
-			max_count += velocity_rx_srv(vptr, isr_status);
-		if (isr_status & (ISR_PTXI | ISR_PPTXI))
-			max_count += velocity_tx_srv(vptr, isr_status);
-		isr_status = mac_read_isr(vptr->mac_regs);
-		if (max_count > vptr->options.int_works)
-		{
-			printk(KERN_WARNING "%s: excessive work at interrupt.\n",
-				dev->name);
-			max_count = 0;
-		}
-	}
-	spin_unlock(&vptr->lock);
-	mac_enable_int(vptr->mac_regs);
-	return IRQ_HANDLED;
+	memset(vptr, 0, sizeof(struct velocity_info));
 
+	vptr->pdev = pdev;
+	vptr->chip_id = info->chip_id;
+	vptr->tx.numq = info->txqueue;
+	vptr->multicast_limit = MCAM_SIZE;
+	spin_lock_init(&vptr->lock);
+	INIT_LIST_HEAD(&vptr->list);
 }
 
-
 /**
- *	velocity_set_multi	-	filter list change callback
- *	@dev: network device
+ *	velocity_get_pci_info	-	retrieve PCI info for device
+ *	@vptr: velocity device
+ *	@pdev: PCI device it matches
  *
- *	Called by the network layer when the filter lists need to change
- *	for a velocity adapter. Reload the CAMs with the new address
- *	filter ruleset.
+ *	Retrieve the PCI configuration space data that interests us from
+ *	the kernel PCI layer
  */
-
-static void velocity_set_multi(struct net_device *dev)
+static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev)
 {
-	struct velocity_info *vptr = netdev_priv(dev);
-	struct mac_regs __iomem * regs = vptr->mac_regs;
-	u8 rx_mode;
-	int i;
-	struct dev_mc_list *mclist;
+	vptr->rev_id = pdev->revision;
 
-	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
-		writel(0xffffffff, &regs->MARCAM[0]);
-		writel(0xffffffff, &regs->MARCAM[4]);
-		rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
-	} else if ((dev->mc_count > vptr->multicast_limit)
-		   || (dev->flags & IFF_ALLMULTI)) {
-		writel(0xffffffff, &regs->MARCAM[0]);
-		writel(0xffffffff, &regs->MARCAM[4]);
-		rx_mode = (RCR_AM | RCR_AB);
-	} else {
-		int offset = MCAM_SIZE - vptr->multicast_limit;
-		mac_get_cam_mask(regs, vptr->mCAMmask);
+	pci_set_master(pdev);
 
-		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
-			mac_set_cam(regs, i + offset, mclist->dmi_addr);
-			vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
-		}
+	vptr->ioaddr = pci_resource_start(pdev, 0);
+	vptr->memaddr = pci_resource_start(pdev, 1);
 
-		mac_set_cam_mask(regs, vptr->mCAMmask);
-		rx_mode = RCR_AM | RCR_AB | RCR_AP;
+	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
+		dev_err(&pdev->dev,
+			   "region #0 is not an I/O resource, aborting.\n");
+		return -EINVAL;
 	}
-	if (dev->mtu > 1500)
-		rx_mode |= RCR_AL;
 
-	BYTE_REG_BITS_ON(rx_mode, &regs->RCR);
+	if ((pci_resource_flags(pdev, 1) & IORESOURCE_IO)) {
+		dev_err(&pdev->dev,
+			   "region #1 is an I/O resource, aborting.\n");
+		return -EINVAL;
+	}
 
+	if (pci_resource_len(pdev, 1) < VELOCITY_IO_SIZE) {
+		dev_err(&pdev->dev, "region #1 is too small.\n");
+		return -EINVAL;
+	}
+	vptr->pdev = pdev;
+
+	return 0;
 }
 
 /**
- *	velocity_get_status	-	statistics callback
- *	@dev: network device
+ *	velocity_print_info	-	per driver data
+ *	@vptr: velocity
  *
- *	Callback from the network layer to allow driver statistics
- *	to be resynchronized with hardware collected state. In the
- *	case of the velocity we need to pull the MIB counters from
- *	the hardware into the counters before letting the network
- *	layer display them.
+ *	Print per driver data as the kernel driver finds Velocity
+ *	hardware
  */
-
-static struct net_device_stats *velocity_get_stats(struct net_device *dev)
+static void __devinit velocity_print_info(struct velocity_info *vptr)
 {
-	struct velocity_info *vptr = netdev_priv(dev);
-
-	/* If the hardware is down, don't touch MII */
-	if(!netif_running(dev))
-		return &dev->stats;
-
-	spin_lock_irq(&vptr->lock);
-	velocity_update_hw_mibs(vptr);
-	spin_unlock_irq(&vptr->lock);
-
-	dev->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
-	dev->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
-	dev->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
-
-//  unsigned long   rx_dropped;     /* no space in linux buffers    */
-	dev->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
-	/* detailed rx_errors: */
-//  unsigned long   rx_length_errors;
-//  unsigned long   rx_over_errors;     /* receiver ring buff overflow  */
-	dev->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
-//  unsigned long   rx_frame_errors;    /* recv'd frame alignment error */
-//  unsigned long   rx_fifo_errors;     /* recv'r fifo overrun      */
-//  unsigned long   rx_missed_errors;   /* receiver missed packet   */
-
-	/* detailed tx_errors */
-//  unsigned long   tx_fifo_errors;
+	struct net_device *dev = vptr->dev;
 
-	return &dev->stats;
+	printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
+	printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+		dev->name,
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 }
 
-
-/**
- *	velocity_ioctl		-	ioctl entry point
- *	@dev: network device
- *	@rq: interface request ioctl
- *	@cmd: command code
- *
- *	Called when the user issues an ioctl request to the network
- *	device in question. The velocity interface supports MII.
- */
-
-static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static u32 velocity_get_link(struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
-	int ret;
-
-	/* If we are asked for information and the device is power
-	   saving then we need to bring the device back up to talk to it */
-
-	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D0);
-
-	switch (cmd) {
-	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
-	case SIOCGMIIREG:	/* Read MII PHY register. */
-	case SIOCSMIIREG:	/* Write to MII PHY register. */
-		ret = velocity_mii_ioctl(dev, rq, cmd);
-		break;
-
-	default:
-		ret = -EOPNOTSUPP;
-	}
-	if (!netif_running(dev))
-		pci_set_power_state(vptr->pdev, PCI_D3hot);
-
-
-	return ret;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, &regs->PHYSR0) ? 1 : 0;
 }
 
-/*
- *	Definition for our device driver. The PCI layer interface
- *	uses this to handle all our card discover and plugging
- */
-
-static struct pci_driver velocity_driver = {
-      .name	= VELOCITY_NAME,
-      .id_table	= velocity_id_table,
-      .probe	= velocity_found1,
-      .remove	= __devexit_p(velocity_remove1),
-#ifdef CONFIG_PM
-      .suspend	= velocity_suspend,
-      .resume	= velocity_resume,
-#endif
-};
 
 /**
- *	velocity_init_module	-	load time function
+ *	velocity_found1		-	set up discovered velocity card
+ *	@pdev: PCI device
+ *	@ent: PCI device table entry that matched
  *
- *	Called when the velocity module is loaded. The PCI driver
- *	is registered with the PCI layer, and in turn will call
- *	the probe functions for each velocity adapter installed
- *	in the system.
+ *	Configure a discovered adapter from scratch. Return a negative
+ *	errno error code on failure paths.
  */
-
-static int __init velocity_init_module(void)
+static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	int ret;
+	static int first = 1;
+	struct net_device *dev;
+	int i;
+	const char *drv_string;
+	const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data];
+	struct velocity_info *vptr;
+	struct mac_regs __iomem *regs;
+	int ret = -ENOMEM;
 
-	velocity_register_notifier();
-	ret = pci_register_driver(&velocity_driver);
-	if (ret < 0)
-		velocity_unregister_notifier();
-	return ret;
-}
+	/* FIXME: this driver, like almost all other ethernet drivers,
+	 * can support more than MAX_UNITS.
+	 */
+	if (velocity_nics >= MAX_UNITS) {
+		dev_notice(&pdev->dev, "already found %d NICs.\n",
+			   velocity_nics);
+		return -ENODEV;
+	}
 
-/**
- *	velocity_cleanup	-	module unload
- *
- *	When the velocity hardware is unloaded this function is called.
- *	It will clean up the notifiers and the unregister the PCI
- *	driver interface for this hardware. This in turn cleans up
- *	all discovered interfaces before returning from the function
- */
+	dev = alloc_etherdev(sizeof(struct velocity_info));
+	if (!dev) {
+		dev_err(&pdev->dev, "allocate net device failed.\n");
+		goto out;
+	}
 
-static void __exit velocity_cleanup_module(void)
-{
-	velocity_unregister_notifier();
-	pci_unregister_driver(&velocity_driver);
-}
+	/* Chain it all together */
 
-module_init(velocity_init_module);
-module_exit(velocity_cleanup_module);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	vptr = netdev_priv(dev);
 
 
-/*
- * MII access , media link mode setting functions
- */
+	if (first) {
+		printk(KERN_INFO "%s Ver. %s\n",
+			VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
+		printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
+		printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
+		first = 0;
+	}
 
+	velocity_init_info(pdev, vptr, info);
 
-/**
- *	mii_init	-	set up MII
- *	@vptr: velocity adapter
- *	@mii_status:  links tatus
- *
- *	Set up the PHY for the current link state.
- */
+	vptr->dev = dev;
 
-static void mii_init(struct velocity_info *vptr, u32 mii_status)
-{
-	u16 BMCR;
+	dev->irq = pdev->irq;
 
-	switch (PHYID_GET_PHY_ID(vptr->phy_id)) {
-	case PHYID_CICADA_CS8201:
-		/*
-		 *	Reset to hardware default
-		 */
-		MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
-		/*
-		 *	Turn on ECHODIS bit in NWay-forced full mode and turn it
-		 *	off it in NWay-forced half mode for NWay-forced v.s.
-		 *	legacy-forced issue.
-		 */
-		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-			MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
-		else
-			MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
-		/*
-		 *	Turn on Link/Activity LED enable bit for CIS8201
-		 */
-		MII_REG_BITS_ON(PLED_LALBE, MII_REG_PLED, vptr->mac_regs);
-		break;
-	case PHYID_VT3216_32BIT:
-	case PHYID_VT3216_64BIT:
-		/*
-		 *	Reset to hardware default
-		 */
-		MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
-		/*
-		 *	Turn on ECHODIS bit in NWay-forced full mode and turn it
-		 *	off it in NWay-forced half mode for NWay-forced v.s.
-		 *	legacy-forced issue
-		 */
-		if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
-			MII_REG_BITS_ON(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
-		else
-			MII_REG_BITS_OFF(TCSR_ECHODIS, MII_REG_TCSR, vptr->mac_regs);
-		break;
+	ret = pci_enable_device(pdev);
+	if (ret < 0)
+		goto err_free_dev;
 
-	case PHYID_MARVELL_1000:
-	case PHYID_MARVELL_1000S:
-		/*
-		 *	Assert CRS on Transmit
-		 */
-		MII_REG_BITS_ON(PSCR_ACRSTX, MII_REG_PSCR, vptr->mac_regs);
-		/*
-		 *	Reset to hardware default
-		 */
-		MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
-		break;
-	default:
-		;
-	}
-	velocity_mii_read(vptr->mac_regs, MII_REG_BMCR, &BMCR);
-	if (BMCR & BMCR_ISO) {
-		BMCR &= ~BMCR_ISO;
-		velocity_mii_write(vptr->mac_regs, MII_REG_BMCR, BMCR);
+	ret = velocity_get_pci_info(vptr, pdev);
+	if (ret < 0) {
+		/* error message already printed */
+		goto err_disable;
 	}
-}
 
-/**
- *	safe_disable_mii_autopoll	-	autopoll off
- *	@regs: velocity registers
- *
- *	Turn off the autopoll and wait for it to disable on the chip
- */
-
-static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs)
-{
-	u16 ww;
-
-	/*  turn off MAUTO */
-	writeb(0, &regs->MIICR);
-	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
-		udelay(1);
-		if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
-			break;
+	ret = pci_request_regions(pdev, VELOCITY_NAME);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "No PCI resources.\n");
+		goto err_disable;
 	}
-}
-
-/**
- *	enable_mii_autopoll	-	turn on autopolling
- *	@regs: velocity registers
- *
- *	Enable the MII link status autopoll feature on the Velocity
- *	hardware. Wait for it to enable.
- */
 
-static void enable_mii_autopoll(struct mac_regs __iomem * regs)
-{
-	int ii;
+	regs = ioremap(vptr->memaddr, VELOCITY_IO_SIZE);
+	if (regs == NULL) {
+		ret = -EIO;
+		goto err_release_res;
+	}
 
-	writeb(0, &(regs->MIICR));
-	writeb(MIIADR_SWMPL, &regs->MIIADR);
+	vptr->mac_regs = regs;
 
-	for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
-		udelay(1);
-		if (BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
-			break;
-	}
+	mac_wol_reset(regs);
 
-	writeb(MIICR_MAUTO, &regs->MIICR);
+	dev->base_addr = vptr->ioaddr;
 
-	for (ii = 0; ii < W_MAX_TIMEOUT; ii++) {
-		udelay(1);
-		if (!BYTE_REG_BITS_IS_ON(MIISR_MIDLE, &regs->MIISR))
-			break;
-	}
+	for (i = 0; i < 6; i++)
+		dev->dev_addr[i] = readb(&regs->PAR[i]);
 
-}
 
-/**
- *	velocity_mii_read	-	read MII data
- *	@regs: velocity registers
- *	@index: MII register index
- *	@data: buffer for received data
- *
- *	Perform a single read of an MII 16bit register. Returns zero
- *	on success or -ETIMEDOUT if the PHY did not respond.
- */
+	drv_string = dev_driver_string(&pdev->dev);
 
-static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
-{
-	u16 ww;
+	velocity_get_options(&vptr->options, velocity_nics, drv_string);
 
 	/*
-	 *	Disable MIICR_MAUTO, so that mii addr can be set normally
+	 *	Mask out the options cannot be set to the chip
 	 */
-	safe_disable_mii_autopoll(regs);
 
-	writeb(index, &regs->MIIADR);
-
-	BYTE_REG_BITS_ON(MIICR_RCMD, &regs->MIICR);
+	vptr->options.flags &= info->flags;
 
-	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
-		if (!(readb(&regs->MIICR) & MIICR_RCMD))
-			break;
-	}
+	/*
+	 *	Enable the chip specified capbilities
+	 */
 
-	*data = readw(&regs->MIIDATA);
+	vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
 
-	enable_mii_autopoll(regs);
-	if (ww == W_MAX_TIMEOUT)
-		return -ETIMEDOUT;
-	return 0;
-}
+	vptr->wol_opts = vptr->options.wol_opts;
+	vptr->flags |= VELOCITY_FLAGS_WOL_ENABLED;
 
-/**
- *	velocity_mii_write	-	write MII data
- *	@regs: velocity registers
- *	@index: MII register index
- *	@data: 16bit data for the MII register
- *
- *	Perform a single write to an MII 16bit register. Returns zero
- *	on success or -ETIMEDOUT if the PHY did not respond.
- */
+	vptr->phy_id = MII_GET_PHY_ID(vptr->mac_regs);
 
-static int velocity_mii_write(struct mac_regs __iomem *regs, u8 mii_addr, u16 data)
-{
-	u16 ww;
+	dev->irq = pdev->irq;
+	dev->netdev_ops = &velocity_netdev_ops;
+	dev->ethtool_ops = &velocity_ethtool_ops;
 
-	/*
-	 *	Disable MIICR_MAUTO, so that mii addr can be set normally
-	 */
-	safe_disable_mii_autopoll(regs);
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
+		NETIF_F_HW_VLAN_RX;
 
-	/* MII reg offset */
-	writeb(mii_addr, &regs->MIIADR);
-	/* set MII data */
-	writew(data, &regs->MIIDATA);
+	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
+		dev->features |= NETIF_F_IP_CSUM;
 
-	/* turn on MIICR_WCMD */
-	BYTE_REG_BITS_ON(MIICR_WCMD, &regs->MIICR);
+	ret = register_netdev(dev);
+	if (ret < 0)
+		goto err_iounmap;
 
-	/* W_MAX_TIMEOUT is the timeout period */
-	for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
-		udelay(5);
-		if (!(readb(&regs->MIICR) & MIICR_WCMD))
-			break;
+	if (!velocity_get_link(dev)) {
+		netif_carrier_off(dev);
+		vptr->mii_status |= VELOCITY_LINK_FAIL;
 	}
-	enable_mii_autopoll(regs);
 
-	if (ww == W_MAX_TIMEOUT)
-		return -ETIMEDOUT;
-	return 0;
-}
+	velocity_print_info(vptr);
+	pci_set_drvdata(pdev, dev);
 
-/**
- *	velocity_get_opt_media_mode	-	get media selection
- *	@vptr: velocity adapter
- *
- *	Get the media mode stored in EEPROM or module options and load
- *	mii_status accordingly. The requested link state information
- *	is also returned.
- */
+	/* and leave the chip powered down */
 
-static u32 velocity_get_opt_media_mode(struct velocity_info *vptr)
-{
-	u32 status = 0;
+	pci_set_power_state(pdev, PCI_D3hot);
+#ifdef CONFIG_PM
+	{
+		unsigned long flags;
 
-	switch (vptr->options.spd_dpx) {
-	case SPD_DPX_AUTO:
-		status = VELOCITY_AUTONEG_ENABLE;
-		break;
-	case SPD_DPX_100_FULL:
-		status = VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL;
-		break;
-	case SPD_DPX_10_FULL:
-		status = VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL;
-		break;
-	case SPD_DPX_100_HALF:
-		status = VELOCITY_SPEED_100;
-		break;
-	case SPD_DPX_10_HALF:
-		status = VELOCITY_SPEED_10;
-		break;
+		spin_lock_irqsave(&velocity_dev_list_lock, flags);
+		list_add(&vptr->list, &velocity_dev_list);
+		spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
 	}
-	vptr->mii_status = status;
-	return status;
-}
-
-/**
- *	mii_set_auto_on		-	autonegotiate on
- *	@vptr: velocity
- *
- *	Enable autonegotation on this interface
- */
+#endif
+	velocity_nics++;
+out:
+	return ret;
 
-static void mii_set_auto_on(struct velocity_info *vptr)
-{
-	if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
-		MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
-	else
-		MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
+err_iounmap:
+	iounmap(regs);
+err_release_res:
+	pci_release_regions(pdev);
+err_disable:
+	pci_disable_device(pdev);
+err_free_dev:
+	free_netdev(dev);
+	goto out;
 }
 
 
-/*
-static void mii_set_auto_off(struct velocity_info * vptr)
-{
-    MII_REG_BITS_OFF(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs);
-}
-*/
-
+#ifdef CONFIG_PM
 /**
- *	set_mii_flow_control	-	flow control setup
- *	@vptr: velocity interface
+ *	wol_calc_crc		-	WOL CRC
+ *	@pattern: data pattern
+ *	@mask_pattern: mask
  *
- *	Set up the flow control on this interface according to
- *	the supplied user/eeprom options.
+ *	Compute the wake on lan crc hashes for the packet header
+ *	we are interested in.
  */
-
-static void set_mii_flow_control(struct velocity_info *vptr)
+static u16 wol_calc_crc(int size, u8 *pattern, u8 *mask_pattern)
 {
-	/*Enable or Disable PAUSE in ANAR */
-	switch (vptr->options.flow_cntl) {
-	case FLOW_CNTL_TX:
-		MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
-		MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
-		break;
+	u16 crc = 0xFFFF;
+	u8 mask;
+	int i, j;
 
-	case FLOW_CNTL_RX:
-		MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
-		MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
-		break;
+	for (i = 0; i < size; i++) {
+		mask = mask_pattern[i];
 
-	case FLOW_CNTL_TX_RX:
-		MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
-		MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
-		break;
+		/* Skip this loop if the mask equals to zero */
+		if (mask == 0x00)
+			continue;
 
-	case FLOW_CNTL_DISABLE:
-		MII_REG_BITS_OFF(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
-		MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
-		break;
-	default:
-		break;
+		for (j = 0; j < 8; j++) {
+			if ((mask & 0x01) == 0) {
+				mask >>= 1;
+				continue;
+			}
+			mask >>= 1;
+			crc = crc_ccitt(crc, &(pattern[i * 8 + j]), 1);
+		}
 	}
+	/*	Finally, invert the result once to get the correct data */
+	crc = ~crc;
+	return bitrev32(crc) >> 16;
 }
 
 /**
- *	velocity_set_media_mode		-	set media mode
- *	@mii_status: old MII link state
+ *	velocity_set_wol	-	set up for wake on lan
+ *	@vptr: velocity to set WOL status on
  *
- *	Check the media link state and configure the flow control
- *	PHY and also velocity hardware setup accordingly. In particular
- *	we need to set up CD polling and frame bursting.
+ *	Set a card up for wake on lan either by unicast or by
+ *	ARP packet.
+ *
+ *	FIXME: check static buffer is safe here
  */
-
-static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
+static int velocity_set_wol(struct velocity_info *vptr)
 {
-	u32 curr_status;
-	struct mac_regs __iomem * regs = vptr->mac_regs;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	static u8 buf[256];
+	int i;
 
-	vptr->mii_status = mii_check_media_mode(vptr->mac_regs);
-	curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL);
+	static u32 mask_pattern[2][4] = {
+		{0x00203000, 0x000003C0, 0x00000000, 0x0000000}, /* ARP */
+		{0xfffff000, 0xffffffff, 0xffffffff, 0x000ffff}	 /* Magic Packet */
+	};
 
-	/* Set mii link status */
-	set_mii_flow_control(vptr);
+	writew(0xFFFF, &regs->WOLCRClr);
+	writeb(WOLCFG_SAB | WOLCFG_SAM, &regs->WOLCFGSet);
+	writew(WOLCR_MAGIC_EN, &regs->WOLCRSet);
 
 	/*
-	   Check if new status is consisent with current status
-	   if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE)
-	   || (mii_status==curr_status)) {
-	   vptr->mii_status=mii_check_media_mode(vptr->mac_regs);
-	   vptr->mii_status=check_connection_type(vptr->mac_regs);
-	   VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n");
-	   return 0;
-	   }
+	   if (vptr->wol_opts & VELOCITY_WOL_PHY)
+	   writew((WOLCR_LINKON_EN|WOLCR_LINKOFF_EN), &regs->WOLCRSet);
 	 */
 
-	if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) {
-		MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs);
-	}
+	if (vptr->wol_opts & VELOCITY_WOL_UCAST)
+		writew(WOLCR_UNICAST_EN, &regs->WOLCRSet);
 
-	/*
-	 *	If connection type is AUTO
-	 */
-	if (mii_status & VELOCITY_AUTONEG_ENABLE) {
-		VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity is AUTO mode\n");
-		/* clear force MAC mode bit */
-		BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
-		/* set duplex mode of MAC according to duplex mode of MII */
-		MII_REG_BITS_ON(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10, MII_REG_ANAR, vptr->mac_regs);
-		MII_REG_BITS_ON(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
-		MII_REG_BITS_ON(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs);
+	if (vptr->wol_opts & VELOCITY_WOL_ARP) {
+		struct arp_packet *arp = (struct arp_packet *) buf;
+		u16 crc;
+		memset(buf, 0, sizeof(struct arp_packet) + 7);
 
-		/* enable AUTO-NEGO mode */
-		mii_set_auto_on(vptr);
-	} else {
-		u16 ANAR;
-		u8 CHIPGCR;
+		for (i = 0; i < 4; i++)
+			writel(mask_pattern[0][i], &regs->ByteMask[0][i]);
 
-		/*
-		 * 1. if it's 3119, disable frame bursting in halfduplex mode
-		 *    and enable it in fullduplex mode
-		 * 2. set correct MII/GMII and half/full duplex mode in CHIPGCR
-		 * 3. only enable CD heart beat counter in 10HD mode
-		 */
+		arp->type = htons(ETH_P_ARP);
+		arp->ar_op = htons(1);
 
-		/* set force MAC mode bit */
-		BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
+		memcpy(arp->ar_tip, vptr->ip_addr, 4);
 
-		CHIPGCR = readb(&regs->CHIPGCR);
-		CHIPGCR &= ~CHIPGCR_FCGMII;
+		crc = wol_calc_crc((sizeof(struct arp_packet) + 7) / 8, buf,
+				(u8 *) & mask_pattern[0][0]);
 
-		if (mii_status & VELOCITY_DUPLEX_FULL) {
-			CHIPGCR |= CHIPGCR_FCFDX;
-			writeb(CHIPGCR, &regs->CHIPGCR);
-			VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced full mode\n");
-			if (vptr->rev_id < REV_ID_VT3216_A0)
-				BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
-		} else {
-			CHIPGCR &= ~CHIPGCR_FCFDX;
-			VELOCITY_PRT(MSG_LEVEL_INFO, "set Velocity to forced half mode\n");
-			writeb(CHIPGCR, &regs->CHIPGCR);
-			if (vptr->rev_id < REV_ID_VT3216_A0)
-				BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
-		}
+		writew(crc, &regs->PatternCRC[0]);
+		writew(WOLCR_ARP_EN, &regs->WOLCRSet);
+	}
+
+	BYTE_REG_BITS_ON(PWCFG_WOLTYPE, &regs->PWCFGSet);
+	BYTE_REG_BITS_ON(PWCFG_LEGACY_WOLEN, &regs->PWCFGSet);
+
+	writew(0x0FFF, &regs->WOLSRClr);
+
+	if (vptr->mii_status & VELOCITY_AUTONEG_ENABLE) {
+		if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201)
+			MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs);
 
 		MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
+	}
 
-		if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10)) {
-			BYTE_REG_BITS_OFF(TESTCFG_HBDIS, &regs->TESTCFG);
-		} else {
-			BYTE_REG_BITS_ON(TESTCFG_HBDIS, &regs->TESTCFG);
-		}
-		/* MII_REG_BITS_OFF(BMCR_SPEED1G, MII_REG_BMCR, vptr->mac_regs); */
-		velocity_mii_read(vptr->mac_regs, MII_REG_ANAR, &ANAR);
-		ANAR &= (~(ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10));
-		if (mii_status & VELOCITY_SPEED_100) {
-			if (mii_status & VELOCITY_DUPLEX_FULL)
-				ANAR |= ANAR_TXFD;
-			else
-				ANAR |= ANAR_TX;
-		} else {
-			if (mii_status & VELOCITY_DUPLEX_FULL)
-				ANAR |= ANAR_10FD;
-			else
-				ANAR |= ANAR_10;
-		}
-		velocity_mii_write(vptr->mac_regs, MII_REG_ANAR, ANAR);
-		/* enable AUTO-NEGO mode */
-		mii_set_auto_on(vptr);
-		/* MII_REG_BITS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs); */
+	if (vptr->mii_status & VELOCITY_SPEED_1000)
+		MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
+
+	BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
+
+	{
+		u8 GCR;
+		GCR = readb(&regs->CHIPGCR);
+		GCR = (GCR & ~CHIPGCR_FCGMII) | CHIPGCR_FCFDX;
+		writeb(GCR, &regs->CHIPGCR);
 	}
-	/* vptr->mii_status=mii_check_media_mode(vptr->mac_regs); */
-	/* vptr->mii_status=check_connection_type(vptr->mac_regs); */
-	return VELOCITY_LINK_CHANGE;
+
+	BYTE_REG_BITS_OFF(ISR_PWEI, &regs->ISR);
+	/* Turn on SWPTAG just before entering power mode */
+	BYTE_REG_BITS_ON(STICKHW_SWPTAG, &regs->STICKHW);
+	/* Go to bed ..... */
+	BYTE_REG_BITS_ON((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
+
+	return 0;
 }
 
 /**
- *	mii_check_media_mode	-	check media state
- *	@regs: velocity registers
+ *	velocity_save_context	-	save registers
+ *	@vptr: velocity
+ *	@context: buffer for stored context
  *
- *	Check the current MII status and determine the link status
- *	accordingly
+ *	Retrieve the current configuration from the velocity hardware
+ *	and stash it in the context structure, for use by the context
+ *	restore functions. This allows us to save things we need across
+ *	power down states
  */
-
-static u32 mii_check_media_mode(struct mac_regs __iomem * regs)
+static void velocity_save_context(struct velocity_info *vptr, struct velocity_context *context)
 {
-	u32 status = 0;
-	u16 ANAR;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	u16 i;
+	u8 __iomem *ptr = (u8 __iomem *)regs;
 
-	if (!MII_REG_BITS_IS_ON(BMSR_LNK, MII_REG_BMSR, regs))
-		status |= VELOCITY_LINK_FAIL;
+	for (i = MAC_REG_PAR; i < MAC_REG_CR0_CLR; i += 4)
+		*((u32 *) (context->mac_reg + i)) = readl(ptr + i);
 
-	if (MII_REG_BITS_IS_ON(G1000CR_1000FD, MII_REG_G1000CR, regs))
-		status |= VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL;
-	else if (MII_REG_BITS_IS_ON(G1000CR_1000, MII_REG_G1000CR, regs))
-		status |= (VELOCITY_SPEED_1000);
-	else {
-		velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
-		if (ANAR & ANAR_TXFD)
-			status |= (VELOCITY_SPEED_100 | VELOCITY_DUPLEX_FULL);
-		else if (ANAR & ANAR_TX)
-			status |= VELOCITY_SPEED_100;
-		else if (ANAR & ANAR_10FD)
-			status |= (VELOCITY_SPEED_10 | VELOCITY_DUPLEX_FULL);
-		else
-			status |= (VELOCITY_SPEED_10);
-	}
+	for (i = MAC_REG_MAR; i < MAC_REG_TDCSR_CLR; i += 4)
+		*((u32 *) (context->mac_reg + i)) = readl(ptr + i);
 
-	if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
-		velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
-		if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
-		    == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
-			if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs))
-				status |= VELOCITY_AUTONEG_ENABLE;
-		}
-	}
+	for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4)
+		*((u32 *) (context->mac_reg + i)) = readl(ptr + i);
 
-	return status;
 }
 
-static u32 check_connection_type(struct mac_regs __iomem * regs)
+static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	u32 status = 0;
-	u8 PHYSR0;
-	u16 ANAR;
-	PHYSR0 = readb(&regs->PHYSR0);
-
-	/*
-	   if (!(PHYSR0 & PHYSR0_LINKGD))
-	   status|=VELOCITY_LINK_FAIL;
-	 */
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct velocity_info *vptr = netdev_priv(dev);
+	unsigned long flags;
 
-	if (PHYSR0 & PHYSR0_FDPX)
-		status |= VELOCITY_DUPLEX_FULL;
+	if (!netif_running(vptr->dev))
+		return 0;
 
-	if (PHYSR0 & PHYSR0_SPDG)
-		status |= VELOCITY_SPEED_1000;
-	else if (PHYSR0 & PHYSR0_SPD10)
-		status |= VELOCITY_SPEED_10;
-	else
-		status |= VELOCITY_SPEED_100;
+	netif_device_detach(vptr->dev);
 
-	if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, regs)) {
-		velocity_mii_read(regs, MII_REG_ANAR, &ANAR);
-		if ((ANAR & (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10))
-		    == (ANAR_TXFD | ANAR_TX | ANAR_10FD | ANAR_10)) {
-			if (MII_REG_BITS_IS_ON(G1000CR_1000 | G1000CR_1000FD, MII_REG_G1000CR, regs))
-				status |= VELOCITY_AUTONEG_ENABLE;
-		}
+	spin_lock_irqsave(&vptr->lock, flags);
+	pci_save_state(pdev);
+#ifdef ETHTOOL_GWOL
+	if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
+		velocity_get_ip(vptr);
+		velocity_save_context(vptr, &vptr->context);
+		velocity_shutdown(vptr);
+		velocity_set_wol(vptr);
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+		pci_set_power_state(pdev, PCI_D3hot);
+	} else {
+		velocity_save_context(vptr, &vptr->context);
+		velocity_shutdown(vptr);
+		pci_disable_device(pdev);
+		pci_set_power_state(pdev, pci_choose_state(pdev, state));
 	}
-
-	return status;
+#else
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#endif
+	spin_unlock_irqrestore(&vptr->lock, flags);
+	return 0;
 }
 
 /**
- *	enable_flow_control_ability	-	flow control
- *	@vptr: veloity to configure
+ *	velocity_restore_context	-	restore registers
+ *	@vptr: velocity
+ *	@context: buffer for stored context
  *
- *	Set up flow control according to the flow control options
- *	determined by the eeprom/configuration.
+ *	Reload the register configuration from the velocity context
+ *	created by velocity_save_context.
  */
-
-static void enable_flow_control_ability(struct velocity_info *vptr)
+static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
 {
+	struct mac_regs __iomem *regs = vptr->mac_regs;
+	int i;
+	u8 __iomem *ptr = (u8 __iomem *)regs;
 
-	struct mac_regs __iomem * regs = vptr->mac_regs;
+	for (i = MAC_REG_PAR; i < MAC_REG_CR0_SET; i += 4)
+		writel(*((u32 *) (context->mac_reg + i)), ptr + i);
 
-	switch (vptr->options.flow_cntl) {
+	/* Just skip cr0 */
+	for (i = MAC_REG_CR1_SET; i < MAC_REG_CR0_CLR; i++) {
+		/* Clear */
+		writeb(~(*((u8 *) (context->mac_reg + i))), ptr + i + 4);
+		/* Set */
+		writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
+	}
 
-	case FLOW_CNTL_DEFAULT:
-		if (BYTE_REG_BITS_IS_ON(PHYSR0_RXFLC, &regs->PHYSR0))
-			writel(CR0_FDXRFCEN, &regs->CR0Set);
-		else
-			writel(CR0_FDXRFCEN, &regs->CR0Clr);
+	for (i = MAC_REG_MAR; i < MAC_REG_IMR; i += 4)
+		writel(*((u32 *) (context->mac_reg + i)), ptr + i);
 
-		if (BYTE_REG_BITS_IS_ON(PHYSR0_TXFLC, &regs->PHYSR0))
-			writel(CR0_FDXTFCEN, &regs->CR0Set);
-		else
-			writel(CR0_FDXTFCEN, &regs->CR0Clr);
-		break;
+	for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4)
+		writel(*((u32 *) (context->mac_reg + i)), ptr + i);
 
-	case FLOW_CNTL_TX:
-		writel(CR0_FDXTFCEN, &regs->CR0Set);
-		writel(CR0_FDXRFCEN, &regs->CR0Clr);
-		break;
+	for (i = MAC_REG_TDCSR_SET; i <= MAC_REG_RDCSR_SET; i++)
+		writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
+}
 
-	case FLOW_CNTL_RX:
-		writel(CR0_FDXRFCEN, &regs->CR0Set);
-		writel(CR0_FDXTFCEN, &regs->CR0Clr);
-		break;
+static int velocity_resume(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct velocity_info *vptr = netdev_priv(dev);
+	unsigned long flags;
+	int i;
 
-	case FLOW_CNTL_TX_RX:
-		writel(CR0_FDXTFCEN, &regs->CR0Set);
-		writel(CR0_FDXRFCEN, &regs->CR0Set);
-		break;
+	if (!netif_running(vptr->dev))
+		return 0;
 
-	case FLOW_CNTL_DISABLE:
-		writel(CR0_FDXRFCEN, &regs->CR0Clr);
-		writel(CR0_FDXTFCEN, &regs->CR0Clr);
-		break;
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, 0, 0);
+	pci_restore_state(pdev);
 
-	default:
-		break;
+	mac_wol_reset(vptr->mac_regs);
+
+	spin_lock_irqsave(&vptr->lock, flags);
+	velocity_restore_context(vptr, &vptr->context);
+	velocity_init_registers(vptr, VELOCITY_INIT_WOL);
+	mac_disable_int(vptr->mac_regs);
+
+	velocity_tx_srv(vptr, 0);
+
+	for (i = 0; i < vptr->tx.numq; i++) {
+		if (vptr->tx.used[i])
+			mac_tx_queue_wake(vptr->mac_regs, i);
 	}
 
+	mac_enable_int(vptr->mac_regs);
+	spin_unlock_irqrestore(&vptr->lock, flags);
+	netif_device_attach(vptr->dev);
+
+	return 0;
 }
+#endif
+
+/*
+ *	Definition for our device driver. The PCI layer interface
+ *	uses this to handle all our card discover and plugging
+ */
+static struct pci_driver velocity_driver = {
+      .name	= VELOCITY_NAME,
+      .id_table	= velocity_id_table,
+      .probe	= velocity_found1,
+      .remove	= __devexit_p(velocity_remove1),
+#ifdef CONFIG_PM
+      .suspend	= velocity_suspend,
+      .resume	= velocity_resume,
+#endif
+};
 
 
 /**
@@ -2991,7 +3078,6 @@ static void enable_flow_control_ability(struct velocity_info *vptr)
  *	Called before an ethtool operation. We need to make sure the
  *	chip is out of D3 state before we poke at it.
  */
-
 static int velocity_ethtool_up(struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
@@ -3007,7 +3093,6 @@ static int velocity_ethtool_up(struct net_device *dev)
  *	Called after an ethtool operation. Restore the chip back to D3
  *	state if it isn't running.
  */
-
 static void velocity_ethtool_down(struct net_device *dev)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
@@ -3018,7 +3103,7 @@ static void velocity_ethtool_down(struct net_device *dev)
 static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
-	struct mac_regs __iomem * regs = vptr->mac_regs;
+	struct mac_regs __iomem *regs = vptr->mac_regs;
 	u32 status;
 	status = check_connection_type(vptr->mac_regs);
 
@@ -3072,13 +3157,6 @@ static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd
 	return ret;
 }
 
-static u32 velocity_get_link(struct net_device *dev)
-{
-	struct velocity_info *vptr = netdev_priv(dev);
-	struct mac_regs __iomem * regs = vptr->mac_regs;
-	return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, &regs->PHYSR0) ? 1 : 0;
-}
-
 static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
@@ -3157,338 +3235,86 @@ static const struct ethtool_ops velocity_ethtool_ops = {
 	.complete	=	velocity_ethtool_down
 };
 
-/**
- *	velocity_mii_ioctl		-	MII ioctl handler
- *	@dev: network device
- *	@ifr: the ifreq block for the ioctl
- *	@cmd: the command
- *
- *	Process MII requests made via ioctl from the network layer. These
- *	are used by tools like kudzu to interrogate the link state of the
- *	hardware
- */
-
-static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+#ifdef CONFIG_PM
+#ifdef CONFIG_INET
+static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
 {
-	struct velocity_info *vptr = netdev_priv(dev);
-	struct mac_regs __iomem * regs = vptr->mac_regs;
+	struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
+	struct net_device *dev = ifa->ifa_dev->dev;
+	struct velocity_info *vptr;
 	unsigned long flags;
-	struct mii_ioctl_data *miidata = if_mii(ifr);
-	int err;
 
-	switch (cmd) {
-	case SIOCGMIIPHY:
-		miidata->phy_id = readb(&regs->MIIADR) & 0x1f;
-		break;
-	case SIOCGMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		if(velocity_mii_read(vptr->mac_regs, miidata->reg_num & 0x1f, &(miidata->val_out)) < 0)
-			return -ETIMEDOUT;
-		break;
-	case SIOCSMIIREG:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		spin_lock_irqsave(&vptr->lock, flags);
-		err = velocity_mii_write(vptr->mac_regs, miidata->reg_num & 0x1f, miidata->val_in);
-		spin_unlock_irqrestore(&vptr->lock, flags);
-		check_connection_type(vptr->mac_regs);
-		if(err)
-			return err;
-		break;
-	default:
-		return -EOPNOTSUPP;
+	if (dev_net(dev) != &init_net)
+		return NOTIFY_DONE;
+
+	spin_lock_irqsave(&velocity_dev_list_lock, flags);
+	list_for_each_entry(vptr, &velocity_dev_list, list) {
+		if (vptr->dev == dev) {
+			velocity_get_ip(vptr);
+			break;
+		}
 	}
-	return 0;
-}
+	spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
 
-#ifdef CONFIG_PM
+	return NOTIFY_DONE;
+}
+#endif	/* CONFIG_INET */
+#endif	/* CONFIG_PM */
 
-/**
- *	velocity_save_context	-	save registers
- *	@vptr: velocity
- *	@context: buffer for stored context
- *
- *	Retrieve the current configuration from the velocity hardware
- *	and stash it in the context structure, for use by the context
- *	restore functions. This allows us to save things we need across
- *	power down states
- */
+#if defined(CONFIG_PM) && defined(CONFIG_INET)
+static struct notifier_block velocity_inetaddr_notifier = {
+      .notifier_call	= velocity_netdev_event,
+};
 
-static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
+static void velocity_register_notifier(void)
 {
-	struct mac_regs __iomem * regs = vptr->mac_regs;
-	u16 i;
-	u8 __iomem *ptr = (u8 __iomem *)regs;
-
-	for (i = MAC_REG_PAR; i < MAC_REG_CR0_CLR; i += 4)
-		*((u32 *) (context->mac_reg + i)) = readl(ptr + i);
-
-	for (i = MAC_REG_MAR; i < MAC_REG_TDCSR_CLR; i += 4)
-		*((u32 *) (context->mac_reg + i)) = readl(ptr + i);
-
-	for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4)
-		*((u32 *) (context->mac_reg + i)) = readl(ptr + i);
-
+	register_inetaddr_notifier(&velocity_inetaddr_notifier);
 }
 
-/**
- *	velocity_restore_context	-	restore registers
- *	@vptr: velocity
- *	@context: buffer for stored context
- *
- *	Reload the register configuration from the velocity context
- *	created by velocity_save_context.
- */
-
-static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
+static void velocity_unregister_notifier(void)
 {
-	struct mac_regs __iomem * regs = vptr->mac_regs;
-	int i;
-	u8 __iomem *ptr = (u8 __iomem *)regs;
-
-	for (i = MAC_REG_PAR; i < MAC_REG_CR0_SET; i += 4) {
-		writel(*((u32 *) (context->mac_reg + i)), ptr + i);
-	}
-
-	/* Just skip cr0 */
-	for (i = MAC_REG_CR1_SET; i < MAC_REG_CR0_CLR; i++) {
-		/* Clear */
-		writeb(~(*((u8 *) (context->mac_reg + i))), ptr + i + 4);
-		/* Set */
-		writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
-	}
-
-	for (i = MAC_REG_MAR; i < MAC_REG_IMR; i += 4) {
-		writel(*((u32 *) (context->mac_reg + i)), ptr + i);
-	}
+	unregister_inetaddr_notifier(&velocity_inetaddr_notifier);
+}
 
-	for (i = MAC_REG_RDBASE_LO; i < MAC_REG_FIFO_TEST0; i += 4) {
-		writel(*((u32 *) (context->mac_reg + i)), ptr + i);
-	}
+#else
 
-	for (i = MAC_REG_TDCSR_SET; i <= MAC_REG_RDCSR_SET; i++) {
-		writeb(*((u8 *) (context->mac_reg + i)), ptr + i);
-	}
+#define velocity_register_notifier()	do {} while (0)
+#define velocity_unregister_notifier()	do {} while (0)
 
-}
+#endif	/* defined(CONFIG_PM) && defined(CONFIG_INET) */
 
 /**
- *	wol_calc_crc		-	WOL CRC
- *	@pattern: data pattern
- *	@mask_pattern: mask
+ *	velocity_init_module	-	load time function
  *
- *	Compute the wake on lan crc hashes for the packet header
- *	we are interested in.
+ *	Called when the velocity module is loaded. The PCI driver
+ *	is registered with the PCI layer, and in turn will call
+ *	the probe functions for each velocity adapter installed
+ *	in the system.
  */
-
-static u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
+static int __init velocity_init_module(void)
 {
-	u16 crc = 0xFFFF;
-	u8 mask;
-	int i, j;
-
-	for (i = 0; i < size; i++) {
-		mask = mask_pattern[i];
-
-		/* Skip this loop if the mask equals to zero */
-		if (mask == 0x00)
-			continue;
+	int ret;
 
-		for (j = 0; j < 8; j++) {
-			if ((mask & 0x01) == 0) {
-				mask >>= 1;
-				continue;
-			}
-			mask >>= 1;
-			crc = crc_ccitt(crc, &(pattern[i * 8 + j]), 1);
-		}
-	}
-	/*	Finally, invert the result once to get the correct data */
-	crc = ~crc;
-	return bitrev32(crc) >> 16;
+	velocity_register_notifier();
+	ret = pci_register_driver(&velocity_driver);
+	if (ret < 0)
+		velocity_unregister_notifier();
+	return ret;
 }
 
 /**
- *	velocity_set_wol	-	set up for wake on lan
- *	@vptr: velocity to set WOL status on
- *
- *	Set a card up for wake on lan either by unicast or by
- *	ARP packet.
+ *	velocity_cleanup	-	module unload
  *
- *	FIXME: check static buffer is safe here
+ *	When the velocity hardware is unloaded this function is called.
+ *	It will clean up the notifiers and the unregister the PCI
+ *	driver interface for this hardware. This in turn cleans up
+ *	all discovered interfaces before returning from the function
  */
-
-static int velocity_set_wol(struct velocity_info *vptr)
-{
-	struct mac_regs __iomem * regs = vptr->mac_regs;
-	static u8 buf[256];
-	int i;
-
-	static u32 mask_pattern[2][4] = {
-		{0x00203000, 0x000003C0, 0x00000000, 0x0000000}, /* ARP */
-		{0xfffff000, 0xffffffff, 0xffffffff, 0x000ffff}	 /* Magic Packet */
-	};
-
-	writew(0xFFFF, &regs->WOLCRClr);
-	writeb(WOLCFG_SAB | WOLCFG_SAM, &regs->WOLCFGSet);
-	writew(WOLCR_MAGIC_EN, &regs->WOLCRSet);
-
-	/*
-	   if (vptr->wol_opts & VELOCITY_WOL_PHY)
-	   writew((WOLCR_LINKON_EN|WOLCR_LINKOFF_EN), &regs->WOLCRSet);
-	 */
-
-	if (vptr->wol_opts & VELOCITY_WOL_UCAST) {
-		writew(WOLCR_UNICAST_EN, &regs->WOLCRSet);
-	}
-
-	if (vptr->wol_opts & VELOCITY_WOL_ARP) {
-		struct arp_packet *arp = (struct arp_packet *) buf;
-		u16 crc;
-		memset(buf, 0, sizeof(struct arp_packet) + 7);
-
-		for (i = 0; i < 4; i++)
-			writel(mask_pattern[0][i], &regs->ByteMask[0][i]);
-
-		arp->type = htons(ETH_P_ARP);
-		arp->ar_op = htons(1);
-
-		memcpy(arp->ar_tip, vptr->ip_addr, 4);
-
-		crc = wol_calc_crc((sizeof(struct arp_packet) + 7) / 8, buf,
-				(u8 *) & mask_pattern[0][0]);
-
-		writew(crc, &regs->PatternCRC[0]);
-		writew(WOLCR_ARP_EN, &regs->WOLCRSet);
-	}
-
-	BYTE_REG_BITS_ON(PWCFG_WOLTYPE, &regs->PWCFGSet);
-	BYTE_REG_BITS_ON(PWCFG_LEGACY_WOLEN, &regs->PWCFGSet);
-
-	writew(0x0FFF, &regs->WOLSRClr);
-
-	if (vptr->mii_status & VELOCITY_AUTONEG_ENABLE) {
-		if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201)
-			MII_REG_BITS_ON(AUXCR_MDPPS, MII_REG_AUXCR, vptr->mac_regs);
-
-		MII_REG_BITS_OFF(G1000CR_1000FD | G1000CR_1000, MII_REG_G1000CR, vptr->mac_regs);
-	}
-
-	if (vptr->mii_status & VELOCITY_SPEED_1000)
-		MII_REG_BITS_ON(BMCR_REAUTO, MII_REG_BMCR, vptr->mac_regs);
-
-	BYTE_REG_BITS_ON(CHIPGCR_FCMODE, &regs->CHIPGCR);
-
-	{
-		u8 GCR;
-		GCR = readb(&regs->CHIPGCR);
-		GCR = (GCR & ~CHIPGCR_FCGMII) | CHIPGCR_FCFDX;
-		writeb(GCR, &regs->CHIPGCR);
-	}
-
-	BYTE_REG_BITS_OFF(ISR_PWEI, &regs->ISR);
-	/* Turn on SWPTAG just before entering power mode */
-	BYTE_REG_BITS_ON(STICKHW_SWPTAG, &regs->STICKHW);
-	/* Go to bed ..... */
-	BYTE_REG_BITS_ON((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
-
-	return 0;
-}
-
-static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
-	unsigned long flags;
-
-	if(!netif_running(vptr->dev))
-		return 0;
-
-	netif_device_detach(vptr->dev);
-
-	spin_lock_irqsave(&vptr->lock, flags);
-	pci_save_state(pdev);
-#ifdef ETHTOOL_GWOL
-	if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
-		velocity_get_ip(vptr);
-		velocity_save_context(vptr, &vptr->context);
-		velocity_shutdown(vptr);
-		velocity_set_wol(vptr);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_set_power_state(pdev, PCI_D3hot);
-	} else {
-		velocity_save_context(vptr, &vptr->context);
-		velocity_shutdown(vptr);
-		pci_disable_device(pdev);
-		pci_set_power_state(pdev, pci_choose_state(pdev, state));
-	}
-#else
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-#endif
-	spin_unlock_irqrestore(&vptr->lock, flags);
-	return 0;
-}
-
-static int velocity_resume(struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct velocity_info *vptr = netdev_priv(dev);
-	unsigned long flags;
-	int i;
-
-	if(!netif_running(vptr->dev))
-		return 0;
-
-	pci_set_power_state(pdev, PCI_D0);
-	pci_enable_wake(pdev, 0, 0);
-	pci_restore_state(pdev);
-
-	mac_wol_reset(vptr->mac_regs);
-
-	spin_lock_irqsave(&vptr->lock, flags);
-	velocity_restore_context(vptr, &vptr->context);
-	velocity_init_registers(vptr, VELOCITY_INIT_WOL);
-	mac_disable_int(vptr->mac_regs);
-
-	velocity_tx_srv(vptr, 0);
-
-	for (i = 0; i < vptr->tx.numq; i++) {
-		if (vptr->tx.used[i]) {
-			mac_tx_queue_wake(vptr->mac_regs, i);
-		}
-	}
-
-	mac_enable_int(vptr->mac_regs);
-	spin_unlock_irqrestore(&vptr->lock, flags);
-	netif_device_attach(vptr->dev);
-
-	return 0;
-}
-
-#ifdef CONFIG_INET
-
-static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
+static void __exit velocity_cleanup_module(void)
 {
-	struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
-	struct net_device *dev = ifa->ifa_dev->dev;
-	struct velocity_info *vptr;
-	unsigned long flags;
-
-	if (dev_net(dev) != &init_net)
-		return NOTIFY_DONE;
-
-	spin_lock_irqsave(&velocity_dev_list_lock, flags);
-	list_for_each_entry(vptr, &velocity_dev_list, list) {
-		if (vptr->dev == dev) {
-			velocity_get_ip(vptr);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&velocity_dev_list_lock, flags);
-
-	return NOTIFY_DONE;
+	velocity_unregister_notifier();
+	pci_unregister_driver(&velocity_driver);
 }
 
-#endif
-#endif
+module_init(velocity_init_module);
+module_exit(velocity_cleanup_module);
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 4cd3f6c..2f00c13 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -96,8 +96,8 @@
  * Bits in the CSM register
  */
 
-#define CSM_IPOK            0x40	//IP Checkusm validatiaon ok
-#define CSM_TUPOK           0x20	//TCP/UDP Checkusm validatiaon ok
+#define CSM_IPOK            0x40	//IP Checksum validation ok
+#define CSM_TUPOK           0x20	//TCP/UDP Checksum validation ok
 #define CSM_FRAG            0x10	//Fragment IP datagram
 #define CSM_IPKT            0x04	//Received an IP packet
 #define CSM_TCPKT           0x02	//Received a TCP packet
@@ -819,7 +819,7 @@ enum  velocity_owner {
  *	Bits in the EECSR register
  */
 
-#define EECSR_EMBP          0x40	/* eeprom embeded programming */
+#define EECSR_EMBP          0x40	/* eeprom embedded programming */
 #define EECSR_RELOAD        0x20	/* eeprom content reload */
 #define EECSR_DPM           0x10	/* eeprom direct programming */
 #define EECSR_ECS           0x08	/* eeprom CS pin */
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index bbedf03..32266fb 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -547,7 +547,7 @@ static void xmit_tasklet(unsigned long data)
 	netif_tx_unlock_bh(vi->dev);
 }
 
-static int start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
 
@@ -798,10 +798,11 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
 		dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid);
 }
 
-static struct ethtool_ops virtnet_ethtool_ops = {
+static const struct ethtool_ops virtnet_ethtool_ops = {
 	.set_tx_csum = virtnet_set_tx_csum,
 	.set_sg = ethtool_op_set_sg,
 	.set_tso = ethtool_op_set_tso,
+	.set_ufo = ethtool_op_set_ufo,
 	.get_link = ethtool_op_get_link,
 };
 
@@ -1036,7 +1037,7 @@ static unsigned int features[] = {
 	VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
 	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
 	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
-	VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */
+	VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
 	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
 	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
 	VIRTIO_F_NOTIFY_ON_EMPTY,
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index 58d2551..9e94c4b 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -313,14 +313,6 @@ __vxge_hw_device_reg_addr_get(struct __vxge_hw_device *hldev)
 		hldev->kdfc = (u8 __iomem *)(hldev->bar0 +
 			VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
 		break;
-	case 2:
-		hldev->kdfc = (u8 __iomem *)(hldev->bar1 +
-			VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
-		break;
-	case 4:
-		hldev->kdfc = (u8 __iomem *)(hldev->bar2 +
-			VXGE_HW_TOC_GET_KDFC_INITIAL_OFFSET(val64));
-		break;
 	default:
 		break;
 	}
@@ -831,8 +823,6 @@ vxge_hw_device_initialize(
 		sizeof(struct vxge_hw_device_config));
 
 	hldev->bar0 = attr->bar0;
-	hldev->bar1 = attr->bar1;
-	hldev->bar2 = attr->bar2;
 	hldev->pdev = attr->pdev;
 
 	hldev->uld_callbacks.link_up = attr->uld_callbacks.link_up;
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index afbdf6f..62779a5 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -682,8 +682,6 @@ struct __vxge_hw_vpath_handle{
  * @major_revision: PCI Device major revision
  * @minor_revision: PCI Device minor revision
  * @bar0: BAR0 virtual address.
- * @bar1: BAR1 virtual address.
- * @bar2: BAR2 virtual address.
  * @pdev: Physical device handle
  * @config: Confguration passed by the LL driver at initialization
  * @link_state: Link state
@@ -698,8 +696,6 @@ struct __vxge_hw_device {
 	u8				major_revision;
 	u8				minor_revision;
 	void __iomem			*bar0;
-	void __iomem			*bar1;
-	void __iomem			*bar2;
 	struct pci_dev			*pdev;
 	struct net_device		*ndev;
 	struct vxge_hw_device_config	config;
@@ -788,17 +784,13 @@ struct vxge_hw_device_hw_info {
 /**
  * struct vxge_hw_device_attr - Device memory spaces.
  * @bar0: BAR0 virtual address.
- * @bar1: BAR1 virtual address.
- * @bar2: BAR2 virtual address.
  * @pdev: PCI device object.
  *
- * Device memory spaces. Includes configuration, BAR0, BAR1, etc. per device
+ * Device memory spaces. Includes configuration, BAR0 etc. per device
  * mapped memories. Also, includes a pointer to OS-specific PCI device object.
  */
 struct vxge_hw_device_attr {
 	void __iomem		*bar0;
-	void __iomem		*bar1;
-	void __iomem		*bar2;
 	struct pci_dev 		*pdev;
 	struct vxge_hw_uld_cbs	uld_callbacks;
 };
@@ -986,7 +978,9 @@ struct __vxge_hw_fifo {
 			void *txdlh,
 			enum vxge_hw_fifo_tcode t_code,
 			void *userdata,
-			void **skb_ptr);
+			struct sk_buff ***skb_ptr,
+			int nr_skb,
+			int *more);
 
 	void (*txdl_term)(
 			void *txdlh,
@@ -1787,7 +1781,8 @@ struct vxge_hw_fifo_attr {
 			void *txdlh,
 			enum vxge_hw_fifo_tcode t_code,
 			void *userdata,
-			void **skb_ptr);
+			struct sk_buff ***skb_ptr,
+			int nr_skb, int *more);
 
 	void (*txdl_term)(
 			void *txdlh,
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 6034497..b378037 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -87,22 +87,25 @@ static inline int is_vxge_card_up(struct vxgedev *vdev)
 static inline void VXGE_COMPLETE_VPATH_TX(struct vxge_fifo *fifo)
 {
 	unsigned long flags = 0;
-	struct sk_buff *skb_ptr = NULL;
-	struct sk_buff **temp, *head, *skb;
-
-	if (spin_trylock_irqsave(&fifo->tx_lock, flags)) {
-		vxge_hw_vpath_poll_tx(fifo->handle, (void **)&skb_ptr);
-		spin_unlock_irqrestore(&fifo->tx_lock, flags);
-	}
-	/* free SKBs */
-	head = skb_ptr;
-	while (head) {
-		skb = head;
-		temp = (struct sk_buff **)&skb->cb;
-		head = *temp;
-		*temp = NULL;
-		dev_kfree_skb_irq(skb);
-	}
+	struct sk_buff **skb_ptr = NULL;
+	struct sk_buff **temp;
+#define NR_SKB_COMPLETED 128
+	struct sk_buff *completed[NR_SKB_COMPLETED];
+	int more;
+
+	do {
+		more = 0;
+		skb_ptr = completed;
+
+		if (spin_trylock_irqsave(&fifo->tx_lock, flags)) {
+			vxge_hw_vpath_poll_tx(fifo->handle, &skb_ptr,
+						NR_SKB_COMPLETED, &more);
+			spin_unlock_irqrestore(&fifo->tx_lock, flags);
+		}
+		/* free SKBs */
+		for (temp = completed; temp != skb_ptr; temp++)
+			dev_kfree_skb_irq(*temp);
+	} while (more) ;
 }
 
 static inline void VXGE_COMPLETE_ALL_TX(struct vxgedev *vdev)
@@ -283,6 +286,7 @@ vxge_rx_alloc(void *dtrh, struct vxge_ring *ring, const int skb_size)
 	skb_reserve(skb, VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN);
 
 	rx_priv->skb = skb;
+	rx_priv->skb_data = NULL;
 	rx_priv->data_size = skb_size;
 	vxge_debug_entryexit(VXGE_TRACE,
 		"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
@@ -302,7 +306,8 @@ static int vxge_rx_map(void *dtrh, struct vxge_ring *ring)
 		ring->ndev->name, __func__, __LINE__);
 	rx_priv = vxge_hw_ring_rxd_private_get(dtrh);
 
-	dma_addr = pci_map_single(ring->pdev, rx_priv->skb->data,
+	rx_priv->skb_data = rx_priv->skb->data;
+	dma_addr = pci_map_single(ring->pdev, rx_priv->skb_data,
 				rx_priv->data_size, PCI_DMA_FROMDEVICE);
 
 	if (dma_addr == 0) {
@@ -374,10 +379,10 @@ vxge_rx_complete(struct vxge_ring *ring, struct sk_buff *skb, u16 vlan,
 		if (ring->vlgrp && ext_info->vlan &&
 			(ring->vlan_tag_strip ==
 				VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
-			vlan_gro_receive(&ring->napi, ring->vlgrp,
+			vlan_gro_receive(ring->napi_p, ring->vlgrp,
 					ext_info->vlan, skb);
 		else
-			napi_gro_receive(&ring->napi, skb);
+			napi_gro_receive(ring->napi_p, skb);
 	} else {
 		if (ring->vlgrp && vlan &&
 			(ring->vlan_tag_strip ==
@@ -442,10 +447,12 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
 	vxge_hw_ring_replenish(ringh, 0);
 
 	do {
+		prefetch((char *)dtr + L1_CACHE_BYTES);
 		rx_priv = vxge_hw_ring_rxd_private_get(dtr);
 		skb = rx_priv->skb;
 		data_size = rx_priv->data_size;
 		data_dma = rx_priv->data_dma;
+		prefetch(rx_priv->skb_data);
 
 		vxge_debug_rx(VXGE_TRACE,
 			"%s: %s:%d  skb = 0x%p",
@@ -454,6 +461,8 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
 		vxge_hw_ring_rxd_1b_get(ringh, dtr, &dma_sizes);
 		pkt_length = dma_sizes;
 
+		pkt_length -= ETH_FCS_LEN;
+
 		vxge_debug_rx(VXGE_TRACE,
 			"%s: %s:%d  Packet Length = %d",
 			ring->ndev->name, __func__, __LINE__, pkt_length);
@@ -579,8 +588,6 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
 	if (first_dtr)
 		vxge_hw_ring_rxd_post_post_wmb(ringh, first_dtr);
 
-	dev->last_rx = jiffies;
-
 	vxge_debug_entryexit(VXGE_TRACE,
 				"%s:%d  Exiting...",
 				__func__, __LINE__);
@@ -598,11 +605,10 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
 enum vxge_hw_status
 vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
 		enum vxge_hw_fifo_tcode t_code, void *userdata,
-		void **skb_ptr)
+		struct sk_buff ***skb_ptr, int nr_skb, int *more)
 {
 	struct vxge_fifo *fifo = (struct vxge_fifo *)userdata;
-	struct sk_buff *skb, *head = NULL;
-	struct sk_buff **temp;
+	struct sk_buff *skb, **done_skb = *skb_ptr;
 	int pkt_cnt = 0;
 
 	vxge_debug_entryexit(VXGE_TRACE,
@@ -655,9 +661,12 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
 		fifo->stats.tx_frms++;
 		fifo->stats.tx_bytes += skb->len;
 
-		temp = (struct sk_buff **)&skb->cb;
-		*temp = head;
-		head = skb;
+		*done_skb++ = skb;
+
+		if (--nr_skb <= 0) {
+			*more = 1;
+			break;
+		}
 
 		pkt_cnt++;
 		if (pkt_cnt > fifo->indicate_max_pkts)
@@ -666,11 +675,9 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
 	} while (vxge_hw_fifo_txdl_next_completed(fifo_hw,
 				&dtr, &t_code) == VXGE_HW_OK);
 
+	*skb_ptr = done_skb;
 	vxge_wake_tx_queue(fifo, skb);
 
-	if (skb_ptr)
-		*skb_ptr = (void *) head;
-
 	vxge_debug_entryexit(VXGE_TRACE,
 				"%s: %s:%d  Exiting...",
 				fifo->ndev->name, __func__, __LINE__);
@@ -803,7 +810,7 @@ static int vxge_learn_mac(struct vxgedev *vdev, u8 *mac_header)
  * NOTE: when device cant queue the pkt, just the trans_start variable will
  * not be upadted.
 */
-static int
+static netdev_tx_t
 vxge_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct vxge_fifo *fifo = NULL;
@@ -817,7 +824,6 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
 	u64 dma_pointer;
 	struct vxge_tx_priv *txdl_priv = NULL;
 	struct __vxge_hw_fifo *fifo_hw;
-	u32 max_mss = 0x0;
 	int offload_type;
 	unsigned long flags = 0;
 	int vpath_no = 0;
@@ -894,6 +900,12 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
 		goto _exit2;
 	}
 
+	/* Last TXD?  Stop tx queue to avoid dropping packets.  TX
+	 * completion will resume the queue.
+	 */
+	if (avail == 1)
+		vxge_stop_tx_queue(fifo);
+
 	status = vxge_hw_fifo_txdl_reserve(fifo_hw, &dtr, &dtr_priv);
 	if (unlikely(status != VXGE_HW_OK)) {
 		vxge_debug_tx(VXGE_ERR,
@@ -969,10 +981,6 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		int mss = vxge_tcp_mss(skb);
 		if (mss) {
-			max_mss = dev->mtu + ETH_HLEN -
-				VXGE_HW_TCPIP_HEADER_MAX_SIZE;
-			if (mss > max_mss)
-				mss = max_mss;
 			vxge_debug_tx(VXGE_TRACE,
 				"%s: %s:%d mss = %d",
 				dev->name, __func__, __LINE__, mss);
@@ -1000,7 +1008,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
 	VXGE_COMPLETE_VPATH_TX(fifo);
 	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d  Exiting...",
 		dev->name, __func__, __LINE__);
-	return 0;
+	return NETDEV_TX_OK;
 
 _exit0:
 	vxge_debug_tx(VXGE_TRACE, "%s: pci_map_page failed", dev->name);
@@ -1024,7 +1032,7 @@ _exit2:
 	spin_unlock_irqrestore(&fifo->tx_lock, flags);
 	VXGE_COMPLETE_VPATH_TX(fifo);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -1049,6 +1057,7 @@ vxge_rx_term(void *dtrh, enum vxge_hw_rxd_state state, void *userdata)
 		rx_priv->data_size, PCI_DMA_FROMDEVICE);
 
 	dev_kfree_skb(rx_priv->skb);
+	rx_priv->skb_data = NULL;
 
 	vxge_debug_entryexit(VXGE_TRACE,
 		"%s: %s:%d  Exiting...",
@@ -2137,16 +2146,16 @@ int vxge_open_vpaths(struct vxgedev *vdev)
  */
 static irqreturn_t vxge_isr_napi(int irq, void *dev_id)
 {
-	struct __vxge_hw_device  *hldev = (struct __vxge_hw_device  *)dev_id;
-	struct vxgedev *vdev;
 	struct net_device *dev;
+	struct __vxge_hw_device *hldev;
 	u64 reason;
 	enum vxge_hw_status status;
+	struct vxgedev *vdev = (struct vxgedev *) dev_id;;
 
 	vxge_debug_intr(VXGE_TRACE, "%s:%d", __func__, __LINE__);
 
-	dev = hldev->ndev;
-	vdev = netdev_priv(dev);
+	dev = vdev->ndev;
+	hldev = (struct __vxge_hw_device *)pci_get_drvdata(vdev->pdev);
 
 	if (pci_channel_offline(vdev->pdev))
 		return IRQ_NONE;
@@ -2417,15 +2426,13 @@ static void vxge_rem_isr(struct vxgedev *vdev)
 #endif
 	if (vdev->config.intr_type == INTA) {
 			synchronize_irq(vdev->pdev->irq);
-			free_irq(vdev->pdev->irq, hldev);
+			free_irq(vdev->pdev->irq, vdev);
 	}
 }
 
 static int vxge_add_isr(struct vxgedev *vdev)
 {
 	int ret = 0;
-	struct __vxge_hw_device  *hldev =
-		(struct __vxge_hw_device  *) pci_get_drvdata(vdev->pdev);
 #ifdef CONFIG_PCI_MSI
 	int vp_idx = 0, intr_idx = 0, intr_cnt = 0, msix_idx = 0, irq_req = 0;
 	u64 function_mode = vdev->config.device_hw_info.function_mode;
@@ -2579,7 +2586,7 @@ INTA_MODE:
 	if (vdev->config.intr_type == INTA) {
 		ret = request_irq((int) vdev->pdev->irq,
 			vxge_isr_napi,
-			IRQF_SHARED, vdev->desc[0], hldev);
+			IRQF_SHARED, vdev->desc[0], vdev);
 		if (ret) {
 			vxge_debug_init(VXGE_ERR,
 				"%s %s-%d: ISR registration failed",
@@ -2712,11 +2719,15 @@ vxge_open(struct net_device *dev)
 		netif_napi_add(dev, &vdev->napi, vxge_poll_inta,
 			vdev->config.napi_weight);
 		napi_enable(&vdev->napi);
+		for (i = 0; i < vdev->no_of_vpath; i++)
+			vdev->vpaths[i].ring.napi_p = &vdev->napi;
 	} else {
 		for (i = 0; i < vdev->no_of_vpath; i++) {
 			netif_napi_add(dev, &vdev->vpaths[i].ring.napi,
 			    vxge_poll_msix, vdev->config.napi_weight);
 			napi_enable(&vdev->vpaths[i].ring.napi);
+			vdev->vpaths[i].ring.napi_p =
+				&vdev->vpaths[i].ring.napi;
 		}
 	}
 
@@ -2890,6 +2901,9 @@ int do_vxge_close(struct net_device *dev, int do_io)
 	vdev = (struct vxgedev *)netdev_priv(dev);
 	hldev = (struct __vxge_hw_device *) pci_get_drvdata(vdev->pdev);
 
+	if (unlikely(!is_vxge_card_up(vdev)))
+		return 0;
+
 	/* If vxge_handle_crit_err task is executing,
 	 * wait till it completes. */
 	while (test_and_set_bit(__VXGE_STATE_RESET_CARD, &vdev->state))
@@ -3954,6 +3968,9 @@ static pci_ers_result_t vxge_io_error_detected(struct pci_dev *pdev,
 
 	netif_device_detach(netdev);
 
+	if (state == pci_channel_io_perm_failure)
+		return PCI_ERS_RESULT_DISCONNECT;
+
 	if (netif_running(netdev)) {
 		/* Bring down the card, while avoiding PCI I/O */
 		do_vxge_close(netdev, 0);
@@ -4152,18 +4169,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 		attr.bar0,
 		(unsigned long long)pci_resource_start(pdev, 0));
 
-	attr.bar1 = pci_ioremap_bar(pdev, 2);
-	if (!attr.bar1) {
-		vxge_debug_init(VXGE_ERR,
-			"%s : cannot remap io memory bar2", __func__);
-		ret = -ENODEV;
-		goto _exit3;
-	}
-	vxge_debug_ll_config(VXGE_TRACE,
-		"pci ioremap bar1: %p:0x%llx",
-		attr.bar1,
-		(unsigned long long)pci_resource_start(pdev, 2));
-
 	status = vxge_hw_device_hw_info_get(attr.bar0,
 			&ll_config.device_hw_info);
 	if (status != VXGE_HW_OK) {
@@ -4171,17 +4176,17 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 			"%s: Reading of hardware info failed."
 			"Please try upgrading the firmware.", VXGE_DRIVER_NAME);
 		ret = -EINVAL;
-		goto _exit4;
+		goto _exit3;
 	}
 
 	if (ll_config.device_hw_info.fw_version.major !=
-		VXGE_DRIVER_VERSION_MAJOR) {
+		VXGE_DRIVER_FW_VERSION_MAJOR) {
 		vxge_debug_init(VXGE_ERR,
-			"FW Ver.(maj): %d not driver's expected version: %d",
-			ll_config.device_hw_info.fw_version.major,
-			VXGE_DRIVER_VERSION_MAJOR);
+			"%s: Incorrect firmware version."
+			"Please upgrade the firmware to version 1.x.x",
+			VXGE_DRIVER_NAME);
 		ret = -EINVAL;
-		goto _exit4;
+		goto _exit3;
 	}
 
 	vpath_mask = ll_config.device_hw_info.vpath_mask;
@@ -4189,7 +4194,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 		vxge_debug_ll_config(VXGE_TRACE,
 			"%s: No vpaths available in device", VXGE_DRIVER_NAME);
 		ret = -EINVAL;
-		goto _exit4;
+		goto _exit3;
 	}
 
 	vxge_debug_ll_config(VXGE_TRACE,
@@ -4222,7 +4227,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 		vxge_debug_ll_config(VXGE_ERR,
 			"%s: No more vpaths to configure", VXGE_DRIVER_NAME);
 		ret = 0;
-		goto _exit4;
+		goto _exit3;
 	}
 
 	/* Setting driver callbacks */
@@ -4235,7 +4240,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 		vxge_debug_init(VXGE_ERR,
 			"Failed to initialize device (%d)", status);
 			ret = -EINVAL;
-			goto _exit4;
+			goto _exit3;
 	}
 
 	vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
@@ -4260,7 +4265,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 	if (vxge_device_register(hldev, &ll_config, high_dma, no_of_vpath,
 		&vdev)) {
 		ret = -EINVAL;
-		goto _exit5;
+		goto _exit4;
 	}
 
 	vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL);
@@ -4271,7 +4276,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 	hldev->ndev = vdev->ndev;
 	vdev->mtu = VXGE_HW_DEFAULT_MTU;
 	vdev->bar0 = attr.bar0;
-	vdev->bar1 = attr.bar1;
 	vdev->max_vpath_supported = max_vpath_supported;
 	vdev->no_of_vpath = no_of_vpath;
 
@@ -4336,6 +4340,27 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 		ll_config.device_hw_info.fw_version.version,
 		ll_config.device_hw_info.fw_date.date);
 
+	if (new_device) {
+		switch (ll_config.device_hw_info.function_mode) {
+		case VXGE_HW_FUNCTION_MODE_SINGLE_FUNCTION:
+			vxge_debug_init(VXGE_TRACE,
+			"%s: Single Function Mode Enabled", vdev->ndev->name);
+		break;
+		case VXGE_HW_FUNCTION_MODE_MULTI_FUNCTION:
+			vxge_debug_init(VXGE_TRACE,
+			"%s: Multi Function Mode Enabled", vdev->ndev->name);
+		break;
+		case VXGE_HW_FUNCTION_MODE_SRIOV:
+			vxge_debug_init(VXGE_TRACE,
+			"%s: Single Root IOV Mode Enabled", vdev->ndev->name);
+		break;
+		case VXGE_HW_FUNCTION_MODE_MRIOV:
+			vxge_debug_init(VXGE_TRACE,
+			"%s: Multi Root IOV Mode Enabled", vdev->ndev->name);
+		break;
+		}
+	}
+
 	vxge_print_parm(vdev, vpath_mask);
 
 	/* Store the fw version for ethttool option */
@@ -4353,7 +4378,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 				"%s: mac_addr_list : memory allocation failed",
 				vdev->ndev->name);
 			ret = -EPERM;
-			goto _exit6;
+			goto _exit5;
 		}
 		macaddr = (u8 *)&entry->macaddr;
 		memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN);
@@ -4361,6 +4386,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 		vdev->vpaths[i].mac_addr_cnt = 1;
 	}
 
+	kfree(device_config);
 	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d  Exiting...",
 		vdev->ndev->name, __func__, __LINE__);
 
@@ -4370,16 +4396,14 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
 
 	return 0;
 
-_exit6:
+_exit5:
 	for (i = 0; i < vdev->no_of_vpath; i++)
 		vxge_free_mac_add_list(&vdev->vpaths[i]);
 
 	vxge_device_unregister(hldev);
-_exit5:
+_exit4:
 	pci_disable_sriov(pdev);
 	vxge_hw_device_terminate(hldev);
-_exit4:
-	iounmap(attr.bar1);
 _exit3:
 	iounmap(attr.bar0);
 _exit2:
@@ -4438,7 +4462,6 @@ vxge_remove(struct pci_dev *pdev)
 	kfree(vdev->vpaths);
 
 	iounmap(vdev->bar0);
-	iounmap(vdev->bar1);
 
 	pci_disable_sriov(pdev);
 
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 9704b2b..9c36b3a 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -21,7 +21,7 @@
 
 #define VXGE_DRIVER_NAME		"vxge"
 #define VXGE_DRIVER_VENDOR		"Neterion, Inc"
-#define VXGE_DRIVER_VERSION_MAJOR 0
+#define VXGE_DRIVER_FW_VERSION_MAJOR	1
 
 #define DRV_VERSION	VXGE_VERSION_MAJOR"."VXGE_VERSION_MINOR"."\
 	VXGE_VERSION_FIX"."VXGE_VERSION_BUILD"-"\
@@ -260,6 +260,7 @@ struct vxge_ring {
 	int gro_enable;
 
 	struct napi_struct napi;
+	struct napi_struct *napi_p;
 
 #define VXGE_MAX_MAC_ADDR_COUNT		30
 
@@ -363,7 +364,6 @@ struct vxgedev {
 
 	struct __vxge_hw_vpath_handle *vp_handles[VXGE_HW_MAX_VIRTUAL_PATHS];
 	void __iomem *bar0;
-	void __iomem *bar1;
 	struct vxge_sw_stats	stats;
 	int		mtu;
 	/* Below variables are used for vpath selection to transmit a packet */
@@ -378,6 +378,7 @@ struct vxgedev {
 
 struct vxge_rx_priv {
 	struct sk_buff		*skb;
+	unsigned char		*skb_data;
 	dma_addr_t		data_dma;
 	dma_addr_t		data_size;
 };
@@ -428,7 +429,8 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr,
 
 enum vxge_hw_status
 vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
-	enum vxge_hw_fifo_tcode t_code, void *userdata, void **skb_ptr);
+	enum vxge_hw_fifo_tcode t_code, void *userdata,
+	struct sk_buff ***skb_ptr, int nr_skbs, int *more);
 
 int vxge_close(struct net_device *dev);
 
diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h
index 10f4da3..9a3b823 100644
--- a/drivers/net/vxge/vxge-reg.h
+++ b/drivers/net/vxge/vxge-reg.h
@@ -1784,7 +1784,7 @@ struct vxge_hw_mrpcim_reg {
 #define	VXGE_HW_XMAC_GEN_ERR_REG_XMACJ_XMAC_FSM_ERR	vxge_mBIT(63)
 /*0x01e18*/	u64	xmac_gen_err_mask;
 /*0x01e20*/	u64	xmac_gen_err_alarm;
-/*0x01e28*/	u64	xmac_link_err_port_reg[2];
+/*0x01e28*/	u64	xmac_link_err_port0_reg;
 #define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_DOWN	vxge_mBIT(3)
 #define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_UP	vxge_mBIT(7)
 #define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMACJ_PORT_WENT_DOWN	vxge_mBIT(11)
@@ -1798,8 +1798,11 @@ struct vxge_hw_mrpcim_reg {
 #define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_RATEMGMT_LASI_INV	vxge_mBIT(39)
 #define	VXGE_HW_XMAC_LINK_ERR_PORT_REG_XMDIO_MDIO_MGR_ACCESS_COMPLETE \
 								vxge_mBIT(47)
-/*0x01e30*/	u64	xmac_link_err_port_mask[2];
-/*0x01e38*/	u64	xmac_link_err_port_alarm[2];
+/*0x01e30*/	u64	xmac_link_err_port0_mask;
+/*0x01e38*/	u64	xmac_link_err_port0_alarm;
+/*0x01e40*/	u64	xmac_link_err_port1_reg;
+/*0x01e48*/	u64	xmac_link_err_port1_mask;
+/*0x01e50*/	u64	xmac_link_err_port1_alarm;
 /*0x01e58*/	u64	xgxs_gen_err_reg;
 #define	VXGE_HW_XGXS_GEN_ERR_REG_XGXS_XGXS_FSM_ERR	vxge_mBIT(63)
 /*0x01e60*/	u64	xgxs_gen_err_mask;
diff --git a/drivers/net/vxge/vxge-traffic.c b/drivers/net/vxge/vxge-traffic.c
index 370f55c..fe3ae51 100644
--- a/drivers/net/vxge/vxge-traffic.c
+++ b/drivers/net/vxge/vxge-traffic.c
@@ -731,6 +731,7 @@ vxge_hw_channel_dtr_try_complete(struct __vxge_hw_channel *channel, void **dtrh)
 	vxge_assert(channel->compl_index < channel->length);
 
 	*dtrh =	channel->work_arr[channel->compl_index];
+	prefetch(*dtrh);
 }
 
 /*
@@ -1070,11 +1071,11 @@ static void __vxge_hw_non_offload_db_post(struct __vxge_hw_fifo *fifo,
 		VXGE_HW_NODBW_GET_NO_SNOOP(no_snoop),
 		&fifo->nofl_db->control_0);
 
-	wmb();
+	mmiowb();
 
 	writeq(txdl_ptr, &fifo->nofl_db->txdl_ptr);
-	wmb();
 
+	mmiowb();
 }
 
 /**
@@ -2508,7 +2509,8 @@ enum vxge_hw_status vxge_hw_vpath_poll_rx(struct __vxge_hw_ring *ring)
  * See also: vxge_hw_vpath_poll_tx().
  */
 enum vxge_hw_status vxge_hw_vpath_poll_tx(struct __vxge_hw_fifo *fifo,
-					void **skb_ptr)
+					struct sk_buff ***skb_ptr, int nr_skb,
+					int *more)
 {
 	enum vxge_hw_fifo_tcode t_code;
 	void *first_txdlh;
@@ -2520,8 +2522,8 @@ enum vxge_hw_status vxge_hw_vpath_poll_tx(struct __vxge_hw_fifo *fifo,
 	status = vxge_hw_fifo_txdl_next_completed(fifo,
 				&first_txdlh, &t_code);
 	if (status == VXGE_HW_OK)
-		if (fifo->callback(fifo, first_txdlh,
-			t_code, channel->userdata, skb_ptr) != VXGE_HW_OK)
+		if (fifo->callback(fifo, first_txdlh, t_code,
+			channel->userdata, skb_ptr, nr_skb, more) != VXGE_HW_OK)
 			status = VXGE_HW_COMPLETIONS_REMAIN;
 
 	return status;
diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h
index 7567a11..461742b 100644
--- a/drivers/net/vxge/vxge-traffic.h
+++ b/drivers/net/vxge/vxge-traffic.h
@@ -35,8 +35,6 @@
 			VXGE_HW_HEADER_VLAN_SIZE + \
 			VXGE_HW_HEADER_SNAP_SIZE)
 
-#define VXGE_HW_TCPIP_HEADER_MAX_SIZE	(64 + 64)
-
 /* 32bit alignments */
 #define VXGE_HW_HEADER_ETHERNET_II_802_3_ALIGN		2
 #define VXGE_HW_HEADER_802_2_SNAP_ALIGN			2
@@ -2328,7 +2326,7 @@ enum vxge_hw_status vxge_hw_vpath_poll_rx(
 
 enum vxge_hw_status vxge_hw_vpath_poll_tx(
 	struct __vxge_hw_fifo *fifoh,
-	void **skb_ptr);
+	struct sk_buff ***skb_ptr, int nr_skb, int *more);
 
 enum vxge_hw_status vxge_hw_vpath_alarm_process(
 	struct __vxge_hw_vpath_handle *vpath_handle,
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h
index 82786ff..8fbce75 100644
--- a/drivers/net/vxge/vxge-version.h
+++ b/drivers/net/vxge/vxge-version.h
@@ -17,7 +17,7 @@
 
 #define VXGE_VERSION_MAJOR	"2"
 #define VXGE_VERSION_MINOR	"0"
-#define VXGE_VERSION_FIX	"4"
-#define VXGE_VERSION_BUILD	"17795"
+#define VXGE_VERSION_FIX	"5"
+#define VXGE_VERSION_BUILD	"18053"
 #define VXGE_VERSION_FOR	"k"
 #endif
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 61581ee..66360a2 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -279,7 +279,7 @@ static int cosa_net_attach(struct net_device *dev, unsigned short encoding,
 static int cosa_net_open(struct net_device *d);
 static int cosa_net_close(struct net_device *d);
 static void cosa_net_timeout(struct net_device *d);
-static int cosa_net_tx(struct sk_buff *skb, struct net_device *d);
+static netdev_tx_t cosa_net_tx(struct sk_buff *skb, struct net_device *d);
 static char *cosa_net_setup_rx(struct channel_data *channel, int size);
 static int cosa_net_rx_done(struct channel_data *channel);
 static int cosa_net_tx_done(struct channel_data *channel, int size);
@@ -672,7 +672,8 @@ static int cosa_net_open(struct net_device *dev)
 	return 0;
 }
 
-static int cosa_net_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t cosa_net_tx(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct channel_data *chan = dev_to_chan(dev);
 
@@ -680,7 +681,7 @@ static int cosa_net_tx(struct sk_buff *skb, struct net_device *dev)
 
 	chan->tx_skb = skb;
 	cosa_start_tx(chan, skb->data, skb->len);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void cosa_net_timeout(struct net_device *dev)
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index f525f9f..2573c18 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -139,8 +139,8 @@ static int cycx_netdevice_hard_header(struct sk_buff *skb,
 				      const void *daddr, const void *saddr,
 				      unsigned len);
 static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
-static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
-					  struct net_device *dev);
+static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
+							struct net_device *dev);
 
 static struct net_device_stats *
 			cycx_netdevice_get_stats(struct net_device *dev);
@@ -593,8 +593,8 @@ static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
  *    bottom half" (with interrupts enabled).
  * 2. Setting tbusy flag will inhibit further transmit requests from the
  *    protocol stack and can be used for flow control with protocol layer. */
-static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
-					  struct net_device *dev)
+static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
+							struct net_device *dev)
 {
 	struct cycx_x25_channel *chan = netdev_priv(dev);
 	struct cycx_device *card = chan->card;
@@ -663,7 +663,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
 free_packet:
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* Get Ethernet-style interface statistics.
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c
index 2fa275a..15d353f 100644
--- a/drivers/net/wan/dlci.c
+++ b/drivers/net/wan/dlci.c
@@ -186,45 +186,13 @@ static void dlci_receive(struct sk_buff *skb, struct net_device *dev)
 		dev_kfree_skb(skb);
 }
 
-static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t dlci_transmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct dlci_local *dlp;
-	int					ret;
-
-	ret = 0;
-
-	if (!skb || !dev)
-		return(0);
-
-	dlp = netdev_priv(dev);
-
-	netif_stop_queue(dev);
-	
-	ret = dlp->slave->netdev_ops->ndo_start_xmit(skb, dlp->slave);
-	switch (ret)
-	{
-		case DLCI_RET_OK:
-			dev->stats.tx_packets++;
-			ret = NETDEV_TX_OK;
-			break;
-			case DLCI_RET_ERR:
-			dev->stats.tx_errors++;
-			ret = NETDEV_TX_OK;
-			break;
-			case DLCI_RET_DROP:
-			dev->stats.tx_dropped++;
-			ret = NETDEV_TX_BUSY;
-			break;
-	}
-	/* Alan Cox recommends always returning 0, and always freeing the packet */
-	/* experience suggest a slightly more conservative approach */
+	struct dlci_local *dlp = netdev_priv(dev);
 
-	if (!ret)
-	{
-		dev_kfree_skb(skb);
-		netif_wake_queue(dev);
-	}
-	return(ret);
+	if (skb)
+		dlp->slave->netdev_ops->ndo_start_xmit(skb, dlp->slave);
+	return NETDEV_TX_OK;
 }
 
 static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, int get)
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 8face5d..81c8aec 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -359,7 +359,8 @@ static void dscc4_tx_irq(struct dscc4_pci_priv *, struct dscc4_dev_priv *);
 static int dscc4_found1(struct pci_dev *, void __iomem *ioaddr);
 static int dscc4_init_one(struct pci_dev *, const struct pci_device_id *ent);
 static int dscc4_open(struct net_device *);
-static int dscc4_start_xmit(struct sk_buff *, struct net_device *);
+static netdev_tx_t dscc4_start_xmit(struct sk_buff *,
+					  struct net_device *);
 static int dscc4_close(struct net_device *);
 static int dscc4_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int dscc4_init_ring(struct net_device *);
@@ -663,12 +664,12 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
 	} else {
 		if (skb->data[pkt_len] & FrameRdo)
 			dev->stats.rx_fifo_errors++;
-		else if (!(skb->data[pkt_len] | ~FrameCrc))
+		else if (!(skb->data[pkt_len] & FrameCrc))
 			dev->stats.rx_crc_errors++;
-		else if (!(skb->data[pkt_len] | ~(FrameVfr | FrameRab)))
+		else if ((skb->data[pkt_len] & (FrameVfr | FrameRab)) !=
+			 (FrameVfr | FrameRab))
 			dev->stats.rx_length_errors++;
-		else
-			dev->stats.rx_errors++;
+		dev->stats.rx_errors++;
 		dev_kfree_skb_irq(skb);
 	}
 refill:
@@ -1148,7 +1149,8 @@ static int dscc4_tx_poll(struct dscc4_dev_priv *dpriv, struct net_device *dev)
 }
 #endif /* DSCC4_POLLING */
 
-static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t dscc4_start_xmit(struct sk_buff *skb,
+					  struct net_device *dev)
 {
 	struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
 	struct dscc4_pci_priv *ppriv = dpriv->pci_priv;
@@ -1182,7 +1184,7 @@ static int dscc4_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (dscc4_tx_quiescent(dpriv, dev))
 		dscc4_do_tx(dpriv, dev);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int dscc4_close(struct net_device *dev)
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 25c9ef6..3e90eb8 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -792,25 +792,6 @@ fst_process_rx_status(int rx_status, char *name)
 			 */
 			break;
 		}
-
-	case NET_RX_CN_LOW:
-		{
-			dbg(DBG_ASS, "%s: Receive Low Congestion\n", name);
-			break;
-		}
-
-	case NET_RX_CN_MOD:
-		{
-			dbg(DBG_ASS, "%s: Receive Moderate Congestion\n", name);
-			break;
-		}
-
-	case NET_RX_CN_HIGH:
-		{
-			dbg(DBG_ASS, "%s: Receive High Congestion\n", name);
-			break;
-		}
-
 	case NET_RX_DROP:
 		{
 			dbg(DBG_ASS, "%s: Received packet dropped\n", name);
@@ -2293,7 +2274,7 @@ fst_tx_timeout(struct net_device *dev)
 	port->start = 0;
 }
 
-static int
+static netdev_tx_t
 fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fst_card_info *card;
@@ -2313,7 +2294,7 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		dbg(DBG_ASS,
 		    "Tried to transmit but no carrier on card %d port %d\n",
 		    card->card_no, port->index);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* Drop it if it's too big! MTU failure ? */
@@ -2322,7 +2303,7 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		    LEN_TX_BUFFER);
 		dev_kfree_skb(skb);
 		dev->stats.tx_errors++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/*
@@ -2356,7 +2337,7 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		dev->stats.tx_errors++;
 		dbg(DBG_ASS, "Tx queue overflow card %d port %d\n",
 		    card->card_no, port->index);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/*
@@ -2373,7 +2354,7 @@ fst_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	fst_q_work_item(&fst_work_txq, card->card_no);
 	tasklet_schedule(&fst_tx_task);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/wan/hd64570.c b/drivers/net/wan/hd64570.c
index 1ea1ef6..80114c9 100644
--- a/drivers/net/wan/hd64570.c
+++ b/drivers/net/wan/hd64570.c
@@ -620,7 +620,7 @@ static void sca_dump_rings(struct net_device *dev)
 #endif /* DEBUG_RINGS */
 
 
-static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sca_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
 	card_t *card = port_to_card(port);
@@ -674,7 +674,7 @@ static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irq(&port->lock);
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c
index f099c34..84f0137 100644
--- a/drivers/net/wan/hd64572.c
+++ b/drivers/net/wan/hd64572.c
@@ -562,7 +562,7 @@ static void sca_dump_rings(struct net_device *dev)
 #endif /* DEBUG_RINGS */
 
 
-static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sca_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
 	card_t *card = port->card;
@@ -601,7 +601,7 @@ static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irq(&port->lock);
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 7596eae..cc07236 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -66,7 +66,7 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
 	return hdlc->proto->netif_rx(skb);
 }
 
-int hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index bfa0161..840cff7 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -407,7 +407,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	return -EINVAL;
 }
 
-static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t pvc_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	pvc_device *pvc = dev->ml_priv;
 
@@ -421,7 +421,7 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
 							     GFP_ATOMIC)) {
 						dev->stats.tx_dropped++;
 						dev_kfree_skb(skb);
-						return 0;
+						return NETDEV_TX_OK;
 					}
 				skb_put(skb, pad);
 				memset(skb->data + len, 0, pad);
@@ -435,13 +435,13 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
 				dev->stats.tx_compressed++;
 			skb->dev = pvc->frad;
 			dev_queue_xmit(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 	}
 
 	dev->stats.tx_dropped++;
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static inline void fr_log_dlci_active(pvc_device *pvc)
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 72a7cda..b9b9d6b 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -389,6 +389,7 @@ static void ppp_cp_parse_cr(struct net_device *dev, u16 pid, u8 id,
 	for (opt = data; len; len -= opt[1], opt += opt[1]) {
 		if (len < 2 || len < opt[1]) {
 			dev->stats.rx_errors++;
+			kfree(out);
 			return; /* bad packet, drop silently */
 		}
 
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 49e68f5..1b30fcc 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -25,7 +25,7 @@
 
 static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
 
-static int eth_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t eth_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	int pad = ETH_ZLEN - skb->len;
 	if (pad > 0) {		/* Pad the frame with zeros */
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index b1dc29e..aa9248f 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -87,7 +87,7 @@ static void x25_data_transmit(struct net_device *dev, struct sk_buff *skb)
 
 
 
-static int x25_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	int result;
 
@@ -98,7 +98,7 @@ static int x25_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb_pull(skb, 1);
 		if ((result = lapb_data_request(dev, skb)) != LAPB_OK)
 			dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 
 	case 1:
 		if ((result = lapb_connect_request(dev))!= LAPB_OK) {
@@ -129,7 +129,7 @@ static int x25_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index 567d4f5..15002c3 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -156,7 +156,8 @@ static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
  *	Passed network frames, fire them downwind.
  */
 
-static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d)
+static netdev_tx_t hostess_queue_xmit(struct sk_buff *skb,
+					    struct net_device *d)
 {
 	return z8530_queue_xmit(&dev_to_sv(d)->chanA, skb);
 }
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index bb719b6..c705046 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -166,6 +166,29 @@
 #define CLK46X_SPEED_4096KHZ	((   16 << 22) | (280 << 12) | 1023)
 #define CLK46X_SPEED_8192KHZ	((    8 << 22) | (280 << 12) | 2047)
 
+/*
+ * HSS_CONFIG_CLOCK_CR register consists of 3 parts:
+ *     A (10 bits), B (10 bits) and C (12 bits).
+ * IXP42x HSS clock generator operation (verified with an oscilloscope):
+ * Each clock bit takes 7.5 ns (1 / 133.xx MHz).
+ * The clock sequence consists of (C - B) states of 0s and 1s, each state is
+ * A bits wide. It's followed by (B + 1) states of 0s and 1s, each state is
+ * (A + 1) bits wide.
+ *
+ * The resulting average clock frequency (assuming 33.333 MHz oscillator) is:
+ * freq = 66.666 MHz / (A + (B + 1) / (C + 1))
+ * minumum freq = 66.666 MHz / (A + 1)
+ * maximum freq = 66.666 MHz / A
+ *
+ * Example: A = 2, B = 2, C = 7, CLOCK_CR register = 2 << 22 | 2 << 12 | 7
+ * freq = 66.666 MHz / (2 + (2 + 1) / (7 + 1)) = 28.07 MHz (Mb/s).
+ * The clock sequence is: 1100110011 (5 doubles) 000111000 (3 triples).
+ * The sequence takes (C - B) * A + (B + 1) * (A + 1) = 5 * 2 + 3 * 3 bits
+ * = 19 bits (each 7.5 ns long) = 142.5 ns (then the sequence repeats).
+ * The sequence consists of 4 complete clock periods, thus the average
+ * frequency (= clock rate) is 4 / 142.5 ns = 28.07 MHz (Mb/s).
+ * (max specified clock rate for IXP42x HSS is 8.192 Mb/s).
+ */
 
 /* hss_config, LUT entries */
 #define TDMMAP_UNASSIGNED	0
@@ -239,6 +262,7 @@ struct port {
 	unsigned int clock_type, clock_rate, loopback;
 	unsigned int initialized, carrier;
 	u8 hdlc_cfg;
+	u32 clock_reg;
 };
 
 /* NPE message structure */
@@ -393,7 +417,7 @@ static void hss_config(struct port *port)
 	msg.cmd = PORT_CONFIG_WRITE;
 	msg.hss_port = port->id;
 	msg.index = HSS_CONFIG_CLOCK_CR;
-	msg.data32 = CLK42X_SPEED_2048KHZ /* FIXME */;
+	msg.data32 = port->clock_reg;
 	hss_npe_send(port, &msg, "HSS_SET_CLOCK_CR");
 
 	memset(&msg, 0, sizeof(msg));
@@ -1160,6 +1184,62 @@ static int hss_hdlc_attach(struct net_device *dev, unsigned short encoding,
 	}
 }
 
+static u32 check_clock(u32 rate, u32 a, u32 b, u32 c,
+		       u32 *best, u32 *best_diff, u32 *reg)
+{
+	/* a is 10-bit, b is 10-bit, c is 12-bit */
+	u64 new_rate;
+	u32 new_diff;
+
+	new_rate = ixp4xx_timer_freq * (u64)(c + 1);
+	do_div(new_rate, a * (c + 1) + b + 1);
+	new_diff = abs((u32)new_rate - rate);
+
+	if (new_diff < *best_diff) {
+		*best = new_rate;
+		*best_diff = new_diff;
+		*reg = (a << 22) | (b << 12) | c;
+	}
+	return new_diff;
+}
+
+static void find_best_clock(u32 rate, u32 *best, u32 *reg)
+{
+	u32 a, b, diff = 0xFFFFFFFF;
+
+	a = ixp4xx_timer_freq / rate;
+
+	if (a > 0x3FF) { /* 10-bit value - we can go as slow as ca. 65 kb/s */
+		check_clock(rate, 0x3FF, 1, 1, best, &diff, reg);
+		return;
+	}
+	if (a == 0) { /* > 66.666 MHz */
+		a = 1; /* minimum divider is 1 (a = 0, b = 1, c = 1) */
+		rate = ixp4xx_timer_freq;
+	}
+
+	if (rate * a == ixp4xx_timer_freq) { /* don't divide by 0 later */
+		check_clock(rate, a - 1, 1, 1, best, &diff, reg);
+		return;
+	}
+
+	for (b = 0; b < 0x400; b++) {
+		u64 c = (b + 1) * (u64)rate;
+		do_div(c, ixp4xx_timer_freq - rate * a);
+		c--;
+		if (c >= 0xFFF) { /* 12-bit - no need to check more 'b's */
+			if (b == 0 && /* also try a bit higher rate */
+			    !check_clock(rate, a - 1, 1, 1, best, &diff, reg))
+				return;
+			check_clock(rate, a, b, 0xFFF, best, &diff, reg);
+			return;
+		}
+		if (!check_clock(rate, a, b, c, best, &diff, reg))
+			return;
+		if (!check_clock(rate, a, b, c + 1, best, &diff, reg))
+			return;
+	}
+}
 
 static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -1182,7 +1262,7 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		}
 		memset(&new_line, 0, sizeof(new_line));
 		new_line.clock_type = port->clock_type;
-		new_line.clock_rate = 2048000; /* FIXME */
+		new_line.clock_rate = port->clock_rate;
 		new_line.loopback = port->loopback;
 		if (copy_to_user(line, &new_line, size))
 			return -EFAULT;
@@ -1206,7 +1286,13 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			return -EINVAL;
 
 		port->clock_type = clk; /* Update settings */
-		/* FIXME port->clock_rate = new_line.clock_rate */;
+		if (clk == CLOCK_INT)
+			find_best_clock(new_line.clock_rate, &port->clock_rate,
+					&port->clock_reg);
+		else {
+			port->clock_rate = 0;
+			port->clock_reg = CLK42X_SPEED_2048KHZ;
+		}
 		port->loopback = new_line.loopback;
 
 		spin_lock_irqsave(&npe_lock, flags);
@@ -1266,7 +1352,8 @@ static int __devinit hss_init_one(struct platform_device *pdev)
 	dev->netdev_ops = &hss_hdlc_ops;
 	dev->tx_queue_len = 100;
 	port->clock_type = CLOCK_EXT;
-	port->clock_rate = 2048000;
+	port->clock_rate = 0;
+	port->clock_reg = CLK42X_SPEED_2048KHZ;
 	port->id = pdev->id;
 	port->dev = &pdev->dev;
 	port->plat = pdev->dev.platform_data;
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
index aff4f6b..d1e3c67 100644
--- a/drivers/net/wan/lapbether.c
+++ b/drivers/net/wan/lapbether.c
@@ -147,7 +147,8 @@ static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb)
 /*
  *	Send a LAPB frame via an ethernet interface
  */
-static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lapbeth_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	int err;
 
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 45b1822..7ea71b3 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -89,7 +89,8 @@ MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
 MODULE_LICENSE("GPL v2");
 
 
-static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t lmc_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static int lmc_rx (struct net_device *dev);
 static int lmc_open(struct net_device *dev);
 static int lmc_close(struct net_device *dev);
@@ -1423,12 +1424,12 @@ lmc_int_fail_out:
     return IRQ_RETVAL(handled);
 }
 
-static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lmc_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
     lmc_softc_t *sc = dev_to_sc(dev);
     u32 flag;
     int entry;
-    int ret = 0;
     unsigned long flags;
 
     lmc_trace(dev, "lmc_start_xmit in");
@@ -1510,7 +1511,7 @@ static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev)
     spin_unlock_irqrestore(&sc->lmc_lock, flags);
 
     lmc_trace(dev, "lmc_start_xmit_out");
-    return ret;
+    return NETDEV_TX_OK;
 }
 
 
@@ -1657,7 +1658,7 @@ static int lmc_rx(struct net_device *dev)
             }
             skb_copy_from_linear_data(skb, skb_put(nsb, len), len);
             
-            nsb->protocol = lmc_proto_type(sc, skb);
+            nsb->protocol = lmc_proto_type(sc, nsb);
             skb_reset_mac_header(nsb);
             /* skb_reset_network_header(nsb); */
             nsb->dev = dev;
@@ -1897,11 +1898,12 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
     /*
      * Sets end of ring
      */
-    sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */
-    sc->lmc_rxring[i - 1].buffer2 = virt_to_bus (&sc->lmc_rxring[0]); /* Point back to the start */
+    if (i != 0) {
+        sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */
+        sc->lmc_rxring[i - 1].buffer2 = virt_to_bus(&sc->lmc_rxring[0]); /* Point back to the start */
+    }
     LMC_CSR_WRITE (sc, csr_rxlist, virt_to_bus (sc->lmc_rxring)); /* write base address */
 
-
     /* Initialize the transmit rings and buffers */
     for (i = 0; i < LMC_TXDESCS; i++)
     {
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index e035d8c..a52f29c 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -360,15 +360,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 	       " %u RX packets rings\n", ramsize / 1024, ramphys,
 	       pdev->irq, card->tx_ring_buffers, card->rx_ring_buffers);
 
-	if (pdev->subsystem_device == PCI_DEVICE_ID_PLX_9050) {
-		printk(KERN_ERR "Detected PCI200SYN card with old "
-		       "configuration data.\n");
-		printk(KERN_ERR "See <http://www.kernel.org/pub/"
-		       "linux/utils/net/hdlc/pci200syn/> for update.\n");
-		printk(KERN_ERR "The card will stop working with"
-		       " future versions of Linux if not updated.\n");
-	}
-
 	if (card->tx_ring_buffers < 1) {
 		printk(KERN_ERR "pci200syn: RAM test failed\n");
 		pci200_pci_remove_one(pdev);
@@ -427,8 +418,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 
 static struct pci_device_id pci200_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX,
-	  PCI_DEVICE_ID_PLX_9050, 0, 0, 0 },
-	{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX,
 	  PCI_DEVICE_ID_PLX_PCI200SYN, 0, 0, 0 },
 	{ 0, }
 };
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index d14e95a..1cc24a4 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -114,7 +114,8 @@ static int  sbni_pci_probe( struct net_device  * );
 static struct net_device  *sbni_probe1(struct net_device *, unsigned long, int);
 static int  sbni_open( struct net_device * );
 static int  sbni_close( struct net_device * );
-static int  sbni_start_xmit( struct sk_buff *, struct net_device * );
+static netdev_tx_t sbni_start_xmit(struct sk_buff *,
+					 struct net_device * );
 static int  sbni_ioctl( struct net_device *, struct ifreq *, int );
 static void  set_multicast_list( struct net_device * );
 
@@ -444,7 +445,7 @@ sbni_probe1( struct net_device  *dev,  unsigned long  ioaddr,  int  irq )
 
 #ifdef CONFIG_SBNI_MULTILINE
 
-static int
+static netdev_tx_t
 sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
 {
 	struct net_device  *p;
@@ -463,7 +464,7 @@ sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
 			prepare_to_send( skb, p );
 			spin_unlock( &nl->lock );
 			netif_start_queue( dev );
-			return  0;
+			return NETDEV_TX_OK;
 		}
 	}
 
@@ -472,7 +473,7 @@ sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
 
 #else	/* CONFIG_SBNI_MULTILINE */
 
-static int
+static netdev_tx_t
 sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
 {
 	struct net_local  *nl  = netdev_priv(dev);
@@ -483,7 +484,7 @@ sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
 	prepare_to_send( skb, dev );
 
 	spin_unlock( &nl->lock );
-	return  0;
+	return NETDEV_TX_OK;
 }
 
 #endif	/* CONFIG_SBNI_MULTILINE */
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 1d637f4..2b15a7e 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -651,7 +651,8 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i
  **************************/
 
 /* NOTE: the DLCI driver deals with freeing the SKB!! */
-static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t sdla_transmit(struct sk_buff *skb,
+				 struct net_device *dev)
 {
 	struct frad_local *flp;
 	int               ret, addr, accept, i;
@@ -711,23 +712,21 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
 				}
 				break;
 		}
+
 		switch (ret)
 		{
 			case SDLA_RET_OK:
 				dev->stats.tx_packets++;
-				ret = DLCI_RET_OK;
 				break;
 
 			case SDLA_RET_CIR_OVERFLOW:
 			case SDLA_RET_BUF_OVERSIZE:
 			case SDLA_RET_NO_BUFS:
 				dev->stats.tx_dropped++;
-				ret = DLCI_RET_DROP;
 				break;
 
 			default:
 				dev->stats.tx_errors++;
-				ret = DLCI_RET_ERR;
 				break;
 		}
 	}
@@ -737,7 +736,9 @@ static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
 		if(flp->master[i]!=NULL)
 			netif_wake_queue(flp->master[i]);
 	}		
-	return(ret);
+
+	dev_kfree_skb(skb);
+	return NETDEV_TX_OK;
 }
 
 static void sdla_receive(struct net_device *dev)
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 23b2690..0c525e2 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -156,7 +156,8 @@ static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
  *	Passed network frames, fire them downwind.
  */
 
-static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d)
+static netdev_tx_t sealevel_queue_xmit(struct sk_buff *skb,
+					     struct net_device *d)
 {
 	return z8530_queue_xmit(dev_to_chan(d)->chan, skb);
 }
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c
index e4ad7b6..daee8a0 100644
--- a/drivers/net/wan/wanxl.c
+++ b/drivers/net/wan/wanxl.c
@@ -268,7 +268,7 @@ static irqreturn_t wanxl_intr(int irq, void* dev_id)
 
 
 
-static int wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
         port_t *port = dev_to_port(dev);
 	desc_t *desc;
@@ -310,7 +310,7 @@ static int wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	spin_unlock(&port->lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index d67e208..2794504 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -299,7 +299,8 @@ static void x25_asy_timeout(struct net_device *dev)
 
 /* Encapsulate an IP datagram and kick it into a TTY queue. */
 
-static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t x25_asy_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct x25_asy *sl = netdev_priv(dev);
 	int err;
@@ -308,7 +309,7 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_ERR "%s: xmit call when iface is down\n",
 			dev->name);
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	switch (skb->data[0]) {
@@ -319,14 +320,14 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
 		if (err != LAPB_OK)
 			printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err);
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	case 0x02: /* Disconnect request .. do nothing - hang up ?? */
 		err = lapb_disconnect_request(dev);
 		if (err != LAPB_OK)
 			printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err);
 	default:
 		kfree_skb(skb);
-		return  0;
+		return NETDEV_TX_OK;
 	}
 	skb_pull(skb, 1);	/* Remove control byte */
 	/*
@@ -344,9 +345,9 @@ static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (err != LAPB_OK) {
 		printk(KERN_ERR "x25_asy: lapb_data_request error - %d\n", err);
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index ad4e79c..0be7ec7 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -1727,15 +1727,14 @@ static inline int spans_boundary(struct sk_buff *skb)
  *	point.
  */
 
-int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
+netdev_tx_t z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
 {
 	unsigned long flags;
 	
 	netif_stop_queue(c->netdevice);
 	if(c->tx_next_skb)
-	{
-		return 1;
-	}
+		return NETDEV_TX_BUSY;
+
 	
 	/* PC SPECIFIC - DMA limits */
 	
@@ -1767,7 +1766,7 @@ int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
 	z8530_tx_begin(c);
 	spin_unlock_irqrestore(c->lock, flags);
 	
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 EXPORT_SYMBOL(z8530_queue_xmit);
diff --git a/drivers/net/wan/z85230.h b/drivers/net/wan/z85230.h
index 85b3e78..f29d554 100644
--- a/drivers/net/wan/z85230.h
+++ b/drivers/net/wan/z85230.h
@@ -406,7 +406,8 @@ extern int z8530_sync_dma_close(struct net_device *, struct z8530_channel *);
 extern int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *);
 extern int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *);
 extern int z8530_channel_load(struct z8530_channel *, u8 *);
-extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb);
+extern netdev_tx_t z8530_queue_xmit(struct z8530_channel *c,
+					  struct sk_buff *skb);
 extern void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb);
 
 
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 9653f47..796396c 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -334,12 +334,12 @@ int i2400m_net_tx(struct i2400m *i2400m, struct net_device *net_dev,
  * that will sleep. See i2400m_net_wake_tx() for details.
  */
 static
-int i2400m_hard_start_xmit(struct sk_buff *skb,
-			   struct net_device *net_dev)
+netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb,
+					 struct net_device *net_dev)
 {
-	int result;
 	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
 	struct device *dev = i2400m_dev(i2400m);
+	int result;
 
 	d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
 	if (i2400m->state == I2400M_SS_IDLE)
@@ -353,9 +353,9 @@ int i2400m_hard_start_xmit(struct sk_buff *skb,
 		net_dev->stats.tx_bytes += skb->len;
 	}
 	kfree_skb(skb);
-	result = NETDEV_TX_OK;
-	d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result);
-	return result;
+
+	d_fnend(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
+	return NETDEV_TX_OK;
 }
 
 
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index 2538825..2981e21 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -58,6 +58,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 #include "i2400m-sdio.h"
@@ -370,6 +371,10 @@ error:
 }
 
 
+static struct device_type i2400ms_type = {
+	.name	= "wimax",
+};
+
 /*
  * Probe a i2400m interface and register it
  *
@@ -411,6 +416,7 @@ int i2400ms_probe(struct sdio_func *func,
 		goto error_alloc_netdev;
 	}
 	SET_NETDEV_DEV(net_dev, dev);
+	SET_NETDEV_DEVTYPE(net_dev, &i2400ms_type);
 	i2400m = net_dev_to_i2400m(net_dev);
 	i2400ms = container_of(i2400m, struct i2400ms, i2400m);
 	i2400m->wimax_dev.net_dev = net_dev;
@@ -501,15 +507,12 @@ void i2400ms_remove(struct sdio_func *func)
 	d_fnend(3, dev, "SDIO func %p\n", func);
 }
 
-enum {
-	I2400MS_INTEL_VID = 0x89,
-};
-
 static
 const struct sdio_device_id i2400ms_sdio_ids[] = {
-	/* Intel: i2400m WiMAX over SDIO */
-	{ SDIO_DEVICE(I2400MS_INTEL_VID, 0x1402) },
-	{ }, 			/* end: all zeroes */
+	/* Intel: i2400m WiMAX (iwmc3200) over SDIO */
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
+		      SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX) },
+	{ /* end: all zeroes */ },
 };
 MODULE_DEVICE_TABLE(sdio, i2400ms_sdio_ids);
 
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index cfdaf69..7eadd11 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -351,6 +351,10 @@ error:
 }
 
 
+static struct device_type i2400mu_type = {
+	.name	= "wimax",
+};
+
 /*
  * Probe a i2400m interface and register it
  *
@@ -388,6 +392,7 @@ int i2400mu_probe(struct usb_interface *iface,
 		goto error_alloc_netdev;
 	}
 	SET_NETDEV_DEV(net_dev, dev);
+	SET_NETDEV_DEVTYPE(net_dev, &i2400mu_type);
 	i2400m = net_dev_to_i2400m(net_dev);
 	i2400mu = container_of(i2400m, struct i2400mu, i2400m);
 	i2400m->wimax_dev.net_dev = net_dev;
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 5bc00db..49ea9c9 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -2,10 +2,20 @@
 # Wireless LAN device configuration
 #
 
-menu "Wireless LAN"
+menuconfig WLAN
+	bool "Wireless LAN"
 	depends on !S390
+	default y
+	---help---
+	  This section contains all the pre 802.11 and 802.11 wireless
+	  device drivers. For a complete list of drivers and documentation
+	  on them refer to the wireless wiki:
+
+	  http://wireless.kernel.org/en/users/Drivers
 
-config WLAN_PRE80211
+if WLAN
+
+menuconfig WLAN_PRE80211
 	bool "Wireless LAN (pre-802.11)"
 	depends on NETDEVICES
 	---help---
@@ -101,7 +111,7 @@ config PCMCIA_NETWAVE
 	  called netwave_cs.  If unsure, say N.
 
 
-config WLAN_80211
+menuconfig WLAN_80211
 	bool "Wireless LAN (IEEE 802.11)"
 	depends on NETDEVICES
 	---help---
@@ -266,51 +276,26 @@ config PCMCIA_WL3501
 	 micro support for ethtool.
 
 config PRISM54
-	tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus' 
+	tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus (DEPRECATED)'
 	depends on PCI && EXPERIMENTAL && WLAN_80211
 	select WIRELESS_EXT
 	select FW_LOADER
 	---help---
-	  Enable PCI and Cardbus support for the following chipset based cards:
-
-	  ISL3880 - Prism GT            802.11 b/g
-	  ISL3877 - Prism Indigo        802.11 a
-	  ISL3890 - Prism Duette        802.11 a/b/g
-	  
-	  For a complete list of supported cards visit <http://prism54.org>.
-	  Here is the latest confirmed list of supported cards:
-
-	  3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 (version 1)
-	  Allnet ALL0271 PCI Card
-	  Compex WL54G Cardbus Card
-	  Corega CG-WLCB54GT Cardbus Card
-	  D-Link Air Plus Xtreme G A1 Cardbus Card aka DWL-g650
-	  I-O Data WN-G54/CB Cardbus Card
-	  Kobishi XG-300 aka Z-Com Cardbus Card
-	  Netgear WG511 Cardbus Card
-	  Ovislink WL-5400PCI PCI Card
-	  Peabird WLG-PCI PCI Card
-	  Sitecom WL-100i Cardbus Card
-	  Sitecom WL-110i PCI Card
-	  SMC2802W -    EZ Connect g 2.4GHz 54 Mbps Wireless PCI Card
-	  SMC2835W -    EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
-	  SMC2835W-V2 - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
-	  Z-Com XG-900 PCI Card
-	  Zyxel G-100 Cardbus Card
-
-	  If you enable this you will need a firmware file as well.
-	  You will need to copy this to /usr/lib/hotplug/firmware/isl3890.
-	  You can get this non-GPL'd firmware file from the Prism54 project page:
-	  <http://prism54.org>
-	  You will also need the /etc/hotplug/firmware.agent script from
-	  a current hotplug package.
-
-	  Note: You need a motherboard with DMA support to use any of these cards 
-	  
-	  If you want to compile the driver as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/kbuild/modules.txt>.
-	  The module will be called prism54.
+	  This enables support for FullMAC PCI/Cardbus prism54 devices. This
+	  driver is now deprecated in favor for the SoftMAC driver, p54pci.
+	  p54pci supports FullMAC PCI/Cardbus devices as well. For details on
+	  the scheduled removal of this driver on the kernel see the feature
+	  removal schedule:
+
+	  Documentation/feature-removal-schedule.txt
+
+	  For more information refer to the p54 wiki:
+
+	  http://wireless.kernel.org/en/users/Drivers/p54
+
+	  Note: You need a motherboard with DMA support to use any of these cards
+
+	  When built as module you get the module prism54
 
 config USB_ZD1201
 	tristate "USB ZD1201 based Wireless device support"
@@ -337,7 +322,6 @@ config USB_NET_RNDIS_WLAN
 	select USB_USBNET
 	select USB_NET_CDCETHER
 	select USB_NET_RNDIS_HOST
-	select WIRELESS_EXT
 	---help---
 	  This is a driver for wireless RNDIS devices.
 	  These are USB based adapters found in devices such as:
@@ -428,10 +412,12 @@ config RTL8187
 	  Micronet SP907GK V5
 	  Encore ENUWI-G2
 	  Trendnet TEW-424UB
-	  ASUS P5B Deluxe
+	  ASUS P5B Deluxe/P5K Premium motherboards
 	  Toshiba Satellite Pro series of laptops
 	  Asus Wireless Link
-	  Linksys WUSB54GC-EU
+	  Linksys WUSB54GC-EU v2
+	    (v1 = rt73usb; v3 is rt2070-based,
+	     use staging/rt3070 or try rt2800usb)
 
 	  Thanks to Realtek for their support!
 
@@ -504,4 +490,4 @@ source "drivers/net/wireless/orinoco/Kconfig"
 source "drivers/net/wireless/wl12xx/Kconfig"
 source "drivers/net/wireless/iwmc3200wifi/Kconfig"
 
-endmenu
+endif # WLAN
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 2b9e379..b80f514 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -452,7 +452,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
 			rx_status.freq = adm8211_channels[priv->channel - 1].center_freq;
 			rx_status.band = IEEE80211_BAND_2GHZ;
 
-			ieee80211_rx_irqsafe(dev, skb, &rx_status);
+			memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+			ieee80211_rx_irqsafe(dev, skb);
 		}
 
 		entry = (++priv->cur_rx) % priv->rx_ring_size;
@@ -1327,16 +1328,39 @@ static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
 	}
 }
 
+static u64 adm8211_prepare_multicast(struct ieee80211_hw *hw,
+				     int mc_count, struct dev_addr_list *mclist)
+{
+	unsigned int bit_nr, i;
+	u32 mc_filter[2];
+
+	mc_filter[1] = mc_filter[0] = 0;
+
+	for (i = 0; i < mc_count; i++) {
+		if (!mclist)
+			break;
+		bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+
+		bit_nr &= 0x3F;
+		mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+		mclist = mclist->next;
+	}
+
+	return mc_filter[0] | ((u64)(mc_filter[1]) << 32);
+}
+
 static void adm8211_configure_filter(struct ieee80211_hw *dev,
 				     unsigned int changed_flags,
 				     unsigned int *total_flags,
-				     int mc_count, struct dev_mc_list *mclist)
+				     u64 multicast)
 {
 	static const u8 bcast[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 	struct adm8211_priv *priv = dev->priv;
-	unsigned int bit_nr, new_flags;
+	unsigned int new_flags;
 	u32 mc_filter[2];
-	int i;
+
+	mc_filter[0] = multicast;
+	mc_filter[1] = multicast >> 32;
 
 	new_flags = 0;
 
@@ -1345,23 +1369,13 @@ static void adm8211_configure_filter(struct ieee80211_hw *dev,
 		priv->nar |= ADM8211_NAR_PR;
 		priv->nar &= ~ADM8211_NAR_MM;
 		mc_filter[1] = mc_filter[0] = ~0;
-	} else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) {
+	} else if (*total_flags & FIF_ALLMULTI || multicast == ~(0ULL)) {
 		new_flags |= FIF_ALLMULTI;
 		priv->nar &= ~ADM8211_NAR_PR;
 		priv->nar |= ADM8211_NAR_MM;
 		mc_filter[1] = mc_filter[0] = ~0;
 	} else {
 		priv->nar &= ~(ADM8211_NAR_MM | ADM8211_NAR_PR);
-		mc_filter[1] = mc_filter[0] = 0;
-		for (i = 0; i < mc_count; i++) {
-			if (!mclist)
-				break;
-			bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
-
-			bit_nr &= 0x3F;
-			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-			mclist = mclist->next;
-		}
 	}
 
 	ADM8211_IDLE_RX();
@@ -1756,6 +1770,7 @@ static const struct ieee80211_ops adm8211_ops = {
 	.remove_interface	= adm8211_remove_interface,
 	.config			= adm8211_config,
 	.bss_info_changed	= adm8211_bss_info_changed,
+	.prepare_multicast	= adm8211_prepare_multicast,
 	.configure_filter	= adm8211_configure_filter,
 	.get_stats		= adm8211_get_stats,
 	.get_tx_stats		= adm8211_get_tx_stats,
@@ -1963,14 +1978,6 @@ static void __devexit adm8211_remove(struct pci_dev *pdev)
 #ifdef CONFIG_PM
 static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
-	struct adm8211_priv *priv = dev->priv;
-
-	if (priv->mode != NL80211_IFTYPE_UNSPECIFIED) {
-		ieee80211_stop_queues(dev);
-		adm8211_stop(dev);
-	}
-
 	pci_save_state(pdev);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 	return 0;
@@ -1978,17 +1985,8 @@ static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
 
 static int adm8211_resume(struct pci_dev *pdev)
 {
-	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
-	struct adm8211_priv *priv = dev->priv;
-
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
-
-	if (priv->mode != NL80211_IFTYPE_UNSPECIFIED) {
-		adm8211_start(dev);
-		ieee80211_wake_queues(dev);
-	}
-
 	return 0;
 }
 #endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 8ce5e4c..7116a1a 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1920,14 +1920,16 @@ static int airo_open(struct net_device *dev) {
 	return 0;
 }
 
-static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
+static netdev_tx_t mpi_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
+{
 	int npacks, pending;
 	unsigned long flags;
 	struct airo_info *ai = dev->ml_priv;
 
 	if (!skb) {
 		airo_print_err(dev->name, "%s: skb == NULL!",__func__);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	npacks = skb_queue_len (&ai->txq);
 
@@ -1938,7 +1940,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
 			return NETDEV_TX_BUSY;
 		}
 		skb_queue_tail (&ai->txq, skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	spin_lock_irqsave(&ai->aux_lock, flags);
@@ -1951,7 +1953,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
 		set_bit(FLAG_PENDING_XMIT, &ai->flags);
 		mpi_send_packet (dev);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -2119,7 +2121,9 @@ static void airo_end_xmit(struct net_device *dev) {
 	dev_kfree_skb(skb);
 }
 
-static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
+static netdev_tx_t airo_start_xmit(struct sk_buff *skb,
+					 struct net_device *dev)
+{
 	s16 len;
 	int i, j;
 	struct airo_info *priv = dev->ml_priv;
@@ -2127,7 +2131,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
 
 	if ( skb == NULL ) {
 		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* Find a vacant FID */
@@ -2155,7 +2159,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
 		wake_up_interruptible(&priv->thr_wait);
 	} else
 		airo_end_xmit(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void airo_end_xmit11(struct net_device *dev) {
@@ -2184,7 +2188,9 @@ static void airo_end_xmit11(struct net_device *dev) {
 	dev_kfree_skb(skb);
 }
 
-static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
+static netdev_tx_t airo_start_xmit11(struct sk_buff *skb,
+					   struct net_device *dev)
+{
 	s16 len;
 	int i, j;
 	struct airo_info *priv = dev->ml_priv;
@@ -2199,7 +2205,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
 
 	if ( skb == NULL ) {
 		airo_print_err(dev->name, "%s: skb == NULL!", __func__);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* Find a vacant FID */
@@ -2227,7 +2233,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
 		wake_up_interruptible(&priv->thr_wait);
 	} else
 		airo_end_xmit11(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void airo_read_stats(struct net_device *dev)
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
index d84caf1..921a082 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -77,7 +77,7 @@ struct arlan_conf_stru arlan_conf[MAX_ARLANS];
 static int arlans_found;
 
 static  int 	arlan_open(struct net_device *dev);
-static  int 	arlan_tx(struct sk_buff *skb, struct net_device *dev);
+static  netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev);
 static  irqreturn_t arlan_interrupt(int irq, void *dev_id);
 static  int 	arlan_close(struct net_device *dev);
 static  struct net_device_stats *
@@ -1022,7 +1022,7 @@ static int arlan_mac_addr(struct net_device *dev, void *p)
 	ARLAN_DEBUG_ENTRY("arlan_mac_addr");
 	return -EINVAL;
 
-	if (!netif_running(dev))
+	if (netif_running(dev))
 		return -EBUSY;
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
@@ -1169,7 +1169,7 @@ static void arlan_tx_timeout (struct net_device *dev)
 }
 
 
-static int arlan_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t arlan_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	short length;
 	unsigned char *buf;
@@ -1193,7 +1193,7 @@ static int arlan_tx(struct sk_buff *skb, struct net_device *dev)
 
 	arlan_process_interrupt(dev);
 	ARLAN_DEBUG_EXIT("arlan_tx");
-	return 0;
+	return NETDEV_TX_OK;
 
 bad_end:
 	arlan_process_interrupt(dev);
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 4efbdbe..8e1a55d 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1568,7 +1568,8 @@ static void at76_rx_tasklet(unsigned long param)
 
 	at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
 		 priv->rx_skb->len, priv->rx_skb->data_len);
-	ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+	memcpy(IEEE80211_SKB_RXCB(priv->rx_skb), &rx_status, sizeof(rx_status));
+	ieee80211_rx_irqsafe(priv->hw, priv->rx_skb);
 
 	/* Use a new skb for the next receive */
 	priv->rx_skb = NULL;
@@ -1772,6 +1773,9 @@ static void at76_mac80211_stop(struct ieee80211_hw *hw)
 
 	at76_dbg(DBG_MAC80211, "%s()", __func__);
 
+	cancel_delayed_work(&priv->dwork_hw_scan);
+	cancel_work_sync(&priv->work_set_promisc);
+
 	mutex_lock(&priv->mtx);
 
 	if (!priv->device_unplugged) {
@@ -1871,8 +1875,8 @@ static void at76_dwork_hw_scan(struct work_struct *work)
 	/* FIXME: add maximum time for scan to complete */
 
 	if (ret != CMD_STATUS_COMPLETE) {
-		queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
-				   SCAN_POLL_INTERVAL);
+		ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
+					     SCAN_POLL_INTERVAL);
 		mutex_unlock(&priv->mtx);
 		return;
 	}
@@ -1933,8 +1937,8 @@ static int at76_hw_scan(struct ieee80211_hw *hw,
 		goto exit;
 	}
 
-	queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
-			   SCAN_POLL_INTERVAL);
+	ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
+				     SCAN_POLL_INTERVAL);
 
 exit:
 	mutex_unlock(&priv->mtx);
@@ -1946,9 +1950,8 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct at76_priv *priv = hw->priv;
 
-	at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
-		 __func__, hw->conf.channel->hw_value,
-		 hw->conf.radio_enabled);
+	at76_dbg(DBG_MAC80211, "%s(): channel %d",
+		 __func__, hw->conf.channel->hw_value);
 	at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
 
 	mutex_lock(&priv->mtx);
@@ -1993,15 +1996,14 @@ static void at76_bss_info_changed(struct ieee80211_hw *hw,
 /* must be atomic */
 static void at76_configure_filter(struct ieee80211_hw *hw,
 				  unsigned int changed_flags,
-				  unsigned int *total_flags, int mc_count,
-				  struct dev_addr_list *mc_list)
+				  unsigned int *total_flags, u64 multicast)
 {
 	struct at76_priv *priv = hw->priv;
 	int flags;
 
 	at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
-		 "total_flags=0x%08x mc_count=%d",
-		 __func__, changed_flags, *total_flags, mc_count);
+		 "total_flags=0x%08x",
+		 __func__, changed_flags, *total_flags);
 
 	flags = changed_flags & AT76_SUPPORTED_FILTERS;
 	*total_flags = AT76_SUPPORTED_FILTERS;
@@ -2023,7 +2025,7 @@ static void at76_configure_filter(struct ieee80211_hw *hw,
 	} else
 		return;
 
-	queue_work(hw->workqueue, &priv->work_set_promisc);
+	ieee80211_queue_work(hw, &priv->work_set_promisc);
 }
 
 static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -2294,11 +2296,8 @@ static void at76_delete_device(struct at76_priv *priv)
 
 	tasklet_kill(&priv->rx_tasklet);
 
-	if (priv->mac80211_registered) {
-		cancel_delayed_work(&priv->dwork_hw_scan);
-		flush_workqueue(priv->hw->workqueue);
+	if (priv->mac80211_registered)
 		ieee80211_unregister_hw(priv->hw);
-	}
 
 	if (priv->tx_urb) {
 		usb_kill_urb(priv->tx_urb);
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index eb0337c..11ded15 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,9 +1,22 @@
-config ATH_COMMON
+menuconfig ATH_COMMON
 	tristate "Atheros Wireless Cards"
 	depends on WLAN_80211
-	depends on ATH5K || ATH9K || AR9170_USB
+	depends on CFG80211
+	---help---
+	  This will enable the support for the Atheros wireless drivers.
+	  ath5k, ath9k and ar9170 drivers share some common code, this option
+	  enables the common ath.ko module which shares common helpers.
 
+	  For more information and documentation on this module you can visit:
+
+	  http://wireless.kernel.org/en/users/Drivers/ath
+
+	  For information on all Atheros wireless drivers visit:
+
+	  http://wireless.kernel.org/en/users/Drivers/Atheros
+
+if ATH_COMMON
 source "drivers/net/wireless/ath/ath5k/Kconfig"
 source "drivers/net/wireless/ath/ath9k/Kconfig"
 source "drivers/net/wireless/ath/ar9170/Kconfig"
-
+endif
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
index b99e326..05918f1 100644
--- a/drivers/net/wireless/ath/ar9170/Kconfig
+++ b/drivers/net/wireless/ath/ar9170/Kconfig
@@ -1,13 +1,13 @@
 config AR9170_USB
 	tristate "Atheros AR9170 802.11n USB support"
-	depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
+	depends on USB && MAC80211 && WLAN_80211
 	select FW_LOADER
-	select ATH_COMMON
 	help
 	  This is a driver for the Atheros "otus" 802.11n USB devices.
 
 	  These devices require additional firmware (2 files).
 	  For now, these files can be downloaded from here:
+
 	  http://wireless.kernel.org/en/users/Drivers/ar9170
 
 	  If you choose to build a module, it'll be called ar9170usb.
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index bb97981..914e471 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -109,13 +109,55 @@ struct ar9170_rxstream_mpdu_merge {
 	bool has_plcp;
 };
 
+#define AR9170_NUM_MAX_BA_RETRY	5
+#define AR9170_NUM_TID	16
+#define WME_BA_BMP_SIZE         64
+#define AR9170_NUM_MAX_AGG_LEN	(2 * WME_BA_BMP_SIZE)
+
+#define WME_AC_BE   2
+#define WME_AC_BK   3
+#define WME_AC_VI   1
+#define WME_AC_VO   0
+
+#define TID_TO_WME_AC(_tid)				\
+	((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE :	\
+	 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK :	\
+	 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI :	\
+	 WME_AC_VO)
+
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+	((((_seqno) - (_start)) & 0xfff) < (_bawsz))
+
+enum ar9170_tid_state {
+	AR9170_TID_STATE_INVALID,
+	AR9170_TID_STATE_SHUTDOWN,
+	AR9170_TID_STATE_PROGRESS,
+	AR9170_TID_STATE_COMPLETE,
+};
+
+struct ar9170_sta_tid {
+	struct list_head list;
+	struct sk_buff_head queue;
+	u8 addr[ETH_ALEN];
+	u16 ssn;
+	u16 tid;
+	enum ar9170_tid_state state;
+	bool active;
+	u8 retry;
+};
+
 #define AR9170_QUEUE_TIMEOUT		64
 #define AR9170_TX_TIMEOUT		8
+#define AR9170_BA_TIMEOUT		4
 #define AR9170_JANITOR_DELAY		128
 #define AR9170_TX_INVALID_RATE		0xffffffff
 
+#define AR9170_NUM_TX_STATUS		128
+#define AR9170_NUM_TX_AGG_MAX		30
+
 struct ar9170 {
 	struct ieee80211_hw *hw;
+	struct ath_common common;
 	struct mutex mutex;
 	enum ar9170_device_state state;
 	unsigned long bad_hw_nagger;
@@ -136,6 +178,7 @@ struct ar9170 {
 	/* beaconing */
 	struct sk_buff *beacon;
 	struct work_struct beacon_work;
+	bool enable_beacon;
 
 	/* cryptographic engine */
 	u64 usedkeys;
@@ -143,10 +186,8 @@ struct ar9170 {
 	bool disable_offload;
 
 	/* filter settings */
-	struct work_struct filter_config_work;
-	u64 cur_mc_hash, want_mc_hash;
-	u32 cur_filter, want_filter;
-	unsigned long filter_changed;
+	u64 cur_mc_hash;
+	u32 cur_filter;
 	unsigned int filter_state;
 	bool sniffer_enabled;
 
@@ -181,20 +222,30 @@ struct ar9170 {
 
 	/* EEPROM */
 	struct ar9170_eeprom eeprom;
-	struct ath_regulatory regulatory;
 
 	/* tx queues - as seen by hw - */
 	struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
 	struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
 	struct delayed_work tx_janitor;
+	/* tx ampdu */
+	struct sk_buff_head tx_status_ampdu;
+	spinlock_t tx_ampdu_list_lock;
+	struct list_head tx_ampdu_list;
+	unsigned int tx_ampdu_pending;
 
 	/* rxstream mpdu merge */
 	struct ar9170_rxstream_mpdu_merge rx_mpdu;
 	struct sk_buff *rx_failover;
 	int rx_failover_missing;
+
+	/* (cached) HW A-MPDU settings */
+	u8 global_ampdu_density;
+	u8 global_ampdu_factor;
 };
 
 struct ar9170_sta_info {
+	struct ar9170_sta_tid agg[AR9170_NUM_TID];
+	unsigned int ampdu_max_len;
 };
 
 #define AR9170_TX_FLAG_WAIT_FOR_ACK	BIT(0)
@@ -209,10 +260,6 @@ struct ar9170_tx_info {
 #define IS_STARTED(a)		(((struct ar9170 *)a)->state >= AR9170_STARTED)
 #define IS_ACCEPTING_CMD(a)	(((struct ar9170 *)a)->state >= AR9170_IDLE)
 
-#define AR9170_FILTER_CHANGED_MODE		BIT(0)
-#define AR9170_FILTER_CHANGED_MULTICAST		BIT(1)
-#define AR9170_FILTER_CHANGED_FRAMEFILTER	BIT(2)
-
 /* exported interface */
 void *ar9170_alloc(size_t priv_size);
 int ar9170_register(struct ar9170 *ar, struct device *pdev);
@@ -226,8 +273,8 @@ int ar9170_nag_limiter(struct ar9170 *ar);
 int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
 int ar9170_init_mac(struct ar9170 *ar);
 int ar9170_set_qos(struct ar9170 *ar);
-int ar9170_update_multicast(struct ar9170 *ar);
-int ar9170_update_frame_filter(struct ar9170 *ar);
+int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
+int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter);
 int ar9170_set_operating_mode(struct ar9170 *ar);
 int ar9170_set_beacon_timers(struct ar9170 *ar);
 int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
index 63fda6c..86c4e79 100644
--- a/drivers/net/wireless/ath/ar9170/led.c
+++ b/drivers/net/wireless/ath/ar9170/led.c
@@ -90,9 +90,12 @@ static void ar9170_update_leds(struct work_struct *work)
 	ar9170_set_leds_state(ar, led_val);
 	mutex_unlock(&ar->mutex);
 
-	if (rerun)
-		queue_delayed_work(ar->hw->workqueue, &ar->led_work,
-				   msecs_to_jiffies(blink_delay));
+	if (!rerun)
+		return;
+
+	ieee80211_queue_delayed_work(ar->hw,
+				     &ar->led_work,
+				     msecs_to_jiffies(blink_delay));
 }
 
 static void ar9170_led_brightness_set(struct led_classdev *led,
@@ -110,7 +113,7 @@ static void ar9170_led_brightness_set(struct led_classdev *led,
 	}
 
 	if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
-		queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
+		ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
 }
 
 static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index d9f1f46..614e321 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -238,39 +238,31 @@ static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
 	return ar9170_regwrite_result();
 }
 
-int ar9170_update_multicast(struct ar9170 *ar)
+int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
 {
 	int err;
 
 	ar9170_regwrite_begin(ar);
-	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
-		ar->want_mc_hash >> 32);
-	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
-		ar->want_mc_hash);
-
+	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
+	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
 	ar9170_regwrite_finish();
 	err = ar9170_regwrite_result();
-
 	if (err)
 		return err;
 
-	ar->cur_mc_hash = ar->want_mc_hash;
-
+	ar->cur_mc_hash = mc_hash;
 	return 0;
 }
 
-int ar9170_update_frame_filter(struct ar9170 *ar)
+int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter)
 {
 	int err;
 
-	err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
-			       ar->want_filter);
-
+	err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter);
 	if (err)
 		return err;
 
-	ar->cur_filter = ar->want_filter;
-
+	ar->cur_filter = filter;
 	return 0;
 }
 
@@ -391,24 +383,26 @@ int ar9170_set_beacon_timers(struct ar9170 *ar)
 	if (ar->vif) {
 		v |= ar->vif->bss_conf.beacon_int;
 
-		switch (ar->vif->type) {
-		case NL80211_IFTYPE_MESH_POINT:
-		case NL80211_IFTYPE_ADHOC:
-			v |= BIT(25);
-			break;
-		case NL80211_IFTYPE_AP:
-			v |= BIT(24);
-			pretbtt = (ar->vif->bss_conf.beacon_int - 6) << 16;
-			break;
-		default:
+		if (ar->enable_beacon) {
+			switch (ar->vif->type) {
+			case NL80211_IFTYPE_MESH_POINT:
+			case NL80211_IFTYPE_ADHOC:
+				v |= BIT(25);
+				break;
+			case NL80211_IFTYPE_AP:
+				v |= BIT(24);
+				pretbtt = (ar->vif->bss_conf.beacon_int - 6) <<
+					  16;
+				break;
+			default:
 			break;
+			}
 		}
 
 		v |= ar->vif->bss_conf.dtim_period << 16;
 	}
 
 	ar9170_regwrite_begin(ar);
-
 	ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
 	ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
 	ar9170_regwrite_finish();
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 88c3d85..c1f8c69 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -49,6 +49,10 @@ static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
+static int modparam_ht;
+module_param_named(ht, modparam_ht, bool, S_IRUGO);
+MODULE_PARM_DESC(ht, "enable MPDU aggregation.");
+
 #define RATE(_bitrate, _hw_rate, _txpidx, _flags) {	\
 	.bitrate	= (_bitrate),			\
 	.flags		= (_flags),			\
@@ -148,12 +152,15 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
 	.cap		= IEEE80211_HT_CAP_MAX_AMSDU |			\
 			  IEEE80211_HT_CAP_SUP_WIDTH_20_40 |		\
 			  IEEE80211_HT_CAP_SGI_40 |			\
+			  IEEE80211_HT_CAP_GRN_FLD |			\
 			  IEEE80211_HT_CAP_DSSSCCK40 |			\
 			  IEEE80211_HT_CAP_SM_PS,			\
 	.ampdu_factor	= 3,						\
 	.ampdu_density	= 6,						\
 	.mcs		= {						\
-		.rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, },	\
+		.rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, },	\
+		.rx_highest = cpu_to_le16(300),				\
+		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,		\
 	},								\
 }
 
@@ -174,8 +181,31 @@ static struct ieee80211_supported_band ar9170_band_5GHz = {
 };
 
 static void ar9170_tx(struct ar9170 *ar);
+static bool ar9170_tx_ampdu(struct ar9170 *ar);
 
-#ifdef AR9170_QUEUE_DEBUG
+static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
+{
+	return le16_to_cpu(hdr->seq_ctrl) >> 4;
+}
+
+static inline u16 ar9170_get_seq(struct sk_buff *skb)
+{
+	struct ar9170_tx_control *txc = (void *) skb->data;
+	return ar9170_get_seq_h((void *) txc->frame_data);
+}
+
+static inline u16 ar9170_get_tid(struct sk_buff *skb)
+{
+	struct ar9170_tx_control *txc = (void *) skb->data;
+	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+
+	return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+#define GET_NEXT_SEQ(seq)	((seq + 1) & 0x0fff)
+#define GET_NEXT_SEQ_FROM_SKB(skb)	(GET_NEXT_SEQ(ar9170_get_seq(skb)))
+
+#if (defined AR9170_QUEUE_DEBUG) || (defined AR9170_TXAGG_DEBUG)
 static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
 {
 	struct ar9170_tx_control *txc = (void *) skb->data;
@@ -183,10 +213,10 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
 	struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
 	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
 
-	printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x "
+	printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d "
 			  "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
 	       wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
-	       ieee80211_get_DA(hdr), arinfo->flags,
+	       ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr),
 	       le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
 	       jiffies_to_msecs(arinfo->timeout - jiffies));
 }
@@ -210,7 +240,9 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar,
 		       "mismatch %d != %d\n", skb_queue_len(queue), i);
 	printk(KERN_DEBUG "---[ end ]---\n");
 }
+#endif /* AR9170_QUEUE_DEBUG || AR9170_TXAGG_DEBUG */
 
+#ifdef AR9170_QUEUE_DEBUG
 static void ar9170_dump_txqueue(struct ar9170 *ar,
 				struct sk_buff_head *queue)
 {
@@ -220,7 +252,9 @@ static void ar9170_dump_txqueue(struct ar9170 *ar,
 	__ar9170_dump_txqueue(ar, queue);
 	spin_unlock_irqrestore(&queue->lock, flags);
 }
+#endif /* AR9170_QUEUE_DEBUG */
 
+#ifdef AR9170_QUEUE_STOP_DEBUG
 static void __ar9170_dump_txstats(struct ar9170 *ar)
 {
 	int i;
@@ -229,20 +263,27 @@ static void __ar9170_dump_txstats(struct ar9170 *ar)
 	       wiphy_name(ar->hw->wiphy));
 
 	for (i = 0; i < __AR9170_NUM_TXQ; i++)
-		printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n",
-		       wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit,
-		       ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i]));
+		printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d "
+		       " stopped:%d\n", wiphy_name(ar->hw->wiphy), i,
+		       ar->tx_stats[i].limit, ar->tx_stats[i].len,
+		       skb_queue_len(&ar->tx_status[i]),
+		       ieee80211_queue_stopped(ar->hw, i));
 }
+#endif /* AR9170_QUEUE_STOP_DEBUG */
 
-static void ar9170_dump_txstats(struct ar9170 *ar)
+#ifdef AR9170_TXAGG_DEBUG
+static void ar9170_dump_tx_status_ampdu(struct ar9170 *ar)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&ar->tx_stats_lock, flags);
-	__ar9170_dump_txstats(ar);
-	spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+	spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags);
+	printk(KERN_DEBUG "%s: A-MPDU tx_status queue => \n",
+	       wiphy_name(ar->hw->wiphy));
+	__ar9170_dump_txqueue(ar, &ar->tx_status_ampdu);
+	spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags);
 }
-#endif /* AR9170_QUEUE_DEBUG */
+
+#endif /* AR9170_TXAGG_DEBUG */
 
 /* caller must guarantee exclusive access for _bin_ queue. */
 static void ar9170_recycle_expired(struct ar9170 *ar,
@@ -315,6 +356,70 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
 	ieee80211_tx_status_irqsafe(ar->hw, skb);
 }
 
+static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar)
+{
+	struct sk_buff_head success;
+	struct sk_buff *skb;
+	unsigned int i;
+	unsigned long queue_bitmap = 0;
+
+	skb_queue_head_init(&success);
+
+	while (skb_queue_len(&ar->tx_status_ampdu) > AR9170_NUM_TX_STATUS)
+		__skb_queue_tail(&success, skb_dequeue(&ar->tx_status_ampdu));
+
+	ar9170_recycle_expired(ar, &ar->tx_status_ampdu, &success);
+
+#ifdef AR9170_TXAGG_DEBUG
+	printk(KERN_DEBUG "%s: collected %d A-MPDU frames.\n",
+	       wiphy_name(ar->hw->wiphy), skb_queue_len(&success));
+	__ar9170_dump_txqueue(ar, &success);
+#endif /* AR9170_TXAGG_DEBUG */
+
+	while ((skb = __skb_dequeue(&success))) {
+		struct ieee80211_tx_info *txinfo;
+
+		queue_bitmap |= BIT(skb_get_queue_mapping(skb));
+
+		txinfo = IEEE80211_SKB_CB(skb);
+		ieee80211_tx_info_clear_status(txinfo);
+
+		txinfo->flags |= IEEE80211_TX_STAT_ACK;
+		txinfo->status.rates[0].count = 1;
+
+		skb_pull(skb, sizeof(struct ar9170_tx_control));
+		ieee80211_tx_status_irqsafe(ar->hw, skb);
+	}
+
+	for_each_bit(i, &queue_bitmap, BITS_PER_BYTE) {
+#ifdef AR9170_QUEUE_STOP_DEBUG
+		printk(KERN_DEBUG "%s: wake queue %d\n",
+		       wiphy_name(ar->hw->wiphy), i);
+		__ar9170_dump_txstats(ar);
+#endif /* AR9170_QUEUE_STOP_DEBUG */
+		ieee80211_wake_queue(ar->hw, i);
+	}
+
+	if (queue_bitmap)
+		ar9170_tx(ar);
+}
+
+static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+	struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
+
+	arinfo->timeout = jiffies +
+			  msecs_to_jiffies(AR9170_BA_TIMEOUT);
+
+	skb_queue_tail(&ar->tx_status_ampdu, skb);
+	ar9170_tx_fake_ampdu_status(ar);
+	ar->tx_ampdu_pending--;
+
+	if (!list_empty(&ar->tx_ampdu_list) && !ar->tx_ampdu_pending)
+		ar9170_tx_ampdu(ar);
+}
+
 void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -336,7 +441,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
 	spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
 
 	if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) {
-		dev_kfree_skb_any(skb);
+		ar9170_tx_ampdu_callback(ar, skb);
 	} else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
 		arinfo->timeout = jiffies +
 				  msecs_to_jiffies(AR9170_TX_TIMEOUT);
@@ -420,6 +525,38 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
 	return NULL;
 }
 
+static void ar9170_handle_block_ack(struct ar9170 *ar, u16 count, u16 r)
+{
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *txinfo;
+
+	while (count) {
+		skb = ar9170_get_queued_skb(ar, NULL, &ar->tx_status_ampdu, r);
+		if (!skb)
+			break;
+
+		txinfo = IEEE80211_SKB_CB(skb);
+		ieee80211_tx_info_clear_status(txinfo);
+
+		/* FIXME: maybe more ? */
+		txinfo->status.rates[0].count = 1;
+
+		skb_pull(skb, sizeof(struct ar9170_tx_control));
+		ieee80211_tx_status_irqsafe(ar->hw, skb);
+		count--;
+	}
+
+#ifdef AR9170_TXAGG_DEBUG
+	if (count) {
+		printk(KERN_DEBUG "%s: got %d more failed mpdus, but no more "
+		       "suitable frames left in tx_status queue.\n",
+		       wiphy_name(ar->hw->wiphy), count);
+
+		ar9170_dump_tx_status_ampdu(ar);
+	}
+#endif /* AR9170_TXAGG_DEBUG */
+}
+
 /*
  * This worker tries to keeps an maintain tx_status queues.
  * So we can guarantee that incoming tx_status reports are
@@ -456,10 +593,14 @@ static void ar9170_tx_janitor(struct work_struct *work)
 			resched = true;
 	}
 
-	if (resched)
-		queue_delayed_work(ar->hw->workqueue,
-				   &ar->tx_janitor,
-				   msecs_to_jiffies(AR9170_JANITOR_DELAY));
+	ar9170_tx_fake_ampdu_status(ar);
+
+	if (!resched)
+		return;
+
+	ieee80211_queue_delayed_work(ar->hw,
+				     &ar->tx_janitor,
+				     msecs_to_jiffies(AR9170_JANITOR_DELAY));
 }
 
 void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
@@ -509,7 +650,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
 		 * pre-TBTT event
 		 */
 		if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
-			queue_work(ar->hw->workqueue, &ar->beacon_work);
+			ieee80211_queue_work(ar->hw, &ar->beacon_work);
 		break;
 
 	case 0xc2:
@@ -528,8 +669,15 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
 		break;
 
 	case 0xc4:
+		/* BlockACK bitmap */
+		break;
+
 	case 0xc5:
 		/* BlockACK events */
+		ar9170_handle_block_ack(ar,
+					le16_to_cpu(cmd->ba_fail_cnt.failed),
+					le16_to_cpu(cmd->ba_fail_cnt.rate));
+		ar9170_tx_fake_ampdu_status(ar);
 		break;
 
 	case 0xc6:
@@ -917,8 +1065,10 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 		ar9170_rx_phy_status(ar, phy, &status);
 
 	skb = ar9170_rx_copy_data(buf, mpdu_len);
-	if (likely(skb))
-		ieee80211_rx_irqsafe(ar->hw, skb, &status);
+	if (likely(skb)) {
+		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+		ieee80211_rx_irqsafe(ar->hw, skb);
+	}
 }
 
 void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
@@ -1082,8 +1232,6 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
 
 	mutex_lock(&ar->mutex);
 
-	ar->filter_changed = 0;
-
 	/* reinitialize queues statistics */
 	memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
 	for (i = 0; i < __AR9170_NUM_TXQ; i++)
@@ -1096,6 +1244,10 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
 	AR9170_FILL_QUEUE(ar->edcf[3], 2, 3,     7, 47); /* VOICE */
 	AR9170_FILL_QUEUE(ar->edcf[4], 2, 3,     7,  0); /* SPECIAL */
 
+	/* set sane AMPDU defaults */
+	ar->global_ampdu_density = 6;
+	ar->global_ampdu_factor = 3;
+
 	ar->bad_hw_nagger = jiffies;
 
 	err = ar->open(ar);
@@ -1138,11 +1290,12 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
 	if (IS_STARTED(ar))
 		ar->state = AR9170_IDLE;
 
-	flush_workqueue(ar->hw->workqueue);
-
 	cancel_delayed_work_sync(&ar->tx_janitor);
-	cancel_work_sync(&ar->filter_config_work);
+#ifdef CONFIG_AR9170_LEDS
+	cancel_delayed_work_sync(&ar->led_work);
+#endif
 	cancel_work_sync(&ar->beacon_work);
+
 	mutex_lock(&ar->mutex);
 
 	if (IS_ACCEPTING_CMD(ar)) {
@@ -1157,9 +1310,40 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
 		skb_queue_purge(&ar->tx_pending[i]);
 		skb_queue_purge(&ar->tx_status[i]);
 	}
+	skb_queue_purge(&ar->tx_status_ampdu);
+
 	mutex_unlock(&ar->mutex);
 }
 
+static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
+{
+	struct ar9170_tx_control *txc = (void *) skb->data;
+
+	txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
+}
+
+static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
+			       struct sk_buff *src)
+{
+	struct ar9170_tx_control *dst_txc, *src_txc;
+	struct ieee80211_tx_info *dst_info, *src_info;
+	struct ar9170_tx_info *dst_arinfo, *src_arinfo;
+
+	src_txc = (void *) src->data;
+	src_info = IEEE80211_SKB_CB(src);
+	src_arinfo = (void *) src_info->rate_driver_data;
+
+	dst_txc = (void *) dst->data;
+	dst_info = IEEE80211_SKB_CB(dst);
+	dst_arinfo = (void *) dst_info->rate_driver_data;
+
+	dst_txc->phy_control = src_txc->phy_control;
+
+	/* same MCS for the whole aggregate */
+	memcpy(dst_info->driver_rates, src_info->driver_rates,
+	       sizeof(dst_info->driver_rates));
+}
+
 static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr;
@@ -1228,6 +1412,7 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
 
 			txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
 			arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
+
 			goto out;
 		}
 
@@ -1358,6 +1543,159 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
 	txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
 }
 
+static bool ar9170_tx_ampdu(struct ar9170 *ar)
+{
+	struct sk_buff_head agg;
+	struct ar9170_sta_tid *tid_info = NULL, *tmp;
+	struct sk_buff *skb, *first = NULL;
+	unsigned long flags, f2;
+	unsigned int i = 0;
+	u16 seq, queue, tmpssn;
+	bool run = false;
+
+	skb_queue_head_init(&agg);
+
+	spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
+	if (list_empty(&ar->tx_ampdu_list)) {
+#ifdef AR9170_TXAGG_DEBUG
+		printk(KERN_DEBUG "%s: aggregation list is empty.\n",
+		       wiphy_name(ar->hw->wiphy));
+#endif /* AR9170_TXAGG_DEBUG */
+		goto out_unlock;
+	}
+
+	list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
+		if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
+#ifdef AR9170_TXAGG_DEBUG
+			printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
+			       wiphy_name(ar->hw->wiphy));
+#endif /* AR9170_TXAGG_DEBUG */
+			continue;
+		}
+
+		if (++i > 64) {
+#ifdef AR9170_TXAGG_DEBUG
+			printk(KERN_DEBUG "%s: enough frames aggregated.\n",
+			       wiphy_name(ar->hw->wiphy));
+#endif /* AR9170_TXAGG_DEBUG */
+			break;
+		}
+
+		queue = TID_TO_WME_AC(tid_info->tid);
+
+		if (skb_queue_len(&ar->tx_pending[queue]) >=
+		    AR9170_NUM_TX_AGG_MAX) {
+#ifdef AR9170_TXAGG_DEBUG
+			printk(KERN_DEBUG "%s: queue %d full.\n",
+			       wiphy_name(ar->hw->wiphy), queue);
+#endif /* AR9170_TXAGG_DEBUG */
+			continue;
+		}
+
+		list_del_init(&tid_info->list);
+
+		spin_lock_irqsave(&tid_info->queue.lock, f2);
+		tmpssn = seq = tid_info->ssn;
+		first = skb_peek(&tid_info->queue);
+
+		if (likely(first))
+			tmpssn = ar9170_get_seq(first);
+
+		if (unlikely(tmpssn != seq)) {
+#ifdef AR9170_TXAGG_DEBUG
+			printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
+			       wiphy_name(ar->hw->wiphy), seq, tmpssn);
+#endif /* AR9170_TXAGG_DEBUG */
+			tid_info->ssn = tmpssn;
+		}
+
+#ifdef AR9170_TXAGG_DEBUG
+		printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
+		       "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
+		       tid_info->tid, tid_info->ssn,
+		       skb_queue_len(&tid_info->queue));
+		__ar9170_dump_txqueue(ar, &tid_info->queue);
+#endif /* AR9170_TXAGG_DEBUG */
+
+		while ((skb = skb_peek(&tid_info->queue))) {
+			if (unlikely(ar9170_get_seq(skb) != seq))
+				break;
+
+			__skb_unlink(skb, &tid_info->queue);
+			tid_info->ssn = seq = GET_NEXT_SEQ(seq);
+
+			if (unlikely(skb_get_queue_mapping(skb) != queue)) {
+#ifdef AR9170_TXAGG_DEBUG
+				printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
+				       "!match.\n", wiphy_name(ar->hw->wiphy),
+				       tid_info->tid,
+				       TID_TO_WME_AC(tid_info->tid),
+				       skb_get_queue_mapping(skb));
+#endif /* AR9170_TXAGG_DEBUG */
+					dev_kfree_skb_any(skb);
+					continue;
+			}
+
+			if (unlikely(first == skb)) {
+				ar9170_tx_prepare_phy(ar, skb);
+				__skb_queue_tail(&agg, skb);
+				first = skb;
+			} else {
+				ar9170_tx_copy_phy(ar, skb, first);
+				__skb_queue_tail(&agg, skb);
+			}
+
+			if (unlikely(skb_queue_len(&agg) ==
+			    AR9170_NUM_TX_AGG_MAX))
+				break;
+		}
+
+		if (skb_queue_empty(&tid_info->queue))
+			tid_info->active = false;
+		else
+			list_add_tail(&tid_info->list,
+				      &ar->tx_ampdu_list);
+
+		spin_unlock_irqrestore(&tid_info->queue.lock, f2);
+
+		if (unlikely(skb_queue_empty(&agg))) {
+#ifdef AR9170_TXAGG_DEBUG
+			printk(KERN_DEBUG "%s: queued empty list!\n",
+			       wiphy_name(ar->hw->wiphy));
+#endif /* AR9170_TXAGG_DEBUG */
+			continue;
+		}
+
+		/*
+		 * tell the FW/HW that this is the last frame,
+		 * that way it will wait for the immediate block ack.
+		 */
+		if (likely(skb_peek_tail(&agg)))
+			ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
+
+#ifdef AR9170_TXAGG_DEBUG
+		printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
+		       wiphy_name(ar->hw->wiphy));
+		__ar9170_dump_txqueue(ar, &agg);
+#endif /* AR9170_TXAGG_DEBUG */
+
+		spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+
+		spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
+		skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
+		spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
+		run = true;
+
+		spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
+	}
+
+out_unlock:
+	spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+	__skb_queue_purge(&agg);
+
+	return run;
+}
+
 static void ar9170_tx(struct ar9170 *ar)
 {
 	struct sk_buff *skb;
@@ -1382,11 +1720,17 @@ static void ar9170_tx(struct ar9170 *ar)
 			printk(KERN_DEBUG "%s: queue %d full\n",
 			       wiphy_name(ar->hw->wiphy), i);
 
-			__ar9170_dump_txstats(ar);
-			printk(KERN_DEBUG "stuck frames: ===> \n");
+			printk(KERN_DEBUG "%s: stuck frames: ===> \n",
+			       wiphy_name(ar->hw->wiphy));
 			ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
 			ar9170_dump_txqueue(ar, &ar->tx_status[i]);
 #endif /* AR9170_QUEUE_DEBUG */
+
+#ifdef AR9170_QUEUE_STOP_DEBUG
+			printk(KERN_DEBUG "%s: stop queue %d\n",
+			       wiphy_name(ar->hw->wiphy), i);
+			__ar9170_dump_txstats(ar);
+#endif /* AR9170_QUEUE_STOP_DEBUG */
 			ieee80211_stop_queue(ar->hw, i);
 			spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
 			continue;
@@ -1401,8 +1745,6 @@ static void ar9170_tx(struct ar9170 *ar)
 			       "remaining slots:%d, needed:%d\n",
 			       wiphy_name(ar->hw->wiphy), i, remaining_space,
 			       frames);
-
-			ar9170_dump_txstats(ar);
 #endif /* AR9170_QUEUE_DEBUG */
 			frames = remaining_space;
 		}
@@ -1430,6 +1772,9 @@ static void ar9170_tx(struct ar9170 *ar)
 			arinfo->timeout = jiffies +
 					  msecs_to_jiffies(AR9170_TX_TIMEOUT);
 
+			if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
+				ar->tx_ampdu_pending++;
+
 #ifdef AR9170_QUEUE_DEBUG
 			printk(KERN_DEBUG "%s: send frame q:%d =>\n",
 			       wiphy_name(ar->hw->wiphy), i);
@@ -1438,6 +1783,9 @@ static void ar9170_tx(struct ar9170 *ar)
 
 			err = ar->tx(ar, skb);
 			if (unlikely(err)) {
+				if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
+					ar->tx_ampdu_pending--;
+
 				frames_failed++;
 				dev_kfree_skb_any(skb);
 			} else {
@@ -1459,22 +1807,113 @@ static void ar9170_tx(struct ar9170 *ar)
 
 		if (unlikely(frames_failed)) {
 #ifdef AR9170_QUEUE_DEBUG
-			printk(KERN_DEBUG "%s: frames failed =>\n",
+			printk(KERN_DEBUG "%s: frames failed %d =>\n",
 			       wiphy_name(ar->hw->wiphy), frames_failed);
 #endif /* AR9170_QUEUE_DEBUG */
 
 			spin_lock_irqsave(&ar->tx_stats_lock, flags);
 			ar->tx_stats[i].len -= frames_failed;
 			ar->tx_stats[i].count -= frames_failed;
+#ifdef AR9170_QUEUE_STOP_DEBUG
+			printk(KERN_DEBUG "%s: wake queue %d\n",
+			       wiphy_name(ar->hw->wiphy), i);
+			__ar9170_dump_txstats(ar);
+#endif /* AR9170_QUEUE_STOP_DEBUG */
 			ieee80211_wake_queue(ar->hw, i);
 			spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
 		}
 	}
 
-	if (schedule_garbagecollector)
-		queue_delayed_work(ar->hw->workqueue,
-				   &ar->tx_janitor,
-				   msecs_to_jiffies(AR9170_JANITOR_DELAY));
+	if (!schedule_garbagecollector)
+		return;
+
+	ieee80211_queue_delayed_work(ar->hw,
+				     &ar->tx_janitor,
+				     msecs_to_jiffies(AR9170_JANITOR_DELAY));
+}
+
+static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *txinfo;
+	struct ar9170_sta_info *sta_info;
+	struct ar9170_sta_tid *agg;
+	struct sk_buff *iter;
+	unsigned long flags, f2;
+	unsigned int max;
+	u16 tid, seq, qseq;
+	bool run = false, queue = false;
+
+	tid = ar9170_get_tid(skb);
+	seq = ar9170_get_seq(skb);
+	txinfo = IEEE80211_SKB_CB(skb);
+	sta_info = (void *) txinfo->control.sta->drv_priv;
+	agg = &sta_info->agg[tid];
+	max = sta_info->ampdu_max_len;
+
+	spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
+
+	if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) {
+#ifdef AR9170_TXAGG_DEBUG
+		printk(KERN_DEBUG "%s: BlockACK session not fully initialized "
+		       "for ESS:%pM tid:%d state:%d.\n",
+		       wiphy_name(ar->hw->wiphy), agg->addr, agg->tid,
+		       agg->state);
+#endif /* AR9170_TXAGG_DEBUG */
+		goto err_unlock;
+	}
+
+	if (!agg->active) {
+		agg->active = true;
+		agg->ssn = seq;
+		queue = true;
+	}
+
+	/* check if seq is within the BA window */
+	if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) {
+#ifdef AR9170_TXAGG_DEBUG
+		printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not "
+		       "fit into BA window (%d - %d)\n",
+		       wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn,
+		       (agg->ssn + max) & 0xfff);
+#endif /* AR9170_TXAGG_DEBUG */
+		goto err_unlock;
+	}
+
+	spin_lock_irqsave(&agg->queue.lock, f2);
+
+	skb_queue_reverse_walk(&agg->queue, iter) {
+		qseq = ar9170_get_seq(iter);
+
+		if (GET_NEXT_SEQ(qseq) == seq) {
+			__skb_queue_after(&agg->queue, iter, skb);
+			goto queued;
+		}
+	}
+
+	__skb_queue_head(&agg->queue, skb);
+
+queued:
+	spin_unlock_irqrestore(&agg->queue.lock, f2);
+
+#ifdef AR9170_TXAGG_DEBUG
+	printk(KERN_DEBUG "%s: new aggregate %p queued.\n",
+	       wiphy_name(ar->hw->wiphy), skb);
+	__ar9170_dump_txqueue(ar, &agg->queue);
+#endif /* AR9170_TXAGG_DEBUG */
+
+	if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX)
+		run = true;
+
+	if (queue)
+		list_add_tail(&agg->list, &ar->tx_ampdu_list);
+
+	spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+	return run;
+
+err_unlock:
+	spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+	dev_kfree_skb_irq(skb);
+	return false;
 }
 
 int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -1490,8 +1929,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 
 	info = IEEE80211_SKB_CB(skb);
 	if (info->flags & IEEE80211_TX_CTL_AMPDU) {
-		/* drop frame, we do not allow TX A-MPDU aggregation yet. */
-		goto err_free;
+		bool run = ar9170_tx_ampdu_queue(ar, skb);
+
+		if (run || !ar->tx_ampdu_pending)
+			ar9170_tx_ampdu(ar);
 	} else {
 		unsigned int queue = skb_get_queue_mapping(skb);
 
@@ -1529,8 +1970,7 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw,
 	}
 
 	ar->cur_filter = 0;
-	ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
-	err = ar9170_update_frame_filter(ar);
+	err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
 	if (err)
 		goto unlock;
 
@@ -1548,8 +1988,7 @@ static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
 
 	mutex_lock(&ar->mutex);
 	ar->vif = NULL;
-	ar->want_filter = 0;
-	ar9170_update_frame_filter(ar);
+	ar9170_update_frame_filter(ar, 0);
 	ar9170_set_beacon_timers(ar);
 	dev_kfree_skb(ar->beacon);
 	ar->beacon = NULL;
@@ -1592,12 +2031,6 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
 			goto out;
 	}
 
-	if (changed & BSS_CHANGED_BEACON_INT) {
-		err = ar9170_set_beacon_timers(ar);
-		if (err)
-			goto out;
-	}
-
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 
 		/* adjust slot time for 5 GHz */
@@ -1621,48 +2054,37 @@ out:
 	return err;
 }
 
-static void ar9170_set_filters(struct work_struct *work)
+static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
+				       struct dev_addr_list *mclist)
 {
-	struct ar9170 *ar = container_of(work, struct ar9170,
-					 filter_config_work);
-	int err;
-
-	if (unlikely(!IS_STARTED(ar)))
-		return ;
-
-	mutex_lock(&ar->mutex);
-	if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
-			       &ar->filter_changed)) {
-		err = ar9170_set_operating_mode(ar);
-		if (err)
-			goto unlock;
-	}
+	u64 mchash;
+	int i;
 
-	if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
-			       &ar->filter_changed)) {
-		err = ar9170_update_multicast(ar);
-		if (err)
-			goto unlock;
-	}
+	/* always get broadcast frames */
+	mchash = 1ULL << (0xff >> 2);
 
-	if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
-			       &ar->filter_changed)) {
-		err = ar9170_update_frame_filter(ar);
-		if (err)
-			goto unlock;
+	for (i = 0; i < mc_count; i++) {
+		if (WARN_ON(!mclist))
+			break;
+		mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
+		mclist = mclist->next;
 	}
 
-unlock:
-	mutex_unlock(&ar->mutex);
+	return mchash;
 }
 
 static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
 				       unsigned int changed_flags,
 				       unsigned int *new_flags,
-				       int mc_count, struct dev_mc_list *mclist)
+				       u64 multicast)
 {
 	struct ar9170 *ar = hw->priv;
 
+	if (unlikely(!IS_ACCEPTING_CMD(ar)))
+		return ;
+
+	mutex_lock(&ar->mutex);
+
 	/* mask supported flags */
 	*new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
 		      FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
@@ -1672,26 +2094,11 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
 	 * then checking the error flags, later.
 	 */
 
-	if (changed_flags & FIF_ALLMULTI) {
-		if (*new_flags & FIF_ALLMULTI) {
-			ar->want_mc_hash = ~0ULL;
-		} else {
-			u64 mchash;
-			int i;
-
-			/* always get broadcast frames */
-			mchash = 1ULL << (0xff >> 2);
+	if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
+		multicast = ~0ULL;
 
-			for (i = 0; i < mc_count; i++) {
-				if (WARN_ON(!mclist))
-					break;
-				mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
-				mclist = mclist->next;
-			}
-		ar->want_mc_hash = mchash;
-		}
-		set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
-	}
+	if (multicast != ar->cur_mc_hash)
+		ar9170_update_multicast(ar, multicast);
 
 	if (changed_flags & FIF_CONTROL) {
 		u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
@@ -1702,24 +2109,22 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
 			     AR9170_MAC_REG_FTF_CFE_ACK;
 
 		if (*new_flags & FIF_CONTROL)
-			ar->want_filter = ar->cur_filter | filter;
+			filter |= ar->cur_filter;
 		else
-			ar->want_filter = ar->cur_filter & ~filter;
+			filter &= (~ar->cur_filter);
 
-		set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
-			&ar->filter_changed);
+		ar9170_update_frame_filter(ar, filter);
 	}
 
 	if (changed_flags & FIF_PROMISC_IN_BSS) {
 		ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
-		set_bit(AR9170_FILTER_CHANGED_MODE,
-			&ar->filter_changed);
+		ar9170_set_operating_mode(ar);
 	}
 
-	if (likely(IS_STARTED(ar)))
-		queue_work(ar->hw->workqueue, &ar->filter_config_work);
+	mutex_unlock(&ar->mutex);
 }
 
+
 static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_bss_conf *bss_conf,
@@ -1737,11 +2142,17 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
 			goto out;
 	}
 
-	if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
+	if (changed & BSS_CHANGED_BEACON_ENABLED)
+		ar->enable_beacon = bss_conf->enable_beacon;
+
+	if (changed & BSS_CHANGED_BEACON) {
 		err = ar9170_update_beacon(ar);
 		if (err)
 			goto out;
+	}
 
+	if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
+		       BSS_CHANGED_BEACON_INT)) {
 		err = ar9170_set_beacon_timers(ar);
 		if (err)
 			goto out;
@@ -1754,12 +2165,6 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
 #endif /* CONFIG_AR9170_LEDS */
 	}
 
-	if (changed & BSS_CHANGED_BEACON_INT) {
-		err = ar9170_set_beacon_timers(ar);
-		if (err)
-			goto out;
-	}
-
 	if (changed & BSS_CHANGED_HT) {
 		/* TODO */
 		err = 0;
@@ -1929,6 +2334,50 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
 			      enum sta_notify_cmd cmd,
 			      struct ieee80211_sta *sta)
 {
+	struct ar9170 *ar = hw->priv;
+	struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
+	unsigned int i;
+
+	switch (cmd) {
+	case STA_NOTIFY_ADD:
+		memset(sta_info, 0, sizeof(*sta_info));
+
+		if (!sta->ht_cap.ht_supported)
+			break;
+
+		if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
+			ar->global_ampdu_density = sta->ht_cap.ampdu_density;
+
+		if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
+			ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
+
+		for (i = 0; i < AR9170_NUM_TID; i++) {
+			sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
+			sta_info->agg[i].active = false;
+			sta_info->agg[i].ssn = 0;
+			sta_info->agg[i].retry = 0;
+			sta_info->agg[i].tid = i;
+			INIT_LIST_HEAD(&sta_info->agg[i].list);
+			skb_queue_head_init(&sta_info->agg[i].queue);
+		}
+
+		sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
+		break;
+
+	case STA_NOTIFY_REMOVE:
+		if (!sta->ht_cap.ht_supported)
+			break;
+
+		for (i = 0; i < AR9170_NUM_TID; i++) {
+			sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
+			skb_queue_purge(&sta_info->agg[i].queue);
+		}
+
+		break;
+
+	default:
+		break;
+	}
 }
 
 static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -1984,18 +2433,65 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw,
 			       enum ieee80211_ampdu_mlme_action action,
 			       struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
+	struct ar9170 *ar = hw->priv;
+	struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
+	struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
+	unsigned long flags;
+
+	if (!modparam_ht)
+		return -EOPNOTSUPP;
+
 	switch (action) {
+	case IEEE80211_AMPDU_TX_START:
+		spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
+		if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
+		    !list_empty(&tid_info->list)) {
+			spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+#ifdef AR9170_TXAGG_DEBUG
+			printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
+			       "is in a very bad state!\n",
+			       wiphy_name(hw->wiphy), sta->addr, tid);
+#endif /* AR9170_TXAGG_DEBUG */
+			return -EBUSY;
+		}
+
+		*ssn = tid_info->ssn;
+		tid_info->state = AR9170_TID_STATE_PROGRESS;
+		tid_info->active = false;
+		spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+		ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		break;
+
+	case IEEE80211_AMPDU_TX_STOP:
+		spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
+		tid_info->state = AR9170_TID_STATE_SHUTDOWN;
+		list_del_init(&tid_info->list);
+		tid_info->active = false;
+		skb_queue_purge(&tid_info->queue);
+		spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+		ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		break;
+
+	case IEEE80211_AMPDU_TX_OPERATIONAL:
+#ifdef AR9170_TXAGG_DEBUG
+		printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
+		       wiphy_name(hw->wiphy), sta->addr, tid);
+#endif /* AR9170_TXAGG_DEBUG */
+		spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
+		sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
+		spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
+		break;
+
 	case IEEE80211_AMPDU_RX_START:
 	case IEEE80211_AMPDU_RX_STOP:
-		/*
-		 * Something goes wrong -- RX locks up
-		 * after a while of receiving aggregated
-		 * frames -- not enabling for now.
-		 */
-		return -EOPNOTSUPP;
+		/* Handled by firmware */
+		break;
+
 	default:
 		return -EOPNOTSUPP;
 	}
+
+	return 0;
 }
 
 static const struct ieee80211_ops ar9170_ops = {
@@ -2005,6 +2501,7 @@ static const struct ieee80211_ops ar9170_ops = {
 	.add_interface		= ar9170_op_add_interface,
 	.remove_interface	= ar9170_op_remove_interface,
 	.config			= ar9170_op_config,
+	.prepare_multicast	= ar9170_op_prepare_multicast,
 	.configure_filter	= ar9170_op_configure_filter,
 	.conf_tx		= ar9170_conf_tx,
 	.bss_info_changed	= ar9170_op_bss_info_changed,
@@ -2044,14 +2541,16 @@ void *ar9170_alloc(size_t priv_size)
 	mutex_init(&ar->mutex);
 	spin_lock_init(&ar->cmdlock);
 	spin_lock_init(&ar->tx_stats_lock);
+	spin_lock_init(&ar->tx_ampdu_list_lock);
+	skb_queue_head_init(&ar->tx_status_ampdu);
 	for (i = 0; i < __AR9170_NUM_TXQ; i++) {
 		skb_queue_head_init(&ar->tx_status[i]);
 		skb_queue_head_init(&ar->tx_pending[i]);
 	}
 	ar9170_rx_reset_rx_mpdu(ar);
-	INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
 	INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
 	INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
+	INIT_LIST_HEAD(&ar->tx_ampdu_list);
 
 	/* all hw supports 2.4 GHz, so set channel to 1 by default */
 	ar->channel = &ar9170_2ghz_chantable[0];
@@ -2065,6 +2564,13 @@ void *ar9170_alloc(size_t priv_size)
 			 IEEE80211_HW_SIGNAL_DBM |
 			 IEEE80211_HW_NOISE_DBM;
 
+	if (modparam_ht) {
+		ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+	} else {
+		ar9170_band_2GHz.ht_cap.ht_supported = false;
+		ar9170_band_5GHz.ht_cap.ht_supported = false;
+	}
+
 	ar->hw->queues = __AR9170_NUM_TXQ;
 	ar->hw->extra_tx_headroom = 8;
 	ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
@@ -2086,10 +2592,11 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
 {
 #define RW	8	/* number of words to read at once */
 #define RB	(sizeof(u32) * RW)
-	DECLARE_MAC_BUF(mbuf);
+	struct ath_regulatory *regulatory = &ar->common.regulatory;
 	u8 *eeprom = (void *)&ar->eeprom;
 	u8 *addr = ar->eeprom.mac_address;
 	__le32 offsets[RW];
+	unsigned int rx_streams, tx_streams, tx_params = 0;
 	int i, j, err, bands = 0;
 
 	BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
@@ -2126,6 +2633,20 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
 		ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
 		bands++;
 	}
+
+	rx_streams = hweight8(ar->eeprom.rx_mask);
+	tx_streams = hweight8(ar->eeprom.tx_mask);
+
+	if (rx_streams != tx_streams)
+		tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
+
+	if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
+		tx_params = (tx_streams - 1) <<
+			    IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
+
+	ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
+	ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
+
 	/*
 	 * I measured this, a bandswitch takes roughly
 	 * 135 ms and a frequency switch about 80.
@@ -2138,8 +2659,8 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
 	else
 		ar->hw->channel_change_time = 80 * 1000;
 
-	ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
-	ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+	regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+	regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
 
 	/* second part of wiphy init */
 	SET_IEEE80211_PERM_ADDR(ar->hw, addr);
@@ -2153,11 +2674,12 @@ static int ar9170_reg_notifier(struct wiphy *wiphy,
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct ar9170 *ar = hw->priv;
 
-	return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
+	return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
 }
 
 int ar9170_register(struct ar9170 *ar, struct device *pdev)
 {
+	struct ath_regulatory *regulatory = &ar->common.regulatory;
 	int err;
 
 	/* try to read EEPROM, init MAC addr */
@@ -2165,7 +2687,7 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
 	if (err)
 		goto err_out;
 
-	err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
+	err = ath_regd_init(regulatory, ar->hw->wiphy,
 			    ar9170_reg_notifier);
 	if (err)
 		goto err_out;
@@ -2174,8 +2696,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
 	if (err)
 		goto err_out;
 
-	if (!ath_is_world_regd(&ar->regulatory))
-		regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
+	if (!ath_is_world_regd(regulatory))
+		regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
 
 	err = ar9170_init_leds(ar);
 	if (err)
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index df86f70..b3e5cf3 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -396,6 +396,136 @@ static struct ar9170_phy_init ar5416_phy_init[] = {
 	{ 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
 };
 
+/*
+ * look up a certain register in ar5416_phy_init[] and return the init. value
+ * for the band and bandwidth given. Return 0 if register address not found.
+ */
+static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz)
+{
+	unsigned int i;
+	for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+		if (ar5416_phy_init[i].reg != reg)
+			continue;
+
+		if (is_2ghz) {
+			if (is_40mhz)
+				return ar5416_phy_init[i]._2ghz_40;
+			else
+				return ar5416_phy_init[i]._2ghz_20;
+		} else {
+			if (is_40mhz)
+				return ar5416_phy_init[i]._5ghz_40;
+			else
+				return ar5416_phy_init[i]._5ghz_20;
+		}
+	}
+	return 0;
+}
+
+/*
+ * initialize some phy regs from eeprom values in modal_header[]
+ * acc. to band and bandwith
+ */
+static int ar9170_init_phy_from_eeprom(struct ar9170 *ar,
+				bool is_2ghz, bool is_40mhz)
+{
+	static const u8 xpd2pd[16] = {
+		0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
+		0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2
+	};
+	u32 defval, newval;
+	/* pointer to the modal_header acc. to band */
+	struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
+
+	ar9170_regwrite_begin(ar);
+
+	/* ant common control (index 0) */
+	newval = le32_to_cpu(m->antCtrlCommon);
+	ar9170_regwrite(0x1c5964, newval);
+
+	/* ant control chain 0 (index 1) */
+	newval = le32_to_cpu(m->antCtrlChain[0]);
+	ar9170_regwrite(0x1c5960, newval);
+
+	/* ant control chain 2 (index 2) */
+	newval = le32_to_cpu(m->antCtrlChain[1]);
+	ar9170_regwrite(0x1c7960, newval);
+
+	/* SwSettle (index 3) */
+	if (!is_40mhz) {
+		defval = ar9170_get_default_phy_reg_val(0x1c5844,
+							is_2ghz, is_40mhz);
+		newval = (defval & ~0x3f80) |
+			((m->switchSettling & 0x7f) << 7);
+		ar9170_regwrite(0x1c5844, newval);
+	}
+
+	/* adcDesired, pdaDesired (index 4) */
+	defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz);
+	newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) |
+		((u8)m->adcDesiredSize);
+	ar9170_regwrite(0x1c5850, newval);
+
+	/* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
+	defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz);
+	newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) |
+		(m->txFrameToXpaOn << 8) | m->txFrameToXpaOn;
+	ar9170_regwrite(0x1c5834, newval);
+
+	/* TxEndToRxOn (index 6) */
+	defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz);
+	newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16);
+	ar9170_regwrite(0x1c5828, newval);
+
+	/* thresh62 (index 7) */
+	defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz);
+	newval = (defval & ~0x7f000) | (m->thresh62 << 12);
+	ar9170_regwrite(0x1c8864, newval);
+
+	/* tx/rx attenuation chain 0 (index 8) */
+	defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz);
+	newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12);
+	ar9170_regwrite(0x1c5848, newval);
+
+	/* tx/rx attenuation chain 2 (index 9) */
+	defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz);
+	newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12);
+	ar9170_regwrite(0x1c7848, newval);
+
+	/* tx/rx margin chain 0 (index 10) */
+	defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz);
+	newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18);
+	/* bsw margin chain 0 for 5GHz only */
+	if (!is_2ghz)
+		newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10);
+	ar9170_regwrite(0x1c620c, newval);
+
+	/* tx/rx margin chain 2 (index 11) */
+	defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz);
+	newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18);
+	ar9170_regwrite(0x1c820c, newval);
+
+	/* iqCall, iqCallq chain 0 (index 12) */
+	defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz);
+	newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) |
+		((u8)m->iqCalQCh[0] & 0x1f);
+	ar9170_regwrite(0x1c5920, newval);
+
+	/* iqCall, iqCallq chain 2 (index 13) */
+	defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz);
+	newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) |
+		((u8)m->iqCalQCh[1] & 0x1f);
+	ar9170_regwrite(0x1c7920, newval);
+
+	/* xpd gain mask (index 14) */
+	defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz);
+	newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16);
+	ar9170_regwrite(0x1c6258, newval);
+	ar9170_regwrite_finish();
+
+	return ar9170_regwrite_result();
+}
+
 int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
 {
 	int i, err;
@@ -426,7 +556,9 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
 	if (err)
 		return err;
 
-	/* XXX: use EEPROM data here! */
+	err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
+	if (err)
+		return err;
 
 	err = ar9170_init_power_cal(ar);
 	if (err)
@@ -987,6 +1119,282 @@ static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
 #undef SHIFT
 }
 
+static u8 ar9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array)
+{
+	int i;
+
+	for (i = 0; i < 3; i++)
+		if (x <= x_array[i + 1])
+			break;
+
+	return ar9170_interpolate_u8(x,
+				     x_array[i],
+				     y_array[i],
+				     x_array[i + 1],
+				     y_array[i + 1]);
+}
+
+static int ar9170_set_freq_cal_data(struct ar9170 *ar,
+				    struct ieee80211_channel *channel)
+{
+	u8 *cal_freq_pier;
+	u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
+	u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
+	int chain, idx, i;
+	u8 f;
+
+	switch (channel->band) {
+	case IEEE80211_BAND_2GHZ:
+		f = channel->center_freq - 2300;
+		cal_freq_pier = ar->eeprom.cal_freq_pier_2G;
+		i = AR5416_NUM_2G_CAL_PIERS - 1;
+		break;
+
+	case IEEE80211_BAND_5GHZ:
+		f = (channel->center_freq - 4800) / 5;
+		cal_freq_pier = ar->eeprom.cal_freq_pier_5G;
+		i = AR5416_NUM_5G_CAL_PIERS - 1;
+		break;
+
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	for (; i >= 0; i--) {
+		if (cal_freq_pier[i] != 0xff)
+			break;
+	}
+	if (i < 0)
+		return -EINVAL;
+
+	idx = ar9170_find_freq_idx(i, cal_freq_pier, f);
+
+	ar9170_regwrite_begin(ar);
+
+	for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) {
+		for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) {
+			struct ar9170_calibration_data_per_freq *cal_pier_data;
+			int j;
+
+			switch (channel->band) {
+			case IEEE80211_BAND_2GHZ:
+				cal_pier_data = &ar->eeprom.
+					cal_pier_data_2G[chain][idx];
+				break;
+
+			case IEEE80211_BAND_5GHZ:
+				cal_pier_data = &ar->eeprom.
+					cal_pier_data_5G[chain][idx];
+				break;
+
+			default:
+				return -EINVAL;
+			}
+
+			for (j = 0; j < 2; j++) {
+				vpds[j][i] = ar9170_interpolate_u8(f,
+					cal_freq_pier[idx],
+					cal_pier_data->vpd_pdg[j][i],
+					cal_freq_pier[idx + 1],
+					cal_pier_data[1].vpd_pdg[j][i]);
+
+				pwrs[j][i] = ar9170_interpolate_u8(f,
+					cal_freq_pier[idx],
+					cal_pier_data->pwr_pdg[j][i],
+					cal_freq_pier[idx + 1],
+					cal_pier_data[1].pwr_pdg[j][i]) / 2;
+			}
+		}
+
+		for (i = 0; i < 76; i++) {
+			u32 phy_data;
+			u8 tmp;
+
+			if (i < 25) {
+				tmp = ar9170_interpolate_val(i, &pwrs[0][0],
+							     &vpds[0][0]);
+			} else {
+				tmp = ar9170_interpolate_val(i - 12,
+							     &pwrs[1][0],
+							     &vpds[1][0]);
+			}
+
+			phy_data |= tmp << ((i & 3) << 3);
+			if ((i & 3) == 3) {
+				ar9170_regwrite(0x1c6280 + chain * 0x1000 +
+						(i & ~3), phy_data);
+				phy_data = 0;
+			}
+		}
+
+		for (i = 19; i < 32; i++)
+			ar9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
+					0x0);
+	}
+
+	ar9170_regwrite_finish();
+	return ar9170_regwrite_result();
+}
+
+static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
+				    struct ar9170_calctl_edges edges[],
+				    u32 freq)
+{
+/* TODO: move somewhere else */
+#define AR5416_MAX_RATE_POWER        63
+
+	int i;
+	u8 rc = AR5416_MAX_RATE_POWER;
+	u8 f;
+	if (freq < 3000)
+		f = freq - 2300;
+	else
+		f = (freq - 4800) / 5;
+
+	for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
+		if (edges[i].channel == 0xff)
+			break;
+		if (f == edges[i].channel) {
+			/* exact freq match */
+			rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS;
+			break;
+		}
+		if (i > 0 && f < edges[i].channel) {
+			if (f > edges[i-1].channel &&
+			    edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
+				/* lower channel has the inband flag set */
+				rc = edges[i-1].power_flags &
+					~AR9170_CALCTL_EDGE_FLAGS;
+			}
+			break;
+		}
+	}
+
+	if (i == AR5416_NUM_BAND_EDGES) {
+		if (f > edges[i-1].channel &&
+		    edges[i-1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
+			/* lower channel has the inband flag set */
+			rc = edges[i-1].power_flags &
+				~AR9170_CALCTL_EDGE_FLAGS;
+		}
+	}
+	return rc;
+}
+
+/* calculate the conformance test limits and apply them to ar->power*
+ * (derived from otus hal/hpmain.c, line 3706 ff.)
+ */
+static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
+{
+	u8 ctl_grp; /* CTL group */
+	u8 ctl_idx; /* CTL index */
+	int i, j;
+	struct ctl_modes {
+		u8 ctl_mode;
+		u8 max_power;
+		u8 *pwr_cal_data;
+		int pwr_cal_len;
+	} *modes;
+
+	/* order is relevant in the mode_list_*: we fall back to the
+	 * lower indices if any mode is missed in the EEPROM.
+	 */
+	struct ctl_modes mode_list_2ghz[] = {
+		{ CTL_11B, 0, ar->power_2G_cck, 4 },
+		{ CTL_11G, 0, ar->power_2G_ofdm, 4 },
+		{ CTL_2GHT20, 0, ar->power_2G_ht20, 8 },
+		{ CTL_2GHT40, 0, ar->power_2G_ht40, 8 },
+	};
+	struct ctl_modes mode_list_5ghz[] = {
+		{ CTL_11A, 0, ar->power_5G_leg, 4 },
+		{ CTL_5GHT20, 0, ar->power_5G_ht20, 8 },
+		{ CTL_5GHT40, 0, ar->power_5G_ht40, 8 },
+	};
+	int nr_modes;
+
+#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
+
+	/* TODO: investigate the differences between OTUS'
+	 * hpreg.c::zfHpGetRegulatoryDomain() and
+	 * ath/regd.c::ath_regd_get_band_ctl() -
+	 * e.g. for FCC3_WORLD the OTUS procedure
+	 * always returns CTL_FCC, while the one in ath/ delivers
+	 * CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
+	 */
+	ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
+					ar->hw->conf.channel->band);
+
+	/* ctl group not found - either invalid band (NO_CTL) or ww roaming */
+	if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
+		ctl_grp = CTL_FCC;
+
+	if (ctl_grp != CTL_FCC)
+		/* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
+		return;
+
+	if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
+		modes = mode_list_2ghz;
+		nr_modes = ARRAY_SIZE(mode_list_2ghz);
+	} else {
+		modes = mode_list_5ghz;
+		nr_modes = ARRAY_SIZE(mode_list_5ghz);
+	}
+
+	for (i = 0; i < nr_modes; i++) {
+		u8 c = ctl_grp | modes[i].ctl_mode;
+		for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++)
+			if (c == ar->eeprom.ctl_index[ctl_idx])
+				break;
+		if (ctl_idx < AR5416_NUM_CTLS) {
+			int f_off = 0;
+
+			/* adjust freq for 40MHz */
+			if (modes[i].ctl_mode == CTL_2GHT40 ||
+			    modes[i].ctl_mode == CTL_5GHT40) {
+				if (bw == AR9170_BW_40_BELOW)
+					f_off = -10;
+				else
+					f_off = 10;
+			}
+
+			modes[i].max_power =
+				ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1),
+							  freq+f_off);
+
+			/* TODO: check if the regulatory max. power is
+			 *  controlled by cfg80211 for DFS
+			 * (hpmain applies it to max_power itself for DFS freq)
+			 */
+
+		} else {
+			/* Workaround in otus driver, hpmain.c, line 3906:
+			 * if no data for 5GHT20 are found, take the
+			 * legacy 5G value.
+			 * We extend this here to fallback from any other *HT or
+			 * 11G, too.
+			 */
+			int k = i;
+
+			modes[i].max_power = AR5416_MAX_RATE_POWER;
+			while (k-- > 0) {
+				if (modes[k].max_power !=
+				    AR5416_MAX_RATE_POWER) {
+					modes[i].max_power = modes[k].max_power;
+					break;
+				}
+			}
+		}
+
+		/* apply max power to pwr_cal_data (ar->power_*) */
+		for (j = 0; j < modes[i].pwr_cal_len; j++) {
+			modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j],
+						       modes[i].max_power);
+		}
+	}
+#undef EDGES
+}
+
 static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
 {
 	struct ar9170_calibration_target_power_legacy *ctpl;
@@ -1089,6 +1497,12 @@ static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
 					ctph[idx + 1].power[n]);
 	}
 
+
+	/* calc. conformance test limits and apply to ar->power*[] */
+	ar9170_calc_ctl(ar, freq, bw);
+
+	/* TODO: (heavy clip) regulatory domain power level fine-tuning. */
+
 	/* set ACK/CTS TX power */
 	ar9170_regwrite_begin(ar);
 
@@ -1207,6 +1621,10 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
 	if (err)
 		return err;
 
+	err = ar9170_set_freq_cal_data(ar, channel);
+	if (err)
+		return err;
+
 	err = ar9170_set_power_cal(ar, channel->center_freq, bw);
 	if (err)
 		return err;
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index 007eb85..e0138ac 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -783,7 +783,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
 	aru->req_one_stage_fw = ar9170_requires_one_stage(id);
 
 	usb_set_intfdata(intf, aru);
-	SET_IEEE80211_DEV(ar->hw, &udev->dev);
+	SET_IEEE80211_DEV(ar->hw, &intf->dev);
 
 	init_usb_anchor(&aru->rx_submitted);
 	init_usb_anchor(&aru->tx_pending);
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
new file mode 100644
index 0000000..a63e90c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ATH_H
+#define ATH_H
+
+#include <linux/skbuff.h>
+
+struct reg_dmn_pair_mapping {
+	u16 regDmnEnum;
+	u16 reg_5ghz_ctl;
+	u16 reg_2ghz_ctl;
+};
+
+struct ath_regulatory {
+	char alpha2[2];
+	u16 country_code;
+	u16 max_power_level;
+	u32 tp_scale;
+	u16 current_rd;
+	u16 current_rd_ext;
+	int16_t power_limit;
+	struct reg_dmn_pair_mapping *regpair;
+};
+
+struct ath_common {
+	u16 cachelsz;
+	struct ath_regulatory regulatory;
+};
+
+struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
+				u32 len,
+				gfp_t gfp_mask);
+
+#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index daf0c83..06d0066 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,7 +1,6 @@
 config ATH5K
 	tristate "Atheros 5xxx wireless cards support"
-	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
-	select ATH_COMMON
+	depends on PCI && MAC80211 && WLAN_80211
 	select MAC80211_LEDS
 	select LEDS_CLASS
 	select NEW_LEDS
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6358233..6cd5efc 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -27,8 +27,6 @@
 #include <linux/types.h>
 #include <net/mac80211.h>
 
-#include "../regd.h"
-
 /* RX/TX descriptor hw structs
  * TODO: Driver part should only see sw structs */
 #include "desc.h"
@@ -308,6 +306,7 @@ struct ath5k_srev_name {
 #define AR5K_SREV_AR5311B	0x30 /* Spirit */
 #define AR5K_SREV_AR5211	0x40 /* Oahu */
 #define AR5K_SREV_AR5212	0x50 /* Venice */
+#define AR5K_SREV_AR5212_V4	0x54 /* ??? */
 #define AR5K_SREV_AR5213	0x55 /* ??? */
 #define AR5K_SREV_AR5213A	0x59 /* Hainan */
 #define AR5K_SREV_AR2413	0x78 /* Griffin lite */
@@ -713,8 +712,8 @@ struct ath5k_gain {
  * Used internaly for reset_tx_queue).
  * Also see struct struct ieee80211_channel.
  */
-#define IS_CHAN_XR(_c)	((_c.hw_value & CHANNEL_XR) != 0)
-#define IS_CHAN_B(_c)	((_c.hw_value & CHANNEL_B) != 0)
+#define IS_CHAN_XR(_c)	((_c->hw_value & CHANNEL_XR) != 0)
+#define IS_CHAN_B(_c)	((_c->hw_value & CHANNEL_B) != 0)
 
 /*
  * The following structure is used to map 2GHz channels to
@@ -919,6 +918,12 @@ enum ath5k_int {
 	AR5K_INT_NOCARD	= 0xffffffff
 };
 
+/* Software interrupts used for calibration */
+enum ath5k_software_interrupt {
+	AR5K_SWI_FULL_CALIBRATION = 0x01,
+	AR5K_SWI_SHORT_CALIBRATION = 0x02,
+};
+
 /*
  * Power management
  */
@@ -1029,14 +1034,16 @@ struct ath5k_hw {
 	enum ath5k_int		ah_imr;
 
 	enum nl80211_iftype	ah_op_mode;
-	enum ath5k_power_mode	ah_power_mode;
-	struct ieee80211_channel ah_current_channel;
+	struct ieee80211_channel *ah_current_channel;
 	bool			ah_turbo;
 	bool			ah_calibration;
-	bool			ah_running;
 	bool			ah_single_chip;
+	bool			ah_aes_support;
 	bool			ah_combined_mic;
 
+	enum ath5k_version	ah_version;
+	enum ath5k_radio	ah_radio;
+	u32			ah_phy;
 	u32			ah_mac_srev;
 	u16			ah_mac_version;
 	u16			ah_mac_revision;
@@ -1044,13 +1051,6 @@ struct ath5k_hw {
 	u16			ah_radio_5ghz_revision;
 	u16			ah_radio_2ghz_revision;
 
-	enum ath5k_version	ah_version;
-	enum ath5k_radio	ah_radio;
-	u32			ah_phy;
-
-	bool			ah_5ghz;
-	bool			ah_2ghz;
-
 #define ah_modes		ah_capabilities.cap_mode
 #define ah_ee_version		ah_capabilities.cap_eeprom.ee_version
 
@@ -1058,7 +1058,6 @@ struct ath5k_hw {
 	u32			ah_aifs;
 	u32			ah_cw_min;
 	u32			ah_cw_max;
-	bool			ah_software_retry;
 	u32			ah_limit_tx_retries;
 
 	/* Antenna Control */
@@ -1066,6 +1065,7 @@ struct ath5k_hw {
 	u8			ah_ant_mode;
 	u8			ah_tx_ant;
 	u8			ah_def_ant;
+	bool			ah_software_retry;
 
 	u8			ah_sta_id[ETH_ALEN];
 
@@ -1075,10 +1075,8 @@ struct ath5k_hw {
 	u8			ah_bssid[ETH_ALEN];
 	u8			ah_bssid_mask[ETH_ALEN];
 
-	u32			ah_gpio[AR5K_MAX_GPIO];
 	int			ah_gpio_npins;
 
-	struct ath_regulatory	ah_regulatory;
 	struct ath5k_capabilities ah_capabilities;
 
 	struct ath5k_txq_info	ah_txq[AR5K_NUM_TX_QUEUES];
@@ -1130,6 +1128,15 @@ struct ath5k_hw {
 	/* noise floor from last periodic calibration */
 	s32			ah_noise_floor;
 
+	/* Calibration timestamp */
+	unsigned long		ah_cal_tstamp;
+
+	/* Calibration interval (secs) */
+	u8			ah_cal_intval;
+
+	/* Software interrupt mask */
+	u8			ah_swi_mask;
+
 	/*
 	 * Function pointers
 	 */
@@ -1153,7 +1160,7 @@ struct ath5k_hw {
  */
 
 /* Attach/Detach Functions */
-extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
+extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc);
 extern void ath5k_hw_detach(struct ath5k_hw *ah);
 
 /* LED functions */
@@ -1164,6 +1171,7 @@ extern void ath5k_unregister_leds(struct ath5k_softc *sc);
 
 /* Reset Functions */
 extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
+extern int ath5k_hw_on_hold(struct ath5k_hw *ah);
 extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
 /* Power management functions */
 extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
@@ -1282,6 +1290,7 @@ extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *chann
 /* PHY calibration */
 extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
 extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
+extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
 /* Spur mitigation */
 bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
 				struct ieee80211_channel *channel);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index c41ef58..71a1bd2 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -95,17 +95,17 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
  * ath5k_hw_attach - Check if hw is supported and init the needed structs
  *
  * @sc: The &struct ath5k_softc we got from the driver's attach function
- * @mac_version: The mac version id (check out ath5k.h) based on pci id
  *
  * Check if the device is supported, perform a POST and initialize the needed
  * structs. Returns -ENOMEM if we don't have memory for the needed structs,
  * -ENODEV if the device is not supported or prints an error msg if something
  * else went wrong.
  */
-struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
+struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
 {
 	struct ath5k_hw *ah;
 	struct pci_dev *pdev = sc->pdev;
+	struct ath5k_eeprom_info *ee;
 	int ret;
 	u32 srev;
 
@@ -135,9 +135,15 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 	ah->ah_software_retry = false;
 
 	/*
-	 * Set the mac version based on the pci id
+	 * Find the mac version
 	 */
-	ah->ah_version = mac_version;
+	srev = ath5k_hw_reg_read(ah, AR5K_SREV);
+	if (srev < AR5K_SREV_AR5311)
+		ah->ah_version = AR5K_AR5210;
+	else if (srev < AR5K_SREV_AR5212)
+		ah->ah_version = AR5K_AR5211;
+	else
+		ah->ah_version = AR5K_AR5212;
 
 	/*Fill the ath5k_hw struct with the needed functions*/
 	ret = ath5k_hw_init_desc_functions(ah);
@@ -145,12 +151,11 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 		goto err_free;
 
 	/* Bring device out of sleep and reset it's units */
-	ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
+	ret = ath5k_hw_nic_wakeup(ah, 0, true);
 	if (ret)
 		goto err_free;
 
 	/* Get MAC, PHY and RADIO revisions */
-	srev = ath5k_hw_reg_read(ah, AR5K_SREV);
 	ah->ah_mac_srev = srev;
 	ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
 	ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
@@ -253,28 +258,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 	}
 
 	/*
-	 * Write PCI-E power save settings
-	 */
-	if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
-		ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
-		ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
-		/* Shut off RX when elecidle is asserted */
-		ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
-		ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
-		/* TODO: EEPROM work */
-		ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
-		/* Shut off PLL and CLKREQ active in L1 */
-		ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
-		/* Preserce other settings */
-		ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
-		ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
-		ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
-		/* Reset SERDES to load new settings */
-		ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
-		mdelay(1);
-	}
-
-	/*
 	 * POST
 	 */
 	ret = ath5k_hw_post(ah);
@@ -283,7 +266,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 
 	/* Enable pci core retry fix on Hainan (5213A) and later chips */
 	if (srev >= AR5K_SREV_AR5213A)
-		ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
+		AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_RETRY_FIX);
 
 	/*
 	 * Get card capabilities, calibration values etc
@@ -295,6 +278,40 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 		goto err_free;
 	}
 
+	/*
+	 * Write PCI-E power save settings
+	 */
+	if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
+		struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+
+		ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
+		ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
+
+		/* Shut off RX when elecidle is asserted */
+		ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
+		ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
+
+		/* If serdes programing is enabled, increase PCI-E
+		 * tx power for systems with long trace from host
+		 * to minicard connector. */
+		if (ee->ee_serdes)
+			ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
+		else
+			ath5k_hw_reg_write(ah, 0xf6800579, AR5K_PCIE_SERDES);
+
+		/* Shut off PLL and CLKREQ active in L1 */
+		ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
+
+		/* Preserve other settings */
+		ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
+		ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
+		ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
+
+		/* Reset SERDES to load new settings */
+		ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
+		mdelay(1);
+	}
+
 	/* Get misc capabilities */
 	ret = ath5k_hw_set_capabilities(ah);
 	if (ret) {
@@ -303,6 +320,12 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 		goto err_free;
 	}
 
+	/* Crypto settings */
+	ee = &ah->ah_capabilities.cap_eeprom;
+	ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 &&
+		(ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
+		 !AR5K_EEPROM_AES_DIS(ee->ee_misc5));
+
 	if (srev >= AR5K_SREV_AR2414) {
 		ah->ah_combined_mic = true;
 		AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
@@ -319,6 +342,9 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
 
 	ath5k_hw_rfgain_opt_init(ah);
 
+	/* turn on HW LEDs */
+	ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
+
 	return ah;
 err_free:
 	kfree(ah);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 029c1bc..9c6ab53 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -59,7 +59,7 @@
 #include "reg.h"
 #include "debug.h"
 
-static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
+static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
 static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
@@ -84,24 +84,24 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
 
 /* Known PCI ids */
 static const struct pci_device_id ath5k_pci_id_table[] = {
-	{ PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
-	{ PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
-	{ PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
-	{ PCI_VDEVICE(ATHEROS, 0x0012), .driver_data = AR5K_AR5211 }, /* 5211 */
-	{ PCI_VDEVICE(ATHEROS, 0x0013), .driver_data = AR5K_AR5212 }, /* 5212 */
-	{ PCI_VDEVICE(3COM_2,  0x0013), .driver_data = AR5K_AR5212 }, /* 3com 5212 */
-	{ PCI_VDEVICE(3COM,    0x0013), .driver_data = AR5K_AR5212 }, /* 3com 3CRDAG675 5212 */
-	{ PCI_VDEVICE(ATHEROS, 0x1014), .driver_data = AR5K_AR5212 }, /* IBM minipci 5212 */
-	{ PCI_VDEVICE(ATHEROS, 0x0014), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0015), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0016), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0017), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0018), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-	{ PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
-	{ PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
-	{ PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */
-	{ PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */
+	{ PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */
+	{ PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */
+	{ PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/
+	{ PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */
+	{ PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */
+	{ PCI_VDEVICE(3COM_2,  0x0013) }, /* 3com 5212 */
+	{ PCI_VDEVICE(3COM,    0x0013) }, /* 3com 3CRDAG675 5212 */
+	{ PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */
+	{ PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */
+	{ PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */
+	{ PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */
+	{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
+	{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
+	{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
@@ -218,6 +218,8 @@ static struct pci_driver ath5k_pci_driver = {
  * Prototypes - MAC 802.11 stack related functions
  */
 static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+		struct ath5k_txq *txq);
 static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
 static int ath5k_reset_wake(struct ath5k_softc *sc);
 static int ath5k_start(struct ieee80211_hw *hw);
@@ -227,10 +229,12 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 static void ath5k_remove_interface(struct ieee80211_hw *hw,
 		struct ieee80211_if_init_conf *conf);
 static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
+static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
+				   int mc_count, struct dev_addr_list *mc_list);
 static void ath5k_configure_filter(struct ieee80211_hw *hw,
 		unsigned int changed_flags,
 		unsigned int *new_flags,
-		int mc_count, struct dev_mc_list *mclist);
+		u64 multicast);
 static int ath5k_set_key(struct ieee80211_hw *hw,
 		enum set_key_cmd cmd,
 		struct ieee80211_vif *vif, struct ieee80211_sta *sta,
@@ -248,6 +252,8 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 		struct ieee80211_vif *vif,
 		struct ieee80211_bss_conf *bss_conf,
 		u32 changes);
+static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
+static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
 
 static const struct ieee80211_ops ath5k_hw_ops = {
 	.tx 		= ath5k_tx,
@@ -256,6 +262,7 @@ static const struct ieee80211_ops ath5k_hw_ops = {
 	.add_interface 	= ath5k_add_interface,
 	.remove_interface = ath5k_remove_interface,
 	.config 	= ath5k_config,
+	.prepare_multicast = ath5k_prepare_multicast,
 	.configure_filter = ath5k_configure_filter,
 	.set_key 	= ath5k_set_key,
 	.get_stats 	= ath5k_get_stats,
@@ -265,6 +272,8 @@ static const struct ieee80211_ops ath5k_hw_ops = {
 	.set_tsf 	= ath5k_set_tsf,
 	.reset_tsf 	= ath5k_reset_tsf,
 	.bss_info_changed = ath5k_bss_info_changed,
+	.sw_scan_start	= ath5k_sw_scan_start,
+	.sw_scan_complete = ath5k_sw_scan_complete,
 };
 
 /*
@@ -297,7 +306,8 @@ static void	ath5k_desc_free(struct ath5k_softc *sc,
 static int 	ath5k_rxbuf_setup(struct ath5k_softc *sc,
 				struct ath5k_buf *bf);
 static int 	ath5k_txbuf_setup(struct ath5k_softc *sc,
-				struct ath5k_buf *bf);
+				struct ath5k_buf *bf,
+				struct ath5k_txq *txq);
 static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
 				struct ath5k_buf *bf)
 {
@@ -369,7 +379,7 @@ static int 	ath5k_stop_hw(struct ath5k_softc *sc);
 static irqreturn_t ath5k_intr(int irq, void *dev_id);
 static void 	ath5k_tasklet_reset(unsigned long data);
 
-static void 	ath5k_calibrate(unsigned long data);
+static void 	ath5k_tasklet_calibrate(unsigned long data);
 
 /*
  * Module init/exit functions
@@ -464,7 +474,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 		 * DMA to work so force a reasonable value here if it
 		 * comes up zero.
 		 */
-		csz = L1_CACHE_BYTES / sizeof(u32);
+		csz = L1_CACHE_BYTES >> 2;
 		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
 	}
 	/*
@@ -512,6 +522,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 	/* Initialize driver private data */
 	SET_IEEE80211_DEV(hw, &pdev->dev);
 	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+		    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 		    IEEE80211_HW_SIGNAL_DBM |
 		    IEEE80211_HW_NOISE_DBM;
 
@@ -536,7 +547,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 	__set_bit(ATH_STAT_INVALID, sc->status);
 
 	sc->iobase = mem; /* So we can unmap it on detach */
-	sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
+	sc->common.cachelsz = csz << 2; /* convert to bytes */
 	sc->opmode = NL80211_IFTYPE_STATION;
 	sc->bintval = 1000;
 	mutex_init(&sc->lock);
@@ -555,7 +566,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
 	}
 
 	/* Initialize device */
-	sc->ah = ath5k_hw_attach(sc, id->driver_data);
+	sc->ah = ath5k_hw_attach(sc);
 	if (IS_ERR(sc->ah)) {
 		ret = PTR_ERR(sc->ah);
 		goto err_irq;
@@ -666,7 +677,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	ath5k_led_off(sc);
 
-	free_irq(pdev->irq, sc);
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
@@ -694,18 +704,8 @@ ath5k_pci_resume(struct pci_dev *pdev)
 	 */
 	pci_write_config_byte(pdev, 0x41, 0);
 
-	err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
-	if (err) {
-		ATH5K_ERR(sc, "request_irq failed\n");
-		goto err_no_irq;
-	}
-
 	ath5k_led_enable(sc);
 	return 0;
-
-err_no_irq:
-	pci_disable_device(pdev);
-	return err;
 }
 #endif /* CONFIG_PM */
 
@@ -718,9 +718,9 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
 {
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct ath5k_softc *sc = hw->priv;
-	struct ath_regulatory *reg = &sc->ah->ah_regulatory;
+	struct ath_regulatory *regulatory = &sc->common.regulatory;
 
-	return ath_reg_notifier_apply(wiphy, request, reg);
+	return ath_reg_notifier_apply(wiphy, request, regulatory);
 }
 
 static int
@@ -728,6 +728,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 {
 	struct ath5k_softc *sc = hw->priv;
 	struct ath5k_hw *ah = sc->ah;
+	struct ath_regulatory *regulatory = &sc->common.regulatory;
 	u8 mac[ETH_ALEN] = {};
 	int ret;
 
@@ -785,19 +786,25 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 		goto err_desc;
 	}
 	sc->bhalq = ret;
+	sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0);
+	if (IS_ERR(sc->cabq)) {
+		ATH5K_ERR(sc, "can't setup cab queue\n");
+		ret = PTR_ERR(sc->cabq);
+		goto err_bhal;
+	}
 
 	sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
 	if (IS_ERR(sc->txq)) {
 		ATH5K_ERR(sc, "can't setup xmit queue\n");
 		ret = PTR_ERR(sc->txq);
-		goto err_bhal;
+		goto err_queues;
 	}
 
 	tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
 	tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
 	tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
+	tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
 	tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
-	setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
 
 	ret = ath5k_eeprom_read_mac(ah, mac);
 	if (ret) {
@@ -811,9 +818,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 	memset(sc->bssidmask, 0xff, ETH_ALEN);
 	ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
 
-	ah->ah_regulatory.current_rd =
-		ah->ah_capabilities.cap_eeprom.ee_regdomain;
-	ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier);
+	regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
+	ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
 	if (ret) {
 		ATH5K_ERR(sc, "can't initialize regulatory system\n");
 		goto err_queues;
@@ -825,8 +831,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
 		goto err_queues;
 	}
 
-	if (!ath_is_world_regd(&sc->ah->ah_regulatory))
-		regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2);
+	if (!ath_is_world_regd(regulatory))
+		regulatory_hint(hw->wiphy, regulatory->alpha2);
 
 	ath5k_init_leds(sc);
 
@@ -1068,10 +1074,9 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
 }
 
 /*
- * Set/change channels.  If the channel is really being changed,
- * it's done by reseting the chip.  To accomplish this we must
- * first cleanup any pending DMA, then restart stuff after a la
- * ath5k_init.
+ * Set/change channels. We always reset the chip.
+ * To accomplish this we must first cleanup any pending DMA,
+ * then restart stuff after a la  ath5k_init.
  *
  * Called with sc->lock.
  */
@@ -1081,19 +1086,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
 	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
 		sc->curchan->center_freq, chan->center_freq);
 
-	if (chan->center_freq != sc->curchan->center_freq ||
-		chan->hw_value != sc->curchan->hw_value) {
-
-		/*
-		 * To switch channels clear any pending DMA operations;
-		 * wait long enough for the RX fifo to drain, reset the
-		 * hardware at the new frequency, and then re-enable
-		 * the relevant bits of the h/w.
-		 */
-		return ath5k_reset(sc, chan);
-	}
-
-	return 0;
+	/*
+	 * To switch channels clear any pending DMA operations;
+	 * wait long enough for the RX fifo to drain, reset the
+	 * hardware at the new frequency, and then re-enable
+	 * the relevant bits of the h/w.
+	 */
+	return ath5k_reset(sc, chan);
 }
 
 static void
@@ -1114,6 +1113,8 @@ ath5k_mode_setup(struct ath5k_softc *sc)
 	struct ath5k_hw *ah = sc->ah;
 	u32 rfilt;
 
+	ah->ah_op_mode = sc->opmode;
+
 	/* configure rx filter */
 	rfilt = sc->filter_flags;
 	ath5k_hw_set_rx_filter(ah, rfilt);
@@ -1153,27 +1154,20 @@ static
 struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
 {
 	struct sk_buff *skb;
-	unsigned int off;
 
 	/*
 	 * Allocate buffer with headroom_needed space for the
 	 * fake physical layer header at the start.
 	 */
-	skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
+	skb = ath_rxbuf_alloc(&sc->common,
+			      sc->rxbufsize + sc->common.cachelsz - 1,
+			      GFP_ATOMIC);
 
 	if (!skb) {
 		ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
-				sc->rxbufsize + sc->cachelsz - 1);
+				sc->rxbufsize + sc->common.cachelsz - 1);
 		return NULL;
 	}
-	/*
-	 * Cache-line-align.  This is important (for the
-	 * 5210 at least) as not doing so causes bogus data
-	 * in rx'd frames.
-	 */
-	off = ((unsigned long)skb->data) % sc->cachelsz;
-	if (off != 0)
-		skb_reserve(skb, sc->cachelsz - off);
 
 	*skb_addr = pci_map_single(sc->pdev,
 		skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
@@ -1228,10 +1222,10 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
 }
 
 static int
-ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
+		  struct ath5k_txq *txq)
 {
 	struct ath5k_hw *ah = sc->ah;
-	struct ath5k_txq *txq = sc->txq;
 	struct ath5k_desc *ds = bf->desc;
 	struct sk_buff *skb = bf->skb;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1615,10 +1609,10 @@ ath5k_rx_start(struct ath5k_softc *sc)
 	struct ath5k_buf *bf;
 	int ret;
 
-	sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz);
+	sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz);
 
 	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
-		sc->cachelsz, sc->rxbufsize);
+		sc->common.cachelsz, sc->rxbufsize);
 
 	spin_lock_bh(&sc->rxbuflock);
 	sc->rxlink = NULL;
@@ -1747,7 +1741,7 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
 static void
 ath5k_tasklet_rx(unsigned long data)
 {
-	struct ieee80211_rx_status rxs = {};
+	struct ieee80211_rx_status *rxs;
 	struct ath5k_rx_status rs = {};
 	struct sk_buff *skb, *next_skb;
 	dma_addr_t next_skb_addr;
@@ -1757,6 +1751,7 @@ ath5k_tasklet_rx(unsigned long data)
 	int ret;
 	int hdrlen;
 	int padsize;
+	int rx_flag;
 
 	spin_lock(&sc->rxbuflock);
 	if (list_empty(&sc->rxbuf)) {
@@ -1764,7 +1759,7 @@ ath5k_tasklet_rx(unsigned long data)
 		goto unlock;
 	}
 	do {
-		rxs.flag = 0;
+		rx_flag = 0;
 
 		bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
 		BUG_ON(bf->skb == NULL);
@@ -1808,7 +1803,7 @@ ath5k_tasklet_rx(unsigned long data)
 					goto accept;
 			}
 			if (rs.rs_status & AR5K_RXERR_MIC) {
-				rxs.flag |= RX_FLAG_MMIC_ERROR;
+				rx_flag |= RX_FLAG_MMIC_ERROR;
 				goto accept;
 			}
 
@@ -1846,6 +1841,7 @@ accept:
 			memmove(skb->data + padsize, skb->data, hdrlen);
 			skb_pull(skb, padsize);
 		}
+		rxs = IEEE80211_SKB_RXCB(skb);
 
 		/*
 		 * always extend the mac timestamp, since this information is
@@ -1867,41 +1863,41 @@ accept:
 		 * impossible to comply to that. This affects IBSS merge only
 		 * right now, so it's not too bad...
 		 */
-		rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
-		rxs.flag |= RX_FLAG_TSFT;
+		rxs->mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
+		rxs->flag = rx_flag | RX_FLAG_TSFT;
 
-		rxs.freq = sc->curchan->center_freq;
-		rxs.band = sc->curband->band;
+		rxs->freq = sc->curchan->center_freq;
+		rxs->band = sc->curband->band;
 
-		rxs.noise = sc->ah->ah_noise_floor;
-		rxs.signal = rxs.noise + rs.rs_rssi;
+		rxs->noise = sc->ah->ah_noise_floor;
+		rxs->signal = rxs->noise + rs.rs_rssi;
 
 		/* An rssi of 35 indicates you should be able use
 		 * 54 Mbps reliably. A more elaborate scheme can be used
 		 * here but it requires a map of SNR/throughput for each
 		 * possible mode used */
-		rxs.qual = rs.rs_rssi * 100 / 35;
+		rxs->qual = rs.rs_rssi * 100 / 35;
 
 		/* rssi can be more than 35 though, anything above that
 		 * should be considered at 100% */
-		if (rxs.qual > 100)
-			rxs.qual = 100;
+		if (rxs->qual > 100)
+			rxs->qual = 100;
 
-		rxs.antenna = rs.rs_antenna;
-		rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
-		rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
+		rxs->antenna = rs.rs_antenna;
+		rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
+		rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
 
-		if (rxs.rate_idx >= 0 && rs.rs_rate ==
-		    sc->curband->bitrates[rxs.rate_idx].hw_value_short)
-			rxs.flag |= RX_FLAG_SHORTPRE;
+		if (rxs->rate_idx >= 0 && rs.rs_rate ==
+		    sc->curband->bitrates[rxs->rate_idx].hw_value_short)
+			rxs->flag |= RX_FLAG_SHORTPRE;
 
 		ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
 
 		/* check beacons in IBSS mode */
 		if (sc->opmode == NL80211_IFTYPE_ADHOC)
-			ath5k_check_ibss_tsf(sc, skb, &rxs);
+			ath5k_check_ibss_tsf(sc, skb, rxs);
 
-		__ieee80211_rx(sc->hw, skb, &rxs);
+		ieee80211_rx(sc->hw, skb);
 
 		bf->skb = next_skb;
 		bf->skbaddr = next_skb_addr;
@@ -1994,9 +1990,12 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
 static void
 ath5k_tasklet_tx(unsigned long data)
 {
+	int i;
 	struct ath5k_softc *sc = (void *)data;
 
-	ath5k_tx_processq(sc, sc->txq);
+	for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
+		if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
+			ath5k_tx_processq(sc, &sc->txqs[i]);
 }
 
 
@@ -2078,13 +2077,6 @@ err_unmap:
 	return ret;
 }
 
-static void ath5k_beacon_disable(struct ath5k_softc *sc)
-{
-	sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
-	ath5k_hw_set_imr(sc->ah, sc->imask);
-	ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
-}
-
 /*
  * Transmit a beacon frame at SWBA.  Dynamic updates to the
  * frame contents are done as needed and the slot time is
@@ -2098,6 +2090,7 @@ ath5k_beacon_send(struct ath5k_softc *sc)
 {
 	struct ath5k_buf *bf = sc->bbuf;
 	struct ath5k_hw *ah = sc->ah;
+	struct sk_buff *skb;
 
 	ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
 
@@ -2151,6 +2144,12 @@ ath5k_beacon_send(struct ath5k_softc *sc)
 	ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
 		sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
 
+	skb = ieee80211_get_buffered_bc(sc->hw, sc->vif);
+	while (skb) {
+		ath5k_tx_queue(sc->hw, skb, sc->cabq);
+		skb = ieee80211_get_buffered_bc(sc->hw, sc->vif);
+	}
+
 	sc->bsent++;
 }
 
@@ -2271,13 +2270,11 @@ ath5k_beacon_config(struct ath5k_softc *sc)
 	struct ath5k_hw *ah = sc->ah;
 	unsigned long flags;
 
-	ath5k_hw_set_imr(ah, 0);
+	spin_lock_irqsave(&sc->block, flags);
 	sc->bmisscount = 0;
 	sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
 
-	if (sc->opmode == NL80211_IFTYPE_ADHOC ||
-			sc->opmode == NL80211_IFTYPE_MESH_POINT ||
-			sc->opmode == NL80211_IFTYPE_AP) {
+	if (sc->enable_beacon) {
 		/*
 		 * In IBSS mode we use a self-linked tx descriptor and let the
 		 * hardware send the beacons automatically. We have to load it
@@ -2290,16 +2287,17 @@ ath5k_beacon_config(struct ath5k_softc *sc)
 		sc->imask |= AR5K_INT_SWBA;
 
 		if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-			if (ath5k_hw_hasveol(ah)) {
-				spin_lock_irqsave(&sc->block, flags);
+			if (ath5k_hw_hasveol(ah))
 				ath5k_beacon_send(sc);
-				spin_unlock_irqrestore(&sc->block, flags);
-			}
 		} else
 			ath5k_beacon_update_timers(sc, -1);
+	} else {
+		ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
 	}
 
 	ath5k_hw_set_imr(ah, sc->imask);
+	mmiowb();
+	spin_unlock_irqrestore(&sc->block, flags);
 }
 
 static void ath5k_tasklet_beacon(unsigned long data)
@@ -2363,7 +2361,7 @@ ath5k_init(struct ath5k_softc *sc)
 	sc->curband = &sc->sbands[sc->curchan->band];
 	sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
 		AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
-		AR5K_INT_FATAL | AR5K_INT_GLOBAL;
+		AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI;
 	ret = ath5k_reset(sc, NULL);
 	if (ret)
 		goto done;
@@ -2380,8 +2378,8 @@ ath5k_init(struct ath5k_softc *sc)
 	/* Set ack to be sent at low bit-rates */
 	ath5k_hw_set_ack_bitrate_high(ah, false);
 
-	mod_timer(&sc->calib_tim, round_jiffies(jiffies +
-			msecs_to_jiffies(ath5k_calinterval * 1000)));
+	/* Set PHY calibration inteval */
+	ah->ah_cal_intval = ath5k_calinterval;
 
 	ret = 0;
 done:
@@ -2445,37 +2443,39 @@ ath5k_stop_hw(struct ath5k_softc *sc)
 	ret = ath5k_stop_locked(sc);
 	if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
 		/*
-		 * Set the chip in full sleep mode.  Note that we are
-		 * careful to do this only when bringing the interface
-		 * completely to a stop.  When the chip is in this state
-		 * it must be carefully woken up or references to
-		 * registers in the PCI clock domain may freeze the bus
-		 * (and system).  This varies by chip and is mostly an
-		 * issue with newer parts that go to sleep more quickly.
-		 */
-		if (sc->ah->ah_mac_srev >= 0x78) {
-			/*
-			 * XXX
-			 * don't put newer MAC revisions > 7.8 to sleep because
-			 * of the above mentioned problems
-			 */
-			ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
-				"not putting device to sleep\n");
-		} else {
-			ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
-				"putting device to full sleep\n");
-			ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
-		}
+		 * Don't set the card in full sleep mode!
+		 *
+		 * a) When the device is in this state it must be carefully
+		 * woken up or references to registers in the PCI clock
+		 * domain may freeze the bus (and system).  This varies
+		 * by chip and is mostly an issue with newer parts
+		 * (madwifi sources mentioned srev >= 0x78) that go to
+		 * sleep more quickly.
+		 *
+		 * b) On older chips full sleep results a weird behaviour
+		 * during wakeup. I tested various cards with srev < 0x78
+		 * and they don't wake up after module reload, a second
+		 * module reload is needed to bring the card up again.
+		 *
+		 * Until we figure out what's going on don't enable
+		 * full chip reset on any chip (this is what Legacy HAL
+		 * and Sam's HAL do anyway). Instead Perform a full reset
+		 * on the device (same as initial state after attach) and
+		 * leave it idle (keep MAC/BB on warm reset) */
+		ret = ath5k_hw_on_hold(sc->ah);
+
+		ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+				"putting device to sleep\n");
 	}
 	ath5k_txbuf_free(sc, sc->bbuf);
 
 	mmiowb();
 	mutex_unlock(&sc->lock);
 
-	del_timer_sync(&sc->calib_tim);
 	tasklet_kill(&sc->rxtq);
 	tasklet_kill(&sc->txtq);
 	tasklet_kill(&sc->restq);
+	tasklet_kill(&sc->calib);
 	tasklet_kill(&sc->beacontq);
 
 	ath5k_rfkill_hw_stop(sc->ah);
@@ -2531,6 +2531,9 @@ ath5k_intr(int irq, void *dev_id)
 			if (status & AR5K_INT_BMISS) {
 				/* TODO */
 			}
+			if (status & AR5K_INT_SWI) {
+				tasklet_schedule(&sc->calib);
+			}
 			if (status & AR5K_INT_MIB) {
 				/*
 				 * These stats are also used for ANI i think
@@ -2547,6 +2550,8 @@ ath5k_intr(int irq, void *dev_id)
 	if (unlikely(!counter))
 		ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
 
+	ath5k_hw_calibration_poll(ah);
+
 	return IRQ_HANDLED;
 }
 
@@ -2563,11 +2568,19 @@ ath5k_tasklet_reset(unsigned long data)
  * for temperature/environment changes.
  */
 static void
-ath5k_calibrate(unsigned long data)
+ath5k_tasklet_calibrate(unsigned long data)
 {
 	struct ath5k_softc *sc = (void *)data;
 	struct ath5k_hw *ah = sc->ah;
 
+	/* Only full calibration for now */
+	if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION)
+		return;
+
+	/* Stop queues so that calibration
+	 * doesn't interfere with tx */
+	ieee80211_stop_queues(sc->hw);
+
 	ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
 		ieee80211_frequency_to_channel(sc->curchan->center_freq),
 		sc->curchan->hw_value);
@@ -2585,8 +2598,11 @@ ath5k_calibrate(unsigned long data)
 			ieee80211_frequency_to_channel(
 				sc->curchan->center_freq));
 
-	mod_timer(&sc->calib_tim, round_jiffies(jiffies +
-			msecs_to_jiffies(ath5k_calinterval * 1000)));
+	ah->ah_swi_mask = 0;
+
+	/* Wake queues */
+	ieee80211_wake_queues(sc->hw);
+
 }
 
 
@@ -2598,6 +2614,14 @@ static int
 ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct ath5k_softc *sc = hw->priv;
+
+	return ath5k_tx_queue(hw, skb, sc->txq);
+}
+
+static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
+			  struct ath5k_txq *txq)
+{
+	struct ath5k_softc *sc = hw->priv;
 	struct ath5k_buf *bf;
 	unsigned long flags;
 	int hdrlen;
@@ -2641,7 +2665,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 
 	bf->skb = skb;
 
-	if (ath5k_txbuf_setup(sc, bf)) {
+	if (ath5k_txbuf_setup(sc, bf, txq)) {
 		bf->skb = NULL;
 		spin_lock_irqsave(&sc->txbuflock, flags);
 		list_add_tail(&bf->list, &sc->txbuf);
@@ -2676,7 +2700,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
 		sc->curchan = chan;
 		sc->curband = &sc->sbands[chan->band];
 	}
-	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
+	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL);
 	if (ret) {
 		ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
 		goto err;
@@ -2757,6 +2781,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
 	}
 
 	ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
+	ath5k_mode_setup(sc);
 
 	ret = 0;
 end:
@@ -2776,7 +2801,6 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
 		goto end;
 
 	ath5k_hw_set_lladdr(sc->ah, mac);
-	ath5k_beacon_disable(sc);
 	sc->vif = NULL;
 end:
 	mutex_unlock(&sc->lock);
@@ -2795,9 +2819,11 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
 
 	mutex_lock(&sc->lock);
 
-	ret = ath5k_chan_set(sc, conf->channel);
-	if (ret < 0)
-		goto unlock;
+	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+		ret = ath5k_chan_set(sc, conf->channel);
+		if (ret < 0)
+			goto unlock;
+	}
 
 	if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
 	(sc->power_level != conf->power_level)) {
@@ -2831,6 +2857,37 @@ unlock:
 	return ret;
 }
 
+static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
+				   int mc_count, struct dev_addr_list *mclist)
+{
+	u32 mfilt[2], val;
+	int i;
+	u8 pos;
+
+	mfilt[0] = 0;
+	mfilt[1] = 1;
+
+	for (i = 0; i < mc_count; i++) {
+		if (!mclist)
+			break;
+		/* calculate XOR of eight 6-bit values */
+		val = get_unaligned_le32(mclist->dmi_addr + 0);
+		pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+		val = get_unaligned_le32(mclist->dmi_addr + 3);
+		pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+		pos &= 0x3f;
+		mfilt[pos / 32] |= (1 << (pos % 32));
+		/* XXX: we might be able to just do this instead,
+		* but not sure, needs testing, if we do use this we'd
+		* neet to inform below to not reset the mcast */
+		/* ath5k_hw_set_mcast_filterindex(ah,
+		 *      mclist->dmi_addr[5]); */
+		mclist = mclist->next;
+	}
+
+	return ((u64)(mfilt[1]) << 32) | mfilt[0];
+}
+
 #define SUPPORTED_FIF_FLAGS \
 	FIF_PROMISC_IN_BSS |  FIF_ALLMULTI | FIF_FCSFAIL | \
 	FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
@@ -2856,16 +2913,16 @@ unlock:
 static void ath5k_configure_filter(struct ieee80211_hw *hw,
 		unsigned int changed_flags,
 		unsigned int *new_flags,
-		int mc_count, struct dev_mc_list *mclist)
+		u64 multicast)
 {
 	struct ath5k_softc *sc = hw->priv;
 	struct ath5k_hw *ah = sc->ah;
-	u32 mfilt[2], val, rfilt;
-	u8 pos;
-	int i;
+	u32 mfilt[2], rfilt;
 
-	mfilt[0] = 0;
-	mfilt[1] = 0;
+	mutex_lock(&sc->lock);
+
+	mfilt[0] = multicast;
+	mfilt[1] = multicast >> 32;
 
 	/* Only deal with supported flags */
 	changed_flags &= SUPPORTED_FIF_FLAGS;
@@ -2891,24 +2948,6 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
 	if (*new_flags & FIF_ALLMULTI) {
 		mfilt[0] =  ~0;
 		mfilt[1] =  ~0;
-	} else {
-		for (i = 0; i < mc_count; i++) {
-			if (!mclist)
-				break;
-			/* calculate XOR of eight 6-bit values */
-			val = get_unaligned_le32(mclist->dmi_addr + 0);
-			pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-			val = get_unaligned_le32(mclist->dmi_addr + 3);
-			pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-			pos &= 0x3f;
-			mfilt[pos / 32] |= (1 << (pos % 32));
-			/* XXX: we might be able to just do this instead,
-			* but not sure, needs testing, if we do use this we'd
-			* neet to inform below to not reset the mcast */
-			/* ath5k_hw_set_mcast_filterindex(ah,
-			 *      mclist->dmi_addr[5]); */
-			mclist = mclist->next;
-		}
 	}
 
 	/* This is the best we can do */
@@ -2932,22 +2971,25 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
 
 	/* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
 
-	if (sc->opmode == NL80211_IFTYPE_MONITOR)
-		rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
-			AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
-	if (sc->opmode != NL80211_IFTYPE_STATION)
-		rfilt |= AR5K_RX_FILTER_PROBEREQ;
-	if (sc->opmode != NL80211_IFTYPE_AP &&
-		sc->opmode != NL80211_IFTYPE_MESH_POINT &&
-		test_bit(ATH_STAT_PROMISC, sc->status))
-		rfilt |= AR5K_RX_FILTER_PROM;
-	if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) ||
-		sc->opmode == NL80211_IFTYPE_ADHOC ||
-		sc->opmode == NL80211_IFTYPE_AP)
-		rfilt |= AR5K_RX_FILTER_BEACON;
-	if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
-		rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
-			AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
+	switch (sc->opmode) {
+	case NL80211_IFTYPE_MESH_POINT:
+	case NL80211_IFTYPE_MONITOR:
+		rfilt |= AR5K_RX_FILTER_CONTROL |
+			 AR5K_RX_FILTER_BEACON |
+			 AR5K_RX_FILTER_PROBEREQ |
+			 AR5K_RX_FILTER_PROM;
+		break;
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_ADHOC:
+		rfilt |= AR5K_RX_FILTER_PROBEREQ |
+			 AR5K_RX_FILTER_BEACON;
+		break;
+	case NL80211_IFTYPE_STATION:
+		if (sc->assoc)
+			rfilt |= AR5K_RX_FILTER_BEACON;
+	default:
+		break;
+	}
 
 	/* Set filters */
 	ath5k_hw_set_rx_filter(ah, rfilt);
@@ -2957,6 +2999,8 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
 	/* Set the cached hw filter flags, this will alter actually
 	 * be set in HW */
 	sc->filter_flags = rfilt;
+
+	mutex_unlock(&sc->lock);
 }
 
 static int
@@ -2978,6 +3022,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 	case ALG_TKIP:
 		break;
 	case ALG_CCMP:
+		if (sc->ah->ah_aes_support)
+			break;
+
 		return -EOPNOTSUPP;
 	default:
 		WARN_ON(1);
@@ -3108,25 +3155,6 @@ out:
 	return ret;
 }
 
-/*
- *  Update the beacon and reconfigure the beacon queues.
- */
-static void
-ath5k_beacon_reconfig(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-{
-	int ret;
-	unsigned long flags;
-	struct ath5k_softc *sc = hw->priv;
-
-	spin_lock_irqsave(&sc->block, flags);
-	ret = ath5k_beacon_update(hw, vif);
-	spin_unlock_irqrestore(&sc->block, flags);
-	if (ret == 0) {
-		ath5k_beacon_config(sc);
-		mmiowb();
-	}
-}
-
 static void
 set_beacon_filter(struct ieee80211_hw *hw, bool enable)
 {
@@ -3149,6 +3177,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 {
 	struct ath5k_softc *sc = hw->priv;
 	struct ath5k_hw *ah = sc->ah;
+	unsigned long flags;
 
 	mutex_lock(&sc->lock);
 	if (WARN_ON(sc->vif != vif))
@@ -3170,15 +3199,37 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
 		sc->assoc = bss_conf->assoc;
 		if (sc->opmode == NL80211_IFTYPE_STATION)
 			set_beacon_filter(hw, sc->assoc);
+		ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
+			AR5K_LED_ASSOC : AR5K_LED_INIT);
 	}
 
-	if (changes & BSS_CHANGED_BEACON &&
-	    (vif->type == NL80211_IFTYPE_ADHOC ||
-	     vif->type == NL80211_IFTYPE_MESH_POINT ||
-	     vif->type == NL80211_IFTYPE_AP)) {
-		ath5k_beacon_reconfig(hw, vif);
+	if (changes & BSS_CHANGED_BEACON) {
+		spin_lock_irqsave(&sc->block, flags);
+		ath5k_beacon_update(hw, vif);
+		spin_unlock_irqrestore(&sc->block, flags);
 	}
 
+	if (changes & BSS_CHANGED_BEACON_ENABLED)
+		sc->enable_beacon = bss_conf->enable_beacon;
+
+	if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED |
+		       BSS_CHANGED_BEACON_INT))
+		ath5k_beacon_config(sc);
+
  unlock:
 	mutex_unlock(&sc->lock);
 }
+
+static void ath5k_sw_scan_start(struct ieee80211_hw *hw)
+{
+	struct ath5k_softc *sc = hw->priv;
+	if (!sc->assoc)
+		ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN);
+}
+
+static void ath5k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+	struct ath5k_softc *sc = hw->priv;
+	ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
+		AR5K_LED_ASSOC : AR5K_LED_INIT);
+}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index f9b7f2f..a28c42f 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -51,6 +51,9 @@
 #include "ath5k.h"
 #include "debug.h"
 
+#include "../regd.h"
+#include "../ath.h"
+
 #define	ATH_RXBUF	40		/* number of RX buffers */
 #define	ATH_TXBUF	200		/* number of TX buffers */
 #define ATH_BCBUF	1		/* number of beacon buffers */
@@ -112,10 +115,10 @@ struct ath5k_rfkill {
  * associated with an instance of a device */
 struct ath5k_softc {
 	struct pci_dev		*pdev;		/* for dma mapping */
+	struct ath_common	common;
 	void __iomem		*iobase;	/* address of the device */
 	struct mutex		lock;		/* dev-level lock */
-	/* FIXME: how many does it really need? */
-	struct ieee80211_tx_queue_stats tx_stats[16];
+	struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
 	struct ieee80211_low_level_stats ll_stats;
 	struct ieee80211_hw	*hw;		/* IEEE 802.11 common */
 	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
@@ -135,7 +138,6 @@ struct ath5k_softc {
 	struct ath5k_desc	*desc;		/* TX/RX descriptors */
 	dma_addr_t		desc_daddr;	/* DMA (physical) address */
 	size_t			desc_len;	/* size of TX/RX descriptors */
-	u16			cachelsz;	/* cache line size */
 
 	DECLARE_BITMAP(status, 5);
 #define ATH_STAT_INVALID	0		/* disable hardware accesses */
@@ -171,14 +173,15 @@ struct ath5k_softc {
 	struct list_head	txbuf;		/* transmit buffer */
 	spinlock_t		txbuflock;
 	unsigned int		txbuf_len;	/* buf count in txbuf list */
-	struct ath5k_txq	txqs[2];	/* beacon and tx */
-
-	struct ath5k_txq	*txq;		/* beacon and tx*/
+	struct ath5k_txq	txqs[AR5K_NUM_TX_QUEUES];	/* tx queues */
+	struct ath5k_txq	*txq;		/* main tx queue */
 	struct tasklet_struct	txtq;		/* tx intr tasklet */
 	struct ath5k_led	tx_led;		/* tx led */
 
 	struct ath5k_rfkill	rf_kill;
 
+	struct tasklet_struct	calib;		/* calibration tasklet */
+
 	spinlock_t		block;		/* protects beacon */
 	struct tasklet_struct	beacontq;	/* beacon intr tasklet */
 	struct ath5k_buf	*bbuf;		/* beacon buffer */
@@ -187,10 +190,11 @@ struct ath5k_softc {
 				bintval,	/* beacon interval in TU */
 				bsent;
 	unsigned int		nexttbtt;	/* next beacon time in TU */
+	struct ath5k_txq	*cabq;		/* content after beacon */
 
-	struct timer_list	calib_tim;	/* calibration timer */
 	int 			power_level;	/* Requested tx power in dbm */
 	bool			assoc;		/* assocate state */
+	bool			enable_beacon;	/* true if beacons are on */
 };
 
 #define ath5k_hw_hasbssidmask(_ah) \
@@ -198,4 +202,15 @@ struct ath5k_softc {
 #define ath5k_hw_hasveol(_ah) \
 	(ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
 
+static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
+{
+	return &ah->ah_sc->common;
+}
+
+static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
+{
+	return &(ath5k_hw_common(ah)->regulatory);
+
+}
+
 #endif
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
index 4904a07..747508c 100644
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -380,13 +380,15 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
 	sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
 				ath5k_global_debugfs);
 
-	sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUGO,
+	sc->debug.debugfs_debug = debugfs_create_file("debug",
+				S_IWUSR | S_IRUSR,
 				sc->debug.debugfs_phydir, sc, &fops_debug);
 
-	sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
+	sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR,
 				sc->debug.debugfs_phydir, sc, &fops_registers);
 
-	sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
+	sc->debug.debugfs_beacon = debugfs_create_file("beacon",
+				S_IWUSR | S_IRUSR,
 				sc->debug.debugfs_phydir, sc, &fops_beacon);
 
 	sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index c56b494..644962a 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -167,6 +167,16 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
 	ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
 	ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
 
+	/* Check if PCIE_OFFSET points to PCIE_SERDES_SECTION
+	 * and enable serdes programming if needed.
+	 *
+	 * XXX: Serdes values seem to be fixed so
+	 * no need to read them here, we write them
+	 * during ath5k_hw_attach */
+	AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
+	ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
+							true : false;
+
 	return 0;
 }
 
@@ -404,27 +414,11 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
 		break;
 	}
 
-done:
-	/* return new offset */
-	*offset = o;
-
-	return 0;
-}
-
-/*
- * Read turbo mode information on newer EEPROM versions
- */
-static int
-ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
-			      u32 *offset, unsigned int mode)
-{
-	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-	u32 o = *offset;
-	u16 val;
-	int ret;
-
+	/*
+	 * Read turbo mode information on newer EEPROM versions
+	 */
 	if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
-		return 0;
+		goto done;
 
 	switch (mode){
 	case AR5K_EEPROM_MODE_11A:
@@ -458,6 +452,7 @@ ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
 		break;
 	}
 
+done:
 	/* return new offset */
 	*offset = o;
 
@@ -494,10 +489,6 @@ ath5k_eeprom_init_modes(struct ath5k_hw *ah)
 		ret = ath5k_eeprom_read_modes(ah, &offset, mode);
 		if (ret)
 			return ret;
-
-		ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode);
-		if (ret)
-			return ret;
 	}
 
 	/* override for older eeprom versions for better performance */
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 64be73a..0123f35 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -19,6 +19,9 @@
 /*
  * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
  */
+#define	AR5K_EEPROM_PCIE_OFFSET		0x02	/* Contains offset to PCI-E infos */
+#define	AR5K_EEPROM_PCIE_SERDES_SECTION	0x40	/* PCIE_OFFSET points here when
+						 * SERDES infos are present */
 #define AR5K_EEPROM_MAGIC		0x003d	/* EEPROM Magic number */
 #define AR5K_EEPROM_MAGIC_VALUE		0x5aa5	/* Default - found on EEPROM */
 #define AR5K_EEPROM_MAGIC_5212		0x0000145c /* 5212 */
@@ -391,6 +394,7 @@ struct ath5k_eeprom_info {
 	u8	ee_rfkill_pin;
 	bool	ee_rfkill_pol;
 	bool	ee_is_hb63;
+	bool	ee_serdes;
 	u16	ee_misc0;
 	u16	ee_misc1;
 	u16	ee_misc2;
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index 876725f..b767c3b 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -69,6 +69,8 @@ static const struct pci_device_id ath5k_led_devices[] = {
 	{ ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
 	/* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
 	{ ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
+	/* HP Compaq C700 (nitrousnrg@gmail.com) */
+	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
 	/* IBM-specific AR5212 (all others) */
 	{ PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
 	{ }
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index a876ca8..1a039f2 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -740,13 +740,22 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 						AR5K_RF_XPD_GAIN, true);
 
 		} else {
-			/* TODO: Set high and low gain bits */
-			ath5k_hw_rfb_op(ah, rf_regs,
-						ee->ee_x_gain[ee_mode],
+			u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
+			if (ee->ee_pd_gains[ee_mode] > 1) {
+				ath5k_hw_rfb_op(ah, rf_regs,
+						pdg_curve_to_idx[0],
 						AR5K_RF_PD_GAIN_LO, true);
-			ath5k_hw_rfb_op(ah, rf_regs,
-						ee->ee_x_gain[ee_mode],
+				ath5k_hw_rfb_op(ah, rf_regs,
+						pdg_curve_to_idx[1],
 						AR5K_RF_PD_GAIN_HI, true);
+			} else {
+				ath5k_hw_rfb_op(ah, rf_regs,
+						pdg_curve_to_idx[0],
+						AR5K_RF_PD_GAIN_LO, true);
+				ath5k_hw_rfb_op(ah, rf_regs,
+						pdg_curve_to_idx[0],
+						AR5K_RF_PD_GAIN_HI, true);
+			}
 
 			/* Lower synth voltage on Rev 2 */
 			ath5k_hw_rfb_op(ah, rf_regs, 2,
@@ -1085,8 +1094,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
 				AR5K_PHY_CCKTXCTL_WORLD);
 	}
 
-	ah->ah_current_channel.center_freq = channel->center_freq;
-	ah->ah_current_channel.hw_value = channel->hw_value;
+	ah->ah_current_channel = channel;
 	ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
 
 	return 0;
@@ -1096,6 +1104,29 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
   PHY calibration
 \*****************/
 
+void
+ath5k_hw_calibration_poll(struct ath5k_hw *ah)
+{
+	/* Calibration interval in jiffies */
+	unsigned long cal_intval;
+
+	cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000);
+
+	/* Initialize timestamp if needed */
+	if (!ah->ah_cal_tstamp)
+		ah->ah_cal_tstamp = jiffies;
+
+	/* For now we always do full calibration
+	 * Mark software interrupt mask and fire software
+	 * interrupt (bit gets auto-cleared) */
+	if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) {
+		ah->ah_cal_tstamp = jiffies;
+		ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
+		AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
+	}
+
+}
+
 /**
  * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
  *
@@ -1731,7 +1762,7 @@ ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
 void
 ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
 {
-	struct ieee80211_channel *channel = &ah->ah_current_channel;
+	struct ieee80211_channel *channel = ah->ah_current_channel;
 	bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
 	bool use_def_for_sg;
 	u8 def_ant, tx_ant, ee_mode;
@@ -1897,8 +1928,9 @@ ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
 	s16 min_pwrL, min_pwrR;
 	s16 pwr_i;
 
-	if (WARN_ON(stepL[0] == stepL[1] || stepR[0] == stepR[1]))
-		return 0;
+	/* Some vendors write the same pcdac value twice !!! */
+	if (stepL[0] == stepL[1] || stepR[0] == stepR[1])
+		return max(pwrL[0], pwrR[0]);
 
 	if (pwrL[0] == pwrL[1])
 		min_pwrL = pwrL[0];
@@ -2166,6 +2198,7 @@ static void
 ath5k_get_max_ctl_power(struct ath5k_hw *ah,
 			struct ieee80211_channel *channel)
 {
+	struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
 	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
 	struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
 	u8 *ctl_val = ee->ee_ctl;
@@ -2176,7 +2209,7 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
 	u8 ctl_idx = 0xFF;
 	u32 target = channel->center_freq;
 
-	ctl_mode = ath_regd_get_band_ctl(&ah->ah_regulatory, channel->band);
+	ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);
 
 	switch (channel->hw_value & CHANNEL_MODES) {
 	case CHANNEL_A:
@@ -3011,7 +3044,7 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
 int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
 {
 	/*Just a try M.F.*/
-	struct ieee80211_channel *channel = &ah->ah_current_channel;
+	struct ieee80211_channel *channel = ah->ah_current_channel;
 	u8 ee_mode;
 
 	ATH5K_TRACE(ah->ah_sc);
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index 73407b3..eeebb9a 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -362,7 +362,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 		}
 
 		if (tq->tqi_ready_time &&
-		(tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
+		(tq->tqi_type != AR5K_TX_QUEUE_CAB))
 			ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
 				AR5K_QCU_RDYTIMECFG_INTVAL) |
 				AR5K_QCU_RDYTIMECFG_ENABLE,
@@ -411,7 +411,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 			AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
 				AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
 				AR5K_QCU_MISC_CBREXP_DIS |
-				AR5K_QCU_MISC_RDY_VEOL_POLICY |
 				AR5K_QCU_MISC_CBREXP_BCN_DIS);
 
 			ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 6809b54..debad07 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -339,9 +339,9 @@
 #define AR5K_SISR2		0x008c			/* Register Address [5211+] */
 #define AR5K_SISR2_QCU_TXURN	0x000003ff	/* Mask for QCU_TXURN */
 #define	AR5K_SISR2_QCU_TXURN_S	0
-#define	AR5K_SISR2_MCABT	0x00100000	/* Master Cycle Abort */
-#define	AR5K_SISR2_SSERR	0x00200000	/* Signaled System Error */
-#define	AR5K_SISR2_DPERR	0x00400000	/* Bus parity error */
+#define	AR5K_SISR2_MCABT	0x00010000	/* Master Cycle Abort */
+#define	AR5K_SISR2_SSERR	0x00020000	/* Signaled System Error */
+#define	AR5K_SISR2_DPERR	0x00040000	/* Bus parity error */
 #define	AR5K_SISR2_TIM		0x01000000	/* [5212+] */
 #define	AR5K_SISR2_CAB_END	0x02000000	/* [5212+] */
 #define	AR5K_SISR2_DTIM_SYNC	0x04000000	/* DTIM sync lost [5212+] */
@@ -430,9 +430,9 @@
 #define AR5K_SIMR2		0x00ac			/* Register Address [5211+] */
 #define AR5K_SIMR2_QCU_TXURN	0x000003ff	/* Mask for QCU_TXURN */
 #define AR5K_SIMR2_QCU_TXURN_S	0
-#define	AR5K_SIMR2_MCABT	0x00100000	/* Master Cycle Abort */
-#define	AR5K_SIMR2_SSERR	0x00200000	/* Signaled System Error */
-#define	AR5K_SIMR2_DPERR	0x00400000	/* Bus parity error */
+#define	AR5K_SIMR2_MCABT	0x00010000	/* Master Cycle Abort */
+#define	AR5K_SIMR2_SSERR	0x00020000	/* Signaled System Error */
+#define	AR5K_SIMR2_DPERR	0x00040000	/* Bus parity error */
 #define	AR5K_SIMR2_TIM		0x01000000	/* [5212+] */
 #define	AR5K_SIMR2_CAB_END	0x02000000	/* [5212+] */
 #define	AR5K_SIMR2_DTIM_SYNC	0x04000000	/* DTIM Sync lost [5212+] */
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index bd0a97a..34e13c7 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -258,29 +258,35 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
 		if (!set_chip)
 			goto commit;
 
-		/* Preserve sleep duration */
 		data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
+
+		/* If card is down we 'll get 0xffff... so we
+		 * need to clean this up before we write the register
+		 */
 		if (data & 0xffc00000)
 			data = 0;
 		else
-			data = data & 0xfffcffff;
+			/* Preserve sleep duration etc */
+			data = data & ~AR5K_SLEEP_CTL_SLE;
 
-		ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+		ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
+							AR5K_SLEEP_CTL);
 		udelay(15);
 
-		for (i = 50; i > 0; i--) {
+		for (i = 200; i > 0; i--) {
 			/* Check if the chip did wake up */
 			if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
 					AR5K_PCICFG_SPWR_DN) == 0)
 				break;
 
 			/* Wait a bit and retry */
-			udelay(200);
-			ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+			udelay(50);
+			ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
+							AR5K_SLEEP_CTL);
 		}
 
 		/* Fail if the chip didn't wake up */
-		if (i <= 0)
+		if (i == 0)
 			return -EIO;
 
 		break;
@@ -290,13 +296,70 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
 	}
 
 commit:
-	ah->ah_power_mode = mode;
 	ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
 
 	return 0;
 }
 
 /*
+ * Put device on hold
+ *
+ * Put MAC and Baseband on warm reset and
+ * keep that state (don't clean sleep control
+ * register). After this MAC and Baseband are
+ * disabled and a full reset is needed to come
+ * back. This way we save as much power as possible
+ * without puting the card on full sleep.
+ */
+int ath5k_hw_on_hold(struct ath5k_hw *ah)
+{
+	struct pci_dev *pdev = ah->ah_sc->pdev;
+	u32 bus_flags;
+	int ret;
+
+	/* Make sure device is awake */
+	ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+	if (ret) {
+		ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+		return ret;
+	}
+
+	/*
+	 * Put chipset on warm reset...
+	 *
+	 * Note: puting PCI core on warm reset on PCI-E cards
+	 * results card to hang and always return 0xffff... so
+	 * we ingore that flag for PCI-E cards. On PCI cards
+	 * this flag gets cleared after 64 PCI clocks.
+	 */
+	bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+	if (ah->ah_version == AR5K_AR5210) {
+		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+			AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+			AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+			mdelay(2);
+	} else {
+		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+			AR5K_RESET_CTL_BASEBAND | bus_flags);
+	}
+
+	if (ret) {
+		ATH5K_ERR(ah->ah_sc, "failed to put device on warm reset\n");
+		return -EIO;
+	}
+
+	/* ...wakeup again!*/
+	ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+	if (ret) {
+		ATH5K_ERR(ah->ah_sc, "failed to put device on hold\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+/*
  * Bring up MAC + PHY Chips and program PLL
  * TODO: Half/Quarter rate support
  */
@@ -319,6 +382,50 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 		return ret;
 	}
 
+	/*
+	 * Put chipset on warm reset...
+	 *
+	 * Note: puting PCI core on warm reset on PCI-E cards
+	 * results card to hang and always return 0xffff... so
+	 * we ingore that flag for PCI-E cards. On PCI cards
+	 * this flag gets cleared after 64 PCI clocks.
+	 */
+	bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+	if (ah->ah_version == AR5K_AR5210) {
+		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+			AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+			AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+			mdelay(2);
+	} else {
+		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+			AR5K_RESET_CTL_BASEBAND | bus_flags);
+	}
+
+	if (ret) {
+		ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
+		return -EIO;
+	}
+
+	/* ...wakeup again!...*/
+	ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+	if (ret) {
+		ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
+		return ret;
+	}
+
+	/* ...clear reset control register and pull device out of
+	 * warm reset */
+	if (ath5k_hw_nic_reset(ah, 0)) {
+		ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
+		return -EIO;
+	}
+
+	/* On initialization skip PLL programming since we don't have
+	 * a channel / mode set yet */
+	if (initial)
+		return 0;
+
 	if (ah->ah_version != AR5K_AR5210) {
 		/*
 		 * Get channel mode flags
@@ -384,39 +491,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
 					AR5K_PHY_TURBO);
 	}
 
-	/* reseting PCI on PCI-E cards results card to hang
-	 * and always return 0xffff... so we ingore that flag
-	 * for PCI-E cards */
-	bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
-
-	/* Reset chipset */
-	if (ah->ah_version == AR5K_AR5210) {
-		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-			AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
-			AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
-			mdelay(2);
-	} else {
-		ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-			AR5K_RESET_CTL_BASEBAND | bus_flags);
-	}
-	if (ret) {
-		ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
-		return -EIO;
-	}
-
-	/* ...wakeup again!*/
-	ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
-	if (ret) {
-		ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
-		return ret;
-	}
-
-	/* ...final warm reset */
-	if (ath5k_hw_nic_reset(ah, 0)) {
-		ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
-		return -EIO;
-	}
-
 	if (ah->ah_version != AR5K_AR5210) {
 
 		/* ...update PLL if needed */
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 2d79610..ef5f59c 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -1,13 +1,18 @@
 config ATH9K
 	tristate "Atheros 802.11n wireless cards support"
 	depends on PCI && MAC80211 && WLAN_80211
-	select ATH_COMMON
 	select MAC80211_LEDS
 	select LEDS_CLASS
 	select NEW_LEDS
 	---help---
 	  This module adds support for wireless adapters based on
-	  Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
+	  Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family
+	  of chipsets. For a specific list of supported external
+	  cards, laptops that already ship with these cards and
+	  APs that come with these cards refer to to ath9k wiki
+	  products page:
+
+	  http://wireless.kernel.org/en/users/Drivers/ath9k/products
 
 	  If you choose to build a module, it'll be called ath9k.
 
@@ -18,6 +23,6 @@ config ATH9K_DEBUG
 	  Say Y, if you need ath9k to display debug messages.
 	  Pass the debug mask as a module parameter:
 
-	  modprobe ath9k debug=0x00002000
+	  modprobe ath9k debug=0x00000200
 
-	  Look in ath9k/core.h for possible debug masks
+	  Look in ath9k/debug.h for possible debug masks
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 783bc39..ff2c9a2 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -1,5 +1,8 @@
 ath9k-y +=	hw.o \
 		eeprom.o \
+		eeprom_def.o \
+		eeprom_4k.o \
+		eeprom_9287.o \
 		mac.o \
 		calib.o \
 		ani.o \
@@ -9,7 +12,8 @@ ath9k-y +=	hw.o \
 		recv.o \
 		xmit.o \
 		virtual.o \
-		rc.o
+		rc.o \
+		btcoex.o
 
 ath9k-$(CONFIG_PCI) += pci.o
 ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 0e65c51..2ad7d02 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -119,17 +119,15 @@ static int ath_ahb_probe(struct platform_device *pdev)
 	sc->bus_ops = &ath_ahb_bus_ops;
 	sc->irq = irq;
 
-	ret = ath_attach(AR5416_AR9100_DEVID, sc);
-	if (ret != 0) {
-		dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
-		ret = -ENODEV;
+	ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize device\n");
 		goto err_free_hw;
 	}
 
 	ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
 	if (ret) {
-		dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
-		ret = -EIO;
+		dev_err(&pdev->dev, "request_irq failed\n");
 		goto err_detach;
 	}
 
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index aad259b..2b49374 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -236,36 +236,35 @@ static void ath9k_ani_restart(struct ath_hw *ah)
 		return;
 
 	aniState = ah->curani;
-
 	aniState->listenTime = 0;
-	if (ah->has_hw_phycounters) {
-		if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
-			aniState->ofdmPhyErrBase = 0;
-			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-				"OFDM Trigger is too high for hw counters\n");
-		} else {
-			aniState->ofdmPhyErrBase =
-				AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
-		}
-		if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
-			aniState->cckPhyErrBase = 0;
-			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-				"CCK Trigger is too high for hw counters\n");
-		} else {
-			aniState->cckPhyErrBase =
-				AR_PHY_COUNTMAX - aniState->cckTrigHigh;
-		}
+
+	if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
+		aniState->ofdmPhyErrBase = 0;
 		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"Writing ofdmbase=%u   cckbase=%u\n",
-			aniState->ofdmPhyErrBase,
-			aniState->cckPhyErrBase);
-		REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
-		REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
-		REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-		REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
-		ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+			"OFDM Trigger is too high for hw counters\n");
+	} else {
+		aniState->ofdmPhyErrBase =
+			AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
+	}
+	if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
+		aniState->cckPhyErrBase = 0;
+		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+			"CCK Trigger is too high for hw counters\n");
+	} else {
+		aniState->cckPhyErrBase =
+			AR_PHY_COUNTMAX - aniState->cckTrigHigh;
 	}
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+		"Writing ofdmbase=%u   cckbase=%u\n",
+		aniState->ofdmPhyErrBase,
+		aniState->cckPhyErrBase);
+	REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
+	REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
+	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+
 	aniState->ofdmPhyErrCount = 0;
 	aniState->cckPhyErrCount = 0;
 }
@@ -328,7 +327,8 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
 					     aniState->firstepLevel + 1);
 		return;
 	} else {
-		if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+		if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+		    !conf_is_ht(conf)) {
 			if (!aniState->ofdmWeakSigDetectOff)
 				ath9k_hw_ani_control(ah,
 				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -370,7 +370,8 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
 			ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
 					     aniState->firstepLevel + 1);
 	} else {
-		if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+		if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+		    !conf_is_ht(conf)) {
 			if (aniState->firstepLevel > 0)
 				ath9k_hw_ani_control(ah,
 					     ATH9K_ANI_FIRSTEP_LEVEL, 0);
@@ -530,32 +531,26 @@ void ath9k_ani_reset(struct ath_hw *ah)
 	if (aniState->firstepLevel != 0)
 		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
 				     aniState->firstepLevel);
-	if (ah->has_hw_phycounters) {
-		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
-				     ~ATH9K_RX_FILTER_PHYERR);
-		ath9k_ani_restart(ah);
-		REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-		REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 
-	} else {
-		ath9k_ani_restart(ah);
-		ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
-				     ATH9K_RX_FILTER_PHYERR);
-	}
+	ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
+			     ~ATH9K_RX_FILTER_PHYERR);
+	ath9k_ani_restart(ah);
+	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
 }
 
 void ath9k_hw_ani_monitor(struct ath_hw *ah,
-			  const struct ath9k_node_stats *stats,
 			  struct ath9k_channel *chan)
 {
 	struct ar5416AniState *aniState;
 	int32_t listenTime;
+	u32 phyCnt1, phyCnt2;
+	u32 ofdmPhyErrCnt, cckPhyErrCnt;
 
 	if (!DO_ANI(ah))
 		return;
 
 	aniState = ah->curani;
-	ah->stats.ast_nodestats = *stats;
 
 	listenTime = ath9k_hw_ani_get_listen_time(ah);
 	if (listenTime < 0) {
@@ -566,50 +561,45 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
 
 	aniState->listenTime += listenTime;
 
-	if (ah->has_hw_phycounters) {
-		u32 phyCnt1, phyCnt2;
-		u32 ofdmPhyErrCnt, cckPhyErrCnt;
+	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
 
-		ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-
-		phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
-		phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
-
-		if (phyCnt1 < aniState->ofdmPhyErrBase ||
-		    phyCnt2 < aniState->cckPhyErrBase) {
-			if (phyCnt1 < aniState->ofdmPhyErrBase) {
-				DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-					"phyCnt1 0x%x, resetting "
-					"counter value to 0x%x\n",
-					phyCnt1, aniState->ofdmPhyErrBase);
-				REG_WRITE(ah, AR_PHY_ERR_1,
-					  aniState->ofdmPhyErrBase);
-				REG_WRITE(ah, AR_PHY_ERR_MASK_1,
-					  AR_PHY_ERR_OFDM_TIMING);
-			}
-			if (phyCnt2 < aniState->cckPhyErrBase) {
-				DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-					"phyCnt2 0x%x, resetting "
-					"counter value to 0x%x\n",
-					phyCnt2, aniState->cckPhyErrBase);
-				REG_WRITE(ah, AR_PHY_ERR_2,
-					  aniState->cckPhyErrBase);
-				REG_WRITE(ah, AR_PHY_ERR_MASK_2,
-					  AR_PHY_ERR_CCK_TIMING);
-			}
-			return;
+	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
+	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
+
+	if (phyCnt1 < aniState->ofdmPhyErrBase ||
+	    phyCnt2 < aniState->cckPhyErrBase) {
+		if (phyCnt1 < aniState->ofdmPhyErrBase) {
+			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+				"phyCnt1 0x%x, resetting "
+				"counter value to 0x%x\n",
+				phyCnt1, aniState->ofdmPhyErrBase);
+			REG_WRITE(ah, AR_PHY_ERR_1,
+				  aniState->ofdmPhyErrBase);
+			REG_WRITE(ah, AR_PHY_ERR_MASK_1,
+				  AR_PHY_ERR_OFDM_TIMING);
+		}
+		if (phyCnt2 < aniState->cckPhyErrBase) {
+			DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+				"phyCnt2 0x%x, resetting "
+				"counter value to 0x%x\n",
+				phyCnt2, aniState->cckPhyErrBase);
+			REG_WRITE(ah, AR_PHY_ERR_2,
+				  aniState->cckPhyErrBase);
+			REG_WRITE(ah, AR_PHY_ERR_MASK_2,
+				  AR_PHY_ERR_CCK_TIMING);
 		}
+		return;
+	}
 
-		ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
-		ah->stats.ast_ani_ofdmerrs +=
-			ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
-		aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+	ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+	ah->stats.ast_ani_ofdmerrs +=
+		ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+	aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
 
-		cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-		ah->stats.ast_ani_cckerrs +=
-			cckPhyErrCnt - aniState->cckPhyErrCount;
-		aniState->cckPhyErrCount = cckPhyErrCnt;
-	}
+	cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+	ah->stats.ast_ani_cckerrs +=
+		cckPhyErrCnt - aniState->cckPhyErrCount;
+	aniState->cckPhyErrCount = cckPhyErrCnt;
 
 	if (aniState->listenTime > 5 * ah->aniperiod) {
 		if (aniState->ofdmPhyErrCount <= aniState->listenTime *
@@ -632,11 +622,6 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
 	}
 }
 
-bool ath9k_hw_phycounters(struct ath_hw *ah)
-{
-	return ah->has_hw_phycounters ? true : false;
-}
-
 void ath9k_enable_mib_counters(struct ath_hw *ah)
 {
 	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
@@ -708,8 +693,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
  * any of the MIB counters overflow/trigger so don't assume we're
  * here because a PHY error counter triggered.
  */
-void ath9k_hw_procmibevent(struct ath_hw *ah,
-			   const struct ath9k_node_stats *stats)
+void ath9k_hw_procmibevent(struct ath_hw *ah)
 {
 	u32 phyCnt1, phyCnt2;
 
@@ -721,7 +705,6 @@ void ath9k_hw_procmibevent(struct ath_hw *ah,
 
 	/* Clear the mib counters and save them in the stats */
 	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-	ah->stats.ast_nodestats = *stats;
 
 	if (!DO_ANI(ah))
 		return;
@@ -777,13 +760,11 @@ void ath9k_hw_ani_setup(struct ath_hw *ah)
 	}
 }
 
-void ath9k_hw_ani_attach(struct ath_hw *ah)
+void ath9k_hw_ani_init(struct ath_hw *ah)
 {
 	int i;
 
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
-
-	ah->has_hw_phycounters = 1;
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Initialize ANI\n");
 
 	memset(ah->ani, 0, sizeof(ah->ani));
 	for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
@@ -799,36 +780,32 @@ void ath9k_hw_ani_attach(struct ath_hw *ah)
 			ATH9K_ANI_CCK_WEAK_SIG_THR;
 		ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
 		ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-		if (ah->has_hw_phycounters) {
-			ah->ani[i].ofdmPhyErrBase =
-				AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
-			ah->ani[i].cckPhyErrBase =
-				AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
-		}
-	}
-	if (ah->has_hw_phycounters) {
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"Setting OfdmErrBase = 0x%08x\n",
-			ah->ani[0].ofdmPhyErrBase);
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
-			ah->ani[0].cckPhyErrBase);
-
-		REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
-		REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
-		ath9k_enable_mib_counters(ah);
+		ah->ani[i].ofdmPhyErrBase =
+			AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
+		ah->ani[i].cckPhyErrBase =
+			AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
 	}
+
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+		"Setting OfdmErrBase = 0x%08x\n",
+		ah->ani[0].ofdmPhyErrBase);
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
+		ah->ani[0].cckPhyErrBase);
+
+	REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
+	REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
+	ath9k_enable_mib_counters(ah);
+
 	ah->aniperiod = ATH9K_ANI_PERIOD;
 	if (ah->config.enable_ani)
 		ah->proc_phyerr |= HAL_PROCESS_ANI;
 }
 
-void ath9k_hw_ani_detach(struct ath_hw *ah)
+void ath9k_hw_ani_disable(struct ath_hw *ah)
 {
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling ANI\n");
 
-	if (ah->has_hw_phycounters) {
-		ath9k_hw_disable_mib_counters(ah);
-		REG_WRITE(ah, AR_PHY_ERR_1, 0);
-		REG_WRITE(ah, AR_PHY_ERR_2, 0);
-	}
+	ath9k_hw_disable_mib_counters(ah);
+	REG_WRITE(ah, AR_PHY_ERR_1, 0);
+	REG_WRITE(ah, AR_PHY_ERR_2, 0);
 }
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 08b4e7e..4e1ab94 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -18,15 +18,10 @@
 #define ANI_H
 
 #define HAL_PROCESS_ANI           0x00000001
-#define ATH9K_RSSI_EP_MULTIPLIER  (1<<7)
 
 #define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
 
-#define HAL_EP_RND(x, mul)						\
-	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-#define BEACON_RSSI(ahp)					\
-	HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi,	\
-		   ATH9K_RSSI_EP_MULTIPLIER)
+#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
 
 #define ATH9K_ANI_OFDM_TRIG_HIGH          500
 #define ATH9K_ANI_OFDM_TRIG_LOW           200
@@ -65,13 +60,6 @@ struct ath9k_mib_stats {
 	u32 beacons;
 };
 
-struct ath9k_node_stats {
-	u32 ns_avgbrssi;
-	u32 ns_avgrssi;
-	u32 ns_avgtxrssi;
-	u32 ns_avgtxrate;
-};
-
 struct ar5416AniState {
 	struct ath9k_channel *c;
 	u8 noiseImmunityLevel;
@@ -115,24 +103,21 @@ struct ar5416Stats {
 	u32 ast_ani_reset;
 	u32 ast_ani_lzero;
 	u32 ast_ani_lneg;
+	u32 avgbrssi;
 	struct ath9k_mib_stats ast_mibstats;
-	struct ath9k_node_stats ast_nodestats;
 };
 #define ah_mibStats stats.ast_mibstats
 
 void ath9k_ani_reset(struct ath_hw *ah);
 void ath9k_hw_ani_monitor(struct ath_hw *ah,
-			  const struct ath9k_node_stats *stats,
 			  struct ath9k_channel *chan);
-bool ath9k_hw_phycounters(struct ath_hw *ah);
 void ath9k_enable_mib_counters(struct ath_hw *ah);
 void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
 u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
 				  u32 *rxf_pcnt, u32 *txf_pcnt);
-void ath9k_hw_procmibevent(struct ath_hw *ah,
-			   const struct ath9k_node_stats *stats);
+void ath9k_hw_procmibevent(struct ath_hw *ah);
 void ath9k_hw_ani_setup(struct ath_hw *ah);
-void ath9k_hw_ani_attach(struct ath_hw *ah);
-void ath9k_hw_ani_detach(struct ath_hw *ah);
+void ath9k_hw_ani_init(struct ath_hw *ah);
+void ath9k_hw_ani_disable(struct ath_hw *ah);
 
 #endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 5efc934..1d59f10 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -25,6 +25,8 @@
 #include "hw.h"
 #include "rc.h"
 #include "debug.h"
+#include "../ath.h"
+#include "btcoex.h"
 
 struct ath_node;
 
@@ -164,7 +166,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
 #define WME_NUM_TID             16
 #define ATH_TXBUF               512
 #define ATH_TXMAXTRY            13
-#define ATH_11N_TXMAXTRY        10
 #define ATH_MGT_TXMAXTRY        4
 #define WME_BA_BMP_SIZE         64
 #define WME_MAX_BA              WME_BA_BMP_SIZE
@@ -191,12 +192,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
 #define ATH_AGGR_MIN_QDEPTH        2
 #define ATH_AMPDU_SUBFRAME_DEFAULT 32
 #define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
-#define ATH_AMPDU_LIMIT_DEFAULT    ATH_AMPDU_LIMIT_MAX
 
 #define IEEE80211_SEQ_SEQ_SHIFT    4
 #define IEEE80211_SEQ_MAX          4096
-#define IEEE80211_MIN_AMPDU_BUF    0x8
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
 #define IEEE80211_WEP_IVLEN        3
 #define IEEE80211_WEP_KIDLEN       1
 #define IEEE80211_WEP_CRCLEN       4
@@ -226,6 +224,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
 #define ATH_DS_TX_BA(_ds)          ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
 #define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
 
+#define ATH_TX_COMPLETE_POLL_INT	1000
+
 enum ATH_AGGR_STATUS {
 	ATH_AGGR_DONE,
 	ATH_AGGR_BAW_CLOSED,
@@ -239,8 +239,8 @@ struct ath_txq {
 	spinlock_t axq_lock;
 	u32 axq_depth;
 	u8 axq_aggr_depth;
-	u32 axq_totalqueued;
 	bool stopped;
+	bool axq_tx_inprogress;
 	struct ath_buf *axq_linkbuf;
 
 	/* first desc of the last descriptor that contains CTS */
@@ -272,7 +272,6 @@ struct ath_atx_tid {
 	int sched;
 	int paused;
 	u8 state;
-	int addba_exchangeattempts;
 };
 
 struct ath_atx_ac {
@@ -292,12 +291,28 @@ struct ath_tx_control {
 #define ATH_TX_XRETRY       0x02
 #define ATH_TX_BAR          0x04
 
+#define ATH_RSSI_LPF_LEN 		10
+#define RSSI_LPF_THRESHOLD		-20
+#define ATH9K_RSSI_BAD			0x80
+#define ATH_RSSI_EP_MULTIPLIER     (1<<7)
+#define ATH_EP_MUL(x, mul)         ((x) * (mul))
+#define ATH_RSSI_IN(x)             (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
+#define ATH_LPF_RSSI(x, y, len) \
+    ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
+#define ATH_RSSI_LPF(x, y) do {                     			\
+    if ((y) >= RSSI_LPF_THRESHOLD)                         		\
+	x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN);  	\
+} while (0)
+#define ATH_EP_RND(x, mul) 						\
+	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+
 struct ath_node {
 	struct ath_softc *an_sc;
 	struct ath_atx_tid tid[WME_NUM_TID];
 	struct ath_atx_ac ac[WME_NUM_AC];
 	u16 maxampdu;
 	u8 mpdudensity;
+	int last_rssi;
 };
 
 struct ath_tx {
@@ -348,9 +363,9 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 void ath_tx_tasklet(struct ath_softc *sc);
 void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
 bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-		      u16 tid, u16 *ssn);
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+		       u16 tid, u16 *ssn);
+void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
 
 /********/
@@ -440,7 +455,8 @@ struct ath_ani {
 /*   LED Control    */
 /********************/
 
-#define ATH_LED_PIN	1
+#define ATH_LED_PIN_DEF 		1
+#define ATH_LED_PIN_9287		8
 #define ATH_LED_ON_DURATION_IDLE	350	/* in msecs */
 #define ATH_LED_OFF_DURATION_IDLE	250	/* in msecs */
 
@@ -506,6 +522,8 @@ struct ath_led {
 #define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
 #define SC_OP_WAIT_FOR_TX_ACK   BIT(18)
 #define SC_OP_BEACON_SYNC       BIT(19)
+#define SC_OP_BTCOEX_ENABLED    BIT(20)
+#define SC_OP_BT_PRIORITY_DETECTED BIT(21)
 
 struct ath_bus_ops {
 	void		(*read_cachesize)(struct ath_softc *sc, int *csz);
@@ -519,6 +537,8 @@ struct ath_softc {
 	struct ieee80211_hw *hw;
 	struct device *dev;
 
+	struct ath_common common;
+
 	spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
 	struct ath_wiphy *pri_wiphy;
 	struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
@@ -541,6 +561,8 @@ struct ath_softc {
 	int irq;
 	spinlock_t sc_resetlock;
 	spinlock_t sc_serial_rw;
+	spinlock_t ani_lock;
+	spinlock_t sc_pm_lock;
 	struct mutex mutex;
 
 	u8 curbssid[ETH_ALEN];
@@ -549,7 +571,6 @@ struct ath_softc {
 	u32 sc_flags; /* SC_OP_* */
 	u16 curtxpow;
 	u16 curaid;
-	u16 cachelsz;
 	u8 nbcnvifs;
 	u16 nvifs;
 	u8 tx_chainmask;
@@ -557,7 +578,8 @@ struct ath_softc {
 	u32 keymax;
 	DECLARE_BITMAP(keymap, ATH_KEYMAX);
 	u8 splitmic;
-	atomic_t ps_usecount;
+	bool ps_enabled;
+	unsigned long ps_usecount;
 	enum ath9k_int imask;
 	enum ath9k_ht_extprotspacing ht_extprotspacing;
 	enum ath9k_ht_macmode tx_chan_width;
@@ -584,12 +606,13 @@ struct ath_softc {
 	int beacon_interval;
 
 	struct ath_ani ani;
-	struct ath9k_node_stats nodestats;
 #ifdef CONFIG_ATH9K_DEBUG
 	struct ath9k_debug debug;
 #endif
 	struct ath_bus_ops *bus_ops;
 	struct ath_beacon_config cur_beacon_conf;
+	struct delayed_work tx_complete_work;
+	struct ath_btcoex_info btcoex_info;
 };
 
 struct ath_wiphy {
@@ -611,6 +634,16 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
 int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
 int ath_cabq_update(struct ath_softc *);
 
+static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
+{
+	return &ah->ah_sc->common;
+}
+
+static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
+{
+	return &(ath9k_hw_common(ah)->regulatory);
+}
+
 static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
 {
 	sc->bus_ops->read_cachesize(sc, csz);
@@ -625,7 +658,7 @@ extern struct ieee80211_ops ath9k_ops;
 
 irqreturn_t ath_isr(int irq, void *dev);
 void ath_cleanup(struct ath_softc *sc);
-int ath_attach(u16 devid, struct ath_softc *sc);
+int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid);
 void ath_detach(struct ath_softc *sc);
 const char *ath_mac_bb_name(u32 mac_bb_version);
 const char *ath_rf_name(u16 rf_version);
@@ -654,27 +687,8 @@ static inline int ath_ahb_init(void) { return 0; };
 static inline void ath_ahb_exit(void) {};
 #endif
 
-static inline void ath9k_ps_wakeup(struct ath_softc *sc)
-{
-	if (atomic_inc_return(&sc->ps_usecount) == 1)
-		if (sc->sc_ah->power_mode !=  ATH9K_PM_AWAKE) {
-			sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
-			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
-		}
-}
-
-static inline void ath9k_ps_restore(struct ath_softc *sc)
-{
-	if (atomic_dec_and_test(&sc->ps_usecount))
-		if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
-		    !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
-				      SC_OP_WAIT_FOR_CAB |
-				      SC_OP_WAIT_FOR_PSPOLL_DATA |
-				      SC_OP_WAIT_FOR_TX_ACK)))
-			ath9k_hw_setpower(sc->sc_ah,
-					  sc->sc_ah->restore_mode);
-}
-
+void ath9k_ps_wakeup(struct ath_softc *sc);
+void ath9k_ps_restore(struct ath_softc *sc);
 
 void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
 int ath9k_wiphy_add(struct ath_softc *sc);
@@ -690,8 +704,10 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
 				  struct ath_wiphy *selected);
 bool ath9k_wiphy_scanning(struct ath_softc *sc);
 void ath9k_wiphy_work(struct work_struct *work);
+bool ath9k_all_wiphys_idle(struct ath_softc *sc);
 
 void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
 unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
 
+int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
 #endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 3639a2e..45c4ea5 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -674,13 +674,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
 
 	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
 
-	/*
-	 * It looks like mac80211 may end up using beacon interval of zero in
-	 * some cases (at least for mesh point). Avoid getting into an
-	 * infinite loop by using a bit safer value instead..
-	 */
-	if (intval == 0)
-		intval = 100;
 
 	/* Pull nexttbtt forward to reflect the current TSF */
 
@@ -745,6 +738,14 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
 		iftype = sc->sc_ah->opmode;
 	}
 
+	/*
+	 * It looks like mac80211 may end up using beacon interval of zero in
+	 * some cases (at least for mesh point). Avoid getting into an
+	 * infinite loop by using a bit safer value instead. To be safe,
+	 * do sanity check on beacon interval for all operating modes.
+	 */
+	if (cur_conf->beacon_interval == 0)
+		cur_conf->beacon_interval = 100;
 
 	switch (iftype) {
 	case NL80211_IFTYPE_AP:
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
new file mode 100644
index 0000000..55f607b
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+static const struct ath_btcoex_config ath_bt_config = { 0, true, true,
+			ATH_BT_COEX_MODE_SLOTTED, true, true, 2, 5, true };
+
+static const u16 ath_subsysid_tbl[] = {
+	AR9280_COEX2WIRE_SUBSYSID,
+	AT9285_COEX3WIRE_SA_SUBSYSID,
+	AT9285_COEX3WIRE_DA_SUBSYSID
+};
+
+/*
+ * Checks the subsystem id of the device to see if it
+ * supports btcoex
+ */
+bool ath_btcoex_supported(u16 subsysid)
+{
+	int i;
+
+	if (!subsysid)
+		return false;
+
+	for (i = 0; i < ARRAY_SIZE(ath_subsysid_tbl); i++)
+		if (subsysid == ath_subsysid_tbl[i])
+			return true;
+
+	return false;
+}
+
+/*
+ * Detects if there is any priority bt traffic
+ */
+static void ath_detect_bt_priority(struct ath_softc *sc)
+{
+	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
+
+	if (ath9k_hw_gpio_get(sc->sc_ah, btinfo->btpriority_gpio))
+		btinfo->bt_priority_cnt++;
+
+	if (time_after(jiffies, btinfo->bt_priority_time +
+			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
+		if (btinfo->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
+			DPRINTF(sc, ATH_DBG_BTCOEX,
+				"BT priority traffic detected");
+			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
+		} else {
+			sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
+		}
+
+		btinfo->bt_priority_cnt = 0;
+		btinfo->bt_priority_time = jiffies;
+	}
+}
+
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+static void ath_btcoex_bt_stomp(struct ath_softc *sc,
+				struct ath_btcoex_info *btinfo,
+				int stomp_type)
+{
+
+	switch (stomp_type) {
+	case ATH_BTCOEX_STOMP_ALL:
+		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
+				      AR_STOMP_ALL_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_LOW:
+		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
+				      AR_STOMP_LOW_WLAN_WGHT);
+		break;
+	case ATH_BTCOEX_STOMP_NONE:
+		ath_btcoex_set_weight(btinfo, AR_BT_COEX_WGHT,
+				      AR_STOMP_NONE_WLAN_WGHT);
+		break;
+	default:
+		DPRINTF(sc, ATH_DBG_BTCOEX, "Invalid Stomptype\n");
+		break;
+	}
+
+	ath9k_hw_btcoex_enable(sc->sc_ah);
+}
+
+/*
+ * This is the master bt coex timer which runs for every
+ * 45ms, bt traffic will be given priority during 55% of this
+ * period while wlan gets remaining 45%
+ */
+
+static void ath_btcoex_period_timer(unsigned long data)
+{
+	struct ath_softc *sc = (struct ath_softc *) data;
+	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
+
+	ath_detect_bt_priority(sc);
+
+	spin_lock_bh(&btinfo->btcoex_lock);
+
+	ath_btcoex_bt_stomp(sc, btinfo, btinfo->bt_stomp_type);
+
+	spin_unlock_bh(&btinfo->btcoex_lock);
+
+	if (btinfo->btcoex_period != btinfo->btcoex_no_stomp) {
+		if (btinfo->hw_timer_enabled)
+			ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
+
+		ath_gen_timer_start(sc->sc_ah,
+			btinfo->no_stomp_timer,
+			(ath9k_hw_gettsf32(sc->sc_ah) +
+				btinfo->btcoex_no_stomp),
+				btinfo->btcoex_no_stomp * 10);
+		btinfo->hw_timer_enabled = true;
+	}
+
+	mod_timer(&btinfo->period_timer, jiffies +
+				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
+}
+
+/*
+ * Generic tsf based hw timer which configures weight
+ * registers to time slice between wlan and bt traffic
+ */
+
+static void ath_btcoex_no_stomp_timer(void *arg)
+{
+	struct ath_softc *sc = (struct ath_softc *)arg;
+	struct ath_btcoex_info *btinfo = &sc->btcoex_info;
+
+	DPRINTF(sc, ATH_DBG_BTCOEX, "no stomp timer running \n");
+
+	spin_lock_bh(&btinfo->btcoex_lock);
+
+	if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
+		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_NONE);
+	 else if (btinfo->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
+		ath_btcoex_bt_stomp(sc, btinfo, ATH_BTCOEX_STOMP_LOW);
+
+	spin_unlock_bh(&btinfo->btcoex_lock);
+}
+
+static int ath_init_btcoex_info(struct ath_hw *hw,
+				struct ath_btcoex_info *btcoex_info)
+{
+	u32 i;
+	int qnum;
+
+	qnum = ath_tx_get_qnum(hw->ah_sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+
+	btcoex_info->bt_coex_mode =
+		(btcoex_info->bt_coex_mode & AR_BT_QCU_THRESH) |
+		SM(ath_bt_config.bt_time_extend, AR_BT_TIME_EXTEND) |
+		SM(ath_bt_config.bt_txstate_extend, AR_BT_TXSTATE_EXTEND) |
+		SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
+		SM(ath_bt_config.bt_mode, AR_BT_MODE) |
+		SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
+		SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
+		SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
+		SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
+		SM(qnum, AR_BT_QCU_THRESH);
+
+	btcoex_info->bt_coex_mode2 =
+		SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) |
+		SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) |
+		AR_BT_DISABLE_BT_ANT;
+
+	btcoex_info->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+
+	btcoex_info->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
+
+	btcoex_info->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
+		btcoex_info->btcoex_period / 100;
+
+	for (i = 0; i < 32; i++)
+		hw->hw_gen_timers.gen_timer_index[(debruijn32 << i) >> 27] = i;
+
+	setup_timer(&btcoex_info->period_timer, ath_btcoex_period_timer,
+			(unsigned long) hw->ah_sc);
+
+	btcoex_info->no_stomp_timer = ath_gen_timer_alloc(hw,
+			ath_btcoex_no_stomp_timer,
+			ath_btcoex_no_stomp_timer,
+			(void *)hw->ah_sc, AR_FIRST_NDP_TIMER);
+
+	if (btcoex_info->no_stomp_timer == NULL)
+		return -ENOMEM;
+
+	spin_lock_init(&btcoex_info->btcoex_lock);
+
+	return 0;
+}
+
+int ath9k_hw_btcoex_init(struct ath_hw *ah)
+{
+	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+	int ret = 0;
+
+	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
+		/* connect bt_active to baseband */
+		REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+				(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+				 AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+
+		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+				AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+		/* Set input mux for bt_active to gpio pin */
+		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+				AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+				btcoex_info->btactive_gpio);
+
+		/* Configure the desired gpio port for input */
+		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
+	} else {
+		/* btcoex 3-wire */
+		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+				(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
+				 AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB));
+
+		/* Set input mux for bt_prority_async and
+		 *                  bt_active_async to GPIO pins */
+		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+				AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+				btcoex_info->btactive_gpio);
+
+		REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+				AR_GPIO_INPUT_MUX1_BT_PRIORITY,
+				btcoex_info->btpriority_gpio);
+
+		/* Configure the desired GPIO ports for input */
+
+		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btactive_gpio);
+		ath9k_hw_cfg_gpio_input(ah, btcoex_info->btpriority_gpio);
+
+		ret = ath_init_btcoex_info(ah, btcoex_info);
+	}
+
+	return ret;
+}
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+
+	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_2WIRE) {
+		/* Configure the desired GPIO port for TX_FRAME output */
+		ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
+				AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+	} else {
+		/*
+		 * Program coex mode and weight registers to
+		 * enable coex 3-wire
+		 */
+		REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_info->bt_coex_mode);
+		REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_info->bt_coex_weights);
+		REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_info->bt_coex_mode2);
+
+		REG_RMW_FIELD(ah, AR_QUIET1,
+				AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1);
+		REG_RMW_FIELD(ah, AR_PCU_MISC,
+				AR_PCU_BT_ANT_PREVENT_RX, 0);
+
+		ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
+				AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL);
+	}
+
+	REG_RMW(ah, AR_GPIO_PDPU,
+		(0x2 << (btcoex_info->btactive_gpio * 2)),
+		(0x3 << (btcoex_info->btactive_gpio * 2)));
+
+	ah->ah_sc->sc_flags |= SC_OP_BTCOEX_ENABLED;
+}
+
+void ath9k_hw_btcoex_disable(struct ath_hw *ah)
+{
+	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+
+	ath9k_hw_set_gpio(ah, btcoex_info->wlanactive_gpio, 0);
+
+	ath9k_hw_cfg_output(ah, btcoex_info->wlanactive_gpio,
+			AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+
+	if (btcoex_info->btcoex_scheme == ATH_BTCOEX_CFG_3WIRE) {
+		REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
+		REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
+		REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
+	}
+
+	ah->ah_sc->sc_flags &= ~SC_OP_BTCOEX_ENABLED;
+}
+
+/*
+ * Pause btcoex timer and bt duty cycle timer
+ */
+void ath_btcoex_timer_pause(struct ath_softc *sc,
+			    struct ath_btcoex_info *btinfo)
+{
+
+	del_timer_sync(&btinfo->period_timer);
+
+	if (btinfo->hw_timer_enabled)
+		ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
+
+	btinfo->hw_timer_enabled = false;
+}
+
+/*
+ * (Re)start btcoex timers
+ */
+void ath_btcoex_timer_resume(struct ath_softc *sc,
+			     struct ath_btcoex_info *btinfo)
+{
+
+	DPRINTF(sc, ATH_DBG_BTCOEX, "Starting btcoex timers");
+
+	/* make sure duty cycle timer is also stopped when resuming */
+	if (btinfo->hw_timer_enabled)
+		ath_gen_timer_stop(sc->sc_ah, btinfo->no_stomp_timer);
+
+	btinfo->bt_priority_cnt = 0;
+	btinfo->bt_priority_time = jiffies;
+	sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
+
+	mod_timer(&btinfo->period_timer, jiffies);
+}
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
new file mode 100644
index 0000000..297b027
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef BTCOEX_H
+#define BTCOEX_H
+
+#define ATH_WLANACTIVE_GPIO	5
+#define ATH_BTACTIVE_GPIO	6
+#define ATH_BTPRIORITY_GPIO	7
+
+#define ATH_BTCOEX_DEF_BT_PERIOD  45
+#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
+#define ATH_BTCOEX_BMISS_THRESH   50
+
+#define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */
+#define ATH_BT_CNT_THRESHOLD	       3
+
+enum ath_btcoex_scheme {
+	ATH_BTCOEX_CFG_NONE,
+	ATH_BTCOEX_CFG_2WIRE,
+	ATH_BTCOEX_CFG_3WIRE,
+};
+
+enum ath_stomp_type {
+	ATH_BTCOEX_NO_STOMP,
+	ATH_BTCOEX_STOMP_ALL,
+	ATH_BTCOEX_STOMP_LOW,
+	ATH_BTCOEX_STOMP_NONE
+};
+
+enum ath_bt_mode {
+	ATH_BT_COEX_MODE_LEGACY,	/* legacy rx_clear mode */
+	ATH_BT_COEX_MODE_UNSLOTTED,	/* untimed/unslotted mode */
+	ATH_BT_COEX_MODE_SLOTTED,	/* slotted mode */
+	ATH_BT_COEX_MODE_DISALBED,	/* coexistence disabled */
+};
+
+struct ath_btcoex_config {
+	u8 bt_time_extend;
+	bool bt_txstate_extend;
+	bool bt_txframe_extend;
+	enum ath_bt_mode bt_mode; /* coexistence mode */
+	bool bt_quiet_collision;
+	bool bt_rxclear_polarity; /* invert rx_clear as WLAN_ACTIVE*/
+	u8 bt_priority_time;
+	u8 bt_first_slot_time;
+	bool bt_hold_rx_clear;
+};
+
+struct ath_btcoex_info {
+	enum ath_btcoex_scheme btcoex_scheme;
+	u8 wlanactive_gpio;
+	u8 btactive_gpio;
+	u8 btpriority_gpio;
+	u8 bt_duty_cycle; 	/* BT duty cycle in percentage */
+	int bt_stomp_type; 	/* Types of BT stomping */
+	u32 bt_coex_mode; 	/* Register setting for AR_BT_COEX_MODE */
+	u32 bt_coex_weights; 	/* Register setting for AR_BT_COEX_WEIGHT */
+	u32 bt_coex_mode2; 	/* Register setting for AR_BT_COEX_MODE2 */
+	u32 btcoex_no_stomp;   /* in usec */
+	u32 btcoex_period;     	/* in usec */
+	u32 bt_priority_cnt;
+	unsigned long bt_priority_time;
+	bool hw_timer_enabled;
+	spinlock_t btcoex_lock;
+	struct timer_list period_timer;      /* Timer for BT period */
+	struct ath_gen_timer *no_stomp_timer; /*Timer for no BT stomping*/
+};
+
+bool ath_btcoex_supported(u16 subsysid);
+int ath9k_hw_btcoex_init(struct ath_hw *ah);
+void ath9k_hw_btcoex_enable(struct ath_hw *ah);
+void ath9k_hw_btcoex_disable(struct ath_hw *ah);
+void ath_btcoex_timer_resume(struct ath_softc *sc,
+			     struct ath_btcoex_info *btinfo);
+void ath_btcoex_timer_pause(struct ath_softc *sc,
+			    struct ath_btcoex_info *btinfo);
+
+static inline void ath_btcoex_set_weight(struct ath_btcoex_info *btcoex_info,
+					 u32 bt_weight,
+					 u32 wlan_weight)
+{
+	btcoex_info->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
+				       SM(wlan_weight, AR_BTCOEX_WL_WGHT);
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index a32d7e7..3234995 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -116,7 +116,7 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
 				"NF calibrated [ctl] [chain 1] is %d\n", nf);
 		nfarray[1] = nf;
 
-		if (!AR_SREV_9280(ah)) {
+		if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
 			nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
 					AR_PHY_CH2_MINCCA_PWR);
 			if (nf & 0x100)
@@ -154,7 +154,7 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
 				"NF calibrated [ext] [chain 1] is %d\n", nf);
 		nfarray[4] = nf;
 
-		if (!AR_SREV_9280(ah)) {
+		if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
 			nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
 					AR_PHY_CH2_EXT_MINCCA_PWR);
 			if (nf & 0x100)
@@ -613,7 +613,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
 
 	if (AR_SREV_9285(ah))
 		chainmask = 0x9;
-	else if (AR_SREV_9280(ah))
+	else if (AR_SREV_9280(ah) || AR_SREV_9287(ah))
 		chainmask = 0x1B;
 	else
 		chainmask = 0x3F;
@@ -691,15 +691,22 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
 {
 	int i, j;
+	s16 noise_floor;
+
+	if (AR_SREV_9280(ah))
+		noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
+	else if (AR_SREV_9285(ah))
+		noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
+	else
+		noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
 
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		ah->nfCalHist[i].currIndex = 0;
-		ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
+		ah->nfCalHist[i].privNF = noise_floor;
 		ah->nfCalHist[i].invalidNFcount =
 			AR_PHY_CCA_FILTERWINDOW_LENGTH;
 		for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
-			ah->nfCalHist[i].nfCalBuffer[j] =
-				AR_PHY_CCA_MAX_GOOD_VALUE;
+			ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
 		}
 	}
 }
@@ -722,31 +729,139 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
 static void ath9k_olc_temp_compensation(struct ath_hw *ah)
 {
 	u32 rddata, i;
-	int delta, currPDADC, regval;
+	int delta, currPDADC, regval, slope;
 
 	rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-
 	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
 
-	if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
-		delta = (currPDADC - ah->initPDADC + 4) / 8;
-	else
-		delta = (currPDADC - ah->initPDADC + 5) / 10;
 
-	if (delta != ah->PDADCdelta) {
-		ah->PDADCdelta = delta;
-		for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
-			regval = ah->originalGain[i] - delta;
-			if (regval < 0)
-				regval = 0;
+	if (OLC_FOR_AR9287_10_LATER) {
+		if (ah->initPDADC == 0 || currPDADC == 0) {
+			return;
+		} else {
+			slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
+			if (slope == 0)
+				delta = 0;
+			else
+				delta = ((currPDADC - ah->initPDADC)*4) / slope;
+			REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
+					AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+			REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
+					AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
+		}
+	} else {
+		if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+			delta = (currPDADC - ah->initPDADC + 4) / 8;
+		else
+			delta = (currPDADC - ah->initPDADC + 5) / 10;
+
+		if (delta != ah->PDADCdelta) {
+			ah->PDADCdelta = delta;
+			for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+				regval = ah->originalGain[i] - delta;
+				if (regval < 0)
+					regval = 0;
 
-			REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
-					AR_PHY_TX_GAIN, regval);
+				REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
+						AR_PHY_TX_GAIN, regval);
+			}
 		}
 	}
 }
 
-static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
+static void ath9k_hw_9271_pa_cal(struct ath_hw *ah)
+{
+	u32 regVal;
+	unsigned int i;
+	u32 regList [][2] = {
+		{ 0x786c, 0 },
+		{ 0x7854, 0 },
+		{ 0x7820, 0 },
+		{ 0x7824, 0 },
+		{ 0x7868, 0 },
+		{ 0x783c, 0 },
+		{ 0x7838, 0 } ,
+		{ 0x7828, 0 } ,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		regList[i][1] = REG_READ(ah, regList[i][0]);
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal &= (~(0x1));
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal |= (0x1 << 27);
+	REG_WRITE(ah, 0x9808, regVal);
+
+	/* 786c,b23,1, pwddac=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+	/* 7854, b5,1, pdrxtxbb=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+	/* 7854, b7,1, pdv2i=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+	/* 7854, b8,1, pddacinterface=1 */
+	REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+	/* 7824,b12,0, offcal=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+	/* 7838, b1,0, pwddb=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+	/* 7820,b11,0, enpacal=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+	/* 7820,b25,1, pdpadrv1=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
+	/* 7820,b24,0, pdpadrv2=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0);
+	/* 7820,b23,0, pdpaout=0 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+	/* 783c,b14-16,7, padrvgn2tab_0=7 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+	/*
+	 * 7838,b29-31,0, padrvgn1tab_0=0
+	 * does not matter since we turn it off
+	 */
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
+
+	/* Set:
+	 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
+	 * txon=1,paon=1,oscon=1,synthon_force=1
+	 */
+	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+	udelay(30);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
+
+	/* find off_6_1; */
+	for (i = 6; i >= 0; i--) {
+		regVal = REG_READ(ah, 0x7834);
+		regVal |= (1 << (20 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+		udelay(1);
+		//regVal = REG_READ(ah, 0x7834);
+		regVal &= (~(0x1 << (20 + i)));
+		regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
+			    << (20 + i));
+		REG_WRITE(ah, 0x7834, regVal);
+	}
+
+	/*  Empirical offset correction  */
+#if 0
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0x20);
+#endif
+
+	regVal = REG_READ(ah, 0x7834);
+	regVal |= 0x1;
+	REG_WRITE(ah, 0x7834, regVal);
+	regVal = REG_READ(ah, 0x9808);
+	regVal &= (~(0x1 << 27));
+	REG_WRITE(ah, 0x9808, regVal);
+
+	for (i = 0; i < ARRAY_SIZE(regList); i++)
+		REG_WRITE(ah, regList[i][0], regList[i][1]);
+}
+
+static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
 {
 
 	u32 regVal;
@@ -762,6 +877,13 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
 		{ 0x7838, 0 },
 	};
 
+	DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Running PA Calibration\n");
+
+	/* PA CAL is not needed for high power solution */
+	if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) ==
+	    AR5416_EEP_TXGAIN_HIGH_POWER)
+		return;
+
 	if (AR_SREV_9285_11(ah)) {
 		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
 		udelay(10);
@@ -784,13 +906,13 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
 	ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
-	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
+	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf);
 
 	REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
 	udelay(30);
@@ -802,7 +924,6 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
 		regVal |= (1 << (19 + i));
 		REG_WRITE(ah, 0x7834, regVal);
 		udelay(1);
-		regVal = REG_READ(ah, 0x7834);
 		regVal &= (~(0x1 << (19 + i)));
 		reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
 		regVal |= (reg_field << (19 + i));
@@ -821,6 +942,17 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
 	offs_6_1 = offset>>1;
 	offs_0 = offset & 1;
 
+	if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) {
+		if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT)
+			ah->pacal_info.max_skipcount =
+				2 * ah->pacal_info.max_skipcount;
+		ah->pacal_info.skipcount = ah->pacal_info.max_skipcount;
+	} else {
+		ah->pacal_info.max_skipcount = 1;
+		ah->pacal_info.skipcount = 0;
+		ah->pacal_info.prev_offset = offset;
+	}
+
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
 	REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
 
@@ -862,14 +994,30 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
 		}
 	}
 
+	/* Do NF cal only at longer intervals */
 	if (longcal) {
-		if (AR_SREV_9285_11_OR_LATER(ah))
-			ath9k_hw_9285_pa_cal(ah);
+		/* Do periodic PAOffset Cal */
+		if (AR_SREV_9271(ah))
+			ath9k_hw_9271_pa_cal(ah);
+		else if (AR_SREV_9285_11_OR_LATER(ah)) {
+			if (!ah->pacal_info.skipcount)
+				ath9k_hw_9285_pa_cal(ah, false);
+			else
+				ah->pacal_info.skipcount--;
+		}
 
-		if (OLC_FOR_AR9280_20_LATER)
+		if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
 			ath9k_olc_temp_compensation(ah);
+
+		/* Get the value from the previous NF cal and update history buffer */
 		ath9k_hw_getnf(ah, chan);
+
+		/*
+		 * Load the NF from history buffer of the current channel.
+		 * NF is slow time-variant, so it is OK to use a historical value.
+		 */
 		ath9k_hw_loadnf(ah, ah->curchan);
+
 		ath9k_hw_start_nfcal(ah);
 	}
 
@@ -922,8 +1070,11 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
 			return false;
 	} else {
 		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+			if (!AR_SREV_9287_10_OR_LATER(ah))
+				REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
+					    AR_PHY_ADC_CTL_OFF_PWDADC);
+			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+				    AR_PHY_AGC_CONTROL_FLTR_CAL);
 		}
 
 		/* Calibrate the AGC */
@@ -941,14 +1092,17 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
 		}
 
 		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+			if (!AR_SREV_9287_10_OR_LATER(ah))
+				REG_SET_BIT(ah, AR_PHY_ADC_CTL,
+					    AR_PHY_ADC_CTL_OFF_PWDADC);
+			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+				    AR_PHY_AGC_CONTROL_FLTR_CAL);
 		}
 	}
 
 	/* Do PA Calibration */
 	if (AR_SREV_9285_11_OR_LATER(ah))
-		ath9k_hw_9285_pa_cal(ah);
+		ath9k_hw_9285_pa_cal(ah, true);
 
 	/* Do NF Calibration after DC offset and other calibrations */
 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index fe5367f..019bcbb 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -25,7 +25,9 @@ extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
 extern const struct ath9k_percal_data adc_dc_cal_single_sample;
 extern const struct ath9k_percal_data adc_init_dc_cal;
 
-#define AR_PHY_CCA_MAX_GOOD_VALUE      		-85
+#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE	-85
+#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE	-112
+#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE	-118
 #define AR_PHY_CCA_MAX_HIGH_VALUE      		-62
 #define AR_PHY_CCA_MIN_BAD_VALUE       		-140
 #define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
@@ -108,6 +110,13 @@ struct ath9k_nfcal_hist {
 	u8 invalidNFcount;
 };
 
+#define MAX_PACAL_SKIPCOUNT 8
+struct ath9k_pacal_info{
+	int32_t prev_offset;	/* Previous value of PA offset value */
+	int8_t max_skipcount;	/* Max No. of times PACAL can be skipped */
+	int8_t skipcount;	/* No. of times the PACAL to be skipped */
+};
+
 bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
 void ath9k_hw_start_nfcal(struct ath_hw *ah);
 void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 6d20725..2be4c22 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -93,6 +93,8 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
 	int i, qcuOffset = 0, dcuOffset = 0;
 	u32 *qcuBase = &val[0], *dcuBase = &val[4];
 
+	ath9k_ps_wakeup(sc);
+
 	REG_WRITE(ah, AR_MACMISC,
 		  ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
 		   (AR_MACMISC_MISC_OBS_BUS_1 <<
@@ -159,6 +161,8 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf,
 	len += snprintf(buf + len, sizeof(buf) - len,
 			"AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
 
+	ath9k_ps_restore(sc);
+
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
 
@@ -486,6 +490,83 @@ static const struct file_operations fops_wiphy = {
 	.owner = THIS_MODULE
 };
 
+#define PR(str, elem)							\
+	do {								\
+		len += snprintf(buf + len, size - len,			\
+				"%s%13u%11u%10u%10u\n", str,		\
+		sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \
+		sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \
+		sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \
+		sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \
+} while(0)
+
+static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
+			      size_t count, loff_t *ppos)
+{
+	struct ath_softc *sc = file->private_data;
+	char *buf;
+	unsigned int len = 0, size = 2048;
+	ssize_t retval = 0;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return 0;
+
+	len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO");
+
+	PR("MPDUs Queued:    ", queued);
+	PR("MPDUs Completed: ", completed);
+	PR("Aggregates:      ", a_aggr);
+	PR("AMPDUs Queued:   ", a_queued);
+	PR("AMPDUs Completed:", a_completed);
+	PR("AMPDUs Retried:  ", a_retries);
+	PR("AMPDUs XRetried: ", a_xretries);
+	PR("FIFO Underrun:   ", fifo_underrun);
+	PR("TXOP Exceeded:   ", xtxop);
+	PR("TXTIMER Expiry:  ", timer_exp);
+	PR("DESC CFG Error:  ", desc_cfg_err);
+	PR("DATA Underrun:   ", data_underrun);
+	PR("DELIM Underrun:  ", delim_underrun);
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+}
+
+void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
+		       struct ath_buf *bf)
+{
+	struct ath_desc *ds = bf->bf_desc;
+
+	if (bf_isampdu(bf)) {
+		if (bf_isxretried(bf))
+			TX_STAT_INC(txq->axq_qnum, a_xretries);
+		else
+			TX_STAT_INC(txq->axq_qnum, a_completed);
+	} else {
+		TX_STAT_INC(txq->axq_qnum, completed);
+	}
+
+	if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)
+		TX_STAT_INC(txq->axq_qnum, fifo_underrun);
+	if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP)
+		TX_STAT_INC(txq->axq_qnum, xtxop);
+	if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED)
+		TX_STAT_INC(txq->axq_qnum, timer_exp);
+	if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR)
+		TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
+	if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN)
+		TX_STAT_INC(txq->axq_qnum, data_underrun);
+	if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN)
+		TX_STAT_INC(txq->axq_qnum, delim_underrun);
+}
+
+static const struct file_operations fops_xmit = {
+	.read = read_file_xmit,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE
+};
 
 int ath9k_init_debug(struct ath_softc *sc)
 {
@@ -500,35 +581,42 @@ int ath9k_init_debug(struct ath_softc *sc)
 		goto err;
 
 	sc->debug.debugfs_debug = debugfs_create_file("debug",
-		S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
+		S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
 	if (!sc->debug.debugfs_debug)
 		goto err;
 
-	sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
+	sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
 				       sc->debug.debugfs_phy, sc, &fops_dma);
 	if (!sc->debug.debugfs_dma)
 		goto err;
 
 	sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
-						     S_IRUGO,
+						     S_IRUSR,
 						     sc->debug.debugfs_phy,
 						     sc, &fops_interrupt);
 	if (!sc->debug.debugfs_interrupt)
 		goto err;
 
 	sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
-						  S_IRUGO,
+						  S_IRUSR,
 						  sc->debug.debugfs_phy,
 						  sc, &fops_rcstat);
 	if (!sc->debug.debugfs_rcstat)
 		goto err;
 
 	sc->debug.debugfs_wiphy = debugfs_create_file(
-		"wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
+		"wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc,
 		&fops_wiphy);
 	if (!sc->debug.debugfs_wiphy)
 		goto err;
 
+	sc->debug.debugfs_xmit = debugfs_create_file("xmit",
+						     S_IRUSR,
+						     sc->debug.debugfs_phy,
+						     sc, &fops_xmit);
+	if (!sc->debug.debugfs_xmit)
+		goto err;
+
 	return 0;
 err:
 	ath9k_exit_debug(sc);
@@ -537,6 +625,7 @@ err:
 
 void ath9k_exit_debug(struct ath_softc *sc)
 {
+	debugfs_remove(sc->debug.debugfs_xmit);
 	debugfs_remove(sc->debug.debugfs_wiphy);
 	debugfs_remove(sc->debug.debugfs_rcstat);
 	debugfs_remove(sc->debug.debugfs_interrupt);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index edda15b..7241f47 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -30,11 +30,22 @@ enum ATH_DEBUG {
 	ATH_DBG_CONFIG		= 0x00000200,
 	ATH_DBG_FATAL		= 0x00000400,
 	ATH_DBG_PS		= 0x00000800,
+	ATH_DBG_HWTIMER		= 0x00001000,
+	ATH_DBG_BTCOEX		= 0x00002000,
 	ATH_DBG_ANY		= 0xffffffff
 };
 
 #define DBG_DEFAULT (ATH_DBG_FATAL)
 
+struct ath_txq;
+struct ath_buf;
+
+#ifdef CONFIG_ATH9K_DEBUG
+#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
+#else
+#define TX_STAT_INC(q, c) do { } while (0)
+#endif
+
 #ifdef CONFIG_ATH9K_DEBUG
 
 /**
@@ -87,9 +98,45 @@ struct ath_rc_stats {
 	u8 per;
 };
 
+/**
+ * struct ath_tx_stats - Statistics about TX
+ * @queued: Total MPDUs (non-aggr) queued
+ * @completed: Total MPDUs (non-aggr) completed
+ * @a_aggr: Total no. of aggregates queued
+ * @a_queued: Total AMPDUs queued
+ * @a_completed: Total AMPDUs completed
+ * @a_retries: No. of AMPDUs retried (SW)
+ * @a_xretries: No. of AMPDUs dropped due to xretries
+ * @fifo_underrun: FIFO underrun occurrences
+	Valid only for:
+		- non-aggregate condition.
+		- first packet of aggregate.
+ * @xtxop: No. of frames filtered because of TXOP limit
+ * @timer_exp: Transmit timer expiry
+ * @desc_cfg_err: Descriptor configuration errors
+ * @data_urn: TX data underrun errors
+ * @delim_urn: TX delimiter underrun errors
+ */
+struct ath_tx_stats {
+	u32 queued;
+	u32 completed;
+	u32 a_aggr;
+	u32 a_queued;
+	u32 a_completed;
+	u32 a_retries;
+	u32 a_xretries;
+	u32 fifo_underrun;
+	u32 xtxop;
+	u32 timer_exp;
+	u32 desc_cfg_err;
+	u32 data_underrun;
+	u32 delim_underrun;
+};
+
 struct ath_stats {
 	struct ath_interrupt_stats istats;
 	struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
+	struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
 };
 
 struct ath9k_debug {
@@ -100,6 +147,7 @@ struct ath9k_debug {
 	struct dentry *debugfs_interrupt;
 	struct dentry *debugfs_rcstat;
 	struct dentry *debugfs_wiphy;
+	struct dentry *debugfs_xmit;
 	struct ath_stats stats;
 };
 
@@ -110,6 +158,8 @@ int ath9k_debug_create_root(void);
 void ath9k_debug_remove_root(void);
 void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
 void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
+void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
+		       struct ath_buf *bf);
 void ath_debug_stat_retries(struct ath_softc *sc, int rix,
 			    int xretries, int retries, u8 per);
 
@@ -148,6 +198,12 @@ static inline void ath_debug_stat_rc(struct ath_softc *sc,
 {
 }
 
+static inline void ath_debug_stat_tx(struct ath_softc *sc,
+				     struct ath_txq *txq,
+				     struct ath_buf *bf)
+{
+}
+
 static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
 					  int xretries, int retries, u8 per)
 {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index ce0e86c..b6e52d0 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -16,9 +16,16 @@
 
 #include "ath9k.h"
 
-static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
-				      u32 reg, u32 mask,
-				      u32 shift, u32 val)
+static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
+{
+	if (fbin == AR5416_BCHAN_UNUSED)
+		return fbin;
+
+	return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
+}
+
+void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
+			       u32 shift, u32 val)
 {
 	u32 regVal;
 
@@ -33,19 +40,8 @@ static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
 	return;
 }
 
-static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
-{
-
-	if (fbin == AR5416_BCHAN_UNUSED)
-		return fbin;
-
-	return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
-}
-
-static inline int16_t ath9k_hw_interpolate(u16 target,
-					   u16 srcLeft, u16 srcRight,
-					   int16_t targetLeft,
-					   int16_t targetRight)
+int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
+			     int16_t targetLeft, int16_t targetRight)
 {
 	int16_t rv;
 
@@ -59,9 +55,8 @@ static inline int16_t ath9k_hw_interpolate(u16 target,
 	return rv;
 }
 
-static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
-						  u16 listSize, u16 *indexL,
-						  u16 *indexR)
+bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
+				    u16 *indexL, u16 *indexR)
 {
 	u16 i;
 
@@ -88,16 +83,16 @@ static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
 	return false;
 }
 
-static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
+bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
 {
 	struct ath_softc *sc = ah->ah_sc;
 
 	return sc->bus_ops->eeprom_read(ah, off, data);
 }
 
-static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
-					   u8 *pVpdList, u16 numIntercepts,
-					   u8 *pRetVpdList)
+void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+			     u8 *pVpdList, u16 numIntercepts,
+			     u8 *pRetVpdList)
 {
 	u16 i, k;
 	u8 currPwr = pwrMin;
@@ -120,16 +115,14 @@ static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
 		pRetVpdList[i] = (u8) k;
 		currPwr += 2;
 	}
-
-	return true;
 }
 
-static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
-				      struct ath9k_channel *chan,
-				      struct cal_target_power_leg *powInfo,
-				      u16 numChannels,
-				      struct cal_target_power_leg *pNewPower,
-				      u16 numRates, bool isExtTarget)
+void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+				       struct ath9k_channel *chan,
+				       struct cal_target_power_leg *powInfo,
+				       u16 numChannels,
+				       struct cal_target_power_leg *pNewPower,
+				       u16 numRates, bool isExtTarget)
 {
 	struct chan_centers centers;
 	u16 clo, chi;
@@ -150,10 +143,10 @@ static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
 						       IS_CHAN_2GHZ(chan))) {
 				matchIndex = i;
 				break;
-			} else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
-						      IS_CHAN_2GHZ(chan))) &&
-				   (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
-						      IS_CHAN_2GHZ(chan)))) {
+			} else if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+						IS_CHAN_2GHZ(chan)) && i > 0 &&
+				   freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+						IS_CHAN_2GHZ(chan))) {
 				lowIndex = i - 1;
 				break;
 			}
@@ -179,75 +172,12 @@ static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
 	}
 }
 
-static void ath9k_get_txgain_index(struct ath_hw *ah,
-		struct ath9k_channel *chan,
-		struct calDataPerFreqOpLoop *rawDatasetOpLoop,
-		u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
-{
-	u8 pcdac, i = 0;
-	u16 idxL = 0, idxR = 0, numPiers;
-	bool match;
-	struct chan_centers centers;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-	for (numPiers = 0; numPiers < availPiers; numPiers++)
-		if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
-			break;
-
-	match = ath9k_hw_get_lower_upper_index(
-			(u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
-			calChans, numPiers, &idxL, &idxR);
-	if (match) {
-		pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
-		*pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
-	} else {
-		pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
-		*pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
-				rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
-	}
-
-	while (pcdac > ah->originalGain[i] &&
-			i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
-		i++;
-
-	*pcdacIdx = i;
-	return;
-}
-
-static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
-				u32 initTxGain,
-				int txPower,
-				u8 *pPDADCValues)
-{
-	u32 i;
-	u32 offset;
-
-	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
-			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
-	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
-			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
-
-	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
-			AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
-
-	offset = txPower;
-	for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
-		if (i < offset)
-			pPDADCValues[i] = 0x0;
-		else
-			pPDADCValues[i] = 0xFF;
-}
-
-
-
-
-static void ath9k_hw_get_target_powers(struct ath_hw *ah,
-				       struct ath9k_channel *chan,
-				       struct cal_target_power_ht *powInfo,
-				       u16 numChannels,
-				       struct cal_target_power_ht *pNewPower,
-				       u16 numRates, bool isHt40Target)
+void ath9k_hw_get_target_powers(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				struct cal_target_power_ht *powInfo,
+				u16 numChannels,
+				struct cal_target_power_ht *pNewPower,
+				u16 numRates, bool isHt40Target)
 {
 	struct chan_centers centers;
 	u16 clo, chi;
@@ -268,10 +198,10 @@ static void ath9k_hw_get_target_powers(struct ath_hw *ah,
 				matchIndex = i;
 				break;
 			} else
-				if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
-						       IS_CHAN_2GHZ(chan))) &&
-				    (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
-						       IS_CHAN_2GHZ(chan)))) {
+				if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+						IS_CHAN_2GHZ(chan)) && i > 0 &&
+				    freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+						IS_CHAN_2GHZ(chan))) {
 					lowIndex = i - 1;
 					break;
 				}
@@ -297,9 +227,8 @@ static void ath9k_hw_get_target_powers(struct ath_hw *ah,
 	}
 }
 
-static u16 ath9k_hw_get_max_edge_power(u16 freq,
-				       struct cal_ctl_edges *pRdEdgesPower,
-				       bool is2GHz, int num_band_edges)
+u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
+				bool is2GHz, int num_band_edges)
 {
 	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
 	int i;
@@ -325,2451 +254,14 @@ static u16 ath9k_hw_get_max_edge_power(u16 freq,
 	return twiceMaxEdgePower;
 }
 
-/****************************************/
-/* EEPROM Operations for 4K sized cards */
-/****************************************/
-
-static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
-{
-	return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
-}
-
-static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
-{
-	return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
-}
-
-static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
-{
-#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-	u16 *eep_data = (u16 *)&ah->eeprom.map4k;
-	int addr, eep_start_loc = 0;
-
-	eep_start_loc = 64;
-
-	if (!ath9k_hw_use_flash(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Reading from EEPROM, not flash\n");
-	}
-
-	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
-		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			       "Unable to read eeprom region \n");
-			return false;
-		}
-		eep_data++;
-	}
-
-	return true;
-#undef SIZE_EEPROM_4K
-}
-
-static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
-{
-#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-	struct ar5416_eeprom_4k *eep =
-		(struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
-	u16 *eepdata, temp, magic, magic2;
-	u32 sum = 0, el;
-	bool need_swap = false;
-	int i, addr;
-
-
-	if (!ath9k_hw_use_flash(ah)) {
-		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
-					 &magic)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Reading Magic # failed\n");
-			return false;
-		}
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Read Magic = 0x%04X\n", magic);
-
-		if (magic != AR5416_EEPROM_MAGIC) {
-			magic2 = swab16(magic);
-
-			if (magic2 == AR5416_EEPROM_MAGIC) {
-				need_swap = true;
-				eepdata = (u16 *) (&ah->eeprom);
-
-				for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
-					temp = swab16(*eepdata);
-					*eepdata = temp;
-					eepdata++;
-				}
-			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-					"Invalid EEPROM Magic. "
-					"endianness mismatch.\n");
-				return -EINVAL;
-			}
-		}
-	}
-
-	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-		need_swap ? "True" : "False");
-
-	if (need_swap)
-		el = swab16(ah->eeprom.map4k.baseEepHeader.length);
-	else
-		el = ah->eeprom.map4k.baseEepHeader.length;
-
-	if (el > sizeof(struct ar5416_eeprom_4k))
-		el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
-	else
-		el = el / sizeof(u16);
-
-	eepdata = (u16 *)(&ah->eeprom);
-
-	for (i = 0; i < el; i++)
-		sum ^= *eepdata++;
-
-	if (need_swap) {
-		u32 integer;
-		u16 word;
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"EEPROM Endianness is not native.. Changing\n");
-
-		word = swab16(eep->baseEepHeader.length);
-		eep->baseEepHeader.length = word;
-
-		word = swab16(eep->baseEepHeader.checksum);
-		eep->baseEepHeader.checksum = word;
-
-		word = swab16(eep->baseEepHeader.version);
-		eep->baseEepHeader.version = word;
-
-		word = swab16(eep->baseEepHeader.regDmn[0]);
-		eep->baseEepHeader.regDmn[0] = word;
-
-		word = swab16(eep->baseEepHeader.regDmn[1]);
-		eep->baseEepHeader.regDmn[1] = word;
-
-		word = swab16(eep->baseEepHeader.rfSilent);
-		eep->baseEepHeader.rfSilent = word;
-
-		word = swab16(eep->baseEepHeader.blueToothOptions);
-		eep->baseEepHeader.blueToothOptions = word;
-
-		word = swab16(eep->baseEepHeader.deviceCap);
-		eep->baseEepHeader.deviceCap = word;
-
-		integer = swab32(eep->modalHeader.antCtrlCommon);
-		eep->modalHeader.antCtrlCommon = integer;
-
-		for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
-			integer = swab32(eep->modalHeader.antCtrlChain[i]);
-			eep->modalHeader.antCtrlChain[i] = integer;
-		}
-
-		for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
-			word = swab16(eep->modalHeader.spurChans[i].spurChan);
-			eep->modalHeader.spurChans[i].spurChan = word;
-		}
-	}
-
-	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
-	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-			sum, ah->eep_ops->get_eeprom_ver(ah));
-		return -EINVAL;
-	}
-
-	return 0;
-#undef EEPROM_4K_SIZE
-}
-
-static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
-				  enum eeprom_param param)
-{
-	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-	struct modal_eep_4k_header *pModal = &eep->modalHeader;
-	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
-
-	switch (param) {
-	case EEP_NFTHRESH_2:
-		return pModal->noiseFloorThreshCh[0];
-	case AR_EEPROM_MAC(0):
-		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-	case AR_EEPROM_MAC(1):
-		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-	case AR_EEPROM_MAC(2):
-		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
-	case EEP_REG_0:
-		return pBase->regDmn[0];
-	case EEP_REG_1:
-		return pBase->regDmn[1];
-	case EEP_OP_CAP:
-		return pBase->deviceCap;
-	case EEP_OP_MODE:
-		return pBase->opCapFlags;
-	case EEP_RF_SILENT:
-		return pBase->rfSilent;
-	case EEP_OB_2:
-		return pModal->ob_01;
-	case EEP_DB_2:
-		return pModal->db1_01;
-	case EEP_MINOR_REV:
-		return pBase->version & AR5416_EEP_VER_MINOR_MASK;
-	case EEP_TX_MASK:
-		return pBase->txMask;
-	case EEP_RX_MASK:
-		return pBase->rxMask;
-	case EEP_FRAC_N_5G:
-		return 0;
-	default:
-		return 0;
-	}
-}
-
-static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
-				struct ath9k_channel *chan,
-				struct cal_data_per_freq_4k *pRawDataSet,
-				u8 *bChans, u16 availPiers,
-				u16 tPdGainOverlap, int16_t *pMinCalPower,
-				u16 *pPdGainBoundaries, u8 *pPDADCValues,
-				u16 numXpdGains)
-{
-#define TMP_VAL_VPD_TABLE \
-	((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
-	int i, j, k;
-	int16_t ss;
-	u16 idxL = 0, idxR = 0, numPiers;
-	static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-	static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-	static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-	u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
-	u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
-	int16_t vpdStep;
-	int16_t tmpVal;
-	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-	bool match;
-	int16_t minDelta = 0;
-	struct chan_centers centers;
-#define PD_GAIN_BOUNDARY_DEFAULT 58;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-	for (numPiers = 0; numPiers < availPiers; numPiers++) {
-		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
-			break;
-	}
-
-	match = ath9k_hw_get_lower_upper_index(
-					(u8)FREQ2FBIN(centers.synth_center,
-					IS_CHAN_2GHZ(chan)), bChans, numPiers,
-					&idxL, &idxR);
-
-	if (match) {
-		for (i = 0; i < numXpdGains; i++) {
-			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
-			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-					pRawDataSet[idxL].pwrPdg[i],
-					pRawDataSet[idxL].vpdPdg[i],
-					AR5416_EEP4K_PD_GAIN_ICEPTS,
-					vpdTableI[i]);
-		}
-	} else {
-		for (i = 0; i < numXpdGains; i++) {
-			pVpdL = pRawDataSet[idxL].vpdPdg[i];
-			pPwrL = pRawDataSet[idxL].pwrPdg[i];
-			pVpdR = pRawDataSet[idxR].vpdPdg[i];
-			pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
-			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
-			maxPwrT4[i] =
-				min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
-				    pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
-
-
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-						pPwrL, pVpdL,
-						AR5416_EEP4K_PD_GAIN_ICEPTS,
-						vpdTableL[i]);
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-						pPwrR, pVpdR,
-						AR5416_EEP4K_PD_GAIN_ICEPTS,
-						vpdTableR[i]);
-
-			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
-				vpdTableI[i][j] =
-					(u8)(ath9k_hw_interpolate((u16)
-					     FREQ2FBIN(centers.
-						       synth_center,
-						       IS_CHAN_2GHZ
-						       (chan)),
-					     bChans[idxL], bChans[idxR],
-					     vpdTableL[i][j], vpdTableR[i][j]));
-			}
-		}
-	}
-
-	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
-
-	k = 0;
-
-	for (i = 0; i < numXpdGains; i++) {
-		if (i == (numXpdGains - 1))
-			pPdGainBoundaries[i] =
-				(u16)(maxPwrT4[i] / 2);
-		else
-			pPdGainBoundaries[i] =
-				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
-		pPdGainBoundaries[i] =
-			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
-		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
-			minDelta = pPdGainBoundaries[0] - 23;
-			pPdGainBoundaries[0] = 23;
-		} else {
-			minDelta = 0;
-		}
-
-		if (i == 0) {
-			if (AR_SREV_9280_10_OR_LATER(ah))
-				ss = (int16_t)(0 - (minPwrT4[i] / 2));
-			else
-				ss = 0;
-		} else {
-			ss = (int16_t)((pPdGainBoundaries[i - 1] -
-					(minPwrT4[i] / 2)) -
-				       tPdGainOverlap + 1 + minDelta);
-		}
-		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
-		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
-			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
-			ss++;
-		}
-
-		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
-				(minPwrT4[i] / 2));
-		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
-			tgtIndex : sizeCurrVpdTable;
-
-		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
-			pPDADCValues[k++] = vpdTableI[i][ss++];
-
-		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
-				    vpdTableI[i][sizeCurrVpdTable - 2]);
-		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-		if (tgtIndex >= maxIndex) {
-			while ((ss <= tgtIndex) &&
-			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-				tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
-				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
-							 255 : tmpVal);
-				ss++;
-			}
-		}
-	}
-
-	while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
-		pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
-		i++;
-	}
-
-	while (k < AR5416_NUM_PDADC_VALUES) {
-		pPDADCValues[k] = pPDADCValues[k - 1];
-		k++;
-	}
-
-	return;
-#undef TMP_VAL_VPD_TABLE
-}
-
-static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
-				  struct ath9k_channel *chan,
-				  int16_t *pTxPowerIndexOffset)
-{
-	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-	struct cal_data_per_freq_4k *pRawDataset;
-	u8 *pCalBChans = NULL;
-	u16 pdGainOverlap_t2;
-	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-	u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
-	u16 numPiers, i, j;
-	int16_t tMinCalPower;
-	u16 numXpdGain, xpdMask;
-	u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
-	u32 reg32, regOffset, regChainOffset;
-
-	xpdMask = pEepData->modalHeader.xpdGain;
-
-	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_2) {
-		pdGainOverlap_t2 =
-			pEepData->modalHeader.pdGainOverlap;
-	} else {
-		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
-					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
-	}
-
-	pCalBChans = pEepData->calFreqPier2G;
-	numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
-
-	numXpdGain = 0;
-
-	for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
-		if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
-			if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
-				break;
-			xpdGainValues[numXpdGain] =
-				(u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
-			numXpdGain++;
-		}
-	}
-
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
-		      (numXpdGain - 1) & 0x3);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
-		      xpdGainValues[0]);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
-		      xpdGainValues[1]);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
-
-	for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
-		if (AR_SREV_5416_20_OR_LATER(ah) &&
-		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
-		    (i != 0)) {
-			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-		} else
-			regChainOffset = i * 0x1000;
-
-		if (pEepData->baseEepHeader.txMask & (1 << i)) {
-			pRawDataset = pEepData->calPierData2G[i];
-
-			ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
-					    pRawDataset, pCalBChans,
-					    numPiers, pdGainOverlap_t2,
-					    &tMinCalPower, gainBoundaries,
-					    pdadcValues, numXpdGain);
-
-			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
-				REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
-					  SM(pdGainOverlap_t2,
-					     AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
-					  | SM(gainBoundaries[0],
-					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
-					  | SM(gainBoundaries[1],
-					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
-					  | SM(gainBoundaries[2],
-					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
-					  | SM(gainBoundaries[3],
-				       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
-			}
-
-			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
-			for (j = 0; j < 32; j++) {
-				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
-					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
-					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
-					((pdadcValues[4 * j + 3] & 0xFF) << 24);
-				REG_WRITE(ah, regOffset, reg32);
-
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC (%d,%4x): %4.4x %8.8x\n",
-					i, regChainOffset, regOffset,
-					reg32);
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC: Chain %d | "
-					"PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d |\n",
-					i, 4 * j, pdadcValues[4 * j],
-					4 * j + 1, pdadcValues[4 * j + 1],
-					4 * j + 2, pdadcValues[4 * j + 2],
-					4 * j + 3,
-					pdadcValues[4 * j + 3]);
-
-				regOffset += 4;
-			}
-		}
-	}
-
-	*pTxPowerIndexOffset = 0;
-}
-
-static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
-						 struct ath9k_channel *chan,
-						 int16_t *ratesArray,
-						 u16 cfgCtl,
-						 u16 AntennaReduction,
-						 u16 twiceMaxRegulatoryPower,
-						 u16 powerLimit)
-{
-	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-	static const u16 tpScaleReductionTable[5] =
-		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
-	int i;
-	int16_t twiceLargestAntenna;
-	struct cal_ctl_data_4k *rep;
-	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
-		0, { 0, 0, 0, 0}
-	};
-	struct cal_target_power_leg targetPowerOfdmExt = {
-		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
-		0, { 0, 0, 0, 0 }
-	};
-	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
-		0, {0, 0, 0, 0}
-	};
-	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-	u16 ctlModesFor11g[] =
-		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-		  CTL_2GHT40
-		};
-	u16 numCtlModes, *pCtlMode, ctlMode, freq;
-	struct chan_centers centers;
-	int tx_chainmask;
-	u16 twiceMinEdgePower;
-
-	tx_chainmask = ah->txchainmask;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-	twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
-
-	twiceLargestAntenna = (int16_t)min(AntennaReduction -
-					   twiceLargestAntenna, 0);
-
-	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
-	if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
-		maxRegAllowedPower -=
-			(tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
-	}
-
-	scaledPower = min(powerLimit, maxRegAllowedPower);
-	scaledPower = max((u16)0, scaledPower);
-
-	numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
-	pCtlMode = ctlModesFor11g;
-
-	ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPowerCck,
-			AR5416_NUM_2G_CCK_TARGET_POWERS,
-			&targetPowerCck, 4, false);
-	ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPower2G,
-			AR5416_NUM_2G_20_TARGET_POWERS,
-			&targetPowerOfdm, 4, false);
-	ath9k_hw_get_target_powers(ah, chan,
-			pEepData->calTargetPower2GHT20,
-			AR5416_NUM_2G_20_TARGET_POWERS,
-			&targetPowerHt20, 8, false);
-
-	if (IS_CHAN_HT40(chan)) {
-		numCtlModes = ARRAY_SIZE(ctlModesFor11g);
-		ath9k_hw_get_target_powers(ah, chan,
-				pEepData->calTargetPower2GHT40,
-				AR5416_NUM_2G_40_TARGET_POWERS,
-				&targetPowerHt40, 8, true);
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPowerCck,
-				AR5416_NUM_2G_CCK_TARGET_POWERS,
-				&targetPowerCckExt, 4, true);
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPower2G,
-				AR5416_NUM_2G_20_TARGET_POWERS,
-				&targetPowerOfdmExt, 4, true);
-	}
-
-	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
-			(pCtlMode[ctlMode] == CTL_2GHT40);
-		if (isHt40CtlMode)
-			freq = centers.synth_center;
-		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
-			freq = centers.ext_center;
-		else
-			freq = centers.ctl_center;
-
-		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
-		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
-			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
-			"EXT_ADDITIVE %d\n",
-			ctlMode, numCtlModes, isHt40CtlMode,
-			(pCtlMode[ctlMode] & EXT_ADDITIVE));
-
-		for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
-				pEepData->ctlIndex[i]; i++) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
-				"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
-				"chan %d\n",
-				i, cfgCtl, pCtlMode[ctlMode],
-				pEepData->ctlIndex[i], chan->channel);
-
-			if ((((cfgCtl & ~CTL_MODE_M) |
-			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-			     pEepData->ctlIndex[i]) ||
-			    (((cfgCtl & ~CTL_MODE_M) |
-			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-			     ((pEepData->ctlIndex[i] & CTL_MODE_M) |
-			      SD_NO_CTL))) {
-				rep = &(pEepData->ctlData[i]);
-
-				twiceMinEdgePower =
-					ath9k_hw_get_max_edge_power(freq,
-				rep->ctlEdges[ar5416_get_ntxchains
-						(tx_chainmask) - 1],
-				IS_CHAN_2GHZ(chan),
-				AR5416_EEP4K_NUM_BAND_EDGES);
-
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"    MATCH-EE_IDX %d: ch %d is2 %d "
-					"2xMinEdge %d chainmask %d chains %d\n",
-					i, freq, IS_CHAN_2GHZ(chan),
-					twiceMinEdgePower, tx_chainmask,
-					ar5416_get_ntxchains
-					(tx_chainmask));
-				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
-					twiceMaxEdgePower =
-						min(twiceMaxEdgePower,
-						    twiceMinEdgePower);
-				} else {
-					twiceMaxEdgePower = twiceMinEdgePower;
-					break;
-				}
-			}
-		}
-
-		minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"    SEL-Min ctlMode %d pCtlMode %d "
-			"2xMaxEdge %d sP %d minCtlPwr %d\n",
-			ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
-			scaledPower, minCtlPower);
-
-		switch (pCtlMode[ctlMode]) {
-		case CTL_11B:
-			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
-					i++) {
-				targetPowerCck.tPow2x[i] =
-					min((u16)targetPowerCck.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_11G:
-			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
-					i++) {
-				targetPowerOfdm.tPow2x[i] =
-					min((u16)targetPowerOfdm.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_2GHT20:
-			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
-					i++) {
-				targetPowerHt20.tPow2x[i] =
-					min((u16)targetPowerHt20.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_11B_EXT:
-			targetPowerCckExt.tPow2x[0] = min((u16)
-					targetPowerCckExt.tPow2x[0],
-					minCtlPower);
-			break;
-		case CTL_11G_EXT:
-			targetPowerOfdmExt.tPow2x[0] = min((u16)
-					targetPowerOfdmExt.tPow2x[0],
-					minCtlPower);
-			break;
-		case CTL_2GHT40:
-			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
-					i++) {
-				targetPowerHt40.tPow2x[i] =
-					min((u16)targetPowerHt40.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		default:
-			break;
-		}
-	}
-
-	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
-		ratesArray[rate18mb] = ratesArray[rate24mb] =
-		targetPowerOfdm.tPow2x[0];
-	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
-	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
-	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
-	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
-	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
-		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
-	ratesArray[rate1l] = targetPowerCck.tPow2x[0];
-	ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
-	ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
-	ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
-
-	if (IS_CHAN_HT40(chan)) {
-		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-			ratesArray[rateHt40_0 + i] =
-				targetPowerHt40.tPow2x[i];
-		}
-		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
-		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
-		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
-		ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
-	}
-}
-
-static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
-				   struct ath9k_channel *chan,
-				   u16 cfgCtl,
-				   u8 twiceAntennaReduction,
-				   u8 twiceMaxRegulatoryPower,
-				   u8 powerLimit)
-{
-	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-	struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
-	int16_t ratesArray[Ar5416RateSize];
-	int16_t txPowerIndexOffset = 0;
-	u8 ht40PowerIncForPdadc = 2;
-	int i;
-
-	memset(ratesArray, 0, sizeof(ratesArray));
-
-	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_2) {
-		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
-	}
-
-	ath9k_hw_set_4k_power_per_rate_table(ah, chan,
-					       &ratesArray[0], cfgCtl,
-					       twiceAntennaReduction,
-					       twiceMaxRegulatoryPower,
-					       powerLimit);
-
-	ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
-
-	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
-		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
-			ratesArray[i] = AR5416_MAX_RATE_POWER;
-	}
-
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		for (i = 0; i < Ar5416RateSize; i++)
-			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
-	}
-
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
-		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
-		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
-		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
-		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
-		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
-		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
-		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
-		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
-
-	if (IS_CHAN_2GHZ(chan)) {
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-			  ATH9K_POW_SM(ratesArray[rate2s], 24)
-			  | ATH9K_POW_SM(ratesArray[rate2l], 16)
-			  | ATH9K_POW_SM(ratesArray[rateXr], 8)
-			  | ATH9K_POW_SM(ratesArray[rate1l], 0));
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-			  ATH9K_POW_SM(ratesArray[rate11s], 24)
-			  | ATH9K_POW_SM(ratesArray[rate11l], 16)
-			  | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
-			  | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
-	}
-
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
-		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
-		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
-
-	if (IS_CHAN_HT40(chan)) {
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
-			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
-				       ht40PowerIncForPdadc, 24)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
-					 ht40PowerIncForPdadc, 16)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
-					 ht40PowerIncForPdadc, 8)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
-					 ht40PowerIncForPdadc, 0));
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
-			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
-				       ht40PowerIncForPdadc, 24)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
-					 ht40PowerIncForPdadc, 16)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
-					 ht40PowerIncForPdadc, 8)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
-					 ht40PowerIncForPdadc, 0));
-
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-			  ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-			  | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
-			  | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-			  | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
-	}
-
-	i = rate6mb;
-
-	if (IS_CHAN_HT40(chan))
-		i = rateHt40_0;
-	else if (IS_CHAN_HT20(chan))
-		i = rateHt20_0;
-
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ah->regulatory.max_power_level =
-			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-	else
-		ah->regulatory.max_power_level = ratesArray[i];
-
-}
-
-static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
-				  struct ath9k_channel *chan)
-{
-	struct modal_eep_4k_header *pModal;
-	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-	u8 biaslevel;
-
-	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
-		return;
-
-	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
-		return;
-
-	pModal = &eep->modalHeader;
-
-	if (pModal->xpaBiasLvl != 0xff) {
-		biaslevel = pModal->xpaBiasLvl;
-		INI_RA(&ah->iniAddac, 7, 1) =
-		  (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
-	}
-}
-
-static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
-				 struct modal_eep_4k_header *pModal,
-				 struct ar5416_eeprom_4k *eep,
-				 u8 txRxAttenLocal, int regChainOffset)
-{
-	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
-		  pModal->antCtrlChain[0]);
-
-	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
-		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
-		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
-
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_3) {
-		txRxAttenLocal = pModal->txRxAttenCh[0];
-
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
-			      pModal->xatten2Margin[0]);
-		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
-	}
-
-	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
-		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
-	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
-		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
-
-	if (AR_SREV_9285_11(ah))
-		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
-}
-
-static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
-					 struct ath9k_channel *chan)
-{
-	struct modal_eep_4k_header *pModal;
-	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-	u8 txRxAttenLocal;
-	u8 ob[5], db1[5], db2[5];
-	u8 ant_div_control1, ant_div_control2;
-	u32 regVal;
-
-	pModal = &eep->modalHeader;
-	txRxAttenLocal = 23;
-
-	REG_WRITE(ah, AR_PHY_SWITCH_COM,
-		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
-
-	/* Single chain for 4K EEPROM*/
-	ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
-
-	/* Initialize Ant Diversity settings from EEPROM */
-	if (pModal->version == 3) {
-		ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
-		ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
-		regVal = REG_READ(ah, 0x99ac);
-		regVal &= (~(0x7f000000));
-		regVal |= ((ant_div_control1 & 0x1) << 24);
-		regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
-		regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
-		regVal |= ((ant_div_control2 & 0x3) << 25);
-		regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
-		REG_WRITE(ah, 0x99ac, regVal);
-		regVal = REG_READ(ah, 0x99ac);
-		regVal = REG_READ(ah, 0xa208);
-		regVal &= (~(0x1 << 13));
-		regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
-		REG_WRITE(ah, 0xa208, regVal);
-		regVal = REG_READ(ah, 0xa208);
-	}
-
-	if (pModal->version >= 2) {
-		ob[0] = (pModal->ob_01 & 0xf);
-		ob[1] = (pModal->ob_01 >> 4) & 0xf;
-		ob[2] = (pModal->ob_234 & 0xf);
-		ob[3] = ((pModal->ob_234 >> 4) & 0xf);
-		ob[4] = ((pModal->ob_234 >> 8) & 0xf);
-
-		db1[0] = (pModal->db1_01 & 0xf);
-		db1[1] = ((pModal->db1_01 >> 4) & 0xf);
-		db1[2] = (pModal->db1_234 & 0xf);
-		db1[3] = ((pModal->db1_234 >> 4) & 0xf);
-		db1[4] = ((pModal->db1_234 >> 8) & 0xf);
-
-		db2[0] = (pModal->db2_01 & 0xf);
-		db2[1] = ((pModal->db2_01 >> 4) & 0xf);
-		db2[2] = (pModal->db2_234 & 0xf);
-		db2[3] = ((pModal->db2_234 >> 4) & 0xf);
-		db2[4] = ((pModal->db2_234 >> 8) & 0xf);
-
-	} else if (pModal->version == 1) {
-		ob[0] = (pModal->ob_01 & 0xf);
-		ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
-		db1[0] = (pModal->db1_01 & 0xf);
-		db1[1] = db1[2] = db1[3] =
-			db1[4] = ((pModal->db1_01 >> 4) & 0xf);
-		db2[0] = (pModal->db2_01 & 0xf);
-		db2[1] = db2[2] = db2[3] =
-			db2[4] = ((pModal->db2_01 >> 4) & 0xf);
-	} else {
-		int i;
-		for (i = 0; i < 5; i++) {
-			ob[i] = pModal->ob_01;
-			db1[i] = pModal->db1_01;
-			db2[i] = pModal->db1_01;
-		}
-	}
-
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
-
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-			AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
-
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
-	ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-			AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
-
-
-	if (AR_SREV_9285_11(ah))
-		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
-
-	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-		      pModal->switchSettling);
-	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
-		      pModal->adcDesiredSize);
-
-	REG_WRITE(ah, AR_PHY_RF_CTL4,
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
-		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
-
-	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
-		      pModal->txEndToRxOn);
-	REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
-		      pModal->thresh62);
-	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
-		      pModal->thresh62);
-
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-						AR5416_EEP_MINOR_VER_2) {
-		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
-			      pModal->txFrameToDataStart);
-		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
-			      pModal->txFrameToPaOn);
-	}
-
-	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-						AR5416_EEP_MINOR_VER_3) {
-		if (IS_CHAN_HT40(chan))
-			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
-				      AR_PHY_SETTLING_SWITCH,
-				      pModal->swSettleHt40);
-	}
-}
-
-static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
-					      struct ath9k_channel *chan)
-{
-	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-	struct modal_eep_4k_header *pModal = &eep->modalHeader;
-
-	return pModal->antCtrlCommon & 0xFFFF;
-}
-
-static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
-					 enum ieee80211_band freq_band)
-{
-	return 1;
-}
-
-static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
-{
-#define EEP_MAP4K_SPURCHAN \
-	(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
-
-	u16 spur_val = AR_NO_SPUR;
-
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"Getting spur idx %d is2Ghz. %d val %x\n",
-		i, is2GHz, ah->config.spurchans[i][is2GHz]);
-
-	switch (ah->config.spurmode) {
-	case SPUR_DISABLE:
-		break;
-	case SPUR_ENABLE_IOCTL:
-		spur_val = ah->config.spurchans[i][is2GHz];
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"Getting spur val from new loc. %d\n", spur_val);
-		break;
-	case SPUR_ENABLE_EEPROM:
-		spur_val = EEP_MAP4K_SPURCHAN;
-		break;
-	}
-
-	return spur_val;
-
-#undef EEP_MAP4K_SPURCHAN
-}
-
-static struct eeprom_ops eep_4k_ops = {
-	.check_eeprom		= ath9k_hw_4k_check_eeprom,
-	.get_eeprom		= ath9k_hw_4k_get_eeprom,
-	.fill_eeprom		= ath9k_hw_4k_fill_eeprom,
-	.get_eeprom_ver		= ath9k_hw_4k_get_eeprom_ver,
-	.get_eeprom_rev		= ath9k_hw_4k_get_eeprom_rev,
-	.get_num_ant_config	= ath9k_hw_4k_get_num_ant_config,
-	.get_eeprom_antenna_cfg	= ath9k_hw_4k_get_eeprom_antenna_cfg,
-	.set_board_values	= ath9k_hw_4k_set_board_values,
-	.set_addac		= ath9k_hw_4k_set_addac,
-	.set_txpower		= ath9k_hw_4k_set_txpower,
-	.get_spur_channel	= ath9k_hw_4k_get_spur_channel
-};
-
-/************************************************/
-/* EEPROM Operations for non-4K (Default) cards */
-/************************************************/
-
-static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
-{
-	return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
-}
-
-static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
-{
-	return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
-}
-
-static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
-{
-#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
-	u16 *eep_data = (u16 *)&ah->eeprom.def;
-	int addr, ar5416_eep_start_loc = 0x100;
-
-	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
-		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
-					 eep_data)) {
-			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-				"Unable to read eeprom region\n");
-			return false;
-		}
-		eep_data++;
-	}
-	return true;
-#undef SIZE_EEPROM_DEF
-}
-
-static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
-{
-	struct ar5416_eeprom_def *eep =
-		(struct ar5416_eeprom_def *) &ah->eeprom.def;
-	u16 *eepdata, temp, magic, magic2;
-	u32 sum = 0, el;
-	bool need_swap = false;
-	int i, addr, size;
-
-	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
-		return false;
-	}
-
-	if (!ath9k_hw_use_flash(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Read Magic = 0x%04X\n", magic);
-
-		if (magic != AR5416_EEPROM_MAGIC) {
-			magic2 = swab16(magic);
-
-			if (magic2 == AR5416_EEPROM_MAGIC) {
-				size = sizeof(struct ar5416_eeprom_def);
-				need_swap = true;
-				eepdata = (u16 *) (&ah->eeprom);
-
-				for (addr = 0; addr < size / sizeof(u16); addr++) {
-					temp = swab16(*eepdata);
-					*eepdata = temp;
-					eepdata++;
-				}
-			} else {
-				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-					"Invalid EEPROM Magic. "
-					"Endianness mismatch.\n");
-				return -EINVAL;
-			}
-		}
-	}
-
-	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-		need_swap ? "True" : "False");
-
-	if (need_swap)
-		el = swab16(ah->eeprom.def.baseEepHeader.length);
-	else
-		el = ah->eeprom.def.baseEepHeader.length;
-
-	if (el > sizeof(struct ar5416_eeprom_def))
-		el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
-	else
-		el = el / sizeof(u16);
-
-	eepdata = (u16 *)(&ah->eeprom);
-
-	for (i = 0; i < el; i++)
-		sum ^= *eepdata++;
-
-	if (need_swap) {
-		u32 integer, j;
-		u16 word;
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"EEPROM Endianness is not native.. Changing.\n");
-
-		word = swab16(eep->baseEepHeader.length);
-		eep->baseEepHeader.length = word;
-
-		word = swab16(eep->baseEepHeader.checksum);
-		eep->baseEepHeader.checksum = word;
-
-		word = swab16(eep->baseEepHeader.version);
-		eep->baseEepHeader.version = word;
-
-		word = swab16(eep->baseEepHeader.regDmn[0]);
-		eep->baseEepHeader.regDmn[0] = word;
-
-		word = swab16(eep->baseEepHeader.regDmn[1]);
-		eep->baseEepHeader.regDmn[1] = word;
-
-		word = swab16(eep->baseEepHeader.rfSilent);
-		eep->baseEepHeader.rfSilent = word;
-
-		word = swab16(eep->baseEepHeader.blueToothOptions);
-		eep->baseEepHeader.blueToothOptions = word;
-
-		word = swab16(eep->baseEepHeader.deviceCap);
-		eep->baseEepHeader.deviceCap = word;
-
-		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
-			struct modal_eep_header *pModal =
-				&eep->modalHeader[j];
-			integer = swab32(pModal->antCtrlCommon);
-			pModal->antCtrlCommon = integer;
-
-			for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-				integer = swab32(pModal->antCtrlChain[i]);
-				pModal->antCtrlChain[i] = integer;
-			}
-
-			for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
-				word = swab16(pModal->spurChans[i].spurChan);
-				pModal->spurChans[i].spurChan = word;
-			}
-		}
-	}
-
-	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
-	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-			sum, ah->eep_ops->get_eeprom_ver(ah));
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
-				   enum eeprom_param param)
-{
-	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-	struct modal_eep_header *pModal = eep->modalHeader;
-	struct base_eep_header *pBase = &eep->baseEepHeader;
-
-	switch (param) {
-	case EEP_NFTHRESH_5:
-		return pModal[0].noiseFloorThreshCh[0];
-	case EEP_NFTHRESH_2:
-		return pModal[1].noiseFloorThreshCh[0];
-	case AR_EEPROM_MAC(0):
-		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-	case AR_EEPROM_MAC(1):
-		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-	case AR_EEPROM_MAC(2):
-		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
-	case EEP_REG_0:
-		return pBase->regDmn[0];
-	case EEP_REG_1:
-		return pBase->regDmn[1];
-	case EEP_OP_CAP:
-		return pBase->deviceCap;
-	case EEP_OP_MODE:
-		return pBase->opCapFlags;
-	case EEP_RF_SILENT:
-		return pBase->rfSilent;
-	case EEP_OB_5:
-		return pModal[0].ob;
-	case EEP_DB_5:
-		return pModal[0].db;
-	case EEP_OB_2:
-		return pModal[1].ob;
-	case EEP_DB_2:
-		return pModal[1].db;
-	case EEP_MINOR_REV:
-		return AR5416_VER_MASK;
-	case EEP_TX_MASK:
-		return pBase->txMask;
-	case EEP_RX_MASK:
-		return pBase->rxMask;
-	case EEP_RXGAIN_TYPE:
-		return pBase->rxGainType;
-	case EEP_TXGAIN_TYPE:
-		return pBase->txGainType;
-	case EEP_OL_PWRCTRL:
-		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-			return pBase->openLoopPwrCntl ? true : false;
-		else
-			return false;
-	case EEP_RC_CHAIN_MASK:
-		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-			return pBase->rcChainMask;
-		else
-			return 0;
-	case EEP_DAC_HPWR_5G:
-		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
-			return pBase->dacHiPwrMode_5G;
-		else
-			return 0;
-	case EEP_FRAC_N_5G:
-		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
-			return pBase->frac_n_5g;
-		else
-			return 0;
-	default:
-		return 0;
-	}
-}
-
-static void ath9k_hw_def_set_gain(struct ath_hw *ah,
-				  struct modal_eep_header *pModal,
-				  struct ar5416_eeprom_def *eep,
-				  u8 txRxAttenLocal, int regChainOffset, int i)
-{
-	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
-		txRxAttenLocal = pModal->txRxAttenCh[i];
-
-		if (AR_SREV_9280_10_OR_LATER(ah)) {
-			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
-			      pModal->bswMargin[i]);
-			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN1_DB,
-			      pModal->bswAtten[i]);
-			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
-			      pModal->xatten2Margin[i]);
-			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
-			      pModal->xatten2Db[i]);
-		} else {
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
-			  | SM(pModal-> bswMargin[i],
-			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
-			  | SM(pModal->bswAtten[i],
-			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-		}
-	}
-
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		REG_RMW_FIELD(ah,
-		      AR_PHY_RXGAIN + regChainOffset,
-		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
-		REG_RMW_FIELD(ah,
-		      AR_PHY_RXGAIN + regChainOffset,
-		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
-	} else {
-		REG_WRITE(ah,
-			  AR_PHY_RXGAIN + regChainOffset,
-			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
-			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
-			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
-		REG_WRITE(ah,
-			  AR_PHY_GAIN_2GHZ + regChainOffset,
-			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
-	}
-}
-
-static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-					  struct ath9k_channel *chan)
-{
-	struct modal_eep_header *pModal;
-	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-	int i, regChainOffset;
-	u8 txRxAttenLocal;
-
-	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-	txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
-
-	REG_WRITE(ah, AR_PHY_SWITCH_COM,
-		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
-
-	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		if (AR_SREV_9280(ah)) {
-			if (i >= 2)
-				break;
-		}
-
-		if (AR_SREV_5416_20_OR_LATER(ah) &&
-		    (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
-			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-		else
-			regChainOffset = i * 0x1000;
-
-		REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
-			  pModal->antCtrlChain[i]);
-
-		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
-			  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
-			   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-			  SM(pModal->iqCalICh[i],
-			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-			  SM(pModal->iqCalQCh[i],
-			     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
-
-		if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
-			ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
-					      regChainOffset, i);
-	}
-
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		if (IS_CHAN_2GHZ(chan)) {
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
-						  AR_AN_RF2G1_CH0_OB,
-						  AR_AN_RF2G1_CH0_OB_S,
-						  pModal->ob);
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
-						  AR_AN_RF2G1_CH0_DB,
-						  AR_AN_RF2G1_CH0_DB_S,
-						  pModal->db);
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
-						  AR_AN_RF2G1_CH1_OB,
-						  AR_AN_RF2G1_CH1_OB_S,
-						  pModal->ob_ch1);
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
-						  AR_AN_RF2G1_CH1_DB,
-						  AR_AN_RF2G1_CH1_DB_S,
-						  pModal->db_ch1);
-		} else {
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
-						  AR_AN_RF5G1_CH0_OB5,
-						  AR_AN_RF5G1_CH0_OB5_S,
-						  pModal->ob);
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
-						  AR_AN_RF5G1_CH0_DB5,
-						  AR_AN_RF5G1_CH0_DB5_S,
-						  pModal->db);
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
-						  AR_AN_RF5G1_CH1_OB5,
-						  AR_AN_RF5G1_CH1_OB5_S,
-						  pModal->ob_ch1);
-			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
-						  AR_AN_RF5G1_CH1_DB5,
-						  AR_AN_RF5G1_CH1_DB5_S,
-						  pModal->db_ch1);
-		}
-		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
-					  AR_AN_TOP2_XPABIAS_LVL,
-					  AR_AN_TOP2_XPABIAS_LVL_S,
-					  pModal->xpaBiasLvl);
-		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
-					  AR_AN_TOP2_LOCALBIAS,
-					  AR_AN_TOP2_LOCALBIAS_S,
-					  pModal->local_bias);
-		REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
-			      pModal->force_xpaon);
-	}
-
-	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-		      pModal->switchSettling);
-	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
-		      pModal->adcDesiredSize);
-
-	if (!AR_SREV_9280_10_OR_LATER(ah))
-		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-			      AR_PHY_DESIRED_SZ_PGA,
-			      pModal->pgaDesiredSize);
-
-	REG_WRITE(ah, AR_PHY_RF_CTL4,
-		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
-		  | SM(pModal->txEndToXpaOff,
-		       AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
-		  | SM(pModal->txFrameToXpaOn,
-		       AR_PHY_RF_CTL4_FRAME_XPAA_ON)
-		  | SM(pModal->txFrameToXpaOn,
-		       AR_PHY_RF_CTL4_FRAME_XPAB_ON));
-
-	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
-		      pModal->txEndToRxOn);
-
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
-			      pModal->thresh62);
-		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
-			      AR_PHY_EXT_CCA0_THRESH62,
-			      pModal->thresh62);
-	} else {
-		REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
-			      pModal->thresh62);
-		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
-			      AR_PHY_EXT_CCA_THRESH62,
-			      pModal->thresh62);
-	}
-
-	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
-		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
-			      AR_PHY_TX_END_DATA_START,
-			      pModal->txFrameToDataStart);
-		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
-			      pModal->txFrameToPaOn);
-	}
-
-	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
-		if (IS_CHAN_HT40(chan))
-			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
-				      AR_PHY_SETTLING_SWITCH,
-				      pModal->swSettleHt40);
-	}
-
-	if (AR_SREV_9280_20_OR_LATER(ah) &&
-	    AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-		REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
-			      AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
-			      pModal->miscBits);
-
-
-	if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
-		if (IS_CHAN_2GHZ(chan))
-			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
-					eep->baseEepHeader.dacLpMode);
-		else if (eep->baseEepHeader.dacHiPwrMode_5G)
-			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
-		else
-			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
-				      eep->baseEepHeader.dacLpMode);
-
-		REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
-			      pModal->miscBits >> 2);
-
-		REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
-			      AR_PHY_TX_DESIRED_SCALE_CCK,
-			      eep->baseEepHeader.desiredScaleCCK);
-	}
-}
-
-static void ath9k_hw_def_set_addac(struct ath_hw *ah,
-				   struct ath9k_channel *chan)
-{
-#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
-	struct modal_eep_header *pModal;
-	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-	u8 biaslevel;
-
-	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
-		return;
-
-	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
-		return;
-
-	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-	if (pModal->xpaBiasLvl != 0xff) {
-		biaslevel = pModal->xpaBiasLvl;
-	} else {
-		u16 resetFreqBin, freqBin, freqCount = 0;
-		struct chan_centers centers;
-
-		ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-		resetFreqBin = FREQ2FBIN(centers.synth_center,
-					 IS_CHAN_2GHZ(chan));
-		freqBin = XPA_LVL_FREQ(0) & 0xff;
-		biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
-
-		freqCount++;
-
-		while (freqCount < 3) {
-			if (XPA_LVL_FREQ(freqCount) == 0x0)
-				break;
-
-			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
-			if (resetFreqBin >= freqBin)
-				biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
-			else
-				break;
-			freqCount++;
-		}
-	}
-
-	if (IS_CHAN_2GHZ(chan)) {
-		INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
-					7, 1) & (~0x18)) | biaslevel << 3;
-	} else {
-		INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
-					6, 1) & (~0xc0)) | biaslevel << 6;
-	}
-#undef XPA_LVL_FREQ
-}
-
-static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
-				struct ath9k_channel *chan,
-				struct cal_data_per_freq *pRawDataSet,
-				u8 *bChans, u16 availPiers,
-				u16 tPdGainOverlap, int16_t *pMinCalPower,
-				u16 *pPdGainBoundaries, u8 *pPDADCValues,
-				u16 numXpdGains)
-{
-	int i, j, k;
-	int16_t ss;
-	u16 idxL = 0, idxR = 0, numPiers;
-	static u8 vpdTableL[AR5416_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-	static u8 vpdTableR[AR5416_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-	static u8 vpdTableI[AR5416_NUM_PD_GAINS]
-		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-	u8 minPwrT4[AR5416_NUM_PD_GAINS];
-	u8 maxPwrT4[AR5416_NUM_PD_GAINS];
-	int16_t vpdStep;
-	int16_t tmpVal;
-	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-	bool match;
-	int16_t minDelta = 0;
-	struct chan_centers centers;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-	for (numPiers = 0; numPiers < availPiers; numPiers++) {
-		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
-			break;
-	}
-
-	match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
-							     IS_CHAN_2GHZ(chan)),
-					       bChans, numPiers, &idxL, &idxR);
-
-	if (match) {
-		for (i = 0; i < numXpdGains; i++) {
-			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
-			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-					pRawDataSet[idxL].pwrPdg[i],
-					pRawDataSet[idxL].vpdPdg[i],
-					AR5416_PD_GAIN_ICEPTS,
-					vpdTableI[i]);
-		}
-	} else {
-		for (i = 0; i < numXpdGains; i++) {
-			pVpdL = pRawDataSet[idxL].vpdPdg[i];
-			pPwrL = pRawDataSet[idxL].pwrPdg[i];
-			pVpdR = pRawDataSet[idxR].vpdPdg[i];
-			pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
-			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
-			maxPwrT4[i] =
-				min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
-				    pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
-
-
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-						pPwrL, pVpdL,
-						AR5416_PD_GAIN_ICEPTS,
-						vpdTableL[i]);
-			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-						pPwrR, pVpdR,
-						AR5416_PD_GAIN_ICEPTS,
-						vpdTableR[i]);
-
-			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
-				vpdTableI[i][j] =
-					(u8)(ath9k_hw_interpolate((u16)
-					     FREQ2FBIN(centers.
-						       synth_center,
-						       IS_CHAN_2GHZ
-						       (chan)),
-					     bChans[idxL], bChans[idxR],
-					     vpdTableL[i][j], vpdTableR[i][j]));
-			}
-		}
-	}
-
-	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
-
-	k = 0;
-
-	for (i = 0; i < numXpdGains; i++) {
-		if (i == (numXpdGains - 1))
-			pPdGainBoundaries[i] =
-				(u16)(maxPwrT4[i] / 2);
-		else
-			pPdGainBoundaries[i] =
-				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
-		pPdGainBoundaries[i] =
-			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
-		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
-			minDelta = pPdGainBoundaries[0] - 23;
-			pPdGainBoundaries[0] = 23;
-		} else {
-			minDelta = 0;
-		}
-
-		if (i == 0) {
-			if (AR_SREV_9280_10_OR_LATER(ah))
-				ss = (int16_t)(0 - (minPwrT4[i] / 2));
-			else
-				ss = 0;
-		} else {
-			ss = (int16_t)((pPdGainBoundaries[i - 1] -
-					(minPwrT4[i] / 2)) -
-				       tPdGainOverlap + 1 + minDelta);
-		}
-		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
-		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
-			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
-			ss++;
-		}
-
-		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
-				(minPwrT4[i] / 2));
-		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
-			tgtIndex : sizeCurrVpdTable;
-
-		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-			pPDADCValues[k++] = vpdTableI[i][ss++];
-		}
-
-		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
-				    vpdTableI[i][sizeCurrVpdTable - 2]);
-		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-		if (tgtIndex > maxIndex) {
-			while ((ss <= tgtIndex) &&
-			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-				tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
-						    (ss - maxIndex + 1) * vpdStep));
-				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
-							 255 : tmpVal);
-				ss++;
-			}
-		}
-	}
-
-	while (i < AR5416_PD_GAINS_IN_MASK) {
-		pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
-		i++;
-	}
-
-	while (k < AR5416_NUM_PDADC_VALUES) {
-		pPDADCValues[k] = pPDADCValues[k - 1];
-		k++;
-	}
-
-	return;
-}
-
-static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
-				  struct ath9k_channel *chan,
-				  int16_t *pTxPowerIndexOffset)
-{
-#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
-#define SM_PDGAIN_B(x, y) \
-		SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
-
-	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-	struct cal_data_per_freq *pRawDataset;
-	u8 *pCalBChans = NULL;
-	u16 pdGainOverlap_t2;
-	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
-	u16 numPiers, i, j;
-	int16_t tMinCalPower;
-	u16 numXpdGain, xpdMask;
-	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
-	u32 reg32, regOffset, regChainOffset;
-	int16_t modalIdx;
-
-	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
-	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
-
-	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_2) {
-		pdGainOverlap_t2 =
-			pEepData->modalHeader[modalIdx].pdGainOverlap;
-	} else {
-		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
-					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
-	}
-
-	if (IS_CHAN_2GHZ(chan)) {
-		pCalBChans = pEepData->calFreqPier2G;
-		numPiers = AR5416_NUM_2G_CAL_PIERS;
-	} else {
-		pCalBChans = pEepData->calFreqPier5G;
-		numPiers = AR5416_NUM_5G_CAL_PIERS;
-	}
-
-	if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
-		pRawDataset = pEepData->calPierData2G[0];
-		ah->initPDADC = ((struct calDataPerFreqOpLoop *)
-				 pRawDataset)->vpdPdg[0][0];
-	}
-
-	numXpdGain = 0;
-
-	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
-		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
-			if (numXpdGain >= AR5416_NUM_PD_GAINS)
-				break;
-			xpdGainValues[numXpdGain] =
-				(u16)(AR5416_PD_GAINS_IN_MASK - i);
-			numXpdGain++;
-		}
-	}
-
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
-		      (numXpdGain - 1) & 0x3);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
-		      xpdGainValues[0]);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
-		      xpdGainValues[1]);
-	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
-		      xpdGainValues[2]);
-
-	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		if (AR_SREV_5416_20_OR_LATER(ah) &&
-		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
-		    (i != 0)) {
-			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-		} else
-			regChainOffset = i * 0x1000;
-
-		if (pEepData->baseEepHeader.txMask & (1 << i)) {
-			if (IS_CHAN_2GHZ(chan))
-				pRawDataset = pEepData->calPierData2G[i];
-			else
-				pRawDataset = pEepData->calPierData5G[i];
-
-
-			if (OLC_FOR_AR9280_20_LATER) {
-				u8 pcdacIdx;
-				u8 txPower;
-
-				ath9k_get_txgain_index(ah, chan,
-				(struct calDataPerFreqOpLoop *)pRawDataset,
-				pCalBChans, numPiers, &txPower, &pcdacIdx);
-				ath9k_olc_get_pdadcs(ah, pcdacIdx,
-						     txPower/2, pdadcValues);
-			} else {
-				ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
-							chan, pRawDataset,
-							pCalBChans, numPiers,
-							pdGainOverlap_t2,
-							&tMinCalPower,
-							gainBoundaries,
-							pdadcValues,
-							numXpdGain);
-			}
-
-			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
-				if (OLC_FOR_AR9280_20_LATER) {
-					REG_WRITE(ah,
-						AR_PHY_TPCRG5 + regChainOffset,
-						SM(0x6,
-						AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
-						SM_PD_GAIN(1) | SM_PD_GAIN(2) |
-						SM_PD_GAIN(3) | SM_PD_GAIN(4));
-				} else {
-					REG_WRITE(ah,
-						AR_PHY_TPCRG5 + regChainOffset,
-						SM(pdGainOverlap_t2,
-						AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
-						SM_PDGAIN_B(0, 1) |
-						SM_PDGAIN_B(1, 2) |
-						SM_PDGAIN_B(2, 3) |
-						SM_PDGAIN_B(3, 4));
-				}
-			}
-
-			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
-			for (j = 0; j < 32; j++) {
-				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
-					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
-					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
-					((pdadcValues[4 * j + 3] & 0xFF) << 24);
-				REG_WRITE(ah, regOffset, reg32);
-
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC (%d,%4x): %4.4x %8.8x\n",
-					i, regChainOffset, regOffset,
-					reg32);
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"PDADC: Chain %d | PDADC %3d "
-					"Value %3d | PDADC %3d Value %3d | "
-					"PDADC %3d Value %3d | PDADC %3d "
-					"Value %3d |\n",
-					i, 4 * j, pdadcValues[4 * j],
-					4 * j + 1, pdadcValues[4 * j + 1],
-					4 * j + 2, pdadcValues[4 * j + 2],
-					4 * j + 3,
-					pdadcValues[4 * j + 3]);
-
-				regOffset += 4;
-			}
-		}
-	}
-
-	*pTxPowerIndexOffset = 0;
-#undef SM_PD_GAIN
-#undef SM_PDGAIN_B
-}
-
-static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
-						  struct ath9k_channel *chan,
-						  int16_t *ratesArray,
-						  u16 cfgCtl,
-						  u16 AntennaReduction,
-						  u16 twiceMaxRegulatoryPower,
-						  u16 powerLimit)
-{
-#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
-#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
-
-	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-	static const u16 tpScaleReductionTable[5] =
-		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
-	int i;
-	int16_t twiceLargestAntenna;
-	struct cal_ctl_data *rep;
-	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
-		0, { 0, 0, 0, 0}
-	};
-	struct cal_target_power_leg targetPowerOfdmExt = {
-		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
-		0, { 0, 0, 0, 0 }
-	};
-	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
-		0, {0, 0, 0, 0}
-	};
-	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-	u16 ctlModesFor11a[] =
-		{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
-	u16 ctlModesFor11g[] =
-		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-		  CTL_2GHT40
-		};
-	u16 numCtlModes, *pCtlMode, ctlMode, freq;
-	struct chan_centers centers;
-	int tx_chainmask;
-	u16 twiceMinEdgePower;
-
-	tx_chainmask = ah->txchainmask;
-
-	ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-	twiceLargestAntenna = max(
-		pEepData->modalHeader
-			[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
-		pEepData->modalHeader
-			[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
-
-	twiceLargestAntenna = max((u8)twiceLargestAntenna,
-				  pEepData->modalHeader
-				  [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
-
-	twiceLargestAntenna = (int16_t)min(AntennaReduction -
-					   twiceLargestAntenna, 0);
-
-	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
-	if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
-		maxRegAllowedPower -=
-			(tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
-	}
-
-	scaledPower = min(powerLimit, maxRegAllowedPower);
-
-	switch (ar5416_get_ntxchains(tx_chainmask)) {
-	case 1:
-		break;
-	case 2:
-		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
-		break;
-	case 3:
-		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
-		break;
-	}
-
-	scaledPower = max((u16)0, scaledPower);
-
-	if (IS_CHAN_2GHZ(chan)) {
-		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
-			SUB_NUM_CTL_MODES_AT_2G_40;
-		pCtlMode = ctlModesFor11g;
-
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPowerCck,
-			AR5416_NUM_2G_CCK_TARGET_POWERS,
-			&targetPowerCck, 4, false);
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPower2G,
-			AR5416_NUM_2G_20_TARGET_POWERS,
-			&targetPowerOfdm, 4, false);
-		ath9k_hw_get_target_powers(ah, chan,
-			pEepData->calTargetPower2GHT20,
-			AR5416_NUM_2G_20_TARGET_POWERS,
-			&targetPowerHt20, 8, false);
-
-		if (IS_CHAN_HT40(chan)) {
-			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
-			ath9k_hw_get_target_powers(ah, chan,
-				pEepData->calTargetPower2GHT40,
-				AR5416_NUM_2G_40_TARGET_POWERS,
-				&targetPowerHt40, 8, true);
-			ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPowerCck,
-				AR5416_NUM_2G_CCK_TARGET_POWERS,
-				&targetPowerCckExt, 4, true);
-			ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPower2G,
-				AR5416_NUM_2G_20_TARGET_POWERS,
-				&targetPowerOfdmExt, 4, true);
-		}
-	} else {
-		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
-			SUB_NUM_CTL_MODES_AT_5G_40;
-		pCtlMode = ctlModesFor11a;
-
-		ath9k_hw_get_legacy_target_powers(ah, chan,
-			pEepData->calTargetPower5G,
-			AR5416_NUM_5G_20_TARGET_POWERS,
-			&targetPowerOfdm, 4, false);
-		ath9k_hw_get_target_powers(ah, chan,
-			pEepData->calTargetPower5GHT20,
-			AR5416_NUM_5G_20_TARGET_POWERS,
-			&targetPowerHt20, 8, false);
-
-		if (IS_CHAN_HT40(chan)) {
-			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
-			ath9k_hw_get_target_powers(ah, chan,
-				pEepData->calTargetPower5GHT40,
-				AR5416_NUM_5G_40_TARGET_POWERS,
-				&targetPowerHt40, 8, true);
-			ath9k_hw_get_legacy_target_powers(ah, chan,
-				pEepData->calTargetPower5G,
-				AR5416_NUM_5G_20_TARGET_POWERS,
-				&targetPowerOfdmExt, 4, true);
-		}
-	}
-
-	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
-			(pCtlMode[ctlMode] == CTL_2GHT40);
-		if (isHt40CtlMode)
-			freq = centers.synth_center;
-		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
-			freq = centers.ext_center;
-		else
-			freq = centers.ctl_center;
-
-		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
-		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
-			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
-			"EXT_ADDITIVE %d\n",
-			ctlMode, numCtlModes, isHt40CtlMode,
-			(pCtlMode[ctlMode] & EXT_ADDITIVE));
-
-		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
-			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-				"  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
-				"pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
-				"chan %d\n",
-				i, cfgCtl, pCtlMode[ctlMode],
-				pEepData->ctlIndex[i], chan->channel);
-
-			if ((((cfgCtl & ~CTL_MODE_M) |
-			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-			     pEepData->ctlIndex[i]) ||
-			    (((cfgCtl & ~CTL_MODE_M) |
-			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-			     ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
-				rep = &(pEepData->ctlData[i]);
-
-				twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
-				rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
-				IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
-
-				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-					"    MATCH-EE_IDX %d: ch %d is2 %d "
-					"2xMinEdge %d chainmask %d chains %d\n",
-					i, freq, IS_CHAN_2GHZ(chan),
-					twiceMinEdgePower, tx_chainmask,
-					ar5416_get_ntxchains
-					(tx_chainmask));
-				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
-					twiceMaxEdgePower = min(twiceMaxEdgePower,
-								twiceMinEdgePower);
-				} else {
-					twiceMaxEdgePower = twiceMinEdgePower;
-					break;
-				}
-			}
-		}
-
-		minCtlPower = min(twiceMaxEdgePower, scaledPower);
-
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"    SEL-Min ctlMode %d pCtlMode %d "
-			"2xMaxEdge %d sP %d minCtlPwr %d\n",
-			ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
-			scaledPower, minCtlPower);
-
-		switch (pCtlMode[ctlMode]) {
-		case CTL_11B:
-			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
-				targetPowerCck.tPow2x[i] =
-					min((u16)targetPowerCck.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_11A:
-		case CTL_11G:
-			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
-				targetPowerOfdm.tPow2x[i] =
-					min((u16)targetPowerOfdm.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_5GHT20:
-		case CTL_2GHT20:
-			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
-				targetPowerHt20.tPow2x[i] =
-					min((u16)targetPowerHt20.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		case CTL_11B_EXT:
-			targetPowerCckExt.tPow2x[0] = min((u16)
-					targetPowerCckExt.tPow2x[0],
-					minCtlPower);
-			break;
-		case CTL_11A_EXT:
-		case CTL_11G_EXT:
-			targetPowerOfdmExt.tPow2x[0] = min((u16)
-					targetPowerOfdmExt.tPow2x[0],
-					minCtlPower);
-			break;
-		case CTL_5GHT40:
-		case CTL_2GHT40:
-			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-				targetPowerHt40.tPow2x[i] =
-					min((u16)targetPowerHt40.tPow2x[i],
-					    minCtlPower);
-			}
-			break;
-		default:
-			break;
-		}
-	}
-
-	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
-		ratesArray[rate18mb] = ratesArray[rate24mb] =
-		targetPowerOfdm.tPow2x[0];
-	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
-	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
-	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
-	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
-	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
-		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
-	if (IS_CHAN_2GHZ(chan)) {
-		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
-		ratesArray[rate2s] = ratesArray[rate2l] =
-			targetPowerCck.tPow2x[1];
-		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
-			targetPowerCck.tPow2x[2];
-		;
-		ratesArray[rate11s] = ratesArray[rate11l] =
-			targetPowerCck.tPow2x[3];
-		;
-	}
-	if (IS_CHAN_HT40(chan)) {
-		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-			ratesArray[rateHt40_0 + i] =
-				targetPowerHt40.tPow2x[i];
-		}
-		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
-		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
-		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
-		if (IS_CHAN_2GHZ(chan)) {
-			ratesArray[rateExtCck] =
-				targetPowerCckExt.tPow2x[0];
-		}
-	}
-}
-
-static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
-				    struct ath9k_channel *chan,
-				    u16 cfgCtl,
-				    u8 twiceAntennaReduction,
-				    u8 twiceMaxRegulatoryPower,
-				    u8 powerLimit)
-{
-#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
-	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-	struct modal_eep_header *pModal =
-		&(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
-	int16_t ratesArray[Ar5416RateSize];
-	int16_t txPowerIndexOffset = 0;
-	u8 ht40PowerIncForPdadc = 2;
-	int i, cck_ofdm_delta = 0;
-
-	memset(ratesArray, 0, sizeof(ratesArray));
-
-	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-	    AR5416_EEP_MINOR_VER_2) {
-		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
-	}
-
-	ath9k_hw_set_def_power_per_rate_table(ah, chan,
-					       &ratesArray[0], cfgCtl,
-					       twiceAntennaReduction,
-					       twiceMaxRegulatoryPower,
-					       powerLimit);
-
-	ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
-
-	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
-		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
-			ratesArray[i] = AR5416_MAX_RATE_POWER;
-	}
-
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		for (i = 0; i < Ar5416RateSize; i++)
-			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
-	}
-
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
-		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
-		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
-		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
-		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
-		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
-		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
-		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
-		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
-
-	if (IS_CHAN_2GHZ(chan)) {
-		if (OLC_FOR_AR9280_20_LATER) {
-			cck_ofdm_delta = 2;
-			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-				ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
-				| ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
-				| ATH9K_POW_SM(ratesArray[rateXr], 8)
-				| ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
-			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-				ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
-				| ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
-				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
-				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
-		} else {
-			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-				ATH9K_POW_SM(ratesArray[rate2s], 24)
-				| ATH9K_POW_SM(ratesArray[rate2l], 16)
-				| ATH9K_POW_SM(ratesArray[rateXr], 8)
-				| ATH9K_POW_SM(ratesArray[rate1l], 0));
-			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-				ATH9K_POW_SM(ratesArray[rate11s], 24)
-				| ATH9K_POW_SM(ratesArray[rate11l], 16)
-				| ATH9K_POW_SM(ratesArray[rate5_5s], 8)
-				| ATH9K_POW_SM(ratesArray[rate5_5l], 0));
-		}
-	}
-
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
-		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
-	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
-		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
-		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
-
-	if (IS_CHAN_HT40(chan)) {
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
-			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
-				       ht40PowerIncForPdadc, 24)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
-					 ht40PowerIncForPdadc, 16)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
-					 ht40PowerIncForPdadc, 8)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
-					 ht40PowerIncForPdadc, 0));
-		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
-			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
-				       ht40PowerIncForPdadc, 24)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
-					 ht40PowerIncForPdadc, 16)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
-					 ht40PowerIncForPdadc, 8)
-			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
-					 ht40PowerIncForPdadc, 0));
-		if (OLC_FOR_AR9280_20_LATER) {
-			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-				| ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
-				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-				| ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
-		} else {
-			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-				| ATH9K_POW_SM(ratesArray[rateExtCck], 16)
-				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-				| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
-		}
-	}
-
-	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
-		  ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
-		  | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
-
-	i = rate6mb;
-
-	if (IS_CHAN_HT40(chan))
-		i = rateHt40_0;
-	else if (IS_CHAN_HT20(chan))
-		i = rateHt20_0;
-
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ah->regulatory.max_power_level =
-			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-	else
-		ah->regulatory.max_power_level = ratesArray[i];
-
-	switch(ar5416_get_ntxchains(ah->txchainmask)) {
-	case 1:
-		break;
-	case 2:
-		ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
-		break;
-	case 3:
-		ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
-		break;
-	default:
-		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-			"Invalid chainmask configuration\n");
-		break;
-	}
-}
-
-static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
-					  enum ieee80211_band freq_band)
-{
-	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-	struct modal_eep_header *pModal =
-		&(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
-	struct base_eep_header *pBase = &eep->baseEepHeader;
-	u8 num_ant_config;
-
-	num_ant_config = 1;
-
-	if (pBase->version >= 0x0E0D)
-		if (pModal->useAnt1)
-			num_ant_config += 1;
-
-	return num_ant_config;
-}
-
-static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
-					       struct ath9k_channel *chan)
-{
-	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-	struct modal_eep_header *pModal =
-		&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-	return pModal->antCtrlCommon & 0xFFFF;
-}
-
-static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
-{
-#define EEP_DEF_SPURCHAN \
-	(ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
-
-	u16 spur_val = AR_NO_SPUR;
-
-	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-		"Getting spur idx %d is2Ghz. %d val %x\n",
-		i, is2GHz, ah->config.spurchans[i][is2GHz]);
-
-	switch (ah->config.spurmode) {
-	case SPUR_DISABLE:
-		break;
-	case SPUR_ENABLE_IOCTL:
-		spur_val = ah->config.spurchans[i][is2GHz];
-		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-			"Getting spur val from new loc. %d\n", spur_val);
-		break;
-	case SPUR_ENABLE_EEPROM:
-		spur_val = EEP_DEF_SPURCHAN;
-		break;
-	}
-
-	return spur_val;
-
-#undef EEP_DEF_SPURCHAN
-}
-
-static struct eeprom_ops eep_def_ops = {
-	.check_eeprom		= ath9k_hw_def_check_eeprom,
-	.get_eeprom		= ath9k_hw_def_get_eeprom,
-	.fill_eeprom		= ath9k_hw_def_fill_eeprom,
-	.get_eeprom_ver		= ath9k_hw_def_get_eeprom_ver,
-	.get_eeprom_rev		= ath9k_hw_def_get_eeprom_rev,
-	.get_num_ant_config	= ath9k_hw_def_get_num_ant_config,
-	.get_eeprom_antenna_cfg	= ath9k_hw_def_get_eeprom_antenna_cfg,
-	.set_board_values	= ath9k_hw_def_set_board_values,
-	.set_addac		= ath9k_hw_def_set_addac,
-	.set_txpower		= ath9k_hw_def_set_txpower,
-	.get_spur_channel	= ath9k_hw_def_get_spur_channel
-};
-
-int ath9k_hw_eeprom_attach(struct ath_hw *ah)
+int ath9k_hw_eeprom_init(struct ath_hw *ah)
 {
 	int status;
 
-	if (AR_SREV_9285(ah)) {
+	if (AR_SREV_9287(ah)) {
+		ah->eep_map = EEP_MAP_AR9287;
+		ah->eep_ops = &eep_AR9287_ops;
+	} else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
 		ah->eep_map = EEP_MAP_4KBITS;
 		ah->eep_ops = &eep_4k_ops;
 	} else {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 67b8bd1..4fe33f7 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -100,6 +100,8 @@
 #define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
 #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
 				 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_10_OR_LATER(ah) && \
+				 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
 
 #define AR_EEPROM_RFSILENT_GPIO_SEL     0x001c
 #define AR_EEPROM_RFSILENT_GPIO_SEL_S   2
@@ -176,6 +178,57 @@
 
 #define AR9280_TX_GAIN_TABLE_SIZE 22
 
+#define AR9287_EEP_VER               0xE
+#define AR9287_EEP_VER_MINOR_MASK    0xFFF
+#define AR9287_EEP_MINOR_VER_1       0x1
+#define AR9287_EEP_MINOR_VER_2       0x2
+#define AR9287_EEP_MINOR_VER_3       0x3
+#define AR9287_EEP_MINOR_VER         AR9287_EEP_MINOR_VER_3
+#define AR9287_EEP_MINOR_VER_b       AR9287_EEP_MINOR_VER
+#define AR9287_EEP_NO_BACK_VER       AR9287_EEP_MINOR_VER_1
+
+#define AR9287_EEP_START_LOC            128
+#define AR9287_NUM_2G_CAL_PIERS         3
+#define AR9287_NUM_2G_CCK_TARGET_POWERS 3
+#define AR9287_NUM_2G_20_TARGET_POWERS  3
+#define AR9287_NUM_2G_40_TARGET_POWERS  3
+#define AR9287_NUM_CTLS              	12
+#define AR9287_NUM_BAND_EDGES        	4
+#define AR9287_NUM_PD_GAINS             4
+#define AR9287_PD_GAINS_IN_MASK         4
+#define AR9287_PD_GAIN_ICEPTS           1
+#define AR9287_EEPROM_MODAL_SPURS       5
+#define AR9287_MAX_RATE_POWER           63
+#define AR9287_NUM_PDADC_VALUES         128
+#define AR9287_NUM_RATES                16
+#define AR9287_BCHAN_UNUSED             0xFF
+#define AR9287_MAX_PWR_RANGE_IN_HALF_DB 64
+#define AR9287_OPFLAGS_11A              0x01
+#define AR9287_OPFLAGS_11G              0x02
+#define AR9287_OPFLAGS_2G_HT40          0x08
+#define AR9287_OPFLAGS_2G_HT20          0x20
+#define AR9287_OPFLAGS_5G_HT40          0x04
+#define AR9287_OPFLAGS_5G_HT20          0x10
+#define AR9287_EEPMISC_BIG_ENDIAN       0x01
+#define AR9287_EEPMISC_WOW              0x02
+#define AR9287_MAX_CHAINS               2
+#define AR9287_ANT_16S                  32
+#define AR9287_custdatasize             20
+
+#define AR9287_NUM_ANT_CHAIN_FIELDS     6
+#define AR9287_NUM_ANT_COMMON_FIELDS    4
+#define AR9287_SIZE_ANT_CHAIN_FIELD     2
+#define AR9287_SIZE_ANT_COMMON_FIELD    4
+#define AR9287_ANT_CHAIN_MASK           0x3
+#define AR9287_ANT_COMMON_MASK          0xf
+#define AR9287_CHAIN_0_IDX              0
+#define AR9287_CHAIN_1_IDX              1
+#define AR9287_DATA_SZ                  32
+
+#define AR9287_PWR_TABLE_OFFSET_DB  -5
+
+#define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
+
 enum eeprom_param {
 	EEP_NFTHRESH_5,
 	EEP_NFTHRESH_2,
@@ -199,7 +252,11 @@ enum eeprom_param {
 	EEP_OL_PWRCTRL,
 	EEP_RC_CHAIN_MASK,
 	EEP_DAC_HPWR_5G,
-	EEP_FRAC_N_5G
+	EEP_FRAC_N_5G,
+	EEP_DEV_TYPE,
+	EEP_TEMPSENSE_SLOPE,
+	EEP_TEMPSENSE_SLOPE_PAL_ON,
+	EEP_PWR_TABLE_OFFSET
 };
 
 enum ar5416_rates {
@@ -328,46 +385,123 @@ struct calDataPerFreqOpLoop {
 } __packed;
 
 struct modal_eep_4k_header {
-	u32  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
-	u32  antCtrlCommon;
-	u8   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
-	u8   switchSettling;
-	u8   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
-	u8   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
-	u8   adcDesiredSize;
-	u8   pgaDesiredSize;
-	u8   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
-	u8   txEndToXpaOff;
-	u8   txEndToRxOn;
-	u8   txFrameToXpaOn;
-	u8   thresh62;
-	u8   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
-	u8   xpdGain;
-	u8   xpd;
-	u8   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
-	u8   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
-	u8   pdGainOverlap;
-	u8   ob_01;
-	u8   db1_01;
-	u8   xpaBiasLvl;
-	u8   txFrameToDataStart;
-	u8   txFrameToPaOn;
-	u8   ht40PowerIncForPdadc;
-	u8   bswAtten[AR5416_EEP4K_MAX_CHAINS];
-	u8   bswMargin[AR5416_EEP4K_MAX_CHAINS];
-	u8   swSettleHt40;
-	u8   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
-	u8   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
-	u8   db2_01;
-	u8   version;
-	u16  ob_234;
-	u16  db1_234;
-	u16  db2_234;
-	u8   futureModal[4];
-
+	u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+	u32 antCtrlCommon;
+	u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+	u8 switchSettling;
+	u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+	u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+	u8 adcDesiredSize;
+	u8 pgaDesiredSize;
+	u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+	u8 txEndToXpaOff;
+	u8 txEndToRxOn;
+	u8 txFrameToXpaOn;
+	u8 thresh62;
+	u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+	u8 xpdGain;
+	u8 xpd;
+	u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+	u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+	u8 pdGainOverlap;
+#ifdef __BIG_ENDIAN_BITFIELD
+	u8 ob_1:4, ob_0:4;
+	u8 db1_1:4, db1_0:4;
+#else
+	u8 ob_0:4, ob_1:4;
+	u8 db1_0:4, db1_1:4;
+#endif
+	u8 xpaBiasLvl;
+	u8 txFrameToDataStart;
+	u8 txFrameToPaOn;
+	u8 ht40PowerIncForPdadc;
+	u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
+	u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
+	u8 swSettleHt40;
+	u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+	u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+#ifdef __BIG_ENDIAN_BITFIELD
+	u8 db2_1:4, db2_0:4;
+#else
+	u8 db2_0:4, db2_1:4;
+#endif
+	u8 version;
+#ifdef __BIG_ENDIAN_BITFIELD
+	u8 ob_3:4, ob_2:4;
+	u8 antdiv_ctl1:4, ob_4:4;
+	u8 db1_3:4, db1_2:4;
+	u8 antdiv_ctl2:4, db1_4:4;
+	u8 db2_2:4, db2_3:4;
+	u8 reserved:4, db2_4:4;
+#else
+	u8 ob_2:4, ob_3:4;
+	u8 ob_4:4, antdiv_ctl1:4;
+	u8 db1_2:4, db1_3:4;
+	u8 db1_4:4, antdiv_ctl2:4;
+	u8 db2_2:4, db2_3:4;
+	u8 db2_4:4, reserved:4;
+#endif
+	u8 futureModal[4];
 	struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
 } __packed;
 
+struct base_eep_ar9287_header {
+	u16 length;
+	u16 checksum;
+	u16 version;
+	u8 opCapFlags;
+	u8 eepMisc;
+	u16 regDmn[2];
+	u8 macAddr[6];
+	u8 rxMask;
+	u8 txMask;
+	u16 rfSilent;
+	u16 blueToothOptions;
+	u16 deviceCap;
+	u32 binBuildNumber;
+	u8 deviceType;
+	u8 openLoopPwrCntl;
+	int8_t pwrTableOffset;
+	int8_t tempSensSlope;
+	int8_t tempSensSlopePalOn;
+	u8 futureBase[29];
+} __packed;
+
+struct modal_eep_ar9287_header {
+	u32 antCtrlChain[AR9287_MAX_CHAINS];
+	u32 antCtrlCommon;
+	int8_t antennaGainCh[AR9287_MAX_CHAINS];
+	u8 switchSettling;
+	u8 txRxAttenCh[AR9287_MAX_CHAINS];
+	u8 rxTxMarginCh[AR9287_MAX_CHAINS];
+	int8_t adcDesiredSize;
+	u8 txEndToXpaOff;
+	u8 txEndToRxOn;
+	u8 txFrameToXpaOn;
+	u8 thresh62;
+	int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
+	u8 xpdGain;
+	u8 xpd;
+	int8_t iqCalICh[AR9287_MAX_CHAINS];
+	int8_t iqCalQCh[AR9287_MAX_CHAINS];
+	u8 pdGainOverlap;
+	u8 xpaBiasLvl;
+	u8 txFrameToDataStart;
+	u8 txFrameToPaOn;
+	u8 ht40PowerIncForPdadc;
+	u8 bswAtten[AR9287_MAX_CHAINS];
+	u8 bswMargin[AR9287_MAX_CHAINS];
+	u8 swSettleHt40;
+	u8 version;
+	u8 db1;
+	u8 db2;
+	u8 ob_cck;
+	u8 ob_psk;
+	u8 ob_qam;
+	u8 ob_pal_off;
+	u8 futureModal[30];
+	struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS];
+} __packed;
 
 struct cal_data_per_freq {
 	u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
@@ -402,6 +536,28 @@ struct cal_ctl_edges {
 } __packed;
 #endif
 
+struct cal_data_op_loop_ar9287 {
+	u8 pwrPdg[2][5];
+	u8 vpdPdg[2][5];
+	u8 pcdac[2][5];
+	u8 empty[2][5];
+} __packed;
+
+struct cal_data_per_freq_ar9287 {
+	u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+	u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
+} __packed;
+
+union cal_data_per_freq_ar9287_u {
+	struct cal_data_op_loop_ar9287 calDataOpen;
+	struct cal_data_per_freq_ar9287 calDataClose;
+} __packed;
+
+struct cal_ctl_data_ar9287 {
+	struct cal_ctl_edges
+	ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES];
+} __packed;
+
 struct cal_ctl_data {
 	struct cal_ctl_edges
 	ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
@@ -461,6 +617,26 @@ struct ar5416_eeprom_4k {
 	u8 padding;
 } __packed;
 
+struct ar9287_eeprom {
+	struct base_eep_ar9287_header baseEepHeader;
+	u8 custData[AR9287_DATA_SZ];
+	struct modal_eep_ar9287_header modalHeader;
+	u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
+	union cal_data_per_freq_ar9287_u
+	calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
+	struct cal_target_power_leg
+	calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
+	struct cal_target_power_leg
+	calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
+	struct cal_target_power_ht
+	calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
+	u8 ctlIndex[AR9287_NUM_CTLS];
+	struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS];
+	u8 padding;
+} __packed;
+
 enum reg_ext_bitmap {
 	REG_EXT_JAPAN_MIDBAND = 1,
 	REG_EXT_FCC_DFS_HT40 = 2,
@@ -480,6 +656,7 @@ struct ath9k_country_entry {
 enum ath9k_eep_map {
 	EEP_MAP_DEFAULT = 0x0,
 	EEP_MAP_4KBITS,
+	EEP_MAP_AR9287,
 	EEP_MAP_MAX
 };
 
@@ -500,10 +677,39 @@ struct eeprom_ops {
 	u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
 };
 
+void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
+			       u32 shift, u32 val);
+int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
+			     int16_t targetLeft,
+			     int16_t targetRight);
+bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
+				    u16 *indexL, u16 *indexR);
+bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data);
+void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+			     u8 *pVpdList, u16 numIntercepts,
+			     u8 *pRetVpdList);
+void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+				       struct ath9k_channel *chan,
+				       struct cal_target_power_leg *powInfo,
+				       u16 numChannels,
+				       struct cal_target_power_leg *pNewPower,
+				       u16 numRates, bool isExtTarget);
+void ath9k_hw_get_target_powers(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				struct cal_target_power_ht *powInfo,
+				u16 numChannels,
+				struct cal_target_power_ht *pNewPower,
+				u16 numRates, bool isHt40Target);
+u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
+				bool is2GHz, int num_band_edges);
+int ath9k_hw_eeprom_init(struct ath_hw *ah);
+
 #define ar5416_get_ntxchains(_txchainmask)			\
 	(((_txchainmask >> 2) & 1) +                            \
 	 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
 
-int ath9k_hw_eeprom_attach(struct ath_hw *ah);
+extern const struct eeprom_ops eep_def_ops;
+extern const struct eeprom_ops eep_4k_ops;
+extern const struct eeprom_ops eep_AR9287_ops;
 
 #endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
new file mode 100644
index 0000000..b8eca7b
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
+{
+	return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
+{
+	return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+	u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+	int addr, eep_start_loc = 0;
+
+	eep_start_loc = 64;
+
+	if (!ath9k_hw_use_flash(ah)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Reading from EEPROM, not flash\n");
+	}
+
+	for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			       "Unable to read eeprom region \n");
+			return false;
+		}
+		eep_data++;
+	}
+
+	return true;
+#undef SIZE_EEPROM_4K
+}
+
+static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
+{
+#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+	struct ar5416_eeprom_4k *eep =
+		(struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
+	u16 *eepdata, temp, magic, magic2;
+	u32 sum = 0, el;
+	bool need_swap = false;
+	int i, addr;
+
+
+	if (!ath9k_hw_use_flash(ah)) {
+		if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+					 &magic)) {
+			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+				"Reading Magic # failed\n");
+			return false;
+		}
+
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Read Magic = 0x%04X\n", magic);
+
+		if (magic != AR5416_EEPROM_MAGIC) {
+			magic2 = swab16(magic);
+
+			if (magic2 == AR5416_EEPROM_MAGIC) {
+				need_swap = true;
+				eepdata = (u16 *) (&ah->eeprom);
+
+				for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
+					temp = swab16(*eepdata);
+					*eepdata = temp;
+					eepdata++;
+				}
+			} else {
+				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+					"Invalid EEPROM Magic. "
+					"endianness mismatch.\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+		need_swap ? "True" : "False");
+
+	if (need_swap)
+		el = swab16(ah->eeprom.map4k.baseEepHeader.length);
+	else
+		el = ah->eeprom.map4k.baseEepHeader.length;
+
+	if (el > sizeof(struct ar5416_eeprom_4k))
+		el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
+	else
+		el = el / sizeof(u16);
+
+	eepdata = (u16 *)(&ah->eeprom);
+
+	for (i = 0; i < el; i++)
+		sum ^= *eepdata++;
+
+	if (need_swap) {
+		u32 integer;
+		u16 word;
+
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"EEPROM Endianness is not native.. Changing\n");
+
+		word = swab16(eep->baseEepHeader.length);
+		eep->baseEepHeader.length = word;
+
+		word = swab16(eep->baseEepHeader.checksum);
+		eep->baseEepHeader.checksum = word;
+
+		word = swab16(eep->baseEepHeader.version);
+		eep->baseEepHeader.version = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[0]);
+		eep->baseEepHeader.regDmn[0] = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[1]);
+		eep->baseEepHeader.regDmn[1] = word;
+
+		word = swab16(eep->baseEepHeader.rfSilent);
+		eep->baseEepHeader.rfSilent = word;
+
+		word = swab16(eep->baseEepHeader.blueToothOptions);
+		eep->baseEepHeader.blueToothOptions = word;
+
+		word = swab16(eep->baseEepHeader.deviceCap);
+		eep->baseEepHeader.deviceCap = word;
+
+		integer = swab32(eep->modalHeader.antCtrlCommon);
+		eep->modalHeader.antCtrlCommon = integer;
+
+		for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+			integer = swab32(eep->modalHeader.antCtrlChain[i]);
+			eep->modalHeader.antCtrlChain[i] = integer;
+		}
+
+		for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+			word = swab16(eep->modalHeader.spurChans[i].spurChan);
+			eep->modalHeader.spurChans[i].spurChan = word;
+		}
+	}
+
+	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+			sum, ah->eep_ops->get_eeprom_ver(ah));
+		return -EINVAL;
+	}
+
+	return 0;
+#undef EEPROM_4K_SIZE
+}
+
+static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
+				  enum eeprom_param param)
+{
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &eep->modalHeader;
+	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+
+	switch (param) {
+	case EEP_NFTHRESH_2:
+		return pModal->noiseFloorThreshCh[0];
+	case AR_EEPROM_MAC(0):
+		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+	case AR_EEPROM_MAC(1):
+		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+	case AR_EEPROM_MAC(2):
+		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+	case EEP_REG_0:
+		return pBase->regDmn[0];
+	case EEP_REG_1:
+		return pBase->regDmn[1];
+	case EEP_OP_CAP:
+		return pBase->deviceCap;
+	case EEP_OP_MODE:
+		return pBase->opCapFlags;
+	case EEP_RF_SILENT:
+		return pBase->rfSilent;
+	case EEP_OB_2:
+		return pModal->ob_0;
+	case EEP_DB_2:
+		return pModal->db1_1;
+	case EEP_MINOR_REV:
+		return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+	case EEP_TX_MASK:
+		return pBase->txMask;
+	case EEP_RX_MASK:
+		return pBase->rxMask;
+	case EEP_FRAC_N_5G:
+		return 0;
+	default:
+		return 0;
+	}
+}
+
+static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				struct cal_data_per_freq_4k *pRawDataSet,
+				u8 *bChans, u16 availPiers,
+				u16 tPdGainOverlap, int16_t *pMinCalPower,
+				u16 *pPdGainBoundaries, u8 *pPDADCValues,
+				u16 numXpdGains)
+{
+#define TMP_VAL_VPD_TABLE \
+	((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
+	int i, j, k;
+	int16_t ss;
+	u16 idxL = 0, idxR = 0, numPiers;
+	static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+	u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+	u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+	int16_t vpdStep;
+	int16_t tmpVal;
+	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+	bool match;
+	int16_t minDelta = 0;
+	struct chan_centers centers;
+#define PD_GAIN_BOUNDARY_DEFAULT 58;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
+		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+			break;
+	}
+
+	match = ath9k_hw_get_lower_upper_index(
+					(u8)FREQ2FBIN(centers.synth_center,
+					IS_CHAN_2GHZ(chan)), bChans, numPiers,
+					&idxL, &idxR);
+
+	if (match) {
+		for (i = 0; i < numXpdGains; i++) {
+			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+					pRawDataSet[idxL].pwrPdg[i],
+					pRawDataSet[idxL].vpdPdg[i],
+					AR5416_EEP4K_PD_GAIN_ICEPTS,
+					vpdTableI[i]);
+		}
+	} else {
+		for (i = 0; i < numXpdGains; i++) {
+			pVpdL = pRawDataSet[idxL].vpdPdg[i];
+			pPwrL = pRawDataSet[idxL].pwrPdg[i];
+			pVpdR = pRawDataSet[idxR].vpdPdg[i];
+			pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+			maxPwrT4[i] =
+				min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
+				    pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
+
+
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+						pPwrL, pVpdL,
+						AR5416_EEP4K_PD_GAIN_ICEPTS,
+						vpdTableL[i]);
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+						pPwrR, pVpdR,
+						AR5416_EEP4K_PD_GAIN_ICEPTS,
+						vpdTableR[i]);
+
+			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+				vpdTableI[i][j] =
+					(u8)(ath9k_hw_interpolate((u16)
+					     FREQ2FBIN(centers.
+						       synth_center,
+						       IS_CHAN_2GHZ
+						       (chan)),
+					     bChans[idxL], bChans[idxR],
+					     vpdTableL[i][j], vpdTableR[i][j]));
+			}
+		}
+	}
+
+	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+	k = 0;
+
+	for (i = 0; i < numXpdGains; i++) {
+		if (i == (numXpdGains - 1))
+			pPdGainBoundaries[i] =
+				(u16)(maxPwrT4[i] / 2);
+		else
+			pPdGainBoundaries[i] =
+				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+		pPdGainBoundaries[i] =
+			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+			minDelta = pPdGainBoundaries[0] - 23;
+			pPdGainBoundaries[0] = 23;
+		} else {
+			minDelta = 0;
+		}
+
+		if (i == 0) {
+			if (AR_SREV_9280_10_OR_LATER(ah))
+				ss = (int16_t)(0 - (minPwrT4[i] / 2));
+			else
+				ss = 0;
+		} else {
+			ss = (int16_t)((pPdGainBoundaries[i - 1] -
+					(minPwrT4[i] / 2)) -
+				       tPdGainOverlap + 1 + minDelta);
+		}
+		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+			ss++;
+		}
+
+		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+				(minPwrT4[i] / 2));
+		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+			tgtIndex : sizeCurrVpdTable;
+
+		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
+			pPDADCValues[k++] = vpdTableI[i][ss++];
+
+		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+				    vpdTableI[i][sizeCurrVpdTable - 2]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		if (tgtIndex >= maxIndex) {
+			while ((ss <= tgtIndex) &&
+			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+				tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
+				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+							 255 : tmpVal);
+				ss++;
+			}
+		}
+	}
+
+	while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
+		pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
+		i++;
+	}
+
+	while (k < AR5416_NUM_PDADC_VALUES) {
+		pPDADCValues[k] = pPDADCValues[k - 1];
+		k++;
+	}
+
+	return;
+#undef TMP_VAL_VPD_TABLE
+}
+
+static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
+				  struct ath9k_channel *chan,
+				  int16_t *pTxPowerIndexOffset)
+{
+	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+	struct cal_data_per_freq_4k *pRawDataset;
+	u8 *pCalBChans = NULL;
+	u16 pdGainOverlap_t2;
+	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+	u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
+	u16 numPiers, i, j;
+	int16_t tMinCalPower;
+	u16 numXpdGain, xpdMask;
+	u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
+	u32 reg32, regOffset, regChainOffset;
+
+	xpdMask = pEepData->modalHeader.xpdGain;
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		pdGainOverlap_t2 =
+			pEepData->modalHeader.pdGainOverlap;
+	} else {
+		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+	}
+
+	pCalBChans = pEepData->calFreqPier2G;
+	numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
+
+	numXpdGain = 0;
+
+	for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
+		if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
+			if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
+				break;
+			xpdGainValues[numXpdGain] =
+				(u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
+			numXpdGain++;
+		}
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+		      (numXpdGain - 1) & 0x3);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+		      xpdGainValues[0]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+		      xpdGainValues[1]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
+
+	for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+		if (AR_SREV_5416_20_OR_LATER(ah) &&
+		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+		    (i != 0)) {
+			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+		} else
+			regChainOffset = i * 0x1000;
+
+		if (pEepData->baseEepHeader.txMask & (1 << i)) {
+			pRawDataset = pEepData->calPierData2G[i];
+
+			ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
+					    pRawDataset, pCalBChans,
+					    numPiers, pdGainOverlap_t2,
+					    &tMinCalPower, gainBoundaries,
+					    pdadcValues, numXpdGain);
+
+			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+				REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
+					  SM(pdGainOverlap_t2,
+					     AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+					  | SM(gainBoundaries[0],
+					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+					  | SM(gainBoundaries[1],
+					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+					  | SM(gainBoundaries[2],
+					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+					  | SM(gainBoundaries[3],
+				       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+			}
+
+			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+			for (j = 0; j < 32; j++) {
+				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+					((pdadcValues[4 * j + 3] & 0xFF) << 24);
+				REG_WRITE(ah, regOffset, reg32);
+
+				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+					"PDADC (%d,%4x): %4.4x %8.8x\n",
+					i, regChainOffset, regOffset,
+					reg32);
+				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+					"PDADC: Chain %d | "
+					"PDADC %3d Value %3d | "
+					"PDADC %3d Value %3d | "
+					"PDADC %3d Value %3d | "
+					"PDADC %3d Value %3d |\n",
+					i, 4 * j, pdadcValues[4 * j],
+					4 * j + 1, pdadcValues[4 * j + 1],
+					4 * j + 2, pdadcValues[4 * j + 2],
+					4 * j + 3,
+					pdadcValues[4 * j + 3]);
+
+				regOffset += 4;
+			}
+		}
+	}
+
+	*pTxPowerIndexOffset = 0;
+}
+
+static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
+						 struct ath9k_channel *chan,
+						 int16_t *ratesArray,
+						 u16 cfgCtl,
+						 u16 AntennaReduction,
+						 u16 twiceMaxRegulatoryPower,
+						 u16 powerLimit)
+{
+#define CMP_TEST_GRP \
+	(((cfgCtl & ~CTL_MODE_M)| (pCtlMode[ctlMode] & CTL_MODE_M)) ==	\
+	 pEepData->ctlIndex[i])						\
+	|| (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
+	    ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
+
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	int i;
+	int16_t twiceLargestAntenna;
+	u16 twiceMinEdgePower;
+	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+	u16 numCtlModes, *pCtlMode, ctlMode, freq;
+	struct chan_centers centers;
+	struct cal_ctl_data_4k *rep;
+	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+	static const u16 tpScaleReductionTable[5] =
+		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+		0, { 0, 0, 0, 0}
+	};
+	struct cal_target_power_leg targetPowerOfdmExt = {
+		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+		0, { 0, 0, 0, 0 }
+	};
+	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+		0, {0, 0, 0, 0}
+	};
+	u16 ctlModesFor11g[] =
+		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+		  CTL_2GHT40
+		};
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
+	twiceLargestAntenna = (int16_t)min(AntennaReduction -
+					   twiceLargestAntenna, 0);
+
+	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+	if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+		maxRegAllowedPower -=
+			(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+	}
+
+	scaledPower = min(powerLimit, maxRegAllowedPower);
+	scaledPower = max((u16)0, scaledPower);
+
+	numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+	pCtlMode = ctlModesFor11g;
+
+	ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPowerCck,
+			AR5416_NUM_2G_CCK_TARGET_POWERS,
+			&targetPowerCck, 4, false);
+	ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPower2G,
+			AR5416_NUM_2G_20_TARGET_POWERS,
+			&targetPowerOfdm, 4, false);
+	ath9k_hw_get_target_powers(ah, chan,
+			pEepData->calTargetPower2GHT20,
+			AR5416_NUM_2G_20_TARGET_POWERS,
+			&targetPowerHt20, 8, false);
+
+	if (IS_CHAN_HT40(chan)) {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+		ath9k_hw_get_target_powers(ah, chan,
+				pEepData->calTargetPower2GHT40,
+				AR5416_NUM_2G_40_TARGET_POWERS,
+				&targetPowerHt40, 8, true);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPowerCck,
+				AR5416_NUM_2G_CCK_TARGET_POWERS,
+				&targetPowerCckExt, 4, true);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPower2G,
+				AR5416_NUM_2G_20_TARGET_POWERS,
+				&targetPowerOfdmExt, 4, true);
+	}
+
+	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+			(pCtlMode[ctlMode] == CTL_2GHT40);
+
+		if (isHt40CtlMode)
+			freq = centers.synth_center;
+		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+			freq = centers.ext_center;
+		else
+			freq = centers.ctl_center;
+
+		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
+			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+		for (i = 0; (i < AR5416_EEP4K_NUM_CTLS) &&
+			     pEepData->ctlIndex[i]; i++) {
+
+			if (CMP_TEST_GRP) {
+				rep = &(pEepData->ctlData[i]);
+
+				twiceMinEdgePower = ath9k_hw_get_max_edge_power(
+					freq,
+					rep->ctlEdges[
+					ar5416_get_ntxchains(ah->txchainmask) - 1],
+					IS_CHAN_2GHZ(chan),
+					AR5416_EEP4K_NUM_BAND_EDGES);
+
+				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+					twiceMaxEdgePower =
+						min(twiceMaxEdgePower,
+						    twiceMinEdgePower);
+				} else {
+					twiceMaxEdgePower = twiceMinEdgePower;
+					break;
+				}
+			}
+		}
+
+		minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+		switch (pCtlMode[ctlMode]) {
+		case CTL_11B:
+			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+				targetPowerCck.tPow2x[i] =
+					min((u16)targetPowerCck.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_11G:
+			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+				targetPowerOfdm.tPow2x[i] =
+					min((u16)targetPowerOfdm.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_2GHT20:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+				targetPowerHt20.tPow2x[i] =
+					min((u16)targetPowerHt20.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_11B_EXT:
+			targetPowerCckExt.tPow2x[0] =
+				min((u16)targetPowerCckExt.tPow2x[0],
+				    minCtlPower);
+			break;
+		case CTL_11G_EXT:
+			targetPowerOfdmExt.tPow2x[0] =
+				min((u16)targetPowerOfdmExt.tPow2x[0],
+				    minCtlPower);
+			break;
+		case CTL_2GHT40:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+				targetPowerHt40.tPow2x[i] =
+					min((u16)targetPowerHt40.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	ratesArray[rate6mb] =
+	ratesArray[rate9mb] =
+	ratesArray[rate12mb] =
+	ratesArray[rate18mb] =
+	ratesArray[rate24mb] =
+	targetPowerOfdm.tPow2x[0];
+
+	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+	ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+	ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
+	ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
+	ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
+
+	if (IS_CHAN_HT40(chan)) {
+		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+			ratesArray[rateHt40_0 + i] =
+				targetPowerHt40.tPow2x[i];
+		}
+		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+		ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
+	}
+
+#undef CMP_TEST_GRP
+}
+
+static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+				    struct ath9k_channel *chan,
+				    u16 cfgCtl,
+				    u8 twiceAntennaReduction,
+				    u8 twiceMaxRegulatoryPower,
+				    u8 powerLimit)
+{
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
+	int16_t ratesArray[Ar5416RateSize];
+	int16_t txPowerIndexOffset = 0;
+	u8 ht40PowerIncForPdadc = 2;
+	int i;
+
+	memset(ratesArray, 0, sizeof(ratesArray));
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+	}
+
+	ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+					     &ratesArray[0], cfgCtl,
+					     twiceAntennaReduction,
+					     twiceMaxRegulatoryPower,
+					     powerLimit);
+
+	ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
+		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+			ratesArray[i] = AR5416_MAX_RATE_POWER;
+	}
+
+
+	/* Update regulatory */
+
+	i = rate6mb;
+	if (IS_CHAN_HT40(chan))
+		i = rateHt40_0;
+	else if (IS_CHAN_HT20(chan))
+		i = rateHt20_0;
+
+	regulatory->max_power_level = ratesArray[i];
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		for (i = 0; i < Ar5416RateSize; i++)
+			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+	}
+
+	/* OFDM power per rate */
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+	/* CCK power per rate */
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+		  ATH9K_POW_SM(ratesArray[rate2s], 24)
+		  | ATH9K_POW_SM(ratesArray[rate2l], 16)
+		  | ATH9K_POW_SM(ratesArray[rateXr], 8)
+		  | ATH9K_POW_SM(ratesArray[rate1l], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+		  ATH9K_POW_SM(ratesArray[rate11s], 24)
+		  | ATH9K_POW_SM(ratesArray[rate11l], 16)
+		  | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+		  | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+
+	/* HT20 power per rate */
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+	/* HT40 power per rate */
+	if (IS_CHAN_HT40(chan)) {
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
+				       ht40PowerIncForPdadc, 24)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+					 ht40PowerIncForPdadc, 16)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+					 ht40PowerIncForPdadc, 8)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+					 ht40PowerIncForPdadc, 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
+				       ht40PowerIncForPdadc, 24)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+					 ht40PowerIncForPdadc, 16)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+					 ht40PowerIncForPdadc, 8)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+					 ht40PowerIncForPdadc, 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+			  ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+			  | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+			  | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+			  | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+	}
+}
+
+static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+				  struct ath9k_channel *chan)
+{
+	struct modal_eep_4k_header *pModal;
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	u8 biaslevel;
+
+	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+		return;
+
+	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+		return;
+
+	pModal = &eep->modalHeader;
+
+	if (pModal->xpaBiasLvl != 0xff) {
+		biaslevel = pModal->xpaBiasLvl;
+		INI_RA(&ah->iniAddac, 7, 1) =
+		  (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+	}
+}
+
+static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
+				 struct modal_eep_4k_header *pModal,
+				 struct ar5416_eeprom_4k *eep,
+				 u8 txRxAttenLocal)
+{
+	REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0,
+		  pModal->antCtrlChain[0]);
+
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0),
+		  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+		   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+		     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+		  SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+		  SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_3) {
+		txRxAttenLocal = pModal->txRxAttenCh[0];
+
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+			      pModal->xatten2Margin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
+
+		/* Set the block 1 value to block 0 value */
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+			      pModal->bswMargin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+			      pModal->xatten2Margin[0]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+			      pModal->xatten2Db[0]);
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
+		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
+		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
+		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+	REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
+		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+}
+
+/*
+ * Read EEPROM header info and program the device for correct operation
+ * given the channel value.
+ */
+static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
+					 struct ath9k_channel *chan)
+{
+	struct modal_eep_4k_header *pModal;
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	u8 txRxAttenLocal;
+	u8 ob[5], db1[5], db2[5];
+	u8 ant_div_control1, ant_div_control2;
+	u32 regVal;
+
+	pModal = &eep->modalHeader;
+	txRxAttenLocal = 23;
+
+	REG_WRITE(ah, AR_PHY_SWITCH_COM,
+		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+	/* Single chain for 4K EEPROM*/
+	ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
+
+	/* Initialize Ant Diversity settings from EEPROM */
+	if (pModal->version >= 3) {
+		ant_div_control1 = pModal->antdiv_ctl1;
+		ant_div_control2 = pModal->antdiv_ctl2;
+
+		regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+		regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
+
+		regVal |= SM(ant_div_control1,
+			     AR_PHY_9285_ANT_DIV_CTL);
+		regVal |= SM(ant_div_control2,
+			     AR_PHY_9285_ANT_DIV_ALT_LNACONF);
+		regVal |= SM((ant_div_control2 >> 2),
+			     AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
+		regVal |= SM((ant_div_control1 >> 1),
+			     AR_PHY_9285_ANT_DIV_ALT_GAINTB);
+		regVal |= SM((ant_div_control1 >> 2),
+			     AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
+
+
+		REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
+		regVal = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
+		regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
+		regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
+		regVal |= SM((ant_div_control1 >> 3),
+			     AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
+
+		REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
+		regVal = REG_READ(ah, AR_PHY_CCK_DETECT);
+	}
+
+	if (pModal->version >= 2) {
+		ob[0] = pModal->ob_0;
+		ob[1] = pModal->ob_1;
+		ob[2] = pModal->ob_2;
+		ob[3] = pModal->ob_3;
+		ob[4] = pModal->ob_4;
+
+		db1[0] = pModal->db1_0;
+		db1[1] = pModal->db1_1;
+		db1[2] = pModal->db1_2;
+		db1[3] = pModal->db1_3;
+		db1[4] = pModal->db1_4;
+
+		db2[0] = pModal->db2_0;
+		db2[1] = pModal->db2_1;
+		db2[2] = pModal->db2_2;
+		db2[3] = pModal->db2_3;
+		db2[4] = pModal->db2_4;
+	} else if (pModal->version == 1) {
+		ob[0] = pModal->ob_0;
+		ob[1] = ob[2] = ob[3] = ob[4] = pModal->ob_1;
+		db1[0] = pModal->db1_0;
+		db1[1] = db1[2] = db1[3] = db1[4] = pModal->db1_1;
+		db2[0] = pModal->db2_0;
+		db2[1] = db2[2] = db2[3] = db2[4] = pModal->db2_1;
+	} else {
+		int i;
+
+		for (i = 0; i < 5; i++) {
+			ob[i] = pModal->ob_0;
+			db1[i] = pModal->db1_0;
+			db2[i] = pModal->db1_0;
+		}
+	}
+
+	if (AR_SREV_9271(ah)) {
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9271_AN_RF2G3_OB_cck,
+					  AR9271_AN_RF2G3_OB_cck_S,
+					  ob[0]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9271_AN_RF2G3_OB_psk,
+					  AR9271_AN_RF2G3_OB_psk_S,
+					  ob[1]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9271_AN_RF2G3_OB_qam,
+					  AR9271_AN_RF2G3_OB_qam_S,
+					  ob[2]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9271_AN_RF2G3_DB_1,
+					  AR9271_AN_RF2G3_DB_1_S,
+					  db1[0]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9271_AN_RF2G4_DB_2,
+					  AR9271_AN_RF2G4_DB_2_S,
+					  db2[0]);
+	} else {
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_OB_0,
+					  AR9285_AN_RF2G3_OB_0_S,
+					  ob[0]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_OB_1,
+					  AR9285_AN_RF2G3_OB_1_S,
+					  ob[1]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_OB_2,
+					  AR9285_AN_RF2G3_OB_2_S,
+					  ob[2]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_OB_3,
+					  AR9285_AN_RF2G3_OB_3_S,
+					  ob[3]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_OB_4,
+					  AR9285_AN_RF2G3_OB_4_S,
+					  ob[4]);
+
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_DB1_0,
+					  AR9285_AN_RF2G3_DB1_0_S,
+					  db1[0]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_DB1_1,
+					  AR9285_AN_RF2G3_DB1_1_S,
+					  db1[1]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G3,
+					  AR9285_AN_RF2G3_DB1_2,
+					  AR9285_AN_RF2G3_DB1_2_S,
+					  db1[2]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9285_AN_RF2G4_DB1_3,
+					  AR9285_AN_RF2G4_DB1_3_S,
+					  db1[3]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9285_AN_RF2G4_DB1_4,
+					  AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9285_AN_RF2G4_DB2_0,
+					  AR9285_AN_RF2G4_DB2_0_S,
+					  db2[0]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9285_AN_RF2G4_DB2_1,
+					  AR9285_AN_RF2G4_DB2_1_S,
+					  db2[1]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9285_AN_RF2G4_DB2_2,
+					  AR9285_AN_RF2G4_DB2_2_S,
+					  db2[2]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9285_AN_RF2G4_DB2_3,
+					  AR9285_AN_RF2G4_DB2_3_S,
+					  db2[3]);
+		ath9k_hw_analog_shift_rmw(ah,
+					  AR9285_AN_RF2G4,
+					  AR9285_AN_RF2G4_DB2_4,
+					  AR9285_AN_RF2G4_DB2_4_S,
+					  db2[4]);
+	}
+
+
+	if (AR_SREV_9285_11(ah))
+		REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+		      pModal->switchSettling);
+	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+		      pModal->adcDesiredSize);
+
+	REG_WRITE(ah, AR_PHY_RF_CTL4,
+		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
+		  SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+		      pModal->txEndToRxOn);
+	REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+		      pModal->thresh62);
+	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
+		      pModal->thresh62);
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+						AR5416_EEP_MINOR_VER_2) {
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+			      pModal->txFrameToDataStart);
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+			      pModal->txFrameToPaOn);
+	}
+
+	if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+						AR5416_EEP_MINOR_VER_3) {
+		if (IS_CHAN_HT40(chan))
+			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+				      AR_PHY_SETTLING_SWITCH,
+				      pModal->swSettleHt40);
+	}
+}
+
+static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
+					      struct ath9k_channel *chan)
+{
+	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	struct modal_eep_4k_header *pModal = &eep->modalHeader;
+
+	return pModal->antCtrlCommon & 0xFFFF;
+}
+
+static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
+					 enum ieee80211_band freq_band)
+{
+	return 1;
+}
+
+static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_MAP4K_SPURCHAN \
+	(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
+
+	u16 spur_val = AR_NO_SPUR;
+
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+		"Getting spur idx %d is2Ghz. %d val %x\n",
+		i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+	switch (ah->config.spurmode) {
+	case SPUR_DISABLE:
+		break;
+	case SPUR_ENABLE_IOCTL:
+		spur_val = ah->config.spurchans[i][is2GHz];
+		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+			"Getting spur val from new loc. %d\n", spur_val);
+		break;
+	case SPUR_ENABLE_EEPROM:
+		spur_val = EEP_MAP4K_SPURCHAN;
+		break;
+	}
+
+	return spur_val;
+
+#undef EEP_MAP4K_SPURCHAN
+}
+
+const struct eeprom_ops eep_4k_ops = {
+	.check_eeprom		= ath9k_hw_4k_check_eeprom,
+	.get_eeprom		= ath9k_hw_4k_get_eeprom,
+	.fill_eeprom		= ath9k_hw_4k_fill_eeprom,
+	.get_eeprom_ver		= ath9k_hw_4k_get_eeprom_ver,
+	.get_eeprom_rev		= ath9k_hw_4k_get_eeprom_rev,
+	.get_num_ant_config	= ath9k_hw_4k_get_num_ant_config,
+	.get_eeprom_antenna_cfg	= ath9k_hw_4k_get_eeprom_antenna_cfg,
+	.set_board_values	= ath9k_hw_4k_set_board_values,
+	.set_addac		= ath9k_hw_4k_set_addac,
+	.set_txpower		= ath9k_hw_4k_set_txpower,
+	.get_spur_channel	= ath9k_hw_4k_get_spur_channel
+};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
new file mode 100644
index 0000000..c20c21a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -0,0 +1,1177 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
+{
+	return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF;
+}
+
+static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah)
+{
+	return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
+}
+
+static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
+{
+	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+	u16 *eep_data;
+	int addr, eep_start_loc = AR9287_EEP_START_LOC;
+	eep_data = (u16 *)eep;
+
+	if (!ath9k_hw_use_flash(ah)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Reading from EEPROM, not flash\n");
+	}
+
+	for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
+			addr++)	{
+		if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+			DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+				"Unable to read eeprom region \n");
+			return false;
+		}
+		eep_data++;
+	}
+	return true;
+}
+
+static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
+{
+	u32 sum = 0, el, integer;
+	u16 temp, word, magic, magic2, *eepdata;
+	int i, addr;
+	bool need_swap = false;
+	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+
+	if (!ath9k_hw_use_flash(ah)) {
+		if (!ath9k_hw_nvram_read
+		    (ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+				"Reading Magic # failed\n");
+			return false;
+		}
+
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+				"Read Magic = 0x%04X\n", magic);
+		if (magic != AR5416_EEPROM_MAGIC) {
+			magic2 = swab16(magic);
+
+			if (magic2 == AR5416_EEPROM_MAGIC) {
+				need_swap = true;
+				eepdata = (u16 *)(&ah->eeprom);
+
+				for (addr = 0;
+				     addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
+				     addr++) {
+					temp = swab16(*eepdata);
+					*eepdata = temp;
+					eepdata++;
+				}
+			} else {
+				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+					"Invalid EEPROM Magic. "
+					"endianness mismatch.\n");
+				return -EINVAL;
+			}
+		}
+	}
+	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ?
+		"True" : "False");
+
+	if (need_swap)
+		el = swab16(ah->eeprom.map9287.baseEepHeader.length);
+	else
+		el = ah->eeprom.map9287.baseEepHeader.length;
+
+	if (el > sizeof(struct ar9287_eeprom))
+		el = sizeof(struct ar9287_eeprom) / sizeof(u16);
+	else
+		el = el / sizeof(u16);
+
+	eepdata = (u16 *)(&ah->eeprom);
+	for (i = 0; i < el; i++)
+		sum ^= *eepdata++;
+
+	if (need_swap) {
+		word = swab16(eep->baseEepHeader.length);
+		eep->baseEepHeader.length = word;
+
+		word = swab16(eep->baseEepHeader.checksum);
+		eep->baseEepHeader.checksum = word;
+
+		word = swab16(eep->baseEepHeader.version);
+		eep->baseEepHeader.version = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[0]);
+		eep->baseEepHeader.regDmn[0] = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[1]);
+		eep->baseEepHeader.regDmn[1] = word;
+
+		word = swab16(eep->baseEepHeader.rfSilent);
+		eep->baseEepHeader.rfSilent = word;
+
+		word = swab16(eep->baseEepHeader.blueToothOptions);
+		eep->baseEepHeader.blueToothOptions = word;
+
+		word = swab16(eep->baseEepHeader.deviceCap);
+		eep->baseEepHeader.deviceCap = word;
+
+		integer = swab32(eep->modalHeader.antCtrlCommon);
+		eep->modalHeader.antCtrlCommon = integer;
+
+		for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+			integer = swab32(eep->modalHeader.antCtrlChain[i]);
+			eep->modalHeader.antCtrlChain[i] = integer;
+		}
+
+		for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) {
+			word = swab16(eep->modalHeader.spurChans[i].spurChan);
+			eep->modalHeader.spurChans[i].spurChan = word;
+		}
+	}
+
+	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
+	    || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+			 sum, ah->eep_ops->get_eeprom_ver(ah));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
+				      enum eeprom_param param)
+{
+	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+	struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
+	struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
+	u16 ver_minor;
+
+	ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK;
+	switch (param) {
+	case EEP_NFTHRESH_2:
+		return pModal->noiseFloorThreshCh[0];
+	case AR_EEPROM_MAC(0):
+		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+	case AR_EEPROM_MAC(1):
+		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+	case AR_EEPROM_MAC(2):
+		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+	case EEP_REG_0:
+		return pBase->regDmn[0];
+	case EEP_REG_1:
+		return pBase->regDmn[1];
+	case EEP_OP_CAP:
+		return pBase->deviceCap;
+	case EEP_OP_MODE:
+		return pBase->opCapFlags;
+	case EEP_RF_SILENT:
+		return pBase->rfSilent;
+	case EEP_MINOR_REV:
+		return ver_minor;
+	case EEP_TX_MASK:
+		return pBase->txMask;
+	case EEP_RX_MASK:
+		return pBase->rxMask;
+	case EEP_DEV_TYPE:
+		return pBase->deviceType;
+	case EEP_OL_PWRCTRL:
+		return pBase->openLoopPwrCntl;
+	case EEP_TEMPSENSE_SLOPE:
+		if (ver_minor >= AR9287_EEP_MINOR_VER_2)
+			return pBase->tempSensSlope;
+		else
+			return 0;
+	case EEP_TEMPSENSE_SLOPE_PAL_ON:
+		if (ver_minor >= AR9287_EEP_MINOR_VER_3)
+			return pBase->tempSensSlopePalOn;
+		else
+			return 0;
+	default:
+		return 0;
+	}
+}
+
+
+static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
+				   struct ath9k_channel *chan,
+				   struct cal_data_per_freq_ar9287 *pRawDataSet,
+				   u8 *bChans,  u16 availPiers,
+				   u16 tPdGainOverlap, int16_t *pMinCalPower,
+				   u16 *pPdGainBoundaries, u8 *pPDADCValues,
+				   u16 numXpdGains)
+{
+#define TMP_VAL_VPD_TABLE \
+	((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
+
+	int       i, j, k;
+	int16_t   ss;
+	u16  idxL = 0, idxR = 0, numPiers;
+	u8   *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+	u8   minPwrT4[AR9287_NUM_PD_GAINS];
+	u8   maxPwrT4[AR9287_NUM_PD_GAINS];
+	int16_t   vpdStep;
+	int16_t   tmpVal;
+	u16  sizeCurrVpdTable, maxIndex, tgtIndex;
+	bool    match;
+	int16_t  minDelta = 0;
+	struct chan_centers centers;
+	static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
+		if (bChans[numPiers] == AR9287_BCHAN_UNUSED)
+			break;
+	}
+
+	match = ath9k_hw_get_lower_upper_index(
+				   (u8)FREQ2FBIN(centers.synth_center,
+				    IS_CHAN_2GHZ(chan)), bChans, numPiers,
+				    &idxL, &idxR);
+
+	if (match) {
+		for (i = 0; i < numXpdGains; i++) {
+			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+					pRawDataSet[idxL].pwrPdg[i],
+					pRawDataSet[idxL].vpdPdg[i],
+					AR9287_PD_GAIN_ICEPTS, vpdTableI[i]);
+		}
+	} else {
+		for (i = 0; i < numXpdGains; i++) {
+			pVpdL = pRawDataSet[idxL].vpdPdg[i];
+			pPwrL = pRawDataSet[idxL].pwrPdg[i];
+			pVpdR = pRawDataSet[idxR].vpdPdg[i];
+			pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+			maxPwrT4[i] =
+				min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
+				    pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
+
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+					pPwrL, pVpdL,
+					AR9287_PD_GAIN_ICEPTS,
+					vpdTableL[i]);
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+					pPwrR, pVpdR,
+					AR9287_PD_GAIN_ICEPTS,
+					vpdTableR[i]);
+
+			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+				vpdTableI[i][j] =
+					(u8)(ath9k_hw_interpolate((u16)
+					FREQ2FBIN(centers. synth_center,
+					IS_CHAN_2GHZ(chan)),
+					bChans[idxL], bChans[idxR],
+					vpdTableL[i][j], vpdTableR[i][j]));
+			}
+		}
+	}
+	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+	k = 0;
+	for (i = 0; i < numXpdGains; i++) {
+		if (i == (numXpdGains - 1))
+			pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2);
+		else
+			pPdGainBoundaries[i] = (u16)((maxPwrT4[i] +
+						      minPwrT4[i+1]) / 4);
+
+		pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
+					    pPdGainBoundaries[i]);
+
+
+		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+			minDelta = pPdGainBoundaries[0] - 23;
+			pPdGainBoundaries[0] = 23;
+		} else
+			minDelta = 0;
+
+		if (i == 0) {
+			if (AR_SREV_9280_10_OR_LATER(ah))
+				ss = (int16_t)(0 - (minPwrT4[i] / 2));
+			else
+				ss = 0;
+		} else
+			ss = (int16_t)((pPdGainBoundaries[i-1] -
+				       (minPwrT4[i] / 2)) -
+				       tPdGainOverlap + 1 + minDelta);
+
+		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+		while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1)))	{
+			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+			ss++;
+		}
+
+		sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+		tgtIndex = (u8)(pPdGainBoundaries[i] +
+				tPdGainOverlap - (minPwrT4[i] / 2));
+		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+			    tgtIndex : sizeCurrVpdTable;
+
+		while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1)))
+			pPDADCValues[k++] = vpdTableI[i][ss++];
+
+		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+				    vpdTableI[i][sizeCurrVpdTable - 2]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+		if (tgtIndex > maxIndex) {
+			while ((ss <= tgtIndex) &&
+				(k < (AR9287_NUM_PDADC_VALUES - 1))) {
+				tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
+				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+							  255 : tmpVal);
+				ss++;
+			}
+		}
+	}
+
+	while (i < AR9287_PD_GAINS_IN_MASK) {
+		pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
+		i++;
+	}
+
+	while (k < AR9287_NUM_PDADC_VALUES) {
+		pPDADCValues[k] = pPDADCValues[k-1];
+		k++;
+	}
+
+#undef TMP_VAL_VPD_TABLE
+}
+
+static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
+			    struct ath9k_channel *chan,
+			    struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
+			    u8 *pCalChans,  u16 availPiers,
+			    int8_t *pPwr)
+{
+	u16  idxL = 0, idxR = 0, numPiers;
+	bool match;
+	struct chan_centers centers;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
+		if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED)
+			break;
+	}
+
+	match = ath9k_hw_get_lower_upper_index(
+			(u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+			pCalChans, numPiers,
+			&idxL, &idxR);
+
+	if (match) {
+		*pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0];
+	} else {
+		*pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
+			    (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+	}
+
+}
+
+static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
+					  int32_t txPower, u16 chain)
+{
+	u32 tmpVal;
+	u32 a;
+
+	tmpVal = REG_READ(ah, 0xa270);
+	tmpVal = tmpVal & 0xFCFFFFFF;
+	tmpVal = tmpVal | (0x3 << 24);
+	REG_WRITE(ah, 0xa270, tmpVal);
+
+	tmpVal = REG_READ(ah, 0xb270);
+	tmpVal = tmpVal & 0xFCFFFFFF;
+	tmpVal = tmpVal | (0x3 << 24);
+	REG_WRITE(ah, 0xb270, tmpVal);
+
+	if (chain == 0) {
+		tmpVal = REG_READ(ah, 0xa398);
+		tmpVal = tmpVal & 0xff00ffff;
+		a = (txPower)&0xff;
+		tmpVal = tmpVal | (a << 16);
+		REG_WRITE(ah, 0xa398, tmpVal);
+	}
+
+	if (chain == 1) {
+		tmpVal = REG_READ(ah, 0xb398);
+		tmpVal = tmpVal & 0xff00ffff;
+		a = (txPower)&0xff;
+		tmpVal = tmpVal | (a << 16);
+		REG_WRITE(ah, 0xb398, tmpVal);
+	}
+}
+
+static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
+						struct ath9k_channel *chan,
+						int16_t *pTxPowerIndexOffset)
+{
+	struct cal_data_per_freq_ar9287 *pRawDataset;
+	struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
+	u8  *pCalBChans = NULL;
+	u16 pdGainOverlap_t2;
+	u8  pdadcValues[AR9287_NUM_PDADC_VALUES];
+	u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK];
+	u16 numPiers = 0, i, j;
+	int16_t  tMinCalPower;
+	u16 numXpdGain, xpdMask;
+	u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
+	u32 reg32, regOffset, regChainOffset;
+	int16_t   modalIdx, diff = 0;
+	struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
+	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+	xpdMask = pEepData->modalHeader.xpdGain;
+	if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
+			AR9287_EEP_MINOR_VER_2)
+		pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
+	else
+		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+
+	if (IS_CHAN_2GHZ(chan)) {
+		pCalBChans = pEepData->calFreqPier2G;
+		numPiers = AR9287_NUM_2G_CAL_PIERS;
+		if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+			pRawDatasetOpenLoop =
+				(struct cal_data_op_loop_ar9287 *)
+				pEepData->calPierData2G[0];
+			ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
+		}
+	}
+
+	numXpdGain = 0;
+	for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) {
+		if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) {
+			if (numXpdGain >= AR9287_NUM_PD_GAINS)
+				break;
+			xpdGainValues[numXpdGain] =
+				(u16)(AR9287_PD_GAINS_IN_MASK-i);
+			numXpdGain++;
+		}
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+		      (numXpdGain - 1) & 0x3);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+		      xpdGainValues[0]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+		      xpdGainValues[1]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+		      xpdGainValues[2]);
+
+	for (i = 0; i < AR9287_MAX_CHAINS; i++)	{
+		regChainOffset = i * 0x1000;
+		if (pEepData->baseEepHeader.txMask & (1 << i)) {
+			pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *)
+					       pEepData->calPierData2G[i];
+			if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+				int8_t txPower;
+				ar9287_eeprom_get_tx_gain_index(ah, chan,
+							  pRawDatasetOpenLoop,
+							  pCalBChans, numPiers,
+							  &txPower);
+				ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i);
+			} else {
+				pRawDataset =
+					(struct cal_data_per_freq_ar9287 *)
+					pEepData->calPierData2G[i];
+				ath9k_hw_get_AR9287_gain_boundaries_pdadcs(
+						  ah, chan, pRawDataset,
+						  pCalBChans, numPiers,
+						  pdGainOverlap_t2,
+						  &tMinCalPower, gainBoundaries,
+						  pdadcValues, numXpdGain);
+			}
+
+			if (i == 0) {
+				if (!ath9k_hw_AR9287_get_eeprom(
+					    ah, EEP_OL_PWRCTRL)) {
+					REG_WRITE(ah, AR_PHY_TPCRG5 +
+					  regChainOffset,
+					  SM(pdGainOverlap_t2,
+					     AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+					  SM(gainBoundaries[0],
+					     AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+					  | SM(gainBoundaries[1],
+					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+					  | SM(gainBoundaries[2],
+					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+					  | SM(gainBoundaries[3],
+					       AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+				}
+			}
+
+			if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB !=
+				     pEepData->baseEepHeader.pwrTableOffset) {
+				diff = (u16)
+				       (pEepData->baseEepHeader.pwrTableOffset
+					- (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
+				diff *= 2;
+
+				for (j = 0;
+				     j < ((u16)AR9287_NUM_PDADC_VALUES-diff);
+				     j++)
+					pdadcValues[j] = pdadcValues[j+diff];
+
+				for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff);
+				     j < AR9287_NUM_PDADC_VALUES; j++)
+					pdadcValues[j] =
+					  pdadcValues[
+					  AR9287_NUM_PDADC_VALUES-diff];
+			}
+
+			if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+				regOffset = AR_PHY_BASE + (672 << 2) +
+							   regChainOffset;
+				for (j = 0; j < 32; j++) {
+					reg32 = ((pdadcValues[4*j + 0]
+						  & 0xFF) << 0)  |
+						((pdadcValues[4*j + 1]
+						  & 0xFF) << 8)  |
+						((pdadcValues[4*j + 2]
+						  & 0xFF) << 16) |
+						((pdadcValues[4*j + 3]
+						  & 0xFF) << 24) ;
+					REG_WRITE(ah, regOffset, reg32);
+
+					DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+						"PDADC (%d,%4x): %4.4x %8.8x\n",
+						i, regChainOffset, regOffset,
+						reg32);
+
+					DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+						"PDADC: Chain %d | "
+						"PDADC %3d Value %3d | "
+						"PDADC %3d Value %3d | "
+						"PDADC %3d Value %3d | "
+						"PDADC %3d Value %3d |\n",
+						i, 4 * j, pdadcValues[4 * j],
+						4 * j + 1,
+						pdadcValues[4 * j + 1],
+						4 * j + 2,
+						pdadcValues[4 * j + 2],
+						4 * j + 3,
+						pdadcValues[4 * j + 3]);
+
+					regOffset += 4;
+				}
+			}
+		}
+	}
+
+	*pTxPowerIndexOffset = 0;
+}
+
+static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
+		struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl,
+		u16 AntennaReduction, u16 twiceMaxRegulatoryPower,
+		u16 powerLimit)
+{
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	static const u16 tpScaleReductionTable[5] =
+		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+	int i;
+	int16_t  twiceLargestAntenna;
+	struct cal_ctl_data_ar9287 *rep;
+	struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
+				    targetPowerCck = {0, {0, 0, 0, 0} };
+	struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} },
+				    targetPowerCckExt = {0, {0, 0, 0, 0} };
+	struct cal_target_power_ht  targetPowerHt20,
+				    targetPowerHt40 = {0, {0, 0, 0, 0} };
+	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+	u16 ctlModesFor11g[] =
+		{CTL_11B, CTL_11G, CTL_2GHT20,
+		 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40};
+	u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq;
+	struct chan_centers centers;
+	int tx_chainmask;
+	u16 twiceMinEdgePower;
+	struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
+	tx_chainmask = ah->txchainmask;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
+				  pEepData->modalHeader.antennaGainCh[1]);
+
+	twiceLargestAntenna =  (int16_t)min((AntennaReduction) -
+					    twiceLargestAntenna, 0);
+
+	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+	if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
+		maxRegAllowedPower -=
+			(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+
+	scaledPower = min(powerLimit, maxRegAllowedPower);
+
+	switch (ar5416_get_ntxchains(tx_chainmask)) {
+	case 1:
+		break;
+	case 2:
+		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		break;
+	case 3:
+		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+		break;
+	}
+	scaledPower = max((u16)0, scaledPower);
+
+	if (IS_CHAN_2GHZ(chan))	{
+		numCtlModes =
+			ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+		pCtlMode = ctlModesFor11g;
+
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+						  pEepData->calTargetPowerCck,
+						  AR9287_NUM_2G_CCK_TARGET_POWERS,
+						  &targetPowerCck, 4, false);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+						  pEepData->calTargetPower2G,
+						  AR9287_NUM_2G_20_TARGET_POWERS,
+						  &targetPowerOfdm, 4, false);
+		ath9k_hw_get_target_powers(ah, chan,
+					   pEepData->calTargetPower2GHT20,
+					   AR9287_NUM_2G_20_TARGET_POWERS,
+					   &targetPowerHt20, 8, false);
+
+		if (IS_CHAN_HT40(chan))	{
+			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+			ath9k_hw_get_target_powers(ah, chan,
+						   pEepData->calTargetPower2GHT40,
+						   AR9287_NUM_2G_40_TARGET_POWERS,
+						   &targetPowerHt40, 8, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+						  pEepData->calTargetPowerCck,
+						  AR9287_NUM_2G_CCK_TARGET_POWERS,
+						  &targetPowerCckExt, 4, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+						  pEepData->calTargetPower2G,
+						  AR9287_NUM_2G_20_TARGET_POWERS,
+						  &targetPowerOfdmExt, 4, true);
+		}
+	}
+
+	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+				     (pCtlMode[ctlMode] == CTL_2GHT40);
+		if (isHt40CtlMode)
+			freq = centers.synth_center;
+		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+			freq = centers.ext_center;
+		else
+			freq = centers.ctl_center;
+
+		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
+			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+		for (i = 0; (i < AR9287_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+			if ((((cfgCtl & ~CTL_MODE_M) |
+			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			     pEepData->ctlIndex[i]) ||
+			    (((cfgCtl & ~CTL_MODE_M) |
+			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			     ((pEepData->ctlIndex[i] &
+			       CTL_MODE_M) | SD_NO_CTL))) {
+
+				rep = &(pEepData->ctlData[i]);
+				twiceMinEdgePower = ath9k_hw_get_max_edge_power(
+				    freq,
+				    rep->ctlEdges[ar5416_get_ntxchains(
+				    tx_chainmask) - 1],
+				    IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
+					twiceMaxEdgePower = min(
+							    twiceMaxEdgePower,
+							    twiceMinEdgePower);
+				else {
+					twiceMaxEdgePower = twiceMinEdgePower;
+					break;
+				}
+			}
+		}
+
+		minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+		switch (pCtlMode[ctlMode]) {
+		case CTL_11B:
+			for (i = 0;
+			     i < ARRAY_SIZE(targetPowerCck.tPow2x);
+			     i++) {
+				targetPowerCck.tPow2x[i] = (u8)min(
+					(u16)targetPowerCck.tPow2x[i],
+					minCtlPower);
+			}
+			break;
+		case CTL_11A:
+		case CTL_11G:
+			for (i = 0;
+			     i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
+			     i++) {
+				targetPowerOfdm.tPow2x[i] = (u8)min(
+					(u16)targetPowerOfdm.tPow2x[i],
+					minCtlPower);
+			}
+			break;
+		case CTL_5GHT20:
+		case CTL_2GHT20:
+			for (i = 0;
+			     i < ARRAY_SIZE(targetPowerHt20.tPow2x);
+			     i++) {
+				targetPowerHt20.tPow2x[i] = (u8)min(
+					(u16)targetPowerHt20.tPow2x[i],
+					minCtlPower);
+			}
+			break;
+		case CTL_11B_EXT:
+			targetPowerCckExt.tPow2x[0] = (u8)min(
+				    (u16)targetPowerCckExt.tPow2x[0],
+				    minCtlPower);
+			break;
+		case CTL_11A_EXT:
+		case CTL_11G_EXT:
+			targetPowerOfdmExt.tPow2x[0] = (u8)min(
+				    (u16)targetPowerOfdmExt.tPow2x[0],
+				    minCtlPower);
+			break;
+		case CTL_5GHT40:
+		case CTL_2GHT40:
+			for (i = 0;
+			     i < ARRAY_SIZE(targetPowerHt40.tPow2x);
+			     i++) {
+				targetPowerHt40.tPow2x[i] = (u8)min(
+					(u16)targetPowerHt40.tPow2x[i],
+					minCtlPower);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	ratesArray[rate6mb] =
+	ratesArray[rate9mb] =
+	ratesArray[rate12mb] =
+	ratesArray[rate18mb] =
+	ratesArray[rate24mb] =
+	targetPowerOfdm.tPow2x[0];
+
+	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+	if (IS_CHAN_2GHZ(chan))	{
+		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+		ratesArray[rate2s] = ratesArray[rate2l] =
+			targetPowerCck.tPow2x[1];
+		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+			targetPowerCck.tPow2x[2];
+		ratesArray[rate11s] = ratesArray[rate11l] =
+			targetPowerCck.tPow2x[3];
+	}
+	if (IS_CHAN_HT40(chan))	{
+		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++)
+			ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
+
+		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateDupCck]  = targetPowerHt40.tPow2x[0];
+		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+		if (IS_CHAN_2GHZ(chan))
+			ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
+	}
+
+#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
+#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
+}
+
+static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
+					struct ath9k_channel *chan, u16 cfgCtl,
+					u8 twiceAntennaReduction,
+					u8 twiceMaxRegulatoryPower,
+					u8 powerLimit)
+{
+#define INCREASE_MAXPOW_BY_TWO_CHAIN     6
+#define INCREASE_MAXPOW_BY_THREE_CHAIN   10
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
+	struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
+	int16_t ratesArray[Ar5416RateSize];
+	int16_t  txPowerIndexOffset = 0;
+	u8 ht40PowerIncForPdadc = 2;
+	int i;
+
+	memset(ratesArray, 0, sizeof(ratesArray));
+
+	if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
+	    AR9287_EEP_MINOR_VER_2)
+		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+
+	ath9k_hw_set_AR9287_power_per_rate_table(ah, chan,
+						 &ratesArray[0], cfgCtl,
+						 twiceAntennaReduction,
+						 twiceMaxRegulatoryPower,
+						 powerLimit);
+
+	ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+		ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+		if (ratesArray[i] > AR9287_MAX_RATE_POWER)
+			ratesArray[i] = AR9287_MAX_RATE_POWER;
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		for (i = 0; i < Ar5416RateSize; i++)
+			ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+	if (IS_CHAN_2GHZ(chan))	{
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+			  ATH9K_POW_SM(ratesArray[rate2s], 24)
+			  | ATH9K_POW_SM(ratesArray[rate2l], 16)
+			  | ATH9K_POW_SM(ratesArray[rateXr], 8)
+			  | ATH9K_POW_SM(ratesArray[rate1l], 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+			  ATH9K_POW_SM(ratesArray[rate11s], 24)
+			  | ATH9K_POW_SM(ratesArray[rate11l], 16)
+			  | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+			  | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+	if (IS_CHAN_HT40(chan))	{
+		if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+				  ATH9K_POW_SM(ratesArray[rateHt40_3], 24)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_2], 16)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_1], 8)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_0], 0));
+
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+				  ATH9K_POW_SM(ratesArray[rateHt40_7], 24)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_6], 16)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_5], 8)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_4], 0));
+		} else {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+				  ATH9K_POW_SM(ratesArray[rateHt40_3] +
+					       ht40PowerIncForPdadc, 24)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+						 ht40PowerIncForPdadc, 16)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+						 ht40PowerIncForPdadc, 8)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+						 ht40PowerIncForPdadc, 0));
+
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+				  ATH9K_POW_SM(ratesArray[rateHt40_7] +
+					       ht40PowerIncForPdadc, 24)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+						 ht40PowerIncForPdadc, 16)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+						 ht40PowerIncForPdadc, 8)
+				  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+						 ht40PowerIncForPdadc, 0));
+		}
+
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+			  ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+			  | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+			  | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+			  | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+	}
+
+	if (IS_CHAN_2GHZ(chan))
+		i = rate1l;
+	else
+		i = rate6mb;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		regulatory->max_power_level =
+			ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
+	else
+		regulatory->max_power_level = ratesArray[i];
+
+	switch (ar5416_get_ntxchains(ah->txchainmask)) {
+	case 1:
+		break;
+	case 2:
+		regulatory->max_power_level +=
+			INCREASE_MAXPOW_BY_TWO_CHAIN;
+		break;
+	case 3:
+		regulatory->max_power_level +=
+			INCREASE_MAXPOW_BY_THREE_CHAIN;
+		break;
+	default:
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Invalid chainmask configuration\n");
+		break;
+	}
+}
+
+static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah,
+				      struct ath9k_channel *chan)
+{
+}
+
+static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah,
+					     struct ath9k_channel *chan)
+{
+	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+	struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
+	u16 antWrites[AR9287_ANT_16S];
+	u32 regChainOffset;
+	u8 txRxAttenLocal;
+	int i, j, offset_num;
+
+	pModal = &eep->modalHeader;
+
+	antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF);
+	antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF);
+	antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF);
+	antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF);
+	antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF);
+	antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF);
+	antWrites[6] = (u16)((pModal->antCtrlCommon >> 4)  & 0xF);
+	antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF);
+
+	offset_num = 8;
+
+	for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
+		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf);
+		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3);
+		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3);
+		antWrites[j++] = 0;
+		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3);
+		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3);
+		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3);
+		antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
+	}
+
+	REG_WRITE(ah, AR_PHY_SWITCH_COM,
+		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+	for (i = 0; i < AR9287_MAX_CHAINS; i++)	{
+		regChainOffset = i * 0x1000;
+
+		REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+			  pModal->antCtrlChain[i]);
+
+		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+			  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset)
+			   & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+			       AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+			  SM(pModal->iqCalICh[i],
+			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+			  SM(pModal->iqCalQCh[i],
+			     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+		txRxAttenLocal = pModal->txRxAttenCh[i];
+
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+			      pModal->bswMargin[i]);
+		REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+			      pModal->bswAtten[i]);
+		REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+			      AR9280_PHY_RXGAIN_TXRX_ATTEN,
+			      txRxAttenLocal);
+		REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+			      AR9280_PHY_RXGAIN_TXRX_MARGIN,
+			      pModal->rxTxMarginCh[i]);
+	}
+
+
+	if (IS_CHAN_HT40(chan))
+		REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+			      AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
+	else
+		REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+			      AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
+
+	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+		      AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
+
+	REG_WRITE(ah, AR_PHY_RF_CTL4,
+		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+		  | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+		  | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+		  | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3,
+		      AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
+
+	REG_RMW_FIELD(ah, AR_PHY_CCA,
+		      AR9280_PHY_CCA_THRESH62, pModal->thresh62);
+	REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+		      AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
+
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1,
+				  AR9287_AN_RF2G3_DB1_S, pModal->db1);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2,
+				  AR9287_AN_RF2G3_DB2_S, pModal->db2);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
+				  AR9287_AN_RF2G3_OB_CCK,
+				  AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
+				  AR9287_AN_RF2G3_OB_PSK,
+				  AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
+				  AR9287_AN_RF2G3_OB_QAM,
+				  AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
+				  AR9287_AN_RF2G3_OB_PAL_OFF,
+				  AR9287_AN_RF2G3_OB_PAL_OFF_S,
+				  pModal->ob_pal_off);
+
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
+				  AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S,
+				  pModal->db1);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2,
+				  AR9287_AN_RF2G3_DB2_S, pModal->db2);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
+				  AR9287_AN_RF2G3_OB_CCK,
+				  AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
+				  AR9287_AN_RF2G3_OB_PSK,
+				  AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
+				  AR9287_AN_RF2G3_OB_QAM,
+				  AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
+				  AR9287_AN_RF2G3_OB_PAL_OFF,
+				  AR9287_AN_RF2G3_OB_PAL_OFF_S,
+				  pModal->ob_pal_off);
+
+	REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+		      AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart);
+	REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+		      AR_PHY_TX_END_PA_ON, pModal->txFrameToPaOn);
+
+	ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TOP2,
+				  AR9287_AN_TOP2_XPABIAS_LVL,
+				  AR9287_AN_TOP2_XPABIAS_LVL_S,
+				  pModal->xpaBiasLvl);
+}
+
+static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah,
+					     enum ieee80211_band freq_band)
+{
+	return 1;
+}
+
+static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
+						  struct ath9k_channel *chan)
+{
+	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
+	struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
+
+	return pModal->antCtrlCommon & 0xFFFF;
+}
+
+static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
+					    u16 i, bool is2GHz)
+{
+#define EEP_MAP9287_SPURCHAN \
+	(ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
+	u16 spur_val = AR_NO_SPUR;
+
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+		"Getting spur idx %d is2Ghz. %d val %x\n",
+		i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+	switch (ah->config.spurmode) {
+	case SPUR_DISABLE:
+		break;
+	case SPUR_ENABLE_IOCTL:
+		spur_val = ah->config.spurchans[i][is2GHz];
+		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+		       "Getting spur val from new loc. %d\n", spur_val);
+		break;
+	case SPUR_ENABLE_EEPROM:
+		spur_val = EEP_MAP9287_SPURCHAN;
+		break;
+	}
+
+	return spur_val;
+
+#undef EEP_MAP9287_SPURCHAN
+}
+
+const struct eeprom_ops eep_AR9287_ops = {
+	.check_eeprom		= ath9k_hw_AR9287_check_eeprom,
+	.get_eeprom		= ath9k_hw_AR9287_get_eeprom,
+	.fill_eeprom		= ath9k_hw_AR9287_fill_eeprom,
+	.get_eeprom_ver		= ath9k_hw_AR9287_get_eeprom_ver,
+	.get_eeprom_rev		= ath9k_hw_AR9287_get_eeprom_rev,
+	.get_num_ant_config	= ath9k_hw_AR9287_get_num_ant_config,
+	.get_eeprom_antenna_cfg	= ath9k_hw_AR9287_get_eeprom_antenna_cfg,
+	.set_board_values	= ath9k_hw_AR9287_set_board_values,
+	.set_addac		= ath9k_hw_AR9287_set_addac,
+	.set_txpower		= ath9k_hw_AR9287_set_txpower,
+	.get_spur_channel	= ath9k_hw_AR9287_get_spur_channel
+};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
new file mode 100644
index 0000000..ae7fb5d
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -0,0 +1,1387 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+
+static void ath9k_get_txgain_index(struct ath_hw *ah,
+		struct ath9k_channel *chan,
+		struct calDataPerFreqOpLoop *rawDatasetOpLoop,
+		u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
+{
+	u8 pcdac, i = 0;
+	u16 idxL = 0, idxR = 0, numPiers;
+	bool match;
+	struct chan_centers centers;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	for (numPiers = 0; numPiers < availPiers; numPiers++)
+		if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
+			break;
+
+	match = ath9k_hw_get_lower_upper_index(
+			(u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+			calChans, numPiers, &idxL, &idxR);
+	if (match) {
+		pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
+		*pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
+	} else {
+		pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
+		*pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
+				rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+	}
+
+	while (pcdac > ah->originalGain[i] &&
+			i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
+		i++;
+
+	*pcdacIdx = i;
+	return;
+}
+
+static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
+				u32 initTxGain,
+				int txPower,
+				u8 *pPDADCValues)
+{
+	u32 i;
+	u32 offset;
+
+	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
+			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
+			AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+
+	REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
+			AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
+
+	offset = txPower;
+	for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
+		if (i < offset)
+			pPDADCValues[i] = 0x0;
+		else
+			pPDADCValues[i] = 0xFF;
+}
+
+static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
+{
+	return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
+{
+	return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+	u16 *eep_data = (u16 *)&ah->eeprom.def;
+	int addr, ar5416_eep_start_loc = 0x100;
+
+	for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+		if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+					 eep_data)) {
+			DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+				"Unable to read eeprom region\n");
+			return false;
+		}
+		eep_data++;
+	}
+	return true;
+#undef SIZE_EEPROM_DEF
+}
+
+static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
+{
+	struct ar5416_eeprom_def *eep =
+		(struct ar5416_eeprom_def *) &ah->eeprom.def;
+	u16 *eepdata, temp, magic, magic2;
+	u32 sum = 0, el;
+	bool need_swap = false;
+	int i, addr, size;
+
+	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
+		return false;
+	}
+
+	if (!ath9k_hw_use_flash(ah)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Read Magic = 0x%04X\n", magic);
+
+		if (magic != AR5416_EEPROM_MAGIC) {
+			magic2 = swab16(magic);
+
+			if (magic2 == AR5416_EEPROM_MAGIC) {
+				size = sizeof(struct ar5416_eeprom_def);
+				need_swap = true;
+				eepdata = (u16 *) (&ah->eeprom);
+
+				for (addr = 0; addr < size / sizeof(u16); addr++) {
+					temp = swab16(*eepdata);
+					*eepdata = temp;
+					eepdata++;
+				}
+			} else {
+				DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+					"Invalid EEPROM Magic. "
+					"Endianness mismatch.\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+		need_swap ? "True" : "False");
+
+	if (need_swap)
+		el = swab16(ah->eeprom.def.baseEepHeader.length);
+	else
+		el = ah->eeprom.def.baseEepHeader.length;
+
+	if (el > sizeof(struct ar5416_eeprom_def))
+		el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
+	else
+		el = el / sizeof(u16);
+
+	eepdata = (u16 *)(&ah->eeprom);
+
+	for (i = 0; i < el; i++)
+		sum ^= *eepdata++;
+
+	if (need_swap) {
+		u32 integer, j;
+		u16 word;
+
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"EEPROM Endianness is not native.. Changing.\n");
+
+		word = swab16(eep->baseEepHeader.length);
+		eep->baseEepHeader.length = word;
+
+		word = swab16(eep->baseEepHeader.checksum);
+		eep->baseEepHeader.checksum = word;
+
+		word = swab16(eep->baseEepHeader.version);
+		eep->baseEepHeader.version = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[0]);
+		eep->baseEepHeader.regDmn[0] = word;
+
+		word = swab16(eep->baseEepHeader.regDmn[1]);
+		eep->baseEepHeader.regDmn[1] = word;
+
+		word = swab16(eep->baseEepHeader.rfSilent);
+		eep->baseEepHeader.rfSilent = word;
+
+		word = swab16(eep->baseEepHeader.blueToothOptions);
+		eep->baseEepHeader.blueToothOptions = word;
+
+		word = swab16(eep->baseEepHeader.deviceCap);
+		eep->baseEepHeader.deviceCap = word;
+
+		for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+			struct modal_eep_header *pModal =
+				&eep->modalHeader[j];
+			integer = swab32(pModal->antCtrlCommon);
+			pModal->antCtrlCommon = integer;
+
+			for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+				integer = swab32(pModal->antCtrlChain[i]);
+				pModal->antCtrlChain[i] = integer;
+			}
+
+			for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+				word = swab16(pModal->spurChans[i].spurChan);
+				pModal->spurChans[i].spurChan = word;
+			}
+		}
+	}
+
+	if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+	    ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+			"Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+			sum, ah->eep_ops->get_eeprom_ver(ah));
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
+				   enum eeprom_param param)
+{
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	struct modal_eep_header *pModal = eep->modalHeader;
+	struct base_eep_header *pBase = &eep->baseEepHeader;
+
+	switch (param) {
+	case EEP_NFTHRESH_5:
+		return pModal[0].noiseFloorThreshCh[0];
+	case EEP_NFTHRESH_2:
+		return pModal[1].noiseFloorThreshCh[0];
+	case AR_EEPROM_MAC(0):
+		return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+	case AR_EEPROM_MAC(1):
+		return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+	case AR_EEPROM_MAC(2):
+		return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+	case EEP_REG_0:
+		return pBase->regDmn[0];
+	case EEP_REG_1:
+		return pBase->regDmn[1];
+	case EEP_OP_CAP:
+		return pBase->deviceCap;
+	case EEP_OP_MODE:
+		return pBase->opCapFlags;
+	case EEP_RF_SILENT:
+		return pBase->rfSilent;
+	case EEP_OB_5:
+		return pModal[0].ob;
+	case EEP_DB_5:
+		return pModal[0].db;
+	case EEP_OB_2:
+		return pModal[1].ob;
+	case EEP_DB_2:
+		return pModal[1].db;
+	case EEP_MINOR_REV:
+		return AR5416_VER_MASK;
+	case EEP_TX_MASK:
+		return pBase->txMask;
+	case EEP_RX_MASK:
+		return pBase->rxMask;
+	case EEP_RXGAIN_TYPE:
+		return pBase->rxGainType;
+	case EEP_TXGAIN_TYPE:
+		return pBase->txGainType;
+	case EEP_OL_PWRCTRL:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+			return pBase->openLoopPwrCntl ? true : false;
+		else
+			return false;
+	case EEP_RC_CHAIN_MASK:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+			return pBase->rcChainMask;
+		else
+			return 0;
+	case EEP_DAC_HPWR_5G:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+			return pBase->dacHiPwrMode_5G;
+		else
+			return 0;
+	case EEP_FRAC_N_5G:
+		if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+			return pBase->frac_n_5g;
+		else
+			return 0;
+	default:
+		return 0;
+	}
+}
+
+static void ath9k_hw_def_set_gain(struct ath_hw *ah,
+				  struct modal_eep_header *pModal,
+				  struct ar5416_eeprom_def *eep,
+				  u8 txRxAttenLocal, int regChainOffset, int i)
+{
+	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+		txRxAttenLocal = pModal->txRxAttenCh[i];
+
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+			      pModal->bswMargin[i]);
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+			      pModal->bswAtten[i]);
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+			      pModal->xatten2Margin[i]);
+			REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			      AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+			      pModal->xatten2Db[i]);
+		} else {
+			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+			   ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
+			  | SM(pModal-> bswMargin[i],
+			       AR_PHY_GAIN_2GHZ_BSW_MARGIN));
+			REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+			   ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
+			  | SM(pModal->bswAtten[i],
+			       AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+		}
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		REG_RMW_FIELD(ah,
+		      AR_PHY_RXGAIN + regChainOffset,
+		      AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+		REG_RMW_FIELD(ah,
+		      AR_PHY_RXGAIN + regChainOffset,
+		      AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
+	} else {
+		REG_WRITE(ah,
+			  AR_PHY_RXGAIN + regChainOffset,
+			  (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
+			   ~AR_PHY_RXGAIN_TXRX_ATTEN)
+			  | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
+		REG_WRITE(ah,
+			  AR_PHY_GAIN_2GHZ + regChainOffset,
+			  (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+			   ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
+			  SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+	}
+}
+
+static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
+					  struct ath9k_channel *chan)
+{
+	struct modal_eep_header *pModal;
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	int i, regChainOffset;
+	u8 txRxAttenLocal;
+
+	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+	txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+
+	REG_WRITE(ah, AR_PHY_SWITCH_COM,
+		  ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		if (AR_SREV_9280(ah)) {
+			if (i >= 2)
+				break;
+		}
+
+		if (AR_SREV_5416_20_OR_LATER(ah) &&
+		    (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
+			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+		else
+			regChainOffset = i * 0x1000;
+
+		REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+			  pModal->antCtrlChain[i]);
+
+		REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+			  (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+			   ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+			  SM(pModal->iqCalICh[i],
+			     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+			  SM(pModal->iqCalQCh[i],
+			     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+		if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
+			ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
+					      regChainOffset, i);
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		if (IS_CHAN_2GHZ(chan)) {
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+						  AR_AN_RF2G1_CH0_OB,
+						  AR_AN_RF2G1_CH0_OB_S,
+						  pModal->ob);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+						  AR_AN_RF2G1_CH0_DB,
+						  AR_AN_RF2G1_CH0_DB_S,
+						  pModal->db);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+						  AR_AN_RF2G1_CH1_OB,
+						  AR_AN_RF2G1_CH1_OB_S,
+						  pModal->ob_ch1);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+						  AR_AN_RF2G1_CH1_DB,
+						  AR_AN_RF2G1_CH1_DB_S,
+						  pModal->db_ch1);
+		} else {
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+						  AR_AN_RF5G1_CH0_OB5,
+						  AR_AN_RF5G1_CH0_OB5_S,
+						  pModal->ob);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+						  AR_AN_RF5G1_CH0_DB5,
+						  AR_AN_RF5G1_CH0_DB5_S,
+						  pModal->db);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+						  AR_AN_RF5G1_CH1_OB5,
+						  AR_AN_RF5G1_CH1_OB5_S,
+						  pModal->ob_ch1);
+			ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+						  AR_AN_RF5G1_CH1_DB5,
+						  AR_AN_RF5G1_CH1_DB5_S,
+						  pModal->db_ch1);
+		}
+		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+					  AR_AN_TOP2_XPABIAS_LVL,
+					  AR_AN_TOP2_XPABIAS_LVL_S,
+					  pModal->xpaBiasLvl);
+		ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+					  AR_AN_TOP2_LOCALBIAS,
+					  AR_AN_TOP2_LOCALBIAS_S,
+					  pModal->local_bias);
+		REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
+			      pModal->force_xpaon);
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+		      pModal->switchSettling);
+	REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+		      pModal->adcDesiredSize);
+
+	if (!AR_SREV_9280_10_OR_LATER(ah))
+		REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+			      AR_PHY_DESIRED_SZ_PGA,
+			      pModal->pgaDesiredSize);
+
+	REG_WRITE(ah, AR_PHY_RF_CTL4,
+		  SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+		  | SM(pModal->txEndToXpaOff,
+		       AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+		  | SM(pModal->txFrameToXpaOn,
+		       AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+		  | SM(pModal->txFrameToXpaOn,
+		       AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+	REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+		      pModal->txEndToRxOn);
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+			      pModal->thresh62);
+		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+			      AR_PHY_EXT_CCA0_THRESH62,
+			      pModal->thresh62);
+	} else {
+		REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
+			      pModal->thresh62);
+		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+			      AR_PHY_EXT_CCA_THRESH62,
+			      pModal->thresh62);
+	}
+
+	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+			      AR_PHY_TX_END_DATA_START,
+			      pModal->txFrameToDataStart);
+		REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+			      pModal->txFrameToPaOn);
+	}
+
+	if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+		if (IS_CHAN_HT40(chan))
+			REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+				      AR_PHY_SETTLING_SWITCH,
+				      pModal->swSettleHt40);
+	}
+
+	if (AR_SREV_9280_20_OR_LATER(ah) &&
+	    AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+		REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
+			      AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+			      pModal->miscBits);
+
+
+	if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+		if (IS_CHAN_2GHZ(chan))
+			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+					eep->baseEepHeader.dacLpMode);
+		else if (eep->baseEepHeader.dacHiPwrMode_5G)
+			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
+		else
+			REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+				      eep->baseEepHeader.dacLpMode);
+
+		REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
+			      pModal->miscBits >> 2);
+
+		REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
+			      AR_PHY_TX_DESIRED_SCALE_CCK,
+			      eep->baseEepHeader.desiredScaleCCK);
+	}
+}
+
+static void ath9k_hw_def_set_addac(struct ath_hw *ah,
+				   struct ath9k_channel *chan)
+{
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+	struct modal_eep_header *pModal;
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	u8 biaslevel;
+
+	if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+		return;
+
+	if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+		return;
+
+	pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+	if (pModal->xpaBiasLvl != 0xff) {
+		biaslevel = pModal->xpaBiasLvl;
+	} else {
+		u16 resetFreqBin, freqBin, freqCount = 0;
+		struct chan_centers centers;
+
+		ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+		resetFreqBin = FREQ2FBIN(centers.synth_center,
+					 IS_CHAN_2GHZ(chan));
+		freqBin = XPA_LVL_FREQ(0) & 0xff;
+		biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
+
+		freqCount++;
+
+		while (freqCount < 3) {
+			if (XPA_LVL_FREQ(freqCount) == 0x0)
+				break;
+
+			freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+			if (resetFreqBin >= freqBin)
+				biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+			else
+				break;
+			freqCount++;
+		}
+	}
+
+	if (IS_CHAN_2GHZ(chan)) {
+		INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
+					7, 1) & (~0x18)) | biaslevel << 3;
+	} else {
+		INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
+					6, 1) & (~0xc0)) | biaslevel << 6;
+	}
+#undef XPA_LVL_FREQ
+}
+
+static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				struct cal_data_per_freq *pRawDataSet,
+				u8 *bChans, u16 availPiers,
+				u16 tPdGainOverlap, int16_t *pMinCalPower,
+				u16 *pPdGainBoundaries, u8 *pPDADCValues,
+				u16 numXpdGains)
+{
+	int i, j, k;
+	int16_t ss;
+	u16 idxL = 0, idxR = 0, numPiers;
+	static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+	static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+	u8 minPwrT4[AR5416_NUM_PD_GAINS];
+	u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+	int16_t vpdStep;
+	int16_t tmpVal;
+	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+	bool match;
+	int16_t minDelta = 0;
+	struct chan_centers centers;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
+		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+			break;
+	}
+
+	match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+							     IS_CHAN_2GHZ(chan)),
+					       bChans, numPiers, &idxL, &idxR);
+
+	if (match) {
+		for (i = 0; i < numXpdGains; i++) {
+			minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+			maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+					pRawDataSet[idxL].pwrPdg[i],
+					pRawDataSet[idxL].vpdPdg[i],
+					AR5416_PD_GAIN_ICEPTS,
+					vpdTableI[i]);
+		}
+	} else {
+		for (i = 0; i < numXpdGains; i++) {
+			pVpdL = pRawDataSet[idxL].vpdPdg[i];
+			pPwrL = pRawDataSet[idxL].pwrPdg[i];
+			pVpdR = pRawDataSet[idxR].vpdPdg[i];
+			pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+			maxPwrT4[i] =
+				min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
+				    pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
+
+
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+						pPwrL, pVpdL,
+						AR5416_PD_GAIN_ICEPTS,
+						vpdTableL[i]);
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+						pPwrR, pVpdR,
+						AR5416_PD_GAIN_ICEPTS,
+						vpdTableR[i]);
+
+			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+				vpdTableI[i][j] =
+					(u8)(ath9k_hw_interpolate((u16)
+					     FREQ2FBIN(centers.
+						       synth_center,
+						       IS_CHAN_2GHZ
+						       (chan)),
+					     bChans[idxL], bChans[idxR],
+					     vpdTableL[i][j], vpdTableR[i][j]));
+			}
+		}
+	}
+
+	*pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+	k = 0;
+
+	for (i = 0; i < numXpdGains; i++) {
+		if (i == (numXpdGains - 1))
+			pPdGainBoundaries[i] =
+				(u16)(maxPwrT4[i] / 2);
+		else
+			pPdGainBoundaries[i] =
+				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+		pPdGainBoundaries[i] =
+			min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+			minDelta = pPdGainBoundaries[0] - 23;
+			pPdGainBoundaries[0] = 23;
+		} else {
+			minDelta = 0;
+		}
+
+		if (i == 0) {
+			if (AR_SREV_9280_10_OR_LATER(ah))
+				ss = (int16_t)(0 - (minPwrT4[i] / 2));
+			else
+				ss = 0;
+		} else {
+			ss = (int16_t)((pPdGainBoundaries[i - 1] -
+					(minPwrT4[i] / 2)) -
+				       tPdGainOverlap + 1 + minDelta);
+		}
+		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+			ss++;
+		}
+
+		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+				(minPwrT4[i] / 2));
+		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+			tgtIndex : sizeCurrVpdTable;
+
+		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+			pPDADCValues[k++] = vpdTableI[i][ss++];
+		}
+
+		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+				    vpdTableI[i][sizeCurrVpdTable - 2]);
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+		if (tgtIndex > maxIndex) {
+			while ((ss <= tgtIndex) &&
+			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+				tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+						    (ss - maxIndex + 1) * vpdStep));
+				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+							 255 : tmpVal);
+				ss++;
+			}
+		}
+	}
+
+	while (i < AR5416_PD_GAINS_IN_MASK) {
+		pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
+		i++;
+	}
+
+	while (k < AR5416_NUM_PDADC_VALUES) {
+		pPDADCValues[k] = pPDADCValues[k - 1];
+		k++;
+	}
+
+	return;
+}
+
+static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+				  struct ath9k_channel *chan,
+				  int16_t *pTxPowerIndexOffset)
+{
+#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
+#define SM_PDGAIN_B(x, y) \
+		SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
+
+	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+	struct cal_data_per_freq *pRawDataset;
+	u8 *pCalBChans = NULL;
+	u16 pdGainOverlap_t2;
+	static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+	u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+	u16 numPiers, i, j;
+	int16_t tMinCalPower;
+	u16 numXpdGain, xpdMask;
+	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+	u32 reg32, regOffset, regChainOffset;
+	int16_t modalIdx;
+
+	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+	xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		pdGainOverlap_t2 =
+			pEepData->modalHeader[modalIdx].pdGainOverlap;
+	} else {
+		pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+					    AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+	}
+
+	if (IS_CHAN_2GHZ(chan)) {
+		pCalBChans = pEepData->calFreqPier2G;
+		numPiers = AR5416_NUM_2G_CAL_PIERS;
+	} else {
+		pCalBChans = pEepData->calFreqPier5G;
+		numPiers = AR5416_NUM_5G_CAL_PIERS;
+	}
+
+	if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
+		pRawDataset = pEepData->calPierData2G[0];
+		ah->initPDADC = ((struct calDataPerFreqOpLoop *)
+				 pRawDataset)->vpdPdg[0][0];
+	}
+
+	numXpdGain = 0;
+
+	for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+		if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+			if (numXpdGain >= AR5416_NUM_PD_GAINS)
+				break;
+			xpdGainValues[numXpdGain] =
+				(u16)(AR5416_PD_GAINS_IN_MASK - i);
+			numXpdGain++;
+		}
+	}
+
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+		      (numXpdGain - 1) & 0x3);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+		      xpdGainValues[0]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+		      xpdGainValues[1]);
+	REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+		      xpdGainValues[2]);
+
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+		if (AR_SREV_5416_20_OR_LATER(ah) &&
+		    (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+		    (i != 0)) {
+			regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+		} else
+			regChainOffset = i * 0x1000;
+
+		if (pEepData->baseEepHeader.txMask & (1 << i)) {
+			if (IS_CHAN_2GHZ(chan))
+				pRawDataset = pEepData->calPierData2G[i];
+			else
+				pRawDataset = pEepData->calPierData5G[i];
+
+
+			if (OLC_FOR_AR9280_20_LATER) {
+				u8 pcdacIdx;
+				u8 txPower;
+
+				ath9k_get_txgain_index(ah, chan,
+				(struct calDataPerFreqOpLoop *)pRawDataset,
+				pCalBChans, numPiers, &txPower, &pcdacIdx);
+				ath9k_olc_get_pdadcs(ah, pcdacIdx,
+						     txPower/2, pdadcValues);
+			} else {
+				ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
+							chan, pRawDataset,
+							pCalBChans, numPiers,
+							pdGainOverlap_t2,
+							&tMinCalPower,
+							gainBoundaries,
+							pdadcValues,
+							numXpdGain);
+			}
+
+			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+				if (OLC_FOR_AR9280_20_LATER) {
+					REG_WRITE(ah,
+						AR_PHY_TPCRG5 + regChainOffset,
+						SM(0x6,
+						AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+						SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+						SM_PD_GAIN(3) | SM_PD_GAIN(4));
+				} else {
+					REG_WRITE(ah,
+						AR_PHY_TPCRG5 + regChainOffset,
+						SM(pdGainOverlap_t2,
+						AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+						SM_PDGAIN_B(0, 1) |
+						SM_PDGAIN_B(1, 2) |
+						SM_PDGAIN_B(2, 3) |
+						SM_PDGAIN_B(3, 4));
+				}
+			}
+
+			regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+			for (j = 0; j < 32; j++) {
+				reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+					((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+					((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+					((pdadcValues[4 * j + 3] & 0xFF) << 24);
+				REG_WRITE(ah, regOffset, reg32);
+
+				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+					"PDADC (%d,%4x): %4.4x %8.8x\n",
+					i, regChainOffset, regOffset,
+					reg32);
+				DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+					"PDADC: Chain %d | PDADC %3d "
+					"Value %3d | PDADC %3d Value %3d | "
+					"PDADC %3d Value %3d | PDADC %3d "
+					"Value %3d |\n",
+					i, 4 * j, pdadcValues[4 * j],
+					4 * j + 1, pdadcValues[4 * j + 1],
+					4 * j + 2, pdadcValues[4 * j + 2],
+					4 * j + 3,
+					pdadcValues[4 * j + 3]);
+
+				regOffset += 4;
+			}
+		}
+	}
+
+	*pTxPowerIndexOffset = 0;
+#undef SM_PD_GAIN
+#undef SM_PDGAIN_B
+}
+
+static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+						  struct ath9k_channel *chan,
+						  int16_t *ratesArray,
+						  u16 cfgCtl,
+						  u16 AntennaReduction,
+						  u16 twiceMaxRegulatoryPower,
+						  u16 powerLimit)
+{
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
+
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+	u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+	static const u16 tpScaleReductionTable[5] =
+		{ 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+	int i;
+	int16_t twiceLargestAntenna;
+	struct cal_ctl_data *rep;
+	struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+		0, { 0, 0, 0, 0}
+	};
+	struct cal_target_power_leg targetPowerOfdmExt = {
+		0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+		0, { 0, 0, 0, 0 }
+	};
+	struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+		0, {0, 0, 0, 0}
+	};
+	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+	u16 ctlModesFor11a[] =
+		{ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+	u16 ctlModesFor11g[] =
+		{ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+		  CTL_2GHT40
+		};
+	u16 numCtlModes, *pCtlMode, ctlMode, freq;
+	struct chan_centers centers;
+	int tx_chainmask;
+	u16 twiceMinEdgePower;
+
+	tx_chainmask = ah->txchainmask;
+
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+	twiceLargestAntenna = max(
+		pEepData->modalHeader
+			[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+		pEepData->modalHeader
+			[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+	twiceLargestAntenna = max((u8)twiceLargestAntenna,
+				  pEepData->modalHeader
+				  [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+	twiceLargestAntenna = (int16_t)min(AntennaReduction -
+					   twiceLargestAntenna, 0);
+
+	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+	if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+		maxRegAllowedPower -=
+			(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+	}
+
+	scaledPower = min(powerLimit, maxRegAllowedPower);
+
+	switch (ar5416_get_ntxchains(tx_chainmask)) {
+	case 1:
+		break;
+	case 2:
+		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		break;
+	case 3:
+		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+		break;
+	}
+
+	scaledPower = max((u16)0, scaledPower);
+
+	if (IS_CHAN_2GHZ(chan)) {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+			SUB_NUM_CTL_MODES_AT_2G_40;
+		pCtlMode = ctlModesFor11g;
+
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPowerCck,
+			AR5416_NUM_2G_CCK_TARGET_POWERS,
+			&targetPowerCck, 4, false);
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPower2G,
+			AR5416_NUM_2G_20_TARGET_POWERS,
+			&targetPowerOfdm, 4, false);
+		ath9k_hw_get_target_powers(ah, chan,
+			pEepData->calTargetPower2GHT20,
+			AR5416_NUM_2G_20_TARGET_POWERS,
+			&targetPowerHt20, 8, false);
+
+		if (IS_CHAN_HT40(chan)) {
+			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+			ath9k_hw_get_target_powers(ah, chan,
+				pEepData->calTargetPower2GHT40,
+				AR5416_NUM_2G_40_TARGET_POWERS,
+				&targetPowerHt40, 8, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPowerCck,
+				AR5416_NUM_2G_CCK_TARGET_POWERS,
+				&targetPowerCckExt, 4, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPower2G,
+				AR5416_NUM_2G_20_TARGET_POWERS,
+				&targetPowerOfdmExt, 4, true);
+		}
+	} else {
+		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+			SUB_NUM_CTL_MODES_AT_5G_40;
+		pCtlMode = ctlModesFor11a;
+
+		ath9k_hw_get_legacy_target_powers(ah, chan,
+			pEepData->calTargetPower5G,
+			AR5416_NUM_5G_20_TARGET_POWERS,
+			&targetPowerOfdm, 4, false);
+		ath9k_hw_get_target_powers(ah, chan,
+			pEepData->calTargetPower5GHT20,
+			AR5416_NUM_5G_20_TARGET_POWERS,
+			&targetPowerHt20, 8, false);
+
+		if (IS_CHAN_HT40(chan)) {
+			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+			ath9k_hw_get_target_powers(ah, chan,
+				pEepData->calTargetPower5GHT40,
+				AR5416_NUM_5G_40_TARGET_POWERS,
+				&targetPowerHt40, 8, true);
+			ath9k_hw_get_legacy_target_powers(ah, chan,
+				pEepData->calTargetPower5G,
+				AR5416_NUM_5G_20_TARGET_POWERS,
+				&targetPowerOfdmExt, 4, true);
+		}
+	}
+
+	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+			(pCtlMode[ctlMode] == CTL_2GHT40);
+		if (isHt40CtlMode)
+			freq = centers.synth_center;
+		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+			freq = centers.ext_center;
+		else
+			freq = centers.ctl_center;
+
+		if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+		    ah->eep_ops->get_eeprom_rev(ah) <= 2)
+			twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+		for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+			if ((((cfgCtl & ~CTL_MODE_M) |
+			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			     pEepData->ctlIndex[i]) ||
+			    (((cfgCtl & ~CTL_MODE_M) |
+			      (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+			     ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+				rep = &(pEepData->ctlData[i]);
+
+				twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+				rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
+				IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+				if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+					twiceMaxEdgePower = min(twiceMaxEdgePower,
+								twiceMinEdgePower);
+				} else {
+					twiceMaxEdgePower = twiceMinEdgePower;
+					break;
+				}
+			}
+		}
+
+		minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+		switch (pCtlMode[ctlMode]) {
+		case CTL_11B:
+			for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+				targetPowerCck.tPow2x[i] =
+					min((u16)targetPowerCck.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_11A:
+		case CTL_11G:
+			for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+				targetPowerOfdm.tPow2x[i] =
+					min((u16)targetPowerOfdm.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_5GHT20:
+		case CTL_2GHT20:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+				targetPowerHt20.tPow2x[i] =
+					min((u16)targetPowerHt20.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		case CTL_11B_EXT:
+			targetPowerCckExt.tPow2x[0] = min((u16)
+					targetPowerCckExt.tPow2x[0],
+					minCtlPower);
+			break;
+		case CTL_11A_EXT:
+		case CTL_11G_EXT:
+			targetPowerOfdmExt.tPow2x[0] = min((u16)
+					targetPowerOfdmExt.tPow2x[0],
+					minCtlPower);
+			break;
+		case CTL_5GHT40:
+		case CTL_2GHT40:
+			for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+				targetPowerHt40.tPow2x[i] =
+					min((u16)targetPowerHt40.tPow2x[i],
+					    minCtlPower);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+		ratesArray[rate18mb] = ratesArray[rate24mb] =
+		targetPowerOfdm.tPow2x[0];
+	ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+	ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+	ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+	ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+	for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+		ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+	if (IS_CHAN_2GHZ(chan)) {
+		ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+		ratesArray[rate2s] = ratesArray[rate2l] =
+			targetPowerCck.tPow2x[1];
+		ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+			targetPowerCck.tPow2x[2];
+		ratesArray[rate11s] = ratesArray[rate11l] =
+			targetPowerCck.tPow2x[3];
+	}
+	if (IS_CHAN_HT40(chan)) {
+		for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+			ratesArray[rateHt40_0 + i] =
+				targetPowerHt40.tPow2x[i];
+		}
+		ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+		ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+		if (IS_CHAN_2GHZ(chan)) {
+			ratesArray[rateExtCck] =
+				targetPowerCckExt.tPow2x[0];
+		}
+	}
+}
+
+static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
+				    struct ath9k_channel *chan,
+				    u16 cfgCtl,
+				    u8 twiceAntennaReduction,
+				    u8 twiceMaxRegulatoryPower,
+				    u8 powerLimit)
+{
+#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+	struct modal_eep_header *pModal =
+		&(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
+	int16_t ratesArray[Ar5416RateSize];
+	int16_t txPowerIndexOffset = 0;
+	u8 ht40PowerIncForPdadc = 2;
+	int i, cck_ofdm_delta = 0;
+
+	memset(ratesArray, 0, sizeof(ratesArray));
+
+	if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+	    AR5416_EEP_MINOR_VER_2) {
+		ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+	}
+
+	ath9k_hw_set_def_power_per_rate_table(ah, chan,
+					       &ratesArray[0], cfgCtl,
+					       twiceAntennaReduction,
+					       twiceMaxRegulatoryPower,
+					       powerLimit);
+
+	ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+	for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+		ratesArray[i] =	(int16_t)(txPowerIndexOffset + ratesArray[i]);
+		if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+			ratesArray[i] = AR5416_MAX_RATE_POWER;
+	}
+
+	if (AR_SREV_9280_10_OR_LATER(ah)) {
+		for (i = 0; i < Ar5416RateSize; i++)
+			ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+		  ATH9K_POW_SM(ratesArray[rate54mb], 24)
+		  | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+		  | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+		  | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+	if (IS_CHAN_2GHZ(chan)) {
+		if (OLC_FOR_AR9280_20_LATER) {
+			cck_ofdm_delta = 2;
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+				ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
+				| ATH9K_POW_SM(ratesArray[rateXr], 8)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+				ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
+				| ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
+		} else {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+				ATH9K_POW_SM(ratesArray[rate2s], 24)
+				| ATH9K_POW_SM(ratesArray[rate2l], 16)
+				| ATH9K_POW_SM(ratesArray[rateXr], 8)
+				| ATH9K_POW_SM(ratesArray[rate1l], 0));
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+				ATH9K_POW_SM(ratesArray[rate11s], 24)
+				| ATH9K_POW_SM(ratesArray[rate11l], 16)
+				| ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+				| ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+		}
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+		  ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+	REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+		  ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+		  | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+	if (IS_CHAN_HT40(chan)) {
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+			  ATH9K_POW_SM(ratesArray[rateHt40_3] +
+				       ht40PowerIncForPdadc, 24)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+					 ht40PowerIncForPdadc, 16)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+					 ht40PowerIncForPdadc, 8)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+					 ht40PowerIncForPdadc, 0));
+		REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+			  ATH9K_POW_SM(ratesArray[rateHt40_7] +
+				       ht40PowerIncForPdadc, 24)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+					 ht40PowerIncForPdadc, 16)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+					 ht40PowerIncForPdadc, 8)
+			  | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+					 ht40PowerIncForPdadc, 0));
+		if (OLC_FOR_AR9280_20_LATER) {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+				| ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
+				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+				| ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
+		} else {
+			REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+				ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+				| ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+				| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+				| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+		}
+	}
+
+	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+		  ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+		  | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+	i = rate6mb;
+
+	if (IS_CHAN_HT40(chan))
+		i = rateHt40_0;
+	else if (IS_CHAN_HT20(chan))
+		i = rateHt20_0;
+
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		regulatory->max_power_level =
+			ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+	else
+		regulatory->max_power_level = ratesArray[i];
+
+	switch(ar5416_get_ntxchains(ah->txchainmask)) {
+	case 1:
+		break;
+	case 2:
+		regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+		break;
+	case 3:
+		regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+		break;
+	default:
+		DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+			"Invalid chainmask configuration\n");
+		break;
+	}
+}
+
+static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
+					  enum ieee80211_band freq_band)
+{
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	struct modal_eep_header *pModal =
+		&(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
+	struct base_eep_header *pBase = &eep->baseEepHeader;
+	u8 num_ant_config;
+
+	num_ant_config = 1;
+
+	if (pBase->version >= 0x0E0D)
+		if (pModal->useAnt1)
+			num_ant_config += 1;
+
+	return num_ant_config;
+}
+
+static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
+					       struct ath9k_channel *chan)
+{
+	struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+	struct modal_eep_header *pModal =
+		&(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+	return pModal->antCtrlCommon & 0xFFFF;
+}
+
+static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_DEF_SPURCHAN \
+	(ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
+	u16 spur_val = AR_NO_SPUR;
+
+	DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+		"Getting spur idx %d is2Ghz. %d val %x\n",
+		i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+	switch (ah->config.spurmode) {
+	case SPUR_DISABLE:
+		break;
+	case SPUR_ENABLE_IOCTL:
+		spur_val = ah->config.spurchans[i][is2GHz];
+		DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+			"Getting spur val from new loc. %d\n", spur_val);
+		break;
+	case SPUR_ENABLE_EEPROM:
+		spur_val = EEP_DEF_SPURCHAN;
+		break;
+	}
+
+	return spur_val;
+
+#undef EEP_DEF_SPURCHAN
+}
+
+const struct eeprom_ops eep_def_ops = {
+	.check_eeprom		= ath9k_hw_def_check_eeprom,
+	.get_eeprom		= ath9k_hw_def_get_eeprom,
+	.fill_eeprom		= ath9k_hw_def_fill_eeprom,
+	.get_eeprom_ver		= ath9k_hw_def_get_eeprom_ver,
+	.get_eeprom_rev		= ath9k_hw_def_get_eeprom_rev,
+	.get_num_ant_config	= ath9k_hw_def_get_num_ant_config,
+	.get_eeprom_antenna_cfg	= ath9k_hw_def_get_eeprom_antenna_cfg,
+	.set_board_values	= ath9k_hw_def_set_board_values,
+	.set_addac		= ath9k_hw_def_set_addac,
+	.set_txpower		= ath9k_hw_def_set_txpower,
+	.get_spur_channel	= ath9k_hw_def_get_spur_channel
+};
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 34935a8..b6c6cca 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -16,14 +16,11 @@
 
 #include <linux/io.h>
 #include <asm/unaligned.h>
+#include <linux/pci.h>
 
 #include "ath9k.h"
 #include "initvals.h"
 
-static int btcoex_enable;
-module_param(btcoex_enable, bool, 0);
-MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
-
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
@@ -380,12 +377,15 @@ static const char *ath9k_hw_devname(u16 devid)
 		return "Atheros 9280";
 	case AR9285_DEVID_PCIE:
 		return "Atheros 9285";
+	case AR5416_DEVID_AR9287_PCI:
+	case AR5416_DEVID_AR9287_PCIE:
+		return "Atheros 9287";
 	}
 
 	return NULL;
 }
 
-static void ath9k_hw_set_defaults(struct ath_hw *ah)
+static void ath9k_hw_init_config(struct ath_hw *ah)
 {
 	int i;
 
@@ -404,7 +404,7 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
 	ah->config.cck_trig_high = 200;
 	ah->config.cck_trig_low = 100;
 	ah->config.enable_ani = 1;
-	ah->config.diversity_control = 0;
+	ah->config.diversity_control = ATH9K_ANT_VARIABLE;
 	ah->config.antenna_switch_swap = 0;
 
 	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
@@ -434,37 +434,24 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
 		ah->config.serialize_regmode = SER_REG_MODE_AUTO;
 }
 
-static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
-					int *status)
+static void ath9k_hw_init_defaults(struct ath_hw *ah)
 {
-	struct ath_hw *ah;
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 
-	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
-	if (ah == NULL) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Cannot allocate memory for state block\n");
-		*status = -ENOMEM;
-		return NULL;
-	}
+	regulatory->country_code = CTRY_DEFAULT;
+	regulatory->power_limit = MAX_RATE_POWER;
+	regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
 
-	ah->ah_sc = sc;
 	ah->hw_version.magic = AR5416_MAGIC;
-	ah->regulatory.country_code = CTRY_DEFAULT;
-	ah->hw_version.devid = devid;
 	ah->hw_version.subvendorid = 0;
 
 	ah->ah_flags = 0;
-	if ((devid == AR5416_AR9100_DEVID))
+	if (ah->hw_version.devid == AR5416_AR9100_DEVID)
 		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
 	if (!AR_SREV_9100(ah))
 		ah->ah_flags = AH_USE_EEPROM;
 
-	ah->regulatory.power_limit = MAX_RATE_POWER;
-	ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
 	ah->atim_window = 0;
-	ah->diversity_control = ah->config.diversity_control;
-	ah->antenna_switch_swap =
-		ah->config.antenna_switch_swap;
 	ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
 	ah->beacon_interval = 100;
 	ah->enable_32kHz_clock = DONT_USE_32KHZ;
@@ -475,7 +462,7 @@ static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
 
 	ah->gbeacon_rate = 0;
 
-	return ah;
+	ah->power_mode = ATH9K_PM_UNDEFINED;
 }
 
 static int ath9k_hw_rfattach(struct ath_hw *ah)
@@ -588,7 +575,7 @@ static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
 	}
 }
 
-static int ath9k_hw_post_attach(struct ath_hw *ah)
+static int ath9k_hw_post_init(struct ath_hw *ah)
 {
 	int ecode;
 
@@ -599,7 +586,7 @@ static int ath9k_hw_post_attach(struct ath_hw *ah)
 	if (ecode != 0)
 		return ecode;
 
-	ecode = ath9k_hw_eeprom_attach(ah);
+	ecode = ath9k_hw_eeprom_init(ah);
 	if (ecode != 0)
 		return ecode;
 
@@ -612,70 +599,52 @@ static int ath9k_hw_post_attach(struct ath_hw *ah)
 
 	if (!AR_SREV_9100(ah)) {
 		ath9k_hw_ani_setup(ah);
-		ath9k_hw_ani_attach(ah);
+		ath9k_hw_ani_init(ah);
 	}
 
 	return 0;
 }
 
-static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
-					 int *status)
+static bool ath9k_hw_devid_supported(u16 devid)
 {
-	struct ath_hw *ah;
-	int ecode;
-	u32 i, j;
-
-	ah = ath9k_hw_newstate(devid, sc, status);
-	if (ah == NULL)
-		return NULL;
-
-	ath9k_hw_set_defaults(ah);
-
-	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
-		DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
-		ecode = -EIO;
-		goto bad;
-	}
-
-	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-		DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
-		ecode = -EIO;
-		goto bad;
-	}
-
-	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
-		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
-		    (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
-			ah->config.serialize_regmode =
-				SER_REG_MODE_ON;
-		} else {
-			ah->config.serialize_regmode =
-				SER_REG_MODE_OFF;
-		}
-	}
-
-	DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
-		ah->config.serialize_regmode);
-
-	if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
-	    (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
-	    (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
-	    (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"Mac Chip Rev 0x%02x.%x is not supported by "
-			"this driver\n", ah->hw_version.macVersion,
-			ah->hw_version.macRev);
-		ecode = -EOPNOTSUPP;
-		goto bad;
+	switch (devid) {
+	case AR5416_DEVID_PCI:
+	case AR5416_DEVID_PCIE:
+	case AR5416_AR9100_DEVID:
+	case AR9160_DEVID_PCI:
+	case AR9280_DEVID_PCI:
+	case AR9280_DEVID_PCIE:
+	case AR9285_DEVID_PCIE:
+	case AR5416_DEVID_AR9287_PCI:
+	case AR5416_DEVID_AR9287_PCIE:
+		return true;
+	default:
+		break;
 	}
+	return false;
+}
 
-	if (AR_SREV_9100(ah)) {
-		ah->iq_caldata.calData = &iq_cal_multi_sample;
-		ah->supp_cals = IQ_MISMATCH_CAL;
-		ah->is_pciexpress = false;
+static bool ath9k_hw_macversion_supported(u32 macversion)
+{
+	switch (macversion) {
+	case AR_SREV_VERSION_5416_PCI:
+	case AR_SREV_VERSION_5416_PCIE:
+	case AR_SREV_VERSION_9160:
+	case AR_SREV_VERSION_9100:
+	case AR_SREV_VERSION_9280:
+	case AR_SREV_VERSION_9285:
+	case AR_SREV_VERSION_9287:
+		return true;
+	/* Not yet */
+	case AR_SREV_VERSION_9271:
+	default:
+		break;
 	}
-	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+	return false;
+}
 
+static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
+{
 	if (AR_SREV_9160_10_OR_LATER(ah)) {
 		if (AR_SREV_9280_10_OR_LATER(ah)) {
 			ah->iq_caldata.calData = &iq_cal_single_sample;
@@ -696,12 +665,49 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
 		}
 		ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
 	}
+}
 
-	ah->ani_function = ATH9K_ANI_ALL;
-	if (AR_SREV_9280_10_OR_LATER(ah))
-		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
+{
+	if (AR_SREV_9271(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271_1_0,
+			       ARRAY_SIZE(ar9271Modes_9271_1_0), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271_1_0,
+			       ARRAY_SIZE(ar9271Common_9271_1_0), 2);
+		return;
+	}
+
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
+				ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
+				ARRAY_SIZE(ar9287Common_9287_1_1), 2);
+		if (ah->config.pcie_clock_req)
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_off_L1_9287_1_1,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
+		else
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
+					2);
+	} else if (AR_SREV_9287_10_OR_LATER(ah)) {
+		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
+				ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
+		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
+				ARRAY_SIZE(ar9287Common_9287_1_0), 2);
+
+		if (ah->config.pcie_clock_req)
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_off_L1_9287_1_0,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
+		else
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
+			ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
+			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
+				  2);
+	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
 
-	if (AR_SREV_9285_12_OR_LATER(ah)) {
 
 		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
 			       ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
@@ -832,17 +838,32 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
 		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
 			       ARRAY_SIZE(ar5416Addac), 2);
 	}
+}
 
-	if (ah->is_pciexpress)
-		ath9k_hw_configpcipowersave(ah, 0);
-	else
-		ath9k_hw_disablepcie(ah);
-
-	ecode = ath9k_hw_post_attach(ah);
-	if (ecode != 0)
-		goto bad;
+static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
+{
+	if (AR_SREV_9287_11(ah))
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+		ar9287Modes_rx_gain_9287_1_1,
+		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
+	else if (AR_SREV_9287_10(ah))
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
+		ar9287Modes_rx_gain_9287_1_0,
+		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
+	else if (AR_SREV_9280_20(ah))
+		ath9k_hw_init_rxgain_ini(ah);
 
-	if (AR_SREV_9285_12_OR_LATER(ah)) {
+	if (AR_SREV_9287_11(ah)) {
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+		ar9287Modes_tx_gain_9287_1_1,
+		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
+	} else if (AR_SREV_9287_10(ah)) {
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
+		ar9287Modes_tx_gain_9287_1_0,
+		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
+	} else if (AR_SREV_9280_20(ah)) {
+		ath9k_hw_init_txgain_ini(ah);
+	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
 		u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
 
 		/* txgain table */
@@ -857,16 +878,11 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
 		}
 
 	}
+}
 
-	/* rxgain table */
-	if (AR_SREV_9280_20(ah))
-		ath9k_hw_init_rxgain_ini(ah);
-
-	/* txgain table */
-	if (AR_SREV_9280_20(ah))
-		ath9k_hw_init_txgain_ini(ah);
-
-	ath9k_hw_fill_cap_info(ah);
+static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah)
+{
+	u32 i, j;
 
 	if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
 	    test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
@@ -885,29 +901,97 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
 			}
 		}
 	}
+}
+
+int ath9k_hw_init(struct ath_hw *ah)
+{
+	int r = 0;
+
+	if (!ath9k_hw_devid_supported(ah->hw_version.devid))
+		return -EOPNOTSUPP;
+
+	ath9k_hw_init_defaults(ah);
+	ath9k_hw_init_config(ah);
+
+	if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
+		return -EIO;
+	}
+
+	if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
+		return -EIO;
+	}
+
+	if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+		if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+		    (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+			ah->config.serialize_regmode =
+				SER_REG_MODE_ON;
+		} else {
+			ah->config.serialize_regmode =
+				SER_REG_MODE_OFF;
+		}
+	}
+
+	DPRINTF(ah->ah_sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+		ah->config.serialize_regmode);
+
+	if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+			"Mac Chip Rev 0x%02x.%x is not supported by "
+			"this driver\n", ah->hw_version.macVersion,
+			ah->hw_version.macRev);
+		return -EOPNOTSUPP;
+	}
+
+	if (AR_SREV_9100(ah)) {
+		ah->iq_caldata.calData = &iq_cal_multi_sample;
+		ah->supp_cals = IQ_MISMATCH_CAL;
+		ah->is_pciexpress = false;
+	}
+
+	if (AR_SREV_9271(ah))
+		ah->is_pciexpress = false;
+
+	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+
+	ath9k_hw_init_cal_settings(ah);
+
+	ah->ani_function = ATH9K_ANI_ALL;
+	if (AR_SREV_9280_10_OR_LATER(ah))
+		ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
 
-	ecode = ath9k_hw_init_macaddr(ah);
-	if (ecode != 0) {
-		DPRINTF(sc, ATH_DBG_FATAL,
+	ath9k_hw_init_mode_regs(ah);
+
+	if (ah->is_pciexpress)
+		ath9k_hw_configpcipowersave(ah, 0);
+	else
+		ath9k_hw_disablepcie(ah);
+
+	r = ath9k_hw_post_init(ah);
+	if (r)
+		return r;
+
+	ath9k_hw_init_mode_gain_regs(ah);
+	ath9k_hw_fill_cap_info(ah);
+	ath9k_hw_init_11a_eeprom_fix(ah);
+
+	r = ath9k_hw_init_macaddr(ah);
+	if (r) {
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
 			"Failed to initialize MAC address\n");
-		goto bad;
+		return r;
 	}
 
-	if (AR_SREV_9285(ah))
+	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
 		ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
 	else
 		ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
 
 	ath9k_init_nfcal_hist_buffer(ah);
 
-	return ah;
-bad:
-	if (ah)
-		ath9k_hw_detach(ah);
-	if (status)
-		*status = ecode;
-
-	return NULL;
+	return 0;
 }
 
 static void ath9k_hw_init_bb(struct ath_hw *ah,
@@ -1146,33 +1230,12 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid)
 void ath9k_hw_detach(struct ath_hw *ah)
 {
 	if (!AR_SREV_9100(ah))
-		ath9k_hw_ani_detach(ah);
+		ath9k_hw_ani_disable(ah);
 
-	ath9k_hw_rfdetach(ah);
+	ath9k_hw_rf_free(ah);
 	ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
 	kfree(ah);
-}
-
-struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
-{
-	struct ath_hw *ah = NULL;
-
-	switch (devid) {
-	case AR5416_DEVID_PCI:
-	case AR5416_DEVID_PCIE:
-	case AR5416_AR9100_DEVID:
-	case AR9160_DEVID_PCI:
-	case AR9280_DEVID_PCI:
-	case AR9280_DEVID_PCIE:
-	case AR9285_DEVID_PCIE:
-		ah = ath9k_hw_do_attach(devid, sc, error);
-		break;
-	default:
-		*error = -ENXIO;
-		break;
-	}
-
-	return ah;
+	ah = NULL;
 }
 
 /*******/
@@ -1182,6 +1245,27 @@ struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
 static void ath9k_hw_override_ini(struct ath_hw *ah,
 				  struct ath9k_channel *chan)
 {
+	u32 val;
+
+	if (AR_SREV_9271(ah)) {
+		/*
+		 * Enable spectral scan to solution for issues with stuck
+		 * beacons on AR9271 1.0. The beacon stuck issue is not seeon on
+		 * AR9271 1.1
+		 */
+		if (AR_SREV_9271_10(ah)) {
+			val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) | AR_PHY_SPECTRAL_SCAN_ENABLE;
+			REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
+		}
+		else if (AR_SREV_9271_11(ah))
+			/*
+			 * change AR_PHY_RF_CTL3 setting to fix MAC issue
+			 * present on AR9271 1.1
+			 */
+			REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001);
+		return;
+	}
+
 	/*
 	 * Set the RX_ABORT and RX_DIS and clear if off only after
 	 * RXE is set for MAC. This prevents frames with corrupted
@@ -1193,7 +1277,10 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
 	if (!AR_SREV_5416_20_OR_LATER(ah) ||
 	    AR_SREV_9280_10_OR_LATER(ah))
 		return;
-
+	/*
+	 * Disable BB clock gating
+	 * Necessary to avoid issues on AR5416 2.0
+	 */
 	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
 }
 
@@ -1245,11 +1332,21 @@ static void ath9k_olc_init(struct ath_hw *ah)
 {
 	u32 i;
 
-	for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
-		ah->originalGain[i] =
-			MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
-					AR_PHY_TX_GAIN);
-	ah->PDADCdelta = 0;
+	if (OLC_FOR_AR9287_10_LATER) {
+		REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
+				AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
+		ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
+				AR9287_AN_TXPC0_TXPCMODE,
+				AR9287_AN_TXPC0_TXPCMODE_S,
+				AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
+		udelay(100);
+	} else {
+		for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
+			ah->originalGain[i] =
+				MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
+						AR_PHY_TX_GAIN);
+		ah->PDADCdelta = 0;
+	}
 }
 
 static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
@@ -1271,6 +1368,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
 				struct ath9k_channel *chan,
 				enum ath9k_ht_macmode macmode)
 {
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	int i, regWrites = 0;
 	struct ieee80211_channel *channel = chan->chan;
 	u32 modesIndex, freqIndex;
@@ -1341,10 +1439,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
 		DO_DELAY(regWrites);
 	}
 
-	if (AR_SREV_9280(ah))
+	if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
 		REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
 
-	if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah))
+	if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
+	    AR_SREV_9287_10_OR_LATER(ah))
 		REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
 
 	for (i = 0; i < ah->iniCommon.ia_rows; i++) {
@@ -1376,11 +1475,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
 		ath9k_olc_init(ah);
 
 	ah->eep_ops->set_txpower(ah, chan,
-				 ath9k_regd_get_ctl(&ah->regulatory, chan),
+				 ath9k_regd_get_ctl(regulatory, chan),
 				 channel->max_antenna_gain * 2,
 				 channel->max_power * 2,
 				 min((u32) MAX_RATE_POWER,
-				 (u32) ah->regulatory.power_limit));
+				 (u32) regulatory->power_limit));
 
 	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
@@ -1424,23 +1523,48 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
 	u32 regval;
 
+	/*
+	 * set AHB_MODE not to do cacheline prefetches
+	*/
 	regval = REG_READ(ah, AR_AHB_MODE);
 	REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
 
+	/*
+	 * let mac dma reads be in 128 byte chunks
+	 */
 	regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
 	REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
 
+	/*
+	 * Restore TX Trigger Level to its pre-reset value.
+	 * The initial value depends on whether aggregation is enabled, and is
+	 * adjusted whenever underruns are detected.
+	 */
 	REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
 
+	/*
+	 * let mac dma writes be in 128 byte chunks
+	 */
 	regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
 	REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
 
+	/*
+	 * Setup receive FIFO threshold to hold off TX activities
+	 */
 	REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
 
+	/*
+	 * reduce the number of usable entries in PCU TXBUF to avoid
+	 * wrap around issues.
+	 */
 	if (AR_SREV_9285(ah)) {
+		/* For AR9285 the number of Fifos are reduced to half.
+		 * So set the usable tx buf size also to half to
+		 * avoid data/delimiter underruns
+		 */
 		REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
 			  AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
-	} else {
+	} else if (!AR_SREV_9271(ah)) {
 		REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
 			  AR_PCU_TXBUF_CTRL_USABLE_SIZE);
 	}
@@ -1585,8 +1709,15 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
 	REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
 		  AR_RTC_FORCE_WAKE_ON_INT);
 
+	if (!AR_SREV_9100(ah))
+		REG_WRITE(ah, AR_RC, AR_RC_AHB);
+
 	REG_WRITE(ah, AR_RTC_RESET, 0);
 	udelay(2);
+
+	if (!AR_SREV_9100(ah))
+		REG_WRITE(ah, AR_RC, 0);
+
 	REG_WRITE(ah, AR_RTC_RESET, 1);
 
 	if (!ath9k_hw_wait(ah,
@@ -1673,6 +1804,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 				    struct ath9k_channel *chan,
 				    enum ath9k_ht_macmode macmode)
 {
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	struct ieee80211_channel *channel = chan->chan;
 	u32 synthDelay, qnum;
 
@@ -1705,11 +1837,11 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
 	}
 
 	ah->eep_ops->set_txpower(ah, chan,
-			     ath9k_regd_get_ctl(&ah->regulatory, chan),
+			     ath9k_regd_get_ctl(regulatory, chan),
 			     channel->max_antenna_gain * 2,
 			     channel->max_power * 2,
 			     min((u32) MAX_RATE_POWER,
-			     (u32) ah->regulatory.power_limit));
+			     (u32) regulatory->power_limit));
 
 	synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
 	if (IS_CHAN_B(chan))
@@ -2246,14 +2378,39 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	ath9k_hw_mark_phy_inactive(ah);
 
+	if (AR_SREV_9271(ah) && ah->htc_reset_init) {
+		REG_WRITE(ah,
+			  AR9271_RESET_POWER_DOWN_CONTROL,
+			  AR9271_RADIO_RF_RST);
+		udelay(50);
+	}
+
 	if (!ath9k_hw_chip_reset(ah, chan)) {
 		DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
 		return -EINVAL;
 	}
 
+	if (AR_SREV_9271(ah) && ah->htc_reset_init) {
+		ah->htc_reset_init = false;
+		REG_WRITE(ah,
+			  AR9271_RESET_POWER_DOWN_CONTROL,
+			  AR9271_GATE_MAC_CTL);
+		udelay(50);
+	}
+
 	if (AR_SREV_9280_10_OR_LATER(ah))
 		REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
 
+	if (AR_SREV_9287_12_OR_LATER(ah)) {
+		/* Enable ASYNC FIFO */
+		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+				AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
+		REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
+		REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
+				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
+	}
 	r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
 	if (r)
 		return r;
@@ -2330,6 +2487,27 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	ath9k_hw_init_user_settings(ah);
 
+	if (AR_SREV_9287_12_OR_LATER(ah)) {
+		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
+			  AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
+		REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
+			  AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
+		REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
+			  AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
+
+		REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
+		REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
+
+		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
+			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
+		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
+			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
+	}
+	if (AR_SREV_9287_12_OR_LATER(ah)) {
+		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+				AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
+	}
+
 	REG_WRITE(ah, AR_STA_ID1,
 		  REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
 
@@ -2345,7 +2523,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 	ath9k_hw_init_bb(ah, chan);
 
 	if (!ath9k_hw_init_cal(ah, chan))
-		return -EIO;;
+		return -EIO;
 
 	rx_chainmask = ah->rxchainmask;
 	if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
@@ -2355,6 +2533,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 
 	REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
 
+	/*
+	 * For big endian systems turn on swapping for descriptors
+	 */
 	if (AR_SREV_9100(ah)) {
 		u32 mask;
 		mask = REG_READ(ah, AR_CFG);
@@ -2369,11 +2550,18 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 				"Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
 		}
 	} else {
+		/* Configure AR9271 target WLAN */
+                if (AR_SREV_9271(ah))
+			REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
 #ifdef __BIG_ENDIAN
-		REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+                else
+			REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
 #endif
 	}
 
+	if (ah->ah_sc->sc_flags & SC_OP_BTCOEX_ENABLED)
+		ath9k_hw_btcoex_enable(ah);
+
 	return 0;
 }
 
@@ -2412,9 +2600,6 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
 
 	}
 
-	if (ah->curchan == NULL)
-		return true;
-
 	return true;
 }
 
@@ -2728,7 +2913,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
 	return true;
 }
 
-bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
+static bool ath9k_hw_setpower_nolock(struct ath_hw *ah,
+				     enum ath9k_power_mode mode)
 {
 	int status = true, setChip = true;
 	static const char *modes[] = {
@@ -2738,6 +2924,9 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 		"UNDEFINED"
 	};
 
+	if (ah->power_mode == mode)
+		return status;
+
 	DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
 		modes[ah->power_mode], modes[mode]);
 
@@ -2762,6 +2951,51 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
 	return status;
 }
 
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
+{
+	unsigned long flags;
+	bool ret;
+
+	spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags);
+	ret = ath9k_hw_setpower_nolock(ah, mode);
+	spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags);
+
+	return ret;
+}
+
+void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	if (++sc->ps_usecount != 1)
+		goto unlock;
+
+	ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
+
+ unlock:
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+}
+
+void ath9k_ps_restore(struct ath_softc *sc)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->sc_pm_lock, flags);
+	if (--sc->ps_usecount != 0)
+		goto unlock;
+
+	if (sc->ps_enabled &&
+	    !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+			      SC_OP_WAIT_FOR_CAB |
+			      SC_OP_WAIT_FOR_PSPOLL_DATA |
+			      SC_OP_WAIT_FOR_TX_ACK)))
+		ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+
+ unlock:
+	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
+}
+
 /*
  * Helper for ASPM support.
  *
@@ -2790,7 +3024,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
 		/*
 		 * AR9280 2.0 or later chips use SerDes values from the
 		 * initvals.h initialized depending on chipset during
-		 * ath9k_hw_do_attach()
+		 * ath9k_hw_init()
 		 */
 		for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
 			REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
@@ -2851,7 +3085,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
 	if (ah->config.pcie_waen) {
 		REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
 	} else {
-		if (AR_SREV_9285(ah))
+		if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah))
 			REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
 		/*
 		 * On AR9280 chips bit 22 of 0x4004 needs to be set to
@@ -2985,6 +3219,23 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
 	if (AR_SREV_9100(ah))
 		return true;
 
+	if (isr & AR_ISR_GENTMR) {
+		u32 s5_s;
+
+		s5_s = REG_READ(ah, AR_ISR_S5_S);
+		if (isr & AR_ISR_GENTMR) {
+			ah->intr_gen_timer_trigger =
+				MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
+
+			ah->intr_gen_timer_thresh =
+				MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
+
+			if (ah->intr_gen_timer_trigger)
+				*masked |= ATH9K_INT_GENTIMER;
+
+		}
+	}
+
 	if (sync_cause) {
 		fatal_int =
 			(sync_cause &
@@ -3021,11 +3272,6 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
 	return true;
 }
 
-enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
-{
-	return ah->mask_reg;
-}
-
 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
 {
 	u32 omask = ah->mask_reg;
@@ -3263,27 +3509,30 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
 void ath9k_hw_fill_cap_info(struct ath_hw *ah)
 {
 	struct ath9k_hw_capabilities *pCap = &ah->caps;
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	struct ath_btcoex_info *btcoex_info = &ah->ah_sc->btcoex_info;
+
 	u16 capField = 0, eeval;
 
 	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
-	ah->regulatory.current_rd = eeval;
+	regulatory->current_rd = eeval;
 
 	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
 	if (AR_SREV_9285_10_OR_LATER(ah))
 		eeval |= AR9285_RDEXT_DEFAULT;
-	ah->regulatory.current_rd_ext = eeval;
+	regulatory->current_rd_ext = eeval;
 
 	capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
 
 	if (ah->opmode != NL80211_IFTYPE_AP &&
 	    ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
-		if (ah->regulatory.current_rd == 0x64 ||
-		    ah->regulatory.current_rd == 0x65)
-			ah->regulatory.current_rd += 5;
-		else if (ah->regulatory.current_rd == 0x41)
-			ah->regulatory.current_rd = 0x43;
+		if (regulatory->current_rd == 0x64 ||
+		    regulatory->current_rd == 0x65)
+			regulatory->current_rd += 5;
+		else if (regulatory->current_rd == 0x41)
+			regulatory->current_rd = 0x43;
 		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-			"regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
+			"regdomain mapped to 0x%x\n", regulatory->current_rd);
 	}
 
 	eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
@@ -3305,7 +3554,6 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
 	}
 
 	if (eeval & AR5416_OPFLAGS_11G) {
-		set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
 		set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
 		if (ah->config.ht_enable) {
 			if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
@@ -3321,10 +3569,17 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
 	}
 
 	pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
+	/*
+	 * For AR9271 we will temporarilly uses the rx chainmax as read from
+	 * the EEPROM.
+	 */
 	if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
-	    !(eeval & AR5416_OPFLAGS_11A))
+	    !(eeval & AR5416_OPFLAGS_11A) &&
+	    !(AR_SREV_9271(ah)))
+		/* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
 		pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
 	else
+		/* Use rx_chainmask from EEPROM. */
 		pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
 
 	if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
@@ -3412,7 +3667,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
 	else
 		pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
 
-	if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
+	if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
 		pCap->reg_cap =
 			AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
 			AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
@@ -3431,16 +3686,26 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
 	pCap->num_antcfg_2ghz =
 		ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
 
-	if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
-		pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
-		ah->btactive_gpio = 6;
-		ah->wlanactive_gpio = 5;
+	if (AR_SREV_9280_10_OR_LATER(ah) &&
+	    ath_btcoex_supported(ah->hw_version.subsysid)) {
+		btcoex_info->btactive_gpio = ATH_BTACTIVE_GPIO;
+		btcoex_info->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
+
+		if (AR_SREV_9285(ah)) {
+			btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_3WIRE;
+			btcoex_info->btpriority_gpio = ATH_BTPRIORITY_GPIO;
+		} else {
+			btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_2WIRE;
+		}
+	} else {
+		btcoex_info->btcoex_scheme = ATH_BTCOEX_CFG_NONE;
 	}
 }
 
 bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 			    u32 capability, u32 *result)
 {
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	switch (type) {
 	case ATH9K_CAP_CIPHER:
 		switch (capability) {
@@ -3489,13 +3754,13 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
 		case 0:
 			return 0;
 		case 1:
-			*result = ah->regulatory.power_limit;
+			*result = regulatory->power_limit;
 			return 0;
 		case 2:
-			*result = ah->regulatory.max_power_level;
+			*result = regulatory->max_power_level;
 			return 0;
 		case 3:
-			*result = ah->regulatory.tp_scale;
+			*result = regulatory->tp_scale;
 			return 0;
 		}
 		return false;
@@ -3595,7 +3860,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
 	if (gpio >= ah->caps.num_gpio_pins)
 		return 0xffffffff;
 
-	if (AR_SREV_9285_10_OR_LATER(ah))
+	if (AR_SREV_9287_10_OR_LATER(ah))
+		return MS_REG_READ(AR9287, gpio) != 0;
+	else if (AR_SREV_9285_10_OR_LATER(ah))
 		return MS_REG_READ(AR9285, gpio) != 0;
 	else if (AR_SREV_9280_10_OR_LATER(ah))
 		return MS_REG_READ(AR928X, gpio) != 0;
@@ -3673,7 +3940,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
 			break;
 		}
 	} else {
-		ah->diversity_control = settings;
+		ah->config.diversity_control = settings;
 	}
 
 	return true;
@@ -3700,7 +3967,8 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
 {
 	u32 phybits;
 
-	REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
+	REG_WRITE(ah, AR_RX_FILTER, bits);
+
 	phybits = 0;
 	if (bits & ATH9K_RX_FILTER_PHYRADAR)
 		phybits |= AR_PHY_ERR_RADAR;
@@ -3731,17 +3999,18 @@ bool ath9k_hw_disable(struct ath_hw *ah)
 
 void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
 {
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	struct ath9k_channel *chan = ah->curchan;
 	struct ieee80211_channel *channel = chan->chan;
 
-	ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
+	regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
 
 	ah->eep_ops->set_txpower(ah, chan,
-				 ath9k_regd_get_ctl(&ah->regulatory, chan),
+				 ath9k_regd_get_ctl(regulatory, chan),
 				 channel->max_antenna_gain * 2,
 				 channel->max_power * 2,
 				 min((u32) MAX_RATE_POWER,
-				 (u32) ah->regulatory.power_limit));
+				 (u32) regulatory->power_limit));
 }
 
 void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
@@ -3791,29 +4060,22 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
 
 void ath9k_hw_reset_tsf(struct ath_hw *ah)
 {
-	int count;
+	ath9k_ps_wakeup(ah->ah_sc);
+	if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0,
+			   AH_TSF_WRITE_TIMEOUT))
+		DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+			"AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
 
-	count = 0;
-	while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
-		count++;
-		if (count > 10) {
-			DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-				"AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
-			break;
-		}
-		udelay(10);
-	}
 	REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
+	ath9k_ps_restore(ah->ah_sc);
 }
 
-bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
+void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
 {
 	if (setting)
 		ah->misc_mode |= AR_PCU_TX_ADD_TSF;
 	else
 		ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
-
-	return true;
 }
 
 bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
@@ -3842,29 +4104,210 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
 	REG_WRITE(ah, AR_2040_MODE, macmode);
 }
 
-/***************************/
-/*  Bluetooth Coexistence  */
-/***************************/
+/* HW Generic timers configuration */
 
-void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+static const struct ath_gen_timer_configuration gen_tmr_configuration[] =
+{
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP_TIMER, AR_NDP_PERIOD, AR_TIMER_MODE, 0x0080},
+	{AR_NEXT_NDP2_TIMER, AR_NDP2_PERIOD, AR_NDP2_TIMER_MODE, 0x0001},
+	{AR_NEXT_NDP2_TIMER + 1*4, AR_NDP2_PERIOD + 1*4,
+				AR_NDP2_TIMER_MODE, 0x0002},
+	{AR_NEXT_NDP2_TIMER + 2*4, AR_NDP2_PERIOD + 2*4,
+				AR_NDP2_TIMER_MODE, 0x0004},
+	{AR_NEXT_NDP2_TIMER + 3*4, AR_NDP2_PERIOD + 3*4,
+				AR_NDP2_TIMER_MODE, 0x0008},
+	{AR_NEXT_NDP2_TIMER + 4*4, AR_NDP2_PERIOD + 4*4,
+				AR_NDP2_TIMER_MODE, 0x0010},
+	{AR_NEXT_NDP2_TIMER + 5*4, AR_NDP2_PERIOD + 5*4,
+				AR_NDP2_TIMER_MODE, 0x0020},
+	{AR_NEXT_NDP2_TIMER + 6*4, AR_NDP2_PERIOD + 6*4,
+				AR_NDP2_TIMER_MODE, 0x0040},
+	{AR_NEXT_NDP2_TIMER + 7*4, AR_NDP2_PERIOD + 7*4,
+				AR_NDP2_TIMER_MODE, 0x0080}
+};
+
+/* HW generic timer primitives */
+
+/* compute and clear index of rightmost 1 */
+static u32 rightmost_index(struct ath_gen_timer_table *timer_table, u32 *mask)
 {
-	/* connect bt_active to baseband */
-	REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-			(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
-			 AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+	u32 b;
 
-	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-			AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+	b = *mask;
+	b &= (0-b);
+	*mask &= ~b;
+	b *= debruijn32;
+	b >>= 27;
+
+	return timer_table->gen_timer_index[b];
+}
+
+u32 ath9k_hw_gettsf32(struct ath_hw *ah)
+{
+	return REG_READ(ah, AR_TSF_L32);
+}
+
+struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
+					  void (*trigger)(void *),
+					  void (*overflow)(void *),
+					  void *arg,
+					  u8 timer_index)
+{
+	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
+	struct ath_gen_timer *timer;
+
+	timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL);
+
+	if (timer == NULL) {
+		printk(KERN_DEBUG "Failed to allocate memory"
+		       "for hw timer[%d]\n", timer_index);
+		return NULL;
+	}
+
+	/* allocate a hardware generic timer slot */
+	timer_table->timers[timer_index] = timer;
+	timer->index = timer_index;
+	timer->trigger = trigger;
+	timer->overflow = overflow;
+	timer->arg = arg;
 
-	/* Set input mux for bt_active to gpio pin */
-	REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-			AR_GPIO_INPUT_MUX1_BT_ACTIVE,
-			ah->btactive_gpio);
+	return timer;
+}
+
+void ath_gen_timer_start(struct ath_hw *ah,
+			 struct ath_gen_timer *timer,
+			 u32 timer_next, u32 timer_period)
+{
+	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
+	u32 tsf;
+
+	BUG_ON(!timer_period);
+
+	set_bit(timer->index, &timer_table->timer_mask.timer_bits);
+
+	tsf = ath9k_hw_gettsf32(ah);
+
+	DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER, "curent tsf %x period %x"
+		"timer_next %x\n", tsf, timer_period, timer_next);
+
+	/*
+	 * Pull timer_next forward if the current TSF already passed it
+	 * because of software latency
+	 */
+	if (timer_next < tsf)
+		timer_next = tsf + timer_period;
+
+	/*
+	 * Program generic timer registers
+	 */
+	REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr,
+		 timer_next);
+	REG_WRITE(ah, gen_tmr_configuration[timer->index].period_addr,
+		  timer_period);
+	REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
+		    gen_tmr_configuration[timer->index].mode_mask);
+
+	/* Enable both trigger and thresh interrupt masks */
+	REG_SET_BIT(ah, AR_IMR_S5,
+		(SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
+		SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
+
+	if ((ah->ah_sc->imask & ATH9K_INT_GENTIMER) == 0) {
+		ath9k_hw_set_interrupts(ah, 0);
+		ah->ah_sc->imask |= ATH9K_INT_GENTIMER;
+		ath9k_hw_set_interrupts(ah, ah->ah_sc->imask);
+	}
+}
+
+void ath_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
+{
+	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
+
+	if ((timer->index < AR_FIRST_NDP_TIMER) ||
+		(timer->index >= ATH_MAX_GEN_TIMER)) {
+		return;
+	}
+
+	/* Clear generic timer enable bits. */
+	REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
+			gen_tmr_configuration[timer->index].mode_mask);
 
-	/* Configure the desired gpio port for input */
-	ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
+	/* Disable both trigger and thresh interrupt masks */
+	REG_CLR_BIT(ah, AR_IMR_S5,
+		(SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
+		SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_TRIG)));
+
+	clear_bit(timer->index, &timer_table->timer_mask.timer_bits);
+
+	/* if no timer is enabled, turn off interrupt mask */
+	if (timer_table->timer_mask.val == 0) {
+		ath9k_hw_set_interrupts(ah, 0);
+		ah->ah_sc->imask &= ~ATH9K_INT_GENTIMER;
+		ath9k_hw_set_interrupts(ah, ah->ah_sc->imask);
+	}
+}
+
+void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer)
+{
+	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
+
+	/* free the hardware generic timer slot */
+	timer_table->timers[timer->index] = NULL;
+	kfree(timer);
+}
+
+/*
+ * Generic Timer Interrupts handling
+ */
+void ath_gen_timer_isr(struct ath_hw *ah)
+{
+	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
+	struct ath_gen_timer *timer;
+	u32 trigger_mask, thresh_mask, index;
+
+	/* get hardware generic timer interrupt status */
+	trigger_mask = ah->intr_gen_timer_trigger;
+	thresh_mask = ah->intr_gen_timer_thresh;
+	trigger_mask &= timer_table->timer_mask.val;
+	thresh_mask &= timer_table->timer_mask.val;
+
+	trigger_mask &= ~thresh_mask;
+
+	while (thresh_mask) {
+		index = rightmost_index(timer_table, &thresh_mask);
+		timer = timer_table->timers[index];
+		BUG_ON(!timer);
+		DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER,
+			"TSF overflow for Gen timer %d\n", index);
+		timer->overflow(timer->arg);
+	}
+
+	while (trigger_mask) {
+		index = rightmost_index(timer_table, &trigger_mask);
+		timer = timer_table->timers[index];
+		BUG_ON(!timer);
+		DPRINTF(ah->ah_sc, ATH_DBG_HWTIMER,
+			"Gen timer[%d] trigger\n", index);
+		timer->trigger(timer->arg);
+	}
+}
+
+/*
+ * Primitive to disable ASPM
+ */
+void ath_pcie_aspm_disable(struct ath_softc *sc)
+{
+	struct pci_dev *pdev = to_pci_dev(sc->dev);
+	u8 aspm;
 
-	/* Configure the desired GPIO port for TX_FRAME output */
-	ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
-			    AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+	pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
+	aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
+	pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
 }
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9d0b31a..9106a0b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -42,6 +42,13 @@
 #define AR_SUBVENDOR_ID_NEW_A	0x7065
 #define AR5416_MAGIC		0x19641014
 
+#define AR5416_DEVID_AR9287_PCI  0x002D
+#define AR5416_DEVID_AR9287_PCIE 0x002E
+
+#define AR9280_COEX2WIRE_SUBSYSID	0x309b
+#define AT9285_COEX3WIRE_SA_SUBSYSID	0x30aa
+#define AT9285_COEX3WIRE_DA_SUBSYSID	0x30ab
+
 /* Register read/write primitives */
 #define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
 #define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
@@ -76,6 +83,7 @@
 #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
 #define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     2
 #define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME           3
+#define AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL  4
 #define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
 #define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
 
@@ -95,6 +103,7 @@
 
 #define MAX_RATE_POWER              63
 #define AH_WAIT_TIMEOUT             100000 /* (us) */
+#define AH_TSF_WRITE_TIMEOUT        100    /* (us) */
 #define AH_TIME_QUANTUM             10
 #define AR_KEYTABLE_SIZE            128
 #define POWER_UP_TIME               200000
@@ -113,15 +122,20 @@
 
 enum wireless_mode {
 	ATH9K_MODE_11A = 0,
-	ATH9K_MODE_11B = 2,
-	ATH9K_MODE_11G = 3,
-	ATH9K_MODE_11NA_HT20 = 6,
-	ATH9K_MODE_11NG_HT20 = 7,
-	ATH9K_MODE_11NA_HT40PLUS = 8,
-	ATH9K_MODE_11NA_HT40MINUS = 9,
-	ATH9K_MODE_11NG_HT40PLUS = 10,
-	ATH9K_MODE_11NG_HT40MINUS = 11,
-	ATH9K_MODE_MAX
+	ATH9K_MODE_11G,
+	ATH9K_MODE_11NA_HT20,
+	ATH9K_MODE_11NG_HT20,
+	ATH9K_MODE_11NA_HT40PLUS,
+	ATH9K_MODE_11NA_HT40MINUS,
+	ATH9K_MODE_11NG_HT40PLUS,
+	ATH9K_MODE_11NG_HT40MINUS,
+	ATH9K_MODE_MAX,
+};
+
+enum ath9k_ant_setting {
+	ATH9K_ANT_VARIABLE = 0,
+	ATH9K_ANT_FIXED_A,
+	ATH9K_ANT_FIXED_B
 };
 
 enum ath9k_hw_caps {
@@ -142,7 +156,6 @@ enum ath9k_hw_caps {
 	ATH9K_HW_CAP_ENHANCEDPM                 = BIT(14),
 	ATH9K_HW_CAP_AUTOSLEEP                  = BIT(15),
 	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
-	ATH9K_HW_CAP_BT_COEX			= BIT(17)
 };
 
 enum ath9k_capability_type {
@@ -188,7 +201,7 @@ struct ath9k_ops_config {
 	u32 cck_trig_high;
 	u32 cck_trig_low;
 	u32 enable_ani;
-	u16 diversity_control;
+	enum ath9k_ant_setting diversity_control;
 	u16 antenna_switch_swap;
 	int serialize_regmode;
 	bool intr_mitigation;
@@ -229,6 +242,7 @@ enum ath9k_int {
 	ATH9K_INT_GPIO = 0x01000000,
 	ATH9K_INT_CABEND = 0x02000000,
 	ATH9K_INT_TSFOOR = 0x04000000,
+	ATH9K_INT_GENTIMER = 0x08000000,
 	ATH9K_INT_CST = 0x10000000,
 	ATH9K_INT_GTT = 0x20000000,
 	ATH9K_INT_FATAL = 0x40000000,
@@ -327,12 +341,6 @@ enum ath9k_power_mode {
 	ATH9K_PM_UNDEFINED
 };
 
-enum ath9k_ant_setting {
-	ATH9K_ANT_VARIABLE = 0,
-	ATH9K_ANT_FIXED_A,
-	ATH9K_ANT_FIXED_B
-};
-
 enum ath9k_tp_scale {
 	ATH9K_TP_SCALE_MAX = 0,
 	ATH9K_TP_SCALE_50,
@@ -386,6 +394,42 @@ struct ath9k_hw_version {
 	u16 phyRev;
 	u16 analog5GhzRev;
 	u16 analog2GhzRev;
+	u16 subsysid;
+};
+
+/* Generic TSF timer definitions */
+
+#define ATH_MAX_GEN_TIMER	16
+
+#define AR_GENTMR_BIT(_index)	(1 << (_index))
+
+/*
+ * Using de Bruijin sequence to to look up 1's index in a 32 bit number
+ * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
+ */
+#define debruijn32 0x077CB531UL
+
+struct ath_gen_timer_configuration {
+	u32 next_addr;
+	u32 period_addr;
+	u32 mode_addr;
+	u32 mode_mask;
+};
+
+struct ath_gen_timer {
+	void (*trigger)(void *arg);
+	void (*overflow)(void *arg);
+	void *arg;
+	u8 index;
+};
+
+struct ath_gen_timer_table {
+	u32 gen_timer_index[32];
+	struct ath_gen_timer *timers[ATH_MAX_GEN_TIMER];
+	union {
+		unsigned long timer_bits;
+		u16 val;
+	} timer_mask;
 };
 
 struct ath_hw {
@@ -393,13 +437,13 @@ struct ath_hw {
 	struct ath9k_hw_version hw_version;
 	struct ath9k_ops_config config;
 	struct ath9k_hw_capabilities caps;
-	struct ath_regulatory regulatory;
 	struct ath9k_channel channels[38];
 	struct ath9k_channel *curchan;
 
 	union {
 		struct ar5416_eeprom_def def;
 		struct ar5416_eeprom_4k map4k;
+		struct ar9287_eeprom map9287;
 	} eeprom;
 	const struct eeprom_ops *eep_ops;
 	enum ath9k_eep_map eep_map;
@@ -411,15 +455,15 @@ struct ath_hw {
 	u16 rfsilent;
 	u32 rfkill_gpio;
 	u32 rfkill_polarity;
-	u32 btactive_gpio;
-	u32 wlanactive_gpio;
 	u32 ah_flags;
 
+	bool htc_reset_init;
+
 	enum nl80211_iftype opmode;
 	enum ath9k_power_mode power_mode;
-	enum ath9k_power_mode restore_mode;
 
 	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+	struct ath9k_pacal_info pacal_info;
 	struct ar5416Stats stats;
 	struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
 
@@ -432,8 +476,6 @@ struct ath_hw {
 	u32 txurn_interrupt_mask;
 	bool chip_fullsleep;
 	u32 atim_window;
-	u16 antenna_switch_swap;
-	enum ath9k_ant_setting diversity_control;
 
 	/* Calibration */
 	enum ath9k_cal_types supp_cals;
@@ -502,7 +544,6 @@ struct ath_hw {
 
 	/* ANI */
 	u32 proc_phyerr;
-	bool has_hw_phycounters;
 	u32 aniperiod;
 	struct ar5416AniState *curani;
 	struct ar5416AniState ani[255];
@@ -520,6 +561,7 @@ struct ath_hw {
 	u32 originalGain[22];
 	int initPDADC;
 	int PDADCdelta;
+	u8 led_pin;
 
 	struct ar5416IniArray iniModes;
 	struct ar5416IniArray iniCommon;
@@ -536,13 +578,17 @@ struct ath_hw {
 	struct ar5416IniArray iniModesAdditional;
 	struct ar5416IniArray iniModesRxGain;
 	struct ar5416IniArray iniModesTxGain;
+
+	u32 intr_gen_timer_trigger;
+	u32 intr_gen_timer_thresh;
+	struct ath_gen_timer_table hw_gen_timers;
 };
 
-/* Attach, Detach, Reset */
+/* Initialization, Detach, Reset */
 const char *ath9k_hw_probe(u16 vendorid, u16 devid);
 void ath9k_hw_detach(struct ath_hw *ah);
-struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
-void ath9k_hw_rfdetach(struct ath_hw *ah);
+int ath9k_hw_init(struct ath_hw *ah);
+void ath9k_hw_rf_free(struct ath_hw *ah);
 int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
 		   bool bChannelChange);
 void ath9k_hw_fill_cap_info(struct ath_hw *ah);
@@ -596,7 +642,7 @@ void ath9k_hw_write_associd(struct ath_softc *sc);
 u64 ath9k_hw_gettsf64(struct ath_hw *ah);
 void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
 void ath9k_hw_reset_tsf(struct ath_hw *ah);
-bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
+void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
 bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
 void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
@@ -609,9 +655,24 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
 /* Interrupt Handling */
 bool ath9k_hw_intrpend(struct ath_hw *ah);
 bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
 
-void ath9k_hw_btcoex_enable(struct ath_hw *ah);
-
+/* Generic hw timer primitives */
+struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
+					  void (*trigger)(void *),
+					  void (*overflow)(void *),
+					  void *arg,
+					  u8 timer_index);
+void ath_gen_timer_start(struct ath_hw *ah, struct ath_gen_timer *timer,
+			 u32 timer_next, u32 timer_period);
+void ath_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer);
+void ath_gen_timer_free(struct ath_hw *ah, struct ath_gen_timer *timer);
+void ath_gen_timer_isr(struct ath_hw *hw);
+u32 ath9k_hw_gettsf32(struct ath_hw *ah);
+
+#define ATH_PCIE_CAP_LINK_CTRL	0x70
+#define ATH_PCIE_CAP_LINK_L0S	1
+#define ATH_PCIE_CAP_LINK_L1	2
+
+void ath_pcie_aspm_disable(struct ath_softc *sc);
 #endif
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index e2f0a34..8622265 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -2782,7 +2782,7 @@ static const u32 ar9280Common_9280_2[][2] = {
     { 0x00008338, 0x00ff0000 },
     { 0x0000833c, 0x00000000 },
     { 0x00008340, 0x000107ff },
-    { 0x00008344, 0x00581043 },
+    { 0x00008344, 0x00481043 },
     { 0x00009808, 0x00000000 },
     { 0x0000980c, 0xafa68e30 },
     { 0x00009810, 0xfd14e000 },
@@ -3439,7 +3439,7 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
     {0x00004044,  0x00000000 },
 };
 
-/* AR9285 */
+/* AR9285 Revsion 10*/
 static const u_int32_t ar9285Modes_9285[][6] = {
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -3955,7 +3955,7 @@ static const u_int32_t ar9285Common_9285[][2] = {
     { 0x00008338, 0x00000000 },
     { 0x0000833c, 0x00000000 },
     { 0x00008340, 0x00010380 },
-    { 0x00008344, 0x00581043 },
+    { 0x00008344, 0x00481043 },
     { 0x00009808, 0x00000000 },
     { 0x0000980c, 0xafe68e30 },
     { 0x00009810, 0xfd14e000 },
@@ -4121,8 +4121,9 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
     {0x00004044,  0x00000000 },
 };
 
-/* AR9285 v1_2 PCI Register Writes.  Created: 03/04/09 */
+/* AR9285 v1_2 PCI Register Writes.  Created: 04/13/09 */
 static const u_int32_t ar9285Modes_9285_1_2[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
     { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
     { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -4132,13 +4133,14 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
     { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
     { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
     { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009824, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e },
     { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
     { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
     { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
     { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
     { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
     { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
+    { 0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
     { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
     { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
     { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
@@ -4156,7 +4158,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
     { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
     { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
     { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
+    { 0x000099c8, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f, 0x6af6532f },
     { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
     { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
     { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
@@ -4419,6 +4421,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
     { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
     { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
     { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
+    { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
     { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
     { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
     { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
@@ -4598,7 +4601,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
     { 0x00008258, 0x00000000 },
     { 0x0000825c, 0x400000ff },
     { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8a00010 },
+    { 0x00008264, 0x88a00010 },
     { 0x00008270, 0x00000000 },
     { 0x00008274, 0x40000000 },
     { 0x00008278, 0x003e4180 },
@@ -4618,7 +4621,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
     { 0x00008338, 0x00ff0000 },
     { 0x0000833c, 0x00000000 },
     { 0x00008340, 0x00010380 },
-    { 0x00008344, 0x00581043 },
+    { 0x00008344, 0x00481043 },
     { 0x00009808, 0x00000000 },
     { 0x0000980c, 0xafe68e30 },
     { 0x00009810, 0xfd14e000 },
@@ -4647,7 +4650,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
     { 0x00009954, 0x5f3ca3de },
     { 0x00009958, 0x2108ecff },
     { 0x00009968, 0x000003ce },
-    { 0x00009970, 0x192bb515 },
+    { 0x00009970, 0x192bb514 },
     { 0x00009974, 0x00000000 },
     { 0x00009978, 0x00000001 },
     { 0x0000997c, 0x00000000 },
@@ -4725,7 +4728,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
     { 0x00007800, 0x00140000 },
     { 0x00007804, 0x0e4548d8 },
     { 0x00007808, 0x54214514 },
-    { 0x0000780c, 0x02025820 },
+    { 0x0000780c, 0x02025830 },
     { 0x00007810, 0x71c0d388 },
     { 0x00007814, 0x924934a8 },
     { 0x0000781c, 0x00000000 },
@@ -4752,18 +4755,18 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
 static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
     /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
     { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
-    { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 },
     { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
     { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
-    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
-    { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
-    { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
-    { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
-    { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
-    { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 },
     { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
     { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
     { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
@@ -4776,13 +4779,13 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
     { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
     { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
     { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
-    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
-    { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
-    { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
-    { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 },
+    { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
+    { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 },
+    { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
+    { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
+    { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
+    { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
 };
 
 static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
@@ -4846,3 +4849,2185 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
     {0x00004040,  0x00043007 },
     {0x00004044,  0x00000000 },
 };
+
+/* AR9287 Revision 10 */
+static const u_int32_t ar9287Modes_9287_1_0[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+    { 0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a },
+    { 0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880 },
+    { 0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e },
+    { 0x00009828, 0x00000000, 0x00000000, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e },
+    { 0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
+    { 0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+    { 0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18 },
+    { 0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+    { 0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010 },
+    { 0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210 },
+    { 0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce },
+    { 0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c },
+    { 0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+    { 0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444 },
+    { 0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+    { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u_int32_t ar9287Common_9287_1_0[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00004024, 0x0000001f },
+    { 0x00004060, 0x00000000 },
+    { 0x00004064, 0x00000000 },
+    { 0x00007010, 0x00000033 },
+    { 0x00007020, 0x00000000 },
+    { 0x00007034, 0x00000002 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x00008070, 0x00000000 },
+    { 0x000080c0, 0x2a80001a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x18487320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c0, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d4, 0x00000000 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8a00010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x000000ff },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x0000829c, 0x00000000 },
+    { 0x00008300, 0x00000040 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00008344, 0x01c81043 },
+    { 0x00008360, 0xffffffff },
+    { 0x00008364, 0xffffffff },
+    { 0x00008368, 0x00000000 },
+    { 0x00008370, 0x00000000 },
+    { 0x00008374, 0x000000ff },
+    { 0x00008378, 0x00000000 },
+    { 0x0000837c, 0x00000000 },
+    { 0x00008380, 0xffffffff },
+    { 0x00008384, 0xffffffff },
+    { 0x00008390, 0x0fffffff },
+    { 0x00008394, 0x0fffffff },
+    { 0x00008398, 0x00000000 },
+    { 0x0000839c, 0x00000000 },
+    { 0x000083a0, 0x00000000 },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xafe68e30 },
+    { 0x00009810, 0xfd14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x0000984c, 0x0040233c },
+    { 0x0000a84c, 0x0040233c },
+    { 0x00009854, 0x00000044 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x00009910, 0x10002310 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x04900000 },
+    { 0x0000a920, 0x04900000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009930, 0x00000000 },
+    { 0x0000a930, 0x00000000 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280c00a },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x0108ecff },
+    { 0x00009940, 0x14750604 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x00009970, 0x990bb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x0c6f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099c4, 0x06336f77 },
+    { 0x000099c8, 0x6af65329 },
+    { 0x000099cc, 0x08f186c8 },
+    { 0x000099d0, 0x00046384 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },
+    { 0x000099fc, 0x00001042 },
+    { 0x0000a1f4, 0x00fffeff },
+    { 0x0000a1f8, 0x00f5f9ff },
+    { 0x0000a1fc, 0xb79f6427 },
+    { 0x0000a208, 0x803e4788 },
+    { 0x0000a210, 0x4080a333 },
+    { 0x0000a214, 0x40206c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x01834061 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x000003b5 },
+    { 0x0000a22c, 0x233f7180 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00000000 },
+    { 0x0000a248, 0xfffffffc },
+    { 0x0000a24c, 0x00000000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cdbd380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a264, 0x00418a11 },
+    { 0x0000b264, 0x00418a11 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0e79e5c6 },
+    { 0x0000b26c, 0x0e79e5c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000b398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f70081 },
+    { 0x0000a3f0, 0x01036a1e },
+    { 0x0000a3f4, 0x00000000 },
+    { 0x0000b3f4, 0x00000000 },
+    { 0x0000a7d8, 0x00000001 },
+    { 0x00007800, 0x00000800 },
+    { 0x00007804, 0x6c35ffb0 },
+    { 0x00007808, 0x6db6c000 },
+    { 0x0000780c, 0x6db6cb30 },
+    { 0x00007810, 0x6db6cb6c },
+    { 0x00007814, 0x0501e200 },
+    { 0x00007818, 0x0094128d },
+    { 0x0000781c, 0x976ee392 },
+    { 0x00007820, 0xf75ff6fc },
+    { 0x00007824, 0x00040000 },
+    { 0x00007828, 0xdb003012 },
+    { 0x0000782c, 0x04924914 },
+    { 0x00007830, 0x21084210 },
+    { 0x00007834, 0x00140000 },
+    { 0x00007838, 0x0e4548d8 },
+    { 0x0000783c, 0x54214514 },
+    { 0x00007840, 0x02025820 },
+    { 0x00007844, 0x71c0d388 },
+    { 0x00007848, 0x934934a8 },
+    { 0x00007850, 0x00000000 },
+    { 0x00007854, 0x00000800 },
+    { 0x00007858, 0x6c35ffb0 },
+    { 0x0000785c, 0x6db6c000 },
+    { 0x00007860, 0x6db6cb2c },
+    { 0x00007864, 0x6db6cb6c },
+    { 0x00007868, 0x0501e200 },
+    { 0x0000786c, 0x0094128d },
+    { 0x00007870, 0x976ee392 },
+    { 0x00007874, 0xf75ff6fc },
+    { 0x00007878, 0x00040000 },
+    { 0x0000787c, 0xdb003012 },
+    { 0x00007880, 0x04924914 },
+    { 0x00007884, 0x21084210 },
+    { 0x00007888, 0x001b6db0 },
+    { 0x0000788c, 0x00376b63 },
+    { 0x00007890, 0x06db6db6 },
+    { 0x00007894, 0x006d8000 },
+    { 0x00007898, 0x48100000 },
+    { 0x0000789c, 0x00000000 },
+    { 0x000078a0, 0x08000000 },
+    { 0x000078a4, 0x0007ffd8 },
+    { 0x000078a8, 0x0007ffd8 },
+    { 0x000078ac, 0x001c0020 },
+    { 0x000078b0, 0x000611eb },
+    { 0x000078b4, 0x40008080 },
+    { 0x000078b8, 0x2a850160 },
+};
+
+static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a },
+    { 0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c },
+    { 0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc },
+    { 0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4 },
+    { 0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc },
+    { 0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede },
+    { 0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e },
+    { 0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e },
+    { 0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e },
+    { 0x0000a780, 0x00000000, 0x00000000, 0x00000060, 0x00000060, 0x00000060 },
+    { 0x0000a784, 0x00000000, 0x00000000, 0x00004062, 0x00004062, 0x00004062 },
+    { 0x0000a788, 0x00000000, 0x00000000, 0x00008064, 0x00008064, 0x00008064 },
+    { 0x0000a78c, 0x00000000, 0x00000000, 0x0000c0a4, 0x0000c0a4, 0x0000c0a4 },
+    { 0x0000a790, 0x00000000, 0x00000000, 0x000100b0, 0x000100b0, 0x000100b0 },
+    { 0x0000a794, 0x00000000, 0x00000000, 0x000140b2, 0x000140b2, 0x000140b2 },
+    { 0x0000a798, 0x00000000, 0x00000000, 0x000180b4, 0x000180b4, 0x000180b4 },
+    { 0x0000a79c, 0x00000000, 0x00000000, 0x0001c0f4, 0x0001c0f4, 0x0001c0f4 },
+    { 0x0000a7a0, 0x00000000, 0x00000000, 0x00020134, 0x00020134, 0x00020134 },
+    { 0x0000a7a4, 0x00000000, 0x00000000, 0x000240fe, 0x000240fe, 0x000240fe },
+    { 0x0000a7a8, 0x00000000, 0x00000000, 0x0002813e, 0x0002813e, 0x0002813e },
+    { 0x0000a7ac, 0x00000000, 0x00000000, 0x0002c17e, 0x0002c17e, 0x0002c17e },
+    { 0x0000a7b0, 0x00000000, 0x00000000, 0x000301be, 0x000301be, 0x000301be },
+    { 0x0000a7b4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7b8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7bc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7c0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7c4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7c8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7cc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7d0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a7d4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
+    { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 },
+};
+
+
+static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
+    { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
+    { 0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
+    { 0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
+    { 0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
+    { 0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
+    { 0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
+    { 0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
+    { 0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
+    { 0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
+    { 0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
+    { 0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
+    { 0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
+    { 0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
+    { 0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
+    { 0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
+    { 0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
+    { 0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
+    { 0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
+    { 0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
+    { 0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
+    { 0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
+    { 0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
+    { 0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
+    { 0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
+    { 0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
+    { 0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
+    { 0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
+    { 0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
+    { 0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
+    { 0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
+    { 0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
+    { 0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
+    { 0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
+    { 0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
+    { 0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
+    { 0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
+    { 0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
+    { 0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
+    { 0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
+    { 0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
+    { 0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
+    { 0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
+    { 0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
+    { 0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
+    { 0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
+    { 0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
+    { 0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
+    { 0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
+    { 0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
+    { 0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
+    { 0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
+    { 0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
+    { 0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
+    { 0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
+    { 0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
+    { 0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
+    { 0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
+    { 0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
+    { 0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
+    { 0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
+    { 0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
+    { 0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
+    { 0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
+    { 0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
+    { 0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
+    { 0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
+    { 0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
+    { 0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
+    { 0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
+    { 0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
+    { 0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
+    { 0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
+    { 0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
+    { 0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
+    { 0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
+    { 0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
+    { 0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
+    { 0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
+    { 0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
+    { 0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
+    { 0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
+    { 0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
+    { 0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
+    { 0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
+    { 0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
+    { 0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
+    { 0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
+    { 0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
+    { 0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
+    { 0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
+    { 0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
+    { 0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
+    { 0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
+    { 0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
+    { 0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
+    { 0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
+    { 0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
+    { 0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
+    { 0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
+    { 0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
+    { 0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
+    { 0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
+    { 0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
+    { 0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
+    { 0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
+    { 0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
+    { 0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
+    { 0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
+    { 0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
+    { 0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
+    { 0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
+    { 0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
+    { 0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
+    { 0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
+    { 0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
+    { 0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
+    { 0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
+    { 0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
+    { 0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
+    { 0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
+    { 0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
+    { 0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
+    { 0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
+    { 0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
+    { 0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
+    { 0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
+    { 0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
+    { 0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
+    { 0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
+    { 0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
+    { 0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
+    { 0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
+    { 0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
+    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
+    { 0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
+    { 0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
+    { 0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
+    { 0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
+    { 0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
+    { 0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
+    { 0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
+    { 0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
+    { 0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
+    { 0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
+    { 0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
+    { 0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
+    { 0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
+    { 0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
+    { 0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
+    { 0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
+    { 0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
+    { 0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
+    { 0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
+    { 0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
+    { 0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
+    { 0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
+    { 0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
+    { 0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
+    { 0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
+    { 0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
+    { 0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
+    { 0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
+    { 0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
+    { 0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
+    { 0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
+    { 0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
+    { 0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
+    { 0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
+    { 0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
+    { 0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
+    { 0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
+    { 0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
+    { 0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
+    { 0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
+    { 0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
+    { 0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
+    { 0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
+    { 0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
+    { 0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
+    { 0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
+    { 0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
+    { 0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
+    { 0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
+    { 0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
+    { 0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
+    { 0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
+    { 0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
+    { 0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
+    { 0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
+    { 0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
+    { 0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
+    { 0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
+    { 0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
+    { 0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
+    { 0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
+    { 0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
+    { 0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
+    { 0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
+    { 0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
+    { 0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
+    { 0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
+    { 0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
+    { 0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
+    { 0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
+    { 0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
+    { 0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
+    { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
+};
+
+static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffd },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffc },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+/* AR9287 Revision 11 */
+
+static const u_int32_t ar9287Modes_9287_1_1[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+    { 0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a },
+    { 0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880 },
+    { 0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e },
+    { 0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001 },
+    { 0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e },
+    { 0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
+    { 0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+    { 0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18 },
+    { 0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+    { 0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010 },
+    { 0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210 },
+    { 0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce },
+    { 0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c },
+    { 0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+    { 0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444 },
+    { 0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+    { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u_int32_t ar9287Common_9287_1_1[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00004024, 0x0000001f },
+    { 0x00004060, 0x00000000 },
+    { 0x00004064, 0x00000000 },
+    { 0x00007010, 0x00000033 },
+    { 0x00007020, 0x00000000 },
+    { 0x00007034, 0x00000002 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x00008070, 0x00000000 },
+    { 0x000080c0, 0x2a80001a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x18487320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c0, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d4, 0x00000000 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0x88a00010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x000000ff },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x0000829c, 0x00000000 },
+    { 0x00008300, 0x00000040 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00008344, 0x01c81043 },
+    { 0x00008360, 0xffffffff },
+    { 0x00008364, 0xffffffff },
+    { 0x00008368, 0x00000000 },
+    { 0x00008370, 0x00000000 },
+    { 0x00008374, 0x000000ff },
+    { 0x00008378, 0x00000000 },
+    { 0x0000837c, 0x00000000 },
+    { 0x00008380, 0xffffffff },
+    { 0x00008384, 0xffffffff },
+    { 0x00008390, 0x0fffffff },
+    { 0x00008394, 0x0fffffff },
+    { 0x00008398, 0x00000000 },
+    { 0x0000839c, 0x00000000 },
+    { 0x000083a0, 0x00000000 },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xafe68e30 },
+    { 0x00009810, 0xfd14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x0000984c, 0x0040233c },
+    { 0x0000a84c, 0x0040233c },
+    { 0x00009854, 0x00000044 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x00009910, 0x10002310 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x04900000 },
+    { 0x0000a920, 0x04900000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009930, 0x00000000 },
+    { 0x0000a930, 0x00000000 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280c00a },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x0108ecff },
+    { 0x00009940, 0x14750604 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x00009970, 0x990bb514 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x0c6f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099c4, 0x06336f77 },
+    { 0x000099c8, 0x6af6532f },
+    { 0x000099cc, 0x08f186c8 },
+    { 0x000099d0, 0x00046384 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },
+    { 0x000099fc, 0x00001042 },
+    { 0x0000a1f4, 0x00fffeff },
+    { 0x0000a1f8, 0x00f5f9ff },
+    { 0x0000a1fc, 0xb79f6427 },
+    { 0x0000a208, 0x803e4788 },
+    { 0x0000a210, 0x4080a333 },
+    { 0x0000a214, 0x40206c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x01834061 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x000003b5 },
+    { 0x0000a22c, 0x233f7180 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00000000 },
+    { 0x0000a248, 0xfffffffc },
+    { 0x0000a24c, 0x00000000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cdbd380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a264, 0x00418a11 },
+    { 0x0000b264, 0x00418a11 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0e79e5c6 },
+    { 0x0000b26c, 0x0e79e5c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000b398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f70081 },
+    { 0x0000a3f0, 0x01036a1e },
+    { 0x0000a3f4, 0x00000000 },
+    { 0x0000b3f4, 0x00000000 },
+    { 0x0000a7d8, 0x000003f1 },
+    { 0x00007800, 0x00000800 },
+    { 0x00007804, 0x6c35ffc2 },
+    { 0x00007808, 0x6db6c000 },
+    { 0x0000780c, 0x6db6cb30 },
+    { 0x00007810, 0x6db6cb6c },
+    { 0x00007814, 0x0501e200 },
+    { 0x00007818, 0x0094128d },
+    { 0x0000781c, 0x976ee392 },
+    { 0x00007820, 0xf75ff6fc },
+    { 0x00007824, 0x00040000 },
+    { 0x00007828, 0xdb003012 },
+    { 0x0000782c, 0x04924914 },
+    { 0x00007830, 0x21084210 },
+    { 0x00007834, 0x00140000 },
+    { 0x00007838, 0x0e4548d8 },
+    { 0x0000783c, 0x54214514 },
+    { 0x00007840, 0x02025830 },
+    { 0x00007844, 0x71c0d388 },
+    { 0x00007848, 0x934934a8 },
+    { 0x00007850, 0x00000000 },
+    { 0x00007854, 0x00000800 },
+    { 0x00007858, 0x6c35ffc2 },
+    { 0x0000785c, 0x6db6c000 },
+    { 0x00007860, 0x6db6cb30 },
+    { 0x00007864, 0x6db6cb6c },
+    { 0x00007868, 0x0501e200 },
+    { 0x0000786c, 0x0094128d },
+    { 0x00007870, 0x976ee392 },
+    { 0x00007874, 0xf75ff6fc },
+    { 0x00007878, 0x00040000 },
+    { 0x0000787c, 0xdb003012 },
+    { 0x00007880, 0x04924914 },
+    { 0x00007884, 0x21084210 },
+    { 0x00007888, 0x001b6db0 },
+    { 0x0000788c, 0x00376b63 },
+    { 0x00007890, 0x06db6db6 },
+    { 0x00007894, 0x006d8000 },
+    { 0x00007898, 0x48100000 },
+    { 0x0000789c, 0x00000000 },
+    { 0x000078a0, 0x08000000 },
+    { 0x000078a4, 0x0007ffd8 },
+    { 0x000078a8, 0x0007ffd8 },
+    { 0x000078ac, 0x001c0020 },
+    { 0x000078b0, 0x00060aeb },
+    { 0x000078b4, 0x40008080 },
+    { 0x000078b8, 0x2a850160 },
+};
+
+static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a },
+    { 0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c },
+    { 0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc },
+    { 0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4 },
+    { 0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc },
+    { 0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede },
+    { 0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e },
+    { 0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e },
+    { 0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e },
+    { 0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062 },
+    { 0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064 },
+    { 0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4 },
+    { 0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa },
+    { 0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac },
+    { 0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4 },
+    { 0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4 },
+    { 0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134 },
+    { 0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174 },
+    { 0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c },
+    { 0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e },
+    { 0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be },
+    { 0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
+    { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 },
+};
+
+static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
+    { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
+    { 0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
+    { 0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
+    { 0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
+    { 0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
+    { 0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
+    { 0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
+    { 0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
+    { 0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
+    { 0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
+    { 0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
+    { 0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
+    { 0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
+    { 0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
+    { 0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
+    { 0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
+    { 0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
+    { 0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
+    { 0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
+    { 0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
+    { 0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
+    { 0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
+    { 0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
+    { 0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
+    { 0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
+    { 0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
+    { 0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
+    { 0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
+    { 0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
+    { 0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
+    { 0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
+    { 0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
+    { 0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
+    { 0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
+    { 0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
+    { 0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
+    { 0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
+    { 0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
+    { 0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
+    { 0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
+    { 0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
+    { 0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
+    { 0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
+    { 0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
+    { 0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
+    { 0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
+    { 0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
+    { 0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
+    { 0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
+    { 0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
+    { 0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
+    { 0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
+    { 0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
+    { 0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
+    { 0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
+    { 0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
+    { 0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
+    { 0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
+    { 0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
+    { 0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
+    { 0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
+    { 0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
+    { 0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
+    { 0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
+    { 0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
+    { 0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
+    { 0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
+    { 0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
+    { 0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
+    { 0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
+    { 0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
+    { 0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
+    { 0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
+    { 0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
+    { 0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
+    { 0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
+    { 0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
+    { 0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
+    { 0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
+    { 0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
+    { 0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
+    { 0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
+    { 0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
+    { 0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
+    { 0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
+    { 0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
+    { 0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
+    { 0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
+    { 0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
+    { 0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
+    { 0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
+    { 0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
+    { 0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
+    { 0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
+    { 0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
+    { 0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
+    { 0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
+    { 0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
+    { 0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
+    { 0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
+    { 0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
+    { 0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
+    { 0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
+    { 0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
+    { 0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
+    { 0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
+    { 0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
+    { 0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
+    { 0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
+    { 0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
+    { 0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
+    { 0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
+    { 0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
+    { 0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
+    { 0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
+    { 0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
+    { 0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
+    { 0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
+    { 0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
+    { 0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
+    { 0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
+    { 0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
+    { 0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
+    { 0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
+    { 0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
+    { 0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
+    { 0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
+    { 0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
+    { 0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
+    { 0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
+    { 0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
+    { 0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
+    { 0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
+    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
+    { 0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
+    { 0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
+    { 0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
+    { 0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
+    { 0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
+    { 0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
+    { 0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
+    { 0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
+    { 0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
+    { 0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
+    { 0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
+    { 0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
+    { 0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
+    { 0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
+    { 0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
+    { 0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
+    { 0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
+    { 0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
+    { 0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
+    { 0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
+    { 0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
+    { 0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
+    { 0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
+    { 0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
+    { 0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
+    { 0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
+    { 0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
+    { 0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
+    { 0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
+    { 0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
+    { 0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
+    { 0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
+    { 0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
+    { 0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
+    { 0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
+    { 0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
+    { 0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
+    { 0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
+    { 0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
+    { 0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
+    { 0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
+    { 0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
+    { 0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
+    { 0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
+    { 0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
+    { 0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
+    { 0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
+    { 0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
+    { 0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
+    { 0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
+    { 0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
+    { 0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
+    { 0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
+    { 0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
+    { 0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
+    { 0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
+    { 0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
+    { 0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
+    { 0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
+    { 0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
+    { 0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
+    { 0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
+    { 0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
+    { 0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
+    { 0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
+    { 0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
+    { 0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
+    { 0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
+    { 0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
+    { 0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
+    { 0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
+    { 0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
+    { 0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
+    { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
+};
+
+static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffd },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffc },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+
+/* AR9271 initialization values automaticaly created: 03/23/09 */
+static const u_int32_t ar9271Modes_9271_1_0[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
+    { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
+    { 0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
+    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
+    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
+    { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18 },
+    { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
+    { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 },
+    { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c },
+    { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+    { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+    { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+    { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+    { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+    { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+    { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+    { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+    { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
+    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
+    { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
+    { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
+    { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
+    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+};
+
+static const u_int32_t ar9271Common_9271_1_0[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020045 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00004024, 0x0000001f },
+    { 0x00004060, 0x00000000 },
+    { 0x00004064, 0x00000000 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x00000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x02000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x00008070, 0x00000000 },
+    { 0x000080b0, 0x00000000 },
+    { 0x000080b4, 0x00000000 },
+    { 0x000080b8, 0x00000000 },
+    { 0x000080bc, 0x00000000 },
+    { 0x000080c0, 0x2a80001a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04814 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c0, 0x00000000 },
+    { 0x000081d0, 0x0000320a },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8a00010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x0000829c, 0x00000000 },
+    { 0x00008300, 0x00000040 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000001 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x00010380 },
+    { 0x00008344, 0x00581043 },
+    { 0x00007010, 0x00000030 },
+    { 0x00007034, 0x00000002 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00007800, 0x00140000 },
+    { 0x00007804, 0x0e4548d8 },
+    { 0x00007808, 0x54214514 },
+    { 0x0000780c, 0x02025820 },
+    { 0x00007810, 0x71c0d388 },
+    { 0x00007814, 0x924934a8 },
+    { 0x0000781c, 0x00000000 },
+    { 0x00007820, 0x00000c04 },
+    { 0x00007824, 0x00d86bff },
+    { 0x00007828, 0x66964300 },
+    { 0x0000782c, 0x8db6d961 },
+    { 0x00007830, 0x8db6d96c },
+    { 0x00007834, 0x6140008b },
+    { 0x00007838, 0x00000029 },
+    { 0x0000783c, 0x72ee0a72 },
+    { 0x00007840, 0xbbfffffc },
+    { 0x00007844, 0x000c0db6 },
+    { 0x00007848, 0x6db61b6f },
+    { 0x0000784c, 0x6d9b66db },
+    { 0x00007850, 0x6d8c6dba },
+    { 0x00007854, 0x00040000 },
+    { 0x00007858, 0xdb003012 },
+    { 0x0000785c, 0x04924914 },
+    { 0x00007860, 0x21084210 },
+    { 0x00007864, 0xf7d7ffde },
+    { 0x00007868, 0xc2034080 },
+    { 0x0000786c, 0x48609eb4 },
+    { 0x00007870, 0x10142c00 },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xafe68e30 },
+    { 0x00009810, 0xfd14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x0000984c, 0x0040233c },
+    { 0x00009854, 0x00000044 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x00009910, 0x30002310 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x04900000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009940, 0x14750604 },
+    { 0x00009948, 0x9280c00a },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x0108ecff },
+    { 0x00009968, 0x000003ce },
+    { 0x00009970, 0x192bb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x2def0400 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },
+    { 0x0000a1f4, 0x00000000 },
+    { 0x0000a1f8, 0x71733d01 },
+    { 0x0000a1fc, 0xd0ad5c12 },
+    { 0x0000a208, 0x803e68c8 },
+    { 0x0000a210, 0x4080a333 },
+    { 0x0000a214, 0x00206c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x01834061 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x000003b5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a244, 0x00000000 },
+    { 0x0000a248, 0xfffffffc },
+    { 0x0000a24c, 0x00000000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0ccb5380 },
+    { 0x0000a25c, 0x15151501 },
+    { 0x0000a260, 0xdfa90f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0ebae9e6 },
+    { 0x0000a278, 0x3bdef7bd },
+    { 0x0000a27c, 0x050e83bd },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x3bdef7bd },
+    { 0x0000a398, 0x000003bd },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x3bdef7bd },
+    { 0x0000a3e0, 0x000003bd },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f70081 },
+    { 0x0000a3f0, 0x01036a2f },
+    { 0x0000a3f4, 0x00000000 },
+    { 0x0000d270, 0x0d820820 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+};
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 8ae4ec2..800bfab 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -40,20 +40,15 @@ u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
 	return REG_READ(ah, AR_QTXDP(q));
 }
 
-bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
+void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
 {
 	REG_WRITE(ah, AR_QTXDP(q), txdp);
-
-	return true;
 }
 
-bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
+void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
 {
 	DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
-
 	REG_WRITE(ah, AR_Q_TXE, 1 << q);
-
-	return true;
 }
 
 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
@@ -178,7 +173,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
 #undef ATH9K_TIME_QUANTUM
 }
 
-bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			 u32 segLen, bool firstSeg,
 			 bool lastSeg, const struct ath_desc *ds0)
 {
@@ -202,8 +197,6 @@ bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
 	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
 	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-
-	return true;
 }
 
 void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
@@ -825,13 +818,29 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 	ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
 	ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
 
-	ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
-	ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
-	ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
-	ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
-	ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
-	ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
-	ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
+	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
+		ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD;
+		ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD;
+		ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD;
+		ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD;
+		ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD;
+		ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD;
+		ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD;
+	} else {
+		ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
+		ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
+						AR_RxRSSIAnt00);
+		ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
+						AR_RxRSSIAnt01);
+		ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
+						AR_RxRSSIAnt02);
+		ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4,
+						AR_RxRSSIAnt10);
+		ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4,
+						AR_RxRSSIAnt11);
+		ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4,
+						AR_RxRSSIAnt12);
+	}
 	if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
 		ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
 	else
@@ -872,7 +881,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 	return 0;
 }
 
-bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			  u32 size, u32 flags)
 {
 	struct ar5416_desc *ads = AR5416DESC(ds);
@@ -885,8 +894,6 @@ bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
 	ads->ds_rxstatus8 &= ~AR_RxDone;
 	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
 		memset(&(ads->u), 0, sizeof(ads->u));
-
-	return true;
 }
 
 bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 1176bce..f56e77d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -568,6 +568,7 @@ enum ath9k_rx_filter {
 	ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
 	ATH9K_RX_FILTER_PHYERR = 0x00000100,
 	ATH9K_RX_FILTER_MYBEACON = 0x00000200,
+	ATH9K_RX_FILTER_COMP_BAR = 0x00000400,
 	ATH9K_RX_FILTER_PSPOLL = 0x00004000,
 	ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
 	ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
@@ -628,12 +629,12 @@ struct ath9k_channel;
 struct ath_rate_table;
 
 u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
-bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
-bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
+void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
 bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
 bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
-bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			 u32 segLen, bool firstSeg,
 			 bool lastSeg, const struct ath_desc *ds0);
 void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
@@ -668,7 +669,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
 bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
 int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
 			u32 pa, struct ath_desc *nds, u64 tsf);
-bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			  u32 size, u32 flags);
 bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
 void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 66a6c1f..3dc7b5a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -17,8 +17,6 @@
 #include <linux/nl80211.h>
 #include "ath9k.h"
 
-#define ATH_PCI_VERSION "0.1"
-
 static char *dev_info = "ath9k";
 
 MODULE_AUTHOR("Atheros Communications");
@@ -342,6 +340,7 @@ static void ath_ani_calibrate(unsigned long data)
 	* don't calibrate when we're scanning.
 	* we are most likely not on our home channel.
 	*/
+	spin_lock(&sc->ani_lock);
 	if (sc->sc_flags & SC_OP_SCANNING)
 		goto set_timer;
 
@@ -385,7 +384,7 @@ static void ath_ani_calibrate(unsigned long data)
 	if (longcal || shortcal || aniflag) {
 		/* Call ANI routine if necessary */
 		if (aniflag)
-			ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan);
+			ath9k_hw_ani_monitor(ah, ah->curchan);
 
 		/* Perform calibration if necessary */
 		if (longcal || shortcal) {
@@ -405,6 +404,7 @@ static void ath_ani_calibrate(unsigned long data)
 	ath9k_ps_restore(sc);
 
 set_timer:
+	spin_unlock(&sc->ani_lock);
 	/*
 	* Set timer interval based on previous results.
 	* The interval must be the shortest necessary to satisfy ANI,
@@ -439,8 +439,8 @@ static void ath_start_ani(struct ath_softc *sc)
  */
 void ath_update_chainmask(struct ath_softc *sc, int is_ht)
 {
-	if (is_ht ||
-	    (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
+	if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
+	    (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE)) {
 		sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
 		sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
 	} else {
@@ -460,9 +460,10 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
 
 	if (sc->sc_flags & SC_OP_TXAGGR) {
 		ath_tx_node_init(sc, an);
-		an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
+		an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
 				     sta->ht_cap.ampdu_factor);
 		an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
+		an->last_rssi = ATH_RSSI_DUMMY_MARKER;
 	}
 }
 
@@ -496,8 +497,7 @@ static void ath9k_tasklet(unsigned long data)
 	if (status & ATH9K_INT_TX)
 		ath_tx_tasklet(sc);
 
-	if ((status & ATH9K_INT_TSFOOR) &&
-	    (sc->hw->conf.flags & IEEE80211_CONF_PS)) {
+	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
 		/*
 		 * TSF sync does not look correct; remain awake to sync with
 		 * the next Beacon.
@@ -506,6 +506,10 @@ static void ath9k_tasklet(unsigned long data)
 		sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
 	}
 
+	if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+		if (status & ATH9K_INT_GENTIMER)
+			ath_gen_timer_isr(sc->sc_ah);
+
 	/* re-enable hardware interrupt */
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 	ath9k_ps_restore(sc);
@@ -521,7 +525,8 @@ irqreturn_t ath_isr(int irq, void *dev)
 		ATH9K_INT_TX |			\
 		ATH9K_INT_BMISS |		\
 		ATH9K_INT_CST |			\
-		ATH9K_INT_TSFOOR)
+		ATH9K_INT_TSFOOR |		\
+		ATH9K_INT_GENTIMER)
 
 	struct ath_softc *sc = dev;
 	struct ath_hw *ah = sc->sc_ah;
@@ -589,7 +594,7 @@ irqreturn_t ath_isr(int irq, void *dev)
 		 * it will clear whatever condition caused
 		 * the interrupt.
 		 */
-		ath9k_hw_procmibevent(ah, &sc->nodestats);
+		ath9k_hw_procmibevent(ah);
 		ath9k_hw_set_interrupts(ah, sc->imask);
 	}
 
@@ -885,8 +890,7 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
 static void setup_ht_cap(struct ath_softc *sc,
 			 struct ieee80211_sta_ht_cap *ht_info)
 {
-#define	ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3	/* 2 ^ 16 */
-#define	ATH9K_HT_CAP_MPDUDENSITY_8 0x6		/* 8 usec */
+	u8 tx_streams, rx_streams;
 
 	ht_info->ht_supported = true;
 	ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
@@ -894,64 +898,61 @@ static void setup_ht_cap(struct ath_softc *sc,
 		       IEEE80211_HT_CAP_SGI_40 |
 		       IEEE80211_HT_CAP_DSSSCCK40;
 
-	ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
-	ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
+	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
 
 	/* set up supported mcs set */
 	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
+	tx_streams = !(sc->tx_chainmask & (sc->tx_chainmask - 1)) ? 1 : 2;
+	rx_streams = !(sc->rx_chainmask & (sc->rx_chainmask - 1)) ? 1 : 2;
 
-	switch(sc->rx_chainmask) {
-	case 1:
-		ht_info->mcs.rx_mask[0] = 0xff;
-		break;
-	case 3:
-	case 5:
-	case 7:
-	default:
-		ht_info->mcs.rx_mask[0] = 0xff;
-		ht_info->mcs.rx_mask[1] = 0xff;
-		break;
+	if (tx_streams != rx_streams) {
+		DPRINTF(sc, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n",
+			tx_streams, rx_streams);
+		ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
+		ht_info->mcs.tx_params |= ((tx_streams - 1) <<
+				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
 	}
 
-	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+	ht_info->mcs.rx_mask[0] = 0xff;
+	if (rx_streams >= 2)
+		ht_info->mcs.rx_mask[1] = 0xff;
+
+	ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
 }
 
 static void ath9k_bss_assoc_info(struct ath_softc *sc,
 				 struct ieee80211_vif *vif,
 				 struct ieee80211_bss_conf *bss_conf)
 {
-	struct ath_vif *avp = (void *)vif->drv_priv;
 
 	if (bss_conf->assoc) {
 		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
 			bss_conf->aid, sc->curbssid);
 
 		/* New association, store aid */
-		if (avp->av_opmode == NL80211_IFTYPE_STATION) {
-			sc->curaid = bss_conf->aid;
-			ath9k_hw_write_associd(sc);
+		sc->curaid = bss_conf->aid;
+		ath9k_hw_write_associd(sc);
 
-			/*
-			 * Request a re-configuration of Beacon related timers
-			 * on the receipt of the first Beacon frame (i.e.,
-			 * after time sync with the AP).
-			 */
-			sc->sc_flags |= SC_OP_BEACON_SYNC;
-		}
+		/*
+		 * Request a re-configuration of Beacon related timers
+		 * on the receipt of the first Beacon frame (i.e.,
+		 * after time sync with the AP).
+		 */
+		sc->sc_flags |= SC_OP_BEACON_SYNC;
 
 		/* Configure the beacon */
 		ath_beacon_config(sc, vif);
 
 		/* Reset rssi stats */
-		sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
-		sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
-		sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
-		sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
+		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
 
 		ath_start_ani(sc);
 	} else {
 		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
 		sc->curaid = 0;
+		/* Stop ANI */
+		del_timer_sync(&sc->ani.timer);
 	}
 }
 
@@ -969,15 +970,16 @@ static void ath_led_blink_work(struct work_struct *work)
 
 	if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
 	    (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
-		ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+		ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
 	else
-		ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+		ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
 				  (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
 
-	queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
-			   (sc->sc_flags & SC_OP_LED_ON) ?
-			   msecs_to_jiffies(sc->led_off_duration) :
-			   msecs_to_jiffies(sc->led_on_duration));
+	ieee80211_queue_delayed_work(sc->hw,
+				     &sc->ath_led_blink_work,
+				     (sc->sc_flags & SC_OP_LED_ON) ?
+					msecs_to_jiffies(sc->led_off_duration) :
+					msecs_to_jiffies(sc->led_on_duration));
 
 	sc->led_on_duration = sc->led_on_cnt ?
 			max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
@@ -1002,7 +1004,7 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
 	case LED_OFF:
 		if (led->led_type == ATH_LED_ASSOC ||
 		    led->led_type == ATH_LED_RADIO) {
-			ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+			ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
 				(led->led_type == ATH_LED_RADIO));
 			sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
 			if (led->led_type == ATH_LED_RADIO)
@@ -1014,10 +1016,10 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
 	case LED_FULL:
 		if (led->led_type == ATH_LED_ASSOC) {
 			sc->sc_flags |= SC_OP_LED_ASSOCIATED;
-			queue_delayed_work(sc->hw->workqueue,
-					   &sc->ath_led_blink_work, 0);
+			ieee80211_queue_delayed_work(sc->hw,
+						     &sc->ath_led_blink_work, 0);
 		} else if (led->led_type == ATH_LED_RADIO) {
-			ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+			ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
 			sc->sc_flags |= SC_OP_LED_ON;
 		} else {
 			sc->led_on_cnt++;
@@ -1057,13 +1059,12 @@ static void ath_unregister_led(struct ath_led *led)
 
 static void ath_deinit_leds(struct ath_softc *sc)
 {
-	cancel_delayed_work_sync(&sc->ath_led_blink_work);
 	ath_unregister_led(&sc->assoc_led);
 	sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
 	ath_unregister_led(&sc->tx_led);
 	ath_unregister_led(&sc->rx_led);
 	ath_unregister_led(&sc->radio_led);
-	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 }
 
 static void ath_init_leds(struct ath_softc *sc)
@@ -1071,11 +1072,16 @@ static void ath_init_leds(struct ath_softc *sc)
 	char *trigger;
 	int ret;
 
+	if (AR_SREV_9287(sc->sc_ah))
+		sc->sc_ah->led_pin = ATH_LED_PIN_9287;
+	else
+		sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+
 	/* Configure gpio 1 for output */
-	ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+	ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
 	/* LED off, active low */
-	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 
 	INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
 
@@ -1114,6 +1120,7 @@ static void ath_init_leds(struct ath_softc *sc)
 	return;
 
 fail:
+	cancel_delayed_work_sync(&sc->ath_led_blink_work);
 	ath_deinit_leds(sc);
 }
 
@@ -1153,9 +1160,9 @@ void ath_radio_enable(struct ath_softc *sc)
 	ath9k_hw_set_interrupts(ah, sc->imask);
 
 	/* Enable LED */
-	ath9k_hw_cfg_output(ah, ATH_LED_PIN,
+	ath9k_hw_cfg_output(ah, ah->led_pin,
 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-	ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
+	ath9k_hw_set_gpio(ah, ah->led_pin, 0);
 
 	ieee80211_wake_queues(sc->hw);
 	ath9k_ps_restore(sc);
@@ -1171,8 +1178,8 @@ void ath_radio_disable(struct ath_softc *sc)
 	ieee80211_stop_queues(sc->hw);
 
 	/* Disable LED */
-	ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1);
-	ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN);
+	ath9k_hw_set_gpio(ah, ah->led_pin, 1);
+	ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
 
 	/* Disable interrupts */
 	ath9k_hw_set_interrupts(ah, 0);
@@ -1253,8 +1260,6 @@ void ath_detach(struct ath_softc *sc)
 	DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
 
 	ath_deinit_leds(sc);
-	cancel_work_sync(&sc->chan_work);
-	cancel_delayed_work_sync(&sc->wiphy_work);
 
 	for (i = 0; i < sc->num_sec_wiphy; i++) {
 		struct ath_wiphy *aphy = sc->sec_wiphy[i];
@@ -1279,9 +1284,13 @@ void ath_detach(struct ath_softc *sc)
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
+	if ((sc->btcoex_info.no_stomp_timer) &&
+	    sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+		ath_gen_timer_free(sc->sc_ah, sc->btcoex_info.no_stomp_timer);
+
 	ath9k_hw_detach(sc->sc_ah);
+	sc->sc_ah = NULL;
 	ath9k_exit_debug(sc);
-	ath9k_ps_restore(sc);
 }
 
 static int ath9k_reg_notifier(struct wiphy *wiphy,
@@ -1290,16 +1299,21 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
-	struct ath_regulatory *reg = &sc->sc_ah->regulatory;
+	struct ath_regulatory *reg = &sc->common.regulatory;
 
 	return ath_reg_notifier_apply(wiphy, request, reg);
 }
 
-static int ath_init(u16 devid, struct ath_softc *sc)
+/*
+ * Initialize and fill ath_softc, ath_sofct is the
+ * "Software Carrier" struct. Historically it has existed
+ * to allow the separation between hardware specific
+ * variables (now in ath_hw) and driver specific variables.
+ */
+static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
 {
 	struct ath_hw *ah = NULL;
-	int status;
-	int error = 0, i;
+	int r = 0, i;
 	int csz = 0;
 
 	/* XXX: hardware will not be ready until ath_open() being called */
@@ -1311,6 +1325,8 @@ static int ath_init(u16 devid, struct ath_softc *sc)
 	spin_lock_init(&sc->wiphy_lock);
 	spin_lock_init(&sc->sc_resetlock);
 	spin_lock_init(&sc->sc_serial_rw);
+	spin_lock_init(&sc->ani_lock);
+	spin_lock_init(&sc->sc_pm_lock);
 	mutex_init(&sc->mutex);
 	tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
 	tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
@@ -1322,16 +1338,26 @@ static int ath_init(u16 devid, struct ath_softc *sc)
 	 */
 	ath_read_cachesize(sc, &csz);
 	/* XXX assert csz is non-zero */
-	sc->cachelsz = csz << 2;	/* convert to bytes */
+	sc->common.cachelsz = csz << 2;	/* convert to bytes */
+
+	ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
+	if (!ah) {
+		r = -ENOMEM;
+		goto bad_no_ah;
+	}
+
+	ah->ah_sc = sc;
+	ah->hw_version.devid = devid;
+	ah->hw_version.subsysid = subsysid;
+	sc->sc_ah = ah;
 
-	ah = ath9k_hw_attach(devid, sc, &status);
-	if (ah == NULL) {
+	r = ath9k_hw_init(ah);
+	if (r) {
 		DPRINTF(sc, ATH_DBG_FATAL,
-			"Unable to attach hardware; HAL status %d\n", status);
-		error = -ENXIO;
+			"Unable to initialize hardware; "
+			"initialization status: %d\n", r);
 		goto bad;
 	}
-	sc->sc_ah = ah;
 
 	/* Get the hardware key cache size. */
 	sc->keymax = ah->caps.keycache_size;
@@ -1349,9 +1375,6 @@ static int ath_init(u16 devid, struct ath_softc *sc)
 	for (i = 0; i < sc->keymax; i++)
 		ath9k_hw_keyreset(ah, (u16) i);
 
-	if (error)
-		goto bad;
-
 	/* default to MONITOR mode */
 	sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
 
@@ -1371,14 +1394,14 @@ static int ath_init(u16 devid, struct ath_softc *sc)
 	if (sc->beacon.beaconq == -1) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to setup a beacon xmit queue\n");
-		error = -EIO;
+		r = -EIO;
 		goto bad2;
 	}
 	sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
 	if (sc->beacon.cabq == NULL) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to setup CAB xmit queue\n");
-		error = -EIO;
+		r = -EIO;
 		goto bad2;
 	}
 
@@ -1393,26 +1416,26 @@ static int ath_init(u16 devid, struct ath_softc *sc)
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to setup xmit queue for BK traffic\n");
-		error = -EIO;
+		r = -EIO;
 		goto bad2;
 	}
 
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to setup xmit queue for BE traffic\n");
-		error = -EIO;
+		r = -EIO;
 		goto bad2;
 	}
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to setup xmit queue for VI traffic\n");
-		error = -EIO;
+		r = -EIO;
 		goto bad2;
 	}
 	if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
 		DPRINTF(sc, ATH_DBG_FATAL,
 			"Unable to setup xmit queue for VO traffic\n");
-		error = -EIO;
+		r = -EIO;
 		goto bad2;
 	}
 
@@ -1496,8 +1519,11 @@ static int ath_init(u16 devid, struct ath_softc *sc)
 			ARRAY_SIZE(ath9k_5ghz_chantable);
 	}
 
-	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
-		ath9k_hw_btcoex_enable(sc->sc_ah);
+	if (sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) {
+		r = ath9k_hw_btcoex_init(ah);
+		if (r)
+			goto bad2;
+	}
 
 	return 0;
 bad2:
@@ -1506,11 +1532,12 @@ bad2:
 		if (ATH_TXQ_SETUP(sc, i))
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 bad:
-	if (ah)
-		ath9k_hw_detach(ah);
+	ath9k_hw_detach(ah);
+	sc->sc_ah = NULL;
+bad_no_ah:
 	ath9k_exit_debug(sc);
 
-	return error;
+	return r;
 }
 
 void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
@@ -1536,7 +1563,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 	hw->max_rates = 4;
 	hw->channel_change_time = 5000;
 	hw->max_listen_interval = 10;
-	hw->max_rate_tries = ATH_11N_TXMAXTRY;
+	/* Hardware supports 10 but we use 4 */
+	hw->max_rate_tries = 4;
 	hw->sta_data_size = sizeof(struct ath_node);
 	hw->vif_data_size = sizeof(struct ath_vif);
 
@@ -1549,7 +1577,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
 			&sc->sbands[IEEE80211_BAND_5GHZ];
 }
 
-int ath_attach(u16 devid, struct ath_softc *sc)
+/* Device driver core initialization */
+int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid)
 {
 	struct ieee80211_hw *hw = sc->hw;
 	int error = 0, i;
@@ -1557,7 +1586,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
 
 	DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
 
-	error = ath_init(devid, sc);
+	error = ath_init_softc(devid, sc, subsysid);
 	if (error != 0)
 		return error;
 
@@ -1567,12 +1596,12 @@ int ath_attach(u16 devid, struct ath_softc *sc)
 
 	ath_set_hw_capab(sc, hw);
 
-	error = ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy,
+	error = ath_regd_init(&sc->common.regulatory, sc->hw->wiphy,
 			      ath9k_reg_notifier);
 	if (error)
 		return error;
 
-	reg = &sc->sc_ah->regulatory;
+	reg = &sc->common.regulatory;
 
 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
 		setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
@@ -1615,6 +1644,7 @@ error_attach:
 			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
 
 	ath9k_hw_detach(sc->sc_ah);
+	sc->sc_ah = NULL;
 	ath9k_exit_debug(sc);
 
 	return error;
@@ -1850,7 +1880,7 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
 
 	if (chan->band == IEEE80211_BAND_2GHZ) {
 		ichan->chanmode = CHANNEL_G;
-		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
+		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
 	} else {
 		ichan->chanmode = CHANNEL_A;
 		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
@@ -1973,6 +2003,19 @@ static int ath9k_start(struct ieee80211_hw *hw)
 
 	ieee80211_wake_queues(hw);
 
+	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+
+	if ((sc->btcoex_info.btcoex_scheme != ATH_BTCOEX_CFG_NONE) &&
+	    !(sc->sc_flags & SC_OP_BTCOEX_ENABLED)) {
+		ath_btcoex_set_weight(&sc->btcoex_info, AR_BT_COEX_WGHT,
+				      AR_STOMP_LOW_WLAN_WGHT);
+		ath9k_hw_btcoex_enable(sc->sc_ah);
+
+		ath_pcie_aspm_disable(sc);
+		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+			ath_btcoex_timer_resume(sc, &sc->btcoex_info);
+	}
+
 mutex_unlock:
 	mutex_unlock(&sc->mutex);
 
@@ -1994,7 +2037,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
 		goto exit;
 	}
 
-	if (sc->hw->conf.flags & IEEE80211_CONF_PS) {
+	if (sc->ps_enabled) {
 		struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 		/*
 		 * mac80211 does not set PM field for normal data frames, so we
@@ -2083,22 +2126,35 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 
+	mutex_lock(&sc->mutex);
+
 	aphy->state = ATH_WIPHY_INACTIVE;
 
+	cancel_delayed_work_sync(&sc->ath_led_blink_work);
+	cancel_delayed_work_sync(&sc->tx_complete_work);
+
+	if (!sc->num_sec_wiphy) {
+		cancel_delayed_work_sync(&sc->wiphy_work);
+		cancel_work_sync(&sc->chan_work);
+	}
+
 	if (sc->sc_flags & SC_OP_INVALID) {
 		DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
+		mutex_unlock(&sc->mutex);
 		return;
 	}
 
-	mutex_lock(&sc->mutex);
-
-	ieee80211_stop_queues(hw);
-
 	if (ath9k_wiphy_started(sc)) {
 		mutex_unlock(&sc->mutex);
 		return; /* another wiphy still in use */
 	}
 
+	if (sc->sc_flags & SC_OP_BTCOEX_ENABLED) {
+		ath9k_hw_btcoex_disable(sc->sc_ah);
+		if (sc->btcoex_info.btcoex_scheme == ATH_BTCOEX_CFG_3WIRE)
+			ath_btcoex_timer_pause(sc, &sc->btcoex_info);
+	}
+
 	/* make sure h/w will not generate any interrupt
 	 * before setting the invalid flag. */
 	ath9k_hw_set_interrupts(sc->sc_ah, 0);
@@ -2115,6 +2171,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
 	/* disable HAL and put h/w to sleep */
 	ath9k_hw_disable(sc->sc_ah);
 	ath9k_hw_configpcipowersave(sc->sc_ah, 1);
+	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
 
 	sc->sc_flags |= SC_OP_INVALID;
 
@@ -2189,14 +2246,15 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
 	if ((conf->type == NL80211_IFTYPE_STATION) ||
 	    (conf->type == NL80211_IFTYPE_ADHOC) ||
 	    (conf->type == NL80211_IFTYPE_MESH_POINT)) {
-		if (ath9k_hw_phycounters(sc->sc_ah))
-			sc->imask |= ATH9K_INT_MIB;
+		sc->imask |= ATH9K_INT_MIB;
 		sc->imask |= ATH9K_INT_TSFOOR;
 	}
 
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
-	if (conf->type == NL80211_IFTYPE_AP)
+	if (conf->type == NL80211_IFTYPE_AP    ||
+	    conf->type == NL80211_IFTYPE_ADHOC ||
+	    conf->type == NL80211_IFTYPE_MONITOR)
 		ath_start_ani(sc);
 
 out:
@@ -2249,9 +2307,28 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 	struct ath_softc *sc = aphy->sc;
 	struct ieee80211_conf *conf = &hw->conf;
 	struct ath_hw *ah = sc->sc_ah;
+	bool all_wiphys_idle = false, disable_radio = false;
 
 	mutex_lock(&sc->mutex);
 
+	/* Leave this as the first check */
+	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+
+		spin_lock_bh(&sc->wiphy_lock);
+		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
+		spin_unlock_bh(&sc->wiphy_lock);
+
+		if (conf->flags & IEEE80211_CONF_IDLE){
+			if (all_wiphys_idle)
+				disable_radio = true;
+		}
+		else if (all_wiphys_idle) {
+			ath_radio_enable(sc);
+			DPRINTF(sc, ATH_DBG_CONFIG,
+				"not-idle: enabling radio\n");
+		}
+	}
+
 	if (changed & IEEE80211_CONF_CHANGE_PS) {
 		if (conf->flags & IEEE80211_CONF_PS) {
 			if (!(ah->caps.hw_caps &
@@ -2263,8 +2340,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 				}
 				ath9k_hw_setrxabort(sc->sc_ah, 1);
 			}
-			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+			sc->ps_enabled = true;
 		} else {
+			sc->ps_enabled = false;
 			ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
 			if (!(ah->caps.hw_caps &
 			      ATH9K_HW_CAP_AUTOSLEEP)) {
@@ -2319,6 +2397,11 @@ skip_chan_change:
 	if (changed & IEEE80211_CONF_CHANGE_POWER)
 		sc->config.txpowlimit = 2 * conf->power_level;
 
+	if (disable_radio) {
+		DPRINTF(sc, ATH_DBG_CONFIG, "idle: disabling radio\n");
+		ath_radio_disable(sc);
+	}
+
 	mutex_unlock(&sc->mutex);
 
 	return 0;
@@ -2328,6 +2411,7 @@ skip_chan_change:
 	(FIF_PROMISC_IN_BSS |			\
 	FIF_ALLMULTI |				\
 	FIF_CONTROL |				\
+	FIF_PSPOLL |				\
 	FIF_OTHER_BSS |				\
 	FIF_BCN_PRBRESP_PROMISC |		\
 	FIF_FCSFAIL)
@@ -2336,8 +2420,7 @@ skip_chan_change:
 static void ath9k_configure_filter(struct ieee80211_hw *hw,
 				   unsigned int changed_flags,
 				   unsigned int *total_flags,
-				   int mc_count,
-				   struct dev_mc_list *mclist)
+				   u64 multicast)
 {
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
@@ -2352,7 +2435,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
 	ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
 	ath9k_ps_restore(sc);
 
-	DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
+	DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", rfilt);
 }
 
 static void ath9k_sta_notify(struct ieee80211_hw *hw,
@@ -2638,19 +2721,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 	case IEEE80211_AMPDU_RX_STOP:
 		break;
 	case IEEE80211_AMPDU_TX_START:
-		ret = ath_tx_aggr_start(sc, sta, tid, ssn);
-		if (ret < 0)
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"Unable to start TX aggregation\n");
-		else
-			ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+		ath_tx_aggr_start(sc, sta, tid, ssn);
+		ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
 		break;
 	case IEEE80211_AMPDU_TX_STOP:
-		ret = ath_tx_aggr_stop(sc, sta, tid);
-		if (ret < 0)
-			DPRINTF(sc, ATH_DBG_FATAL,
-				"Unable to stop TX aggregation\n");
-
+		ath_tx_aggr_stop(sc, sta, tid);
 		ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
 		break;
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
@@ -2668,6 +2743,7 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 
+	mutex_lock(&sc->mutex);
 	if (ath9k_wiphy_scanning(sc)) {
 		printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
 		       "same time\n");
@@ -2675,14 +2751,16 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
 		 * Do not allow the concurrent scanning state for now. This
 		 * could be improved with scanning control moved into ath9k.
 		 */
+		mutex_unlock(&sc->mutex);
 		return;
 	}
 
 	aphy->state = ATH_WIPHY_SCAN;
 	ath9k_wiphy_pause_all_forced(sc, aphy);
 
-	mutex_lock(&sc->mutex);
+	spin_lock_bh(&sc->ani_lock);
 	sc->sc_flags |= SC_OP_SCANNING;
+	spin_unlock_bh(&sc->ani_lock);
 	mutex_unlock(&sc->mutex);
 }
 
@@ -2692,9 +2770,12 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
 	struct ath_softc *sc = aphy->sc;
 
 	mutex_lock(&sc->mutex);
+	spin_lock_bh(&sc->ani_lock);
 	aphy->state = ATH_WIPHY_ACTIVE;
 	sc->sc_flags &= ~SC_OP_SCANNING;
 	sc->sc_flags |= SC_OP_FULL_RESET;
+	spin_unlock_bh(&sc->ani_lock);
+	ath_beacon_config(sc, NULL);
 	mutex_unlock(&sc->mutex);
 }
 
@@ -2728,7 +2809,8 @@ static struct {
 	{ AR_SREV_VERSION_9100,		"9100" },
 	{ AR_SREV_VERSION_9160,		"9160" },
 	{ AR_SREV_VERSION_9280,		"9280" },
-	{ AR_SREV_VERSION_9285,		"9285" }
+	{ AR_SREV_VERSION_9285,		"9285" },
+	{ AR_SREV_VERSION_9287,         "9287" }
 };
 
 static struct {
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 170c5b3..903dd8a 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -25,6 +25,8 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = {
 	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
 	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
 	{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
+	{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI   */
+	{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
 	{ 0 }
 };
 
@@ -33,8 +35,7 @@ static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
 {
 	u8 u8tmp;
 
-	pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
-			     (u8 *)&u8tmp);
+	pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, &u8tmp);
 	*csz = (int)u8tmp;
 
 	/*
@@ -87,6 +88,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	struct ath_softc *sc;
 	struct ieee80211_hw *hw;
 	u8 csz;
+	u16 subsysid;
 	u32 val;
 	int ret = 0;
 	struct ath_hw *ah;
@@ -158,8 +160,9 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
 				sizeof(struct ath_softc), &ath9k_ops);
-	if (hw == NULL) {
-		printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
+	if (!hw) {
+		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+		ret = -ENOMEM;
 		goto bad2;
 	}
 
@@ -176,17 +179,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	sc->mem = mem;
 	sc->bus_ops = &ath_pci_bus_ops;
 
-	if (ath_attach(id->device, sc) != 0) {
-		ret = -ENODEV;
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
+	ret = ath_init_device(id->device, sc, subsysid);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize device\n");
 		goto bad3;
 	}
 
 	/* setup interrupt service routine */
 
-	if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
-		printk(KERN_ERR "%s: request_irq failed\n",
-			wiphy_name(hw->wiphy));
-		ret = -EIO;
+	ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
+	if (ret) {
+		dev_err(&pdev->dev, "request_irq failed\n");
 		goto bad4;
 	}
 
@@ -234,7 +238,7 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
 
-	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
@@ -251,10 +255,12 @@ static int ath_pci_resume(struct pci_dev *pdev)
 	u32 val;
 	int err;
 
+	pci_restore_state(pdev);
+
 	err = pci_enable_device(pdev);
 	if (err)
 		return err;
-	pci_restore_state(pdev);
+
 	/*
 	 * Suspend/Resume resets the PCI configuration space, so we have to
 	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
@@ -265,9 +271,9 @@ static int ath_pci_resume(struct pci_dev *pdev)
 		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
 
 	/* Enable LED */
-	ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+	ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
 			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-	ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index aaa9415..63bf9a3 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -264,44 +264,23 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
 }
 
 void
-ath9k_hw_rfdetach(struct ath_hw *ah)
+ath9k_hw_rf_free(struct ath_hw *ah)
 {
-	if (ah->analogBank0Data != NULL) {
-		kfree(ah->analogBank0Data);
-		ah->analogBank0Data = NULL;
-	}
-	if (ah->analogBank1Data != NULL) {
-		kfree(ah->analogBank1Data);
-		ah->analogBank1Data = NULL;
-	}
-	if (ah->analogBank2Data != NULL) {
-		kfree(ah->analogBank2Data);
-		ah->analogBank2Data = NULL;
-	}
-	if (ah->analogBank3Data != NULL) {
-		kfree(ah->analogBank3Data);
-		ah->analogBank3Data = NULL;
-	}
-	if (ah->analogBank6Data != NULL) {
-		kfree(ah->analogBank6Data);
-		ah->analogBank6Data = NULL;
-	}
-	if (ah->analogBank6TPCData != NULL) {
-		kfree(ah->analogBank6TPCData);
-		ah->analogBank6TPCData = NULL;
-	}
-	if (ah->analogBank7Data != NULL) {
-		kfree(ah->analogBank7Data);
-		ah->analogBank7Data = NULL;
-	}
-	if (ah->addac5416_21 != NULL) {
-		kfree(ah->addac5416_21);
-		ah->addac5416_21 = NULL;
-	}
-	if (ah->bank6Temp != NULL) {
-		kfree(ah->bank6Temp);
-		ah->bank6Temp = NULL;
-	}
+#define ATH_FREE_BANK(bank) do { \
+		kfree(bank); \
+		bank = NULL; \
+	} while (0);
+
+	ATH_FREE_BANK(ah->analogBank0Data);
+	ATH_FREE_BANK(ah->analogBank1Data);
+	ATH_FREE_BANK(ah->analogBank2Data);
+	ATH_FREE_BANK(ah->analogBank3Data);
+	ATH_FREE_BANK(ah->analogBank6Data);
+	ATH_FREE_BANK(ah->analogBank6TPCData);
+	ATH_FREE_BANK(ah->analogBank7Data);
+	ATH_FREE_BANK(ah->addac5416_21);
+	ATH_FREE_BANK(ah->bank6Temp);
+#undef ATH_FREE_BANK
 }
 
 bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
@@ -374,18 +353,16 @@ ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
 	u32 bank6SelMask;
 	u32 *bank6Temp = ah->bank6Temp;
 
-	switch (ah->diversity_control) {
+	switch (ah->config.diversity_control) {
 	case ATH9K_ANT_FIXED_A:
 		bank6SelMask =
-		    (ah->
-		     antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
-		    REDUCE_CHAIN_1;
+		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
+			REDUCE_CHAIN_0 : REDUCE_CHAIN_1;
 		break;
 	case ATH9K_ANT_FIXED_B:
 		bank6SelMask =
-		    (ah->
-		     antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
-		    REDUCE_CHAIN_0;
+		    (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
+			REDUCE_CHAIN_1 : REDUCE_CHAIN_0;
 		break;
 	case ATH9K_ANT_VARIABLE:
 		return;
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index c70f530..dfda6f4 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -185,6 +185,9 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_PLL_CTL_44_2133  0xeb
 #define AR_PHY_PLL_CTL_40_2133  0xea
 
+#define AR_PHY_SPECTRAL_SCAN		0x9912
+#define AR_PHY_SPECTRAL_SCAN_ENABLE	0x1
+
 #define AR_PHY_RX_DELAY           0x9914
 #define AR_PHY_SEARCH_START_DELAY 0x9918
 #define AR_PHY_RX_DELAY_DELAY     0x00003FFF
@@ -309,7 +312,25 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
 #define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
 #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
-#define AR_PHY_MULTICHAIN_GAIN_CTL  0x99ac
+
+#define AR_PHY_MULTICHAIN_GAIN_CTL          0x99ac
+#define AR_PHY_9285_ANT_DIV_CTL_ALL         0x7f000000
+#define AR_PHY_9285_ANT_DIV_CTL             0x01000000
+#define AR_PHY_9285_ANT_DIV_CTL_S           24
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF     0x06000000
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S   25
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF    0x18000000
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S  27
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB      0x20000000
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S    29
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB     0x40000000
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S   30
+#define AR_PHY_9285_ANT_DIV_LNA1            2
+#define AR_PHY_9285_ANT_DIV_LNA2            1
+#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2  3
+#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
+#define AR_PHY_9285_ANT_DIV_GAINTB_0        0
+#define AR_PHY_9285_ANT_DIV_GAINTB_1        1
 
 #define AR_PHY_EXT_CCA0             0x99b8
 #define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
@@ -375,6 +396,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_CHAN_INFO_GAIN          0x9CFC
 
 #define AR_PHY_MODE         0xA200
+#define AR_PHY_MODE_ASYNCFIFO 0x80
 #define AR_PHY_MODE_AR2133  0x08
 #define AR_PHY_MODE_AR5111  0x00
 #define AR_PHY_MODE_AR5112  0x08
@@ -397,6 +419,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
 #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
 #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S  13
 
 #define AR_PHY_GAIN_2GHZ                0xA20C
 #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
@@ -467,11 +490,18 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
 #define AR_PHY_TX_PWRCTRL9       0xa27C
 #define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
 #define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL  0x80000000
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
 
 #define AR_PHY_TX_GAIN_TBL1      0xa300
 #define AR_PHY_TX_GAIN                     0x0007F000
 #define AR_PHY_TX_GAIN_S                   12
 
+#define AR_PHY_CH0_TX_PWRCTRL11  0xa398
+#define AR_PHY_CH1_TX_PWRCTRL11  0xb398
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP   0x0000FC00
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
+
 #define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
 #define AR_PHY_MASK2_M_31_45     0xa3a4
 #define AR_PHY_MASK2_M_16_30     0xa3a8
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ba06e78..16a2717 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -22,133 +22,132 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
 	{
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0x0b, 0x00, 12,
-			0, 2, 1, 0, 0, 0, 0, 0 },
+			0, 0, 0, 0, 0, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800,  0x0f, 0x00, 18,
-			0, 3, 1, 1, 1, 1, 1, 0 },
+			0, 1, 1, 1, 1, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 0x0a, 0x00, 24,
-			2, 4, 2, 2, 2, 2, 2, 0 },
+			2, 2, 2, 2, 2, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 0x0e, 0x00, 36,
-			2, 6,  2, 3, 3, 3, 3, 0 },
+			2,  3, 3, 3, 3, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 0x09, 0x00, 48,
-			4, 10, 3, 4, 4, 4, 4, 0 },
+			4,  4, 4, 4, 4, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 0x0d, 0x00, 72,
-			4, 14, 3, 5, 5, 5, 5, 0 },
+			4,  5, 5, 5, 5, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 0x08, 0x00, 96,
-			4, 20, 3, 6, 6, 6, 6, 0 },
+			4,  6, 6, 6, 6, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 0x0c, 0x00, 108,
-			4, 23, 3, 7, 7, 7, 7, 0 },
-		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
+			4,  7, 7, 7, 7, 0 },
+		{ VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
 			6400, 0x80, 0x00, 0,
-			0, 2, 3, 8, 24, 8, 24, 3216 },
+			0, 8, 24, 8, 24, 3216 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
 			12700, 0x81, 0x00, 1,
-			2, 4, 3, 9, 25, 9, 25, 6434 },
+			2, 9, 25, 9, 25, 6434 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
 			18800, 0x82, 0x00, 2,
-			2, 6, 3, 10, 26, 10, 26, 9650 },
+			2, 10, 26, 10, 26, 9650 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
 			25000, 0x83, 0x00, 3,
-			4, 10, 3, 11, 27, 11, 27, 12868 },
+			4,  11, 27, 11, 27, 12868 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
 			36700, 0x84, 0x00, 4,
-			4, 14, 3, 12, 28, 12, 28, 19304 },
+			4,  12, 28, 12, 28, 19304 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
 			48100, 0x85, 0x00, 5,
-			4, 20, 3, 13, 29, 13, 29, 25740 },
+			4,  13, 29, 13, 29, 25740 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
 			53500, 0x86, 0x00, 6,
-			4, 23, 3, 14, 30, 14, 30,  28956 },
+			4,  14, 30, 14, 30,  28956 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
 			59000, 0x87, 0x00, 7,
-			4, 25, 3, 15, 31, 15, 32, 32180 },
+			4,  15, 31, 15, 32, 32180 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
 			12700, 0x88, 0x00,
-			8, 0, 2, 3, 16, 33, 16, 33, 6430 },
+			8, 3, 16, 33, 16, 33, 6430 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
 			24800, 0x89, 0x00, 9,
-			2, 4, 3, 17, 34, 17, 34, 12860 },
+			2, 17, 34, 17, 34, 12860 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
 			36600, 0x8a, 0x00, 10,
-			2, 6, 3, 18, 35, 18, 35, 19300 },
+			2, 18, 35, 18, 35, 19300 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
 			48100, 0x8b, 0x00, 11,
-			4, 10, 3, 19, 36, 19, 36, 25736 },
+			4,  19, 36, 19, 36, 25736 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
 			69500, 0x8c, 0x00, 12,
-			4, 14, 3, 20, 37, 20, 37, 38600 },
+			4,  20, 37, 20, 37, 38600 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
 			89500, 0x8d, 0x00, 13,
-			4, 20, 3, 21, 38, 21, 38, 51472 },
+			4,  21, 38, 21, 38, 51472 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
 			98900, 0x8e, 0x00, 14,
-			4, 23, 3, 22, 39, 22, 39, 57890 },
+			4,  22, 39, 22, 39, 57890 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
 			108300, 0x8f, 0x00, 15,
-			4, 25, 3, 23, 40, 23, 41, 64320 },
+			4,  23, 40, 23, 41, 64320 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
 			13200, 0x80, 0x00, 0,
-			0, 2, 3, 8, 24, 24, 24, 6684 },
+			0, 8, 24, 24, 24, 6684 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
 			25900, 0x81, 0x00, 1,
-			2, 4, 3, 9, 25, 25, 25, 13368 },
+			2, 9, 25, 25, 25, 13368 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
 			38600, 0x82, 0x00, 2,
-			2, 6, 3, 10, 26, 26, 26, 20052 },
+			2, 10, 26, 26, 26, 20052 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
 			49800, 0x83, 0x00, 3,
-			4, 10, 3, 11, 27, 27, 27, 26738 },
+			4,  11, 27, 27, 27, 26738 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
 			72200, 0x84, 0x00, 4,
-			4, 14, 3, 12, 28, 28, 28, 40104 },
+			4,  12, 28, 28, 28, 40104 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
 			92900, 0x85, 0x00, 5,
-			4, 20, 3, 13, 29, 29, 29, 53476 },
+			4,  13, 29, 29, 29, 53476 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
 			102700, 0x86, 0x00, 6,
-			4, 23, 3, 14, 30, 30, 30, 60156 },
+			4,  14, 30, 30, 30, 60156 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
 			112000, 0x87, 0x00, 7,
-			4, 25, 3, 15, 31, 32, 32, 66840 },
+			4,  15, 31, 32, 32, 66840 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
 			122000, 0x87, 0x00, 7,
-			4, 25, 3, 15, 31, 32, 32, 74200 },
+			4,  15, 31, 32, 32, 74200 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
 			25800, 0x88, 0x00, 8,
-			0, 2, 3, 16, 33, 33, 33, 13360 },
+			0, 16, 33, 33, 33, 13360 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
 			49800, 0x89, 0x00, 9,
-			2, 4, 3, 17, 34, 34, 34, 26720 },
+			2, 17, 34, 34, 34, 26720 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
 			71900, 0x8a, 0x00, 10,
-			2, 6, 3, 18, 35, 35, 35, 40080 },
+			2, 18, 35, 35, 35, 40080 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
 			92500, 0x8b, 0x00, 11,
-			4, 10, 3, 19, 36, 36, 36, 53440 },
+			4,  19, 36, 36, 36, 53440 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
 			130300, 0x8c, 0x00, 12,
-			4, 14, 3, 20, 37, 37, 37, 80160 },
+			4,  20, 37, 37, 37, 80160 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
 			162800, 0x8d, 0x00, 13,
-			4, 20, 3, 21, 38, 38, 38, 106880 },
+			4,  21, 38, 38, 38, 106880 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
 			178200, 0x8e, 0x00, 14,
-			4, 23, 3, 22, 39, 39, 39, 120240 },
+			4,  22, 39, 39, 39, 120240 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
 			192100, 0x8f, 0x00, 15,
-			4, 25, 3, 23, 40, 41, 41, 133600 },
+			4,  23, 40, 41, 41, 133600 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
 			207000, 0x8f, 0x00, 15,
-			4, 25, 3, 23, 40, 41, 41, 148400 },
+			4,  23, 40, 41, 41, 148400 },
 	},
 	50,  /* probe interval */
-	50,  /* rssi reduce interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
 };
 
@@ -160,145 +159,144 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
 	{
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0x1b, 0x00, 2,
-			0, 0, 1, 0, 0, 0, 0, 0 },
+			0, 0, 0, 0, 0, 0 },
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
 			1900, 0x1a, 0x04, 4,
-			1, 1, 1, 1, 1, 1, 1, 0 },
+			1, 1, 1, 1, 1, 0 },
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
 			4900, 0x19, 0x04, 11,
-			2, 2, 2, 2, 2, 2, 2, 0 },
+			2, 2, 2, 2, 2, 0 },
 		{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
 			8100, 0x18, 0x04, 22,
-			3, 3, 2, 3, 3, 3, 3, 0 },
+			3, 3, 3, 3, 3, 0 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0x0b, 0x00, 12,
-			4, 2, 1, 4, 4, 4, 4, 0 },
+			4, 4, 4, 4, 4, 0 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800, 0x0f, 0x00, 18,
-			4, 3, 1, 5, 5, 5, 5, 0 },
+			4, 5, 5, 5, 5, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10100, 0x0a, 0x00, 24,
-			6, 4, 1, 6, 6, 6, 6, 0 },
+			6, 6, 6, 6, 6, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			14100,  0x0e, 0x00, 36,
-			6, 6, 2, 7, 7, 7, 7, 0 },
+			6, 7, 7, 7, 7, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17700, 0x09, 0x00, 48,
-			8, 10, 3, 8, 8, 8, 8, 0 },
+			8,  8, 8, 8, 8, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23700, 0x0d, 0x00, 72,
-			8, 14, 3, 9, 9, 9, 9, 0 },
+			8,  9, 9, 9, 9, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 0x08, 0x00, 96,
-			8, 20, 3, 10, 10, 10, 10, 0 },
+			8,  10, 10, 10, 10, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			30900, 0x0c, 0x00, 108,
-			8, 23, 3, 11, 11, 11, 11, 0 },
+			8,  11, 11, 11, 11, 0 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
 			6400, 0x80, 0x00, 0,
-			4, 2, 3, 12, 28, 12, 28, 3216 },
+			4, 12, 28, 12, 28, 3216 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
 			12700, 0x81, 0x00, 1,
-			6, 4, 3, 13, 29, 13, 29, 6434 },
+			6, 13, 29, 13, 29, 6434 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
 			18800, 0x82, 0x00, 2,
-			6, 6, 3, 14, 30, 14, 30, 9650 },
+			6, 14, 30, 14, 30, 9650 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
 			25000, 0x83, 0x00, 3,
-			8, 10, 3, 15, 31, 15, 31, 12868 },
+			8,  15, 31, 15, 31, 12868 },
 		{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
 			36700, 0x84, 0x00, 4,
-			8, 14, 3, 16, 32, 16, 32, 19304 },
+			8,  16, 32, 16, 32, 19304 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
 			48100, 0x85, 0x00, 5,
-			8, 20, 3, 17, 33, 17, 33, 25740 },
+			8,  17, 33, 17, 33, 25740 },
 		{ INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
 			53500, 0x86, 0x00, 6,
-			8, 23, 3, 18, 34, 18, 34, 28956 },
+			8,  18, 34, 18, 34, 28956 },
 		{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
 			59000, 0x87, 0x00, 7,
-			8, 25, 3, 19, 35, 19, 36, 32180 },
+			8,  19, 35, 19, 36, 32180 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
 			12700, 0x88, 0x00, 8,
-			4, 2, 3, 20, 37, 20, 37, 6430 },
+			4, 20, 37, 20, 37, 6430 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
 			24800, 0x89, 0x00, 9,
-			6, 4, 3, 21, 38, 21, 38, 12860 },
+			6, 21, 38, 21, 38, 12860 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
 			36600, 0x8a, 0x00, 10,
-			6, 6, 3, 22, 39, 22, 39, 19300 },
+			6, 22, 39, 22, 39, 19300 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
 			48100, 0x8b, 0x00, 11,
-			8, 10, 3, 23, 40, 23, 40, 25736 },
+			8,  23, 40, 23, 40, 25736 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
 			69500, 0x8c, 0x00, 12,
-			8, 14, 3, 24, 41, 24, 41, 38600 },
+			8,  24, 41, 24, 41, 38600 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
 			89500, 0x8d, 0x00, 13,
-			8, 20, 3, 25, 42, 25, 42, 51472 },
+			8,  25, 42, 25, 42, 51472 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
 			98900, 0x8e, 0x00, 14,
-			8, 23, 3, 26, 43, 26, 44, 57890 },
+			8,  26, 43, 26, 44, 57890 },
 		{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
 			108300, 0x8f, 0x00, 15,
-			8, 25, 3, 27, 44, 27, 45, 64320 },
+			8,  27, 44, 27, 45, 64320 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
 			13200, 0x80, 0x00, 0,
-			8, 2, 3, 12, 28, 28, 28, 6684 },
+			8, 12, 28, 28, 28, 6684 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
 			25900, 0x81, 0x00, 1,
-			8, 4, 3, 13, 29, 29, 29, 13368 },
+			8, 13, 29, 29, 29, 13368 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
 			38600, 0x82, 0x00, 2,
-			8, 6, 3, 14, 30, 30, 30, 20052 },
+			8, 14, 30, 30, 30, 20052 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
 			49800, 0x83, 0x00, 3,
-			8, 10, 3, 15, 31, 31, 31, 26738 },
+			8,  15, 31, 31, 31, 26738 },
 		{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
 			72200, 0x84, 0x00, 4,
-			8, 14, 3, 16, 32, 32, 32, 40104 },
+			8,  16, 32, 32, 32, 40104 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
 			92900, 0x85, 0x00, 5,
-			8, 20, 3, 17, 33, 33, 33, 53476 },
+			8,  17, 33, 33, 33, 53476 },
 		{ INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
 			102700, 0x86, 0x00, 6,
-			8, 23, 3, 18, 34, 34, 34, 60156 },
+			8,  18, 34, 34, 34, 60156 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
 			112000, 0x87, 0x00, 7,
-			8, 23, 3, 19, 35, 36, 36, 66840 },
+			8,  19, 35, 36, 36, 66840 },
 		{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
 			122000, 0x87, 0x00, 7,
-			8, 25, 3, 19, 35, 36, 36, 74200 },
+			8,  19, 35, 36, 36, 74200 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
 			25800, 0x88, 0x00, 8,
-			8, 2, 3, 20, 37, 37, 37, 13360 },
+			8, 20, 37, 37, 37, 13360 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
 			49800, 0x89, 0x00, 9,
-			8, 4, 3, 21, 38, 38, 38, 26720 },
+			8, 21, 38, 38, 38, 26720 },
 		{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
 			71900, 0x8a, 0x00, 10,
-			8, 6, 3, 22, 39, 39, 39, 40080 },
+			8, 22, 39, 39, 39, 40080 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
 			92500, 0x8b, 0x00, 11,
-			8, 10, 3, 23, 40, 40, 40, 53440 },
+			8,  23, 40, 40, 40, 53440 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
 			130300, 0x8c, 0x00, 12,
-			8, 14, 3, 24, 41, 41, 41, 80160 },
+			8,  24, 41, 41, 41, 80160 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
 			162800, 0x8d, 0x00, 13,
-			8, 20, 3, 25, 42, 42, 42, 106880 },
+			8,  25, 42, 42, 42, 106880 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
 			178200, 0x8e, 0x00, 14,
-			8, 23, 3, 26, 43, 43, 43, 120240 },
+			8,  26, 43, 43, 43, 120240 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
 			192100, 0x8f, 0x00, 15,
-			8, 23, 3, 27, 44, 45, 45, 133600 },
+			8,  27, 44, 45, 45, 133600 },
 		{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
 			207000, 0x8f, 0x00, 15,
-			8, 25, 3, 27, 44, 45, 45, 148400 },
+			8,  27, 44, 45, 45, 148400 },
 		},
 	50,  /* probe interval */
-	50,  /* rssi reduce interval */
 	WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
 };
 
@@ -307,31 +305,30 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
 	{
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0x0b, 0x00, (0x80|12),
-			0, 2, 1, 0, 0 },
+			0, 0, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800, 0x0f, 0x00, 18,
-			0, 3, 1, 1, 0 },
+			0, 1, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 0x0a, 0x00, (0x80|24),
-			2, 4, 2, 2, 0 },
+			2, 2, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 0x0e, 0x00, 36,
-			2, 6, 2, 3, 0 },
+			2, 3, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 0x09, 0x00, (0x80|48),
-			4, 10, 3, 4, 0 },
+			4,  4, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 0x0d, 0x00, 72,
-			4, 14, 3, 5, 0 },
+			4,  5, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 0x08, 0x00, 96,
-			4, 19, 3, 6, 0 },
+			4,  6, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 0x0c, 0x00, 108,
-			4, 23, 3, 7, 0 },
+			4,  7, 0 },
 	},
 	50,  /* probe interval */
-	50,  /* rssi reduce interval */
 	0,   /* Phy rates allowed initially */
 };
 
@@ -340,64 +337,42 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
 	{
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
 			900, 0x1b, 0x00, 2,
-			0, 0, 1, 0, 0 },
+			0, 0, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
 			1900, 0x1a, 0x04, 4,
-			1, 1, 1, 1, 0 },
+			1, 1, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
 			4900, 0x19, 0x04, 11,
-			2, 2, 2, 2, 0 },
+			2, 2, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
 			8100, 0x18, 0x04, 22,
-			3, 3, 2, 3, 0 },
+			3, 3, 0 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
 			5400, 0x0b, 0x00, 12,
-			4, 2, 1, 4, 0 },
+			4, 4, 0 },
 		{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
 			7800, 0x0f, 0x00, 18,
-			4, 3, 1, 5, 0 },
+			4, 5, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
 			10000, 0x0a, 0x00, 24,
-			6, 4, 1, 6, 0 },
+			6, 6, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
 			13900, 0x0e, 0x00, 36,
-			6, 6, 2, 7, 0 },
+			6, 7, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
 			17300, 0x09, 0x00, 48,
-			8, 10, 3, 8, 0 },
+			8,  8, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
 			23000, 0x0d, 0x00, 72,
-			8, 14, 3, 9, 0 },
+			8,  9, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
 			27400, 0x08, 0x00, 96,
-			8, 19, 3, 10, 0 },
+			8,  10, 0 },
 		{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
 			29300, 0x0c, 0x00, 108,
-			8, 23, 3, 11, 0 },
+			8,  11, 0 },
 	},
 	50,  /* probe interval */
-	50,  /* rssi reduce interval */
-	0,   /* Phy rates allowed initially */
-};
-
-static const struct ath_rate_table ar5416_11b_ratetable = {
-	4,
-	{
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-			900, 0x1b,  0x00, (0x80|2),
-			0, 0, 1, 0, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-			1800, 0x1a, 0x04, (0x80|4),
-			1, 1, 1, 1, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-			4300, 0x19, 0x04, (0x80|11),
-			1, 2, 2, 2, 0 },
-		{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-			7100, 0x18, 0x04, (0x80|22),
-			1, 4, 100, 3, 0 },
-	},
-	100, /* probe interval */
-	100, /* rssi reduce interval */
 	0,   /* Phy rates allowed initially */
 };
 
@@ -454,13 +429,6 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
 	ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
 }
 
-static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
-					u8 index)
-{
-	ASSERT(index <= ath_rc_priv->rate_table_size);
-	return ath_rc_priv->valid_rate_index[index];
-}
-
 static inline
 int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
 				struct ath_rate_priv *ath_rc_priv,
@@ -495,15 +463,13 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
 	if (!ignore_cw && WLAN_RC_PHY_HT(phy))
 		if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
 			return 0;
-		if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
-			return 0;
 	return 1;
 }
 
 static inline int
-ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table,
-				 struct ath_rate_priv *ath_rc_priv,
-				 u8 cur_valid_txrate, u8 *next_idx)
+ath_rc_get_lower_rix(const struct ath_rate_table *rate_table,
+		     struct ath_rate_priv *ath_rc_priv,
+		     u8 cur_valid_txrate, u8 *next_idx)
 {
 	int8_t i;
 
@@ -629,52 +595,20 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
 	return hi;
 }
 
-static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
-			     struct ath_rate_priv *ath_rc_priv,
-			     const struct ath_rate_table *rate_table,
-			     int *is_probing)
+/* Finds the highest rate index we can use */
+static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
+			         struct ath_rate_priv *ath_rc_priv,
+				 const struct ath_rate_table *rate_table,
+				 int *is_probing)
 {
-	u32 dt, best_thruput, this_thruput, now_msec;
+	u32 best_thruput, this_thruput, now_msec;
 	u8 rate, next_rate, best_rate, maxindex, minindex;
-	int8_t  rssi_last, rssi_reduce = 0, index = 0;
-
-	*is_probing = 0;
-
-	rssi_last = median(ath_rc_priv->rssi_last,
-			   ath_rc_priv->rssi_last_prev,
-			   ath_rc_priv->rssi_last_prev2);
-
-	/*
-	 * Age (reduce) last ack rssi based on how old it is.
-	 * The bizarre numbers are so the delta is 160msec,
-	 * meaning we divide by 16.
-	 *   0msec   <= dt <= 25msec:   don't derate
-	 *   25msec  <= dt <= 185msec:  derate linearly from 0 to 10dB
-	 *   185msec <= dt:             derate by 10dB
-	 */
+	int8_t index = 0;
 
 	now_msec = jiffies_to_msecs(jiffies);
-	dt = now_msec - ath_rc_priv->rssi_time;
-
-	if (dt >= 185)
-		rssi_reduce = 10;
-	else if (dt >= 25)
-		rssi_reduce = (u8)((dt - 25) >> 4);
-
-	/* Now reduce rssi_last by rssi_reduce */
-	if (rssi_last < rssi_reduce)
-		rssi_last = 0;
-	else
-		rssi_last -= rssi_reduce;
-
-	/*
-	 * Now look up the rate in the rssi table and return it.
-	 * If no rates match then we return 0 (lowest rate)
-	 */
-
+	*is_probing = 0;
 	best_thruput = 0;
 	maxindex = ath_rc_priv->max_valid_rate-1;
-
 	minindex = 0;
 	best_rate = minindex;
 
@@ -700,7 +634,7 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
 		 * 10-15 and we would be worse off then staying
 		 * at the current rate.
 		 */
-		per_thres = ath_rc_priv->state[rate].per;
+		per_thres = ath_rc_priv->per[rate];
 		if (per_thres < 12)
 			per_thres = 12;
 
@@ -714,7 +648,6 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
 	}
 
 	rate = best_rate;
-	ath_rc_priv->rssi_last_lookup = rssi_last;
 
 	/*
 	 * Must check the actual rate (ratekbps) to account for
@@ -741,10 +674,18 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
 	if (rate > (ath_rc_priv->rate_table_size - 1))
 		rate = ath_rc_priv->rate_table_size - 1;
 
-	ASSERT((rate_table->info[rate].valid &&
-		(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) ||
-	       (rate_table->info[rate].valid_single_stream &&
-		!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)));
+	if (rate_table->info[rate].valid &&
+	    (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
+		return rate;
+
+	if (rate_table->info[rate].valid_single_stream &&
+	    !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG));
+		return rate;
+
+	/* This should not happen */
+	WARN_ON(1);
+
+	rate = ath_rc_priv->valid_rate_index[0];
 
 	return rate;
 }
@@ -796,7 +737,6 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
 	 * just CTS.  Note that this is only done for OFDM/HT unicast frames.
 	 */
 	if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
-	    !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
 	    (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
 	     WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
 		rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
@@ -806,50 +746,37 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
 	tx_info->control.rts_cts_rate_idx = cix;
 }
 
-static u8 ath_rc_rate_getidx(struct ath_softc *sc,
-			     struct ath_rate_priv *ath_rc_priv,
-			     const struct ath_rate_table *rate_table,
-			     u8 rix, u16 stepdown,
-			     u16 min_rate)
-{
-	u32 j;
-	u8 nextindex = 0;
-
-	if (min_rate) {
-		for (j = RATE_TABLE_SIZE; j > 0; j--) {
-			if (ath_rc_get_nextlowervalid_txrate(rate_table,
-						ath_rc_priv, rix, &nextindex))
-				rix = nextindex;
-			else
-				break;
-		}
-	} else {
-		for (j = stepdown; j > 0; j--) {
-			if (ath_rc_get_nextlowervalid_txrate(rate_table,
-						ath_rc_priv, rix, &nextindex))
-				rix = nextindex;
-			else
-				break;
-		}
-	}
-	return rix;
-}
-
-static void ath_rc_ratefind(struct ath_softc *sc,
-			    struct ath_rate_priv *ath_rc_priv,
-			    struct ieee80211_tx_rate_control *txrc)
+static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+			 struct ieee80211_tx_rate_control *txrc)
 {
+	struct ath_softc *sc = priv;
+	struct ath_rate_priv *ath_rc_priv = priv_sta;
 	const struct ath_rate_table *rate_table;
 	struct sk_buff *skb = txrc->skb;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_rate *rates = tx_info->control.rates;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	__le16 fc = hdr->frame_control;
-	u8 try_per_rate = 0, i = 0, rix, nrix;
+	u8 try_per_rate, i = 0, rix, nrix;
 	int is_probe = 0;
 
+	if (rate_control_send_low(sta, priv_sta, txrc))
+		return;
+
+	/*
+	 * For Multi Rate Retry we use a different number of
+	 * retry attempt counts. This ends up looking like this:
+	 *
+	 * MRR[0] = 2
+	 * MRR[1] = 2
+	 * MRR[2] = 2
+	 * MRR[3] = 4
+	 *
+	 */
+	try_per_rate = sc->hw->max_rate_tries;
+
 	rate_table = sc->cur_rate_table;
-	rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
+	rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
 	nrix = rix;
 
 	if (is_probe) {
@@ -858,18 +785,15 @@ static void ath_rc_ratefind(struct ath_softc *sc,
 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
 				       1, nrix, 0);
 
-		try_per_rate = (ATH_11N_TXMAXTRY/4);
 		/* Get the next tried/allowed rate. No RTS for the next series
 		 * after the probe rate
 		 */
-		nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
-					  rate_table, nrix, 1, 0);
+		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
 				       try_per_rate, nrix, 0);
 
 		tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
 	} else {
-		try_per_rate = (ATH_11N_TXMAXTRY/4);
 		/* Set the choosen rate. No RTS for first series entry. */
 		ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
 				       try_per_rate, nrix, 0);
@@ -877,18 +801,14 @@ static void ath_rc_ratefind(struct ath_softc *sc,
 
 	/* Fill in the other rates for multirate retry */
 	for ( ; i < 4; i++) {
-		u8 try_num;
-		u8 min_rate;
+		/* Use twice the number of tries for the last MRR segment. */
+		if (i + 1 == 4)
+			try_per_rate = 4;
 
-		try_num = ((i + 1) == 4) ?
-			ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
-		min_rate = (((i + 1) == 4) && 0);
-
-		nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
-					  rate_table, nrix, 1, min_rate);
+		ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
 		/* All other rates in the series have RTS enabled */
 		ath_rc_rate_set_series(rate_table, &rates[i], txrc,
-				       try_num, nrix, 1);
+				       try_per_rate, nrix, 1);
 	}
 
 	/*
@@ -925,9 +845,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
 	 *
 	 * FIXME: Fix duration
 	 */
-	if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-	    (ieee80211_has_morefrags(fc) ||
-	     (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
+	if (ieee80211_has_morefrags(fc) ||
+	    (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
 		rates[1].count = rates[2].count = rates[3].count = 0;
 		rates[1].idx = rates[2].idx = rates[3].idx = 0;
 		rates[0].count = ATH_TXMAXTRY;
@@ -960,13 +879,13 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 		100 * 9 / 10
 	};
 
-	last_per = ath_rc_priv->state[tx_rate].per;
+	last_per = ath_rc_priv->per[tx_rate];
 
 	if (xretries) {
 		if (xretries == 1) {
-			ath_rc_priv->state[tx_rate].per += 30;
-			if (ath_rc_priv->state[tx_rate].per > 100)
-				ath_rc_priv->state[tx_rate].per = 100;
+			ath_rc_priv->per[tx_rate] += 30;
+			if (ath_rc_priv->per[tx_rate] > 100)
+				ath_rc_priv->per[tx_rate] = 100;
 		} else {
 			/* xretries == 2 */
 			count = ARRAY_SIZE(nretry_to_per_lookup);
@@ -974,7 +893,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 				retries = count - 1;
 
 			/* new_PER = 7/8*old_PER + 1/8*(currentPER) */
-			ath_rc_priv->state[tx_rate].per =
+			ath_rc_priv->per[tx_rate] =
 				(u8)(last_per - (last_per >> 3) + (100 >> 3));
 		}
 
@@ -1010,18 +929,14 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 				n_frames = tx_info_priv->n_frames * (retries + 1);
 				cur_per = (100 * n_bad_frames / n_frames) >> 3;
 				new_per = (u8)(last_per - (last_per >> 3) + cur_per);
-				ath_rc_priv->state[tx_rate].per = new_per;
+				ath_rc_priv->per[tx_rate] = new_per;
 			}
 		} else {
-			ath_rc_priv->state[tx_rate].per =
+			ath_rc_priv->per[tx_rate] =
 				(u8)(last_per - (last_per >> 3) +
 				     (nretry_to_per_lookup[retries] >> 3));
 		}
 
-		ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
-		ath_rc_priv->rssi_last_prev  = ath_rc_priv->rssi_last;
-		ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
-		ath_rc_priv->rssi_time = now_msec;
 
 		/*
 		 * If we got at most one retry then increase the max rate if
@@ -1045,8 +960,8 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 					ath_rc_priv->probe_rate;
 				probe_rate = ath_rc_priv->probe_rate;
 
-				if (ath_rc_priv->state[probe_rate].per > 30)
-					ath_rc_priv->state[probe_rate].per = 20;
+				if (ath_rc_priv->per[probe_rate] > 30)
+					ath_rc_priv->per[probe_rate] = 20;
 
 				ath_rc_priv->probe_rate = 0;
 
@@ -1065,18 +980,9 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 			/*
 			 * Don't update anything.  We don't know if
 			 * this was because of collisions or poor signal.
-			 *
-			 * Later: if rssi_ack is close to
-			 * ath_rc_priv->state[txRate].rssi_thres and we see lots
-			 * of retries, then we could increase
-			 * ath_rc_priv->state[txRate].rssi_thres.
 			 */
 			ath_rc_priv->hw_maxretry_pktcnt = 0;
 		} else {
-			int32_t rssi_ackAvg;
-			int8_t rssi_thres;
-			int8_t rssi_ack_vmin;
-
 			/*
 			 * It worked with no retries. First ignore bogus (small)
 			 * rssi_ack values.
@@ -1086,43 +992,9 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 				ath_rc_priv->hw_maxretry_pktcnt++;
 			}
 
-			if (tx_info_priv->tx.ts_rssi <
-			    rate_table->info[tx_rate].rssi_ack_validmin)
-				goto exit;
-
-			/* Average the rssi */
-			if (tx_rate != ath_rc_priv->rssi_sum_rate) {
-				ath_rc_priv->rssi_sum_rate = tx_rate;
-				ath_rc_priv->rssi_sum =
-					ath_rc_priv->rssi_sum_cnt = 0;
-			}
-
-			ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
-			ath_rc_priv->rssi_sum_cnt++;
-
-			if (ath_rc_priv->rssi_sum_cnt < 4)
-				goto exit;
-
-			rssi_ackAvg =
-				(ath_rc_priv->rssi_sum + 2) / 4;
-			rssi_thres =
-				ath_rc_priv->state[tx_rate].rssi_thres;
-			rssi_ack_vmin =
-				rate_table->info[tx_rate].rssi_ack_validmin;
-
-			ath_rc_priv->rssi_sum =
-				ath_rc_priv->rssi_sum_cnt = 0;
-
-			/* Now reduce the current rssi threshold */
-			if ((rssi_ackAvg < rssi_thres + 2) &&
-			    (rssi_thres > rssi_ack_vmin)) {
-				ath_rc_priv->state[tx_rate].rssi_thres--;
-			}
-
-			state_change = true;
 		}
 	}
-exit:
+
 	return state_change;
 }
 
@@ -1134,11 +1006,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 			     struct ath_tx_info_priv *tx_info_priv,
 			     int tx_rate, int xretries, int retries)
 {
-#define CHK_RSSI(rate)					\
-	((ath_rc_priv->state[(rate)].rssi_thres +	\
-	  rate_table->info[(rate)].rssi_ack_deltamin) > \
-	 ath_rc_priv->state[(rate)+1].rssi_thres)
-
 	u32 now_msec = jiffies_to_msecs(jiffies);
 	int rate;
 	u8 last_per;
@@ -1149,14 +1016,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 	if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
 		return;
 
-	/* To compensate for some imbalance between ctrl and ext. channel */
-
-	if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
-		tx_info_priv->tx.ts_rssi =
-			tx_info_priv->tx.ts_rssi < 3 ? 0 :
-			tx_info_priv->tx.ts_rssi - 3;
-
-	last_per = ath_rc_priv->state[tx_rate].per;
+	last_per = ath_rc_priv->per[tx_rate];
 
 	/* Update PER first */
 	state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
@@ -1167,114 +1027,52 @@ static void ath_rc_update_ht(struct ath_softc *sc,
 	 * If this rate looks bad (high PER) then stop using it for
 	 * a while (except if we are probing).
 	 */
-	if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
+	if (ath_rc_priv->per[tx_rate] >= 55 && tx_rate > 0 &&
 	    rate_table->info[tx_rate].ratekbps <=
 	    rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
-		ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
-				 (u8)tx_rate, &ath_rc_priv->rate_max_phy);
+		ath_rc_get_lower_rix(rate_table, ath_rc_priv,
+				     (u8)tx_rate, &ath_rc_priv->rate_max_phy);
 
 		/* Don't probe for a little while. */
 		ath_rc_priv->probe_time = now_msec;
 	}
 
-	if (state_change) {
-		/*
-		 * Make sure the rates above this have higher rssi thresholds.
-		 * (Note:  Monotonicity is kept within the OFDM rates and
-		 *         within the CCK rates. However, no adjustment is
-		 *         made to keep the rssi thresholds monotonically
-		 *         increasing between the CCK and OFDM rates.)
-		 */
-		for (rate = tx_rate; rate < size - 1; rate++) {
-			if (rate_table->info[rate+1].phy !=
-			    rate_table->info[tx_rate].phy)
-				break;
-
-			if (CHK_RSSI(rate)) {
-				ath_rc_priv->state[rate+1].rssi_thres =
-					ath_rc_priv->state[rate].rssi_thres +
-					rate_table->info[rate].rssi_ack_deltamin;
-			}
-		}
-
-		/* Make sure the rates below this have lower rssi thresholds. */
-		for (rate = tx_rate - 1; rate >= 0; rate--) {
-			if (rate_table->info[rate].phy !=
-			    rate_table->info[tx_rate].phy)
-				break;
-
-			if (CHK_RSSI(rate)) {
-				if (ath_rc_priv->state[rate+1].rssi_thres <
-				    rate_table->info[rate].rssi_ack_deltamin)
-					ath_rc_priv->state[rate].rssi_thres = 0;
-				else {
-					ath_rc_priv->state[rate].rssi_thres =
-					ath_rc_priv->state[rate+1].rssi_thres -
-					rate_table->info[rate].rssi_ack_deltamin;
-				}
-
-				if (ath_rc_priv->state[rate].rssi_thres <
-				    rate_table->info[rate].rssi_ack_validmin) {
-					ath_rc_priv->state[rate].rssi_thres =
-					rate_table->info[rate].rssi_ack_validmin;
-				}
-			}
-		}
-	}
-
 	/* Make sure the rates below this have lower PER */
 	/* Monotonicity is kept only for rates below the current rate. */
-	if (ath_rc_priv->state[tx_rate].per < last_per) {
+	if (ath_rc_priv->per[tx_rate] < last_per) {
 		for (rate = tx_rate - 1; rate >= 0; rate--) {
-			if (rate_table->info[rate].phy !=
-			    rate_table->info[tx_rate].phy)
-				break;
 
-			if (ath_rc_priv->state[rate].per >
-			    ath_rc_priv->state[rate+1].per) {
-				ath_rc_priv->state[rate].per =
-					ath_rc_priv->state[rate+1].per;
+			if (ath_rc_priv->per[rate] >
+			    ath_rc_priv->per[rate+1]) {
+				ath_rc_priv->per[rate] =
+					ath_rc_priv->per[rate+1];
 			}
 		}
 	}
 
 	/* Maintain monotonicity for rates above the current rate */
 	for (rate = tx_rate; rate < size - 1; rate++) {
-		if (ath_rc_priv->state[rate+1].per <
-		    ath_rc_priv->state[rate].per)
-			ath_rc_priv->state[rate+1].per =
-				ath_rc_priv->state[rate].per;
-	}
-
-	/* Every so often, we reduce the thresholds and
-	 * PER (different for CCK and OFDM). */
-	if (now_msec - ath_rc_priv->rssi_down_time >=
-	    rate_table->rssi_reduce_interval) {
-
-		for (rate = 0; rate < size; rate++) {
-			if (ath_rc_priv->state[rate].rssi_thres >
-			    rate_table->info[rate].rssi_ack_validmin)
-				ath_rc_priv->state[rate].rssi_thres -= 1;
-		}
-		ath_rc_priv->rssi_down_time = now_msec;
+		if (ath_rc_priv->per[rate+1] <
+		    ath_rc_priv->per[rate])
+			ath_rc_priv->per[rate+1] =
+				ath_rc_priv->per[rate];
 	}
 
 	/* Every so often, we reduce the thresholds
 	 * and PER (different for CCK and OFDM). */
 	if (now_msec - ath_rc_priv->per_down_time >=
-	    rate_table->rssi_reduce_interval) {
+	    rate_table->probe_interval) {
 		for (rate = 0; rate < size; rate++) {
-			ath_rc_priv->state[rate].per =
-				7 * ath_rc_priv->state[rate].per / 8;
+			ath_rc_priv->per[rate] =
+				7 * ath_rc_priv->per[rate] / 8;
 		}
 
 		ath_rc_priv->per_down_time = now_msec;
 	}
 
 	ath_debug_stat_retries(sc, tx_rate, xretries, retries,
-			       ath_rc_priv->state[tx_rate].per);
+			       ath_rc_priv->per[tx_rate]);
 
-#undef CHK_RSSI
 }
 
 static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
@@ -1410,9 +1208,7 @@ static void ath_rc_init(struct ath_softc *sc,
 
 	/* Initialize thresholds according to the global rate table */
 	for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
-		ath_rc_priv->state[i].rssi_thres =
-			rate_table->info[i].rssi_ack_validmin;
-		ath_rc_priv->state[i].per = 0;
+		ath_rc_priv->per[i] = 0;
 	}
 
 	/* Determine the valid rates */
@@ -1521,7 +1317,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 	/*
 	 * If underrun error is seen assume it as an excessive retry only
 	 * if prefetch trigger level have reached the max (0x3f for 5416)
-	 * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
+	 * Adjust the long retry as if the frame was tried hw->max_rate_tries
 	 * times. This affects how ratectrl updates PER for the failed rate.
 	 */
 	if (tx_info_priv->tx.ts_flags &
@@ -1536,7 +1332,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
 		tx_status = 1;
 
 	ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
-			 (is_underrun) ? ATH_11N_TXMAXTRY :
+			 (is_underrun) ? sc->hw->max_rate_tries :
 			 tx_info_priv->tx.ts_longretry);
 
 	/* Check if aggregation has to be enabled for this tid */
@@ -1560,31 +1356,6 @@ exit:
 	kfree(tx_info_priv);
 }
 
-static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
-			 struct ieee80211_tx_rate_control *txrc)
-{
-	struct ieee80211_supported_band *sband = txrc->sband;
-	struct sk_buff *skb = txrc->skb;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	struct ath_softc *sc = priv;
-	struct ath_rate_priv *ath_rc_priv = priv_sta;
-	__le16 fc = hdr->frame_control;
-
-	/* lowest rate for management and NO_ACK frames */
-	if (!ieee80211_is_data(fc) ||
-	    tx_info->flags & IEEE80211_TX_CTL_NO_ACK || !sta) {
-		tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
-		tx_info->control.rates[0].count =
-			(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ?
-				1 : ATH_MGT_TXMAXTRY;
-		return;
-	}
-
-	/* Find tx rate for unicast frames */
-	ath_rc_ratefind(sc, ath_rc_priv, txrc);
-}
-
 static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
                           struct ieee80211_sta *sta, void *priv_sta)
 {
@@ -1697,7 +1468,6 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
 		return NULL;
 	}
 
-	rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
 	rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
 
 	return rate_priv;
@@ -1725,8 +1495,6 @@ static struct rate_control_ops ath_rate_ops = {
 
 void ath_rate_attach(struct ath_softc *sc)
 {
-	sc->hw_rate_table[ATH9K_MODE_11B] =
-		&ar5416_11b_ratetable;
 	sc->hw_rate_table[ATH9K_MODE_11A] =
 		&ar5416_11a_ratetable;
 	sc->hw_rate_table[ATH9K_MODE_11G] =
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index e3abd76..fa21a62 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -112,8 +112,6 @@ struct ath_rate_table {
 		u8 short_preamble;
 		u8 dot11rate;
 		u8 ctrl_rate;
-		int8_t rssi_ack_validmin;
-		int8_t rssi_ack_deltamin;
 		u8 base_index;
 		u8 cw40index;
 		u8 sgi_index;
@@ -121,15 +119,9 @@ struct ath_rate_table {
 		u32 max_4ms_framelen;
 	} info[RATE_TABLE_SIZE];
 	u32 probe_interval;
-	u32 rssi_reduce_interval;
 	u8 initial_ratemax;
 };
 
-struct ath_tx_ratectrl_state {
-	int8_t rssi_thres;	/* required rssi for this rate (dB) */
-	u8 per;			/* recent estimate of packet error rate (%) */
-};
-
 struct ath_rateset {
 	u8 rs_nrates;
 	u8 rs_rates[ATH_RATE_MAX];
@@ -138,22 +130,14 @@ struct ath_rateset {
 /**
  * struct ath_rate_priv - Rate Control priv data
  * @state: RC state
- * @rssi_last: last ACK rssi
- * @rssi_last_lookup: last ACK rssi used for lookup
- * @rssi_last_prev: previous last ACK rssi
- * @rssi_last_prev2: 2nd previous last ACK rssi
- * @rssi_sum_cnt: count of rssi_sum for averaging
- * @rssi_sum_rate: rate that we are averaging
- * @rssi_sum: running sum of rssi for averaging
  * @probe_rate: rate we are probing at
- * @rssi_time: msec timestamp for last ack rssi
- * @rssi_down_time: msec timestamp for last down step
  * @probe_time: msec timestamp for last probe
  * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
  * @max_valid_rate: maximum number of valid rate
  * @per_down_time: msec timestamp for last PER down step
  * @valid_phy_ratecnt: valid rate count
  * @rate_max_phy: phy index for the max rate
+ * @per: PER for every valid rate in %
  * @probe_interval: interval for ratectrl to probe for other rates
  * @prev_data_rix: rate idx of last data frame
  * @ht_cap: HT capabilities
@@ -161,13 +145,6 @@ struct ath_rateset {
  * @neg_ht_rates: Negotiated HT rates
  */
 struct ath_rate_priv {
-	int8_t rssi_last;
-	int8_t rssi_last_lookup;
-	int8_t rssi_last_prev;
-	int8_t rssi_last_prev2;
-	int32_t rssi_sum_cnt;
-	int32_t rssi_sum_rate;
-	int32_t rssi_sum;
 	u8 rate_table_size;
 	u8 probe_rate;
 	u8 hw_maxretry_pktcnt;
@@ -177,14 +154,12 @@ struct ath_rate_priv {
 	u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
 	u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
 	u8 rate_max_phy;
-	u32 rssi_time;
-	u32 rssi_down_time;
+	u8 per[RATE_TABLE_SIZE];
 	u32 probe_time;
 	u32 per_down_time;
 	u32 probe_interval;
 	u32 prev_data_rix;
 	u32 tx_triglevel_max;
-	struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE];
 	struct ath_rateset neg_rates;
 	struct ath_rateset neg_ht_rates;
 	struct ath_rate_softc *asc;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index cece1c4..ec0abf8 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -100,38 +100,6 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
 	return (tsf & ~0x7fff) | rstamp;
 }
 
-static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
-{
-	struct sk_buff *skb;
-	u32 off;
-
-	/*
-	 * Cache-line-align.  This is important (for the
-	 * 5210 at least) as not doing so causes bogus data
-	 * in rx'd frames.
-	 */
-
-	/* Note: the kernel can allocate a value greater than
-	 * what we ask it to give us. We really only need 4 KB as that
-	 * is this hardware supports and in fact we need at least 3849
-	 * as that is the MAX AMSDU size this hardware supports.
-	 * Unfortunately this means we may get 8 KB here from the
-	 * kernel... and that is actually what is observed on some
-	 * systems :( */
-	skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
-	if (skb != NULL) {
-		off = ((unsigned long) skb->data) % sc->cachelsz;
-		if (off != 0)
-			skb_reserve(skb, sc->cachelsz - off);
-	} else {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"skbuff alloc of size %u failed\n", len);
-		return NULL;
-	}
-
-	return skb;
-}
-
 /*
  * For Decrypt or Demic errors, we only mark packet status here and always push
  * up the frame up to let mac80211 handle the actual error case, be it no
@@ -145,6 +113,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
 	u8 ratecode;
 	__le16 fc;
 	struct ieee80211_hw *hw;
+	struct ieee80211_sta *sta;
+	struct ath_node *an;
+	int last_rssi = ATH_RSSI_DUMMY_MARKER;
+
 
 	hdr = (struct ieee80211_hdr *)skb->data;
 	fc = hdr->frame_control;
@@ -229,17 +201,61 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
 		}
 	}
 
+	rcu_read_lock();
+	sta = ieee80211_find_sta(sc->hw, hdr->addr2);
+	if (sta) {
+		an = (struct ath_node *) sta->drv_priv;
+		if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
+		   !ds->ds_rxstat.rs_moreaggr)
+			ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
+		last_rssi = an->last_rssi;
+	}
+	rcu_read_unlock();
+
+	if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
+		ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
+					ATH_RSSI_EP_MULTIPLIER);
+	if (ds->ds_rxstat.rs_rssi < 0)
+		ds->ds_rxstat.rs_rssi = 0;
+	else if (ds->ds_rxstat.rs_rssi > 127)
+		ds->ds_rxstat.rs_rssi = 127;
+
+	/* Update Beacon RSSI, this is used by ANI. */
+	if (ieee80211_is_beacon(fc))
+		sc->sc_ah->stats.avgbrssi = ds->ds_rxstat.rs_rssi;
+
 	rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
 	rx_status->band = hw->conf.channel->band;
 	rx_status->freq = hw->conf.channel->center_freq;
 	rx_status->noise = sc->ani.noise_floor;
-	rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
+	rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
 	rx_status->antenna = ds->ds_rxstat.rs_antenna;
 
-	/* at 45 you will be able to use MCS 15 reliably. A more elaborate
-	 * scheme can be used here but it requires tables of SNR/throughput for
-	 * each possible mode used. */
-	rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+	/*
+	 * Theory for reporting quality:
+	 *
+	 * At a hardware RSSI of 45 you will be able to use MCS 7  reliably.
+	 * At a hardware RSSI of 45 you will be able to use MCS 15 reliably.
+	 * At a hardware RSSI of 35 you should be able use 54 Mbps reliably.
+	 *
+	 * MCS 7  is the highets MCS index usable by a 1-stream device.
+	 * MCS 15 is the highest MCS index usable by a 2-stream device.
+	 *
+	 * All ath9k devices are either 1-stream or 2-stream.
+	 *
+	 * How many bars you see is derived from the qual reporting.
+	 *
+	 * A more elaborate scheme can be used here but it requires tables
+	 * of SNR/throughput for each possible mode used. For the MCS table
+	 * you can refer to the wireless wiki:
+	 *
+	 * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n
+	 *
+	 */
+	if (conf_is_ht(&hw->conf))
+		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+	else
+		rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 35;
 
 	/* rssi can be more than 45 though, anything above that
 	 * should be considered at 100% */
@@ -288,10 +304,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
 	spin_lock_init(&sc->rx.rxbuflock);
 
 	sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-				 min(sc->cachelsz, (u16)64));
+				 min(sc->common.cachelsz, (u16)64));
 
 	DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-		sc->cachelsz, sc->rx.bufsize);
+		sc->common.cachelsz, sc->rx.bufsize);
 
 	/* Initialize rx descriptors */
 
@@ -304,7 +320,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
 	}
 
 	list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-		skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
+		skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_KERNEL);
 		if (skb == NULL) {
 			error = -ENOMEM;
 			goto err;
@@ -404,15 +420,18 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
 	else
 		rfilt |= ATH9K_RX_FILTER_BEACON;
 
-	/* If in HOSTAP mode, want to enable reception of PSPOLL frames */
-	if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
+	if (sc->rx.rxfilter & FIF_PSPOLL)
 		rfilt |= ATH9K_RX_FILTER_PSPOLL;
 
-	if (sc->sec_wiphy) {
+	if (conf_is_ht(&sc->hw->conf))
+		rfilt |= ATH9K_RX_FILTER_COMP_BAR;
+
+	if (sc->sec_wiphy || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
 		/* TODO: only needed if more than one BSSID is in use in
 		 * station/adhoc mode */
-		/* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
-		 */
+		/* The following may also be needed for other older chips */
+		if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160)
+			rfilt |= ATH9K_RX_FILTER_PROM;
 		rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
 	}
 
@@ -505,11 +524,6 @@ static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
 	return false;
 }
 
-static void ath_rx_ps_back_to_sleep(struct ath_softc *sc)
-{
-	sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
-}
-
 static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
 {
 	struct ieee80211_mgmt *mgmt;
@@ -521,6 +535,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
 	if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
 		return; /* not from our current AP */
 
+	sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
+
 	if (sc->sc_flags & SC_OP_BEACON_SYNC) {
 		sc->sc_flags &= ~SC_OP_BEACON_SYNC;
 		DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
@@ -528,14 +544,6 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
 		ath_beacon_config(sc, NULL);
 	}
 
-	if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) {
-		/* We are not in PS mode anymore; remain awake */
-		DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain "
-			"awake\n");
-		sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
-		return;
-	}
-
 	if (ath_beacon_dtim_pending_cab(skb)) {
 		/*
 		 * Remain awake waiting for buffered broadcast/multicast
@@ -556,11 +564,9 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
 		 * fails to send a frame indicating that all CAB frames have
 		 * been delivered.
 		 */
+		sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
 		DPRINTF(sc, ATH_DBG_PS, "PS wait for CAB frames timed out\n");
 	}
-
-	/* No more broadcast/multicast frames to be received at this point. */
-	ath_rx_ps_back_to_sleep(sc);
 }
 
 static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
@@ -578,13 +584,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
 		  ieee80211_is_action(hdr->frame_control)) &&
 		 is_multicast_ether_addr(hdr->addr1) &&
 		 !ieee80211_has_moredata(hdr->frame_control)) {
-		DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
-			"sleep\n");
 		/*
 		 * No more broadcast/multicast frames to be received at this
 		 * point.
 		 */
-		ath_rx_ps_back_to_sleep(sc);
+		sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB;
+		DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
+			"sleep\n");
 	} else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) &&
 		   !is_multicast_ether_addr(hdr->addr1) &&
 		   !ieee80211_has_morefrags(hdr->frame_control)) {
@@ -619,13 +625,18 @@ static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
 			if (aphy == NULL)
 				continue;
 			nskb = skb_copy(skb, GFP_ATOMIC);
-			if (nskb)
-				__ieee80211_rx(aphy->hw, nskb, rx_status);
+			if (nskb) {
+				memcpy(IEEE80211_SKB_RXCB(nskb), rx_status,
+					sizeof(*rx_status));
+				ieee80211_rx(aphy->hw, nskb);
+			}
 		}
-		__ieee80211_rx(sc->hw, skb, rx_status);
+		memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
+		ieee80211_rx(sc->hw, skb);
 	} else {
 		/* Deliver unicast frames based on receiver address */
-		__ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, rx_status);
+		memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
+		ieee80211_rx(ath_get_virt_hw(sc, hdr), skb);
 	}
 }
 
@@ -738,7 +749,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 
 		/* Ensure we always have an skb to requeue once we are done
 		 * processing the current buffer's skb */
-		requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
+		requeue_skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_ATOMIC);
 
 		/* If there is no memory we ignore the current RX'd frame,
 		 * tell hardware it can give us a new frame using the old
@@ -753,7 +764,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
 				 DMA_FROM_DEVICE);
 
 		skb_put(skb, ds->ds_rxstat.rs_datalen);
-		skb->protocol = cpu_to_be16(ETH_P_CONTROL);
 
 		/* see if any padding is done by the hw and remove it */
 		hdr = (struct ieee80211_hdr *)skb->data;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 5260524..e5c29eb 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -234,7 +234,15 @@
 #define AR_IMR_S5                   0x00b8
 #define AR_IMR_S5_TIM_TIMER         0x00000010
 #define AR_IMR_S5_DTIM_TIMER        0x00000020
-
+#define AR_ISR_S5_GENTIMER_TRIG     0x0000FF80
+#define AR_ISR_S5_GENTIMER_TRIG_S   0
+#define AR_ISR_S5_GENTIMER_THRESH   0xFF800000
+#define AR_ISR_S5_GENTIMER_THRESH_S 16
+#define AR_ISR_S5_S                 0x00d8
+#define AR_IMR_S5_GENTIMER_TRIG     0x0000FF80
+#define AR_IMR_S5_GENTIMER_TRIG_S   0
+#define AR_IMR_S5_GENTIMER_THRESH   0xFF800000
+#define AR_IMR_S5_GENTIMER_THRESH_S 16
 
 #define AR_IMR               0x00a0
 #define AR_IMR_RXOK          0x00000001
@@ -574,6 +582,7 @@
 
 #define AR_D_GBL_IFS_SIFS         0x1030
 #define AR_D_GBL_IFS_SIFS_M       0x0000FFFF
+#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
 #define AR_D_GBL_IFS_SIFS_RESV0   0xFFFFFFFF
 
 #define AR_D_TXBLK_BASE            0x1038
@@ -589,10 +598,12 @@
 #define AR_D_GBL_IFS_SLOT         0x1070
 #define AR_D_GBL_IFS_SLOT_M       0x0000FFFF
 #define AR_D_GBL_IFS_SLOT_RESV0   0xFFFF0000
+#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR   0x00000420
 
 #define AR_D_GBL_IFS_EIFS         0x10b0
 #define AR_D_GBL_IFS_EIFS_M       0x0000FFFF
 #define AR_D_GBL_IFS_EIFS_RESV0   0xFFFF0000
+#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR   0x0000A5EB
 
 #define AR_D_GBL_IFS_MISC        0x10f0
 #define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL        0x00000007
@@ -738,6 +749,13 @@
 #define AR_SREV_REVISION_9285_10              0
 #define AR_SREV_REVISION_9285_11              1
 #define AR_SREV_REVISION_9285_12              2
+#define AR_SREV_VERSION_9287                  0x180
+#define AR_SREV_REVISION_9287_10              0
+#define AR_SREV_REVISION_9287_11              1
+#define AR_SREV_REVISION_9287_12              2
+#define AR_SREV_VERSION_9271			0x140
+#define AR_SREV_REVISION_9271_10		0
+#define AR_SREV_REVISION_9271_11		1
 
 #define AR_SREV_5416(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -794,6 +812,36 @@
 	 (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
 			       AR_SREV_REVISION_9285_12)))
 
+#define AR_SREV_9287(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287))
+#define AR_SREV_9287_10_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9287))
+#define AR_SREV_9287_10(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_10))
+#define AR_SREV_9287_11(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_11))
+#define AR_SREV_9287_11_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
+	 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+	  ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11)))
+#define AR_SREV_9287_12(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_12))
+#define AR_SREV_9287_12_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
+	 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
+	  ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_12)))
+#define AR_SREV_9271(_ah) \
+    (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271)
+#define AR_SREV_9271_10(_ah) \
+    (AR_SREV_9271(_ah) && \
+     ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_10))
+#define AR_SREV_9271_11(_ah) \
+    (AR_SREV_9271(_ah) && \
+     ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11))
+
 #define AR_RADIO_SREV_MAJOR                   0xf0
 #define AR_RAD5133_SREV_MAJOR                 0xc0
 #define AR_RAD2133_SREV_MAJOR                 0xd0
@@ -809,6 +857,9 @@
 #define AR_AHB_PAGE_SIZE_1K                   0x00000000
 #define AR_AHB_PAGE_SIZE_2K                   0x00000008
 #define AR_AHB_PAGE_SIZE_4K                   0x00000010
+#define AR_AHB_CUSTOM_BURST_EN                0x000000C0
+#define AR_AHB_CUSTOM_BURST_EN_S              6
+#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL    3
 
 #define AR_INTR_RTC_IRQ                       0x00000001
 #define AR_INTR_MAC_IRQ                       0x00000002
@@ -885,6 +936,7 @@ enum {
 #define AR_NUM_GPIO                              14
 #define AR928X_NUM_GPIO                          10
 #define AR9285_NUM_GPIO                          12
+#define AR9287_NUM_GPIO                          11
 
 #define AR_GPIO_IN_OUT                           0x4048
 #define AR_GPIO_IN_VAL                           0x0FFFC000
@@ -893,6 +945,8 @@ enum {
 #define AR928X_GPIO_IN_VAL_S                     10
 #define AR9285_GPIO_IN_VAL                       0x00FFF000
 #define AR9285_GPIO_IN_VAL_S                     12
+#define AR9287_GPIO_IN_VAL                       0x003FF800
+#define AR9287_GPIO_IN_VAL_S                     11
 
 #define AR_GPIO_OE_OUT                           0x404c
 #define AR_GPIO_OE_OUT_DRV                       0x3
@@ -916,6 +970,8 @@ enum {
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S      7
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB        0x00001000
 #define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB      0x00001000
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB_S    1
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB         0x00008000
 #define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S       15
 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
@@ -924,6 +980,8 @@ enum {
 #define AR_GPIO_INPUT_MUX1                       0x4058
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
+#define AR_GPIO_INPUT_MUX1_BT_PRIORITY           0x00000f00
+#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S         8
 
 #define AR_GPIO_INPUT_MUX2                       0x405c
 #define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
@@ -949,6 +1007,8 @@ enum {
 
 #define AR_OBS                  0x4080
 
+#define AR_GPIO_PDPU                             0x4088
+
 #define AR_PCIE_MSI                              0x4094
 #define AR_PCIE_MSI_ENABLE                       0x00000001
 
@@ -1115,12 +1175,32 @@ enum {
 #define AR9285_AN_RF2G4_DB2_4    0x00003800
 #define AR9285_AN_RF2G4_DB2_4_S    11
 
+/* AR9271 : 0x7828, 0x782c different setting from AR9285 */
+#define AR9271_AN_RF2G3_OB_cck		0x001C0000
+#define AR9271_AN_RF2G3_OB_cck_S	18
+#define AR9271_AN_RF2G3_OB_psk		0x00038000
+#define AR9271_AN_RF2G3_OB_psk_S	15
+#define AR9271_AN_RF2G3_OB_qam		0x00007000
+#define AR9271_AN_RF2G3_OB_qam_S	12
+
+#define AR9271_AN_RF2G3_DB_1		0x00E00000
+#define AR9271_AN_RF2G3_DB_1_S		21
+
+#define AR9271_AN_RF2G3_CCOMP		0xFFF
+#define AR9271_AN_RF2G3_CCOMP_S		0
+
+#define AR9271_AN_RF2G4_DB_2		0xE0000000
+#define AR9271_AN_RF2G4_DB_2_S		29
+
 #define AR9285_AN_RF2G6                 0x7834
 #define AR9285_AN_RF2G6_CCOMP           0x00007800
 #define AR9285_AN_RF2G6_CCOMP_S         11
 #define AR9285_AN_RF2G6_OFFS            0x03f00000
 #define AR9285_AN_RF2G6_OFFS_S          20
 
+#define AR9271_AN_RF2G6_OFFS            0x07f00000
+#define AR9271_AN_RF2G6_OFFS_S            20
+
 #define AR9285_AN_RF2G7                 0x7838
 #define AR9285_AN_RF2G7_PWDDB           0x00000002
 #define AR9285_AN_RF2G7_PWDDB_S         1
@@ -1154,6 +1234,38 @@ enum {
 #define AR9285_AN_TOP4           0x7870
 #define AR9285_AN_TOP4_DEFAULT   0x10142c00
 
+#define AR9287_AN_RF2G3_CH0             0x7808
+#define AR9287_AN_RF2G3_CH1             0x785c
+#define AR9287_AN_RF2G3_DB1             0xE0000000
+#define AR9287_AN_RF2G3_DB1_S           29
+#define AR9287_AN_RF2G3_DB2             0x1C000000
+#define AR9287_AN_RF2G3_DB2_S           26
+#define AR9287_AN_RF2G3_OB_CCK          0x03800000
+#define AR9287_AN_RF2G3_OB_CCK_S        23
+#define AR9287_AN_RF2G3_OB_PSK          0x00700000
+#define AR9287_AN_RF2G3_OB_PSK_S        20
+#define AR9287_AN_RF2G3_OB_QAM          0x000E0000
+#define AR9287_AN_RF2G3_OB_QAM_S        17
+#define AR9287_AN_RF2G3_OB_PAL_OFF      0x0001C000
+#define AR9287_AN_RF2G3_OB_PAL_OFF_S    14
+
+#define AR9287_AN_TXPC0                 0x7898
+#define AR9287_AN_TXPC0_TXPCMODE        0x0000C000
+#define AR9287_AN_TXPC0_TXPCMODE_S      14
+#define AR9287_AN_TXPC0_TXPCMODE_NORMAL    0
+#define AR9287_AN_TXPC0_TXPCMODE_TEST      1
+#define AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE 2
+#define AR9287_AN_TXPC0_TXPCMODE_ATBTEST   3
+
+#define AR9287_AN_TOP2                  0x78b4
+#define AR9287_AN_TOP2_XPABIAS_LVL      0xC0000000
+#define AR9287_AN_TOP2_XPABIAS_LVL_S    30
+
+/* AR9271 specific stuff */
+#define AR9271_RESET_POWER_DOWN_CONTROL		0x50044
+#define AR9271_RADIO_RF_RST			0x20
+#define AR9271_GATE_MAC_CTL			0x4000
+
 #define AR_STA_ID0                 0x8000
 #define AR_STA_ID1                 0x8004
 #define AR_STA_ID1_SADH_MASK       0x0000FFFF
@@ -1188,6 +1300,7 @@ enum {
 #define AR_TIME_OUT_ACK_S    0
 #define AR_TIME_OUT_CTS      0x3FFF0000
 #define AR_TIME_OUT_CTS_S    16
+#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR    0x16001D56
 
 #define AR_RSSI_THR          0x8018
 #define AR_RSSI_THR_MASK     0x000000FF
@@ -1203,6 +1316,7 @@ enum {
 #define AR_USEC_TX_LAT_S     14
 #define AR_USEC_RX_LAT       0x1F800000
 #define AR_USEC_RX_LAT_S     23
+#define AR_USEC_ASYNC_FIFO_DUR    0x12e00074
 
 #define AR_RESET_TSF        0x8020
 #define AR_RESET_TSF_ONCE   0x01000000
@@ -1211,7 +1325,6 @@ enum {
 #define AR_CFP_VAL          0x0000FFFF
 
 #define AR_RX_FILTER        0x803C
-#define AR_RX_COMPR_BAR     0x00000400
 
 #define AR_MCAST_FIL0       0x8040
 #define AR_MCAST_FIL1       0x8044
@@ -1328,6 +1441,7 @@ enum {
 #define AR_QUIET1_NEXT_QUIET_M         0x0000ffff
 #define AR_QUIET1_QUIET_ENABLE         0x00010000
 #define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000
+#define AR_QUIET1_QUIET_ACK_CTS_ENABLE_S 17
 #define AR_QUIET2          0x8100
 #define AR_QUIET2_QUIET_PERIOD_S       0
 #define AR_QUIET2_QUIET_PERIOD_M       0x0000ffff
@@ -1373,6 +1487,8 @@ enum {
 #define AR_PCU_CLEAR_VMF           0x01000000
 #define AR_PCU_CLEAR_BA_VALID      0x04000000
 
+#define AR_PCU_BT_ANT_PREVENT_RX   0x00100000
+#define AR_PCU_BT_ANT_PREVENT_RX_S 20
 
 #define AR_FILT_OFDM           0x8124
 #define AR_FILT_OFDM_COUNT     0x00FFFFFF
@@ -1400,6 +1516,46 @@ enum {
 #define AR_PHY_ERR_3_COUNT     0x00FFFFFF
 #define AR_PHY_ERR_MASK_3      0x816c
 
+#define AR_BT_COEX_MODE            0x8170
+#define AR_BT_TIME_EXTEND          0x000000ff
+#define AR_BT_TIME_EXTEND_S        0
+#define AR_BT_TXSTATE_EXTEND       0x00000100
+#define AR_BT_TXSTATE_EXTEND_S     8
+#define AR_BT_TX_FRAME_EXTEND      0x00000200
+#define AR_BT_TX_FRAME_EXTEND_S    9
+#define AR_BT_MODE                 0x00000c00
+#define AR_BT_MODE_S               10
+#define AR_BT_QUIET                0x00001000
+#define AR_BT_QUIET_S              12
+#define AR_BT_QCU_THRESH           0x0001e000
+#define AR_BT_QCU_THRESH_S         13
+#define AR_BT_RX_CLEAR_POLARITY    0x00020000
+#define AR_BT_RX_CLEAR_POLARITY_S  17
+#define AR_BT_PRIORITY_TIME        0x00fc0000
+#define AR_BT_PRIORITY_TIME_S      18
+#define AR_BT_FIRST_SLOT_TIME      0xff000000
+#define AR_BT_FIRST_SLOT_TIME_S    24
+
+#define AR_BT_COEX_WEIGHT          0x8174
+#define AR_BT_COEX_WGHT		   0xff55
+#define AR_STOMP_ALL_WLAN_WGHT	   0xffcc
+#define AR_STOMP_LOW_WLAN_WGHT	   0xaaa8
+#define AR_STOMP_NONE_WLAN_WGHT	   0xaa00
+#define AR_BTCOEX_BT_WGHT          0x0000ffff
+#define AR_BTCOEX_BT_WGHT_S        0
+#define AR_BTCOEX_WL_WGHT          0xffff0000
+#define AR_BTCOEX_WL_WGHT_S        16
+
+#define AR_BT_COEX_MODE2           0x817c
+#define AR_BT_BCN_MISS_THRESH      0x000000ff
+#define AR_BT_BCN_MISS_THRESH_S    0
+#define AR_BT_BCN_MISS_CNT         0x0000ff00
+#define AR_BT_BCN_MISS_CNT_S       8
+#define AR_BT_HOLD_RX_CLEAR        0x00010000
+#define AR_BT_HOLD_RX_CLEAR_S      16
+#define AR_BT_DISABLE_BT_ANT       0x00100000
+#define AR_BT_DISABLE_BT_ANT_S     20
+
 #define AR_TXSIFS              0x81d0
 #define AR_TXSIFS_TIME         0x000000FF
 #define AR_TXSIFS_TX_LATENCY   0x00000F00
@@ -1416,7 +1572,10 @@ enum {
 #define AR_TXOP_8_11   0x81f8
 #define AR_TXOP_12_15  0x81fc
 
-
+#define AR_NEXT_NDP2_TIMER                  0x8180
+#define AR_FIRST_NDP_TIMER                  7
+#define AR_NDP2_PERIOD                      0x81a0
+#define AR_NDP2_TIMER_MODE                  0x81c0
 #define AR_NEXT_TBTT_TIMER                  0x8200
 #define AR_NEXT_DMA_BEACON_ALERT            0x8204
 #define AR_NEXT_SWBA                        0x8208
@@ -1468,6 +1627,10 @@ enum {
 #define AR_SLP_MIB_CLEAR   0x00000001
 #define AR_SLP_MIB_PENDING 0x00000002
 
+#define AR_MAC_PCU_LOGIC_ANALYZER               0x8264
+#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768   0x20000000
+
+
 #define AR_2040_MODE                0x8318
 #define AR_2040_JOINED_RX_CLEAR 0x00000001
 
@@ -1485,6 +1648,39 @@ enum {
 #define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
 #define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
 
+#define AR_PCU_MISC_MODE2_RESERVED                     0x00000038
+#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE     0x00000040
+#define AR_PCU_MISC_MODE2_CFP_IGNORE                   0x00000080
+#define AR_PCU_MISC_MODE2_MGMT_QOS                     0x0000FF00
+#define AR_PCU_MISC_MODE2_MGMT_QOS_S                   8
+#define AR_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION 0x00010000
+#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP                0x00020000
+#define AR_PCU_MISC_MODE2_HWWAR1                       0x00100000
+#define AR_PCU_MISC_MODE2_HWWAR2                       0x02000000
+#define AR_PCU_MISC_MODE2_RESERVED2                    0xFFFE0000
+
+#define AR_MAC_PCU_ASYNC_FIFO_REG3                     0x8358
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL        0x00000400
+#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET          0x80000000
+
+
+#define AR_AES_MUTE_MASK0       0x805c
+#define AR_AES_MUTE_MASK0_FC    0x0000FFFF
+#define AR_AES_MUTE_MASK0_QOS   0xFFFF0000
+#define AR_AES_MUTE_MASK0_QOS_S 16
+
+#define AR_AES_MUTE_MASK1              0x8060
+#define AR_AES_MUTE_MASK1_SEQ          0x0000FFFF
+#define AR_AES_MUTE_MASK1_SEQ_S        0
+#define AR_AES_MUTE_MASK1_FC_MGMT      0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S    16
+
+#define AR_RATE_DURATION_0      0x8700
+#define AR_RATE_DURATION_31     0x87CC
+#define AR_RATE_DURATION_32     0x8780
+#define AR_RATE_DURATION(_n)    (AR_RATE_DURATION_0 + ((_n)<<2))
+
+
 #define AR_KEYTABLE_0           0x8800
 #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
 #define AR_KEY_CACHE_SIZE       128
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 1ff429b..19b88f8 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -351,7 +351,7 @@ void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 			 * Drop from tasklet to work to allow mutex for channel
 			 * change.
 			 */
-			queue_work(aphy->sc->hw->workqueue,
+			ieee80211_queue_work(aphy->sc->hw,
 				   &aphy->sc->chan_work);
 		}
 	}
@@ -367,7 +367,7 @@ static void ath9k_mark_paused(struct ath_wiphy *aphy)
 	struct ath_softc *sc = aphy->sc;
 	aphy->state = ATH_WIPHY_PAUSED;
 	if (!__ath9k_wiphy_pausing(sc))
-		queue_work(sc->hw->workqueue, &sc->chan_work);
+		ieee80211_queue_work(sc->hw, &sc->chan_work);
 }
 
 static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -521,7 +521,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
 			spin_unlock_bh(&sc->wiphy_lock);
 			ath_radio_disable(sc);
 			ath_radio_enable(sc);
-			queue_work(aphy->sc->hw->workqueue,
+			ieee80211_queue_work(aphy->sc->hw,
 				   &aphy->sc->chan_work);
 			return -EBUSY; /* previous select still in progress */
 		}
@@ -541,7 +541,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
 
 	if (now) {
 		/* Ready to request channel change immediately */
-		queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
+		ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work);
 	}
 
 	/*
@@ -648,8 +648,9 @@ try_again:
 		       "change\n");
 	}
 
-	queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
-			   sc->wiphy_scheduler_int);
+	ieee80211_queue_delayed_work(sc->hw,
+				     &sc->wiphy_work,
+				     sc->wiphy_scheduler_int);
 }
 
 void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
@@ -657,6 +658,23 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
 	cancel_delayed_work_sync(&sc->wiphy_work);
 	sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
 	if (sc->wiphy_scheduler_int)
-		queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
-				   sc->wiphy_scheduler_int);
+		ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work,
+					     sc->wiphy_scheduler_int);
+}
+
+/* caller must hold wiphy_lock */
+bool ath9k_all_wiphys_idle(struct ath_softc *sc)
+{
+	unsigned int i;
+	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+		return false;
+	}
+	for (i = 0; i < sc->num_sec_wiphy; i++) {
+		struct ath_wiphy *aphy = sc->sec_wiphy[i];
+		if (!aphy)
+			continue;
+		if (aphy->state != ATH_WIPHY_INACTIVE)
+			return false;
+	}
+	return true;
 }
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4ccf48e..42551a4 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -59,6 +59,7 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
 				  struct ath_atx_tid *tid,
 				  struct list_head *bf_head);
 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+				struct ath_txq *txq,
 				struct list_head *bf_q,
 				int txok, int sendbar);
 static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
@@ -73,18 +74,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
 /* Aggregation logic */
 /*********************/
 
-static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
-{
-	struct ath_atx_tid *tid;
-	tid = ATH_AN_2_TID(an, tidno);
-
-	if (tid->state & AGGR_ADDBA_COMPLETE ||
-	    tid->state & AGGR_ADDBA_PROGRESS)
-		return 1;
-	else
-		return 0;
-}
-
 static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
 {
 	struct ath_atx_ac *ac = tid->ac;
@@ -224,7 +213,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
 			ath_tx_update_baw(sc, tid, bf->bf_seqno);
 
 		spin_unlock(&txq->axq_lock);
-		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+		ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
 		spin_lock(&txq->axq_lock);
 	}
 
@@ -232,13 +221,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
 	tid->baw_tail = tid->baw_head;
 }
 
-static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
+static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
+			     struct ath_buf *bf)
 {
 	struct sk_buff *skb;
 	struct ieee80211_hdr *hdr;
 
 	bf->bf_state.bf_type |= BUF_RETRY;
 	bf->bf_retries++;
+	TX_STAT_INC(txq->axq_qnum, a_retries);
 
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -250,7 +241,10 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
 	struct ath_buf *tbf;
 
 	spin_lock_bh(&sc->tx.txbuflock);
-	ASSERT(!list_empty((&sc->tx.txbuf)));
+	if (WARN_ON(list_empty(&sc->tx.txbuf))) {
+		spin_unlock_bh(&sc->tx.txbuflock);
+		return NULL;
+	}
 	tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
 	list_del(&tbf->list);
 	spin_unlock_bh(&sc->tx.txbuflock);
@@ -337,7 +331,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 			if (!(tid->state & AGGR_CLEANUP) &&
 			    ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
 				if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
-					ath_tx_set_retry(sc, bf);
+					ath_tx_set_retry(sc, txq, bf);
 					txpending = 1;
 				} else {
 					bf->bf_state.bf_type |= BUF_XRETRY;
@@ -384,13 +378,31 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 				ath_tx_rc_status(bf, ds, nbad, txok, false);
 			}
 
-			ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
+			ath_tx_complete_buf(sc, bf, txq, &bf_head, !txfail, sendbar);
 		} else {
 			/* retry the un-acked ones */
 			if (bf->bf_next == NULL && bf_last->bf_stale) {
 				struct ath_buf *tbf;
 
 				tbf = ath_clone_txbuf(sc, bf_last);
+				/*
+				 * Update tx baw and complete the frame with
+				 * failed status if we run out of tx buf
+				 */
+				if (!tbf) {
+					spin_lock_bh(&txq->axq_lock);
+					ath_tx_update_baw(sc, tid,
+							  bf->bf_seqno);
+					spin_unlock_bh(&txq->axq_lock);
+
+					bf->bf_state.bf_type |= BUF_XRETRY;
+					ath_tx_rc_status(bf, ds, nbad,
+							 0, false);
+					ath_tx_complete_buf(sc, bf, txq,
+							    &bf_head, 0, 0);
+					break;
+				}
+
 				ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
 				list_add_tail(&tbf->list, &bf_head);
 			} else {
@@ -414,7 +426,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
 	if (tid->state & AGGR_CLEANUP) {
 		if (tid->baw_head == tid->baw_tail) {
 			tid->state &= ~AGGR_ADDBA_COMPLETE;
-			tid->addba_exchangeattempts = 0;
 			tid->state &= ~AGGR_CLEANUP;
 
 			/* send buffered frames as singles */
@@ -447,7 +458,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 	struct ieee80211_tx_rate *rates;
 	struct ath_tx_info_priv *tx_info_priv;
 	u32 max_4ms_framelen, frmlen;
-	u16 aggr_limit, legacy = 0, maxampdu;
+	u16 aggr_limit, legacy = 0;
 	int i;
 
 	skb = bf->bf_mpdu;
@@ -482,16 +493,20 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 	if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
 		return 0;
 
-	aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
+	if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED)
+		aggr_limit = min((max_4ms_framelen * 3) / 8,
+				 (u32)ATH_AMPDU_LIMIT_MAX);
+	else
+		aggr_limit = min(max_4ms_framelen,
+				 (u32)ATH_AMPDU_LIMIT_MAX);
 
 	/*
 	 * h/w can accept aggregates upto 16 bit lengths (65535).
 	 * The IE, however can hold upto 65536, which shows up here
 	 * as zero. Ignore 65536 since we  are constrained by hw.
 	 */
-	maxampdu = tid->an->maxampdu;
-	if (maxampdu)
-		aggr_limit = min(aggr_limit, maxampdu);
+	if (tid->an->maxampdu)
+		aggr_limit = min(aggr_limit, tid->an->maxampdu);
 
 	return aggr_limit;
 }
@@ -499,7 +514,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
 /*
  * Returns the number of delimiters to be added to
  * meet the minimum required mpdudensity.
- * caller should make sure that the rate is HT rate .
  */
 static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
 				  struct ath_buf *bf, u16 frmlen)
@@ -507,7 +521,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
 	const struct ath_rate_table *rt = sc->cur_rate_table;
 	struct sk_buff *skb = bf->bf_mpdu;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-	u32 nsymbits, nsymbols, mpdudensity;
+	u32 nsymbits, nsymbols;
 	u16 minlen;
 	u8 rc, flags, rix;
 	int width, half_gi, ndelim, mindelim;
@@ -529,14 +543,12 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
 	 * on highest rate in rate series (i.e. first rate) to determine
 	 * required minimum length for subframe. Take into account
 	 * whether high rate is 20 or 40Mhz and half or full GI.
-	 */
-	mpdudensity = tid->an->mpdudensity;
-
-	/*
+	 *
 	 * If there is no mpdu density restriction, no further calculation
 	 * is needed.
 	 */
-	if (mpdudensity == 0)
+
+	if (tid->an->mpdudensity == 0)
 		return ndelim;
 
 	rix = tx_info->control.rates[0].idx;
@@ -546,9 +558,9 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
 	half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
 
 	if (half_gi)
-		nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
+		nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(tid->an->mpdudensity);
 	else
-		nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
+		nsymbols = NUM_SYMBOLS_PER_USEC(tid->an->mpdudensity);
 
 	if (nsymbols == 0)
 		nsymbols = 1;
@@ -565,6 +577,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
 }
 
 static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
+					     struct ath_txq *txq,
 					     struct ath_atx_tid *tid,
 					     struct list_head *bf_q)
 {
@@ -629,6 +642,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
 			bf_prev->bf_desc->ds_link = bf->bf_daddr;
 		}
 		bf_prev = bf;
+
 	} while (!list_empty(&tid->buf_q));
 
 	bf_first->bf_al = al;
@@ -651,7 +665,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
 
 		INIT_LIST_HEAD(&bf_q);
 
-		status = ath_tx_form_aggr(sc, tid, &bf_q);
+		status = ath_tx_form_aggr(sc, txq, tid, &bf_q);
 
 		/*
 		 * no frames picked up to be aggregated;
@@ -682,30 +696,26 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
 
 		txq->axq_aggr_depth++;
 		ath_tx_txqaddbuf(sc, txq, &bf_q);
+		TX_STAT_INC(txq->axq_qnum, a_aggr);
 
 	} while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
 		 status != ATH_AGGR_BAW_CLOSED);
 }
 
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-		      u16 tid, u16 *ssn)
+void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+		       u16 tid, u16 *ssn)
 {
 	struct ath_atx_tid *txtid;
 	struct ath_node *an;
 
 	an = (struct ath_node *)sta->drv_priv;
-
-	if (sc->sc_flags & SC_OP_TXAGGR) {
-		txtid = ATH_AN_2_TID(an, tid);
-		txtid->state |= AGGR_ADDBA_PROGRESS;
-		ath_tx_pause_tid(sc, txtid);
-		*ssn = txtid->seq_start;
-	}
-
-	return 0;
+	txtid = ATH_AN_2_TID(an, tid);
+	txtid->state |= AGGR_ADDBA_PROGRESS;
+	ath_tx_pause_tid(sc, txtid);
+	*ssn = txtid->seq_start;
 }
 
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
 	struct ath_node *an = (struct ath_node *)sta->drv_priv;
 	struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
@@ -715,12 +725,11 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 	INIT_LIST_HEAD(&bf_head);
 
 	if (txtid->state & AGGR_CLEANUP)
-		return 0;
+		return;
 
 	if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
 		txtid->state &= ~AGGR_ADDBA_PROGRESS;
-		txtid->addba_exchangeattempts = 0;
-		return 0;
+		return;
 	}
 
 	ath_tx_pause_tid(sc, txtid);
@@ -739,7 +748,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 		}
 		list_move_tail(&bf->list, &bf_head);
 		ath_tx_update_baw(sc, txtid, bf->bf_seqno);
-		ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+		ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
 	}
 	spin_unlock_bh(&txq->axq_lock);
 
@@ -747,11 +756,8 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 		txtid->state |= AGGR_CLEANUP;
 	} else {
 		txtid->state &= ~AGGR_ADDBA_COMPLETE;
-		txtid->addba_exchangeattempts = 0;
 		ath_tx_flush_tid(sc, txtid);
 	}
-
-	return 0;
 }
 
 void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
@@ -780,14 +786,8 @@ bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
 
 	txtid = ATH_AN_2_TID(an, tidno);
 
-	if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-		if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
-		    (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
-			txtid->addba_exchangeattempts++;
+	if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS)))
 			return true;
-		}
-	}
-
 	return false;
 }
 
@@ -870,14 +870,14 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
 		spin_lock_init(&txq->axq_lock);
 		txq->axq_depth = 0;
 		txq->axq_aggr_depth = 0;
-		txq->axq_totalqueued = 0;
 		txq->axq_linkbuf = NULL;
+		txq->axq_tx_inprogress = false;
 		sc->tx.txqsetup |= 1<<qnum;
 	}
 	return &sc->tx.txq[qnum];
 }
 
-static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
+int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
 {
 	int qnum;
 
@@ -1035,9 +1035,13 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
 		if (bf_isampdu(bf))
 			ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
 		else
-			ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+			ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
 	}
 
+	spin_lock_bh(&txq->axq_lock);
+	txq->axq_tx_inprogress = false;
+	spin_unlock_bh(&txq->axq_lock);
+
 	/* flush any pending frames if aggregation is enabled */
 	if (sc->sc_flags & SC_OP_TXAGGR) {
 		if (!retry_tx) {
@@ -1118,8 +1122,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
 		if (tid->paused)
 			continue;
 
-		if ((txq->axq_depth % 2) == 0)
-			ath_tx_sched_aggr(sc, txq, tid);
+		ath_tx_sched_aggr(sc, txq, tid);
 
 		/*
 		 * add tid to round-robin queue if more frames
@@ -1183,7 +1186,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
 
 	list_splice_tail_init(head, &txq->axq_q);
 	txq->axq_depth++;
-	txq->axq_totalqueued++;
 	txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
 
 	DPRINTF(sc, ATH_DBG_QUEUE,
@@ -1231,6 +1233,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
 
 	bf = list_first_entry(bf_head, struct ath_buf, list);
 	bf->bf_state.bf_type |= BUF_AMPDU;
+	TX_STAT_INC(txctl->txq->axq_qnum, a_queued);
 
 	/*
 	 * Do not queue to h/w when any of the following conditions is true:
@@ -1277,6 +1280,7 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
 	bf->bf_lastbf = bf;
 	ath_buf_set_rate(sc, bf);
 	ath_tx_txqaddbuf(sc, txq, bf_head);
+	TX_STAT_INC(txq->axq_qnum, queued);
 }
 
 static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
@@ -1290,6 +1294,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
 	bf->bf_nframes = 1;
 	ath_buf_set_rate(sc, bf);
 	ath_tx_txqaddbuf(sc, txq, bf_head);
+	TX_STAT_INC(txq->axq_qnum, queued);
 }
 
 static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
@@ -1636,7 +1641,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
 			goto tx_done;
 		}
 
-		if (ath_aggr_query(sc, an, bf->bf_tidno)) {
+		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
 			/*
 			 * Try aggregation if it's a unicast data frame
 			 * and the destination is HT capable.
@@ -1815,6 +1820,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
 }
 
 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+				struct ath_txq *txq,
 				struct list_head *bf_q,
 				int txok, int sendbar)
 {
@@ -1822,7 +1828,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
 	unsigned long flags;
 	int tx_flags = 0;
 
-
 	if (sendbar)
 		tx_flags = ATH_TX_BAR;
 
@@ -1835,6 +1840,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
 
 	dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
 	ath_tx_complete(sc, skb, tx_flags);
+	ath_debug_stat_tx(sc, txq, bf);
 
 	/*
 	 * Return the list of ath_buf of this mpdu to free queue
@@ -1962,19 +1968,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 		if (bf->bf_stale) {
 			bf_held = bf;
 			if (list_is_last(&bf_held->list, &txq->axq_q)) {
-				txq->axq_link = NULL;
-				txq->axq_linkbuf = NULL;
 				spin_unlock_bh(&txq->axq_lock);
-
-				/*
-				 * The holding descriptor is the last
-				 * descriptor in queue. It's safe to remove
-				 * the last holding descriptor in BH context.
-				 */
-				spin_lock_bh(&sc->tx.txbuflock);
-				list_move_tail(&bf_held->list, &sc->tx.txbuf);
-				spin_unlock_bh(&sc->tx.txbuflock);
-
 				break;
 			} else {
 				bf = list_entry(bf_held->list.next,
@@ -2011,6 +2005,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 			txq->axq_aggr_depth--;
 
 		txok = (ds->ds_txstat.ts_status == 0);
+		txq->axq_tx_inprogress = false;
 		spin_unlock_bh(&txq->axq_lock);
 
 		if (bf_held) {
@@ -2033,7 +2028,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 		if (bf_isampdu(bf))
 			ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
 		else
-			ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
+			ath_tx_complete_buf(sc, bf, txq, &bf_head, txok, 0);
 
 		ath_wake_mac80211_queue(sc, txq);
 
@@ -2044,6 +2039,40 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 	}
 }
 
+static void ath_tx_complete_poll_work(struct work_struct *work)
+{
+	struct ath_softc *sc = container_of(work, struct ath_softc,
+			tx_complete_work.work);
+	struct ath_txq *txq;
+	int i;
+	bool needreset = false;
+
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+		if (ATH_TXQ_SETUP(sc, i)) {
+			txq = &sc->tx.txq[i];
+			spin_lock_bh(&txq->axq_lock);
+			if (txq->axq_depth) {
+				if (txq->axq_tx_inprogress) {
+					needreset = true;
+					spin_unlock_bh(&txq->axq_lock);
+					break;
+				} else {
+					txq->axq_tx_inprogress = true;
+				}
+			}
+			spin_unlock_bh(&txq->axq_lock);
+		}
+
+	if (needreset) {
+		DPRINTF(sc, ATH_DBG_RESET, "tx hung, resetting the chip\n");
+		ath_reset(sc, false);
+	}
+
+	ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
+			msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
+}
+
+
 
 void ath_tx_tasklet(struct ath_softc *sc)
 {
@@ -2084,6 +2113,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
 		goto err;
 	}
 
+	INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
+
 err:
 	if (error != 0)
 		ath_tx_cleanup(sc);
@@ -2122,7 +2153,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
 		tid->ac = &an->ac[acno];
 		tid->state &= ~AGGR_ADDBA_COMPLETE;
 		tid->state &= ~AGGR_ADDBA_PROGRESS;
-		tid->addba_exchangeattempts = 0;
 	}
 
 	for (acno = 0, ac = &an->ac[acno];
@@ -2179,7 +2209,6 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
 					tid->sched = false;
 					ath_tid_drain(sc, txq, tid);
 					tid->state &= ~AGGR_ADDBA_COMPLETE;
-					tid->addba_exchangeattempts = 0;
 					tid->state &= ~AGGR_CLEANUP;
 				}
 			}
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
index 9949b11..487193f 100644
--- a/drivers/net/wireless/ath/main.c
+++ b/drivers/net/wireless/ath/main.c
@@ -17,6 +17,42 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 
+#include "ath.h"
+
 MODULE_AUTHOR("Atheros Communications");
 MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards.");
 MODULE_LICENSE("Dual BSD/GPL");
+
+struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
+				u32 len,
+				gfp_t gfp_mask)
+{
+	struct sk_buff *skb;
+	u32 off;
+
+	/*
+	 * Cache-line-align.  This is important (for the
+	 * 5210 at least) as not doing so causes bogus data
+	 * in rx'd frames.
+	 */
+
+	/* Note: the kernel can allocate a value greater than
+	 * what we ask it to give us. We really only need 4 KB as that
+	 * is this hardware supports and in fact we need at least 3849
+	 * as that is the MAX AMSDU size this hardware supports.
+	 * Unfortunately this means we may get 8 KB here from the
+	 * kernel... and that is actually what is observed on some
+	 * systems :( */
+	skb = __dev_alloc_skb(len + common->cachelsz - 1, gfp_mask);
+	if (skb != NULL) {
+		off = ((unsigned long) skb->data) % common->cachelsz;
+		if (off != 0)
+			skb_reserve(skb, common->cachelsz - off);
+	} else {
+		printk(KERN_ERR "skbuff alloc of size %u failed\n", len);
+		return NULL;
+	}
+
+	return skb;
+}
+EXPORT_SYMBOL(ath_rxbuf_alloc);
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index bf3d25b..077bcc1 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -586,7 +586,5 @@ u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
 	default:
 		return NO_CTL;
 	}
-
-	return NO_CTL;
 }
 EXPORT_SYMBOL(ath_regd_get_band_ctl);
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 07291cc..c1dd857 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -18,9 +18,16 @@
 #define REGD_H
 
 #include <linux/nl80211.h>
-
 #include <net/cfg80211.h>
 
+#include "ath.h"
+
+enum ctl_group {
+	CTL_FCC = 0x10,
+	CTL_MKK = 0x40,
+	CTL_ETSI = 0x30,
+};
+
 #define NO_CTL 0xff
 #define SD_NO_CTL               0xE0
 #define NO_CTL                  0xff
@@ -47,29 +54,12 @@
 #define CHANNEL_HALF_BW         10
 #define CHANNEL_QUARTER_BW      5
 
-struct reg_dmn_pair_mapping {
-	u16 regDmnEnum;
-	u16 reg_5ghz_ctl;
-	u16 reg_2ghz_ctl;
-};
-
 struct country_code_to_enum_rd {
 	u16 countryCode;
 	u16 regDmnEnum;
 	const char *isoName;
 };
 
-struct ath_regulatory {
-	char alpha2[2];
-	u16 country_code;
-	u16 max_power_level;
-	u32 tp_scale;
-	u16 current_rd;
-	u16 current_rd_ext;
-	int16_t power_limit;
-	struct reg_dmn_pair_mapping *regpair;
-};
-
 enum CountryCode {
 	CTRY_ALBANIA = 8,
 	CTRY_ALGERIA = 12,
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index 4d0e298..9847af7 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -154,12 +154,6 @@ enum EnumRd {
 	DEBUG_REG_DMN = 0x01ff,
 };
 
-enum ctl_group {
-	CTL_FCC = 0x10,
-	CTL_MKK = 0x40,
-	CTL_ETSI = 0x30,
-};
-
 /* Regpair to CTL band mapping */
 static struct reg_dmn_pair_mapping regDomainPairs[] = {
 	/* regpair, 5 GHz CTL, 2 GHz CTL */
@@ -450,7 +444,7 @@ static struct country_code_to_enum_rd allCountries[] = {
 	{CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
 	{CTRY_SYRIA, NULL1_WORLD, "SY"},
 	{CTRY_TAIWAN, APL3_FCCA, "TW"},
-	{CTRY_THAILAND, NULL1_WORLD, "TH"},
+	{CTRY_THAILAND, FCC3_WORLD, "TH"},
 	{CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
 	{CTRY_TUNISIA, ETSI3_WORLD, "TN"},
 	{CTRY_TURKEY, ETSI3_WORLD, "TR"},
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 291a94b..a3b36b3 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -781,7 +781,7 @@ static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
 	priv->tx_free_mem -= len;
 }
 
-static int start_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
 	struct atmel_private *priv = netdev_priv(dev);
@@ -793,13 +793,13 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 	    !(*priv->present_callback)(priv->card)) {
 		dev->stats.tx_errors++;
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (priv->station_state != STATION_STATE_READY) {
 		dev->stats.tx_errors++;
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* first ensure the timer func cannot run */
@@ -856,7 +856,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_bh(&priv->timerlock);
 	dev_kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void atmel_transmit_management_frame(struct atmel_private *priv,
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 67f564e..83e3813 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -42,8 +42,8 @@ config B43_PCICORE_AUTOSELECT
 	default y
 
 config B43_PCMCIA
-	bool "Broadcom 43xx PCMCIA device support (EXPERIMENTAL)"
-	depends on B43 && SSB_PCMCIAHOST_POSSIBLE && EXPERIMENTAL
+	bool "Broadcom 43xx PCMCIA device support"
+	depends on B43 && SSB_PCMCIAHOST_POSSIBLE
 	select SSB_PCMCIAHOST
 	---help---
 	  Broadcom 43xx PCMCIA device support.
@@ -80,16 +80,14 @@ config B43_NPHY
 	  SAY N.
 
 config B43_PHY_LP
-	bool "IEEE 802.11g LP-PHY support (BROKEN)"
-	depends on B43 && EXPERIMENTAL && BROKEN
+	bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)"
+	depends on B43 && EXPERIMENTAL
+	default y
 	---help---
 	  Support for the LP-PHY.
-	  The LP-PHY is an IEEE 802.11g based PHY built into some notebooks
-	  and embedded devices.
-
-	  THIS IS BROKEN AND DOES NOT WORK YET.
-
-	  SAY N.
+	  The LP-PHY is a low-power PHY built into some notebooks
+	  and embedded devices. It supports 802.11a/g
+	  (802.11a support is optional, and currently disabled).
 
 # This config option automatically enables b43 LEDS support,
 # if it's possible.
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 4044806..09cfe68 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -142,6 +142,17 @@
 #define B43_BFL_BTCMOD			0x4000	/* BFL_BTCOEXIST is given in alternate GPIOs */
 #define B43_BFL_ALTIQ			0x8000	/* alternate I/Q settings */
 
+/* SPROM boardflags_hi values */
+#define B43_BFH_NOPA			0x0001	/* has no PA */
+#define B43_BFH_RSSIINV			0x0002	/* RSSI uses positive slope (not TSSI) */
+#define B43_BFH_PAREF			0x0004	/* uses the PARef LDO */
+#define B43_BFH_3TSWITCH		0x0008	/* uses a triple throw switch shared
+						 * with bluetooth */
+#define B43_BFH_PHASESHIFT		0x0010	/* can support phase shifter */
+#define B43_BFH_BUCKBOOST		0x0020	/* has buck/booster */
+#define B43_BFH_FEM_BT			0x0040	/* has FEM and switch to share antenna
+						 * with bluetooth */
+
 /* GPIO register offset, in both ChipCommon and PCI core. */
 #define B43_GPIO_CONTROL		0x6c
 
@@ -482,6 +493,10 @@ enum {
 
 /* Max size of a security key */
 #define B43_SEC_KEYSIZE			16
+/* Max number of group keys */
+#define B43_NR_GROUP_KEYS		4
+/* Max number of pairwise keys */
+#define B43_NR_PAIRWISE_KEYS		50
 /* Security algorithms. */
 enum {
 	B43_SEC_ALGO_NONE = 0,	/* unencrypted, as of TX header. */
@@ -601,6 +616,12 @@ struct b43_wl {
 	/* Pointer to the ieee80211 hardware data structure */
 	struct ieee80211_hw *hw;
 
+	/* Global driver mutex. Every operation must run with this mutex locked. */
+	struct mutex mutex;
+	/* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
+	 * handler, only. This basically is just the IRQ mask register. */
+	spinlock_t hardirq_lock;
+
 	/* The number of queues that were registered with the mac80211 subsystem
 	 * initially. This is a backup copy of hw->queues in case hw->queues has
 	 * to be dynamically lowered at runtime (Firmware does not support QoS).
@@ -608,16 +629,12 @@ struct b43_wl {
 	 * from the mac80211 subsystem. */
 	u16 mac80211_initially_registered_queues;
 
-	struct mutex mutex;
-	spinlock_t irq_lock;
 	/* R/W lock for data transmission.
 	 * Transmissions on 2+ queues can run concurrently, but somebody else
 	 * might sync with TX by write_lock_irqsave()'ing. */
 	rwlock_t tx_lock;
 	/* Lock for LEDs access. */
 	spinlock_t leds_lock;
-	/* Lock for SHM access. */
-	spinlock_t shm_lock;
 
 	/* We can only have one operating interface (802.11 core)
 	 * at a time. General information about this interface follows.
@@ -628,7 +645,7 @@ struct b43_wl {
 	u8 mac_addr[ETH_ALEN];
 	/* Current BSSID */
 	u8 bssid[ETH_ALEN];
-	/* Interface type. (IEEE80211_IF_TYPE_XXX) */
+	/* Interface type. (NL80211_IFTYPE_XXX) */
 	int if_type;
 	/* Is the card operating in AP, STA or IBSS mode? */
 	bool operating;
@@ -650,8 +667,7 @@ struct b43_wl {
 	bool radiotap_enabled;
 	bool radio_enabled;
 
-	/* The beacon we are currently using (AP or IBSS mode).
-	 * This beacon stuff is protected by the irq_lock. */
+	/* The beacon we are currently using (AP or IBSS mode). */
 	struct sk_buff *current_beacon;
 	bool beacon0_uploaded;
 	bool beacon1_uploaded;
@@ -665,6 +681,11 @@ struct b43_wl {
 	 * This is scheduled when we determine that the actual TX output
 	 * power doesn't match what we want. */
 	struct work_struct txpower_adjust_work;
+
+	/* Packet transmit work */
+	struct work_struct tx_work;
+	/* Queue of packets to be transmitted. */
+	struct sk_buff_head tx_queue;
 };
 
 /* The type of the firmware file. */
@@ -739,14 +760,6 @@ enum {
 		smp_wmb();					\
 					} while (0)
 
-/* XXX---   HOW LOCKING WORKS IN B43   ---XXX
- *
- * You should always acquire both, wl->mutex and wl->irq_lock unless:
- * - You don't need to acquire wl->irq_lock, if the interface is stopped.
- * - You don't need to acquire wl->mutex in the IRQ handler, IRQ tasklet
- *   and packet TX path (and _ONLY_ there.)
- */
-
 /* Data structure for one wireless device (802.11 core) */
 struct b43_wldev {
 	struct ssb_device *dev;
@@ -792,14 +805,12 @@ struct b43_wldev {
 	u32 dma_reason[6];
 	/* The currently active generic-interrupt mask. */
 	u32 irq_mask;
+
 	/* Link Quality calculation context. */
 	struct b43_noise_calculation noisecalc;
 	/* if > 0 MAC is suspended. if == 0 MAC is enabled. */
 	int mac_suspended;
 
-	/* Interrupt Service Routine tasklet (bottom-half) */
-	struct tasklet_struct isr_tasklet;
-
 	/* Periodic tasks */
 	struct delayed_work periodic_work;
 	unsigned int periodic_state;
@@ -808,8 +819,7 @@ struct b43_wldev {
 
 	/* encryption/decryption */
 	u16 ktp;		/* Key table pointer */
-	u8 max_nr_keys;
-	struct b43_key key[58];
+	struct b43_key key[B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS];
 
 	/* Firmware data */
 	struct b43_firmware fw;
@@ -834,7 +844,7 @@ static inline struct b43_wldev *dev_to_b43_wldev(struct device *dev)
 	return ssb_get_drvdata(ssb_dev);
 }
 
-/* Is the device operating in a specified mode (IEEE80211_IF_TYPE_XXX). */
+/* Is the device operating in a specified mode (NL80211_IFTYPE_XXX). */
 static inline int b43_is_mode(struct b43_wl *wl, int type)
 {
 	return (wl->operating && wl->if_type == type);
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c
index 45e3d6a..8f64943 100644
--- a/drivers/net/wireless/b43/debugfs.c
+++ b/drivers/net/wireless/b43/debugfs.c
@@ -46,8 +46,6 @@ struct b43_debugfs_fops {
 	struct file_operations fops;
 	/* Offset of struct b43_dfs_file in struct b43_dfsentry */
 	size_t file_struct_offset;
-	/* Take wl->irq_lock before calling read/write? */
-	bool take_irqlock;
 };
 
 static inline
@@ -127,7 +125,6 @@ static int shm16write__write_file(struct b43_wldev *dev,
 	unsigned int routing, addr, mask, set;
 	u16 val;
 	int res;
-	unsigned long flags;
 
 	res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
 		     &routing, &addr, &mask, &set);
@@ -144,15 +141,13 @@ static int shm16write__write_file(struct b43_wldev *dev,
 	if ((mask > 0xFFFF) || (set > 0xFFFF))
 		return -E2BIG;
 
-	spin_lock_irqsave(&dev->wl->shm_lock, flags);
 	if (mask == 0)
 		val = 0;
 	else
-		val = __b43_shm_read16(dev, routing, addr);
+		val = b43_shm_read16(dev, routing, addr);
 	val &= mask;
 	val |= set;
-	__b43_shm_write16(dev, routing, addr, val);
-	spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
+	b43_shm_write16(dev, routing, addr, val);
 
 	return 0;
 }
@@ -206,7 +201,6 @@ static int shm32write__write_file(struct b43_wldev *dev,
 	unsigned int routing, addr, mask, set;
 	u32 val;
 	int res;
-	unsigned long flags;
 
 	res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X",
 		     &routing, &addr, &mask, &set);
@@ -223,15 +217,13 @@ static int shm32write__write_file(struct b43_wldev *dev,
 	if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF))
 		return -E2BIG;
 
-	spin_lock_irqsave(&dev->wl->shm_lock, flags);
 	if (mask == 0)
 		val = 0;
 	else
-		val = __b43_shm_read32(dev, routing, addr);
+		val = b43_shm_read32(dev, routing, addr);
 	val &= mask;
 	val |= set;
-	__b43_shm_write32(dev, routing, addr, val);
-	spin_unlock_irqrestore(&dev->wl->shm_lock, flags);
+	b43_shm_write32(dev, routing, addr, val);
 
 	return 0;
 }
@@ -372,14 +364,12 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
 {
 	struct b43_txstatus_log *log = &dev->dfsentry->txstatlog;
 	ssize_t count = 0;
-	unsigned long flags;
 	int i, idx;
 	struct b43_txstatus *stat;
 
-	spin_lock_irqsave(&log->lock, flags);
 	if (log->end < 0) {
 		fappend("Nothing transmitted, yet\n");
-		goto out_unlock;
+		goto out;
 	}
 	fappend("b43 TX status reports:\n\n"
 		"index | cookie | seq | phy_stat | frame_count | "
@@ -409,13 +399,11 @@ static ssize_t txstat_read_file(struct b43_wldev *dev,
 			break;
 		i++;
 	}
-out_unlock:
-	spin_unlock_irqrestore(&log->lock, flags);
+out:
 
 	return count;
 }
 
-/* wl->irq_lock is locked */
 static int restart_write_file(struct b43_wldev *dev,
 			      const char *buf, size_t count)
 {
@@ -556,12 +544,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
 			goto out_unlock;
 		}
 		memset(buf, 0, bufsize);
-		if (dfops->take_irqlock) {
-			spin_lock_irq(&dev->wl->irq_lock);
-			ret = dfops->read(dev, buf, bufsize);
-			spin_unlock_irq(&dev->wl->irq_lock);
-		} else
-			ret = dfops->read(dev, buf, bufsize);
+		ret = dfops->read(dev, buf, bufsize);
 		if (ret <= 0) {
 			free_pages((unsigned long)buf, buforder);
 			err = ret;
@@ -623,12 +606,7 @@ static ssize_t b43_debugfs_write(struct file *file,
 		err = -EFAULT;
 		goto out_freepage;
 	}
-	if (dfops->take_irqlock) {
-		spin_lock_irq(&dev->wl->irq_lock);
-		err = dfops->write(dev, buf, count);
-		spin_unlock_irq(&dev->wl->irq_lock);
-	} else
-		err = dfops->write(dev, buf, count);
+	err = dfops->write(dev, buf, count);
 	if (err)
 		goto out_freepage;
 
@@ -641,7 +619,7 @@ out_unlock:
 }
 
 
-#define B43_DEBUGFS_FOPS(name, _read, _write, _take_irqlock)	\
+#define B43_DEBUGFS_FOPS(name, _read, _write)			\
 	static struct b43_debugfs_fops fops_##name = {		\
 		.read	= _read,				\
 		.write	= _write,				\
@@ -652,20 +630,19 @@ out_unlock:
 		},						\
 		.file_struct_offset = offsetof(struct b43_dfsentry, \
 					       file_##name),	\
-		.take_irqlock	= _take_irqlock,		\
 	}
 
-B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1);
-B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1);
-B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1);
-B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1);
-B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1);
-B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1);
-B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1);
-B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1);
-B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0);
-B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1);
-B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL, 0);
+B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file);
+B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file);
+B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file);
+B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file);
+B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file);
+B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file);
+B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file);
+B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file);
+B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL);
+B43_DEBUGFS_FOPS(restart, NULL, restart_write_file);
+B43_DEBUGFS_FOPS(loctls, loctls_read_file, NULL);
 
 
 bool b43_debug(struct b43_wldev *dev, enum b43_dyndbg feature)
@@ -738,7 +715,6 @@ void b43_debugfs_add_device(struct b43_wldev *dev)
 		return;
 	}
 	log->end = -1;
-	spin_lock_init(&log->lock);
 
 	dev->dfsentry = e;
 
@@ -822,7 +798,6 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
 	kfree(e);
 }
 
-/* Called with IRQs disabled. */
 void b43_debugfs_log_txstat(struct b43_wldev *dev,
 			    const struct b43_txstatus *status)
 {
@@ -834,14 +809,12 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
 	if (!e)
 		return;
 	log = &e->txstatlog;
-	spin_lock(&log->lock); /* IRQs are already disabled. */
 	i = log->end + 1;
 	if (i == B43_NR_LOGGED_TXSTATUS)
 		i = 0;
 	log->end = i;
 	cur = &(log->log[i]);
 	memcpy(cur, status, sizeof(*cur));
-	spin_unlock(&log->lock);
 }
 
 void b43_debugfs_init(void)
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h
index b9d4de4..e47b4b4 100644
--- a/drivers/net/wireless/b43/debugfs.h
+++ b/drivers/net/wireless/b43/debugfs.h
@@ -23,9 +23,10 @@ struct dentry;
 #define B43_NR_LOGGED_TXSTATUS	100
 
 struct b43_txstatus_log {
+	/* This structure is protected by wl->mutex */
+
 	struct b43_txstatus *log;
 	int end;
-	spinlock_t lock;
 };
 
 struct b43_dfs_file {
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 7964cc3..a467ee2 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -856,7 +856,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
 		} else
 			B43_WARN_ON(1);
 	}
-	spin_lock_init(&ring->lock);
 #ifdef CONFIG_B43_DEBUG
 	ring->last_injected_overflow = jiffies;
 #endif
@@ -1188,7 +1187,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 	header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]);
 	cookie = generate_cookie(ring, slot);
 	err = b43_generate_txhdr(ring->dev, header,
-				 skb->data, skb->len, info, cookie);
+				 skb, info, cookie);
 	if (unlikely(err)) {
 		ring->current_slot = old_top_slot;
 		ring->used_slots = old_used_slots;
@@ -1315,7 +1314,6 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
 	struct b43_dmaring *ring;
 	struct ieee80211_hdr *hdr;
 	int err = 0;
-	unsigned long flags;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -1331,18 +1329,25 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
 			dev, skb_get_queue_mapping(skb));
 	}
 
-	spin_lock_irqsave(&ring->lock, flags);
-
 	B43_WARN_ON(!ring->tx);
-	/* Check if the queue was stopped in mac80211,
-	 * but we got called nevertheless.
-	 * That would be a mac80211 bug. */
-	B43_WARN_ON(ring->stopped);
 
-	if (unlikely(free_slots(ring) < TX_SLOTS_PER_FRAME)) {
-		b43warn(dev->wl, "DMA queue overflow\n");
+	if (unlikely(ring->stopped)) {
+		/* We get here only because of a bug in mac80211.
+		 * Because of a race, one packet may be queued after
+		 * the queue is stopped, thus we got called when we shouldn't.
+		 * For now, just refuse the transmit. */
+		if (b43_debug(dev, B43_DBG_DMAVERBOSE))
+			b43err(dev->wl, "Packet after queue stopped\n");
 		err = -ENOSPC;
-		goto out_unlock;
+		goto out;
+	}
+
+	if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) {
+		/* If we get here, we have a real error with the queue
+		 * full, but queues not stopped. */
+		b43err(dev->wl, "DMA queue overflow\n");
+		err = -ENOSPC;
+		goto out;
 	}
 
 	/* Assign the queue number to the ring (if not already done before)
@@ -1356,11 +1361,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
 		 * anymore and must not transmit it unencrypted. */
 		dev_kfree_skb_any(skb);
 		err = 0;
-		goto out_unlock;
+		goto out;
 	}
 	if (unlikely(err)) {
 		b43err(dev->wl, "DMA tx mapping failure\n");
-		goto out_unlock;
+		goto out;
 	}
 	ring->nr_tx_packets++;
 	if ((free_slots(ring) < TX_SLOTS_PER_FRAME) ||
@@ -1372,13 +1377,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
 			b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
 		}
 	}
-out_unlock:
-	spin_unlock_irqrestore(&ring->lock, flags);
+out:
 
 	return err;
 }
 
-/* Called with IRQs disabled. */
 void b43_dma_handle_txstatus(struct b43_wldev *dev,
 			     const struct b43_txstatus *status)
 {
@@ -1393,8 +1396,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
 	if (unlikely(!ring))
 		return;
 
-	spin_lock(&ring->lock); /* IRQs are already disabled. */
-
 	B43_WARN_ON(!ring->tx);
 	ops = ring->ops;
 	while (1) {
@@ -1453,8 +1454,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
 			b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index);
 		}
 	}
-
-	spin_unlock(&ring->lock);
 }
 
 void b43_dma_get_tx_stats(struct b43_wldev *dev,
@@ -1462,17 +1461,14 @@ void b43_dma_get_tx_stats(struct b43_wldev *dev,
 {
 	const int nr_queues = dev->wl->hw->queues;
 	struct b43_dmaring *ring;
-	unsigned long flags;
 	int i;
 
 	for (i = 0; i < nr_queues; i++) {
 		ring = select_ring_by_priority(dev, i);
 
-		spin_lock_irqsave(&ring->lock, flags);
 		stats[i].len = ring->used_slots / TX_SLOTS_PER_FRAME;
 		stats[i].limit = ring->nr_slots / TX_SLOTS_PER_FRAME;
 		stats[i].count = ring->nr_tx_packets;
-		spin_unlock_irqrestore(&ring->lock, flags);
 	}
 }
 
@@ -1583,22 +1579,14 @@ void b43_dma_rx(struct b43_dmaring *ring)
 
 static void b43_dma_tx_suspend_ring(struct b43_dmaring *ring)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ring->lock, flags);
 	B43_WARN_ON(!ring->tx);
 	ring->ops->tx_suspend(ring);
-	spin_unlock_irqrestore(&ring->lock, flags);
 }
 
 static void b43_dma_tx_resume_ring(struct b43_dmaring *ring)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&ring->lock, flags);
 	B43_WARN_ON(!ring->tx);
 	ring->ops->tx_resume(ring);
-	spin_unlock_irqrestore(&ring->lock, flags);
 }
 
 void b43_dma_tx_suspend(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h
index 05dde64..f0b0838 100644
--- a/drivers/net/wireless/b43/dma.h
+++ b/drivers/net/wireless/b43/dma.h
@@ -2,7 +2,6 @@
 #define B43_DMA_H_
 
 #include <linux/ieee80211.h>
-#include <linux/spinlock.h>
 
 #include "b43.h"
 
@@ -244,8 +243,6 @@ struct b43_dmaring {
 	/* The QOS priority assigned to this ring. Only used for TX rings.
 	 * This is the mac80211 "queue" value. */
 	u8 queue_prio;
-	/* Lock, only used for TX. */
-	spinlock_t lock;
 	struct b43_wldev *dev;
 #ifdef CONFIG_B43_DEBUG
 	/* Maximum number of used slots. */
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 22d0fbd..976104f 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -477,7 +477,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
 	} else
 		b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x0802);
 	if (phy->rev >= 2)
-		b43_dummy_transmission(dev);
+		b43_dummy_transmission(dev, false, true);
 	b43_gphy_channel_switch(dev, 6, 0);
 	b43_radio_read16(dev, 0x51);	/* dummy read */
 	if (phy->type == B43_PHYTYPE_G)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index e71c8d9..e789792 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -58,6 +58,7 @@ MODULE_DESCRIPTION("Broadcom B43 wireless driver");
 MODULE_AUTHOR("Martin Langer");
 MODULE_AUTHOR("Stefano Brivio");
 MODULE_AUTHOR("Michael Buesch");
+MODULE_AUTHOR("GÃ¡bor Stefanik");
 MODULE_LICENSE("GPL");
 
 MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
@@ -80,13 +81,17 @@ static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
+static int modparam_hwtkip;
+module_param_named(hwtkip, modparam_hwtkip, int, 0444);
+MODULE_PARM_DESC(hwtkip, "Enable hardware tkip.");
+
 static int modparam_qos = 1;
 module_param_named(qos, modparam_qos, int, 0444);
 MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
 
 static int modparam_btcoex = 1;
 module_param_named(btcoex, modparam_btcoex, int, 0444);
-MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistance (default on)");
+MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistence (default on)");
 
 int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
 module_param_named(verbose, b43_modparam_verbose, int, 0644);
@@ -286,7 +291,7 @@ static struct ieee80211_supported_band b43_band_2GHz = {
 
 static void b43_wireless_core_exit(struct b43_wldev *dev);
 static int b43_wireless_core_init(struct b43_wldev *dev);
-static void b43_wireless_core_stop(struct b43_wldev *dev);
+static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
 static int b43_wireless_core_start(struct b43_wldev *dev);
 
 static int b43_ratelimit(struct b43_wl *wl)
@@ -385,7 +390,7 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
 	b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
 }
 
-u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
+u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
 {
 	u32 ret;
 
@@ -395,9 +400,8 @@ u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
 			/* Unaligned access */
 			b43_shm_control_word(dev, routing, offset >> 2);
 			ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED);
-			ret <<= 16;
 			b43_shm_control_word(dev, routing, (offset >> 2) + 1);
-			ret |= b43_read16(dev, B43_MMIO_SHM_DATA);
+			ret |= ((u32)b43_read16(dev, B43_MMIO_SHM_DATA)) << 16;
 
 			goto out;
 		}
@@ -409,20 +413,7 @@ out:
 	return ret;
 }
 
-u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
-{
-	struct b43_wl *wl = dev->wl;
-	unsigned long flags;
-	u32 ret;
-
-	spin_lock_irqsave(&wl->shm_lock, flags);
-	ret = __b43_shm_read32(dev, routing, offset);
-	spin_unlock_irqrestore(&wl->shm_lock, flags);
-
-	return ret;
-}
-
-u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
+u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
 {
 	u16 ret;
 
@@ -443,20 +434,7 @@ out:
 	return ret;
 }
 
-u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
-{
-	struct b43_wl *wl = dev->wl;
-	unsigned long flags;
-	u16 ret;
-
-	spin_lock_irqsave(&wl->shm_lock, flags);
-	ret = __b43_shm_read16(dev, routing, offset);
-	spin_unlock_irqrestore(&wl->shm_lock, flags);
-
-	return ret;
-}
-
-void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
+void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
 {
 	if (routing == B43_SHM_SHARED) {
 		B43_WARN_ON(offset & 0x0001);
@@ -464,9 +442,10 @@ void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value
 			/* Unaligned access */
 			b43_shm_control_word(dev, routing, offset >> 2);
 			b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED,
-				    (value >> 16) & 0xffff);
+				    value & 0xFFFF);
 			b43_shm_control_word(dev, routing, (offset >> 2) + 1);
-			b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
+			b43_write16(dev, B43_MMIO_SHM_DATA,
+				    (value >> 16) & 0xFFFF);
 			return;
 		}
 		offset >>= 2;
@@ -475,17 +454,7 @@ void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value
 	b43_write32(dev, B43_MMIO_SHM_DATA, value);
 }
 
-void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
-{
-	struct b43_wl *wl = dev->wl;
-	unsigned long flags;
-
-	spin_lock_irqsave(&wl->shm_lock, flags);
-	__b43_shm_write32(dev, routing, offset, value);
-	spin_unlock_irqrestore(&wl->shm_lock, flags);
-}
-
-void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
+void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
 {
 	if (routing == B43_SHM_SHARED) {
 		B43_WARN_ON(offset & 0x0001);
@@ -501,16 +470,6 @@ void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value
 	b43_write16(dev, B43_MMIO_SHM_DATA, value);
 }
 
-void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
-{
-	struct b43_wl *wl = dev->wl;
-	unsigned long flags;
-
-	spin_lock_irqsave(&wl->shm_lock, flags);
-	__b43_shm_write16(dev, routing, offset, value);
-	spin_unlock_irqrestore(&wl->shm_lock, flags);
-}
-
 /* Read HostFlags */
 u64 b43_hf_read(struct b43_wldev *dev)
 {
@@ -680,22 +639,11 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
 	b43_set_slot_time(dev, 20);
 }
 
-/* Synchronize IRQ top- and bottom-half.
- * IRQs must be masked before calling this.
- * This must not be called with the irq_lock held.
- */
-static void b43_synchronize_irq(struct b43_wldev *dev)
-{
-	synchronize_irq(dev->dev->irq);
-	tasklet_kill(&dev->isr_tasklet);
-}
-
 /* DummyTransmission function, as documented on
- * http://bcm-specs.sipsolutions.net/DummyTransmission
+ * http://bcm-v4.sipsolutions.net/802.11/DummyTransmission
  */
-void b43_dummy_transmission(struct b43_wldev *dev)
+void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
 {
-	struct b43_wl *wl = dev->wl;
 	struct b43_phy *phy = &dev->phy;
 	unsigned int i, max_loop;
 	u16 value;
@@ -707,41 +655,46 @@ void b43_dummy_transmission(struct b43_wldev *dev)
 		0x00000000,
 	};
 
-	switch (phy->type) {
-	case B43_PHYTYPE_A:
+	if (ofdm) {
 		max_loop = 0x1E;
 		buffer[0] = 0x000201CC;
-		break;
-	case B43_PHYTYPE_B:
-	case B43_PHYTYPE_G:
+	} else {
 		max_loop = 0xFA;
 		buffer[0] = 0x000B846E;
-		break;
-	default:
-		B43_WARN_ON(1);
-		return;
 	}
 
-	spin_lock_irq(&wl->irq_lock);
-	write_lock(&wl->tx_lock);
-
 	for (i = 0; i < 5; i++)
 		b43_ram_write(dev, i * 4, buffer[i]);
 
-	/* Commit writes */
-	b43_read32(dev, B43_MMIO_MACCTL);
-
 	b43_write16(dev, 0x0568, 0x0000);
-	b43_write16(dev, 0x07C0, 0x0000);
-	value = ((phy->type == B43_PHYTYPE_A) ? 1 : 0);
+	if (dev->dev->id.revision < 11)
+		b43_write16(dev, 0x07C0, 0x0000);
+	else
+		b43_write16(dev, 0x07C0, 0x0100);
+	value = (ofdm ? 0x41 : 0x40);
 	b43_write16(dev, 0x050C, value);
+	if ((phy->type == B43_PHYTYPE_N) || (phy->type == B43_PHYTYPE_LP))
+		b43_write16(dev, 0x0514, 0x1A02);
 	b43_write16(dev, 0x0508, 0x0000);
 	b43_write16(dev, 0x050A, 0x0000);
 	b43_write16(dev, 0x054C, 0x0000);
 	b43_write16(dev, 0x056A, 0x0014);
 	b43_write16(dev, 0x0568, 0x0826);
 	b43_write16(dev, 0x0500, 0x0000);
-	b43_write16(dev, 0x0502, 0x0030);
+	if (!pa_on && (phy->type == B43_PHYTYPE_N)) {
+		//SPEC TODO
+	}
+
+	switch (phy->type) {
+	case B43_PHYTYPE_N:
+		b43_write16(dev, 0x0502, 0x00D0);
+		break;
+	case B43_PHYTYPE_LP:
+		b43_write16(dev, 0x0502, 0x0050);
+		break;
+	default:
+		b43_write16(dev, 0x0502, 0x0030);
+	}
 
 	if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
 		b43_radio_write16(dev, 0x0051, 0x0017);
@@ -765,9 +718,6 @@ void b43_dummy_transmission(struct b43_wldev *dev)
 	}
 	if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
 		b43_radio_write16(dev, 0x0051, 0x0037);
-
-	write_unlock(&wl->tx_lock);
-	spin_unlock_irq(&wl->irq_lock);
 }
 
 static void key_write(struct b43_wldev *dev,
@@ -796,18 +746,19 @@ static void key_write(struct b43_wldev *dev,
 static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
 {
 	u32 addrtmp[2] = { 0, 0, };
-	u8 per_sta_keys_start = 8;
+	u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
 
 	if (b43_new_kidx_api(dev))
-		per_sta_keys_start = 4;
+		pairwise_keys_start = B43_NR_GROUP_KEYS;
 
-	B43_WARN_ON(index < per_sta_keys_start);
-	/* We have two default TX keys and possibly two default RX keys.
+	B43_WARN_ON(index < pairwise_keys_start);
+	/* We have four default TX keys and possibly four default RX keys.
 	 * Physical mac 0 is mapped to physical key 4 or 8, depending
 	 * on the firmware version.
 	 * So we must adjust the index here.
 	 */
-	index -= per_sta_keys_start;
+	index -= pairwise_keys_start;
+	B43_WARN_ON(index >= B43_NR_PAIRWISE_KEYS);
 
 	if (addr) {
 		addrtmp[0] = addr[0];
@@ -818,27 +769,90 @@ static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
 		addrtmp[1] |= ((u32) (addr[5]) << 8);
 	}
 
-	if (dev->dev->id.revision >= 5) {
-		/* Receive match transmitter address mechanism */
-		b43_shm_write32(dev, B43_SHM_RCMTA,
-				(index * 2) + 0, addrtmp[0]);
-		b43_shm_write16(dev, B43_SHM_RCMTA,
-				(index * 2) + 1, addrtmp[1]);
-	} else {
-		/* RXE (Receive Engine) and
-		 * PSM (Programmable State Machine) mechanism
-		 */
-		if (index < 8) {
-			/* TODO write to RCM 16, 19, 22 and 25 */
-		} else {
-			b43_shm_write32(dev, B43_SHM_SHARED,
-					B43_SHM_SH_PSM + (index * 6) + 0,
-					addrtmp[0]);
-			b43_shm_write16(dev, B43_SHM_SHARED,
-					B43_SHM_SH_PSM + (index * 6) + 4,
-					addrtmp[1]);
-		}
+	/* Receive match transmitter address (RCMTA) mechanism */
+	b43_shm_write32(dev, B43_SHM_RCMTA,
+			(index * 2) + 0, addrtmp[0]);
+	b43_shm_write16(dev, B43_SHM_RCMTA,
+			(index * 2) + 1, addrtmp[1]);
+}
+
+/* The ucode will use phase1 key with TEK key to decrypt rx packets.
+ * When a packet is received, the iv32 is checked.
+ * - if it doesn't the packet is returned without modification (and software
+ *   decryption can be done). That's what happen when iv16 wrap.
+ * - if it does, the rc4 key is computed, and decryption is tried.
+ *   Either it will success and B43_RX_MAC_DEC is returned,
+ *   either it fails and B43_RX_MAC_DEC|B43_RX_MAC_DECERR is returned
+ *   and the packet is not usable (it got modified by the ucode).
+ * So in order to never have B43_RX_MAC_DECERR, we should provide
+ * a iv32 and phase1key that match. Because we drop packets in case of
+ * B43_RX_MAC_DECERR, if we have a correct iv32 but a wrong phase1key, all
+ * packets will be lost without higher layer knowing (ie no resync possible
+ * until next wrap).
+ *
+ * NOTE : this should support 50 key like RCMTA because
+ * (B43_SHM_SH_KEYIDXBLOCK - B43_SHM_SH_TKIPTSCTTAK)/14 = 50
+ */
+static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
+		u16 *phase1key)
+{
+	unsigned int i;
+	u32 offset;
+	u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
+
+	if (!modparam_hwtkip)
+		return;
+
+	if (b43_new_kidx_api(dev))
+		pairwise_keys_start = B43_NR_GROUP_KEYS;
+
+	B43_WARN_ON(index < pairwise_keys_start);
+	/* We have four default TX keys and possibly four default RX keys.
+	 * Physical mac 0 is mapped to physical key 4 or 8, depending
+	 * on the firmware version.
+	 * So we must adjust the index here.
+	 */
+	index -= pairwise_keys_start;
+	B43_WARN_ON(index >= B43_NR_PAIRWISE_KEYS);
+
+	if (b43_debug(dev, B43_DBG_KEYS)) {
+		b43dbg(dev->wl, "rx_tkip_phase1_write : idx 0x%x, iv32 0x%x\n",
+				index, iv32);
+	}
+	/* Write the key to the  RX tkip shared mem */
+	offset = B43_SHM_SH_TKIPTSCTTAK + index * (10 + 4);
+	for (i = 0; i < 10; i += 2) {
+		b43_shm_write16(dev, B43_SHM_SHARED, offset + i,
+				phase1key ? phase1key[i / 2] : 0);
 	}
+	b43_shm_write16(dev, B43_SHM_SHARED, offset + i, iv32);
+	b43_shm_write16(dev, B43_SHM_SHARED, offset + i + 2, iv32 >> 16);
+}
+
+static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
+			struct ieee80211_key_conf *keyconf, const u8 *addr,
+			u32 iv32, u16 *phase1key)
+{
+	struct b43_wl *wl = hw_to_b43_wl(hw);
+	struct b43_wldev *dev;
+	int index = keyconf->hw_key_idx;
+
+	if (B43_WARN_ON(!modparam_hwtkip))
+		return;
+
+	mutex_lock(&wl->mutex);
+
+	dev = wl->current_dev;
+	if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
+		goto out_unlock;
+
+	keymac_write(dev, index, NULL);	/* First zero out mac to avoid race */
+
+	rx_tkip_phase1_write(dev, index, iv32, phase1key);
+	keymac_write(dev, index, addr);
+
+out_unlock:
+	mutex_unlock(&wl->mutex);
 }
 
 static void do_key_write(struct b43_wldev *dev,
@@ -846,20 +860,33 @@ static void do_key_write(struct b43_wldev *dev,
 			 const u8 *key, size_t key_len, const u8 *mac_addr)
 {
 	u8 buf[B43_SEC_KEYSIZE] = { 0, };
-	u8 per_sta_keys_start = 8;
+	u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
 
 	if (b43_new_kidx_api(dev))
-		per_sta_keys_start = 4;
+		pairwise_keys_start = B43_NR_GROUP_KEYS;
 
-	B43_WARN_ON(index >= dev->max_nr_keys);
+	B43_WARN_ON(index >= ARRAY_SIZE(dev->key));
 	B43_WARN_ON(key_len > B43_SEC_KEYSIZE);
 
-	if (index >= per_sta_keys_start)
+	if (index >= pairwise_keys_start)
 		keymac_write(dev, index, NULL);	/* First zero out mac. */
+	if (algorithm == B43_SEC_ALGO_TKIP) {
+		/*
+		 * We should provide an initial iv32, phase1key pair.
+		 * We could start with iv32=0 and compute the corresponding
+		 * phase1key, but this means calling ieee80211_get_tkip_key
+		 * with a fake skb (or export other tkip function).
+		 * Because we are lazy we hope iv32 won't start with
+		 * 0xffffffff and let's b43_op_update_tkip_key provide a
+		 * correct pair.
+		 */
+		rx_tkip_phase1_write(dev, index, 0xffffffff, (u16*)buf);
+	} else if (index >= pairwise_keys_start) /* clear it */
+		rx_tkip_phase1_write(dev, index, 0, NULL);
 	if (key)
 		memcpy(buf, key, key_len);
 	key_write(dev, index, algorithm, buf);
-	if (index >= per_sta_keys_start)
+	if (index >= pairwise_keys_start)
 		keymac_write(dev, index, mac_addr);
 
 	dev->key[index].algorithm = algorithm;
@@ -872,21 +899,33 @@ static int b43_key_write(struct b43_wldev *dev,
 			 struct ieee80211_key_conf *keyconf)
 {
 	int i;
-	int sta_keys_start;
-
+	int pairwise_keys_start;
+
+	/* For ALG_TKIP the key is encoded as a 256-bit (32 byte) data block:
+	 * 	- Temporal Encryption Key (128 bits)
+	 * 	- Temporal Authenticator Tx MIC Key (64 bits)
+	 * 	- Temporal Authenticator Rx MIC Key (64 bits)
+	 *
+	 * 	Hardware only store TEK
+	 */
+	if (algorithm == B43_SEC_ALGO_TKIP && key_len == 32)
+		key_len = 16;
 	if (key_len > B43_SEC_KEYSIZE)
 		return -EINVAL;
-	for (i = 0; i < dev->max_nr_keys; i++) {
+	for (i = 0; i < ARRAY_SIZE(dev->key); i++) {
 		/* Check that we don't already have this key. */
 		B43_WARN_ON(dev->key[i].keyconf == keyconf);
 	}
 	if (index < 0) {
 		/* Pairwise key. Get an empty slot for the key. */
 		if (b43_new_kidx_api(dev))
-			sta_keys_start = 4;
+			pairwise_keys_start = B43_NR_GROUP_KEYS;
 		else
-			sta_keys_start = 8;
-		for (i = sta_keys_start; i < dev->max_nr_keys; i++) {
+			pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
+		for (i = pairwise_keys_start;
+		     i < pairwise_keys_start + B43_NR_PAIRWISE_KEYS;
+		     i++) {
+			B43_WARN_ON(i >= ARRAY_SIZE(dev->key));
 			if (!dev->key[i].keyconf) {
 				/* found empty */
 				index = i;
@@ -914,7 +953,7 @@ static int b43_key_write(struct b43_wldev *dev,
 
 static int b43_key_clear(struct b43_wldev *dev, int index)
 {
-	if (B43_WARN_ON((index < 0) || (index >= dev->max_nr_keys)))
+	if (B43_WARN_ON((index < 0) || (index >= ARRAY_SIZE(dev->key))))
 		return -EINVAL;
 	do_key_write(dev, index, B43_SEC_ALGO_NONE,
 		     NULL, B43_SEC_KEYSIZE, NULL);
@@ -929,16 +968,19 @@ static int b43_key_clear(struct b43_wldev *dev, int index)
 
 static void b43_clear_keys(struct b43_wldev *dev)
 {
-	int i;
+	int i, count;
 
-	for (i = 0; i < dev->max_nr_keys; i++)
+	if (b43_new_kidx_api(dev))
+		count = B43_NR_GROUP_KEYS + B43_NR_PAIRWISE_KEYS;
+	else
+		count = B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS;
+	for (i = 0; i < count; i++)
 		b43_key_clear(dev, i);
 }
 
 static void b43_dump_keymemory(struct b43_wldev *dev)
 {
-	unsigned int i, index, offset;
-	DECLARE_MAC_BUF(macbuf);
+	unsigned int i, index, count, offset, pairwise_keys_start;
 	u8 mac[ETH_ALEN];
 	u16 algo;
 	u32 rcmta0;
@@ -952,7 +994,14 @@ static void b43_dump_keymemory(struct b43_wldev *dev)
 	hf = b43_hf_read(dev);
 	b43dbg(dev->wl, "Hardware key memory dump:  USEDEFKEYS=%u\n",
 	       !!(hf & B43_HF_USEDEFKEYS));
-	for (index = 0; index < dev->max_nr_keys; index++) {
+	if (b43_new_kidx_api(dev)) {
+		pairwise_keys_start = B43_NR_GROUP_KEYS;
+		count = B43_NR_GROUP_KEYS + B43_NR_PAIRWISE_KEYS;
+	} else {
+		pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
+		count = B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS;
+	}
+	for (index = 0; index < count; index++) {
 		key = &(dev->key[index]);
 		printk(KERN_DEBUG "Key slot %02u: %s",
 		       index, (key->keyconf == NULL) ? " " : "*");
@@ -966,15 +1015,22 @@ static void b43_dump_keymemory(struct b43_wldev *dev)
 				      B43_SHM_SH_KEYIDXBLOCK + (index * 2));
 		printk("   Algo: %04X/%02X", algo, key->algorithm);
 
-		if (index >= 4) {
+		if (index >= pairwise_keys_start) {
+			if (key->algorithm == B43_SEC_ALGO_TKIP) {
+				printk("   TKIP: ");
+				offset = B43_SHM_SH_TKIPTSCTTAK + (index - 4) * (10 + 4);
+				for (i = 0; i < 14; i += 2) {
+					u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i);
+					printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF));
+				}
+			}
 			rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA,
-						((index - 4) * 2) + 0);
+						((index - pairwise_keys_start) * 2) + 0);
 			rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA,
-						((index - 4) * 2) + 1);
+						((index - pairwise_keys_start) * 2) + 1);
 			*((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0);
 			*((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1);
-			printk("   MAC: %s",
-			       print_mac(macbuf, mac));
+			printk("   MAC: %pM", mac);
 		} else
 			printk("   DEFAULT KEY");
 		printk("\n");
@@ -1338,7 +1394,8 @@ static u16 b43_antenna_to_phyctl(int antenna)
 		return B43_TXH_PHY_ANT2;
 	case B43_ANTENNA3:
 		return B43_TXH_PHY_ANT3;
-	case B43_ANTENNA_AUTO:
+	case B43_ANTENNA_AUTO0:
+	case B43_ANTENNA_AUTO1:
 		return B43_TXH_PHY_ANT01AUTO;
 	}
 	B43_WARN_ON(1);
@@ -1431,113 +1488,6 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
 	b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset);
 }
 
-static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
-				      u16 shm_offset, u16 size,
-				      struct ieee80211_rate *rate)
-{
-	struct b43_plcp_hdr4 plcp;
-	u32 tmp;
-	__le16 dur;
-
-	plcp.data = 0;
-	b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
-	dur = ieee80211_generic_frame_duration(dev->wl->hw,
-					       dev->wl->vif, size,
-					       rate);
-	/* Write PLCP in two parts and timing for packet transfer */
-	tmp = le32_to_cpu(plcp.data);
-	b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF);
-	b43_shm_write16(dev, B43_SHM_SHARED, shm_offset + 2, tmp >> 16);
-	b43_shm_write16(dev, B43_SHM_SHARED, shm_offset + 6, le16_to_cpu(dur));
-}
-
-/* Instead of using custom probe response template, this function
- * just patches custom beacon template by:
- * 1) Changing packet type
- * 2) Patching duration field
- * 3) Stripping TIM
- */
-static const u8 *b43_generate_probe_resp(struct b43_wldev *dev,
-					 u16 *dest_size,
-					 struct ieee80211_rate *rate)
-{
-	const u8 *src_data;
-	u8 *dest_data;
-	u16 src_size, elem_size, src_pos, dest_pos;
-	__le16 dur;
-	struct ieee80211_hdr *hdr;
-	size_t ie_start;
-
-	src_size = dev->wl->current_beacon->len;
-	src_data = (const u8 *)dev->wl->current_beacon->data;
-
-	/* Get the start offset of the variable IEs in the packet. */
-	ie_start = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
-	B43_WARN_ON(ie_start != offsetof(struct ieee80211_mgmt, u.beacon.variable));
-
-	if (B43_WARN_ON(src_size < ie_start))
-		return NULL;
-
-	dest_data = kmalloc(src_size, GFP_ATOMIC);
-	if (unlikely(!dest_data))
-		return NULL;
-
-	/* Copy the static data and all Information Elements, except the TIM. */
-	memcpy(dest_data, src_data, ie_start);
-	src_pos = ie_start;
-	dest_pos = ie_start;
-	for ( ; src_pos < src_size - 2; src_pos += elem_size) {
-		elem_size = src_data[src_pos + 1] + 2;
-		if (src_data[src_pos] == 5) {
-			/* This is the TIM. */
-			continue;
-		}
-		memcpy(dest_data + dest_pos, src_data + src_pos,
-		       elem_size);
-		dest_pos += elem_size;
-	}
-	*dest_size = dest_pos;
-	hdr = (struct ieee80211_hdr *)dest_data;
-
-	/* Set the frame control. */
-	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-					 IEEE80211_STYPE_PROBE_RESP);
-	dur = ieee80211_generic_frame_duration(dev->wl->hw,
-					       dev->wl->vif, *dest_size,
-					       rate);
-	hdr->duration_id = dur;
-
-	return dest_data;
-}
-
-static void b43_write_probe_resp_template(struct b43_wldev *dev,
-					  u16 ram_offset,
-					  u16 shm_size_offset,
-					  struct ieee80211_rate *rate)
-{
-	const u8 *probe_resp_data;
-	u16 size;
-
-	size = dev->wl->current_beacon->len;
-	probe_resp_data = b43_generate_probe_resp(dev, &size, rate);
-	if (unlikely(!probe_resp_data))
-		return;
-
-	/* Looks like PLCP headers plus packet timings are stored for
-	 * all possible basic rates
-	 */
-	b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]);
-	b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]);
-	b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]);
-	b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]);
-
-	size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6));
-	b43_write_template_common(dev, probe_resp_data,
-				  size, ram_offset, shm_size_offset,
-				  rate->hw_value);
-	kfree(probe_resp_data);
-}
-
 static void b43_upload_beacon0(struct b43_wldev *dev)
 {
 	struct b43_wl *wl = dev->wl;
@@ -1545,10 +1495,6 @@ static void b43_upload_beacon0(struct b43_wldev *dev)
 	if (wl->beacon0_uploaded)
 		return;
 	b43_write_beacon_template(dev, 0x68, 0x18);
-	/* FIXME: Probe resp upload doesn't really belong here,
-	 *        but we don't use that feature anyway. */
-	b43_write_probe_resp_template(dev, 0x268, 0x4A,
-				      &__b43_ratetable[3]);
 	wl->beacon0_uploaded = 1;
 }
 
@@ -1611,6 +1557,27 @@ static void handle_irq_beacon(struct b43_wldev *dev)
 	}
 }
 
+static void b43_do_beacon_update_trigger_work(struct b43_wldev *dev)
+{
+	u32 old_irq_mask = dev->irq_mask;
+
+	/* update beacon right away or defer to irq */
+	handle_irq_beacon(dev);
+	if (old_irq_mask != dev->irq_mask) {
+		/* The handler updated the IRQ mask. */
+		B43_WARN_ON(!dev->irq_mask);
+		if (b43_read32(dev, B43_MMIO_GEN_IRQ_MASK)) {
+			b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
+		} else {
+			/* Device interrupts are currently disabled. That means
+			 * we just ran the hardirq handler and scheduled the
+			 * IRQ thread. The thread will write the IRQ mask when
+			 * it finished, so there's nothing to do here. Writing
+			 * the mask _here_ would incorrectly re-enable IRQs. */
+		}
+	}
+}
+
 static void b43_beacon_update_trigger_work(struct work_struct *work)
 {
 	struct b43_wl *wl = container_of(work, struct b43_wl,
@@ -1620,19 +1587,22 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
 	mutex_lock(&wl->mutex);
 	dev = wl->current_dev;
 	if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
-		spin_lock_irq(&wl->irq_lock);
-		/* update beacon right away or defer to irq */
-		handle_irq_beacon(dev);
-		/* The handler might have updated the IRQ mask. */
-		b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
-		mmiowb();
-		spin_unlock_irq(&wl->irq_lock);
+		if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
+			/* wl->mutex is enough. */
+			b43_do_beacon_update_trigger_work(dev);
+			mmiowb();
+		} else {
+			spin_lock_irq(&wl->hardirq_lock);
+			b43_do_beacon_update_trigger_work(dev);
+			mmiowb();
+			spin_unlock_irq(&wl->hardirq_lock);
+		}
 	}
 	mutex_unlock(&wl->mutex);
 }
 
 /* Asynchronously update the packet templates in template RAM.
- * Locking: Requires wl->irq_lock to be locked. */
+ * Locking: Requires wl->mutex to be locked. */
 static void b43_update_templates(struct b43_wl *wl)
 {
 	struct sk_buff *beacon;
@@ -1656,7 +1626,7 @@ static void b43_update_templates(struct b43_wl *wl)
 	wl->current_beacon = beacon;
 	wl->beacon0_uploaded = 0;
 	wl->beacon1_uploaded = 0;
-	queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
+	ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
 }
 
 static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
@@ -1769,18 +1739,15 @@ out:
 			B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK);
 }
 
-/* Interrupt handler bottom-half */
-static void b43_interrupt_tasklet(struct b43_wldev *dev)
+static void b43_do_interrupt_thread(struct b43_wldev *dev)
 {
 	u32 reason;
 	u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
 	u32 merged_dma_reason = 0;
 	int i;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev->wl->irq_lock, flags);
 
-	B43_WARN_ON(b43_status(dev) != B43_STAT_STARTED);
+	if (unlikely(b43_status(dev) != B43_STAT_STARTED))
+		return;
 
 	reason = dev->irq_reason;
 	for (i = 0; i < ARRAY_SIZE(dma_reason); i++) {
@@ -1813,8 +1780,6 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
 			       dma_reason[2], dma_reason[3],
 			       dma_reason[4], dma_reason[5]);
 			b43_controller_restart(dev, "DMA error");
-			mmiowb();
-			spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
 			return;
 		}
 		if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -1858,47 +1823,36 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
 	if (reason & B43_IRQ_TX_OK)
 		handle_irq_transmit_status(dev);
 
+	/* Re-enable interrupts on the device by restoring the current interrupt mask. */
 	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
-	mmiowb();
-	spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
 }
 
-static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason)
+/* Interrupt thread handler. Handles device interrupts in thread context. */
+static irqreturn_t b43_interrupt_thread_handler(int irq, void *dev_id)
 {
-	b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason);
+	struct b43_wldev *dev = dev_id;
 
-	b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]);
-	b43_write32(dev, B43_MMIO_DMA1_REASON, dev->dma_reason[1]);
-	b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
-	b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
-	b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
-/* Unused ring
-	b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
-*/
+	mutex_lock(&dev->wl->mutex);
+	b43_do_interrupt_thread(dev);
+	mmiowb();
+	mutex_unlock(&dev->wl->mutex);
+
+	return IRQ_HANDLED;
 }
 
-/* Interrupt handler top-half */
-static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
+static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
 {
-	irqreturn_t ret = IRQ_NONE;
-	struct b43_wldev *dev = dev_id;
 	u32 reason;
 
-	B43_WARN_ON(!dev);
-
-	spin_lock(&dev->wl->irq_lock);
+	/* This code runs under wl->hardirq_lock, but _only_ on non-SDIO busses.
+	 * On SDIO, this runs under wl->mutex. */
 
-	if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
-		/* This can only happen on shared IRQ lines. */
-		goto out;
-	}
 	reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
 	if (reason == 0xffffffff)	/* shared IRQ */
-		goto out;
-	ret = IRQ_HANDLED;
+		return IRQ_NONE;
 	reason &= dev->irq_mask;
 	if (!reason)
-		goto out;
+		return IRQ_HANDLED;
 
 	dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
 	    & 0x0001DC00;
@@ -1915,15 +1869,38 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
 	    & 0x0000DC00;
 */
 
-	b43_interrupt_ack(dev, reason);
-	/* disable all IRQs. They are enabled again in the bottom half. */
+	/* ACK the interrupt. */
+	b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason);
+	b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]);
+	b43_write32(dev, B43_MMIO_DMA1_REASON, dev->dma_reason[1]);
+	b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
+	b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
+	b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
+/* Unused ring
+	b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
+*/
+
+	/* Disable IRQs on the device. The IRQ thread handler will re-enable them. */
 	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
-	/* save the reason code and call our bottom half. */
+	/* Save the reason bitmasks for the IRQ thread handler. */
 	dev->irq_reason = reason;
-	tasklet_schedule(&dev->isr_tasklet);
-out:
+
+	return IRQ_WAKE_THREAD;
+}
+
+/* Interrupt handler top-half. This runs with interrupts disabled. */
+static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
+{
+	struct b43_wldev *dev = dev_id;
+	irqreturn_t ret;
+
+	if (unlikely(b43_status(dev) < B43_STAT_STARTED))
+		return IRQ_NONE;
+
+	spin_lock(&dev->wl->hardirq_lock);
+	ret = b43_do_interrupt(dev);
 	mmiowb();
-	spin_unlock(&dev->wl->irq_lock);
+	spin_unlock(&dev->wl->hardirq_lock);
 
 	return ret;
 }
@@ -2061,8 +2038,12 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 		filename = "ucode5";
 	else if ((rev >= 11) && (rev <= 12))
 		filename = "ucode11";
-	else if (rev >= 13)
+	else if (rev == 13)
 		filename = "ucode13";
+	else if (rev == 14)
+		filename = "ucode14";
+	else if (rev >= 15)
+		filename = "ucode15";
 	else
 		goto err_no_ucode;
 	err = b43_do_request_fw(ctx, filename, &fw->ucode);
@@ -2110,6 +2091,16 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 		else
 			goto err_no_initvals;
 		break;
+	case B43_PHYTYPE_LP:
+		if (rev == 13)
+			filename = "lp0initvals13";
+		else if (rev == 14)
+			filename = "lp0initvals14";
+		else if (rev >= 15)
+			filename = "lp0initvals15";
+		else
+			goto err_no_initvals;
+		break;
 	default:
 		goto err_no_initvals;
 	}
@@ -2144,6 +2135,16 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
 		else
 			goto err_no_initvals;
 		break;
+	case B43_PHYTYPE_LP:
+		if (rev == 13)
+			filename = "lp0bsinitvals13";
+		else if (rev == 14)
+			filename = "lp0bsinitvals14";
+		else if (rev >= 15)
+			filename = "lp0bsinitvals15";
+		else
+			goto err_no_initvals;
+		break;
 	default:
 		goto err_no_initvals;
 	}
@@ -2288,11 +2289,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
 			err = -ENODEV;
 			goto error;
 		}
-		msleep_interruptible(50);
-		if (signal_pending(current)) {
-			err = -EINTR;
-			goto error;
-		}
+		msleep(50);
 	}
 	b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);	/* dummy read */
 
@@ -2671,6 +2668,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
 	case B43_PHYTYPE_A:
 	case B43_PHYTYPE_G:
 	case B43_PHYTYPE_N:
+	case B43_PHYTYPE_LP:
 		b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
 		b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
 		b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
@@ -2916,7 +2914,7 @@ out_requeue:
 		delay = msecs_to_jiffies(50);
 	else
 		delay = round_jiffies_relative(HZ * 15);
-	queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);
+	ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
 out:
 	mutex_unlock(&wl->mutex);
 }
@@ -2927,15 +2925,16 @@ static void b43_periodic_tasks_setup(struct b43_wldev *dev)
 
 	dev->periodic_state = 0;
 	INIT_DELAYED_WORK(work, b43_periodic_work_handler);
-	queue_delayed_work(dev->wl->hw->workqueue, work, 0);
+	ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
 }
 
 /* Check if communication with the device works correctly. */
 static int b43_validate_chipaccess(struct b43_wldev *dev)
 {
-	u32 v, backup;
+	u32 v, backup0, backup4;
 
-	backup = b43_shm_read32(dev, B43_SHM_SHARED, 0);
+	backup0 = b43_shm_read32(dev, B43_SHM_SHARED, 0);
+	backup4 = b43_shm_read32(dev, B43_SHM_SHARED, 4);
 
 	/* Check for read/write and endianness problems. */
 	b43_shm_write32(dev, B43_SHM_SHARED, 0, 0x55AAAA55);
@@ -2945,7 +2944,23 @@ static int b43_validate_chipaccess(struct b43_wldev *dev)
 	if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)
 		goto error;
 
-	b43_shm_write32(dev, B43_SHM_SHARED, 0, backup);
+	/* Check if unaligned 32bit SHM_SHARED access works properly.
+	 * However, don't bail out on failure, because it's noncritical. */
+	b43_shm_write16(dev, B43_SHM_SHARED, 0, 0x1122);
+	b43_shm_write16(dev, B43_SHM_SHARED, 2, 0x3344);
+	b43_shm_write16(dev, B43_SHM_SHARED, 4, 0x5566);
+	b43_shm_write16(dev, B43_SHM_SHARED, 6, 0x7788);
+	if (b43_shm_read32(dev, B43_SHM_SHARED, 2) != 0x55663344)
+		b43warn(dev->wl, "Unaligned 32bit SHM read access is broken\n");
+	b43_shm_write32(dev, B43_SHM_SHARED, 2, 0xAABBCCDD);
+	if (b43_shm_read16(dev, B43_SHM_SHARED, 0) != 0x1122 ||
+	    b43_shm_read16(dev, B43_SHM_SHARED, 2) != 0xCCDD ||
+	    b43_shm_read16(dev, B43_SHM_SHARED, 4) != 0xAABB ||
+	    b43_shm_read16(dev, B43_SHM_SHARED, 6) != 0x7788)
+		b43warn(dev->wl, "Unaligned 32bit SHM write access is broken\n");
+
+	b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);
+	b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4);
 
 	if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) {
 		/* The 32bit register shadows the two 16bit registers
@@ -2972,17 +2987,14 @@ error:
 
 static void b43_security_init(struct b43_wldev *dev)
 {
-	dev->max_nr_keys = (dev->dev->id.revision >= 5) ? 58 : 20;
-	B43_WARN_ON(dev->max_nr_keys > ARRAY_SIZE(dev->key));
 	dev->ktp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_KTP);
 	/* KTP is a word address, but we address SHM bytewise.
 	 * So multiply by two.
 	 */
 	dev->ktp *= 2;
-	if (dev->dev->id.revision >= 5) {
-		/* Number of RCMTA address slots */
-		b43_write16(dev, B43_MMIO_RCMTA_COUNT, dev->max_nr_keys - 8);
-	}
+	/* Number of RCMTA address slots */
+	b43_write16(dev, B43_MMIO_RCMTA_COUNT, B43_NR_PAIRWISE_KEYS);
+	/* Clear the key memory. */
 	b43_clear_keys(dev);
 }
 
@@ -2990,15 +3002,12 @@ static void b43_security_init(struct b43_wldev *dev)
 static int b43_rng_read(struct hwrng *rng, u32 *data)
 {
 	struct b43_wl *wl = (struct b43_wl *)rng->priv;
-	unsigned long flags;
 
-	/* Don't take wl->mutex here, as it could deadlock with
-	 * hwrng internal locking. It's not needed to take
-	 * wl->mutex here, anyway. */
+	/* FIXME: We need to take wl->mutex here to make sure the device
+	 * is not going away from under our ass. However it could deadlock
+	 * with hwrng internal locking. */
 
-	spin_lock_irqsave(&wl->irq_lock, flags);
 	*data = b43_read16(wl->current_dev, B43_MMIO_RNG);
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
 
 	return (sizeof(u16));
 }
@@ -3034,46 +3043,52 @@ static int b43_rng_init(struct b43_wl *wl)
 	return err;
 }
 
-static int b43_op_tx(struct ieee80211_hw *hw,
-		     struct sk_buff *skb)
+static void b43_tx_work(struct work_struct *work)
 {
-	struct b43_wl *wl = hw_to_b43_wl(hw);
-	struct b43_wldev *dev = wl->current_dev;
-	unsigned long flags;
-	int err;
+	struct b43_wl *wl = container_of(work, struct b43_wl, tx_work);
+	struct b43_wldev *dev;
+	struct sk_buff *skb;
+	int err = 0;
 
-	if (unlikely(skb->len < 2 + 2 + 6)) {
-		/* Too short, this can't be a valid frame. */
-		goto drop_packet;
+	mutex_lock(&wl->mutex);
+	dev = wl->current_dev;
+	if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED)) {
+		mutex_unlock(&wl->mutex);
+		return;
 	}
-	B43_WARN_ON(skb_shinfo(skb)->nr_frags);
-	if (unlikely(!dev))
-		goto drop_packet;
 
-	/* Transmissions on seperate queues can run concurrently. */
-	read_lock_irqsave(&wl->tx_lock, flags);
+	while (skb_queue_len(&wl->tx_queue)) {
+		skb = skb_dequeue(&wl->tx_queue);
 
-	err = -ENODEV;
-	if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
 		if (b43_using_pio_transfers(dev))
 			err = b43_pio_tx(dev, skb);
 		else
 			err = b43_dma_tx(dev, skb);
+		if (unlikely(err))
+			dev_kfree_skb(skb); /* Drop it */
 	}
 
-	read_unlock_irqrestore(&wl->tx_lock, flags);
+	mutex_unlock(&wl->mutex);
+}
 
-	if (unlikely(err))
-		goto drop_packet;
-	return NETDEV_TX_OK;
+static int b43_op_tx(struct ieee80211_hw *hw,
+		     struct sk_buff *skb)
+{
+	struct b43_wl *wl = hw_to_b43_wl(hw);
+
+	if (unlikely(skb->len < 2 + 2 + 6)) {
+		/* Too short, this can't be a valid frame. */
+		dev_kfree_skb_any(skb);
+		return NETDEV_TX_OK;
+	}
+	B43_WARN_ON(skb_shinfo(skb)->nr_frags);
+
+	skb_queue_tail(&wl->tx_queue, skb);
+	ieee80211_queue_work(wl->hw, &wl->tx_work);
 
-drop_packet:
-	/* We can not transmit this packet. Drop it. */
-	dev_kfree_skb_any(skb);
 	return NETDEV_TX_OK;
 }
 
-/* Locking: wl->irq_lock */
 static void b43_qos_params_upload(struct b43_wldev *dev,
 				  const struct ieee80211_tx_queue_params *p,
 				  u16 shm_offset)
@@ -3082,6 +3097,9 @@ static void b43_qos_params_upload(struct b43_wldev *dev,
 	int bslots, tmp;
 	unsigned int i;
 
+	if (!dev->qos_enabled)
+		return;
+
 	bslots = b43_read16(dev, B43_MMIO_RNG) & p->cw_min;
 
 	memset(&params, 0, sizeof(params));
@@ -3127,6 +3145,9 @@ static void b43_qos_upload_all(struct b43_wldev *dev)
 	struct b43_qos_params *params;
 	unsigned int i;
 
+	if (!dev->qos_enabled)
+		return;
+
 	BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
 		     ARRAY_SIZE(wl->qos_params));
 
@@ -3186,6 +3207,16 @@ static void b43_qos_clear(struct b43_wl *wl)
 /* Initialize the core's QOS capabilities */
 static void b43_qos_init(struct b43_wldev *dev)
 {
+	if (!dev->qos_enabled) {
+		/* Disable QOS support. */
+		b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_EDCF);
+		b43_write16(dev, B43_MMIO_IFSCTL,
+			    b43_read16(dev, B43_MMIO_IFSCTL)
+			    & ~B43_MMIO_IFSCTL_USE_EDCF);
+		b43dbg(dev->wl, "QoS disabled\n");
+		return;
+	}
+
 	/* Upload the current QOS parameters. */
 	b43_qos_upload_all(dev);
 
@@ -3194,6 +3225,7 @@ static void b43_qos_init(struct b43_wldev *dev)
 	b43_write16(dev, B43_MMIO_IFSCTL,
 		    b43_read16(dev, B43_MMIO_IFSCTL)
 		    | B43_MMIO_IFSCTL_USE_EDCF);
+	b43dbg(dev->wl, "QoS enabled\n");
 }
 
 static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
@@ -3235,22 +3267,20 @@ static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
 			       struct ieee80211_tx_queue_stats *stats)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
-	struct b43_wldev *dev = wl->current_dev;
-	unsigned long flags;
+	struct b43_wldev *dev;
 	int err = -ENODEV;
 
-	if (!dev)
-		goto out;
-	spin_lock_irqsave(&wl->irq_lock, flags);
-	if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
+	mutex_lock(&wl->mutex);
+	dev = wl->current_dev;
+	if (dev && b43_status(dev) >= B43_STAT_STARTED) {
 		if (b43_using_pio_transfers(dev))
 			b43_pio_get_tx_stats(dev, stats);
 		else
 			b43_dma_get_tx_stats(dev, stats);
 		err = 0;
 	}
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
-out:
+	mutex_unlock(&wl->mutex);
+
 	return err;
 }
 
@@ -3258,11 +3288,10 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
 			    struct ieee80211_low_level_stats *stats)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
-	unsigned long flags;
 
-	spin_lock_irqsave(&wl->irq_lock, flags);
+	mutex_lock(&wl->mutex);
 	memcpy(stats, &wl->ieee_stats, sizeof(*stats));
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
+	mutex_unlock(&wl->mutex);
 
 	return 0;
 }
@@ -3274,7 +3303,6 @@ static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
 	u64 tsf;
 
 	mutex_lock(&wl->mutex);
-	spin_lock_irq(&wl->irq_lock);
 	dev = wl->current_dev;
 
 	if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
@@ -3282,7 +3310,6 @@ static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
 	else
 		tsf = 0;
 
-	spin_unlock_irq(&wl->irq_lock);
 	mutex_unlock(&wl->mutex);
 
 	return tsf;
@@ -3294,13 +3321,11 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
 	struct b43_wldev *dev;
 
 	mutex_lock(&wl->mutex);
-	spin_lock_irq(&wl->irq_lock);
 	dev = wl->current_dev;
 
 	if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
 		b43_tsf_write(dev, tsf);
 
-	spin_unlock_irq(&wl->irq_lock);
 	mutex_unlock(&wl->mutex);
 }
 
@@ -3386,7 +3411,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan)
 	prev_status = b43_status(down_dev);
 	/* Shutdown the currently running core. */
 	if (prev_status >= B43_STAT_STARTED)
-		b43_wireless_core_stop(down_dev);
+		down_dev = b43_wireless_core_stop(down_dev);
 	if (prev_status >= B43_STAT_INITIALIZED)
 		b43_wireless_core_exit(down_dev);
 
@@ -3450,7 +3475,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
 	struct b43_wldev *dev;
 	struct b43_phy *phy;
 	struct ieee80211_conf *conf = &hw->conf;
-	unsigned long flags;
 	int antenna;
 	int err = 0;
 
@@ -3481,13 +3505,11 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
 
 	/* Adjust the desired TX power level. */
 	if (conf->power_level != 0) {
-		spin_lock_irqsave(&wl->irq_lock, flags);
 		if (conf->power_level != phy->desired_txpower) {
 			phy->desired_txpower = conf->power_level;
 			b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME |
 						   B43_TXPWR_IGNORE_TSSI);
 		}
-		spin_unlock_irqrestore(&wl->irq_lock, flags);
 	}
 
 	/* Antennas for RX and management frame TX. */
@@ -3572,7 +3594,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev;
-	unsigned long flags;
 
 	mutex_lock(&wl->mutex);
 
@@ -3582,7 +3603,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
 
 	B43_WARN_ON(wl->vif != vif);
 
-	spin_lock_irqsave(&wl->irq_lock, flags);
 	if (changed & BSS_CHANGED_BSSID) {
 		if (conf->bssid)
 			memcpy(wl->bssid, conf->bssid, ETH_ALEN);
@@ -3600,7 +3620,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
 		if (changed & BSS_CHANGED_BSSID)
 			b43_write_mac_bssid_templates(dev);
 	}
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
 
 	b43_mac_suspend(dev);
 
@@ -3641,15 +3660,6 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		return -ENOSPC; /* User disabled HW-crypto */
 
 	mutex_lock(&wl->mutex);
-	spin_lock_irq(&wl->irq_lock);
-	write_lock(&wl->tx_lock);
-	/* Why do we need all this locking here?
-	 * mutex     -> Every config operation must take it.
-	 * irq_lock  -> We modify the dev->key array, which is accessed
-	 *              in the IRQ handlers.
-	 * tx_lock   -> We modify the dev->key array, which is accessed
-	 *              in the TX handler.
-	 */
 
 	dev = wl->current_dev;
 	err = -ENODEV;
@@ -3687,8 +3697,10 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
 	switch (cmd) {
 	case SET_KEY:
-		if (algorithm == B43_SEC_ALGO_TKIP) {
-			/* FIXME: No TKIP hardware encryption for now. */
+		if (algorithm == B43_SEC_ALGO_TKIP &&
+		    (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ||
+		    !modparam_hwtkip)) {
+			/* We support only pairwise key */
 			err = -EOPNOTSUPP;
 			goto out_unlock;
 		}
@@ -3718,6 +3730,8 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 				     b43_hf_read(dev) & ~B43_HF_USEDEFKEYS);
 		}
 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+		if (algorithm == B43_SEC_ALGO_TKIP)
+			key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
 		break;
 	case DISABLE_KEY: {
 		err = b43_key_clear(dev, key->hw_key_idx);
@@ -3737,8 +3751,6 @@ out_unlock:
 		       sta ? sta->addr : bcast_addr);
 		b43_dump_keymemory(dev);
 	}
-	write_unlock(&wl->tx_lock);
-	spin_unlock_irq(&wl->irq_lock);
 	mutex_unlock(&wl->mutex);
 
 	return err;
@@ -3746,18 +3758,18 @@ out_unlock:
 
 static void b43_op_configure_filter(struct ieee80211_hw *hw,
 				    unsigned int changed, unsigned int *fflags,
-				    int mc_count, struct dev_addr_list *mc_list)
+				    u64 multicast)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
-	struct b43_wldev *dev = wl->current_dev;
-	unsigned long flags;
+	struct b43_wldev *dev;
 
+	mutex_lock(&wl->mutex);
+	dev = wl->current_dev;
 	if (!dev) {
 		*fflags = 0;
-		return;
+		goto out_unlock;
 	}
 
-	spin_lock_irqsave(&wl->irq_lock, flags);
 	*fflags &= FIF_PROMISC_IN_BSS |
 		  FIF_ALLMULTI |
 		  FIF_FCSFAIL |
@@ -3778,41 +3790,70 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
 
 	if (changed && b43_status(dev) >= B43_STAT_INITIALIZED)
 		b43_adjust_opmode(dev);
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
+
+out_unlock:
+	mutex_unlock(&wl->mutex);
 }
 
-/* Locking: wl->mutex */
-static void b43_wireless_core_stop(struct b43_wldev *dev)
+/* Locking: wl->mutex
+ * Returns the current dev. This might be different from the passed in dev,
+ * because the core might be gone away while we unlocked the mutex. */
+static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
 {
 	struct b43_wl *wl = dev->wl;
-	unsigned long flags;
+	struct b43_wldev *orig_dev;
 
-	if (b43_status(dev) < B43_STAT_STARTED)
-		return;
+redo:
+	if (!dev || b43_status(dev) < B43_STAT_STARTED)
+		return dev;
 
-	/* Disable and sync interrupts. We must do this before than
-	 * setting the status to INITIALIZED, as the interrupt handler
-	 * won't care about IRQs then. */
-	spin_lock_irqsave(&wl->irq_lock, flags);
-	b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
-	b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);	/* flush */
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
-	b43_synchronize_irq(dev);
+	/* Cancel work. Unlock to avoid deadlocks. */
+	mutex_unlock(&wl->mutex);
+	cancel_delayed_work_sync(&dev->periodic_work);
+	cancel_work_sync(&wl->tx_work);
+	mutex_lock(&wl->mutex);
+	dev = wl->current_dev;
+	if (!dev || b43_status(dev) < B43_STAT_STARTED) {
+		/* Whoops, aliens ate up the device while we were unlocked. */
+		return dev;
+	}
 
-	write_lock_irqsave(&wl->tx_lock, flags);
+	/* Disable interrupts on the device. */
 	b43_set_status(dev, B43_STAT_INITIALIZED);
-	write_unlock_irqrestore(&wl->tx_lock, flags);
-
-	b43_pio_stop(dev);
+	if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
+		/* wl->mutex is locked. That is enough. */
+		b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
+		b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);	/* Flush */
+	} else {
+		spin_lock_irq(&wl->hardirq_lock);
+		b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
+		b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);	/* Flush */
+		spin_unlock_irq(&wl->hardirq_lock);
+	}
+	/* Synchronize the interrupt handlers. Unlock to avoid deadlocks. */
+	orig_dev = dev;
 	mutex_unlock(&wl->mutex);
-	/* Must unlock as it would otherwise deadlock. No races here.
-	 * Cancel the possibly running self-rearming periodic work. */
-	cancel_delayed_work_sync(&dev->periodic_work);
+	synchronize_irq(dev->dev->irq);
 	mutex_lock(&wl->mutex);
+	dev = wl->current_dev;
+	if (!dev)
+		return dev;
+	if (dev != orig_dev) {
+		if (b43_status(dev) >= B43_STAT_STARTED)
+			goto redo;
+		return dev;
+	}
+	B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK));
+
+	/* Drain the TX queue */
+	while (skb_queue_len(&wl->tx_queue))
+		dev_kfree_skb(skb_dequeue(&wl->tx_queue));
 
 	b43_mac_suspend(dev);
 	free_irq(dev->dev->irq, dev);
 	b43dbg(wl, "Wireless interface stopped\n");
+
+	return dev;
 }
 
 /* Locking: wl->mutex */
@@ -3823,8 +3864,9 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
 	B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
 
 	drain_txstatus_queue(dev);
-	err = request_irq(dev->dev->irq, b43_interrupt_handler,
-			  IRQF_SHARED, KBUILD_MODNAME, dev);
+	err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
+				   b43_interrupt_thread_handler,
+				   IRQF_SHARED, KBUILD_MODNAME, dev);
 	if (err) {
 		b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
 		goto out;
@@ -3885,7 +3927,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 #endif
 #ifdef CONFIG_B43_PHY_LP
 	case B43_PHYTYPE_LP:
-		if (phy_rev > 1)
+		if (phy_rev > 2)
 			unsupported = 1;
 		break;
 #endif
@@ -3942,7 +3984,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
 			unsupported = 1;
 		break;
 	case B43_PHYTYPE_LP:
-		if (radio_ver != 0x2062)
+		if (radio_ver != 0x2062 && radio_ver != 0x2063)
 			unsupported = 1;
 		break;
 	default:
@@ -4046,16 +4088,20 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
 	    bus->pcicore.dev->id.revision <= 5) {
 		/* IMCFGLO timeouts workaround. */
 		tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
-		tmp &= ~SSB_IMCFGLO_REQTO;
-		tmp &= ~SSB_IMCFGLO_SERTO;
 		switch (bus->bustype) {
 		case SSB_BUSTYPE_PCI:
 		case SSB_BUSTYPE_PCMCIA:
+			tmp &= ~SSB_IMCFGLO_REQTO;
+			tmp &= ~SSB_IMCFGLO_SERTO;
 			tmp |= 0x32;
 			break;
 		case SSB_BUSTYPE_SSB:
+			tmp &= ~SSB_IMCFGLO_REQTO;
+			tmp &= ~SSB_IMCFGLO_SERTO;
 			tmp |= 0x53;
 			break;
+		default:
+			break;
 		}
 		ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
 	}
@@ -4103,8 +4149,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
 {
 	u32 macctl;
 
-	B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED);
-	if (b43_status(dev) != B43_STAT_INITIALIZED)
+	B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
+	if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
 		return;
 	b43_set_status(dev, B43_STAT_UNINIT);
 
@@ -4237,6 +4283,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
 	if (!dev->suspend_in_progress)
 		b43_rng_init(wl);
 
+	ieee80211_wake_queues(dev->wl->hw);
+
 	b43_set_status(dev, B43_STAT_INITIALIZED);
 
 	if (!dev->suspend_in_progress)
@@ -4257,7 +4305,6 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev;
-	unsigned long flags;
 	int err = -EOPNOTSUPP;
 
 	/* TODO: allow WDS/AP devices to coexist */
@@ -4281,12 +4328,10 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
 	wl->if_type = conf->type;
 	memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
 
-	spin_lock_irqsave(&wl->irq_lock, flags);
 	b43_adjust_opmode(dev);
 	b43_set_pretbtt(dev);
 	b43_set_synth_pu_delay(dev, 0);
 	b43_upload_card_macaddress(dev);
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
 
 	err = 0;
  out_mutex_unlock:
@@ -4300,7 +4345,6 @@ static void b43_op_remove_interface(struct ieee80211_hw *hw,
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev = wl->current_dev;
-	unsigned long flags;
 
 	b43dbg(wl, "Removing Interface type %d\n", conf->type);
 
@@ -4312,11 +4356,9 @@ static void b43_op_remove_interface(struct ieee80211_hw *hw,
 
 	wl->operating = 0;
 
-	spin_lock_irqsave(&wl->irq_lock, flags);
 	b43_adjust_opmode(dev);
 	memset(wl->mac_addr, 0, ETH_ALEN);
 	b43_upload_card_macaddress(dev);
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
 
 	mutex_unlock(&wl->mutex);
 }
@@ -4376,10 +4418,15 @@ static void b43_op_stop(struct ieee80211_hw *hw)
 	cancel_work_sync(&(wl->beacon_update_trigger));
 
 	mutex_lock(&wl->mutex);
-	if (b43_status(dev) >= B43_STAT_STARTED)
-		b43_wireless_core_stop(dev);
+	if (b43_status(dev) >= B43_STAT_STARTED) {
+		dev = b43_wireless_core_stop(dev);
+		if (!dev)
+			goto out_unlock;
+	}
 	b43_wireless_core_exit(dev);
 	wl->radio_enabled = 0;
+
+out_unlock:
 	mutex_unlock(&wl->mutex);
 
 	cancel_work_sync(&(wl->txpower_adjust_work));
@@ -4389,11 +4436,10 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
 				 struct ieee80211_sta *sta, bool set)
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
-	unsigned long flags;
 
-	spin_lock_irqsave(&wl->irq_lock, flags);
+	mutex_lock(&wl->mutex);
 	b43_update_templates(wl);
-	spin_unlock_irqrestore(&wl->irq_lock, flags);
+	mutex_unlock(&wl->mutex);
 
 	return 0;
 }
@@ -4445,6 +4491,7 @@ static const struct ieee80211_ops b43_hw_ops = {
 	.bss_info_changed	= b43_op_bss_info_changed,
 	.configure_filter	= b43_op_configure_filter,
 	.set_key		= b43_op_set_key,
+	.update_tkip_key	= b43_op_update_tkip_key,
 	.get_stats		= b43_op_get_stats,
 	.get_tx_stats		= b43_op_get_tx_stats,
 	.get_tsf		= b43_op_get_tsf,
@@ -4473,8 +4520,13 @@ static void b43_chip_reset(struct work_struct *work)
 
 	prev_status = b43_status(dev);
 	/* Bring the device down... */
-	if (prev_status >= B43_STAT_STARTED)
-		b43_wireless_core_stop(dev);
+	if (prev_status >= B43_STAT_STARTED) {
+		dev = b43_wireless_core_stop(dev);
+		if (!dev) {
+			err = -ENODEV;
+			goto out;
+		}
+	}
 	if (prev_status >= B43_STAT_INITIALIZED)
 		b43_wireless_core_exit(dev);
 
@@ -4580,9 +4632,12 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
 		case B43_PHYTYPE_A:
 			have_5ghz_phy = 1;
 			break;
+		case B43_PHYTYPE_LP: //FIXME not always!
+#if 0 //FIXME enabling 5GHz causes a NULL pointer dereference
+			have_5ghz_phy = 1;
+#endif
 		case B43_PHYTYPE_G:
 		case B43_PHYTYPE_N:
-		case B43_PHYTYPE_LP:
 			have_2ghz_phy = 1;
 			break;
 		default:
@@ -4597,7 +4652,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
 	}
 	if (1 /* disable A-PHY */) {
 		/* FIXME: For now we disable the A-PHY on multi-PHY devices. */
-		if (dev->phy.type != B43_PHYTYPE_N) {
+		if (dev->phy.type != B43_PHYTYPE_N &&
+		    dev->phy.type != B43_PHYTYPE_LP) {
 			have_2ghz_phy = 1;
 			have_5ghz_phy = 0;
 		}
@@ -4685,9 +4741,6 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
 	wldev->wl = wl;
 	b43_set_status(wldev, B43_STAT_UNINIT);
 	wldev->bad_frames_preempt = modparam_bad_frames_preempt;
-	tasklet_init(&wldev->isr_tasklet,
-		     (void (*)(unsigned long))b43_interrupt_tasklet,
-		     (unsigned long)wldev);
 	INIT_LIST_HEAD(&wldev->list);
 
 	err = b43_wireless_core_attach(wldev);
@@ -4784,14 +4837,14 @@ static int b43_wireless_init(struct ssb_device *dev)
 
 	/* Initialize struct b43_wl */
 	wl->hw = hw;
-	spin_lock_init(&wl->irq_lock);
-	rwlock_init(&wl->tx_lock);
 	spin_lock_init(&wl->leds_lock);
-	spin_lock_init(&wl->shm_lock);
 	mutex_init(&wl->mutex);
+	spin_lock_init(&wl->hardirq_lock);
 	INIT_LIST_HEAD(&wl->devlist);
 	INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
 	INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
+	INIT_WORK(&wl->tx_work, b43_tx_work);
+	skb_queue_head_init(&wl->tx_queue);
 
 	ssb_set_devtypedata(dev, wl);
 	b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
@@ -4873,7 +4926,7 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)
 	if (b43_status(dev) < B43_STAT_INITIALIZED)
 		return;
 	b43info(dev->wl, "Controller RESET (%s) ...\n", reason);
-	queue_work(dev->wl->hw->workqueue, &dev->restart_work);
+	ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
 }
 
 #ifdef CONFIG_PM
@@ -4889,8 +4942,8 @@ static int b43_suspend(struct ssb_device *dev, pm_message_t state)
 	wldev->suspend_in_progress = true;
 	wldev->suspend_init_status = b43_status(wldev);
 	if (wldev->suspend_init_status >= B43_STAT_STARTED)
-		b43_wireless_core_stop(wldev);
-	if (wldev->suspend_init_status >= B43_STAT_INITIALIZED)
+		wldev = b43_wireless_core_stop(wldev);
+	if (wldev && wldev->suspend_init_status >= B43_STAT_INITIALIZED)
 		b43_wireless_core_exit(wldev);
 	mutex_unlock(&wl->mutex);
 
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 950fb1b..40db036 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -112,18 +112,14 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
 void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
 
 u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
-u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset);
 u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
-u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset);
 void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
-void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value);
 void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
-void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value);
 
 u64 b43_hf_read(struct b43_wldev *dev);
 void b43_hf_write(struct b43_wldev *dev, u64 value);
 
-void b43_dummy_transmission(struct b43_wldev *dev);
+void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on);
 
 void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags);
 
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index 816e028..d90217c 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -518,58 +518,40 @@ static unsigned int b43_aphy_op_get_default_chan(struct b43_wldev *dev)
 static void b43_aphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
 {//TODO
 	struct b43_phy *phy = &dev->phy;
-	u64 hf;
 	u16 tmp;
 	int autodiv = 0;
 
 	if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
 		autodiv = 1;
 
-	hf = b43_hf_read(dev);
-	hf &= ~B43_HF_ANTDIVHELP;
-	b43_hf_write(dev, hf);
+	b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
 
-	tmp = b43_phy_read(dev, B43_PHY_BBANDCFG);
-	tmp &= ~B43_PHY_BBANDCFG_RXANT;
-	tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
-	    << B43_PHY_BBANDCFG_RXANT_SHIFT;
-	b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
+	b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT,
+			(autodiv ? B43_ANTENNA_AUTO1 : antenna) <<
+			B43_PHY_BBANDCFG_RXANT_SHIFT);
 
 	if (autodiv) {
 		tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
-		if (antenna == B43_ANTENNA_AUTO0)
+		if (antenna == B43_ANTENNA_AUTO1)
 			tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
 		else
 			tmp |= B43_PHY_ANTDWELL_AUTODIV1;
 		b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
 	}
-	if (phy->rev < 3) {
-		tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
-		tmp = (tmp & 0xFF00) | 0x24;
-		b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
-	} else {
-		tmp = b43_phy_read(dev, B43_PHY_OFDM61);
-		tmp |= 0x10;
-		b43_phy_write(dev, B43_PHY_OFDM61, tmp);
-		if (phy->analog == 3) {
-			b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
-				      0x1D);
-			b43_phy_write(dev, B43_PHY_ADIVRELATED,
-				      8);
+	if (phy->rev < 3)
+		b43_phy_maskset(dev, B43_PHY_ANTDWELL, 0xFF00, 0x24);
+	else {
+		b43_phy_set(dev, B43_PHY_OFDM61, 0x10);
+		if (phy->rev == 3) {
+			b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x1D);
+			b43_phy_write(dev, B43_PHY_ADIVRELATED, 8);
 		} else {
-			b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT,
-				      0x3A);
-			tmp =
-			    b43_phy_read(dev,
-					 B43_PHY_ADIVRELATED);
-			tmp = (tmp & 0xFF00) | 8;
-			b43_phy_write(dev, B43_PHY_ADIVRELATED,
-				      tmp);
+			b43_phy_write(dev, B43_PHY_CLIPPWRDOWNT, 0x3A);
+			b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8);
 		}
 	}
 
-	hf |= B43_HF_ANTDIVHELP;
-	b43_hf_write(dev, hf);
+	b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
 }
 
 static void b43_aphy_op_adjust_txpower(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 6d24162..75b26e1 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -240,22 +240,44 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
 	dev->phy.ops->phy_write(dev, reg, value);
 }
 
+void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
+{
+	assert_mac_suspended(dev);
+	dev->phy.ops->phy_write(dev, destreg,
+		dev->phy.ops->phy_read(dev, srcreg));
+}
+
 void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
 {
-	b43_phy_write(dev, offset,
-		      b43_phy_read(dev, offset) & mask);
+	if (dev->phy.ops->phy_maskset) {
+		assert_mac_suspended(dev);
+		dev->phy.ops->phy_maskset(dev, offset, mask, 0);
+	} else {
+		b43_phy_write(dev, offset,
+			      b43_phy_read(dev, offset) & mask);
+	}
 }
 
 void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set)
 {
-	b43_phy_write(dev, offset,
-		      b43_phy_read(dev, offset) | set);
+	if (dev->phy.ops->phy_maskset) {
+		assert_mac_suspended(dev);
+		dev->phy.ops->phy_maskset(dev, offset, 0xFFFF, set);
+	} else {
+		b43_phy_write(dev, offset,
+			      b43_phy_read(dev, offset) | set);
+	}
 }
 
 void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
 {
-	b43_phy_write(dev, offset,
-		      (b43_phy_read(dev, offset) & mask) | set);
+	if (dev->phy.ops->phy_maskset) {
+		assert_mac_suspended(dev);
+		dev->phy.ops->phy_maskset(dev, offset, mask, set);
+	} else {
+		b43_phy_write(dev, offset,
+			      (b43_phy_read(dev, offset) & mask) | set);
+	}
 }
 
 int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
@@ -325,7 +347,6 @@ void b43_phy_txpower_adjust_work(struct work_struct *work)
 	mutex_unlock(&wl->mutex);
 }
 
-/* Called with wl->irq_lock locked */
 void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
 {
 	struct b43_phy *phy = &dev->phy;
@@ -352,7 +373,7 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
 
 	/* We must adjust the transmission power in hardware.
 	 * Schedule b43_phy_txpower_adjust_work(). */
-	queue_work(dev->wl->hw->workqueue, &dev->wl->txpower_adjust_work);
+	ieee80211_queue_work(dev->wl->hw, &dev->wl->txpower_adjust_work);
 }
 
 int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset)
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 44cc918..9edd4e8 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -49,11 +49,11 @@ enum b43_interference_mitigation {
 
 /* Antenna identifiers */
 enum {
-	B43_ANTENNA0,		/* Antenna 0 */
-	B43_ANTENNA1,		/* Antenna 0 */
-	B43_ANTENNA_AUTO1,	/* Automatic, starting with antenna 1 */
-	B43_ANTENNA_AUTO0,	/* Automatic, starting with antenna 0 */
-	B43_ANTENNA2,
+	B43_ANTENNA0 = 0,	/* Antenna 0 */
+	B43_ANTENNA1 = 1,	/* Antenna 1 */
+	B43_ANTENNA_AUTO0 = 2,	/* Automatic, starting with antenna 0 */
+	B43_ANTENNA_AUTO1 = 3,	/* Automatic, starting with antenna 1 */
+	B43_ANTENNA2 = 4,
 	B43_ANTENNA3 = 8,
 
 	B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
@@ -95,6 +95,8 @@ enum b43_txpwr_result {
  * 			Must not be NULL.
  * @phy_write:		Write to a PHY register.
  * 			Must not be NULL.
+ * @phy_maskset:	Maskset a PHY register, taking shortcuts.
+ *			If it is NULL, a generic algorithm is used.
  * @radio_read:		Read from a Radio register.
  * 			Must not be NULL.
  * @radio_write:	Write to a Radio register.
@@ -129,7 +131,7 @@ enum b43_txpwr_result {
  * 			If the parameter "ignore_tssi" is true, the TSSI values should
  * 			be ignored and a recalculation of the power settings should be
  * 			done even if the TSSI values did not change.
- * 			This callback is called with wl->irq_lock held and must not sleep.
+ * 			This function may sleep, but should not.
  * 			Must not be NULL.
  * @adjust_txpower:	Write the previously calculated TX power settings
  * 			(from @recalc_txpower) to the hardware.
@@ -154,6 +156,7 @@ struct b43_phy_operations {
 	/* Register access */
 	u16 (*phy_read)(struct b43_wldev *dev, u16 reg);
 	void (*phy_write)(struct b43_wldev *dev, u16 reg, u16 value);
+	void (*phy_maskset)(struct b43_wldev *dev, u16 reg, u16 mask, u16 set);
 	u16 (*radio_read)(struct b43_wldev *dev, u16 reg);
 	void (*radio_write)(struct b43_wldev *dev, u16 reg, u16 value);
 
@@ -291,6 +294,11 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg);
 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value);
 
 /**
+ * b43_phy_copy - copy contents of 16bit PHY register to another
+ */
+void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg);
+
+/**
  * b43_phy_mask - Mask a PHY register with a mask
  */
 void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
@@ -371,7 +379,6 @@ void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
  *
  * Compare the current TX power output to the desired power emission
  * and schedule an adjustment in case it mismatches.
- * Requires wl->irq_lock locked.
  *
  * @flags:	OR'ed enum b43_phy_txpower_check_flags flags.
  * 		See the docs below.
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 5300232..382826a 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -333,7 +333,7 @@ static void b43_set_all_gains(struct b43_wldev *dev,
 		b43_phy_maskset(dev, 0x04A1, 0xBFBF, tmp);
 		b43_phy_maskset(dev, 0x04A2, 0xBFBF, tmp);
 	}
-	b43_dummy_transmission(dev);
+	b43_dummy_transmission(dev, false, true);
 }
 
 static void b43_set_original_gains(struct b43_wldev *dev)
@@ -365,7 +365,7 @@ static void b43_set_original_gains(struct b43_wldev *dev)
 	b43_phy_maskset(dev, 0x04A0, 0xBFBF, 0x4040);
 	b43_phy_maskset(dev, 0x04A1, 0xBFBF, 0x4040);
 	b43_phy_maskset(dev, 0x04A2, 0xBFBF, 0x4000);
-	b43_dummy_transmission(dev);
+	b43_dummy_transmission(dev, false, true);
 }
 
 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
@@ -1964,7 +1964,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
 			}
 			b43_set_txpower_g(dev, &bbatt, &rfatt, 0);
 		}
-		b43_dummy_transmission(dev);
+		b43_dummy_transmission(dev, false, true);
 		gphy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_ITSSI);
 		if (B43_DEBUG) {
 			/* Current-Idle-TSSI sanity check. */
@@ -2651,65 +2651,54 @@ static unsigned int b43_gphy_op_get_default_chan(struct b43_wldev *dev)
 static void b43_gphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
 {
 	struct b43_phy *phy = &dev->phy;
-	u64 hf;
 	u16 tmp;
 	int autodiv = 0;
 
 	if (antenna == B43_ANTENNA_AUTO0 || antenna == B43_ANTENNA_AUTO1)
 		autodiv = 1;
 
-	hf = b43_hf_read(dev);
-	hf &= ~B43_HF_ANTDIVHELP;
-	b43_hf_write(dev, hf);
+	b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ANTDIVHELP);
 
-	tmp = b43_phy_read(dev, B43_PHY_BBANDCFG);
-	tmp &= ~B43_PHY_BBANDCFG_RXANT;
-	tmp |= (autodiv ? B43_ANTENNA_AUTO0 : antenna)
-			<< B43_PHY_BBANDCFG_RXANT_SHIFT;
-	b43_phy_write(dev, B43_PHY_BBANDCFG, tmp);
+	b43_phy_maskset(dev, B43_PHY_BBANDCFG, ~B43_PHY_BBANDCFG_RXANT,
+			(autodiv ? B43_ANTENNA_AUTO1 : antenna) <<
+			B43_PHY_BBANDCFG_RXANT_SHIFT);
 
 	if (autodiv) {
 		tmp = b43_phy_read(dev, B43_PHY_ANTDWELL);
-		if (antenna == B43_ANTENNA_AUTO0)
+		if (antenna == B43_ANTENNA_AUTO1)
 			tmp &= ~B43_PHY_ANTDWELL_AUTODIV1;
 		else
 			tmp |= B43_PHY_ANTDWELL_AUTODIV1;
 		b43_phy_write(dev, B43_PHY_ANTDWELL, tmp);
 	}
+
 	tmp = b43_phy_read(dev, B43_PHY_ANTWRSETT);
 	if (autodiv)
 		tmp |= B43_PHY_ANTWRSETT_ARXDIV;
 	else
 		tmp &= ~B43_PHY_ANTWRSETT_ARXDIV;
 	b43_phy_write(dev, B43_PHY_ANTWRSETT, tmp);
-	if (phy->rev >= 2) {
-		tmp = b43_phy_read(dev, B43_PHY_OFDM61);
-		tmp |= B43_PHY_OFDM61_10;
-		b43_phy_write(dev, B43_PHY_OFDM61, tmp);
 
-		tmp =
-		    b43_phy_read(dev, B43_PHY_DIVSRCHGAINBACK);
-		tmp = (tmp & 0xFF00) | 0x15;
-		b43_phy_write(dev, B43_PHY_DIVSRCHGAINBACK,
-			      tmp);
+	if (autodiv)
+		b43_phy_set(dev, B43_PHY_ANTWRSETT, B43_PHY_ANTWRSETT_ARXDIV);
+	else {
+		b43_phy_mask(dev, B43_PHY_ANTWRSETT,
+			     B43_PHY_ANTWRSETT_ARXDIV);
+	}
 
-		if (phy->rev == 2) {
-			b43_phy_write(dev, B43_PHY_ADIVRELATED,
-				      8);
-		} else {
-			tmp =
-			    b43_phy_read(dev,
-					 B43_PHY_ADIVRELATED);
-			tmp = (tmp & 0xFF00) | 8;
-			b43_phy_write(dev, B43_PHY_ADIVRELATED,
-				      tmp);
-		}
+	if (phy->rev >= 2) {
+		b43_phy_set(dev, B43_PHY_OFDM61, B43_PHY_OFDM61_10);
+		b43_phy_maskset(dev, B43_PHY_DIVSRCHGAINBACK, 0xFF00, 0x15);
+
+		if (phy->rev == 2)
+			b43_phy_write(dev, B43_PHY_ADIVRELATED, 8);
+		else
+			b43_phy_maskset(dev, B43_PHY_ADIVRELATED, 0xFF00, 8);
 	}
 	if (phy->rev >= 6)
 		b43_phy_write(dev, B43_PHY_OFDM9B, 0xDC);
 
-	hf |= B43_HF_ANTDIVHELP;
-	b43_hf_write(dev, hf);
+	b43_hf_write(dev, b43_hf_read(dev) | B43_HF_ANTDIVHELP);
 }
 
 static int b43_gphy_op_interf_mitigation(struct b43_wldev *dev,
@@ -2834,8 +2823,6 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
 
 	b43_mac_suspend(dev);
 
-	spin_lock_irq(&dev->wl->irq_lock);
-
 	/* Calculate the new attenuation values. */
 	bbatt = gphy->bbatt.att;
 	bbatt += gphy->bbatt_delta;
@@ -2875,11 +2862,6 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
 	gphy->rfatt.att = rfatt;
 	gphy->bbatt.att = bbatt;
 
-	/* We drop the lock early, so we can sleep during hardware
-	 * adjustment. Possible races with op_recalc_txpower are harmless,
-	 * as we will be called once again in case we raced. */
-	spin_unlock_irq(&dev->wl->irq_lock);
-
 	if (b43_debug(dev, B43_DBG_XMITPOWER))
 		b43dbg(dev->wl, "Adjusting TX power\n");
 
diff --git a/drivers/net/wireless/b43/phy_g.h b/drivers/net/wireless/b43/phy_g.h
index 718947f..8569fdd 100644
--- a/drivers/net/wireless/b43/phy_g.h
+++ b/drivers/net/wireless/b43/phy_g.h
@@ -141,8 +141,7 @@ struct b43_phy_g {
 	int tgt_idle_tssi;
 	/* Current idle TSSI */
 	int cur_idle_tssi;
-	/* The current average TSSI.
-	 * Needs irq_lock, as it's updated in the IRQ path. */
+	/* The current average TSSI. */
 	u8 average_tssi;
 	/* Current TX power level attenuation control values */
 	struct b43_bbatt bbatt;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index ea0d3a3..3e02d96 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -1,9 +1,10 @@
 /*
 
   Broadcom B43 wireless driver
-  IEEE 802.11g LP-PHY driver
+  IEEE 802.11a/g LP-PHY driver
 
   Copyright (c) 2008-2009 Michael Buesch <mb@bu3sch.de>
+  Copyright (c) 2009 GÃ¡bor Stefanik <netrolller.3d@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
@@ -29,6 +30,25 @@
 #include "tables_lpphy.h"
 
 
+static inline u16 channel2freq_lp(u8 channel)
+{
+	if (channel < 14)
+		return (2407 + 5 * channel);
+	else if (channel == 14)
+		return 2484;
+	else if (channel < 184)
+		return (5000 + 5 * channel);
+	else
+		return (4000 + 5 * channel);
+}
+
+static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
+{
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		return 1;
+	return 36;
+}
+
 static int b43_lpphy_op_allocate(struct b43_wldev *dev)
 {
 	struct b43_phy_lp *lpphy;
@@ -59,14 +79,325 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
 	dev->phy.lp = NULL;
 }
 
+static void lpphy_read_band_sprom(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	struct ssb_bus *bus = dev->dev->bus;
+	u16 cckpo, maxpwr;
+	u32 ofdmpo;
+	int i;
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		lpphy->tx_isolation_med_band = bus->sprom.tri2g;
+		lpphy->bx_arch = bus->sprom.bxa2g;
+		lpphy->rx_pwr_offset = bus->sprom.rxpo2g;
+		lpphy->rssi_vf = bus->sprom.rssismf2g;
+		lpphy->rssi_vc = bus->sprom.rssismc2g;
+		lpphy->rssi_gs = bus->sprom.rssisav2g;
+		lpphy->txpa[0] = bus->sprom.pa0b0;
+		lpphy->txpa[1] = bus->sprom.pa0b1;
+		lpphy->txpa[2] = bus->sprom.pa0b2;
+		maxpwr = bus->sprom.maxpwr_bg;
+		lpphy->max_tx_pwr_med_band = maxpwr;
+		cckpo = bus->sprom.cck2gpo;
+		ofdmpo = bus->sprom.ofdm2gpo;
+		if (cckpo) {
+			for (i = 0; i < 4; i++) {
+				lpphy->tx_max_rate[i] =
+					maxpwr - (ofdmpo & 0xF) * 2;
+				ofdmpo >>= 4;
+			}
+			ofdmpo = bus->sprom.ofdm2gpo;
+			for (i = 4; i < 15; i++) {
+				lpphy->tx_max_rate[i] =
+					maxpwr - (ofdmpo & 0xF) * 2;
+				ofdmpo >>= 4;
+			}
+		} else {
+			ofdmpo &= 0xFF;
+			for (i = 0; i < 4; i++)
+				lpphy->tx_max_rate[i] = maxpwr;
+			for (i = 4; i < 15; i++)
+				lpphy->tx_max_rate[i] = maxpwr - ofdmpo;
+		}
+	} else { /* 5GHz */
+		lpphy->tx_isolation_low_band = bus->sprom.tri5gl;
+		lpphy->tx_isolation_med_band = bus->sprom.tri5g;
+		lpphy->tx_isolation_hi_band = bus->sprom.tri5gh;
+		lpphy->bx_arch = bus->sprom.bxa5g;
+		lpphy->rx_pwr_offset = bus->sprom.rxpo5g;
+		lpphy->rssi_vf = bus->sprom.rssismf5g;
+		lpphy->rssi_vc = bus->sprom.rssismc5g;
+		lpphy->rssi_gs = bus->sprom.rssisav5g;
+		lpphy->txpa[0] = bus->sprom.pa1b0;
+		lpphy->txpa[1] = bus->sprom.pa1b1;
+		lpphy->txpa[2] = bus->sprom.pa1b2;
+		lpphy->txpal[0] = bus->sprom.pa1lob0;
+		lpphy->txpal[1] = bus->sprom.pa1lob1;
+		lpphy->txpal[2] = bus->sprom.pa1lob2;
+		lpphy->txpah[0] = bus->sprom.pa1hib0;
+		lpphy->txpah[1] = bus->sprom.pa1hib1;
+		lpphy->txpah[2] = bus->sprom.pa1hib2;
+		maxpwr = bus->sprom.maxpwr_al;
+		ofdmpo = bus->sprom.ofdm5glpo;
+		lpphy->max_tx_pwr_low_band = maxpwr;
+		for (i = 4; i < 12; i++) {
+			lpphy->tx_max_ratel[i] = maxpwr - (ofdmpo & 0xF) * 2;
+			ofdmpo >>= 4;
+		}
+		maxpwr = bus->sprom.maxpwr_a;
+		ofdmpo = bus->sprom.ofdm5gpo;
+		lpphy->max_tx_pwr_med_band = maxpwr;
+		for (i = 4; i < 12; i++) {
+			lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2;
+			ofdmpo >>= 4;
+		}
+		maxpwr = bus->sprom.maxpwr_ah;
+		ofdmpo = bus->sprom.ofdm5ghpo;
+		lpphy->max_tx_pwr_hi_band = maxpwr;
+		for (i = 4; i < 12; i++) {
+			lpphy->tx_max_rateh[i] = maxpwr - (ofdmpo & 0xF) * 2;
+			ofdmpo >>= 4;
+		}
+	}
+}
+
+static void lpphy_adjust_gain_table(struct b43_wldev *dev, u32 freq)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	u16 temp[3];
+	u16 isolation;
+
+	B43_WARN_ON(dev->phy.rev >= 2);
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+		isolation = lpphy->tx_isolation_med_band;
+	else if (freq <= 5320)
+		isolation = lpphy->tx_isolation_low_band;
+	else if (freq <= 5700)
+		isolation = lpphy->tx_isolation_med_band;
+	else
+		isolation = lpphy->tx_isolation_hi_band;
+
+	temp[0] = ((isolation - 26) / 12) << 12;
+	temp[1] = temp[0] + 0x1000;
+	temp[2] = temp[0] + 0x2000;
+
+	b43_lptab_write_bulk(dev, B43_LPTAB16(13, 0), 3, temp);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(12, 0), 3, temp);
+}
+
 static void lpphy_table_init(struct b43_wldev *dev)
 {
-	//TODO
+	u32 freq = channel2freq_lp(b43_lpphy_op_get_default_chan(dev));
+
+	if (dev->phy.rev < 2)
+		lpphy_rev0_1_table_init(dev);
+	else
+		lpphy_rev2plus_table_init(dev);
+
+	lpphy_init_tx_gain_table(dev);
+
+	if (dev->phy.rev < 2)
+		lpphy_adjust_gain_table(dev, freq);
 }
 
 static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
 {
-	B43_WARN_ON(1);//TODO rev < 2 not supported, yet.
+	struct ssb_bus *bus = dev->dev->bus;
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	u16 tmp, tmp2;
+
+	b43_phy_mask(dev, B43_LPPHY_AFE_DAC_CTL, 0xF7FF);
+	b43_phy_write(dev, B43_LPPHY_AFE_CTL, 0);
+	b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVR, 0);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, 0);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0);
+	b43_phy_set(dev, B43_LPPHY_AFE_DAC_CTL, 0x0004);
+	b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0x0078);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x5800);
+	b43_phy_write(dev, B43_LPPHY_ADC_COMPENSATION_CTL, 0x0016);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_0, 0xFFF8, 0x0004);
+	b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5400);
+	b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2400);
+	b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
+	b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0x0006);
+	b43_phy_mask(dev, B43_LPPHY_RX_RADIO_CTL, 0xFFFE);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x0005);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0x0180);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x3C00);
+	b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xFFF0, 0x0005);
+	b43_phy_maskset(dev, B43_LPPHY_GAIN_MISMATCH_LIMIT, 0xFFC0, 0x001A);
+	b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0xFF00, 0x00B3);
+	b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
+	b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB,
+			0xFF00, lpphy->rx_pwr_offset);
+	if ((bus->sprom.boardflags_lo & B43_BFL_FEM) &&
+	   ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
+	   (bus->sprom.boardflags_hi & B43_BFH_PAREF))) {
+		ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28);
+		ssb_pmu_set_ldo_paref(&bus->chipco, true);
+		if (dev->phy.rev == 0) {
+			b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT,
+					0xFFCF, 0x0010);
+		}
+		b43_lptab_write(dev, B43_LPTAB16(11, 7), 60);
+	} else {
+		ssb_pmu_set_ldo_paref(&bus->chipco, false);
+		b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT,
+				0xFFCF, 0x0020);
+		b43_lptab_write(dev, B43_LPTAB16(11, 7), 100);
+	}
+	tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000;
+	b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp);
+	if (bus->sprom.boardflags_hi & B43_BFH_RSSIINV)
+		b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA);
+	else
+		b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA);
+	b43_lptab_write(dev, B43_LPTAB16(11, 1), 24);
+	b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL,
+			0xFFF9, (lpphy->bx_arch << 1));
+	if (dev->phy.rev == 1 &&
+	   (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) {
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0B00);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0400);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0B00);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_5, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_5, 0xC0FF, 0x0900);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_6, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_6, 0xC0FF, 0x0B00);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_7, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_7, 0xC0FF, 0x0900);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00);
+	} else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ ||
+		  (bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) &&
+		  (bus->sprom.boardflags_lo & B43_BFL_FEM))) {
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0500);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x0002);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0800);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00);
+	} else if (dev->phy.rev == 1 ||
+		  (bus->sprom.boardflags_lo & B43_BFL_FEM)) {
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0C00);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x0002);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0100);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0300);
+	} else {
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0900);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0B00);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x0006);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0500);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006);
+		b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700);
+	}
+	if (dev->phy.rev == 1 && (bus->sprom.boardflags_hi & B43_BFH_PAREF)) {
+		b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1);
+		b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2);
+		b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3);
+		b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4);
+	}
+	if ((bus->sprom.boardflags_hi & B43_BFH_FEM_BT) &&
+	    (bus->chip_id == 0x5354) &&
+	    (bus->chip_package == SSB_CHIPPACK_BCM4712S)) {
+		b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006);
+		b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005);
+		b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF);
+		//FIXME the Broadcom driver caches & delays this HF write!
+		b43_hf_write(dev, b43_hf_read(dev) | B43_HF_PR45960W);
+	}
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		b43_phy_set(dev, B43_LPPHY_LP_PHY_CTL, 0x8000);
+		b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0040);
+		b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0xA400);
+		b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xF0FF, 0x0B00);
+		b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x0007);
+		b43_phy_maskset(dev, B43_LPPHY_DSSS_CONFIRM_CNT, 0xFFF8, 0x0003);
+		b43_phy_maskset(dev, B43_LPPHY_DSSS_CONFIRM_CNT, 0xFFC7, 0x0020);
+		b43_phy_mask(dev, B43_LPPHY_IDLEAFTERPKTRXTO, 0x00FF);
+	} else { /* 5GHz */
+		b43_phy_mask(dev, B43_LPPHY_LP_PHY_CTL, 0x7FFF);
+		b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFBF);
+	}
+	if (dev->phy.rev == 1) {
+		tmp = b43_phy_read(dev, B43_LPPHY_CLIPCTRTHRESH);
+		tmp2 = (tmp & 0x03E0) >> 5;
+		tmp2 |= tmp2 << 5;
+		b43_phy_write(dev, B43_LPPHY_4C3, tmp2);
+		tmp = b43_phy_read(dev, B43_LPPHY_GAINDIRECTMISMATCH);
+		tmp2 = (tmp & 0x1F00) >> 8;
+		tmp2 |= tmp2 << 5;
+		b43_phy_write(dev, B43_LPPHY_4C4, tmp2);
+		tmp = b43_phy_read(dev, B43_LPPHY_VERYLOWGAINDB);
+		tmp2 = tmp & 0x00FF;
+		tmp2 |= tmp << 8;
+		b43_phy_write(dev, B43_LPPHY_4C5, tmp2);
+	}
+}
+
+static void lpphy_save_dig_flt_state(struct b43_wldev *dev)
+{
+	static const u16 addr[] = {
+		B43_PHY_OFDM(0xC1),
+		B43_PHY_OFDM(0xC2),
+		B43_PHY_OFDM(0xC3),
+		B43_PHY_OFDM(0xC4),
+		B43_PHY_OFDM(0xC5),
+		B43_PHY_OFDM(0xC6),
+		B43_PHY_OFDM(0xC7),
+		B43_PHY_OFDM(0xC8),
+		B43_PHY_OFDM(0xCF),
+	};
+
+	static const u16 coefs[] = {
+		0xDE5E, 0xE832, 0xE331, 0x4D26,
+		0x0026, 0x1420, 0x0020, 0xFE08,
+		0x0008,
+	};
+
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addr); i++) {
+		lpphy->dig_flt_state[i] = b43_phy_read(dev, addr[i]);
+		b43_phy_write(dev, addr[i], coefs[i]);
+	}
+}
+
+static void lpphy_restore_dig_flt_state(struct b43_wldev *dev)
+{
+	static const u16 addr[] = {
+		B43_PHY_OFDM(0xC1),
+		B43_PHY_OFDM(0xC2),
+		B43_PHY_OFDM(0xC3),
+		B43_PHY_OFDM(0xC4),
+		B43_PHY_OFDM(0xC5),
+		B43_PHY_OFDM(0xC6),
+		B43_PHY_OFDM(0xC7),
+		B43_PHY_OFDM(0xC8),
+		B43_PHY_OFDM(0xCF),
+	};
+
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(addr); i++)
+		b43_phy_write(dev, addr[i], lpphy->dig_flt_state[i]);
 }
 
 static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
@@ -83,7 +414,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 	b43_phy_write(dev, B43_PHY_OFDM(0xF9), 0);
 	b43_phy_write(dev, B43_LPPHY_TR_LOOKUP_1, 0);
 	b43_phy_set(dev, B43_LPPHY_ADC_COMPENSATION_CTL, 0x10);
-	b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0x78);
+	b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0xB4);
 	b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xF8FF, 0x200);
 	b43_phy_maskset(dev, B43_LPPHY_DCOFFSETTRANSIENT, 0xFF00, 0x7F);
 	b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xFF0F, 0x40);
@@ -91,7 +422,12 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 	b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000);
 	b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000);
 	b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1);
-	b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x10);
+	if (bus->boardinfo.rev >= 0x18) {
+		b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14);
+	} else {
+		b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x10);
+	}
 	b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0xFF00, 0xF4);
 	b43_phy_maskset(dev, B43_PHY_OFDM(0xDF), 0x00FF, 0xF100);
 	b43_phy_write(dev, B43_LPPHY_CLIPTHRESH, 0x48);
@@ -100,7 +436,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 	b43_phy_maskset(dev, B43_LPPHY_PWR_THRESH1, 0xFFF0, 0x9);
 	b43_phy_mask(dev, B43_LPPHY_GAINDIRECTMISMATCH, ~0xF);
 	b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5500);
-	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xF81F, 0xA0);
+	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0);
 	b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
 	b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
 	if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
@@ -121,8 +457,10 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 	b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
 	b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
 
-	b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
-	b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
+	if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+		b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
+		b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
+	}
 
 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
 		b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x40);
@@ -130,6 +468,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 		b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x6);
 		b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0x9D00);
 		b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0xFF00, 0xA1);
+		b43_phy_mask(dev, B43_LPPHY_IDLEAFTERPKTRXTO, 0x00FF);
 	} else /* 5GHz */
 		b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x40);
 
@@ -142,6 +481,14 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 	b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_1,
 		      0x2000 | ((u16)lpphy->rssi_gs << 10) |
 		      ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf);
+
+	if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+		b43_phy_set(dev, B43_LPPHY_AFE_ADC_CTL_0, 0x1C);
+		b43_phy_maskset(dev, B43_LPPHY_AFE_CTL, 0x00FF, 0x8800);
+		b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_1, 0xFC3C, 0x0400);
+	}
+
+	lpphy_save_dig_flt_state(dev);
 }
 
 static void lpphy_baseband_init(struct b43_wldev *dev)
@@ -161,8 +508,9 @@ struct b2062_freqdata {
 /* Initialize the 2062 radio. */
 static void lpphy_2062_init(struct b43_wldev *dev)
 {
+	struct b43_phy_lp *lpphy = dev->phy.lp;
 	struct ssb_bus *bus = dev->dev->bus;
-	u32 crystalfreq, pdiv, tmp, ref;
+	u32 crystalfreq, tmp, ref;
 	unsigned int i;
 	const struct b2062_freqdata *fd = NULL;
 
@@ -186,10 +534,15 @@ static void lpphy_2062_init(struct b43_wldev *dev)
 	b43_radio_write(dev, B2062_N_TX_CTL3, 0);
 	b43_radio_write(dev, B2062_N_TX_CTL4, 0);
 	b43_radio_write(dev, B2062_N_TX_CTL5, 0);
+	b43_radio_write(dev, B2062_N_TX_CTL6, 0);
 	b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
 	b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
 	b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
 	b43_radio_write(dev, B2062_N_CALIB_TS, 0);
+	if (dev->phy.rev > 0) {
+		b43_radio_write(dev, B2062_S_BG_CTL1,
+			(b43_radio_read(dev, B2062_N_COMM2) >> 1) | 0x80);
+	}
 	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
 		b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
 	else
@@ -201,23 +554,27 @@ static void lpphy_2062_init(struct b43_wldev *dev)
 	B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
 	B43_WARN_ON(crystalfreq == 0);
 
-	if (crystalfreq >= 30000000) {
-		pdiv = 1;
+	if (crystalfreq <= 30000000) {
+		lpphy->pdiv = 1;
 		b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
 	} else {
-		pdiv = 2;
+		lpphy->pdiv = 2;
 		b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
 	}
 
-	tmp = (800000000 * pdiv + crystalfreq) / (32000000 * pdiv);
-	tmp = (tmp - 1) & 0xFF;
+	tmp = (((800000000 * lpphy->pdiv + crystalfreq) /
+	      (2 * crystalfreq)) - 8) & 0xFF;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL7, tmp);
+
+	tmp = (((100 * crystalfreq + 16000000 * lpphy->pdiv) /
+	      (32000000 * lpphy->pdiv)) - 1) & 0xFF;
 	b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
 
-	tmp = (2 * crystalfreq + 1000000 * pdiv) / (2000000 * pdiv);
-	tmp = ((tmp & 0xFF) - 1) & 0xFFFF;
+	tmp = (((2 * crystalfreq + 1000000 * lpphy->pdiv) /
+	      (2000000 * lpphy->pdiv)) - 1) & 0xFF;
 	b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
 
-	ref = (1000 * pdiv + 2 * crystalfreq) / (2000 * pdiv);
+	ref = (1000 * lpphy->pdiv + 2 * crystalfreq) / (2000 * lpphy->pdiv);
 	ref &= 0xFFFF;
 	for (i = 0; i < ARRAY_SIZE(freqdata_tab); i++) {
 		if (ref < freqdata_tab[i].freq) {
@@ -241,12 +598,78 @@ static void lpphy_2062_init(struct b43_wldev *dev)
 /* Initialize the 2063 radio. */
 static void lpphy_2063_init(struct b43_wldev *dev)
 {
-	//TODO
+	b2063_upload_init_table(dev);
+	b43_radio_write(dev, B2063_LOGEN_SP5, 0);
+	b43_radio_set(dev, B2063_COMM8, 0x38);
+	b43_radio_write(dev, B2063_REG_SP1, 0x56);
+	b43_radio_mask(dev, B2063_RX_BB_CTL2, ~0x2);
+	b43_radio_write(dev, B2063_PA_SP7, 0);
+	b43_radio_write(dev, B2063_TX_RF_SP6, 0x20);
+	b43_radio_write(dev, B2063_TX_RF_SP9, 0x40);
+	if (dev->phy.rev == 2) {
+		b43_radio_write(dev, B2063_PA_SP3, 0xa0);
+		b43_radio_write(dev, B2063_PA_SP4, 0xa0);
+		b43_radio_write(dev, B2063_PA_SP2, 0x18);
+	} else {
+		b43_radio_write(dev, B2063_PA_SP3, 0x20);
+		b43_radio_write(dev, B2063_PA_SP2, 0x20);
+	}
 }
 
+struct lpphy_stx_table_entry {
+	u16 phy_offset;
+	u16 phy_shift;
+	u16 rf_addr;
+	u16 rf_shift;
+	u16 mask;
+};
+
+static const struct lpphy_stx_table_entry lpphy_stx_table[] = {
+	{ .phy_offset = 2, .phy_shift = 6, .rf_addr = 0x3d, .rf_shift = 3, .mask = 0x01, },
+	{ .phy_offset = 1, .phy_shift = 12, .rf_addr = 0x4c, .rf_shift = 1, .mask = 0x01, },
+	{ .phy_offset = 1, .phy_shift = 8, .rf_addr = 0x50, .rf_shift = 0, .mask = 0x7f, },
+	{ .phy_offset = 0, .phy_shift = 8, .rf_addr = 0x44, .rf_shift = 0, .mask = 0xff, },
+	{ .phy_offset = 1, .phy_shift = 0, .rf_addr = 0x4a, .rf_shift = 0, .mask = 0xff, },
+	{ .phy_offset = 0, .phy_shift = 4, .rf_addr = 0x4d, .rf_shift = 0, .mask = 0xff, },
+	{ .phy_offset = 1, .phy_shift = 4, .rf_addr = 0x4e, .rf_shift = 0, .mask = 0xff, },
+	{ .phy_offset = 0, .phy_shift = 12, .rf_addr = 0x4f, .rf_shift = 0, .mask = 0x0f, },
+	{ .phy_offset = 1, .phy_shift = 0, .rf_addr = 0x4f, .rf_shift = 4, .mask = 0x0f, },
+	{ .phy_offset = 3, .phy_shift = 0, .rf_addr = 0x49, .rf_shift = 0, .mask = 0x0f, },
+	{ .phy_offset = 4, .phy_shift = 3, .rf_addr = 0x46, .rf_shift = 4, .mask = 0x07, },
+	{ .phy_offset = 3, .phy_shift = 15, .rf_addr = 0x46, .rf_shift = 0, .mask = 0x01, },
+	{ .phy_offset = 4, .phy_shift = 0, .rf_addr = 0x46, .rf_shift = 1, .mask = 0x07, },
+	{ .phy_offset = 3, .phy_shift = 8, .rf_addr = 0x48, .rf_shift = 4, .mask = 0x07, },
+	{ .phy_offset = 3, .phy_shift = 11, .rf_addr = 0x48, .rf_shift = 0, .mask = 0x0f, },
+	{ .phy_offset = 3, .phy_shift = 4, .rf_addr = 0x49, .rf_shift = 4, .mask = 0x0f, },
+	{ .phy_offset = 2, .phy_shift = 15, .rf_addr = 0x45, .rf_shift = 0, .mask = 0x01, },
+	{ .phy_offset = 5, .phy_shift = 13, .rf_addr = 0x52, .rf_shift = 4, .mask = 0x07, },
+	{ .phy_offset = 6, .phy_shift = 0, .rf_addr = 0x52, .rf_shift = 7, .mask = 0x01, },
+	{ .phy_offset = 5, .phy_shift = 3, .rf_addr = 0x41, .rf_shift = 5, .mask = 0x07, },
+	{ .phy_offset = 5, .phy_shift = 6, .rf_addr = 0x41, .rf_shift = 0, .mask = 0x0f, },
+	{ .phy_offset = 5, .phy_shift = 10, .rf_addr = 0x42, .rf_shift = 5, .mask = 0x07, },
+	{ .phy_offset = 4, .phy_shift = 15, .rf_addr = 0x42, .rf_shift = 0, .mask = 0x01, },
+	{ .phy_offset = 5, .phy_shift = 0, .rf_addr = 0x42, .rf_shift = 1, .mask = 0x07, },
+	{ .phy_offset = 4, .phy_shift = 11, .rf_addr = 0x43, .rf_shift = 4, .mask = 0x0f, },
+	{ .phy_offset = 4, .phy_shift = 7, .rf_addr = 0x43, .rf_shift = 0, .mask = 0x0f, },
+	{ .phy_offset = 4, .phy_shift = 6, .rf_addr = 0x45, .rf_shift = 1, .mask = 0x01, },
+	{ .phy_offset = 2, .phy_shift = 7, .rf_addr = 0x40, .rf_shift = 4, .mask = 0x0f, },
+	{ .phy_offset = 2, .phy_shift = 11, .rf_addr = 0x40, .rf_shift = 0, .mask = 0x0f, },
+};
+
 static void lpphy_sync_stx(struct b43_wldev *dev)
 {
-	//TODO
+	const struct lpphy_stx_table_entry *e;
+	unsigned int i;
+	u16 tmp;
+
+	for (i = 0; i < ARRAY_SIZE(lpphy_stx_table); i++) {
+		e = &lpphy_stx_table[i];
+		tmp = b43_radio_read(dev, e->rf_addr);
+		tmp >>= e->rf_shift;
+		tmp <<= e->phy_shift;
+		b43_phy_maskset(dev, B43_PHY_OFDM(0xF2 + e->phy_offset),
+				~(e->mask << e->phy_shift), tmp);
+	}
 }
 
 static void lpphy_radio_init(struct b43_wldev *dev)
@@ -257,17 +680,381 @@ static void lpphy_radio_init(struct b43_wldev *dev)
 	b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
 	udelay(1);
 
-	if (dev->phy.rev < 2) {
+	if (dev->phy.radio_ver == 0x2062) {
 		lpphy_2062_init(dev);
 	} else {
 		lpphy_2063_init(dev);
 		lpphy_sync_stx(dev);
 		b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
 		b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
-		//TODO Do something on the backplane
+		if (dev->dev->bus->chip_id == 0x4325) {
+			// TODO SSB PMU recalibration
+		}
+	}
+}
+
+struct lpphy_iq_est { u32 iq_prod, i_pwr, q_pwr; };
+
+static void lpphy_set_rc_cap(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	u8 rc_cap = (lpphy->rc_cap & 0x1F) >> 1;
+
+	if (dev->phy.rev == 1) //FIXME check channel 14!
+		rc_cap = min_t(u8, rc_cap + 5, 15);
+
+	b43_radio_write(dev, B2062_N_RXBB_CALIB2,
+			max_t(u8, lpphy->rc_cap - 4, 0x80));
+	b43_radio_write(dev, B2062_N_TX_CTL_A, rc_cap | 0x80);
+	b43_radio_write(dev, B2062_S_RXG_CNT16,
+			((lpphy->rc_cap & 0x1F) >> 2) | 0x80);
+}
+
+static u8 lpphy_get_bb_mult(struct b43_wldev *dev)
+{
+	return (b43_lptab_read(dev, B43_LPTAB16(0, 87)) & 0xFF00) >> 8;
+}
+
+static void lpphy_set_bb_mult(struct b43_wldev *dev, u8 bb_mult)
+{
+	b43_lptab_write(dev, B43_LPTAB16(0, 87), (u16)bb_mult << 8);
+}
+
+static void lpphy_set_deaf(struct b43_wldev *dev, bool user)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	if (user)
+		lpphy->crs_usr_disable = 1;
+	else
+		lpphy->crs_sys_disable = 1;
+	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x80);
+}
+
+static void lpphy_clear_deaf(struct b43_wldev *dev, bool user)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	if (user)
+		lpphy->crs_usr_disable = 0;
+	else
+		lpphy->crs_sys_disable = 0;
+
+	if (!lpphy->crs_usr_disable && !lpphy->crs_sys_disable) {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
+					0xFF1F, 0x60);
+		else
+			b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
+					0xFF1F, 0x20);
 	}
 }
 
+static void lpphy_disable_crs(struct b43_wldev *dev, bool user)
+{
+	lpphy_set_deaf(dev, user);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x4);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFF7);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x8);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x10);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFDF);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x20);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFBF);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0x7);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0x38);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFF3F);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0x100);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFDFF);
+	b43_phy_write(dev, B43_LPPHY_PS_CTL_OVERRIDE_VAL0, 0);
+	b43_phy_write(dev, B43_LPPHY_PS_CTL_OVERRIDE_VAL1, 1);
+	b43_phy_write(dev, B43_LPPHY_PS_CTL_OVERRIDE_VAL2, 0x20);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFBFF);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xF7FF);
+	b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
+	b43_phy_write(dev, B43_LPPHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45AF);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0x3FF);
+}
+
+static void lpphy_restore_crs(struct b43_wldev *dev, bool user)
+{
+	lpphy_clear_deaf(dev, user);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFF80);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFC00);
+}
+
+struct lpphy_tx_gains { u16 gm, pga, pad, dac; };
+
+static struct lpphy_tx_gains lpphy_get_tx_gains(struct b43_wldev *dev)
+{
+	struct lpphy_tx_gains gains;
+	u16 tmp;
+
+	gains.dac = (b43_phy_read(dev, B43_LPPHY_AFE_DAC_CTL) & 0x380) >> 7;
+	if (dev->phy.rev < 2) {
+		tmp = b43_phy_read(dev,
+				   B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7FF;
+		gains.gm = tmp & 0x0007;
+		gains.pga = (tmp & 0x0078) >> 3;
+		gains.pad = (tmp & 0x780) >> 7;
+	} else {
+		tmp = b43_phy_read(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL);
+		gains.pad = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0xFF;
+		gains.gm = tmp & 0xFF;
+		gains.pga = (tmp >> 8) & 0xFF;
+	}
+
+	return gains;
+}
+
+static void lpphy_set_dac_gain(struct b43_wldev *dev, u16 dac)
+{
+	u16 ctl = b43_phy_read(dev, B43_LPPHY_AFE_DAC_CTL) & 0xC7F;
+	ctl |= dac << 7;
+	b43_phy_maskset(dev, B43_LPPHY_AFE_DAC_CTL, 0xF000, ctl);
+}
+
+static void lpphy_set_tx_gains(struct b43_wldev *dev,
+			       struct lpphy_tx_gains gains)
+{
+	u16 rf_gain, pa_gain;
+
+	if (dev->phy.rev < 2) {
+		rf_gain = (gains.pad << 7) | (gains.pga << 3) | gains.gm;
+		b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
+				0xF800, rf_gain);
+	} else {
+		pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0;
+		pa_gain <<= 2;
+		b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
+			      (gains.pga << 8) | gains.gm);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0xFB),
+				0x8000, gains.pad | pa_gain);
+		b43_phy_write(dev, B43_PHY_OFDM(0xFC),
+			      (gains.pga << 8) | gains.gm);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0xFD),
+				0x8000, gains.pad | pa_gain);
+	}
+	lpphy_set_dac_gain(dev, gains.dac);
+	if (dev->phy.rev < 2) {
+		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF, 1 << 8);
+	} else {
+		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7);
+		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14);
+	}
+	b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6);
+}
+
+static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain)
+{
+	u16 trsw = gain & 0x1;
+	u16 lna = (gain & 0xFFFC) | ((gain & 0xC) >> 2);
+	u16 ext_lna = (gain & 2) >> 1;
+
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFE, trsw);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL,
+			0xFBFF, ext_lna << 10);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL,
+			0xF7FF, ext_lna << 11);
+	b43_phy_write(dev, B43_LPPHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
+}
+
+static void lpphy_rev2plus_set_rx_gain(struct b43_wldev *dev, u32 gain)
+{
+	u16 low_gain = gain & 0xFFFF;
+	u16 high_gain = (gain >> 16) & 0xF;
+	u16 ext_lna = (gain >> 21) & 0x1;
+	u16 trsw = ~(gain >> 20) & 0x1;
+	u16 tmp;
+
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFE, trsw);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL,
+			0xFDFF, ext_lna << 9);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL,
+			0xFBFF, ext_lna << 10);
+	b43_phy_write(dev, B43_LPPHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_DDFS, 0xFFF0, high_gain);
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		tmp = (gain >> 2) & 0x3;
+		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL,
+				0xE7FF, tmp<<11);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0xE6), 0xFFE7, tmp << 3);
+	}
+}
+
+static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
+{
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
+	if (dev->phy.rev >= 2) {
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
+			b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
+		}
+	} else {
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
+	}
+}
+
+static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
+{
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
+	if (dev->phy.rev >= 2) {
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
+			b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
+		}
+	} else {
+		b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
+	}
+}
+
+static void lpphy_set_rx_gain(struct b43_wldev *dev, u32 gain)
+{
+	if (dev->phy.rev < 2)
+		lpphy_rev0_1_set_rx_gain(dev, gain);
+	else
+		lpphy_rev2plus_set_rx_gain(dev, gain);
+	lpphy_enable_rx_gain_override(dev);
+}
+
+static void lpphy_set_rx_gain_by_index(struct b43_wldev *dev, u16 idx)
+{
+	u32 gain = b43_lptab_read(dev, B43_LPTAB16(12, idx));
+	lpphy_set_rx_gain(dev, gain);
+}
+
+static void lpphy_stop_ddfs(struct b43_wldev *dev)
+{
+	b43_phy_mask(dev, B43_LPPHY_AFE_DDFS, 0xFFFD);
+	b43_phy_mask(dev, B43_LPPHY_LP_PHY_CTL, 0xFFDF);
+}
+
+static void lpphy_run_ddfs(struct b43_wldev *dev, int i_on, int q_on,
+			   int incr1, int incr2, int scale_idx)
+{
+	lpphy_stop_ddfs(dev);
+	b43_phy_mask(dev, B43_LPPHY_AFE_DDFS_POINTER_INIT, 0xFF80);
+	b43_phy_mask(dev, B43_LPPHY_AFE_DDFS_POINTER_INIT, 0x80FF);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_DDFS_INCR_INIT, 0xFF80, incr1);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_DDFS_INCR_INIT, 0x80FF, incr2 << 8);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_DDFS, 0xFFF7, i_on << 3);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_DDFS, 0xFFEF, q_on << 4);
+	b43_phy_maskset(dev, B43_LPPHY_AFE_DDFS, 0xFF9F, scale_idx << 5);
+	b43_phy_mask(dev, B43_LPPHY_AFE_DDFS, 0xFFFB);
+	b43_phy_set(dev, B43_LPPHY_AFE_DDFS, 0x2);
+	b43_phy_set(dev, B43_LPPHY_LP_PHY_CTL, 0x20);
+}
+
+static bool lpphy_rx_iq_est(struct b43_wldev *dev, u16 samples, u8 time,
+			   struct lpphy_iq_est *iq_est)
+{
+	int i;
+
+	b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFF7);
+	b43_phy_write(dev, B43_LPPHY_IQ_NUM_SMPLS_ADDR, samples);
+	b43_phy_maskset(dev, B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xFF00, time);
+	b43_phy_mask(dev, B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xFEFF);
+	b43_phy_set(dev, B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
+
+	for (i = 0; i < 500; i++) {
+		if (!(b43_phy_read(dev,
+				B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
+			break;
+		msleep(1);
+	}
+
+	if ((b43_phy_read(dev, B43_LPPHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
+		b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x8);
+		return false;
+	}
+
+	iq_est->iq_prod = b43_phy_read(dev, B43_LPPHY_IQ_ACC_HI_ADDR);
+	iq_est->iq_prod <<= 16;
+	iq_est->iq_prod |= b43_phy_read(dev, B43_LPPHY_IQ_ACC_LO_ADDR);
+
+	iq_est->i_pwr = b43_phy_read(dev, B43_LPPHY_IQ_I_PWR_ACC_HI_ADDR);
+	iq_est->i_pwr <<= 16;
+	iq_est->i_pwr |= b43_phy_read(dev, B43_LPPHY_IQ_I_PWR_ACC_LO_ADDR);
+
+	iq_est->q_pwr = b43_phy_read(dev, B43_LPPHY_IQ_Q_PWR_ACC_HI_ADDR);
+	iq_est->q_pwr <<= 16;
+	iq_est->q_pwr |= b43_phy_read(dev, B43_LPPHY_IQ_Q_PWR_ACC_LO_ADDR);
+
+	b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x8);
+	return true;
+}
+
+static int lpphy_loopback(struct b43_wldev *dev)
+{
+	struct lpphy_iq_est iq_est;
+	int i, index = -1;
+	u32 tmp;
+
+	memset(&iq_est, 0, sizeof(iq_est));
+
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x3);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
+	b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 1);
+	b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFFE);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x800);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x800);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x8);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x8);
+	b43_radio_write(dev, B2062_N_TX_CTL_A, 0x80);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x80);
+	b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0x80);
+	for (i = 0; i < 32; i++) {
+		lpphy_set_rx_gain_by_index(dev, i);
+		lpphy_run_ddfs(dev, 1, 1, 5, 5, 0);
+		if (!(lpphy_rx_iq_est(dev, 1000, 32, &iq_est)))
+			continue;
+		tmp = (iq_est.i_pwr + iq_est.q_pwr) / 1000;
+		if ((tmp > 4000) && (tmp < 10000)) {
+			index = i;
+			break;
+		}
+	}
+	lpphy_stop_ddfs(dev);
+	return index;
+}
+
+/* Fixed-point division algorithm using only integer math. */
+static u32 lpphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
+{
+	u32 quotient, remainder;
+
+	if (divisor == 0)
+		return 0;
+
+	quotient = dividend / divisor;
+	remainder = dividend % divisor;
+
+	while (precision > 0) {
+		quotient <<= 1;
+		if (remainder << 1 >= divisor) {
+			quotient++;
+			remainder = (remainder << 1) - divisor;
+		}
+		precision--;
+	}
+
+	if (remainder << 1 >= divisor)
+		quotient++;
+
+	return quotient;
+}
+
 /* Read the TX power control mode from hardware. */
 static void lpphy_read_tx_pctl_mode_from_hardware(struct b43_wldev *dev)
 {
@@ -322,9 +1109,9 @@ static void lpphy_set_tx_power_control(struct b43_wldev *dev,
 	struct b43_phy_lp *lpphy = dev->phy.lp;
 	enum b43_lpphy_txpctl_mode oldmode;
 
-	oldmode = lpphy->txpctl_mode;
 	lpphy_read_tx_pctl_mode_from_hardware(dev);
-	if (lpphy->txpctl_mode == mode)
+	oldmode = lpphy->txpctl_mode;
+	if (oldmode == mode)
 		return;
 	lpphy->txpctl_mode = mode;
 
@@ -345,13 +1132,186 @@ static void lpphy_set_tx_power_control(struct b43_wldev *dev,
 	}
 	if (dev->phy.rev >= 2) {
 		if (mode == B43_LPPHY_TXPCTL_HW)
-			b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0x2);
+			b43_phy_set(dev, B43_PHY_OFDM(0xD0), 0x2);
 		else
-			b43_phy_maskset(dev, B43_PHY_OFDM(0xD0), 0xFD, 0);
+			b43_phy_mask(dev, B43_PHY_OFDM(0xD0), 0xFFFD);
 	}
 	lpphy_write_tx_pctl_mode_to_hardware(dev);
 }
 
+static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
+				       unsigned int new_channel);
+
+static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	struct lpphy_iq_est iq_est;
+	struct lpphy_tx_gains tx_gains;
+	static const u32 ideal_pwr_table[21] = {
+		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
+		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
+		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
+		0x0004c, 0x0002c, 0x0001a,
+	};
+	bool old_txg_ovr;
+	u8 old_bbmult;
+	u16 old_rf_ovr, old_rf_ovrval, old_afe_ovr, old_afe_ovrval,
+	    old_rf2_ovr, old_rf2_ovrval, old_phy_ctl;
+	enum b43_lpphy_txpctl_mode old_txpctl;
+	u32 normal_pwr, ideal_pwr, mean_sq_pwr, tmp = 0, mean_sq_pwr_min = 0;
+	int loopback, i, j, inner_sum, err;
+
+	memset(&iq_est, 0, sizeof(iq_est));
+
+	err = b43_lpphy_op_switch_channel(dev, 7);
+	if (err) {
+		b43dbg(dev->wl,
+		       "RC calib: Failed to switch to channel 7, error = %d\n",
+		       err);
+	}
+	old_txg_ovr = !!(b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40);
+	old_bbmult = lpphy_get_bb_mult(dev);
+	if (old_txg_ovr)
+		tx_gains = lpphy_get_tx_gains(dev);
+	old_rf_ovr = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_0);
+	old_rf_ovrval = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_VAL_0);
+	old_afe_ovr = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR);
+	old_afe_ovrval = b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVRVAL);
+	old_rf2_ovr = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_2);
+	old_rf2_ovrval = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_2_VAL);
+	old_phy_ctl = b43_phy_read(dev, B43_LPPHY_LP_PHY_CTL);
+	lpphy_read_tx_pctl_mode_from_hardware(dev);
+	old_txpctl = lpphy->txpctl_mode;
+
+	lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
+	lpphy_disable_crs(dev, true);
+	loopback = lpphy_loopback(dev);
+	if (loopback == -1)
+		goto finish;
+	lpphy_set_rx_gain_by_index(dev, loopback);
+	b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFFBF, 0x40);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFFF8, 0x1);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFFC7, 0x8);
+	b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, 0xFF3F, 0xC0);
+	for (i = 128; i <= 159; i++) {
+		b43_radio_write(dev, B2062_N_RXBB_CALIB2, i);
+		inner_sum = 0;
+		for (j = 5; j <= 25; j++) {
+			lpphy_run_ddfs(dev, 1, 1, j, j, 0);
+			if (!(lpphy_rx_iq_est(dev, 1000, 32, &iq_est)))
+				goto finish;
+			mean_sq_pwr = iq_est.i_pwr + iq_est.q_pwr;
+			if (j == 5)
+				tmp = mean_sq_pwr;
+			ideal_pwr = ((ideal_pwr_table[j-5] >> 3) + 1) >> 1;
+			normal_pwr = lpphy_qdiv_roundup(mean_sq_pwr, tmp, 12);
+			mean_sq_pwr = ideal_pwr - normal_pwr;
+			mean_sq_pwr *= mean_sq_pwr;
+			inner_sum += mean_sq_pwr;
+			if ((i == 128) || (inner_sum < mean_sq_pwr_min)) {
+				lpphy->rc_cap = i;
+				mean_sq_pwr_min = inner_sum;
+			}
+		}
+	}
+	lpphy_stop_ddfs(dev);
+
+finish:
+	lpphy_restore_crs(dev, true);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, old_rf_ovrval);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, old_rf_ovr);
+	b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, old_afe_ovrval);
+	b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVR, old_afe_ovr);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2_VAL, old_rf2_ovrval);
+	b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, old_rf2_ovr);
+	b43_phy_write(dev, B43_LPPHY_LP_PHY_CTL, old_phy_ctl);
+
+	lpphy_set_bb_mult(dev, old_bbmult);
+	if (old_txg_ovr) {
+		/*
+		 * SPEC FIXME: The specs say "get_tx_gains" here, which is
+		 * illogical. According to lwfinger, vendor driver v4.150.10.5
+		 * has a Set here, while v4.174.64.19 has a Get - regression in
+		 * the vendor driver? This should be tested this once the code
+		 * is testable.
+		 */
+		lpphy_set_tx_gains(dev, tx_gains);
+	}
+	lpphy_set_tx_power_control(dev, old_txpctl);
+	if (lpphy->rc_cap)
+		lpphy_set_rc_cap(dev);
+}
+
+static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+	u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
+	u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF;
+	int i;
+
+	b43_radio_write(dev, B2063_RX_BB_SP8, 0x0);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7E);
+	b43_radio_mask(dev, B2063_PLL_SP1, 0xF7);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7C);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL2, 0x15);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL3, 0x70);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL4, 0x52);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL5, 0x1);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7D);
+
+	for (i = 0; i < 10000; i++) {
+		if (b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2)
+			break;
+		msleep(1);
+	}
+
+	if (!(b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2))
+		b43_radio_write(dev, B2063_RX_BB_SP8, tmp);
+
+	tmp = b43_radio_read(dev, B2063_TX_BB_SP3) & 0xFF;
+
+	b43_radio_write(dev, B2063_TX_BB_SP3, 0x0);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7E);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7C);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL2, 0x55);
+	b43_radio_write(dev, B2063_RC_CALIB_CTL3, 0x76);
+
+	if (crystal_freq == 24000000) {
+		b43_radio_write(dev, B2063_RC_CALIB_CTL4, 0xFC);
+		b43_radio_write(dev, B2063_RC_CALIB_CTL5, 0x0);
+	} else {
+		b43_radio_write(dev, B2063_RC_CALIB_CTL4, 0x13);
+		b43_radio_write(dev, B2063_RC_CALIB_CTL5, 0x1);
+	}
+
+	b43_radio_write(dev, B2063_PA_SP7, 0x7D);
+
+	for (i = 0; i < 10000; i++) {
+		if (b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2)
+			break;
+		msleep(1);
+	}
+
+	if (!(b43_radio_read(dev, B2063_RC_CALIB_CTL6) & 0x2))
+		b43_radio_write(dev, B2063_TX_BB_SP3, tmp);
+
+	b43_radio_write(dev, B2063_RC_CALIB_CTL1, 0x7E);
+}
+
+static void lpphy_calibrate_rc(struct b43_wldev *dev)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+
+	if (dev->phy.rev >= 2) {
+		lpphy_rev2plus_rc_calib(dev);
+	} else if (!lpphy->rc_cap) {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			lpphy_rev0_1_rc_calib(dev);
+	} else {
+		lpphy_set_rc_cap(dev);
+	}
+}
+
 static void lpphy_set_tx_power_by_index(struct b43_wldev *dev, u8 index)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
@@ -423,32 +1383,110 @@ static void lpphy_calibration(struct b43_wldev *dev)
 	b43_mac_enable(dev);
 }
 
-/* Initialize TX power control */
-static void lpphy_tx_pctl_init(struct b43_wldev *dev)
+static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode)
 {
-	if (0/*FIXME HWPCTL capable */) {
-		//TODO
-	} else { /* This device is only software TX power control capable. */
-		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-			//TODO
+	if (mode != TSSI_MUX_EXT) {
+		b43_radio_set(dev, B2063_PA_SP1, 0x2);
+		b43_phy_set(dev, B43_PHY_OFDM(0xF3), 0x1000);
+		b43_radio_write(dev, B2063_PA_CTL10, 0x51);
+		if (mode == TSSI_MUX_POSTPA) {
+			b43_radio_mask(dev, B2063_PA_SP1, 0xFFFE);
+			b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFC7);
 		} else {
-			//TODO
+			b43_radio_maskset(dev, B2063_PA_SP1, 0xFFFE, 0x1);
+			b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVRVAL,
+					0xFFC7, 0x20);
 		}
-		//TODO set BB multiplier to 0x0096
+	} else {
+		B43_WARN_ON(1);
 	}
 }
 
-static int b43_lpphy_op_init(struct b43_wldev *dev)
+static void lpphy_tx_pctl_init_hw(struct b43_wldev *dev)
 {
-	/* TODO: band SPROM */
-	lpphy_baseband_init(dev);
-	lpphy_radio_init(dev);
-	//TODO calibrate RC
-	//TODO set channel
-	lpphy_tx_pctl_init(dev);
-	//TODO full calib
+	u16 tmp;
+	int i;
 
-	return 0;
+	//SPEC TODO Call LP PHY Clear TX Power offsets
+	for (i = 0; i < 64; i++) {
+		if (dev->phy.rev >= 2)
+			b43_lptab_write(dev, B43_LPTAB32(7, i + 1), i);
+		else
+			b43_lptab_write(dev, B43_LPTAB32(10, i + 1), i);
+	}
+
+	b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0xFF00, 0xFF);
+	b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0x8FFF, 0x5000);
+	b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_IDLETSSI, 0xFFC0, 0x1F);
+	if (dev->phy.rev < 2) {
+		b43_phy_mask(dev, B43_LPPHY_LP_PHY_CTL, 0xEFFF);
+		b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xDFFF, 0x2000);
+	} else {
+		b43_phy_mask(dev, B43_PHY_OFDM(0x103), 0xFFFE);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0x103), 0xFFFB, 0x4);
+		b43_phy_maskset(dev, B43_PHY_OFDM(0x103), 0xFFEF, 0x10);
+		b43_radio_maskset(dev, B2063_IQ_CALIB_CTL2, 0xF3, 0x1);
+		lpphy_set_tssi_mux(dev, TSSI_MUX_POSTPA);
+	}
+	b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_IDLETSSI, 0x7FFF, 0x8000);
+	b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xFF);
+	b43_phy_write(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xA);
+	b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+			(u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE,
+			B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF);
+	b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0xF8FF);
+	b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
+			(u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE,
+			B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW);
+
+	if (dev->phy.rev < 2) {
+		b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_0, 0xEFFF, 0x1000);
+		b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xEFFF);
+	} else {
+		lpphy_set_tx_power_by_index(dev, 0x7F);
+	}
+
+	b43_dummy_transmission(dev, true, true);
+
+	tmp = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_STAT);
+	if (tmp & 0x8000) {
+		b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_IDLETSSI,
+				0xFFC0, (tmp & 0xFF) - 32);
+	}
+
+	b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xEFFF);
+
+	// (SPEC?) TODO Set "Target TX frequency" variable to 0
+	// SPEC FIXME "Set BB Multiplier to 0xE000" impossible - bb_mult is u8!
+}
+
+static void lpphy_tx_pctl_init_sw(struct b43_wldev *dev)
+{
+	struct lpphy_tx_gains gains;
+
+	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+		gains.gm = 4;
+		gains.pad = 12;
+		gains.pga = 12;
+		gains.dac = 0;
+	} else {
+		gains.gm = 7;
+		gains.pad = 14;
+		gains.pga = 15;
+		gains.dac = 0;
+	}
+	lpphy_set_tx_gains(dev, gains);
+	lpphy_set_bb_mult(dev, 150);
+}
+
+/* Initialize TX power control */
+static void lpphy_tx_pctl_init(struct b43_wldev *dev)
+{
+	if (0/*FIXME HWPCTL capable */) {
+		lpphy_tx_pctl_init_hw(dev);
+	} else { /* This device is only software TX power control capable. */
+		lpphy_tx_pctl_init_sw(dev);
+	}
 }
 
 static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg)
@@ -463,6 +1501,14 @@ static void b43_lpphy_op_write(struct b43_wldev *dev, u16 reg, u16 value)
 	b43_write16(dev, B43_MMIO_PHY_DATA, value);
 }
 
+static void b43_lpphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
+				 u16 set)
+{
+	b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
+	b43_write16(dev, B43_MMIO_PHY_DATA,
+		    (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
+}
+
 static u16 b43_lpphy_op_radio_read(struct b43_wldev *dev, u16 reg)
 {
 	/* Register 1 is a 32-bit register. */
@@ -493,23 +1539,681 @@ static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
 	//TODO
 }
 
+struct b206x_channel {
+	u8 channel;
+	u16 freq;
+	u8 data[12];
+};
+
+static const struct b206x_channel b2062_chantbl[] = {
+	{ .channel = 1, .freq = 2412, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 2, .freq = 2417, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 3, .freq = 2422, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 4, .freq = 2427, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 5, .freq = 2432, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 6, .freq = 2437, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 7, .freq = 2442, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 8, .freq = 2447, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 9, .freq = 2452, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 10, .freq = 2457, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 11, .freq = 2462, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 12, .freq = 2467, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 13, .freq = 2472, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 14, .freq = 2484, .data[0] = 0xFF, .data[1] = 0xFF,
+	  .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
+	  .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
+	{ .channel = 34, .freq = 5170, .data[0] = 0x00, .data[1] = 0x22,
+	  .data[2] = 0x20, .data[3] = 0x84, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 38, .freq = 5190, .data[0] = 0x00, .data[1] = 0x11,
+	  .data[2] = 0x10, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 42, .freq = 5210, .data[0] = 0x00, .data[1] = 0x11,
+	  .data[2] = 0x10, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 46, .freq = 5230, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 36, .freq = 5180, .data[0] = 0x00, .data[1] = 0x11,
+	  .data[2] = 0x20, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 40, .freq = 5200, .data[0] = 0x00, .data[1] = 0x11,
+	  .data[2] = 0x10, .data[3] = 0x84, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 44, .freq = 5220, .data[0] = 0x00, .data[1] = 0x11,
+	  .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 48, .freq = 5240, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 52, .freq = 5260, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 56, .freq = 5280, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 60, .freq = 5300, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x63, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 64, .freq = 5320, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x62, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 100, .freq = 5500, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x30, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 104, .freq = 5520, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 108, .freq = 5540, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 112, .freq = 5560, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 116, .freq = 5580, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x10, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 120, .freq = 5600, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 124, .freq = 5620, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 128, .freq = 5640, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 132, .freq = 5660, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 136, .freq = 5680, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 140, .freq = 5700, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 149, .freq = 5745, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 153, .freq = 5765, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 157, .freq = 5785, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 161, .freq = 5805, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 165, .freq = 5825, .data[0] = 0x00, .data[1] = 0x00,
+	  .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 184, .freq = 4920, .data[0] = 0x55, .data[1] = 0x77,
+	  .data[2] = 0x90, .data[3] = 0xF7, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
+	{ .channel = 188, .freq = 4940, .data[0] = 0x44, .data[1] = 0x77,
+	  .data[2] = 0x80, .data[3] = 0xE7, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
+	{ .channel = 192, .freq = 4960, .data[0] = 0x44, .data[1] = 0x66,
+	  .data[2] = 0x80, .data[3] = 0xE7, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
+	{ .channel = 196, .freq = 4980, .data[0] = 0x33, .data[1] = 0x66,
+	  .data[2] = 0x70, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
+	{ .channel = 200, .freq = 5000, .data[0] = 0x22, .data[1] = 0x55,
+	  .data[2] = 0x60, .data[3] = 0xD7, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
+	{ .channel = 204, .freq = 5020, .data[0] = 0x22, .data[1] = 0x55,
+	  .data[2] = 0x60, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
+	{ .channel = 208, .freq = 5040, .data[0] = 0x22, .data[1] = 0x44,
+	  .data[2] = 0x50, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
+	{ .channel = 212, .freq = 5060, .data[0] = 0x11, .data[1] = 0x44,
+	  .data[2] = 0x50, .data[3] = 0xA5, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+	{ .channel = 216, .freq = 5080, .data[0] = 0x00, .data[1] = 0x44,
+	  .data[2] = 0x40, .data[3] = 0xB6, .data[4] = 0x3C, .data[5] = 0x77,
+	  .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
+};
+
+static const struct b206x_channel b2063_chantbl[] = {
+	{ .channel = 1, .freq = 2412, .data[0] = 0x6F, .data[1] = 0x3C,
+	  .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 2, .freq = 2417, .data[0] = 0x6F, .data[1] = 0x3C,
+	  .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 3, .freq = 2422, .data[0] = 0x6F, .data[1] = 0x3C,
+	  .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 4, .freq = 2427, .data[0] = 0x6F, .data[1] = 0x2C,
+	  .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 5, .freq = 2432, .data[0] = 0x6F, .data[1] = 0x2C,
+	  .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 6, .freq = 2437, .data[0] = 0x6F, .data[1] = 0x2C,
+	  .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 7, .freq = 2442, .data[0] = 0x6F, .data[1] = 0x2C,
+	  .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 8, .freq = 2447, .data[0] = 0x6F, .data[1] = 0x2C,
+	  .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 9, .freq = 2452, .data[0] = 0x6F, .data[1] = 0x1C,
+	  .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 10, .freq = 2457, .data[0] = 0x6F, .data[1] = 0x1C,
+	  .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 11, .freq = 2462, .data[0] = 0x6E, .data[1] = 0x1C,
+	  .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 12, .freq = 2467, .data[0] = 0x6E, .data[1] = 0x1C,
+	  .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 13, .freq = 2472, .data[0] = 0x6E, .data[1] = 0x1C,
+	  .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 14, .freq = 2484, .data[0] = 0x6E, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
+	  .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x80, .data[11] = 0x70, },
+	{ .channel = 34, .freq = 5170, .data[0] = 0x6A, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x02, .data[5] = 0x05,
+	  .data[6] = 0x0D, .data[7] = 0x0D, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 36, .freq = 5180, .data[0] = 0x6A, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x05,
+	  .data[6] = 0x0D, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 38, .freq = 5190, .data[0] = 0x6A, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
+	  .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 40, .freq = 5200, .data[0] = 0x69, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
+	  .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 42, .freq = 5210, .data[0] = 0x69, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
+	  .data[6] = 0x0B, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 44, .freq = 5220, .data[0] = 0x69, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x04,
+	  .data[6] = 0x0B, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 46, .freq = 5230, .data[0] = 0x69, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03,
+	  .data[6] = 0x0A, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 48, .freq = 5240, .data[0] = 0x69, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03,
+	  .data[6] = 0x0A, .data[7] = 0x0A, .data[8] = 0x77, .data[9] = 0x60,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 52, .freq = 5260, .data[0] = 0x68, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x02,
+	  .data[6] = 0x09, .data[7] = 0x09, .data[8] = 0x77, .data[9] = 0x60,
+	  .data[10] = 0x20, .data[11] = 0x00, },
+	{ .channel = 56, .freq = 5280, .data[0] = 0x68, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01,
+	  .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
+	  .data[10] = 0x10, .data[11] = 0x00, },
+	{ .channel = 60, .freq = 5300, .data[0] = 0x68, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01,
+	  .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
+	  .data[10] = 0x10, .data[11] = 0x00, },
+	{ .channel = 64, .freq = 5320, .data[0] = 0x67, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
+	  .data[10] = 0x10, .data[11] = 0x00, },
+	{ .channel = 100, .freq = 5500, .data[0] = 0x64, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x02, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 104, .freq = 5520, .data[0] = 0x64, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x01, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 108, .freq = 5540, .data[0] = 0x63, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x01, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 112, .freq = 5560, .data[0] = 0x63, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 116, .freq = 5580, .data[0] = 0x62, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 120, .freq = 5600, .data[0] = 0x62, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 124, .freq = 5620, .data[0] = 0x62, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 128, .freq = 5640, .data[0] = 0x61, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 132, .freq = 5660, .data[0] = 0x61, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 136, .freq = 5680, .data[0] = 0x61, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 140, .freq = 5700, .data[0] = 0x60, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 149, .freq = 5745, .data[0] = 0x60, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 153, .freq = 5765, .data[0] = 0x60, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 157, .freq = 5785, .data[0] = 0x60, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 161, .freq = 5805, .data[0] = 0x60, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 165, .freq = 5825, .data[0] = 0x60, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
+	  .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
+	  .data[10] = 0x00, .data[11] = 0x00, },
+	{ .channel = 184, .freq = 4920, .data[0] = 0x6E, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0E,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xC0,
+	  .data[10] = 0x50, .data[11] = 0x00, },
+	{ .channel = 188, .freq = 4940, .data[0] = 0x6E, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0D,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0,
+	  .data[10] = 0x50, .data[11] = 0x00, },
+	{ .channel = 192, .freq = 4960, .data[0] = 0x6E, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0,
+	  .data[10] = 0x50, .data[11] = 0x00, },
+	{ .channel = 196, .freq = 4980, .data[0] = 0x6D, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
+	  .data[10] = 0x40, .data[11] = 0x00, },
+	{ .channel = 200, .freq = 5000, .data[0] = 0x6D, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0B,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
+	  .data[10] = 0x40, .data[11] = 0x00, },
+	{ .channel = 204, .freq = 5020, .data[0] = 0x6D, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0A,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
+	  .data[10] = 0x40, .data[11] = 0x00, },
+	{ .channel = 208, .freq = 5040, .data[0] = 0x6C, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x07, .data[5] = 0x09,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
+	  .data[10] = 0x40, .data[11] = 0x00, },
+	{ .channel = 212, .freq = 5060, .data[0] = 0x6C, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x06, .data[5] = 0x08,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
+	  .data[10] = 0x40, .data[11] = 0x00, },
+	{ .channel = 216, .freq = 5080, .data[0] = 0x6C, .data[1] = 0x0C,
+	  .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x05, .data[5] = 0x08,
+	  .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
+	  .data[10] = 0x40, .data[11] = 0x00, },
+};
+
+static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+
+	b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF);
+	udelay(20);
+	if (bus->chip_id == 0x5354) {
+		b43_radio_write(dev, B2062_N_COMM1, 4);
+		b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4);
+	} else {
+		b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0);
+	}
+	udelay(5);
+}
+
+static void lpphy_b2062_vco_calib(struct b43_wldev *dev)
+{
+	b43_radio_write(dev, B2062_S_RFPLL_CTL21, 0x42);
+	b43_radio_write(dev, B2062_S_RFPLL_CTL21, 0x62);
+	udelay(200);
+}
+
+static int lpphy_b2062_tune(struct b43_wldev *dev,
+			    unsigned int channel)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	struct ssb_bus *bus = dev->dev->bus;
+	const struct b206x_channel *chandata = NULL;
+	u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
+	u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
+	int i, err = 0;
+
+	for (i = 0; i < ARRAY_SIZE(b2062_chantbl); i++) {
+		if (b2062_chantbl[i].channel == channel) {
+			chandata = &b2062_chantbl[i];
+			break;
+		}
+	}
+
+	if (B43_WARN_ON(!chandata))
+		return -EINVAL;
+
+	b43_radio_set(dev, B2062_S_RFPLL_CTL14, 0x04);
+	b43_radio_write(dev, B2062_N_LGENA_TUNE0, chandata->data[0]);
+	b43_radio_write(dev, B2062_N_LGENA_TUNE2, chandata->data[1]);
+	b43_radio_write(dev, B2062_N_LGENA_TUNE3, chandata->data[2]);
+	b43_radio_write(dev, B2062_N_TX_TUNE, chandata->data[3]);
+	b43_radio_write(dev, B2062_S_LGENG_CTL1, chandata->data[4]);
+	b43_radio_write(dev, B2062_N_LGENA_CTL5, chandata->data[5]);
+	b43_radio_write(dev, B2062_N_LGENA_CTL6, chandata->data[6]);
+	b43_radio_write(dev, B2062_N_TX_PGA, chandata->data[7]);
+	b43_radio_write(dev, B2062_N_TX_PAD, chandata->data[8]);
+
+	tmp1 = crystal_freq / 1000;
+	tmp2 = lpphy->pdiv * 1000;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL33, 0xCC);
+	b43_radio_write(dev, B2062_S_RFPLL_CTL34, 0x07);
+	lpphy_b2062_reset_pll_bias(dev);
+	tmp3 = tmp2 * channel2freq_lp(channel);
+	if (channel2freq_lp(channel) < 4000)
+		tmp3 *= 2;
+	tmp4 = 48 * tmp1;
+	tmp6 = tmp3 / tmp4;
+	tmp7 = tmp3 % tmp4;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL26, tmp6);
+	tmp5 = tmp7 * 0x100;
+	tmp6 = tmp5 / tmp4;
+	tmp7 = tmp5 % tmp4;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL27, tmp6);
+	tmp5 = tmp7 * 0x100;
+	tmp6 = tmp5 / tmp4;
+	tmp7 = tmp5 % tmp4;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL28, tmp6);
+	tmp5 = tmp7 * 0x100;
+	tmp6 = tmp5 / tmp4;
+	tmp7 = tmp5 % tmp4;
+	b43_radio_write(dev, B2062_S_RFPLL_CTL29, tmp6 + ((2 * tmp7) / tmp4));
+	tmp8 = b43_radio_read(dev, B2062_S_RFPLL_CTL19);
+	tmp9 = ((2 * tmp3 * (tmp8 + 1)) + (3 * tmp1)) / (6 * tmp1);
+	b43_radio_write(dev, B2062_S_RFPLL_CTL23, (tmp9 >> 8) + 16);
+	b43_radio_write(dev, B2062_S_RFPLL_CTL24, tmp9 & 0xFF);
+
+	lpphy_b2062_vco_calib(dev);
+	if (b43_radio_read(dev, B2062_S_RFPLL_CTL3) & 0x10) {
+		b43_radio_write(dev, B2062_S_RFPLL_CTL33, 0xFC);
+		b43_radio_write(dev, B2062_S_RFPLL_CTL34, 0);
+		lpphy_b2062_reset_pll_bias(dev);
+		lpphy_b2062_vco_calib(dev);
+		if (b43_radio_read(dev, B2062_S_RFPLL_CTL3) & 0x10)
+			err = -EIO;
+	}
+
+	b43_radio_mask(dev, B2062_S_RFPLL_CTL14, ~0x04);
+	return err;
+}
+
+
+/* This was previously called lpphy_japan_filter */
+static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel)
+{
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter!
+
+	if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific?
+		b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9);
+		if ((dev->phy.rev == 1) && (lpphy->rc_cap))
+			lpphy_set_rc_cap(dev);
+	} else {
+		b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F);
+	}
+}
+
+static void lpphy_b2063_vco_calib(struct b43_wldev *dev)
+{
+	u16 tmp;
+
+	b43_radio_mask(dev, B2063_PLL_SP1, ~0x40);
+	tmp = b43_radio_read(dev, B2063_PLL_JTAG_CALNRST) & 0xF8;
+	b43_radio_write(dev, B2063_PLL_JTAG_CALNRST, tmp);
+	udelay(1);
+	b43_radio_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x4);
+	udelay(1);
+	b43_radio_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x6);
+	udelay(1);
+	b43_radio_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x7);
+	udelay(300);
+	b43_radio_set(dev, B2063_PLL_SP1, 0x40);
+}
+
+static int lpphy_b2063_tune(struct b43_wldev *dev,
+			    unsigned int channel)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+
+	static const struct b206x_channel *chandata = NULL;
+	u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
+	u32 freqref, vco_freq, val1, val2, val3, timeout, timeoutref, count;
+	u16 old_comm15, scale;
+	u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
+	int i, div = (crystal_freq <= 26000000 ? 1 : 2);
+
+	for (i = 0; i < ARRAY_SIZE(b2063_chantbl); i++) {
+		if (b2063_chantbl[i].channel == channel) {
+			chandata = &b2063_chantbl[i];
+			break;
+		}
+	}
+
+	if (B43_WARN_ON(!chandata))
+		return -EINVAL;
+
+	b43_radio_write(dev, B2063_LOGEN_VCOBUF1, chandata->data[0]);
+	b43_radio_write(dev, B2063_LOGEN_MIXER2, chandata->data[1]);
+	b43_radio_write(dev, B2063_LOGEN_BUF2, chandata->data[2]);
+	b43_radio_write(dev, B2063_LOGEN_RCCR1, chandata->data[3]);
+	b43_radio_write(dev, B2063_A_RX_1ST3, chandata->data[4]);
+	b43_radio_write(dev, B2063_A_RX_2ND1, chandata->data[5]);
+	b43_radio_write(dev, B2063_A_RX_2ND4, chandata->data[6]);
+	b43_radio_write(dev, B2063_A_RX_2ND7, chandata->data[7]);
+	b43_radio_write(dev, B2063_A_RX_PS6, chandata->data[8]);
+	b43_radio_write(dev, B2063_TX_RF_CTL2, chandata->data[9]);
+	b43_radio_write(dev, B2063_TX_RF_CTL5, chandata->data[10]);
+	b43_radio_write(dev, B2063_PA_CTL11, chandata->data[11]);
+
+	old_comm15 = b43_radio_read(dev, B2063_COMM15);
+	b43_radio_set(dev, B2063_COMM15, 0x1E);
+
+	if (chandata->freq > 4000) /* spec says 2484, but 4000 is safer */
+		vco_freq = chandata->freq << 1;
+	else
+		vco_freq = chandata->freq << 2;
+
+	freqref = crystal_freq * 3;
+	val1 = lpphy_qdiv_roundup(crystal_freq, 1000000, 16);
+	val2 = lpphy_qdiv_roundup(crystal_freq, 1000000 * div, 16);
+	val3 = lpphy_qdiv_roundup(vco_freq, 3, 16);
+	timeout = ((((8 * crystal_freq) / (div * 5000000)) + 1) >> 1) - 1;
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB3, 0x2);
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB6,
+			  0xFFF8, timeout >> 2);
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB7,
+			  0xFF9F,timeout << 5);
+
+	timeoutref = ((((8 * crystal_freq) / (div * (timeout + 1))) +
+						999999) / 1000000) + 1;
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB5, timeoutref);
+
+	count = lpphy_qdiv_roundup(val3, val2 + 16, 16);
+	count *= (timeout + 1) * (timeoutref + 1);
+	count--;
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB7,
+						0xF0, count >> 8);
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB8, count & 0xFF);
+
+	tmp1 = ((val3 * 62500) / freqref) << 4;
+	tmp2 = ((val3 * 62500) % freqref) << 4;
+	while (tmp2 >= freqref) {
+		tmp1++;
+		tmp2 -= freqref;
+	}
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG1, 0xFFE0, tmp1 >> 4);
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG2, 0xFE0F, tmp1 << 4);
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG2, 0xFFF0, tmp1 >> 16);
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_SG3, (tmp2 >> 8) & 0xFF);
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_SG4, tmp2 & 0xFF);
+
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF1, 0xB9);
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF2, 0x88);
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF3, 0x28);
+	b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF4, 0x63);
+
+	tmp3 = ((41 * (val3 - 3000)) /1200) + 27;
+	tmp4 = lpphy_qdiv_roundup(132000 * tmp1, 8451, 16);
+
+	if ((tmp4 + tmp3 - 1) / tmp3 > 60) {
+		scale = 1;
+		tmp5 = ((tmp4 + tmp3) / (tmp3 << 1)) - 8;
+	} else {
+		scale = 0;
+		tmp5 = ((tmp4 + (tmp3 >> 1)) / tmp3) - 8;
+	}
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_CP2, 0xFFC0, tmp5);
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_CP2, 0xFFBF, scale << 6);
+
+	tmp6 = lpphy_qdiv_roundup(100 * val1, val3, 16);
+	tmp6 *= (tmp5 * 8) * (scale + 1);
+	if (tmp6 > 150)
+		tmp6 = 0;
+
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_CP3, 0xFFE0, tmp6);
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_CP3, 0xFFDF, scale << 5);
+
+	b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0xFFFB, 0x4);
+	if (crystal_freq > 26000000)
+		b43_radio_set(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0x2);
+	else
+		b43_radio_mask(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0xFD);
+
+	if (val1 == 45)
+		b43_radio_set(dev, B2063_PLL_JTAG_PLL_VCO1, 0x2);
+	else
+		b43_radio_mask(dev, B2063_PLL_JTAG_PLL_VCO1, 0xFD);
+
+	b43_radio_set(dev, B2063_PLL_SP2, 0x3);
+	udelay(1);
+	b43_radio_mask(dev, B2063_PLL_SP2, 0xFFFC);
+	lpphy_b2063_vco_calib(dev);
+	b43_radio_write(dev, B2063_COMM15, old_comm15);
+
+	return 0;
+}
+
 static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
 				       unsigned int new_channel)
 {
-	//TODO
+	struct b43_phy_lp *lpphy = dev->phy.lp;
+	int err;
+
+	if (dev->phy.radio_ver == 0x2063) {
+		err = lpphy_b2063_tune(dev, new_channel);
+		if (err)
+			return err;
+	} else {
+		err = lpphy_b2062_tune(dev, new_channel);
+		if (err)
+			return err;
+		lpphy_set_analog_filter(dev, new_channel);
+		lpphy_adjust_gain_table(dev, channel2freq_lp(new_channel));
+	}
+
+	lpphy->channel = new_channel;
+	b43_write16(dev, B43_MMIO_CHANNEL, new_channel);
+
 	return 0;
 }
 
-static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
+static int b43_lpphy_op_init(struct b43_wldev *dev)
 {
-	if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
-		return 1;
-	return 36;
+	int err;
+
+	lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs?
+	lpphy_baseband_init(dev);
+	lpphy_radio_init(dev);
+	lpphy_calibrate_rc(dev);
+	err = b43_lpphy_op_switch_channel(dev, 7);
+	if (err) {
+		b43dbg(dev->wl, "Switch to channel 7 failed, error = %d.\n",
+		       err);
+	}
+	lpphy_tx_pctl_init(dev);
+	lpphy_calibration(dev);
+	//TODO ACI init
+
+	return 0;
 }
 
 static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
 {
-	//TODO
+	if (dev->phy.rev >= 2)
+		return; // rev2+ doesn't support antenna diversity
+
+	if (B43_WARN_ON(antenna > B43_ANTENNA_AUTO1))
+		return;
+
+	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFD, antenna & 0x2);
+	b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFFE, antenna & 0x1);
 }
 
 static void b43_lpphy_op_adjust_txpower(struct b43_wldev *dev)
@@ -524,7 +2228,6 @@ static enum b43_txpwr_result b43_lpphy_op_recalc_txpower(struct b43_wldev *dev,
 	return B43_TXPWR_RES_DONE;
 }
 
-
 const struct b43_phy_operations b43_phyops_lp = {
 	.allocate		= b43_lpphy_op_allocate,
 	.free			= b43_lpphy_op_free,
@@ -532,6 +2235,7 @@ const struct b43_phy_operations b43_phyops_lp = {
 	.init			= b43_lpphy_op_init,
 	.phy_read		= b43_lpphy_op_read,
 	.phy_write		= b43_lpphy_op_write,
+	.phy_maskset		= b43_lpphy_op_maskset,
 	.radio_read		= b43_lpphy_op_radio_read,
 	.radio_write		= b43_lpphy_op_radio_write,
 	.software_rfkill	= b43_lpphy_op_software_rfkill,
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index 18370b4..c3232c1 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -273,12 +273,19 @@
 #define B43_LPPHY_AFE_DDFS_POINTER_INIT		B43_PHY_OFDM(0xB8) /* AFE DDFS pointer init */
 #define B43_LPPHY_AFE_DDFS_INCR_INIT		B43_PHY_OFDM(0xB9) /* AFE DDFS incr init */
 #define B43_LPPHY_MRCNOISEREDUCTION		B43_PHY_OFDM(0xBA) /* mrcNoiseReduction */
-#define B43_LPPHY_TRLOOKUP3			B43_PHY_OFDM(0xBB) /* TRLookup3 */
-#define B43_LPPHY_TRLOOKUP4			B43_PHY_OFDM(0xBC) /* TRLookup4 */
+#define B43_LPPHY_TR_LOOKUP_3			B43_PHY_OFDM(0xBB) /* TR Lookup 3 */
+#define B43_LPPHY_TR_LOOKUP_4			B43_PHY_OFDM(0xBC) /* TR Lookup 4 */
 #define B43_LPPHY_RADAR_FIFO_STAT		B43_PHY_OFDM(0xBD) /* Radar FIFO Status */
 #define B43_LPPHY_GPIO_OUTEN			B43_PHY_OFDM(0xBE) /* GPIO Out enable */
 #define B43_LPPHY_GPIO_SELECT			B43_PHY_OFDM(0xBF) /* GPIO Select */
 #define B43_LPPHY_GPIO_OUT			B43_PHY_OFDM(0xC0) /* GPIO Out */
+#define B43_LPPHY_4C3				B43_PHY_OFDM(0xC3) /* unknown, used during BB init */
+#define B43_LPPHY_4C4				B43_PHY_OFDM(0xC4) /* unknown, used during BB init */
+#define B43_LPPHY_4C5				B43_PHY_OFDM(0xC5) /* unknown, used during BB init */
+#define B43_LPPHY_TR_LOOKUP_5			B43_PHY_OFDM(0xC7) /* TR Lookup 5 */
+#define B43_LPPHY_TR_LOOKUP_6			B43_PHY_OFDM(0xC8) /* TR Lookup 6 */
+#define B43_LPPHY_TR_LOOKUP_7			B43_PHY_OFDM(0xC9) /* TR Lookup 7 */
+#define B43_LPPHY_TR_LOOKUP_8			B43_PHY_OFDM(0xCA) /* TR Lookup 8 */
 
 
 
@@ -818,14 +825,30 @@ struct b43_phy_lp {
 	enum b43_lpphy_txpctl_mode txpctl_mode;
 
 	/* Transmit isolation medium band */
-	u8 tx_isolation_med_band; /* FIXME initial value? */
+	u8 tx_isolation_med_band;
 	/* Transmit isolation low band */
-	u8 tx_isolation_low_band; /* FIXME initial value? */
+	u8 tx_isolation_low_band;
 	/* Transmit isolation high band */
-	u8 tx_isolation_hi_band; /* FIXME initial value? */
+	u8 tx_isolation_hi_band;
+
+	/* Max transmit power medium band */
+	u16 max_tx_pwr_med_band;
+	/* Max transmit power low band */
+	u16 max_tx_pwr_low_band;
+	/* Max transmit power high band */
+	u16 max_tx_pwr_hi_band;
+
+	/* FIXME What are these used for? */
+	/* FIXME Is 15 the correct array size? */
+	u16 tx_max_rate[15];
+	u16 tx_max_ratel[15];
+	u16 tx_max_rateh[15];
+
+	/* Transmit power arrays */
+	s16 txpa[3], txpal[3], txpah[3];
 
 	/* Receive power offset */
-	u8 rx_pwr_offset; /* FIXME initial value? */
+	u8 rx_pwr_offset;
 
 	/* TSSI transmit count */
 	u16 tssi_tx_count;
@@ -841,16 +864,16 @@ struct b43_phy_lp {
 	s8 tx_pwr_idx_over; /* FIXME initial value? */
 
 	/* RSSI vf */
-	u8 rssi_vf; /* FIXME initial value? */
+	u8 rssi_vf;
 	/* RSSI vc */
-	u8 rssi_vc; /* FIXME initial value? */
+	u8 rssi_vc;
 	/* RSSI gs */
-	u8 rssi_gs; /* FIXME initial value? */
+	u8 rssi_gs;
 
 	/* RC cap */
 	u8 rc_cap; /* FIXME initial value? */
 	/* BX arch */
-	u8 bx_arch; /* FIXME initial value? */
+	u8 bx_arch;
 
 	/* Full calibration channel */
 	u8 full_calib_chan; /* FIXME initial value? */
@@ -858,8 +881,23 @@ struct b43_phy_lp {
 	/* Transmit iqlocal best coeffs */
 	bool tx_iqloc_best_coeffs_valid;
 	u8 tx_iqloc_best_coeffs[11];
+
+	/* Used for "Save/Restore Dig Filt State" */
+	u16 dig_flt_state[9];
+
+	bool crs_usr_disable, crs_sys_disable;
+
+	unsigned int pdiv;
+
+	/* The channel we are tuned to */
+	u8 channel;
 };
 
+enum tssi_mux_mode {
+	TSSI_MUX_PREPA,
+	TSSI_MUX_POSTPA,
+	TSSI_MUX_EXT,
+};
 
 struct b43_phy_operations;
 extern const struct b43_phy_operations b43_phyops_lp;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index be7b560..992318a 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -137,7 +137,8 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
 
 	b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
 	msleep(1);
-	if ((sprom->revision != 4) || !(sprom->boardflags_hi & 0x0002)) {
+	if ((sprom->revision != 4) ||
+	   !(sprom->boardflags_hi & B43_BFH_RSSIINV)) {
 		if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) ||
 		    (binfo->type != 0x46D) ||
 		    (binfo->rev < 0x41)) {
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 69138e8..3498b68 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -32,9 +32,6 @@
 #include <linux/delay.h>
 
 
-static void b43_pio_rx_work(struct work_struct *work);
-
-
 static u16 generate_cookie(struct b43_pio_txqueue *q,
 			   struct b43_pio_txpacket *pack)
 {
@@ -144,7 +141,6 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
 	q = kzalloc(sizeof(*q), GFP_KERNEL);
 	if (!q)
 		return NULL;
-	spin_lock_init(&q->lock);
 	q->dev = dev;
 	q->rev = dev->dev->id.revision;
 	q->mmio_base = index_to_pioqueue_base(dev, index) +
@@ -179,12 +175,10 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
 	q = kzalloc(sizeof(*q), GFP_KERNEL);
 	if (!q)
 		return NULL;
-	spin_lock_init(&q->lock);
 	q->dev = dev;
 	q->rev = dev->dev->id.revision;
 	q->mmio_base = index_to_pioqueue_base(dev, index) +
 		       pio_rxqueue_offset(dev);
-	INIT_WORK(&q->rx_work, b43_pio_rx_work);
 
 	/* Enable Direct FIFO RX (PIO) on the engine. */
 	b43_dma_direct_fifo_rx(dev, index, 1);
@@ -249,13 +243,6 @@ void b43_pio_free(struct b43_wldev *dev)
 	destroy_queue_tx(pio, tx_queue_AC_BK);
 }
 
-void b43_pio_stop(struct b43_wldev *dev)
-{
-	if (!b43_using_pio_transfers(dev))
-		return;
-	cancel_work_sync(&dev->pio.rx_queue->rx_work);
-}
-
 int b43_pio_init(struct b43_wldev *dev)
 {
 	struct b43_pio *pio = &dev->pio;
@@ -461,8 +448,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
 
 	cookie = generate_cookie(q, pack);
 	hdrlen = b43_txhdr_size(q->dev);
-	err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb->data,
-				 skb->len, info, cookie);
+	err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb,
+				 info, cookie);
 	if (err)
 		return err;
 
@@ -494,7 +481,6 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
 {
 	struct b43_pio_txqueue *q;
 	struct ieee80211_hdr *hdr;
-	unsigned long flags;
 	unsigned int hdrlen, total_len;
 	int err = 0;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -512,20 +498,18 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
 		q = select_queue_by_priority(dev, skb_get_queue_mapping(skb));
 	}
 
-	spin_lock_irqsave(&q->lock, flags);
-
 	hdrlen = b43_txhdr_size(dev);
 	total_len = roundup(skb->len + hdrlen, 4);
 
 	if (unlikely(total_len > q->buffer_size)) {
 		err = -ENOBUFS;
 		b43dbg(dev->wl, "PIO: TX packet longer than queue.\n");
-		goto out_unlock;
+		goto out;
 	}
 	if (unlikely(q->free_packet_slots == 0)) {
 		err = -ENOBUFS;
 		b43warn(dev->wl, "PIO: TX packet overflow.\n");
-		goto out_unlock;
+		goto out;
 	}
 	B43_WARN_ON(q->buffer_used > q->buffer_size);
 
@@ -534,7 +518,7 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
 		err = -EBUSY;
 		ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb));
 		q->stopped = 1;
-		goto out_unlock;
+		goto out;
 	}
 
 	/* Assign the queue number to the ring (if not already done before)
@@ -548,11 +532,11 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
 		 * anymore and must not transmit it unencrypted. */
 		dev_kfree_skb_any(skb);
 		err = 0;
-		goto out_unlock;
+		goto out;
 	}
 	if (unlikely(err)) {
 		b43err(dev->wl, "PIO transmission failure\n");
-		goto out_unlock;
+		goto out;
 	}
 	q->nr_tx_packets++;
 
@@ -564,13 +548,10 @@ int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
 		q->stopped = 1;
 	}
 
-out_unlock:
-	spin_unlock_irqrestore(&q->lock, flags);
-
+out:
 	return err;
 }
 
-/* Called with IRQs disabled. */
 void b43_pio_handle_txstatus(struct b43_wldev *dev,
 			     const struct b43_txstatus *status)
 {
@@ -584,8 +565,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
 		return;
 	B43_WARN_ON(!pack);
 
-	spin_lock(&q->lock); /* IRQs are already disabled. */
-
 	info = IEEE80211_SKB_CB(pack->skb);
 
 	b43_fill_txstatus_report(dev, info, status);
@@ -603,8 +582,6 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
 		ieee80211_wake_queue(dev->wl->hw, q->queue_prio);
 		q->stopped = 0;
 	}
-
-	spin_unlock(&q->lock);
 }
 
 void b43_pio_get_tx_stats(struct b43_wldev *dev,
@@ -612,17 +589,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
 {
 	const int nr_queues = dev->wl->hw->queues;
 	struct b43_pio_txqueue *q;
-	unsigned long flags;
 	int i;
 
 	for (i = 0; i < nr_queues; i++) {
 		q = select_queue_by_priority(dev, i);
 
-		spin_lock_irqsave(&q->lock, flags);
 		stats[i].len = B43_PIO_MAX_NR_TXPACKETS - q->free_packet_slots;
 		stats[i].limit = B43_PIO_MAX_NR_TXPACKETS;
 		stats[i].count = q->nr_tx_packets;
-		spin_unlock_irqrestore(&q->lock, flags);
 	}
 }
 
@@ -760,37 +734,23 @@ rx_error:
 	return 1;
 }
 
-/* RX workqueue. We can sleep, yay! */
-static void b43_pio_rx_work(struct work_struct *work)
+void b43_pio_rx(struct b43_pio_rxqueue *q)
 {
-	struct b43_pio_rxqueue *q = container_of(work, struct b43_pio_rxqueue,
-						 rx_work);
-	unsigned int budget = 50;
+	unsigned int count = 0;
 	bool stop;
 
-	do {
-		spin_lock_irq(&q->lock);
+	while (1) {
 		stop = (pio_rx_frame(q) == 0);
-		spin_unlock_irq(&q->lock);
-		cond_resched();
 		if (stop)
 			break;
-	} while (--budget);
-}
-
-/* Called with IRQs disabled. */
-void b43_pio_rx(struct b43_pio_rxqueue *q)
-{
-	/* Due to latency issues we must run the RX path in
-	 * a workqueue to be able to schedule between packets. */
-	queue_work(q->dev->wl->hw->workqueue, &q->rx_work);
+		cond_resched();
+		if (WARN_ON_ONCE(++count > 10000))
+			break;
+	}
 }
 
 static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&q->lock, flags);
 	if (q->rev >= 8) {
 		b43_piotx_write32(q, B43_PIO8_TXCTL,
 				  b43_piotx_read32(q, B43_PIO8_TXCTL)
@@ -800,14 +760,10 @@ static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
 				  b43_piotx_read16(q, B43_PIO_TXCTL)
 				  | B43_PIO_TXCTL_SUSPREQ);
 	}
-	spin_unlock_irqrestore(&q->lock, flags);
 }
 
 static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&q->lock, flags);
 	if (q->rev >= 8) {
 		b43_piotx_write32(q, B43_PIO8_TXCTL,
 				  b43_piotx_read32(q, B43_PIO8_TXCTL)
@@ -817,7 +773,6 @@ static void b43_pio_tx_resume_queue(struct b43_pio_txqueue *q)
 				  b43_piotx_read16(q, B43_PIO_TXCTL)
 				  & ~B43_PIO_TXCTL_SUSPREQ);
 	}
-	spin_unlock_irqrestore(&q->lock, flags);
 }
 
 void b43_pio_tx_suspend(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
index 6c174c9..7dd649c 100644
--- a/drivers/net/wireless/b43/pio.h
+++ b/drivers/net/wireless/b43/pio.h
@@ -70,7 +70,6 @@ struct b43_pio_txpacket {
 
 struct b43_pio_txqueue {
 	struct b43_wldev *dev;
-	spinlock_t lock;
 	u16 mmio_base;
 
 	/* The device queue buffer size in bytes. */
@@ -103,12 +102,8 @@ struct b43_pio_txqueue {
 
 struct b43_pio_rxqueue {
 	struct b43_wldev *dev;
-	spinlock_t lock;
 	u16 mmio_base;
 
-	/* Work to reduce latency issues on RX. */
-	struct work_struct rx_work;
-
 	/* Shortcut to the 802.11 core revision. This is to
 	 * avoid horrible pointer dereferencing in the fastpaths. */
 	u8 rev;
@@ -162,7 +157,6 @@ static inline void b43_piorx_write32(struct b43_pio_rxqueue *q,
 
 
 int b43_pio_init(struct b43_wldev *dev);
-void b43_pio_stop(struct b43_wldev *dev);
 void b43_pio_free(struct b43_wldev *dev);
 
 int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb);
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c
index 5adaa36..f1ae4e0 100644
--- a/drivers/net/wireless/b43/sysfs.c
+++ b/drivers/net/wireless/b43/sysfs.c
@@ -94,7 +94,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
 					 const char *buf, size_t count)
 {
 	struct b43_wldev *wldev = dev_to_b43_wldev(dev);
-	unsigned long flags;
 	int err;
 	int mode;
 
@@ -120,7 +119,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
 	}
 
 	mutex_lock(&wldev->wl->mutex);
-	spin_lock_irqsave(&wldev->wl->irq_lock, flags);
 
 	if (wldev->phy.ops->interf_mitigation) {
 		err = wldev->phy.ops->interf_mitigation(wldev, mode);
@@ -132,7 +130,6 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
 		err = -ENOSYS;
 
 	mmiowb();
-	spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
 	mutex_unlock(&wldev->wl->mutex);
 
 	return err ? err : count;
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
index 4ea734d..61027ee 100644
--- a/drivers/net/wireless/b43/tables_lpphy.c
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -1,9 +1,10 @@
 /*
 
   Broadcom B43 wireless driver
-  IEEE 802.11g LP-PHY and radio device data tables
+  IEEE 802.11a/g LP-PHY and radio device data tables
 
   Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
+  Copyright (c) 2009 GÃ¡bor Stefanik <netrolller.3d@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
@@ -28,22 +29,22 @@
 #include "phy_lp.h"
 
 
-/* Entry of the 2062 radio init table */
-struct b2062_init_tab_entry {
+/* Entry of the 2062/2063 radio init table */
+struct b206x_init_tab_entry {
 	u16 offset;
 	u16 value_a;
 	u16 value_g;
 	u8 flags;
 };
-#define B2062_FLAG_A	0x01 /* Flag: Init in A mode */
-#define B2062_FLAG_G	0x02 /* Flag: Init in G mode */
+#define B206X_FLAG_A	0x01 /* Flag: Init in A mode */
+#define B206X_FLAG_G	0x02 /* Flag: Init in G mode */
 
-static const struct b2062_init_tab_entry b2062_init_tab[] = {
+static const struct b206x_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_N_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = 0x0001, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_N_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
@@ -56,42 +57,42 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_N_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_PDN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_N_PDN_CTL1, .value_a = 0x0000, .value_g = 0x00CA, .flags = B2062_FLAG_G, },
+	{ .offset = B2062_N_PDN_CTL1, .value_a = 0x0000, .value_g = 0x00CA, .flags = B206X_FLAG_G, },
 	/* { .offset = B2062_N_PDN_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
-	{ .offset = B2062_N_PDN_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_N_PDN_CTL4, .value_a = 0x0015, .value_g = 0x002A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_PDN_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_N_PDN_CTL4, .value_a = 0x0015, .value_g = 0x002A, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_GEN_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_IQ_CALIB, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
-	{ .offset = B2062_N_LGENC, .value_a = 0x00DB, .value_g = 0x00FF, .flags = B2062_FLAG_A, },
+	{ .offset = B2062_N_LGENC, .value_a = 0x00DB, .value_g = 0x00FF, .flags = B206X_FLAG_A, },
 	/* { .offset = B2062_N_LGENA_LPF, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
 	/* { .offset = B2062_N_LGENA_BIAS0, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
 	/* { .offset = B2062_N_LGNEA_BIAS1, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
 	/* { .offset = B2062_N_LGENA_CTL0, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
 	/* { .offset = B2062_N_LGENA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_LGENA_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_N_LGENA_TUNE0, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_LGENA_TUNE0, .value_a = 0x00DD, .value_g = 0x0000, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_LGENA_TUNE1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_N_LGENA_TUNE2, .value_a = 0x00DD, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_N_LGENA_TUNE3, .value_a = 0x0077, .value_g = 0x00B5, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_N_LGENA_CTL3, .value_a = 0x0000, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_LGENA_TUNE2, .value_a = 0x00DD, .value_g = 0x0000, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_N_LGENA_TUNE3, .value_a = 0x0077, .value_g = 0x00B5, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_N_LGENA_CTL3, .value_a = 0x0000, .value_g = 0x00FF, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_LGENA_CTL4, .value_a = 0x001F, .value_g = 0x001F, .flags = 0, }, */
 	/* { .offset = B2062_N_LGENA_CTL5, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
 	/* { .offset = B2062_N_LGENA_CTL6, .value_a = 0x0032, .value_g = 0x0032, .flags = 0, }, */
-	{ .offset = B2062_N_LGENA_CTL7, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_LGENA_CTL7, .value_a = 0x0033, .value_g = 0x0033, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_RXA_CTL0, .value_a = 0x0009, .value_g = 0x0009, .flags = 0, }, */
-	{ .offset = B2062_N_RXA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_G, },
+	{ .offset = B2062_N_RXA_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
 	/* { .offset = B2062_N_RXA_CTL2, .value_a = 0x0018, .value_g = 0x0018, .flags = 0, }, */
 	/* { .offset = B2062_N_RXA_CTL3, .value_a = 0x0027, .value_g = 0x0027, .flags = 0, }, */
 	/* { .offset = B2062_N_RXA_CTL4, .value_a = 0x0028, .value_g = 0x0028, .flags = 0, }, */
 	/* { .offset = B2062_N_RXA_CTL5, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
 	/* { .offset = B2062_N_RXA_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_RXA_CTL7, .value_a = 0x0008, .value_g = 0x0008, .flags = 0, }, */
-	{ .offset = B2062_N_RXBB_CTL0, .value_a = 0x0082, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_RXBB_CTL0, .value_a = 0x0082, .value_g = 0x0080, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_RXBB_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_RXBB_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_RXBB_GAIN0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_N_RXBB_GAIN1, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_N_RXBB_GAIN2, .value_a = 0x0000, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_RXBB_GAIN1, .value_a = 0x0004, .value_g = 0x0004, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_N_RXBB_GAIN2, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_RXBB_GAIN3, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
 	/* { .offset = B2062_N_RXBB_RSSI0, .value_a = 0x0043, .value_g = 0x0043, .flags = 0, }, */
 	/* { .offset = B2062_N_RXBB_RSSI1, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
@@ -112,8 +113,8 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_N_TX_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_CTL2, .value_a = 0x0084, .value_g = 0x0084, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_N_TX_CTL4, .value_a = 0x0003, .value_g = 0x0003, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_N_TX_CTL5, .value_a = 0x0002, .value_g = 0x0002, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_TX_CTL4, .value_a = 0x0003, .value_g = 0x0003, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_N_TX_CTL5, .value_a = 0x0002, .value_g = 0x0002, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_TX_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_CTL7, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_CTL8, .value_a = 0x0082, .value_g = 0x0082, .flags = 0, }, */
@@ -121,7 +122,7 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_N_TX_CTL_A, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_GC2G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_GC5G, .value_a = 0x00FF, .value_g = 0x00FF, .flags = 0, }, */
-	{ .offset = B2062_N_TX_TUNE, .value_a = 0x0088, .value_g = 0x001B, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_N_TX_TUNE, .value_a = 0x0088, .value_g = 0x001B, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_N_TX_PAD, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_PGA, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
 	/* { .offset = B2062_N_TX_PADAUX, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
@@ -150,7 +151,7 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_S_RADIO_ID_CODE, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_COMM4, .value_a = 0x0001, .value_g = 0x0000, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
@@ -162,24 +163,24 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_S_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_COMM14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_COMM15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_PDS_CTL0, .value_a = 0x00FF, .value_g = 0x00FF, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_PDS_CTL0, .value_a = 0x00FF, .value_g = 0x00FF, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_PDS_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_PDS_CTL2, .value_a = 0x008E, .value_g = 0x008E, .flags = 0, }, */
 	/* { .offset = B2062_S_PDS_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_BG_CTL0, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
 	/* { .offset = B2062_S_BG_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_BG_CTL2, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
-	{ .offset = B2062_S_LGENG_CTL0, .value_a = 0x00F8, .value_g = 0x00D8, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_LGENG_CTL1, .value_a = 0x003C, .value_g = 0x0024, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_LGENG_CTL0, .value_a = 0x00F8, .value_g = 0x00D8, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_LGENG_CTL1, .value_a = 0x003C, .value_g = 0x0024, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_LGENG_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_LGENG_CTL3, .value_a = 0x0041, .value_g = 0x0041, .flags = 0, }, */
 	/* { .offset = B2062_S_LGENG_CTL4, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
 	/* { .offset = B2062_S_LGENG_CTL5, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
 	/* { .offset = B2062_S_LGENG_CTL6, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
 	/* { .offset = B2062_S_LGENG_CTL7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_LGENG_CTL8, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_LGENG_CTL8, .value_a = 0x0088, .value_g = 0x0080, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_LGENG_CTL9, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
-	{ .offset = B2062_S_LGENG_CTL10, .value_a = 0x0088, .value_g = 0x0080, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_LGENG_CTL10, .value_a = 0x0088, .value_g = 0x0080, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_LGENG_CTL11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_REFPLL_CTL0, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_REFPLL_CTL1, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
@@ -198,41 +199,41 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_S_REFPLL_CTL14, .value_a = 0x0075, .value_g = 0x0075, .flags = 0, }, */
 	/* { .offset = B2062_S_REFPLL_CTL15, .value_a = 0x00B4, .value_g = 0x00B4, .flags = 0, }, */
 	/* { .offset = B2062_S_REFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_RFPLL_CTL0, .value_a = 0x0098, .value_g = 0x0098, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL1, .value_a = 0x0010, .value_g = 0x0010, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL0, .value_a = 0x0098, .value_g = 0x0098, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL1, .value_a = 0x0010, .value_g = 0x0010, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_RFPLL_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RFPLL_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RFPLL_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_RFPLL_CTL5, .value_a = 0x0043, .value_g = 0x0043, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL6, .value_a = 0x0047, .value_g = 0x0047, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL7, .value_a = 0x000C, .value_g = 0x000C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL8, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL9, .value_a = 0x0011, .value_g = 0x0011, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL10, .value_a = 0x000E, .value_g = 0x000E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL11, .value_a = 0x0008, .value_g = 0x0008, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL12, .value_a = 0x0033, .value_g = 0x0033, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL13, .value_a = 0x000A, .value_g = 0x000A, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL14, .value_a = 0x0006, .value_g = 0x0006, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL5, .value_a = 0x0043, .value_g = 0x0043, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL6, .value_a = 0x0047, .value_g = 0x0047, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL7, .value_a = 0x000C, .value_g = 0x000C, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL8, .value_a = 0x0011, .value_g = 0x0011, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL9, .value_a = 0x0011, .value_g = 0x0011, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL10, .value_a = 0x000E, .value_g = 0x000E, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL11, .value_a = 0x0008, .value_g = 0x0008, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL12, .value_a = 0x0033, .value_g = 0x0033, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL13, .value_a = 0x000A, .value_g = 0x000A, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL14, .value_a = 0x0006, .value_g = 0x0006, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_RFPLL_CTL15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RFPLL_CTL16, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RFPLL_CTL17, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_RFPLL_CTL18, .value_a = 0x003E, .value_g = 0x003E, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL19, .value_a = 0x0013, .value_g = 0x0013, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL18, .value_a = 0x003E, .value_g = 0x003E, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL19, .value_a = 0x0013, .value_g = 0x0013, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_RFPLL_CTL20, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_RFPLL_CTL21, .value_a = 0x0062, .value_g = 0x0062, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL22, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL23, .value_a = 0x0016, .value_g = 0x0016, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL24, .value_a = 0x005C, .value_g = 0x005C, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL25, .value_a = 0x0095, .value_g = 0x0095, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL21, .value_a = 0x0062, .value_g = 0x0062, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL22, .value_a = 0x0007, .value_g = 0x0007, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL23, .value_a = 0x0016, .value_g = 0x0016, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL24, .value_a = 0x005C, .value_g = 0x005C, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL25, .value_a = 0x0095, .value_g = 0x0095, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_RFPLL_CTL26, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RFPLL_CTL27, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RFPLL_CTL28, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RFPLL_CTL29, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_RFPLL_CTL30, .value_a = 0x00A0, .value_g = 0x00A0, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL31, .value_a = 0x0004, .value_g = 0x0004, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL30, .value_a = 0x00A0, .value_g = 0x00A0, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL31, .value_a = 0x0004, .value_g = 0x0004, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_RFPLL_CTL32, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
-	{ .offset = B2062_S_RFPLL_CTL33, .value_a = 0x00CC, .value_g = 0x00CC, .flags = B2062_FLAG_A | B2062_FLAG_G, },
-	{ .offset = B2062_S_RFPLL_CTL34, .value_a = 0x0007, .value_g = 0x0007, .flags = B2062_FLAG_A | B2062_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL33, .value_a = 0x00CC, .value_g = 0x00CC, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2062_S_RFPLL_CTL34, .value_a = 0x0007, .value_g = 0x0007, .flags = B206X_FLAG_A | B206X_FLAG_G, },
 	/* { .offset = B2062_S_RXG_CNT0, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
 	/* { .offset = B2062_S_RXG_CNT1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RXG_CNT2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
@@ -241,7 +242,7 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_S_RXG_CNT5, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
 	/* { .offset = B2062_S_RXG_CNT6, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
 	/* { .offset = B2062_S_RXG_CNT7, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
-	{ .offset = B2062_S_RXG_CNT8, .value_a = 0x000F, .value_g = 0x000F, .flags = B2062_FLAG_A, },
+	{ .offset = B2062_S_RXG_CNT8, .value_a = 0x000F, .value_g = 0x000F, .flags = B206X_FLAG_A, },
 	/* { .offset = B2062_S_RXG_CNT9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
 	/* { .offset = B2062_S_RXG_CNT10, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
 	/* { .offset = B2062_S_RXG_CNT11, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
@@ -253,19 +254,337 @@ static const struct b2062_init_tab_entry b2062_init_tab[] = {
 	/* { .offset = B2062_S_RXG_CNT17, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
 };
 
+static const struct b206x_init_tab_entry b2063_init_tab[] = {
+	{ .offset = B2063_COMM1, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	/* { .offset = B2063_COMM2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_COMM10, .value_a = 0x0001, .value_g = 0x0000, .flags = B206X_FLAG_A, },
+	/* { .offset = B2063_COMM11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_COMM14, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+	/* { .offset = B2063_COMM15, .value_a = 0x000f, .value_g = 0x000f, .flags = 0, }, */
+	{ .offset = B2063_COMM16, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM17, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM18, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM19, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM20, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM21, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM22, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM23, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_COMM24, .value_a = 0x0000, .value_g = 0x0000, .flags = B206X_FLAG_G, },
+	/* { .offset = B2063_PWR_SWITCH_CTL, .value_a = 0x007f, .value_g = 0x007f, .flags = 0, }, */
+	/* { .offset = B2063_PLL_SP1, .value_a = 0x003f, .value_g = 0x003f, .flags = 0, }, */
+	/* { .offset = B2063_PLL_SP2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_LOGEN_SP1, .value_a = 0x00e8, .value_g = 0x00d4, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2063_LOGEN_SP2, .value_a = 0x00a7, .value_g = 0x0053, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_LOGEN_SP3, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	{ .offset = B2063_LOGEN_SP4, .value_a = 0x00f0, .value_g = 0x000f, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_LOGEN_SP5, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	{ .offset = B2063_G_RX_SP1, .value_a = 0x001f, .value_g = 0x005e, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_G_RX_SP2, .value_a = 0x007f, .value_g = 0x007e, .flags = B206X_FLAG_G, },
+	{ .offset = B2063_G_RX_SP3, .value_a = 0x0030, .value_g = 0x00f0, .flags = B206X_FLAG_G, },
+	/* { .offset = B2063_G_RX_SP4, .value_a = 0x0035, .value_g = 0x0035, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_SP5, .value_a = 0x003f, .value_g = 0x003f, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_SP6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_G_RX_SP7, .value_a = 0x007f, .value_g = 0x007f, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_G_RX_SP8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_SP9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_G_RX_SP10, .value_a = 0x000c, .value_g = 0x000c, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_G_RX_SP11, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_A_RX_SP1, .value_a = 0x003c, .value_g = 0x003f, .flags = B206X_FLAG_A, },
+	{ .offset = B2063_A_RX_SP2, .value_a = 0x00fc, .value_g = 0x00fe, .flags = B206X_FLAG_A, },
+	/* { .offset = B2063_A_RX_SP3, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_SP4, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_SP5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_SP6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_A_RX_SP7, .value_a = 0x0008, .value_g = 0x0008, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_RX_BB_SP1, .value_a = 0x000f, .value_g = 0x000f, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_SP2, .value_a = 0x0022, .value_g = 0x0022, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_SP3, .value_a = 0x00a8, .value_g = 0x00a8, .flags = 0, }, */
+	{ .offset = B2063_RX_BB_SP4, .value_a = 0x0060, .value_g = 0x0060, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_RX_BB_SP5, .value_a = 0x0011, .value_g = 0x0011, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_SP6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_SP7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_RX_BB_SP8, .value_a = 0x0030, .value_g = 0x0030, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_TX_RF_SP1, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP2, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+	{ .offset = B2063_TX_RF_SP3, .value_a = 0x000c, .value_g = 0x000b, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2063_TX_RF_SP4, .value_a = 0x0010, .value_g = 0x000f, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_TX_RF_SP5, .value_a = 0x000f, .value_g = 0x000f, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP6, .value_a = 0x0080, .value_g = 0x0080, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP7, .value_a = 0x0068, .value_g = 0x0068, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP8, .value_a = 0x0068, .value_g = 0x0068, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP9, .value_a = 0x0080, .value_g = 0x0080, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP10, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP11, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP12, .value_a = 0x0038, .value_g = 0x0038, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP13, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP14, .value_a = 0x0038, .value_g = 0x0038, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP15, .value_a = 0x00c0, .value_g = 0x00c0, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP16, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_SP17, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	{ .offset = B2063_PA_SP1, .value_a = 0x003d, .value_g = 0x00fd, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_PA_SP2, .value_a = 0x000c, .value_g = 0x000c, .flags = 0, }, */
+	/* { .offset = B2063_PA_SP3, .value_a = 0x0096, .value_g = 0x0096, .flags = 0, }, */
+	/* { .offset = B2063_PA_SP4, .value_a = 0x005a, .value_g = 0x005a, .flags = 0, }, */
+	/* { .offset = B2063_PA_SP5, .value_a = 0x007f, .value_g = 0x007f, .flags = 0, }, */
+	/* { .offset = B2063_PA_SP6, .value_a = 0x007f, .value_g = 0x007f, .flags = 0, }, */
+	/* { .offset = B2063_PA_SP7, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	{ .offset = B2063_TX_BB_SP1, .value_a = 0x0002, .value_g = 0x0002, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_TX_BB_SP2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_TX_BB_SP3, .value_a = 0x0030, .value_g = 0x0030, .flags = 0, }, */
+	/* { .offset = B2063_REG_SP1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_BANDGAP_CTL1, .value_a = 0x0056, .value_g = 0x0056, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_BANDGAP_CTL2, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+	/* { .offset = B2063_LPO_CTL1, .value_a = 0x000e, .value_g = 0x000e, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL1, .value_a = 0x007e, .value_g = 0x007e, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL2, .value_a = 0x0015, .value_g = 0x0015, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL3, .value_a = 0x000f, .value_g = 0x000f, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RC_CALIB_CTL10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_CALNRST, .value_a = 0x0004, .value_g = 0x0004, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_IN_PLL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_IN_PLL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_CP1, .value_a = 0x00cf, .value_g = 0x00cf, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_CP2, .value_a = 0x0059, .value_g = 0x0059, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_CP3, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_CP4, .value_a = 0x0042, .value_g = 0x0042, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_LF1, .value_a = 0x00db, .value_g = 0x00db, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_LF2, .value_a = 0x0094, .value_g = 0x0094, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_LF3, .value_a = 0x0028, .value_g = 0x0028, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_LF4, .value_a = 0x0063, .value_g = 0x0063, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_SG1, .value_a = 0x0007, .value_g = 0x0007, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_SG2, .value_a = 0x00d3, .value_g = 0x00d3, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_SG3, .value_a = 0x00b1, .value_g = 0x00b1, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_SG4, .value_a = 0x003b, .value_g = 0x003b, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_SG5, .value_a = 0x0006, .value_g = 0x0006, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO1, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
+	{ .offset = B2063_PLL_JTAG_PLL_VCO2, .value_a = 0x00f7, .value_g = 0x00f7, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB3, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB5, .value_a = 0x0009, .value_g = 0x0009, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB6, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB7, .value_a = 0x0016, .value_g = 0x0016, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB8, .value_a = 0x006b, .value_g = 0x006b, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_VCO_CALIB10, .value_a = 0x00b3, .value_g = 0x00b3, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_XTAL_12, .value_a = 0x0004, .value_g = 0x0004, .flags = 0, }, */
+	/* { .offset = B2063_PLL_JTAG_PLL_XTAL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_ACL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_ACL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_ACL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_ACL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_ACL5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_INPUTS, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_WAITCNT, .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVR1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVR2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVAL1, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVAL2, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVAL3, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVAL4, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVAL5, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVAL6, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_OVAL7, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CALVLD1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CALVLD2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CVAL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CVAL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CVAL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CVAL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CVAL5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CVAL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LO_CALIB_CVAL7, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_CALIB_EN, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_PEAKDET1, .value_a = 0x00ff, .value_g = 0x00ff, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_RCCR1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_VCOBUF1, .value_a = 0x0060, .value_g = 0x0060, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_MIXER1, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_MIXER2, .value_a = 0x000c, .value_g = 0x000c, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_BUF1, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_BUF2, .value_a = 0x000c, .value_g = 0x000c, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_DIV1, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_DIV2, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_DIV3, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_CBUFRX1, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_CBUFRX2, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_CBUFTX1, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_CBUFTX2, .value_a = 0x0066, .value_g = 0x0066, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_IDAC1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_SPARE1, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_SPARE2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_LOGEN_SPARE3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_1ST1, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_1ST2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_1ST3, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND1, .value_a = 0x0030, .value_g = 0x0030, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND2, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND3, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND5, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND7, .value_a = 0x0035, .value_g = 0x0035, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_2ND8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_PS1, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_PS2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_PS3, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_PS4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_PS5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_MIX1, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_MIX2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_G_RX_MIX3, .value_a = 0x0071, .value_g = 0x0071, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2063_G_RX_MIX4, .value_a = 0x0071, .value_g = 0x0071, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_G_RX_MIX5, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_MIX6, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_MIX7, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_MIX8, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_PDET1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_SPARES1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_SPARES2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_G_RX_SPARES3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_1ST1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_A_RX_1ST2, .value_a = 0x00f0, .value_g = 0x0030, .flags = B206X_FLAG_A, },
+	/* { .offset = B2063_A_RX_1ST3, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_1ST4, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_1ST5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_2ND1, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_2ND2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_2ND3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_2ND4, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_2ND5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_2ND6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_2ND7, .value_a = 0x0005, .value_g = 0x0005, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_PS1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_PS2, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_PS3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_PS4, .value_a = 0x0033, .value_g = 0x0033, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_PS5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_A_RX_PS6, .value_a = 0x0077, .value_g = 0x0077, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_A_RX_MIX1, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_MIX2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_MIX3, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+	{ .offset = B2063_A_RX_MIX4, .value_a = 0x0003, .value_g = 0x0003, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2063_A_RX_MIX5, .value_a = 0x000f, .value_g = 0x000f, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	{ .offset = B2063_A_RX_MIX6, .value_a = 0x000f, .value_g = 0x000f, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_A_RX_MIX7, .value_a = 0x0044, .value_g = 0x0044, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_MIX8, .value_a = 0x0001, .value_g = 0x0001, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_PWRDET1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_SPARE1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_SPARE2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_A_RX_SPARE3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_RX_TIA_CTL1, .value_a = 0x0077, .value_g = 0x0077, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_RX_TIA_CTL2, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
+	{ .offset = B2063_RX_TIA_CTL3, .value_a = 0x0077, .value_g = 0x0077, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_RX_TIA_CTL4, .value_a = 0x0058, .value_g = 0x0058, .flags = 0, }, */
+	/* { .offset = B2063_RX_TIA_CTL5, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RX_TIA_CTL6, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_CTL1, .value_a = 0x0074, .value_g = 0x0074, .flags = 0, }, */
+	{ .offset = B2063_RX_BB_CTL2, .value_a = 0x0004, .value_g = 0x0004, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_RX_BB_CTL3, .value_a = 0x00a2, .value_g = 0x00a2, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_CTL4, .value_a = 0x00aa, .value_g = 0x00aa, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_CTL5, .value_a = 0x0024, .value_g = 0x0024, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_CTL6, .value_a = 0x00a9, .value_g = 0x00a9, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_CTL7, .value_a = 0x0028, .value_g = 0x0028, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_CTL8, .value_a = 0x0010, .value_g = 0x0010, .flags = 0, }, */
+	/* { .offset = B2063_RX_BB_CTL9, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL1, .value_a = 0x0080, .value_g = 0x0080, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_IDAC_LO_RF_I, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_IDAC_LO_RF_Q, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_IDAC_LO_BB_I, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_IDAC_LO_BB_Q, .value_a = 0x0088, .value_g = 0x0088, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL2, .value_a = 0x0080, .value_g = 0x0080, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL3, .value_a = 0x0038, .value_g = 0x0038, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL4, .value_a = 0x00b8, .value_g = 0x00b8, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL5, .value_a = 0x0080, .value_g = 0x0080, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL6, .value_a = 0x0038, .value_g = 0x0038, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL7, .value_a = 0x0078, .value_g = 0x0078, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL8, .value_a = 0x00c0, .value_g = 0x00c0, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL9, .value_a = 0x0003, .value_g = 0x0003, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL10, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL14, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_TX_RF_CTL15, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_PA_CTL1, .value_a = 0x0000, .value_g = 0x0004, .flags = B206X_FLAG_A, },
+	/* { .offset = B2063_PA_CTL2, .value_a = 0x000c, .value_g = 0x000c, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL3, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL4, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL5, .value_a = 0x0096, .value_g = 0x0096, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL6, .value_a = 0x0077, .value_g = 0x0077, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL7, .value_a = 0x005a, .value_g = 0x005a, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL8, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL9, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL10, .value_a = 0x0021, .value_g = 0x0021, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL11, .value_a = 0x0070, .value_g = 0x0070, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL12, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_PA_CTL13, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_TX_BB_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_TX_BB_CTL2, .value_a = 0x00b3, .value_g = 0x00b3, .flags = 0, }, */
+	/* { .offset = B2063_TX_BB_CTL3, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2063_TX_BB_CTL4, .value_a = 0x000b, .value_g = 0x000b, .flags = 0, }, */
+	/* { .offset = B2063_GPIO_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	{ .offset = B2063_VREG_CTL1, .value_a = 0x0003, .value_g = 0x0003, .flags = B206X_FLAG_A | B206X_FLAG_G, },
+	/* { .offset = B2063_AMUX_CTL1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_IQ_CALIB_GVAR, .value_a = 0x00b3, .value_g = 0x00b3, .flags = 0, }, */
+	/* { .offset = B2063_IQ_CALIB_CTL1, .value_a = 0x0055, .value_g = 0x0055, .flags = 0, }, */
+	/* { .offset = B2063_IQ_CALIB_CTL2, .value_a = 0x0030, .value_g = 0x0030, .flags = 0, }, */
+	/* { .offset = B2063_TEMPSENSE_CTL1, .value_a = 0x0046, .value_g = 0x0046, .flags = 0, }, */
+	/* { .offset = B2063_TEMPSENSE_CTL2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_TX_RX_LOOPBACK1, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_TX_RX_LOOPBACK2, .value_a = 0x0000, .value_g = 0x0000, .flags = 0, }, */
+	/* { .offset = B2063_EXT_TSSI_CTL1, .value_a = 0x0021, .value_g = 0x0021, .flags = 0, }, */
+	/* { .offset = B2063_EXT_TSSI_CTL2, .value_a = 0x0023, .value_g = 0x0023, .flags = 0, }, */
+	/* { .offset = B2063_AFE_CTL , .value_a = 0x0002, .value_g = 0x0002, .flags = 0, }, */
+};
+
 void b2062_upload_init_table(struct b43_wldev *dev)
 {
-	const struct b2062_init_tab_entry *e;
+	const struct b206x_init_tab_entry *e;
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(b2062_init_tab); i++) {
 		e = &b2062_init_tab[i];
 		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
-			if (!(e->flags & B2062_FLAG_G))
+			if (!(e->flags & B206X_FLAG_G))
 				continue;
 			b43_radio_write(dev, e->offset, e->value_g);
 		} else {
-			if (!(e->flags & B2062_FLAG_A))
+			if (!(e->flags & B206X_FLAG_A))
+				continue;
+			b43_radio_write(dev, e->offset, e->value_a);
+		}
+	}
+}
+
+void b2063_upload_init_table(struct b43_wldev *dev)
+{
+	const struct b206x_init_tab_entry *e;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(b2063_init_tab); i++) {
+		e = &b2063_init_tab[i];
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+			if (!(e->flags & B206X_FLAG_G))
+				continue;
+			b43_radio_write(dev, e->offset, e->value_g);
+		} else {
+			if (!(e->flags & B206X_FLAG_A))
 				continue;
 			b43_radio_write(dev, e->offset, e->value_a);
 		}
@@ -306,30 +625,35 @@ u32 b43_lptab_read(struct b43_wldev *dev, u32 offset)
 void b43_lptab_read_bulk(struct b43_wldev *dev, u32 offset,
 			 unsigned int nr_elements, void *_data)
 {
-	u32 type, value;
+	u32 type;
 	u8 *data = _data;
 	unsigned int i;
 
 	type = offset & B43_LPTAB_TYPEMASK;
+	offset &= ~B43_LPTAB_TYPEMASK;
+	B43_WARN_ON(offset > 0xFFFF);
+
+	b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+
 	for (i = 0; i < nr_elements; i++) {
-		value = b43_lptab_read(dev, offset);
 		switch (type) {
 		case B43_LPTAB_8BIT:
-			*data = value;
+			*data = b43_phy_read(dev, B43_LPPHY_TABLEDATALO) & 0xFF;
 			data++;
 			break;
 		case B43_LPTAB_16BIT:
-			*((u16 *)data) = value;
+			*((u16 *)data) = b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
 			data += 2;
 			break;
 		case B43_LPTAB_32BIT:
-			*((u32 *)data) = value;
+			*((u32 *)data) = b43_phy_read(dev, B43_LPPHY_TABLEDATAHI);
+			*((u32 *)data) <<= 16;
+			*((u32 *)data) |= b43_phy_read(dev, B43_LPPHY_TABLEDATALO);
 			data += 4;
 			break;
 		default:
 			B43_WARN_ON(1);
 		}
-		offset++;
 	}
 }
 
@@ -370,25 +694,1764 @@ void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
 	unsigned int i;
 
 	type = offset & B43_LPTAB_TYPEMASK;
+	offset &= ~B43_LPTAB_TYPEMASK;
+	B43_WARN_ON(offset > 0xFFFF);
+
+	b43_phy_write(dev, B43_LPPHY_TABLE_ADDR, offset);
+
 	for (i = 0; i < nr_elements; i++) {
 		switch (type) {
 		case B43_LPTAB_8BIT:
 			value = *data;
 			data++;
+			B43_WARN_ON(value & ~0xFF);
+			b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
 			break;
 		case B43_LPTAB_16BIT:
 			value = *((u16 *)data);
 			data += 2;
+			B43_WARN_ON(value & ~0xFFFF);
+			b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
 			break;
 		case B43_LPTAB_32BIT:
 			value = *((u32 *)data);
 			data += 4;
+			b43_phy_write(dev, B43_LPPHY_TABLEDATAHI, value >> 16);
+			b43_phy_write(dev, B43_LPPHY_TABLEDATALO, value);
 			break;
 		default:
 			B43_WARN_ON(1);
-			value = 0;
 		}
-		b43_lptab_write(dev, offset, value);
-		offset++;
+	}
+}
+
+static const u8 lpphy_min_sig_sq_table[] = {
+	0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
+	0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
+	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
+	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
+	0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
+	0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
+};
+
+static const u16 lpphy_rev01_noise_scale_table[] = {
+	0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
+	0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
+	0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0x00a4,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c00, 0x2d36,
+	0x0000, 0x0000, 0x4c00, 0x2d36,
+};
+
+static const u16 lpphy_rev2plus_noise_scale_table[] = {
+	0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
+	0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
+	0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x0000,
+	0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
+	0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
+	0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
+	0x00a4,
+};
+
+static const u16 lpphy_crs_gain_nft_table[] = {
+	0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f, 0x036f,
+	0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381, 0x0374, 0x0381,
+	0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f, 0x0040, 0x005e, 0x007f,
+	0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d, 0x013d,
+};
+
+static const u16 lpphy_rev01_filter_control_table[] = {
+	0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077, 0xff53,
+	0x0127,
+};
+
+static const u32 lpphy_rev2plus_filter_control_table[] = {
+	0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27, 0x0000217f,
+	0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f,
+};
+
+static const u32 lpphy_rev01_ps_control_table[] = {
+	0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101, 0x00000080,
+	0x08080101, 0x00000040, 0x08080101, 0x000000c0, 0x08a81501, 0x000000c0,
+	0x0fe8fd01, 0x000000c0, 0x08300105, 0x000000c0, 0x08080201, 0x000000c0,
+	0x08280205, 0x000000c0, 0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0,
+	0x08080202, 0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
+	0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106, 0x000000c0,
+	0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
+};
+
+static const u32 lpphy_rev2plus_ps_control_table[] = {
+	0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000, 0x00002080,
+	0x00006180, 0x00003002, 0x00000040, 0x00002042, 0x00180047, 0x00080043,
+	0x00000041, 0x000020c1, 0x00046006, 0x00042002, 0x00040000, 0x00002003,
+	0x00180006, 0x00080002,
+};
+
+static const u8 lpphy_pll_fraction_table[] = {
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
+	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+};
+
+static const u16 lpphy_iqlo_cal_table[] = {
+	0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
+	0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
+	0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
+	0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static const u16 lpphy_rev0_ofdm_cck_gain_table[] = {
+	0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 0x5001,
+	0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 0x2065, 0x2075,
+	0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 0x135d, 0x055d, 0x155d,
+	0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 0x755d,
+};
+
+static const u16 lpphy_rev1_ofdm_cck_gain_table[] = {
+	0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001, 0x5001,
+	0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055, 0x2065, 0x2075,
+	0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d, 0x135d, 0x055d, 0x155d,
+	0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d, 0x755d,
+};
+
+static const u16 lpphy_gain_delta_table[] = {
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static const u32 lpphy_tx_power_control_table[] = {
+	0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c, 0x0000004b,
+	0x0000004a, 0x00000049, 0x00000048, 0x00000047, 0x00000046, 0x00000045,
+	0x00000044, 0x00000043, 0x00000042, 0x00000041, 0x00000040, 0x0000003f,
+	0x0000003e, 0x0000003d, 0x0000003c, 0x0000003b, 0x0000003a, 0x00000039,
+	0x00000038, 0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
+	0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e, 0x0000002d,
+	0x0000002c, 0x0000002b, 0x0000002a, 0x00000029, 0x00000028, 0x00000027,
+	0x00000026, 0x00000025, 0x00000024, 0x00000023, 0x00000022, 0x00000021,
+	0x00000020, 0x0000001f, 0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b,
+	0x0000001a, 0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
+	0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x000075a0, 0x000075a0, 0x000075a1, 0x000075a1, 0x000075a2, 0x000075a2,
+	0x000075a3, 0x000075a3, 0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1,
+	0x000074b2, 0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
+	0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23, 0x00006d23,
+	0x00004660, 0x00004660, 0x00004661, 0x00004661, 0x00004662, 0x00004662,
+	0x00004663, 0x00004663, 0x00003e60, 0x00003e60, 0x00003e61, 0x00003e61,
+	0x00003e62, 0x00003e62, 0x00003e63, 0x00003e63, 0x00003660, 0x00003660,
+	0x00003661, 0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
+	0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62, 0x00002e62,
+	0x00002e63, 0x00002e63, 0x00002660, 0x00002660, 0x00002661, 0x00002661,
+	0x00002662, 0x00002662, 0x00002663, 0x00002663, 0x000025e0, 0x000025e0,
+	0x000025e1, 0x000025e1, 0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3,
+	0x00001de0, 0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
+	0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61, 0x00001d61,
+	0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63, 0x00001560, 0x00001560,
+	0x00001561, 0x00001561, 0x00001562, 0x00001562, 0x00001563, 0x00001563,
+	0x00000d60, 0x00000d60, 0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62,
+	0x00000d63, 0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
+	0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10, 0x00000e10,
+	0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12, 0x00000e13, 0x00000e13,
+	0x00000bf0, 0x00000bf0, 0x00000bf1, 0x00000bf1, 0x00000bf2, 0x00000bf2,
+	0x00000bf3, 0x00000bf3, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
+	0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
+	0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04, 0x0000fcff,
+	0x000005fb, 0x0000fd01, 0x00000401, 0x00000006, 0x0000ff03, 0x000007fc,
+	0x0000fc08, 0x00000203, 0x0000fffb, 0x00000600, 0x0000fa01, 0x0000fc03,
+	0x0000fe06, 0x0000fe00, 0x00000102, 0x000007fd, 0x000004fb, 0x000006ff,
+	0x000004fd, 0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
+	0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa, 0x00000700,
+	0x00000305, 0x000004ff, 0x00000801, 0x00000503, 0x000005f9, 0x00000404,
+	0x0000fb08, 0x000005fd, 0x00000501, 0x00000405, 0x0000fb03, 0x000007fc,
+	0x00000403, 0x00000303, 0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd,
+	0x0000fe01, 0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
+	0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa, 0x000003fe,
+	0x00000304, 0x000004f9, 0x00000100, 0x0000fd06, 0x000008fc, 0x00000701,
+	0x00000504, 0x0000fdfe, 0x0000fdfc, 0x000003fe, 0x00000704, 0x000002fc,
+	0x000004f9, 0x0000fdfd, 0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb,
+	0x000004f9, 0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
+	0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa, 0x00000305,
+	0x000008fc, 0x00000102, 0x000001fd, 0x000004fc, 0x0000fe03, 0x00000701,
+	0x000001fb, 0x000001f9, 0x00000206, 0x000006fd, 0x00000508, 0x00000700,
+	0x00000304, 0x000005fe, 0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb,
+	0x000007f9, 0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
+	0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb, 0x00000702,
+};
+
+static const u32 lpphy_gain_idx_table[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x10000001, 0x00000000, 0x20000082, 0x00000000, 0x40000104, 0x00000000,
+	0x60004207, 0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
+	0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
+	0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711, 0x00000001,
+	0xb0a18612, 0x00000010, 0xe1024794, 0x00000010, 0x11630915, 0x00000011,
+	0x31c3ca1b, 0x00000011, 0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018,
+	0x22468e21, 0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
+	0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
+	0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c, 0x0000001a,
+	0x64ca55ad, 0x0000001a, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082, 0x00000000,
+	0x40000104, 0x00000000, 0x60004207, 0x00000001, 0x7000838a, 0x00000001,
+	0xd021050d, 0x00000001, 0xe041c683, 0x00000001, 0x50828805, 0x00000000,
+	0x80e34288, 0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
+	0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
+	0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c, 0x00000018,
+	0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019, 0x4286d023, 0x00000019,
+	0xa347d0a4, 0x00000019, 0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019,
+	0x0408d329, 0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
+	0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a,
+};
+
+static const u16 lpphy_aux_gain_idx_table[] = {
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0016,
+};
+
+static const u32 lpphy_gain_value_table[] = {
+	0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 0x00000004,
+	0x00000008, 0x0000000d, 0x00000001, 0x00000004, 0x00000007, 0x0000000a,
+	0x0000000d, 0x00000010, 0x00000012, 0x00000015, 0x00000000, 0x00000006,
+	0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000012, 0x00000000,
+	0x00000000, 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x0000001e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000003, 0x00000006, 0x00000009, 0x0000000c, 0x0000000f,
+	0x00000012, 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 0x000000f1,
+	0x00000000, 0x00000000,
+};
+
+static const u16 lpphy_gain_table[] = {
+	0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808, 0x080a,
+	0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813, 0x0814, 0x0816,
+	0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824, 0x0830, 0x0834, 0x0837,
+	0x083b, 0x083f, 0x0840, 0x0844, 0x0857, 0x085b, 0x085f, 0x08d7, 0x08db,
+	0x08df, 0x0957, 0x095b, 0x095f, 0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f,
+	0x175f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static const u32 lpphy_a0_gain_idx_table[] = {
+	0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 0x00511065,
+	0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 0x003ca087, 0x0039408f,
+	0x0035e098, 0x0032e0a1, 0x003030aa, 0x002d80b4, 0x002ae0bf, 0x002880ca,
+	0x002640d6, 0x002410e3, 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e,
+	0x001b012f, 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
+	0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 0x000e523a,
+	0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 0x000ac2f8, 0x000a2325,
+	0x00099355, 0x00091387, 0x000883bd, 0x000813f5, 0x0007a432, 0x00073471,
+	0x0006c4b5, 0x000664fc, 0x00061547, 0x0005b598, 0x000565ec, 0x00051646,
+	0x0004d6a5, 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
+	0x00036963, 0x000339f2, 0x00030a89, 0x0002db28,
+};
+
+static const u16 lpphy_a0_aux_gain_idx_table[] = {
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0002, 0x0014,
+};
+
+static const u32 lpphy_a0_gain_value_table[] = {
+	0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb, 0x00000004,
+	0x00000008, 0x0000000d, 0x00000001, 0x00000004, 0x00000007, 0x0000000a,
+	0x0000000d, 0x00000010, 0x00000012, 0x00000015, 0x00000000, 0x00000006,
+	0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000012, 0x00000000,
+	0x00000000, 0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x0000001e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000003, 0x00000006, 0x00000009, 0x0000000c, 0x0000000f,
+	0x00000012, 0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x000000f7,
+	0x00000000, 0x00000000,
+};
+
+static const u16 lpphy_a0_gain_table[] = {
+	0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b, 0x000c,
+	0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016, 0x0017, 0x001a,
+	0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034, 0x0037, 0x003b, 0x003f,
+	0x0040, 0x0044, 0x0057, 0x005b, 0x005f, 0x00d7, 0x00db, 0x00df, 0x0157,
+	0x015b, 0x015f, 0x0357, 0x035b, 0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static const u16 lpphy_sw_control_table[] = {
+	0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 0x0128,
+	0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028, 0x0009, 0x0009,
+	0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0018, 0x0018, 0x0018,
+	0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0128, 0x0128, 0x0009, 0x0009,
+	0x0028, 0x0028, 0x0028, 0x0028, 0x0128, 0x0128, 0x0009, 0x0009, 0x0028,
+	0x0028, 0x0028, 0x0028, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
+	0x0009, 0x0009, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
+	0x0018,
+};
+
+static const u8 lpphy_hf_table[] = {
+	0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
+	0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17,
+};
+
+static const u32 lpphy_papd_eps_table[] = {
+	0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9, 0x00021fdf,
+	0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7, 0x0004efc2, 0x00055fb5,
+	0x0005cfb0, 0x00063fa8, 0x00068fa3, 0x00071f98, 0x0007ef92, 0x00084f8b,
+	0x0008df82, 0x00097f77, 0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c,
+	0x000bff41, 0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
+	0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15, 0x00143f1c,
+	0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f, 0x001e6f7e, 0x0021cfa4,
+	0x0025bfd2, 0x002a2008, 0x002fb047, 0x00360090, 0x003d40e0, 0x0045c135,
+	0x004fb189, 0x005ae1d7, 0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf,
+	0x007ff2e3, 0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
+	0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506,
+};
+
+static const u32 lpphy_papd_mult_table[] = {
+	0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060, 0x00511065,
+	0x004c806b, 0x0047d072, 0x00444078, 0x00400080, 0x003ca087, 0x0039408f,
+	0x0035e098, 0x0032e0a1, 0x003030aa, 0x002d80b4, 0x002ae0bf, 0x002880ca,
+	0x002640d6, 0x002410e3, 0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e,
+	0x001b012f, 0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
+	0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a, 0x000e523a,
+	0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd, 0x000ac2f8, 0x000a2325,
+	0x00099355, 0x00091387, 0x000883bd, 0x000813f5, 0x0007a432, 0x00073471,
+	0x0006c4b5, 0x000664fc, 0x00061547, 0x0005b598, 0x000565ec, 0x00051646,
+	0x0004d6a5, 0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
+	0x00036963, 0x000339f2, 0x00030a89, 0x0002db28,
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev0_nopa_tx_gain_table[] = {
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 152, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 147, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 143, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 139, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 135, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 131, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 128, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 124, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 121, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 117, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 114, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 111, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 107, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 104, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 101, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 99, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 96, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 93, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 90, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 88, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 85, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 83, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 81, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 78, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 76, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 74, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 73, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 73, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev0_2ghz_tx_gain_table[] = {
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 73, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 71, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 69, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 67, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 73, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 69, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 67, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 10, .pad = 5, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 9, .pad = 5, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 71, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 69, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 67, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 9, .pad = 4, .dac = 0, .bb_mult = 58, },
+	{ .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 8, .pad = 4, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 7, .pad = 4, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 67, },
+	{ .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 7, .pad = 3, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 6, .pad = 3, .dac = 0, .bb_mult = 58, },
+	{ .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 5, .pad = 3, .dac = 0, .bb_mult = 57, },
+	{ .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 83, },
+	{ .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 81, },
+	{ .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 78, },
+	{ .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 76, },
+	{ .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 74, },
+	{ .gm = 4, .pga = 4, .pad = 2, .dac = 0, .bb_mult = 72, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev0_5ghz_tx_gain_table[] = {
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 99, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 96, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 93, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 90, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 88, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 85, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 83, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 81, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 78, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 76, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 74, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 55, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 55, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 73, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev1_nopa_tx_gain_table[] = {
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 152, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 147, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 143, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 139, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 135, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 131, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 128, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 124, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 121, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 117, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 114, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 111, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 107, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 104, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 101, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 99, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 96, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 93, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 90, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 88, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 85, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 83, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 81, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 78, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 76, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 74, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 73, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 73, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev1_2ghz_tx_gain_table[] = {
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 90, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 88, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 85, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 83, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 81, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 78, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 76, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 74, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 73, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 71, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 69, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 67, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 73, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 71, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 69, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 67, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 65, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 63, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 61, },
+	{ .gm = 4, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 72, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 70, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 68, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 66, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 64, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 62, },
+	{ .gm = 4, .pga = 10, .pad = 6, .dac = 0, .bb_mult = 60, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev1_5ghz_tx_gain_table[] = {
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 99, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 96, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 93, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 90, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 88, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 85, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 83, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 81, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 78, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 76, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 74, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 15, .dac = 0, .bb_mult = 55, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 15, .pad = 14, .dac = 0, .bb_mult = 55, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 13, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 72, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 12, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 73, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 11, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 71, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 15, .pad = 10, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 15, .pad = 9, .dac = 0, .bb_mult = 56, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 14, .pad = 9, .dac = 0, .bb_mult = 58, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 9, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 60, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 13, .pad = 8, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 8, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 12, .pad = 7, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 70, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 68, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 66, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 61, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 59, },
+	{ .gm = 7, .pga = 11, .pad = 7, .dac = 0, .bb_mult = 57, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 69, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 67, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 65, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 63, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 62, },
+	{ .gm = 7, .pga = 11, .pad = 6, .dac = 0, .bb_mult = 60, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev2_nopa_tx_gain_table[] = {
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 152, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 147, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 143, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 139, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 135, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 131, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 128, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 124, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 121, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 117, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 114, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 111, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 107, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 104, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 101, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 99, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 96, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 93, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 90, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 88, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 85, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 83, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 81, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 78, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 76, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 74, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 72, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 70, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 68, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 66, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 197, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 192, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 186, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 181, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 176, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 171, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 166, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 161, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 157, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 152, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 148, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 144, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 140, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 136, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 132, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 128, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 124, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 121, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 117, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 114, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 111, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 108, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 105, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 102, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 99, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 96, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 93, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 91, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 88, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 86, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 83, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 81, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 79, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 76, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 74, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 72, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 70, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 68, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 66, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 64, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 248, .pad = 64, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 248, .pad = 62, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 241, .pad = 62, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 241, .pad = 60, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 234, .pad = 60, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 234, .pad = 59, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 227, .pad = 59, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 227, .pad = 57, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 221, .pad = 57, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 221, .pad = 55, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 215, .pad = 55, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 215, .pad = 54, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 208, .pad = 54, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 208, .pad = 52, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 203, .pad = 52, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 203, .pad = 51, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 197, .pad = 51, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 197, .pad = 49, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 191, .pad = 49, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 191, .pad = 48, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 186, .pad = 48, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 186, .pad = 47, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 181, .pad = 47, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 181, .pad = 45, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 175, .pad = 45, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 175, .pad = 44, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 170, .pad = 44, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 170, .pad = 43, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 166, .pad = 43, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 166, .pad = 42, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 161, .pad = 42, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 161, .pad = 40, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 156, .pad = 40, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 156, .pad = 39, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 152, .pad = 39, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 152, .pad = 38, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 148, .pad = 38, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 148, .pad = 37, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 143, .pad = 37, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 143, .pad = 36, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 139, .pad = 36, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 139, .pad = 35, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 135, .pad = 35, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 135, .pad = 34, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 132, .pad = 34, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 132, .pad = 33, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 128, .pad = 33, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 128, .pad = 32, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 124, .pad = 32, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 124, .pad = 31, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 121, .pad = 31, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 121, .pad = 30, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 117, .pad = 30, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 117, .pad = 29, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 114, .pad = 29, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 114, .pad = 29, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 111, .pad = 29, .dac = 0, .bb_mult = 64, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev2_2ghz_tx_gain_table[] = {
+	{ .gm = 7, .pga = 99, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 96, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 93, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 90, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 88, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 85, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 83, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 81, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 78, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 76, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 74, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 72, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 70, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 68, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 66, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 64, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 64, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 62, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 62, .pad = 248, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 60, .pad = 248, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 60, .pad = 241, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 59, .pad = 241, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 59, .pad = 234, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 57, .pad = 234, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 57, .pad = 227, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 55, .pad = 227, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 55, .pad = 221, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 54, .pad = 221, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 54, .pad = 215, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 52, .pad = 215, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 52, .pad = 208, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 51, .pad = 208, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 51, .pad = 203, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 49, .pad = 203, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 49, .pad = 197, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 48, .pad = 197, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 48, .pad = 191, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 47, .pad = 191, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 47, .pad = 186, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 45, .pad = 186, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 45, .pad = 181, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 44, .pad = 181, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 44, .pad = 175, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 43, .pad = 175, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 43, .pad = 170, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 42, .pad = 170, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 42, .pad = 166, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 40, .pad = 166, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 40, .pad = 161, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 39, .pad = 161, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 39, .pad = 156, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 38, .pad = 156, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 38, .pad = 152, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 37, .pad = 152, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 37, .pad = 148, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 36, .pad = 148, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 36, .pad = 143, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 35, .pad = 143, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 35, .pad = 139, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 34, .pad = 139, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 34, .pad = 135, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 33, .pad = 135, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 33, .pad = 132, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 32, .pad = 132, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 32, .pad = 128, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 31, .pad = 128, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 31, .pad = 124, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 30, .pad = 124, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 30, .pad = 121, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 29, .pad = 121, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 29, .pad = 117, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 29, .pad = 117, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 29, .pad = 114, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 28, .pad = 114, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 28, .pad = 111, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 27, .pad = 111, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 27, .pad = 108, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 26, .pad = 108, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 26, .pad = 104, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 25, .pad = 104, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 25, .pad = 102, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 25, .pad = 102, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 25, .pad = 99, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 24, .pad = 99, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 24, .pad = 96, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 23, .pad = 96, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 23, .pad = 93, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 23, .pad = 93, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 23, .pad = 90, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 22, .pad = 90, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 22, .pad = 88, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 21, .pad = 88, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 21, .pad = 85, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 21, .pad = 85, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 21, .pad = 83, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 20, .pad = 83, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 20, .pad = 81, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 20, .pad = 81, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 20, .pad = 78, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 19, .pad = 78, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 19, .pad = 76, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 19, .pad = 76, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 19, .pad = 74, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 18, .pad = 74, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 18, .pad = 72, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 18, .pad = 72, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 18, .pad = 70, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 17, .pad = 70, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 17, .pad = 68, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 17, .pad = 68, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 17, .pad = 66, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 16, .pad = 66, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 16, .pad = 64, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 16, .pad = 64, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 16, .pad = 62, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 62, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 60, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 60, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 15, .pad = 59, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 59, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 57, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 57, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 55, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 55, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 14, .pad = 54, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 54, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 52, .dac = 0, .bb_mult = 64, },
+	{ .gm = 7, .pga = 13, .pad = 52, .dac = 0, .bb_mult = 64, },
+};
+
+static struct lpphy_tx_gain_table_entry lpphy_rev2_5ghz_tx_gain_table[] = {
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 152, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 147, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 143, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 139, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 135, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 131, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 128, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 124, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 121, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 117, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 114, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 111, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 107, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 104, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 101, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 99, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 96, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 93, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 90, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 88, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 85, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 83, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 81, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 78, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 76, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 74, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 72, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 70, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 68, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 66, },
+	{ .gm = 255, .pga = 255, .pad = 255, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 248, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 241, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 234, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 227, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 221, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 215, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 208, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 203, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 197, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 191, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 186, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 181, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 175, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 170, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 166, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 161, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 156, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 152, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 148, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 143, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 139, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 135, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 132, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 128, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 124, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 121, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 117, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 114, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 111, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 108, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 104, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 102, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 99, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 96, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 93, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 90, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 88, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 85, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 83, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 81, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 78, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 76, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 74, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 72, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 70, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 68, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 66, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 64, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 64, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 255, .pad = 62, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 248, .pad = 62, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 248, .pad = 60, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 241, .pad = 60, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 241, .pad = 59, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 234, .pad = 59, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 234, .pad = 57, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 227, .pad = 57, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 227, .pad = 55, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 221, .pad = 55, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 221, .pad = 54, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 215, .pad = 54, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 215, .pad = 52, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 208, .pad = 52, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 208, .pad = 51, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 203, .pad = 51, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 203, .pad = 49, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 197, .pad = 49, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 197, .pad = 48, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 191, .pad = 48, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 191, .pad = 47, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 186, .pad = 47, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 186, .pad = 45, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 181, .pad = 45, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 181, .pad = 44, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 175, .pad = 44, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 175, .pad = 43, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 170, .pad = 43, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 170, .pad = 42, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 166, .pad = 42, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 166, .pad = 40, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 161, .pad = 40, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 161, .pad = 39, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 156, .pad = 39, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 156, .pad = 38, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 152, .pad = 38, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 152, .pad = 37, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 148, .pad = 37, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 148, .pad = 36, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 143, .pad = 36, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 143, .pad = 35, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 139, .pad = 35, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 139, .pad = 34, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 135, .pad = 34, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 135, .pad = 33, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 132, .pad = 33, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 132, .pad = 32, .dac = 0, .bb_mult = 64, },
+	{ .gm = 255, .pga = 128, .pad = 32, .dac = 0, .bb_mult = 64, },
+};
+
+void lpphy_rev0_1_table_init(struct b43_wldev *dev)
+{
+	B43_WARN_ON(dev->phy.rev >= 2);
+
+	b43_lptab_write_bulk(dev, B43_LPTAB8(2, 0),
+		ARRAY_SIZE(lpphy_min_sig_sq_table), lpphy_min_sig_sq_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(1, 0),
+		ARRAY_SIZE(lpphy_rev01_noise_scale_table), lpphy_rev01_noise_scale_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0),
+		ARRAY_SIZE(lpphy_crs_gain_nft_table), lpphy_crs_gain_nft_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(8, 0),
+		ARRAY_SIZE(lpphy_rev01_filter_control_table), lpphy_rev01_filter_control_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(9, 0),
+		ARRAY_SIZE(lpphy_rev01_ps_control_table), lpphy_rev01_ps_control_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB8(6, 0),
+		ARRAY_SIZE(lpphy_pll_fraction_table), lpphy_pll_fraction_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(0, 0),
+		ARRAY_SIZE(lpphy_iqlo_cal_table), lpphy_iqlo_cal_table);
+	if (dev->phy.rev == 0) {
+		b43_lptab_write_bulk(dev, B43_LPTAB16(13, 0),
+			ARRAY_SIZE(lpphy_rev0_ofdm_cck_gain_table), lpphy_rev0_ofdm_cck_gain_table);
+		b43_lptab_write_bulk(dev, B43_LPTAB16(12, 0),
+			ARRAY_SIZE(lpphy_rev0_ofdm_cck_gain_table), lpphy_rev0_ofdm_cck_gain_table);
+	} else {
+		b43_lptab_write_bulk(dev, B43_LPTAB16(13, 0),
+			ARRAY_SIZE(lpphy_rev1_ofdm_cck_gain_table), lpphy_rev1_ofdm_cck_gain_table);
+		b43_lptab_write_bulk(dev, B43_LPTAB16(12, 0),
+			ARRAY_SIZE(lpphy_rev1_ofdm_cck_gain_table), lpphy_rev1_ofdm_cck_gain_table);
+}
+	b43_lptab_write_bulk(dev, B43_LPTAB16(15, 0),
+		ARRAY_SIZE(lpphy_gain_delta_table), lpphy_gain_delta_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0),
+		ARRAY_SIZE(lpphy_tx_power_control_table), lpphy_tx_power_control_table);
+}
+
+void lpphy_rev2plus_table_init(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+	int i;
+
+	B43_WARN_ON(dev->phy.rev < 2);
+
+	for (i = 0; i < 704; i++)
+		b43_lptab_write(dev, B43_LPTAB32(7, i), 0);
+
+	b43_lptab_write_bulk(dev, B43_LPTAB8(2, 0),
+		ARRAY_SIZE(lpphy_min_sig_sq_table), lpphy_min_sig_sq_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(1, 0),
+		ARRAY_SIZE(lpphy_rev2plus_noise_scale_table), lpphy_rev2plus_noise_scale_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(11, 0),
+		ARRAY_SIZE(lpphy_rev2plus_filter_control_table), lpphy_rev2plus_filter_control_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(12, 0),
+		ARRAY_SIZE(lpphy_rev2plus_ps_control_table), lpphy_rev2plus_ps_control_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0),
+		ARRAY_SIZE(lpphy_gain_idx_table), lpphy_gain_idx_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0),
+		ARRAY_SIZE(lpphy_aux_gain_idx_table), lpphy_aux_gain_idx_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(15, 0),
+		ARRAY_SIZE(lpphy_sw_control_table), lpphy_sw_control_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB8(16, 0),
+		ARRAY_SIZE(lpphy_hf_table), lpphy_hf_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(17, 0),
+		ARRAY_SIZE(lpphy_gain_value_table), lpphy_gain_value_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(18, 0),
+		ARRAY_SIZE(lpphy_gain_table), lpphy_gain_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB8(6, 0),
+		ARRAY_SIZE(lpphy_pll_fraction_table), lpphy_pll_fraction_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB16(0, 0),
+		ARRAY_SIZE(lpphy_iqlo_cal_table), lpphy_iqlo_cal_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(9, 0),
+		ARRAY_SIZE(lpphy_papd_eps_table), lpphy_papd_eps_table);
+	b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0),
+		ARRAY_SIZE(lpphy_papd_mult_table), lpphy_papd_mult_table);
+
+	if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
+		b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0),
+			ARRAY_SIZE(lpphy_a0_gain_idx_table), lpphy_a0_gain_idx_table);
+		b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0),
+			ARRAY_SIZE(lpphy_a0_aux_gain_idx_table), lpphy_a0_aux_gain_idx_table);
+		b43_lptab_write_bulk(dev, B43_LPTAB32(17, 0),
+			ARRAY_SIZE(lpphy_a0_gain_value_table), lpphy_a0_gain_value_table);
+		b43_lptab_write_bulk(dev, B43_LPTAB16(18, 0),
+			ARRAY_SIZE(lpphy_a0_gain_table), lpphy_a0_gain_table);
+	}
+}
+
+static void lpphy_rev0_1_write_gain_table(struct b43_wldev *dev, int offset,
+				struct lpphy_tx_gain_table_entry data)
+{
+	u32 tmp;
+
+	B43_WARN_ON(dev->phy.rev >= 2);
+
+	tmp  = data.pad << 11;
+	tmp |= data.pga << 7;
+	tmp |= data.gm  << 4;
+	tmp |= data.dac;
+	b43_lptab_write(dev, B43_LPTAB32(10, 0xC0 + offset), tmp);
+	tmp  = data.bb_mult << 20;
+	b43_lptab_write(dev, B43_LPTAB32(10, 0x140 + offset), tmp);
+}
+
+static void lpphy_rev2plus_write_gain_table(struct b43_wldev *dev, int offset,
+				struct lpphy_tx_gain_table_entry data)
+{
+	u32 tmp;
+
+	B43_WARN_ON(dev->phy.rev < 2);
+
+	tmp  = data.pad << 16;
+	tmp |= data.pga << 8;
+	tmp |= data.gm;
+	if (dev->phy.rev >= 3) {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+			tmp |= 0x10 << 24;
+		else
+			tmp |= 0x70 << 24;
+	} else {
+		if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+			tmp |= 0x14 << 24;
+		else
+			tmp |= 0x7F << 24;
+	}
+	b43_lptab_write(dev, B43_LPTAB32(7, 0xC0 + offset), tmp);
+	tmp  = data.bb_mult << 20;
+	tmp |= data.dac << 28;
+	b43_lptab_write(dev, B43_LPTAB32(7, 0x140 + offset), tmp);
+}
+
+void lpphy_write_gain_table(struct b43_wldev *dev, int offset,
+			    struct lpphy_tx_gain_table_entry data)
+{
+	if (dev->phy.rev >= 2)
+		lpphy_rev2plus_write_gain_table(dev, offset, data);
+	else
+		lpphy_rev0_1_write_gain_table(dev, offset, data);
+}
+
+void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
+				 struct lpphy_tx_gain_table_entry *table)
+{
+	int i;
+
+	for (i = offset; i < count; i++)
+		lpphy_write_gain_table(dev, i, table[i]);
+}
+
+void lpphy_init_tx_gain_table(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->dev->bus;
+
+	switch (dev->phy.rev) {
+	case 0:
+		if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) ||
+		    (bus->sprom.boardflags_lo & B43_BFL_HGPA))
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev0_nopa_tx_gain_table);
+		else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev0_2ghz_tx_gain_table);
+		else
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev0_5ghz_tx_gain_table);
+		break;
+	case 1:
+		if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) ||
+		    (bus->sprom.boardflags_lo & B43_BFL_HGPA))
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev1_nopa_tx_gain_table);
+		else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev1_2ghz_tx_gain_table);
+		else
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev1_5ghz_tx_gain_table);
+		break;
+	default:
+		if (bus->sprom.boardflags_hi & B43_BFH_NOPA)
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev2_nopa_tx_gain_table);
+		else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev2_2ghz_tx_gain_table);
+		else
+			lpphy_write_gain_table_bulk(dev, 0, 128,
+					lpphy_rev2_5ghz_tx_gain_table);
 	}
 }
diff --git a/drivers/net/wireless/b43/tables_lpphy.h b/drivers/net/wireless/b43/tables_lpphy.h
index 0b8d028..84f1d26 100644
--- a/drivers/net/wireless/b43/tables_lpphy.h
+++ b/drivers/net/wireless/b43/tables_lpphy.h
@@ -26,6 +26,19 @@ void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
 			  unsigned int nr_elements, const void *data);
 
 void b2062_upload_init_table(struct b43_wldev *dev);
+void b2063_upload_init_table(struct b43_wldev *dev);
 
+struct lpphy_tx_gain_table_entry {
+	u8 gm,  pga,  pad,  dac,  bb_mult;
+};
+
+void lpphy_write_gain_table(struct b43_wldev *dev, int offset,
+			    struct lpphy_tx_gain_table_entry data);
+void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
+				 struct lpphy_tx_gain_table_entry *table);
+
+void lpphy_rev0_1_table_init(struct b43_wldev *dev);
+void lpphy_rev2plus_table_init(struct b43_wldev *dev);
+void lpphy_init_tx_gain_table(struct b43_wldev *dev);
 
 #endif /* B43_TABLES_LPPHY_H_ */
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index e1e20f6..97c7916 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -37,7 +37,7 @@ static void b43_wa_papd(struct b43_wldev *dev)
 	backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0);
 	b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7);
 	b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0);
-	b43_dummy_transmission(dev);
+	b43_dummy_transmission(dev, true, true);
 	b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup);
 }
 
@@ -628,7 +628,7 @@ void b43_wa_all(struct b43_wldev *dev)
 			B43_WARN_ON(1);
 		}
 		b43_wa_boards_g(dev);
-	} else { /* No N PHY support so far */
+	} else { /* No N PHY support so far, LP PHY is in phy_lp.c */
 		B43_WARN_ON(1);
 	}
 
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 55f36a7..14f5412 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -180,11 +180,12 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
 /* Generate a TX data header. */
 int b43_generate_txhdr(struct b43_wldev *dev,
 		       u8 *_txhdr,
-		       const unsigned char *fragment_data,
-		       unsigned int fragment_len,
+		       struct sk_buff *skb_frag,
 		       struct ieee80211_tx_info *info,
 		       u16 cookie)
 {
+	const unsigned char *fragment_data = skb_frag->data;
+	unsigned int fragment_len = skb_frag->len;
 	struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
 	const struct b43_phy *phy = &dev->phy;
 	const struct ieee80211_hdr *wlhdr =
@@ -237,7 +238,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
 		int wlhdr_len;
 		size_t iv_len;
 
-		B43_WARN_ON(key_idx >= dev->max_nr_keys);
+		B43_WARN_ON(key_idx >= ARRAY_SIZE(dev->key));
 		key = &(dev->key[key_idx]);
 
 		if (unlikely(!key->keyconf)) {
@@ -258,9 +259,26 @@ int b43_generate_txhdr(struct b43_wldev *dev,
 		mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
 			   B43_TXH_MAC_KEYALG;
 		wlhdr_len = ieee80211_hdrlen(fctl);
-		iv_len = min((size_t) info->control.hw_key->iv_len,
-			     ARRAY_SIZE(txhdr->iv));
-		memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
+		if (key->algorithm == B43_SEC_ALGO_TKIP) {
+			u16 phase1key[5];
+			int i;
+			/* we give the phase1key and iv16 here, the key is stored in
+			 * shm. With that the hardware can do phase 2 and encryption.
+			 */
+			ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
+					IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
+			/* phase1key is in host endian. Copy to little-endian txhdr->iv. */
+			for (i = 0; i < 5; i++) {
+				txhdr->iv[i * 2 + 0] = phase1key[i];
+				txhdr->iv[i * 2 + 1] = phase1key[i] >> 8;
+			}
+			/* iv16 */
+			memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3);
+		} else {
+			iv_len = min((size_t) info->control.hw_key->iv_len,
+				     ARRAY_SIZE(txhdr->iv));
+			memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
+		}
 	}
 	if (b43_is_old_txhdr_format(dev)) {
 		b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
@@ -578,7 +596,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 		 * key index, but the ucode passed it slightly different.
 		 */
 		keyidx = b43_kidx_to_raw(dev, keyidx);
-		B43_WARN_ON(keyidx >= dev->max_nr_keys);
+		B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key));
 
 		if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
 			wlhdr_len = ieee80211_hdrlen(fctl);
@@ -655,6 +673,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 		status.freq = chanid + 2400;
 		break;
 	case B43_PHYTYPE_N:
+	case B43_PHYTYPE_LP:
 		/* chanid is the SHM channel cookie. Which is the plain
 		 * channel number in b43. */
 		if (chanstat & B43_RX_CHAN_5GHZ) {
@@ -670,7 +689,8 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
 		goto drop;
 	}
 
-	ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
+	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+	ieee80211_rx_irqsafe(dev->wl->hw, skb);
 
 	return;
 drop:
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 4fb2a19..3530de8 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -176,8 +176,7 @@ size_t b43_txhdr_size(struct b43_wldev *dev)
 
 int b43_generate_txhdr(struct b43_wldev *dev,
 		       u8 * txhdr,
-		       const unsigned char *fragment_data,
-		       unsigned int fragment_len,
+		       struct sk_buff *skb_frag,
 		       struct ieee80211_tx_info *txctl, u16 cookie);
 
 /* Transmit Status */
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 2f90fb9..8664034 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -1366,15 +1366,25 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
 	ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
 	spin_lock_irqsave(&ring->lock, flags);
 	B43legacy_WARN_ON(!ring->tx);
-	if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
-		b43legacywarn(dev->wl, "DMA queue overflow\n");
+
+	if (unlikely(ring->stopped)) {
+		/* We get here only because of a bug in mac80211.
+		 * Because of a race, one packet may be queued after
+		 * the queue is stopped, thus we got called when we shouldn't.
+		 * For now, just refuse the transmit. */
+		if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
+			b43legacyerr(dev->wl, "Packet after queue stopped\n");
+		err = -ENOSPC;
+		goto out_unlock;
+	}
+
+	if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) {
+		/* If we get here, we have a real error with the queue
+		 * full, but queues not stopped. */
+		b43legacyerr(dev->wl, "DMA queue overflow\n");
 		err = -ENOSPC;
 		goto out_unlock;
 	}
-	/* Check if the queue was stopped in mac80211,
-	 * but we got called nevertheless.
-	 * That would be a mac80211 bug. */
-	B43legacy_BUG_ON(ring->stopped);
 
 	err = dma_tx_fragment(ring, skb);
 	if (unlikely(err == -ENOKEY)) {
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index c4973c1..1d9223b 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1252,7 +1252,7 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
 	wl->current_beacon = beacon;
 	wl->beacon0_uploaded = 0;
 	wl->beacon1_uploaded = 0;
-	queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
+	ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
 }
 
 static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
@@ -2300,7 +2300,7 @@ out_requeue:
 		delay = msecs_to_jiffies(50);
 	else
 		delay = round_jiffies_relative(HZ * 15);
-	queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);
+	ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
 out:
 	mutex_unlock(&wl->mutex);
 }
@@ -2311,7 +2311,7 @@ static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev)
 
 	dev->periodic_state = 0;
 	INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler);
-	queue_delayed_work(dev->wl->hw->workqueue, work, 0);
+	ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
 }
 
 /* Validate access to the chip (SHM) */
@@ -2836,9 +2836,7 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
 
 static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
 					  unsigned int changed,
-					  unsigned int *fflags,
-					  int mc_count,
-					  struct dev_addr_list *mc_list)
+					  unsigned int *fflags,u64 multicast)
 {
 	struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
 	struct b43legacy_wldev *dev = wl->current_dev;
@@ -3108,16 +3106,20 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
 	    bus->pcicore.dev->id.revision <= 5) {
 		/* IMCFGLO timeouts workaround. */
 		tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
-		tmp &= ~SSB_IMCFGLO_REQTO;
-		tmp &= ~SSB_IMCFGLO_SERTO;
 		switch (bus->bustype) {
 		case SSB_BUSTYPE_PCI:
 		case SSB_BUSTYPE_PCMCIA:
+			tmp &= ~SSB_IMCFGLO_REQTO;
+			tmp &= ~SSB_IMCFGLO_SERTO;
 			tmp |= 0x32;
 			break;
 		case SSB_BUSTYPE_SSB:
+			tmp &= ~SSB_IMCFGLO_REQTO;
+			tmp &= ~SSB_IMCFGLO_SERTO;
 			tmp |= 0x53;
 			break;
+		default:
+			break;
 		}
 		ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
 	}
@@ -3885,7 +3887,7 @@ void b43legacy_controller_restart(struct b43legacy_wldev *dev,
 	if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
 		return;
 	b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason);
-	queue_work(dev->wl->hw->workqueue, &dev->restart_work);
+	ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index b8e39dd..103f3c9 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -590,8 +590,8 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
 		       chanstat);
 	}
 
-	dev->stats.last_rx = jiffies;
-	ieee80211_rx_irqsafe(dev->wl->hw, skb, &status);
+	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+	ieee80211_rx_irqsafe(dev->wl->hw, skb);
 
 	return;
 drop:
diff --git a/drivers/net/wireless/hostap/hostap_80211.h b/drivers/net/wireless/hostap/hostap_80211.h
index 2e9fb0f..7f9d8d9 100644
--- a/drivers/net/wireless/hostap/hostap_80211.h
+++ b/drivers/net/wireless/hostap/hostap_80211.h
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <linux/skbuff.h>
+#include <linux/netdevice.h>
 
 struct hostap_ieee80211_mgmt {
 	__le16 frame_control;
@@ -85,8 +86,11 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
 			  struct hostap_80211_rx_status *rx_stats);
 
 void hostap_dump_tx_80211(const char *name, struct sk_buff *skb);
-int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t hostap_data_start_xmit(struct sk_buff *skb,
+				   struct net_device *dev);
+netdev_tx_t hostap_mgmt_start_xmit(struct sk_buff *skb,
+				   struct net_device *dev);
+netdev_tx_t hostap_master_start_xmit(struct sk_buff *skb,
+				     struct net_device *dev);
 
 #endif /* HOSTAP_80211_H */
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index d313b00..90108b6 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -53,7 +53,8 @@ void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
 /* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta)
  * Convert Ethernet header into a suitable IEEE 802.11 header depending on
  * device configuration. */
-int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t hostap_data_start_xmit(struct sk_buff *skb,
+				   struct net_device *dev)
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
@@ -75,7 +76,7 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb "
 		       "(len=%d)\n", dev->name, skb->len);
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (local->ddev != dev) {
@@ -89,14 +90,14 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			printk(KERN_DEBUG "%s: prism2_tx: trying to use "
 			       "AP device with Ethernet net dev\n", dev->name);
 			kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		}
 	} else {
 		if (local->iw_mode == IW_MODE_REPEAT) {
 			printk(KERN_DEBUG "%s: prism2_tx: trying to use "
 			       "non-WDS link in Repeater mode\n", dev->name);
 			kfree_skb(skb);
-			return 0;
+			return NETDEV_TX_OK;
 		} else if (local->iw_mode == IW_MODE_INFRA &&
 			   (local->wds_type & HOSTAP_WDS_AP_CLIENT) &&
 			   memcmp(skb->data + ETH_ALEN, dev->dev_addr,
@@ -210,13 +211,13 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb = skb_unshare(skb, GFP_ATOMIC);
 		if (skb == NULL) {
 			iface->stats.tx_dropped++;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 		if (pskb_expand_head(skb, need_headroom, need_tailroom,
 				     GFP_ATOMIC)) {
 			kfree_skb(skb);
 			iface->stats.tx_dropped++;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 	} else if (skb_headroom(skb) < need_headroom) {
 		struct sk_buff *tmp = skb;
@@ -224,13 +225,13 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		kfree_skb(tmp);
 		if (skb == NULL) {
 			iface->stats.tx_dropped++;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 	} else {
 		skb = skb_unshare(skb, GFP_ATOMIC);
 		if (skb == NULL) {
 			iface->stats.tx_dropped++;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 	}
 
@@ -256,12 +257,13 @@ int hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Send IEEE 802.11 encapsulated frame using the master radio device */
 	skb->dev = local->dev;
 	dev_queue_xmit(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
 /* hard_start_xmit function for hostapd wlan#ap interfaces */
-int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t hostap_mgmt_start_xmit(struct sk_buff *skb,
+				   struct net_device *dev)
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
@@ -276,7 +278,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: hostap_mgmt_start_xmit: short skb "
 		       "(len=%d)\n", dev->name, skb->len);
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	iface->stats.tx_packets++;
@@ -301,7 +303,7 @@ int hostap_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Send IEEE 802.11 encapsulated frame using the master radio device */
 	skb->dev = local->dev;
 	dev_queue_xmit(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
@@ -373,11 +375,12 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
 /* hard_start_xmit function for master radio interface wifi#.
  * AP processing (TX rate control, power save buffering, etc.).
  * Use hardware TX function to send the frame. */
-int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t hostap_master_start_xmit(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	int ret = NETDEV_TX_BUSY;
+	netdev_tx_t ret = NETDEV_TX_BUSY;
 	u16 fc;
 	struct hostap_tx_data tx;
 	ap_tx_ret tx_ret;
@@ -396,7 +399,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: invalid skb->cb magic (0x%08x, "
 		       "expected 0x%08x)\n",
 		       dev->name, meta->magic, HOSTAP_SKB_TX_DATA_MAGIC);
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		iface->stats.tx_dropped++;
 		goto fail;
 	}
@@ -414,7 +417,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (skb->len < 24) {
 		printk(KERN_DEBUG "%s: hostap_master_start_xmit: short skb "
 		       "(len=%d)\n", dev->name, skb->len);
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		iface->stats.tx_dropped++;
 		goto fail;
 	}
@@ -441,13 +444,13 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			       dev->name, meta->ethertype);
 			hostap_dump_tx_80211(dev->name, skb);
 
-			ret = 0; /* drop packet */
+			ret = NETDEV_TX_OK; /* drop packet */
 			iface->stats.tx_dropped++;
 			goto fail;
 		}
 		break;
 	case AP_TX_DROP:
-		ret = 0; /* drop packet */
+		ret = NETDEV_TX_OK; /* drop packet */
 		iface->stats.tx_dropped++;
 		goto fail;
 	case AP_TX_RETRY:
@@ -455,7 +458,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	case AP_TX_BUFFERED:
 		/* do not free skb here, it will be freed when the
 		 * buffered frame is sent/timed out */
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		goto tx_exit;
 	}
 
@@ -501,7 +504,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			       "frame (drop_unencrypted=1)\n", dev->name);
 		}
 		iface->stats.tx_dropped++;
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		goto fail;
 	}
 
@@ -510,7 +513,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		if (skb == NULL) {
 			printk(KERN_DEBUG "%s: TX - encryption failed\n",
 			       dev->name);
-			ret = 0;
+			ret = NETDEV_TX_OK;
 			goto fail;
 		}
 		meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -519,23 +522,23 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			       "expected 0x%08x) after hostap_tx_encrypt\n",
 			       dev->name, meta->magic,
 			       HOSTAP_SKB_TX_DATA_MAGIC);
-			ret = 0;
+			ret = NETDEV_TX_OK;
 			iface->stats.tx_dropped++;
 			goto fail;
 		}
 	}
 
 	if (local->func->tx == NULL || local->func->tx(skb, dev)) {
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		iface->stats.tx_dropped++;
 	} else {
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		iface->stats.tx_packets++;
 		iface->stats.tx_bytes += skb->len;
 	}
 
  fail:
-	if (!ret && skb)
+	if (ret == NETDEV_TX_OK && skb)
 		dev_kfree_skb(skb);
  tx_exit:
 	if (tx.sta_ptr)
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 6337402..ad8eab4 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -666,7 +666,8 @@ static int prism2_config(struct pcmcia_device *link)
 	 * irq structure is initialized.
 	 */
 	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-		link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+		link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
+				       IRQ_HANDLE_PRESENT;
 		link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 		link->irq.Handler = prism2_interrupt;
 		link->irq.Instance = dev;
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index 6fe122f..eb57d1e 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -875,15 +875,16 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local,
 
 	switch(type) {
 	case HOSTAP_INTERFACE_AP:
+		dev->tx_queue_len = 0;	/* use main radio device queue */
 		dev->netdev_ops = &hostap_mgmt_netdev_ops;
 		dev->type = ARPHRD_IEEE80211;
 		dev->header_ops = &hostap_80211_ops;
 		break;
 	case HOSTAP_INTERFACE_MASTER:
-		dev->tx_queue_len = 0;	/* use main radio device queue */
 		dev->netdev_ops = &hostap_master_ops;
 		break;
 	default:
+		dev->tx_queue_len = 0;	/* use main radio device queue */
 		dev->netdev_ops = &hostap_netdev_ops;
 	}
 
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig
index 85cc799..a813138 100644
--- a/drivers/net/wireless/ipw2x00/Kconfig
+++ b/drivers/net/wireless/ipw2x00/Kconfig
@@ -4,7 +4,7 @@
 
 config IPW2100
 	tristate "Intel PRO/Wireless 2100 Network Connection"
-	depends on PCI && WLAN_80211
+	depends on PCI && WLAN_80211 && CFG80211
 	select WIRELESS_EXT
 	select FW_LOADER
 	select LIB80211
@@ -63,7 +63,7 @@ config IPW2100_DEBUG
 
 config IPW2200
 	tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
-	depends on PCI && WLAN_80211
+	depends on PCI && WLAN_80211 && CFG80211
 	select WIRELESS_EXT
 	select FW_LOADER
 	select LIB80211
@@ -150,7 +150,7 @@ config IPW2200_DEBUG
 
 config LIBIPW
 	tristate
-	depends on PCI && WLAN_80211
+	depends on PCI && WLAN_80211 && CFG80211
 	select WIRELESS_EXT
 	select CRYPTO
 	select CRYPTO_ARC4
diff --git a/drivers/net/wireless/ipw2x00/ieee80211.h b/drivers/net/wireless/ipw2x00/ieee80211.h
deleted file mode 100644
index 70755c1..0000000
--- a/drivers/net/wireless/ipw2x00/ieee80211.h
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <j@w1.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004-2005, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- *
- * API Version History
- * 1.0.x -- Initial version
- * 1.1.x -- Added radiotap, QoS, TIM, ieee80211_geo APIs,
- *          various structure changes, and crypto API init method
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h>	/* ETH_ALEN */
-#include <linux/kernel.h>	/* ARRAY_SIZE */
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-
-#include <net/lib80211.h>
-
-#define IEEE80211_VERSION "git-1.1.13"
-
-#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
-
-/* QOS control */
-#define IEEE80211_QCTL_TID		0x000F
-
-/* debug macros */
-
-#ifdef CONFIG_LIBIPW_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
-  printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
-         in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-static inline bool ieee80211_ratelimit_debug(u32 level)
-{
-	return (ieee80211_debug_level & level) && net_ratelimit();
-}
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-static inline bool ieee80211_ratelimit_debug(u32 level)
-{
-	return false;
-}
-#endif				/* CONFIG_LIBIPW_DEBUG */
-
-/*
- * To use the debug system:
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IEEE80211_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/ieee80211/debug_level
- *
- * you simply need to add your entry to the ieee80211_debug_level array.
- *
- * If you do not see debug_level in /proc/net/ieee80211 then you do not have
- * CONFIG_LIBIPW_DEBUG defined in your kernel configuration
- *
- */
-
-#define IEEE80211_DL_INFO          (1<<0)
-#define IEEE80211_DL_WX            (1<<1)
-#define IEEE80211_DL_SCAN          (1<<2)
-#define IEEE80211_DL_STATE         (1<<3)
-#define IEEE80211_DL_MGMT          (1<<4)
-#define IEEE80211_DL_FRAG          (1<<5)
-#define IEEE80211_DL_DROP          (1<<7)
-
-#define IEEE80211_DL_TX            (1<<8)
-#define IEEE80211_DL_RX            (1<<9)
-#define IEEE80211_DL_QOS           (1<<31)
-
-#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
-#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
-#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
-
-#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
-#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
-#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
-#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
-#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
-#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
-#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
-#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
-#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>	/* ARPHRD_ETHER */
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY		/* enable iwspy support */
-#endif
-#include <net/iw_handler.h>	/* new driver API */
-
-#define ETH_P_PREAUTH 0x88C7	/* IEEE 802.11i pre-authentication */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
-
-	u8 dsap;		/* always 0xAA */
-	u8 ssap;		/* always 0xAA */
-	u8 ctrl;		/* always 0x03 */
-	u8 oui[P80211_OUI_LEN];	/* organizational universal id */
-
-} __attribute__ ((packed));
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
-#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
-
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-#define IEEE80211_CCK_MODULATION    (1<<0)
-#define IEEE80211_OFDM_MODULATION   (1<<1)
-
-#define IEEE80211_24GHZ_BAND     (1<<0)
-#define IEEE80211_52GHZ_BAND     (1<<1)
-
-#define IEEE80211_CCK_RATE_1MB		        0x02
-#define IEEE80211_CCK_RATE_2MB		        0x04
-#define IEEE80211_CCK_RATE_5MB		        0x0B
-#define IEEE80211_CCK_RATE_11MB		        0x16
-#define IEEE80211_OFDM_RATE_6MB		        0x0C
-#define IEEE80211_OFDM_RATE_9MB		        0x12
-#define IEEE80211_OFDM_RATE_12MB		0x18
-#define IEEE80211_OFDM_RATE_18MB		0x24
-#define IEEE80211_OFDM_RATE_24MB		0x30
-#define IEEE80211_OFDM_RATE_36MB		0x48
-#define IEEE80211_OFDM_RATE_48MB		0x60
-#define IEEE80211_OFDM_RATE_54MB		0x6C
-#define IEEE80211_BASIC_RATE_MASK		0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
-
-#define IEEE80211_CCK_RATES_MASK	        0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
-	IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
-        IEEE80211_CCK_RATE_5MB_MASK | \
-        IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
-	IEEE80211_OFDM_RATE_12MB_MASK | \
-	IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
-	IEEE80211_OFDM_RATE_9MB_MASK  | \
-	IEEE80211_OFDM_RATE_18MB_MASK | \
-	IEEE80211_OFDM_RATE_36MB_MASK | \
-	IEEE80211_OFDM_RATE_48MB_MASK | \
-	IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
-                                IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES	    8
-#define IEEE80211_NUM_CCK_RATES	            4
-#define IEEE80211_OFDM_SHIFT_MASK_A         4
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- *       information for frames received.
- *       For ieee80211_rx_mgt, you need to set at least the 'len' parameter.
- */
-struct ieee80211_rx_stats {
-	u32 mac_time;
-	s8 rssi;
-	u8 signal;
-	u8 noise;
-	u16 rate;		/* in 100 kbps */
-	u8 received_channel;
-	u8 control;
-	u8 mask;
-	u8 freq;
-	u16 len;
-	u64 tsf;
-	u32 beacon_time;
-};
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
-#define IEEE80211_FRAG_CACHE_LEN 4
-
-struct ieee80211_frag_entry {
-	unsigned long first_frag_time;
-	unsigned int seq;
-	unsigned int last_frag;
-	struct sk_buff *skb;
-	u8 src_addr[ETH_ALEN];
-	u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
-	unsigned int tx_unicast_frames;
-	unsigned int tx_multicast_frames;
-	unsigned int tx_fragments;
-	unsigned int tx_unicast_octets;
-	unsigned int tx_multicast_octets;
-	unsigned int tx_deferred_transmissions;
-	unsigned int tx_single_retry_frames;
-	unsigned int tx_multiple_retry_frames;
-	unsigned int tx_retry_limit_exceeded;
-	unsigned int tx_discards;
-	unsigned int rx_unicast_frames;
-	unsigned int rx_multicast_frames;
-	unsigned int rx_fragments;
-	unsigned int rx_unicast_octets;
-	unsigned int rx_multicast_octets;
-	unsigned int rx_fcs_errors;
-	unsigned int rx_discards_no_buffer;
-	unsigned int tx_discards_wrong_sa;
-	unsigned int rx_discards_undecryptable;
-	unsigned int rx_message_in_msg_fragments;
-	unsigned int rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_device;
-
-#define SEC_KEY_1		(1<<0)
-#define SEC_KEY_2		(1<<1)
-#define SEC_KEY_3		(1<<2)
-#define SEC_KEY_4		(1<<3)
-#define SEC_ACTIVE_KEY		(1<<4)
-#define SEC_AUTH_MODE		(1<<5)
-#define SEC_UNICAST_GROUP	(1<<6)
-#define SEC_LEVEL		(1<<7)
-#define SEC_ENABLED		(1<<8)
-#define SEC_ENCRYPT		(1<<9)
-
-#define SEC_LEVEL_0		0	/* None */
-#define SEC_LEVEL_1		1	/* WEP 40 and 104 bit */
-#define SEC_LEVEL_2		2	/* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP	3	/* Level 1 + CKIP */
-#define SEC_LEVEL_3		4	/* Level 2 + CCMP */
-
-#define SEC_ALG_NONE		0
-#define SEC_ALG_WEP		1
-#define SEC_ALG_TKIP		2
-#define SEC_ALG_CCMP		3
-
-#define WEP_KEYS		4
-#define WEP_KEY_LEN		13
-#define SCM_KEY_LEN		32
-#define SCM_TEMPORAL_KEY_LENGTH	16
-
-struct ieee80211_security {
-	u16 active_key:2, enabled:1, unicast_uses_group:1, encrypt:1;
-	u8 auth_mode;
-	u8 encode_alg[WEP_KEYS];
-	u8 key_sizes[WEP_KEYS];
-	u8 keys[WEP_KEYS][SCM_KEY_LEN];
-	u8 level;
-	u16 flags;
-} __attribute__ ((packed));
-
-/*
-
- 802.11 data frame from AP
-
-      ,-------------------------------------------------------------------.
-Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
-      |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
-      |      | tion | (BSSID) |         |         | ence |  data   |      |
-      `-------------------------------------------------------------------'
-
-Total: 28-2340 bytes
-
-*/
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-struct ieee80211_hdr_1addr {
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_2addr {
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 payload[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_hdr_4addr {
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	__le16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-	u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addrqos {
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	__le16 seq_ctl;
-	u8 payload[0];
-	__le16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
-	u8 id;
-	u8 len;
-	u8 data[0];
-} __attribute__ ((packed));
-
-/*
- * These are the data types that can make up management packets
- *
-	u16 auth_algorithm;
-	u16 auth_sequence;
-	u16 beacon_interval;
-	u16 capability;
-	u8 current_ap[ETH_ALEN];
-	u16 listen_interval;
-	struct {
-		u16 association_id:14, reserved:2;
-	} __attribute__ ((packed));
-	u32 time_stamp[2];
-	u16 reason;
-	u16 status;
-*/
-
-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_channel_switch {
-	u8 id;
-	u8 len;
-	u8 mode;
-	u8 channel;
-	u8 count;
-} __attribute__ ((packed));
-
-struct ieee80211_action {
-	struct ieee80211_hdr_3addr header;
-	u8 category;
-	u8 action;
-	union {
-		struct ieee80211_action_exchange {
-			u8 token;
-			struct ieee80211_info_element info_element[0];
-		} exchange;
-		struct ieee80211_channel_switch channel_switch;
-
-	} format;
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc {
-	struct ieee80211_hdr_3addr header;
-	__le16 reason;
-} __attribute__ ((packed));
-
-/* Alias deauth for disassoc */
-#define ieee80211_deauth ieee80211_disassoc
-
-struct ieee80211_probe_request {
-	struct ieee80211_hdr_3addr header;
-	/* SSID, supported rates */
-	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_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_reassoc_request {
-	struct ieee80211_hdr_3addr header;
-	__le16 capability;
-	__le16 listen_interval;
-	u8 current_ap[ETH_ALEN];
-	struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-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_txb {
-	u8 nr_frags;
-	u8 encrypted;
-	u8 rts_included;
-	u8 reserved;
-	u16 frag_size;
-	u16 payload_size;
-	struct sk_buff *fragments[0];
-};
-
-/* SWEEP TABLE ENTRIES NUMBER */
-#define MAX_SWEEP_TAB_ENTRIES		  42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
-/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates.  Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH                  ((u8)12)
-#define MAX_RATES_EX_LENGTH               ((u8)16)
-#define MAX_NETWORK_COUNT                  128
-
-#define CRC_LENGTH                 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_HAS_OFDM       (1<<1)
-#define NETWORK_HAS_CCK        (1<<2)
-
-/* QoS structure */
-#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
-#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
-#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
-					 NETWORK_HAS_QOS_INFORMATION)
-
-/* 802.11h */
-#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
-#define NETWORK_HAS_CSA                 (1<<6)
-#define NETWORK_HAS_QUIET               (1<<7)
-#define NETWORK_HAS_IBSS_DFS            (1<<8)
-#define NETWORK_HAS_TPC_REPORT          (1<<9)
-
-#define NETWORK_HAS_ERP_VALUE           (1<<10)
-
-#define QOS_QUEUE_NUM                   4
-#define QOS_OUI_LEN                     3
-#define QOS_OUI_TYPE                    2
-#define QOS_ELEMENT_ID                  221
-#define QOS_OUI_INFO_SUB_TYPE           0
-#define QOS_OUI_PARAM_SUB_TYPE          1
-#define QOS_VERSION_1                   1
-#define QOS_AIFSN_MIN_VALUE             2
-
-struct ieee80211_qos_information_element {
-	u8 elementID;
-	u8 length;
-	u8 qui[QOS_OUI_LEN];
-	u8 qui_type;
-	u8 qui_subtype;
-	u8 version;
-	u8 ac_info;
-} __attribute__ ((packed));
-
-struct ieee80211_qos_ac_parameter {
-	u8 aci_aifsn;
-	u8 ecw_min_max;
-	__le16 tx_op_limit;
-} __attribute__ ((packed));
-
-struct ieee80211_qos_parameter_info {
-	struct ieee80211_qos_information_element info_element;
-	u8 reserved;
-	struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
-} __attribute__ ((packed));
-
-struct ieee80211_qos_parameters {
-	__le16 cw_min[QOS_QUEUE_NUM];
-	__le16 cw_max[QOS_QUEUE_NUM];
-	u8 aifs[QOS_QUEUE_NUM];
-	u8 flag[QOS_QUEUE_NUM];
-	__le16 tx_op_limit[QOS_QUEUE_NUM];
-} __attribute__ ((packed));
-
-struct ieee80211_qos_data {
-	struct ieee80211_qos_parameters parameters;
-	int active;
-	int supported;
-	u8 param_count;
-	u8 old_param_count;
-};
-
-struct ieee80211_tim_parameters {
-	u8 tim_count;
-	u8 tim_period;
-} __attribute__ ((packed));
-
-/*******************************************************/
-
-enum {				/* ieee80211_basic_report.map */
-	IEEE80211_BASIC_MAP_BSS = (1 << 0),
-	IEEE80211_BASIC_MAP_OFDM = (1 << 1),
-	IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
-	IEEE80211_BASIC_MAP_RADAR = (1 << 3),
-	IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
-	/* Bits 5-7 are reserved */
-
-};
-struct ieee80211_basic_report {
-	u8 channel;
-	__le64 start_time;
-	__le16 duration;
-	u8 map;
-} __attribute__ ((packed));
-
-enum {				/* ieee80211_measurement_request.mode */
-	/* Bit 0 is reserved */
-	IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
-	IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
-	IEEE80211_MEASUREMENT_REPORT = (1 << 3),
-	/* Bits 4-7 are reserved */
-};
-
-enum {
-	IEEE80211_REPORT_BASIC = 0,	/* required */
-	IEEE80211_REPORT_CCA = 1,	/* optional */
-	IEEE80211_REPORT_RPI = 2,	/* optional */
-	/* 3-255 reserved */
-};
-
-struct ieee80211_measurement_params {
-	u8 channel;
-	__le64 start_time;
-	__le16 duration;
-} __attribute__ ((packed));
-
-struct ieee80211_measurement_request {
-	struct ieee80211_info_element ie;
-	u8 token;
-	u8 mode;
-	u8 type;
-	struct ieee80211_measurement_params params[0];
-} __attribute__ ((packed));
-
-struct ieee80211_measurement_report {
-	struct ieee80211_info_element ie;
-	u8 token;
-	u8 mode;
-	u8 type;
-	union {
-		struct ieee80211_basic_report basic[0];
-	} u;
-} __attribute__ ((packed));
-
-struct ieee80211_tpc_report {
-	u8 transmit_power;
-	u8 link_margin;
-} __attribute__ ((packed));
-
-struct ieee80211_channel_map {
-	u8 channel;
-	u8 map;
-} __attribute__ ((packed));
-
-struct ieee80211_ibss_dfs {
-	struct ieee80211_info_element ie;
-	u8 owner[ETH_ALEN];
-	u8 recovery_interval;
-	struct ieee80211_channel_map channel_map[0];
-};
-
-struct ieee80211_csa {
-	u8 mode;
-	u8 channel;
-	u8 count;
-} __attribute__ ((packed));
-
-struct ieee80211_quiet {
-	u8 count;
-	u8 period;
-	u8 duration;
-	u8 offset;
-} __attribute__ ((packed));
-
-struct ieee80211_network {
-	/* These entries are used to identify a unique network */
-	u8 bssid[ETH_ALEN];
-	u8 channel;
-	/* Ensure null-terminated for any debug msgs */
-	u8 ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 ssid_len;
-
-	struct ieee80211_qos_data qos_data;
-
-	/* These are network statistics */
-	struct ieee80211_rx_stats stats;
-	u16 capability;
-	u8 rates[MAX_RATES_LENGTH];
-	u8 rates_len;
-	u8 rates_ex[MAX_RATES_EX_LENGTH];
-	u8 rates_ex_len;
-	unsigned long last_scanned;
-	u8 mode;
-	u32 flags;
-	u32 last_associate;
-	u32 time_stamp[2];
-	u16 beacon_interval;
-	u16 listen_interval;
-	u16 atim_window;
-	u8 erp_value;
-	u8 wpa_ie[MAX_WPA_IE_LEN];
-	size_t wpa_ie_len;
-	u8 rsn_ie[MAX_WPA_IE_LEN];
-	size_t rsn_ie_len;
-	struct ieee80211_tim_parameters tim;
-
-	/* 802.11h info */
-
-	/* Power Constraint - mandatory if spctrm mgmt required */
-	u8 power_constraint;
-
-	/* TPC Report - mandatory if spctrm mgmt required */
-	struct ieee80211_tpc_report tpc_report;
-
-	/* IBSS DFS - mandatory if spctrm mgmt required and IBSS
-	 * NOTE: This is variable length and so must be allocated dynamically */
-	struct ieee80211_ibss_dfs *ibss_dfs;
-
-	/* Channel Switch Announcement - optional if spctrm mgmt required */
-	struct ieee80211_csa csa;
-
-	/* Quiet - optional if spctrm mgmt required */
-	struct ieee80211_quiet quiet;
-
-	struct list_head list;
-};
-
-enum ieee80211_state {
-	IEEE80211_UNINITIALIZED = 0,
-	IEEE80211_INITIALIZED,
-	IEEE80211_ASSOCIATING,
-	IEEE80211_ASSOCIATED,
-	IEEE80211_AUTHENTICATING,
-	IEEE80211_AUTHENTICATED,
-	IEEE80211_SHUTDOWN
-};
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-#define CFG_IEEE80211_RTS (1<<2)
-
-#define IEEE80211_24GHZ_MIN_CHANNEL 1
-#define IEEE80211_24GHZ_MAX_CHANNEL 14
-#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
-				  IEEE80211_24GHZ_MIN_CHANNEL + 1)
-
-#define IEEE80211_52GHZ_MIN_CHANNEL 34
-#define IEEE80211_52GHZ_MAX_CHANNEL 165
-#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
-				  IEEE80211_52GHZ_MIN_CHANNEL + 1)
-
-enum {
-	IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
-	IEEE80211_CH_80211H_RULES = (1 << 1),
-	IEEE80211_CH_B_ONLY = (1 << 2),
-	IEEE80211_CH_NO_IBSS = (1 << 3),
-	IEEE80211_CH_UNIFORM_SPREADING = (1 << 4),
-	IEEE80211_CH_RADAR_DETECT = (1 << 5),
-	IEEE80211_CH_INVALID = (1 << 6),
-};
-
-struct ieee80211_channel {
-	u32 freq;	/* in MHz */
-	u8 channel;
-	u8 flags;
-	u8 max_power;	/* in dBm */
-};
-
-struct ieee80211_geo {
-	u8 name[4];
-	u8 bg_channels;
-	u8 a_channels;
-	struct ieee80211_channel bg[IEEE80211_24GHZ_CHANNELS];
-	struct ieee80211_channel a[IEEE80211_52GHZ_CHANNELS];
-};
-
-struct ieee80211_device {
-	struct net_device *dev;
-	struct ieee80211_security sec;
-
-	/* Bookkeeping structures */
-	struct ieee80211_stats ieee_stats;
-
-	struct ieee80211_geo geo;
-
-	/* Probe / Beacon management */
-	struct list_head network_free_list;
-	struct list_head network_list;
-	struct ieee80211_network *networks;
-	int scans;
-	int scan_age;
-
-	int iw_mode;		/* operating mode (IW_MODE_*) */
-	struct iw_spy_data spy_data;	/* iwspy support */
-
-	spinlock_t lock;
-
-	int tx_headroom;	/* Set to size of any additional room needed at front
-				 * of allocated Tx SKBs */
-	u32 config;
-
-	/* WEP and other encryption related settings at the device level */
-	int open_wep;		/* Set to 1 to allow unencrypted frames */
-
-	int reset_on_keychange;	/* Set to 1 if the HW needs to be reset on
-				 * WEP key changes */
-
-	/* If the host performs {en,de}cryption, then set to 1 */
-	int host_encrypt;
-	int host_encrypt_msdu;
-	int host_decrypt;
-	/* host performs multicast decryption */
-	int host_mc_decrypt;
-
-	/* host should strip IV and ICV from protected frames */
-	/* meaningful only when hardware decryption is being used */
-	int host_strip_iv_icv;
-
-	int host_open_frag;
-	int host_build_iv;
-	int ieee802_1x;		/* is IEEE 802.1X used */
-
-	/* WPA data */
-	int wpa_enabled;
-	int drop_unencrypted;
-	int privacy_invoked;
-	size_t wpa_ie_len;
-	u8 *wpa_ie;
-
-	struct lib80211_crypt_info crypt_info;
-
-	int bcrx_sta_key;	/* use individual keys to override default keys even
-				 * with RX of broad/multicast frames */
-
-	/* Fragmentation structures */
-	struct ieee80211_frag_entry frag_cache[IEEE80211_FRAG_CACHE_LEN];
-	unsigned int frag_next_idx;
-	u16 fts;		/* Fragmentation Threshold */
-	u16 rts;		/* RTS threshold */
-
-	/* Association info */
-	u8 bssid[ETH_ALEN];
-
-	enum ieee80211_state state;
-
-	int mode;		/* A, B, G */
-	int modulation;		/* CCK, OFDM */
-	int freq_band;		/* 2.4Ghz, 5.2Ghz, Mixed */
-	int abg_true;		/* ABG flag              */
-
-	int perfect_rssi;
-	int worst_rssi;
-
-	u16 prev_seq_ctl;	/* used to drop duplicate frames */
-
-	/* Callback functions */
-	void (*set_security) (struct net_device * dev,
-			      struct ieee80211_security * sec);
-	int (*hard_start_xmit) (struct ieee80211_txb * txb,
-				struct net_device * dev, int pri);
-	int (*reset_port) (struct net_device * dev);
-	int (*is_queue_full) (struct net_device * dev, int pri);
-
-	int (*handle_management) (struct net_device * dev,
-				  struct ieee80211_network * network, u16 type);
-	int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
-
-	/* Typical STA methods */
-	int (*handle_auth) (struct net_device * dev,
-			    struct ieee80211_auth * auth);
-	int (*handle_deauth) (struct net_device * dev,
-			      struct ieee80211_deauth * auth);
-	int (*handle_action) (struct net_device * dev,
-			      struct ieee80211_action * action,
-			      struct ieee80211_rx_stats * stats);
-	int (*handle_disassoc) (struct net_device * dev,
-				struct ieee80211_disassoc * assoc);
-	int (*handle_beacon) (struct net_device * dev,
-			      struct ieee80211_beacon * beacon,
-			      struct ieee80211_network * network);
-	int (*handle_probe_response) (struct net_device * dev,
-				      struct ieee80211_probe_response * resp,
-				      struct ieee80211_network * network);
-	int (*handle_probe_request) (struct net_device * dev,
-				     struct ieee80211_probe_request * req,
-				     struct ieee80211_rx_stats * stats);
-	int (*handle_assoc_response) (struct net_device * dev,
-				      struct ieee80211_assoc_response * resp,
-				      struct ieee80211_network * network);
-
-	/* Typical AP methods */
-	int (*handle_assoc_request) (struct net_device * dev);
-	int (*handle_reassoc_request) (struct net_device * dev,
-				       struct ieee80211_reassoc_request * req);
-
-	/* This must be the last item so that it points to the data
-	 * allocated beyond this structure by alloc_ieee80211 */
-	u8 priv[0];
-};
-
-#define IEEE_A            (1<<0)
-#define IEEE_B            (1<<1)
-#define IEEE_G            (1<<2)
-#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
-	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-}
-
-static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee,
-					  int mode)
-{
-	/*
-	 * It is possible for both access points and our device to support
-	 * combinations of modes, so as long as there is one valid combination
-	 * of ap/device supported modes, then return success
-	 *
-	 */
-	if ((mode & IEEE_A) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_G) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_B) &&
-	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	return 0;
-}
-
-static inline int ieee80211_get_hdrlen(u16 fc)
-{
-	int hdrlen = IEEE80211_3ADDR_LEN;
-	u16 stype = WLAN_FC_GET_STYPE(fc);
-
-	switch (WLAN_FC_GET_TYPE(fc)) {
-	case IEEE80211_FTYPE_DATA:
-		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-			hdrlen = IEEE80211_4ADDR_LEN;
-		if (stype & IEEE80211_STYPE_QOS_DATA)
-			hdrlen += 2;
-		break;
-	case IEEE80211_FTYPE_CTL:
-		switch (WLAN_FC_GET_STYPE(fc)) {
-		case IEEE80211_STYPE_CTS:
-		case IEEE80211_STYPE_ACK:
-			hdrlen = IEEE80211_1ADDR_LEN;
-			break;
-		default:
-			hdrlen = IEEE80211_2ADDR_LEN;
-			break;
-		}
-		break;
-	}
-
-	return hdrlen;
-}
-
-static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
-{
-	switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control))) {
-	case IEEE80211_1ADDR_LEN:
-		return ((struct ieee80211_hdr_1addr *)hdr)->payload;
-	case IEEE80211_2ADDR_LEN:
-		return ((struct ieee80211_hdr_2addr *)hdr)->payload;
-	case IEEE80211_3ADDR_LEN:
-		return ((struct ieee80211_hdr_3addr *)hdr)->payload;
-	case IEEE80211_4ADDR_LEN:
-		return ((struct ieee80211_hdr_4addr *)hdr)->payload;
-	}
-	return NULL;
-}
-
-static inline int ieee80211_is_ofdm_rate(u8 rate)
-{
-	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
-	case IEEE80211_OFDM_RATE_6MB:
-	case IEEE80211_OFDM_RATE_9MB:
-	case IEEE80211_OFDM_RATE_12MB:
-	case IEEE80211_OFDM_RATE_18MB:
-	case IEEE80211_OFDM_RATE_24MB:
-	case IEEE80211_OFDM_RATE_36MB:
-	case IEEE80211_OFDM_RATE_48MB:
-	case IEEE80211_OFDM_RATE_54MB:
-		return 1;
-	}
-	return 0;
-}
-
-static inline int ieee80211_is_cck_rate(u8 rate)
-{
-	switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
-	case IEEE80211_CCK_RATE_1MB:
-	case IEEE80211_CCK_RATE_2MB:
-	case IEEE80211_CCK_RATE_5MB:
-	case IEEE80211_CCK_RATE_11MB:
-		return 1;
-	}
-	return 0;
-}
-
-/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
-extern int ieee80211_change_mtu(struct net_device *dev, int new_mtu);
-
-extern void ieee80211_networks_age(struct ieee80211_device *ieee,
-				   unsigned long age_secs);
-
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-/* ieee80211_rx.c */
-extern void ieee80211_rx_any(struct ieee80211_device *ieee,
-		     struct sk_buff *skb, struct ieee80211_rx_stats *stats);
-extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-			struct ieee80211_rx_stats *rx_stats);
-/* make sure to set stats->len */
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-			     struct ieee80211_hdr_4addr *header,
-			     struct ieee80211_rx_stats *stats);
-extern void ieee80211_network_reset(struct ieee80211_network *network);
-
-/* ieee80211_geo.c */
-extern const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device
-						     *ieee);
-extern int ieee80211_set_geo(struct ieee80211_device *ieee,
-			     const struct ieee80211_geo *geo);
-
-extern int ieee80211_is_valid_channel(struct ieee80211_device *ieee,
-				      u8 channel);
-extern int ieee80211_channel_to_index(struct ieee80211_device *ieee,
-				      u8 channel);
-extern u8 ieee80211_freq_to_channel(struct ieee80211_device *ieee, u32 freq);
-extern u8 ieee80211_get_channel_flags(struct ieee80211_device *ieee,
-				      u8 channel);
-extern const struct ieee80211_channel *ieee80211_get_channel(struct
-							     ieee80211_device
-							     *ieee, u8 channel);
-extern u32 ieee80211_channel_to_freq(struct ieee80211_device * ieee,
-				      u8 channel);
-
-/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
-				      struct iw_request_info *info,
-				      union iwreq_data *wrqu, char *extra);
-extern int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
-				      struct iw_request_info *info,
-				      union iwreq_data *wrqu, char *extra);
-
-static inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
-	ieee->scans++;
-}
-
-static inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
-	return ieee->scans;
-}
-
-#endif				/* IEEE80211_H */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 7424323..240cff1 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -19,7 +19,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
   Portions of this file are based on the sample_* files provided by Wireless
@@ -185,7 +185,7 @@ MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
 static int debug = 0;
-static int mode = 0;
+static int network_mode = 0;
 static int channel = 0;
 static int associate = 0;
 static int disable = 0;
@@ -195,7 +195,7 @@ static struct ipw2100_fw ipw2100_firmware;
 
 #include <linux/moduleparam.h>
 module_param(debug, int, 0444);
-module_param(mode, int, 0444);
+module_param_named(mode, network_mode, int, 0444);
 module_param(channel, int, 0444);
 module_param(associate, int, 0444);
 module_param(disable, int, 0444);
@@ -1673,7 +1673,7 @@ static int ipw2100_start_scan(struct ipw2100_priv *priv)
 	return err;
 }
 
-static const struct ieee80211_geo ipw_geos[] = {
+static const struct libipw_geo ipw_geos[] = {
 	{			/* Restricted */
 	 "---",
 	 .bg_channels = 14,
@@ -1694,7 +1694,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 
 	/* Age scan list entries found before suspend */
 	if (priv->suspend_time) {
-		ieee80211_networks_age(priv->ieee, priv->suspend_time);
+		libipw_networks_age(priv->ieee, priv->suspend_time);
 		priv->suspend_time = 0;
 	}
 
@@ -1752,11 +1752,11 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 	}
 
 	/* Initialize the geo */
-	if (ieee80211_set_geo(priv->ieee, &ipw_geos[0])) {
+	if (libipw_set_geo(priv->ieee, &ipw_geos[0])) {
 		printk(KERN_WARNING DRV_NAME "Could not set geo\n");
 		return 0;
 	}
-	priv->ieee->freq_band = IEEE80211_24GHZ_BAND;
+	priv->ieee->freq_band = LIBIPW_24GHZ_BAND;
 
 	lock = LOCK_NONE;
 	if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
@@ -1817,7 +1817,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 /* Called by register_netdev() */
 static int ipw2100_net_init(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	return ipw2100_up(priv, 1);
 }
 
@@ -2340,8 +2340,8 @@ static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
  *
  * When packet is provided by the firmware, it contains the following:
  *
- * .  ieee80211_hdr
- * .  ieee80211_snap_hdr
+ * .  libipw_hdr
+ * .  libipw_snap_hdr
  *
  * The size of the constructed ethernet
  *
@@ -2396,7 +2396,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 }
 
 static void isr_rx(struct ipw2100_priv *priv, int i,
-			  struct ieee80211_rx_stats *stats)
+			  struct libipw_rx_stats *stats)
 {
 	struct net_device *dev = priv->net_dev;
 	struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2435,13 +2435,13 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
 
 #ifdef IPW2100_RX_DEBUG
 	/* Make a copy of the frame so we can dump it to the logs if
-	 * ieee80211_rx fails */
+	 * libipw_rx fails */
 	skb_copy_from_linear_data(packet->skb, packet_data,
 				  min_t(u32, status->frame_size,
 					     IPW_RX_NIC_BUFFER_LENGTH));
 #endif
 
-	if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
+	if (!libipw_rx(priv->ieee, packet->skb, stats)) {
 #ifdef IPW2100_RX_DEBUG
 		IPW_DEBUG_DROP("%s: Non consumed packet:\n",
 			       dev->name);
@@ -2449,7 +2449,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
 #endif
 		dev->stats.rx_errors++;
 
-		/* ieee80211_rx failed, so it didn't free the SKB */
+		/* libipw_rx failed, so it didn't free the SKB */
 		dev_kfree_skb_any(packet->skb);
 		packet->skb = NULL;
 	}
@@ -2470,7 +2470,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
 #ifdef CONFIG_IPW2100_MONITOR
 
 static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
-		   struct ieee80211_rx_stats *stats)
+		   struct libipw_rx_stats *stats)
 {
 	struct net_device *dev = priv->net_dev;
 	struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2528,10 +2528,10 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
 
 	skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr));
 
-	if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
+	if (!libipw_rx(priv->ieee, packet->skb, stats)) {
 		dev->stats.rx_errors++;
 
-		/* ieee80211_rx failed, so it didn't free the SKB */
+		/* libipw_rx failed, so it didn't free the SKB */
 		dev_kfree_skb_any(packet->skb);
 		packet->skb = NULL;
 	}
@@ -2615,7 +2615,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 	u16 frame_type;
 	u32 r, w, i, s;
 	struct ipw2100_rx *u;
-	struct ieee80211_rx_stats stats = {
+	struct libipw_rx_stats stats = {
 		.mac_time = jiffies,
 	};
 
@@ -2661,8 +2661,8 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 
 		stats.mask = 0;
 		if (stats.rssi != 0)
-			stats.mask |= IEEE80211_STATMASK_RSSI;
-		stats.freq = IEEE80211_24GHZ_BAND;
+			stats.mask |= LIBIPW_STATMASK_RSSI;
+		stats.freq = LIBIPW_24GHZ_BAND;
 
 		IPW_DEBUG_RX("%s: '%s' frame type received (%d).\n",
 			     priv->net_dev->name, frame_types[frame_type],
@@ -2686,11 +2686,11 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 				break;
 			}
 #endif
-			if (stats.len < sizeof(struct ieee80211_hdr_3addr))
+			if (stats.len < sizeof(struct libipw_hdr_3addr))
 				break;
 			switch (WLAN_FC_GET_TYPE(le16_to_cpu(u->rx_data.header.frame_ctl))) {
 			case IEEE80211_FTYPE_MGMT:
-				ieee80211_rx_mgt(priv->ieee,
+				libipw_rx_mgt(priv->ieee,
 						 &u->rx_data.header, &stats);
 				break;
 
@@ -2844,7 +2844,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
 
 #ifdef CONFIG_IPW2100_DEBUG
 	{
-		int i = txq->oldest;
+		i = txq->oldest;
 		IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
 			     &txq->drv[i],
 			     (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
@@ -2884,7 +2884,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
 					 tbd->buf_length, PCI_DMA_TODEVICE);
 		}
 
-		ieee80211_txb_free(packet->info.d_struct.txb);
+		libipw_txb_free(packet->info.d_struct.txb);
 		packet->info.d_struct.txb = NULL;
 
 		list_add_tail(element, &priv->tx_free_list);
@@ -3028,7 +3028,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
 	int next = txq->next;
 	int i = 0;
 	struct ipw2100_data_header *ipw_hdr;
-	struct ieee80211_hdr_3addr *hdr;
+	struct libipw_hdr_3addr *hdr;
 
 	while (!list_empty(&priv->tx_pend_list)) {
 		/* if there isn't enough space in TBD queue, then
@@ -3062,7 +3062,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
 		packet->index = txq->next;
 
 		ipw_hdr = packet->info.d_struct.data;
-		hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
+		hdr = (struct libipw_hdr_3addr *)packet->info.d_struct.txb->
 		    fragments[0]->data;
 
 		if (priv->ieee->iw_mode == IW_MODE_INFRA) {
@@ -3086,7 +3086,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
 		if (packet->info.d_struct.txb->nr_frags > 1)
 			ipw_hdr->fragment_size =
 			    packet->info.d_struct.txb->frag_size -
-			    IEEE80211_3ADDR_LEN;
+			    LIBIPW_3ADDR_LEN;
 		else
 			ipw_hdr->fragment_size = 0;
 
@@ -3119,13 +3119,13 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
 				    IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
 
 			tbd->buf_length = packet->info.d_struct.txb->
-			    fragments[i]->len - IEEE80211_3ADDR_LEN;
+			    fragments[i]->len - LIBIPW_3ADDR_LEN;
 
 			tbd->host_addr = pci_map_single(priv->pci_dev,
 							packet->info.d_struct.
 							txb->fragments[i]->
 							data +
-							IEEE80211_3ADDR_LEN,
+							LIBIPW_3ADDR_LEN,
 							tbd->buf_length,
 							PCI_DMA_TODEVICE);
 
@@ -3330,10 +3330,10 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data)
 	return IRQ_NONE;
 }
 
-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
-		      int pri)
+static netdev_tx_t ipw2100_tx(struct libipw_txb *txb,
+			      struct net_device *dev, int pri)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	struct list_head *element;
 	struct ipw2100_tx_packet *packet;
 	unsigned long flags;
@@ -3369,12 +3369,12 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
 	ipw2100_tx_send_data(priv);
 
 	spin_unlock_irqrestore(&priv->low_lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 
-      fail_unlock:
+fail_unlock:
 	netif_stop_queue(dev);
 	spin_unlock_irqrestore(&priv->low_lock, flags);
-	return 1;
+	return NETDEV_TX_BUSY;
 }
 
 static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
@@ -4488,7 +4488,7 @@ static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
 		/* We simply drop any SKBs that have been queued for
 		 * transmit */
 		if (priv->tx_buffers[i].info.d_struct.txb) {
-			ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
+			libipw_txb_free(priv->tx_buffers[i].info.d_struct.
 					   txb);
 			priv->tx_buffers[i].info.d_struct.txb = NULL;
 		}
@@ -4527,7 +4527,7 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
 
 	for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
 		if (priv->tx_buffers[i].info.d_struct.txb) {
-			ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
+			libipw_txb_free(priv->tx_buffers[i].info.d_struct.
 					   txb);
 			priv->tx_buffers[i].info.d_struct.txb = NULL;
 		}
@@ -5558,9 +5558,9 @@ static void ipw2100_security_work(struct work_struct *work)
 }
 
 static void shim__set_security(struct net_device *dev,
-			       struct ieee80211_security *sec)
+			       struct libipw_security *sec)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int i, force_update = 0;
 
 	mutex_lock(&priv->action_mutex);
@@ -5753,7 +5753,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
  * method as well) to talk to the firmware */
 static int ipw2100_set_address(struct net_device *dev, void *p)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	struct sockaddr *addr = p;
 	int err = 0;
 
@@ -5781,7 +5781,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
 
 static int ipw2100_open(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	unsigned long flags;
 	IPW_DEBUG_INFO("dev->open\n");
 
@@ -5797,7 +5797,7 @@ static int ipw2100_open(struct net_device *dev)
 
 static int ipw2100_close(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	unsigned long flags;
 	struct list_head *element;
 	struct ipw2100_tx_packet *packet;
@@ -5818,7 +5818,7 @@ static int ipw2100_close(struct net_device *dev)
 		list_del(element);
 		DEC_STAT(&priv->tx_pend_stat);
 
-		ieee80211_txb_free(packet->info.d_struct.txb);
+		libipw_txb_free(packet->info.d_struct.txb);
 		packet->info.d_struct.txb = NULL;
 
 		list_add_tail(element, &priv->tx_free_list);
@@ -5836,7 +5836,7 @@ static int ipw2100_close(struct net_device *dev)
  */
 static void ipw2100_tx_timeout(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	dev->stats.tx_errors++;
 
@@ -5861,8 +5861,8 @@ static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
 static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
 {
 
-	struct ieee80211_device *ieee = priv->ieee;
-	struct ieee80211_security sec = {
+	struct libipw_device *ieee = priv->ieee;
+	struct libipw_security sec = {
 		.flags = SEC_AUTH_MODE,
 	};
 	int ret = 0;
@@ -5907,7 +5907,7 @@ static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 				    struct ethtool_drvinfo *info)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	char fw_ver[64], ucode_ver[64];
 
 	strcpy(info->driver, DRV_NAME);
@@ -5924,7 +5924,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 
 static u32 ipw2100_ethtool_get_link(struct net_device *dev)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
 }
 
@@ -6011,8 +6011,8 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
 static const struct net_device_ops ipw2100_netdev_ops = {
 	.ndo_open		= ipw2100_open,
 	.ndo_stop		= ipw2100_close,
-	.ndo_start_xmit		= ieee80211_xmit,
-	.ndo_change_mtu		= ieee80211_change_mtu,
+	.ndo_start_xmit		= libipw_xmit,
+	.ndo_change_mtu		= libipw_change_mtu,
 	.ndo_init		= ipw2100_net_init,
 	.ndo_tx_timeout		= ipw2100_tx_timeout,
 	.ndo_set_mac_address	= ipw2100_set_address,
@@ -6029,10 +6029,10 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
 	struct ipw2100_priv *priv;
 	struct net_device *dev;
 
-	dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
+	dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0);
 	if (!dev)
 		return NULL;
-	priv = ieee80211_priv(dev);
+	priv = libipw_priv(dev);
 	priv->ieee = netdev_priv(dev);
 	priv->pci_dev = pci_dev;
 	priv->net_dev = dev;
@@ -6046,7 +6046,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
 	dev->netdev_ops = &ipw2100_netdev_ops;
 	dev->ethtool_ops = &ipw2100_ethtool_ops;
 	dev->wireless_handlers = &ipw2100_wx_handler_def;
-	priv->wireless_data.ieee80211 = priv->ieee;
+	priv->wireless_data.libipw = priv->ieee;
 	dev->wireless_data = &priv->wireless_data;
 	dev->watchdog_timeo = 3 * HZ;
 	dev->irq = 0;
@@ -6076,7 +6076,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
 	priv->ieee->ieee802_1x = 1;
 
 	/* Set module parameters */
-	switch (mode) {
+	switch (network_mode) {
 	case 1:
 		priv->ieee->iw_mode = IW_MODE_ADHOC;
 		break;
@@ -6202,7 +6202,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
 		return err;
 	}
 
-	priv = ieee80211_priv(dev);
+	priv = libipw_priv(dev);
 
 	pci_set_master(pci_dev);
 	pci_set_drvdata(pci_dev, priv);
@@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
 		sysfs_remove_group(&pci_dev->dev.kobj,
 				   &ipw2100_attribute_group);
 
-		free_ieee80211(dev);
+		free_ieee80211(dev, 0);
 		pci_set_drvdata(pci_dev, NULL);
 	}
 
@@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
 		if (dev->base_addr)
 			iounmap((void __iomem *)dev->base_addr);
 
-		free_ieee80211(dev);
+		free_ieee80211(dev, 0);
 	}
 
 	pci_release_regions(pci_dev);
@@ -6629,7 +6629,7 @@ static int ipw2100_wx_get_name(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	if (!(priv->status & STATUS_ASSOCIATED))
 		strcpy(wrqu->name, "unassociated");
 	else
@@ -6643,7 +6643,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	struct iw_freq *fwrq = &wrqu->freq;
 	int err = 0;
 
@@ -6693,7 +6693,7 @@ static int ipw2100_wx_get_freq(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	wrqu->freq.e = 0;
 
@@ -6714,7 +6714,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode);
@@ -6757,7 +6757,7 @@ static int ipw2100_wx_get_mode(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	wrqu->mode = priv->ieee->iw_mode;
 	IPW_DEBUG_WX("GET Mode -> %d\n", wrqu->mode);
@@ -6792,7 +6792,7 @@ static int ipw2100_wx_get_range(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	struct iw_range *range = (struct iw_range *)extra;
 	u16 val;
 	int i, level;
@@ -6913,7 +6913,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
 			      struct iw_request_info *info,
 			      union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	static const unsigned char any[] = {
@@ -6962,7 +6962,7 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	/* If we are associated, trying to associate, or have a statically
 	 * configured BSSID then return that; otherwise return ANY */
@@ -6980,7 +6980,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	char *essid = "";	/* ANY */
 	int length = 0;
 	int err = 0;
@@ -7035,7 +7035,7 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	DECLARE_SSID_BUF(ssid);
 
 	/* If we are associated, trying to associate, or have a statically
@@ -7063,7 +7063,7 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE)
 		return -E2BIG;
@@ -7085,7 +7085,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	wrqu->data.length = strlen(priv->nick);
 	memcpy(extra, priv->nick, wrqu->data.length);
@@ -7100,7 +7100,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	u32 target_rate = wrqu->bitrate.value;
 	u32 rate;
 	int err = 0;
@@ -7140,7 +7140,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int val;
 	unsigned int len = sizeof(val);
 	int err = 0;
@@ -7192,7 +7192,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
 			      struct iw_request_info *info,
 			      union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int value, err;
 
 	/* Auto RTS not yet supported */
@@ -7231,7 +7231,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
 	wrqu->rts.fixed = 1;	/* no auto select */
@@ -7248,7 +7248,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err = 0, value;
 	
 	if (ipw_radio_kill_sw(priv, wrqu->txpower.disabled))
@@ -7293,7 +7293,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	wrqu->txpower.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
 
@@ -7320,7 +7320,7 @@ static int ipw2100_wx_set_frag(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	if (!wrqu->frag.fixed)
 		return -EINVAL;
@@ -7350,7 +7350,7 @@ static int ipw2100_wx_get_frag(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	wrqu->frag.value = priv->frag_threshold & ~FRAG_DISABLED;
 	wrqu->frag.fixed = 0;	/* no auto select */
 	wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
@@ -7364,7 +7364,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
@@ -7412,7 +7412,7 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	wrqu->retry.disabled = 0;	/* can't be disabled */
 
@@ -7440,7 +7440,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	mutex_lock(&priv->action_mutex);
@@ -7472,8 +7472,8 @@ static int ipw2100_wx_get_scan(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	return libipw_wx_get_scan(priv->ieee, info, wrqu, extra);
 }
 
 /*
@@ -7487,8 +7487,8 @@ static int ipw2100_wx_set_encode(struct net_device *dev,
 	 * No check of STATUS_INITIALIZED required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	return libipw_wx_set_encode(priv->ieee, info, wrqu, key);
 }
 
 static int ipw2100_wx_get_encode(struct net_device *dev,
@@ -7499,15 +7499,15 @@ static int ipw2100_wx_get_encode(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	return libipw_wx_get_encode(priv->ieee, info, wrqu, key);
 }
 
 static int ipw2100_wx_set_power(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	mutex_lock(&priv->action_mutex);
@@ -7556,7 +7556,7 @@ static int ipw2100_wx_get_power(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
@@ -7580,8 +7580,8 @@ static int ipw2100_wx_set_genie(struct net_device *dev,
 				union iwreq_data *wrqu, char *extra)
 {
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 	u8 *buf;
 
 	if (!ieee->wpa_enabled)
@@ -7615,8 +7615,8 @@ static int ipw2100_wx_get_genie(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 
 	if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
 		wrqu->data.length = 0;
@@ -7637,8 +7637,8 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 	struct iw_param *param = &wrqu->param;
 	struct lib80211_crypt_data *crypt;
 	unsigned long flags;
@@ -7682,7 +7682,7 @@ static int ipw2100_wx_set_auth(struct net_device *dev,
 			 * can use this to determine if the CAP_PRIVACY_ON bit should
 			 * be set.
 			 */
-			struct ieee80211_security sec = {
+			struct libipw_security sec = {
 				.flags = SEC_ENABLED,
 				.enabled = param->value,
 			};
@@ -7730,8 +7730,8 @@ static int ipw2100_wx_get_auth(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 	struct lib80211_crypt_data *crypt;
 	struct iw_param *param = &wrqu->param;
 	int ret = 0;
@@ -7792,8 +7792,8 @@ static int ipw2100_wx_set_encodeext(struct net_device *dev,
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	return libipw_wx_set_encodeext(priv->ieee, info, wrqu, extra);
 }
 
 /* SIOCGIWENCODEEXT */
@@ -7801,8 +7801,8 @@ static int ipw2100_wx_get_encodeext(struct net_device *dev,
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
+	struct ipw2100_priv *priv = libipw_priv(dev);
+	return libipw_wx_get_encodeext(priv->ieee, info, wrqu, extra);
 }
 
 /* SIOCSIWMLME */
@@ -7810,7 +7810,7 @@ static int ipw2100_wx_set_mlme(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
 	__le16 reason;
 
@@ -7841,7 +7841,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int *parms = (int *)extra;
 	int enable = (parms[0] > 0);
 	int err = 0;
@@ -7872,7 +7872,7 @@ static int ipw2100_wx_reset(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	if (priv->status & STATUS_INITIALIZED)
 		schedule_reset(priv);
 	return 0;
@@ -7884,7 +7884,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err = 0, mode = *(int *)extra;
 
 	mutex_lock(&priv->action_mutex);
@@ -7912,7 +7912,7 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int level = IPW_POWER_LEVEL(priv->power_mode);
 	s32 timeout, period;
 
@@ -7948,7 +7948,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err, mode = *(int *)extra;
 
 	mutex_lock(&priv->action_mutex);
@@ -7981,7 +7981,7 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	if (priv->config & CFG_LONG_PREAMBLE)
 		snprintf(wrqu->name, IFNAMSIZ, "long (1)");
@@ -7996,7 +7996,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev,
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	int err, mode = *(int *)extra;
 
 	mutex_lock(&priv->action_mutex);
@@ -8028,7 +8028,7 @@ static int ipw2100_wx_get_crc_check(struct net_device *dev,
 	 * This can be called at any time.  No action lock required
 	 */
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 
 	if (priv->config & CFG_CRC_CHECK)
 		snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
@@ -8179,10 +8179,11 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
 	int rssi_qual;
 	int tx_qual;
 	int beacon_qual;
+	int quality;
 
-	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ipw2100_priv *priv = libipw_priv(dev);
 	struct iw_statistics *wstats;
-	u32 rssi, quality, tx_retries, missed_beacons, tx_failures;
+	u32 rssi, tx_retries, missed_beacons, tx_failures;
 	u32 ord_len = sizeof(u32);
 
 	if (!priv)
@@ -8265,7 +8266,8 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
 			beacon_qual = (20 - missed_beacons) *
 			    (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
 
-		quality = min(beacon_qual, min(tx_qual, rssi_qual));
+		quality = min(tx_qual, rssi_qual);
+		quality = min(beacon_qual, quality);
 
 #ifdef CONFIG_IPW2100_DEBUG
 		if (beacon_qual == quality)
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index f183d95..1eab0d6 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
@@ -19,7 +19,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 ******************************************************************************/
@@ -46,7 +46,7 @@
 #include <linux/workqueue.h>
 #include <linux/mutex.h>
 
-#include "ieee80211.h"
+#include "libipw.h"
 
 struct ipw2100_priv;
 struct ipw2100_tx_packet;
@@ -343,7 +343,7 @@ struct ipw2100_tx_packet {
 		struct {	/* DATA */
 			struct ipw2100_data_header *data;
 			dma_addr_t data_phys;
-			struct ieee80211_txb *txb;
+			struct libipw_txb *txb;
 		} d_struct;
 	} info;
 	int jiffy_start;
@@ -492,7 +492,7 @@ struct ipw2100_priv {
 	int stop_hang_check;	/* Set 1 when shutting down to kill hang_check */
 	int stop_rf_kill;	/* Set 1 when shutting down to kill rf_kill */
 
-	struct ieee80211_device *ieee;
+	struct libipw_device *ieee;
 	unsigned long status;
 	unsigned long config;
 	unsigned long capability;
@@ -788,7 +788,7 @@ struct ipw2100_priv {
 #define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT	    100	// 100 milli
 #define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT	    100	// 100 milli
 
-#define IPW_HEADER_802_11_SIZE		 sizeof(struct ieee80211_hdr_3addr)
+#define IPW_HEADER_802_11_SIZE		 sizeof(struct libipw_hdr_3addr)
 #define IPW_MAX_80211_PAYLOAD_SIZE              2304U
 #define IPW_MAX_802_11_PAYLOAD_LENGTH		2312
 #define IPW_MAX_ACCEPTABLE_TX_FRAME_LENGTH	1536
@@ -803,13 +803,13 @@ struct ipw2100_priv {
 		IPW_802_11_FCS_LENGTH)
 
 #define IPW_802_11_PAYLOAD_OFFSET \
-        (sizeof(struct ieee80211_hdr_3addr) + \
-         sizeof(struct ieee80211_snap_hdr))
+        (sizeof(struct libipw_hdr_3addr) + \
+         sizeof(struct libipw_snap_hdr))
 
 struct ipw2100_rx {
 	union {
 		unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
-		struct ieee80211_hdr_4addr header;
+		struct libipw_hdr_4addr header;
 		u32 status;
 		struct ipw2100_notification notification;
 		struct ipw2100_cmd_header command;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index f593fbb..8d58e6e 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -25,7 +25,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 ******************************************************************************/
@@ -83,13 +83,13 @@ MODULE_LICENSE("GPL");
 
 static int cmdlog = 0;
 static int debug = 0;
-static int channel = 0;
-static int mode = 0;
+static int default_channel = 0;
+static int network_mode = 0;
 
 static u32 ipw_debug_level;
 static int associate;
 static int auto_create = 1;
-static int led = 0;
+static int led_support = 0;
 static int disable = 0;
 static int bt_coexist = 0;
 static int hwcrypto = 0;
@@ -103,6 +103,25 @@ static int antenna = CFG_SYS_ANTENNA_BOTH;
 static int rtap_iface = 0;     /* def: 0 -- do not create rtap interface */
 #endif
 
+static struct ieee80211_rate ipw2200_rates[] = {
+	{ .bitrate = 10 },
+	{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 60 },
+	{ .bitrate = 90 },
+	{ .bitrate = 120 },
+	{ .bitrate = 180 },
+	{ .bitrate = 240 },
+	{ .bitrate = 360 },
+	{ .bitrate = 480 },
+	{ .bitrate = 540 }
+};
+
+#define ipw2200_a_rates		(ipw2200_rates + 4)
+#define ipw2200_num_a_rates	8
+#define ipw2200_bg_rates	(ipw2200_rates + 0)
+#define ipw2200_num_bg_rates	12
 
 #ifdef CONFIG_IPW2200_QOS
 static int qos_enable = 0;
@@ -111,7 +130,7 @@ static int qos_no_ack_mask = 0;
 static int burst_duration_CCK = 0;
 static int burst_duration_OFDM = 0;
 
-static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
+static struct libipw_qos_parameters def_qos_parameters_OFDM = {
 	{QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
 	 QOS_TX3_CW_MIN_OFDM},
 	{QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
@@ -122,7 +141,7 @@ static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
 	 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
 };
 
-static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
+static struct libipw_qos_parameters def_qos_parameters_CCK = {
 	{QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
 	 QOS_TX3_CW_MIN_CCK},
 	{QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
@@ -133,7 +152,7 @@ static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
 	 QOS_TX3_TXOP_LIMIT_CCK}
 };
 
-static struct ieee80211_qos_parameters def_parameters_OFDM = {
+static struct libipw_qos_parameters def_parameters_OFDM = {
 	{DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
 	 DEF_TX3_CW_MIN_OFDM},
 	{DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
@@ -144,7 +163,7 @@ static struct ieee80211_qos_parameters def_parameters_OFDM = {
 	 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
 };
 
-static struct ieee80211_qos_parameters def_parameters_CCK = {
+static struct libipw_qos_parameters def_parameters_CCK = {
 	{DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
 	 DEF_TX3_CW_MIN_CCK},
 	{DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
@@ -164,9 +183,9 @@ static int from_priority_to_tx_queue[] = {
 
 static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
 
-static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
+static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters
 				       *qos_param);
-static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
+static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element
 				     *qos_param);
 #endif				/* CONFIG_IPW2200_QOS */
 
@@ -1830,7 +1849,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
 			break;
 		}
 
-		if (ieee80211_is_valid_channel(priv->ieee, channel))
+		if (libipw_is_valid_channel(priv->ieee, channel))
 			priv->speed_scan[pos++] = channel;
 		else
 			IPW_WARNING("Skipping invalid channel request: %d\n",
@@ -1882,7 +1901,7 @@ static ssize_t show_channels(struct device *d,
 			     char *buf)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
 	int len = 0, i;
 
 	len = sprintf(&buf[len],
@@ -1892,14 +1911,14 @@ static ssize_t show_channels(struct device *d,
 	for (i = 0; i < geo->bg_channels; i++) {
 		len += sprintf(&buf[len], "%d: BSS%s%s, %s, Band %s.\n",
 			       geo->bg[i].channel,
-			       geo->bg[i].flags & IEEE80211_CH_RADAR_DETECT ?
+			       geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT ?
 			       " (radar spectrum)" : "",
-			       ((geo->bg[i].flags & IEEE80211_CH_NO_IBSS) ||
-				(geo->bg[i].flags & IEEE80211_CH_RADAR_DETECT))
+			       ((geo->bg[i].flags & LIBIPW_CH_NO_IBSS) ||
+				(geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT))
 			       ? "" : ", IBSS",
-			       geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY ?
+			       geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY ?
 			       "passive only" : "active/passive",
-			       geo->bg[i].flags & IEEE80211_CH_B_ONLY ?
+			       geo->bg[i].flags & LIBIPW_CH_B_ONLY ?
 			       "B" : "B/G");
 	}
 
@@ -1909,12 +1928,12 @@ static ssize_t show_channels(struct device *d,
 	for (i = 0; i < geo->a_channels; i++) {
 		len += sprintf(&buf[len], "%d: BSS%s%s, %s.\n",
 			       geo->a[i].channel,
-			       geo->a[i].flags & IEEE80211_CH_RADAR_DETECT ?
+			       geo->a[i].flags & LIBIPW_CH_RADAR_DETECT ?
 			       " (radar spectrum)" : "",
-			       ((geo->a[i].flags & IEEE80211_CH_NO_IBSS) ||
-				(geo->a[i].flags & IEEE80211_CH_RADAR_DETECT))
+			       ((geo->a[i].flags & LIBIPW_CH_NO_IBSS) ||
+				(geo->a[i].flags & LIBIPW_CH_RADAR_DETECT))
 			       ? "" : ", IBSS",
-			       geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY ?
+			       geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY ?
 			       "passive only" : "active/passive");
 	}
 
@@ -2429,7 +2448,7 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
 
 static int ipw_set_tx_power(struct ipw_priv *priv)
 {
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
 	struct ipw_tx_power tx_power;
 	s8 max_power;
 	int i;
@@ -2942,12 +2961,12 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
 static void ipw_remove_current_network(struct ipw_priv *priv)
 {
 	struct list_head *element, *safe;
-	struct ieee80211_network *network = NULL;
+	struct libipw_network *network = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->ieee->lock, flags);
 	list_for_each_safe(element, safe, &priv->ieee->network_list) {
-		network = list_entry(element, struct ieee80211_network, list);
+		network = list_entry(element, struct libipw_network, list);
 		if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
 			list_del(element);
 			list_add_tail(&network->list,
@@ -3765,7 +3784,7 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
 				 le16_to_cpu(bd->u.data.chunk_len[i]),
 				 PCI_DMA_TODEVICE);
 		if (txq->txb[txq->q.last_used]) {
-			ieee80211_txb_free(txq->txb[txq->q.last_used]);
+			libipw_txb_free(txq->txb[txq->q.last_used]);
 			txq->txb[txq->q.last_used] = NULL;
 		}
 	}
@@ -4084,7 +4103,7 @@ static u32 ipw_get_max_rate(struct ipw_priv *priv)
 	/* If currently associated in B mode, restrict the maximum
 	 * rate match to B rates */
 	if (priv->assoc_request.ieee_mode == IPW_B_MODE)
-		mask &= IEEE80211_CCK_RATES_MASK;
+		mask &= LIBIPW_CCK_RATES_MASK;
 
 	/* TODO: Verify that the rate is supported by the current rates
 	 * list. */
@@ -4092,29 +4111,29 @@ static u32 ipw_get_max_rate(struct ipw_priv *priv)
 	while (i && !(mask & i))
 		i >>= 1;
 	switch (i) {
-	case IEEE80211_CCK_RATE_1MB_MASK:
+	case LIBIPW_CCK_RATE_1MB_MASK:
 		return 1000000;
-	case IEEE80211_CCK_RATE_2MB_MASK:
+	case LIBIPW_CCK_RATE_2MB_MASK:
 		return 2000000;
-	case IEEE80211_CCK_RATE_5MB_MASK:
+	case LIBIPW_CCK_RATE_5MB_MASK:
 		return 5500000;
-	case IEEE80211_OFDM_RATE_6MB_MASK:
+	case LIBIPW_OFDM_RATE_6MB_MASK:
 		return 6000000;
-	case IEEE80211_OFDM_RATE_9MB_MASK:
+	case LIBIPW_OFDM_RATE_9MB_MASK:
 		return 9000000;
-	case IEEE80211_CCK_RATE_11MB_MASK:
+	case LIBIPW_CCK_RATE_11MB_MASK:
 		return 11000000;
-	case IEEE80211_OFDM_RATE_12MB_MASK:
+	case LIBIPW_OFDM_RATE_12MB_MASK:
 		return 12000000;
-	case IEEE80211_OFDM_RATE_18MB_MASK:
+	case LIBIPW_OFDM_RATE_18MB_MASK:
 		return 18000000;
-	case IEEE80211_OFDM_RATE_24MB_MASK:
+	case LIBIPW_OFDM_RATE_24MB_MASK:
 		return 24000000;
-	case IEEE80211_OFDM_RATE_36MB_MASK:
+	case LIBIPW_OFDM_RATE_36MB_MASK:
 		return 36000000;
-	case IEEE80211_OFDM_RATE_48MB_MASK:
+	case LIBIPW_OFDM_RATE_48MB_MASK:
 		return 48000000;
-	case IEEE80211_OFDM_RATE_54MB_MASK:
+	case LIBIPW_OFDM_RATE_54MB_MASK:
 		return 54000000;
 	}
 
@@ -4279,9 +4298,10 @@ static void ipw_gather_stats(struct ipw_priv *priv)
 	IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
 			signal_quality, rssi);
 
-	quality = min(beacon_quality,
-		      min(rate_quality,
-			  min(tx_quality, min(rx_quality, signal_quality))));
+	quality = min(rx_quality, signal_quality);
+	quality = min(tx_quality, quality);
+	quality = min(rate_quality, quality);
+	quality = min(beacon_quality, quality);
 	if (quality == beacon_quality)
 		IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
 				quality);
@@ -4425,7 +4445,6 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 {
 	DECLARE_SSID_BUF(ssid);
 	u16 size = le16_to_cpu(notif->size);
-	notif->size = le16_to_cpu(notif->size);
 
 	IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
 
@@ -4480,11 +4499,11 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 					     == IEEE80211_STYPE_ASSOC_RESP)) {
 						if ((sizeof
 						     (struct
-						      ieee80211_assoc_response)
+						      libipw_assoc_response)
 						     <= size)
 						    && (size <= 2314)) {
 							struct
-							ieee80211_rx_stats
+							libipw_rx_stats
 							    stats = {
 								.len = size - 1,
 							};
@@ -4492,10 +4511,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 							IPW_DEBUG_QOS
 							    ("QoS Associate "
 							     "size %d\n", size);
-							ieee80211_rx_mgt(priv->
+							libipw_rx_mgt(priv->
 									 ieee,
 									 (struct
-									  ieee80211_hdr_4addr
+									  libipw_hdr_4addr
 									  *)
 									 &notif->u.raw, &stats);
 						}
@@ -4551,11 +4570,11 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 			case CMAS_INIT:{
 					if (priv->status & STATUS_AUTH) {
 						struct
-						    ieee80211_assoc_response
+						    libipw_assoc_response
 						*resp;
 						resp =
 						    (struct
-						     ieee80211_assoc_response
+						     libipw_assoc_response
 						     *)&notif->u.raw;
 						IPW_DEBUG(IPW_DL_NOTIF |
 							  IPW_DL_STATE |
@@ -5241,33 +5260,33 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
 
 static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
 {
-	rate &= ~IEEE80211_BASIC_RATE_MASK;
+	rate &= ~LIBIPW_BASIC_RATE_MASK;
 	if (ieee_mode == IEEE_A) {
 		switch (rate) {
-		case IEEE80211_OFDM_RATE_6MB:
-			return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ?
+		case LIBIPW_OFDM_RATE_6MB:
+			return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ?
 			    1 : 0;
-		case IEEE80211_OFDM_RATE_9MB:
-			return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ?
+		case LIBIPW_OFDM_RATE_9MB:
+			return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ?
 			    1 : 0;
-		case IEEE80211_OFDM_RATE_12MB:
+		case LIBIPW_OFDM_RATE_12MB:
 			return priv->
-			    rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
-		case IEEE80211_OFDM_RATE_18MB:
+			    rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;
+		case LIBIPW_OFDM_RATE_18MB:
 			return priv->
-			    rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
-		case IEEE80211_OFDM_RATE_24MB:
+			    rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;
+		case LIBIPW_OFDM_RATE_24MB:
 			return priv->
-			    rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
-		case IEEE80211_OFDM_RATE_36MB:
+			    rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;
+		case LIBIPW_OFDM_RATE_36MB:
 			return priv->
-			    rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
-		case IEEE80211_OFDM_RATE_48MB:
+			    rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;
+		case LIBIPW_OFDM_RATE_48MB:
 			return priv->
-			    rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
-		case IEEE80211_OFDM_RATE_54MB:
+			    rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;
+		case LIBIPW_OFDM_RATE_54MB:
 			return priv->
-			    rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
+			    rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;
 		default:
 			return 0;
 		}
@@ -5275,14 +5294,14 @@ static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
 
 	/* B and G mixed */
 	switch (rate) {
-	case IEEE80211_CCK_RATE_1MB:
-		return priv->rates_mask & IEEE80211_CCK_RATE_1MB_MASK ? 1 : 0;
-	case IEEE80211_CCK_RATE_2MB:
-		return priv->rates_mask & IEEE80211_CCK_RATE_2MB_MASK ? 1 : 0;
-	case IEEE80211_CCK_RATE_5MB:
-		return priv->rates_mask & IEEE80211_CCK_RATE_5MB_MASK ? 1 : 0;
-	case IEEE80211_CCK_RATE_11MB:
-		return priv->rates_mask & IEEE80211_CCK_RATE_11MB_MASK ? 1 : 0;
+	case LIBIPW_CCK_RATE_1MB:
+		return priv->rates_mask & LIBIPW_CCK_RATE_1MB_MASK ? 1 : 0;
+	case LIBIPW_CCK_RATE_2MB:
+		return priv->rates_mask & LIBIPW_CCK_RATE_2MB_MASK ? 1 : 0;
+	case LIBIPW_CCK_RATE_5MB:
+		return priv->rates_mask & LIBIPW_CCK_RATE_5MB_MASK ? 1 : 0;
+	case LIBIPW_CCK_RATE_11MB:
+		return priv->rates_mask & LIBIPW_CCK_RATE_11MB_MASK ? 1 : 0;
 	}
 
 	/* If we are limited to B modulations, bail at this point */
@@ -5291,29 +5310,29 @@ static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
 
 	/* G */
 	switch (rate) {
-	case IEEE80211_OFDM_RATE_6MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? 1 : 0;
-	case IEEE80211_OFDM_RATE_9MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? 1 : 0;
-	case IEEE80211_OFDM_RATE_12MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
-	case IEEE80211_OFDM_RATE_18MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
-	case IEEE80211_OFDM_RATE_24MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
-	case IEEE80211_OFDM_RATE_36MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
-	case IEEE80211_OFDM_RATE_48MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
-	case IEEE80211_OFDM_RATE_54MB:
-		return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_6MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_9MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_12MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_18MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_24MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_36MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_48MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;
+	case LIBIPW_OFDM_RATE_54MB:
+		return priv->rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;
 	}
 
 	return 0;
 }
 
 static int ipw_compatible_rates(struct ipw_priv *priv,
-				const struct ieee80211_network *network,
+				const struct libipw_network *network,
 				struct ipw_supported_rates *rates)
 {
 	int num_rates, i;
@@ -5325,7 +5344,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
 		if (!ipw_is_rate_in_mask(priv, network->mode,
 					 network->rates[i])) {
 
-			if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
+			if (network->rates[i] & LIBIPW_BASIC_RATE_MASK) {
 				IPW_DEBUG_SCAN("Adding masked mandatory "
 					       "rate %02X\n",
 					       network->rates[i]);
@@ -5347,7 +5366,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
 	for (i = 0; i < num_rates; i++) {
 		if (!ipw_is_rate_in_mask(priv, network->mode,
 					 network->rates_ex[i])) {
-			if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
+			if (network->rates_ex[i] & LIBIPW_BASIC_RATE_MASK) {
 				IPW_DEBUG_SCAN("Adding masked mandatory "
 					       "rate %02X\n",
 					       network->rates_ex[i]);
@@ -5383,73 +5402,73 @@ static void ipw_copy_rates(struct ipw_supported_rates *dest,
 static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,
 				   u8 modulation, u32 rate_mask)
 {
-	u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
-	    IEEE80211_BASIC_RATE_MASK : 0;
+	u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?
+	    LIBIPW_BASIC_RATE_MASK : 0;
 
-	if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK)
+	if (rate_mask & LIBIPW_CCK_RATE_1MB_MASK)
 		rates->supported_rates[rates->num_rates++] =
-		    IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+		    LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_1MB;
 
-	if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK)
+	if (rate_mask & LIBIPW_CCK_RATE_2MB_MASK)
 		rates->supported_rates[rates->num_rates++] =
-		    IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+		    LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_2MB;
 
-	if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK)
+	if (rate_mask & LIBIPW_CCK_RATE_5MB_MASK)
 		rates->supported_rates[rates->num_rates++] = basic_mask |
-		    IEEE80211_CCK_RATE_5MB;
+		    LIBIPW_CCK_RATE_5MB;
 
-	if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK)
+	if (rate_mask & LIBIPW_CCK_RATE_11MB_MASK)
 		rates->supported_rates[rates->num_rates++] = basic_mask |
-		    IEEE80211_CCK_RATE_11MB;
+		    LIBIPW_CCK_RATE_11MB;
 }
 
 static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,
 				    u8 modulation, u32 rate_mask)
 {
-	u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
-	    IEEE80211_BASIC_RATE_MASK : 0;
+	u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?
+	    LIBIPW_BASIC_RATE_MASK : 0;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_6MB_MASK)
 		rates->supported_rates[rates->num_rates++] = basic_mask |
-		    IEEE80211_OFDM_RATE_6MB;
+		    LIBIPW_OFDM_RATE_6MB;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_9MB_MASK)
 		rates->supported_rates[rates->num_rates++] =
-		    IEEE80211_OFDM_RATE_9MB;
+		    LIBIPW_OFDM_RATE_9MB;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_12MB_MASK)
 		rates->supported_rates[rates->num_rates++] = basic_mask |
-		    IEEE80211_OFDM_RATE_12MB;
+		    LIBIPW_OFDM_RATE_12MB;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_18MB_MASK)
 		rates->supported_rates[rates->num_rates++] =
-		    IEEE80211_OFDM_RATE_18MB;
+		    LIBIPW_OFDM_RATE_18MB;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_24MB_MASK)
 		rates->supported_rates[rates->num_rates++] = basic_mask |
-		    IEEE80211_OFDM_RATE_24MB;
+		    LIBIPW_OFDM_RATE_24MB;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_36MB_MASK)
 		rates->supported_rates[rates->num_rates++] =
-		    IEEE80211_OFDM_RATE_36MB;
+		    LIBIPW_OFDM_RATE_36MB;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_48MB_MASK)
 		rates->supported_rates[rates->num_rates++] =
-		    IEEE80211_OFDM_RATE_48MB;
+		    LIBIPW_OFDM_RATE_48MB;
 
-	if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK)
+	if (rate_mask & LIBIPW_OFDM_RATE_54MB_MASK)
 		rates->supported_rates[rates->num_rates++] =
-		    IEEE80211_OFDM_RATE_54MB;
+		    LIBIPW_OFDM_RATE_54MB;
 }
 
 struct ipw_network_match {
-	struct ieee80211_network *network;
+	struct libipw_network *network;
 	struct ipw_supported_rates rates;
 };
 
 static int ipw_find_adhoc_network(struct ipw_priv *priv,
 				  struct ipw_network_match *match,
-				  struct ieee80211_network *network,
+				  struct libipw_network *network,
 				  int roaming)
 {
 	struct ipw_supported_rates rates;
@@ -5570,7 +5589,7 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv,
 	}
 
 	/* Filter out any incompatible freq / mode combinations */
-	if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
+	if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
 		IPW_DEBUG_MERGE("Network '%s (%pM)' excluded "
 				"because of invalid frequency/mode "
 				"combination.\n",
@@ -5620,7 +5639,7 @@ static void ipw_merge_adhoc_network(struct work_struct *work)
 	DECLARE_SSID_BUF(ssid);
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, merge_networks);
-	struct ieee80211_network *network = NULL;
+	struct libipw_network *network = NULL;
 	struct ipw_network_match match = {
 		.network = priv->assoc_network
 	};
@@ -5662,7 +5681,7 @@ static void ipw_merge_adhoc_network(struct work_struct *work)
 
 static int ipw_best_network(struct ipw_priv *priv,
 			    struct ipw_network_match *match,
-			    struct ieee80211_network *network, int roaming)
+			    struct libipw_network *network, int roaming)
 {
 	struct ipw_supported_rates rates;
 	DECLARE_SSID_BUF(ssid);
@@ -5796,7 +5815,7 @@ static int ipw_best_network(struct ipw_priv *priv,
 	}
 
 	/* Filter out any incompatible freq / mode combinations */
-	if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
+	if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
 		IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
 				"because of invalid frequency/mode "
 				"combination.\n",
@@ -5807,7 +5826,7 @@ static int ipw_best_network(struct ipw_priv *priv,
 	}
 
 	/* Filter out invalid channel in current GEO */
-	if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) {
+	if (!libipw_is_valid_channel(priv->ieee, network->channel)) {
 		IPW_DEBUG_ASSOC("Network '%s (%pM)' excluded "
 				"because of invalid channel in current GEO\n",
 				print_ssid(ssid, network->ssid,
@@ -5853,9 +5872,9 @@ static int ipw_best_network(struct ipw_priv *priv,
 }
 
 static void ipw_adhoc_create(struct ipw_priv *priv,
-			     struct ieee80211_network *network)
+			     struct libipw_network *network)
 {
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
 	int i;
 
 	/*
@@ -5870,25 +5889,25 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
 	 * FW fatal error.
 	 *
 	 */
-	switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
-	case IEEE80211_52GHZ_BAND:
+	switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
+	case LIBIPW_52GHZ_BAND:
 		network->mode = IEEE_A;
-		i = ieee80211_channel_to_index(priv->ieee, priv->channel);
+		i = libipw_channel_to_index(priv->ieee, priv->channel);
 		BUG_ON(i == -1);
-		if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
+		if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) {
 			IPW_WARNING("Overriding invalid channel\n");
 			priv->channel = geo->a[0].channel;
 		}
 		break;
 
-	case IEEE80211_24GHZ_BAND:
+	case LIBIPW_24GHZ_BAND:
 		if (priv->ieee->mode & IEEE_G)
 			network->mode = IEEE_G;
 		else
 			network->mode = IEEE_B;
-		i = ieee80211_channel_to_index(priv->ieee, priv->channel);
+		i = libipw_channel_to_index(priv->ieee, priv->channel);
 		BUG_ON(i == -1);
-		if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
+		if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) {
 			IPW_WARNING("Overriding invalid channel\n");
 			priv->channel = geo->bg[0].channel;
 		}
@@ -6115,70 +6134,71 @@ static void ipw_debug_config(struct ipw_priv *priv)
 static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
 {
 	/* TODO: Verify that this works... */
-	struct ipw_fixed_rate fr = {
-		.tx_rates = priv->rates_mask
-	};
+	struct ipw_fixed_rate fr;
 	u32 reg;
 	u16 mask = 0;
+	u16 new_tx_rates = priv->rates_mask;
 
 	/* Identify 'current FW band' and match it with the fixed
 	 * Tx rates */
 
 	switch (priv->ieee->freq_band) {
-	case IEEE80211_52GHZ_BAND:	/* A only */
+	case LIBIPW_52GHZ_BAND:	/* A only */
 		/* IEEE_A */
-		if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
+		if (priv->rates_mask & ~LIBIPW_OFDM_RATES_MASK) {
 			/* Invalid fixed rate mask */
 			IPW_DEBUG_WX
 			    ("invalid fixed rate mask in ipw_set_fixed_rate\n");
-			fr.tx_rates = 0;
+			new_tx_rates = 0;
 			break;
 		}
 
-		fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
+		new_tx_rates >>= LIBIPW_OFDM_SHIFT_MASK_A;
 		break;
 
 	default:		/* 2.4Ghz or Mixed */
 		/* IEEE_B */
 		if (mode == IEEE_B) {
-			if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
+			if (new_tx_rates & ~LIBIPW_CCK_RATES_MASK) {
 				/* Invalid fixed rate mask */
 				IPW_DEBUG_WX
 				    ("invalid fixed rate mask in ipw_set_fixed_rate\n");
-				fr.tx_rates = 0;
+				new_tx_rates = 0;
 			}
 			break;
 		}
 
 		/* IEEE_G */
-		if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
-				    IEEE80211_OFDM_RATES_MASK)) {
+		if (new_tx_rates & ~(LIBIPW_CCK_RATES_MASK |
+				    LIBIPW_OFDM_RATES_MASK)) {
 			/* Invalid fixed rate mask */
 			IPW_DEBUG_WX
 			    ("invalid fixed rate mask in ipw_set_fixed_rate\n");
-			fr.tx_rates = 0;
+			new_tx_rates = 0;
 			break;
 		}
 
-		if (IEEE80211_OFDM_RATE_6MB_MASK & fr.tx_rates) {
-			mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1);
-			fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
+		if (LIBIPW_OFDM_RATE_6MB_MASK & new_tx_rates) {
+			mask |= (LIBIPW_OFDM_RATE_6MB_MASK >> 1);
+			new_tx_rates &= ~LIBIPW_OFDM_RATE_6MB_MASK;
 		}
 
-		if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) {
-			mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1);
-			fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
+		if (LIBIPW_OFDM_RATE_9MB_MASK & new_tx_rates) {
+			mask |= (LIBIPW_OFDM_RATE_9MB_MASK >> 1);
+			new_tx_rates &= ~LIBIPW_OFDM_RATE_9MB_MASK;
 		}
 
-		if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) {
-			mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1);
-			fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
+		if (LIBIPW_OFDM_RATE_12MB_MASK & new_tx_rates) {
+			mask |= (LIBIPW_OFDM_RATE_12MB_MASK >> 1);
+			new_tx_rates &= ~LIBIPW_OFDM_RATE_12MB_MASK;
 		}
 
-		fr.tx_rates |= mask;
+		new_tx_rates |= mask;
 		break;
 	}
 
+	fr.tx_rates = cpu_to_le16(new_tx_rates);
+
 	reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
 	ipw_write_reg32(priv, reg, *(u32 *) & fr);
 }
@@ -6203,12 +6223,12 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
 				  int scan_type)
 {
 	int channel_index = 0;
-	const struct ieee80211_geo *geo;
+	const struct libipw_geo *geo;
 	int i;
 
-	geo = ieee80211_get_geo(priv->ieee);
+	geo = libipw_get_geo(priv->ieee);
 
-	if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
+	if (priv->ieee->freq_band & LIBIPW_52GHZ_BAND) {
 		int start = channel_index;
 		for (i = 0; i < geo->a_channels; i++) {
 			if ((priv->status & STATUS_ASSOCIATED) &&
@@ -6218,7 +6238,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
 			scan->channels_list[channel_index] = geo->a[i].channel;
 			ipw_set_scan_type(scan, channel_index,
 					  geo->a[i].
-					  flags & IEEE80211_CH_PASSIVE_ONLY ?
+					  flags & LIBIPW_CH_PASSIVE_ONLY ?
 					  IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
 					  scan_type);
 		}
@@ -6230,11 +6250,11 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
 		}
 	}
 
-	if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
+	if (priv->ieee->freq_band & LIBIPW_24GHZ_BAND) {
 		int start = channel_index;
 		if (priv->config & CFG_SPEED_SCAN) {
 			int index;
-			u8 channels[IEEE80211_24GHZ_CHANNELS] = {
+			u8 channels[LIBIPW_24GHZ_CHANNELS] = {
 				/* nop out the list */
 				[0] = 0
 			};
@@ -6266,11 +6286,11 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
 				channel_index++;
 				scan->channels_list[channel_index] = channel;
 				index =
-				    ieee80211_channel_to_index(priv->ieee, channel);
+				    libipw_channel_to_index(priv->ieee, channel);
 				ipw_set_scan_type(scan, channel_index,
 						  geo->bg[index].
 						  flags &
-						  IEEE80211_CH_PASSIVE_ONLY ?
+						  LIBIPW_CH_PASSIVE_ONLY ?
 						  IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
 						  : scan_type);
 			}
@@ -6285,7 +6305,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
 				ipw_set_scan_type(scan, channel_index,
 						  geo->bg[i].
 						  flags &
-						  IEEE80211_CH_PASSIVE_ONLY ?
+						  LIBIPW_CH_PASSIVE_ONLY ?
 						  IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
 						  : scan_type);
 			}
@@ -6352,7 +6372,7 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
 	}
 
 	memset(&scan, 0, sizeof(scan));
-	scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
+	scan.full_scan_index = cpu_to_le32(libipw_get_scans(priv->ieee));
 
 	if (type == IW_SCAN_TYPE_PASSIVE) {
 		IPW_DEBUG_WX("use passive scanning\n");
@@ -6383,13 +6403,13 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
 		u8 channel;
 		u8 band = 0;
 
-		switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
-		case IEEE80211_52GHZ_BAND:
+		switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
+		case LIBIPW_52GHZ_BAND:
 			band = (u8) (IPW_A_MODE << 6) | 1;
 			channel = priv->channel;
 			break;
 
-		case IEEE80211_24GHZ_BAND:
+		case LIBIPW_24GHZ_BAND:
 			band = (u8) (IPW_B_MODE << 6) | 1;
 			channel = priv->channel;
 			break;
@@ -6510,8 +6530,8 @@ static int ipw_wpa_enable(struct ipw_priv *priv, int value)
 
 static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
 {
-	struct ieee80211_device *ieee = priv->ieee;
-	struct ieee80211_security sec = {
+	struct libipw_device *ieee = priv->ieee;
+	struct libipw_security sec = {
 		.flags = SEC_AUTH_MODE,
 	};
 	int ret = 0;
@@ -6561,8 +6581,8 @@ static int ipw_wx_set_genie(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 	u8 *buf;
 	int err = 0;
 
@@ -6597,8 +6617,8 @@ static int ipw_wx_get_genie(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 	int err = 0;
 
 	if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
@@ -6640,8 +6660,8 @@ static int ipw_wx_set_auth(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 	struct iw_param *param = &wrqu->param;
 	struct lib80211_crypt_data *crypt;
 	unsigned long flags;
@@ -6692,7 +6712,7 @@ static int ipw_wx_set_auth(struct net_device *dev,
 			 * can use this to determine if the CAP_PRIVACY_ON bit should
 			 * be set.
 			 */
-			struct ieee80211_security sec = {
+			struct libipw_security sec = {
 				.flags = SEC_ENABLED,
 				.enabled = param->value,
 			};
@@ -6740,8 +6760,8 @@ static int ipw_wx_get_auth(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
+	struct ipw_priv *priv = libipw_priv(dev);
+	struct libipw_device *ieee = priv->ieee;
 	struct lib80211_crypt_data *crypt;
 	struct iw_param *param = &wrqu->param;
 	int ret = 0;
@@ -6799,7 +6819,7 @@ static int ipw_wx_set_encodeext(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 
 	if (hwcrypto) {
@@ -6821,7 +6841,7 @@ static int ipw_wx_set_encodeext(struct net_device *dev,
 		}
 	}
 
-	return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
+	return libipw_wx_set_encodeext(priv->ieee, info, wrqu, extra);
 }
 
 /* SIOCGIWENCODEEXT */
@@ -6829,8 +6849,8 @@ static int ipw_wx_get_encodeext(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
+	struct ipw_priv *priv = libipw_priv(dev);
+	return libipw_wx_get_encodeext(priv->ieee, info, wrqu, extra);
 }
 
 /* SIOCSIWMLME */
@@ -6838,7 +6858,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
 	__le16 reason;
 
@@ -6888,9 +6908,9 @@ static u8 ipw_qos_current_mode(struct ipw_priv * priv)
 */
 static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
 					 int active_network,
-					 struct ieee80211_network *network)
+					 struct libipw_network *network)
 {
-	u32 size = sizeof(struct ieee80211_qos_parameters);
+	u32 size = sizeof(struct libipw_qos_parameters);
 
 	if (network->capability & WLAN_CAPABILITY_IBSS)
 		network->qos_data.active = network->qos_data.supported;
@@ -6948,12 +6968,12 @@ static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
 * IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
 */
 static int ipw_qos_activate(struct ipw_priv *priv,
-			    struct ieee80211_qos_data *qos_network_data)
+			    struct libipw_qos_data *qos_network_data)
 {
 	int err;
-	struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
-	struct ieee80211_qos_parameters *active_one = NULL;
-	u32 size = sizeof(struct ieee80211_qos_parameters);
+	struct libipw_qos_parameters qos_parameters[QOS_QOS_SETS];
+	struct libipw_qos_parameters *active_one = NULL;
+	u32 size = sizeof(struct libipw_qos_parameters);
 	u32 burst_duration;
 	int i;
 	u8 type;
@@ -7014,7 +7034,7 @@ static int ipw_qos_activate(struct ipw_priv *priv,
 
 	IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
 	err = ipw_send_qos_params_command(priv,
-					  (struct ieee80211_qos_parameters *)
+					  (struct libipw_qos_parameters *)
 					  &(qos_parameters[0]));
 	if (err)
 		IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
@@ -7028,13 +7048,13 @@ static int ipw_qos_activate(struct ipw_priv *priv,
 static int ipw_qos_set_info_element(struct ipw_priv *priv)
 {
 	int ret = 0;
-	struct ieee80211_qos_information_element qos_info;
+	struct libipw_qos_information_element qos_info;
 
 	if (priv == NULL)
 		return -1;
 
 	qos_info.elementID = QOS_ELEMENT_ID;
-	qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
+	qos_info.length = sizeof(struct libipw_qos_information_element) - 2;
 
 	qos_info.version = QOS_VERSION_1;
 	qos_info.ac_info = 0;
@@ -7054,11 +7074,11 @@ static int ipw_qos_set_info_element(struct ipw_priv *priv)
 * Set the QoS parameter with the association request structure
 */
 static int ipw_qos_association(struct ipw_priv *priv,
-			       struct ieee80211_network *network)
+			       struct libipw_network *network)
 {
 	int err = 0;
-	struct ieee80211_qos_data *qos_data = NULL;
-	struct ieee80211_qos_data ibss_data = {
+	struct libipw_qos_data *qos_data = NULL;
+	struct libipw_qos_data ibss_data = {
 		.supported = 1,
 		.active = 1,
 	};
@@ -7100,11 +7120,11 @@ static int ipw_qos_association(struct ipw_priv *priv,
 * setting
 */
 static int ipw_qos_association_resp(struct ipw_priv *priv,
-				    struct ieee80211_network *network)
+				    struct libipw_network *network)
 {
 	int ret = 0;
 	unsigned long flags;
-	u32 size = sizeof(struct ieee80211_qos_parameters);
+	u32 size = sizeof(struct libipw_qos_parameters);
 	int set_qos_param = 0;
 
 	if ((priv == NULL) || (network == NULL) ||
@@ -7120,7 +7140,7 @@ static int ipw_qos_association_resp(struct ipw_priv *priv,
 	spin_lock_irqsave(&priv->ieee->lock, flags);
 	if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
 		memcpy(&priv->assoc_network->qos_data, &network->qos_data,
-		       sizeof(struct ieee80211_qos_data));
+		       sizeof(struct libipw_qos_data));
 		priv->assoc_network->qos_data.active = 1;
 		if ((network->qos_data.old_param_count !=
 		     network->qos_data.param_count)) {
@@ -7156,7 +7176,7 @@ static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
 	if ((priv == NULL))
 		return 0;
 
-	if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION))
+	if (!(priv->ieee->modulation & LIBIPW_OFDM_MODULATION))
 		ret = priv->qos_data.burst_duration_CCK;
 	else
 		ret = priv->qos_data.burst_duration_OFDM;
@@ -7208,8 +7228,8 @@ static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
 static int ipw_is_qos_active(struct net_device *dev,
 			     struct sk_buff *skb)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_qos_data *qos_data = NULL;
+	struct ipw_priv *priv = libipw_priv(dev);
+	struct libipw_qos_data *qos_data = NULL;
 	int active, supported;
 	u8 *daddr = skb->data + ETH_ALEN;
 	int unicast = !is_multicast_ether_addr(daddr);
@@ -7264,9 +7284,6 @@ static void ipw_bg_qos_activate(struct work_struct *work)
 	struct ipw_priv *priv =
 		container_of(work, struct ipw_priv, qos_activate);
 
-	if (priv == NULL)
-		return;
-
 	mutex_lock(&priv->mutex);
 
 	if (priv->status & STATUS_ASSOCIATED)
@@ -7276,10 +7293,10 @@ static void ipw_bg_qos_activate(struct work_struct *work)
 }
 
 static int ipw_handle_probe_response(struct net_device *dev,
-				     struct ieee80211_probe_response *resp,
-				     struct ieee80211_network *network)
+				     struct libipw_probe_response *resp,
+				     struct libipw_network *network)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int active_network = ((priv->status & STATUS_ASSOCIATED) &&
 			      (network == priv->assoc_network));
 
@@ -7289,10 +7306,10 @@ static int ipw_handle_probe_response(struct net_device *dev,
 }
 
 static int ipw_handle_beacon(struct net_device *dev,
-			     struct ieee80211_beacon *resp,
-			     struct ieee80211_network *network)
+			     struct libipw_beacon *resp,
+			     struct libipw_network *network)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int active_network = ((priv->status & STATUS_ASSOCIATED) &&
 			      (network == priv->assoc_network));
 
@@ -7302,22 +7319,22 @@ static int ipw_handle_beacon(struct net_device *dev,
 }
 
 static int ipw_handle_assoc_response(struct net_device *dev,
-				     struct ieee80211_assoc_response *resp,
-				     struct ieee80211_network *network)
+				     struct libipw_assoc_response *resp,
+				     struct libipw_network *network)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	ipw_qos_association_resp(priv, network);
 	return 0;
 }
 
-static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
+static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters
 				       *qos_param)
 {
 	return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS,
 				sizeof(*qos_param) * 3, qos_param);
 }
 
-static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
+static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element
 				     *qos_param)
 {
 	return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param),
@@ -7327,7 +7344,7 @@ static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos
 #endif				/* CONFIG_IPW2200_QOS */
 
 static int ipw_associate_network(struct ipw_priv *priv,
-				 struct ieee80211_network *network,
+				 struct libipw_network *network,
 				 struct ipw_supported_rates *rates, int roaming)
 {
 	int err;
@@ -7509,7 +7526,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
 static void ipw_roam(void *data)
 {
 	struct ipw_priv *priv = data;
-	struct ieee80211_network *network = NULL;
+	struct libipw_network *network = NULL;
 	struct ipw_network_match match = {
 		.network = priv->assoc_network
 	};
@@ -7584,7 +7601,7 @@ static int ipw_associate(void *data)
 {
 	struct ipw_priv *priv = data;
 
-	struct ieee80211_network *network = NULL;
+	struct libipw_network *network = NULL;
 	struct ipw_network_match match = {
 		.network = NULL
 	};
@@ -7638,8 +7655,8 @@ static int ipw_associate(void *data)
 	    priv->config & CFG_STATIC_CHANNEL) {
 		/* Use oldest network if the free list is empty */
 		if (list_empty(&priv->ieee->network_free_list)) {
-			struct ieee80211_network *oldest = NULL;
-			struct ieee80211_network *target;
+			struct libipw_network *oldest = NULL;
+			struct libipw_network *target;
 
 			list_for_each_entry(target, &priv->ieee->network_list, list) {
 				if ((oldest == NULL) ||
@@ -7660,7 +7677,7 @@ static int ipw_associate(void *data)
 		}
 
 		element = priv->ieee->network_free_list.next;
-		network = list_entry(element, struct ieee80211_network, list);
+		network = list_entry(element, struct libipw_network, list);
 		ipw_adhoc_create(priv, network);
 		rates = &priv->rates;
 		list_del(element);
@@ -7716,18 +7733,18 @@ static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
 	switch (priv->ieee->sec.level) {
 	case SEC_LEVEL_3:
 		/* Remove CCMP HDR */
-		memmove(skb->data + IEEE80211_3ADDR_LEN,
-			skb->data + IEEE80211_3ADDR_LEN + 8,
-			skb->len - IEEE80211_3ADDR_LEN - 8);
+		memmove(skb->data + LIBIPW_3ADDR_LEN,
+			skb->data + LIBIPW_3ADDR_LEN + 8,
+			skb->len - LIBIPW_3ADDR_LEN - 8);
 		skb_trim(skb, skb->len - 16);	/* CCMP_HDR_LEN + CCMP_MIC_LEN */
 		break;
 	case SEC_LEVEL_2:
 		break;
 	case SEC_LEVEL_1:
 		/* Remove IV */
-		memmove(skb->data + IEEE80211_3ADDR_LEN,
-			skb->data + IEEE80211_3ADDR_LEN + 4,
-			skb->len - IEEE80211_3ADDR_LEN - 4);
+		memmove(skb->data + LIBIPW_3ADDR_LEN,
+			skb->data + LIBIPW_3ADDR_LEN + 4,
+			skb->len - LIBIPW_3ADDR_LEN - 4);
 		skb_trim(skb, skb->len - 8);	/* IV + ICV */
 		break;
 	case SEC_LEVEL_0:
@@ -7741,10 +7758,10 @@ static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
 
 static void ipw_handle_data_packet(struct ipw_priv *priv,
 				   struct ipw_rx_mem_buffer *rxb,
-				   struct ieee80211_rx_stats *stats)
+				   struct libipw_rx_stats *stats)
 {
 	struct net_device *dev = priv->net_dev;
-	struct ieee80211_hdr_4addr *hdr;
+	struct libipw_hdr_4addr *hdr;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
 
 	/* We received data from the HW, so stop the watchdog */
@@ -7774,15 +7791,15 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
 
 	/* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
-	hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
+	hdr = (struct libipw_hdr_4addr *)rxb->skb->data;
 	if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
 	    (is_multicast_ether_addr(hdr->addr1) ?
 	     !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
-	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
+	if (!libipw_rx(priv->ieee, rxb->skb, stats))
 		dev->stats.rx_errors++;
-	else {			/* ieee80211_rx succeeded, so it now owns the SKB */
+	else {			/* libipw_rx succeeded, so it now owns the SKB */
 		rxb->skb = NULL;
 		__ipw_led_activity_on(priv);
 	}
@@ -7791,7 +7808,7 @@ static void ipw_handle_data_packet(struct ipw_priv *priv,
 #ifdef CONFIG_IPW2200_RADIOTAP
 static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
 					   struct ipw_rx_mem_buffer *rxb,
-					   struct ieee80211_rx_stats *stats)
+					   struct libipw_rx_stats *stats)
 {
 	struct net_device *dev = priv->net_dev;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
@@ -7867,7 +7884,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
 
 	/* Convert signal to DBM */
 	ipw_rt->rt_dbmsignal = antsignal;
-	ipw_rt->rt_dbmnoise = frame->noise;
+	ipw_rt->rt_dbmnoise = (s8) le16_to_cpu(frame->noise);
 
 	/* Convert the channel data and set the flags */
 	ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
@@ -7937,9 +7954,9 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
 
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
 
-	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
+	if (!libipw_rx(priv->ieee, rxb->skb, stats))
 		dev->stats.rx_errors++;
-	else {			/* ieee80211_rx succeeded, so it now owns the SKB */
+	else {			/* libipw_rx succeeded, so it now owns the SKB */
 		rxb->skb = NULL;
 		/* no LED during capture */
 	}
@@ -7947,28 +7964,28 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
 #endif
 
 #ifdef CONFIG_IPW2200_PROMISCUOUS
-#define ieee80211_is_probe_response(fc) \
+#define libipw_is_probe_response(fc) \
    ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && \
     (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP )
 
-#define ieee80211_is_management(fc) \
+#define libipw_is_management(fc) \
    ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
 
-#define ieee80211_is_control(fc) \
+#define libipw_is_control(fc) \
    ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
 
-#define ieee80211_is_data(fc) \
+#define libipw_is_data(fc) \
    ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
 
-#define ieee80211_is_assoc_request(fc) \
+#define libipw_is_assoc_request(fc) \
    ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ)
 
-#define ieee80211_is_reassoc_request(fc) \
+#define libipw_is_reassoc_request(fc) \
    ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
 
 static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 				      struct ipw_rx_mem_buffer *rxb,
-				      struct ieee80211_rx_stats *stats)
+				      struct libipw_rx_stats *stats)
 {
 	struct net_device *dev = priv->prom_net_dev;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
@@ -7981,7 +7998,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 	u16 channel = frame->received_channel;
 	u8 phy_flags = frame->antennaAndPhy;
 	s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
-	s8 noise = frame->noise;
+	s8 noise = (s8) le16_to_cpu(frame->noise);
 	u8 rate = frame->rate;
 	short len = le16_to_cpu(pkt->u.frame.length);
 	struct sk_buff *skb;
@@ -8018,17 +8035,17 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 	}
 
 	hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
-	if (ieee80211_is_management(le16_to_cpu(hdr->frame_control))) {
+	if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {
 		if (filter & IPW_PROM_NO_MGMT)
 			return;
 		if (filter & IPW_PROM_MGMT_HEADER_ONLY)
 			hdr_only = 1;
-	} else if (ieee80211_is_control(le16_to_cpu(hdr->frame_control))) {
+	} else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {
 		if (filter & IPW_PROM_NO_CTL)
 			return;
 		if (filter & IPW_PROM_CTL_HEADER_ONLY)
 			hdr_only = 1;
-	} else if (ieee80211_is_data(le16_to_cpu(hdr->frame_control))) {
+	} else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {
 		if (filter & IPW_PROM_NO_DATA)
 			return;
 		if (filter & IPW_PROM_DATA_HEADER_ONLY)
@@ -8046,7 +8063,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 	ipw_rt = (void *)skb->data;
 
 	if (hdr_only)
-		len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
+		len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));
 
 	memcpy(ipw_rt->payload, hdr, len);
 
@@ -8143,7 +8160,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
 
-	if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
+	if (!libipw_rx(priv->prom_priv->ieee, skb, stats)) {
 		dev->stats.rx_errors++;
 		dev_kfree_skb_any(skb);
 	}
@@ -8151,7 +8168,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 #endif
 
 static int is_network_packet(struct ipw_priv *priv,
-				    struct ieee80211_hdr_4addr *header)
+				    struct libipw_hdr_4addr *header)
 {
 	/* Filter incoming packets to determine if they are targetted toward
 	 * this network, discarding packets coming from ourselves */
@@ -8189,7 +8206,7 @@ static int is_network_packet(struct ipw_priv *priv,
 #define IPW_PACKET_RETRY_TIME HZ
 
 static  int is_duplicate_packet(struct ipw_priv *priv,
-				      struct ieee80211_hdr_4addr *header)
+				      struct libipw_hdr_4addr *header)
 {
 	u16 sc = le16_to_cpu(header->seq_ctl);
 	u16 seq = WLAN_GET_SEQ_SEQ(sc);
@@ -8263,14 +8280,14 @@ static  int is_duplicate_packet(struct ipw_priv *priv,
 
 static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
 				   struct ipw_rx_mem_buffer *rxb,
-				   struct ieee80211_rx_stats *stats)
+				   struct libipw_rx_stats *stats)
 {
 	struct sk_buff *skb = rxb->skb;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
-	struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
+	struct libipw_hdr_4addr *header = (struct libipw_hdr_4addr *)
 	    (skb->data + IPW_RX_FRAME_SIZE);
 
-	ieee80211_rx_mgt(priv->ieee, header, stats);
+	libipw_rx_mgt(priv->ieee, header, stats);
 
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
 	    ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
@@ -8292,12 +8309,12 @@ static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
 		/* Advance past the ipw packet header to the 802.11 frame */
 		skb_pull(skb, IPW_RX_FRAME_SIZE);
 
-		/* Push the ieee80211_rx_stats before the 802.11 frame */
+		/* Push the libipw_rx_stats before the 802.11 frame */
 		memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
 
 		skb->dev = priv->ieee->dev;
 
-		/* Point raw at the ieee80211_stats */
+		/* Point raw at the libipw_stats */
 		skb_reset_mac_header(skb);
 
 		skb->pkt_type = PACKET_OTHERHOST;
@@ -8317,7 +8334,7 @@ static void ipw_rx(struct ipw_priv *priv)
 {
 	struct ipw_rx_mem_buffer *rxb;
 	struct ipw_rx_packet *pkt;
-	struct ieee80211_hdr_4addr *header;
+	struct libipw_hdr_4addr *header;
 	u32 r, w, i;
 	u8 network_packet;
 	u8 fill_rx = 0;
@@ -8348,11 +8365,11 @@ static void ipw_rx(struct ipw_priv *priv)
 
 		switch (pkt->header.message_type) {
 		case RX_FRAME_TYPE:	/* 802.11 frame */  {
-				struct ieee80211_rx_stats stats = {
+				struct libipw_rx_stats stats = {
 					.rssi = pkt->u.frame.rssi_dbm -
 					    IPW_RSSI_TO_DBM,
 					.signal =
-					    le16_to_cpu(pkt->u.frame.rssi_dbm) -
+					    pkt->u.frame.rssi_dbm -
 					    IPW_RSSI_TO_DBM + 0x100,
 					.noise =
 					    le16_to_cpu(pkt->u.frame.noise),
@@ -8363,19 +8380,19 @@ static void ipw_rx(struct ipw_priv *priv)
 					.freq =
 					    (pkt->u.frame.
 					     control & (1 << 0)) ?
-					    IEEE80211_24GHZ_BAND :
-					    IEEE80211_52GHZ_BAND,
+					    LIBIPW_24GHZ_BAND :
+					    LIBIPW_52GHZ_BAND,
 					.len = le16_to_cpu(pkt->u.frame.length),
 				};
 
 				if (stats.rssi != 0)
-					stats.mask |= IEEE80211_STATMASK_RSSI;
+					stats.mask |= LIBIPW_STATMASK_RSSI;
 				if (stats.signal != 0)
-					stats.mask |= IEEE80211_STATMASK_SIGNAL;
+					stats.mask |= LIBIPW_STATMASK_SIGNAL;
 				if (stats.noise != 0)
-					stats.mask |= IEEE80211_STATMASK_NOISE;
+					stats.mask |= LIBIPW_STATMASK_NOISE;
 				if (stats.rate != 0)
-					stats.mask |= IEEE80211_STATMASK_RATE;
+					stats.mask |= LIBIPW_STATMASK_RATE;
 
 				priv->rx_packets++;
 
@@ -8400,7 +8417,7 @@ static void ipw_rx(struct ipw_priv *priv)
 #endif
 
 				header =
-				    (struct ieee80211_hdr_4addr *)(rxb->skb->
+				    (struct libipw_hdr_4addr *)(rxb->skb->
 								   data +
 								   IPW_RX_FRAME_SIZE);
 				/* TODO: Check Ad-Hoc dest/source and make sure
@@ -8423,7 +8440,7 @@ static void ipw_rx(struct ipw_priv *priv)
 					     le16_to_cpu(pkt->u.frame.length));
 
 				if (le16_to_cpu(pkt->u.frame.length) <
-				    ieee80211_get_hdrlen(le16_to_cpu(
+				    libipw_get_hdrlen(le16_to_cpu(
 						    header->frame_ctl))) {
 					IPW_DEBUG_DROP
 					    ("Received packet is too small. "
@@ -8534,7 +8551,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 
 	/* We default to disabling the LED code as right now it causes
 	 * too many systems to lock up... */
-	if (!led)
+	if (!led_support)
 		priv->config |= CFG_NO_LED;
 
 	if (associate)
@@ -8556,10 +8573,10 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 		IPW_DEBUG_INFO("Radio disabled.\n");
 	}
 
-	if (channel != 0) {
+	if (default_channel != 0) {
 		priv->config |= CFG_STATIC_CHANNEL;
-		priv->channel = channel;
-		IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
+		priv->channel = default_channel;
+		IPW_DEBUG_INFO("Bind to static channel %d\n", default_channel);
 		/* TODO: Validate that provided channel is in range */
 	}
 #ifdef CONFIG_IPW2200_QOS
@@ -8567,7 +8584,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 		     burst_duration_CCK, burst_duration_OFDM);
 #endif				/* CONFIG_IPW2200_QOS */
 
-	switch (mode) {
+	switch (network_mode) {
 	case 1:
 		priv->ieee->iw_mode = IW_MODE_ADHOC;
 		priv->net_dev->type = ARPHRD_ETHER;
@@ -8608,9 +8625,9 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 			       ": Detected Intel PRO/Wireless 2915ABG Network "
 			       "Connection\n");
 		priv->ieee->abg_true = 1;
-		band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
-		modulation = IEEE80211_OFDM_MODULATION |
-		    IEEE80211_CCK_MODULATION;
+		band = LIBIPW_52GHZ_BAND | LIBIPW_24GHZ_BAND;
+		modulation = LIBIPW_OFDM_MODULATION |
+		    LIBIPW_CCK_MODULATION;
 		priv->adapter = IPW_2915ABG;
 		priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
 	} else {
@@ -8620,9 +8637,9 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 			       "Connection\n");
 
 		priv->ieee->abg_true = 0;
-		band = IEEE80211_24GHZ_BAND;
-		modulation = IEEE80211_OFDM_MODULATION |
-		    IEEE80211_CCK_MODULATION;
+		band = LIBIPW_24GHZ_BAND;
+		modulation = LIBIPW_OFDM_MODULATION |
+		    LIBIPW_CCK_MODULATION;
 		priv->adapter = IPW_2200BG;
 		priv->ieee->mode = IEEE_G | IEEE_B;
 	}
@@ -8630,7 +8647,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 	priv->ieee->freq_band = band;
 	priv->ieee->modulation = modulation;
 
-	priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
+	priv->rates_mask = LIBIPW_DEFAULT_RATES_MASK;
 
 	priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
 	priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
@@ -8656,24 +8673,6 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
  *
  */
 
-static int ipw_wx_get_name(struct net_device *dev,
-			   struct iw_request_info *info,
-			   union iwreq_data *wrqu, char *extra)
-{
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	mutex_lock(&priv->mutex);
-	if (priv->status & STATUS_RF_KILL_MASK)
-		strcpy(wrqu->name, "radio off");
-	else if (!(priv->status & STATUS_ASSOCIATED))
-		strcpy(wrqu->name, "unassociated");
-	else
-		snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
-			 ipw_modes[priv->assoc_request.ieee_mode]);
-	IPW_DEBUG_WX("Name: %s\n", wrqu->name);
-	mutex_unlock(&priv->mutex);
-	return 0;
-}
-
 static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
 {
 	if (channel == 0) {
@@ -8730,8 +8729,8 @@ static int ipw_wx_set_freq(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	struct ipw_priv *priv = libipw_priv(dev);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
 	struct iw_freq *fwrq = &wrqu->freq;
 	int ret = 0, i;
 	u8 channel, flags;
@@ -8746,23 +8745,23 @@ static int ipw_wx_set_freq(struct net_device *dev,
 	}
 	/* if setting by freq convert to channel */
 	if (fwrq->e == 1) {
-		channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m);
+		channel = libipw_freq_to_channel(priv->ieee, fwrq->m);
 		if (channel == 0)
 			return -EINVAL;
 	} else
 		channel = fwrq->m;
 
-	if (!(band = ieee80211_is_valid_channel(priv->ieee, channel)))
+	if (!(band = libipw_is_valid_channel(priv->ieee, channel)))
 		return -EINVAL;
 
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
-		i = ieee80211_channel_to_index(priv->ieee, channel);
+		i = libipw_channel_to_index(priv->ieee, channel);
 		if (i == -1)
 			return -EINVAL;
 
-		flags = (band == IEEE80211_24GHZ_BAND) ?
+		flags = (band == LIBIPW_24GHZ_BAND) ?
 		    geo->bg[i].flags : geo->a[i].flags;
-		if (flags & IEEE80211_CH_PASSIVE_ONLY) {
+		if (flags & LIBIPW_CH_PASSIVE_ONLY) {
 			IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
 			return -EINVAL;
 		}
@@ -8779,7 +8778,7 @@ static int ipw_wx_get_freq(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 
 	wrqu->freq.e = 0;
 
@@ -8790,16 +8789,16 @@ static int ipw_wx_get_freq(struct net_device *dev,
 	    priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) {
 		int i;
 
-		i = ieee80211_channel_to_index(priv->ieee, priv->channel);
+		i = libipw_channel_to_index(priv->ieee, priv->channel);
 		BUG_ON(i == -1);
 		wrqu->freq.e = 1;
 
-		switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
-		case IEEE80211_52GHZ_BAND:
+		switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
+		case LIBIPW_52GHZ_BAND:
 			wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000;
 			break;
 
-		case IEEE80211_24GHZ_BAND:
+		case LIBIPW_24GHZ_BAND:
 			wrqu->freq.m = priv->ieee->geo.bg[i].freq * 100000;
 			break;
 
@@ -8818,7 +8817,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
@@ -8870,7 +8869,7 @@ static int ipw_wx_get_mode(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	wrqu->mode = priv->ieee->iw_mode;
 	IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
@@ -8899,9 +8898,9 @@ static int ipw_wx_get_range(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	struct iw_range *range = (struct iw_range *)extra;
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
 	int i = 0, j;
 
 	wrqu->data.length = sizeof(*range);
@@ -8945,7 +8944,7 @@ static int ipw_wx_get_range(struct net_device *dev,
 	if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
 		for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {
 			if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
-			    (geo->bg[j].flags & IEEE80211_CH_PASSIVE_ONLY))
+			    (geo->bg[j].flags & LIBIPW_CH_PASSIVE_ONLY))
 				continue;
 
 			range->freq[i].i = geo->bg[j].channel;
@@ -8958,7 +8957,7 @@ static int ipw_wx_get_range(struct net_device *dev,
 	if (priv->ieee->mode & IEEE_A) {
 		for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {
 			if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
-			    (geo->a[j].flags & IEEE80211_CH_PASSIVE_ONLY))
+			    (geo->a[j].flags & LIBIPW_CH_PASSIVE_ONLY))
 				continue;
 
 			range->freq[i].i = geo->a[j].channel;
@@ -8993,7 +8992,7 @@ static int ipw_wx_set_wap(struct net_device *dev,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 
 	static const unsigned char any[] = {
 		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
@@ -9042,7 +9041,7 @@ static int ipw_wx_get_wap(struct net_device *dev,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 
 	/* If we are associated, trying to associate, or have a statically
 	 * configured BSSID then return that; otherwise return ANY */
@@ -9064,7 +9063,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
         int length;
 	DECLARE_SSID_BUF(ssid);
 
@@ -9110,7 +9109,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	DECLARE_SSID_BUF(ssid);
 
 	/* If we are associated, trying to associate, or have a statically
@@ -9136,7 +9135,7 @@ static int ipw_wx_set_nick(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 
 	IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE)
@@ -9155,7 +9154,7 @@ static int ipw_wx_get_nick(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	IPW_DEBUG_WX("Getting nick\n");
 	mutex_lock(&priv->mutex);
 	wrqu->data.length = strlen(priv->nick);
@@ -9169,7 +9168,7 @@ static int ipw_wx_set_sens(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value);
@@ -9199,7 +9198,7 @@ static int ipw_wx_get_sens(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	wrqu->sens.fixed = 1;
 	wrqu->sens.value = priv->roaming_threshold;
@@ -9216,7 +9215,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
 			   union iwreq_data *wrqu, char *extra)
 {
 	/* TODO: We should use semaphores or locks for access to priv */
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	u32 target_rate = wrqu->bitrate.value;
 	u32 fixed, mask;
 
@@ -9226,7 +9225,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
 
 	if (target_rate == -1) {
 		fixed = 0;
-		mask = IEEE80211_DEFAULT_RATES_MASK;
+		mask = LIBIPW_DEFAULT_RATES_MASK;
 		/* Now we should reassociate */
 		goto apply;
 	}
@@ -9235,62 +9234,62 @@ static int ipw_wx_set_rate(struct net_device *dev,
 	fixed = wrqu->bitrate.fixed;
 
 	if (target_rate == 1000000 || !fixed)
-		mask |= IEEE80211_CCK_RATE_1MB_MASK;
+		mask |= LIBIPW_CCK_RATE_1MB_MASK;
 	if (target_rate == 1000000)
 		goto apply;
 
 	if (target_rate == 2000000 || !fixed)
-		mask |= IEEE80211_CCK_RATE_2MB_MASK;
+		mask |= LIBIPW_CCK_RATE_2MB_MASK;
 	if (target_rate == 2000000)
 		goto apply;
 
 	if (target_rate == 5500000 || !fixed)
-		mask |= IEEE80211_CCK_RATE_5MB_MASK;
+		mask |= LIBIPW_CCK_RATE_5MB_MASK;
 	if (target_rate == 5500000)
 		goto apply;
 
 	if (target_rate == 6000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_6MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_6MB_MASK;
 	if (target_rate == 6000000)
 		goto apply;
 
 	if (target_rate == 9000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_9MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_9MB_MASK;
 	if (target_rate == 9000000)
 		goto apply;
 
 	if (target_rate == 11000000 || !fixed)
-		mask |= IEEE80211_CCK_RATE_11MB_MASK;
+		mask |= LIBIPW_CCK_RATE_11MB_MASK;
 	if (target_rate == 11000000)
 		goto apply;
 
 	if (target_rate == 12000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_12MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_12MB_MASK;
 	if (target_rate == 12000000)
 		goto apply;
 
 	if (target_rate == 18000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_18MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_18MB_MASK;
 	if (target_rate == 18000000)
 		goto apply;
 
 	if (target_rate == 24000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_24MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_24MB_MASK;
 	if (target_rate == 24000000)
 		goto apply;
 
 	if (target_rate == 36000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_36MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_36MB_MASK;
 	if (target_rate == 36000000)
 		goto apply;
 
 	if (target_rate == 48000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_48MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_48MB_MASK;
 	if (target_rate == 48000000)
 		goto apply;
 
 	if (target_rate == 54000000 || !fixed)
-		mask |= IEEE80211_OFDM_RATE_54MB_MASK;
+		mask |= LIBIPW_OFDM_RATE_54MB_MASK;
 	if (target_rate == 54000000)
 		goto apply;
 
@@ -9301,7 +9300,7 @@ static int ipw_wx_set_rate(struct net_device *dev,
 	IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
 		     mask, fixed ? "fixed" : "sub-rates");
 	mutex_lock(&priv->mutex);
-	if (mask == IEEE80211_DEFAULT_RATES_MASK) {
+	if (mask == LIBIPW_DEFAULT_RATES_MASK) {
 		priv->config &= ~CFG_FIXED_RATE;
 		ipw_set_fixed_rate(priv, priv->ieee->mode);
 	} else
@@ -9328,7 +9327,7 @@ static int ipw_wx_get_rate(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	wrqu->bitrate.value = priv->last_rate;
 	wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;
@@ -9341,7 +9340,7 @@ static int ipw_wx_set_rts(struct net_device *dev,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	if (wrqu->rts.disabled || !wrqu->rts.fixed)
 		priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
@@ -9364,7 +9363,7 @@ static int ipw_wx_get_rts(struct net_device *dev,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	wrqu->rts.value = priv->rts_threshold;
 	wrqu->rts.fixed = 0;	/* no auto select */
@@ -9378,7 +9377,7 @@ static int ipw_wx_set_txpow(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int err = 0;
 
 	mutex_lock(&priv->mutex);
@@ -9412,7 +9411,7 @@ static int ipw_wx_get_txpow(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	wrqu->power.value = priv->tx_power;
 	wrqu->power.fixed = 1;
@@ -9430,7 +9429,7 @@ static int ipw_wx_set_frag(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	if (wrqu->frag.disabled || !wrqu->frag.fixed)
 		priv->ieee->fts = DEFAULT_FTS;
@@ -9454,7 +9453,7 @@ static int ipw_wx_get_frag(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	wrqu->frag.value = priv->ieee->fts;
 	wrqu->frag.fixed = 0;	/* no auto select */
@@ -9469,7 +9468,7 @@ static int ipw_wx_set_retry(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 
 	if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
 		return -EINVAL;
@@ -9502,7 +9501,7 @@ static int ipw_wx_get_retry(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 
 	mutex_lock(&priv->mutex);
 	wrqu->retry.disabled = 0;
@@ -9533,7 +9532,7 @@ static int ipw_wx_set_scan(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	struct iw_scan_req *req = (struct iw_scan_req *)extra;
 	struct delayed_work *work = NULL;
 
@@ -9569,20 +9568,20 @@ static int ipw_wx_get_scan(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
+	struct ipw_priv *priv = libipw_priv(dev);
+	return libipw_wx_get_scan(priv->ieee, info, wrqu, extra);
 }
 
 static int ipw_wx_set_encode(struct net_device *dev,
 			     struct iw_request_info *info,
 			     union iwreq_data *wrqu, char *key)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int ret;
 	u32 cap = priv->capability;
 
 	mutex_lock(&priv->mutex);
-	ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
+	ret = libipw_wx_set_encode(priv->ieee, info, wrqu, key);
 
 	/* In IBSS mode, we need to notify the firmware to update
 	 * the beacon info after we changed the capability. */
@@ -9599,15 +9598,15 @@ static int ipw_wx_get_encode(struct net_device *dev,
 			     struct iw_request_info *info,
 			     union iwreq_data *wrqu, char *key)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
+	struct ipw_priv *priv = libipw_priv(dev);
+	return libipw_wx_get_encode(priv->ieee, info, wrqu, key);
 }
 
 static int ipw_wx_set_power(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int err;
 	mutex_lock(&priv->mutex);
 	if (wrqu->power.disabled) {
@@ -9658,7 +9657,7 @@ static int ipw_wx_get_power(struct net_device *dev,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
@@ -9675,7 +9674,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int mode = *(int *)extra;
 	int err;
 
@@ -9701,7 +9700,7 @@ static int ipw_wx_get_powermode(struct net_device *dev,
 				struct iw_request_info *info,
 				union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int level = IPW_POWER_LEVEL(priv->power_mode);
 	char *p = extra;
 
@@ -9733,7 +9732,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int mode = *(int *)extra;
 	u8 band = 0, modulation = 0;
 
@@ -9745,8 +9744,8 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
 	if (priv->adapter == IPW_2915ABG) {
 		priv->ieee->abg_true = 1;
 		if (mode & IEEE_A) {
-			band |= IEEE80211_52GHZ_BAND;
-			modulation |= IEEE80211_OFDM_MODULATION;
+			band |= LIBIPW_52GHZ_BAND;
+			modulation |= LIBIPW_OFDM_MODULATION;
 		} else
 			priv->ieee->abg_true = 0;
 	} else {
@@ -9761,14 +9760,14 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
 	}
 
 	if (mode & IEEE_B) {
-		band |= IEEE80211_24GHZ_BAND;
-		modulation |= IEEE80211_CCK_MODULATION;
+		band |= LIBIPW_24GHZ_BAND;
+		modulation |= LIBIPW_CCK_MODULATION;
 	} else
 		priv->ieee->abg_true = 0;
 
 	if (mode & IEEE_G) {
-		band |= IEEE80211_24GHZ_BAND;
-		modulation |= IEEE80211_OFDM_MODULATION;
+		band |= LIBIPW_24GHZ_BAND;
+		modulation |= LIBIPW_OFDM_MODULATION;
 	} else
 		priv->ieee->abg_true = 0;
 
@@ -9798,7 +9797,7 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
 				    struct iw_request_info *info,
 				    union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	switch (priv->ieee->mode) {
 	case IEEE_A:
@@ -9839,7 +9838,7 @@ static int ipw_wx_set_preamble(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int mode = *(int *)extra;
 	mutex_lock(&priv->mutex);
 	/* Switching from SHORT -> LONG requires a disassociation */
@@ -9872,7 +9871,7 @@ static int ipw_wx_get_preamble(struct net_device *dev,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	mutex_lock(&priv->mutex);
 	if (priv->config & CFG_PREAMBLE_LONG)
 		snprintf(wrqu->name, IFNAMSIZ, "long (1)");
@@ -9887,7 +9886,7 @@ static int ipw_wx_set_monitor(struct net_device *dev,
 			      struct iw_request_info *info,
 			      union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int *parms = (int *)extra;
 	int enable = (parms[0] > 0);
 	mutex_lock(&priv->mutex);
@@ -9921,7 +9920,7 @@ static int ipw_wx_reset(struct net_device *dev,
 			struct iw_request_info *info,
 			union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	IPW_DEBUG_WX("RESET\n");
 	queue_work(priv->workqueue, &priv->adapter_restart);
 	return 0;
@@ -9931,7 +9930,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	union iwreq_data wrqu_sec = {
 		.encoding = {
 			     .flags = IW_ENCODE_DISABLED,
@@ -9954,7 +9953,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 	ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
 
 	mutex_unlock(&priv->mutex);
-	ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
+	libipw_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
 	mutex_lock(&priv->mutex);
 
 	if (!(priv->status & STATUS_RF_KILL_MASK)) {
@@ -9973,7 +9972,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 /* Rebase the WE IOCTLs to zero for the handler array */
 #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
 static iw_handler ipw_wx_handlers[] = {
-	IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
+	IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
 	IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
 	IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
 	IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@@ -10099,7 +10098,7 @@ static struct iw_handler_def ipw_wx_handler_def = {
  */
 static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	struct iw_statistics *wstats;
 
 	wstats = &priv->wstats;
@@ -10180,13 +10179,13 @@ static int ipw_net_stop(struct net_device *dev)
 todo:
 
 modify to send one tfd per fragment instead of using chunking.  otherwise
-we need to heavily modify the ieee80211_skb_to_txb.
+we need to heavily modify the libipw_skb_to_txb.
 */
 
-static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
+static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb,
 			     int pri)
 {
-	struct ieee80211_hdr_3addrqos *hdr = (struct ieee80211_hdr_3addrqos *)
+	struct libipw_hdr_3addrqos *hdr = (struct libipw_hdr_3addrqos *)
 	    txb->fragments[0]->data;
 	int i = 0;
 	struct tfd_frame *tfd;
@@ -10198,13 +10197,12 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
 #endif
 	struct clx2_queue *q = &txq->q;
 	u8 id, hdr_len, unicast;
-	u16 remaining_bytes;
 	int fc;
 
 	if (!(priv->status & STATUS_ASSOCIATED))
 		goto drop;
 
-	hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdr_len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
 		unicast = !is_multicast_ether_addr(hdr->addr1);
@@ -10237,7 +10235,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
 
 	tfd->u.data.cmd_id = DINO_CMD_TX;
 	tfd->u.data.len = cpu_to_le16(txb->payload_size);
-	remaining_bytes = txb->payload_size;
 
 	if (priv->assoc_request.ieee_mode == IPW_B_MODE)
 		tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
@@ -10374,13 +10371,13 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
 
       drop:
 	IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
-	ieee80211_txb_free(txb);
+	libipw_txb_free(txb);
 	return NETDEV_TX_OK;
 }
 
 static int ipw_net_is_queue_full(struct net_device *dev, int pri)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 #ifdef CONFIG_IPW2200_QOS
 	int tx_id = ipw_get_tx_queue_number(priv, pri);
 	struct clx2_tx_queue *txq = &priv->txq[tx_id];
@@ -10396,9 +10393,9 @@ static int ipw_net_is_queue_full(struct net_device *dev, int pri)
 
 #ifdef CONFIG_IPW2200_PROMISCUOUS
 static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
-				      struct ieee80211_txb *txb)
+				      struct libipw_txb *txb)
 {
-	struct ieee80211_rx_stats dummystats;
+	struct libipw_rx_stats dummystats;
 	struct ieee80211_hdr *hdr;
 	u8 n;
 	u16 filter = priv->prom_priv->filter;
@@ -10411,17 +10408,17 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
 
 	/* Filtering of fragment chains is done agains the first fragment */
 	hdr = (void *)txb->fragments[0]->data;
-	if (ieee80211_is_management(le16_to_cpu(hdr->frame_control))) {
+	if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {
 		if (filter & IPW_PROM_NO_MGMT)
 			return;
 		if (filter & IPW_PROM_MGMT_HEADER_ONLY)
 			hdr_only = 1;
-	} else if (ieee80211_is_control(le16_to_cpu(hdr->frame_control))) {
+	} else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {
 		if (filter & IPW_PROM_NO_CTL)
 			return;
 		if (filter & IPW_PROM_CTL_HEADER_ONLY)
 			hdr_only = 1;
-	} else if (ieee80211_is_data(le16_to_cpu(hdr->frame_control))) {
+	} else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {
 		if (filter & IPW_PROM_NO_DATA)
 			return;
 		if (filter & IPW_PROM_DATA_HEADER_ONLY)
@@ -10436,7 +10433,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
 
 		if (hdr_only) {
 			hdr = (void *)src->data;
-			len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));
+			len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));
 		} else
 			len = src->len;
 
@@ -10470,18 +10467,18 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
 
 		skb_copy_from_linear_data(src, skb_put(dst, len), len);
 
-		if (!ieee80211_rx(priv->prom_priv->ieee, dst, &dummystats))
+		if (!libipw_rx(priv->prom_priv->ieee, dst, &dummystats))
 			dev_kfree_skb_any(dst);
 	}
 }
 #endif
 
-static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
-				   struct net_device *dev, int pri)
+static netdev_tx_t ipw_net_hard_start_xmit(struct libipw_txb *txb,
+					   struct net_device *dev, int pri)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	unsigned long flags;
-	int ret;
+	netdev_tx_t ret;
 
 	IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
 	spin_lock_irqsave(&priv->lock, flags);
@@ -10506,7 +10503,7 @@ static void ipw_net_set_multicast_list(struct net_device *dev)
 
 static int ipw_net_set_mac_address(struct net_device *dev, void *p)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	struct sockaddr *addr = p;
 
 	if (!is_valid_ether_addr(addr->sa_data))
@@ -10524,7 +10521,7 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 				    struct ethtool_drvinfo *info)
 {
-	struct ipw_priv *p = ieee80211_priv(dev);
+	struct ipw_priv *p = libipw_priv(dev);
 	char vers[64];
 	char date[32];
 	u32 len;
@@ -10545,7 +10542,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 
 static u32 ipw_ethtool_get_link(struct net_device *dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	return (priv->status & STATUS_ASSOCIATED) != 0;
 }
 
@@ -10557,7 +10554,7 @@ static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
 static int ipw_ethtool_get_eeprom(struct net_device *dev,
 				  struct ethtool_eeprom *eeprom, u8 * bytes)
 {
-	struct ipw_priv *p = ieee80211_priv(dev);
+	struct ipw_priv *p = libipw_priv(dev);
 
 	if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
 		return -EINVAL;
@@ -10570,7 +10567,7 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
 static int ipw_ethtool_set_eeprom(struct net_device *dev,
 				  struct ethtool_eeprom *eeprom, u8 * bytes)
 {
-	struct ipw_priv *p = ieee80211_priv(dev);
+	struct ipw_priv *p = libipw_priv(dev);
 	int i;
 
 	if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
@@ -10786,9 +10783,9 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv)
 }
 
 static void shim__set_security(struct net_device *dev,
-			       struct ieee80211_security *sec)
+			       struct libipw_security *sec)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ipw_priv *priv = libipw_priv(dev);
 	int i;
 	for (i = 0; i < 4; i++) {
 		if (sec->flags & (1 << i)) {
@@ -10873,21 +10870,21 @@ static int init_supported_rates(struct ipw_priv *priv,
 	memset(rates, 0, sizeof(*rates));
 	/* configure supported rates */
 	switch (priv->ieee->freq_band) {
-	case IEEE80211_52GHZ_BAND:
+	case LIBIPW_52GHZ_BAND:
 		rates->ieee_mode = IPW_A_MODE;
 		rates->purpose = IPW_RATE_CAPABILITIES;
-		ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
-					IEEE80211_OFDM_DEFAULT_RATES_MASK);
+		ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,
+					LIBIPW_OFDM_DEFAULT_RATES_MASK);
 		break;
 
 	default:		/* Mixed or 2.4Ghz */
 		rates->ieee_mode = IPW_G_MODE;
 		rates->purpose = IPW_RATE_CAPABILITIES;
-		ipw_add_cck_scan_rates(rates, IEEE80211_CCK_MODULATION,
-				       IEEE80211_CCK_DEFAULT_RATES_MASK);
-		if (priv->ieee->modulation & IEEE80211_OFDM_MODULATION) {
-			ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
-						IEEE80211_OFDM_DEFAULT_RATES_MASK);
+		ipw_add_cck_scan_rates(rates, LIBIPW_CCK_MODULATION,
+				       LIBIPW_CCK_DEFAULT_RATES_MASK);
+		if (priv->ieee->modulation & LIBIPW_OFDM_MODULATION) {
+			ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,
+						LIBIPW_OFDM_DEFAULT_RATES_MASK);
 		}
 		break;
 	}
@@ -10993,7 +10990,7 @@ static int ipw_config(struct ipw_priv *priv)
  * table.
  *
  */
-static const struct ieee80211_geo ipw_geos[] = {
+static const struct libipw_geo ipw_geos[] = {
 	{			/* Restricted */
 	 "---",
 	 .bg_channels = 11,
@@ -11015,10 +11012,10 @@ static const struct ieee80211_geo ipw_geos[] = {
 	       {5200, 40},
 	       {5220, 44},
 	       {5240, 48},
-	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
-	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
-	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
-	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
+	       {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
+	       {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
+	       {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
+	       {5320, 64, LIBIPW_CH_PASSIVE_ONLY}},
 	 },
 
 	{			/* Rest of World */
@@ -11043,10 +11040,10 @@ static const struct ieee80211_geo ipw_geos[] = {
 	       {5200, 40},
 	       {5220, 44},
 	       {5240, 48},
-	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
-	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
-	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
-	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+	       {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
+	       {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
+	       {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
+	       {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
 	       {5745, 149},
 	       {5765, 153},
 	       {5785, 157},
@@ -11066,15 +11063,15 @@ static const struct ieee80211_geo ipw_geos[] = {
 	       {5200, 40},
 	       {5220, 44},
 	       {5240, 48},
-	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
-	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
-	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
-	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
-	       {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
-	       {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
-	       {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
-	       {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
-	       {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+	       {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
+	       {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
+	       {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
+	       {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
+	       {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
+	       {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
+	       {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
+	       {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
+	       {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
 	 },
 
 	{			/* Custom Japan */
@@ -11111,21 +11108,21 @@ static const struct ieee80211_geo ipw_geos[] = {
 	       {5200, 40},
 	       {5220, 44},
 	       {5240, 48},
-	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
-	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
-	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
-	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
-	       {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
-	       {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
-	       {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
-	       {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
-	       {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
-	       {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
-	       {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
-	       {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
-	       {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
-	       {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
-	       {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
+	       {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
+	       {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
+	       {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
+	       {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
+	       {5500, 100, LIBIPW_CH_PASSIVE_ONLY},
+	       {5520, 104, LIBIPW_CH_PASSIVE_ONLY},
+	       {5540, 108, LIBIPW_CH_PASSIVE_ONLY},
+	       {5560, 112, LIBIPW_CH_PASSIVE_ONLY},
+	       {5580, 116, LIBIPW_CH_PASSIVE_ONLY},
+	       {5600, 120, LIBIPW_CH_PASSIVE_ONLY},
+	       {5620, 124, LIBIPW_CH_PASSIVE_ONLY},
+	       {5640, 128, LIBIPW_CH_PASSIVE_ONLY},
+	       {5660, 132, LIBIPW_CH_PASSIVE_ONLY},
+	       {5680, 136, LIBIPW_CH_PASSIVE_ONLY},
+	       {5700, 140, LIBIPW_CH_PASSIVE_ONLY}},
 	 },
 
 	{			/* Custom Japan */
@@ -11135,7 +11132,7 @@ static const struct ieee80211_geo ipw_geos[] = {
 		{2427, 4}, {2432, 5}, {2437, 6},
 		{2442, 7}, {2447, 8}, {2452, 9},
 		{2457, 10}, {2462, 11}, {2467, 12},
-		{2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
+		{2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY}},
 	 .a_channels = 4,
 	 .a = {{5170, 34}, {5190, 38},
 	       {5210, 42}, {5230, 46}},
@@ -11148,8 +11145,8 @@ static const struct ieee80211_geo ipw_geos[] = {
 		{2427, 4}, {2432, 5}, {2437, 6},
 		{2442, 7}, {2447, 8}, {2452, 9},
 		{2457, 10}, {2462, 11}, {2467, 12},
-		{2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY |
-			     IEEE80211_CH_PASSIVE_ONLY}},
+		{2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY |
+			     LIBIPW_CH_PASSIVE_ONLY}},
 	 },
 
 	{			/* High Band */
@@ -11159,8 +11156,8 @@ static const struct ieee80211_geo ipw_geos[] = {
 		{2427, 4}, {2432, 5}, {2437, 6},
 		{2442, 7}, {2447, 8}, {2452, 9},
 		{2457, 10}, {2462, 11},
-		{2467, 12, IEEE80211_CH_PASSIVE_ONLY},
-		{2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
+		{2467, 12, LIBIPW_CH_PASSIVE_ONLY},
+		{2472, 13, LIBIPW_CH_PASSIVE_ONLY}},
 	 .a_channels = 4,
 	 .a = {{5745, 149}, {5765, 153},
 	       {5785, 157}, {5805, 161}},
@@ -11186,33 +11183,33 @@ static const struct ieee80211_geo ipw_geos[] = {
 		{2427, 4}, {2432, 5}, {2437, 6},
 		{2442, 7}, {2447, 8}, {2452, 9},
 		{2457, 10}, {2462, 11},
-		{2467, 12, IEEE80211_CH_PASSIVE_ONLY},
-		{2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
+		{2467, 12, LIBIPW_CH_PASSIVE_ONLY},
+		{2472, 13, LIBIPW_CH_PASSIVE_ONLY}},
 	 .a_channels = 24,
-	 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
-	       {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
-	       {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
-	       {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
-	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
-	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
-	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
-	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
-	       {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
-	       {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
-	       {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
-	       {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
-	       {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
-	       {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
-	       {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
-	       {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
-	       {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
-	       {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
-	       {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
-	       {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
-	       {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
-	       {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
-	       {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
-	       {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+	 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},
+	       {5200, 40, LIBIPW_CH_PASSIVE_ONLY},
+	       {5220, 44, LIBIPW_CH_PASSIVE_ONLY},
+	       {5240, 48, LIBIPW_CH_PASSIVE_ONLY},
+	       {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
+	       {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
+	       {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
+	       {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
+	       {5500, 100, LIBIPW_CH_PASSIVE_ONLY},
+	       {5520, 104, LIBIPW_CH_PASSIVE_ONLY},
+	       {5540, 108, LIBIPW_CH_PASSIVE_ONLY},
+	       {5560, 112, LIBIPW_CH_PASSIVE_ONLY},
+	       {5580, 116, LIBIPW_CH_PASSIVE_ONLY},
+	       {5600, 120, LIBIPW_CH_PASSIVE_ONLY},
+	       {5620, 124, LIBIPW_CH_PASSIVE_ONLY},
+	       {5640, 128, LIBIPW_CH_PASSIVE_ONLY},
+	       {5660, 132, LIBIPW_CH_PASSIVE_ONLY},
+	       {5680, 136, LIBIPW_CH_PASSIVE_ONLY},
+	       {5700, 140, LIBIPW_CH_PASSIVE_ONLY},
+	       {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
+	       {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
+	       {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
+	       {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
+	       {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
 	 },
 
 	{			/* Europe */
@@ -11223,19 +11220,19 @@ static const struct ieee80211_geo ipw_geos[] = {
 		{2442, 7}, {2447, 8}, {2452, 9},
 		{2457, 10}, {2462, 11}},
 	 .a_channels = 13,
-	 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
-	       {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
-	       {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
-	       {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
-	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
-	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
-	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
-	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
-	       {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
-	       {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
-	       {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
-	       {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
-	       {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+	 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},
+	       {5200, 40, LIBIPW_CH_PASSIVE_ONLY},
+	       {5220, 44, LIBIPW_CH_PASSIVE_ONLY},
+	       {5240, 48, LIBIPW_CH_PASSIVE_ONLY},
+	       {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
+	       {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
+	       {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
+	       {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
+	       {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
+	       {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
+	       {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
+	       {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
+	       {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
 	 }
 };
 
@@ -11246,7 +11243,7 @@ static int ipw_up(struct ipw_priv *priv)
 
 	/* Age scan list entries found before suspend */
 	if (priv->suspend_time) {
-		ieee80211_networks_age(priv->ieee, priv->suspend_time);
+		libipw_networks_age(priv->ieee, priv->suspend_time);
 		priv->suspend_time = 0;
 	}
 
@@ -11291,7 +11288,7 @@ static int ipw_up(struct ipw_priv *priv)
 				    priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
 			j = 0;
 		}
-		if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) {
+		if (libipw_set_geo(priv->ieee, &ipw_geos[j])) {
 			IPW_WARNING("Could not set geography.");
 			return 0;
 		}
@@ -11419,16 +11416,100 @@ static void ipw_bg_down(struct work_struct *work)
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
 {
-	struct ipw_priv *priv = ieee80211_priv(dev);
+	int i, rc = 0;
+	struct ipw_priv *priv = libipw_priv(dev);
+	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
+	struct wireless_dev *wdev = &priv->ieee->wdev;
 	mutex_lock(&priv->mutex);
 
 	if (ipw_up(priv)) {
-		mutex_unlock(&priv->mutex);
-		return -EIO;
+		rc = -EIO;
+		goto out;
+	}
+
+	memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
+
+	/* fill-out priv->ieee->bg_band */
+	if (geo->bg_channels) {
+		struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
+
+		bg_band->band = IEEE80211_BAND_2GHZ;
+		bg_band->n_channels = geo->bg_channels;
+		bg_band->channels =
+			kzalloc(geo->bg_channels *
+				sizeof(struct ieee80211_channel), GFP_KERNEL);
+		/* translate geo->bg to bg_band.channels */
+		for (i = 0; i < geo->bg_channels; i++) {
+			bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
+			bg_band->channels[i].center_freq = geo->bg[i].freq;
+			bg_band->channels[i].hw_value = geo->bg[i].channel;
+			bg_band->channels[i].max_power = geo->bg[i].max_power;
+			if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_PASSIVE_SCAN;
+			if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_NO_IBSS;
+			if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
+				bg_band->channels[i].flags |=
+					IEEE80211_CHAN_RADAR;
+			/* No equivalent for LIBIPW_CH_80211H_RULES,
+			   LIBIPW_CH_UNIFORM_SPREADING, or
+			   LIBIPW_CH_B_ONLY... */
+		}
+		/* point at bitrate info */
+		bg_band->bitrates = ipw2200_bg_rates;
+		bg_band->n_bitrates = ipw2200_num_bg_rates;
+
+		wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
+	}
+
+	/* fill-out priv->ieee->a_band */
+	if (geo->a_channels) {
+		struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
+
+		a_band->band = IEEE80211_BAND_5GHZ;
+		a_band->n_channels = geo->a_channels;
+		a_band->channels =
+			kzalloc(geo->a_channels *
+				sizeof(struct ieee80211_channel), GFP_KERNEL);
+		/* translate geo->bg to a_band.channels */
+		for (i = 0; i < geo->a_channels; i++) {
+			a_band->channels[i].band = IEEE80211_BAND_2GHZ;
+			a_band->channels[i].center_freq = geo->a[i].freq;
+			a_band->channels[i].hw_value = geo->a[i].channel;
+			a_band->channels[i].max_power = geo->a[i].max_power;
+			if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
+				a_band->channels[i].flags |=
+					IEEE80211_CHAN_PASSIVE_SCAN;
+			if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
+				a_band->channels[i].flags |=
+					IEEE80211_CHAN_NO_IBSS;
+			if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
+				a_band->channels[i].flags |=
+					IEEE80211_CHAN_RADAR;
+			/* No equivalent for LIBIPW_CH_80211H_RULES,
+			   LIBIPW_CH_UNIFORM_SPREADING, or
+			   LIBIPW_CH_B_ONLY... */
+		}
+		/* point at bitrate info */
+		a_band->bitrates = ipw2200_a_rates;
+		a_band->n_bitrates = ipw2200_num_a_rates;
+
+		wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
+	}
+
+	set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
+
+	/* With that information in place, we can now register the wiphy... */
+	if (wiphy_register(wdev->wiphy)) {
+		rc = -EIO;
+		goto out;
 	}
 
+out:
 	mutex_unlock(&priv->mutex);
-	return 0;
+	return rc;
 }
 
 /* PCI driver stuff */
@@ -11450,11 +11531,11 @@ static struct pci_device_id card_ids[] = {
 	{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
-	{PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* BG */
-	{PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* BG */
-	{PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* ABG */
-	{PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* ABG */
+	{PCI_VDEVICE(INTEL, 0x104f), 0},
+	{PCI_VDEVICE(INTEL, 0x4220), 0},	/* BG */
+	{PCI_VDEVICE(INTEL, 0x4221), 0},	/* BG */
+	{PCI_VDEVICE(INTEL, 0x4223), 0},	/* ABG */
+	{PCI_VDEVICE(INTEL, 0x4224), 0},	/* ABG */
 
 	/* required last entry */
 	{0,}
@@ -11498,7 +11579,7 @@ static struct attribute_group ipw_attribute_group = {
 #ifdef CONFIG_IPW2200_PROMISCUOUS
 static int ipw_prom_open(struct net_device *dev)
 {
-	struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
+	struct ipw_prom_priv *prom_priv = libipw_priv(dev);
 	struct ipw_priv *priv = prom_priv->priv;
 
 	IPW_DEBUG_INFO("prom dev->open\n");
@@ -11518,7 +11599,7 @@ static int ipw_prom_open(struct net_device *dev)
 
 static int ipw_prom_stop(struct net_device *dev)
 {
-	struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
+	struct ipw_prom_priv *prom_priv = libipw_priv(dev);
 	struct ipw_priv *priv = prom_priv->priv;
 
 	IPW_DEBUG_INFO("prom dev->stop\n");
@@ -11535,7 +11616,8 @@ static int ipw_prom_stop(struct net_device *dev)
 	return 0;
 }
 
-static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ipw_prom_hard_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	IPW_DEBUG_INFO("prom dev->xmit\n");
 	dev_kfree_skb(skb);
@@ -11546,7 +11628,7 @@ static const struct net_device_ops ipw_prom_netdev_ops = {
 	.ndo_open 		= ipw_prom_open,
 	.ndo_stop		= ipw_prom_stop,
 	.ndo_start_xmit		= ipw_prom_hard_start_xmit,
-	.ndo_change_mtu		= ieee80211_change_mtu,
+	.ndo_change_mtu		= libipw_change_mtu,
 	.ndo_set_mac_address 	= eth_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
 };
@@ -11558,11 +11640,11 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
 	if (priv->prom_net_dev)
 		return -EPERM;
 
-	priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
+	priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
 	if (priv->prom_net_dev == NULL)
 		return -ENOMEM;
 
-	priv->prom_priv = ieee80211_priv(priv->prom_net_dev);
+	priv->prom_priv = libipw_priv(priv->prom_net_dev);
 	priv->prom_priv->ieee = netdev_priv(priv->prom_net_dev);
 	priv->prom_priv->priv = priv;
 
@@ -11577,7 +11659,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
 
 	rc = register_netdev(priv->prom_net_dev);
 	if (rc) {
-		free_ieee80211(priv->prom_net_dev);
+		free_ieee80211(priv->prom_net_dev, 1);
 		priv->prom_net_dev = NULL;
 		return rc;
 	}
@@ -11591,7 +11673,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
 		return;
 
 	unregister_netdev(priv->prom_net_dev);
-	free_ieee80211(priv->prom_net_dev);
+	free_ieee80211(priv->prom_net_dev, 1);
 
 	priv->prom_net_dev = NULL;
 }
@@ -11604,8 +11686,8 @@ static const struct net_device_ops ipw_netdev_ops = {
 	.ndo_stop		= ipw_net_stop,
 	.ndo_set_multicast_list	= ipw_net_set_multicast_list,
 	.ndo_set_mac_address	= ipw_net_set_mac_address,
-	.ndo_start_xmit		= ieee80211_xmit,
-	.ndo_change_mtu		= ieee80211_change_mtu,
+	.ndo_start_xmit		= libipw_xmit,
+	.ndo_change_mtu		= libipw_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
@@ -11619,13 +11701,13 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
 	struct ipw_priv *priv;
 	int i;
 
-	net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
+	net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
 	if (net_dev == NULL) {
 		err = -ENOMEM;
 		goto out;
 	}
 
-	priv = ieee80211_priv(net_dev);
+	priv = libipw_priv(net_dev);
 	priv->ieee = netdev_priv(net_dev);
 
 	priv->net_dev = net_dev;
@@ -11767,7 +11849,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
       out_free_ieee80211:
-	free_ieee80211(priv->net_dev);
+	free_ieee80211(priv->net_dev, 0);
       out:
 	return err;
 }
@@ -11834,7 +11916,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
-	free_ieee80211(priv->net_dev);
+	free_ieee80211(priv->net_dev, 0);
 	free_firmware();
 }
 
@@ -11963,13 +12045,13 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");
 module_param(auto_create, int, 0444);
 MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
 
-module_param(led, int, 0444);
+module_param_named(led, led_support, int, 0444);
 MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)");
 
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
 
-module_param(channel, int, 0444);
+module_param_named(channel, default_channel, int, 0444);
 MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
 
 #ifdef CONFIG_IPW2200_PROMISCUOUS
@@ -11995,10 +12077,10 @@ MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
 #endif				/* CONFIG_IPW2200_QOS */
 
 #ifdef CONFIG_IPW2200_MONITOR
-module_param(mode, int, 0444);
+module_param_named(mode, network_mode, int, 0444);
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
 #else
-module_param(mode, int, 0444);
+module_param_named(mode, network_mode, int, 0444);
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
 #endif
 
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index 05e8ccf..bf0eeb2 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
@@ -19,7 +19,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 ******************************************************************************/
@@ -55,7 +55,7 @@
 
 #include <linux/workqueue.h>
 
-#include "ieee80211.h"
+#include "libipw.h"
 
 /* Authentication  and Association States */
 enum connection_manager_assoc_states {
@@ -365,8 +365,8 @@ enum connection_manager_assoc_states {
 /* QoS sturctures */
 struct ipw_qos_info {
 	int qos_enable;
-	struct ieee80211_qos_parameters *def_qos_parm_OFDM;
-	struct ieee80211_qos_parameters *def_qos_parm_CCK;
+	struct libipw_qos_parameters *def_qos_parm_OFDM;
+	struct libipw_qos_parameters *def_qos_parm_CCK;
 	u32 burst_duration_CCK;
 	u32 burst_duration_OFDM;
 	u16 qos_no_ack_mask;
@@ -534,7 +534,7 @@ typedef void destructor_func(const void *);
 struct clx2_tx_queue {
 	struct clx2_queue q;
 	struct tfd_frame *bd;
-	struct ieee80211_txb **txb;
+	struct libipw_txb **txb;
 };
 
 /*
@@ -1144,7 +1144,7 @@ enum ipw_prom_filter {
 struct ipw_priv;
 struct ipw_prom_priv {
 	struct ipw_priv *priv;
-	struct ieee80211_device *ieee;
+	struct libipw_device *ieee;
 	enum ipw_prom_filter filter;
 	int tx_packets;
 	int rx_packets;
@@ -1175,7 +1175,7 @@ struct ipw_rt_hdr {
 
 struct ipw_priv {
 	/* ieee device used by generic ieee processing code */
-	struct ieee80211_device *ieee;
+	struct libipw_device *ieee;
 
 	spinlock_t lock;
 	spinlock_t irq_lock;
@@ -1222,7 +1222,7 @@ struct ipw_priv {
 	u32 roaming_threshold;
 
 	struct ipw_associate assoc_request;
-	struct ieee80211_network *assoc_network;
+	struct libipw_network *assoc_network;
 
 	unsigned long ts_scan_abort;
 	struct ipw_supported_rates rates;
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
new file mode 100644
index 0000000..bf45391
--- /dev/null
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -0,0 +1,1092 @@
+/*
+ * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
+ * remains copyright by the original authors
+ *
+ * Portions of the merged code are based on Host AP (software wireless
+ * LAN access point) driver for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <j@w1.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ * Copyright (c) 2004-2005, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. See README and COPYING for
+ * more details.
+ *
+ * API Version History
+ * 1.0.x -- Initial version
+ * 1.1.x -- Added radiotap, QoS, TIM, libipw_geo APIs,
+ *          various structure changes, and crypto API init method
+ */
+#ifndef LIBIPW_H
+#define LIBIPW_H
+#include <linux/if_ether.h>	/* ETH_ALEN */
+#include <linux/kernel.h>	/* ARRAY_SIZE */
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+
+#include <net/lib80211.h>
+#include <net/cfg80211.h>
+
+#define LIBIPW_VERSION "git-1.1.13"
+
+#define LIBIPW_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 LIBIPW_1ADDR_LEN 10
+#define LIBIPW_2ADDR_LEN 16
+#define LIBIPW_3ADDR_LEN 24
+#define LIBIPW_4ADDR_LEN 30
+#define LIBIPW_FCS_LEN    4
+#define LIBIPW_HLEN			(LIBIPW_4ADDR_LEN)
+#define LIBIPW_FRAME_LEN		(LIBIPW_DATA_LEN + LIBIPW_HLEN)
+
+#define MIN_FRAG_THRESHOLD     256U
+#define	MAX_FRAG_THRESHOLD     2346U
+
+/* QOS control */
+#define LIBIPW_QCTL_TID		0x000F
+
+/* debug macros */
+
+#ifdef CONFIG_LIBIPW_DEBUG
+extern u32 libipw_debug_level;
+#define LIBIPW_DEBUG(level, fmt, args...) \
+do { if (libipw_debug_level & (level)) \
+  printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
+         in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
+static inline bool libipw_ratelimit_debug(u32 level)
+{
+	return (libipw_debug_level & level) && net_ratelimit();
+}
+#else
+#define LIBIPW_DEBUG(level, fmt, args...) do {} while (0)
+static inline bool libipw_ratelimit_debug(u32 level)
+{
+	return false;
+}
+#endif				/* CONFIG_LIBIPW_DEBUG */
+
+/*
+ * To use the debug system:
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define LIBIPW_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry.  xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a LIBIPW_xxxx_DEBUG() macro definition for your
+ * classification, or use LIBIPW_DEBUG(LIBIPW_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/ieee80211/debug_level
+ *
+ * you simply need to add your entry to the libipw_debug_level array.
+ *
+ * If you do not see debug_level in /proc/net/ieee80211 then you do not have
+ * CONFIG_LIBIPW_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define LIBIPW_DL_INFO          (1<<0)
+#define LIBIPW_DL_WX            (1<<1)
+#define LIBIPW_DL_SCAN          (1<<2)
+#define LIBIPW_DL_STATE         (1<<3)
+#define LIBIPW_DL_MGMT          (1<<4)
+#define LIBIPW_DL_FRAG          (1<<5)
+#define LIBIPW_DL_DROP          (1<<7)
+
+#define LIBIPW_DL_TX            (1<<8)
+#define LIBIPW_DL_RX            (1<<9)
+#define LIBIPW_DL_QOS           (1<<31)
+
+#define LIBIPW_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
+#define LIBIPW_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
+#define LIBIPW_DEBUG_INFO(f, a...)   LIBIPW_DEBUG(LIBIPW_DL_INFO, f, ## a)
+
+#define LIBIPW_DEBUG_WX(f, a...)     LIBIPW_DEBUG(LIBIPW_DL_WX, f, ## a)
+#define LIBIPW_DEBUG_SCAN(f, a...)   LIBIPW_DEBUG(LIBIPW_DL_SCAN, f, ## a)
+#define LIBIPW_DEBUG_STATE(f, a...)  LIBIPW_DEBUG(LIBIPW_DL_STATE, f, ## a)
+#define LIBIPW_DEBUG_MGMT(f, a...)  LIBIPW_DEBUG(LIBIPW_DL_MGMT, f, ## a)
+#define LIBIPW_DEBUG_FRAG(f, a...)  LIBIPW_DEBUG(LIBIPW_DL_FRAG, f, ## a)
+#define LIBIPW_DEBUG_DROP(f, a...)  LIBIPW_DEBUG(LIBIPW_DL_DROP, f, ## a)
+#define LIBIPW_DEBUG_TX(f, a...)  LIBIPW_DEBUG(LIBIPW_DL_TX, f, ## a)
+#define LIBIPW_DEBUG_RX(f, a...)  LIBIPW_DEBUG(LIBIPW_DL_RX, f, ## a)
+#define LIBIPW_DEBUG_QOS(f, a...)  LIBIPW_DEBUG(LIBIPW_DL_QOS, f, ## a)
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>	/* ARPHRD_ETHER */
+
+#ifndef WIRELESS_SPY
+#define WIRELESS_SPY		/* enable iwspy support */
+#endif
+#include <net/iw_handler.h>	/* new driver API */
+
+#define ETH_P_PREAUTH 0x88C7	/* IEEE 802.11i pre-authentication */
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#endif
+
+/* IEEE 802.11 defines */
+
+#define P80211_OUI_LEN 3
+
+struct libipw_snap_hdr {
+
+	u8 dsap;		/* always 0xAA */
+	u8 ssap;		/* always 0xAA */
+	u8 ctrl;		/* always 0x03 */
+	u8 oui[P80211_OUI_LEN];	/* organizational universal id */
+
+} __attribute__ ((packed));
+
+#define SNAP_SIZE sizeof(struct libipw_snap_hdr)
+
+#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+#define LIBIPW_STATMASK_SIGNAL (1<<0)
+#define LIBIPW_STATMASK_RSSI (1<<1)
+#define LIBIPW_STATMASK_NOISE (1<<2)
+#define LIBIPW_STATMASK_RATE (1<<3)
+#define LIBIPW_STATMASK_WEMASK 0x7
+
+#define LIBIPW_CCK_MODULATION    (1<<0)
+#define LIBIPW_OFDM_MODULATION   (1<<1)
+
+#define LIBIPW_24GHZ_BAND     (1<<0)
+#define LIBIPW_52GHZ_BAND     (1<<1)
+
+#define LIBIPW_CCK_RATE_1MB		        0x02
+#define LIBIPW_CCK_RATE_2MB		        0x04
+#define LIBIPW_CCK_RATE_5MB		        0x0B
+#define LIBIPW_CCK_RATE_11MB		        0x16
+#define LIBIPW_OFDM_RATE_6MB		        0x0C
+#define LIBIPW_OFDM_RATE_9MB		        0x12
+#define LIBIPW_OFDM_RATE_12MB		0x18
+#define LIBIPW_OFDM_RATE_18MB		0x24
+#define LIBIPW_OFDM_RATE_24MB		0x30
+#define LIBIPW_OFDM_RATE_36MB		0x48
+#define LIBIPW_OFDM_RATE_48MB		0x60
+#define LIBIPW_OFDM_RATE_54MB		0x6C
+#define LIBIPW_BASIC_RATE_MASK		0x80
+
+#define LIBIPW_CCK_RATE_1MB_MASK		(1<<0)
+#define LIBIPW_CCK_RATE_2MB_MASK		(1<<1)
+#define LIBIPW_CCK_RATE_5MB_MASK		(1<<2)
+#define LIBIPW_CCK_RATE_11MB_MASK		(1<<3)
+#define LIBIPW_OFDM_RATE_6MB_MASK		(1<<4)
+#define LIBIPW_OFDM_RATE_9MB_MASK		(1<<5)
+#define LIBIPW_OFDM_RATE_12MB_MASK		(1<<6)
+#define LIBIPW_OFDM_RATE_18MB_MASK		(1<<7)
+#define LIBIPW_OFDM_RATE_24MB_MASK		(1<<8)
+#define LIBIPW_OFDM_RATE_36MB_MASK		(1<<9)
+#define LIBIPW_OFDM_RATE_48MB_MASK		(1<<10)
+#define LIBIPW_OFDM_RATE_54MB_MASK		(1<<11)
+
+#define LIBIPW_CCK_RATES_MASK	        0x0000000F
+#define LIBIPW_CCK_BASIC_RATES_MASK	(LIBIPW_CCK_RATE_1MB_MASK | \
+	LIBIPW_CCK_RATE_2MB_MASK)
+#define LIBIPW_CCK_DEFAULT_RATES_MASK	(LIBIPW_CCK_BASIC_RATES_MASK | \
+        LIBIPW_CCK_RATE_5MB_MASK | \
+        LIBIPW_CCK_RATE_11MB_MASK)
+
+#define LIBIPW_OFDM_RATES_MASK		0x00000FF0
+#define LIBIPW_OFDM_BASIC_RATES_MASK	(LIBIPW_OFDM_RATE_6MB_MASK | \
+	LIBIPW_OFDM_RATE_12MB_MASK | \
+	LIBIPW_OFDM_RATE_24MB_MASK)
+#define LIBIPW_OFDM_DEFAULT_RATES_MASK	(LIBIPW_OFDM_BASIC_RATES_MASK | \
+	LIBIPW_OFDM_RATE_9MB_MASK  | \
+	LIBIPW_OFDM_RATE_18MB_MASK | \
+	LIBIPW_OFDM_RATE_36MB_MASK | \
+	LIBIPW_OFDM_RATE_48MB_MASK | \
+	LIBIPW_OFDM_RATE_54MB_MASK)
+#define LIBIPW_DEFAULT_RATES_MASK (LIBIPW_OFDM_DEFAULT_RATES_MASK | \
+                                LIBIPW_CCK_DEFAULT_RATES_MASK)
+
+#define LIBIPW_NUM_OFDM_RATES	    8
+#define LIBIPW_NUM_CCK_RATES	            4
+#define LIBIPW_OFDM_SHIFT_MASK_A         4
+
+/* NOTE: This data is for statistical purposes; not all hardware provides this
+ *       information for frames received.
+ *       For libipw_rx_mgt, you need to set at least the 'len' parameter.
+ */
+struct libipw_rx_stats {
+	u32 mac_time;
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate;		/* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+};
+
+/* IEEE 802.11 requires that STA supports concurrent reception of at least
+ * three fragmented frames. This define can be increased to support more
+ * concurrent frames, but it should be noted that each entry can consume about
+ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
+#define LIBIPW_FRAG_CACHE_LEN 4
+
+struct libipw_frag_entry {
+	unsigned long first_frag_time;
+	unsigned int seq;
+	unsigned int last_frag;
+	struct sk_buff *skb;
+	u8 src_addr[ETH_ALEN];
+	u8 dst_addr[ETH_ALEN];
+};
+
+struct libipw_stats {
+	unsigned int tx_unicast_frames;
+	unsigned int tx_multicast_frames;
+	unsigned int tx_fragments;
+	unsigned int tx_unicast_octets;
+	unsigned int tx_multicast_octets;
+	unsigned int tx_deferred_transmissions;
+	unsigned int tx_single_retry_frames;
+	unsigned int tx_multiple_retry_frames;
+	unsigned int tx_retry_limit_exceeded;
+	unsigned int tx_discards;
+	unsigned int rx_unicast_frames;
+	unsigned int rx_multicast_frames;
+	unsigned int rx_fragments;
+	unsigned int rx_unicast_octets;
+	unsigned int rx_multicast_octets;
+	unsigned int rx_fcs_errors;
+	unsigned int rx_discards_no_buffer;
+	unsigned int tx_discards_wrong_sa;
+	unsigned int rx_discards_undecryptable;
+	unsigned int rx_message_in_msg_fragments;
+	unsigned int rx_message_in_bad_msg_fragments;
+};
+
+struct libipw_device;
+
+#define SEC_KEY_1		(1<<0)
+#define SEC_KEY_2		(1<<1)
+#define SEC_KEY_3		(1<<2)
+#define SEC_KEY_4		(1<<3)
+#define SEC_ACTIVE_KEY		(1<<4)
+#define SEC_AUTH_MODE		(1<<5)
+#define SEC_UNICAST_GROUP	(1<<6)
+#define SEC_LEVEL		(1<<7)
+#define SEC_ENABLED		(1<<8)
+#define SEC_ENCRYPT		(1<<9)
+
+#define SEC_LEVEL_0		0	/* None */
+#define SEC_LEVEL_1		1	/* WEP 40 and 104 bit */
+#define SEC_LEVEL_2		2	/* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP	3	/* Level 1 + CKIP */
+#define SEC_LEVEL_3		4	/* Level 2 + CCMP */
+
+#define SEC_ALG_NONE		0
+#define SEC_ALG_WEP		1
+#define SEC_ALG_TKIP		2
+#define SEC_ALG_CCMP		3
+
+#define WEP_KEYS		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN		32
+#define SCM_TEMPORAL_KEY_LENGTH	16
+
+struct libipw_security {
+	u16 active_key:2, enabled:1, unicast_uses_group:1, encrypt:1;
+	u8 auth_mode;
+	u8 encode_alg[WEP_KEYS];
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+	u8 level;
+	u16 flags;
+} __attribute__ ((packed));
+
+/*
+
+ 802.11 data frame from AP
+
+      ,-------------------------------------------------------------------.
+Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
+      |------|------|---------|---------|---------|------|---------|------|
+Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
+      |      | tion | (BSSID) |         |         | ence |  data   |      |
+      `-------------------------------------------------------------------'
+
+Total: 28-2340 bytes
+
+*/
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct libipw_hdr_1addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct libipw_hdr_2addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct libipw_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 libipw_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u8 payload[0];
+} __attribute__ ((packed));
+
+struct libipw_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct libipw_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+/*
+ * These are the data types that can make up management packets
+ *
+	u16 auth_algorithm;
+	u16 auth_sequence;
+	u16 beacon_interval;
+	u16 capability;
+	u8 current_ap[ETH_ALEN];
+	u16 listen_interval;
+	struct {
+		u16 association_id:14, reserved:2;
+	} __attribute__ ((packed));
+	u32 time_stamp[2];
+	u16 reason;
+	u16 status;
+*/
+
+struct libipw_auth {
+	struct libipw_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/* challenge */
+	struct libipw_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct libipw_channel_switch {
+	u8 id;
+	u8 len;
+	u8 mode;
+	u8 channel;
+	u8 count;
+} __attribute__ ((packed));
+
+struct libipw_action {
+	struct libipw_hdr_3addr header;
+	u8 category;
+	u8 action;
+	union {
+		struct libipw_action_exchange {
+			u8 token;
+			struct libipw_info_element info_element[0];
+		} exchange;
+		struct libipw_channel_switch channel_switch;
+
+	} format;
+} __attribute__ ((packed));
+
+struct libipw_disassoc {
+	struct libipw_hdr_3addr header;
+	__le16 reason;
+} __attribute__ ((packed));
+
+/* Alias deauth for disassoc */
+#define libipw_deauth libipw_disassoc
+
+struct libipw_probe_request {
+	struct libipw_hdr_3addr header;
+	/* SSID, supported rates */
+	struct libipw_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct libipw_probe_response {
+	struct libipw_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 libipw_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define libipw_beacon libipw_probe_response
+
+struct libipw_assoc_request {
+	struct libipw_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	/* SSID, supported rates, RSN */
+	struct libipw_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct libipw_reassoc_request {
+	struct libipw_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	struct libipw_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct libipw_assoc_response {
+	struct libipw_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	/* supported rates */
+	struct libipw_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct libipw_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 rts_included;
+	u8 reserved;
+	u16 frag_size;
+	u16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+/* SWEEP TABLE ENTRIES NUMBER */
+#define MAX_SWEEP_TAB_ENTRIES		  42
+#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
+/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
+ * only use 8, and then use extended rates for the remaining supported
+ * rates.  Other APs, however, stick all of their supported rates on the
+ * main rates information element... */
+#define MAX_RATES_LENGTH                  ((u8)12)
+#define MAX_RATES_EX_LENGTH               ((u8)16)
+#define MAX_NETWORK_COUNT                  128
+
+#define CRC_LENGTH                 4U
+
+#define MAX_WPA_IE_LEN 64
+
+#define NETWORK_HAS_OFDM       (1<<1)
+#define NETWORK_HAS_CCK        (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+					 NETWORK_HAS_QOS_INFORMATION)
+
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+
+struct libipw_qos_information_element {
+	u8 elementID;
+	u8 length;
+	u8 qui[QOS_OUI_LEN];
+	u8 qui_type;
+	u8 qui_subtype;
+	u8 version;
+	u8 ac_info;
+} __attribute__ ((packed));
+
+struct libipw_qos_ac_parameter {
+	u8 aci_aifsn;
+	u8 ecw_min_max;
+	__le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct libipw_qos_parameter_info {
+	struct libipw_qos_information_element info_element;
+	u8 reserved;
+	struct libipw_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct libipw_qos_parameters {
+	__le16 cw_min[QOS_QUEUE_NUM];
+	__le16 cw_max[QOS_QUEUE_NUM];
+	u8 aifs[QOS_QUEUE_NUM];
+	u8 flag[QOS_QUEUE_NUM];
+	__le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct libipw_qos_data {
+	struct libipw_qos_parameters parameters;
+	int active;
+	int supported;
+	u8 param_count;
+	u8 old_param_count;
+};
+
+struct libipw_tim_parameters {
+	u8 tim_count;
+	u8 tim_period;
+} __attribute__ ((packed));
+
+/*******************************************************/
+
+enum {				/* libipw_basic_report.map */
+	LIBIPW_BASIC_MAP_BSS = (1 << 0),
+	LIBIPW_BASIC_MAP_OFDM = (1 << 1),
+	LIBIPW_BASIC_MAP_UNIDENTIFIED = (1 << 2),
+	LIBIPW_BASIC_MAP_RADAR = (1 << 3),
+	LIBIPW_BASIC_MAP_UNMEASURED = (1 << 4),
+	/* Bits 5-7 are reserved */
+
+};
+struct libipw_basic_report {
+	u8 channel;
+	__le64 start_time;
+	__le16 duration;
+	u8 map;
+} __attribute__ ((packed));
+
+enum {				/* libipw_measurement_request.mode */
+	/* Bit 0 is reserved */
+	LIBIPW_MEASUREMENT_ENABLE = (1 << 1),
+	LIBIPW_MEASUREMENT_REQUEST = (1 << 2),
+	LIBIPW_MEASUREMENT_REPORT = (1 << 3),
+	/* Bits 4-7 are reserved */
+};
+
+enum {
+	LIBIPW_REPORT_BASIC = 0,	/* required */
+	LIBIPW_REPORT_CCA = 1,	/* optional */
+	LIBIPW_REPORT_RPI = 2,	/* optional */
+	/* 3-255 reserved */
+};
+
+struct libipw_measurement_params {
+	u8 channel;
+	__le64 start_time;
+	__le16 duration;
+} __attribute__ ((packed));
+
+struct libipw_measurement_request {
+	struct libipw_info_element ie;
+	u8 token;
+	u8 mode;
+	u8 type;
+	struct libipw_measurement_params params[0];
+} __attribute__ ((packed));
+
+struct libipw_measurement_report {
+	struct libipw_info_element ie;
+	u8 token;
+	u8 mode;
+	u8 type;
+	union {
+		struct libipw_basic_report basic[0];
+	} u;
+} __attribute__ ((packed));
+
+struct libipw_tpc_report {
+	u8 transmit_power;
+	u8 link_margin;
+} __attribute__ ((packed));
+
+struct libipw_channel_map {
+	u8 channel;
+	u8 map;
+} __attribute__ ((packed));
+
+struct libipw_ibss_dfs {
+	struct libipw_info_element ie;
+	u8 owner[ETH_ALEN];
+	u8 recovery_interval;
+	struct libipw_channel_map channel_map[0];
+};
+
+struct libipw_csa {
+	u8 mode;
+	u8 channel;
+	u8 count;
+} __attribute__ ((packed));
+
+struct libipw_quiet {
+	u8 count;
+	u8 period;
+	u8 duration;
+	u8 offset;
+} __attribute__ ((packed));
+
+struct libipw_network {
+	/* These entries are used to identify a unique network */
+	u8 bssid[ETH_ALEN];
+	u8 channel;
+	/* Ensure null-terminated for any debug msgs */
+	u8 ssid[IW_ESSID_MAX_SIZE + 1];
+	u8 ssid_len;
+
+	struct libipw_qos_data qos_data;
+
+	/* These are network statistics */
+	struct libipw_rx_stats stats;
+	u16 capability;
+	u8 rates[MAX_RATES_LENGTH];
+	u8 rates_len;
+	u8 rates_ex[MAX_RATES_EX_LENGTH];
+	u8 rates_ex_len;
+	unsigned long last_scanned;
+	u8 mode;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8 erp_value;
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8 rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+	struct libipw_tim_parameters tim;
+
+	/* 802.11h info */
+
+	/* Power Constraint - mandatory if spctrm mgmt required */
+	u8 power_constraint;
+
+	/* TPC Report - mandatory if spctrm mgmt required */
+	struct libipw_tpc_report tpc_report;
+
+	/* IBSS DFS - mandatory if spctrm mgmt required and IBSS
+	 * NOTE: This is variable length and so must be allocated dynamically */
+	struct libipw_ibss_dfs *ibss_dfs;
+
+	/* Channel Switch Announcement - optional if spctrm mgmt required */
+	struct libipw_csa csa;
+
+	/* Quiet - optional if spctrm mgmt required */
+	struct libipw_quiet quiet;
+
+	struct list_head list;
+};
+
+enum libipw_state {
+	LIBIPW_UNINITIALIZED = 0,
+	LIBIPW_INITIALIZED,
+	LIBIPW_ASSOCIATING,
+	LIBIPW_ASSOCIATED,
+	LIBIPW_AUTHENTICATING,
+	LIBIPW_AUTHENTICATED,
+	LIBIPW_SHUTDOWN
+};
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+
+#define CFG_LIBIPW_RESERVE_FCS (1<<0)
+#define CFG_LIBIPW_COMPUTE_FCS (1<<1)
+#define CFG_LIBIPW_RTS (1<<2)
+
+#define LIBIPW_24GHZ_MIN_CHANNEL 1
+#define LIBIPW_24GHZ_MAX_CHANNEL 14
+#define LIBIPW_24GHZ_CHANNELS (LIBIPW_24GHZ_MAX_CHANNEL - \
+				  LIBIPW_24GHZ_MIN_CHANNEL + 1)
+
+#define LIBIPW_52GHZ_MIN_CHANNEL 34
+#define LIBIPW_52GHZ_MAX_CHANNEL 165
+#define LIBIPW_52GHZ_CHANNELS (LIBIPW_52GHZ_MAX_CHANNEL - \
+				  LIBIPW_52GHZ_MIN_CHANNEL + 1)
+
+enum {
+	LIBIPW_CH_PASSIVE_ONLY = (1 << 0),
+	LIBIPW_CH_80211H_RULES = (1 << 1),
+	LIBIPW_CH_B_ONLY = (1 << 2),
+	LIBIPW_CH_NO_IBSS = (1 << 3),
+	LIBIPW_CH_UNIFORM_SPREADING = (1 << 4),
+	LIBIPW_CH_RADAR_DETECT = (1 << 5),
+	LIBIPW_CH_INVALID = (1 << 6),
+};
+
+struct libipw_channel {
+	u32 freq;	/* in MHz */
+	u8 channel;
+	u8 flags;
+	u8 max_power;	/* in dBm */
+};
+
+struct libipw_geo {
+	u8 name[4];
+	u8 bg_channels;
+	u8 a_channels;
+	struct libipw_channel bg[LIBIPW_24GHZ_CHANNELS];
+	struct libipw_channel a[LIBIPW_52GHZ_CHANNELS];
+};
+
+struct libipw_device {
+	struct net_device *dev;
+	struct wireless_dev wdev;
+	struct libipw_security sec;
+
+	/* Bookkeeping structures */
+	struct libipw_stats ieee_stats;
+
+	struct libipw_geo geo;
+	struct ieee80211_supported_band bg_band;
+	struct ieee80211_supported_band a_band;
+
+	/* Probe / Beacon management */
+	struct list_head network_free_list;
+	struct list_head network_list;
+	struct libipw_network *networks;
+	int scans;
+	int scan_age;
+
+	int iw_mode;		/* operating mode (IW_MODE_*) */
+	struct iw_spy_data spy_data;	/* iwspy support */
+
+	spinlock_t lock;
+
+	int tx_headroom;	/* Set to size of any additional room needed at front
+				 * of allocated Tx SKBs */
+	u32 config;
+
+	/* WEP and other encryption related settings at the device level */
+	int open_wep;		/* Set to 1 to allow unencrypted frames */
+
+	int reset_on_keychange;	/* Set to 1 if the HW needs to be reset on
+				 * WEP key changes */
+
+	/* If the host performs {en,de}cryption, then set to 1 */
+	int host_encrypt;
+	int host_encrypt_msdu;
+	int host_decrypt;
+	/* host performs multicast decryption */
+	int host_mc_decrypt;
+
+	/* host should strip IV and ICV from protected frames */
+	/* meaningful only when hardware decryption is being used */
+	int host_strip_iv_icv;
+
+	int host_open_frag;
+	int host_build_iv;
+	int ieee802_1x;		/* is IEEE 802.1X used */
+
+	/* WPA data */
+	int wpa_enabled;
+	int drop_unencrypted;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+
+	struct lib80211_crypt_info crypt_info;
+
+	int bcrx_sta_key;	/* use individual keys to override default keys even
+				 * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	struct libipw_frag_entry frag_cache[LIBIPW_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx;
+	u16 fts;		/* Fragmentation Threshold */
+	u16 rts;		/* RTS threshold */
+
+	/* Association info */
+	u8 bssid[ETH_ALEN];
+
+	enum libipw_state state;
+
+	int mode;		/* A, B, G */
+	int modulation;		/* CCK, OFDM */
+	int freq_band;		/* 2.4Ghz, 5.2Ghz, Mixed */
+	int abg_true;		/* ABG flag              */
+
+	int perfect_rssi;
+	int worst_rssi;
+
+	u16 prev_seq_ctl;	/* used to drop duplicate frames */
+
+	/* Callback functions */
+	void (*set_security) (struct net_device * dev,
+			      struct libipw_security * sec);
+	netdev_tx_t (*hard_start_xmit) (struct libipw_txb * txb,
+					struct net_device * dev, int pri);
+	int (*reset_port) (struct net_device * dev);
+	int (*is_queue_full) (struct net_device * dev, int pri);
+
+	int (*handle_management) (struct net_device * dev,
+				  struct libipw_network * network, u16 type);
+	int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* Typical STA methods */
+	int (*handle_auth) (struct net_device * dev,
+			    struct libipw_auth * auth);
+	int (*handle_deauth) (struct net_device * dev,
+			      struct libipw_deauth * auth);
+	int (*handle_action) (struct net_device * dev,
+			      struct libipw_action * action,
+			      struct libipw_rx_stats * stats);
+	int (*handle_disassoc) (struct net_device * dev,
+				struct libipw_disassoc * assoc);
+	int (*handle_beacon) (struct net_device * dev,
+			      struct libipw_beacon * beacon,
+			      struct libipw_network * network);
+	int (*handle_probe_response) (struct net_device * dev,
+				      struct libipw_probe_response * resp,
+				      struct libipw_network * network);
+	int (*handle_probe_request) (struct net_device * dev,
+				     struct libipw_probe_request * req,
+				     struct libipw_rx_stats * stats);
+	int (*handle_assoc_response) (struct net_device * dev,
+				      struct libipw_assoc_response * resp,
+				      struct libipw_network * network);
+
+	/* Typical AP methods */
+	int (*handle_assoc_request) (struct net_device * dev);
+	int (*handle_reassoc_request) (struct net_device * dev,
+				       struct libipw_reassoc_request * req);
+
+	/* This must be the last item so that it points to the data
+	 * allocated beyond this structure by alloc_ieee80211 */
+	u8 priv[0];
+};
+
+#define IEEE_A            (1<<0)
+#define IEEE_B            (1<<1)
+#define IEEE_G            (1<<2)
+#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
+
+static inline void *libipw_priv(struct net_device *dev)
+{
+	return ((struct libipw_device *)netdev_priv(dev))->priv;
+}
+
+static inline int libipw_is_valid_mode(struct libipw_device *ieee,
+					  int mode)
+{
+	/*
+	 * It is possible for both access points and our device to support
+	 * combinations of modes, so as long as there is one valid combination
+	 * of ap/device supported modes, then return success
+	 *
+	 */
+	if ((mode & IEEE_A) &&
+	    (ieee->modulation & LIBIPW_OFDM_MODULATION) &&
+	    (ieee->freq_band & LIBIPW_52GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_G) &&
+	    (ieee->modulation & LIBIPW_OFDM_MODULATION) &&
+	    (ieee->freq_band & LIBIPW_24GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_B) &&
+	    (ieee->modulation & LIBIPW_CCK_MODULATION) &&
+	    (ieee->freq_band & LIBIPW_24GHZ_BAND))
+		return 1;
+
+	return 0;
+}
+
+static inline int libipw_get_hdrlen(u16 fc)
+{
+	int hdrlen = LIBIPW_3ADDR_LEN;
+	u16 stype = WLAN_FC_GET_STYPE(fc);
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = LIBIPW_4ADDR_LEN;
+		if (stype & IEEE80211_STYPE_QOS_DATA)
+			hdrlen += 2;
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (WLAN_FC_GET_STYPE(fc)) {
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = LIBIPW_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = LIBIPW_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *libipw_get_payload(struct ieee80211_hdr *hdr)
+{
+	switch (libipw_get_hdrlen(le16_to_cpu(hdr->frame_control))) {
+	case LIBIPW_1ADDR_LEN:
+		return ((struct libipw_hdr_1addr *)hdr)->payload;
+	case LIBIPW_2ADDR_LEN:
+		return ((struct libipw_hdr_2addr *)hdr)->payload;
+	case LIBIPW_3ADDR_LEN:
+		return ((struct libipw_hdr_3addr *)hdr)->payload;
+	case LIBIPW_4ADDR_LEN:
+		return ((struct libipw_hdr_4addr *)hdr)->payload;
+	}
+	return NULL;
+}
+
+static inline int libipw_is_ofdm_rate(u8 rate)
+{
+	switch (rate & ~LIBIPW_BASIC_RATE_MASK) {
+	case LIBIPW_OFDM_RATE_6MB:
+	case LIBIPW_OFDM_RATE_9MB:
+	case LIBIPW_OFDM_RATE_12MB:
+	case LIBIPW_OFDM_RATE_18MB:
+	case LIBIPW_OFDM_RATE_24MB:
+	case LIBIPW_OFDM_RATE_36MB:
+	case LIBIPW_OFDM_RATE_48MB:
+	case LIBIPW_OFDM_RATE_54MB:
+		return 1;
+	}
+	return 0;
+}
+
+static inline int libipw_is_cck_rate(u8 rate)
+{
+	switch (rate & ~LIBIPW_BASIC_RATE_MASK) {
+	case LIBIPW_CCK_RATE_1MB:
+	case LIBIPW_CCK_RATE_2MB:
+	case LIBIPW_CCK_RATE_5MB:
+	case LIBIPW_CCK_RATE_11MB:
+		return 1;
+	}
+	return 0;
+}
+
+/* ieee80211.c */
+extern void free_ieee80211(struct net_device *dev, int monitor);
+extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
+extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
+
+extern void libipw_networks_age(struct libipw_device *ieee,
+				   unsigned long age_secs);
+
+extern int libipw_set_encryption(struct libipw_device *ieee);
+
+/* libipw_tx.c */
+extern netdev_tx_t libipw_xmit(struct sk_buff *skb,
+			       struct net_device *dev);
+extern void libipw_txb_free(struct libipw_txb *);
+
+/* libipw_rx.c */
+extern void libipw_rx_any(struct libipw_device *ieee,
+		     struct sk_buff *skb, struct libipw_rx_stats *stats);
+extern int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
+			struct libipw_rx_stats *rx_stats);
+/* make sure to set stats->len */
+extern void libipw_rx_mgt(struct libipw_device *ieee,
+			     struct libipw_hdr_4addr *header,
+			     struct libipw_rx_stats *stats);
+extern void libipw_network_reset(struct libipw_network *network);
+
+/* libipw_geo.c */
+extern const struct libipw_geo *libipw_get_geo(struct libipw_device
+						     *ieee);
+extern int libipw_set_geo(struct libipw_device *ieee,
+			     const struct libipw_geo *geo);
+
+extern int libipw_is_valid_channel(struct libipw_device *ieee,
+				      u8 channel);
+extern int libipw_channel_to_index(struct libipw_device *ieee,
+				      u8 channel);
+extern u8 libipw_freq_to_channel(struct libipw_device *ieee, u32 freq);
+extern u8 libipw_get_channel_flags(struct libipw_device *ieee,
+				      u8 channel);
+extern const struct libipw_channel *libipw_get_channel(struct
+							     libipw_device
+							     *ieee, u8 channel);
+extern u32 libipw_channel_to_freq(struct libipw_device * ieee,
+				      u8 channel);
+
+/* libipw_wx.c */
+extern int libipw_wx_get_scan(struct libipw_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *key);
+extern int libipw_wx_set_encode(struct libipw_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int libipw_wx_get_encode(struct libipw_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int libipw_wx_set_encodeext(struct libipw_device *ieee,
+				      struct iw_request_info *info,
+				      union iwreq_data *wrqu, char *extra);
+extern int libipw_wx_get_encodeext(struct libipw_device *ieee,
+				      struct iw_request_info *info,
+				      union iwreq_data *wrqu, char *extra);
+
+static inline void libipw_increment_scans(struct libipw_device *ieee)
+{
+	ieee->scans++;
+}
+
+static inline int libipw_get_scans(struct libipw_device *ieee)
+{
+	return ieee->scans;
+}
+
+#endif				/* LIBIPW_H */
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c
index 9dfbb87..65e8c17 100644
--- a/drivers/net/wireless/ipw2x00/libipw_geo.c
+++ b/drivers/net/wireless/ipw2x00/libipw_geo.c
@@ -19,7 +19,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 ******************************************************************************/
@@ -41,9 +41,9 @@
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
 
-#include "ieee80211.h"
+#include "libipw.h"
 
-int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
+int libipw_is_valid_channel(struct libipw_device *ieee, u8 channel)
 {
 	int i;
 
@@ -52,27 +52,27 @@ int ieee80211_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
 	if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
 		return 0;
 
-	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+	if (ieee->freq_band & LIBIPW_24GHZ_BAND)
 		for (i = 0; i < ieee->geo.bg_channels; i++)
 			/* NOTE: If G mode is currently supported but
 			 * this is a B only channel, we don't see it
 			 * as valid. */
 			if ((ieee->geo.bg[i].channel == channel) &&
-			    !(ieee->geo.bg[i].flags & IEEE80211_CH_INVALID) &&
+			    !(ieee->geo.bg[i].flags & LIBIPW_CH_INVALID) &&
 			    (!(ieee->mode & IEEE_G) ||
-			     !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
-				return IEEE80211_24GHZ_BAND;
+			     !(ieee->geo.bg[i].flags & LIBIPW_CH_B_ONLY)))
+				return LIBIPW_24GHZ_BAND;
 
-	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+	if (ieee->freq_band & LIBIPW_52GHZ_BAND)
 		for (i = 0; i < ieee->geo.a_channels; i++)
 			if ((ieee->geo.a[i].channel == channel) &&
-			    !(ieee->geo.a[i].flags & IEEE80211_CH_INVALID))
-				return IEEE80211_52GHZ_BAND;
+			    !(ieee->geo.a[i].flags & LIBIPW_CH_INVALID))
+				return LIBIPW_52GHZ_BAND;
 
 	return 0;
 }
 
-int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
+int libipw_channel_to_index(struct libipw_device *ieee, u8 channel)
 {
 	int i;
 
@@ -81,12 +81,12 @@ int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
 	if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
 		return -1;
 
-	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+	if (ieee->freq_band & LIBIPW_24GHZ_BAND)
 		for (i = 0; i < ieee->geo.bg_channels; i++)
 			if (ieee->geo.bg[i].channel == channel)
 				return i;
 
-	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+	if (ieee->freq_band & LIBIPW_52GHZ_BAND)
 		for (i = 0; i < ieee->geo.a_channels; i++)
 			if (ieee->geo.a[i].channel == channel)
 				return i;
@@ -94,22 +94,22 @@ int ieee80211_channel_to_index(struct ieee80211_device *ieee, u8 channel)
 	return -1;
 }
 
-u32 ieee80211_channel_to_freq(struct ieee80211_device * ieee, u8 channel)
+u32 libipw_channel_to_freq(struct libipw_device * ieee, u8 channel)
 {
-	const struct ieee80211_channel * ch;
+	const struct libipw_channel * ch;
 
 	/* Driver needs to initialize the geography map before using
 	 * these helper functions */
 	if (ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0)
 		return 0;
 
-	ch = ieee80211_get_channel(ieee, channel);
+	ch = libipw_get_channel(ieee, channel);
 	if (!ch->channel)
 		return 0;
 	return ch->freq;
 }
 
-u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
+u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq)
 {
 	int i;
 
@@ -120,12 +120,12 @@ u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
 
 	freq /= 100000;
 
-	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+	if (ieee->freq_band & LIBIPW_24GHZ_BAND)
 		for (i = 0; i < ieee->geo.bg_channels; i++)
 			if (ieee->geo.bg[i].freq == freq)
 				return ieee->geo.bg[i].channel;
 
-	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+	if (ieee->freq_band & LIBIPW_52GHZ_BAND)
 		for (i = 0; i < ieee->geo.a_channels; i++)
 			if (ieee->geo.a[i].freq == freq)
 				return ieee->geo.a[i].channel;
@@ -133,63 +133,63 @@ u8 ieee80211_freq_to_channel(struct ieee80211_device * ieee, u32 freq)
 	return 0;
 }
 
-int ieee80211_set_geo(struct ieee80211_device *ieee,
-		      const struct ieee80211_geo *geo)
+int libipw_set_geo(struct libipw_device *ieee,
+		      const struct libipw_geo *geo)
 {
 	memcpy(ieee->geo.name, geo->name, 3);
 	ieee->geo.name[3] = '\0';
 	ieee->geo.bg_channels = geo->bg_channels;
 	ieee->geo.a_channels = geo->a_channels;
 	memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
-	       sizeof(struct ieee80211_channel));
+	       sizeof(struct libipw_channel));
 	memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
-	       sizeof(struct ieee80211_channel));
+	       sizeof(struct libipw_channel));
 	return 0;
 }
 
-const struct ieee80211_geo *ieee80211_get_geo(struct ieee80211_device *ieee)
+const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee)
 {
 	return &ieee->geo;
 }
 
-u8 ieee80211_get_channel_flags(struct ieee80211_device * ieee, u8 channel)
+u8 libipw_get_channel_flags(struct libipw_device * ieee, u8 channel)
 {
-	int index = ieee80211_channel_to_index(ieee, channel);
+	int index = libipw_channel_to_index(ieee, channel);
 
 	if (index == -1)
-		return IEEE80211_CH_INVALID;
+		return LIBIPW_CH_INVALID;
 
-	if (channel <= IEEE80211_24GHZ_CHANNELS)
+	if (channel <= LIBIPW_24GHZ_CHANNELS)
 		return ieee->geo.bg[index].flags;
 
 	return ieee->geo.a[index].flags;
 }
 
-static const struct ieee80211_channel bad_channel = {
+static const struct libipw_channel bad_channel = {
 	.channel = 0,
-	.flags = IEEE80211_CH_INVALID,
+	.flags = LIBIPW_CH_INVALID,
 	.max_power = 0,
 };
 
-const struct ieee80211_channel *ieee80211_get_channel(struct ieee80211_device
+const struct libipw_channel *libipw_get_channel(struct libipw_device
 						      *ieee, u8 channel)
 {
-	int index = ieee80211_channel_to_index(ieee, channel);
+	int index = libipw_channel_to_index(ieee, channel);
 
 	if (index == -1)
 		return &bad_channel;
 
-	if (channel <= IEEE80211_24GHZ_CHANNELS)
+	if (channel <= LIBIPW_24GHZ_CHANNELS)
 		return &ieee->geo.bg[index];
 
 	return &ieee->geo.a[index];
 }
 
-EXPORT_SYMBOL(ieee80211_get_channel);
-EXPORT_SYMBOL(ieee80211_get_channel_flags);
-EXPORT_SYMBOL(ieee80211_is_valid_channel);
-EXPORT_SYMBOL(ieee80211_freq_to_channel);
-EXPORT_SYMBOL(ieee80211_channel_to_freq);
-EXPORT_SYMBOL(ieee80211_channel_to_index);
-EXPORT_SYMBOL(ieee80211_set_geo);
-EXPORT_SYMBOL(ieee80211_get_geo);
+EXPORT_SYMBOL(libipw_get_channel);
+EXPORT_SYMBOL(libipw_get_channel_flags);
+EXPORT_SYMBOL(libipw_is_valid_channel);
+EXPORT_SYMBOL(libipw_freq_to_channel);
+EXPORT_SYMBOL(libipw_channel_to_freq);
+EXPORT_SYMBOL(libipw_channel_to_index);
+EXPORT_SYMBOL(libipw_set_geo);
+EXPORT_SYMBOL(libipw_get_geo);
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 8ce6e96..a0e9f6a 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -25,7 +25,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 *******************************************************************************/
@@ -50,11 +50,11 @@
 #include <net/net_namespace.h>
 #include <net/arp.h>
 
-#include "ieee80211.h"
+#include "libipw.h"
 
 #define DRV_DESCRIPTION "802.11 data/management/control stack"
 #define DRV_NAME        "ieee80211"
-#define DRV_VERSION	IEEE80211_VERSION
+#define DRV_VERSION	LIBIPW_VERSION
 #define DRV_COPYRIGHT   "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
 
 MODULE_VERSION(DRV_VERSION);
@@ -62,13 +62,16 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
-static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
+struct cfg80211_ops libipw_config_ops = { };
+void *libipw_wiphy_privid = &libipw_wiphy_privid;
+
+static int libipw_networks_allocate(struct libipw_device *ieee)
 {
 	if (ieee->networks)
 		return 0;
 
 	ieee->networks =
-	    kzalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
+	    kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
 		    GFP_KERNEL);
 	if (!ieee->networks) {
 		printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
@@ -79,7 +82,7 @@ static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
 	return 0;
 }
 
-void ieee80211_network_reset(struct ieee80211_network *network)
+void libipw_network_reset(struct libipw_network *network)
 {
 	if (!network)
 		return;
@@ -90,7 +93,7 @@ void ieee80211_network_reset(struct ieee80211_network *network)
 	}
 }
 
-static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
+static inline void libipw_networks_free(struct libipw_device *ieee)
 {
 	int i;
 
@@ -105,10 +108,10 @@ static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
 	ieee->networks = NULL;
 }
 
-void ieee80211_networks_age(struct ieee80211_device *ieee,
+void libipw_networks_age(struct libipw_device *ieee,
                             unsigned long age_secs)
 {
-	struct ieee80211_network *network = NULL;
+	struct libipw_network *network = NULL;
 	unsigned long flags;
 	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
 
@@ -118,9 +121,9 @@ void ieee80211_networks_age(struct ieee80211_device *ieee,
 	}
 	spin_unlock_irqrestore(&ieee->lock, flags);
 }
-EXPORT_SYMBOL(ieee80211_networks_age);
+EXPORT_SYMBOL(libipw_networks_age);
 
-static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
+static void libipw_networks_initialize(struct libipw_device *ieee)
 {
 	int i;
 
@@ -131,38 +134,59 @@ static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
 			      &ieee->network_free_list);
 }
 
-int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
+int libipw_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
+	if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
 		return -EINVAL;
 	dev->mtu = new_mtu;
 	return 0;
 }
-EXPORT_SYMBOL(ieee80211_change_mtu);
+EXPORT_SYMBOL(libipw_change_mtu);
 
-struct net_device *alloc_ieee80211(int sizeof_priv)
+struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
 {
-	struct ieee80211_device *ieee;
+	struct libipw_device *ieee;
 	struct net_device *dev;
 	int err;
 
-	IEEE80211_DEBUG_INFO("Initializing...\n");
+	LIBIPW_DEBUG_INFO("Initializing...\n");
 
-	dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
+	dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
 	if (!dev) {
-		IEEE80211_ERROR("Unable to allocate network device.\n");
+		LIBIPW_ERROR("Unable to allocate network device.\n");
 		goto failed;
 	}
 	ieee = netdev_priv(dev);
 
 	ieee->dev = dev;
 
-	err = ieee80211_networks_allocate(ieee);
+	if (!monitor) {
+		ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
+		if (!ieee->wdev.wiphy) {
+			LIBIPW_ERROR("Unable to allocate wiphy.\n");
+			goto failed_free_netdev;
+		}
+
+		ieee->dev->ieee80211_ptr = &ieee->wdev;
+		ieee->wdev.iftype = NL80211_IFTYPE_STATION;
+
+		/* Fill-out wiphy structure bits we know...  Not enough info
+		   here to call set_wiphy_dev or set MAC address or channel info
+		   -- have to do that in ->ndo_init... */
+		ieee->wdev.wiphy->privid = libipw_wiphy_privid;
+
+		ieee->wdev.wiphy->max_scan_ssids = 1;
+		ieee->wdev.wiphy->max_scan_ie_len = 0;
+		ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+						| BIT(NL80211_IFTYPE_ADHOC);
+	}
+
+	err = libipw_networks_allocate(ieee);
 	if (err) {
-		IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
-		goto failed_free_netdev;
+		LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
+		goto failed_free_wiphy;
 	}
-	ieee80211_networks_initialize(ieee);
+	libipw_networks_initialize(ieee);
 
 	/* Default fragmentation threshold is maximum payload size */
 	ieee->fts = DEFAULT_FTS;
@@ -193,33 +217,45 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
 	return dev;
 
+failed_free_wiphy:
+	if (!monitor)
+		wiphy_free(ieee->wdev.wiphy);
 failed_free_netdev:
 	free_netdev(dev);
 failed:
 	return NULL;
 }
 
-void free_ieee80211(struct net_device *dev)
+void free_ieee80211(struct net_device *dev, int monitor)
 {
-	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct libipw_device *ieee = netdev_priv(dev);
 
 	lib80211_crypt_info_free(&ieee->crypt_info);
 
-	ieee80211_networks_free(ieee);
+	libipw_networks_free(ieee);
+
+	/* free cfg80211 resources */
+	if (!monitor) {
+		wiphy_unregister(ieee->wdev.wiphy);
+		kfree(ieee->a_band.channels);
+		kfree(ieee->bg_band.channels);
+		wiphy_free(ieee->wdev.wiphy);
+	}
+
 	free_netdev(dev);
 }
 
 #ifdef CONFIG_LIBIPW_DEBUG
 
 static int debug = 0;
-u32 ieee80211_debug_level = 0;
-EXPORT_SYMBOL_GPL(ieee80211_debug_level);
-static struct proc_dir_entry *ieee80211_proc = NULL;
+u32 libipw_debug_level = 0;
+EXPORT_SYMBOL_GPL(libipw_debug_level);
+static struct proc_dir_entry *libipw_proc = NULL;
 
 static int show_debug_level(char *page, char **start, off_t offset,
 			    int count, int *eof, void *data)
 {
-	return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
+	return snprintf(page, count, "0x%08X\n", libipw_debug_level);
 }
 
 static int store_debug_level(struct file *file, const char __user * buffer,
@@ -236,29 +272,29 @@ static int store_debug_level(struct file *file, const char __user * buffer,
 		printk(KERN_INFO DRV_NAME
 		       ": %s is not in hex or decimal form.\n", buf);
 	else
-		ieee80211_debug_level = val;
+		libipw_debug_level = val;
 
 	return strnlen(buf, len);
 }
 #endif				/* CONFIG_LIBIPW_DEBUG */
 
-static int __init ieee80211_init(void)
+static int __init libipw_init(void)
 {
 #ifdef CONFIG_LIBIPW_DEBUG
 	struct proc_dir_entry *e;
 
-	ieee80211_debug_level = debug;
-	ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
-	if (ieee80211_proc == NULL) {
-		IEEE80211_ERROR("Unable to create " DRV_NAME
+	libipw_debug_level = debug;
+	libipw_proc = proc_mkdir(DRV_NAME, init_net.proc_net);
+	if (libipw_proc == NULL) {
+		LIBIPW_ERROR("Unable to create " DRV_NAME
 				" proc directory\n");
 		return -EIO;
 	}
 	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
-			      ieee80211_proc);
+			      libipw_proc);
 	if (!e) {
 		remove_proc_entry(DRV_NAME, init_net.proc_net);
-		ieee80211_proc = NULL;
+		libipw_proc = NULL;
 		return -EIO;
 	}
 	e->read_proc = show_debug_level;
@@ -272,13 +308,13 @@ static int __init ieee80211_init(void)
 	return 0;
 }
 
-static void __exit ieee80211_exit(void)
+static void __exit libipw_exit(void)
 {
 #ifdef CONFIG_LIBIPW_DEBUG
-	if (ieee80211_proc) {
-		remove_proc_entry("debug_level", ieee80211_proc);
+	if (libipw_proc) {
+		remove_proc_entry("debug_level", libipw_proc);
 		remove_proc_entry(DRV_NAME, init_net.proc_net);
-		ieee80211_proc = NULL;
+		libipw_proc = NULL;
 	}
 #endif				/* CONFIG_LIBIPW_DEBUG */
 }
@@ -289,8 +325,8 @@ module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
 #endif				/* CONFIG_LIBIPW_DEBUG */
 
-module_exit(ieee80211_exit);
-module_init(ieee80211_init);
+module_exit(libipw_exit);
+module_init(libipw_init);
 
 EXPORT_SYMBOL(alloc_ieee80211);
 EXPORT_SYMBOL(free_ieee80211);
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index dae4b8e..282b1f7 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -34,18 +34,18 @@
 
 #include <net/lib80211.h>
 
-#include "ieee80211.h"
+#include "libipw.h"
 
-static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
+static void libipw_monitor_rx(struct libipw_device *ieee,
 					struct sk_buff *skb,
-					struct ieee80211_rx_stats *rx_stats)
+					struct libipw_rx_stats *rx_stats)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	u16 fc = le16_to_cpu(hdr->frame_control);
 
 	skb->dev = ieee->dev;
 	skb_reset_mac_header(skb);
-	skb_pull(skb, ieee80211_get_hdrlen(fc));
+	skb_pull(skb, libipw_get_hdrlen(fc));
 	skb->pkt_type = PACKET_OTHERHOST;
 	skb->protocol = htons(ETH_P_80211_RAW);
 	memset(skb->cb, 0, sizeof(skb->cb));
@@ -53,22 +53,22 @@ static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
 }
 
 /* Called only as a tasklet (software IRQ) */
-static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
-							      ieee80211_device
+static struct libipw_frag_entry *libipw_frag_cache_find(struct
+							      libipw_device
 							      *ieee,
 							      unsigned int seq,
 							      unsigned int frag,
 							      u8 * src,
 							      u8 * dst)
 {
-	struct ieee80211_frag_entry *entry;
+	struct libipw_frag_entry *entry;
 	int i;
 
-	for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
+	for (i = 0; i < LIBIPW_FRAG_CACHE_LEN; i++) {
 		entry = &ieee->frag_cache[i];
 		if (entry->skb != NULL &&
 		    time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
-			IEEE80211_DEBUG_FRAG("expiring fragment cache entry "
+			LIBIPW_DEBUG_FRAG("expiring fragment cache entry "
 					     "seq=%u last_frag=%u\n",
 					     entry->seq, entry->last_frag);
 			dev_kfree_skb_any(entry->skb);
@@ -86,13 +86,13 @@ static struct ieee80211_frag_entry *ieee80211_frag_cache_find(struct
 }
 
 /* Called only as a tasklet (software IRQ) */
-static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
-						struct ieee80211_hdr_4addr *hdr)
+static struct sk_buff *libipw_frag_cache_get(struct libipw_device *ieee,
+						struct libipw_hdr_4addr *hdr)
 {
 	struct sk_buff *skb = NULL;
 	u16 sc;
 	unsigned int frag, seq;
-	struct ieee80211_frag_entry *entry;
+	struct libipw_frag_entry *entry;
 
 	sc = le16_to_cpu(hdr->seq_ctl);
 	frag = WLAN_GET_SEQ_FRAG(sc);
@@ -101,7 +101,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 	if (frag == 0) {
 		/* Reserve enough space to fit maximum frame length */
 		skb = dev_alloc_skb(ieee->dev->mtu +
-				    sizeof(struct ieee80211_hdr_4addr) +
+				    sizeof(struct libipw_hdr_4addr) +
 				    8 /* LLC */  +
 				    2 /* alignment */  +
 				    8 /* WEP */  + ETH_ALEN /* WDS */ );
@@ -110,7 +110,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 
 		entry = &ieee->frag_cache[ieee->frag_next_idx];
 		ieee->frag_next_idx++;
-		if (ieee->frag_next_idx >= IEEE80211_FRAG_CACHE_LEN)
+		if (ieee->frag_next_idx >= LIBIPW_FRAG_CACHE_LEN)
 			ieee->frag_next_idx = 0;
 
 		if (entry->skb != NULL)
@@ -125,7 +125,7 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 	} else {
 		/* received a fragment of a frame for which the head fragment
 		 * should have already been received */
-		entry = ieee80211_frag_cache_find(ieee, seq, frag, hdr->addr2,
+		entry = libipw_frag_cache_find(ieee, seq, frag, hdr->addr2,
 						  hdr->addr1);
 		if (entry != NULL) {
 			entry->last_frag = frag;
@@ -137,21 +137,21 @@ static struct sk_buff *ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 }
 
 /* Called only as a tasklet (software IRQ) */
-static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
-					   struct ieee80211_hdr_4addr *hdr)
+static int libipw_frag_cache_invalidate(struct libipw_device *ieee,
+					   struct libipw_hdr_4addr *hdr)
 {
 	u16 sc;
 	unsigned int seq;
-	struct ieee80211_frag_entry *entry;
+	struct libipw_frag_entry *entry;
 
 	sc = le16_to_cpu(hdr->seq_ctl);
 	seq = WLAN_GET_SEQ_SEQ(sc);
 
-	entry = ieee80211_frag_cache_find(ieee, seq, -1, hdr->addr2,
+	entry = libipw_frag_cache_find(ieee, seq, -1, hdr->addr2,
 					  hdr->addr1);
 
 	if (entry == NULL) {
-		IEEE80211_DEBUG_FRAG("could not invalidate fragment cache "
+		LIBIPW_DEBUG_FRAG("could not invalidate fragment cache "
 				     "entry (seq=%u)\n", seq);
 		return -1;
 	}
@@ -161,14 +161,14 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
 }
 
 #ifdef NOT_YET
-/* ieee80211_rx_frame_mgtmt
+/* libipw_rx_frame_mgtmt
  *
  * Responsible for handling management control frames
  *
- * Called by ieee80211_rx */
+ * Called by libipw_rx */
 static int
-ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
-			struct ieee80211_rx_stats *rx_stats, u16 type,
+libipw_rx_frame_mgmt(struct libipw_device *ieee, struct sk_buff *skb,
+			struct libipw_rx_stats *rx_stats, u16 type,
 			u16 stype)
 {
 	if (ieee->iw_mode == IW_MODE_MASTER) {
@@ -176,7 +176,7 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 		       ieee->dev->name);
 		return 0;
 /*
-  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
+  hostap_update_sta_ps(ieee, (struct hostap_libipw_hdr_4addr *)
   skb->data);*/
 	}
 
@@ -219,26 +219,27 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+static unsigned char libipw_rfc1042_header[] =
+    { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
 
 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] =
+static unsigned char libipw_bridge_tunnel_header[] =
     { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
 /* No encapsulation header if EtherType < 0x600 (=length) */
 
-/* Called by ieee80211_rx_frame_decrypt */
-static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
+/* Called by libipw_rx_frame_decrypt */
+static int libipw_is_eapol_frame(struct libipw_device *ieee,
 				    struct sk_buff *skb)
 {
 	struct net_device *dev = ieee->dev;
 	u16 fc, ethertype;
-	struct ieee80211_hdr_3addr *hdr;
+	struct libipw_hdr_3addr *hdr;
 	u8 *pos;
 
 	if (skb->len < 24)
 		return 0;
 
-	hdr = (struct ieee80211_hdr_3addr *)skb->data;
+	hdr = (struct libipw_hdr_3addr *)skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	/* check that the frame is unicast frame to us */
@@ -266,28 +267,28 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
 	return 0;
 }
 
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
+/* Called only as a tasklet (software IRQ), by libipw_rx */
 static int
-ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
+libipw_rx_frame_decrypt(struct libipw_device *ieee, struct sk_buff *skb,
 			   struct lib80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr_3addr *hdr;
+	struct libipw_hdr_3addr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr_3addr *)skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdr = (struct libipw_hdr_3addr *)skb->data;
+	hdrlen = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
 	atomic_inc(&crypt->refcnt);
 	res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
 	atomic_dec(&crypt->refcnt);
 	if (res < 0) {
-		IEEE80211_DEBUG_DROP("decryption failed (SA=%pM) res=%d\n",
+		LIBIPW_DEBUG_DROP("decryption failed (SA=%pM) res=%d\n",
 				     hdr->addr2, res);
 		if (res == -2)
-			IEEE80211_DEBUG_DROP("Decryption failed ICV "
+			LIBIPW_DEBUG_DROP("Decryption failed ICV "
 					     "mismatch (key %d)\n",
 					     skb->data[hdrlen + 3] >> 6);
 		ieee->ieee_stats.rx_discards_undecryptable++;
@@ -297,20 +298,20 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
 	return res;
 }
 
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
+/* Called only as a tasklet (software IRQ), by libipw_rx */
 static int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
+libipw_rx_frame_decrypt_msdu(struct libipw_device *ieee,
 				struct sk_buff *skb, int keyidx,
 				struct lib80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr_3addr *hdr;
+	struct libipw_hdr_3addr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr_3addr *)skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdr = (struct libipw_hdr_3addr *)skb->data;
+	hdrlen = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
 	atomic_inc(&crypt->refcnt);
 	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
@@ -328,11 +329,11 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
 /* All received frames are sent to this function. @skb contains the frame in
  * IEEE 802.11 format, i.e., in the format it was sent over air.
  * This function is called only as a tasklet (software IRQ). */
-int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-		 struct ieee80211_rx_stats *rx_stats)
+int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb,
+		 struct libipw_rx_stats *rx_stats)
 {
 	struct net_device *dev = ieee->dev;
-	struct ieee80211_hdr_4addr *hdr;
+	struct libipw_hdr_4addr *hdr;
 	size_t hdrlen;
 	u16 fc, type, stype, sc;
 	unsigned int frag;
@@ -352,7 +353,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	int keyidx = 0;
 	int can_be_decrypted = 0;
 
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	hdr = (struct libipw_hdr_4addr *)skb->data;
 	if (skb->len < 10) {
 		printk(KERN_INFO "%s: SKB length < 10\n", dev->name);
 		goto rx_dropped;
@@ -363,7 +364,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	stype = WLAN_FC_GET_STYPE(fc);
 	sc = le16_to_cpu(hdr->seq_ctl);
 	frag = WLAN_GET_SEQ_FRAG(sc);
-	hdrlen = ieee80211_get_hdrlen(fc);
+	hdrlen = libipw_get_hdrlen(fc);
 
 	if (skb->len < hdrlen) {
 		printk(KERN_INFO "%s: invalid SKB length %d\n",
@@ -380,19 +381,19 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		struct iw_quality wstats;
 
 		wstats.updated = 0;
-		if (rx_stats->mask & IEEE80211_STATMASK_RSSI) {
+		if (rx_stats->mask & LIBIPW_STATMASK_RSSI) {
 			wstats.level = rx_stats->signal;
 			wstats.updated |= IW_QUAL_LEVEL_UPDATED;
 		} else
 			wstats.updated |= IW_QUAL_LEVEL_INVALID;
 
-		if (rx_stats->mask & IEEE80211_STATMASK_NOISE) {
+		if (rx_stats->mask & LIBIPW_STATMASK_NOISE) {
 			wstats.noise = rx_stats->noise;
 			wstats.updated |= IW_QUAL_NOISE_UPDATED;
 		} else
 			wstats.updated |= IW_QUAL_NOISE_INVALID;
 
-		if (rx_stats->mask & IEEE80211_STATMASK_SIGNAL) {
+		if (rx_stats->mask & LIBIPW_STATMASK_SIGNAL) {
 			wstats.qual = rx_stats->signal;
 			wstats.updated |= IW_QUAL_QUAL_UPDATED;
 		} else
@@ -411,7 +412,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	if (ieee->iw_mode == IW_MODE_MONITOR) {
 		dev->stats.rx_packets++;
 		dev->stats.rx_bytes += skb->len;
-		ieee80211_monitor_rx(ieee, skb, rx_stats);
+		libipw_monitor_rx(ieee, skb, rx_stats);
 		return 1;
 	}
 
@@ -457,7 +458,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 			 * frames from other than current BSS, so just drop the
 			 * frames silently instead of filling system log with
 			 * these reports. */
-			IEEE80211_DEBUG_DROP("Decryption failed (not set)"
+			LIBIPW_DEBUG_DROP("Decryption failed (not set)"
 					     " (SA=%pM)\n", hdr->addr2);
 			ieee->ieee_stats.rx_discards_undecryptable++;
 			goto rx_dropped;
@@ -475,7 +476,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 			goto rx_dropped;
 		}
 
-		if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
+		if (libipw_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
 			goto rx_dropped;
 		else
 			goto rx_exit;
@@ -488,7 +489,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		ieee->prev_seq_ctl = sc;
 
 	/* Data frame - extract src/dst addresses */
-	if (skb->len < IEEE80211_3ADDR_LEN)
+	if (skb->len < LIBIPW_3ADDR_LEN)
 		goto rx_dropped;
 
 	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
@@ -501,7 +502,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		memcpy(src, hdr->addr2, ETH_ALEN);
 		break;
 	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
-		if (skb->len < IEEE80211_4ADDR_LEN)
+		if (skb->len < LIBIPW_4ADDR_LEN)
 			goto rx_dropped;
 		memcpy(dst, hdr->addr3, ETH_ALEN);
 		memcpy(src, hdr->addr4, ETH_ALEN);
@@ -560,7 +561,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	    stype != IEEE80211_STYPE_DATA_CFPOLL &&
 	    stype != IEEE80211_STYPE_DATA_CFACKPOLL) {
 		if (stype != IEEE80211_STYPE_NULLFUNC)
-			IEEE80211_DEBUG_DROP("RX: dropped data frame "
+			LIBIPW_DEBUG_DROP("RX: dropped data frame "
 					     "with no data (type=0x%02x, "
 					     "subtype=0x%02x, len=%d)\n",
 					     type, stype, skb->len);
@@ -570,21 +571,21 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
 
 	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
-	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
+	    (keyidx = libipw_rx_frame_decrypt(ieee, skb, crypt)) < 0)
 		goto rx_dropped;
 
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	hdr = (struct libipw_hdr_4addr *)skb->data;
 
 	/* skb: hdr + (possibly fragmented) plaintext payload */
 	// PR: FIXME: hostap has additional conditions in the "if" below:
 	// ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
 	if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
 		int flen;
-		struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
-		IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
+		struct sk_buff *frag_skb = libipw_frag_cache_get(ieee, hdr);
+		LIBIPW_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
 
 		if (!frag_skb) {
-			IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
+			LIBIPW_DEBUG(LIBIPW_DL_RX | LIBIPW_DL_FRAG,
 					"Rx cannot get skb from fragment "
 					"cache (morefrag=%d seq=%u frag=%u)\n",
 					(fc & IEEE80211_FCTL_MOREFRAGS) != 0,
@@ -600,7 +601,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 			printk(KERN_WARNING "%s: host decrypted and "
 			       "reassembled frame did not fit skb\n",
 			       dev->name);
-			ieee80211_frag_cache_invalidate(ieee, hdr);
+			libipw_frag_cache_invalidate(ieee, hdr);
 			goto rx_dropped;
 		}
 
@@ -627,24 +628,24 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		/* this was the last fragment and the frame will be
 		 * delivered, so remove skb from fragment cache */
 		skb = frag_skb;
-		hdr = (struct ieee80211_hdr_4addr *)skb->data;
-		ieee80211_frag_cache_invalidate(ieee, hdr);
+		hdr = (struct libipw_hdr_4addr *)skb->data;
+		libipw_frag_cache_invalidate(ieee, hdr);
 	}
 
 	/* skb: hdr + (possible reassembled) full MSDU payload; possibly still
 	 * encrypted/authenticated */
 	if ((fc & IEEE80211_FCTL_PROTECTED) && can_be_decrypted &&
-	    ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
+	    libipw_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
 		goto rx_dropped;
 
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	hdr = (struct libipw_hdr_4addr *)skb->data;
 	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep) {
 		if (		/*ieee->ieee802_1x && */
-			   ieee80211_is_eapol_frame(ieee, skb)) {
+			   libipw_is_eapol_frame(ieee, skb)) {
 			/* pass unencrypted EAPOL frames even if encryption is
 			 * configured */
 		} else {
-			IEEE80211_DEBUG_DROP("encryption configured, but RX "
+			LIBIPW_DEBUG_DROP("encryption configured, but RX "
 					     "frame not encrypted (SA=%pM)\n",
 					     hdr->addr2);
 			goto rx_dropped;
@@ -652,8 +653,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	}
 
 	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
-	    !ieee80211_is_eapol_frame(ieee, skb)) {
-		IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
+	    !libipw_is_eapol_frame(ieee, skb)) {
+		LIBIPW_DEBUG_DROP("dropped unencrypted RX data "
 				     "frame from %pM (drop_unencrypted=1)\n",
 				     hdr->addr2);
 		goto rx_dropped;
@@ -736,9 +737,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 	/* convert hdr + possible LLC headers into Ethernet header */
 	if (skb->len - hdrlen >= 8 &&
-	    ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
+	    ((memcmp(payload, libipw_rfc1042_header, SNAP_SIZE) == 0 &&
 	      ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-	     memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
+	     memcmp(payload, libipw_bridge_tunnel_header, SNAP_SIZE) == 0)) {
 		/* remove RFC1042 or Bridge-Tunnel encapsulation and
 		 * replace EtherType */
 		skb_pull(skb, hdrlen + SNAP_SIZE);
@@ -807,7 +808,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 			/* netif_rx always succeeds, but it might drop
 			 * the packet.  If it drops the packet, we log that
 			 * in our stats. */
-			IEEE80211_DEBUG_DROP
+			LIBIPW_DEBUG_DROP
 			    ("RX: netif_rx dropped the packet\n");
 			dev->stats.rx_dropped++;
 		}
@@ -829,18 +830,18 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	return 0;
 }
 
-/* Filter out unrelated packets, call ieee80211_rx[_mgt]
+/* Filter out unrelated packets, call libipw_rx[_mgt]
  * This function takes over the skb, it should not be used again after calling
  * this function. */
-void ieee80211_rx_any(struct ieee80211_device *ieee,
-		     struct sk_buff *skb, struct ieee80211_rx_stats *stats)
+void libipw_rx_any(struct libipw_device *ieee,
+		     struct sk_buff *skb, struct libipw_rx_stats *stats)
 {
-	struct ieee80211_hdr_4addr *hdr;
+	struct libipw_hdr_4addr *hdr;
 	int is_packet_for_us;
 	u16 fc;
 
 	if (ieee->iw_mode == IW_MODE_MONITOR) {
-		if (!ieee80211_rx(ieee, skb, stats))
+		if (!libipw_rx(ieee, skb, stats))
 			dev_kfree_skb_irq(skb);
 		return;
 	}
@@ -848,7 +849,7 @@ void ieee80211_rx_any(struct ieee80211_device *ieee,
 	if (skb->len < sizeof(struct ieee80211_hdr))
 		goto drop_free;
 
-	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	hdr = (struct libipw_hdr_4addr *)skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	if ((fc & IEEE80211_FCTL_VERS) != 0)
@@ -856,9 +857,9 @@ void ieee80211_rx_any(struct ieee80211_device *ieee,
 
 	switch (fc & IEEE80211_FCTL_FTYPE) {
 	case IEEE80211_FTYPE_MGMT:
-		if (skb->len < sizeof(struct ieee80211_hdr_3addr))
+		if (skb->len < sizeof(struct libipw_hdr_3addr))
 			goto drop_free;
-		ieee80211_rx_mgt(ieee, hdr, stats);
+		libipw_rx_mgt(ieee, hdr, stats);
 		dev_kfree_skb_irq(skb);
 		return;
 	case IEEE80211_FTYPE_DATA:
@@ -910,7 +911,7 @@ void ieee80211_rx_any(struct ieee80211_device *ieee,
 	}
 
 	if (is_packet_for_us)
-		if (!ieee80211_rx(ieee, skb, stats))
+		if (!libipw_rx(ieee, skb, stats))
 			dev_kfree_skb_irq(skb);
 	return;
 
@@ -928,7 +929,7 @@ static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
 * Make ther structure we read from the beacon packet has
 * the right values
 */
-static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
+static int libipw_verify_qos_info(struct libipw_qos_information_element
 				     *info_element, int sub_type)
 {
 
@@ -947,12 +948,12 @@ static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
 /*
  * Parse a QoS parameter element
  */
-static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
-					    *element_param, struct ieee80211_info_element
+static int libipw_read_qos_param_element(struct libipw_qos_parameter_info
+					    *element_param, struct libipw_info_element
 					    *info_element)
 {
 	int ret = 0;
-	u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
+	u16 size = sizeof(struct libipw_qos_parameter_info) - 2;
 
 	if ((info_element == NULL) || (element_param == NULL))
 		return -1;
@@ -965,7 +966,7 @@ static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
 	} else
 		ret = -1;
 	if (ret == 0)
-		ret = ieee80211_verify_qos_info(&element_param->info_element,
+		ret = libipw_verify_qos_info(&element_param->info_element,
 						QOS_OUI_PARAM_SUB_TYPE);
 	return ret;
 }
@@ -973,13 +974,13 @@ static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
 /*
  * Parse a QoS information element
  */
-static int ieee80211_read_qos_info_element(struct
-					   ieee80211_qos_information_element
-					   *element_info, struct ieee80211_info_element
+static int libipw_read_qos_info_element(struct
+					   libipw_qos_information_element
+					   *element_info, struct libipw_info_element
 					   *info_element)
 {
 	int ret = 0;
-	u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
+	u16 size = sizeof(struct libipw_qos_information_element) - 2;
 
 	if (element_info == NULL)
 		return -1;
@@ -995,7 +996,7 @@ static int ieee80211_read_qos_info_element(struct
 		ret = -1;
 
 	if (ret == 0)
-		ret = ieee80211_verify_qos_info(element_info,
+		ret = libipw_verify_qos_info(element_info,
 						QOS_OUI_INFO_SUB_TYPE);
 	return ret;
 }
@@ -1003,15 +1004,15 @@ static int ieee80211_read_qos_info_element(struct
 /*
  * Write QoS parameters from the ac parameters.
  */
-static int ieee80211_qos_convert_ac_to_parameters(struct
-						  ieee80211_qos_parameter_info
+static int libipw_qos_convert_ac_to_parameters(struct
+						  libipw_qos_parameter_info
 						  *param_elm, struct
-						  ieee80211_qos_parameters
+						  libipw_qos_parameters
 						  *qos_param)
 {
 	int rc = 0;
 	int i;
-	struct ieee80211_qos_ac_parameter *ac_params;
+	struct libipw_qos_ac_parameter *ac_params;
 	u32 txop;
 	u8 cw_min;
 	u8 cw_max;
@@ -1042,27 +1043,27 @@ static int ieee80211_qos_convert_ac_to_parameters(struct
  * parameters element. check the information element length to decide
  * which type to read
  */
-static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
+static int libipw_parse_qos_info_param_IE(struct libipw_info_element
 					     *info_element,
-					     struct ieee80211_network *network)
+					     struct libipw_network *network)
 {
 	int rc = 0;
-	struct ieee80211_qos_parameters *qos_param = NULL;
-	struct ieee80211_qos_information_element qos_info_element;
+	struct libipw_qos_parameters *qos_param = NULL;
+	struct libipw_qos_information_element qos_info_element;
 
-	rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
+	rc = libipw_read_qos_info_element(&qos_info_element, info_element);
 
 	if (rc == 0) {
 		network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
 		network->flags |= NETWORK_HAS_QOS_INFORMATION;
 	} else {
-		struct ieee80211_qos_parameter_info param_element;
+		struct libipw_qos_parameter_info param_element;
 
-		rc = ieee80211_read_qos_param_element(&param_element,
+		rc = libipw_read_qos_param_element(&param_element,
 						      info_element);
 		if (rc == 0) {
 			qos_param = &(network->qos_data.parameters);
-			ieee80211_qos_convert_ac_to_parameters(&param_element,
+			libipw_qos_convert_ac_to_parameters(&param_element,
 							       qos_param);
 			network->flags |= NETWORK_HAS_QOS_PARAMETERS;
 			network->qos_data.param_count =
@@ -1071,7 +1072,7 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
 	}
 
 	if (rc == 0) {
-		IEEE80211_DEBUG_QOS("QoS is supported\n");
+		LIBIPW_DEBUG_QOS("QoS is supported\n");
 		network->qos_data.supported = 1;
 	}
 	return rc;
@@ -1116,9 +1117,9 @@ static const char *get_info_element_string(u16 id)
 }
 #endif
 
-static int ieee80211_parse_info_param(struct ieee80211_info_element
+static int libipw_parse_info_param(struct libipw_info_element
 				      *info_element, u16 length,
-				      struct ieee80211_network *network)
+				      struct libipw_network *network)
 {
 	DECLARE_SSID_BUF(ssid);
 	u8 i;
@@ -1129,7 +1130,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 
 	while (length >= sizeof(*info_element)) {
 		if (sizeof(*info_element) + info_element->len > length) {
-			IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
+			LIBIPW_DEBUG_MGMT("Info elem: parse failed: "
 					     "info_element->len + 2 > left : "
 					     "info_element->len+2=%zd left=%d, id=%d.\n",
 					     info_element->len +
@@ -1151,7 +1152,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 				memset(network->ssid + network->ssid_len, 0,
 				       IW_ESSID_MAX_SIZE - network->ssid_len);
 
-			IEEE80211_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n",
+			LIBIPW_DEBUG_MGMT("WLAN_EID_SSID: '%s' len=%d.\n",
 					     print_ssid(ssid, network->ssid,
 							network->ssid_len),
 					     network->ssid_len);
@@ -1170,17 +1171,17 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 					      (p - rates_str), "%02X ",
 					      network->rates[i]);
 #endif
-				if (ieee80211_is_ofdm_rate
+				if (libipw_is_ofdm_rate
 				    (info_element->data[i])) {
 					network->flags |= NETWORK_HAS_OFDM;
 					if (info_element->data[i] &
-					    IEEE80211_BASIC_RATE_MASK)
+					    LIBIPW_BASIC_RATE_MASK)
 						network->flags &=
 						    ~NETWORK_HAS_CCK;
 				}
 			}
 
-			IEEE80211_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
+			LIBIPW_DEBUG_MGMT("WLAN_EID_SUPP_RATES: '%s' (%d)\n",
 					     rates_str, network->rates_len);
 			break;
 
@@ -1197,61 +1198,61 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 					      (p - rates_str), "%02X ",
 					      network->rates[i]);
 #endif
-				if (ieee80211_is_ofdm_rate
+				if (libipw_is_ofdm_rate
 				    (info_element->data[i])) {
 					network->flags |= NETWORK_HAS_OFDM;
 					if (info_element->data[i] &
-					    IEEE80211_BASIC_RATE_MASK)
+					    LIBIPW_BASIC_RATE_MASK)
 						network->flags &=
 						    ~NETWORK_HAS_CCK;
 				}
 			}
 
-			IEEE80211_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
+			LIBIPW_DEBUG_MGMT("WLAN_EID_EXT_SUPP_RATES: '%s' (%d)\n",
 					     rates_str, network->rates_ex_len);
 			break;
 
 		case WLAN_EID_DS_PARAMS:
-			IEEE80211_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
+			LIBIPW_DEBUG_MGMT("WLAN_EID_DS_PARAMS: %d\n",
 					     info_element->data[0]);
 			network->channel = info_element->data[0];
 			break;
 
 		case WLAN_EID_FH_PARAMS:
-			IEEE80211_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
+			LIBIPW_DEBUG_MGMT("WLAN_EID_FH_PARAMS: ignored\n");
 			break;
 
 		case WLAN_EID_CF_PARAMS:
-			IEEE80211_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
+			LIBIPW_DEBUG_MGMT("WLAN_EID_CF_PARAMS: ignored\n");
 			break;
 
 		case WLAN_EID_TIM:
 			network->tim.tim_count = info_element->data[0];
 			network->tim.tim_period = info_element->data[1];
-			IEEE80211_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
+			LIBIPW_DEBUG_MGMT("WLAN_EID_TIM: partially ignored\n");
 			break;
 
 		case WLAN_EID_ERP_INFO:
 			network->erp_value = info_element->data[0];
 			network->flags |= NETWORK_HAS_ERP_VALUE;
-			IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
+			LIBIPW_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
 					     network->erp_value);
 			break;
 
 		case WLAN_EID_IBSS_PARAMS:
 			network->atim_window = info_element->data[0];
-			IEEE80211_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
+			LIBIPW_DEBUG_MGMT("WLAN_EID_IBSS_PARAMS: %d\n",
 					     network->atim_window);
 			break;
 
 		case WLAN_EID_CHALLENGE:
-			IEEE80211_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
+			LIBIPW_DEBUG_MGMT("WLAN_EID_CHALLENGE: ignored\n");
 			break;
 
 		case WLAN_EID_GENERIC:
-			IEEE80211_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n",
+			LIBIPW_DEBUG_MGMT("WLAN_EID_GENERIC: %d bytes\n",
 					     info_element->len);
-			if (!ieee80211_parse_qos_info_param_IE(info_element,
+			if (!libipw_parse_qos_info_param_IE(info_element,
 							       network))
 				break;
 
@@ -1268,7 +1269,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 			break;
 
 		case WLAN_EID_RSN:
-			IEEE80211_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
+			LIBIPW_DEBUG_MGMT("WLAN_EID_RSN: %d bytes\n",
 					     info_element->len);
 			network->rsn_ie_len = min(info_element->len + 2,
 						  MAX_WPA_IE_LEN);
@@ -1318,7 +1319,7 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 			break;
 
 		default:
-			IEEE80211_DEBUG_MGMT
+			LIBIPW_DEBUG_MGMT
 			    ("Unsupported info element: %s (%d)\n",
 			     get_info_element_string(info_element->id),
 			     info_element->id);
@@ -1327,20 +1328,20 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
 
 		length -= sizeof(*info_element) + info_element->len;
 		info_element =
-		    (struct ieee80211_info_element *)&info_element->
+		    (struct libipw_info_element *)&info_element->
 		    data[info_element->len];
 	}
 
 	return 0;
 }
 
-static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
-				       *frame, struct ieee80211_rx_stats *stats)
+static int libipw_handle_assoc_resp(struct libipw_device *ieee, struct libipw_assoc_response
+				       *frame, struct libipw_rx_stats *stats)
 {
-	struct ieee80211_network network_resp = {
+	struct libipw_network network_resp = {
 		.ibss_dfs = NULL,
 	};
-	struct ieee80211_network *network = &network_resp;
+	struct libipw_network *network = &network_resp;
 	struct net_device *dev = ieee->dev;
 
 	network->flags = 0;
@@ -1361,7 +1362,7 @@ static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct iee
 	network->erp_value =
 	    (network->capability & WLAN_CAPABILITY_IBSS) ? 0x3 : 0x0;
 
-	if (stats->freq == IEEE80211_52GHZ_BAND) {
+	if (stats->freq == LIBIPW_52GHZ_BAND) {
 		/* for A band (No DS info) */
 		network->channel = stats->received_channel;
 	} else
@@ -1370,12 +1371,12 @@ static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct iee
 	network->wpa_ie_len = 0;
 	network->rsn_ie_len = 0;
 
-	if (ieee80211_parse_info_param
+	if (libipw_parse_info_param
 	    (frame->info_element, stats->len - sizeof(*frame), network))
 		return 1;
 
 	network->mode = 0;
-	if (stats->freq == IEEE80211_52GHZ_BAND)
+	if (stats->freq == LIBIPW_52GHZ_BAND)
 		network->mode = IEEE_A;
 	else {
 		if (network->flags & NETWORK_HAS_OFDM)
@@ -1394,10 +1395,10 @@ static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct iee
 
 /***************************************************/
 
-static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response
+static int libipw_network_init(struct libipw_device *ieee, struct libipw_probe_response
 					 *beacon,
-					 struct ieee80211_network *network,
-					 struct ieee80211_rx_stats *stats)
+					 struct libipw_network *network,
+					 struct libipw_rx_stats *stats)
 {
 	DECLARE_SSID_BUF(ssid);
 
@@ -1423,7 +1424,7 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021
 	network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
 	    0x3 : 0x0;
 
-	if (stats->freq == IEEE80211_52GHZ_BAND) {
+	if (stats->freq == LIBIPW_52GHZ_BAND) {
 		/* for A band (No DS info) */
 		network->channel = stats->received_channel;
 	} else
@@ -1432,12 +1433,12 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021
 	network->wpa_ie_len = 0;
 	network->rsn_ie_len = 0;
 
-	if (ieee80211_parse_info_param
+	if (libipw_parse_info_param
 	    (beacon->info_element, stats->len - sizeof(*beacon), network))
 		return 1;
 
 	network->mode = 0;
-	if (stats->freq == IEEE80211_52GHZ_BAND)
+	if (stats->freq == LIBIPW_52GHZ_BAND)
 		network->mode = IEEE_A;
 	else {
 		if (network->flags & NETWORK_HAS_OFDM)
@@ -1447,7 +1448,7 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021
 	}
 
 	if (network->mode == 0) {
-		IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
+		LIBIPW_DEBUG_SCAN("Filtered out '%s (%pM)' "
 				     "network.\n",
 				     print_ssid(ssid, network->ssid,
 						 network->ssid_len),
@@ -1460,8 +1461,8 @@ static int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee8021
 	return 0;
 }
 
-static inline int is_same_network(struct ieee80211_network *src,
-				  struct ieee80211_network *dst)
+static inline int is_same_network(struct libipw_network *src,
+				  struct libipw_network *dst)
 {
 	/* A network is only a duplicate if the channel, BSSID, and ESSID
 	 * all match.  We treat all <hidden> with the same BSSID and channel
@@ -1472,13 +1473,13 @@ static inline int is_same_network(struct ieee80211_network *src,
 		!memcmp(src->ssid, dst->ssid, src->ssid_len));
 }
 
-static void update_network(struct ieee80211_network *dst,
-				  struct ieee80211_network *src)
+static void update_network(struct libipw_network *dst,
+				  struct libipw_network *src)
 {
 	int qos_active;
 	u8 old_param;
 
-	ieee80211_network_reset(dst);
+	libipw_network_reset(dst);
 	dst->ibss_dfs = src->ibss_dfs;
 
 	/* We only update the statistics if they were created by receiving
@@ -1488,9 +1489,9 @@ static void update_network(struct ieee80211_network *dst,
 	 * down the signal level of an AP. */
 	if (dst->channel == src->stats.received_channel)
 		memcpy(&dst->stats, &src->stats,
-		       sizeof(struct ieee80211_rx_stats));
+		       sizeof(struct libipw_rx_stats));
 	else
-		IEEE80211_DEBUG_SCAN("Network %pM info received "
+		LIBIPW_DEBUG_SCAN("Network %pM info received "
 			"off channel (%d vs. %d)\n", src->bssid,
 			dst->channel, src->stats.received_channel);
 
@@ -1521,7 +1522,7 @@ static void update_network(struct ieee80211_network *dst,
 	old_param = dst->qos_data.old_param_count;
 	if (dst->flags & NETWORK_HAS_QOS_MASK)
 		memcpy(&dst->qos_data, &src->qos_data,
-		       sizeof(struct ieee80211_qos_data));
+		       sizeof(struct libipw_qos_data));
 	else {
 		dst->qos_data.supported = src->qos_data.supported;
 		dst->qos_data.param_count = src->qos_data.param_count;
@@ -1529,11 +1530,11 @@ static void update_network(struct ieee80211_network *dst,
 
 	if (dst->qos_data.supported == 1) {
 		if (dst->ssid_len)
-			IEEE80211_DEBUG_QOS
+			LIBIPW_DEBUG_QOS
 			    ("QoS the network %s is QoS supported\n",
 			     dst->ssid);
 		else
-			IEEE80211_DEBUG_QOS
+			LIBIPW_DEBUG_QOS
 			    ("QoS the network is QoS supported\n");
 	}
 	dst->qos_data.active = qos_active;
@@ -1547,25 +1548,25 @@ static inline int is_beacon(__le16 fc)
 	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
 }
 
-static void ieee80211_process_probe_response(struct ieee80211_device
+static void libipw_process_probe_response(struct libipw_device
 						    *ieee, struct
-						    ieee80211_probe_response
-						    *beacon, struct ieee80211_rx_stats
+						    libipw_probe_response
+						    *beacon, struct libipw_rx_stats
 						    *stats)
 {
 	struct net_device *dev = ieee->dev;
-	struct ieee80211_network network = {
+	struct libipw_network network = {
 		.ibss_dfs = NULL,
 	};
-	struct ieee80211_network *target;
-	struct ieee80211_network *oldest = NULL;
+	struct libipw_network *target;
+	struct libipw_network *oldest = NULL;
 #ifdef CONFIG_LIBIPW_DEBUG
-	struct ieee80211_info_element *info_element = beacon->info_element;
+	struct libipw_info_element *info_element = beacon->info_element;
 #endif
 	unsigned long flags;
 	DECLARE_SSID_BUF(ssid);
 
-	IEEE80211_DEBUG_SCAN("'%s' (%pM"
+	LIBIPW_DEBUG_SCAN("'%s' (%pM"
 		     "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
 		     print_ssid(ssid, info_element->data, info_element->len),
 		     beacon->header.addr3,
@@ -1586,8 +1587,8 @@ static void ieee80211_process_probe_response(struct ieee80211_device
 		     (beacon->capability & cpu_to_le16(1 << 0x1)) ? '1' : '0',
 		     (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
 
-	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
-		IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
+	if (libipw_network_init(ieee, beacon, &network, stats)) {
+		LIBIPW_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
 				     print_ssid(ssid, info_element->data,
 						 info_element->len),
 				     beacon->header.addr3,
@@ -1624,21 +1625,21 @@ static void ieee80211_process_probe_response(struct ieee80211_device
 			/* If there are no more slots, expire the oldest */
 			list_del(&oldest->list);
 			target = oldest;
-			IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
+			LIBIPW_DEBUG_SCAN("Expired '%s' (%pM) from "
 					     "network list.\n",
 					     print_ssid(ssid, target->ssid,
 							 target->ssid_len),
 					     target->bssid);
-			ieee80211_network_reset(target);
+			libipw_network_reset(target);
 		} else {
 			/* Otherwise just pull from the free list */
 			target = list_entry(ieee->network_free_list.next,
-					    struct ieee80211_network, list);
+					    struct libipw_network, list);
 			list_del(ieee->network_free_list.next);
 		}
 
 #ifdef CONFIG_LIBIPW_DEBUG
-		IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
+		LIBIPW_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
 				     print_ssid(ssid, network.ssid,
 						 network.ssid_len),
 				     network.bssid,
@@ -1649,7 +1650,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
 		network.ibss_dfs = NULL;
 		list_add_tail(&target->list, &ieee->network_list);
 	} else {
-		IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
+		LIBIPW_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
 				     print_ssid(ssid, target->ssid,
 						 target->ssid_len),
 				     target->bssid,
@@ -1670,121 +1671,121 @@ static void ieee80211_process_probe_response(struct ieee80211_device
 	}
 }
 
-void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-		      struct ieee80211_hdr_4addr *header,
-		      struct ieee80211_rx_stats *stats)
+void libipw_rx_mgt(struct libipw_device *ieee,
+		      struct libipw_hdr_4addr *header,
+		      struct libipw_rx_stats *stats)
 {
 	switch (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl))) {
 	case IEEE80211_STYPE_ASSOC_RESP:
-		IEEE80211_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
+		LIBIPW_DEBUG_MGMT("received ASSOCIATION RESPONSE (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
-		ieee80211_handle_assoc_resp(ieee,
-					    (struct ieee80211_assoc_response *)
+		libipw_handle_assoc_resp(ieee,
+					    (struct libipw_assoc_response *)
 					    header, stats);
 		break;
 
 	case IEEE80211_STYPE_REASSOC_RESP:
-		IEEE80211_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
+		LIBIPW_DEBUG_MGMT("received REASSOCIATION RESPONSE (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 		break;
 
 	case IEEE80211_STYPE_PROBE_REQ:
-		IEEE80211_DEBUG_MGMT("received auth (%d)\n",
+		LIBIPW_DEBUG_MGMT("received auth (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
 		if (ieee->handle_probe_request != NULL)
 			ieee->handle_probe_request(ieee->dev,
 						   (struct
-						    ieee80211_probe_request *)
+						    libipw_probe_request *)
 						   header, stats);
 		break;
 
 	case IEEE80211_STYPE_PROBE_RESP:
-		IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
+		LIBIPW_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
-		IEEE80211_DEBUG_SCAN("Probe response\n");
-		ieee80211_process_probe_response(ieee,
+		LIBIPW_DEBUG_SCAN("Probe response\n");
+		libipw_process_probe_response(ieee,
 						 (struct
-						  ieee80211_probe_response *)
+						  libipw_probe_response *)
 						 header, stats);
 		break;
 
 	case IEEE80211_STYPE_BEACON:
-		IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
+		LIBIPW_DEBUG_MGMT("received BEACON (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
-		IEEE80211_DEBUG_SCAN("Beacon\n");
-		ieee80211_process_probe_response(ieee,
+		LIBIPW_DEBUG_SCAN("Beacon\n");
+		libipw_process_probe_response(ieee,
 						 (struct
-						  ieee80211_probe_response *)
+						  libipw_probe_response *)
 						 header, stats);
 		break;
 	case IEEE80211_STYPE_AUTH:
 
-		IEEE80211_DEBUG_MGMT("received auth (%d)\n",
+		LIBIPW_DEBUG_MGMT("received auth (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
 		if (ieee->handle_auth != NULL)
 			ieee->handle_auth(ieee->dev,
-					  (struct ieee80211_auth *)header);
+					  (struct libipw_auth *)header);
 		break;
 
 	case IEEE80211_STYPE_DISASSOC:
 		if (ieee->handle_disassoc != NULL)
 			ieee->handle_disassoc(ieee->dev,
-					      (struct ieee80211_disassoc *)
+					      (struct libipw_disassoc *)
 					      header);
 		break;
 
 	case IEEE80211_STYPE_ACTION:
-		IEEE80211_DEBUG_MGMT("ACTION\n");
+		LIBIPW_DEBUG_MGMT("ACTION\n");
 		if (ieee->handle_action)
 			ieee->handle_action(ieee->dev,
-					    (struct ieee80211_action *)
+					    (struct libipw_action *)
 					    header, stats);
 		break;
 
 	case IEEE80211_STYPE_REASSOC_REQ:
-		IEEE80211_DEBUG_MGMT("received reassoc (%d)\n",
+		LIBIPW_DEBUG_MGMT("received reassoc (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
-		IEEE80211_DEBUG_MGMT("%s: IEEE80211_REASSOC_REQ received\n",
+		LIBIPW_DEBUG_MGMT("%s: LIBIPW_REASSOC_REQ received\n",
 				     ieee->dev->name);
 		if (ieee->handle_reassoc_request != NULL)
 			ieee->handle_reassoc_request(ieee->dev,
-						    (struct ieee80211_reassoc_request *)
+						    (struct libipw_reassoc_request *)
 						     header);
 		break;
 
 	case IEEE80211_STYPE_ASSOC_REQ:
-		IEEE80211_DEBUG_MGMT("received assoc (%d)\n",
+		LIBIPW_DEBUG_MGMT("received assoc (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
 
-		IEEE80211_DEBUG_MGMT("%s: IEEE80211_ASSOC_REQ received\n",
+		LIBIPW_DEBUG_MGMT("%s: LIBIPW_ASSOC_REQ received\n",
 				     ieee->dev->name);
 		if (ieee->handle_assoc_request != NULL)
 			ieee->handle_assoc_request(ieee->dev);
 		break;
 
 	case IEEE80211_STYPE_DEAUTH:
-		IEEE80211_DEBUG_MGMT("DEAUTH\n");
+		LIBIPW_DEBUG_MGMT("DEAUTH\n");
 		if (ieee->handle_deauth != NULL)
 			ieee->handle_deauth(ieee->dev,
-					    (struct ieee80211_deauth *)
+					    (struct libipw_deauth *)
 					    header);
 		break;
 	default:
-		IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
+		LIBIPW_DEBUG_MGMT("received UNKNOWN (%d)\n",
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
-		IEEE80211_DEBUG_MGMT("%s: Unknown management packet: %d\n",
+		LIBIPW_DEBUG_MGMT("%s: Unknown management packet: %d\n",
 				     ieee->dev->name,
 				     WLAN_FC_GET_STYPE(le16_to_cpu
 						       (header->frame_ctl)));
@@ -1792,6 +1793,6 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
 	}
 }
 
-EXPORT_SYMBOL_GPL(ieee80211_rx_any);
-EXPORT_SYMBOL(ieee80211_rx_mgt);
-EXPORT_SYMBOL(ieee80211_rx);
+EXPORT_SYMBOL_GPL(libipw_rx_any);
+EXPORT_SYMBOL(libipw_rx_mgt);
+EXPORT_SYMBOL(libipw_rx);
diff --git a/drivers/net/wireless/ipw2x00/libipw_tx.c b/drivers/net/wireless/ipw2x00/libipw_tx.c
index da2ad54..da8beac 100644
--- a/drivers/net/wireless/ipw2x00/libipw_tx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_tx.c
@@ -19,7 +19,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 ******************************************************************************/
@@ -41,7 +41,7 @@
 #include <linux/etherdevice.h>
 #include <asm/uaccess.h>
 
-#include "ieee80211.h"
+#include "libipw.h"
 
 /*
 
@@ -126,12 +126,12 @@ payload of each frame is reduced to 492 bytes.
 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
 
-static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
+static int libipw_copy_snap(u8 * data, __be16 h_proto)
 {
-	struct ieee80211_snap_hdr *snap;
+	struct libipw_snap_hdr *snap;
 	u8 *oui;
 
-	snap = (struct ieee80211_snap_hdr *)data;
+	snap = (struct libipw_snap_hdr *)data;
 	snap->dsap = 0xaa;
 	snap->ssap = 0xaa;
 	snap->ctrl = 0x03;
@@ -149,7 +149,7 @@ static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
 	return SNAP_SIZE + sizeof(u16);
 }
 
-static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
+static int libipw_encrypt_fragment(struct libipw_device *ieee,
 					     struct sk_buff *frag, int hdr_len)
 {
 	struct lib80211_crypt_data *crypt =
@@ -177,7 +177,7 @@ static int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
 	return 0;
 }
 
-void ieee80211_txb_free(struct ieee80211_txb *txb)
+void libipw_txb_free(struct libipw_txb *txb)
 {
 	int i;
 	if (unlikely(!txb))
@@ -188,17 +188,17 @@ void ieee80211_txb_free(struct ieee80211_txb *txb)
 	kfree(txb);
 }
 
-static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+static struct libipw_txb *libipw_alloc_txb(int nr_frags, int txb_size,
 						 int headroom, gfp_t gfp_mask)
 {
-	struct ieee80211_txb *txb;
+	struct libipw_txb *txb;
 	int i;
-	txb = kmalloc(sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
+	txb = kmalloc(sizeof(struct libipw_txb) + (sizeof(u8 *) * nr_frags),
 		      gfp_mask);
 	if (!txb)
 		return NULL;
 
-	memset(txb, 0, sizeof(struct ieee80211_txb));
+	memset(txb, 0, sizeof(struct libipw_txb));
 	txb->nr_frags = nr_frags;
 	txb->frag_size = txb_size;
 
@@ -220,7 +220,7 @@ static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
 	return txb;
 }
 
-static int ieee80211_classify(struct sk_buff *skb)
+static int libipw_classify(struct sk_buff *skb)
 {
 	struct ethhdr *eth;
 	struct iphdr *ip;
@@ -252,11 +252,11 @@ static int ieee80211_classify(struct sk_buff *skb)
 
 /* Incoming skb is converted to a txb which consists of
  * a block of 802.11 fragment packets (stored as skbs) */
-int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct ieee80211_device *ieee = netdev_priv(dev);
-	struct ieee80211_txb *txb = NULL;
-	struct ieee80211_hdr_3addrqos *frag_hdr;
+	struct libipw_device *ieee = netdev_priv(dev);
+	struct libipw_txb *txb = NULL;
+	struct libipw_hdr_3addrqos *frag_hdr;
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
 	    rts_required;
 	unsigned long flags;
@@ -264,7 +264,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 	__be16 ether_type;
 	int bytes, fc, hdr_len;
 	struct sk_buff *skb_frag;
-	struct ieee80211_hdr_3addrqos header = {/* Ensure zero initialized */
+	struct libipw_hdr_3addrqos header = {/* Ensure zero initialized */
 		.duration_id = 0,
 		.seq_ctl = 0,
 		.qos_ctl = 0
@@ -331,14 +331,14 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		memcpy(header.addr2, src, ETH_ALEN);
 		memcpy(header.addr3, ieee->bssid, ETH_ALEN);
 	}
-	hdr_len = IEEE80211_3ADDR_LEN;
+	hdr_len = LIBIPW_3ADDR_LEN;
 
 	if (ieee->is_qos_active && ieee->is_qos_active(dev, skb)) {
 		fc |= IEEE80211_STYPE_QOS_DATA;
 		hdr_len += 2;
 
-		skb->priority = ieee80211_classify(skb);
-		header.qos_ctl |= cpu_to_le16(skb->priority & IEEE80211_QCTL_TID);
+		skb->priority = libipw_classify(skb);
+		header.qos_ctl |= cpu_to_le16(skb->priority & LIBIPW_QCTL_TID);
 	}
 	header.frame_ctl = cpu_to_le16(fc);
 
@@ -362,12 +362,12 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb_reserve(skb_new, crypt->ops->extra_msdu_prefix_len);
 		memcpy(skb_put(skb_new, hdr_len), &header, hdr_len);
 		snapped = 1;
-		ieee80211_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
+		libipw_copy_snap(skb_put(skb_new, SNAP_SIZE + sizeof(u16)),
 				    ether_type);
 		skb_copy_from_linear_data(skb, skb_put(skb_new, skb->len), skb->len);
 		res = crypt->ops->encrypt_msdu(skb_new, hdr_len, crypt->priv);
 		if (res < 0) {
-			IEEE80211_ERROR("msdu encryption failed\n");
+			LIBIPW_ERROR("msdu encryption failed\n");
 			dev_kfree_skb_any(skb_new);
 			goto failed;
 		}
@@ -393,8 +393,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		 * for it when determining the amount of payload space. */
 		bytes_per_frag = frag_size - hdr_len;
 		if (ieee->config &
-		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
-			bytes_per_frag -= IEEE80211_FCS_LEN;
+		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
+			bytes_per_frag -= LIBIPW_FCS_LEN;
 
 		/* Each fragment may need to have room for encryptiong
 		 * pre/postfix */
@@ -417,14 +417,14 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	rts_required = (frag_size > ieee->rts
-			&& ieee->config & CFG_IEEE80211_RTS);
+			&& ieee->config & CFG_LIBIPW_RTS);
 	if (rts_required)
 		nr_frags++;
 
 	/* When we allocate the TXB we allocate enough space for the reserve
 	 * and full fragment bytes (bytes_per_frag doesn't include prefix,
 	 * postfix, header, FCS, etc.) */
-	txb = ieee80211_alloc_txb(nr_frags, frag_size,
+	txb = libipw_alloc_txb(nr_frags, frag_size,
 				  ieee->tx_headroom, GFP_ATOMIC);
 	if (unlikely(!txb)) {
 		printk(KERN_WARNING "%s: Could not allocate TXB\n",
@@ -441,7 +441,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (rts_required) {
 		skb_frag = txb->fragments[0];
 		frag_hdr =
-		    (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
+		    (struct libipw_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 
 		/*
 		 * Set header frame_ctl to the RTS.
@@ -456,7 +456,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		header.frame_ctl = cpu_to_le16(fc);
 
 		if (ieee->config &
-		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
 			skb_put(skb_frag, 4);
 
 		txb->rts_included = 1;
@@ -472,7 +472,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 				    crypt->ops->extra_mpdu_prefix_len);
 
 		frag_hdr =
-		    (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
+		    (struct libipw_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 		memcpy(frag_hdr, &header, hdr_len);
 
 		/* If this is not the last fragment, then add the MOREFRAGS
@@ -487,7 +487,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 
 		if (i == 0 && !snapped) {
-			ieee80211_copy_snap(skb_put
+			libipw_copy_snap(skb_put
 					    (skb_frag, SNAP_SIZE + sizeof(u16)),
 					    ether_type);
 			bytes -= SNAP_SIZE + sizeof(u16);
@@ -501,7 +501,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		/* Encryption routine will move the header forward in order
 		 * to insert the IV between the header and the payload */
 		if (host_encrypt)
-			ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
+			libipw_encrypt_fragment(ieee, skb_frag, hdr_len);
 		else if (host_build_iv) {
 			atomic_inc(&crypt->refcnt);
 			if (crypt->ops->build_iv)
@@ -513,7 +513,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 
 		if (ieee->config &
-		    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+		    (CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
 			skb_put(skb_frag, 4);
 	}
 
@@ -523,17 +523,17 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev_kfree_skb_any(skb);
 
 	if (txb) {
-		int ret = (*ieee->hard_start_xmit) (txb, dev, priority);
-		if (ret == 0) {
+		netdev_tx_t ret = (*ieee->hard_start_xmit)(txb, dev, priority);
+		if (ret == NETDEV_TX_OK) {
 			dev->stats.tx_packets++;
 			dev->stats.tx_bytes += txb->payload_size;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 
-		ieee80211_txb_free(txb);
+		libipw_txb_free(txb);
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 
       failed:
 	spin_unlock_irqrestore(&ieee->lock, flags);
@@ -541,6 +541,6 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->stats.tx_errors++;
 	return NETDEV_TX_BUSY;
 }
-EXPORT_SYMBOL(ieee80211_xmit);
+EXPORT_SYMBOL(libipw_xmit);
 
-EXPORT_SYMBOL(ieee80211_txb_free);
+EXPORT_SYMBOL(libipw_txb_free);
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
index 3c0812d..4d89f66 100644
--- a/drivers/net/wireless/ipw2x00/libipw_wx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -25,7 +25,7 @@
   file called LICENSE.
 
   Contact Information:
-  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Linux Wireless <ilw@linux.intel.com>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 ******************************************************************************/
@@ -37,9 +37,9 @@
 #include <net/lib80211.h>
 #include <linux/wireless.h>
 
-#include "ieee80211.h"
+#include "libipw.h"
 
-static const char *ieee80211_modes[] = {
+static const char *libipw_modes[] = {
 	"?", "a", "b", "ab", "g", "ag", "bg", "abg"
 };
 
@@ -54,9 +54,9 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
 }
 
 #define MAX_CUSTOM_LEN 64
-static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
+static char *libipw_translate_scan(struct libipw_device *ieee,
 				      char *start, char *stop,
-				      struct ieee80211_network *network,
+				      struct libipw_network *network,
 				      struct iw_request_info *info)
 {
 	char custom[MAX_CUSTOM_LEN];
@@ -84,7 +84,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 	/* Add the protocol name */
 	iwe.cmd = SIOCGIWNAME;
 	snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
-		 ieee80211_modes[network->mode]);
+		 libipw_modes[network->mode]);
 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
 
 	/* Add mode */
@@ -102,7 +102,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 	/* Add channel and frequency */
 	/* Note : userspace automatically computes channel using iwrange */
 	iwe.cmd = SIOCGIWFREQ;
-	iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
+	iwe.u.freq.m = libipw_channel_to_freq(ieee, network->channel);
 	iwe.u.freq.e = 6;
 	iwe.u.freq.i = 0;
 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
@@ -155,7 +155,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 	iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
 	    IW_QUAL_NOISE_UPDATED;
 
-	if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) {
+	if (!(network->stats.mask & LIBIPW_STATMASK_RSSI)) {
 		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID |
 		    IW_QUAL_LEVEL_INVALID;
 		iwe.u.qual.qual = 0;
@@ -180,14 +180,14 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 			iwe.u.qual.qual = 0;
 	}
 
-	if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) {
+	if (!(network->stats.mask & LIBIPW_STATMASK_NOISE)) {
 		iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
 		iwe.u.qual.noise = 0;
 	} else {
 		iwe.u.qual.noise = network->stats.noise;
 	}
 
-	if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) {
+	if (!(network->stats.mask & LIBIPW_STATMASK_SIGNAL)) {
 		iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
 		iwe.u.qual.level = 0;
 	} else {
@@ -237,14 +237,14 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 	p = custom;
 	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: ");
 
-	if (ieee80211_get_channel_flags(ieee, network->channel) &
-	    IEEE80211_CH_INVALID) {
+	if (libipw_get_channel_flags(ieee, network->channel) &
+	    LIBIPW_CH_INVALID) {
 		iwe.cmd = IWEVCUSTOM;
 		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID ");
 	}
 
-	if (ieee80211_get_channel_flags(ieee, network->channel) &
-	    IEEE80211_CH_RADAR_DETECT) {
+	if (libipw_get_channel_flags(ieee, network->channel) &
+	    LIBIPW_CH_RADAR_DETECT) {
 		iwe.cmd = IWEVCUSTOM;
 		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS ");
 	}
@@ -259,11 +259,11 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 
 #define SCAN_ITEM_SIZE 128
 
-int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+int libipw_wx_get_scan(struct libipw_device *ieee,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
 {
-	struct ieee80211_network *network;
+	struct libipw_network *network;
 	unsigned long flags;
 	int err = 0;
 
@@ -272,7 +272,7 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
 	int i = 0;
 	DECLARE_SSID_BUF(ssid);
 
-	IEEE80211_DEBUG_WX("Getting scan\n");
+	LIBIPW_DEBUG_WX("Getting scan\n");
 
 	spin_lock_irqsave(&ieee->lock, flags);
 
@@ -285,10 +285,10 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
 
 		if (ieee->scan_age == 0 ||
 		    time_after(network->last_scanned + ieee->scan_age, jiffies))
-			ev = ieee80211_translate_scan(ieee, ev, stop, network,
+			ev = libipw_translate_scan(ieee, ev, stop, network,
 						      info);
 		else {
-			IEEE80211_DEBUG_SCAN("Not showing network '%s ("
+			LIBIPW_DEBUG_SCAN("Not showing network '%s ("
 					     "%pM)' due to age (%ums).\n",
 					     print_ssid(ssid, network->ssid,
 							 network->ssid_len),
@@ -303,18 +303,18 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
 	wrqu->data.length = ev - extra;
 	wrqu->data.flags = 0;
 
-	IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
+	LIBIPW_DEBUG_WX("exit: %d networks returned.\n", i);
 
 	return err;
 }
 
-int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+int libipw_wx_set_encode(struct libipw_device *ieee,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *keybuf)
 {
 	struct iw_point *erq = &(wrqu->encoding);
 	struct net_device *dev = ieee->dev;
-	struct ieee80211_security sec = {
+	struct libipw_security sec = {
 		.flags = 0
 	};
 	int i, key, key_provided, len;
@@ -322,7 +322,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 	int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
 	DECLARE_SSID_BUF(ssid);
 
-	IEEE80211_DEBUG_WX("SET_ENCODE\n");
+	LIBIPW_DEBUG_WX("SET_ENCODE\n");
 
 	key = erq->flags & IW_ENCODE_INDEX;
 	if (key) {
@@ -335,18 +335,18 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 		key = ieee->crypt_info.tx_keyidx;
 	}
 
-	IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
+	LIBIPW_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
 			   "provided" : "default");
 
 	crypt = &ieee->crypt_info.crypt[key];
 
 	if (erq->flags & IW_ENCODE_DISABLED) {
 		if (key_provided && *crypt) {
-			IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
+			LIBIPW_DEBUG_WX("Disabling encryption on key %d.\n",
 					   key);
 			lib80211_crypt_delayed_deinit(&ieee->crypt_info, crypt);
 		} else
-			IEEE80211_DEBUG_WX("Disabling encryption.\n");
+			LIBIPW_DEBUG_WX("Disabling encryption.\n");
 
 		/* Check all the keys to see if any are still configured,
 		 * and if no key index was provided, de-init them all */
@@ -410,7 +410,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 
 	/* If a new key was provided, set it up */
 	if (erq->length > 0) {
-#ifdef CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_LIBIPW_DEBUG
 		DECLARE_SSID_BUF(ssid);
 #endif
 
@@ -419,7 +419,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 		if (len > erq->length)
 			memset(sec.keys[key] + erq->length, 0,
 			       len - erq->length);
-		IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
+		LIBIPW_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
 				   key, print_ssid(ssid, sec.keys[key], len),
 				   erq->length, len);
 		sec.key_sizes[key] = len;
@@ -438,7 +438,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 						     NULL, (*crypt)->priv);
 			if (len == 0) {
 				/* Set a default key of all 0 */
-				IEEE80211_DEBUG_WX("Setting key %d to all "
+				LIBIPW_DEBUG_WX("Setting key %d to all "
 						   "zero.\n", key);
 				memset(sec.keys[key], 0, 13);
 				(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
@@ -449,7 +449,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 		}
 		/* No key data - just set the default TX key index */
 		if (key_provided) {
-			IEEE80211_DEBUG_WX("Setting key %d to default Tx "
+			LIBIPW_DEBUG_WX("Setting key %d to default Tx "
 					   "key.\n", key);
 			ieee->crypt_info.tx_keyidx = key;
 			sec.active_key = key;
@@ -461,7 +461,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 		sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN :
 		    WLAN_AUTH_SHARED_KEY;
 		sec.flags |= SEC_AUTH_MODE;
-		IEEE80211_DEBUG_WX("Auth: %s\n",
+		LIBIPW_DEBUG_WX("Auth: %s\n",
 				   sec.auth_mode == WLAN_AUTH_OPEN ?
 				   "OPEN" : "SHARED KEY");
 	}
@@ -490,16 +490,16 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 	return 0;
 }
 
-int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+int libipw_wx_get_encode(struct libipw_device *ieee,
 			    struct iw_request_info *info,
 			    union iwreq_data *wrqu, char *keybuf)
 {
 	struct iw_point *erq = &(wrqu->encoding);
 	int len, key;
 	struct lib80211_crypt_data *crypt;
-	struct ieee80211_security *sec = &ieee->sec;
+	struct libipw_security *sec = &ieee->sec;
 
-	IEEE80211_DEBUG_WX("GET_ENCODE\n");
+	LIBIPW_DEBUG_WX("GET_ENCODE\n");
 
 	key = erq->flags & IW_ENCODE_INDEX;
 	if (key) {
@@ -532,7 +532,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
 	return 0;
 }
 
-int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
+int libipw_wx_set_encodeext(struct libipw_device *ieee,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
@@ -545,7 +545,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 	struct lib80211_crypto_ops *ops;
 	struct lib80211_crypt_data **crypt;
 
-	struct ieee80211_security sec = {
+	struct libipw_security sec = {
 		.flags = 0,
 	};
 
@@ -611,7 +611,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 		module = "lib80211_crypt_ccmp";
 		break;
 	default:
-		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+		LIBIPW_DEBUG_WX("%s: unknown crypto alg %d\n",
 				   dev->name, ext->alg);
 		ret = -EINVAL;
 		goto done;
@@ -623,7 +623,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 		ops = lib80211_get_crypto_ops(alg);
 	}
 	if (ops == NULL) {
-		IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+		LIBIPW_DEBUG_WX("%s: unknown crypto alg %d\n",
 				   dev->name, ext->alg);
 		ret = -EINVAL;
 		goto done;
@@ -653,7 +653,7 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 	if (ext->key_len > 0 && (*crypt)->ops->set_key &&
 	    (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
 				   (*crypt)->priv) < 0) {
-		IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
+		LIBIPW_DEBUG_WX("%s: key setting failed\n", dev->name);
 		ret = -EINVAL;
 		goto done;
 	}
@@ -700,20 +700,20 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
 	if (ieee->reset_on_keychange &&
 	    ieee->iw_mode != IW_MODE_INFRA &&
 	    ieee->reset_port && ieee->reset_port(dev)) {
-		IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
+		LIBIPW_DEBUG_WX("%s: reset_port failed\n", dev->name);
 		return -EINVAL;
 	}
 
 	return ret;
 }
 
-int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
+int libipw_wx_get_encodeext(struct libipw_device *ieee,
 			       struct iw_request_info *info,
 			       union iwreq_data *wrqu, char *extra)
 {
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	struct ieee80211_security *sec = &ieee->sec;
+	struct libipw_security *sec = &ieee->sec;
 	int idx, max_key_len;
 
 	max_key_len = encoding->length - sizeof(*ext);
@@ -763,9 +763,9 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
 	return 0;
 }
 
-EXPORT_SYMBOL(ieee80211_wx_set_encodeext);
-EXPORT_SYMBOL(ieee80211_wx_get_encodeext);
+EXPORT_SYMBOL(libipw_wx_set_encodeext);
+EXPORT_SYMBOL(libipw_wx_get_encodeext);
 
-EXPORT_SYMBOL(ieee80211_wx_get_scan);
-EXPORT_SYMBOL(ieee80211_wx_set_encode);
-EXPORT_SYMBOL(ieee80211_wx_get_encode);
+EXPORT_SYMBOL(libipw_wx_get_scan);
+EXPORT_SYMBOL(libipw_wx_set_encode);
+EXPORT_SYMBOL(libipw_wx_get_encode);
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index e092af0..99310c0 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -9,6 +9,9 @@ config IWLWIFI
 config IWLWIFI_LEDS
 	bool "Enable LED support in iwlagn and iwl3945 drivers"
 	depends on IWLWIFI
+	default y
+	---help---
+	  Select this if you want LED support.
 
 config IWLWIFI_SPECTRUM_MEASUREMENT
 	bool "Enable Spectrum Measurement in iwlagn driver"
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 7da52f1..a95caa0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -46,7 +46,7 @@
 #include "iwl-5000-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL1000_UCODE_API_MAX 2
+#define IWL1000_UCODE_API_MAX 3
 
 /* Lowest firmware API version supported */
 #define IWL1000_UCODE_API_MIN 1
@@ -55,19 +55,109 @@
 #define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
 #define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
 
+
+/*
+ * For 1000, use advance thermal throttling critical temperature threshold,
+ * but legacy thermal management implementation for now.
+ * This is for the reason of 1000 uCode using advance thermal throttling API
+ * but not implement ct_kill_exit based on ct_kill exit temperature
+ * so the thermal throttling will still based on legacy thermal throttling
+ * management.
+ * The code here need to be modified once 1000 uCode has the advanced thermal
+ * throttling algorithm in place
+ */
+static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
+{
+	/* want Celsius */
+	priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
+	priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
+}
+
+/* NIC configuration for 1000 series */
+static void iwl1000_nic_config(struct iwl_priv *priv)
+{
+	iwl5000_nic_config(priv);
+
+	/* Setting digital SVR for 1000 card to 1.32V */
+	/* locking is acquired in iwl_set_bits_mask_prph() function */
+	iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
+				APMG_SVR_DIGITAL_VOLTAGE_1_32,
+				~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
+}
+
+static struct iwl_lib_ops iwl1000_lib = {
+	.set_hw_params = iwl5000_hw_set_hw_params,
+	.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
+	.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
+	.txq_set_sched = iwl5000_txq_set_sched,
+	.txq_agg_enable = iwl5000_txq_agg_enable,
+	.txq_agg_disable = iwl5000_txq_agg_disable,
+	.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+	.txq_free_tfd = iwl_hw_txq_free_tfd,
+	.txq_init = iwl_hw_tx_queue_init,
+	.rx_handler_setup = iwl5000_rx_handler_setup,
+	.setup_deferred_work = iwl5000_setup_deferred_work,
+	.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
+	.load_ucode = iwl5000_load_ucode,
+	.init_alive_start = iwl5000_init_alive_start,
+	.alive_notify = iwl5000_alive_notify,
+	.send_tx_power = iwl5000_send_tx_power,
+	.update_chain_flags = iwl_update_chain_flags,
+	.apm_ops = {
+		.init =	iwl5000_apm_init,
+		.reset = iwl5000_apm_reset,
+		.stop = iwl5000_apm_stop,
+		.config = iwl1000_nic_config,
+		.set_pwr_src = iwl_set_pwr_src,
+	},
+	.eeprom_ops = {
+		.regulatory_bands = {
+			EEPROM_5000_REG_BAND_1_CHANNELS,
+			EEPROM_5000_REG_BAND_2_CHANNELS,
+			EEPROM_5000_REG_BAND_3_CHANNELS,
+			EEPROM_5000_REG_BAND_4_CHANNELS,
+			EEPROM_5000_REG_BAND_5_CHANNELS,
+			EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+			EEPROM_5000_REG_BAND_52_HT40_CHANNELS
+		},
+		.verify_signature  = iwlcore_eeprom_verify_signature,
+		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+		.release_semaphore = iwlcore_eeprom_release_semaphore,
+		.calib_version	= iwl5000_eeprom_calib_version,
+		.query_addr = iwl5000_eeprom_query_addr,
+	},
+	.post_associate = iwl_post_associate,
+	.isr = iwl_isr_ict,
+	.config_ap = iwl_config_ap,
+	.temp_ops = {
+		.temperature = iwl5000_temperature,
+		.set_ct_kill = iwl1000_set_ct_threshold,
+	 },
+};
+
+static struct iwl_ops iwl1000_ops = {
+	.ucode = &iwl5000_ucode,
+	.lib = &iwl1000_lib,
+	.hcmd = &iwl5000_hcmd,
+	.utils = &iwl5000_hcmd_utils,
+};
+
 struct iwl_cfg iwl1000_bgn_cfg = {
 	.name = "1000 Series BGN",
 	.fw_name_pre = IWL1000_FW_PRE,
 	.ucode_api_max = IWL1000_UCODE_API_MAX,
 	.ucode_api_min = IWL1000_UCODE_API_MIN,
 	.sku = IWL_SKU_G|IWL_SKU_N,
-	.ops = &iwl5000_ops,
-	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.ops = &iwl1000_ops,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
 	.need_pll_cfg = true,
+	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
+	.shadow_ram_support = false,
+	.ht_greenfield_support = true,
 };
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 73f93a0..1677278 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -176,7 +176,7 @@ struct iwl3945_eeprom {
  * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
  * txpower (MSB).
  *
- * Entries immediately below are for 20 MHz channel width.  FAT (40 MHz)
+ * Entries immediately below are for 20 MHz channel width.  HT40 (40 MHz)
  * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
  *
  * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
@@ -232,9 +232,8 @@ struct iwl3945_eeprom {
 #define PCI_CFG_REV_ID_BIT_BASIC_SKU                (0x40)	/* bit 6    */
 #define PCI_CFG_REV_ID_BIT_RTP                      (0x80)	/* bit 7    */
 
-#define TFD_QUEUE_MIN           0
-#define TFD_QUEUE_MAX           5	/* 4 DATA + 1 CMD */
-
+/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */
+#define IWL39_NUM_QUEUES        5
 #define IWL_NUM_SCAN_RATES         (2)
 
 #define IWL_DEFAULT_TX_RETRY  15
@@ -280,8 +279,6 @@ struct iwl3945_eeprom {
 /* Size of uCode instruction memory in bootstrap state machine */
 #define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE
 
-#define IWL39_MAX_NUM_QUEUES	8
-
 static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr)
 {
 	return (addr >= IWL39_RTC_DATA_LOWER_BOUND) &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 225e5f8..8c29ded 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -79,11 +79,10 @@ static const struct {
 #define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
 #define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
 
-static int iwl3945_led_cmd_callback(struct iwl_priv *priv,
-				    struct iwl_cmd *cmd,
-				    struct sk_buff *skb)
+static void iwl3945_led_cmd_callback(struct iwl_priv *priv,
+				     struct iwl_device_cmd *cmd,
+				     struct sk_buff *skb)
 {
-	return 1;
 }
 
 static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
@@ -99,8 +98,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv,
 		.id = REPLY_LEDS_CMD,
 		.len = sizeof(struct iwl_led_cmd),
 		.data = led_cmd,
-		.meta.flags = CMD_ASYNC,
-		.meta.u.callback = iwl3945_led_cmd_callback,
+		.flags = CMD_ASYNC,
+		.callback = iwl3945_led_cmd_callback,
 	};
 
 	return iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 5eb538d..a16bd41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -673,33 +673,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
 	s8 scale_action = 0;
 	unsigned long flags;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	u16 fc;
-	u16 rate_mask = 0;
+	u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
 	s8 max_rate_idx = -1;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
 	IWL_DEBUG_RATE(priv, "enter\n");
 
-	if (sta)
-		rate_mask = sta->supp_rates[sband->band];
-
-	/* Send management frames and NO_ACK data using lowest rate. */
-	fc = le16_to_cpu(hdr->frame_control);
-	if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-	    info->flags & IEEE80211_TX_CTL_NO_ACK ||
-	    !sta || !priv_sta) {
-		IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
-		if (!rate_mask)
-			info->control.rates[0].idx =
-					rate_lowest_index(sband, NULL);
-		else
-			info->control.rates[0].idx =
-					rate_lowest_index(sband, sta);
-		if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-			info->control.rates[0].count = 1;
+	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
-	}
+
+	rate_mask = sta->supp_rates[sband->band];
 
 	/* get user max rate if set */
 	max_rate_idx = txrc->max_rate_idx;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 46288e7..e9a685d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -349,12 +349,13 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
  *
  *****************************************************************************/
 
-void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
+		struct iwl_rx_mem_buffer *rxb)
 {
 	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
 		     (int)sizeof(struct iwl3945_notif_statistics),
-		     le32_to_cpu(pkt->len));
+		     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
 
 	memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
 
@@ -509,7 +510,7 @@ static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
 		      struct iwl_rx_packet *pkt,
 		      struct ieee80211_hdr *header, int group100)
 {
-	if (priv->debug_level & IWL_DL_RX)
+	if (iwl_get_debug_level(priv) & IWL_DL_RX)
 		_iwl3945_dbg_report_frame(priv, pkt, header, group100);
 }
 
@@ -544,9 +545,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
 				   struct ieee80211_rx_status *stats)
 {
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-#ifdef CONFIG_IWLWIFI_LEDS
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
-#endif
 	struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
 	struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
 	short len = le16_to_cpu(rx_hdr->len);
@@ -577,7 +576,10 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
 	if (ieee80211_is_data(hdr->frame_control))
 		priv->rxtxpackets += len;
 #endif
-	ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
+	iwl_update_stats(priv, false, hdr->frame_control, len);
+
+	memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
+	ieee80211_rx_irqsafe(priv->hw, rxb->skb);
 	rxb->skb = NULL;
 }
 
@@ -678,6 +680,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
 
 	/* Set "1" to report good data frames in groups of 100 */
 	iwl3945_dbg_report_frame(priv, pkt, header, 1);
+	iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header);
 
 	if (network_packet) {
 		priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
@@ -748,8 +751,8 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 	/* Unmap tx_cmd */
 	if (counter)
 		pci_unmap_single(dev,
-				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
-				pci_unmap_len(&txq->cmd[index]->meta, len),
+				pci_unmap_addr(&txq->meta[index], mapping),
+				pci_unmap_len(&txq->meta[index], len),
 				PCI_DMA_TODEVICE);
 
 	/* unmap chunks if any */
@@ -773,9 +776,11 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
  * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
  *
 */
-void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
-			      struct ieee80211_tx_info *info,
-			      struct ieee80211_hdr *hdr, int sta_id, int tx_id)
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
+				  struct iwl_device_cmd *cmd,
+				  struct ieee80211_tx_info *info,
+				  struct ieee80211_hdr *hdr,
+				  int sta_id, int tx_id)
 {
 	u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
 	u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
@@ -962,7 +967,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
 		goto error;
 
 	/* Tx queue(s) */
-	for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
+	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
 		slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
 				TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
 		rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
@@ -1139,7 +1144,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
 	int txq_id;
 
 	/* Tx queues */
-	for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++)
+	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
 		if (txq_id == IWL_CMD_QUEUE_NUM)
 			iwl_cmd_queue_free(priv);
 		else
@@ -1155,7 +1160,7 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
 	iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
 
 	/* reset TFD queues */
-	for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) {
+	for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
 		iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
 		iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
 				FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
@@ -1857,7 +1862,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_RXON_ASSOC,
 		.len = sizeof(rxon_assoc),
-		.meta.flags = CMD_WANT_SKB,
+		.flags = CMD_WANT_SKB,
 		.data = &rxon_assoc,
 	};
 	const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
@@ -1881,14 +1886,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
 	if (rc)
 		return rc;
 
-	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
 		rc = -EIO;
 	}
 
 	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.meta.u.skb);
+	dev_kfree_skb_any(cmd.reply_skb);
 
 	return rc;
 }
@@ -1986,7 +1991,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
 	staging_rxon->reserved4 = 0;
 	staging_rxon->reserved5 = 0;
 
-	iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+	iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto);
 
 	/* Apply the new configuration */
 	rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -2551,7 +2556,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
 	}
 
 	/* Assign number of Usable TX queues */
-	priv->hw_params.max_txq_num = TFD_QUEUE_MAX;
+	priv->hw_params.max_txq_num = IWL39_NUM_QUEUES;
 
 	priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
 	priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
@@ -2562,6 +2567,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
 	priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
 
 	priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
+	priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
 
 	return 0;
 }
@@ -2784,11 +2790,50 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
 	return 0;
 }
 
+#define IWL3945_UCODE_GET(item)						\
+static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
+				    u32 api_ver)			\
+{									\
+	return le32_to_cpu(ucode->u.v1.item);				\
+}
+
+static u32 iwl3945_ucode_get_header_size(u32 api_ver)
+{
+	return UCODE_HEADER_SIZE(1);
+}
+static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
+				   u32 api_ver)
+{
+	return 0;
+}
+static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
+				  u32 api_ver)
+{
+	return (u8 *) ucode->u.v1.data;
+}
+
+IWL3945_UCODE_GET(inst_size);
+IWL3945_UCODE_GET(data_size);
+IWL3945_UCODE_GET(init_size);
+IWL3945_UCODE_GET(init_data_size);
+IWL3945_UCODE_GET(boot_size);
+
 static struct iwl_hcmd_ops iwl3945_hcmd = {
 	.rxon_assoc = iwl3945_send_rxon_assoc,
 	.commit_rxon = iwl3945_commit_rxon,
 };
 
+static struct iwl_ucode_ops iwl3945_ucode = {
+	.get_header_size = iwl3945_ucode_get_header_size,
+	.get_build = iwl3945_ucode_get_build,
+	.get_inst_size = iwl3945_ucode_get_inst_size,
+	.get_data_size = iwl3945_ucode_get_data_size,
+	.get_init_size = iwl3945_ucode_get_init_size,
+	.get_init_data_size = iwl3945_ucode_get_init_data_size,
+	.get_boot_size = iwl3945_ucode_get_boot_size,
+	.get_data = iwl3945_ucode_get_data,
+};
+
 static struct iwl_lib_ops iwl3945_lib = {
 	.txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
 	.txq_free_tfd = iwl3945_hw_txq_free_tfd,
@@ -2808,8 +2853,8 @@ static struct iwl_lib_ops iwl3945_lib = {
 			EEPROM_REGULATORY_BAND_3_CHANNELS,
 			EEPROM_REGULATORY_BAND_4_CHANNELS,
 			EEPROM_REGULATORY_BAND_5_CHANNELS,
-			EEPROM_REGULATORY_BAND_NO_FAT,
-			EEPROM_REGULATORY_BAND_NO_FAT,
+			EEPROM_REGULATORY_BAND_NO_HT40,
+			EEPROM_REGULATORY_BAND_NO_HT40,
 		},
 		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
@@ -2829,6 +2874,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
 };
 
 static struct iwl_ops iwl3945_ops = {
+	.ucode = &iwl3945_ucode,
 	.lib = &iwl3945_lib,
 	.hcmd = &iwl3945_hcmd,
 	.utils = &iwl3945_hcmd_utils,
@@ -2844,7 +2890,8 @@ static struct iwl_cfg iwl3945_bg_cfg = {
 	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
 	.ops = &iwl3945_ops,
 	.mod_params = &iwl3945_mod_params,
-	.use_isr_legacy = true
+	.use_isr_legacy = true,
+	.ht_greenfield_support = false,
 };
 
 static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2857,7 +2904,8 @@ static struct iwl_cfg iwl3945_abg_cfg = {
 	.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
 	.ops = &iwl3945_ops,
 	.mod_params = &iwl3945_mod_params,
-	.use_isr_legacy = true
+	.use_isr_legacy = true,
+	.ht_greenfield_support = false,
 };
 
 struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 2de6471..f240369 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -111,9 +111,6 @@ enum iwl3945_antenna {
 #define IWL_TX_FIFO_HCCA_2	6
 #define IWL_TX_FIFO_NONE	7
 
-/* Minimum number of queues. MAX_NUM is defined in hw specific files */
-#define IWL39_MIN_NUM_QUEUES	4
-
 #define IEEE80211_DATA_LEN              2304
 #define IEEE80211_4ADDR_LEN             30
 #define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
@@ -257,10 +254,11 @@ extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
 				struct iwl_tx_queue *txq);
 extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
 				 struct iwl3945_frame *frame, u8 rate);
-void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
-				     struct ieee80211_tx_info *info,
-				     struct ieee80211_hdr *hdr,
-				     int sta_id, int tx_id);
+void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
+				  struct iwl_device_cmd *cmd,
+				  struct ieee80211_tx_info *info,
+				  struct ieee80211_hdr *hdr,
+				  int sta_id, int tx_id);
 extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
 extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
 extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index a71a489..b34322a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -188,7 +188,7 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
  *
  * 1)  Regulatory information (max txpower and channel usage flags) is provided
  *     separately for each channel that can possibly supported by 4965.
- *     40 MHz wide (.11n fat) channels are listed separately from 20 MHz
+ *     40 MHz wide (.11n HT40) channels are listed separately from 20 MHz
  *     (legacy) channels.
  *
  *     See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom
@@ -251,8 +251,8 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
  *     no reduction (such as with regulatory txpower limits) is required.
  *
  *     Saturation and Backoff values apply equally to 20 Mhz (legacy) channel
- *     widths and 40 Mhz (.11n fat) channel widths; there is no separate
- *     factory measurement for fat channels.
+ *     widths and 40 Mhz (.11n HT40) channel widths; there is no separate
+ *     factory measurement for ht40 channels.
  *
  *     The result of this step is the final target txpower.  The rest of
  *     the steps figure out the proper settings for the device to achieve
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 8f3d4bc..ca61d37 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -46,7 +46,7 @@
 #include "iwl-sta.h"
 
 static int iwl4965_send_tx_power(struct iwl_priv *priv);
-static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
+static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
 
 /* Highest firmware API version supported */
 #define IWL4965_UCODE_API_MAX 2
@@ -293,7 +293,7 @@ restart:
 	queue_work(priv->workqueue, &priv->restart);
 }
 
-static bool is_fat_channel(__le32 rxon_flags)
+static bool is_ht40_channel(__le32 rxon_flags)
 {
 	int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK)
 				    >> RXON_FLG_CHANNEL_MODE_POS;
@@ -728,7 +728,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
 
 static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
 	.min_nrg_cck = 97,
-	.max_nrg_cck = 0,
+	.max_nrg_cck = 0, /* not used, set to 0 */
 
 	.auto_corr_min_ofdm = 85,
 	.auto_corr_min_ofdm_mrc = 170,
@@ -752,7 +752,8 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
 static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
 {
 	/* want Kelvin */
-	priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
+	priv->hw_params.ct_kill_threshold =
+		CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
 }
 
 /**
@@ -781,7 +782,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
 	priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
 	priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
-	priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ);
+	priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
 
 	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
 
@@ -1241,7 +1242,7 @@ static const struct gain_entry gain_table[2][108] = {
 };
 
 static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
-				    u8 is_fat, u8 ctrl_chan_high,
+				    u8 is_ht40, u8 ctrl_chan_high,
 				    struct iwl4965_tx_power_db *tx_power_tbl)
 {
 	u8 saturation_power;
@@ -1273,8 +1274,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
 	user_target_power = 2 * priv->tx_power_user_lmt;
 
 	/* Get current (RXON) channel, band, width */
-	IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_fat %d\n", channel, band,
-			  is_fat);
+	IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_ht40 %d\n", channel, band,
+			  is_ht40);
 
 	ch_info = iwl_get_channel_info(priv, priv->band, channel);
 
@@ -1293,7 +1294,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
 	IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
 			  channel, txatten_grp);
 
-	if (is_fat) {
+	if (is_ht40) {
 		if (ctrl_chan_high)
 			channel -= 2;
 		else
@@ -1317,8 +1318,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
 
 	/* regulatory txpower limits ... reg_limit values are in half-dBm,
 	 *   max_power_avg values are in dBm, convert * 2 */
-	if (is_fat)
-		reg_limit = ch_info->fat_max_power_avg * 2;
+	if (is_ht40)
+		reg_limit = ch_info->ht40_max_power_avg * 2;
 	else
 		reg_limit = ch_info->max_power_avg * 2;
 
@@ -1484,7 +1485,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
 /**
  * iwl4965_send_tx_power - Configure the TXPOWER level user limit
  *
- * Uses the active RXON for channel, band, and characteristics (fat, high)
+ * Uses the active RXON for channel, band, and characteristics (ht40, high)
  * The power limit is taken from priv->tx_power_user_lmt.
  */
 static int iwl4965_send_tx_power(struct iwl_priv *priv)
@@ -1492,7 +1493,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
 	struct iwl4965_txpowertable_cmd cmd = { 0 };
 	int ret;
 	u8 band = 0;
-	bool is_fat = false;
+	bool is_ht40 = false;
 	u8 ctrl_chan_high = 0;
 
 	if (test_bit(STATUS_SCANNING, &priv->status)) {
@@ -1505,9 +1506,9 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
 
 	band = priv->band == IEEE80211_BAND_2GHZ;
 
-	is_fat =  is_fat_channel(priv->active_rxon.flags);
+	is_ht40 =  is_ht40_channel(priv->active_rxon.flags);
 
-	if (is_fat &&
+	if (is_ht40 &&
 	    (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
 		ctrl_chan_high = 1;
 
@@ -1516,7 +1517,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
 
 	ret = iwl4965_fill_txpower_tbl(priv, band,
 				le16_to_cpu(priv->active_rxon.channel),
-				is_fat, ctrl_chan_high, &cmd.tx_power);
+				is_ht40, ctrl_chan_high, &cmd.tx_power);
 	if (ret)
 		goto out;
 
@@ -1570,7 +1571,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 {
 	int rc;
 	u8 band = 0;
-	bool is_fat = false;
+	bool is_ht40 = false;
 	u8 ctrl_chan_high = 0;
 	struct iwl4965_channel_switch_cmd cmd = { 0 };
 	const struct iwl_channel_info *ch_info;
@@ -1579,9 +1580,9 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 
 	ch_info = iwl_get_channel_info(priv, priv->band, channel);
 
-	is_fat = is_fat_channel(priv->staging_rxon.flags);
+	is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
 
-	if (is_fat &&
+	if (is_ht40 &&
 	    (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
 		ctrl_chan_high = 1;
 
@@ -1596,7 +1597,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 	else
 		cmd.expect_beacon = 1;
 
-	rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_fat,
+	rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40,
 				      ctrl_chan_high, &cmd.tx_power);
 	if (rc) {
 		IWL_DEBUG_11H(priv, "error:%d  fill txpower_tbl\n", rc);
@@ -1655,7 +1656,7 @@ static s32 sign_extend(u32 oper, int index)
  *
  * A return of <0 indicates bogus data in the statistics
  */
-static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
+static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
 {
 	s32 temperature;
 	s32 vt;
@@ -1663,8 +1664,8 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
 	u32 R4;
 
 	if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
-		(priv->statistics.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)) {
-		IWL_DEBUG_TEMP(priv, "Running FAT temperature calibration\n");
+		(priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) {
+		IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n");
 		R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
 		R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
 		R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
@@ -1772,6 +1773,7 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv)
 	}
 
 	priv->temperature = temp;
+	iwl_tt_handler(priv);
 	set_bit(STATUS_TEMPERATURE, &priv->status);
 
 	if (!priv->disable_tx_power_cal &&
@@ -2221,12 +2223,50 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
 	cancel_work_sync(&priv->txpower_work);
 }
 
+#define IWL4965_UCODE_GET(item)						\
+static u32 iwl4965_ucode_get_##item(const struct iwl_ucode_header *ucode,\
+				    u32 api_ver)			\
+{									\
+	return le32_to_cpu(ucode->u.v1.item);				\
+}
+
+static u32 iwl4965_ucode_get_header_size(u32 api_ver)
+{
+	return UCODE_HEADER_SIZE(1);
+}
+static u32 iwl4965_ucode_get_build(const struct iwl_ucode_header *ucode,
+				   u32 api_ver)
+{
+	return 0;
+}
+static u8 *iwl4965_ucode_get_data(const struct iwl_ucode_header *ucode,
+				  u32 api_ver)
+{
+	return (u8 *) ucode->u.v1.data;
+}
+
+IWL4965_UCODE_GET(inst_size);
+IWL4965_UCODE_GET(data_size);
+IWL4965_UCODE_GET(init_size);
+IWL4965_UCODE_GET(init_data_size);
+IWL4965_UCODE_GET(boot_size);
+
 static struct iwl_hcmd_ops iwl4965_hcmd = {
 	.rxon_assoc = iwl4965_send_rxon_assoc,
 	.commit_rxon = iwl_commit_rxon,
 	.set_rxon_chain = iwl_set_rxon_chain,
 };
 
+static struct iwl_ucode_ops iwl4965_ucode = {
+	.get_header_size = iwl4965_ucode_get_header_size,
+	.get_build = iwl4965_ucode_get_build,
+	.get_inst_size = iwl4965_ucode_get_inst_size,
+	.get_data_size = iwl4965_ucode_get_data_size,
+	.get_init_size = iwl4965_ucode_get_init_size,
+	.get_init_data_size = iwl4965_ucode_get_init_data_size,
+	.get_boot_size = iwl4965_ucode_get_boot_size,
+	.get_data = iwl4965_ucode_get_data,
+};
 static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
 	.get_hcmd_size = iwl4965_get_hcmd_size,
 	.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2266,8 +2306,8 @@ static struct iwl_lib_ops iwl4965_lib = {
 			EEPROM_REGULATORY_BAND_3_CHANNELS,
 			EEPROM_REGULATORY_BAND_4_CHANNELS,
 			EEPROM_REGULATORY_BAND_5_CHANNELS,
-			EEPROM_4965_REGULATORY_BAND_24_FAT_CHANNELS,
-			EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS
+			EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
+			EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
 		},
 		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
@@ -2287,6 +2327,7 @@ static struct iwl_lib_ops iwl4965_lib = {
 };
 
 static struct iwl_ops iwl4965_ops = {
+	.ucode = &iwl4965_ucode,
 	.lib = &iwl4965_lib,
 	.hcmd = &iwl4965_hcmd,
 	.utils = &iwl4965_hcmd_utils,
@@ -2303,7 +2344,9 @@ struct iwl_cfg iwl4965_agn_cfg = {
 	.eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
 	.ops = &iwl4965_ops,
 	.mod_params = &iwl4965_mod_params,
-	.use_isr_legacy = true
+	.use_isr_legacy = true,
+	.ht_greenfield_support = false,
+	.broken_powersave = true,
 };
 
 /* Module firmware */
@@ -2313,8 +2356,6 @@ module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
 module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(debug, iwl4965_mod_params.debug, uint, 0444);
-MODULE_PARM_DESC(debug, "debug output mask");
 module_param_named(
 	disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index b3c648c..1d539e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -91,7 +91,7 @@ static int iwl5000_apm_stop_master(struct iwl_priv *priv)
 }
 
 
-static int iwl5000_apm_init(struct iwl_priv *priv)
+int iwl5000_apm_init(struct iwl_priv *priv)
 {
 	int ret = 0;
 
@@ -137,7 +137,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
 }
 
 /* FIXME: this is identical to 4965 */
-static void iwl5000_apm_stop(struct iwl_priv *priv)
+void iwl5000_apm_stop(struct iwl_priv *priv)
 {
 	unsigned long flags;
 
@@ -156,7 +156,7 @@ static void iwl5000_apm_stop(struct iwl_priv *priv)
 }
 
 
-static int iwl5000_apm_reset(struct iwl_priv *priv)
+int iwl5000_apm_reset(struct iwl_priv *priv)
 {
 	int ret = 0;
 
@@ -198,7 +198,8 @@ out:
 }
 
 
-static void iwl5000_nic_config(struct iwl_priv *priv)
+/* NIC configuration for 5000 series and up */
+void iwl5000_nic_config(struct iwl_priv *priv)
 {
 	unsigned long flags;
 	u16 radio_cfg;
@@ -239,11 +240,11 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
 				APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
 				~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
 
+
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 
-
 /*
  * EEPROM
  */
@@ -283,7 +284,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
 	return (address & ADDRESS_MSK) + (offset << 1);
 }
 
-static u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv)
+u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv)
 {
 	struct iwl_eeprom_calib_hdr {
 		u8 version;
@@ -388,7 +389,7 @@ void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 
 static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
 	.min_nrg_cck = 95,
-	.max_nrg_cck = 0,
+	.max_nrg_cck = 0, /* not used, set to 0 */
 	.auto_corr_min_ofdm = 90,
 	.auto_corr_min_ofdm_mrc = 170,
 	.auto_corr_min_ofdm_x1 = 120,
@@ -407,7 +408,29 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
 	.nrg_th_ofdm = 95,
 };
 
-static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
+static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
+	.min_nrg_cck = 95,
+	.max_nrg_cck = 0, /* not used, set to 0 */
+	.auto_corr_min_ofdm = 90,
+	.auto_corr_min_ofdm_mrc = 170,
+	.auto_corr_min_ofdm_x1 = 105,
+	.auto_corr_min_ofdm_mrc_x1 = 220,
+
+	.auto_corr_max_ofdm = 120,
+	.auto_corr_max_ofdm_mrc = 210,
+	/* max = min for performance bug in 5150 DSP */
+	.auto_corr_max_ofdm_x1 = 105,
+	.auto_corr_max_ofdm_mrc_x1 = 220,
+
+	.auto_corr_min_cck = 125,
+	.auto_corr_max_cck = 200,
+	.auto_corr_min_cck_mrc = 170,
+	.auto_corr_max_cck_mrc = 400,
+	.nrg_th_cck = 95,
+	.nrg_th_ofdm = 95,
+};
+
+const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
 					   size_t offset)
 {
 	u32 address = eeprom_indirect_address(priv, offset);
@@ -418,7 +441,7 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
 static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
 {
 	const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
-	s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) -
+	s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
 			iwl_temp_calib_to_offset(priv);
 
 	priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
@@ -427,7 +450,7 @@ static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
 static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
 {
 	/* want Celsius */
-	priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
+	priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
 }
 
 /*
@@ -471,7 +494,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
 {
 	struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
 	struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
-	int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
+	int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
 	int index;
 
 	/* reduce the size of the length field itself */
@@ -602,7 +625,7 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
 	return ret;
 }
 
-static int iwl5000_load_ucode(struct iwl_priv *priv)
+int iwl5000_load_ucode(struct iwl_priv *priv)
 {
 	int ret = 0;
 
@@ -629,7 +652,7 @@ static int iwl5000_load_ucode(struct iwl_priv *priv)
 	return ret;
 }
 
-static void iwl5000_init_alive_start(struct iwl_priv *priv)
+void iwl5000_init_alive_start(struct iwl_priv *priv)
 {
 	int ret = 0;
 
@@ -705,7 +728,7 @@ static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
 				sizeof(coex_cmd), &coex_cmd);
 }
 
-static int iwl5000_alive_notify(struct iwl_priv *priv)
+int iwl5000_alive_notify(struct iwl_priv *priv)
 {
 	u32 a;
 	unsigned long flags;
@@ -792,7 +815,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
 	return 0;
 }
 
-static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
+int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 {
 	if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
 	    (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
@@ -822,12 +845,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 	}
 
 	priv->hw_params.max_bsm_size = 0;
-	priv->hw_params.fat_channel =  BIT(IEEE80211_BAND_2GHZ) |
+	priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
 					BIT(IEEE80211_BAND_5GHZ);
 	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
 
-	priv->hw_params.sens = &iwl5000_sensitivity;
-
 	priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
 	priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
 	priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
@@ -836,9 +857,11 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 	if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
 		priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
 
+	/* Set initial sensitivity parameters */
 	/* Set initial calibration set */
 	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
 	case CSR_HW_REV_TYPE_5150:
+		priv->hw_params.sens = &iwl5150_sensitivity;
 		priv->hw_params.calib_init_cfg =
 			BIT(IWL_CALIB_DC)		|
 			BIT(IWL_CALIB_LO)		|
@@ -847,6 +870,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 
 		break;
 	default:
+		priv->hw_params.sens = &iwl5000_sensitivity;
 		priv->hw_params.calib_init_cfg =
 			BIT(IWL_CALIB_XTAL)		|
 			BIT(IWL_CALIB_LO)		|
@@ -862,7 +886,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
 /**
  * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
  */
-static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
 					    struct iwl_tx_queue *txq,
 					    u16 byte_cnt)
 {
@@ -902,7 +926,7 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
 			tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
 
-static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
 					   struct iwl_tx_queue *txq)
 {
 	struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
@@ -957,7 +981,7 @@ static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
 		(1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
 }
 
-static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
+int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
 				  int tx_fifo, int sta_id, int tid, u16 ssn_idx)
 {
 	unsigned long flags;
@@ -1018,7 +1042,7 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
 	return 0;
 }
 
-static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
 				   u16 ssn_idx, u8 tx_fifo)
 {
 	if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
@@ -1061,7 +1085,7 @@ u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
  * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
  * must be called under priv->lock and mac access
  */
-static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
+void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
 {
 	iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
 }
@@ -1282,13 +1306,13 @@ u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
 	return len;
 }
 
-static void iwl5000_setup_deferred_work(struct iwl_priv *priv)
+void iwl5000_setup_deferred_work(struct iwl_priv *priv)
 {
 	/* in 5000 the tx power calibration is done in uCode */
 	priv->disable_tx_power_cal = 1;
 }
 
-static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
+void iwl5000_rx_handler_setup(struct iwl_priv *priv)
 {
 	/* init calibration handlers */
 	priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
@@ -1299,7 +1323,7 @@ static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
 }
 
 
-static int iwl5000_hw_valid_rtc_data_addr(u32 addr)
+int iwl5000_hw_valid_rtc_data_addr(u32 addr)
 {
 	return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
 		(addr < IWL50_RTC_DATA_UPPER_BOUND);
@@ -1351,7 +1375,7 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
 
 	return ret;
 }
-static int  iwl5000_send_tx_power(struct iwl_priv *priv)
+int  iwl5000_send_tx_power(struct iwl_priv *priv)
 {
 	struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
 	u8 tx_ant_cfg_cmd;
@@ -1371,10 +1395,11 @@ static int  iwl5000_send_tx_power(struct iwl_priv *priv)
 				       NULL);
 }
 
-static void iwl5000_temperature(struct iwl_priv *priv)
+void iwl5000_temperature(struct iwl_priv *priv)
 {
 	/* store temperature from statistics (in Celsius) */
 	priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
+	iwl_tt_handler(priv);
 }
 
 static void iwl5150_temperature(struct iwl_priv *priv)
@@ -1386,6 +1411,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
 	vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
 	/* now vt hold the temperature in Kelvin */
 	priv->temperature = KELVIN_TO_CELSIUS(vt);
+	iwl_tt_handler(priv);
 }
 
 /* Calc max signal level (dBm) among 3 possible receivers */
@@ -1426,6 +1452,44 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
 	return max_rssi - agc - IWL49_RSSI_OFFSET;
 }
 
+#define IWL5000_UCODE_GET(item)						\
+static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
+				    u32 api_ver)			\
+{									\
+	if (api_ver <= 2)						\
+		return le32_to_cpu(ucode->u.v1.item);			\
+	return le32_to_cpu(ucode->u.v2.item);				\
+}
+
+static u32 iwl5000_ucode_get_header_size(u32 api_ver)
+{
+	if (api_ver <= 2)
+		return UCODE_HEADER_SIZE(1);
+	return UCODE_HEADER_SIZE(2);
+}
+
+static u32 iwl5000_ucode_get_build(const struct iwl_ucode_header *ucode,
+				   u32 api_ver)
+{
+	if (api_ver <= 2)
+		return 0;
+	return le32_to_cpu(ucode->u.v2.build);
+}
+
+static u8 *iwl5000_ucode_get_data(const struct iwl_ucode_header *ucode,
+				  u32 api_ver)
+{
+	if (api_ver <= 2)
+		return (u8 *) ucode->u.v1.data;
+	return (u8 *) ucode->u.v2.data;
+}
+
+IWL5000_UCODE_GET(inst_size);
+IWL5000_UCODE_GET(data_size);
+IWL5000_UCODE_GET(init_size);
+IWL5000_UCODE_GET(init_data_size);
+IWL5000_UCODE_GET(boot_size);
+
 struct iwl_hcmd_ops iwl5000_hcmd = {
 	.rxon_assoc = iwl5000_send_rxon_assoc,
 	.commit_rxon = iwl_commit_rxon,
@@ -1441,6 +1505,17 @@ struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
 	.calc_rssi = iwl5000_calc_rssi,
 };
 
+struct iwl_ucode_ops iwl5000_ucode = {
+	.get_header_size = iwl5000_ucode_get_header_size,
+	.get_build = iwl5000_ucode_get_build,
+	.get_inst_size = iwl5000_ucode_get_inst_size,
+	.get_data_size = iwl5000_ucode_get_data_size,
+	.get_init_size = iwl5000_ucode_get_init_size,
+	.get_init_data_size = iwl5000_ucode_get_init_data_size,
+	.get_boot_size = iwl5000_ucode_get_boot_size,
+	.get_data = iwl5000_ucode_get_data,
+};
+
 struct iwl_lib_ops iwl5000_lib = {
 	.set_hw_params = iwl5000_hw_set_hw_params,
 	.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -1473,8 +1548,8 @@ struct iwl_lib_ops iwl5000_lib = {
 			EEPROM_5000_REG_BAND_3_CHANNELS,
 			EEPROM_5000_REG_BAND_4_CHANNELS,
 			EEPROM_5000_REG_BAND_5_CHANNELS,
-			EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
-			EEPROM_5000_REG_BAND_52_FAT_CHANNELS
+			EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+			EEPROM_5000_REG_BAND_52_HT40_CHANNELS
 		},
 		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
@@ -1523,8 +1598,8 @@ static struct iwl_lib_ops iwl5150_lib = {
 			EEPROM_5000_REG_BAND_3_CHANNELS,
 			EEPROM_5000_REG_BAND_4_CHANNELS,
 			EEPROM_5000_REG_BAND_5_CHANNELS,
-			EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
-			EEPROM_5000_REG_BAND_52_FAT_CHANNELS
+			EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+			EEPROM_5000_REG_BAND_52_HT40_CHANNELS
 		},
 		.verify_signature  = iwlcore_eeprom_verify_signature,
 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
@@ -1542,12 +1617,14 @@ static struct iwl_lib_ops iwl5150_lib = {
 };
 
 struct iwl_ops iwl5000_ops = {
+	.ucode = &iwl5000_ucode,
 	.lib = &iwl5000_lib,
 	.hcmd = &iwl5000_hcmd,
 	.utils = &iwl5000_hcmd_utils,
 };
 
 static struct iwl_ops iwl5150_ops = {
+	.ucode = &iwl5000_ucode,
 	.lib = &iwl5150_lib,
 	.hcmd = &iwl5000_hcmd,
 	.utils = &iwl5000_hcmd_utils,
@@ -1576,6 +1653,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
 	.need_pll_cfg = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl5100_bg_cfg = {
@@ -1592,6 +1670,7 @@ struct iwl_cfg iwl5100_bg_cfg = {
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
 	.need_pll_cfg = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl5100_abg_cfg = {
@@ -1608,6 +1687,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
 	.need_pll_cfg = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl5100_agn_cfg = {
@@ -1624,6 +1704,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
 	.valid_tx_ant = ANT_B,
 	.valid_rx_ant = ANT_AB,
 	.need_pll_cfg = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl5350_agn_cfg = {
@@ -1640,6 +1721,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
 	.need_pll_cfg = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl5150_agn_cfg = {
@@ -1656,6 +1738,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
 	.valid_tx_ant = ANT_A,
 	.valid_rx_ant = ANT_AB,
 	.need_pll_cfg = true,
+	.ht_greenfield_support = true,
 };
 
 MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
@@ -1664,8 +1747,6 @@ MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
 module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
 MODULE_PARM_DESC(swcrypto50,
 		  "using software crypto engine (default 0 [hardware])\n");
-module_param_named(debug50, iwl50_mod_params.debug, uint, 0444);
-MODULE_PARM_DESC(debug50, "50XX debug output mask");
 module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
 MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
 module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index bd438d8..82b9c93 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -46,8 +46,8 @@
 #include "iwl-5000-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL6000_UCODE_API_MAX 2
-#define IWL6050_UCODE_API_MAX 2
+#define IWL6000_UCODE_API_MAX 4
+#define IWL6050_UCODE_API_MAX 4
 
 /* Lowest firmware API version supported */
 #define IWL6000_UCODE_API_MIN 1
@@ -61,6 +61,82 @@
 #define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
 #define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
 
+static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
+{
+	/* want Celsius */
+	priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
+	priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
+}
+
+/* NIC configuration for 6000 series */
+static void iwl6000_nic_config(struct iwl_priv *priv)
+{
+	iwl5000_nic_config(priv);
+
+	/* no locking required for register write */
+	if (priv->cfg->pa_type == IWL_PA_HYBRID) {
+		/* 2x2 hybrid phy type */
+		iwl_write32(priv, CSR_GP_DRIVER_REG,
+			     CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB);
+	} else if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
+		/* 2x2 IPA phy type */
+		iwl_write32(priv, CSR_GP_DRIVER_REG,
+			     CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
+	}
+	/* else do nothing, uCode configured */
+}
+
+static struct iwl_lib_ops iwl6000_lib = {
+	.set_hw_params = iwl5000_hw_set_hw_params,
+	.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
+	.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
+	.txq_set_sched = iwl5000_txq_set_sched,
+	.txq_agg_enable = iwl5000_txq_agg_enable,
+	.txq_agg_disable = iwl5000_txq_agg_disable,
+	.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+	.txq_free_tfd = iwl_hw_txq_free_tfd,
+	.txq_init = iwl_hw_tx_queue_init,
+	.rx_handler_setup = iwl5000_rx_handler_setup,
+	.setup_deferred_work = iwl5000_setup_deferred_work,
+	.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
+	.load_ucode = iwl5000_load_ucode,
+	.init_alive_start = iwl5000_init_alive_start,
+	.alive_notify = iwl5000_alive_notify,
+	.send_tx_power = iwl5000_send_tx_power,
+	.update_chain_flags = iwl_update_chain_flags,
+	.apm_ops = {
+		.init =	iwl5000_apm_init,
+		.reset = iwl5000_apm_reset,
+		.stop = iwl5000_apm_stop,
+		.config = iwl6000_nic_config,
+		.set_pwr_src = iwl_set_pwr_src,
+	},
+	.eeprom_ops = {
+		.regulatory_bands = {
+			EEPROM_5000_REG_BAND_1_CHANNELS,
+			EEPROM_5000_REG_BAND_2_CHANNELS,
+			EEPROM_5000_REG_BAND_3_CHANNELS,
+			EEPROM_5000_REG_BAND_4_CHANNELS,
+			EEPROM_5000_REG_BAND_5_CHANNELS,
+			EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
+			EEPROM_5000_REG_BAND_52_HT40_CHANNELS
+		},
+		.verify_signature  = iwlcore_eeprom_verify_signature,
+		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+		.release_semaphore = iwlcore_eeprom_release_semaphore,
+		.calib_version	= iwl5000_eeprom_calib_version,
+		.query_addr = iwl5000_eeprom_query_addr,
+		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
+	},
+	.post_associate = iwl_post_associate,
+	.isr = iwl_isr_ict,
+	.config_ap = iwl_config_ap,
+	.temp_ops = {
+		.temperature = iwl5000_temperature,
+		.set_ct_kill = iwl6000_set_ct_threshold,
+	 },
+};
+
 static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
 	.get_hcmd_size = iwl5000_get_hcmd_size,
 	.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
@@ -69,41 +145,57 @@ static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
 };
 
 static struct iwl_ops iwl6000_ops = {
-	.lib = &iwl5000_lib,
+	.ucode = &iwl5000_ucode,
+	.lib = &iwl6000_lib,
 	.hcmd = &iwl5000_hcmd,
 	.utils = &iwl6000_hcmd_utils,
 };
 
-struct iwl_cfg iwl6000_2ag_cfg = {
-	.name = "6000 Series 2x2 AG",
+
+/*
+ * "h": Hybrid configuration, use both internal and external Power Amplifier
+ */
+struct iwl_cfg iwl6000h_2agn_cfg = {
+	.name = "6000 Series 2x2 AGN",
 	.fw_name_pre = IWL6000_FW_PRE,
 	.ucode_api_max = IWL6000_UCODE_API_MAX,
 	.ucode_api_min = IWL6000_UCODE_API_MIN,
-	.sku = IWL_SKU_A|IWL_SKU_G,
+	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl6000_ops,
-	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
-	.valid_tx_ant = ANT_BC,
-	.valid_rx_ant = ANT_BC,
+	.valid_tx_ant = ANT_AB,
+	.valid_rx_ant = ANT_AB,
 	.need_pll_cfg = false,
+	.pa_type = IWL_PA_HYBRID,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.shadow_ram_support = true,
+	.ht_greenfield_support = true,
 };
 
-struct iwl_cfg iwl6000_2agn_cfg = {
+/*
+ * "i": Internal configuration, use internal Power Amplifier
+ */
+struct iwl_cfg iwl6000i_2agn_cfg = {
 	.name = "6000 Series 2x2 AGN",
 	.fw_name_pre = IWL6000_FW_PRE,
 	.ucode_api_max = IWL6000_UCODE_API_MAX,
 	.ucode_api_min = IWL6000_UCODE_API_MIN,
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl6000_ops,
-	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
-	.valid_tx_ant = ANT_AB,
-	.valid_rx_ant = ANT_AB,
+	.valid_tx_ant = ANT_BC,
+	.valid_rx_ant = ANT_BC,
 	.need_pll_cfg = false,
+	.pa_type = IWL_PA_INTERNAL,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.shadow_ram_support = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl6050_2agn_cfg = {
@@ -113,13 +205,17 @@ struct iwl_cfg iwl6050_2agn_cfg = {
 	.ucode_api_min = IWL6050_UCODE_API_MIN,
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl6000_ops,
-	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_AB,
 	.valid_rx_ant = ANT_AB,
 	.need_pll_cfg = false,
+	.pa_type = IWL_PA_SYSTEM,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.shadow_ram_support = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -129,13 +225,17 @@ struct iwl_cfg iwl6000_3agn_cfg = {
 	.ucode_api_min = IWL6000_UCODE_API_MIN,
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl6000_ops,
-	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
 	.need_pll_cfg = false,
+	.pa_type = IWL_PA_SYSTEM,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.shadow_ram_support = true,
+	.ht_greenfield_support = true,
 };
 
 struct iwl_cfg iwl6050_3agn_cfg = {
@@ -145,13 +245,17 @@ struct iwl_cfg iwl6050_3agn_cfg = {
 	.ucode_api_min = IWL6050_UCODE_API_MIN,
 	.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
 	.ops = &iwl6000_ops,
-	.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
+	.eeprom_size = OTP_LOW_IMAGE_SIZE,
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
 	.mod_params = &iwl50_mod_params,
 	.valid_tx_ant = ANT_ABC,
 	.valid_rx_ant = ANT_ABC,
 	.need_pll_cfg = false,
+	.pa_type = IWL_PA_SYSTEM,
+	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
+	.shadow_ram_support = true,
+	.ht_greenfield_support = true,
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index ff20e50..346dc06 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -97,7 +97,7 @@ struct iwl_scale_tbl_info {
 	enum iwl_table_type lq_type;
 	u8 ant_type;
 	u8 is_SGI;	/* 1 = short guard interval */
-	u8 is_fat;	/* 1 = 40 MHz channel width */
+	u8 is_ht40;	/* 1 = 40 MHz channel width */
 	u8 is_dup;	/* 1 = duplicated data streams */
 	u8 action;	/* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
 	u8 max_search;	/* maximun number of tables we can search */
@@ -177,7 +177,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 				   struct sk_buff *skb,
 				   struct ieee80211_sta *sta,
 				   struct iwl_lq_sta *lq_sta);
-static void rs_fill_link_cmd(const struct iwl_priv *priv,
+static void rs_fill_link_cmd(struct iwl_priv *priv,
 			     struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
 
 
@@ -332,6 +332,9 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
 	} else
 		return MAX_TID_COUNT;
 
+	if (unlikely(tid >= TID_MAX_LOAD_COUNT))
+		return MAX_TID_COUNT;
+
 	tl = &lq_data->load[tid];
 
 	curr_time -= curr_time % TID_ROUND_VALUE;
@@ -539,11 +542,11 @@ static u32 rate_n_flags_from_tbl(struct iwl_priv *priv,
 						     RATE_MCS_ANT_ABC_MSK);
 
 	if (is_Ht(tbl->lq_type)) {
-		if (tbl->is_fat) {
+		if (tbl->is_ht40) {
 			if (tbl->is_dup)
 				rate_n_flags |= RATE_MCS_DUP_MSK;
 			else
-				rate_n_flags |= RATE_MCS_FAT_MSK;
+				rate_n_flags |= RATE_MCS_HT40_MSK;
 		}
 		if (tbl->is_SGI)
 			rate_n_flags |= RATE_MCS_SGI_MSK;
@@ -579,7 +582,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
 		return -EINVAL;
 	}
 	tbl->is_SGI = 0;	/* default legacy setup */
-	tbl->is_fat = 0;
+	tbl->is_ht40 = 0;
 	tbl->is_dup = 0;
 	tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
 	tbl->lq_type = LQ_NONE;
@@ -598,9 +601,9 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
 		if (rate_n_flags & RATE_MCS_SGI_MSK)
 			tbl->is_SGI = 1;
 
-		if ((rate_n_flags & RATE_MCS_FAT_MSK) ||
+		if ((rate_n_flags & RATE_MCS_HT40_MSK) ||
 		    (rate_n_flags & RATE_MCS_DUP_MSK))
-			tbl->is_fat = 1;
+			tbl->is_ht40 = 1;
 
 		if (rate_n_flags & RATE_MCS_DUP_MSK)
 			tbl->is_dup = 1;
@@ -654,19 +657,15 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
 	return 1;
 }
 
-/* in 4965 we don't use greenfield at all */
-static inline u8 rs_use_green(struct iwl_priv *priv,
-			      struct ieee80211_conf *conf)
+/**
+ * Green-field mode is valid if the station supports it and
+ * there are no non-GF stations present in the BSS.
+ */
+static inline u8 rs_use_green(struct ieee80211_sta *sta,
+			      struct iwl_ht_info *ht_conf)
 {
-	u8 is_green;
-
-	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
-		is_green = 0;
-	else
-		is_green = (conf_is_ht(conf) &&
-			   priv->current_ht_config.is_green_field &&
-			   !priv->current_ht_config.non_GF_STA_present);
-	return is_green;
+	return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
+		!(ht_conf->non_GF_STA_present);
 }
 
 /**
@@ -761,6 +760,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
 	u16 high_low;
 	u8 switch_to_legacy = 0;
 	u8 is_green = lq_sta->is_green;
+	struct iwl_priv *priv = lq_sta->drv;
 
 	/* check if we need to switch from HT to legacy rates.
 	 * assumption is that mandatory rates (1Mbps or 6Mbps)
@@ -774,9 +774,10 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
 			tbl->lq_type = LQ_G;
 
 		if (num_of_ant(tbl->ant_type) > 1)
-			tbl->ant_type = ANT_A;/*FIXME:RS*/
+			tbl->ant_type =
+				first_antenna(priv->hw_params.valid_tx_ant);
 
-		tbl->is_fat = 0;
+		tbl->is_ht40 = 0;
 		tbl->is_SGI = 0;
 		tbl->max_search = IWL_MAX_SEARCH;
 	}
@@ -819,15 +820,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
 {
 	int status;
 	u8 retries;
-	int rs_index, index = 0;
+	int rs_index, mac_index, index = 0;
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	struct iwl_link_quality_cmd *table;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
-	struct ieee80211_hw *hw = priv->hw;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct iwl_rate_scale_data *window = NULL;
 	struct iwl_rate_scale_data *search_win = NULL;
+	enum mac80211_rate_control_flags mac_flags;
 	u32 tx_rate;
 	struct iwl_scale_tbl_info tbl_type;
 	struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
@@ -877,17 +878,30 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
 	rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
 	if (priv->band == IEEE80211_BAND_5GHZ)
 		rs_index -= IWL_FIRST_OFDM_RATE;
+	mac_flags = info->status.rates[0].flags;
+	mac_index = info->status.rates[0].idx;
+	/* For HT packets, map MCS to PLCP */
+	if (mac_flags & IEEE80211_TX_RC_MCS) {
+		mac_index &= RATE_MCS_CODE_MSK;	/* Remove # of streams */
+		if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
+			mac_index++;
+		/*
+		 * mac80211 HT index is always zero-indexed; we need to move
+		 * HT OFDM rates after CCK rates in 2.4 GHz band
+		 */
+		if (priv->band == IEEE80211_BAND_2GHZ)
+			mac_index += IWL_FIRST_OFDM_RATE;
+	}
 
-	if ((info->status.rates[0].idx < 0) ||
-	    (tbl_type.is_SGI != !!(info->status.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)) ||
-	    (tbl_type.is_fat != !!(info->status.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
-	    (tbl_type.is_dup != !!(info->status.rates[0].flags & IEEE80211_TX_RC_DUP_DATA)) ||
+	if ((mac_index < 0) ||
+	    (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
+	    (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) ||
+	    (tbl_type.is_dup != !!(mac_flags & IEEE80211_TX_RC_DUP_DATA)) ||
 	    (tbl_type.ant_type != info->antenna_sel_tx) ||
-	    (!!(tx_rate & RATE_MCS_HT_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) ||
-	    (!!(tx_rate & RATE_MCS_GF_MSK) != !!(info->status.rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
-	    (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
-	     hw->wiphy->bands[info->band]->bitrates[info->status.rates[0].idx].bitrate)) {
-		IWL_DEBUG_RATE(priv, "initial rate does not match 0x%x\n", tx_rate);
+	    (!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
+	    (!!(tx_rate & RATE_MCS_GF_MSK) != !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
+	    (rs_index != mac_index)) {
+		IWL_DEBUG_RATE(priv, "initial rate %d does not match %d (0x%x)\n", mac_index, rs_index, tx_rate);
 		/* the last LQ command could failed so the LQ in ucode not
 		 * the same in driver sync up
 		 */
@@ -1049,7 +1063,7 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
 		else
 			tbl->expected_tpt = expected_tpt_A;
 	} else if (is_siso(tbl->lq_type)) {
-		if (tbl->is_fat && !lq_sta->is_dup)
+		if (tbl->is_ht40 && !lq_sta->is_dup)
 			if (tbl->is_SGI)
 				tbl->expected_tpt = expected_tpt_siso40MHzSGI;
 			else
@@ -1059,7 +1073,7 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
 		else
 			tbl->expected_tpt = expected_tpt_siso20MHz;
 	} else if (is_mimo2(tbl->lq_type)) {
-		if (tbl->is_fat && !lq_sta->is_dup)
+		if (tbl->is_ht40 && !lq_sta->is_dup)
 			if (tbl->is_SGI)
 				tbl->expected_tpt = expected_tpt_mimo2_40MHzSGI;
 			else
@@ -1069,7 +1083,7 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
 		else
 			tbl->expected_tpt = expected_tpt_mimo2_20MHz;
 	} else if (is_mimo3(tbl->lq_type)) {
-		if (tbl->is_fat && !lq_sta->is_dup)
+		if (tbl->is_ht40 && !lq_sta->is_dup)
 			if (tbl->is_SGI)
 				tbl->expected_tpt = expected_tpt_mimo3_40MHzSGI;
 			else
@@ -1217,22 +1231,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
 	tbl->max_search = IWL_MAX_SEARCH;
 	rate_mask = lq_sta->active_mimo2_rate;
 
-	if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
-		tbl->is_fat = 1;
-	else
-		tbl->is_fat = 0;
-
-	/* FIXME: - don't toggle SGI here
-	if (tbl->is_fat) {
-		if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
-			tbl->is_SGI = 1;
-		else
-			tbl->is_SGI = 0;
-	} else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
-		tbl->is_SGI = 1;
+	if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+		tbl->is_ht40 = 1;
 	else
-		tbl->is_SGI = 0;
-	*/
+		tbl->is_ht40 = 0;
 
 	rs_set_expected_tpt_table(lq_sta, tbl);
 
@@ -1283,22 +1285,10 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
 	tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
 	rate_mask = lq_sta->active_mimo3_rate;
 
-	if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
-		tbl->is_fat = 1;
+	if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+		tbl->is_ht40 = 1;
 	else
-		tbl->is_fat = 0;
-
-	/* FIXME: - don't toggle SGI here
-	if (tbl->is_fat) {
-		if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
-			tbl->is_SGI = 1;
-		else
-			tbl->is_SGI = 0;
-	} else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
-		tbl->is_SGI = 1;
-	else
-		tbl->is_SGI = 0;
-	*/
+		tbl->is_ht40 = 0;
 
 	rs_set_expected_tpt_table(lq_sta, tbl);
 
@@ -1342,22 +1332,10 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
 	tbl->max_search = IWL_MAX_SEARCH;
 	rate_mask = lq_sta->active_siso_rate;
 
-	if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
-		tbl->is_fat = 1;
+	if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap))
+		tbl->is_ht40 = 1;
 	else
-		tbl->is_fat = 0;
-
-	/* FIXME: - don't toggle SGI here
-	if (tbl->is_fat) {
-		if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
-			tbl->is_SGI = 1;
-		else
-			tbl->is_SGI = 0;
-	} else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
-		tbl->is_SGI = 1;
-	else
-		tbl->is_SGI = 0;
-	*/
+		tbl->is_ht40 = 0;
 
 	if (is_green)
 		tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
@@ -1398,6 +1376,12 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
 	int ret = 0;
 	u8 update_search_tbl_counter = 0;
 
+	if (!iwl_ht_enabled(priv))
+		/* stay in Legacy */
+		tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+	else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
+		   tbl->action > IWL_LEGACY_SWITCH_SISO)
+		tbl->action = IWL_LEGACY_SWITCH_SISO;
 	for (; ;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -1521,6 +1505,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
 	struct iwl_scale_tbl_info *search_tbl =
 				&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
 	struct iwl_rate_scale_data *window = &(tbl->win[index]);
+	struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 	u32 sz = (sizeof(struct iwl_scale_tbl_info) -
 		  (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
 	u8 start_action = tbl->action;
@@ -1529,6 +1514,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
 	u8 update_search_tbl_counter = 0;
 	int ret;
 
+	if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE &&
+	    tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
+		/* stay in SISO */
+		tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+	}
 	for (;;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -1575,13 +1565,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
 				goto out;
 			break;
 		case IWL_SISO_SWITCH_GI:
-			if (!tbl->is_fat &&
-				!(priv->current_ht_config.sgf &
-						HT_SHORT_GI_20MHZ))
+			if (!tbl->is_ht40 && !(ht_cap->cap &
+						IEEE80211_HT_CAP_SGI_20))
 				break;
-			if (tbl->is_fat &&
-				!(priv->current_ht_config.sgf &
-						HT_SHORT_GI_40MHZ))
+			if (tbl->is_ht40 && !(ht_cap->cap &
+						IEEE80211_HT_CAP_SGI_40))
 				break;
 
 			IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n");
@@ -1655,6 +1643,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
 	struct iwl_scale_tbl_info *search_tbl =
 				&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
 	struct iwl_rate_scale_data *window = &(tbl->win[index]);
+	struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 	u32 sz = (sizeof(struct iwl_scale_tbl_info) -
 		  (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
 	u8 start_action = tbl->action;
@@ -1663,6 +1652,12 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
 	u8 update_search_tbl_counter = 0;
 	int ret;
 
+	if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
+	    (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
+	     tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
+		/* switch in SISO */
+		tbl->action = IWL_MIMO2_SWITCH_SISO_A;
+	}
 	for (;;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -1709,13 +1704,11 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
 			break;
 
 		case IWL_MIMO2_SWITCH_GI:
-			if (!tbl->is_fat &&
-				!(priv->current_ht_config.sgf &
-						HT_SHORT_GI_20MHZ))
+			if (!tbl->is_ht40 && !(ht_cap->cap &
+						IEEE80211_HT_CAP_SGI_20))
 				break;
-			if (tbl->is_fat &&
-				!(priv->current_ht_config.sgf &
-						HT_SHORT_GI_40MHZ))
+			if (tbl->is_ht40 && !(ht_cap->cap &
+						IEEE80211_HT_CAP_SGI_40))
 				break;
 
 			IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n");
@@ -1791,6 +1784,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
 	struct iwl_scale_tbl_info *search_tbl =
 				&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
 	struct iwl_rate_scale_data *window = &(tbl->win[index]);
+	struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 	u32 sz = (sizeof(struct iwl_scale_tbl_info) -
 		  (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
 	u8 start_action = tbl->action;
@@ -1799,6 +1793,12 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
 	int ret;
 	u8 update_search_tbl_counter = 0;
 
+	if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) &&
+	    (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
+	     tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
+		/* switch in SISO */
+		tbl->action = IWL_MIMO3_SWITCH_SISO_A;
+	}
 	for (;;) {
 		lq_sta->action_counter++;
 		switch (tbl->action) {
@@ -1867,13 +1867,11 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
 			break;
 
 		case IWL_MIMO3_SWITCH_GI:
-			if (!tbl->is_fat &&
-				!(priv->current_ht_config.sgf &
-						HT_SHORT_GI_20MHZ))
+			if (!tbl->is_ht40 && !(ht_cap->cap &
+						IEEE80211_HT_CAP_SGI_20))
 				break;
-			if (tbl->is_fat &&
-				!(priv->current_ht_config.sgf &
-						HT_SHORT_GI_40MHZ))
+			if (tbl->is_ht40 && !(ht_cap->cap &
+						IEEE80211_HT_CAP_SGI_40))
 				break;
 
 			IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n");
@@ -2003,6 +2001,25 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
 }
 
 /*
+ * setup rate table in uCode
+ * return rate_n_flags as used in the table
+ */
+static u32 rs_update_rate_tbl(struct iwl_priv *priv,
+				struct iwl_lq_sta *lq_sta,
+				struct iwl_scale_tbl_info *tbl,
+				int index, u8 is_green)
+{
+	u32 rate;
+
+	/* Update uCode's rate table. */
+	rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
+	rs_fill_link_cmd(priv, lq_sta, rate);
+	iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
+
+	return rate;
+}
+
+/*
  * Do rate scaling and search for new modulation mode.
  */
 static void rs_rate_scale_perform(struct iwl_priv *priv,
@@ -2066,7 +2083,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 	if (is_legacy(tbl->lq_type))
 		lq_sta->is_green = 0;
 	else
-		lq_sta->is_green = rs_use_green(priv, conf);
+		lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
 	is_green = lq_sta->is_green;
 
 	/* current tx rate */
@@ -2098,6 +2115,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 
 	if (!((1 << index) & rate_scale_index_msk)) {
 		IWL_ERR(priv, "Current Rate is not valid\n");
+		if (lq_sta->search_better_tbl) {
+			/* revert to active table if search table is not valid*/
+			tbl->lq_type = LQ_NONE;
+			lq_sta->search_better_tbl = 0;
+			tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+			/* get "active" rate info */
+			index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
+			rate = rs_update_rate_tbl(priv, lq_sta,
+						  tbl, index, is_green);
+		}
 		return;
 	}
 
@@ -2149,8 +2176,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 			tbl->expected_tpt[index] + 64) / 128));
 
 	/* If we are searching for better modulation mode, check success. */
-	if (lq_sta->search_better_tbl) {
-
+	if (lq_sta->search_better_tbl &&
+	    (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI)) {
 		/* If good success, continue using the "search" mode;
 		 * no need to send new link quality command, since we're
 		 * continuing to use the setup that we've been trying. */
@@ -2278,7 +2305,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 		    ((sr > IWL_RATE_HIGH_TH) ||
 		     (current_tpt > (100 * tbl->expected_tpt[low]))))
 		scale_action = 0;
-
+	if (!iwl_ht_enabled(priv) && !is_legacy(tbl->lq_type))
+		scale_action = -1;
+	if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI &&
+		(is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
+		scale_action = -1;
 	switch (scale_action) {
 	case -1:
 		/* Decrease starting rate, update uCode's rate table */
@@ -2308,15 +2339,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 
 lq_update:
 	/* Replace uCode's rate table for the destination station. */
-	if (update_lq) {
-		rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
-		rs_fill_link_cmd(priv, lq_sta, rate);
-		iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
-	}
-
-	/* Should we stay with this modulation mode, or search for a new one? */
-	rs_stay_in_table(lq_sta);
+	if (update_lq)
+		rate = rs_update_rate_tbl(priv, lq_sta,
+					  tbl, index, is_green);
 
+	if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
+		/* Should we stay with this modulation mode,
+		 * or search for a new one? */
+		rs_stay_in_table(lq_sta);
+	}
 	/*
 	 * Search for new modulation mode if we're:
 	 * 1)  Not changing rates right now
@@ -2373,7 +2404,8 @@ lq_update:
 		 * have been tried and compared, stay in this best modulation
 		 * mode for a while before next round of mode comparisons. */
 		if (lq_sta->enable_counter &&
-		    (lq_sta->action_counter >= tbl1->max_search)) {
+		    (lq_sta->action_counter >= tbl1->max_search) &&
+		    iwl_ht_enabled(priv)) {
 			if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
 			    (lq_sta->tx_agg_tid_en & (1 << tid)) &&
 			    (tid != MAX_TID_COUNT)) {
@@ -2409,7 +2441,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
 	int rate_idx;
 	int i;
 	u32 rate;
-	u8 use_green = rs_use_green(priv, conf);
+	u8 use_green = rs_use_green(sta, &priv->current_ht_config);
 	u8 active_tbl = 0;
 	u8 valid_tx_ant;
 
@@ -2462,11 +2494,11 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
 	struct ieee80211_supported_band *sband = txrc->sband;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
 	struct ieee80211_conf *conf = &priv->hw->conf;
+	struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct iwl_lq_sta *lq_sta = priv_sta;
 	int rate_idx;
-	u64 mask_bit = 0;
 
 	IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
 
@@ -2481,22 +2513,9 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
 			lq_sta->max_rate_idx = -1;
 	}
 
-	if (sta)
-		mask_bit = sta->supp_rates[sband->band];
-
 	/* Send management frames and NO_ACK data using lowest rate. */
-	if (!ieee80211_is_data(hdr->frame_control) ||
-	    info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
-		if (!mask_bit)
-			info->control.rates[0].idx =
-					rate_lowest_index(sband, NULL);
-		else
-			info->control.rates[0].idx =
-					rate_lowest_index(sband, sta);
-		if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-			info->control.rates[0].count = 1;
+	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
-	}
 
 	rate_idx  = lq_sta->last_txrate_idx;
 
@@ -2508,7 +2527,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
 			IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
 				       hdr->addr1);
 			sta_id = iwl_add_station(priv, hdr->addr1,
-						false, CMD_ASYNC, NULL);
+						false, CMD_ASYNC, ht_cap);
 		}
 		if ((sta_id != IWL_INVALID_STATION)) {
 			lq_sta->lq.sta_id = sta_id;
@@ -2533,15 +2552,20 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
 			info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
 		if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK)
 			info->control.rates[0].flags |= IEEE80211_TX_RC_DUP_DATA;
-		if (lq_sta->last_rate_n_flags & RATE_MCS_FAT_MSK)
+		if (lq_sta->last_rate_n_flags & RATE_MCS_HT40_MSK)
 			info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
 		if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK)
 			info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
 	} else {
-		if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT)
+		/* Check for invalid rates */
+		if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) ||
+				((sband->band == IEEE80211_BAND_5GHZ) &&
+				 (rate_idx < IWL_FIRST_OFDM_RATE)))
 			rate_idx = rate_lowest_index(sband, sta);
+		/* On valid 5 GHz rate, adjust index */
 		else if (sband->band == IEEE80211_BAND_5GHZ)
 			rate_idx -= IWL_FIRST_OFDM_RATE;
+		info->control.rates[0].flags = 0;
 	}
 	info->control.rates[0].idx = rate_idx;
 
@@ -2577,10 +2601,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 	int i, j;
 	struct iwl_priv *priv = (struct iwl_priv *)priv_r;
 	struct ieee80211_conf *conf = &priv->hw->conf;
+	struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
 	struct iwl_lq_sta *lq_sta = priv_sta;
-	u16 mask_bit = 0;
-	int count;
-	int start_rate = 0;
 
 	lq_sta->flush_timer = 0;
 	lq_sta->supp_rates = sta->supp_rates[sband->band];
@@ -2605,7 +2627,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 		if (sta_id == IWL_INVALID_STATION) {
 			IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
 			sta_id = iwl_add_station(priv, sta->addr, false,
-						CMD_ASYNC, NULL);
+						CMD_ASYNC, ht_cap);
 		}
 		if ((sta_id != IWL_INVALID_STATION)) {
 			lq_sta->lq.sta_id = sta_id;
@@ -2618,7 +2640,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 	lq_sta->is_dup = 0;
 	lq_sta->max_rate_idx = -1;
 	lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
-	lq_sta->is_green = rs_use_green(priv, conf);
+	lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
 	lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
 	lq_sta->active_rate_basic = priv->active_rate_basic;
 	lq_sta->band = priv->band;
@@ -2626,19 +2648,19 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 	 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
 	 * supp_rates[] does not; shift to convert format, force 9 MBits off.
 	 */
-	lq_sta->active_siso_rate = sta->ht_cap.mcs.rx_mask[0] << 1;
-	lq_sta->active_siso_rate |= sta->ht_cap.mcs.rx_mask[0] & 0x1;
+	lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
+	lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
 	lq_sta->active_siso_rate &= ~((u16)0x2);
 	lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
 
 	/* Same here */
-	lq_sta->active_mimo2_rate = sta->ht_cap.mcs.rx_mask[1] << 1;
-	lq_sta->active_mimo2_rate |= sta->ht_cap.mcs.rx_mask[1] & 0x1;
+	lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
+	lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
 	lq_sta->active_mimo2_rate &= ~((u16)0x2);
 	lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
 
-	lq_sta->active_mimo3_rate = sta->ht_cap.mcs.rx_mask[2] << 1;
-	lq_sta->active_mimo3_rate |= sta->ht_cap.mcs.rx_mask[2] & 0x1;
+	lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1;
+	lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1;
 	lq_sta->active_mimo3_rate &= ~((u16)0x2);
 	lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
 
@@ -2655,25 +2677,15 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 	lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
 	lq_sta->drv = priv;
 
-	/* Find highest tx rate supported by hardware and destination station */
-	mask_bit = sta->supp_rates[sband->band];
-	count = sband->n_bitrates;
-	if (sband->band == IEEE80211_BAND_5GHZ) {
-		count += IWL_FIRST_OFDM_RATE;
-		start_rate = IWL_FIRST_OFDM_RATE;
-		mask_bit <<= IWL_FIRST_OFDM_RATE;
-	}
-
-	mask_bit = mask_bit & lq_sta->active_legacy_rate;
-	lq_sta->last_txrate_idx = 4;
-	for (i = start_rate; i < count; i++)
-		if (mask_bit & BIT(i))
-			lq_sta->last_txrate_idx = i;
+	/* Set last_txrate_idx to lowest rate */
+	lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
+	if (sband->band == IEEE80211_BAND_5GHZ)
+		lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
 
 	rs_initialize_lq(priv, conf, sta, lq_sta);
 }
 
-static void rs_fill_link_cmd(const struct iwl_priv *priv,
+static void rs_fill_link_cmd(struct iwl_priv *priv,
 			     struct iwl_lq_sta *lq_sta, u32 new_rate)
 {
 	struct iwl_scale_tbl_info tbl_type;
@@ -2920,7 +2932,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
 		   (is_siso(tbl->lq_type)) ? "SISO" :
 		   ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
 		   desc += sprintf(buff+desc, " %s",
-		   (tbl->is_fat) ? "40MHz" : "20MHz");
+		   (tbl->is_ht40) ? "40MHz" : "20MHz");
 		   desc += sprintf(buff+desc, " %s %s\n", (tbl->is_SGI) ? "SGI" : "",
 		   (lq_sta->is_green) ? "GF enabled" : "");
 	}
@@ -2985,12 +2997,13 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
 		return -ENOMEM;
 
 	for (i = 0; i < LQ_SIZE; i++) {
-		desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d GF=%d\n"
+		desc += sprintf(buff+desc,
+				"%s type=%d SGI=%d HT40=%d DUP=%d GF=%d\n"
 				"rate=0x%X\n",
 				lq_sta->active_tbl == i ? "*" : "x",
 				lq_sta->lq_info[i].lq_type,
 				lq_sta->lq_info[i].is_SGI,
-				lq_sta->lq_info[i].is_fat,
+				lq_sta->lq_info[i].is_ht40,
 				lq_sta->lq_info[i].is_dup,
 				lq_sta->is_green,
 				lq_sta->lq_info[i].current_rate);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index 25050bf..9fac530 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -73,6 +73,7 @@ enum {
 	IWL_RATE_54M_INDEX,
 	IWL_RATE_60M_INDEX,
 	IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
+	IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1,	/* Excluding 60M */
 	IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
 	IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
 	IWL_RATE_INVALID = IWL_RATE_COUNT,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 355f50e..00457bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -171,7 +171,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
 		       le16_to_cpu(priv->staging_rxon.channel),
 		       priv->staging_rxon.bssid_addr);
 
-	iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+	iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
 
 	/* Apply the new configuration
 	 * RXON unassoc clears the station table in uCode, send it before
@@ -442,8 +442,8 @@ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 	/* Unmap tx_cmd */
 	if (num_tbs)
 		pci_unmap_single(dev,
-				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
-				pci_unmap_len(&txq->cmd[index]->meta, len),
+				pci_unmap_addr(&txq->meta[index], mapping),
+				pci_unmap_len(&txq->meta[index], len),
 				PCI_DMA_BIDIRECTIONAL);
 
 	/* Unmap chunks, if any. */
@@ -512,70 +512,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv,
 	return 0;
 }
 
-
-/******************************************************************************
- *
- * Misc. internal state and helper functions
- *
- ******************************************************************************/
-
-#define MAX_UCODE_BEACON_INTERVAL	4096
-
-static u16 iwl_adjust_beacon_interval(u16 beacon_val)
-{
-	u16 new_val = 0;
-	u16 beacon_factor = 0;
-
-	beacon_factor = (beacon_val + MAX_UCODE_BEACON_INTERVAL)
-					/ MAX_UCODE_BEACON_INTERVAL;
-	new_val = beacon_val / beacon_factor;
-
-	if (!new_val)
-		new_val = MAX_UCODE_BEACON_INTERVAL;
-
-	return new_val;
-}
-
-static void iwl_setup_rxon_timing(struct iwl_priv *priv)
-{
-	u64 tsf;
-	s32 interval_tm, rem;
-	unsigned long flags;
-	struct ieee80211_conf *conf = NULL;
-	u16 beacon_int = 0;
-
-	conf = ieee80211_get_hw_conf(priv->hw);
-
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
-	priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
-
-	if (priv->iw_mode == NL80211_IFTYPE_STATION) {
-		beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
-		priv->rxon_timing.atim_window = 0;
-	} else {
-		beacon_int = iwl_adjust_beacon_interval(
-			priv->vif->bss_conf.beacon_int);
-
-		/* TODO: we need to get atim_window from upper stack
-		 * for now we set to 0 */
-		priv->rxon_timing.atim_window = 0;
-	}
-
-	priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
-
-	tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
-	interval_tm = beacon_int * 1024;
-	rem = do_div(tsf, interval_tm);
-	priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-	IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n",
-			le16_to_cpu(priv->rxon_timing.beacon_interval),
-			le32_to_cpu(priv->rxon_timing.beacon_init_val),
-			le16_to_cpu(priv->rxon_timing.atim_window));
-}
-
 /******************************************************************************
  *
  * Generic RX handler implementations
@@ -697,7 +633,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
 	unsigned long status = priv->status;
-	unsigned long reg_flags;
 
 	IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
 			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
@@ -717,19 +652,12 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
 				    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 			iwl_write_direct32(priv, HBUS_TARG_MBX_C,
 					HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
-
-		}
-
-		if (flags & RF_CARD_DISABLED) {
-			iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
-				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
-			iwl_read32(priv, CSR_UCODE_DRV_GP1);
-			spin_lock_irqsave(&priv->reg_lock, reg_flags);
-			if (!iwl_grab_nic_access(priv))
-				iwl_release_nic_access(priv);
-			spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 		}
+		if (flags & RF_CARD_DISABLED)
+			iwl_tt_enter_ct_kill(priv);
 	}
+	if (!(flags & RF_CARD_DISABLED))
+		iwl_tt_exit_ct_kill(priv);
 
 	if (flags & HW_CARD_DISABLED)
 		set_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -964,7 +892,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 	iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & IWL_DL_ISR) {
+	if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
 		/* just for debug */
 		inta_mask = iwl_read32(priv, CSR_INT_MASK);
 		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -983,7 +911,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 
 	/* Now service all interrupt bits discovered above. */
 	if (inta & CSR_INT_BIT_HW_ERR) {
-		IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
+		IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
 
 		/* Tell the device to stop sending interrupts */
 		iwl_disable_interrupts(priv);
@@ -999,7 +927,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 	}
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & (IWL_DL_ISR)) {
+	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
 		/* NIC fires this, but we don't use it, redundant with WAKEUP */
 		if (inta & CSR_INT_BIT_SCD) {
 			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
@@ -1024,7 +952,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
 			hw_rf_kill = 1;
 
-		IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
+		IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
 				hw_rf_kill ? "disable radio" : "enable radio");
 
 		priv->isr_stats.rfkill++;
@@ -1113,7 +1041,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 		iwl_enable_interrupts(priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & (IWL_DL_ISR)) {
+	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
 		inta = iwl_read32(priv, CSR_INT);
 		inta_mask = iwl_read32(priv, CSR_INT_MASK);
 		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
@@ -1144,7 +1072,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 	inta = priv->inta;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & IWL_DL_ISR) {
+	if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
 		/* just for debug */
 		inta_mask = iwl_read32(priv, CSR_INT_MASK);
 		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
@@ -1156,7 +1084,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 
 	/* Now service all interrupt bits discovered above. */
 	if (inta & CSR_INT_BIT_HW_ERR) {
-		IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
+		IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
 
 		/* Tell the device to stop sending interrupts */
 		iwl_disable_interrupts(priv);
@@ -1172,7 +1100,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 	}
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & (IWL_DL_ISR)) {
+	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
 		/* NIC fires this, but we don't use it, redundant with WAKEUP */
 		if (inta & CSR_INT_BIT_SCD) {
 			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
@@ -1197,7 +1125,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
 			hw_rf_kill = 1;
 
-		IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
+		IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
 				hw_rf_kill ? "disable radio" : "enable radio");
 
 		priv->isr_stats.rfkill++;
@@ -1348,7 +1276,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
  */
 static int iwl_read_ucode(struct iwl_priv *priv)
 {
-	struct iwl_ucode *ucode;
+	struct iwl_ucode_header *ucode;
 	int ret = -EINVAL, index;
 	const struct firmware *ucode_raw;
 	const char *name_pre = priv->cfg->fw_name_pre;
@@ -1357,7 +1285,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 	char buf[25];
 	u8 *src;
 	size_t len;
-	u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size;
+	u32 api_ver, build;
+	u32 inst_size, data_size, init_size, init_data_size, boot_size;
+	u16 eeprom_ver;
 
 	/* Ask kernel firmware_class module to get the boot firmware off disk.
 	 * request_firmware() is synchronous, file is in memory on return. */
@@ -1387,23 +1317,26 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 	if (ret < 0)
 		goto error;
 
-	/* Make sure that we got at least our header! */
-	if (ucode_raw->size < sizeof(*ucode)) {
+	/* Make sure that we got at least the v1 header! */
+	if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
 		IWL_ERR(priv, "File size way too small!\n");
 		ret = -EINVAL;
 		goto err_release;
 	}
 
 	/* Data from ucode file:  header followed by uCode images */
-	ucode = (void *)ucode_raw->data;
+	ucode = (struct iwl_ucode_header *)ucode_raw->data;
 
 	priv->ucode_ver = le32_to_cpu(ucode->ver);
 	api_ver = IWL_UCODE_API(priv->ucode_ver);
-	inst_size = le32_to_cpu(ucode->inst_size);
-	data_size = le32_to_cpu(ucode->data_size);
-	init_size = le32_to_cpu(ucode->init_size);
-	init_data_size = le32_to_cpu(ucode->init_data_size);
-	boot_size = le32_to_cpu(ucode->boot_size);
+	build = priv->cfg->ops->ucode->get_build(ucode, api_ver);
+	inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
+	data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
+	init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
+	init_data_size =
+		priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
+	boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
+	src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
 
 	/* api_ver should match the api version forming part of the
 	 * firmware filename ... but we don't check for that and only rely
@@ -1429,6 +1362,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 	       IWL_UCODE_API(priv->ucode_ver),
 	       IWL_UCODE_SERIAL(priv->ucode_ver));
 
+	if (build)
+		IWL_DEBUG_INFO(priv, "Build %u\n", build);
+
+	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
+	IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
+		       (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+		       ? "OTP" : "EEPROM", eeprom_ver);
+
 	IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
 		       priv->ucode_ver);
 	IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@ -1443,12 +1384,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 		       boot_size);
 
 	/* Verify size of file vs. image size info in file's header */
-	if (ucode_raw->size < sizeof(*ucode) +
+	if (ucode_raw->size !=
+		priv->cfg->ops->ucode->get_header_size(api_ver) +
 		inst_size + data_size + init_size +
 		init_data_size + boot_size) {
 
-		IWL_DEBUG_INFO(priv, "uCode file size %d too small\n",
-			       (int)ucode_raw->size);
+		IWL_DEBUG_INFO(priv,
+			"uCode file size %d does not match expected size\n",
+			(int)ucode_raw->size);
 		ret = -EINVAL;
 		goto err_release;
 	}
@@ -1528,42 +1471,42 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 	/* Copy images into buffers for card's bus-master reads ... */
 
 	/* Runtime instructions (first block of data in file) */
-	src = &ucode->data[0];
-	len = priv->ucode_code.len;
+	len = inst_size;
 	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
 	memcpy(priv->ucode_code.v_addr, src, len);
+	src += len;
+
 	IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
 		priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
 	/* Runtime data (2nd block)
 	 * NOTE:  Copy into backup buffer will be done in iwl_up()  */
-	src = &ucode->data[inst_size];
-	len = priv->ucode_data.len;
+	len = data_size;
 	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
 	memcpy(priv->ucode_data.v_addr, src, len);
 	memcpy(priv->ucode_data_backup.v_addr, src, len);
+	src += len;
 
 	/* Initialization instructions (3rd block) */
 	if (init_size) {
-		src = &ucode->data[inst_size + data_size];
-		len = priv->ucode_init.len;
+		len = init_size;
 		IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
 				len);
 		memcpy(priv->ucode_init.v_addr, src, len);
+		src += len;
 	}
 
 	/* Initialization data (4th block) */
 	if (init_data_size) {
-		src = &ucode->data[inst_size + data_size + init_size];
-		len = priv->ucode_init_data.len;
+		len = init_data_size;
 		IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
 			       len);
 		memcpy(priv->ucode_init_data.v_addr, src, len);
+		src += len;
 	}
 
 	/* Bootstrap instructions (5th block) */
-	src = &ucode->data[inst_size + data_size + init_size + init_data_size];
-	len = priv->ucode_boot.len;
+	len = boot_size;
 	IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
 	memcpy(priv->ucode_boot.v_addr, src, len);
 
@@ -1663,7 +1606,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
 	set_bit(STATUS_READY, &priv->status);
 	wake_up_interruptible(&priv->wait_command_queue);
 
-	iwl_power_update_mode(priv, 1);
+	iwl_power_update_mode(priv, true);
 
 	/* reassociate for ADHOC mode */
 	if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
@@ -1812,6 +1755,11 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
 
 	IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n");
 
+	ret = iwl_set_hw_ready(priv);
+	if (priv->hw_ready)
+		return ret;
+
+	/* If HW is not ready, prepare the conditions to check again */
 	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 			CSR_HW_IF_CONFIG_REG_PREPARE);
 
@@ -1819,6 +1767,7 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
 			~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
 			CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
 
+	/* HW should be ready by now, check again. */
 	if (ret != -ETIMEDOUT)
 		iwl_set_hw_ready(priv);
 
@@ -2126,7 +2075,7 @@ void iwl_post_associate(struct iwl_priv *priv)
 	 * If chain noise has already been run, then we need to enable
 	 * power management here */
 	if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
-		iwl_power_update_mode(priv, 0);
+		iwl_power_update_mode(priv, false);
 
 	/* Enable Rx differential gain and sensitivity calibrations */
 	iwl_chain_noise_reset(priv);
@@ -2206,7 +2155,7 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
 
 	priv->is_open = 0;
 
-	if (iwl_is_ready_rf(priv)) {
+	if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) {
 		/* stop mac, cancel any scan request and clear
 		 * RXON_FILTER_ASSOC_MSK BIT
 		 */
@@ -2331,7 +2280,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	if (priv->hw_params.sw_crypto) {
+	if (priv->cfg->mod_params->sw_crypto) {
 		IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
 		return -EOPNOTSUPP;
 	}
@@ -2455,14 +2404,16 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
  * used for controlling the debug level.
  *
  * See the level definitions in iwl for details.
+ *
+ * The debug_level being managed using sysfs below is a per device debug
+ * level that is used instead of the global debug level if it (the per
+ * device debug level) is set.
  */
-
 static ssize_t show_debug_level(struct device *d,
 				struct device_attribute *attr, char *buf)
 {
 	struct iwl_priv *priv = dev_get_drvdata(d);
-
-	return sprintf(buf, "0x%08X\n", priv->debug_level);
+	return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv));
 }
 static ssize_t store_debug_level(struct device *d,
 				struct device_attribute *attr,
@@ -2475,9 +2426,12 @@ static ssize_t store_debug_level(struct device *d,
 	ret = strict_strtoul(buf, 0, &val);
 	if (ret)
 		IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
-	else
+	else {
 		priv->debug_level = val;
-
+		if (iwl_alloc_traffic_mem(priv))
+			IWL_ERR(priv,
+				"Not enough memory to generate traffic log\n");
+	}
 	return strnlen(buf, count);
 }
 
@@ -2488,39 +2442,6 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
 #endif /* CONFIG_IWLWIFI_DEBUG */
 
 
-static ssize_t show_version(struct device *d,
-				struct device_attribute *attr, char *buf)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	struct iwl_alive_resp *palive = &priv->card_alive;
-	ssize_t pos = 0;
-	u16 eeprom_ver;
-
-	if (palive->is_valid)
-		pos += sprintf(buf + pos,
-				"fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n"
-				"fw type: 0x%01X 0x%01X\n",
-				palive->ucode_major, palive->ucode_minor,
-				palive->sw_rev[0], palive->sw_rev[1],
-				palive->ver_type, palive->ver_subtype);
-	else
-		pos += sprintf(buf + pos, "fw not loaded\n");
-
-	if (priv->eeprom) {
-		eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-		pos += sprintf(buf + pos, "NVM Type: %s, version: 0x%x\n",
-			       (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
-			       ? "OTP" : "EEPROM", eeprom_ver);
-
-	} else {
-		pos += sprintf(buf + pos, "EEPROM not initialzed\n");
-	}
-
-	return pos;
-}
-
-static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
-
 static ssize_t show_temperature(struct device *d,
 				struct device_attribute *attr, char *buf)
 {
@@ -2556,10 +2477,15 @@ static ssize_t store_tx_power(struct device *d,
 	ret = strict_strtoul(buf, 10, &val);
 	if (ret)
 		IWL_INFO(priv, "%s is not in decimal form.\n", buf);
-	else
-		iwl_set_tx_power(priv, val, false);
-
-	return count;
+	else {
+		ret = iwl_set_tx_power(priv, val, false);
+		if (ret)
+			IWL_ERR(priv, "failed setting tx power (0x%d).\n",
+				ret);
+		else
+			ret = count;
+	}
+	return ret;
 }
 
 static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
@@ -2644,67 +2570,6 @@ static ssize_t store_filter_flags(struct device *d,
 static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
 		   store_filter_flags);
 
-static ssize_t store_power_level(struct device *d,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	int ret;
-	unsigned long mode;
-
-
-	mutex_lock(&priv->mutex);
-
-	ret = strict_strtoul(buf, 10, &mode);
-	if (ret)
-		goto out;
-
-	ret = iwl_power_set_user_mode(priv, mode);
-	if (ret) {
-		IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
-		goto out;
-	}
-	ret = count;
-
- out:
-	mutex_unlock(&priv->mutex);
-	return ret;
-}
-
-static ssize_t show_power_level(struct device *d,
-				struct device_attribute *attr, char *buf)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	int level = priv->power_data.power_mode;
-	char *p = buf;
-
-	p += sprintf(p, "%d\n", level);
-	return p - buf + 1;
-}
-
-static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
-		   store_power_level);
-
-static ssize_t show_qos(struct device *d,
-				struct device_attribute *attr, char *buf)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	char *p = buf;
-	int   q;
-
-	for (q = 0; q < AC_NUM; q++) {
-		p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n");
-		p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q,
-			     priv->qos_data.def_qos_parm.ac[q].cw_min,
-			     priv->qos_data.def_qos_parm.ac[q].cw_max,
-			     priv->qos_data.def_qos_parm.ac[q].aifsn,
-			     priv->qos_data.def_qos_parm.ac[q].edca_txop);
-	}
-
-	return p - buf + 1;
-}
-
-static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL);
 
 static ssize_t show_statistics(struct device *d,
 			       struct device_attribute *attr, char *buf)
@@ -2797,15 +2662,12 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 static struct attribute *iwl_sysfs_entries[] = {
 	&dev_attr_flags.attr,
 	&dev_attr_filter_flags.attr,
-	&dev_attr_power_level.attr,
 	&dev_attr_statistics.attr,
 	&dev_attr_temperature.attr,
 	&dev_attr_tx_power.attr,
 #ifdef CONFIG_IWLWIFI_DEBUG
 	&dev_attr_debug_level.attr,
 #endif
-	&dev_attr_version.attr,
-	&dev_attr_qos.attr,
 	NULL
 };
 
@@ -2849,7 +2711,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	/* Disabling hardware scan means that mac80211 will perform scans
 	 * "the hard way", rather than using device's scan. */
 	if (cfg->mod_params->disable_hw_scan) {
-		if (cfg->mod_params->debug & IWL_DL_INFO)
+		if (iwl_debug_level & IWL_DL_INFO)
 			dev_printk(KERN_DEBUG, &(pdev->dev),
 				   "Disabling hw_scan\n");
 		iwl_hw_ops.hw_scan = NULL;
@@ -2871,9 +2733,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	priv->inta_mask = CSR_INI_SET_MASK;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	priv->debug_level = priv->cfg->mod_params->debug;
 	atomic_set(&priv->restrict_refcnt, 0);
 #endif
+	if (iwl_alloc_traffic_mem(priv))
+		IWL_ERR(priv, "Not enough memory to generate traffic log\n");
 
 	/**************************
 	 * 2. Initializing PCI bus
@@ -3034,6 +2897,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		test_bit(STATUS_RF_KILL_HW, &priv->status));
 
 	iwl_power_initialize(priv);
+	iwl_tt_initialize(priv);
 	return 0;
 
  out_remove_sysfs:
@@ -3057,6 +2921,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	pci_disable_device(pdev);
  out_ieee80211_free_hw:
 	ieee80211_free_hw(priv->hw);
+	iwl_free_traffic_mem(priv);
  out:
 	return err;
 }
@@ -3086,6 +2951,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 		iwl_down(priv);
 	}
 
+	iwl_tt_exit(priv);
+
 	/* make sure we flush any pending irq or
 	 * tasklet for the driver
 	 */
@@ -3113,6 +2980,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 	 * until now... */
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
+	iwl_free_traffic_mem(priv);
 
 	free_irq(priv->pci_dev->irq, priv);
 	pci_disable_msi(priv->pci_dev);
@@ -3163,15 +3031,12 @@ static struct pci_device_id iwl_hw_card_ids[] = {
 	{IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
 	{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
 /* 6000/6050 Series */
-	{IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)},
-	{IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)},
-	{IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
+	{IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
-	{IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)},
+	{IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
-	{IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)},
-	{IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
-	{IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
+	{IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
 	{IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
 	{IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
@@ -3231,3 +3096,11 @@ static void __exit iwl_exit(void)
 
 module_exit(iwl_exit);
 module_init(iwl_init);
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+module_param_named(debug50, iwl_debug_level, uint, 0444);
+MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
+module_param_named(debug, iwl_debug_level, uint, 0644);
+MODULE_PARM_DESC(debug, "debug output mask");
+#endif
+
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index a5d6367..c4b565a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -86,7 +86,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
 
 	struct iwl_host_cmd hcmd = {
 		.id = REPLY_PHY_CALIBRATION_CMD,
-		.meta.flags = CMD_SIZE_HUGE,
+		.flags = CMD_SIZE_HUGE,
 	};
 
 	for (i = 0; i < IWL_CALIB_MAX; i++) {
@@ -251,12 +251,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
 
 		/* increase energy threshold (reduce nrg value)
 		 *   to decrease sensitivity */
-		if (data->nrg_th_cck >
-			(ranges->max_nrg_cck + NRG_STEP_CCK))
-			data->nrg_th_cck = data->nrg_th_cck
-						 - NRG_STEP_CCK;
-		else
-			data->nrg_th_cck = ranges->max_nrg_cck;
+		data->nrg_th_cck = data->nrg_th_cck - NRG_STEP_CCK;
 	/* Else if we got fewer than desired, increase sensitivity */
 	} else if (false_alarms < min_false_alarms) {
 		data->nrg_curr_state = IWL_FA_TOO_FEW;
@@ -424,7 +419,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
 	struct iwl_host_cmd cmd_out = {
 		.id = SENSITIVITY_CMD,
 		.len = sizeof(struct iwl_sensitivity_cmd),
-		.meta.flags = CMD_ASYNC,
+		.flags = CMD_ASYNC,
 		.data = &cmd,
 	};
 
@@ -857,7 +852,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
 		priv->cfg->ops->lib->update_chain_flags(priv);
 
 	data->state = IWL_CHAIN_NOISE_DONE;
-	iwl_power_update_mode(priv, 0);
+	iwl_power_update_mode(priv, false);
 }
 EXPORT_SYMBOL(iwl_chain_noise_calibration);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index c87033b..2c5c88f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -283,7 +283,7 @@ struct iwl3945_power_per_rate {
  *        1)  Dual stream (MIMO)
  *        2)  Triple stream (MIMO)
  *
- *    5:  Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data
+ *    5:  Value of 0x20 in bits 7:0 indicates 6 Mbps HT40 duplicate data
  *
  * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"):
  *  3-0:  0xD)   6 Mbps
@@ -320,11 +320,11 @@ struct iwl3945_power_per_rate {
 #define RATE_MCS_GF_POS 10
 #define RATE_MCS_GF_MSK 0x400
 
-/* Bit 11: (1) Use 40Mhz FAT chnl width, (0) use 20 MHz legacy chnl width */
-#define RATE_MCS_FAT_POS 11
-#define RATE_MCS_FAT_MSK 0x800
+/* Bit 11: (1) Use 40Mhz HT40 chnl width, (0) use 20 MHz legacy chnl width */
+#define RATE_MCS_HT40_POS 11
+#define RATE_MCS_HT40_MSK 0x800
 
-/* Bit 12: (1) Duplicate data on both 20MHz chnls.  FAT (bit 11) must be set. */
+/* Bit 12: (1) Duplicate data on both 20MHz chnls. HT40 (bit 11) must be set. */
 #define RATE_MCS_DUP_POS 12
 #define RATE_MCS_DUP_MSK 0x1000
 
@@ -459,7 +459,7 @@ struct iwl_init_alive_resp {
 
 	/* calibration values from "initialize" uCode */
 	__le32 voltage;		/* signed, higher value is lower voltage */
-	__le32 therm_r1[2];	/* signed, 1st for normal, 2nd for FAT channel*/
+	__le32 therm_r1[2];	/* signed, 1st for normal, 2nd for HT40 */
 	__le32 therm_r2[2];	/* signed */
 	__le32 therm_r3[2];	/* signed */
 	__le32 therm_r4[2];	/* signed */
@@ -610,7 +610,7 @@ enum {
 #define RXON_FLG_HT_OPERATING_MODE_POS		(23)
 
 #define RXON_FLG_HT_PROT_MSK			cpu_to_le32(0x1 << 23)
-#define RXON_FLG_FAT_PROT_MSK			cpu_to_le32(0x2 << 23)
+#define RXON_FLG_HT40_PROT_MSK			cpu_to_le32(0x2 << 23)
 
 #define RXON_FLG_CHANNEL_MODE_POS		(25)
 #define RXON_FLG_CHANNEL_MODE_MSK		cpu_to_le32(0x3 << 25)
@@ -765,6 +765,8 @@ struct iwl5000_rxon_assoc_cmd {
 } __attribute__ ((packed));
 
 #define IWL_CONN_MAX_LISTEN_INTERVAL	10
+#define IWL_MAX_UCODE_BEACON_INTERVAL	4 /* 4096 */
+#define IWL39_MAX_UCODE_BEACON_INTERVAL	1 /* 1024 */
 
 /*
  * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
@@ -884,12 +886,11 @@ struct iwl_qosparam_cmd {
 
 #define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2);
 #define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8);
-#define STA_FLG_PWR_SAVE_MSK		cpu_to_le32(1 << 8);
 #define STA_FLG_RTS_MIMO_PROT_MSK	cpu_to_le32(1 << 17)
 #define STA_FLG_AGG_MPDU_8US_MSK	cpu_to_le32(1 << 18)
 #define STA_FLG_MAX_AGG_SIZE_POS	(19)
 #define STA_FLG_MAX_AGG_SIZE_MSK	cpu_to_le32(3 << 19)
-#define STA_FLG_FAT_EN_MSK		cpu_to_le32(1 << 21)
+#define STA_FLG_HT40_EN_MSK		cpu_to_le32(1 << 21)
 #define STA_FLG_MIMO_DIS_MSK		cpu_to_le32(1 << 22)
 #define STA_FLG_AGG_MPDU_DENSITY_POS	(23)
 #define STA_FLG_AGG_MPDU_DENSITY_MSK	cpu_to_le32(7 << 23)
@@ -1154,6 +1155,7 @@ struct iwl_wep_cmd {
 #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK	cpu_to_le16(1 << 2)
 #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK	cpu_to_le16(1 << 3)
 #define RX_RES_PHY_FLAGS_ANTENNA_MSK		cpu_to_le16(0xf0)
+#define RX_RES_PHY_FLAGS_ANTENNA_POS		4
 
 #define RX_RES_STATUS_SEC_TYPE_MSK	(0x7 << 8)
 #define RX_RES_STATUS_SEC_TYPE_NONE	(0x0 << 8)
@@ -1922,7 +1924,7 @@ struct iwl_link_qual_general_params {
 #define LINK_QUAL_AGG_DISABLE_START_MIN	(0)
 
 #define LINK_QUAL_AGG_FRAME_LIMIT_DEF	(31)
-#define LINK_QUAL_AGG_FRAME_LIMIT_MAX	(64)
+#define LINK_QUAL_AGG_FRAME_LIMIT_MAX	(63)
 #define LINK_QUAL_AGG_FRAME_LIMIT_MIN	(0)
 
 /**
@@ -1982,10 +1984,10 @@ struct iwl_link_qual_agg_params {
  *     a) Use this same initial rate for first 3 entries.
  *     b) Find next lower available rate using same mode (SISO or MIMO),
  *        use for next 3 entries.  If no lower rate available, switch to
- *        legacy mode (no FAT channel, no MIMO, no short guard interval).
+ *        legacy mode (no HT40 channel, no MIMO, no short guard interval).
  *     c) If using MIMO, set command's mimo_delimiter to number of entries
  *        using MIMO (3 or 6).
- *     d) After trying 2 HT rates, switch to legacy mode (no FAT channel,
+ *     d) After trying 2 HT rates, switch to legacy mode (no HT40 channel,
  *        no MIMO, no short guard interval), at the next lower bit rate
  *        (e.g. if second HT bit rate was 54, try 48 legacy), and follow
  *        legacy procedure for remaining table entries.
@@ -2311,15 +2313,22 @@ struct iwl_spectrum_notification {
  * PM allow:
  *   bit 0 - '0' Driver not allow power management
  *           '1' Driver allow PM (use rest of parameters)
+ *
  * uCode send sleep notifications:
  *   bit 1 - '0' Don't send sleep notification
  *           '1' send sleep notification (SEND_PM_NOTIFICATION)
+ *
  * Sleep over DTIM
  *   bit 2 - '0' PM have to walk up every DTIM
  *           '1' PM could sleep over DTIM till listen Interval.
+ *
  * PCI power managed
  *   bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1)
  *           '1' !(PCI_CFG_LINK_CTRL & 0x1)
+ *
+ * Fast PD
+ *   bit 4 - '1' Put radio to sleep when receiving frame for others
+ *
  * Force sleep Modes
  *   bit 31/30- '00' use both mac/xtal sleeps
  *              '01' force Mac sleep
@@ -2411,6 +2420,13 @@ struct iwl_ct_kill_config {
 	__le32   critical_temperature_R;
 }  __attribute__ ((packed));
 
+/* 1000, and 6x00 */
+struct iwl_ct_kill_throttling_config {
+	__le32   critical_temperature_exit;
+	__le32   reserved;
+	__le32   critical_temperature_enter;
+}  __attribute__ ((packed));
+
 /******************************************************************************
  * (8)
  * Scan Commands, Responses, Notifications:
@@ -2913,6 +2929,20 @@ struct statistics_rx {
 	struct statistics_rx_ht_phy ofdm_ht;
 } __attribute__ ((packed));
 
+/**
+ * struct statistics_tx_power - current tx power
+ *
+ * @ant_a: current tx power on chain a in 1/2 dB step
+ * @ant_b: current tx power on chain b in 1/2 dB step
+ * @ant_c: current tx power on chain c in 1/2 dB step
+ */
+struct statistics_tx_power {
+	u8 ant_a;
+	u8 ant_b;
+	u8 ant_c;
+	u8 reserved;
+} __attribute__ ((packed));
+
 struct statistics_tx_non_phy_agg {
 	__le32 ba_timeout;
 	__le32 ba_reschedule_frames;
@@ -2924,8 +2954,6 @@ struct statistics_tx_non_phy_agg {
 	__le32 underrun;
 	__le32 bt_prio_kill;
 	__le32 rx_ba_rsp_cnt;
-	__le32 reserved2;
-	__le32 reserved3;
 } __attribute__ ((packed));
 
 struct statistics_tx {
@@ -2944,6 +2972,8 @@ struct statistics_tx {
 	__le32 cts_timeout_collision;
 	__le32 ack_or_ba_timeout_collision;
 	struct statistics_tx_non_phy_agg agg;
+	struct statistics_tx_power tx_power;
+	__le32 reserved1;
 } __attribute__ ((packed));
 
 
@@ -3008,7 +3038,7 @@ struct iwl_statistics_cmd {
  * one channel that has just been scanned.
  */
 #define STATISTICS_REPLY_FLG_BAND_24G_MSK         cpu_to_le32(0x2)
-#define STATISTICS_REPLY_FLG_FAT_MODE_MSK         cpu_to_le32(0x8)
+#define STATISTICS_REPLY_FLG_HT40_MODE_MSK        cpu_to_le32(0x8)
 
 struct iwl3945_notif_statistics {
 	__le32 flag;
@@ -3465,7 +3495,7 @@ struct iwl_wimax_coex_cmd {
  *****************************************************************************/
 
 struct iwl_rx_packet {
-	__le32 len;
+	__le32 len_n_flags;
 	struct iwl_cmd_header hdr;
 	union {
 		struct iwl3945_rx_frame rx_frame;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 18b135f..fd26c0d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -59,6 +59,9 @@ MODULE_LICENSE("GPL");
 				    IWL_RATE_##pp##M_INDEX,    \
 				    IWL_RATE_##np##M_INDEX }
 
+u32 iwl_debug_level;
+EXPORT_SYMBOL(iwl_debug_level);
+
 static irqreturn_t iwl_isr(int irq, void *data);
 
 /*
@@ -93,7 +96,6 @@ EXPORT_SYMBOL(iwl_rates);
 void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
 				  struct ieee80211_tx_info *info)
 {
-	int rate_index;
 	struct ieee80211_tx_rate *r = &info->control.rates[0];
 
 	info->antenna_sel_tx =
@@ -102,16 +104,13 @@ void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
 		r->flags |= IEEE80211_TX_RC_MCS;
 	if (rate_n_flags & RATE_MCS_GF_MSK)
 		r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
-	if (rate_n_flags & RATE_MCS_FAT_MSK)
+	if (rate_n_flags & RATE_MCS_HT40_MSK)
 		r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
 	if (rate_n_flags & RATE_MCS_DUP_MSK)
 		r->flags |= IEEE80211_TX_RC_DUP_DATA;
 	if (rate_n_flags & RATE_MCS_SGI_MSK)
 		r->flags |= IEEE80211_TX_RC_SHORT_GI;
-	rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags);
-	if (info->band == IEEE80211_BAND_5GHZ)
-		rate_index -= IWL_FIRST_OFDM_RATE;
-	r->idx = rate_index;
+	r->idx = iwl_hwrate_to_mac80211_idx(rate_n_flags, info->band);
 }
 EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
 
@@ -146,6 +145,27 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
 }
 EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
 
+int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
+{
+	int idx = 0;
+	int band_offset = 0;
+
+	/* HT rate format: mac80211 wants an MCS number, which is just LSB */
+	if (rate_n_flags & RATE_MCS_HT_MSK) {
+		idx = (rate_n_flags & 0xff);
+		return idx;
+	/* Legacy rate format, search for match in table */
+	} else {
+		if (band == IEEE80211_BAND_5GHZ)
+			band_offset = IWL_FIRST_OFDM_RATE;
+		for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
+			if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+				return idx - band_offset;
+	}
+
+	return -1;
+}
+
 u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant)
 {
 	int i;
@@ -391,13 +411,14 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
 
 	ht_info->ht_supported = true;
 
-	ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
+	if (priv->cfg->ht_greenfield_support)
+		ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
 	ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
 	ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
 			     (WLAN_HT_CAP_SM_PS_DISABLED << 2));
 
 	max_bit_rate = MAX_BIT_RATE_20_MHZ;
-	if (priv->hw_params.fat_channel & BIT(band)) {
+	if (priv->hw_params.ht40_channel & BIT(band)) {
 		ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
 		ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
 		ht_info->mcs.rx_mask[4] = 0x01;
@@ -435,12 +456,12 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv,
 {
 	int i;
 
-	for (i = 0; i < IWL_RATE_COUNT; i++) {
+	for (i = 0; i < IWL_RATE_COUNT_LEGACY; i++) {
 		rates[i].bitrate = iwl_rates[i].ieee * 5;
 		rates[i].hw_value = i; /* Rate scaling will work on indexes */
 		rates[i].hw_value_short = i;
 		rates[i].flags = 0;
-		if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
+		if ((i >= IWL_FIRST_CCK_RATE) && (i <= IWL_LAST_CCK_RATE)) {
 			/*
 			 * If CCK != 1M then set short preamble rate flag.
 			 */
@@ -476,7 +497,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
 	if (!channels)
 		return -ENOMEM;
 
-	rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
+	rates = kzalloc((sizeof(struct ieee80211_rate) * IWL_RATE_COUNT_LEGACY),
 			GFP_KERNEL);
 	if (!rates) {
 		kfree(channels);
@@ -488,7 +509,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
 	sband->channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
 	/* just OFDM */
 	sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
-	sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
+	sband->n_bitrates = IWL_RATE_COUNT_LEGACY - IWL_FIRST_OFDM_RATE;
 
 	if (priv->cfg->sku & IWL_SKU_N)
 		iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
@@ -498,7 +519,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
 	sband->channels = channels;
 	/* OFDM & CCK */
 	sband->bitrates = rates;
-	sband->n_bitrates = IWL_RATE_COUNT;
+	sband->n_bitrates = IWL_RATE_COUNT_LEGACY;
 
 	if (priv->cfg->sku & IWL_SKU_N)
 		iwlcore_init_ht_hw_capab(priv, &sband->ht_cap,
@@ -537,17 +558,14 @@ int iwlcore_init_geos(struct iwl_priv *priv)
 			if (ch->flags & EEPROM_CHANNEL_RADAR)
 				geo_ch->flags |= IEEE80211_CHAN_RADAR;
 
-			geo_ch->flags |= ch->fat_extension_channel;
+			geo_ch->flags |= ch->ht40_extension_channel;
 
-			if (ch->max_power_avg > priv->tx_power_channel_lmt)
-				priv->tx_power_channel_lmt = ch->max_power_avg;
+			if (ch->max_power_avg > priv->tx_power_device_lmt)
+				priv->tx_power_device_lmt = ch->max_power_avg;
 		} else {
 			geo_ch->flags |= IEEE80211_CHAN_DISABLED;
 		}
 
-		/* Save flags for reg domain usage */
-		geo_ch->orig_flags = geo_ch->flags;
-
 		IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
 				ch->channel, geo_ch->center_freq,
 				is_channel_a_band(ch) ?  "5.2" : "2.4",
@@ -604,16 +622,16 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
 		return 0;
 
 	if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
-		return !(ch_info->fat_extension_channel &
+		return !(ch_info->ht40_extension_channel &
 					IEEE80211_CHAN_NO_HT40PLUS);
 	else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
-		return !(ch_info->fat_extension_channel &
+		return !(ch_info->ht40_extension_channel &
 					IEEE80211_CHAN_NO_HT40MINUS);
 
 	return 0;
 }
 
-u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
+u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
 			 struct ieee80211_sta_ht_cap *sta_ht_inf)
 {
 	struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
@@ -629,11 +647,72 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
 		if (!sta_ht_inf->ht_supported)
 			return 0;
 	}
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if (priv->disable_ht40)
+		return 0;
+#endif
 	return iwl_is_channel_extension(priv, priv->band,
 			le16_to_cpu(priv->staging_rxon.channel),
 			iwl_ht_conf->extension_chan_offset);
 }
-EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
+EXPORT_SYMBOL(iwl_is_ht40_tx_allowed);
+
+static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
+{
+	u16 new_val = 0;
+	u16 beacon_factor = 0;
+
+	beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;
+	new_val = beacon_val / beacon_factor;
+
+	if (!new_val)
+		new_val = max_beacon_val;
+
+	return new_val;
+}
+
+void iwl_setup_rxon_timing(struct iwl_priv *priv)
+{
+	u64 tsf;
+	s32 interval_tm, rem;
+	unsigned long flags;
+	struct ieee80211_conf *conf = NULL;
+	u16 beacon_int;
+
+	conf = ieee80211_get_hw_conf(priv->hw);
+
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
+	priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
+
+	if (priv->iw_mode == NL80211_IFTYPE_STATION) {
+		beacon_int = priv->beacon_int;
+		priv->rxon_timing.atim_window = 0;
+	} else {
+		beacon_int = priv->vif->bss_conf.beacon_int;
+
+		/* TODO: we need to get atim_window from upper stack
+		 * for now we set to 0 */
+		priv->rxon_timing.atim_window = 0;
+	}
+
+	beacon_int = iwl_adjust_beacon_interval(beacon_int,
+				priv->hw_params.max_beacon_itrvl * 1024);
+	priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);
+
+	tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
+	interval_tm = beacon_int * 1024;
+	rem = do_div(tsf, interval_tm);
+	priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	IWL_DEBUG_ASSOC(priv,
+			"beacon interval %d beacon timer %d beacon tim %d\n",
+			le16_to_cpu(priv->rxon_timing.beacon_interval),
+			le32_to_cpu(priv->rxon_timing.beacon_init_val),
+			le16_to_cpu(priv->rxon_timing.atim_window));
+}
+EXPORT_SYMBOL(iwl_setup_rxon_timing);
 
 void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
 {
@@ -805,7 +884,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
 	if (!ht_info->is_ht) {
 		rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
 			RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
-			RXON_FLG_FAT_PROT_MSK |
+			RXON_FLG_HT40_PROT_MSK |
 			RXON_FLG_HT_PROT_MSK);
 		return;
 	}
@@ -816,12 +895,12 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
 	rxon->flags |= cpu_to_le32(ht_info->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
 
 	/* Set up channel bandwidth:
-	 * 20 MHz only, 20/40 mixed or pure 40 if fat ok */
+	 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
 	/* clear the HT channel mode before set the mode */
 	rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
 			 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
-	if (iwl_is_fat_tx_allowed(priv, NULL)) {
-		/* pure 40 fat */
+	if (iwl_is_ht40_tx_allowed(priv, NULL)) {
+		/* pure ht40 */
 		if (ht_info->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
 			rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
 			/* Note: control channel is opposite of extension channel */
@@ -1076,7 +1155,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
 		priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
 	}
 }
-EXPORT_SYMBOL(iwl_set_flags_for_band);
 
 /*
  * initialize rxon structure with default values from eeprom
@@ -1170,7 +1248,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
 
 	for (i = 0; i < hw->n_bitrates; i++) {
 		rate = &(hw->bitrates[i]);
-		if (rate->hw_value < IWL_RATE_COUNT)
+		if (rate->hw_value < IWL_RATE_COUNT_LEGACY)
 			priv->active_rate |= (1 << rate->hw_value);
 	}
 
@@ -1231,8 +1309,190 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
 	IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
 	IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
 }
-#endif
 
+static const char *desc_lookup_text[] = {
+	"OK",
+	"FAIL",
+	"BAD_PARAM",
+	"BAD_CHECKSUM",
+	"NMI_INTERRUPT_WDG",
+	"SYSASSERT",
+	"FATAL_ERROR",
+	"BAD_COMMAND",
+	"HW_ERROR_TUNE_LOCK",
+	"HW_ERROR_TEMPERATURE",
+	"ILLEGAL_CHAN_FREQ",
+	"VCC_NOT_STABLE",
+	"FH_ERROR",
+	"NMI_INTERRUPT_HOST",
+	"NMI_INTERRUPT_ACTION_PT",
+	"NMI_INTERRUPT_UNKNOWN",
+	"UCODE_VERSION_MISMATCH",
+	"HW_ERROR_ABS_LOCK",
+	"HW_ERROR_CAL_LOCK_FAIL",
+	"NMI_INTERRUPT_INST_ACTION_PT",
+	"NMI_INTERRUPT_DATA_ACTION_PT",
+	"NMI_TRM_HW_ER",
+	"NMI_INTERRUPT_TRM",
+	"NMI_INTERRUPT_BREAK_POINT"
+	"DEBUG_0",
+	"DEBUG_1",
+	"DEBUG_2",
+	"DEBUG_3",
+	"UNKNOWN"
+};
+
+static const char *desc_lookup(int i)
+{
+	int max = ARRAY_SIZE(desc_lookup_text) - 1;
+
+	if (i < 0 || i > max)
+		i = max;
+
+	return desc_lookup_text[i];
+}
+
+#define ERROR_START_OFFSET  (1 * sizeof(u32))
+#define ERROR_ELEM_SIZE     (7 * sizeof(u32))
+
+static void iwl_dump_nic_error_log(struct iwl_priv *priv)
+{
+	u32 data2, line;
+	u32 desc, time, count, base, data1;
+	u32 blink1, blink2, ilink1, ilink2;
+
+	if (priv->ucode_type == UCODE_INIT)
+		base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
+	else
+		base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
+
+	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+		IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
+		return;
+	}
+
+	count = iwl_read_targ_mem(priv, base);
+
+	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
+		IWL_ERR(priv, "Start IWL Error Log Dump:\n");
+		IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
+			priv->status, count);
+	}
+
+	desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
+	blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
+	blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
+	ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
+	ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
+	data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
+	data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
+	line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
+	time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
+
+	IWL_ERR(priv, "Desc                               Time       "
+		"data1      data2      line\n");
+	IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
+		desc_lookup(desc), desc, time, data1, data2, line);
+	IWL_ERR(priv, "blink1  blink2  ilink1  ilink2\n");
+	IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
+		ilink1, ilink2);
+
+}
+
+#define EVENT_START_OFFSET  (4 * sizeof(u32))
+
+/**
+ * iwl_print_event_log - Dump error event log to syslog
+ *
+ */
+static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+				u32 num_events, u32 mode)
+{
+	u32 i;
+	u32 base;       /* SRAM byte address of event log header */
+	u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
+	u32 ptr;        /* SRAM byte address of log data */
+	u32 ev, time, data; /* event log data */
+
+	if (num_events == 0)
+		return;
+	if (priv->ucode_type == UCODE_INIT)
+		base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+	else
+		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+
+	if (mode == 0)
+		event_size = 2 * sizeof(u32);
+	else
+		event_size = 3 * sizeof(u32);
+
+	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
+
+	/* "time" is actually "data" for mode 0 (no timestamp).
+	* place event id # at far right for easier visual parsing. */
+	for (i = 0; i < num_events; i++) {
+		ev = iwl_read_targ_mem(priv, ptr);
+		ptr += sizeof(u32);
+		time = iwl_read_targ_mem(priv, ptr);
+		ptr += sizeof(u32);
+		if (mode == 0) {
+			/* data, ev */
+			IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
+		} else {
+			data = iwl_read_targ_mem(priv, ptr);
+			ptr += sizeof(u32);
+			IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
+					time, data, ev);
+		}
+	}
+}
+
+void iwl_dump_nic_event_log(struct iwl_priv *priv)
+{
+	u32 base;       /* SRAM byte address of event log header */
+	u32 capacity;   /* event log capacity in # entries */
+	u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
+	u32 num_wraps;  /* # times uCode wrapped to top of log */
+	u32 next_entry; /* index of next entry to be written by uCode */
+	u32 size;       /* # entries that we'll print */
+
+	if (priv->ucode_type == UCODE_INIT)
+		base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+	else
+		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
+
+	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+		IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
+		return;
+	}
+
+	/* event log header */
+	capacity = iwl_read_targ_mem(priv, base);
+	mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
+	num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
+	next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
+
+	size = num_wraps ? capacity : next_entry;
+
+	/* bail out if nothing in log */
+	if (size == 0) {
+		IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
+		return;
+	}
+
+	IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
+			size, num_wraps);
+
+	/* if uCode has wrapped back to top of log, start at the oldest entry,
+	 * i.e the next one that uCode would fill. */
+	if (num_wraps)
+		iwl_print_event_log(priv, next_entry,
+					capacity - next_entry, mode);
+	/* (then/else) start at top of log */
+	iwl_print_event_log(priv, 0, next_entry, mode);
+
+}
+#endif
 /**
  * iwl_irq_handle_error - called for HW or SW error interrupt from card
  */
@@ -1245,7 +1505,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
 	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & IWL_DL_FW_ERRORS) {
+	if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) {
 		iwl_dump_nic_error_log(priv);
 		iwl_dump_nic_event_log(priv);
 		iwl_print_rx_config_cmd(priv);
@@ -1271,7 +1531,7 @@ EXPORT_SYMBOL(iwl_irq_handle_error);
 void iwl_configure_filter(struct ieee80211_hw *hw,
 			  unsigned int changed_flags,
 			  unsigned int *total_flags,
-			  int mc_count, struct dev_addr_list *mc_list)
+			  u64 multicast)
 {
 	struct iwl_priv *priv = hw->priv;
 	__le32 *filter_flags = &priv->staging_rxon.filter_flags;
@@ -1326,6 +1586,11 @@ int iwl_setup_mac(struct iwl_priv *priv)
 		    IEEE80211_HW_NOISE_DBM |
 		    IEEE80211_HW_AMPDU_AGGREGATION |
 		    IEEE80211_HW_SPECTRUM_MGMT;
+
+	if (!priv->cfg->broken_powersave)
+		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+			     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
 		BIT(NL80211_IFTYPE_ADHOC);
@@ -1335,6 +1600,12 @@ int iwl_setup_mac(struct iwl_priv *priv)
 	/* Firmware does not support this */
 	hw->wiphy->disable_beacon_hints = true;
 
+	/*
+	 * For now, disable PS by default because it affects
+	 * RX performance significantly.
+	 */
+	hw->wiphy->ps_default = false;
+
 	hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
 	/* we create the 802.11 header and a zero-length SSID element */
 	hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
@@ -1364,7 +1635,6 @@ EXPORT_SYMBOL(iwl_setup_mac);
 
 int iwl_set_hw_params(struct iwl_priv *priv)
 {
-	priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto;
 	priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
 	priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
 	if (priv->cfg->mod_params->amsdu_size_8K)
@@ -1373,6 +1643,8 @@ int iwl_set_hw_params(struct iwl_priv *priv)
 		priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_4K;
 	priv->hw_params.max_pkt_size = priv->hw_params.rx_buf_size - 256;
 
+	priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
+
 	if (priv->cfg->mod_params->disable_11n)
 		priv->cfg->sku &= ~IWL_SKU_N;
 
@@ -1419,9 +1691,10 @@ int iwl_init_drv(struct iwl_priv *priv)
 	priv->qos_data.qos_cap.val = 0;
 
 	priv->rates_mask = IWL_RATES_MASK;
-	/* If power management is turned on, default to CAM mode */
-	priv->power_mode = IWL_POWER_MODE_CAM;
-	priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
+	/* Set the tx_power_user_lmt to the lowest power level
+	 * this value will get overwritten by channel max power avg
+	 * from eeprom */
+	priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MIN;
 
 	ret = iwl_init_channel_map(priv);
 	if (ret) {
@@ -1448,6 +1721,8 @@ EXPORT_SYMBOL(iwl_init_drv);
 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 {
 	int ret = 0;
+	s8 prev_tx_power = priv->tx_power_user_lmt;
+
 	if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
 		IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n",
 			 tx_power,
@@ -1455,25 +1730,37 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 		return -EINVAL;
 	}
 
-	if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
-		IWL_WARN(priv, "Requested user TXPOWER %d above upper limit %d.\n",
-			 tx_power,
-			 IWL_TX_POWER_TARGET_POWER_MAX);
+	if (tx_power > priv->tx_power_device_lmt) {
+		IWL_WARN(priv,
+			"Requested user TXPOWER %d above upper limit %d.\n",
+			 tx_power, priv->tx_power_device_lmt);
 		return -EINVAL;
 	}
 
 	if (priv->tx_power_user_lmt != tx_power)
 		force = true;
 
-	priv->tx_power_user_lmt = tx_power;
-
 	/* if nic is not up don't send command */
-	if (!iwl_is_ready_rf(priv))
-		return ret;
-
-	if (force && priv->cfg->ops->lib->send_tx_power)
-		ret = priv->cfg->ops->lib->send_tx_power(priv);
+	if (iwl_is_ready_rf(priv)) {
+		priv->tx_power_user_lmt = tx_power;
+		if (force && priv->cfg->ops->lib->send_tx_power)
+			ret = priv->cfg->ops->lib->send_tx_power(priv);
+		else if (!priv->cfg->ops->lib->send_tx_power)
+			ret = -EOPNOTSUPP;
+		/*
+		 * if fail to set tx_power, restore the orig. tx power
+		 */
+		if (ret)
+			priv->tx_power_user_lmt = prev_tx_power;
+	}
 
+	/*
+	 * Even this is an async host command, the command
+	 * will always report success from uCode
+	 * So once driver can placing the command into the queue
+	 * successfully, driver can use priv->tx_power_user_lmt
+	 * to reflect the current tx power
+	 */
 	return ret;
 }
 EXPORT_SYMBOL(iwl_set_tx_power);
@@ -1487,31 +1774,6 @@ void iwl_uninit_drv(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_uninit_drv);
 
-
-void iwl_disable_interrupts(struct iwl_priv *priv)
-{
-	clear_bit(STATUS_INT_ENABLED, &priv->status);
-
-	/* disable interrupts from uCode/NIC to host */
-	iwl_write32(priv, CSR_INT_MASK, 0x00000000);
-
-	/* acknowledge/clear/reset any interrupts still pending
-	 * from uCode or flow handler (Rx/Tx DMA) */
-	iwl_write32(priv, CSR_INT, 0xffffffff);
-	iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
-	IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
-}
-EXPORT_SYMBOL(iwl_disable_interrupts);
-
-void iwl_enable_interrupts(struct iwl_priv *priv)
-{
-	IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
-	set_bit(STATUS_INT_ENABLED, &priv->status);
-	iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
-}
-EXPORT_SYMBOL(iwl_enable_interrupts);
-
-
 #define ICT_COUNT (PAGE_SIZE/sizeof(u32))
 
 /* Free dram table */
@@ -1581,7 +1843,7 @@ int iwl_reset_ict(struct iwl_priv *priv)
 	spin_lock_irqsave(&priv->lock, flags);
 	iwl_disable_interrupts(priv);
 
-	memset(&priv->ict_tbl[0],0, sizeof(u32) * ICT_COUNT);
+	memset(&priv->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
 
 	val = priv->aligned_ict_tbl_dma >> PAGE_SHIFT;
 
@@ -1659,13 +1921,13 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
 	/* read all entries that not 0 start with ict_index */
 	while (priv->ict_tbl[priv->ict_index]) {
 
-		val |= priv->ict_tbl[priv->ict_index];
+		val |= le32_to_cpu(priv->ict_tbl[priv->ict_index]);
 		IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
-					priv->ict_index,
-					priv->ict_tbl[priv->ict_index]);
+				priv->ict_index,
+				le32_to_cpu(priv->ict_tbl[priv->ict_index]));
 		priv->ict_tbl[priv->ict_index] = 0;
 		priv->ict_index = iwl_queue_inc_wrap(priv->ict_index,
-								ICT_COUNT);
+						     ICT_COUNT);
 
 	}
 
@@ -1745,7 +2007,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
 	}
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & (IWL_DL_ISR)) {
+	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
 		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
 		IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
 			      "fh 0x%08x\n", inta, inta_mask, inta_fh);
@@ -1852,7 +2114,7 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
 	u32 stat_flags = 0;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_STATISTICS_CMD,
-		.meta.flags = flags,
+		.flags = flags,
 		.len = sizeof(stat_flags),
 		.data = (u8 *) &stat_flags,
 	};
@@ -1984,194 +2246,10 @@ int iwl_verify_ucode(struct iwl_priv *priv)
 EXPORT_SYMBOL(iwl_verify_ucode);
 
 
-static const char *desc_lookup_text[] = {
-	"OK",
-	"FAIL",
-	"BAD_PARAM",
-	"BAD_CHECKSUM",
-	"NMI_INTERRUPT_WDG",
-	"SYSASSERT",
-	"FATAL_ERROR",
-	"BAD_COMMAND",
-	"HW_ERROR_TUNE_LOCK",
-	"HW_ERROR_TEMPERATURE",
-	"ILLEGAL_CHAN_FREQ",
-	"VCC_NOT_STABLE",
-	"FH_ERROR",
-	"NMI_INTERRUPT_HOST",
-	"NMI_INTERRUPT_ACTION_PT",
-	"NMI_INTERRUPT_UNKNOWN",
-	"UCODE_VERSION_MISMATCH",
-	"HW_ERROR_ABS_LOCK",
-	"HW_ERROR_CAL_LOCK_FAIL",
-	"NMI_INTERRUPT_INST_ACTION_PT",
-	"NMI_INTERRUPT_DATA_ACTION_PT",
-	"NMI_TRM_HW_ER",
-	"NMI_INTERRUPT_TRM",
-	"NMI_INTERRUPT_BREAK_POINT"
-	"DEBUG_0",
-	"DEBUG_1",
-	"DEBUG_2",
-	"DEBUG_3",
-	"UNKNOWN"
-};
-
-static const char *desc_lookup(int i)
-{
-	int max = ARRAY_SIZE(desc_lookup_text) - 1;
-
-	if (i < 0 || i > max)
-		i = max;
-
-	return desc_lookup_text[i];
-}
-
-#define ERROR_START_OFFSET  (1 * sizeof(u32))
-#define ERROR_ELEM_SIZE     (7 * sizeof(u32))
-
-void iwl_dump_nic_error_log(struct iwl_priv *priv)
-{
-	u32 data2, line;
-	u32 desc, time, count, base, data1;
-	u32 blink1, blink2, ilink1, ilink2;
-
-	if (priv->ucode_type == UCODE_INIT)
-		base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
-	else
-		base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
-
-	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
-		IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
-		return;
-	}
-
-	count = iwl_read_targ_mem(priv, base);
-
-	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
-		IWL_ERR(priv, "Start IWL Error Log Dump:\n");
-		IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
-			priv->status, count);
-	}
-
-	desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
-	blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
-	blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
-	ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
-	ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
-	data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
-	data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
-	line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
-	time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
-
-	IWL_ERR(priv, "Desc                               Time       "
-		"data1      data2      line\n");
-	IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
-		desc_lookup(desc), desc, time, data1, data2, line);
-	IWL_ERR(priv, "blink1  blink2  ilink1  ilink2\n");
-	IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
-		ilink1, ilink2);
-
-}
-EXPORT_SYMBOL(iwl_dump_nic_error_log);
-
-#define EVENT_START_OFFSET  (4 * sizeof(u32))
-
-/**
- * iwl_print_event_log - Dump error event log to syslog
- *
- */
-static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
-				u32 num_events, u32 mode)
-{
-	u32 i;
-	u32 base;       /* SRAM byte address of event log header */
-	u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
-	u32 ptr;        /* SRAM byte address of log data */
-	u32 ev, time, data; /* event log data */
-
-	if (num_events == 0)
-		return;
-	if (priv->ucode_type == UCODE_INIT)
-		base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
-	else
-		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-
-	if (mode == 0)
-		event_size = 2 * sizeof(u32);
-	else
-		event_size = 3 * sizeof(u32);
-
-	ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
-
-	/* "time" is actually "data" for mode 0 (no timestamp).
-	* place event id # at far right for easier visual parsing. */
-	for (i = 0; i < num_events; i++) {
-		ev = iwl_read_targ_mem(priv, ptr);
-		ptr += sizeof(u32);
-		time = iwl_read_targ_mem(priv, ptr);
-		ptr += sizeof(u32);
-		if (mode == 0) {
-			/* data, ev */
-			IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
-		} else {
-			data = iwl_read_targ_mem(priv, ptr);
-			ptr += sizeof(u32);
-			IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
-					time, data, ev);
-		}
-	}
-}
-
-void iwl_dump_nic_event_log(struct iwl_priv *priv)
-{
-	u32 base;       /* SRAM byte address of event log header */
-	u32 capacity;   /* event log capacity in # entries */
-	u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
-	u32 num_wraps;  /* # times uCode wrapped to top of log */
-	u32 next_entry; /* index of next entry to be written by uCode */
-	u32 size;       /* # entries that we'll print */
-
-	if (priv->ucode_type == UCODE_INIT)
-		base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
-	else
-		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-
-	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
-		IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
-		return;
-	}
-
-	/* event log header */
-	capacity = iwl_read_targ_mem(priv, base);
-	mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
-	num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
-	next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
-
-	size = num_wraps ? capacity : next_entry;
-
-	/* bail out if nothing in log */
-	if (size == 0) {
-		IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
-		return;
-	}
-
-	IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
-			size, num_wraps);
-
-	/* if uCode has wrapped back to top of log, start at the oldest entry,
-	 * i.e the next one that uCode would fill. */
-	if (num_wraps)
-		iwl_print_event_log(priv, next_entry,
-					capacity - next_entry, mode);
-	/* (then/else) start at top of log */
-	iwl_print_event_log(priv, 0, next_entry, mode);
-
-}
-EXPORT_SYMBOL(iwl_dump_nic_event_log);
-
 void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 {
 	struct iwl_ct_kill_config cmd;
+	struct iwl_ct_kill_throttling_config adv_cmd;
 	unsigned long flags;
 	int ret = 0;
 
@@ -2179,18 +2257,44 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
 		    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
 	spin_unlock_irqrestore(&priv->lock, flags);
+	priv->thermal_throttle.ct_kill_toggle = false;
+
+	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+	case CSR_HW_REV_TYPE_1000:
+	case CSR_HW_REV_TYPE_6x00:
+	case CSR_HW_REV_TYPE_6x50:
+		adv_cmd.critical_temperature_enter =
+			cpu_to_le32(priv->hw_params.ct_kill_threshold);
+		adv_cmd.critical_temperature_exit =
+			cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
+
+		ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+				       sizeof(adv_cmd), &adv_cmd);
+		if (ret)
+			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+		else
+			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+					"succeeded, "
+					"critical temperature enter is %d,"
+					"exit is %d\n",
+				       priv->hw_params.ct_kill_threshold,
+				       priv->hw_params.ct_kill_exit_threshold);
+		break;
+	default:
+		cmd.critical_temperature_R =
+			cpu_to_le32(priv->hw_params.ct_kill_threshold);
 
-	cmd.critical_temperature_R =
-		cpu_to_le32(priv->hw_params.ct_kill_threshold);
-
-	ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
-			       sizeof(cmd), &cmd);
-	if (ret)
-		IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
-	else
-		IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD succeeded, "
-			"critical temperature is %d\n",
-			cmd.critical_temperature_R);
+		ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+				       sizeof(cmd), &cmd);
+		if (ret)
+			IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
+		else
+			IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
+					"succeeded, "
+					"critical temperature is %d\n",
+					priv->hw_params.ct_kill_threshold);
+		break;
+	}
 }
 EXPORT_SYMBOL(iwl_rf_kill_ct_config);
 
@@ -2211,12 +2315,11 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
 		.id = REPLY_CARD_STATE_CMD,
 		.len = sizeof(u32),
 		.data = &flags,
-		.meta.flags = meta_flag,
+		.flags = meta_flag,
 	};
 
 	return iwl_send_cmd(priv, &cmd);
 }
-EXPORT_SYMBOL(iwl_send_card_state);
 
 void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
 			   struct iwl_rx_mem_buffer *rxb)
@@ -2234,10 +2337,11 @@ void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
 				      struct iwl_rx_mem_buffer *rxb)
 {
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+	u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
 	IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
-			"notification for %s:\n",
-			le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
-	iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+			"notification for %s:\n", len,
+			get_cmd_string(pkt->hdr.cmd));
+	iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
 }
 EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
 
@@ -2260,7 +2364,6 @@ void iwl_clear_isr_stats(struct iwl_priv *priv)
 {
 	memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
 }
-EXPORT_SYMBOL(iwl_clear_isr_stats);
 
 int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
 			   const struct ieee80211_tx_queue_params *params)
@@ -2333,39 +2436,10 @@ static void iwl_ht_conf(struct iwl_priv *priv,
 	}
 	ht_conf = &sta->ht_cap;
 
-	if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
-		iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
-	if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
-		iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
-
-	iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
-	iwl_conf->max_amsdu_size =
-		!!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
-	iwl_conf->supported_chan_width =
-		!!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-
-	/*
-	 * XXX: The HT configuration needs to be moved into iwl_mac_config()
-	 *	to be done there correctly.
-	 */
-
-	iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
-	if (conf_is_ht40_minus(&priv->hw->conf))
-		iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-	else if (conf_is_ht40_plus(&priv->hw->conf))
-		iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-
-	/* If no above or below channel supplied disable FAT channel */
-	if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
-	    iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
-		iwl_conf->supported_chan_width = 0;
-
 	iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
 
 	memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
 
-	iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
 	iwl_conf->ht_protection =
 		bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
 	iwl_conf->non_GF_STA_present =
@@ -2492,7 +2566,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
 		if (bss_conf->assoc) {
 			priv->assoc_id = bss_conf->aid;
 			priv->beacon_int = bss_conf->beacon_int;
-			priv->power_data.dtim_period = bss_conf->dtim_period;
 			priv->timestamp = bss_conf->timestamp;
 			priv->assoc_capability = bss_conf->assoc_capability;
 
@@ -2679,6 +2752,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
 	struct iwl_priv *priv = hw->priv;
 	const struct iwl_channel_info *ch_info;
 	struct ieee80211_conf *conf = &hw->conf;
+	struct iwl_ht_info *ht_conf = &priv->current_ht_config;
 	unsigned long flags = 0;
 	int ret = 0;
 	u16 ch;
@@ -2720,10 +2794,32 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
 			goto set_ch_out;
 		}
 
-		priv->current_ht_config.is_ht = conf_is_ht(conf);
-
 		spin_lock_irqsave(&priv->lock, flags);
 
+		/* Configure HT40 channels */
+		ht_conf->is_ht = conf_is_ht(conf);
+		if (ht_conf->is_ht) {
+			if (conf_is_ht40_minus(conf)) {
+				ht_conf->extension_chan_offset =
+					IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+				ht_conf->supported_chan_width =
+					IWL_CHANNEL_WIDTH_40MHZ;
+			} else if (conf_is_ht40_plus(conf)) {
+				ht_conf->extension_chan_offset =
+					IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+				ht_conf->supported_chan_width =
+					IWL_CHANNEL_WIDTH_40MHZ;
+			} else {
+				ht_conf->extension_chan_offset =
+					IEEE80211_HT_PARAM_CHA_SEC_NONE;
+				ht_conf->supported_chan_width =
+					IWL_CHANNEL_WIDTH_20MHZ;
+			}
+		} else
+			ht_conf->supported_chan_width = IWL_CHANNEL_WIDTH_20MHZ;
+		/* Default to no protection. Protection mode will later be set
+		 * from BSS config in iwl_ht_conf */
+		ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
 
 		/* if we are switching from ht to 2.4 clear flags
 		 * from any ht related info since 2.4 does not
@@ -2742,13 +2838,10 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
 		iwl_set_rate(priv);
 	}
 
-	if (changed & IEEE80211_CONF_CHANGE_PS &&
-	    priv->iw_mode == NL80211_IFTYPE_STATION) {
-		priv->power_data.power_disabled =
-			!(conf->flags & IEEE80211_CONF_PS);
-		ret = iwl_power_update_mode(priv, 0);
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		ret = iwl_power_update_mode(priv, false);
 		if (ret)
-			IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
+			IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
 	}
 
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -2881,6 +2974,248 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 }
 EXPORT_SYMBOL(iwl_mac_reset_tsf);
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+
+#define IWL_TRAFFIC_DUMP_SIZE	(IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
+
+void iwl_reset_traffic_log(struct iwl_priv *priv)
+{
+	priv->tx_traffic_idx = 0;
+	priv->rx_traffic_idx = 0;
+	if (priv->tx_traffic)
+		memset(priv->tx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE);
+	if (priv->rx_traffic)
+		memset(priv->rx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE);
+}
+
+int iwl_alloc_traffic_mem(struct iwl_priv *priv)
+{
+	u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE;
+
+	if (iwl_debug_level & IWL_DL_TX) {
+		if (!priv->tx_traffic) {
+			priv->tx_traffic =
+				kzalloc(traffic_size, GFP_KERNEL);
+			if (!priv->tx_traffic)
+				return -ENOMEM;
+		}
+	}
+	if (iwl_debug_level & IWL_DL_RX) {
+		if (!priv->rx_traffic) {
+			priv->rx_traffic =
+				kzalloc(traffic_size, GFP_KERNEL);
+			if (!priv->rx_traffic)
+				return -ENOMEM;
+		}
+	}
+	iwl_reset_traffic_log(priv);
+	return 0;
+}
+EXPORT_SYMBOL(iwl_alloc_traffic_mem);
+
+void iwl_free_traffic_mem(struct iwl_priv *priv)
+{
+	kfree(priv->tx_traffic);
+	priv->tx_traffic = NULL;
+
+	kfree(priv->rx_traffic);
+	priv->rx_traffic = NULL;
+}
+EXPORT_SYMBOL(iwl_free_traffic_mem);
+
+void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
+		      u16 length, struct ieee80211_hdr *header)
+{
+	__le16 fc;
+	u16 len;
+
+	if (likely(!(iwl_debug_level & IWL_DL_TX)))
+		return;
+
+	if (!priv->tx_traffic)
+		return;
+
+	fc = header->frame_control;
+	if (ieee80211_is_data(fc)) {
+		len = (length > IWL_TRAFFIC_ENTRY_SIZE)
+		       ? IWL_TRAFFIC_ENTRY_SIZE : length;
+		memcpy((priv->tx_traffic +
+		       (priv->tx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)),
+		       header, len);
+		priv->tx_traffic_idx =
+			(priv->tx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES;
+	}
+}
+EXPORT_SYMBOL(iwl_dbg_log_tx_data_frame);
+
+void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
+		      u16 length, struct ieee80211_hdr *header)
+{
+	__le16 fc;
+	u16 len;
+
+	if (likely(!(iwl_debug_level & IWL_DL_RX)))
+		return;
+
+	if (!priv->rx_traffic)
+		return;
+
+	fc = header->frame_control;
+	if (ieee80211_is_data(fc)) {
+		len = (length > IWL_TRAFFIC_ENTRY_SIZE)
+		       ? IWL_TRAFFIC_ENTRY_SIZE : length;
+		memcpy((priv->rx_traffic +
+		       (priv->rx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)),
+		       header, len);
+		priv->rx_traffic_idx =
+			(priv->rx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES;
+	}
+}
+EXPORT_SYMBOL(iwl_dbg_log_rx_data_frame);
+
+const char *get_mgmt_string(int cmd)
+{
+	switch (cmd) {
+		IWL_CMD(MANAGEMENT_ASSOC_REQ);
+		IWL_CMD(MANAGEMENT_ASSOC_RESP);
+		IWL_CMD(MANAGEMENT_REASSOC_REQ);
+		IWL_CMD(MANAGEMENT_REASSOC_RESP);
+		IWL_CMD(MANAGEMENT_PROBE_REQ);
+		IWL_CMD(MANAGEMENT_PROBE_RESP);
+		IWL_CMD(MANAGEMENT_BEACON);
+		IWL_CMD(MANAGEMENT_ATIM);
+		IWL_CMD(MANAGEMENT_DISASSOC);
+		IWL_CMD(MANAGEMENT_AUTH);
+		IWL_CMD(MANAGEMENT_DEAUTH);
+		IWL_CMD(MANAGEMENT_ACTION);
+	default:
+		return "UNKNOWN";
+
+	}
+}
+
+const char *get_ctrl_string(int cmd)
+{
+	switch (cmd) {
+		IWL_CMD(CONTROL_BACK_REQ);
+		IWL_CMD(CONTROL_BACK);
+		IWL_CMD(CONTROL_PSPOLL);
+		IWL_CMD(CONTROL_RTS);
+		IWL_CMD(CONTROL_CTS);
+		IWL_CMD(CONTROL_ACK);
+		IWL_CMD(CONTROL_CFEND);
+		IWL_CMD(CONTROL_CFENDACK);
+	default:
+		return "UNKNOWN";
+
+	}
+}
+
+void iwl_clear_tx_stats(struct iwl_priv *priv)
+{
+	memset(&priv->tx_stats, 0, sizeof(struct traffic_stats));
+
+}
+
+void iwl_clear_rx_stats(struct iwl_priv *priv)
+{
+	memset(&priv->rx_stats, 0, sizeof(struct traffic_stats));
+}
+
+/*
+ * if CONFIG_IWLWIFI_DEBUGFS defined, iwl_update_stats function will
+ * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass.
+ * Use debugFs to display the rx/rx_statistics
+ * if CONFIG_IWLWIFI_DEBUGFS not being defined, then no MGMT and CTRL
+ * information will be recorded, but DATA pkt still will be recorded
+ * for the reason of iwl_led.c need to control the led blinking based on
+ * number of tx and rx data.
+ *
+ */
+void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
+{
+	struct traffic_stats	*stats;
+
+	if (is_tx)
+		stats = &priv->tx_stats;
+	else
+		stats = &priv->rx_stats;
+
+	if (ieee80211_is_mgmt(fc)) {
+		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+		case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+			stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+			stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+			stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
+			stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
+			stats->mgmt[MANAGEMENT_PROBE_REQ]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+			stats->mgmt[MANAGEMENT_PROBE_RESP]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_BEACON):
+			stats->mgmt[MANAGEMENT_BEACON]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_ATIM):
+			stats->mgmt[MANAGEMENT_ATIM]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+			stats->mgmt[MANAGEMENT_DISASSOC]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_AUTH):
+			stats->mgmt[MANAGEMENT_AUTH]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+			stats->mgmt[MANAGEMENT_DEAUTH]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_ACTION):
+			stats->mgmt[MANAGEMENT_ACTION]++;
+			break;
+		}
+	} else if (ieee80211_is_ctl(fc)) {
+		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+		case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
+			stats->ctrl[CONTROL_BACK_REQ]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_BACK):
+			stats->ctrl[CONTROL_BACK]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
+			stats->ctrl[CONTROL_PSPOLL]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_RTS):
+			stats->ctrl[CONTROL_RTS]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_CTS):
+			stats->ctrl[CONTROL_CTS]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_ACK):
+			stats->ctrl[CONTROL_ACK]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_CFEND):
+			stats->ctrl[CONTROL_CFEND]++;
+			break;
+		case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
+			stats->ctrl[CONTROL_CFENDACK]++;
+			break;
+		}
+	} else {
+		/* data */
+		stats->data_cnt++;
+		stats->data_bytes += len;
+	}
+}
+EXPORT_SYMBOL(iwl_update_stats);
+#endif
+
 #ifdef CONFIG_PM
 
 int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index dabf663..7ff9ffb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -83,6 +83,8 @@ struct iwl_cmd;
 #define IWL_SKU_A       0x2
 #define IWL_SKU_N       0x8
 
+#define IWL_CMD(x) case x: return #x
+
 struct iwl_hcmd_ops {
 	int (*rxon_assoc)(struct iwl_priv *priv);
 	int (*commit_rxon)(struct iwl_priv *priv);
@@ -116,6 +118,17 @@ struct iwl_temp_ops {
 	void (*set_ct_kill)(struct iwl_priv *priv);
 };
 
+struct iwl_ucode_ops {
+	u32 (*get_header_size)(u32);
+	u32 (*get_build)(const struct iwl_ucode_header *, u32);
+	u32 (*get_inst_size)(const struct iwl_ucode_header *, u32);
+	u32 (*get_data_size)(const struct iwl_ucode_header *, u32);
+	u32 (*get_init_size)(const struct iwl_ucode_header *, u32);
+	u32 (*get_init_data_size)(const struct iwl_ucode_header *, u32);
+	u32 (*get_boot_size)(const struct iwl_ucode_header *, u32);
+	u8 * (*get_data)(const struct iwl_ucode_header *, u32);
+};
+
 struct iwl_lib_ops {
 	/* set hw dependent parameters */
 	int (*set_hw_params)(struct iwl_priv *priv);
@@ -171,6 +184,7 @@ struct iwl_lib_ops {
 };
 
 struct iwl_ops {
+	const struct iwl_ucode_ops *ucode;
 	const struct iwl_lib_ops *lib;
 	const struct iwl_hcmd_ops *hcmd;
 	const struct iwl_hcmd_utils_ops *utils;
@@ -178,7 +192,6 @@ struct iwl_ops {
 
 struct iwl_mod_params {
 	int sw_crypto;		/* def: 0 = using hardware encryption */
-	u32 debug;		/* def: 0 = minimal debug log messages */
 	int disable_hw_scan;	/* def: 0 = use h/w scan */
 	int num_of_queues;	/* def: HW dependent */
 	int num_of_ampdu_queues;/* def: HW dependent */
@@ -195,6 +208,9 @@ struct iwl_mod_params {
  * 	filename is constructed as fw_name_pre<api>.ucode.
  * @ucode_api_max: Highest version of uCode API supported by driver.
  * @ucode_api_min: Lowest version of uCode API supported by driver.
+ * @pa_type: used by 6000 series only to identify the type of Power Amplifier
+ * @max_ll_items: max number of OTP blocks
+ * @shadow_ram_support: shadow support for OTP memory
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -215,6 +231,7 @@ struct iwl_mod_params {
  * iwl_hcmd_utils_ops etc. we accommodate different command structures
  * and flows between hardware versions (4965/5000) as well as their API
  * versions.
+ *
  */
 struct iwl_cfg {
 	const char *name;
@@ -231,6 +248,11 @@ struct iwl_cfg {
 	u8   valid_rx_ant;
 	bool need_pll_cfg;
 	bool use_isr_legacy;
+	enum iwl_pa_type pa_type;
+	const u16 max_ll_items;
+	const bool shadow_ram_support;
+	const bool ht_greenfield_support;
+	const bool broken_powersave;
 };
 
 /***************************
@@ -250,7 +272,7 @@ int iwl_full_rxon_required(struct iwl_priv *priv);
 void iwl_set_rxon_chain(struct iwl_priv *priv);
 int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
 void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
-u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
+u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
 			 struct ieee80211_sta_ht_cap *sta_ht_inf);
 void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band);
 void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode);
@@ -261,8 +283,7 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
 void iwl_irq_handle_error(struct iwl_priv *priv);
 void iwl_configure_filter(struct ieee80211_hw *hw,
 			  unsigned int changed_flags,
-			  unsigned int *total_flags,
-			  int mc_count, struct dev_addr_list *mc_list);
+			  unsigned int *total_flags, u64 multicast);
 int iwl_hw_nic_init(struct iwl_priv *priv);
 int iwl_setup_mac(struct iwl_priv *priv);
 int iwl_set_hw_params(struct iwl_priv *priv);
@@ -286,7 +307,55 @@ void iwl_config_ap(struct iwl_priv *priv);
 int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
 			 struct ieee80211_tx_queue_stats *stats);
 void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+int iwl_alloc_traffic_mem(struct iwl_priv *priv);
+void iwl_free_traffic_mem(struct iwl_priv *priv);
+void iwl_reset_traffic_log(struct iwl_priv *priv);
+void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
+				u16 length, struct ieee80211_hdr *header);
+void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
+				u16 length, struct ieee80211_hdr *header);
+const char *get_mgmt_string(int cmd);
+const char *get_ctrl_string(int cmd);
+void iwl_clear_tx_stats(struct iwl_priv *priv);
+void iwl_clear_rx_stats(struct iwl_priv *priv);
+void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc,
+		      u16 len);
+#else
+static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv)
+{
+	return 0;
+}
+static inline void iwl_free_traffic_mem(struct iwl_priv *priv)
+{
+}
+static inline void iwl_reset_traffic_log(struct iwl_priv *priv)
+{
+}
+static inline void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
+		      u16 length, struct ieee80211_hdr *header)
+{
+}
+static inline void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
+		      u16 length, struct ieee80211_hdr *header)
+{
+}
+static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
+				    __le16 fc, u16 len)
+{
+	struct traffic_stats	*stats;
+
+	if (is_tx)
+		stats = &priv->tx_stats;
+	else
+		stats = &priv->rx_stats;
 
+	if (ieee80211_is_data(fc)) {
+		/* data */
+		stats->data_bytes += len;
+	}
+}
+#endif
 /*****************************************************
  * RX handlers.
  * **************************************************/
@@ -355,6 +424,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
 void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
 			      struct ieee80211_tx_info *info);
 int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
+int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
 
 u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
 
@@ -384,7 +454,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
 void iwl_init_scan_params(struct iwl_priv *priv);
 int iwl_scan_cancel(struct iwl_priv *priv);
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
-int iwl_scan_initiate(struct iwl_priv *priv);
 int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
 u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
 		       const u8 *ie, int ie_len, int left);
@@ -398,7 +467,6 @@ void iwl_bg_scan_check(struct work_struct *data);
 void iwl_bg_abort_scan(struct work_struct *work);
 void iwl_bg_scan_completed(struct work_struct *work);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
-int iwl_send_scan_abort(struct iwl_priv *priv);
 
 /* For faster active scanning, scan will move to the next channel if fewer than
  * PLCP_QUIET_THRESH packets are heard on this channel within
@@ -437,9 +505,9 @@ int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id,
 				  u16 len, const void *data);
 int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
 			   const void *data,
-			   int (*callback)(struct iwl_priv *priv,
-					   struct iwl_cmd *cmd,
-					   struct sk_buff *skb));
+			   void (*callback)(struct iwl_priv *priv,
+					    struct iwl_device_cmd *cmd,
+					    struct sk_buff *skb));
 
 int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
 
@@ -449,8 +517,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
 /*****************************************************
  * PCI						     *
  *****************************************************/
-void iwl_disable_interrupts(struct iwl_priv *priv);
-void iwl_enable_interrupts(struct iwl_priv *priv);
 irqreturn_t iwl_isr_legacy(int irq, void *data);
 int iwl_reset_ict(struct iwl_priv *priv);
 void iwl_disable_ict(struct iwl_priv *priv);
@@ -474,7 +540,6 @@ int iwl_pci_resume(struct pci_dev *pdev);
 /*****************************************************
 *  Error Handling Debugging
 ******************************************************/
-void iwl_dump_nic_error_log(struct iwl_priv *priv);
 void iwl_dump_nic_event_log(struct iwl_priv *priv);
 void iwl_clear_isr_stats(struct iwl_priv *priv);
 
@@ -556,6 +621,7 @@ extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
 void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
 					   struct iwl_rx_mem_buffer *rxb);
 
+void iwl_setup_rxon_timing(struct iwl_priv *priv);
 static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
 {
 	return priv->cfg->ops->hcmd->rxon_assoc(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f03dae1..06437d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -91,7 +91,8 @@
 #define CSR_EEPROM_GP           (CSR_BASE+0x030)
 #define CSR_OTP_GP_REG   	(CSR_BASE+0x034)
 #define CSR_GIO_REG		(CSR_BASE+0x03C)
-#define CSR_GP_UCODE		(CSR_BASE+0x044)
+#define CSR_GP_UCODE_REG	(CSR_BASE+0x048)
+#define CSR_GP_DRIVER_REG	(CSR_BASE+0x050)
 #define CSR_UCODE_DRV_GP1       (CSR_BASE+0x054)
 #define CSR_UCODE_DRV_GP1_SET   (CSR_BASE+0x058)
 #define CSR_UCODE_DRV_GP1_CLR   (CSR_BASE+0x05c)
@@ -245,6 +246,13 @@
 #define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED           (0x00000004)
 #define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT      (0x00000008)
 
+/* GP Driver */
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_MSK	    (0x00000003)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB	    (0x00000000)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB	    (0x00000001)
+#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA	    (0x00000002)
+
+
 /* GI Chicken Bits */
 #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX  (0x00800000)
 #define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER  (0x20000000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 2cf014f..cbc6290 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -30,16 +30,23 @@
 #define __iwl_debug_h__
 
 struct iwl_priv;
+extern u32 iwl_debug_level;
 
 #define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a)
 #define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a)
 #define IWL_INFO(p, f, a...) dev_info(&((p)->pci_dev->dev), f, ## a)
 #define IWL_CRIT(p, f, a...) dev_crit(&((p)->pci_dev->dev), f, ## a)
 
+#define iwl_print_hex_error(priv, p, len) 				\
+do {									\
+	print_hex_dump(KERN_ERR, "iwl data: ",				\
+		       DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);		\
+} while (0)
+
 #ifdef CONFIG_IWLWIFI_DEBUG
 #define IWL_DEBUG(__priv, level, fmt, args...)				\
 do {									\
-	if (__priv->debug_level & (level))				\
+	if (iwl_get_debug_level(__priv) & (level))					\
 		dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev),		\
 			 "%c %s " fmt, in_interrupt() ? 'I' : 'U',	\
 			__func__ , ## args);				\
@@ -47,7 +54,7 @@ do {									\
 
 #define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)			\
 do {									\
-	if ((__priv->debug_level & (level)) && net_ratelimit())		\
+	if ((iwl_get_debug_level(__priv) & (level)) && net_ratelimit())		\
 		dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev),		\
 			"%c %s " fmt, in_interrupt() ? 'I' : 'U',	\
 			 __func__ , ## args);				\
@@ -55,7 +62,7 @@ do {									\
 
 #define iwl_print_hex_dump(priv, level, p, len) 			\
 do {                                            			\
-	if (priv->debug_level & level)          			\
+	if (iwl_get_debug_level(priv) & level) 				\
 		print_hex_dump(KERN_DEBUG, "iwl data: ",		\
 			       DUMP_PREFIX_OFFSET, 16, 1, p, len, 1);	\
 } while (0)
@@ -65,23 +72,43 @@ struct iwl_debugfs {
 	const char *name;
 	struct dentry *dir_drv;
 	struct dentry *dir_data;
+	struct dentry *dir_debug;
 	struct dentry *dir_rf;
 	struct dir_data_files {
 		struct dentry *file_sram;
 		struct dentry *file_nvm;
 		struct dentry *file_stations;
-		struct dentry *file_rx_statistics;
-		struct dentry *file_tx_statistics;
 		struct dentry *file_log_event;
 		struct dentry *file_channels;
 		struct dentry *file_status;
 		struct dentry *file_interrupt;
+		struct dentry *file_qos;
+		struct dentry *file_thermal_throttling;
+#ifdef CONFIG_IWLWIFI_LEDS
+		struct dentry *file_led;
+#endif
+		struct dentry *file_disable_ht40;
+		struct dentry *file_sleep_level_override;
+		struct dentry *file_current_sleep_command;
 	} dbgfs_data_files;
 	struct dir_rf_files {
 		struct dentry *file_disable_sensitivity;
 		struct dentry *file_disable_chain_noise;
 		struct dentry *file_disable_tx_power;
 	} dbgfs_rf_files;
+	struct dir_debug_files {
+		struct dentry *file_rx_statistics;
+		struct dentry *file_tx_statistics;
+		struct dentry *file_traffic_log;
+		struct dentry *file_rx_queue;
+		struct dentry *file_tx_queue;
+		struct dentry *file_ucode_rx_stats;
+		struct dentry *file_ucode_tx_stats;
+		struct dentry *file_ucode_general_stats;
+		struct dentry *file_sensitivity;
+		struct dentry *file_chain_noise;
+		struct dentry *file_tx_power;
+	} dbgfs_debug_files;
 	u32 sram_offset;
 	u32 sram_len;
 };
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index ca00cc8..fb84485 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -38,7 +38,7 @@
 #include "iwl-debug.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
-
+#include "iwl-calib.h"
 
 /* create and remove of files */
 #define DEBUGFS_ADD_DIR(name, parent) do {                              \
@@ -49,7 +49,8 @@
 
 #define DEBUGFS_ADD_FILE(name, parent) do {                             \
 	dbgfs->dbgfs_##parent##_files.file_##name =                     \
-	debugfs_create_file(#name, 0644, dbgfs->dir_##parent, priv,     \
+	debugfs_create_file(#name, S_IWUSR | S_IRUSR,                   \
+				dbgfs->dir_##parent, priv,              \
 				&iwl_dbgfs_##name##_ops);               \
 	if (!(dbgfs->dbgfs_##parent##_files.file_##name))               \
 		goto err;                                               \
@@ -57,7 +58,8 @@
 
 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do {                        \
 	dbgfs->dbgfs_##parent##_files.file_##name =                     \
-	debugfs_create_bool(#name, 0644, dbgfs->dir_##parent, ptr);     \
+	debugfs_create_bool(#name, S_IWUSR | S_IRUSR,                   \
+			    dbgfs->dir_##parent, ptr);                  \
 	if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)		\
 			|| !dbgfs->dbgfs_##parent##_files.file_##name)	\
 		goto err;                                               \
@@ -65,7 +67,7 @@
 
 #define DEBUGFS_ADD_X32(name, parent, ptr) do {                        \
 	dbgfs->dbgfs_##parent##_files.file_##name =                     \
-	debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr);     \
+	debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr);   \
 	if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name)		\
 			|| !dbgfs->dbgfs_##parent##_files.file_##name)	\
 		goto err;                                               \
@@ -124,18 +126,58 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
 						size_t count, loff_t *ppos) {
 
 	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
-	char buf[256];
+	char *buf;
 	int pos = 0;
-	const size_t bufsz = sizeof(buf);
 
-	pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n",
-						priv->tx_stats[0].cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n",
-						priv->tx_stats[1].cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n",
-						priv->tx_stats[2].cnt);
+	int cnt;
+	ssize_t ret;
+	const size_t bufsz = 100 + sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX);
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
+	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "\t%s\t\t: %u\n",
+				 get_mgmt_string(cnt),
+				 priv->tx_stats.mgmt[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
+	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "\t%s\t\t: %u\n",
+				 get_ctrl_string(cnt),
+				 priv->tx_stats.ctrl[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
+			 priv->tx_stats.data_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
+			 priv->tx_stats.data_bytes);
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
 
-	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+static ssize_t iwl_dbgfs_tx_statistics_write(struct file *file,
+					const char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	u32 clear_flag;
+	char buf[8];
+	int buf_size;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%x", &clear_flag) != 1)
+		return -EFAULT;
+	if (clear_flag == 1)
+		iwl_clear_tx_stats(priv);
+
+	return count;
 }
 
 static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
@@ -143,18 +185,59 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
 						size_t count, loff_t *ppos) {
 
 	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
-	char buf[256];
+	char *buf;
 	int pos = 0;
-	const size_t bufsz = sizeof(buf);
+	int cnt;
+	ssize_t ret;
+	const size_t bufsz = 100 +
+		sizeof(char) * 24 * (MANAGEMENT_MAX + CONTROL_MAX);
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
-	pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n",
-						priv->rx_stats[0].cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n",
-						priv->rx_stats[1].cnt);
-	pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n",
-						priv->rx_stats[2].cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
+	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "\t%s\t\t: %u\n",
+				 get_mgmt_string(cnt),
+				 priv->rx_stats.mgmt[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
+	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "\t%s\t\t: %u\n",
+				 get_ctrl_string(cnt),
+				 priv->rx_stats.ctrl[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
+			 priv->rx_stats.data_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
+			 priv->rx_stats.data_bytes);
 
-	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_rx_statistics_write(struct file *file,
+					const char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	u32 clear_flag;
+	char buf[8];
+	int buf_size;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%x", &clear_flag) != 1)
+		return -EFAULT;
+	if (clear_flag == 1)
+		iwl_clear_rx_stats(priv);
+	return count;
 }
 
 #define BYTE1_MASK 0x000000ff;
@@ -566,16 +649,982 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
 	return count;
 }
 
+static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
+				       size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0, i;
+	char buf[256];
+	const size_t bufsz = sizeof(buf);
+	ssize_t ret;
+
+	for (i = 0; i < AC_NUM; i++) {
+		pos += scnprintf(buf + pos, bufsz - pos,
+			"\tcw_min\tcw_max\taifsn\ttxop\n");
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"AC[%d]\t%u\t%u\t%u\t%u\n", i,
+				priv->qos_data.def_qos_parm.ac[i].cw_min,
+				priv->qos_data.def_qos_parm.ac[i].cw_max,
+				priv->qos_data.def_qos_parm.ac[i].aifsn,
+				priv->qos_data.def_qos_parm.ac[i].edca_txop);
+	}
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	return ret;
+}
+
+#ifdef CONFIG_IWLWIFI_LEDS
+static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
+				  size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	char buf[256];
+	const size_t bufsz = sizeof(buf);
+	ssize_t ret;
+
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "allow blinking: %s\n",
+			 (priv->allow_blinking) ? "True" : "False");
+	if (priv->allow_blinking) {
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "Led blinking rate: %u\n",
+				 priv->last_blink_rate);
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "Last blink time: %lu\n",
+				 priv->last_blink_time);
+	}
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	return ret;
+}
+#endif
+
+static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
+				char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	struct iwl_tt_restriction *restriction;
+	char buf[100];
+	int pos = 0;
+	const size_t bufsz = sizeof(buf);
+	ssize_t ret;
+
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"Thermal Throttling Mode: %s\n",
+			tt->advanced_tt ? "Advance" : "Legacy");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"Thermal Throttling State: %d\n",
+			tt->state);
+	if (tt->advanced_tt) {
+		restriction = tt->restriction + tt->state;
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"Tx mode: %d\n",
+				restriction->tx_stream);
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"Rx mode: %d\n",
+				restriction->rx_stream);
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"HT mode: %d\n",
+				restriction->is_ht);
+	}
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int ht40;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &ht40) != 1)
+		return -EFAULT;
+	if (!iwl_is_associated(priv))
+		priv->disable_ht40 = ht40 ? true : false;
+	else {
+		IWL_ERR(priv, "Sta associated with AP - "
+			"Change to 40MHz channel support is not allowed\n");
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
+					 char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	char buf[100];
+	int pos = 0;
+	const size_t bufsz = sizeof(buf);
+	ssize_t ret;
+
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"11n 40MHz Mode: %s\n",
+			priv->disable_ht40 ? "Disabled" : "Enabled");
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file,
+						    const char __user *user_buf,
+						    size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int value;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	if (sscanf(buf, "%d", &value) != 1)
+		return -EINVAL;
+
+	/*
+	 * Our users expect 0 to be "CAM", but 0 isn't actually
+	 * valid here. However, let's not confuse them and present
+	 * IWL_POWER_INDEX_1 as "1", not "0".
+	 */
+	if (value > 0)
+		value -= 1;
+
+	if (value != -1 && (value < 0 || value >= IWL_POWER_NUM))
+		return -EINVAL;
+
+	priv->power_data.debug_sleep_level_override = value;
+
+	iwl_power_update_mode(priv, false);
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
+						   char __user *user_buf,
+						   size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	char buf[10];
+	int pos, value;
+	const size_t bufsz = sizeof(buf);
+
+	/* see the write function */
+	value = priv->power_data.debug_sleep_level_override;
+	if (value >= 0)
+		value += 1;
+
+	pos = scnprintf(buf, bufsz, "%d\n", value);
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
+						    char __user *user_buf,
+						    size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	char buf[200];
+	int pos = 0, i;
+	const size_t bufsz = sizeof(buf);
+	struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd;
+
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "flags: %#.2x\n", le16_to_cpu(cmd->flags));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "RX/TX timeout: %d/%d usec\n",
+			 le32_to_cpu(cmd->rx_data_timeout),
+			 le32_to_cpu(cmd->tx_data_timeout));
+	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
+		pos += scnprintf(buf + pos, bufsz - pos,
+				 "sleep_interval[%d]: %d\n", i,
+				 le32_to_cpu(cmd->sleep_interval[i]));
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
 
 DEBUGFS_READ_WRITE_FILE_OPS(sram);
 DEBUGFS_WRITE_FILE_OPS(log_event);
 DEBUGFS_READ_FILE_OPS(nvm);
 DEBUGFS_READ_FILE_OPS(stations);
-DEBUGFS_READ_FILE_OPS(rx_statistics);
-DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_FILE_OPS(channels);
 DEBUGFS_READ_FILE_OPS(status);
 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
+DEBUGFS_READ_FILE_OPS(qos);
+#ifdef CONFIG_IWLWIFI_LEDS
+DEBUGFS_READ_FILE_OPS(led);
+#endif
+DEBUGFS_READ_FILE_OPS(thermal_throttling);
+DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
+DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
+DEBUGFS_READ_FILE_OPS(current_sleep_command);
+
+static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
+					 char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	int pos = 0, ofs = 0;
+	int cnt = 0, entry;
+	struct iwl_tx_queue *txq;
+	struct iwl_queue *q;
+	struct iwl_rx_queue *rxq = &priv->rxq;
+	char *buf;
+	int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
+		(IWL_MAX_NUM_QUEUES * 32 * 8) + 400;
+	const u8 *ptr;
+	ssize_t ret;
+
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate buffer\n");
+		return -ENOMEM;
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
+	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
+		txq = &priv->txq[cnt];
+		q = &txq->q;
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"q[%d]: read_ptr: %u, write_ptr: %u\n",
+				cnt, q->read_ptr, q->write_ptr);
+	}
+	if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) {
+		ptr = priv->tx_traffic;
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"Tx Traffic idx: %u\n",	priv->tx_traffic_idx);
+		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
+			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
+			     entry++,  ofs += 16) {
+				pos += scnprintf(buf + pos, bufsz - pos,
+						"0x%.4x ", ofs);
+				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
+						   buf + pos, bufsz - pos, 0);
+				pos += strlen(buf);
+				if (bufsz - pos > 0)
+					buf[pos++] = '\n';
+			}
+		}
+	}
+
+	pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"read: %u, write: %u\n",
+			 rxq->read, rxq->write);
+
+	if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) {
+		ptr = priv->rx_traffic;
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"Rx Traffic idx: %u\n",	priv->rx_traffic_idx);
+		for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
+			for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
+			     entry++,  ofs += 16) {
+				pos += scnprintf(buf + pos, bufsz - pos,
+						"0x%.4x ", ofs);
+				hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
+						   buf + pos, bufsz - pos, 0);
+				pos += strlen(buf);
+				if (bufsz - pos > 0)
+					buf[pos++] = '\n';
+			}
+		}
+	}
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = file->private_data;
+	char buf[8];
+	int buf_size;
+	int traffic_log;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	if (sscanf(buf, "%d", &traffic_log) != 1)
+		return -EFAULT;
+	if (traffic_log == 0)
+		iwl_reset_traffic_log(priv);
+
+	return count;
+}
+
+static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
+						char __user *user_buf,
+						size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_tx_queue *txq;
+	struct iwl_queue *q;
+	char *buf;
+	int pos = 0;
+	int cnt;
+	int ret;
+	const size_t bufsz = sizeof(char) * 60 * IWL_MAX_NUM_QUEUES;
+
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
+		txq = &priv->txq[cnt];
+		q = &txq->q;
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"hwq %.2d: read=%u write=%u stop=%d"
+				" swq_id=%#.2x (ac %d/hwq %d)\n",
+				cnt, q->read_ptr, q->write_ptr,
+				!!test_bit(cnt, priv->queue_stopped),
+				txq->swq_id,
+				txq->swq_id & 0x80 ? txq->swq_id & 3 :
+				txq->swq_id,
+				txq->swq_id & 0x80 ? (txq->swq_id >> 2) &
+				0x1f : txq->swq_id);
+		if (cnt >= 4)
+			continue;
+		/* for the ACs, display the stop count too */
+		pos += scnprintf(buf + pos, bufsz - pos,
+				"        stop-count: %d\n",
+				atomic_read(&priv->queue_stop_count[cnt]));
+	}
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
+						char __user *user_buf,
+						size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	struct iwl_rx_queue *rxq = &priv->rxq;
+	char buf[256];
+	int pos = 0;
+	const size_t bufsz = sizeof(buf);
+
+	pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n",
+						rxq->read);
+	pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
+						rxq->write);
+	pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
+						rxq->free_count);
+	pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",
+			 le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF);
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+#define UCODE_STATISTICS_CLEAR_MSK		(0x1 << 0)
+#define UCODE_STATISTICS_FREQUENCY_MSK		(0x1 << 1)
+#define UCODE_STATISTICS_NARROW_BAND_MSK	(0x1 << 2)
+
+static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf,
+				     int bufsz)
+{
+	int p = 0;
+
+	p += scnprintf(buf + p, bufsz - p,
+		"Statistics Flag(0x%X):\n",
+		le32_to_cpu(priv->statistics.flag));
+	if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
+		p += scnprintf(buf + p, bufsz - p,
+		"\tStatistics have been cleared\n");
+	p += scnprintf(buf + p, bufsz - p,
+		"\tOperational Frequency: %s\n",
+		(le32_to_cpu(priv->statistics.flag) &
+		UCODE_STATISTICS_FREQUENCY_MSK)
+		 ? "2.4 GHz" : "5.2 GHz");
+	p += scnprintf(buf + p, bufsz - p,
+		"\tTGj Narrow Band: %s\n",
+		(le32_to_cpu(priv->statistics.flag) &
+		UCODE_STATISTICS_NARROW_BAND_MSK)
+		 ? "enabled" : "disabled");
+	return p;
+}
+
+
+static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	char *buf;
+	int bufsz = sizeof(struct statistics_rx_phy) * 20 +
+		sizeof(struct statistics_rx_non_phy) * 20 +
+		sizeof(struct statistics_rx_ht_phy) * 20 + 400;
+	ssize_t ret;
+	struct statistics_rx_phy *ofdm;
+	struct statistics_rx_phy *cck;
+	struct statistics_rx_non_phy *general;
+	struct statistics_rx_ht_phy *ht;
+
+	if (!iwl_is_alive(priv))
+		return -EAGAIN;
+
+	/* make request to uCode to retrieve statistics information */
+	mutex_lock(&priv->mutex);
+	ret = iwl_send_statistics_request(priv, 0);
+	mutex_unlock(&priv->mutex);
+
+	if (ret) {
+		IWL_ERR(priv,
+			"Error sending statistics request: %zd\n", ret);
+		return -EAGAIN;
+	}
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	/* the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	ofdm = &priv->statistics.rx.ofdm;
+	cck = &priv->statistics.rx.cck;
+	general = &priv->statistics.rx.general;
+	ht = &priv->statistics.rx.ofdm_ht;
+	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt: %u\n",
+			 le32_to_cpu(ofdm->ina_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt: %u\n",
+			 le32_to_cpu(ofdm->fina_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n",
+			 le32_to_cpu(ofdm->plcp_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n",
+			 le32_to_cpu(ofdm->crc32_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n",
+			 le32_to_cpu(ofdm->overrun_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n",
+			 le32_to_cpu(ofdm->early_overrun_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n",
+			 le32_to_cpu(ofdm->crc32_good));
+	pos += scnprintf(buf + pos, bufsz - pos, "false_alarm_cnt: %u\n",
+			 le32_to_cpu(ofdm->false_alarm_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_sync_err_cnt: %u\n",
+			 le32_to_cpu(ofdm->fina_sync_err_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "sfd_timeout: %u\n",
+			 le32_to_cpu(ofdm->sfd_timeout));
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_timeout: %u\n",
+			 le32_to_cpu(ofdm->fina_timeout));
+	pos += scnprintf(buf + pos, bufsz - pos, "unresponded_rts: %u\n",
+			 le32_to_cpu(ofdm->unresponded_rts));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"rxe_frame_limit_overrun: %u\n",
+			le32_to_cpu(ofdm->rxe_frame_limit_overrun));
+	pos += scnprintf(buf + pos, bufsz - pos, "sent_ack_cnt: %u\n",
+			 le32_to_cpu(ofdm->sent_ack_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "sent_cts_cnt: %u\n",
+			 le32_to_cpu(ofdm->sent_cts_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "sent_ba_rsp_cnt: %u\n",
+			 le32_to_cpu(ofdm->sent_ba_rsp_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "dsp_self_kill: %u\n",
+			 le32_to_cpu(ofdm->dsp_self_kill));
+	pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n",
+			 le32_to_cpu(ofdm->mh_format_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "re_acq_main_rssi_sum: %u\n",
+			 le32_to_cpu(ofdm->re_acq_main_rssi_sum));
+
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt: %u\n",
+			 le32_to_cpu(cck->ina_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt: %u\n",
+			 le32_to_cpu(cck->fina_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n",
+			 le32_to_cpu(cck->plcp_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n",
+			 le32_to_cpu(cck->crc32_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n",
+			 le32_to_cpu(cck->overrun_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n",
+			 le32_to_cpu(cck->early_overrun_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n",
+			 le32_to_cpu(cck->crc32_good));
+	pos += scnprintf(buf + pos, bufsz - pos, "false_alarm_cnt: %u\n",
+			 le32_to_cpu(cck->false_alarm_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_sync_err_cnt: %u\n",
+			 le32_to_cpu(cck->fina_sync_err_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "sfd_timeout: %u\n",
+			 le32_to_cpu(cck->sfd_timeout));
+	pos += scnprintf(buf + pos, bufsz - pos, "fina_timeout: %u\n",
+			 le32_to_cpu(cck->fina_timeout));
+	pos += scnprintf(buf + pos, bufsz - pos, "unresponded_rts: %u\n",
+			 le32_to_cpu(cck->unresponded_rts));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"rxe_frame_limit_overrun: %u\n",
+			le32_to_cpu(cck->rxe_frame_limit_overrun));
+	pos += scnprintf(buf + pos, bufsz - pos, "sent_ack_cnt: %u\n",
+			 le32_to_cpu(cck->sent_ack_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "sent_cts_cnt: %u\n",
+			 le32_to_cpu(cck->sent_cts_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "sent_ba_rsp_cnt: %u\n",
+			 le32_to_cpu(cck->sent_ba_rsp_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "dsp_self_kill: %u\n",
+			 le32_to_cpu(cck->dsp_self_kill));
+	pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n",
+			 le32_to_cpu(cck->mh_format_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "re_acq_main_rssi_sum: %u\n",
+			 le32_to_cpu(cck->re_acq_main_rssi_sum));
+
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts: %u\n",
+			 le32_to_cpu(general->bogus_cts));
+	pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack: %u\n",
+			 le32_to_cpu(general->bogus_ack));
+	pos += scnprintf(buf + pos, bufsz - pos, "non_bssid_frames: %u\n",
+			 le32_to_cpu(general->non_bssid_frames));
+	pos += scnprintf(buf + pos, bufsz - pos, "filtered_frames: %u\n",
+			 le32_to_cpu(general->filtered_frames));
+	pos += scnprintf(buf + pos, bufsz - pos, "non_channel_beacons: %u\n",
+			 le32_to_cpu(general->non_channel_beacons));
+	pos += scnprintf(buf + pos, bufsz - pos, "channel_beacons: %u\n",
+			 le32_to_cpu(general->channel_beacons));
+	pos += scnprintf(buf + pos, bufsz - pos, "num_missed_bcon: %u\n",
+			 le32_to_cpu(general->num_missed_bcon));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"adc_rx_saturation_time: %u\n",
+			le32_to_cpu(general->adc_rx_saturation_time));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"ina_detection_search_time: %u\n",
+			le32_to_cpu(general->ina_detection_search_time));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_a: %u\n",
+			 le32_to_cpu(general->beacon_silence_rssi_a));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_b: %u\n",
+			 le32_to_cpu(general->beacon_silence_rssi_b));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_silence_rssi_c: %u\n",
+			 le32_to_cpu(general->beacon_silence_rssi_c));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"interference_data_flag: %u\n",
+			le32_to_cpu(general->interference_data_flag));
+	pos += scnprintf(buf + pos, bufsz - pos, "channel_load: %u\n",
+			 le32_to_cpu(general->channel_load));
+	pos += scnprintf(buf + pos, bufsz - pos, "dsp_false_alarms: %u\n",
+			 le32_to_cpu(general->dsp_false_alarms));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_a: %u\n",
+			 le32_to_cpu(general->beacon_rssi_a));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_b: %u\n",
+			 le32_to_cpu(general->beacon_rssi_b));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_rssi_c: %u\n",
+			 le32_to_cpu(general->beacon_rssi_c));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_a: %u\n",
+			 le32_to_cpu(general->beacon_energy_a));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_b: %u\n",
+			 le32_to_cpu(general->beacon_energy_b));
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_energy_c: %u\n",
+			 le32_to_cpu(general->beacon_energy_c));
+
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "plcp_err: %u\n",
+			 le32_to_cpu(ht->plcp_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "overrun_err: %u\n",
+			 le32_to_cpu(ht->overrun_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "early_overrun_err: %u\n",
+			 le32_to_cpu(ht->early_overrun_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_good: %u\n",
+			 le32_to_cpu(ht->crc32_good));
+	pos += scnprintf(buf + pos, bufsz - pos, "crc32_err: %u\n",
+			 le32_to_cpu(ht->crc32_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "mh_format_err: %u\n",
+			 le32_to_cpu(ht->mh_format_err));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg_crc32_good: %u\n",
+			 le32_to_cpu(ht->agg_crc32_good));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg_mpdu_cnt: %u\n",
+			 le32_to_cpu(ht->agg_mpdu_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt: %u\n",
+			 le32_to_cpu(ht->agg_cnt));
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	char *buf;
+	int bufsz = (sizeof(struct statistics_tx) * 24) + 250;
+	ssize_t ret;
+	struct statistics_tx *tx;
+
+	if (!iwl_is_alive(priv))
+		return -EAGAIN;
+
+	/* make request to uCode to retrieve statistics information */
+	mutex_lock(&priv->mutex);
+	ret = iwl_send_statistics_request(priv, 0);
+	mutex_unlock(&priv->mutex);
+
+	if (ret) {
+		IWL_ERR(priv,
+			"Error sending statistics request: %zd\n", ret);
+		return -EAGAIN;
+	}
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	/* the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	tx = &priv->statistics.tx;
+	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "preamble: %u\n",
+			 le32_to_cpu(tx->preamble_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "rx_detected_cnt: %u\n",
+			 le32_to_cpu(tx->rx_detected_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "bt_prio_defer_cnt: %u\n",
+			 le32_to_cpu(tx->bt_prio_defer_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "bt_prio_kill_cnt: %u\n",
+			 le32_to_cpu(tx->bt_prio_kill_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "few_bytes_cnt: %u\n",
+			 le32_to_cpu(tx->few_bytes_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "cts_timeout: %u\n",
+			 le32_to_cpu(tx->cts_timeout));
+	pos += scnprintf(buf + pos, bufsz - pos, "ack_timeout: %u\n",
+			 le32_to_cpu(tx->ack_timeout));
+	pos += scnprintf(buf + pos, bufsz - pos, "expected_ack_cnt: %u\n",
+			 le32_to_cpu(tx->expected_ack_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "actual_ack_cnt: %u\n",
+			 le32_to_cpu(tx->actual_ack_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "dump_msdu_cnt: %u\n",
+			 le32_to_cpu(tx->dump_msdu_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"burst_abort_next_frame_mismatch_cnt: %u\n",
+			le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"burst_abort_missing_next_frame_cnt: %u\n",
+			le32_to_cpu(tx->burst_abort_missing_next_frame_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "cts_timeout_collision: %u\n",
+			 le32_to_cpu(tx->cts_timeout_collision));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"ack_or_ba_timeout_collision: %u\n",
+			le32_to_cpu(tx->ack_or_ba_timeout_collision));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg ba_timeout: %u\n",
+			 le32_to_cpu(tx->agg.ba_timeout));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"agg ba_reschedule_frames: %u\n",
+			le32_to_cpu(tx->agg.ba_reschedule_frames));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"agg scd_query_agg_frame_cnt: %u\n",
+			le32_to_cpu(tx->agg.scd_query_agg_frame_cnt));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg scd_query_no_agg: %u\n",
+			 le32_to_cpu(tx->agg.scd_query_no_agg));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg scd_query_agg: %u\n",
+			 le32_to_cpu(tx->agg.scd_query_agg));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"agg scd_query_mismatch: %u\n",
+			le32_to_cpu(tx->agg.scd_query_mismatch));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg frame_not_ready: %u\n",
+			 le32_to_cpu(tx->agg.frame_not_ready));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg underrun: %u\n",
+			 le32_to_cpu(tx->agg.underrun));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg bt_prio_kill: %u\n",
+			 le32_to_cpu(tx->agg.bt_prio_kill));
+	pos += scnprintf(buf + pos, bufsz - pos, "agg rx_ba_rsp_cnt: %u\n",
+			 le32_to_cpu(tx->agg.rx_ba_rsp_cnt));
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	char *buf;
+	int bufsz = sizeof(struct statistics_general) * 4 + 250;
+	ssize_t ret;
+	struct statistics_general *general;
+	struct statistics_dbg *dbg;
+	struct statistics_div *div;
+
+	if (!iwl_is_alive(priv))
+		return -EAGAIN;
+
+	/* make request to uCode to retrieve statistics information */
+	mutex_lock(&priv->mutex);
+	ret = iwl_send_statistics_request(priv, 0);
+	mutex_unlock(&priv->mutex);
+
+	if (ret) {
+		IWL_ERR(priv,
+			"Error sending statistics request: %zd\n", ret);
+		return -EAGAIN;
+	}
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	/* the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	general = &priv->statistics.general;
+	dbg = &priv->statistics.general.dbg;
+	div = &priv->statistics.general.div;
+	pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "temperature: %u\n",
+			 le32_to_cpu(general->temperature));
+	pos += scnprintf(buf + pos, bufsz - pos, "temperature_m: %u\n",
+			 le32_to_cpu(general->temperature_m));
+	pos += scnprintf(buf + pos, bufsz - pos, "burst_check: %u\n",
+			 le32_to_cpu(dbg->burst_check));
+	pos += scnprintf(buf + pos, bufsz - pos, "burst_count: %u\n",
+			 le32_to_cpu(dbg->burst_count));
+	pos += scnprintf(buf + pos, bufsz - pos, "sleep_time: %u\n",
+			 le32_to_cpu(general->sleep_time));
+	pos += scnprintf(buf + pos, bufsz - pos, "slots_out: %u\n",
+			 le32_to_cpu(general->slots_out));
+	pos += scnprintf(buf + pos, bufsz - pos, "slots_idle: %u\n",
+			 le32_to_cpu(general->slots_idle));
+	pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp: %u\n",
+			 le32_to_cpu(general->ttl_timestamp));
+	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a: %u\n",
+			 le32_to_cpu(div->tx_on_a));
+	pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b: %u\n",
+			 le32_to_cpu(div->tx_on_b));
+	pos += scnprintf(buf + pos, bufsz - pos, "exec_time: %u\n",
+			 le32_to_cpu(div->exec_time));
+	pos += scnprintf(buf + pos, bufsz - pos, "probe_time: %u\n",
+			 le32_to_cpu(div->probe_time));
+	pos += scnprintf(buf + pos, bufsz - pos, "rx_enable_counter: %u\n",
+			 le32_to_cpu(general->rx_enable_counter));
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	int cnt = 0;
+	char *buf;
+	int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100;
+	ssize_t ret;
+	struct iwl_sensitivity_data *data;
+
+	data = &priv->sensitivity_data;
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
+			data->auto_corr_ofdm);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"auto_corr_ofdm_mrc:\t\t %u\n",
+			data->auto_corr_ofdm_mrc);
+	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",
+			data->auto_corr_ofdm_x1);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"auto_corr_ofdm_mrc_x1:\t\t %u\n",
+			data->auto_corr_ofdm_mrc_x1);
+	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",
+			data->auto_corr_cck);
+	pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",
+			data->auto_corr_cck_mrc);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"last_bad_plcp_cnt_ofdm:\t\t %u\n",
+			data->last_bad_plcp_cnt_ofdm);
+	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",
+			data->last_fa_cnt_ofdm);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"last_bad_plcp_cnt_cck:\t\t %u\n",
+			data->last_bad_plcp_cnt_cck);
+	pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",
+			data->last_fa_cnt_cck);
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",
+			data->nrg_curr_state);
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",
+			data->nrg_prev_state);
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");
+	for (cnt = 0; cnt < 10; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos, " %u",
+				data->nrg_value[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");
+	for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos, " %u",
+				data->nrg_silence_rssi[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",
+			data->nrg_silence_ref);
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",
+			data->nrg_energy_idx);
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",
+			data->nrg_silence_idx);
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",
+			data->nrg_th_cck);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"nrg_auto_corr_silence_diff:\t %u\n",
+			data->nrg_auto_corr_silence_diff);
+	pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",
+			data->num_in_cck_no_fa);
+	pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",
+			data->nrg_th_ofdm);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+
+static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	int pos = 0;
+	int cnt = 0;
+	char *buf;
+	int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100;
+	ssize_t ret;
+	struct iwl_chain_noise_data *data;
+
+	data = &priv->chain_noise_data;
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
+			data->active_chains);
+	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",
+			data->chain_noise_a);
+	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",
+			data->chain_noise_b);
+	pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",
+			data->chain_noise_c);
+	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",
+			data->chain_signal_a);
+	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",
+			data->chain_signal_b);
+	pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",
+			data->chain_signal_c);
+	pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",
+			data->beacon_count);
+
+	pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");
+	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos, " %u",
+				data->disconn_array[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");
+	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {
+		pos += scnprintf(buf + pos, bufsz - pos, " %u",
+				data->delta_gain_code[cnt]);
+	}
+	pos += scnprintf(buf + pos, bufsz - pos, "\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",
+			data->radio_write);
+	pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",
+			data->state);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
+					char __user *user_buf,
+					size_t count, loff_t *ppos) {
+
+	struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+	char buf[128];
+	int pos = 0;
+	ssize_t ret;
+	const size_t bufsz = sizeof(buf);
+	struct statistics_tx *tx;
+
+	if (!iwl_is_alive(priv))
+		pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
+	else {
+		/* make request to uCode to retrieve statistics information */
+		mutex_lock(&priv->mutex);
+		ret = iwl_send_statistics_request(priv, 0);
+		mutex_unlock(&priv->mutex);
+
+		if (ret) {
+			IWL_ERR(priv, "Error sending statistics request: %zd\n",
+				ret);
+			return -EAGAIN;
+		}
+		tx = &priv->statistics.tx;
+		if (tx->tx_power.ant_a ||
+		    tx->tx_power.ant_b ||
+		    tx->tx_power.ant_c) {
+			pos += scnprintf(buf + pos, bufsz - pos,
+				"tx power: (1/2 dB step)\n");
+			if ((priv->cfg->valid_tx_ant & ANT_A) &&
+			    tx->tx_power.ant_a)
+				pos += scnprintf(buf + pos, bufsz - pos,
+						"\tantenna A: 0x%X\n",
+						tx->tx_power.ant_a);
+			if ((priv->cfg->valid_tx_ant & ANT_B) &&
+			    tx->tx_power.ant_b)
+				pos += scnprintf(buf + pos, bufsz - pos,
+						"\tantenna B: 0x%X\n",
+						tx->tx_power.ant_b);
+			if ((priv->cfg->valid_tx_ant & ANT_C) &&
+			    tx->tx_power.ant_c)
+				pos += scnprintf(buf + pos, bufsz - pos,
+						"\tantenna C: 0x%X\n",
+						tx->tx_power.ant_c);
+		} else
+			pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
+	}
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
+DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics);
+DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics);
+DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
+DEBUGFS_READ_FILE_OPS(rx_queue);
+DEBUGFS_READ_FILE_OPS(tx_queue);
+DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
+DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
+DEBUGFS_READ_FILE_OPS(ucode_general_stats);
+DEBUGFS_READ_FILE_OPS(sensitivity);
+DEBUGFS_READ_FILE_OPS(chain_noise);
+DEBUGFS_READ_FILE_OPS(tx_power);
 
 /*
  * Create the debugfs files and directories
@@ -603,19 +1652,42 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 
 	DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
 	DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
+	DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
 	DEBUGFS_ADD_FILE(nvm, data);
 	DEBUGFS_ADD_FILE(sram, data);
 	DEBUGFS_ADD_FILE(log_event, data);
 	DEBUGFS_ADD_FILE(stations, data);
-	DEBUGFS_ADD_FILE(rx_statistics, data);
-	DEBUGFS_ADD_FILE(tx_statistics, data);
 	DEBUGFS_ADD_FILE(channels, data);
 	DEBUGFS_ADD_FILE(status, data);
 	DEBUGFS_ADD_FILE(interrupt, data);
+	DEBUGFS_ADD_FILE(qos, data);
+#ifdef CONFIG_IWLWIFI_LEDS
+	DEBUGFS_ADD_FILE(led, data);
+#endif
+	DEBUGFS_ADD_FILE(sleep_level_override, data);
+	DEBUGFS_ADD_FILE(current_sleep_command, data);
+	DEBUGFS_ADD_FILE(thermal_throttling, data);
+	DEBUGFS_ADD_FILE(disable_ht40, data);
+	DEBUGFS_ADD_FILE(rx_statistics, debug);
+	DEBUGFS_ADD_FILE(tx_statistics, debug);
+	DEBUGFS_ADD_FILE(traffic_log, debug);
+	DEBUGFS_ADD_FILE(rx_queue, debug);
+	DEBUGFS_ADD_FILE(tx_queue, debug);
+	DEBUGFS_ADD_FILE(tx_power, debug);
+	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
+		DEBUGFS_ADD_FILE(ucode_rx_stats, debug);
+		DEBUGFS_ADD_FILE(ucode_tx_stats, debug);
+		DEBUGFS_ADD_FILE(ucode_general_stats, debug);
+		DEBUGFS_ADD_FILE(sensitivity, debug);
+		DEBUGFS_ADD_FILE(chain_noise, debug);
+	}
 	DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
 	DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
 			 &priv->disable_chain_noise_cal);
-	DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal);
+	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
+	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
+		DEBUGFS_ADD_BOOL(disable_tx_power, rf,
+				&priv->disable_tx_power_cal);
 	return 0;
 
 err:
@@ -634,19 +1706,46 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
 	if (!priv->dbgfs)
 		return;
 
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
+#ifdef CONFIG_IWLWIFI_LEDS
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
+#endif
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
 	DEBUGFS_REMOVE(priv->dbgfs->dir_data);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue);
+	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power);
+	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
+		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
+			file_ucode_rx_stats);
+		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
+			file_ucode_tx_stats);
+		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
+			file_ucode_general_stats);
+		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
+			file_sensitivity);
+		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
+			file_chain_noise);
+	}
+	DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
 	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
-	DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
+	if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
+	    ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
+		DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
 	DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
 	DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
 	kfree(priv->dbgfs);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 650e20a..028d505 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -56,16 +56,19 @@ extern struct iwl_cfg iwl5350_agn_cfg;
 extern struct iwl_cfg iwl5100_bg_cfg;
 extern struct iwl_cfg iwl5100_abg_cfg;
 extern struct iwl_cfg iwl5150_agn_cfg;
-extern struct iwl_cfg iwl6000_2ag_cfg;
-extern struct iwl_cfg iwl6000_2agn_cfg;
+extern struct iwl_cfg iwl6000h_2agn_cfg;
+extern struct iwl_cfg iwl6000i_2agn_cfg;
 extern struct iwl_cfg iwl6000_3agn_cfg;
 extern struct iwl_cfg iwl6050_2agn_cfg;
 extern struct iwl_cfg iwl6050_3agn_cfg;
 extern struct iwl_cfg iwl1000_bgn_cfg;
 
+struct iwl_tx_queue;
+
 /* shared structures from iwl-5000.c */
 extern struct iwl_mod_params iwl50_mod_params;
 extern struct iwl_ops iwl5000_ops;
+extern struct iwl_ucode_ops iwl5000_ucode;
 extern struct iwl_lib_ops iwl5000_lib;
 extern struct iwl_hcmd_ops iwl5000_hcmd;
 extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
@@ -78,9 +81,37 @@ extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
 				    __le32 *tx_flags);
 extern int iwl5000_calc_rssi(struct iwl_priv *priv,
 			     struct iwl_rx_phy_res *rx_resp);
+extern int iwl5000_apm_init(struct iwl_priv *priv);
+extern void iwl5000_apm_stop(struct iwl_priv *priv);
+extern int iwl5000_apm_reset(struct iwl_priv *priv);
+extern void iwl5000_nic_config(struct iwl_priv *priv);
+extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv);
+extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
+				    size_t offset);
+extern void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+					    struct iwl_tx_queue *txq,
+					    u16 byte_cnt);
+extern void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+				    struct iwl_tx_queue *txq);
+extern int iwl5000_load_ucode(struct iwl_priv *priv);
+extern void iwl5000_init_alive_start(struct iwl_priv *priv);
+extern int iwl5000_alive_notify(struct iwl_priv *priv);
+extern int iwl5000_hw_set_hw_params(struct iwl_priv *priv);
+extern int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
+			   int tx_fifo, int sta_id, int tid, u16 ssn_idx);
+extern int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+			    u16 ssn_idx, u8 tx_fifo);
+extern void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask);
+extern void iwl5000_setup_deferred_work(struct iwl_priv *priv);
+extern void iwl5000_rx_handler_setup(struct iwl_priv *priv);
+extern int iwl5000_hw_valid_rtc_data_addr(u32 addr);
+extern int iwl5000_send_tx_power(struct iwl_priv *priv);
+extern void iwl5000_temperature(struct iwl_priv *priv);
 
 /* CT-KILL constants */
-#define CT_KILL_THRESHOLD	110 /* in Celsius */
+#define CT_KILL_THRESHOLD_LEGACY   110 /* in Celsius */
+#define CT_KILL_THRESHOLD	   114 /* in Celsius */
+#define CT_KILL_EXIT_THRESHOLD     95  /* in Celsius */
 
 /* Default noise level to report when noise measurement is not available.
  *   This may be because we're:
@@ -119,6 +150,31 @@ struct iwl_rx_mem_buffer {
 	struct list_head list;
 };
 
+/* defined below */
+struct iwl_device_cmd;
+
+struct iwl_cmd_meta {
+	/* only for SYNC commands, iff the reply skb is wanted */
+	struct iwl_host_cmd *source;
+	/*
+	 * only for ASYNC commands
+	 * (which is somewhat stupid -- look at iwl-sta.c for instance
+	 * which duplicates a bunch of code because the callback isn't
+	 * invoked for SYNC commands, if it were and its result passed
+	 * through it would be simpler...)
+	 */
+	void (*callback)(struct iwl_priv *priv,
+			 struct iwl_device_cmd *cmd,
+			 struct sk_buff *skb);
+
+	/* The CMD_SIZE_HUGE flag bit indicates that the command
+	 * structure is stored at the end of the shared queue memory. */
+	u32 flags;
+
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+	DECLARE_PCI_UNMAP_LEN(len)
+};
+
 /*
  * Generic queue structure
  *
@@ -146,7 +202,8 @@ struct iwl_tx_info {
  * struct iwl_tx_queue - Tx Queue for DMA
  * @q: generic Rx/Tx queue descriptor
  * @bd: base of circular buffer of TFDs
- * @cmd: array of command/Tx buffers
+ * @cmd: array of command/TX buffer pointers
+ * @meta: array of meta data for each command/tx buffer
  * @dma_addr_cmd: physical address of cmd/tx buffer array
  * @txb: array of per-TFD driver data
  * @need_update: indicates need to update read/write index
@@ -161,7 +218,8 @@ struct iwl_tx_info {
 struct iwl_tx_queue {
 	struct iwl_queue q;
 	void *tfds;
-	struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
+	struct iwl_device_cmd **cmd;
+	struct iwl_cmd_meta *meta;
 	struct iwl_tx_info *txb;
 	u8 need_update;
 	u8 sched_retry;
@@ -219,8 +277,8 @@ struct iwl_channel_info {
 	struct iwl4965_channel_tgd_info tgd;
 	struct iwl4965_channel_tgh_info tgh;
 	struct iwl_eeprom_channel eeprom;	/* EEPROM regulatory limit */
-	struct iwl_eeprom_channel fat_eeprom;	/* EEPROM regulatory limit for
-						 * FAT channel */
+	struct iwl_eeprom_channel ht40_eeprom;	/* EEPROM regulatory limit for
+						 * HT40 channel */
 
 	u8 channel;	  /* channel number */
 	u8 flags;	  /* flags copied from EEPROM */
@@ -233,13 +291,13 @@ struct iwl_channel_info {
 	u8 band_index;	  /* 0-4, maps channel to band1/2/3/4/5 */
 	enum ieee80211_band band;
 
-	/* FAT channel info */
-	s8 fat_max_power_avg;	/* (dBm) regul. eeprom, normal Tx, any rate */
-	s8 fat_curr_txpow;	/* (dBm) regulatory/spectrum/user (not h/w) */
-	s8 fat_min_power;	/* always 0 */
-	s8 fat_scan_power;	/* (dBm) eeprom, direct scans, any rate */
-	u8 fat_flags;		/* flags copied from EEPROM */
-	u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
+	/* HT40 channel info */
+	s8 ht40_max_power_avg;	/* (dBm) regul. eeprom, normal Tx, any rate */
+	s8 ht40_curr_txpow;	/* (dBm) regulatory/spectrum/user (not h/w) */
+	s8 ht40_min_power;	/* always 0 */
+	s8 ht40_scan_power;	/* (dBm) eeprom, direct scans, any rate */
+	u8 ht40_flags;		/* flags copied from EEPROM */
+	u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */
 
 	/* Radio/DSP gain settings for each "normal" data Tx rate.
 	 * These include, in addition to RF and DSP gain, a few fields for
@@ -298,35 +356,16 @@ enum {
 	CMD_WANT_SKB = (1 << 2),
 };
 
-struct iwl_cmd;
-struct iwl_priv;
-
-struct iwl_cmd_meta {
-	struct iwl_cmd_meta *source;
-	union {
-		struct sk_buff *skb;
-		int (*callback)(struct iwl_priv *priv,
-				struct iwl_cmd *cmd, struct sk_buff *skb);
-	} __attribute__ ((packed)) u;
-
-	/* The CMD_SIZE_HUGE flag bit indicates that the command
-	 * structure is stored at the end of the shared queue memory. */
-	u32 flags;
-	DECLARE_PCI_UNMAP_ADDR(mapping)
-	DECLARE_PCI_UNMAP_LEN(len)
-} __attribute__ ((packed));
-
 #define IWL_CMD_MAX_PAYLOAD 320
 
 /**
- * struct iwl_cmd
+ * struct iwl_device_cmd
  *
  * For allocation of the command and tx queues, this establishes the overall
  * size of the largest command we send to uCode, except for a scan command
  * (which is relatively huge; space is allocated separately).
  */
-struct iwl_cmd {
-	struct iwl_cmd_meta meta;	/* driver data */
+struct iwl_device_cmd {
 	struct iwl_cmd_header hdr;	/* uCode API */
 	union {
 		u32 flags;
@@ -338,17 +377,20 @@ struct iwl_cmd {
 	} __attribute__ ((packed)) cmd;
 } __attribute__ ((packed));
 
+#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
+
 
 struct iwl_host_cmd {
-	u8 id;
-	u16 len;
-	struct iwl_cmd_meta meta;
 	const void *data;
+	struct sk_buff *reply_skb;
+	void (*callback)(struct iwl_priv *priv,
+			 struct iwl_device_cmd *cmd,
+			 struct sk_buff *skb);
+	u32 flags;
+	u16 len;
+	u8 id;
 };
 
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \
-			      sizeof(struct iwl_cmd_meta))
-
 /*
  * RX related structures and functions
  */
@@ -449,23 +491,25 @@ union iwl_ht_rate_supp {
 };
 
 #define CFG_HT_RX_AMPDU_FACTOR_DEF  (0x3)
-#define CFG_HT_MPDU_DENSITY_2USEC   (0x5)
-#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC
+
+/*
+ * Maximal MPDU density for TX aggregation
+ * 4 - 2us density
+ * 5 - 4us density
+ * 6 - 8us density
+ * 7 - 16us density
+ */
+#define CFG_HT_MPDU_DENSITY_4USEC   (0x5)
+#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC
 
 struct iwl_ht_info {
 	/* self configuration data */
 	u8 is_ht;
 	u8 supported_chan_width;
 	u8 sm_ps;
-	u8 is_green_field;
-	u8 sgf;			/* HT_SHORT_GI_* short guard interval */
-	u8 max_amsdu_size;
-	u8 ampdu_factor;
-	u8 mpdu_density;
 	struct ieee80211_mcs_info mcs;
 	/* BSS related data */
 	u8 extension_chan_offset;
-	u8 tx_chan_width;
 	u8 ht_protection;
 	u8 non_GF_STA_present;
 };
@@ -525,15 +569,29 @@ struct fw_desc {
 };
 
 /* uCode file layout */
-struct iwl_ucode {
-	__le32 ver;		/* major/minor/API/serial */
-	__le32 inst_size;	/* bytes of runtime instructions */
-	__le32 data_size;	/* bytes of runtime data */
-	__le32 init_size;	/* bytes of initialization instructions */
-	__le32 init_data_size;	/* bytes of initialization data */
-	__le32 boot_size;	/* bytes of bootstrap instructions */
-	u8 data[0];		/* data in same order as "size" elements */
+struct iwl_ucode_header {
+	__le32 ver;	/* major/minor/API/serial */
+	union {
+		struct {
+			__le32 inst_size;	/* bytes of runtime code */
+			__le32 data_size;	/* bytes of runtime data */
+			__le32 init_size;	/* bytes of init code */
+			__le32 init_data_size;	/* bytes of init data */
+			__le32 boot_size;	/* bytes of bootstrap code */
+			u8 data[0];		/* in same order as sizes */
+		} v1;
+		struct {
+			__le32 build;		/* build number */
+			__le32 inst_size;	/* bytes of runtime code */
+			__le32 data_size;	/* bytes of runtime data */
+			__le32 init_size;	/* bytes of init code */
+			__le32 init_data_size;	/* bytes of init data */
+			__le32 boot_size;	/* bytes of bootstrap code */
+			u8 data[0];		/* in same order as sizes */
+		} v2;
+	} u;
 };
+#define UCODE_HEADER_SIZE(ver) ((ver) == 1 ? 24 : 28)
 
 struct iwl4965_ibss_seq {
 	u8 mac[ETH_ALEN];
@@ -585,7 +643,7 @@ struct iwl_sensitivity_ranges {
  * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
  * @max_stations:
  * @bcast_sta_id:
- * @fat_channel: is 40MHz width possible in band 2.4
+ * @ht40_channel: is 40MHz width possible in band 2.4
  * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ)
  * @sw_crypto: 0 for hw, 1 for sw
  * @max_xxx_size: for ucode uses
@@ -609,12 +667,14 @@ struct iwl_hw_params {
 	u32 max_pkt_size;
 	u8  max_stations;
 	u8  bcast_sta_id;
-	u8 fat_channel;
-	u8 sw_crypto;
+	u8  ht40_channel;
+	u8  max_beacon_itrvl;	/* in 1024 ms */
 	u32 max_inst_size;
 	u32 max_data_size;
 	u32 max_bsm_size;
 	u32 ct_kill_threshold; /* value in hw-dependent units */
+	u32 ct_kill_exit_threshold; /* value in hw-dependent units */
+				    /* for 1000, 6000 series and up */
 	u32 calib_init_cfg;
 	const struct iwl_sensitivity_ranges *sens;
 };
@@ -666,9 +726,6 @@ struct iwl_dma_ptr {
 	size_t size;
 };
 
-#define HT_SHORT_GI_20MHZ	(1 << 0)
-#define HT_SHORT_GI_40MHZ	(1 << 1)
-
 #define IWL_CHANNEL_WIDTH_20MHZ   0
 #define IWL_CHANNEL_WIDTH_40MHZ   1
 
@@ -809,6 +866,8 @@ struct iwl_chain_noise_data {
 #define	EEPROM_SEM_TIMEOUT 10		/* milliseconds */
 #define EEPROM_SEM_RETRY_LIMIT 1000	/* number of attempts (not time) */
 
+#define IWL_TRAFFIC_ENTRIES	(256)
+#define IWL_TRAFFIC_ENTRY_SIZE  (64)
 
 enum {
 	MEASUREMENT_READY = (1 << 0),
@@ -820,6 +879,30 @@ enum iwl_nvm_type {
 	NVM_DEVICE_TYPE_OTP,
 };
 
+/*
+ * Two types of OTP memory access modes
+ *   IWL_OTP_ACCESS_ABSOLUTE - absolute address mode,
+ * 			        based on physical memory addressing
+ *   IWL_OTP_ACCESS_RELATIVE - relative address mode,
+ * 			       based on logical memory addressing
+ */
+enum iwl_access_mode {
+	IWL_OTP_ACCESS_ABSOLUTE,
+	IWL_OTP_ACCESS_RELATIVE,
+};
+
+/**
+ * enum iwl_pa_type - Power Amplifier type
+ * @IWL_PA_SYSTEM:  based on uCode configuration
+ * @IWL_PA_HYBRID: use both Internal and external PA
+ * @IWL_PA_INTERNAL: use Internal only
+ */
+enum iwl_pa_type {
+	IWL_PA_SYSTEM = 0,
+	IWL_PA_HYBRID = 1,
+	IWL_PA_INTERNAL = 2,
+};
+
 /* interrupt statistics */
 struct isr_statistics {
 	u32 hw;
@@ -836,6 +919,48 @@ struct isr_statistics {
 	u32 unhandled;
 };
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+/* management statistics */
+enum iwl_mgmt_stats {
+	MANAGEMENT_ASSOC_REQ = 0,
+	MANAGEMENT_ASSOC_RESP,
+	MANAGEMENT_REASSOC_REQ,
+	MANAGEMENT_REASSOC_RESP,
+	MANAGEMENT_PROBE_REQ,
+	MANAGEMENT_PROBE_RESP,
+	MANAGEMENT_BEACON,
+	MANAGEMENT_ATIM,
+	MANAGEMENT_DISASSOC,
+	MANAGEMENT_AUTH,
+	MANAGEMENT_DEAUTH,
+	MANAGEMENT_ACTION,
+	MANAGEMENT_MAX,
+};
+/* control statistics */
+enum iwl_ctrl_stats {
+	CONTROL_BACK_REQ =  0,
+	CONTROL_BACK,
+	CONTROL_PSPOLL,
+	CONTROL_RTS,
+	CONTROL_CTS,
+	CONTROL_ACK,
+	CONTROL_CFEND,
+	CONTROL_CFENDACK,
+	CONTROL_MAX,
+};
+
+struct traffic_stats {
+	u32 mgmt[MANAGEMENT_MAX];
+	u32 ctrl[CONTROL_MAX];
+	u32 data_cnt;
+	u64 data_bytes;
+};
+#else
+struct traffic_stats {
+	u64 data_bytes;
+};
+#endif
+
 #define IWL_MAX_NUM_QUEUES	20 /* FIXME: do dynamic allocation */
 
 struct iwl_priv {
@@ -981,15 +1106,14 @@ struct iwl_priv {
 	int last_rx_noise;	/* From beacon statistics */
 
 	/* counts mgmt, ctl, and data packets */
-	struct traffic_stats {
-		u32 cnt;
-		u64 bytes;
-	} tx_stats[3], rx_stats[3];
+	struct traffic_stats tx_stats;
+	struct traffic_stats rx_stats;
 
 	/* counts interrupts */
 	struct isr_statistics isr_stats;
 
 	struct iwl_power_mgr power_data;
+	struct iwl_tt_mgmt thermal_throttle;
 
 	struct iwl_notif_statistics statistics;
 	unsigned long last_statistics_time;
@@ -997,7 +1121,6 @@ struct iwl_priv {
 	/* context information */
 	u16 rates_mask;
 
-	u32 power_mode;
 	u8 bssid[ETH_ALEN];
 	u16 rts_threshold;
 	u8 mac_addr[ETH_ALEN];
@@ -1047,7 +1170,7 @@ struct iwl_priv {
 	struct iwl_hw_params hw_params;
 
 	/* INT ICT Table */
-	u32 *ict_tbl;
+	__le32 *ict_tbl;
 	dma_addr_t ict_tbl_dma;
 	dma_addr_t aligned_ict_tbl_dma;
 	int ict_index;
@@ -1076,6 +1199,9 @@ struct iwl_priv {
 	struct work_struct report_work;
 	struct work_struct request_scan;
 	struct work_struct beacon_update;
+	struct work_struct tt_work;
+	struct work_struct ct_enter;
+	struct work_struct ct_exit;
 
 	struct tasklet_struct irq_tasklet;
 
@@ -1089,16 +1215,22 @@ struct iwl_priv {
 
 	/* TX Power */
 	s8 tx_power_user_lmt;
-	s8 tx_power_channel_lmt;
+	s8 tx_power_device_lmt;
 
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 	/* debugging info */
-	u32 debug_level;
+	u32 debug_level; /* per device debugging will override global
+			    iwl_debug_level if set */
 	u32 framecnt_to_us;
 	atomic_t restrict_refcnt;
+	bool disable_ht40;
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 	/* debugfs */
+	u16 tx_traffic_idx;
+	u16 rx_traffic_idx;
+	u8 *tx_traffic;
+	u8 *rx_traffic;
 	struct iwl_debugfs *dbgfs;
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 #endif /* CONFIG_IWLWIFI_DEBUG */
@@ -1130,8 +1262,27 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
 
 #ifdef CONFIG_IWLWIFI_DEBUG
 const char *iwl_get_tx_fail_reason(u32 status);
+/*
+ * iwl_get_debug_level: Return active debug level for device
+ *
+ * Using sysfs it is possible to set per device debug level. This debug
+ * level will be used if set, otherwise the global debug level which can be
+ * set via module parameter is used.
+ */
+static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
+{
+	if (priv->debug_level)
+		return priv->debug_level;
+	else
+		return iwl_debug_level;
+}
 #else
 static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
+
+static inline u32 iwl_get_debug_level(struct iwl_priv *priv)
+{
+	return iwl_debug_level;
+}
 #endif
 
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 7d7554a..3d2b93a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -127,14 +127,86 @@ static const u8 iwl_eeprom_band_5[] = {	/* 5725-5825MHz */
 	145, 149, 153, 157, 161, 165
 };
 
-static const u8 iwl_eeprom_band_6[] = {       /* 2.4 FAT channel */
+static const u8 iwl_eeprom_band_6[] = {       /* 2.4 ht40 channel */
 	1, 2, 3, 4, 5, 6, 7
 };
 
-static const u8 iwl_eeprom_band_7[] = {       /* 5.2 FAT channel */
+static const u8 iwl_eeprom_band_7[] = {       /* 5.2 ht40 channel */
 	36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
 };
 
+/**
+ * struct iwl_txpwr_section: eeprom section information
+ * @offset: indirect address into eeprom image
+ * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section
+ * @band: band type for the section
+ * @is_common - true: common section, false: channel section
+ * @is_cck - true: cck section, false: not cck section
+ * @is_ht_40 - true: all channel in the section are HT40 channel,
+ * 	       false: legacy or HT 20 MHz
+ *	       ignore if it is common section
+ * @iwl_eeprom_section_channel: channel array in the section,
+ *	       ignore if common section
+ */
+struct iwl_txpwr_section {
+	u32 offset;
+	u8 count;
+	enum ieee80211_band band;
+	bool is_common;
+	bool is_cck;
+	bool is_ht40;
+	u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS];
+};
+
+/**
+ * section 1 - 3 are regulatory tx power apply to all channels based on
+ *    modulation: CCK, OFDM
+ *    Band: 2.4GHz, 5.2GHz
+ * section 4 - 10 are regulatory tx power apply to specified channels
+ *    For example:
+ *	1L - Channel 1 Legacy
+ *	1HT - Channel 1 HT
+ *	(1,+1) - Channel 1 HT40 "_above_"
+ *
+ * Section 1: all CCK channels
+ * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT
+ * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1)
+ * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT
+ * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1)
+ * Section 8: 2.4 GHz channel: 13L, 13HT
+ * Section 9: 2.4 GHz channel: 140L, 140HT
+ * Section 10: 2.4 GHz 40MHz channels: (132,+1)  (44,+1)
+ *
+ */
+static const struct iwl_txpwr_section enhinfo[] = {
+	{ EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false },
+	{ EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false },
+	{ EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false },
+	{ EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ,
+		false, false, false,
+		{1, 1, 2, 2, 10, 10, 11, 11 } },
+	{ EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ,
+		false, false, true,
+		{ 1, 2, 6, 7, 9 } },
+	{ EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ,
+		false, false, false,
+		{ 36, 64, 100, 36, 64, 100 } },
+	{ EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ,
+		false, false, true,
+		{ 36, 60, 100 } },
+	{ EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ,
+		false, false, false,
+		{ 13, 13 } },
+	{ EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ,
+		false, false, false,
+		{ 140, 140 } },
+	{ EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ,
+		false, false, true,
+		{ 132, 44 } },
+};
+
 /******************************************************************************
  *
  * EEPROM related functions
@@ -152,6 +224,19 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
 
+static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
+{
+	u32 otpgp;
+
+	otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
+	if (mode == IWL_OTP_ACCESS_ABSOLUTE)
+		iwl_clear_bit(priv, CSR_OTP_GP_REG,
+				CSR_OTP_GP_REG_OTP_ACCESS_MODE);
+	else
+		iwl_set_bit(priv, CSR_OTP_GP_REG,
+				CSR_OTP_GP_REG_OTP_ACCESS_MODE);
+}
+
 static int iwlcore_get_nvm_type(struct iwl_priv *priv)
 {
 	u32 otpgp;
@@ -159,6 +244,9 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
 
 	/* OTP only valid for CP/PP and after */
 	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+	case CSR_HW_REV_TYPE_NONE:
+		IWL_ERR(priv, "Unknown hardware type\n");
+		return -ENOENT;
 	case CSR_HW_REV_TYPE_3945:
 	case CSR_HW_REV_TYPE_4965:
 	case CSR_HW_REV_TYPE_5300:
@@ -249,6 +337,124 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
 	return ret;
 }
 
+static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
+{
+	int ret = 0;
+	u32 r;
+	u32 otpgp;
+
+	_iwl_write32(priv, CSR_EEPROM_REG,
+		     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+	ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+				  CSR_EEPROM_REG_READ_VALID_MSK,
+				  IWL_EEPROM_ACCESS_TIMEOUT);
+	if (ret < 0) {
+		IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
+		return ret;
+	}
+	r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+	/* check for ECC errors: */
+	otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
+	if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
+		/* stop in this case */
+		/* set the uncorrectable OTP ECC bit for acknowledgement */
+		iwl_set_bit(priv, CSR_OTP_GP_REG,
+			CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
+		IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n");
+		return -EINVAL;
+	}
+	if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
+		/* continue in this case */
+		/* set the correctable OTP ECC bit for acknowledgement */
+		iwl_set_bit(priv, CSR_OTP_GP_REG,
+				CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
+		IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
+	}
+	*eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
+	return 0;
+}
+
+/*
+ * iwl_is_otp_empty: check for empty OTP
+ */
+static bool iwl_is_otp_empty(struct iwl_priv *priv)
+{
+	u16 next_link_addr = 0, link_value;
+	bool is_empty = false;
+
+	/* locate the beginning of OTP link list */
+	if (!iwl_read_otp_word(priv, next_link_addr, &link_value)) {
+		if (!link_value) {
+			IWL_ERR(priv, "OTP is empty\n");
+			is_empty = true;
+		}
+	} else {
+		IWL_ERR(priv, "Unable to read first block of OTP list.\n");
+		is_empty = true;
+	}
+
+	return is_empty;
+}
+
+
+/*
+ * iwl_find_otp_image: find EEPROM image in OTP
+ *   finding the OTP block that contains the EEPROM image.
+ *   the last valid block on the link list (the block _before_ the last block)
+ *   is the block we should read and used to configure the device.
+ *   If all the available OTP blocks are full, the last block will be the block
+ *   we should read and used to configure the device.
+ *   only perform this operation if shadow RAM is disabled
+ */
+static int iwl_find_otp_image(struct iwl_priv *priv,
+					u16 *validblockaddr)
+{
+	u16 next_link_addr = 0, link_value = 0, valid_addr;
+	int ret = 0;
+	int usedblocks = 0;
+
+	/* set addressing mode to absolute to traverse the link list */
+	iwl_set_otp_access(priv, IWL_OTP_ACCESS_ABSOLUTE);
+
+	/* checking for empty OTP or error */
+	if (iwl_is_otp_empty(priv))
+		return -EINVAL;
+
+	/*
+	 * start traverse link list
+	 * until reach the max number of OTP blocks
+	 * different devices have different number of OTP blocks
+	 */
+	do {
+		/* save current valid block address
+		 * check for more block on the link list
+		 */
+		valid_addr = next_link_addr;
+		next_link_addr = link_value;
+		IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
+			       usedblocks, next_link_addr);
+		if (iwl_read_otp_word(priv, next_link_addr, &link_value))
+			return -EINVAL;
+		if (!link_value) {
+			/*
+			 * reach the end of link list,
+			 * set address point to the starting address
+			 * of the image
+			 */
+			goto done;
+		}
+		/* more in the link list, continue */
+		usedblocks++;
+	} while (usedblocks < priv->cfg->max_ll_items);
+	/* OTP full, use last block */
+	IWL_DEBUG_INFO(priv, "OTP is full, use last block\n");
+done:
+	*validblockaddr = valid_addr;
+	/* skip first 2 bytes (link list pointer) */
+	*validblockaddr += 2;
+	return ret;
+}
+
 /**
  * iwl_eeprom_init - read EEPROM contents
  *
@@ -263,14 +469,14 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 	int sz;
 	int ret;
 	u16 addr;
-	u32 otpgp;
+	u16 validblockaddr = 0;
+	u16 cache_addr = 0;
 
 	priv->nvm_device_type = iwlcore_get_nvm_type(priv);
-
+	if (priv->nvm_device_type == -ENOENT)
+		return -ENOENT;
 	/* allocate eeprom */
-	if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
-		priv->cfg->eeprom_size =
-			OTP_BLOCK_SIZE * OTP_LOWER_BLOCKS_TOTAL;
+	IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size);
 	sz = priv->cfg->eeprom_size;
 	priv->eeprom = kzalloc(sz, GFP_KERNEL);
 	if (!priv->eeprom) {
@@ -298,46 +504,31 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 		if (ret) {
 			IWL_ERR(priv, "Failed to initialize OTP access.\n");
 			ret = -ENOENT;
-			goto err;
+			goto done;
 		}
 		_iwl_write32(priv, CSR_EEPROM_GP,
 			     iwl_read32(priv, CSR_EEPROM_GP) &
 			     ~CSR_EEPROM_GP_IF_OWNER_MSK);
-		/* clear */
-		_iwl_write32(priv, CSR_OTP_GP_REG,
-			     iwl_read32(priv, CSR_OTP_GP_REG) |
+
+		iwl_set_bit(priv, CSR_OTP_GP_REG,
 			     CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
 			     CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
-
-		for (addr = 0; addr < sz; addr += sizeof(u16)) {
-			u32 r;
-
-			_iwl_write32(priv, CSR_EEPROM_REG,
-				     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
-
-			ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
-						  CSR_EEPROM_REG_READ_VALID_MSK,
-						  IWL_EEPROM_ACCESS_TIMEOUT);
-			if (ret < 0) {
-				IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
+		/* traversing the linked list if no shadow ram supported */
+		if (!priv->cfg->shadow_ram_support) {
+			if (iwl_find_otp_image(priv, &validblockaddr)) {
+				ret = -ENOENT;
 				goto done;
 			}
-			r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
-			/* check for ECC errors: */
-			otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
-			if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
-				/* stop in this case */
-				IWL_ERR(priv, "Uncorrectable OTP ECC error, Abort OTP read\n");
+		}
+		for (addr = validblockaddr; addr < validblockaddr + sz;
+		     addr += sizeof(u16)) {
+			u16 eeprom_data;
+
+			ret = iwl_read_otp_word(priv, addr, &eeprom_data);
+			if (ret)
 				goto done;
-			}
-			if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
-				/* continue in this case */
-				_iwl_write32(priv, CSR_OTP_GP_REG,
-					     iwl_read32(priv, CSR_OTP_GP_REG) |
-					     CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
-				IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
-			}
-			e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+			e[cache_addr / 2] = eeprom_data;
+			cache_addr += sizeof(u16);
 		}
 	} else {
 		/* eeprom is an array of 16bit values */
@@ -458,13 +649,13 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
 				iwl_eeprom_query_addr(priv, offset);
 		*eeprom_ch_index = iwl_eeprom_band_5;
 		break;
-	case 6:		/* 2.4GHz FAT channels */
+	case 6:		/* 2.4GHz ht40 channels */
 		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6);
 		*eeprom_ch_info = (struct iwl_eeprom_channel *)
 				iwl_eeprom_query_addr(priv, offset);
 		*eeprom_ch_index = iwl_eeprom_band_6;
 		break;
-	case 7:		/* 5 GHz FAT channels */
+	case 7:		/* 5 GHz ht40 channels */
 		*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7);
 		*eeprom_ch_info = (struct iwl_eeprom_channel *)
 				iwl_eeprom_query_addr(priv, offset);
@@ -480,14 +671,14 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
 			    ? # x " " : "")
 
 /**
- * iwl_set_fat_chan_info - Copy fat channel info into driver's priv.
+ * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
  *
  * Does not set up a command, or touch hardware.
  */
-static int iwl_set_fat_chan_info(struct iwl_priv *priv,
+static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
 			      enum ieee80211_band band, u16 channel,
 			      const struct iwl_eeprom_channel *eeprom_ch,
-			      u8 fat_extension_channel)
+			      u8 clear_ht40_extension_channel)
 {
 	struct iwl_channel_info *ch_info;
 
@@ -497,7 +688,7 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv,
 	if (!is_channel_valid(ch_info))
 		return -1;
 
-	IWL_DEBUG_INFO(priv, "FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
+	IWL_DEBUG_INFO(priv, "HT40 Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
 			" Ad-Hoc %ssupported\n",
 			ch_info->channel,
 			is_channel_a_band(ch_info) ?
@@ -513,17 +704,189 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv,
 			 && !(eeprom_ch->flags & EEPROM_CHANNEL_RADAR)) ?
 			"" : "not ");
 
-	ch_info->fat_eeprom = *eeprom_ch;
-	ch_info->fat_max_power_avg = eeprom_ch->max_power_avg;
-	ch_info->fat_curr_txpow = eeprom_ch->max_power_avg;
-	ch_info->fat_min_power = 0;
-	ch_info->fat_scan_power = eeprom_ch->max_power_avg;
-	ch_info->fat_flags = eeprom_ch->flags;
-	ch_info->fat_extension_channel = fat_extension_channel;
+	ch_info->ht40_eeprom = *eeprom_ch;
+	ch_info->ht40_max_power_avg = eeprom_ch->max_power_avg;
+	ch_info->ht40_curr_txpow = eeprom_ch->max_power_avg;
+	ch_info->ht40_min_power = 0;
+	ch_info->ht40_scan_power = eeprom_ch->max_power_avg;
+	ch_info->ht40_flags = eeprom_ch->flags;
+	ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
 
 	return 0;
 }
 
+/**
+ * iwl_get_max_txpower_avg - get the highest tx power from all chains.
+ *     find the highest tx power from all chains for the channel
+ */
+static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
+		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, int element)
+{
+	s8 max_txpower_avg = 0; /* (dBm) */
+
+	IWL_DEBUG_INFO(priv, "%d - "
+			"chain_a: %d dB chain_b: %d dB "
+			"chain_c: %d dB mimo2: %d dB mimo3: %d dB\n",
+			element,
+			enhanced_txpower[element].chain_a_max >> 1,
+			enhanced_txpower[element].chain_b_max >> 1,
+			enhanced_txpower[element].chain_c_max >> 1,
+			enhanced_txpower[element].mimo2_max >> 1,
+			enhanced_txpower[element].mimo3_max >> 1);
+	/* Take the highest tx power from any valid chains */
+	if ((priv->cfg->valid_tx_ant & ANT_A) &&
+	    (enhanced_txpower[element].chain_a_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].chain_a_max;
+	if ((priv->cfg->valid_tx_ant & ANT_B) &&
+	    (enhanced_txpower[element].chain_b_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].chain_b_max;
+	if ((priv->cfg->valid_tx_ant & ANT_C) &&
+	    (enhanced_txpower[element].chain_c_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].chain_c_max;
+	if (((priv->cfg->valid_tx_ant == ANT_AB) |
+	    (priv->cfg->valid_tx_ant == ANT_BC) |
+	    (priv->cfg->valid_tx_ant == ANT_AC)) &&
+	    (enhanced_txpower[element].mimo2_max > max_txpower_avg))
+		max_txpower_avg =  enhanced_txpower[element].mimo2_max;
+	if ((priv->cfg->valid_tx_ant == ANT_ABC) &&
+	    (enhanced_txpower[element].mimo3_max > max_txpower_avg))
+		max_txpower_avg = enhanced_txpower[element].mimo3_max;
+
+	/* max. tx power in EEPROM is in 1/2 dBm format
+	 * convert from 1/2 dBm to dBm
+	 */
+	return max_txpower_avg >> 1;
+}
+
+/**
+ * iwl_update_common_txpower: update channel tx power
+ *     update tx power per band based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_common_txpower(struct iwl_priv *priv,
+		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+		int section, int element)
+{
+	struct iwl_channel_info *ch_info;
+	int ch;
+	bool is_ht40 = false;
+	s8 max_txpower_avg; /* (dBm) */
+
+	/* it is common section, contain all type (Legacy, HT and HT40)
+	 * based on the element in the section to determine
+	 * is it HT 40 or not
+	 */
+	if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX)
+		is_ht40 = true;
+	max_txpower_avg =
+		iwl_get_max_txpower_avg(priv, enhanced_txpower, element);
+	ch_info = priv->channel_info;
+
+	for (ch = 0; ch < priv->channel_count; ch++) {
+		/* find matching band and update tx power if needed */
+		if ((ch_info->band == enhinfo[section].band) &&
+		    (ch_info->max_power_avg < max_txpower_avg) && (!is_ht40)) {
+			/* Update regulatory-based run-time data */
+			ch_info->max_power_avg = ch_info->curr_txpow =
+			    max_txpower_avg;
+			ch_info->scan_power = max_txpower_avg;
+		}
+		if ((ch_info->band == enhinfo[section].band) && is_ht40 &&
+		    ch_info->ht40_max_power_avg &&
+		    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+			/* Update regulatory-based run-time data */
+			ch_info->ht40_max_power_avg = max_txpower_avg;
+			ch_info->ht40_curr_txpow = max_txpower_avg;
+			ch_info->ht40_scan_power = max_txpower_avg;
+		}
+		ch_info++;
+	}
+	return max_txpower_avg;
+}
+
+/**
+ * iwl_update_channel_txpower: update channel tx power
+ *      update channel tx power based on EEPROM enhanced tx power info.
+ */
+static s8 iwl_update_channel_txpower(struct iwl_priv *priv,
+		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
+		int section, int element)
+{
+	struct iwl_channel_info *ch_info;
+	int ch;
+	u8 channel;
+	s8 max_txpower_avg; /* (dBm) */
+
+	channel = enhinfo[section].iwl_eeprom_section_channel[element];
+	max_txpower_avg =
+		iwl_get_max_txpower_avg(priv, enhanced_txpower, element);
+
+	ch_info = priv->channel_info;
+	for (ch = 0; ch < priv->channel_count; ch++) {
+		/* find matching channel and update tx power if needed */
+		if (ch_info->channel == channel) {
+			if ((ch_info->max_power_avg < max_txpower_avg) &&
+			    (!enhinfo[section].is_ht40)) {
+				/* Update regulatory-based run-time data */
+				ch_info->max_power_avg = max_txpower_avg;
+				ch_info->curr_txpow = max_txpower_avg;
+				ch_info->scan_power = max_txpower_avg;
+			}
+			if ((enhinfo[section].is_ht40) &&
+			    (ch_info->ht40_max_power_avg) &&
+			    (ch_info->ht40_max_power_avg < max_txpower_avg)) {
+				/* Update regulatory-based run-time data */
+				ch_info->ht40_max_power_avg = max_txpower_avg;
+				ch_info->ht40_curr_txpow = max_txpower_avg;
+				ch_info->ht40_scan_power = max_txpower_avg;
+			}
+			break;
+		}
+		ch_info++;
+	}
+	return max_txpower_avg;
+}
+
+/**
+ * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info
+ */
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv)
+{
+	int eeprom_section_count = 0;
+	int section, element;
+	struct iwl_eeprom_enhanced_txpwr *enhanced_txpower;
+	u32 offset;
+	s8 max_txpower_avg; /* (dBm) */
+
+	/* Loop through all the sections
+	 * adjust bands and channel's max tx power
+	 * Set the tx_power_user_lmt to the highest power
+	 * supported by any channels and chains
+	 */
+	for (section = 0; section < ARRAY_SIZE(enhinfo); section++) {
+		eeprom_section_count = enhinfo[section].count;
+		offset = enhinfo[section].offset;
+		enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *)
+				iwl_eeprom_query_addr(priv, offset);
+
+		for (element = 0; element < eeprom_section_count; element++) {
+			if (enhinfo[section].is_common)
+				max_txpower_avg =
+					iwl_update_common_txpower(priv,
+					enhanced_txpower, section, element);
+			else
+				max_txpower_avg =
+					iwl_update_channel_txpower(priv,
+					enhanced_txpower, section, element);
+
+			/* Update the tx_power_user_lmt to the highest power
+			 * supported by any channel */
+			if (max_txpower_avg > priv->tx_power_user_lmt)
+				priv->tx_power_user_lmt = max_txpower_avg;
+		}
+	}
+}
+EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower);
+
 #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
 			    ? # x " " : "")
 
@@ -585,11 +948,10 @@ int iwl_init_channel_map(struct iwl_priv *priv)
 			/* Copy the run-time flags so they are there even on
 			 * invalid channels */
 			ch_info->flags = eeprom_ch_info[ch].flags;
-			/* First write that fat is not enabled, and then enable
+			/* First write that ht40 is not enabled, and then enable
 			 * one by one */
-			ch_info->fat_extension_channel =
-				(IEEE80211_CHAN_NO_HT40PLUS |
-				 IEEE80211_CHAN_NO_HT40MINUS);
+			ch_info->ht40_extension_channel =
+					IEEE80211_CHAN_NO_HT40;
 
 			if (!(is_channel_valid(ch_info))) {
 				IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
@@ -638,17 +1000,16 @@ int iwl_init_channel_map(struct iwl_priv *priv)
 		}
 	}
 
-	/* Check if we do have FAT channels */
+	/* Check if we do have HT40 channels */
 	if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
-	    EEPROM_REGULATORY_BAND_NO_FAT &&
+	    EEPROM_REGULATORY_BAND_NO_HT40 &&
 	    priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
-	    EEPROM_REGULATORY_BAND_NO_FAT)
+	    EEPROM_REGULATORY_BAND_NO_HT40)
 		return 0;
 
-	/* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
+	/* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */
 	for (band = 6; band <= 7; band++) {
 		enum ieee80211_band ieeeband;
-		u8 fat_extension_chan;
 
 		iwl_init_band_reference(priv, band, &eeprom_ch_count,
 					&eeprom_ch_info, &eeprom_ch_index);
@@ -659,31 +1020,28 @@ int iwl_init_channel_map(struct iwl_priv *priv)
 
 		/* Loop through each band adding each of the channels */
 		for (ch = 0; ch < eeprom_ch_count; ch++) {
-
-			if ((band == 6) &&
-				((eeprom_ch_index[ch] == 5) ||
-				 (eeprom_ch_index[ch] == 6) ||
-				 (eeprom_ch_index[ch] == 7)))
-				/* both are allowed: above and below */
-				fat_extension_chan = 0;
-			else
-				fat_extension_chan =
-					IEEE80211_CHAN_NO_HT40MINUS;
-
 			/* Set up driver's info for lower half */
-			iwl_set_fat_chan_info(priv, ieeeband,
+			iwl_mod_ht40_chan_info(priv, ieeeband,
 						eeprom_ch_index[ch],
-						&(eeprom_ch_info[ch]),
-						fat_extension_chan);
+						&eeprom_ch_info[ch],
+						IEEE80211_CHAN_NO_HT40PLUS);
 
 			/* Set up driver's info for upper half */
-			iwl_set_fat_chan_info(priv, ieeeband,
-						(eeprom_ch_index[ch] + 4),
-						&(eeprom_ch_info[ch]),
-						IEEE80211_CHAN_NO_HT40PLUS);
+			iwl_mod_ht40_chan_info(priv, ieeeband,
+						eeprom_ch_index[ch] + 4,
+						&eeprom_ch_info[ch],
+						IEEE80211_CHAN_NO_HT40MINUS);
 		}
 	}
 
+	/* for newer device (6000 series and up)
+	 * EEPROM contain enhanced tx power information
+	 * driver need to process addition information
+	 * to determine the max channel tx power limits
+	 */
+	if (priv->cfg->ops->lib->eeprom_ops.update_enhanced_txpower)
+		priv->cfg->ops->lib->eeprom_ops.update_enhanced_txpower(priv);
+
 	return 0;
 }
 EXPORT_SYMBOL(iwl_init_channel_map);
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 195b4ef..6b68db7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -88,10 +88,10 @@ struct iwl_priv;
  * requirement for establishing a new network for legal operation on channels
  * requiring RADAR detection or restricting ACTIVE scanning.
  *
- * NOTE:  "WIDE" flag does not indicate anything about "FAT" 40 MHz channels.
- *        It only indicates that 20 MHz channel use is supported; FAT channel
+ * NOTE:  "WIDE" flag does not indicate anything about "HT40" 40 MHz channels.
+ *        It only indicates that 20 MHz channel use is supported; HT40 channel
  *        usage is indicated by a separate set of regulatory flags for each
- *        FAT channel pair.
+ *        HT40 channel pair.
  *
  * NOTE:  Using a channel inappropriately will result in a uCode error!
  */
@@ -112,12 +112,36 @@ enum {
 #define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE                (1 << 1)
 
 /* *regulatory* channel data format in eeprom, one for each channel.
- * There are separate entries for FAT (40 MHz) vs. normal (20 MHz) channels. */
+ * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */
 struct iwl_eeprom_channel {
 	u8 flags;		/* EEPROM_CHANNEL_* flags copied from EEPROM */
 	s8 max_power_avg;	/* max power (dBm) on this chnl, limit 31 */
 } __attribute__ ((packed));
 
+/**
+ * iwl_eeprom_enhanced_txpwr structure
+ *    This structure presents the enhanced regulatory tx power limit layout
+ *    in eeprom image
+ *    Enhanced regulatory tx power portion of eeprom image can be broken down
+ *    into individual structures; each one is 8 bytes in size and contain the
+ *    following information
+ * @chain_a_max_pwr: chain a max power in 1/2 dBm
+ * @chain_b_max_pwr: chain b max power in 1/2 dBm
+ * @chain_c_max_pwr: chain c max power in 1/2 dBm
+ * @mimo2_max_pwr: mimo2 max power in 1/2 dBm
+ * @mimo3_max_pwr: mimo3 max power in 1/2 dBm
+ *
+ */
+struct iwl_eeprom_enhanced_txpwr {
+	u16 reserved;
+	s8 chain_a_max;
+	s8 chain_b_max;
+	s8 chain_c_max;
+	s8 reserved1;
+	s8 mimo2_max;
+	s8 mimo3_max;
+} __attribute__ ((packed));
+
 /* 3945 Specific */
 #define EEPROM_3945_EEPROM_VERSION	(0x2f)
 
@@ -170,18 +194,77 @@ struct iwl_eeprom_channel {
 		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 22 bytes */
 #define EEPROM_5000_REG_BAND_5_CHANNELS       ((0x74)\
 		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 12 bytes */
-#define EEPROM_5000_REG_BAND_24_FAT_CHANNELS  ((0x82)\
+#define EEPROM_5000_REG_BAND_24_HT40_CHANNELS  ((0x82)\
 		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 14  bytes */
-#define EEPROM_5000_REG_BAND_52_FAT_CHANNELS  ((0x92)\
+#define EEPROM_5000_REG_BAND_52_HT40_CHANNELS  ((0x92)\
 		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 22  bytes */
 
+/* 6000 and up regulatory tx power - indirect access */
+/* max. elements per section */
+#define EEPROM_MAX_TXPOWER_SECTION_ELEMENTS	(8)
+#define EEPROM_TXPOWER_COMMON_HT40_INDEX	(2)
+
+/**
+ * Partition the enhanced tx power portion of eeprom image into
+ * 10 sections based on band, modulation, frequency and channel
+ *
+ * Section 1: all CCK channels
+ * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40 ) channels
+ * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels
+ * Section 4: 2.4 GHz 20MHz channels: 1, 2, 10, 11. Both Legacy and HT
+ * Section 5: 2.4 GHz 40MHz channels: 1, 2, 6, 7, 9, (_above_)
+ * Section 6: 5.2 GHz 20MHz channels: 36, 64, 100, both Legacy and HT
+ * Section 7: 5.2 GHz 40MHz channels: 36, 60, 100 (_above_)
+ * Section 8: 2.4 GHz channel 13, Both Legacy and HT
+ * Section 9: 2.4 GHz channel 140, Both Legacy and HT
+ * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
+ */
+/* 2.4 GHz band: CCK */
+#define EEPROM_LB_CCK_20_COMMON       ((0xAA)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 8 bytes */
+/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
+#define EEPROM_LB_OFDM_COMMON       ((0xB2)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 24 bytes */
+/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
+#define EEPROM_HB_OFDM_COMMON       ((0xCA)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 24 bytes */
+/* 2.4GHz band channels:
+ *	1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
+#define EEPROM_LB_OFDM_20_BAND       ((0xE2)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 64 bytes */
+/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
+#define EEPROM_LB_OFDM_HT40_BAND       ((0x122)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 40 bytes */
+/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
+#define EEPROM_HB_OFDM_20_BAND       ((0x14A)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 48 bytes */
+/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
+#define EEPROM_HB_OFDM_HT40_BAND       ((0x17A)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 24 bytes */
+/* 2.4 GHz band, channnel 13: Legacy, HT */
+#define EEPROM_LB_OFDM_20_CHANNEL_13       ((0x192)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 16 bytes */
+/* 5.2 GHz band, channnel 140: Legacy, HT */
+#define EEPROM_HB_OFDM_20_CHANNEL_140       ((0x1A2)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 16 bytes */
+/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
+#define EEPROM_HB_OFDM_HT40_BAND_1       ((0x1B2)\
+		| INDIRECT_ADDRESS | INDIRECT_REGULATORY)   /* 16 bytes */
+
+
 /* 5050 Specific */
 #define EEPROM_5050_TX_POWER_VERSION    (4)
 #define EEPROM_5050_EEPROM_VERSION	(0x21E)
 
 /* OTP */
-#define OTP_LOWER_BLOCKS_TOTAL		(3)
-#define OTP_BLOCK_SIZE			(0x400)
+/* lower blocks contain EEPROM image and calibration data */
+#define OTP_LOW_IMAGE_SIZE		(2 * 512 * sizeof(u16)) /* 2 KB */
+/* high blocks contain PAPD data */
+#define OTP_HIGH_IMAGE_SIZE_6x00        (6 * 512 * sizeof(u16)) /* 6 KB */
+#define OTP_HIGH_IMAGE_SIZE_1000        (0x200 * sizeof(u16)) /* 1024 bytes */
+#define OTP_MAX_LL_ITEMS_1000		(3)	/* OTP blocks for 1000 */
+#define OTP_MAX_LL_ITEMS_6x00		(4)	/* OTP blocks for 6x00 */
+#define OTP_MAX_LL_ITEMS_6x50		(7)	/* OTP blocks for 6x50 */
 
 /* 2.4 GHz */
 extern const u8 iwl_eeprom_band_1[14];
@@ -313,7 +396,7 @@ struct iwl_eeprom_calib_info {
  * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
  * txpower (MSB).
  *
- * Entries immediately below are for 20 MHz channel width.  FAT (40 MHz)
+ * Entries immediately below are for 20 MHz channel width.  HT40 (40 MHz)
  * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
  *
  * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
@@ -352,29 +435,29 @@ struct iwl_eeprom_calib_info {
 #define EEPROM_REGULATORY_BAND_5_CHANNELS   (2*0x99)	/* 12 bytes */
 
 /*
- * 2.4 GHz FAT channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
+ * 2.4 GHz HT40 channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
  *
  * The channel listed is the center of the lower 20 MHz half of the channel.
  * The overall center frequency is actually 2 channels (10 MHz) above that,
- * and the upper half of each FAT channel is centered 4 channels (20 MHz) away
- * from the lower half; e.g. the upper half of FAT channel 1 is channel 5,
- * and the overall FAT channel width centers on channel 3.
+ * and the upper half of each HT40 channel is centered 4 channels (20 MHz) away
+ * from the lower half; e.g. the upper half of HT40 channel 1 is channel 5,
+ * and the overall HT40 channel width centers on channel 3.
  *
  * NOTE:  The RXON command uses 20 MHz channel numbers to specify the
  *        control channel to which to tune.  RXON also specifies whether the
- *        control channel is the upper or lower half of a FAT channel.
+ *        control channel is the upper or lower half of a HT40 channel.
  *
- * NOTE:  4965 does not support FAT channels on 2.4 GHz.
+ * NOTE:  4965 does not support HT40 channels on 2.4 GHz.
  */
-#define EEPROM_4965_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0)	/* 14 bytes */
+#define EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS (2*0xA0)	/* 14 bytes */
 
 /*
- * 5.2 GHz FAT channels 36 (40), 44 (48), 52 (56), 60 (64),
+ * 5.2 GHz HT40 channels 36 (40), 44 (48), 52 (56), 60 (64),
  * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
  */
-#define EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8)	/* 22 bytes */
+#define EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS (2*0xA8)	/* 22 bytes */
 
-#define EEPROM_REGULATORY_BAND_NO_FAT			(0)
+#define EEPROM_REGULATORY_BAND_NO_HT40			(0)
 
 struct iwl_eeprom_ops {
 	const u32 regulatory_bands[7];
@@ -383,6 +466,7 @@ struct iwl_eeprom_ops {
 	void (*release_semaphore) (struct iwl_priv *priv);
 	u16 (*calib_version) (struct iwl_priv *priv);
 	const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
+	void (*update_enhanced_txpower) (struct iwl_priv *priv);
 };
 
 
@@ -397,7 +481,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
 int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
 void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
 const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
-
+void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
 int iwl_init_channel_map(struct iwl_priv *priv);
 void iwl_free_channel_map(struct iwl_priv *priv);
 const struct iwl_channel_info *iwl_get_channel_info(
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 17d61ac..532c8d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -36,8 +36,6 @@
 #include "iwl-core.h"
 
 
-#define IWL_CMD(x) case x: return #x
-
 const char *get_cmd_string(u8 cmd)
 {
 	switch (cmd) {
@@ -103,22 +101,23 @@ EXPORT_SYMBOL(get_cmd_string);
 
 #define HOST_COMPLETE_TIMEOUT (HZ / 2)
 
-static int iwl_generic_cmd_callback(struct iwl_priv *priv,
-				    struct iwl_cmd *cmd, struct sk_buff *skb)
+static void iwl_generic_cmd_callback(struct iwl_priv *priv,
+				     struct iwl_device_cmd *cmd,
+				     struct sk_buff *skb)
 {
 	struct iwl_rx_packet *pkt = NULL;
 
 	if (!skb) {
 		IWL_ERR(priv, "Error: Response NULL in %s.\n",
 				get_cmd_string(cmd->hdr.cmd));
-		return 1;
+		return;
 	}
 
 	pkt = (struct iwl_rx_packet *)skb->data;
 	if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
 			get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-		return 1;
+		return;
 	}
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -127,29 +126,26 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
 	case SENSITIVITY_CMD:
 		IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
 				get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-				break;
+		break;
 	default:
 		IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
 				get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
 	}
 #endif
-
-	/* Let iwl_tx_complete free the response skb */
-	return 1;
 }
 
 static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
 	int ret;
 
-	BUG_ON(!(cmd->meta.flags & CMD_ASYNC));
+	BUG_ON(!(cmd->flags & CMD_ASYNC));
 
 	/* An asynchronous command can not expect an SKB to be set. */
-	BUG_ON(cmd->meta.flags & CMD_WANT_SKB);
+	BUG_ON(cmd->flags & CMD_WANT_SKB);
 
 	/* Assign a generic callback if one is not provided */
-	if (!cmd->meta.u.callback)
-		cmd->meta.u.callback = iwl_generic_cmd_callback;
+	if (!cmd->callback)
+		cmd->callback = iwl_generic_cmd_callback;
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return -EBUSY;
@@ -168,10 +164,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	int cmd_idx;
 	int ret;
 
-	BUG_ON(cmd->meta.flags & CMD_ASYNC);
+	BUG_ON(cmd->flags & CMD_ASYNC);
 
 	 /* A synchronous command can not have a callback set. */
-	BUG_ON(cmd->meta.u.callback != NULL);
+	BUG_ON(cmd->callback);
 
 	if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
 		IWL_ERR(priv,
@@ -183,9 +179,6 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
 	set_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
-	if (cmd->meta.flags & CMD_WANT_SKB)
-		cmd->meta.source = &cmd->meta;
-
 	cmd_idx = iwl_enqueue_hcmd(priv, cmd);
 	if (cmd_idx < 0) {
 		ret = cmd_idx;
@@ -222,7 +215,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 		ret = -EIO;
 		goto fail;
 	}
-	if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
+	if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_skb) {
 		IWL_ERR(priv, "Error: Response NULL in '%s'\n",
 			  get_cmd_string(cmd->id));
 		ret = -EIO;
@@ -233,20 +226,20 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	goto out;
 
 cancel:
-	if (cmd->meta.flags & CMD_WANT_SKB) {
-		struct iwl_cmd *qcmd;
-
-		/* Cancel the CMD_WANT_SKB flag for the cmd in the
+	if (cmd->flags & CMD_WANT_SKB) {
+		/*
+		 * Cancel the CMD_WANT_SKB flag for the cmd in the
 		 * TX cmd queue. Otherwise in case the cmd comes
 		 * in later, it will possibly set an invalid
-		 * address (cmd->meta.source). */
-		qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
-		qcmd->meta.flags &= ~CMD_WANT_SKB;
+		 * address (cmd->meta.source).
+		 */
+		priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &=
+							~CMD_WANT_SKB;
 	}
 fail:
-	if (cmd->meta.u.skb) {
-		dev_kfree_skb_any(cmd->meta.u.skb);
-		cmd->meta.u.skb = NULL;
+	if (cmd->reply_skb) {
+		dev_kfree_skb_any(cmd->reply_skb);
+		cmd->reply_skb = NULL;
 	}
 out:
 	clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
@@ -256,7 +249,7 @@ EXPORT_SYMBOL(iwl_send_cmd_sync);
 
 int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
-	if (cmd->meta.flags & CMD_ASYNC)
+	if (cmd->flags & CMD_ASYNC)
 		return iwl_send_cmd_async(priv, cmd);
 
 	return iwl_send_cmd_sync(priv, cmd);
@@ -277,9 +270,9 @@ EXPORT_SYMBOL(iwl_send_cmd_pdu);
 
 int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
 			   u8 id, u16 len, const void *data,
-			   int (*callback)(struct iwl_priv *priv,
-					   struct iwl_cmd *cmd,
-					   struct sk_buff *skb))
+			   void (*callback)(struct iwl_priv *priv,
+					    struct iwl_device_cmd *cmd,
+					    struct sk_buff *skb))
 {
 	struct iwl_host_cmd cmd = {
 		.id = id,
@@ -287,8 +280,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
 		.data = data,
 	};
 
-	cmd.meta.flags |= CMD_ASYNC;
-	cmd.meta.u.callback = callback;
+	cmd.flags |= CMD_ASYNC;
+	cmd.callback = callback;
 
 	return iwl_send_cmd_async(priv, &cmd);
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index a1328c3..bd0b12e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -145,4 +145,25 @@ static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
 #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
 #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
 
+static inline void iwl_disable_interrupts(struct iwl_priv *priv)
+{
+	clear_bit(STATUS_INT_ENABLED, &priv->status);
+
+	/* disable interrupts from uCode/NIC to host */
+	iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+	/* acknowledge/clear/reset any interrupts still pending
+	 * from uCode or flow handler (Rx/Tx DMA) */
+	iwl_write32(priv, CSR_INT, 0xffffffff);
+	iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
+	IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
+}
+
+static inline void iwl_enable_interrupts(struct iwl_priv *priv)
+{
+	IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
+	set_bit(STATUS_INT_ENABLED, &priv->status);
+	iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
+}
+
 #endif				/* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 5e64252..f420c99 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -54,7 +54,7 @@ static const char *led_type_str[] = {
 
 
 static const struct {
-	u16 tpt;
+	u16 tpt;	/* Mb/s */
 	u8 on_time;
 	u8 off_time;
 } blink_tbl[] =
@@ -91,8 +91,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
 		.id = REPLY_LEDS_CMD,
 		.len = sizeof(struct iwl_led_cmd),
 		.data = led_cmd,
-		.meta.flags = CMD_ASYNC,
-		.meta.u.callback = NULL,
+		.flags = CMD_ASYNC,
+		.callback = NULL,
 	};
 	u32 reg;
 
@@ -104,7 +104,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
 }
 
 /* Set led pattern command */
-static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id,
+static int iwl_led_pattern(struct iwl_priv *priv, int led_id,
 			       unsigned int idx)
 {
 	struct iwl_led_cmd led_cmd = {
@@ -121,7 +121,7 @@ static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id,
 }
 
 /* Set led register off */
-static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
+static int iwl_led_on_reg(struct iwl_priv *priv, int led_id)
 {
 	IWL_DEBUG_LED(priv, "led on %d\n", led_id);
 	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
@@ -130,7 +130,7 @@ static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
 
 #if 0
 /* Set led on command */
-static int iwl4965_led_on(struct iwl_priv *priv, int led_id)
+static int iwl_led_on(struct iwl_priv *priv, int led_id)
 {
 	struct iwl_led_cmd led_cmd = {
 		.id = led_id,
@@ -142,7 +142,7 @@ static int iwl4965_led_on(struct iwl_priv *priv, int led_id)
 }
 
 /* Set led off command */
-int iwl4965_led_off(struct iwl_priv *priv, int led_id)
+int iwl_led_off(struct iwl_priv *priv, int led_id)
 {
 	struct iwl_led_cmd led_cmd = {
 		.id = led_id,
@@ -157,7 +157,7 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
 
 
 /* Set led register off */
-static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
+static int iwl_led_off_reg(struct iwl_priv *priv, int led_id)
 {
 	IWL_DEBUG_LED(priv, "LED Reg off\n");
 	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
@@ -171,7 +171,7 @@ static int iwl_led_associate(struct iwl_priv *priv, int led_id)
 {
 	IWL_DEBUG_LED(priv, "Associated\n");
 	priv->allow_blinking = 1;
-	return iwl4965_led_on_reg(priv, led_id);
+	return iwl_led_on_reg(priv, led_id);
 }
 static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
 {
@@ -264,13 +264,16 @@ static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
 
 
 /*
- * calculate blink rate according to last 2 sec Tx/Rx activities
+ * calculate blink rate according to last second Tx/Rx activities
  */
 static int iwl_get_blink_rate(struct iwl_priv *priv)
 {
 	int i;
-	u64 current_tpt = priv->tx_stats[2].bytes;
-	/* FIXME: + priv->rx_stats[2].bytes; */
+	/* count both tx and rx traffic to be able to
+	 * handle traffic in either direction
+	 */
+	u64 current_tpt = priv->tx_stats.data_bytes +
+			  priv->rx_stats.data_bytes;
 	s64 tpt = current_tpt - priv->led_tpt;
 
 	if (tpt < 0) /* wraparound */
@@ -314,7 +317,7 @@ void iwl_leds_background(struct iwl_priv *priv)
 		priv->last_blink_time = 0;
 		if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
 			priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
-			iwl4965_led_pattern(priv, IWL_LED_LINK,
+			iwl_led_pattern(priv, IWL_LED_LINK,
 					    IWL_SOLID_BLINK_IDX);
 		}
 		return;
@@ -328,12 +331,11 @@ void iwl_leds_background(struct iwl_priv *priv)
 
 	/* call only if blink rate change */
 	if (blink_idx != priv->last_blink_rate)
-		iwl4965_led_pattern(priv, IWL_LED_LINK, blink_idx);
+		iwl_led_pattern(priv, IWL_LED_LINK, blink_idx);
 
 	priv->last_blink_time = jiffies;
 	priv->last_blink_rate = blink_idx;
 }
-EXPORT_SYMBOL(iwl_leds_background);
 
 /* Register all led handler */
 int iwl_leds_register(struct iwl_priv *priv)
@@ -351,8 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv)
 		 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
 		 wiphy_name(priv->hw->wiphy));
 
-	priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
-	priv->led[IWL_LED_TRG_RADIO].led_off = iwl4965_led_off_reg;
+	priv->led[IWL_LED_TRG_RADIO].led_on = iwl_led_on_reg;
+	priv->led[IWL_LED_TRG_RADIO].led_off = iwl_led_off_reg;
 	priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
 
 	ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
@@ -386,7 +388,7 @@ int iwl_leds_register(struct iwl_priv *priv)
 
 	priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
 	priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
-	priv->led[IWL_LED_TRG_RX].led_pattern = iwl4965_led_pattern;
+	priv->led[IWL_LED_TRG_RX].led_pattern = iwl_led_pattern;
 
 	if (ret)
 		goto exit_fail;
@@ -401,7 +403,7 @@ int iwl_leds_register(struct iwl_priv *priv)
 
 	priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
 	priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
-	priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern;
+	priv->led[IWL_LED_TRG_TX].led_pattern = iwl_led_pattern;
 
 	if (ret)
 		goto exit_fail;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index f2ea3f0..60be976 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -36,25 +36,41 @@
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
+#include "iwl-io.h"
 #include "iwl-commands.h"
 #include "iwl-debug.h"
 #include "iwl-power.h"
 
 /*
- * Setting power level allow the card to go to sleep when not busy.
+ * Setting power level allows the card to go to sleep when not busy.
  *
- * The power level is set to INDEX_1 (the least deep state) by
- * default, and will, in the future, be the deepest state unless
- * otherwise required by pm_qos network latency requirements.
- *
- * Using INDEX_1 without pm_qos is ok because mac80211 will disable
- * PS when even checking every beacon for the TIM bit would exceed
- * the required latency.
+ * We calculate a sleep command based on the required latency, which
+ * we get from mac80211. In order to handle thermal throttling, we can
+ * also use pre-defined power levels.
  */
 
-#define IWL_POWER_RANGE_0_MAX  (2)
-#define IWL_POWER_RANGE_1_MAX  (10)
+/*
+ * For now, keep using power level 1 instead of automatically
+ * adjusting ...
+ */
+bool no_sleep_autoadjust = true;
+module_param(no_sleep_autoadjust, bool, S_IRUGO);
+MODULE_PARM_DESC(no_sleep_autoadjust,
+		 "don't automatically adjust sleep level "
+		 "according to maximum network latency");
 
+/*
+ * This defines the old power levels. They are still used by default
+ * (level 1) and for thermal throttle (levels 3 through 5)
+ */
+
+struct iwl_power_vec_entry {
+	struct iwl_powertable_cmd cmd;
+	u8 no_dtim;
+};
+
+#define IWL_DTIM_RANGE_0_MAX	2
+#define IWL_DTIM_RANGE_1_MAX	10
 
 #define NOSLP cpu_to_le16(0), 0, 0
 #define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
@@ -66,9 +82,8 @@
 				     cpu_to_le32(X3), \
 				     cpu_to_le32(X4)}
 /* default power management (not Tx power) table values */
-/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */
+/* for DTIM period 0 through IWL_DTIM_RANGE_0_MAX */
 static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
-	{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 2, 2, 2, 0xFF)}, 0},
@@ -77,9 +92,8 @@ static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
 };
 
 
-/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */
+/* for DTIM period IWL_DTIM_RANGE_0_MAX + 1 through IWL_DTIM_RANGE_1_MAX */
 static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
-	{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
 	{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 4, 6, 7, 9)}, 0},
@@ -87,9 +101,8 @@ static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
 	{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
 };
 
-/* for DTIM period > IWL_POWER_RANGE_1_MAX */
+/* for DTIM period > IWL_DTIM_RANGE_1_MAX */
 static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
-	{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
 	{{SLP, SLP_TOUT(50), SLP_TOUT(100), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
@@ -97,80 +110,29 @@ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
 	{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
 };
 
-
-/* set card power command */
-static int iwl_set_power(struct iwl_priv *priv, void *cmd)
-{
-	return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
-				sizeof(struct iwl_powertable_cmd), cmd);
-}
-
-/* initialize to default */
-static void iwl_power_init_handle(struct iwl_priv *priv)
-{
-	struct iwl_power_mgr *pow_data;
-	int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM;
-	struct iwl_powertable_cmd *cmd;
-	int i;
-	u16 lctl;
-
-	IWL_DEBUG_POWER(priv, "Initialize power \n");
-
-	pow_data = &priv->power_data;
-
-	memset(pow_data, 0, sizeof(*pow_data));
-
-	memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
-	memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
-	memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);
-
-	lctl = iwl_pcie_link_ctl(priv);
-
-	IWL_DEBUG_POWER(priv, "adjust power command flags\n");
-
-	for (i = 0; i < IWL_POWER_NUM; i++) {
-		cmd = &pow_data->pwr_range_0[i].cmd;
-
-		if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
-			cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
-		else
-			cmd->flags |= IWL_POWER_PCI_PM_MSK;
-	}
-}
-
-/* adjust power command according to DTIM period and power level*/
-static int iwl_update_power_cmd(struct iwl_priv *priv,
-				struct iwl_powertable_cmd *cmd, u16 mode)
+static void iwl_static_sleep_cmd(struct iwl_priv *priv,
+				 struct iwl_powertable_cmd *cmd,
+				 enum iwl_power_level lvl, int period)
 {
-	struct iwl_power_vec_entry *range;
-	struct iwl_power_mgr *pow_data;
-	int i;
-	u32 max_sleep = 0;
-	u8 period;
+	const struct iwl_power_vec_entry *table;
+	int max_sleep, i;
 	bool skip;
 
-	if (mode > IWL_POWER_INDEX_5) {
-		IWL_DEBUG_POWER(priv, "Error invalid power mode \n");
-		return -EINVAL;
-	}
+	table = range_2;
+	if (period < IWL_DTIM_RANGE_1_MAX)
+		table = range_1;
+	if (period < IWL_DTIM_RANGE_0_MAX)
+		table = range_0;
 
-	pow_data = &priv->power_data;
+	BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
 
-	if (pow_data->dtim_period <= IWL_POWER_RANGE_0_MAX)
-		range = &pow_data->pwr_range_0[0];
-	else if (pow_data->dtim_period <= IWL_POWER_RANGE_1_MAX)
-		range = &pow_data->pwr_range_1[0];
-	else
-		range = &pow_data->pwr_range_2[0];
-
-	period = pow_data->dtim_period;
-	memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd));
+	*cmd = table[lvl].cmd;
 
 	if (period == 0) {
-		period = 1;
 		skip = false;
+		period = 1;
 	} else {
-		skip = !!range[mode].no_dtim;
+		skip = !!table[lvl].no_dtim;
 	}
 
 	if (skip) {
@@ -178,7 +140,7 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
 		max_sleep = le32_to_cpu(slp_itrvl);
 		if (max_sleep == 0xFF)
 			max_sleep = period * (skip + 1);
-		else if (max_sleep >  period)
+		else if (max_sleep > period)
 			max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
 		cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
 	} else {
@@ -190,6 +152,112 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
 		if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
 			cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
 
+	if (priv->power_data.pci_pm)
+		cmd->flags |= IWL_POWER_PCI_PM_MSK;
+	else
+		cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
+
+	IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1);
+}
+
+/* default Thermal Throttling transaction table
+ * Current state   |         Throttling Down               |  Throttling Up
+ *=============================================================================
+ *                 Condition Nxt State  Condition Nxt State Condition Nxt State
+ *-----------------------------------------------------------------------------
+ *     IWL_TI_0     T >= 115   CT_KILL  115>T>=105   TI_1      N/A      N/A
+ *     IWL_TI_1     T >= 115   CT_KILL  115>T>=110   TI_2     T<=95     TI_0
+ *     IWL_TI_2     T >= 115   CT_KILL                        T<=100    TI_1
+ *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
+ *=============================================================================
+ */
+static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
+	{IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
+	{IWL_TI_1, 105, CT_KILL_THRESHOLD},
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
+	{IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
+	{IWL_TI_2, 110, CT_KILL_THRESHOLD},
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
+	{IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
+	{IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+};
+static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
+	{IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
+	{IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
+	{IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
+};
+
+/* Advance Thermal Throttling default restriction table */
+static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
+	{IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true },
+	{IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true },
+	{IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false },
+	{IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false }
+};
+
+
+static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv,
+				    struct iwl_powertable_cmd *cmd)
+{
+	memset(cmd, 0, sizeof(*cmd));
+
+	if (priv->power_data.pci_pm)
+		cmd->flags |= IWL_POWER_PCI_PM_MSK;
+
+	IWL_DEBUG_POWER(priv, "Sleep command for CAM\n");
+}
+
+static void iwl_power_fill_sleep_cmd(struct iwl_priv *priv,
+				     struct iwl_powertable_cmd *cmd,
+				     int dynps_ms, int wakeup_period)
+{
+	/*
+	 * These are the original power level 3 sleep successions. The
+	 * device may behave better with such succession and was also
+	 * only tested with that. Just like the original sleep commands,
+	 * also adjust the succession here to the wakeup_period below.
+	 * The ranges are the same as for the sleep commands, 0-2, 3-9
+	 * and >10, which is selected based on the DTIM interval for
+	 * the sleep index but here we use the wakeup period since that
+	 * is what we need to do for the latency requirements.
+	 */
+	static const u8 slp_succ_r0[IWL_POWER_VEC_SIZE] = { 2, 2, 2, 2, 2 };
+	static const u8 slp_succ_r1[IWL_POWER_VEC_SIZE] = { 2, 4, 6, 7, 9 };
+	static const u8 slp_succ_r2[IWL_POWER_VEC_SIZE] = { 2, 7, 9, 9, 0xFF };
+	const u8 *slp_succ = slp_succ_r0;
+	int i;
+
+	if (wakeup_period > IWL_DTIM_RANGE_0_MAX)
+		slp_succ = slp_succ_r1;
+	if (wakeup_period > IWL_DTIM_RANGE_1_MAX)
+		slp_succ = slp_succ_r2;
+
+	memset(cmd, 0, sizeof(*cmd));
+
+	cmd->flags = IWL_POWER_DRIVER_ALLOW_SLEEP_MSK |
+		     IWL_POWER_FAST_PD; /* no use seeing frames for others */
+
+	if (priv->power_data.pci_pm)
+		cmd->flags |= IWL_POWER_PCI_PM_MSK;
+
+	cmd->rx_data_timeout = cpu_to_le32(1000 * dynps_ms);
+	cmd->tx_data_timeout = cpu_to_le32(1000 * dynps_ms);
+
+	for (i = 0; i < IWL_POWER_VEC_SIZE; i++)
+		cmd->sleep_interval[i] =
+			cpu_to_le32(min_t(int, slp_succ[i], wakeup_period));
+
+	IWL_DEBUG_POWER(priv, "Automatic sleep command\n");
+}
+
+static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd)
+{
+	IWL_DEBUG_POWER(priv, "Sending power/sleep command\n");
 	IWL_DEBUG_POWER(priv, "Flags value = 0x%08X\n", cmd->flags);
 	IWL_DEBUG_POWER(priv, "Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
 	IWL_DEBUG_POWER(priv, "Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
@@ -200,79 +268,588 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
 			le32_to_cpu(cmd->sleep_interval[3]),
 			le32_to_cpu(cmd->sleep_interval[4]));
 
-	return 0;
+	return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
+				sizeof(struct iwl_powertable_cmd), cmd);
 }
 
 
-/*
- * compute the final power mode index
- */
 int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 {
-	struct iwl_power_mgr *setting = &(priv->power_data);
 	int ret = 0;
-	u16 uninitialized_var(final_mode);
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) &&
+			(priv->hw->conf.flags & IEEE80211_CONF_PS);
 	bool update_chains;
+	struct iwl_powertable_cmd cmd;
+	int dtimper;
 
 	/* Don't update the RX chain when chain noise calibration is running */
 	update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
 			priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
 
-	final_mode = priv->power_data.user_power_setting;
-
-	if (setting->power_disabled)
-		final_mode = IWL_POWER_MODE_CAM;
+	if (priv->vif)
+		dtimper = priv->vif->bss_conf.dtim_period;
+	else
+		dtimper = 1;
+
+	if (priv->cfg->broken_powersave)
+		iwl_power_sleep_cam_cmd(priv, &cmd);
+	else if (tt->state >= IWL_TI_1)
+		iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper);
+	else if (!enabled)
+		iwl_power_sleep_cam_cmd(priv, &cmd);
+	else if (priv->power_data.debug_sleep_level_override >= 0)
+		iwl_static_sleep_cmd(priv, &cmd,
+				     priv->power_data.debug_sleep_level_override,
+				     dtimper);
+	else if (no_sleep_autoadjust)
+		iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_1, dtimper);
+	else
+		iwl_power_fill_sleep_cmd(priv, &cmd,
+					 priv->hw->conf.dynamic_ps_timeout,
+					 priv->hw->conf.max_sleep_period);
 
 	if (iwl_is_ready_rf(priv) &&
-	    ((setting->power_mode != final_mode) || force)) {
-		struct iwl_powertable_cmd cmd;
-
-		if (final_mode != IWL_POWER_MODE_CAM)
+	    (memcmp(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd)) || force)) {
+		if (cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK)
 			set_bit(STATUS_POWER_PMI, &priv->status);
 
-		iwl_update_power_cmd(priv, &cmd, final_mode);
-		cmd.keep_alive_beacons = 0;
-
-		if (final_mode == IWL_POWER_INDEX_5)
-			cmd.flags |= IWL_POWER_FAST_PD;
-
 		ret = iwl_set_power(priv, &cmd);
-
-		if (final_mode == IWL_POWER_MODE_CAM)
-			clear_bit(STATUS_POWER_PMI, &priv->status);
-
-		if (priv->cfg->ops->lib->update_chain_flags && update_chains)
-			priv->cfg->ops->lib->update_chain_flags(priv);
-		else
-			IWL_DEBUG_POWER(priv, "Cannot update the power, chain noise "
+		if (!ret) {
+			if (!(cmd.flags & IWL_POWER_DRIVER_ALLOW_SLEEP_MSK))
+				clear_bit(STATUS_POWER_PMI, &priv->status);
+
+			if (priv->cfg->ops->lib->update_chain_flags &&
+			    update_chains)
+				priv->cfg->ops->lib->update_chain_flags(priv);
+			else if (priv->cfg->ops->lib->update_chain_flags)
+				IWL_DEBUG_POWER(priv,
+					"Cannot update the power, chain noise "
 					"calibration running: %d\n",
 					priv->chain_noise_data.state);
-		if (!ret)
-			setting->power_mode = final_mode;
+			memcpy(&priv->power_data.sleep_cmd, &cmd, sizeof(cmd));
+		} else
+			IWL_ERR(priv, "set power fail, ret = %d", ret);
 	}
 
 	return ret;
 }
 EXPORT_SYMBOL(iwl_power_update_mode);
 
-/* set user_power_setting */
-int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
+bool iwl_ht_enabled(struct iwl_priv *priv)
+{
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	struct iwl_tt_restriction *restriction;
+
+	if (!priv->thermal_throttle.advanced_tt)
+		return true;
+	restriction = tt->restriction + tt->state;
+	return restriction->is_ht;
+}
+EXPORT_SYMBOL(iwl_ht_enabled);
+
+enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv)
 {
-	if (mode >= IWL_POWER_NUM)
-		return -EINVAL;
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	struct iwl_tt_restriction *restriction;
 
-	priv->power_data.user_power_setting = mode;
+	if (!priv->thermal_throttle.advanced_tt)
+		return IWL_ANT_OK_MULTI;
+	restriction = tt->restriction + tt->state;
+	return restriction->tx_stream;
+}
+EXPORT_SYMBOL(iwl_tx_ant_restriction);
+
+enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv)
+{
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	struct iwl_tt_restriction *restriction;
+
+	if (!priv->thermal_throttle.advanced_tt)
+		return IWL_ANT_OK_MULTI;
+	restriction = tt->restriction + tt->state;
+	return restriction->rx_stream;
+}
+
+#define CT_KILL_EXIT_DURATION (5)	/* 5 seconds duration */
+
+/*
+ * toggle the bit to wake up uCode and check the temperature
+ * if the temperature is below CT, uCode will stay awake and send card
+ * state notification with CT_KILL bit clear to inform Thermal Throttling
+ * Management to change state. Otherwise, uCode will go back to sleep
+ * without doing anything, driver should continue the 5 seconds timer
+ * to wake up uCode for temperature check until temperature drop below CT
+ */
+static void iwl_tt_check_exit_ct_kill(unsigned long data)
+{
+	struct iwl_priv *priv = (struct iwl_priv *)data;
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	unsigned long flags;
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	if (tt->state == IWL_TI_CT_KILL) {
+		if (priv->thermal_throttle.ct_kill_toggle) {
+			iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+			priv->thermal_throttle.ct_kill_toggle = false;
+		} else {
+			iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+				    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+			priv->thermal_throttle.ct_kill_toggle = true;
+		}
+		iwl_read32(priv, CSR_UCODE_DRV_GP1);
+		spin_lock_irqsave(&priv->reg_lock, flags);
+		if (!iwl_grab_nic_access(priv))
+			iwl_release_nic_access(priv);
+		spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+		/* Reschedule the ct_kill timer to occur in
+		 * CT_KILL_EXIT_DURATION seconds to ensure we get a
+		 * thermal update */
+		mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
+			  CT_KILL_EXIT_DURATION * HZ);
+	}
+}
+
+static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
+			   bool stop)
+{
+	if (stop) {
+		IWL_DEBUG_POWER(priv, "Stop all queues\n");
+		if (priv->mac80211_registered)
+			ieee80211_stop_queues(priv->hw);
+		IWL_DEBUG_POWER(priv,
+				"Schedule 5 seconds CT_KILL Timer\n");
+		mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies +
+			  CT_KILL_EXIT_DURATION * HZ);
+	} else {
+		IWL_DEBUG_POWER(priv, "Wake all queues\n");
+		if (priv->mac80211_registered)
+			ieee80211_wake_queues(priv->hw);
+	}
+}
+
+#define IWL_MINIMAL_POWER_THRESHOLD		(CT_KILL_THRESHOLD_LEGACY)
+#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2	(100)
+#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1	(90)
+
+/*
+ * Legacy thermal throttling
+ * 1) Avoid NIC destruction due to high temperatures
+ *	Chip will identify dangerously high temperatures that can
+ *	harm the device and will power down
+ * 2) Avoid the NIC power down due to high temperature
+ *	Throttle early enough to lower the power consumption before
+ *	drastic steps are needed
+ */
+static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
+{
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	enum iwl_tt_state old_state;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+	if ((tt->tt_previous_temp) &&
+	    (temp > tt->tt_previous_temp) &&
+	    ((temp - tt->tt_previous_temp) >
+	    IWL_TT_INCREASE_MARGIN)) {
+		IWL_DEBUG_POWER(priv,
+			"Temperature increase %d degree Celsius\n",
+			(temp - tt->tt_previous_temp));
+	}
+#endif
+	old_state = tt->state;
+	/* in Celsius */
+	if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
+		tt->state = IWL_TI_CT_KILL;
+	else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
+		tt->state = IWL_TI_2;
+	else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
+		tt->state = IWL_TI_1;
+	else
+		tt->state = IWL_TI_0;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+	tt->tt_previous_temp = temp;
+#endif
+	if (tt->state != old_state) {
+		switch (tt->state) {
+		case IWL_TI_0:
+			/*
+			 * When the system is ready to go back to IWL_TI_0
+			 * we only have to call iwl_power_update_mode() to
+			 * do so.
+			 */
+			break;
+		case IWL_TI_1:
+			tt->tt_power_mode = IWL_POWER_INDEX_3;
+			break;
+		case IWL_TI_2:
+			tt->tt_power_mode = IWL_POWER_INDEX_4;
+			break;
+		default:
+			tt->tt_power_mode = IWL_POWER_INDEX_5;
+			break;
+		}
+		mutex_lock(&priv->mutex);
+		if (iwl_power_update_mode(priv, true)) {
+			/* TT state not updated
+			 * try again during next temperature read
+			 */
+			tt->state = old_state;
+			IWL_ERR(priv, "Cannot update power mode, "
+					"TT state not updated\n");
+		} else {
+			if (tt->state == IWL_TI_CT_KILL)
+				iwl_perform_ct_kill_task(priv, true);
+			else if (old_state == IWL_TI_CT_KILL &&
+				 tt->state != IWL_TI_CT_KILL)
+				iwl_perform_ct_kill_task(priv, false);
+			IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
+					tt->state);
+			IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
+					tt->tt_power_mode);
+		}
+		mutex_unlock(&priv->mutex);
+	}
+}
 
-	return iwl_power_update_mode(priv, 0);
+/*
+ * Advance thermal throttling
+ * 1) Avoid NIC destruction due to high temperatures
+ *	Chip will identify dangerously high temperatures that can
+ *	harm the device and will power down
+ * 2) Avoid the NIC power down due to high temperature
+ *	Throttle early enough to lower the power consumption before
+ *	drastic steps are needed
+ *	Actions include relaxing the power down sleep thresholds and
+ *	decreasing the number of TX streams
+ * 3) Avoid throughput performance impact as much as possible
+ *
+ *=============================================================================
+ *                 Condition Nxt State  Condition Nxt State Condition Nxt State
+ *-----------------------------------------------------------------------------
+ *     IWL_TI_0     T >= 115   CT_KILL  115>T>=105   TI_1      N/A      N/A
+ *     IWL_TI_1     T >= 115   CT_KILL  115>T>=110   TI_2     T<=95     TI_0
+ *     IWL_TI_2     T >= 115   CT_KILL                        T<=100    TI_1
+ *    IWL_CT_KILL      N/A       N/A       N/A        N/A     T<=95     TI_0
+ *=============================================================================
+ */
+static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
+{
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	int i;
+	bool changed = false;
+	enum iwl_tt_state old_state;
+	struct iwl_tt_trans *transaction;
+
+	old_state = tt->state;
+	for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
+		/* based on the current TT state,
+		 * find the curresponding transaction table
+		 * each table has (IWL_TI_STATE_MAX - 1) entries
+		 * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
+		 * will advance to the correct table.
+		 * then based on the current temperature
+		 * find the next state need to transaction to
+		 * go through all the possible (IWL_TI_STATE_MAX - 1) entries
+		 * in the current table to see if transaction is needed
+		 */
+		transaction = tt->transaction +
+			((old_state * (IWL_TI_STATE_MAX - 1)) + i);
+		if (temp >= transaction->tt_low &&
+		    temp <= transaction->tt_high) {
+#ifdef CONFIG_IWLWIFI_DEBUG
+			if ((tt->tt_previous_temp) &&
+			    (temp > tt->tt_previous_temp) &&
+			    ((temp - tt->tt_previous_temp) >
+			    IWL_TT_INCREASE_MARGIN)) {
+				IWL_DEBUG_POWER(priv,
+					"Temperature increase %d "
+					"degree Celsius\n",
+					(temp - tt->tt_previous_temp));
+			}
+			tt->tt_previous_temp = temp;
+#endif
+			if (old_state !=
+			    transaction->next_state) {
+				changed = true;
+				tt->state =
+					transaction->next_state;
+			}
+			break;
+		}
+	}
+	if (changed) {
+		struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+
+		if (tt->state >= IWL_TI_1) {
+			/* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
+			tt->tt_power_mode = IWL_POWER_INDEX_5;
+			if (!iwl_ht_enabled(priv))
+				/* disable HT */
+				rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
+					RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
+					RXON_FLG_HT40_PROT_MSK |
+					RXON_FLG_HT_PROT_MSK);
+			else {
+				/* check HT capability and set
+				 * according to the system HT capability
+				 * in case get disabled before */
+				iwl_set_rxon_ht(priv, &priv->current_ht_config);
+			}
+
+		} else {
+			/*
+			 * restore system power setting -- it will be
+			 * recalculated automatically.
+			 */
+
+			/* check HT capability and set
+			 * according to the system HT capability
+			 * in case get disabled before */
+			iwl_set_rxon_ht(priv, &priv->current_ht_config);
+		}
+		mutex_lock(&priv->mutex);
+		if (iwl_power_update_mode(priv, true)) {
+			/* TT state not updated
+			 * try again during next temperature read
+			 */
+			IWL_ERR(priv, "Cannot update power mode, "
+					"TT state not updated\n");
+			tt->state = old_state;
+		} else {
+			IWL_DEBUG_POWER(priv,
+					"Thermal Throttling to new state: %u\n",
+					tt->state);
+			if (old_state != IWL_TI_CT_KILL &&
+			    tt->state == IWL_TI_CT_KILL) {
+				IWL_DEBUG_POWER(priv, "Enter IWL_TI_CT_KILL\n");
+				iwl_perform_ct_kill_task(priv, true);
+
+			} else if (old_state == IWL_TI_CT_KILL &&
+				  tt->state != IWL_TI_CT_KILL) {
+				IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
+				iwl_perform_ct_kill_task(priv, false);
+			}
+		}
+		mutex_unlock(&priv->mutex);
+	}
+}
+
+/* Card State Notification indicated reach critical temperature
+ * if PSP not enable, no Thermal Throttling function will be performed
+ * just set the GP1 bit to acknowledge the event
+ * otherwise, go into IWL_TI_CT_KILL state
+ * since Card State Notification will not provide any temperature reading
+ * for Legacy mode
+ * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
+ * for advance mode
+ * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
+ */
+static void iwl_bg_ct_enter(struct work_struct *work)
+{
+	struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	if (!iwl_is_ready(priv))
+		return;
+
+	if (tt->state != IWL_TI_CT_KILL) {
+		IWL_ERR(priv, "Device reached critical temperature "
+			      "- ucode going to sleep!\n");
+		if (!priv->thermal_throttle.advanced_tt)
+			iwl_legacy_tt_handler(priv,
+					      IWL_MINIMAL_POWER_THRESHOLD);
+		else
+			iwl_advance_tt_handler(priv,
+					       CT_KILL_THRESHOLD + 1);
+	}
 }
-EXPORT_SYMBOL(iwl_power_set_user_mode);
+
+/* Card State Notification indicated out of critical temperature
+ * since Card State Notification will not provide any temperature reading
+ * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
+ * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
+ */
+static void iwl_bg_ct_exit(struct work_struct *work)
+{
+	struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	if (!iwl_is_ready(priv))
+		return;
+
+	/* stop ct_kill_exit_tm timer */
+	del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+
+	if (tt->state == IWL_TI_CT_KILL) {
+		IWL_ERR(priv,
+			"Device temperature below critical"
+			"- ucode awake!\n");
+		if (!priv->thermal_throttle.advanced_tt)
+			iwl_legacy_tt_handler(priv,
+					IWL_REDUCED_PERFORMANCE_THRESHOLD_2);
+		else
+			iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD);
+	}
+}
+
+void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
+{
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
+	queue_work(priv->workqueue, &priv->ct_enter);
+}
+EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
+
+void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
+{
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
+	queue_work(priv->workqueue, &priv->ct_exit);
+}
+EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
+
+static void iwl_bg_tt_work(struct work_struct *work)
+{
+	struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
+	s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
+		temp = KELVIN_TO_CELSIUS(priv->temperature);
+
+	if (!priv->thermal_throttle.advanced_tt)
+		iwl_legacy_tt_handler(priv, temp);
+	else
+		iwl_advance_tt_handler(priv, temp);
+}
+
+void iwl_tt_handler(struct iwl_priv *priv)
+{
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return;
+
+	IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
+	queue_work(priv->workqueue, &priv->tt_work);
+}
+EXPORT_SYMBOL(iwl_tt_handler);
+
+/* Thermal throttling initialization
+ * For advance thermal throttling:
+ *     Initialize Thermal Index and temperature threshold table
+ *     Initialize thermal throttling restriction table
+ */
+void iwl_tt_initialize(struct iwl_priv *priv)
+{
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+	int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
+	struct iwl_tt_trans *transaction;
+
+	IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling \n");
+
+	memset(tt, 0, sizeof(struct iwl_tt_mgmt));
+
+	tt->state = IWL_TI_0;
+	init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
+	priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
+	priv->thermal_throttle.ct_kill_exit_tm.function = iwl_tt_check_exit_ct_kill;
+
+	/* setup deferred ct kill work */
+	INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
+	INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
+	INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
+
+	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+	case CSR_HW_REV_TYPE_6x00:
+	case CSR_HW_REV_TYPE_6x50:
+		IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
+		tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
+					 IWL_TI_STATE_MAX, GFP_KERNEL);
+		tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
+			IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
+			GFP_KERNEL);
+		if (!tt->restriction || !tt->transaction) {
+			IWL_ERR(priv, "Fallback to Legacy Throttling\n");
+			priv->thermal_throttle.advanced_tt = false;
+			kfree(tt->restriction);
+			tt->restriction = NULL;
+			kfree(tt->transaction);
+			tt->transaction = NULL;
+		} else {
+			transaction = tt->transaction +
+				(IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
+			memcpy(transaction, &tt_range_0[0], size);
+			transaction = tt->transaction +
+				(IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
+			memcpy(transaction, &tt_range_1[0], size);
+			transaction = tt->transaction +
+				(IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
+			memcpy(transaction, &tt_range_2[0], size);
+			transaction = tt->transaction +
+				(IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
+			memcpy(transaction, &tt_range_3[0], size);
+			size = sizeof(struct iwl_tt_restriction) *
+				IWL_TI_STATE_MAX;
+			memcpy(tt->restriction,
+				&restriction_range[0], size);
+			priv->thermal_throttle.advanced_tt = true;
+		}
+		break;
+	default:
+		IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
+		priv->thermal_throttle.advanced_tt = false;
+		break;
+	}
+}
+EXPORT_SYMBOL(iwl_tt_initialize);
+
+/* cleanup thermal throttling management related memory and timer */
+void iwl_tt_exit(struct iwl_priv *priv)
+{
+	struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
+
+	/* stop ct_kill_exit_tm timer if activated */
+	del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
+	cancel_work_sync(&priv->tt_work);
+	cancel_work_sync(&priv->ct_enter);
+	cancel_work_sync(&priv->ct_exit);
+
+	if (priv->thermal_throttle.advanced_tt) {
+		/* free advance thermal throttling memory */
+		kfree(tt->restriction);
+		tt->restriction = NULL;
+		kfree(tt->transaction);
+		tt->transaction = NULL;
+	}
+}
+EXPORT_SYMBOL(iwl_tt_exit);
 
 /* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
-	iwl_power_init_handle(priv);
-	priv->power_data.user_power_setting = IWL_POWER_INDEX_1;
-	/* default to disabled until mac80211 says otherwise */
-	priv->power_data.power_disabled = 1;
+	u16 lctl = iwl_pcie_link_ctl(priv);
+
+	priv->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
+
+	priv->power_data.debug_sleep_level_override = -1;
+
+	memset(&priv->power_data.sleep_cmd, 0,
+		sizeof(priv->power_data.sleep_cmd));
 }
 EXPORT_SYMBOL(iwl_power_initialize);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 37ba3bb..df6f6a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -28,13 +28,91 @@
 #ifndef __iwl_power_setting_h__
 #define __iwl_power_setting_h__
 
-#include <net/mac80211.h>
 #include "iwl-commands.h"
 
-struct iwl_priv;
+#define IWL_ABSOLUTE_ZERO		0
+#define IWL_ABSOLUTE_MAX		0xFFFFFFFF
+#define IWL_TT_INCREASE_MARGIN	5
 
-enum {
-	IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */
+enum iwl_antenna_ok {
+	IWL_ANT_OK_NONE,
+	IWL_ANT_OK_SINGLE,
+	IWL_ANT_OK_MULTI,
+};
+
+/* Thermal Throttling State Machine states */
+enum  iwl_tt_state {
+	IWL_TI_0,	/* normal temperature, system power state */
+	IWL_TI_1,	/* high temperature detect, low power state */
+	IWL_TI_2,	/* higher temperature detected, lower power state */
+	IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */
+	IWL_TI_STATE_MAX
+};
+
+/**
+ * struct iwl_tt_restriction - Thermal Throttling restriction table
+ * @tx_stream: number of tx stream allowed
+ * @is_ht: ht enable/disable
+ * @rx_stream: number of rx stream allowed
+ *
+ * This table is used by advance thermal throttling management
+ * based on the current thermal throttling state, and determines
+ * the number of tx/rx streams and the status of HT operation.
+ */
+struct iwl_tt_restriction {
+	enum iwl_antenna_ok tx_stream;
+	enum iwl_antenna_ok rx_stream;
+	bool is_ht;
+};
+
+/**
+ * struct iwl_tt_trans - Thermal Throttling transaction table
+ * @next_state:  next thermal throttling mode
+ * @tt_low: low temperature threshold to change state
+ * @tt_high: high temperature threshold to change state
+ *
+ * This is used by the advanced thermal throttling algorithm
+ * to determine the next thermal state to go based on the
+ * current temperature.
+ */
+struct iwl_tt_trans {
+	enum iwl_tt_state next_state;
+	u32 tt_low;
+	u32 tt_high;
+};
+
+/**
+ * struct iwl_tt_mgnt - Thermal Throttling Management structure
+ * @advanced_tt:    advanced thermal throttle required
+ * @state:          current Thermal Throttling state
+ * @tt_power_mode:  Thermal Throttling power mode index
+ *		    being used to set power level when
+ * 		    when thermal throttling state != IWL_TI_0
+ *		    the tt_power_mode should set to different
+ *		    power mode based on the current tt state
+ * @tt_previous_temperature: last measured temperature
+ * @iwl_tt_restriction: ptr to restriction tbl, used by advance
+ *		    thermal throttling to determine how many tx/rx streams
+ *		    should be used in tt state; and can HT be enabled or not
+ * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling
+ *		    state transaction
+ * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature
+ * @ct_kill_exit_tm: timer to exit thermal kill
+ */
+struct iwl_tt_mgmt {
+	enum iwl_tt_state state;
+	bool advanced_tt;
+	u8 tt_power_mode;
+	bool ct_kill_toggle;
+#ifdef CONFIG_IWLWIFI_DEBUG
+	s32 tt_previous_temp;
+#endif
+	struct iwl_tt_restriction *restriction;
+	struct iwl_tt_trans *transaction;
+	struct timer_list ct_kill_exit_tm;
+};
+
+enum iwl_power_level {
 	IWL_POWER_INDEX_1,
 	IWL_POWER_INDEX_2,
 	IWL_POWER_INDEX_3,
@@ -43,26 +121,23 @@ enum {
 	IWL_POWER_NUM
 };
 
-/* Power management (not Tx power) structures */
-
-struct iwl_power_vec_entry {
-	struct iwl_powertable_cmd cmd;
-	u8 no_dtim;
-};
-
 struct iwl_power_mgr {
-	struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM];
-	struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM];
-	struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM];
-	u32 dtim_period;
-	/* final power level that used to calculate final power command */
-	u8 power_mode;
-	u8 user_power_setting; /* set by user through sysfs */
-	u8 power_disabled; /* set by mac80211's CONF_PS */
+	struct iwl_powertable_cmd sleep_cmd;
+	int debug_sleep_level_override;
+	bool pci_pm;
 };
 
 int iwl_power_update_mode(struct iwl_priv *priv, bool force);
-int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
+bool iwl_ht_enabled(struct iwl_priv *priv);
+enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
+enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
+void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
+void iwl_tt_exit_ct_kill(struct iwl_priv *priv);
+void iwl_tt_handler(struct iwl_priv *priv);
+void iwl_tt_initialize(struct iwl_priv *priv);
+void iwl_tt_exit(struct iwl_priv *priv);
 void iwl_power_initialize(struct iwl_priv *priv);
 
+extern bool no_sleep_autoadjust;
+
 #endif  /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 3b9cac3..d393e8f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -80,6 +80,8 @@
 #define APMG_RFKILL_REG			(APMG_BASE + 0x0014)
 #define APMG_RTC_INT_STT_REG		(APMG_BASE + 0x001c)
 #define APMG_RTC_INT_MSK_REG		(APMG_BASE + 0x0020)
+#define APMG_DIGITAL_SVR_REG		(APMG_BASE + 0x0058)
+#define APMG_ANALOG_SVR_REG		(APMG_BASE + 0x006C)
 
 #define APMG_CLK_VAL_DMA_CLK_RQT	(0x00000200)
 #define APMG_CLK_VAL_BSM_CLK_RQT	(0x00000800)
@@ -91,7 +93,8 @@
 #define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN		(0x00000000)
 #define APMG_PS_CTRL_VAL_PWR_SRC_MAX		(0x01000000) /* 3945 only */
 #define APMG_PS_CTRL_VAL_PWR_SRC_VAUX		(0x02000000)
-
+#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK	(0x000001E0) /* bit 8:5 */
+#define APMG_SVR_DIGITAL_VOLTAGE_1_32		(0x00000060)
 
 #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS		(0x00000800)
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 2b8d40b..b90adcb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -239,26 +239,22 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
 	struct iwl_rx_mem_buffer *rxb;
+	struct sk_buff *skb;
 	unsigned long flags;
 
 	while (1) {
 		spin_lock_irqsave(&rxq->lock, flags);
-
 		if (list_empty(&rxq->rx_used)) {
 			spin_unlock_irqrestore(&rxq->lock, flags);
 			return;
 		}
-		element = rxq->rx_used.next;
-		rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
-		list_del(element);
-
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
 		/* Alloc a new receive buffer */
-		rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
+		skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
 						priority);
 
-		if (!rxb->skb) {
+		if (!skb) {
 			IWL_CRIT(priv, "Can not allocate SKB buffers\n");
 			/* We don't reschedule replenish work here -- we will
 			 * call the restock method and if it still needs
@@ -266,6 +262,20 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 			break;
 		}
 
+		spin_lock_irqsave(&rxq->lock, flags);
+
+		if (list_empty(&rxq->rx_used)) {
+			spin_unlock_irqrestore(&rxq->lock, flags);
+			dev_kfree_skb_any(skb);
+			return;
+		}
+		element = rxq->rx_used.next;
+		rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+		list_del(element);
+
+		spin_unlock_irqrestore(&rxq->lock, flags);
+
+		rxb->skb = skb;
 		/* Get physical address of RB/SKB */
 		rxb->real_dma_addr = pci_map_single(
 					priv->pci_dev,
@@ -406,7 +416,6 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 	rxq->free_count = 0;
 	spin_unlock_irqrestore(&rxq->lock, flags);
 }
-EXPORT_SYMBOL(iwl_rx_queue_reset);
 
 int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 {
@@ -540,13 +549,14 @@ void iwl_rx_statistics(struct iwl_priv *priv,
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 
 	IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
-		     (int)sizeof(priv->statistics), pkt->len);
+		     (int)sizeof(priv->statistics),
+		     le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
 
 	change = ((priv->statistics.general.temperature !=
 		   pkt->u.stats.general.temperature) ||
 		  ((priv->statistics.flag &
-		    STATISTICS_REPLY_FLG_FAT_MODE_MSK) !=
-		   (pkt->u.stats.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)));
+		    STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+		   (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
 
 	memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
 
@@ -646,7 +656,7 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
 	u32 tsf_low;
 	int rssi;
 
-	if (likely(!(priv->debug_level & IWL_DL_RX)))
+	if (likely(!(iwl_get_debug_level(priv) & IWL_DL_RX)))
 		return;
 
 	/* MAC header */
@@ -746,14 +756,6 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
 }
 #endif
 
-static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
-{
-	/* 0 - mgmt, 1 - cnt, 2 - data */
-	int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
-	priv->rx_stats[idx].cnt++;
-	priv->rx_stats[idx].bytes += len;
-}
-
 /*
  * returns non-zero if packet should be dropped
  */
@@ -862,61 +864,12 @@ static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
 }
 
 static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
-				       int include_phy,
-				       struct iwl_rx_mem_buffer *rxb,
-				       struct ieee80211_rx_status *stats)
+					struct ieee80211_hdr *hdr,
+					u16 len,
+					u32 ampdu_status,
+					struct iwl_rx_mem_buffer *rxb,
+					struct ieee80211_rx_status *stats)
 {
-	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-	struct iwl_rx_phy_res *rx_start = (include_phy) ?
-	    (struct iwl_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
-	struct ieee80211_hdr *hdr;
-	u16 len;
-	__le32 *rx_end;
-	unsigned int skblen;
-	u32 ampdu_status;
-	u32 ampdu_status_legacy;
-
-	if (!include_phy && priv->last_phy_res[0])
-		rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
-
-	if (!rx_start) {
-		IWL_ERR(priv, "MPDU frame without a PHY data\n");
-		return;
-	}
-	if (include_phy) {
-		hdr = (struct ieee80211_hdr *)((u8 *) &rx_start[1] +
-					       rx_start->cfg_phy_cnt);
-
-		len = le16_to_cpu(rx_start->byte_count);
-
-		rx_end = (__le32 *)((u8 *) &pkt->u.raw[0] +
-				  sizeof(struct iwl_rx_phy_res) +
-				  rx_start->cfg_phy_cnt + len);
-
-	} else {
-		struct iwl4965_rx_mpdu_res_start *amsdu =
-		    (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
-
-		hdr = (struct ieee80211_hdr *)(pkt->u.raw +
-			       sizeof(struct iwl4965_rx_mpdu_res_start));
-		len =  le16_to_cpu(amsdu->byte_count);
-		rx_start->byte_count = amsdu->byte_count;
-		rx_end = (__le32 *) (((u8 *) hdr) + len);
-	}
-
-	ampdu_status = le32_to_cpu(*rx_end);
-	skblen = ((u8 *) rx_end - (u8 *) &pkt->u.raw[0]) + sizeof(u32);
-
-	if (!include_phy) {
-		/* New status scheme, need to translate */
-		ampdu_status_legacy = ampdu_status;
-		ampdu_status = iwl_translate_rx_status(priv, ampdu_status);
-	}
-
-	/* start from MAC */
-	skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
-	skb_put(rxb->skb, len);	/* end where data ends */
-
 	/* We only process data packets if the interface is open */
 	if (unlikely(!priv->is_open)) {
 		IWL_DEBUG_DROP_LIMIT(priv,
@@ -924,15 +877,18 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr *)rxb->skb->data;
-
-	/*  in case of HW accelerated crypto and bad decryption, drop */
-	if (!priv->hw_params.sw_crypto &&
+	/* In case of HW accelerated crypto and bad decryption, drop */
+	if (!priv->cfg->mod_params->sw_crypto &&
 	    iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
 		return;
 
-	iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
-	ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
+	/* Resize SKB from mac header to end of packet */
+	skb_reserve(rxb->skb, (void *)hdr - (void *)rxb->skb->data);
+	skb_put(rxb->skb, len);
+
+	iwl_update_stats(priv, false, hdr->frame_control, len);
+	memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
+	ieee80211_rx_irqsafe(priv->hw, rxb->skb);
 	priv->alloc_rxb_skb--;
 	rxb->skb = NULL;
 }
@@ -963,82 +919,80 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
 	struct ieee80211_hdr *header;
 	struct ieee80211_rx_status rx_status;
 	struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-	/* Use phy data (Rx signal strength, etc.) contained within
-	 *   this rx packet for legacy frames,
-	 *   or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
-	int include_phy = (pkt->hdr.cmd == REPLY_RX);
-	struct iwl_rx_phy_res *rx_start = (include_phy) ?
-		(struct iwl_rx_phy_res *)&(pkt->u.raw[0]) :
-		(struct iwl_rx_phy_res *)&priv->last_phy_res[1];
-	__le32 *rx_end;
-	unsigned int len = 0;
+	struct iwl_rx_phy_res *phy_res;
+	__le32 rx_pkt_status;
+	struct iwl4965_rx_mpdu_res_start *amsdu;
+	u32 len;
+	u32 ampdu_status;
 	u16 fc;
-	u8 network_packet;
-
-	rx_status.mactime = le64_to_cpu(rx_start->timestamp);
-	rx_status.freq =
-		ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel));
-	rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
-				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
-	rx_status.rate_idx =
-		iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
-	if (rx_status.band == IEEE80211_BAND_5GHZ)
-		rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
-
-	rx_status.flag = 0;
+	u32 rate_n_flags;
 
-	/* TSF isn't reliable. In order to allow smooth user experience,
-	 * this W/A doesn't propagate it to the mac80211 */
-	/*rx_status.flag |= RX_FLAG_TSFT;*/
+	/**
+	 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
+	 *	REPLY_RX: physical layer info is in this buffer
+	 *	REPLY_RX_MPDU_CMD: physical layer info was sent in separate
+	 *		command and cached in priv->last_phy_res
+	 *
+	 * Here we set up local variables depending on which command is
+	 * received.
+	 */
+	if (pkt->hdr.cmd == REPLY_RX) {
+		phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
+		header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
+				+ phy_res->cfg_phy_cnt);
+
+		len = le16_to_cpu(phy_res->byte_count);
+		rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
+				phy_res->cfg_phy_cnt + len);
+		ampdu_status = le32_to_cpu(rx_pkt_status);
+	} else {
+		if (!priv->last_phy_res[0]) {
+			IWL_ERR(priv, "MPDU frame without cached PHY data\n");
+			return;
+		}
+		phy_res = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
+		amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
+		header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
+		len = le16_to_cpu(amsdu->byte_count);
+		rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
+		ampdu_status = iwl_translate_rx_status(priv,
+				le32_to_cpu(rx_pkt_status));
+	}
 
-	if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
+	if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
 		IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
-				rx_start->cfg_phy_cnt);
+				phy_res->cfg_phy_cnt);
 		return;
 	}
 
-	if (!include_phy) {
-		if (priv->last_phy_res[0])
-			rx_start = (struct iwl_rx_phy_res *)
-				&priv->last_phy_res[1];
-		else
-			rx_start = NULL;
-	}
-
-	if (!rx_start) {
-		IWL_ERR(priv, "MPDU frame without a PHY data\n");
+	if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
+	    !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
+		IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
+				le32_to_cpu(rx_pkt_status));
 		return;
 	}
 
-	if (include_phy) {
-		header = (struct ieee80211_hdr *)((u8 *) &rx_start[1]
-						  + rx_start->cfg_phy_cnt);
-
-		len = le16_to_cpu(rx_start->byte_count);
-		rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
-				  sizeof(struct iwl_rx_phy_res) + len);
-	} else {
-		struct iwl4965_rx_mpdu_res_start *amsdu =
-			(struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
+	/* This will be used in several places later */
+	rate_n_flags = le32_to_cpu(phy_res->rate_n_flags);
 
-		header = (void *)(pkt->u.raw +
-			sizeof(struct iwl4965_rx_mpdu_res_start));
-		len = le16_to_cpu(amsdu->byte_count);
-		rx_end = (__le32 *) (pkt->u.raw +
-			sizeof(struct iwl4965_rx_mpdu_res_start) + len);
-	}
+	/* rx_status carries information about the packet to mac80211 */
+	rx_status.mactime = le64_to_cpu(phy_res->timestamp);
+	rx_status.freq =
+		ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
+	rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
+				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+	rx_status.rate_idx =
+		iwl_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
+	rx_status.flag = 0;
 
-	if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
-	    !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
-		IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
-				le32_to_cpu(*rx_end));
-		return;
-	}
+	/* TSF isn't reliable. In order to allow smooth user experience,
+	 * this W/A doesn't propagate it to the mac80211 */
+	/*rx_status.flag |= RX_FLAG_TSFT;*/
 
-	priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
+	priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
 
 	/* Find max signal strength (dBm) among 3 antenna/receiver chains */
-	rx_status.signal = iwl_calc_rssi(priv, rx_start);
+	rx_status.signal = iwl_calc_rssi(priv, phy_res);
 
 	/* Meaningful noise values are available only from beacon statistics,
 	 *   which are gathered only when associated, and indicate noise
@@ -1058,13 +1012,14 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
 	if (!iwl_is_associated(priv))
 		priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
 
-	/* Set "1" to report good data frames in groups of 100 */
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (unlikely(priv->debug_level & IWL_DL_RX))
-		iwl_dbg_report_frame(priv, rx_start, len, header, 1);
+	/* Set "1" to report good data frames in groups of 100 */
+	if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
+		iwl_dbg_report_frame(priv, phy_res, len, header, 1);
 #endif
+	iwl_dbg_log_rx_data_frame(priv, len, header);
 	IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n",
-		rx_status.signal, rx_status.noise, rx_status.signal,
+		rx_status.signal, rx_status.noise, rx_status.qual,
 		(unsigned long long)rx_status.mactime);
 
 	/*
@@ -1080,18 +1035,26 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
 	 * new 802.11n radiotap field "RX chains" that is defined
 	 * as a bitmask.
 	 */
-	rx_status.antenna = le16_to_cpu(rx_start->phy_flags &
-					RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
+	rx_status.antenna =
+		le16_to_cpu(phy_res->phy_flags & RX_RES_PHY_FLAGS_ANTENNA_MSK)
+		>> RX_RES_PHY_FLAGS_ANTENNA_POS;
 
 	/* set the preamble flag if appropriate */
-	if (rx_start->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
+	if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
 		rx_status.flag |= RX_FLAG_SHORTPRE;
 
-	network_packet = iwl_is_network_packet(priv, header);
-	if (network_packet) {
+	/* Set up the HT phy flags */
+	if (rate_n_flags & RATE_MCS_HT_MSK)
+		rx_status.flag |= RX_FLAG_HT;
+	if (rate_n_flags & RATE_MCS_HT40_MSK)
+		rx_status.flag |= RX_FLAG_40MHZ;
+	if (rate_n_flags & RATE_MCS_SGI_MSK)
+		rx_status.flag |= RX_FLAG_SHORT_GI;
+
+	if (iwl_is_network_packet(priv, header)) {
 		priv->last_rx_rssi = rx_status.signal;
 		priv->last_beacon_time =  priv->ucode_beacon_time;
-		priv->last_tsf = le64_to_cpu(rx_start->timestamp);
+		priv->last_tsf = le64_to_cpu(phy_res->timestamp);
 	}
 
 	fc = le16_to_cpu(header->frame_control);
@@ -1103,8 +1066,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
 						header->addr2);
 		/* fall through */
 	default:
-			iwl_pass_packet_to_mac80211(priv, include_phy, rxb,
-				   &rx_status);
+		iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
+				rxb, &rx_status);
 		break;
 
 	}
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e26875d..4f3a108 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -109,13 +109,13 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 }
 EXPORT_SYMBOL(iwl_scan_cancel_timeout);
 
-int iwl_send_scan_abort(struct iwl_priv *priv)
+static int iwl_send_scan_abort(struct iwl_priv *priv)
 {
 	int ret = 0;
 	struct iwl_rx_packet *res;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_ABORT_CMD,
-		.meta.flags = CMD_WANT_SKB,
+		.flags = CMD_WANT_SKB,
 	};
 
 	/* If there isn't a scan actively going on in the hardware
@@ -132,7 +132,7 @@ int iwl_send_scan_abort(struct iwl_priv *priv)
 		return ret;
 	}
 
-	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
 	if (res->u.status != CAN_ABORT_STATUS) {
 		/* The scan abort will return 1 for success or
 		 * 2 for "failure".  A failure condition can be
@@ -146,11 +146,10 @@ int iwl_send_scan_abort(struct iwl_priv *priv)
 	}
 
 	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.meta.u.skb);
+	dev_kfree_skb_any(cmd.reply_skb);
 
 	return ret;
 }
-EXPORT_SYMBOL(iwl_send_scan_abort);
 
 /* Service response to REPLY_SCAN_CMD (0x80) */
 static void iwl_rx_reply_scan(struct iwl_priv *priv,
@@ -322,7 +321,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 				     u8 is_active, u8 n_probes,
 				     struct iwl_scan_channel *scan_ch)
 {
-	const struct ieee80211_channel *channels = NULL;
+	struct ieee80211_channel *chan;
 	const struct ieee80211_supported_band *sband;
 	const struct iwl_channel_info *ch_info;
 	u16 passive_dwell = 0;
@@ -334,20 +333,19 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 	if (!sband)
 		return 0;
 
-	channels = sband->channels;
-
 	active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
 	passive_dwell = iwl_get_passive_dwell_time(priv, band);
 
 	if (passive_dwell <= active_dwell)
 		passive_dwell = active_dwell + 1;
 
-	for (i = 0, added = 0; i < sband->n_channels; i++) {
-		if (channels[i].flags & IEEE80211_CHAN_DISABLED)
+	for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
+		chan = priv->scan_request->channels[i];
+
+		if (chan->band != band)
 			continue;
 
-		channel =
-			ieee80211_frequency_to_channel(channels[i].center_freq);
+		channel = ieee80211_frequency_to_channel(chan->center_freq);
 		scan_ch->channel = cpu_to_le16(channel);
 
 		ch_info = iwl_get_channel_info(priv, band, channel);
@@ -358,7 +356,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 		}
 
 		if (!is_active || is_channel_passive(ch_info) ||
-		    (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
+		    (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
 			scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
 		else
 			scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
@@ -405,7 +403,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
 		priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx;
 }
 
-int iwl_scan_initiate(struct iwl_priv *priv)
+static int iwl_scan_initiate(struct iwl_priv *priv)
 {
 	if (!iwl_is_ready_rf(priv)) {
 		IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
@@ -423,10 +421,6 @@ int iwl_scan_initiate(struct iwl_priv *priv)
 	}
 
 	IWL_DEBUG_INFO(priv, "Starting scan...\n");
-	if (priv->cfg->sku & IWL_SKU_G)
-		priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
-	if (priv->cfg->sku & IWL_SKU_A)
-		priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
 	set_bit(STATUS_SCANNING, &priv->status);
 	priv->scan_start = jiffies;
 	priv->scan_pass_start = priv->scan_start;
@@ -435,7 +429,6 @@ int iwl_scan_initiate(struct iwl_priv *priv)
 
 	return 0;
 }
-EXPORT_SYMBOL(iwl_scan_initiate);
 
 #define IWL_DELAY_NEXT_SCAN (HZ*2)
 
@@ -444,7 +437,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 {
 	unsigned long flags;
 	struct iwl_priv *priv = hw->priv;
-	int ret;
+	int ret, i;
 
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
@@ -478,6 +471,10 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 		goto out_unlock;
 	}
 
+	priv->scan_bands = 0;
+	for (i = 0; i < req->n_channels; i++)
+		priv->scan_bands |= BIT(req->channels[i]->band);
+
 	priv->scan_request = req;
 
 	ret = iwl_scan_initiate(priv);
@@ -570,7 +567,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_CMD,
 		.len = sizeof(struct iwl_scan_cmd),
-		.meta.flags = CMD_SIZE_HUGE,
+		.flags = CMD_SIZE_HUGE,
 	};
 	struct iwl_scan_cmd *scan;
 	struct ieee80211_conf *conf = NULL;
@@ -799,7 +796,8 @@ void iwl_bg_abort_scan(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
 
-	if (!iwl_is_ready(priv))
+	if (!test_bit(STATUS_READY, &priv->status) ||
+	    !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
 		return;
 
 	mutex_lock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index ffd5c61..a2b9ec8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -97,8 +97,9 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 
-static int iwl_add_sta_callback(struct iwl_priv *priv,
-				   struct iwl_cmd *cmd, struct sk_buff *skb)
+static void iwl_add_sta_callback(struct iwl_priv *priv,
+				 struct iwl_device_cmd *cmd,
+				 struct sk_buff *skb)
 {
 	struct iwl_rx_packet *res = NULL;
 	struct iwl_addsta_cmd *addsta =
@@ -107,14 +108,14 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
 
 	if (!skb) {
 		IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
-		return 1;
+		return;
 	}
 
 	res = (struct iwl_rx_packet *)skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
 			  res->hdr.flags);
-		return 1;
+		return;
 	}
 
 	switch (res->u.add_sta.status) {
@@ -126,9 +127,6 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
 			     res->u.add_sta.status);
 		break;
 	}
-
-	/* We didn't cache the SKB; let the caller free it */
-	return 1;
 }
 
 int iwl_send_add_sta(struct iwl_priv *priv,
@@ -139,14 +137,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
 	u8 data[sizeof(*sta)];
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_ADD_STA,
-		.meta.flags = flags,
+		.flags = flags,
 		.data = data,
 	};
 
 	if (flags & CMD_ASYNC)
-		cmd.meta.u.callback = iwl_add_sta_callback;
+		cmd.callback = iwl_add_sta_callback;
 	else
-		cmd.meta.flags |= CMD_WANT_SKB;
+		cmd.flags |= CMD_WANT_SKB;
 
 	cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
 	ret = iwl_send_cmd(priv, &cmd);
@@ -154,7 +152,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
 	if (ret || (flags & CMD_ASYNC))
 		return ret;
 
-	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
 			  res->hdr.flags);
@@ -175,7 +173,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
 	}
 
 	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.meta.u.skb);
+	dev_kfree_skb_any(cmd.reply_skb);
 
 	return ret;
 }
@@ -216,10 +214,10 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
 	sta_flags |= cpu_to_le32(
 	      (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
 
-	if (iwl_is_fat_tx_allowed(priv, sta_ht_inf))
-		sta_flags |= STA_FLG_FAT_EN_MSK;
+	if (iwl_is_ht40_tx_allowed(priv, sta_ht_inf))
+		sta_flags |= STA_FLG_HT40_EN_MSK;
 	else
-		sta_flags &= ~STA_FLG_FAT_EN_MSK;
+		sta_flags &= ~STA_FLG_HT40_EN_MSK;
 
 	priv->stations[index].sta.station_flags = sta_flags;
  done:
@@ -324,8 +322,9 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 
-static int iwl_remove_sta_callback(struct iwl_priv *priv,
-				   struct iwl_cmd *cmd, struct sk_buff *skb)
+static void iwl_remove_sta_callback(struct iwl_priv *priv,
+				    struct iwl_device_cmd *cmd,
+				    struct sk_buff *skb)
 {
 	struct iwl_rx_packet *res = NULL;
 	struct iwl_rem_sta_cmd *rm_sta =
@@ -334,14 +333,14 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
 
 	if (!skb) {
 		IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n");
-		return 1;
+		return;
 	}
 
 	res = (struct iwl_rx_packet *)skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
 		res->hdr.flags);
-		return 1;
+		return;
 	}
 
 	switch (res->u.rem_sta.status) {
@@ -352,9 +351,6 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
 		IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
 		break;
 	}
-
-	/* We didn't cache the SKB; let the caller free it */
-	return 1;
 }
 
 static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
@@ -368,7 +364,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_REMOVE_STA,
 		.len = sizeof(struct iwl_rem_sta_cmd),
-		.meta.flags = flags,
+		.flags = flags,
 		.data = &rm_sta_cmd,
 	};
 
@@ -377,15 +373,15 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
 	memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN);
 
 	if (flags & CMD_ASYNC)
-		cmd.meta.u.callback = iwl_remove_sta_callback;
+		cmd.callback = iwl_remove_sta_callback;
 	else
-		cmd.meta.flags |= CMD_WANT_SKB;
+		cmd.flags |= CMD_WANT_SKB;
 	ret = iwl_send_cmd(priv, &cmd);
 
 	if (ret || (flags & CMD_ASYNC))
 		return ret;
 
-	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
 			  res->hdr.flags);
@@ -406,7 +402,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
 	}
 
 	priv->alloc_rxb_skb--;
-	dev_kfree_skb_any(cmd.meta.u.skb);
+	dev_kfree_skb_any(cmd.reply_skb);
 
 	return ret;
 }
@@ -468,7 +464,6 @@ out:
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 	return ret;
 }
-EXPORT_SYMBOL(iwl_remove_station);
 
 /**
  * iwl_clear_stations_table - Clear the driver's station table
@@ -525,7 +520,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_WEPKEY,
 		.data = wep_cmd,
-		.meta.flags = CMD_ASYNC,
+		.flags = CMD_SYNC,
 	};
 
 	memset(wep_cmd, 0, cmd_size +
@@ -930,7 +925,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_TX_LINK_QUALITY_CMD,
 		.len = sizeof(struct iwl_link_quality_cmd),
-		.meta.flags = flags,
+		.flags = flags,
 		.data = lq,
 	};
 
@@ -1056,11 +1051,10 @@ EXPORT_SYMBOL(iwl_rxon_add_station);
 int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
 {
 	int sta_id;
-	u16 fc = le16_to_cpu(hdr->frame_control);
+	__le16 fc = hdr->frame_control;
 
 	/* If this frame is broadcast or management, use broadcast station id */
-	if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
-	    is_multicast_ether_addr(hdr->addr1))
+	if (!ieee80211_is_data(fc) ||  is_multicast_ether_addr(hdr->addr1))
 		return priv->hw_params.bcast_sta_id;
 
 	switch (priv->iw_mode) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 2e89040..a7422e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -141,7 +141,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
 	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
 		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
 
-	len = sizeof(struct iwl_cmd) * q->n_window;
+	len = sizeof(struct iwl_device_cmd) * q->n_window;
 
 	/* De-alloc array of command/tx buffers */
 	for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
@@ -156,6 +156,12 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
 	kfree(txq->txb);
 	txq->txb = NULL;
 
+	/* deallocate arrays */
+	kfree(txq->cmd);
+	kfree(txq->meta);
+	txq->cmd = NULL;
+	txq->meta = NULL;
+
 	/* 0-fill queue descriptor structure */
 	memset(txq, 0, sizeof(*txq));
 }
@@ -179,7 +185,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
 	if (q->n_bd == 0)
 		return;
 
-	len = sizeof(struct iwl_cmd) * q->n_window;
+	len = sizeof(struct iwl_device_cmd) * q->n_window;
 	len += IWL_MAX_SCAN_SIZE;
 
 	/* De-alloc array of command/tx buffers */
@@ -318,6 +324,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 {
 	int i, len;
 	int ret;
+	int actual_slots = slots_num;
 
 	/*
 	 * Alloc buffer array for commands (Tx or other types of commands).
@@ -327,14 +334,22 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 	 * For normal Tx queues (all other queues), no super-size command
 	 * space is needed.
 	 */
-	len = sizeof(struct iwl_cmd);
-	for (i = 0; i <= slots_num; i++) {
-		if (i == slots_num) {
-			if (txq_id == IWL_CMD_QUEUE_NUM)
-				len += IWL_MAX_SCAN_SIZE;
-			else
-				continue;
-		}
+	if (txq_id == IWL_CMD_QUEUE_NUM)
+		actual_slots++;
+
+	txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots,
+			    GFP_KERNEL);
+	txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots,
+			   GFP_KERNEL);
+
+	if (!txq->meta || !txq->cmd)
+		goto out_free_arrays;
+
+	len = sizeof(struct iwl_device_cmd);
+	for (i = 0; i < actual_slots; i++) {
+		/* only happens for cmd queue */
+		if (i == slots_num)
+			len += IWL_MAX_SCAN_SIZE;
 
 		txq->cmd[i] = kmalloc(len, GFP_KERNEL);
 		if (!txq->cmd[i])
@@ -348,6 +363,10 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 
 	txq->need_update = 0;
 
+	/* aggregation TX queues will get their ID when aggregation begins */
+	if (txq_id <= IWL_TX_FIFO_AC3)
+		txq->swq_id = txq_id;
+
 	/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
 	 * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
 	BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
@@ -360,15 +379,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 
 	return 0;
 err:
-	for (i = 0; i < slots_num; i++) {
+	for (i = 0; i < actual_slots; i++)
 		kfree(txq->cmd[i]);
-		txq->cmd[i] = NULL;
-	}
+out_free_arrays:
+	kfree(txq->meta);
+	kfree(txq->cmd);
 
-	if (txq_id == IWL_CMD_QUEUE_NUM) {
-		kfree(txq->cmd[slots_num]);
-		txq->cmd[slots_num] = NULL;
-	}
 	return -ENOMEM;
 }
 EXPORT_SYMBOL(iwl_tx_queue_init);
@@ -550,62 +566,81 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
 static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
 			      struct iwl_tx_cmd *tx_cmd,
 			      struct ieee80211_tx_info *info,
-			      __le16 fc, int sta_id,
-			      int is_hcca)
+			      __le16 fc, int is_hcca)
 {
-	u32 rate_flags = 0;
+	u32 rate_flags;
 	int rate_idx;
-	u8 rts_retry_limit = 0;
-	u8 data_retry_limit = 0;
+	u8 rts_retry_limit;
+	u8 data_retry_limit;
 	u8 rate_plcp;
 
-	rate_idx = min(ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xffff,
-			IWL_RATE_COUNT - 1);
-
-	rate_plcp = iwl_rates[rate_idx].plcp;
-
-	rts_retry_limit = (is_hcca) ?
-	    RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT;
-
-	if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
-		rate_flags |= RATE_MCS_CCK_MSK;
-
-
-	if (ieee80211_is_probe_resp(fc)) {
-		data_retry_limit = 3;
-		if (data_retry_limit < rts_retry_limit)
-			rts_retry_limit = data_retry_limit;
-	} else
-		data_retry_limit = IWL_DEFAULT_TX_RETRY;
-
+	/* Set retry limit on DATA packets and Probe Responses*/
 	if (priv->data_retry_limit != -1)
 		data_retry_limit = priv->data_retry_limit;
+	else if (ieee80211_is_probe_resp(fc))
+		data_retry_limit = 3;
+	else
+		data_retry_limit = IWL_DEFAULT_TX_RETRY;
+	tx_cmd->data_retry_limit = data_retry_limit;
 
+	/* Set retry limit on RTS packets */
+	rts_retry_limit = (is_hcca) ?  RTS_HCCA_RETRY_LIMIT :
+		RTS_DFAULT_RETRY_LIMIT;
+	if (data_retry_limit < rts_retry_limit)
+		rts_retry_limit = data_retry_limit;
+	tx_cmd->rts_retry_limit = rts_retry_limit;
 
+	/* DATA packets will use the uCode station table for rate/antenna
+	 * selection */
 	if (ieee80211_is_data(fc)) {
 		tx_cmd->initial_rate_index = 0;
 		tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
-	} else {
-		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
-		case cpu_to_le16(IEEE80211_STYPE_AUTH):
-		case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
-		case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
-		case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
-			if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
-				tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
-				tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
-			}
-			break;
-		default:
-			break;
-		}
+		return;
+	}
 
-		priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
-		rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
+	/**
+	 * If the current TX rate stored in mac80211 has the MCS bit set, it's
+	 * not really a TX rate.  Thus, we use the lowest supported rate for
+	 * this band.  Also use the lowest supported rate if the stored rate
+	 * index is invalid.
+	 */
+	rate_idx = info->control.rates[0].idx;
+	if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS ||
+			(rate_idx < 0) || (rate_idx > IWL_RATE_COUNT_LEGACY))
+		rate_idx = rate_lowest_index(&priv->bands[info->band],
+				info->control.sta);
+	/* For 5 GHZ band, remap mac80211 rate indices into driver indices */
+	if (info->band == IEEE80211_BAND_5GHZ)
+		rate_idx += IWL_FIRST_OFDM_RATE;
+	/* Get PLCP rate for tx_cmd->rate_n_flags */
+	rate_plcp = iwl_rates[rate_idx].plcp;
+	/* Zero out flags for this packet */
+	rate_flags = 0;
+
+	/* Set CCK flag as needed */
+	if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
+		rate_flags |= RATE_MCS_CCK_MSK;
+
+	/* Set up RTS and CTS flags for certain packets */
+	switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+	case cpu_to_le16(IEEE80211_STYPE_AUTH):
+	case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+	case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+	case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+		if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
+			tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+			tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
+		}
+		break;
+	default:
+		break;
 	}
 
-	tx_cmd->rts_retry_limit = rts_retry_limit;
-	tx_cmd->data_retry_limit = data_retry_limit;
+	/* Set up antennas */
+	priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant);
+	rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
+
+	/* Set the rate in the TX cmd */
 	tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
 }
 
@@ -652,14 +687,6 @@ static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
 	}
 }
 
-static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len)
-{
-	/* 0 - mgmt, 1 - cnt, 2 - data */
-	int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
-	priv->tx_stats[idx].cnt++;
-	priv->tx_stats[idx].bytes += len;
-}
-
 /*
  * start REPLY_TX command process
  */
@@ -669,7 +696,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct iwl_tx_queue *txq;
 	struct iwl_queue *q;
-	struct iwl_cmd *out_cmd;
+	struct iwl_device_cmd *out_cmd;
+	struct iwl_cmd_meta *out_meta;
 	struct iwl_tx_cmd *tx_cmd;
 	int swq_id, txq_id;
 	dma_addr_t phys_addr;
@@ -692,12 +720,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 		goto drop_unlock;
 	}
 
-	if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
-	     IWL_INVALID_RATE) {
-		IWL_ERR(priv, "ERROR: No TX rate available.\n");
-		goto drop_unlock;
-	}
-
 	fc = hdr->frame_control;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -709,10 +731,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 		IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
 #endif
 
-	/* drop all data frame if we are not associated */
+	/* drop all non-injected data frame if we are not associated */
 	if (ieee80211_is_data(fc) &&
-	    (!iwl_is_monitor_mode(priv) ||
-	    !(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injection */
+	    !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
 	    (!iwl_is_associated(priv) ||
 	     ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
 	     !priv->assoc_station_added)) {
@@ -723,7 +744,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	hdr_len = ieee80211_hdrlen(fc);
 
 	/* Find (or create) index into station table for destination station */
-	sta_id = iwl_get_sta_id(priv, hdr);
+	if (info->flags & IEEE80211_TX_CTL_INJECTED)
+		sta_id = priv->hw_params.bcast_sta_id;
+	else
+		sta_id = iwl_get_sta_id(priv, hdr);
 	if (sta_id == IWL_INVALID_STATION) {
 		IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
 			       hdr->addr1);
@@ -732,11 +756,12 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 	IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);
 
-	swq_id = skb_get_queue_mapping(skb);
-	txq_id = swq_id;
+	txq_id = skb_get_queue_mapping(skb);
 	if (ieee80211_is_data_qos(fc)) {
 		qc = ieee80211_get_qos_ctl(hdr);
 		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+		if (unlikely(tid >= MAX_TID_COUNT))
+			goto drop_unlock;
 		seq_number = priv->stations[sta_id].tid[tid].seq_number;
 		seq_number &= IEEE80211_SCTL_SEQ;
 		hdr->seq_ctrl = hdr->seq_ctrl &
@@ -744,15 +769,13 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 		hdr->seq_ctrl |= cpu_to_le16(seq_number);
 		seq_number += 0x10;
 		/* aggregation is on for this <sta,tid> */
-		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+		if (info->flags & IEEE80211_TX_CTL_AMPDU)
 			txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
-			swq_id = iwl_virtual_agg_queue_num(swq_id, txq_id);
-		}
 	}
 
 	txq = &priv->txq[txq_id];
+	swq_id = txq->swq_id;
 	q = &txq->q;
-	txq->swq_id = swq_id;
 
 	if (unlikely(iwl_queue_space(q) < q->high_mark))
 		goto drop_unlock;
@@ -766,6 +789,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 	/* Set up first empty entry in queue's array of Tx/cmd buffers */
 	out_cmd = txq->cmd[q->write_ptr];
+	out_meta = &txq->meta[q->write_ptr];
 	tx_cmd = &out_cmd->cmd.tx;
 	memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
 	memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
@@ -793,12 +817,12 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 	/* TODO need this for burst mode later on */
 	iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
+	iwl_dbg_log_tx_data_frame(priv, len, hdr);
 
 	/* set is_hcca to 0; it probably will never be implemented */
-	iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
-
-	iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
+	iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, 0);
 
+	iwl_update_stats(priv, true, fc, len);
 	/*
 	 * Use the first empty entry in this queue's command buffer array
 	 * to contain the Tx command and MAC header concatenated together
@@ -828,8 +852,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	txcmd_phys = pci_map_single(priv->pci_dev,
 				    &out_cmd->hdr, len,
 				    PCI_DMA_BIDIRECTIONAL);
-	pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
-	pci_unmap_len_set(&out_cmd->meta, len, len);
+	pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
+	pci_unmap_len_set(out_meta, len, len);
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
 	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
@@ -922,7 +946,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
 	struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 	struct iwl_queue *q = &txq->q;
-	struct iwl_cmd *out_cmd;
+	struct iwl_device_cmd *out_cmd;
+	struct iwl_cmd_meta *out_meta;
 	dma_addr_t phys_addr;
 	unsigned long flags;
 	int len, ret;
@@ -936,25 +961,32 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	 * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
 	 * we will need to increase the size of the TFD entries */
 	BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
-	       !(cmd->meta.flags & CMD_SIZE_HUGE));
+	       !(cmd->flags & CMD_SIZE_HUGE));
 
 	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_INFO(priv, "Not sending command - RF KILL");
+		IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n");
 		return -EIO;
 	}
 
-	if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
+	if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
 		IWL_ERR(priv, "No space for Tx\n");
 		return -ENOSPC;
 	}
 
 	spin_lock_irqsave(&priv->hcmd_lock, flags);
 
-	idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
+	idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
 	out_cmd = txq->cmd[idx];
+	out_meta = &txq->meta[idx];
+
+	memset(out_meta, 0, sizeof(*out_meta));	/* re-initialize to NULL */
+	out_meta->flags = cmd->flags;
+	if (cmd->flags & CMD_WANT_SKB)
+		out_meta->source = cmd;
+	if (cmd->flags & CMD_ASYNC)
+		out_meta->callback = cmd->callback;
 
 	out_cmd->hdr.cmd = cmd->id;
-	memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
 	memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
 
 	/* At this point, the out_cmd now has all of the incoming cmd
@@ -963,9 +995,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 	out_cmd->hdr.flags = 0;
 	out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
 			INDEX_TO_SEQ(q->write_ptr));
-	if (out_cmd->meta.flags & CMD_SIZE_HUGE)
+	if (cmd->flags & CMD_SIZE_HUGE)
 		out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
-	len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta);
+	len = sizeof(struct iwl_device_cmd);
 	len += (idx == TFD_CMD_SLOTS) ?  IWL_MAX_SCAN_SIZE : 0;
 
 
@@ -997,8 +1029,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
 	phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
 				   fix_size, PCI_DMA_BIDIRECTIONAL);
-	pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
-	pci_unmap_len_set(&out_cmd->meta, len, fix_size);
+	pci_unmap_addr_set(out_meta, mapping, phys_addr);
+	pci_unmap_len_set(out_meta, len, fix_size);
 
 	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
 						   phys_addr, fix_size, 1,
@@ -1067,8 +1099,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
 	}
 
 	pci_unmap_single(priv->pci_dev,
-		pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping),
-		pci_unmap_len(&txq->cmd[cmd_idx]->meta, len),
+		pci_unmap_addr(&txq->meta[cmd_idx], mapping),
+		pci_unmap_len(&txq->meta[cmd_idx], len),
 		PCI_DMA_BIDIRECTIONAL);
 
 	for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
@@ -1099,7 +1131,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 	int index = SEQ_TO_INDEX(sequence);
 	int cmd_index;
 	bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
-	struct iwl_cmd *cmd;
+	struct iwl_device_cmd *cmd;
+	struct iwl_cmd_meta *meta;
 
 	/* If a Tx command is being handled and it isn't in the actual
 	 * command queue then there a command routing bug has been introduced
@@ -1109,24 +1142,24 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 		  txq_id, sequence,
 		  priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
 		  priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
-		iwl_print_hex_dump(priv, IWL_DL_INFO , rxb, 32);
+		iwl_print_hex_error(priv, pkt, 32);
 		return;
 	}
 
 	cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
 	cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
+	meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
 
 	/* Input error checking is done when commands are added to queue. */
-	if (cmd->meta.flags & CMD_WANT_SKB) {
-		cmd->meta.source->u.skb = rxb->skb;
-		rxb->skb = NULL;
-	} else if (cmd->meta.u.callback &&
-		   !cmd->meta.u.callback(priv, cmd, rxb->skb))
+	if (meta->flags & CMD_WANT_SKB) {
+		meta->source->reply_skb = rxb->skb;
 		rxb->skb = NULL;
+	} else if (meta->callback)
+		meta->callback(priv, cmd, rxb->skb);
 
 	iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
 
-	if (!(cmd->meta.flags & CMD_ASYNC)) {
+	if (!(meta->flags & CMD_ASYNC)) {
 		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
@@ -1189,6 +1222,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
 	tid_data = &priv->stations[sta_id].tid[tid];
 	*ssn = SEQ_TO_SN(tid_data->seq_number);
 	tid_data->agg.txq_id = txq_id;
+	priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(tx_fifo, txq_id);
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
 	ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
@@ -1221,6 +1255,9 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
 		return -EINVAL;
 	}
 
+	if (unlikely(tid >= MAX_TID_COUNT))
+		return -EINVAL;
+
 	if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
 		tx_fifo_id = default_tid_to_tx_fifo[tid];
 	else
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5238433..0909668 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -89,7 +89,7 @@ MODULE_LICENSE("GPL");
 
  /* module parameters */
 struct iwl_mod_params iwl3945_mod_params = {
-	.num_of_queues = IWL39_MAX_NUM_QUEUES,
+	.num_of_queues = IWL39_NUM_QUEUES, /* Not used */
 	.sw_crypto = 1,
 	.restart_fw = 1,
 	/* the rest are 0 by default */
@@ -361,79 +361,9 @@ static void iwl3945_unset_hw_params(struct iwl_priv *priv)
 				    priv->shared_phys);
 }
 
-#define MAX_UCODE_BEACON_INTERVAL	1024
-#define INTEL_CONN_LISTEN_INTERVAL	cpu_to_le16(0xA)
-
-static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
-{
-	u16 new_val = 0;
-	u16 beacon_factor = 0;
-
-	beacon_factor =
-	    (beacon_val + MAX_UCODE_BEACON_INTERVAL)
-		/ MAX_UCODE_BEACON_INTERVAL;
-	new_val = beacon_val / beacon_factor;
-
-	return cpu_to_le16(new_val);
-}
-
-static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
-{
-	u64 interval_tm_unit;
-	u64 tsf, result;
-	unsigned long flags;
-	struct ieee80211_conf *conf = NULL;
-	u16 beacon_int = 0;
-
-	conf = ieee80211_get_hw_conf(priv->hw);
-
-	spin_lock_irqsave(&priv->lock, flags);
-	priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
-	priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
-
-	tsf = priv->timestamp;
-
-	beacon_int = priv->beacon_int;
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	if (priv->iw_mode == NL80211_IFTYPE_STATION) {
-		if (beacon_int == 0) {
-			priv->rxon_timing.beacon_interval = cpu_to_le16(100);
-			priv->rxon_timing.beacon_init_val = cpu_to_le32(102400);
-		} else {
-			priv->rxon_timing.beacon_interval =
-				cpu_to_le16(beacon_int);
-			priv->rxon_timing.beacon_interval =
-			    iwl3945_adjust_beacon_interval(
-				le16_to_cpu(priv->rxon_timing.beacon_interval));
-		}
-
-		priv->rxon_timing.atim_window = 0;
-	} else {
-		priv->rxon_timing.beacon_interval =
-			iwl3945_adjust_beacon_interval(
-				priv->vif->bss_conf.beacon_int);
-		/* TODO: we need to get atim_window from upper stack
-		 * for now we set to 0 */
-		priv->rxon_timing.atim_window = 0;
-	}
-
-	interval_tm_unit =
-		(le16_to_cpu(priv->rxon_timing.beacon_interval) * 1024);
-	result = do_div(tsf, interval_tm_unit);
-	priv->rxon_timing.beacon_init_val =
-	    cpu_to_le32((u32) ((u64) interval_tm_unit - result));
-
-	IWL_DEBUG_ASSOC(priv,
-		"beacon interval %d beacon timer %d beacon tim %d\n",
-		le16_to_cpu(priv->rxon_timing.beacon_interval),
-		le32_to_cpu(priv->rxon_timing.beacon_init_val),
-		le16_to_cpu(priv->rxon_timing.atim_window));
-}
-
 static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
 				      struct ieee80211_tx_info *info,
-				      struct iwl_cmd *cmd,
+				      struct iwl_device_cmd *cmd,
 				      struct sk_buff *skb_frag,
 				      int sta_id)
 {
@@ -473,7 +403,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
  * handle build REPLY_TX command notification.
  */
 static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
-				  struct iwl_cmd *cmd,
+				  struct iwl_device_cmd *cmd,
 				  struct ieee80211_tx_info *info,
 				  struct ieee80211_hdr *hdr, u8 std_id)
 {
@@ -546,7 +476,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	struct iwl3945_tx_cmd *tx;
 	struct iwl_tx_queue *txq = NULL;
 	struct iwl_queue *q = NULL;
-	struct iwl_cmd *out_cmd = NULL;
+	struct iwl_device_cmd *out_cmd;
+	struct iwl_cmd_meta *out_meta;
 	dma_addr_t phys_addr;
 	dma_addr_t txcmd_phys;
 	int txq_id = skb_get_queue_mapping(skb);
@@ -587,9 +518,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 		IWL_DEBUG_TX(priv, "Sending REASSOC frame\n");
 #endif
 
-	/* drop all data frame if we are not associated */
+	/* drop all non-injected data frame if we are not associated */
 	if (ieee80211_is_data(fc) &&
-	    (!iwl_is_monitor_mode(priv)) && /* packet injection */
+	    !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
 	    (!iwl_is_associated(priv) ||
 	     ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
 		IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
@@ -601,7 +532,10 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	hdr_len = ieee80211_hdrlen(fc);
 
 	/* Find (or create) index into station table for destination station */
-	sta_id = iwl_get_sta_id(priv, hdr);
+	if (info->flags & IEEE80211_TX_CTL_INJECTED)
+		sta_id = priv->hw_params.bcast_sta_id;
+	else
+		sta_id = iwl_get_sta_id(priv, hdr);
 	if (sta_id == IWL_INVALID_STATION) {
 		IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
 			       hdr->addr1);
@@ -613,6 +547,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	if (ieee80211_is_data_qos(fc)) {
 		qc = ieee80211_get_qos_ctl(hdr);
 		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+		if (unlikely(tid >= MAX_TID_COUNT))
+			goto drop;
 		seq_number = priv->stations[sta_id].tid[tid].seq_number &
 				IEEE80211_SCTL_SEQ;
 		hdr->seq_ctrl = cpu_to_le16(seq_number) |
@@ -635,6 +571,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
 	/* Init first empty entry in queue's array of Tx/cmd buffers */
 	out_cmd = txq->cmd[idx];
+	out_meta = &txq->meta[idx];
 	tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
 	memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
 	memset(tx, 0, sizeof(*tx));
@@ -666,7 +603,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 	len = (u16)skb->len;
 	tx->len = cpu_to_le16(len);
 
-
+	iwl_dbg_log_tx_data_frame(priv, len, hdr);
+	iwl_update_stats(priv, true, fc, len);
 	tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
 	tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
 
@@ -712,8 +650,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 				    len, PCI_DMA_TODEVICE);
 	/* we do not map meta data ... so we can safely access address to
 	 * provide to unmap command*/
-	pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
-	pci_unmap_len_set(&out_cmd->meta, len, len);
+	pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
+	pci_unmap_len_set(out_meta, len, len);
 
 	/* Add buffer containing Tx command and MAC(!) header to TFD's
 	 * first entry */
@@ -823,7 +761,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SPECTRUM_MEASUREMENT_CMD,
 		.data = (void *)&spectrum,
-		.meta.flags = CMD_WANT_SKB,
+		.flags = CMD_WANT_SKB,
 	};
 	u32 add_time = le64_to_cpu(params->start_time);
 	int rc;
@@ -864,7 +802,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
 	if (rc)
 		return rc;
 
-	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
 	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
 		IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
 		rc = -EIO;
@@ -887,7 +825,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
 		break;
 	}
 
-	dev_kfree_skb_any(cmd.meta.u.skb);
+	dev_kfree_skb_any(cmd.reply_skb);
 
 	return rc;
 }
@@ -996,7 +934,7 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
 	u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
 	unsigned long status = priv->status;
 
-	IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
+	IWL_WARN(priv, "Card state received: HW:%s SW:%s\n",
 			  (flags & HW_CARD_DISABLED) ? "Kill" : "On",
 			  (flags & SW_CARD_DISABLED) ? "Kill" : "On");
 
@@ -1196,6 +1134,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 	struct iwl_rx_queue *rxq = &priv->rxq;
 	struct list_head *element;
 	struct iwl_rx_mem_buffer *rxb;
+	struct sk_buff *skb;
 	unsigned long flags;
 
 	while (1) {
@@ -1205,17 +1144,11 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 			spin_unlock_irqrestore(&rxq->lock, flags);
 			return;
 		}
-
-		element = rxq->rx_used.next;
-		rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
-		list_del(element);
 		spin_unlock_irqrestore(&rxq->lock, flags);
 
 		/* Alloc a new receive buffer */
-		rxb->skb =
-		    alloc_skb(priv->hw_params.rx_buf_size,
-				priority);
-		if (!rxb->skb) {
+		skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
+		if (!skb) {
 			if (net_ratelimit())
 				IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
 			/* We don't reschedule replenish work here -- we will
@@ -1224,6 +1157,19 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 			break;
 		}
 
+		spin_lock_irqsave(&rxq->lock, flags);
+		if (list_empty(&rxq->rx_used)) {
+			spin_unlock_irqrestore(&rxq->lock, flags);
+			dev_kfree_skb_any(skb);
+			return;
+		}
+		element = rxq->rx_used.next;
+		rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+		list_del(element);
+		spin_unlock_irqrestore(&rxq->lock, flags);
+
+		rxb->skb = skb;
+
 		/* If radiotap head is required, reserve some headroom here.
 		 * The physical head count is a variable rx_stats->phy_count.
 		 * We reserve 4 bytes here. Plus these extra bytes, the
@@ -1435,7 +1381,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
 		fill_rx = 1;
 	/* Rx interrupt, but nothing sent from uCode */
 	if (i == r)
-		IWL_DEBUG(priv, IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
+		IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
 
 	while (i != r) {
 		rxb = rxq->queue[i];
@@ -1466,15 +1412,13 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
 		 *   handle those that need handling via function in
 		 *   rx_handlers table.  See iwl3945_setup_rx_handlers() */
 		if (priv->rx_handlers[pkt->hdr.cmd]) {
-			IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
-				"r = %d, i = %d, %s, 0x%02x\n", r, i,
+			IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r, i,
 				get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
 			priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
 			priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
 		} else {
 			/* No handling needed */
-			IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
-				"r %d i %d No handler needed for %s, 0x%02x\n",
+			IWL_DEBUG_RX(priv, "r %d i %d No handler needed for %s, 0x%02x\n",
 				r, i, get_cmd_string(pkt->hdr.cmd),
 				pkt->hdr.cmd);
 		}
@@ -1714,7 +1658,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
 	iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & IWL_DL_ISR) {
+	if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
 		/* just for debug */
 		inta_mask = iwl_read32(priv, CSR_INT_MASK);
 		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -1733,7 +1677,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
 
 	/* Now service all interrupt bits discovered above. */
 	if (inta & CSR_INT_BIT_HW_ERR) {
-		IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
+		IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
 
 		/* Tell the device to stop sending interrupts */
 		iwl_disable_interrupts(priv);
@@ -1749,7 +1693,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
 	}
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & (IWL_DL_ISR)) {
+	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
 		/* NIC fires this, but we don't use it, redundant with WAKEUP */
 		if (inta & CSR_INT_BIT_SCD) {
 			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
@@ -1828,7 +1772,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
 		iwl_enable_interrupts(priv);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	if (priv->debug_level & (IWL_DL_ISR)) {
+	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
 		inta = iwl_read32(priv, CSR_INT);
 		inta_mask = iwl_read32(priv, CSR_INT_MASK);
 		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
@@ -1844,7 +1788,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
 				     u8 is_active, u8 n_probes,
 				     struct iwl3945_scan_channel *scan_ch)
 {
-	const struct ieee80211_channel *channels = NULL;
+	struct ieee80211_channel *chan;
 	const struct ieee80211_supported_band *sband;
 	const struct iwl_channel_info *ch_info;
 	u16 passive_dwell = 0;
@@ -1855,19 +1799,19 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
 	if (!sband)
 		return 0;
 
-	channels = sband->channels;
-
 	active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
 	passive_dwell = iwl_get_passive_dwell_time(priv, band);
 
 	if (passive_dwell <= active_dwell)
 		passive_dwell = active_dwell + 1;
 
-	for (i = 0, added = 0; i < sband->n_channels; i++) {
-		if (channels[i].flags & IEEE80211_CHAN_DISABLED)
+	for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
+		chan = priv->scan_request->channels[i];
+
+		if (chan->band != band)
 			continue;
 
-		scan_ch->channel = channels[i].hw_value;
+		scan_ch->channel = chan->hw_value;
 
 		ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
 		if (!is_channel_valid(ch_info)) {
@@ -1882,7 +1826,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
 		 *  and use long active_dwell time.
 		 */
 		if (!is_active || is_channel_passive(ch_info) ||
-		    (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
+		    (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
 			scan_ch->type = 0;	/* passive */
 			if (IWL_UCODE_API(priv->ucode_ver) == 1)
 				scan_ch->active_dwell = cpu_to_le16(passive_dwell - 1);
@@ -2111,7 +2055,7 @@ static void iwl3945_nic_start(struct iwl_priv *priv)
  */
 static int iwl3945_read_ucode(struct iwl_priv *priv)
 {
-	struct iwl_ucode *ucode;
+	const struct iwl_ucode_header *ucode;
 	int ret = -EINVAL, index;
 	const struct firmware *ucode_raw;
 	/* firmware file name contains uCode/driver compatibility version */
@@ -2152,22 +2096,24 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
 		goto error;
 
 	/* Make sure that we got at least our header! */
-	if (ucode_raw->size < sizeof(*ucode)) {
+	if (ucode_raw->size <  priv->cfg->ops->ucode->get_header_size(1)) {
 		IWL_ERR(priv, "File size way too small!\n");
 		ret = -EINVAL;
 		goto err_release;
 	}
 
 	/* Data from ucode file:  header followed by uCode images */
-	ucode = (void *)ucode_raw->data;
+	ucode = (struct iwl_ucode_header *)ucode_raw->data;
 
 	priv->ucode_ver = le32_to_cpu(ucode->ver);
 	api_ver = IWL_UCODE_API(priv->ucode_ver);
-	inst_size = le32_to_cpu(ucode->inst_size);
-	data_size = le32_to_cpu(ucode->data_size);
-	init_size = le32_to_cpu(ucode->init_size);
-	init_data_size = le32_to_cpu(ucode->init_data_size);
-	boot_size = le32_to_cpu(ucode->boot_size);
+	inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
+	data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
+	init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
+	init_data_size =
+		priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
+	boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
+	src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
 
 	/* api_ver should match the api version forming part of the
 	 * firmware filename ... but we don't check for that and only rely
@@ -2208,12 +2154,13 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
 
 
 	/* Verify size of file vs. image size info in file's header */
-	if (ucode_raw->size < sizeof(*ucode) +
+	if (ucode_raw->size != priv->cfg->ops->ucode->get_header_size(api_ver) +
 		inst_size + data_size + init_size +
 		init_data_size + boot_size) {
 
-		IWL_DEBUG_INFO(priv, "uCode file size %zd too small\n",
-			       ucode_raw->size);
+		IWL_DEBUG_INFO(priv,
+			"uCode file size %zd does not match expected size\n",
+			ucode_raw->size);
 		ret = -EINVAL;
 		goto err_release;
 	}
@@ -2296,44 +2243,44 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
 	/* Copy images into buffers for card's bus-master reads ... */
 
 	/* Runtime instructions (first block of data in file) */
-	src = &ucode->data[0];
-	len = priv->ucode_code.len;
+	len = inst_size;
 	IWL_DEBUG_INFO(priv,
 		"Copying (but not loading) uCode instr len %zd\n", len);
 	memcpy(priv->ucode_code.v_addr, src, len);
+	src += len;
+
 	IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
 		priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
 	/* Runtime data (2nd block)
 	 * NOTE:  Copy into backup buffer will be done in iwl3945_up()  */
-	src = &ucode->data[inst_size];
-	len = priv->ucode_data.len;
+	len = data_size;
 	IWL_DEBUG_INFO(priv,
 		"Copying (but not loading) uCode data len %zd\n", len);
 	memcpy(priv->ucode_data.v_addr, src, len);
 	memcpy(priv->ucode_data_backup.v_addr, src, len);
+	src += len;
 
 	/* Initialization instructions (3rd block) */
 	if (init_size) {
-		src = &ucode->data[inst_size + data_size];
-		len = priv->ucode_init.len;
+		len = init_size;
 		IWL_DEBUG_INFO(priv,
 			"Copying (but not loading) init instr len %zd\n", len);
 		memcpy(priv->ucode_init.v_addr, src, len);
+		src += len;
 	}
 
 	/* Initialization data (4th block) */
 	if (init_data_size) {
-		src = &ucode->data[inst_size + data_size + init_size];
-		len = priv->ucode_init_data.len;
+		len = init_data_size;
 		IWL_DEBUG_INFO(priv,
 			"Copying (but not loading) init data len %zd\n", len);
 		memcpy(priv->ucode_init_data.v_addr, src, len);
+		src += len;
 	}
 
 	/* Bootstrap instructions (5th block) */
-	src = &ucode->data[inst_size + data_size + init_size + init_data_size];
-	len = priv->ucode_boot.len;
+	len = boot_size;
 	IWL_DEBUG_INFO(priv,
 		"Copying (but not loading) boot instr len %zd\n", len);
 	memcpy(priv->ucode_boot.v_addr, src, len);
@@ -2784,7 +2731,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_CMD,
 		.len = sizeof(struct iwl3945_scan_cmd),
-		.meta.flags = CMD_SIZE_HUGE,
+		.flags = CMD_SIZE_HUGE,
 	};
 	int rc = 0;
 	struct iwl3945_scan_cmd *scan;
@@ -3066,7 +3013,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
 	iwlcore_commit_rxon(priv);
 
 	memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
-	iwl3945_setup_rxon_timing(priv);
+	iwl_setup_rxon_timing(priv);
 	rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
 			      sizeof(priv->rxon_timing), &priv->rxon_timing);
 	if (rc)
@@ -3261,7 +3208,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
 
 		/* RXON Timing */
 		memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
-		iwl3945_setup_rxon_timing(priv);
+		iwl_setup_rxon_timing(priv);
 		rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
 				      sizeof(priv->rxon_timing),
 				      &priv->rxon_timing);
@@ -3375,13 +3322,16 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
  * used for controlling the debug level.
  *
  * See the level definitions in iwl for details.
+ *
+ * The debug_level being managed using sysfs below is a per device debug
+ * level that is used instead of the global debug level if it (the per
+ * device debug level) is set.
  */
 static ssize_t show_debug_level(struct device *d,
 				struct device_attribute *attr, char *buf)
 {
 	struct iwl_priv *priv = dev_get_drvdata(d);
-
-	return sprintf(buf, "0x%08X\n", priv->debug_level);
+	return sprintf(buf, "0x%08X\n", iwl_get_debug_level(priv));
 }
 static ssize_t store_debug_level(struct device *d,
 				struct device_attribute *attr,
@@ -3394,9 +3344,12 @@ static ssize_t store_debug_level(struct device *d,
 	ret = strict_strtoul(buf, 0, &val);
 	if (ret)
 		IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf);
-	else
+	else {
 		priv->debug_level = val;
-
+		if (iwl_alloc_traffic_mem(priv))
+			IWL_ERR(priv,
+				"Not enough memory to generate traffic log\n");
+	}
 	return strnlen(buf, count);
 }
 
@@ -3612,65 +3565,6 @@ static DEVICE_ATTR(retry_rate, S_IWUSR | S_IRUSR, show_retry_rate,
 		   store_retry_rate);
 
 
-static ssize_t store_power_level(struct device *d,
-				 struct device_attribute *attr,
-				 const char *buf, size_t count)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	int ret;
-	unsigned long mode;
-
-
-	mutex_lock(&priv->mutex);
-
-	ret = strict_strtoul(buf, 10, &mode);
-	if (ret)
-		goto out;
-
-	ret = iwl_power_set_user_mode(priv, mode);
-	if (ret) {
-		IWL_DEBUG_MAC80211(priv, "failed setting power mode.\n");
-		goto out;
-	}
-	ret = count;
-
- out:
-	mutex_unlock(&priv->mutex);
-	return ret;
-}
-
-static ssize_t show_power_level(struct device *d,
-				struct device_attribute *attr, char *buf)
-{
-	struct iwl_priv *priv = dev_get_drvdata(d);
-	int level = priv->power_data.power_mode;
-	char *p = buf;
-
-	p += sprintf(p, "%d\n", level);
-	return p - buf + 1;
-}
-
-static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR,
-		   show_power_level, store_power_level);
-
-#define MAX_WX_STRING 80
-
-/* Values are in microsecond */
-static const s32 timeout_duration[] = {
-	350000,
-	250000,
-	75000,
-	37000,
-	25000,
-};
-static const s32 period_duration[] = {
-	400000,
-	700000,
-	1000000,
-	1000000,
-	1000000
-};
-
 static ssize_t show_channels(struct device *d,
 			     struct device_attribute *attr, char *buf)
 {
@@ -3847,7 +3741,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
 #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
 	&dev_attr_measurement.attr,
 #endif
-	&dev_attr_power_level.attr,
 	&dev_attr_retry_rate.attr,
 	&dev_attr_statistics.attr,
 	&dev_attr_status.attr,
@@ -3912,8 +3805,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
 	priv->qos_data.qos_cap.val = 0;
 
 	priv->rates_mask = IWL_RATES_MASK;
-	/* If power management is turned on, default to CAM mode */
-	priv->power_mode = IWL_POWER_MODE_CAM;
 	priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
 
 	if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
@@ -3960,7 +3851,9 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
 	/* Tell mac80211 our characteristics */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
 		    IEEE80211_HW_NOISE_DBM |
-		    IEEE80211_HW_SPECTRUM_MGMT;
+		    IEEE80211_HW_SPECTRUM_MGMT |
+		    IEEE80211_HW_SUPPORTS_PS |
+		    IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
@@ -4020,15 +3913,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 	priv = hw->priv;
 	SET_IEEE80211_DEV(hw, &pdev->dev);
 
-	if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) ||
-	     (iwl3945_mod_params.num_of_queues < IWL39_MIN_NUM_QUEUES)) {
-		IWL_ERR(priv,
-			"invalid queues_num, should be between %d and %d\n",
-			IWL39_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
-		err = -EINVAL;
-		goto out_ieee80211_free_hw;
-	}
-
 	/*
 	 * Disabling hardware scan means that mac80211 will perform scans
 	 * "the hard way", rather than using device's scan.
@@ -4045,9 +3929,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 	priv->inta_mask = CSR_INI_SET_MASK;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-	priv->debug_level = iwl3945_mod_params.debug;
 	atomic_set(&priv->restrict_refcnt, 0);
 #endif
+	if (iwl_alloc_traffic_mem(priv))
+		IWL_ERR(priv, "Not enough memory to generate traffic log\n");
 
 	/***************************
 	 * 2. Initializing PCI bus
@@ -4210,6 +4095,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 	pci_disable_device(pdev);
  out_ieee80211_free_hw:
 	ieee80211_free_hw(priv->hw);
+	iwl_free_traffic_mem(priv);
  out:
 	return err;
 }
@@ -4265,6 +4151,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 	 * until now... */
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
+	iwl_free_traffic_mem(priv);
 
 	free_irq(pdev->irq, priv);
 	pci_disable_msi(pdev);
@@ -4341,14 +4228,12 @@ MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
 module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
 MODULE_PARM_DESC(swcrypto,
 		 "using software crypto (default 1 [software])\n");
-module_param_named(debug, iwl3945_mod_params.debug, uint, 0444);
+#ifdef CONFIG_IWLWIFI_DEBUG
+module_param_named(debug, iwl_debug_level, uint, 0644);
 MODULE_PARM_DESC(debug, "debug output mask");
+#endif
 module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
-
-module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444);
-MODULE_PARM_DESC(queues_num, "number of hw queues.");
-
 module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
 MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
 
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index 030401d..c25a043 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -2,7 +2,6 @@ config IWM
 	tristate "Intel Wireless Multicomm 3200 WiFi driver"
 	depends on MMC && WLAN_80211 && EXPERIMENTAL
 	depends on CFG80211
-	select WIRELESS_EXT
 	select FW_LOADER
 	help
 	  The Intel Wireless Multicomm 3200 hardware is a combo
@@ -25,8 +24,8 @@ config IWM_DEBUG
 	  To see the list of debug modules and levels, see iwm/debug.h
 
 	  For example, if you want the full MLME debug output:
-	  echo 0xff > /debug/iwm/phyN/debug/mlme
+	  echo 0xff > /sys/kernel/debug/iwm/phyN/debug/mlme
 
 	  Or, if you want the full debug, for all modules:
-	  echo 0xff > /debug/iwm/phyN/debug/level
-	  echo 0xff > /debug/iwm/phyN/debug/modules
+	  echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level
+	  echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
index 927f022..d34291b 100644
--- a/drivers/net/wireless/iwmc3200wifi/Makefile
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -1,5 +1,5 @@
 obj-$(CONFIG_IWM) := iwmc3200wifi.o
 iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
-iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o
+iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o
 
 iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 96f714e..a56a2b0 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
 #include <net/cfg80211.h>
@@ -130,6 +131,134 @@ static struct ieee80211_supported_band iwm_band_5ghz = {
 	.n_bitrates = iwm_a_rates_size,
 };
 
+static int iwm_key_init(struct iwm_key *key, u8 key_index,
+			const u8 *mac_addr, struct key_params *params)
+{
+	key->hdr.key_idx = key_index;
+	if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
+		key->hdr.multicast = 1;
+		memset(key->hdr.mac, 0xff, ETH_ALEN);
+	} else {
+		key->hdr.multicast = 0;
+		memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
+	}
+
+	if (params) {
+		if (params->key_len > WLAN_MAX_KEY_LEN ||
+		    params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
+			return -EINVAL;
+
+		key->cipher = params->cipher;
+		key->key_len = params->key_len;
+		key->seq_len = params->seq_len;
+		memcpy(key->key, params->key, key->key_len);
+		memcpy(key->seq, params->seq, key->seq_len);
+	}
+
+	return 0;
+}
+
+static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
+				u8 key_index, const u8 *mac_addr,
+				struct key_params *params)
+{
+	struct iwm_priv *iwm = ndev_to_iwm(ndev);
+	struct iwm_key *key = &iwm->keys[key_index];
+	int ret;
+
+	IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);
+
+	memset(key, 0, sizeof(struct iwm_key));
+	ret = iwm_key_init(key, key_index, mac_addr, params);
+	if (ret < 0) {
+		IWM_ERR(iwm, "Invalid key_params\n");
+		return ret;
+	}
+
+	return iwm_set_key(iwm, 0, key);
+}
+
+static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
+				u8 key_index, const u8 *mac_addr, void *cookie,
+				void (*callback)(void *cookie,
+						 struct key_params*))
+{
+	struct iwm_priv *iwm = ndev_to_iwm(ndev);
+	struct iwm_key *key = &iwm->keys[key_index];
+	struct key_params params;
+
+	IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
+
+	memset(&params, 0, sizeof(params));
+
+	params.cipher = key->cipher;
+	params.key_len = key->key_len;
+	params.seq_len = key->seq_len;
+	params.seq = key->seq;
+	params.key = key->key;
+
+	callback(cookie, &params);
+
+	return key->key_len ? 0 : -ENOENT;
+}
+
+
+static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
+				u8 key_index, const u8 *mac_addr)
+{
+	struct iwm_priv *iwm = ndev_to_iwm(ndev);
+	struct iwm_key *key = &iwm->keys[key_index];
+
+	if (!iwm->keys[key_index].key_len) {
+		IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
+		return 0;
+	}
+
+	if (key_index == iwm->default_key)
+		iwm->default_key = -1;
+
+	return iwm_set_key(iwm, 1, key);
+}
+
+static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
+					struct net_device *ndev,
+					u8 key_index)
+{
+	struct iwm_priv *iwm = ndev_to_iwm(ndev);
+
+	IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
+
+	if (!iwm->keys[key_index].key_len) {
+		IWM_ERR(iwm, "Key %d not used\n", key_index);
+		return -EINVAL;
+	}
+
+	iwm->default_key = key_index;
+
+	return iwm_set_tx_key(iwm, key_index);
+}
+
+static int iwm_cfg80211_get_station(struct wiphy *wiphy,
+				    struct net_device *ndev,
+				    u8 *mac, struct station_info *sinfo)
+{
+	struct iwm_priv *iwm = ndev_to_iwm(ndev);
+
+	if (memcmp(mac, iwm->bssid, ETH_ALEN))
+		return -ENOENT;
+
+	sinfo->filled |= STATION_INFO_TX_BITRATE;
+	sinfo->txrate.legacy = iwm->rate * 10;
+
+	if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+		sinfo->filled |= STATION_INFO_SIGNAL;
+		sinfo->signal = iwm->wstats.qual.level;
+	}
+
+	return 0;
+}
+
+
 int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
 {
 	struct wiphy *wiphy = iwm_to_wiphy(iwm);
@@ -167,20 +296,15 @@ int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
 	return 0;
 }
 
-static int iwm_cfg80211_change_iface(struct wiphy *wiphy, int ifindex,
+static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
+				     struct net_device *ndev,
 				     enum nl80211_iftype type, u32 *flags,
 				     struct vif_params *params)
 {
-	struct net_device *ndev;
 	struct wireless_dev *wdev;
 	struct iwm_priv *iwm;
 	u32 old_mode;
 
-	/* we're under RTNL */
-	ndev = __dev_get_by_index(&init_net, ifindex);
-	if (!ndev)
-		return -ENODEV;
-
 	wdev = ndev->ieee80211_ptr;
 	iwm = ndev_to_iwm(ndev);
 	old_mode = iwm->conf.mode;
@@ -203,11 +327,8 @@ static int iwm_cfg80211_change_iface(struct wiphy *wiphy, int ifindex,
 
 	iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
 
-	if (iwm->umac_profile_active) {
-		int ret = iwm_invalidate_mlme_profile(iwm);
-		if (ret < 0)
-			IWM_ERR(iwm, "Couldn't invalidate profile\n");
-	}
+	if (iwm->umac_profile_active)
+		iwm_invalidate_mlme_profile(iwm);
 
 	return 0;
 }
@@ -329,12 +450,300 @@ static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 	return 0;
 }
 
+static int iwm_set_auth_type(struct iwm_priv *iwm,
+			     enum nl80211_auth_type sme_auth_type)
+{
+	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
+
+	switch (sme_auth_type) {
+	case NL80211_AUTHTYPE_AUTOMATIC:
+	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+		IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
+		*auth_type = UMAC_AUTH_TYPE_OPEN;
+		break;
+	case NL80211_AUTHTYPE_SHARED_KEY:
+		if (iwm->umac_profile->sec.flags &
+		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
+			IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
+			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
+		} else {
+			IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
+			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+		}
+
+		break;
+	default:
+		IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
+{
+	IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
+
+	if (!wpa_version) {
+		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
+		return 0;
+	}
+
+	if (wpa_version & NL80211_WPA_VERSION_2)
+		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
+
+	if (wpa_version & NL80211_WPA_VERSION_1)
+		iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK;
+
+	return 0;
+}
+
+static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
+{
+	u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
+		&iwm->umac_profile->sec.mcast_cipher;
+
+	if (!cipher) {
+		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
+		return 0;
+	}
+
+	IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
+		     cipher);
+
+	switch (cipher) {
+	case IW_AUTH_CIPHER_NONE:
+		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
+		break;
+	case WLAN_CIPHER_SUITE_WEP40:
+		*profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
+		break;
+	case WLAN_CIPHER_SUITE_WEP104:
+		*profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
+		break;
+	case WLAN_CIPHER_SUITE_TKIP:
+		*profile_cipher = UMAC_CIPHER_TYPE_TKIP;
+		break;
+	case WLAN_CIPHER_SUITE_CCMP:
+		*profile_cipher = UMAC_CIPHER_TYPE_CCMP;
+		break;
+	default:
+		IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
+{
+	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
+
+	IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
+
+	if (key_mgt == WLAN_AKM_SUITE_8021X)
+		*auth_type = UMAC_AUTH_TYPE_8021X;
+	else if (key_mgt == WLAN_AKM_SUITE_PSK) {
+		if (iwm->umac_profile->sec.flags &
+		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
+			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
+		else
+			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+	} else {
+		IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+				 struct cfg80211_connect_params *sme)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+	struct ieee80211_channel *chan = sme->channel;
+	struct key_params key_param;
+	int ret;
+
+	if (!test_bit(IWM_STATUS_READY, &iwm->status))
+		return -EIO;
+
+	if (!sme->ssid)
+		return -EINVAL;
+
+	if (iwm->umac_profile_active) {
+		ret = iwm_invalidate_mlme_profile(iwm);
+		if (ret) {
+			IWM_ERR(iwm, "Couldn't invalidate profile\n");
+			return ret;
+		}
+	}
+
+	if (chan)
+		iwm->channel =
+			ieee80211_frequency_to_channel(chan->center_freq);
+
+	iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
+	memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
+
+	if (sme->bssid) {
+		IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
+		memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
+		iwm->umac_profile->bss_num = 1;
+	} else {
+		memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
+		iwm->umac_profile->bss_num = 0;
+	}
+
+	ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
+	if (ret < 0)
+		return ret;
+
+	ret = iwm_set_auth_type(iwm, sme->auth_type);
+	if (ret < 0)
+		return ret;
+
+	if (sme->crypto.n_ciphers_pairwise) {
+		ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
+				     true);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
+	if (ret < 0)
+		return ret;
+
+	if (sme->crypto.n_akm_suites) {
+		ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
+		if (ret < 0)
+			return ret;
+	}
+
+	/*
+	 * We save the WEP key in case we want to do shared authentication.
+	 * We have to do it so because UMAC will assert whenever it gets a
+	 * key before a profile.
+	 */
+	if (sme->key) {
+		key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
+		if (key_param.key == NULL)
+			return -ENOMEM;
+		key_param.key_len = sme->key_len;
+		key_param.seq_len = 0;
+		key_param.cipher = sme->crypto.ciphers_pairwise[0];
+
+		ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
+				   NULL, &key_param);
+		kfree(key_param.key);
+		if (ret < 0) {
+			IWM_ERR(iwm, "Invalid key_params\n");
+			return ret;
+		}
+
+		iwm->default_key = sme->key_idx;
+	}
+
+	ret = iwm_send_mlme_profile(iwm);
+
+	if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
+	    sme->key == NULL)
+		return ret;
+
+	/*
+	 * We want to do shared auth.
+	 * We need to actually set the key we previously cached,
+	 * and then tell the UMAC it's the default one.
+	 * That will trigger the auth+assoc UMAC machinery, and again,
+	 * this must be done after setting the profile.
+	 */
+	ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
+	if (ret < 0)
+		return ret;
+
+	return iwm_set_tx_key(iwm, iwm->default_key);
+}
+
+static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+				   u16 reason_code)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+	IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
+
+	if (iwm->umac_profile_active)
+		iwm_invalidate_mlme_profile(iwm);
+
+	return 0;
+}
+
+static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
+				    enum tx_power_setting type, int dbm)
+{
+	switch (type) {
+	case TX_POWER_AUTOMATIC:
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+	*dbm = iwm->txpower;
+
+	return 0;
+}
+
+static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+				       struct net_device *dev,
+				       bool enabled, int timeout)
+{
+	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+	u32 power_index;
+
+	if (enabled)
+		power_index = IWM_POWER_INDEX_DEFAULT;
+	else
+		power_index = IWM_POWER_INDEX_MIN;
+
+	if (power_index == iwm->conf.power_index)
+		return 0;
+
+	iwm->conf.power_index = power_index;
+
+	return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+				       CFG_POWER_INDEX, iwm->conf.power_index);
+}
+
 static struct cfg80211_ops iwm_cfg80211_ops = {
 	.change_virtual_intf = iwm_cfg80211_change_iface,
+	.add_key = iwm_cfg80211_add_key,
+	.get_key = iwm_cfg80211_get_key,
+	.del_key = iwm_cfg80211_del_key,
+	.set_default_key = iwm_cfg80211_set_default_key,
+	.get_station = iwm_cfg80211_get_station,
 	.scan = iwm_cfg80211_scan,
 	.set_wiphy_params = iwm_cfg80211_set_wiphy_params,
+	.connect = iwm_cfg80211_connect,
+	.disconnect = iwm_cfg80211_disconnect,
 	.join_ibss = iwm_cfg80211_join_ibss,
 	.leave_ibss = iwm_cfg80211_leave_ibss,
+	.set_tx_power = iwm_cfg80211_set_txpower,
+	.get_tx_power = iwm_cfg80211_get_txpower,
+	.set_power_mgmt = iwm_cfg80211_set_power_mgmt,
+};
+
+static const u32 cipher_suites[] = {
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+	WLAN_CIPHER_SUITE_CCMP,
 };
 
 struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
@@ -379,6 +788,9 @@ struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
 	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
 	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
 
+	wdev->wiphy->cipher_suites = cipher_suites;
+	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
 	ret = wiphy_register(wdev->wiphy);
 	if (ret < 0) {
 		dev_err(dev, "Couldn't register wiphy device\n");
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index e2334d1..23b52fa 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -70,14 +70,27 @@ static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm,
 int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
 			 bool resp)
 {
+	struct iwm_umac_wifi_if *hdr = (struct iwm_umac_wifi_if *)payload;
 	struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
 	struct iwm_umac_cmd umac_cmd;
+	int ret;
+	u8 oid = hdr->oid;
 
 	umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
 	umac_cmd.resp = resp;
 
-	return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
-				     payload, payload_size);
+	ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
+				    payload, payload_size);
+
+	if (resp) {
+		ret = wait_event_interruptible_timeout(iwm->wifi_ntfy_queue,
+				   test_and_clear_bit(oid, &iwm->wifi_ntfy[0]),
+				   3 * HZ);
+
+		return ret ? 0 : -EBUSY;
+	}
+
+	return ret;
 }
 
 static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] =
@@ -106,7 +119,7 @@ static struct coex_event iwm_sta_cm_prio_tbl[COEX_EVENTS_NUM] =
 	{4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
 	{3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
 	{5, 5, 0, COEX_CALIBRATION_FLAGS},
-	{4, 4, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+	{3, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
 	{5, 4, 0, COEX_CONNECTION_ESTAB_FLAGS},
 	{4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS},
 	{4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
@@ -332,8 +345,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
 	return ret;
 }
 
-int iwm_send_umac_config(struct iwm_priv *iwm,
-			 __le32 reset_flags)
+int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags)
 {
 	int ret;
 
@@ -361,6 +373,12 @@ int iwm_send_umac_config(struct iwm_priv *iwm,
 		return ret;
 
 	ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+				      CFG_WIRELESS_MODE,
+				      iwm->conf.wireless_mode);
+	if (ret < 0)
+		return ret;
+
+	ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
 				      CFG_COEX_MODE, iwm->conf.coexist_mode);
 	if (ret < 0)
 		return ret;
@@ -402,7 +420,7 @@ int iwm_send_umac_config(struct iwm_priv *iwm,
 		return ret;
 
 	ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
-				      CFG_PM_CTRL_FLAGS, 0x30001);
+				      CFG_PM_CTRL_FLAGS, 0x1);
 	if (ret < 0)
 		return ret;
 
@@ -462,8 +480,10 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
 	target_cmd.eop = 1;
 
 	ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
-	if (ret < 0)
+	if (ret < 0) {
 		IWM_ERR(iwm, "Couldn't send READ command\n");
+		return ret;
+	}
 
 	/* When succeding, the send_target routine returns the seq number */
 	seq_num = ret;
@@ -483,7 +503,7 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
 
 	kfree(cmd);
 
-	return ret;
+	return 0;
 }
 
 int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
@@ -493,7 +513,7 @@ int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
 
 	ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR),
 			      mac_align, sizeof(mac_align));
-	if (ret < 0)
+	if (ret)
 		return ret;
 
 	if (is_valid_ether_addr(mac_align))
@@ -507,22 +527,6 @@ int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
 	return 0;
 }
 
-int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx)
-{
-	struct iwm_umac_tx_key_id tx_key_id;
-
-	if (!iwm->default_key || !iwm->default_key->in_use)
-		return -EINVAL;
-
-	tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID;
-	tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) -
-					     sizeof(struct iwm_umac_wifi_if));
-
-	tx_key_id.key_idx = key_idx;
-
-	return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1);
-}
-
 static int iwm_check_profile(struct iwm_priv *iwm)
 {
 	if (!iwm->umac_profile_active)
@@ -556,10 +560,35 @@ static int iwm_check_profile(struct iwm_priv *iwm)
 	return 0;
 }
 
-int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
-		struct iwm_key *key)
+int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx)
 {
+	struct iwm_umac_tx_key_id tx_key_id;
 	int ret;
+
+	ret = iwm_check_profile(iwm);
+	if (ret < 0)
+		return ret;
+
+	/* UMAC only allows to set default key for WEP and auth type is
+	 * NOT 802.1X or RSNA. */
+	if ((iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
+	     iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_104) ||
+	    iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_8021X ||
+	    iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_RSNA_PSK)
+		return 0;
+
+	tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID;
+	tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) -
+					     sizeof(struct iwm_umac_wifi_if));
+
+	tx_key_id.key_idx = key_idx;
+
+	return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1);
+}
+
+int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
+{
+	int ret = 0;
 	u8 cmd[64], *sta_addr, *key_data, key_len;
 	s8 key_idx;
 	u16 cmd_size = 0;
@@ -569,15 +598,6 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 	struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd;
 	struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd;
 
-	if (set_tx_key)
-		iwm->default_key = key;
-
-	/*
-	 * We check if our current profile is valid.
-	 * If not, we dont push the key, we just cache them,
-	 * so that with the next siwsessid call, the keys
-	 * will be actually pushed.
-	 */
 	if (!remove) {
 		ret = iwm_check_profile(iwm);
 		if (ret < 0)
@@ -590,8 +610,9 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 	key_idx = key->hdr.key_idx;
 
 	if (!remove) {
-		IWM_DBG_WEXT(iwm, DBG, "key_idx:%d set tx key:%d\n",
-			     key_idx, set_tx_key);
+		u8 auth_type = iwm->umac_profile->sec.auth_type;
+
+		IWM_DBG_WEXT(iwm, DBG, "key_idx:%d\n", key_idx);
 		IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len);
 		IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n",
 		       key_hdr->mac, key_hdr->key_idx, key_hdr->multicast);
@@ -603,8 +624,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 			     iwm->umac_profile->sec.auth_type,
 			     iwm->umac_profile->sec.flags);
 
-		switch (key->alg) {
-		case UMAC_CIPHER_TYPE_WEP_40:
+		switch (key->cipher) {
+		case WLAN_CIPHER_SUITE_WEP40:
 			wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY;
 			wep40->hdr.buf_size =
 				cpu_to_le16(sizeof(struct iwm_umac_key_wep40) -
@@ -613,12 +634,14 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 			memcpy(&wep40->key_hdr, key_hdr,
 			       sizeof(struct iwm_umac_key_hdr));
 			memcpy(wep40->key, key_data, key_len);
-			wep40->static_key = 1;
+			wep40->static_key =
+				!!((auth_type != UMAC_AUTH_TYPE_8021X) &&
+				   (auth_type != UMAC_AUTH_TYPE_RSNA_PSK));
 
 			cmd_size = sizeof(struct iwm_umac_key_wep40);
 			break;
 
-		case UMAC_CIPHER_TYPE_WEP_104:
+		case WLAN_CIPHER_SUITE_WEP104:
 			wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY;
 			wep104->hdr.buf_size =
 				cpu_to_le16(sizeof(struct iwm_umac_key_wep104) -
@@ -627,12 +650,14 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 			memcpy(&wep104->key_hdr, key_hdr,
 			       sizeof(struct iwm_umac_key_hdr));
 			memcpy(wep104->key, key_data, key_len);
-			wep104->static_key = 1;
+			wep104->static_key =
+				!!((auth_type != UMAC_AUTH_TYPE_8021X) &&
+				   (auth_type != UMAC_AUTH_TYPE_RSNA_PSK));
 
 			cmd_size = sizeof(struct iwm_umac_key_wep104);
 			break;
 
-		case UMAC_CIPHER_TYPE_CCMP:
+		case WLAN_CIPHER_SUITE_CCMP:
 			key_hdr->key_idx++;
 			ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY;
 			ccmp->hdr.buf_size =
@@ -644,13 +669,13 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 
 			memcpy(ccmp->key, key_data, key_len);
 
-			if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID)
-				memcpy(ccmp->iv_count, key->rx_seq, 6);
+			if (key->seq_len)
+				memcpy(ccmp->iv_count, key->seq, key->seq_len);
 
 			cmd_size = sizeof(struct iwm_umac_key_ccmp);
 			break;
 
-		case UMAC_CIPHER_TYPE_TKIP:
+		case WLAN_CIPHER_SUITE_TKIP:
 			key_hdr->key_idx++;
 			tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY;
 			tkip->hdr.buf_size =
@@ -667,8 +692,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 			       key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE,
 			       IWM_TKIP_MIC_SIZE);
 
-			if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID)
-				memcpy(ccmp->iv_count, key->rx_seq, 6);
+			if (key->seq_len)
+				memcpy(ccmp->iv_count, key->seq, key->seq_len);
 
 			cmd_size = sizeof(struct iwm_umac_key_tkip);
 			break;
@@ -677,8 +702,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 			return -ENOTSUPP;
 		}
 
-		if ((key->alg == UMAC_CIPHER_TYPE_CCMP) ||
-		    (key->alg == UMAC_CIPHER_TYPE_TKIP))
+		if ((key->cipher == WLAN_CIPHER_SUITE_TKIP) ||
+		    (key->cipher == WLAN_CIPHER_SUITE_CCMP))
 			/*
 			 * UGLY_UGLY_UGLY
 			 * Copied HACK from the MWG driver.
@@ -689,23 +714,11 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 			schedule_timeout_interruptible(usecs_to_jiffies(300));
 
 		ret =  iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1);
-		if (ret < 0)
-			goto err;
-
-		/*
-		 * We need a default key only if it is set and
-		 * if we're doing WEP.
-		 */
-		if (iwm->default_key == key &&
-			((key->alg == UMAC_CIPHER_TYPE_WEP_40) ||
-			 (key->alg == UMAC_CIPHER_TYPE_WEP_104))) {
-			ret = iwm_set_tx_key(iwm, key_idx);
-			if (ret < 0)
-				goto err;
-		}
 	} else {
 		struct iwm_umac_key_remove key_remove;
 
+		IWM_DBG_WEXT(iwm, ERR, "Removing key_idx:%d\n", key_idx);
+
 		key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY;
 		key_remove.hdr.buf_size =
 			cpu_to_le16(sizeof(struct iwm_umac_key_remove) -
@@ -716,23 +729,19 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
 		ret =  iwm_send_wifi_if_cmd(iwm, &key_remove,
 					    sizeof(struct iwm_umac_key_remove),
 					    1);
-		if (ret < 0)
+		if (ret)
 			return ret;
 
-		iwm->keys[key_idx].in_use = 0;
+		iwm->keys[key_idx].key_len = 0;
 	}
 
-	return 0;
-
- err:
-	kfree(key);
 	return ret;
 }
 
 
 int iwm_send_mlme_profile(struct iwm_priv *iwm)
 {
-	int ret, i;
+	int ret;
 	struct iwm_umac_profile profile;
 
 	memcpy(&profile, iwm->umac_profile, sizeof(profile));
@@ -742,45 +751,19 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
 					   sizeof(struct iwm_umac_wifi_if));
 
 	ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1);
-	if (ret < 0) {
+	if (ret) {
 		IWM_ERR(iwm, "Send profile command failed\n");
 		return ret;
 	}
 
-	/* Wait for the profile to be active */
-	ret = wait_event_interruptible_timeout(iwm->mlme_queue,
-					       iwm->umac_profile_active == 1,
-					       3 * HZ);
-	if (!ret)
-		return -EBUSY;
-
-
-	for (i = 0; i < IWM_NUM_KEYS; i++)
-		if (iwm->keys[i].in_use) {
-			int default_key = 0;
-			struct iwm_key *key = &iwm->keys[i];
-
-			if (key == iwm->default_key)
-				default_key = 1;
-
-			/* Wait for the profile before sending the keys */
-			wait_event_interruptible_timeout(iwm->mlme_queue,
-			     (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) ||
-			      test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)),
-							 3 * HZ);
-
-			ret = iwm_set_key(iwm, 0, default_key, key);
-			if (ret < 0)
-				return ret;
-		}
-
+	set_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
 	return 0;
 }
 
 int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
 {
-	int ret;
 	struct iwm_umac_invalidate_profile invalid;
+	int ret;
 
 	invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
 	invalid.hdr.buf_size =
@@ -790,16 +773,13 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
 	invalid.reason = WLAN_REASON_UNSPECIFIED;
 
 	ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
-	if (ret < 0)
+	if (ret)
 		return ret;
 
 	ret = wait_event_interruptible_timeout(iwm->mlme_queue,
-				 (iwm->umac_profile_active == 0),
-					       2 * HZ);
-	if (!ret)
-		return -EBUSY;
+				(iwm->umac_profile_active == 0), 2 * HZ);
 
-	return 0;
+	return ret ? 0 : -EBUSY;
 }
 
 int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
@@ -882,7 +862,7 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
 	}
 
 	ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0);
-	if (ret < 0) {
+	if (ret) {
 		IWM_ERR(iwm, "Couldn't send scan request\n");
 		return ret;
 	}
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
index 36b13a1..e24d5b6 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.h
+++ b/drivers/net/wireless/iwmc3200wifi/commands.h
@@ -106,8 +106,7 @@ enum {
 	CFG_TLC_SPATIAL_STREAM_SUPPORTED,
 	CFG_TLC_RETRY_PER_RATE,
 	CFG_TLC_RETRY_PER_HT_RATE,
-	CFG_TLC_FIXED_RATE,
-	CFG_TLC_FIXED_RATE_FLAGS,
+	CFG_TLC_FIXED_MCS,
 	CFG_TLC_CONTROL_FLAGS,
 	CFG_TLC_SR_MIN_FAIL,
 	CFG_TLC_SR_MIN_PASS,
@@ -232,6 +231,7 @@ struct iwm_umac_cmd_get_channel_list {
 /* Wireless mode */
 #define WIRELESS_MODE_11A  0x1
 #define WIRELESS_MODE_11G  0x2
+#define WIRELESS_MODE_11N  0x4
 
 #define UMAC_PROFILE_EX_IE_REQUIRED	0x1
 #define UMAC_PROFILE_QOS_ALLOWED	0x2
@@ -406,8 +406,7 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm);
 int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
 int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
 int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
-int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
-		struct iwm_key *key);
+int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key);
 int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags);
 int iwm_send_umac_channel_list(struct iwm_priv *iwm);
 int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h
index 8fbb42d..e35c9b6 100644
--- a/drivers/net/wireless/iwmc3200wifi/debug.h
+++ b/drivers/net/wireless/iwmc3200wifi/debug.h
@@ -108,6 +108,8 @@ struct iwm_debugfs {
 	struct dentry *txq_dentry;
 	struct dentry *tx_credit_dentry;
 	struct dentry *rx_ticket_dentry;
+
+	struct dentry *fw_err_dentry;
 };
 
 #ifdef CONFIG_IWM_DEBUG
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
index 0fa7b91..1465379 100644
--- a/drivers/net/wireless/iwmc3200wifi/debugfs.c
+++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c
@@ -98,7 +98,7 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_modules,
 			iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write,
 			"%llu\n");
 
-static int iwm_txrx_open(struct inode *inode, struct file *filp)
+static int iwm_generic_open(struct inode *inode, struct file *filp)
 {
 	filp->private_data = inode->i_private;
 	return 0;
@@ -289,25 +289,111 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
 	return ret;
 }
 
+static ssize_t iwm_debugfs_fw_err_read(struct file *filp,
+				       char __user *buffer,
+				       size_t count, loff_t *ppos)
+{
+
+	struct iwm_priv *iwm = filp->private_data;
+	char buf[512];
+	int buf_len = 512;
+	size_t len = 0;
+
+	if (*ppos != 0)
+		return 0;
+	if (count < sizeof(buf))
+		return -ENOSPC;
+
+	if (!iwm->last_fw_err)
+		return -ENOMEM;
+
+	if (iwm->last_fw_err->line_num == 0)
+		goto out;
+
+	len += snprintf(buf + len, buf_len - len, "%cMAC FW ERROR:\n",
+	     (le32_to_cpu(iwm->last_fw_err->category) == UMAC_SYS_ERR_CAT_LMAC)
+			? 'L' : 'U');
+	len += snprintf(buf + len, buf_len - len,
+			"\tCategory:    %d\n",
+			le32_to_cpu(iwm->last_fw_err->category));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tStatus:      0x%x\n",
+			le32_to_cpu(iwm->last_fw_err->status));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tPC:          0x%x\n",
+			le32_to_cpu(iwm->last_fw_err->pc));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tblink1:      %d\n",
+			le32_to_cpu(iwm->last_fw_err->blink1));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tblink2:      %d\n",
+			le32_to_cpu(iwm->last_fw_err->blink2));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tilink1:      %d\n",
+			le32_to_cpu(iwm->last_fw_err->ilink1));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tilink2:      %d\n",
+			le32_to_cpu(iwm->last_fw_err->ilink2));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tData1:       0x%x\n",
+			le32_to_cpu(iwm->last_fw_err->data1));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tData2:       0x%x\n",
+			le32_to_cpu(iwm->last_fw_err->data2));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tLine number: %d\n",
+			le32_to_cpu(iwm->last_fw_err->line_num));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tUMAC status: 0x%x\n",
+			le32_to_cpu(iwm->last_fw_err->umac_status));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tLMAC status: 0x%x\n",
+			le32_to_cpu(iwm->last_fw_err->lmac_status));
+
+	len += snprintf(buf + len, buf_len - len,
+			"\tSDIO status: 0x%x\n",
+			le32_to_cpu(iwm->last_fw_err->sdio_status));
+
+out:
+
+	return simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+}
 
 static const struct file_operations iwm_debugfs_txq_fops = {
 	.owner =	THIS_MODULE,
-	.open =		iwm_txrx_open,
+	.open =		iwm_generic_open,
 	.read =		iwm_debugfs_txq_read,
 };
 
 static const struct file_operations iwm_debugfs_tx_credit_fops = {
 	.owner =	THIS_MODULE,
-	.open =		iwm_txrx_open,
+	.open =		iwm_generic_open,
 	.read =		iwm_debugfs_tx_credit_read,
 };
 
 static const struct file_operations iwm_debugfs_rx_ticket_fops = {
 	.owner =	THIS_MODULE,
-	.open =		iwm_txrx_open,
+	.open =		iwm_generic_open,
 	.read =		iwm_debugfs_rx_ticket_read,
 };
 
+static const struct file_operations iwm_debugfs_fw_err_fops = {
+	.owner =	THIS_MODULE,
+	.open =		iwm_generic_open,
+	.read =		iwm_debugfs_fw_err_read,
+};
+
 int iwm_debugfs_init(struct iwm_priv *iwm)
 {
 	int i, result;
@@ -423,6 +509,16 @@ int iwm_debugfs_init(struct iwm_priv *iwm)
 		goto error;
 	}
 
+	iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200,
+						     iwm->dbg.dbgdir, iwm,
+						     &iwm_debugfs_fw_err_fops);
+	result = PTR_ERR(iwm->dbg.fw_err_dentry);
+	if (IS_ERR(iwm->dbg.fw_err_dentry) && (result != -ENODEV)) {
+		IWM_ERR(iwm, "Couldn't create last FW err: %d\n", result);
+		goto error;
+	}
+
+
 	return 0;
 
  error:
@@ -441,6 +537,7 @@ void iwm_debugfs_exit(struct iwm_priv *iwm)
 	debugfs_remove(iwm->dbg.txq_dentry);
 	debugfs_remove(iwm->dbg.tx_credit_dentry);
 	debugfs_remove(iwm->dbg.rx_ticket_dentry);
+	debugfs_remove(iwm->dbg.fw_err_dentry);
 	if (iwm->bus_ops->debugfs_exit)
 		iwm->bus_ops->debugfs_exit(iwm);
 
diff --git a/drivers/net/wireless/iwmc3200wifi/eeprom.c b/drivers/net/wireless/iwmc3200wifi/eeprom.c
index 0f34b84..365910f 100644
--- a/drivers/net/wireless/iwmc3200wifi/eeprom.c
+++ b/drivers/net/wireless/iwmc3200wifi/eeprom.c
@@ -156,10 +156,6 @@ int iwm_eeprom_init(struct iwm_priv *iwm)
 		return -ENOMEM;
 
 	for (i = IWM_EEPROM_FIRST; i < IWM_EEPROM_LAST; i++) {
-#ifdef CONFIG_IWM_B0_HW_SUPPORT
-		if (iwm->conf.hw_b0 && (i >= IWM_EEPROM_INDIRECT_OFFSET))
-			break;
-#endif
 		ret = iwm_eeprom_read(iwm, i);
 		if (ret < 0) {
 			IWM_ERR(iwm, "Couldn't read eeprom entry #%d: %s\n",
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index ec1a15a..6b0bcad 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -261,6 +261,33 @@ static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
 			cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_CLK_EN), 0);
 }
 
+static int iwm_init_calib(struct iwm_priv *iwm, unsigned long cfg_bitmap,
+			  unsigned long expected_bitmap, u8 rx_iq_cmd)
+{
+	/* Read RX IQ calibration result from EEPROM */
+	if (test_bit(rx_iq_cmd, &cfg_bitmap)) {
+		iwm_store_rxiq_calib_result(iwm);
+		set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
+	}
+
+	iwm_send_prio_table(iwm);
+	iwm_send_init_calib_cfg(iwm, cfg_bitmap);
+
+	while (iwm->calib_done_map != expected_bitmap) {
+		if (iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
+				     IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT)) {
+			IWM_DBG_FW(iwm, DBG, "Initial calibration timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
+			   "0x%lx, expected calibrations: 0x%lx\n",
+			   iwm->calib_done_map, expected_bitmap);
+	}
+
+	return 0;
+}
+
 /*
  * We currently have to load 3 FWs:
  * 1) The UMAC (Upper MAC).
@@ -275,6 +302,8 @@ static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
  */
 int iwm_load_fw(struct iwm_priv *iwm)
 {
+	unsigned long init_calib_map, periodic_calib_map;
+	unsigned long expected_calib_map;
 	int ret;
 
 	/* We first start downloading the UMAC */
@@ -315,32 +344,22 @@ int iwm_load_fw(struct iwm_priv *iwm)
 		return ret;
 	}
 
-#ifdef CONFIG_IWM_B0_HW_SUPPORT
-	if (iwm->conf.hw_b0) {
-		clear_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->conf.init_calib_map);
-		clear_bit(PHY_CALIBRATE_RX_IQ_CMD,
-			  &iwm->conf.periodic_calib_map);
-	}
-#endif
-	/* Read RX IQ calibration result from EEPROM */
-	if (test_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->conf.init_calib_map)) {
-		iwm_store_rxiq_calib_result(iwm);
-		set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
-	}
-
-	iwm_send_prio_table(iwm);
-	iwm_send_init_calib_cfg(iwm, iwm->conf.init_calib_map);
+	init_calib_map = iwm->conf.calib_map & IWM_CALIB_MAP_INIT_MSK;
+	expected_calib_map = iwm->conf.expected_calib_map &
+		IWM_CALIB_MAP_INIT_MSK;
+	periodic_calib_map = IWM_CALIB_MAP_PER_LMAC(iwm->conf.calib_map);
 
-	while (iwm->calib_done_map != iwm->conf.init_calib_map) {
-		ret = iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
-				       IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
-		if (ret) {
-			IWM_ERR(iwm, "Wait for calibration result timeout\n");
+	ret = iwm_init_calib(iwm, init_calib_map, expected_calib_map,
+			     CALIB_CFG_RX_IQ_IDX);
+	if (ret < 0) {
+		/* Let's try the old way */
+		ret = iwm_init_calib(iwm, expected_calib_map,
+				     expected_calib_map,
+				     PHY_CALIBRATE_RX_IQ_CMD);
+		if (ret < 0) {
+			IWM_ERR(iwm, "Calibration result timeout\n");
 			goto out;
 		}
-		IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
-			   "0x%lx, requested calibrations: 0x%lx\n",
-			   iwm->calib_done_map, iwm->conf.init_calib_map);
 	}
 
 	/* Handle LMAC CALIBRATION_COMPLETE notification */
@@ -378,7 +397,7 @@ int iwm_load_fw(struct iwm_priv *iwm)
 
 	iwm_send_prio_table(iwm);
 	iwm_send_calib_results(iwm);
-	iwm_send_periodic_calib_cfg(iwm, iwm->conf.periodic_calib_map);
+	iwm_send_periodic_calib_cfg(iwm, periodic_calib_map);
 
 	return 0;
 
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
index ee127fe..c430418 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.c
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -105,9 +105,9 @@
 #include "umac.h"
 #include "debug.h"
 
-static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
-				 struct iwm_nonwifi_cmd *cmd,
-				 struct iwm_udma_nonwifi_cmd *udma_cmd)
+static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
+				struct iwm_nonwifi_cmd *cmd,
+				struct iwm_udma_nonwifi_cmd *udma_cmd)
 {
 	INIT_LIST_HEAD(&cmd->pending);
 
@@ -118,7 +118,7 @@ static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
 	cmd->seq_num = iwm->nonwifi_seq_num;
 	udma_cmd->seq_num = cpu_to_le16(cmd->seq_num);
 
-	cmd->seq_num = iwm->nonwifi_seq_num++;
+	iwm->nonwifi_seq_num++;
 	iwm->nonwifi_seq_num %= UMAC_NONWIFI_SEQ_NUM_MAX;
 
 	if (udma_cmd->resp)
@@ -130,6 +130,8 @@ static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
 	cmd->buf.len = 0;
 
 	memcpy(&cmd->udma_cmd, udma_cmd, sizeof(*udma_cmd));
+
+	return cmd->seq_num;
 }
 
 u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm)
@@ -369,7 +371,7 @@ int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
 			    const void *payload)
 {
 	struct iwm_nonwifi_cmd *cmd;
-	int ret;
+	int ret, seq_num;
 
 	cmd = kzalloc(sizeof(struct iwm_nonwifi_cmd), GFP_KERNEL);
 	if (!cmd) {
@@ -377,7 +379,7 @@ int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
 		return -ENOMEM;
 	}
 
-	iwm_nonwifi_cmd_init(iwm, cmd, udma_cmd);
+	seq_num = iwm_nonwifi_cmd_init(iwm, cmd, udma_cmd);
 
 	if (cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE ||
 	    cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE_PERSISTENT) {
@@ -393,7 +395,7 @@ int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
 	if (ret < 0)
 		return ret;
 
-	return cmd->seq_num;
+	return seq_num;
 }
 
 static void iwm_build_lmac_hdr(struct iwm_priv *iwm, struct iwm_lmac_hdr *hdr,
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 77c339f..1b02a4e 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -52,8 +52,6 @@
 #define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation"
 #define IWM_AUTHOR "<ilw@linux.intel.com>"
 
-#define CONFIG_IWM_B0_HW_SUPPORT	1
-
 #define IWM_SRC_LMAC	UMAC_HDI_IN_SOURCE_FHRX
 #define IWM_SRC_UDMA	UMAC_HDI_IN_SOURCE_UDMA
 #define IWM_SRC_UMAC	UMAC_HDI_IN_SOURCE_FW
@@ -65,8 +63,8 @@
 
 struct iwm_conf {
 	u32 sdio_ior_timeout;
-	unsigned long init_calib_map;
-	unsigned long periodic_calib_map;
+	unsigned long calib_map;
+	unsigned long expected_calib_map;
 	bool reset_on_fatal_err;
 	bool auto_connect;
 	bool wimax_not_present;
@@ -87,9 +85,6 @@ struct iwm_conf {
 	u8 ibss_channel;
 
 	u8 mac_addr[ETH_ALEN];
-#ifdef CONFIG_IWM_B0_HW_SUPPORT
-	bool hw_b0;
-#endif
 };
 
 enum {
@@ -162,13 +157,11 @@ struct iwm_umac_key_hdr {
 
 struct iwm_key {
 	struct iwm_umac_key_hdr hdr;
-	u8 in_use;
-	u8 alg;
-	u32 flags;
-	u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE];
-	u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE];
-	u8 key_len;
-	u8 key[32];
+	u32 cipher;
+	u8 key[WLAN_MAX_KEY_LEN];
+	u8 seq[IW_ENCODE_SEQ_MAX_SIZE];
+	int key_len;
+	int seq_len;
 };
 
 #define IWM_RX_ID_HASH  0xff
@@ -183,12 +176,9 @@ struct iwm_key {
 #define IWM_STATUS_READY		0
 #define IWM_STATUS_SCANNING		1
 #define IWM_STATUS_SCAN_ABORTING	2
-#define IWM_STATUS_ASSOCIATING		3
+#define IWM_STATUS_SME_CONNECTING	3
 #define IWM_STATUS_ASSOCIATED		4
-
-#define IWM_RADIO_RFKILL_OFF		0
-#define IWM_RADIO_RFKILL_HW		1
-#define IWM_RADIO_RFKILL_SW		2
+#define IWM_STATUS_RESETTING		5
 
 struct iwm_tx_queue {
 	int id;
@@ -223,7 +213,6 @@ struct iwm_priv {
 	struct iwm_conf conf;
 
 	unsigned long status;
-	unsigned long radio;
 
 	struct list_head pending_notif;
 	wait_queue_head_t notif_queue;
@@ -242,6 +231,7 @@ struct iwm_priv {
 	u8 bssid[ETH_ALEN];
 	u8 channel;
 	u16 rate;
+	u32 txpower;
 
 	struct iwm_sta_info sta_table[IWM_STA_TABLE_NUM];
 	struct list_head bss_list;
@@ -276,12 +266,16 @@ struct iwm_priv {
 	struct iwm_tx_queue txq[IWM_TX_QUEUES];
 
 	struct iwm_key keys[IWM_NUM_KEYS];
-	struct iwm_key *default_key;
+	s8 default_key;
+
+	DECLARE_BITMAP(wifi_ntfy, WIFI_IF_NTFY_MAX);
+	wait_queue_head_t wifi_ntfy_queue;
 
 	wait_queue_head_t mlme_queue;
 
 	struct iw_statistics wstats;
 	struct delayed_work stats_request;
+	struct delayed_work disconnect;
 
 	struct iwm_debugfs dbg;
 
@@ -289,7 +283,13 @@ struct iwm_priv {
 	struct timer_list watchdog;
 	struct work_struct reset_worker;
 	struct mutex mutex;
-	struct rfkill *rfkill;
+
+	u8 *req_ie;
+	int req_ie_len;
+	u8 *resp_ie;
+	int resp_ie_len;
+
+	struct iwm_fw_error_hdr *last_fw_err;
 
 	char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
 };
@@ -311,8 +311,6 @@ static inline void *iwm_private(struct iwm_priv *iwm)
 #define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb))
 #define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb)
 
-extern const struct iw_handler_def iwm_iw_handler_def;
-
 void *iwm_if_alloc(int sizeof_bus, struct device *dev,
 		   struct iwm_if_ops *if_ops);
 void iwm_if_free(struct iwm_priv *iwm);
@@ -322,6 +320,7 @@ int iwm_mode_to_nl80211_iftype(int mode);
 int iwm_priv_init(struct iwm_priv *iwm);
 void iwm_priv_deinit(struct iwm_priv *iwm);
 void iwm_reset(struct iwm_priv *iwm);
+void iwm_resetting(struct iwm_priv *iwm);
 void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
 			      struct iwm_umac_notif_alive *alive);
 int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb);
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
index db2e5ee..6c1a14c 100644
--- a/drivers/net/wireless/iwmc3200wifi/lmac.h
+++ b/drivers/net/wireless/iwmc3200wifi/lmac.h
@@ -396,6 +396,25 @@ enum {
 	CALIBRATION_CMD_NUM,
 };
 
+enum {
+	CALIB_CFG_RX_BB_IDX       = 0,
+	CALIB_CFG_DC_IDX          = 1,
+	CALIB_CFG_LO_IDX          = 2,
+	CALIB_CFG_TX_IQ_IDX       = 3,
+	CALIB_CFG_RX_IQ_IDX       = 4,
+	CALIB_CFG_NOISE_IDX       = 5,
+	CALIB_CFG_CRYSTAL_IDX     = 6,
+	CALIB_CFG_TEMPERATURE_IDX = 7,
+	CALIB_CFG_PAPD_IDX        = 8,
+	CALIB_CFG_LAST_IDX        = CALIB_CFG_PAPD_IDX,
+	CALIB_CFG_MODULE_NUM,
+};
+
+#define IWM_CALIB_MAP_INIT_MSK		0xFFFF
+#define IWM_CALIB_MAP_PER_LMAC(m)	((m & 0xFF0000) >> 16)
+#define IWM_CALIB_MAP_PER_UMAC(m)	((m & 0xFF000000) >> 24)
+#define IWM_CALIB_OPCODE_TO_INDEX(op)   (op - PHY_CALIBRATE_OPCODES_NUM)
+
 struct iwm_lmac_calib_hdr {
 	u8 opcode;
 	u8 first_grp;
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 8be206d..d668e47 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -53,11 +53,12 @@
 static struct iwm_conf def_iwm_conf = {
 
 	.sdio_ior_timeout	= 5000,
-	.init_calib_map		= BIT(PHY_CALIBRATE_DC_CMD)	|
-				  BIT(PHY_CALIBRATE_LO_CMD)	|
-				  BIT(PHY_CALIBRATE_TX_IQ_CMD)	|
-				  BIT(PHY_CALIBRATE_RX_IQ_CMD),
-	.periodic_calib_map	= BIT(PHY_CALIBRATE_DC_CMD)	|
+	.calib_map		= BIT(CALIB_CFG_DC_IDX)	|
+				  BIT(CALIB_CFG_LO_IDX)	|
+				  BIT(CALIB_CFG_TX_IQ_IDX)	|
+				  BIT(CALIB_CFG_RX_IQ_IDX)	|
+				  BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
+	.expected_calib_map	= BIT(PHY_CALIBRATE_DC_CMD)	|
 				  BIT(PHY_CALIBRATE_LO_CMD)	|
 				  BIT(PHY_CALIBRATE_TX_IQ_CMD)	|
 				  BIT(PHY_CALIBRATE_RX_IQ_CMD)	|
@@ -112,8 +113,28 @@ static void iwm_statistics_request(struct work_struct *work)
 	iwm_send_umac_stats_req(iwm, 0);
 }
 
-int __iwm_up(struct iwm_priv *iwm);
-int __iwm_down(struct iwm_priv *iwm);
+static void iwm_disconnect_work(struct work_struct *work)
+{
+	struct iwm_priv *iwm =
+		container_of(work, struct iwm_priv, disconnect.work);
+
+	if (iwm->umac_profile_active)
+		iwm_invalidate_mlme_profile(iwm);
+
+	clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+	iwm->umac_profile_active = 0;
+	memset(iwm->bssid, 0, ETH_ALEN);
+	iwm->channel = 0;
+
+	iwm_link_off(iwm);
+
+	wake_up_interruptible(&iwm->mlme_queue);
+
+	cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
+}
+
+static int __iwm_up(struct iwm_priv *iwm);
+static int __iwm_down(struct iwm_priv *iwm);
 
 static void iwm_reset_worker(struct work_struct *work)
 {
@@ -166,7 +187,8 @@ static void iwm_reset_worker(struct work_struct *work)
 		memcpy(iwm->umac_profile, profile, sizeof(*profile));
 		iwm_send_mlme_profile(iwm);
 		kfree(profile);
-	}
+	} else
+		clear_bit(IWM_STATUS_RESETTING, &iwm->status);
 
  out:
 	mutex_unlock(&iwm->mutex);
@@ -179,7 +201,7 @@ static void iwm_watchdog(unsigned long data)
 	IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
 
 	if (modparam_reset)
-		schedule_work(&iwm->reset_worker);
+		iwm_resetting(iwm);
 }
 
 int iwm_priv_init(struct iwm_priv *iwm)
@@ -191,6 +213,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
 	INIT_LIST_HEAD(&iwm->pending_notif);
 	init_waitqueue_head(&iwm->notif_queue);
 	init_waitqueue_head(&iwm->nonwifi_queue);
+	init_waitqueue_head(&iwm->wifi_ntfy_queue);
 	init_waitqueue_head(&iwm->mlme_queue);
 	memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf));
 	spin_lock_init(&iwm->tx_credit.lock);
@@ -201,6 +224,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
 	spin_lock_init(&iwm->cmd_lock);
 	iwm->scan_id = 1;
 	INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
+	INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
 	INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
 	INIT_LIST_HEAD(&iwm->bss_list);
 
@@ -229,13 +253,18 @@ int iwm_priv_init(struct iwm_priv *iwm)
 	for (i = 0; i < IWM_NUM_KEYS; i++)
 		memset(&iwm->keys[i], 0, sizeof(struct iwm_key));
 
-	iwm->default_key = NULL;
+	iwm->default_key = -1;
 
 	init_timer(&iwm->watchdog);
 	iwm->watchdog.function = iwm_watchdog;
 	iwm->watchdog.data = (unsigned long)iwm;
 	mutex_init(&iwm->mutex);
 
+	iwm->last_fw_err = kzalloc(sizeof(struct iwm_fw_error_hdr),
+				   GFP_KERNEL);
+	if (iwm->last_fw_err == NULL)
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -247,6 +276,7 @@ void iwm_priv_deinit(struct iwm_priv *iwm)
 		destroy_workqueue(iwm->txq[i].wq);
 
 	destroy_workqueue(iwm->rx_wq);
+	kfree(iwm->last_fw_err);
 }
 
 /*
@@ -261,7 +291,11 @@ void iwm_reset(struct iwm_priv *iwm)
 	if (test_bit(IWM_STATUS_READY, &iwm->status))
 		iwm_target_reset(iwm);
 
-	iwm->status = 0;
+	if (test_bit(IWM_STATUS_RESETTING, &iwm->status)) {
+		iwm->status = 0;
+		set_bit(IWM_STATUS_RESETTING, &iwm->status);
+	} else
+		iwm->status = 0;
 	iwm->scan_id = 1;
 
 	list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
@@ -277,6 +311,13 @@ void iwm_reset(struct iwm_priv *iwm)
 	iwm_link_off(iwm);
 }
 
+void iwm_resetting(struct iwm_priv *iwm)
+{
+	set_bit(IWM_STATUS_RESETTING, &iwm->status);
+
+	schedule_work(&iwm->reset_worker);
+}
+
 /*
  * Notification code:
  *
@@ -500,6 +541,13 @@ void iwm_link_off(struct iwm_priv *iwm)
 	memset(wstats, 0, sizeof(struct iw_statistics));
 	wstats->qual.updated = IW_QUAL_ALL_INVALID;
 
+	kfree(iwm->req_ie);
+	iwm->req_ie = NULL;
+	iwm->req_ie_len = 0;
+	kfree(iwm->resp_ie);
+	iwm->resp_ie = NULL;
+	iwm->resp_ie_len = 0;
+
 	del_timer_sync(&iwm->watchdog);
 }
 
@@ -518,13 +566,6 @@ static int iwm_channels_init(struct iwm_priv *iwm)
 {
 	int ret;
 
-#ifdef CONFIG_IWM_B0_HW_SUPPORT
-	if (iwm->conf.hw_b0) {
-		IWM_INFO(iwm, "Workaround EEPROM channels for B0 hardware\n");
-		return 0;
-	}
-#endif
-
 	ret = iwm_send_umac_channel_list(iwm);
 	if (ret) {
 		IWM_ERR(iwm, "Send channel list failed\n");
@@ -541,7 +582,7 @@ static int iwm_channels_init(struct iwm_priv *iwm)
 	return 0;
 }
 
-int __iwm_up(struct iwm_priv *iwm)
+static int __iwm_up(struct iwm_priv *iwm)
 {
 	int ret;
 	struct iwm_notif *notif_reboot, *notif_ack = NULL;
@@ -642,19 +683,10 @@ int __iwm_up(struct iwm_priv *iwm)
 		}
 	}
 
-	iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
-				    GFP_KERNEL);
-	if (!iwm->umac_profile) {
-		IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
-		goto err_fw;
-	}
-
-	iwm_init_default_profile(iwm, iwm->umac_profile);
-
 	ret = iwm_channels_init(iwm);
 	if (ret < 0) {
 		IWM_ERR(iwm, "Couldn't init channels\n");
-		goto err_profile;
+		goto err_fw;
 	}
 
 	/* Set the READY bit to indicate interface is brought up successfully */
@@ -662,10 +694,6 @@ int __iwm_up(struct iwm_priv *iwm)
 
 	return 0;
 
- err_profile:
-	kfree(iwm->umac_profile);
-	iwm->umac_profile = NULL;
-
  err_fw:
 	iwm_eeprom_exit(iwm);
 
@@ -688,7 +716,7 @@ int iwm_up(struct iwm_priv *iwm)
 	return ret;
 }
 
-int __iwm_down(struct iwm_priv *iwm)
+static int __iwm_down(struct iwm_priv *iwm)
 {
 	int ret;
 
@@ -704,11 +732,10 @@ int __iwm_down(struct iwm_priv *iwm)
 	clear_bit(IWM_STATUS_READY, &iwm->status);
 
 	iwm_eeprom_exit(iwm);
-	kfree(iwm->umac_profile);
-	iwm->umac_profile = NULL;
 	iwm_bss_list_clean(iwm);
-
-	iwm->default_key = NULL;
+	iwm_init_default_profile(iwm, iwm->umac_profile);
+	iwm->umac_profile_active = false;
+	iwm->default_key = -1;
 	iwm->core_enabled = 0;
 
 	ret = iwm_bus_disable(iwm);
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
index bf294e4..35ec006 100644
--- a/drivers/net/wireless/iwmc3200wifi/netdev.c
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -48,29 +48,22 @@
 #include <linux/netdevice.h>
 
 #include "iwm.h"
+#include "commands.h"
 #include "cfg80211.h"
 #include "debug.h"
 
 static int iwm_open(struct net_device *ndev)
 {
 	struct iwm_priv *iwm = ndev_to_iwm(ndev);
-	int ret = 0;
-
-	if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
-		ret = iwm_up(iwm);
 
-	return ret;
+	return iwm_up(iwm);
 }
 
 static int iwm_stop(struct net_device *ndev)
 {
 	struct iwm_priv *iwm = ndev_to_iwm(ndev);
-	int ret = 0;
-
-	if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
-		ret = iwm_down(iwm);
 
-	return ret;
+	return iwm_down(iwm);
 }
 
 /*
@@ -128,13 +121,24 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
 	}
 
 	ndev->netdev_ops = &iwm_netdev_ops;
-	ndev->wireless_handlers = &iwm_iw_handler_def;
 	ndev->ieee80211_ptr = wdev;
 	SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
 	wdev->netdev = ndev;
 
+	iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
+				    GFP_KERNEL);
+	if (!iwm->umac_profile) {
+		dev_err(dev, "Couldn't alloc memory for profile\n");
+		goto out_profile;
+	}
+
+	iwm_init_default_profile(iwm, iwm->umac_profile);
+
 	return iwm;
 
+ out_profile:
+	free_netdev(ndev);
+
  out_priv:
 	iwm_priv_deinit(iwm);
 
@@ -150,6 +154,8 @@ void iwm_if_free(struct iwm_priv *iwm)
 
 	free_netdev(iwm_to_ndev(iwm));
 	iwm_priv_deinit(iwm);
+	kfree(iwm->umac_profile);
+	iwm->umac_profile = NULL;
 	iwm_wdev_free(iwm);
 }
 
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index d73cf96..40dbcbc 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -102,6 +102,7 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
 	error = (struct iwm_umac_notif_error *)buf;
 	fw_err = &error->err;
 
+	memcpy(iwm->last_fw_err, fw_err, sizeof(struct iwm_fw_error_hdr));
 
 	IWM_ERR(iwm, "%cMAC FW ERROR:\n",
 	 (le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U');
@@ -119,6 +120,8 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
 	IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status));
 	IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status));
 
+	iwm_resetting(iwm);
+
 	return 0;
 }
 
@@ -143,17 +146,18 @@ static int iwm_ntf_init_complete(struct iwm_priv *iwm, u8 *buf,
 				 unsigned long buf_size,
 				 struct iwm_wifi_cmd *cmd)
 {
+	struct wiphy *wiphy = iwm_to_wiphy(iwm);
 	struct iwm_umac_notif_init_complete *init_complete =
 			(struct iwm_umac_notif_init_complete *)(buf);
 	u16 status = le16_to_cpu(init_complete->status);
+	bool blocked = (status == UMAC_NTFY_INIT_COMPLETE_STATUS_ERR);
 
-	if (status == UMAC_NTFY_INIT_COMPLETE_STATUS_ERR) {
+	if (blocked)
 		IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is on (radio off)\n");
-		set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
-	} else {
+	else
 		IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is off (radio on)\n");
-		clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
-	}
+
+	wiphy_rfkill_set_hw_state(wiphy, blocked);
 
 	return 0;
 }
@@ -218,17 +222,17 @@ static int iwm_ntf_tx(struct iwm_priv *iwm, u8 *buf,
 		(buf + sizeof(struct iwm_umac_wifi_in_hdr));
 	hdr = (struct iwm_umac_wifi_in_hdr *)buf;
 
-	IWM_DBG_NTF(iwm, DBG, "REPLY_TX, buf size: %lu\n", buf_size);
+	IWM_DBG_TX(iwm, DBG, "REPLY_TX, buf size: %lu\n", buf_size);
 
-	IWM_DBG_NTF(iwm, DBG, "Seqnum: %d\n",
-		    le16_to_cpu(hdr->sw_hdr.cmd.seq_num));
-	IWM_DBG_NTF(iwm, DBG, "\tFrame cnt: %d\n", tx_resp->frame_cnt);
-	IWM_DBG_NTF(iwm, DBG, "\tRetry cnt: %d\n",
-		    le16_to_cpu(tx_resp->retry_cnt));
-	IWM_DBG_NTF(iwm, DBG, "\tSeq ctl: %d\n", le16_to_cpu(tx_resp->seq_ctl));
-	IWM_DBG_NTF(iwm, DBG, "\tByte cnt: %d\n",
-		    le16_to_cpu(tx_resp->byte_cnt));
-	IWM_DBG_NTF(iwm, DBG, "\tStatus: 0x%x\n", le32_to_cpu(tx_resp->status));
+	IWM_DBG_TX(iwm, DBG, "Seqnum: %d\n",
+		   le16_to_cpu(hdr->sw_hdr.cmd.seq_num));
+	IWM_DBG_TX(iwm, DBG, "\tFrame cnt: %d\n", tx_resp->frame_cnt);
+	IWM_DBG_TX(iwm, DBG, "\tRetry cnt: %d\n",
+		   le16_to_cpu(tx_resp->retry_cnt));
+	IWM_DBG_TX(iwm, DBG, "\tSeq ctl: %d\n", le16_to_cpu(tx_resp->seq_ctl));
+	IWM_DBG_TX(iwm, DBG, "\tByte cnt: %d\n",
+		   le16_to_cpu(tx_resp->byte_cnt));
+	IWM_DBG_TX(iwm, DBG, "\tStatus: 0x%x\n", le32_to_cpu(tx_resp->status));
 
 	return 0;
 }
@@ -418,8 +422,8 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
 			if (IS_ERR(ticket_node))
 				return PTR_ERR(ticket_node);
 
-			IWM_DBG_NTF(iwm, DBG, "TICKET RELEASE(%d)\n",
-				    ticket->id);
+			IWM_DBG_RX(iwm, DBG, "TICKET RELEASE(%d)\n",
+				   ticket->id);
 			list_add_tail(&ticket_node->node, &iwm->rx_tickets);
 
 			/*
@@ -454,15 +458,15 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
 	u16 id, buf_offset;
 	u32 packet_size;
 
-	IWM_DBG_NTF(iwm, DBG, "\n");
+	IWM_DBG_RX(iwm, DBG, "\n");
 
 	wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
 	id = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
 	buf_offset = sizeof(struct iwm_umac_wifi_in_hdr);
 	packet_size = buf_size - sizeof(struct iwm_umac_wifi_in_hdr);
 
-	IWM_DBG_NTF(iwm, DBG, "CMD:0x%x, seqnum: %d, packet size: %d\n",
-		    wifi_hdr->sw_hdr.cmd.cmd, id, packet_size);
+	IWM_DBG_RX(iwm, DBG, "CMD:0x%x, seqnum: %d, packet size: %d\n",
+		   wifi_hdr->sw_hdr.cmd.cmd, id, packet_size);
 	IWM_DBG_RX(iwm, DBG, "Packet id: %d\n", id);
 	IWM_HEXDUMP(iwm, DBG, RX, "PACKET: ", buf + buf_offset, packet_size);
 
@@ -487,8 +491,6 @@ static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
 
 	start = (struct iwm_umac_notif_assoc_start *)buf;
 
-	set_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
-
 	IWM_DBG_MLME(iwm, INFO, "Association with %pM Started, reason: %d\n",
 		     start->bssid, le32_to_cpu(start->roam_reason));
 
@@ -503,43 +505,84 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
 {
 	struct iwm_umac_notif_assoc_complete *complete =
 		(struct iwm_umac_notif_assoc_complete *)buf;
-	union iwreq_data wrqu;
 
 	IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
 		     complete->bssid, complete->status);
 
-	memset(&wrqu, 0, sizeof(wrqu));
-
-	clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
-
 	switch (le32_to_cpu(complete->status)) {
 	case UMAC_ASSOC_COMPLETE_SUCCESS:
 		set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
 		memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
 		iwm->channel = complete->channel;
 
+		/* Internal roaming state, avoid notifying SME. */
+		if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
+		    && iwm->conf.mode == UMAC_MODE_BSS) {
+			cancel_delayed_work(&iwm->disconnect);
+			cfg80211_roamed(iwm_to_ndev(iwm),
+					complete->bssid,
+					iwm->req_ie, iwm->req_ie_len,
+					iwm->resp_ie, iwm->resp_ie_len,
+					GFP_KERNEL);
+			break;
+		}
+
 		iwm_link_on(iwm);
 
-		memcpy(wrqu.ap_addr.sa_data, complete->bssid, ETH_ALEN);
+		if (iwm->conf.mode == UMAC_MODE_IBSS)
+			goto ibss;
+
+		if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
+			cfg80211_connect_result(iwm_to_ndev(iwm),
+						complete->bssid,
+						iwm->req_ie, iwm->req_ie_len,
+						iwm->resp_ie, iwm->resp_ie_len,
+						WLAN_STATUS_SUCCESS,
+						GFP_KERNEL);
+		else
+			cfg80211_roamed(iwm_to_ndev(iwm),
+					complete->bssid,
+					iwm->req_ie, iwm->req_ie_len,
+					iwm->resp_ie, iwm->resp_ie_len,
+					GFP_KERNEL);
 		break;
 	case UMAC_ASSOC_COMPLETE_FAILURE:
 		clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
 		memset(iwm->bssid, 0, ETH_ALEN);
 		iwm->channel = 0;
 
+		/* Internal roaming state, avoid notifying SME. */
+		if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
+		    && iwm->conf.mode == UMAC_MODE_BSS) {
+			cancel_delayed_work(&iwm->disconnect);
+			break;
+		}
+
 		iwm_link_off(iwm);
+
+		if (iwm->conf.mode == UMAC_MODE_IBSS)
+			goto ibss;
+
+		if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
+			cfg80211_connect_result(iwm_to_ndev(iwm),
+						complete->bssid,
+						NULL, 0, NULL, 0,
+						WLAN_STATUS_UNSPECIFIED_FAILURE,
+						GFP_KERNEL);
+		else
+			cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
+					      GFP_KERNEL);
+		break;
 	default:
 		break;
 	}
 
-	if (iwm->conf.mode == UMAC_MODE_IBSS) {
-		cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
-		return 0;
-	}
-
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	wireless_send_event(iwm_to_ndev(iwm), SIOCGIWAP, &wrqu, NULL);
+	clear_bit(IWM_STATUS_RESETTING, &iwm->status);
+	return 0;
 
+ ibss:
+	cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
+	clear_bit(IWM_STATUS_RESETTING, &iwm->status);
 	return 0;
 }
 
@@ -548,13 +591,20 @@ static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
 				       struct iwm_wifi_cmd *cmd)
 {
 	struct iwm_umac_notif_profile_invalidate *invalid;
+	u32 reason;
 
 	invalid = (struct iwm_umac_notif_profile_invalidate *)buf;
+	reason = le32_to_cpu(invalid->reason);
+
+	IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n", reason);
 
-	IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n",
-		     le32_to_cpu(invalid->reason));
+	if (reason != UMAC_PROFILE_INVALID_REQUEST &&
+	    test_bit(IWM_STATUS_SME_CONNECTING, &iwm->status))
+		cfg80211_connect_result(iwm_to_ndev(iwm), NULL, NULL, 0, NULL,
+					0, WLAN_STATUS_UNSPECIFIED_FAILURE,
+					GFP_KERNEL);
 
-	clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+	clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status);
 	clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
 
 	iwm->umac_profile_active = 0;
@@ -568,6 +618,19 @@ static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
 	return 0;
 }
 
+#define IWM_DISCONNECT_INTERVAL	(5 * HZ)
+
+static int iwm_mlme_connection_terminated(struct iwm_priv *iwm, u8 *buf,
+					  unsigned long buf_size,
+					  struct iwm_wifi_cmd *cmd)
+{
+	IWM_DBG_MLME(iwm, DBG, "Connection terminated\n");
+
+	schedule_delayed_work(&iwm->disconnect, IWM_DISCONNECT_INTERVAL);
+
+	return 0;
+}
+
 static int iwm_mlme_scan_complete(struct iwm_priv *iwm, u8 *buf,
 				  unsigned long buf_size,
 				  struct iwm_wifi_cmd *cmd)
@@ -769,37 +832,47 @@ static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
 			      unsigned long buf_size, struct iwm_wifi_cmd *cmd)
 {
 	struct iwm_umac_notif_mgt_frame *mgt_frame =
-	(struct iwm_umac_notif_mgt_frame *)buf;
+			(struct iwm_umac_notif_mgt_frame *)buf;
 	struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame;
 	u8 *ie;
-	unsigned int event;
-	union iwreq_data wrqu;
 
 	IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame,
 		    le16_to_cpu(mgt_frame->len));
 
 	if (ieee80211_is_assoc_req(mgt->frame_control)) {
 		ie = mgt->u.assoc_req.variable;;
-		event = IWEVASSOCREQIE;
+		iwm->req_ie_len =
+				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		kfree(iwm->req_ie);
+		iwm->req_ie = kmemdup(mgt->u.assoc_req.variable,
+				      iwm->req_ie_len, GFP_KERNEL);
 	} else if (ieee80211_is_reassoc_req(mgt->frame_control)) {
 		ie = mgt->u.reassoc_req.variable;;
-		event = IWEVASSOCREQIE;
+		iwm->req_ie_len =
+				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		kfree(iwm->req_ie);
+		iwm->req_ie = kmemdup(mgt->u.reassoc_req.variable,
+				      iwm->req_ie_len, GFP_KERNEL);
 	} else if (ieee80211_is_assoc_resp(mgt->frame_control)) {
 		ie = mgt->u.assoc_resp.variable;;
-		event = IWEVASSOCRESPIE;
+		iwm->resp_ie_len =
+				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		kfree(iwm->resp_ie);
+		iwm->resp_ie = kmemdup(mgt->u.assoc_resp.variable,
+				       iwm->resp_ie_len, GFP_KERNEL);
 	} else if (ieee80211_is_reassoc_resp(mgt->frame_control)) {
 		ie = mgt->u.reassoc_resp.variable;;
-		event = IWEVASSOCRESPIE;
+		iwm->resp_ie_len =
+				le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+		kfree(iwm->resp_ie);
+		iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable,
+				       iwm->resp_ie_len, GFP_KERNEL);
 	} else {
-		IWM_ERR(iwm, "Unsupported management frame");
+		IWM_ERR(iwm, "Unsupported management frame: 0x%x",
+			le16_to_cpu(mgt->frame_control));
 		return 0;
 	}
 
-	wrqu.data.length = le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
-
-	IWM_HEXDUMP(iwm, DBG, MLME, "EVT: ", ie, wrqu.data.length);
-	wireless_send_event(iwm_to_ndev(iwm), event, &wrqu, ie);
-
 	return 0;
 }
 
@@ -817,8 +890,7 @@ static int iwm_ntf_mlme(struct iwm_priv *iwm, u8 *buf,
 	case WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE:
 		return iwm_mlme_profile_invalidate(iwm, buf, buf_size, cmd);
 	case WIFI_IF_NTFY_CONNECTION_TERMINATED:
-		IWM_DBG_MLME(iwm, DBG, "Connection terminated\n");
-		break;
+		return iwm_mlme_connection_terminated(iwm, buf, buf_size, cmd);
 	case WIFI_IF_NTFY_SCAN_COMPLETE:
 		return iwm_mlme_scan_complete(iwm, buf, buf_size, cmd);
 	case WIFI_IF_NTFY_STA_TABLE_CHANGE:
@@ -875,6 +947,7 @@ static int iwm_ntf_statistics(struct iwm_priv *iwm, u8 *buf,
 		/* UMAC passes rate info multiplies by 2 */
 		iwm->rate = max_rate >> 1;
 	}
+	iwm->txpower = le32_to_cpu(stats->tx_power);
 
 	wstats->status = 0;
 
@@ -922,13 +995,6 @@ static int iwm_ntf_eeprom_proxy(struct iwm_priv *iwm, u8 *buf,
 	if ((hdr_offset + hdr_len) > IWM_EEPROM_LEN)
 		return -EINVAL;
 
-#ifdef CONFIG_IWM_B0_HW_SUPPORT
-	if (hdr_offset == IWM_EEPROM_SKU_CAP_OFF) {
-		if (eeprom_proxy->buf[0] == 0xff)
-			iwm->conf.hw_b0 = 1;
-	}
-#endif
-
 	switch (hdr_type) {
 	case IWM_UMAC_CMD_EEPROM_TYPE_READ:
 		memcpy(iwm->eeprom + hdr_offset, eeprom_proxy->buf, hdr_len);
@@ -993,12 +1059,17 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
 			(struct iwm_umac_wifi_if *)cmd->buf.payload;
 
 	IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
-		    "oid is %d\n", hdr->oid);
+		    "oid is 0x%x\n", hdr->oid);
+
+	if (hdr->oid <= WIFI_IF_NTFY_MAX) {
+		set_bit(hdr->oid, &iwm->wifi_ntfy[0]);
+		wake_up_interruptible(&iwm->wifi_ntfy_queue);
+	} else
+		return -EINVAL;
 
 	switch (hdr->oid) {
 	case UMAC_WIFI_IF_CMD_SET_PROFILE:
 		iwm->umac_profile_active = 1;
-		wake_up_interruptible(&iwm->mlme_queue);
 		break;
 	default:
 		break;
@@ -1010,6 +1081,7 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
 static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
 			      unsigned long buf_size, struct iwm_wifi_cmd *cmd)
 {
+	struct wiphy *wiphy = iwm_to_wiphy(iwm);
 	struct iwm_lmac_card_state *state = (struct iwm_lmac_card_state *)
 				(buf + sizeof(struct iwm_umac_wifi_in_hdr));
 	u32 flags = le32_to_cpu(state->flags);
@@ -1018,10 +1090,7 @@ static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
 		 flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF",
 		 flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF");
 
-	if (flags & IWM_CARD_STATE_HW_DISABLED)
-		set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
-	else
-		clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+	wiphy_rfkill_set_hw_state(wiphy, flags & IWM_CARD_STATE_HW_DISABLED);
 
 	return 0;
 }
@@ -1362,13 +1431,13 @@ static void iwm_rx_process_packet(struct iwm_priv *iwm,
 
 		skb->dev = iwm_to_ndev(iwm);
 		skb->protocol = eth_type_trans(skb, ndev);
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+		skb->ip_summed = CHECKSUM_NONE;
 		memset(skb->cb, 0, sizeof(skb->cb));
 
 		ndev->stats.rx_packets++;
 		ndev->stats.rx_bytes += skb->len;
 
-		if (netif_rx(skb) == NET_RX_DROP) {
+		if (netif_rx_ni(skb) == NET_RX_DROP) {
 			IWM_ERR(iwm, "Packet dropped\n");
 			ndev->stats.rx_dropped++;
 		}
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index 9166818..8b1de84 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -65,6 +65,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/debugfs.h>
+#include <linux/mmc/sdio_ids.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
 
@@ -492,7 +493,8 @@ static void iwm_sdio_remove(struct sdio_func *func)
 }
 
 static const struct sdio_device_id iwm_sdio_ids[] = {
-	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, SDIO_DEVICE_ID_IWM) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_INTEL,
+		      SDIO_DEVICE_ID_INTEL_IWMC3200WIFI) },
 	{ /* end: all zeroes */	},
 };
 MODULE_DEVICE_TABLE(sdio, iwm_sdio_ids);
@@ -506,11 +508,7 @@ static struct sdio_driver iwm_sdio_driver = {
 
 static int __init iwm_sdio_init_module(void)
 {
-	int ret;
-
-	ret = sdio_register_driver(&iwm_sdio_driver);
-
-	return ret;
+	return sdio_register_driver(&iwm_sdio_driver);
 }
 
 static void __exit iwm_sdio_exit_module(void)
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.h b/drivers/net/wireless/iwmc3200wifi/sdio.h
index b3c156b..aab6b68 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.h
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.h
@@ -39,9 +39,6 @@
 #ifndef __IWM_SDIO_H__
 #define __IWM_SDIO_H__
 
-#define SDIO_VENDOR_ID_INTEL 0x89
-#define SDIO_DEVICE_ID_IWM   0x1403
-
 #define IWM_SDIO_DATA_ADDR           0x0
 #define IWM_SDIO_INTR_ENABLE_ADDR    0x14
 #define IWM_SDIO_INTR_STATUS_ADDR    0x13
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h
index 4a95cce..c5a14ae 100644
--- a/drivers/net/wireless/iwmc3200wifi/umac.h
+++ b/drivers/net/wireless/iwmc3200wifi/umac.h
@@ -495,6 +495,8 @@ struct iwm_fw_alive_hdr {
 #define WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP		0xE8
 #define WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP	0xE9
 
+#define WIFI_IF_NTFY_MAX 0xff
+
 /* Notification structures */
 struct iwm_umac_notif_wifi_if {
 	struct iwm_umac_wifi_in_hdr hdr;
@@ -613,6 +615,7 @@ struct iwm_umac_notif_alive {
 } __attribute__ ((packed));
 
 struct iwm_umac_notif_init_complete {
+	struct iwm_umac_wifi_in_hdr hdr;
 	__le16 status;
 	__le16 reserved;
 } __attribute__ ((packed));
@@ -641,6 +644,11 @@ struct iwm_fw_error_hdr {
 	__le32 umac_status;
 	__le32 lmac_status;
 	__le32 sdio_status;
+	__le32 dbm_sample_ctrl;
+	__le32 dbm_buf_base;
+	__le32 dbm_buf_end;
+	__le32 dbm_buf_write_ptr;
+	__le32 dbm_buf_cycle_cnt;
 } __attribute__ ((packed));
 
 struct iwm_umac_notif_error {
diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c
deleted file mode 100644
index 584c94d..0000000
--- a/drivers/net/wireless/iwmc3200wifi/wext.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Intel Wireless Multicomm 3200 WiFi driver
- *
- * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
- * Samuel Ortiz <samuel.ortiz@intel.com>
- * Zhu Yi <yi.zhu@intel.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 Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <net/cfg80211.h>
-#include <net/iw_handler.h>
-
-#include "iwm.h"
-#include "umac.h"
-#include "commands.h"
-#include "debug.h"
-
-static struct iw_statistics *iwm_get_wireless_stats(struct net_device *dev)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	struct iw_statistics *wstats = &iwm->wstats;
-
-	if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
-		memset(wstats, 0, sizeof(struct iw_statistics));
-		wstats->qual.updated = IW_QUAL_ALL_INVALID;
-	}
-
-	return wstats;
-}
-
-static int iwm_wext_siwfreq(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_freq *freq, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	if (freq->flags == IW_FREQ_AUTO)
-		return 0;
-
-	/* frequency/channel can only be set in IBSS mode */
-	if (iwm->conf.mode != UMAC_MODE_IBSS)
-		return -EOPNOTSUPP;
-
-	return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
-}
-
-static int iwm_wext_giwfreq(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_freq *freq, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	if (iwm->conf.mode == UMAC_MODE_IBSS)
-		return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
-
-	freq->e = 0;
-	freq->m = iwm->channel;
-
-	return 0;
-}
-
-static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info,
-			  struct sockaddr *ap_addr, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	if (iwm->conf.mode == UMAC_MODE_IBSS)
-		return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
-
-	if (!test_bit(IWM_STATUS_READY, &iwm->status))
-		return -EIO;
-
-	if (is_zero_ether_addr(ap_addr->sa_data) ||
-	    is_broadcast_ether_addr(ap_addr->sa_data)) {
-		IWM_DBG_WEXT(iwm, DBG, "clear mandatory bssid %pM\n",
-			     iwm->umac_profile->bssid[0]);
-		memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
-		iwm->umac_profile->bss_num = 0;
-	} else {
-		IWM_DBG_WEXT(iwm, DBG, "add mandatory bssid %pM\n",
-			     ap_addr->sa_data);
-		memcpy(&iwm->umac_profile->bssid[0], ap_addr->sa_data,
-		       ETH_ALEN);
-		iwm->umac_profile->bss_num = 1;
-	}
-
-	if (iwm->umac_profile_active) {
-		if (!memcmp(&iwm->umac_profile->bssid[0], iwm->bssid, ETH_ALEN))
-			return 0;
-
-		iwm_invalidate_mlme_profile(iwm);
-	}
-
-	if (iwm->umac_profile->ssid.ssid_len)
-		return iwm_send_mlme_profile(iwm);
-
-	return 0;
-}
-
-static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info,
-			  struct sockaddr *ap_addr, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	switch (iwm->conf.mode) {
-	case UMAC_MODE_IBSS:
-		return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
-	case UMAC_MODE_BSS:
-		if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
-			ap_addr->sa_family = ARPHRD_ETHER;
-			memcpy(&ap_addr->sa_data, iwm->bssid, ETH_ALEN);
-		} else
-			memset(&ap_addr->sa_data, 0, ETH_ALEN);
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-static int iwm_wext_siwessid(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct iw_point *data, char *ssid)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	size_t len = data->length;
-	int ret;
-
-	if (iwm->conf.mode == UMAC_MODE_IBSS)
-		return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
-
-	if (!test_bit(IWM_STATUS_READY, &iwm->status))
-		return -EIO;
-
-	if (len > 0 && ssid[len - 1] == '\0')
-		len--;
-
-	if (iwm->umac_profile_active) {
-		if (iwm->umac_profile->ssid.ssid_len == len &&
-		    !memcmp(iwm->umac_profile->ssid.ssid, ssid, len))
-			return 0;
-
-		ret = iwm_invalidate_mlme_profile(iwm);
-		if (ret < 0) {
-			IWM_ERR(iwm, "Couldn't invalidate profile\n");
-			return ret;
-		}
-	}
-
-	iwm->umac_profile->ssid.ssid_len = len;
-	memcpy(iwm->umac_profile->ssid.ssid, ssid, len);
-
-	return iwm_send_mlme_profile(iwm);
-}
-
-static int iwm_wext_giwessid(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct iw_point *data, char *ssid)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	if (iwm->conf.mode == UMAC_MODE_IBSS)
-		return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
-
-	if (!test_bit(IWM_STATUS_READY, &iwm->status))
-		return -EIO;
-
-	data->length = iwm->umac_profile->ssid.ssid_len;
-	if (data->length) {
-		memcpy(ssid, iwm->umac_profile->ssid.ssid, data->length);
-		data->flags = 1;
-	} else
-		data->flags = 0;
-
-	return 0;
-}
-
-static struct iwm_key *
-iwm_key_init(struct iwm_priv *iwm, u8 key_idx, bool in_use,
-	     struct iw_encode_ext *ext, u8 alg)
-{
-	struct iwm_key *key = &iwm->keys[key_idx];
-
-	memset(key, 0, sizeof(struct iwm_key));
-	memcpy(key->hdr.mac, ext->addr.sa_data, ETH_ALEN);
-	key->hdr.key_idx = key_idx;
-	if (is_broadcast_ether_addr(ext->addr.sa_data))
-		key->hdr.multicast = 1;
-
-	key->in_use = in_use;
-	key->flags = ext->ext_flags;
-	key->alg = alg;
-	key->key_len = ext->key_len;
-	memcpy(key->key, ext->key, ext->key_len);
-
-	return key;
-}
-
-static int iwm_wext_giwrate(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_param *rate, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	rate->value = iwm->rate * 1000000;
-
-	return 0;
-}
-
-static int iwm_wext_siwencode(struct net_device *dev,
-			      struct iw_request_info *info,
-			      struct iw_point *erq, char *key_buf)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	struct iwm_key *uninitialized_var(key);
-	int idx, i, uninitialized_var(alg), remove = 0, ret;
-
-	IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", erq->length);
-	IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags);
-
-	if (!iwm->umac_profile) {
-		IWM_ERR(iwm, "UMAC profile not allocated yet\n");
-		return -ENODEV;
-	}
-
-	if (erq->length == WLAN_KEY_LEN_WEP40) {
-		alg = UMAC_CIPHER_TYPE_WEP_40;
-		iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_40;
-		iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_40;
-	} else if (erq->length == WLAN_KEY_LEN_WEP104) {
-		alg = UMAC_CIPHER_TYPE_WEP_104;
-		iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_104;
-		iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_104;
-	}
-
-	if (erq->flags & IW_ENCODE_RESTRICTED)
-		iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
-	else
-		iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN;
-
-	idx = erq->flags & IW_ENCODE_INDEX;
-	if (idx == 0) {
-		if (iwm->default_key)
-			for (i = 0; i < IWM_NUM_KEYS; i++) {
-				if (iwm->default_key == &iwm->keys[i]) {
-					idx = i;
-					break;
-				}
-			}
-		else
-			iwm->default_key = &iwm->keys[idx];
-	} else if (idx < 1 || idx > 4) {
-		return -EINVAL;
-	} else
-		idx--;
-
-	if (erq->flags & IW_ENCODE_DISABLED)
-		remove = 1;
-	else if (erq->length == 0) {
-		if (!iwm->keys[idx].in_use)
-			return -EINVAL;
-		iwm->default_key = &iwm->keys[idx];
-	}
-
-	if (erq->length) {
-		key = &iwm->keys[idx];
-		memset(key, 0, sizeof(struct iwm_key));
-		memset(key->hdr.mac, 0xff, ETH_ALEN);
-		key->hdr.key_idx = idx;
-		key->hdr.multicast = 1;
-		key->in_use = !remove;
-		key->alg = alg;
-		key->key_len = erq->length;
-		memcpy(key->key, key_buf, erq->length);
-
-		IWM_DBG_WEXT(iwm, DBG, "Setting key %d, default: %d\n",
-			     idx, !!iwm->default_key);
-	}
-
-	if (remove) {
-		if ((erq->flags & IW_ENCODE_NOKEY) || (erq->length == 0)) {
-			int j;
-			for (j = 0; j < IWM_NUM_KEYS; j++)
-				if (iwm->keys[j].in_use) {
-					struct iwm_key *k = &iwm->keys[j];
-
-					k->in_use = 0;
-					ret = iwm_set_key(iwm, remove, 0, k);
-					if (ret < 0)
-						return ret;
-				}
-
-			iwm->umac_profile->sec.ucast_cipher =
-							UMAC_CIPHER_TYPE_NONE;
-			iwm->umac_profile->sec.mcast_cipher =
-							UMAC_CIPHER_TYPE_NONE;
-			iwm->umac_profile->sec.auth_type =
-							UMAC_AUTH_TYPE_OPEN;
-
-			return 0;
-		} else {
-			key->in_use = 0;
-			return iwm_set_key(iwm, remove, 0, key);
-		}
-	}
-
-	/*
-	 * If we havent set a profile yet, we cant set keys.
-	 * Keys will be pushed after we're associated.
-	 */
-	if (!iwm->umac_profile_active)
-		return 0;
-
-	/*
-	 * If there is a current active profile, but no
-	 * default key, it's not worth trying to associate again.
-	 */
-	if (!iwm->default_key)
-		return 0;
-
-	/*
-	 * Here we have an active profile, but a key setting changed.
-	 * We thus have to invalidate the current profile, and push the
-	 * new one. Keys will be pushed when association takes place.
-	 */
-	ret = iwm_invalidate_mlme_profile(iwm);
-	if (ret < 0) {
-		IWM_ERR(iwm, "Couldn't invalidate profile\n");
-		return ret;
-	}
-
-	return iwm_send_mlme_profile(iwm);
-}
-
-static int iwm_wext_giwencode(struct net_device *dev,
-			      struct iw_request_info *info,
-			      struct iw_point *erq, char *key)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	int idx, i;
-
-	idx = erq->flags & IW_ENCODE_INDEX;
-	if (idx < 1 || idx > 4) {
-		idx = -1;
-		if (!iwm->default_key) {
-			erq->length = 0;
-			erq->flags |= IW_ENCODE_NOKEY;
-			return 0;
-		} else
-			for (i = 0; i < IWM_NUM_KEYS; i++) {
-				if (iwm->default_key == &iwm->keys[i]) {
-					idx = i;
-					break;
-				}
-			}
-		if (idx < 0)
-			return -EINVAL;
-	} else
-		idx--;
-
-	erq->flags = idx + 1;
-
-	if (!iwm->keys[idx].in_use) {
-		erq->length = 0;
-		erq->flags |= IW_ENCODE_DISABLED;
-		return 0;
-	}
-
-	memcpy(key, iwm->keys[idx].key,
-	       min_t(int, erq->length, iwm->keys[idx].key_len));
-	erq->length = iwm->keys[idx].key_len;
-	erq->flags |= IW_ENCODE_ENABLED;
-
-	if (iwm->umac_profile->mode == UMAC_MODE_BSS) {
-		switch (iwm->umac_profile->sec.auth_type) {
-		case UMAC_AUTH_TYPE_OPEN:
-			erq->flags |= IW_ENCODE_OPEN;
-			break;
-		default:
-			erq->flags |= IW_ENCODE_RESTRICTED;
-			break;
-		}
-	}
-
-	return 0;
-}
-
-static int iwm_set_wpa_version(struct iwm_priv *iwm, u8 wpa_version)
-{
-	if (wpa_version & IW_AUTH_WPA_VERSION_WPA2)
-		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
-	else if (wpa_version & IW_AUTH_WPA_VERSION_WPA)
-		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
-	else
-		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
-
-	return 0;
-}
-
-static int iwm_wext_siwpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct iw_param *wrq, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	u32 power_index;
-
-	if (wrq->disabled) {
-		power_index = IWM_POWER_INDEX_MIN;
-		goto set;
-	} else
-		power_index = IWM_POWER_INDEX_DEFAULT;
-
-	switch (wrq->flags & IW_POWER_MODE) {
-	case IW_POWER_ON:
-	case IW_POWER_MODE:
-	case IW_POWER_ALL_R:
-		break;
-	default:
-		return -EINVAL;
-	}
-
- set:
-	if (power_index == iwm->conf.power_index)
-		return 0;
-
-	iwm->conf.power_index = power_index;
-
-	return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
-				       CFG_POWER_INDEX, iwm->conf.power_index);
-}
-
-static int iwm_wext_giwpower(struct net_device *dev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-
-	wrqu->power.disabled = (iwm->conf.power_index == IWM_POWER_INDEX_MIN);
-
-	return 0;
-}
-
-static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt)
-{
-	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
-
-	if (key_mgt == IW_AUTH_KEY_MGMT_802_1X)
-		*auth_type = UMAC_AUTH_TYPE_8021X;
-	else if (key_mgt == IW_AUTH_KEY_MGMT_PSK) {
-		if (iwm->umac_profile->sec.flags &
-		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
-			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
-		else
-			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
-	} else {
-		IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int iwm_set_cipher(struct iwm_priv *iwm, u8 cipher, u8 ucast)
-{
-	u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
-		&iwm->umac_profile->sec.mcast_cipher;
-
-	switch (cipher) {
-	case IW_AUTH_CIPHER_NONE:
-		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
-		break;
-	case IW_AUTH_CIPHER_WEP40:
-		*profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
-		break;
-	case IW_AUTH_CIPHER_TKIP:
-		*profile_cipher = UMAC_CIPHER_TYPE_TKIP;
-		break;
-	case IW_AUTH_CIPHER_CCMP:
-		*profile_cipher = UMAC_CIPHER_TYPE_CCMP;
-		break;
-	case IW_AUTH_CIPHER_WEP104:
-		*profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
-		break;
-	default:
-		IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
-		return -ENOTSUPP;
-	}
-
-	return 0;
-}
-
-static int iwm_set_auth_alg(struct iwm_priv *iwm, u8 auth_alg)
-{
-	u8 *auth_type = &iwm->umac_profile->sec.auth_type;
-
-	switch (auth_alg) {
-	case IW_AUTH_ALG_OPEN_SYSTEM:
-		*auth_type = UMAC_AUTH_TYPE_OPEN;
-		break;
-	case IW_AUTH_ALG_SHARED_KEY:
-		if (iwm->umac_profile->sec.flags &
-		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
-			if (*auth_type == UMAC_AUTH_TYPE_8021X)
-				return -EINVAL;
-			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
-		} else {
-			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
-		}
-		break;
-	case IW_AUTH_ALG_LEAP:
-	default:
-		IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", auth_alg);
-		return -ENOTSUPP;
-	}
-
-	return 0;
-}
-
-static int iwm_wext_siwauth(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_param *data, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	int ret;
-
-	if ((data->flags) &
-	    (IW_AUTH_WPA_VERSION | IW_AUTH_KEY_MGMT |
-	     IW_AUTH_WPA_ENABLED | IW_AUTH_80211_AUTH_ALG)) {
-		/* We need to invalidate the current profile */
-		if (iwm->umac_profile_active) {
-			ret = iwm_invalidate_mlme_profile(iwm);
-			if (ret < 0) {
-				IWM_ERR(iwm, "Couldn't invalidate profile\n");
-				return ret;
-			}
-		}
-	}
-
-	switch (data->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-		return iwm_set_wpa_version(iwm, data->value);
-		break;
-	case IW_AUTH_CIPHER_PAIRWISE:
-		return iwm_set_cipher(iwm, data->value, 1);
-		break;
-	case IW_AUTH_CIPHER_GROUP:
-		return iwm_set_cipher(iwm, data->value, 0);
-		break;
-	case IW_AUTH_KEY_MGMT:
-		return iwm_set_key_mgt(iwm, data->value);
-		break;
-	case IW_AUTH_80211_AUTH_ALG:
-		return iwm_set_auth_alg(iwm, data->value);
-		break;
-	default:
-		return -ENOTSUPP;
-	}
-
-	return 0;
-}
-
-static int iwm_wext_giwauth(struct net_device *dev,
-			    struct iw_request_info *info,
-			    struct iw_param *data, char *extra)
-{
-	return 0;
-}
-
-static int iwm_wext_siwencodeext(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *erq, char *extra)
-{
-	struct iwm_priv *iwm = ndev_to_iwm(dev);
-	struct iwm_key *key;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
-	int uninitialized_var(alg), idx, i, remove = 0;
-
-	IWM_DBG_WEXT(iwm, DBG, "alg: 0x%x\n", ext->alg);
-	IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", ext->key_len);
-	IWM_DBG_WEXT(iwm, DBG, "ext_flags: 0x%x\n", ext->ext_flags);
-	IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags);
-	IWM_DBG_WEXT(iwm, DBG, "length: 0x%x\n", erq->length);
-
-	switch (ext->alg) {
-	case IW_ENCODE_ALG_NONE:
-		remove = 1;
-		break;
-	case IW_ENCODE_ALG_WEP:
-		if (ext->key_len == WLAN_KEY_LEN_WEP40)
-			alg = UMAC_CIPHER_TYPE_WEP_40;
-		else if (ext->key_len == WLAN_KEY_LEN_WEP104)
-			alg = UMAC_CIPHER_TYPE_WEP_104;
-		else {
-			IWM_ERR(iwm, "Invalid key length: %d\n", ext->key_len);
-			return -EINVAL;
-		}
-
-		break;
-	case IW_ENCODE_ALG_TKIP:
-		alg = UMAC_CIPHER_TYPE_TKIP;
-		break;
-	case IW_ENCODE_ALG_CCMP:
-		alg = UMAC_CIPHER_TYPE_CCMP;
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	idx = erq->flags & IW_ENCODE_INDEX;
-
-	if (idx == 0) {
-		if (iwm->default_key)
-			for (i = 0; i < IWM_NUM_KEYS; i++) {
-				if (iwm->default_key == &iwm->keys[i]) {
-					idx = i;
-					break;
-				}
-			}
-	} else if (idx < 1 || idx > 4) {
-		return -EINVAL;
-	} else
-		idx--;
-
-	if (erq->flags & IW_ENCODE_DISABLED)
-		remove = 1;
-	else if ((erq->length == 0) ||
-		 (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
-		iwm->default_key = &iwm->keys[idx];
-		if (iwm->umac_profile_active && ext->alg == IW_ENCODE_ALG_WEP)
-			return iwm_set_tx_key(iwm, idx);
-	}
-
-	key = iwm_key_init(iwm, idx, !remove, ext, alg);
-
-	return iwm_set_key(iwm, remove, !iwm->default_key, key);
-}
-
-static const iw_handler iwm_handlers[] =
-{
-	(iw_handler) NULL,				/* SIOCSIWCOMMIT */
-	(iw_handler) cfg80211_wext_giwname,		/* SIOCGIWNAME */
-	(iw_handler) NULL,				/* SIOCSIWNWID */
-	(iw_handler) NULL,				/* SIOCGIWNWID */
-	(iw_handler) iwm_wext_siwfreq,			/* SIOCSIWFREQ */
-	(iw_handler) iwm_wext_giwfreq,			/* SIOCGIWFREQ */
-	(iw_handler) cfg80211_wext_siwmode,		/* SIOCSIWMODE */
-	(iw_handler) cfg80211_wext_giwmode,		/* SIOCGIWMODE */
-	(iw_handler) NULL,				/* SIOCSIWSENS */
-	(iw_handler) NULL,				/* SIOCGIWSENS */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE */
-	(iw_handler) cfg80211_wext_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) NULL,				/* SIOCSIWSPY */
-	(iw_handler) NULL,				/* SIOCGIWSPY */
-	(iw_handler) NULL,				/* SIOCSIWTHRSPY */
-	(iw_handler) NULL,				/* SIOCGIWTHRSPY */
-	(iw_handler) iwm_wext_siwap,	                /* SIOCSIWAP */
-	(iw_handler) iwm_wext_giwap,			/* SIOCGIWAP */
-	(iw_handler) NULL,			        /* SIOCSIWMLME */
-	(iw_handler) NULL,				/* SIOCGIWAPLIST */
-	(iw_handler) cfg80211_wext_siwscan,		/* SIOCSIWSCAN */
-	(iw_handler) cfg80211_wext_giwscan,		/* SIOCGIWSCAN */
-	(iw_handler) iwm_wext_siwessid,			/* SIOCSIWESSID */
-	(iw_handler) iwm_wext_giwessid,			/* SIOCGIWESSID */
-	(iw_handler) NULL,				/* SIOCSIWNICKN */
-	(iw_handler) NULL,				/* SIOCGIWNICKN */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* SIOCSIWRATE */
-	(iw_handler) iwm_wext_giwrate,			/* SIOCGIWRATE */
-	(iw_handler) cfg80211_wext_siwrts,		/* SIOCSIWRTS */
-	(iw_handler) cfg80211_wext_giwrts,		/* SIOCGIWRTS */
-	(iw_handler) cfg80211_wext_siwfrag,	        /* SIOCSIWFRAG */
-	(iw_handler) cfg80211_wext_giwfrag,		/* SIOCGIWFRAG */
-	(iw_handler) NULL,				/* SIOCSIWTXPOW */
-	(iw_handler) NULL,				/* SIOCGIWTXPOW */
-	(iw_handler) NULL,				/* SIOCSIWRETRY */
-	(iw_handler) NULL,				/* SIOCGIWRETRY */
-	(iw_handler) iwm_wext_siwencode,		/* SIOCSIWENCODE */
-	(iw_handler) iwm_wext_giwencode,		/* SIOCGIWENCODE */
-	(iw_handler) iwm_wext_siwpower,			/* SIOCSIWPOWER */
-	(iw_handler) iwm_wext_giwpower,			/* SIOCGIWPOWER */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,                              /* SIOCSIWGENIE */
-	(iw_handler) NULL,				/* SIOCGIWGENIE */
-	(iw_handler) iwm_wext_siwauth,			/* SIOCSIWAUTH */
-	(iw_handler) iwm_wext_giwauth,			/* SIOCGIWAUTH */
-	(iw_handler) iwm_wext_siwencodeext,	        /* SIOCSIWENCODEEXT */
-	(iw_handler) NULL,				/* SIOCGIWENCODEEXT */
-	(iw_handler) NULL,				/* SIOCSIWPMKSA */
-	(iw_handler) NULL,				/* -- hole -- */
-};
-
-const struct iw_handler_def iwm_iw_handler_def = {
-	.num_standard	= ARRAY_SIZE(iwm_handlers),
-	.standard	= (iw_handler *) iwm_handlers,
-	.get_wireless_stats = iwm_get_wireless_stats,
-};
-
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index b9b3741..dd87326 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -34,7 +34,8 @@ static const u8 bssid_off[ETH_ALEN]  __attribute__ ((aligned (2))) =
  *
  *  @param priv     A pointer to struct lbs_private structure
  *  @param rates       the buffer which keeps input and output
- *  @param rates_size  the size of rate1 buffer; new size of buffer on return
+ *  @param rates_size  the size of rates buffer; new size of buffer on return,
+ *                     which will be less than or equal to original rates_size
  *
  *  @return            0 on success, or -1 on error
  */
@@ -42,42 +43,42 @@ static int get_common_rates(struct lbs_private *priv,
 	u8 *rates,
 	u16 *rates_size)
 {
-	u8 *card_rates = lbs_bg_rates;
-	size_t num_card_rates = sizeof(lbs_bg_rates);
-	int ret = 0, i, j;
-	u8 tmp[30];
-	size_t tmp_size = 0;
-
-	/* For each rate in card_rates that exists in rate1, copy to tmp */
-	for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
-		for (j = 0; rates[j] && (j < *rates_size); j++) {
-			if (rates[j] == card_rates[i])
-				tmp[tmp_size++] = card_rates[i];
+	int i, j;
+	u8 intersection[MAX_RATES];
+	u16 intersection_size;
+	u16 num_rates = 0;
+
+	intersection_size = min_t(u16, *rates_size, ARRAY_SIZE(intersection));
+
+	/* Allow each rate from 'rates' that is supported by the hardware */
+	for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && lbs_bg_rates[i]; i++) {
+		for (j = 0; j < intersection_size && rates[j]; j++) {
+			if (rates[j] == lbs_bg_rates[i])
+				intersection[num_rates++] = rates[j];
 		}
 	}
 
 	lbs_deb_hex(LBS_DEB_JOIN, "AP rates    ", rates, *rates_size);
-	lbs_deb_hex(LBS_DEB_JOIN, "card rates  ", card_rates, num_card_rates);
-	lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
+	lbs_deb_hex(LBS_DEB_JOIN, "card rates  ", lbs_bg_rates,
+			ARRAY_SIZE(lbs_bg_rates));
+	lbs_deb_hex(LBS_DEB_JOIN, "common rates", intersection, num_rates);
 	lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
 
 	if (!priv->enablehwauto) {
-		for (i = 0; i < tmp_size; i++) {
-			if (tmp[i] == priv->cur_rate)
+		for (i = 0; i < num_rates; i++) {
+			if (intersection[i] == priv->cur_rate)
 				goto done;
 		}
 		lbs_pr_alert("Previously set fixed data rate %#x isn't "
 		       "compatible with the network.\n", priv->cur_rate);
-		ret = -1;
-		goto done;
+		return -1;
 	}
-	ret = 0;
 
 done:
 	memset(rates, 0, *rates_size);
-	*rates_size = min_t(int, tmp_size, *rates_size);
-	memcpy(rates, tmp, *rates_size);
-	return ret;
+	*rates_size = num_rates;
+	memcpy(rates, intersection, num_rates);
+	return 0;
 }
 
 
@@ -129,7 +130,6 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth
 {
 	struct cmd_ds_802_11_authenticate cmd;
 	int ret = -1;
-	DECLARE_MAC_BUF(mac);
 
 	lbs_deb_enter(LBS_DEB_JOIN);
 
@@ -138,8 +138,7 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth
 
 	cmd.authtype = iw_auth_to_ieee_auth(auth);
 
-	lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
-		print_mac(mac, bssid), cmd.authtype);
+	lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", bssid, cmd.authtype);
 
 	ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
 
@@ -321,8 +320,8 @@ static int lbs_associate(struct lbs_private *priv,
 
 	rates = (struct mrvl_ie_rates_param_set *) pos;
 	rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
-	memcpy(&rates->rates, &bss->rates, MAX_RATES);
-	tmplen = MAX_RATES;
+	tmplen = min_t(u16, ARRAY_SIZE(bss->rates), MAX_RATES);
+	memcpy(&rates->rates, &bss->rates, tmplen);
 	if (get_common_rates(priv, rates->rates, &tmplen)) {
 		ret = -1;
 		goto done;
@@ -342,8 +341,6 @@ static int lbs_associate(struct lbs_private *priv,
 
 	/* Firmware v9+ indicate authentication suites as a TLV */
 	if (priv->fwrelease >= 0x09000000) {
-		DECLARE_MAC_BUF(mac);
-
 		auth = (struct mrvl_ie_auth_type *) pos;
 		auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
 		auth->header.len = cpu_to_le16(2);
@@ -351,8 +348,8 @@ static int lbs_associate(struct lbs_private *priv,
 		auth->auth = cpu_to_le16(tmpauth);
 		pos += sizeof(auth->header) + 2;
 
-		lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
-			print_mac(mac, bss->bssid), priv->secinfo.auth_mode);
+		lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
+			bss->bssid, priv->secinfo.auth_mode);
 	}
 
 	/* WPA/WPA2 IEs */
@@ -598,7 +595,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
 
 	/* Copy Data rates from the rates recorded in scan response */
 	memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates));
-	ratesize = min_t(u16, sizeof(cmd.bss.rates), MAX_RATES);
+	ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), ARRAY_SIZE (bss->rates));
 	memcpy(cmd.bss.rates, bss->rates, ratesize);
 	if (get_common_rates(priv, cmd.bss.rates, &ratesize)) {
 		lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n");
@@ -1368,11 +1365,17 @@ static int assoc_helper_wpa_keys(struct lbs_private *priv,
 	if (ret)
 		goto out;
 
+	memcpy(&priv->wpa_unicast_key, &assoc_req->wpa_unicast_key,
+			sizeof(struct enc_key));
+
 	if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
 		clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
 
 		ret = lbs_cmd_802_11_key_material(priv, CMD_ACT_SET, assoc_req);
 		assoc_req->flags = flags;
+
+		memcpy(&priv->wpa_mcast_key, &assoc_req->wpa_mcast_key,
+				sizeof(struct enc_key));
 	}
 
 out:
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 811ffc3..893a55c 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -45,6 +45,8 @@ static ssize_t lbs_dev_info(struct file *file, char __user *userbuf,
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
 	ssize_t res;
+	if (!buf)
+		return -ENOMEM;
 
 	pos += snprintf(buf+pos, len-pos, "state = %s\n",
 				szStates[priv->connect_status]);
@@ -68,6 +70,8 @@ static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
 	char *buf = (char *)addr;
 	DECLARE_SSID_BUF(ssid);
 	struct bss_descriptor * iter_bss;
+	if (!buf)
+		return -ENOMEM;
 
 	pos += snprintf(buf+pos, len-pos,
 		"# | ch  | rssi |       bssid       |   cap    | Qual | SSID \n");
@@ -110,6 +114,8 @@ static ssize_t lbs_sleepparams_write(struct file *file,
 	int p1, p2, p3, p4, p5, p6;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, user_buf, buf_size)) {
@@ -148,6 +154,8 @@ static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf,
 	struct sleep_params sp;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	ret = lbs_cmd_802_11_sleep_params(priv, CMD_ACT_GET, &sp);
 	if (ret)
@@ -433,6 +441,8 @@ static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
 	int ret;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	offval.offset = priv->mac_offset;
 	offval.value = 0;
@@ -457,6 +467,8 @@ static ssize_t lbs_rdmac_write(struct file *file,
 	ssize_t res, buf_size;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
@@ -481,6 +493,8 @@ static ssize_t lbs_wrmac_write(struct file *file,
 	struct lbs_offset_value offval;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
@@ -515,6 +529,8 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
 	int ret;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	offval.offset = priv->bbp_offset;
 	offval.value = 0;
@@ -540,6 +556,8 @@ static ssize_t lbs_rdbbp_write(struct file *file,
 	ssize_t res, buf_size;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
@@ -564,6 +582,8 @@ static ssize_t lbs_wrbbp_write(struct file *file,
 	struct lbs_offset_value offval;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
@@ -598,6 +618,8 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
 	int ret;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	offval.offset = priv->rf_offset;
 	offval.value = 0;
@@ -623,6 +645,8 @@ static ssize_t lbs_rdrf_write(struct file *file,
 	ssize_t res, buf_size;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
@@ -647,6 +671,8 @@ static ssize_t lbs_wrrf_write(struct file *file,
 	struct lbs_offset_value offval;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
@@ -853,6 +879,8 @@ static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
 	struct debug_data *d;
 	unsigned long addr = get_zeroed_page(GFP_KERNEL);
 	char *buf = (char *)addr;
+	if (!buf)
+		return -ENOMEM;
 
 	p = buf;
 
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 0b84bdc..8b15380 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -6,7 +6,7 @@
 #ifndef _LBS_DECL_H_
 #define _LBS_DECL_H_
 
-#include <linux/device.h>
+#include <linux/netdevice.h>
 
 #include "defs.h"
 
@@ -41,7 +41,8 @@ u8 lbs_data_rate_to_fw_index(u32 rate);
 int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len);
 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
 			  int result);
-int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb,
+				struct net_device *dev);
 int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
 
 int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *);
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index f9ec69e..d3b69a4 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -14,7 +14,7 @@
 #include "defs.h"
 #include "hostcmd.h"
 
-extern struct ethtool_ops lbs_ethtool_ops;
+extern const struct ethtool_ops lbs_ethtool_ops;
 
 #define	MAX_BSSID_PER_CHANNEL		16
 
@@ -260,7 +260,6 @@ struct lbs_private {
 	u16 psmode;		/* Wlan802_11PowermodeCAM=disable
 				   Wlan802_11PowermodeMAX_PSP=enable */
 	u32 psstate;
-	char ps_supported;
 	u8 needtowakeup;
 
 	struct assoc_request * pending_assoc_req;
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index b118a35..039b555 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -183,7 +183,7 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
 	return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
 }
 
-struct ethtool_ops lbs_ethtool_ops = {
+const struct ethtool_ops lbs_ethtool_ops = {
 	.get_drvinfo = lbs_ethtool_get_drvinfo,
 	.get_eeprom =  lbs_ethtool_get_eeprom,
 	.get_eeprom_len = lbs_ethtool_get_eeprom_len,
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 2a5b083..6238176 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -59,6 +59,7 @@ struct if_cs_card {
 	struct pcmcia_device *p_dev;
 	struct lbs_private *priv;
 	void __iomem *iobase;
+	bool align_regs;
 };
 
 
@@ -274,16 +275,25 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
 #define IF_CS_PRODUCT_ID		0x0000001C
 #define IF_CS_CF8385_B1_REV		0x12
 #define IF_CS_CF8381_B3_REV		0x04
+#define IF_CS_CF8305_B1_REV		0x03
 
 /*
  * Used to detect other cards than CF8385 since their revisions of silicon
  * doesn't match those from CF8385, eg. CF8381 B3 works with this driver.
  */
+#define CF8305_MANFID		0x02db
+#define CF8305_CARDID		0x8103
 #define CF8381_MANFID		0x02db
 #define CF8381_CARDID		0x6064
 #define CF8385_MANFID		0x02df
 #define CF8385_CARDID		0x8103
 
+static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev)
+{
+	return (p_dev->manf_id == CF8305_MANFID &&
+		p_dev->card_id == CF8305_CARDID);
+}
+
 static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
 {
 	return (p_dev->manf_id == CF8381_MANFID &&
@@ -556,7 +566,15 @@ static int if_cs_prog_helper(struct if_cs_card *card)
 
 	lbs_deb_enter(LBS_DEB_CS);
 
-	scratch = if_cs_read8(card, IF_CS_SCRATCH);
+	/*
+	 * This is the only place where an unaligned register access happens on
+	 * the CF8305 card, therefore for the sake of speed of the driver, we do
+	 * the alignment correction here.
+	 */
+	if (card->align_regs)
+		scratch = if_cs_read16(card, IF_CS_SCRATCH) >> 8;
+	else
+		scratch = if_cs_read8(card, IF_CS_SCRATCH);
 
 	/* "If the value is 0x5a, the firmware is already
 	 * downloaded successfully"
@@ -880,8 +898,24 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
 	       p_dev->irq.AssignedIRQ, p_dev->io.BasePort1,
 	       p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
 
+	/*
+	 * Most of the libertas cards can do unaligned register access, but some
+	 * weird ones can not. That's especially true for the CF8305 card.
+	 */
+	card->align_regs = 0;
+
 	/* Check if we have a current silicon */
 	prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
+	if (if_cs_hw_is_cf8305(p_dev)) {
+		card->align_regs = 1;
+		if (prod_id < IF_CS_CF8305_B1_REV) {
+			lbs_pr_err("old chips like 8305 rev B3 "
+				"aren't supported\n");
+			ret = -ENODEV;
+			goto out2;
+		}
+	}
+
 	if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) {
 		lbs_pr_err("old chips like 8381 rev B3 aren't supported\n");
 		ret = -ENODEV;
@@ -896,7 +930,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
 
 	/* Load the firmware early, before calling into libertas.ko */
 	ret = if_cs_prog_helper(card);
-	if (ret == 0)
+	if (ret == 0 && !if_cs_hw_is_cf8305(p_dev))
 		ret = if_cs_prog_real(card);
 	if (ret)
 		goto out2;
@@ -933,9 +967,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
 		goto out3;
 	}
 
-	/* The firmware for the CF card supports powersave */
-	priv->ps_supported = 1;
-
 	ret = 0;
 	goto out;
 
@@ -979,6 +1010,7 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
 /********************************************************************/
 
 static struct pcmcia_device_id if_cs_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
 	PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
 	PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
 	PCMCIA_DEVICE_NULL,
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 8cdb88c..485a8d4 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -1039,9 +1039,6 @@ static int if_sdio_probe(struct sdio_func *func,
 	if (ret)
 		goto err_activate_card;
 
-	if (priv->fwcapinfo & FW_CAPINFO_PS)
-		priv->ps_supported = 1;
-
 out:
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 
@@ -1096,11 +1093,11 @@ static void if_sdio_remove(struct sdio_func *func)
 			lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
 	}
 
-	card->priv->surpriseremoved = 1;
 
 	lbs_deb_sdio("call remove card\n");
 	lbs_stop_card(card->priv);
 	lbs_remove_card(card->priv);
+	card->priv->surpriseremoved = 1;
 
 	flush_workqueue(card->workqueue);
 	destroy_workqueue(card->workqueue);
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 6564282..446e327 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -376,7 +376,7 @@ static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
 	err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval);
 	if (err)
 		return err;
-	if (rval != mode) {
+	if ((rval & 0xF) != mode) {
 		lbs_pr_err("Can't read bus mode register.\n");
 		return -EIO;
 	}
@@ -737,7 +737,7 @@ static int if_spi_c2h_data(struct if_spi_card *card)
 		goto out;
 	} else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
 		lbs_pr_err("%s: error: card has %d bytes of data, but "
-			   "our maximum skb size is %lu\n",
+			   "our maximum skb size is %zu\n",
 			   __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
 		err = -EINVAL;
 		goto out;
@@ -1118,7 +1118,6 @@ static int __devinit if_spi_probe(struct spi_device *spi)
 	priv->card = card;
 	priv->hw_host_to_card = if_spi_host_to_card;
 	priv->fw_ready = 1;
-	priv->ps_supported = 1;
 
 	/* Initialize interrupt handling stuff. */
 	card->run_thread = 1;
@@ -1171,12 +1170,13 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
 
 	lbs_deb_spi("libertas_spi_remove\n");
 	lbs_deb_enter(LBS_DEB_SPI);
-	priv->surpriseremoved = 1;
 
 	lbs_stop_card(priv);
+	lbs_remove_card(priv); /* will call free_netdev */
+
+	priv->surpriseremoved = 1;
 	free_irq(spi->irq, card);
 	if_spi_terminate_spi_thread(card);
-	lbs_remove_card(priv); /* will call free_netdev */
 	if (card->pdata->teardown)
 		card->pdata->teardown(spi);
 	free_if_spi_card(card);
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 1844c5a..92bc8c5 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -181,13 +181,14 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
 	wake_method.action = cpu_to_le16(CMD_ACT_GET);
 	if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
 		lbs_pr_info("Firmware does not seem to support PS mode\n");
+		priv->fwcapinfo &= ~FW_CAPINFO_PS;
 	} else {
 		if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
 			lbs_deb_usb("Firmware seems to support PS with wake-via-command\n");
-			priv->ps_supported = 1;
 		} else {
 			/* The versions which boot up this way don't seem to
 			   work even if we set it to the command interrupt */
+			priv->fwcapinfo &= ~FW_CAPINFO_PS;
 			lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
 		}
 	}
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 89575e4..87b4e49 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1176,7 +1176,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 	/* Allocate an Ethernet device and register it */
 	dev = alloc_etherdev(sizeof(struct lbs_private));
 	if (!dev) {
-		lbs_pr_err("init ethX device failed\n");
+		lbs_pr_err("init wlanX device failed\n");
 		goto done;
 	}
 	priv = netdev_priv(dev);
@@ -1204,6 +1204,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 	SET_NETDEV_DEV(dev, dmdev);
 
 	priv->rtap_net_dev = NULL;
+	strcpy(dev->name, "wlan%d");
 
 	lbs_deb_thread("Starting main thread...\n");
 	init_waitqueue_head(&priv->waitq);
@@ -1646,7 +1647,8 @@ static int lbs_rtap_stop(struct net_device *dev)
 	return 0;
 }
 
-static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lbs_rtap_hard_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	netif_stop_queue(dev);
 	return NETDEV_TX_BUSY;
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 160cfd8..4c018f7 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -57,19 +57,17 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
  *  @param skb     A pointer to skb which includes TX packet
  *  @return 	   0 or -1
  */
-int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	unsigned long flags;
 	struct lbs_private *priv = dev->ml_priv;
 	struct txpd *txpd;
 	char *p802x_hdr;
 	uint16_t pkt_len;
-	int ret;
+	netdev_tx_t ret = NETDEV_TX_OK;
 
 	lbs_deb_enter(LBS_DEB_TX);
 
-	ret = NETDEV_TX_OK;
-
 	/* We need to protect against the queues being restarted before
 	   we get round to stopping them */
 	spin_lock_irqsave(&priv->driver_lock, flags);
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 8bc1907..be837a0 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -712,7 +712,7 @@ static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
 
 	lbs_deb_enter(LBS_DEB_WEXT);
 
-	if (!priv->ps_supported) {
+	if (!(priv->fwcapinfo & FW_CAPINFO_PS)) {
 		if (vwrq->disabled)
 			return 0;
 		else
@@ -1728,6 +1728,8 @@ static int lbs_set_auth(struct net_device *dev,
 	}
 
 	switch (dwrq->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_PRIVACY_INVOKED:
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
 	case IW_AUTH_TKIP_COUNTERMEASURES:
 	case IW_AUTH_CIPHER_PAIRWISE:
 	case IW_AUTH_CIPHER_GROUP:
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 10a99e2..019431d 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -366,15 +366,35 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
 	return 0;
 }
 
+static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw,
+				     int mc_count, struct dev_addr_list *mclist)
+{
+	struct lbtf_private *priv = hw->priv;
+	int i;
+
+	if (!mc_count || mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE)
+		return mc_count;
+
+	priv->nr_of_multicastmacaddr = mc_count;
+	for (i = 0; i < mc_count; i++) {
+		if (!mclist)
+			break;
+		memcpy(&priv->multicastlist[i], mclist->da_addr,
+				ETH_ALEN);
+		mclist = mclist->next;
+	}
+
+	return mc_count;
+}
+
 #define SUPPORTED_FIF_FLAGS  (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)
 static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
 			unsigned int changed_flags,
 			unsigned int *new_flags,
-			int mc_count, struct dev_mc_list *mclist)
+			u64 multicast)
 {
 	struct lbtf_private *priv = hw->priv;
 	int old_mac_control = priv->mac_control;
-	int i;
 	changed_flags &= SUPPORTED_FIF_FLAGS;
 	*new_flags &= SUPPORTED_FIF_FLAGS;
 
@@ -386,20 +406,12 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
 	else
 		priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
 	if (*new_flags & (FIF_ALLMULTI) ||
-	    mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) {
+	    multicast > MRVDRV_MAX_MULTICAST_LIST_SIZE) {
 		priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
 		priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;
-	} else if (mc_count) {
+	} else if (multicast) {
 		priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
 		priv->mac_control &= ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
-		priv->nr_of_multicastmacaddr = mc_count;
-		for (i = 0; i < mc_count; i++) {
-			if (!mclist)
-				break;
-			memcpy(&priv->multicastlist[i], mclist->da_addr,
-					ETH_ALEN);
-			mclist = mclist->next;
-		}
 		lbtf_cmd_set_mac_multicast_addr(priv);
 	} else {
 		priv->mac_control &= ~(CMD_ACT_MAC_MULTICAST_ENABLE |
@@ -461,6 +473,7 @@ static const struct ieee80211_ops lbtf_ops = {
 	.add_interface		= lbtf_op_add_interface,
 	.remove_interface	= lbtf_op_remove_interface,
 	.config			= lbtf_op_config,
+	.prepare_multicast	= lbtf_op_prepare_multicast,
 	.configure_filter	= lbtf_op_configure_filter,
 	.bss_info_changed	= lbtf_op_bss_info_changed,
 };
@@ -503,7 +516,8 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
 		skb_reserve(skb, 2);
 	}
 
-	ieee80211_rx_irqsafe(priv->hw, skb, &stats);
+	memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
+	ieee80211_rx_irqsafe(priv->hw, skb);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lbtf_rx);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7916ca3..896f532 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -15,6 +15,8 @@
 
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <net/dst.h>
+#include <net/xfrm.h>
 #include <net/mac80211.h>
 #include <net/ieee80211_radiotap.h>
 #include <linux/if_arp.h>
@@ -310,11 +312,12 @@ struct hwsim_radiotap_hdr {
 } __attribute__ ((packed));
 
 
-static int hwsim_mon_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
 	/* TODO: allow packet injection */
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 
@@ -404,11 +407,19 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
 	rx_status.freq = data->channel->center_freq;
 	rx_status.band = data->channel->band;
 	rx_status.rate_idx = info->control.rates[0].idx;
-	/* TODO: simulate signal strength (and optional packet drop) */
+	/* TODO: simulate real signal strength (and optional packet loss) */
+	rx_status.signal = -50;
 
 	if (data->ps != PS_DISABLED)
 		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
 
+	/* release the skb's source info */
+	skb_orphan(skb);
+	skb_dst_drop(skb);
+	skb->mark = 0;
+	secpath_reset(skb);
+	nf_reset(skb);
+
 	/* Copy skb to all enabled radios that are on the current frequency */
 	spin_lock(&hwsim_radio_lock);
 	list_for_each_entry(data2, &hwsim_radios, list) {
@@ -430,7 +441,8 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
 		if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr,
 			   ETH_ALEN) == 0)
 			ack = true;
-		ieee80211_rx_irqsafe(data2->hw, nskb, &rx_status);
+		memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status));
+		ieee80211_rx_irqsafe(data2->hw, nskb);
 	}
 	spin_unlock(&hwsim_radio_lock);
 
@@ -571,9 +583,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
 
 static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
 					    unsigned int changed_flags,
-					    unsigned int *total_flags,
-					    int mc_count,
-					    struct dev_addr_list *mc_list)
+					    unsigned int *total_flags,u64 multicast)
 {
 	struct mac80211_hwsim_data *data = hw->priv;
 
@@ -690,6 +700,74 @@ static int mac80211_hwsim_conf_tx(
 	return 0;
 }
 
+#ifdef CONFIG_NL80211_TESTMODE
+/*
+ * This section contains example code for using netlink
+ * attributes with the testmode command in nl80211.
+ */
+
+/* These enums need to be kept in sync with userspace */
+enum hwsim_testmode_attr {
+	__HWSIM_TM_ATTR_INVALID	= 0,
+	HWSIM_TM_ATTR_CMD	= 1,
+	HWSIM_TM_ATTR_PS	= 2,
+
+	/* keep last */
+	__HWSIM_TM_ATTR_AFTER_LAST,
+	HWSIM_TM_ATTR_MAX	= __HWSIM_TM_ATTR_AFTER_LAST - 1
+};
+
+enum hwsim_testmode_cmd {
+	HWSIM_TM_CMD_SET_PS		= 0,
+	HWSIM_TM_CMD_GET_PS		= 1,
+};
+
+static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = {
+	[HWSIM_TM_ATTR_CMD] = { .type = NLA_U32 },
+	[HWSIM_TM_ATTR_PS] = { .type = NLA_U32 },
+};
+
+static int hwsim_fops_ps_write(void *dat, u64 val);
+
+static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
+				       void *data, int len)
+{
+	struct mac80211_hwsim_data *hwsim = hw->priv;
+	struct nlattr *tb[HWSIM_TM_ATTR_MAX + 1];
+	struct sk_buff *skb;
+	int err, ps;
+
+	err = nla_parse(tb, HWSIM_TM_ATTR_MAX, data, len,
+			hwsim_testmode_policy);
+	if (err)
+		return err;
+
+	if (!tb[HWSIM_TM_ATTR_CMD])
+		return -EINVAL;
+
+	switch (nla_get_u32(tb[HWSIM_TM_ATTR_CMD])) {
+	case HWSIM_TM_CMD_SET_PS:
+		if (!tb[HWSIM_TM_ATTR_PS])
+			return -EINVAL;
+		ps = nla_get_u32(tb[HWSIM_TM_ATTR_PS]);
+		return hwsim_fops_ps_write(hwsim, ps);
+	case HWSIM_TM_CMD_GET_PS:
+		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
+						nla_total_size(sizeof(u32)));
+		if (!skb)
+			return -ENOMEM;
+		NLA_PUT_U32(skb, HWSIM_TM_ATTR_PS, hwsim->ps);
+		return cfg80211_testmode_reply(skb);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+ nla_put_failure:
+	kfree_skb(skb);
+	return -ENOBUFS;
+}
+#endif
+
 static const struct ieee80211_ops mac80211_hwsim_ops =
 {
 	.tx = mac80211_hwsim_tx,
@@ -703,6 +781,7 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
 	.sta_notify = mac80211_hwsim_sta_notify,
 	.set_tim = mac80211_hwsim_set_tim,
 	.conf_tx = mac80211_hwsim_conf_tx,
+	CFG80211_TESTMODE_CMD(mac80211_hwsim_testmode_cmd)
 };
 
 
@@ -757,7 +836,6 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
 {
 	struct mac80211_hwsim_data *data = dat;
 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
-	DECLARE_MAC_BUF(buf);
 	struct sk_buff *skb;
 	struct ieee80211_pspoll *pspoll;
 
@@ -787,7 +865,6 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
 				struct ieee80211_vif *vif, int ps)
 {
 	struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
-	DECLARE_MAC_BUF(buf);
 	struct sk_buff *skb;
 	struct ieee80211_hdr *hdr;
 
@@ -945,7 +1022,8 @@ static int __init init_mac80211_hwsim(void)
 			BIT(NL80211_IFTYPE_AP) |
 			BIT(NL80211_IFTYPE_MESH_POINT);
 
-		hw->flags = IEEE80211_HW_MFP_CAPABLE;
+		hw->flags = IEEE80211_HW_MFP_CAPABLE |
+			    IEEE80211_HW_SIGNAL_DBM;
 
 		/* ask mac80211 to reserve space for magic */
 		hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 83967af..746532e 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1,7 +1,8 @@
 /*
- * drivers/net/wireless/mwl8k.c driver for Marvell TOPDOG 802.11 Wireless cards
+ * drivers/net/wireless/mwl8k.c
+ * Driver for Marvell TOPDOG 802.11 Wireless cards
  *
- * Copyright (C) 2008 Marvell Semiconductor Inc.
+ * Copyright (C) 2008-2009 Marvell Semiconductor Inc.
  *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without any
@@ -24,7 +25,7 @@
 
 #define MWL8K_DESC	"Marvell TOPDOG(R) 802.11 Wireless Network Driver"
 #define MWL8K_NAME	KBUILD_MODNAME
-#define MWL8K_VERSION	"0.9.1"
+#define MWL8K_VERSION	"0.10"
 
 MODULE_DESCRIPTION(MWL8K_DESC);
 MODULE_VERSION(MWL8K_VERSION);
@@ -38,16 +39,14 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_table) = {
 };
 MODULE_DEVICE_TABLE(pci, mwl8k_table);
 
-#define IEEE80211_ADDR_LEN			ETH_ALEN
-
 /* Register definitions */
 #define MWL8K_HIU_GEN_PTR			0x00000c10
-#define  MWL8K_MODE_STA				0x0000005a
-#define  MWL8K_MODE_AP				0x000000a5
+#define  MWL8K_MODE_STA				 0x0000005a
+#define  MWL8K_MODE_AP				 0x000000a5
 #define MWL8K_HIU_INT_CODE			0x00000c14
-#define  MWL8K_FWSTA_READY			0xf0f1f2f4
-#define  MWL8K_FWAP_READY			0xf1f2f4a5
-#define  MWL8K_INT_CODE_CMD_FINISHED		0x00000005
+#define  MWL8K_FWSTA_READY			 0xf0f1f2f4
+#define  MWL8K_FWAP_READY			 0xf1f2f4a5
+#define  MWL8K_INT_CODE_CMD_FINISHED		 0x00000005
 #define MWL8K_HIU_SCRATCH			0x00000c40
 
 /* Host->device communications */
@@ -56,11 +55,10 @@ MODULE_DEVICE_TABLE(pci, mwl8k_table);
 #define MWL8K_HIU_H2A_INTERRUPT_MASK		0x00000c20
 #define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL	0x00000c24
 #define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK	0x00000c28
-#define  MWL8K_H2A_INT_DUMMY			(1 << 20)
-#define  MWL8K_H2A_INT_RESET			(1 << 15)
-#define  MWL8K_H2A_INT_PS			(1 << 2)
-#define  MWL8K_H2A_INT_DOORBELL			(1 << 1)
-#define  MWL8K_H2A_INT_PPA_READY		(1 << 0)
+#define  MWL8K_H2A_INT_DUMMY			 (1 << 20)
+#define  MWL8K_H2A_INT_RESET			 (1 << 15)
+#define  MWL8K_H2A_INT_DOORBELL			 (1 << 1)
+#define  MWL8K_H2A_INT_PPA_READY		 (1 << 0)
 
 /* Device->host communications */
 #define MWL8K_HIU_A2H_INTERRUPT_EVENTS		0x00000c2c
@@ -68,16 +66,16 @@ MODULE_DEVICE_TABLE(pci, mwl8k_table);
 #define MWL8K_HIU_A2H_INTERRUPT_MASK		0x00000c34
 #define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL	0x00000c38
 #define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK	0x00000c3c
-#define  MWL8K_A2H_INT_DUMMY			(1 << 20)
-#define  MWL8K_A2H_INT_CHNL_SWITCHED		(1 << 11)
-#define  MWL8K_A2H_INT_QUEUE_EMPTY		(1 << 10)
-#define  MWL8K_A2H_INT_RADAR_DETECT		(1 << 7)
-#define  MWL8K_A2H_INT_RADIO_ON			(1 << 6)
-#define  MWL8K_A2H_INT_RADIO_OFF		(1 << 5)
-#define  MWL8K_A2H_INT_MAC_EVENT		(1 << 3)
-#define  MWL8K_A2H_INT_OPC_DONE			(1 << 2)
-#define  MWL8K_A2H_INT_RX_READY			(1 << 1)
-#define  MWL8K_A2H_INT_TX_DONE			(1 << 0)
+#define  MWL8K_A2H_INT_DUMMY			 (1 << 20)
+#define  MWL8K_A2H_INT_CHNL_SWITCHED		 (1 << 11)
+#define  MWL8K_A2H_INT_QUEUE_EMPTY		 (1 << 10)
+#define  MWL8K_A2H_INT_RADAR_DETECT		 (1 << 7)
+#define  MWL8K_A2H_INT_RADIO_ON			 (1 << 6)
+#define  MWL8K_A2H_INT_RADIO_OFF		 (1 << 5)
+#define  MWL8K_A2H_INT_MAC_EVENT		 (1 << 3)
+#define  MWL8K_A2H_INT_OPC_DONE			 (1 << 2)
+#define  MWL8K_A2H_INT_RX_READY			 (1 << 1)
+#define  MWL8K_A2H_INT_TX_DONE			 (1 << 0)
 
 #define MWL8K_A2H_EVENTS	(MWL8K_A2H_INT_DUMMY | \
 				 MWL8K_A2H_INT_CHNL_SWITCHED | \
@@ -113,17 +111,6 @@ struct mwl8k_rx_queue {
 	struct sk_buff **rx_skb;
 };
 
-struct mwl8k_skb {
-	/*
-	 * The DMA engine requires a modification to the payload.
-	 * If the skbuff is shared/cloned, it needs to be unshared.
-	 * This method is used to ensure the stack always gets back
-	 * the skbuff it sent for transmission.
-	 */
-	struct sk_buff *clone;
-	struct sk_buff *skb;
-};
-
 struct mwl8k_tx_queue {
 	/* hw transmits here */
 	int tx_head;
@@ -134,7 +121,7 @@ struct mwl8k_tx_queue {
 	struct ieee80211_tx_queue_stats tx_stats;
 	struct mwl8k_tx_desc *tx_desc_area;
 	dma_addr_t tx_desc_dma;
-	struct mwl8k_skb *tx_skb;
+	struct sk_buff **tx_skb;
 };
 
 /* Pointers to the firmware data and meta information about it.  */
@@ -152,19 +139,22 @@ struct mwl8k_priv {
 
 	struct pci_dev *pdev;
 	u8 name[16];
-	/* firmware access lock */
-	spinlock_t fw_lock;
 
 	/* firmware files and meta data */
 	struct mwl8k_firmware fw;
 	u32 part_num;
 
+	/* firmware access */
+	struct mutex fw_mutex;
+	struct task_struct *fw_mutex_owner;
+	int fw_mutex_depth;
+	struct completion *tx_wait;
+	struct completion *hostcmd_wait;
+
 	/* lock held over TX and TX reap */
 	spinlock_t tx_lock;
-	u32 int_mask;
 
 	struct ieee80211_vif *vif;
-	struct list_head vif_list;
 
 	struct ieee80211_channel *current_channel;
 
@@ -173,10 +163,8 @@ struct mwl8k_priv {
 	dma_addr_t cookie_dma;
 
 	u16 num_mcaddrs;
-	u16 region_code;
 	u8 hw_rev;
-	__le32 fw_rev;
-	u32 wep_enabled;
+	u32 fw_rev;
 
 	/*
 	 * Running count of TX packets in flight, to avoid
@@ -192,19 +180,13 @@ struct mwl8k_priv {
 	struct ieee80211_channel channels[14];
 	struct ieee80211_rate rates[12];
 
-	/* RF preamble: Short, Long or Auto */
-	u8	radio_preamble;
-	u8	radio_state;
-
-	/* WMM MODE 1 for enabled; 0 for disabled */
-	bool wmm_mode;
-
-	/* Set if PHY config is in progress */
-	bool inconfig;
+	bool radio_on;
+	bool radio_short_preamble;
+	bool wmm_enabled;
 
 	/* XXX need to convert this to handle multiple interfaces */
 	bool capture_beacon;
-	u8 capture_bssid[IEEE80211_ADDR_LEN];
+	u8 capture_bssid[ETH_ALEN];
 	struct sk_buff *beacon_skb;
 
 	/*
@@ -220,14 +202,10 @@ struct mwl8k_priv {
 
 	/* Work thread to serialize configuration requests */
 	struct workqueue_struct *config_wq;
-	struct completion *hostcmd_wait;
-	struct completion *tx_wait;
 };
 
 /* Per interface specific private data */
 struct mwl8k_vif {
-	struct list_head node;
-
 	/* backpointer to parent config block */
 	struct mwl8k_priv *priv;
 
@@ -235,8 +213,8 @@ struct mwl8k_vif {
 	struct ieee80211_bss_conf bss_info;
 
 	/* BSSID of AP or IBSS */
-	u8	bssid[IEEE80211_ADDR_LEN];
-	u8	mac_addr[IEEE80211_ADDR_LEN];
+	u8	bssid[ETH_ALEN];
+	u8	mac_addr[ETH_ALEN];
 
 	/*
 	 * Subset of supported legacy rates.
@@ -247,18 +225,11 @@ struct mwl8k_vif {
 	/* number of supported legacy rates */
 	u8	legacy_nrates;
 
-	/* Number of supported MCS rates. Work in progress */
-	u8	mcs_nrates;
-
 	 /* Index into station database.Returned by update_sta_db call */
 	u8	peer_id;
 
 	/* Non AMPDU sequence number assigned by driver */
 	u16	seqno;
-
-	/* Note:There is no channel info,
-	 * refer to the master channel info in priv
-	 */
 };
 
 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
@@ -292,28 +263,6 @@ static const struct ieee80211_rate mwl8k_rates[] = {
 	{ .bitrate = 540, .hw_value = 108, },
 };
 
-/* Radio settings */
-#define MWL8K_RADIO_FORCE		0x2
-#define MWL8K_RADIO_ENABLE		0x1
-#define MWL8K_RADIO_DISABLE		0x0
-#define MWL8K_RADIO_AUTO_PREAMBLE	0x0005
-#define MWL8K_RADIO_SHORT_PREAMBLE	0x0003
-#define MWL8K_RADIO_LONG_PREAMBLE	0x0001
-
-/* WMM */
-#define MWL8K_WMM_ENABLE		1
-#define MWL8K_WMM_DISABLE		0
-
-#define MWL8K_RADIO_DEFAULT_PREAMBLE	MWL8K_RADIO_LONG_PREAMBLE
-
-/* Slot time */
-
-/* Short Slot: 9us slot time */
-#define MWL8K_SHORT_SLOTTIME		1
-
-/* Long slot: 20us slot time */
-#define MWL8K_LONG_SLOTTIME		0
-
 /* Set or get info from Firmware */
 #define MWL8K_CMD_SET			0x0001
 #define MWL8K_CMD_GET			0x0000
@@ -323,25 +272,23 @@ static const struct ieee80211_rate mwl8k_rates[] = {
 #define MWL8K_CMD_GET_HW_SPEC		0x0003
 #define MWL8K_CMD_MAC_MULTICAST_ADR	0x0010
 #define MWL8K_CMD_GET_STAT		0x0014
-#define MWL8K_CMD_RADIO_CONTROL		0x001C
-#define MWL8K_CMD_RF_TX_POWER		0x001E
+#define MWL8K_CMD_RADIO_CONTROL		0x001c
+#define MWL8K_CMD_RF_TX_POWER		0x001e
 #define MWL8K_CMD_SET_PRE_SCAN		0x0107
 #define MWL8K_CMD_SET_POST_SCAN		0x0108
-#define MWL8K_CMD_SET_RF_CHANNEL	0x010A
+#define MWL8K_CMD_SET_RF_CHANNEL	0x010a
+#define MWL8K_CMD_SET_AID		0x010d
+#define MWL8K_CMD_SET_RATE		0x0110
+#define MWL8K_CMD_SET_FINALIZE_JOIN	0x0111
+#define MWL8K_CMD_RTS_THRESHOLD		0x0113
 #define MWL8K_CMD_SET_SLOT		0x0114
+#define MWL8K_CMD_SET_EDCA_PARAMS	0x0115
+#define MWL8K_CMD_SET_WMM_MODE		0x0123
 #define MWL8K_CMD_MIMO_CONFIG		0x0125
+#define MWL8K_CMD_USE_FIXED_RATE	0x0126
 #define MWL8K_CMD_ENABLE_SNIFFER	0x0150
-#define MWL8K_CMD_SET_WMM_MODE		0x0123
-#define MWL8K_CMD_SET_EDCA_PARAMS	0x0115
-#define MWL8K_CMD_SET_FINALIZE_JOIN	0x0111
-#define MWL8K_CMD_UPDATE_STADB		0x1123
 #define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
-#define MWL8K_CMD_SET_LINKADAPT_MODE	0x0129
-#define MWL8K_CMD_SET_AID		0x010d
-#define MWL8K_CMD_SET_RATE		0x0110
-#define MWL8K_CMD_USE_FIXED_RATE	0x0126
-#define MWL8K_CMD_RTS_THRESHOLD		0x0113
-#define MWL8K_CMD_ENCRYPTION		0x1122
+#define MWL8K_CMD_UPDATE_STADB		0x1123
 
 static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
 {
@@ -349,7 +296,7 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
 					snprintf(buf, bufsize, "%s", #x);\
 					return buf;\
 					} while (0)
-	switch (cmd & (~0x8000)) {
+	switch (cmd & ~0x8000) {
 		MWL8K_CMDNAME(CODE_DNLD);
 		MWL8K_CMDNAME(GET_HW_SPEC);
 		MWL8K_CMDNAME(MAC_MULTICAST_ADR);
@@ -359,20 +306,18 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
 		MWL8K_CMDNAME(SET_PRE_SCAN);
 		MWL8K_CMDNAME(SET_POST_SCAN);
 		MWL8K_CMDNAME(SET_RF_CHANNEL);
+		MWL8K_CMDNAME(SET_AID);
+		MWL8K_CMDNAME(SET_RATE);
+		MWL8K_CMDNAME(SET_FINALIZE_JOIN);
+		MWL8K_CMDNAME(RTS_THRESHOLD);
 		MWL8K_CMDNAME(SET_SLOT);
+		MWL8K_CMDNAME(SET_EDCA_PARAMS);
+		MWL8K_CMDNAME(SET_WMM_MODE);
 		MWL8K_CMDNAME(MIMO_CONFIG);
+		MWL8K_CMDNAME(USE_FIXED_RATE);
 		MWL8K_CMDNAME(ENABLE_SNIFFER);
-		MWL8K_CMDNAME(SET_WMM_MODE);
-		MWL8K_CMDNAME(SET_EDCA_PARAMS);
-		MWL8K_CMDNAME(SET_FINALIZE_JOIN);
-		MWL8K_CMDNAME(UPDATE_STADB);
 		MWL8K_CMDNAME(SET_RATEADAPT_MODE);
-		MWL8K_CMDNAME(SET_LINKADAPT_MODE);
-		MWL8K_CMDNAME(SET_AID);
-		MWL8K_CMDNAME(SET_RATE);
-		MWL8K_CMDNAME(USE_FIXED_RATE);
-		MWL8K_CMDNAME(RTS_THRESHOLD);
-		MWL8K_CMDNAME(ENCRYPTION);
+		MWL8K_CMDNAME(UPDATE_STADB);
 	default:
 		snprintf(buf, bufsize, "0x%x", cmd);
 	}
@@ -466,7 +411,6 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
 {
 	void __iomem *regs = priv->regs;
 	dma_addr_t dma_addr;
-	int rc;
 	int loops;
 
 	dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
@@ -480,7 +424,6 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
 	iowrite32(MWL8K_H2A_INT_DUMMY,
 		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
 
-	rc = -ETIMEDOUT;
 	loops = 1000;
 	do {
 		u32 int_code;
@@ -488,7 +431,6 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
 		int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
 		if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
 			iowrite32(0, regs + MWL8K_HIU_INT_CODE);
-			rc = 0;
 			break;
 		}
 
@@ -497,26 +439,7 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
 
 	pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);
 
-	/*
-	 * Clear 'command done' interrupt bit.
-	 */
-	loops = 1000;
-	do {
-		u32 status;
-
-		status = ioread32(priv->regs +
-				MWL8K_HIU_A2H_INTERRUPT_STATUS);
-		if (status & MWL8K_A2H_INT_OPC_DONE) {
-			iowrite32(~MWL8K_A2H_INT_OPC_DONE,
-				priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
-			ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
-			break;
-		}
-
-		udelay(1);
-	} while (--loops);
-
-	return rc;
+	return loops ? 0 : -ETIMEDOUT;
 }
 
 static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
@@ -681,11 +604,9 @@ struct ewc_ht_info {
 
 /* Peer Entry flags - used to define the type of the peer node */
 #define MWL8K_PEER_TYPE_ACCESSPOINT	2
-#define MWL8K_PEER_TYPE_ADHOC_STATION	4
 
 #define MWL8K_IEEE_LEGACY_DATA_RATES	12
 #define MWL8K_MCS_BITMAP_SIZE		16
-#define pad_size			16
 
 struct peer_capability_info {
 	/* Peer type - AP vs. STA.  */
@@ -707,7 +628,7 @@ struct peer_capability_info {
 
 	/* HT rate table. Intersection of our rates and peer rates.  */
 	__u8	ht_rates[MWL8K_MCS_BITMAP_SIZE];
-	__u8	pad[pad_size];
+	__u8	pad[16];
 
 	/* If set, interoperability mode, no proprietary extensions.  */
 	__u8	interop;
@@ -717,15 +638,6 @@ struct peer_capability_info {
 } __attribute__((packed));
 
 /* Inline functions to manipulate QoS field in data descriptor.  */
-static inline u16 mwl8k_qos_setbit_tid(u16 qos, u8 tid)
-{
-	u16 val_mask = 0x000f;
-	u16 qos_mask = ~val_mask;
-
-	/* TID bits 0-3 */
-	return (qos & qos_mask) | (tid & val_mask);
-}
-
 static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
 {
 	u16 val_mask = 1 << 4;
@@ -769,12 +681,11 @@ struct mwl8k_dma_data {
 } __attribute__((packed));
 
 /* Routines to add/remove DMA header from skb.  */
-static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
+static inline void mwl8k_remove_dma_header(struct sk_buff *skb)
 {
-	struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)(skb->data);
+	struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)skb->data;
 	void *dst, *src = &tr->wh;
-	__le16 fc = tr->wh.frame_control;
-	int hdrlen = ieee80211_hdrlen(fc);
+	int hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
 	u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
 
 	dst = (void *)tr + space;
@@ -782,11 +693,9 @@ static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
 		memmove(dst, src, hdrlen);
 		skb_pull(skb, space);
 	}
-
-	return 0;
 }
 
-static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
+static inline void mwl8k_add_dma_header(struct sk_buff *skb)
 {
 	struct ieee80211_hdr *wh;
 	u32 hdrlen, pktlen;
@@ -810,7 +719,7 @@ static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
 		memmove(&tr->wh, wh, hdrlen);
 
 	/* Clear addr4 */
-	memset(tr->wh.addr4, 0, IEEE80211_ADDR_LEN);
+	memset(tr->wh.addr4, 0, ETH_ALEN);
 
 	/*
 	 * Firmware length is the length of the fully formed "802.11
@@ -818,17 +727,13 @@ static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
 	 * This includes all crypto material including the MIC.
 	 */
 	tr->fwlen = cpu_to_le16(pktlen - hdrlen);
-
-	return skb;
 }
 
 
 /*
  * Packet reception.
  */
-#define MWL8K_RX_CTRL_KEY_INDEX_MASK	0x30
 #define MWL8K_RX_CTRL_OWNED_BY_HOST	0x02
-#define MWL8K_RX_CTRL_AMPDU		0x01
 
 struct mwl8k_rx_desc {
 	__le16 pkt_len;
@@ -979,7 +884,7 @@ static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
 							struct sk_buff *skb)
 {
 	priv->capture_beacon = false;
-	memset(priv->capture_bssid, 0, IEEE80211_ADDR_LEN);
+	memset(priv->capture_bssid, 0, ETH_ALEN);
 
 	/*
 	 * Use GFP_ATOMIC as rxq_process is called from
@@ -1024,10 +929,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 					MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
 
 		skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
-		if (mwl8k_remove_dma_header(skb)) {
-			dev_kfree_skb(skb);
-			continue;
-		}
+		mwl8k_remove_dma_header(skb);
 
 		wh = (struct ieee80211_hdr *)skb->data;
 
@@ -1049,7 +951,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
 		status.flag = 0;
 		status.band = IEEE80211_BAND_2GHZ;
 		status.freq = ieee80211_channel_to_frequency(rx_desc->channel);
-		ieee80211_rx_irqsafe(hw, skb, &status);
+		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+		ieee80211_rx_irqsafe(hw, skb);
 
 		processed++;
 	}
@@ -1072,8 +975,6 @@ enum {
 
 /* Transmit packet ACK policy */
 #define MWL8K_TXD_ACK_POLICY_NORMAL		0
-#define MWL8K_TXD_ACK_POLICY_NONE		1
-#define MWL8K_TXD_ACK_POLICY_NO_EXPLICIT	2
 #define MWL8K_TXD_ACK_POLICY_BLOCKACK		3
 
 #define GET_TXQ(_ac) (\
@@ -1082,20 +983,11 @@ enum {
 		((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \
 		MWL8K_WME_AC_BE)
 
-#define MWL8K_TXD_STATUS_IDLE			0x00000000
-#define MWL8K_TXD_STATUS_USED			0x00000001
 #define MWL8K_TXD_STATUS_OK			0x00000001
 #define MWL8K_TXD_STATUS_OK_RETRY		0x00000002
 #define MWL8K_TXD_STATUS_OK_MORE_RETRY		0x00000004
 #define MWL8K_TXD_STATUS_MULTICAST_TX		0x00000008
-#define MWL8K_TXD_STATUS_BROADCAST_TX		0x00000010
-#define MWL8K_TXD_STATUS_FAILED_LINK_ERROR	0x00000020
-#define MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT	0x00000040
-#define MWL8K_TXD_STATUS_FAILED_AGING		0x00000080
-#define MWL8K_TXD_STATUS_HOST_CMD		0x40000000
 #define MWL8K_TXD_STATUS_FW_OWNED		0x80000000
-#define  MWL8K_TXD_SOFTSTALE				0x80
-#define  MWL8K_TXD_SOFTSTALE_MGMT_RETRY			0x01
 
 struct mwl8k_tx_desc {
 	__le32 status;
@@ -1104,7 +996,7 @@ struct mwl8k_tx_desc {
 	__le16 qos_control;
 	__le32 pkt_phys_addr;
 	__le16 pkt_len;
-	__u8 dest_MAC_addr[IEEE80211_ADDR_LEN];
+	__u8 dest_MAC_addr[ETH_ALEN];
 	__le32 next_tx_desc_phys_addr;
 	__le32 reserved;
 	__le16 rate_info;
@@ -1121,8 +1013,7 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
 	int size;
 	int i;
 
-	memset(&txq->tx_stats, 0,
-		sizeof(struct ieee80211_tx_queue_stats));
+	memset(&txq->tx_stats, 0, sizeof(struct ieee80211_tx_queue_stats));
 	txq->tx_stats.limit = MWL8K_TX_DESCS;
 	txq->tx_head = 0;
 	txq->tx_tail = 0;
@@ -1189,17 +1080,17 @@ struct mwl8k_txq_info {
 };
 
 static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
-				struct mwl8k_txq_info txinfo[],
-				u32 num_queues)
+				struct mwl8k_txq_info *txinfo)
 {
 	int count, desc, status;
 	struct mwl8k_tx_queue *txq;
 	struct mwl8k_tx_desc *tx_desc;
 	int ndescs = 0;
 
-	memset(txinfo, 0, num_queues * sizeof(struct mwl8k_txq_info));
+	memset(txinfo, 0, MWL8K_TX_QUEUES * sizeof(struct mwl8k_txq_info));
+
 	spin_lock_bh(&priv->tx_lock);
-	for (count = 0; count < num_queues; count++) {
+	for (count = 0; count < MWL8K_TX_QUEUES; count++) {
 		txq = priv->txq + count;
 		txinfo[count].len = txq->tx_stats.len;
 		txinfo[count].head = txq->tx_head;
@@ -1222,34 +1113,34 @@ static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
 	return ndescs;
 }
 
-static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
+/*
+ * Must be called with hw->fw_mutex held and tx queues stopped.
+ */
+static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
 {
-	u32 count = 0;
-	unsigned long timeout = 0;
 	struct mwl8k_priv *priv = hw->priv;
 	DECLARE_COMPLETION_ONSTACK(cmd_wait);
+	u32 count;
+	unsigned long timeout;
 
 	might_sleep();
 
-	if (priv->tx_wait != NULL)
-		printk(KERN_ERR "WARNING Previous TXWaitEmpty instance\n");
-
 	spin_lock_bh(&priv->tx_lock);
 	count = mwl8k_txq_busy(priv);
 	if (count) {
 		priv->tx_wait = &cmd_wait;
-		if (priv->radio_state)
+		if (priv->radio_on)
 			mwl8k_tx_start(priv);
 	}
 	spin_unlock_bh(&priv->tx_lock);
 
 	if (count) {
-		struct mwl8k_txq_info txinfo[4];
+		struct mwl8k_txq_info txinfo[MWL8K_TX_QUEUES];
 		int index;
 		int newcount;
 
 		timeout = wait_for_completion_timeout(&cmd_wait,
-					msecs_to_jiffies(delay_ms));
+					msecs_to_jiffies(5000));
 		if (timeout)
 			return 0;
 
@@ -1258,11 +1149,11 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
 		newcount = mwl8k_txq_busy(priv);
 		spin_unlock_bh(&priv->tx_lock);
 
-		printk(KERN_ERR "%s(%u) TIMEDOUT:%ums Pend:%u-->%u\n",
-		       __func__, __LINE__, delay_ms, count, newcount);
+		printk(KERN_ERR "%s(%u) TIMEDOUT:5000ms Pend:%u-->%u\n",
+		       __func__, __LINE__, count, newcount);
 
-		mwl8k_scan_tx_ring(priv, txinfo, 4);
-		for (index = 0 ; index < 4; index++)
+		mwl8k_scan_tx_ring(priv, txinfo);
+		for (index = 0; index < MWL8K_TX_QUEUES; index++)
 			printk(KERN_ERR
 				"TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n",
 					index,
@@ -1272,18 +1163,17 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
 					txinfo[index].fw_owned,
 					txinfo[index].drv_owned,
 					txinfo[index].unused);
+
 		return -ETIMEDOUT;
 	}
 
 	return 0;
 }
 
-#define MWL8K_TXD_OK	(MWL8K_TXD_STATUS_OK | \
-			 MWL8K_TXD_STATUS_OK_RETRY | \
-			 MWL8K_TXD_STATUS_OK_MORE_RETRY)
-#define MWL8K_TXD_SUCCESS(stat)		((stat) & MWL8K_TXD_OK)
-#define MWL8K_TXD_FAIL_RETRY(stat)	\
-	((stat) & (MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT))
+#define MWL8K_TXD_SUCCESS(status)				\
+	((status) & (MWL8K_TXD_STATUS_OK |			\
+		     MWL8K_TXD_STATUS_OK_RETRY |		\
+		     MWL8K_TXD_STATUS_OK_MORE_RETRY))
 
 static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
 {
@@ -1293,15 +1183,13 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
 
 	while (txq->tx_stats.len > 0) {
 		int tx;
-		int rc;
 		struct mwl8k_tx_desc *tx_desc;
 		unsigned long addr;
-		size_t size;
+		int size;
 		struct sk_buff *skb;
 		struct ieee80211_tx_info *info;
 		u32 status;
 
-		rc = 0;
 		tx = txq->tx_head;
 		tx_desc = txq->tx_desc_area + tx;
 
@@ -1320,56 +1208,30 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
 		priv->pending_tx_pkts--;
 
 		addr = le32_to_cpu(tx_desc->pkt_phys_addr);
-		size = (u32)(le16_to_cpu(tx_desc->pkt_len));
-		skb = txq->tx_skb[tx].skb;
-		txq->tx_skb[tx].skb = NULL;
+		size = le16_to_cpu(tx_desc->pkt_len);
+		skb = txq->tx_skb[tx];
+		txq->tx_skb[tx] = NULL;
 
 		BUG_ON(skb == NULL);
 		pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
 
-		rc = mwl8k_remove_dma_header(skb);
+		mwl8k_remove_dma_header(skb);
 
 		/* Mark descriptor as unused */
 		tx_desc->pkt_phys_addr = 0;
 		tx_desc->pkt_len = 0;
 
-		if (txq->tx_skb[tx].clone) {
-			/* Replace with original skb
-			 * before returning to stack
-			 * as buffer has been cloned
-			 */
-			dev_kfree_skb(skb);
-			skb = txq->tx_skb[tx].clone;
-			txq->tx_skb[tx].clone = NULL;
-		}
-
-		if (rc) {
-			/* Something has gone wrong here.
-			 * Failed to remove DMA header.
-			 * Print error message and drop packet.
-			 */
-			printk(KERN_ERR "%s: Error removing DMA header from "
-					"tx skb 0x%p.\n", priv->name, skb);
-
-			dev_kfree_skb(skb);
-			continue;
-		}
-
 		info = IEEE80211_SKB_CB(skb);
 		ieee80211_tx_info_clear_status(info);
-
-		/* Convert firmware status stuff into tx_status */
-		if (MWL8K_TXD_SUCCESS(status)) {
-			/* Transmit OK */
+		if (MWL8K_TXD_SUCCESS(status))
 			info->flags |= IEEE80211_TX_STAT_ACK;
-		}
 
 		ieee80211_tx_status_irqsafe(hw, skb);
 
-		wake = !priv->inconfig && priv->radio_state;
+		wake = 1;
 	}
 
-	if (wake)
+	if (wake && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
 		ieee80211_wake_queue(hw, index);
 }
 
@@ -1395,56 +1257,60 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct ieee80211_tx_info *tx_info;
+	struct mwl8k_vif *mwl8k_vif;
 	struct ieee80211_hdr *wh;
 	struct mwl8k_tx_queue *txq;
 	struct mwl8k_tx_desc *tx;
-	struct mwl8k_dma_data *tr;
-	struct mwl8k_vif *mwl8k_vif;
-	struct sk_buff *org_skb = skb;
 	dma_addr_t dma;
-	u16 qos = 0;
-	bool qosframe = false, ampduframe = false;
-	bool mcframe = false, eapolframe = false;
-	bool amsduframe = false;
-	__le16 fc;
-
-	txq = priv->txq + index;
-	tx = txq->tx_desc_area + txq->tx_tail;
+	u32 txstatus;
+	u8 txdatarate;
+	u16 qos;
 
-	BUG_ON(txq->tx_skb[txq->tx_tail].skb != NULL);
+	wh = (struct ieee80211_hdr *)skb->data;
+	if (ieee80211_is_data_qos(wh->frame_control))
+		qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
+	else
+		qos = 0;
 
-	/*
-	 * Append HW DMA header to start of packet.  Drop packet if
-	 * there is not enough space or a failure to unshare/unclone
-	 * the skb.
-	 */
-	skb = mwl8k_add_dma_header(skb);
-
-	if (skb == NULL) {
-		printk(KERN_DEBUG "%s: failed to prepend HW DMA "
-			"header, dropping TX frame.\n", priv->name);
-		dev_kfree_skb(org_skb);
-		return NETDEV_TX_OK;
-	}
+	mwl8k_add_dma_header(skb);
+	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
 
 	tx_info = IEEE80211_SKB_CB(skb);
 	mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
-	tr = (struct mwl8k_dma_data *)skb->data;
-	wh = &tr->wh;
-	fc = wh->frame_control;
-	qosframe = ieee80211_is_data_qos(fc);
-	mcframe = is_multicast_ether_addr(wh->addr1);
-	ampduframe = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
 
 	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
 		u16 seqno = mwl8k_vif->seqno;
+
 		wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
 		wh->seq_ctrl |= cpu_to_le16(seqno << 4);
 		mwl8k_vif->seqno = seqno++ % 4096;
 	}
 
-	if (qosframe)
-		qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
+	/* Setup firmware control bit fields for each frame type.  */
+	txstatus = 0;
+	txdatarate = 0;
+	if (ieee80211_is_mgmt(wh->frame_control) ||
+	    ieee80211_is_ctl(wh->frame_control)) {
+		txdatarate = 0;
+		qos = mwl8k_qos_setbit_eosp(qos);
+		/* Set Queue size to unspecified */
+		qos = mwl8k_qos_setbit_qlen(qos, 0xff);
+	} else if (ieee80211_is_data(wh->frame_control)) {
+		txdatarate = 1;
+		if (is_multicast_ether_addr(wh->addr1))
+			txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX;
+
+		/* Send pkt in an aggregate if AMPDU frame.  */
+		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+			qos = mwl8k_qos_setbit_ack(qos,
+				MWL8K_TXD_ACK_POLICY_BLOCKACK);
+		else
+			qos = mwl8k_qos_setbit_ack(qos,
+				MWL8K_TXD_ACK_POLICY_NORMAL);
+
+		if (qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+			qos = mwl8k_qos_setbit_amsdu(qos);
+	}
 
 	dma = pci_map_single(priv->pdev, skb->data,
 				skb->len, PCI_DMA_TODEVICE);
@@ -1452,99 +1318,40 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 	if (pci_dma_mapping_error(priv->pdev, dma)) {
 		printk(KERN_DEBUG "%s: failed to dma map skb, "
 			"dropping TX frame.\n", priv->name);
-
-		if (org_skb != NULL)
-			dev_kfree_skb(org_skb);
-		if (skb != NULL)
-			dev_kfree_skb(skb);
+		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
 
-	/* Set desc header, cpu bit order.  */
-	tx->status = 0;
-	tx->data_rate = 0;
-	tx->tx_priority = index;
-	tx->qos_control = 0;
-	tx->rate_info = 0;
-	tx->peer_id = mwl8k_vif->peer_id;
-
-	amsduframe = !!(qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
-
-	/* Setup firmware control bit fields for each frame type.  */
-	if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
-		tx->data_rate = 0;
-		qos = mwl8k_qos_setbit_eosp(qos);
-		/* Set Queue size to unspecified */
-		qos = mwl8k_qos_setbit_qlen(qos, 0xff);
-	} else if (ieee80211_is_data(fc)) {
-		tx->data_rate = 1;
-		if (mcframe)
-			tx->status |= MWL8K_TXD_STATUS_MULTICAST_TX;
+	spin_lock_bh(&priv->tx_lock);
 
-		/*
-		 * Tell firmware to not send EAPOL pkts in an
-		 * aggregate.  Verify against mac80211 tx path.  If
-		 * stack turns off AMPDU for an EAPOL frame this
-		 * check will be removed.
-		 */
-		if (eapolframe) {
-			qos = mwl8k_qos_setbit_ack(qos,
-				MWL8K_TXD_ACK_POLICY_NORMAL);
-		} else {
-			/* Send pkt in an aggregate if AMPDU frame.  */
-			if (ampduframe)
-				qos = mwl8k_qos_setbit_ack(qos,
-					MWL8K_TXD_ACK_POLICY_BLOCKACK);
-			else
-				qos = mwl8k_qos_setbit_ack(qos,
-					MWL8K_TXD_ACK_POLICY_NORMAL);
+	txq = priv->txq + index;
 
-			if (amsduframe)
-				qos = mwl8k_qos_setbit_amsdu(qos);
-		}
-	}
+	BUG_ON(txq->tx_skb[txq->tx_tail] != NULL);
+	txq->tx_skb[txq->tx_tail] = skb;
 
-	/* Convert to little endian */
+	tx = txq->tx_desc_area + txq->tx_tail;
+	tx->data_rate = txdatarate;
+	tx->tx_priority = index;
 	tx->qos_control = cpu_to_le16(qos);
-	tx->status = cpu_to_le32(tx->status);
 	tx->pkt_phys_addr = cpu_to_le32(dma);
 	tx->pkt_len = cpu_to_le16(skb->len);
-
-	txq->tx_skb[txq->tx_tail].skb = skb;
-	txq->tx_skb[txq->tx_tail].clone =
-		skb == org_skb ? NULL : org_skb;
-
-	spin_lock_bh(&priv->tx_lock);
-
-	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_OK |
-					MWL8K_TXD_STATUS_FW_OWNED);
+	tx->rate_info = 0;
+	tx->peer_id = mwl8k_vif->peer_id;
 	wmb();
+	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
+
+	txq->tx_stats.count++;
 	txq->tx_stats.len++;
 	priv->pending_tx_pkts++;
-	txq->tx_stats.count++;
-	txq->tx_tail++;
 
+	txq->tx_tail++;
 	if (txq->tx_tail == MWL8K_TX_DESCS)
 		txq->tx_tail = 0;
+
 	if (txq->tx_head == txq->tx_tail)
 		ieee80211_stop_queue(hw, index);
 
-	if (priv->inconfig) {
-		/*
-		 * Silently queue packet when we are in the middle of
-		 * a config cycle.  Notify firmware only if we are
-		 * waiting for TXQs to empty.  If a packet is sent
-		 * before .config() is complete, perhaps it is better
-		 * to drop the packet, as the channel is being changed
-		 * and the packet will end up on the wrong channel.
-		 */
-		printk(KERN_ERR "%s(): WARNING TX activity while "
-			"in config\n", __func__);
-
-		if (priv->tx_wait != NULL)
-			mwl8k_tx_start(priv);
-	} else
-		mwl8k_tx_start(priv);
+	mwl8k_tx_start(priv);
 
 	spin_unlock_bh(&priv->tx_lock);
 
@@ -1553,6 +1360,60 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 
 
 /*
+ * Firmware access.
+ *
+ * We have the following requirements for issuing firmware commands:
+ * - Some commands require that the packet transmit path is idle when
+ *   the command is issued.  (For simplicity, we'll just quiesce the
+ *   transmit path for every command.)
+ * - There are certain sequences of commands that need to be issued to
+ *   the hardware sequentially, with no other intervening commands.
+ *
+ * This leads to an implementation of a "firmware lock" as a mutex that
+ * can be taken recursively, and which is taken by both the low-level
+ * command submission function (mwl8k_post_cmd) as well as any users of
+ * that function that require issuing of an atomic sequence of commands,
+ * and quiesces the transmit path whenever it's taken.
+ */
+static int mwl8k_fw_lock(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	if (priv->fw_mutex_owner != current) {
+		int rc;
+
+		mutex_lock(&priv->fw_mutex);
+		ieee80211_stop_queues(hw);
+
+		rc = mwl8k_tx_wait_empty(hw);
+		if (rc) {
+			ieee80211_wake_queues(hw);
+			mutex_unlock(&priv->fw_mutex);
+
+			return rc;
+		}
+
+		priv->fw_mutex_owner = current;
+	}
+
+	priv->fw_mutex_depth++;
+
+	return 0;
+}
+
+static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+
+	if (!--priv->fw_mutex_depth) {
+		ieee80211_wake_queues(hw);
+		priv->fw_mutex_owner = NULL;
+		mutex_unlock(&priv->fw_mutex);
+	}
+}
+
+
+/*
  * Command processing.
  */
 
@@ -1567,7 +1428,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
 	dma_addr_t dma_addr;
 	unsigned int dma_size;
 	int rc;
-	u16 __iomem *result;
 	unsigned long timeout = 0;
 	u8 buf[32];
 
@@ -1578,41 +1438,43 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
 	if (pci_dma_mapping_error(priv->pdev, dma_addr))
 		return -ENOMEM;
 
-	if (priv->hostcmd_wait != NULL)
-		printk(KERN_ERR "WARNING host command in progress\n");
+	rc = mwl8k_fw_lock(hw);
+	if (rc) {
+		pci_unmap_single(priv->pdev, dma_addr, dma_size,
+						PCI_DMA_BIDIRECTIONAL);
+		return rc;
+	}
 
-	spin_lock_irq(&priv->fw_lock);
 	priv->hostcmd_wait = &cmd_wait;
 	iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
 	iowrite32(MWL8K_H2A_INT_DOORBELL,
 		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
 	iowrite32(MWL8K_H2A_INT_DUMMY,
 		regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
-	spin_unlock_irq(&priv->fw_lock);
 
 	timeout = wait_for_completion_timeout(&cmd_wait,
 				msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
 
+	priv->hostcmd_wait = NULL;
+
+	mwl8k_fw_unlock(hw);
+
 	pci_unmap_single(priv->pdev, dma_addr, dma_size,
 					PCI_DMA_BIDIRECTIONAL);
 
-	result = &cmd->result;
 	if (!timeout) {
-		spin_lock_irq(&priv->fw_lock);
-		priv->hostcmd_wait = NULL;
-		spin_unlock_irq(&priv->fw_lock);
 		printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
 		       priv->name,
 		       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
 		       MWL8K_CMD_TIMEOUT_MS);
 		rc = -ETIMEDOUT;
 	} else {
-		rc = *result ? -EINVAL : 0;
+		rc = cmd->result ? -EINVAL : 0;
 		if (rc)
 			printk(KERN_ERR "%s: Command %s error 0x%x\n",
 			       priv->name,
 			       mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
-			       *result);
+			       le16_to_cpu(cmd->result));
 	}
 
 	return rc;
@@ -1626,7 +1488,7 @@ struct mwl8k_cmd_get_hw_spec {
 	__u8 hw_rev;
 	__u8 host_interface;
 	__le16 num_mcaddrs;
-	__u8 perm_addr[IEEE80211_ADDR_LEN];
+	__u8 perm_addr[ETH_ALEN];
 	__le16 region_code;
 	__le32 fw_rev;
 	__le32 ps_cookie;
@@ -1670,7 +1532,6 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
 		priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
 		priv->fw_rev = le32_to_cpu(cmd->fw_rev);
 		priv->hw_rev = cmd->hw_rev;
-		priv->region_code = le16_to_cpu(cmd->region_code);
 	}
 
 	kfree(cmd);
@@ -1684,41 +1545,44 @@ struct mwl8k_cmd_mac_multicast_adr {
 	struct mwl8k_cmd_pkt header;
 	__le16 action;
 	__le16 numaddr;
-	__u8 addr[1][IEEE80211_ADDR_LEN];
+	__u8 addr[0][ETH_ALEN];
 };
 
 #define MWL8K_ENABLE_RX_MULTICAST 0x000F
-static int mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
-					int mc_count,
-					struct dev_addr_list *mclist)
+
+static struct mwl8k_cmd_pkt *
+__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
+			      int mc_count, struct dev_addr_list *mclist)
 {
+	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_cmd_mac_multicast_adr *cmd;
-	int index = 0;
-	int rc;
-	int size = sizeof(*cmd) + ((mc_count - 1) * IEEE80211_ADDR_LEN);
-	cmd = kzalloc(size, GFP_KERNEL);
+	int size;
+	int i;
+
+	if (mc_count > priv->num_mcaddrs)
+		mc_count = priv->num_mcaddrs;
+
+	size = sizeof(*cmd) + mc_count * ETH_ALEN;
+
+	cmd = kzalloc(size, GFP_ATOMIC);
 	if (cmd == NULL)
-		return -ENOMEM;
+		return NULL;
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
 	cmd->header.length = cpu_to_le16(size);
 	cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
 	cmd->numaddr = cpu_to_le16(mc_count);
-	while ((index < mc_count) && mclist) {
-		if (mclist->da_addrlen != IEEE80211_ADDR_LEN) {
-			rc = -EINVAL;
-			goto mwl8k_cmd_mac_multicast_adr_exit;
+
+	for (i = 0; i < mc_count && mclist; i++) {
+		if (mclist->da_addrlen != ETH_ALEN) {
+			kfree(cmd);
+			return NULL;
 		}
-		memcpy(cmd->addr[index], mclist->da_addr, IEEE80211_ADDR_LEN);
-		index++;
+		memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
 		mclist = mclist->next;
 	}
 
-	rc = mwl8k_post_cmd(hw, &cmd->header);
-
-mwl8k_cmd_mac_multicast_adr_exit:
-	kfree(cmd);
-	return rc;
+	return &cmd->header;
 }
 
 /*
@@ -1775,18 +1639,16 @@ struct mwl8k_cmd_802_11_radio_control {
 	__le16 radio_on;
 } __attribute__((packed));
 
-static int mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, int enable)
+static int
+mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_cmd_802_11_radio_control *cmd;
 	int rc;
 
-	if (((enable & MWL8K_RADIO_ENABLE) == priv->radio_state) &&
-	    !(enable & MWL8K_RADIO_FORCE))
+	if (enable == priv->radio_on && !force)
 		return 0;
 
-	enable &= MWL8K_RADIO_ENABLE;
-
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (cmd == NULL)
 		return -ENOMEM;
@@ -1794,18 +1656,28 @@ static int mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, int enable)
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
-	cmd->control = cpu_to_le16(priv->radio_preamble);
+	cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1);
 	cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
 
 	if (!rc)
-		priv->radio_state = enable;
+		priv->radio_on = enable;
 
 	return rc;
 }
 
+static int mwl8k_cmd_802_11_radio_disable(struct ieee80211_hw *hw)
+{
+	return mwl8k_cmd_802_11_radio_control(hw, 0, 0);
+}
+
+static int mwl8k_cmd_802_11_radio_enable(struct ieee80211_hw *hw)
+{
+	return mwl8k_cmd_802_11_radio_control(hw, 1, 0);
+}
+
 static int
 mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
 {
@@ -1815,12 +1687,9 @@ mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
 		return -EINVAL;
 	priv = hw->priv;
 
-	priv->radio_preamble = (short_preamble ?
-		MWL8K_RADIO_SHORT_PREAMBLE :
-		MWL8K_RADIO_LONG_PREAMBLE);
+	priv->radio_short_preamble = short_preamble;
 
-	return mwl8k_cmd_802_11_radio_control(hw,
-			MWL8K_RADIO_ENABLE | MWL8K_RADIO_FORCE);
+	return mwl8k_cmd_802_11_radio_control(hw, 1, 1);
 }
 
 /*
@@ -1888,11 +1757,11 @@ static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
 struct mwl8k_cmd_set_post_scan {
 	struct mwl8k_cmd_pkt header;
 	__le32 isibss;
-	__u8 bssid[IEEE80211_ADDR_LEN];
+	__u8 bssid[ETH_ALEN];
 } __attribute__((packed));
 
 static int
-mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 mac[IEEE80211_ADDR_LEN])
+mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 *mac)
 {
 	struct mwl8k_cmd_set_post_scan *cmd;
 	int rc;
@@ -1904,7 +1773,7 @@ mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 mac[IEEE80211_ADDR_LEN])
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->isibss = 0;
-	memcpy(cmd->bssid, mac, IEEE80211_ADDR_LEN);
+	memcpy(cmd->bssid, mac, ETH_ALEN);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -1956,7 +1825,7 @@ struct mwl8k_cmd_set_slot {
 	__u8 short_slot;
 } __attribute__((packed));
 
-static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, int slot_time)
+static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
 {
 	struct mwl8k_cmd_set_slot *cmd;
 	int rc;
@@ -1968,7 +1837,7 @@ static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, int slot_time)
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->action = cpu_to_le16(MWL8K_CMD_SET);
-	cmd->short_slot = slot_time == MWL8K_SHORT_SLOTTIME ? 1 : 0;
+	cmd->short_slot = short_slot_time;
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2026,7 +1895,7 @@ static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->action = enable ? cpu_to_le32((u32)MWL8K_CMD_SET) : 0;
+	cmd->action = cpu_to_le32(!!enable);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2035,7 +1904,7 @@ static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
 }
 
 /*
- * CMD_SET_RATE_ADAPT_MODE.
+ * CMD_SET_RATEADAPT_MODE.
  */
 struct mwl8k_cmd_set_rate_adapt_mode {
 	struct mwl8k_cmd_pkt header;
@@ -2083,13 +1952,13 @@ static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable)
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-	cmd->action = enable ? cpu_to_le16(MWL8K_CMD_SET) : 0;
+	cmd->action = cpu_to_le16(!!enable);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
 
 	if (!rc)
-		priv->wmm_mode = enable;
+		priv->wmm_enabled = enable;
 
 	return rc;
 }
@@ -2104,7 +1973,7 @@ struct mwl8k_cmd_rts_threshold {
 } __attribute__((packed));
 
 static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
-			       u16 action, u16 *threshold)
+			       u16 action, u16 threshold)
 {
 	struct mwl8k_cmd_rts_threshold *cmd;
 	int rc;
@@ -2116,7 +1985,7 @@ static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->action = cpu_to_le16(action);
-	cmd->threshold = cpu_to_le16(*threshold);
+	cmd->threshold = cpu_to_le16(threshold);
 
 	rc = mwl8k_post_cmd(hw, &cmd->header);
 	kfree(cmd);
@@ -2149,7 +2018,6 @@ struct mwl8k_cmd_set_edca_params {
 	__u8 txq;
 } __attribute__((packed));
 
-#define MWL8K_GET_EDCA_ALL	0
 #define MWL8K_SET_EDCA_CW	0x01
 #define MWL8K_SET_EDCA_TXOP	0x02
 #define MWL8K_SET_EDCA_AIFS	0x04
@@ -2164,22 +2032,18 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
 		__u8 aifs, __u16 txop)
 {
 	struct mwl8k_cmd_set_edca_params *cmd;
-	u32 log_cw_min, log_cw_max;
 	int rc;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
 	if (cmd == NULL)
 		return -ENOMEM;
 
-	log_cw_min = ilog2(cw_min+1);
-	log_cw_max = ilog2(cw_max+1);
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-
 	cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
 	cmd->txop = cpu_to_le16(txop);
-	cmd->log_cw_max = (u8)log_cw_max;
-	cmd->log_cw_min = (u8)log_cw_min;
+	cmd->log_cw_max = (u8)ilog2(cw_max + 1);
+	cmd->log_cw_min = (u8)ilog2(cw_min + 1);
 	cmd->aifs = aifs;
 	cmd->txq = qnum;
 
@@ -2220,11 +2084,7 @@ static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
 
 	cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
-
-	if (dtim)
-		cmd->sleep_interval = cpu_to_le32(dtim);
-	else
-		cmd->sleep_interval = cpu_to_le32(1);
+	cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
 
 	hdrlen = ieee80211_hdrlen(payload->frame_control);
 
@@ -2236,8 +2096,8 @@ static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
 			"sent to firmware. Sz=%u MAX=%u\n", __func__,
 			payload_len, MWL8K_FJ_BEACON_MAXLEN);
 
-	payload_len = payload_len > MWL8K_FJ_BEACON_MAXLEN ?
-				MWL8K_FJ_BEACON_MAXLEN : payload_len;
+	if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
+		payload_len = MWL8K_FJ_BEACON_MAXLEN;
 
 	if (payload && payload_len)
 		memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
@@ -2257,7 +2117,7 @@ struct mwl8k_cmd_update_sta_db {
 	__le32	action;
 
 	/* Peer MAC address */
-	__u8	peer_addr[IEEE80211_ADDR_LEN];
+	__u8	peer_addr[ETH_ALEN];
 
 	__le32	reserved;
 
@@ -2273,7 +2133,6 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
 	struct mwl8k_cmd_update_sta_db *cmd;
 	struct peer_capability_info *peer_info;
 	struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
-	DECLARE_MAC_BUF(mac);
 	int rc;
 	__u8 count, *rates;
 
@@ -2286,7 +2145,7 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
 
 	cmd->action = cpu_to_le32(action);
 	peer_info = &cmd->peer_info;
-	memcpy(cmd->peer_addr, mv_vif->bssid, IEEE80211_ADDR_LEN);
+	memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN);
 
 	switch (action) {
 	case MWL8K_STA_DB_ADD_ENTRY:
@@ -2298,7 +2157,7 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
 		peer_info->amsdu_enabled = 0;
 
 		rates = peer_info->legacy_rates;
-		for (count = 0 ; count < mv_vif->legacy_nrates; count++)
+		for (count = 0; count < mv_vif->legacy_nrates; count++)
 			rates[count] = bitrates[count].hw_value;
 
 		rc = mwl8k_post_cmd(hw, &cmd->header);
@@ -2323,25 +2182,19 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
 /*
  * CMD_SET_AID.
  */
-#define IEEE80211_OPMODE_DISABLED			0x00
-#define IEEE80211_OPMODE_NON_MEMBER_PROT_MODE		0x01
-#define IEEE80211_OPMODE_ONE_20MHZ_STA_PROT_MODE	0x02
-#define IEEE80211_OPMODE_HTMIXED_PROT_MODE		0x03
-
 #define MWL8K_RATE_INDEX_MAX_ARRAY			14
 
 #define MWL8K_FRAME_PROT_DISABLED			0x00
 #define MWL8K_FRAME_PROT_11G				0x07
 #define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY		0x02
 #define MWL8K_FRAME_PROT_11N_HT_ALL			0x06
-#define MWL8K_FRAME_PROT_MASK				0x07
 
 struct mwl8k_cmd_update_set_aid {
 	struct	mwl8k_cmd_pkt header;
 	__le16	aid;
 
 	 /* AP's MAC address (BSSID) */
-	__u8	bssid[IEEE80211_ADDR_LEN];
+	__u8	bssid[ETH_ALEN];
 	__le16	protection_mode;
 	__u8	supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
 } __attribute__((packed));
@@ -2365,9 +2218,7 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
 	cmd->header.length = cpu_to_le16(sizeof(*cmd));
 	cmd->aid = cpu_to_le16(info->aid);
 
-	memcpy(cmd->bssid, mv_vif->bssid, IEEE80211_ADDR_LEN);
-
-	prot_mode = MWL8K_FRAME_PROT_DISABLED;
+	memcpy(cmd->bssid, mv_vif->bssid, ETH_ALEN);
 
 	if (info->use_cts_prot) {
 		prot_mode = MWL8K_FRAME_PROT_11G;
@@ -2385,7 +2236,6 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
 			break;
 		}
 	}
-
 	cmd->protection_mode = cpu_to_le16(prot_mode);
 
 	for (count = 0; count < mv_vif->legacy_nrates; count++)
@@ -2439,10 +2289,6 @@ static int mwl8k_update_rateset(struct ieee80211_hw *hw,
  */
 #define MWL8K_RATE_TABLE_SIZE	8
 #define MWL8K_UCAST_RATE	0
-#define MWL8K_MCAST_RATE	1
-#define MWL8K_BCAST_RATE	2
-
-#define MWL8K_USE_FIXED_RATE	0x0001
 #define MWL8K_USE_AUTO_RATE	0x0002
 
 struct mwl8k_rate_entry {
@@ -2535,7 +2381,6 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
 	status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
 	iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
 
-	status &= priv->int_mask;
 	if (!status)
 		return IRQ_NONE;
 
@@ -2548,17 +2393,14 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
 	}
 
 	if (status & MWL8K_A2H_INT_OPC_DONE) {
-		if (priv->hostcmd_wait != NULL) {
+		if (priv->hostcmd_wait != NULL)
 			complete(priv->hostcmd_wait);
-			priv->hostcmd_wait = NULL;
-		}
 	}
 
 	if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
-		if (!priv->inconfig &&
-			priv->radio_state &&
-			mwl8k_txq_busy(priv))
-				mwl8k_tx_start(priv);
+		if (!mutex_is_locked(&priv->fw_mutex) &&
+		    priv->radio_on && mwl8k_txq_busy(priv))
+			mwl8k_tx_start(priv);
 	}
 
 	return IRQ_HANDLED;
@@ -2586,365 +2428,68 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 	return rc;
 }
 
-struct mwl8k_work_struct {
-	/* Initialized by mwl8k_queue_work().  */
-	struct work_struct wt;
-
-	/* Required field passed in to mwl8k_queue_work().  */
-	struct ieee80211_hw *hw;
-
-	/* Required field passed in to mwl8k_queue_work().  */
-	int (*wfunc)(struct work_struct *w);
-
-	/* Initialized by mwl8k_queue_work().  */
-	struct completion *cmd_wait;
-
-	/* Result code.  */
-	int rc;
-
-	/*
-	 * Optional field. Refer to explanation of MWL8K_WQ_XXX_XXX
-	 * flags for explanation.  Defaults to MWL8K_WQ_DEFAULT_OPTIONS.
-	 */
-	u32 options;
-
-	/* Optional field.  Defaults to MWL8K_CONFIG_TIMEOUT_MS.  */
-	unsigned long timeout_ms;
-
-	/* Optional field.  Defaults to MWL8K_WQ_TXWAIT_ATTEMPTS.  */
-	u32 txwait_attempts;
-
-	/* Optional field.  Defaults to MWL8K_TXWAIT_MS.  */
-	u32 tx_timeout_ms;
-	u32 step;
-};
-
-/* Flags controlling behavior of config queue requests */
-
-/* Caller spins while waiting for completion.  */
-#define MWL8K_WQ_SPIN			0x00000001
-
-/* Wait for TX queues to empty before proceeding with configuration.  */
-#define MWL8K_WQ_TX_WAIT_EMPTY		0x00000002
-
-/* Queue request and return immediately.  */
-#define MWL8K_WQ_POST_REQUEST		0x00000004
-
-/*
- * Caller sleeps and waits for task complete notification.
- * Do not use in atomic context.
- */
-#define MWL8K_WQ_SLEEP			0x00000008
-
-/* Free work struct when task is done.  */
-#define MWL8K_WQ_FREE_WORKSTRUCT	0x00000010
-
-/*
- * Config request is queued and returns to caller imediately.  Use
- * this in atomic context. Work struct is freed by mwl8k_queue_work()
- * when this flag is set.
- */
-#define MWL8K_WQ_QUEUE_ONLY	(MWL8K_WQ_POST_REQUEST | \
-				 MWL8K_WQ_FREE_WORKSTRUCT)
-
-/* Default work queue behavior is to sleep and wait for tx completion.  */
-#define MWL8K_WQ_DEFAULT_OPTIONS (MWL8K_WQ_SLEEP | MWL8K_WQ_TX_WAIT_EMPTY)
-
-/*
- * Default config request timeout.  Add adjustments to make sure the
- * config thread waits long enough for both tx wait and cmd wait before
- * timing out.
- */
-
-/* Time to wait for all TXQs to drain.  TX Doorbell is pressed each time.  */
-#define MWL8K_TXWAIT_TIMEOUT_MS		1000
-
-/* Default number of TX wait attempts.  */
-#define MWL8K_WQ_TXWAIT_ATTEMPTS	4
-
-/* Total time to wait for TXQ to drain.  */
-#define MWL8K_TXWAIT_MS			(MWL8K_TXWAIT_TIMEOUT_MS * \
-						MWL8K_WQ_TXWAIT_ATTEMPTS)
-
-/* Scheduling slop.  */
-#define MWL8K_OS_SCHEDULE_OVERHEAD_MS	200
-
-#define MWL8K_CONFIG_TIMEOUT_MS	(MWL8K_CMD_TIMEOUT_MS + \
-				 MWL8K_TXWAIT_MS + \
-				 MWL8K_OS_SCHEDULE_OVERHEAD_MS)
-
-static void mwl8k_config_thread(struct work_struct *wt)
-{
-	struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
-	struct ieee80211_hw *hw = worker->hw;
-	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
-
-	spin_lock_irq(&priv->tx_lock);
-	priv->inconfig = true;
-	spin_unlock_irq(&priv->tx_lock);
-
-	ieee80211_stop_queues(hw);
-
-	/*
-	 * Wait for host queues to drain before doing PHY
-	 * reconfiguration. This avoids interrupting any in-flight
-	 * DMA transfers to the hardware.
-	 */
-	if (worker->options & MWL8K_WQ_TX_WAIT_EMPTY) {
-		u32 timeout;
-		u32 time_remaining;
-		u32 iter;
-		u32 tx_wait_attempts = worker->txwait_attempts;
-
-		time_remaining = worker->tx_timeout_ms;
-		if (!tx_wait_attempts)
-			tx_wait_attempts = 1;
-
-		timeout = worker->tx_timeout_ms/tx_wait_attempts;
-		if (!timeout)
-			timeout = 1;
-
-		iter = tx_wait_attempts;
-		do {
-			int wait_time;
-
-			if (time_remaining > timeout) {
-				time_remaining -= timeout;
-				wait_time = timeout;
-			} else
-				wait_time = time_remaining;
-
-			if (!wait_time)
-				wait_time = 1;
-
-			rc = mwl8k_tx_wait_empty(hw, wait_time);
-			if (rc)
-				printk(KERN_ERR "%s() txwait timeout=%ums "
-					"Retry:%u/%u\n", __func__, timeout,
-					tx_wait_attempts - iter + 1,
-					tx_wait_attempts);
-
-		} while (rc && --iter);
-
-		rc = iter ? 0 : -ETIMEDOUT;
-	}
-	if (!rc)
-		rc = worker->wfunc(wt);
-
-	spin_lock_irq(&priv->tx_lock);
-	priv->inconfig = false;
-	if (priv->pending_tx_pkts && priv->radio_state)
-		mwl8k_tx_start(priv);
-	spin_unlock_irq(&priv->tx_lock);
-	ieee80211_wake_queues(hw);
-
-	worker->rc = rc;
-	if (worker->options & MWL8K_WQ_SLEEP)
-		complete(worker->cmd_wait);
-
-	if (worker->options & MWL8K_WQ_FREE_WORKSTRUCT)
-		kfree(wt);
-}
-
-static int mwl8k_queue_work(struct ieee80211_hw *hw,
-				struct mwl8k_work_struct *worker,
-				struct workqueue_struct *wqueue,
-				int (*wfunc)(struct work_struct *w))
-{
-	unsigned long timeout = 0;
-	int rc = 0;
-
-	DECLARE_COMPLETION_ONSTACK(cmd_wait);
-
-	if (!worker->timeout_ms)
-		worker->timeout_ms = MWL8K_CONFIG_TIMEOUT_MS;
-
-	if (!worker->options)
-		worker->options = MWL8K_WQ_DEFAULT_OPTIONS;
-
-	if (!worker->txwait_attempts)
-		worker->txwait_attempts = MWL8K_WQ_TXWAIT_ATTEMPTS;
-
-	if (!worker->tx_timeout_ms)
-		worker->tx_timeout_ms = MWL8K_TXWAIT_MS;
-
-	worker->hw = hw;
-	worker->cmd_wait = &cmd_wait;
-	worker->rc = 1;
-	worker->wfunc = wfunc;
-
-	INIT_WORK(&worker->wt, mwl8k_config_thread);
-	queue_work(wqueue, &worker->wt);
-
-	if (worker->options & MWL8K_WQ_POST_REQUEST) {
-		rc = 0;
-	} else {
-		if (worker->options & MWL8K_WQ_SPIN) {
-			timeout = worker->timeout_ms;
-			while (timeout && (worker->rc > 0)) {
-				mdelay(1);
-				timeout--;
-			}
-		} else if (worker->options & MWL8K_WQ_SLEEP)
-			timeout = wait_for_completion_timeout(&cmd_wait,
-				msecs_to_jiffies(worker->timeout_ms));
-
-		if (timeout)
-			rc = worker->rc;
-		else {
-			cancel_work_sync(&worker->wt);
-			rc = -ETIMEDOUT;
-		}
-	}
-
-	return rc;
-}
-
-struct mwl8k_start_worker {
-	struct mwl8k_work_struct header;
-};
-
-static int mwl8k_start_wt(struct work_struct *wt)
-{
-	struct mwl8k_start_worker *worker = (struct mwl8k_start_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
-	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
-
-	if (priv->vif != NULL) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Turn on radio */
-	if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Purge TX/RX HW queues */
-	if (mwl8k_cmd_set_pre_scan(hw)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	if (mwl8k_cmd_set_post_scan(hw, "\x00\x00\x00\x00\x00\x00")) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Enable firmware rate adaptation */
-	if (mwl8k_cmd_setrateadaptmode(hw, 0)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Disable WMM. WMM gets enabled when stack sends WMM parms */
-	if (mwl8k_set_wmm(hw, MWL8K_WMM_DISABLE)) {
-		rc = -EIO;
-		goto mwl8k_start_exit;
-	}
-
-	/* Disable sniffer mode */
-	if (mwl8k_enable_sniffer(hw, 0))
-		rc = -EIO;
-
-mwl8k_start_exit:
-	return rc;
-}
-
 static int mwl8k_start(struct ieee80211_hw *hw)
 {
-	struct mwl8k_start_worker *worker;
 	struct mwl8k_priv *priv = hw->priv;
 	int rc;
 
-	/* Enable tx reclaim tasklet */
-	tasklet_enable(&priv->tx_reclaim_task);
-
 	rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
 			 IRQF_SHARED, MWL8K_NAME, hw);
 	if (rc) {
 		printk(KERN_ERR "%s: failed to register IRQ handler\n",
 		       priv->name);
-		rc = -EIO;
-		goto mwl8k_start_disable_tasklet;
+		return -EIO;
 	}
 
-	/* Enable interrupts */
-	iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL) {
-		rc = -ENOMEM;
-		goto mwl8k_start_disable_irq;
-	}
+	/* Enable tx reclaim tasklet */
+	tasklet_enable(&priv->tx_reclaim_task);
 
-	rc = mwl8k_queue_work(hw, &worker->header,
-			      priv->config_wq, mwl8k_start_wt);
-	kfree(worker);
-	if (!rc)
-		return rc;
+	/* Enable interrupts */
+	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 
-	if (rc == -ETIMEDOUT)
-		printk(KERN_ERR "%s() timed out\n", __func__);
+	rc = mwl8k_fw_lock(hw);
+	if (!rc) {
+		rc = mwl8k_cmd_802_11_radio_enable(hw);
 
-	rc = -EIO;
+		if (!rc)
+			rc = mwl8k_cmd_set_pre_scan(hw);
 
-mwl8k_start_disable_irq:
-	spin_lock_irq(&priv->tx_lock);
-	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-	spin_unlock_irq(&priv->tx_lock);
-	free_irq(priv->pdev->irq, hw);
+		if (!rc)
+			rc = mwl8k_cmd_set_post_scan(hw,
+					"\x00\x00\x00\x00\x00\x00");
 
-mwl8k_start_disable_tasklet:
-	tasklet_disable(&priv->tx_reclaim_task);
+		if (!rc)
+			rc = mwl8k_cmd_setrateadaptmode(hw, 0);
 
-	return rc;
-}
+		if (!rc)
+			rc = mwl8k_set_wmm(hw, 0);
 
-struct mwl8k_stop_worker {
-	struct mwl8k_work_struct header;
-};
+		if (!rc)
+			rc = mwl8k_enable_sniffer(hw, 0);
 
-static int mwl8k_stop_wt(struct work_struct *wt)
-{
-	struct mwl8k_stop_worker *worker = (struct mwl8k_stop_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
-	int rc;
+		mwl8k_fw_unlock(hw);
+	}
 
-	rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+	if (rc) {
+		iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+		free_irq(priv->pdev->irq, hw);
+		tasklet_disable(&priv->tx_reclaim_task);
+	}
 
 	return rc;
 }
 
 static void mwl8k_stop(struct ieee80211_hw *hw)
 {
-	int rc;
-	struct mwl8k_stop_worker *worker;
 	struct mwl8k_priv *priv = hw->priv;
 	int i;
 
-	if (priv->vif != NULL)
-		return;
+	mwl8k_cmd_802_11_radio_disable(hw);
 
 	ieee80211_stop_queues(hw);
 
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return;
-
-	rc = mwl8k_queue_work(hw, &worker->header,
-			      priv->config_wq, mwl8k_stop_wt);
-	kfree(worker);
-	if (rc == -ETIMEDOUT)
-		printk(KERN_ERR "%s() timed out\n", __func__);
-
 	/* Disable interrupts */
-	spin_lock_irq(&priv->tx_lock);
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-	spin_unlock_irq(&priv->tx_lock);
 	free_irq(priv->pdev->irq, hw);
 
 	/* Stop finalize join worker */
@@ -2978,8 +2523,7 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
 	/*
 	 * We only support managed interfaces for now.
 	 */
-	if (conf->type != NL80211_IFTYPE_STATION &&
-	    conf->type != NL80211_IFTYPE_MONITOR)
+	if (conf->type != NL80211_IFTYPE_STATION)
 		return -EINVAL;
 
 	/* Clean out driver private area */
@@ -2987,13 +2531,13 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
 	memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
 
 	/* Save the mac address */
-	memcpy(mwl8k_vif->mac_addr, conf->mac_addr, IEEE80211_ADDR_LEN);
+	memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN);
 
 	/* Back pointer to parent config block */
 	mwl8k_vif->priv = priv;
 
 	/* Setup initial PHY parameters */
-	memcpy(mwl8k_vif->legacy_rates ,
+	memcpy(mwl8k_vif->legacy_rates,
 		priv->rates, sizeof(mwl8k_vif->legacy_rates));
 	mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates);
 
@@ -3017,213 +2561,148 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
 	priv->vif = NULL;
 }
 
-struct mwl8k_config_worker {
-	struct mwl8k_work_struct header;
-	u32 changed;
-};
-
-static int mwl8k_config_wt(struct work_struct *wt)
+static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
 {
-	struct mwl8k_config_worker *worker =
-		(struct mwl8k_config_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
 	struct ieee80211_conf *conf = &hw->conf;
 	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
+	int rc;
 
-	if (!conf->radio_enabled) {
-		mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+	if (conf->flags & IEEE80211_CONF_IDLE) {
+		mwl8k_cmd_802_11_radio_disable(hw);
 		priv->current_channel = NULL;
-		rc = 0;
-		goto mwl8k_config_exit;
+		return 0;
 	}
 
-	if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
-		rc = -EINVAL;
-		goto mwl8k_config_exit;
-	}
+	rc = mwl8k_fw_lock(hw);
+	if (rc)
+		return rc;
 
-	priv->current_channel = conf->channel;
+	rc = mwl8k_cmd_802_11_radio_enable(hw);
+	if (rc)
+		goto out;
 
-	if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) {
-		rc = -EINVAL;
-		goto mwl8k_config_exit;
-	}
+	rc = mwl8k_cmd_set_rf_channel(hw, conf->channel);
+	if (rc)
+		goto out;
+
+	priv->current_channel = conf->channel;
 
 	if (conf->power_level > 18)
 		conf->power_level = 18;
-	if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) {
-		rc = -EINVAL;
-		goto mwl8k_config_exit;
-	}
+	rc = mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level);
+	if (rc)
+		goto out;
 
 	if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
 		rc = -EINVAL;
 
-mwl8k_config_exit:
+out:
+	mwl8k_fw_unlock(hw);
+
 	return rc;
 }
 
-static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
+static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   struct ieee80211_bss_conf *info,
+				   u32 changed)
 {
-	int rc = 0;
-	struct mwl8k_config_worker *worker;
 	struct mwl8k_priv *priv = hw->priv;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
-
-	worker->changed = changed;
-	rc = mwl8k_queue_work(hw, &worker->header,
-			      priv->config_wq, mwl8k_config_wt);
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out.\n", __func__);
-		rc = -EINVAL;
-	}
-
-	kfree(worker);
-
-	/*
-	 * mac80211 will crash on anything other than -EINVAL on
-	 * error. Looks like wireless extensions which calls mac80211
-	 * may be the actual culprit...
-	 */
-	return rc ? -EINVAL : 0;
-}
-
-struct mwl8k_bss_info_changed_worker {
-	struct mwl8k_work_struct header;
-	struct ieee80211_vif *vif;
-	struct ieee80211_bss_conf *info;
-	u32 changed;
-};
-
-static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
-{
-	struct mwl8k_bss_info_changed_worker *worker =
-		(struct mwl8k_bss_info_changed_worker *)wt;
-	struct ieee80211_hw *hw = worker->header.hw;
-	struct ieee80211_vif *vif = worker->vif;
-	struct ieee80211_bss_conf *info = worker->info;
-	u32 changed;
+	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
 	int rc;
 
-	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+	if (changed & BSS_CHANGED_BSSID)
+		memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
+
+	if ((changed & BSS_CHANGED_ASSOC) == 0)
+		return;
 
-	changed = worker->changed;
 	priv->capture_beacon = false;
 
+	rc = mwl8k_fw_lock(hw);
+	if (rc)
+		return;
+
 	if (info->assoc) {
 		memcpy(&mwl8k_vif->bss_info, info,
 			sizeof(struct ieee80211_bss_conf));
 
 		/* Install rates */
-		if (mwl8k_update_rateset(hw, vif))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_update_rateset(hw, vif);
+		if (rc)
+			goto out;
 
 		/* Turn on rate adaptation */
-		if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
-			MWL8K_UCAST_RATE, NULL))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
+			MWL8K_UCAST_RATE, NULL);
+		if (rc)
+			goto out;
 
 		/* Set radio preamble */
-		if (mwl8k_set_radio_preamble(hw,
-				info->use_short_preamble))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_set_radio_preamble(hw, info->use_short_preamble);
+		if (rc)
+			goto out;
 
 		/* Set slot time */
-		if (mwl8k_cmd_set_slot(hw, info->use_short_slot ?
-				MWL8K_SHORT_SLOTTIME : MWL8K_LONG_SLOTTIME))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_set_slot(hw, info->use_short_slot);
+		if (rc)
+			goto out;
 
 		/* Update peer rate info */
-		if (mwl8k_cmd_update_sta_db(hw, vif,
-				MWL8K_STA_DB_MODIFY_ENTRY))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_update_sta_db(hw, vif,
+				MWL8K_STA_DB_MODIFY_ENTRY);
+		if (rc)
+			goto out;
 
 		/* Set AID */
-		if (mwl8k_cmd_set_aid(hw, vif))
-			goto mwl8k_bss_info_changed_exit;
+		rc = mwl8k_cmd_set_aid(hw, vif);
+		if (rc)
+			goto out;
 
 		/*
 		 * Finalize the join.  Tell rx handler to process
 		 * next beacon from our BSSID.
 		 */
-		memcpy(priv->capture_bssid,
-				mwl8k_vif->bssid, IEEE80211_ADDR_LEN);
+		memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN);
 		priv->capture_beacon = true;
 	} else {
-		mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
+		rc = mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
 		memset(&mwl8k_vif->bss_info, 0,
 			sizeof(struct ieee80211_bss_conf));
-		memset(mwl8k_vif->bssid, 0, IEEE80211_ADDR_LEN);
+		memset(mwl8k_vif->bssid, 0, ETH_ALEN);
 	}
 
-mwl8k_bss_info_changed_exit:
-	rc = 0;
-	return rc;
+out:
+	mwl8k_fw_unlock(hw);
 }
 
-static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
-				   struct ieee80211_vif *vif,
-				   struct ieee80211_bss_conf *info,
-				   u32 changed)
+static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
+				   int mc_count, struct dev_addr_list *mclist)
 {
-	struct mwl8k_bss_info_changed_worker *worker;
-	struct mwl8k_priv *priv = hw->priv;
-	struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
-	int rc;
-
-	if (changed & BSS_CHANGED_BSSID)
-		memcpy(mv_vif->bssid, info->bssid, IEEE80211_ADDR_LEN);
-
-	if ((changed & BSS_CHANGED_ASSOC) == 0)
-		return;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return;
+	struct mwl8k_cmd_pkt *cmd;
 
-	worker->vif = vif;
-	worker->info = info;
-	worker->changed = changed;
-	rc = mwl8k_queue_work(hw, &worker->header,
-			      priv->config_wq,
-			      mwl8k_bss_info_changed_wt);
-	kfree(worker);
-	if (rc == -ETIMEDOUT)
-		printk(KERN_ERR "%s() timed out\n", __func__);
-}
-
-struct mwl8k_configure_filter_worker {
-	struct mwl8k_work_struct header;
-	unsigned int changed_flags;
-	unsigned int *total_flags;
-	int mc_count;
-	struct dev_addr_list *mclist;
-};
+	cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
 
-#define MWL8K_SUPPORTED_IF_FLAGS	FIF_BCN_PRBRESP_PROMISC
+	return (unsigned long)cmd;
+}
 
-static int mwl8k_configure_filter_wt(struct work_struct *wt)
+static void mwl8k_configure_filter(struct ieee80211_hw *hw,
+				   unsigned int changed_flags,
+				   unsigned int *total_flags,
+				   u64 multicast)
 {
-	struct mwl8k_configure_filter_worker *worker =
-		(struct mwl8k_configure_filter_worker *)wt;
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_cmd_pkt *multicast_adr_cmd;
 
-	struct ieee80211_hw *hw = worker->header.hw;
-	unsigned int changed_flags = worker->changed_flags;
-	unsigned int *total_flags = worker->total_flags;
-	int mc_count = worker->mc_count;
-	struct dev_addr_list *mclist = worker->mclist;
+	/* Clear unsupported feature flags */
+	*total_flags &= FIF_BCN_PRBRESP_PROMISC;
 
-	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
+	if (mwl8k_fw_lock(hw))
+		return;
 
 	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
 		if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
-			rc = mwl8k_cmd_set_pre_scan(hw);
+			mwl8k_cmd_set_pre_scan(hw);
 		else {
 			u8 *bssid;
 
@@ -3231,151 +2710,45 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)
 			if (priv->vif != NULL)
 				bssid = MWL8K_VIF(priv->vif)->bssid;
 
-			rc = mwl8k_cmd_set_post_scan(hw, bssid);
+			mwl8k_cmd_set_post_scan(hw, bssid);
 		}
 	}
 
-	if (rc)
-		goto mwl8k_configure_filter_exit;
-	if (mc_count) {
-		mc_count = mc_count < priv->num_mcaddrs ?
-				mc_count : priv->num_mcaddrs;
-		rc = mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
-		if (rc)
-			printk(KERN_ERR
-			"%s()Error setting multicast addresses\n",
-			__func__);
+	multicast_adr_cmd = (void *)(unsigned long)multicast;
+	if (multicast_adr_cmd != NULL) {
+		mwl8k_post_cmd(hw, multicast_adr_cmd);
+		kfree(multicast_adr_cmd);
 	}
 
-mwl8k_configure_filter_exit:
-	return rc;
-}
-
-static void mwl8k_configure_filter(struct ieee80211_hw *hw,
-				   unsigned int changed_flags,
-				   unsigned int *total_flags,
-				   int mc_count,
-				   struct dev_addr_list *mclist)
-{
-
-	struct mwl8k_configure_filter_worker *worker;
-	struct mwl8k_priv *priv = hw->priv;
-
-	/* Clear unsupported feature flags */
-	*total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
-
-	if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS) && !mc_count)
-		return;
-
-	worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
-	if (worker == NULL)
-		return;
-
-	worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY;
-	worker->changed_flags = changed_flags;
-	worker->total_flags = total_flags;
-	worker->mc_count = mc_count;
-	worker->mclist = mclist;
-
-	mwl8k_queue_work(hw, &worker->header, priv->config_wq,
-			 mwl8k_configure_filter_wt);
-}
-
-struct mwl8k_set_rts_threshold_worker {
-	struct mwl8k_work_struct header;
-	u32 value;
-};
-
-static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
-{
-	struct mwl8k_set_rts_threshold_worker *worker =
-		(struct mwl8k_set_rts_threshold_worker *)wt;
-
-	struct ieee80211_hw *hw = worker->header.hw;
-	u16 threshold = (u16)(worker->value);
-	int rc;
-
-	rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
-
-	return rc;
+	mwl8k_fw_unlock(hw);
 }
 
 static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 {
-	int rc;
-	struct mwl8k_set_rts_threshold_worker *worker;
-	struct mwl8k_priv *priv = hw->priv;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
-
-	worker->value = value;
-
-	rc = mwl8k_queue_work(hw, &worker->header,
-			      priv->config_wq,
-			      mwl8k_set_rts_threshold_wt);
-	kfree(worker);
-
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out\n", __func__);
-		rc = -EINVAL;
-	}
-
-	return rc;
-}
-
-struct mwl8k_conf_tx_worker {
-	struct mwl8k_work_struct header;
-	u16 queue;
-	const struct ieee80211_tx_queue_params *params;
-};
-
-static int mwl8k_conf_tx_wt(struct work_struct *wt)
-{
-	struct mwl8k_conf_tx_worker *worker =
-	(struct mwl8k_conf_tx_worker *)wt;
-
-	struct ieee80211_hw *hw = worker->header.hw;
-	u16 queue = worker->queue;
-	const struct ieee80211_tx_queue_params *params = worker->params;
-
-	struct mwl8k_priv *priv = hw->priv;
-	int rc = 0;
-
-	if (priv->wmm_mode == MWL8K_WMM_DISABLE)
-		if (mwl8k_set_wmm(hw, MWL8K_WMM_ENABLE)) {
-			rc = -EINVAL;
-			goto mwl8k_conf_tx_exit;
-	}
-
-	if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
-		params->cw_max, params->aifs, params->txop))
-			rc = -EINVAL;
-mwl8k_conf_tx_exit:
-	return rc;
+	return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value);
 }
 
 static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
 			 const struct ieee80211_tx_queue_params *params)
 {
-	int rc;
-	struct mwl8k_conf_tx_worker *worker;
 	struct mwl8k_priv *priv = hw->priv;
+	int rc;
 
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
+	rc = mwl8k_fw_lock(hw);
+	if (!rc) {
+		if (!priv->wmm_enabled)
+			rc = mwl8k_set_wmm(hw, 1);
 
-	worker->queue = queue;
-	worker->params = params;
-	rc = mwl8k_queue_work(hw, &worker->header,
-			      priv->config_wq, mwl8k_conf_tx_wt);
-	kfree(worker);
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out\n", __func__);
-		rc = -EINVAL;
+		if (!rc)
+			rc = mwl8k_set_edca_params(hw, queue,
+						   params->cw_min,
+						   params->cw_max,
+						   params->aifs,
+						   params->txop);
+
+		mwl8k_fw_unlock(hw);
 	}
+
 	return rc;
 }
 
@@ -3393,44 +2766,14 @@ static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
 			sizeof(struct ieee80211_tx_queue_stats));
 	}
 	spin_unlock_bh(&priv->tx_lock);
-	return 0;
-}
-
-struct mwl8k_get_stats_worker {
-	struct mwl8k_work_struct header;
-	struct ieee80211_low_level_stats *stats;
-};
-
-static int mwl8k_get_stats_wt(struct work_struct *wt)
-{
-	struct mwl8k_get_stats_worker *worker =
-		(struct mwl8k_get_stats_worker *)wt;
 
-	return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats);
+	return 0;
 }
 
 static int mwl8k_get_stats(struct ieee80211_hw *hw,
 			   struct ieee80211_low_level_stats *stats)
 {
-	int rc;
-	struct mwl8k_get_stats_worker *worker;
-	struct mwl8k_priv *priv = hw->priv;
-
-	worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-	if (worker == NULL)
-		return -ENOMEM;
-
-	worker->stats = stats;
-	rc = mwl8k_queue_work(hw, &worker->header,
-			      priv->config_wq, mwl8k_get_stats_wt);
-
-	kfree(worker);
-	if (rc == -ETIMEDOUT) {
-		printk(KERN_ERR "%s() timed out\n", __func__);
-		rc = -EINVAL;
-	}
-
-	return rc;
+	return mwl8k_cmd_802_11_get_stat(hw, stats);
 }
 
 static const struct ieee80211_ops mwl8k_ops = {
@@ -3441,6 +2784,7 @@ static const struct ieee80211_ops mwl8k_ops = {
 	.remove_interface	= mwl8k_remove_interface,
 	.config			= mwl8k_config,
 	.bss_info_changed	= mwl8k_bss_info_changed,
+	.prepare_multicast	= mwl8k_prepare_multicast,
 	.configure_filter	= mwl8k_configure_filter,
 	.set_rts_threshold	= mwl8k_set_rts_threshold,
 	.conf_tx		= mwl8k_conf_tx,
@@ -3458,12 +2802,9 @@ static void mwl8k_tx_reclaim_handler(unsigned long data)
 	for (i = 0; i < MWL8K_TX_QUEUES; i++)
 		mwl8k_txq_reclaim(hw, i, 0);
 
-	if (priv->tx_wait != NULL) {
-		int count = mwl8k_txq_busy(priv);
-		if (count == 0) {
-			complete(priv->tx_wait);
-			priv->tx_wait = NULL;
-		}
+	if (priv->tx_wait != NULL && mwl8k_txq_busy(priv) == 0) {
+		complete(priv->tx_wait);
+		priv->tx_wait = NULL;
 	}
 	spin_unlock_bh(&priv->tx_lock);
 }
@@ -3473,7 +2814,7 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
 	struct mwl8k_priv *priv =
 		container_of(work, struct mwl8k_priv, finalize_join_worker);
 	struct sk_buff *skb = priv->beacon_skb;
-	u8 dtim = (MWL8K_VIF(priv->vif))->bss_info.dtim_period;
+	u8 dtim = MWL8K_VIF(priv->vif)->bss_info.dtim_period;
 
 	mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim);
 	dev_kfree_skb(skb);
@@ -3484,12 +2825,16 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
 static int __devinit mwl8k_probe(struct pci_dev *pdev,
 				 const struct pci_device_id *id)
 {
+	static int printed_version = 0;
 	struct ieee80211_hw *hw;
 	struct mwl8k_priv *priv;
-	DECLARE_MAC_BUF(mac);
 	int rc;
 	int i;
-	u8 *fw;
+
+	if (!printed_version) {
+		printk(KERN_INFO "%s version %s\n", MWL8K_DESC, MWL8K_VERSION);
+		printed_version = 1;
+	}
 
 	rc = pci_enable_device(pdev);
 	if (rc) {
@@ -3517,16 +2862,10 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	priv = hw->priv;
 	priv->hw = hw;
 	priv->pdev = pdev;
-	priv->hostcmd_wait = NULL;
-	priv->tx_wait = NULL;
-	priv->inconfig = false;
-	priv->wep_enabled = 0;
-	priv->wmm_mode = false;
+	priv->wmm_enabled = false;
 	priv->pending_tx_pkts = 0;
 	strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
 
-	spin_lock_init(&priv->fw_lock);
-
 	SET_IEEE80211_DEV(hw, &pdev->dev);
 	pci_set_drvdata(pdev, hw);
 
@@ -3558,17 +2897,16 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 
 	hw->queues = MWL8K_TX_QUEUES;
 
-	hw->wiphy->interface_modes =
-		BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_MONITOR);
+	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 
 	/* Set rssi and noise values to dBm */
-	hw->flags |= (IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM);
+	hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
 	hw->vif_data_size = sizeof(struct mwl8k_vif);
 	priv->vif = NULL;
 
 	/* Set default radio state and preamble */
-	priv->radio_preamble = MWL8K_RADIO_DEFAULT_PREAMBLE;
-	priv->radio_state = MWL8K_RADIO_DISABLE;
+	priv->radio_on = 0;
+	priv->radio_short_preamble = 0;
 
 	/* Finalize join worker */
 	INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
@@ -3593,6 +2931,12 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 		goto err_iounmap;
 	rxq_refill(hw, 0, INT_MAX);
 
+	mutex_init(&priv->fw_mutex);
+	priv->fw_mutex_owner = NULL;
+	priv->fw_mutex_depth = 0;
+	priv->tx_wait = NULL;
+	priv->hostcmd_wait = NULL;
+
 	spin_lock_init(&priv->tx_lock);
 
 	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
@@ -3602,8 +2946,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	}
 
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
-	priv->int_mask = 0;
-	iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
 	iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
 
@@ -3640,9 +2983,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	 * commands use interrupts and avoids polling.  Disable
 	 * interrupts when done.
 	 */
-	priv->int_mask |= MWL8K_A2H_EVENTS;
-
-	iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
 
 	/* Get config data, mac addrs etc */
 	rc = mwl8k_cmd_get_hw_spec(hw);
@@ -3652,16 +2993,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 	}
 
 	/* Turn radio off */
-	rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE);
+	rc = mwl8k_cmd_802_11_radio_disable(hw);
 	if (rc) {
 		printk(KERN_ERR "%s: Cannot disable\n", priv->name);
 		goto err_stop_firmware;
 	}
 
 	/* Disable interrupts */
-	spin_lock_irq(&priv->tx_lock);
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-	spin_unlock_irq(&priv->tx_lock);
 	free_irq(priv->pdev->irq, hw);
 
 	rc = ieee80211_register_hw(hw);
@@ -3670,13 +3009,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
 		goto err_stop_firmware;
 	}
 
-	fw = (u8 *)&priv->fw_rev;
-	printk(KERN_INFO "%s: 88W%u %s\n", priv->name, priv->part_num,
-		MWL8K_DESC);
-	printk(KERN_INFO "%s: Driver Ver:%s  Firmware Ver:%u.%u.%u.%u\n",
-		priv->name, MWL8K_VERSION, fw[3], fw[2], fw[1], fw[0]);
-	printk(KERN_INFO "%s: MAC Address: %s\n", priv->name,
-	       print_mac(mac, hw->wiphy->perm_addr));
+	printk(KERN_INFO "%s: 88w%u v%d, %pM, firmware version %u.%u.%u.%u\n",
+	       wiphy_name(hw->wiphy), priv->part_num, priv->hw_rev,
+	       hw->wiphy->perm_addr,
+	       (priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
+	       (priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
 
 	return 0;
 
@@ -3685,9 +3022,7 @@ err_stop_firmware:
 	mwl8k_release_firmware(priv);
 
 err_free_irq:
-	spin_lock_irq(&priv->tx_lock);
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-	spin_unlock_irq(&priv->tx_lock);
 	free_irq(priv->pdev->irq, hw);
 
 err_free_queues:
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index d63c899..9498b46 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -203,7 +203,8 @@ static int netwave_open(struct net_device *dev);  /* Open the device */
 static int netwave_close(struct net_device *dev); /* Close the device */
 
 /* Packet transmission and Packet reception */
-static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t netwave_start_xmit( struct sk_buff *skb,
+					     struct net_device *dev);
 static int netwave_rx( struct net_device *dev);
 
 /* Interrupt routines */
@@ -1026,7 +1027,8 @@ static int netwave_hw_xmit(unsigned char* data, int len,
     return 0;
 }
 
-static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
+static netdev_tx_t netwave_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev) {
 	/* This flag indicate that the hardware can't perform a transmission.
 	 * Theoritically, NET3 check it before sending a packet to the driver,
 	 * but in fact it never do that and pool continuously.
@@ -1047,7 +1049,7 @@ static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
     }
     dev_kfree_skb(skb);
     
-    return 0;
+    return NETDEV_TX_OK;
 } /* netwave_start_xmit */
 
 /*
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index 44411eb..83b635f 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -1,6 +1,7 @@
 config HERMES
 	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
 	depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
+	depends on CFG80211
 	select WIRELESS_EXT
 	select FW_LOADER
 	select CRYPTO
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
index 1fc7409..9abd632 100644
--- a/drivers/net/wireless/orinoco/Makefile
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for the orinoco wireless device drivers.
 #
-orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o
+orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o cfg.o
 
 obj-$(CONFIG_HERMES)		+= orinoco.o
 obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index 8c4065f..c60df2c 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -27,6 +27,7 @@
 struct airport {
 	struct macio_dev *mdev;
 	void __iomem *vaddr;
+	unsigned int irq;
 	int irq_requested;
 	int ndev_registered;
 };
@@ -34,8 +35,9 @@ struct airport {
 static int
 airport_suspend(struct macio_dev *mdev, pm_message_t state)
 {
-	struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
+	struct net_device *dev = priv->ndev;
+	struct airport *card = priv->card;
 	unsigned long flags;
 	int err;
 
@@ -48,18 +50,10 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
 		return 0;
 	}
 
-	err = __orinoco_down(dev);
-	if (err)
-		printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
-		       dev->name, err);
-
-	netif_device_detach(dev);
-
-	priv->hw_unavailable++;
-
+	orinoco_down(priv);
 	orinoco_unlock(priv, &flags);
 
-	disable_irq(dev->irq);
+	disable_irq(card->irq);
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
 			  macio_get_of_node(mdev), 0, 0);
 
@@ -69,8 +63,9 @@ airport_suspend(struct macio_dev *mdev, pm_message_t state)
 static int
 airport_resume(struct macio_dev *mdev)
 {
-	struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
+	struct net_device *dev = priv->ndev;
+	struct airport *card = priv->card;
 	unsigned long flags;
 	int err;
 
@@ -80,47 +75,27 @@ airport_resume(struct macio_dev *mdev)
 			  macio_get_of_node(mdev), 0, 1);
 	msleep(200);
 
-	enable_irq(dev->irq);
-
-	err = orinoco_reinit_firmware(dev);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
-		       dev->name, err);
-		return 0;
-	}
+	enable_irq(card->irq);
 
 	spin_lock_irqsave(&priv->lock, flags);
-
-	netif_device_attach(dev);
-
-	priv->hw_unavailable--;
-
-	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(dev);
-		if (err)
-			printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
-			       dev->name, err);
-	}
-
-
+	err = orinoco_up(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return 0;
+	return err;
 }
 
 static int
 airport_detach(struct macio_dev *mdev)
 {
-	struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev);
 	struct airport *card = priv->card;
 
 	if (card->ndev_registered)
-		unregister_netdev(dev);
+		orinoco_if_del(priv);
 	card->ndev_registered = 0;
 
 	if (card->irq_requested)
-		free_irq(dev->irq, dev);
+		free_irq(card->irq, priv);
 	card->irq_requested = 0;
 
 	if (card->vaddr)
@@ -134,7 +109,7 @@ airport_detach(struct macio_dev *mdev)
 	ssleep(1);
 
 	macio_set_drvdata(mdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
 	return 0;
 }
@@ -146,7 +121,6 @@ static int airport_hard_reset(struct orinoco_private *priv)
 	 * re-initialize properly, it falls in a screaming heap
 	 * shortly afterwards. */
 #if 0
-	struct net_device *dev = priv->ndev;
 	struct airport *card = priv->card;
 
 	/* Vitally important.  If we don't do this it seems we get an
@@ -154,7 +128,7 @@ static int airport_hard_reset(struct orinoco_private *priv)
 	 * hw_unavailable is already set it doesn't get ACKed, we get
 	 * into an interrupt loop and the PMU decides to turn us
 	 * off. */
-	disable_irq(dev->irq);
+	disable_irq(card->irq);
 
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
 			  macio_get_of_node(card->mdev), 0, 0);
@@ -163,7 +137,7 @@ static int airport_hard_reset(struct orinoco_private *priv)
 			  macio_get_of_node(card->mdev), 0, 1);
 	ssleep(1);
 
-	enable_irq(dev->irq);
+	enable_irq(card->irq);
 	ssleep(1);
 #endif
 
@@ -174,7 +148,6 @@ static int
 airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 {
 	struct orinoco_private *priv;
-	struct net_device *dev;
 	struct airport *card;
 	unsigned long phys_addr;
 	hermes_t *hw;
@@ -185,33 +158,29 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	}
 
 	/* Allocate space for private device-specific data */
-	dev = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
-			       airport_hard_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
+				airport_hard_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		return -ENODEV;
 	}
-	priv = netdev_priv(dev);
 	card = priv->card;
 
 	hw = &priv->hw;
 	card->mdev = mdev;
 
-	if (macio_request_resource(mdev, 0, "airport")) {
+	if (macio_request_resource(mdev, 0, DRIVER_NAME)) {
 		printk(KERN_ERR PFX "can't request IO resource !\n");
-		free_orinocodev(dev);
+		free_orinocodev(priv);
 		return -EBUSY;
 	}
 
-	SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
-
-	macio_set_drvdata(mdev, dev);
+	macio_set_drvdata(mdev, priv);
 
 	/* Setup interrupts & base address */
-	dev->irq = macio_irq(mdev, 0);
+	card->irq = macio_irq(mdev, 0);
 	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
 	printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
-	dev->base_addr = phys_addr;
 	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
 	if (!card->vaddr) {
 		printk(KERN_ERR PFX "ioremap() failed\n");
@@ -228,18 +197,23 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
 	/* Reset it before we get the interrupt */
 	hermes_init(hw);
 
-	if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
-		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
+	if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
+		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq);
 		goto failed;
 	}
 	card->irq_requested = 1;
 
-	/* Tell the stack we exist */
-	if (register_netdev(dev) != 0) {
-		printk(KERN_ERR PFX "register_netdev() failed\n");
+	/* Initialise the main driver */
+	if (orinoco_init(priv) != 0) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto failed;
+	}
+
+	/* Register an interface with the stack */
+	if (orinoco_if_add(priv, phys_addr, card->irq) != 0) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto failed;
 	}
-	printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
 	card->ndev_registered = 1;
 	return 0;
  failed:
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
new file mode 100644
index 0000000..27f2d33
--- /dev/null
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -0,0 +1,203 @@
+/* cfg80211 support
+ *
+ * See copyright notice in main.c
+ */
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+#include "hw.h"
+#include "main.h"
+#include "orinoco.h"
+
+#include "cfg.h"
+
+/* Supported bitrates. Must agree with hw.c */
+static struct ieee80211_rate orinoco_rates[] = {
+	{ .bitrate = 10 },
+	{ .bitrate = 20 },
+	{ .bitrate = 55 },
+	{ .bitrate = 110 },
+};
+
+static const void * const orinoco_wiphy_privid = &orinoco_wiphy_privid;
+
+/* Called after orinoco_private is allocated. */
+void orinoco_wiphy_init(struct wiphy *wiphy)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+
+	wiphy->privid = orinoco_wiphy_privid;
+
+	set_wiphy_dev(wiphy, priv->dev);
+}
+
+/* Called after firmware is initialised */
+int orinoco_wiphy_register(struct wiphy *wiphy)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	int i, channels = 0;
+
+	if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
+		wiphy->max_scan_ssids = 1;
+	else
+		wiphy->max_scan_ssids = 0;
+
+	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+	/* TODO: should we set if we only have demo ad-hoc?
+	 *       (priv->has_port3)
+	 */
+	if (priv->has_ibss)
+		wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
+
+	if (!priv->broken_monitor || force_monitor)
+		wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
+
+	priv->band.bitrates = orinoco_rates;
+	priv->band.n_bitrates = ARRAY_SIZE(orinoco_rates);
+
+	/* Only support channels allowed by the card EEPROM */
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		if (priv->channel_mask & (1 << i)) {
+			priv->channels[i].center_freq =
+				ieee80211_dsss_chan_to_freq(i+1);
+			channels++;
+		}
+	}
+	priv->band.channels = priv->channels;
+	priv->band.n_channels = channels;
+
+	wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+	i = 0;
+	if (priv->has_wep) {
+		priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP40;
+		i++;
+
+		if (priv->has_big_wep) {
+			priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP104;
+			i++;
+		}
+	}
+	if (priv->has_wpa) {
+		priv->cipher_suites[i] = WLAN_CIPHER_SUITE_TKIP;
+		i++;
+	}
+	wiphy->cipher_suites = priv->cipher_suites;
+	wiphy->n_cipher_suites = i;
+
+	wiphy->rts_threshold = priv->rts_thresh;
+	if (!priv->has_mwo)
+		wiphy->frag_threshold = priv->frag_thresh;
+
+	return wiphy_register(wiphy);
+}
+
+static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,
+			      enum nl80211_iftype type, u32 *flags,
+			      struct vif_params *params)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	int err = 0;
+	unsigned long lock;
+
+	if (orinoco_lock(priv, &lock) != 0)
+		return -EBUSY;
+
+	switch (type) {
+	case NL80211_IFTYPE_ADHOC:
+		if (!priv->has_ibss && !priv->has_port3)
+			err = -EINVAL;
+		break;
+
+	case NL80211_IFTYPE_STATION:
+		break;
+
+	case NL80211_IFTYPE_MONITOR:
+		if (priv->broken_monitor && !force_monitor) {
+			printk(KERN_WARNING "%s: Monitor mode support is "
+			       "buggy in this firmware, not enabling\n",
+			       wiphy_name(wiphy));
+			err = -EINVAL;
+		}
+		break;
+
+	default:
+		err = -EINVAL;
+	}
+
+	if (!err) {
+		priv->iw_mode = type;
+		set_port_type(priv);
+		err = orinoco_commit(priv);
+	}
+
+	orinoco_unlock(priv, &lock);
+
+	return err;
+}
+
+static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
+			struct cfg80211_scan_request *request)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	int err;
+
+	if (!request)
+		return -EINVAL;
+
+	if (priv->scan_request && priv->scan_request != request)
+		return -EBUSY;
+
+	priv->scan_request = request;
+
+	err = orinoco_hw_trigger_scan(priv, request->ssids);
+
+	return err;
+}
+
+static int orinoco_set_channel(struct wiphy *wiphy,
+			struct ieee80211_channel *chan,
+			enum nl80211_channel_type channel_type)
+{
+	struct orinoco_private *priv = wiphy_priv(wiphy);
+	int err = 0;
+	unsigned long flags;
+	int channel;
+
+	if (!chan)
+		return -EINVAL;
+
+	if (channel_type != NL80211_CHAN_NO_HT)
+		return -EINVAL;
+
+	if (chan->band != IEEE80211_BAND_2GHZ)
+		return -EINVAL;
+
+	channel = ieee80211_freq_to_dsss_chan(chan->center_freq);
+
+	if ((channel < 1) || (channel > NUM_CHANNELS) ||
+	     !(priv->channel_mask & (1 << (channel-1))))
+		return -EINVAL;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	priv->channel = channel;
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
+		/* Fast channel change - no commit if successful */
+		hermes_t *hw = &priv->hw;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_SET_CHANNEL,
+					channel, NULL);
+	}
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+const struct cfg80211_ops orinoco_cfg_ops = {
+	.change_virtual_intf = orinoco_change_vif,
+	.set_channel = orinoco_set_channel,
+	.scan = orinoco_scan,
+};
diff --git a/drivers/net/wireless/orinoco/cfg.h b/drivers/net/wireless/orinoco/cfg.h
new file mode 100644
index 0000000..3ddc96a
--- /dev/null
+++ b/drivers/net/wireless/orinoco/cfg.h
@@ -0,0 +1,15 @@
+/* cfg80211 support.
+ *
+ * See copyright notice in main.c
+ */
+#ifndef ORINOCO_CFG_H
+#define ORINOCO_CFG_H
+
+#include <net/cfg80211.h>
+
+extern const struct cfg80211_ops orinoco_cfg_ops;
+
+void orinoco_wiphy_init(struct wiphy *wiphy);
+int orinoco_wiphy_register(struct wiphy *wiphy);
+
+#endif /* ORINOCO_CFG_H */
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
index 1084b43..1257250 100644
--- a/drivers/net/wireless/orinoco/fw.c
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -4,6 +4,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/firmware.h>
+#include <linux/device.h>
 
 #include "hermes.h"
 #include "hermes_dld.h"
@@ -99,7 +100,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 	const void *end;
 	const char *firmware;
 	const char *fw_err;
-	struct net_device *dev = priv->ndev;
+	struct device *dev = priv->dev;
 	int err = 0;
 
 	pda = kzalloc(fw->pda_size, GFP_KERNEL);
@@ -111,12 +112,11 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 	else
 		firmware = fw->sta_fw;
 
-	printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
-	       dev->name, firmware);
+	dev_dbg(dev, "Attempting to download firmware %s\n", firmware);
 
 	/* Read current plug data */
 	err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
-	printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
+	dev_dbg(dev, "Read PDA returned %d\n", err);
 	if (err)
 		goto free;
 
@@ -124,8 +124,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 		err = request_firmware(&fw_entry, firmware, priv->dev);
 
 		if (err) {
-			printk(KERN_ERR "%s: Cannot find firmware %s\n",
-			       dev->name, firmware);
+			dev_err(dev, "Cannot find firmware %s\n", firmware);
 			err = -ENOENT;
 			goto free;
 		}
@@ -136,16 +135,15 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 
 	fw_err = validate_fw(hdr, fw_entry->size);
 	if (fw_err) {
-		printk(KERN_WARNING "%s: Invalid firmware image detected (%s). "
-		       "Aborting download\n",
-		       dev->name, fw_err);
+		dev_warn(dev, "Invalid firmware image detected (%s). "
+			 "Aborting download\n", fw_err);
 		err = -EINVAL;
 		goto abort;
 	}
 
 	/* Enable aux port to allow programming */
 	err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
-	printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
+	dev_dbg(dev, "Program init returned %d\n", err);
 	if (err != 0)
 		goto abort;
 
@@ -156,7 +154,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 	end = fw_entry->data + fw_entry->size;
 
 	err = hermes_program(hw, first_block, end);
-	printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
+	dev_dbg(dev, "Program returned %d\n", err);
 	if (err != 0)
 		goto abort;
 
@@ -167,19 +165,18 @@ orinoco_dl_firmware(struct orinoco_private *priv,
 
 	err = hermes_apply_pda_with_defaults(hw, first_block, end, pda,
 					     &pda[fw->pda_size / sizeof(*pda)]);
-	printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
+	dev_dbg(dev, "Apply PDA returned %d\n", err);
 	if (err)
 		goto abort;
 
 	/* Tell card we've finished */
 	err = hermesi_program_end(hw);
-	printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
+	dev_dbg(dev, "Program end returned %d\n", err);
 	if (err != 0)
 		goto abort;
 
 	/* Check if we're running */
-	printk(KERN_DEBUG "%s: hermes_present returned %d\n",
-	       dev->name, hermes_present(hw));
+	dev_dbg(dev, "hermes_present returned %d\n", hermes_present(hw));
 
 abort:
 	/* If we requested the firmware, release it. */
@@ -282,14 +279,13 @@ static int
 symbol_dl_firmware(struct orinoco_private *priv,
 		   const struct fw_info *fw)
 {
-	struct net_device *dev = priv->ndev;
+	struct device *dev = priv->dev;
 	int ret;
 	const struct firmware *fw_entry;
 
 	if (!orinoco_cached_fw_get(priv, true)) {
 		if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
-			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-			       dev->name, fw->pri_fw);
+			dev_err(dev, "Cannot find firmware: %s\n", fw->pri_fw);
 			return -ENOENT;
 		}
 	} else
@@ -302,15 +298,13 @@ symbol_dl_firmware(struct orinoco_private *priv,
 	if (!orinoco_cached_fw_get(priv, true))
 		release_firmware(fw_entry);
 	if (ret) {
-		printk(KERN_ERR "%s: Primary firmware download failed\n",
-		       dev->name);
+		dev_err(dev, "Primary firmware download failed\n");
 		return ret;
 	}
 
 	if (!orinoco_cached_fw_get(priv, false)) {
 		if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
-			printk(KERN_ERR "%s: Cannot find firmware: %s\n",
-			       dev->name, fw->sta_fw);
+			dev_err(dev, "Cannot find firmware: %s\n", fw->sta_fw);
 			return -ENOENT;
 		}
 	} else
@@ -322,8 +316,7 @@ symbol_dl_firmware(struct orinoco_private *priv,
 	if (!orinoco_cached_fw_get(priv, false))
 		release_firmware(fw_entry);
 	if (ret) {
-		printk(KERN_ERR "%s: Secondary firmware download failed\n",
-		       dev->name);
+		dev_err(dev, "Secondary firmware download failed\n");
 	}
 
 	return ret;
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index f2c918c..1a2fca7 100644
--- a/drivers/net/wireless/orinoco/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
@@ -469,7 +469,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
 	u16 rlength, rtype;
 	unsigned nwords;
 
-	if ((bufsize < 0) || (bufsize % 2))
+	if (bufsize % 2)
 		return -EINVAL;
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h
index c78c442..2dddbb5 100644
--- a/drivers/net/wireless/orinoco/hermes.h
+++ b/drivers/net/wireless/orinoco/hermes.h
@@ -342,7 +342,7 @@ struct agere_ext_scan_info {
 	__le64	timestamp;
 	__le16	beacon_interval;
 	__le16	capabilities;
-	u8	data[316];
+	u8	data[0];
 } __attribute__ ((packed));
 
 #define HERMES_LINKSTATUS_NOT_CONNECTED   (0x0000)
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index a9ba195..a3eefe1 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -309,7 +309,7 @@ int hermes_read_pda(hermes_t *hw,
 
 	/* Open auxiliary port */
 	ret = hermes_aux_control(hw, 1);
-	printk(KERN_DEBUG PFX "AUX enable returned %d\n", ret);
+	pr_debug(PFX "AUX enable returned %d\n", ret);
 	if (ret)
 		return ret;
 
@@ -319,12 +319,12 @@ int hermes_read_pda(hermes_t *hw,
 
 	/* Close aux port */
 	ret = hermes_aux_control(hw, 0);
-	printk(KERN_DEBUG PFX "AUX disable returned %d\n", ret);
+	pr_debug(PFX "AUX disable returned %d\n", ret);
 
 	/* Check PDA length */
 	pda_size = le16_to_cpu(pda[0]);
-	printk(KERN_DEBUG PFX "Actual PDA length %d, Max allowed %d\n",
-	       pda_size, pda_len);
+	pr_debug(PFX "Actual PDA length %d, Max allowed %d\n",
+		 pda_size, pda_len);
 	if (pda_size > pda_len)
 		return -EINVAL;
 
@@ -422,20 +422,19 @@ int hermesi_program_init(hermes_t *hw, u32 offset)
 		return err;
 
 	err = hermes_aux_control(hw, 1);
-	printk(KERN_DEBUG PFX "AUX enable returned %d\n", err);
+	pr_debug(PFX "AUX enable returned %d\n", err);
 
 	if (err)
 		return err;
 
-	printk(KERN_DEBUG PFX "Enabling volatile, EP 0x%08x\n", offset);
+	pr_debug(KERN_DEBUG PFX "Enabling volatile, EP 0x%08x\n", offset);
 	err = hermes_doicmd_wait(hw,
 				 HERMES_PROGRAM_ENABLE_VOLATILE,
 				 offset & 0xFFFFu,
 				 offset >> 16,
 				 0,
 				 NULL);
-	printk(KERN_DEBUG PFX "PROGRAM_ENABLE returned %d\n",
-	       err);
+	pr_debug(PFX "PROGRAM_ENABLE returned %d\n", err);
 
 	return err;
 }
@@ -454,16 +453,16 @@ int hermesi_program_end(hermes_t *hw)
 
 	rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
 
-	printk(KERN_DEBUG PFX "PROGRAM_DISABLE returned %d, "
-	       "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
-	       rc, resp.resp0, resp.resp1, resp.resp2);
+	pr_debug(PFX "PROGRAM_DISABLE returned %d, "
+		 "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
+		 rc, resp.resp0, resp.resp1, resp.resp2);
 
 	if ((rc == 0) &&
 	    ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
 		rc = -EIO;
 
 	err = hermes_aux_control(hw, 0);
-	printk(KERN_DEBUG PFX "AUX disable returned %d\n", err);
+	pr_debug(PFX "AUX disable returned %d\n", err);
 
 	/* Acknowledge any outstanding command */
 	hermes_write_regn(hw, EVACK, 0xFFFF);
@@ -496,9 +495,8 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
 
 	while ((blkaddr != BLOCK_END) &&
 	       (((void *) blk + blklen) <= end)) {
-		printk(KERN_DEBUG PFX
-		       "Programming block of length %d to address 0x%08x\n",
-		       blklen, blkaddr);
+		pr_debug(PFX "Programming block of length %d "
+			 "to address 0x%08x\n", blklen, blkaddr);
 
 #if !LIMIT_PROGRAM_SIZE
 		/* wl_lkm driver splits this into writes of 2000 bytes */
@@ -510,10 +508,9 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
 		addr = blkaddr;
 
 		while (addr < (blkaddr + blklen)) {
-			printk(KERN_DEBUG PFX
-			       "Programming subblock of length %d "
-			       "to address 0x%08x. Data @ %p\n",
-			       len, addr, &blk->data[addr - blkaddr]);
+			pr_debug(PFX "Programming subblock of length %d "
+				 "to address 0x%08x. Data @ %p\n",
+				 len, addr, &blk->data[addr - blkaddr]);
 
 			hermes_aux_setaddr(hw, addr);
 			hermes_write_bytes(hw, HERMES_AUXDATA,
@@ -643,8 +640,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
 
 		pdi = hermes_find_pdi(first_pdi, record_id, pda_end);
 		if (pdi)
-			printk(KERN_DEBUG PFX "Found record 0x%04x at %p\n",
-			       record_id, pdi);
+			pr_debug(PFX "Found record 0x%04x at %p\n",
+				 record_id, pdi);
 
 		switch (record_id) {
 		case 0x110: /* Modem REFDAC values */
@@ -654,9 +651,9 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
 			default_pdi = NULL;
 			if (outdoor_pdi) {
 				pdi = outdoor_pdi;
-				printk(KERN_DEBUG PFX
-				       "Using outdoor record 0x%04x at %p\n",
-				       record_id + 1, pdi);
+				pr_debug(PFX
+					 "Using outdoor record 0x%04x at %p\n",
+					 record_id + 1, pdi);
 			}
 			break;
 		case 0x5: /*  HWIF Compatiblity */
@@ -684,9 +681,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
 		if (!pdi && default_pdi) {
 			/* Use default */
 			pdi = default_pdi;
-			printk(KERN_DEBUG PFX
-			       "Using default record 0x%04x at %p\n",
-			       record_id, pdi);
+			pr_debug(PFX "Using default record 0x%04x at %p\n",
+				 record_id, pdi);
 		}
 
 		if (pdi) {
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index b394627..359652d 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -3,16 +3,22 @@
  * See copyright notice in main.c
  */
 #include <linux/kernel.h>
+#include <linux/device.h>
 #include <linux/if_arp.h>
 #include <linux/ieee80211.h>
 #include <linux/wireless.h>
-
+#include <net/cfg80211.h>
 #include "hermes.h"
 #include "hermes_rid.h"
 #include "orinoco.h"
 
 #include "hw.h"
 
+#define SYMBOL_MAX_VER_LEN	(14)
+
+/* Symbol firmware has a bug allocating buffers larger than this */
+#define TX_NICBUF_SIZE_BUG	1585
+
 /********************************************************************/
 /* Data tables                                                      */
 /********************************************************************/
@@ -36,6 +42,343 @@ static const struct {
 };
 #define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
 
+/* Firmware version encoding */
+struct comp_id {
+	u16 id, variant, major, minor;
+} __attribute__ ((packed));
+
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
+{
+	if (nic_id->id < 0x8000)
+		return FIRMWARE_TYPE_AGERE;
+	else if (nic_id->id == 0x8000 && nic_id->major == 0)
+		return FIRMWARE_TYPE_SYMBOL;
+	else
+		return FIRMWARE_TYPE_INTERSIL;
+}
+
+/* Set priv->firmware type, determine firmware properties
+ * This function can be called before we have registerred with netdev,
+ * so all errors go out with dev_* rather than printk
+ */
+int determine_fw_capabilities(struct orinoco_private *priv)
+{
+	struct device *dev = priv->dev;
+	hermes_t *hw = &priv->hw;
+	int err;
+	struct comp_id nic_id, sta_id;
+	unsigned int firmver;
+	char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
+
+	/* Get the hardware version */
+	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+	if (err) {
+		dev_err(dev, "Cannot read hardware identity: error %d\n",
+			err);
+		return err;
+	}
+
+	le16_to_cpus(&nic_id.id);
+	le16_to_cpus(&nic_id.variant);
+	le16_to_cpus(&nic_id.major);
+	le16_to_cpus(&nic_id.minor);
+	dev_info(dev, "Hardware identity %04x:%04x:%04x:%04x\n",
+		 nic_id.id, nic_id.variant, nic_id.major, nic_id.minor);
+
+	priv->firmware_type = determine_firmware_type(&nic_id);
+
+	/* Get the firmware version */
+	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
+	if (err) {
+		dev_err(dev, "Cannot read station identity: error %d\n",
+			err);
+		return err;
+	}
+
+	le16_to_cpus(&sta_id.id);
+	le16_to_cpus(&sta_id.variant);
+	le16_to_cpus(&sta_id.major);
+	le16_to_cpus(&sta_id.minor);
+	dev_info(dev, "Station identity  %04x:%04x:%04x:%04x\n",
+		 sta_id.id, sta_id.variant, sta_id.major, sta_id.minor);
+
+	switch (sta_id.id) {
+	case 0x15:
+		dev_err(dev, "Primary firmware is active\n");
+		return -ENODEV;
+	case 0x14b:
+		dev_err(dev, "Tertiary firmware is active\n");
+		return -ENODEV;
+	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
+	case 0x21:	/* Symbol Spectrum24 Trilogy */
+		break;
+	default:
+		dev_notice(dev, "Unknown station ID, please report\n");
+		break;
+	}
+
+	/* Default capabilities */
+	priv->has_sensitivity = 1;
+	priv->has_mwo = 0;
+	priv->has_preamble = 0;
+	priv->has_port3 = 1;
+	priv->has_ibss = 1;
+	priv->has_wep = 0;
+	priv->has_big_wep = 0;
+	priv->has_alt_txcntl = 0;
+	priv->has_ext_scan = 0;
+	priv->has_wpa = 0;
+	priv->do_fw_download = 0;
+
+	/* Determine capabilities from the firmware version */
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
+		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
+		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
+
+		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
+
+		priv->has_ibss = (firmver >= 0x60006);
+		priv->has_wep = (firmver >= 0x40020);
+		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
+					  Gold cards from the others? */
+		priv->has_mwo = (firmver >= 0x60000);
+		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
+		priv->ibss_port = 1;
+		priv->has_hostscan = (firmver >= 0x8000a);
+		priv->do_fw_download = 1;
+		priv->broken_monitor = (firmver >= 0x80000);
+		priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
+		priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
+		priv->has_wpa = (firmver >= 0x9002a);
+		/* Tested with Agere firmware :
+		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
+		 * Tested CableTron firmware : 4.32 => Anton */
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
+		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
+		/* Intel MAC : 00:02:B3:* */
+		/* 3Com MAC : 00:50:DA:* */
+		memset(tmp, 0, sizeof(tmp));
+		/* Get the Symbol firmware version */
+		err = hermes_read_ltv(hw, USER_BAP,
+				      HERMES_RID_SECONDARYVERSION_SYMBOL,
+				      SYMBOL_MAX_VER_LEN, NULL, &tmp);
+		if (err) {
+			dev_warn(dev, "Error %d reading Symbol firmware info. "
+				 "Wildly guessing capabilities...\n", err);
+			firmver = 0;
+			tmp[0] = '\0';
+		} else {
+			/* The firmware revision is a string, the format is
+			 * something like : "V2.20-01".
+			 * Quick and dirty parsing... - Jean II
+			 */
+			firmver = ((tmp[1] - '0') << 16)
+				| ((tmp[3] - '0') << 12)
+				| ((tmp[4] - '0') << 8)
+				| ((tmp[6] - '0') << 4)
+				| (tmp[7] - '0');
+
+			tmp[SYMBOL_MAX_VER_LEN] = '\0';
+		}
+
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Symbol %s", tmp);
+
+		priv->has_ibss = (firmver >= 0x20000);
+		priv->has_wep = (firmver >= 0x15012);
+		priv->has_big_wep = (firmver >= 0x20000);
+		priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
+			       (firmver >= 0x29000 && firmver < 0x30000) ||
+			       firmver >= 0x31000;
+		priv->has_preamble = (firmver >= 0x20000);
+		priv->ibss_port = 4;
+
+		/* Symbol firmware is found on various cards, but
+		 * there has been no attempt to check firmware
+		 * download on non-spectrum_cs based cards.
+		 *
+		 * Given that the Agere firmware download works
+		 * differently, we should avoid doing a firmware
+		 * download with the Symbol algorithm on non-spectrum
+		 * cards.
+		 *
+		 * For now we can identify a spectrum_cs based card
+		 * because it has a firmware reset function.
+		 */
+		priv->do_fw_download = (priv->stop_fw != NULL);
+
+		priv->broken_disableport = (firmver == 0x25013) ||
+				(firmver >= 0x30000 && firmver <= 0x31000);
+		priv->has_hostscan = (firmver >= 0x31001) ||
+				     (firmver >= 0x29057 && firmver < 0x30000);
+		/* Tested with Intel firmware : 0x20015 => Jean II */
+		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
+		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
+		 * Samsung, Compaq 100/200 and Proxim are slightly
+		 * different and less well tested */
+		/* D-Link MAC : 00:40:05:* */
+		/* Addtron MAC : 00:90:D1:* */
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
+			 sta_id.variant);
+
+		firmver = ((unsigned long)sta_id.major << 16) |
+			((unsigned long)sta_id.minor << 8) | sta_id.variant;
+
+		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
+		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
+		priv->has_pm = (firmver >= 0x000700);
+		priv->has_hostscan = (firmver >= 0x010301);
+
+		if (firmver >= 0x000800)
+			priv->ibss_port = 0;
+		else {
+			dev_notice(dev, "Intersil firmware earlier than v0.8.x"
+				   " - several features not supported\n");
+			priv->ibss_port = 1;
+		}
+		break;
+	}
+	dev_info(dev, "Firmware determined as %s\n", priv->fw_name);
+
+	return 0;
+}
+
+/* Read settings from EEPROM into our private structure.
+ * MAC address gets dropped into callers buffer
+ * Can be called before netdev registration.
+ */
+int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
+{
+	struct device *dev = priv->dev;
+	struct hermes_idstring nickbuf;
+	hermes_t *hw = &priv->hw;
+	int len;
+	int err;
+	u16 reclen;
+
+	/* Get the MAC address */
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+			      ETH_ALEN, NULL, dev_addr);
+	if (err) {
+		dev_warn(dev, "Failed to read MAC address!\n");
+		goto out;
+	}
+
+	dev_dbg(dev, "MAC address %pM\n", dev_addr);
+
+	/* Get the station name */
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+			      sizeof(nickbuf), &reclen, &nickbuf);
+	if (err) {
+		dev_err(dev, "failed to read station name\n");
+		goto out;
+	}
+	if (nickbuf.len)
+		len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
+	else
+		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
+	memcpy(priv->nick, &nickbuf.val, len);
+	priv->nick[len] = '\0';
+
+	dev_dbg(dev, "Station name \"%s\"\n", priv->nick);
+
+	/* Get allowed channels */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
+				  &priv->channel_mask);
+	if (err) {
+		dev_err(dev, "Failed to read channel list!\n");
+		goto out;
+	}
+
+	/* Get initial AP density */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+				  &priv->ap_density);
+	if (err || priv->ap_density < 1 || priv->ap_density > 3)
+		priv->has_sensitivity = 0;
+
+	/* Get initial RTS threshold */
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+				  &priv->rts_thresh);
+	if (err) {
+		dev_err(dev, "Failed to read RTS threshold!\n");
+		goto out;
+	}
+
+	/* Get initial fragmentation settings */
+	if (priv->has_mwo)
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFMWOROBUST_AGERE,
+					  &priv->mwo_robust);
+	else
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+					  &priv->frag_thresh);
+	if (err) {
+		dev_err(dev, "Failed to read fragmentation settings!\n");
+		goto out;
+	}
+
+	/* Power management setup */
+	if (priv->has_pm) {
+		priv->pm_on = 0;
+		priv->pm_mcast = 1;
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFMAXSLEEPDURATION,
+					  &priv->pm_period);
+		if (err) {
+			dev_err(dev, "Failed to read power management "
+				"period!\n");
+			goto out;
+		}
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFPMHOLDOVERDURATION,
+					  &priv->pm_timeout);
+		if (err) {
+			dev_err(dev, "Failed to read power management "
+				"timeout!\n");
+			goto out;
+		}
+	}
+
+	/* Preamble setup */
+	if (priv->has_preamble) {
+		err = hermes_read_wordrec(hw, USER_BAP,
+					  HERMES_RID_CNFPREAMBLE_SYMBOL,
+					  &priv->preamble);
+	}
+
+out:
+	return err;
+}
+
+/* Can be called before netdev registration */
+int orinoco_hw_allocate_fid(struct orinoco_private *priv)
+{
+	struct device *dev = priv->dev;
+	struct hermes *hw = &priv->hw;
+	int err;
+
+	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+	if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
+		/* Try workaround for old Symbol firmware bug */
+		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+
+		dev_warn(dev, "Firmware ALLOC bug detected "
+			 "(old Symbol firmware?). Work around %s\n",
+			 err ? "failed!" : "ok.");
+	}
+
+	return err;
+}
+
 int orinoco_get_bitratemode(int bitrate, int automatic)
 {
 	int ratemode = -1;
@@ -63,12 +406,243 @@ void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
 	*automatic = bitrate_table[ratemode].automatic;
 }
 
+int orinoco_hw_program_rids(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	struct wireless_dev *wdev = netdev_priv(dev);
+	hermes_t *hw = &priv->hw;
+	int err;
+	struct hermes_idstring idbuf;
+
+	/* Set the MAC address */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
+			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting MAC address\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set up the link mode */
+	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
+				   priv->port_type);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting port type\n",
+		       dev->name, err);
+		return err;
+	}
+	/* Set the channel/frequency */
+	if (priv->channel != 0 && priv->iw_mode != NL80211_IFTYPE_STATION) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFOWNCHANNEL,
+					   priv->channel);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting channel %d\n",
+			       dev->name, err, priv->channel);
+			return err;
+		}
+	}
+
+	if (priv->has_ibss) {
+		u16 createibss;
+
+		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
+			printk(KERN_WARNING "%s: This firmware requires an "
+			       "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
+			/* With wvlan_cs, in this case, we would crash.
+			 * hopefully, this driver will behave better...
+			 * Jean II */
+			createibss = 0;
+		} else {
+			createibss = priv->createibss;
+		}
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFCREATEIBSS,
+					   createibss);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set the desired BSSID */
+	err = __orinoco_hw_set_wap(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting AP address\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set the desired ESSID */
+	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
+	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
+	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			&idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
+		       dev->name, err);
+		return err;
+	}
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
+			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			&idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set the station name */
+	idbuf.len = cpu_to_le16(strlen(priv->nick));
+	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
+			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
+			       &idbuf);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting nickname\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set AP density */
+	if (priv->has_sensitivity) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFSYSTEMSCALE,
+					   priv->ap_density);
+		if (err) {
+			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
+			       "Disabling sensitivity control\n",
+			       dev->name, err);
+
+			priv->has_sensitivity = 0;
+		}
+	}
+
+	/* Set RTS threshold */
+	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
+				   priv->rts_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set fragmentation threshold or MWO robustness */
+	if (priv->has_mwo)
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMWOROBUST_AGERE,
+					   priv->mwo_robust);
+	else
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
+					   priv->frag_thresh);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting fragmentation\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set bitrate */
+	err = __orinoco_hw_set_bitrate(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d setting bitrate\n",
+		       dev->name, err);
+		return err;
+	}
+
+	/* Set power management */
+	if (priv->has_pm) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPMENABLED,
+					   priv->pm_on);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMULTICASTRECEIVE,
+					   priv->pm_mcast);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFMAXSLEEPDURATION,
+					   priv->pm_period);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPMHOLDOVERDURATION,
+					   priv->pm_timeout);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting up PM\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set preamble - only for Symbol so far... */
+	if (priv->has_preamble) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPREAMBLE_SYMBOL,
+					   priv->preamble);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting preamble\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	/* Set up encryption */
+	if (priv->has_wep || priv->has_wpa) {
+		err = __orinoco_hw_setup_enc(priv);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d activating encryption\n",
+			       dev->name, err);
+			return err;
+		}
+	}
+
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
+		/* Enable monitor mode */
+		dev->type = ARPHRD_IEEE80211;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_MONITOR, 0, NULL);
+	} else {
+		/* Disable monitor mode */
+		dev->type = ARPHRD_ETHER;
+		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
+					    HERMES_TEST_STOP, 0, NULL);
+	}
+	if (err)
+		return err;
+
+	/* Reset promiscuity / multicast*/
+	priv->promiscuous = 0;
+	priv->mc_count = 0;
+
+	/* Record mode change */
+	wdev->iftype = priv->iw_mode;
+
+	return 0;
+}
+
 /* Get tsc from the firmware */
 int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
+	u8 tsc_arr[4][ORINOCO_SEQ_LEN];
 
 	if ((key < 0) || (key >= 4))
 		return -EINVAL;
@@ -194,12 +768,29 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
+	int i;
 
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE:
+	{
+		struct orinoco_key keys[ORINOCO_MAX_KEYS];
+
+		memset(&keys, 0, sizeof(keys));
+		for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
+			int len = min(priv->keys[i].key_len,
+				      ORINOCO_MAX_KEY_SIZE);
+			memcpy(&keys[i].data, priv->keys[i].key, len);
+			if (len > SMALL_KEY_SIZE)
+				keys[i].len = cpu_to_le16(LARGE_KEY_SIZE);
+			else if (len > 0)
+				keys[i].len = cpu_to_le16(SMALL_KEY_SIZE);
+			else
+				keys[i].len = cpu_to_le16(0);
+		}
+
 		err = HERMES_WRITE_RECORD(hw, USER_BAP,
 					  HERMES_RID_CNFWEPKEYS_AGERE,
-					  &priv->keys);
+					  &keys);
 		if (err)
 			return err;
 		err = hermes_write_wordrec(hw, USER_BAP,
@@ -208,28 +799,38 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
 		if (err)
 			return err;
 		break;
+	}
 	case FIRMWARE_TYPE_INTERSIL:
 	case FIRMWARE_TYPE_SYMBOL:
 		{
 			int keylen;
-			int i;
 
 			/* Force uniform key length to work around
 			 * firmware bugs */
-			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
+			keylen = priv->keys[priv->tx_key].key_len;
 
 			if (keylen > LARGE_KEY_SIZE) {
 				printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
 				       priv->ndev->name, priv->tx_key, keylen);
 				return -E2BIG;
-			}
+			} else if (keylen > SMALL_KEY_SIZE)
+				keylen = LARGE_KEY_SIZE;
+			else if (keylen > 0)
+				keylen = SMALL_KEY_SIZE;
+			else
+				keylen = 0;
 
 			/* Write all 4 keys */
 			for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
+				u8 key[LARGE_KEY_SIZE] = { 0 };
+
+				memcpy(key, priv->keys[i].key,
+				       priv->keys[i].key_len);
+
 				err = hermes_write_ltv(hw, USER_BAP,
 						HERMES_RID_CNFDEFAULTKEY0 + i,
 						HERMES_BYTES_TO_RECLEN(keylen),
-						priv->keys[i].data);
+						key);
 				if (err)
 					return err;
 			}
@@ -255,8 +856,8 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
 	int auth_flag;
 	int enc_flag;
 
-	/* Setup WEP keys for WEP and WPA */
-	if (priv->encode_alg)
+	/* Setup WEP keys */
+	if (priv->encode_alg == ORINOCO_ALG_WEP)
 		__orinoco_hw_setup_wepkeys(priv);
 
 	if (priv->wep_restrict)
@@ -266,14 +867,14 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
 
 	if (priv->wpa_enabled)
 		enc_flag = 2;
-	else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
+	else if (priv->encode_alg == ORINOCO_ALG_WEP)
 		enc_flag = 1;
 	else
 		enc_flag = 0;
 
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
-		if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+		if (priv->encode_alg == ORINOCO_ALG_WEP) {
 			/* Enable the shared-key authentication. */
 			err = hermes_write_wordrec(hw, USER_BAP,
 					HERMES_RID_CNFAUTHENTICATION_AGERE,
@@ -298,7 +899,7 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
 
 	case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
 	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
-		if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
+		if (priv->encode_alg == ORINOCO_ALG_WEP) {
 			if (priv->wep_restrict ||
 			    (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
 				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
@@ -314,7 +915,7 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
 		} else
 			master_wep_flag = 0;
 
-		if (priv->iw_mode == IW_MODE_MONITOR)
+		if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
 			master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
 
 		/* Master WEP setting : on/off */
@@ -331,20 +932,22 @@ int __orinoco_hw_setup_enc(struct orinoco_private *priv)
 }
 
 /* key must be 32 bytes, including the tx and rx MIC keys.
- * rsc must be 8 bytes
- * tsc must be 8 bytes or NULL
+ * rsc must be NULL or up to 8 bytes
+ * tsc must be NULL or up to 8 bytes
  */
-int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
-			      u8 *key, u8 *rsc, u8 *tsc)
+int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx,
+			      int set_tx, u8 *key, u8 *rsc, size_t rsc_len,
+			      u8 *tsc, size_t tsc_len)
 {
 	struct {
 		__le16 idx;
-		u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
+		u8 rsc[ORINOCO_SEQ_LEN];
 		u8 key[TKIP_KEYLEN];
 		u8 tx_mic[MIC_KEYLEN];
 		u8 rx_mic[MIC_KEYLEN];
-		u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
+		u8 tsc[ORINOCO_SEQ_LEN];
 	} __attribute__ ((packed)) buf;
+	hermes_t *hw = &priv->hw;
 	int ret;
 	int err;
 	int k;
@@ -359,17 +962,22 @@ int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
 	memcpy(buf.key, key,
 	       sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
 
-	if (rsc == NULL)
-		memset(buf.rsc, 0, sizeof(buf.rsc));
-	else
-		memcpy(buf.rsc, rsc, sizeof(buf.rsc));
+	if (rsc_len > sizeof(buf.rsc))
+		rsc_len = sizeof(buf.rsc);
+
+	if (tsc_len > sizeof(buf.tsc))
+		tsc_len = sizeof(buf.tsc);
 
-	if (tsc == NULL) {
-		memset(buf.tsc, 0, sizeof(buf.tsc));
+	memset(buf.rsc, 0, sizeof(buf.rsc));
+	memset(buf.tsc, 0, sizeof(buf.tsc));
+
+	if (rsc != NULL)
+		memcpy(buf.rsc, rsc, rsc_len);
+
+	if (tsc != NULL)
+		memcpy(buf.tsc, tsc, tsc_len);
+	else
 		buf.tsc[4] = 0x10;
-	} else {
-		memcpy(buf.tsc, tsc, sizeof(buf.tsc));
-	}
 
 	/* Wait upto 100ms for tx queue to empty */
 	for (k = 100; k > 0; k--) {
@@ -395,7 +1003,6 @@ int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx)
 	hermes_t *hw = &priv->hw;
 	int err;
 
-	memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
 	err = hermes_write_wordrec(hw, USER_BAP,
 				   HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
 				   key_idx);
@@ -582,3 +1189,124 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
 
 	return 0;
 }
+
+int orinoco_hw_trigger_scan(struct orinoco_private *priv,
+			    const struct cfg80211_ssid *ssid)
+{
+	struct net_device *dev = priv->ndev;
+	hermes_t *hw = &priv->hw;
+	unsigned long flags;
+	int err = 0;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
+
+	/* Scanning with port 0 disabled would fail */
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
+
+	/* In monitor mode, the scan results are always empty.
+	 * Probe responses are passed to the driver as received
+	 * frames and could be processed in software. */
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (priv->has_hostscan) {
+		switch (priv->firmware_type) {
+		case FIRMWARE_TYPE_SYMBOL:
+			err = hermes_write_wordrec(hw, USER_BAP,
+						HERMES_RID_CNFHOSTSCAN_SYMBOL,
+						HERMES_HOSTSCAN_SYMBOL_ONCE |
+						HERMES_HOSTSCAN_SYMBOL_BCAST);
+			break;
+		case FIRMWARE_TYPE_INTERSIL: {
+			__le16 req[3];
+
+			req[0] = cpu_to_le16(0x3fff);	/* All channels */
+			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
+			req[2] = 0;			/* Any ESSID */
+			err = HERMES_WRITE_RECORD(hw, USER_BAP,
+						  HERMES_RID_CNFHOSTSCAN, &req);
+			break;
+		}
+		case FIRMWARE_TYPE_AGERE:
+			if (ssid->ssid_len > 0) {
+				struct hermes_idstring idbuf;
+				size_t len = ssid->ssid_len;
+
+				idbuf.len = cpu_to_le16(len);
+				memcpy(idbuf.val, ssid->ssid, len);
+
+				err = hermes_write_ltv(hw, USER_BAP,
+					       HERMES_RID_CNFSCANSSID_AGERE,
+					       HERMES_BYTES_TO_RECLEN(len + 2),
+					       &idbuf);
+			} else
+				err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFSCANSSID_AGERE,
+						   0);	/* Any ESSID */
+			if (err)
+				break;
+
+			if (priv->has_ext_scan) {
+				err = hermes_write_wordrec(hw, USER_BAP,
+						HERMES_RID_CNFSCANCHANNELS2GHZ,
+						0x7FFF);
+				if (err)
+					goto out;
+
+				err = hermes_inquire(hw,
+						     HERMES_INQ_CHANNELINFO);
+			} else
+				err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+			break;
+		}
+	} else
+		err = hermes_inquire(hw, HERMES_INQ_SCAN);
+
+ out:
+	orinoco_unlock(priv, &flags);
+
+	return err;
+}
+
+/* Disassociate from node with BSSID addr */
+int orinoco_hw_disassociate(struct orinoco_private *priv,
+			    u8 *addr, u16 reason_code)
+{
+	hermes_t *hw = &priv->hw;
+	int err;
+
+	struct {
+		u8 addr[ETH_ALEN];
+		__le16 reason_code;
+	} __attribute__ ((packed)) buf;
+
+	/* Currently only supported by WPA enabled Agere fw */
+	if (!priv->has_wpa)
+		return -EOPNOTSUPP;
+
+	memcpy(buf.addr, addr, ETH_ALEN);
+	buf.reason_code = cpu_to_le16(reason_code);
+	err = HERMES_WRITE_RECORD(hw, USER_BAP,
+				  HERMES_RID_CNFDISASSOCIATE,
+				  &buf);
+	return err;
+}
+
+int orinoco_hw_get_current_bssid(struct orinoco_private *priv,
+				 u8 *addr)
+{
+	hermes_t *hw = &priv->hw;
+	int err;
+
+	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
+			      ETH_ALEN, NULL, addr);
+
+	return err;
+}
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index dc3f23a..8df6e87 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -7,6 +7,7 @@
 
 #include <linux/types.h>
 #include <linux/wireless.h>
+#include <net/cfg80211.h>
 
 /* Hardware BAPs */
 #define USER_BAP 0
@@ -23,17 +24,22 @@
 struct orinoco_private;
 struct dev_addr_list;
 
+int determine_fw_capabilities(struct orinoco_private *priv);
+int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr);
+int orinoco_hw_allocate_fid(struct orinoco_private *priv);
 int orinoco_get_bitratemode(int bitrate, int automatic);
 void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic);
 
+int orinoco_hw_program_rids(struct orinoco_private *priv);
 int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc);
 int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
 int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate);
 int __orinoco_hw_set_wap(struct orinoco_private *priv);
 int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv);
 int __orinoco_hw_setup_enc(struct orinoco_private *priv);
-int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
-			      u8 *key, u8 *rsc, u8 *tsc);
+int __orinoco_hw_set_tkip_key(struct orinoco_private *priv, int key_idx,
+			      int set_tx, u8 *key, u8 *rsc, size_t rsc_len,
+			      u8 *tsc, size_t tsc_len);
 int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx);
 int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
 				    struct dev_addr_list *mc_list,
@@ -43,5 +49,11 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
 int orinoco_hw_get_freq(struct orinoco_private *priv);
 int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
 			       int *numrates, s32 *rates, int max);
+int orinoco_hw_trigger_scan(struct orinoco_private *priv,
+			    const struct cfg80211_ssid *ssid);
+int orinoco_hw_disassociate(struct orinoco_private *priv,
+			    u8 *addr, u16 reason_code);
+int orinoco_hw_get_current_bssid(struct orinoco_private *priv,
+				 u8 *addr);
 
 #endif /* _ORINOCO_HW_H_ */
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index a370e51..7a32bcb 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -80,6 +80,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/device.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
@@ -88,6 +89,7 @@
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 
 #include "hermes_rid.h"
 #include "hermes_dld.h"
@@ -96,6 +98,7 @@
 #include "mic.h"
 #include "fw.h"
 #include "wext.h"
+#include "cfg.h"
 #include "main.h"
 
 #include "orinoco.h"
@@ -142,13 +145,11 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
 #define ORINOCO_MIN_MTU		256
 #define ORINOCO_MAX_MTU		(IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
 
-#define SYMBOL_MAX_VER_LEN	(14)
 #define MAX_IRQLOOPS_PER_IRQ	10
 #define MAX_IRQLOOPS_PER_JIFFY	(20000/HZ) /* Based on a guestimate of
 					    * how many events the
 					    * device could
 					    * legitimately generate */
-#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
 
 #define DUMMY_FID		0xFFFF
 
@@ -205,11 +206,21 @@ struct orinoco_rx_data {
 	struct list_head list;
 };
 
+struct orinoco_scan_data {
+	void *buf;
+	size_t len;
+	int type;
+	struct list_head list;
+};
+
 /********************************************************************/
 /* Function prototypes                                              */
 /********************************************************************/
 
-static void __orinoco_set_multicast_list(struct net_device *dev);
+static int __orinoco_set_multicast_list(struct net_device *dev);
+static int __orinoco_up(struct orinoco_private *priv);
+static int __orinoco_down(struct orinoco_private *priv);
+static int __orinoco_commit(struct orinoco_private *priv);
 
 /********************************************************************/
 /* Internal helper functions                                        */
@@ -218,11 +229,11 @@ static void __orinoco_set_multicast_list(struct net_device *dev);
 void set_port_type(struct orinoco_private *priv)
 {
 	switch (priv->iw_mode) {
-	case IW_MODE_INFRA:
+	case NL80211_IFTYPE_STATION:
 		priv->port_type = 1;
 		priv->createibss = 0;
 		break;
-	case IW_MODE_ADHOC:
+	case NL80211_IFTYPE_ADHOC:
 		if (priv->prefer_port3) {
 			priv->port_type = 3;
 			priv->createibss = 0;
@@ -231,7 +242,7 @@ void set_port_type(struct orinoco_private *priv)
 			priv->createibss = 1;
 		}
 		break;
-	case IW_MODE_MONITOR:
+	case NL80211_IFTYPE_MONITOR:
 		priv->port_type = 3;
 		priv->createibss = 0;
 		break;
@@ -247,14 +258,14 @@ void set_port_type(struct orinoco_private *priv)
 
 static int orinoco_open(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 	int err;
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	err = __orinoco_up(dev);
+	err = __orinoco_up(priv);
 
 	if (!err)
 		priv->open = 1;
@@ -266,7 +277,7 @@ static int orinoco_open(struct net_device *dev)
 
 static int orinoco_stop(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 
 	/* We mustn't use orinoco_lock() here, because we need to be
@@ -276,7 +287,7 @@ static int orinoco_stop(struct net_device *dev)
 
 	priv->open = 0;
 
-	err = __orinoco_down(dev);
+	err = __orinoco_down(priv);
 
 	spin_unlock_irq(&priv->lock);
 
@@ -285,14 +296,14 @@ static int orinoco_stop(struct net_device *dev)
 
 static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	return &priv->stats;
 }
 
 static void orinoco_set_multicast_list(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0) {
@@ -307,7 +318,7 @@ static void orinoco_set_multicast_list(struct net_device *dev)
 
 static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
 		return -EINVAL;
@@ -326,16 +337,18 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
 /* Tx path                                                          */
 /********************************************************************/
 
-static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
+	struct orinoco_tkip_key *key;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 txfid = priv->txfid;
 	struct ethhdr *eh;
 	int tx_control;
 	unsigned long flags;
+	int do_mic;
 
 	if (!netif_running(dev)) {
 		printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -355,7 +368,8 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 		return NETDEV_TX_BUSY;
 	}
 
-	if (!netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
+	if (!netif_carrier_ok(dev) ||
+	    (priv->iw_mode == NL80211_IFTYPE_MONITOR)) {
 		/* Oops, the firmware hasn't established a connection,
 		   silently drop the packet (this seems to be the
 		   safest approach). */
@@ -366,9 +380,14 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (skb->len < ETH_HLEN)
 		goto drop;
 
+	key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
+
+	do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
+		  (key != NULL));
+
 	tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
 
-	if (priv->encode_alg == IW_ENCODE_ALG_TKIP)
+	if (do_mic)
 		tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
 			HERMES_TXCTRL_MIC;
 
@@ -450,7 +469,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* Calculate Michael MIC */
-	if (priv->encode_alg == IW_ENCODE_ALG_TKIP) {
+	if (do_mic) {
 		u8 mic_buf[MICHAEL_MIC_LEN + 1];
 		u8 *mic;
 		size_t offset;
@@ -468,8 +487,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 			len = MICHAEL_MIC_LEN;
 		}
 
-		orinoco_mic(priv->tx_tfm_mic,
-			    priv->tkip_key[priv->tx_key].tx_mic,
+		orinoco_mic(priv->tx_tfm_mic, key->tx_mic,
 			    eh->h_dest, eh->h_source, 0 /* priority */,
 			    skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
 
@@ -518,7 +536,7 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	u16 fid = hermes_read_regn(hw, ALLOCFID);
 
 	if (fid != priv->txfid) {
@@ -533,7 +551,7 @@ static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
 
 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 
 	stats->tx_packets++;
@@ -545,7 +563,7 @@ static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
 
 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
 	u16 status;
@@ -601,7 +619,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
 
 static void orinoco_tx_timeout(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	struct hermes *hw = &priv->hw;
 
@@ -650,7 +668,7 @@ static void orinoco_stat_gather(struct net_device *dev,
 				struct sk_buff *skb,
 				struct hermes_rx_descriptor *desc)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	/* Using spy support with lots of Rx packets, like in an
 	 * infrastructure (AP), will really slow down everything, because
@@ -687,7 +705,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
 	int err;
 	int len;
 	struct sk_buff *skb;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	hermes_t *hw = &priv->hw;
 
@@ -778,7 +796,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
 
 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	struct iw_statistics *wstats = &priv->wstats;
 	struct sk_buff *skb = NULL;
@@ -816,7 +834,7 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
 	}
 
 	/* Handle frames in monitor mode */
-	if (priv->iw_mode == IW_MODE_MONITOR) {
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
 		orinoco_rx_monitor(dev, rxfid, desc);
 		goto out;
 	}
@@ -902,7 +920,7 @@ static void orinoco_rx(struct net_device *dev,
 		       struct hermes_rx_descriptor *desc,
 		       struct sk_buff *skb)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	u16 status, fc;
 	int length;
@@ -914,6 +932,7 @@ static void orinoco_rx(struct net_device *dev,
 
 	/* Calculate and check MIC */
 	if (status & HERMES_RXSTAT_MIC) {
+		struct orinoco_tkip_key *key;
 		int key_id = ((status & HERMES_RXSTAT_MIC_KEY_ID) >>
 			      HERMES_MIC_KEY_ID_SHIFT);
 		u8 mic[MICHAEL_MIC_LEN];
@@ -927,14 +946,18 @@ static void orinoco_rx(struct net_device *dev,
 		skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
 		length -= MICHAEL_MIC_LEN;
 
-		orinoco_mic(priv->rx_tfm_mic,
-			    priv->tkip_key[key_id].rx_mic,
-			    desc->addr1,
-			    src,
+		key = (struct orinoco_tkip_key *) priv->keys[key_id].key;
+
+		if (!key) {
+			printk(KERN_WARNING "%s: Received encrypted frame from "
+			       "%pM using key %i, but key is not installed\n",
+			       dev->name, src, key_id);
+			goto drop;
+		}
+
+		orinoco_mic(priv->rx_tfm_mic, key->rx_mic, desc->addr1, src,
 			    0, /* priority or QoS? */
-			    skb->data,
-			    skb->len,
-			    &mic[0]);
+			    skb->data, skb->len, &mic[0]);
 
 		if (memcmp(mic, rxmic,
 			   MICHAEL_MIC_LEN)) {
@@ -1016,8 +1039,8 @@ static void orinoco_rx(struct net_device *dev,
 
 static void orinoco_rx_isr_tasklet(unsigned long data)
 {
-	struct net_device *dev = (struct net_device *) data;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = (struct orinoco_private *) data;
+	struct net_device *dev = priv->ndev;
 	struct orinoco_rx_data *rx_data, *temp;
 	struct hermes_rx_descriptor *desc;
 	struct sk_buff *skb;
@@ -1260,9 +1283,81 @@ static void orinoco_send_wevents(struct work_struct *work)
 	orinoco_unlock(priv, &flags);
 }
 
+static void qbuf_scan(struct orinoco_private *priv, void *buf,
+		      int len, int type)
+{
+	struct orinoco_scan_data *sd;
+	unsigned long flags;
+
+	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	sd->buf = buf;
+	sd->len = len;
+	sd->type = type;
+
+	spin_lock_irqsave(&priv->scan_lock, flags);
+	list_add_tail(&sd->list, &priv->scan_list);
+	spin_unlock_irqrestore(&priv->scan_lock, flags);
+
+	schedule_work(&priv->process_scan);
+}
+
+static void qabort_scan(struct orinoco_private *priv)
+{
+	struct orinoco_scan_data *sd;
+	unsigned long flags;
+
+	sd = kmalloc(sizeof(*sd), GFP_ATOMIC);
+	sd->len = -1; /* Abort */
+
+	spin_lock_irqsave(&priv->scan_lock, flags);
+	list_add_tail(&sd->list, &priv->scan_list);
+	spin_unlock_irqrestore(&priv->scan_lock, flags);
+
+	schedule_work(&priv->process_scan);
+}
+
+static void orinoco_process_scan_results(struct work_struct *work)
+{
+	struct orinoco_private *priv =
+		container_of(work, struct orinoco_private, process_scan);
+	struct orinoco_scan_data *sd, *temp;
+	unsigned long flags;
+	void *buf;
+	int len;
+	int type;
+
+	spin_lock_irqsave(&priv->scan_lock, flags);
+	list_for_each_entry_safe(sd, temp, &priv->scan_list, list) {
+		spin_unlock_irqrestore(&priv->scan_lock, flags);
+
+		buf = sd->buf;
+		len = sd->len;
+		type = sd->type;
+
+		list_del(&sd->list);
+		kfree(sd);
+
+		if (len > 0) {
+			if (type == HERMES_INQ_CHANNELINFO)
+				orinoco_add_extscan_result(priv, buf, len);
+			else
+				orinoco_add_hostscan_results(priv, buf, len);
+
+			kfree(buf);
+		} else if (priv->scan_request) {
+			/* Either abort or complete the scan */
+			cfg80211_scan_done(priv->scan_request, (len < 0));
+			priv->scan_request = NULL;
+		}
+
+		spin_lock_irqsave(&priv->scan_lock, flags);
+	}
+	spin_unlock_irqrestore(&priv->scan_lock, flags);
+}
+
 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	u16 infofid;
 	struct {
 		__le16 len;
@@ -1327,7 +1422,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		u16 newstatus;
 		int connected;
 
-		if (priv->iw_mode == IW_MODE_MONITOR)
+		if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
 			break;
 
 		if (len != sizeof(linkstatus)) {
@@ -1346,7 +1441,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		 * the hostscan frame can be requested.  */
 		if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
 		    priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
-		    priv->has_hostscan && priv->scan_inprogress) {
+		    priv->has_hostscan && priv->scan_request) {
 			hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
 			break;
 		}
@@ -1372,7 +1467,7 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 	}
 	break;
 	case HERMES_INQ_SCAN:
-		if (!priv->scan_inprogress && priv->bssid_fixed &&
+		if (!priv->scan_request && priv->bssid_fixed &&
 		    priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
 			schedule_work(&priv->join_work);
 			break;
@@ -1382,30 +1477,30 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 	case HERMES_INQ_HOSTSCAN_SYMBOL: {
 		/* Result of a scanning. Contains information about
 		 * cells in the vicinity - Jean II */
-		union iwreq_data	wrqu;
 		unsigned char *buf;
 
-		/* Scan is no longer in progress */
-		priv->scan_inprogress = 0;
-
 		/* Sanity check */
 		if (len > 4096) {
 			printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
 			       dev->name, len);
+			qabort_scan(priv);
 			break;
 		}
 
 		/* Allocate buffer for results */
 		buf = kmalloc(len, GFP_ATOMIC);
-		if (buf == NULL)
+		if (buf == NULL) {
 			/* No memory, so can't printk()... */
+			qabort_scan(priv);
 			break;
+		}
 
 		/* Read scan data */
 		err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
 				       infofid, sizeof(info));
 		if (err) {
 			kfree(buf);
+			qabort_scan(priv);
 			break;
 		}
 
@@ -1419,24 +1514,14 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		}
 #endif	/* ORINOCO_DEBUG */
 
-		if (orinoco_process_scan_results(priv, buf, len) == 0) {
-			/* Send an empty event to user space.
-			 * We don't send the received data on the event because
-			 * it would require us to do complex transcoding, and
-			 * we want to minimise the work done in the irq handler
-			 * Use a request to extract the data - Jean II */
-			wrqu.data.length = 0;
-			wrqu.data.flags = 0;
-			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
-		}
-		kfree(buf);
+		qbuf_scan(priv, buf, len, type);
 	}
 	break;
 	case HERMES_INQ_CHANNELINFO:
 	{
 		struct agere_ext_scan_info *bss;
 
-		if (!priv->scan_inprogress) {
+		if (!priv->scan_request) {
 			printk(KERN_DEBUG "%s: Got chaninfo without scan, "
 			       "len=%d\n", dev->name, len);
 			break;
@@ -1444,25 +1529,12 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 
 		/* An empty result indicates that the scan is complete */
 		if (len == 0) {
-			union iwreq_data	wrqu;
-
-			/* Scan is no longer in progress */
-			priv->scan_inprogress = 0;
-
-			wrqu.data.length = 0;
-			wrqu.data.flags = 0;
-			wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+			qbuf_scan(priv, NULL, len, type);
 			break;
 		}
 
 		/* Sanity check */
-		else if (len > sizeof(*bss)) {
-			printk(KERN_WARNING
-			       "%s: Ext scan results too large (%d bytes). "
-			       "Truncating results to %zd bytes.\n",
-			       dev->name, len, sizeof(*bss));
-			len = sizeof(*bss);
-		} else if (len < (offsetof(struct agere_ext_scan_info,
+		else if (len < (offsetof(struct agere_ext_scan_info,
 					   data) + 2)) {
 			/* Drop this result now so we don't have to
 			 * keep checking later */
@@ -1472,21 +1544,18 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 			break;
 		}
 
-		bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
+		bss = kmalloc(len, GFP_ATOMIC);
 		if (bss == NULL)
 			break;
 
 		/* Read scan data */
 		err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
 				       infofid, sizeof(info));
-		if (err) {
+		if (err)
 			kfree(bss);
-			break;
-		}
-
-		orinoco_add_ext_scan_result(priv, bss);
+		else
+			qbuf_scan(priv, bss, len, type);
 
-		kfree(bss);
 		break;
 	}
 	case HERMES_INQ_SEC_STAT_AGERE:
@@ -1501,6 +1570,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 		/* We don't actually do anything about it */
 		break;
 	}
+
+	return;
 }
 
 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
@@ -1513,15 +1584,15 @@ static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
 /* Internal hardware control routines                               */
 /********************************************************************/
 
-int __orinoco_up(struct net_device *dev)
+static int __orinoco_up(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device *dev = priv->ndev;
 	struct hermes *hw = &priv->hw;
 	int err;
 
 	netif_carrier_off(dev); /* just to make sure */
 
-	err = __orinoco_program_rids(dev);
+	err = __orinoco_commit(priv);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d configuring card\n",
 		       dev->name, err);
@@ -1541,11 +1612,10 @@ int __orinoco_up(struct net_device *dev)
 
 	return 0;
 }
-EXPORT_SYMBOL(__orinoco_up);
 
-int __orinoco_down(struct net_device *dev)
+static int __orinoco_down(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct net_device *dev = priv->ndev;
 	struct hermes *hw = &priv->hw;
 	int err;
 
@@ -1573,31 +1643,9 @@ int __orinoco_down(struct net_device *dev)
 
 	return 0;
 }
-EXPORT_SYMBOL(__orinoco_down);
-
-static int orinoco_allocate_fid(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
-	int err;
-
-	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-	if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
-		/* Try workaround for old Symbol firmware bug */
-		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
-		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
-
-		printk(KERN_WARNING "%s: firmware ALLOC bug detected "
-		       "(old Symbol firmware?). Work around %s\n",
-		       dev->name, err ? "failed!" : "ok.");
-	}
-
-	return err;
-}
 
-int orinoco_reinit_firmware(struct net_device *dev)
+static int orinoco_reinit_firmware(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
 	struct hermes *hw = &priv->hw;
 	int err;
 
@@ -1608,246 +1656,15 @@ int orinoco_reinit_firmware(struct net_device *dev)
 			priv->do_fw_download = 0;
 	}
 	if (!err)
-		err = orinoco_allocate_fid(dev);
+		err = orinoco_hw_allocate_fid(priv);
 
 	return err;
 }
-EXPORT_SYMBOL(orinoco_reinit_firmware);
-
-int __orinoco_program_rids(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err;
-	struct hermes_idstring idbuf;
-
-	/* Set the MAC address */
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-			       HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting MAC address\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set up the link mode */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
-				   priv->port_type);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting port type\n",
-		       dev->name, err);
-		return err;
-	}
-	/* Set the channel/frequency */
-	if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFOWNCHANNEL,
-					   priv->channel);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting channel %d\n",
-			       dev->name, err, priv->channel);
-			return err;
-		}
-	}
-
-	if (priv->has_ibss) {
-		u16 createibss;
-
-		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
-			printk(KERN_WARNING "%s: This firmware requires an "
-			       "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
-			/* With wvlan_cs, in this case, we would crash.
-			 * hopefully, this driver will behave better...
-			 * Jean II */
-			createibss = 0;
-		} else {
-			createibss = priv->createibss;
-		}
-
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFCREATEIBSS,
-					   createibss);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
-			       dev->name, err);
-			return err;
-		}
-	}
 
-	/* Set the desired BSSID */
-	err = __orinoco_hw_set_wap(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting AP address\n",
-		       dev->name, err);
-		return err;
-	}
-	/* Set the desired ESSID */
-	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
-	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
-	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
-			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-			&idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
-		       dev->name, err);
-		return err;
-	}
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
-			HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
-			&idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set the station name */
-	idbuf.len = cpu_to_le16(strlen(priv->nick));
-	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
-	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
-			       &idbuf);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting nickname\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set AP density */
-	if (priv->has_sensitivity) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFSYSTEMSCALE,
-					   priv->ap_density);
-		if (err) {
-			printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
-			       "Disabling sensitivity control\n",
-			       dev->name, err);
-
-			priv->has_sensitivity = 0;
-		}
-	}
-
-	/* Set RTS threshold */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-				   priv->rts_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set fragmentation threshold or MWO robustness */
-	if (priv->has_mwo)
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMWOROBUST_AGERE,
-					   priv->mwo_robust);
-	else
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-					   priv->frag_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting fragmentation\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set bitrate */
-	err = __orinoco_hw_set_bitrate(priv);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d setting bitrate\n",
-		       dev->name, err);
-		return err;
-	}
-
-	/* Set power management */
-	if (priv->has_pm) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPMENABLED,
-					   priv->pm_on);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMULTICASTRECEIVE,
-					   priv->pm_mcast);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFMAXSLEEPDURATION,
-					   priv->pm_period);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPMHOLDOVERDURATION,
-					   priv->pm_timeout);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting up PM\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set preamble - only for Symbol so far... */
-	if (priv->has_preamble) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPREAMBLE_SYMBOL,
-					   priv->preamble);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting preamble\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	/* Set up encryption */
-	if (priv->has_wep || priv->has_wpa) {
-		err = __orinoco_hw_setup_enc(priv);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d activating encryption\n",
-			       dev->name, err);
-			return err;
-		}
-	}
-
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		/* Enable monitor mode */
-		dev->type = ARPHRD_IEEE80211;
-		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-					    HERMES_TEST_MONITOR, 0, NULL);
-	} else {
-		/* Disable monitor mode */
-		dev->type = ARPHRD_ETHER;
-		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
-					    HERMES_TEST_STOP, 0, NULL);
-	}
-	if (err)
-		return err;
-
-	/* Set promiscuity / multicast*/
-	priv->promiscuous = 0;
-	priv->mc_count = 0;
-
-	/* FIXME: what about netif_tx_lock */
-	__orinoco_set_multicast_list(dev);
-
-	return 0;
-}
-
-/* FIXME: return int? */
-static void
+static int
 __orinoco_set_multicast_list(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 	int promisc, mc_count;
 
@@ -1864,6 +1681,8 @@ __orinoco_set_multicast_list(struct net_device *dev)
 
 	err = __orinoco_hw_set_multicast_list(priv, dev->mc_list, mc_count,
 					      promisc);
+
+	return err;
 }
 
 /* This must be called from user context, without locks held - use
@@ -1896,9 +1715,11 @@ void orinoco_reset(struct work_struct *work)
 
 	orinoco_unlock(priv, &flags);
 
-	/* Scanning support: Cleanup of driver struct */
-	orinoco_clear_scan_results(priv, 0);
-	priv->scan_inprogress = 0;
+	/* Scanning support: Notify scan cancellation */
+	if (priv->scan_request) {
+		cfg80211_scan_done(priv->scan_request, 1);
+		priv->scan_request = NULL;
+	}
 
 	if (priv->hard_reset) {
 		err = (*priv->hard_reset)(priv);
@@ -1909,7 +1730,7 @@ void orinoco_reset(struct work_struct *work)
 		}
 	}
 
-	err = orinoco_reinit_firmware(dev);
+	err = orinoco_reinit_firmware(priv);
 	if (err) {
 		printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
 		       dev->name, err);
@@ -1924,7 +1745,7 @@ void orinoco_reset(struct work_struct *work)
 	/* priv->open or priv->hw_unavailable might have changed while
 	 * we dropped the lock */
 	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(dev);
+		err = __orinoco_up(priv);
 		if (err) {
 			printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
 			       dev->name, err);
@@ -1941,6 +1762,64 @@ void orinoco_reset(struct work_struct *work)
 	printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
 }
 
+static int __orinoco_commit(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	int err = 0;
+
+	err = orinoco_hw_program_rids(priv);
+
+	/* FIXME: what about netif_tx_lock */
+	(void) __orinoco_set_multicast_list(dev);
+
+	return err;
+}
+
+/* Ensures configuration changes are applied. May result in a reset.
+ * The caller should hold priv->lock
+ */
+int orinoco_commit(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	hermes_t *hw = &priv->hw;
+	int err;
+
+	if (priv->broken_disableport) {
+		schedule_work(&priv->reset_work);
+		return 0;
+	}
+
+	err = hermes_disable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to disable port "
+		       "while reconfiguring card\n", dev->name);
+		priv->broken_disableport = 1;
+		goto out;
+	}
+
+	err = __orinoco_commit(priv);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
+		       dev->name);
+		goto out;
+	}
+
+	err = hermes_enable_port(hw, 0);
+	if (err) {
+		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
+		       dev->name);
+		goto out;
+	}
+
+ out:
+	if (err) {
+		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
+		schedule_work(&priv->reset_work);
+		err = 0;
+	}
+	return err;
+}
+
 /********************************************************************/
 /* Interrupt handler                                                */
 /********************************************************************/
@@ -1960,8 +1839,8 @@ static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
 
 irqreturn_t orinoco_interrupt(int irq, void *dev_id)
 {
-	struct net_device *dev = dev_id;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = dev_id;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int count = MAX_IRQLOOPS_PER_IRQ;
 	u16 evstat, events;
@@ -2096,227 +1975,12 @@ static void orinoco_unregister_pm_notifier(struct orinoco_private *priv)
 /* Initialization                                                   */
 /********************************************************************/
 
-struct comp_id {
-	u16 id, variant, major, minor;
-} __attribute__ ((packed));
-
-static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
-{
-	if (nic_id->id < 0x8000)
-		return FIRMWARE_TYPE_AGERE;
-	else if (nic_id->id == 0x8000 && nic_id->major == 0)
-		return FIRMWARE_TYPE_SYMBOL;
-	else
-		return FIRMWARE_TYPE_INTERSIL;
-}
-
-/* Set priv->firmware type, determine firmware properties */
-static int determine_firmware(struct net_device *dev)
+int orinoco_init(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	int err;
-	struct comp_id nic_id, sta_id;
-	unsigned int firmver;
-	char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
-
-	/* Get the hardware version */
-	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
-	if (err) {
-		printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
-		       dev->name, err);
-		return err;
-	}
-
-	le16_to_cpus(&nic_id.id);
-	le16_to_cpus(&nic_id.variant);
-	le16_to_cpus(&nic_id.major);
-	le16_to_cpus(&nic_id.minor);
-	printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
-	       dev->name, nic_id.id, nic_id.variant,
-	       nic_id.major, nic_id.minor);
-
-	priv->firmware_type = determine_firmware_type(&nic_id);
-
-	/* Get the firmware version */
-	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
-	if (err) {
-		printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
-		       dev->name, err);
-		return err;
-	}
-
-	le16_to_cpus(&sta_id.id);
-	le16_to_cpus(&sta_id.variant);
-	le16_to_cpus(&sta_id.major);
-	le16_to_cpus(&sta_id.minor);
-	printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
-	       dev->name, sta_id.id, sta_id.variant,
-	       sta_id.major, sta_id.minor);
-
-	switch (sta_id.id) {
-	case 0x15:
-		printk(KERN_ERR "%s: Primary firmware is active\n",
-		       dev->name);
-		return -ENODEV;
-	case 0x14b:
-		printk(KERN_ERR "%s: Tertiary firmware is active\n",
-		       dev->name);
-		return -ENODEV;
-	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
-	case 0x21:	/* Symbol Spectrum24 Trilogy */
-		break;
-	default:
-		printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
-		       dev->name);
-		break;
-	}
-
-	/* Default capabilities */
-	priv->has_sensitivity = 1;
-	priv->has_mwo = 0;
-	priv->has_preamble = 0;
-	priv->has_port3 = 1;
-	priv->has_ibss = 1;
-	priv->has_wep = 0;
-	priv->has_big_wep = 0;
-	priv->has_alt_txcntl = 0;
-	priv->has_ext_scan = 0;
-	priv->has_wpa = 0;
-	priv->do_fw_download = 0;
-
-	/* Determine capabilities from the firmware version */
-	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE:
-		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
-		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
-
-		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
-
-		priv->has_ibss = (firmver >= 0x60006);
-		priv->has_wep = (firmver >= 0x40020);
-		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
-					  Gold cards from the others? */
-		priv->has_mwo = (firmver >= 0x60000);
-		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
-		priv->ibss_port = 1;
-		priv->has_hostscan = (firmver >= 0x8000a);
-		priv->do_fw_download = 1;
-		priv->broken_monitor = (firmver >= 0x80000);
-		priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
-		priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
-		priv->has_wpa = (firmver >= 0x9002a);
-		/* Tested with Agere firmware :
-		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
-		 * Tested CableTron firmware : 4.32 => Anton */
-		break;
-	case FIRMWARE_TYPE_SYMBOL:
-		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
-		/* Intel MAC : 00:02:B3:* */
-		/* 3Com MAC : 00:50:DA:* */
-		memset(tmp, 0, sizeof(tmp));
-		/* Get the Symbol firmware version */
-		err = hermes_read_ltv(hw, USER_BAP,
-				      HERMES_RID_SECONDARYVERSION_SYMBOL,
-				      SYMBOL_MAX_VER_LEN, NULL, &tmp);
-		if (err) {
-			printk(KERN_WARNING
-			       "%s: Error %d reading Symbol firmware info. "
-			       "Wildly guessing capabilities...\n",
-			       dev->name, err);
-			firmver = 0;
-			tmp[0] = '\0';
-		} else {
-			/* The firmware revision is a string, the format is
-			 * something like : "V2.20-01".
-			 * Quick and dirty parsing... - Jean II
-			 */
-			firmver = ((tmp[1] - '0') << 16)
-				| ((tmp[3] - '0') << 12)
-				| ((tmp[4] - '0') << 8)
-				| ((tmp[6] - '0') << 4)
-				| (tmp[7] - '0');
-
-			tmp[SYMBOL_MAX_VER_LEN] = '\0';
-		}
-
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Symbol %s", tmp);
-
-		priv->has_ibss = (firmver >= 0x20000);
-		priv->has_wep = (firmver >= 0x15012);
-		priv->has_big_wep = (firmver >= 0x20000);
-		priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
-			       (firmver >= 0x29000 && firmver < 0x30000) ||
-			       firmver >= 0x31000;
-		priv->has_preamble = (firmver >= 0x20000);
-		priv->ibss_port = 4;
-
-		/* Symbol firmware is found on various cards, but
-		 * there has been no attempt to check firmware
-		 * download on non-spectrum_cs based cards.
-		 *
-		 * Given that the Agere firmware download works
-		 * differently, we should avoid doing a firmware
-		 * download with the Symbol algorithm on non-spectrum
-		 * cards.
-		 *
-		 * For now we can identify a spectrum_cs based card
-		 * because it has a firmware reset function.
-		 */
-		priv->do_fw_download = (priv->stop_fw != NULL);
-
-		priv->broken_disableport = (firmver == 0x25013) ||
-				(firmver >= 0x30000 && firmver <= 0x31000);
-		priv->has_hostscan = (firmver >= 0x31001) ||
-				     (firmver >= 0x29057 && firmver < 0x30000);
-		/* Tested with Intel firmware : 0x20015 => Jean II */
-		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
-		break;
-	case FIRMWARE_TYPE_INTERSIL:
-		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
-		 * Samsung, Compaq 100/200 and Proxim are slightly
-		 * different and less well tested */
-		/* D-Link MAC : 00:40:05:* */
-		/* Addtron MAC : 00:90:D1:* */
-		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
-			 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
-			 sta_id.variant);
-
-		firmver = ((unsigned long)sta_id.major << 16) |
-			((unsigned long)sta_id.minor << 8) | sta_id.variant;
-
-		priv->has_ibss = (firmver >= 0x000700); /* FIXME */
-		priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
-		priv->has_pm = (firmver >= 0x000700);
-		priv->has_hostscan = (firmver >= 0x010301);
-
-		if (firmver >= 0x000800)
-			priv->ibss_port = 0;
-		else {
-			printk(KERN_NOTICE "%s: Intersil firmware earlier "
-			       "than v0.8.x - several features not supported\n",
-			       dev->name);
-			priv->ibss_port = 1;
-		}
-		break;
-	}
-	printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
-	       priv->fw_name);
-
-	return 0;
-}
-
-static int orinoco_init(struct net_device *dev)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct device *dev = priv->dev;
+	struct wiphy *wiphy = priv_to_wiphy(priv);
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	struct hermes_idstring nickbuf;
-	u16 reclen;
-	int len;
 
 	/* No need to lock, the hw_unavailable flag is already set in
 	 * alloc_orinocodev() */
@@ -2325,15 +1989,14 @@ static int orinoco_init(struct net_device *dev)
 	/* Initialize the firmware */
 	err = hermes_init(hw);
 	if (err != 0) {
-		printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
-		       dev->name, err);
+		dev_err(dev, "Failed to initialize firmware (err = %d)\n",
+			err);
 		goto out;
 	}
 
-	err = determine_firmware(dev);
+	err = determine_fw_capabilities(priv);
 	if (err != 0) {
-		printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-		       dev->name);
+		dev_err(dev, "Incompatible firmware, aborting\n");
 		goto out;
 	}
 
@@ -2347,154 +2010,48 @@ static int orinoco_init(struct net_device *dev)
 			priv->do_fw_download = 0;
 
 		/* Check firmware version again */
-		err = determine_firmware(dev);
+		err = determine_fw_capabilities(priv);
 		if (err != 0) {
-			printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
-			       dev->name);
+			dev_err(dev, "Incompatible firmware, aborting\n");
 			goto out;
 		}
 	}
 
 	if (priv->has_port3)
-		printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n",
-		       dev->name);
+		dev_info(dev, "Ad-hoc demo mode supported\n");
 	if (priv->has_ibss)
-		printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
-		       dev->name);
-	if (priv->has_wep) {
-		printk(KERN_DEBUG "%s: WEP supported, %s-bit key\n", dev->name,
-		       priv->has_big_wep ? "104" : "40");
-	}
+		dev_info(dev, "IEEE standard IBSS ad-hoc mode supported\n");
+	if (priv->has_wep)
+		dev_info(dev, "WEP supported, %s-bit key\n",
+			 priv->has_big_wep ? "104" : "40");
 	if (priv->has_wpa) {
-		printk(KERN_DEBUG "%s: WPA-PSK supported\n", dev->name);
+		dev_info(dev, "WPA-PSK supported\n");
 		if (orinoco_mic_init(priv)) {
-			printk(KERN_ERR "%s: Failed to setup MIC crypto "
-			       "algorithm. Disabling WPA support\n", dev->name);
+			dev_err(dev, "Failed to setup MIC crypto algorithm. "
+				"Disabling WPA support\n");
 			priv->has_wpa = 0;
 		}
 	}
 
-	/* Now we have the firmware capabilities, allocate appropiate
-	 * sized scan buffers */
-	if (orinoco_bss_data_allocate(priv))
-		goto out;
-	orinoco_bss_data_init(priv);
-
-	/* Get the MAC address */
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
-			      ETH_ALEN, NULL, dev->dev_addr);
-	if (err) {
-		printk(KERN_WARNING "%s: failed to read MAC address!\n",
-		       dev->name);
-		goto out;
-	}
-
-	printk(KERN_DEBUG "%s: MAC address %pM\n",
-	       dev->name, dev->dev_addr);
-
-	/* Get the station name */
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
-			      sizeof(nickbuf), &reclen, &nickbuf);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read station name\n",
-		       dev->name);
-		goto out;
-	}
-	if (nickbuf.len)
-		len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
-	else
-		len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
-	memcpy(priv->nick, &nickbuf.val, len);
-	priv->nick[len] = '\0';
-
-	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
-
-	err = orinoco_allocate_fid(dev);
-	if (err) {
-		printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Get allowed channels */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
-				  &priv->channel_mask);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read channel list!\n",
-		       dev->name);
-		goto out;
-	}
-
-	/* Get initial AP density */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
-				  &priv->ap_density);
-	if (err || priv->ap_density < 1 || priv->ap_density > 3)
-		priv->has_sensitivity = 0;
-
-	/* Get initial RTS threshold */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
-				  &priv->rts_thresh);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read RTS threshold!\n",
-		       dev->name);
+	err = orinoco_hw_read_card_settings(priv, wiphy->perm_addr);
+	if (err)
 		goto out;
-	}
 
-	/* Get initial fragmentation settings */
-	if (priv->has_mwo)
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFMWOROBUST_AGERE,
-					  &priv->mwo_robust);
-	else
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
-					  &priv->frag_thresh);
+	err = orinoco_hw_allocate_fid(priv);
 	if (err) {
-		printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
-		       dev->name);
+		dev_err(dev, "Failed to allocate NIC buffer!\n");
 		goto out;
 	}
 
-	/* Power management setup */
-	if (priv->has_pm) {
-		priv->pm_on = 0;
-		priv->pm_mcast = 1;
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFMAXSLEEPDURATION,
-					  &priv->pm_period);
-		if (err) {
-			printk(KERN_ERR "%s: failed to read power management period!\n",
-			       dev->name);
-			goto out;
-		}
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFPMHOLDOVERDURATION,
-					  &priv->pm_timeout);
-		if (err) {
-			printk(KERN_ERR "%s: failed to read power management timeout!\n",
-			       dev->name);
-			goto out;
-		}
-	}
-
-	/* Preamble setup */
-	if (priv->has_preamble) {
-		err = hermes_read_wordrec(hw, USER_BAP,
-					  HERMES_RID_CNFPREAMBLE_SYMBOL,
-					  &priv->preamble);
-		if (err)
-			goto out;
-	}
-
 	/* Set up the default configuration */
-	priv->iw_mode = IW_MODE_INFRA;
+	priv->iw_mode = NL80211_IFTYPE_STATION;
 	/* By default use IEEE/IBSS ad-hoc mode if we have it */
 	priv->prefer_port3 = priv->has_port3 && (!priv->has_ibss);
 	set_port_type(priv);
 	priv->channel = 0; /* use firmware default */
 
 	priv->promiscuous = 0;
-	priv->encode_alg = IW_ENCODE_ALG_NONE;
+	priv->encode_alg = ORINOCO_ALG_NONE;
 	priv->tx_key = 0;
 	priv->wpa_enabled = 0;
 	priv->tkip_cm_active = 0;
@@ -2502,20 +2059,25 @@ static int orinoco_init(struct net_device *dev)
 	priv->wpa_ie_len = 0;
 	priv->wpa_ie = NULL;
 
+	if (orinoco_wiphy_register(wiphy)) {
+		err = -ENODEV;
+		goto out;
+	}
+
 	/* Make the hardware available, as long as it hasn't been
 	 * removed elsewhere (e.g. by PCMCIA hot unplug) */
 	spin_lock_irq(&priv->lock);
 	priv->hw_unavailable--;
 	spin_unlock_irq(&priv->lock);
 
-	printk(KERN_DEBUG "%s: ready\n", dev->name);
+	dev_dbg(dev, "Ready\n");
 
  out:
 	return err;
 }
+EXPORT_SYMBOL(orinoco_init);
 
 static const struct net_device_ops orinoco_netdev_ops = {
-	.ndo_init		= orinoco_init,
 	.ndo_open		= orinoco_open,
 	.ndo_stop		= orinoco_stop,
 	.ndo_start_xmit		= orinoco_xmit,
@@ -2527,40 +2089,64 @@ static const struct net_device_ops orinoco_netdev_ops = {
 	.ndo_get_stats		= orinoco_get_stats,
 };
 
-struct net_device
+/* Allocate private data.
+ *
+ * This driver has a number of structures associated with it
+ *  netdev - Net device structure for each network interface
+ *  wiphy - structure associated with wireless phy
+ *  wireless_dev (wdev) - structure for each wireless interface
+ *  hw - structure for hermes chip info
+ *  card - card specific structure for use by the card driver
+ *         (airport, orinoco_cs)
+ *  priv - orinoco private data
+ *  device - generic linux device structure
+ *
+ *  +---------+    +---------+
+ *  |  wiphy  |    | netdev  |
+ *  | +-------+    | +-------+
+ *  | | priv  |    | | wdev  |
+ *  | | +-----+    +-+-------+
+ *  | | | hw  |
+ *  | +-+-----+
+ *  | | card  |
+ *  +-+-------+
+ *
+ * priv has a link to netdev and device
+ * wdev has a link to wiphy
+ */
+struct orinoco_private
 *alloc_orinocodev(int sizeof_card,
 		  struct device *device,
 		  int (*hard_reset)(struct orinoco_private *),
 		  int (*stop_fw)(struct orinoco_private *, int))
 {
-	struct net_device *dev;
 	struct orinoco_private *priv;
+	struct wiphy *wiphy;
 
-	dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
-	if (!dev)
+	/* allocate wiphy
+	 * NOTE: We only support a single virtual interface
+	 *       but this may change when monitor mode is added
+	 */
+	wiphy = wiphy_new(&orinoco_cfg_ops,
+			  sizeof(struct orinoco_private) + sizeof_card);
+	if (!wiphy)
 		return NULL;
-	priv = netdev_priv(dev);
-	priv->ndev = dev;
+
+	priv = wiphy_priv(wiphy);
+	priv->dev = device;
+
 	if (sizeof_card)
 		priv->card = (void *)((unsigned long)priv
 				      + sizeof(struct orinoco_private));
 	else
 		priv->card = NULL;
-	priv->dev = device;
 
-	/* Setup / override net_device fields */
-	dev->netdev_ops = &orinoco_netdev_ops;
-	dev->watchdog_timeo = HZ; /* 1 second timeout */
-	dev->ethtool_ops = &orinoco_ethtool_ops;
-	dev->wireless_handlers = &orinoco_handler_def;
+	orinoco_wiphy_init(wiphy);
+
 #ifdef WIRELESS_SPY
 	priv->wireless_data.spy_data = &priv->spy_data;
-	dev->wireless_data = &priv->wireless_data;
 #endif
 
-	/* Reserve space in skb for the SNAP header */
-	dev->hard_header_len += ENCAPS_OVERHEAD;
-
 	/* Set up default callbacks */
 	priv->hard_reset = hard_reset;
 	priv->stop_fw = stop_fw;
@@ -2576,9 +2162,12 @@ struct net_device
 
 	INIT_LIST_HEAD(&priv->rx_list);
 	tasklet_init(&priv->rx_tasklet, orinoco_rx_isr_tasklet,
-		     (unsigned long) dev);
+		     (unsigned long) priv);
+
+	spin_lock_init(&priv->scan_lock);
+	INIT_LIST_HEAD(&priv->scan_list);
+	INIT_WORK(&priv->process_scan, orinoco_process_scan_results);
 
-	netif_carrier_off(dev);
 	priv->last_linkstatus = 0xffff;
 
 #if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
@@ -2589,14 +2178,91 @@ struct net_device
 	/* Register PM notifiers */
 	orinoco_register_pm_notifier(priv);
 
-	return dev;
+	return priv;
 }
 EXPORT_SYMBOL(alloc_orinocodev);
 
-void free_orinocodev(struct net_device *dev)
+/* We can only support a single interface. We provide a separate
+ * function to set it up to distinguish between hardware
+ * initialisation and interface setup.
+ *
+ * The base_addr and irq parameters are passed on to netdev for use
+ * with SIOCGIFMAP.
+ */
+int orinoco_if_add(struct orinoco_private *priv,
+		   unsigned long base_addr,
+		   unsigned int irq)
+{
+	struct wiphy *wiphy = priv_to_wiphy(priv);
+	struct wireless_dev *wdev;
+	struct net_device *dev;
+	int ret;
+
+	dev = alloc_etherdev(sizeof(struct wireless_dev));
+
+	if (!dev)
+		return -ENOMEM;
+
+	/* Initialise wireless_dev */
+	wdev = netdev_priv(dev);
+	wdev->wiphy = wiphy;
+	wdev->iftype = NL80211_IFTYPE_STATION;
+
+	/* Setup / override net_device fields */
+	dev->ieee80211_ptr = wdev;
+	dev->netdev_ops = &orinoco_netdev_ops;
+	dev->watchdog_timeo = HZ; /* 1 second timeout */
+	dev->ethtool_ops = &orinoco_ethtool_ops;
+	dev->wireless_handlers = &orinoco_handler_def;
+#ifdef WIRELESS_SPY
+	dev->wireless_data = &priv->wireless_data;
+#endif
+	/* we use the default eth_mac_addr for setting the MAC addr */
+
+	/* Reserve space in skb for the SNAP header */
+	dev->hard_header_len += ENCAPS_OVERHEAD;
+
+	netif_carrier_off(dev);
+
+	memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
+
+	dev->base_addr = base_addr;
+	dev->irq = irq;
+
+	SET_NETDEV_DEV(dev, priv->dev);
+	ret = register_netdev(dev);
+	if (ret)
+		goto fail;
+
+	priv->ndev = dev;
+
+	/* Report what we've done */
+	dev_dbg(priv->dev, "Registerred interface %s.\n", dev->name);
+
+	return 0;
+
+ fail:
+	free_netdev(dev);
+	return ret;
+}
+EXPORT_SYMBOL(orinoco_if_add);
+
+void orinoco_if_del(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+
+	unregister_netdev(dev);
+	free_netdev(dev);
+}
+EXPORT_SYMBOL(orinoco_if_del);
+
+void free_orinocodev(struct orinoco_private *priv)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct wiphy *wiphy = priv_to_wiphy(priv);
 	struct orinoco_rx_data *rx_data, *temp;
+	struct orinoco_scan_data *sd, *sdtemp;
+
+	wiphy_unregister(wiphy);
 
 	/* If the tasklet is scheduled when we call tasklet_kill it
 	 * will run one final time. However the tasklet will only
@@ -2612,21 +2278,80 @@ void free_orinocodev(struct net_device *dev)
 		kfree(rx_data);
 	}
 
+	cancel_work_sync(&priv->process_scan);
+	/* Explicitly drain priv->scan_list */
+	list_for_each_entry_safe(sd, sdtemp, &priv->scan_list, list) {
+		list_del(&sd->list);
+
+		if ((sd->len > 0) && sd->buf)
+			kfree(sd->buf);
+		kfree(sd);
+	}
+
 	orinoco_unregister_pm_notifier(priv);
 	orinoco_uncache_fw(priv);
 
 	priv->wpa_ie_len = 0;
 	kfree(priv->wpa_ie);
 	orinoco_mic_free(priv);
-	orinoco_bss_data_free(priv);
-	free_netdev(dev);
+	wiphy_free(wiphy);
 }
 EXPORT_SYMBOL(free_orinocodev);
 
+int orinoco_up(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	err = orinoco_reinit_firmware(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+		       dev->name, err);
+		goto exit;
+	}
+
+	netif_device_attach(dev);
+	priv->hw_unavailable--;
+
+	if (priv->open && !priv->hw_unavailable) {
+		err = __orinoco_up(priv);
+		if (err)
+			printk(KERN_ERR "%s: Error %d restarting card\n",
+			       dev->name, err);
+	}
+
+exit:
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(orinoco_up);
+
+void orinoco_down(struct orinoco_private *priv)
+{
+	struct net_device *dev = priv->ndev;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	err = __orinoco_down(priv);
+	if (err)
+		printk(KERN_WARNING "%s: Error %d downing interface\n",
+		       dev->name, err);
+
+	netif_device_detach(dev);
+	priv->hw_unavailable++;
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+EXPORT_SYMBOL(orinoco_down);
+
 static void orinoco_get_drvinfo(struct net_device *dev,
 				struct ethtool_drvinfo *info)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
 	strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h
index af2bae4..21ab36c 100644
--- a/drivers/net/wireless/orinoco/main.h
+++ b/drivers/net/wireless/orinoco/main.h
@@ -29,10 +29,9 @@ struct net_device;
 struct work_struct;
 
 void set_port_type(struct orinoco_private *priv);
-int __orinoco_program_rids(struct net_device *dev);
+int orinoco_commit(struct orinoco_private *priv);
 void orinoco_reset(struct work_struct *work);
 
-
 /* Information element helpers - find a home for these... */
 static inline u8 *orinoco_get_ie(u8 *data, size_t len,
 				 enum ieee80211_eid eid)
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 8e5a72c..9ac6f1d 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -14,6 +14,7 @@
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 
 #include "hermes.h"
 
@@ -24,6 +25,7 @@
 
 #define MAX_SCAN_LEN		4096
 
+#define ORINOCO_SEQ_LEN		8
 #define ORINOCO_MAX_KEY_SIZE	14
 #define ORINOCO_MAX_KEYS	4
 
@@ -41,24 +43,18 @@ struct orinoco_tkip_key {
 	u8 rx_mic[MIC_KEYLEN];
 };
 
+enum orinoco_alg {
+	ORINOCO_ALG_NONE,
+	ORINOCO_ALG_WEP,
+	ORINOCO_ALG_TKIP
+};
+
 typedef enum {
 	FIRMWARE_TYPE_AGERE,
 	FIRMWARE_TYPE_INTERSIL,
 	FIRMWARE_TYPE_SYMBOL
 } fwtype_t;
 
-struct bss_element {
-	union hermes_scan_info bss;
-	unsigned long last_scanned;
-	struct list_head list;
-};
-
-struct xbss_element {
-	struct agere_ext_scan_info bss;
-	unsigned long last_scanned;
-	struct list_head list;
-};
-
 struct firmware;
 
 struct orinoco_private {
@@ -67,6 +63,10 @@ struct orinoco_private {
 	int (*hard_reset)(struct orinoco_private *);
 	int (*stop_fw)(struct orinoco_private *, int);
 
+	struct ieee80211_supported_band band;
+	struct ieee80211_channel channels[14];
+	u32 cipher_suites[3];
+
 	/* Synchronisation stuff */
 	spinlock_t lock;
 	int hw_unavailable;
@@ -114,12 +114,14 @@ struct orinoco_private {
 	unsigned int do_fw_download:1;
 	unsigned int broken_disableport:1;
 	unsigned int broken_monitor:1;
+	unsigned int prefer_port3:1;
 
 	/* Configuration paramaters */
-	u32 iw_mode;
-	int prefer_port3;
-	u16 encode_alg, wep_restrict, tx_key;
-	struct orinoco_key keys[ORINOCO_MAX_KEYS];
+	enum nl80211_iftype iw_mode;
+	enum orinoco_alg encode_alg;
+	u16 wep_restrict, tx_key;
+	struct key_params keys[ORINOCO_MAX_KEYS];
+
 	int bitratemode;
 	char nick[IW_ESSID_MAX_SIZE+1];
 	char desired_essid[IW_ESSID_MAX_SIZE+1];
@@ -140,18 +142,15 @@ struct orinoco_private {
 	int promiscuous, mc_count;
 
 	/* Scanning support */
-	struct list_head bss_list;
-	struct list_head bss_free_list;
-	void *bss_xbss_data;
-
-	int	scan_inprogress;	/* Scan pending... */
-	u32	scan_mode;		/* Type of scan done */
+	struct cfg80211_scan_request *scan_request;
+	struct work_struct process_scan;
+	struct list_head scan_list;
+	spinlock_t scan_lock; /* protects the scan list */
 
 	/* WPA support */
 	u8 *wpa_ie;
 	int wpa_ie_len;
 
-	struct orinoco_tkip_key tkip_key[ORINOCO_MAX_KEYS];
 	struct crypto_hash *rx_tfm_mic;
 	struct crypto_hash *tx_tfm_mic;
 
@@ -182,14 +181,18 @@ extern int orinoco_debug;
 /* Exported prototypes                                              */
 /********************************************************************/
 
-extern struct net_device *alloc_orinocodev(
+extern struct orinoco_private *alloc_orinocodev(
 	int sizeof_card, struct device *device,
 	int (*hard_reset)(struct orinoco_private *),
 	int (*stop_fw)(struct orinoco_private *, int));
-extern void free_orinocodev(struct net_device *dev);
-extern int __orinoco_up(struct net_device *dev);
-extern int __orinoco_down(struct net_device *dev);
-extern int orinoco_reinit_firmware(struct net_device *dev);
+extern void free_orinocodev(struct orinoco_private *priv);
+extern int orinoco_init(struct orinoco_private *priv);
+extern int orinoco_if_add(struct orinoco_private *priv,
+			  unsigned long base_addr,
+			  unsigned int irq);
+extern void orinoco_if_del(struct orinoco_private *priv);
+extern int orinoco_up(struct orinoco_private *priv);
+extern void orinoco_down(struct orinoco_private *priv);
 extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
 
 /********************************************************************/
@@ -215,4 +218,10 @@ static inline void orinoco_unlock(struct orinoco_private *priv,
 	spin_unlock_irqrestore(&priv->lock, *flags);
 }
 
+/*** Navigate from net_device to orinoco_private ***/
+static inline struct orinoco_private *ndev_priv(struct net_device *dev)
+{
+	struct wireless_dev *wdev = netdev_priv(dev);
+	return wdev_priv(wdev);
+}
 #endif /* _ORINOCO_H */
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index b381aed..38c1c9d 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -106,26 +106,24 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
 static int
 orinoco_cs_probe(struct pcmcia_device *link)
 {
-	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 
-	dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
-			       orinoco_cs_hard_reset, NULL);
-	if (!dev)
+	priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+				orinoco_cs_hard_reset, NULL);
+	if (!priv)
 		return -ENOMEM;
-	priv = netdev_priv(dev);
 	card = priv->card;
 
 	/* Link both structures together */
 	card->p_dev = link;
-	link->priv = dev;
+	link->priv = priv;
 
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = dev;
+	link->irq.Instance = priv;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -146,14 +144,14 @@ orinoco_cs_probe(struct pcmcia_device *link)
  */
 static void orinoco_cs_detach(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = link->priv;
 
 	if (link->dev_node)
-		unregister_netdev(dev);
+		orinoco_if_del(priv);
 
 	orinoco_cs_release(link);
 
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 }				/* orinoco_cs_detach */
 
 /*
@@ -239,8 +237,7 @@ next_entry:
 static int
 orinoco_cs_config(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
 	hermes_t *hw = &priv->hw;
 	int last_fn, last_ret;
@@ -295,29 +292,27 @@ orinoco_cs_config(struct pcmcia_device *link)
 		 pcmcia_request_configuration(link, &link->conf));
 
 	/* Ok, we have the configuration, prepare to register the netdev */
-	dev->base_addr = link->io.BasePort1;
-	dev->irq = link->irq.AssignedIRQ;
 	card->node.major = card->node.minor = 0;
 
-	SET_NETDEV_DEV(dev, &handle_to_dev(link));
-	/* Tell the stack we exist */
-	if (register_netdev(dev) != 0) {
-		printk(KERN_ERR PFX "register_netdev() failed\n");
+	/* Initialise the main driver */
+	if (orinoco_init(priv) != 0) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto failed;
+	}
+
+	/* Register an interface with the stack */
+	if (orinoco_if_add(priv, link->io.BasePort1,
+			   link->irq.AssignedIRQ) != 0) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto failed;
 	}
 
 	/* At this point, the dev_node_t structure(s) needs to be
 	 * initialized and arranged in a linked list at link->dev_node. */
-	strcpy(card->node.dev_name, dev->name);
+	strcpy(card->node.dev_name, priv->ndev->name);
 	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
 				       * used to indicate that the
 				       * net_device has been registered */
-
-	/* Finally, report what we've done */
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-	       "0x%04x-0x%04x\n", dev->name, dev_name(dev->dev.parent),
-	       link->irq.AssignedIRQ, link->io.BasePort1,
-	       link->io.BasePort1 + link->io.NumPorts1 - 1);
 	return 0;
 
  cs_failed:
@@ -336,8 +331,7 @@ orinoco_cs_config(struct pcmcia_device *link)
 static void
 orinoco_cs_release(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	unsigned long flags;
 
 	/* We're committed to taking the device away now, so mark the
@@ -353,62 +347,26 @@ orinoco_cs_release(struct pcmcia_device *link)
 
 static int orinoco_cs_suspend(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
-	int err = 0;
-	unsigned long flags;
 
 	/* This is probably racy, but I can't think of
 	   a better way, short of rewriting the PCMCIA
 	   layer to not suck :-( */
-	if (!test_bit(0, &card->hard_reset_in_progress)) {
-		spin_lock_irqsave(&priv->lock, flags);
-
-		err = __orinoco_down(dev);
-		if (err)
-			printk(KERN_WARNING "%s: Error %d downing interface\n",
-			       dev->name, err);
-
-		netif_device_detach(dev);
-		priv->hw_unavailable++;
-
-		spin_unlock_irqrestore(&priv->lock, flags);
-	}
+	if (!test_bit(0, &card->hard_reset_in_progress))
+		orinoco_down(priv);
 
 	return 0;
 }
 
 static int orinoco_cs_resume(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
 	int err = 0;
-	unsigned long flags;
-
-	if (!test_bit(0, &card->hard_reset_in_progress)) {
-		err = orinoco_reinit_firmware(dev);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
-			       dev->name, err);
-			return -EIO;
-		}
-
-		spin_lock_irqsave(&priv->lock, flags);
 
-		netif_device_attach(dev);
-		priv->hw_unavailable--;
-
-		if (priv->open && !priv->hw_unavailable) {
-			err = __orinoco_up(dev);
-			if (err)
-				printk(KERN_ERR "%s: Error %d restarting card\n",
-				       dev->name, err);
-		}
-
-		spin_unlock_irqrestore(&priv->lock, flags);
-	}
+	if (!test_bit(0, &card->hard_reset_in_progress))
+		err = orinoco_up(priv);
 
 	return err;
 }
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index b017262..c13a4c3 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -144,7 +144,6 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io, *bridge_io, *attr_io;
 
 	err = pci_enable_device(pdev);
@@ -181,24 +180,22 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_nortel_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_nortel_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
 	card = priv->card;
 	card->bridge_io = bridge_io;
 	card->attr_io = attr_io;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -217,24 +214,28 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_init(priv);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
+	err = orinoco_if_add(priv, 0, 0);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
+		goto fail;
+	}
+
+	pci_set_drvdata(pdev, priv);
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -256,17 +257,16 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
 	struct orinoco_pci_card *card = priv->card;
 
 	/* Clear LEDs */
 	iowrite16(0, card->bridge_io + 10);
 
-	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	orinoco_if_del(priv);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_iounmap(pdev, card->attr_io);
 	pci_iounmap(pdev, card->bridge_io);
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index 78cafff..fea7781 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -116,7 +116,6 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io;
 
 	err = pci_enable_device(pdev);
@@ -139,22 +138,20 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_pci_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_pci_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
 	card = priv->card;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -167,24 +164,28 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_init(priv);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
+	err = orinoco_if_add(priv, 0, 0);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
+		goto fail;
+	}
+
+	pci_set_drvdata(pdev, priv);
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -200,13 +201,12 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
 
-	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	orinoco_if_del(priv);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.h b/drivers/net/wireless/orinoco/orinoco_pci.h
index c655b4a..ea7231a 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.h
+++ b/drivers/net/wireless/orinoco/orinoco_pci.h
@@ -21,30 +21,10 @@ struct orinoco_pci_card {
 #ifdef CONFIG_PM
 static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-	int err;
-
-	err = orinoco_lock(priv, &flags);
-	if (err) {
-		printk(KERN_ERR "%s: cannot lock hardware for suspend\n",
-		       dev->name);
-		return err;
-	}
-
-	err = __orinoco_down(dev);
-	if (err)
-		printk(KERN_WARNING "%s: error %d bringing interface down "
-		       "for suspend\n", dev->name, err);
-
-	netif_device_detach(dev);
-
-	priv->hw_unavailable++;
-
-	orinoco_unlock(priv, &flags);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
 
-	free_irq(pdev->irq, dev);
+	orinoco_down(priv);
+	free_irq(pdev->irq, priv);
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
@@ -54,9 +34,8 @@ static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 
 static int orinoco_pci_resume(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
+	struct net_device *dev = priv->ndev;
 	int err;
 
 	pci_set_power_state(pdev, 0);
@@ -69,7 +48,7 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
 	pci_restore_state(pdev);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  dev->name, priv);
 	if (err) {
 		printk(KERN_ERR "%s: cannot re-allocate IRQ on resume\n",
 		       dev->name);
@@ -77,29 +56,9 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
 		return -EBUSY;
 	}
 
-	err = orinoco_reinit_firmware(dev);
-	if (err) {
-		printk(KERN_ERR "%s: error %d re-initializing firmware "
-		       "on resume\n", dev->name, err);
-		return err;
-	}
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	netif_device_attach(dev);
+	err = orinoco_up(priv);
 
-	priv->hw_unavailable--;
-
-	if (priv->open && (!priv->hw_unavailable)) {
-		err = __orinoco_up(dev);
-		if (err)
-			printk(KERN_ERR "%s: Error %d restarting card on resume\n",
-			       dev->name, err);
-	}
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	return 0;
+	return err;
 }
 #else
 #define orinoco_pci_suspend NULL
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index a2a4471..3f2942a 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -183,7 +183,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io, *attr_io, *bridge_io;
 
 	err = pci_enable_device(pdev);
@@ -220,24 +219,22 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_plx_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_plx_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
 	card = priv->card;
 	card->bridge_io = bridge_io;
 	card->attr_io = attr_io;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -256,24 +253,28 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_init(priv);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
+	err = orinoco_if_add(priv, 0, 0);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
+		goto fail;
+	}
+
+	pci_set_drvdata(pdev, priv);
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -295,14 +296,13 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
 	struct orinoco_pci_card *card = priv->card;
 
-	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	orinoco_if_del(priv);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_iounmap(pdev, card->attr_io);
 	pci_iounmap(pdev, card->bridge_io);
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index cda0e6e..d345254 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -94,7 +94,6 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 	int err;
 	struct orinoco_private *priv;
 	struct orinoco_pci_card *card;
-	struct net_device *dev;
 	void __iomem *hermes_io, *bridge_io;
 
 	err = pci_enable_device(pdev);
@@ -124,23 +123,21 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
-			       orinoco_tmd_cor_reset, NULL);
-	if (!dev) {
+	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
+				orinoco_tmd_cor_reset, NULL);
+	if (!priv) {
 		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
 		goto fail_alloc;
 	}
 
-	priv = netdev_priv(dev);
 	card = priv->card;
 	card->bridge_io = bridge_io;
-	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
-			  dev->name, dev);
+			  DRIVER_NAME, priv);
 	if (err) {
 		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
@@ -153,24 +150,28 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	err = register_netdev(dev);
+	err = orinoco_init(priv);
 	if (err) {
-		printk(KERN_ERR PFX "Cannot register network device\n");
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
 		goto fail;
 	}
 
-	pci_set_drvdata(pdev, dev);
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
-	       pci_name(pdev));
+	err = orinoco_if_add(priv, 0, 0);
+	if (err) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
+		goto fail;
+	}
+
+	pci_set_drvdata(pdev, priv);
 
 	return 0;
 
  fail:
-	free_irq(pdev->irq, dev);
+	free_irq(pdev->irq, priv);
 
  fail_irq:
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 
  fail_alloc:
 	pci_iounmap(pdev, hermes_io);
@@ -189,14 +190,13 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
 
 static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
 {
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = pci_get_drvdata(pdev);
 	struct orinoco_pci_card *card = priv->card;
 
-	unregister_netdev(dev);
-	free_irq(pdev->irq, dev);
+	orinoco_if_del(priv);
+	free_irq(pdev->irq, priv);
 	pci_set_drvdata(pdev, NULL);
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 	pci_iounmap(pdev, priv->hw.iobase);
 	pci_iounmap(pdev, card->bridge_io);
 	pci_release_regions(pdev);
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 89d699d..d2f10e9 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -5,147 +5,166 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/etherdevice.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
 
 #include "hermes.h"
 #include "orinoco.h"
+#include "main.h"
 
 #include "scan.h"
 
-#define ORINOCO_MAX_BSS_COUNT	64
+#define ZERO_DBM_OFFSET 0x95
+#define MAX_SIGNAL_LEVEL 0x8A
+#define MIN_SIGNAL_LEVEL 0x2F
 
-#define PRIV_BSS	((struct bss_element *)priv->bss_xbss_data)
-#define PRIV_XBSS	((struct xbss_element *)priv->bss_xbss_data)
+#define SIGNAL_TO_DBM(x)					\
+	(clamp_t(s32, (x), MIN_SIGNAL_LEVEL, MAX_SIGNAL_LEVEL)	\
+	 - ZERO_DBM_OFFSET)
+#define SIGNAL_TO_MBM(x) (SIGNAL_TO_DBM(x) * 100)
 
-int orinoco_bss_data_allocate(struct orinoco_private *priv)
+static int symbol_build_supp_rates(u8 *buf, const __le16 *rates)
 {
-	if (priv->bss_xbss_data)
-		return 0;
-
-	if (priv->has_ext_scan)
-		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-					      sizeof(struct xbss_element),
-					      GFP_KERNEL);
-	else
-		priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
-					      sizeof(struct bss_element),
-					      GFP_KERNEL);
-
-	if (!priv->bss_xbss_data) {
-		printk(KERN_WARNING "Out of memory allocating beacons");
-		return -ENOMEM;
+	int i;
+	u8 rate;
+
+	buf[0] = WLAN_EID_SUPP_RATES;
+	for (i = 0; i < 5; i++) {
+		rate = le16_to_cpu(rates[i]);
+		/* NULL terminated */
+		if (rate == 0x0)
+			break;
+		buf[i + 2] = rate;
 	}
-	return 0;
-}
+	buf[1] = i;
 
-void orinoco_bss_data_free(struct orinoco_private *priv)
-{
-	kfree(priv->bss_xbss_data);
-	priv->bss_xbss_data = NULL;
+	return i + 2;
 }
 
-void orinoco_bss_data_init(struct orinoco_private *priv)
+static int prism_build_supp_rates(u8 *buf, const u8 *rates)
 {
 	int i;
 
-	INIT_LIST_HEAD(&priv->bss_free_list);
-	INIT_LIST_HEAD(&priv->bss_list);
-	if (priv->has_ext_scan)
-		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-			list_add_tail(&(PRIV_XBSS[i].list),
-				      &priv->bss_free_list);
-	else
-		for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
-			list_add_tail(&(PRIV_BSS[i].list),
-				      &priv->bss_free_list);
-
-}
-
-void orinoco_clear_scan_results(struct orinoco_private *priv,
-				unsigned long scan_age)
-{
-	if (priv->has_ext_scan) {
-		struct xbss_element *bss;
-		struct xbss_element *tmp_bss;
-
-		/* Blow away current list of scan results */
-		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-			if (!scan_age ||
-			    time_after(jiffies, bss->last_scanned + scan_age)) {
-				list_move_tail(&bss->list,
-					       &priv->bss_free_list);
-				/* Don't blow away ->list, just BSS data */
-				memset(&bss->bss, 0, sizeof(bss->bss));
-				bss->last_scanned = 0;
-			}
-		}
-	} else {
-		struct bss_element *bss;
-		struct bss_element *tmp_bss;
-
-		/* Blow away current list of scan results */
-		list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
-			if (!scan_age ||
-			    time_after(jiffies, bss->last_scanned + scan_age)) {
-				list_move_tail(&bss->list,
-					       &priv->bss_free_list);
-				/* Don't blow away ->list, just BSS data */
-				memset(&bss->bss, 0, sizeof(bss->bss));
-				bss->last_scanned = 0;
-			}
+	buf[0] = WLAN_EID_SUPP_RATES;
+	for (i = 0; i < 8; i++) {
+		/* NULL terminated */
+		if (rates[i] == 0x0)
+			break;
+		buf[i + 2] = rates[i];
+	}
+	buf[1] = i;
+
+	/* We might still have another 2 rates, which need to go in
+	 * extended supported rates */
+	if (i == 8 && rates[i] > 0) {
+		buf[10] = WLAN_EID_EXT_SUPP_RATES;
+		for (; i < 10; i++) {
+			/* NULL terminated */
+			if (rates[i] == 0x0)
+				break;
+			buf[i + 2] = rates[i];
 		}
+		buf[11] = i - 8;
 	}
+
+	return (i < 8) ? i + 2 : i + 4;
 }
 
-void orinoco_add_ext_scan_result(struct orinoco_private *priv,
-				 struct agere_ext_scan_info *atom)
+static void orinoco_add_hostscan_result(struct orinoco_private *priv,
+					const union hermes_scan_info *bss)
 {
-	struct xbss_element *bss = NULL;
-	int found = 0;
-
-	/* Try to update an existing bss first */
-	list_for_each_entry(bss, &priv->bss_list, list) {
-		if (compare_ether_addr(bss->bss.bssid, atom->bssid))
-			continue;
-		/* ESSID lengths */
-		if (bss->bss.data[1] != atom->data[1])
-			continue;
-		if (memcmp(&bss->bss.data[2], &atom->data[2],
-			   atom->data[1]))
-			continue;
-		found = 1;
+	struct wiphy *wiphy = priv_to_wiphy(priv);
+	struct ieee80211_channel *channel;
+	u8 *ie;
+	u8 ie_buf[46];
+	u64 timestamp;
+	s32 signal;
+	u16 capability;
+	u16 beacon_interval;
+	int ie_len;
+	int freq;
+	int len;
+
+	len = le16_to_cpu(bss->a.essid_len);
+
+	/* Reconstruct SSID and bitrate IEs to pass up */
+	ie_buf[0] = WLAN_EID_SSID;
+	ie_buf[1] = len;
+	memcpy(&ie_buf[2], bss->a.essid, len);
+
+	ie = ie_buf + len + 2;
+	ie_len = ie_buf[1] + 2;
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_SYMBOL:
+		ie_len += symbol_build_supp_rates(ie, bss->s.rates);
 		break;
-	}
 
-	/* Grab a bss off the free list */
-	if (!found && !list_empty(&priv->bss_free_list)) {
-		bss = list_entry(priv->bss_free_list.next,
-				 struct xbss_element, list);
-		list_del(priv->bss_free_list.next);
+	case FIRMWARE_TYPE_INTERSIL:
+		ie_len += prism_build_supp_rates(ie, bss->p.rates);
+		break;
 
-		list_add_tail(&bss->list, &priv->bss_list);
+	case FIRMWARE_TYPE_AGERE:
+	default:
+		break;
 	}
 
-	if (bss) {
-		/* Always update the BSS to get latest beacon info */
-		memcpy(&bss->bss, atom, sizeof(bss->bss));
-		bss->last_scanned = jiffies;
-	}
+	freq = ieee80211_dsss_chan_to_freq(le16_to_cpu(bss->a.channel));
+	channel = ieee80211_get_channel(wiphy, freq);
+	timestamp = 0;
+	capability = le16_to_cpu(bss->a.capabilities);
+	beacon_interval = le16_to_cpu(bss->a.beacon_interv);
+	signal = SIGNAL_TO_MBM(le16_to_cpu(bss->a.level));
+
+	cfg80211_inform_bss(wiphy, channel, bss->a.bssid, timestamp,
+			    capability, beacon_interval, ie_buf, ie_len,
+			    signal, GFP_KERNEL);
 }
 
-int orinoco_process_scan_results(struct orinoco_private *priv,
-				 unsigned char *buf,
-				 int len)
+void orinoco_add_extscan_result(struct orinoco_private *priv,
+				struct agere_ext_scan_info *bss,
+				size_t len)
 {
-	int			offset;		/* In the scan data */
-	union hermes_scan_info *atom;
-	int			atom_len;
+	struct wiphy *wiphy = priv_to_wiphy(priv);
+	struct ieee80211_channel *channel;
+	u8 *ie;
+	u64 timestamp;
+	s32 signal;
+	u16 capability;
+	u16 beacon_interval;
+	size_t ie_len;
+	int chan, freq;
+
+	ie_len = len - sizeof(*bss);
+	ie = orinoco_get_ie(bss->data, ie_len, WLAN_EID_DS_PARAMS);
+	chan = ie ? ie[2] : 0;
+	freq = ieee80211_dsss_chan_to_freq(chan);
+	channel = ieee80211_get_channel(wiphy, freq);
+
+	timestamp = le64_to_cpu(bss->timestamp);
+	capability = le16_to_cpu(bss->capabilities);
+	beacon_interval = le16_to_cpu(bss->beacon_interval);
+	ie = bss->data;
+	signal = SIGNAL_TO_MBM(bss->level);
+
+	cfg80211_inform_bss(wiphy, channel, bss->bssid, timestamp,
+			    capability, beacon_interval, ie, ie_len,
+			    signal, GFP_KERNEL);
+}
+
+void orinoco_add_hostscan_results(struct orinoco_private *priv,
+				  unsigned char *buf,
+				  size_t len)
+{
+	int offset;		/* In the scan data */
+	size_t atom_len;
+	bool abort = false;
 
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE:
 		atom_len = sizeof(struct agere_scan_apinfo);
 		offset = 0;
 		break;
+
 	case FIRMWARE_TYPE_SYMBOL:
 		/* Lack of documentation necessitates this hack.
 		 * Different firmwares have 68 or 76 byte long atoms.
@@ -163,6 +182,7 @@ int orinoco_process_scan_results(struct orinoco_private *priv,
 			atom_len = 68;
 		offset = 0;
 		break;
+
 	case FIRMWARE_TYPE_INTERSIL:
 		offset = 4;
 		if (priv->has_hostscan) {
@@ -170,64 +190,41 @@ int orinoco_process_scan_results(struct orinoco_private *priv,
 			/* Sanity check for atom_len */
 			if (atom_len < sizeof(struct prism2_scan_apinfo)) {
 				printk(KERN_ERR "%s: Invalid atom_len in scan "
-				       "data: %d\n", priv->ndev->name,
+				       "data: %zu\n", priv->ndev->name,
 				       atom_len);
-				return -EIO;
+				abort = true;
+				goto scan_abort;
 			}
 		} else
 			atom_len = offsetof(struct prism2_scan_apinfo, atim);
 		break;
+
 	default:
-		return -EOPNOTSUPP;
+		abort = true;
+		goto scan_abort;
 	}
 
 	/* Check that we got an whole number of atoms */
 	if ((len - offset) % atom_len) {
-		printk(KERN_ERR "%s: Unexpected scan data length %d, "
-		       "atom_len %d, offset %d\n", priv->ndev->name, len,
+		printk(KERN_ERR "%s: Unexpected scan data length %zu, "
+		       "atom_len %zu, offset %d\n", priv->ndev->name, len,
 		       atom_len, offset);
-		return -EIO;
+		abort = true;
+		goto scan_abort;
 	}
 
-	orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
-
-	/* Read the entries one by one */
+	/* Process the entries one by one */
 	for (; offset + atom_len <= len; offset += atom_len) {
-		int found = 0;
-		struct bss_element *bss = NULL;
+		union hermes_scan_info *atom;
 
-		/* Get next atom */
 		atom = (union hermes_scan_info *) (buf + offset);
 
-		/* Try to update an existing bss first */
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
-				continue;
-			if (le16_to_cpu(bss->bss.a.essid_len) !=
-			      le16_to_cpu(atom->a.essid_len))
-				continue;
-			if (memcmp(bss->bss.a.essid, atom->a.essid,
-			      le16_to_cpu(atom->a.essid_len)))
-				continue;
-			found = 1;
-			break;
-		}
-
-		/* Grab a bss off the free list */
-		if (!found && !list_empty(&priv->bss_free_list)) {
-			bss = list_entry(priv->bss_free_list.next,
-					 struct bss_element, list);
-			list_del(priv->bss_free_list.next);
-
-			list_add_tail(&bss->list, &priv->bss_list);
-		}
-
-		if (bss) {
-			/* Always update the BSS to get latest beacon info */
-			memcpy(&bss->bss, atom, sizeof(bss->bss));
-			bss->last_scanned = jiffies;
-		}
+		orinoco_add_hostscan_result(priv, atom);
 	}
 
-	return 0;
+ scan_abort:
+	if (priv->scan_request) {
+		cfg80211_scan_done(priv->scan_request, abort);
+		priv->scan_request = NULL;
+	}
 }
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h
index f319f74..2dc4e04 100644
--- a/drivers/net/wireless/orinoco/scan.h
+++ b/drivers/net/wireless/orinoco/scan.h
@@ -9,21 +9,12 @@
 struct orinoco_private;
 struct agere_ext_scan_info;
 
-/* Setup and free memory for scan results */
-int orinoco_bss_data_allocate(struct orinoco_private *priv);
-void orinoco_bss_data_free(struct orinoco_private *priv);
-void orinoco_bss_data_init(struct orinoco_private *priv);
-
 /* Add scan results */
-void orinoco_add_ext_scan_result(struct orinoco_private *priv,
-				 struct agere_ext_scan_info *atom);
-int orinoco_process_scan_results(struct orinoco_private *dev,
-				 unsigned char *buf,
-				 int len);
-
-/* Clear scan results */
-void orinoco_clear_scan_results(struct orinoco_private *priv,
-				unsigned long scan_age);
-
+void orinoco_add_extscan_result(struct orinoco_private *priv,
+				struct agere_ext_scan_info *atom,
+				size_t len);
+void orinoco_add_hostscan_results(struct orinoco_private *dev,
+				  unsigned char *buf,
+				  size_t len);
 
 #endif /* _ORINOCO_SCAN_H_ */
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 38e5198..c361310 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -178,27 +178,25 @@ spectrum_cs_stop_firmware(struct orinoco_private *priv, int idle)
 static int
 spectrum_cs_probe(struct pcmcia_device *link)
 {
-	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 
-	dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
-			       spectrum_cs_hard_reset,
-			       spectrum_cs_stop_firmware);
-	if (!dev)
+	priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+				spectrum_cs_hard_reset,
+				spectrum_cs_stop_firmware);
+	if (!priv)
 		return -ENOMEM;
-	priv = netdev_priv(dev);
 	card = priv->card;
 
 	/* Link both structures together */
 	card->p_dev = link;
-	link->priv = dev;
+	link->priv = priv;
 
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = orinoco_interrupt;
-	link->irq.Instance = dev;
+	link->irq.Instance = priv;
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -219,14 +217,14 @@ spectrum_cs_probe(struct pcmcia_device *link)
  */
 static void spectrum_cs_detach(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = link->priv;
 
 	if (link->dev_node)
-		unregister_netdev(dev);
+		orinoco_if_del(priv);
 
 	spectrum_cs_release(link);
 
-	free_orinocodev(dev);
+	free_orinocodev(priv);
 }				/* spectrum_cs_detach */
 
 /*
@@ -306,8 +304,7 @@ next_entry:
 static int
 spectrum_cs_config(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = priv->card;
 	hermes_t *hw = &priv->hw;
 	int last_fn, last_ret;
@@ -362,34 +359,31 @@ spectrum_cs_config(struct pcmcia_device *link)
 		 pcmcia_request_configuration(link, &link->conf));
 
 	/* Ok, we have the configuration, prepare to register the netdev */
-	dev->base_addr = link->io.BasePort1;
-	dev->irq = link->irq.AssignedIRQ;
 	card->node.major = card->node.minor = 0;
 
 	/* Reset card */
 	if (spectrum_cs_hard_reset(priv) != 0)
 		goto failed;
 
-	SET_NETDEV_DEV(dev, &handle_to_dev(link));
-	/* Tell the stack we exist */
-	if (register_netdev(dev) != 0) {
-		printk(KERN_ERR PFX "register_netdev() failed\n");
+	/* Initialise the main driver */
+	if (orinoco_init(priv) != 0) {
+		printk(KERN_ERR PFX "orinoco_init() failed\n");
+		goto failed;
+	}
+
+	/* Register an interface with the stack */
+	if (orinoco_if_add(priv, link->io.BasePort1,
+			   link->irq.AssignedIRQ) != 0) {
+		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
 		goto failed;
 	}
 
 	/* At this point, the dev_node_t structure(s) needs to be
 	 * initialized and arranged in a linked list at link->dev_node. */
-	strcpy(card->node.dev_name, dev->name);
+	strcpy(card->node.dev_name, priv->ndev->name);
 	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
 				       * used to indicate that the
 				       * net_device has been registered */
-
-	/* Finally, report what we've done */
-	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
-	       "0x%04x-0x%04x\n", dev->name, dev_name(dev->dev.parent),
-	       link->irq.AssignedIRQ, link->io.BasePort1,
-	       link->io.BasePort1 + link->io.NumPorts1 - 1);
-
 	return 0;
 
  cs_failed:
@@ -408,8 +402,7 @@ spectrum_cs_config(struct pcmcia_device *link)
 static void
 spectrum_cs_release(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = link->priv;
 	unsigned long flags;
 
 	/* We're committed to taking the device away now, so mark the
@@ -427,23 +420,11 @@ spectrum_cs_release(struct pcmcia_device *link)
 static int
 spectrum_cs_suspend(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
+	struct orinoco_private *priv = link->priv;
 	int err = 0;
 
 	/* Mark the device as stopped, to block IO until later */
-	spin_lock_irqsave(&priv->lock, flags);
-
-	err = __orinoco_down(dev);
-	if (err)
-		printk(KERN_WARNING "%s: Error %d downing interface\n",
-		       dev->name, err);
-
-	netif_device_detach(dev);
-	priv->hw_unavailable++;
-
-	spin_unlock_irqrestore(&priv->lock, flags);
+	orinoco_down(priv);
 
 	return err;
 }
@@ -451,33 +432,10 @@ spectrum_cs_suspend(struct pcmcia_device *link)
 static int
 spectrum_cs_resume(struct pcmcia_device *link)
 {
-	struct net_device *dev = link->priv;
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-	int err;
-
-	err = orinoco_reinit_firmware(dev);
-	if (err) {
-		printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
-		       dev->name, err);
-		return -EIO;
-	}
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	netif_device_attach(dev);
-	priv->hw_unavailable--;
+	struct orinoco_private *priv = link->priv;
+	int err = orinoco_up(priv);
 
-	if (priv->open && !priv->hw_unavailable) {
-		err = __orinoco_up(dev);
-		if (err)
-			printk(KERN_ERR "%s: Error %d restarting card\n",
-			       dev->name, err);
-	}
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	return 0;
+	return err;
 }
 
 
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 3f08142..7698fdd 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -7,6 +7,7 @@
 #include <linux/wireless.h>
 #include <linux/ieee80211.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 
 #include "hermes.h"
 #include "hermes_rid.h"
@@ -21,9 +22,70 @@
 
 #define MAX_RID_LEN 1024
 
+/* Helper routine to record keys
+ * Do not call from interrupt context */
+static int orinoco_set_key(struct orinoco_private *priv, int index,
+			   enum orinoco_alg alg, const u8 *key, int key_len,
+			   const u8 *seq, int seq_len)
+{
+	kzfree(priv->keys[index].key);
+	kzfree(priv->keys[index].seq);
+
+	if (key_len) {
+		priv->keys[index].key = kzalloc(key_len, GFP_KERNEL);
+		if (!priv->keys[index].key)
+			goto nomem;
+	} else
+		priv->keys[index].key = NULL;
+
+	if (seq_len) {
+		priv->keys[index].seq = kzalloc(seq_len, GFP_KERNEL);
+		if (!priv->keys[index].seq)
+			goto free_key;
+	} else
+		priv->keys[index].seq = NULL;
+
+	priv->keys[index].key_len = key_len;
+	priv->keys[index].seq_len = seq_len;
+
+	if (key_len)
+		memcpy(priv->keys[index].key, key, key_len);
+	if (seq_len)
+		memcpy(priv->keys[index].seq, seq, seq_len);
+
+	switch (alg) {
+	case ORINOCO_ALG_TKIP:
+		priv->keys[index].cipher = WLAN_CIPHER_SUITE_TKIP;
+		break;
+
+	case ORINOCO_ALG_WEP:
+		priv->keys[index].cipher = (key_len > SMALL_KEY_SIZE) ?
+			WLAN_CIPHER_SUITE_WEP104 : WLAN_CIPHER_SUITE_WEP40;
+		break;
+
+	case ORINOCO_ALG_NONE:
+	default:
+		priv->keys[index].cipher = 0;
+		break;
+	}
+
+	return 0;
+
+free_key:
+	kfree(priv->keys[index].key);
+	priv->keys[index].key = NULL;
+
+nomem:
+	priv->keys[index].key_len = 0;
+	priv->keys[index].seq_len = 0;
+	priv->keys[index].cipher = 0;
+
+	return -ENOMEM;
+}
+
 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	struct iw_statistics *wstats = &priv->wstats;
 	int err;
@@ -51,7 +113,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
 	 * here so we're not safe to sleep here. */
 	hermes_inquire(hw, HERMES_INQ_TALLIES);
 
-	if (priv->iw_mode == IW_MODE_ADHOC) {
+	if (priv->iw_mode == NL80211_IFTYPE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
 		/* If a spy address is defined, we report stats of the
 		 * first spy address - Jean II */
@@ -87,31 +149,12 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
 /* Wireless extensions                                              */
 /********************************************************************/
 
-static int orinoco_ioctl_getname(struct net_device *dev,
-				 struct iw_request_info *info,
-				 char *name,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int numrates;
-	int err;
-
-	err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
-
-	if (!err && (numrates > 2))
-		strcpy(name, "IEEE 802.11b");
-	else
-		strcpy(name, "IEEE 802.11-DS");
-
-	return 0;
-}
-
 static int orinoco_ioctl_setwap(struct net_device *dev,
 				struct iw_request_info *info,
 				struct sockaddr *ap_addr,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 	static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -142,7 +185,7 @@ static int orinoco_ioctl_setwap(struct net_device *dev,
 		goto out;
 	}
 
-	if (priv->iw_mode != IW_MODE_INFRA) {
+	if (priv->iw_mode != NL80211_IFTYPE_STATION) {
 		printk(KERN_WARNING "%s: Manual roaming supported only in "
 		       "managed mode\n", dev->name);
 		err = -EOPNOTSUPP;
@@ -172,9 +215,8 @@ static int orinoco_ioctl_getwap(struct net_device *dev,
 				struct sockaddr *ap_addr,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
-	hermes_t *hw = &priv->hw;
 	int err = 0;
 	unsigned long flags;
 
@@ -182,197 +224,23 @@ static int orinoco_ioctl_getwap(struct net_device *dev,
 		return -EBUSY;
 
 	ap_addr->sa_family = ARPHRD_ETHER;
-	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
-			      ETH_ALEN, NULL, ap_addr->sa_data);
+	err = orinoco_hw_get_current_bssid(priv, ap_addr->sa_data);
 
 	orinoco_unlock(priv, &flags);
 
 	return err;
 }
 
-static int orinoco_ioctl_setmode(struct net_device *dev,
-				 struct iw_request_info *info,
-				 u32 *mode,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = -EINPROGRESS;		/* Call commit handler */
-	unsigned long flags;
-
-	if (priv->iw_mode == *mode)
-		return 0;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	switch (*mode) {
-	case IW_MODE_ADHOC:
-		if (!priv->has_ibss && !priv->has_port3)
-			err = -EOPNOTSUPP;
-		break;
-
-	case IW_MODE_INFRA:
-		break;
-
-	case IW_MODE_MONITOR:
-		if (priv->broken_monitor && !force_monitor) {
-			printk(KERN_WARNING "%s: Monitor mode support is "
-			       "buggy in this firmware, not enabling\n",
-			       dev->name);
-			err = -EOPNOTSUPP;
-		}
-		break;
-
-	default:
-		err = -EOPNOTSUPP;
-		break;
-	}
-
-	if (err == -EINPROGRESS) {
-		priv->iw_mode = *mode;
-		set_port_type(priv);
-	}
-
-	orinoco_unlock(priv, &flags);
-
-	return err;
-}
-
-static int orinoco_ioctl_getmode(struct net_device *dev,
-				 struct iw_request_info *info,
-				 u32 *mode,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-
-	*mode = priv->iw_mode;
-	return 0;
-}
-
-static int orinoco_ioctl_getiwrange(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *rrq,
-				    char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
-	struct iw_range *range = (struct iw_range *) extra;
-	int numrates;
-	int i, k;
-
-	rrq->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(struct iw_range));
-
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 22;
-
-	/* Set available channels/frequencies */
-	range->num_channels = NUM_CHANNELS;
-	k = 0;
-	for (i = 0; i < NUM_CHANNELS; i++) {
-		if (priv->channel_mask & (1 << i)) {
-			range->freq[k].i = i + 1;
-			range->freq[k].m = (ieee80211_dsss_chan_to_freq(i + 1) *
-					    100000);
-			range->freq[k].e = 1;
-			k++;
-		}
-
-		if (k >= IW_MAX_FREQUENCIES)
-			break;
-	}
-	range->num_frequency = k;
-	range->sensitivity = 3;
-
-	if (priv->has_wep) {
-		range->max_encoding_tokens = ORINOCO_MAX_KEYS;
-		range->encoding_size[0] = SMALL_KEY_SIZE;
-		range->num_encoding_sizes = 1;
-
-		if (priv->has_big_wep) {
-			range->encoding_size[1] = LARGE_KEY_SIZE;
-			range->num_encoding_sizes = 2;
-		}
-	}
-
-	if (priv->has_wpa)
-		range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_CIPHER_TKIP;
-
-	if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))) {
-		/* Quality stats meaningless in ad-hoc mode */
-	} else {
-		range->max_qual.qual = 0x8b - 0x2f;
-		range->max_qual.level = 0x2f - 0x95 - 1;
-		range->max_qual.noise = 0x2f - 0x95 - 1;
-		/* Need to get better values */
-		range->avg_qual.qual = 0x24;
-		range->avg_qual.level = 0xC2;
-		range->avg_qual.noise = 0x9E;
-	}
-
-	err = orinoco_hw_get_bitratelist(priv, &numrates,
-					 range->bitrate, IW_MAX_BITRATES);
-	if (err)
-		return err;
-	range->num_bitrates = numrates;
-
-	/* Set an indication of the max TCP throughput in bit/s that we can
-	 * expect using this interface. May be use for QoS stuff...
-	 * Jean II */
-	if (numrates > 2)
-		range->throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */
-	else
-		range->throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */
-
-	range->min_rts = 0;
-	range->max_rts = 2347;
-	range->min_frag = 256;
-	range->max_frag = 2346;
-
-	range->min_pmp = 0;
-	range->max_pmp = 65535000;
-	range->min_pmt = 0;
-	range->max_pmt = 65535 * 1000;	/* ??? */
-	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);
-
-	range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
-	range->retry_flags = IW_RETRY_LIMIT;
-	range->r_time_flags = IW_RETRY_LIFETIME;
-	range->min_retry = 0;
-	range->max_retry = 65535;	/* ??? */
-	range->min_r_time = 0;
-	range->max_r_time = 65535 * 1000;	/* ??? */
-
-	if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
-		range->scan_capa = IW_SCAN_CAPA_ESSID;
-	else
-		range->scan_capa = IW_SCAN_CAPA_NONE;
-
-	/* Event capability (kernel) */
-	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
-	/* Event capability (driver) */
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
-	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
-	IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
-
-	return 0;
-}
-
 static int orinoco_ioctl_setiwencode(struct net_device *dev,
 				     struct iw_request_info *info,
 				     struct iw_point *erq,
 				     char *keybuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	int setindex = priv->tx_key;
-	int encode_alg = priv->encode_alg;
+	enum orinoco_alg encode_alg = priv->encode_alg;
 	int restricted = priv->wep_restrict;
-	u16 xlen = 0;
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
@@ -392,25 +260,17 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
 		return -EBUSY;
 
 	/* Clear any TKIP key we have */
-	if ((priv->has_wpa) && (priv->encode_alg == IW_ENCODE_ALG_TKIP))
+	if ((priv->has_wpa) && (priv->encode_alg == ORINOCO_ALG_TKIP))
 		(void) orinoco_clear_tkip_key(priv, setindex);
 
 	if (erq->length > 0) {
 		if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
 			index = priv->tx_key;
 
-		/* Adjust key length to a supported value */
-		if (erq->length > SMALL_KEY_SIZE)
-			xlen = LARGE_KEY_SIZE;
-		else if (erq->length > 0)
-			xlen = SMALL_KEY_SIZE;
-		else
-			xlen = 0;
-
 		/* Switch on WEP if off */
-		if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
+		if (encode_alg != ORINOCO_ALG_WEP) {
 			setindex = index;
-			encode_alg = IW_ENCODE_ALG_WEP;
+			encode_alg = ORINOCO_ALG_WEP;
 		}
 	} else {
 		/* Important note : if the user do "iwconfig eth0 enc off",
@@ -423,7 +283,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
 			}
 		} else {
 			/* Set the index : Check that the key is valid */
-			if (priv->keys[index].len == 0) {
+			if (priv->keys[index].key_len == 0) {
 				err = -EINVAL;
 				goto out;
 			}
@@ -432,17 +292,15 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev,
 	}
 
 	if (erq->flags & IW_ENCODE_DISABLED)
-		encode_alg = IW_ENCODE_ALG_NONE;
+		encode_alg = ORINOCO_ALG_NONE;
 	if (erq->flags & IW_ENCODE_OPEN)
 		restricted = 0;
 	if (erq->flags & IW_ENCODE_RESTRICTED)
 		restricted = 1;
 
 	if (erq->pointer && erq->length > 0) {
-		priv->keys[index].len = cpu_to_le16(xlen);
-		memset(priv->keys[index].data, 0,
-		       sizeof(priv->keys[index].data));
-		memcpy(priv->keys[index].data, keybuf, erq->length);
+		err = orinoco_set_key(priv, index, ORINOCO_ALG_WEP, keybuf,
+				      erq->length, NULL, 0);
 	}
 	priv->tx_key = setindex;
 
@@ -469,9 +327,8 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev,
 				     struct iw_point *erq,
 				     char *keybuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-	u16 xlen = 0;
 	unsigned long flags;
 
 	if (!priv->has_wep)
@@ -493,11 +350,9 @@ static int orinoco_ioctl_getiwencode(struct net_device *dev,
 	else
 		erq->flags |= IW_ENCODE_OPEN;
 
-	xlen = le16_to_cpu(priv->keys[index].len);
-
-	erq->length = xlen;
+	erq->length = priv->keys[index].key_len;
 
-	memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
+	memcpy(keybuf, priv->keys[index].key, erq->length);
 
 	orinoco_unlock(priv, &flags);
 	return 0;
@@ -508,7 +363,7 @@ static int orinoco_ioctl_setessid(struct net_device *dev,
 				  struct iw_point *erq,
 				  char *essidbuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 
 	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
@@ -539,7 +394,7 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
 				  struct iw_point *erq,
 				  char *essidbuf)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int active;
 	int err = 0;
 	unsigned long flags;
@@ -562,59 +417,18 @@ static int orinoco_ioctl_getessid(struct net_device *dev,
 	return 0;
 }
 
-static int orinoco_ioctl_setnick(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *nrq,
-				 char *nickbuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-
-	if (nrq->length > IW_ESSID_MAX_SIZE)
-		return -E2BIG;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	memset(priv->nick, 0, sizeof(priv->nick));
-	memcpy(priv->nick, nickbuf, nrq->length);
-
-	orinoco_unlock(priv, &flags);
-
-	return -EINPROGRESS;		/* Call commit handler */
-}
-
-static int orinoco_ioctl_getnick(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *nrq,
-				 char *nickbuf)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	unsigned long flags;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
-	orinoco_unlock(priv, &flags);
-
-	nrq->length = strlen(priv->nick);
-
-	return 0;
-}
-
 static int orinoco_ioctl_setfreq(struct net_device *dev,
 				 struct iw_request_info *info,
 				 struct iw_freq *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int chan = -1;
 	unsigned long flags;
 	int err = -EINPROGRESS;		/* Call commit handler */
 
 	/* In infrastructure mode the AP sets the channel */
-	if (priv->iw_mode == IW_MODE_INFRA)
+	if (priv->iw_mode == NL80211_IFTYPE_STATION)
 		return -EBUSY;
 
 	if ((frq->e == 0) && (frq->m <= 1000)) {
@@ -640,7 +454,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
 		return -EBUSY;
 
 	priv->channel = chan;
-	if (priv->iw_mode == IW_MODE_MONITOR) {
+	if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
 		/* Fast channel change - no commit if successful */
 		hermes_t *hw = &priv->hw;
 		err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
@@ -657,7 +471,7 @@ static int orinoco_ioctl_getfreq(struct net_device *dev,
 				 struct iw_freq *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int tmp;
 
 	/* Locking done in there */
@@ -676,7 +490,7 @@ static int orinoco_ioctl_getsens(struct net_device *dev,
 				 struct iw_param *srq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	u16 val;
 	int err;
@@ -705,7 +519,7 @@ static int orinoco_ioctl_setsens(struct net_device *dev,
 				 struct iw_param *srq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = srq->value;
 	unsigned long flags;
 
@@ -728,7 +542,7 @@ static int orinoco_ioctl_setrts(struct net_device *dev,
 				struct iw_param *rrq,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = rrq->value;
 	unsigned long flags;
 
@@ -752,7 +566,7 @@ static int orinoco_ioctl_getrts(struct net_device *dev,
 				struct iw_param *rrq,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	rrq->value = priv->rts_thresh;
 	rrq->disabled = (rrq->value == 2347);
@@ -766,7 +580,7 @@ static int orinoco_ioctl_setfrag(struct net_device *dev,
 				 struct iw_param *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
@@ -806,7 +620,7 @@ static int orinoco_ioctl_getfrag(struct net_device *dev,
 				 struct iw_param *frq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err;
 	u16 val;
@@ -847,7 +661,7 @@ static int orinoco_ioctl_setrate(struct net_device *dev,
 				 struct iw_param *rrq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int ratemode;
 	int bitrate; /* 100s of kilobits */
 	unsigned long flags;
@@ -881,7 +695,7 @@ static int orinoco_ioctl_getrate(struct net_device *dev,
 				 struct iw_param *rrq,
 				 char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = 0;
 	int bitrate, automatic;
 	unsigned long flags;
@@ -910,7 +724,7 @@ static int orinoco_ioctl_setpower(struct net_device *dev,
 				  struct iw_param *prq,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int err = -EINPROGRESS;		/* Call commit handler */
 	unsigned long flags;
 
@@ -964,7 +778,7 @@ static int orinoco_ioctl_getpower(struct net_device *dev,
 				  struct iw_param *prq,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 enable, period, timeout, mcast;
@@ -1018,13 +832,12 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
 				       union iwreq_data *wrqu,
 				       char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 	int idx, alg = ext->alg, set_key = 1;
 	unsigned long flags;
 	int err = -EINVAL;
-	u16 key_len;
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
@@ -1056,48 +869,41 @@ static int orinoco_ioctl_set_encodeext(struct net_device *dev,
 		/* Set the requested key first */
 		switch (alg) {
 		case IW_ENCODE_ALG_NONE:
-			priv->encode_alg = alg;
-			priv->keys[idx].len = 0;
+			priv->encode_alg = ORINOCO_ALG_NONE;
+			err = orinoco_set_key(priv, idx, ORINOCO_ALG_NONE,
+					      NULL, 0, NULL, 0);
 			break;
 
 		case IW_ENCODE_ALG_WEP:
-			if (ext->key_len > SMALL_KEY_SIZE)
-				key_len = LARGE_KEY_SIZE;
-			else if (ext->key_len > 0)
-				key_len = SMALL_KEY_SIZE;
-			else
+			if (ext->key_len <= 0)
 				goto out;
 
-			priv->encode_alg = alg;
-			priv->keys[idx].len = cpu_to_le16(key_len);
-
-			key_len = min(ext->key_len, key_len);
-
-			memset(priv->keys[idx].data, 0, ORINOCO_MAX_KEY_SIZE);
-			memcpy(priv->keys[idx].data, ext->key, key_len);
+			priv->encode_alg = ORINOCO_ALG_WEP;
+			err = orinoco_set_key(priv, idx, ORINOCO_ALG_WEP,
+					      ext->key, ext->key_len, NULL, 0);
 			break;
 
 		case IW_ENCODE_ALG_TKIP:
 		{
-			hermes_t *hw = &priv->hw;
 			u8 *tkip_iv = NULL;
 
 			if (!priv->has_wpa ||
-			    (ext->key_len > sizeof(priv->tkip_key[0])))
+			    (ext->key_len > sizeof(struct orinoco_tkip_key)))
 				goto out;
 
-			priv->encode_alg = alg;
-			memset(&priv->tkip_key[idx], 0,
-			       sizeof(priv->tkip_key[idx]));
-			memcpy(&priv->tkip_key[idx], ext->key, ext->key_len);
+			priv->encode_alg = ORINOCO_ALG_TKIP;
 
 			if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
 				tkip_iv = &ext->rx_seq[0];
 
-			err = __orinoco_hw_set_tkip_key(hw, idx,
+			err = orinoco_set_key(priv, idx, ORINOCO_ALG_TKIP,
+					      ext->key, ext->key_len, tkip_iv,
+					      ORINOCO_SEQ_LEN);
+
+			err = __orinoco_hw_set_tkip_key(priv, idx,
 				 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
-				 (u8 *) &priv->tkip_key[idx],
-				 tkip_iv, NULL);
+				 priv->keys[idx].key,
+				 tkip_iv, ORINOCO_SEQ_LEN, NULL, 0);
 			if (err)
 				printk(KERN_ERR "%s: Error %d setting TKIP key"
 				       "\n", dev->name, err);
@@ -1120,7 +926,7 @@ static int orinoco_ioctl_get_encodeext(struct net_device *dev,
 				       union iwreq_data *wrqu,
 				       char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct iw_point *encoding = &wrqu->encoding;
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 	int idx, max_key_len;
@@ -1146,22 +952,22 @@ static int orinoco_ioctl_get_encodeext(struct net_device *dev,
 	encoding->flags = idx + 1;
 	memset(ext, 0, sizeof(*ext));
 
-	ext->alg = priv->encode_alg;
 	switch (priv->encode_alg) {
-	case IW_ENCODE_ALG_NONE:
+	case ORINOCO_ALG_NONE:
+		ext->alg = IW_ENCODE_ALG_NONE;
 		ext->key_len = 0;
 		encoding->flags |= IW_ENCODE_DISABLED;
 		break;
-	case IW_ENCODE_ALG_WEP:
-		ext->key_len = min_t(u16, le16_to_cpu(priv->keys[idx].len),
-				     max_key_len);
-		memcpy(ext->key, priv->keys[idx].data, ext->key_len);
+	case ORINOCO_ALG_WEP:
+		ext->alg = IW_ENCODE_ALG_WEP;
+		ext->key_len = min(priv->keys[idx].key_len, max_key_len);
+		memcpy(ext->key, priv->keys[idx].key, ext->key_len);
 		encoding->flags |= IW_ENCODE_ENABLED;
 		break;
-	case IW_ENCODE_ALG_TKIP:
-		ext->key_len = min_t(u16, sizeof(struct orinoco_tkip_key),
-				     max_key_len);
-		memcpy(ext->key, &priv->tkip_key[idx], ext->key_len);
+	case ORINOCO_ALG_TKIP:
+		ext->alg = IW_ENCODE_ALG_TKIP;
+		ext->key_len = min(priv->keys[idx].key_len, max_key_len);
+		memcpy(ext->key, priv->keys[idx].key, ext->key_len);
 		encoding->flags |= IW_ENCODE_ENABLED;
 		break;
 	}
@@ -1177,7 +983,7 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	struct iw_param *param = &wrqu->param;
 	unsigned long flags;
@@ -1255,7 +1061,7 @@ static int orinoco_ioctl_get_auth(struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct iw_param *param = &wrqu->param;
 	unsigned long flags;
 	int ret = 0;
@@ -1295,7 +1101,7 @@ static int orinoco_ioctl_set_genie(struct net_device *dev,
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	u8 *buf;
 	unsigned long flags;
 
@@ -1338,7 +1144,7 @@ static int orinoco_ioctl_get_genie(struct net_device *dev,
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 	int err = 0;
 
@@ -1367,8 +1173,7 @@ static int orinoco_ioctl_set_mlme(struct net_device *dev,
 				  struct iw_request_info *info,
 				  union iwreq_data *wrqu, char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
+	struct orinoco_private *priv = ndev_priv(dev);
 	struct iw_mlme *mlme = (struct iw_mlme *)extra;
 	unsigned long flags;
 	int ret = 0;
@@ -1382,19 +1187,11 @@ static int orinoco_ioctl_set_mlme(struct net_device *dev,
 		break;
 
 	case IW_MLME_DISASSOC:
-	{
-		struct {
-			u8 addr[ETH_ALEN];
-			__le16 reason_code;
-		} __attribute__ ((packed)) buf;
-
-		memcpy(buf.addr, mlme->addr.sa_data, ETH_ALEN);
-		buf.reason_code = cpu_to_le16(mlme->reason_code);
-		ret = HERMES_WRITE_RECORD(hw, USER_BAP,
-					  HERMES_RID_CNFDISASSOCIATE,
-					  &buf);
+
+		ret = orinoco_hw_disassociate(priv, mlme->addr.sa_data,
+					      mlme->reason_code);
 		break;
-	}
+
 	default:
 		ret = -EOPNOTSUPP;
 	}
@@ -1408,7 +1205,7 @@ static int orinoco_ioctl_getretry(struct net_device *dev,
 				  struct iw_param *rrq,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	u16 short_limit, long_limit, lifetime;
@@ -1462,7 +1259,7 @@ static int orinoco_ioctl_reset(struct net_device *dev,
 			       void *wrqu,
 			       char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -1487,14 +1284,14 @@ static int orinoco_ioctl_setibssport(struct net_device *dev,
 				     char *extra)
 
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = *((int *) extra);
 	unsigned long flags;
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
-	priv->ibss_port = val ;
+	priv->ibss_port = val;
 
 	/* Actually update the mode we are using */
 	set_port_type(priv);
@@ -1508,7 +1305,7 @@ static int orinoco_ioctl_getibssport(struct net_device *dev,
 				     void *wrqu,
 				     char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int *val = (int *) extra;
 
 	*val = priv->ibss_port;
@@ -1520,7 +1317,7 @@ static int orinoco_ioctl_setport3(struct net_device *dev,
 				  void *wrqu,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int val = *((int *) extra);
 	int err = 0;
 	unsigned long flags;
@@ -1566,7 +1363,7 @@ static int orinoco_ioctl_getport3(struct net_device *dev,
 				  void *wrqu,
 				  char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int *val = (int *) extra;
 
 	*val = priv->prefer_port3;
@@ -1578,7 +1375,7 @@ static int orinoco_ioctl_setpreamble(struct net_device *dev,
 				     void *wrqu,
 				     char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 	int val;
 
@@ -1610,7 +1407,7 @@ static int orinoco_ioctl_getpreamble(struct net_device *dev,
 				     void *wrqu,
 				     char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	int *val = (int *) extra;
 
 	if (!priv->has_preamble)
@@ -1630,7 +1427,7 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
 				struct iw_point *data,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_private *priv = ndev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int rid = data->flags;
 	u16 length;
@@ -1661,519 +1458,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
 	return err;
 }
 
-/* Trigger a scan (look for other cells in the vicinity) */
-static int orinoco_ioctl_setscan(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	hermes_t *hw = &priv->hw;
-	struct iw_scan_req *si = (struct iw_scan_req *) extra;
-	int err = 0;
-	unsigned long flags;
-
-	/* Note : you may have realised that, as this is a SET operation,
-	 * this is privileged and therefore a normal user can't
-	 * perform scanning.
-	 * This is not an error, while the device perform scanning,
-	 * traffic doesn't flow, so it's a perfect DoS...
-	 * Jean II */
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	/* Scanning with port 0 disabled would fail */
-	if (!netif_running(dev)) {
-		err = -ENETDOWN;
-		goto out;
-	}
-
-	/* In monitor mode, the scan results are always empty.
-	 * Probe responses are passed to the driver as received
-	 * frames and could be processed in software. */
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		err = -EOPNOTSUPP;
-		goto out;
-	}
-
-	/* Note : because we don't lock out the irq handler, the way
-	 * we access scan variables in priv is critical.
-	 *	o scan_inprogress : not touched by irq handler
-	 *	o scan_mode : not touched by irq handler
-	 * Before modifying anything on those variables, please think hard !
-	 * Jean II */
-
-	/* Save flags */
-	priv->scan_mode = srq->flags;
-
-	/* Always trigger scanning, even if it's in progress.
-	 * This way, if the info frame get lost, we will recover somewhat
-	 * gracefully  - Jean II */
-
-	if (priv->has_hostscan) {
-		switch (priv->firmware_type) {
-		case FIRMWARE_TYPE_SYMBOL:
-			err = hermes_write_wordrec(hw, USER_BAP,
-						HERMES_RID_CNFHOSTSCAN_SYMBOL,
-						HERMES_HOSTSCAN_SYMBOL_ONCE |
-						HERMES_HOSTSCAN_SYMBOL_BCAST);
-			break;
-		case FIRMWARE_TYPE_INTERSIL: {
-			__le16 req[3];
-
-			req[0] = cpu_to_le16(0x3fff);	/* All channels */
-			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
-			req[2] = 0;			/* Any ESSID */
-			err = HERMES_WRITE_RECORD(hw, USER_BAP,
-						  HERMES_RID_CNFHOSTSCAN, &req);
-		}
-		break;
-		case FIRMWARE_TYPE_AGERE:
-			if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
-				struct hermes_idstring idbuf;
-				size_t len = min(sizeof(idbuf.val),
-						 (size_t) si->essid_len);
-				idbuf.len = cpu_to_le16(len);
-				memcpy(idbuf.val, si->essid, len);
-
-				err = hermes_write_ltv(hw, USER_BAP,
-					       HERMES_RID_CNFSCANSSID_AGERE,
-					       HERMES_BYTES_TO_RECLEN(len + 2),
-					       &idbuf);
-			} else
-				err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFSCANSSID_AGERE,
-						   0);	/* Any ESSID */
-			if (err)
-				break;
-
-			if (priv->has_ext_scan) {
-				/* Clear scan results at the start of
-				 * an extended scan */
-				orinoco_clear_scan_results(priv,
-						msecs_to_jiffies(15000));
-
-				/* TODO: Is this available on older firmware?
-				 *   Can we use it to scan specific channels
-				 *   for IW_SCAN_THIS_FREQ? */
-				err = hermes_write_wordrec(hw, USER_BAP,
-						HERMES_RID_CNFSCANCHANNELS2GHZ,
-						0x7FFF);
-				if (err)
-					goto out;
-
-				err = hermes_inquire(hw,
-						     HERMES_INQ_CHANNELINFO);
-			} else
-				err = hermes_inquire(hw, HERMES_INQ_SCAN);
-			break;
-		}
-	} else
-		err = hermes_inquire(hw, HERMES_INQ_SCAN);
-
-	/* One more client */
-	if (!err)
-		priv->scan_inprogress = 1;
-
- out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
-
-#define MAX_CUSTOM_LEN 64
-
-/* Translate scan data returned from the card to a card independant
- * format that the Wireless Tools will understand - Jean II */
-static inline char *orinoco_translate_scan(struct net_device *dev,
-					   struct iw_request_info *info,
-					   char *current_ev,
-					   char *end_buf,
-					   union hermes_scan_info *bss,
-					   unsigned long last_scanned)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	u16			capabilities;
-	u16			channel;
-	struct iw_event		iwe;		/* Temporary buffer */
-	char custom[MAX_CUSTOM_LEN];
-
-	memset(&iwe, 0, sizeof(iwe));
-
-	/* 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, bss->a.bssid, ETH_ALEN);
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_ADDR_LEN);
-
-	/* Other entries will be displayed in the order we give them */
-
-	/* Add the ESSID */
-	iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
-	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, bss->a.essid);
-
-	/* Add mode */
-	iwe.cmd = SIOCGIWMODE;
-	capabilities = le16_to_cpu(bss->a.capabilities);
-	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-		if (capabilities & WLAN_CAPABILITY_ESS)
-			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);
-	}
-
-	channel = bss->s.channel;
-	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-		/* Add channel and frequency */
-		iwe.cmd = SIOCGIWFREQ;
-		iwe.u.freq.m = channel;
-		iwe.u.freq.e = 0;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-
-		iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
-		iwe.u.freq.e = 1;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-	}
-
-	/* Add quality statistics. level and noise in dB. No link quality */
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-	iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
-	iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
-	/* Wireless tools prior to 27.pre22 will show link quality
-	 * anyway, so we provide a reasonable value. */
-	if (iwe.u.qual.level > iwe.u.qual.noise)
-		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-	else
-		iwe.u.qual.qual = 0;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_QUAL_LEN);
-
-	/* Add encryption capability */
-	iwe.cmd = SIOCGIWENCODE;
-	if (capabilities & WLAN_CAPABILITY_PRIVACY)
-		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, NULL);
-
-	/* Bit rate is not available in Lucent/Agere firmwares */
-	if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
-		char *current_val = current_ev + iwe_stream_lcp_len(info);
-		int i;
-		int step;
-
-		if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
-			step = 2;
-		else
-			step = 1;
-
-		iwe.cmd = SIOCGIWRATE;
-		/* Those two flags are ignored... */
-		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-		/* Max 10 values */
-		for (i = 0; i < 10; i += step) {
-			/* NULL terminated */
-			if (bss->p.rates[i] == 0x0)
-				break;
-			/* Bit rate given in 500 kb/s units (+ 0x80) */
-			iwe.u.bitrate.value =
-				((bss->p.rates[i] & 0x7f) * 500000);
-			current_val = iwe_stream_add_value(info, current_ev,
-							   current_val,
-							   end_buf, &iwe,
-							   IW_EV_PARAM_LEN);
-		}
-		/* Check if we added any event */
-		if ((current_val - current_ev) > iwe_stream_lcp_len(info))
-			current_ev = current_val;
-	}
-
-	/* Beacon interval */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "bcn_int=%d",
-				     le16_to_cpu(bss->a.beacon_interv));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Capabilites */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "capab=0x%04x",
-				     capabilities);
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Add EXTRA: Age to display seconds since last beacon/probe response
-	 * for given network. */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     " Last beacon: %dms ago",
-				     jiffies_to_msecs(jiffies - last_scanned));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	return current_ev;
-}
-
-static inline char *orinoco_translate_ext_scan(struct net_device *dev,
-					       struct iw_request_info *info,
-					       char *current_ev,
-					       char *end_buf,
-					       struct agere_ext_scan_info *bss,
-					       unsigned long last_scanned)
-{
-	u16			capabilities;
-	u16			channel;
-	struct iw_event		iwe;		/* Temporary buffer */
-	char custom[MAX_CUSTOM_LEN];
-	u8 *ie;
-
-	memset(&iwe, 0, sizeof(iwe));
-
-	/* 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, bss->bssid, ETH_ALEN);
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_ADDR_LEN);
-
-	/* Other entries will be displayed in the order we give them */
-
-	/* Add the ESSID */
-	ie = bss->data;
-	iwe.u.data.length = ie[1];
-	if (iwe.u.data.length) {
-		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, &ie[2]);
-	}
-
-	/* Add mode */
-	capabilities = le16_to_cpu(bss->capabilities);
-	if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
-		iwe.cmd = SIOCGIWMODE;
-		if (capabilities & WLAN_CAPABILITY_ESS)
-			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);
-	}
-
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_DS_PARAMS);
-	channel = ie ? ie[2] : 0;
-	if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
-		/* Add channel and frequency */
-		iwe.cmd = SIOCGIWFREQ;
-		iwe.u.freq.m = channel;
-		iwe.u.freq.e = 0;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-
-		iwe.u.freq.m = ieee80211_dsss_chan_to_freq(channel) * 100000;
-		iwe.u.freq.e = 1;
-		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-						  &iwe, IW_EV_FREQ_LEN);
-	}
-
-	/* Add quality statistics. level and noise in dB. No link quality */
-	iwe.cmd = IWEVQUAL;
-	iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
-	iwe.u.qual.level = bss->level - 0x95;
-	iwe.u.qual.noise = bss->noise - 0x95;
-	/* Wireless tools prior to 27.pre22 will show link quality
-	 * anyway, so we provide a reasonable value. */
-	if (iwe.u.qual.level > iwe.u.qual.noise)
-		iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-	else
-		iwe.u.qual.qual = 0;
-	current_ev = iwe_stream_add_event(info, current_ev, end_buf,
-					  &iwe, IW_EV_QUAL_LEN);
-
-	/* Add encryption capability */
-	iwe.cmd = SIOCGIWENCODE;
-	if (capabilities & WLAN_CAPABILITY_PRIVACY)
-		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, NULL);
-
-	/* WPA IE */
-	ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
-	if (ie) {
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = ie[1] + 2;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, ie);
-	}
-
-	/* RSN IE */
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_RSN);
-	if (ie) {
-		iwe.cmd = IWEVGENIE;
-		iwe.u.data.length = ie[1] + 2;
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, ie);
-	}
-
-	ie = orinoco_get_ie(bss->data, sizeof(bss->data), WLAN_EID_SUPP_RATES);
-	if (ie) {
-		char *p = current_ev + iwe_stream_lcp_len(info);
-		int i;
-
-		iwe.cmd = SIOCGIWRATE;
-		/* Those two flags are ignored... */
-		iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
-		for (i = 2; i < (ie[1] + 2); i++) {
-			iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
-			p = iwe_stream_add_value(info, current_ev, p, end_buf,
-						 &iwe, IW_EV_PARAM_LEN);
-		}
-		/* Check if we added any event */
-		if (p > (current_ev + iwe_stream_lcp_len(info)))
-			current_ev = p;
-	}
-
-	/* Timestamp */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length =
-		snprintf(custom, MAX_CUSTOM_LEN, "tsf=%016llx",
-			 (unsigned long long) le64_to_cpu(bss->timestamp));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Beacon interval */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "bcn_int=%d",
-				     le16_to_cpu(bss->beacon_interval));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Capabilites */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     "capab=0x%04x",
-				     capabilities);
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	/* Add EXTRA: Age to display seconds since last beacon/probe response
-	 * for given network. */
-	iwe.cmd = IWEVCUSTOM;
-	iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
-				     " Last beacon: %dms ago",
-				     jiffies_to_msecs(jiffies - last_scanned));
-	if (iwe.u.data.length)
-		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
-						  &iwe, custom);
-
-	return current_ev;
-}
-
-/* Return results of a scan */
-static int orinoco_ioctl_getscan(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct iw_point *srq,
-				 char *extra)
-{
-	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
-	unsigned long flags;
-	char *current_ev = extra;
-
-	if (orinoco_lock(priv, &flags) != 0)
-		return -EBUSY;
-
-	if (priv->scan_inprogress) {
-		/* Important note : we don't want to block the caller
-		 * until results are ready for various reasons.
-		 * First, managing wait queues is complex and racy.
-		 * Second, we grab some rtnetlink lock before comming
-		 * here (in dev_ioctl()).
-		 * Third, we generate an Wireless Event, so the
-		 * caller can wait itself on that - Jean II */
-		err = -EAGAIN;
-		goto out;
-	}
-
-	if (priv->has_ext_scan) {
-		struct xbss_element *bss;
-
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			/* Translate this entry to WE format */
-			current_ev =
-				orinoco_translate_ext_scan(dev, info,
-							   current_ev,
-							   extra + srq->length,
-							   &bss->bss,
-							   bss->last_scanned);
-
-			/* Check if there is space for one more entry */
-			if ((extra + srq->length - current_ev)
-			    <= IW_EV_ADDR_LEN) {
-				/* Ask user space to try again with a
-				 * bigger buffer */
-				err = -E2BIG;
-				goto out;
-			}
-		}
-
-	} else {
-		struct bss_element *bss;
-
-		list_for_each_entry(bss, &priv->bss_list, list) {
-			/* Translate this entry to WE format */
-			current_ev = orinoco_translate_scan(dev, info,
-							    current_ev,
-							    extra + srq->length,
-							    &bss->bss,
-							    bss->last_scanned);
-
-			/* Check if there is space for one more entry */
-			if ((extra + srq->length - current_ev)
-			    <= IW_EV_ADDR_LEN) {
-				/* Ask user space to try again with a
-				 * bigger buffer */
-				err = -E2BIG;
-				goto out;
-			}
-		}
-	}
-
-	srq->length = (current_ev - extra);
-	srq->flags = (__u16) priv->scan_mode;
-
-out:
-	orinoco_unlock(priv, &flags);
-	return err;
-}
 
 /* Commit handler, called after set operations */
 static int orinoco_ioctl_commit(struct net_device *dev,
@@ -2181,50 +1465,17 @@ static int orinoco_ioctl_commit(struct net_device *dev,
 				void *wrqu,
 				char *extra)
 {
-	struct orinoco_private *priv = netdev_priv(dev);
-	struct hermes *hw = &priv->hw;
+	struct orinoco_private *priv = ndev_priv(dev);
 	unsigned long flags;
 	int err = 0;
 
 	if (!priv->open)
 		return 0;
 
-	if (priv->broken_disableport) {
-		orinoco_reset(&priv->reset_work);
-		return 0;
-	}
-
 	if (orinoco_lock(priv, &flags) != 0)
 		return err;
 
-	err = hermes_disable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to disable port "
-		       "while reconfiguring card\n", dev->name);
-		priv->broken_disableport = 1;
-		goto out;
-	}
-
-	err = __orinoco_program_rids(dev);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to reconfigure card\n",
-		       dev->name);
-		goto out;
-	}
-
-	err = hermes_enable_port(hw, 0);
-	if (err) {
-		printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
-		       dev->name);
-		goto out;
-	}
-
- out:
-	if (err) {
-		printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
-		schedule_work(&priv->reset_work);
-		err = 0;
-	}
+	err = orinoco_commit(priv);
 
 	orinoco_unlock(priv, &flags);
 	return err;
@@ -2258,26 +1509,24 @@ static const struct iw_priv_args orinoco_privtab[] = {
 	[IW_IOCTL_IDX(id)] = (iw_handler) func
 static const iw_handler	orinoco_handler[] = {
 	STD_IW_HANDLER(SIOCSIWCOMMIT,	orinoco_ioctl_commit),
-	STD_IW_HANDLER(SIOCGIWNAME,	orinoco_ioctl_getname),
+	STD_IW_HANDLER(SIOCGIWNAME,	cfg80211_wext_giwname),
 	STD_IW_HANDLER(SIOCSIWFREQ,	orinoco_ioctl_setfreq),
 	STD_IW_HANDLER(SIOCGIWFREQ,	orinoco_ioctl_getfreq),
-	STD_IW_HANDLER(SIOCSIWMODE,	orinoco_ioctl_setmode),
-	STD_IW_HANDLER(SIOCGIWMODE,	orinoco_ioctl_getmode),
+	STD_IW_HANDLER(SIOCSIWMODE,	cfg80211_wext_siwmode),
+	STD_IW_HANDLER(SIOCGIWMODE,	cfg80211_wext_giwmode),
 	STD_IW_HANDLER(SIOCSIWSENS,	orinoco_ioctl_setsens),
 	STD_IW_HANDLER(SIOCGIWSENS,	orinoco_ioctl_getsens),
-	STD_IW_HANDLER(SIOCGIWRANGE,	orinoco_ioctl_getiwrange),
+	STD_IW_HANDLER(SIOCGIWRANGE,	cfg80211_wext_giwrange),
 	STD_IW_HANDLER(SIOCSIWSPY,	iw_handler_set_spy),
 	STD_IW_HANDLER(SIOCGIWSPY,	iw_handler_get_spy),
 	STD_IW_HANDLER(SIOCSIWTHRSPY,	iw_handler_set_thrspy),
 	STD_IW_HANDLER(SIOCGIWTHRSPY,	iw_handler_get_thrspy),
 	STD_IW_HANDLER(SIOCSIWAP,	orinoco_ioctl_setwap),
 	STD_IW_HANDLER(SIOCGIWAP,	orinoco_ioctl_getwap),
-	STD_IW_HANDLER(SIOCSIWSCAN,	orinoco_ioctl_setscan),
-	STD_IW_HANDLER(SIOCGIWSCAN,	orinoco_ioctl_getscan),
+	STD_IW_HANDLER(SIOCSIWSCAN,	cfg80211_wext_siwscan),
+	STD_IW_HANDLER(SIOCGIWSCAN,	cfg80211_wext_giwscan),
 	STD_IW_HANDLER(SIOCSIWESSID,	orinoco_ioctl_setessid),
 	STD_IW_HANDLER(SIOCGIWESSID,	orinoco_ioctl_getessid),
-	STD_IW_HANDLER(SIOCSIWNICKN,	orinoco_ioctl_setnick),
-	STD_IW_HANDLER(SIOCGIWNICKN,	orinoco_ioctl_getnick),
 	STD_IW_HANDLER(SIOCSIWRATE,	orinoco_ioctl_setrate),
 	STD_IW_HANDLER(SIOCGIWRATE,	orinoco_ioctl_getrate),
 	STD_IW_HANDLER(SIOCSIWRTS,	orinoco_ioctl_setrts),
diff --git a/drivers/net/wireless/p54/Makefile b/drivers/net/wireless/p54/Makefile
index c2050de..b542e68 100644
--- a/drivers/net/wireless/p54/Makefile
+++ b/drivers/net/wireless/p54/Makefile
@@ -1,3 +1,6 @@
+p54common-objs			:= eeprom.o fwio.o txrx.o main.o
+p54common-$(CONFIG_P54_LEDS)	+= led.o
+
 obj-$(CONFIG_P54_COMMON)	+= p54common.o
 obj-$(CONFIG_P54_USB)		+= p54usb.o
 obj-$(CONFIG_P54_PCI)		+= p54pci.o
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
new file mode 100644
index 0000000..0efe67d
--- /dev/null
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -0,0 +1,753 @@
+/*
+ * EEPROM parser code for mac80211 Prism54 drivers
+ *
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * - stlc45xx driver
+ *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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/firmware.h>
+#include <linux/etherdevice.h>
+#include <linux/sort.h>
+
+#include <net/mac80211.h>
+
+#include "p54.h"
+#include "eeprom.h"
+#include "lmac.h"
+
+static struct ieee80211_rate p54_bgrates[] = {
+	{ .bitrate = 10, .hw_value = 0, },
+	{ .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 60, .hw_value = 4, },
+	{ .bitrate = 90, .hw_value = 5, },
+	{ .bitrate = 120, .hw_value = 6, },
+	{ .bitrate = 180, .hw_value = 7, },
+	{ .bitrate = 240, .hw_value = 8, },
+	{ .bitrate = 360, .hw_value = 9, },
+	{ .bitrate = 480, .hw_value = 10, },
+	{ .bitrate = 540, .hw_value = 11, },
+};
+
+static struct ieee80211_rate p54_arates[] = {
+	{ .bitrate = 60, .hw_value = 4, },
+	{ .bitrate = 90, .hw_value = 5, },
+	{ .bitrate = 120, .hw_value = 6, },
+	{ .bitrate = 180, .hw_value = 7, },
+	{ .bitrate = 240, .hw_value = 8, },
+	{ .bitrate = 360, .hw_value = 9, },
+	{ .bitrate = 480, .hw_value = 10, },
+	{ .bitrate = 540, .hw_value = 11, },
+};
+
+#define CHAN_HAS_CAL		BIT(0)
+#define CHAN_HAS_LIMIT		BIT(1)
+#define CHAN_HAS_CURVE		BIT(2)
+#define CHAN_HAS_ALL		(CHAN_HAS_CAL | CHAN_HAS_LIMIT | CHAN_HAS_CURVE)
+
+struct p54_channel_entry {
+	u16 freq;
+	u16 data;
+	int index;
+	enum ieee80211_band band;
+};
+
+struct p54_channel_list {
+	struct p54_channel_entry *channels;
+	size_t entries;
+	size_t max_entries;
+	size_t band_channel_num[IEEE80211_NUM_BANDS];
+};
+
+static int p54_get_band_from_freq(u16 freq)
+{
+	/* FIXME: sync these values with the 802.11 spec */
+
+	if ((freq >= 2412) && (freq <= 2484))
+		return IEEE80211_BAND_2GHZ;
+
+	if ((freq >= 4920) && (freq <= 5825))
+		return IEEE80211_BAND_5GHZ;
+
+	return -1;
+}
+
+static int p54_compare_channels(const void *_a,
+				const void *_b)
+{
+	const struct p54_channel_entry *a = _a;
+	const struct p54_channel_entry *b = _b;
+
+	return a->index - b->index;
+}
+
+static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
+				  struct ieee80211_supported_band *band_entry,
+				  enum ieee80211_band band)
+{
+	/* TODO: generate rate array dynamically */
+
+	switch (band) {
+	case IEEE80211_BAND_2GHZ:
+		band_entry->bitrates = p54_bgrates;
+		band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates);
+		break;
+	case IEEE80211_BAND_5GHZ:
+		band_entry->bitrates = p54_arates;
+		band_entry->n_bitrates = ARRAY_SIZE(p54_arates);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int p54_generate_band(struct ieee80211_hw *dev,
+			     struct p54_channel_list *list,
+			     enum ieee80211_band band)
+{
+	struct p54_common *priv = dev->priv;
+	struct ieee80211_supported_band *tmp, *old;
+	unsigned int i, j;
+	int ret = -ENOMEM;
+
+	if ((!list->entries) || (!list->band_channel_num[band]))
+		return 0;
+
+	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
+	if (!tmp)
+		goto err_out;
+
+	tmp->channels = kzalloc(sizeof(struct ieee80211_channel) *
+				list->band_channel_num[band], GFP_KERNEL);
+	if (!tmp->channels)
+		goto err_out;
+
+	ret = p54_fill_band_bitrates(dev, tmp, band);
+	if (ret)
+		goto err_out;
+
+	for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
+			   (i < list->entries); i++) {
+
+		if (list->channels[i].band != band)
+			continue;
+
+		if (list->channels[i].data != CHAN_HAS_ALL) {
+			printk(KERN_ERR "%s:%s%s%s is/are missing for "
+					"channel:%d [%d MHz].\n",
+			       wiphy_name(dev->wiphy),
+			       (list->channels[i].data & CHAN_HAS_CAL ? "" :
+				" [iqauto calibration data]"),
+			       (list->channels[i].data & CHAN_HAS_LIMIT ? "" :
+				" [output power limits]"),
+			       (list->channels[i].data & CHAN_HAS_CURVE ? "" :
+				" [curve data]"),
+			       list->channels[i].index, list->channels[i].freq);
+		}
+
+		tmp->channels[j].band = list->channels[i].band;
+		tmp->channels[j].center_freq = list->channels[i].freq;
+		j++;
+	}
+
+	tmp->n_channels = list->band_channel_num[band];
+	old = priv->band_table[band];
+	priv->band_table[band] = tmp;
+	if (old) {
+		kfree(old->channels);
+		kfree(old);
+	}
+
+	return 0;
+
+err_out:
+	if (tmp) {
+		kfree(tmp->channels);
+		kfree(tmp);
+	}
+
+	return ret;
+}
+
+static void p54_update_channel_param(struct p54_channel_list *list,
+				     u16 freq, u16 data)
+{
+	int band, i;
+
+	/*
+	 * usually all lists in the eeprom are mostly sorted.
+	 * so it's very likely that the entry we are looking for
+	 * is right at the end of the list
+	 */
+	for (i = list->entries; i >= 0; i--) {
+		if (freq == list->channels[i].freq) {
+			list->channels[i].data |= data;
+			break;
+		}
+	}
+
+	if ((i < 0) && (list->entries < list->max_entries)) {
+		/* entry does not exist yet. Initialize a new one. */
+		band = p54_get_band_from_freq(freq);
+
+		/*
+		 * filter out frequencies which don't belong into
+		 * any supported band.
+		 */
+		if (band < 0)
+			return ;
+
+		i = list->entries++;
+		list->band_channel_num[band]++;
+
+		list->channels[i].freq = freq;
+		list->channels[i].data = data;
+		list->channels[i].band = band;
+		list->channels[i].index = ieee80211_frequency_to_channel(freq);
+		/* TODO: parse output_limit and fill max_power */
+	}
+}
+
+static int p54_generate_channel_lists(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+	struct p54_channel_list *list;
+	unsigned int i, j, max_channel_num;
+	int ret = -ENOMEM;
+	u16 freq;
+
+	if ((priv->iq_autocal_len != priv->curve_data->entries) ||
+	    (priv->iq_autocal_len != priv->output_limit->entries))
+		printk(KERN_ERR "%s: EEPROM is damaged... you may not be able"
+				"to use all channels with this device.\n",
+				wiphy_name(dev->wiphy));
+
+	max_channel_num = max_t(unsigned int, priv->output_limit->entries,
+				priv->iq_autocal_len);
+	max_channel_num = max_t(unsigned int, max_channel_num,
+				priv->curve_data->entries);
+
+	list = kzalloc(sizeof(*list), GFP_KERNEL);
+	if (!list)
+		goto free;
+
+	list->max_entries = max_channel_num;
+	list->channels = kzalloc(sizeof(struct p54_channel_entry) *
+				 max_channel_num, GFP_KERNEL);
+	if (!list->channels)
+		goto free;
+
+	for (i = 0; i < max_channel_num; i++) {
+		if (i < priv->iq_autocal_len) {
+			freq = le16_to_cpu(priv->iq_autocal[i].freq);
+			p54_update_channel_param(list, freq, CHAN_HAS_CAL);
+		}
+
+		if (i < priv->output_limit->entries) {
+			freq = le16_to_cpup((__le16 *) (i *
+					    priv->output_limit->entry_size +
+					    priv->output_limit->offset +
+					    priv->output_limit->data));
+
+			p54_update_channel_param(list, freq, CHAN_HAS_LIMIT);
+		}
+
+		if (i < priv->curve_data->entries) {
+			freq = le16_to_cpup((__le16 *) (i *
+					    priv->curve_data->entry_size +
+					    priv->curve_data->offset +
+					    priv->curve_data->data));
+
+			p54_update_channel_param(list, freq, CHAN_HAS_CURVE);
+		}
+	}
+
+	/* sort the list by the channel index */
+	sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
+	     p54_compare_channels, NULL);
+
+	for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
+		if (list->band_channel_num[i]) {
+			ret = p54_generate_band(dev, list, i);
+			if (ret)
+				goto free;
+
+			j++;
+		}
+	}
+	if (j == 0) {
+		/* no useable band available. */
+		ret = -EINVAL;
+	}
+
+free:
+	if (list) {
+		kfree(list->channels);
+		kfree(list);
+	}
+
+	return ret;
+}
+
+static int p54_convert_rev0(struct ieee80211_hw *dev,
+			    struct pda_pa_curve_data *curve_data)
+{
+	struct p54_common *priv = dev->priv;
+	struct p54_pa_curve_data_sample *dst;
+	struct pda_pa_curve_data_sample_rev0 *src;
+	size_t cd_len = sizeof(*curve_data) +
+		(curve_data->points_per_channel*sizeof(*dst) + 2) *
+		 curve_data->channels;
+	unsigned int i, j;
+	void *source, *target;
+
+	priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
+				   GFP_KERNEL);
+	if (!priv->curve_data)
+		return -ENOMEM;
+
+	priv->curve_data->entries = curve_data->channels;
+	priv->curve_data->entry_size = sizeof(__le16) +
+		sizeof(*dst) * curve_data->points_per_channel;
+	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+	priv->curve_data->len = cd_len;
+	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
+	source = curve_data->data;
+	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
+	for (i = 0; i < curve_data->channels; i++) {
+		__le16 *freq = source;
+		source += sizeof(__le16);
+		*((__le16 *)target) = *freq;
+		target += sizeof(__le16);
+		for (j = 0; j < curve_data->points_per_channel; j++) {
+			dst = target;
+			src = source;
+
+			dst->rf_power = src->rf_power;
+			dst->pa_detector = src->pa_detector;
+			dst->data_64qam = src->pcv;
+			/* "invent" the points for the other modulations */
+#define SUB(x, y) (u8)(((x) - (y)) > (x) ? 0 : (x) - (y))
+			dst->data_16qam = SUB(src->pcv, 12);
+			dst->data_qpsk = SUB(dst->data_16qam, 12);
+			dst->data_bpsk = SUB(dst->data_qpsk, 12);
+			dst->data_barker = SUB(dst->data_bpsk, 14);
+#undef SUB
+			target += sizeof(*dst);
+			source += sizeof(*src);
+		}
+	}
+
+	return 0;
+}
+
+static int p54_convert_rev1(struct ieee80211_hw *dev,
+			    struct pda_pa_curve_data *curve_data)
+{
+	struct p54_common *priv = dev->priv;
+	struct p54_pa_curve_data_sample *dst;
+	struct pda_pa_curve_data_sample_rev1 *src;
+	size_t cd_len = sizeof(*curve_data) +
+		(curve_data->points_per_channel*sizeof(*dst) + 2) *
+		 curve_data->channels;
+	unsigned int i, j;
+	void *source, *target;
+
+	priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
+				   GFP_KERNEL);
+	if (!priv->curve_data)
+		return -ENOMEM;
+
+	priv->curve_data->entries = curve_data->channels;
+	priv->curve_data->entry_size = sizeof(__le16) +
+		sizeof(*dst) * curve_data->points_per_channel;
+	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
+	priv->curve_data->len = cd_len;
+	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
+	source = curve_data->data;
+	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
+	for (i = 0; i < curve_data->channels; i++) {
+		__le16 *freq = source;
+		source += sizeof(__le16);
+		*((__le16 *)target) = *freq;
+		target += sizeof(__le16);
+		for (j = 0; j < curve_data->points_per_channel; j++) {
+			memcpy(target, source, sizeof(*src));
+
+			target += sizeof(*dst);
+			source += sizeof(*src);
+		}
+		source++;
+	}
+
+	return 0;
+}
+
+static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
+	"Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
+
+static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
+			     u16 type)
+{
+	struct p54_common *priv = dev->priv;
+	int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0;
+	int entry_size = sizeof(struct pda_rssi_cal_entry) + offset;
+	int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
+	int i;
+
+	if (len != (entry_size * num_entries)) {
+		printk(KERN_ERR "%s: unknown rssi calibration data packing "
+				 " type:(%x) len:%d.\n",
+		       wiphy_name(dev->wiphy), type, len);
+
+		print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
+				     data, len);
+
+		printk(KERN_ERR "%s: please report this issue.\n",
+			wiphy_name(dev->wiphy));
+		return;
+	}
+
+	for (i = 0; i < num_entries; i++) {
+		struct pda_rssi_cal_entry *cal = data +
+						 (offset + i * entry_size);
+		priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul);
+		priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add);
+	}
+}
+
+static void p54_parse_default_country(struct ieee80211_hw *dev,
+				      void *data, int len)
+{
+	struct pda_country *country;
+
+	if (len != sizeof(*country)) {
+		printk(KERN_ERR "%s: found possible invalid default country "
+				"eeprom entry. (entry size: %d)\n",
+		       wiphy_name(dev->wiphy), len);
+
+		print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
+				     data, len);
+
+		printk(KERN_ERR "%s: please report this issue.\n",
+			wiphy_name(dev->wiphy));
+		return;
+	}
+
+	country = (struct pda_country *) data;
+	if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
+		regulatory_hint(dev->wiphy, country->alpha2);
+	else {
+		/* TODO:
+		 * write a shared/common function that converts
+		 * "Regulatory domain codes" (802.11-2007 14.8.2.2)
+		 * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
+		 */
+	}
+}
+
+static int p54_convert_output_limits(struct ieee80211_hw *dev,
+				     u8 *data, size_t len)
+{
+	struct p54_common *priv = dev->priv;
+
+	if (len < 2)
+		return -EINVAL;
+
+	if (data[0] != 0) {
+		printk(KERN_ERR "%s: unknown output power db revision:%x\n",
+		       wiphy_name(dev->wiphy), data[0]);
+		return -EINVAL;
+	}
+
+	if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
+		return -EINVAL;
+
+	priv->output_limit = kmalloc(data[1] *
+		sizeof(struct pda_channel_output_limit) +
+		sizeof(*priv->output_limit), GFP_KERNEL);
+
+	if (!priv->output_limit)
+		return -ENOMEM;
+
+	priv->output_limit->offset = 0;
+	priv->output_limit->entries = data[1];
+	priv->output_limit->entry_size =
+		sizeof(struct pda_channel_output_limit);
+	priv->output_limit->len = priv->output_limit->entry_size *
+				  priv->output_limit->entries +
+				  priv->output_limit->offset;
+
+	memcpy(priv->output_limit->data, &data[2],
+	       data[1] * sizeof(struct pda_channel_output_limit));
+
+	return 0;
+}
+
+static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
+					       size_t total_len)
+{
+	struct p54_cal_database *dst;
+	size_t payload_len, entries, entry_size, offset;
+
+	payload_len = le16_to_cpu(src->len);
+	entries = le16_to_cpu(src->entries);
+	entry_size = le16_to_cpu(src->entry_size);
+	offset = le16_to_cpu(src->offset);
+	if (((entries * entry_size + offset) != payload_len) ||
+	     (payload_len + sizeof(*src) != total_len))
+		return NULL;
+
+	dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
+	if (!dst)
+		return NULL;
+
+	dst->entries = entries;
+	dst->entry_size = entry_size;
+	dst->offset = offset;
+	dst->len = payload_len;
+
+	memcpy(dst->data, src->data, payload_len);
+	return dst;
+}
+
+int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
+{
+	struct p54_common *priv = dev->priv;
+	struct eeprom_pda_wrap *wrap;
+	struct pda_entry *entry;
+	unsigned int data_len, entry_len;
+	void *tmp;
+	int err;
+	u8 *end = (u8 *)eeprom + len;
+	u16 synth = 0;
+
+	wrap = (struct eeprom_pda_wrap *) eeprom;
+	entry = (void *)wrap->data + le16_to_cpu(wrap->len);
+
+	/* verify that at least the entry length/code fits */
+	while ((u8 *)entry <= end - sizeof(*entry)) {
+		entry_len = le16_to_cpu(entry->len);
+		data_len = ((entry_len - 1) << 1);
+
+		/* abort if entry exceeds whole structure */
+		if ((u8 *)entry + sizeof(*entry) + data_len > end)
+			break;
+
+		switch (le16_to_cpu(entry->code)) {
+		case PDR_MAC_ADDRESS:
+			if (data_len != ETH_ALEN)
+				break;
+			SET_IEEE80211_PERM_ADDR(dev, entry->data);
+			break;
+		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
+			if (priv->output_limit)
+				break;
+			err = p54_convert_output_limits(dev, entry->data,
+							data_len);
+			if (err)
+				goto err;
+			break;
+		case PDR_PRISM_PA_CAL_CURVE_DATA: {
+			struct pda_pa_curve_data *curve_data =
+				(struct pda_pa_curve_data *)entry->data;
+			if (data_len < sizeof(*curve_data)) {
+				err = -EINVAL;
+				goto err;
+			}
+
+			switch (curve_data->cal_method_rev) {
+			case 0:
+				err = p54_convert_rev0(dev, curve_data);
+				break;
+			case 1:
+				err = p54_convert_rev1(dev, curve_data);
+				break;
+			default:
+				printk(KERN_ERR "%s: unknown curve data "
+						"revision %d\n",
+						wiphy_name(dev->wiphy),
+						curve_data->cal_method_rev);
+				err = -ENODEV;
+				break;
+			}
+			if (err)
+				goto err;
+			}
+			break;
+		case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
+			priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
+			if (!priv->iq_autocal) {
+				err = -ENOMEM;
+				goto err;
+			}
+
+			memcpy(priv->iq_autocal, entry->data, data_len);
+			priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
+			break;
+		case PDR_DEFAULT_COUNTRY:
+			p54_parse_default_country(dev, entry->data, data_len);
+			break;
+		case PDR_INTERFACE_LIST:
+			tmp = entry->data;
+			while ((u8 *)tmp < entry->data + data_len) {
+				struct exp_if *exp_if = tmp;
+				if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
+					synth = le16_to_cpu(exp_if->variant);
+				tmp += sizeof(*exp_if);
+			}
+			break;
+		case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
+			if (data_len < 2)
+				break;
+			priv->version = *(u8 *)(entry->data + 1);
+			break;
+		case PDR_RSSI_LINEAR_APPROXIMATION:
+		case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
+		case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
+			p54_parse_rssical(dev, entry->data, data_len,
+					  le16_to_cpu(entry->code));
+			break;
+		case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
+			__le16 *src = (void *) entry->data;
+			s16 *dst = (void *) &priv->rssical_db;
+			int i;
+
+			if (data_len != sizeof(priv->rssical_db)) {
+				err = -EINVAL;
+				goto err;
+			}
+			for (i = 0; i < sizeof(priv->rssical_db) /
+					sizeof(*src); i++)
+				*(dst++) = (s16) le16_to_cpu(*(src++));
+			}
+			break;
+		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
+			struct pda_custom_wrapper *pda = (void *) entry->data;
+			if (priv->output_limit || data_len < sizeof(*pda))
+				break;
+			priv->output_limit = p54_convert_db(pda, data_len);
+			}
+			break;
+		case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
+			struct pda_custom_wrapper *pda = (void *) entry->data;
+			if (priv->curve_data || data_len < sizeof(*pda))
+				break;
+			priv->curve_data = p54_convert_db(pda, data_len);
+			}
+			break;
+		case PDR_END:
+			/* make it overrun */
+			entry_len = len;
+			break;
+		default:
+			break;
+		}
+
+		entry = (void *)entry + (entry_len + 1)*2;
+	}
+
+	if (!synth || !priv->iq_autocal || !priv->output_limit ||
+	    !priv->curve_data) {
+		printk(KERN_ERR "%s: not all required entries found in eeprom!\n",
+			wiphy_name(dev->wiphy));
+		err = -EINVAL;
+		goto err;
+	}
+
+	err = p54_generate_channel_lists(dev);
+	if (err)
+		goto err;
+
+	priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
+		p54_init_xbow_synth(priv);
+	if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
+		dev->wiphy->bands[IEEE80211_BAND_2GHZ] =
+			priv->band_table[IEEE80211_BAND_2GHZ];
+	if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
+		dev->wiphy->bands[IEEE80211_BAND_5GHZ] =
+			priv->band_table[IEEE80211_BAND_5GHZ];
+	if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
+		priv->rx_diversity_mask = 3;
+	if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
+		priv->tx_diversity_mask = 3;
+
+	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
+		u8 perm_addr[ETH_ALEN];
+
+		printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n",
+			wiphy_name(dev->wiphy));
+		random_ether_addr(perm_addr);
+		SET_IEEE80211_PERM_ADDR(dev, perm_addr);
+	}
+
+	printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n",
+		wiphy_name(dev->wiphy),	dev->wiphy->perm_addr, priv->version,
+		p54_rf_chips[priv->rxhw]);
+
+	return 0;
+
+err:
+	kfree(priv->iq_autocal);
+	kfree(priv->output_limit);
+	kfree(priv->curve_data);
+	priv->iq_autocal = NULL;
+	priv->output_limit = NULL;
+	priv->curve_data = NULL;
+
+	printk(KERN_ERR "%s: eeprom parse failed!\n",
+		wiphy_name(dev->wiphy));
+	return err;
+}
+EXPORT_SYMBOL_GPL(p54_parse_eeprom);
+
+int p54_read_eeprom(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+	size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
+	int ret = -ENOMEM;
+	void *eeprom;
+
+	maxblocksize = EEPROM_READBACK_LEN;
+	if (priv->fw_var >= 0x509)
+		maxblocksize -= 0xc;
+	else
+		maxblocksize -= 0x4;
+
+	eeprom = kzalloc(eeprom_size, GFP_KERNEL);
+	if (unlikely(!eeprom))
+		goto free;
+
+	while (eeprom_size) {
+		blocksize = min(eeprom_size, maxblocksize);
+		ret = p54_download_eeprom(priv, (void *) (eeprom + offset),
+					  offset, blocksize);
+		if (unlikely(ret))
+			goto free;
+
+		offset += blocksize;
+		eeprom_size -= blocksize;
+	}
+
+	ret = p54_parse_eeprom(dev, eeprom, offset);
+free:
+	kfree(eeprom);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(p54_read_eeprom);
diff --git a/drivers/net/wireless/p54/eeprom.h b/drivers/net/wireless/p54/eeprom.h
new file mode 100644
index 0000000..9051aef
--- /dev/null
+++ b/drivers/net/wireless/p54/eeprom.h
@@ -0,0 +1,226 @@
+/*
+ * eeprom specific definitions for mac80211 Prism54 drivers
+ *
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ *
+ * - LMAC API interface header file for STLC4560 (lmac_longbow.h)
+ *   Copyright (C) 2007 Conexant Systems, Inc.
+ *
+ * - islmvc driver
+ *   Copyright (C) 2001 Intersil Americas Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef EEPROM_H
+#define EEPROM_H
+
+/* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */
+
+struct pda_entry {
+	__le16 len;	/* includes both code and data */
+	__le16 code;
+	u8 data[0];
+} __packed;
+
+struct eeprom_pda_wrap {
+	__le32 magic;
+	__le16 pad;
+	__le16 len;
+	__le32 arm_opcode;
+	u8 data[0];
+} __packed;
+
+struct p54_iq_autocal_entry {
+	__le16 iq_param[4];
+} __packed;
+
+struct pda_iq_autocal_entry {
+	__le16 freq;
+	struct p54_iq_autocal_entry params;
+} __packed;
+
+struct pda_channel_output_limit {
+	__le16 freq;
+	u8 val_bpsk;
+	u8 val_qpsk;
+	u8 val_16qam;
+	u8 val_64qam;
+	u8 rate_set_mask;
+	u8 rate_set_size;
+} __packed;
+
+struct pda_pa_curve_data_sample_rev0 {
+	u8 rf_power;
+	u8 pa_detector;
+	u8 pcv;
+} __packed;
+
+struct pda_pa_curve_data_sample_rev1 {
+	u8 rf_power;
+	u8 pa_detector;
+	u8 data_barker;
+	u8 data_bpsk;
+	u8 data_qpsk;
+	u8 data_16qam;
+	u8 data_64qam;
+} __packed;
+
+struct pda_pa_curve_data {
+	u8 cal_method_rev;
+	u8 channels;
+	u8 points_per_channel;
+	u8 padding;
+	u8 data[0];
+} __packed;
+
+struct pda_rssi_cal_entry {
+	__le16 mul;
+	__le16 add;
+} __packed;
+
+struct pda_country {
+	u8 regdomain;
+	u8 alpha2[2];
+	u8 flags;
+} __packed;
+
+struct pda_antenna_gain {
+	struct {
+		u8 gain_5GHz;	/* 0.25 dBi units */
+		u8 gain_2GHz;	/* 0.25 dBi units */
+	} __packed antenna[0];
+} __packed;
+
+struct pda_custom_wrapper {
+	__le16 entries;
+	__le16 entry_size;
+	__le16 offset;
+	__le16 len;
+	u8 data[0];
+} __packed;
+
+/*
+ * this defines the PDR codes used to build PDAs as defined in document
+ * number 553155. The current implementation mirrors version 1.1 of the
+ * document and lists only PDRs supported by the ARM platform.
+ */
+
+/* common and choice range (0x0000 - 0x0fff) */
+#define PDR_END					0x0000
+#define PDR_MANUFACTURING_PART_NUMBER		0x0001
+#define PDR_PDA_VERSION				0x0002
+#define PDR_NIC_SERIAL_NUMBER			0x0003
+#define PDR_NIC_RAM_SIZE			0x0005
+#define PDR_RFMODEM_SUP_RANGE			0x0006
+#define PDR_PRISM_MAC_SUP_RANGE			0x0007
+#define PDR_NIC_ID				0x0008
+
+#define PDR_MAC_ADDRESS				0x0101
+#define PDR_REGULATORY_DOMAIN_LIST		0x0103 /* obsolete */
+#define PDR_ALLOWED_CHAN_SET			0x0104
+#define PDR_DEFAULT_CHAN			0x0105
+#define PDR_TEMPERATURE_TYPE			0x0107
+
+#define PDR_IFR_SETTING				0x0200
+#define PDR_RFR_SETTING				0x0201
+#define PDR_3861_BASELINE_REG_SETTINGS		0x0202
+#define PDR_3861_SHADOW_REG_SETTINGS		0x0203
+#define PDR_3861_IFRF_REG_SETTINGS		0x0204
+
+#define PDR_3861_CHAN_CALIB_SET_POINTS		0x0300
+#define PDR_3861_CHAN_CALIB_INTEGRATOR		0x0301
+
+#define PDR_3842_PRISM_II_NIC_CONFIG		0x0400
+#define PDR_PRISM_USB_ID			0x0401
+#define PDR_PRISM_PCI_ID			0x0402
+#define PDR_PRISM_PCI_IF_CONFIG			0x0403
+#define PDR_PRISM_PCI_PM_CONFIG			0x0404
+
+#define PDR_3861_MF_TEST_CHAN_SET_POINTS	0x0900
+#define PDR_3861_MF_TEST_CHAN_INTEGRATORS	0x0901
+
+/* ARM range (0x1000 - 0x1fff) */
+#define PDR_COUNTRY_INFORMATION			0x1000 /* obsolete */
+#define PDR_INTERFACE_LIST			0x1001
+#define PDR_HARDWARE_PLATFORM_COMPONENT_ID	0x1002
+#define PDR_OEM_NAME				0x1003
+#define PDR_PRODUCT_NAME			0x1004
+#define PDR_UTF8_OEM_NAME			0x1005
+#define PDR_UTF8_PRODUCT_NAME			0x1006
+#define PDR_COUNTRY_LIST			0x1007
+#define PDR_DEFAULT_COUNTRY			0x1008
+
+#define PDR_ANTENNA_GAIN			0x1100
+
+#define PDR_PRISM_INDIGO_PA_CALIBRATION_DATA	0x1901
+#define PDR_RSSI_LINEAR_APPROXIMATION		0x1902
+#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS	0x1903
+#define PDR_PRISM_PA_CAL_CURVE_DATA		0x1904
+#define PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND	0x1905
+#define PDR_PRISM_ZIF_TX_IQ_CALIBRATION		0x1906
+#define PDR_REGULATORY_POWER_LIMITS		0x1907
+#define PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED	0x1908
+#define PDR_RADIATED_TRANSMISSION_CORRECTION	0x1909
+#define PDR_PRISM_TX_IQ_CALIBRATION		0x190a
+
+/* reserved range (0x2000 - 0x7fff) */
+
+/* customer range (0x8000 - 0xffff) */
+#define PDR_BASEBAND_REGISTERS				0x8000
+#define PDR_PER_CHANNEL_BASEBAND_REGISTERS		0x8001
+
+/* used by our modificated eeprom image */
+#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM		0xDEAD
+#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM	0xBEEF
+#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM		0xB05D
+
+/* Interface Definitions */
+#define PDR_INTERFACE_ROLE_SERVER	0x0000
+#define PDR_INTERFACE_ROLE_CLIENT	0x0001
+
+/* PDR definitions for default country & country list */
+#define PDR_COUNTRY_CERT_CODE		0x80
+#define PDR_COUNTRY_CERT_CODE_REAL	0x00
+#define PDR_COUNTRY_CERT_CODE_PSEUDO	0x80
+#define PDR_COUNTRY_CERT_BAND		0x40
+#define PDR_COUNTRY_CERT_BAND_2GHZ	0x00
+#define PDR_COUNTRY_CERT_BAND_5GHZ	0x40
+#define PDR_COUNTRY_CERT_IODOOR		0x30
+#define PDR_COUNTRY_CERT_IODOOR_BOTH	0x00
+#define PDR_COUNTRY_CERT_IODOOR_INDOOR	0x20
+#define PDR_COUNTRY_CERT_IODOOR_OUTDOOR	0x30
+#define PDR_COUNTRY_CERT_INDEX		0x0f
+
+/* Specific LMAC FW/HW variant definitions */
+#define PDR_SYNTH_FRONTEND_MASK		0x0007
+#define PDR_SYNTH_FRONTEND_DUETTE3	0x0001
+#define PDR_SYNTH_FRONTEND_DUETTE2	0x0002
+#define PDR_SYNTH_FRONTEND_FRISBEE	0x0003
+#define PDR_SYNTH_FRONTEND_XBOW		0x0004
+#define PDR_SYNTH_FRONTEND_LONGBOW	0x0005
+#define PDR_SYNTH_IQ_CAL_MASK		0x0018
+#define PDR_SYNTH_IQ_CAL_PA_DETECTOR	0x0000
+#define PDR_SYNTH_IQ_CAL_DISABLED	0x0008
+#define PDR_SYNTH_IQ_CAL_ZIF		0x0010
+#define PDR_SYNTH_FAA_SWITCH_MASK	0x0020
+#define PDR_SYNTH_FAA_SWITCH_ENABLED	0x0020
+#define PDR_SYNTH_24_GHZ_MASK		0x0040
+#define PDR_SYNTH_24_GHZ_DISABLED	0x0040
+#define PDR_SYNTH_5_GHZ_MASK		0x0080
+#define PDR_SYNTH_5_GHZ_DISABLED	0x0080
+#define PDR_SYNTH_RX_DIV_MASK		0x0100
+#define PDR_SYNTH_RX_DIV_SUPPORTED	0x0100
+#define PDR_SYNTH_TX_DIV_MASK		0x0200
+#define PDR_SYNTH_TX_DIV_SUPPORTED	0x0200
+#define PDR_SYNTH_ASM_MASK		0x0400
+#define PDR_SYNTH_ASM_XSWON		0x0400
+
+#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
new file mode 100644
index 0000000..e7b9e9c
--- /dev/null
+++ b/drivers/net/wireless/p54/fwio.c
@@ -0,0 +1,716 @@
+/*
+ * Firmware I/O code for mac80211 Prism54 drivers
+ *
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * - stlc45xx driver
+ *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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/firmware.h>
+#include <linux/etherdevice.h>
+
+#include <net/mac80211.h>
+
+#include "p54.h"
+#include "eeprom.h"
+#include "lmac.h"
+
+int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
+{
+	struct p54_common *priv = dev->priv;
+	struct exp_if *exp_if;
+	struct bootrec *bootrec;
+	u32 *data = (u32 *)fw->data;
+	u32 *end_data = (u32 *)fw->data + (fw->size >> 2);
+	u8 *fw_version = NULL;
+	size_t len;
+	int i;
+	int maxlen;
+
+	if (priv->rx_start)
+		return 0;
+
+	while (data < end_data && *data)
+		data++;
+
+	while (data < end_data && !*data)
+		data++;
+
+	bootrec = (struct bootrec *) data;
+
+	while (bootrec->data <= end_data && (bootrec->data +
+	       (len = le32_to_cpu(bootrec->len))) <= end_data) {
+		u32 code = le32_to_cpu(bootrec->code);
+		switch (code) {
+		case BR_CODE_COMPONENT_ID:
+			priv->fw_interface = be32_to_cpup((__be32 *)
+					     bootrec->data);
+			switch (priv->fw_interface) {
+			case FW_LM86:
+			case FW_LM20:
+			case FW_LM87: {
+				char *iftype = (char *)bootrec->data;
+				printk(KERN_INFO "%s: p54 detected a LM%c%c "
+						 "firmware\n",
+					wiphy_name(priv->hw->wiphy),
+					iftype[2], iftype[3]);
+				break;
+				}
+			case FW_FMAC:
+			default:
+				printk(KERN_ERR "%s: unsupported firmware\n",
+					wiphy_name(priv->hw->wiphy));
+				return -ENODEV;
+			}
+			break;
+		case BR_CODE_COMPONENT_VERSION:
+			/* 24 bytes should be enough for all firmwares */
+			if (strnlen((unsigned char *) bootrec->data, 24) < 24)
+				fw_version = (unsigned char *) bootrec->data;
+			break;
+		case BR_CODE_DESCR: {
+			struct bootrec_desc *desc =
+				(struct bootrec_desc *)bootrec->data;
+			priv->rx_start = le32_to_cpu(desc->rx_start);
+			/* FIXME add sanity checking */
+			priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500;
+			priv->headroom = desc->headroom;
+			priv->tailroom = desc->tailroom;
+			priv->privacy_caps = desc->privacy_caps;
+			priv->rx_keycache_size = desc->rx_keycache_size;
+			if (le32_to_cpu(bootrec->len) == 11)
+				priv->rx_mtu = le16_to_cpu(desc->rx_mtu);
+			else
+				priv->rx_mtu = (size_t)
+					0x620 - priv->tx_hdr_len;
+			maxlen = priv->tx_hdr_len + /* USB devices */
+				 sizeof(struct p54_rx_data) +
+				 4 + /* rx alignment */
+				 IEEE80211_MAX_FRAG_THRESHOLD;
+			if (priv->rx_mtu > maxlen && PAGE_SIZE == 4096) {
+				printk(KERN_INFO "p54: rx_mtu reduced from %d "
+				       "to %d\n", priv->rx_mtu, maxlen);
+				priv->rx_mtu = maxlen;
+			}
+			break;
+			}
+		case BR_CODE_EXPOSED_IF:
+			exp_if = (struct exp_if *) bootrec->data;
+			for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
+				if (exp_if[i].if_id == cpu_to_le16(IF_ID_LMAC))
+					priv->fw_var = le16_to_cpu(exp_if[i].variant);
+			break;
+		case BR_CODE_DEPENDENT_IF:
+			break;
+		case BR_CODE_END_OF_BRA:
+		case LEGACY_BR_CODE_END_OF_BRA:
+			end_data = NULL;
+			break;
+		default:
+			break;
+		}
+		bootrec = (struct bootrec *)&bootrec->data[len];
+	}
+
+	if (fw_version)
+		printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n",
+			wiphy_name(priv->hw->wiphy), fw_version,
+			priv->fw_var >> 8, priv->fw_var & 0xff);
+
+	if (priv->fw_var < 0x500)
+		printk(KERN_INFO "%s: you are using an obsolete firmware. "
+		       "visit http://wireless.kernel.org/en/users/Drivers/p54 "
+		       "and grab one for \"kernel >= 2.6.28\"!\n",
+			wiphy_name(priv->hw->wiphy));
+
+	if (priv->fw_var >= 0x300) {
+		/* Firmware supports QoS, use it! */
+
+		if (priv->fw_var >= 0x500) {
+			priv->tx_stats[P54_QUEUE_AC_VO].limit = 16;
+			priv->tx_stats[P54_QUEUE_AC_VI].limit = 16;
+			priv->tx_stats[P54_QUEUE_AC_BE].limit = 16;
+			priv->tx_stats[P54_QUEUE_AC_BK].limit = 16;
+		} else {
+			priv->tx_stats[P54_QUEUE_AC_VO].limit = 3;
+			priv->tx_stats[P54_QUEUE_AC_VI].limit = 4;
+			priv->tx_stats[P54_QUEUE_AC_BE].limit = 3;
+			priv->tx_stats[P54_QUEUE_AC_BK].limit = 2;
+		}
+		priv->hw->queues = P54_QUEUE_AC_NUM;
+	}
+
+	printk(KERN_INFO "%s: cryptographic accelerator "
+	       "WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(priv->hw->wiphy),
+		(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" :
+		"no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP |
+		BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no",
+		(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
+		"YES" : "no");
+
+	if (priv->rx_keycache_size) {
+		/*
+		 * NOTE:
+		 *
+		 * The firmware provides at most 255 (0 - 254) slots
+		 * for keys which are then used to offload decryption.
+		 * As a result the 255 entry (aka 0xff) can be used
+		 * safely by the driver to mark keys that didn't fit
+		 * into the full cache. This trick saves us from
+		 * keeping a extra list for uploaded keys.
+		 */
+
+		priv->used_rxkeys = kzalloc(BITS_TO_LONGS(
+			priv->rx_keycache_size), GFP_KERNEL);
+
+		if (!priv->used_rxkeys)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(p54_parse_firmware);
+
+static struct sk_buff *p54_alloc_skb(struct p54_common *priv, u16 hdr_flags,
+				     u16 payload_len, u16 type, gfp_t memflags)
+{
+	struct p54_hdr *hdr;
+	struct sk_buff *skb;
+	size_t frame_len = sizeof(*hdr) + payload_len;
+
+	if (frame_len > P54_MAX_CTRL_FRAME_LEN)
+		return NULL;
+
+	if (unlikely(skb_queue_len(&priv->tx_pending) > 64))
+		return NULL;
+
+	skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
+	if (!skb)
+		return NULL;
+	skb_reserve(skb, priv->tx_hdr_len);
+
+	hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr));
+	hdr->flags = cpu_to_le16(hdr_flags);
+	hdr->len = cpu_to_le16(payload_len);
+	hdr->type = cpu_to_le16(type);
+	hdr->tries = hdr->rts_tries = 0;
+	return skb;
+}
+
+int p54_download_eeprom(struct p54_common *priv, void *buf,
+			u16 offset, u16 len)
+{
+	struct p54_eeprom_lm86 *eeprom_hdr;
+	struct sk_buff *skb;
+	size_t eeprom_hdr_size;
+	int ret = 0;
+
+	if (priv->fw_var >= 0x509)
+		eeprom_hdr_size = sizeof(*eeprom_hdr);
+	else
+		eeprom_hdr_size = 0x4;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL, eeprom_hdr_size +
+			    len, P54_CONTROL_TYPE_EEPROM_READBACK,
+			    GFP_KERNEL);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	mutex_lock(&priv->eeprom_mutex);
+	priv->eeprom = buf;
+	eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb,
+		eeprom_hdr_size + len);
+
+	if (priv->fw_var < 0x509) {
+		eeprom_hdr->v1.offset = cpu_to_le16(offset);
+		eeprom_hdr->v1.len = cpu_to_le16(len);
+	} else {
+		eeprom_hdr->v2.offset = cpu_to_le32(offset);
+		eeprom_hdr->v2.len = cpu_to_le16(len);
+		eeprom_hdr->v2.magic2 = 0xf;
+		memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4);
+	}
+
+	p54_tx(priv, skb);
+
+	if (!wait_for_completion_interruptible_timeout(
+	     &priv->eeprom_comp, HZ)) {
+		printk(KERN_ERR "%s: device does not respond!\n",
+		       wiphy_name(priv->hw->wiphy));
+		ret = -EBUSY;
+	}
+	priv->eeprom = NULL;
+	mutex_unlock(&priv->eeprom_mutex);
+	return ret;
+}
+
+int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set)
+{
+	struct sk_buff *skb;
+	struct p54_tim *tim;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
+			    P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	tim = (struct p54_tim *) skb_put(skb, sizeof(*tim));
+	tim->count = 1;
+	tim->entry[0] = cpu_to_le16(set ? (aid | 0x8000) : aid);
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_sta_unlock(struct p54_common *priv, u8 *addr)
+{
+	struct sk_buff *skb;
+	struct p54_sta_unlock *sta;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
+			    P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	sta = (struct p54_sta_unlock *)skb_put(skb, sizeof(*sta));
+	memcpy(sta->addr, addr, ETH_ALEN);
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_tx_cancel(struct p54_common *priv, __le32 req_id)
+{
+	struct sk_buff *skb;
+	struct p54_txcancel *cancel;
+	u32 _req_id = le32_to_cpu(req_id);
+
+	if (unlikely(_req_id < priv->rx_start || _req_id > priv->rx_end))
+		return -EINVAL;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
+			    P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	cancel = (struct p54_txcancel *)skb_put(skb, sizeof(*cancel));
+	cancel->req_id = req_id;
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_setup_mac(struct p54_common *priv)
+{
+	struct sk_buff *skb;
+	struct p54_setup_mac *setup;
+	u16 mode;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
+			    P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	setup = (struct p54_setup_mac *) skb_put(skb, sizeof(*setup));
+	if (!(priv->hw->conf.flags & IEEE80211_CONF_IDLE)) {
+		switch (priv->mode) {
+		case NL80211_IFTYPE_STATION:
+			mode = P54_FILTER_TYPE_STATION;
+			break;
+		case NL80211_IFTYPE_AP:
+			mode = P54_FILTER_TYPE_AP;
+			break;
+		case NL80211_IFTYPE_ADHOC:
+		case NL80211_IFTYPE_MESH_POINT:
+			mode = P54_FILTER_TYPE_IBSS;
+			break;
+		case NL80211_IFTYPE_MONITOR:
+			mode = P54_FILTER_TYPE_PROMISCUOUS;
+			break;
+		default:
+			mode = P54_FILTER_TYPE_HIBERNATE;
+			break;
+		}
+
+		/*
+		 * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
+		 * STSW45X0C LMAC API - page 12
+		 */
+		if (((priv->filter_flags & FIF_PROMISC_IN_BSS) ||
+		     (priv->filter_flags & FIF_OTHER_BSS)) &&
+		    (mode != P54_FILTER_TYPE_PROMISCUOUS))
+			mode |= P54_FILTER_TYPE_TRANSPARENT;
+	} else {
+		mode = P54_FILTER_TYPE_HIBERNATE;
+	}
+
+	setup->mac_mode = cpu_to_le16(mode);
+	memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
+	memcpy(setup->bssid, priv->bssid, ETH_ALEN);
+	setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */
+	setup->rx_align = 0;
+	if (priv->fw_var < 0x500) {
+		setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+		memset(setup->v1.rts_rates, 0, 8);
+		setup->v1.rx_addr = cpu_to_le32(priv->rx_end);
+		setup->v1.max_rx = cpu_to_le16(priv->rx_mtu);
+		setup->v1.rxhw = cpu_to_le16(priv->rxhw);
+		setup->v1.wakeup_timer = cpu_to_le16(priv->wakeup_timer);
+		setup->v1.unalloc0 = cpu_to_le16(0);
+	} else {
+		setup->v2.rx_addr = cpu_to_le32(priv->rx_end);
+		setup->v2.max_rx = cpu_to_le16(priv->rx_mtu);
+		setup->v2.rxhw = cpu_to_le16(priv->rxhw);
+		setup->v2.timer = cpu_to_le16(priv->wakeup_timer);
+		setup->v2.truncate = cpu_to_le16(48896);
+		setup->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+		setup->v2.sbss_offset = 0;
+		setup->v2.mcast_window = 0;
+		setup->v2.rx_rssi_threshold = 0;
+		setup->v2.rx_ed_threshold = 0;
+		setup->v2.ref_clock = cpu_to_le32(644245094);
+		setup->v2.lpf_bandwidth = cpu_to_le16(65535);
+		setup->v2.osc_start_delay = cpu_to_le16(65535);
+	}
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
+{
+	struct sk_buff *skb;
+	struct p54_hdr *hdr;
+	struct p54_scan_head *head;
+	struct p54_iq_autocal_entry *iq_autocal;
+	union p54_scan_body_union *body;
+	struct p54_scan_tail_rate *rate;
+	struct pda_rssi_cal_entry *rssi;
+	unsigned int i;
+	void *entry;
+	int band = priv->hw->conf.channel->band;
+	__le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq);
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
+			    2 + sizeof(*iq_autocal) + sizeof(*body) +
+			    sizeof(*rate) + 2 * sizeof(*rssi),
+			    P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	head = (struct p54_scan_head *) skb_put(skb, sizeof(*head));
+	memset(head->scan_params, 0, sizeof(head->scan_params));
+	head->mode = cpu_to_le16(mode);
+	head->dwell = cpu_to_le16(dwell);
+	head->freq = freq;
+
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+		__le16 *pa_power_points = (__le16 *) skb_put(skb, 2);
+		*pa_power_points = cpu_to_le16(0x0c);
+	}
+
+	iq_autocal = (void *) skb_put(skb, sizeof(*iq_autocal));
+	for (i = 0; i < priv->iq_autocal_len; i++) {
+		if (priv->iq_autocal[i].freq != freq)
+			continue;
+
+		memcpy(iq_autocal, &priv->iq_autocal[i].params,
+		       sizeof(struct p54_iq_autocal_entry));
+		break;
+	}
+	if (i == priv->iq_autocal_len)
+		goto err;
+
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
+		body = (void *) skb_put(skb, sizeof(body->longbow));
+	else
+		body = (void *) skb_put(skb, sizeof(body->normal));
+
+	for (i = 0; i < priv->output_limit->entries; i++) {
+		__le16 *entry_freq = (void *) (priv->output_limit->data +
+				     priv->output_limit->entry_size * i);
+
+		if (*entry_freq != freq)
+			continue;
+
+		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+			memcpy(&body->longbow.power_limits,
+			       (void *) entry_freq + sizeof(__le16),
+			       priv->output_limit->entry_size);
+		} else {
+			struct pda_channel_output_limit *limits =
+			       (void *) entry_freq;
+
+			body->normal.val_barker = 0x38;
+			body->normal.val_bpsk = body->normal.dup_bpsk =
+				limits->val_bpsk;
+			body->normal.val_qpsk = body->normal.dup_qpsk =
+				limits->val_qpsk;
+			body->normal.val_16qam = body->normal.dup_16qam =
+				limits->val_16qam;
+			body->normal.val_64qam = body->normal.dup_64qam =
+				limits->val_64qam;
+		}
+		break;
+	}
+	if (i == priv->output_limit->entries)
+		goto err;
+
+	entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
+	for (i = 0; i < priv->curve_data->entries; i++) {
+		if (*((__le16 *)entry) != freq) {
+			entry += priv->curve_data->entry_size;
+			continue;
+		}
+
+		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+			memcpy(&body->longbow.curve_data,
+				(void *) entry + sizeof(__le16),
+				priv->curve_data->entry_size);
+		} else {
+			struct p54_scan_body *chan = &body->normal;
+			struct pda_pa_curve_data *curve_data =
+				(void *) priv->curve_data->data;
+
+			entry += sizeof(__le16);
+			chan->pa_points_per_curve = 8;
+			memset(chan->curve_data, 0, sizeof(*chan->curve_data));
+			memcpy(chan->curve_data, entry,
+			       sizeof(struct p54_pa_curve_data_sample) *
+			       min((u8)8, curve_data->points_per_channel));
+		}
+		break;
+	}
+	if (i == priv->curve_data->entries)
+		goto err;
+
+	if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
+		rate = (void *) skb_put(skb, sizeof(*rate));
+		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+		for (i = 0; i < sizeof(rate->rts_rates); i++)
+			rate->rts_rates[i] = i;
+	}
+
+	rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
+	rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
+	rssi->add = cpu_to_le16(priv->rssical_db[band].add);
+	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
+		/* Longbow frontend needs ever more */
+		rssi = (void *) skb_put(skb, sizeof(*rssi));
+		rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
+		rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
+	}
+
+	if (priv->fw_var >= 0x509) {
+		rate = (void *) skb_put(skb, sizeof(*rate));
+		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
+		for (i = 0; i < sizeof(rate->rts_rates); i++)
+			rate->rts_rates[i] = i;
+	}
+
+	hdr = (struct p54_hdr *) skb->data;
+	hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
+
+	p54_tx(priv, skb);
+	return 0;
+
+err:
+	printk(KERN_ERR "%s: frequency change to channel %d failed.\n",
+	       wiphy_name(priv->hw->wiphy), ieee80211_frequency_to_channel(
+	       priv->hw->conf.channel->center_freq));
+
+	dev_kfree_skb_any(skb);
+	return -EINVAL;
+}
+
+int p54_set_leds(struct p54_common *priv)
+{
+	struct sk_buff *skb;
+	struct p54_led *led;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
+			    P54_CONTROL_TYPE_LED, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	led = (struct p54_led *) skb_put(skb, sizeof(*led));
+	led->flags = cpu_to_le16(0x0003);
+	led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
+	led->delay[0] = cpu_to_le16(1);
+	led->delay[1] = cpu_to_le16(0);
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_set_edcf(struct p54_common *priv)
+{
+	struct sk_buff *skb;
+	struct p54_edcf *edcf;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
+			    P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	edcf = (struct p54_edcf *)skb_put(skb, sizeof(*edcf));
+	if (priv->use_short_slot) {
+		edcf->slottime = 9;
+		edcf->sifs = 0x10;
+		edcf->eofpad = 0x00;
+	} else {
+		edcf->slottime = 20;
+		edcf->sifs = 0x0a;
+		edcf->eofpad = 0x06;
+	}
+	/* (see prism54/isl_oid.h for further details) */
+	edcf->frameburst = cpu_to_le16(0);
+	edcf->round_trip_delay = cpu_to_le16(0);
+	edcf->flags = 0;
+	memset(edcf->mapping, 0, sizeof(edcf->mapping));
+	memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_set_ps(struct p54_common *priv)
+{
+	struct sk_buff *skb;
+	struct p54_psm *psm;
+	unsigned int i;
+	u16 mode;
+
+	if (priv->hw->conf.flags & IEEE80211_CONF_PS &&
+	    !priv->powersave_override)
+		mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
+		       P54_PSM_CHECKSUM | P54_PSM_MCBC;
+	else
+		mode = P54_PSM_CAM;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
+			    P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	psm = (struct p54_psm *)skb_put(skb, sizeof(*psm));
+	psm->mode = cpu_to_le16(mode);
+	psm->aid = cpu_to_le16(priv->aid);
+	for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) {
+		psm->intervals[i].interval =
+			cpu_to_le16(priv->hw->conf.listen_interval);
+		psm->intervals[i].periods = cpu_to_le16(1);
+	}
+
+	psm->beacon_rssi_skip_max = 200;
+	psm->rssi_delta_threshold = 0;
+	psm->nr = 1;
+	psm->exclude[0] = WLAN_EID_TIM;
+
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_init_xbow_synth(struct p54_common *priv)
+{
+	struct sk_buff *skb;
+	struct p54_xbow_synth *xbow;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
+			    P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	xbow = (struct p54_xbow_synth *)skb_put(skb, sizeof(*xbow));
+	xbow->magic1 = cpu_to_le16(0x1);
+	xbow->magic2 = cpu_to_le16(0x2);
+	xbow->freq = cpu_to_le16(5390);
+	memset(xbow->padding, 0, sizeof(xbow->padding));
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
+		   u8 *addr, u8* key)
+{
+	struct sk_buff *skb;
+	struct p54_keycache *rxkey;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
+			    P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL);
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	rxkey = (struct p54_keycache *)skb_put(skb, sizeof(*rxkey));
+	rxkey->entry = slot;
+	rxkey->key_id = idx;
+	rxkey->key_type = algo;
+	if (addr)
+		memcpy(rxkey->mac, addr, ETH_ALEN);
+	else
+		memset(rxkey->mac, ~0, ETH_ALEN);
+
+	switch (algo) {
+	case P54_CRYPTO_WEP:
+	case P54_CRYPTO_AESCCMP:
+		rxkey->key_len = min_t(u8, 16, len);
+		memcpy(rxkey->key, key, rxkey->key_len);
+		break;
+
+	case P54_CRYPTO_TKIPMICHAEL:
+		rxkey->key_len = 24;
+		memcpy(rxkey->key, key, 16);
+		memcpy(&(rxkey->key[16]), &(key
+			[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8);
+		break;
+
+	case P54_CRYPTO_NONE:
+		rxkey->key_len = 0;
+		memset(rxkey->key, 0, sizeof(rxkey->key));
+		break;
+
+	default:
+		printk(KERN_ERR "%s: invalid cryptographic algorithm: %d\n",
+		       wiphy_name(priv->hw->wiphy), algo);
+		dev_kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	p54_tx(priv, skb);
+	return 0;
+}
+
+int p54_fetch_statistics(struct p54_common *priv)
+{
+	struct ieee80211_tx_info *txinfo;
+	struct p54_tx_info *p54info;
+	struct sk_buff *skb;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL,
+			    sizeof(struct p54_statistics),
+			    P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	/*
+	 * The statistic feedback causes some extra headaches here, if it
+	 * is not to crash/corrupt the firmware data structures.
+	 *
+	 * Unlike all other Control Get OIDs we can not use helpers like
+	 * skb_put to reserve the space for the data we're requesting.
+	 * Instead the extra frame length -which will hold the results later-
+	 * will only be told to the p54_assign_address, so that following
+	 * frames won't be placed into the  allegedly empty area.
+	 */
+	txinfo = IEEE80211_SKB_CB(skb);
+	p54info = (void *) txinfo->rate_driver_data;
+	p54info->extra_len = sizeof(struct p54_statistics);
+
+	p54_tx(priv, skb);
+	return 0;
+}
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c
new file mode 100644
index 0000000..9575ac0
--- /dev/null
+++ b/drivers/net/wireless/p54/led.c
@@ -0,0 +1,162 @@
+/*
+ * Common code for mac80211 Prism54 drivers
+ *
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * - stlc45xx driver
+ *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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/firmware.h>
+#include <linux/etherdevice.h>
+
+#include <net/mac80211.h>
+#ifdef CONFIG_P54_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_P54_LEDS */
+
+#include "p54.h"
+#include "lmac.h"
+
+static void p54_update_leds(struct work_struct *work)
+{
+	struct p54_common *priv = container_of(work, struct p54_common,
+					       led_work.work);
+	int err, i, tmp, blink_delay = 400;
+	bool rerun = false;
+
+	/* Don't toggle the LED, when the device is down. */
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+		return ;
+
+	for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
+		if (priv->leds[i].toggled) {
+			priv->softled_state |= BIT(i);
+
+			tmp = 70 + 200 / (priv->leds[i].toggled);
+			if (tmp < blink_delay)
+				blink_delay = tmp;
+
+			if (priv->leds[i].led_dev.brightness == LED_OFF)
+				rerun = true;
+
+			priv->leds[i].toggled =
+				!!priv->leds[i].led_dev.brightness;
+		} else
+			priv->softled_state &= ~BIT(i);
+
+	err = p54_set_leds(priv);
+	if (err && net_ratelimit())
+		printk(KERN_ERR "%s: failed to update LEDs (%d).\n",
+			wiphy_name(priv->hw->wiphy), err);
+
+	if (rerun)
+		ieee80211_queue_delayed_work(priv->hw, &priv->led_work,
+			msecs_to_jiffies(blink_delay));
+}
+
+static void p54_led_brightness_set(struct led_classdev *led_dev,
+				   enum led_brightness brightness)
+{
+	struct p54_led_dev *led = container_of(led_dev, struct p54_led_dev,
+					       led_dev);
+	struct ieee80211_hw *dev = led->hw_dev;
+	struct p54_common *priv = dev->priv;
+
+	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+		return ;
+
+	if ((brightness) && (led->registered)) {
+		led->toggled++;
+		ieee80211_queue_delayed_work(priv->hw, &priv->led_work, HZ/10);
+	}
+}
+
+static int p54_register_led(struct p54_common *priv,
+			    unsigned int led_index,
+			    char *name, char *trigger)
+{
+	struct p54_led_dev *led = &priv->leds[led_index];
+	int err;
+
+	if (led->registered)
+		return -EEXIST;
+
+	snprintf(led->name, sizeof(led->name), "p54-%s::%s",
+		 wiphy_name(priv->hw->wiphy), name);
+	led->hw_dev = priv->hw;
+	led->index = led_index;
+	led->led_dev.name = led->name;
+	led->led_dev.default_trigger = trigger;
+	led->led_dev.brightness_set = p54_led_brightness_set;
+
+	err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev);
+	if (err)
+		printk(KERN_ERR "%s: Failed to register %s LED.\n",
+			wiphy_name(priv->hw->wiphy), name);
+	else
+		led->registered = 1;
+
+	return err;
+}
+
+int p54_init_leds(struct p54_common *priv)
+{
+	int err;
+
+	/*
+	 * TODO:
+	 * Figure out if the EEPROM contains some hints about the number
+	 * of available/programmable LEDs of the device.
+	 */
+
+	INIT_DELAYED_WORK(&priv->led_work, p54_update_leds);
+
+	err = p54_register_led(priv, 0, "assoc",
+			       ieee80211_get_assoc_led_name(priv->hw));
+	if (err)
+		return err;
+
+	err = p54_register_led(priv, 1, "tx",
+			       ieee80211_get_tx_led_name(priv->hw));
+	if (err)
+		return err;
+
+	err = p54_register_led(priv, 2, "rx",
+			       ieee80211_get_rx_led_name(priv->hw));
+	if (err)
+		return err;
+
+	err = p54_register_led(priv, 3, "radio",
+			       ieee80211_get_radio_led_name(priv->hw));
+	if (err)
+		return err;
+
+	err = p54_set_leds(priv);
+	return err;
+}
+
+void p54_unregister_leds(struct p54_common *priv)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(priv->leds); i++) {
+		if (priv->leds[i].registered) {
+			priv->leds[i].registered = false;
+			priv->leds[i].toggled = 0;
+			led_classdev_unregister(&priv->leds[i].led_dev);
+		}
+	}
+
+	cancel_delayed_work_sync(&priv->led_work);
+}
diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h
new file mode 100644
index 0000000..04b63ec
--- /dev/null
+++ b/drivers/net/wireless/p54/lmac.h
@@ -0,0 +1,558 @@
+/*
+ * LMAC Interface specific definitions for mac80211 Prism54 drivers
+ *
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007 - 2009, Christian Lamparter <chunkeey@web.de>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ *
+ * - LMAC API interface header file for STLC4560 (lmac_longbow.h)
+ *   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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef LMAC_H
+#define LMAC_H
+
+enum p54_control_frame_types {
+	P54_CONTROL_TYPE_SETUP = 0,
+	P54_CONTROL_TYPE_SCAN,
+	P54_CONTROL_TYPE_TRAP,
+	P54_CONTROL_TYPE_DCFINIT,
+	P54_CONTROL_TYPE_RX_KEYCACHE,
+	P54_CONTROL_TYPE_TIM,
+	P54_CONTROL_TYPE_PSM,
+	P54_CONTROL_TYPE_TXCANCEL,
+	P54_CONTROL_TYPE_TXDONE,
+	P54_CONTROL_TYPE_BURST,
+	P54_CONTROL_TYPE_STAT_READBACK,
+	P54_CONTROL_TYPE_BBP,
+	P54_CONTROL_TYPE_EEPROM_READBACK,
+	P54_CONTROL_TYPE_LED,
+	P54_CONTROL_TYPE_GPIO,
+	P54_CONTROL_TYPE_TIMER,
+	P54_CONTROL_TYPE_MODULATION,
+	P54_CONTROL_TYPE_SYNTH_CONFIG,
+	P54_CONTROL_TYPE_DETECTOR_VALUE,
+	P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
+	P54_CONTROL_TYPE_CCE_QUIET,
+	P54_CONTROL_TYPE_PSM_STA_UNLOCK,
+	P54_CONTROL_TYPE_PCS,
+	P54_CONTROL_TYPE_BT_BALANCER = 28,
+	P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE = 30,
+	P54_CONTROL_TYPE_ARPTABLE = 31,
+	P54_CONTROL_TYPE_BT_OPTIONS = 35,
+};
+
+#define P54_HDR_FLAG_CONTROL		BIT(15)
+#define P54_HDR_FLAG_CONTROL_OPSET	(BIT(15) + BIT(0))
+#define P54_HDR_FLAG_DATA_ALIGN		BIT(14)
+
+#define P54_HDR_FLAG_DATA_OUT_PROMISC		BIT(0)
+#define P54_HDR_FLAG_DATA_OUT_TIMESTAMP		BIT(1)
+#define P54_HDR_FLAG_DATA_OUT_SEQNR		BIT(2)
+#define P54_HDR_FLAG_DATA_OUT_BIT3		BIT(3)
+#define P54_HDR_FLAG_DATA_OUT_BURST		BIT(4)
+#define P54_HDR_FLAG_DATA_OUT_NOCANCEL		BIT(5)
+#define P54_HDR_FLAG_DATA_OUT_CLEARTIM		BIT(6)
+#define P54_HDR_FLAG_DATA_OUT_HITCHHIKE		BIT(7)
+#define P54_HDR_FLAG_DATA_OUT_COMPRESS		BIT(8)
+#define P54_HDR_FLAG_DATA_OUT_CONCAT		BIT(9)
+#define P54_HDR_FLAG_DATA_OUT_PCS_ACCEPT	BIT(10)
+#define P54_HDR_FLAG_DATA_OUT_WAITEOSP		BIT(11)
+
+#define P54_HDR_FLAG_DATA_IN_FCS_GOOD		BIT(0)
+#define P54_HDR_FLAG_DATA_IN_MATCH_MAC		BIT(1)
+#define P54_HDR_FLAG_DATA_IN_MCBC		BIT(2)
+#define P54_HDR_FLAG_DATA_IN_BEACON		BIT(3)
+#define P54_HDR_FLAG_DATA_IN_MATCH_BSS		BIT(4)
+#define P54_HDR_FLAG_DATA_IN_BCAST_BSS		BIT(5)
+#define P54_HDR_FLAG_DATA_IN_DATA		BIT(6)
+#define P54_HDR_FLAG_DATA_IN_TRUNCATED		BIT(7)
+#define P54_HDR_FLAG_DATA_IN_BIT8		BIT(8)
+#define P54_HDR_FLAG_DATA_IN_TRANSPARENT	BIT(9)
+
+struct p54_hdr {
+	__le16 flags;
+	__le16 len;
+	__le32 req_id;
+	__le16 type;	/* enum p54_control_frame_types */
+	u8 rts_tries;
+	u8 tries;
+	u8 data[0];
+} __packed;
+
+#define GET_REQ_ID(skb)							\
+	(((struct p54_hdr *) ((struct sk_buff *) skb)->data)->req_id)	\
+
+#define FREE_AFTER_TX(skb)						\
+	((((struct p54_hdr *) ((struct sk_buff *) skb)->data)->		\
+	flags) == cpu_to_le16(P54_HDR_FLAG_CONTROL_OPSET))
+
+#define IS_DATA_FRAME(skb)						\
+	(!((((struct p54_hdr *) ((struct sk_buff *) skb)->data)->	\
+	flags) & cpu_to_le16(P54_HDR_FLAG_CONTROL)))
+
+#define GET_HW_QUEUE(skb)						\
+	(((struct p54_tx_data *)((struct p54_hdr *)			\
+	skb->data)->data)->hw_queue)
+
+/*
+ * shared interface ID definitions
+ * The interface ID is a unique identification of a specific interface.
+ * The following values are reserved: 0x0000, 0x0002, 0x0012, 0x0014, 0x0015
+ */
+#define IF_ID_ISL36356A			0x0001	/* ISL36356A <-> Firmware */
+#define IF_ID_MVC			0x0003	/* MAC Virtual Coprocessor */
+#define IF_ID_DEBUG			0x0008	/* PolDebug Interface */
+#define IF_ID_PRODUCT			0x0009
+#define IF_ID_OEM			0x000a
+#define IF_ID_PCI3877			0x000b	/* 3877 <-> Host PCI */
+#define IF_ID_ISL37704C			0x000c	/* ISL37704C <-> Fw */
+#define IF_ID_ISL39000			0x000f	/* ISL39000 <-> Fw */
+#define IF_ID_ISL39300A			0x0010	/* ISL39300A <-> Fw */
+#define IF_ID_ISL37700_UAP		0x0016	/* ISL37700 uAP Fw <-> Fw */
+#define IF_ID_ISL39000_UAP		0x0017	/* ISL39000 uAP Fw <-> Fw */
+#define IF_ID_LMAC			0x001a	/* Interface exposed by LMAC */
+
+struct exp_if {
+	__le16 role;
+	__le16 if_id;
+	__le16 variant;
+	__le16 btm_compat;
+	__le16 top_compat;
+} __packed;
+
+struct dep_if {
+	__le16 role;
+	__le16 if_id;
+	__le16 variant;
+} __packed;
+
+/* driver <-> lmac definitions */
+struct p54_eeprom_lm86 {
+	union {
+		struct {
+			__le16 offset;
+			__le16 len;
+			u8 data[0];
+		} __packed v1;
+		struct {
+			__le32 offset;
+			__le16 len;
+			u8 magic2;
+			u8 pad;
+			u8 magic[4];
+			u8 data[0];
+		} __packed v2;
+	}  __packed;
+} __packed;
+
+enum p54_rx_decrypt_status {
+	P54_DECRYPT_NONE = 0,
+	P54_DECRYPT_OK,
+	P54_DECRYPT_NOKEY,
+	P54_DECRYPT_NOMICHAEL,
+	P54_DECRYPT_NOCKIPMIC,
+	P54_DECRYPT_FAIL_WEP,
+	P54_DECRYPT_FAIL_TKIP,
+	P54_DECRYPT_FAIL_MICHAEL,
+	P54_DECRYPT_FAIL_CKIPKP,
+	P54_DECRYPT_FAIL_CKIPMIC,
+	P54_DECRYPT_FAIL_AESCCMP
+};
+
+struct p54_rx_data {
+	__le16 flags;
+	__le16 len;
+	__le16 freq;
+	u8 antenna;
+	u8 rate;
+	u8 rssi;
+	u8 quality;
+	u8 decrypt_status;
+	u8 rssi_raw;
+	__le32 tsf32;
+	__le32 unalloc0;
+	u8 align[0];
+} __packed;
+
+enum p54_trap_type {
+	P54_TRAP_SCAN = 0,
+	P54_TRAP_TIMER,
+	P54_TRAP_BEACON_TX,
+	P54_TRAP_FAA_RADIO_ON,
+	P54_TRAP_FAA_RADIO_OFF,
+	P54_TRAP_RADAR,
+	P54_TRAP_NO_BEACON,
+	P54_TRAP_TBTT,
+	P54_TRAP_SCO_ENTER,
+	P54_TRAP_SCO_EXIT
+};
+
+struct p54_trap {
+	__le16 event;
+	__le16 frequency;
+} __packed;
+
+enum p54_frame_sent_status {
+	P54_TX_OK = 0,
+	P54_TX_FAILED,
+	P54_TX_PSM,
+	P54_TX_PSM_CANCELLED = 4
+};
+
+struct p54_frame_sent {
+	u8 status;
+	u8 tries;
+	u8 ack_rssi;
+	u8 quality;
+	__le16 seq;
+	u8 antenna;
+	u8 padding;
+} __packed;
+
+enum p54_tx_data_crypt {
+	P54_CRYPTO_NONE = 0,
+	P54_CRYPTO_WEP,
+	P54_CRYPTO_TKIP,
+	P54_CRYPTO_TKIPMICHAEL,
+	P54_CRYPTO_CCX_WEPMIC,
+	P54_CRYPTO_CCX_KPMIC,
+	P54_CRYPTO_CCX_KP,
+	P54_CRYPTO_AESCCMP
+};
+
+enum p54_tx_data_queue {
+	P54_QUEUE_BEACON	= 0,
+	P54_QUEUE_FWSCAN	= 1,
+	P54_QUEUE_MGMT		= 2,
+	P54_QUEUE_CAB		= 3,
+	P54_QUEUE_DATA		= 4,
+
+	P54_QUEUE_AC_NUM	= 4,
+	P54_QUEUE_AC_VO		= 4,
+	P54_QUEUE_AC_VI		= 5,
+	P54_QUEUE_AC_BE		= 6,
+	P54_QUEUE_AC_BK		= 7,
+
+	/* keep last */
+	P54_QUEUE_NUM		= 8,
+};
+
+#define IS_QOS_QUEUE(n)	(n >= P54_QUEUE_DATA)
+
+struct p54_tx_data {
+	u8 rateset[8];
+	u8 rts_rate_idx;
+	u8 crypt_offset;
+	u8 key_type;
+	u8 key_len;
+	u8 key[16];
+	u8 hw_queue;
+	u8 backlog;
+	__le16 durations[4];
+	u8 tx_antenna;
+	union {
+		struct {
+			u8 cts_rate;
+			__le16 output_power;
+		} __packed longbow;
+		struct {
+			u8 output_power;
+			u8 cts_rate;
+			u8 unalloc;
+		} __packed normal;
+	} __packed;
+	u8 unalloc2[2];
+	u8 align[0];
+} __packed;
+
+/* unit is ms */
+#define P54_TX_FRAME_LIFETIME 2000
+#define P54_TX_TIMEOUT 4000
+#define P54_STATISTICS_UPDATE 5000
+
+#define P54_FILTER_TYPE_NONE		0
+#define P54_FILTER_TYPE_STATION		BIT(0)
+#define P54_FILTER_TYPE_IBSS		BIT(1)
+#define P54_FILTER_TYPE_AP		BIT(2)
+#define P54_FILTER_TYPE_TRANSPARENT	BIT(3)
+#define P54_FILTER_TYPE_PROMISCUOUS	BIT(4)
+#define P54_FILTER_TYPE_HIBERNATE	BIT(5)
+#define P54_FILTER_TYPE_NOACK		BIT(6)
+#define P54_FILTER_TYPE_RX_DISABLED	BIT(7)
+
+struct p54_setup_mac {
+	__le16 mac_mode;
+	u8 mac_addr[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+	u8 rx_antenna;
+	u8 rx_align;
+	union {
+		struct {
+			__le32 basic_rate_mask;
+			u8 rts_rates[8];
+			__le32 rx_addr;
+			__le16 max_rx;
+			__le16 rxhw;
+			__le16 wakeup_timer;
+			__le16 unalloc0;
+		} __packed v1;
+		struct {
+			__le32 rx_addr;
+			__le16 max_rx;
+			__le16 rxhw;
+			__le16 timer;
+			__le16 truncate;
+			__le32 basic_rate_mask;
+			u8 sbss_offset;
+			u8 mcast_window;
+			u8 rx_rssi_threshold;
+			u8 rx_ed_threshold;
+			__le32 ref_clock;
+			__le16 lpf_bandwidth;
+			__le16 osc_start_delay;
+		} __packed v2;
+	} __packed;
+} __packed;
+
+#define P54_SETUP_V1_LEN 40
+#define P54_SETUP_V2_LEN (sizeof(struct p54_setup_mac))
+
+#define P54_SCAN_EXIT	BIT(0)
+#define P54_SCAN_TRAP	BIT(1)
+#define P54_SCAN_ACTIVE BIT(2)
+#define P54_SCAN_FILTER BIT(3)
+
+struct p54_scan_head {
+	__le16 mode;
+	__le16 dwell;
+	u8 scan_params[20];
+	__le16 freq;
+} __packed;
+
+struct p54_pa_curve_data_sample {
+	u8 rf_power;
+	u8 pa_detector;
+	u8 data_barker;
+	u8 data_bpsk;
+	u8 data_qpsk;
+	u8 data_16qam;
+	u8 data_64qam;
+	u8 padding;
+} __packed;
+
+struct p54_scan_body {
+	u8 pa_points_per_curve;
+	u8 val_barker;
+	u8 val_bpsk;
+	u8 val_qpsk;
+	u8 val_16qam;
+	u8 val_64qam;
+	struct p54_pa_curve_data_sample curve_data[8];
+	u8 dup_bpsk;
+	u8 dup_qpsk;
+	u8 dup_16qam;
+	u8 dup_64qam;
+} __packed;
+
+/*
+ * Warning: Longbow's structures are bogus.
+ */
+struct p54_channel_output_limit_longbow {
+	__le16 rf_power_points[12];
+} __packed;
+
+struct p54_pa_curve_data_sample_longbow {
+	__le16 rf_power;
+	__le16 pa_detector;
+	struct {
+		__le16 data[4];
+	} points[3] __packed;
+} __packed;
+
+struct p54_scan_body_longbow {
+	struct p54_channel_output_limit_longbow power_limits;
+	struct p54_pa_curve_data_sample_longbow curve_data[8];
+	__le16 unkn[6];		/* maybe more power_limits or rate_mask */
+} __packed;
+
+union p54_scan_body_union {
+	struct p54_scan_body normal;
+	struct p54_scan_body_longbow longbow;
+} __packed;
+
+struct p54_scan_tail_rate {
+	__le32 basic_rate_mask;
+	u8 rts_rates[8];
+} __packed;
+
+struct p54_led {
+	__le16 flags;
+	__le16 mask[2];
+	__le16 delay[2];
+} __packed;
+
+struct p54_edcf {
+	u8 flags;
+	u8 slottime;
+	u8 sifs;
+	u8 eofpad;
+	struct p54_edcf_queue_param queue[8];
+	u8 mapping[4];
+	__le16 frameburst;
+	__le16 round_trip_delay;
+} __packed;
+
+struct p54_statistics {
+	__le32 rx_success;
+	__le32 rx_bad_fcs;
+	__le32 rx_abort;
+	__le32 rx_abort_phy;
+	__le32 rts_success;
+	__le32 rts_fail;
+	__le32 tsf32;
+	__le32 airtime;
+	__le32 noise;
+	__le32 sample_noise[8];
+	__le32 sample_cca;
+	__le32 sample_tx;
+} __packed;
+
+struct p54_xbow_synth {
+	__le16 magic1;
+	__le16 magic2;
+	__le16 freq;
+	u32 padding[5];
+} __packed;
+
+struct p54_timer {
+	__le32 interval;
+} __packed;
+
+struct p54_keycache {
+	u8 entry;
+	u8 key_id;
+	u8 mac[ETH_ALEN];
+	u8 padding[2];
+	u8 key_type;
+	u8 key_len;
+	u8 key[24];
+} __packed;
+
+struct p54_burst {
+	u8 flags;
+	u8 queue;
+	u8 backlog;
+	u8 pad;
+	__le16 durations[32];
+} __packed;
+
+struct p54_psm_interval {
+	__le16 interval;
+	__le16 periods;
+} __packed;
+
+#define P54_PSM_CAM			0
+#define P54_PSM				BIT(0)
+#define P54_PSM_DTIM			BIT(1)
+#define P54_PSM_MCBC			BIT(2)
+#define P54_PSM_CHECKSUM		BIT(3)
+#define P54_PSM_SKIP_MORE_DATA		BIT(4)
+#define P54_PSM_BEACON_TIMEOUT		BIT(5)
+#define P54_PSM_HFOSLEEP		BIT(6)
+#define P54_PSM_AUTOSWITCH_SLEEP	BIT(7)
+#define P54_PSM_LPIT			BIT(8)
+#define P54_PSM_BF_UCAST_SKIP		BIT(9)
+#define P54_PSM_BF_MCAST_SKIP		BIT(10)
+
+struct p54_psm {
+	__le16 mode;
+	__le16 aid;
+	struct p54_psm_interval intervals[4];
+	u8 beacon_rssi_skip_max;
+	u8 rssi_delta_threshold;
+	u8 nr;
+	u8 exclude[1];
+} __packed;
+
+#define MC_FILTER_ADDRESS_NUM 4
+
+struct p54_group_address_table {
+	__le16 filter_enable;
+	__le16 num_address;
+	u8 mac_list[MC_FILTER_ADDRESS_NUM][ETH_ALEN];
+} __packed;
+
+struct p54_txcancel {
+	__le32 req_id;
+} __packed;
+
+struct p54_sta_unlock {
+	u8 addr[ETH_ALEN];
+	u16 padding;
+} __packed;
+
+#define P54_TIM_CLEAR BIT(15)
+struct p54_tim {
+	u8 count;
+	u8 padding[3];
+	__le16 entry[8];
+} __packed;
+
+struct p54_cce_quiet {
+	__le32 period;
+} __packed;
+
+struct p54_bt_balancer {
+	__le16 prio_thresh;
+	__le16 acl_thresh;
+} __packed;
+
+struct p54_arp_table {
+	__le16 filter_enable;
+	u8 ipv4_addr[4];
+} __packed;
+
+/* LED control */
+int p54_set_leds(struct p54_common *priv);
+int p54_init_leds(struct p54_common *priv);
+void p54_unregister_leds(struct p54_common *priv);
+
+/* xmit functions */
+int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb);
+int p54_tx_cancel(struct p54_common *priv, __le32 req_id);
+void p54_tx(struct p54_common *priv, struct sk_buff *skb);
+
+/* synth/phy configuration */
+int p54_init_xbow_synth(struct p54_common *priv);
+int p54_scan(struct p54_common *priv, u16 mode, u16 dwell);
+
+/* MAC */
+int p54_sta_unlock(struct p54_common *priv, u8 *addr);
+int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set);
+int p54_setup_mac(struct p54_common *priv);
+int p54_set_ps(struct p54_common *priv);
+int p54_fetch_statistics(struct p54_common *priv);
+
+/* e/v DCF setup */
+int p54_set_edcf(struct p54_common *priv);
+
+/* cryptographic engine */
+int p54_upload_key(struct p54_common *priv, u8 algo, int slot,
+		   u8 idx, u8 len, u8 *addr, u8* key);
+
+/* eeprom */
+int p54_download_eeprom(struct p54_common *priv, void *buf,
+			u16 offset, u16 len);
+
+/* utility */
+u8 *p54_find_ie(struct sk_buff *skb, u8 ie);
+
+#endif /* LMAC_H */
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
new file mode 100644
index 0000000..4d486bf
--- /dev/null
+++ b/drivers/net/wireless/p54/main.c
@@ -0,0 +1,648 @@
+/*
+ * mac80211 glue code for mac80211 Prism54 drivers
+ *
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * - stlc45xx driver
+ *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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/firmware.h>
+#include <linux/etherdevice.h>
+
+#include <net/mac80211.h>
+
+#include "p54.h"
+#include "lmac.h"
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
+MODULE_DESCRIPTION("Softmac Prism54 common code");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("prism54common");
+
+static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
+			      enum sta_notify_cmd notify_cmd,
+			      struct ieee80211_sta *sta)
+{
+	struct p54_common *priv = dev->priv;
+	switch (notify_cmd) {
+	case STA_NOTIFY_ADD:
+	case STA_NOTIFY_REMOVE:
+		/*
+		 * Notify the firmware that we don't want or we don't
+		 * need to buffer frames for this station anymore.
+		 */
+
+		p54_sta_unlock(priv, sta->addr);
+		break;
+	case STA_NOTIFY_AWAKE:
+		/* update the firmware's filter table */
+		p54_sta_unlock(priv, sta->addr);
+		break;
+	default:
+		break;
+	}
+}
+
+static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
+			bool set)
+{
+	struct p54_common *priv = dev->priv;
+
+	return p54_update_beacon_tim(priv, sta->aid, set);
+}
+
+u8 *p54_find_ie(struct sk_buff *skb, u8 ie)
+{
+	struct ieee80211_mgmt *mgmt = (void *)skb->data;
+	u8 *pos, *end;
+
+	if (skb->len <= sizeof(mgmt))
+		return NULL;
+
+	pos = (u8 *)mgmt->u.beacon.variable;
+	end = skb->data + skb->len;
+	while (pos < end) {
+		if (pos + 2 + pos[1] > end)
+			return NULL;
+
+		if (pos[0] == ie)
+			return pos;
+
+		pos += 2 + pos[1];
+	}
+	return NULL;
+}
+
+static int p54_beacon_format_ie_tim(struct sk_buff *skb)
+{
+	/*
+	 * the good excuse for this mess is ... the firmware.
+	 * The dummy TIM MUST be at the end of the beacon frame,
+	 * because it'll be overwritten!
+	 */
+	u8 *tim;
+	u8 dtim_len;
+	u8 dtim_period;
+	u8 *next;
+
+	tim = p54_find_ie(skb, WLAN_EID_TIM);
+	if (!tim)
+		return 0;
+
+	dtim_len = tim[1];
+	dtim_period = tim[3];
+	next = tim + 2 + dtim_len;
+
+	if (dtim_len < 3)
+		return -EINVAL;
+
+	memmove(tim, next, skb_tail_pointer(skb) - next);
+	tim = skb_tail_pointer(skb) - (dtim_len + 2);
+
+	/* add the dummy at the end */
+	tim[0] = WLAN_EID_TIM;
+	tim[1] = 3;
+	tim[2] = 0;
+	tim[3] = dtim_period;
+	tim[4] = 0;
+
+	if (dtim_len > 3)
+		skb_trim(skb, skb->len - (dtim_len - 3));
+
+	return 0;
+}
+
+static int p54_beacon_update(struct p54_common *priv,
+			struct ieee80211_vif *vif)
+{
+	struct sk_buff *beacon;
+	int ret;
+
+	beacon = ieee80211_beacon_get(priv->hw, vif);
+	if (!beacon)
+		return -ENOMEM;
+	ret = p54_beacon_format_ie_tim(beacon);
+	if (ret)
+		return ret;
+
+	/*
+	 * During operation, the firmware takes care of beaconing.
+	 * The driver only needs to upload a new beacon template, once
+	 * the template was changed by the stack or userspace.
+	 *
+	 * LMAC API 3.2.2 also specifies that the driver does not need
+	 * to cancel the old beacon template by hand, instead the firmware
+	 * will release the previous one through the feedback mechanism.
+	 */
+	WARN_ON(p54_tx_80211(priv->hw, beacon));
+	priv->tsf_high32 = 0;
+	priv->tsf_low32 = 0;
+
+	return 0;
+}
+
+static int p54_start(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+	int err;
+
+	mutex_lock(&priv->conf_mutex);
+	err = priv->open(dev);
+	if (err)
+		goto out;
+	P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
+	P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
+	P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
+	P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
+	err = p54_set_edcf(priv);
+	if (err)
+		goto out;
+
+	memset(priv->bssid, ~0, ETH_ALEN);
+	priv->mode = NL80211_IFTYPE_MONITOR;
+	err = p54_setup_mac(priv);
+	if (err) {
+		priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+		goto out;
+	}
+
+	ieee80211_queue_delayed_work(dev, &priv->work, 0);
+
+	priv->softled_state = 0;
+	err = p54_set_leds(priv);
+
+out:
+	mutex_unlock(&priv->conf_mutex);
+	return err;
+}
+
+static void p54_stop(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+	int i;
+
+	mutex_lock(&priv->conf_mutex);
+	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+	priv->softled_state = 0;
+	p54_set_leds(priv);
+
+	cancel_delayed_work_sync(&priv->work);
+
+	priv->stop(dev);
+	skb_queue_purge(&priv->tx_pending);
+	skb_queue_purge(&priv->tx_queue);
+	for (i = 0; i < P54_QUEUE_NUM; i++) {
+		priv->tx_stats[i].count = 0;
+		priv->tx_stats[i].len = 0;
+	}
+
+	priv->beacon_req_id = cpu_to_le32(0);
+	priv->tsf_high32 = priv->tsf_low32 = 0;
+	mutex_unlock(&priv->conf_mutex);
+}
+
+static int p54_add_interface(struct ieee80211_hw *dev,
+			     struct ieee80211_if_init_conf *conf)
+{
+	struct p54_common *priv = dev->priv;
+
+	mutex_lock(&priv->conf_mutex);
+	if (priv->mode != NL80211_IFTYPE_MONITOR) {
+		mutex_unlock(&priv->conf_mutex);
+		return -EOPNOTSUPP;
+	}
+
+	priv->vif = conf->vif;
+
+	switch (conf->type) {
+	case NL80211_IFTYPE_STATION:
+	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
+		priv->mode = conf->type;
+		break;
+	default:
+		mutex_unlock(&priv->conf_mutex);
+		return -EOPNOTSUPP;
+	}
+
+	memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+	p54_setup_mac(priv);
+	mutex_unlock(&priv->conf_mutex);
+	return 0;
+}
+
+static void p54_remove_interface(struct ieee80211_hw *dev,
+				 struct ieee80211_if_init_conf *conf)
+{
+	struct p54_common *priv = dev->priv;
+
+	mutex_lock(&priv->conf_mutex);
+	priv->vif = NULL;
+
+	/*
+	 * LMAC API 3.2.2 states that any active beacon template must be
+	 * canceled by the driver before attempting a mode transition.
+	 */
+	if (le32_to_cpu(priv->beacon_req_id) != 0) {
+		p54_tx_cancel(priv, priv->beacon_req_id);
+		wait_for_completion_interruptible_timeout(&priv->beacon_comp, HZ);
+	}
+	priv->mode = NL80211_IFTYPE_MONITOR;
+	memset(priv->mac_addr, 0, ETH_ALEN);
+	memset(priv->bssid, 0, ETH_ALEN);
+	p54_setup_mac(priv);
+	mutex_unlock(&priv->conf_mutex);
+}
+
+static int p54_config(struct ieee80211_hw *dev, u32 changed)
+{
+	int ret = 0;
+	struct p54_common *priv = dev->priv;
+	struct ieee80211_conf *conf = &dev->conf;
+
+	mutex_lock(&priv->conf_mutex);
+	if (changed & IEEE80211_CONF_CHANGE_POWER)
+		priv->output_power = conf->power_level << 2;
+	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+		ret = p54_scan(priv, P54_SCAN_EXIT, 0);
+		if (ret)
+			goto out;
+	}
+	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		ret = p54_set_ps(priv);
+		if (ret)
+			goto out;
+	}
+	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		ret = p54_setup_mac(priv);
+		if (ret)
+			goto out;
+	}
+
+out:
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
+}
+
+static void p54_configure_filter(struct ieee80211_hw *dev,
+				 unsigned int changed_flags,
+				 unsigned int *total_flags,
+				 u64 multicast)
+{
+	struct p54_common *priv = dev->priv;
+
+	*total_flags &= FIF_PROMISC_IN_BSS |
+			FIF_OTHER_BSS;
+
+	priv->filter_flags = *total_flags;
+
+	if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
+		p54_setup_mac(priv);
+}
+
+static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
+		       const struct ieee80211_tx_queue_params *params)
+{
+	struct p54_common *priv = dev->priv;
+	int ret;
+
+	mutex_lock(&priv->conf_mutex);
+	if (queue < dev->queues) {
+		P54_SET_QUEUE(priv->qos_params[queue], params->aifs,
+			params->cw_min, params->cw_max, params->txop);
+		ret = p54_set_edcf(priv);
+	} else
+		ret = -EINVAL;
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
+}
+
+static void p54_work(struct work_struct *work)
+{
+	struct p54_common *priv = container_of(work, struct p54_common,
+					       work.work);
+
+	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
+		return ;
+
+	/*
+	 * TODO: walk through tx_queue and do the following tasks
+	 * 	1. initiate bursts.
+	 *      2. cancel stuck frames / reset the device if necessary.
+	 */
+
+	p54_fetch_statistics(priv);
+}
+
+static int p54_get_stats(struct ieee80211_hw *dev,
+			 struct ieee80211_low_level_stats *stats)
+{
+	struct p54_common *priv = dev->priv;
+
+	memcpy(stats, &priv->stats, sizeof(*stats));
+	return 0;
+}
+
+static int p54_get_tx_stats(struct ieee80211_hw *dev,
+			    struct ieee80211_tx_queue_stats *stats)
+{
+	struct p54_common *priv = dev->priv;
+
+	memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
+	       sizeof(stats[0]) * dev->queues);
+	return 0;
+}
+
+static void p54_bss_info_changed(struct ieee80211_hw *dev,
+				 struct ieee80211_vif *vif,
+				 struct ieee80211_bss_conf *info,
+				 u32 changed)
+{
+	struct p54_common *priv = dev->priv;
+
+	mutex_lock(&priv->conf_mutex);
+	if (changed & BSS_CHANGED_BSSID) {
+		memcpy(priv->bssid, info->bssid, ETH_ALEN);
+		p54_setup_mac(priv);
+	}
+
+	if (changed & BSS_CHANGED_BEACON) {
+		p54_scan(priv, P54_SCAN_EXIT, 0);
+		p54_setup_mac(priv);
+		p54_beacon_update(priv, vif);
+		p54_set_edcf(priv);
+	}
+
+	if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BEACON)) {
+		priv->use_short_slot = info->use_short_slot;
+		p54_set_edcf(priv);
+	}
+	if (changed & BSS_CHANGED_BASIC_RATES) {
+		if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
+			priv->basic_rate_mask = (info->basic_rates << 4);
+		else
+			priv->basic_rate_mask = info->basic_rates;
+		p54_setup_mac(priv);
+		if (priv->fw_var >= 0x500)
+			p54_scan(priv, P54_SCAN_EXIT, 0);
+	}
+	if (changed & BSS_CHANGED_ASSOC) {
+		if (info->assoc) {
+			priv->aid = info->aid;
+			priv->wakeup_timer = info->beacon_int *
+					     info->dtim_period * 5;
+			p54_setup_mac(priv);
+		} else {
+			priv->wakeup_timer = 500;
+			priv->aid = 0;
+		}
+	}
+
+	mutex_unlock(&priv->conf_mutex);
+}
+
+static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
+		       struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+		       struct ieee80211_key_conf *key)
+{
+	struct p54_common *priv = dev->priv;
+	int slot, ret = 0;
+	u8 algo = 0;
+	u8 *addr = NULL;
+
+	if (modparam_nohwcrypt)
+		return -EOPNOTSUPP;
+
+	mutex_lock(&priv->conf_mutex);
+	if (cmd == SET_KEY) {
+		switch (key->alg) {
+		case ALG_TKIP:
+			if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
+			      BR_DESC_PRIV_CAP_TKIP))) {
+				ret = -EOPNOTSUPP;
+				goto out_unlock;
+			}
+			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+			algo = P54_CRYPTO_TKIPMICHAEL;
+			break;
+		case ALG_WEP:
+			if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
+				ret = -EOPNOTSUPP;
+				goto out_unlock;
+			}
+			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+			algo = P54_CRYPTO_WEP;
+			break;
+		case ALG_CCMP:
+			if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
+				ret = -EOPNOTSUPP;
+				goto out_unlock;
+			}
+			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+			algo = P54_CRYPTO_AESCCMP;
+			break;
+		default:
+			ret = -EOPNOTSUPP;
+			goto out_unlock;
+		}
+		slot = bitmap_find_free_region(priv->used_rxkeys,
+					       priv->rx_keycache_size, 0);
+
+		if (slot < 0) {
+			/*
+			 * The device supports the choosen algorithm, but the
+			 * firmware does not provide enough key slots to store
+			 * all of them.
+			 * But encryption offload for outgoing frames is always
+			 * possible, so we just pretend that the upload was
+			 * successful and do the decryption in software.
+			 */
+
+			/* mark the key as invalid. */
+			key->hw_key_idx = 0xff;
+			goto out_unlock;
+		}
+	} else {
+		slot = key->hw_key_idx;
+
+		if (slot == 0xff) {
+			/* This key was not uploaded into the rx key cache. */
+
+			goto out_unlock;
+		}
+
+		bitmap_release_region(priv->used_rxkeys, slot, 0);
+		algo = 0;
+	}
+
+	if (sta)
+		addr = sta->addr;
+
+	ret = p54_upload_key(priv, algo, slot, key->keyidx,
+			     key->keylen, addr, key->key);
+	if (ret) {
+		bitmap_release_region(priv->used_rxkeys, slot, 0);
+		ret = -EOPNOTSUPP;
+		goto out_unlock;
+	}
+
+	key->hw_key_idx = slot;
+
+out_unlock:
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
+}
+
+static const struct ieee80211_ops p54_ops = {
+	.tx			= p54_tx_80211,
+	.start			= p54_start,
+	.stop			= p54_stop,
+	.add_interface		= p54_add_interface,
+	.remove_interface	= p54_remove_interface,
+	.set_tim		= p54_set_tim,
+	.sta_notify		= p54_sta_notify,
+	.set_key		= p54_set_key,
+	.config			= p54_config,
+	.bss_info_changed	= p54_bss_info_changed,
+	.configure_filter	= p54_configure_filter,
+	.conf_tx		= p54_conf_tx,
+	.get_stats		= p54_get_stats,
+	.get_tx_stats		= p54_get_tx_stats
+};
+
+struct ieee80211_hw *p54_init_common(size_t priv_data_len)
+{
+	struct ieee80211_hw *dev;
+	struct p54_common *priv;
+
+	dev = ieee80211_alloc_hw(priv_data_len, &p54_ops);
+	if (!dev)
+		return NULL;
+
+	priv = dev->priv;
+	priv->hw = dev;
+	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
+	priv->basic_rate_mask = 0x15f;
+	spin_lock_init(&priv->tx_stats_lock);
+	skb_queue_head_init(&priv->tx_queue);
+	skb_queue_head_init(&priv->tx_pending);
+	dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+		     IEEE80211_HW_SIGNAL_DBM |
+		     IEEE80211_HW_SUPPORTS_PS |
+		     IEEE80211_HW_PS_NULLFUNC_STACK |
+		     IEEE80211_HW_BEACON_FILTER |
+		     IEEE80211_HW_NOISE_DBM;
+
+	dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+				      BIT(NL80211_IFTYPE_ADHOC) |
+				      BIT(NL80211_IFTYPE_AP) |
+				      BIT(NL80211_IFTYPE_MESH_POINT);
+
+	dev->channel_change_time = 1000;	/* TODO: find actual value */
+	priv->beacon_req_id = cpu_to_le32(0);
+	priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
+	priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
+	priv->tx_stats[P54_QUEUE_MGMT].limit = 3;
+	priv->tx_stats[P54_QUEUE_CAB].limit = 3;
+	priv->tx_stats[P54_QUEUE_DATA].limit = 5;
+	dev->queues = 1;
+	priv->noise = -94;
+	/*
+	 * We support at most 8 tries no matter which rate they're at,
+	 * we cannot support max_rates * max_rate_tries as we set it
+	 * here, but setting it correctly to 4/2 or so would limit us
+	 * artificially if the RC algorithm wants just two rates, so
+	 * let's say 4/7, we'll redistribute it at TX time, see the
+	 * comments there.
+	 */
+	dev->max_rates = 4;
+	dev->max_rate_tries = 7;
+	dev->extra_tx_headroom = sizeof(struct p54_hdr) + 4 +
+				 sizeof(struct p54_tx_data);
+
+	/*
+	 * For now, disable PS by default because it affects
+	 * link stability significantly.
+	 */
+	dev->wiphy->ps_default = false;
+
+	mutex_init(&priv->conf_mutex);
+	mutex_init(&priv->eeprom_mutex);
+	init_completion(&priv->eeprom_comp);
+	init_completion(&priv->beacon_comp);
+	INIT_DELAYED_WORK(&priv->work, p54_work);
+
+	return dev;
+}
+EXPORT_SYMBOL_GPL(p54_init_common);
+
+int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
+{
+	struct p54_common *priv = dev->priv;
+	int err;
+
+	err = ieee80211_register_hw(dev);
+	if (err) {
+		dev_err(pdev, "Cannot register device (%d).\n", err);
+		return err;
+	}
+
+#ifdef CONFIG_P54_LEDS
+	err = p54_init_leds(priv);
+	if (err)
+		return err;
+#endif /* CONFIG_P54_LEDS */
+
+	dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
+	return 0;
+}
+EXPORT_SYMBOL_GPL(p54_register_common);
+
+void p54_free_common(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+	unsigned int i;
+
+	for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+		kfree(priv->band_table[i]);
+
+	kfree(priv->iq_autocal);
+	kfree(priv->output_limit);
+	kfree(priv->curve_data);
+	kfree(priv->used_rxkeys);
+	priv->iq_autocal = NULL;
+	priv->output_limit = NULL;
+	priv->curve_data = NULL;
+	priv->used_rxkeys = NULL;
+	ieee80211_free_hw(dev);
+}
+EXPORT_SYMBOL_GPL(p54_free_common);
+
+void p54_unregister_common(struct ieee80211_hw *dev)
+{
+	struct p54_common *priv = dev->priv;
+
+#ifdef CONFIG_P54_LEDS
+	p54_unregister_leds(priv);
+#endif /* CONFIG_P54_LEDS */
+
+	ieee80211_unregister_hw(dev);
+	mutex_destroy(&priv->conf_mutex);
+	mutex_destroy(&priv->eeprom_mutex);
+}
+EXPORT_SYMBOL_GPL(p54_unregister_common);
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index db3df94..1afc394 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -1,6 +1,3 @@
-#ifndef P54_H
-#define P54_H
-
 /*
  * Shared defines for all mac80211 Prism54 code
  *
@@ -14,39 +11,78 @@
  * published by the Free Software Foundation.
  */
 
+#ifndef P54_H
+#define P54_H
+
 #ifdef CONFIG_P54_LEDS
 #include <linux/leds.h>
 #endif /* CONFIG_P54_LEDS */
 
-enum p54_control_frame_types {
-	P54_CONTROL_TYPE_SETUP = 0,
-	P54_CONTROL_TYPE_SCAN,
-	P54_CONTROL_TYPE_TRAP,
-	P54_CONTROL_TYPE_DCFINIT,
-	P54_CONTROL_TYPE_RX_KEYCACHE,
-	P54_CONTROL_TYPE_TIM,
-	P54_CONTROL_TYPE_PSM,
-	P54_CONTROL_TYPE_TXCANCEL,
-	P54_CONTROL_TYPE_TXDONE,
-	P54_CONTROL_TYPE_BURST,
-	P54_CONTROL_TYPE_STAT_READBACK,
-	P54_CONTROL_TYPE_BBP,
-	P54_CONTROL_TYPE_EEPROM_READBACK,
-	P54_CONTROL_TYPE_LED,
-	P54_CONTROL_TYPE_GPIO,
-	P54_CONTROL_TYPE_TIMER,
-	P54_CONTROL_TYPE_MODULATION,
-	P54_CONTROL_TYPE_SYNTH_CONFIG,
-	P54_CONTROL_TYPE_DETECTOR_VALUE,
-	P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
-	P54_CONTROL_TYPE_CCE_QUIET,
-	P54_CONTROL_TYPE_PSM_STA_UNLOCK,
-	P54_CONTROL_TYPE_PCS,
-	P54_CONTROL_TYPE_BT_BALANCER = 28,
-	P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE = 30,
-	P54_CONTROL_TYPE_ARPTABLE = 31,
-	P54_CONTROL_TYPE_BT_OPTIONS = 35
-};
+#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
+
+#define BR_CODE_MIN			0x80000000
+#define BR_CODE_COMPONENT_ID		0x80000001
+#define BR_CODE_COMPONENT_VERSION	0x80000002
+#define BR_CODE_DEPENDENT_IF		0x80000003
+#define BR_CODE_EXPOSED_IF		0x80000004
+#define BR_CODE_DESCR			0x80000101
+#define BR_CODE_MAX			0x8FFFFFFF
+#define BR_CODE_END_OF_BRA		0xFF0000FF
+#define LEGACY_BR_CODE_END_OF_BRA	0xFFFFFFFF
+
+struct bootrec {
+	__le32 code;
+	__le32 len;
+	u32 data[10];
+} __packed;
+
+/* Interface role definitions */
+#define BR_INTERFACE_ROLE_SERVER	0x0000
+#define BR_INTERFACE_ROLE_CLIENT	0x8000
+
+#define BR_DESC_PRIV_CAP_WEP		BIT(0)
+#define BR_DESC_PRIV_CAP_TKIP		BIT(1)
+#define BR_DESC_PRIV_CAP_MICHAEL	BIT(2)
+#define BR_DESC_PRIV_CAP_CCX_CP		BIT(3)
+#define BR_DESC_PRIV_CAP_CCX_MIC	BIT(4)
+#define BR_DESC_PRIV_CAP_AESCCMP	BIT(5)
+
+struct bootrec_desc {
+	__le16 modes;
+	__le16 flags;
+	__le32 rx_start;
+	__le32 rx_end;
+	u8 headroom;
+	u8 tailroom;
+	u8 tx_queues;
+	u8 tx_depth;
+	u8 privacy_caps;
+	u8 rx_keycache_size;
+	u8 time_size;
+	u8 padding;
+	u8 rates[16];
+	u8 padding2[4];
+	__le16 rx_mtu;
+} __packed;
+
+#define FW_FMAC 0x464d4143
+#define FW_LM86 0x4c4d3836
+#define FW_LM87 0x4c4d3837
+#define FW_LM20 0x4c4d3230
+
+struct bootrec_comp_id {
+	__le32 fw_variant;
+} __packed;
+
+struct bootrec_comp_ver {
+	char fw_version[24];
+} __packed;
+
+struct bootrec_end {
+	__le16 crc;
+	u8 padding[2];
+	u8 md5[16];
+} __packed;
 
 /* provide 16 bytes for the transport back-end */
 #define P54_TX_INFO_DATA_SIZE		16
@@ -55,34 +91,30 @@ enum p54_control_frame_types {
 struct p54_tx_info {
 	u32 start_addr;
 	u32 end_addr;
-	void *data[P54_TX_INFO_DATA_SIZE / sizeof(void *)];
+	union {
+		void *data[P54_TX_INFO_DATA_SIZE / sizeof(void *)];
+		struct {
+			u32 extra_len;
+		};
+	};
 };
 
 #define P54_MAX_CTRL_FRAME_LEN		0x1000
 
-#define P54_HDR_FLAG_CONTROL		BIT(15)
-#define P54_HDR_FLAG_CONTROL_OPSET	(BIT(15) + BIT(0))
-
-struct p54_hdr {
-	__le16 flags;
-	__le16 len;
-	__le32 req_id;
-	__le16 type;	/* enum p54_control_frame_types */
-	u8 rts_tries;
-	u8 tries;
-	u8 data[0];
-} __attribute__ ((packed));
-
-#define FREE_AFTER_TX(skb)						\
-	((((struct p54_hdr *) ((struct sk_buff *) skb)->data)->		\
-	flags) == cpu_to_le16(P54_HDR_FLAG_CONTROL_OPSET))
+#define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, _txop)	\
+do {								\
+	queue.aifs = cpu_to_le16(ai_fs);			\
+	queue.cwmin = cpu_to_le16(cw_min);			\
+	queue.cwmax = cpu_to_le16(cw_max);			\
+	queue.txop = cpu_to_le16(_txop);			\
+} while (0)
 
 struct p54_edcf_queue_param {
 	__le16 aifs;
 	__le16 cwmin;
 	__le16 cwmax;
 	__le16 txop;
-} __attribute__ ((packed));
+} __packed;
 
 struct p54_rssi_linear_approximation {
 	s16 mul;
@@ -101,13 +133,6 @@ struct p54_cal_database {
 
 #define EEPROM_READBACK_LEN 0x3fc
 
-#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
-
-#define FW_FMAC 0x464d4143
-#define FW_LM86 0x4c4d3836
-#define FW_LM87 0x4c4d3837
-#define FW_LM20 0x4c4d3230
-
 enum fw_state {
 	FW_STATE_OFF,
 	FW_STATE_BOOTING,
@@ -138,6 +163,7 @@ struct p54_common {
 	void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb);
 	int (*open)(struct ieee80211_hw *dev);
 	void (*stop)(struct ieee80211_hw *dev);
+	struct sk_buff_head tx_pending;
 	struct sk_buff_head tx_queue;
 	struct mutex conf_mutex;
 
@@ -156,6 +182,7 @@ struct p54_common {
 
 	/* (e)DCF / QOS state */
 	bool use_short_slot;
+	spinlock_t tx_stats_lock;
 	struct ieee80211_tx_queue_stats tx_stats[8];
 	struct p54_edcf_queue_param qos_params[8];
 
@@ -171,6 +198,7 @@ struct p54_common {
 	struct p54_cal_database *curve_data;
 	struct p54_cal_database *output_limit;
 	struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
+	struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS];
 
 	/* BBP/MAC state */
 	u8 mac_addr[ETH_ALEN];
@@ -181,7 +209,9 @@ struct p54_common {
 	u32 tsf_low32, tsf_high32;
 	u32 basic_rate_mask;
 	u16 aid;
-	struct sk_buff *cached_beacon;
+	bool powersave_override;
+	__le32 beacon_req_id;
+	struct completion beacon_comp;
 
 	/* cryptographic engine information */
 	u8 privacy_caps;
@@ -202,15 +232,20 @@ struct p54_common {
 	/* eeprom handling */
 	void *eeprom;
 	struct completion eeprom_comp;
+	struct mutex eeprom_mutex;
 };
 
+/* interfaces for the drivers */
 int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
 void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb);
 int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
 int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len);
 int p54_read_eeprom(struct ieee80211_hw *dev);
+
 struct ieee80211_hw *p54_init_common(size_t priv_data_len);
 int p54_register_common(struct ieee80211_hw *dev, struct device *pdev);
 void p54_free_common(struct ieee80211_hw *dev);
 
+void p54_unregister_common(struct ieee80211_hw *dev);
+
 #endif /* P54_H */
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
deleted file mode 100644
index 22ca122..0000000
--- a/drivers/net/wireless/p54/p54common.c
+++ /dev/null
@@ -1,2688 +0,0 @@
-/*
- * Common code for mac80211 Prism54 drivers
- *
- * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
- * Copyright (c) 2007, Christian Lamparter <chunkeey@web.de>
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * Based on:
- * - the islsm (softmac prism54) driver, which is:
- *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
- * - stlc45xx driver
- *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
- *
- * 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/firmware.h>
-#include <linux/etherdevice.h>
-
-#include <net/mac80211.h>
-#ifdef CONFIG_P54_LEDS
-#include <linux/leds.h>
-#endif /* CONFIG_P54_LEDS */
-
-#include "p54.h"
-#include "p54common.h"
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
-MODULE_DESCRIPTION("Softmac Prism54 common code");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("prism54common");
-
-static struct ieee80211_rate p54_bgrates[] = {
-	{ .bitrate = 10, .hw_value = 0, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-	{ .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-	{ .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-	{ .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-	{ .bitrate = 60, .hw_value = 4, },
-	{ .bitrate = 90, .hw_value = 5, },
-	{ .bitrate = 120, .hw_value = 6, },
-	{ .bitrate = 180, .hw_value = 7, },
-	{ .bitrate = 240, .hw_value = 8, },
-	{ .bitrate = 360, .hw_value = 9, },
-	{ .bitrate = 480, .hw_value = 10, },
-	{ .bitrate = 540, .hw_value = 11, },
-};
-
-static struct ieee80211_channel p54_bgchannels[] = {
-	{ .center_freq = 2412, .hw_value = 1, },
-	{ .center_freq = 2417, .hw_value = 2, },
-	{ .center_freq = 2422, .hw_value = 3, },
-	{ .center_freq = 2427, .hw_value = 4, },
-	{ .center_freq = 2432, .hw_value = 5, },
-	{ .center_freq = 2437, .hw_value = 6, },
-	{ .center_freq = 2442, .hw_value = 7, },
-	{ .center_freq = 2447, .hw_value = 8, },
-	{ .center_freq = 2452, .hw_value = 9, },
-	{ .center_freq = 2457, .hw_value = 10, },
-	{ .center_freq = 2462, .hw_value = 11, },
-	{ .center_freq = 2467, .hw_value = 12, },
-	{ .center_freq = 2472, .hw_value = 13, },
-	{ .center_freq = 2484, .hw_value = 14, },
-};
-
-static struct ieee80211_supported_band band_2GHz = {
-	.channels = p54_bgchannels,
-	.n_channels = ARRAY_SIZE(p54_bgchannels),
-	.bitrates = p54_bgrates,
-	.n_bitrates = ARRAY_SIZE(p54_bgrates),
-};
-
-static struct ieee80211_rate p54_arates[] = {
-	{ .bitrate = 60, .hw_value = 4, },
-	{ .bitrate = 90, .hw_value = 5, },
-	{ .bitrate = 120, .hw_value = 6, },
-	{ .bitrate = 180, .hw_value = 7, },
-	{ .bitrate = 240, .hw_value = 8, },
-	{ .bitrate = 360, .hw_value = 9, },
-	{ .bitrate = 480, .hw_value = 10, },
-	{ .bitrate = 540, .hw_value = 11, },
-};
-
-static struct ieee80211_channel p54_achannels[] = {
-	{ .center_freq = 4920 },
-	{ .center_freq = 4940 },
-	{ .center_freq = 4960 },
-	{ .center_freq = 4980 },
-	{ .center_freq = 5040 },
-	{ .center_freq = 5060 },
-	{ .center_freq = 5080 },
-	{ .center_freq = 5170 },
-	{ .center_freq = 5180 },
-	{ .center_freq = 5190 },
-	{ .center_freq = 5200 },
-	{ .center_freq = 5210 },
-	{ .center_freq = 5220 },
-	{ .center_freq = 5230 },
-	{ .center_freq = 5240 },
-	{ .center_freq = 5260 },
-	{ .center_freq = 5280 },
-	{ .center_freq = 5300 },
-	{ .center_freq = 5320 },
-	{ .center_freq = 5500 },
-	{ .center_freq = 5520 },
-	{ .center_freq = 5540 },
-	{ .center_freq = 5560 },
-	{ .center_freq = 5580 },
-	{ .center_freq = 5600 },
-	{ .center_freq = 5620 },
-	{ .center_freq = 5640 },
-	{ .center_freq = 5660 },
-	{ .center_freq = 5680 },
-	{ .center_freq = 5700 },
-	{ .center_freq = 5745 },
-	{ .center_freq = 5765 },
-	{ .center_freq = 5785 },
-	{ .center_freq = 5805 },
-	{ .center_freq = 5825 },
-};
-
-static struct ieee80211_supported_band band_5GHz = {
-	.channels = p54_achannels,
-	.n_channels = ARRAY_SIZE(p54_achannels),
-	.bitrates = p54_arates,
-	.n_bitrates = ARRAY_SIZE(p54_arates),
-};
-
-int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
-{
-	struct p54_common *priv = dev->priv;
-	struct bootrec_exp_if *exp_if;
-	struct bootrec *bootrec;
-	u32 *data = (u32 *)fw->data;
-	u32 *end_data = (u32 *)fw->data + (fw->size >> 2);
-	u8 *fw_version = NULL;
-	size_t len;
-	int i;
-	int maxlen;
-
-	if (priv->rx_start)
-		return 0;
-
-	while (data < end_data && *data)
-		data++;
-
-	while (data < end_data && !*data)
-		data++;
-
-	bootrec = (struct bootrec *) data;
-
-	while (bootrec->data <= end_data &&
-	       (bootrec->data + (len = le32_to_cpu(bootrec->len))) <= end_data) {
-		u32 code = le32_to_cpu(bootrec->code);
-		switch (code) {
-		case BR_CODE_COMPONENT_ID:
-			priv->fw_interface = be32_to_cpup((__be32 *)
-					     bootrec->data);
-			switch (priv->fw_interface) {
-			case FW_LM86:
-			case FW_LM20:
-			case FW_LM87: {
-				char *iftype = (char *)bootrec->data;
-				printk(KERN_INFO "%s: p54 detected a LM%c%c "
-						 "firmware\n",
-					wiphy_name(dev->wiphy),
-					iftype[2], iftype[3]);
-				break;
-				}
-			case FW_FMAC:
-			default:
-				printk(KERN_ERR "%s: unsupported firmware\n",
-					wiphy_name(dev->wiphy));
-				return -ENODEV;
-			}
-			break;
-		case BR_CODE_COMPONENT_VERSION:
-			/* 24 bytes should be enough for all firmwares */
-			if (strnlen((unsigned char*)bootrec->data, 24) < 24)
-				fw_version = (unsigned char*)bootrec->data;
-			break;
-		case BR_CODE_DESCR: {
-			struct bootrec_desc *desc =
-				(struct bootrec_desc *)bootrec->data;
-			priv->rx_start = le32_to_cpu(desc->rx_start);
-			/* FIXME add sanity checking */
-			priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500;
-			priv->headroom = desc->headroom;
-			priv->tailroom = desc->tailroom;
-			priv->privacy_caps = desc->privacy_caps;
-			priv->rx_keycache_size = desc->rx_keycache_size;
-			if (le32_to_cpu(bootrec->len) == 11)
-				priv->rx_mtu = le16_to_cpu(desc->rx_mtu);
-			else
-				priv->rx_mtu = (size_t)
-					0x620 - priv->tx_hdr_len;
-			maxlen = priv->tx_hdr_len + /* USB devices */
-				 sizeof(struct p54_rx_data) +
-				 4 + /* rx alignment */
-				 IEEE80211_MAX_FRAG_THRESHOLD;
-			if (priv->rx_mtu > maxlen && PAGE_SIZE == 4096) {
-				printk(KERN_INFO "p54: rx_mtu reduced from %d "
-					         "to %d\n", priv->rx_mtu,
-						 maxlen);
-				priv->rx_mtu = maxlen;
-			}
-			break;
-			}
-		case BR_CODE_EXPOSED_IF:
-			exp_if = (struct bootrec_exp_if *) bootrec->data;
-			for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
-				if (exp_if[i].if_id == cpu_to_le16(0x1a))
-					priv->fw_var = le16_to_cpu(exp_if[i].variant);
-			break;
-		case BR_CODE_DEPENDENT_IF:
-			break;
-		case BR_CODE_END_OF_BRA:
-		case LEGACY_BR_CODE_END_OF_BRA:
-			end_data = NULL;
-			break;
-		default:
-			break;
-		}
-		bootrec = (struct bootrec *)&bootrec->data[len];
-	}
-
-	if (fw_version)
-		printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n",
-			wiphy_name(dev->wiphy), fw_version,
-			priv->fw_var >> 8, priv->fw_var & 0xff);
-
-	if (priv->fw_var < 0x500)
-		printk(KERN_INFO "%s: you are using an obsolete firmware. "
-		       "visit http://wireless.kernel.org/en/users/Drivers/p54 "
-		       "and grab one for \"kernel >= 2.6.28\"!\n",
-			wiphy_name(dev->wiphy));
-
-	if (priv->fw_var >= 0x300) {
-		/* Firmware supports QoS, use it! */
-		priv->tx_stats[P54_QUEUE_AC_VO].limit = 3;
-		priv->tx_stats[P54_QUEUE_AC_VI].limit = 4;
-		priv->tx_stats[P54_QUEUE_AC_BE].limit = 3;
-		priv->tx_stats[P54_QUEUE_AC_BK].limit = 2;
-		dev->queues = P54_QUEUE_AC_NUM;
-	}
-
-	if (!modparam_nohwcrypt) {
-		printk(KERN_INFO "%s: cryptographic accelerator "
-				 "WEP:%s, TKIP:%s, CCMP:%s\n",
-			wiphy_name(dev->wiphy),
-			(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" :
-			"no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP |
-			 BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no",
-			(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
-			"YES" : "no");
-
-		if (priv->rx_keycache_size) {
-			/*
-			 * NOTE:
-			 *
-			 * The firmware provides at most 255 (0 - 254) slots
-			 * for keys which are then used to offload decryption.
-			 * As a result the 255 entry (aka 0xff) can be used
-			 * safely by the driver to mark keys that didn't fit
-			 * into the full cache. This trick saves us from
-			 * keeping a extra list for uploaded keys.
-			 */
-
-			priv->used_rxkeys = kzalloc(BITS_TO_LONGS(
-				priv->rx_keycache_size), GFP_KERNEL);
-
-			if (!priv->used_rxkeys)
-				return -ENOMEM;
-		}
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(p54_parse_firmware);
-
-static int p54_convert_rev0(struct ieee80211_hw *dev,
-			    struct pda_pa_curve_data *curve_data)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_pa_curve_data_sample *dst;
-	struct pda_pa_curve_data_sample_rev0 *src;
-	size_t cd_len = sizeof(*curve_data) +
-		(curve_data->points_per_channel*sizeof(*dst) + 2) *
-		 curve_data->channels;
-	unsigned int i, j;
-	void *source, *target;
-
-	priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
-				   GFP_KERNEL);
-	if (!priv->curve_data)
-		return -ENOMEM;
-
-	priv->curve_data->entries = curve_data->channels;
-	priv->curve_data->entry_size = sizeof(__le16) +
-		sizeof(*dst) * curve_data->points_per_channel;
-	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
-	priv->curve_data->len = cd_len;
-	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
-	source = curve_data->data;
-	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
-	for (i = 0; i < curve_data->channels; i++) {
-		__le16 *freq = source;
-		source += sizeof(__le16);
-		*((__le16 *)target) = *freq;
-		target += sizeof(__le16);
-		for (j = 0; j < curve_data->points_per_channel; j++) {
-			dst = target;
-			src = source;
-
-			dst->rf_power = src->rf_power;
-			dst->pa_detector = src->pa_detector;
-			dst->data_64qam = src->pcv;
-			/* "invent" the points for the other modulations */
-#define SUB(x,y) (u8)((x) - (y)) > (x) ? 0 : (x) - (y)
-			dst->data_16qam = SUB(src->pcv, 12);
-			dst->data_qpsk = SUB(dst->data_16qam, 12);
-			dst->data_bpsk = SUB(dst->data_qpsk, 12);
-			dst->data_barker = SUB(dst->data_bpsk, 14);
-#undef SUB
-			target += sizeof(*dst);
-			source += sizeof(*src);
-		}
-	}
-
-	return 0;
-}
-
-static int p54_convert_rev1(struct ieee80211_hw *dev,
-			    struct pda_pa_curve_data *curve_data)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_pa_curve_data_sample *dst;
-	struct pda_pa_curve_data_sample_rev1 *src;
-	size_t cd_len = sizeof(*curve_data) +
-		(curve_data->points_per_channel*sizeof(*dst) + 2) *
-		 curve_data->channels;
-	unsigned int i, j;
-	void *source, *target;
-
-	priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
-				   GFP_KERNEL);
-	if (!priv->curve_data)
-		return -ENOMEM;
-
-	priv->curve_data->entries = curve_data->channels;
-	priv->curve_data->entry_size = sizeof(__le16) +
-		sizeof(*dst) * curve_data->points_per_channel;
-	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
-	priv->curve_data->len = cd_len;
-	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
-	source = curve_data->data;
-	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
-	for (i = 0; i < curve_data->channels; i++) {
-		__le16 *freq = source;
-		source += sizeof(__le16);
-		*((__le16 *)target) = *freq;
-		target += sizeof(__le16);
-		for (j = 0; j < curve_data->points_per_channel; j++) {
-			memcpy(target, source, sizeof(*src));
-
-			target += sizeof(*dst);
-			source += sizeof(*src);
-		}
-		source++;
-	}
-
-	return 0;
-}
-
-static const char *p54_rf_chips[] = { "NULL", "Duette3", "Duette2",
-                              "Frisbee", "Xbow", "Longbow", "NULL", "NULL" };
-static int p54_init_xbow_synth(struct ieee80211_hw *dev);
-
-static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
-			     u16 type)
-{
-	struct p54_common *priv = dev->priv;
-	int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0;
-	int entry_size = sizeof(struct pda_rssi_cal_entry) + offset;
-	int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
-	int i;
-
-	if (len != (entry_size * num_entries)) {
-		printk(KERN_ERR "%s: unknown rssi calibration data packing "
-				 " type:(%x) len:%d.\n",
-		       wiphy_name(dev->wiphy), type, len);
-
-		print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
-				     data, len);
-
-		printk(KERN_ERR "%s: please report this issue.\n",
-			wiphy_name(dev->wiphy));
-		return;
-	}
-
-	for (i = 0; i < num_entries; i++) {
-		struct pda_rssi_cal_entry *cal = data +
-						 (offset + i * entry_size);
-		priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul);
-		priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add);
-	}
-}
-
-static void p54_parse_default_country(struct ieee80211_hw *dev,
-				      void *data, int len)
-{
-	struct pda_country *country;
-
-	if (len != sizeof(*country)) {
-		printk(KERN_ERR "%s: found possible invalid default country "
-				"eeprom entry. (entry size: %d)\n",
-		       wiphy_name(dev->wiphy), len);
-
-		print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
-				     data, len);
-
-		printk(KERN_ERR "%s: please report this issue.\n",
-			wiphy_name(dev->wiphy));
-		return;
-	}
-
-	country = (struct pda_country *) data;
-	if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
-		regulatory_hint(dev->wiphy, country->alpha2);
-	else {
-		/* TODO:
-		 * write a shared/common function that converts
-		 * "Regulatory domain codes" (802.11-2007 14.8.2.2)
-		 * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
-		 */
-	}
-}
-
-static int p54_convert_output_limits(struct ieee80211_hw *dev,
-				     u8 *data, size_t len)
-{
-	struct p54_common *priv = dev->priv;
-
-	if (len < 2)
-		return -EINVAL;
-
-	if (data[0] != 0) {
-		printk(KERN_ERR "%s: unknown output power db revision:%x\n",
-		       wiphy_name(dev->wiphy), data[0]);
-		return -EINVAL;
-	}
-
-	if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
-		return -EINVAL;
-
-	priv->output_limit = kmalloc(data[1] *
-		sizeof(struct pda_channel_output_limit) +
-		sizeof(*priv->output_limit), GFP_KERNEL);
-
-	if (!priv->output_limit)
-		return -ENOMEM;
-
-	priv->output_limit->offset = 0;
-	priv->output_limit->entries = data[1];
-	priv->output_limit->entry_size =
-		sizeof(struct pda_channel_output_limit);
-	priv->output_limit->len = priv->output_limit->entry_size *
-				  priv->output_limit->entries +
-				  priv->output_limit->offset;
-
-	memcpy(priv->output_limit->data, &data[2],
-	       data[1] * sizeof(struct pda_channel_output_limit));
-
-	return 0;
-}
-
-static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
-					       size_t total_len)
-{
-	struct p54_cal_database *dst;
-	size_t payload_len, entries, entry_size, offset;
-
-	payload_len = le16_to_cpu(src->len);
-	entries = le16_to_cpu(src->entries);
-	entry_size = le16_to_cpu(src->entry_size);
-	offset = le16_to_cpu(src->offset);
-	if (((entries * entry_size + offset) != payload_len) ||
-	     (payload_len + sizeof(*src) != total_len))
-		return NULL;
-
-	dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
-	if (!dst)
-		return NULL;
-
-	dst->entries = entries;
-	dst->entry_size = entry_size;
-	dst->offset = offset;
-	dst->len = payload_len;
-
-	memcpy(dst->data, src->data, payload_len);
-	return dst;
-}
-
-int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
-{
-	struct p54_common *priv = dev->priv;
-	struct eeprom_pda_wrap *wrap = NULL;
-	struct pda_entry *entry;
-	unsigned int data_len, entry_len;
-	void *tmp;
-	int err;
-	u8 *end = (u8 *)eeprom + len;
-	u16 synth = 0;
-
-	wrap = (struct eeprom_pda_wrap *) eeprom;
-	entry = (void *)wrap->data + le16_to_cpu(wrap->len);
-
-	/* verify that at least the entry length/code fits */
-	while ((u8 *)entry <= end - sizeof(*entry)) {
-		entry_len = le16_to_cpu(entry->len);
-		data_len = ((entry_len - 1) << 1);
-
-		/* abort if entry exceeds whole structure */
-		if ((u8 *)entry + sizeof(*entry) + data_len > end)
-			break;
-
-		switch (le16_to_cpu(entry->code)) {
-		case PDR_MAC_ADDRESS:
-			if (data_len != ETH_ALEN)
-				break;
-			SET_IEEE80211_PERM_ADDR(dev, entry->data);
-			break;
-		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
-			if (priv->output_limit)
-				break;
-			err = p54_convert_output_limits(dev, entry->data,
-							data_len);
-			if (err)
-				goto err;
-			break;
-		case PDR_PRISM_PA_CAL_CURVE_DATA: {
-			struct pda_pa_curve_data *curve_data =
-				(struct pda_pa_curve_data *)entry->data;
-			if (data_len < sizeof(*curve_data)) {
-				err = -EINVAL;
-				goto err;
-			}
-
-			switch (curve_data->cal_method_rev) {
-			case 0:
-				err = p54_convert_rev0(dev, curve_data);
-				break;
-			case 1:
-				err = p54_convert_rev1(dev, curve_data);
-				break;
-			default:
-				printk(KERN_ERR "%s: unknown curve data "
-						"revision %d\n",
-						wiphy_name(dev->wiphy),
-						curve_data->cal_method_rev);
-				err = -ENODEV;
-				break;
-			}
-			if (err)
-				goto err;
-			}
-			break;
-		case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
-			priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
-			if (!priv->iq_autocal) {
-				err = -ENOMEM;
-				goto err;
-			}
-
-			memcpy(priv->iq_autocal, entry->data, data_len);
-			priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
-			break;
-		case PDR_DEFAULT_COUNTRY:
-			p54_parse_default_country(dev, entry->data, data_len);
-			break;
-		case PDR_INTERFACE_LIST:
-			tmp = entry->data;
-			while ((u8 *)tmp < entry->data + data_len) {
-				struct bootrec_exp_if *exp_if = tmp;
-				if (le16_to_cpu(exp_if->if_id) == 0xf)
-					synth = le16_to_cpu(exp_if->variant);
-				tmp += sizeof(struct bootrec_exp_if);
-			}
-			break;
-		case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
-			if (data_len < 2)
-				break;
-			priv->version = *(u8 *)(entry->data + 1);
-			break;
-		case PDR_RSSI_LINEAR_APPROXIMATION:
-		case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
-		case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
-			p54_parse_rssical(dev, entry->data, data_len,
-					  le16_to_cpu(entry->code));
-			break;
-		case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: {
-			__le16 *src = (void *) entry->data;
-			s16 *dst = (void *) &priv->rssical_db;
-			int i;
-
-			if (data_len != sizeof(priv->rssical_db)) {
-				err = -EINVAL;
-				goto err;
-			}
-			for (i = 0; i < sizeof(priv->rssical_db) /
-					sizeof(*src); i++)
-				*(dst++) = (s16) le16_to_cpu(*(src++));
-			}
-			break;
-		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
-			struct pda_custom_wrapper *pda = (void *) entry->data;
-			if (priv->output_limit || data_len < sizeof(*pda))
-				break;
-			priv->output_limit = p54_convert_db(pda, data_len);
-			}
-			break;
-		case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
-			struct pda_custom_wrapper *pda = (void *) entry->data;
-			if (priv->curve_data || data_len < sizeof(*pda))
-				break;
-			priv->curve_data = p54_convert_db(pda, data_len);
-			}
-			break;
-		case PDR_END:
-			/* make it overrun */
-			entry_len = len;
-			break;
-		case PDR_MANUFACTURING_PART_NUMBER:
-		case PDR_PDA_VERSION:
-		case PDR_NIC_SERIAL_NUMBER:
-		case PDR_REGULATORY_DOMAIN_LIST:
-		case PDR_TEMPERATURE_TYPE:
-		case PDR_PRISM_PCI_IDENTIFIER:
-		case PDR_COUNTRY_INFORMATION:
-		case PDR_OEM_NAME:
-		case PDR_PRODUCT_NAME:
-		case PDR_UTF8_OEM_NAME:
-		case PDR_UTF8_PRODUCT_NAME:
-		case PDR_COUNTRY_LIST:
-		case PDR_ANTENNA_GAIN:
-		case PDR_PRISM_INDIGO_PA_CALIBRATION_DATA:
-		case PDR_REGULATORY_POWER_LIMITS:
-		case PDR_RADIATED_TRANSMISSION_CORRECTION:
-		case PDR_PRISM_TX_IQ_CALIBRATION:
-		case PDR_BASEBAND_REGISTERS:
-		case PDR_PER_CHANNEL_BASEBAND_REGISTERS:
-			break;
-		default:
-			printk(KERN_INFO "%s: unknown eeprom code : 0x%x\n",
-				wiphy_name(dev->wiphy),
-				le16_to_cpu(entry->code));
-			break;
-		}
-
-		entry = (void *)entry + (entry_len + 1)*2;
-	}
-
-	if (!synth || !priv->iq_autocal || !priv->output_limit ||
-	    !priv->curve_data) {
-		printk(KERN_ERR "%s: not all required entries found in eeprom!\n",
-			wiphy_name(dev->wiphy));
-		err = -EINVAL;
-		goto err;
-	}
-
-	priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
-	if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
-		p54_init_xbow_synth(dev);
-	if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
-		dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
-	if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
-		dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
-	if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
-		priv->rx_diversity_mask = 3;
-	if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
-		priv->tx_diversity_mask = 3;
-
-	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
-		u8 perm_addr[ETH_ALEN];
-
-		printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n",
-			wiphy_name(dev->wiphy));
-		random_ether_addr(perm_addr);
-		SET_IEEE80211_PERM_ADDR(dev, perm_addr);
-	}
-
-	printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n",
-		wiphy_name(dev->wiphy),
-		dev->wiphy->perm_addr,
-		priv->version, p54_rf_chips[priv->rxhw]);
-
-	return 0;
-
-  err:
-	if (priv->iq_autocal) {
-		kfree(priv->iq_autocal);
-		priv->iq_autocal = NULL;
-	}
-
-	if (priv->output_limit) {
-		kfree(priv->output_limit);
-		priv->output_limit = NULL;
-	}
-
-	if (priv->curve_data) {
-		kfree(priv->curve_data);
-		priv->curve_data = NULL;
-	}
-
-	printk(KERN_ERR "%s: eeprom parse failed!\n",
-		wiphy_name(dev->wiphy));
-	return err;
-}
-EXPORT_SYMBOL_GPL(p54_parse_eeprom);
-
-static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
-{
-	struct p54_common *priv = dev->priv;
-	int band = dev->conf.channel->band;
-
-	if (priv->rxhw != PDR_SYNTH_FRONTEND_LONGBOW)
-		return ((rssi * priv->rssical_db[band].mul) / 64 +
-			 priv->rssical_db[band].add) / 4;
-	else
-		/*
-		 * TODO: find the correct formula
-		 */
-		return ((rssi * priv->rssical_db[band].mul) / 64 +
-			 priv->rssical_db[band].add) / 4;
-}
-
-static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_rx_data *hdr = (struct p54_rx_data *) skb->data;
-	struct ieee80211_rx_status rx_status = {0};
-	u16 freq = le16_to_cpu(hdr->freq);
-	size_t header_len = sizeof(*hdr);
-	u32 tsf32;
-	u8 rate = hdr->rate & 0xf;
-
-	/*
-	 * If the device is in a unspecified state we have to
-	 * ignore all data frames. Else we could end up with a
-	 * nasty crash.
-	 */
-	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
-		return 0;
-
-	if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD))) {
-		return 0;
-	}
-
-	if (hdr->decrypt_status == P54_DECRYPT_OK)
-		rx_status.flag |= RX_FLAG_DECRYPTED;
-	if ((hdr->decrypt_status == P54_DECRYPT_FAIL_MICHAEL) ||
-	    (hdr->decrypt_status == P54_DECRYPT_FAIL_TKIP))
-		rx_status.flag |= RX_FLAG_MMIC_ERROR;
-
-	rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi);
-	rx_status.noise = priv->noise;
-	if (hdr->rate & 0x10)
-		rx_status.flag |= RX_FLAG_SHORTPRE;
-	if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
-		rx_status.rate_idx = (rate < 4) ? 0 : rate - 4;
-	else
-		rx_status.rate_idx = rate;
-
-	rx_status.freq = freq;
-	rx_status.band =  dev->conf.channel->band;
-	rx_status.antenna = hdr->antenna;
-
-	tsf32 = le32_to_cpu(hdr->tsf32);
-	if (tsf32 < priv->tsf_low32)
-		priv->tsf_high32++;
-	rx_status.mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
-	priv->tsf_low32 = tsf32;
-
-	rx_status.flag |= RX_FLAG_TSFT;
-
-	if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
-		header_len += hdr->align[0];
-
-	skb_pull(skb, header_len);
-	skb_trim(skb, le16_to_cpu(hdr->len));
-
-	ieee80211_rx_irqsafe(dev, skb, &rx_status);
-
-	queue_delayed_work(dev->workqueue, &priv->work,
-			   msecs_to_jiffies(P54_STATISTICS_UPDATE));
-
-	return -1;
-}
-
-static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	int i;
-
-	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
-		return ;
-
-	for (i = 0; i < dev->queues; i++)
-		if (priv->tx_stats[i + P54_QUEUE_DATA].len <
-		    priv->tx_stats[i + P54_QUEUE_DATA].limit)
-			ieee80211_wake_queue(dev, i);
-}
-
-void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	struct p54_common *priv = dev->priv;
-	struct ieee80211_tx_info *info;
-	struct p54_tx_info *range;
-	unsigned long flags;
-
-	if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))
-		return;
-
-	/*
-	 * don't try to free an already unlinked skb
-	 */
-	if (unlikely((!skb->next) || (!skb->prev)))
-		return;
-
-	spin_lock_irqsave(&priv->tx_queue.lock, flags);
-	info = IEEE80211_SKB_CB(skb);
-	range = (void *)info->rate_driver_data;
-	if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
-		struct ieee80211_tx_info *ni;
-		struct p54_tx_info *mr;
-
-		ni = IEEE80211_SKB_CB(skb->prev);
-		mr = (struct p54_tx_info *)ni->rate_driver_data;
-	}
-	if (skb->next != (struct sk_buff *)&priv->tx_queue) {
-		struct ieee80211_tx_info *ni;
-		struct p54_tx_info *mr;
-
-		ni = IEEE80211_SKB_CB(skb->next);
-		mr = (struct p54_tx_info *)ni->rate_driver_data;
-	}
-	__skb_unlink(skb, &priv->tx_queue);
-	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-	dev_kfree_skb_any(skb);
-	p54_wake_free_queues(dev);
-}
-EXPORT_SYMBOL_GPL(p54_free_skb);
-
-static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev,
-					   __le32 req_id)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *entry;
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->tx_queue.lock, flags);
-	entry = priv->tx_queue.next;
-	while (entry != (struct sk_buff *)&priv->tx_queue) {
-		struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
-
-		if (hdr->req_id == req_id) {
-			spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-			return entry;
-		}
-		entry = entry->next;
-	}
-	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-	return NULL;
-}
-
-static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
-	struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
-	struct sk_buff *entry;
-	u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
-	struct p54_tx_info *range = NULL;
-	unsigned long flags;
-	int count, idx;
-
-	spin_lock_irqsave(&priv->tx_queue.lock, flags);
-	entry = (struct sk_buff *) priv->tx_queue.next;
-	while (entry != (struct sk_buff *)&priv->tx_queue) {
-		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
-		struct p54_hdr *entry_hdr;
-		struct p54_tx_data *entry_data;
-		unsigned int pad = 0, frame_len;
-
-		range = (void *)info->rate_driver_data;
-		if (range->start_addr != addr) {
-			entry = entry->next;
-			continue;
-		}
-
-		if (entry->next != (struct sk_buff *)&priv->tx_queue) {
-			struct ieee80211_tx_info *ni;
-			struct p54_tx_info *mr;
-
-			ni = IEEE80211_SKB_CB(entry->next);
-			mr = (struct p54_tx_info *)ni->rate_driver_data;
-		}
-
-		__skb_unlink(entry, &priv->tx_queue);
-
-		frame_len = entry->len;
-		entry_hdr = (struct p54_hdr *) entry->data;
-		entry_data = (struct p54_tx_data *) entry_hdr->data;
-		if (priv->tx_stats[entry_data->hw_queue].len)
-			priv->tx_stats[entry_data->hw_queue].len--;
-		priv->stats.dot11ACKFailureCount += payload->tries - 1;
-		spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-
-		/*
-		 * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
-		 * generated by the driver. Therefore tx_status is bogus
-		 * and we don't want to confuse the mac80211 stack.
-		 */
-		if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
-			if (entry_data->hw_queue == P54_QUEUE_BEACON)
-				priv->cached_beacon = NULL;
-
-			kfree_skb(entry);
-			goto out;
-		}
-
-		/*
-		 * Clear manually, ieee80211_tx_info_clear_status would
-		 * clear the counts too and we need them.
-		 */
-		memset(&info->status.ampdu_ack_len, 0,
-		       sizeof(struct ieee80211_tx_info) -
-		       offsetof(struct ieee80211_tx_info, status.ampdu_ack_len));
-		BUILD_BUG_ON(offsetof(struct ieee80211_tx_info,
-				      status.ampdu_ack_len) != 23);
-
-		if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
-			pad = entry_data->align[0];
-
-		/* walk through the rates array and adjust the counts */
-		count = payload->tries;
-		for (idx = 0; idx < 4; idx++) {
-			if (count >= info->status.rates[idx].count) {
-				count -= info->status.rates[idx].count;
-			} else if (count > 0) {
-				info->status.rates[idx].count = count;
-				count = 0;
-			} else {
-				info->status.rates[idx].idx = -1;
-				info->status.rates[idx].count = 0;
-			}
-		}
-
-		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-		     (!payload->status))
-			info->flags |= IEEE80211_TX_STAT_ACK;
-		if (payload->status & P54_TX_PSM_CANCELLED)
-			info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-		info->status.ack_signal = p54_rssi_to_dbm(dev,
-				(int)payload->ack_rssi);
-
-		/* Undo all changes to the frame. */
-		switch (entry_data->key_type) {
-		case P54_CRYPTO_TKIPMICHAEL: {
-			u8 *iv = (u8 *)(entry_data->align + pad +
-					entry_data->crypt_offset);
-
-			/* Restore the original TKIP IV. */
-			iv[2] = iv[0];
-			iv[0] = iv[1];
-			iv[1] = (iv[0] | 0x20) & 0x7f;	/* WEPSeed - 8.3.2.2 */
-
-			frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */
-			break;
-			}
-		case P54_CRYPTO_AESCCMP:
-			frame_len -= 8; /* remove CCMP_MIC */
-			break;
-		case P54_CRYPTO_WEP:
-			frame_len -= 4; /* remove WEP_ICV */
-			break;
-		}
-		skb_trim(entry, frame_len);
-		skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
-		ieee80211_tx_status_irqsafe(dev, entry);
-		goto out;
-	}
-	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-
-out:
-	p54_wake_free_queues(dev);
-}
-
-static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
-				   struct sk_buff *skb)
-{
-	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
-	struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data;
-	struct p54_common *priv = dev->priv;
-
-	if (!priv->eeprom)
-		return ;
-
-	if (priv->fw_var >= 0x509) {
-		memcpy(priv->eeprom, eeprom->v2.data,
-		       le16_to_cpu(eeprom->v2.len));
-	} else {
-		memcpy(priv->eeprom, eeprom->v1.data,
-		       le16_to_cpu(eeprom->v1.len));
-	}
-
-	complete(&priv->eeprom_comp);
-}
-
-static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
-	struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
-	u32 tsf32;
-
-	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
-		return ;
-
-	tsf32 = le32_to_cpu(stats->tsf32);
-	if (tsf32 < priv->tsf_low32)
-		priv->tsf_high32++;
-	priv->tsf_low32 = tsf32;
-
-	priv->stats.dot11RTSFailureCount = le32_to_cpu(stats->rts_fail);
-	priv->stats.dot11RTSSuccessCount = le32_to_cpu(stats->rts_success);
-	priv->stats.dot11FCSErrorCount = le32_to_cpu(stats->rx_bad_fcs);
-
-	priv->noise = p54_rssi_to_dbm(dev, le32_to_cpu(stats->noise));
-
-	p54_free_skb(dev, p54_find_tx_entry(dev, hdr->req_id));
-}
-
-static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
-	struct p54_trap *trap = (struct p54_trap *) hdr->data;
-	u16 event = le16_to_cpu(trap->event);
-	u16 freq = le16_to_cpu(trap->frequency);
-
-	switch (event) {
-	case P54_TRAP_BEACON_TX:
-		break;
-	case P54_TRAP_RADAR:
-		printk(KERN_INFO "%s: radar (freq:%d MHz)\n",
-			wiphy_name(dev->wiphy), freq);
-		break;
-	case P54_TRAP_NO_BEACON:
-		if (priv->vif)
-			ieee80211_beacon_loss(priv->vif);
-		break;
-	case P54_TRAP_SCAN:
-		break;
-	case P54_TRAP_TBTT:
-		break;
-	case P54_TRAP_TIMER:
-		break;
-	default:
-		printk(KERN_INFO "%s: received event:%x freq:%d\n",
-		       wiphy_name(dev->wiphy), event, freq);
-		break;
-	}
-}
-
-static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
-
-	switch (le16_to_cpu(hdr->type)) {
-	case P54_CONTROL_TYPE_TXDONE:
-		p54_rx_frame_sent(dev, skb);
-		break;
-	case P54_CONTROL_TYPE_TRAP:
-		p54_rx_trap(dev, skb);
-		break;
-	case P54_CONTROL_TYPE_BBP:
-		break;
-	case P54_CONTROL_TYPE_STAT_READBACK:
-		p54_rx_stats(dev, skb);
-		break;
-	case P54_CONTROL_TYPE_EEPROM_READBACK:
-		p54_rx_eeprom_readback(dev, skb);
-		break;
-	default:
-		printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n",
-		       wiphy_name(dev->wiphy), le16_to_cpu(hdr->type));
-		break;
-	}
-
-	return 0;
-}
-
-/* returns zero if skb can be reused */
-int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	u16 type = le16_to_cpu(*((__le16 *)skb->data));
-
-	if (type & P54_HDR_FLAG_CONTROL)
-		return p54_rx_control(dev, skb);
-	else
-		return p54_rx_data(dev, skb);
-}
-EXPORT_SYMBOL_GPL(p54_rx);
-
-/*
- * So, the firmware is somewhat stupid and doesn't know what places in its
- * memory incoming data should go to. By poking around in the firmware, we
- * can find some unused memory to upload our packets to. However, data that we
- * want the card to TX needs to stay intact until the card has told us that
- * it is done with it. This function finds empty places we can upload to and
- * marks allocated areas as reserved if necessary. p54_rx_frame_sent or
- * p54_free_skb frees allocated areas.
- */
-static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
-			       struct p54_hdr *data, u32 len)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *entry;
-	struct sk_buff *target_skb = NULL;
-	struct ieee80211_tx_info *info;
-	struct p54_tx_info *range;
-	u32 last_addr = priv->rx_start;
-	u32 largest_hole = 0;
-	u32 target_addr = priv->rx_start;
-	unsigned long flags;
-	unsigned int left;
-	len = (len + priv->headroom + priv->tailroom + 3) & ~0x3;
-
-	if (!skb)
-		return -EINVAL;
-
-	spin_lock_irqsave(&priv->tx_queue.lock, flags);
-
-	left = skb_queue_len(&priv->tx_queue);
-	if (unlikely(left >= 28)) {
-		/*
-		 * The tx_queue is nearly full!
-		 * We have throttle normal data traffic, because we must
-		 * have a few spare slots for control frames left.
-		 */
-		ieee80211_stop_queues(dev);
-		queue_delayed_work(dev->workqueue, &priv->work,
-				   msecs_to_jiffies(P54_TX_TIMEOUT));
-
-		if (unlikely(left == 32)) {
-			/*
-			 * The tx_queue is now really full.
-			 *
-			 * TODO: check if the device has crashed and reset it.
-			 */
-			spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-			return -ENOSPC;
-		}
-	}
-
-	entry = priv->tx_queue.next;
-	while (left--) {
-		u32 hole_size;
-		info = IEEE80211_SKB_CB(entry);
-		range = (void *)info->rate_driver_data;
-		hole_size = range->start_addr - last_addr;
-		if (!target_skb && hole_size >= len) {
-			target_skb = entry->prev;
-			hole_size -= len;
-			target_addr = last_addr;
-		}
-		largest_hole = max(largest_hole, hole_size);
-		last_addr = range->end_addr;
-		entry = entry->next;
-	}
-	if (!target_skb && priv->rx_end - last_addr >= len) {
-		target_skb = priv->tx_queue.prev;
-		largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
-		if (!skb_queue_empty(&priv->tx_queue)) {
-			info = IEEE80211_SKB_CB(target_skb);
-			range = (void *)info->rate_driver_data;
-			target_addr = range->end_addr;
-		}
-	} else
-		largest_hole = max(largest_hole, priv->rx_end - last_addr);
-
-	if (!target_skb) {
-		spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-		ieee80211_stop_queues(dev);
-		return -ENOSPC;
-	}
-
-	info = IEEE80211_SKB_CB(skb);
-	range = (void *)info->rate_driver_data;
-	range->start_addr = target_addr;
-	range->end_addr = target_addr + len;
-	__skb_queue_after(&priv->tx_queue, target_skb, skb);
-	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
-
-	if (largest_hole < priv->headroom + sizeof(struct p54_hdr) +
-			   48 + IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
-		ieee80211_stop_queues(dev);
-
-	data->req_id = cpu_to_le32(target_addr + priv->headroom);
-	return 0;
-}
-
-static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev, u16 hdr_flags,
-				     u16 payload_len, u16 type, gfp_t memflags)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_hdr *hdr;
-	struct sk_buff *skb;
-	size_t frame_len = sizeof(*hdr) + payload_len;
-
-	if (frame_len > P54_MAX_CTRL_FRAME_LEN)
-		return NULL;
-
-	skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags);
-	if (!skb)
-		return NULL;
-	skb_reserve(skb, priv->tx_hdr_len);
-
-	hdr = (struct p54_hdr *) skb_put(skb, sizeof(*hdr));
-	hdr->flags = cpu_to_le16(hdr_flags);
-	hdr->len = cpu_to_le16(payload_len);
-	hdr->type = cpu_to_le16(type);
-	hdr->tries = hdr->rts_tries = 0;
-
-	if (p54_assign_address(dev, skb, hdr, frame_len)) {
-		kfree_skb(skb);
-		return NULL;
-	}
-	return skb;
-}
-
-int p54_read_eeprom(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_eeprom_lm86 *eeprom_hdr;
-	struct sk_buff *skb;
-	size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
-	int ret = -ENOMEM;
-	void *eeprom = NULL;
-
-	maxblocksize = EEPROM_READBACK_LEN;
-	if (priv->fw_var >= 0x509)
-		maxblocksize -= 0xc;
-	else
-		maxblocksize -= 0x4;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL, sizeof(*eeprom_hdr) +
-			    maxblocksize, P54_CONTROL_TYPE_EEPROM_READBACK,
-			    GFP_KERNEL);
-	if (!skb)
-		goto free;
-	priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
-	if (!priv->eeprom)
-		goto free;
-	eeprom = kzalloc(eeprom_size, GFP_KERNEL);
-	if (!eeprom)
-		goto free;
-
-	eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb,
-		     sizeof(*eeprom_hdr) + maxblocksize);
-
-	while (eeprom_size) {
-		blocksize = min(eeprom_size, maxblocksize);
-		if (priv->fw_var < 0x509) {
-			eeprom_hdr->v1.offset = cpu_to_le16(offset);
-			eeprom_hdr->v1.len = cpu_to_le16(blocksize);
-		} else {
-			eeprom_hdr->v2.offset = cpu_to_le32(offset);
-			eeprom_hdr->v2.len = cpu_to_le16(blocksize);
-			eeprom_hdr->v2.magic2 = 0xf;
-			memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4);
-		}
-		priv->tx(dev, skb);
-
-		if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
-			printk(KERN_ERR "%s: device does not respond!\n",
-				wiphy_name(dev->wiphy));
-			ret = -EBUSY;
-			goto free;
-	        }
-
-		memcpy(eeprom + offset, priv->eeprom, blocksize);
-		offset += blocksize;
-		eeprom_size -= blocksize;
-	}
-
-	ret = p54_parse_eeprom(dev, eeprom, offset);
-free:
-	kfree(priv->eeprom);
-	priv->eeprom = NULL;
-	p54_free_skb(dev, skb);
-	kfree(eeprom);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(p54_read_eeprom);
-
-static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
-		bool set)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_tim *tim;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim),
-			    P54_CONTROL_TYPE_TIM, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	tim = (struct p54_tim *) skb_put(skb, sizeof(*tim));
-	tim->count = 1;
-	tim->entry[0] = cpu_to_le16(set ? (sta->aid | 0x8000) : sta->aid);
-	priv->tx(dev, skb);
-	return 0;
-}
-
-static int p54_sta_unlock(struct ieee80211_hw *dev, u8 *addr)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_sta_unlock *sta;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta),
-			    P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	sta = (struct p54_sta_unlock *)skb_put(skb, sizeof(*sta));
-	memcpy(sta->addr, addr, ETH_ALEN);
-	priv->tx(dev, skb);
-	return 0;
-}
-
-static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
-			      enum sta_notify_cmd notify_cmd,
-			      struct ieee80211_sta *sta)
-{
-	switch (notify_cmd) {
-	case STA_NOTIFY_ADD:
-	case STA_NOTIFY_REMOVE:
-		/*
-		 * Notify the firmware that we don't want or we don't
-		 * need to buffer frames for this station anymore.
-		 */
-
-		p54_sta_unlock(dev, sta->addr);
-		break;
-	case STA_NOTIFY_AWAKE:
-		/* update the firmware's filter table */
-		p54_sta_unlock(dev, sta->addr);
-		break;
-	default:
-		break;
-	}
-}
-
-static int p54_tx_cancel(struct ieee80211_hw *dev, struct sk_buff *entry)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_hdr *hdr;
-	struct p54_txcancel *cancel;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel),
-			    P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	hdr = (void *)entry->data;
-	cancel = (struct p54_txcancel *)skb_put(skb, sizeof(*cancel));
-	cancel->req_id = hdr->req_id;
-	priv->tx(dev, skb);
-	return 0;
-}
-
-static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
-		struct ieee80211_tx_info *info, u8 *queue, size_t *extra_len,
-		u16 *flags, u16 *aid)
-{
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	struct p54_common *priv = dev->priv;
-	int ret = 1;
-
-	switch (priv->mode) {
-	case NL80211_IFTYPE_MONITOR:
-		/*
-		 * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
-		 * every frame in promiscuous/monitor mode.
-		 * see STSW45x0C LMAC API - page 12.
-		 */
-		*aid = 0;
-		*flags = P54_HDR_FLAG_DATA_OUT_PROMISC;
-		*queue += P54_QUEUE_DATA;
-		break;
-	case NL80211_IFTYPE_STATION:
-		*aid = 1;
-		if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
-			*queue = P54_QUEUE_MGMT;
-			ret = 0;
-		} else
-			*queue += P54_QUEUE_DATA;
-		break;
-	case NL80211_IFTYPE_AP:
-	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_MESH_POINT:
-		if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
-			*aid = 0;
-			*queue = P54_QUEUE_CAB;
-			return 0;
-		}
-
-		if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
-			if (ieee80211_is_probe_resp(hdr->frame_control)) {
-				*aid = 0;
-				*queue = P54_QUEUE_MGMT;
-				*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
-					 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
-				return 0;
-			} else if (ieee80211_is_beacon(hdr->frame_control)) {
-				*aid = 0;
-
-				if (info->flags & IEEE80211_TX_CTL_INJECTED) {
-					/*
-					 * Injecting beacons on top of a AP is
-					 * not a good idea... nevertheless,
-					 * it should be doable.
-					 */
-
-					*queue += P54_QUEUE_DATA;
-					return 1;
-				}
-
-				*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
-				*queue = P54_QUEUE_BEACON;
-				*extra_len = IEEE80211_MAX_TIM_LEN;
-				return 0;
-			} else {
-				*queue = P54_QUEUE_MGMT;
-				ret = 0;
-			}
-		} else
-			*queue += P54_QUEUE_DATA;
-
-		if (info->control.sta)
-			*aid = info->control.sta->aid;
-
-		if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
-			*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
-		break;
-	}
-	return ret;
-}
-
-static u8 p54_convert_algo(enum ieee80211_key_alg alg)
-{
-	switch (alg) {
-	case ALG_WEP:
-		return P54_CRYPTO_WEP;
-	case ALG_TKIP:
-		return P54_CRYPTO_TKIPMICHAEL;
-	case ALG_CCMP:
-		return P54_CRYPTO_AESCCMP;
-	default:
-		return 0;
-	}
-}
-
-static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ieee80211_tx_queue_stats *current_queue;
-	struct p54_common *priv = dev->priv;
-	struct p54_hdr *hdr;
-	struct p54_tx_data *txhdr;
-	size_t padding, len, tim_len = 0;
-	int i, j, ridx, ret;
-	u16 hdr_flags = 0, aid = 0;
-	u8 rate, queue, crypt_offset = 0;
-	u8 cts_rate = 0x20;
-	u8 rc_flags;
-	u8 calculated_tries[4];
-	u8 nrates = 0, nremaining = 8;
-
-	queue = skb_get_queue_mapping(skb);
-
-	ret = p54_tx_fill(dev, skb, info, &queue, &tim_len, &hdr_flags, &aid);
-	current_queue = &priv->tx_stats[queue];
-	if (unlikely((current_queue->len > current_queue->limit) && ret))
-		return NETDEV_TX_BUSY;
-	current_queue->len++;
-	current_queue->count++;
-	if ((current_queue->len == current_queue->limit) && ret)
-		ieee80211_stop_queue(dev, skb_get_queue_mapping(skb));
-
-	padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
-	len = skb->len;
-
-	if (info->control.hw_key) {
-		crypt_offset = ieee80211_get_hdrlen_from_skb(skb);
-		if (info->control.hw_key->alg == ALG_TKIP) {
-			u8 *iv = (u8 *)(skb->data + crypt_offset);
-			/*
-			 * The firmware excepts that the IV has to have
-			 * this special format
-			 */
-			iv[1] = iv[0];
-			iv[0] = iv[2];
-			iv[2] = 0;
-		}
-	}
-
-	txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding);
-	hdr = (struct p54_hdr *) skb_push(skb, sizeof(*hdr));
-
-	if (padding)
-		hdr_flags |= P54_HDR_FLAG_DATA_ALIGN;
-	hdr->type = cpu_to_le16(aid);
-	hdr->rts_tries = info->control.rates[0].count;
-
-	/*
-	 * we register the rates in perfect order, and
-	 * RTS/CTS won't happen on 5 GHz
-	 */
-	cts_rate = info->control.rts_cts_rate_idx;
-
-	memset(&txhdr->rateset, 0, sizeof(txhdr->rateset));
-
-	/* see how many rates got used */
-	for (i = 0; i < 4; i++) {
-		if (info->control.rates[i].idx < 0)
-			break;
-		nrates++;
-	}
-
-	/* limit tries to 8/nrates per rate */
-	for (i = 0; i < nrates; i++) {
-		/*
-		 * The magic expression here is equivalent to 8/nrates for
-		 * all values that matter, but avoids division and jumps.
-		 * Note that nrates can only take the values 1 through 4.
-		 */
-		calculated_tries[i] = min_t(int, ((15 >> nrates) | 1) + 1,
-						 info->control.rates[i].count);
-		nremaining -= calculated_tries[i];
-	}
-
-	/* if there are tries left, distribute from back to front */
-	for (i = nrates - 1; nremaining > 0 && i >= 0; i--) {
-		int tmp = info->control.rates[i].count - calculated_tries[i];
-
-		if (tmp <= 0)
-			continue;
-		/* RC requested more tries at this rate */
-
-		tmp = min_t(int, tmp, nremaining);
-		calculated_tries[i] += tmp;
-		nremaining -= tmp;
-	}
-
-	ridx = 0;
-	for (i = 0; i < nrates && ridx < 8; i++) {
-		/* we register the rates in perfect order */
-		rate = info->control.rates[i].idx;
-		if (info->band == IEEE80211_BAND_5GHZ)
-			rate += 4;
-
-		/* store the count we actually calculated for TX status */
-		info->control.rates[i].count = calculated_tries[i];
-
-		rc_flags = info->control.rates[i].flags;
-		if (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) {
-			rate |= 0x10;
-			cts_rate |= 0x10;
-		}
-		if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
-			rate |= 0x40;
-		else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-			rate |= 0x20;
-		for (j = 0; j < calculated_tries[i] && ridx < 8; j++) {
-			txhdr->rateset[ridx] = rate;
-			ridx++;
-		}
-	}
-
-	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
-		hdr_flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
-
-	/* TODO: enable bursting */
-	hdr->flags = cpu_to_le16(hdr_flags);
-	hdr->tries = ridx;
-	txhdr->rts_rate_idx = 0;
-	if (info->control.hw_key) {
-		txhdr->key_type = p54_convert_algo(info->control.hw_key->alg);
-		txhdr->key_len = min((u8)16, info->control.hw_key->keylen);
-		memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len);
-		if (info->control.hw_key->alg == ALG_TKIP) {
-			if (unlikely(skb_tailroom(skb) < 12))
-				goto err;
-			/* reserve space for the MIC key */
-			len += 8;
-			memcpy(skb_put(skb, 8), &(info->control.hw_key->key
-				[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]), 8);
-		}
-		/* reserve some space for ICV */
-		len += info->control.hw_key->icv_len;
-		memset(skb_put(skb, info->control.hw_key->icv_len), 0,
-		       info->control.hw_key->icv_len);
-	} else {
-		txhdr->key_type = 0;
-		txhdr->key_len = 0;
-	}
-	txhdr->crypt_offset = crypt_offset;
-	txhdr->hw_queue = queue;
-	txhdr->backlog = current_queue->len;
-	memset(txhdr->durations, 0, sizeof(txhdr->durations));
-	txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ?
-		2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask;
-	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
-		txhdr->longbow.cts_rate = cts_rate;
-		txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
-	} else {
-		txhdr->normal.output_power = priv->output_power;
-		txhdr->normal.cts_rate = cts_rate;
-	}
-	if (padding)
-		txhdr->align[0] = padding;
-
-	hdr->len = cpu_to_le16(len);
-	/* modifies skb->cb and with it info, so must be last! */
-	if (unlikely(p54_assign_address(dev, skb, hdr, skb->len + tim_len)))
-		goto err;
-	priv->tx(dev, skb);
-
-	queue_delayed_work(dev->workqueue, &priv->work,
-			   msecs_to_jiffies(P54_TX_FRAME_LIFETIME));
-
-	return NETDEV_TX_OK;
-
- err:
-	skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding);
-	current_queue->len--;
-	current_queue->count--;
-	return NETDEV_TX_BUSY;
-}
-
-static int p54_setup_mac(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_setup_mac *setup;
-	u16 mode;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup),
-			    P54_CONTROL_TYPE_SETUP, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	setup = (struct p54_setup_mac *) skb_put(skb, sizeof(*setup));
-	if (dev->conf.radio_enabled) {
-		switch (priv->mode) {
-		case NL80211_IFTYPE_STATION:
-			mode = P54_FILTER_TYPE_STATION;
-			break;
-		case NL80211_IFTYPE_AP:
-			mode = P54_FILTER_TYPE_AP;
-			break;
-		case NL80211_IFTYPE_ADHOC:
-		case NL80211_IFTYPE_MESH_POINT:
-			mode = P54_FILTER_TYPE_IBSS;
-			break;
-		case NL80211_IFTYPE_MONITOR:
-			mode = P54_FILTER_TYPE_PROMISCUOUS;
-			break;
-		default:
-			mode = P54_FILTER_TYPE_HIBERNATE;
-			break;
-		}
-
-		/*
-		 * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
-		 * STSW45X0C LMAC API - page 12
-		 */
-		if (((priv->filter_flags & FIF_PROMISC_IN_BSS) ||
-		     (priv->filter_flags & FIF_OTHER_BSS)) &&
-		    (mode != P54_FILTER_TYPE_PROMISCUOUS))
-			mode |= P54_FILTER_TYPE_TRANSPARENT;
-	} else
-		mode = P54_FILTER_TYPE_HIBERNATE;
-
-	setup->mac_mode = cpu_to_le16(mode);
-	memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN);
-	memcpy(setup->bssid, priv->bssid, ETH_ALEN);
-	setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */
-	setup->rx_align = 0;
-	if (priv->fw_var < 0x500) {
-		setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
-		memset(setup->v1.rts_rates, 0, 8);
-		setup->v1.rx_addr = cpu_to_le32(priv->rx_end);
-		setup->v1.max_rx = cpu_to_le16(priv->rx_mtu);
-		setup->v1.rxhw = cpu_to_le16(priv->rxhw);
-		setup->v1.wakeup_timer = cpu_to_le16(priv->wakeup_timer);
-		setup->v1.unalloc0 = cpu_to_le16(0);
-	} else {
-		setup->v2.rx_addr = cpu_to_le32(priv->rx_end);
-		setup->v2.max_rx = cpu_to_le16(priv->rx_mtu);
-		setup->v2.rxhw = cpu_to_le16(priv->rxhw);
-		setup->v2.timer = cpu_to_le16(priv->wakeup_timer);
-		setup->v2.truncate = cpu_to_le16(48896);
-		setup->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
-		setup->v2.sbss_offset = 0;
-		setup->v2.mcast_window = 0;
-		setup->v2.rx_rssi_threshold = 0;
-		setup->v2.rx_ed_threshold = 0;
-		setup->v2.ref_clock = cpu_to_le32(644245094);
-		setup->v2.lpf_bandwidth = cpu_to_le16(65535);
-		setup->v2.osc_start_delay = cpu_to_le16(65535);
-	}
-	priv->tx(dev, skb);
-	return 0;
-}
-
-static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_hdr *hdr;
-	struct p54_scan_head *head;
-	struct p54_iq_autocal_entry *iq_autocal;
-	union p54_scan_body_union *body;
-	struct p54_scan_tail_rate *rate;
-	struct pda_rssi_cal_entry *rssi;
-	unsigned int i;
-	void *entry;
-	int band = dev->conf.channel->band;
-	__le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
-			    2 + sizeof(*iq_autocal) + sizeof(*body) +
-			    sizeof(*rate) + 2 * sizeof(*rssi),
-			    P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	head = (struct p54_scan_head *) skb_put(skb, sizeof(*head));
-	memset(head->scan_params, 0, sizeof(head->scan_params));
-	head->mode = cpu_to_le16(mode);
-	head->dwell = cpu_to_le16(dwell);
-	head->freq = freq;
-
-	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
-		__le16 *pa_power_points = (__le16 *) skb_put(skb, 2);
-		*pa_power_points = cpu_to_le16(0x0c);
-	}
-
-	iq_autocal = (void *) skb_put(skb, sizeof(*iq_autocal));
-	for (i = 0; i < priv->iq_autocal_len; i++) {
-		if (priv->iq_autocal[i].freq != freq)
-			continue;
-
-		memcpy(iq_autocal, &priv->iq_autocal[i].params,
-		       sizeof(struct p54_iq_autocal_entry));
-		break;
-	}
-	if (i == priv->iq_autocal_len)
-		goto err;
-
-	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
-		body = (void *) skb_put(skb, sizeof(body->longbow));
-	else
-		body = (void *) skb_put(skb, sizeof(body->normal));
-
-	for (i = 0; i < priv->output_limit->entries; i++) {
-		__le16 *entry_freq = (void *) (priv->output_limit->data +
-				     priv->output_limit->entry_size * i);
-
-		if (*entry_freq != freq)
-			continue;
-
-		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
-			memcpy(&body->longbow.power_limits,
-			       (void *) entry_freq + sizeof(__le16),
-			       priv->output_limit->entry_size);
-		} else {
-			struct pda_channel_output_limit *limits =
-			       (void *) entry_freq;
-
-			body->normal.val_barker = 0x38;
-			body->normal.val_bpsk = body->normal.dup_bpsk =
-				limits->val_bpsk;
-			body->normal.val_qpsk = body->normal.dup_qpsk =
-				limits->val_qpsk;
-			body->normal.val_16qam = body->normal.dup_16qam =
-				limits->val_16qam;
-			body->normal.val_64qam = body->normal.dup_64qam =
-				limits->val_64qam;
-		}
-		break;
-	}
-	if (i == priv->output_limit->entries)
-		goto err;
-
-	entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
-	for (i = 0; i < priv->curve_data->entries; i++) {
-		if (*((__le16 *)entry) != freq) {
-			entry += priv->curve_data->entry_size;
-			continue;
-		}
-
-		if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
-			memcpy(&body->longbow.curve_data,
-				(void *) entry + sizeof(__le16),
-				priv->curve_data->entry_size);
-		} else {
-			struct p54_scan_body *chan = &body->normal;
-			struct pda_pa_curve_data *curve_data =
-				(void *) priv->curve_data->data;
-
-			entry += sizeof(__le16);
-			chan->pa_points_per_curve = 8;
-			memset(chan->curve_data, 0, sizeof(*chan->curve_data));
-			memcpy(chan->curve_data, entry,
-			       sizeof(struct p54_pa_curve_data_sample) *
-			       min((u8)8, curve_data->points_per_channel));
-		}
-		break;
-	}
-	if (i == priv->curve_data->entries)
-		goto err;
-
-	if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
-		rate = (void *) skb_put(skb, sizeof(*rate));
-		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
-		for (i = 0; i < sizeof(rate->rts_rates); i++)
-			rate->rts_rates[i] = i;
-	}
-
-	rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
-	rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
-	rssi->add = cpu_to_le16(priv->rssical_db[band].add);
-	if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
-		/* Longbow frontend needs ever more */
-		rssi = (void *) skb_put(skb, sizeof(*rssi));
-		rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
-		rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
-	}
-
-	if (priv->fw_var >= 0x509) {
-		rate = (void *) skb_put(skb, sizeof(*rate));
-		rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
-		for (i = 0; i < sizeof(rate->rts_rates); i++)
-			rate->rts_rates[i] = i;
-	}
-
-	hdr = (struct p54_hdr *) skb->data;
-	hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
-
-	priv->tx(dev, skb);
-	return 0;
-
- err:
-	printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
-	p54_free_skb(dev, skb);
-	return -EINVAL;
-}
-
-static int p54_set_leds(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_led *led;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led),
-			    P54_CONTROL_TYPE_LED, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	led = (struct p54_led *) skb_put(skb, sizeof(*led));
-	led->flags = cpu_to_le16(0x0003);
-	led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state);
-	led->delay[0] = cpu_to_le16(1);
-	led->delay[1] = cpu_to_le16(0);
-	priv->tx(dev, skb);
-	return 0;
-}
-
-#define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, _txop)	\
-do {	 							\
-	queue.aifs = cpu_to_le16(ai_fs);			\
-	queue.cwmin = cpu_to_le16(cw_min);			\
-	queue.cwmax = cpu_to_le16(cw_max);			\
-	queue.txop = cpu_to_le16(_txop);			\
-} while(0)
-
-static int p54_set_edcf(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_edcf *edcf;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
-			    P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	edcf = (struct p54_edcf *)skb_put(skb, sizeof(*edcf));
-	if (priv->use_short_slot) {
-		edcf->slottime = 9;
-		edcf->sifs = 0x10;
-		edcf->eofpad = 0x00;
-	} else {
-		edcf->slottime = 20;
-		edcf->sifs = 0x0a;
-		edcf->eofpad = 0x06;
-	}
-	/* (see prism54/isl_oid.h for further details) */
-	edcf->frameburst = cpu_to_le16(0);
-	edcf->round_trip_delay = cpu_to_le16(0);
-	edcf->flags = 0;
-	memset(edcf->mapping, 0, sizeof(edcf->mapping));
-	memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
-	priv->tx(dev, skb);
-	return 0;
-}
-
-static int p54_set_ps(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_psm *psm;
-	u16 mode;
-	int i;
-
-	if (dev->conf.flags & IEEE80211_CONF_PS)
-		mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
-		       P54_PSM_CHECKSUM | P54_PSM_MCBC;
-	else
-		mode = P54_PSM_CAM;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm),
-			    P54_CONTROL_TYPE_PSM, GFP_ATOMIC);
-	if (!skb)
-		return -ENOMEM;
-
-	psm = (struct p54_psm *)skb_put(skb, sizeof(*psm));
-	psm->mode = cpu_to_le16(mode);
-	psm->aid = cpu_to_le16(priv->aid);
-	for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) {
-		psm->intervals[i].interval =
-			cpu_to_le16(dev->conf.listen_interval);
-		psm->intervals[i].periods = cpu_to_le16(1);
-	}
-
-	psm->beacon_rssi_skip_max = 200;
-	psm->rssi_delta_threshold = 0;
-	psm->nr = 10;
-	psm->exclude[0] = 0;
-
-	priv->tx(dev, skb);
-
-	return 0;
-}
-
-static int p54_beacon_tim(struct sk_buff *skb)
-{
-	/*
-	 * the good excuse for this mess is ... the firmware.
-	 * The dummy TIM MUST be at the end of the beacon frame,
-	 * because it'll be overwritten!
-	 */
-
-	struct ieee80211_mgmt *mgmt = (void *)skb->data;
-	u8 *pos, *end;
-
-	if (skb->len <= sizeof(mgmt))
-		return -EINVAL;
-
-	pos = (u8 *)mgmt->u.beacon.variable;
-	end = skb->data + skb->len;
-	while (pos < end) {
-		if (pos + 2 + pos[1] > end)
-			return -EINVAL;
-
-		if (pos[0] == WLAN_EID_TIM) {
-			u8 dtim_len = pos[1];
-			u8 dtim_period = pos[3];
-			u8 *next = pos + 2 + dtim_len;
-
-			if (dtim_len < 3)
-				return -EINVAL;
-
-			memmove(pos, next, end - next);
-
-			if (dtim_len > 3)
-				skb_trim(skb, skb->len - (dtim_len - 3));
-
-			pos = end - (dtim_len + 2);
-
-			/* add the dummy at the end */
-			pos[0] = WLAN_EID_TIM;
-			pos[1] = 3;
-			pos[2] = 0;
-			pos[3] = dtim_period;
-			pos[4] = 0;
-			return 0;
-		}
-		pos += 2 + pos[1];
-	}
-	return 0;
-}
-
-static int p54_beacon_update(struct ieee80211_hw *dev,
-			struct ieee80211_vif *vif)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *beacon;
-	int ret;
-
-	if (priv->cached_beacon) {
-		p54_tx_cancel(dev, priv->cached_beacon);
-		/* wait for the last beacon the be freed */
-		msleep(10);
-	}
-
-	beacon = ieee80211_beacon_get(dev, vif);
-	if (!beacon)
-		return -ENOMEM;
-	ret = p54_beacon_tim(beacon);
-	if (ret)
-		return ret;
-	ret = p54_tx(dev, beacon);
-	if (ret)
-		return ret;
-	priv->cached_beacon = beacon;
-	priv->tsf_high32 = 0;
-	priv->tsf_low32 = 0;
-
-	return 0;
-}
-
-static int p54_start(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	int err;
-
-	mutex_lock(&priv->conf_mutex);
-	err = priv->open(dev);
-	if (err)
-		goto out;
-	P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
-	P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
-	P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
-	P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
-	err = p54_set_edcf(dev);
-	if (err)
-		goto out;
-
-	memset(priv->bssid, ~0, ETH_ALEN);
-	priv->mode = NL80211_IFTYPE_MONITOR;
-	err = p54_setup_mac(dev);
-	if (err) {
-		priv->mode = NL80211_IFTYPE_UNSPECIFIED;
-		goto out;
-	}
-
-	queue_delayed_work(dev->workqueue, &priv->work, 0);
-
-	priv->softled_state = 0;
-	err = p54_set_leds(dev);
-
-out:
-	mutex_unlock(&priv->conf_mutex);
-	return err;
-}
-
-static void p54_stop(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-
-	mutex_lock(&priv->conf_mutex);
-	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
-	priv->softled_state = 0;
-	p54_set_leds(dev);
-
-#ifdef CONFIG_P54_LEDS
-	cancel_delayed_work_sync(&priv->led_work);
-#endif /* CONFIG_P54_LEDS */
-	cancel_delayed_work_sync(&priv->work);
-	if (priv->cached_beacon)
-		p54_tx_cancel(dev, priv->cached_beacon);
-
-	priv->stop(dev);
-	while ((skb = skb_dequeue(&priv->tx_queue)))
-		kfree_skb(skb);
-	priv->cached_beacon = NULL;
-	priv->tsf_high32 = priv->tsf_low32 = 0;
-	mutex_unlock(&priv->conf_mutex);
-}
-
-static int p54_add_interface(struct ieee80211_hw *dev,
-			     struct ieee80211_if_init_conf *conf)
-{
-	struct p54_common *priv = dev->priv;
-
-	mutex_lock(&priv->conf_mutex);
-	if (priv->mode != NL80211_IFTYPE_MONITOR) {
-		mutex_unlock(&priv->conf_mutex);
-		return -EOPNOTSUPP;
-	}
-
-	priv->vif = conf->vif;
-
-	switch (conf->type) {
-	case NL80211_IFTYPE_STATION:
-	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_AP:
-	case NL80211_IFTYPE_MESH_POINT:
-		priv->mode = conf->type;
-		break;
-	default:
-		mutex_unlock(&priv->conf_mutex);
-		return -EOPNOTSUPP;
-	}
-
-	memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
-	p54_setup_mac(dev);
-	mutex_unlock(&priv->conf_mutex);
-	return 0;
-}
-
-static void p54_remove_interface(struct ieee80211_hw *dev,
-				 struct ieee80211_if_init_conf *conf)
-{
-	struct p54_common *priv = dev->priv;
-
-	mutex_lock(&priv->conf_mutex);
-	priv->vif = NULL;
-	if (priv->cached_beacon)
-		p54_tx_cancel(dev, priv->cached_beacon);
-	priv->mode = NL80211_IFTYPE_MONITOR;
-	memset(priv->mac_addr, 0, ETH_ALEN);
-	memset(priv->bssid, 0, ETH_ALEN);
-	p54_setup_mac(dev);
-	mutex_unlock(&priv->conf_mutex);
-}
-
-static int p54_config(struct ieee80211_hw *dev, u32 changed)
-{
-	int ret = 0;
-	struct p54_common *priv = dev->priv;
-	struct ieee80211_conf *conf = &dev->conf;
-
-	mutex_lock(&priv->conf_mutex);
-	if (changed & IEEE80211_CONF_CHANGE_POWER)
-		priv->output_power = conf->power_level << 2;
-	if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
-		ret = p54_setup_mac(dev);
-		if (ret)
-			goto out;
-	}
-	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-		ret = p54_scan(dev, P54_SCAN_EXIT, 0);
-		if (ret)
-			goto out;
-	}
-	if (changed & IEEE80211_CONF_CHANGE_PS) {
-		ret = p54_set_ps(dev);
-		if (ret)
-			goto out;
-	}
-
-out:
-	mutex_unlock(&priv->conf_mutex);
-	return ret;
-}
-
-static void p54_configure_filter(struct ieee80211_hw *dev,
-				 unsigned int changed_flags,
-				 unsigned int *total_flags,
-				 int mc_count, struct dev_mc_list *mclist)
-{
-	struct p54_common *priv = dev->priv;
-
-	*total_flags &= FIF_PROMISC_IN_BSS |
-			FIF_OTHER_BSS;
-
-	priv->filter_flags = *total_flags;
-
-	if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
-		p54_setup_mac(dev);
-}
-
-static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
-		       const struct ieee80211_tx_queue_params *params)
-{
-	struct p54_common *priv = dev->priv;
-	int ret;
-
-	mutex_lock(&priv->conf_mutex);
-	if ((params) && !(queue > 4)) {
-		P54_SET_QUEUE(priv->qos_params[queue], params->aifs,
-			params->cw_min, params->cw_max, params->txop);
-		ret = p54_set_edcf(dev);
-	} else
-		ret = -EINVAL;
-	mutex_unlock(&priv->conf_mutex);
-	return ret;
-}
-
-static int p54_init_xbow_synth(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_xbow_synth *xbow;
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow),
-			    P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL);
-	if (!skb)
-		return -ENOMEM;
-
-	xbow = (struct p54_xbow_synth *)skb_put(skb, sizeof(*xbow));
-	xbow->magic1 = cpu_to_le16(0x1);
-	xbow->magic2 = cpu_to_le16(0x2);
-	xbow->freq = cpu_to_le16(5390);
-	memset(xbow->padding, 0, sizeof(xbow->padding));
-	priv->tx(dev, skb);
-	return 0;
-}
-
-static void p54_work(struct work_struct *work)
-{
-	struct p54_common *priv = container_of(work, struct p54_common,
-					       work.work);
-	struct ieee80211_hw *dev = priv->hw;
-	struct sk_buff *skb;
-
-	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
-		return ;
-
-	/*
-	 * TODO: walk through tx_queue and do the following tasks
-	 * 	1. initiate bursts.
-	 *      2. cancel stuck frames / reset the device if necessary.
-	 */
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL,
-			    sizeof(struct p54_statistics),
-			    P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL);
-	if (!skb)
-		return ;
-
-	priv->tx(dev, skb);
-}
-
-static int p54_get_stats(struct ieee80211_hw *dev,
-			 struct ieee80211_low_level_stats *stats)
-{
-	struct p54_common *priv = dev->priv;
-
-	memcpy(stats, &priv->stats, sizeof(*stats));
-	return 0;
-}
-
-static int p54_get_tx_stats(struct ieee80211_hw *dev,
-			    struct ieee80211_tx_queue_stats *stats)
-{
-	struct p54_common *priv = dev->priv;
-
-	memcpy(stats, &priv->tx_stats[P54_QUEUE_DATA],
-	       sizeof(stats[0]) * dev->queues);
-	return 0;
-}
-
-static void p54_bss_info_changed(struct ieee80211_hw *dev,
-				 struct ieee80211_vif *vif,
-				 struct ieee80211_bss_conf *info,
-				 u32 changed)
-{
-	struct p54_common *priv = dev->priv;
-	int ret;
-
-	mutex_lock(&priv->conf_mutex);
-	if (changed & BSS_CHANGED_BSSID) {
-		memcpy(priv->bssid, info->bssid, ETH_ALEN);
-		ret = p54_setup_mac(dev);
-		if (ret)
-			goto out;
-	}
-
-	if (changed & BSS_CHANGED_BEACON) {
-		ret = p54_scan(dev, P54_SCAN_EXIT, 0);
-		if (ret)
-			goto out;
-		ret = p54_setup_mac(dev);
-		if (ret)
-			goto out;
-		ret = p54_beacon_update(dev, vif);
-		if (ret)
-			goto out;
-	}
-	/* XXX: this mimics having two callbacks... clean up */
- out:
-	mutex_unlock(&priv->conf_mutex);
-
-	if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BEACON)) {
-		priv->use_short_slot = info->use_short_slot;
-		p54_set_edcf(dev);
-	}
-	if (changed & BSS_CHANGED_BASIC_RATES) {
-		if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
-			priv->basic_rate_mask = (info->basic_rates << 4);
-		else
-			priv->basic_rate_mask = info->basic_rates;
-		p54_setup_mac(dev);
-		if (priv->fw_var >= 0x500)
-			p54_scan(dev, P54_SCAN_EXIT, 0);
-	}
-	if (changed & BSS_CHANGED_ASSOC) {
-		if (info->assoc) {
-			priv->aid = info->aid;
-			priv->wakeup_timer = info->beacon_int *
-					     info->dtim_period * 5;
-			p54_setup_mac(dev);
-		}
-	}
-}
-
-static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
-		       struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-		       struct ieee80211_key_conf *key)
-{
-	struct p54_common *priv = dev->priv;
-	struct sk_buff *skb;
-	struct p54_keycache *rxkey;
-	int slot, ret = 0;
-	u8 algo = 0;
-
-	if (modparam_nohwcrypt)
-		return -EOPNOTSUPP;
-
-	mutex_lock(&priv->conf_mutex);
-	if (cmd == SET_KEY) {
-		switch (key->alg) {
-		case ALG_TKIP:
-			if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
-			      BR_DESC_PRIV_CAP_TKIP))) {
-				ret = -EOPNOTSUPP;
-				goto out_unlock;
-			}
-			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-			algo = P54_CRYPTO_TKIPMICHAEL;
-			break;
-		case ALG_WEP:
-			if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
-				ret = -EOPNOTSUPP;
-				goto out_unlock;
-			}
-			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-			algo = P54_CRYPTO_WEP;
-			break;
-		case ALG_CCMP:
-			if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
-				ret = -EOPNOTSUPP;
-				goto out_unlock;
-			}
-			key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-			algo = P54_CRYPTO_AESCCMP;
-			break;
-		default:
-			ret = -EOPNOTSUPP;
-			goto out_unlock;
-		}
-		slot = bitmap_find_free_region(priv->used_rxkeys,
-					       priv->rx_keycache_size, 0);
-
-		if (slot < 0) {
-			/*
-			 * The device supports the choosen algorithm, but the
-			 * firmware does not provide enough key slots to store
-			 * all of them.
-			 * But encryption offload for outgoing frames is always
-			 * possible, so we just pretend that the upload was
-			 * successful and do the decryption in software.
-			 */
-
-			/* mark the key as invalid. */
-			key->hw_key_idx = 0xff;
-			goto out_unlock;
-		}
-	} else {
-		slot = key->hw_key_idx;
-
-		if (slot == 0xff) {
-			/* This key was not uploaded into the rx key cache. */
-
-			goto out_unlock;
-		}
-
-		bitmap_release_region(priv->used_rxkeys, slot, 0);
-		algo = 0;
-	}
-
-	skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
-			    P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL);
-	if (!skb) {
-		bitmap_release_region(priv->used_rxkeys, slot, 0);
-		ret = -ENOSPC;
-		goto out_unlock;
-	}
-
-	rxkey = (struct p54_keycache *)skb_put(skb, sizeof(*rxkey));
-	rxkey->entry = slot;
-	rxkey->key_id = key->keyidx;
-	rxkey->key_type = algo;
-	if (sta)
-		memcpy(rxkey->mac, sta->addr, ETH_ALEN);
-	else
-		memset(rxkey->mac, ~0, ETH_ALEN);
-	if (key->alg != ALG_TKIP) {
-		rxkey->key_len = min((u8)16, key->keylen);
-		memcpy(rxkey->key, key->key, rxkey->key_len);
-	} else {
-		rxkey->key_len = 24;
-		memcpy(rxkey->key, key->key, 16);
-		memcpy(&(rxkey->key[16]), &(key->key
-			[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8);
-	}
-
-	priv->tx(dev, skb);
-	key->hw_key_idx = slot;
-
-out_unlock:
-	mutex_unlock(&priv->conf_mutex);
-	return ret;
-}
-
-#ifdef CONFIG_P54_LEDS
-static void p54_update_leds(struct work_struct *work)
-{
-	struct p54_common *priv = container_of(work, struct p54_common,
-					       led_work.work);
-	int err, i, tmp, blink_delay = 400;
-	bool rerun = false;
-
-	/* Don't toggle the LED, when the device is down. */
-	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
-		return ;
-
-	for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
-		if (priv->leds[i].toggled) {
-			priv->softled_state |= BIT(i);
-
-			tmp = 70 + 200 / (priv->leds[i].toggled);
-			if (tmp < blink_delay)
-				blink_delay = tmp;
-
-			if (priv->leds[i].led_dev.brightness == LED_OFF)
-				rerun = true;
-
-			priv->leds[i].toggled =
-				!!priv->leds[i].led_dev.brightness;
-		} else
-			priv->softled_state &= ~BIT(i);
-
-	err = p54_set_leds(priv->hw);
-	if (err && net_ratelimit())
-		printk(KERN_ERR "%s: failed to update LEDs.\n",
-			wiphy_name(priv->hw->wiphy));
-
-	if (rerun)
-		queue_delayed_work(priv->hw->workqueue, &priv->led_work,
-			msecs_to_jiffies(blink_delay));
-}
-
-static void p54_led_brightness_set(struct led_classdev *led_dev,
-				   enum led_brightness brightness)
-{
-	struct p54_led_dev *led = container_of(led_dev, struct p54_led_dev,
-					       led_dev);
-	struct ieee80211_hw *dev = led->hw_dev;
-	struct p54_common *priv = dev->priv;
-
-	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
-		return ;
-
-	if (brightness) {
-		led->toggled++;
-		queue_delayed_work(priv->hw->workqueue, &priv->led_work,
-				   HZ/10);
-	}
-}
-
-static int p54_register_led(struct ieee80211_hw *dev,
-			    unsigned int led_index,
-			    char *name, char *trigger)
-{
-	struct p54_common *priv = dev->priv;
-	struct p54_led_dev *led = &priv->leds[led_index];
-	int err;
-
-	if (led->registered)
-		return -EEXIST;
-
-	snprintf(led->name, sizeof(led->name), "p54-%s::%s",
-		 wiphy_name(dev->wiphy), name);
-	led->hw_dev = dev;
-	led->index = led_index;
-	led->led_dev.name = led->name;
-	led->led_dev.default_trigger = trigger;
-	led->led_dev.brightness_set = p54_led_brightness_set;
-
-	err = led_classdev_register(wiphy_dev(dev->wiphy), &led->led_dev);
-	if (err)
-		printk(KERN_ERR "%s: Failed to register %s LED.\n",
-			wiphy_name(dev->wiphy), name);
-	else
-		led->registered = 1;
-
-	return err;
-}
-
-static int p54_init_leds(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	int err;
-
-	/*
-	 * TODO:
-	 * Figure out if the EEPROM contains some hints about the number
-	 * of available/programmable LEDs of the device.
-	 */
-
-	INIT_DELAYED_WORK(&priv->led_work, p54_update_leds);
-
-	err = p54_register_led(dev, 0, "assoc",
-			       ieee80211_get_assoc_led_name(dev));
-	if (err)
-		return err;
-
-	err = p54_register_led(dev, 1, "tx",
-			       ieee80211_get_tx_led_name(dev));
-	if (err)
-		return err;
-
-	err = p54_register_led(dev, 2, "rx",
-			       ieee80211_get_rx_led_name(dev));
-	if (err)
-		return err;
-
-	err = p54_register_led(dev, 3, "radio",
-			       ieee80211_get_radio_led_name(dev));
-	if (err)
-		return err;
-
-	err = p54_set_leds(dev);
-	return err;
-}
-
-static void p54_unregister_leds(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
-		if (priv->leds[i].registered)
-			led_classdev_unregister(&priv->leds[i].led_dev);
-}
-#endif /* CONFIG_P54_LEDS */
-
-static const struct ieee80211_ops p54_ops = {
-	.tx			= p54_tx,
-	.start			= p54_start,
-	.stop			= p54_stop,
-	.add_interface		= p54_add_interface,
-	.remove_interface	= p54_remove_interface,
-	.set_tim		= p54_set_tim,
-	.sta_notify		= p54_sta_notify,
-	.set_key		= p54_set_key,
-	.config			= p54_config,
-	.bss_info_changed	= p54_bss_info_changed,
-	.configure_filter	= p54_configure_filter,
-	.conf_tx		= p54_conf_tx,
-	.get_stats		= p54_get_stats,
-	.get_tx_stats		= p54_get_tx_stats
-};
-
-struct ieee80211_hw *p54_init_common(size_t priv_data_len)
-{
-	struct ieee80211_hw *dev;
-	struct p54_common *priv;
-
-	dev = ieee80211_alloc_hw(priv_data_len, &p54_ops);
-	if (!dev)
-		return NULL;
-
-	priv = dev->priv;
-	priv->hw = dev;
-	priv->mode = NL80211_IFTYPE_UNSPECIFIED;
-	priv->basic_rate_mask = 0x15f;
-	skb_queue_head_init(&priv->tx_queue);
-	dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-		     IEEE80211_HW_SIGNAL_DBM |
-		     IEEE80211_HW_NOISE_DBM;
-
-	dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-				      BIT(NL80211_IFTYPE_ADHOC) |
-				      BIT(NL80211_IFTYPE_AP) |
-				      BIT(NL80211_IFTYPE_MESH_POINT);
-
-	dev->channel_change_time = 1000;	/* TODO: find actual value */
-	priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
-	priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
-	priv->tx_stats[P54_QUEUE_MGMT].limit = 3;
-	priv->tx_stats[P54_QUEUE_CAB].limit = 3;
-	priv->tx_stats[P54_QUEUE_DATA].limit = 5;
-	dev->queues = 1;
-	priv->noise = -94;
-	/*
-	 * We support at most 8 tries no matter which rate they're at,
-	 * we cannot support max_rates * max_rate_tries as we set it
-	 * here, but setting it correctly to 4/2 or so would limit us
-	 * artificially if the RC algorithm wants just two rates, so
-	 * let's say 4/7, we'll redistribute it at TX time, see the
-	 * comments there.
-	 */
-	dev->max_rates = 4;
-	dev->max_rate_tries = 7;
-	dev->extra_tx_headroom = sizeof(struct p54_hdr) + 4 +
-				 sizeof(struct p54_tx_data);
-
-	mutex_init(&priv->conf_mutex);
-	init_completion(&priv->eeprom_comp);
-	INIT_DELAYED_WORK(&priv->work, p54_work);
-
-	return dev;
-}
-EXPORT_SYMBOL_GPL(p54_init_common);
-
-int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
-{
-	int err;
-
-	err = ieee80211_register_hw(dev);
-	if (err) {
-		dev_err(pdev, "Cannot register device (%d).\n", err);
-		return err;
-	}
-
-#ifdef CONFIG_P54_LEDS
-	err = p54_init_leds(dev);
-	if (err)
-		return err;
-#endif /* CONFIG_P54_LEDS */
-
-	dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
-	return 0;
-}
-EXPORT_SYMBOL_GPL(p54_register_common);
-
-void p54_free_common(struct ieee80211_hw *dev)
-{
-	struct p54_common *priv = dev->priv;
-	kfree(priv->iq_autocal);
-	kfree(priv->output_limit);
-	kfree(priv->curve_data);
-	kfree(priv->used_rxkeys);
-
-#ifdef CONFIG_P54_LEDS
-	p54_unregister_leds(dev);
-#endif /* CONFIG_P54_LEDS */
-}
-EXPORT_SYMBOL_GPL(p54_free_common);
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
deleted file mode 100644
index 75ead7a..0000000
--- a/drivers/net/wireless/p54/p54common.h
+++ /dev/null
@@ -1,644 +0,0 @@
-#ifndef P54COMMON_H
-#define P54COMMON_H
-
-/*
- * Common code specific definitions for mac80211 Prism54 drivers
- *
- * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
- * Copyright (c) 2007, Christian Lamparter <chunkeey@web.de>
- *
- * Based on:
- * - the islsm (softmac prism54) driver, which is:
- *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
- *
- * - LMAC API interface header file for STLC4560 (lmac_longbow.h)
- *   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 version 2 as
- * published by the Free Software Foundation.
- */
-
-struct bootrec {
-	__le32 code;
-	__le32 len;
-	u32 data[10];
-} __attribute__((packed));
-
-#define PDR_SYNTH_FRONTEND_MASK		0x0007
-#define PDR_SYNTH_FRONTEND_DUETTE3	0x0001
-#define PDR_SYNTH_FRONTEND_DUETTE2	0x0002
-#define PDR_SYNTH_FRONTEND_FRISBEE	0x0003
-#define PDR_SYNTH_FRONTEND_XBOW		0x0004
-#define PDR_SYNTH_FRONTEND_LONGBOW	0x0005
-#define PDR_SYNTH_IQ_CAL_MASK		0x0018
-#define PDR_SYNTH_IQ_CAL_PA_DETECTOR	0x0000
-#define PDR_SYNTH_IQ_CAL_DISABLED	0x0008
-#define PDR_SYNTH_IQ_CAL_ZIF		0x0010
-#define PDR_SYNTH_FAA_SWITCH_MASK	0x0020
-#define PDR_SYNTH_FAA_SWITCH_ENABLED	0x0020
-#define PDR_SYNTH_24_GHZ_MASK		0x0040
-#define PDR_SYNTH_24_GHZ_DISABLED	0x0040
-#define PDR_SYNTH_5_GHZ_MASK		0x0080
-#define PDR_SYNTH_5_GHZ_DISABLED	0x0080
-#define PDR_SYNTH_RX_DIV_MASK		0x0100
-#define PDR_SYNTH_RX_DIV_SUPPORTED	0x0100
-#define PDR_SYNTH_TX_DIV_MASK		0x0200
-#define PDR_SYNTH_TX_DIV_SUPPORTED	0x0200
-
-struct bootrec_exp_if {
-	__le16 role;
-	__le16 if_id;
-	__le16 variant;
-	__le16 btm_compat;
-	__le16 top_compat;
-} __attribute__((packed));
-
-#define BR_DESC_PRIV_CAP_WEP		BIT(0)
-#define BR_DESC_PRIV_CAP_TKIP		BIT(1)
-#define BR_DESC_PRIV_CAP_MICHAEL	BIT(2)
-#define BR_DESC_PRIV_CAP_CCX_CP		BIT(3)
-#define BR_DESC_PRIV_CAP_CCX_MIC	BIT(4)
-#define BR_DESC_PRIV_CAP_AESCCMP	BIT(5)
-
-struct bootrec_desc {
-	__le16 modes;
-	__le16 flags;
-	__le32 rx_start;
-	__le32 rx_end;
-	u8 headroom;
-	u8 tailroom;
-	u8 tx_queues;
-	u8 tx_depth;
-	u8 privacy_caps;
-	u8 rx_keycache_size;
-	u8 time_size;
-	u8 padding;
-	u8 rates[16];
-	u8 padding2[4];
-	__le16 rx_mtu;
-} __attribute__((packed));
-
-#define BR_CODE_MIN			0x80000000
-#define BR_CODE_COMPONENT_ID		0x80000001
-#define BR_CODE_COMPONENT_VERSION	0x80000002
-#define BR_CODE_DEPENDENT_IF		0x80000003
-#define BR_CODE_EXPOSED_IF		0x80000004
-#define BR_CODE_DESCR			0x80000101
-#define BR_CODE_MAX			0x8FFFFFFF
-#define BR_CODE_END_OF_BRA		0xFF0000FF
-#define LEGACY_BR_CODE_END_OF_BRA	0xFFFFFFFF
-
-#define P54_HDR_FLAG_DATA_ALIGN		BIT(14)
-#define P54_HDR_FLAG_DATA_OUT_PROMISC	BIT(0)
-#define P54_HDR_FLAG_DATA_OUT_TIMESTAMP BIT(1)
-#define P54_HDR_FLAG_DATA_OUT_SEQNR	BIT(2)
-#define P54_HDR_FLAG_DATA_OUT_BIT3	BIT(3)
-#define P54_HDR_FLAG_DATA_OUT_BURST	BIT(4)
-#define P54_HDR_FLAG_DATA_OUT_NOCANCEL	BIT(5)
-#define P54_HDR_FLAG_DATA_OUT_CLEARTIM	BIT(6)
-#define P54_HDR_FLAG_DATA_OUT_HITCHHIKE	BIT(7)
-#define P54_HDR_FLAG_DATA_OUT_COMPRESS	BIT(8)
-#define P54_HDR_FLAG_DATA_OUT_CONCAT	BIT(9)
-#define P54_HDR_FLAG_DATA_OUT_PCS_ACCEPT BIT(10)
-#define P54_HDR_FLAG_DATA_OUT_WAITEOSP	BIT(11)
-
-#define P54_HDR_FLAG_DATA_IN_FCS_GOOD	BIT(0)
-#define P54_HDR_FLAG_DATA_IN_MATCH_MAC	BIT(1)
-#define P54_HDR_FLAG_DATA_IN_MCBC	BIT(2)
-#define P54_HDR_FLAG_DATA_IN_BEACON	BIT(3)
-#define P54_HDR_FLAG_DATA_IN_MATCH_BSS	BIT(4)
-#define P54_HDR_FLAG_DATA_IN_BCAST_BSS	BIT(5)
-#define P54_HDR_FLAG_DATA_IN_DATA	BIT(6)
-#define P54_HDR_FLAG_DATA_IN_TRUNCATED	BIT(7)
-#define P54_HDR_FLAG_DATA_IN_BIT8	BIT(8)
-#define P54_HDR_FLAG_DATA_IN_TRANSPARENT BIT(9)
-
-/* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */
-
-struct pda_entry {
-	__le16 len;	/* includes both code and data */
-	__le16 code;
-	u8 data[0];
-} __attribute__ ((packed));
-
-struct eeprom_pda_wrap {
-	__le32 magic;
-	__le16 pad;
-	__le16 len;
-	__le32 arm_opcode;
-	u8 data[0];
-} __attribute__ ((packed));
-
-struct p54_iq_autocal_entry {
-	__le16 iq_param[4];
-} __attribute__ ((packed));
-
-struct pda_iq_autocal_entry {
-        __le16 freq;
-	struct p54_iq_autocal_entry params;
-} __attribute__ ((packed));
-
-struct pda_channel_output_limit {
-	__le16 freq;
-	u8 val_bpsk;
-	u8 val_qpsk;
-	u8 val_16qam;
-	u8 val_64qam;
-	u8 rate_set_mask;
-	u8 rate_set_size;
-} __attribute__ ((packed));
-
-struct pda_pa_curve_data_sample_rev0 {
-	u8 rf_power;
-	u8 pa_detector;
-	u8 pcv;
-} __attribute__ ((packed));
-
-struct pda_pa_curve_data_sample_rev1 {
-	u8 rf_power;
-	u8 pa_detector;
-	u8 data_barker;
-	u8 data_bpsk;
-	u8 data_qpsk;
-	u8 data_16qam;
-	u8 data_64qam;
-} __attribute__ ((packed));
-
-struct p54_pa_curve_data_sample {
-	u8 rf_power;
-	u8 pa_detector;
-	u8 data_barker;
-	u8 data_bpsk;
-	u8 data_qpsk;
-	u8 data_16qam;
-	u8 data_64qam;
-	u8 padding;
-} __attribute__ ((packed));
-
-struct pda_pa_curve_data {
-	u8 cal_method_rev;
-	u8 channels;
-	u8 points_per_channel;
-	u8 padding;
-	u8 data[0];
-} __attribute__ ((packed));
-
-struct pda_rssi_cal_entry {
-	__le16 mul;
-	__le16 add;
-} __attribute__ ((packed));
-
-struct pda_country {
-	u8 regdomain;
-	u8 alpha2[2];
-	u8 flags;
-} __attribute__ ((packed));
-
-/*
- * Warning: Longbow's structures are bogus.
- */
-struct p54_channel_output_limit_longbow {
-	__le16 rf_power_points[12];
-} __attribute__ ((packed));
-
-struct p54_pa_curve_data_sample_longbow {
-	__le16 rf_power;
-	__le16 pa_detector;
-	struct {
-		__le16 data[4];
-	} points[3] __attribute__ ((packed));
-} __attribute__ ((packed));
-
-struct pda_custom_wrapper {
-	__le16 entries;
-	__le16 entry_size;
-	__le16 offset;
-	__le16 len;
-	u8 data[0];
-} __attribute__ ((packed));
-
-/*
- * this defines the PDR codes used to build PDAs as defined in document
- * number 553155. The current implementation mirrors version 1.1 of the
- * document and lists only PDRs supported by the ARM platform.
- */
-
-/* common and choice range (0x0000 - 0x0fff) */
-#define PDR_END					0x0000
-#define PDR_MANUFACTURING_PART_NUMBER		0x0001
-#define PDR_PDA_VERSION				0x0002
-#define PDR_NIC_SERIAL_NUMBER			0x0003
-
-#define PDR_MAC_ADDRESS				0x0101
-#define PDR_REGULATORY_DOMAIN_LIST		0x0103
-#define PDR_TEMPERATURE_TYPE			0x0107
-
-#define PDR_PRISM_PCI_IDENTIFIER		0x0402
-
-/* ARM range (0x1000 - 0x1fff) */
-#define PDR_COUNTRY_INFORMATION			0x1000
-#define PDR_INTERFACE_LIST			0x1001
-#define PDR_HARDWARE_PLATFORM_COMPONENT_ID	0x1002
-#define PDR_OEM_NAME				0x1003
-#define PDR_PRODUCT_NAME			0x1004
-#define PDR_UTF8_OEM_NAME			0x1005
-#define PDR_UTF8_PRODUCT_NAME			0x1006
-#define PDR_COUNTRY_LIST			0x1007
-#define PDR_DEFAULT_COUNTRY			0x1008
-
-#define PDR_ANTENNA_GAIN			0x1100
-
-#define PDR_PRISM_INDIGO_PA_CALIBRATION_DATA	0x1901
-#define PDR_RSSI_LINEAR_APPROXIMATION		0x1902
-#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS	0x1903
-#define PDR_PRISM_PA_CAL_CURVE_DATA		0x1904
-#define PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND	0x1905
-#define PDR_PRISM_ZIF_TX_IQ_CALIBRATION		0x1906
-#define PDR_REGULATORY_POWER_LIMITS		0x1907
-#define PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED	0x1908
-#define PDR_RADIATED_TRANSMISSION_CORRECTION	0x1909
-#define PDR_PRISM_TX_IQ_CALIBRATION		0x190a
-
-/* reserved range (0x2000 - 0x7fff) */
-
-/* customer range (0x8000 - 0xffff) */
-#define PDR_BASEBAND_REGISTERS				0x8000
-#define PDR_PER_CHANNEL_BASEBAND_REGISTERS		0x8001
-
-/* used by our modificated eeprom image */
-#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM		0xDEAD
-#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM	0xBEEF
-#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM		0xB05D
-
-/* PDR definitions for default country & country list */
-#define PDR_COUNTRY_CERT_CODE		0x80
-#define PDR_COUNTRY_CERT_CODE_REAL	0x00
-#define PDR_COUNTRY_CERT_CODE_PSEUDO	0x80
-#define PDR_COUNTRY_CERT_BAND		0x40
-#define PDR_COUNTRY_CERT_BAND_2GHZ	0x00
-#define PDR_COUNTRY_CERT_BAND_5GHZ	0x40
-#define PDR_COUNTRY_CERT_IODOOR		0x30
-#define PDR_COUNTRY_CERT_IODOOR_BOTH	0x00
-#define PDR_COUNTRY_CERT_IODOOR_INDOOR	0x20
-#define PDR_COUNTRY_CERT_IODOOR_OUTDOOR	0x30
-#define PDR_COUNTRY_CERT_INDEX		0x0F
-
-struct p54_eeprom_lm86 {
-	union {
-		struct {
-			__le16 offset;
-			__le16 len;
-			u8 data[0];
-		} v1;
-		struct {
-			__le32 offset;
-			__le16 len;
-			u8 magic2;
-			u8 pad;
-			u8 magic[4];
-			u8 data[0];
-		} v2;
-	}  __attribute__ ((packed));
-} __attribute__ ((packed));
-
-enum p54_rx_decrypt_status {
-	P54_DECRYPT_NONE = 0,
-	P54_DECRYPT_OK,
-	P54_DECRYPT_NOKEY,
-	P54_DECRYPT_NOMICHAEL,
-	P54_DECRYPT_NOCKIPMIC,
-	P54_DECRYPT_FAIL_WEP,
-	P54_DECRYPT_FAIL_TKIP,
-	P54_DECRYPT_FAIL_MICHAEL,
-	P54_DECRYPT_FAIL_CKIPKP,
-	P54_DECRYPT_FAIL_CKIPMIC,
-	P54_DECRYPT_FAIL_AESCCMP
-};
-
-struct p54_rx_data {
-	__le16 flags;
-	__le16 len;
-	__le16 freq;
-	u8 antenna;
-	u8 rate;
-	u8 rssi;
-	u8 quality;
-	u8 decrypt_status;
-	u8 rssi_raw;
-	__le32 tsf32;
-	__le32 unalloc0;
-	u8 align[0];
-} __attribute__ ((packed));
-
-enum p54_trap_type {
-	P54_TRAP_SCAN = 0,
-	P54_TRAP_TIMER,
-	P54_TRAP_BEACON_TX,
-	P54_TRAP_FAA_RADIO_ON,
-	P54_TRAP_FAA_RADIO_OFF,
-	P54_TRAP_RADAR,
-	P54_TRAP_NO_BEACON,
-	P54_TRAP_TBTT,
-	P54_TRAP_SCO_ENTER,
-	P54_TRAP_SCO_EXIT
-};
-
-struct p54_trap {
-	__le16 event;
-	__le16 frequency;
-} __attribute__ ((packed));
-
-enum p54_frame_sent_status {
-	P54_TX_OK = 0,
-	P54_TX_FAILED,
-	P54_TX_PSM,
-	P54_TX_PSM_CANCELLED = 4
-};
-
-struct p54_frame_sent {
-	u8 status;
-	u8 tries;
-	u8 ack_rssi;
-	u8 quality;
-	__le16 seq;
-	u8 antenna;
-	u8 padding;
-} __attribute__ ((packed));
-
-enum p54_tx_data_crypt {
-	P54_CRYPTO_NONE = 0,
-	P54_CRYPTO_WEP,
-	P54_CRYPTO_TKIP,
-	P54_CRYPTO_TKIPMICHAEL,
-	P54_CRYPTO_CCX_WEPMIC,
-	P54_CRYPTO_CCX_KPMIC,
-	P54_CRYPTO_CCX_KP,
-	P54_CRYPTO_AESCCMP
-};
-
-enum p54_tx_data_queue {
-	P54_QUEUE_BEACON	= 0,
-	P54_QUEUE_FWSCAN	= 1,
-	P54_QUEUE_MGMT		= 2,
-	P54_QUEUE_CAB		= 3,
-	P54_QUEUE_DATA		= 4,
-
-	P54_QUEUE_AC_NUM	= 4,
-	P54_QUEUE_AC_VO		= 4,
-	P54_QUEUE_AC_VI		= 5,
-	P54_QUEUE_AC_BE		= 6,
-	P54_QUEUE_AC_BK		= 7,
-
-	/* keep last */
-	P54_QUEUE_NUM		= 8,
-};
-
-struct p54_tx_data {
-	u8 rateset[8];
-	u8 rts_rate_idx;
-	u8 crypt_offset;
-	u8 key_type;
-	u8 key_len;
-	u8 key[16];
-	u8 hw_queue;
-	u8 backlog;
-	__le16 durations[4];
-	u8 tx_antenna;
-	union {
-		struct {
-			u8 cts_rate;
-			__le16 output_power;
-		} __attribute__((packed)) longbow;
-		struct {
-			u8 output_power;
-			u8 cts_rate;
-			u8 unalloc;
-		} __attribute__ ((packed)) normal;
-	} __attribute__ ((packed));
-	u8 unalloc2[2];
-	u8 align[0];
-} __attribute__ ((packed));
-
-/* unit is ms */
-#define P54_TX_FRAME_LIFETIME 2000
-#define P54_TX_TIMEOUT 4000
-#define P54_STATISTICS_UPDATE 5000
-
-#define P54_FILTER_TYPE_NONE		0
-#define P54_FILTER_TYPE_STATION		BIT(0)
-#define P54_FILTER_TYPE_IBSS		BIT(1)
-#define P54_FILTER_TYPE_AP		BIT(2)
-#define P54_FILTER_TYPE_TRANSPARENT	BIT(3)
-#define P54_FILTER_TYPE_PROMISCUOUS	BIT(4)
-#define P54_FILTER_TYPE_HIBERNATE	BIT(5)
-#define P54_FILTER_TYPE_NOACK		BIT(6)
-#define P54_FILTER_TYPE_RX_DISABLED	BIT(7)
-
-struct p54_setup_mac {
-	__le16 mac_mode;
-	u8 mac_addr[ETH_ALEN];
-	u8 bssid[ETH_ALEN];
-	u8 rx_antenna;
-	u8 rx_align;
-	union {
-		struct {
-			__le32 basic_rate_mask;
-			u8 rts_rates[8];
-			__le32 rx_addr;
-			__le16 max_rx;
-			__le16 rxhw;
-			__le16 wakeup_timer;
-			__le16 unalloc0;
-		} v1 __attribute__ ((packed));
-		struct {
-			__le32 rx_addr;
-			__le16 max_rx;
-			__le16 rxhw;
-			__le16 timer;
-			__le16 truncate;
-			__le32 basic_rate_mask;
-			u8 sbss_offset;
-			u8 mcast_window;
-			u8 rx_rssi_threshold;
-			u8 rx_ed_threshold;
-			__le32 ref_clock;
-			__le16 lpf_bandwidth;
-			__le16 osc_start_delay;
-		} v2 __attribute__ ((packed));
-	} __attribute__ ((packed));
-} __attribute__ ((packed));
-
-#define P54_SETUP_V1_LEN 40
-#define P54_SETUP_V2_LEN (sizeof(struct p54_setup_mac))
-
-#define P54_SCAN_EXIT	BIT(0)
-#define P54_SCAN_TRAP	BIT(1)
-#define P54_SCAN_ACTIVE BIT(2)
-#define P54_SCAN_FILTER BIT(3)
-
-struct p54_scan_head {
-	__le16 mode;
-	__le16 dwell;
-	u8 scan_params[20];
-	__le16 freq;
-} __attribute__ ((packed));
-
-struct p54_scan_body {
-	u8 pa_points_per_curve;
-	u8 val_barker;
-	u8 val_bpsk;
-	u8 val_qpsk;
-	u8 val_16qam;
-	u8 val_64qam;
-	struct p54_pa_curve_data_sample curve_data[8];
-	u8 dup_bpsk;
-	u8 dup_qpsk;
-	u8 dup_16qam;
-	u8 dup_64qam;
-} __attribute__ ((packed));
-
-struct p54_scan_body_longbow {
-	struct p54_channel_output_limit_longbow power_limits;
-	struct p54_pa_curve_data_sample_longbow curve_data[8];
-	__le16 unkn[6];		/* maybe more power_limits or rate_mask */
-} __attribute__ ((packed));
-
-union p54_scan_body_union {
-	struct p54_scan_body normal;
-	struct p54_scan_body_longbow longbow;
-} __attribute__ ((packed));
-
-struct p54_scan_tail_rate {
-	__le32 basic_rate_mask;
-	u8 rts_rates[8];
-} __attribute__ ((packed));
-
-struct p54_led {
-	__le16 flags;
-	__le16 mask[2];
-	__le16 delay[2];
-} __attribute__ ((packed));
-
-struct p54_edcf {
-	u8 flags;
-	u8 slottime;
-	u8 sifs;
-	u8 eofpad;
-	struct p54_edcf_queue_param queue[8];
-	u8 mapping[4];
-	__le16 frameburst;
-	__le16 round_trip_delay;
-} __attribute__ ((packed));
-
-struct p54_statistics {
-	__le32 rx_success;
-	__le32 rx_bad_fcs;
-	__le32 rx_abort;
-	__le32 rx_abort_phy;
-	__le32 rts_success;
-	__le32 rts_fail;
-	__le32 tsf32;
-	__le32 airtime;
-	__le32 noise;
-	__le32 sample_noise[8];
-	__le32 sample_cca;
-	__le32 sample_tx;
-} __attribute__ ((packed));
-
-struct p54_xbow_synth {
-	__le16 magic1;
-	__le16 magic2;
-	__le16 freq;
-	u32 padding[5];
-} __attribute__ ((packed));
-
-struct p54_timer {
-	__le32 interval;
-} __attribute__ ((packed));
-
-struct p54_keycache {
-	u8 entry;
-	u8 key_id;
-	u8 mac[ETH_ALEN];
-	u8 padding[2];
-	u8 key_type;
-	u8 key_len;
-	u8 key[24];
-} __attribute__ ((packed));
-
-struct p54_burst {
-	u8 flags;
-	u8 queue;
-	u8 backlog;
-	u8 pad;
-	__le16 durations[32];
-} __attribute__ ((packed));
-
-struct p54_psm_interval {
-	__le16 interval;
-	__le16 periods;
-} __attribute__ ((packed));
-
-#define P54_PSM_CAM			0
-#define P54_PSM				BIT(0)
-#define P54_PSM_DTIM			BIT(1)
-#define P54_PSM_MCBC			BIT(2)
-#define P54_PSM_CHECKSUM		BIT(3)
-#define P54_PSM_SKIP_MORE_DATA		BIT(4)
-#define P54_PSM_BEACON_TIMEOUT		BIT(5)
-#define P54_PSM_HFOSLEEP		BIT(6)
-#define P54_PSM_AUTOSWITCH_SLEEP	BIT(7)
-#define P54_PSM_LPIT			BIT(8)
-#define P54_PSM_BF_UCAST_SKIP		BIT(9)
-#define P54_PSM_BF_MCAST_SKIP		BIT(10)
-
-struct p54_psm {
-	__le16 mode;
-	__le16 aid;
-	struct p54_psm_interval intervals[4];
-	u8 beacon_rssi_skip_max;
-	u8 rssi_delta_threshold;
-	u8 nr;
-	u8 exclude[1];
-} __attribute__ ((packed));
-
-#define MC_FILTER_ADDRESS_NUM 4
-
-struct p54_group_address_table {
-	__le16 filter_enable;
-	__le16 num_address;
-	u8 mac_list[MC_FILTER_ADDRESS_NUM][ETH_ALEN];
-} __attribute__ ((packed));
-
-struct p54_txcancel {
-	__le32 req_id;
-} __attribute__ ((packed));
-
-struct p54_sta_unlock {
-	u8 addr[ETH_ALEN];
-	u16 padding;
-} __attribute__ ((packed));
-
-#define P54_TIM_CLEAR BIT(15)
-struct p54_tim {
-	u8 count;
-	u8 padding[3];
-	__le16 entry[8];
-} __attribute__ ((packed));
-
-struct p54_cce_quiet {
-	__le32 period;
-} __attribute__ ((packed));
-
-struct p54_bt_balancer {
-	__le16 prio_thresh;
-	__le16 acl_thresh;
-} __attribute__ ((packed));
-
-struct p54_arp_table {
-	__le16 filter_enable;
-	u8 ipv4_addr[4];
-} __attribute__ ((packed));
-
-#endif /* P54COMMON_H */
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index b1610ea..d348c26 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -22,6 +22,7 @@
 #include <net/mac80211.h>
 
 #include "p54.h"
+#include "lmac.h"
 #include "p54pci.h"
 
 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
@@ -564,7 +565,6 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
 
  err_free_common:
 	release_firmware(priv->firmware);
-	p54_free_common(dev);
 	pci_free_consistent(pdev, sizeof(*priv->ring_control),
 			    priv->ring_control, priv->ring_control_dma);
 
@@ -573,7 +573,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
 
  err_free_dev:
 	pci_set_drvdata(pdev, NULL);
-	ieee80211_free_hw(dev);
+	p54_free_common(dev);
 
  err_free_reg:
 	pci_release_regions(pdev);
@@ -590,16 +590,15 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
 	if (!dev)
 		return;
 
-	ieee80211_unregister_hw(dev);
+	p54_unregister_common(dev);
 	priv = dev->priv;
 	release_firmware(priv->firmware);
 	pci_free_consistent(pdev, sizeof(*priv->ring_control),
 			    priv->ring_control, priv->ring_control_dma);
-	p54_free_common(dev);
 	iounmap(priv->map);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
-	ieee80211_free_hw(dev);
+	p54_free_common(dev);
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 72c7dbd..05458d9 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -34,7 +34,7 @@
 #include "p54spi_eeprom.h"
 #include "p54.h"
 
-#include "p54common.h"
+#include "lmac.h"
 
 MODULE_FIRMWARE("3826.arm");
 MODULE_ALIAS("stlc45xx");
@@ -111,15 +111,6 @@ static void p54spi_spi_write(struct p54s_priv *priv, u8 address,
 	spi_sync(priv->spi, &m);
 }
 
-static u16 p54spi_read16(struct p54s_priv *priv, u8 addr)
-{
-	__le16 val;
-
-	p54spi_spi_read(priv, addr, &val, sizeof(val));
-
-	return le16_to_cpu(val);
-}
-
 static u32 p54spi_read32(struct p54s_priv *priv, u8 addr)
 {
 	__le32 val;
@@ -139,37 +130,12 @@ static inline void p54spi_write32(struct p54s_priv *priv, u8 addr, __le32 val)
 	p54spi_spi_write(priv, addr, &val, sizeof(val));
 }
 
-struct p54spi_spi_reg {
-	u16 address;		/* __le16 ? */
-	u16 length;
-	char *name;
-};
-
-static const struct p54spi_spi_reg p54spi_registers_array[] =
-{
-	{ SPI_ADRS_ARM_INTERRUPTS,	32, "ARM_INT     " },
-	{ SPI_ADRS_ARM_INT_EN,		32, "ARM_INT_ENA " },
-	{ SPI_ADRS_HOST_INTERRUPTS,	32, "HOST_INT    " },
-	{ SPI_ADRS_HOST_INT_EN,		32, "HOST_INT_ENA" },
-	{ SPI_ADRS_HOST_INT_ACK,	32, "HOST_INT_ACK" },
-	{ SPI_ADRS_GEN_PURP_1,		32, "GP1_COMM    " },
-	{ SPI_ADRS_GEN_PURP_2,		32, "GP2_COMM    " },
-	{ SPI_ADRS_DEV_CTRL_STAT,	32, "DEV_CTRL_STA" },
-	{ SPI_ADRS_DMA_DATA,		16, "DMA_DATA    " },
-	{ SPI_ADRS_DMA_WRITE_CTRL,	16, "DMA_WR_CTRL " },
-	{ SPI_ADRS_DMA_WRITE_LEN,	16, "DMA_WR_LEN  " },
-	{ SPI_ADRS_DMA_WRITE_BASE,	32, "DMA_WR_BASE " },
-	{ SPI_ADRS_DMA_READ_CTRL,	16, "DMA_RD_CTRL " },
-	{ SPI_ADRS_DMA_READ_LEN,	16, "DMA_RD_LEN  " },
-	{ SPI_ADRS_DMA_WRITE_BASE,	32, "DMA_RD_BASE " }
-};
-
-static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits)
+static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, u32 bits)
 {
 	int i;
 
 	for (i = 0; i < 2000; i++) {
-		__le32 buffer = p54spi_read32(priv, reg);
+		u32 buffer = p54spi_read32(priv, reg);
 		if ((buffer & bits) == bits)
 			return 1;
 	}
@@ -179,8 +145,7 @@ static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits)
 static int p54spi_spi_write_dma(struct p54s_priv *priv, __le32 base,
 				const void *buf, size_t len)
 {
-	if (!p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
-			     cpu_to_le32(HOST_ALLOWED))) {
+	if (!p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL, HOST_ALLOWED)) {
 		dev_err(&priv->spi->dev, "spi_write_dma not allowed "
 			"to DMA write.\n");
 		return -EAGAIN;
@@ -333,7 +298,7 @@ static int p54spi_wakeup(struct p54s_priv *priv)
 
 	/* And wait for the READY interrupt */
 	if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
-			     cpu_to_le32(SPI_HOST_INT_READY))) {
+			     SPI_HOST_INT_READY)) {
 		dev_err(&priv->spi->dev, "INT_READY timeout\n");
 		return -EBUSY;
 	}
@@ -426,7 +391,7 @@ static irqreturn_t p54spi_interrupt(int irq, void *config)
 	struct spi_device *spi = config;
 	struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
 
-	queue_work(priv->hw->workqueue, &priv->work);
+	ieee80211_queue_work(priv->hw, &priv->work);
 
 	return IRQ_HANDLED;
 }
@@ -444,7 +409,7 @@ static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb)
 		goto out;
 
 	if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
-			     cpu_to_le32(SPI_HOST_INT_WR_READY))) {
+			     SPI_HOST_INT_WR_READY)) {
 		dev_err(&priv->spi->dev, "WR_READY timeout\n");
 		ret = -EAGAIN;
 		goto out;
@@ -514,7 +479,7 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 	list_add_tail(&di->tx_list, &priv->tx_pending);
 	spin_unlock_irqrestore(&priv->tx_lock, flags);
 
-	queue_work(priv->hw->workqueue, &priv->work);
+	ieee80211_queue_work(priv->hw, &priv->work);
 }
 
 static void p54spi_work(struct work_struct *work)
@@ -713,7 +678,7 @@ static int __devexit p54spi_remove(struct spi_device *spi)
 {
 	struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
 
-	ieee80211_unregister_hw(priv->hw);
+	p54_unregister_common(priv->hw);
 
 	free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
 
@@ -724,7 +689,6 @@ static int __devexit p54spi_remove(struct spi_device *spi)
 	mutex_destroy(&priv->mutex);
 
 	p54_free_common(priv->hw);
-	ieee80211_free_hw(priv->hw);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 0e877a1..17e1995 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -22,6 +22,7 @@
 #include <net/mac80211.h>
 
 #include "p54.h"
+#include "lmac.h"
 #include "p54usb.h"
 
 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
@@ -66,6 +67,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
 	{USB_DEVICE(0x0bf8, 0x1009)},   /* FUJITSU E-5400 USB D1700*/
 	{USB_DEVICE(0x0cde, 0x0006)},   /* Medion MD40900 */
 	{USB_DEVICE(0x0cde, 0x0008)},	/* Sagem XG703A */
+	{USB_DEVICE(0x0cde, 0x0015)},	/* Zcomax XG-705A */
 	{USB_DEVICE(0x0d8e, 0x3762)},	/* DLink DWL-G120 Cohiba */
 	{USB_DEVICE(0x124a, 0x4025)},	/* IOGear GWU513 (GW3887IK chip) */
 	{USB_DEVICE(0x1260, 0xee22)},	/* SMC 2862W-G version 2 */
@@ -245,8 +247,10 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
 	struct lm87_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
 
 	data_urb = usb_alloc_urb(0, GFP_ATOMIC);
-	if (!data_urb)
+	if (!data_urb) {
+		p54_free_skb(dev, skb);
 		return;
+	}
 
 	hdr->chksum = p54u_lm87_chksum((__le32 *)skb->data, skb->len);
 	hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id;
@@ -268,27 +272,22 @@ static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb)
 static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
 	struct p54u_priv *priv = dev->priv;
-	struct urb *int_urb, *data_urb;
+	struct urb *int_urb = NULL, *data_urb = NULL;
 	struct net2280_tx_hdr *hdr = (void *)skb->data - sizeof(*hdr);
-	struct net2280_reg_write *reg;
-	int err = 0;
+	struct net2280_reg_write *reg = NULL;
+	int err = -ENOMEM;
 
 	reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
 	if (!reg)
-		return;
+		goto out;
 
 	int_urb = usb_alloc_urb(0, GFP_ATOMIC);
-	if (!int_urb) {
-		kfree(reg);
-		return;
-	}
+	if (!int_urb)
+		goto out;
 
 	data_urb = usb_alloc_urb(0, GFP_ATOMIC);
-	if (!data_urb) {
-		kfree(reg);
-		usb_free_urb(int_urb);
-		return;
-	}
+	if (!data_urb)
+		goto out;
 
 	reg->port = cpu_to_le16(NET2280_DEV_U32);
 	reg->addr = cpu_to_le32(P54U_DEV_BASE);
@@ -303,11 +302,12 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 		p54u_tx_dummy_cb, dev);
 
 	/*
-	 * This flag triggers a code path in the USB subsystem that will
-	 * free what's inside the transfer_buffer after the callback routine
-	 * has completed.
+	 * URB_FREE_BUFFER triggers a code path in the USB subsystem that will
+	 * free what is inside the transfer_buffer after the last reference to
+	 * the int_urb is dropped.
 	 */
 	int_urb->transfer_flags |= URB_FREE_BUFFER | URB_ZERO_PACKET;
+	reg = NULL;
 
 	usb_fill_bulk_urb(data_urb, priv->udev,
 			  usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
@@ -328,12 +328,12 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb)
 		usb_unanchor_urb(data_urb);
 		goto out;
 	}
- out:
+out:
 	usb_free_urb(int_urb);
 	usb_free_urb(data_urb);
 
 	if (err) {
-		skb_pull(skb, sizeof(*hdr));
+		kfree(reg);
 		p54_free_skb(dev, skb);
 	}
 }
@@ -961,7 +961,7 @@ err_free_fw:
 	release_firmware(priv->fw);
 
 err_free_dev:
-	ieee80211_free_hw(dev);
+	p54_free_common(dev);
 	usb_set_intfdata(intf, NULL);
 	usb_put_dev(udev);
 	return err;
@@ -975,13 +975,12 @@ static void __devexit p54u_disconnect(struct usb_interface *intf)
 	if (!dev)
 		return;
 
-	ieee80211_unregister_hw(dev);
+	p54_unregister_common(dev);
 
 	priv = dev->priv;
 	usb_put_dev(interface_to_usbdev(intf));
 	release_firmware(priv->fw);
 	p54_free_common(dev);
-	ieee80211_free_hw(dev);
 }
 
 static int p54u_pre_reset(struct usb_interface *intf)
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
new file mode 100644
index 0000000..b6dda2b
--- /dev/null
+++ b/drivers/net/wireless/p54/txrx.c
@@ -0,0 +1,869 @@
+/*
+ * Common code for mac80211 Prism54 drivers
+ *
+ * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ *
+ * Based on:
+ * - the islsm (softmac prism54) driver, which is:
+ *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
+ * - stlc45xx driver
+ *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * 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/firmware.h>
+#include <linux/etherdevice.h>
+
+#include <net/mac80211.h>
+
+#include "p54.h"
+#include "lmac.h"
+
+#ifdef P54_MM_DEBUG
+static void p54_dump_tx_queue(struct p54_common *priv)
+{
+	unsigned long flags;
+	struct ieee80211_tx_info *info;
+	struct p54_tx_info *range;
+	struct sk_buff *skb;
+	struct p54_hdr *hdr;
+	unsigned int i = 0;
+	u32 prev_addr;
+	u32 largest_hole = 0, free;
+
+	spin_lock_irqsave(&priv->tx_queue.lock, flags);
+	printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) --- \n",
+	       wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue));
+
+	prev_addr = priv->rx_start;
+	skb_queue_walk(&priv->tx_queue, skb) {
+		info = IEEE80211_SKB_CB(skb);
+		range = (void *) info->rate_driver_data;
+		hdr = (void *) skb->data;
+
+		free = range->start_addr - prev_addr;
+		printk(KERN_DEBUG "%s: | [%02d] => [skb:%p skb_len:0x%04x "
+		       "hdr:{flags:%02x len:%04x req_id:%04x type:%02x} "
+		       "mem:{start:%04x end:%04x, free:%d}]\n",
+		       wiphy_name(priv->hw->wiphy), i++, skb, skb->len,
+		       le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len),
+		       le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type),
+		       range->start_addr, range->end_addr, free);
+
+		prev_addr = range->end_addr;
+		largest_hole = max(largest_hole, free);
+	}
+	free = priv->rx_end - prev_addr;
+	largest_hole = max(largest_hole, free);
+	printk(KERN_DEBUG "%s: \\ --- [free: %d], largest free block: %d ---\n",
+	       wiphy_name(priv->hw->wiphy), free, largest_hole);
+	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+}
+#endif /* P54_MM_DEBUG */
+
+/*
+ * So, the firmware is somewhat stupid and doesn't know what places in its
+ * memory incoming data should go to. By poking around in the firmware, we
+ * can find some unused memory to upload our packets to. However, data that we
+ * want the card to TX needs to stay intact until the card has told us that
+ * it is done with it. This function finds empty places we can upload to and
+ * marks allocated areas as reserved if necessary. p54_find_and_unlink_skb or
+ * p54_free_skb frees allocated areas.
+ */
+static int p54_assign_address(struct p54_common *priv, struct sk_buff *skb)
+{
+	struct sk_buff *entry, *target_skb = NULL;
+	struct ieee80211_tx_info *info;
+	struct p54_tx_info *range;
+	struct p54_hdr *data = (void *) skb->data;
+	unsigned long flags;
+	u32 last_addr = priv->rx_start;
+	u32 target_addr = priv->rx_start;
+	u16 len = priv->headroom + skb->len + priv->tailroom + 3;
+
+	info = IEEE80211_SKB_CB(skb);
+	range = (void *) info->rate_driver_data;
+	len = (range->extra_len + len) & ~0x3;
+
+	spin_lock_irqsave(&priv->tx_queue.lock, flags);
+	if (unlikely(skb_queue_len(&priv->tx_queue) == 32)) {
+		/*
+		 * The tx_queue is now really full.
+		 *
+		 * TODO: check if the device has crashed and reset it.
+		 */
+		spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+		return -EBUSY;
+	}
+
+	skb_queue_walk(&priv->tx_queue, entry) {
+		u32 hole_size;
+		info = IEEE80211_SKB_CB(entry);
+		range = (void *) info->rate_driver_data;
+		hole_size = range->start_addr - last_addr;
+
+		if (!target_skb && hole_size >= len) {
+			target_skb = entry->prev;
+			hole_size -= len;
+			target_addr = last_addr;
+			break;
+		}
+		last_addr = range->end_addr;
+	}
+	if (unlikely(!target_skb)) {
+		if (priv->rx_end - last_addr >= len) {
+			target_skb = priv->tx_queue.prev;
+			if (!skb_queue_empty(&priv->tx_queue)) {
+				info = IEEE80211_SKB_CB(target_skb);
+				range = (void *)info->rate_driver_data;
+				target_addr = range->end_addr;
+			}
+		} else {
+			spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+			return -ENOSPC;
+		}
+	}
+
+	info = IEEE80211_SKB_CB(skb);
+	range = (void *) info->rate_driver_data;
+	range->start_addr = target_addr;
+	range->end_addr = target_addr + len;
+	data->req_id = cpu_to_le32(target_addr + priv->headroom);
+	if (IS_DATA_FRAME(skb) &&
+	    unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON))
+		priv->beacon_req_id = data->req_id;
+
+	__skb_queue_after(&priv->tx_queue, target_skb, skb);
+	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+	return 0;
+}
+
+static void p54_tx_pending(struct p54_common *priv)
+{
+	struct sk_buff *skb;
+	int ret;
+
+	skb = skb_dequeue(&priv->tx_pending);
+	if (unlikely(!skb))
+		return ;
+
+	ret = p54_assign_address(priv, skb);
+	if (unlikely(ret))
+		skb_queue_head(&priv->tx_pending, skb);
+	else
+		priv->tx(priv->hw, skb);
+}
+
+static void p54_wake_queues(struct p54_common *priv)
+{
+	unsigned long flags;
+	unsigned int i;
+
+	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
+		return ;
+
+	p54_tx_pending(priv);
+
+	spin_lock_irqsave(&priv->tx_stats_lock, flags);
+	for (i = 0; i < priv->hw->queues; i++) {
+		if (priv->tx_stats[i + P54_QUEUE_DATA].len <
+		    priv->tx_stats[i + P54_QUEUE_DATA].limit)
+			ieee80211_wake_queue(priv->hw, i);
+	}
+	spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
+}
+
+static int p54_tx_qos_accounting_alloc(struct p54_common *priv,
+				       struct sk_buff *skb,
+				       const u16 p54_queue)
+{
+	struct ieee80211_tx_queue_stats *queue;
+	unsigned long flags;
+
+	if (WARN_ON(p54_queue > P54_QUEUE_NUM))
+		return -EINVAL;
+
+	queue = &priv->tx_stats[p54_queue];
+
+	spin_lock_irqsave(&priv->tx_stats_lock, flags);
+	if (unlikely(queue->len >= queue->limit && IS_QOS_QUEUE(p54_queue))) {
+		spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
+		return -ENOSPC;
+	}
+
+	queue->len++;
+	queue->count++;
+
+	if (unlikely(queue->len == queue->limit && IS_QOS_QUEUE(p54_queue))) {
+		u16 ac_queue = p54_queue - P54_QUEUE_DATA;
+		ieee80211_stop_queue(priv->hw, ac_queue);
+	}
+
+	spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
+	return 0;
+}
+
+static void p54_tx_qos_accounting_free(struct p54_common *priv,
+				       struct sk_buff *skb)
+{
+	if (IS_DATA_FRAME(skb)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&priv->tx_stats_lock, flags);
+		priv->tx_stats[GET_HW_QUEUE(skb)].len--;
+		spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
+
+		if (unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON)) {
+			if (priv->beacon_req_id == GET_REQ_ID(skb)) {
+				/* this is the  active beacon set anymore */
+				priv->beacon_req_id = 0;
+			}
+			complete(&priv->beacon_comp);
+		}
+	}
+	p54_wake_queues(priv);
+}
+
+void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+	struct p54_common *priv = dev->priv;
+	if (unlikely(!skb))
+		return ;
+
+	skb_unlink(skb, &priv->tx_queue);
+	p54_tx_qos_accounting_free(priv, skb);
+	dev_kfree_skb_any(skb);
+}
+EXPORT_SYMBOL_GPL(p54_free_skb);
+
+static struct sk_buff *p54_find_and_unlink_skb(struct p54_common *priv,
+					       const __le32 req_id)
+{
+	struct sk_buff *entry;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tx_queue.lock, flags);
+	skb_queue_walk(&priv->tx_queue, entry) {
+		struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
+
+		if (hdr->req_id == req_id) {
+			__skb_unlink(entry, &priv->tx_queue);
+			spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+			p54_tx_qos_accounting_free(priv, entry);
+			return entry;
+		}
+	}
+	spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
+	return NULL;
+}
+
+void p54_tx(struct p54_common *priv, struct sk_buff *skb)
+{
+	skb_queue_tail(&priv->tx_pending, skb);
+	p54_tx_pending(priv);
+}
+
+static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
+{
+	int band = priv->hw->conf.channel->band;
+
+	if (priv->rxhw != 5)
+		return ((rssi * priv->rssical_db[band].mul) / 64 +
+			 priv->rssical_db[band].add) / 4;
+	else
+		/*
+		 * TODO: find the correct formula
+		 */
+		return ((rssi * priv->rssical_db[band].mul) / 64 +
+			 priv->rssical_db[band].add) / 4;
+}
+
+/*
+ * Even if the firmware is capable of dealing with incoming traffic,
+ * while dozing, we have to prepared in case mac80211 uses PS-POLL
+ * to retrieve outstanding frames from our AP.
+ * (see comment in net/mac80211/mlme.c @ line 1993)
+ */
+static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr = (void *) skb->data;
+	struct ieee80211_tim_ie *tim_ie;
+	u8 *tim;
+	u8 tim_len;
+	bool new_psm;
+
+	/* only beacons have a TIM IE */
+	if (!ieee80211_is_beacon(hdr->frame_control))
+		return;
+
+	if (!priv->aid)
+		return;
+
+	/* only consider beacons from the associated BSSID */
+	if (compare_ether_addr(hdr->addr3, priv->bssid))
+		return;
+
+	tim = p54_find_ie(skb, WLAN_EID_TIM);
+	if (!tim)
+		return;
+
+	tim_len = tim[1];
+	tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+	new_psm = ieee80211_check_tim(tim_ie, tim_len, priv->aid);
+	if (new_psm != priv->powersave_override) {
+		priv->powersave_override = new_psm;
+		p54_set_ps(priv);
+	}
+}
+
+static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
+{
+	struct p54_rx_data *hdr = (struct p54_rx_data *) skb->data;
+	struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
+	u16 freq = le16_to_cpu(hdr->freq);
+	size_t header_len = sizeof(*hdr);
+	u32 tsf32;
+	u8 rate = hdr->rate & 0xf;
+
+	/*
+	 * If the device is in a unspecified state we have to
+	 * ignore all data frames. Else we could end up with a
+	 * nasty crash.
+	 */
+	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
+		return 0;
+
+	if (!(hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_IN_FCS_GOOD)))
+		return 0;
+
+	if (hdr->decrypt_status == P54_DECRYPT_OK)
+		rx_status->flag |= RX_FLAG_DECRYPTED;
+	if ((hdr->decrypt_status == P54_DECRYPT_FAIL_MICHAEL) ||
+	    (hdr->decrypt_status == P54_DECRYPT_FAIL_TKIP))
+		rx_status->flag |= RX_FLAG_MMIC_ERROR;
+
+	rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi);
+	rx_status->noise = priv->noise;
+	if (hdr->rate & 0x10)
+		rx_status->flag |= RX_FLAG_SHORTPRE;
+	if (priv->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+		rx_status->rate_idx = (rate < 4) ? 0 : rate - 4;
+	else
+		rx_status->rate_idx = rate;
+
+	rx_status->freq = freq;
+	rx_status->band =  priv->hw->conf.channel->band;
+	rx_status->antenna = hdr->antenna;
+
+	tsf32 = le32_to_cpu(hdr->tsf32);
+	if (tsf32 < priv->tsf_low32)
+		priv->tsf_high32++;
+	rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
+	priv->tsf_low32 = tsf32;
+
+	rx_status->flag |= RX_FLAG_TSFT;
+
+	if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
+		header_len += hdr->align[0];
+
+	skb_pull(skb, header_len);
+	skb_trim(skb, le16_to_cpu(hdr->len));
+	if (unlikely(priv->hw->conf.flags & IEEE80211_CONF_PS))
+		p54_pspoll_workaround(priv, skb);
+
+	ieee80211_rx_irqsafe(priv->hw, skb);
+
+	ieee80211_queue_delayed_work(priv->hw, &priv->work,
+			   msecs_to_jiffies(P54_STATISTICS_UPDATE));
+
+	return -1;
+}
+
+static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
+{
+	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+	struct p54_frame_sent *payload = (struct p54_frame_sent *) hdr->data;
+	struct ieee80211_tx_info *info;
+	struct p54_hdr *entry_hdr;
+	struct p54_tx_data *entry_data;
+	struct sk_buff *entry;
+	unsigned int pad = 0, frame_len;
+	int count, idx;
+
+	entry = p54_find_and_unlink_skb(priv, hdr->req_id);
+	if (unlikely(!entry))
+		return ;
+
+	frame_len = entry->len;
+	info = IEEE80211_SKB_CB(entry);
+	entry_hdr = (struct p54_hdr *) entry->data;
+	entry_data = (struct p54_tx_data *) entry_hdr->data;
+	priv->stats.dot11ACKFailureCount += payload->tries - 1;
+
+	/*
+	 * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
+	 * generated by the driver. Therefore tx_status is bogus
+	 * and we don't want to confuse the mac80211 stack.
+	 */
+	if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
+		dev_kfree_skb_any(entry);
+		return ;
+	}
+
+	/*
+	 * Clear manually, ieee80211_tx_info_clear_status would
+	 * clear the counts too and we need them.
+	 */
+	memset(&info->status.ampdu_ack_len, 0,
+	       sizeof(struct ieee80211_tx_info) -
+	       offsetof(struct ieee80211_tx_info, status.ampdu_ack_len));
+	BUILD_BUG_ON(offsetof(struct ieee80211_tx_info,
+			      status.ampdu_ack_len) != 23);
+
+	if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
+		pad = entry_data->align[0];
+
+	/* walk through the rates array and adjust the counts */
+	count = payload->tries;
+	for (idx = 0; idx < 4; idx++) {
+		if (count >= info->status.rates[idx].count) {
+			count -= info->status.rates[idx].count;
+		} else if (count > 0) {
+			info->status.rates[idx].count = count;
+			count = 0;
+		} else {
+			info->status.rates[idx].idx = -1;
+			info->status.rates[idx].count = 0;
+		}
+	}
+
+	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+	     (!payload->status))
+		info->flags |= IEEE80211_TX_STAT_ACK;
+	if (payload->status & P54_TX_PSM_CANCELLED)
+		info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+	info->status.ack_signal = p54_rssi_to_dbm(priv,
+						  (int)payload->ack_rssi);
+
+	/* Undo all changes to the frame. */
+	switch (entry_data->key_type) {
+	case P54_CRYPTO_TKIPMICHAEL: {
+		u8 *iv = (u8 *)(entry_data->align + pad +
+				entry_data->crypt_offset);
+
+		/* Restore the original TKIP IV. */
+		iv[2] = iv[0];
+		iv[0] = iv[1];
+		iv[1] = (iv[0] | 0x20) & 0x7f;	/* WEPSeed - 8.3.2.2 */
+
+		frame_len -= 12; /* remove TKIP_MMIC + TKIP_ICV */
+		break;
+		}
+	case P54_CRYPTO_AESCCMP:
+		frame_len -= 8; /* remove CCMP_MIC */
+		break;
+	case P54_CRYPTO_WEP:
+		frame_len -= 4; /* remove WEP_ICV */
+		break;
+	}
+
+	skb_trim(entry, frame_len);
+	skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
+	ieee80211_tx_status_irqsafe(priv->hw, entry);
+}
+
+static void p54_rx_eeprom_readback(struct p54_common *priv,
+				   struct sk_buff *skb)
+{
+	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+	struct p54_eeprom_lm86 *eeprom = (struct p54_eeprom_lm86 *) hdr->data;
+	struct sk_buff *tmp;
+
+	if (!priv->eeprom)
+		return ;
+
+	if (priv->fw_var >= 0x509) {
+		memcpy(priv->eeprom, eeprom->v2.data,
+		       le16_to_cpu(eeprom->v2.len));
+	} else {
+		memcpy(priv->eeprom, eeprom->v1.data,
+		       le16_to_cpu(eeprom->v1.len));
+	}
+
+	priv->eeprom = NULL;
+	tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
+	dev_kfree_skb_any(tmp);
+	complete(&priv->eeprom_comp);
+}
+
+static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
+{
+	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+	struct p54_statistics *stats = (struct p54_statistics *) hdr->data;
+	struct sk_buff *tmp;
+	u32 tsf32;
+
+	if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
+		return ;
+
+	tsf32 = le32_to_cpu(stats->tsf32);
+	if (tsf32 < priv->tsf_low32)
+		priv->tsf_high32++;
+	priv->tsf_low32 = tsf32;
+
+	priv->stats.dot11RTSFailureCount = le32_to_cpu(stats->rts_fail);
+	priv->stats.dot11RTSSuccessCount = le32_to_cpu(stats->rts_success);
+	priv->stats.dot11FCSErrorCount = le32_to_cpu(stats->rx_bad_fcs);
+
+	priv->noise = p54_rssi_to_dbm(priv, le32_to_cpu(stats->noise));
+
+	tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
+	dev_kfree_skb_any(tmp);
+}
+
+static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
+{
+	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+	struct p54_trap *trap = (struct p54_trap *) hdr->data;
+	u16 event = le16_to_cpu(trap->event);
+	u16 freq = le16_to_cpu(trap->frequency);
+
+	switch (event) {
+	case P54_TRAP_BEACON_TX:
+		break;
+	case P54_TRAP_RADAR:
+		printk(KERN_INFO "%s: radar (freq:%d MHz)\n",
+			wiphy_name(priv->hw->wiphy), freq);
+		break;
+	case P54_TRAP_NO_BEACON:
+		if (priv->vif)
+			ieee80211_beacon_loss(priv->vif);
+		break;
+	case P54_TRAP_SCAN:
+		break;
+	case P54_TRAP_TBTT:
+		break;
+	case P54_TRAP_TIMER:
+		break;
+	case P54_TRAP_FAA_RADIO_OFF:
+		wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+		break;
+	case P54_TRAP_FAA_RADIO_ON:
+		wiphy_rfkill_set_hw_state(priv->hw->wiphy, false);
+		break;
+	default:
+		printk(KERN_INFO "%s: received event:%x freq:%d\n",
+		       wiphy_name(priv->hw->wiphy), event, freq);
+		break;
+	}
+}
+
+static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb)
+{
+	struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
+
+	switch (le16_to_cpu(hdr->type)) {
+	case P54_CONTROL_TYPE_TXDONE:
+		p54_rx_frame_sent(priv, skb);
+		break;
+	case P54_CONTROL_TYPE_TRAP:
+		p54_rx_trap(priv, skb);
+		break;
+	case P54_CONTROL_TYPE_BBP:
+		break;
+	case P54_CONTROL_TYPE_STAT_READBACK:
+		p54_rx_stats(priv, skb);
+		break;
+	case P54_CONTROL_TYPE_EEPROM_READBACK:
+		p54_rx_eeprom_readback(priv, skb);
+		break;
+	default:
+		printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n",
+		       wiphy_name(priv->hw->wiphy), le16_to_cpu(hdr->type));
+		break;
+	}
+	return 0;
+}
+
+/* returns zero if skb can be reused */
+int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+	struct p54_common *priv = dev->priv;
+	u16 type = le16_to_cpu(*((__le16 *)skb->data));
+
+	if (type & P54_HDR_FLAG_CONTROL)
+		return p54_rx_control(priv, skb);
+	else
+		return p54_rx_data(priv, skb);
+}
+EXPORT_SYMBOL_GPL(p54_rx);
+
+static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
+				struct ieee80211_tx_info *info, u8 *queue,
+				u32 *extra_len, u16 *flags, u16 *aid,
+				bool *burst_possible)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+
+	if (ieee80211_is_data_qos(hdr->frame_control))
+		*burst_possible = true;
+	else
+		*burst_possible = false;
+
+	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
+		*flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
+
+	if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)
+		*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+
+	if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
+		*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+
+	*queue = skb_get_queue_mapping(skb) + P54_QUEUE_DATA;
+
+	switch (priv->mode) {
+	case NL80211_IFTYPE_MONITOR:
+		/*
+		 * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
+		 * every frame in promiscuous/monitor mode.
+		 * see STSW45x0C LMAC API - page 12.
+		 */
+		*aid = 0;
+		*flags |= P54_HDR_FLAG_DATA_OUT_PROMISC;
+		break;
+	case NL80211_IFTYPE_STATION:
+		*aid = 1;
+		break;
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_ADHOC:
+	case NL80211_IFTYPE_MESH_POINT:
+		if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
+			*aid = 0;
+			*queue = P54_QUEUE_CAB;
+			return;
+		}
+
+		if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+			if (ieee80211_is_probe_resp(hdr->frame_control)) {
+				*aid = 0;
+				*flags |= P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
+					  P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+				return;
+			} else if (ieee80211_is_beacon(hdr->frame_control)) {
+				*aid = 0;
+
+				if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+					/*
+					 * Injecting beacons on top of a AP is
+					 * not a good idea... nevertheless,
+					 * it should be doable.
+					 */
+
+					return;
+				}
+
+				*flags |= P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
+				*queue = P54_QUEUE_BEACON;
+				*extra_len = IEEE80211_MAX_TIM_LEN;
+				return;
+			}
+		}
+
+		if (info->control.sta)
+			*aid = info->control.sta->aid;
+		break;
+	}
+}
+
+static u8 p54_convert_algo(enum ieee80211_key_alg alg)
+{
+	switch (alg) {
+	case ALG_WEP:
+		return P54_CRYPTO_WEP;
+	case ALG_TKIP:
+		return P54_CRYPTO_TKIPMICHAEL;
+	case ALG_CCMP:
+		return P54_CRYPTO_AESCCMP;
+	default:
+		return 0;
+	}
+}
+
+int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
+{
+	struct p54_common *priv = dev->priv;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct p54_tx_info *p54info;
+	struct p54_hdr *hdr;
+	struct p54_tx_data *txhdr;
+	unsigned int padding, len, extra_len;
+	int i, j, ridx;
+	u16 hdr_flags = 0, aid = 0;
+	u8 rate, queue = 0, crypt_offset = 0;
+	u8 cts_rate = 0x20;
+	u8 rc_flags;
+	u8 calculated_tries[4];
+	u8 nrates = 0, nremaining = 8;
+	bool burst_allowed = false;
+
+	p54_tx_80211_header(priv, skb, info, &queue, &extra_len,
+			    &hdr_flags, &aid, &burst_allowed);
+
+	if (p54_tx_qos_accounting_alloc(priv, skb, queue)) {
+		if (!IS_QOS_QUEUE(queue)) {
+			dev_kfree_skb_any(skb);
+			return NETDEV_TX_OK;
+		} else {
+			return NETDEV_TX_BUSY;
+		}
+	}
+
+	padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
+	len = skb->len;
+
+	if (info->control.hw_key) {
+		crypt_offset = ieee80211_get_hdrlen_from_skb(skb);
+		if (info->control.hw_key->alg == ALG_TKIP) {
+			u8 *iv = (u8 *)(skb->data + crypt_offset);
+			/*
+			 * The firmware excepts that the IV has to have
+			 * this special format
+			 */
+			iv[1] = iv[0];
+			iv[0] = iv[2];
+			iv[2] = 0;
+		}
+	}
+
+	txhdr = (struct p54_tx_data *) skb_push(skb, sizeof(*txhdr) + padding);
+	hdr = (struct p54_hdr *) skb_push(skb, sizeof(*hdr));
+
+	if (padding)
+		hdr_flags |= P54_HDR_FLAG_DATA_ALIGN;
+	hdr->type = cpu_to_le16(aid);
+	hdr->rts_tries = info->control.rates[0].count;
+
+	/*
+	 * we register the rates in perfect order, and
+	 * RTS/CTS won't happen on 5 GHz
+	 */
+	cts_rate = info->control.rts_cts_rate_idx;
+
+	memset(&txhdr->rateset, 0, sizeof(txhdr->rateset));
+
+	/* see how many rates got used */
+	for (i = 0; i < dev->max_rates; i++) {
+		if (info->control.rates[i].idx < 0)
+			break;
+		nrates++;
+	}
+
+	/* limit tries to 8/nrates per rate */
+	for (i = 0; i < nrates; i++) {
+		/*
+		 * The magic expression here is equivalent to 8/nrates for
+		 * all values that matter, but avoids division and jumps.
+		 * Note that nrates can only take the values 1 through 4.
+		 */
+		calculated_tries[i] = min_t(int, ((15 >> nrates) | 1) + 1,
+						 info->control.rates[i].count);
+		nremaining -= calculated_tries[i];
+	}
+
+	/* if there are tries left, distribute from back to front */
+	for (i = nrates - 1; nremaining > 0 && i >= 0; i--) {
+		int tmp = info->control.rates[i].count - calculated_tries[i];
+
+		if (tmp <= 0)
+			continue;
+		/* RC requested more tries at this rate */
+
+		tmp = min_t(int, tmp, nremaining);
+		calculated_tries[i] += tmp;
+		nremaining -= tmp;
+	}
+
+	ridx = 0;
+	for (i = 0; i < nrates && ridx < 8; i++) {
+		/* we register the rates in perfect order */
+		rate = info->control.rates[i].idx;
+		if (info->band == IEEE80211_BAND_5GHZ)
+			rate += 4;
+
+		/* store the count we actually calculated for TX status */
+		info->control.rates[i].count = calculated_tries[i];
+
+		rc_flags = info->control.rates[i].flags;
+		if (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) {
+			rate |= 0x10;
+			cts_rate |= 0x10;
+		}
+		if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+			burst_allowed = false;
+			rate |= 0x40;
+		} else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+			rate |= 0x20;
+			burst_allowed = false;
+		}
+		for (j = 0; j < calculated_tries[i] && ridx < 8; j++) {
+			txhdr->rateset[ridx] = rate;
+			ridx++;
+		}
+	}
+
+	if (burst_allowed)
+		hdr_flags |= P54_HDR_FLAG_DATA_OUT_BURST;
+
+	/* TODO: enable bursting */
+	hdr->flags = cpu_to_le16(hdr_flags);
+	hdr->tries = ridx;
+	txhdr->rts_rate_idx = 0;
+	if (info->control.hw_key) {
+		txhdr->key_type = p54_convert_algo(info->control.hw_key->alg);
+		txhdr->key_len = min((u8)16, info->control.hw_key->keylen);
+		memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len);
+		if (info->control.hw_key->alg == ALG_TKIP) {
+			/* reserve space for the MIC key */
+			len += 8;
+			memcpy(skb_put(skb, 8), &(info->control.hw_key->key
+				[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]), 8);
+		}
+		/* reserve some space for ICV */
+		len += info->control.hw_key->icv_len;
+		memset(skb_put(skb, info->control.hw_key->icv_len), 0,
+		       info->control.hw_key->icv_len);
+	} else {
+		txhdr->key_type = 0;
+		txhdr->key_len = 0;
+	}
+	txhdr->crypt_offset = crypt_offset;
+	txhdr->hw_queue = queue;
+	txhdr->backlog = priv->tx_stats[queue].len - 1;
+	memset(txhdr->durations, 0, sizeof(txhdr->durations));
+	txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ?
+		2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask;
+	if (priv->rxhw == 5) {
+		txhdr->longbow.cts_rate = cts_rate;
+		txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
+	} else {
+		txhdr->normal.output_power = priv->output_power;
+		txhdr->normal.cts_rate = cts_rate;
+	}
+	if (padding)
+		txhdr->align[0] = padding;
+
+	hdr->len = cpu_to_le16(len);
+	/* modifies skb->cb and with it info, so must be last! */
+	p54info = (void *) info->rate_driver_data;
+	p54info->extra_len = extra_len;
+
+	p54_tx(priv, skb);
+	return NETDEV_TX_OK;
+}
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 8f62109..872b647 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -50,7 +50,7 @@ islpci_eth_cleanup_transmit(islpci_private *priv,
 
 		/* check for holes in the arrays caused by multi fragment frames
 		 * searching for the last fragment of a frame */
-		if (priv->pci_map_tx_address[index] != (dma_addr_t) NULL) {
+		if (priv->pci_map_tx_address[index]) {
 			/* entry is the last fragment of a frame
 			 * free the skb structure and unmap pci memory */
 			skb = priv->data_low_tx[index];
@@ -72,7 +72,7 @@ islpci_eth_cleanup_transmit(islpci_private *priv,
 	}
 }
 
-int
+netdev_tx_t
 islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
 {
 	islpci_private *priv = netdev_priv(ndev);
@@ -234,7 +234,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
 	/* unlock the driver code */
 	spin_unlock_irqrestore(&priv->slock, flags);
 
-	return 0;
+	return NETDEV_TX_OK;
 
       drop_free:
 	ndev->stats.tx_dropped++;
@@ -450,7 +450,7 @@ islpci_eth_receive(islpci_private *priv)
 		    pci_map_single(priv->pdev, (void *) skb->data,
 				   MAX_FRAGMENT_SIZE_RX + 2,
 				   PCI_DMA_FROMDEVICE);
-		if (unlikely(priv->pci_map_rx_address[index] == (dma_addr_t) NULL)) {
+		if (unlikely(!priv->pci_map_rx_address[index])) {
 			/* error mapping the buffer to device accessable memory address */
 			DEBUG(SHOW_ERROR_MESSAGES,
 			      "Error mapping DMA address\n");
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
index 61454d3..54f9a4b 100644
--- a/drivers/net/wireless/prism54/islpci_eth.h
+++ b/drivers/net/wireless/prism54/islpci_eth.h
@@ -64,7 +64,7 @@ struct avs_80211_1_header {
 };
 
 void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *);
-int islpci_eth_transmit(struct sk_buff *, struct net_device *);
+netdev_tx_t islpci_eth_transmit(struct sk_buff *, struct net_device *);
 int islpci_eth_receive(islpci_private *);
 void islpci_eth_tx_timeout(struct net_device *);
 void islpci_do_reset_and_wake(struct work_struct *);
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index 3087672..83d3662 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -49,9 +49,7 @@ static const struct pci_device_id prism54_id_tbl[] = {
 
 	/* 3COM 3CRWE154G72 Wireless LAN adapter */
 	{
-	 0x10b7, 0x6001,
-	 PCI_ANY_ID, PCI_ANY_ID,
-	 0, 0, 0
+	 PCI_VDEVICE(3COM, 0x6001), 0
 	},
 
 	/* Intersil PRISM Indigo Wireless LAN adapter */
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 698b11b..88cd58e 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -104,7 +104,8 @@ static int ray_dev_init(struct net_device *dev);
 static const struct ethtool_ops netdev_ethtool_ops;
 
 static int ray_open(struct net_device *dev);
-static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
 static void ray_update_multi_list(struct net_device *dev, int all);
 static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
@@ -915,16 +916,19 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map)
 }
 
 /*===========================================================================*/
-static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
 	ray_dev_t *local = netdev_priv(dev);
 	struct pcmcia_device *link = local->finder;
 	short length = skb->len;
 
-	if (!(pcmcia_dev_present(link))) {
+	if (!pcmcia_dev_present(link)) {
 		DEBUG(2, "ray_dev_start_xmit - device not present\n");
-		return NETDEV_TX_LOCKED;
+		dev_kfree_skb(skb);
+		return NETDEV_TX_OK;
 	}
+
 	DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
 	if (local->authentication_state == NEED_TO_AUTH) {
 		DEBUG(0, "ray_cs Sending authentication request.\n");
@@ -937,7 +941,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 	switch (ray_hw_xmit(skb->data, length, dev, DATA_TYPE)) {
@@ -951,9 +955,9 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	default:
 		dev->trans_start = jiffies;
 		dev_kfree_skb(skb);
-		return 0;
 	}
-	return 0;
+
+	return NETDEV_TX_OK;
 } /* ray_dev_start_xmit */
 
 /*===========================================================================*/
@@ -1511,9 +1515,6 @@ static iw_stats *ray_get_wireless_stats(struct net_device *dev)
 	struct pcmcia_device *link = local->finder;
 	struct status __iomem *p = local->sram + STATUS_BASE;
 
-	if (local == (ray_dev_t *) NULL)
-		return (iw_stats *) NULL;
-
 	local->wstats.status = local->card_status;
 #ifdef WIRELESS_SPY
 	if ((local->spy_data.spy_number > 0)
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 3bec3db..54175b6 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -100,7 +100,6 @@ MODULE_PARM_DESC(workaround_interval,
 #define OID_GEN_RCV_ERROR			cpu_to_le32(0x00020104)
 #define OID_GEN_RCV_NO_BUFFER			cpu_to_le32(0x00020105)
 
-#define OID_802_3_PERMANENT_ADDRESS		cpu_to_le32(0x01010101)
 #define OID_802_3_CURRENT_ADDRESS		cpu_to_le32(0x01010102)
 #define OID_802_3_MULTICAST_LIST		cpu_to_le32(0x01010103)
 #define OID_802_3_MAXIMUM_LIST_SIZE		cpu_to_le32(0x01010104)
@@ -139,9 +138,15 @@ MODULE_PARM_DESC(workaround_interval,
 /* Assume that Broadcom 4320 (only chipset at time of writing known to be
  * based on wireless rndis) has default txpower of 13dBm.
  * This value is from Linksys WUSB54GSC User Guide, Appendix F: Specifications.
- *   13dBm == 19.9mW
+ *  100% : 20 mW ~ 13dBm
+ *   75% : 15 mW ~ 12dBm
+ *   50% : 10 mW ~ 10dBm
+ *   25% :  5 mW ~  7dBm
  */
-#define BCM4320_DEFAULT_TXPOWER 20
+#define BCM4320_DEFAULT_TXPOWER_DBM_100 13
+#define BCM4320_DEFAULT_TXPOWER_DBM_75  12
+#define BCM4320_DEFAULT_TXPOWER_DBM_50  10
+#define BCM4320_DEFAULT_TXPOWER_DBM_25  7
 
 
 /* codes for "status" field of completion messages */
@@ -196,6 +201,24 @@ enum ndis_80211_priv_filter {
 	NDIS_80211_PRIV_8021X_WEP
 };
 
+enum ndis_80211_status_type {
+	NDIS_80211_STATUSTYPE_AUTHENTICATION,
+	NDIS_80211_STATUSTYPE_MEDIASTREAMMODE,
+	NDIS_80211_STATUSTYPE_PMKID_CANDIDATELIST,
+	NDIS_80211_STATUSTYPE_RADIOSTATE,
+};
+
+enum ndis_80211_media_stream_mode {
+	NDIS_80211_MEDIA_STREAM_OFF,
+	NDIS_80211_MEDIA_STREAM_ON
+};
+
+enum ndis_80211_radio_status {
+	NDIS_80211_RADIO_STATUS_ON,
+	NDIS_80211_RADIO_STATUS_HARDWARE_OFF,
+	NDIS_80211_RADIO_STATUS_SOFTWARE_OFF,
+};
+
 enum ndis_80211_addkey_bits {
 	NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28),
 	NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29),
@@ -208,6 +231,35 @@ enum ndis_80211_addwep_bits {
 	NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
 };
 
+struct ndis_80211_auth_request {
+	__le32 length;
+	u8 bssid[6];
+	u8 padding[2];
+	__le32 flags;
+} __attribute__((packed));
+
+struct ndis_80211_pmkid_candidate {
+	u8 bssid[6];
+	u8 padding[2];
+	__le32 flags;
+} __attribute__((packed));
+
+struct ndis_80211_pmkid_cand_list {
+	__le32 version;
+	__le32 num_candidates;
+	struct ndis_80211_pmkid_candidate candidate_list[0];
+} __attribute__((packed));
+
+struct ndis_80211_status_indication {
+	__le32 status_type;
+	union {
+		__le32					media_stream_mode;
+		__le32					radio_status;
+		struct ndis_80211_auth_request		auth_request[0];
+		struct ndis_80211_pmkid_cand_list	cand_list;
+	} u;
+} __attribute__((packed));
+
 struct ndis_80211_ssid {
 	__le32 length;
 	u8 essid[NDIS_802_11_LENGTH_SSID];
@@ -275,6 +327,7 @@ struct ndis_80211_remove_key {
 	__le32 size;
 	__le32 index;
 	u8 bssid[6];
+	u8 padding[2];
 } __attribute__((packed));
 
 struct ndis_config_param {
@@ -305,13 +358,6 @@ struct ndis_80211_assoc_info {
 	__le32 offset_resp_ies;
 } __attribute__((packed));
 
-/* these have to match what is in wpa_supplicant */
-enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP };
-enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
-		  CIPHER_WEP104 };
-enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
-		    KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE };
-
 /*
  *  private data
  */
@@ -326,6 +372,15 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
 #define WORK_LINK_DOWN		(1<<1)
 #define WORK_SET_MULTICAST_LIST	(1<<2)
 
+#define RNDIS_WLAN_ALG_NONE	0
+#define RNDIS_WLAN_ALG_WEP	(1<<0)
+#define RNDIS_WLAN_ALG_TKIP	(1<<1)
+#define RNDIS_WLAN_ALG_CCMP	(1<<2)
+
+#define RNDIS_WLAN_KEY_MGMT_NONE	0
+#define RNDIS_WLAN_KEY_MGMT_802_1X	(1<<0)
+#define RNDIS_WLAN_KEY_MGMT_PSK		(1<<1)
+
 #define COMMAND_BUFFER_SIZE	(CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
 
 static const struct ieee80211_channel rndis_channels[] = {
@@ -360,6 +415,22 @@ static const struct ieee80211_rate rndis_rates[] = {
 	{ .bitrate = 540 }
 };
 
+static const u32 rndis_cipher_suites[] = {
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+	WLAN_CIPHER_SUITE_CCMP,
+};
+
+struct rndis_wlan_encr_key {
+	int len;
+	u32 cipher;
+	u8 material[32];
+	u8 bssid[ETH_ALEN];
+	bool pairwise;
+	bool tx_key;
+};
+
 /* RNDIS device private data */
 struct rndis_wlan_private {
 	struct usbnet *usbdev;
@@ -369,19 +440,17 @@ struct rndis_wlan_private {
 	struct cfg80211_scan_request *scan_request;
 
 	struct workqueue_struct *workqueue;
-	struct delayed_work stats_work;
+	struct delayed_work dev_poller_work;
 	struct delayed_work scan_work;
 	struct work_struct work;
 	struct mutex command_lock;
-	spinlock_t stats_lock;
 	unsigned long work_pending;
+	int last_qual;
 
 	struct ieee80211_supported_band band;
 	struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
 	struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
-
-	struct iw_statistics iwstats;
-	struct iw_statistics privstats;
+	u32 cipher_suites[ARRAY_SIZE(rndis_cipher_suites)];
 
 	int caps;
 	int multicast_size;
@@ -397,18 +466,19 @@ struct rndis_wlan_private {
 	u32  param_workaround_interval;
 
 	/* hardware state */
-	int radio_on;
+	bool radio_on;
 	int infra_mode;
+	bool connected;
+	u8 bssid[ETH_ALEN];
 	struct ndis_80211_ssid essid;
+	__le32 current_command_oid;
 
 	/* encryption stuff */
 	int  encr_tx_key_index;
-	char encr_keys[4][32];
-	int  encr_key_len[4];
-	char encr_key_wpa[4];
+	struct rndis_wlan_encr_key encr_keys[4];
+	enum nl80211_auth_type wpa_auth_type;
 	int  wpa_version;
 	int  wpa_keymgmt;
-	int  wpa_authalg;
 	int  wpa_ie_len;
 	u8  *wpa_ie;
 	int  wpa_cipher_pair;
@@ -420,39 +490,186 @@ struct rndis_wlan_private {
 /*
  * cfg80211 ops
  */
-static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+static int rndis_change_virtual_intf(struct wiphy *wiphy,
+					struct net_device *dev,
 					enum nl80211_iftype type, u32 *flags,
 					struct vif_params *params);
 
 static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
 			struct cfg80211_scan_request *request);
 
+static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed);
+
+static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
+				int dbm);
+static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm);
+
+static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
+				struct cfg80211_connect_params *sme);
+
+static int rndis_disconnect(struct wiphy *wiphy, struct net_device *dev,
+				u16 reason_code);
+
+static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+					struct cfg80211_ibss_params *params);
+
+static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev);
+
+static int rndis_set_channel(struct wiphy *wiphy,
+	struct ieee80211_channel *chan, enum nl80211_channel_type channel_type);
+
+static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
+					u8 key_index, const u8 *mac_addr,
+					struct key_params *params);
+
+static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
+					u8 key_index, const u8 *mac_addr);
+
+static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
+								u8 key_index);
+
+static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
+					u8 *mac, struct station_info *sinfo);
+
+static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
+			       int idx, u8 *mac, struct station_info *sinfo);
+
 static struct cfg80211_ops rndis_config_ops = {
 	.change_virtual_intf = rndis_change_virtual_intf,
 	.scan = rndis_scan,
+	.set_wiphy_params = rndis_set_wiphy_params,
+	.set_tx_power = rndis_set_tx_power,
+	.get_tx_power = rndis_get_tx_power,
+	.connect = rndis_connect,
+	.disconnect = rndis_disconnect,
+	.join_ibss = rndis_join_ibss,
+	.leave_ibss = rndis_leave_ibss,
+	.set_channel = rndis_set_channel,
+	.add_key = rndis_add_key,
+	.del_key = rndis_del_key,
+	.set_default_key = rndis_set_default_key,
+	.get_station = rndis_get_station,
+	.dump_station = rndis_dump_station,
 };
 
 static void *rndis_wiphy_privid = &rndis_wiphy_privid;
 
-static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
-
-static const unsigned char zero_bssid[ETH_ALEN] = {0,};
-static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
-							0xff, 0xff, 0xff };
-
 
 static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
 {
 	return (struct rndis_wlan_private *)dev->driver_priv;
 }
 
+static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
+{
+	switch (priv->param_power_output) {
+	default:
+	case 3:
+		return BCM4320_DEFAULT_TXPOWER_DBM_100;
+	case 2:
+		return BCM4320_DEFAULT_TXPOWER_DBM_75;
+	case 1:
+		return BCM4320_DEFAULT_TXPOWER_DBM_50;
+	case 0:
+		return BCM4320_DEFAULT_TXPOWER_DBM_25;
+	}
+}
 
-static u32 get_bcm4320_power(struct rndis_wlan_private *priv)
+static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
 {
-	return BCM4320_DEFAULT_TXPOWER *
-		bcm4320_power_output[priv->param_power_output] / 100;
+	int cipher = priv->encr_keys[idx].cipher;
+
+	return (cipher == WLAN_CIPHER_SUITE_CCMP ||
+		cipher == WLAN_CIPHER_SUITE_TKIP);
 }
 
+static int rndis_cipher_to_alg(u32 cipher)
+{
+	switch (cipher) {
+	default:
+		return RNDIS_WLAN_ALG_NONE;
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		return RNDIS_WLAN_ALG_WEP;
+	case WLAN_CIPHER_SUITE_TKIP:
+		return RNDIS_WLAN_ALG_TKIP;
+	case WLAN_CIPHER_SUITE_CCMP:
+		return RNDIS_WLAN_ALG_CCMP;
+	}
+}
+
+static int rndis_akm_suite_to_key_mgmt(u32 akm_suite)
+{
+	switch (akm_suite) {
+	default:
+		return RNDIS_WLAN_KEY_MGMT_NONE;
+	case WLAN_AKM_SUITE_8021X:
+		return RNDIS_WLAN_KEY_MGMT_802_1X;
+	case WLAN_AKM_SUITE_PSK:
+		return RNDIS_WLAN_KEY_MGMT_PSK;
+	}
+}
+
+#ifdef DEBUG
+static const char *oid_to_string(__le32 oid)
+{
+	switch (oid) {
+#define OID_STR(oid) case oid: return(#oid)
+		/* from rndis_host.h */
+		OID_STR(OID_802_3_PERMANENT_ADDRESS);
+		OID_STR(OID_GEN_MAXIMUM_FRAME_SIZE);
+		OID_STR(OID_GEN_CURRENT_PACKET_FILTER);
+		OID_STR(OID_GEN_PHYSICAL_MEDIUM);
+
+		/* from rndis_wlan.c */
+		OID_STR(OID_GEN_LINK_SPEED);
+		OID_STR(OID_GEN_RNDIS_CONFIG_PARAMETER);
+
+		OID_STR(OID_GEN_XMIT_OK);
+		OID_STR(OID_GEN_RCV_OK);
+		OID_STR(OID_GEN_XMIT_ERROR);
+		OID_STR(OID_GEN_RCV_ERROR);
+		OID_STR(OID_GEN_RCV_NO_BUFFER);
+
+		OID_STR(OID_802_3_CURRENT_ADDRESS);
+		OID_STR(OID_802_3_MULTICAST_LIST);
+		OID_STR(OID_802_3_MAXIMUM_LIST_SIZE);
+
+		OID_STR(OID_802_11_BSSID);
+		OID_STR(OID_802_11_SSID);
+		OID_STR(OID_802_11_INFRASTRUCTURE_MODE);
+		OID_STR(OID_802_11_ADD_WEP);
+		OID_STR(OID_802_11_REMOVE_WEP);
+		OID_STR(OID_802_11_DISASSOCIATE);
+		OID_STR(OID_802_11_AUTHENTICATION_MODE);
+		OID_STR(OID_802_11_PRIVACY_FILTER);
+		OID_STR(OID_802_11_BSSID_LIST_SCAN);
+		OID_STR(OID_802_11_ENCRYPTION_STATUS);
+		OID_STR(OID_802_11_ADD_KEY);
+		OID_STR(OID_802_11_REMOVE_KEY);
+		OID_STR(OID_802_11_ASSOCIATION_INFORMATION);
+		OID_STR(OID_802_11_PMKID);
+		OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED);
+		OID_STR(OID_802_11_NETWORK_TYPE_IN_USE);
+		OID_STR(OID_802_11_TX_POWER_LEVEL);
+		OID_STR(OID_802_11_RSSI);
+		OID_STR(OID_802_11_RSSI_TRIGGER);
+		OID_STR(OID_802_11_FRAGMENTATION_THRESHOLD);
+		OID_STR(OID_802_11_RTS_THRESHOLD);
+		OID_STR(OID_802_11_SUPPORTED_RATES);
+		OID_STR(OID_802_11_CONFIGURATION);
+		OID_STR(OID_802_11_BSSID_LIST);
+#undef OID_STR
+	}
+
+	return "?";
+}
+#else
+static const char *oid_to_string(__le32 oid)
+{
+	return "?";
+}
+#endif
 
 /* translate error code */
 static int rndis_error_status(__le32 rndis_status)
@@ -477,7 +694,6 @@ static int rndis_error_status(__le32 rndis_status)
 	return ret;
 }
 
-
 static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
@@ -508,12 +724,25 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
 	u.get->msg_len = cpu_to_le32(sizeof *u.get);
 	u.get->oid = oid;
 
+	priv->current_command_oid = oid;
 	ret = rndis_command(dev, u.header, buflen);
+	priv->current_command_oid = 0;
+	if (ret < 0)
+		devdbg(dev, "rndis_query_oid(%s): rndis_command() failed, %d "
+			"(%08x)", oid_to_string(oid), ret,
+			le32_to_cpu(u.get_c->status));
+
 	if (ret == 0) {
 		ret = le32_to_cpu(u.get_c->len);
-		*len = (*len > ret) ? ret : *len;
+		if (ret > *len)
+			*len = ret;
 		memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
 		ret = rndis_error_status(u.get_c->status);
+
+		if (ret < 0)
+			devdbg(dev, "rndis_query_oid(%s): device returned "
+				"error,  0x%08x (%d)", oid_to_string(oid),
+				le32_to_cpu(u.get_c->status), ret);
 	}
 
 	mutex_unlock(&priv->command_lock);
@@ -523,7 +752,6 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
 	return ret;
 }
 
-
 static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
@@ -558,10 +786,23 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
 	u.set->handle = cpu_to_le32(0);
 	memcpy(u.buf + sizeof(*u.set), data, len);
 
+	priv->current_command_oid = oid;
 	ret = rndis_command(dev, u.header, buflen);
-	if (ret == 0)
+	priv->current_command_oid = 0;
+	if (ret < 0)
+		devdbg(dev, "rndis_set_oid(%s): rndis_command() failed, %d "
+			"(%08x)", oid_to_string(oid), ret,
+			le32_to_cpu(u.set_c->status));
+
+	if (ret == 0) {
 		ret = rndis_error_status(u.set_c->status);
 
+		if (ret < 0)
+			devdbg(dev, "rndis_set_oid(%s): device returned error, "
+				"0x%08x (%d)", oid_to_string(oid),
+				le32_to_cpu(u.set_c->status), ret);
+	}
+
 	mutex_unlock(&priv->command_lock);
 
 	if (u.buf != priv->command_buffer)
@@ -569,6 +810,27 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
 	return ret;
 }
 
+static int rndis_reset(struct usbnet *usbdev)
+{
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	struct rndis_reset *reset;
+	int ret;
+
+	mutex_lock(&priv->command_lock);
+
+	reset = (void *)priv->command_buffer;
+	memset(reset, 0, sizeof(*reset));
+	reset->msg_type = RNDIS_MSG_RESET;
+	reset->msg_len = cpu_to_le32(sizeof(*reset));
+	priv->current_command_oid = 0;
+	ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE);
+
+	mutex_unlock(&priv->command_lock);
+
+	if (ret < 0)
+		return ret;
+	return 0;
+}
 
 /*
  * Specs say that we can only set config parameters only soon after device
@@ -656,16 +918,9 @@ static int rndis_set_config_parameter(struct usbnet *dev, char *param,
 static int rndis_set_config_parameter_str(struct usbnet *dev,
 						char *param, char *value)
 {
-	return(rndis_set_config_parameter(dev, param, 2, value));
+	return rndis_set_config_parameter(dev, param, 2, value);
 }
 
-/*static int rndis_set_config_parameter_u32(struct usbnet *dev,
-						char *param, u32 value)
-{
-	return(rndis_set_config_parameter(dev, param, 0, &value));
-}*/
-
-
 /*
  * data conversion functions
  */
@@ -675,91 +930,51 @@ static int level_to_qual(int level)
 	return qual >= 0 ? (qual <= 100 ? qual : 100) : 0;
 }
 
-
-static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq)
-{
-	freq->e = 0;
-	freq->i = 0;
-	freq->flags = 0;
-
-	/* see comment in wireless.h above the "struct iw_freq"
-	 * definition for an explanation of this if
-	 * NOTE: 1000000 is due to the kHz
-	 */
-	if (dsconfig > 1000000) {
-		freq->m = dsconfig / 10;
-		freq->e = 1;
-	} else
-		freq->m = dsconfig;
-
-	/* convert from kHz to Hz */
-	freq->e += 3;
-}
-
-
-static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
-{
-	if (freq->m < 1000 && freq->e == 0) {
-		if (freq->m >= 1 && freq->m <= 14)
-			*dsconfig = ieee80211_dsss_chan_to_freq(freq->m) * 1000;
-		else
-			return -1;
-	} else {
-		int i;
-		*dsconfig = freq->m;
-		for (i = freq->e; i > 0; i--)
-			*dsconfig *= 10;
-		*dsconfig /= 1000;
-	}
-
-	return 0;
-}
-
-
 /*
  * common functions
  */
-static int
-add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index);
+static int set_infra_mode(struct usbnet *usbdev, int mode);
+static void restore_keys(struct usbnet *usbdev);
+static int rndis_check_bssid_list(struct usbnet *usbdev);
 
-static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
+static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
 {
-	int ret, len;
-
-	len = sizeof(*ssid);
-	ret = rndis_query_oid(usbdev, OID_802_11_SSID, ssid, &len);
-
-	if (ret != 0)
-		ssid->length = 0;
-
-#ifdef DEBUG
-	{
-		unsigned char tmp[NDIS_802_11_LENGTH_SSID + 1];
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	int ret;
 
-		memcpy(tmp, ssid->essid, le32_to_cpu(ssid->length));
-		tmp[le32_to_cpu(ssid->length)] = 0;
-		devdbg(usbdev, "get_essid: '%s', ret: %d", tmp, ret);
+	ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
+	if (ret < 0) {
+		devwarn(usbdev, "setting SSID failed (%08X)", ret);
+		return ret;
 	}
-#endif
+	if (ret == 0) {
+		memcpy(&priv->essid, ssid, sizeof(priv->essid));
+		priv->radio_on = true;
+		devdbg(usbdev, "set_essid: radio_on = true");
+	}
+
 	return ret;
 }
 
-
-static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
+static int set_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
 {
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	int ret;
 
-	ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
-	if (ret == 0) {
-		memcpy(&priv->essid, ssid, sizeof(priv->essid));
-		priv->radio_on = 1;
-		devdbg(usbdev, "set_essid: radio_on = 1");
+	ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
+	if (ret < 0) {
+		devwarn(usbdev, "setting BSSID[%pM] failed (%08X)", bssid, ret);
+		return ret;
 	}
 
 	return ret;
 }
 
+static int clear_bssid(struct usbnet *usbdev)
+{
+	u8 broadcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+	return set_bssid(usbdev, broadcast_mac);
+}
 
 static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN])
 {
@@ -781,18 +996,21 @@ static int get_association_info(struct usbnet *usbdev,
 				info, &len);
 }
 
-static int is_associated(struct usbnet *usbdev)
+static bool is_associated(struct usbnet *usbdev)
 {
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	u8 bssid[ETH_ALEN];
 	int ret;
 
+	if (!priv->radio_on)
+		return false;
+
 	ret = get_bssid(usbdev, bssid);
 
-	return(ret == 0 && memcmp(bssid, zero_bssid, ETH_ALEN) != 0);
+	return (ret == 0 && !is_zero_ether_addr(bssid));
 }
 
-
-static int disassociate(struct usbnet *usbdev, int reset_ssid)
+static int disassociate(struct usbnet *usbdev, bool reset_ssid)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	struct ndis_80211_ssid ssid;
@@ -801,8 +1019,8 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
 	if (priv->radio_on) {
 		ret = rndis_set_oid(usbdev, OID_802_11_DISASSOCIATE, NULL, 0);
 		if (ret == 0) {
-			priv->radio_on = 0;
-			devdbg(usbdev, "disassociate: radio_on = 0");
+			priv->radio_on = false;
+			devdbg(usbdev, "disassociate: radio_on = false");
 
 			if (reset_ssid)
 				msleep(100);
@@ -812,6 +1030,11 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
 	/* disassociate causes radio to be turned off; if reset_ssid
 	 * is given, set random ssid to enable radio */
 	if (reset_ssid) {
+		/* Set device to infrastructure mode so we don't get ad-hoc
+		 * 'media connect' indications with the random ssid.
+		 */
+		set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
+
 		ssid.length = cpu_to_le32(sizeof(ssid.essid));
 		get_random_bytes(&ssid.essid[2], sizeof(ssid.essid)-2);
 		ssid.essid[0] = 0x1;
@@ -823,35 +1046,34 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
 	return ret;
 }
 
-
-static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
+static int set_auth_mode(struct usbnet *usbdev, u32 wpa_version,
+				enum nl80211_auth_type auth_type, int keymgmt)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	__le32 tmp;
 	int auth_mode, ret;
 
 	devdbg(usbdev, "set_auth_mode: wpa_version=0x%x authalg=0x%x "
-		"keymgmt=0x%x", wpa_version, authalg, priv->wpa_keymgmt);
+		"keymgmt=0x%x", wpa_version, auth_type, keymgmt);
 
-	if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
-		if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
+	if (wpa_version & NL80211_WPA_VERSION_2) {
+		if (keymgmt & RNDIS_WLAN_KEY_MGMT_802_1X)
 			auth_mode = NDIS_80211_AUTH_WPA2;
 		else
 			auth_mode = NDIS_80211_AUTH_WPA2_PSK;
-	} else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
-		if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
+	} else if (wpa_version & NL80211_WPA_VERSION_1) {
+		if (keymgmt & RNDIS_WLAN_KEY_MGMT_802_1X)
 			auth_mode = NDIS_80211_AUTH_WPA;
-		else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
+		else if (keymgmt & RNDIS_WLAN_KEY_MGMT_PSK)
 			auth_mode = NDIS_80211_AUTH_WPA_PSK;
 		else
 			auth_mode = NDIS_80211_AUTH_WPA_NONE;
-	} else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
-		if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
-			auth_mode = NDIS_80211_AUTH_AUTO_SWITCH;
-		else
-			auth_mode = NDIS_80211_AUTH_SHARED;
-	} else
+	} else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
+		auth_mode = NDIS_80211_AUTH_SHARED;
+	else if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
 		auth_mode = NDIS_80211_AUTH_OPEN;
+	else
+		return -ENOTSUPP;
 
 	tmp = cpu_to_le32(auth_mode);
 	ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
@@ -862,11 +1084,12 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
 	}
 
 	priv->wpa_version = wpa_version;
-	priv->wpa_authalg = authalg;
+	priv->wpa_auth_type = auth_type;
+	priv->wpa_keymgmt = keymgmt;
+
 	return 0;
 }
 
-
 static int set_priv_filter(struct usbnet *usbdev)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -874,8 +1097,8 @@ static int set_priv_filter(struct usbnet *usbdev)
 
 	devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
 
-	if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
-	    priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
+	if (priv->wpa_version & NL80211_WPA_VERSION_2 ||
+	    priv->wpa_version & NL80211_WPA_VERSION_1)
 		tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP);
 	else
 		tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL);
@@ -884,7 +1107,6 @@ static int set_priv_filter(struct usbnet *usbdev)
 								sizeof(tmp));
 }
 
-
 static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -892,19 +1114,17 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
 	int encr_mode, ret;
 
 	devdbg(usbdev, "set_encr_mode: cipher_pair=0x%x cipher_group=0x%x",
-		pairwise,
-		groupwise);
+		pairwise, groupwise);
 
-	if (pairwise & IW_AUTH_CIPHER_CCMP)
+	if (pairwise & RNDIS_WLAN_ALG_CCMP)
 		encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
-	else if (pairwise & IW_AUTH_CIPHER_TKIP)
+	else if (pairwise & RNDIS_WLAN_ALG_TKIP)
 		encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
-	else if (pairwise &
-		 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
+	else if (pairwise & RNDIS_WLAN_ALG_WEP)
 		encr_mode = NDIS_80211_ENCR_WEP_ENABLED;
-	else if (groupwise & IW_AUTH_CIPHER_CCMP)
+	else if (groupwise & RNDIS_WLAN_ALG_CCMP)
 		encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
-	else if (groupwise & IW_AUTH_CIPHER_TKIP)
+	else if (groupwise & RNDIS_WLAN_ALG_TKIP)
 		encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
 	else
 		encr_mode = NDIS_80211_ENCR_DISABLED;
@@ -922,24 +1142,11 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
 	return 0;
 }
 
-
-static int set_assoc_params(struct usbnet *usbdev)
-{
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-
-	set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
-	set_priv_filter(usbdev);
-	set_encr_mode(usbdev, priv->wpa_cipher_pair, priv->wpa_cipher_group);
-
-	return 0;
-}
-
-
 static int set_infra_mode(struct usbnet *usbdev, int mode)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	__le32 tmp;
-	int ret, i;
+	int ret;
 
 	devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode);
 
@@ -954,55 +1161,107 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
 	/* NDIS drivers clear keys when infrastructure mode is
 	 * changed. But Linux tools assume otherwise. So set the
 	 * keys */
-	if (priv->wpa_keymgmt == 0 ||
-		priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
-		for (i = 0; i < 4; i++) {
-			if (priv->encr_key_len[i] > 0 && !priv->encr_key_wpa[i])
-				add_wep_key(usbdev, priv->encr_keys[i],
-						priv->encr_key_len[i], i);
-		}
-	}
+	restore_keys(usbdev);
 
 	priv->infra_mode = mode;
 	return 0;
 }
 
+static int set_rts_threshold(struct usbnet *usbdev, u32 rts_threshold)
+{
+	__le32 tmp;
 
-static void set_default_iw_params(struct usbnet *usbdev)
+	devdbg(usbdev, "set_rts_threshold %i", rts_threshold);
+
+	if (rts_threshold < 0 || rts_threshold > 2347)
+		rts_threshold = 2347;
+
+	tmp = cpu_to_le32(rts_threshold);
+	return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp,
+								sizeof(tmp));
+}
+
+static int set_frag_threshold(struct usbnet *usbdev, u32 frag_threshold)
 {
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	__le32 tmp;
+
+	devdbg(usbdev, "set_frag_threshold %i", frag_threshold);
 
-	priv->wpa_keymgmt = 0;
-	priv->wpa_version = 0;
+	if (frag_threshold < 256 || frag_threshold > 2346)
+		frag_threshold = 2346;
 
+	tmp = cpu_to_le32(frag_threshold);
+	return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
+								sizeof(tmp));
+}
+
+static void set_default_iw_params(struct usbnet *usbdev)
+{
 	set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
-	set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
-				IW_AUTH_ALG_OPEN_SYSTEM);
+	set_auth_mode(usbdev, 0, NL80211_AUTHTYPE_OPEN_SYSTEM,
+						RNDIS_WLAN_KEY_MGMT_NONE);
 	set_priv_filter(usbdev);
-	set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
+	set_encr_mode(usbdev, RNDIS_WLAN_ALG_NONE, RNDIS_WLAN_ALG_NONE);
 }
 
-
 static int deauthenticate(struct usbnet *usbdev)
 {
 	int ret;
 
-	ret = disassociate(usbdev, 1);
+	ret = disassociate(usbdev, true);
 	set_default_iw_params(usbdev);
 	return ret;
 }
 
+static int set_channel(struct usbnet *usbdev, int channel)
+{
+	struct ndis_80211_conf config;
+	unsigned int dsconfig;
+	int len, ret;
+
+	devdbg(usbdev, "set_channel(%d)", channel);
+
+	/* this OID is valid only when not associated */
+	if (is_associated(usbdev))
+		return 0;
+
+	dsconfig = ieee80211_dsss_chan_to_freq(channel) * 1000;
+
+	len = sizeof(config);
+	ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
+	if (ret < 0) {
+		devdbg(usbdev, "set_channel: querying configuration failed");
+		return ret;
+	}
+
+	config.ds_config = cpu_to_le32(dsconfig);
+	ret = rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
+								sizeof(config));
+
+	devdbg(usbdev, "set_channel: %d -> %d", channel, ret);
+
+	return ret;
+}
 
 /* index must be 0 - N, as per NDIS  */
-static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
+static int add_wep_key(struct usbnet *usbdev, const u8 *key, int key_len,
+								int index)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	struct ndis_80211_wep_key ndis_key;
+	u32 cipher;
 	int ret;
 
-	if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4)
+	devdbg(usbdev, "add_wep_key(idx: %d, len: %d)", index, key_len);
+
+	if ((key_len != 5 && key_len != 13) || index < 0 || index > 3)
 		return -EINVAL;
 
+	if (key_len == 5)
+		cipher = WLAN_CIPHER_SUITE_WEP40;
+	else
+		cipher = WLAN_CIPHER_SUITE_WEP104;
+
 	memset(&ndis_key, 0, sizeof(ndis_key));
 
 	ndis_key.size = cpu_to_le32(sizeof(ndis_key));
@@ -1012,8 +1271,8 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
 
 	if (index == priv->encr_tx_key_index) {
 		ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY;
-		ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
-						IW_AUTH_CIPHER_NONE);
+		ret = set_encr_mode(usbdev, RNDIS_WLAN_ALG_WEP,
+							RNDIS_WLAN_ALG_NONE);
 		if (ret)
 			devwarn(usbdev, "encryption couldn't be enabled (%08X)",
 									ret);
@@ -1027,30 +1286,51 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
 		return ret;
 	}
 
-	priv->encr_key_len[index] = key_len;
-	priv->encr_key_wpa[index] = 0;
-	memcpy(&priv->encr_keys[index], key, key_len);
+	priv->encr_keys[index].len = key_len;
+	priv->encr_keys[index].cipher = cipher;
+	memcpy(&priv->encr_keys[index].material, key, key_len);
+	memset(&priv->encr_keys[index].bssid, 0xff, ETH_ALEN);
 
 	return 0;
 }
 
-
 static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
-			int index, const struct sockaddr *addr,
-			const u8 *rx_seq, int alg, int flags)
+			int index, const u8 *addr, const u8 *rx_seq,
+			int seq_len, u32 cipher, __le32 flags)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	struct ndis_80211_key ndis_key;
+	bool is_addr_ok;
 	int ret;
 
-	if (index < 0 || index >= 4)
-		return -EINVAL;
-	if (key_len > sizeof(ndis_key.material) || key_len < 0)
+	if (index < 0 || index >= 4) {
+		devdbg(usbdev, "add_wpa_key: index out of range (%i)", index);
 		return -EINVAL;
-	if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq)
+	}
+	if (key_len > sizeof(ndis_key.material) || key_len < 0) {
+		devdbg(usbdev, "add_wpa_key: key length out of range (%i)",
+			key_len);
 		return -EINVAL;
-	if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr)
+	}
+	if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) {
+		if (!rx_seq || seq_len <= 0) {
+			devdbg(usbdev, "add_wpa_key: recv seq flag without"
+					"buffer");
+			return -EINVAL;
+		}
+		if (rx_seq && seq_len > sizeof(ndis_key.rsc)) {
+			devdbg(usbdev, "add_wpa_key: too big recv seq buffer");
+			return -EINVAL;
+		}
+	}
+
+	is_addr_ok = addr && !is_zero_ether_addr(addr) &&
+					!is_broadcast_ether_addr(addr);
+	if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !is_addr_ok) {
+		devdbg(usbdev, "add_wpa_key: pairwise but bssid invalid (%pM)",
+			addr);
 		return -EINVAL;
+	}
 
 	devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index,
 			!!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY),
@@ -1064,7 +1344,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
 	ndis_key.length = cpu_to_le32(key_len);
 	ndis_key.index = cpu_to_le32(index) | flags;
 
-	if (alg == IW_ENCODE_ALG_TKIP && key_len == 32) {
+	if (cipher == WLAN_CIPHER_SUITE_TKIP && key_len == 32) {
 		/* wpa_supplicant gives us the Michael MIC RX/TX keys in
 		 * different order than NDIS spec, so swap the order here. */
 		memcpy(ndis_key.material, key, 16);
@@ -1074,11 +1354,11 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
 		memcpy(ndis_key.material, key, key_len);
 
 	if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)
-		memcpy(ndis_key.rsc, rx_seq, 6);
+		memcpy(ndis_key.rsc, rx_seq, seq_len);
 
 	if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) {
 		/* pairwise key */
-		memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN);
+		memcpy(ndis_key.bssid, addr, ETH_ALEN);
 	} else {
 		/* group key */
 		if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
@@ -1093,8 +1373,14 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
 	if (ret != 0)
 		return ret;
 
-	priv->encr_key_len[index] = key_len;
-	priv->encr_key_wpa[index] = 1;
+	memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
+	priv->encr_keys[index].len = key_len;
+	priv->encr_keys[index].cipher = cipher;
+	memcpy(&priv->encr_keys[index].material, key, key_len);
+	if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY)
+		memcpy(&priv->encr_keys[index].bssid, ndis_key.bssid, ETH_ALEN);
+	else
+		memset(&priv->encr_keys[index].bssid, 0xff, ETH_ALEN);
 
 	if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY)
 		priv->encr_tx_key_index = index;
@@ -1102,31 +1388,62 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
 	return 0;
 }
 
+static int restore_key(struct usbnet *usbdev, int key_idx)
+{
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	struct rndis_wlan_encr_key key;
+
+	if (is_wpa_key(priv, key_idx))
+		return 0;
+
+	key = priv->encr_keys[key_idx];
+
+	devdbg(usbdev, "restore_key: %i:%i", key_idx, key.len);
+
+	if (key.len == 0)
+		return 0;
+
+	return add_wep_key(usbdev, key.material, key.len, key_idx);
+}
+
+static void restore_keys(struct usbnet *usbdev)
+{
+	int i;
+
+	for (i = 0; i < 4; i++)
+		restore_key(usbdev, i);
+}
+
+static void clear_key(struct rndis_wlan_private *priv, int idx)
+{
+	memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx]));
+}
 
 /* remove_key is for both wep and wpa */
-static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
+static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 	struct ndis_80211_remove_key remove_key;
 	__le32 keyindex;
+	bool is_wpa;
 	int ret;
 
-	if (priv->encr_key_len[index] == 0)
+	if (priv->encr_keys[index].len == 0)
 		return 0;
 
-	priv->encr_key_len[index] = 0;
-	priv->encr_key_wpa[index] = 0;
-	memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
+	is_wpa = is_wpa_key(priv, index);
+
+	devdbg(usbdev, "remove_key: %i:%s:%i", index, is_wpa ? "wpa" : "wep",
+		priv->encr_keys[index].len);
 
-	if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
-	    priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP ||
-	    priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP ||
-	    priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) {
+	clear_key(priv, index);
+
+	if (is_wpa) {
 		remove_key.size = cpu_to_le32(sizeof(remove_key));
 		remove_key.index = cpu_to_le32(index);
 		if (bssid) {
 			/* pairwise key */
-			if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
+			if (!is_broadcast_ether_addr(bssid))
 				remove_key.index |=
 					NDIS_80211_ADDKEY_PAIRWISE_KEY;
 			memcpy(remove_key.bssid, bssid,
@@ -1153,12 +1470,11 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
 
 	/* if it is transmit key, disable encryption */
 	if (index == priv->encr_tx_key_index)
-		set_encr_mode(usbdev, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
+		set_encr_mode(usbdev, RNDIS_WLAN_ALG_NONE, RNDIS_WLAN_ALG_NONE);
 
 	return 0;
 }
 
-
 static void set_multicast_list(struct usbnet *usbdev)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -1218,24 +1534,18 @@ static void set_multicast_list(struct usbnet *usbdev)
 						le32_to_cpu(filter), ret);
 }
 
-
 /*
  * cfg80211 ops
  */
-static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+static int rndis_change_virtual_intf(struct wiphy *wiphy,
+					struct net_device *dev,
 					enum nl80211_iftype type, u32 *flags,
 					struct vif_params *params)
 {
-	struct net_device *dev;
-	struct usbnet *usbdev;
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
 	int mode;
 
-	/* we're under RTNL */
-	dev = __dev_get_by_index(&init_net, ifindex);
-	if (!dev)
-		return -ENODEV;
-	usbdev = netdev_priv(dev);
-
 	switch (type) {
 	case NL80211_IFTYPE_ADHOC:
 		mode = NDIS_80211_INFRA_ADHOC;
@@ -1247,11 +1557,67 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
 		return -EINVAL;
 	}
 
+	priv->wdev.iftype = type;
+
 	return set_infra_mode(usbdev, mode);
 }
 
+static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
+	int err;
+
+	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
+		err = set_frag_threshold(usbdev, wiphy->frag_threshold);
+		if (err < 0)
+			return err;
+	}
+
+	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+		err = set_rts_threshold(usbdev, wiphy->rts_threshold);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+static int rndis_set_tx_power(struct wiphy *wiphy, enum tx_power_setting type,
+				int dbm)
+{
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
+
+	devdbg(usbdev, "rndis_set_tx_power type:0x%x dbm:%i", type, dbm);
 
-#define SCAN_DELAY_JIFFIES (HZ)
+	/* Device doesn't support changing txpower after initialization, only
+	 * turn off/on radio. Support 'auto' mode and setting same dBm that is
+	 * currently used.
+	 */
+	if (type == TX_POWER_AUTOMATIC || dbm == get_bcm4320_power_dbm(priv)) {
+		if (!priv->radio_on)
+			disassociate(usbdev, true); /* turn on radio */
+
+		return 0;
+	}
+
+	return -ENOTSUPP;
+}
+
+static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm)
+{
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
+
+	*dbm = get_bcm4320_power_dbm(priv);
+
+	devdbg(usbdev, "rndis_get_tx_power dbm:%i", *dbm);
+
+	return 0;
+}
+
+#define SCAN_DELAY_JIFFIES (6 * HZ)
 static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
 			struct cfg80211_scan_request *request)
 {
@@ -1262,6 +1628,11 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
 
 	devdbg(usbdev, "cfg80211.scan");
 
+	/* Get current bssid list from device before new scan, as new scan
+	 * clears internal bssid list.
+	 */
+	rndis_check_bssid_list(usbdev);
+
 	if (!request)
 		return -EINVAL;
 
@@ -1282,7 +1653,6 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
 	return ret;
 }
 
-
 static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
 					struct ndis_80211_bssid_ex *bssid)
 {
@@ -1296,6 +1666,9 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
 	int ie_len, bssid_len;
 	u8 *ie;
 
+	devdbg(usbdev, " found bssid: '%.32s' [%pM]", bssid->ssid.essid,
+							bssid->mac);
+
 	/* parse bssid structure */
 	bssid_len = le32_to_cpu(bssid->length);
 
@@ -1328,17 +1701,18 @@ static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
 		GFP_KERNEL);
 }
 
-
 static int rndis_check_bssid_list(struct usbnet *usbdev)
 {
 	void *buf = NULL;
 	struct ndis_80211_bssid_list_ex *bssid_list;
 	struct ndis_80211_bssid_ex *bssid;
 	int ret = -EINVAL, len, count, bssid_len;
+	bool resized = false;
 
 	devdbg(usbdev, "check_bssid_list");
 
 	len = CONTROL_BUFFER_SIZE;
+resize_buf:
 	buf = kmalloc(len, GFP_KERNEL);
 	if (!buf) {
 		ret = -ENOMEM;
@@ -1349,11 +1723,18 @@ static int rndis_check_bssid_list(struct usbnet *usbdev)
 	if (ret != 0)
 		goto out;
 
+	if (!resized && len > CONTROL_BUFFER_SIZE) {
+		resized = true;
+		kfree(buf);
+		goto resize_buf;
+	}
+
 	bssid_list = buf;
 	bssid = bssid_list->bssid;
 	bssid_len = le32_to_cpu(bssid->length);
 	count = le32_to_cpu(bssid_list->num_items);
-	devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count);
+	devdbg(usbdev, "check_bssid_list: %d BSSIDs found (buflen: %d)", count,
+									len);
 
 	while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
 		rndis_bss_info_update(usbdev, bssid);
@@ -1368,7 +1749,6 @@ out:
 	return ret;
 }
 
-
 static void rndis_get_scan_results(struct work_struct *work)
 {
 	struct rndis_wlan_private *priv =
@@ -1378,6 +1758,9 @@ static void rndis_get_scan_results(struct work_struct *work)
 
 	devdbg(usbdev, "get_scan_results");
 
+	if (!priv->scan_request)
+		return;
+
 	ret = rndis_check_bssid_list(usbdev);
 
 	cfg80211_scan_done(priv->scan_request, ret < 0);
@@ -1385,761 +1768,718 @@ static void rndis_get_scan_results(struct work_struct *work)
 	priv->scan_request = NULL;
 }
 
-
-/*
- * wireless extension handlers
- */
-
-static int rndis_iw_commit(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-	/* dummy op */
-	return 0;
-}
-
-
-static int rndis_iw_set_essid(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
+static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
+					struct cfg80211_connect_params *sme)
 {
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
+	struct ieee80211_channel *channel = sme->channel;
 	struct ndis_80211_ssid ssid;
-	int length = wrqu->essid.length;
-	struct usbnet *usbdev = netdev_priv(dev);
+	int pairwise = RNDIS_WLAN_ALG_NONE;
+	int groupwise = RNDIS_WLAN_ALG_NONE;
+	int keymgmt = RNDIS_WLAN_KEY_MGMT_NONE;
+	int length, i, ret, chan = -1;
+
+	if (channel)
+		chan = ieee80211_frequency_to_channel(channel->center_freq);
+
+	groupwise = rndis_cipher_to_alg(sme->crypto.cipher_group);
+	for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
+		pairwise |=
+			rndis_cipher_to_alg(sme->crypto.ciphers_pairwise[i]);
+
+	if (sme->crypto.n_ciphers_pairwise > 0 &&
+			pairwise == RNDIS_WLAN_ALG_NONE) {
+		deverr(usbdev, "Unsupported pairwise cipher");
+		return -ENOTSUPP;
+	}
 
-	devdbg(usbdev, "SIOCSIWESSID: [flags:%d,len:%d] '%.32s'",
-		wrqu->essid.flags, wrqu->essid.length, essid);
+	for (i = 0; i < sme->crypto.n_akm_suites; i++)
+		keymgmt |=
+			rndis_akm_suite_to_key_mgmt(sme->crypto.akm_suites[i]);
 
-	if (length > NDIS_802_11_LENGTH_SSID)
-		length = NDIS_802_11_LENGTH_SSID;
+	if (sme->crypto.n_akm_suites > 0 &&
+			keymgmt == RNDIS_WLAN_KEY_MGMT_NONE) {
+		deverr(usbdev, "Invalid keymgmt");
+		return -ENOTSUPP;
+	}
 
-	ssid.length = cpu_to_le32(length);
-	if (length > 0)
-		memcpy(ssid.essid, essid, length);
-	else
-		memset(ssid.essid, 0, NDIS_802_11_LENGTH_SSID);
+	devdbg(usbdev, "cfg80211.connect('%.32s':[%pM]:%d:[%d,0x%x:0x%x]:[0x%x:"
+			"0x%x]:0x%x)", sme->ssid, sme->bssid, chan,
+			sme->privacy, sme->crypto.wpa_versions, sme->auth_type,
+			groupwise, pairwise, keymgmt);
 
-	set_assoc_params(usbdev);
+	if (is_associated(usbdev))
+		disassociate(usbdev, false);
 
-	if (!wrqu->essid.flags || length == 0)
-		return disassociate(usbdev, 1);
-	else
-		return set_essid(usbdev, &ssid);
-}
+	ret = set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
+	if (ret < 0) {
+		devdbg(usbdev, "connect: set_infra_mode failed, %d", ret);
+		goto err_turn_radio_on;
+	}
 
+	ret = set_auth_mode(usbdev, sme->crypto.wpa_versions, sme->auth_type,
+								keymgmt);
+	if (ret < 0) {
+		devdbg(usbdev, "connect: set_auth_mode failed, %d", ret);
+		goto err_turn_radio_on;
+	}
 
-static int rndis_iw_get_essid(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *essid)
-{
-	struct ndis_80211_ssid ssid;
-	struct usbnet *usbdev = netdev_priv(dev);
-	int ret;
+	set_priv_filter(usbdev);
 
-	ret = get_essid(usbdev, &ssid);
+	ret = set_encr_mode(usbdev, pairwise, groupwise);
+	if (ret < 0) {
+		devdbg(usbdev, "connect: set_encr_mode failed, %d", ret);
+		goto err_turn_radio_on;
+	}
 
-	if (ret == 0 && le32_to_cpu(ssid.length) > 0) {
-		wrqu->essid.flags = 1;
-		wrqu->essid.length = le32_to_cpu(ssid.length);
-		memcpy(essid, ssid.essid, wrqu->essid.length);
-		essid[wrqu->essid.length] = 0;
-	} else {
-		memset(essid, 0, sizeof(NDIS_802_11_LENGTH_SSID));
-		wrqu->essid.flags = 0;
-		wrqu->essid.length = 0;
+	if (channel) {
+		ret = set_channel(usbdev, chan);
+		if (ret < 0) {
+			devdbg(usbdev, "connect: set_channel failed, %d", ret);
+			goto err_turn_radio_on;
+		}
 	}
-	devdbg(usbdev, "SIOCGIWESSID: %s", essid);
-	return ret;
-}
 
+	if (sme->key && ((groupwise | pairwise) & RNDIS_WLAN_ALG_WEP)) {
+		priv->encr_tx_key_index = sme->key_idx;
+		ret = add_wep_key(usbdev, sme->key, sme->key_len, sme->key_idx);
+		if (ret < 0) {
+			devdbg(usbdev, "connect: add_wep_key failed, %d "
+				"(%d, %d)", ret, sme->key_len, sme->key_idx);
+			goto err_turn_radio_on;
+		}
+	}
 
-static int rndis_iw_get_bssid(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-	struct usbnet *usbdev = netdev_priv(dev);
-	unsigned char bssid[ETH_ALEN];
-	int ret;
+	if (sme->bssid && !is_zero_ether_addr(sme->bssid) &&
+				!is_broadcast_ether_addr(sme->bssid)) {
+		ret = set_bssid(usbdev, sme->bssid);
+		if (ret < 0) {
+			devdbg(usbdev, "connect: set_bssid failed, %d", ret);
+			goto err_turn_radio_on;
+		}
+	} else
+		clear_bssid(usbdev);
 
-	ret = get_bssid(usbdev, bssid);
+	length = sme->ssid_len;
+	if (length > NDIS_802_11_LENGTH_SSID)
+		length = NDIS_802_11_LENGTH_SSID;
 
-	if (ret == 0)
-		devdbg(usbdev, "SIOCGIWAP: %pM", bssid);
-	else
-		devdbg(usbdev, "SIOCGIWAP: <not associated>");
+	memset(&ssid, 0, sizeof(ssid));
+	ssid.length = cpu_to_le32(length);
+	memcpy(ssid.essid, sme->ssid, length);
 
-	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-	memcpy(wrqu->ap_addr.sa_data, bssid, ETH_ALEN);
+	/* Pause and purge rx queue, so we don't pass packets before
+	 * 'media connect'-indication.
+	 */
+	usbnet_pause_rx(usbdev);
+	usbnet_purge_paused_rxq(usbdev);
 
+	ret = set_essid(usbdev, &ssid);
+	if (ret < 0)
+		devdbg(usbdev, "connect: set_essid failed, %d", ret);
 	return ret;
-}
 
+err_turn_radio_on:
+	disassociate(usbdev, true);
 
-static int rndis_iw_set_bssid(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-	struct usbnet *usbdev = netdev_priv(dev);
-	u8 *bssid = (u8 *)wrqu->ap_addr.sa_data;
-	int ret;
+	return ret;
+}
 
-	devdbg(usbdev, "SIOCSIWAP: %pM", bssid);
+static int rndis_disconnect(struct wiphy *wiphy, struct net_device *dev,
+								u16 reason_code)
+{
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
 
-	ret = rndis_set_oid(usbdev, OID_802_11_BSSID, bssid, ETH_ALEN);
+	devdbg(usbdev, "cfg80211.disconnect(%d)", reason_code);
 
-	/* user apps may set ap's mac address, which is not required;
-	 * they may fail to work if this function fails, so return
-	 * success */
-	if (ret)
-		devwarn(usbdev, "setting AP mac address failed (%08X)", ret);
+	priv->connected = false;
+	memset(priv->bssid, 0, ETH_ALEN);
 
-	return 0;
+	return deauthenticate(usbdev);
 }
 
-
-static int rndis_iw_set_auth(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+					struct cfg80211_ibss_params *params)
 {
-	struct iw_param *p = &wrqu->param;
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	int ret = -ENOTSUPP;
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
+	struct ieee80211_channel *channel = params->channel;
+	struct ndis_80211_ssid ssid;
+	enum nl80211_auth_type auth_type;
+	int ret, alg, length, chan = -1;
 
-	switch (p->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-		devdbg(usbdev, "SIOCSIWAUTH: WPA_VERSION, %08x", p->value);
-		priv->wpa_version = p->value;
-		ret = 0;
-		break;
+	if (channel)
+		chan = ieee80211_frequency_to_channel(channel->center_freq);
 
-	case IW_AUTH_CIPHER_PAIRWISE:
-		devdbg(usbdev, "SIOCSIWAUTH: CIPHER_PAIRWISE, %08x", p->value);
-		priv->wpa_cipher_pair = p->value;
-		ret = 0;
-		break;
+	/* TODO: How to handle ad-hoc encryption?
+	 * connect() has *key, join_ibss() doesn't. RNDIS requires key to be
+	 * pre-shared for encryption (open/shared/wpa), is key set before
+	 * join_ibss? Which auth_type to use (not in params)? What about WPA?
+	 */
+	if (params->privacy) {
+		auth_type = NL80211_AUTHTYPE_SHARED_KEY;
+		alg = RNDIS_WLAN_ALG_WEP;
+	} else {
+		auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+		alg = RNDIS_WLAN_ALG_NONE;
+	}
 
-	case IW_AUTH_CIPHER_GROUP:
-		devdbg(usbdev, "SIOCSIWAUTH: CIPHER_GROUP, %08x", p->value);
-		priv->wpa_cipher_group = p->value;
-		ret = 0;
-		break;
+	devdbg(usbdev, "cfg80211.join_ibss('%.32s':[%pM]:%d:%d)", params->ssid,
+					params->bssid, chan, params->privacy);
 
-	case IW_AUTH_KEY_MGMT:
-		devdbg(usbdev, "SIOCSIWAUTH: KEY_MGMT, %08x", p->value);
-		priv->wpa_keymgmt = p->value;
-		ret = 0;
-		break;
+	if (is_associated(usbdev))
+		disassociate(usbdev, false);
 
-	case IW_AUTH_TKIP_COUNTERMEASURES:
-		devdbg(usbdev, "SIOCSIWAUTH: TKIP_COUNTERMEASURES, %08x",
-								p->value);
-		ret = 0;
-		break;
+	ret = set_infra_mode(usbdev, NDIS_80211_INFRA_ADHOC);
+	if (ret < 0) {
+		devdbg(usbdev, "join_ibss: set_infra_mode failed, %d", ret);
+		goto err_turn_radio_on;
+	}
 
-	case IW_AUTH_DROP_UNENCRYPTED:
-		devdbg(usbdev, "SIOCSIWAUTH: DROP_UNENCRYPTED, %08x", p->value);
-		ret = 0;
-		break;
+	ret = set_auth_mode(usbdev, 0, auth_type, RNDIS_WLAN_KEY_MGMT_NONE);
+	if (ret < 0) {
+		devdbg(usbdev, "join_ibss: set_auth_mode failed, %d", ret);
+		goto err_turn_radio_on;
+	}
 
-	case IW_AUTH_80211_AUTH_ALG:
-		devdbg(usbdev, "SIOCSIWAUTH: 80211_AUTH_ALG, %08x", p->value);
-		priv->wpa_authalg = p->value;
-		ret = 0;
-		break;
+	set_priv_filter(usbdev);
 
-	case IW_AUTH_WPA_ENABLED:
-		devdbg(usbdev, "SIOCSIWAUTH: WPA_ENABLED, %08x", p->value);
-		if (wrqu->param.value)
-			deauthenticate(usbdev);
-		ret = 0;
-		break;
+	ret = set_encr_mode(usbdev, alg, RNDIS_WLAN_ALG_NONE);
+	if (ret < 0) {
+		devdbg(usbdev, "join_ibss: set_encr_mode failed, %d", ret);
+		goto err_turn_radio_on;
+	}
 
-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-		devdbg(usbdev, "SIOCSIWAUTH: RX_UNENCRYPTED_EAPOL, %08x",
-								p->value);
-		ret = 0;
-		break;
+	if (channel) {
+		ret = set_channel(usbdev, chan);
+		if (ret < 0) {
+			devdbg(usbdev, "join_ibss: set_channel failed, %d",
+				ret);
+			goto err_turn_radio_on;
+		}
+	}
 
-	case IW_AUTH_ROAMING_CONTROL:
-		devdbg(usbdev, "SIOCSIWAUTH: ROAMING_CONTROL, %08x", p->value);
-		ret = 0;
-		break;
+	if (params->bssid && !is_zero_ether_addr(params->bssid) &&
+				!is_broadcast_ether_addr(params->bssid)) {
+		ret = set_bssid(usbdev, params->bssid);
+		if (ret < 0) {
+			devdbg(usbdev, "join_ibss: set_bssid failed, %d", ret);
+			goto err_turn_radio_on;
+		}
+	} else
+		clear_bssid(usbdev);
 
-	case IW_AUTH_PRIVACY_INVOKED:
-		devdbg(usbdev, "SIOCSIWAUTH: invalid cmd %d",
-				wrqu->param.flags & IW_AUTH_INDEX);
-		return -EOPNOTSUPP;
+	length = params->ssid_len;
+	if (length > NDIS_802_11_LENGTH_SSID)
+		length = NDIS_802_11_LENGTH_SSID;
 
-	default:
-		devdbg(usbdev, "SIOCSIWAUTH: UNKNOWN  %08x, %08x",
-			p->flags & IW_AUTH_INDEX, p->value);
-	}
-	return ret;
-}
+	memset(&ssid, 0, sizeof(ssid));
+	ssid.length = cpu_to_le32(length);
+	memcpy(ssid.essid, params->ssid, length);
 
+	/* Don't need to pause rx queue for ad-hoc. */
+	usbnet_purge_paused_rxq(usbdev);
+	usbnet_resume_rx(usbdev);
 
-static int rndis_iw_get_auth(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-	struct iw_param *p = &wrqu->param;
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	ret = set_essid(usbdev, &ssid);
+	if (ret < 0)
+		devdbg(usbdev, "join_ibss: set_essid failed, %d", ret);
+	return ret;
 
-	switch (p->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-		p->value = priv->wpa_version;
-		break;
-	case IW_AUTH_CIPHER_PAIRWISE:
-		p->value = priv->wpa_cipher_pair;
-		break;
-	case IW_AUTH_CIPHER_GROUP:
-		p->value = priv->wpa_cipher_group;
-		break;
-	case IW_AUTH_KEY_MGMT:
-		p->value = priv->wpa_keymgmt;
-		break;
-	case IW_AUTH_80211_AUTH_ALG:
-		p->value = priv->wpa_authalg;
-		break;
-	default:
-		devdbg(usbdev, "SIOCGIWAUTH: invalid cmd %d",
-				wrqu->param.flags & IW_AUTH_INDEX);
-		return -EOPNOTSUPP;
-	}
-	return 0;
-}
+err_turn_radio_on:
+	disassociate(usbdev, true);
 
+	return ret;
+}
 
-static int rndis_iw_set_encode(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	int ret, index, key_len;
-	u8 *key;
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
 
-	index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
+	devdbg(usbdev, "cfg80211.leave_ibss()");
 
-	/* iwconfig gives index as 1 - N */
-	if (index > 0)
-		index--;
-	else
-		index = priv->encr_tx_key_index;
+	priv->connected = false;
+	memset(priv->bssid, 0, ETH_ALEN);
 
-	if (index < 0 || index >= 4) {
-		devwarn(usbdev, "encryption index out of range (%u)", index);
-		return -EINVAL;
-	}
+	return deauthenticate(usbdev);
+}
 
-	/* remove key if disabled */
-	if (wrqu->data.flags & IW_ENCODE_DISABLED) {
-		if (remove_key(usbdev, index, NULL))
-			return -EINVAL;
-		else
-			return 0;
-	}
+static int rndis_set_channel(struct wiphy *wiphy,
+	struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
+{
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
 
-	/* global encryption state (for all keys) */
-	if (wrqu->data.flags & IW_ENCODE_OPEN)
-		ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
-						IW_AUTH_ALG_OPEN_SYSTEM);
-	else /*if (wrqu->data.flags & IW_ENCODE_RESTRICTED)*/
-		ret = set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
-						IW_AUTH_ALG_SHARED_KEY);
-	if (ret != 0)
-		return ret;
+	return set_channel(usbdev,
+			ieee80211_frequency_to_channel(chan->center_freq));
+}
 
-	if (wrqu->data.length > 0) {
-		key_len = wrqu->data.length;
-		key = extra;
-	} else {
-		/* must be set as tx key */
-		if (priv->encr_key_len[index] == 0)
-			return -EINVAL;
-		key_len = priv->encr_key_len[index];
-		key = priv->encr_keys[index];
-		priv->encr_tx_key_index = index;
+static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev,
+					u8 key_index, const u8 *mac_addr,
+					struct key_params *params)
+{
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
+	__le32 flags;
+
+	devdbg(usbdev, "rndis_add_key(%i, %pM, %08x)", key_index, mac_addr,
+							params->cipher);
+
+	switch (params->cipher) {
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		return add_wep_key(usbdev, params->key, params->key_len,
+								key_index);
+	case WLAN_CIPHER_SUITE_TKIP:
+	case WLAN_CIPHER_SUITE_CCMP:
+		flags = 0;
+
+		if (params->seq && params->seq_len > 0)
+			flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ;
+		if (mac_addr)
+			flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY |
+					NDIS_80211_ADDKEY_TRANSMIT_KEY;
+
+		return add_wpa_key(usbdev, params->key, params->key_len,
+				key_index, mac_addr, params->seq,
+				params->seq_len, params->cipher, flags);
+	default:
+		devdbg(usbdev, "rndis_add_key: unsupported cipher %08x",
+							params->cipher);
+		return -ENOTSUPP;
 	}
-
-	if (add_wep_key(usbdev, key, key_len, index) != 0)
-		return -EINVAL;
-
-	if (index == priv->encr_tx_key_index)
-		/* ndis drivers want essid to be set after setting encr */
-		set_essid(usbdev, &priv->essid);
-
-	return 0;
 }
 
-
-static int rndis_iw_set_encode_ext(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev,
+					u8 key_index, const u8 *mac_addr)
 {
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	int keyidx, flags;
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
 
-	keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
+	devdbg(usbdev, "rndis_del_key(%i, %pM)", key_index, mac_addr);
 
-	/* iwconfig gives index as 1 - N */
-	if (keyidx)
-		keyidx--;
-	else
-		keyidx = priv->encr_tx_key_index;
+	return remove_key(usbdev, key_index, mac_addr);
+}
 
-	if (keyidx < 0 || keyidx >= 4)
-		return -EINVAL;
+static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
+								u8 key_index)
+{
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
+	struct rndis_wlan_encr_key key;
 
-	if (ext->alg == WPA_ALG_WEP) {
-		if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-			priv->encr_tx_key_index = keyidx;
-		return add_wep_key(usbdev, ext->key, ext->key_len, keyidx);
-	}
+	devdbg(usbdev, "rndis_set_default_key(%i)", key_index);
 
-	if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||
-	    ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
-		return remove_key(usbdev, keyidx, NULL);
+	priv->encr_tx_key_index = key_index;
 
-	flags = 0;
-	if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
-		flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ;
-	if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
-		flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY;
-	if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-		flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;
+	key = priv->encr_keys[key_index];
 
-	return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr,
-				ext->rx_seq, ext->alg, flags);
+	return add_wep_key(usbdev, key.material, key.len, key_index);
 }
 
-
-static int rndis_iw_set_genie(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static void rndis_fill_station_info(struct usbnet *usbdev,
+						struct station_info *sinfo)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	int ret = 0;
+	__le32 linkspeed, rssi;
+	int ret, len;
 
-#ifdef DEBUG
-	int j;
-	u8 *gie = extra;
-	for (j = 0; j < wrqu->data.length; j += 8)
-		devdbg(usbdev,
-			"SIOCSIWGENIE %04x - "
-			"%02x %02x %02x %02x %02x %02x %02x %02x", j,
-			gie[j + 0], gie[j + 1], gie[j + 2], gie[j + 3],
-			gie[j + 4], gie[j + 5], gie[j + 6], gie[j + 7]);
-#endif
-	/* clear existing IEs */
-	if (priv->wpa_ie_len) {
-		kfree(priv->wpa_ie);
-		priv->wpa_ie_len = 0;
+	memset(sinfo, 0, sizeof(*sinfo));
+
+	len = sizeof(linkspeed);
+	ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &linkspeed, &len);
+	if (ret == 0) {
+		sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000;
+		sinfo->filled |= STATION_INFO_TX_BITRATE;
 	}
 
-	/* set new IEs */
-	priv->wpa_ie = kmalloc(wrqu->data.length, GFP_KERNEL);
-	if (priv->wpa_ie) {
-		priv->wpa_ie_len = wrqu->data.length;
-		memcpy(priv->wpa_ie, extra, priv->wpa_ie_len);
-	} else
-		ret = -ENOMEM;
-	return ret;
+	len = sizeof(rssi);
+	ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
+	if (ret == 0) {
+		sinfo->signal = level_to_qual(le32_to_cpu(rssi));
+		sinfo->filled |= STATION_INFO_SIGNAL;
+	}
 }
 
-
-static int rndis_iw_get_genie(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_get_station(struct wiphy *wiphy, struct net_device *dev,
+					u8 *mac, struct station_info *sinfo)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-
-	devdbg(usbdev, "SIOCGIWGENIE");
-
-	if (priv->wpa_ie_len == 0 || priv->wpa_ie == NULL) {
-		wrqu->data.length = 0;
-		return 0;
-	}
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
 
-	if (wrqu->data.length < priv->wpa_ie_len)
-		return -E2BIG;
+	if (compare_ether_addr(priv->bssid, mac))
+		return -ENOENT;
 
-	wrqu->data.length = priv->wpa_ie_len;
-	memcpy(extra, priv->wpa_ie, priv->wpa_ie_len);
+	rndis_fill_station_info(usbdev, sinfo);
 
 	return 0;
 }
 
-
-static int rndis_iw_set_rts(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_dump_station(struct wiphy *wiphy, struct net_device *dev,
+			       int idx, u8 *mac, struct station_info *sinfo)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	__le32 tmp;
-	devdbg(usbdev, "SIOCSIWRTS");
+	struct rndis_wlan_private *priv = wiphy_priv(wiphy);
+	struct usbnet *usbdev = priv->usbdev;
 
-	tmp = cpu_to_le32(wrqu->rts.value);
-	return rndis_set_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp,
-								sizeof(tmp));
-}
+	if (idx != 0)
+		return -ENOENT;
+
+	memcpy(mac, priv->bssid, ETH_ALEN);
 
+	rndis_fill_station_info(usbdev, sinfo);
 
-static int rndis_iw_get_rts(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+	return 0;
+}
+
+/*
+ * workers, indication handlers, device poller
+ */
+static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	__le32 tmp;
-	int len, ret;
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	struct ndis_80211_assoc_info *info;
+	u8 assoc_buf[sizeof(*info) + IW_CUSTOM_MAX + 32];
+	u8 bssid[ETH_ALEN];
+	int resp_ie_len, req_ie_len;
+	u8 *req_ie, *resp_ie;
+	int ret, offset;
+	bool roamed = false;
 
-	len = sizeof(tmp);
-	ret = rndis_query_oid(usbdev, OID_802_11_RTS_THRESHOLD, &tmp, &len);
-	if (ret == 0) {
-		wrqu->rts.value = le32_to_cpu(tmp);
-		wrqu->rts.flags = 1;
-		wrqu->rts.disabled = 0;
+	if (priv->infra_mode == NDIS_80211_INFRA_INFRA && priv->connected) {
+		/* received media connect indication while connected, either
+		 * device reassociated with same AP or roamed to new. */
+		roamed = true;
 	}
 
-	devdbg(usbdev, "SIOCGIWRTS: %d", wrqu->rts.value);
+	req_ie_len = 0;
+	resp_ie_len = 0;
+	req_ie = NULL;
+	resp_ie = NULL;
 
-	return ret;
-}
+	if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
+		memset(assoc_buf, 0, sizeof(assoc_buf));
+		info = (void *)assoc_buf;
 
+		/* Get association info IEs from device and send them back to
+		 * userspace. */
+		ret = get_association_info(usbdev, info, sizeof(assoc_buf));
+		if (!ret) {
+			req_ie_len = le32_to_cpu(info->req_ie_length);
+			if (req_ie_len > 0) {
+				offset = le32_to_cpu(info->offset_req_ies);
+				req_ie = (u8 *)info + offset;
+			}
 
-static int rndis_iw_set_frag(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-	struct usbnet *usbdev = netdev_priv(dev);
-	__le32 tmp;
+			resp_ie_len = le32_to_cpu(info->resp_ie_length);
+			if (resp_ie_len > 0) {
+				offset = le32_to_cpu(info->offset_resp_ies);
+				resp_ie = (u8 *)info + offset;
+			}
+		}
+	} else if (WARN_ON(priv->infra_mode != NDIS_80211_INFRA_ADHOC))
+		return;
 
-	devdbg(usbdev, "SIOCSIWFRAG");
+	ret = get_bssid(usbdev, bssid);
+	if (ret < 0)
+		memset(bssid, 0, sizeof(bssid));
 
-	tmp = cpu_to_le32(wrqu->frag.value);
-	return rndis_set_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
-								sizeof(tmp));
-}
+	devdbg(usbdev, "link up work: [%pM] %s", bssid, roamed ? "roamed" : "");
 
+	/* Internal bss list in device always contains at least the currently
+	 * connected bss and we can get it to cfg80211 with
+	 * rndis_check_bssid_list().
+	 * NOTE: This is true for Broadcom chip, but not mentioned in RNDIS
+	 * spec.
+	 */
+	rndis_check_bssid_list(usbdev);
 
-static int rndis_iw_get_frag(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-	struct usbnet *usbdev = netdev_priv(dev);
-	__le32 tmp;
-	int len, ret;
+	if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
+		if (!roamed)
+			cfg80211_connect_result(usbdev->net, bssid, req_ie,
+						req_ie_len, resp_ie,
+						resp_ie_len, 0, GFP_KERNEL);
+		else
+			cfg80211_roamed(usbdev->net, bssid, req_ie, req_ie_len,
+					resp_ie, resp_ie_len, GFP_KERNEL);
+	} else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
+		cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
 
-	len = sizeof(tmp);
-	ret = rndis_query_oid(usbdev, OID_802_11_FRAGMENTATION_THRESHOLD, &tmp,
-									&len);
-	if (ret == 0) {
-		wrqu->frag.value = le32_to_cpu(tmp);
-		wrqu->frag.flags = 1;
-		wrqu->frag.disabled = 0;
-	}
-	devdbg(usbdev, "SIOCGIWFRAG: %d", wrqu->frag.value);
-	return ret;
-}
+	priv->connected = true;
+	memcpy(priv->bssid, bssid, ETH_ALEN);
 
+	usbnet_resume_rx(usbdev);
+	netif_carrier_on(usbdev->net);
+}
 
-static int rndis_iw_set_freq(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static void rndis_wlan_do_link_down_work(struct usbnet *usbdev)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct ndis_80211_conf config;
-	unsigned int dsconfig;
-	int len, ret;
-
-	/* this OID is valid only when not associated */
-	if (is_associated(usbdev))
-		return 0;
-
-	dsconfig = 0;
-	if (freq_to_dsconfig(&wrqu->freq, &dsconfig))
-		return -EINVAL;
-
-	len = sizeof(config);
-	ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
-	if (ret != 0) {
-		devdbg(usbdev, "SIOCSIWFREQ: querying configuration failed");
-		return 0;
-	}
+	union iwreq_data evt;
 
-	config.ds_config = cpu_to_le32(dsconfig);
+	netif_carrier_off(usbdev->net);
 
-	devdbg(usbdev, "SIOCSIWFREQ: %d * 10^%d", wrqu->freq.m, wrqu->freq.e);
-	return rndis_set_oid(usbdev, OID_802_11_CONFIGURATION, &config,
-								sizeof(config));
+	evt.data.flags = 0;
+	evt.data.length = 0;
+	memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
+	wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
 }
 
-
-static int rndis_iw_get_freq(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static void rndis_wlan_worker(struct work_struct *work)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct ndis_80211_conf config;
-	int len, ret;
+	struct rndis_wlan_private *priv =
+		container_of(work, struct rndis_wlan_private, work);
+	struct usbnet *usbdev = priv->usbdev;
 
-	len = sizeof(config);
-	ret = rndis_query_oid(usbdev, OID_802_11_CONFIGURATION, &config, &len);
-	if (ret == 0)
-		dsconfig_to_freq(le32_to_cpu(config.ds_config), &wrqu->freq);
+	if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending))
+		rndis_wlan_do_link_up_work(usbdev);
 
-	devdbg(usbdev, "SIOCGIWFREQ: %d", wrqu->freq.m);
-	return ret;
-}
+	if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending))
+		rndis_wlan_do_link_down_work(usbdev);
 
+	if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
+		set_multicast_list(usbdev);
+}
 
-static int rndis_iw_get_txpower(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static void rndis_wlan_set_multicast_list(struct net_device *dev)
 {
 	struct usbnet *usbdev = netdev_priv(dev);
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	__le32 tx_power;
-
-	if (priv->radio_on) {
-		/* fake since changing tx_power (by userlevel) not supported */
-		tx_power = cpu_to_le32(get_bcm4320_power(priv));
 
-		wrqu->txpower.flags = IW_TXPOW_MWATT;
-		wrqu->txpower.value = le32_to_cpu(tx_power);
-		wrqu->txpower.disabled = 0;
-	} else {
-		wrqu->txpower.flags = IW_TXPOW_MWATT;
-		wrqu->txpower.value = 0;
-		wrqu->txpower.disabled = 1;
-	}
-
-	devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
+	if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
+		return;
 
-	return 0;
+	set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending);
+	queue_work(priv->workqueue, &priv->work);
 }
 
-
-static int rndis_iw_set_txpower(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static void rndis_wlan_auth_indication(struct usbnet *usbdev,
+				struct ndis_80211_status_indication *indication,
+				int len)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	__le32 tx_power = 0;
-
-	if (!wrqu->txpower.disabled) {
-		if (wrqu->txpower.flags == IW_TXPOW_MWATT)
-			tx_power = cpu_to_le32(wrqu->txpower.value);
-		else { /* wrqu->txpower.flags == IW_TXPOW_DBM */
-			if (wrqu->txpower.value > 20)
-				tx_power = cpu_to_le32(128);
-			else if (wrqu->txpower.value < -43)
-				tx_power = cpu_to_le32(127);
-			else {
-				signed char tmp;
-				tmp = wrqu->txpower.value;
-				tmp = -12 - tmp;
-				tmp <<= 2;
-				tx_power = cpu_to_le32((unsigned char)tmp);
-			}
-		}
+	u8 *buf;
+	const char *type;
+	int flags, buflen, key_id;
+	bool pairwise_error, group_error;
+	struct ndis_80211_auth_request *auth_req;
+	enum nl80211_key_type key_type;
+
+	/* must have at least one array entry */
+	if (len < offsetof(struct ndis_80211_status_indication, u) +
+				sizeof(struct ndis_80211_auth_request)) {
+		devinfo(usbdev, "authentication indication: "
+				"too short message (%i)", len);
+		return;
 	}
 
-	devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
+	buf = (void *)&indication->u.auth_request[0];
+	buflen = len - offsetof(struct ndis_80211_status_indication, u);
+
+	while (buflen >= sizeof(*auth_req)) {
+		auth_req = (void *)buf;
+		type = "unknown";
+		flags = le32_to_cpu(auth_req->flags);
+		pairwise_error = false;
+		group_error = false;
+
+		if (flags & 0x1)
+			type = "reauth request";
+		if (flags & 0x2)
+			type = "key update request";
+		if (flags & 0x6) {
+			pairwise_error = true;
+			type = "pairwise_error";
+		}
+		if (flags & 0xe) {
+			group_error = true;
+			type = "group_error";
+		}
 
-	if (le32_to_cpu(tx_power) != 0) {
-		/* txpower unsupported, just turn radio on */
-		if (!priv->radio_on)
-			return disassociate(usbdev, 1);
-		return 0; /* all ready on */
-	}
+		devinfo(usbdev, "authentication indication: %s (0x%08x)", type,
+				le32_to_cpu(auth_req->flags));
 
-	/* tx_power == 0, turn off radio */
-	return disassociate(usbdev, 0);
-}
+		if (pairwise_error) {
+			key_type = NL80211_KEYTYPE_PAIRWISE;
+			key_id = -1;
 
+			cfg80211_michael_mic_failure(usbdev->net,
+							auth_req->bssid,
+							key_type, key_id, NULL,
+							GFP_KERNEL);
+		}
 
-static int rndis_iw_get_rate(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-	struct usbnet *usbdev = netdev_priv(dev);
-	__le32 tmp;
-	int ret, len;
+		if (group_error) {
+			key_type = NL80211_KEYTYPE_GROUP;
+			key_id = -1;
 
-	len = sizeof(tmp);
-	ret = rndis_query_oid(usbdev, OID_GEN_LINK_SPEED, &tmp, &len);
-	if (ret == 0) {
-		wrqu->bitrate.value = le32_to_cpu(tmp) * 100;
-		wrqu->bitrate.disabled = 0;
-		wrqu->bitrate.flags = 1;
+			cfg80211_michael_mic_failure(usbdev->net,
+							auth_req->bssid,
+							key_type, key_id, NULL,
+							GFP_KERNEL);
+		}
+
+		buflen -= le32_to_cpu(auth_req->length);
+		buf += le32_to_cpu(auth_req->length);
 	}
-	return ret;
 }
 
-
-static int rndis_iw_set_mlme(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static void rndis_wlan_pmkid_cand_list_indication(struct usbnet *usbdev,
+				struct ndis_80211_status_indication *indication,
+				int len)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	struct iw_mlme *mlme = (struct iw_mlme *)extra;
-	unsigned char bssid[ETH_ALEN];
+	struct ndis_80211_pmkid_cand_list *cand_list;
+	int list_len, expected_len, i;
 
-	get_bssid(usbdev, bssid);
+	if (len < offsetof(struct ndis_80211_status_indication, u) +
+				sizeof(struct ndis_80211_pmkid_cand_list)) {
+		devinfo(usbdev, "pmkid candidate list indication: "
+				"too short message (%i)", len);
+		return;
+	}
 
-	if (memcmp(bssid, mlme->addr.sa_data, ETH_ALEN))
-		return -EINVAL;
+	list_len = le32_to_cpu(indication->u.cand_list.num_candidates) *
+			sizeof(struct ndis_80211_pmkid_candidate);
+	expected_len = sizeof(struct ndis_80211_pmkid_cand_list) + list_len +
+			offsetof(struct ndis_80211_status_indication, u);
 
-	switch (mlme->cmd) {
-	case IW_MLME_DEAUTH:
-		return deauthenticate(usbdev);
-	case IW_MLME_DISASSOC:
-		return disassociate(usbdev, priv->radio_on);
-	default:
-		return -EOPNOTSUPP;
+	if (len < expected_len) {
+		devinfo(usbdev, "pmkid candidate list indication: "
+				"list larger than buffer (%i < %i)",
+				len, expected_len);
+		return;
 	}
 
-	return 0;
-}
+	cand_list = &indication->u.cand_list;
 
+	devinfo(usbdev, "pmkid candidate list indication: "
+			"version %i, candidates %i",
+			le32_to_cpu(cand_list->version),
+			le32_to_cpu(cand_list->num_candidates));
 
-static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
-{
-	struct usbnet *usbdev = netdev_priv(dev);
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->stats_lock, flags);
-	memcpy(&priv->iwstats, &priv->privstats, sizeof(priv->iwstats));
-	spin_unlock_irqrestore(&priv->stats_lock, flags);
-
-	return &priv->iwstats;
-}
-
-
-#define IW_IOCTL(x) [(x) - SIOCSIWCOMMIT]
-static const iw_handler rndis_iw_handler[] =
-{
-	IW_IOCTL(SIOCSIWCOMMIT)    = rndis_iw_commit,
-	IW_IOCTL(SIOCGIWNAME)      = (iw_handler) cfg80211_wext_giwname,
-	IW_IOCTL(SIOCSIWFREQ)      = rndis_iw_set_freq,
-	IW_IOCTL(SIOCGIWFREQ)      = rndis_iw_get_freq,
-	IW_IOCTL(SIOCSIWMODE)      = (iw_handler) cfg80211_wext_siwmode,
-	IW_IOCTL(SIOCGIWMODE)      = (iw_handler) cfg80211_wext_giwmode,
-	IW_IOCTL(SIOCGIWRANGE)     = (iw_handler) cfg80211_wext_giwrange,
-	IW_IOCTL(SIOCSIWAP)        = rndis_iw_set_bssid,
-	IW_IOCTL(SIOCGIWAP)        = rndis_iw_get_bssid,
-	IW_IOCTL(SIOCSIWSCAN)      = (iw_handler) cfg80211_wext_siwscan,
-	IW_IOCTL(SIOCGIWSCAN)      = (iw_handler) cfg80211_wext_giwscan,
-	IW_IOCTL(SIOCSIWESSID)     = rndis_iw_set_essid,
-	IW_IOCTL(SIOCGIWESSID)     = rndis_iw_get_essid,
-	IW_IOCTL(SIOCGIWRATE)      = rndis_iw_get_rate,
-	IW_IOCTL(SIOCSIWRTS)       = rndis_iw_set_rts,
-	IW_IOCTL(SIOCGIWRTS)       = rndis_iw_get_rts,
-	IW_IOCTL(SIOCSIWFRAG)      = rndis_iw_set_frag,
-	IW_IOCTL(SIOCGIWFRAG)      = rndis_iw_get_frag,
-	IW_IOCTL(SIOCSIWTXPOW)     = rndis_iw_set_txpower,
-	IW_IOCTL(SIOCGIWTXPOW)     = rndis_iw_get_txpower,
-	IW_IOCTL(SIOCSIWENCODE)    = rndis_iw_set_encode,
-	IW_IOCTL(SIOCSIWENCODEEXT) = rndis_iw_set_encode_ext,
-	IW_IOCTL(SIOCSIWAUTH)      = rndis_iw_set_auth,
-	IW_IOCTL(SIOCGIWAUTH)      = rndis_iw_get_auth,
-	IW_IOCTL(SIOCSIWGENIE)     = rndis_iw_set_genie,
-	IW_IOCTL(SIOCGIWGENIE)     = rndis_iw_get_genie,
-	IW_IOCTL(SIOCSIWMLME)      = rndis_iw_set_mlme,
-};
+	if (le32_to_cpu(cand_list->version) != 1)
+		return;
 
-static const iw_handler rndis_wlan_private_handler[] = {
-};
+	for (i = 0; i < le32_to_cpu(cand_list->num_candidates); i++) {
+		struct ndis_80211_pmkid_candidate *cand =
+						&cand_list->candidate_list[i];
 
-static const struct iw_priv_args rndis_wlan_private_args[] = {
-};
+		devdbg(usbdev, "cand[%i]: flags: 0x%08x, bssid: %pM",
+				i, le32_to_cpu(cand->flags), cand->bssid);
 
+#if 0
+		struct iw_pmkid_cand pcand;
+		union iwreq_data wrqu;
 
-static const struct iw_handler_def rndis_iw_handlers = {
-	.num_standard = ARRAY_SIZE(rndis_iw_handler),
-	.num_private  = ARRAY_SIZE(rndis_wlan_private_handler),
-	.num_private_args = ARRAY_SIZE(rndis_wlan_private_args),
-	.standard = (iw_handler *)rndis_iw_handler,
-	.private  = (iw_handler *)rndis_wlan_private_handler,
-	.private_args = (struct iw_priv_args *)rndis_wlan_private_args,
-	.get_wireless_stats = rndis_get_wireless_stats,
-};
+		memset(&pcand, 0, sizeof(pcand));
+		if (le32_to_cpu(cand->flags) & 0x01)
+			pcand.flags |= IW_PMKID_CAND_PREAUTH;
+		pcand.index = i;
+		memcpy(pcand.bssid.sa_data, cand->bssid, ETH_ALEN);
 
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = sizeof(pcand);
+		wireless_send_event(usbdev->net, IWEVPMKIDCAND, &wrqu,
+								(u8 *)&pcand);
+#endif
+	}
+}
 
-static void rndis_wlan_worker(struct work_struct *work)
+static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
+			struct rndis_indicate *msg, int buflen)
 {
-	struct rndis_wlan_private *priv =
-		container_of(work, struct rndis_wlan_private, work);
-	struct usbnet *usbdev = priv->usbdev;
-	union iwreq_data evt;
-	unsigned char bssid[ETH_ALEN];
-	struct ndis_80211_assoc_info *info;
-	int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32;
-	int ret, offset;
+	struct ndis_80211_status_indication *indication;
+	int len, offset;
 
-	if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) {
-		netif_carrier_on(usbdev->net);
+	offset = offsetof(struct rndis_indicate, status) +
+			le32_to_cpu(msg->offset);
+	len = le32_to_cpu(msg->length);
 
-		info = kzalloc(assoc_size, GFP_KERNEL);
-		if (!info)
-			goto get_bssid;
+	if (len < 8) {
+		devinfo(usbdev, "media specific indication, "
+				"ignore too short message (%i < 8)", len);
+		return;
+	}
 
-		/* Get association info IEs from device and send them back to
-		 * userspace. */
-		ret = get_association_info(usbdev, info, assoc_size);
-		if (!ret) {
-			evt.data.length = le32_to_cpu(info->req_ie_length);
-			if (evt.data.length > 0) {
-				offset = le32_to_cpu(info->offset_req_ies);
-				wireless_send_event(usbdev->net,
-					IWEVASSOCREQIE, &evt,
-					(char *)info + offset);
-			}
+	if (offset + len > buflen) {
+		devinfo(usbdev, "media specific indication, "
+				"too large to fit to buffer (%i > %i)",
+				offset + len, buflen);
+		return;
+	}
 
-			evt.data.length = le32_to_cpu(info->resp_ie_length);
-			if (evt.data.length > 0) {
-				offset = le32_to_cpu(info->offset_resp_ies);
-				wireless_send_event(usbdev->net,
-					IWEVASSOCRESPIE, &evt,
-					(char *)info + offset);
-			}
-		}
+	indication = (void *)((u8 *)msg + offset);
 
-		kfree(info);
+	switch (le32_to_cpu(indication->status_type)) {
+	case NDIS_80211_STATUSTYPE_RADIOSTATE:
+		devinfo(usbdev, "radio state indication: %i",
+			le32_to_cpu(indication->u.radio_status));
+		return;
 
-get_bssid:
-		ret = get_bssid(usbdev, bssid);
-		if (!ret) {
-			evt.data.flags = 0;
-			evt.data.length = 0;
-			memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
-			wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
-		}
-	}
+	case NDIS_80211_STATUSTYPE_MEDIASTREAMMODE:
+		devinfo(usbdev, "media stream mode indication: %i",
+			le32_to_cpu(indication->u.media_stream_mode));
+		return;
 
-	if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) {
-		netif_carrier_off(usbdev->net);
+	case NDIS_80211_STATUSTYPE_AUTHENTICATION:
+		rndis_wlan_auth_indication(usbdev, indication, len);
+		return;
 
-		evt.data.flags = 0;
-		evt.data.length = 0;
-		memset(evt.ap_addr.sa_data, 0, ETH_ALEN);
-		wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
-	}
+	case NDIS_80211_STATUSTYPE_PMKID_CANDIDATELIST:
+		rndis_wlan_pmkid_cand_list_indication(usbdev, indication, len);
+		return;
 
-	if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
-		set_multicast_list(usbdev);
+	default:
+		devinfo(usbdev, "media specific indication: "
+				"unknown status type 0x%08x",
+				le32_to_cpu(indication->status_type));
+	}
 }
 
-static void rndis_wlan_set_multicast_list(struct net_device *dev)
+static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
 {
-	struct usbnet *usbdev = netdev_priv(dev);
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	struct rndis_indicate *msg = ind;
+
+	switch (msg->status) {
+	case RNDIS_STATUS_MEDIA_CONNECT:
+		if (priv->current_command_oid == OID_802_11_ADD_KEY) {
+			/* OID_802_11_ADD_KEY causes sometimes extra
+			 * "media connect" indications which confuses driver
+			 * and userspace to think that device is
+			 * roaming/reassociating when it isn't.
+			 */
+			devdbg(usbdev, "ignored OID_802_11_ADD_KEY triggered "
+					"'media connect'");
+			return;
+		}
 
-	if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
-		return;
+		usbnet_pause_rx(usbdev);
 
-	set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending);
-	queue_work(priv->workqueue, &priv->work);
-}
+		devinfo(usbdev, "media connect");
 
-static void rndis_wlan_link_change(struct usbnet *usbdev, int state)
-{
-	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+		/* queue work to avoid recursive calls into rndis_command */
+		set_bit(WORK_LINK_UP, &priv->work_pending);
+		queue_work(priv->workqueue, &priv->work);
+		break;
 
-	/* queue work to avoid recursive calls into rndis_command */
-	set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending);
-	queue_work(priv->workqueue, &priv->work);
-}
+	case RNDIS_STATUS_MEDIA_DISCONNECT:
+		devinfo(usbdev, "media disconnect");
+
+		/* queue work to avoid recursive calls into rndis_command */
+		set_bit(WORK_LINK_DOWN, &priv->work_pending);
+		queue_work(priv->workqueue, &priv->work);
+		break;
 
+	case RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION:
+		rndis_wlan_media_specific_indication(usbdev, msg, buflen);
+		break;
+
+	default:
+		devinfo(usbdev, "indication: 0x%08x",
+				le32_to_cpu(msg->status));
+		break;
+	}
+}
 
 static int rndis_wlan_get_caps(struct usbnet *usbdev)
 {
@@ -2177,78 +2517,44 @@ static int rndis_wlan_get_caps(struct usbnet *usbdev)
 	return retval;
 }
 
-
-#define STATS_UPDATE_JIFFIES (HZ)
-static void rndis_update_wireless_stats(struct work_struct *work)
+#define DEVICE_POLLER_JIFFIES (HZ)
+static void rndis_device_poller(struct work_struct *work)
 {
 	struct rndis_wlan_private *priv =
-		container_of(work, struct rndis_wlan_private, stats_work.work);
+		container_of(work, struct rndis_wlan_private,
+							dev_poller_work.work);
 	struct usbnet *usbdev = priv->usbdev;
-	struct iw_statistics iwstats;
 	__le32 rssi, tmp;
 	int len, ret, j;
-	unsigned long flags;
-	int update_jiffies = STATS_UPDATE_JIFFIES;
+	int update_jiffies = DEVICE_POLLER_JIFFIES;
 	void *buf;
 
-	spin_lock_irqsave(&priv->stats_lock, flags);
-	memcpy(&iwstats, &priv->privstats, sizeof(iwstats));
-	spin_unlock_irqrestore(&priv->stats_lock, flags);
-
-	/* only update stats when connected */
-	if (!is_associated(usbdev)) {
-		iwstats.qual.qual = 0;
-		iwstats.qual.level = 0;
-		iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
-				| IW_QUAL_LEVEL_UPDATED
-				| IW_QUAL_NOISE_INVALID
-				| IW_QUAL_QUAL_INVALID
-				| IW_QUAL_LEVEL_INVALID;
+	/* Only check/do workaround when connected. Calling is_associated()
+	 * also polls device with rndis_command() and catches for media link
+	 * indications.
+	 */
+	if (!is_associated(usbdev))
 		goto end;
-	}
 
 	len = sizeof(rssi);
 	ret = rndis_query_oid(usbdev, OID_802_11_RSSI, &rssi, &len);
-
-	devdbg(usbdev, "stats: OID_802_11_RSSI -> %d, rssi:%d", ret,
-							le32_to_cpu(rssi));
-	if (ret == 0) {
-		memset(&iwstats.qual, 0, sizeof(iwstats.qual));
-		iwstats.qual.qual  = level_to_qual(le32_to_cpu(rssi));
-		iwstats.qual.level = level_to_qual(le32_to_cpu(rssi));
-		iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
-				| IW_QUAL_LEVEL_UPDATED
-				| IW_QUAL_NOISE_INVALID;
-	}
-
-	memset(&iwstats.discard, 0, sizeof(iwstats.discard));
-
-	len = sizeof(tmp);
-	ret = rndis_query_oid(usbdev, OID_GEN_XMIT_ERROR, &tmp, &len);
 	if (ret == 0)
-		iwstats.discard.misc += le32_to_cpu(tmp);
+		priv->last_qual = level_to_qual(le32_to_cpu(rssi));
 
-	len = sizeof(tmp);
-	ret = rndis_query_oid(usbdev, OID_GEN_RCV_ERROR, &tmp, &len);
-	if (ret == 0)
-		iwstats.discard.misc += le32_to_cpu(tmp);
-
-	len = sizeof(tmp);
-	ret = rndis_query_oid(usbdev, OID_GEN_RCV_NO_BUFFER, &tmp, &len);
-	if (ret == 0)
-		iwstats.discard.misc += le32_to_cpu(tmp);
+	devdbg(usbdev, "dev-poller: OID_802_11_RSSI -> %d, rssi:%d, qual: %d",
+		ret, le32_to_cpu(rssi), level_to_qual(le32_to_cpu(rssi)));
 
 	/* Workaround transfer stalls on poor quality links.
 	 * TODO: find right way to fix these stalls (as stalls do not happen
 	 * with ndiswrapper/windows driver). */
-	if (iwstats.qual.qual <= 25) {
+	if (priv->last_qual <= 25) {
 		/* Decrease stats worker interval to catch stalls.
 		 * faster. Faster than 400-500ms causes packet loss,
 		 * Slower doesn't catch stalls fast enough.
 		 */
 		j = msecs_to_jiffies(priv->param_workaround_interval);
-		if (j > STATS_UPDATE_JIFFIES)
-			j = STATS_UPDATE_JIFFIES;
+		if (j > DEVICE_POLLER_JIFFIES)
+			j = DEVICE_POLLER_JIFFIES;
 		else if (j <= 0)
 			j = 1;
 		update_jiffies = j;
@@ -2268,11 +2574,8 @@ static void rndis_update_wireless_stats(struct work_struct *work)
 		rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
 		kfree(buf);
 	}
-end:
-	spin_lock_irqsave(&priv->stats_lock, flags);
-	memcpy(&priv->privstats, &iwstats, sizeof(iwstats));
-	spin_unlock_irqrestore(&priv->stats_lock, flags);
 
+end:
 	if (update_jiffies >= HZ)
 		update_jiffies = round_jiffies_relative(update_jiffies);
 	else {
@@ -2281,10 +2584,13 @@ end:
 			update_jiffies = j;
 	}
 
-	queue_delayed_work(priv->workqueue, &priv->stats_work, update_jiffies);
+	queue_delayed_work(priv->workqueue, &priv->dev_poller_work,
+								update_jiffies);
 }
 
-
+/*
+ * driver/device initialization
+ */
 static int bcm4320a_early_init(struct usbnet *usbdev)
 {
 	/* bcm4320a doesn't handle configuration parameters well. Try
@@ -2294,7 +2600,6 @@ static int bcm4320a_early_init(struct usbnet *usbdev)
 	return 0;
 }
 
-
 static int bcm4320b_early_init(struct usbnet *usbdev)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
@@ -2373,7 +2678,6 @@ static const struct net_device_ops rndis_wlan_netdev_ops = {
 	.ndo_set_multicast_list	= rndis_wlan_set_multicast_list,
 };
 
-
 static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
 {
 	struct wiphy *wiphy;
@@ -2398,16 +2702,14 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
 	 * Otherwise we'll be in big trouble in rndis_wlan_early_init().
 	 */
 	usbdev->driver_priv = priv;
-	usbdev->net->wireless_handlers = &rndis_iw_handlers;
 	priv->usbdev = usbdev;
 
 	mutex_init(&priv->command_lock);
-	spin_lock_init(&priv->stats_lock);
 
 	/* because rndis_command() sleeps we need to use workqueue */
 	priv->workqueue = create_singlethread_workqueue("rndis_wlan");
 	INIT_WORK(&priv->work, rndis_wlan_worker);
-	INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
+	INIT_DELAYED_WORK(&priv->dev_poller_work, rndis_device_poller);
 	INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
 
 	/* try bind rndis_host */
@@ -2439,14 +2741,6 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
 	else
 		usbdev->net->flags &= ~IFF_MULTICAST;
 
-	priv->iwstats.qual.qual = 0;
-	priv->iwstats.qual.level = 0;
-	priv->iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
-					| IW_QUAL_LEVEL_UPDATED
-					| IW_QUAL_NOISE_INVALID
-					| IW_QUAL_QUAL_INVALID
-					| IW_QUAL_LEVEL_INVALID;
-
 	/* fill-out wiphy structure and register w/ cfg80211 */
 	memcpy(wiphy->perm_addr, usbdev->net->dev_addr, ETH_ALEN);
 	wiphy->privid = rndis_wiphy_privid;
@@ -2454,7 +2748,7 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
 					| BIT(NL80211_IFTYPE_ADHOC);
 	wiphy->max_scan_ssids = 1;
 
-	/* TODO: fill-out band information based on priv->caps */
+	/* TODO: fill-out band/encr information based on priv->caps */
 	rndis_wlan_get_caps(usbdev);
 
 	memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
@@ -2466,6 +2760,11 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
 	wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
 
+	memcpy(priv->cipher_suites, rndis_cipher_suites,
+						sizeof(rndis_cipher_suites));
+	wiphy->cipher_suites = priv->cipher_suites;
+	wiphy->n_cipher_suites = ARRAY_SIZE(rndis_cipher_suites);
+
 	set_wiphy_dev(wiphy, &usbdev->udev->dev);
 
 	if (wiphy_register(wiphy)) {
@@ -2475,18 +2774,19 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
 
 	set_default_iw_params(usbdev);
 
+	/* set default rts/frag */
+	rndis_set_wiphy_params(wiphy,
+			WIPHY_PARAM_FRAG_THRESHOLD | WIPHY_PARAM_RTS_THRESHOLD);
+
 	/* turn radio on */
-	priv->radio_on = 1;
-	disassociate(usbdev, 1);
+	priv->radio_on = true;
+	disassociate(usbdev, true);
 	netif_carrier_off(usbdev->net);
 
-	queue_delayed_work(priv->workqueue, &priv->stats_work,
-		round_jiffies_relative(STATS_UPDATE_JIFFIES));
-
 	return 0;
 
 fail:
-	cancel_delayed_work_sync(&priv->stats_work);
+	cancel_delayed_work_sync(&priv->dev_poller_work);
 	cancel_delayed_work_sync(&priv->scan_work);
 	cancel_work_sync(&priv->work);
 	flush_workqueue(priv->workqueue);
@@ -2496,15 +2796,14 @@ fail:
 	return retval;
 }
 
-
 static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
 {
 	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
 	/* turn radio off */
-	disassociate(usbdev, 0);
+	disassociate(usbdev, false);
 
-	cancel_delayed_work_sync(&priv->stats_work);
+	cancel_delayed_work_sync(&priv->dev_poller_work);
 	cancel_delayed_work_sync(&priv->scan_work);
 	cancel_work_sync(&priv->work);
 	flush_workqueue(priv->workqueue);
@@ -2519,50 +2818,100 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
 	wiphy_free(priv->wdev.wiphy);
 }
 
-
 static int rndis_wlan_reset(struct usbnet *usbdev)
 {
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	int retval;
+
+	devdbg(usbdev, "rndis_wlan_reset");
+
+	retval = rndis_reset(usbdev);
+	if (retval)
+		devwarn(usbdev, "rndis_reset() failed: %d", retval);
+
+	/* rndis_reset cleared multicast list, so restore here.
+	   (set_multicast_list() also turns on current packet filter) */
+	set_multicast_list(usbdev);
+
+	queue_delayed_work(priv->workqueue, &priv->dev_poller_work,
+		round_jiffies_relative(DEVICE_POLLER_JIFFIES));
+
 	return deauthenticate(usbdev);
 }
 
+static int rndis_wlan_stop(struct usbnet *usbdev)
+{
+	struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+	int retval;
+	__le32 filter;
+
+	devdbg(usbdev, "rndis_wlan_stop");
+
+	retval = disassociate(usbdev, false);
+
+	priv->work_pending = 0;
+	cancel_delayed_work_sync(&priv->dev_poller_work);
+	cancel_delayed_work_sync(&priv->scan_work);
+	cancel_work_sync(&priv->work);
+	flush_workqueue(priv->workqueue);
+
+	if (priv->scan_request) {
+		cfg80211_scan_done(priv->scan_request, true);
+		priv->scan_request = NULL;
+	}
+
+	/* Set current packet filter zero to block receiving data packets from
+	   device. */
+	filter = 0;
+	rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
+								sizeof(filter));
+
+	return retval;
+}
 
 static const struct driver_info	bcm4320b_info = {
 	.description =	"Wireless RNDIS device, BCM4320b based",
-	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
+				FLAG_AVOID_UNLINK_URBS,
 	.bind =		rndis_wlan_bind,
 	.unbind =	rndis_wlan_unbind,
 	.status =	rndis_status,
 	.rx_fixup =	rndis_rx_fixup,
 	.tx_fixup =	rndis_tx_fixup,
 	.reset =	rndis_wlan_reset,
+	.stop =		rndis_wlan_stop,
 	.early_init =	bcm4320b_early_init,
-	.link_change =	rndis_wlan_link_change,
+	.indication =	rndis_wlan_indication,
 };
 
 static const struct driver_info	bcm4320a_info = {
 	.description =	"Wireless RNDIS device, BCM4320a based",
-	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
+				FLAG_AVOID_UNLINK_URBS,
 	.bind =		rndis_wlan_bind,
 	.unbind =	rndis_wlan_unbind,
 	.status =	rndis_status,
 	.rx_fixup =	rndis_rx_fixup,
 	.tx_fixup =	rndis_tx_fixup,
 	.reset =	rndis_wlan_reset,
+	.stop =		rndis_wlan_stop,
 	.early_init =	bcm4320a_early_init,
-	.link_change =	rndis_wlan_link_change,
+	.indication =	rndis_wlan_indication,
 };
 
 static const struct driver_info rndis_wlan_info = {
 	.description =	"Wireless RNDIS device",
-	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+	.flags =	FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
+				FLAG_AVOID_UNLINK_URBS,
 	.bind =		rndis_wlan_bind,
 	.unbind =	rndis_wlan_unbind,
 	.status =	rndis_status,
 	.rx_fixup =	rndis_rx_fixup,
 	.tx_fixup =	rndis_tx_fixup,
 	.reset =	rndis_wlan_reset,
+	.stop =		rndis_wlan_stop,
 	.early_init =	bcm4320a_early_init,
-	.link_change =	rndis_wlan_link_change,
+	.indication =	rndis_wlan_indication,
 };
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 8aab3e6..ed1f997 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -1,8 +1,8 @@
 menuconfig RT2X00
 	tristate "Ralink driver support"
-	depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
+	depends on MAC80211 && WLAN_80211
 	---help---
-	  This will enable the experimental support for the Ralink drivers,
+	  This will enable the support for the Ralink drivers,
 	  developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
 
 	  These drivers make use of the mac80211 stack.
@@ -79,14 +79,14 @@ config RT73USB
 
 config RT2800USB
 	tristate "Ralink rt2800 (USB) support"
-	depends on USB
+	depends on USB && EXPERIMENTAL
 	select RT2X00_LIB_USB
 	select RT2X00_LIB_HT
 	select RT2X00_LIB_FIRMWARE
 	select RT2X00_LIB_CRYPTO
 	select CRC_CCITT
 	---help---
-	  This adds support for rt2800 wireless chipset family.
+	  This adds experimental support for rt2800 wireless chipset family.
 	  Supported chips: RT2770, RT2870 & RT3070.
 
 	  When compiled as a module, this driver will be called "rt2800usb.ko".
@@ -112,14 +112,6 @@ config RT2X00_LIB_FIRMWARE
 config RT2X00_LIB_CRYPTO
 	boolean
 
-config RT2X00_LIB_RFKILL
-	boolean
-	default y if (RT2X00_LIB=y && INPUT=y) || (RT2X00_LIB=m && INPUT!=n)
-	select INPUT_POLLDEV
-
-comment "rt2x00 rfkill support disabled due to modularized INPUT and built-in rt2x00"
-	depends on RT2X00_LIB=y && INPUT=m
-
 config RT2X00_LIB_LEDS
 	boolean
 	default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index bfc7226..13043ea 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -5,7 +5,6 @@ rt2x00lib-y				+= rt2x00queue.o
 rt2x00lib-y				+= rt2x00link.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS)	+= rt2x00debug.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO)	+= rt2x00crypto.o
-rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL)	+= rt2x00rfkill.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE)	+= rt2x00firmware.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS)	+= rt2x00leds.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_HT)	+= rt2x00ht.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 435f945..798f625 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -199,7 +199,6 @@ static const struct rt2x00debug rt2400pci_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -207,9 +206,6 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 	rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
 	return rt2x00_get_field32(reg, GPIOCSR_BIT0);
 }
-#else
-#define rt2400pci_rfkill_poll	NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt2400pci_brightness_set(struct led_classdev *led_cdev,
@@ -335,9 +331,8 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
 	preamble_mask = erp->short_preamble << 3;
 
 	rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
-	rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout);
-	rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
-			   erp->ack_consume_time);
+	rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
+	rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
 	rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
 	rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
 	rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
@@ -1073,8 +1068,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry)
 	 * otherwise we might be sending out invalid data.
 	 */
 	rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
-	rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
-	rt2x00_set_field32(&reg, CSR14_TBCN, 0);
 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
 	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 
@@ -1391,10 +1384,8 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
 		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 	/*
 	 * Check if the BBP tuning should be enabled.
@@ -1567,12 +1558,14 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
 	.remove_interface	= rt2x00mac_remove_interface,
 	.config			= rt2x00mac_config,
 	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt2x00mac_set_tim,
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt2400pci_conf_tx,
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt2400pci_get_tsf,
 	.tx_last_beacon		= rt2400pci_tx_last_beacon,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index ec3b004..ccd6441 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -928,7 +928,7 @@
 #define RXD_W7_RESERVED			FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  * NOTE: Logics in rt2400pci for txpower are reversed
  * compared to the other rt2x00 drivers. A higher txpower
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 08b30d0..2e872ac 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -199,7 +199,6 @@ static const struct rt2x00debug rt2500pci_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -207,9 +206,6 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 	rt2x00pci_register_read(rt2x00dev, GPIOCSR, &reg);
 	return rt2x00_get_field32(reg, GPIOCSR_BIT0);
 }
-#else
-#define rt2500pci_rfkill_poll	NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt2500pci_brightness_set(struct led_classdev *led_cdev,
@@ -341,9 +337,8 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
 	preamble_mask = erp->short_preamble << 3;
 
 	rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
-	rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout);
-	rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
-			   erp->ack_consume_time);
+	rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x162);
+	rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0xa2);
 	rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
 	rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
 	rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
@@ -1231,8 +1226,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry)
 	 * otherwise we might be sending out invalid data.
 	 */
 	rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
-	rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
-	rt2x00_set_field32(&reg, CSR14_TBCN, 0);
 	rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
 	rt2x00pci_register_write(rt2x00dev, CSR14, reg);
 
@@ -1548,10 +1541,8 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
 		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 	/*
 	 * Check if the BBP tuning should be enabled.
@@ -1866,12 +1857,14 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
 	.remove_interface	= rt2x00mac_remove_interface,
 	.config			= rt2x00mac_config,
 	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt2x00mac_set_tim,
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt2x00mac_conf_tx,
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt2500pci_get_tsf,
 	.tx_last_beacon		= rt2500pci_tx_last_beacon,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index ce2f065..54d3795 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1218,7 +1218,7 @@
 #define RXD_W10_DROP			FIELD32(0x00000001)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index ce75426..22dd6d9 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -277,7 +277,6 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
 	u16 reg;
@@ -285,9 +284,6 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 	rt2500usb_register_read(rt2x00dev, MAC_CSR19, &reg);
 	return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
 }
-#else
-#define rt2500usb_rfkill_poll	NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt2500usb_brightness_set(struct led_classdev *led_cdev,
@@ -492,10 +488,6 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
 {
 	u16 reg;
 
-	rt2500usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
-	rt2x00_set_field16(&reg, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout);
-	rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg);
-
 	rt2500usb_register_read(rt2x00dev, TXRX_CSR10, &reg);
 	rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
 			   !!erp->short_preamble);
@@ -1242,8 +1234,6 @@ static void rt2500usb_write_beacon(struct queue_entry *entry)
 	 * otherwise we might be sending out invalid data.
 	 */
 	rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
-	rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
-	rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
 	rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
 	rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
 
@@ -1291,7 +1281,7 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry)
 static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 				    const enum data_queue_qid queue)
 {
-	u16 reg;
+	u16 reg, reg0;
 
 	if (queue != QID_BEACON) {
 		rt2x00usb_kick_tx_queue(rt2x00dev, queue);
@@ -1302,16 +1292,19 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 	if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) {
 		rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
 		rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
+		reg0 = reg;
 		rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 1);
 		/*
 		 * Beacon generation will fail initially.
-		 * To prevent this we need to register the TXRX_CSR19
-		 * register several times.
+		 * To prevent this we need to change the TXRX_CSR19
+		 * register several times (reg0 is the same as reg
+		 * except for TXRX_CSR19_BEACON_GEN, which is 0 in reg0
+		 * and 1 in reg).
 		 */
 		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
-		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0);
+		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
 		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
-		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0);
+		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg0);
 		rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
 	}
 }
@@ -1603,10 +1596,8 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
 		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 	/*
 	 * Check if the BBP tuning should be disabled.
@@ -1879,7 +1870,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 	 */
 	__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
 	if (!modparam_nohwcrypt) {
 		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
 		__set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
@@ -1902,11 +1892,13 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
 	.remove_interface	= rt2x00mac_remove_interface,
 	.config			= rt2x00mac_config,
 	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt2x00mac_set_tim,
 	.set_key		= rt2x00mac_set_key,
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt2x00mac_conf_tx,
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 5bc46fe..b01edca 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -831,7 +831,7 @@
 #define RXD_W3_EIV			FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 3756166..a084077 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -264,7 +264,6 @@ static const struct rt2x00debug rt2800usb_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt2800usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -272,9 +271,6 @@ static int rt2800usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 	rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
 	return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
 }
-#else
-#define rt2800usb_rfkill_poll	NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt2800usb_brightness_set(struct led_classdev *led_cdev,
@@ -522,7 +518,7 @@ static void rt2800usb_config_filter(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_RTS,
 			   !(filter_flags & FIF_CONTROL));
 	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
-			   !(filter_flags & FIF_CONTROL));
+			   !(filter_flags & FIF_PSPOLL));
 	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
 	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
 	rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
@@ -584,8 +580,7 @@ static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev,
 	u32 reg;
 
 	rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
-	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT,
-			   DIV_ROUND_UP(erp->ack_timeout, erp->slot_time));
+	rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 0x20);
 	rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
 
 	rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
@@ -1467,6 +1462,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * ASIC will keep garbage value after boot, clear encryption keys.
 	 */
+	for (i = 0; i < 4; i++)
+		rt2x00usb_register_write(rt2x00dev,
+					 SHARED_KEY_MODE_ENTRY(i), 0);
+
 	for (i = 0; i < 256; i++) {
 		u32 wcid[2] = { 0xffffffff, 0x00ffffff };
 		rt2x00usb_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
@@ -1476,10 +1475,6 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
 		rt2x00usb_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
 	}
 
-	for (i = 0; i < 16; i++)
-		rt2x00usb_register_write(rt2x00dev,
-					 SHARED_KEY_MODE_ENTRY(i), 0);
-
 	/*
 	 * Clear all beacons
 	 * For the Beacon base registers we only need to clear
@@ -1524,7 +1519,7 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
 	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
 	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
-	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 3);
+	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 9);
 	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
 	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
 	rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
@@ -1914,7 +1909,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 		/*
 		 * Before the radio can be enabled, the device first has
 		 * to be woken up. After that it needs a bit of time
-		 * to be fully awake and the radio can be enabled.
+		 * to be fully awake and then the radio can be enabled.
 		 */
 		rt2800usb_set_state(rt2x00dev, STATE_AWAKE);
 		msleep(1);
@@ -1922,7 +1917,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
 		break;
 	case STATE_RADIO_OFF:
 		/*
-		 * After the radio has been disablee, the device should
+		 * After the radio has been disabled, the device should
 		 * be put to sleep for powersaving.
 		 */
 		rt2800usb_disable_radio(rt2x00dev);
@@ -1999,11 +1994,11 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
 	rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
 			   test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
-			       txdesc->key_idx : 0xff);
+			       (skbdesc->entry->entry_idx + 1) : 0xff);
 	rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
 			   skb->len - txdesc->l2pad);
 	rt2x00_set_field32(&word, TXWI_W1_PACKETID,
-			   skbdesc->entry->entry_idx);
+			   skbdesc->entry->queue->qid + 1);
 	rt2x00_desc_write(txwi, 1, word);
 
 	/*
@@ -2054,8 +2049,6 @@ static void rt2800usb_write_beacon(struct queue_entry *entry)
 	 * otherwise we might be sending out invalid data.
 	 */
 	rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
-	rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
 	rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
 	rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
@@ -2169,8 +2162,10 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
 	if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
 		rxdesc->dev_flags |= RXDONE_MY_BSS;
 
-	if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
+	if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) {
 		rxdesc->dev_flags |= RXDONE_L2PAD;
+		skbdesc->flags |= SKBDESC_L2_PADDED;
+	}
 
 	if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
 		rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -2224,10 +2219,8 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
 	 */
 	mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
 	if (!is_valid_ether_addr(mac)) {
-		DECLARE_MAC_BUF(macbuf);
-
 		random_ether_addr(mac);
-		EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+		EEPROM(rt2x00dev, "MAC: %pM\n", mac);
 	}
 
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -2385,10 +2378,8 @@ static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
 		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 	/*
 	 * Store led settings, for correct led behaviour.
@@ -2632,10 +2623,16 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 		return retval;
 
 	/*
+	 * This device has multiple filters for control frames
+	 * and has a separate filter for PS Poll frames.
+	 */
+	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+	__set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
+
+	/*
 	 * This device requires firmware.
 	 */
 	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
 	__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
 	if (!modparam_nohwcrypt)
 		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
@@ -2792,6 +2789,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
 	.remove_interface	= rt2x00mac_remove_interface,
 	.config			= rt2x00mac_config,
 	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt2x00mac_set_tim,
 	.set_key		= rt2x00mac_set_key,
 	.get_stats		= rt2x00mac_get_stats,
 	.get_tkip_seq		= rt2800usb_get_tkip_seq,
@@ -2800,6 +2798,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
 	.conf_tx		= rt2800usb_conf_tx,
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt2800usb_get_tsf,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 61a8be6..4d9991c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -36,6 +36,9 @@
  * RF2750 2.4G/5G 1T2R
  * RF3020 2.4G 1T1R
  * RF2020 2.4G B/G
+ * RF3021 2.4G 1T2R
+ * RF3022 2.4G 2T2R
+ * RF3052 2.4G 2T2R
  */
 #define RF2820				0x0001
 #define RF2850				0x0002
@@ -43,6 +46,9 @@
 #define RF2750				0x0004
 #define RF3020				0x0005
 #define RF2020				0x0006
+#define RF3021				0x0007
+#define RF3022				0x0008
+#define RF3052				0x0009
 
 /*
  * RT2870 version
@@ -1300,8 +1306,8 @@
  * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
  * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
  * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry
- * SHARED_KEY_TABLE_BASE: 32-byte * 16-entry
- * SHARED_KEY_MODE_BASE: 4-byte * 16-entry
+ * SHARED_KEY_TABLE_BASE: 32 bytes * 32-entry
+ * SHARED_KEY_MODE_BASE: 4 bits * 32-entry
  */
 #define MAC_WCID_BASE			0x1800
 #define PAIRWISE_KEY_TABLE_BASE		0x4000
@@ -1921,7 +1927,7 @@ struct mac_iveiv_entry {
 #define RXWI_W3_SNR1			FIELD32(0x0000ff00)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_G_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 49c9e2c..27bc6b7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -134,6 +134,17 @@
 				  GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) )
 
 /*
+ * Structure for average calculation
+ * The avg field contains the actual average value,
+ * but avg_weight is internally used during calculations
+ * to prevent rounding errors.
+ */
+struct avg_val {
+	int avg;
+	int avg_weight;
+};
+
+/*
  * Chipset identification
  * The chipset on the device is composed of a RT and RF chip.
  * The chipset combination is important for determining device capabilities.
@@ -245,21 +256,18 @@ struct link_ant {
 	struct antenna_setup active;
 
 	/*
-	 * RSSI information for the different antenna's.
-	 * These statistics are used to determine when
-	 * to switch antenna when using software diversity.
-	 *
-	 *        rssi[0] -> Antenna A RSSI
-	 *        rssi[1] -> Antenna B RSSI
+	 * RSSI history information for the antenna.
+	 * Used to determine when to switch antenna
+	 * when using software diversity.
 	 */
-	int rssi_history[2];
+	int rssi_history;
 
 	/*
 	 * Current RSSI average of the currently active antenna.
 	 * Similar to the avg_rssi in the link_qual structure
 	 * this value is updated by using the walking average.
 	 */
-	int rssi_ant;
+	struct avg_val rssi_ant;
 };
 
 /*
@@ -288,7 +296,7 @@ struct link {
 	/*
 	 * Currently active average RSSI value
 	 */
-	int avg_rssi;
+	struct avg_val avg_rssi;
 
 	/*
 	 * Currently precalculated percentages of successful
@@ -326,6 +334,11 @@ struct rt2x00_intf {
 	u8 bssid[ETH_ALEN];
 
 	/*
+	 * beacon->skb must be protected with the mutex.
+	 */
+	struct mutex beacon_skb_mutex;
+
+	/*
 	 * Entry in the beacon queue which belongs to
 	 * this interface. Each interface has its own
 	 * dedicated beacon entry.
@@ -337,8 +350,6 @@ struct rt2x00_intf {
 	 */
 	unsigned int delayed_flags;
 #define DELAYED_UPDATE_BEACON		0x00000001
-#define DELAYED_CONFIG_ERP		0x00000002
-#define DELAYED_LED_ASSOC		0x00000004
 
 	/*
 	 * Software sequence counter, this is only required
@@ -406,9 +417,6 @@ struct rt2x00lib_erp {
 	int short_preamble;
 	int cts_protection;
 
-	int ack_timeout;
-	int ack_consume_time;
-
 	u32 basic_rates;
 
 	int slot_time;
@@ -594,7 +602,6 @@ enum rt2x00_flags {
 	DEVICE_STATE_INITIALIZED,
 	DEVICE_STATE_STARTED,
 	DEVICE_STATE_ENABLED_RADIO,
-	DEVICE_STATE_DISABLED_RADIO_HW,
 
 	/*
 	 * Driver requirements
@@ -602,7 +609,6 @@ enum rt2x00_flags {
 	DRIVER_REQUIRE_FIRMWARE,
 	DRIVER_REQUIRE_BEACON_GUARD,
 	DRIVER_REQUIRE_ATIM_QUEUE,
-	DRIVER_REQUIRE_SCHEDULED,
 	DRIVER_REQUIRE_DMA,
 	DRIVER_REQUIRE_COPY_IV,
 	DRIVER_REQUIRE_L2PAD,
@@ -612,6 +618,8 @@ enum rt2x00_flags {
 	 */
 	CONFIG_SUPPORT_HW_BUTTON,
 	CONFIG_SUPPORT_HW_CRYPTO,
+	DRIVER_SUPPORT_CONTROL_FILTERS,
+	DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
 
 	/*
 	 * Driver configuration
@@ -634,7 +642,7 @@ struct rt2x00_dev {
 	 * The structure stored in here depends on the
 	 * system bus (PCI or USB).
 	 * When accessing this variable, the rt2x00dev_{pci,usb}
-	 * macro's should be used for correct typecasting.
+	 * macros should be used for correct typecasting.
 	 */
 	struct device *dev;
 
@@ -651,18 +659,6 @@ struct rt2x00_dev {
 	enum ieee80211_band curr_band;
 
 	/*
-	 * rfkill structure for RF state switching support.
-	 * This will only be compiled in when required.
-	 */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
-	unsigned long rfkill_state;
-#define RFKILL_STATE_ALLOCATED		1
-#define RFKILL_STATE_REGISTERED		2
-#define RFKILL_STATE_BLOCKED		3
-	struct input_polled_dev *rfkill_poll_dev;
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
-
-	/*
 	 * If enabled, the debugfs interface structures
 	 * required for deregistration of debugfs.
 	 */
@@ -824,7 +820,6 @@ struct rt2x00_dev {
 	 * due to RTNL locking requirements.
 	 */
 	struct work_struct intf_work;
-	struct work_struct filter_work;
 
 	/*
 	 * Data queue arrays for RX, TX and Beacon.
@@ -976,7 +971,9 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
 void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
 				unsigned int changed_flags,
 				unsigned int *total_flags,
-				int mc_count, struct dev_addr_list *mc_list);
+				u64 multicast);
+int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+		      bool set);
 #ifdef CONFIG_RT2X00_LIB_CRYPTO
 int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		      struct ieee80211_vif *vif, struct ieee80211_sta *sta,
@@ -994,6 +991,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 				u32 changes);
 int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
 		      const struct ieee80211_tx_queue_params *params);
+void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
 
 /*
  * Driver allocation handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 3e019a1..40a201e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -94,17 +94,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
 	erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS;
 	erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS;
 
-	erp.ack_timeout = PLCP + erp.difs + GET_DURATION(ACK_SIZE, 10);
-	erp.ack_consume_time = SIFS + PLCP + GET_DURATION(ACK_SIZE, 10);
-
-	if (bss_conf->use_short_preamble) {
-		erp.ack_timeout += SHORT_PREAMBLE;
-		erp.ack_consume_time += SHORT_PREAMBLE;
-	} else {
-		erp.ack_timeout += PREAMBLE;
-		erp.ack_consume_time += PREAMBLE;
-	}
-
 	erp.basic_rates = bss_conf->basic_rates;
 	erp.beacon_int = bss_conf->beacon_int;
 
@@ -124,24 +113,34 @@ enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant,
 }
 
 void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
-			      struct antenna_setup *ant)
+			      struct antenna_setup config)
 {
+	struct link_ant *ant = &rt2x00dev->link.ant;
 	struct antenna_setup *def = &rt2x00dev->default_ant;
 	struct antenna_setup *active = &rt2x00dev->link.ant.active;
 
 	/*
 	 * Failsafe: Make sure we are not sending the
 	 * ANTENNA_SW_DIVERSITY state to the driver.
-	 * If that happes fallback to hardware default,
+	 * If that happens, fallback to hardware defaults,
 	 * or our own default.
+	 * If diversity handling is active for a particular antenna,
+	 * we shouldn't overwrite that antenna.
 	 * The calls to rt2x00lib_config_antenna_check()
 	 * might have caused that we restore back to the already
 	 * active setting. If that has happened we can quit.
 	 */
-	ant->rx = rt2x00lib_config_antenna_check(ant->rx, def->rx);
-	ant->tx = rt2x00lib_config_antenna_check(ant->tx, def->tx);
+	if (!(ant->flags & ANTENNA_RX_DIVERSITY))
+		config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
+	else
+		config.rx = active->rx;
+
+	if (!(ant->flags & ANTENNA_TX_DIVERSITY))
+		config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx);
+	else
+		config.tx = active->tx;
 
-	if (ant->rx == active->rx && ant->tx == active->tx)
+	if (config.rx == active->rx && config.tx == active->tx)
 		return;
 
 	/*
@@ -156,11 +155,11 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 	 * The latter is required since we need to recalibrate the
 	 * noise-sensitivity ratio for the new setup.
 	 */
-	rt2x00dev->ops->lib->config_ant(rt2x00dev, ant);
+	rt2x00dev->ops->lib->config_ant(rt2x00dev, &config);
 
 	rt2x00link_reset_tuner(rt2x00dev, true);
 
-	memcpy(active, ant, sizeof(*ant));
+	memcpy(active, &config, sizeof(config));
 
 	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
 		rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index bc4e81e..de36837 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -53,8 +53,7 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
 
-	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
-	    !hw_key || entry->skb->do_not_encrypt)
+	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !hw_key)
 		return;
 
 	__set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
@@ -82,8 +81,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
 	struct ieee80211_key_conf *key = tx_info->control.hw_key;
 	unsigned int overhead = 0;
 
-	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) ||
-	    !key || skb->do_not_encrypt)
+	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !key)
 		return overhead;
 
 	/*
@@ -131,7 +129,7 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
 	/* Pull buffer to correct size */
 	skb_pull(skb, txdesc->iv_len);
 
-	/* IV/EIV data has officially be stripped */
+	/* IV/EIV data has officially been stripped */
 	skbdesc->flags |= SKBDESC_IV_STRIPPED;
 }
 
@@ -156,7 +154,7 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length)
 	skbdesc->flags &= ~SKBDESC_IV_STRIPPED;
 }
 
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
 			       unsigned int header_length,
 			       struct rxdone_entry_desc *rxdesc)
 {
@@ -201,7 +199,7 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
 	 * move the header more then iv_len since we must
 	 * make room for the payload move as well.
 	 */
-	if (l2pad) {
+	if (rxdesc->dev_flags & RXDONE_L2PAD) {
 		skb_push(skb, iv_len - align);
 		skb_put(skb, icv_len);
 
@@ -232,7 +230,7 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
 	 * Move payload for alignment purposes. Note that
 	 * this is only needed when no l2 padding is present.
 	 */
-	if (!l2pad) {
+	if (!(rxdesc->dev_flags & RXDONE_L2PAD)) {
 		memmove(skb->data + transfer,
 			skb->data + transfer + align,
 			payload_len);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 57813e7..71761b3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -40,8 +40,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
 	 * Don't enable the radio twice.
 	 * And check if the hardware button has been disabled.
 	 */
-	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
-	    test_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags))
+	if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
 		return 0;
 
 	/*
@@ -119,20 +118,11 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
 		rt2x00link_start_tuner(rt2x00dev);
 }
 
-static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
-{
-	struct rt2x00_dev *rt2x00dev =
-	    container_of(work, struct rt2x00_dev, filter_work);
-
-	rt2x00dev->ops->lib->config_filter(rt2x00dev, rt2x00dev->packet_filter);
-}
-
 static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 					  struct ieee80211_vif *vif)
 {
 	struct rt2x00_dev *rt2x00dev = data;
 	struct rt2x00_intf *intf = vif_to_intf(vif);
-	struct ieee80211_bss_conf conf;
 	int delayed_flags;
 
 	/*
@@ -142,7 +132,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 	 */
 	spin_lock(&intf->lock);
 
-	memcpy(&conf, &vif->bss_conf, sizeof(conf));
 	delayed_flags = intf->delayed_flags;
 	intf->delayed_flags = 0;
 
@@ -159,12 +148,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 
 	if (delayed_flags & DELAYED_UPDATE_BEACON)
 		rt2x00queue_update_beacon(rt2x00dev, vif, true);
-
-	if (delayed_flags & DELAYED_CONFIG_ERP)
-		rt2x00lib_config_erp(rt2x00dev, intf, &conf);
-
-	if (delayed_flags & DELAYED_LED_ASSOC)
-		rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
 }
 
 static void rt2x00lib_intf_scheduled(struct work_struct *work)
@@ -187,7 +170,6 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
 static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
 				      struct ieee80211_vif *vif)
 {
-	struct rt2x00_dev *rt2x00dev = data;
 	struct rt2x00_intf *intf = vif_to_intf(vif);
 
 	if (vif->type != NL80211_IFTYPE_AP &&
@@ -196,12 +178,6 @@ static void rt2x00lib_beacondone_iter(void *data, u8 *mac,
 	    vif->type != NL80211_IFTYPE_WDS)
 		return;
 
-	/*
-	 * Clean up the beacon skb.
-	 */
-	rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
-	intf->beacon->skb = NULL;
-
 	spin_lock(&intf->lock);
 	intf->delayed_flags |= DELAYED_UPDATE_BEACON;
 	spin_unlock(&intf->lock);
@@ -216,7 +192,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
 						   rt2x00lib_beacondone_iter,
 						   rt2x00dev);
 
-	queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+	ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
 
@@ -228,7 +204,9 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
 	enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
 	unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
-	u8 rate_idx, rate_flags;
+	u8 rate_idx, rate_flags, retry_rates;
+	unsigned int i;
+	bool success;
 
 	/*
 	 * Unmap the skb.
@@ -239,7 +217,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	 * Remove L2 padding which was added during
 	 */
 	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
-		rt2x00queue_payload_align(entry->skb, true, header_length);
+		rt2x00queue_remove_l2pad(entry->skb, header_length);
 
 	/*
 	 * If the IV/EIV data was stripped from the frame before it was
@@ -257,40 +235,54 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
 
 	/*
-	 * Update TX statistics.
+	 * Determine if the frame has been successfully transmitted.
 	 */
-	rt2x00dev->link.qual.tx_success +=
+	success =
 	    test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
-	    test_bit(TXDONE_UNKNOWN, &txdesc->flags);
-	rt2x00dev->link.qual.tx_failed +=
-	    test_bit(TXDONE_FAILURE, &txdesc->flags);
+	    test_bit(TXDONE_UNKNOWN, &txdesc->flags) ||
+	    test_bit(TXDONE_FALLBACK, &txdesc->flags);
+
+	/*
+	 * Update TX statistics.
+	 */
+	rt2x00dev->link.qual.tx_success += success;
+	rt2x00dev->link.qual.tx_failed += !success;
 
 	rate_idx = skbdesc->tx_rate_idx;
 	rate_flags = skbdesc->tx_rate_flags;
+	retry_rates = test_bit(TXDONE_FALLBACK, &txdesc->flags) ?
+	    (txdesc->retry + 1) : 1;
 
 	/*
 	 * Initialize TX status
 	 */
 	memset(&tx_info->status, 0, sizeof(tx_info->status));
 	tx_info->status.ack_signal = 0;
-	tx_info->status.rates[0].idx = rate_idx;
-	tx_info->status.rates[0].flags = rate_flags;
-	tx_info->status.rates[0].count = txdesc->retry + 1;
-	tx_info->status.rates[1].idx = -1; /* terminate */
+
+	/*
+	 * Frame was send with retries, hardware tried
+	 * different rates to send out the frame, at each
+	 * retry it lowered the rate 1 step.
+	 */
+	for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) {
+		tx_info->status.rates[i].idx = rate_idx - i;
+		tx_info->status.rates[i].flags = rate_flags;
+		tx_info->status.rates[i].count = 1;
+	}
+	if (i < (IEEE80211_TX_MAX_RATES - 1))
+		tx_info->status.rates[i].idx = -1; /* terminate */
 
 	if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
-		if (test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
-				test_bit(TXDONE_UNKNOWN, &txdesc->flags))
+		if (success)
 			tx_info->flags |= IEEE80211_TX_STAT_ACK;
-		else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
+		else
 			rt2x00dev->low_level_stats.dot11ACKFailureCount++;
 	}
 
 	if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
-		if (test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
-				test_bit(TXDONE_UNKNOWN, &txdesc->flags))
+		if (success)
 			rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
-		else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
+		else
 			rt2x00dev->low_level_stats.dot11RTSFailureCount++;
 	}
 
@@ -372,7 +364,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
 	struct sk_buff *skb;
 	struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
 	unsigned int header_length;
-	bool l2pad;
 	int rate_idx;
 	/*
 	 * Allocate a new sk_buffer. If no new buffer available, drop the
@@ -401,7 +392,6 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
 	 * aligned on a 4 byte boundary.
 	 */
 	header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
-	l2pad = !!(rxdesc.dev_flags & RXDONE_L2PAD);
 
 	/*
 	 * Hardware might have stripped the IV/EIV/ICV data,
@@ -411,10 +401,12 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
 	 */
 	if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
 	    (rxdesc.flags & RX_FLAG_IV_STRIPPED))
-		rt2x00crypto_rx_insert_iv(entry->skb, l2pad, header_length,
+		rt2x00crypto_rx_insert_iv(entry->skb, header_length,
 					  &rxdesc);
+	else if (rxdesc.dev_flags & RXDONE_L2PAD)
+		rt2x00queue_remove_l2pad(entry->skb, header_length);
 	else
-		rt2x00queue_payload_align(entry->skb, l2pad, header_length);
+		rt2x00queue_align_payload(entry->skb, header_length);
 
 	/*
 	 * Check if the frame was received using HT. In that case,
@@ -449,7 +441,8 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
 	 * mac80211 will clean up the skb structure.
 	 */
 	rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
-	ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status);
+	memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status));
+	ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb);
 
 	/*
 	 * Replace the skb with the freshly allocated one.
@@ -785,6 +778,13 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
 	rt2x00dev->intf_sta_count = 0;
 	rt2x00dev->intf_associated = 0;
 
+	/* Enable the radio */
+	retval = rt2x00lib_enable_radio(rt2x00dev);
+	if (retval) {
+		rt2x00queue_uninitialize(rt2x00dev);
+		return retval;
+	}
+
 	set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
 
 	return 0;
@@ -847,7 +847,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 	 * Initialize configuration work.
 	 */
 	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
-	INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
 
 	/*
 	 * Allocate queue array.
@@ -870,7 +869,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
 	 */
 	rt2x00link_register(rt2x00dev);
 	rt2x00leds_register(rt2x00dev);
-	rt2x00rfkill_allocate(rt2x00dev);
 	rt2x00debug_register(rt2x00dev);
 
 	set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
@@ -894,6 +892,11 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 	rt2x00lib_disable_radio(rt2x00dev);
 
 	/*
+	 * Stop all work.
+	 */
+	cancel_work_sync(&rt2x00dev->intf_work);
+
+	/*
 	 * Uninitialize device.
 	 */
 	rt2x00lib_uninitialize(rt2x00dev);
@@ -902,7 +905,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 	 * Free extra components
 	 */
 	rt2x00debug_deregister(rt2x00dev);
-	rt2x00rfkill_free(rt2x00dev);
 	rt2x00leds_unregister(rt2x00dev);
 
 	/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 0bf2715..5462cb5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -30,10 +30,8 @@
 
 /*
  * Interval defines
- * Both the link tuner as the rfkill will be called once per second.
  */
 #define LINK_TUNE_INTERVAL	round_jiffies_relative(HZ)
-#define RFKILL_POLL_INTERVAL	1000
 
 /*
  * rt2x00_rate: Per rate device information
@@ -90,7 +88,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
 			  struct rt2x00_intf *intf,
 			  struct ieee80211_bss_conf *conf);
 void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
-			      struct antenna_setup *ant);
+			      struct antenna_setup ant);
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
 		      struct ieee80211_conf *conf,
 		      const unsigned int changed_flags);
@@ -122,21 +120,42 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
 void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
 
 /**
- * rt2x00queue_payload_align - Align 802.11 payload to 4-byte boundary
+ * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary
+ * @skb: The skb to align
+ *
+ * Align the start of the 802.11 frame to a 4-byte boundary, this could
+ * mean the payload is not aligned properly though.
+ */
+void rt2x00queue_align_frame(struct sk_buff *skb);
+
+/**
+ * rt2x00queue_align_payload - Align 802.11 payload to 4-byte boundary
+ * @skb: The skb to align
+ * @header_length: Length of 802.11 header
+ *
+ * Align the 802.11 payload to a 4-byte boundary, this could
+ * mean the header is not aligned properly though.
+ */
+void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length);
+
+/**
+ * rt2x00queue_insert_l2pad - Align 802.11 header & payload to 4-byte boundary
+ * @skb: The skb to align
+ * @header_length: Length of 802.11 header
+ *
+ * Apply L2 padding to align both header and payload to 4-byte boundary
+ */
+void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length);
+
+/**
+ * rt2x00queue_insert_l2pad - Remove L2 padding from 802.11 frame
  * @skb: The skb to align
- * @l2pad: Should L2 padding be used
  * @header_length: Length of 802.11 header
  *
- * This function prepares the @skb to be send to the device or mac80211.
- * If @l2pad is set to true padding will occur between the 802.11 header
- * and payload. Otherwise the padding will be done in front of the 802.11
- * header.
- * When @l2pad is set the function will check for the &SKBDESC_L2_PADDED
- * flag in &skb_frame_desc. If that flag is set, the padding is removed
- * and the flag cleared. Otherwise the padding is added and the flag is set.
+ * Remove L2 padding used to align both header and payload to 4-byte boundary,
+ * by removing the L2 padding the header will no longer be 4-byte aligned.
  */
-void rt2x00queue_payload_align(struct sk_buff *skb,
-			       bool l2pad, unsigned int header_length);
+void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length);
 
 /**
  * rt2x00queue_write_tx_frame - Write TX frame to hardware
@@ -326,7 +345,7 @@ void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
 void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
 			       struct txentry_desc *txdesc);
 void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length);
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
 			       unsigned int header_length,
 			       struct rxdone_entry_desc *rxdesc);
 #else
@@ -386,29 +405,18 @@ static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
 /*
  * RFkill handlers.
  */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
-void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev);
-void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev);
-void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev);
-void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev);
-#else
 static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
 {
+	if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+		wiphy_rfkill_start_polling(rt2x00dev->hw->wiphy);
 }
 
 static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
 {
+	if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+		wiphy_rfkill_stop_polling(rt2x00dev->hw->wiphy);
 }
 
-static inline void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
-{
-}
-
-static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
-{
-}
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
-
 /*
  * LED handlers
  */
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index eb9b981..c64db0b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -46,7 +46,15 @@
 #define DEFAULT_PERCENTAGE	50
 
 /*
- * Small helper macro to work with moving/walking averages.
+ * Small helper macro for percentage calculation
+ * This is a very simple macro with the only catch that it will
+ * produce a default value in case no total value was provided.
+ */
+#define PERCENTAGE(__value, __total) \
+	( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) )
+
+/*
+ * Helper struct and macro to work with moving/walking averages.
  * When adding a value to the average value the following calculation
  * is needed:
  *
@@ -60,18 +68,28 @@
  * for a few minutes but when the device is moved away from the AP
  * the average will not decrease fast enough to compensate.
  * The walking average compensates this and will move towards
- * the new values correctly allowing a effective link tuning.
- */
-#define MOVING_AVERAGE(__avg, __val, __samples) \
-	( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
-
-/*
- * Small helper macro for percentage calculation
- * This is a very simple macro with the only catch that it will
- * produce a default value in case no total value was provided.
+ * the new values correctly allowing a effective link tuning,
+ * the speed of the average moving towards other values depends
+ * on the value for the number of samples. The higher the number
+ * of samples, the slower the average will move.
+ * We use two variables to keep track of the average value to
+ * compensate for the rounding errors. This can be a significant
+ * error (>5dBm) if the factor is too low.
  */
-#define PERCENTAGE(__value, __total) \
-	( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) )
+#define AVG_SAMPLES	8
+#define AVG_FACTOR	1000
+#define MOVING_AVERAGE(__avg, __val) \
+({ \
+	struct avg_val __new; \
+	__new.avg_weight = \
+	    (__avg).avg_weight  ? \
+		((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \
+		  ((__val) * (AVG_FACTOR))) / \
+		 (AVG_SAMPLES) ) : \
+		((__val) * (AVG_FACTOR)); \
+	__new.avg = __new.avg_weight / (AVG_FACTOR); \
+	__new; \
+})
 
 /*
  * For calculating the Signal quality we have determined
@@ -98,56 +116,41 @@ static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev)
 {
 	struct link_ant *ant = &rt2x00dev->link.ant;
 
-	if (ant->rssi_ant && rt2x00dev->link.qual.rx_success)
-		return ant->rssi_ant;
+	if (ant->rssi_ant.avg && rt2x00dev->link.qual.rx_success)
+		return ant->rssi_ant.avg;
 	return DEFAULT_RSSI;
 }
 
-static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev,
-					       enum antenna antenna)
+static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev)
 {
 	struct link_ant *ant = &rt2x00dev->link.ant;
 
-	if (ant->rssi_history[antenna - ANTENNA_A])
-		return ant->rssi_history[antenna - ANTENNA_A];
+	if (ant->rssi_history)
+		return ant->rssi_history;
 	return DEFAULT_RSSI;
 }
-/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
-#define rt2x00link_antenna_get_rssi_rx_history(__dev) \
-	rt2x00link_antenna_get_rssi_history((__dev), \
-					    (__dev)->link.ant.active.rx)
-#define rt2x00link_antenna_get_rssi_tx_history(__dev) \
-	rt2x00link_antenna_get_rssi_history((__dev), \
-					    (__dev)->link.ant.active.tx)
 
 static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev,
-						   enum antenna antenna,
 						   int rssi)
 {
 	struct link_ant *ant = &rt2x00dev->link.ant;
-	ant->rssi_history[ant->active.rx - ANTENNA_A] = rssi;
+	ant->rssi_history = rssi;
 }
-/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
-#define rt2x00link_antenna_update_rssi_rx_history(__dev, __rssi) \
-	rt2x00link_antenna_update_rssi_history((__dev), \
-					       (__dev)->link.ant.active.rx, \
-					       (__rssi))
-#define rt2x00link_antenna_update_rssi_tx_history(__dev, __rssi) \
-	rt2x00link_antenna_update_rssi_history((__dev), \
-					       (__dev)->link.ant.active.tx, \
-					       (__rssi))
 
 static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev)
 {
-	rt2x00dev->link.ant.rssi_ant = 0;
+	rt2x00dev->link.ant.rssi_ant.avg = 0;
+	rt2x00dev->link.ant.rssi_ant.avg_weight = 0;
 }
 
 static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
 {
 	struct link_ant *ant = &rt2x00dev->link.ant;
 	struct antenna_setup new_ant;
-	int sample_a = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_A);
-	int sample_b = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_B);
+	int other_antenna;
+
+	int sample_current = rt2x00link_antenna_get_link_rssi(rt2x00dev);
+	int sample_other = rt2x00link_antenna_get_rssi_history(rt2x00dev);
 
 	memcpy(&new_ant, &ant->active, sizeof(new_ant));
 
@@ -158,22 +161,27 @@ static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
 
 	/*
 	 * During the last period we have sampled the RSSI
-	 * from both antenna's. It now is time to determine
+	 * from both antennas. It now is time to determine
 	 * which antenna demonstrated the best performance.
 	 * When we are already on the antenna with the best
-	 * performance, then there really is nothing for us
-	 * left to do.
+	 * performance, just create a good starting point
+	 * for the history and we are done.
 	 */
-	if (sample_a == sample_b)
+	if (sample_current >= sample_other) {
+		rt2x00link_antenna_update_rssi_history(rt2x00dev,
+			sample_current);
 		return;
+	}
+
+	other_antenna = (ant->active.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
 
 	if (ant->flags & ANTENNA_RX_DIVERSITY)
-		new_ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+		new_ant.rx = other_antenna;
 
 	if (ant->flags & ANTENNA_TX_DIVERSITY)
-		new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
+		new_ant.tx = other_antenna;
 
-	rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+	rt2x00lib_config_antenna(rt2x00dev, new_ant);
 }
 
 static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
@@ -190,8 +198,8 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
 	 * after that update the history with the current value.
 	 */
 	rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev);
-	rssi_old = rt2x00link_antenna_get_rssi_rx_history(rt2x00dev);
-	rt2x00link_antenna_update_rssi_rx_history(rt2x00dev, rssi_curr);
+	rssi_old = rt2x00link_antenna_get_rssi_history(rt2x00dev);
+	rt2x00link_antenna_update_rssi_history(rt2x00dev, rssi_curr);
 
 	/*
 	 * Legacy driver indicates that we should swap antenna's
@@ -213,12 +221,13 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
 	if (ant->flags & ANTENNA_TX_DIVERSITY)
 		new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
 
-	rt2x00lib_config_antenna(rt2x00dev, &new_ant);
+	rt2x00lib_config_antenna(rt2x00dev, new_ant);
 }
 
-static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
+static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
 {
 	struct link_ant *ant = &rt2x00dev->link.ant;
+	unsigned int flags = ant->flags;
 
 	/*
 	 * Determine if software diversity is enabled for
@@ -226,30 +235,38 @@ static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
 	 * Always perform this check since within the link
 	 * tuner interval the configuration might have changed.
 	 */
-	ant->flags &= ~ANTENNA_RX_DIVERSITY;
-	ant->flags &= ~ANTENNA_TX_DIVERSITY;
+	flags &= ~ANTENNA_RX_DIVERSITY;
+	flags &= ~ANTENNA_TX_DIVERSITY;
 
 	if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
-		ant->flags |= ANTENNA_RX_DIVERSITY;
+		flags |= ANTENNA_RX_DIVERSITY;
 	if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
-		ant->flags |= ANTENNA_TX_DIVERSITY;
+		flags |= ANTENNA_TX_DIVERSITY;
 
 	if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
 	    !(ant->flags & ANTENNA_TX_DIVERSITY)) {
 		ant->flags = 0;
-		return;
+		return true;
 	}
 
+	/* Update flags */
+	ant->flags = flags;
+
 	/*
 	 * If we have only sampled the data over the last period
 	 * we should now harvest the data. Otherwise just evaluate
 	 * the data. The latter should only be performed once
 	 * every 2 seconds.
 	 */
-	if (ant->flags & ANTENNA_MODE_SAMPLE)
+	if (ant->flags & ANTENNA_MODE_SAMPLE) {
 		rt2x00lib_antenna_diversity_sample(rt2x00dev);
-	else if (rt2x00dev->link.count & 1)
+		return true;
+	} else if (rt2x00dev->link.count & 1) {
 		rt2x00lib_antenna_diversity_eval(rt2x00dev);
+		return true;
+	}
+
+	return false;
 }
 
 void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
@@ -260,8 +277,6 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
 	struct link_qual *qual = &rt2x00dev->link.qual;
 	struct link_ant *ant = &rt2x00dev->link.ant;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	int avg_rssi = rxdesc->rssi;
-	int ant_rssi = rxdesc->rssi;
 
 	/*
 	 * Frame was received successfully since non-succesfull
@@ -281,16 +296,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Update global RSSI
 	 */
-	if (link->avg_rssi)
-		avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi, 8);
-	link->avg_rssi = avg_rssi;
+	link->avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi);
 
 	/*
 	 * Update antenna RSSI
 	 */
-	if (ant->rssi_ant)
-		ant_rssi = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi, 8);
-	ant->rssi_ant = ant_rssi;
+	ant->rssi_ant = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi);
 }
 
 static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev)
@@ -351,8 +362,8 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
 
 	rt2x00link_reset_tuner(rt2x00dev, false);
 
-	queue_delayed_work(rt2x00dev->hw->workqueue,
-			   &link->work, LINK_TUNE_INTERVAL);
+	ieee80211_queue_delayed_work(rt2x00dev->hw,
+				     &link->work, LINK_TUNE_INTERVAL);
 }
 
 void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
@@ -423,10 +434,10 @@ static void rt2x00link_tuner(struct work_struct *work)
 	 * collect the RSSI data we could use this. Otherwise we
 	 * must fallback to the default RSSI value.
 	 */
-	if (!link->avg_rssi || !qual->rx_success)
+	if (!link->avg_rssi.avg || !qual->rx_success)
 		qual->rssi = DEFAULT_RSSI;
 	else
-		qual->rssi = link->avg_rssi;
+		qual->rssi = link->avg_rssi.avg;
 
 	/*
 	 * Only perform the link tuning when Link tuning
@@ -444,25 +455,22 @@ static void rt2x00link_tuner(struct work_struct *work)
 	/*
 	 * Send a signal to the led to update the led signal strength.
 	 */
-	rt2x00leds_led_quality(rt2x00dev, link->avg_rssi);
-
-	/*
-	 * Evaluate antenna setup, make this the last step since this could
-	 * possibly reset some statistics.
-	 */
-	rt2x00lib_antenna_diversity(rt2x00dev);
+	rt2x00leds_led_quality(rt2x00dev, qual->rssi);
 
 	/*
-	 * Reset the quality counters which recounted during each period.
+	 * Evaluate antenna setup, make this the last step when
+	 * rt2x00lib_antenna_diversity made changes the quality
+	 * statistics will be reset.
 	 */
-	rt2x00link_reset_qual(rt2x00dev);
+	if (rt2x00lib_antenna_diversity(rt2x00dev))
+		rt2x00link_reset_qual(rt2x00dev);
 
 	/*
 	 * Increase tuner counter, and reschedule the next link tuner run.
 	 */
 	link->count++;
-	queue_delayed_work(rt2x00dev->hw->workqueue,
-			   &link->work, LINK_TUNE_INTERVAL);
+	ieee80211_queue_delayed_work(rt2x00dev->hw,
+				     &link->work, LINK_TUNE_INTERVAL);
 }
 
 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c4c06b4..929b85f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -73,7 +73,8 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
 	else
 		rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
 
-	skb->do_not_encrypt = 1;
+	/* Disable hardware encryption */
+	rts_info->control.hw_key = NULL;
 
 	/*
 	 * RTS/CTS frame should use the length of the frame plus any
@@ -273,6 +274,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 
 	spin_lock_init(&intf->lock);
 	spin_lock_init(&intf->seqlock);
+	mutex_init(&intf->beacon_skb_mutex);
 	intf->beacon = entry;
 
 	if (conf->type == NL80211_IFTYPE_AP)
@@ -337,54 +339,38 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct ieee80211_conf *conf = &hw->conf;
-	int status;
 
 	/*
-	 * Mac80211 might be calling this function while we are trying
+	 * mac80211 might be calling this function while we are trying
 	 * to remove the device or perhaps suspending it.
 	 */
 	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
 		return 0;
 
 	/*
-	 * Only change device state when the radio is enabled. It does not
-	 * matter what parameters we have configured when the radio is disabled
-	 * because we won't be able to send or receive anyway. Also note that
-	 * some configuration parameters (e.g. channel and antenna values) can
-	 * only be set when the radio is enabled.
+	 * Some configuration parameters (e.g. channel and antenna values) can
+	 * only be set when the radio is enabled, but do require the RX to
+	 * be off.
 	 */
-	if (conf->radio_enabled) {
-		/* For programming the values, we have to turn RX off */
-		rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+	rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
 
-		/* Enable the radio */
-		status = rt2x00lib_enable_radio(rt2x00dev);
-		if (unlikely(status))
-			return status;
+	/*
+	 * When we've just turned on the radio, we want to reprogram
+	 * everything to ensure a consistent state
+	 */
+	rt2x00lib_config(rt2x00dev, conf, changed);
 
-		/*
-		 * When we've just turned on the radio, we want to reprogram
-		 * everything to ensure a consistent state
-		 */
-		rt2x00lib_config(rt2x00dev, conf, changed);
+	/*
+	 * After the radio has been enabled we need to configure
+	 * the antenna to the default settings. rt2x00lib_config_antenna()
+	 * should determine if any action should be taken based on
+	 * checking if diversity has been enabled or no antenna changes
+	 * have been made since the last configuration change.
+	 */
+	rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
 
-		/*
-		 * The radio was enabled, configure the antenna to the
-		 * default settings, the link tuner will later start
-		 * continue configuring the antenna based on the software
-		 * diversity. But for non-diversity configurations, we need
-		 * to have configured the correct state now.
-		 */
-		if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED)
-			rt2x00lib_config_antenna(rt2x00dev,
-						 &rt2x00dev->default_ant);
-
-		/* Turn RX back on */
-		rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
-	} else {
-		/* Disable the radio */
-		rt2x00lib_disable_radio(rt2x00dev);
-	}
+	/* Turn RX back on */
+	rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
 
 	return 0;
 }
@@ -393,7 +379,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_config);
 void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
 				unsigned int changed_flags,
 				unsigned int *total_flags,
-				int mc_count, struct dev_addr_list *mc_list)
+				u64 multicast)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 
@@ -406,6 +392,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
 	    FIF_FCSFAIL |
 	    FIF_PLCPFAIL |
 	    FIF_CONTROL |
+	    FIF_PSPOLL |
 	    FIF_OTHER_BSS |
 	    FIF_PROMISC_IN_BSS;
 
@@ -421,19 +408,42 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
 		*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
 
 	/*
+	 * If the device has a single filter for all control frames,
+	 * FIF_CONTROL and FIF_PSPOLL flags imply each other.
+	 * And if the device has more than one filter for control frames
+	 * of different types, but has no a separate filter for PS Poll frames,
+	 * FIF_CONTROL flag implies FIF_PSPOLL.
+	 */
+	if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags)) {
+		if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL)
+			*total_flags |= FIF_CONTROL | FIF_PSPOLL;
+	}
+	if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags)) {
+		if (*total_flags & FIF_CONTROL)
+			*total_flags |= FIF_PSPOLL;
+	}
+
+	/*
 	 * Check if there is any work left for us.
 	 */
 	if (rt2x00dev->packet_filter == *total_flags)
 		return;
 	rt2x00dev->packet_filter = *total_flags;
 
-	if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
-		rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
-	else
-		queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
+	rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
 
+int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+		      bool set)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+
+	rt2x00lib_beacondone(rt2x00dev);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
+
 #ifdef CONFIG_RT2X00_LIB_CRYPTO
 static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
 {
@@ -572,11 +582,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 	struct rt2x00_intf *intf = vif_to_intf(vif);
-	unsigned int delayed = 0;
 	int update_bssid = 0;
 
 	/*
-	 * Mac80211 might be calling this function while we are trying
+	 * mac80211 might be calling this function while we are trying
 	 * to remove the device or perhaps suspending it.
 	 */
 	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
@@ -626,30 +635,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
 		else
 			rt2x00dev->intf_associated--;
 
-		if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
-			rt2x00leds_led_assoc(rt2x00dev,
-					     !!rt2x00dev->intf_associated);
-		else
-			delayed |= DELAYED_LED_ASSOC;
+		rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
 	}
 
 	/*
 	 * When the erp information has changed, we should perform
 	 * additional configuration steps. For all other changes we are done.
 	 */
-	if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
-		if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
-			rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
-		else
-			delayed |= DELAYED_CONFIG_ERP;
-	}
-
-	spin_lock(&intf->lock);
-	if (delayed) {
-		intf->delayed_flags |= delayed;
-		schedule_work(&rt2x00dev->intf_work);
-	}
-	spin_unlock(&intf->lock);
+	if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT))
+		rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
 
@@ -687,3 +681,12 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_conf_tx);
+
+void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	bool active = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+
+	wiphy_rfkill_set_hw_state(hw->wiphy, !active);
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 44e5b32..577029e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -148,35 +148,89 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
 	dev_kfree_skb_any(skb);
 }
 
-void rt2x00queue_payload_align(struct sk_buff *skb,
-			       bool l2pad, unsigned int header_length)
+void rt2x00queue_align_frame(struct sk_buff *skb)
 {
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
 	unsigned int frame_length = skb->len;
-	unsigned int align = ALIGN_SIZE(skb, header_length);
+	unsigned int align = ALIGN_SIZE(skb, 0);
 
 	if (!align)
 		return;
 
-	if (l2pad) {
-		if (skbdesc->flags & SKBDESC_L2_PADDED) {
-			/* Remove L2 padding */
-			memmove(skb->data + align, skb->data, header_length);
-			skb_pull(skb, align);
-			skbdesc->flags &= ~SKBDESC_L2_PADDED;
-		} else {
-			/* Add L2 padding */
-			skb_push(skb, align);
-			memmove(skb->data, skb->data + align, header_length);
-			skbdesc->flags |= SKBDESC_L2_PADDED;
-		}
+	skb_push(skb, align);
+	memmove(skb->data, skb->data + align, frame_length);
+	skb_trim(skb, frame_length);
+}
+
+void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_lengt)
+{
+	unsigned int frame_length = skb->len;
+	unsigned int align = ALIGN_SIZE(skb, header_lengt);
+
+	if (!align)
+		return;
+
+	skb_push(skb, align);
+	memmove(skb->data, skb->data + align, frame_length);
+	skb_trim(skb, frame_length);
+}
+
+void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
+{
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+	unsigned int frame_length = skb->len;
+	unsigned int header_align = ALIGN_SIZE(skb, 0);
+	unsigned int payload_align = ALIGN_SIZE(skb, header_length);
+	unsigned int l2pad = 4 - (payload_align - header_align);
+
+	if (header_align == payload_align) {
+		/*
+		 * Both header and payload must be moved the same
+		 * amount of bytes to align them properly. This means
+		 * we don't use the L2 padding but just move the entire
+		 * frame.
+		 */
+		rt2x00queue_align_frame(skb);
+	} else if (!payload_align) {
+		/*
+		 * Simple L2 padding, only the header needs to be moved,
+		 * the payload is already properly aligned.
+		 */
+		skb_push(skb, header_align);
+		memmove(skb->data, skb->data + header_align, frame_length);
+		skbdesc->flags |= SKBDESC_L2_PADDED;
 	} else {
-		/* Generic payload alignment to 4-byte boundary */
-		skb_push(skb, align);
-		memmove(skb->data, skb->data + align, frame_length);
+		/*
+		 *
+		 * Complicated L2 padding, both header and payload need
+		 * to be moved. By default we only move to the start
+		 * of the buffer, so our header alignment needs to be
+		 * increased if there is not enough room for the header
+		 * to be moved.
+		 */
+		if (payload_align > header_align)
+			header_align += 4;
+
+		skb_push(skb, header_align);
+		memmove(skb->data, skb->data + header_align, header_length);
+		memmove(skb->data + header_length + l2pad,
+			skb->data + header_length + l2pad + header_align,
+			frame_length - header_length);
+		skbdesc->flags |= SKBDESC_L2_PADDED;
 	}
 }
 
+void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
+{
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+	unsigned int l2pad = 4 - (header_length & 3);
+
+	if (!l2pad || (skbdesc->flags & SKBDESC_L2_PADDED))
+		return;
+
+	memmove(skb->data + l2pad, skb->data, header_length);
+	skb_pull(skb, l2pad);
+}
+
 static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
 						 struct txentry_desc *txdesc)
 {
@@ -324,7 +378,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 	/*
 	 * Check if more fragments are pending
 	 */
-	if (ieee80211_has_morefrags(hdr->frame_control)) {
+	if (ieee80211_has_morefrags(hdr->frame_control) ||
+	    (tx_info->flags & IEEE80211_TX_CTL_MORE_FRAMES)) {
 		__set_bit(ENTRY_TXD_BURST, &txdesc->flags);
 		__set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags);
 	}
@@ -452,9 +507,18 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
 			rt2x00crypto_tx_remove_iv(skb, &txdesc);
 	}
 
+	/*
+	 * When DMA allocation is required we should guarentee to the
+	 * driver that the DMA is aligned to a 4-byte boundary.
+	 * However some drivers require L2 padding to pad the payload
+	 * rather then the header. This could be a requirement for
+	 * PCI and USB devices, while header alignment only is valid
+	 * for PCI devices.
+	 */
 	if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
-		rt2x00queue_payload_align(entry->skb, true,
-					  txdesc.header_length);
+		rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length);
+	else if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
+		rt2x00queue_align_frame(entry->skb);
 
 	/*
 	 * It could be possible that the queue was corrupted and this
@@ -490,14 +554,25 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 	if (unlikely(!intf->beacon))
 		return -ENOBUFS;
 
+	mutex_lock(&intf->beacon_skb_mutex);
+
+	/*
+	 * Clean up the beacon skb.
+	 */
+	rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb);
+	intf->beacon->skb = NULL;
+
 	if (!enable_beacon) {
 		rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON);
+		mutex_unlock(&intf->beacon_skb_mutex);
 		return 0;
 	}
 
 	intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
-	if (!intf->beacon->skb)
+	if (!intf->beacon->skb) {
+		mutex_unlock(&intf->beacon_skb_mutex);
 		return -ENOMEM;
+	}
 
 	/*
 	 * Copy all TX descriptor information into txdesc,
@@ -535,6 +610,8 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
 	rt2x00dev->ops->lib->write_beacon(intf->beacon);
 	rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON);
 
+	mutex_unlock(&intf->beacon_skb_mutex);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index b5e0634..a5591fb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -29,7 +29,7 @@
 #include <linux/prefetch.h>
 
 /**
- * DOC: Entrie frame size
+ * DOC: Entry frame size
  *
  * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes,
  * for USB devices this restriction does not apply, but the value of
@@ -45,13 +45,13 @@
 /**
  * DOC: Number of entries per queue
  *
- * Under normal load without fragmentation 12 entries are sufficient
+ * Under normal load without fragmentation, 12 entries are sufficient
  * without the queue being filled up to the maximum. When using fragmentation
- * and the queue threshold code we need to add some additional margins to
+ * and the queue threshold code, we need to add some additional margins to
  * make sure the queue will never (or only under extreme load) fill up
  * completely.
- * Since we don't use preallocated DMA having a large number of queue entries
- * will have only minimal impact on the memory requirements for the queue.
+ * Since we don't use preallocated DMA, having a large number of queue entries
+ * will have minimal impact on the memory requirements for the queue.
  */
 #define RX_ENTRIES	24
 #define TX_ENTRIES	24
@@ -214,6 +214,7 @@ struct rxdone_entry_desc {
  *
  * @TXDONE_UNKNOWN: Hardware could not determine success of transmission.
  * @TXDONE_SUCCESS: Frame was successfully send
+ * @TXDONE_FALLBACK: Frame was successfully send using a fallback rate.
  * @TXDONE_FAILURE: Frame was not successfully send
  * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the
  *	frame transmission failed due to excessive retries.
@@ -221,6 +222,7 @@ struct rxdone_entry_desc {
 enum txdone_entry_desc_flags {
 	TXDONE_UNKNOWN,
 	TXDONE_SUCCESS,
+	TXDONE_FALLBACK,
 	TXDONE_FAILURE,
 	TXDONE_EXCESSIVE_RETRY,
 };
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 861322d..983e52e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -176,8 +176,8 @@ struct rt2x00_field32 {
 #define is_valid_mask(x)	is_power_of_two(1LU + (x) + low_bit_mask(x))
 
 /*
- * Macro's to find first set bit in a variable.
- * These macro's behaves the same as the __ffs() function with
+ * Macros to find first set bit in a variable.
+ * These macros behave the same as the __ffs() functions but
  * the most important difference that this is done during
  * compile-time rather then run-time.
  */
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
deleted file mode 100644
index b6d4c67..0000000
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-	Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
-	<http://rt2x00.serialmonkey.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.
- */
-
-/*
-	Module: rt2x00rfkill
-	Abstract: rt2x00 rfkill routines.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "rt2x00.h"
-#include "rt2x00lib.h"
-
-static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
-{
-	struct rt2x00_dev *rt2x00dev = poll_dev->private;
-	int state, old_state;
-
-	if (!test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state) ||
-	    !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
-		return;
-
-	/*
-	 * Poll latest state, if the state is different then the previous state,
-	 * we should generate an input event.
-	 */
-	state = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
-	old_state = !!test_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
-
-	if (old_state != state) {
-		input_report_switch(poll_dev->input, SW_RFKILL_ALL, state);
-		change_bit(RFKILL_STATE_BLOCKED, &rt2x00dev->rfkill_state);
-	}
-}
-
-void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
-{
-	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
-	    test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
-		return;
-
-	if (input_register_polled_device(rt2x00dev->rfkill_poll_dev)) {
-		ERROR(rt2x00dev, "Failed to register polled device.\n");
-		return;
-	}
-
-	__set_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
-
-	/*
-	 * Force initial poll which will detect the initial device state,
-	 * and correctly sends the signal to the input layer about this
-	 * state.
-	 */
-	rt2x00rfkill_poll(rt2x00dev->rfkill_poll_dev);
-}
-
-void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
-{
-	if (!test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
-	    !test_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state))
-		return;
-
-	input_unregister_polled_device(rt2x00dev->rfkill_poll_dev);
-
-	__clear_bit(RFKILL_STATE_REGISTERED, &rt2x00dev->rfkill_state);
-}
-
-void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
-{
-	struct input_polled_dev *poll_dev;
-
-	if (test_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state) ||
-	    !test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
-		return;
-
-	poll_dev = input_allocate_polled_device();
-	if (!poll_dev) {
-		ERROR(rt2x00dev, "Failed to allocate polled device.\n");
-		return;
-	}
-
-	poll_dev->private = rt2x00dev;
-	poll_dev->poll = rt2x00rfkill_poll;
-	poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
-
-	poll_dev->input->name = rt2x00dev->ops->name;
-	poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
-	poll_dev->input->id.bustype = BUS_HOST;
-	poll_dev->input->id.vendor = 0x1814;
-	poll_dev->input->id.product = rt2x00dev->chip.rt;
-	poll_dev->input->id.version = rt2x00dev->chip.rev;
-	poll_dev->input->dev.parent = wiphy_dev(rt2x00dev->hw->wiphy);
-	poll_dev->input->evbit[0] = BIT(EV_SW);
-	poll_dev->input->swbit[0] = BIT(SW_RFKILL_ALL);
-
-	rt2x00dev->rfkill_poll_dev = poll_dev;
-
-	__set_bit(RFKILL_STATE_ALLOCATED, &rt2x00dev->rfkill_state);
-}
-
-void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
-{
-	if (!__test_and_clear_bit(RFKILL_STATE_ALLOCATED,
-				  &rt2x00dev->rfkill_state))
-		return;
-
-	input_free_polled_device(rt2x00dev->rfkill_poll_dev);
-	rt2x00dev->rfkill_poll_dev = NULL;
-}
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 49b29ff..b20e3ea 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -237,7 +237,6 @@ static const struct rt2x00debug rt61pci_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -245,9 +244,6 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 	rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
 	return rt2x00_get_field32(reg, MAC_CSR13_BIT5);
 }
-#else
-#define rt61pci_rfkill_poll	NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt61pci_brightness_set(struct led_classdev *led_cdev,
@@ -534,7 +530,7 @@ static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
 			   !(filter_flags & FIF_PLCPFAIL));
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
-			   !(filter_flags & FIF_CONTROL));
+			   !(filter_flags & (FIF_CONTROL | FIF_PSPOLL)));
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
 			   !(filter_flags & FIF_PROMISC_IN_BSS));
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
@@ -602,7 +598,7 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
 	u32 reg;
 
 	rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
-	rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+	rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32);
 	rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
 	rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
 
@@ -1859,8 +1855,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry)
 	 * otherwise we might be sending out invalid data.
 	 */
 	rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
-	rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
-	rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
 	rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
 	rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
 
@@ -2316,7 +2310,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	}
 
 	/*
-	 * Determine number of antenna's.
+	 * Determine number of antennas.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
 		__set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
@@ -2338,10 +2332,8 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
 		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 	/*
 	 * Read frequency offset and RF programming sequence.
@@ -2607,6 +2599,11 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 	int retval;
 
 	/*
+	 * Disable power saving.
+	 */
+	rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007);
+
+	/*
 	 * Allocate eeprom data.
 	 */
 	retval = rt61pci_validate_eeprom(rt2x00dev);
@@ -2625,6 +2622,12 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 		return retval;
 
 	/*
+	 * This device has multiple filters for control frames,
+	 * but has no a separate filter for PS Poll frames.
+	 */
+	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+
+	/*
 	 * This device requires firmware and DMA mapped skbs.
 	 */
 	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
@@ -2722,12 +2725,14 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
 	.remove_interface	= rt2x00mac_remove_interface,
 	.config			= rt2x00mac_config,
 	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt2x00mac_set_tim,
 	.set_key		= rt2x00mac_set_key,
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt61pci_conf_tx,
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt61pci_get_tsf,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 6c71f77..93eb699 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1476,7 +1476,7 @@ struct hw_pairwise_ta_entry {
 #define RXD_W15_RESERVED		FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index c188488..1cbd9b4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -183,7 +183,6 @@ static const struct rt2x00debug rt73usb_rt2x00debug = {
 };
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
@@ -191,9 +190,6 @@ static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
 	rt2x00usb_register_read(rt2x00dev, MAC_CSR13, &reg);
 	return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
 }
-#else
-#define rt73usb_rfkill_poll	NULL
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 #ifdef CONFIG_RT2X00_LIB_LEDS
 static void rt73usb_brightness_set(struct led_classdev *led_cdev,
@@ -497,7 +493,7 @@ static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
 			   !(filter_flags & FIF_PLCPFAIL));
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
-			   !(filter_flags & FIF_CONTROL));
+			   !(filter_flags & (FIF_CONTROL | FIF_PSPOLL)));
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
 			   !(filter_flags & FIF_PROMISC_IN_BSS));
 	rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
@@ -565,7 +561,7 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
 	u32 reg;
 
 	rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
-	rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+	rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, 0x32);
 	rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
 	rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 
@@ -1531,8 +1527,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry)
 	 * otherwise we might be sending out invalid data.
 	 */
 	rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-	rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
-	rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
 	rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
 	rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
 
@@ -1863,10 +1857,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
-#ifdef CONFIG_RT2X00_LIB_RFKILL
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
 		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
-#endif /* CONFIG_RT2X00_LIB_RFKILL */
 
 	/*
 	 * Read frequency offset.
@@ -2150,10 +2142,15 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 		return retval;
 
 	/*
+	 * This device has multiple filters for control frames,
+	 * but has no a separate filter for PS Poll frames.
+	 */
+	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+
+	/*
 	 * This device requires firmware.
 	 */
 	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
 	if (!modparam_nohwcrypt)
 		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
 
@@ -2247,12 +2244,14 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
 	.remove_interface	= rt2x00mac_remove_interface,
 	.config			= rt2x00mac_config,
 	.configure_filter	= rt2x00mac_configure_filter,
+	.set_tim		= rt2x00mac_set_tim,
 	.set_key		= rt2x00mac_set_key,
 	.get_stats		= rt2x00mac_get_stats,
 	.bss_info_changed	= rt2x00mac_bss_info_changed,
 	.conf_tx		= rt73usb_conf_tx,
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt73usb_get_tsf,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
 };
 
 static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index c8016f6..81fe0be 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -809,7 +809,7 @@ struct hw_pairwise_ta_entry {
 
 /*
  * EEPROM antenna.
- * ANTENNA_NUM: Number of antenna's.
+ * ANTENNA_NUM: Number of antennas.
  * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B.
  * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B.
  * FRAME_TYPE: 0: DPDT , 1: SPDT , noted this bit is valid for g only.
@@ -1058,7 +1058,7 @@ struct hw_pairwise_ta_entry {
 #define RXD_W5_RESERVED			FIELD32(0xffffffff)
 
 /*
- * Macro's for converting txpower from EEPROM to mac80211 value
+ * Macros for converting txpower from EEPROM to mac80211 value
  * and from mac80211 value to register value.
  */
 #define MIN_TXPOWER	0
diff --git a/drivers/net/wireless/rtl818x/Makefile b/drivers/net/wireless/rtl818x/Makefile
index 37e3d4d..93cbfbe 100644
--- a/drivers/net/wireless/rtl818x/Makefile
+++ b/drivers/net/wireless/rtl818x/Makefile
@@ -1,5 +1,5 @@
 rtl8180-objs		:= rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
-rtl8187-objs		:= rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o
+rtl8187-objs		:= rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o rtl8187_rfkill.o
 
 obj-$(CONFIG_RTL8180)	+= rtl8180.o
 obj-$(CONFIG_RTL8187)	+= rtl8187.o
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 7e65d7c..16429c4 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -143,7 +143,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
 			if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
 				rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
 
-			ieee80211_rx_irqsafe(dev, skb, &rx_status);
+			memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+			ieee80211_rx_irqsafe(dev, skb);
 
 			skb = new_skb;
 			priv->rx_buf[priv->rx_idx] = skb;
@@ -280,7 +281,7 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
 				(ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
 		remainder = (16 * (skb->len + 4)) %
 			    ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
-		if (remainder > 0 && remainder <= 6)
+		if (remainder <= 6)
 			plcp_len |= 1 << 15;
 	}
 
@@ -727,10 +728,16 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
 	        priv->rf->conf_erp(dev, info);
 }
 
+static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev, int mc_count,
+				     struct dev_addr_list *mc_list)
+{
+	return mc_count;
+}
+
 static void rtl8180_configure_filter(struct ieee80211_hw *dev,
 				     unsigned int changed_flags,
 				     unsigned int *total_flags,
-				     int mc_count, struct dev_addr_list *mclist)
+				     u64 multicast)
 {
 	struct rtl8180_priv *priv = dev->priv;
 
@@ -740,7 +747,7 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
 		priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
 	if (changed_flags & FIF_OTHER_BSS)
 		priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
-	if (*total_flags & FIF_ALLMULTI || mc_count > 0)
+	if (*total_flags & FIF_ALLMULTI || multicast > 0)
 		priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
 	else
 		priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
@@ -767,6 +774,7 @@ static const struct ieee80211_ops rtl8180_ops = {
 	.remove_interface	= rtl8180_remove_interface,
 	.config			= rtl8180_config,
 	.bss_info_changed	= rtl8180_bss_info_changed,
+	.prepare_multicast	= rtl8180_prepare_multicast,
 	.configure_filter	= rtl8180_configure_filter,
 };
 
diff --git a/drivers/net/wireless/rtl818x/rtl8187.h b/drivers/net/wireless/rtl818x/rtl8187.h
index c09bfef..bf9175a 100644
--- a/drivers/net/wireless/rtl818x/rtl8187.h
+++ b/drivers/net/wireless/rtl818x/rtl8187.h
@@ -133,6 +133,7 @@ struct rtl8187_priv {
 		__le16 bits16;
 		__le32 bits32;
 	} *io_dmabuf;
+	bool rfkill_off;
 };
 
 void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 87a9558..2017ccc 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -32,6 +32,7 @@
 #ifdef CONFIG_RTL8187_LEDS
 #include "rtl8187_leds.h"
 #endif
+#include "rtl8187_rfkill.h"
 
 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
 MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
@@ -220,7 +221,7 @@ static void rtl8187_tx_cb(struct urb *urb)
 		 * reading a register in the device. We are in interrupt mode
 		 * here, thus queue the skb and finish on a work queue. */
 		skb_queue_tail(&priv->b_tx_status.queue, skb);
-		queue_delayed_work(hw->workqueue, &priv->work, 0);
+		ieee80211_queue_delayed_work(hw, &priv->work, 0);
 	}
 }
 
@@ -380,7 +381,8 @@ static void rtl8187_rx_cb(struct urb *urb)
 	rx_status.flag |= RX_FLAG_TSFT;
 	if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
 		rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
-	ieee80211_rx_irqsafe(dev, skb, &rx_status);
+	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+	ieee80211_rx_irqsafe(dev, skb);
 
 	skb = dev_alloc_skb(RTL8187_MAX_RX);
 	if (unlikely(!skb)) {
@@ -647,10 +649,10 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
 
 	/* setup card */
 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
-	rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
+	rtl818x_iowrite8(priv, &priv->map->GPIO0, 0);
 
 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
-	rtl818x_iowrite8(priv, &priv->map->GPIO, 1);
+	rtl818x_iowrite8(priv, &priv->map->GPIO0, 1);
 	rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
 
 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
@@ -673,11 +675,11 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
 
 	/* host_usb_init */
 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0);
-	rtl818x_iowrite8(priv, &priv->map->GPIO, 0);
+	rtl818x_iowrite8(priv, &priv->map->GPIO0, 0);
 	reg = rtl818x_ioread8(priv, (u8 *)0xFE53);
 	rtl818x_iowrite8(priv, (u8 *)0xFE53, reg | (1 << 7));
 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, (4 << 8));
-	rtl818x_iowrite8(priv, &priv->map->GPIO, 0x20);
+	rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x20);
 	rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
 	rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x80);
 	rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x80);
@@ -909,12 +911,12 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 	u32 reg;
 	int ret;
 
+	mutex_lock(&priv->conf_mutex);
+
 	ret = (!priv->is_rtl8187b) ? rtl8187_init_hw(dev) :
 				     rtl8187b_init_hw(dev);
 	if (ret)
-		return ret;
-
-	mutex_lock(&priv->conf_mutex);
+		goto rtl8187_start_exit;
 
 	init_usb_anchor(&priv->anchored);
 	priv->dev = dev;
@@ -941,8 +943,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 				  (7 << 21 /* MAX TX DMA */));
 		rtl8187_init_urbs(dev);
 		rtl8187b_init_status_urb(dev);
-		mutex_unlock(&priv->conf_mutex);
-		return 0;
+		goto rtl8187_start_exit;
 	}
 
 	rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
@@ -986,9 +987,10 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 	reg |= RTL818X_CMD_RX_ENABLE;
 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
 	INIT_DELAYED_WORK(&priv->work, rtl8187_work);
-	mutex_unlock(&priv->conf_mutex);
 
-	return 0;
+rtl8187_start_exit:
+	mutex_unlock(&priv->conf_mutex);
+	return ret;
 }
 
 static void rtl8187_stop(struct ieee80211_hw *dev)
@@ -1016,9 +1018,10 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
 		dev_kfree_skb_any(skb);
 
 	usb_kill_anchored_urbs(&priv->anchored);
+	mutex_unlock(&priv->conf_mutex);
+
 	if (!priv->is_rtl8187b)
 		cancel_delayed_work_sync(&priv->work);
-	mutex_unlock(&priv->conf_mutex);
 }
 
 static int rtl8187_add_interface(struct ieee80211_hw *dev,
@@ -1197,10 +1200,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
 				 info->use_short_preamble);
 }
 
+static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev,
+				     int mc_count, struct dev_addr_list *mc_list)
+{
+	return mc_count;
+}
+
 static void rtl8187_configure_filter(struct ieee80211_hw *dev,
 				     unsigned int changed_flags,
 				     unsigned int *total_flags,
-				     int mc_count, struct dev_addr_list *mclist)
+				     u64 multicast)
 {
 	struct rtl8187_priv *priv = dev->priv;
 
@@ -1210,7 +1219,7 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
 		priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
 	if (changed_flags & FIF_OTHER_BSS)
 		priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
-	if (*total_flags & FIF_ALLMULTI || mc_count > 0)
+	if (*total_flags & FIF_ALLMULTI || multicast > 0)
 		priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
 	else
 		priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
@@ -1273,8 +1282,10 @@ static const struct ieee80211_ops rtl8187_ops = {
 	.remove_interface	= rtl8187_remove_interface,
 	.config			= rtl8187_config,
 	.bss_info_changed	= rtl8187_bss_info_changed,
+	.prepare_multicast	= rtl8187_prepare_multicast,
 	.configure_filter	= rtl8187_configure_filter,
-	.conf_tx		= rtl8187_conf_tx
+	.conf_tx		= rtl8187_conf_tx,
+	.rfkill_poll		= rtl8187_rfkill_poll
 };
 
 static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom)
@@ -1514,6 +1525,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
 	reg &= 0xFF;
 	rtl8187_leds_init(dev, reg);
 #endif
+	rtl8187_rfkill_init(dev);
 
 	return 0;
 
@@ -1537,6 +1549,7 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf)
 #ifdef CONFIG_RTL8187_LEDS
 	rtl8187_leds_exit(dev);
 #endif
+	rtl8187_rfkill_exit(dev);
 	ieee80211_unregister_hw(dev);
 
 	priv = dev->priv;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
index cf9f899..a1c670f 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -42,7 +42,7 @@ static void led_turn_on(struct work_struct *work)
 	mutex_lock(&priv->conf_mutex);
 	switch (led->ledpin) {
 	case LED_PIN_GPIO0:
-		rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+		rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01);
 		rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00);
 		break;
 	case LED_PIN_LED0:
@@ -80,7 +80,7 @@ static void led_turn_off(struct work_struct *work)
 	mutex_lock(&priv->conf_mutex);
 	switch (led->ledpin) {
 	case LED_PIN_GPIO0:
-		rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+		rtl818x_iowrite8(priv, &priv->map->GPIO0, 0x01);
 		rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01);
 		break;
 	case LED_PIN_LED0:
@@ -108,11 +108,11 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
 	struct rtl8187_priv *priv = hw->priv;
 
 	if (brightness == LED_OFF) {
-		queue_delayed_work(hw->workqueue, &priv->led_off, 0);
+		ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
 		/* The LED is off for 1/20 sec so that it just blinks. */
-		queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20);
+		ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20);
 	} else
-		queue_delayed_work(hw->workqueue, &priv->led_on, 0);
+		ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
 }
 
 static int rtl8187_register_led(struct ieee80211_hw *dev,
@@ -193,7 +193,7 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
 	err = rtl8187_register_led(dev, &priv->led_rx, name,
 			 ieee80211_get_rx_led_name(dev), ledpin);
 	if (!err) {
-		queue_delayed_work(dev->workqueue, &priv->led_on, 0);
+		ieee80211_queue_delayed_work(dev, &priv->led_on, 0);
 		return;
 	}
 	/* registration of RX LED failed - unregister TX */
@@ -209,7 +209,7 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)
 	struct rtl8187_priv *priv = dev->priv;
 
 	/* turn the LED off before exiting */
-	queue_delayed_work(dev->workqueue, &priv->led_off, 0);
+	ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
 	cancel_delayed_work_sync(&priv->led_off);
 	cancel_delayed_work_sync(&priv->led_on);
 	rtl8187_unregister_led(&priv->led_rx);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
new file mode 100644
index 0000000..9fab13e
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
@@ -0,0 +1,63 @@
+/*
+ * Linux RFKILL support for RTL8187
+ *
+ * Copyright (c) 2009 Herton Ronaldo Krzesinski <herton@mandriva.com.br>
+ *
+ * Based on the RFKILL handling in the r8187 driver, which is:
+ * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+ *
+ * Thanks to Realtek for their support!
+ *
+ * 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/types.h>
+#include <linux/usb.h>
+#include <net/mac80211.h>
+
+#include "rtl8187.h"
+
+static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
+{
+	u8 gpio;
+
+	gpio = rtl818x_ioread8(priv, &priv->map->GPIO0);
+	rtl818x_iowrite8(priv, &priv->map->GPIO0, gpio & ~0x02);
+	gpio = rtl818x_ioread8(priv, &priv->map->GPIO1);
+
+	return gpio & 0x02;
+}
+
+void rtl8187_rfkill_init(struct ieee80211_hw *hw)
+{
+	struct rtl8187_priv *priv = hw->priv;
+
+	priv->rfkill_off = rtl8187_is_radio_enabled(priv);
+	printk(KERN_INFO "rtl8187: wireless switch is %s\n",
+	       priv->rfkill_off ? "on" : "off");
+	wiphy_rfkill_set_hw_state(hw->wiphy, !priv->rfkill_off);
+	wiphy_rfkill_start_polling(hw->wiphy);
+}
+
+void rtl8187_rfkill_poll(struct ieee80211_hw *hw)
+{
+	bool enabled;
+	struct rtl8187_priv *priv = hw->priv;
+
+	mutex_lock(&priv->conf_mutex);
+	enabled = rtl8187_is_radio_enabled(priv);
+	if (unlikely(enabled != priv->rfkill_off)) {
+		priv->rfkill_off = enabled;
+		printk(KERN_INFO "rtl8187: wireless radio switch turned %s\n",
+		       enabled ? "on" : "off");
+		wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
+	}
+	mutex_unlock(&priv->conf_mutex);
+}
+
+void rtl8187_rfkill_exit(struct ieee80211_hw *hw)
+{
+	wiphy_rfkill_stop_polling(hw->wiphy);
+}
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.h b/drivers/net/wireless/rtl818x/rtl8187_rfkill.h
new file mode 100644
index 0000000..e12575e
--- /dev/null
+++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.h
@@ -0,0 +1,8 @@
+#ifndef RTL8187_RFKILL_H
+#define RTL8187_RFKILL_H
+
+void rtl8187_rfkill_init(struct ieee80211_hw *hw);
+void rtl8187_rfkill_poll(struct ieee80211_hw *hw);
+void rtl8187_rfkill_exit(struct ieee80211_hw *hw);
+
+#endif /* RTL8187_RFKILL_H */
diff --git a/drivers/net/wireless/rtl818x/rtl818x.h b/drivers/net/wireless/rtl818x/rtl818x.h
index 34a5555..8522490 100644
--- a/drivers/net/wireless/rtl818x/rtl818x.h
+++ b/drivers/net/wireless/rtl818x/rtl818x.h
@@ -138,8 +138,9 @@ struct rtl818x_csr {
 	__le32	RF_PARA;
 	__le32	RF_TIMING;
 	u8	GP_ENABLE;
-	u8	GPIO;
-	u8	reserved_12[2];
+	u8	GPIO0;
+	u8	GPIO1;
+	u8	reserved_12;
 	__le32	HSSI_PARA;
 	u8	reserved_13[4];
 	u8	TX_AGC_CTL;
@@ -194,8 +195,18 @@ struct rtl818x_rf_ops {
 	void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
 };
 
-/* Tx/Rx flags are common between RTL818X chips */
-
+/**
+ * enum rtl818x_tx_desc_flags - Tx/Rx flags are common between RTL818X chips
+ *
+ * @RTL818X_TX_DESC_FLAG_NO_ENC: Disable hardware based encryption.
+ * @RTL818X_TX_DESC_FLAG_TX_OK: TX frame was ACKed.
+ * @RTL818X_TX_DESC_FLAG_SPLCP: Use short preamble.
+ * @RTL818X_TX_DESC_FLAG_MOREFRAG: More fragments follow.
+ * @RTL818X_TX_DESC_FLAG_CTS: Use CTS-to-self protection.
+ * @RTL818X_TX_DESC_FLAG_RTS: Use RTS/CTS protection.
+ * @RTL818X_TX_DESC_FLAG_LS: Last segment of the frame.
+ * @RTL818X_TX_DESC_FLAG_FS: First segment of the frame.
+ */
 enum rtl818x_tx_desc_flags {
 	RTL818X_TX_DESC_FLAG_NO_ENC	= (1 << 15),
 	RTL818X_TX_DESC_FLAG_TX_OK	= (1 << 15),
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 38366a5..ea6a87c 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -1533,7 +1533,7 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
 }
 
 /* Encapsulate a datagram and kick it into a TTY queue. */
-static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t strip_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct strip *strip_info = netdev_priv(dev);
 
@@ -1550,9 +1550,12 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (time_after(jiffies, strip_info->pps_timer + HZ)) {
 		unsigned long t = jiffies - strip_info->pps_timer;
-		unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t;
-		unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t;
-		unsigned long sx_pps_count = (strip_info->sx_pps_count * HZ * 8 + t / 2) / t;
+		unsigned long rx_pps_count =
+			DIV_ROUND_CLOSEST(strip_info->rx_pps_count*HZ*8, t);
+		unsigned long tx_pps_count =
+			DIV_ROUND_CLOSEST(strip_info->tx_pps_count*HZ*8, t);
+		unsigned long sx_pps_count =
+			DIV_ROUND_CLOSEST(strip_info->sx_pps_count*HZ*8, t);
 
 		strip_info->pps_timer = jiffies;
 		strip_info->rx_pps_count = 0;
@@ -1582,7 +1585,7 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	if (skb)
 		dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index ab7fc5c..d634b2d 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -2841,7 +2841,8 @@ static int wv_packet_write(struct net_device * dev, void *buf, short length)
  * the packet.  We also prevent reentrance.  Then we call the function
  * to send the packet.
  */
-static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
+static netdev_tx_t wavelan_packet_xmit(struct sk_buff *skb,
+					     struct net_device * dev)
 {
 	net_local *lp = netdev_priv(dev);
 	unsigned long flags;
@@ -2891,7 +2892,7 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
 #ifdef DEBUG_TX_TRACE
 	printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
 #endif
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*********************** HARDWARE CONFIGURATION ***********************/
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 2daa021..dbe8de6 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -611,7 +611,7 @@ static inline int
 	wv_packet_write(struct net_device *,	/* Write a packet to the Tx buffer. */
 			void *,
 			short);
-static int
+static netdev_tx_t
 	wavelan_packet_xmit(struct sk_buff *,	/* Send a packet. */
 			    struct net_device *);
 /* -------------------- HARDWARE CONFIGURATION -------------------- */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c6d3006..431a20e 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -3078,7 +3078,7 @@ wv_packet_write(struct net_device *	dev,
  * the packet. We also prevent reentrance. Then, we call the function
  * to send the packet...
  */
-static int
+static netdev_tx_t
 wavelan_packet_xmit(struct sk_buff *	skb,
 		    struct net_device *		dev)
 {
@@ -3113,7 +3113,7 @@ wavelan_packet_xmit(struct sk_buff *	skb,
 	 * able to detect collisions, therefore in theory we don't really
 	 * need to pad. Jean II */
 	if (skb_padto(skb, ETH_ZLEN))
-		return 0;
+		return NETDEV_TX_OK;
 
   wv_packet_write(dev, skb->data, skb->len);
 
@@ -3122,7 +3122,7 @@ wavelan_packet_xmit(struct sk_buff *	skb,
 #ifdef DEBUG_TX_TRACE
   printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
 #endif
-  return(0);
+  return NETDEV_TX_OK;
 }
 
 /********************** HARDWARE CONFIGURATION **********************/
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 706fd30..81d9153 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -707,7 +707,7 @@ static void
 	wv_packet_write(struct net_device *,	/* Write a packet to the Tx buffer */
 			void *,
 			short);
-static int
+static netdev_tx_t
 	wavelan_packet_xmit(struct sk_buff *,	/* Send a packet */
 			    struct net_device *);
 /* -------------------- HARDWARE CONFIGURATION -------------------- */
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index a82c4cd..7b14d5b 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -1,11 +1,52 @@
-config WL12XX
-	tristate "TI wl1251/wl1271 support"
-	depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS && EXPERIMENTAL
+menuconfig WL12XX
+	boolean "TI wl12xx driver support"
+	depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
+	---help---
+	  This will enable TI wl12xx driver support. The drivers make
+	  use of the mac80211 stack.
+
+config WL1251
+	tristate "TI wl1251 support"
+	depends on WL12XX && GENERIC_HARDIRQS
 	select FW_LOADER
 	select CRC7
 	---help---
 	  This module adds support for wireless adapters based on
-	  TI wl1251/wl1271 chipsets.
+	  TI wl1251 chipset.
+
+	  If you choose to build a module, it'll be called wl1251. Say
+	  N if unsure.
+
+config WL1251_SPI
+	tristate "TI wl1251 SPI support"
+	depends on WL1251 && SPI_MASTER
+	---help---
+	  This module adds support for the SPI interface of adapters using
+	  TI wl1251 chipset.  Select this if your platform is using
+	  the SPI bus.
+
+	  If you choose to build a module, it'll be called wl1251_spi.
+	  Say N if unsure.
+
+config WL1251_SDIO
+	tristate "TI wl1251 SDIO support"
+	depends on WL1251 && MMC
+	---help---
+	  This module adds support for the SDIO interface of adapters using
+	  TI wl1251 chipset.  Select this if your platform is using
+	  the SDIO bus.
+
+	  If you choose to build a module, it'll be called
+	  wl1251_sdio. Say N if unsure.
+
+config WL1271
+	tristate "TI wl1271 support"
+	depends on WL12XX && SPI_MASTER && GENERIC_HARDIRQS
+	select FW_LOADER
+	select CRC7
+	---help---
+	  This module adds support for wireless adapters based on the
+	  TI wl1271 chipset.
 
-	  If you choose to build a module, it'll be called wl12xx. Say N if
+	  If you choose to build a module, it'll be called wl1271. Say N if
 	  unsure.
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index d43de27..62e37ad 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -1,4 +1,14 @@
-wl12xx-objs		= main.o spi.o event.o tx.o rx.o \
-			  ps.o cmd.o acx.o boot.o init.o wl1251.o \
-			  debugfs.o
-obj-$(CONFIG_WL12XX)	+= wl12xx.o
+wl1251-objs		= wl1251_main.o wl1251_event.o \
+			  wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \
+			  wl1251_acx.o wl1251_boot.o wl1251_init.o \
+			  wl1251_debugfs.o wl1251_io.o
+
+obj-$(CONFIG_WL1251)	+= wl1251.o
+obj-$(CONFIG_WL1251_SPI)	+= wl1251_spi.o
+obj-$(CONFIG_WL1251_SDIO)	+= wl1251_sdio.o
+
+wl1271-objs		= wl1271_main.o  wl1271_spi.o wl1271_cmd.o  \
+			  wl1271_event.o wl1271_tx.o  wl1271_rx.o   \
+			  wl1271_ps.o    wl1271_acx.o wl1271_boot.o \
+			  wl1271_init.o  wl1271_debugfs.o
+obj-$(CONFIG_WL1271)	+= wl1271.o
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
deleted file mode 100644
index 1cfd458..0000000
--- a/drivers/net/wireless/wl12xx/acx.c
+++ /dev/null
@@ -1,689 +0,0 @@
-#include "acx.h"
-
-#include <linux/module.h>
-#include <linux/crc7.h>
-#include <linux/spi/spi.h>
-
-#include "wl12xx.h"
-#include "wl12xx_80211.h"
-#include "reg.h"
-#include "spi.h"
-#include "ps.h"
-
-int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
-			   u8 mgt_rate, u8 mgt_mod)
-{
-	int ret;
-	struct acx_fw_gen_frame_rates rates;
-
-	wl12xx_debug(DEBUG_ACX, "acx frame rates");
-
-	rates.header.id = ACX_FW_GEN_FRAME_RATES;
-	rates.header.len = sizeof(struct acx_fw_gen_frame_rates) -
-		sizeof(struct acx_header);
-
-	rates.tx_ctrl_frame_rate = ctrl_rate;
-	rates.tx_ctrl_frame_mod = ctrl_mod;
-	rates.tx_mgt_frame_rate = mgt_rate;
-	rates.tx_mgt_frame_mod = mgt_mod;
-
-	ret = wl12xx_cmd_configure(wl, &rates, sizeof(rates));
-	if (ret < 0) {
-		wl12xx_error("Failed to set FW rates and modulation");
-		return ret;
-	}
-
-	return 0;
-}
-
-
-int wl12xx_acx_station_id(struct wl12xx *wl)
-{
-	int ret, i;
-	struct dot11_station_id mac;
-
-	wl12xx_debug(DEBUG_ACX, "acx dot11_station_id");
-
-	mac.header.id = DOT11_STATION_ID;
-	mac.header.len = sizeof(mac) - sizeof(struct acx_header);
-
-	for (i = 0; i < ETH_ALEN; i++)
-		mac.mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
-
-	ret = wl12xx_cmd_configure(wl, &mac, sizeof(mac));
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id)
-{
-	struct acx_dot11_default_key default_key;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
-
-	default_key.header.id = DOT11_DEFAULT_KEY;
-	default_key.header.len = sizeof(default_key) -
-		sizeof(struct acx_header);
-
-	default_key.id = key_id;
-
-	ret = wl12xx_cmd_configure(wl, &default_key, sizeof(default_key));
-	if (ret < 0) {
-		wl12xx_error("Couldnt set default key");
-		return ret;
-	}
-
-	wl->default_key = key_id;
-
-	return 0;
-}
-
-int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval)
-{
-	struct acx_wake_up_condition wake_up;
-
-	wl12xx_debug(DEBUG_ACX, "acx wake up conditions");
-
-	wake_up.header.id = ACX_WAKE_UP_CONDITIONS;
-	wake_up.header.len = sizeof(wake_up) - sizeof(struct acx_header);
-
-	wake_up.wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP;
-	wake_up.listen_interval = listen_interval;
-
-	return wl12xx_cmd_configure(wl, &wake_up, sizeof(wake_up));
-}
-
-int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth)
-{
-	int ret;
-	struct acx_sleep_auth auth;
-
-	wl12xx_debug(DEBUG_ACX, "acx sleep auth");
-
-	auth.header.id = ACX_SLEEP_AUTH;
-	auth.header.len = sizeof(auth) - sizeof(struct acx_header);
-
-	auth.sleep_auth = sleep_auth;
-
-	ret = wl12xx_cmd_configure(wl, &auth, sizeof(auth));
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
-{
-	struct wl12xx_command cmd;
-	struct acx_revision *rev;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx fw rev");
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, sizeof(*rev), &cmd);
-	if (ret < 0) {
-		wl12xx_warning("ACX_FW_REV interrogate failed");
-		return ret;
-	}
-
-	rev = (struct acx_revision *) &cmd.parameters;
-
-	/* be careful with the buffer sizes */
-	strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
-
-	/*
-	 * if the firmware version string is exactly
-	 * sizeof(rev->fw_version) long or fw_len is less than
-	 * sizeof(rev->fw_version) it won't be null terminated
-	 */
-	buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
-
-	return 0;
-}
-
-int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
-{
-	struct acx_current_tx_power ie;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
-
-	if (power < 0 || power > 25)
-		return -EINVAL;
-
-	memset(&ie, 0, sizeof(ie));
-
-	ie.header.id = DOT11_CUR_TX_PWR;
-	ie.header.len = sizeof(ie) - sizeof(struct acx_header);
-	ie.current_tx_power = power * 10;
-
-	ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
-	if (ret < 0) {
-		wl12xx_warning("configure of tx power failed: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_feature_cfg(struct wl12xx *wl)
-{
-	struct acx_feature_config feature;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx feature cfg");
-
-	memset(&feature, 0, sizeof(feature));
-
-	feature.header.id = ACX_FEATURE_CFG;
-	feature.header.len = sizeof(feature) - sizeof(struct acx_header);
-
-	/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
-	feature.data_flow_options = 0;
-	feature.options = 0;
-
-	ret = wl12xx_cmd_configure(wl, &feature, sizeof(feature));
-	if (ret < 0)
-		wl12xx_error("Couldnt set HW encryption");
-
-	return ret;
-}
-
-int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len)
-{
-	struct wl12xx_command cmd;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx mem map");
-
-	ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, len, &cmd);
-	if (ret < 0)
-		return ret;
-	else if (cmd.status != CMD_STATUS_SUCCESS)
-		return -EIO;
-
-	memcpy(mem_map, &cmd.parameters, len);
-
-	return 0;
-}
-
-int wl12xx_acx_data_path_params(struct wl12xx *wl,
-				struct acx_data_path_params_resp *data_path)
-{
-	struct acx_data_path_params params;
-	struct wl12xx_command cmd;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx data path params");
-
-	params.rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
-	params.tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
-
-	params.rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
-	params.tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
-
-	params.tx_complete_threshold = 1;
-
-	params.tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
-
-	params.tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
-
-	params.header.id = ACX_DATA_PATH_PARAMS;
-	params.header.len = sizeof(params) - sizeof(struct acx_header);
-
-	ret = wl12xx_cmd_configure(wl, &params, sizeof(params));
-	if (ret < 0)
-		return ret;
-
-
-	ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
-				     sizeof(struct acx_data_path_params_resp),
-				     &cmd);
-
-	if (ret < 0) {
-		wl12xx_warning("failed to read data path parameters: %d", ret);
-		return ret;
-	} else if (cmd.status != CMD_STATUS_SUCCESS) {
-		wl12xx_warning("data path parameter acx status failed");
-		return -EIO;
-	}
-
-	memcpy(data_path, &cmd.parameters, sizeof(*data_path));
-
-	return 0;
-}
-
-int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time)
-{
-	struct rx_msdu_lifetime msdu_lifetime;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx rx msdu life time");
-
-	msdu_lifetime.header.id = DOT11_RX_MSDU_LIFE_TIME;
-	msdu_lifetime.header.len = sizeof(msdu_lifetime) -
-		sizeof(struct acx_header);
-	msdu_lifetime.lifetime = life_time;
-
-	ret = wl12xx_cmd_configure(wl, &msdu_lifetime, sizeof(msdu_lifetime));
-	if (ret < 0) {
-		wl12xx_warning("failed to set rx msdu life time: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter)
-{
-	struct acx_rx_config rx_config;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx rx config");
-
-	rx_config.header.id = ACX_RX_CFG;
-	rx_config.header.len = sizeof(rx_config) - sizeof(struct acx_header);
-	rx_config.config_options = config;
-	rx_config.filter_options = filter;
-
-	ret = wl12xx_cmd_configure(wl, &rx_config, sizeof(rx_config));
-	if (ret < 0) {
-		wl12xx_warning("failed to set rx config: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_pd_threshold(struct wl12xx *wl)
-{
-	struct acx_packet_detection packet_detection;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx data pd threshold");
-
-	/* FIXME: threshold value not set */
-	packet_detection.header.id = ACX_PD_THRESHOLD;
-	packet_detection.header.len = sizeof(packet_detection) -
-		sizeof(struct acx_header);
-
-	ret = wl12xx_cmd_configure(wl, &packet_detection,
-				   sizeof(packet_detection));
-	if (ret < 0) {
-		wl12xx_warning("failed to set pd threshold: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time)
-{
-	struct acx_slot slot;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx slot");
-
-	slot.header.id = ACX_SLOT;
-	slot.header.len = sizeof(slot) - sizeof(struct acx_header);
-
-	slot.wone_index = STATION_WONE_INDEX;
-	slot.slot_time = slot_time;
-
-	ret = wl12xx_cmd_configure(wl, &slot, sizeof(slot));
-	if (ret < 0) {
-		wl12xx_warning("failed to set slot time: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_group_address_tbl(struct wl12xx *wl)
-{
-	struct multicast_grp_addr_start multicast;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx group address tbl");
-
-	/* MAC filtering */
-	multicast.header.id = DOT11_GROUP_ADDRESS_TBL;
-	multicast.header.len = sizeof(multicast) - sizeof(struct acx_header);
-
-	multicast.enabled = 0;
-	multicast.num_groups = 0;
-	memset(multicast.mac_table, 0, ADDRESS_GROUP_MAX_LEN);
-
-	ret = wl12xx_cmd_configure(wl, &multicast, sizeof(multicast));
-	if (ret < 0) {
-		wl12xx_warning("failed to set group addr table: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_service_period_timeout(struct wl12xx *wl)
-{
-	struct acx_rx_timeout rx_timeout;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx service period timeout");
-
-	/* RX timeout */
-	rx_timeout.header.id = ACX_SERVICE_PERIOD_TIMEOUT;
-	rx_timeout.header.len = sizeof(rx_timeout) - sizeof(struct acx_header);
-
-	rx_timeout.ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
-	rx_timeout.upsd_timeout = RX_TIMEOUT_UPSD_DEF;
-
-	ret = wl12xx_cmd_configure(wl, &rx_timeout, sizeof(rx_timeout));
-	if (ret < 0) {
-		wl12xx_warning("failed to set service period timeout: %d",
-			       ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold)
-{
-	struct acx_rts_threshold rts;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx rts threshold");
-
-	rts.header.id = DOT11_RTS_THRESHOLD;
-	rts.header.len = sizeof(rts) - sizeof(struct acx_header);
-
-	rts.threshold = rts_threshold;
-
-	ret = wl12xx_cmd_configure(wl, &rts, sizeof(rts));
-	if (ret < 0) {
-		wl12xx_warning("failed to set rts threshold: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl)
-{
-	struct acx_beacon_filter_option beacon_filter;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx beacon filter opt");
-
-	beacon_filter.header.id = ACX_BEACON_FILTER_OPT;
-	beacon_filter.header.len = sizeof(beacon_filter) -
-		sizeof(struct acx_header);
-
-	beacon_filter.enable = 0;
-	beacon_filter.max_num_beacons = 0;
-
-	ret = wl12xx_cmd_configure(wl, &beacon_filter, sizeof(beacon_filter));
-	if (ret < 0) {
-		wl12xx_warning("failed to set beacon filter opt: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_beacon_filter_table(struct wl12xx *wl)
-{
-	struct acx_beacon_filter_ie_table ie_table;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx beacon filter table");
-
-	ie_table.header.id = ACX_BEACON_FILTER_TABLE;
-	ie_table.header.len = sizeof(ie_table) - sizeof(struct acx_header);
-
-	ie_table.num_ie = 0;
-	memset(ie_table.table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
-
-	ret = wl12xx_cmd_configure(wl, &ie_table, sizeof(ie_table));
-	if (ret < 0) {
-		wl12xx_warning("failed to set beacon filter table: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_sg_enable(struct wl12xx *wl)
-{
-	struct acx_bt_wlan_coex pta;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx sg enable");
-
-	pta.header.id = ACX_SG_ENABLE;
-	pta.header.len = sizeof(pta) - sizeof(struct acx_header);
-
-	pta.enable = SG_ENABLE;
-
-	ret = wl12xx_cmd_configure(wl, &pta, sizeof(pta));
-	if (ret < 0) {
-		wl12xx_warning("failed to set softgemini enable: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_sg_cfg(struct wl12xx *wl)
-{
-	struct acx_bt_wlan_coex_param param;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx sg cfg");
-
-	/* BT-WLAN coext parameters */
-	param.header.id = ACX_SG_CFG;
-	param.header.len = sizeof(param) - sizeof(struct acx_header);
-
-	param.min_rate = RATE_INDEX_24MBPS;
-	param.bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
-	param.wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
-	param.sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
-	param.rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
-	param.tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
-	param.rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
-	param.tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
-	param.wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
-	param.bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
-	param.next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
-	param.wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
-	param.hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
-	param.next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
-	param.antenna_type = PTA_ANTENNA_TYPE_DEF;
-	param.signal_type = PTA_SIGNALING_TYPE_DEF;
-	param.afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
-	param.quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
-	param.max_cts = PTA_MAX_NUM_CTS_DEF;
-	param.wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
-	param.bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
-	param.missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
-	param.wlan_elp_hp = PTA_ELP_HP_DEF;
-	param.bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
-	param.ack_mode_dual_ant = PTA_ACK_MODE_DEF;
-	param.pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
-	param.pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
-	param.bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
-
-	ret = wl12xx_cmd_configure(wl, &param, sizeof(param));
-	if (ret < 0) {
-		wl12xx_warning("failed to set sg config: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_cca_threshold(struct wl12xx *wl)
-{
-	struct acx_energy_detection detection;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx cca threshold");
-
-	detection.header.id = ACX_CCA_THRESHOLD;
-	detection.header.len = sizeof(detection) - sizeof(struct acx_header);
-
-	detection.rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
-	detection.tx_energy_detection = 0;
-
-	ret = wl12xx_cmd_configure(wl, &detection, sizeof(detection));
-	if (ret < 0) {
-		wl12xx_warning("failed to set cca threshold: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl)
-{
-	struct acx_beacon_broadcast bb;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx bcn dtim options");
-
-	bb.header.id = ACX_BCN_DTIM_OPTIONS;
-	bb.header.len = sizeof(bb) - sizeof(struct acx_header);
-
-	bb.beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
-	bb.broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
-	bb.rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
-	bb.ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
-
-	ret = wl12xx_cmd_configure(wl, &bb, sizeof(bb));
-	if (ret < 0) {
-		wl12xx_warning("failed to set rx config: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_aid(struct wl12xx *wl, u16 aid)
-{
-	struct acx_aid acx_aid;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx aid");
-
-	acx_aid.header.id = ACX_AID;
-	acx_aid.header.len = sizeof(acx_aid) - sizeof(struct acx_header);
-
-	acx_aid.aid = aid;
-
-	ret = wl12xx_cmd_configure(wl, &acx_aid, sizeof(acx_aid));
-	if (ret < 0) {
-		wl12xx_warning("failed to set aid: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask)
-{
-	struct acx_event_mask mask;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx event mbox mask");
-
-	mask.header.id = ACX_EVENT_MBOX_MASK;
-	mask.header.len = sizeof(mask) - sizeof(struct acx_header);
-
-	/* high event mask is unused */
-	mask.high_event_mask = 0xffffffff;
-
-	mask.event_mask = event_mask;
-
-	ret = wl12xx_cmd_configure(wl, &mask, sizeof(mask));
-	if (ret < 0) {
-		wl12xx_warning("failed to set aid: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble)
-{
-	struct acx_preamble ie;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx_set_preamble");
-
-	memset(&ie, 0, sizeof(ie));
-
-	ie.header.id = ACX_PREAMBLE_TYPE;
-	ie.header.len = sizeof(ie) - sizeof(struct acx_header);
-	ie.preamble = preamble;
-	ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
-	if (ret < 0) {
-		wl12xx_warning("Setting of preamble failed: %d", ret);
-		return ret;
-	}
-	return 0;
-}
-
-int wl12xx_acx_cts_protect(struct wl12xx *wl,
-			   enum acx_ctsprotect_type ctsprotect)
-{
-	struct acx_ctsprotect ie;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect");
-
-	memset(&ie, 0, sizeof(ie));
-
-	ie.header.id = ACX_CTS_PROTECTION;
-	ie.header.len = sizeof(ie) - sizeof(struct acx_header);
-	ie.ctsprotect = ctsprotect;
-	ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
-	if (ret < 0) {
-		wl12xx_warning("Setting of ctsprotect failed: %d", ret);
-		return ret;
-	}
-	return 0;
-}
-
-int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats)
-{
-	struct wl12xx_command *answer;
-	int ret;
-
-	wl12xx_debug(DEBUG_ACX, "acx statistics");
-
-	answer = kmalloc(sizeof(*answer), GFP_KERNEL);
-	if (!answer) {
-		wl12xx_warning("could not allocate memory for acx statistics");
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, sizeof(*answer),
-				     answer);
-	if (ret < 0) {
-		wl12xx_warning("acx statistics failed: %d", ret);
-		goto out;
-	}
-
-	memcpy(stats, answer->parameters, sizeof(*stats));
-
-out:
-	kfree(answer);
-	return ret;
-}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
deleted file mode 100644
index fb2d234..0000000
--- a/drivers/net/wireless/wl12xx/acx.h
+++ /dev/null
@@ -1,1245 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_ACX_H__
-#define __WL12XX_ACX_H__
-
-#include "wl12xx.h"
-
-/* Target's information element */
-struct acx_header {
-	u16 id;
-	u16 len;
-};
-
-struct acx_error_counter {
-	struct acx_header header;
-
-	/* The number of PLCP errors since the last time this */
-	/* information element was interrogated. This field is */
-	/* automatically cleared when it is interrogated.*/
-	u32 PLCP_error;
-
-	/* The number of FCS errors since the last time this */
-	/* information element was interrogated. This field is */
-	/* automatically cleared when it is interrogated.*/
-	u32 FCS_error;
-
-	/* The number of MPDUs without PLCP header errors received*/
-	/* since the last time this information element was interrogated. */
-	/* This field is automatically cleared when it is interrogated.*/
-	u32 valid_frame;
-
-	/* the number of missed sequence numbers in the squentially */
-	/* values of frames seq numbers */
-	u32 seq_num_miss;
-} __attribute__ ((packed));
-
-struct acx_revision {
-	struct acx_header header;
-
-	/*
-	 * The WiLink firmware version, an ASCII string x.x.x.x,
-	 * that uniquely identifies the current firmware.
-	 * The left most digit is incremented each time a
-	 * significant change is made to the firmware, such as
-	 * code redesign or new platform support.
-	 * The second digit is incremented when major enhancements
-	 * are added or major fixes are made.
-	 * The third digit is incremented for each GA release.
-	 * The fourth digit is incremented for each build.
-	 * The first two digits identify a firmware release version,
-	 * in other words, a unique set of features.
-	 * The first three digits identify a GA release.
-	 */
-	char fw_version[20];
-
-	/*
-	 * This 4 byte field specifies the WiLink hardware version.
-	 * bits 0  - 15: Reserved.
-	 * bits 16 - 23: Version ID - The WiLink version ID
-	 *              (1 = first spin, 2 = second spin, and so on).
-	 * bits 24 - 31: Chip ID - The WiLink chip ID.
-	 */
-	u32 hw_version;
-} __attribute__ ((packed));
-
-enum wl12xx_psm_mode {
-	/* Active mode */
-	WL12XX_PSM_CAM = 0,
-
-	/* Power save mode */
-	WL12XX_PSM_PS = 1,
-
-	/* Extreme low power */
-	WL12XX_PSM_ELP = 2,
-};
-
-struct acx_sleep_auth {
-	struct acx_header header;
-
-	/* The sleep level authorization of the device. */
-	/* 0 - Always active*/
-	/* 1 - Power down mode: light / fast sleep*/
-	/* 2 - ELP mode: Deep / Max sleep*/
-	u8  sleep_auth;
-	u8  padding[3];
-} __attribute__ ((packed));
-
-#define TIM_ELE_ID    5
-#define PARTIAL_VBM_MAX    251
-
-struct tim {
-	u8 identity;
-	u8 length;
-	u8 dtim_count;
-	u8 dtim_period;
-	u8 bitmap_ctrl;
-	u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
-} __attribute__ ((packed));
-
-/* Virtual Bit Map update */
-struct vbm_update_request {
-	__le16 len;
-	u8  padding[2];
-	struct tim tim;
-} __attribute__ ((packed));
-
-enum {
-	HOSTIF_PCI_MASTER_HOST_INDIRECT,
-	HOSTIF_PCI_MASTER_HOST_DIRECT,
-	HOSTIF_SLAVE,
-	HOSTIF_PKT_RING,
-	HOSTIF_DONTCARE = 0xFF
-};
-
-#define DEFAULT_UCAST_PRIORITY          0
-#define DEFAULT_RX_Q_PRIORITY           0
-#define DEFAULT_NUM_STATIONS            1
-#define DEFAULT_RXQ_PRIORITY            0 /* low 0 .. 15 high  */
-#define DEFAULT_RXQ_TYPE                0x07    /* All frames, Data/Ctrl/Mgmt */
-#define TRACE_BUFFER_MAX_SIZE           256
-
-#define  DP_RX_PACKET_RING_CHUNK_SIZE 1600
-#define  DP_TX_PACKET_RING_CHUNK_SIZE 1600
-#define  DP_RX_PACKET_RING_CHUNK_NUM 2
-#define  DP_TX_PACKET_RING_CHUNK_NUM 2
-#define  DP_TX_COMPLETE_TIME_OUT 20
-#define  FW_TX_CMPLT_BLOCK_SIZE 16
-
-struct acx_data_path_params {
-	struct acx_header header;
-
-	u16 rx_packet_ring_chunk_size;
-	u16 tx_packet_ring_chunk_size;
-
-	u8 rx_packet_ring_chunk_num;
-	u8 tx_packet_ring_chunk_num;
-
-	/*
-	 * Maximum number of packets that can be gathered
-	 * in the TX complete ring before an interrupt
-	 * is generated.
-	 */
-	u8 tx_complete_threshold;
-
-	/* Number of pending TX complete entries in cyclic ring.*/
-	u8 tx_complete_ring_depth;
-
-	/*
-	 * Max num microseconds since a packet enters the TX
-	 * complete ring until an interrupt is generated.
-	 */
-	u32 tx_complete_timeout;
-} __attribute__ ((packed));
-
-
-struct acx_data_path_params_resp {
-	struct acx_header header;
-
-	u16 rx_packet_ring_chunk_size;
-	u16 tx_packet_ring_chunk_size;
-
-	u8 rx_packet_ring_chunk_num;
-	u8 tx_packet_ring_chunk_num;
-
-	u8 pad[2];
-
-	u32 rx_packet_ring_addr;
-	u32 tx_packet_ring_addr;
-
-	u32 rx_control_addr;
-	u32 tx_control_addr;
-
-	u32 tx_complete_addr;
-} __attribute__ ((packed));
-
-#define TX_MSDU_LIFETIME_MIN       0
-#define TX_MSDU_LIFETIME_MAX       3000
-#define TX_MSDU_LIFETIME_DEF       512
-#define RX_MSDU_LIFETIME_MIN       0
-#define RX_MSDU_LIFETIME_MAX       0xFFFFFFFF
-#define RX_MSDU_LIFETIME_DEF       512000
-
-struct rx_msdu_lifetime {
-	struct acx_header header;
-
-	/*
-	 * The maximum amount of time, in TU, before the
-	 * firmware discards the MSDU.
-	 */
-	u32 lifetime;
-} __attribute__ ((packed));
-
-/*
- * RX Config Options Table
- * Bit		Definition
- * ===		==========
- * 31:14		Reserved
- * 13		Copy RX Status - when set, write three receive status words
- * 	 	to top of rx'd MPDUs.
- * 		When cleared, do not write three status words (added rev 1.5)
- * 12		Reserved
- * 11		RX Complete upon FCS error - when set, give rx complete
- *	 	interrupt for FCS errors, after the rx filtering, e.g. unicast
- *	 	frames not to us with FCS error will not generate an interrupt.
- * 10		SSID Filter Enable - When set, the WiLink discards all beacon,
- *	        probe request, and probe response frames with an SSID that does
- *		not match the SSID specified by the host in the START/JOIN
- *		command.
- *		When clear, the WiLink receives frames with any SSID.
- * 9		Broadcast Filter Enable - When set, the WiLink discards all
- * 	 	broadcast frames. When clear, the WiLink receives all received
- *		broadcast frames.
- * 8:6		Reserved
- * 5		BSSID Filter Enable - When set, the WiLink discards any frames
- * 	 	with a BSSID that does not match the BSSID specified by the
- *		host.
- *		When clear, the WiLink receives frames from any BSSID.
- * 4		MAC Addr Filter - When set, the WiLink discards any frames
- * 	 	with a destination address that does not match the MAC address
- *		of the adaptor.
- *		When clear, the WiLink receives frames destined to any MAC
- *		address.
- * 3		Promiscuous - When set, the WiLink receives all valid frames
- * 	 	(i.e., all frames that pass the FCS check).
- *		When clear, only frames that pass the other filters specified
- *		are received.
- * 2		FCS - When set, the WiLink includes the FCS with the received
- *	 	frame.
- *		When cleared, the FCS is discarded.
- * 1		PLCP header - When set, write all data from baseband to frame
- * 	 	buffer including PHY header.
- * 0		Reserved - Always equal to 0.
- *
- * RX Filter Options Table
- * Bit		Definition
- * ===		==========
- * 31:12		Reserved - Always equal to 0.
- * 11		Association - When set, the WiLink receives all association
- * 	 	related frames (association request/response, reassocation
- *		request/response, and disassociation). When clear, these frames
- *		are discarded.
- * 10		Auth/De auth - When set, the WiLink receives all authentication
- * 	 	and de-authentication frames. When clear, these frames are
- *		discarded.
- * 9		Beacon - When set, the WiLink receives all beacon frames.
- * 	 	When clear, these frames are discarded.
- * 8		Contention Free - When set, the WiLink receives all contention
- * 	 	free frames.
- *		When clear, these frames are discarded.
- * 7		Control - When set, the WiLink receives all control frames.
- * 	 	When clear, these frames are discarded.
- * 6		Data - When set, the WiLink receives all data frames.
- * 	 	When clear, these frames are discarded.
- * 5		FCS Error - When set, the WiLink receives frames that have FCS
- *	 	errors.
- *		When clear, these frames are discarded.
- * 4		Management - When set, the WiLink receives all management
- *		frames.
- * 	 	When clear, these frames are discarded.
- * 3		Probe Request - When set, the WiLink receives all probe request
- * 	 	frames.
- *		When clear, these frames are discarded.
- * 2		Probe Response - When set, the WiLink receives all probe
- * 		response frames.
- *		When clear, these frames are discarded.
- * 1		RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
- * 	 	frames.
- *		When clear, these frames are discarded.
- * 0		Rsvd Type/Sub Type - When set, the WiLink receives all frames
- * 	 	that have reserved frame types and sub types as defined by the
- *		802.11 specification.
- *		When clear, these frames are discarded.
- */
-struct acx_rx_config {
-	struct acx_header header;
-
-	u32 config_options;
-	u32 filter_options;
-} __attribute__ ((packed));
-
-enum {
-	QOS_AC_BE = 0,
-	QOS_AC_BK,
-	QOS_AC_VI,
-	QOS_AC_VO,
-	QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
-};
-
-#define MAX_NUM_OF_AC             (QOS_HIGHEST_AC_INDEX+1)
-#define FIRST_AC_INDEX            QOS_AC_BE
-#define MAX_NUM_OF_802_1d_TAGS    8
-#define AC_PARAMS_MAX_TSID        15
-#define MAX_APSD_CONF             0xffff
-
-#define  QOS_TX_HIGH_MIN      (0)
-#define  QOS_TX_HIGH_MAX      (100)
-
-#define  QOS_TX_HIGH_BK_DEF   (25)
-#define  QOS_TX_HIGH_BE_DEF   (35)
-#define  QOS_TX_HIGH_VI_DEF   (35)
-#define  QOS_TX_HIGH_VO_DEF   (35)
-
-#define  QOS_TX_LOW_BK_DEF    (15)
-#define  QOS_TX_LOW_BE_DEF    (25)
-#define  QOS_TX_LOW_VI_DEF    (25)
-#define  QOS_TX_LOW_VO_DEF    (25)
-
-struct acx_tx_queue_qos_config {
-	struct acx_header header;
-
-	u8 qid;
-	u8 pad[3];
-
-	/* Max number of blocks allowd in the queue */
-	u16 high_threshold;
-
-	/* Lowest memory blocks guaranteed for this queue */
-	u16 low_threshold;
-} __attribute__ ((packed));
-
-struct acx_packet_detection {
-	struct acx_header header;
-
-	u32 threshold;
-} __attribute__ ((packed));
-
-
-enum acx_slot_type {
-	SLOT_TIME_LONG = 0,
-	SLOT_TIME_SHORT = 1,
-	DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
-	MAX_SLOT_TIMES = 0xFF
-};
-
-#define STATION_WONE_INDEX 0
-
-struct acx_slot {
-	struct acx_header header;
-
-	u8 wone_index; /* Reserved */
-	u8 slot_time;
-	u8 reserved[6];
-} __attribute__ ((packed));
-
-
-#define ADDRESS_GROUP_MAX	(8)
-#define ADDRESS_GROUP_MAX_LEN	(ETH_ALEN * ADDRESS_GROUP_MAX)
-
-struct multicast_grp_addr_start {
-	struct acx_header header;
-
-	u8 enabled;
-	u8 num_groups;
-	u8 pad[2];
-	u8 mac_table[ADDRESS_GROUP_MAX_LEN];
-} __attribute__ ((packed));
-
-
-#define  RX_TIMEOUT_PS_POLL_MIN    0
-#define  RX_TIMEOUT_PS_POLL_MAX    (200000)
-#define  RX_TIMEOUT_PS_POLL_DEF    (15)
-#define  RX_TIMEOUT_UPSD_MIN       0
-#define  RX_TIMEOUT_UPSD_MAX       (200000)
-#define  RX_TIMEOUT_UPSD_DEF       (15)
-
-struct acx_rx_timeout {
-	struct acx_header header;
-
-	/*
-	 * The longest time the STA will wait to receive
-	 * traffic from the AP after a PS-poll has been
-	 * transmitted.
-	 */
-	u16 ps_poll_timeout;
-
-	/*
-	 * The longest time the STA will wait to receive
-	 * traffic from the AP after a frame has been sent
-	 * from an UPSD enabled queue.
-	 */
-	u16 upsd_timeout;
-} __attribute__ ((packed));
-
-#define RTS_THRESHOLD_MIN              0
-#define RTS_THRESHOLD_MAX              4096
-#define RTS_THRESHOLD_DEF              2347
-
-struct acx_rts_threshold {
-	struct acx_header header;
-
-	u16 threshold;
-	u8 pad[2];
-} __attribute__ ((packed));
-
-struct acx_beacon_filter_option {
-	struct acx_header header;
-
-	u8 enable;
-
-	/*
-	 * The number of beacons without the unicast TIM
-	 * bit set that the firmware buffers before
-	 * signaling the host about ready frames.
-	 * When set to 0 and the filter is enabled, beacons
-	 * without the unicast TIM bit set are dropped.
-	 */
-	u8 max_num_beacons;
-	u8 pad[2];
-} __attribute__ ((packed));
-
-/*
- * ACXBeaconFilterEntry (not 221)
- * Byte Offset     Size (Bytes)    Definition
- * ===========     ============    ==========
- * 0				1               IE identifier
- * 1               1               Treatment bit mask
- *
- * ACXBeaconFilterEntry (221)
- * Byte Offset     Size (Bytes)    Definition
- * ===========     ============    ==========
- * 0               1               IE identifier
- * 1               1               Treatment bit mask
- * 2               3               OUI
- * 5               1               Type
- * 6               2               Version
- *
- *
- * Treatment bit mask - The information element handling:
- * bit 0 - The information element is compared and transferred
- * in case of change.
- * bit 1 - The information element is transferred to the host
- * with each appearance or disappearance.
- * Note that both bits can be set at the same time.
- */
-#define	BEACON_FILTER_TABLE_MAX_IE_NUM		       (32)
-#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
-#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE	       (2)
-#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
-#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
-			    BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
-			   (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
-			    BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
-
-struct acx_beacon_filter_ie_table {
-	struct acx_header header;
-
-	u8 num_ie;
-	u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
-	u8 pad[3];
-} __attribute__ ((packed));
-
-enum {
-	SG_ENABLE = 0,
-	SG_DISABLE,
-	SG_SENSE_NO_ACTIVITY,
-	SG_SENSE_ACTIVE
-};
-
-struct acx_bt_wlan_coex {
-	struct acx_header header;
-
-	/*
-	 * 0 -> PTA enabled
-	 * 1 -> PTA disabled
-	 * 2 -> sense no active mode, i.e.
-	 *      an interrupt is sent upon
-	 *      BT activity.
-	 * 3 -> PTA is switched on in response
-	 *      to the interrupt sending.
-	 */
-	u8 enable;
-	u8 pad[3];
-} __attribute__ ((packed));
-
-#define PTA_ANTENNA_TYPE_DEF		  (0)
-#define PTA_BT_HP_MAXTIME_DEF		  (2000)
-#define PTA_WLAN_HP_MAX_TIME_DEF	  (5000)
-#define PTA_SENSE_DISABLE_TIMER_DEF	  (1350)
-#define PTA_PROTECTIVE_RX_TIME_DEF	  (1500)
-#define PTA_PROTECTIVE_TX_TIME_DEF	  (1500)
-#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
-#define PTA_SIGNALING_TYPE_DEF		  (1)
-#define PTA_AFH_LEVERAGE_ON_DEF		  (0)
-#define PTA_NUMBER_QUIET_CYCLE_DEF	  (0)
-#define PTA_MAX_NUM_CTS_DEF		  (3)
-#define PTA_NUMBER_OF_WLAN_PACKETS_DEF	  (2)
-#define PTA_NUMBER_OF_BT_PACKETS_DEF	  (2)
-#define PTA_PROTECTIVE_RX_TIME_FAST_DEF	  (1500)
-#define PTA_PROTECTIVE_TX_TIME_FAST_DEF	  (3000)
-#define PTA_CYCLE_TIME_FAST_DEF		  (8700)
-#define PTA_RX_FOR_AVALANCHE_DEF	  (5)
-#define PTA_ELP_HP_DEF			  (0)
-#define PTA_ANTI_STARVE_PERIOD_DEF	  (500)
-#define PTA_ANTI_STARVE_NUM_CYCLE_DEF	  (4)
-#define PTA_ALLOW_PA_SD_DEF		  (1)
-#define PTA_TIME_BEFORE_BEACON_DEF	  (6300)
-#define PTA_HPDM_MAX_TIME_DEF		  (1600)
-#define PTA_TIME_OUT_NEXT_WLAN_DEF	  (2550)
-#define PTA_AUTO_MODE_NO_CTS_DEF	  (0)
-#define PTA_BT_HP_RESPECTED_DEF		  (3)
-#define PTA_WLAN_RX_MIN_RATE_DEF	  (24)
-#define PTA_ACK_MODE_DEF		  (1)
-
-struct acx_bt_wlan_coex_param {
-	struct acx_header header;
-
-	/*
-	 * The minimum rate of a received WLAN packet in the STA,
-	 * during protective mode, of which a new BT-HP request
-	 * during this Rx will always be respected and gain the antenna.
-	 */
-	u32 min_rate;
-
-	/* Max time the BT HP will be respected. */
-	u16 bt_hp_max_time;
-
-	/* Max time the WLAN HP will be respected. */
-	u16 wlan_hp_max_time;
-
-	/*
-	 * The time between the last BT activity
-	 * and the moment when the sense mode returns
-	 * to SENSE_INACTIVE.
-	 */
-	u16 sense_disable_timer;
-
-	/* Time before the next BT HP instance */
-	u16 rx_time_bt_hp;
-	u16 tx_time_bt_hp;
-
-	/* range: 10-20000    default: 1500 */
-	u16 rx_time_bt_hp_fast;
-	u16 tx_time_bt_hp_fast;
-
-	/* range: 2000-65535  default: 8700 */
-	u16 wlan_cycle_fast;
-
-	/* range: 0 - 15000 (Msec) default: 1000 */
-	u16 bt_anti_starvation_period;
-
-	/* range 400-10000(Usec) default: 3000 */
-	u16 next_bt_lp_packet;
-
-	/* Deafult: worst case for BT DH5 traffic */
-	u16 wake_up_beacon;
-
-	/* range: 0-50000(Usec) default: 1050 */
-	u16 hp_dm_max_guard_time;
-
-	/*
-	 * This is to prevent both BT & WLAN antenna
-	 * starvation.
-	 * Range: 100-50000(Usec) default:2550
-	 */
-	u16 next_wlan_packet;
-
-	/* 0 -> shared antenna */
-	u8 antenna_type;
-
-	/*
-	 * 0 -> TI legacy
-	 * 1 -> Palau
-	 */
-	u8 signal_type;
-
-	/*
-	 * BT AFH status
-	 * 0 -> no AFH
-	 * 1 -> from dedicated GPIO
-	 * 2 -> AFH on (from host)
-	 */
-	u8 afh_leverage_on;
-
-	/*
-	 * The number of cycles during which no
-	 * TX will be sent after 1 cycle of RX
-	 * transaction in protective mode
-	 */
-	u8 quiet_cycle_num;
-
-	/*
-	 * The maximum number of CTSs that will
-	 * be sent for receiving RX packet in
-	 * protective mode
-	 */
-	u8 max_cts;
-
-	/*
-	 * The number of WLAN packets
-	 * transferred in common mode before
-	 * switching to BT.
-	 */
-	u8 wlan_packets_num;
-
-	/*
-	 * The number of BT packets
-	 * transferred in common mode before
-	 * switching to WLAN.
-	 */
-	u8 bt_packets_num;
-
-	/* range: 1-255  default: 5 */
-	u8 missed_rx_avalanche;
-
-	/* range: 0-1    default: 1 */
-	u8 wlan_elp_hp;
-
-	/* range: 0 - 15  default: 4 */
-	u8 bt_anti_starvation_cycles;
-
-	u8 ack_mode_dual_ant;
-
-	/*
-	 * Allow PA_SD assertion/de-assertion
-	 * during enabled BT activity.
-	 */
-	u8 pa_sd_enable;
-
-	/*
-	 * Enable/Disable PTA in auto mode:
-	 * Support Both Active & P.S modes
-	 */
-	u8 pta_auto_mode_enable;
-
-	/* range: 0 - 20  default: 1 */
-	u8 bt_hp_respected_num;
-} __attribute__ ((packed));
-
-#define CCA_THRSH_ENABLE_ENERGY_D       0x140A
-#define CCA_THRSH_DISABLE_ENERGY_D      0xFFEF
-
-struct acx_energy_detection {
-	struct acx_header header;
-
-	/* The RX Clear Channel Assessment threshold in the PHY */
-	u16 rx_cca_threshold;
-	u8 tx_energy_detection;
-	u8 pad;
-} __attribute__ ((packed));
-
-#define BCN_RX_TIMEOUT_DEF_VALUE        10000
-#define BROADCAST_RX_TIMEOUT_DEF_VALUE  20000
-#define RX_BROADCAST_IN_PS_DEF_VALUE    1
-#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
-
-struct acx_beacon_broadcast {
-	struct acx_header header;
-
-	u16 beacon_rx_timeout;
-	u16 broadcast_timeout;
-
-	/* Enables receiving of broadcast packets in PS mode */
-	u8 rx_broadcast_in_ps;
-
-	/* Consecutive PS Poll failures before updating the host */
-	u8 ps_poll_threshold;
-	u8 pad[2];
-} __attribute__ ((packed));
-
-struct acx_event_mask {
-	struct acx_header header;
-
-	u32 event_mask;
-	u32 high_event_mask; /* Unused */
-} __attribute__ ((packed));
-
-#define CFG_RX_FCS		BIT(2)
-#define CFG_RX_ALL_GOOD		BIT(3)
-#define CFG_UNI_FILTER_EN	BIT(4)
-#define CFG_BSSID_FILTER_EN	BIT(5)
-#define CFG_MC_FILTER_EN	BIT(6)
-#define CFG_MC_ADDR0_EN		BIT(7)
-#define CFG_MC_ADDR1_EN		BIT(8)
-#define CFG_BC_REJECT_EN	BIT(9)
-#define CFG_SSID_FILTER_EN	BIT(10)
-#define CFG_RX_INT_FCS_ERROR	BIT(11)
-#define CFG_RX_INT_ENCRYPTED	BIT(12)
-#define CFG_RX_WR_RX_STATUS	BIT(13)
-#define CFG_RX_FILTER_NULTI	BIT(14)
-#define CFG_RX_RESERVE		BIT(15)
-#define CFG_RX_TIMESTAMP_TSF	BIT(16)
-
-#define CFG_RX_RSV_EN		BIT(0)
-#define CFG_RX_RCTS_ACK		BIT(1)
-#define CFG_RX_PRSP_EN		BIT(2)
-#define CFG_RX_PREQ_EN		BIT(3)
-#define CFG_RX_MGMT_EN		BIT(4)
-#define CFG_RX_FCS_ERROR	BIT(5)
-#define CFG_RX_DATA_EN		BIT(6)
-#define CFG_RX_CTL_EN		BIT(7)
-#define CFG_RX_CF_EN		BIT(8)
-#define CFG_RX_BCN_EN		BIT(9)
-#define CFG_RX_AUTH_EN		BIT(10)
-#define CFG_RX_ASSOC_EN		BIT(11)
-
-#define SCAN_PASSIVE		BIT(0)
-#define SCAN_5GHZ_BAND		BIT(1)
-#define SCAN_TRIGGERED		BIT(2)
-#define SCAN_PRIORITY_HIGH	BIT(3)
-
-struct acx_fw_gen_frame_rates {
-	struct acx_header header;
-
-	u8 tx_ctrl_frame_rate; /* RATE_* */
-	u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
-	u8 tx_mgt_frame_rate;
-	u8 tx_mgt_frame_mod;
-} __attribute__ ((packed));
-
-/* STA MAC */
-struct dot11_station_id {
-	struct acx_header header;
-
-	u8 mac[ETH_ALEN];
-	u8 pad[2];
-} __attribute__ ((packed));
-
-/* HW encryption keys */
-#define NUM_ACCESS_CATEGORIES_COPY 4
-#define MAX_KEY_SIZE 32
-
-/* When set, disable HW encryption */
-#define DF_ENCRYPTION_DISABLE      0x01
-/* When set, disable HW decryption */
-#define DF_SNIFF_MODE_ENABLE       0x80
-
-struct acx_feature_config {
-	struct acx_header header;
-
-	u32 options;
-	u32 data_flow_options;
-} __attribute__ ((packed));
-
-enum acx_key_action {
-	KEY_ADD_OR_REPLACE = 1,
-	KEY_REMOVE         = 2,
-	KEY_SET_ID         = 3,
-	MAX_KEY_ACTION     = 0xffff,
-};
-
-enum acx_key_type {
-	KEY_WEP_DEFAULT       = 0,
-	KEY_WEP_ADDR          = 1,
-	KEY_AES_GROUP         = 4,
-	KEY_AES_PAIRWISE      = 5,
-	KEY_WEP_GROUP         = 6,
-	KEY_TKIP_MIC_GROUP    = 10,
-	KEY_TKIP_MIC_PAIRWISE = 11,
-};
-
-/*
- *
- * key_type_e   key size    key format
- * ----------   ---------   ----------
- * 0x00         5, 13, 29   Key data
- * 0x01         5, 13, 29   Key data
- * 0x04         16          16 bytes of key data
- * 0x05         16          16 bytes of key data
- * 0x0a         32          16 bytes of TKIP key data
- *                          8 bytes of RX MIC key data
- *                          8 bytes of TX MIC key data
- * 0x0b         32          16 bytes of TKIP key data
- *                          8 bytes of RX MIC key data
- *                          8 bytes of TX MIC key data
- *
- */
-
-struct acx_set_key {
-	/* Ignored for default WEP key */
-	u8 addr[ETH_ALEN];
-
-	/* key_action_e */
-	u16 key_action;
-
-	u16 reserved_1;
-
-	/* key size in bytes */
-	u8 key_size;
-
-	/* key_type_e */
-	u8 key_type;
-	u8 ssid_profile;
-
-	/*
-	 * TKIP, AES: frame's key id field.
-	 * For WEP default key: key id;
-	 */
-	u8 id;
-	u8 reserved_2[6];
-	u8 key[MAX_KEY_SIZE];
-	u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
-	u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
-} __attribute__ ((packed));
-
-struct acx_current_tx_power {
-	struct acx_header header;
-
-	u8  current_tx_power;
-	u8  padding[3];
-} __attribute__ ((packed));
-
-struct acx_dot11_default_key {
-	struct acx_header header;
-
-	u8 id;
-	u8 pad[3];
-} __attribute__ ((packed));
-
-struct acx_tsf_info {
-	struct acx_header header;
-
-	u32 current_tsf_msb;
-	u32 current_tsf_lsb;
-	u32 last_TBTT_msb;
-	u32 last_TBTT_lsb;
-	u8 last_dtim_count;
-	u8 pad[3];
-} __attribute__ ((packed));
-
-/* 802.11 PS */
-enum acx_ps_mode {
-	STATION_ACTIVE_MODE,
-	STATION_POWER_SAVE_MODE
-};
-
-struct acx_ps_params {
-	u8 ps_mode; /* STATION_* */
-	u8 send_null_data; /* Do we have to send NULL data packet ? */
-	u8 retries; /* Number of retires for the initial NULL data packet */
-
-	 /*
-	  * TUs during which the target stays awake after switching
-	  * to power save mode.
-	  */
-	u8 hang_over_period;
-	u16 null_data_rate;
-	u8 pad[2];
-} __attribute__ ((packed));
-
-enum acx_wake_up_event {
-	WAKE_UP_EVENT_BEACON_BITMAP	= 0x01, /* Wake on every Beacon*/
-	WAKE_UP_EVENT_DTIM_BITMAP	= 0x02,	/* Wake on every DTIM*/
-	WAKE_UP_EVENT_N_DTIM_BITMAP	= 0x04, /* Wake on every Nth DTIM */
-	WAKE_UP_EVENT_N_BEACONS_BITMAP	= 0x08, /* Wake on every Nth Beacon */
-	WAKE_UP_EVENT_BITS_MASK		= 0x0F
-};
-
-struct acx_wake_up_condition {
-	struct acx_header header;
-
-	u8 wake_up_event; /* Only one bit can be set */
-	u8 listen_interval;
-	u8 pad[2];
-} __attribute__ ((packed));
-
-struct acx_aid {
-	struct acx_header header;
-
-	/*
-	 * To be set when associated with an AP.
-	 */
-	u16 aid;
-	u8 pad[2];
-} __attribute__ ((packed));
-
-enum acx_preamble_type {
-	ACX_PREAMBLE_LONG = 0,
-	ACX_PREAMBLE_SHORT = 1
-};
-
-struct acx_preamble {
-	struct acx_header header;
-	/*
-	 * When set, the WiLink transmits the frames with a short preamble and
-	 * when cleared, the WiLink transmits the frames with a long preamble.
-	 */
-	u8 preamble;
-	u8 padding[3];
-} __attribute__ ((packed));
-
-enum acx_ctsprotect_type {
-	CTSPROTECT_DISABLE = 0,
-	CTSPROTECT_ENABLE = 1
-};
-
-struct acx_ctsprotect {
-	struct acx_header header;
-	u8 ctsprotect;
-	u8 padding[3];
-} __attribute__ ((packed));
-
-struct acx_tx_statistics {
-	u32 internal_desc_overflow;
-}  __attribute__ ((packed));
-
-struct acx_rx_statistics {
-	u32 out_of_mem;
-	u32 hdr_overflow;
-	u32 hw_stuck;
-	u32 dropped;
-	u32 fcs_err;
-	u32 xfr_hint_trig;
-	u32 path_reset;
-	u32 reset_counter;
-} __attribute__ ((packed));
-
-struct acx_dma_statistics {
-	u32 rx_requested;
-	u32 rx_errors;
-	u32 tx_requested;
-	u32 tx_errors;
-}  __attribute__ ((packed));
-
-struct acx_isr_statistics {
-	/* host command complete */
-	u32 cmd_cmplt;
-
-	/* fiqisr() */
-	u32 fiqs;
-
-	/* (INT_STS_ND & INT_TRIG_RX_HEADER) */
-	u32 rx_headers;
-
-	/* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
-	u32 rx_completes;
-
-	/* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
-	u32 rx_mem_overflow;
-
-	/* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
-	u32 rx_rdys;
-
-	/* irqisr() */
-	u32 irqs;
-
-	/* (INT_STS_ND & INT_TRIG_TX_PROC) */
-	u32 tx_procs;
-
-	/* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
-	u32 decrypt_done;
-
-	/* (INT_STS_ND & INT_TRIG_DMA0) */
-	u32 dma0_done;
-
-	/* (INT_STS_ND & INT_TRIG_DMA1) */
-	u32 dma1_done;
-
-	/* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
-	u32 tx_exch_complete;
-
-	/* (INT_STS_ND & INT_TRIG_COMMAND) */
-	u32 commands;
-
-	/* (INT_STS_ND & INT_TRIG_RX_PROC) */
-	u32 rx_procs;
-
-	/* (INT_STS_ND & INT_TRIG_PM_802) */
-	u32 hw_pm_mode_changes;
-
-	/* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
-	u32 host_acknowledges;
-
-	/* (INT_STS_ND & INT_TRIG_PM_PCI) */
-	u32 pci_pm;
-
-	/* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
-	u32 wakeups;
-
-	/* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
-	u32 low_rssi;
-} __attribute__ ((packed));
-
-struct acx_wep_statistics {
-	/* WEP address keys configured */
-	u32 addr_key_count;
-
-	/* default keys configured */
-	u32 default_key_count;
-
-	u32 reserved;
-
-	/* number of times that WEP key not found on lookup */
-	u32 key_not_found;
-
-	/* number of times that WEP key decryption failed */
-	u32 decrypt_fail;
-
-	/* WEP packets decrypted */
-	u32 packets;
-
-	/* WEP decrypt interrupts */
-	u32 interrupt;
-} __attribute__ ((packed));
-
-#define ACX_MISSED_BEACONS_SPREAD 10
-
-struct acx_pwr_statistics {
-	/* the amount of enters into power save mode (both PD & ELP) */
-	u32 ps_enter;
-
-	/* the amount of enters into ELP mode */
-	u32 elp_enter;
-
-	/* the amount of missing beacon interrupts to the host */
-	u32 missing_bcns;
-
-	/* the amount of wake on host-access times */
-	u32 wake_on_host;
-
-	/* the amount of wake on timer-expire */
-	u32 wake_on_timer_exp;
-
-	/* the number of packets that were transmitted with PS bit set */
-	u32 tx_with_ps;
-
-	/* the number of packets that were transmitted with PS bit clear */
-	u32 tx_without_ps;
-
-	/* the number of received beacons */
-	u32 rcvd_beacons;
-
-	/* the number of entering into PowerOn (power save off) */
-	u32 power_save_off;
-
-	/* the number of entries into power save mode */
-	u16 enable_ps;
-
-	/*
-	 * the number of exits from power save, not including failed PS
-	 * transitions
-	 */
-	u16 disable_ps;
-
-	/*
-	 * the number of times the TSF counter was adjusted because
-	 * of drift
-	 */
-	u32 fix_tsf_ps;
-
-	/* Gives statistics about the spread continuous missed beacons.
-	 * The 16 LSB are dedicated for the PS mode.
-	 * The 16 MSB are dedicated for the PS mode.
-	 * cont_miss_bcns_spread[0] - single missed beacon.
-	 * cont_miss_bcns_spread[1] - two continuous missed beacons.
-	 * cont_miss_bcns_spread[2] - three continuous missed beacons.
-	 * ...
-	 * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
-	*/
-	u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
-
-	/* the number of beacons in awake mode */
-	u32 rcvd_awake_beacons;
-} __attribute__ ((packed));
-
-struct acx_mic_statistics {
-	u32 rx_pkts;
-	u32 calc_failure;
-} __attribute__ ((packed));
-
-struct acx_aes_statistics {
-	u32 encrypt_fail;
-	u32 decrypt_fail;
-	u32 encrypt_packets;
-	u32 decrypt_packets;
-	u32 encrypt_interrupt;
-	u32 decrypt_interrupt;
-} __attribute__ ((packed));
-
-struct acx_event_statistics {
-	u32 heart_beat;
-	u32 calibration;
-	u32 rx_mismatch;
-	u32 rx_mem_empty;
-	u32 rx_pool;
-	u32 oom_late;
-	u32 phy_transmit_error;
-	u32 tx_stuck;
-} __attribute__ ((packed));
-
-struct acx_ps_statistics {
-	u32 pspoll_timeouts;
-	u32 upsd_timeouts;
-	u32 upsd_max_sptime;
-	u32 upsd_max_apturn;
-	u32 pspoll_max_apturn;
-	u32 pspoll_utilization;
-	u32 upsd_utilization;
-} __attribute__ ((packed));
-
-struct acx_rxpipe_statistics {
-	u32 rx_prep_beacon_drop;
-	u32 descr_host_int_trig_rx_data;
-	u32 beacon_buffer_thres_host_int_trig_rx_data;
-	u32 missed_beacon_host_int_trig_rx_data;
-	u32 tx_xfr_host_int_trig_rx_data;
-} __attribute__ ((packed));
-
-struct acx_statistics {
-	struct acx_header header;
-
-	struct acx_tx_statistics tx;
-	struct acx_rx_statistics rx;
-	struct acx_dma_statistics dma;
-	struct acx_isr_statistics isr;
-	struct acx_wep_statistics wep;
-	struct acx_pwr_statistics pwr;
-	struct acx_aes_statistics aes;
-	struct acx_mic_statistics mic;
-	struct acx_event_statistics event;
-	struct acx_ps_statistics ps;
-	struct acx_rxpipe_statistics rxpipe;
-} __attribute__ ((packed));
-
-enum {
-	ACX_WAKE_UP_CONDITIONS      = 0x0002,
-	ACX_MEM_CFG                 = 0x0003,
-	ACX_SLOT                    = 0x0004,
-	ACX_QUEUE_HEAD              = 0x0005, /* for MASTER mode only */
-	ACX_AC_CFG                  = 0x0007,
-	ACX_MEM_MAP                 = 0x0008,
-	ACX_AID                     = 0x000A,
-	ACX_RADIO_PARAM             = 0x000B, /* Not used */
-	ACX_CFG                     = 0x000C, /* Not used */
-	ACX_FW_REV                  = 0x000D,
-	ACX_MEDIUM_USAGE            = 0x000F,
-	ACX_RX_CFG                  = 0x0010,
-	ACX_TX_QUEUE_CFG            = 0x0011, /* FIXME: only used by wl1251 */
-	ACX_BSS_IN_PS               = 0x0012, /* for AP only */
-	ACX_STATISTICS              = 0x0013, /* Debug API */
-	ACX_FEATURE_CFG             = 0x0015,
-	ACX_MISC_CFG                = 0x0017, /* Not used */
-	ACX_TID_CFG                 = 0x001A,
-	ACX_BEACON_FILTER_OPT       = 0x001F,
-	ACX_LOW_RSSI                = 0x0020,
-	ACX_NOISE_HIST              = 0x0021,
-	ACX_HDK_VERSION             = 0x0022, /* ??? */
-	ACX_PD_THRESHOLD            = 0x0023,
-	ACX_DATA_PATH_PARAMS        = 0x0024, /* WO */
-	ACX_DATA_PATH_RESP_PARAMS   = 0x0024, /* RO */
-	ACX_CCA_THRESHOLD           = 0x0025,
-	ACX_EVENT_MBOX_MASK         = 0x0026,
-#ifdef FW_RUNNING_AS_AP
-	ACX_DTIM_PERIOD             = 0x0027, /* for AP only */
-#else
-	ACX_WR_TBTT_AND_DTIM        = 0x0027, /* STA only */
-#endif
-	ACX_ACI_OPTION_CFG          = 0x0029, /* OBSOLETE (for 1251)*/
-	ACX_GPIO_CFG                = 0x002A, /* Not used */
-	ACX_GPIO_SET                = 0x002B, /* Not used */
-	ACX_PM_CFG                  = 0x002C, /* To Be Documented */
-	ACX_CONN_MONIT_PARAMS       = 0x002D,
-	ACX_AVERAGE_RSSI            = 0x002E, /* Not used */
-	ACX_CONS_TX_FAILURE         = 0x002F,
-	ACX_BCN_DTIM_OPTIONS        = 0x0031,
-	ACX_SG_ENABLE               = 0x0032,
-	ACX_SG_CFG                  = 0x0033,
-	ACX_ANTENNA_DIVERSITY_CFG   = 0x0035, /* To Be Documented */
-	ACX_LOW_SNR		    = 0x0037, /* To Be Documented */
-	ACX_BEACON_FILTER_TABLE     = 0x0038,
-	ACX_ARP_IP_FILTER           = 0x0039,
-	ACX_ROAMING_STATISTICS_TBL  = 0x003B,
-	ACX_RATE_POLICY             = 0x003D,
-	ACX_CTS_PROTECTION          = 0x003E,
-	ACX_SLEEP_AUTH              = 0x003F,
-	ACX_PREAMBLE_TYPE	    = 0x0040,
-	ACX_ERROR_CNT               = 0x0041,
-	ACX_FW_GEN_FRAME_RATES      = 0x0042,
-	ACX_IBSS_FILTER		    = 0x0044,
-	ACX_SERVICE_PERIOD_TIMEOUT  = 0x0045,
-	ACX_TSF_INFO                = 0x0046,
-	ACX_CONFIG_PS_WMM           = 0x0049,
-	ACX_ENABLE_RX_DATA_FILTER   = 0x004A,
-	ACX_SET_RX_DATA_FILTER      = 0x004B,
-	ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
-	ACX_POWER_LEVEL_TABLE       = 0x004D,
-	ACX_BET_ENABLE              = 0x0050,
-	DOT11_STATION_ID            = 0x1001,
-	DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
-	DOT11_CUR_TX_PWR            = 0x100D,
-	DOT11_DEFAULT_KEY           = 0x1010,
-	DOT11_RX_DOT11_MODE         = 0x1012,
-	DOT11_RTS_THRESHOLD         = 0x1013,
-	DOT11_GROUP_ADDRESS_TBL     = 0x1014,
-
-	MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
-
-	MAX_IE = 0xFFFF
-};
-
-
-int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
-			   u8 mgt_rate, u8 mgt_mod);
-int wl12xx_acx_station_id(struct wl12xx *wl);
-int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id);
-int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval);
-int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth);
-int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len);
-int wl12xx_acx_tx_power(struct wl12xx *wl, int power);
-int wl12xx_acx_feature_cfg(struct wl12xx *wl);
-int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len);
-int wl12xx_acx_data_path_params(struct wl12xx *wl,
-				struct acx_data_path_params_resp *data_path);
-int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time);
-int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter);
-int wl12xx_acx_pd_threshold(struct wl12xx *wl);
-int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time);
-int wl12xx_acx_group_address_tbl(struct wl12xx *wl);
-int wl12xx_acx_service_period_timeout(struct wl12xx *wl);
-int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold);
-int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl);
-int wl12xx_acx_beacon_filter_table(struct wl12xx *wl);
-int wl12xx_acx_sg_enable(struct wl12xx *wl);
-int wl12xx_acx_sg_cfg(struct wl12xx *wl);
-int wl12xx_acx_cca_threshold(struct wl12xx *wl);
-int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl);
-int wl12xx_acx_aid(struct wl12xx *wl, u16 aid);
-int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask);
-int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble);
-int wl12xx_acx_cts_protect(struct wl12xx *wl,
-			    enum acx_ctsprotect_type ctsprotect);
-int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats);
-
-#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
deleted file mode 100644
index 48ac08c..0000000
--- a/drivers/net/wireless/wl12xx/boot.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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/gpio.h>
-
-#include "reg.h"
-#include "boot.h"
-#include "spi.h"
-#include "event.h"
-
-static void wl12xx_boot_enable_interrupts(struct wl12xx *wl)
-{
-	enable_irq(wl->irq);
-}
-
-void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl)
-{
-	wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
-	wl12xx_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
-}
-
-int wl12xx_boot_soft_reset(struct wl12xx *wl)
-{
-	unsigned long timeout;
-	u32 boot_data;
-
-	/* perform soft reset */
-	wl12xx_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
-
-	/* SOFT_RESET is self clearing */
-	timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
-	while (1) {
-		boot_data = wl12xx_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
-		wl12xx_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
-		if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
-			break;
-
-		if (time_after(jiffies, timeout)) {
-			/* 1.2 check pWhalBus->uSelfClearTime if the
-			 * timeout was reached */
-			wl12xx_error("soft reset timeout");
-			return -1;
-		}
-
-		udelay(SOFT_RESET_STALL_TIME);
-	}
-
-	/* disable Rx/Tx */
-	wl12xx_reg_write32(wl, ENABLE, 0x0);
-
-	/* disable auto calibration on start*/
-	wl12xx_reg_write32(wl, SPARE_A2, 0xffff);
-
-	return 0;
-}
-
-int wl12xx_boot_init_seq(struct wl12xx *wl)
-{
-	u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
-
-	/*
-	 * col #1: INTEGER_DIVIDER
-	 * col #2: FRACTIONAL_DIVIDER
-	 * col #3: ATTN_BB
-	 * col #4: ALPHA_BB
-	 * col #5: STOP_TIME_BB
-	 * col #6: BB_PLL_LOOP_FILTER
-	 */
-	static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
-
-		{   83, 87381,  0xB, 5, 0xF00,  3}, /* REF_FREQ_19_2*/
-		{   61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
-		{   41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
-		{   40, 0,      0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
-		{   47, 162280, 0xC, 6, 0x2760, 1}  /* REF_FREQ_33_6        */
-	};
-
-	/* read NVS params */
-	scr_pad6 = wl12xx_reg_read32(wl, SCR_PAD6);
-	wl12xx_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
-
-	/* read ELP_CMD */
-	elp_cmd = wl12xx_reg_read32(wl, ELP_CMD);
-	wl12xx_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
-
-	/* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
-	ref_freq = scr_pad6 & 0x000000FF;
-	wl12xx_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
-
-	wl12xx_reg_write32(wl, PLL_CAL_TIME, 0x9);
-
-	/*
-	 * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
-	 */
-	wl12xx_reg_write32(wl, CLK_BUF_TIME, 0x6);
-
-	/*
-	 * set the clock detect feature to work in the restart wu procedure
-	 * (ELP_CFG_MODE[14]) and Select the clock source type
-	 * (ELP_CFG_MODE[13:12])
-	 */
-	tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
-	wl12xx_reg_write32(wl, ELP_CFG_MODE, tmp);
-
-	/* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
-	elp_cmd |= 0x00000040;
-	wl12xx_reg_write32(wl, ELP_CMD, elp_cmd);
-
-	/* PG 1.2: Set the BB PLL stable time to be 1000usec
-	 * (PLL_STABLE_TIME) */
-	wl12xx_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
-
-	/* PG 1.2: read clock request time */
-	init_data = wl12xx_reg_read32(wl, CLK_REQ_TIME);
-
-	/*
-	 * PG 1.2: set the clock request time to be ref_clk_settling_time -
-	 * 1ms = 4ms
-	 */
-	if (init_data > 0x21)
-		tmp = init_data - 0x21;
-	else
-		tmp = 0;
-	wl12xx_reg_write32(wl, CLK_REQ_TIME, tmp);
-
-	/* set BB PLL configurations in RF AFE */
-	wl12xx_reg_write32(wl, 0x003058cc, 0x4B5);
-
-	/* set RF_AFE_REG_5 */
-	wl12xx_reg_write32(wl, 0x003058d4, 0x50);
-
-	/* set RF_AFE_CTRL_REG_2 */
-	wl12xx_reg_write32(wl, 0x00305948, 0x11c001);
-
-	/*
-	 * change RF PLL and BB PLL divider for VCO clock and adjust VCO
-	 * bais current(RF_AFE_REG_13)
-	 */
-	wl12xx_reg_write32(wl, 0x003058f4, 0x1e);
-
-	/* set BB PLL configurations */
-	tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
-	wl12xx_reg_write32(wl, 0x00305840, tmp);
-
-	/* set fractional divider according to Appendix C-BB PLL
-	 * Calculations
-	 */
-	tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
-	wl12xx_reg_write32(wl, 0x00305844, tmp);
-
-	/* set the initial data for the sigma delta */
-	wl12xx_reg_write32(wl, 0x00305848, 0x3039);
-
-	/*
-	 * set the accumulator attenuation value, calibration loop1
-	 * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
-	 * the VCO gain
-	 */
-	tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
-		(LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
-	wl12xx_reg_write32(wl, 0x00305854, tmp);
-
-	/*
-	 * set the calibration stop time after holdoff time expires and set
-	 * settling time HOLD_OFF_TIME_BB
-	 */
-	tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
-	wl12xx_reg_write32(wl, 0x00305858, tmp);
-
-	/*
-	 * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
-	 * constant leakage current to linearize PFD to 0uA -
-	 * BB_ILOOPF[7:3]
-	 */
-	tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
-	wl12xx_reg_write32(wl, 0x003058f8, tmp);
-
-	/*
-	 * set regulator output voltage for n divider to
-	 * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
-	 * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
-	 * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
-	 */
-	wl12xx_reg_write32(wl, 0x003058f0, 0x29);
-
-	/* enable restart wakeup sequence (ELP_CMD[0]) */
-	wl12xx_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
-
-	/* restart sequence completed */
-	udelay(2000);
-
-	return 0;
-}
-
-int wl12xx_boot_run_firmware(struct wl12xx *wl)
-{
-	int loop, ret;
-	u32 chip_id, interrupt;
-
-	wl->chip.op_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
-
-	chip_id = wl12xx_reg_read32(wl, CHIP_ID_B);
-
-	wl12xx_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
-
-	if (chip_id != wl->chip.id) {
-		wl12xx_error("chip id doesn't match after firmware boot");
-		return -EIO;
-	}
-
-	/* wait for init to complete */
-	loop = 0;
-	while (loop++ < INIT_LOOP) {
-		udelay(INIT_LOOP_DELAY);
-		interrupt = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-
-		if (interrupt == 0xffffffff) {
-			wl12xx_error("error reading hardware complete "
-				     "init indication");
-			return -EIO;
-		}
-		/* check that ACX_INTR_INIT_COMPLETE is enabled */
-		else if (interrupt & wl->chip.intr_init_complete) {
-			wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
-					   wl->chip.intr_init_complete);
-			break;
-		}
-	}
-
-	if (loop >= INIT_LOOP) {
-		wl12xx_error("timeout waiting for the hardware to "
-			     "complete initialization");
-		return -EIO;
-	}
-
-	/* get hardware config command mail box */
-	wl->cmd_box_addr = wl12xx_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
-
-	/* get hardware config event mail box */
-	wl->event_box_addr = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
-
-	/* set the working partition to its "running" mode offset */
-	wl12xx_set_partition(wl,
-			     wl->chip.p_table[PART_WORK].mem.start,
-			     wl->chip.p_table[PART_WORK].mem.size,
-			     wl->chip.p_table[PART_WORK].reg.start,
-			     wl->chip.p_table[PART_WORK].reg.size);
-
-	wl12xx_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
-		     wl->cmd_box_addr, wl->event_box_addr);
-
-	/*
-	 * in case of full asynchronous mode the firmware event must be
-	 * ready to receive event from the command mailbox
-	 */
-
-	/* enable gpio interrupts */
-	wl12xx_boot_enable_interrupts(wl);
-
-	wl->chip.op_target_enable_interrupts(wl);
-
-	/* unmask all mbox events  */
-	wl->event_mask = 0xffffffff;
-
-	ret = wl12xx_event_unmask(wl);
-	if (ret < 0) {
-		wl12xx_error("EVENT mask setting failed");
-		return ret;
-	}
-
-	wl12xx_event_mbox_config(wl);
-
-	/* firmware startup completed */
-	return 0;
-}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
deleted file mode 100644
index 4fa7313..0000000
--- a/drivers/net/wireless/wl12xx/boot.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __BOOT_H__
-#define __BOOT_H__
-
-#include "wl12xx.h"
-
-int wl12xx_boot_soft_reset(struct wl12xx *wl);
-int wl12xx_boot_init_seq(struct wl12xx *wl);
-int wl12xx_boot_run_firmware(struct wl12xx *wl);
-void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl);
-
-/* number of times we try to read the INIT interrupt */
-#define INIT_LOOP 20000
-
-/* delay between retries */
-#define INIT_LOOP_DELAY 50
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
deleted file mode 100644
index f73ab60..0000000
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ /dev/null
@@ -1,353 +0,0 @@
-#include "cmd.h"
-
-#include <linux/module.h>
-#include <linux/crc7.h>
-#include <linux/spi/spi.h>
-
-#include "wl12xx.h"
-#include "wl12xx_80211.h"
-#include "reg.h"
-#include "spi.h"
-#include "ps.h"
-
-int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len)
-{
-	struct wl12xx_command cmd;
-	unsigned long timeout;
-	size_t cmd_len;
-	u32 intr;
-	int ret = 0;
-
-	memset(&cmd, 0, sizeof(cmd));
-	cmd.id = type;
-	cmd.status = 0;
-	memcpy(cmd.parameters, buf, buf_len);
-	cmd_len = ALIGN(buf_len, 4) + CMDMBOX_HEADER_LEN;
-
-	wl12xx_ps_elp_wakeup(wl);
-
-	wl12xx_spi_mem_write(wl, wl->cmd_box_addr, &cmd, cmd_len);
-
-	wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
-
-	timeout = jiffies + msecs_to_jiffies(WL12XX_COMMAND_TIMEOUT);
-
-	intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-	while (!(intr & wl->chip.intr_cmd_complete)) {
-		if (time_after(jiffies, timeout)) {
-			wl12xx_error("command complete timeout");
-			ret = -ETIMEDOUT;
-			goto out;
-		}
-
-		msleep(1);
-
-		intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
-	}
-
-	wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
-			   wl->chip.intr_cmd_complete);
-
-out:
-	wl12xx_ps_elp_sleep(wl);
-
-	return ret;
-}
-
-int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer)
-{
-	int ret;
-
-	wl12xx_debug(DEBUG_CMD, "cmd test");
-
-	ret = wl12xx_cmd_send(wl, CMD_TEST, buf, buf_len);
-	if (ret < 0) {
-		wl12xx_warning("TEST command failed");
-		return ret;
-	}
-
-	if (answer) {
-		struct wl12xx_command *cmd_answer;
-
-		/*
-		 * The test command got in, we can read the answer.
-		 * The answer would be a wl12xx_command, where the
-		 * parameter array contains the actual answer.
-		 */
-
-		wl12xx_ps_elp_wakeup(wl);
-
-		wl12xx_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
-
-		wl12xx_ps_elp_sleep(wl);
-
-		cmd_answer = buf;
-		if (cmd_answer->status != CMD_STATUS_SUCCESS)
-			wl12xx_error("TEST command answer error: %d",
-				     cmd_answer->status);
-	}
-
-	return 0;
-}
-
-
-int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
-			   void *answer)
-{
-	struct wl12xx_command *cmd;
-	struct acx_header header;
-	int ret;
-
-	wl12xx_debug(DEBUG_CMD, "cmd interrogate");
-
-	header.id = ie_id;
-	header.len = ie_len - sizeof(header);
-
-	ret = wl12xx_cmd_send(wl, CMD_INTERROGATE, &header, sizeof(header));
-	if (ret < 0) {
-		wl12xx_error("INTERROGATE command failed");
-		return ret;
-	}
-
-	wl12xx_ps_elp_wakeup(wl);
-
-	/* the interrogate command got in, we can read the answer */
-	wl12xx_spi_mem_read(wl, wl->cmd_box_addr, answer,
-			    CMDMBOX_HEADER_LEN + ie_len);
-
-	wl12xx_ps_elp_sleep(wl);
-
-	cmd = answer;
-	if (cmd->status != CMD_STATUS_SUCCESS)
-		wl12xx_error("INTERROGATE command error: %d",
-			     cmd->status);
-
-	return 0;
-
-}
-
-int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len)
-{
-	int ret;
-
-	wl12xx_debug(DEBUG_CMD, "cmd configure");
-
-	ret = wl12xx_cmd_send(wl, CMD_CONFIGURE, ie,
-			      ie_len);
-	if (ret < 0) {
-		wl12xx_warning("CONFIGURE command NOK");
-		return ret;
-	}
-
-	return 0;
-
-}
-
-int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
-		   void *bitmap, u16 bitmap_len, u8 bitmap_control)
-{
-	struct vbm_update_request vbm;
-	int ret;
-
-	wl12xx_debug(DEBUG_CMD, "cmd vbm");
-
-	/* Count and period will be filled by the target */
-	vbm.tim.bitmap_ctrl = bitmap_control;
-	if (bitmap_len > PARTIAL_VBM_MAX) {
-		wl12xx_warning("cmd vbm len is %d B, truncating to %d",
-			       bitmap_len, PARTIAL_VBM_MAX);
-		bitmap_len = PARTIAL_VBM_MAX;
-	}
-	memcpy(vbm.tim.pvb_field, bitmap, bitmap_len);
-	vbm.tim.identity = identity;
-	vbm.tim.length = bitmap_len + 3;
-
-	vbm.len = cpu_to_le16(bitmap_len + 5);
-
-	ret = wl12xx_cmd_send(wl, CMD_VBM, &vbm, sizeof(vbm));
-	if (ret < 0) {
-		wl12xx_error("VBM command failed");
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable)
-{
-	int ret;
-	u16 cmd_rx, cmd_tx;
-
-	wl12xx_debug(DEBUG_CMD, "cmd data path");
-
-	if (enable) {
-		cmd_rx = CMD_ENABLE_RX;
-		cmd_tx = CMD_ENABLE_TX;
-	} else {
-		cmd_rx = CMD_DISABLE_RX;
-		cmd_tx = CMD_DISABLE_TX;
-	}
-
-	ret = wl12xx_cmd_send(wl, cmd_rx, &channel, sizeof(channel));
-	if (ret < 0) {
-		wl12xx_error("rx %s cmd for channel %d failed",
-			     enable ? "start" : "stop", channel);
-		return ret;
-	}
-
-	wl12xx_debug(DEBUG_BOOT, "rx %s cmd channel %d",
-		     enable ? "start" : "stop", channel);
-
-	ret = wl12xx_cmd_send(wl, cmd_tx, &channel, sizeof(channel));
-	if (ret < 0) {
-		wl12xx_error("tx %s cmd for channel %d failed",
-			     enable ? "start" : "stop", channel);
-		return ret;
-	}
-
-	wl12xx_debug(DEBUG_BOOT, "tx %s cmd channel %d",
-		     enable ? "start" : "stop", channel);
-
-	return 0;
-}
-
-int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
-		    u16 beacon_interval, u8 wait)
-{
-	unsigned long timeout;
-	struct cmd_join join = {};
-	int ret, i;
-	u8 *bssid;
-
-	/* FIXME: this should be in main.c */
-	ret = wl12xx_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
-				     DEFAULT_HW_GEN_MODULATION_TYPE,
-				     wl->tx_mgmt_frm_rate,
-				     wl->tx_mgmt_frm_mod);
-	if (ret < 0)
-		return ret;
-
-	wl12xx_debug(DEBUG_CMD, "cmd join");
-
-	/* Reverse order BSSID */
-	bssid = (u8 *)&join.bssid_lsb;
-	for (i = 0; i < ETH_ALEN; i++)
-		bssid[i] = wl->bssid[ETH_ALEN - i - 1];
-
-	join.rx_config_options = wl->rx_config;
-	join.rx_filter_options = wl->rx_filter;
-
-	join.basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
-		RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
-
-	join.beacon_interval = beacon_interval;
-	join.dtim_interval = dtim_interval;
-	join.bss_type = bss_type;
-	join.channel = wl->channel;
-	join.ctrl = JOIN_CMD_CTRL_TX_FLUSH;
-
-	ret = wl12xx_cmd_send(wl, CMD_START_JOIN, &join, sizeof(join));
-	if (ret < 0) {
-		wl12xx_error("failed to initiate cmd join");
-		return ret;
-	}
-
-	timeout = msecs_to_jiffies(JOIN_TIMEOUT);
-
-	/*
-	 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
-	 * simplify locking we just sleep instead, for now
-	 */
-	if (wait)
-		msleep(10);
-
-	return 0;
-}
-
-int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode)
-{
-	int ret;
-	struct acx_ps_params ps_params;
-
-	/* FIXME: this should be in ps.c */
-	ret = wl12xx_acx_wake_up_conditions(wl, wl->listen_int);
-	if (ret < 0) {
-		wl12xx_error("Couldnt set wake up conditions");
-		return ret;
-	}
-
-	wl12xx_debug(DEBUG_CMD, "cmd set ps mode");
-
-	ps_params.ps_mode = ps_mode;
-	ps_params.send_null_data = 1;
-	ps_params.retries = 5;
-	ps_params.hang_over_period = 128;
-	ps_params.null_data_rate = 1; /* 1 Mbps */
-
-	ret = wl12xx_cmd_send(wl, CMD_SET_PS_MODE, &ps_params,
-			      sizeof(ps_params));
-	if (ret < 0) {
-		wl12xx_error("cmd set_ps_mode failed");
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer)
-{
-	struct cmd_read_write_memory mem_cmd, *mem_answer;
-	struct wl12xx_command cmd;
-	int ret;
-
-	wl12xx_debug(DEBUG_CMD, "cmd read memory");
-
-	memset(&mem_cmd, 0, sizeof(mem_cmd));
-	mem_cmd.addr = addr;
-	mem_cmd.size = len;
-
-	ret = wl12xx_cmd_send(wl, CMD_READ_MEMORY, &mem_cmd, sizeof(mem_cmd));
-	if (ret < 0) {
-		wl12xx_error("read memory command failed: %d", ret);
-		return ret;
-	}
-
-	/* the read command got in, we can now read the answer */
-	wl12xx_spi_mem_read(wl, wl->cmd_box_addr, &cmd,
-			    CMDMBOX_HEADER_LEN + sizeof(mem_cmd));
-
-	if (cmd.status != CMD_STATUS_SUCCESS)
-		wl12xx_error("error in read command result: %d", cmd.status);
-
-	mem_answer = (struct cmd_read_write_memory *) cmd.parameters;
-	memcpy(answer, mem_answer->value, len);
-
-	return 0;
-}
-
-int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
-			    void *buf, size_t buf_len)
-{
-	struct wl12xx_cmd_packet_template template;
-	int ret;
-
-	wl12xx_debug(DEBUG_CMD, "cmd template %d", cmd_id);
-
-	memset(&template, 0, sizeof(template));
-
-	WARN_ON(buf_len > WL12XX_MAX_TEMPLATE_SIZE);
-	buf_len = min_t(size_t, buf_len, WL12XX_MAX_TEMPLATE_SIZE);
-	template.size = cpu_to_le16(buf_len);
-
-	if (buf)
-		memcpy(template.template, buf, buf_len);
-
-	ret = wl12xx_cmd_send(wl, cmd_id, &template,
-			      sizeof(template.size) + buf_len);
-	if (ret < 0) {
-		wl12xx_warning("cmd set_template failed: %d", ret);
-		return ret;
-	}
-
-	return 0;
-}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
deleted file mode 100644
index aa307dc..0000000
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_CMD_H__
-#define __WL12XX_CMD_H__
-
-#include "wl12xx.h"
-
-int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len);
-int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer);
-int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
-			   void *answer);
-int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len);
-int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
-		   void *bitmap, u16 bitmap_len, u8 bitmap_control);
-int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable);
-int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
-		    u16 beacon_interval, u8 wait);
-int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode);
-int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer);
-int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
-			    void *buf, size_t buf_len);
-
-/* unit ms */
-#define WL12XX_COMMAND_TIMEOUT 2000
-
-#define WL12XX_MAX_TEMPLATE_SIZE 300
-
-struct wl12xx_cmd_packet_template {
-	__le16 size;
-	u8 template[WL12XX_MAX_TEMPLATE_SIZE];
-} __attribute__ ((packed));
-
-enum wl12xx_commands {
-	CMD_RESET           = 0,
-	CMD_INTERROGATE     = 1,    /*use this to read information elements*/
-	CMD_CONFIGURE       = 2,    /*use this to write information elements*/
-	CMD_ENABLE_RX       = 3,
-	CMD_ENABLE_TX       = 4,
-	CMD_DISABLE_RX      = 5,
-	CMD_DISABLE_TX      = 6,
-	CMD_SCAN            = 8,
-	CMD_STOP_SCAN       = 9,
-	CMD_VBM             = 10,
-	CMD_START_JOIN      = 11,
-	CMD_SET_KEYS        = 12,
-	CMD_READ_MEMORY     = 13,
-	CMD_WRITE_MEMORY    = 14,
-	CMD_BEACON          = 19,
-	CMD_PROBE_RESP      = 20,
-	CMD_NULL_DATA       = 21,
-	CMD_PROBE_REQ       = 22,
-	CMD_TEST            = 23,
-	CMD_RADIO_CALIBRATE     = 25,   /* OBSOLETE */
-	CMD_ENABLE_RX_PATH      = 27,   /* OBSOLETE */
-	CMD_NOISE_HIST      = 28,
-	CMD_RX_RESET        = 29,
-	CMD_PS_POLL         = 30,
-	CMD_QOS_NULL_DATA   = 31,
-	CMD_LNA_CONTROL     = 32,
-	CMD_SET_BCN_MODE    = 33,
-	CMD_MEASUREMENT      = 34,
-	CMD_STOP_MEASUREMENT = 35,
-	CMD_DISCONNECT       = 36,
-	CMD_SET_PS_MODE      = 37,
-	CMD_CHANNEL_SWITCH   = 38,
-	CMD_STOP_CHANNEL_SWICTH = 39,
-	CMD_AP_DISCOVERY     = 40,
-	CMD_STOP_AP_DISCOVERY = 41,
-	CMD_SPS_SCAN = 42,
-	CMD_STOP_SPS_SCAN = 43,
-	CMD_HEALTH_CHECK     = 45,
-	CMD_DEBUG            = 46,
-	CMD_TRIGGER_SCAN_TO  = 47,
-
-	NUM_COMMANDS,
-	MAX_COMMAND_ID = 0xFFFF,
-};
-
-#define MAX_CMD_PARAMS 572
-
-struct  wl12xx_command {
-	u16 id;
-	u16 status;
-	u8  parameters[MAX_CMD_PARAMS];
-};
-
-enum {
-	CMD_MAILBOX_IDLE              		=  0,
-	CMD_STATUS_SUCCESS            		=  1,
-	CMD_STATUS_UNKNOWN_CMD        		=  2,
-	CMD_STATUS_UNKNOWN_IE         		=  3,
-	CMD_STATUS_REJECT_MEAS_SG_ACTIVE 	= 11,
-	CMD_STATUS_RX_BUSY            		= 13,
-	CMD_STATUS_INVALID_PARAM      		= 14,
-	CMD_STATUS_TEMPLATE_TOO_LARGE 		= 15,
-	CMD_STATUS_OUT_OF_MEMORY      		= 16,
-	CMD_STATUS_STA_TABLE_FULL     		= 17,
-	CMD_STATUS_RADIO_ERROR        		= 18,
-	CMD_STATUS_WRONG_NESTING      		= 19,
-	CMD_STATUS_TIMEOUT            		= 21, /* Driver internal use.*/
-	CMD_STATUS_FW_RESET           		= 22, /* Driver internal use.*/
-	MAX_COMMAND_STATUS            		= 0xff
-};
-
-
-/*
- * CMD_READ_MEMORY
- *
- * The host issues this command to read the WiLink device memory/registers.
- *
- * Note: The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-/*
- * CMD_WRITE_MEMORY
- *
- * The host issues this command to write the WiLink device memory/registers.
- *
- * The Base Band address has special handling (16 bits registers and
- * addresses). For more information, see the hardware specification.
- */
-#define MAX_READ_SIZE 256
-
-struct cmd_read_write_memory {
-	/* The address of the memory to read from or write to.*/
-	u32 addr;
-
-	/* The amount of data in bytes to read from or write to the WiLink
-	 * device.*/
-	u32 size;
-
-	/* The actual value read from or written to the Wilink. The source
-	   of this field is the Host in WRITE command or the Wilink in READ
-	   command. */
-	u8 value[MAX_READ_SIZE];
-};
-
-#define CMDMBOX_HEADER_LEN 4
-#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
-
-
-struct basic_scan_parameters {
-	u32 rx_config_options;
-	u32 rx_filter_options;
-
-	/*
-	 * Scan options:
-	 * bit 0: When this bit is set, passive scan.
-	 * bit 1: Band, when this bit is set we scan
-	 * in the 5Ghz band.
-	 * bit 2: voice mode, 0 for normal scan.
-	 * bit 3: scan priority, 1 for high priority.
-	 */
-	u16 scan_options;
-
-	/* Number of channels to scan */
-	u8 num_channels;
-
-	/* Number opf probe requests to send, per channel */
-	u8 num_probe_requests;
-
-	/* Rate and modulation for probe requests */
-	u16 tx_rate;
-
-	u8 tid_trigger;
-	u8 ssid_len;
-	u32 ssid[8];
-
-} __attribute__ ((packed));
-
-struct basic_scan_channel_parameters {
-	u32 min_duration; /* in TU */
-	u32 max_duration; /* in TU */
-	u32 bssid_lsb;
-	u16 bssid_msb;
-
-	/*
-	 * bits 0-3: Early termination count.
-	 * bits 4-5: Early termination condition.
-	 */
-	u8 early_termination;
-
-	u8 tx_power_att;
-	u8 channel;
-	u8 pad[3];
-} __attribute__ ((packed));
-
-/* SCAN parameters */
-#define SCAN_MAX_NUM_OF_CHANNELS 16
-
-struct cmd_scan {
-	struct basic_scan_parameters params;
-	struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
-} __attribute__ ((packed));
-
-enum {
-	BSS_TYPE_IBSS = 0,
-	BSS_TYPE_STA_BSS = 2,
-	BSS_TYPE_AP_BSS = 3,
-	MAX_BSS_TYPE = 0xFF
-};
-
-#define JOIN_CMD_CTRL_TX_FLUSH             0x80 /* Firmware flushes all Tx */
-#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE  0x01 /* Early wakeup time */
-
-
-struct cmd_join {
-	u32 bssid_lsb;
-	u16 bssid_msb;
-	u16 beacon_interval; /* in TBTTs */
-	u32 rx_config_options;
-	u32 rx_filter_options;
-
-	/*
-	 * The target uses this field to determine the rate at
-	 * which to transmit control frame responses (such as
-	 * ACK or CTS frames).
-	 */
-	u16 basic_rate_set;
-	u8 dtim_interval;
-	u8 tx_ctrl_frame_rate; /* OBSOLETE */
-	u8 tx_ctrl_frame_mod;  /* OBSOLETE */
-	/*
-	 * bits 0-2: This bitwise field specifies the type
-	 * of BSS to start or join (BSS_TYPE_*).
-	 * bit 4: Band - The radio band in which to join
-	 * or start.
-	 *  0 - 2.4GHz band
-	 *  1 - 5GHz band
-	 * bits 3, 5-7: Reserved
-	 */
-	u8 bss_type;
-	u8 channel;
-	u8 ssid_len;
-	u8 ssid[IW_ESSID_MAX_SIZE];
-	u8 ctrl; /* JOIN_CMD_CTRL_* */
-	u8 tx_mgt_frame_rate; /* OBSOLETE */
-	u8 tx_mgt_frame_mod;  /* OBSOLETE */
-	u8 reserved;
-} __attribute__ ((packed));
-
-
-#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
deleted file mode 100644
index cdb368c..0000000
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * 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 "debugfs.h"
-
-#include <linux/skbuff.h>
-
-#include "wl12xx.h"
-#include "acx.h"
-
-/* ms */
-#define WL12XX_DEBUGFS_STATS_LIFETIME 1000
-
-/* debugfs macros idea from mac80211 */
-
-#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)		\
-static ssize_t name## _read(struct file *file, char __user *userbuf,	\
-			    size_t count, loff_t *ppos)			\
-{									\
-	struct wl12xx *wl = file->private_data;				\
-	char buf[buflen];						\
-	int res;							\
-									\
-	res = scnprintf(buf, buflen, fmt "\n", ##value);		\
-	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
-}									\
-									\
-static const struct file_operations name## _ops = {			\
-	.read = name## _read,						\
-	.open = wl12xx_open_file_generic,				\
-};
-
-#define DEBUGFS_ADD(name, parent)					\
-	wl->debugfs.name = debugfs_create_file(#name, 0400, parent,	\
-					       wl, &name## _ops);	\
-	if (IS_ERR(wl->debugfs.name)) {					\
-		ret = PTR_ERR(wl->debugfs.name);			\
-		wl->debugfs.name = NULL;				\
-		goto out;						\
-	}
-
-#define DEBUGFS_DEL(name)						\
-	do {								\
-		debugfs_remove(wl->debugfs.name);			\
-		wl->debugfs.name = NULL;				\
-	} while (0)
-
-#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt)			\
-static ssize_t sub## _ ##name## _read(struct file *file,		\
-				      char __user *userbuf,		\
-				      size_t count, loff_t *ppos)	\
-{									\
-	struct wl12xx *wl = file->private_data;				\
-	char buf[buflen];						\
-	int res;							\
-									\
-	wl12xx_debugfs_update_stats(wl);				\
-									\
-	res = scnprintf(buf, buflen, fmt "\n",				\
-			wl->stats.fw_stats->sub.name);			\
-	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
-}									\
-									\
-static const struct file_operations sub## _ ##name## _ops = {		\
-	.read = sub## _ ##name## _read,					\
-	.open = wl12xx_open_file_generic,				\
-};
-
-#define DEBUGFS_FWSTATS_ADD(sub, name)				\
-	DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
-
-#define DEBUGFS_FWSTATS_DEL(sub, name)				\
-	DEBUGFS_DEL(sub## _ ##name)
-
-static void wl12xx_debugfs_update_stats(struct wl12xx *wl)
-{
-	mutex_lock(&wl->mutex);
-
-	if (wl->state == WL12XX_STATE_ON &&
-	    time_after(jiffies, wl->stats.fw_stats_update +
-		       msecs_to_jiffies(WL12XX_DEBUGFS_STATS_LIFETIME))) {
-		wl12xx_acx_statistics(wl, wl->stats.fw_stats);
-		wl->stats.fw_stats_update = jiffies;
-	}
-
-	mutex_unlock(&wl->mutex);
-}
-
-static int wl12xx_open_file_generic(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
-DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
-DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
-/* skipping wep.reserved */
-DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
-DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
-/* skipping cont_miss_bcns_spread for now */
-DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
-DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
-DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
-DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
-
-DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
-		     20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
-DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
-
-DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
-DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
-		      wl->stats.excessive_retries);
-
-static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
-				 size_t count, loff_t *ppos)
-{
-	struct wl12xx *wl = file->private_data;
-	u32 queue_len;
-	char buf[20];
-	int res;
-
-	queue_len = skb_queue_len(&wl->tx_queue);
-
-	res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
-	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
-}
-
-static const struct file_operations tx_queue_len_ops = {
-	.read = tx_queue_len_read,
-	.open = wl12xx_open_file_generic,
-};
-
-static void wl12xx_debugfs_delete_files(struct wl12xx *wl)
-{
-	DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
-
-	DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
-	DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
-	DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
-	DEBUGFS_FWSTATS_DEL(rx, dropped);
-	DEBUGFS_FWSTATS_DEL(rx, fcs_err);
-	DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
-	DEBUGFS_FWSTATS_DEL(rx, path_reset);
-	DEBUGFS_FWSTATS_DEL(rx, reset_counter);
-
-	DEBUGFS_FWSTATS_DEL(dma, rx_requested);
-	DEBUGFS_FWSTATS_DEL(dma, rx_errors);
-	DEBUGFS_FWSTATS_DEL(dma, tx_requested);
-	DEBUGFS_FWSTATS_DEL(dma, tx_errors);
-
-	DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
-	DEBUGFS_FWSTATS_DEL(isr, fiqs);
-	DEBUGFS_FWSTATS_DEL(isr, rx_headers);
-	DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
-	DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
-	DEBUGFS_FWSTATS_DEL(isr, irqs);
-	DEBUGFS_FWSTATS_DEL(isr, tx_procs);
-	DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
-	DEBUGFS_FWSTATS_DEL(isr, dma0_done);
-	DEBUGFS_FWSTATS_DEL(isr, dma1_done);
-	DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
-	DEBUGFS_FWSTATS_DEL(isr, commands);
-	DEBUGFS_FWSTATS_DEL(isr, rx_procs);
-	DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
-	DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
-	DEBUGFS_FWSTATS_DEL(isr, pci_pm);
-	DEBUGFS_FWSTATS_DEL(isr, wakeups);
-	DEBUGFS_FWSTATS_DEL(isr, low_rssi);
-
-	DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
-	DEBUGFS_FWSTATS_DEL(wep, default_key_count);
-	/* skipping wep.reserved */
-	DEBUGFS_FWSTATS_DEL(wep, key_not_found);
-	DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
-	DEBUGFS_FWSTATS_DEL(wep, packets);
-	DEBUGFS_FWSTATS_DEL(wep, interrupt);
-
-	DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
-	DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
-	DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
-	DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
-	DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
-	DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
-	DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
-	DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
-	DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
-	DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
-	DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
-	DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
-	/* skipping cont_miss_bcns_spread for now */
-	DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
-
-	DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
-	DEBUGFS_FWSTATS_DEL(mic, calc_failure);
-
-	DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
-	DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
-	DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
-	DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
-	DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
-	DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
-
-	DEBUGFS_FWSTATS_DEL(event, heart_beat);
-	DEBUGFS_FWSTATS_DEL(event, calibration);
-	DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
-	DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
-	DEBUGFS_FWSTATS_DEL(event, rx_pool);
-	DEBUGFS_FWSTATS_DEL(event, oom_late);
-	DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
-	DEBUGFS_FWSTATS_DEL(event, tx_stuck);
-
-	DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
-	DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
-	DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
-	DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
-	DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
-	DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
-	DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
-
-	DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
-	DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
-	DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
-	DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
-	DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
-
-	DEBUGFS_DEL(tx_queue_len);
-	DEBUGFS_DEL(retry_count);
-	DEBUGFS_DEL(excessive_retries);
-}
-
-static int wl12xx_debugfs_add_files(struct wl12xx *wl)
-{
-	int ret = 0;
-
-	DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
-
-	DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
-	DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
-	DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
-	DEBUGFS_FWSTATS_ADD(rx, dropped);
-	DEBUGFS_FWSTATS_ADD(rx, fcs_err);
-	DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
-	DEBUGFS_FWSTATS_ADD(rx, path_reset);
-	DEBUGFS_FWSTATS_ADD(rx, reset_counter);
-
-	DEBUGFS_FWSTATS_ADD(dma, rx_requested);
-	DEBUGFS_FWSTATS_ADD(dma, rx_errors);
-	DEBUGFS_FWSTATS_ADD(dma, tx_requested);
-	DEBUGFS_FWSTATS_ADD(dma, tx_errors);
-
-	DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
-	DEBUGFS_FWSTATS_ADD(isr, fiqs);
-	DEBUGFS_FWSTATS_ADD(isr, rx_headers);
-	DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
-	DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
-	DEBUGFS_FWSTATS_ADD(isr, irqs);
-	DEBUGFS_FWSTATS_ADD(isr, tx_procs);
-	DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
-	DEBUGFS_FWSTATS_ADD(isr, dma0_done);
-	DEBUGFS_FWSTATS_ADD(isr, dma1_done);
-	DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
-	DEBUGFS_FWSTATS_ADD(isr, commands);
-	DEBUGFS_FWSTATS_ADD(isr, rx_procs);
-	DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
-	DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
-	DEBUGFS_FWSTATS_ADD(isr, pci_pm);
-	DEBUGFS_FWSTATS_ADD(isr, wakeups);
-	DEBUGFS_FWSTATS_ADD(isr, low_rssi);
-
-	DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
-	DEBUGFS_FWSTATS_ADD(wep, default_key_count);
-	/* skipping wep.reserved */
-	DEBUGFS_FWSTATS_ADD(wep, key_not_found);
-	DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
-	DEBUGFS_FWSTATS_ADD(wep, packets);
-	DEBUGFS_FWSTATS_ADD(wep, interrupt);
-
-	DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
-	DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
-	DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
-	DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
-	DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
-	DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
-	DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
-	DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
-	DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
-	DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
-	DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
-	DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
-	/* skipping cont_miss_bcns_spread for now */
-	DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
-
-	DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
-	DEBUGFS_FWSTATS_ADD(mic, calc_failure);
-
-	DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
-	DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
-	DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
-	DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
-	DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
-	DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
-
-	DEBUGFS_FWSTATS_ADD(event, heart_beat);
-	DEBUGFS_FWSTATS_ADD(event, calibration);
-	DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
-	DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
-	DEBUGFS_FWSTATS_ADD(event, rx_pool);
-	DEBUGFS_FWSTATS_ADD(event, oom_late);
-	DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
-	DEBUGFS_FWSTATS_ADD(event, tx_stuck);
-
-	DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
-	DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
-	DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
-	DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
-	DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
-	DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
-	DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
-
-	DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
-	DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
-	DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
-	DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
-	DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
-
-	DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
-	DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
-	DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
-
-out:
-	if (ret < 0)
-		wl12xx_debugfs_delete_files(wl);
-
-	return ret;
-}
-
-void wl12xx_debugfs_reset(struct wl12xx *wl)
-{
-	memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
-	wl->stats.retry_count = 0;
-	wl->stats.excessive_retries = 0;
-}
-
-int wl12xx_debugfs_init(struct wl12xx *wl)
-{
-	int ret;
-
-	wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
-
-	if (IS_ERR(wl->debugfs.rootdir)) {
-		ret = PTR_ERR(wl->debugfs.rootdir);
-		wl->debugfs.rootdir = NULL;
-		goto err;
-	}
-
-	wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
-						       wl->debugfs.rootdir);
-
-	if (IS_ERR(wl->debugfs.fw_statistics)) {
-		ret = PTR_ERR(wl->debugfs.fw_statistics);
-		wl->debugfs.fw_statistics = NULL;
-		goto err_root;
-	}
-
-	wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
-				      GFP_KERNEL);
-
-	if (!wl->stats.fw_stats) {
-		ret = -ENOMEM;
-		goto err_fw;
-	}
-
-	wl->stats.fw_stats_update = jiffies;
-
-	ret = wl12xx_debugfs_add_files(wl);
-
-	if (ret < 0)
-		goto err_file;
-
-	return 0;
-
-err_file:
-	kfree(wl->stats.fw_stats);
-	wl->stats.fw_stats = NULL;
-
-err_fw:
-	debugfs_remove(wl->debugfs.fw_statistics);
-	wl->debugfs.fw_statistics = NULL;
-
-err_root:
-	debugfs_remove(wl->debugfs.rootdir);
-	wl->debugfs.rootdir = NULL;
-
-err:
-	return ret;
-}
-
-void wl12xx_debugfs_exit(struct wl12xx *wl)
-{
-	wl12xx_debugfs_delete_files(wl);
-
-	kfree(wl->stats.fw_stats);
-	wl->stats.fw_stats = NULL;
-
-	debugfs_remove(wl->debugfs.fw_statistics);
-	wl->debugfs.fw_statistics = NULL;
-
-	debugfs_remove(wl->debugfs.rootdir);
-	wl->debugfs.rootdir = NULL;
-
-}
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
deleted file mode 100644
index 562cdcb..0000000
--- a/drivers/net/wireless/wl12xx/debugfs.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef WL12XX_DEBUGFS_H
-#define WL12XX_DEBUGFS_H
-
-#include "wl12xx.h"
-
-int wl12xx_debugfs_init(struct wl12xx *wl);
-void wl12xx_debugfs_exit(struct wl12xx *wl);
-void wl12xx_debugfs_reset(struct wl12xx *wl);
-
-#endif /* WL12XX_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
deleted file mode 100644
index 99529ca..0000000
--- a/drivers/net/wireless/wl12xx/event.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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 "wl12xx.h"
-#include "reg.h"
-#include "spi.h"
-#include "event.h"
-#include "ps.h"
-
-static int wl12xx_event_scan_complete(struct wl12xx *wl,
-				      struct event_mailbox *mbox)
-{
-	wl12xx_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
-		     mbox->scheduled_scan_status,
-		     mbox->scheduled_scan_channels);
-
-	if (wl->scanning) {
-		mutex_unlock(&wl->mutex);
-		ieee80211_scan_completed(wl->hw, false);
-		mutex_lock(&wl->mutex);
-		wl->scanning = false;
-	}
-
-	return 0;
-}
-
-static void wl12xx_event_mbox_dump(struct event_mailbox *mbox)
-{
-	wl12xx_debug(DEBUG_EVENT, "MBOX DUMP:");
-	wl12xx_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
-	wl12xx_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
-}
-
-static int wl12xx_event_process(struct wl12xx *wl, struct event_mailbox *mbox)
-{
-	int ret;
-	u32 vector;
-
-	wl12xx_event_mbox_dump(mbox);
-
-	vector = mbox->events_vector & ~(mbox->events_mask);
-	wl12xx_debug(DEBUG_EVENT, "vector: 0x%x", vector);
-
-	if (vector & SCAN_COMPLETE_EVENT_ID) {
-		ret = wl12xx_event_scan_complete(wl, mbox);
-		if (ret < 0)
-			return ret;
-	}
-
-	if (vector & BSS_LOSE_EVENT_ID) {
-		wl12xx_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
-
-		if (wl->psm_requested && wl->psm) {
-			ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
-			if (ret < 0)
-				return ret;
-		}
-	}
-
-	return 0;
-}
-
-int wl12xx_event_unmask(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl12xx_acx_event_mbox_mask(wl, ~(wl->event_mask));
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-void wl12xx_event_mbox_config(struct wl12xx *wl)
-{
-	wl->mbox_ptr[0] = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
-	wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
-
-	wl12xx_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
-		     wl->mbox_ptr[0], wl->mbox_ptr[1]);
-}
-
-int wl12xx_event_handle(struct wl12xx *wl, u8 mbox_num)
-{
-	struct event_mailbox mbox;
-	int ret;
-
-	wl12xx_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
-
-	if (mbox_num > 1)
-		return -EINVAL;
-
-	/* first we read the mbox descriptor */
-	wl12xx_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
-			    sizeof(struct event_mailbox));
-
-	/* process the descriptor */
-	ret = wl12xx_event_process(wl, &mbox);
-	if (ret < 0)
-		return ret;
-
-	/* then we let the firmware know it can go on...*/
-	wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
-
-	return 0;
-}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
deleted file mode 100644
index 1f4c2f7..0000000
--- a/drivers/net/wireless/wl12xx/event.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_EVENT_H__
-#define __WL12XX_EVENT_H__
-
-/*
- * Mbox events
- *
- * The event mechanism is based on a pair of event buffers (buffers A and
- * B) at fixed locations in the target's memory. The host processes one
- * buffer while the other buffer continues to collect events. If the host
- * is not processing events, an interrupt is issued to signal that a buffer
- * is ready. Once the host is done with processing events from one buffer,
- * it signals the target (with an ACK interrupt) that the event buffer is
- * free.
- */
-
-enum {
-	RESERVED1_EVENT_ID                       = BIT(0),
-	RESERVED2_EVENT_ID                       = BIT(1),
-	MEASUREMENT_START_EVENT_ID               = BIT(2),
-	SCAN_COMPLETE_EVENT_ID                   = BIT(3),
-	CALIBRATION_COMPLETE_EVENT_ID            = BIT(4),
-	ROAMING_TRIGGER_LOW_RSSI_EVENT_ID        = BIT(5),
-	PS_REPORT_EVENT_ID                       = BIT(6),
-	SYNCHRONIZATION_TIMEOUT_EVENT_ID         = BIT(7),
-	HEALTH_REPORT_EVENT_ID                   = BIT(8),
-	ACI_DETECTION_EVENT_ID                   = BIT(9),
-	DEBUG_REPORT_EVENT_ID                    = BIT(10),
-	MAC_STATUS_EVENT_ID                      = BIT(11),
-	DISCONNECT_EVENT_COMPLETE_ID             = BIT(12),
-	JOIN_EVENT_COMPLETE_ID                   = BIT(13),
-	CHANNEL_SWITCH_COMPLETE_EVENT_ID         = BIT(14),
-	BSS_LOSE_EVENT_ID                        = BIT(15),
-	ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID    = BIT(16),
-	MEASUREMENT_COMPLETE_EVENT_ID            = BIT(17),
-	AP_DISCOVERY_COMPLETE_EVENT_ID           = BIT(18),
-	SCHEDULED_SCAN_COMPLETE_EVENT_ID         = BIT(19),
-	PSPOLL_DELIVERY_FAILURE_EVENT_ID 	 = BIT(20),
-	RESET_BSS_EVENT_ID                       = BIT(21),
-	REGAINED_BSS_EVENT_ID                    = BIT(22),
-	ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID   = BIT(23),
-	ROAMING_TRIGGER_LOW_SNR_EVENT_ID         = BIT(24),
-	ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID    = BIT(25),
-
-	DBG_EVENT_ID                             = BIT(26),
-	BT_PTA_SENSE_EVENT_ID                    = BIT(27),
-	BT_PTA_PREDICTION_EVENT_ID               = BIT(28),
-	BT_PTA_AVALANCHE_EVENT_ID                = BIT(29),
-
-	PLT_RX_CALIBRATION_COMPLETE_EVENT_ID     = BIT(30),
-
-	EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
-};
-
-struct event_debug_report {
-	u8 debug_event_id;
-	u8 num_params;
-	u16 pad;
-	u32 report_1;
-	u32 report_2;
-	u32 report_3;
-} __attribute__ ((packed));
-
-struct event_mailbox {
-	u32 events_vector;
-	u32 events_mask;
-	u32 reserved_1;
-	u32 reserved_2;
-
-	char average_rssi_level;
-	u8 ps_status;
-	u8 channel_switch_status;
-	u8 scheduled_scan_status;
-
-	/* Channels scanned by the scheduled scan */
-	u16 scheduled_scan_channels;
-
-	/* If bit 0 is set -> target's fatal error */
-	u16 health_report;
-	u16 bad_fft_counter;
-	u8 bt_pta_sense_info;
-	u8 bt_pta_protective_info;
-	u32 reserved;
-	u32 debug_report[2];
-
-	/* Number of FCS errors since last event */
-	u32 fcs_err_counter;
-
-	struct event_debug_report report;
-	u8 average_snr_level;
-	u8 padding[19];
-} __attribute__ ((packed));
-
-int wl12xx_event_unmask(struct wl12xx *wl);
-void wl12xx_event_mbox_config(struct wl12xx *wl);
-int wl12xx_event_handle(struct wl12xx *wl, u8 mbox);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
deleted file mode 100644
index 2a573a6..0000000
--- a/drivers/net/wireless/wl12xx/init.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * 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/kernel.h>
-#include <linux/module.h>
-
-#include "init.h"
-#include "wl12xx_80211.h"
-#include "acx.h"
-#include "cmd.h"
-
-int wl12xx_hw_init_hwenc_config(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl12xx_acx_feature_cfg(wl);
-	if (ret < 0) {
-		wl12xx_warning("couldn't set feature config");
-		return ret;
-	}
-
-	ret = wl12xx_acx_default_key(wl, wl->default_key);
-	if (ret < 0) {
-		wl12xx_warning("couldn't set default key");
-		return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_hw_init_templates_config(struct wl12xx *wl)
-{
-	int ret;
-	u8 partial_vbm[PARTIAL_VBM_MAX];
-
-	/* send empty templates for fw memory reservation */
-	ret = wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
-				      sizeof(struct wl12xx_probe_req_template));
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_cmd_template_set(wl, CMD_NULL_DATA, NULL,
-				      sizeof(struct wl12xx_null_data_template));
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_cmd_template_set(wl, CMD_PS_POLL, NULL,
-				      sizeof(struct wl12xx_ps_poll_template));
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
-				      sizeof
-				      (struct wl12xx_qos_null_data_template));
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
-				      sizeof
-				      (struct wl12xx_probe_resp_template));
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_cmd_template_set(wl, CMD_BEACON, NULL,
-				      sizeof
-				      (struct wl12xx_beacon_template));
-	if (ret < 0)
-		return ret;
-
-	/* tim templates, first reserve space then allocate an empty one */
-	memset(partial_vbm, 0, PARTIAL_VBM_MAX);
-	ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter)
-{
-	int ret;
-
-	ret = wl12xx_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_acx_rx_config(wl, config, filter);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_hw_init_phy_config(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl12xx_acx_pd_threshold(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_acx_slot(wl, DEFAULT_SLOT_TIME);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_acx_group_address_tbl(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_acx_service_period_timeout(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_hw_init_beacon_filter(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl12xx_acx_beacon_filter_opt(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_acx_beacon_filter_table(wl);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_hw_init_pta(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl12xx_acx_sg_enable(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_acx_sg_cfg(wl);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_hw_init_energy_detection(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl12xx_acx_cca_threshold(wl);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl12xx_acx_bcn_dtim_options(wl);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_hw_init_power_auth(struct wl12xx *wl)
-{
-	return wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
-}
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
deleted file mode 100644
index c8b6cd0..0000000
--- a/drivers/net/wireless/wl12xx/init.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2009 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_INIT_H__
-#define __WL12XX_INIT_H__
-
-#include "wl12xx.h"
-
-int wl12xx_hw_init_hwenc_config(struct wl12xx *wl);
-int wl12xx_hw_init_templates_config(struct wl12xx *wl);
-int wl12xx_hw_init_mem_config(struct wl12xx *wl);
-int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter);
-int wl12xx_hw_init_phy_config(struct wl12xx *wl);
-int wl12xx_hw_init_beacon_filter(struct wl12xx *wl);
-int wl12xx_hw_init_pta(struct wl12xx *wl);
-int wl12xx_hw_init_energy_detection(struct wl12xx *wl);
-int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl);
-int wl12xx_hw_init_power_auth(struct wl12xx *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
deleted file mode 100644
index 603d611..0000000
--- a/drivers/net/wireless/wl12xx/main.c
+++ /dev/null
@@ -1,1358 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * 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/module.h>
-#include <linux/interrupt.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/spi/spi.h>
-#include <linux/crc32.h>
-#include <linux/etherdevice.h>
-#include <linux/spi/wl12xx.h>
-
-#include "wl12xx.h"
-#include "wl12xx_80211.h"
-#include "reg.h"
-#include "wl1251.h"
-#include "spi.h"
-#include "event.h"
-#include "tx.h"
-#include "rx.h"
-#include "ps.h"
-#include "init.h"
-#include "debugfs.h"
-
-static void wl12xx_disable_interrupts(struct wl12xx *wl)
-{
-	disable_irq(wl->irq);
-}
-
-static void wl12xx_power_off(struct wl12xx *wl)
-{
-	wl->set_power(false);
-}
-
-static void wl12xx_power_on(struct wl12xx *wl)
-{
-	wl->set_power(true);
-}
-
-static irqreturn_t wl12xx_irq(int irq, void *cookie)
-{
-	struct wl12xx *wl;
-
-	wl12xx_debug(DEBUG_IRQ, "IRQ");
-
-	wl = cookie;
-
-	schedule_work(&wl->irq_work);
-
-	return IRQ_HANDLED;
-}
-
-static int wl12xx_fetch_firmware(struct wl12xx *wl)
-{
-	const struct firmware *fw;
-	int ret;
-
-	ret = request_firmware(&fw, wl->chip.fw_filename, &wl->spi->dev);
-
-	if (ret < 0) {
-		wl12xx_error("could not get firmware: %d", ret);
-		return ret;
-	}
-
-	if (fw->size % 4) {
-		wl12xx_error("firmware size is not multiple of 32 bits: %zu",
-			     fw->size);
-		ret = -EILSEQ;
-		goto out;
-	}
-
-	wl->fw_len = fw->size;
-	wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
-
-	if (!wl->fw) {
-		wl12xx_error("could not allocate memory for the firmware");
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	memcpy(wl->fw, fw->data, wl->fw_len);
-
-	ret = 0;
-
-out:
-	release_firmware(fw);
-
-	return ret;
-}
-
-static int wl12xx_fetch_nvs(struct wl12xx *wl)
-{
-	const struct firmware *fw;
-	int ret;
-
-	ret = request_firmware(&fw, wl->chip.nvs_filename, &wl->spi->dev);
-
-	if (ret < 0) {
-		wl12xx_error("could not get nvs file: %d", ret);
-		return ret;
-	}
-
-	if (fw->size % 4) {
-		wl12xx_error("nvs size is not multiple of 32 bits: %zu",
-			     fw->size);
-		ret = -EILSEQ;
-		goto out;
-	}
-
-	wl->nvs_len = fw->size;
-	wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
-
-	if (!wl->nvs) {
-		wl12xx_error("could not allocate memory for the nvs file");
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	memcpy(wl->nvs, fw->data, wl->nvs_len);
-
-	ret = 0;
-
-out:
-	release_firmware(fw);
-
-	return ret;
-}
-
-static void wl12xx_fw_wakeup(struct wl12xx *wl)
-{
-	u32 elp_reg;
-
-	elp_reg = ELPCTRL_WAKE_UP;
-	wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
-	elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-
-	if (!(elp_reg & ELPCTRL_WLAN_READY)) {
-		wl12xx_warning("WLAN not ready");
-		elp_reg = ELPCTRL_WAKE_UP_WLAN_READY;
-		wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
-	}
-}
-
-static int wl12xx_chip_wakeup(struct wl12xx *wl)
-{
-	int ret = 0;
-
-	wl12xx_power_on(wl);
-	msleep(wl->chip.power_on_sleep);
-	wl12xx_spi_reset(wl);
-	wl12xx_spi_init(wl);
-
-	/* We don't need a real memory partition here, because we only want
-	 * to use the registers at this point. */
-	wl12xx_set_partition(wl,
-			     0x00000000,
-			     0x00000000,
-			     REGISTERS_BASE,
-			     REGISTERS_DOWN_SIZE);
-
-	/* ELP module wake up */
-	wl12xx_fw_wakeup(wl);
-
-	/* whal_FwCtrl_BootSm() */
-
-	/* 0. read chip id from CHIP_ID */
-	wl->chip.id = wl12xx_reg_read32(wl, CHIP_ID_B);
-
-	/* 1. check if chip id is valid */
-
-	switch (wl->chip.id) {
-	case CHIP_ID_1251_PG12:
-		wl12xx_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
-			     wl->chip.id);
-
-		wl1251_setup(wl);
-
-		break;
-	case CHIP_ID_1271_PG10:
-	case CHIP_ID_1251_PG10:
-	case CHIP_ID_1251_PG11:
-	default:
-		wl12xx_error("unsupported chip id: 0x%x", wl->chip.id);
-		ret = -ENODEV;
-		goto out;
-	}
-
-	if (wl->fw == NULL) {
-		ret = wl12xx_fetch_firmware(wl);
-		if (ret < 0)
-			goto out;
-	}
-
-	/* No NVS from netlink, try to get it from the filesystem */
-	if (wl->nvs == NULL) {
-		ret = wl12xx_fetch_nvs(wl);
-		if (ret < 0)
-			goto out;
-	}
-
-out:
-	return ret;
-}
-
-static void wl12xx_filter_work(struct work_struct *work)
-{
-	struct wl12xx *wl =
-		container_of(work, struct wl12xx, filter_work);
-	int ret;
-
-	mutex_lock(&wl->mutex);
-
-	if (wl->state == WL12XX_STATE_OFF)
-		goto out;
-
-	ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
-	if (ret < 0)
-		goto out;
-
-out:
-	mutex_unlock(&wl->mutex);
-}
-
-int wl12xx_plt_start(struct wl12xx *wl)
-{
-	int ret;
-
-	wl12xx_notice("power up");
-
-	if (wl->state != WL12XX_STATE_OFF) {
-		wl12xx_error("cannot go into PLT state because not "
-			     "in off state: %d", wl->state);
-		return -EBUSY;
-	}
-
-	wl->state = WL12XX_STATE_PLT;
-
-	ret = wl12xx_chip_wakeup(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl->chip.op_boot(wl);
-	if (ret < 0)
-		return ret;
-
-	wl12xx_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
-
-	ret = wl->chip.op_plt_init(wl);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-int wl12xx_plt_stop(struct wl12xx *wl)
-{
-	wl12xx_notice("power down");
-
-	if (wl->state != WL12XX_STATE_PLT) {
-		wl12xx_error("cannot power down because not in PLT "
-			     "state: %d", wl->state);
-		return -EBUSY;
-	}
-
-	wl12xx_disable_interrupts(wl);
-	wl12xx_power_off(wl);
-
-	wl->state = WL12XX_STATE_OFF;
-
-	return 0;
-}
-
-
-static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-	struct wl12xx *wl = hw->priv;
-
-	skb_queue_tail(&wl->tx_queue, skb);
-
-	schedule_work(&wl->tx_work);
-
-	/*
-	 * The workqueue is slow to process the tx_queue and we need stop
-	 * the queue here, otherwise the queue will get too long.
-	 */
-	if (skb_queue_len(&wl->tx_queue) >= WL12XX_TX_QUEUE_MAX_LENGTH) {
-		ieee80211_stop_queues(wl->hw);
-
-		/*
-		 * FIXME: this is racy, the variable is not properly
-		 * protected. Maybe fix this by removing the stupid
-		 * variable altogether and checking the real queue state?
-		 */
-		wl->tx_queue_stopped = true;
-	}
-
-	return NETDEV_TX_OK;
-}
-
-static int wl12xx_op_start(struct ieee80211_hw *hw)
-{
-	struct wl12xx *wl = hw->priv;
-	int ret = 0;
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 start");
-
-	mutex_lock(&wl->mutex);
-
-	if (wl->state != WL12XX_STATE_OFF) {
-		wl12xx_error("cannot start because not in off state: %d",
-			     wl->state);
-		ret = -EBUSY;
-		goto out;
-	}
-
-	ret = wl12xx_chip_wakeup(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl->chip.op_boot(wl);
-	if (ret < 0)
-		goto out;
-
-	ret = wl->chip.op_hw_init(wl);
-	if (ret < 0)
-		goto out;
-
-	ret = wl12xx_acx_station_id(wl);
-	if (ret < 0)
-		goto out;
-
-	wl->state = WL12XX_STATE_ON;
-
-	wl12xx_info("firmware booted (%s)", wl->chip.fw_ver);
-
-out:
-	if (ret < 0)
-		wl12xx_power_off(wl);
-
-	mutex_unlock(&wl->mutex);
-
-	return ret;
-}
-
-static void wl12xx_op_stop(struct ieee80211_hw *hw)
-{
-	struct wl12xx *wl = hw->priv;
-
-	wl12xx_info("down");
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 stop");
-
-	mutex_lock(&wl->mutex);
-
-	WARN_ON(wl->state != WL12XX_STATE_ON);
-
-	if (wl->scanning) {
-		mutex_unlock(&wl->mutex);
-		ieee80211_scan_completed(wl->hw, true);
-		mutex_lock(&wl->mutex);
-		wl->scanning = false;
-	}
-
-	wl->state = WL12XX_STATE_OFF;
-
-	wl12xx_disable_interrupts(wl);
-
-	mutex_unlock(&wl->mutex);
-
-	cancel_work_sync(&wl->irq_work);
-	cancel_work_sync(&wl->tx_work);
-	cancel_work_sync(&wl->filter_work);
-
-	mutex_lock(&wl->mutex);
-
-	/* let's notify MAC80211 about the remaining pending TX frames */
-	wl12xx_tx_flush(wl);
-
-	wl12xx_power_off(wl);
-
-	memset(wl->bssid, 0, ETH_ALEN);
-	wl->listen_int = 1;
-	wl->bss_type = MAX_BSS_TYPE;
-
-	wl->data_in_count = 0;
-	wl->rx_counter = 0;
-	wl->rx_handled = 0;
-	wl->rx_current_buffer = 0;
-	wl->rx_last_id = 0;
-	wl->next_tx_complete = 0;
-	wl->elp = false;
-	wl->psm = 0;
-	wl->tx_queue_stopped = false;
-	wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
-
-	wl12xx_debugfs_reset(wl);
-
-	mutex_unlock(&wl->mutex);
-}
-
-static int wl12xx_op_add_interface(struct ieee80211_hw *hw,
-				   struct ieee80211_if_init_conf *conf)
-{
-	struct wl12xx *wl = hw->priv;
-	DECLARE_MAC_BUF(mac);
-	int ret = 0;
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s",
-		     conf->type, print_mac(mac, conf->mac_addr));
-
-	mutex_lock(&wl->mutex);
-
-	switch (conf->type) {
-	case NL80211_IFTYPE_STATION:
-		wl->bss_type = BSS_TYPE_STA_BSS;
-		break;
-	case NL80211_IFTYPE_ADHOC:
-		wl->bss_type = BSS_TYPE_IBSS;
-		break;
-	default:
-		ret = -EOPNOTSUPP;
-		goto out;
-	}
-
-	if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
-		memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
-		SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
-		ret = wl12xx_acx_station_id(wl);
-		if (ret < 0)
-			goto out;
-	}
-
-out:
-	mutex_unlock(&wl->mutex);
-	return ret;
-}
-
-static void wl12xx_op_remove_interface(struct ieee80211_hw *hw,
-					 struct ieee80211_if_init_conf *conf)
-{
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 remove interface");
-}
-
-static int wl12xx_build_null_data(struct wl12xx *wl)
-{
-	struct wl12xx_null_data_template template;
-
-	if (!is_zero_ether_addr(wl->bssid)) {
-		memcpy(template.header.da, wl->bssid, ETH_ALEN);
-		memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
-	} else {
-		memset(template.header.da, 0xff, ETH_ALEN);
-		memset(template.header.bssid, 0xff, ETH_ALEN);
-	}
-
-	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
-	template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
-						IEEE80211_STYPE_NULLFUNC);
-
-	return wl12xx_cmd_template_set(wl, CMD_NULL_DATA, &template,
-				       sizeof(template));
-
-}
-
-static int wl12xx_build_ps_poll(struct wl12xx *wl, u16 aid)
-{
-	struct wl12xx_ps_poll_template template;
-
-	memcpy(template.bssid, wl->bssid, ETH_ALEN);
-	memcpy(template.ta, wl->mac_addr, ETH_ALEN);
-	template.aid = aid;
-	template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
-
-	return wl12xx_cmd_template_set(wl, CMD_PS_POLL, &template,
-				       sizeof(template));
-
-}
-
-static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed)
-{
-	struct wl12xx *wl = hw->priv;
-	struct ieee80211_conf *conf = &hw->conf;
-	int channel, ret = 0;
-
-	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
-		     channel,
-		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
-		     conf->power_level);
-
-	mutex_lock(&wl->mutex);
-
-	if (channel != wl->channel) {
-		/* FIXME: use beacon interval provided by mac80211 */
-		ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
-		if (ret < 0)
-			goto out;
-
-		wl->channel = channel;
-	}
-
-	ret = wl12xx_build_null_data(wl);
-	if (ret < 0)
-		goto out;
-
-	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
-		wl12xx_info("psm enabled");
-
-		wl->psm_requested = true;
-
-		/*
-		 * We enter PSM only if we're already associated.
-		 * If we're not, we'll enter it when joining an SSID,
-		 * through the bss_info_changed() hook.
-		 */
-		ret = wl12xx_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
-	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
-		   wl->psm_requested) {
-		wl12xx_info("psm disabled");
-
-		wl->psm_requested = false;
-
-		if (wl->psm)
-			ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
-	}
-
-	if (conf->power_level != wl->power_level) {
-		ret = wl12xx_acx_tx_power(wl, conf->power_level);
-		if (ret < 0)
-			goto out;
-
-		wl->power_level = conf->power_level;
-	}
-
-out:
-	mutex_unlock(&wl->mutex);
-	return ret;
-}
-
-#define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
-				  FIF_ALLMULTI | \
-				  FIF_FCSFAIL | \
-				  FIF_BCN_PRBRESP_PROMISC | \
-				  FIF_CONTROL | \
-				  FIF_OTHER_BSS)
-
-static void wl12xx_op_configure_filter(struct ieee80211_hw *hw,
-				       unsigned int changed,
-				       unsigned int *total,
-				       int mc_count,
-				       struct dev_addr_list *mc_list)
-{
-	struct wl12xx *wl = hw->priv;
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 configure filter");
-
-	*total &= WL12XX_SUPPORTED_FILTERS;
-	changed &= WL12XX_SUPPORTED_FILTERS;
-
-	if (changed == 0)
-		/* no filters which we support changed */
-		return;
-
-	/* FIXME: wl->rx_config and wl->rx_filter are not protected */
-
-	wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
-	wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
-
-	if (*total & FIF_PROMISC_IN_BSS) {
-		wl->rx_config |= CFG_BSSID_FILTER_EN;
-		wl->rx_config |= CFG_RX_ALL_GOOD;
-	}
-	if (*total & FIF_ALLMULTI)
-		/*
-		 * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
-		 * all multicast frames
-		 */
-		wl->rx_config &= ~CFG_MC_FILTER_EN;
-	if (*total & FIF_FCSFAIL)
-		wl->rx_filter |= CFG_RX_FCS_ERROR;
-	if (*total & FIF_BCN_PRBRESP_PROMISC) {
-		wl->rx_config &= ~CFG_BSSID_FILTER_EN;
-		wl->rx_config &= ~CFG_SSID_FILTER_EN;
-	}
-	if (*total & FIF_CONTROL)
-		wl->rx_filter |= CFG_RX_CTL_EN;
-	if (*total & FIF_OTHER_BSS)
-		wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
-
-	/*
-	 * FIXME: workqueues need to be properly cancelled on stop(), for
-	 * now let's just disable changing the filter settings. They will
-	 * be updated any on config().
-	 */
-	/* schedule_work(&wl->filter_work); */
-}
-
-/* HW encryption */
-static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key,
-			       enum set_key_cmd cmd,
-			       struct ieee80211_key_conf *mac80211_key,
-			       const u8 *addr)
-{
-	switch (mac80211_key->alg) {
-	case ALG_WEP:
-		if (is_broadcast_ether_addr(addr))
-			key->key_type = KEY_WEP_DEFAULT;
-		else
-			key->key_type = KEY_WEP_ADDR;
-
-		mac80211_key->hw_key_idx = mac80211_key->keyidx;
-		break;
-	case ALG_TKIP:
-		if (is_broadcast_ether_addr(addr))
-			key->key_type = KEY_TKIP_MIC_GROUP;
-		else
-			key->key_type = KEY_TKIP_MIC_PAIRWISE;
-
-		mac80211_key->hw_key_idx = mac80211_key->keyidx;
-		break;
-	case ALG_CCMP:
-		if (is_broadcast_ether_addr(addr))
-			key->key_type = KEY_AES_GROUP;
-		else
-			key->key_type = KEY_AES_PAIRWISE;
-		mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-		break;
-	default:
-		wl12xx_error("Unknown key algo 0x%x", mac80211_key->alg);
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-			     struct ieee80211_vif *vif,
-			     struct ieee80211_sta *sta,
-			     struct ieee80211_key_conf *key)
-{
-	struct wl12xx *wl = hw->priv;
-	struct acx_set_key wl_key;
-	const u8 *addr;
-	int ret;
-
-	static const u8 bcast_addr[ETH_ALEN] =
-		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 set key");
-
-	memset(&wl_key, 0, sizeof(wl_key));
-
-	addr = sta ? sta->addr : bcast_addr;
-
-	wl12xx_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
-	wl12xx_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
-	wl12xx_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
-		     key->alg, key->keyidx, key->keylen, key->flags);
-	wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
-
-	mutex_lock(&wl->mutex);
-
-	switch (cmd) {
-	case SET_KEY:
-		wl_key.key_action = KEY_ADD_OR_REPLACE;
-		break;
-	case DISABLE_KEY:
-		wl_key.key_action = KEY_REMOVE;
-		break;
-	default:
-		wl12xx_error("Unsupported key cmd 0x%x", cmd);
-		break;
-	}
-
-	ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr);
-	if (ret < 0) {
-		wl12xx_error("Set KEY type failed");
-		goto out;
-	}
-
-	if (wl_key.key_type != KEY_WEP_DEFAULT)
-		memcpy(wl_key.addr, addr, ETH_ALEN);
-
-	if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) ||
-	    (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) {
-		/*
-		 * We get the key in the following form:
-		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
-		 * but the target is expecting:
-		 * TKIP - RX MIC - TX MIC
-		 */
-		memcpy(wl_key.key, key->key, 16);
-		memcpy(wl_key.key + 16, key->key + 24, 8);
-		memcpy(wl_key.key + 24, key->key + 16, 8);
-
-	} else {
-		memcpy(wl_key.key, key->key, key->keylen);
-	}
-	wl_key.key_size = key->keylen;
-
-	wl_key.id = key->keyidx;
-	wl_key.ssid_profile = 0;
-
-	wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key));
-
-	if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) {
-		wl12xx_error("Set KEY failed");
-		ret = -EOPNOTSUPP;
-		goto out;
-	}
-
-out:
-	mutex_unlock(&wl->mutex);
-	return ret;
-}
-
-static int wl12xx_build_basic_rates(char *rates)
-{
-	u8 index = 0;
-
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
-	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-
-	return index;
-}
-
-static int wl12xx_build_extended_rates(char *rates)
-{
-	u8 index = 0;
-
-	rates[index++] = IEEE80211_OFDM_RATE_6MB;
-	rates[index++] = IEEE80211_OFDM_RATE_9MB;
-	rates[index++] = IEEE80211_OFDM_RATE_12MB;
-	rates[index++] = IEEE80211_OFDM_RATE_18MB;
-	rates[index++] = IEEE80211_OFDM_RATE_24MB;
-	rates[index++] = IEEE80211_OFDM_RATE_36MB;
-	rates[index++] = IEEE80211_OFDM_RATE_48MB;
-	rates[index++] = IEEE80211_OFDM_RATE_54MB;
-
-	return index;
-}
-
-
-static int wl12xx_build_probe_req(struct wl12xx *wl, u8 *ssid, size_t ssid_len)
-{
-	struct wl12xx_probe_req_template template;
-	struct wl12xx_ie_rates *rates;
-	char *ptr;
-	u16 size;
-
-	ptr = (char *)&template;
-	size = sizeof(struct ieee80211_header);
-
-	memset(template.header.da, 0xff, ETH_ALEN);
-	memset(template.header.bssid, 0xff, ETH_ALEN);
-	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
-	template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-
-	/* IEs */
-	/* SSID */
-	template.ssid.header.id = WLAN_EID_SSID;
-	template.ssid.header.len = ssid_len;
-	if (ssid_len && ssid)
-		memcpy(template.ssid.ssid, ssid, ssid_len);
-	size += sizeof(struct wl12xx_ie_header) + ssid_len;
-	ptr += size;
-
-	/* Basic Rates */
-	rates = (struct wl12xx_ie_rates *)ptr;
-	rates->header.id = WLAN_EID_SUPP_RATES;
-	rates->header.len = wl12xx_build_basic_rates(rates->rates);
-	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
-	ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
-
-	/* Extended rates */
-	rates = (struct wl12xx_ie_rates *)ptr;
-	rates->header.id = WLAN_EID_EXT_SUPP_RATES;
-	rates->header.len = wl12xx_build_extended_rates(rates->rates);
-	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
-
-	wl12xx_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
-
-	return wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, &template,
-				      size);
-}
-
-static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
-			  u8 active_scan, u8 high_prio, u8 num_channels,
-			  u8 probe_requests)
-{
-	int i, ret;
-	u32 split_scan = 0;
-	u16 scan_options = 0;
-	struct cmd_scan *params;
-	struct wl12xx_command *cmd_answer;
-
-	if (wl->scanning)
-		return -EINVAL;
-
-	params = kzalloc(sizeof(*params), GFP_KERNEL);
-	if (!params)
-		return -ENOMEM;
-
-	params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
-	params->params.rx_filter_options =
-		cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
-
-	/* High priority scan */
-	if (!active_scan)
-		scan_options |= SCAN_PASSIVE;
-	if (high_prio)
-		scan_options |= SCAN_PRIORITY_HIGH;
-	params->params.scan_options = scan_options;
-
-	params->params.num_channels = num_channels;
-	params->params.num_probe_requests = probe_requests;
-	params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
-	params->params.tid_trigger = 0;
-
-	for (i = 0; i < num_channels; i++) {
-		params->channels[i].min_duration = cpu_to_le32(30000);
-		params->channels[i].max_duration = cpu_to_le32(60000);
-		memset(&params->channels[i].bssid_lsb, 0xff, 4);
-		memset(&params->channels[i].bssid_msb, 0xff, 2);
-		params->channels[i].early_termination = 0;
-		params->channels[i].tx_power_att = 0;
-		params->channels[i].channel = i + 1;
-		memset(params->channels[i].pad, 0, 3);
-	}
-
-	for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
-		memset(&params->channels[i], 0,
-		       sizeof(struct basic_scan_channel_parameters));
-
-	if (len && ssid) {
-		params->params.ssid_len = len;
-		memcpy(params->params.ssid, ssid, len);
-	} else {
-		params->params.ssid_len = 0;
-		memset(params->params.ssid, 0, 32);
-	}
-
-	ret = wl12xx_build_probe_req(wl, ssid, len);
-	if (ret < 0) {
-		wl12xx_error("PROBE request template failed");
-		goto out;
-	}
-
-	ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan,
-			      sizeof(u32));
-	if (ret < 0) {
-		wl12xx_error("Split SCAN failed");
-		goto out;
-	}
-
-	wl12xx_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
-
-	wl->scanning = true;
-
-	ret = wl12xx_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
-	if (ret < 0)
-		wl12xx_error("SCAN failed");
-
-	wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
-
-	cmd_answer = (struct wl12xx_command *) params;
-	if (cmd_answer->status != CMD_STATUS_SUCCESS) {
-		wl12xx_error("TEST command answer error: %d",
-			     cmd_answer->status);
-		wl->scanning = false;
-		ret = -EIO;
-		goto out;
-	}
-
-out:
-	kfree(params);
-	return ret;
-
-}
-
-static int wl12xx_op_hw_scan(struct ieee80211_hw *hw,
-			     struct cfg80211_scan_request *req)
-{
-	struct wl12xx *wl = hw->priv;
-	int ret;
-	u8 *ssid = NULL;
-	size_t ssid_len = 0;
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 hw scan");
-
-	if (req->n_ssids) {
-		ssid = req->ssids[0].ssid;
-		ssid_len = req->ssids[0].ssid_len;
-	}
-
-	mutex_lock(&wl->mutex);
-	ret = wl12xx_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
-	mutex_unlock(&wl->mutex);
-
-	return ret;
-}
-
-static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
-{
-	struct wl12xx *wl = hw->priv;
-	int ret;
-
-	ret = wl12xx_acx_rts_threshold(wl, (u16) value);
-
-	if (ret < 0)
-		wl12xx_warning("wl12xx_op_set_rts_threshold failed: %d", ret);
-
-	return ret;
-}
-
-static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw,
-				       struct ieee80211_vif *vif,
-				       struct ieee80211_bss_conf *bss_conf,
-				       u32 changed)
-{
-	enum acx_ps_mode mode;
-	struct wl12xx *wl = hw->priv;
-	struct sk_buff *beacon;
-	int ret;
-
-	wl12xx_debug(DEBUG_MAC80211, "mac80211 bss info changed");
-
-	mutex_lock(&wl->mutex);
-
-	if (changed & BSS_CHANGED_ASSOC) {
-		if (bss_conf->assoc) {
-			wl->aid = bss_conf->aid;
-
-			ret = wl12xx_build_ps_poll(wl, wl->aid);
-			if (ret < 0)
-				goto out;
-
-			ret = wl12xx_acx_aid(wl, wl->aid);
-			if (ret < 0)
-				goto out;
-
-			/* If we want to go in PSM but we're not there yet */
-			if (wl->psm_requested && !wl->psm) {
-				mode = STATION_POWER_SAVE_MODE;
-				ret = wl12xx_ps_set_mode(wl, mode);
-				if (ret < 0)
-					goto out;
-			}
-		}
-	}
-	if (changed & BSS_CHANGED_ERP_SLOT) {
-		if (bss_conf->use_short_slot)
-			ret = wl12xx_acx_slot(wl, SLOT_TIME_SHORT);
-		else
-			ret = wl12xx_acx_slot(wl, SLOT_TIME_LONG);
-		if (ret < 0) {
-			wl12xx_warning("Set slot time failed %d", ret);
-			goto out;
-		}
-	}
-
-	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-		if (bss_conf->use_short_preamble)
-			wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
-		else
-			wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
-	}
-
-	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-		if (bss_conf->use_cts_prot)
-			ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_ENABLE);
-		else
-			ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_DISABLE);
-		if (ret < 0) {
-			wl12xx_warning("Set ctsprotect failed %d", ret);
-			goto out;
-		}
-	}
-
-	if (changed & BSS_CHANGED_BSSID) {
-		memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
-
-		ret = wl12xx_build_null_data(wl);
-		if (ret < 0)
-			goto out;
-
-		if (wl->bss_type != BSS_TYPE_IBSS) {
-			ret = wl12xx_cmd_join(wl, wl->bss_type, 5, 100, 1);
-			if (ret < 0)
-				goto out;
-		}
-	}
-
-	if (changed & BSS_CHANGED_BEACON) {
-		beacon = ieee80211_beacon_get(hw, vif);
-		ret = wl12xx_cmd_template_set(wl, CMD_BEACON, beacon->data,
-					      beacon->len);
-
-		if (ret < 0) {
-			dev_kfree_skb(beacon);
-			goto out;
-		}
-
-		ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
-					      beacon->len);
-
-		dev_kfree_skb(beacon);
-
-		if (ret < 0)
-			goto out;
-
-		ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
-
-		if (ret < 0)
-			goto out;
-	}
-
-out:
-	mutex_unlock(&wl->mutex);
-}
-
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_rate wl12xx_rates[] = {
-	{ .bitrate = 10,
-	  .hw_value = 0x1,
-	  .hw_value_short = 0x1, },
-	{ .bitrate = 20,
-	  .hw_value = 0x2,
-	  .hw_value_short = 0x2,
-	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-	{ .bitrate = 55,
-	  .hw_value = 0x4,
-	  .hw_value_short = 0x4,
-	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-	{ .bitrate = 110,
-	  .hw_value = 0x20,
-	  .hw_value_short = 0x20,
-	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-	{ .bitrate = 60,
-	  .hw_value = 0x8,
-	  .hw_value_short = 0x8, },
-	{ .bitrate = 90,
-	  .hw_value = 0x10,
-	  .hw_value_short = 0x10, },
-	{ .bitrate = 120,
-	  .hw_value = 0x40,
-	  .hw_value_short = 0x40, },
-	{ .bitrate = 180,
-	  .hw_value = 0x80,
-	  .hw_value_short = 0x80, },
-	{ .bitrate = 240,
-	  .hw_value = 0x200,
-	  .hw_value_short = 0x200, },
-	{ .bitrate = 360,
-	 .hw_value = 0x400,
-	 .hw_value_short = 0x400, },
-	{ .bitrate = 480,
-	  .hw_value = 0x800,
-	  .hw_value_short = 0x800, },
-	{ .bitrate = 540,
-	  .hw_value = 0x1000,
-	  .hw_value_short = 0x1000, },
-};
-
-/* can't be const, mac80211 writes to this */
-static struct ieee80211_channel wl12xx_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 wl12xx_band_2ghz = {
-	.channels = wl12xx_channels,
-	.n_channels = ARRAY_SIZE(wl12xx_channels),
-	.bitrates = wl12xx_rates,
-	.n_bitrates = ARRAY_SIZE(wl12xx_rates),
-};
-
-static const struct ieee80211_ops wl12xx_ops = {
-	.start = wl12xx_op_start,
-	.stop = wl12xx_op_stop,
-	.add_interface = wl12xx_op_add_interface,
-	.remove_interface = wl12xx_op_remove_interface,
-	.config = wl12xx_op_config,
-	.configure_filter = wl12xx_op_configure_filter,
-	.tx = wl12xx_op_tx,
-	.set_key = wl12xx_op_set_key,
-	.hw_scan = wl12xx_op_hw_scan,
-	.bss_info_changed = wl12xx_op_bss_info_changed,
-	.set_rts_threshold = wl12xx_op_set_rts_threshold,
-};
-
-static int wl12xx_register_hw(struct wl12xx *wl)
-{
-	int ret;
-
-	if (wl->mac80211_registered)
-		return 0;
-
-	SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
-
-	ret = ieee80211_register_hw(wl->hw);
-	if (ret < 0) {
-		wl12xx_error("unable to register mac80211 hw: %d", ret);
-		return ret;
-	}
-
-	wl->mac80211_registered = true;
-
-	wl12xx_notice("loaded");
-
-	return 0;
-}
-
-static int wl12xx_init_ieee80211(struct wl12xx *wl)
-{
-	/* The tx descriptor buffer and the TKIP space */
-	wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
-		+ WL12XX_TKIP_IV_SPACE;
-
-	/* unit us */
-	/* FIXME: find a proper value */
-	wl->hw->channel_change_time = 10000;
-
-	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
-		IEEE80211_HW_NOISE_DBM;
-
-	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-	wl->hw->wiphy->max_scan_ssids = 1;
-	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl12xx_band_2ghz;
-
-	SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
-
-	return 0;
-}
-
-#define WL12XX_DEFAULT_CHANNEL 1
-static int __devinit wl12xx_probe(struct spi_device *spi)
-{
-	struct wl12xx_platform_data *pdata;
-	struct ieee80211_hw *hw;
-	struct wl12xx *wl;
-	int ret, i;
-	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
-
-	pdata = spi->dev.platform_data;
-	if (!pdata) {
-		wl12xx_error("no platform data");
-		return -ENODEV;
-	}
-
-	hw = ieee80211_alloc_hw(sizeof(*wl), &wl12xx_ops);
-	if (!hw) {
-		wl12xx_error("could not alloc ieee80211_hw");
-		return -ENOMEM;
-	}
-
-	wl = hw->priv;
-	memset(wl, 0, sizeof(*wl));
-
-	wl->hw = hw;
-	dev_set_drvdata(&spi->dev, wl);
-	wl->spi = spi;
-
-	wl->data_in_count = 0;
-
-	skb_queue_head_init(&wl->tx_queue);
-
-	INIT_WORK(&wl->tx_work, wl12xx_tx_work);
-	INIT_WORK(&wl->filter_work, wl12xx_filter_work);
-	wl->channel = WL12XX_DEFAULT_CHANNEL;
-	wl->scanning = false;
-	wl->default_key = 0;
-	wl->listen_int = 1;
-	wl->rx_counter = 0;
-	wl->rx_handled = 0;
-	wl->rx_current_buffer = 0;
-	wl->rx_last_id = 0;
-	wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
-	wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
-	wl->elp = false;
-	wl->psm = 0;
-	wl->psm_requested = false;
-	wl->tx_queue_stopped = false;
-	wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
-
-	/* We use the default power on sleep time until we know which chip
-	 * we're using */
-	wl->chip.power_on_sleep = WL12XX_DEFAULT_POWER_ON_SLEEP;
-
-	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
-		wl->tx_frames[i] = NULL;
-
-	wl->next_tx_complete = 0;
-
-	/*
-	 * In case our MAC address is not correctly set,
-	 * we use a random but Nokia MAC.
-	 */
-	memcpy(wl->mac_addr, nokia_oui, 3);
-	get_random_bytes(wl->mac_addr + 3, 3);
-
-	wl->state = WL12XX_STATE_OFF;
-	mutex_init(&wl->mutex);
-
-	wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
-	wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
-
-	/* This is the only SPI value that we need to set here, the rest
-	 * comes from the board-peripherals file */
-	spi->bits_per_word = 32;
-
-	ret = spi_setup(spi);
-	if (ret < 0) {
-		wl12xx_error("spi_setup failed");
-		goto out_free;
-	}
-
-	wl->set_power = pdata->set_power;
-	if (!wl->set_power) {
-		wl12xx_error("set power function missing in platform data");
-		return -ENODEV;
-	}
-
-	wl->irq = spi->irq;
-	if (wl->irq < 0) {
-		wl12xx_error("irq missing in platform data");
-		return -ENODEV;
-	}
-
-	ret = request_irq(wl->irq, wl12xx_irq, 0, DRIVER_NAME, wl);
-	if (ret < 0) {
-		wl12xx_error("request_irq() failed: %d", ret);
-		goto out_free;
-	}
-
-	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-
-	disable_irq(wl->irq);
-
-	ret = wl12xx_init_ieee80211(wl);
-	if (ret)
-		goto out_irq;
-
-	ret = wl12xx_register_hw(wl);
-	if (ret)
-		goto out_irq;
-
-	wl12xx_debugfs_init(wl);
-
-	wl12xx_notice("initialized");
-
-	return 0;
-
- out_irq:
-	free_irq(wl->irq, wl);
-
- out_free:
-	ieee80211_free_hw(hw);
-
-	return ret;
-}
-
-static int __devexit wl12xx_remove(struct spi_device *spi)
-{
-	struct wl12xx *wl = dev_get_drvdata(&spi->dev);
-
-	ieee80211_unregister_hw(wl->hw);
-
-	wl12xx_debugfs_exit(wl);
-
-	free_irq(wl->irq, wl);
-	kfree(wl->target_mem_map);
-	kfree(wl->data_path);
-	kfree(wl->fw);
-	wl->fw = NULL;
-	kfree(wl->nvs);
-	wl->nvs = NULL;
-	ieee80211_free_hw(wl->hw);
-
-	return 0;
-}
-
-
-static struct spi_driver wl12xx_spi_driver = {
-	.driver = {
-		.name		= "wl12xx",
-		.bus		= &spi_bus_type,
-		.owner		= THIS_MODULE,
-	},
-
-	.probe		= wl12xx_probe,
-	.remove		= __devexit_p(wl12xx_remove),
-};
-
-static int __init wl12xx_init(void)
-{
-	int ret;
-
-	ret = spi_register_driver(&wl12xx_spi_driver);
-	if (ret < 0) {
-		wl12xx_error("failed to register spi driver: %d", ret);
-		goto out;
-	}
-
-out:
-	return ret;
-}
-
-static void __exit wl12xx_exit(void)
-{
-	spi_unregister_driver(&wl12xx_spi_driver);
-
-	wl12xx_notice("unloaded");
-}
-
-module_init(wl12xx_init);
-module_exit(wl12xx_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
-		"Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
deleted file mode 100644
index 83a1011..0000000
--- a/drivers/net/wireless/wl12xx/ps.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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 "reg.h"
-#include "ps.h"
-#include "spi.h"
-
-#define WL12XX_WAKEUP_TIMEOUT 2000
-
-/* Routines to toggle sleep mode while in ELP */
-void wl12xx_ps_elp_sleep(struct wl12xx *wl)
-{
-	if (wl->elp || !wl->psm)
-		return;
-
-	wl12xx_debug(DEBUG_PSM, "chip to elp");
-
-	wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
-
-	wl->elp = true;
-}
-
-int wl12xx_ps_elp_wakeup(struct wl12xx *wl)
-{
-	unsigned long timeout;
-	u32 elp_reg;
-
-	if (!wl->elp)
-		return 0;
-
-	wl12xx_debug(DEBUG_PSM, "waking up chip from elp");
-
-	timeout = jiffies + msecs_to_jiffies(WL12XX_WAKEUP_TIMEOUT);
-
-	wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
-
-	elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-
-	/*
-	 * FIXME: we should wait for irq from chip but, as a temporary
-	 * solution to simplify locking, let's poll instead
-	 */
-	while (!(elp_reg & ELPCTRL_WLAN_READY)) {
-		if (time_after(jiffies, timeout)) {
-			wl12xx_error("elp wakeup timeout");
-			return -ETIMEDOUT;
-		}
-		msleep(1);
-		elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
-	}
-
-	wl12xx_debug(DEBUG_PSM, "wakeup time: %u ms",
-		     jiffies_to_msecs(jiffies) -
-		     (jiffies_to_msecs(timeout) - WL12XX_WAKEUP_TIMEOUT));
-
-	wl->elp = false;
-
-	return 0;
-}
-
-static int wl12xx_ps_set_elp(struct wl12xx *wl, bool enable)
-{
-	int ret;
-
-	if (enable) {
-		wl12xx_debug(DEBUG_PSM, "sleep auth psm/elp");
-
-		/*
-		 * FIXME: we should PSM_ELP, but because of firmware wakeup
-		 * problems let's use only PSM_PS
-		 */
-		ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_PS);
-		if (ret < 0)
-			return ret;
-
-		wl12xx_ps_elp_sleep(wl);
-	} else {
-		wl12xx_debug(DEBUG_PSM, "sleep auth cam");
-
-		/*
-		 * When the target is in ELP, we can only
-		 * access the ELP control register. Thus,
-		 * we have to wake the target up before
-		 * changing the power authorization.
-		 */
-
-		wl12xx_ps_elp_wakeup(wl);
-
-		ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
-		if (ret < 0)
-			return ret;
-	}
-
-	return 0;
-}
-
-int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode)
-{
-	int ret;
-
-	switch (mode) {
-	case STATION_POWER_SAVE_MODE:
-		wl12xx_debug(DEBUG_PSM, "entering psm");
-		ret = wl12xx_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
-		if (ret < 0)
-			return ret;
-
-		ret = wl12xx_ps_set_elp(wl, true);
-		if (ret < 0)
-			return ret;
-
-		wl->psm = 1;
-		break;
-	case STATION_ACTIVE_MODE:
-	default:
-		wl12xx_debug(DEBUG_PSM, "leaving psm");
-		ret = wl12xx_ps_set_elp(wl, false);
-		if (ret < 0)
-			return ret;
-
-		ret = wl12xx_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
-		if (ret < 0)
-			return ret;
-
-		wl->psm = 0;
-		break;
-	}
-
-	return ret;
-}
-
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
deleted file mode 100644
index 5d7c525..0000000
--- a/drivers/net/wireless/wl12xx/ps.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __WL12XX_PS_H__
-#define __WL12XX_PS_H__
-
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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 "wl12xx.h"
-#include "acx.h"
-
-int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode);
-void wl12xx_ps_elp_sleep(struct wl12xx *wl);
-int wl12xx_ps_elp_wakeup(struct wl12xx *wl);
-
-
-#endif /* __WL12XX_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h
deleted file mode 100644
index e421643..0000000
--- a/drivers/net/wireless/wl12xx/reg.h
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __REG_H__
-#define __REG_H__
-
-#include <linux/bitops.h>
-#include "wl12xx.h"
-
-#define REGISTERS_BASE 0x00300000
-#define DRPW_BASE      0x00310000
-
-#define REGISTERS_DOWN_SIZE 0x00008800
-#define REGISTERS_WORK_SIZE 0x0000b000
-
-#define HW_ACCESS_ELP_CTRL_REG_ADDR         0x1FFFC
-
-/* ELP register commands */
-#define ELPCTRL_WAKE_UP             0x1
-#define ELPCTRL_WAKE_UP_WLAN_READY  0x5
-#define ELPCTRL_SLEEP               0x0
-/* ELP WLAN_READY bit */
-#define ELPCTRL_WLAN_READY          0x2
-
-/*
- * Interrupt registers.
- * 64 bit interrupt sources registers ws ced.
- * sme interupts were removed and new ones were added.
- * Order was changed.
- */
-#define FIQ_MASK                       (REGISTERS_BASE + 0x0400)
-#define FIQ_MASK_L                     (REGISTERS_BASE + 0x0400)
-#define FIQ_MASK_H                     (REGISTERS_BASE + 0x0404)
-#define FIQ_MASK_SET                   (REGISTERS_BASE + 0x0408)
-#define FIQ_MASK_SET_L                 (REGISTERS_BASE + 0x0408)
-#define FIQ_MASK_SET_H                 (REGISTERS_BASE + 0x040C)
-#define FIQ_MASK_CLR                   (REGISTERS_BASE + 0x0410)
-#define FIQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0410)
-#define FIQ_MASK_CLR_H                 (REGISTERS_BASE + 0x0414)
-#define IRQ_MASK                       (REGISTERS_BASE + 0x0418)
-#define IRQ_MASK_L                     (REGISTERS_BASE + 0x0418)
-#define IRQ_MASK_H                     (REGISTERS_BASE + 0x041C)
-#define IRQ_MASK_SET                   (REGISTERS_BASE + 0x0420)
-#define IRQ_MASK_SET_L                 (REGISTERS_BASE + 0x0420)
-#define IRQ_MASK_SET_H                 (REGISTERS_BASE + 0x0424)
-#define IRQ_MASK_CLR                   (REGISTERS_BASE + 0x0428)
-#define IRQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0428)
-#define IRQ_MASK_CLR_H                 (REGISTERS_BASE + 0x042C)
-#define ECPU_MASK                      (REGISTERS_BASE + 0x0448)
-#define FIQ_STS_L                      (REGISTERS_BASE + 0x044C)
-#define FIQ_STS_H                      (REGISTERS_BASE + 0x0450)
-#define IRQ_STS_L                      (REGISTERS_BASE + 0x0454)
-#define IRQ_STS_H                      (REGISTERS_BASE + 0x0458)
-#define INT_STS_ND                     (REGISTERS_BASE + 0x0464)
-#define INT_STS_RAW_L                  (REGISTERS_BASE + 0x0464)
-#define INT_STS_RAW_H                  (REGISTERS_BASE + 0x0468)
-#define INT_STS_CLR                    (REGISTERS_BASE + 0x04B4)
-#define INT_STS_CLR_L                  (REGISTERS_BASE + 0x04B4)
-#define INT_STS_CLR_H                  (REGISTERS_BASE + 0x04B8)
-#define INT_ACK                        (REGISTERS_BASE + 0x046C)
-#define INT_ACK_L                      (REGISTERS_BASE + 0x046C)
-#define INT_ACK_H                      (REGISTERS_BASE + 0x0470)
-#define INT_TRIG                       (REGISTERS_BASE + 0x0474)
-#define INT_TRIG_L                     (REGISTERS_BASE + 0x0474)
-#define INT_TRIG_H                     (REGISTERS_BASE + 0x0478)
-#define HOST_STS_L                     (REGISTERS_BASE + 0x045C)
-#define HOST_STS_H                     (REGISTERS_BASE + 0x0460)
-#define HOST_MASK                      (REGISTERS_BASE + 0x0430)
-#define HOST_MASK_L                    (REGISTERS_BASE + 0x0430)
-#define HOST_MASK_H                    (REGISTERS_BASE + 0x0434)
-#define HOST_MASK_SET                  (REGISTERS_BASE + 0x0438)
-#define HOST_MASK_SET_L                (REGISTERS_BASE + 0x0438)
-#define HOST_MASK_SET_H                (REGISTERS_BASE + 0x043C)
-#define HOST_MASK_CLR                  (REGISTERS_BASE + 0x0440)
-#define HOST_MASK_CLR_L                (REGISTERS_BASE + 0x0440)
-#define HOST_MASK_CLR_H                (REGISTERS_BASE + 0x0444)
-
-/* Host Interrupts*/
-#define HINT_MASK                      (REGISTERS_BASE + 0x0494)
-#define HINT_MASK_SET                  (REGISTERS_BASE + 0x0498)
-#define HINT_MASK_CLR                  (REGISTERS_BASE + 0x049C)
-#define HINT_STS_ND_MASKED             (REGISTERS_BASE + 0x04A0)
-/*1150 spec calls this HINT_STS_RAW*/
-#define HINT_STS_ND		       (REGISTERS_BASE + 0x04B0)
-#define HINT_STS_CLR                   (REGISTERS_BASE + 0x04A4)
-#define HINT_ACK                       (REGISTERS_BASE + 0x04A8)
-#define HINT_TRIG                      (REGISTERS_BASE + 0x04AC)
-
-/* Device Configuration registers*/
-#define SOR_CFG                        (REGISTERS_BASE + 0x0800)
-#define ECPU_CTRL                      (REGISTERS_BASE + 0x0804)
-#define HI_CFG                         (REGISTERS_BASE + 0x0808)
-#define EE_START                       (REGISTERS_BASE + 0x080C)
-
-#define CHIP_ID_B                      (REGISTERS_BASE + 0x5674)
-
-#define CHIP_ID_1251_PG10	           (0x7010101)
-#define CHIP_ID_1251_PG11	           (0x7020101)
-#define CHIP_ID_1251_PG12	           (0x7030101)
-
-#define ENABLE                         (REGISTERS_BASE + 0x5450)
-
-/* Power Management registers */
-#define ELP_CFG_MODE                   (REGISTERS_BASE + 0x5804)
-#define ELP_CMD                        (REGISTERS_BASE + 0x5808)
-#define PLL_CAL_TIME                   (REGISTERS_BASE + 0x5810)
-#define CLK_REQ_TIME                   (REGISTERS_BASE + 0x5814)
-#define CLK_BUF_TIME                   (REGISTERS_BASE + 0x5818)
-
-#define CFG_PLL_SYNC_CNT               (REGISTERS_BASE + 0x5820)
-
-/* Scratch Pad registers*/
-#define SCR_PAD0                       (REGISTERS_BASE + 0x5608)
-#define SCR_PAD1                       (REGISTERS_BASE + 0x560C)
-#define SCR_PAD2                       (REGISTERS_BASE + 0x5610)
-#define SCR_PAD3                       (REGISTERS_BASE + 0x5614)
-#define SCR_PAD4                       (REGISTERS_BASE + 0x5618)
-#define SCR_PAD4_SET                   (REGISTERS_BASE + 0x561C)
-#define SCR_PAD4_CLR                   (REGISTERS_BASE + 0x5620)
-#define SCR_PAD5                       (REGISTERS_BASE + 0x5624)
-#define SCR_PAD5_SET                   (REGISTERS_BASE + 0x5628)
-#define SCR_PAD5_CLR                   (REGISTERS_BASE + 0x562C)
-#define SCR_PAD6                       (REGISTERS_BASE + 0x5630)
-#define SCR_PAD7                       (REGISTERS_BASE + 0x5634)
-#define SCR_PAD8                       (REGISTERS_BASE + 0x5638)
-#define SCR_PAD9                       (REGISTERS_BASE + 0x563C)
-
-/* Spare registers*/
-#define SPARE_A1                       (REGISTERS_BASE + 0x0994)
-#define SPARE_A2                       (REGISTERS_BASE + 0x0998)
-#define SPARE_A3                       (REGISTERS_BASE + 0x099C)
-#define SPARE_A4                       (REGISTERS_BASE + 0x09A0)
-#define SPARE_A5                       (REGISTERS_BASE + 0x09A4)
-#define SPARE_A6                       (REGISTERS_BASE + 0x09A8)
-#define SPARE_A7                       (REGISTERS_BASE + 0x09AC)
-#define SPARE_A8                       (REGISTERS_BASE + 0x09B0)
-#define SPARE_B1                       (REGISTERS_BASE + 0x5420)
-#define SPARE_B2                       (REGISTERS_BASE + 0x5424)
-#define SPARE_B3                       (REGISTERS_BASE + 0x5428)
-#define SPARE_B4                       (REGISTERS_BASE + 0x542C)
-#define SPARE_B5                       (REGISTERS_BASE + 0x5430)
-#define SPARE_B6                       (REGISTERS_BASE + 0x5434)
-#define SPARE_B7                       (REGISTERS_BASE + 0x5438)
-#define SPARE_B8                       (REGISTERS_BASE + 0x543C)
-
-enum wl12xx_acx_int_reg {
-	ACX_REG_INTERRUPT_TRIG,
-	ACX_REG_INTERRUPT_TRIG_H,
-
-/*=============================================
-  Host Interrupt Mask Register - 32bit (RW)
-  ------------------------------------------
-  Setting a bit in this register masks the
-  corresponding interrupt to the host.
-  0 - RX0		- Rx first dubble buffer Data Interrupt
-  1 - TXD		- Tx Data Interrupt
-  2 - TXXFR		- Tx Transfer Interrupt
-  3 - RX1		- Rx second dubble buffer Data Interrupt
-  4 - RXXFR		- Rx Transfer Interrupt
-  5 - EVENT_A	- Event Mailbox interrupt
-  6 - EVENT_B	- Event Mailbox interrupt
-  7 - WNONHST	- Wake On Host Interrupt
-  8 - TRACE_A	- Debug Trace interrupt
-  9 - TRACE_B	- Debug Trace interrupt
- 10 - CDCMP		- Command Complete Interrupt
- 11 -
- 12 -
- 13 -
- 14 - ICOMP		- Initialization Complete Interrupt
- 16 - SG SE		- Soft Gemini - Sense enable interrupt
- 17 - SG SD		- Soft Gemini - Sense disable interrupt
- 18 -			-
- 19 -			-
- 20 -			-
- 21-			-
- Default: 0x0001
-*==============================================*/
-	ACX_REG_INTERRUPT_MASK,
-
-/*=============================================
-  Host Interrupt Mask Set 16bit, (Write only)
-  ------------------------------------------
- Setting a bit in this register sets
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-==============================================*/
-	ACX_REG_HINT_MASK_SET,
-
-/*=============================================
-  Host Interrupt Mask Clear 16bit,(Write only)
-  ------------------------------------------
- Setting a bit in this register clears
- the corresponding bin in ACX_HINT_MASK register
- without effecting the mask
- state of other bits (0 = no effect).
-=============================================*/
-	ACX_REG_HINT_MASK_CLR,
-
-/*=============================================
-  Host Interrupt Status Nondestructive Read
-  16bit,(Read only)
-  ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register doesn't
- effect its content.
-=============================================*/
-	ACX_REG_INTERRUPT_NO_CLEAR,
-
-/*=============================================
-  Host Interrupt Status Clear on Read  Register
-  16bit,(Read only)
-  ------------------------------------------
- The host can read this register to determine
- which interrupts are active.
- Reading this register clears it,
- thus making all interrupts inactive.
-==============================================*/
-	ACX_REG_INTERRUPT_CLEAR,
-
-/*=============================================
-  Host Interrupt Acknowledge Register
-  16bit,(Write only)
-  ------------------------------------------
- The host can set individual bits in this
- register to clear (acknowledge) the corresp.
- interrupt status bits in the HINT_STS_CLR and
- HINT_STS_ND registers, thus making the
- assotiated interrupt inactive. (0-no effect)
-==============================================*/
-	ACX_REG_INTERRUPT_ACK,
-
-/*===============================================
-   Host Software Reset - 32bit RW
- ------------------------------------------
-    [31:1] Reserved
-    0  SOFT_RESET Soft Reset  - When this bit is set,
-    it holds the Wlan hardware in a soft reset state.
-    This reset disables all MAC and baseband processor
-    clocks except the CardBus/PCI interface clock.
-    It also initializes all MAC state machines except
-    the host interface. It does not reload the
-    contents of the EEPROM. When this bit is cleared
-    (not self-clearing), the Wlan hardware
-    exits the software reset state.
-===============================================*/
-	ACX_REG_SLV_SOFT_RESET,
-
-/*===============================================
- EEPROM Burst Read Start  - 32bit RW
- ------------------------------------------
- [31:1] Reserved
- 0  ACX_EE_START -  EEPROM Burst Read Start 0
- Setting this bit starts a burst read from
- the external EEPROM.
- If this bit is set (after reset) before an EEPROM read/write,
- the burst read starts at EEPROM address 0.
- Otherwise, it starts at the address
- following the address of the previous access.
- TheWlan hardware hardware clears this bit automatically.
-
- Default: 0x00000000
-*================================================*/
-	ACX_REG_EE_START,
-
-/* Embedded ARM CPU Control */
-
-/*===============================================
- Halt eCPU   - 32bit RW
- ------------------------------------------
- 0 HALT_ECPU Halt Embedded CPU - This bit is the
- compliment of bit 1 (MDATA2) in the SOR_CFG register.
- During a hardware reset, this bit holds
- the inverse of MDATA2.
- When downloading firmware from the host,
- set this bit (pull down MDATA2).
- The host clears this bit after downloading the firmware into
- zero-wait-state SSRAM.
- When loading firmware from Flash, clear this bit (pull up MDATA2)
- so that the eCPU can run the bootloader code in Flash
- HALT_ECPU eCPU State
- --------------------
- 1 halt eCPU
- 0 enable eCPU
- ===============================================*/
-	ACX_REG_ECPU_CONTROL,
-
-	ACX_REG_TABLE_LEN
-};
-
-#define ACX_SLV_SOFT_RESET_BIT   BIT(1)
-#define ACX_REG_EEPROM_START_BIT BIT(1)
-
-/* Command/Information Mailbox Pointers */
-
-/*===============================================
-  Command Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the command mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to
- find the location of the command mailbox.
- The Wlan hardware initializes the command mailbox
- pointer with the default address of the command mailbox.
- The command mailbox pointer is not valid until after
- the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_COMMAND_MAILBOX_PTR				(SCR_PAD0)
-
-/*===============================================
-  Information Mailbox Pointer - 32bit RW
- ------------------------------------------
- This register holds the start address of
- the information mailbox located in the Wlan hardware memory.
- The host must read this pointer after a reset to find
- the location of the information mailbox.
- The Wlan hardware initializes the information mailbox pointer
- with the default address of the information mailbox.
- The information mailbox pointer is not valid
- until after the host receives the Init Complete interrupt from
- the Wlan hardware.
- ===============================================*/
-#define REG_EVENT_MAILBOX_PTR				(SCR_PAD1)
-
-
-/* Misc */
-
-#define REG_ENABLE_TX_RX				(ENABLE)
-/*
- * Rx configuration (filter) information element
- * ---------------------------------------------
- */
-#define REG_RX_CONFIG				(RX_CFG)
-#define REG_RX_FILTER				(RX_FILTER_CFG)
-
-
-#define RX_CFG_ENABLE_PHY_HEADER_PLCP	 0x0002
-
-/* promiscuous - receives all valid frames */
-#define RX_CFG_PROMISCUOUS		 0x0008
-
-/* receives frames from any BSSID */
-#define RX_CFG_BSSID			 0x0020
-
-/* receives frames destined to any MAC address */
-#define RX_CFG_MAC			 0x0010
-
-#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC	 0x0010
-#define RX_CFG_ENABLE_ANY_DEST_MAC	 0x0000
-#define RX_CFG_ENABLE_ONLY_MY_BSSID	 0x0020
-#define RX_CFG_ENABLE_ANY_BSSID		 0x0000
-
-/* discards all broadcast frames */
-#define RX_CFG_DISABLE_BCAST		 0x0200
-
-#define RX_CFG_ENABLE_ONLY_MY_SSID	 0x0400
-#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
-#define RX_CFG_COPY_RX_STATUS		 0x2000
-#define RX_CFG_TSF			 0x10000
-
-#define RX_CONFIG_OPTION_ANY_DST_MY_BSS	 (RX_CFG_ENABLE_ANY_DEST_MAC | \
-					  RX_CFG_ENABLE_ONLY_MY_BSSID)
-
-#define RX_CONFIG_OPTION_MY_DST_ANY_BSS	 (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
-					  | RX_CFG_ENABLE_ANY_BSSID)
-
-#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
-					  RX_CFG_ENABLE_ANY_BSSID)
-
-#define RX_CONFIG_OPTION_MY_DST_MY_BSS	 (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
-					  | RX_CFG_ENABLE_ONLY_MY_BSSID)
-
-#define RX_CONFIG_OPTION_FOR_SCAN  (RX_CFG_ENABLE_PHY_HEADER_PLCP \
-				    | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
-				    | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
-
-#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
-
-#define RX_CONFIG_OPTION_FOR_JOIN	 (RX_CFG_ENABLE_ONLY_MY_BSSID | \
-					  RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
-
-#define RX_CONFIG_OPTION_FOR_IBSS_JOIN   (RX_CFG_ENABLE_ONLY_MY_SSID | \
-					  RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
-
-#define RX_FILTER_OPTION_DEF	      (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
-				       | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
-				       | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
-
-#define RX_FILTER_OPTION_FILTER_ALL	 0
-
-#define RX_FILTER_OPTION_DEF_PRSP_BCN  (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
-					| CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
-
-#define RX_FILTER_OPTION_JOIN	     (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
-				      | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
-				      | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
-				      | CFG_RX_PRSP_EN)
-
-
-/*===============================================
-  Phy regs
- ===============================================*/
-#define ACX_PHY_ADDR_REG                SBB_ADDR
-#define ACX_PHY_DATA_REG                SBB_DATA
-#define ACX_PHY_CTRL_REG                SBB_CTL
-#define ACX_PHY_REG_WR_MASK             0x00000001ul
-#define ACX_PHY_REG_RD_MASK             0x00000002ul
-
-
-/*===============================================
- EEPROM Read/Write Request 32bit RW
- ------------------------------------------
- 1 EE_READ - EEPROM Read Request 1 - Setting this bit
- loads a single byte of data into the EE_DATA
- register from the EEPROM location specified in
- the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
- EE_DATA is valid when this bit is cleared.
-
- 0 EE_WRITE  - EEPROM Write Request  - Setting this bit
- writes a single byte of data from the EE_DATA register into the
- EEPROM location specified in the EE_ADDR register.
- The Wlan hardware hardware clears this bit automatically.
-*===============================================*/
-#define ACX_EE_CTL_REG                      EE_CTL
-#define EE_WRITE                            0x00000001ul
-#define EE_READ                             0x00000002ul
-
-/*===============================================
-  EEPROM Address  - 32bit RW
-  ------------------------------------------
-  This register specifies the address
-  within the EEPROM from/to which to read/write data.
-  ===============================================*/
-#define ACX_EE_ADDR_REG                     EE_ADDR
-
-/*===============================================
-  EEPROM Data  - 32bit RW
-  ------------------------------------------
-  This register either holds the read 8 bits of
-  data from the EEPROM or the write data
-  to be written to the EEPROM.
-  ===============================================*/
-#define ACX_EE_DATA_REG                     EE_DATA
-
-/*===============================================
-  EEPROM Base Address  - 32bit RW
-  ------------------------------------------
-  This register holds the upper nine bits
-  [23:15] of the 24-bit Wlan hardware memory
-  address for burst reads from EEPROM accesses.
-  The EEPROM provides the lower 15 bits of this address.
-  The MSB of the address from the EEPROM is ignored.
-  ===============================================*/
-#define ACX_EE_CFG                          EE_CFG
-
-/*===============================================
-  GPIO Output Values  -32bit, RW
-  ------------------------------------------
-  [31:16]  Reserved
-  [15: 0]  Specify the output values (at the output driver inputs) for
-  GPIO[15:0], respectively.
-  ===============================================*/
-#define ACX_GPIO_OUT_REG            GPIO_OUT
-#define ACX_MAX_GPIO_LINES          15
-
-/*===============================================
-  Contention window  -32bit, RW
-  ------------------------------------------
-  [31:26]  Reserved
-  [25:16]  Max (0x3ff)
-  [15:07]  Reserved
-  [06:00]  Current contention window value - default is 0x1F
-  ===============================================*/
-#define ACX_CONT_WIND_CFG_REG    CONT_WIND_CFG
-#define ACX_CONT_WIND_MIN_MASK   0x0000007f
-#define ACX_CONT_WIND_MAX        0x03ff0000
-
-/*
- * Indirect slave register/memory registers
- * ----------------------------------------
- */
-#define HW_SLAVE_REG_ADDR_REG		0x00000004
-#define HW_SLAVE_REG_DATA_REG		0x00000008
-#define HW_SLAVE_REG_CTRL_REG		0x0000000c
-
-#define SLAVE_AUTO_INC				0x00010000
-#define SLAVE_NO_AUTO_INC			0x00000000
-#define SLAVE_HOST_LITTLE_ENDIAN	0x00000000
-
-#define HW_SLAVE_MEM_ADDR_REG		SLV_MEM_ADDR
-#define HW_SLAVE_MEM_DATA_REG		SLV_MEM_DATA
-#define HW_SLAVE_MEM_CTRL_REG		SLV_MEM_CTL
-#define HW_SLAVE_MEM_ENDIAN_REG		SLV_END_CTL
-
-#define HW_FUNC_EVENT_INT_EN		0x8000
-#define HW_FUNC_EVENT_MASK_REG		0x00000034
-
-#define ACX_MAC_TIMESTAMP_REG	(MAC_TIMESTAMP)
-
-/*===============================================
-  HI_CFG Interface Configuration Register Values
-  ------------------------------------------
-  ===============================================*/
-#define HI_CFG_UART_ENABLE          0x00000004
-#define HI_CFG_RST232_ENABLE        0x00000008
-#define HI_CFG_CLOCK_REQ_SELECT     0x00000010
-#define HI_CFG_HOST_INT_ENABLE      0x00000020
-#define HI_CFG_VLYNQ_OUTPUT_ENABLE  0x00000040
-#define HI_CFG_HOST_INT_ACTIVE_LOW  0x00000080
-#define HI_CFG_UART_TX_OUT_GPIO_15  0x00000100
-#define HI_CFG_UART_TX_OUT_GPIO_14  0x00000200
-#define HI_CFG_UART_TX_OUT_GPIO_7   0x00000400
-
-/*
- * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
- *       for platforms using active high interrupt level
- */
-#ifdef USE_ACTIVE_HIGH
-#define HI_CFG_DEF_VAL              \
-	(HI_CFG_UART_ENABLE |        \
-	HI_CFG_RST232_ENABLE |      \
-	HI_CFG_CLOCK_REQ_SELECT |   \
-	HI_CFG_HOST_INT_ENABLE)
-#else
-#define HI_CFG_DEF_VAL              \
-	(HI_CFG_UART_ENABLE |        \
-	HI_CFG_RST232_ENABLE |      \
-	HI_CFG_CLOCK_REQ_SELECT |   \
-	HI_CFG_HOST_INT_ENABLE)
-
-#endif
-
-#define REF_FREQ_19_2                       0
-#define REF_FREQ_26_0                       1
-#define REF_FREQ_38_4                       2
-#define REF_FREQ_40_0                       3
-#define REF_FREQ_33_6                       4
-#define REF_FREQ_NUM                        5
-
-#define LUT_PARAM_INTEGER_DIVIDER           0
-#define LUT_PARAM_FRACTIONAL_DIVIDER        1
-#define LUT_PARAM_ATTN_BB                   2
-#define LUT_PARAM_ALPHA_BB                  3
-#define LUT_PARAM_STOP_TIME_BB              4
-#define LUT_PARAM_BB_PLL_LOOP_FILTER        5
-#define LUT_PARAM_NUM                       6
-
-#define ACX_EEPROMLESS_IND_REG              (SCR_PAD4)
-#define USE_EEPROM                          0
-#define SOFT_RESET_MAX_TIME                 1000000
-#define SOFT_RESET_STALL_TIME               1000
-#define NVS_DATA_BUNDARY_ALIGNMENT          4
-
-
-/* Firmware image load chunk size */
-#define CHUNK_SIZE          512
-
-/* Firmware image header size */
-#define FW_HDR_SIZE 8
-
-#define ECPU_CONTROL_HALT					0x00000101
-
-
-/******************************************************************************
-
-    CHANNELS, BAND & REG DOMAINS definitions
-
-******************************************************************************/
-
-
-enum {
-	RADIO_BAND_2_4GHZ = 0,  /* 2.4 Ghz band */
-	RADIO_BAND_5GHZ = 1,    /* 5 Ghz band */
-	RADIO_BAND_JAPAN_4_9_GHZ = 2,
-	DEFAULT_BAND = RADIO_BAND_2_4GHZ,
-	INVALID_BAND = 0xFE,
-	MAX_RADIO_BANDS = 0xFF
-};
-
-enum {
-	NO_RATE      = 0,
-	RATE_1MBPS   = 0x0A,
-	RATE_2MBPS   = 0x14,
-	RATE_5_5MBPS = 0x37,
-	RATE_6MBPS   = 0x0B,
-	RATE_9MBPS   = 0x0F,
-	RATE_11MBPS  = 0x6E,
-	RATE_12MBPS  = 0x0A,
-	RATE_18MBPS  = 0x0E,
-	RATE_22MBPS  = 0xDC,
-	RATE_24MBPS  = 0x09,
-	RATE_36MBPS  = 0x0D,
-	RATE_48MBPS  = 0x08,
-	RATE_54MBPS  = 0x0C
-};
-
-enum {
-	RATE_INDEX_1MBPS   =  0,
-	RATE_INDEX_2MBPS   =  1,
-	RATE_INDEX_5_5MBPS =  2,
-	RATE_INDEX_6MBPS   =  3,
-	RATE_INDEX_9MBPS   =  4,
-	RATE_INDEX_11MBPS  =  5,
-	RATE_INDEX_12MBPS  =  6,
-	RATE_INDEX_18MBPS  =  7,
-	RATE_INDEX_22MBPS  =  8,
-	RATE_INDEX_24MBPS  =  9,
-	RATE_INDEX_36MBPS  =  10,
-	RATE_INDEX_48MBPS  =  11,
-	RATE_INDEX_54MBPS  =  12,
-	RATE_INDEX_MAX     =  RATE_INDEX_54MBPS,
-	MAX_RATE_INDEX,
-	INVALID_RATE_INDEX = MAX_RATE_INDEX,
-	RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
-};
-
-enum {
-	RATE_MASK_1MBPS = 0x1,
-	RATE_MASK_2MBPS = 0x2,
-	RATE_MASK_5_5MBPS = 0x4,
-	RATE_MASK_11MBPS = 0x20,
-};
-
-#define SHORT_PREAMBLE_BIT   BIT(0) /* CCK or Barker depending on the rate */
-#define OFDM_RATE_BIT        BIT(6)
-#define PBCC_RATE_BIT        BIT(7)
-
-enum {
-	CCK_LONG = 0,
-	CCK_SHORT = SHORT_PREAMBLE_BIT,
-	PBCC_LONG = PBCC_RATE_BIT,
-	PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
-	OFDM = OFDM_RATE_BIT
-};
-
-/******************************************************************************
-
-Transmit-Descriptor RATE-SET field definitions...
-
-Define a new "Rate-Set" for TX path that incorporates the
-Rate & Modulation info into a single 16-bit field.
-
-TxdRateSet_t:
-b15   - Indicates Preamble type (1=SHORT, 0=LONG).
-	Notes:
-	Must be LONG (0) for 1Mbps rate.
-	Does not apply (set to 0) for RevG-OFDM rates.
-b14   - Indicates PBCC encoding (1=PBCC, 0=not).
-	Notes:
-	Does not apply (set to 0) for rates 1 and 2 Mbps.
-	Does not apply (set to 0) for RevG-OFDM rates.
-b13    - Unused (set to 0).
-b12-b0 - Supported Rate indicator bits as defined below.
-
-******************************************************************************/
-
-
-#define TNETW1251_CHIP_ID_PG1_0         0x07010101
-#define TNETW1251_CHIP_ID_PG1_1         0x07020101
-#define TNETW1251_CHIP_ID_PG1_2	        0x07030101
-
-/*************************************************************************
-
-    Interrupt Trigger Register (Host -> WiLink)
-
-**************************************************************************/
-
-/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
-
-/*
- * Host Command Interrupt. Setting this bit masks
- * the interrupt that the host issues to inform
- * the FW that it has sent a command
- * to the Wlan hardware Command Mailbox.
- */
-#define INTR_TRIG_CMD       BIT(0)
-
-/*
- * Host Event Acknowlegde Interrupt. The host
- * sets this bit to acknowledge that it received
- * the unsolicited information from the event
- * mailbox.
- */
-#define INTR_TRIG_EVENT_ACK BIT(1)
-
-/*
- * The host sets this bit to inform the Wlan
- * FW that a TX packet is in the XFER
- * Buffer #0.
- */
-#define INTR_TRIG_TX_PROC0 BIT(2)
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #0.
- */
-#define INTR_TRIG_RX_PROC0 BIT(3)
-
-#define INTR_TRIG_DEBUG_ACK BIT(4)
-
-#define INTR_TRIG_STATE_CHANGED BIT(5)
-
-
-/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
-
-/*
- * The host sets this bit to inform the FW
- * that it read a packet from RX XFER
- * Buffer #1.
- */
-#define INTR_TRIG_RX_PROC1 BIT(17)
-
-/*
- * The host sets this bit to inform the Wlan
- * hardware that a TX packet is in the XFER
- * Buffer #1.
- */
-#define INTR_TRIG_TX_PROC1 BIT(18)
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
deleted file mode 100644
index 981ea25..0000000
--- a/drivers/net/wireless/wl12xx/rx.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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/skbuff.h>
-#include <net/mac80211.h>
-
-#include "wl12xx.h"
-#include "reg.h"
-#include "spi.h"
-#include "rx.h"
-
-static void wl12xx_rx_header(struct wl12xx *wl,
-			     struct wl12xx_rx_descriptor *desc)
-{
-	u32 rx_packet_ring_addr;
-
-	rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
-	if (wl->rx_current_buffer)
-		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
-
-	wl12xx_spi_mem_read(wl, rx_packet_ring_addr, desc,
-			    sizeof(struct wl12xx_rx_descriptor));
-}
-
-static void wl12xx_rx_status(struct wl12xx *wl,
-			     struct wl12xx_rx_descriptor *desc,
-			     struct ieee80211_rx_status *status,
-			     u8 beacon)
-{
-	memset(status, 0, sizeof(struct ieee80211_rx_status));
-
-	status->band = IEEE80211_BAND_2GHZ;
-	status->mactime = desc->timestamp;
-
-	/*
-	 * The rx status timestamp is a 32 bits value while the TSF is a
-	 * 64 bits one.
-	 * For IBSS merging, TSF is mandatory, so we have to get it
-	 * somehow, so we ask for ACX_TSF_INFO.
-	 * That could be moved to the get_tsf() hook, but unfortunately,
-	 * this one must be atomic, while our SPI routines can sleep.
-	 */
-	if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
-		u64 mactime;
-		int ret;
-		struct wl12xx_command cmd;
-		struct acx_tsf_info *tsf_info;
-
-		memset(&cmd, 0, sizeof(cmd));
-
-		ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
-					     sizeof(struct acx_tsf_info),
-					     &cmd);
-		if (ret < 0) {
-			wl12xx_warning("ACX_FW_REV interrogate failed");
-			return;
-		}
-
-		tsf_info = (struct acx_tsf_info *)&(cmd.parameters);
-
-		mactime = tsf_info->current_tsf_lsb |
-			(tsf_info->current_tsf_msb << 31);
-
-		status->mactime = mactime;
-	}
-
-	status->signal = desc->rssi;
-	status->qual = (desc->rssi - WL12XX_RX_MIN_RSSI) * 100 /
-		(WL12XX_RX_MAX_RSSI - WL12XX_RX_MIN_RSSI);
-	status->qual = min(status->qual, 100);
-	status->qual = max(status->qual, 0);
-
-	/*
-	 * FIXME: guessing that snr needs to be divided by two, otherwise
-	 * the values don't make any sense
-	 */
-	status->noise = desc->rssi - desc->snr / 2;
-
-	status->freq = ieee80211_channel_to_frequency(desc->channel);
-
-	status->flag |= RX_FLAG_TSFT;
-
-	if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
-		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
-
-		if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
-			status->flag |= RX_FLAG_DECRYPTED;
-
-		if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
-			status->flag |= RX_FLAG_MMIC_ERROR;
-	}
-
-	if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
-		status->flag |= RX_FLAG_FAILED_FCS_CRC;
-
-
-	/* FIXME: set status->rate_idx */
-}
-
-static void wl12xx_rx_body(struct wl12xx *wl,
-			   struct wl12xx_rx_descriptor *desc)
-{
-	struct sk_buff *skb;
-	struct ieee80211_rx_status status;
-	u8 *rx_buffer, beacon = 0;
-	u16 length, *fc;
-	u32 curr_id, last_id_inc, rx_packet_ring_addr;
-
-	length = WL12XX_RX_ALIGN(desc->length  - PLCP_HEADER_LENGTH);
-	curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
-	last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
-
-	if (last_id_inc != curr_id) {
-		wl12xx_warning("curr ID:%d, last ID inc:%d",
-			       curr_id, last_id_inc);
-		wl->rx_last_id = curr_id;
-	} else {
-		wl->rx_last_id = last_id_inc;
-	}
-
-	rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
-		sizeof(struct wl12xx_rx_descriptor) + 20;
-	if (wl->rx_current_buffer)
-		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
-
-	skb = dev_alloc_skb(length);
-	if (!skb) {
-		wl12xx_error("Couldn't allocate RX frame");
-		return;
-	}
-
-	rx_buffer = skb_put(skb, length);
-	wl12xx_spi_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
-
-	/* The actual lenght doesn't include the target's alignment */
-	skb->len = desc->length  - PLCP_HEADER_LENGTH;
-
-	fc = (u16 *)skb->data;
-
-	if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
-		beacon = 1;
-
-	wl12xx_rx_status(wl, desc, &status, beacon);
-
-	wl12xx_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
-		     beacon ? "beacon" : "");
-
-	ieee80211_rx(wl->hw, skb, &status);
-}
-
-static void wl12xx_rx_ack(struct wl12xx *wl)
-{
-	u32 data, addr;
-
-	if (wl->rx_current_buffer) {
-		addr = ACX_REG_INTERRUPT_TRIG_H;
-		data = INTR_TRIG_RX_PROC1;
-	} else {
-		addr = ACX_REG_INTERRUPT_TRIG;
-		data = INTR_TRIG_RX_PROC0;
-	}
-
-	wl12xx_reg_write32(wl, addr, data);
-
-	/* Toggle buffer ring */
-	wl->rx_current_buffer = !wl->rx_current_buffer;
-}
-
-
-void wl12xx_rx(struct wl12xx *wl)
-{
-	struct wl12xx_rx_descriptor rx_desc;
-
-	if (wl->state != WL12XX_STATE_ON)
-		return;
-
-	/* We first read the frame's header */
-	wl12xx_rx_header(wl, &rx_desc);
-
-	/* Now we can read the body */
-	wl12xx_rx_body(wl, &rx_desc);
-
-	/* Finally, we need to ACK the RX */
-	wl12xx_rx_ack(wl);
-
-	return;
-}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
deleted file mode 100644
index 8a23fde..0000000
--- a/drivers/net/wireless/wl12xx/rx.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_RX_H__
-#define __WL12XX_RX_H__
-
-#include <linux/bitops.h>
-
-/*
- * RX PATH
- *
- * The Rx path uses a double buffer and an rx_contro structure, each located
- * at a fixed address in the device memory. The host keeps track of which
- * buffer is available and alternates between them on a per packet basis.
- * The size of each of the two buffers is large enough to hold the longest
- * 802.3 packet.
- * The RX path goes like that:
- * 1) The target generates an interrupt each time a new packet is received.
- *   There are 2 RX interrupts, one for each buffer.
- * 2) The host reads the received packet from one of the double buffers.
- * 3) The host triggers a target interrupt.
- * 4) The target prepares the next RX packet.
- */
-
-#define WL12XX_RX_MAX_RSSI -30
-#define WL12XX_RX_MIN_RSSI -95
-
-#define WL12XX_RX_ALIGN_TO 4
-#define WL12XX_RX_ALIGN(len) (((len) + WL12XX_RX_ALIGN_TO - 1) & \
-			     ~(WL12XX_RX_ALIGN_TO - 1))
-
-#define SHORT_PREAMBLE_BIT   BIT(0)
-#define OFDM_RATE_BIT        BIT(6)
-#define PBCC_RATE_BIT        BIT(7)
-
-#define PLCP_HEADER_LENGTH 8
-#define RX_DESC_PACKETID_SHIFT 11
-#define RX_MAX_PACKET_ID 3
-
-#define RX_DESC_VALID_FCS         0x0001
-#define RX_DESC_MATCH_RXADDR1     0x0002
-#define RX_DESC_MCAST             0x0004
-#define RX_DESC_STAINTIM          0x0008
-#define RX_DESC_VIRTUAL_BM        0x0010
-#define RX_DESC_BCAST             0x0020
-#define RX_DESC_MATCH_SSID        0x0040
-#define RX_DESC_MATCH_BSSID       0x0080
-#define RX_DESC_ENCRYPTION_MASK   0x0300
-#define RX_DESC_MEASURMENT        0x0400
-#define RX_DESC_SEQNUM_MASK       0x1800
-#define	RX_DESC_MIC_FAIL	  0x2000
-#define	RX_DESC_DECRYPT_FAIL	  0x4000
-
-struct wl12xx_rx_descriptor {
-	u32 timestamp; /* In microseconds */
-	u16 length; /* Paylod length, including headers */
-	u16 flags;
-
-	/*
-	 * 0 - 802.11
-	 * 1 - 802.3
-	 * 2 - IP
-	 * 3 - Raw Codec
-	 */
-	u8 type;
-
-	/*
-	 * Recevied Rate:
-	 * 0x0A - 1MBPS
-	 * 0x14 - 2MBPS
-	 * 0x37 - 5_5MBPS
-	 * 0x0B - 6MBPS
-	 * 0x0F - 9MBPS
-	 * 0x6E - 11MBPS
-	 * 0x0A - 12MBPS
-	 * 0x0E - 18MBPS
-	 * 0xDC - 22MBPS
-	 * 0x09 - 24MBPS
-	 * 0x0D - 36MBPS
-	 * 0x08 - 48MBPS
-	 * 0x0C - 54MBPS
-	 */
-	u8 rate;
-
-	u8 mod_pre; /* Modulation and preamble */
-	u8 channel;
-
-	/*
-	 * 0 - 2.4 Ghz
-	 * 1 - 5 Ghz
-	 */
-	u8 band;
-
-	s8 rssi; /* in dB */
-	u8 rcpi; /* in dB */
-	u8 snr; /* in dB */
-} __attribute__ ((packed));
-
-void wl12xx_rx(struct wl12xx *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
deleted file mode 100644
index abdf171..0000000
--- a/drivers/net/wireless/wl12xx/spi.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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/module.h>
-#include <linux/crc7.h>
-#include <linux/spi/spi.h>
-
-#include "wl12xx.h"
-#include "wl12xx_80211.h"
-#include "reg.h"
-#include "spi.h"
-#include "ps.h"
-
-static int wl12xx_translate_reg_addr(struct wl12xx *wl, int addr)
-{
-	/* If the address is lower than REGISTERS_BASE, it means that this is
-	 * a chip-specific register address, so look it up in the registers
-	 * table */
-	if (addr < REGISTERS_BASE) {
-		/* Make sure we don't go over the table */
-		if (addr >= ACX_REG_TABLE_LEN) {
-			wl12xx_error("address out of range (%d)", addr);
-			return -EINVAL;
-		}
-		addr = wl->chip.acx_reg_table[addr];
-	}
-
-	return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
-}
-
-static int wl12xx_translate_mem_addr(struct wl12xx *wl, int addr)
-{
-	return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
-}
-
-
-void wl12xx_spi_reset(struct wl12xx *wl)
-{
-	u8 *cmd;
-	struct spi_transfer t;
-	struct spi_message m;
-
-	cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
-	if (!cmd) {
-		wl12xx_error("could not allocate cmd for spi reset");
-		return;
-	}
-
-	memset(&t, 0, sizeof(t));
-	spi_message_init(&m);
-
-	memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
-
-	t.tx_buf = cmd;
-	t.len = WSPI_INIT_CMD_LEN;
-	spi_message_add_tail(&t, &m);
-
-	spi_sync(wl->spi, &m);
-
-	wl12xx_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
-}
-
-void wl12xx_spi_init(struct wl12xx *wl)
-{
-	u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
-	struct spi_transfer t;
-	struct spi_message m;
-
-	cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
-	if (!cmd) {
-		wl12xx_error("could not allocate cmd for spi init");
-		return;
-	}
-
-	memset(crc, 0, sizeof(crc));
-	memset(&t, 0, sizeof(t));
-	spi_message_init(&m);
-
-	/*
-	 * Set WSPI_INIT_COMMAND
-	 * the data is being send from the MSB to LSB
-	 */
-	cmd[2] = 0xff;
-	cmd[3] = 0xff;
-	cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
-	cmd[0] = 0;
-	cmd[7] = 0;
-	cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
-	cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
-
-	if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
-		cmd[5] |=  WSPI_INIT_CMD_DIS_FIXEDBUSY;
-	else
-		cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
-
-	cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
-		| WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
-
-	crc[0] = cmd[1];
-	crc[1] = cmd[0];
-	crc[2] = cmd[7];
-	crc[3] = cmd[6];
-	crc[4] = cmd[5];
-
-	cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
-	cmd[4] |= WSPI_INIT_CMD_END;
-
-	t.tx_buf = cmd;
-	t.len = WSPI_INIT_CMD_LEN;
-	spi_message_add_tail(&t, &m);
-
-	spi_sync(wl->spi, &m);
-
-	wl12xx_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
-}
-
-/* Set the SPI partitions to access the chip addresses
- *
- * There are two VIRTUAL (SPI) partitions (the memory partition and the
- * registers partition), which are mapped to two different areas of the
- * PHYSICAL (hardware) memory.  This function also makes other checks to
- * ensure that the partitions are not overlapping.  In the diagram below, the
- * memory partition comes before the register partition, but the opposite is
- * also supported.
- *
- *                               PHYSICAL address
- *                                     space
- *
- *                                    |    |
- *                                 ...+----+--> mem_start
- *          VIRTUAL address     ...   |    |
- *               space       ...      |    | [PART_0]
- *                        ...         |    |
- * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
- *               |    |         ...   |    |
- *               |MEM |      ...      |    |
- *               |    |   ...         |    |
- *  part_size <--+----+...            |    | {unused area)
- *               |    |   ...         |    |
- *               |REG |      ...      |    |
- *  part_size    |    |         ...   |    |
- *      +     <--+----+...         ...+----+--> reg_start
- *  reg_size              ...         |    |
- *                           ...      |    | [PART_1]
- *                              ...   |    |
- *                                 ...+----+--> reg_start + reg_size
- *                                    |    |
- *
- */
-void wl12xx_set_partition(struct wl12xx *wl,
-			  u32 mem_start, u32 mem_size,
-			  u32 reg_start, u32 reg_size)
-{
-	u8 tx_buf[sizeof(u32) + 2 * sizeof(struct wl12xx_partition)];
-	struct wl12xx_partition *partition;
-	struct spi_transfer t;
-	struct spi_message m;
-	u32 *cmd;
-	size_t len;
-	int addr;
-
-	spi_message_init(&m);
-	memset(&t, 0, sizeof(t));
-	memset(tx_buf, 0, sizeof(tx_buf));
-
-	cmd = (u32 *) tx_buf;
-	partition = (struct wl12xx_partition *) (tx_buf + sizeof(u32));
-	addr = HW_ACCESS_PART0_SIZE_ADDR;
-	len = 2 * sizeof(struct wl12xx_partition);
-
-	*cmd |= WSPI_CMD_WRITE;
-	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
-	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
-	wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-		     mem_start, mem_size);
-	wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-		     reg_start, reg_size);
-
-	/* Make sure that the two partitions together don't exceed the
-	 * address range */
-	if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
-		wl12xx_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
-			     " address range.  Truncating partition[0].");
-		mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
-		wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	}
-
-	if ((mem_start < reg_start) &&
-	    ((mem_start + mem_size) > reg_start)) {
-		/* Guarantee that the memory partition doesn't overlap the
-		 * registers partition */
-		wl12xx_debug(DEBUG_SPI, "End of partition[0] is "
-			     "overlapping partition[1].  Adjusted.");
-		mem_size = reg_start - mem_start;
-		wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	} else if ((reg_start < mem_start) &&
-		   ((reg_start + reg_size) > mem_start)) {
-		/* Guarantee that the register partition doesn't overlap the
-		 * memory partition */
-		wl12xx_debug(DEBUG_SPI, "End of partition[1] is"
-			     " overlapping partition[0].  Adjusted.");
-		reg_size = mem_start - reg_start;
-		wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
-			     mem_start, mem_size);
-		wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
-			     reg_start, reg_size);
-	}
-
-	partition[0].start = mem_start;
-	partition[0].size  = mem_size;
-	partition[1].start = reg_start;
-	partition[1].size  = reg_size;
-
-	wl->physical_mem_addr = mem_start;
-	wl->physical_reg_addr = reg_start;
-
-	wl->virtual_mem_addr = 0;
-	wl->virtual_reg_addr = mem_size;
-
-	t.tx_buf = tx_buf;
-	t.len = sizeof(tx_buf);
-	spi_message_add_tail(&t, &m);
-
-	spi_sync(wl->spi, &m);
-}
-
-void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf,
-		     size_t len)
-{
-	struct spi_transfer t[3];
-	struct spi_message m;
-	char busy_buf[TNETWIF_READ_OFFSET_BYTES];
-	u32 cmd;
-
-	cmd = 0;
-	cmd |= WSPI_CMD_READ;
-	cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
-	cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
-	spi_message_init(&m);
-	memset(t, 0, sizeof(t));
-
-	t[0].tx_buf = &cmd;
-	t[0].len = 4;
-	spi_message_add_tail(&t[0], &m);
-
-	/* Busy and non busy words read */
-	t[1].rx_buf = busy_buf;
-	t[1].len = TNETWIF_READ_OFFSET_BYTES;
-	spi_message_add_tail(&t[1], &m);
-
-	t[2].rx_buf = buf;
-	t[2].len = len;
-	spi_message_add_tail(&t[2], &m);
-
-	spi_sync(wl->spi, &m);
-
-	/* FIXME: check busy words */
-
-	wl12xx_dump(DEBUG_SPI, "spi_read cmd -> ", &cmd, sizeof(cmd));
-	wl12xx_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
-}
-
-void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf,
-		      size_t len)
-{
-	struct spi_transfer t[2];
-	struct spi_message m;
-	u32 cmd;
-
-	cmd = 0;
-	cmd |= WSPI_CMD_WRITE;
-	cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
-	cmd |= addr & WSPI_CMD_BYTE_ADDR;
-
-	spi_message_init(&m);
-	memset(t, 0, sizeof(t));
-
-	t[0].tx_buf = &cmd;
-	t[0].len = sizeof(cmd);
-	spi_message_add_tail(&t[0], &m);
-
-	t[1].tx_buf = buf;
-	t[1].len = len;
-	spi_message_add_tail(&t[1], &m);
-
-	spi_sync(wl->spi, &m);
-
-	wl12xx_dump(DEBUG_SPI, "spi_write cmd -> ", &cmd, sizeof(cmd));
-	wl12xx_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
-}
-
-void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf,
-			 size_t len)
-{
-	int physical;
-
-	physical = wl12xx_translate_mem_addr(wl, addr);
-
-	wl12xx_spi_read(wl, physical, buf, len);
-}
-
-void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf,
-			  size_t len)
-{
-	int physical;
-
-	physical = wl12xx_translate_mem_addr(wl, addr);
-
-	wl12xx_spi_write(wl, physical, buf, len);
-}
-
-u32 wl12xx_mem_read32(struct wl12xx *wl, int addr)
-{
-	return wl12xx_read32(wl, wl12xx_translate_mem_addr(wl, addr));
-}
-
-void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val)
-{
-	wl12xx_write32(wl, wl12xx_translate_mem_addr(wl, addr), val);
-}
-
-u32 wl12xx_reg_read32(struct wl12xx *wl, int addr)
-{
-	return wl12xx_read32(wl, wl12xx_translate_reg_addr(wl, addr));
-}
-
-void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val)
-{
-	wl12xx_write32(wl, wl12xx_translate_reg_addr(wl, addr), val);
-}
diff --git a/drivers/net/wireless/wl12xx/spi.h b/drivers/net/wireless/wl12xx/spi.h
deleted file mode 100644
index fd3227e..0000000
--- a/drivers/net/wireless/wl12xx/spi.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_SPI_H__
-#define __WL12XX_SPI_H__
-
-#include "cmd.h"
-#include "acx.h"
-#include "reg.h"
-
-#define HW_ACCESS_MEMORY_MAX_RANGE		0x1FFC0
-
-#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
-#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
-#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
-#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
-
-#define HW_ACCESS_REGISTER_SIZE             4
-
-#define HW_ACCESS_PRAM_MAX_RANGE		0x3c000
-
-#define WSPI_CMD_READ                 0x40000000
-#define WSPI_CMD_WRITE                0x00000000
-#define WSPI_CMD_FIXED                0x20000000
-#define WSPI_CMD_BYTE_LENGTH          0x1FFE0000
-#define WSPI_CMD_BYTE_LENGTH_OFFSET   17
-#define WSPI_CMD_BYTE_ADDR            0x0001FFFF
-
-#define WSPI_INIT_CMD_CRC_LEN       5
-
-#define WSPI_INIT_CMD_START         0x00
-#define WSPI_INIT_CMD_TX            0x40
-/* the extra bypass bit is sampled by the TNET as '1' */
-#define WSPI_INIT_CMD_BYPASS_BIT    0x80
-#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
-#define WSPI_INIT_CMD_EN_FIXEDBUSY  0x80
-#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
-#define WSPI_INIT_CMD_IOD           0x40
-#define WSPI_INIT_CMD_IP            0x20
-#define WSPI_INIT_CMD_CS            0x10
-#define WSPI_INIT_CMD_WS            0x08
-#define WSPI_INIT_CMD_WSPI          0x01
-#define WSPI_INIT_CMD_END           0x01
-
-#define WSPI_INIT_CMD_LEN           8
-
-#define TNETWIF_READ_OFFSET_BYTES  8
-#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
-		((TNETWIF_READ_OFFSET_BYTES - 4) / sizeof(u32))
-#define HW_ACCESS_WSPI_INIT_CMD_MASK  0
-
-
-/* Raw target IO, address is not translated */
-void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf, size_t len);
-void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf, size_t len);
-
-/* Memory target IO, address is tranlated to partition 0 */
-void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf, size_t len);
-void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf, size_t len);
-u32 wl12xx_mem_read32(struct wl12xx *wl, int addr);
-void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val);
-
-/* Registers IO */
-u32 wl12xx_reg_read32(struct wl12xx *wl, int addr);
-void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val);
-
-/* INIT and RESET words */
-void wl12xx_spi_reset(struct wl12xx *wl);
-void wl12xx_spi_init(struct wl12xx *wl);
-void wl12xx_set_partition(struct wl12xx *wl,
-			  u32 part_start, u32 part_size,
-			  u32 reg_start,  u32 reg_size);
-
-static inline u32 wl12xx_read32(struct wl12xx *wl, int addr)
-{
-	u32 response;
-
-	wl12xx_spi_read(wl, addr, &response, sizeof(u32));
-
-	return response;
-}
-
-static inline void wl12xx_write32(struct wl12xx *wl, int addr, u32 val)
-{
-	wl12xx_spi_write(wl, addr, &val, sizeof(u32));
-}
-
-#endif /* __WL12XX_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
deleted file mode 100644
index 62145e2..0000000
--- a/drivers/net/wireless/wl12xx/tx.c
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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/kernel.h>
-#include <linux/module.h>
-
-#include "wl12xx.h"
-#include "reg.h"
-#include "spi.h"
-#include "tx.h"
-#include "ps.h"
-
-static bool wl12xx_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
-{
-	int used, data_in_count;
-
-	data_in_count = wl->data_in_count;
-
-	if (data_in_count < data_out_count)
-		/* data_in_count has wrapped */
-		data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
-
-	used = data_in_count - data_out_count;
-
-	WARN_ON(used < 0);
-	WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
-
-	if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
-		return true;
-	else
-		return false;
-}
-
-static int wl12xx_tx_path_status(struct wl12xx *wl)
-{
-	u32 status, addr, data_out_count;
-	bool busy;
-
-	addr = wl->data_path->tx_control_addr;
-	status = wl12xx_mem_read32(wl, addr);
-	data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
-	busy = wl12xx_tx_double_buffer_busy(wl, data_out_count);
-
-	if (busy)
-		return -EBUSY;
-
-	return 0;
-}
-
-static int wl12xx_tx_id(struct wl12xx *wl, struct sk_buff *skb)
-{
-	int i;
-
-	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
-		if (wl->tx_frames[i] == NULL) {
-			wl->tx_frames[i] = skb;
-			return i;
-		}
-
-	return -EBUSY;
-}
-
-static void wl12xx_tx_control(struct tx_double_buffer_desc *tx_hdr,
-			      struct ieee80211_tx_info *control, u16 fc)
-{
-	*(u16 *)&tx_hdr->control = 0;
-
-	tx_hdr->control.rate_policy = 0;
-
-	/* 802.11 packets */
-	tx_hdr->control.packet_type = 0;
-
-	if (control->flags & IEEE80211_TX_CTL_NO_ACK)
-		tx_hdr->control.ack_policy = 1;
-
-	tx_hdr->control.tx_complete = 1;
-
-	if ((fc & IEEE80211_FTYPE_DATA) &&
-	    ((fc & IEEE80211_STYPE_QOS_DATA) ||
-	     (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
-		tx_hdr->control.qos = 1;
-}
-
-/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
-#define MAX_MSDU_SECURITY_LENGTH      16
-#define MAX_MPDU_SECURITY_LENGTH      16
-#define WLAN_QOS_HDR_LEN              26
-#define MAX_MPDU_HEADER_AND_SECURITY  (MAX_MPDU_SECURITY_LENGTH + \
-				       WLAN_QOS_HDR_LEN)
-#define HW_BLOCK_SIZE                 252
-static void wl12xx_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
-{
-	u16 payload_len, frag_threshold, mem_blocks;
-	u16 num_mpdus, mem_blocks_per_frag;
-
-	frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
-	tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
-
-	payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH;
-
-	if (payload_len > frag_threshold) {
-		mem_blocks_per_frag =
-			((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
-			 HW_BLOCK_SIZE) + 1;
-		num_mpdus = payload_len / frag_threshold;
-		mem_blocks = num_mpdus * mem_blocks_per_frag;
-		payload_len -= num_mpdus * frag_threshold;
-		num_mpdus++;
-
-	} else {
-		mem_blocks_per_frag = 0;
-		mem_blocks = 0;
-		num_mpdus = 1;
-	}
-
-	mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
-
-	if (num_mpdus > 1)
-		mem_blocks += min(num_mpdus, mem_blocks_per_frag);
-
-	tx_hdr->num_mem_blocks = mem_blocks;
-}
-
-static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
-			      struct ieee80211_tx_info *control)
-{
-	struct tx_double_buffer_desc *tx_hdr;
-	struct ieee80211_rate *rate;
-	int id;
-	u16 fc;
-
-	if (!skb)
-		return -EINVAL;
-
-	id = wl12xx_tx_id(wl, skb);
-	if (id < 0)
-		return id;
-
-	fc = *(u16 *)skb->data;
-	tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
-							   sizeof(*tx_hdr));
-
-	tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
-	rate = ieee80211_get_tx_rate(wl->hw, control);
-	tx_hdr->rate = cpu_to_le16(rate->hw_value);
-	tx_hdr->expiry_time = cpu_to_le32(1 << 16);
-	tx_hdr->id = id;
-
-	/* FIXME: how to get the correct queue id? */
-	tx_hdr->xmit_queue = 0;
-
-	wl12xx_tx_control(tx_hdr, control, fc);
-	wl12xx_tx_frag_block_num(tx_hdr);
-
-	return 0;
-}
-
-/* We copy the packet to the target */
-static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
-				 struct ieee80211_tx_info *control)
-{
-	struct tx_double_buffer_desc *tx_hdr;
-	int len;
-	u32 addr;
-
-	if (!skb)
-		return -EINVAL;
-
-	tx_hdr = (struct tx_double_buffer_desc *) skb->data;
-
-	if (control->control.hw_key &&
-	    control->control.hw_key->alg == ALG_TKIP) {
-		int hdrlen;
-		u16 fc;
-		u8 *pos;
-
-		fc = *(u16 *)(skb->data + sizeof(*tx_hdr));
-		tx_hdr->length += WL12XX_TKIP_IV_SPACE;
-
-		hdrlen = ieee80211_hdrlen(fc);
-
-		pos = skb_push(skb, WL12XX_TKIP_IV_SPACE);
-		memmove(pos, pos + WL12XX_TKIP_IV_SPACE,
-			sizeof(*tx_hdr) + hdrlen);
-	}
-
-	/* Revisit. This is a workaround for getting non-aligned packets.
-	   This happens at least with EAPOL packets from the user space.
-	   Our DMA requires packets to be aligned on a 4-byte boundary.
-	*/
-	if (unlikely((long)skb->data & 0x03)) {
-		int offset = (4 - (long)skb->data) & 0x03;
-		wl12xx_debug(DEBUG_TX, "skb offset %d", offset);
-
-		/* check whether the current skb can be used */
-		if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
-			unsigned char *src = skb->data;
-
-			/* align the buffer on a 4-byte boundary */
-			skb_reserve(skb, offset);
-			memmove(skb->data, src, skb->len);
-		} else {
-			wl12xx_info("No handler, fixme!");
-			return -EINVAL;
-		}
-	}
-
-	/* Our skb->data at this point includes the HW header */
-	len = WL12XX_TX_ALIGN(skb->len);
-
-	if (wl->data_in_count & 0x1)
-		addr = wl->data_path->tx_packet_ring_addr +
-			wl->data_path->tx_packet_ring_chunk_size;
-	else
-		addr = wl->data_path->tx_packet_ring_addr;
-
-	wl12xx_spi_mem_write(wl, addr, skb->data, len);
-
-	wl12xx_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
-		     tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
-
-	return 0;
-}
-
-static void wl12xx_tx_trigger(struct wl12xx *wl)
-{
-	u32 data, addr;
-
-	if (wl->data_in_count & 0x1) {
-		addr = ACX_REG_INTERRUPT_TRIG_H;
-		data = INTR_TRIG_TX_PROC1;
-	} else {
-		addr = ACX_REG_INTERRUPT_TRIG;
-		data = INTR_TRIG_TX_PROC0;
-	}
-
-	wl12xx_reg_write32(wl, addr, data);
-
-	/* Bumping data in */
-	wl->data_in_count = (wl->data_in_count + 1) &
-		TX_STATUS_DATA_OUT_COUNT_MASK;
-}
-
-/* caller must hold wl->mutex */
-static int wl12xx_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
-{
-	struct ieee80211_tx_info *info;
-	int ret = 0;
-	u8 idx;
-
-	info = IEEE80211_SKB_CB(skb);
-
-	if (info->control.hw_key) {
-		idx = info->control.hw_key->hw_key_idx;
-		if (unlikely(wl->default_key != idx)) {
-			ret = wl12xx_acx_default_key(wl, idx);
-			if (ret < 0)
-				return ret;
-		}
-	}
-
-	ret = wl12xx_tx_path_status(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_tx_fill_hdr(wl, skb, info);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_tx_send_packet(wl, skb, info);
-	if (ret < 0)
-		return ret;
-
-	wl12xx_tx_trigger(wl);
-
-	return ret;
-}
-
-void wl12xx_tx_work(struct work_struct *work)
-{
-	struct wl12xx *wl = container_of(work, struct wl12xx, tx_work);
-	struct sk_buff *skb;
-	bool woken_up = false;
-	int ret;
-
-	mutex_lock(&wl->mutex);
-
-	if (unlikely(wl->state == WL12XX_STATE_OFF))
-		goto out;
-
-	while ((skb = skb_dequeue(&wl->tx_queue))) {
-		if (!woken_up) {
-			wl12xx_ps_elp_wakeup(wl);
-			woken_up = true;
-		}
-
-		ret = wl12xx_tx_frame(wl, skb);
-		if (ret == -EBUSY) {
-			/* firmware buffer is full, stop queues */
-			wl12xx_debug(DEBUG_TX, "tx_work: fw buffer full, "
-				     "stop queues");
-			ieee80211_stop_queues(wl->hw);
-			wl->tx_queue_stopped = true;
-			skb_queue_head(&wl->tx_queue, skb);
-			goto out;
-		} else if (ret < 0) {
-			dev_kfree_skb(skb);
-			goto out;
-		}
-	}
-
-out:
-	if (woken_up)
-		wl12xx_ps_elp_sleep(wl);
-
-	mutex_unlock(&wl->mutex);
-}
-
-static const char *wl12xx_tx_parse_status(u8 status)
-{
-	/* 8 bit status field, one character per bit plus null */
-	static char buf[9];
-	int i = 0;
-
-	memset(buf, 0, sizeof(buf));
-
-	if (status & TX_DMA_ERROR)
-		buf[i++] = 'm';
-	if (status & TX_DISABLED)
-		buf[i++] = 'd';
-	if (status & TX_RETRY_EXCEEDED)
-		buf[i++] = 'r';
-	if (status & TX_TIMEOUT)
-		buf[i++] = 't';
-	if (status & TX_KEY_NOT_FOUND)
-		buf[i++] = 'k';
-	if (status & TX_ENCRYPT_FAIL)
-		buf[i++] = 'e';
-	if (status & TX_UNAVAILABLE_PRIORITY)
-		buf[i++] = 'p';
-
-	/* bit 0 is unused apparently */
-
-	return buf;
-}
-
-static void wl12xx_tx_packet_cb(struct wl12xx *wl,
-				struct tx_result *result)
-{
-	struct ieee80211_tx_info *info;
-	struct sk_buff *skb;
-	int hdrlen, ret;
-	u8 *frame;
-
-	skb = wl->tx_frames[result->id];
-	if (skb == NULL) {
-		wl12xx_error("SKB for packet %d is NULL", result->id);
-		return;
-	}
-
-	info = IEEE80211_SKB_CB(skb);
-
-	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-	    (result->status == TX_SUCCESS))
-		info->flags |= IEEE80211_TX_STAT_ACK;
-
-	info->status.rates[0].count = result->ack_failures + 1;
-	wl->stats.retry_count += result->ack_failures;
-
-	/*
-	 * We have to remove our private TX header before pushing
-	 * the skb back to mac80211.
-	 */
-	frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
-	if (info->control.hw_key &&
-	    info->control.hw_key->alg == ALG_TKIP) {
-		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-		memmove(frame + WL12XX_TKIP_IV_SPACE, frame, hdrlen);
-		skb_pull(skb, WL12XX_TKIP_IV_SPACE);
-	}
-
-	wl12xx_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
-		     " status 0x%x (%s)",
-		     result->id, skb, result->ack_failures, result->rate,
-		     result->status, wl12xx_tx_parse_status(result->status));
-
-
-	ieee80211_tx_status(wl->hw, skb);
-
-	wl->tx_frames[result->id] = NULL;
-
-	if (wl->tx_queue_stopped) {
-		wl12xx_debug(DEBUG_TX, "cb: queue was stopped");
-
-		skb = skb_dequeue(&wl->tx_queue);
-
-		/* The skb can be NULL because tx_work might have been
-		   scheduled before the queue was stopped making the
-		   queue empty */
-
-		if (skb) {
-			ret = wl12xx_tx_frame(wl, skb);
-			if (ret == -EBUSY) {
-				/* firmware buffer is still full */
-				wl12xx_debug(DEBUG_TX, "cb: fw buffer "
-					     "still full");
-				skb_queue_head(&wl->tx_queue, skb);
-				return;
-			} else if (ret < 0) {
-				dev_kfree_skb(skb);
-				return;
-			}
-		}
-
-		wl12xx_debug(DEBUG_TX, "cb: waking queues");
-		ieee80211_wake_queues(wl->hw);
-		wl->tx_queue_stopped = false;
-	}
-}
-
-/* Called upon reception of a TX complete interrupt */
-void wl12xx_tx_complete(struct wl12xx *wl)
-{
-	int i, result_index, num_complete = 0;
-	struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
-
-	if (unlikely(wl->state != WL12XX_STATE_ON))
-		return;
-
-	/* First we read the result */
-	wl12xx_spi_mem_read(wl, wl->data_path->tx_complete_addr,
-			    result, sizeof(result));
-
-	result_index = wl->next_tx_complete;
-
-	for (i = 0; i < ARRAY_SIZE(result); i++) {
-		result_ptr = &result[result_index];
-
-		if (result_ptr->done_1 == 1 &&
-		    result_ptr->done_2 == 1) {
-			wl12xx_tx_packet_cb(wl, result_ptr);
-
-			result_ptr->done_1 = 0;
-			result_ptr->done_2 = 0;
-
-			result_index = (result_index + 1) &
-				(FW_TX_CMPLT_BLOCK_SIZE - 1);
-			num_complete++;
-		} else {
-			break;
-		}
-	}
-
-	/* Every completed frame needs to be acknowledged */
-	if (num_complete) {
-		/*
-		 * If we've wrapped, we have to clear
-		 * the results in 2 steps.
-		 */
-		if (result_index > wl->next_tx_complete) {
-			/* Only 1 write is needed */
-			wl12xx_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr +
-					     (wl->next_tx_complete *
-					      sizeof(struct tx_result)),
-					     &result[wl->next_tx_complete],
-					     num_complete *
-					     sizeof(struct tx_result));
-
-
-		} else if (result_index < wl->next_tx_complete) {
-			/* 2 writes are needed */
-			wl12xx_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr +
-					     (wl->next_tx_complete *
-					      sizeof(struct tx_result)),
-					     &result[wl->next_tx_complete],
-					     (FW_TX_CMPLT_BLOCK_SIZE -
-					      wl->next_tx_complete) *
-					     sizeof(struct tx_result));
-
-			wl12xx_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr,
-					     result,
-					     (num_complete -
-					      FW_TX_CMPLT_BLOCK_SIZE +
-					      wl->next_tx_complete) *
-					     sizeof(struct tx_result));
-
-		} else {
-			/* We have to write the whole array */
-			wl12xx_spi_mem_write(wl,
-					     wl->data_path->tx_complete_addr,
-					     result,
-					     FW_TX_CMPLT_BLOCK_SIZE *
-					     sizeof(struct tx_result));
-		}
-
-	}
-
-	wl->next_tx_complete = result_index;
-}
-
-/* caller must hold wl->mutex */
-void wl12xx_tx_flush(struct wl12xx *wl)
-{
-	int i;
-	struct sk_buff *skb;
-	struct ieee80211_tx_info *info;
-
-	/* TX failure */
-/* 	control->flags = 0; FIXME */
-
-	while ((skb = skb_dequeue(&wl->tx_queue))) {
-		info = IEEE80211_SKB_CB(skb);
-
-		wl12xx_debug(DEBUG_TX, "flushing skb 0x%p", skb);
-
-		if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
-				continue;
-
-		ieee80211_tx_status(wl->hw, skb);
-	}
-
-	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
-		if (wl->tx_frames[i] != NULL) {
-			skb = wl->tx_frames[i];
-			info = IEEE80211_SKB_CB(skb);
-
-			if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
-				continue;
-
-			ieee80211_tx_status(wl->hw, skb);
-			wl->tx_frames[i] = NULL;
-		}
-}
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
deleted file mode 100644
index dc82691..0000000
--- a/drivers/net/wireless/wl12xx/tx.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_TX_H__
-#define __WL12XX_TX_H__
-
-#include <linux/bitops.h>
-
-/*
- *
- * TX PATH
- *
- * The Tx path uses a double buffer and a tx_control structure, each located
- * at a fixed address in the device's memory. On startup, the host retrieves
- * the pointers to these addresses. A double buffer allows for continuous data
- * flow towards the device. The host keeps track of which buffer is available
- * and alternates between these two buffers on a per packet basis.
- *
- * The size of each of the two buffers is large enough to hold the longest
- * 802.3 packet - maximum size Ethernet packet + header + descriptor.
- * TX complete indication will be received a-synchronously in a TX done cyclic
- * buffer which is composed of 16 tx_result descriptors structures and is used
- * in a cyclic manner.
- *
- * The TX (HOST) procedure is as follows:
- * 1. Read the Tx path status, that will give the data_out_count.
- * 2. goto 1, if not possible.
- *    i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
- *    buffer).
- * 3. Copy the packet (preceded by double_buffer_desc), if possible.
- *    i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
- *    buffer).
- * 4. increment data_in_count.
- * 5. Inform the firmware by generating a firmware internal interrupt.
- * 6. FW will increment data_out_count after it reads the buffer.
- *
- * The TX Complete procedure:
- * 1. To get a TX complete indication the host enables the tx_complete flag in
- *    the TX descriptor Structure.
- * 2. For each packet with a Tx Complete field set, the firmware adds the
- *    transmit results to the cyclic buffer (txDoneRing) and sets both done_1
- *    and done_2 to 1 to indicate driver ownership.
- * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
- *    host to process the new data. Note: interrupt will be send per packet if
- *    TX complete indication was requested in tx_control or per crossing
- *    aggregation threshold.
- * 4. After receiving the Tx Complete interrupt, the host reads the
- *    TxDescriptorDone information in a cyclic manner and clears both done_1
- *    and done_2 fields.
- *
- */
-
-#define TX_COMPLETE_REQUIRED_BIT	0x80
-#define TX_STATUS_DATA_OUT_COUNT_MASK   0xf
-#define WL12XX_TX_ALIGN_TO 4
-#define WL12XX_TX_ALIGN(len) (((len) + WL12XX_TX_ALIGN_TO - 1) & \
-			     ~(WL12XX_TX_ALIGN_TO - 1))
-#define WL12XX_TKIP_IV_SPACE 4
-
-struct tx_control {
-	/* Rate Policy (class) index */
-	unsigned rate_policy:3;
-
-	/* When set, no ack policy is expected */
-	unsigned ack_policy:1;
-
-	/*
-	 * Packet type:
-	 * 0 -> 802.11
-	 * 1 -> 802.3
-	 * 2 -> IP
-	 * 3 -> raw codec
-	 */
-	unsigned packet_type:2;
-
-	/* If set, this is a QoS-Null or QoS-Data frame */
-	unsigned qos:1;
-
-	/*
-	 * If set, the target triggers the tx complete INT
-	 * upon frame sending completion.
-	 */
-	unsigned tx_complete:1;
-
-	/* 2 bytes padding before packet header */
-	unsigned xfer_pad:1;
-
-	unsigned reserved:7;
-} __attribute__ ((packed));
-
-
-struct tx_double_buffer_desc {
-	/* Length of payload, including headers. */
-	u16 length;
-
-	/*
-	 * A bit mask that specifies the initial rate to be used
-	 * Possible values are:
-	 * 0x0001 - 1Mbits
-	 * 0x0002 - 2Mbits
-	 * 0x0004 - 5.5Mbits
-	 * 0x0008 - 6Mbits
-	 * 0x0010 - 9Mbits
-	 * 0x0020 - 11Mbits
-	 * 0x0040 - 12Mbits
-	 * 0x0080 - 18Mbits
-	 * 0x0100 - 22Mbits
-	 * 0x0200 - 24Mbits
-	 * 0x0400 - 36Mbits
-	 * 0x0800 - 48Mbits
-	 * 0x1000 - 54Mbits
-	 */
-	u16 rate;
-
-	/* Time in us that a packet can spend in the target */
-	u32 expiry_time;
-
-	/* index of the TX queue used for this packet */
-	u8 xmit_queue;
-
-	/* Used to identify a packet */
-	u8 id;
-
-	struct tx_control control;
-
-	/*
-	 * The FW should cut the packet into fragments
-	 * of this size.
-	 */
-	u16 frag_threshold;
-
-	/* Numbers of HW queue blocks to be allocated */
-	u8 num_mem_blocks;
-
-	u8 reserved;
-} __attribute__ ((packed));
-
-enum {
-	TX_SUCCESS              = 0,
-	TX_DMA_ERROR            = BIT(7),
-	TX_DISABLED             = BIT(6),
-	TX_RETRY_EXCEEDED       = BIT(5),
-	TX_TIMEOUT              = BIT(4),
-	TX_KEY_NOT_FOUND        = BIT(3),
-	TX_ENCRYPT_FAIL         = BIT(2),
-	TX_UNAVAILABLE_PRIORITY = BIT(1),
-};
-
-struct tx_result {
-	/*
-	 * Ownership synchronization between the host and
-	 * the firmware. If done_1 and done_2 are cleared,
-	 * owned by the FW (no info ready).
-	 */
-	u8 done_1;
-
-	/* same as double_buffer_desc->id */
-	u8 id;
-
-	/*
-	 * Total air access duration consumed by this
-	 * packet, including all retries and overheads.
-	 */
-	u16 medium_usage;
-
-	/* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
-	u32 medium_delay;
-
-	/* Time between host xfer and tx complete */
-	u32 fw_hnadling_time;
-
-	/* The LS-byte of the last TKIP sequence number. */
-	u8 lsb_seq_num;
-
-	/* Retry count */
-	u8 ack_failures;
-
-	/* At which rate we got a ACK */
-	u16 rate;
-
-	u16 reserved;
-
-	/* TX_* */
-	u8 status;
-
-	/* See done_1 */
-	u8 done_2;
-} __attribute__ ((packed));
-
-void wl12xx_tx_work(struct work_struct *work);
-void wl12xx_tx_complete(struct wl12xx *wl);
-void wl12xx_tx_flush(struct wl12xx *wl);
-
-#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251.c b/drivers/net/wireless/wl12xx/wl1251.c
deleted file mode 100644
index ce1561a..0000000
--- a/drivers/net/wireless/wl12xx/wl1251.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * 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/kernel.h>
-#include <linux/module.h>
-
-#include "wl1251.h"
-#include "reg.h"
-#include "spi.h"
-#include "boot.h"
-#include "event.h"
-#include "acx.h"
-#include "tx.h"
-#include "rx.h"
-#include "ps.h"
-#include "init.h"
-
-static struct wl12xx_partition_set wl1251_part_table[PART_TABLE_LEN] = {
-	[PART_DOWN] = {
-		.mem = {
-			.start = 0x00000000,
-			.size  = 0x00016800
-		},
-		.reg = {
-			.start = REGISTERS_BASE,
-			.size  = REGISTERS_DOWN_SIZE
-		},
-	},
-
-	[PART_WORK] = {
-		.mem = {
-			.start = 0x00028000,
-			.size  = 0x00014000
-		},
-		.reg = {
-			.start = REGISTERS_BASE,
-			.size  = REGISTERS_WORK_SIZE
-		},
-	},
-
-	/* WL1251 doesn't use the DRPW partition, so we don't set it here */
-};
-
-static enum wl12xx_acx_int_reg wl1251_acx_reg_table[ACX_REG_TABLE_LEN] = {
-	[ACX_REG_INTERRUPT_TRIG]     = (REGISTERS_BASE + 0x0474),
-	[ACX_REG_INTERRUPT_TRIG_H]   = (REGISTERS_BASE + 0x0478),
-	[ACX_REG_INTERRUPT_MASK]     = (REGISTERS_BASE + 0x0494),
-	[ACX_REG_HINT_MASK_SET]      = (REGISTERS_BASE + 0x0498),
-	[ACX_REG_HINT_MASK_CLR]      = (REGISTERS_BASE + 0x049C),
-	[ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
-	[ACX_REG_INTERRUPT_CLEAR]    = (REGISTERS_BASE + 0x04A4),
-	[ACX_REG_INTERRUPT_ACK]      = (REGISTERS_BASE + 0x04A8),
-	[ACX_REG_SLV_SOFT_RESET]     = (REGISTERS_BASE + 0x0000),
-	[ACX_REG_EE_START]           = (REGISTERS_BASE + 0x080C),
-	[ACX_REG_ECPU_CONTROL]       = (REGISTERS_BASE + 0x0804)
-};
-
-static int wl1251_upload_firmware(struct wl12xx *wl)
-{
-	struct wl12xx_partition_set *p_table = wl->chip.p_table;
-	int addr, chunk_num, partition_limit;
-	size_t fw_data_len;
-	u8 *p;
-
-	/* whal_FwCtrl_LoadFwImageSm() */
-
-	wl12xx_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
-		     wl12xx_reg_read32(wl, CHIP_ID_B));
-
-	/* 10.0 check firmware length and set partition */
-	fw_data_len =  (wl->fw[4] << 24) | (wl->fw[5] << 16) |
-		(wl->fw[6] << 8) | (wl->fw[7]);
-
-	wl12xx_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
-		CHUNK_SIZE);
-
-	if ((fw_data_len % 4) != 0) {
-		wl12xx_error("firmware length not multiple of four");
-		return -EIO;
-	}
-
-	wl12xx_set_partition(wl,
-			     p_table[PART_DOWN].mem.start,
-			     p_table[PART_DOWN].mem.size,
-			     p_table[PART_DOWN].reg.start,
-			     p_table[PART_DOWN].reg.size);
-
-	/* 10.1 set partition limit and chunk num */
-	chunk_num = 0;
-	partition_limit = p_table[PART_DOWN].mem.size;
-
-	while (chunk_num < fw_data_len / CHUNK_SIZE) {
-		/* 10.2 update partition, if needed */
-		addr = p_table[PART_DOWN].mem.start +
-			(chunk_num + 2) * CHUNK_SIZE;
-		if (addr > partition_limit) {
-			addr = p_table[PART_DOWN].mem.start +
-				chunk_num * CHUNK_SIZE;
-			partition_limit = chunk_num * CHUNK_SIZE +
-				p_table[PART_DOWN].mem.size;
-			wl12xx_set_partition(wl,
-					     addr,
-					     p_table[PART_DOWN].mem.size,
-					     p_table[PART_DOWN].reg.start,
-					     p_table[PART_DOWN].reg.size);
-		}
-
-		/* 10.3 upload the chunk */
-		addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
-		p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
-		wl12xx_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
-			     p, addr);
-		wl12xx_spi_mem_write(wl, addr, p, CHUNK_SIZE);
-
-		chunk_num++;
-	}
-
-	/* 10.4 upload the last chunk */
-	addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
-	p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
-	wl12xx_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
-		     fw_data_len % CHUNK_SIZE, p, addr);
-	wl12xx_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
-
-	return 0;
-}
-
-static int wl1251_upload_nvs(struct wl12xx *wl)
-{
-	size_t nvs_len, nvs_bytes_written, burst_len;
-	int nvs_start, i;
-	u32 dest_addr, val;
-	u8 *nvs_ptr, *nvs;
-
-	nvs = wl->nvs;
-	if (nvs == NULL)
-		return -ENODEV;
-
-	nvs_ptr = nvs;
-
-	nvs_len = wl->nvs_len;
-	nvs_start = wl->fw_len;
-
-	/*
-	 * Layout before the actual NVS tables:
-	 * 1 byte : burst length.
-	 * 2 bytes: destination address.
-	 * n bytes: data to burst copy.
-	 *
-	 * This is ended by a 0 length, then the NVS tables.
-	 */
-
-	while (nvs_ptr[0]) {
-		burst_len = nvs_ptr[0];
-		dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
-
-		/* We move our pointer to the data */
-		nvs_ptr += 3;
-
-		for (i = 0; i < burst_len; i++) {
-			val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
-			       | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
-
-			wl12xx_debug(DEBUG_BOOT,
-				     "nvs burst write 0x%x: 0x%x",
-				     dest_addr, val);
-			wl12xx_mem_write32(wl, dest_addr, val);
-
-			nvs_ptr += 4;
-			dest_addr += 4;
-		}
-	}
-
-	/*
-	 * We've reached the first zero length, the first NVS table
-	 * is 7 bytes further.
-	 */
-	nvs_ptr += 7;
-	nvs_len -= nvs_ptr - nvs;
-	nvs_len = ALIGN(nvs_len, 4);
-
-	/* Now we must set the partition correctly */
-	wl12xx_set_partition(wl, nvs_start,
-			     wl->chip.p_table[PART_DOWN].mem.size,
-			     wl->chip.p_table[PART_DOWN].reg.start,
-			     wl->chip.p_table[PART_DOWN].reg.size);
-
-	/* And finally we upload the NVS tables */
-	nvs_bytes_written = 0;
-	while (nvs_bytes_written < nvs_len) {
-		val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
-		       | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
-
-		val = cpu_to_le32(val);
-
-		wl12xx_debug(DEBUG_BOOT,
-			     "nvs write table 0x%x: 0x%x",
-			     nvs_start, val);
-		wl12xx_mem_write32(wl, nvs_start, val);
-
-		nvs_ptr += 4;
-		nvs_bytes_written += 4;
-		nvs_start += 4;
-	}
-
-	return 0;
-}
-
-static int wl1251_boot(struct wl12xx *wl)
-{
-	int ret = 0, minor_minor_e2_ver;
-	u32 tmp, boot_data;
-
-	ret = wl12xx_boot_soft_reset(wl);
-	if (ret < 0)
-		goto out;
-
-	/* 2. start processing NVS file */
-	ret = wl->chip.op_upload_nvs(wl);
-	if (ret < 0)
-		goto out;
-
-	/* write firmware's last address (ie. it's length) to
-	 * ACX_EEPROMLESS_IND_REG */
-	wl12xx_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
-
-	/* 6. read the EEPROM parameters */
-	tmp = wl12xx_reg_read32(wl, SCR_PAD2);
-
-	/* 7. read bootdata */
-	wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
-	wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
-	tmp = wl12xx_reg_read32(wl, SCR_PAD3);
-
-	/* 8. check bootdata and call restart sequence */
-	wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
-	minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
-
-	wl12xx_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
-		     "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
-		     wl->boot_attr.radio_type, wl->boot_attr.major,
-		     wl->boot_attr.minor, minor_minor_e2_ver);
-
-	ret = wl12xx_boot_init_seq(wl);
-	if (ret < 0)
-		goto out;
-
-	/* 9. NVS processing done */
-	boot_data = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
-
-	wl12xx_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
-
-	/* 10. check that ECPU_CONTROL_HALT bits are set in
-	 * pWhalBus->uBootData and start uploading firmware
-	 */
-	if ((boot_data & ECPU_CONTROL_HALT) == 0) {
-		wl12xx_error("boot failed, ECPU_CONTROL_HALT not set");
-		ret = -EIO;
-		goto out;
-	}
-
-	ret = wl->chip.op_upload_fw(wl);
-	if (ret < 0)
-		goto out;
-
-	/* 10.5 start firmware */
-	ret = wl12xx_boot_run_firmware(wl);
-	if (ret < 0)
-		goto out;
-
-	/* Get and save the firmware version */
-	wl12xx_acx_fw_version(wl, wl->chip.fw_ver, sizeof(wl->chip.fw_ver));
-
-out:
-	return ret;
-}
-
-static int wl1251_mem_cfg(struct wl12xx *wl)
-{
-	struct wl1251_acx_config_memory mem_conf;
-	int ret, i;
-
-	wl12xx_debug(DEBUG_ACX, "wl1251 mem cfg");
-
-	/* memory config */
-	mem_conf.mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
-	mem_conf.mem_config.rx_mem_block_num = 35;
-	mem_conf.mem_config.tx_min_mem_block_num = 64;
-	mem_conf.mem_config.num_tx_queues = MAX_TX_QUEUES;
-	mem_conf.mem_config.host_if_options = HOSTIF_PKT_RING;
-	mem_conf.mem_config.num_ssid_profiles = 1;
-	mem_conf.mem_config.debug_buffer_size =
-		cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
-
-	/* RX queue config */
-	mem_conf.rx_queue_config.dma_address = 0;
-	mem_conf.rx_queue_config.num_descs = ACX_RX_DESC_DEF;
-	mem_conf.rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
-	mem_conf.rx_queue_config.type = DEFAULT_RXQ_TYPE;
-
-	/* TX queue config */
-	for (i = 0; i < MAX_TX_QUEUES; i++) {
-		mem_conf.tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
-		mem_conf.tx_queue_config[i].attributes = i;
-	}
-
-	mem_conf.header.id = ACX_MEM_CFG;
-	mem_conf.header.len = sizeof(struct wl1251_acx_config_memory) -
-		sizeof(struct acx_header);
-	mem_conf.header.len -=
-		(MAX_TX_QUEUE_CONFIGS - mem_conf.mem_config.num_tx_queues) *
-		sizeof(struct wl1251_acx_tx_queue_config);
-
-	ret = wl12xx_cmd_configure(wl, &mem_conf,
-				   sizeof(struct wl1251_acx_config_memory));
-	if (ret < 0)
-		wl12xx_warning("wl1251 mem config failed: %d", ret);
-
-	return ret;
-}
-
-static int wl1251_hw_init_mem_config(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl1251_mem_cfg(wl);
-	if (ret < 0)
-		return ret;
-
-	wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
-					  GFP_KERNEL);
-	if (!wl->target_mem_map) {
-		wl12xx_error("couldn't allocate target memory map");
-		return -ENOMEM;
-	}
-
-	/* we now ask for the firmware built memory map */
-	ret = wl12xx_acx_mem_map(wl, wl->target_mem_map,
-				 sizeof(struct wl1251_acx_mem_map));
-	if (ret < 0) {
-		wl12xx_error("couldn't retrieve firmware memory map");
-		kfree(wl->target_mem_map);
-		wl->target_mem_map = NULL;
-		return ret;
-	}
-
-	return 0;
-}
-
-static void wl1251_set_ecpu_ctrl(struct wl12xx *wl, u32 flag)
-{
-	u32 cpu_ctrl;
-
-	/* 10.5.0 run the firmware (I) */
-	cpu_ctrl = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
-
-	/* 10.5.1 run the firmware (II) */
-	cpu_ctrl &= ~flag;
-	wl12xx_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
-}
-
-static void wl1251_target_enable_interrupts(struct wl12xx *wl)
-{
-	/* Enable target's interrupts */
-	wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
-		WL1251_ACX_INTR_RX1_DATA |
-		WL1251_ACX_INTR_TX_RESULT |
-		WL1251_ACX_INTR_EVENT_A |
-		WL1251_ACX_INTR_EVENT_B |
-		WL1251_ACX_INTR_INIT_COMPLETE;
-	wl12xx_boot_target_enable_interrupts(wl);
-}
-
-static void wl1251_irq_work(struct work_struct *work)
-{
-	u32 intr;
-	struct wl12xx *wl =
-		container_of(work, struct wl12xx, irq_work);
-
-	mutex_lock(&wl->mutex);
-
-	wl12xx_debug(DEBUG_IRQ, "IRQ work");
-
-	if (wl->state == WL12XX_STATE_OFF)
-		goto out;
-
-	wl12xx_ps_elp_wakeup(wl);
-
-	wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
-
-	intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
-	wl12xx_debug(DEBUG_IRQ, "intr: 0x%x", intr);
-
-	if (wl->data_path) {
-		wl12xx_spi_mem_read(wl, wl->data_path->rx_control_addr,
-				    &wl->rx_counter, sizeof(u32));
-
-		/* We handle a frmware bug here */
-		switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
-		case 0:
-			wl12xx_debug(DEBUG_IRQ, "RX: FW and host in sync");
-			intr &= ~WL1251_ACX_INTR_RX0_DATA;
-			intr &= ~WL1251_ACX_INTR_RX1_DATA;
-			break;
-		case 1:
-			wl12xx_debug(DEBUG_IRQ, "RX: FW +1");
-			intr |= WL1251_ACX_INTR_RX0_DATA;
-			intr &= ~WL1251_ACX_INTR_RX1_DATA;
-			break;
-		case 2:
-			wl12xx_debug(DEBUG_IRQ, "RX: FW +2");
-			intr |= WL1251_ACX_INTR_RX0_DATA;
-			intr |= WL1251_ACX_INTR_RX1_DATA;
-			break;
-		default:
-			wl12xx_warning("RX: FW and host out of sync: %d",
-				       wl->rx_counter - wl->rx_handled);
-			break;
-		}
-
-		wl->rx_handled = wl->rx_counter;
-
-
-		wl12xx_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter);
-	}
-
-	intr &= wl->intr_mask;
-
-	if (intr == 0) {
-		wl12xx_debug(DEBUG_IRQ, "INTR is 0");
-		wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
-				   ~(wl->intr_mask));
-
-		goto out_sleep;
-	}
-
-	if (intr & WL1251_ACX_INTR_RX0_DATA) {
-		wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
-		wl12xx_rx(wl);
-	}
-
-	if (intr & WL1251_ACX_INTR_RX1_DATA) {
-		wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
-		wl12xx_rx(wl);
-	}
-
-	if (intr & WL1251_ACX_INTR_TX_RESULT) {
-		wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
-		wl12xx_tx_complete(wl);
-	}
-
-	if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
-		wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
-		if (intr & WL1251_ACX_INTR_EVENT_A)
-			wl12xx_event_handle(wl, 0);
-		else
-			wl12xx_event_handle(wl, 1);
-	}
-
-	if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
-		wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");
-
-	wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
-
-out_sleep:
-	wl12xx_ps_elp_sleep(wl);
-out:
-	mutex_unlock(&wl->mutex);
-}
-
-static int wl1251_hw_init_txq_fill(u8 qid,
-				   struct acx_tx_queue_qos_config *config,
-				   u32 num_blocks)
-{
-	config->qid = qid;
-
-	switch (qid) {
-	case QOS_AC_BE:
-		config->high_threshold =
-			(QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
-		config->low_threshold =
-			(QOS_TX_LOW_BE_DEF * num_blocks) / 100;
-		break;
-	case QOS_AC_BK:
-		config->high_threshold =
-			(QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
-		config->low_threshold =
-			(QOS_TX_LOW_BK_DEF * num_blocks) / 100;
-		break;
-	case QOS_AC_VI:
-		config->high_threshold =
-			(QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
-		config->low_threshold =
-			(QOS_TX_LOW_VI_DEF * num_blocks) / 100;
-		break;
-	case QOS_AC_VO:
-		config->high_threshold =
-			(QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
-		config->low_threshold =
-			(QOS_TX_LOW_VO_DEF * num_blocks) / 100;
-		break;
-	default:
-		wl12xx_error("Invalid TX queue id: %d", qid);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int wl1251_hw_init_tx_queue_config(struct wl12xx *wl)
-{
-	struct acx_tx_queue_qos_config config;
-	struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
-	int ret, i;
-
-	wl12xx_debug(DEBUG_ACX, "acx tx queue config");
-
-	config.header.id = ACX_TX_QUEUE_CFG;
-	config.header.len = sizeof(struct acx_tx_queue_qos_config) -
-		sizeof(struct acx_header);
-
-	for (i = 0; i < MAX_NUM_OF_AC; i++) {
-		ret = wl1251_hw_init_txq_fill(i, &config,
-					      wl_mem_map->num_tx_mem_blocks);
-		if (ret < 0)
-			return ret;
-
-		ret = wl12xx_cmd_configure(wl, &config, sizeof(config));
-		if (ret < 0)
-			return ret;
-	}
-
-	return 0;
-}
-
-static int wl1251_hw_init_data_path_config(struct wl12xx *wl)
-{
-	int ret;
-
-	/* asking for the data path parameters */
-	wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
-				GFP_KERNEL);
-	if (!wl->data_path) {
-		wl12xx_error("Couldnt allocate data path parameters");
-		return -ENOMEM;
-	}
-
-	ret = wl12xx_acx_data_path_params(wl, wl->data_path);
-	if (ret < 0) {
-		kfree(wl->data_path);
-		wl->data_path = NULL;
-		return ret;
-	}
-
-	return 0;
-}
-
-static int wl1251_hw_init(struct wl12xx *wl)
-{
-	struct wl1251_acx_mem_map *wl_mem_map;
-	int ret;
-
-	ret = wl12xx_hw_init_hwenc_config(wl);
-	if (ret < 0)
-		return ret;
-
-	/* Template settings */
-	ret = wl12xx_hw_init_templates_config(wl);
-	if (ret < 0)
-		return ret;
-
-	/* Default memory configuration */
-	ret = wl1251_hw_init_mem_config(wl);
-	if (ret < 0)
-		return ret;
-
-	/* Default data path configuration  */
-	ret = wl1251_hw_init_data_path_config(wl);
-	if (ret < 0)
-		goto out_free_memmap;
-
-	/* RX config */
-	ret = wl12xx_hw_init_rx_config(wl,
-				       RX_CFG_PROMISCUOUS | RX_CFG_TSF,
-				       RX_FILTER_OPTION_DEF);
-	/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
-	   RX_FILTER_OPTION_FILTER_ALL); */
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* TX queues config */
-	ret = wl1251_hw_init_tx_queue_config(wl);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* PHY layer config */
-	ret = wl12xx_hw_init_phy_config(wl);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* Beacon filtering */
-	ret = wl12xx_hw_init_beacon_filter(wl);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* Bluetooth WLAN coexistence */
-	ret = wl12xx_hw_init_pta(wl);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* Energy detection */
-	ret = wl12xx_hw_init_energy_detection(wl);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* Beacons and boradcast settings */
-	ret = wl12xx_hw_init_beacon_broadcast(wl);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* Enable data path */
-	ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	/* Default power state */
-	ret = wl12xx_hw_init_power_auth(wl);
-	if (ret < 0)
-		goto out_free_data_path;
-
-	wl_mem_map = wl->target_mem_map;
-	wl12xx_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
-		    wl_mem_map->num_tx_mem_blocks,
-		    wl->data_path->tx_control_addr,
-		    wl_mem_map->num_rx_mem_blocks,
-		    wl->data_path->rx_control_addr);
-
-	return 0;
-
- out_free_data_path:
-	kfree(wl->data_path);
-
- out_free_memmap:
-	kfree(wl->target_mem_map);
-
-	return ret;
-}
-
-static int wl1251_plt_init(struct wl12xx *wl)
-{
-	int ret;
-
-	ret = wl1251_hw_init_mem_config(wl);
-	if (ret < 0)
-		return ret;
-
-	ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
-	if (ret < 0)
-		return ret;
-
-	return 0;
-}
-
-void wl1251_setup(struct wl12xx *wl)
-{
-	/* FIXME: Is it better to use strncpy here or is this ok? */
-	wl->chip.fw_filename = WL1251_FW_NAME;
-	wl->chip.nvs_filename = WL1251_NVS_NAME;
-
-	/* Now we know what chip we're using, so adjust the power on sleep
-	 * time accordingly */
-	wl->chip.power_on_sleep = WL1251_POWER_ON_SLEEP;
-
-	wl->chip.intr_cmd_complete = WL1251_ACX_INTR_CMD_COMPLETE;
-	wl->chip.intr_init_complete = WL1251_ACX_INTR_INIT_COMPLETE;
-
-	wl->chip.op_upload_nvs = wl1251_upload_nvs;
-	wl->chip.op_upload_fw = wl1251_upload_firmware;
-	wl->chip.op_boot = wl1251_boot;
-	wl->chip.op_set_ecpu_ctrl = wl1251_set_ecpu_ctrl;
-	wl->chip.op_target_enable_interrupts = wl1251_target_enable_interrupts;
-	wl->chip.op_hw_init = wl1251_hw_init;
-	wl->chip.op_plt_init = wl1251_plt_init;
-
-	wl->chip.p_table = wl1251_part_table;
-	wl->chip.acx_reg_table = wl1251_acx_reg_table;
-
-	INIT_WORK(&wl->irq_work, wl1251_irq_work);
-}
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
index 1f4a443..998e4b6 100644
--- a/drivers/net/wireless/wl12xx/wl1251.h
+++ b/drivers/net/wireless/wl12xx/wl1251.h
@@ -1,7 +1,8 @@
 /*
- * This file is part of wl12xx
+ * This file is part of wl1251
  *
- * Copyright (C) 2008 Nokia Corporation
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008-2009 Nokia Corporation
  *
  * Contact: Kalle Valo <kalle.valo@nokia.com>
  *
@@ -24,142 +25,400 @@
 #ifndef __WL1251_H__
 #define __WL1251_H__
 
+#include <linux/mutex.h>
+#include <linux/list.h>
 #include <linux/bitops.h>
-
-#include "wl12xx.h"
-#include "acx.h"
-
-#define WL1251_FW_NAME "wl1251-fw.bin"
-#define WL1251_NVS_NAME "wl1251-nvs.bin"
-
-#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
-
-void wl1251_setup(struct wl12xx *wl);
-
-
-struct wl1251_acx_memory {
-	__le16 num_stations; /* number of STAs to be supported. */
-	u16 reserved_1;
+#include <net/mac80211.h>
+
+#define DRIVER_NAME "wl1251"
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+	DEBUG_NONE	= 0,
+	DEBUG_IRQ	= BIT(0),
+	DEBUG_SPI	= BIT(1),
+	DEBUG_BOOT	= BIT(2),
+	DEBUG_MAILBOX	= BIT(3),
+	DEBUG_NETLINK	= BIT(4),
+	DEBUG_EVENT	= BIT(5),
+	DEBUG_TX	= BIT(6),
+	DEBUG_RX	= BIT(7),
+	DEBUG_SCAN	= BIT(8),
+	DEBUG_CRYPT	= BIT(9),
+	DEBUG_PSM	= BIT(10),
+	DEBUG_MAC80211	= BIT(11),
+	DEBUG_CMD	= BIT(12),
+	DEBUG_ACX	= BIT(13),
+	DEBUG_ALL	= ~0,
+};
+
+#define DEBUG_LEVEL (DEBUG_NONE)
+
+#define DEBUG_DUMP_LIMIT 1024
+
+#define wl1251_error(fmt, arg...) \
+	printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define wl1251_warning(fmt, arg...) \
+	printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define wl1251_notice(fmt, arg...) \
+	printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl1251_info(fmt, arg...) \
+	printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl1251_debug(level, fmt, arg...) \
+	do { \
+		if (level & DEBUG_LEVEL) \
+			printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+	} while (0)
+
+#define wl1251_dump(level, prefix, buf, len)	\
+	do { \
+		if (level & DEBUG_LEVEL) \
+			print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+				       DUMP_PREFIX_OFFSET, 16, 1,	\
+				       buf,				\
+				       min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+				       0);				\
+	} while (0)
+
+#define wl1251_dump_ascii(level, prefix, buf, len)	\
+	do { \
+		if (level & DEBUG_LEVEL) \
+			print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+				       DUMP_PREFIX_OFFSET, 16, 1,	\
+				       buf,				\
+				       min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+				       true);				\
+	} while (0)
+
+#define WL1251_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN |	\
+				  CFG_BSSID_FILTER_EN)
+
+#define WL1251_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN |  \
+				  CFG_RX_MGMT_EN |  \
+				  CFG_RX_DATA_EN |  \
+				  CFG_RX_CTL_EN |   \
+				  CFG_RX_BCN_EN |   \
+				  CFG_RX_AUTH_EN |  \
+				  CFG_RX_ASSOC_EN)
+
+#define WL1251_BUSY_WORD_LEN 8
+
+struct boot_attr {
+	u32 radio_type;
+	u8 mac_clock;
+	u8 arm_clock;
+	int firmware_debug;
+	u32 minor;
+	u32 major;
+	u32 bugfix;
+};
+
+enum wl1251_state {
+	WL1251_STATE_OFF,
+	WL1251_STATE_ON,
+	WL1251_STATE_PLT,
+};
+
+enum wl1251_partition_type {
+	PART_DOWN,
+	PART_WORK,
+	PART_DRPW,
+
+	PART_TABLE_LEN
+};
+
+struct wl1251_partition {
+	u32 size;
+	u32 start;
+};
+
+struct wl1251_partition_set {
+	struct wl1251_partition mem;
+	struct wl1251_partition reg;
+};
+
+struct wl1251;
+
+struct wl1251_stats {
+	struct acx_statistics *fw_stats;
+	unsigned long fw_stats_update;
+
+	unsigned int retry_count;
+	unsigned int excessive_retries;
+};
+
+struct wl1251_debugfs {
+	struct dentry *rootdir;
+	struct dentry *fw_statistics;
+
+	struct dentry *tx_internal_desc_overflow;
+
+	struct dentry *rx_out_of_mem;
+	struct dentry *rx_hdr_overflow;
+	struct dentry *rx_hw_stuck;
+	struct dentry *rx_dropped;
+	struct dentry *rx_fcs_err;
+	struct dentry *rx_xfr_hint_trig;
+	struct dentry *rx_path_reset;
+	struct dentry *rx_reset_counter;
+
+	struct dentry *dma_rx_requested;
+	struct dentry *dma_rx_errors;
+	struct dentry *dma_tx_requested;
+	struct dentry *dma_tx_errors;
+
+	struct dentry *isr_cmd_cmplt;
+	struct dentry *isr_fiqs;
+	struct dentry *isr_rx_headers;
+	struct dentry *isr_rx_mem_overflow;
+	struct dentry *isr_rx_rdys;
+	struct dentry *isr_irqs;
+	struct dentry *isr_tx_procs;
+	struct dentry *isr_decrypt_done;
+	struct dentry *isr_dma0_done;
+	struct dentry *isr_dma1_done;
+	struct dentry *isr_tx_exch_complete;
+	struct dentry *isr_commands;
+	struct dentry *isr_rx_procs;
+	struct dentry *isr_hw_pm_mode_changes;
+	struct dentry *isr_host_acknowledges;
+	struct dentry *isr_pci_pm;
+	struct dentry *isr_wakeups;
+	struct dentry *isr_low_rssi;
+
+	struct dentry *wep_addr_key_count;
+	struct dentry *wep_default_key_count;
+	/* skipping wep.reserved */
+	struct dentry *wep_key_not_found;
+	struct dentry *wep_decrypt_fail;
+	struct dentry *wep_packets;
+	struct dentry *wep_interrupt;
+
+	struct dentry *pwr_ps_enter;
+	struct dentry *pwr_elp_enter;
+	struct dentry *pwr_missing_bcns;
+	struct dentry *pwr_wake_on_host;
+	struct dentry *pwr_wake_on_timer_exp;
+	struct dentry *pwr_tx_with_ps;
+	struct dentry *pwr_tx_without_ps;
+	struct dentry *pwr_rcvd_beacons;
+	struct dentry *pwr_power_save_off;
+	struct dentry *pwr_enable_ps;
+	struct dentry *pwr_disable_ps;
+	struct dentry *pwr_fix_tsf_ps;
+	/* skipping cont_miss_bcns_spread for now */
+	struct dentry *pwr_rcvd_awake_beacons;
+
+	struct dentry *mic_rx_pkts;
+	struct dentry *mic_calc_failure;
+
+	struct dentry *aes_encrypt_fail;
+	struct dentry *aes_decrypt_fail;
+	struct dentry *aes_encrypt_packets;
+	struct dentry *aes_decrypt_packets;
+	struct dentry *aes_encrypt_interrupt;
+	struct dentry *aes_decrypt_interrupt;
+
+	struct dentry *event_heart_beat;
+	struct dentry *event_calibration;
+	struct dentry *event_rx_mismatch;
+	struct dentry *event_rx_mem_empty;
+	struct dentry *event_rx_pool;
+	struct dentry *event_oom_late;
+	struct dentry *event_phy_transmit_error;
+	struct dentry *event_tx_stuck;
+
+	struct dentry *ps_pspoll_timeouts;
+	struct dentry *ps_upsd_timeouts;
+	struct dentry *ps_upsd_max_sptime;
+	struct dentry *ps_upsd_max_apturn;
+	struct dentry *ps_pspoll_max_apturn;
+	struct dentry *ps_pspoll_utilization;
+	struct dentry *ps_upsd_utilization;
+
+	struct dentry *rxpipe_rx_prep_beacon_drop;
+	struct dentry *rxpipe_descr_host_int_trig_rx_data;
+	struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
+	struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
+	struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
+
+	struct dentry *tx_queue_len;
+
+	struct dentry *retry_count;
+	struct dentry *excessive_retries;
+};
+
+struct wl1251_if_operations {
+	void (*read)(struct wl1251 *wl, int addr, void *buf, size_t len);
+	void (*write)(struct wl1251 *wl, int addr, void *buf, size_t len);
+	void (*reset)(struct wl1251 *wl);
+	void (*enable_irq)(struct wl1251 *wl);
+	void (*disable_irq)(struct wl1251 *wl);
+};
+
+struct wl1251 {
+	struct ieee80211_hw *hw;
+	bool mac80211_registered;
+
+	void *if_priv;
+	const struct wl1251_if_operations *if_ops;
+
+	void (*set_power)(bool enable);
+	int irq;
+
+	enum wl1251_state state;
+	struct mutex mutex;
+
+	int physical_mem_addr;
+	int physical_reg_addr;
+	int virtual_mem_addr;
+	int virtual_reg_addr;
+
+	int cmd_box_addr;
+	int event_box_addr;
+	struct boot_attr boot_attr;
+
+	u8 *fw;
+	size_t fw_len;
+	u8 *nvs;
+	size_t nvs_len;
+
+	u8 bssid[ETH_ALEN];
+	u8 mac_addr[ETH_ALEN];
+	u8 bss_type;
+	u8 listen_int;
+	int channel;
+
+	void *target_mem_map;
+	struct acx_data_path_params_resp *data_path;
+
+	/* Number of TX packets transferred to the FW, modulo 16 */
+	u32 data_in_count;
+
+	/* Frames scheduled for transmission, not handled yet */
+	struct sk_buff_head tx_queue;
+	bool tx_queue_stopped;
+
+	struct work_struct tx_work;
+	struct work_struct filter_work;
+
+	/* Pending TX frames */
+	struct sk_buff *tx_frames[16];
 
 	/*
-	 * Nmber of memory buffers for the RX mem pool.
-	 * The actual number may be less if there are
-	 * not enough blocks left for the minimum num
-	 * of TX ones.
+	 * Index pointing to the next TX complete entry
+	 * in the cyclic XT complete array we get from
+	 * the FW.
 	 */
-	u8 rx_mem_block_num;
-	u8 reserved_2;
-	u8 num_tx_queues; /* From 1 to 16 */
-	u8 host_if_options; /* HOST_IF* */
-	u8 tx_min_mem_block_num;
-	u8 num_ssid_profiles;
-	__le16 debug_buffer_size;
-} __attribute__ ((packed));
+	u32 next_tx_complete;
 
+	/* FW Rx counter */
+	u32 rx_counter;
 
-#define ACX_RX_DESC_MIN                1
-#define ACX_RX_DESC_MAX                127
-#define ACX_RX_DESC_DEF                32
-struct wl1251_acx_rx_queue_config {
-	u8 num_descs;
-	u8 pad;
-	u8 type;
-	u8 priority;
-	__le32 dma_address;
-} __attribute__ ((packed));
+	/* Rx frames handled */
+	u32 rx_handled;
 
-#define ACX_TX_DESC_MIN                1
-#define ACX_TX_DESC_MAX                127
-#define ACX_TX_DESC_DEF                16
-struct wl1251_acx_tx_queue_config {
-    u8 num_descs;
-    u8 pad[2];
-    u8 attributes;
-} __attribute__ ((packed));
+	/* Current double buffer */
+	u32 rx_current_buffer;
+	u32 rx_last_id;
 
-#define MAX_TX_QUEUE_CONFIGS 5
-#define MAX_TX_QUEUES 4
-struct wl1251_acx_config_memory {
-	struct acx_header header;
+	/* The target interrupt mask */
+	u32 intr_mask;
+	struct work_struct irq_work;
 
-	struct wl1251_acx_memory mem_config;
-	struct wl1251_acx_rx_queue_config rx_queue_config;
-	struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
-} __attribute__ ((packed));
+	/* The mbox event mask */
+	u32 event_mask;
 
-struct wl1251_acx_mem_map {
-	struct acx_header header;
+	/* Mailbox pointers */
+	u32 mbox_ptr[2];
 
-	void *code_start;
-	void *code_end;
+	/* Are we currently scanning */
+	bool scanning;
 
-	void *wep_defkey_start;
-	void *wep_defkey_end;
+	/* Our association ID */
+	u16 aid;
 
-	void *sta_table_start;
-	void *sta_table_end;
+	/* Default key (for WEP) */
+	u32 default_key;
 
-	void *packet_template_start;
-	void *packet_template_end;
+	unsigned int tx_mgmt_frm_rate;
+	unsigned int tx_mgmt_frm_mod;
 
-	void *queue_memory_start;
-	void *queue_memory_end;
+	unsigned int rx_config;
+	unsigned int rx_filter;
 
-	void *packet_memory_pool_start;
-	void *packet_memory_pool_end;
+	/* is firmware in elp mode */
+	bool elp;
 
-	void *debug_buffer1_start;
-	void *debug_buffer1_end;
+	/* we can be in psm, but not in elp, we have to differentiate */
+	bool psm;
 
-	void *debug_buffer2_start;
-	void *debug_buffer2_end;
+	/* PSM mode requested */
+	bool psm_requested;
 
-	/* Number of blocks FW allocated for TX packets */
-	u32 num_tx_mem_blocks;
+	u16 beacon_int;
+	u8 dtim_period;
 
-	/* Number of blocks FW allocated for RX packets */
-	u32 num_rx_mem_blocks;
-} __attribute__ ((packed));
+	/* in dBm */
+	int power_level;
 
-/*************************************************************************
+	struct wl1251_stats stats;
+	struct wl1251_debugfs debugfs;
 
-    Host Interrupt Register (WiLink -> Host)
+	u32 buffer_32;
+	u32 buffer_cmd;
+	u8 buffer_busyword[WL1251_BUSY_WORD_LEN];
+	struct wl1251_rx_descriptor *rx_descriptor;
 
-**************************************************************************/
+	u32 chip_id;
+	char fw_ver[21];
+};
 
-/* RX packet is ready in Xfer buffer #0 */
-#define WL1251_ACX_INTR_RX0_DATA      BIT(0)
+int wl1251_plt_start(struct wl1251 *wl);
+int wl1251_plt_stop(struct wl1251 *wl);
 
-/* TX result(s) are in the TX complete buffer */
-#define WL1251_ACX_INTR_TX_RESULT	BIT(1)
+struct ieee80211_hw *wl1251_alloc_hw(void);
+int wl1251_free_hw(struct wl1251 *wl);
+int wl1251_init_ieee80211(struct wl1251 *wl);
+void wl1251_enable_interrupts(struct wl1251 *wl);
+void wl1251_disable_interrupts(struct wl1251 *wl);
 
-/* OBSOLETE */
-#define WL1251_ACX_INTR_TX_XFR		BIT(2)
+#define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
+#define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
+#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
 
-/* RX packet is ready in Xfer buffer #1 */
-#define WL1251_ACX_INTR_RX1_DATA	BIT(3)
+#define WL1251_DEFAULT_POWER_LEVEL 20
 
-/* Event was entered to Event MBOX #A */
-#define WL1251_ACX_INTR_EVENT_A		BIT(4)
+#define WL1251_TX_QUEUE_MAX_LENGTH 20
 
-/* Event was entered to Event MBOX #B */
-#define WL1251_ACX_INTR_EVENT_B		BIT(5)
+#define WL1251_DEFAULT_BEACON_INT 100
+#define WL1251_DEFAULT_DTIM_PERIOD 1
 
-/* OBSOLETE */
-#define WL1251_ACX_INTR_WAKE_ON_HOST	BIT(6)
+#define WL1251_DEFAULT_CHANNEL 0
 
-/* Trace meassge on MBOX #A */
-#define WL1251_ACX_INTR_TRACE_A		BIT(7)
+#define CHIP_ID_1251_PG10	           (0x7010101)
+#define CHIP_ID_1251_PG11	           (0x7020101)
+#define CHIP_ID_1251_PG12	           (0x7030101)
+#define CHIP_ID_1271_PG10	           (0x4030101)
+#define CHIP_ID_1271_PG20	           (0x4030111)
 
-/* Trace meassge on MBOX #B */
-#define WL1251_ACX_INTR_TRACE_B		BIT(8)
+#define WL1251_FW_NAME "wl1251-fw.bin"
+#define WL1251_NVS_NAME "wl1251-nvs.bin"
 
-/* Command processing completion */
-#define WL1251_ACX_INTR_CMD_COMPLETE	BIT(9)
+#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
 
-/* Init sequence is done */
-#define WL1251_ACX_INTR_INIT_COMPLETE	BIT(14)
+#define WL1251_PART_DOWN_MEM_START	0x0
+#define WL1251_PART_DOWN_MEM_SIZE	0x16800
+#define WL1251_PART_DOWN_REG_START	REGISTERS_BASE
+#define WL1251_PART_DOWN_REG_SIZE	REGISTERS_DOWN_SIZE
 
-#define WL1251_ACX_INTR_ALL           0xFFFFFFFF
+#define WL1251_PART_WORK_MEM_START	0x28000
+#define WL1251_PART_WORK_MEM_SIZE	0x14000
+#define WL1251_PART_WORK_REG_START	REGISTERS_BASE
+#define WL1251_PART_WORK_REG_SIZE	REGISTERS_WORK_SIZE
 
 #endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
new file mode 100644
index 0000000..10b26c4
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -0,0 +1,918 @@
+#include "wl1251_acx.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+
+#include "wl1251.h"
+#include "wl1251_reg.h"
+#include "wl1251_cmd.h"
+#include "wl1251_ps.h"
+
+int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
+			   u8 mgt_rate, u8 mgt_mod)
+{
+	struct acx_fw_gen_frame_rates *rates;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx frame rates");
+
+	rates = kzalloc(sizeof(*rates), GFP_KERNEL);
+	if (!rates) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	rates->tx_ctrl_frame_rate = ctrl_rate;
+	rates->tx_ctrl_frame_mod = ctrl_mod;
+	rates->tx_mgt_frame_rate = mgt_rate;
+	rates->tx_mgt_frame_mod = mgt_mod;
+
+	ret = wl1251_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
+				   rates, sizeof(*rates));
+	if (ret < 0) {
+		wl1251_error("Failed to set FW rates and modulation");
+		goto out;
+	}
+
+out:
+	kfree(rates);
+	return ret;
+}
+
+
+int wl1251_acx_station_id(struct wl1251 *wl)
+{
+	struct acx_dot11_station_id *mac;
+	int ret, i;
+
+	wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
+
+	mac = kzalloc(sizeof(*mac), GFP_KERNEL);
+	if (!mac) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < ETH_ALEN; i++)
+		mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
+
+	ret = wl1251_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
+	if (ret < 0)
+		goto out;
+
+out:
+	kfree(mac);
+	return ret;
+}
+
+int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
+{
+	struct acx_dot11_default_key *default_key;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
+
+	default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
+	if (!default_key) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	default_key->id = key_id;
+
+	ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
+				   default_key, sizeof(*default_key));
+	if (ret < 0) {
+		wl1251_error("Couldn't set default key");
+		goto out;
+	}
+
+	wl->default_key = key_id;
+
+out:
+	kfree(default_key);
+	return ret;
+}
+
+int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
+				  u8 listen_interval)
+{
+	struct acx_wake_up_condition *wake_up;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx wake up conditions");
+
+	wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
+	if (!wake_up) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	wake_up->wake_up_event = wake_up_event;
+	wake_up->listen_interval = listen_interval;
+
+	ret = wl1251_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
+				   wake_up, sizeof(*wake_up));
+	if (ret < 0) {
+		wl1251_warning("could not set wake up conditions: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(wake_up);
+	return ret;
+}
+
+int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
+{
+	struct acx_sleep_auth *auth;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx sleep auth");
+
+	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
+	if (!auth) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	auth->sleep_auth = sleep_auth;
+
+	ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
+	if (ret < 0)
+		return ret;
+
+out:
+	kfree(auth);
+	return ret;
+}
+
+int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
+{
+	struct acx_revision *rev;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx fw rev");
+
+	rev = kzalloc(sizeof(*rev), GFP_KERNEL);
+	if (!rev) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
+	if (ret < 0) {
+		wl1251_warning("ACX_FW_REV interrogate failed");
+		goto out;
+	}
+
+	/* be careful with the buffer sizes */
+	strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
+
+	/*
+	 * if the firmware version string is exactly
+	 * sizeof(rev->fw_version) long or fw_len is less than
+	 * sizeof(rev->fw_version) it won't be null terminated
+	 */
+	buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
+
+out:
+	kfree(rev);
+	return ret;
+}
+
+int wl1251_acx_tx_power(struct wl1251 *wl, int power)
+{
+	struct acx_current_tx_power *acx;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
+
+	if (power < 0 || power > 25)
+		return -EINVAL;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->current_tx_power = power * 10;
+
+	ret = wl1251_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("configure of tx power failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_feature_cfg(struct wl1251 *wl)
+{
+	struct acx_feature_config *feature;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx feature cfg");
+
+	feature = kzalloc(sizeof(*feature), GFP_KERNEL);
+	if (!feature) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
+	feature->data_flow_options = 0;
+	feature->options = 0;
+
+	ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
+				   feature, sizeof(*feature));
+	if (ret < 0) {
+		wl1251_error("Couldn't set HW encryption");
+		goto out;
+	}
+
+out:
+	kfree(feature);
+	return ret;
+}
+
+int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
+		       size_t len)
+{
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx mem map");
+
+	ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_acx_data_path_params(struct wl1251 *wl,
+				struct acx_data_path_params_resp *resp)
+{
+	struct acx_data_path_params *params;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx data path params");
+
+	params = kzalloc(sizeof(*params), GFP_KERNEL);
+	if (!params) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
+	params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
+
+	params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
+	params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
+
+	params->tx_complete_threshold = 1;
+
+	params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
+
+	params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
+
+	ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
+				   params, sizeof(*params));
+	if (ret < 0)
+		goto out;
+
+	/* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
+	ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
+				     resp, sizeof(*resp));
+
+	if (ret < 0) {
+		wl1251_warning("failed to read data path parameters: %d", ret);
+		goto out;
+	} else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
+		wl1251_warning("data path parameter acx status failed");
+		ret = -EIO;
+		goto out;
+	}
+
+out:
+	kfree(params);
+	return ret;
+}
+
+int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
+{
+	struct acx_rx_msdu_lifetime *acx;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->lifetime = life_time;
+	ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("failed to set rx msdu life time: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
+{
+	struct acx_rx_config *rx_config;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx rx config");
+
+	rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
+	if (!rx_config) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	rx_config->config_options = config;
+	rx_config->filter_options = filter;
+
+	ret = wl1251_cmd_configure(wl, ACX_RX_CFG,
+				   rx_config, sizeof(*rx_config));
+	if (ret < 0) {
+		wl1251_warning("failed to set rx config: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(rx_config);
+	return ret;
+}
+
+int wl1251_acx_pd_threshold(struct wl1251 *wl)
+{
+	struct acx_packet_detection *pd;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx data pd threshold");
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* FIXME: threshold value not set */
+
+	ret = wl1251_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
+	if (ret < 0) {
+		wl1251_warning("failed to set pd threshold: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(pd);
+	return 0;
+}
+
+int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
+{
+	struct acx_slot *slot;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx slot");
+
+	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+	if (!slot) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	slot->wone_index = STATION_WONE_INDEX;
+	slot->slot_time = slot_time;
+
+	ret = wl1251_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
+	if (ret < 0) {
+		wl1251_warning("failed to set slot time: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(slot);
+	return ret;
+}
+
+int wl1251_acx_group_address_tbl(struct wl1251 *wl)
+{
+	struct acx_dot11_grp_addr_tbl *acx;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx group address tbl");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* MAC filtering */
+	acx->enabled = 0;
+	acx->num_groups = 0;
+	memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+
+	ret = wl1251_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("failed to set group addr table: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_service_period_timeout(struct wl1251 *wl)
+{
+	struct acx_rx_timeout *rx_timeout;
+	int ret;
+
+	rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
+	if (!rx_timeout) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	wl1251_debug(DEBUG_ACX, "acx service period timeout");
+
+	rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
+	rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
+
+	ret = wl1251_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
+				   rx_timeout, sizeof(*rx_timeout));
+	if (ret < 0) {
+		wl1251_warning("failed to set service period timeout: %d",
+			       ret);
+		goto out;
+	}
+
+out:
+	kfree(rx_timeout);
+	return ret;
+}
+
+int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
+{
+	struct acx_rts_threshold *rts;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx rts threshold");
+
+	rts = kzalloc(sizeof(*rts), GFP_KERNEL);
+	if (!rts) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	rts->threshold = rts_threshold;
+
+	ret = wl1251_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
+	if (ret < 0) {
+		wl1251_warning("failed to set rts threshold: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(rts);
+	return ret;
+}
+
+int wl1251_acx_beacon_filter_opt(struct wl1251 *wl)
+{
+	struct acx_beacon_filter_option *beacon_filter;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
+
+	beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
+	if (!beacon_filter) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	beacon_filter->enable = 0;
+	beacon_filter->max_num_beacons = 0;
+
+	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
+				   beacon_filter, sizeof(*beacon_filter));
+	if (ret < 0) {
+		wl1251_warning("failed to set beacon filter opt: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(beacon_filter);
+	return ret;
+}
+
+int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
+{
+	struct acx_beacon_filter_ie_table *ie_table;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx beacon filter table");
+
+	ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
+	if (!ie_table) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ie_table->num_ie = 0;
+	memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
+
+	ret = wl1251_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
+				   ie_table, sizeof(*ie_table));
+	if (ret < 0) {
+		wl1251_warning("failed to set beacon filter table: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(ie_table);
+	return ret;
+}
+
+int wl1251_acx_sg_enable(struct wl1251 *wl)
+{
+	struct acx_bt_wlan_coex *pta;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx sg enable");
+
+	pta = kzalloc(sizeof(*pta), GFP_KERNEL);
+	if (!pta) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pta->enable = SG_ENABLE;
+
+	ret = wl1251_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
+	if (ret < 0) {
+		wl1251_warning("failed to set softgemini enable: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(pta);
+	return ret;
+}
+
+int wl1251_acx_sg_cfg(struct wl1251 *wl)
+{
+	struct acx_bt_wlan_coex_param *param;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx sg cfg");
+
+	param = kzalloc(sizeof(*param), GFP_KERNEL);
+	if (!param) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* BT-WLAN coext parameters */
+	param->min_rate = RATE_INDEX_24MBPS;
+	param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
+	param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
+	param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
+	param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
+	param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
+	param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
+	param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
+	param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
+	param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
+	param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
+	param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
+	param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
+	param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
+	param->antenna_type = PTA_ANTENNA_TYPE_DEF;
+	param->signal_type = PTA_SIGNALING_TYPE_DEF;
+	param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
+	param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
+	param->max_cts = PTA_MAX_NUM_CTS_DEF;
+	param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
+	param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
+	param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
+	param->wlan_elp_hp = PTA_ELP_HP_DEF;
+	param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
+	param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
+	param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
+	param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
+	param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
+
+	ret = wl1251_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
+	if (ret < 0) {
+		wl1251_warning("failed to set sg config: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(param);
+	return ret;
+}
+
+int wl1251_acx_cca_threshold(struct wl1251 *wl)
+{
+	struct acx_energy_detection *detection;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx cca threshold");
+
+	detection = kzalloc(sizeof(*detection), GFP_KERNEL);
+	if (!detection) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
+	detection->tx_energy_detection = 0;
+
+	ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD,
+				   detection, sizeof(*detection));
+	if (ret < 0) {
+		wl1251_warning("failed to set cca threshold: %d", ret);
+		return ret;
+	}
+
+out:
+	kfree(detection);
+	return ret;
+}
+
+int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
+{
+	struct acx_beacon_broadcast *bb;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
+
+	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
+	if (!bb) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
+	bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
+	bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
+	bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
+
+	ret = wl1251_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
+	if (ret < 0) {
+		wl1251_warning("failed to set rx config: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(bb);
+	return ret;
+}
+
+int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
+{
+	struct acx_aid *acx_aid;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx aid");
+
+	acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
+	if (!acx_aid) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx_aid->aid = aid;
+
+	ret = wl1251_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
+	if (ret < 0) {
+		wl1251_warning("failed to set aid: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx_aid);
+	return ret;
+}
+
+int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
+{
+	struct acx_event_mask *mask;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx event mbox mask");
+
+	mask = kzalloc(sizeof(*mask), GFP_KERNEL);
+	if (!mask) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* high event mask is unused */
+	mask->high_event_mask = 0xffffffff;
+
+	mask->event_mask = event_mask;
+
+	ret = wl1251_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
+				   mask, sizeof(*mask));
+	if (ret < 0) {
+		wl1251_warning("failed to set acx_event_mbox_mask: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(mask);
+	return ret;
+}
+
+int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
+{
+	struct acx_preamble *acx;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx_set_preamble");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->preamble = preamble;
+
+	ret = wl1251_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("Setting of preamble failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_cts_protect(struct wl1251 *wl,
+			   enum acx_ctsprotect_type ctsprotect)
+{
+	struct acx_ctsprotect *acx;
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->ctsprotect = ctsprotect;
+
+	ret = wl1251_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("Setting of ctsprotect failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
+{
+	struct acx_tsf_info *tsf_info;
+	int ret;
+
+	tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
+	if (!tsf_info) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
+				     tsf_info, sizeof(*tsf_info));
+	if (ret < 0) {
+		wl1251_warning("ACX_FW_REV interrogate failed");
+		goto out;
+	}
+
+	*mactime = tsf_info->current_tsf_lsb |
+		(tsf_info->current_tsf_msb << 31);
+
+out:
+	kfree(tsf_info);
+	return ret;
+}
+
+int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
+{
+	int ret;
+
+	wl1251_debug(DEBUG_ACX, "acx statistics");
+
+	ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
+				     sizeof(*stats));
+	if (ret < 0) {
+		wl1251_warning("acx statistics failed: %d", ret);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int wl1251_acx_rate_policies(struct wl1251 *wl)
+{
+	struct acx_rate_policy *acx;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_ACX, "acx rate policies");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* configure one default (one-size-fits-all) rate class */
+	acx->rate_class_cnt = 1;
+	acx->rate_class[0].enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
+	acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
+	acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
+	acx->rate_class[0].aflags = 0;
+
+	ret = wl1251_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_warning("Setting of rate policies failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1251_acx_mem_cfg(struct wl1251 *wl)
+{
+	struct wl1251_acx_config_memory *mem_conf;
+	int ret, i;
+
+	wl1251_debug(DEBUG_ACX, "acx mem cfg");
+
+	mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
+	if (!mem_conf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* memory config */
+	mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
+	mem_conf->mem_config.rx_mem_block_num = 35;
+	mem_conf->mem_config.tx_min_mem_block_num = 64;
+	mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
+	mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
+	mem_conf->mem_config.num_ssid_profiles = 1;
+	mem_conf->mem_config.debug_buffer_size =
+		cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
+
+	/* RX queue config */
+	mem_conf->rx_queue_config.dma_address = 0;
+	mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
+	mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
+	mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
+
+	/* TX queue config */
+	for (i = 0; i < MAX_TX_QUEUES; i++) {
+		mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
+		mem_conf->tx_queue_config[i].attributes = i;
+	}
+
+	ret = wl1251_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
+				   sizeof(*mem_conf));
+	if (ret < 0) {
+		wl1251_warning("wl1251 mem config failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(mem_conf);
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl12xx/wl1251_acx.h
new file mode 100644
index 0000000..cafb914
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.h
@@ -0,0 +1,1292 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_ACX_H__
+#define __WL1251_ACX_H__
+
+#include "wl1251.h"
+#include "wl1251_cmd.h"
+
+/* Target's information element */
+struct acx_header {
+	struct wl1251_cmd_header cmd;
+
+	/* acx (or information element) header */
+	u16 id;
+
+	/* payload length (not including headers */
+	u16 len;
+};
+
+struct acx_error_counter {
+	struct acx_header header;
+
+	/* The number of PLCP errors since the last time this */
+	/* information element was interrogated. This field is */
+	/* automatically cleared when it is interrogated.*/
+	u32 PLCP_error;
+
+	/* The number of FCS errors since the last time this */
+	/* information element was interrogated. This field is */
+	/* automatically cleared when it is interrogated.*/
+	u32 FCS_error;
+
+	/* The number of MPDUs without PLCP header errors received*/
+	/* since the last time this information element was interrogated. */
+	/* This field is automatically cleared when it is interrogated.*/
+	u32 valid_frame;
+
+	/* the number of missed sequence numbers in the squentially */
+	/* values of frames seq numbers */
+	u32 seq_num_miss;
+} __attribute__ ((packed));
+
+struct acx_revision {
+	struct acx_header header;
+
+	/*
+	 * The WiLink firmware version, an ASCII string x.x.x.x,
+	 * that uniquely identifies the current firmware.
+	 * The left most digit is incremented each time a
+	 * significant change is made to the firmware, such as
+	 * code redesign or new platform support.
+	 * The second digit is incremented when major enhancements
+	 * are added or major fixes are made.
+	 * The third digit is incremented for each GA release.
+	 * The fourth digit is incremented for each build.
+	 * The first two digits identify a firmware release version,
+	 * in other words, a unique set of features.
+	 * The first three digits identify a GA release.
+	 */
+	char fw_version[20];
+
+	/*
+	 * This 4 byte field specifies the WiLink hardware version.
+	 * bits 0  - 15: Reserved.
+	 * bits 16 - 23: Version ID - The WiLink version ID
+	 *              (1 = first spin, 2 = second spin, and so on).
+	 * bits 24 - 31: Chip ID - The WiLink chip ID.
+	 */
+	u32 hw_version;
+} __attribute__ ((packed));
+
+enum wl1251_psm_mode {
+	/* Active mode */
+	WL1251_PSM_CAM = 0,
+
+	/* Power save mode */
+	WL1251_PSM_PS = 1,
+
+	/* Extreme low power */
+	WL1251_PSM_ELP = 2,
+};
+
+struct acx_sleep_auth {
+	struct acx_header header;
+
+	/* The sleep level authorization of the device. */
+	/* 0 - Always active*/
+	/* 1 - Power down mode: light / fast sleep*/
+	/* 2 - ELP mode: Deep / Max sleep*/
+	u8  sleep_auth;
+	u8  padding[3];
+} __attribute__ ((packed));
+
+enum {
+	HOSTIF_PCI_MASTER_HOST_INDIRECT,
+	HOSTIF_PCI_MASTER_HOST_DIRECT,
+	HOSTIF_SLAVE,
+	HOSTIF_PKT_RING,
+	HOSTIF_DONTCARE = 0xFF
+};
+
+#define DEFAULT_UCAST_PRIORITY          0
+#define DEFAULT_RX_Q_PRIORITY           0
+#define DEFAULT_NUM_STATIONS            1
+#define DEFAULT_RXQ_PRIORITY            0 /* low 0 .. 15 high  */
+#define DEFAULT_RXQ_TYPE                0x07    /* All frames, Data/Ctrl/Mgmt */
+#define TRACE_BUFFER_MAX_SIZE           256
+
+#define  DP_RX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_TX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_RX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_COMPLETE_TIME_OUT 20
+#define  FW_TX_CMPLT_BLOCK_SIZE 16
+
+struct acx_data_path_params {
+	struct acx_header header;
+
+	u16 rx_packet_ring_chunk_size;
+	u16 tx_packet_ring_chunk_size;
+
+	u8 rx_packet_ring_chunk_num;
+	u8 tx_packet_ring_chunk_num;
+
+	/*
+	 * Maximum number of packets that can be gathered
+	 * in the TX complete ring before an interrupt
+	 * is generated.
+	 */
+	u8 tx_complete_threshold;
+
+	/* Number of pending TX complete entries in cyclic ring.*/
+	u8 tx_complete_ring_depth;
+
+	/*
+	 * Max num microseconds since a packet enters the TX
+	 * complete ring until an interrupt is generated.
+	 */
+	u32 tx_complete_timeout;
+} __attribute__ ((packed));
+
+
+struct acx_data_path_params_resp {
+	struct acx_header header;
+
+	u16 rx_packet_ring_chunk_size;
+	u16 tx_packet_ring_chunk_size;
+
+	u8 rx_packet_ring_chunk_num;
+	u8 tx_packet_ring_chunk_num;
+
+	u8 pad[2];
+
+	u32 rx_packet_ring_addr;
+	u32 tx_packet_ring_addr;
+
+	u32 rx_control_addr;
+	u32 tx_control_addr;
+
+	u32 tx_complete_addr;
+} __attribute__ ((packed));
+
+#define TX_MSDU_LIFETIME_MIN       0
+#define TX_MSDU_LIFETIME_MAX       3000
+#define TX_MSDU_LIFETIME_DEF       512
+#define RX_MSDU_LIFETIME_MIN       0
+#define RX_MSDU_LIFETIME_MAX       0xFFFFFFFF
+#define RX_MSDU_LIFETIME_DEF       512000
+
+struct acx_rx_msdu_lifetime {
+	struct acx_header header;
+
+	/*
+	 * The maximum amount of time, in TU, before the
+	 * firmware discards the MSDU.
+	 */
+	u32 lifetime;
+} __attribute__ ((packed));
+
+/*
+ * RX Config Options Table
+ * Bit		Definition
+ * ===		==========
+ * 31:14		Reserved
+ * 13		Copy RX Status - when set, write three receive status words
+ * 	 	to top of rx'd MPDUs.
+ * 		When cleared, do not write three status words (added rev 1.5)
+ * 12		Reserved
+ * 11		RX Complete upon FCS error - when set, give rx complete
+ *	 	interrupt for FCS errors, after the rx filtering, e.g. unicast
+ *	 	frames not to us with FCS error will not generate an interrupt.
+ * 10		SSID Filter Enable - When set, the WiLink discards all beacon,
+ *	        probe request, and probe response frames with an SSID that does
+ *		not match the SSID specified by the host in the START/JOIN
+ *		command.
+ *		When clear, the WiLink receives frames with any SSID.
+ * 9		Broadcast Filter Enable - When set, the WiLink discards all
+ * 	 	broadcast frames. When clear, the WiLink receives all received
+ *		broadcast frames.
+ * 8:6		Reserved
+ * 5		BSSID Filter Enable - When set, the WiLink discards any frames
+ * 	 	with a BSSID that does not match the BSSID specified by the
+ *		host.
+ *		When clear, the WiLink receives frames from any BSSID.
+ * 4		MAC Addr Filter - When set, the WiLink discards any frames
+ * 	 	with a destination address that does not match the MAC address
+ *		of the adaptor.
+ *		When clear, the WiLink receives frames destined to any MAC
+ *		address.
+ * 3		Promiscuous - When set, the WiLink receives all valid frames
+ * 	 	(i.e., all frames that pass the FCS check).
+ *		When clear, only frames that pass the other filters specified
+ *		are received.
+ * 2		FCS - When set, the WiLink includes the FCS with the received
+ *	 	frame.
+ *		When cleared, the FCS is discarded.
+ * 1		PLCP header - When set, write all data from baseband to frame
+ * 	 	buffer including PHY header.
+ * 0		Reserved - Always equal to 0.
+ *
+ * RX Filter Options Table
+ * Bit		Definition
+ * ===		==========
+ * 31:12		Reserved - Always equal to 0.
+ * 11		Association - When set, the WiLink receives all association
+ * 	 	related frames (association request/response, reassocation
+ *		request/response, and disassociation). When clear, these frames
+ *		are discarded.
+ * 10		Auth/De auth - When set, the WiLink receives all authentication
+ * 	 	and de-authentication frames. When clear, these frames are
+ *		discarded.
+ * 9		Beacon - When set, the WiLink receives all beacon frames.
+ * 	 	When clear, these frames are discarded.
+ * 8		Contention Free - When set, the WiLink receives all contention
+ * 	 	free frames.
+ *		When clear, these frames are discarded.
+ * 7		Control - When set, the WiLink receives all control frames.
+ * 	 	When clear, these frames are discarded.
+ * 6		Data - When set, the WiLink receives all data frames.
+ * 	 	When clear, these frames are discarded.
+ * 5		FCS Error - When set, the WiLink receives frames that have FCS
+ *	 	errors.
+ *		When clear, these frames are discarded.
+ * 4		Management - When set, the WiLink receives all management
+ *		frames.
+ * 	 	When clear, these frames are discarded.
+ * 3		Probe Request - When set, the WiLink receives all probe request
+ * 	 	frames.
+ *		When clear, these frames are discarded.
+ * 2		Probe Response - When set, the WiLink receives all probe
+ * 		response frames.
+ *		When clear, these frames are discarded.
+ * 1		RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
+ * 	 	frames.
+ *		When clear, these frames are discarded.
+ * 0		Rsvd Type/Sub Type - When set, the WiLink receives all frames
+ * 	 	that have reserved frame types and sub types as defined by the
+ *		802.11 specification.
+ *		When clear, these frames are discarded.
+ */
+struct acx_rx_config {
+	struct acx_header header;
+
+	u32 config_options;
+	u32 filter_options;
+} __attribute__ ((packed));
+
+enum {
+	QOS_AC_BE = 0,
+	QOS_AC_BK,
+	QOS_AC_VI,
+	QOS_AC_VO,
+	QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
+};
+
+#define MAX_NUM_OF_AC             (QOS_HIGHEST_AC_INDEX+1)
+#define FIRST_AC_INDEX            QOS_AC_BE
+#define MAX_NUM_OF_802_1d_TAGS    8
+#define AC_PARAMS_MAX_TSID        15
+#define MAX_APSD_CONF             0xffff
+
+#define  QOS_TX_HIGH_MIN      (0)
+#define  QOS_TX_HIGH_MAX      (100)
+
+#define  QOS_TX_HIGH_BK_DEF   (25)
+#define  QOS_TX_HIGH_BE_DEF   (35)
+#define  QOS_TX_HIGH_VI_DEF   (35)
+#define  QOS_TX_HIGH_VO_DEF   (35)
+
+#define  QOS_TX_LOW_BK_DEF    (15)
+#define  QOS_TX_LOW_BE_DEF    (25)
+#define  QOS_TX_LOW_VI_DEF    (25)
+#define  QOS_TX_LOW_VO_DEF    (25)
+
+struct acx_tx_queue_qos_config {
+	struct acx_header header;
+
+	u8 qid;
+	u8 pad[3];
+
+	/* Max number of blocks allowd in the queue */
+	u16 high_threshold;
+
+	/* Lowest memory blocks guaranteed for this queue */
+	u16 low_threshold;
+} __attribute__ ((packed));
+
+struct acx_packet_detection {
+	struct acx_header header;
+
+	u32 threshold;
+} __attribute__ ((packed));
+
+
+enum acx_slot_type {
+	SLOT_TIME_LONG = 0,
+	SLOT_TIME_SHORT = 1,
+	DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
+	MAX_SLOT_TIMES = 0xFF
+};
+
+#define STATION_WONE_INDEX 0
+
+struct acx_slot {
+	struct acx_header header;
+
+	u8 wone_index; /* Reserved */
+	u8 slot_time;
+	u8 reserved[6];
+} __attribute__ ((packed));
+
+
+#define ADDRESS_GROUP_MAX	(8)
+#define ADDRESS_GROUP_MAX_LEN	(ETH_ALEN * ADDRESS_GROUP_MAX)
+
+struct acx_dot11_grp_addr_tbl {
+	struct acx_header header;
+
+	u8 enabled;
+	u8 num_groups;
+	u8 pad[2];
+	u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+} __attribute__ ((packed));
+
+
+#define  RX_TIMEOUT_PS_POLL_MIN    0
+#define  RX_TIMEOUT_PS_POLL_MAX    (200000)
+#define  RX_TIMEOUT_PS_POLL_DEF    (15)
+#define  RX_TIMEOUT_UPSD_MIN       0
+#define  RX_TIMEOUT_UPSD_MAX       (200000)
+#define  RX_TIMEOUT_UPSD_DEF       (15)
+
+struct acx_rx_timeout {
+	struct acx_header header;
+
+	/*
+	 * The longest time the STA will wait to receive
+	 * traffic from the AP after a PS-poll has been
+	 * transmitted.
+	 */
+	u16 ps_poll_timeout;
+
+	/*
+	 * The longest time the STA will wait to receive
+	 * traffic from the AP after a frame has been sent
+	 * from an UPSD enabled queue.
+	 */
+	u16 upsd_timeout;
+} __attribute__ ((packed));
+
+#define RTS_THRESHOLD_MIN              0
+#define RTS_THRESHOLD_MAX              4096
+#define RTS_THRESHOLD_DEF              2347
+
+struct acx_rts_threshold {
+	struct acx_header header;
+
+	u16 threshold;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_beacon_filter_option {
+	struct acx_header header;
+
+	u8 enable;
+
+	/*
+	 * The number of beacons without the unicast TIM
+	 * bit set that the firmware buffers before
+	 * signaling the host about ready frames.
+	 * When set to 0 and the filter is enabled, beacons
+	 * without the unicast TIM bit set are dropped.
+	 */
+	u8 max_num_beacons;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+/*
+ * ACXBeaconFilterEntry (not 221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0				1               IE identifier
+ * 1               1               Treatment bit mask
+ *
+ * ACXBeaconFilterEntry (221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0               1               IE identifier
+ * 1               1               Treatment bit mask
+ * 2               3               OUI
+ * 5               1               Type
+ * 6               2               Version
+ *
+ *
+ * Treatment bit mask - The information element handling:
+ * bit 0 - The information element is compared and transferred
+ * in case of change.
+ * bit 1 - The information element is transferred to the host
+ * with each appearance or disappearance.
+ * Note that both bits can be set at the same time.
+ */
+#define	BEACON_FILTER_TABLE_MAX_IE_NUM		       (32)
+#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
+#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE	       (2)
+#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
+#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
+			    BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
+			   (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
+			    BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
+
+struct acx_beacon_filter_ie_table {
+	struct acx_header header;
+
+	u8 num_ie;
+	u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
+	u8 pad[3];
+} __attribute__ ((packed));
+
+enum {
+	SG_ENABLE = 0,
+	SG_DISABLE,
+	SG_SENSE_NO_ACTIVITY,
+	SG_SENSE_ACTIVE
+};
+
+struct acx_bt_wlan_coex {
+	struct acx_header header;
+
+	/*
+	 * 0 -> PTA enabled
+	 * 1 -> PTA disabled
+	 * 2 -> sense no active mode, i.e.
+	 *      an interrupt is sent upon
+	 *      BT activity.
+	 * 3 -> PTA is switched on in response
+	 *      to the interrupt sending.
+	 */
+	u8 enable;
+	u8 pad[3];
+} __attribute__ ((packed));
+
+#define PTA_ANTENNA_TYPE_DEF		  (0)
+#define PTA_BT_HP_MAXTIME_DEF		  (2000)
+#define PTA_WLAN_HP_MAX_TIME_DEF	  (5000)
+#define PTA_SENSE_DISABLE_TIMER_DEF	  (1350)
+#define PTA_PROTECTIVE_RX_TIME_DEF	  (1500)
+#define PTA_PROTECTIVE_TX_TIME_DEF	  (1500)
+#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
+#define PTA_SIGNALING_TYPE_DEF		  (1)
+#define PTA_AFH_LEVERAGE_ON_DEF		  (0)
+#define PTA_NUMBER_QUIET_CYCLE_DEF	  (0)
+#define PTA_MAX_NUM_CTS_DEF		  (3)
+#define PTA_NUMBER_OF_WLAN_PACKETS_DEF	  (2)
+#define PTA_NUMBER_OF_BT_PACKETS_DEF	  (2)
+#define PTA_PROTECTIVE_RX_TIME_FAST_DEF	  (1500)
+#define PTA_PROTECTIVE_TX_TIME_FAST_DEF	  (3000)
+#define PTA_CYCLE_TIME_FAST_DEF		  (8700)
+#define PTA_RX_FOR_AVALANCHE_DEF	  (5)
+#define PTA_ELP_HP_DEF			  (0)
+#define PTA_ANTI_STARVE_PERIOD_DEF	  (500)
+#define PTA_ANTI_STARVE_NUM_CYCLE_DEF	  (4)
+#define PTA_ALLOW_PA_SD_DEF		  (1)
+#define PTA_TIME_BEFORE_BEACON_DEF	  (6300)
+#define PTA_HPDM_MAX_TIME_DEF		  (1600)
+#define PTA_TIME_OUT_NEXT_WLAN_DEF	  (2550)
+#define PTA_AUTO_MODE_NO_CTS_DEF	  (0)
+#define PTA_BT_HP_RESPECTED_DEF		  (3)
+#define PTA_WLAN_RX_MIN_RATE_DEF	  (24)
+#define PTA_ACK_MODE_DEF		  (1)
+
+struct acx_bt_wlan_coex_param {
+	struct acx_header header;
+
+	/*
+	 * The minimum rate of a received WLAN packet in the STA,
+	 * during protective mode, of which a new BT-HP request
+	 * during this Rx will always be respected and gain the antenna.
+	 */
+	u32 min_rate;
+
+	/* Max time the BT HP will be respected. */
+	u16 bt_hp_max_time;
+
+	/* Max time the WLAN HP will be respected. */
+	u16 wlan_hp_max_time;
+
+	/*
+	 * The time between the last BT activity
+	 * and the moment when the sense mode returns
+	 * to SENSE_INACTIVE.
+	 */
+	u16 sense_disable_timer;
+
+	/* Time before the next BT HP instance */
+	u16 rx_time_bt_hp;
+	u16 tx_time_bt_hp;
+
+	/* range: 10-20000    default: 1500 */
+	u16 rx_time_bt_hp_fast;
+	u16 tx_time_bt_hp_fast;
+
+	/* range: 2000-65535  default: 8700 */
+	u16 wlan_cycle_fast;
+
+	/* range: 0 - 15000 (Msec) default: 1000 */
+	u16 bt_anti_starvation_period;
+
+	/* range 400-10000(Usec) default: 3000 */
+	u16 next_bt_lp_packet;
+
+	/* Deafult: worst case for BT DH5 traffic */
+	u16 wake_up_beacon;
+
+	/* range: 0-50000(Usec) default: 1050 */
+	u16 hp_dm_max_guard_time;
+
+	/*
+	 * This is to prevent both BT & WLAN antenna
+	 * starvation.
+	 * Range: 100-50000(Usec) default:2550
+	 */
+	u16 next_wlan_packet;
+
+	/* 0 -> shared antenna */
+	u8 antenna_type;
+
+	/*
+	 * 0 -> TI legacy
+	 * 1 -> Palau
+	 */
+	u8 signal_type;
+
+	/*
+	 * BT AFH status
+	 * 0 -> no AFH
+	 * 1 -> from dedicated GPIO
+	 * 2 -> AFH on (from host)
+	 */
+	u8 afh_leverage_on;
+
+	/*
+	 * The number of cycles during which no
+	 * TX will be sent after 1 cycle of RX
+	 * transaction in protective mode
+	 */
+	u8 quiet_cycle_num;
+
+	/*
+	 * The maximum number of CTSs that will
+	 * be sent for receiving RX packet in
+	 * protective mode
+	 */
+	u8 max_cts;
+
+	/*
+	 * The number of WLAN packets
+	 * transferred in common mode before
+	 * switching to BT.
+	 */
+	u8 wlan_packets_num;
+
+	/*
+	 * The number of BT packets
+	 * transferred in common mode before
+	 * switching to WLAN.
+	 */
+	u8 bt_packets_num;
+
+	/* range: 1-255  default: 5 */
+	u8 missed_rx_avalanche;
+
+	/* range: 0-1    default: 1 */
+	u8 wlan_elp_hp;
+
+	/* range: 0 - 15  default: 4 */
+	u8 bt_anti_starvation_cycles;
+
+	u8 ack_mode_dual_ant;
+
+	/*
+	 * Allow PA_SD assertion/de-assertion
+	 * during enabled BT activity.
+	 */
+	u8 pa_sd_enable;
+
+	/*
+	 * Enable/Disable PTA in auto mode:
+	 * Support Both Active & P.S modes
+	 */
+	u8 pta_auto_mode_enable;
+
+	/* range: 0 - 20  default: 1 */
+	u8 bt_hp_respected_num;
+} __attribute__ ((packed));
+
+#define CCA_THRSH_ENABLE_ENERGY_D       0x140A
+#define CCA_THRSH_DISABLE_ENERGY_D      0xFFEF
+
+struct acx_energy_detection {
+	struct acx_header header;
+
+	/* The RX Clear Channel Assessment threshold in the PHY */
+	u16 rx_cca_threshold;
+	u8 tx_energy_detection;
+	u8 pad;
+} __attribute__ ((packed));
+
+#define BCN_RX_TIMEOUT_DEF_VALUE        10000
+#define BROADCAST_RX_TIMEOUT_DEF_VALUE  20000
+#define RX_BROADCAST_IN_PS_DEF_VALUE    1
+#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
+
+struct acx_beacon_broadcast {
+	struct acx_header header;
+
+	u16 beacon_rx_timeout;
+	u16 broadcast_timeout;
+
+	/* Enables receiving of broadcast packets in PS mode */
+	u8 rx_broadcast_in_ps;
+
+	/* Consecutive PS Poll failures before updating the host */
+	u8 ps_poll_threshold;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_event_mask {
+	struct acx_header header;
+
+	u32 event_mask;
+	u32 high_event_mask; /* Unused */
+} __attribute__ ((packed));
+
+#define CFG_RX_FCS		BIT(2)
+#define CFG_RX_ALL_GOOD		BIT(3)
+#define CFG_UNI_FILTER_EN	BIT(4)
+#define CFG_BSSID_FILTER_EN	BIT(5)
+#define CFG_MC_FILTER_EN	BIT(6)
+#define CFG_MC_ADDR0_EN		BIT(7)
+#define CFG_MC_ADDR1_EN		BIT(8)
+#define CFG_BC_REJECT_EN	BIT(9)
+#define CFG_SSID_FILTER_EN	BIT(10)
+#define CFG_RX_INT_FCS_ERROR	BIT(11)
+#define CFG_RX_INT_ENCRYPTED	BIT(12)
+#define CFG_RX_WR_RX_STATUS	BIT(13)
+#define CFG_RX_FILTER_NULTI	BIT(14)
+#define CFG_RX_RESERVE		BIT(15)
+#define CFG_RX_TIMESTAMP_TSF	BIT(16)
+
+#define CFG_RX_RSV_EN		BIT(0)
+#define CFG_RX_RCTS_ACK		BIT(1)
+#define CFG_RX_PRSP_EN		BIT(2)
+#define CFG_RX_PREQ_EN		BIT(3)
+#define CFG_RX_MGMT_EN		BIT(4)
+#define CFG_RX_FCS_ERROR	BIT(5)
+#define CFG_RX_DATA_EN		BIT(6)
+#define CFG_RX_CTL_EN		BIT(7)
+#define CFG_RX_CF_EN		BIT(8)
+#define CFG_RX_BCN_EN		BIT(9)
+#define CFG_RX_AUTH_EN		BIT(10)
+#define CFG_RX_ASSOC_EN		BIT(11)
+
+#define SCAN_PASSIVE		BIT(0)
+#define SCAN_5GHZ_BAND		BIT(1)
+#define SCAN_TRIGGERED		BIT(2)
+#define SCAN_PRIORITY_HIGH	BIT(3)
+
+struct acx_fw_gen_frame_rates {
+	struct acx_header header;
+
+	u8 tx_ctrl_frame_rate; /* RATE_* */
+	u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
+	u8 tx_mgt_frame_rate;
+	u8 tx_mgt_frame_mod;
+} __attribute__ ((packed));
+
+/* STA MAC */
+struct acx_dot11_station_id {
+	struct acx_header header;
+
+	u8 mac[ETH_ALEN];
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_feature_config {
+	struct acx_header header;
+
+	u32 options;
+	u32 data_flow_options;
+} __attribute__ ((packed));
+
+struct acx_current_tx_power {
+	struct acx_header header;
+
+	u8  current_tx_power;
+	u8  padding[3];
+} __attribute__ ((packed));
+
+struct acx_dot11_default_key {
+	struct acx_header header;
+
+	u8 id;
+	u8 pad[3];
+} __attribute__ ((packed));
+
+struct acx_tsf_info {
+	struct acx_header header;
+
+	u32 current_tsf_msb;
+	u32 current_tsf_lsb;
+	u32 last_TBTT_msb;
+	u32 last_TBTT_lsb;
+	u8 last_dtim_count;
+	u8 pad[3];
+} __attribute__ ((packed));
+
+enum acx_wake_up_event {
+	WAKE_UP_EVENT_BEACON_BITMAP	= 0x01, /* Wake on every Beacon*/
+	WAKE_UP_EVENT_DTIM_BITMAP	= 0x02,	/* Wake on every DTIM*/
+	WAKE_UP_EVENT_N_DTIM_BITMAP	= 0x04, /* Wake on every Nth DTIM */
+	WAKE_UP_EVENT_N_BEACONS_BITMAP	= 0x08, /* Wake on every Nth Beacon */
+	WAKE_UP_EVENT_BITS_MASK		= 0x0F
+};
+
+struct acx_wake_up_condition {
+	struct acx_header header;
+
+	u8 wake_up_event; /* Only one bit can be set */
+	u8 listen_interval;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_aid {
+	struct acx_header header;
+
+	/*
+	 * To be set when associated with an AP.
+	 */
+	u16 aid;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_preamble_type {
+	ACX_PREAMBLE_LONG = 0,
+	ACX_PREAMBLE_SHORT = 1
+};
+
+struct acx_preamble {
+	struct acx_header header;
+
+	/*
+	 * When set, the WiLink transmits the frames with a short preamble and
+	 * when cleared, the WiLink transmits the frames with a long preamble.
+	 */
+	u8 preamble;
+	u8 padding[3];
+} __attribute__ ((packed));
+
+enum acx_ctsprotect_type {
+	CTSPROTECT_DISABLE = 0,
+	CTSPROTECT_ENABLE = 1
+};
+
+struct acx_ctsprotect {
+	struct acx_header header;
+	u8 ctsprotect;
+	u8 padding[3];
+} __attribute__ ((packed));
+
+struct acx_tx_statistics {
+	u32 internal_desc_overflow;
+}  __attribute__ ((packed));
+
+struct acx_rx_statistics {
+	u32 out_of_mem;
+	u32 hdr_overflow;
+	u32 hw_stuck;
+	u32 dropped;
+	u32 fcs_err;
+	u32 xfr_hint_trig;
+	u32 path_reset;
+	u32 reset_counter;
+} __attribute__ ((packed));
+
+struct acx_dma_statistics {
+	u32 rx_requested;
+	u32 rx_errors;
+	u32 tx_requested;
+	u32 tx_errors;
+}  __attribute__ ((packed));
+
+struct acx_isr_statistics {
+	/* host command complete */
+	u32 cmd_cmplt;
+
+	/* fiqisr() */
+	u32 fiqs;
+
+	/* (INT_STS_ND & INT_TRIG_RX_HEADER) */
+	u32 rx_headers;
+
+	/* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
+	u32 rx_completes;
+
+	/* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
+	u32 rx_mem_overflow;
+
+	/* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
+	u32 rx_rdys;
+
+	/* irqisr() */
+	u32 irqs;
+
+	/* (INT_STS_ND & INT_TRIG_TX_PROC) */
+	u32 tx_procs;
+
+	/* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
+	u32 decrypt_done;
+
+	/* (INT_STS_ND & INT_TRIG_DMA0) */
+	u32 dma0_done;
+
+	/* (INT_STS_ND & INT_TRIG_DMA1) */
+	u32 dma1_done;
+
+	/* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
+	u32 tx_exch_complete;
+
+	/* (INT_STS_ND & INT_TRIG_COMMAND) */
+	u32 commands;
+
+	/* (INT_STS_ND & INT_TRIG_RX_PROC) */
+	u32 rx_procs;
+
+	/* (INT_STS_ND & INT_TRIG_PM_802) */
+	u32 hw_pm_mode_changes;
+
+	/* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
+	u32 host_acknowledges;
+
+	/* (INT_STS_ND & INT_TRIG_PM_PCI) */
+	u32 pci_pm;
+
+	/* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
+	u32 wakeups;
+
+	/* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
+	u32 low_rssi;
+} __attribute__ ((packed));
+
+struct acx_wep_statistics {
+	/* WEP address keys configured */
+	u32 addr_key_count;
+
+	/* default keys configured */
+	u32 default_key_count;
+
+	u32 reserved;
+
+	/* number of times that WEP key not found on lookup */
+	u32 key_not_found;
+
+	/* number of times that WEP key decryption failed */
+	u32 decrypt_fail;
+
+	/* WEP packets decrypted */
+	u32 packets;
+
+	/* WEP decrypt interrupts */
+	u32 interrupt;
+} __attribute__ ((packed));
+
+#define ACX_MISSED_BEACONS_SPREAD 10
+
+struct acx_pwr_statistics {
+	/* the amount of enters into power save mode (both PD & ELP) */
+	u32 ps_enter;
+
+	/* the amount of enters into ELP mode */
+	u32 elp_enter;
+
+	/* the amount of missing beacon interrupts to the host */
+	u32 missing_bcns;
+
+	/* the amount of wake on host-access times */
+	u32 wake_on_host;
+
+	/* the amount of wake on timer-expire */
+	u32 wake_on_timer_exp;
+
+	/* the number of packets that were transmitted with PS bit set */
+	u32 tx_with_ps;
+
+	/* the number of packets that were transmitted with PS bit clear */
+	u32 tx_without_ps;
+
+	/* the number of received beacons */
+	u32 rcvd_beacons;
+
+	/* the number of entering into PowerOn (power save off) */
+	u32 power_save_off;
+
+	/* the number of entries into power save mode */
+	u16 enable_ps;
+
+	/*
+	 * the number of exits from power save, not including failed PS
+	 * transitions
+	 */
+	u16 disable_ps;
+
+	/*
+	 * the number of times the TSF counter was adjusted because
+	 * of drift
+	 */
+	u32 fix_tsf_ps;
+
+	/* Gives statistics about the spread continuous missed beacons.
+	 * The 16 LSB are dedicated for the PS mode.
+	 * The 16 MSB are dedicated for the PS mode.
+	 * cont_miss_bcns_spread[0] - single missed beacon.
+	 * cont_miss_bcns_spread[1] - two continuous missed beacons.
+	 * cont_miss_bcns_spread[2] - three continuous missed beacons.
+	 * ...
+	 * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
+	*/
+	u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
+
+	/* the number of beacons in awake mode */
+	u32 rcvd_awake_beacons;
+} __attribute__ ((packed));
+
+struct acx_mic_statistics {
+	u32 rx_pkts;
+	u32 calc_failure;
+} __attribute__ ((packed));
+
+struct acx_aes_statistics {
+	u32 encrypt_fail;
+	u32 decrypt_fail;
+	u32 encrypt_packets;
+	u32 decrypt_packets;
+	u32 encrypt_interrupt;
+	u32 decrypt_interrupt;
+} __attribute__ ((packed));
+
+struct acx_event_statistics {
+	u32 heart_beat;
+	u32 calibration;
+	u32 rx_mismatch;
+	u32 rx_mem_empty;
+	u32 rx_pool;
+	u32 oom_late;
+	u32 phy_transmit_error;
+	u32 tx_stuck;
+} __attribute__ ((packed));
+
+struct acx_ps_statistics {
+	u32 pspoll_timeouts;
+	u32 upsd_timeouts;
+	u32 upsd_max_sptime;
+	u32 upsd_max_apturn;
+	u32 pspoll_max_apturn;
+	u32 pspoll_utilization;
+	u32 upsd_utilization;
+} __attribute__ ((packed));
+
+struct acx_rxpipe_statistics {
+	u32 rx_prep_beacon_drop;
+	u32 descr_host_int_trig_rx_data;
+	u32 beacon_buffer_thres_host_int_trig_rx_data;
+	u32 missed_beacon_host_int_trig_rx_data;
+	u32 tx_xfr_host_int_trig_rx_data;
+} __attribute__ ((packed));
+
+struct acx_statistics {
+	struct acx_header header;
+
+	struct acx_tx_statistics tx;
+	struct acx_rx_statistics rx;
+	struct acx_dma_statistics dma;
+	struct acx_isr_statistics isr;
+	struct acx_wep_statistics wep;
+	struct acx_pwr_statistics pwr;
+	struct acx_aes_statistics aes;
+	struct acx_mic_statistics mic;
+	struct acx_event_statistics event;
+	struct acx_ps_statistics ps;
+	struct acx_rxpipe_statistics rxpipe;
+} __attribute__ ((packed));
+
+#define ACX_MAX_RATE_CLASSES       8
+#define ACX_RATE_MASK_UNSPECIFIED  0
+#define ACX_RATE_RETRY_LIMIT      10
+
+struct acx_rate_class {
+	u32 enabled_rates;
+	u8 short_retry_limit;
+	u8 long_retry_limit;
+	u8 aflags;
+	u8 reserved;
+};
+
+struct acx_rate_policy {
+	struct acx_header header;
+
+	u32 rate_class_cnt;
+	struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES];
+} __attribute__ ((packed));
+
+struct wl1251_acx_memory {
+	__le16 num_stations; /* number of STAs to be supported. */
+	u16 reserved_1;
+
+	/*
+	 * Nmber of memory buffers for the RX mem pool.
+	 * The actual number may be less if there are
+	 * not enough blocks left for the minimum num
+	 * of TX ones.
+	 */
+	u8 rx_mem_block_num;
+	u8 reserved_2;
+	u8 num_tx_queues; /* From 1 to 16 */
+	u8 host_if_options; /* HOST_IF* */
+	u8 tx_min_mem_block_num;
+	u8 num_ssid_profiles;
+	__le16 debug_buffer_size;
+} __attribute__ ((packed));
+
+
+#define ACX_RX_DESC_MIN                1
+#define ACX_RX_DESC_MAX                127
+#define ACX_RX_DESC_DEF                32
+struct wl1251_acx_rx_queue_config {
+	u8 num_descs;
+	u8 pad;
+	u8 type;
+	u8 priority;
+	__le32 dma_address;
+} __attribute__ ((packed));
+
+#define ACX_TX_DESC_MIN                1
+#define ACX_TX_DESC_MAX                127
+#define ACX_TX_DESC_DEF                16
+struct wl1251_acx_tx_queue_config {
+    u8 num_descs;
+    u8 pad[2];
+    u8 attributes;
+} __attribute__ ((packed));
+
+#define MAX_TX_QUEUE_CONFIGS 5
+#define MAX_TX_QUEUES 4
+struct wl1251_acx_config_memory {
+	struct acx_header header;
+
+	struct wl1251_acx_memory mem_config;
+	struct wl1251_acx_rx_queue_config rx_queue_config;
+	struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
+} __attribute__ ((packed));
+
+struct wl1251_acx_mem_map {
+	struct acx_header header;
+
+	void *code_start;
+	void *code_end;
+
+	void *wep_defkey_start;
+	void *wep_defkey_end;
+
+	void *sta_table_start;
+	void *sta_table_end;
+
+	void *packet_template_start;
+	void *packet_template_end;
+
+	void *queue_memory_start;
+	void *queue_memory_end;
+
+	void *packet_memory_pool_start;
+	void *packet_memory_pool_end;
+
+	void *debug_buffer1_start;
+	void *debug_buffer1_end;
+
+	void *debug_buffer2_start;
+	void *debug_buffer2_end;
+
+	/* Number of blocks FW allocated for TX packets */
+	u32 num_tx_mem_blocks;
+
+	/* Number of blocks FW allocated for RX packets */
+	u32 num_rx_mem_blocks;
+} __attribute__ ((packed));
+
+/*************************************************************************
+
+    Host Interrupt Register (WiLink -> Host)
+
+**************************************************************************/
+
+/* RX packet is ready in Xfer buffer #0 */
+#define WL1251_ACX_INTR_RX0_DATA      BIT(0)
+
+/* TX result(s) are in the TX complete buffer */
+#define WL1251_ACX_INTR_TX_RESULT	BIT(1)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_TX_XFR		BIT(2)
+
+/* RX packet is ready in Xfer buffer #1 */
+#define WL1251_ACX_INTR_RX1_DATA	BIT(3)
+
+/* Event was entered to Event MBOX #A */
+#define WL1251_ACX_INTR_EVENT_A		BIT(4)
+
+/* Event was entered to Event MBOX #B */
+#define WL1251_ACX_INTR_EVENT_B		BIT(5)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_WAKE_ON_HOST	BIT(6)
+
+/* Trace meassge on MBOX #A */
+#define WL1251_ACX_INTR_TRACE_A		BIT(7)
+
+/* Trace meassge on MBOX #B */
+#define WL1251_ACX_INTR_TRACE_B		BIT(8)
+
+/* Command processing completion */
+#define WL1251_ACX_INTR_CMD_COMPLETE	BIT(9)
+
+/* Init sequence is done */
+#define WL1251_ACX_INTR_INIT_COMPLETE	BIT(14)
+
+#define WL1251_ACX_INTR_ALL           0xFFFFFFFF
+
+enum {
+	ACX_WAKE_UP_CONDITIONS      = 0x0002,
+	ACX_MEM_CFG                 = 0x0003,
+	ACX_SLOT                    = 0x0004,
+	ACX_QUEUE_HEAD              = 0x0005, /* for MASTER mode only */
+	ACX_AC_CFG                  = 0x0007,
+	ACX_MEM_MAP                 = 0x0008,
+	ACX_AID                     = 0x000A,
+	ACX_RADIO_PARAM             = 0x000B, /* Not used */
+	ACX_CFG                     = 0x000C, /* Not used */
+	ACX_FW_REV                  = 0x000D,
+	ACX_MEDIUM_USAGE            = 0x000F,
+	ACX_RX_CFG                  = 0x0010,
+	ACX_TX_QUEUE_CFG            = 0x0011, /* FIXME: only used by wl1251 */
+	ACX_BSS_IN_PS               = 0x0012, /* for AP only */
+	ACX_STATISTICS              = 0x0013, /* Debug API */
+	ACX_FEATURE_CFG             = 0x0015,
+	ACX_MISC_CFG                = 0x0017, /* Not used */
+	ACX_TID_CFG                 = 0x001A,
+	ACX_BEACON_FILTER_OPT       = 0x001F,
+	ACX_LOW_RSSI                = 0x0020,
+	ACX_NOISE_HIST              = 0x0021,
+	ACX_HDK_VERSION             = 0x0022, /* ??? */
+	ACX_PD_THRESHOLD            = 0x0023,
+	ACX_DATA_PATH_PARAMS        = 0x0024, /* WO */
+	ACX_DATA_PATH_RESP_PARAMS   = 0x0024, /* RO */
+	ACX_CCA_THRESHOLD           = 0x0025,
+	ACX_EVENT_MBOX_MASK         = 0x0026,
+#ifdef FW_RUNNING_AS_AP
+	ACX_DTIM_PERIOD             = 0x0027, /* for AP only */
+#else
+	ACX_WR_TBTT_AND_DTIM        = 0x0027, /* STA only */
+#endif
+	ACX_ACI_OPTION_CFG          = 0x0029, /* OBSOLETE (for 1251)*/
+	ACX_GPIO_CFG                = 0x002A, /* Not used */
+	ACX_GPIO_SET                = 0x002B, /* Not used */
+	ACX_PM_CFG                  = 0x002C, /* To Be Documented */
+	ACX_CONN_MONIT_PARAMS       = 0x002D,
+	ACX_AVERAGE_RSSI            = 0x002E, /* Not used */
+	ACX_CONS_TX_FAILURE         = 0x002F,
+	ACX_BCN_DTIM_OPTIONS        = 0x0031,
+	ACX_SG_ENABLE               = 0x0032,
+	ACX_SG_CFG                  = 0x0033,
+	ACX_ANTENNA_DIVERSITY_CFG   = 0x0035, /* To Be Documented */
+	ACX_LOW_SNR		    = 0x0037, /* To Be Documented */
+	ACX_BEACON_FILTER_TABLE     = 0x0038,
+	ACX_ARP_IP_FILTER           = 0x0039,
+	ACX_ROAMING_STATISTICS_TBL  = 0x003B,
+	ACX_RATE_POLICY             = 0x003D,
+	ACX_CTS_PROTECTION          = 0x003E,
+	ACX_SLEEP_AUTH              = 0x003F,
+	ACX_PREAMBLE_TYPE	    = 0x0040,
+	ACX_ERROR_CNT               = 0x0041,
+	ACX_FW_GEN_FRAME_RATES      = 0x0042,
+	ACX_IBSS_FILTER		    = 0x0044,
+	ACX_SERVICE_PERIOD_TIMEOUT  = 0x0045,
+	ACX_TSF_INFO                = 0x0046,
+	ACX_CONFIG_PS_WMM           = 0x0049,
+	ACX_ENABLE_RX_DATA_FILTER   = 0x004A,
+	ACX_SET_RX_DATA_FILTER      = 0x004B,
+	ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
+	ACX_POWER_LEVEL_TABLE       = 0x004D,
+	ACX_BET_ENABLE              = 0x0050,
+	DOT11_STATION_ID            = 0x1001,
+	DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
+	DOT11_CUR_TX_PWR            = 0x100D,
+	DOT11_DEFAULT_KEY           = 0x1010,
+	DOT11_RX_DOT11_MODE         = 0x1012,
+	DOT11_RTS_THRESHOLD         = 0x1013,
+	DOT11_GROUP_ADDRESS_TBL     = 0x1014,
+
+	MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
+
+	MAX_IE = 0xFFFF
+};
+
+
+int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
+			   u8 mgt_rate, u8 mgt_mod);
+int wl1251_acx_station_id(struct wl1251 *wl);
+int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id);
+int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
+				  u8 listen_interval);
+int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth);
+int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len);
+int wl1251_acx_tx_power(struct wl1251 *wl, int power);
+int wl1251_acx_feature_cfg(struct wl1251 *wl);
+int wl1251_acx_mem_map(struct wl1251 *wl,
+		       struct acx_header *mem_map, size_t len);
+int wl1251_acx_data_path_params(struct wl1251 *wl,
+				struct acx_data_path_params_resp *data_path);
+int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time);
+int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter);
+int wl1251_acx_pd_threshold(struct wl1251 *wl);
+int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time);
+int wl1251_acx_group_address_tbl(struct wl1251 *wl);
+int wl1251_acx_service_period_timeout(struct wl1251 *wl);
+int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold);
+int wl1251_acx_beacon_filter_opt(struct wl1251 *wl);
+int wl1251_acx_beacon_filter_table(struct wl1251 *wl);
+int wl1251_acx_sg_enable(struct wl1251 *wl);
+int wl1251_acx_sg_cfg(struct wl1251 *wl);
+int wl1251_acx_cca_threshold(struct wl1251 *wl);
+int wl1251_acx_bcn_dtim_options(struct wl1251 *wl);
+int wl1251_acx_aid(struct wl1251 *wl, u16 aid);
+int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask);
+int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble);
+int wl1251_acx_cts_protect(struct wl1251 *wl,
+			    enum acx_ctsprotect_type ctsprotect);
+int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats);
+int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime);
+int wl1251_acx_rate_policies(struct wl1251 *wl);
+int wl1251_acx_mem_cfg(struct wl1251 *wl);
+
+#endif /* __WL1251_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
new file mode 100644
index 0000000..452d748
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -0,0 +1,530 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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/gpio.h>
+
+#include "wl1251_reg.h"
+#include "wl1251_boot.h"
+#include "wl1251_io.h"
+#include "wl1251_spi.h"
+#include "wl1251_event.h"
+#include "wl1251_acx.h"
+
+void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
+{
+	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+	wl1251_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+}
+
+int wl1251_boot_soft_reset(struct wl1251 *wl)
+{
+	unsigned long timeout;
+	u32 boot_data;
+
+	/* perform soft reset */
+	wl1251_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
+
+	/* SOFT_RESET is self clearing */
+	timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
+	while (1) {
+		boot_data = wl1251_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
+		wl1251_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
+		if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
+			break;
+
+		if (time_after(jiffies, timeout)) {
+			/* 1.2 check pWhalBus->uSelfClearTime if the
+			 * timeout was reached */
+			wl1251_error("soft reset timeout");
+			return -1;
+		}
+
+		udelay(SOFT_RESET_STALL_TIME);
+	}
+
+	/* disable Rx/Tx */
+	wl1251_reg_write32(wl, ENABLE, 0x0);
+
+	/* disable auto calibration on start*/
+	wl1251_reg_write32(wl, SPARE_A2, 0xffff);
+
+	return 0;
+}
+
+int wl1251_boot_init_seq(struct wl1251 *wl)
+{
+	u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
+
+	/*
+	 * col #1: INTEGER_DIVIDER
+	 * col #2: FRACTIONAL_DIVIDER
+	 * col #3: ATTN_BB
+	 * col #4: ALPHA_BB
+	 * col #5: STOP_TIME_BB
+	 * col #6: BB_PLL_LOOP_FILTER
+	 */
+	static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
+
+		{   83, 87381,  0xB, 5, 0xF00,  3}, /* REF_FREQ_19_2*/
+		{   61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
+		{   41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
+		{   40, 0,      0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
+		{   47, 162280, 0xC, 6, 0x2760, 1}  /* REF_FREQ_33_6        */
+	};
+
+	/* read NVS params */
+	scr_pad6 = wl1251_reg_read32(wl, SCR_PAD6);
+	wl1251_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
+
+	/* read ELP_CMD */
+	elp_cmd = wl1251_reg_read32(wl, ELP_CMD);
+	wl1251_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
+
+	/* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
+	ref_freq = scr_pad6 & 0x000000FF;
+	wl1251_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
+
+	wl1251_reg_write32(wl, PLL_CAL_TIME, 0x9);
+
+	/*
+	 * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
+	 */
+	wl1251_reg_write32(wl, CLK_BUF_TIME, 0x6);
+
+	/*
+	 * set the clock detect feature to work in the restart wu procedure
+	 * (ELP_CFG_MODE[14]) and Select the clock source type
+	 * (ELP_CFG_MODE[13:12])
+	 */
+	tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
+	wl1251_reg_write32(wl, ELP_CFG_MODE, tmp);
+
+	/* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
+	elp_cmd |= 0x00000040;
+	wl1251_reg_write32(wl, ELP_CMD, elp_cmd);
+
+	/* PG 1.2: Set the BB PLL stable time to be 1000usec
+	 * (PLL_STABLE_TIME) */
+	wl1251_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
+
+	/* PG 1.2: read clock request time */
+	init_data = wl1251_reg_read32(wl, CLK_REQ_TIME);
+
+	/*
+	 * PG 1.2: set the clock request time to be ref_clk_settling_time -
+	 * 1ms = 4ms
+	 */
+	if (init_data > 0x21)
+		tmp = init_data - 0x21;
+	else
+		tmp = 0;
+	wl1251_reg_write32(wl, CLK_REQ_TIME, tmp);
+
+	/* set BB PLL configurations in RF AFE */
+	wl1251_reg_write32(wl, 0x003058cc, 0x4B5);
+
+	/* set RF_AFE_REG_5 */
+	wl1251_reg_write32(wl, 0x003058d4, 0x50);
+
+	/* set RF_AFE_CTRL_REG_2 */
+	wl1251_reg_write32(wl, 0x00305948, 0x11c001);
+
+	/*
+	 * change RF PLL and BB PLL divider for VCO clock and adjust VCO
+	 * bais current(RF_AFE_REG_13)
+	 */
+	wl1251_reg_write32(wl, 0x003058f4, 0x1e);
+
+	/* set BB PLL configurations */
+	tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
+	wl1251_reg_write32(wl, 0x00305840, tmp);
+
+	/* set fractional divider according to Appendix C-BB PLL
+	 * Calculations
+	 */
+	tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
+	wl1251_reg_write32(wl, 0x00305844, tmp);
+
+	/* set the initial data for the sigma delta */
+	wl1251_reg_write32(wl, 0x00305848, 0x3039);
+
+	/*
+	 * set the accumulator attenuation value, calibration loop1
+	 * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
+	 * the VCO gain
+	 */
+	tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
+		(LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
+	wl1251_reg_write32(wl, 0x00305854, tmp);
+
+	/*
+	 * set the calibration stop time after holdoff time expires and set
+	 * settling time HOLD_OFF_TIME_BB
+	 */
+	tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
+	wl1251_reg_write32(wl, 0x00305858, tmp);
+
+	/*
+	 * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
+	 * constant leakage current to linearize PFD to 0uA -
+	 * BB_ILOOPF[7:3]
+	 */
+	tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
+	wl1251_reg_write32(wl, 0x003058f8, tmp);
+
+	/*
+	 * set regulator output voltage for n divider to
+	 * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
+	 * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
+	 * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
+	 */
+	wl1251_reg_write32(wl, 0x003058f0, 0x29);
+
+	/* enable restart wakeup sequence (ELP_CMD[0]) */
+	wl1251_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
+
+	/* restart sequence completed */
+	udelay(2000);
+
+	return 0;
+}
+
+static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag)
+{
+	u32 cpu_ctrl;
+
+	/* 10.5.0 run the firmware (I) */
+	cpu_ctrl = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+	/* 10.5.1 run the firmware (II) */
+	cpu_ctrl &= ~flag;
+	wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+}
+
+int wl1251_boot_run_firmware(struct wl1251 *wl)
+{
+	int loop, ret;
+	u32 chip_id, interrupt;
+
+	wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
+
+	chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
+
+	wl1251_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
+
+	if (chip_id != wl->chip_id) {
+		wl1251_error("chip id doesn't match after firmware boot");
+		return -EIO;
+	}
+
+	/* wait for init to complete */
+	loop = 0;
+	while (loop++ < INIT_LOOP) {
+		udelay(INIT_LOOP_DELAY);
+		interrupt = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+
+		if (interrupt == 0xffffffff) {
+			wl1251_error("error reading hardware complete "
+				     "init indication");
+			return -EIO;
+		}
+		/* check that ACX_INTR_INIT_COMPLETE is enabled */
+		else if (interrupt & WL1251_ACX_INTR_INIT_COMPLETE) {
+			wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+					   WL1251_ACX_INTR_INIT_COMPLETE);
+			break;
+		}
+	}
+
+	if (loop >= INIT_LOOP) {
+		wl1251_error("timeout waiting for the hardware to "
+			     "complete initialization");
+		return -EIO;
+	}
+
+	/* get hardware config command mail box */
+	wl->cmd_box_addr = wl1251_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
+
+	/* get hardware config event mail box */
+	wl->event_box_addr = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+
+	/* set the working partition to its "running" mode offset */
+	wl1251_set_partition(wl, WL1251_PART_WORK_MEM_START,
+			     WL1251_PART_WORK_MEM_SIZE,
+			     WL1251_PART_WORK_REG_START,
+			     WL1251_PART_WORK_REG_SIZE);
+
+	wl1251_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
+		     wl->cmd_box_addr, wl->event_box_addr);
+
+	wl1251_acx_fw_version(wl, wl->fw_ver, sizeof(wl->fw_ver));
+
+	/*
+	 * in case of full asynchronous mode the firmware event must be
+	 * ready to receive event from the command mailbox
+	 */
+
+	/* enable gpio interrupts */
+	wl1251_enable_interrupts(wl);
+
+	/* Enable target's interrupts */
+	wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
+		WL1251_ACX_INTR_RX1_DATA |
+		WL1251_ACX_INTR_TX_RESULT |
+		WL1251_ACX_INTR_EVENT_A |
+		WL1251_ACX_INTR_EVENT_B |
+		WL1251_ACX_INTR_INIT_COMPLETE;
+	wl1251_boot_target_enable_interrupts(wl);
+
+	/* unmask all mbox events  */
+	wl->event_mask = 0xffffffff;
+
+	ret = wl1251_event_unmask(wl);
+	if (ret < 0) {
+		wl1251_error("EVENT mask setting failed");
+		return ret;
+	}
+
+	wl1251_event_mbox_config(wl);
+
+	/* firmware startup completed */
+	return 0;
+}
+
+static int wl1251_boot_upload_firmware(struct wl1251 *wl)
+{
+	int addr, chunk_num, partition_limit;
+	size_t fw_data_len;
+	u8 *p;
+
+	/* whal_FwCtrl_LoadFwImageSm() */
+
+	wl1251_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
+		     wl1251_reg_read32(wl, CHIP_ID_B));
+
+	/* 10.0 check firmware length and set partition */
+	fw_data_len =  (wl->fw[4] << 24) | (wl->fw[5] << 16) |
+		(wl->fw[6] << 8) | (wl->fw[7]);
+
+	wl1251_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
+		CHUNK_SIZE);
+
+	if ((fw_data_len % 4) != 0) {
+		wl1251_error("firmware length not multiple of four");
+		return -EIO;
+	}
+
+	wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
+			     WL1251_PART_DOWN_MEM_SIZE,
+			     WL1251_PART_DOWN_REG_START,
+			     WL1251_PART_DOWN_REG_SIZE);
+
+	/* 10.1 set partition limit and chunk num */
+	chunk_num = 0;
+	partition_limit = WL1251_PART_DOWN_MEM_SIZE;
+
+	while (chunk_num < fw_data_len / CHUNK_SIZE) {
+		/* 10.2 update partition, if needed */
+		addr = WL1251_PART_DOWN_MEM_START +
+			(chunk_num + 2) * CHUNK_SIZE;
+		if (addr > partition_limit) {
+			addr = WL1251_PART_DOWN_MEM_START +
+				chunk_num * CHUNK_SIZE;
+			partition_limit = chunk_num * CHUNK_SIZE +
+				WL1251_PART_DOWN_MEM_SIZE;
+			wl1251_set_partition(wl,
+					     addr,
+					     WL1251_PART_DOWN_MEM_SIZE,
+					     WL1251_PART_DOWN_REG_START,
+					     WL1251_PART_DOWN_REG_SIZE);
+		}
+
+		/* 10.3 upload the chunk */
+		addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
+		p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+		wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
+			     p, addr);
+		wl1251_mem_write(wl, addr, p, CHUNK_SIZE);
+
+		chunk_num++;
+	}
+
+	/* 10.4 upload the last chunk */
+	addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
+	p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+	wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
+		     fw_data_len % CHUNK_SIZE, p, addr);
+	wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+
+	return 0;
+}
+
+static int wl1251_boot_upload_nvs(struct wl1251 *wl)
+{
+	size_t nvs_len, nvs_bytes_written, burst_len;
+	int nvs_start, i;
+	u32 dest_addr, val;
+	u8 *nvs_ptr, *nvs;
+
+	nvs = wl->nvs;
+	if (nvs == NULL)
+		return -ENODEV;
+
+	nvs_ptr = nvs;
+
+	nvs_len = wl->nvs_len;
+	nvs_start = wl->fw_len;
+
+	/*
+	 * Layout before the actual NVS tables:
+	 * 1 byte : burst length.
+	 * 2 bytes: destination address.
+	 * n bytes: data to burst copy.
+	 *
+	 * This is ended by a 0 length, then the NVS tables.
+	 */
+
+	while (nvs_ptr[0]) {
+		burst_len = nvs_ptr[0];
+		dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
+
+		/* We move our pointer to the data */
+		nvs_ptr += 3;
+
+		for (i = 0; i < burst_len; i++) {
+			val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+			       | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+			wl1251_debug(DEBUG_BOOT,
+				     "nvs burst write 0x%x: 0x%x",
+				     dest_addr, val);
+			wl1251_mem_write32(wl, dest_addr, val);
+
+			nvs_ptr += 4;
+			dest_addr += 4;
+		}
+	}
+
+	/*
+	 * We've reached the first zero length, the first NVS table
+	 * is 7 bytes further.
+	 */
+	nvs_ptr += 7;
+	nvs_len -= nvs_ptr - nvs;
+	nvs_len = ALIGN(nvs_len, 4);
+
+	/* Now we must set the partition correctly */
+	wl1251_set_partition(wl, nvs_start,
+			     WL1251_PART_DOWN_MEM_SIZE,
+			     WL1251_PART_DOWN_REG_START,
+			     WL1251_PART_DOWN_REG_SIZE);
+
+	/* And finally we upload the NVS tables */
+	nvs_bytes_written = 0;
+	while (nvs_bytes_written < nvs_len) {
+		val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+		       | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+		val = cpu_to_le32(val);
+
+		wl1251_debug(DEBUG_BOOT,
+			     "nvs write table 0x%x: 0x%x",
+			     nvs_start, val);
+		wl1251_mem_write32(wl, nvs_start, val);
+
+		nvs_ptr += 4;
+		nvs_bytes_written += 4;
+		nvs_start += 4;
+	}
+
+	return 0;
+}
+
+int wl1251_boot(struct wl1251 *wl)
+{
+	int ret = 0, minor_minor_e2_ver;
+	u32 tmp, boot_data;
+
+	/* halt embedded ARM CPU while loading firmware */
+	wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT);
+
+	ret = wl1251_boot_soft_reset(wl);
+	if (ret < 0)
+		goto out;
+
+	/* 2. start processing NVS file */
+	ret = wl1251_boot_upload_nvs(wl);
+	if (ret < 0)
+		goto out;
+
+	/* write firmware's last address (ie. it's length) to
+	 * ACX_EEPROMLESS_IND_REG */
+	wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+
+	/* 6. read the EEPROM parameters */
+	tmp = wl1251_reg_read32(wl, SCR_PAD2);
+
+	/* 7. read bootdata */
+	wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
+	wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
+	tmp = wl1251_reg_read32(wl, SCR_PAD3);
+
+	/* 8. check bootdata and call restart sequence */
+	wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
+	minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
+
+	wl1251_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
+		     "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
+		     wl->boot_attr.radio_type, wl->boot_attr.major,
+		     wl->boot_attr.minor, minor_minor_e2_ver);
+
+	ret = wl1251_boot_init_seq(wl);
+	if (ret < 0)
+		goto out;
+
+	/* 9. NVS processing done */
+	boot_data = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+	wl1251_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
+
+	/* 10. check that ECPU_CONTROL_HALT bits are set in
+	 * pWhalBus->uBootData and start uploading firmware
+	 */
+	if ((boot_data & ECPU_CONTROL_HALT) == 0) {
+		wl1251_error("boot failed, ECPU_CONTROL_HALT not set");
+		ret = -EIO;
+		goto out;
+	}
+
+	ret = wl1251_boot_upload_firmware(wl);
+	if (ret < 0)
+		goto out;
+
+	/* 10.5 start firmware */
+	ret = wl1251_boot_run_firmware(wl);
+	if (ret < 0)
+		goto out;
+
+out:
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl12xx/wl1251_boot.h
new file mode 100644
index 0000000..9006369
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __BOOT_H__
+#define __BOOT_H__
+
+#include "wl1251.h"
+
+int wl1251_boot_soft_reset(struct wl1251 *wl);
+int wl1251_boot_init_seq(struct wl1251 *wl);
+int wl1251_boot_run_firmware(struct wl1251 *wl);
+void wl1251_boot_target_enable_interrupts(struct wl1251 *wl);
+int wl1251_boot(struct wl1251 *wl);
+
+/* number of times we try to read the INIT interrupt */
+#define INIT_LOOP 20000
+
+/* delay between retries */
+#define INIT_LOOP_DELAY 50
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
new file mode 100644
index 0000000..770f260
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -0,0 +1,412 @@
+#include "wl1251_cmd.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+
+#include "wl1251.h"
+#include "wl1251_reg.h"
+#include "wl1251_io.h"
+#include "wl1251_ps.h"
+#include "wl1251_acx.h"
+
+/**
+ * send command to firmware
+ *
+ * @wl: wl struct
+ * @id: command id
+ * @buf: buffer containing the command, must work with dma
+ * @len: length of the buffer
+ */
+int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len)
+{
+	struct wl1251_cmd_header *cmd;
+	unsigned long timeout;
+	u32 intr;
+	int ret = 0;
+
+	cmd = buf;
+	cmd->id = id;
+	cmd->status = 0;
+
+	WARN_ON(len % 4 != 0);
+
+	wl1251_mem_write(wl, wl->cmd_box_addr, buf, len);
+
+	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+
+	timeout = jiffies + msecs_to_jiffies(WL1251_COMMAND_TIMEOUT);
+
+	intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+	while (!(intr & WL1251_ACX_INTR_CMD_COMPLETE)) {
+		if (time_after(jiffies, timeout)) {
+			wl1251_error("command complete timeout");
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+
+		msleep(1);
+
+		intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+	}
+
+	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+			   WL1251_ACX_INTR_CMD_COMPLETE);
+
+out:
+	return ret;
+}
+
+/**
+ * send test command to firmware
+ *
+ * @wl: wl struct
+ * @buf: buffer containing the command, with all headers, must work with dma
+ * @len: length of the buffer
+ * @answer: is answer needed
+ */
+int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer)
+{
+	int ret;
+
+	wl1251_debug(DEBUG_CMD, "cmd test");
+
+	ret = wl1251_cmd_send(wl, CMD_TEST, buf, buf_len);
+
+	if (ret < 0) {
+		wl1251_warning("TEST command failed");
+		return ret;
+	}
+
+	if (answer) {
+		struct wl1251_command *cmd_answer;
+
+		/*
+		 * The test command got in, we can read the answer.
+		 * The answer would be a wl1251_command, where the
+		 * parameter array contains the actual answer.
+		 */
+		wl1251_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
+
+		cmd_answer = buf;
+
+		if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
+			wl1251_error("TEST command answer error: %d",
+				     cmd_answer->header.status);
+	}
+
+	return 0;
+}
+
+/**
+ * read acx from firmware
+ *
+ * @wl: wl struct
+ * @id: acx id
+ * @buf: buffer for the response, including all headers, must work with dma
+ * @len: lenght of buf
+ */
+int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len)
+{
+	struct acx_header *acx = buf;
+	int ret;
+
+	wl1251_debug(DEBUG_CMD, "cmd interrogate");
+
+	acx->id = id;
+
+	/* payload length, does not include any headers */
+	acx->len = len - sizeof(*acx);
+
+	ret = wl1251_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1251_error("INTERROGATE command failed");
+		goto out;
+	}
+
+	/* the interrogate command got in, we can read the answer */
+	wl1251_mem_read(wl, wl->cmd_box_addr, buf, len);
+
+	acx = buf;
+	if (acx->cmd.status != CMD_STATUS_SUCCESS)
+		wl1251_error("INTERROGATE command error: %d",
+			     acx->cmd.status);
+
+out:
+	return ret;
+}
+
+/**
+ * write acx value to firmware
+ *
+ * @wl: wl struct
+ * @id: acx id
+ * @buf: buffer containing acx, including all headers, must work with dma
+ * @len: length of buf
+ */
+int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len)
+{
+	struct acx_header *acx = buf;
+	int ret;
+
+	wl1251_debug(DEBUG_CMD, "cmd configure");
+
+	acx->id = id;
+
+	/* payload length, does not include any headers */
+	acx->len = len - sizeof(*acx);
+
+	ret = wl1251_cmd_send(wl, CMD_CONFIGURE, acx, len);
+	if (ret < 0) {
+		wl1251_warning("CONFIGURE command NOK");
+		return ret;
+	}
+
+	return 0;
+}
+
+int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
+		   void *bitmap, u16 bitmap_len, u8 bitmap_control)
+{
+	struct wl1251_cmd_vbm_update *vbm;
+	int ret;
+
+	wl1251_debug(DEBUG_CMD, "cmd vbm");
+
+	vbm = kzalloc(sizeof(*vbm), GFP_KERNEL);
+	if (!vbm) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* Count and period will be filled by the target */
+	vbm->tim.bitmap_ctrl = bitmap_control;
+	if (bitmap_len > PARTIAL_VBM_MAX) {
+		wl1251_warning("cmd vbm len is %d B, truncating to %d",
+			       bitmap_len, PARTIAL_VBM_MAX);
+		bitmap_len = PARTIAL_VBM_MAX;
+	}
+	memcpy(vbm->tim.pvb_field, bitmap, bitmap_len);
+	vbm->tim.identity = identity;
+	vbm->tim.length = bitmap_len + 3;
+
+	vbm->len = cpu_to_le16(bitmap_len + 5);
+
+	ret = wl1251_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm));
+	if (ret < 0) {
+		wl1251_error("VBM command failed");
+		goto out;
+	}
+
+out:
+	kfree(vbm);
+	return 0;
+}
+
+int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable)
+{
+	struct cmd_enabledisable_path *cmd;
+	int ret;
+	u16 cmd_rx, cmd_tx;
+
+	wl1251_debug(DEBUG_CMD, "cmd data path");
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->channel = channel;
+
+	if (enable) {
+		cmd_rx = CMD_ENABLE_RX;
+		cmd_tx = CMD_ENABLE_TX;
+	} else {
+		cmd_rx = CMD_DISABLE_RX;
+		cmd_tx = CMD_DISABLE_TX;
+	}
+
+	ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1251_error("rx %s cmd for channel %d failed",
+			     enable ? "start" : "stop", channel);
+		goto out;
+	}
+
+	wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d",
+		     enable ? "start" : "stop", channel);
+
+	ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1251_error("tx %s cmd for channel %d failed",
+			     enable ? "start" : "stop", channel);
+		return ret;
+	}
+
+	wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d",
+		     enable ? "start" : "stop", channel);
+
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
+		    u16 beacon_interval, u8 dtim_interval)
+{
+	struct cmd_join *join;
+	int ret, i;
+	u8 *bssid;
+
+	join = kzalloc(sizeof(*join), GFP_KERNEL);
+	if (!join) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	wl1251_debug(DEBUG_CMD, "cmd join%s ch %d %d/%d",
+		     bss_type == BSS_TYPE_IBSS ? " ibss" : "",
+		     channel, beacon_interval, dtim_interval);
+
+	/* Reverse order BSSID */
+	bssid = (u8 *) &join->bssid_lsb;
+	for (i = 0; i < ETH_ALEN; i++)
+		bssid[i] = wl->bssid[ETH_ALEN - i - 1];
+
+	join->rx_config_options = wl->rx_config;
+	join->rx_filter_options = wl->rx_filter;
+
+	/*
+	 * FIXME: disable temporarily all filters because after commit
+	 * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
+	 * association. The filter logic needs to be implemented properly
+	 * and once that is done, this hack can be removed.
+	 */
+	join->rx_config_options = 0;
+	join->rx_filter_options = WL1251_DEFAULT_RX_FILTER;
+
+	join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
+		RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
+
+	join->beacon_interval = beacon_interval;
+	join->dtim_interval = dtim_interval;
+	join->bss_type = bss_type;
+	join->channel = channel;
+	join->ctrl = JOIN_CMD_CTRL_TX_FLUSH;
+
+	ret = wl1251_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
+	if (ret < 0) {
+		wl1251_error("failed to initiate cmd join");
+		goto out;
+	}
+
+out:
+	kfree(join);
+	return ret;
+}
+
+int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode)
+{
+	struct wl1251_cmd_ps_params *ps_params = NULL;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_CMD, "cmd set ps mode");
+
+	ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
+	if (!ps_params) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ps_params->ps_mode = ps_mode;
+	ps_params->send_null_data = 1;
+	ps_params->retries = 5;
+	ps_params->hang_over_period = 128;
+	ps_params->null_data_rate = 1; /* 1 Mbps */
+
+	ret = wl1251_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
+			      sizeof(*ps_params));
+	if (ret < 0) {
+		wl1251_error("cmd set_ps_mode failed");
+		goto out;
+	}
+
+out:
+	kfree(ps_params);
+	return ret;
+}
+
+int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
+			   size_t len)
+{
+	struct cmd_read_write_memory *cmd;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_CMD, "cmd read memory");
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	WARN_ON(len > MAX_READ_SIZE);
+	len = min_t(size_t, len, MAX_READ_SIZE);
+
+	cmd->addr = addr;
+	cmd->size = len;
+
+	ret = wl1251_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1251_error("read memory command failed: %d", ret);
+		goto out;
+	}
+
+	/* the read command got in, we can now read the answer */
+	wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
+
+	if (cmd->header.status != CMD_STATUS_SUCCESS)
+		wl1251_error("error in read command result: %d",
+			     cmd->header.status);
+
+	memcpy(answer, cmd->value, len);
+
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
+			    void *buf, size_t buf_len)
+{
+	struct wl1251_cmd_packet_template *cmd;
+	size_t cmd_len;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_CMD, "cmd template %d", cmd_id);
+
+	WARN_ON(buf_len > WL1251_MAX_TEMPLATE_SIZE);
+	buf_len = min_t(size_t, buf_len, WL1251_MAX_TEMPLATE_SIZE);
+	cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4);
+
+	cmd = kzalloc(cmd_len, GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->size = cpu_to_le16(buf_len);
+
+	if (buf)
+		memcpy(cmd->data, buf, buf_len);
+
+	ret = wl1251_cmd_send(wl, cmd_id, cmd, cmd_len);
+	if (ret < 0) {
+		wl1251_warning("cmd set_template failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(cmd);
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h
new file mode 100644
index 0000000..dff798a
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.h
@@ -0,0 +1,407 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_CMD_H__
+#define __WL1251_CMD_H__
+
+#include "wl1251.h"
+
+struct acx_header;
+
+int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len);
+int wl1251_cmd_test(struct wl1251 *wl, void *buf, size_t buf_len, u8 answer);
+int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len);
+int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len);
+int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity,
+		   void *bitmap, u16 bitmap_len, u8 bitmap_control);
+int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable);
+int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel,
+		    u16 beacon_interval, u8 dtim_interval);
+int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode);
+int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
+			   size_t len);
+int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
+			    void *buf, size_t buf_len);
+
+/* unit ms */
+#define WL1251_COMMAND_TIMEOUT 2000
+
+enum wl1251_commands {
+	CMD_RESET           = 0,
+	CMD_INTERROGATE     = 1,    /*use this to read information elements*/
+	CMD_CONFIGURE       = 2,    /*use this to write information elements*/
+	CMD_ENABLE_RX       = 3,
+	CMD_ENABLE_TX       = 4,
+	CMD_DISABLE_RX      = 5,
+	CMD_DISABLE_TX      = 6,
+	CMD_SCAN            = 8,
+	CMD_STOP_SCAN       = 9,
+	CMD_VBM             = 10,
+	CMD_START_JOIN      = 11,
+	CMD_SET_KEYS        = 12,
+	CMD_READ_MEMORY     = 13,
+	CMD_WRITE_MEMORY    = 14,
+	CMD_BEACON          = 19,
+	CMD_PROBE_RESP      = 20,
+	CMD_NULL_DATA       = 21,
+	CMD_PROBE_REQ       = 22,
+	CMD_TEST            = 23,
+	CMD_RADIO_CALIBRATE     = 25,   /* OBSOLETE */
+	CMD_ENABLE_RX_PATH      = 27,   /* OBSOLETE */
+	CMD_NOISE_HIST      = 28,
+	CMD_RX_RESET        = 29,
+	CMD_PS_POLL         = 30,
+	CMD_QOS_NULL_DATA   = 31,
+	CMD_LNA_CONTROL     = 32,
+	CMD_SET_BCN_MODE    = 33,
+	CMD_MEASUREMENT      = 34,
+	CMD_STOP_MEASUREMENT = 35,
+	CMD_DISCONNECT       = 36,
+	CMD_SET_PS_MODE      = 37,
+	CMD_CHANNEL_SWITCH   = 38,
+	CMD_STOP_CHANNEL_SWICTH = 39,
+	CMD_AP_DISCOVERY     = 40,
+	CMD_STOP_AP_DISCOVERY = 41,
+	CMD_SPS_SCAN = 42,
+	CMD_STOP_SPS_SCAN = 43,
+	CMD_HEALTH_CHECK     = 45,
+	CMD_DEBUG            = 46,
+	CMD_TRIGGER_SCAN_TO  = 47,
+
+	NUM_COMMANDS,
+	MAX_COMMAND_ID = 0xFFFF,
+};
+
+#define MAX_CMD_PARAMS 572
+
+struct wl1251_cmd_header {
+	u16 id;
+	u16 status;
+	/* payload */
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct  wl1251_command {
+	struct wl1251_cmd_header header;
+	u8  parameters[MAX_CMD_PARAMS];
+};
+
+enum {
+	CMD_MAILBOX_IDLE              		=  0,
+	CMD_STATUS_SUCCESS            		=  1,
+	CMD_STATUS_UNKNOWN_CMD        		=  2,
+	CMD_STATUS_UNKNOWN_IE         		=  3,
+	CMD_STATUS_REJECT_MEAS_SG_ACTIVE 	= 11,
+	CMD_STATUS_RX_BUSY            		= 13,
+	CMD_STATUS_INVALID_PARAM      		= 14,
+	CMD_STATUS_TEMPLATE_TOO_LARGE 		= 15,
+	CMD_STATUS_OUT_OF_MEMORY      		= 16,
+	CMD_STATUS_STA_TABLE_FULL     		= 17,
+	CMD_STATUS_RADIO_ERROR        		= 18,
+	CMD_STATUS_WRONG_NESTING      		= 19,
+	CMD_STATUS_TIMEOUT            		= 21, /* Driver internal use.*/
+	CMD_STATUS_FW_RESET           		= 22, /* Driver internal use.*/
+	MAX_COMMAND_STATUS            		= 0xff
+};
+
+
+/*
+ * CMD_READ_MEMORY
+ *
+ * The host issues this command to read the WiLink device memory/registers.
+ *
+ * Note: The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+/*
+ * CMD_WRITE_MEMORY
+ *
+ * The host issues this command to write the WiLink device memory/registers.
+ *
+ * The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+#define MAX_READ_SIZE 256
+
+struct cmd_read_write_memory {
+	struct wl1251_cmd_header header;
+
+	/* The address of the memory to read from or write to.*/
+	u32 addr;
+
+	/* The amount of data in bytes to read from or write to the WiLink
+	 * device.*/
+	u32 size;
+
+	/* The actual value read from or written to the Wilink. The source
+	   of this field is the Host in WRITE command or the Wilink in READ
+	   command. */
+	u8 value[MAX_READ_SIZE];
+};
+
+#define CMDMBOX_HEADER_LEN 4
+#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
+
+
+struct basic_scan_parameters {
+	u32 rx_config_options;
+	u32 rx_filter_options;
+
+	/*
+	 * Scan options:
+	 * bit 0: When this bit is set, passive scan.
+	 * bit 1: Band, when this bit is set we scan
+	 * in the 5Ghz band.
+	 * bit 2: voice mode, 0 for normal scan.
+	 * bit 3: scan priority, 1 for high priority.
+	 */
+	u16 scan_options;
+
+	/* Number of channels to scan */
+	u8 num_channels;
+
+	/* Number opf probe requests to send, per channel */
+	u8 num_probe_requests;
+
+	/* Rate and modulation for probe requests */
+	u16 tx_rate;
+
+	u8 tid_trigger;
+	u8 ssid_len;
+	u32 ssid[8];
+
+} __attribute__ ((packed));
+
+struct basic_scan_channel_parameters {
+	u32 min_duration; /* in TU */
+	u32 max_duration; /* in TU */
+	u32 bssid_lsb;
+	u16 bssid_msb;
+
+	/*
+	 * bits 0-3: Early termination count.
+	 * bits 4-5: Early termination condition.
+	 */
+	u8 early_termination;
+
+	u8 tx_power_att;
+	u8 channel;
+	u8 pad[3];
+} __attribute__ ((packed));
+
+/* SCAN parameters */
+#define SCAN_MAX_NUM_OF_CHANNELS 16
+
+struct cmd_scan {
+	struct wl1251_cmd_header header;
+
+	struct basic_scan_parameters params;
+	struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
+} __attribute__ ((packed));
+
+enum {
+	BSS_TYPE_IBSS = 0,
+	BSS_TYPE_STA_BSS = 2,
+	BSS_TYPE_AP_BSS = 3,
+	MAX_BSS_TYPE = 0xFF
+};
+
+#define JOIN_CMD_CTRL_TX_FLUSH             0x80 /* Firmware flushes all Tx */
+#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE  0x01 /* Early wakeup time */
+
+
+struct cmd_join {
+	struct wl1251_cmd_header header;
+
+	u32 bssid_lsb;
+	u16 bssid_msb;
+	u16 beacon_interval; /* in TBTTs */
+	u32 rx_config_options;
+	u32 rx_filter_options;
+
+	/*
+	 * The target uses this field to determine the rate at
+	 * which to transmit control frame responses (such as
+	 * ACK or CTS frames).
+	 */
+	u16 basic_rate_set;
+	u8 dtim_interval;
+	u8 tx_ctrl_frame_rate; /* OBSOLETE */
+	u8 tx_ctrl_frame_mod;  /* OBSOLETE */
+	/*
+	 * bits 0-2: This bitwise field specifies the type
+	 * of BSS to start or join (BSS_TYPE_*).
+	 * bit 4: Band - The radio band in which to join
+	 * or start.
+	 *  0 - 2.4GHz band
+	 *  1 - 5GHz band
+	 * bits 3, 5-7: Reserved
+	 */
+	u8 bss_type;
+	u8 channel;
+	u8 ssid_len;
+	u8 ssid[IW_ESSID_MAX_SIZE];
+	u8 ctrl; /* JOIN_CMD_CTRL_* */
+	u8 tx_mgt_frame_rate; /* OBSOLETE */
+	u8 tx_mgt_frame_mod;  /* OBSOLETE */
+	u8 reserved;
+} __attribute__ ((packed));
+
+struct cmd_enabledisable_path {
+	struct wl1251_cmd_header header;
+
+	u8 channel;
+	u8 padding[3];
+} __attribute__ ((packed));
+
+#define WL1251_MAX_TEMPLATE_SIZE 300
+
+struct wl1251_cmd_packet_template {
+	struct wl1251_cmd_header header;
+
+	__le16 size;
+	u8 data[0];
+} __attribute__ ((packed));
+
+#define TIM_ELE_ID    5
+#define PARTIAL_VBM_MAX    251
+
+struct wl1251_tim {
+	u8 identity;
+	u8 length;
+	u8 dtim_count;
+	u8 dtim_period;
+	u8 bitmap_ctrl;
+	u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
+} __attribute__ ((packed));
+
+/* Virtual Bit Map update */
+struct wl1251_cmd_vbm_update {
+	struct wl1251_cmd_header header;
+	__le16 len;
+	u8  padding[2];
+	struct wl1251_tim tim;
+} __attribute__ ((packed));
+
+enum wl1251_cmd_ps_mode {
+	STATION_ACTIVE_MODE,
+	STATION_POWER_SAVE_MODE
+};
+
+struct wl1251_cmd_ps_params {
+	struct wl1251_cmd_header header;
+
+	u8 ps_mode; /* STATION_* */
+	u8 send_null_data; /* Do we have to send NULL data packet ? */
+	u8 retries; /* Number of retires for the initial NULL data packet */
+
+	 /*
+	  * TUs during which the target stays awake after switching
+	  * to power save mode.
+	  */
+	u8 hang_over_period;
+	u16 null_data_rate;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct wl1251_cmd_trigger_scan_to {
+	struct wl1251_cmd_header header;
+
+	u32 timeout;
+};
+
+/* HW encryption keys */
+#define NUM_ACCESS_CATEGORIES_COPY 4
+#define MAX_KEY_SIZE 32
+
+/* When set, disable HW encryption */
+#define DF_ENCRYPTION_DISABLE      0x01
+/* When set, disable HW decryption */
+#define DF_SNIFF_MODE_ENABLE       0x80
+
+enum wl1251_cmd_key_action {
+	KEY_ADD_OR_REPLACE = 1,
+	KEY_REMOVE         = 2,
+	KEY_SET_ID         = 3,
+	MAX_KEY_ACTION     = 0xffff,
+};
+
+enum wl1251_cmd_key_type {
+	KEY_WEP_DEFAULT       = 0,
+	KEY_WEP_ADDR          = 1,
+	KEY_AES_GROUP         = 4,
+	KEY_AES_PAIRWISE      = 5,
+	KEY_WEP_GROUP         = 6,
+	KEY_TKIP_MIC_GROUP    = 10,
+	KEY_TKIP_MIC_PAIRWISE = 11,
+};
+
+/*
+ *
+ * key_type_e   key size    key format
+ * ----------   ---------   ----------
+ * 0x00         5, 13, 29   Key data
+ * 0x01         5, 13, 29   Key data
+ * 0x04         16          16 bytes of key data
+ * 0x05         16          16 bytes of key data
+ * 0x0a         32          16 bytes of TKIP key data
+ *                          8 bytes of RX MIC key data
+ *                          8 bytes of TX MIC key data
+ * 0x0b         32          16 bytes of TKIP key data
+ *                          8 bytes of RX MIC key data
+ *                          8 bytes of TX MIC key data
+ *
+ */
+
+struct wl1251_cmd_set_keys {
+	struct wl1251_cmd_header header;
+
+	/* Ignored for default WEP key */
+	u8 addr[ETH_ALEN];
+
+	/* key_action_e */
+	u16 key_action;
+
+	u16 reserved_1;
+
+	/* key size in bytes */
+	u8 key_size;
+
+	/* key_type_e */
+	u8 key_type;
+	u8 ssid_profile;
+
+	/*
+	 * TKIP, AES: frame's key id field.
+	 * For WEP default key: key id;
+	 */
+	u8 id;
+	u8 reserved_2[6];
+	u8 key[MAX_KEY_SIZE];
+	u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+	u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+} __attribute__ ((packed));
+
+
+#endif /* __WL1251_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
new file mode 100644
index 0000000..a007230
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c
@@ -0,0 +1,518 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * 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 "wl1251_debugfs.h"
+
+#include <linux/skbuff.h>
+
+#include "wl1251.h"
+#include "wl1251_acx.h"
+#include "wl1251_ps.h"
+
+/* ms */
+#define WL1251_DEBUGFS_STATS_LIFETIME 1000
+
+/* debugfs macros idea from mac80211 */
+
+#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)		\
+static ssize_t name## _read(struct file *file, char __user *userbuf,	\
+			    size_t count, loff_t *ppos)			\
+{									\
+	struct wl1251 *wl = file->private_data;				\
+	char buf[buflen];						\
+	int res;							\
+									\
+	res = scnprintf(buf, buflen, fmt "\n", ##value);		\
+	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
+}									\
+									\
+static const struct file_operations name## _ops = {			\
+	.read = name## _read,						\
+	.open = wl1251_open_file_generic,				\
+};
+
+#define DEBUGFS_ADD(name, parent)					\
+	wl->debugfs.name = debugfs_create_file(#name, 0400, parent,	\
+					       wl, &name## _ops);	\
+	if (IS_ERR(wl->debugfs.name)) {					\
+		ret = PTR_ERR(wl->debugfs.name);			\
+		wl->debugfs.name = NULL;				\
+		goto out;						\
+	}
+
+#define DEBUGFS_DEL(name)						\
+	do {								\
+		debugfs_remove(wl->debugfs.name);			\
+		wl->debugfs.name = NULL;				\
+	} while (0)
+
+#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt)			\
+static ssize_t sub## _ ##name## _read(struct file *file,		\
+				      char __user *userbuf,		\
+				      size_t count, loff_t *ppos)	\
+{									\
+	struct wl1251 *wl = file->private_data;				\
+	char buf[buflen];						\
+	int res;							\
+									\
+	wl1251_debugfs_update_stats(wl);				\
+									\
+	res = scnprintf(buf, buflen, fmt "\n",				\
+			wl->stats.fw_stats->sub.name);			\
+	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
+}									\
+									\
+static const struct file_operations sub## _ ##name## _ops = {		\
+	.read = sub## _ ##name## _read,					\
+	.open = wl1251_open_file_generic,				\
+};
+
+#define DEBUGFS_FWSTATS_ADD(sub, name)				\
+	DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
+
+#define DEBUGFS_FWSTATS_DEL(sub, name)				\
+	DEBUGFS_DEL(sub## _ ##name)
+
+static void wl1251_debugfs_update_stats(struct wl1251 *wl)
+{
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	if (wl->state == WL1251_STATE_ON &&
+	    time_after(jiffies, wl->stats.fw_stats_update +
+		       msecs_to_jiffies(WL1251_DEBUGFS_STATS_LIFETIME))) {
+		wl1251_acx_statistics(wl, wl->stats.fw_stats);
+		wl->stats.fw_stats_update = jiffies;
+	}
+
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_open_file_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
+/* skipping wep.reserved */
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
+/* skipping cont_miss_bcns_spread for now */
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
+		     20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
+		      wl->stats.excessive_retries);
+
+static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	struct wl1251 *wl = file->private_data;
+	u32 queue_len;
+	char buf[20];
+	int res;
+
+	queue_len = skb_queue_len(&wl->tx_queue);
+
+	res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
+	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+static const struct file_operations tx_queue_len_ops = {
+	.read = tx_queue_len_read,
+	.open = wl1251_open_file_generic,
+};
+
+static void wl1251_debugfs_delete_files(struct wl1251 *wl)
+{
+	DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
+
+	DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
+	DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
+	DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
+	DEBUGFS_FWSTATS_DEL(rx, dropped);
+	DEBUGFS_FWSTATS_DEL(rx, fcs_err);
+	DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
+	DEBUGFS_FWSTATS_DEL(rx, path_reset);
+	DEBUGFS_FWSTATS_DEL(rx, reset_counter);
+
+	DEBUGFS_FWSTATS_DEL(dma, rx_requested);
+	DEBUGFS_FWSTATS_DEL(dma, rx_errors);
+	DEBUGFS_FWSTATS_DEL(dma, tx_requested);
+	DEBUGFS_FWSTATS_DEL(dma, tx_errors);
+
+	DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
+	DEBUGFS_FWSTATS_DEL(isr, fiqs);
+	DEBUGFS_FWSTATS_DEL(isr, rx_headers);
+	DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
+	DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
+	DEBUGFS_FWSTATS_DEL(isr, irqs);
+	DEBUGFS_FWSTATS_DEL(isr, tx_procs);
+	DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
+	DEBUGFS_FWSTATS_DEL(isr, dma0_done);
+	DEBUGFS_FWSTATS_DEL(isr, dma1_done);
+	DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
+	DEBUGFS_FWSTATS_DEL(isr, commands);
+	DEBUGFS_FWSTATS_DEL(isr, rx_procs);
+	DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
+	DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
+	DEBUGFS_FWSTATS_DEL(isr, pci_pm);
+	DEBUGFS_FWSTATS_DEL(isr, wakeups);
+	DEBUGFS_FWSTATS_DEL(isr, low_rssi);
+
+	DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
+	DEBUGFS_FWSTATS_DEL(wep, default_key_count);
+	/* skipping wep.reserved */
+	DEBUGFS_FWSTATS_DEL(wep, key_not_found);
+	DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
+	DEBUGFS_FWSTATS_DEL(wep, packets);
+	DEBUGFS_FWSTATS_DEL(wep, interrupt);
+
+	DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
+	DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
+	DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
+	DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
+	DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
+	DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
+	DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
+	DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
+	/* skipping cont_miss_bcns_spread for now */
+	DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
+
+	DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
+	DEBUGFS_FWSTATS_DEL(mic, calc_failure);
+
+	DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
+	DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
+	DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
+	DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
+	DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
+	DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
+
+	DEBUGFS_FWSTATS_DEL(event, heart_beat);
+	DEBUGFS_FWSTATS_DEL(event, calibration);
+	DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
+	DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
+	DEBUGFS_FWSTATS_DEL(event, rx_pool);
+	DEBUGFS_FWSTATS_DEL(event, oom_late);
+	DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
+	DEBUGFS_FWSTATS_DEL(event, tx_stuck);
+
+	DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
+	DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
+	DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
+
+	DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
+	DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+	DEBUGFS_DEL(tx_queue_len);
+	DEBUGFS_DEL(retry_count);
+	DEBUGFS_DEL(excessive_retries);
+}
+
+static int wl1251_debugfs_add_files(struct wl1251 *wl)
+{
+	int ret = 0;
+
+	DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
+
+	DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
+	DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
+	DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
+	DEBUGFS_FWSTATS_ADD(rx, dropped);
+	DEBUGFS_FWSTATS_ADD(rx, fcs_err);
+	DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
+	DEBUGFS_FWSTATS_ADD(rx, path_reset);
+	DEBUGFS_FWSTATS_ADD(rx, reset_counter);
+
+	DEBUGFS_FWSTATS_ADD(dma, rx_requested);
+	DEBUGFS_FWSTATS_ADD(dma, rx_errors);
+	DEBUGFS_FWSTATS_ADD(dma, tx_requested);
+	DEBUGFS_FWSTATS_ADD(dma, tx_errors);
+
+	DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
+	DEBUGFS_FWSTATS_ADD(isr, fiqs);
+	DEBUGFS_FWSTATS_ADD(isr, rx_headers);
+	DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
+	DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
+	DEBUGFS_FWSTATS_ADD(isr, irqs);
+	DEBUGFS_FWSTATS_ADD(isr, tx_procs);
+	DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
+	DEBUGFS_FWSTATS_ADD(isr, dma0_done);
+	DEBUGFS_FWSTATS_ADD(isr, dma1_done);
+	DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
+	DEBUGFS_FWSTATS_ADD(isr, commands);
+	DEBUGFS_FWSTATS_ADD(isr, rx_procs);
+	DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
+	DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
+	DEBUGFS_FWSTATS_ADD(isr, pci_pm);
+	DEBUGFS_FWSTATS_ADD(isr, wakeups);
+	DEBUGFS_FWSTATS_ADD(isr, low_rssi);
+
+	DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
+	DEBUGFS_FWSTATS_ADD(wep, default_key_count);
+	/* skipping wep.reserved */
+	DEBUGFS_FWSTATS_ADD(wep, key_not_found);
+	DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
+	DEBUGFS_FWSTATS_ADD(wep, packets);
+	DEBUGFS_FWSTATS_ADD(wep, interrupt);
+
+	DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
+	DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
+	DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
+	DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
+	DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
+	DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
+	DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
+	DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
+	/* skipping cont_miss_bcns_spread for now */
+	DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
+
+	DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
+	DEBUGFS_FWSTATS_ADD(mic, calc_failure);
+
+	DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
+	DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
+	DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
+	DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
+	DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
+	DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
+
+	DEBUGFS_FWSTATS_ADD(event, heart_beat);
+	DEBUGFS_FWSTATS_ADD(event, calibration);
+	DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
+	DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
+	DEBUGFS_FWSTATS_ADD(event, rx_pool);
+	DEBUGFS_FWSTATS_ADD(event, oom_late);
+	DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
+	DEBUGFS_FWSTATS_ADD(event, tx_stuck);
+
+	DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
+	DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
+	DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
+
+	DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
+	DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+	DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+	DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
+	DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
+
+out:
+	if (ret < 0)
+		wl1251_debugfs_delete_files(wl);
+
+	return ret;
+}
+
+void wl1251_debugfs_reset(struct wl1251 *wl)
+{
+	memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+	wl->stats.retry_count = 0;
+	wl->stats.excessive_retries = 0;
+}
+
+int wl1251_debugfs_init(struct wl1251 *wl)
+{
+	int ret;
+
+	wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+	if (IS_ERR(wl->debugfs.rootdir)) {
+		ret = PTR_ERR(wl->debugfs.rootdir);
+		wl->debugfs.rootdir = NULL;
+		goto err;
+	}
+
+	wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
+						       wl->debugfs.rootdir);
+
+	if (IS_ERR(wl->debugfs.fw_statistics)) {
+		ret = PTR_ERR(wl->debugfs.fw_statistics);
+		wl->debugfs.fw_statistics = NULL;
+		goto err_root;
+	}
+
+	wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
+				      GFP_KERNEL);
+
+	if (!wl->stats.fw_stats) {
+		ret = -ENOMEM;
+		goto err_fw;
+	}
+
+	wl->stats.fw_stats_update = jiffies;
+
+	ret = wl1251_debugfs_add_files(wl);
+
+	if (ret < 0)
+		goto err_file;
+
+	return 0;
+
+err_file:
+	kfree(wl->stats.fw_stats);
+	wl->stats.fw_stats = NULL;
+
+err_fw:
+	debugfs_remove(wl->debugfs.fw_statistics);
+	wl->debugfs.fw_statistics = NULL;
+
+err_root:
+	debugfs_remove(wl->debugfs.rootdir);
+	wl->debugfs.rootdir = NULL;
+
+err:
+	return ret;
+}
+
+void wl1251_debugfs_exit(struct wl1251 *wl)
+{
+	wl1251_debugfs_delete_files(wl);
+
+	kfree(wl->stats.fw_stats);
+	wl->stats.fw_stats = NULL;
+
+	debugfs_remove(wl->debugfs.fw_statistics);
+	wl->debugfs.fw_statistics = NULL;
+
+	debugfs_remove(wl->debugfs.rootdir);
+	wl->debugfs.rootdir = NULL;
+
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl12xx/wl1251_debugfs.h
new file mode 100644
index 0000000..6dc3d08
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef WL1251_DEBUGFS_H
+#define WL1251_DEBUGFS_H
+
+#include "wl1251.h"
+
+int wl1251_debugfs_init(struct wl1251 *wl);
+void wl1251_debugfs_exit(struct wl1251 *wl);
+void wl1251_debugfs_reset(struct wl1251 *wl);
+
+#endif /* WL1251_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl12xx/wl1251_event.c
new file mode 100644
index 0000000..00076c4
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_event.c
@@ -0,0 +1,128 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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 "wl1251.h"
+#include "wl1251_reg.h"
+#include "wl1251_io.h"
+#include "wl1251_event.h"
+#include "wl1251_ps.h"
+
+static int wl1251_event_scan_complete(struct wl1251 *wl,
+				      struct event_mailbox *mbox)
+{
+	wl1251_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
+		     mbox->scheduled_scan_status,
+		     mbox->scheduled_scan_channels);
+
+	if (wl->scanning) {
+		mutex_unlock(&wl->mutex);
+		ieee80211_scan_completed(wl->hw, false);
+		mutex_lock(&wl->mutex);
+		wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed");
+		wl->scanning = false;
+	}
+
+	return 0;
+}
+
+static void wl1251_event_mbox_dump(struct event_mailbox *mbox)
+{
+	wl1251_debug(DEBUG_EVENT, "MBOX DUMP:");
+	wl1251_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
+	wl1251_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
+}
+
+static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
+{
+	int ret;
+	u32 vector;
+
+	wl1251_event_mbox_dump(mbox);
+
+	vector = mbox->events_vector & ~(mbox->events_mask);
+	wl1251_debug(DEBUG_EVENT, "vector: 0x%x", vector);
+
+	if (vector & SCAN_COMPLETE_EVENT_ID) {
+		ret = wl1251_event_scan_complete(wl, mbox);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (vector & BSS_LOSE_EVENT_ID) {
+		wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
+
+		if (wl->psm_requested && wl->psm) {
+			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int wl1251_event_unmask(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_event_mbox_mask(wl, ~(wl->event_mask));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+void wl1251_event_mbox_config(struct wl1251 *wl)
+{
+	wl->mbox_ptr[0] = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+	wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
+
+	wl1251_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
+		     wl->mbox_ptr[0], wl->mbox_ptr[1]);
+}
+
+int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num)
+{
+	struct event_mailbox mbox;
+	int ret;
+
+	wl1251_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
+
+	if (mbox_num > 1)
+		return -EINVAL;
+
+	/* first we read the mbox descriptor */
+	wl1251_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+			    sizeof(struct event_mailbox));
+
+	/* process the descriptor */
+	ret = wl1251_event_process(wl, &mbox);
+	if (ret < 0)
+		return ret;
+
+	/* then we let the firmware know it can go on...*/
+	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+
+	return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl12xx/wl1251_event.h
new file mode 100644
index 0000000..be0ac54
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_event.h
@@ -0,0 +1,121 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_EVENT_H__
+#define __WL1251_EVENT_H__
+
+/*
+ * Mbox events
+ *
+ * The event mechanism is based on a pair of event buffers (buffers A and
+ * B) at fixed locations in the target's memory. The host processes one
+ * buffer while the other buffer continues to collect events. If the host
+ * is not processing events, an interrupt is issued to signal that a buffer
+ * is ready. Once the host is done with processing events from one buffer,
+ * it signals the target (with an ACK interrupt) that the event buffer is
+ * free.
+ */
+
+enum {
+	RESERVED1_EVENT_ID                       = BIT(0),
+	RESERVED2_EVENT_ID                       = BIT(1),
+	MEASUREMENT_START_EVENT_ID               = BIT(2),
+	SCAN_COMPLETE_EVENT_ID                   = BIT(3),
+	CALIBRATION_COMPLETE_EVENT_ID            = BIT(4),
+	ROAMING_TRIGGER_LOW_RSSI_EVENT_ID        = BIT(5),
+	PS_REPORT_EVENT_ID                       = BIT(6),
+	SYNCHRONIZATION_TIMEOUT_EVENT_ID         = BIT(7),
+	HEALTH_REPORT_EVENT_ID                   = BIT(8),
+	ACI_DETECTION_EVENT_ID                   = BIT(9),
+	DEBUG_REPORT_EVENT_ID                    = BIT(10),
+	MAC_STATUS_EVENT_ID                      = BIT(11),
+	DISCONNECT_EVENT_COMPLETE_ID             = BIT(12),
+	JOIN_EVENT_COMPLETE_ID                   = BIT(13),
+	CHANNEL_SWITCH_COMPLETE_EVENT_ID         = BIT(14),
+	BSS_LOSE_EVENT_ID                        = BIT(15),
+	ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID    = BIT(16),
+	MEASUREMENT_COMPLETE_EVENT_ID            = BIT(17),
+	AP_DISCOVERY_COMPLETE_EVENT_ID           = BIT(18),
+	SCHEDULED_SCAN_COMPLETE_EVENT_ID         = BIT(19),
+	PSPOLL_DELIVERY_FAILURE_EVENT_ID 	 = BIT(20),
+	RESET_BSS_EVENT_ID                       = BIT(21),
+	REGAINED_BSS_EVENT_ID                    = BIT(22),
+	ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID   = BIT(23),
+	ROAMING_TRIGGER_LOW_SNR_EVENT_ID         = BIT(24),
+	ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID    = BIT(25),
+
+	DBG_EVENT_ID                             = BIT(26),
+	BT_PTA_SENSE_EVENT_ID                    = BIT(27),
+	BT_PTA_PREDICTION_EVENT_ID               = BIT(28),
+	BT_PTA_AVALANCHE_EVENT_ID                = BIT(29),
+
+	PLT_RX_CALIBRATION_COMPLETE_EVENT_ID     = BIT(30),
+
+	EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
+};
+
+struct event_debug_report {
+	u8 debug_event_id;
+	u8 num_params;
+	u16 pad;
+	u32 report_1;
+	u32 report_2;
+	u32 report_3;
+} __attribute__ ((packed));
+
+struct event_mailbox {
+	u32 events_vector;
+	u32 events_mask;
+	u32 reserved_1;
+	u32 reserved_2;
+
+	char average_rssi_level;
+	u8 ps_status;
+	u8 channel_switch_status;
+	u8 scheduled_scan_status;
+
+	/* Channels scanned by the scheduled scan */
+	u16 scheduled_scan_channels;
+
+	/* If bit 0 is set -> target's fatal error */
+	u16 health_report;
+	u16 bad_fft_counter;
+	u8 bt_pta_sense_info;
+	u8 bt_pta_protective_info;
+	u32 reserved;
+	u32 debug_report[2];
+
+	/* Number of FCS errors since last event */
+	u32 fcs_err_counter;
+
+	struct event_debug_report report;
+	u8 average_snr_level;
+	u8 padding[19];
+} __attribute__ ((packed));
+
+int wl1251_event_unmask(struct wl1251 *wl);
+void wl1251_event_mbox_config(struct wl1251 *wl);
+int wl1251_event_handle(struct wl1251 *wl, u8 mbox);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl12xx/wl1251_init.c
new file mode 100644
index 0000000..b2ee4f4
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_init.c
@@ -0,0 +1,413 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+
+#include "wl1251_init.h"
+#include "wl12xx_80211.h"
+#include "wl1251_acx.h"
+#include "wl1251_cmd.h"
+#include "wl1251_reg.h"
+
+int wl1251_hw_init_hwenc_config(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_feature_cfg(wl);
+	if (ret < 0) {
+		wl1251_warning("couldn't set feature config");
+		return ret;
+	}
+
+	ret = wl1251_acx_default_key(wl, wl->default_key);
+	if (ret < 0) {
+		wl1251_warning("couldn't set default key");
+		return ret;
+	}
+
+	return 0;
+}
+
+int wl1251_hw_init_templates_config(struct wl1251 *wl)
+{
+	int ret;
+	u8 partial_vbm[PARTIAL_VBM_MAX];
+
+	/* send empty templates for fw memory reservation */
+	ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
+				      sizeof(struct wl12xx_probe_req_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, NULL,
+				      sizeof(struct wl12xx_null_data_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_cmd_template_set(wl, CMD_PS_POLL, NULL,
+				      sizeof(struct wl12xx_ps_poll_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
+				      sizeof
+				      (struct wl12xx_qos_null_data_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
+				      sizeof
+				      (struct wl12xx_probe_resp_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_cmd_template_set(wl, CMD_BEACON, NULL,
+				      sizeof
+				      (struct wl12xx_beacon_template));
+	if (ret < 0)
+		return ret;
+
+	/* tim templates, first reserve space then allocate an empty one */
+	memset(partial_vbm, 0, PARTIAL_VBM_MAX);
+	ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter)
+{
+	int ret;
+
+	ret = wl1251_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_acx_rx_config(wl, config, filter);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_hw_init_phy_config(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_pd_threshold(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_acx_slot(wl, DEFAULT_SLOT_TIME);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_acx_group_address_tbl(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_acx_service_period_timeout(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_hw_init_beacon_filter(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_beacon_filter_opt(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_acx_beacon_filter_table(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_hw_init_pta(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_sg_enable(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_acx_sg_cfg(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_hw_init_energy_detection(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_cca_threshold(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_bcn_dtim_options(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1251_hw_init_power_auth(struct wl1251 *wl)
+{
+	return wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
+}
+
+int wl1251_hw_init_mem_config(struct wl1251 *wl)
+{
+	int ret;
+
+	ret = wl1251_acx_mem_cfg(wl);
+	if (ret < 0)
+		return ret;
+
+	wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
+					  GFP_KERNEL);
+	if (!wl->target_mem_map) {
+		wl1251_error("couldn't allocate target memory map");
+		return -ENOMEM;
+	}
+
+	/* we now ask for the firmware built memory map */
+	ret = wl1251_acx_mem_map(wl, wl->target_mem_map,
+				 sizeof(struct wl1251_acx_mem_map));
+	if (ret < 0) {
+		wl1251_error("couldn't retrieve firmware memory map");
+		kfree(wl->target_mem_map);
+		wl->target_mem_map = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+static int wl1251_hw_init_txq_fill(u8 qid,
+				   struct acx_tx_queue_qos_config *config,
+				   u32 num_blocks)
+{
+	config->qid = qid;
+
+	switch (qid) {
+	case QOS_AC_BE:
+		config->high_threshold =
+			(QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
+		config->low_threshold =
+			(QOS_TX_LOW_BE_DEF * num_blocks) / 100;
+		break;
+	case QOS_AC_BK:
+		config->high_threshold =
+			(QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
+		config->low_threshold =
+			(QOS_TX_LOW_BK_DEF * num_blocks) / 100;
+		break;
+	case QOS_AC_VI:
+		config->high_threshold =
+			(QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
+		config->low_threshold =
+			(QOS_TX_LOW_VI_DEF * num_blocks) / 100;
+		break;
+	case QOS_AC_VO:
+		config->high_threshold =
+			(QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
+		config->low_threshold =
+			(QOS_TX_LOW_VO_DEF * num_blocks) / 100;
+		break;
+	default:
+		wl1251_error("Invalid TX queue id: %d", qid);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl)
+{
+	struct acx_tx_queue_qos_config *config;
+	struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
+	int ret, i;
+
+	wl1251_debug(DEBUG_ACX, "acx tx queue config");
+
+	config = kzalloc(sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < MAX_NUM_OF_AC; i++) {
+		ret = wl1251_hw_init_txq_fill(i, config,
+					      wl_mem_map->num_tx_mem_blocks);
+		if (ret < 0)
+			goto out;
+
+		ret = wl1251_cmd_configure(wl, ACX_TX_QUEUE_CFG,
+					   config, sizeof(*config));
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	kfree(config);
+	return ret;
+}
+
+static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
+{
+	int ret;
+
+	/* asking for the data path parameters */
+	wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
+				GFP_KERNEL);
+	if (!wl->data_path) {
+		wl1251_error("Couldnt allocate data path parameters");
+		return -ENOMEM;
+	}
+
+	ret = wl1251_acx_data_path_params(wl, wl->data_path);
+	if (ret < 0) {
+		kfree(wl->data_path);
+		wl->data_path = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+
+int wl1251_hw_init(struct wl1251 *wl)
+{
+	struct wl1251_acx_mem_map *wl_mem_map;
+	int ret;
+
+	ret = wl1251_hw_init_hwenc_config(wl);
+	if (ret < 0)
+		return ret;
+
+	/* Template settings */
+	ret = wl1251_hw_init_templates_config(wl);
+	if (ret < 0)
+		return ret;
+
+	/* Default memory configuration */
+	ret = wl1251_hw_init_mem_config(wl);
+	if (ret < 0)
+		return ret;
+
+	/* Default data path configuration  */
+	ret = wl1251_hw_init_data_path_config(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* RX config */
+	ret = wl1251_hw_init_rx_config(wl,
+				       RX_CFG_PROMISCUOUS | RX_CFG_TSF,
+				       RX_FILTER_OPTION_DEF);
+	/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
+	   RX_FILTER_OPTION_FILTER_ALL); */
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* TX queues config */
+	ret = wl1251_hw_init_tx_queue_config(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* PHY layer config */
+	ret = wl1251_hw_init_phy_config(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* Beacon filtering */
+	ret = wl1251_hw_init_beacon_filter(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* Bluetooth WLAN coexistence */
+	ret = wl1251_hw_init_pta(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* Energy detection */
+	ret = wl1251_hw_init_energy_detection(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* Beacons and boradcast settings */
+	ret = wl1251_hw_init_beacon_broadcast(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* Enable data path */
+	ret = wl1251_cmd_data_path(wl, wl->channel, 1);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	/* Default power state */
+	ret = wl1251_hw_init_power_auth(wl);
+	if (ret < 0)
+		goto out_free_data_path;
+
+	wl_mem_map = wl->target_mem_map;
+	wl1251_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
+		    wl_mem_map->num_tx_mem_blocks,
+		    wl->data_path->tx_control_addr,
+		    wl_mem_map->num_rx_mem_blocks,
+		    wl->data_path->rx_control_addr);
+
+	return 0;
+
+ out_free_data_path:
+	kfree(wl->data_path);
+
+ out_free_memmap:
+	kfree(wl->target_mem_map);
+
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl12xx/wl1251_init.h
new file mode 100644
index 0000000..b3b25ec
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_init.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_INIT_H__
+#define __WL1251_INIT_H__
+
+#include "wl1251.h"
+
+int wl1251_hw_init_hwenc_config(struct wl1251 *wl);
+int wl1251_hw_init_templates_config(struct wl1251 *wl);
+int wl1251_hw_init_rx_config(struct wl1251 *wl, u32 config, u32 filter);
+int wl1251_hw_init_phy_config(struct wl1251 *wl);
+int wl1251_hw_init_beacon_filter(struct wl1251 *wl);
+int wl1251_hw_init_pta(struct wl1251 *wl);
+int wl1251_hw_init_energy_detection(struct wl1251 *wl);
+int wl1251_hw_init_beacon_broadcast(struct wl1251 *wl);
+int wl1251_hw_init_power_auth(struct wl1251 *wl);
+int wl1251_hw_init_mem_config(struct wl1251 *wl);
+int wl1251_hw_init(struct wl1251 *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl12xx/wl1251_io.c
new file mode 100644
index 0000000..f1c232e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_io.c
@@ -0,0 +1,196 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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 "wl1251.h"
+#include "wl1251_reg.h"
+#include "wl1251_io.h"
+
+/* FIXME: this is static data nowadays and the table can be removed */
+static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = {
+	[ACX_REG_INTERRUPT_TRIG]     = (REGISTERS_BASE + 0x0474),
+	[ACX_REG_INTERRUPT_TRIG_H]   = (REGISTERS_BASE + 0x0478),
+	[ACX_REG_INTERRUPT_MASK]     = (REGISTERS_BASE + 0x0494),
+	[ACX_REG_HINT_MASK_SET]      = (REGISTERS_BASE + 0x0498),
+	[ACX_REG_HINT_MASK_CLR]      = (REGISTERS_BASE + 0x049C),
+	[ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
+	[ACX_REG_INTERRUPT_CLEAR]    = (REGISTERS_BASE + 0x04A4),
+	[ACX_REG_INTERRUPT_ACK]      = (REGISTERS_BASE + 0x04A8),
+	[ACX_REG_SLV_SOFT_RESET]     = (REGISTERS_BASE + 0x0000),
+	[ACX_REG_EE_START]           = (REGISTERS_BASE + 0x080C),
+	[ACX_REG_ECPU_CONTROL]       = (REGISTERS_BASE + 0x0804)
+};
+
+static int wl1251_translate_reg_addr(struct wl1251 *wl, int addr)
+{
+	/* If the address is lower than REGISTERS_BASE, it means that this is
+	 * a chip-specific register address, so look it up in the registers
+	 * table */
+	if (addr < REGISTERS_BASE) {
+		/* Make sure we don't go over the table */
+		if (addr >= ACX_REG_TABLE_LEN) {
+			wl1251_error("address out of range (%d)", addr);
+			return -EINVAL;
+		}
+		addr = wl1251_io_reg_table[addr];
+	}
+
+	return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
+}
+
+static int wl1251_translate_mem_addr(struct wl1251 *wl, int addr)
+{
+	return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+}
+
+void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int physical;
+
+	physical = wl1251_translate_mem_addr(wl, addr);
+
+	wl->if_ops->read(wl, physical, buf, len);
+}
+
+void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int physical;
+
+	physical = wl1251_translate_mem_addr(wl, addr);
+
+	wl->if_ops->write(wl, physical, buf, len);
+}
+
+u32 wl1251_mem_read32(struct wl1251 *wl, int addr)
+{
+	return wl1251_read32(wl, wl1251_translate_mem_addr(wl, addr));
+}
+
+void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val)
+{
+	wl1251_write32(wl, wl1251_translate_mem_addr(wl, addr), val);
+}
+
+u32 wl1251_reg_read32(struct wl1251 *wl, int addr)
+{
+	return wl1251_read32(wl, wl1251_translate_reg_addr(wl, addr));
+}
+
+void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val)
+{
+	wl1251_write32(wl, wl1251_translate_reg_addr(wl, addr), val);
+}
+
+/* Set the partitions to access the chip addresses.
+ *
+ * There are two VIRTUAL partitions (the memory partition and the
+ * registers partition), which are mapped to two different areas of the
+ * PHYSICAL (hardware) memory.  This function also makes other checks to
+ * ensure that the partitions are not overlapping.  In the diagram below, the
+ * memory partition comes before the register partition, but the opposite is
+ * also supported.
+ *
+ *                               PHYSICAL address
+ *                                     space
+ *
+ *                                    |    |
+ *                                 ...+----+--> mem_start
+ *          VIRTUAL address     ...   |    |
+ *               space       ...      |    | [PART_0]
+ *                        ...         |    |
+ * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
+ *               |    |         ...   |    |
+ *               |MEM |      ...      |    |
+ *               |    |   ...         |    |
+ *  part_size <--+----+...            |    | {unused area)
+ *               |    |   ...         |    |
+ *               |REG |      ...      |    |
+ *  part_size    |    |         ...   |    |
+ *      +     <--+----+...         ...+----+--> reg_start
+ *  reg_size              ...         |    |
+ *                           ...      |    | [PART_1]
+ *                              ...   |    |
+ *                                 ...+----+--> reg_start + reg_size
+ *                                    |    |
+ *
+ */
+void wl1251_set_partition(struct wl1251 *wl,
+			  u32 mem_start, u32 mem_size,
+			  u32 reg_start, u32 reg_size)
+{
+	struct wl1251_partition partition[2];
+
+	wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+		     mem_start, mem_size);
+	wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+		     reg_start, reg_size);
+
+	/* Make sure that the two partitions together don't exceed the
+	 * address range */
+	if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
+		wl1251_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
+			     " address range.  Truncating partition[0].");
+		mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
+		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	}
+
+	if ((mem_start < reg_start) &&
+	    ((mem_start + mem_size) > reg_start)) {
+		/* Guarantee that the memory partition doesn't overlap the
+		 * registers partition */
+		wl1251_debug(DEBUG_SPI, "End of partition[0] is "
+			     "overlapping partition[1].  Adjusted.");
+		mem_size = reg_start - mem_start;
+		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	} else if ((reg_start < mem_start) &&
+		   ((reg_start + reg_size) > mem_start)) {
+		/* Guarantee that the register partition doesn't overlap the
+		 * memory partition */
+		wl1251_debug(DEBUG_SPI, "End of partition[1] is"
+			     " overlapping partition[0].  Adjusted.");
+		reg_size = mem_start - reg_start;
+		wl1251_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1251_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	}
+
+	partition[0].start = mem_start;
+	partition[0].size  = mem_size;
+	partition[1].start = reg_start;
+	partition[1].size  = reg_size;
+
+	wl->physical_mem_addr = mem_start;
+	wl->physical_reg_addr = reg_start;
+
+	wl->virtual_mem_addr = 0;
+	wl->virtual_reg_addr = mem_size;
+
+	wl->if_ops->write(wl, HW_ACCESS_PART0_SIZE_ADDR, partition,
+		sizeof(partition));
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl12xx/wl1251_io.h
new file mode 100644
index 0000000..b89d2ac
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_io.h
@@ -0,0 +1,64 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * 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
+ *
+ */
+#ifndef __WL1251_IO_H__
+#define __WL1251_IO_H__
+
+#include "wl1251.h"
+
+#define HW_ACCESS_MEMORY_MAX_RANGE		0x1FFC0
+
+#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
+#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
+#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
+#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
+
+#define HW_ACCESS_REGISTER_SIZE             4
+
+#define HW_ACCESS_PRAM_MAX_RANGE		0x3c000
+
+static inline u32 wl1251_read32(struct wl1251 *wl, int addr)
+{
+	u32 response;
+
+	wl->if_ops->read(wl, addr, &response, sizeof(u32));
+
+	return response;
+}
+
+static inline void wl1251_write32(struct wl1251 *wl, int addr, u32 val)
+{
+	wl->if_ops->write(wl, addr, &val, sizeof(u32));
+}
+
+/* Memory target IO, address is translated to partition 0 */
+void wl1251_mem_read(struct wl1251 *wl, int addr, void *buf, size_t len);
+void wl1251_mem_write(struct wl1251 *wl, int addr, void *buf, size_t len);
+u32 wl1251_mem_read32(struct wl1251 *wl, int addr);
+void wl1251_mem_write32(struct wl1251 *wl, int addr, u32 val);
+/* Registers IO */
+u32 wl1251_reg_read32(struct wl1251 *wl, int addr);
+void wl1251_reg_write32(struct wl1251 *wl, int addr, u32 val);
+
+void wl1251_set_partition(struct wl1251 *wl,
+			  u32 part_start, u32 part_size,
+			  u32 reg_start,  u32 reg_size);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
new file mode 100644
index 0000000..5809ef5
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -0,0 +1,1428 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+
+#include "wl1251.h"
+#include "wl12xx_80211.h"
+#include "wl1251_reg.h"
+#include "wl1251_io.h"
+#include "wl1251_cmd.h"
+#include "wl1251_event.h"
+#include "wl1251_tx.h"
+#include "wl1251_rx.h"
+#include "wl1251_ps.h"
+#include "wl1251_init.h"
+#include "wl1251_debugfs.h"
+#include "wl1251_boot.h"
+
+void wl1251_enable_interrupts(struct wl1251 *wl)
+{
+	wl->if_ops->enable_irq(wl);
+}
+
+void wl1251_disable_interrupts(struct wl1251 *wl)
+{
+	wl->if_ops->disable_irq(wl);
+}
+
+static void wl1251_power_off(struct wl1251 *wl)
+{
+	wl->set_power(false);
+}
+
+static void wl1251_power_on(struct wl1251 *wl)
+{
+	wl->set_power(true);
+}
+
+static int wl1251_fetch_firmware(struct wl1251 *wl)
+{
+	const struct firmware *fw;
+	struct device *dev = wiphy_dev(wl->hw->wiphy);
+	int ret;
+
+	ret = request_firmware(&fw, WL1251_FW_NAME, dev);
+
+	if (ret < 0) {
+		wl1251_error("could not get firmware: %d", ret);
+		return ret;
+	}
+
+	if (fw->size % 4) {
+		wl1251_error("firmware size is not multiple of 32 bits: %zu",
+			     fw->size);
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	wl->fw_len = fw->size;
+	wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
+
+	if (!wl->fw) {
+		wl1251_error("could not allocate memory for the firmware");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(wl->fw, fw->data, wl->fw_len);
+
+	ret = 0;
+
+out:
+	release_firmware(fw);
+
+	return ret;
+}
+
+static int wl1251_fetch_nvs(struct wl1251 *wl)
+{
+	const struct firmware *fw;
+	struct device *dev = wiphy_dev(wl->hw->wiphy);
+	int ret;
+
+	ret = request_firmware(&fw, WL1251_NVS_NAME, dev);
+
+	if (ret < 0) {
+		wl1251_error("could not get nvs file: %d", ret);
+		return ret;
+	}
+
+	if (fw->size % 4) {
+		wl1251_error("nvs size is not multiple of 32 bits: %zu",
+			     fw->size);
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	wl->nvs_len = fw->size;
+	wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
+
+	if (!wl->nvs) {
+		wl1251_error("could not allocate memory for the nvs file");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(wl->nvs, fw->data, wl->nvs_len);
+
+	ret = 0;
+
+out:
+	release_firmware(fw);
+
+	return ret;
+}
+
+static void wl1251_fw_wakeup(struct wl1251 *wl)
+{
+	u32 elp_reg;
+
+	elp_reg = ELPCTRL_WAKE_UP;
+	wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+	elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+	if (!(elp_reg & ELPCTRL_WLAN_READY))
+		wl1251_warning("WLAN not ready");
+}
+
+static int wl1251_chip_wakeup(struct wl1251 *wl)
+{
+	int ret = 0;
+
+	wl1251_power_on(wl);
+	msleep(WL1251_POWER_ON_SLEEP);
+	wl->if_ops->reset(wl);
+
+	/* We don't need a real memory partition here, because we only want
+	 * to use the registers at this point. */
+	wl1251_set_partition(wl,
+			     0x00000000,
+			     0x00000000,
+			     REGISTERS_BASE,
+			     REGISTERS_DOWN_SIZE);
+
+	/* ELP module wake up */
+	wl1251_fw_wakeup(wl);
+
+	/* whal_FwCtrl_BootSm() */
+
+	/* 0. read chip id from CHIP_ID */
+	wl->chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
+
+	/* 1. check if chip id is valid */
+
+	switch (wl->chip_id) {
+	case CHIP_ID_1251_PG12:
+		wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
+			     wl->chip_id);
+		break;
+	case CHIP_ID_1251_PG10:
+	case CHIP_ID_1251_PG11:
+	default:
+		wl1251_error("unsupported chip id: 0x%x", wl->chip_id);
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (wl->fw == NULL) {
+		ret = wl1251_fetch_firmware(wl);
+		if (ret < 0)
+			goto out;
+	}
+
+	/* No NVS from netlink, try to get it from the filesystem */
+	if (wl->nvs == NULL) {
+		ret = wl1251_fetch_nvs(wl);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void wl1251_irq_work(struct work_struct *work)
+{
+	u32 intr;
+	struct wl1251 *wl =
+		container_of(work, struct wl1251, irq_work);
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	wl1251_debug(DEBUG_IRQ, "IRQ work");
+
+	if (wl->state == WL1251_STATE_OFF)
+		goto out;
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
+
+	intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+	wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr);
+
+	if (wl->data_path) {
+		wl->rx_counter =
+			wl1251_mem_read32(wl, wl->data_path->rx_control_addr);
+
+		/* We handle a frmware bug here */
+		switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
+		case 0:
+			wl1251_debug(DEBUG_IRQ, "RX: FW and host in sync");
+			intr &= ~WL1251_ACX_INTR_RX0_DATA;
+			intr &= ~WL1251_ACX_INTR_RX1_DATA;
+			break;
+		case 1:
+			wl1251_debug(DEBUG_IRQ, "RX: FW +1");
+			intr |= WL1251_ACX_INTR_RX0_DATA;
+			intr &= ~WL1251_ACX_INTR_RX1_DATA;
+			break;
+		case 2:
+			wl1251_debug(DEBUG_IRQ, "RX: FW +2");
+			intr |= WL1251_ACX_INTR_RX0_DATA;
+			intr |= WL1251_ACX_INTR_RX1_DATA;
+			break;
+		default:
+			wl1251_warning("RX: FW and host out of sync: %d",
+				       wl->rx_counter - wl->rx_handled);
+			break;
+		}
+
+		wl->rx_handled = wl->rx_counter;
+
+
+		wl1251_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter);
+	}
+
+	intr &= wl->intr_mask;
+
+	if (intr == 0) {
+		wl1251_debug(DEBUG_IRQ, "INTR is 0");
+		wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+				   ~(wl->intr_mask));
+
+		goto out_sleep;
+	}
+
+	if (intr & WL1251_ACX_INTR_RX0_DATA) {
+		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
+		wl1251_rx(wl);
+	}
+
+	if (intr & WL1251_ACX_INTR_RX1_DATA) {
+		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
+		wl1251_rx(wl);
+	}
+
+	if (intr & WL1251_ACX_INTR_TX_RESULT) {
+		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
+		wl1251_tx_complete(wl);
+	}
+
+	if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
+		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
+		if (intr & WL1251_ACX_INTR_EVENT_A)
+			wl1251_event_handle(wl, 0);
+		else
+			wl1251_event_handle(wl, 1);
+	}
+
+	if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
+		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");
+
+	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+
+out_sleep:
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
+		       u16 beacon_interval, u8 dtim_period)
+{
+	int ret;
+
+	ret = wl1251_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
+				     DEFAULT_HW_GEN_MODULATION_TYPE,
+				     wl->tx_mgmt_frm_rate,
+				     wl->tx_mgmt_frm_mod);
+	if (ret < 0)
+		goto out;
+
+
+	ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval,
+			      dtim_period);
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify
+	 * locking we just sleep instead, for now
+	 */
+	msleep(10);
+
+out:
+	return ret;
+}
+
+static void wl1251_filter_work(struct work_struct *work)
+{
+	struct wl1251 *wl =
+		container_of(work, struct wl1251, filter_work);
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	if (wl->state == WL1251_STATE_OFF)
+		goto out;
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int,
+			  wl->dtim_period);
+	if (ret < 0)
+		goto out_sleep;
+
+out_sleep:
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+	struct wl1251 *wl = hw->priv;
+
+	skb_queue_tail(&wl->tx_queue, skb);
+
+	/*
+	 * The chip specific setup must run before the first TX packet -
+	 * before that, the tx_work will not be initialized!
+	 */
+
+	ieee80211_queue_work(wl->hw, &wl->tx_work);
+
+	/*
+	 * The workqueue is slow to process the tx_queue and we need stop
+	 * the queue here, otherwise the queue will get too long.
+	 */
+	if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
+		ieee80211_stop_queues(wl->hw);
+
+		/*
+		 * FIXME: this is racy, the variable is not properly
+		 * protected. Maybe fix this by removing the stupid
+		 * variable altogether and checking the real queue state?
+		 */
+		wl->tx_queue_stopped = true;
+	}
+
+	return NETDEV_TX_OK;
+}
+
+static int wl1251_op_start(struct ieee80211_hw *hw)
+{
+	struct wl1251 *wl = hw->priv;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 start");
+
+	mutex_lock(&wl->mutex);
+
+	if (wl->state != WL1251_STATE_OFF) {
+		wl1251_error("cannot start because not in off state: %d",
+			     wl->state);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = wl1251_chip_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1251_boot(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1251_hw_init(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1251_acx_station_id(wl);
+	if (ret < 0)
+		goto out;
+
+	wl->state = WL1251_STATE_ON;
+
+	wl1251_info("firmware booted (%s)", wl->fw_ver);
+
+out:
+	if (ret < 0)
+		wl1251_power_off(wl);
+
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+static void wl1251_op_stop(struct ieee80211_hw *hw)
+{
+	struct wl1251 *wl = hw->priv;
+
+	wl1251_info("down");
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
+
+	mutex_lock(&wl->mutex);
+
+	WARN_ON(wl->state != WL1251_STATE_ON);
+
+	if (wl->scanning) {
+		mutex_unlock(&wl->mutex);
+		ieee80211_scan_completed(wl->hw, true);
+		mutex_lock(&wl->mutex);
+		wl->scanning = false;
+	}
+
+	wl->state = WL1251_STATE_OFF;
+
+	wl1251_disable_interrupts(wl);
+
+	mutex_unlock(&wl->mutex);
+
+	cancel_work_sync(&wl->irq_work);
+	cancel_work_sync(&wl->tx_work);
+	cancel_work_sync(&wl->filter_work);
+
+	mutex_lock(&wl->mutex);
+
+	/* let's notify MAC80211 about the remaining pending TX frames */
+	wl1251_tx_flush(wl);
+	wl1251_power_off(wl);
+
+	memset(wl->bssid, 0, ETH_ALEN);
+	wl->listen_int = 1;
+	wl->bss_type = MAX_BSS_TYPE;
+
+	wl->data_in_count = 0;
+	wl->rx_counter = 0;
+	wl->rx_handled = 0;
+	wl->rx_current_buffer = 0;
+	wl->rx_last_id = 0;
+	wl->next_tx_complete = 0;
+	wl->elp = false;
+	wl->psm = 0;
+	wl->tx_queue_stopped = false;
+	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
+	wl->channel = WL1251_DEFAULT_CHANNEL;
+
+	wl1251_debugfs_reset(wl);
+
+	mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_op_add_interface(struct ieee80211_hw *hw,
+				   struct ieee80211_if_init_conf *conf)
+{
+	struct wl1251 *wl = hw->priv;
+	int ret = 0;
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
+		     conf->type, conf->mac_addr);
+
+	mutex_lock(&wl->mutex);
+
+	switch (conf->type) {
+	case NL80211_IFTYPE_STATION:
+		wl->bss_type = BSS_TYPE_STA_BSS;
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		wl->bss_type = BSS_TYPE_IBSS;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
+		memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+		SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+		ret = wl1251_acx_station_id(wl);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	mutex_unlock(&wl->mutex);
+	return ret;
+}
+
+static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
+					 struct ieee80211_if_init_conf *conf)
+{
+	wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
+}
+
+static int wl1251_build_null_data(struct wl1251 *wl)
+{
+	struct wl12xx_null_data_template template;
+
+	if (!is_zero_ether_addr(wl->bssid)) {
+		memcpy(template.header.da, wl->bssid, ETH_ALEN);
+		memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
+	} else {
+		memset(template.header.da, 0xff, ETH_ALEN);
+		memset(template.header.bssid, 0xff, ETH_ALEN);
+	}
+
+	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+	template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+						IEEE80211_STYPE_NULLFUNC);
+
+	return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
+				       sizeof(template));
+
+}
+
+static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid)
+{
+	struct wl12xx_ps_poll_template template;
+
+	memcpy(template.bssid, wl->bssid, ETH_ALEN);
+	memcpy(template.ta, wl->mac_addr, ETH_ALEN);
+	template.aid = aid;
+	template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+
+	return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template,
+				       sizeof(template));
+
+}
+
+static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+	struct wl1251 *wl = hw->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+	int channel, ret = 0;
+
+	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+		     channel,
+		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
+		     conf->power_level);
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	if (channel != wl->channel) {
+		wl->channel = channel;
+
+		ret = wl1251_join(wl, wl->bss_type, wl->channel,
+				  wl->beacon_int, wl->dtim_period);
+		if (ret < 0)
+			goto out_sleep;
+	}
+
+	ret = wl1251_build_null_data(wl);
+	if (ret < 0)
+		goto out_sleep;
+
+	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
+		wl1251_debug(DEBUG_PSM, "psm enabled");
+
+		wl->psm_requested = true;
+
+		/*
+		 * We enter PSM only if we're already associated.
+		 * If we're not, we'll enter it when joining an SSID,
+		 * through the bss_info_changed() hook.
+		 */
+		ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
+		   wl->psm_requested) {
+		wl1251_debug(DEBUG_PSM, "psm disabled");
+
+		wl->psm_requested = false;
+
+		if (wl->psm)
+			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+	}
+
+	if (conf->power_level != wl->power_level) {
+		ret = wl1251_acx_tx_power(wl, conf->power_level);
+		if (ret < 0)
+			goto out;
+
+		wl->power_level = conf->power_level;
+	}
+
+out_sleep:
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
+				  FIF_ALLMULTI | \
+				  FIF_FCSFAIL | \
+				  FIF_BCN_PRBRESP_PROMISC | \
+				  FIF_CONTROL | \
+				  FIF_OTHER_BSS)
+
+static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
+				       unsigned int changed,
+				       unsigned int *total,u64 multicast)
+{
+	struct wl1251 *wl = hw->priv;
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter");
+
+	*total &= WL1251_SUPPORTED_FILTERS;
+	changed &= WL1251_SUPPORTED_FILTERS;
+
+	if (changed == 0)
+		/* no filters which we support changed */
+		return;
+
+	/* FIXME: wl->rx_config and wl->rx_filter are not protected */
+
+	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
+	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
+
+	if (*total & FIF_PROMISC_IN_BSS) {
+		wl->rx_config |= CFG_BSSID_FILTER_EN;
+		wl->rx_config |= CFG_RX_ALL_GOOD;
+	}
+	if (*total & FIF_ALLMULTI)
+		/*
+		 * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
+		 * all multicast frames
+		 */
+		wl->rx_config &= ~CFG_MC_FILTER_EN;
+	if (*total & FIF_FCSFAIL)
+		wl->rx_filter |= CFG_RX_FCS_ERROR;
+	if (*total & FIF_BCN_PRBRESP_PROMISC) {
+		wl->rx_config &= ~CFG_BSSID_FILTER_EN;
+		wl->rx_config &= ~CFG_SSID_FILTER_EN;
+	}
+	if (*total & FIF_CONTROL)
+		wl->rx_filter |= CFG_RX_CTL_EN;
+	if (*total & FIF_OTHER_BSS)
+		wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
+
+	/*
+	 * FIXME: workqueues need to be properly cancelled on stop(), for
+	 * now let's just disable changing the filter settings. They will
+	 * be updated any on config().
+	 */
+	/* schedule_work(&wl->filter_work); */
+}
+
+/* HW encryption */
+static int wl1251_set_key_type(struct wl1251 *wl,
+			       struct wl1251_cmd_set_keys *key,
+			       enum set_key_cmd cmd,
+			       struct ieee80211_key_conf *mac80211_key,
+			       const u8 *addr)
+{
+	switch (mac80211_key->alg) {
+	case ALG_WEP:
+		if (is_broadcast_ether_addr(addr))
+			key->key_type = KEY_WEP_DEFAULT;
+		else
+			key->key_type = KEY_WEP_ADDR;
+
+		mac80211_key->hw_key_idx = mac80211_key->keyidx;
+		break;
+	case ALG_TKIP:
+		if (is_broadcast_ether_addr(addr))
+			key->key_type = KEY_TKIP_MIC_GROUP;
+		else
+			key->key_type = KEY_TKIP_MIC_PAIRWISE;
+
+		mac80211_key->hw_key_idx = mac80211_key->keyidx;
+		break;
+	case ALG_CCMP:
+		if (is_broadcast_ether_addr(addr))
+			key->key_type = KEY_AES_GROUP;
+		else
+			key->key_type = KEY_AES_PAIRWISE;
+		mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+		break;
+	default:
+		wl1251_error("Unknown key algo 0x%x", mac80211_key->alg);
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_sta *sta,
+			     struct ieee80211_key_conf *key)
+{
+	struct wl1251 *wl = hw->priv;
+	struct wl1251_cmd_set_keys *wl_cmd;
+	const u8 *addr;
+	int ret;
+
+	static const u8 bcast_addr[ETH_ALEN] =
+		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 set key");
+
+	wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
+	if (!wl_cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	addr = sta ? sta->addr : bcast_addr;
+
+	wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
+	wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
+	wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
+		     key->alg, key->keyidx, key->keylen, key->flags);
+	wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
+
+	if (is_zero_ether_addr(addr)) {
+		/* We dont support TX only encryption */
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out_unlock;
+
+	switch (cmd) {
+	case SET_KEY:
+		wl_cmd->key_action = KEY_ADD_OR_REPLACE;
+		break;
+	case DISABLE_KEY:
+		wl_cmd->key_action = KEY_REMOVE;
+		break;
+	default:
+		wl1251_error("Unsupported key cmd 0x%x", cmd);
+		break;
+	}
+
+	ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
+	if (ret < 0) {
+		wl1251_error("Set KEY type failed");
+		goto out_sleep;
+	}
+
+	if (wl_cmd->key_type != KEY_WEP_DEFAULT)
+		memcpy(wl_cmd->addr, addr, ETH_ALEN);
+
+	if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
+	    (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
+		/*
+		 * We get the key in the following form:
+		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+		 * but the target is expecting:
+		 * TKIP - RX MIC - TX MIC
+		 */
+		memcpy(wl_cmd->key, key->key, 16);
+		memcpy(wl_cmd->key + 16, key->key + 24, 8);
+		memcpy(wl_cmd->key + 24, key->key + 16, 8);
+
+	} else {
+		memcpy(wl_cmd->key, key->key, key->keylen);
+	}
+	wl_cmd->key_size = key->keylen;
+
+	wl_cmd->id = key->keyidx;
+	wl_cmd->ssid_profile = 0;
+
+	wl1251_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd));
+
+	ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
+	if (ret < 0) {
+		wl1251_warning("could not set keys");
+		goto out_sleep;
+	}
+
+out_sleep:
+	wl1251_ps_elp_sleep(wl);
+
+out_unlock:
+	mutex_unlock(&wl->mutex);
+
+out:
+	kfree(wl_cmd);
+
+	return ret;
+}
+
+static int wl1251_build_basic_rates(char *rates)
+{
+	u8 index = 0;
+
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+
+	return index;
+}
+
+static int wl1251_build_extended_rates(char *rates)
+{
+	u8 index = 0;
+
+	rates[index++] = IEEE80211_OFDM_RATE_6MB;
+	rates[index++] = IEEE80211_OFDM_RATE_9MB;
+	rates[index++] = IEEE80211_OFDM_RATE_12MB;
+	rates[index++] = IEEE80211_OFDM_RATE_18MB;
+	rates[index++] = IEEE80211_OFDM_RATE_24MB;
+	rates[index++] = IEEE80211_OFDM_RATE_36MB;
+	rates[index++] = IEEE80211_OFDM_RATE_48MB;
+	rates[index++] = IEEE80211_OFDM_RATE_54MB;
+
+	return index;
+}
+
+
+static int wl1251_build_probe_req(struct wl1251 *wl, u8 *ssid, size_t ssid_len)
+{
+	struct wl12xx_probe_req_template template;
+	struct wl12xx_ie_rates *rates;
+	char *ptr;
+	u16 size;
+
+	ptr = (char *)&template;
+	size = sizeof(struct ieee80211_header);
+
+	memset(template.header.da, 0xff, ETH_ALEN);
+	memset(template.header.bssid, 0xff, ETH_ALEN);
+	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+	template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+
+	/* IEs */
+	/* SSID */
+	template.ssid.header.id = WLAN_EID_SSID;
+	template.ssid.header.len = ssid_len;
+	if (ssid_len && ssid)
+		memcpy(template.ssid.ssid, ssid, ssid_len);
+	size += sizeof(struct wl12xx_ie_header) + ssid_len;
+	ptr += size;
+
+	/* Basic Rates */
+	rates = (struct wl12xx_ie_rates *)ptr;
+	rates->header.id = WLAN_EID_SUPP_RATES;
+	rates->header.len = wl1251_build_basic_rates(rates->rates);
+	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+	ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+	/* Extended rates */
+	rates = (struct wl12xx_ie_rates *)ptr;
+	rates->header.id = WLAN_EID_EXT_SUPP_RATES;
+	rates->header.len = wl1251_build_extended_rates(rates->rates);
+	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+	wl1251_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
+
+	return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
+				      size);
+}
+
+static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len,
+			  u8 active_scan, u8 high_prio, u8 num_channels,
+			  u8 probe_requests)
+{
+	struct wl1251_cmd_trigger_scan_to *trigger = NULL;
+	struct cmd_scan *params = NULL;
+	int i, ret;
+	u16 scan_options = 0;
+
+	if (wl->scanning)
+		return -EINVAL;
+
+	params = kzalloc(sizeof(*params), GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
+	params->params.rx_filter_options =
+		cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
+
+	/* High priority scan */
+	if (!active_scan)
+		scan_options |= SCAN_PASSIVE;
+	if (high_prio)
+		scan_options |= SCAN_PRIORITY_HIGH;
+	params->params.scan_options = scan_options;
+
+	params->params.num_channels = num_channels;
+	params->params.num_probe_requests = probe_requests;
+	params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
+	params->params.tid_trigger = 0;
+
+	for (i = 0; i < num_channels; i++) {
+		params->channels[i].min_duration = cpu_to_le32(30000);
+		params->channels[i].max_duration = cpu_to_le32(60000);
+		memset(&params->channels[i].bssid_lsb, 0xff, 4);
+		memset(&params->channels[i].bssid_msb, 0xff, 2);
+		params->channels[i].early_termination = 0;
+		params->channels[i].tx_power_att = 0;
+		params->channels[i].channel = i + 1;
+		memset(params->channels[i].pad, 0, 3);
+	}
+
+	for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
+		memset(&params->channels[i], 0,
+		       sizeof(struct basic_scan_channel_parameters));
+
+	if (len && ssid) {
+		params->params.ssid_len = len;
+		memcpy(params->params.ssid, ssid, len);
+	} else {
+		params->params.ssid_len = 0;
+		memset(params->params.ssid, 0, 32);
+	}
+
+	ret = wl1251_build_probe_req(wl, ssid, len);
+	if (ret < 0) {
+		wl1251_error("PROBE request template failed");
+		goto out;
+	}
+
+	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
+	if (!trigger)
+		goto out;
+
+	trigger->timeout = 0;
+
+	ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
+			      sizeof(*trigger));
+	if (ret < 0) {
+		wl1251_error("trigger scan to failed for hw scan");
+		goto out;
+	}
+
+	wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
+
+	wl->scanning = true;
+
+	ret = wl1251_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+	if (ret < 0)
+		wl1251_error("SCAN failed");
+
+	wl1251_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
+
+	if (params->header.status != CMD_STATUS_SUCCESS) {
+		wl1251_error("TEST command answer error: %d",
+			     params->header.status);
+		wl->scanning = false;
+		ret = -EIO;
+		goto out;
+	}
+
+out:
+	kfree(params);
+	return ret;
+
+}
+
+static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
+			     struct cfg80211_scan_request *req)
+{
+	struct wl1251 *wl = hw->priv;
+	int ret;
+	u8 *ssid = NULL;
+	size_t ssid_len = 0;
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
+
+	if (req->n_ssids) {
+		ssid = req->ssids[0].ssid;
+		ssid_len = req->ssids[0].ssid_len;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1251_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
+
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	struct wl1251 *wl = hw->priv;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1251_acx_rts_threshold(wl, (u16) value);
+	if (ret < 0)
+		wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret);
+
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_bss_conf *bss_conf,
+				       u32 changed)
+{
+	enum wl1251_cmd_ps_mode mode;
+	struct wl1251 *wl = hw->priv;
+	struct sk_buff *beacon;
+	int ret;
+
+	wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1251_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	if (changed & BSS_CHANGED_ASSOC) {
+		if (bss_conf->assoc) {
+			wl->beacon_int = bss_conf->beacon_int;
+			wl->dtim_period = bss_conf->dtim_period;
+
+			/* FIXME: call join */
+
+			wl->aid = bss_conf->aid;
+
+			ret = wl1251_build_ps_poll(wl, wl->aid);
+			if (ret < 0)
+				goto out_sleep;
+
+			ret = wl1251_acx_aid(wl, wl->aid);
+			if (ret < 0)
+				goto out_sleep;
+
+			/* If we want to go in PSM but we're not there yet */
+			if (wl->psm_requested && !wl->psm) {
+				mode = STATION_POWER_SAVE_MODE;
+				ret = wl1251_ps_set_mode(wl, mode);
+				if (ret < 0)
+					goto out_sleep;
+			}
+		} else {
+			/* use defaults when not associated */
+			wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
+			wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
+		}
+	}
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		if (bss_conf->use_short_slot)
+			ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT);
+		else
+			ret = wl1251_acx_slot(wl, SLOT_TIME_LONG);
+		if (ret < 0) {
+			wl1251_warning("Set slot time failed %d", ret);
+			goto out_sleep;
+		}
+	}
+
+	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+		if (bss_conf->use_short_preamble)
+			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
+		else
+			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
+	}
+
+	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+		if (bss_conf->use_cts_prot)
+			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE);
+		else
+			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
+		if (ret < 0) {
+			wl1251_warning("Set ctsprotect failed %d", ret);
+			goto out;
+		}
+	}
+
+	if (changed & BSS_CHANGED_BSSID) {
+		memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+
+		ret = wl1251_build_null_data(wl);
+		if (ret < 0)
+			goto out;
+
+		if (wl->bss_type != BSS_TYPE_IBSS) {
+			ret = wl1251_join(wl, wl->bss_type, wl->channel,
+					  wl->beacon_int, wl->dtim_period);
+			if (ret < 0)
+				goto out_sleep;
+			wl1251_warning("Set ctsprotect failed %d", ret);
+			goto out_sleep;
+		}
+	}
+
+	if (changed & BSS_CHANGED_BEACON) {
+		beacon = ieee80211_beacon_get(hw, vif);
+		ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
+					      beacon->len);
+
+		if (ret < 0) {
+			dev_kfree_skb(beacon);
+			goto out;
+		}
+
+		ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
+					      beacon->len);
+
+		dev_kfree_skb(beacon);
+
+		if (ret < 0)
+			goto out;
+
+		ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
+				  wl->channel, wl->dtim_period);
+
+		if (ret < 0)
+			goto out;
+	}
+
+out_sleep:
+	wl1251_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate wl1251_rates[] = {
+	{ .bitrate = 10,
+	  .hw_value = 0x1,
+	  .hw_value_short = 0x1, },
+	{ .bitrate = 20,
+	  .hw_value = 0x2,
+	  .hw_value_short = 0x2,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55,
+	  .hw_value = 0x4,
+	  .hw_value_short = 0x4,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110,
+	  .hw_value = 0x20,
+	  .hw_value_short = 0x20,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 60,
+	  .hw_value = 0x8,
+	  .hw_value_short = 0x8, },
+	{ .bitrate = 90,
+	  .hw_value = 0x10,
+	  .hw_value_short = 0x10, },
+	{ .bitrate = 120,
+	  .hw_value = 0x40,
+	  .hw_value_short = 0x40, },
+	{ .bitrate = 180,
+	  .hw_value = 0x80,
+	  .hw_value_short = 0x80, },
+	{ .bitrate = 240,
+	  .hw_value = 0x200,
+	  .hw_value_short = 0x200, },
+	{ .bitrate = 360,
+	 .hw_value = 0x400,
+	 .hw_value_short = 0x400, },
+	{ .bitrate = 480,
+	  .hw_value = 0x800,
+	  .hw_value_short = 0x800, },
+	{ .bitrate = 540,
+	  .hw_value = 0x1000,
+	  .hw_value_short = 0x1000, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel wl1251_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 wl1251_band_2ghz = {
+	.channels = wl1251_channels,
+	.n_channels = ARRAY_SIZE(wl1251_channels),
+	.bitrates = wl1251_rates,
+	.n_bitrates = ARRAY_SIZE(wl1251_rates),
+};
+
+static const struct ieee80211_ops wl1251_ops = {
+	.start = wl1251_op_start,
+	.stop = wl1251_op_stop,
+	.add_interface = wl1251_op_add_interface,
+	.remove_interface = wl1251_op_remove_interface,
+	.config = wl1251_op_config,
+	.configure_filter = wl1251_op_configure_filter,
+	.tx = wl1251_op_tx,
+	.set_key = wl1251_op_set_key,
+	.hw_scan = wl1251_op_hw_scan,
+	.bss_info_changed = wl1251_op_bss_info_changed,
+	.set_rts_threshold = wl1251_op_set_rts_threshold,
+};
+
+static int wl1251_register_hw(struct wl1251 *wl)
+{
+	int ret;
+
+	if (wl->mac80211_registered)
+		return 0;
+
+	SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+	ret = ieee80211_register_hw(wl->hw);
+	if (ret < 0) {
+		wl1251_error("unable to register mac80211 hw: %d", ret);
+		return ret;
+	}
+
+	wl->mac80211_registered = true;
+
+	wl1251_notice("loaded");
+
+	return 0;
+}
+
+int wl1251_init_ieee80211(struct wl1251 *wl)
+{
+	int ret;
+
+	/* The tx descriptor buffer and the TKIP space */
+	wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
+		+ WL1251_TKIP_IV_SPACE;
+
+	/* unit us */
+	/* FIXME: find a proper value */
+	wl->hw->channel_change_time = 10000;
+
+	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
+		IEEE80211_HW_NOISE_DBM;
+
+	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	wl->hw->wiphy->max_scan_ssids = 1;
+	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
+
+	ret = wl1251_register_hw(wl);
+	if (ret)
+		goto out;
+
+	wl1251_debugfs_init(wl);
+	wl1251_notice("initialized");
+
+	ret = 0;
+
+out:
+	return ret;
+}
+EXPORT_SYMBOL_GPL(wl1251_init_ieee80211);
+
+struct ieee80211_hw *wl1251_alloc_hw(void)
+{
+	struct ieee80211_hw *hw;
+	struct wl1251 *wl;
+	int i;
+	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
+
+	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
+	if (!hw) {
+		wl1251_error("could not alloc ieee80211_hw");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	wl = hw->priv;
+	memset(wl, 0, sizeof(*wl));
+
+	wl->hw = hw;
+
+	wl->data_in_count = 0;
+
+	skb_queue_head_init(&wl->tx_queue);
+
+	INIT_WORK(&wl->filter_work, wl1251_filter_work);
+	wl->channel = WL1251_DEFAULT_CHANNEL;
+	wl->scanning = false;
+	wl->default_key = 0;
+	wl->listen_int = 1;
+	wl->rx_counter = 0;
+	wl->rx_handled = 0;
+	wl->rx_current_buffer = 0;
+	wl->rx_last_id = 0;
+	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
+	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
+	wl->elp = false;
+	wl->psm = 0;
+	wl->psm_requested = false;
+	wl->tx_queue_stopped = false;
+	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
+	wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
+	wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
+
+	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+		wl->tx_frames[i] = NULL;
+
+	wl->next_tx_complete = 0;
+
+	INIT_WORK(&wl->irq_work, wl1251_irq_work);
+	INIT_WORK(&wl->tx_work, wl1251_tx_work);
+
+	/*
+	 * In case our MAC address is not correctly set,
+	 * we use a random but Nokia MAC.
+	 */
+	memcpy(wl->mac_addr, nokia_oui, 3);
+	get_random_bytes(wl->mac_addr + 3, 3);
+
+	wl->state = WL1251_STATE_OFF;
+	mutex_init(&wl->mutex);
+
+	wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
+	wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
+
+	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
+	if (!wl->rx_descriptor) {
+		wl1251_error("could not allocate memory for rx descriptor");
+		ieee80211_free_hw(hw);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	return hw;
+}
+EXPORT_SYMBOL_GPL(wl1251_alloc_hw);
+
+int wl1251_free_hw(struct wl1251 *wl)
+{
+	ieee80211_unregister_hw(wl->hw);
+
+	wl1251_debugfs_exit(wl);
+
+	kfree(wl->target_mem_map);
+	kfree(wl->data_path);
+	kfree(wl->fw);
+	wl->fw = NULL;
+	kfree(wl->nvs);
+	wl->nvs = NULL;
+
+	kfree(wl->rx_descriptor);
+	wl->rx_descriptor = NULL;
+
+	ieee80211_free_hw(wl->hw);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(wl1251_free_hw);
+
+MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_netlink.h b/drivers/net/wireless/wl12xx/wl1251_netlink.h
new file mode 100644
index 0000000..ee36695
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_netlink.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_NETLINK_H__
+#define __WL1251_NETLINK_H__
+
+int wl1251_nl_register(void);
+void wl1251_nl_unregister(void);
+
+#endif /* __WL1251_NETLINK_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c
new file mode 100644
index 0000000..c53e287
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.c
@@ -0,0 +1,161 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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 "wl1251_reg.h"
+#include "wl1251_ps.h"
+#include "wl1251_cmd.h"
+#include "wl1251_io.h"
+
+#define WL1251_WAKEUP_TIMEOUT 2000
+
+/* Routines to toggle sleep mode while in ELP */
+void wl1251_ps_elp_sleep(struct wl1251 *wl)
+{
+	if (wl->elp || !wl->psm)
+		return;
+
+	wl1251_debug(DEBUG_PSM, "chip to elp");
+
+	wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+
+	wl->elp = true;
+}
+
+int wl1251_ps_elp_wakeup(struct wl1251 *wl)
+{
+	unsigned long timeout;
+	u32 elp_reg;
+
+	if (!wl->elp)
+		return 0;
+
+	wl1251_debug(DEBUG_PSM, "waking up chip from elp");
+
+	timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT);
+
+	wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+
+	elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+	/*
+	 * FIXME: we should wait for irq from chip but, as a temporary
+	 * solution to simplify locking, let's poll instead
+	 */
+	while (!(elp_reg & ELPCTRL_WLAN_READY)) {
+		if (time_after(jiffies, timeout)) {
+			wl1251_error("elp wakeup timeout");
+			return -ETIMEDOUT;
+		}
+		msleep(1);
+		elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+	}
+
+	wl1251_debug(DEBUG_PSM, "wakeup time: %u ms",
+		     jiffies_to_msecs(jiffies) -
+		     (jiffies_to_msecs(timeout) - WL1251_WAKEUP_TIMEOUT));
+
+	wl->elp = false;
+
+	return 0;
+}
+
+static int wl1251_ps_set_elp(struct wl1251 *wl, bool enable)
+{
+	int ret;
+
+	if (enable) {
+		wl1251_debug(DEBUG_PSM, "sleep auth psm/elp");
+
+		ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
+		if (ret < 0)
+			return ret;
+
+		wl1251_ps_elp_sleep(wl);
+	} else {
+		wl1251_debug(DEBUG_PSM, "sleep auth cam");
+
+		/*
+		 * When the target is in ELP, we can only
+		 * access the ELP control register. Thus,
+		 * we have to wake the target up before
+		 * changing the power authorization.
+		 */
+
+		wl1251_ps_elp_wakeup(wl);
+
+		ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_CAM);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
+{
+	int ret;
+
+	switch (mode) {
+	case STATION_POWER_SAVE_MODE:
+		wl1251_debug(DEBUG_PSM, "entering psm");
+
+		ret = wl1251_acx_wake_up_conditions(wl,
+						    WAKE_UP_EVENT_DTIM_BITMAP,
+						    wl->listen_int);
+		if (ret < 0)
+			return ret;
+
+		ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+		if (ret < 0)
+			return ret;
+
+		ret = wl1251_ps_set_elp(wl, true);
+		if (ret < 0)
+			return ret;
+
+		wl->psm = 1;
+		break;
+	case STATION_ACTIVE_MODE:
+	default:
+		wl1251_debug(DEBUG_PSM, "leaving psm");
+		ret = wl1251_ps_set_elp(wl, false);
+		if (ret < 0)
+			return ret;
+
+		ret = wl1251_acx_wake_up_conditions(wl,
+						    WAKE_UP_EVENT_DTIM_BITMAP,
+						    wl->listen_int);
+		if (ret < 0)
+			return ret;
+
+		ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+		if (ret < 0)
+			return ret;
+
+		wl->psm = 0;
+		break;
+	}
+
+	return ret;
+}
+
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl12xx/wl1251_ps.h
new file mode 100644
index 0000000..db036fe
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_ps.h
@@ -0,0 +1,36 @@
+#ifndef __WL1251_PS_H__
+#define __WL1251_PS_H__
+
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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 "wl1251.h"
+#include "wl1251_acx.h"
+
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
+void wl1251_ps_elp_sleep(struct wl1251 *wl);
+int wl1251_ps_elp_wakeup(struct wl1251 *wl);
+
+
+#endif /* __WL1251_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h
new file mode 100644
index 0000000..06e1bd9
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_reg.h
@@ -0,0 +1,644 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __REG_H__
+#define __REG_H__
+
+#include <linux/bitops.h>
+
+#define REGISTERS_BASE 0x00300000
+#define DRPW_BASE      0x00310000
+
+#define REGISTERS_DOWN_SIZE 0x00008800
+#define REGISTERS_WORK_SIZE 0x0000b000
+
+#define HW_ACCESS_ELP_CTRL_REG_ADDR         0x1FFFC
+
+/* ELP register commands */
+#define ELPCTRL_WAKE_UP             0x1
+#define ELPCTRL_WAKE_UP_WLAN_READY  0x5
+#define ELPCTRL_SLEEP               0x0
+/* ELP WLAN_READY bit */
+#define ELPCTRL_WLAN_READY          0x2
+
+/* Device Configuration registers*/
+#define SOR_CFG                        (REGISTERS_BASE + 0x0800)
+#define ECPU_CTRL                      (REGISTERS_BASE + 0x0804)
+#define HI_CFG                         (REGISTERS_BASE + 0x0808)
+#define EE_START                       (REGISTERS_BASE + 0x080C)
+
+#define CHIP_ID_B                      (REGISTERS_BASE + 0x5674)
+
+#define CHIP_ID_1251_PG10	           (0x7010101)
+#define CHIP_ID_1251_PG11	           (0x7020101)
+#define CHIP_ID_1251_PG12	           (0x7030101)
+
+#define ENABLE                         (REGISTERS_BASE + 0x5450)
+
+/* Power Management registers */
+#define ELP_CFG_MODE                   (REGISTERS_BASE + 0x5804)
+#define ELP_CMD                        (REGISTERS_BASE + 0x5808)
+#define PLL_CAL_TIME                   (REGISTERS_BASE + 0x5810)
+#define CLK_REQ_TIME                   (REGISTERS_BASE + 0x5814)
+#define CLK_BUF_TIME                   (REGISTERS_BASE + 0x5818)
+
+#define CFG_PLL_SYNC_CNT               (REGISTERS_BASE + 0x5820)
+
+/* Scratch Pad registers*/
+#define SCR_PAD0                       (REGISTERS_BASE + 0x5608)
+#define SCR_PAD1                       (REGISTERS_BASE + 0x560C)
+#define SCR_PAD2                       (REGISTERS_BASE + 0x5610)
+#define SCR_PAD3                       (REGISTERS_BASE + 0x5614)
+#define SCR_PAD4                       (REGISTERS_BASE + 0x5618)
+#define SCR_PAD4_SET                   (REGISTERS_BASE + 0x561C)
+#define SCR_PAD4_CLR                   (REGISTERS_BASE + 0x5620)
+#define SCR_PAD5                       (REGISTERS_BASE + 0x5624)
+#define SCR_PAD5_SET                   (REGISTERS_BASE + 0x5628)
+#define SCR_PAD5_CLR                   (REGISTERS_BASE + 0x562C)
+#define SCR_PAD6                       (REGISTERS_BASE + 0x5630)
+#define SCR_PAD7                       (REGISTERS_BASE + 0x5634)
+#define SCR_PAD8                       (REGISTERS_BASE + 0x5638)
+#define SCR_PAD9                       (REGISTERS_BASE + 0x563C)
+
+/* Spare registers*/
+#define SPARE_A1                       (REGISTERS_BASE + 0x0994)
+#define SPARE_A2                       (REGISTERS_BASE + 0x0998)
+#define SPARE_A3                       (REGISTERS_BASE + 0x099C)
+#define SPARE_A4                       (REGISTERS_BASE + 0x09A0)
+#define SPARE_A5                       (REGISTERS_BASE + 0x09A4)
+#define SPARE_A6                       (REGISTERS_BASE + 0x09A8)
+#define SPARE_A7                       (REGISTERS_BASE + 0x09AC)
+#define SPARE_A8                       (REGISTERS_BASE + 0x09B0)
+#define SPARE_B1                       (REGISTERS_BASE + 0x5420)
+#define SPARE_B2                       (REGISTERS_BASE + 0x5424)
+#define SPARE_B3                       (REGISTERS_BASE + 0x5428)
+#define SPARE_B4                       (REGISTERS_BASE + 0x542C)
+#define SPARE_B5                       (REGISTERS_BASE + 0x5430)
+#define SPARE_B6                       (REGISTERS_BASE + 0x5434)
+#define SPARE_B7                       (REGISTERS_BASE + 0x5438)
+#define SPARE_B8                       (REGISTERS_BASE + 0x543C)
+
+enum wl12xx_acx_int_reg {
+	ACX_REG_INTERRUPT_TRIG,
+	ACX_REG_INTERRUPT_TRIG_H,
+
+/*=============================================
+  Host Interrupt Mask Register - 32bit (RW)
+  ------------------------------------------
+  Setting a bit in this register masks the
+  corresponding interrupt to the host.
+  0 - RX0		- Rx first dubble buffer Data Interrupt
+  1 - TXD		- Tx Data Interrupt
+  2 - TXXFR		- Tx Transfer Interrupt
+  3 - RX1		- Rx second dubble buffer Data Interrupt
+  4 - RXXFR		- Rx Transfer Interrupt
+  5 - EVENT_A	- Event Mailbox interrupt
+  6 - EVENT_B	- Event Mailbox interrupt
+  7 - WNONHST	- Wake On Host Interrupt
+  8 - TRACE_A	- Debug Trace interrupt
+  9 - TRACE_B	- Debug Trace interrupt
+ 10 - CDCMP		- Command Complete Interrupt
+ 11 -
+ 12 -
+ 13 -
+ 14 - ICOMP		- Initialization Complete Interrupt
+ 16 - SG SE		- Soft Gemini - Sense enable interrupt
+ 17 - SG SD		- Soft Gemini - Sense disable interrupt
+ 18 -			-
+ 19 -			-
+ 20 -			-
+ 21-			-
+ Default: 0x0001
+*==============================================*/
+	ACX_REG_INTERRUPT_MASK,
+
+/*=============================================
+  Host Interrupt Mask Set 16bit, (Write only)
+  ------------------------------------------
+ Setting a bit in this register sets
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+==============================================*/
+	ACX_REG_HINT_MASK_SET,
+
+/*=============================================
+  Host Interrupt Mask Clear 16bit,(Write only)
+  ------------------------------------------
+ Setting a bit in this register clears
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+=============================================*/
+	ACX_REG_HINT_MASK_CLR,
+
+/*=============================================
+  Host Interrupt Status Nondestructive Read
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register doesn't
+ effect its content.
+=============================================*/
+	ACX_REG_INTERRUPT_NO_CLEAR,
+
+/*=============================================
+  Host Interrupt Status Clear on Read  Register
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register clears it,
+ thus making all interrupts inactive.
+==============================================*/
+	ACX_REG_INTERRUPT_CLEAR,
+
+/*=============================================
+  Host Interrupt Acknowledge Register
+  16bit,(Write only)
+  ------------------------------------------
+ The host can set individual bits in this
+ register to clear (acknowledge) the corresp.
+ interrupt status bits in the HINT_STS_CLR and
+ HINT_STS_ND registers, thus making the
+ assotiated interrupt inactive. (0-no effect)
+==============================================*/
+	ACX_REG_INTERRUPT_ACK,
+
+/*===============================================
+   Host Software Reset - 32bit RW
+ ------------------------------------------
+    [31:1] Reserved
+    0  SOFT_RESET Soft Reset  - When this bit is set,
+    it holds the Wlan hardware in a soft reset state.
+    This reset disables all MAC and baseband processor
+    clocks except the CardBus/PCI interface clock.
+    It also initializes all MAC state machines except
+    the host interface. It does not reload the
+    contents of the EEPROM. When this bit is cleared
+    (not self-clearing), the Wlan hardware
+    exits the software reset state.
+===============================================*/
+	ACX_REG_SLV_SOFT_RESET,
+
+/*===============================================
+ EEPROM Burst Read Start  - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0  ACX_EE_START -  EEPROM Burst Read Start 0
+ Setting this bit starts a burst read from
+ the external EEPROM.
+ If this bit is set (after reset) before an EEPROM read/write,
+ the burst read starts at EEPROM address 0.
+ Otherwise, it starts at the address
+ following the address of the previous access.
+ TheWlan hardware hardware clears this bit automatically.
+
+ Default: 0x00000000
+*================================================*/
+	ACX_REG_EE_START,
+
+/* Embedded ARM CPU Control */
+
+/*===============================================
+ Halt eCPU   - 32bit RW
+ ------------------------------------------
+ 0 HALT_ECPU Halt Embedded CPU - This bit is the
+ compliment of bit 1 (MDATA2) in the SOR_CFG register.
+ During a hardware reset, this bit holds
+ the inverse of MDATA2.
+ When downloading firmware from the host,
+ set this bit (pull down MDATA2).
+ The host clears this bit after downloading the firmware into
+ zero-wait-state SSRAM.
+ When loading firmware from Flash, clear this bit (pull up MDATA2)
+ so that the eCPU can run the bootloader code in Flash
+ HALT_ECPU eCPU State
+ --------------------
+ 1 halt eCPU
+ 0 enable eCPU
+ ===============================================*/
+	ACX_REG_ECPU_CONTROL,
+
+	ACX_REG_TABLE_LEN
+};
+
+#define ACX_SLV_SOFT_RESET_BIT   BIT(0)
+#define ACX_REG_EEPROM_START_BIT BIT(0)
+
+/* Command/Information Mailbox Pointers */
+
+/*===============================================
+  Command Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the command mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to
+ find the location of the command mailbox.
+ The Wlan hardware initializes the command mailbox
+ pointer with the default address of the command mailbox.
+ The command mailbox pointer is not valid until after
+ the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_COMMAND_MAILBOX_PTR				(SCR_PAD0)
+
+/*===============================================
+  Information Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the information mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to find
+ the location of the information mailbox.
+ The Wlan hardware initializes the information mailbox pointer
+ with the default address of the information mailbox.
+ The information mailbox pointer is not valid
+ until after the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_EVENT_MAILBOX_PTR				(SCR_PAD1)
+
+
+/* Misc */
+
+#define REG_ENABLE_TX_RX				(ENABLE)
+/*
+ * Rx configuration (filter) information element
+ * ---------------------------------------------
+ */
+#define REG_RX_CONFIG				(RX_CFG)
+#define REG_RX_FILTER				(RX_FILTER_CFG)
+
+
+#define RX_CFG_ENABLE_PHY_HEADER_PLCP	 0x0002
+
+/* promiscuous - receives all valid frames */
+#define RX_CFG_PROMISCUOUS		 0x0008
+
+/* receives frames from any BSSID */
+#define RX_CFG_BSSID			 0x0020
+
+/* receives frames destined to any MAC address */
+#define RX_CFG_MAC			 0x0010
+
+#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC	 0x0010
+#define RX_CFG_ENABLE_ANY_DEST_MAC	 0x0000
+#define RX_CFG_ENABLE_ONLY_MY_BSSID	 0x0020
+#define RX_CFG_ENABLE_ANY_BSSID		 0x0000
+
+/* discards all broadcast frames */
+#define RX_CFG_DISABLE_BCAST		 0x0200
+
+#define RX_CFG_ENABLE_ONLY_MY_SSID	 0x0400
+#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
+#define RX_CFG_COPY_RX_STATUS		 0x2000
+#define RX_CFG_TSF			 0x10000
+
+#define RX_CONFIG_OPTION_ANY_DST_MY_BSS	 (RX_CFG_ENABLE_ANY_DEST_MAC | \
+					  RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_ANY_BSS	 (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+					  | RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+					  RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_MY_BSS	 (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+					  | RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_FOR_SCAN  (RX_CFG_ENABLE_PHY_HEADER_PLCP \
+				    | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
+				    | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
+
+#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_JOIN	 (RX_CFG_ENABLE_ONLY_MY_BSSID | \
+					  RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_IBSS_JOIN   (RX_CFG_ENABLE_ONLY_MY_SSID | \
+					  RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_FILTER_OPTION_DEF	      (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+				       | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
+				       | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
+
+#define RX_FILTER_OPTION_FILTER_ALL	 0
+
+#define RX_FILTER_OPTION_DEF_PRSP_BCN  (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
+					| CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
+
+#define RX_FILTER_OPTION_JOIN	     (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+				      | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
+				      | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
+				      | CFG_RX_PRSP_EN)
+
+
+/*===============================================
+ EEPROM Read/Write Request 32bit RW
+ ------------------------------------------
+ 1 EE_READ - EEPROM Read Request 1 - Setting this bit
+ loads a single byte of data into the EE_DATA
+ register from the EEPROM location specified in
+ the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+ EE_DATA is valid when this bit is cleared.
+
+ 0 EE_WRITE  - EEPROM Write Request  - Setting this bit
+ writes a single byte of data from the EE_DATA register into the
+ EEPROM location specified in the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+*===============================================*/
+#define ACX_EE_CTL_REG                      EE_CTL
+#define EE_WRITE                            0x00000001ul
+#define EE_READ                             0x00000002ul
+
+/*===============================================
+  EEPROM Address  - 32bit RW
+  ------------------------------------------
+  This register specifies the address
+  within the EEPROM from/to which to read/write data.
+  ===============================================*/
+#define ACX_EE_ADDR_REG                     EE_ADDR
+
+/*===============================================
+  EEPROM Data  - 32bit RW
+  ------------------------------------------
+  This register either holds the read 8 bits of
+  data from the EEPROM or the write data
+  to be written to the EEPROM.
+  ===============================================*/
+#define ACX_EE_DATA_REG                     EE_DATA
+
+/*===============================================
+  EEPROM Base Address  - 32bit RW
+  ------------------------------------------
+  This register holds the upper nine bits
+  [23:15] of the 24-bit Wlan hardware memory
+  address for burst reads from EEPROM accesses.
+  The EEPROM provides the lower 15 bits of this address.
+  The MSB of the address from the EEPROM is ignored.
+  ===============================================*/
+#define ACX_EE_CFG                          EE_CFG
+
+/*===============================================
+  GPIO Output Values  -32bit, RW
+  ------------------------------------------
+  [31:16]  Reserved
+  [15: 0]  Specify the output values (at the output driver inputs) for
+  GPIO[15:0], respectively.
+  ===============================================*/
+#define ACX_GPIO_OUT_REG            GPIO_OUT
+#define ACX_MAX_GPIO_LINES          15
+
+/*===============================================
+  Contention window  -32bit, RW
+  ------------------------------------------
+  [31:26]  Reserved
+  [25:16]  Max (0x3ff)
+  [15:07]  Reserved
+  [06:00]  Current contention window value - default is 0x1F
+  ===============================================*/
+#define ACX_CONT_WIND_CFG_REG    CONT_WIND_CFG
+#define ACX_CONT_WIND_MIN_MASK   0x0000007f
+#define ACX_CONT_WIND_MAX        0x03ff0000
+
+/*===============================================
+  HI_CFG Interface Configuration Register Values
+  ------------------------------------------
+  ===============================================*/
+#define HI_CFG_UART_ENABLE          0x00000004
+#define HI_CFG_RST232_ENABLE        0x00000008
+#define HI_CFG_CLOCK_REQ_SELECT     0x00000010
+#define HI_CFG_HOST_INT_ENABLE      0x00000020
+#define HI_CFG_VLYNQ_OUTPUT_ENABLE  0x00000040
+#define HI_CFG_HOST_INT_ACTIVE_LOW  0x00000080
+#define HI_CFG_UART_TX_OUT_GPIO_15  0x00000100
+#define HI_CFG_UART_TX_OUT_GPIO_14  0x00000200
+#define HI_CFG_UART_TX_OUT_GPIO_7   0x00000400
+
+/*
+ * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
+ *       for platforms using active high interrupt level
+ */
+#ifdef USE_ACTIVE_HIGH
+#define HI_CFG_DEF_VAL              \
+	(HI_CFG_UART_ENABLE |        \
+	HI_CFG_RST232_ENABLE |      \
+	HI_CFG_CLOCK_REQ_SELECT |   \
+	HI_CFG_HOST_INT_ENABLE)
+#else
+#define HI_CFG_DEF_VAL              \
+	(HI_CFG_UART_ENABLE |        \
+	HI_CFG_RST232_ENABLE |      \
+	HI_CFG_CLOCK_REQ_SELECT |   \
+	HI_CFG_HOST_INT_ENABLE)
+
+#endif
+
+#define REF_FREQ_19_2                       0
+#define REF_FREQ_26_0                       1
+#define REF_FREQ_38_4                       2
+#define REF_FREQ_40_0                       3
+#define REF_FREQ_33_6                       4
+#define REF_FREQ_NUM                        5
+
+#define LUT_PARAM_INTEGER_DIVIDER           0
+#define LUT_PARAM_FRACTIONAL_DIVIDER        1
+#define LUT_PARAM_ATTN_BB                   2
+#define LUT_PARAM_ALPHA_BB                  3
+#define LUT_PARAM_STOP_TIME_BB              4
+#define LUT_PARAM_BB_PLL_LOOP_FILTER        5
+#define LUT_PARAM_NUM                       6
+
+#define ACX_EEPROMLESS_IND_REG              (SCR_PAD4)
+#define USE_EEPROM                          0
+#define SOFT_RESET_MAX_TIME                 1000000
+#define SOFT_RESET_STALL_TIME               1000
+#define NVS_DATA_BUNDARY_ALIGNMENT          4
+
+
+/* Firmware image load chunk size */
+#define CHUNK_SIZE          512
+
+/* Firmware image header size */
+#define FW_HDR_SIZE 8
+
+#define ECPU_CONTROL_HALT					0x00000101
+
+
+/******************************************************************************
+
+    CHANNELS, BAND & REG DOMAINS definitions
+
+******************************************************************************/
+
+
+enum {
+	RADIO_BAND_2_4GHZ = 0,  /* 2.4 Ghz band */
+	RADIO_BAND_5GHZ = 1,    /* 5 Ghz band */
+	RADIO_BAND_JAPAN_4_9_GHZ = 2,
+	DEFAULT_BAND = RADIO_BAND_2_4GHZ,
+	INVALID_BAND = 0xFE,
+	MAX_RADIO_BANDS = 0xFF
+};
+
+enum {
+	NO_RATE      = 0,
+	RATE_1MBPS   = 0x0A,
+	RATE_2MBPS   = 0x14,
+	RATE_5_5MBPS = 0x37,
+	RATE_6MBPS   = 0x0B,
+	RATE_9MBPS   = 0x0F,
+	RATE_11MBPS  = 0x6E,
+	RATE_12MBPS  = 0x0A,
+	RATE_18MBPS  = 0x0E,
+	RATE_22MBPS  = 0xDC,
+	RATE_24MBPS  = 0x09,
+	RATE_36MBPS  = 0x0D,
+	RATE_48MBPS  = 0x08,
+	RATE_54MBPS  = 0x0C
+};
+
+enum {
+	RATE_INDEX_1MBPS   =  0,
+	RATE_INDEX_2MBPS   =  1,
+	RATE_INDEX_5_5MBPS =  2,
+	RATE_INDEX_6MBPS   =  3,
+	RATE_INDEX_9MBPS   =  4,
+	RATE_INDEX_11MBPS  =  5,
+	RATE_INDEX_12MBPS  =  6,
+	RATE_INDEX_18MBPS  =  7,
+	RATE_INDEX_22MBPS  =  8,
+	RATE_INDEX_24MBPS  =  9,
+	RATE_INDEX_36MBPS  =  10,
+	RATE_INDEX_48MBPS  =  11,
+	RATE_INDEX_54MBPS  =  12,
+	RATE_INDEX_MAX     =  RATE_INDEX_54MBPS,
+	MAX_RATE_INDEX,
+	INVALID_RATE_INDEX = MAX_RATE_INDEX,
+	RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
+};
+
+enum {
+	RATE_MASK_1MBPS = 0x1,
+	RATE_MASK_2MBPS = 0x2,
+	RATE_MASK_5_5MBPS = 0x4,
+	RATE_MASK_11MBPS = 0x20,
+};
+
+#define SHORT_PREAMBLE_BIT   BIT(0) /* CCK or Barker depending on the rate */
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+enum {
+	CCK_LONG = 0,
+	CCK_SHORT = SHORT_PREAMBLE_BIT,
+	PBCC_LONG = PBCC_RATE_BIT,
+	PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
+	OFDM = OFDM_RATE_BIT
+};
+
+/******************************************************************************
+
+Transmit-Descriptor RATE-SET field definitions...
+
+Define a new "Rate-Set" for TX path that incorporates the
+Rate & Modulation info into a single 16-bit field.
+
+TxdRateSet_t:
+b15   - Indicates Preamble type (1=SHORT, 0=LONG).
+	Notes:
+	Must be LONG (0) for 1Mbps rate.
+	Does not apply (set to 0) for RevG-OFDM rates.
+b14   - Indicates PBCC encoding (1=PBCC, 0=not).
+	Notes:
+	Does not apply (set to 0) for rates 1 and 2 Mbps.
+	Does not apply (set to 0) for RevG-OFDM rates.
+b13    - Unused (set to 0).
+b12-b0 - Supported Rate indicator bits as defined below.
+
+******************************************************************************/
+
+
+/*************************************************************************
+
+    Interrupt Trigger Register (Host -> WiLink)
+
+**************************************************************************/
+
+/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
+
+/*
+ * Host Command Interrupt. Setting this bit masks
+ * the interrupt that the host issues to inform
+ * the FW that it has sent a command
+ * to the Wlan hardware Command Mailbox.
+ */
+#define INTR_TRIG_CMD       BIT(0)
+
+/*
+ * Host Event Acknowlegde Interrupt. The host
+ * sets this bit to acknowledge that it received
+ * the unsolicited information from the event
+ * mailbox.
+ */
+#define INTR_TRIG_EVENT_ACK BIT(1)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * FW that a TX packet is in the XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_TX_PROC0 BIT(2)
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_RX_PROC0 BIT(3)
+
+#define INTR_TRIG_DEBUG_ACK BIT(4)
+
+#define INTR_TRIG_STATE_CHANGED BIT(5)
+
+
+/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_RX_PROC1 BIT(17)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * hardware that a TX packet is in the XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_TX_PROC1 BIT(18)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl12xx/wl1251_rx.c
new file mode 100644
index 0000000..17c54b5
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.c
@@ -0,0 +1,197 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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/skbuff.h>
+#include <net/mac80211.h>
+
+#include "wl1251.h"
+#include "wl1251_reg.h"
+#include "wl1251_io.h"
+#include "wl1251_rx.h"
+#include "wl1251_cmd.h"
+#include "wl1251_acx.h"
+
+static void wl1251_rx_header(struct wl1251 *wl,
+			     struct wl1251_rx_descriptor *desc)
+{
+	u32 rx_packet_ring_addr;
+
+	rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
+	if (wl->rx_current_buffer)
+		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+	wl1251_mem_read(wl, rx_packet_ring_addr, desc, sizeof(*desc));
+}
+
+static void wl1251_rx_status(struct wl1251 *wl,
+			     struct wl1251_rx_descriptor *desc,
+			     struct ieee80211_rx_status *status,
+			     u8 beacon)
+{
+	u64 mactime;
+	int ret;
+
+	memset(status, 0, sizeof(struct ieee80211_rx_status));
+
+	status->band = IEEE80211_BAND_2GHZ;
+	status->mactime = desc->timestamp;
+
+	/*
+	 * The rx status timestamp is a 32 bits value while the TSF is a
+	 * 64 bits one.
+	 * For IBSS merging, TSF is mandatory, so we have to get it
+	 * somehow, so we ask for ACX_TSF_INFO.
+	 * That could be moved to the get_tsf() hook, but unfortunately,
+	 * this one must be atomic, while our SPI routines can sleep.
+	 */
+	if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
+		ret = wl1251_acx_tsf_info(wl, &mactime);
+		if (ret == 0)
+			status->mactime = mactime;
+	}
+
+	status->signal = desc->rssi;
+	status->qual = (desc->rssi - WL1251_RX_MIN_RSSI) * 100 /
+		(WL1251_RX_MAX_RSSI - WL1251_RX_MIN_RSSI);
+	status->qual = min(status->qual, 100);
+	status->qual = max(status->qual, 0);
+
+	/*
+	 * FIXME: guessing that snr needs to be divided by two, otherwise
+	 * the values don't make any sense
+	 */
+	status->noise = desc->rssi - desc->snr / 2;
+
+	status->freq = ieee80211_channel_to_frequency(desc->channel);
+
+	status->flag |= RX_FLAG_TSFT;
+
+	if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
+		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+
+		if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
+			status->flag |= RX_FLAG_DECRYPTED;
+
+		if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
+			status->flag |= RX_FLAG_MMIC_ERROR;
+	}
+
+	if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
+		status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+
+	/* FIXME: set status->rate_idx */
+}
+
+static void wl1251_rx_body(struct wl1251 *wl,
+			   struct wl1251_rx_descriptor *desc)
+{
+	struct sk_buff *skb;
+	struct ieee80211_rx_status status;
+	u8 *rx_buffer, beacon = 0;
+	u16 length, *fc;
+	u32 curr_id, last_id_inc, rx_packet_ring_addr;
+
+	length = WL1251_RX_ALIGN(desc->length  - PLCP_HEADER_LENGTH);
+	curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
+	last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
+
+	if (last_id_inc != curr_id) {
+		wl1251_warning("curr ID:%d, last ID inc:%d",
+			       curr_id, last_id_inc);
+		wl->rx_last_id = curr_id;
+	} else {
+		wl->rx_last_id = last_id_inc;
+	}
+
+	rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
+		sizeof(struct wl1251_rx_descriptor) + 20;
+	if (wl->rx_current_buffer)
+		rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+	skb = dev_alloc_skb(length);
+	if (!skb) {
+		wl1251_error("Couldn't allocate RX frame");
+		return;
+	}
+
+	rx_buffer = skb_put(skb, length);
+	wl1251_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
+
+	/* The actual lenght doesn't include the target's alignment */
+	skb->len = desc->length  - PLCP_HEADER_LENGTH;
+
+	fc = (u16 *)skb->data;
+
+	if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
+		beacon = 1;
+
+	wl1251_rx_status(wl, desc, &status, beacon);
+
+	wl1251_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+		     beacon ? "beacon" : "");
+
+	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+	ieee80211_rx(wl->hw, skb);
+}
+
+static void wl1251_rx_ack(struct wl1251 *wl)
+{
+	u32 data, addr;
+
+	if (wl->rx_current_buffer) {
+		addr = ACX_REG_INTERRUPT_TRIG_H;
+		data = INTR_TRIG_RX_PROC1;
+	} else {
+		addr = ACX_REG_INTERRUPT_TRIG;
+		data = INTR_TRIG_RX_PROC0;
+	}
+
+	wl1251_reg_write32(wl, addr, data);
+
+	/* Toggle buffer ring */
+	wl->rx_current_buffer = !wl->rx_current_buffer;
+}
+
+
+void wl1251_rx(struct wl1251 *wl)
+{
+	struct wl1251_rx_descriptor *rx_desc;
+
+	if (wl->state != WL1251_STATE_ON)
+		return;
+
+	rx_desc = wl->rx_descriptor;
+
+	/* We first read the frame's header */
+	wl1251_rx_header(wl, rx_desc);
+
+	/* Now we can read the body */
+	wl1251_rx_body(wl, rx_desc);
+
+	/* Finally, we need to ACK the RX */
+	wl1251_rx_ack(wl);
+
+	return;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h
new file mode 100644
index 0000000..563a3fd
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.h
@@ -0,0 +1,124 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_RX_H__
+#define __WL1251_RX_H__
+
+#include <linux/bitops.h>
+
+#include "wl1251.h"
+
+/*
+ * RX PATH
+ *
+ * The Rx path uses a double buffer and an rx_contro structure, each located
+ * at a fixed address in the device memory. The host keeps track of which
+ * buffer is available and alternates between them on a per packet basis.
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet.
+ * The RX path goes like that:
+ * 1) The target generates an interrupt each time a new packet is received.
+ *   There are 2 RX interrupts, one for each buffer.
+ * 2) The host reads the received packet from one of the double buffers.
+ * 3) The host triggers a target interrupt.
+ * 4) The target prepares the next RX packet.
+ */
+
+#define WL1251_RX_MAX_RSSI -30
+#define WL1251_RX_MIN_RSSI -95
+
+#define WL1251_RX_ALIGN_TO 4
+#define WL1251_RX_ALIGN(len) (((len) + WL1251_RX_ALIGN_TO - 1) & \
+			     ~(WL1251_RX_ALIGN_TO - 1))
+
+#define SHORT_PREAMBLE_BIT   BIT(0)
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+#define PLCP_HEADER_LENGTH 8
+#define RX_DESC_PACKETID_SHIFT 11
+#define RX_MAX_PACKET_ID 3
+
+#define RX_DESC_VALID_FCS         0x0001
+#define RX_DESC_MATCH_RXADDR1     0x0002
+#define RX_DESC_MCAST             0x0004
+#define RX_DESC_STAINTIM          0x0008
+#define RX_DESC_VIRTUAL_BM        0x0010
+#define RX_DESC_BCAST             0x0020
+#define RX_DESC_MATCH_SSID        0x0040
+#define RX_DESC_MATCH_BSSID       0x0080
+#define RX_DESC_ENCRYPTION_MASK   0x0300
+#define RX_DESC_MEASURMENT        0x0400
+#define RX_DESC_SEQNUM_MASK       0x1800
+#define	RX_DESC_MIC_FAIL	  0x2000
+#define	RX_DESC_DECRYPT_FAIL	  0x4000
+
+struct wl1251_rx_descriptor {
+	u32 timestamp; /* In microseconds */
+	u16 length; /* Paylod length, including headers */
+	u16 flags;
+
+	/*
+	 * 0 - 802.11
+	 * 1 - 802.3
+	 * 2 - IP
+	 * 3 - Raw Codec
+	 */
+	u8 type;
+
+	/*
+	 * Received Rate:
+	 * 0x0A - 1MBPS
+	 * 0x14 - 2MBPS
+	 * 0x37 - 5_5MBPS
+	 * 0x0B - 6MBPS
+	 * 0x0F - 9MBPS
+	 * 0x6E - 11MBPS
+	 * 0x0A - 12MBPS
+	 * 0x0E - 18MBPS
+	 * 0xDC - 22MBPS
+	 * 0x09 - 24MBPS
+	 * 0x0D - 36MBPS
+	 * 0x08 - 48MBPS
+	 * 0x0C - 54MBPS
+	 */
+	u8 rate;
+
+	u8 mod_pre; /* Modulation and preamble */
+	u8 channel;
+
+	/*
+	 * 0 - 2.4 Ghz
+	 * 1 - 5 Ghz
+	 */
+	u8 band;
+
+	s8 rssi; /* in dB */
+	u8 rcpi; /* in dB */
+	u8 snr; /* in dB */
+} __attribute__ ((packed));
+
+void wl1251_rx(struct wl1251 *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl12xx/wl1251_sdio.c
new file mode 100644
index 0000000..9423f22
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_sdio.c
@@ -0,0 +1,205 @@
+/*
+ * wl12xx SDIO routines
+ *
+ * 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
+ *
+ * Copyright (C) 2005 Texas Instruments Incorporated
+ * Copyright (C) 2008 Google Inc
+ * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
+ */
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/mod_devicetable.h>
+#include <linux/irq.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/platform_device.h>
+
+#include "wl1251.h"
+#include "wl12xx_80211.h"
+#include "wl1251_reg.h"
+#include "wl1251_ps.h"
+#include "wl1251_io.h"
+#include "wl1251_tx.h"
+#include "wl1251_debugfs.h"
+
+#ifndef SDIO_VENDOR_ID_TI
+#define SDIO_VENDOR_ID_TI		0x104c
+#endif
+
+#ifndef SDIO_DEVICE_ID_TI_WL1251
+#define SDIO_DEVICE_ID_TI_WL1251	0x9066
+#endif
+
+static struct sdio_func *wl_to_func(struct wl1251 *wl)
+{
+	return wl->if_priv;
+}
+
+static void wl1251_sdio_interrupt(struct sdio_func *func)
+{
+	struct wl1251 *wl = sdio_get_drvdata(func);
+
+	wl1251_debug(DEBUG_IRQ, "IRQ");
+
+	/* FIXME should be synchronous for sdio */
+	ieee80211_queue_work(wl->hw, &wl->irq_work);
+}
+
+static const struct sdio_device_id wl1251_devices[] = {
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1251) },
+	{}
+};
+MODULE_DEVICE_TABLE(sdio, wl1251_devices);
+
+
+void wl1251_sdio_read(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int ret;
+	struct sdio_func *func = wl_to_func(wl);
+
+	sdio_claim_host(func);
+	ret = sdio_memcpy_fromio(func, buf, addr, len);
+	if (ret)
+		wl1251_error("sdio read failed (%d)", ret);
+	sdio_release_host(func);
+}
+
+void wl1251_sdio_write(struct wl1251 *wl, int addr, void *buf, size_t len)
+{
+	int ret;
+	struct sdio_func *func = wl_to_func(wl);
+
+	sdio_claim_host(func);
+	ret = sdio_memcpy_toio(func, addr, buf, len);
+	if (ret)
+		wl1251_error("sdio write failed (%d)", ret);
+	sdio_release_host(func);
+}
+
+void wl1251_sdio_reset(struct wl1251 *wl)
+{
+}
+
+static void wl1251_sdio_enable_irq(struct wl1251 *wl)
+{
+	struct sdio_func *func = wl_to_func(wl);
+
+	sdio_claim_host(func);
+	sdio_claim_irq(func, wl1251_sdio_interrupt);
+	sdio_release_host(func);
+}
+
+static void wl1251_sdio_disable_irq(struct wl1251 *wl)
+{
+	struct sdio_func *func = wl_to_func(wl);
+
+	sdio_claim_host(func);
+	sdio_release_irq(func);
+	sdio_release_host(func);
+}
+
+void wl1251_sdio_set_power(bool enable)
+{
+}
+
+struct wl1251_if_operations wl1251_sdio_ops = {
+	.read = wl1251_sdio_read,
+	.write = wl1251_sdio_write,
+	.reset = wl1251_sdio_reset,
+	.enable_irq = wl1251_sdio_enable_irq,
+	.disable_irq = wl1251_sdio_disable_irq,
+};
+
+int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
+{
+	int ret;
+	struct wl1251 *wl;
+	struct ieee80211_hw *hw;
+
+	hw = wl1251_alloc_hw();
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	wl = hw->priv;
+
+	sdio_claim_host(func);
+	ret = sdio_enable_func(func);
+	if (ret)
+		goto release;
+
+	sdio_set_block_size(func, 512);
+
+	SET_IEEE80211_DEV(hw, &func->dev);
+	wl->if_priv = func;
+	wl->if_ops = &wl1251_sdio_ops;
+	wl->set_power = wl1251_sdio_set_power;
+
+	sdio_release_host(func);
+	ret = wl1251_init_ieee80211(wl);
+	if (ret)
+		goto disable;
+
+	sdio_set_drvdata(func, wl);
+	return ret;
+
+disable:
+	sdio_claim_host(func);
+	sdio_disable_func(func);
+release:
+	sdio_release_host(func);
+	return ret;
+}
+
+static void __devexit wl1251_sdio_remove(struct sdio_func *func)
+{
+	struct wl1251 *wl = sdio_get_drvdata(func);
+
+	wl1251_free_hw(wl);
+
+	sdio_claim_host(func);
+	sdio_release_irq(func);
+	sdio_disable_func(func);
+	sdio_release_host(func);
+}
+
+static struct sdio_driver wl1251_sdio_driver = {
+	.name		= "wl1251_sdio",
+	.id_table	= wl1251_devices,
+	.probe		= wl1251_sdio_probe,
+	.remove		= __devexit_p(wl1251_sdio_remove),
+};
+
+static int __init wl1251_sdio_init(void)
+{
+	int err;
+
+	err = sdio_register_driver(&wl1251_sdio_driver);
+	if (err)
+		wl1251_error("failed to register sdio driver: %d", err);
+	return err;
+}
+
+static void __exit wl1251_sdio_exit(void)
+{
+	sdio_unregister_driver(&wl1251_sdio_driver);
+	wl1251_notice("unloaded");
+}
+
+module_init(wl1251_sdio_init);
+module_exit(wl1251_sdio_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl12xx/wl1251_spi.c
new file mode 100644
index 0000000..14eff2b
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.c
@@ -0,0 +1,344 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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/irq.h>
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/wl12xx.h>
+
+#include "wl1251.h"
+#include "wl1251_reg.h"
+#include "wl1251_spi.h"
+
+static irqreturn_t wl1251_irq(int irq, void *cookie)
+{
+	struct wl1251 *wl;
+
+	wl1251_debug(DEBUG_IRQ, "IRQ");
+
+	wl = cookie;
+
+	ieee80211_queue_work(wl->hw, &wl->irq_work);
+
+	return IRQ_HANDLED;
+}
+
+static struct spi_device *wl_to_spi(struct wl1251 *wl)
+{
+	return wl->if_priv;
+}
+
+static void wl1251_spi_reset(struct wl1251 *wl)
+{
+	u8 *cmd;
+	struct spi_transfer t;
+	struct spi_message m;
+
+	cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+	if (!cmd) {
+		wl1251_error("could not allocate cmd for spi reset");
+		return;
+	}
+
+	memset(&t, 0, sizeof(t));
+	spi_message_init(&m);
+
+	memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
+
+	t.tx_buf = cmd;
+	t.len = WSPI_INIT_CMD_LEN;
+	spi_message_add_tail(&t, &m);
+
+	spi_sync(wl_to_spi(wl), &m);
+
+	wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+static void wl1251_spi_wake(struct wl1251 *wl)
+{
+	u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
+	struct spi_transfer t;
+	struct spi_message m;
+
+	cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+	if (!cmd) {
+		wl1251_error("could not allocate cmd for spi init");
+		return;
+	}
+
+	memset(crc, 0, sizeof(crc));
+	memset(&t, 0, sizeof(t));
+	spi_message_init(&m);
+
+	/*
+	 * Set WSPI_INIT_COMMAND
+	 * the data is being send from the MSB to LSB
+	 */
+	cmd[2] = 0xff;
+	cmd[3] = 0xff;
+	cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
+	cmd[0] = 0;
+	cmd[7] = 0;
+	cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
+	cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
+
+	if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
+		cmd[5] |=  WSPI_INIT_CMD_DIS_FIXEDBUSY;
+	else
+		cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
+
+	cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
+		| WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
+
+	crc[0] = cmd[1];
+	crc[1] = cmd[0];
+	crc[2] = cmd[7];
+	crc[3] = cmd[6];
+	crc[4] = cmd[5];
+
+	cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
+	cmd[4] |= WSPI_INIT_CMD_END;
+
+	t.tx_buf = cmd;
+	t.len = WSPI_INIT_CMD_LEN;
+	spi_message_add_tail(&t, &m);
+
+	spi_sync(wl_to_spi(wl), &m);
+
+	wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+static void wl1251_spi_reset_wake(struct wl1251 *wl)
+{
+	wl1251_spi_reset(wl);
+	wl1251_spi_wake(wl);
+}
+
+static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf,
+			    size_t len)
+{
+	struct spi_transfer t[3];
+	struct spi_message m;
+	u8 *busy_buf;
+	u32 *cmd;
+
+	cmd = &wl->buffer_cmd;
+	busy_buf = wl->buffer_busyword;
+
+	*cmd = 0;
+	*cmd |= WSPI_CMD_READ;
+	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = cmd;
+	t[0].len = 4;
+	spi_message_add_tail(&t[0], &m);
+
+	/* Busy and non busy words read */
+	t[1].rx_buf = busy_buf;
+	t[1].len = WL1251_BUSY_WORD_LEN;
+	spi_message_add_tail(&t[1], &m);
+
+	t[2].rx_buf = buf;
+	t[2].len = len;
+	spi_message_add_tail(&t[2], &m);
+
+	spi_sync(wl_to_spi(wl), &m);
+
+	/* FIXME: check busy words */
+
+	wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
+	wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+}
+
+static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf,
+			     size_t len)
+{
+	struct spi_transfer t[2];
+	struct spi_message m;
+	u32 *cmd;
+
+	cmd = &wl->buffer_cmd;
+
+	*cmd = 0;
+	*cmd |= WSPI_CMD_WRITE;
+	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = cmd;
+	t[0].len = sizeof(*cmd);
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].tx_buf = buf;
+	t[1].len = len;
+	spi_message_add_tail(&t[1], &m);
+
+	spi_sync(wl_to_spi(wl), &m);
+
+	wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
+	wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+}
+
+static void wl1251_spi_enable_irq(struct wl1251 *wl)
+{
+	return enable_irq(wl->irq);
+}
+
+static void wl1251_spi_disable_irq(struct wl1251 *wl)
+{
+	return disable_irq(wl->irq);
+}
+
+static const struct wl1251_if_operations wl1251_spi_ops = {
+	.read = wl1251_spi_read,
+	.write = wl1251_spi_write,
+	.reset = wl1251_spi_reset_wake,
+	.enable_irq = wl1251_spi_enable_irq,
+	.disable_irq = wl1251_spi_disable_irq,
+};
+
+static int __devinit wl1251_spi_probe(struct spi_device *spi)
+{
+	struct wl12xx_platform_data *pdata;
+	struct ieee80211_hw *hw;
+	struct wl1251 *wl;
+	int ret;
+
+	pdata = spi->dev.platform_data;
+	if (!pdata) {
+		wl1251_error("no platform data");
+		return -ENODEV;
+	}
+
+	hw = wl1251_alloc_hw();
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	wl = hw->priv;
+
+	SET_IEEE80211_DEV(hw, &spi->dev);
+	dev_set_drvdata(&spi->dev, wl);
+	wl->if_priv = spi;
+	wl->if_ops = &wl1251_spi_ops;
+
+	/* This is the only SPI value that we need to set here, the rest
+	 * comes from the board-peripherals file */
+	spi->bits_per_word = 32;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		wl1251_error("spi_setup failed");
+		goto out_free;
+	}
+
+	wl->set_power = pdata->set_power;
+	if (!wl->set_power) {
+		wl1251_error("set power function missing in platform data");
+		return -ENODEV;
+	}
+
+	wl->irq = spi->irq;
+	if (wl->irq < 0) {
+		wl1251_error("irq missing in platform data");
+		return -ENODEV;
+	}
+
+	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
+	if (ret < 0) {
+		wl1251_error("request_irq() failed: %d", ret);
+		goto out_free;
+	}
+
+	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+	disable_irq(wl->irq);
+
+	ret = wl1251_init_ieee80211(wl);
+	if (ret)
+		goto out_irq;
+
+	return 0;
+
+ out_irq:
+	free_irq(wl->irq, wl);
+
+ out_free:
+	ieee80211_free_hw(hw);
+
+	return ret;
+}
+
+static int __devexit wl1251_spi_remove(struct spi_device *spi)
+{
+	struct wl1251 *wl = dev_get_drvdata(&spi->dev);
+
+	free_irq(wl->irq, wl);
+	wl1251_free_hw(wl);
+
+	return 0;
+}
+
+static struct spi_driver wl1251_spi_driver = {
+	.driver = {
+		.name		= "wl12xx",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= wl1251_spi_probe,
+	.remove		= __devexit_p(wl1251_spi_remove),
+};
+
+static int __init wl1251_spi_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&wl1251_spi_driver);
+	if (ret < 0) {
+		wl1251_error("failed to register spi driver: %d", ret);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit wl1251_spi_exit(void)
+{
+	spi_unregister_driver(&wl1251_spi_driver);
+
+	wl1251_notice("unloaded");
+}
+
+module_init(wl1251_spi_init);
+module_exit(wl1251_spi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl12xx/wl1251_spi.h
new file mode 100644
index 0000000..2e273a9
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_spi.h
@@ -0,0 +1,61 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_SPI_H__
+#define __WL1251_SPI_H__
+
+#include "wl1251_cmd.h"
+#include "wl1251_acx.h"
+#include "wl1251_reg.h"
+
+#define WSPI_CMD_READ                 0x40000000
+#define WSPI_CMD_WRITE                0x00000000
+#define WSPI_CMD_FIXED                0x20000000
+#define WSPI_CMD_BYTE_LENGTH          0x1FFE0000
+#define WSPI_CMD_BYTE_LENGTH_OFFSET   17
+#define WSPI_CMD_BYTE_ADDR            0x0001FFFF
+
+#define WSPI_INIT_CMD_CRC_LEN       5
+
+#define WSPI_INIT_CMD_START         0x00
+#define WSPI_INIT_CMD_TX            0x40
+/* the extra bypass bit is sampled by the TNET as '1' */
+#define WSPI_INIT_CMD_BYPASS_BIT    0x80
+#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
+#define WSPI_INIT_CMD_EN_FIXEDBUSY  0x80
+#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
+#define WSPI_INIT_CMD_IOD           0x40
+#define WSPI_INIT_CMD_IP            0x20
+#define WSPI_INIT_CMD_CS            0x10
+#define WSPI_INIT_CMD_WS            0x08
+#define WSPI_INIT_CMD_WSPI          0x01
+#define WSPI_INIT_CMD_END           0x01
+
+#define WSPI_INIT_CMD_LEN           8
+
+#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
+		((WL1251_BUSY_WORD_LEN - 4) / sizeof(u32))
+#define HW_ACCESS_WSPI_INIT_CMD_MASK  0
+
+#endif /* __WL1251_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
new file mode 100644
index 0000000..f859706
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -0,0 +1,559 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+
+#include "wl1251.h"
+#include "wl1251_reg.h"
+#include "wl1251_tx.h"
+#include "wl1251_ps.h"
+#include "wl1251_io.h"
+
+static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count)
+{
+	int used, data_in_count;
+
+	data_in_count = wl->data_in_count;
+
+	if (data_in_count < data_out_count)
+		/* data_in_count has wrapped */
+		data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
+
+	used = data_in_count - data_out_count;
+
+	WARN_ON(used < 0);
+	WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
+
+	if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
+		return true;
+	else
+		return false;
+}
+
+static int wl1251_tx_path_status(struct wl1251 *wl)
+{
+	u32 status, addr, data_out_count;
+	bool busy;
+
+	addr = wl->data_path->tx_control_addr;
+	status = wl1251_mem_read32(wl, addr);
+	data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
+	busy = wl1251_tx_double_buffer_busy(wl, data_out_count);
+
+	if (busy)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int wl1251_tx_id(struct wl1251 *wl, struct sk_buff *skb)
+{
+	int i;
+
+	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+		if (wl->tx_frames[i] == NULL) {
+			wl->tx_frames[i] = skb;
+			return i;
+		}
+
+	return -EBUSY;
+}
+
+static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr,
+			      struct ieee80211_tx_info *control, u16 fc)
+{
+	*(u16 *)&tx_hdr->control = 0;
+
+	tx_hdr->control.rate_policy = 0;
+
+	/* 802.11 packets */
+	tx_hdr->control.packet_type = 0;
+
+	if (control->flags & IEEE80211_TX_CTL_NO_ACK)
+		tx_hdr->control.ack_policy = 1;
+
+	tx_hdr->control.tx_complete = 1;
+
+	if ((fc & IEEE80211_FTYPE_DATA) &&
+	    ((fc & IEEE80211_STYPE_QOS_DATA) ||
+	     (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
+		tx_hdr->control.qos = 1;
+}
+
+/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
+#define MAX_MSDU_SECURITY_LENGTH      16
+#define MAX_MPDU_SECURITY_LENGTH      16
+#define WLAN_QOS_HDR_LEN              26
+#define MAX_MPDU_HEADER_AND_SECURITY  (MAX_MPDU_SECURITY_LENGTH + \
+				       WLAN_QOS_HDR_LEN)
+#define HW_BLOCK_SIZE                 252
+static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
+{
+	u16 payload_len, frag_threshold, mem_blocks;
+	u16 num_mpdus, mem_blocks_per_frag;
+
+	frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
+	tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
+
+	payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH;
+
+	if (payload_len > frag_threshold) {
+		mem_blocks_per_frag =
+			((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
+			 HW_BLOCK_SIZE) + 1;
+		num_mpdus = payload_len / frag_threshold;
+		mem_blocks = num_mpdus * mem_blocks_per_frag;
+		payload_len -= num_mpdus * frag_threshold;
+		num_mpdus++;
+
+	} else {
+		mem_blocks_per_frag = 0;
+		mem_blocks = 0;
+		num_mpdus = 1;
+	}
+
+	mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
+
+	if (num_mpdus > 1)
+		mem_blocks += min(num_mpdus, mem_blocks_per_frag);
+
+	tx_hdr->num_mem_blocks = mem_blocks;
+}
+
+static int wl1251_tx_fill_hdr(struct wl1251 *wl, struct sk_buff *skb,
+			      struct ieee80211_tx_info *control)
+{
+	struct tx_double_buffer_desc *tx_hdr;
+	struct ieee80211_rate *rate;
+	int id;
+	u16 fc;
+
+	if (!skb)
+		return -EINVAL;
+
+	id = wl1251_tx_id(wl, skb);
+	if (id < 0)
+		return id;
+
+	fc = *(u16 *)skb->data;
+	tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
+							   sizeof(*tx_hdr));
+
+	tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
+	rate = ieee80211_get_tx_rate(wl->hw, control);
+	tx_hdr->rate = cpu_to_le16(rate->hw_value);
+	tx_hdr->expiry_time = cpu_to_le32(1 << 16);
+	tx_hdr->id = id;
+
+	/* FIXME: how to get the correct queue id? */
+	tx_hdr->xmit_queue = 0;
+
+	wl1251_tx_control(tx_hdr, control, fc);
+	wl1251_tx_frag_block_num(tx_hdr);
+
+	return 0;
+}
+
+/* We copy the packet to the target */
+static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb,
+				 struct ieee80211_tx_info *control)
+{
+	struct tx_double_buffer_desc *tx_hdr;
+	int len;
+	u32 addr;
+
+	if (!skb)
+		return -EINVAL;
+
+	tx_hdr = (struct tx_double_buffer_desc *) skb->data;
+
+	if (control->control.hw_key &&
+	    control->control.hw_key->alg == ALG_TKIP) {
+		int hdrlen;
+		u16 fc;
+		u8 *pos;
+
+		fc = *(u16 *)(skb->data + sizeof(*tx_hdr));
+		tx_hdr->length += WL1251_TKIP_IV_SPACE;
+
+		hdrlen = ieee80211_hdrlen(fc);
+
+		pos = skb_push(skb, WL1251_TKIP_IV_SPACE);
+		memmove(pos, pos + WL1251_TKIP_IV_SPACE,
+			sizeof(*tx_hdr) + hdrlen);
+	}
+
+	/* Revisit. This is a workaround for getting non-aligned packets.
+	   This happens at least with EAPOL packets from the user space.
+	   Our DMA requires packets to be aligned on a 4-byte boundary.
+	*/
+	if (unlikely((long)skb->data & 0x03)) {
+		int offset = (4 - (long)skb->data) & 0x03;
+		wl1251_debug(DEBUG_TX, "skb offset %d", offset);
+
+		/* check whether the current skb can be used */
+		if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
+			unsigned char *src = skb->data;
+
+			/* align the buffer on a 4-byte boundary */
+			skb_reserve(skb, offset);
+			memmove(skb->data, src, skb->len);
+		} else {
+			wl1251_info("No handler, fixme!");
+			return -EINVAL;
+		}
+	}
+
+	/* Our skb->data at this point includes the HW header */
+	len = WL1251_TX_ALIGN(skb->len);
+
+	if (wl->data_in_count & 0x1)
+		addr = wl->data_path->tx_packet_ring_addr +
+			wl->data_path->tx_packet_ring_chunk_size;
+	else
+		addr = wl->data_path->tx_packet_ring_addr;
+
+	wl1251_mem_write(wl, addr, skb->data, len);
+
+	wl1251_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
+		     tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
+
+	return 0;
+}
+
+static void wl1251_tx_trigger(struct wl1251 *wl)
+{
+	u32 data, addr;
+
+	if (wl->data_in_count & 0x1) {
+		addr = ACX_REG_INTERRUPT_TRIG_H;
+		data = INTR_TRIG_TX_PROC1;
+	} else {
+		addr = ACX_REG_INTERRUPT_TRIG;
+		data = INTR_TRIG_TX_PROC0;
+	}
+
+	wl1251_reg_write32(wl, addr, data);
+
+	/* Bumping data in */
+	wl->data_in_count = (wl->data_in_count + 1) &
+		TX_STATUS_DATA_OUT_COUNT_MASK;
+}
+
+/* caller must hold wl->mutex */
+static int wl1251_tx_frame(struct wl1251 *wl, struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info;
+	int ret = 0;
+	u8 idx;
+
+	info = IEEE80211_SKB_CB(skb);
+
+	if (info->control.hw_key) {
+		idx = info->control.hw_key->hw_key_idx;
+		if (unlikely(wl->default_key != idx)) {
+			ret = wl1251_acx_default_key(wl, idx);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	ret = wl1251_tx_path_status(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_tx_fill_hdr(wl, skb, info);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1251_tx_send_packet(wl, skb, info);
+	if (ret < 0)
+		return ret;
+
+	wl1251_tx_trigger(wl);
+
+	return ret;
+}
+
+void wl1251_tx_work(struct work_struct *work)
+{
+	struct wl1251 *wl = container_of(work, struct wl1251, tx_work);
+	struct sk_buff *skb;
+	bool woken_up = false;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state == WL1251_STATE_OFF))
+		goto out;
+
+	while ((skb = skb_dequeue(&wl->tx_queue))) {
+		if (!woken_up) {
+			ret = wl1251_ps_elp_wakeup(wl);
+			if (ret < 0)
+				goto out;
+			woken_up = true;
+		}
+
+		ret = wl1251_tx_frame(wl, skb);
+		if (ret == -EBUSY) {
+			/* firmware buffer is full, stop queues */
+			wl1251_debug(DEBUG_TX, "tx_work: fw buffer full, "
+				     "stop queues");
+			ieee80211_stop_queues(wl->hw);
+			wl->tx_queue_stopped = true;
+			skb_queue_head(&wl->tx_queue, skb);
+			goto out;
+		} else if (ret < 0) {
+			dev_kfree_skb(skb);
+			goto out;
+		}
+	}
+
+out:
+	if (woken_up)
+		wl1251_ps_elp_sleep(wl);
+
+	mutex_unlock(&wl->mutex);
+}
+
+static const char *wl1251_tx_parse_status(u8 status)
+{
+	/* 8 bit status field, one character per bit plus null */
+	static char buf[9];
+	int i = 0;
+
+	memset(buf, 0, sizeof(buf));
+
+	if (status & TX_DMA_ERROR)
+		buf[i++] = 'm';
+	if (status & TX_DISABLED)
+		buf[i++] = 'd';
+	if (status & TX_RETRY_EXCEEDED)
+		buf[i++] = 'r';
+	if (status & TX_TIMEOUT)
+		buf[i++] = 't';
+	if (status & TX_KEY_NOT_FOUND)
+		buf[i++] = 'k';
+	if (status & TX_ENCRYPT_FAIL)
+		buf[i++] = 'e';
+	if (status & TX_UNAVAILABLE_PRIORITY)
+		buf[i++] = 'p';
+
+	/* bit 0 is unused apparently */
+
+	return buf;
+}
+
+static void wl1251_tx_packet_cb(struct wl1251 *wl,
+				struct tx_result *result)
+{
+	struct ieee80211_tx_info *info;
+	struct sk_buff *skb;
+	int hdrlen, ret;
+	u8 *frame;
+
+	skb = wl->tx_frames[result->id];
+	if (skb == NULL) {
+		wl1251_error("SKB for packet %d is NULL", result->id);
+		return;
+	}
+
+	info = IEEE80211_SKB_CB(skb);
+
+	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+	    (result->status == TX_SUCCESS))
+		info->flags |= IEEE80211_TX_STAT_ACK;
+
+	info->status.rates[0].count = result->ack_failures + 1;
+	wl->stats.retry_count += result->ack_failures;
+
+	/*
+	 * We have to remove our private TX header before pushing
+	 * the skb back to mac80211.
+	 */
+	frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
+	if (info->control.hw_key &&
+	    info->control.hw_key->alg == ALG_TKIP) {
+		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+		memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen);
+		skb_pull(skb, WL1251_TKIP_IV_SPACE);
+	}
+
+	wl1251_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
+		     " status 0x%x (%s)",
+		     result->id, skb, result->ack_failures, result->rate,
+		     result->status, wl1251_tx_parse_status(result->status));
+
+
+	ieee80211_tx_status(wl->hw, skb);
+
+	wl->tx_frames[result->id] = NULL;
+
+	if (wl->tx_queue_stopped) {
+		wl1251_debug(DEBUG_TX, "cb: queue was stopped");
+
+		skb = skb_dequeue(&wl->tx_queue);
+
+		/* The skb can be NULL because tx_work might have been
+		   scheduled before the queue was stopped making the
+		   queue empty */
+
+		if (skb) {
+			ret = wl1251_tx_frame(wl, skb);
+			if (ret == -EBUSY) {
+				/* firmware buffer is still full */
+				wl1251_debug(DEBUG_TX, "cb: fw buffer "
+					     "still full");
+				skb_queue_head(&wl->tx_queue, skb);
+				return;
+			} else if (ret < 0) {
+				dev_kfree_skb(skb);
+				return;
+			}
+		}
+
+		wl1251_debug(DEBUG_TX, "cb: waking queues");
+		ieee80211_wake_queues(wl->hw);
+		wl->tx_queue_stopped = false;
+	}
+}
+
+/* Called upon reception of a TX complete interrupt */
+void wl1251_tx_complete(struct wl1251 *wl)
+{
+	int i, result_index, num_complete = 0;
+	struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
+
+	if (unlikely(wl->state != WL1251_STATE_ON))
+		return;
+
+	/* First we read the result */
+	wl1251_mem_read(wl, wl->data_path->tx_complete_addr,
+			    result, sizeof(result));
+
+	result_index = wl->next_tx_complete;
+
+	for (i = 0; i < ARRAY_SIZE(result); i++) {
+		result_ptr = &result[result_index];
+
+		if (result_ptr->done_1 == 1 &&
+		    result_ptr->done_2 == 1) {
+			wl1251_tx_packet_cb(wl, result_ptr);
+
+			result_ptr->done_1 = 0;
+			result_ptr->done_2 = 0;
+
+			result_index = (result_index + 1) &
+				(FW_TX_CMPLT_BLOCK_SIZE - 1);
+			num_complete++;
+		} else {
+			break;
+		}
+	}
+
+	/* Every completed frame needs to be acknowledged */
+	if (num_complete) {
+		/*
+		 * If we've wrapped, we have to clear
+		 * the results in 2 steps.
+		 */
+		if (result_index > wl->next_tx_complete) {
+			/* Only 1 write is needed */
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr +
+					 (wl->next_tx_complete *
+					  sizeof(struct tx_result)),
+					 &result[wl->next_tx_complete],
+					 num_complete *
+					 sizeof(struct tx_result));
+
+
+		} else if (result_index < wl->next_tx_complete) {
+			/* 2 writes are needed */
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr +
+					 (wl->next_tx_complete *
+					  sizeof(struct tx_result)),
+					 &result[wl->next_tx_complete],
+					 (FW_TX_CMPLT_BLOCK_SIZE -
+					  wl->next_tx_complete) *
+					 sizeof(struct tx_result));
+
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr,
+					 result,
+					 (num_complete -
+					  FW_TX_CMPLT_BLOCK_SIZE +
+					  wl->next_tx_complete) *
+					 sizeof(struct tx_result));
+
+		} else {
+			/* We have to write the whole array */
+			wl1251_mem_write(wl,
+					 wl->data_path->tx_complete_addr,
+					 result,
+					 FW_TX_CMPLT_BLOCK_SIZE *
+					 sizeof(struct tx_result));
+		}
+
+	}
+
+	wl->next_tx_complete = result_index;
+}
+
+/* caller must hold wl->mutex */
+void wl1251_tx_flush(struct wl1251 *wl)
+{
+	int i;
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *info;
+
+	/* TX failure */
+/* 	control->flags = 0; FIXME */
+
+	while ((skb = skb_dequeue(&wl->tx_queue))) {
+		info = IEEE80211_SKB_CB(skb);
+
+		wl1251_debug(DEBUG_TX, "flushing skb 0x%p", skb);
+
+		if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+				continue;
+
+		ieee80211_tx_status(wl->hw, skb);
+	}
+
+	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+		if (wl->tx_frames[i] != NULL) {
+			skb = wl->tx_frames[i];
+			info = IEEE80211_SKB_CB(skb);
+
+			if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+				continue;
+
+			ieee80211_tx_status(wl->hw, skb);
+			wl->tx_frames[i] = NULL;
+		}
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
new file mode 100644
index 0000000..7c1c166
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.h
@@ -0,0 +1,216 @@
+/*
+ * This file is part of wl1251
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * 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
+ *
+ */
+
+#ifndef __WL1251_TX_H__
+#define __WL1251_TX_H__
+
+#include <linux/bitops.h>
+
+/*
+ *
+ * TX PATH
+ *
+ * The Tx path uses a double buffer and a tx_control structure, each located
+ * at a fixed address in the device's memory. On startup, the host retrieves
+ * the pointers to these addresses. A double buffer allows for continuous data
+ * flow towards the device. The host keeps track of which buffer is available
+ * and alternates between these two buffers on a per packet basis.
+ *
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet - maximum size Ethernet packet + header + descriptor.
+ * TX complete indication will be received a-synchronously in a TX done cyclic
+ * buffer which is composed of 16 tx_result descriptors structures and is used
+ * in a cyclic manner.
+ *
+ * The TX (HOST) procedure is as follows:
+ * 1. Read the Tx path status, that will give the data_out_count.
+ * 2. goto 1, if not possible.
+ *    i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
+ *    buffer).
+ * 3. Copy the packet (preceded by double_buffer_desc), if possible.
+ *    i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
+ *    buffer).
+ * 4. increment data_in_count.
+ * 5. Inform the firmware by generating a firmware internal interrupt.
+ * 6. FW will increment data_out_count after it reads the buffer.
+ *
+ * The TX Complete procedure:
+ * 1. To get a TX complete indication the host enables the tx_complete flag in
+ *    the TX descriptor Structure.
+ * 2. For each packet with a Tx Complete field set, the firmware adds the
+ *    transmit results to the cyclic buffer (txDoneRing) and sets both done_1
+ *    and done_2 to 1 to indicate driver ownership.
+ * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
+ *    host to process the new data. Note: interrupt will be send per packet if
+ *    TX complete indication was requested in tx_control or per crossing
+ *    aggregation threshold.
+ * 4. After receiving the Tx Complete interrupt, the host reads the
+ *    TxDescriptorDone information in a cyclic manner and clears both done_1
+ *    and done_2 fields.
+ *
+ */
+
+#define TX_COMPLETE_REQUIRED_BIT	0x80
+#define TX_STATUS_DATA_OUT_COUNT_MASK   0xf
+
+#define WL1251_TX_ALIGN_TO 4
+#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \
+			     ~(WL1251_TX_ALIGN_TO - 1))
+#define WL1251_TKIP_IV_SPACE 4
+
+struct tx_control {
+	/* Rate Policy (class) index */
+	unsigned rate_policy:3;
+
+	/* When set, no ack policy is expected */
+	unsigned ack_policy:1;
+
+	/*
+	 * Packet type:
+	 * 0 -> 802.11
+	 * 1 -> 802.3
+	 * 2 -> IP
+	 * 3 -> raw codec
+	 */
+	unsigned packet_type:2;
+
+	/* If set, this is a QoS-Null or QoS-Data frame */
+	unsigned qos:1;
+
+	/*
+	 * If set, the target triggers the tx complete INT
+	 * upon frame sending completion.
+	 */
+	unsigned tx_complete:1;
+
+	/* 2 bytes padding before packet header */
+	unsigned xfer_pad:1;
+
+	unsigned reserved:7;
+} __attribute__ ((packed));
+
+
+struct tx_double_buffer_desc {
+	/* Length of payload, including headers. */
+	u16 length;
+
+	/*
+	 * A bit mask that specifies the initial rate to be used
+	 * Possible values are:
+	 * 0x0001 - 1Mbits
+	 * 0x0002 - 2Mbits
+	 * 0x0004 - 5.5Mbits
+	 * 0x0008 - 6Mbits
+	 * 0x0010 - 9Mbits
+	 * 0x0020 - 11Mbits
+	 * 0x0040 - 12Mbits
+	 * 0x0080 - 18Mbits
+	 * 0x0100 - 22Mbits
+	 * 0x0200 - 24Mbits
+	 * 0x0400 - 36Mbits
+	 * 0x0800 - 48Mbits
+	 * 0x1000 - 54Mbits
+	 */
+	u16 rate;
+
+	/* Time in us that a packet can spend in the target */
+	u32 expiry_time;
+
+	/* index of the TX queue used for this packet */
+	u8 xmit_queue;
+
+	/* Used to identify a packet */
+	u8 id;
+
+	struct tx_control control;
+
+	/*
+	 * The FW should cut the packet into fragments
+	 * of this size.
+	 */
+	u16 frag_threshold;
+
+	/* Numbers of HW queue blocks to be allocated */
+	u8 num_mem_blocks;
+
+	u8 reserved;
+} __attribute__ ((packed));
+
+enum {
+	TX_SUCCESS              = 0,
+	TX_DMA_ERROR            = BIT(7),
+	TX_DISABLED             = BIT(6),
+	TX_RETRY_EXCEEDED       = BIT(5),
+	TX_TIMEOUT              = BIT(4),
+	TX_KEY_NOT_FOUND        = BIT(3),
+	TX_ENCRYPT_FAIL         = BIT(2),
+	TX_UNAVAILABLE_PRIORITY = BIT(1),
+};
+
+struct tx_result {
+	/*
+	 * Ownership synchronization between the host and
+	 * the firmware. If done_1 and done_2 are cleared,
+	 * owned by the FW (no info ready).
+	 */
+	u8 done_1;
+
+	/* same as double_buffer_desc->id */
+	u8 id;
+
+	/*
+	 * Total air access duration consumed by this
+	 * packet, including all retries and overheads.
+	 */
+	u16 medium_usage;
+
+	/* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
+	u32 medium_delay;
+
+	/* Time between host xfer and tx complete */
+	u32 fw_hnadling_time;
+
+	/* The LS-byte of the last TKIP sequence number. */
+	u8 lsb_seq_num;
+
+	/* Retry count */
+	u8 ack_failures;
+
+	/* At which rate we got a ACK */
+	u16 rate;
+
+	u16 reserved;
+
+	/* TX_* */
+	u8 status;
+
+	/* See done_1 */
+	u8 done_2;
+} __attribute__ ((packed));
+
+void wl1251_tx_work(struct work_struct *work);
+void wl1251_tx_complete(struct wl1251 *wl);
+void wl1251_tx_flush(struct wl1251 *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
new file mode 100644
index 0000000..55818f9
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -0,0 +1,407 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_H__
+#define __WL1271_H__
+
+#include <linux/mutex.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <net/mac80211.h>
+
+#define DRIVER_NAME "wl1271"
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+	DEBUG_NONE	= 0,
+	DEBUG_IRQ	= BIT(0),
+	DEBUG_SPI	= BIT(1),
+	DEBUG_BOOT	= BIT(2),
+	DEBUG_MAILBOX	= BIT(3),
+	DEBUG_NETLINK	= BIT(4),
+	DEBUG_EVENT	= BIT(5),
+	DEBUG_TX	= BIT(6),
+	DEBUG_RX	= BIT(7),
+	DEBUG_SCAN	= BIT(8),
+	DEBUG_CRYPT	= BIT(9),
+	DEBUG_PSM	= BIT(10),
+	DEBUG_MAC80211	= BIT(11),
+	DEBUG_CMD	= BIT(12),
+	DEBUG_ACX	= BIT(13),
+	DEBUG_ALL	= ~0,
+};
+
+#define DEBUG_LEVEL (DEBUG_NONE)
+
+#define DEBUG_DUMP_LIMIT 1024
+
+#define wl1271_error(fmt, arg...) \
+	printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define wl1271_warning(fmt, arg...) \
+	printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define wl1271_notice(fmt, arg...) \
+	printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl1271_info(fmt, arg...) \
+	printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl1271_debug(level, fmt, arg...) \
+	do { \
+		if (level & DEBUG_LEVEL) \
+			printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+	} while (0)
+
+#define wl1271_dump(level, prefix, buf, len)	\
+	do { \
+		if (level & DEBUG_LEVEL) \
+			print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+				       DUMP_PREFIX_OFFSET, 16, 1,	\
+				       buf,				\
+				       min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+				       0);				\
+	} while (0)
+
+#define wl1271_dump_ascii(level, prefix, buf, len)	\
+	do { \
+		if (level & DEBUG_LEVEL) \
+			print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+				       DUMP_PREFIX_OFFSET, 16, 1,	\
+				       buf,				\
+				       min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+				       true);				\
+	} while (0)
+
+#define WL1271_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN |	\
+				  CFG_BSSID_FILTER_EN)
+
+#define WL1271_DEFAULT_RX_FILTER (CFG_RX_RCTS_ACK | CFG_RX_PRSP_EN |  \
+				  CFG_RX_MGMT_EN | CFG_RX_DATA_EN |   \
+				  CFG_RX_CTL_EN | CFG_RX_BCN_EN |     \
+				  CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
+
+#define WL1271_FW_NAME "wl1271-fw.bin"
+#define WL1271_NVS_NAME "wl1271-nvs.bin"
+
+#define WL1271_BUSY_WORD_LEN 8
+
+#define WL1271_ELP_HW_STATE_ASLEEP 0
+#define WL1271_ELP_HW_STATE_IRQ    1
+
+enum wl1271_state {
+	WL1271_STATE_OFF,
+	WL1271_STATE_ON,
+	WL1271_STATE_PLT,
+};
+
+enum wl1271_partition_type {
+	PART_DOWN,
+	PART_WORK,
+	PART_DRPW,
+
+	PART_TABLE_LEN
+};
+
+struct wl1271_partition {
+	u32 size;
+	u32 start;
+};
+
+struct wl1271_partition_set {
+	struct wl1271_partition mem;
+	struct wl1271_partition reg;
+};
+
+struct wl1271;
+
+/* FIXME: I'm not sure about this structure name */
+struct wl1271_chip {
+	u32 id;
+	char fw_ver[21];
+};
+
+struct wl1271_stats {
+	struct acx_statistics *fw_stats;
+	unsigned long fw_stats_update;
+
+	unsigned int retry_count;
+	unsigned int excessive_retries;
+};
+
+struct wl1271_debugfs {
+	struct dentry *rootdir;
+	struct dentry *fw_statistics;
+
+	struct dentry *tx_internal_desc_overflow;
+
+	struct dentry *rx_out_of_mem;
+	struct dentry *rx_hdr_overflow;
+	struct dentry *rx_hw_stuck;
+	struct dentry *rx_dropped;
+	struct dentry *rx_fcs_err;
+	struct dentry *rx_xfr_hint_trig;
+	struct dentry *rx_path_reset;
+	struct dentry *rx_reset_counter;
+
+	struct dentry *dma_rx_requested;
+	struct dentry *dma_rx_errors;
+	struct dentry *dma_tx_requested;
+	struct dentry *dma_tx_errors;
+
+	struct dentry *isr_cmd_cmplt;
+	struct dentry *isr_fiqs;
+	struct dentry *isr_rx_headers;
+	struct dentry *isr_rx_mem_overflow;
+	struct dentry *isr_rx_rdys;
+	struct dentry *isr_irqs;
+	struct dentry *isr_tx_procs;
+	struct dentry *isr_decrypt_done;
+	struct dentry *isr_dma0_done;
+	struct dentry *isr_dma1_done;
+	struct dentry *isr_tx_exch_complete;
+	struct dentry *isr_commands;
+	struct dentry *isr_rx_procs;
+	struct dentry *isr_hw_pm_mode_changes;
+	struct dentry *isr_host_acknowledges;
+	struct dentry *isr_pci_pm;
+	struct dentry *isr_wakeups;
+	struct dentry *isr_low_rssi;
+
+	struct dentry *wep_addr_key_count;
+	struct dentry *wep_default_key_count;
+	/* skipping wep.reserved */
+	struct dentry *wep_key_not_found;
+	struct dentry *wep_decrypt_fail;
+	struct dentry *wep_packets;
+	struct dentry *wep_interrupt;
+
+	struct dentry *pwr_ps_enter;
+	struct dentry *pwr_elp_enter;
+	struct dentry *pwr_missing_bcns;
+	struct dentry *pwr_wake_on_host;
+	struct dentry *pwr_wake_on_timer_exp;
+	struct dentry *pwr_tx_with_ps;
+	struct dentry *pwr_tx_without_ps;
+	struct dentry *pwr_rcvd_beacons;
+	struct dentry *pwr_power_save_off;
+	struct dentry *pwr_enable_ps;
+	struct dentry *pwr_disable_ps;
+	struct dentry *pwr_fix_tsf_ps;
+	/* skipping cont_miss_bcns_spread for now */
+	struct dentry *pwr_rcvd_awake_beacons;
+
+	struct dentry *mic_rx_pkts;
+	struct dentry *mic_calc_failure;
+
+	struct dentry *aes_encrypt_fail;
+	struct dentry *aes_decrypt_fail;
+	struct dentry *aes_encrypt_packets;
+	struct dentry *aes_decrypt_packets;
+	struct dentry *aes_encrypt_interrupt;
+	struct dentry *aes_decrypt_interrupt;
+
+	struct dentry *event_heart_beat;
+	struct dentry *event_calibration;
+	struct dentry *event_rx_mismatch;
+	struct dentry *event_rx_mem_empty;
+	struct dentry *event_rx_pool;
+	struct dentry *event_oom_late;
+	struct dentry *event_phy_transmit_error;
+	struct dentry *event_tx_stuck;
+
+	struct dentry *ps_pspoll_timeouts;
+	struct dentry *ps_upsd_timeouts;
+	struct dentry *ps_upsd_max_sptime;
+	struct dentry *ps_upsd_max_apturn;
+	struct dentry *ps_pspoll_max_apturn;
+	struct dentry *ps_pspoll_utilization;
+	struct dentry *ps_upsd_utilization;
+
+	struct dentry *rxpipe_rx_prep_beacon_drop;
+	struct dentry *rxpipe_descr_host_int_trig_rx_data;
+	struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
+	struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
+	struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
+
+	struct dentry *tx_queue_len;
+
+	struct dentry *retry_count;
+	struct dentry *excessive_retries;
+};
+
+#define NUM_TX_QUEUES              4
+#define NUM_RX_PKT_DESC            8
+
+/* FW status registers */
+struct wl1271_fw_status {
+	u32 intr;
+	u8  fw_rx_counter;
+	u8  drv_rx_counter;
+	u8  reserved;
+	u8  tx_results_counter;
+	u32 rx_pkt_descs[NUM_RX_PKT_DESC];
+	u32 tx_released_blks[NUM_TX_QUEUES];
+	u32 fw_localtime;
+	u32 padding[2];
+} __attribute__ ((packed));
+
+struct wl1271_rx_mem_pool_addr {
+	u32 addr;
+	u32 addr_extra;
+};
+
+struct wl1271 {
+	struct ieee80211_hw *hw;
+	bool mac80211_registered;
+
+	struct spi_device *spi;
+
+	void (*set_power)(bool enable);
+	int irq;
+
+	spinlock_t wl_lock;
+
+	enum wl1271_state state;
+	struct mutex mutex;
+
+	int physical_mem_addr;
+	int physical_reg_addr;
+	int virtual_mem_addr;
+	int virtual_reg_addr;
+
+	struct wl1271_chip chip;
+
+	int cmd_box_addr;
+	int event_box_addr;
+
+	u8 *fw;
+	size_t fw_len;
+	u8 *nvs;
+	size_t nvs_len;
+
+	u8 bssid[ETH_ALEN];
+	u8 mac_addr[ETH_ALEN];
+	u8 bss_type;
+	u8 ssid[IW_ESSID_MAX_SIZE + 1];
+	u8 ssid_len;
+	u8 listen_int;
+	int channel;
+
+	struct wl1271_acx_mem_map *target_mem_map;
+
+	/* Accounting for allocated / available TX blocks on HW */
+	u32 tx_blocks_freed[NUM_TX_QUEUES];
+	u32 tx_blocks_available;
+	u8 tx_results_count;
+
+	/* Transmitted TX packets counter for chipset interface */
+	int tx_packets_count;
+
+	/* Time-offset between host and chipset clocks */
+	int time_offset;
+
+	/* Session counter for the chipset */
+	int session_counter;
+
+	/* Frames scheduled for transmission, not handled yet */
+	struct sk_buff_head tx_queue;
+	bool tx_queue_stopped;
+
+	struct work_struct tx_work;
+	struct work_struct filter_work;
+
+	/* Pending TX frames */
+	struct sk_buff *tx_frames[16];
+
+	/* FW Rx counter */
+	u32 rx_counter;
+
+	/* Rx memory pool address */
+	struct wl1271_rx_mem_pool_addr rx_mem_pool_addr;
+
+	/* The target interrupt mask */
+	struct work_struct irq_work;
+
+	/* The mbox event mask */
+	u32 event_mask;
+
+	/* Mailbox pointers */
+	u32 mbox_ptr[2];
+
+	/* Are we currently scanning */
+	bool scanning;
+
+	/* Our association ID */
+	u16 aid;
+
+	/* Default key (for WEP) */
+	u32 default_key;
+
+	unsigned int rx_config;
+	unsigned int rx_filter;
+
+	/* is firmware in elp mode */
+	bool elp;
+
+	struct completion *elp_compl;
+
+	/* we can be in psm, but not in elp, we have to differentiate */
+	bool psm;
+
+	/* PSM mode requested */
+	bool psm_requested;
+
+	/* in dBm */
+	int power_level;
+
+	struct wl1271_stats stats;
+	struct wl1271_debugfs debugfs;
+
+	u32 buffer_32;
+	u32 buffer_cmd;
+	u8 buffer_busyword[WL1271_BUSY_WORD_LEN];
+	struct wl1271_rx_descriptor *rx_descriptor;
+
+	struct wl1271_fw_status *fw_status;
+	struct wl1271_tx_hw_res_if *tx_res_if;
+};
+
+int wl1271_plt_start(struct wl1271 *wl);
+int wl1271_plt_stop(struct wl1271 *wl);
+
+#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
+
+#define SESSION_COUNTER_MAX 7 /* maximum value for the session counter */
+
+#define WL1271_DEFAULT_POWER_LEVEL 0
+
+#define WL1271_TX_QUEUE_MAX_LENGTH 20
+
+/* WL1271 needs a 200ms sleep after power on */
+#define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
new file mode 100644
index 0000000..f622a40
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -0,0 +1,961 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_acx.h"
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl1271.h"
+#include "wl12xx_80211.h"
+#include "wl1271_reg.h"
+#include "wl1271_spi.h"
+#include "wl1271_ps.h"
+
+int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
+				  u8 listen_interval)
+{
+	struct acx_wake_up_condition *wake_up;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx wake up conditions");
+
+	wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
+	if (!wake_up) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	wake_up->wake_up_event = wake_up_event;
+	wake_up->listen_interval = listen_interval;
+
+	ret = wl1271_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
+				   wake_up, sizeof(*wake_up));
+	if (ret < 0) {
+		wl1271_warning("could not set wake up conditions: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(wake_up);
+	return ret;
+}
+
+int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth)
+{
+	struct acx_sleep_auth *auth;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx sleep auth");
+
+	auth = kzalloc(sizeof(*auth), GFP_KERNEL);
+	if (!auth) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	auth->sleep_auth = sleep_auth;
+
+	ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
+	if (ret < 0)
+		return ret;
+
+out:
+	kfree(auth);
+	return ret;
+}
+
+int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len)
+{
+	struct acx_revision *rev;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx fw rev");
+
+	rev = kzalloc(sizeof(*rev), GFP_KERNEL);
+	if (!rev) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
+	if (ret < 0) {
+		wl1271_warning("ACX_FW_REV interrogate failed");
+		goto out;
+	}
+
+	/* be careful with the buffer sizes */
+	strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
+
+	/*
+	 * if the firmware version string is exactly
+	 * sizeof(rev->fw_version) long or fw_len is less than
+	 * sizeof(rev->fw_version) it won't be null terminated
+	 */
+	buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
+
+out:
+	kfree(rev);
+	return ret;
+}
+
+int wl1271_acx_tx_power(struct wl1271 *wl, int power)
+{
+	struct acx_current_tx_power *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
+
+	if (power < 0 || power > 25)
+		return -EINVAL;
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->current_tx_power = power * 10;
+
+	ret = wl1271_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("configure of tx power failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_feature_cfg(struct wl1271 *wl)
+{
+	struct acx_feature_config *feature;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx feature cfg");
+
+	feature = kzalloc(sizeof(*feature), GFP_KERNEL);
+	if (!feature) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
+	feature->data_flow_options = 0;
+	feature->options = 0;
+
+	ret = wl1271_cmd_configure(wl, ACX_FEATURE_CFG,
+				   feature, sizeof(*feature));
+	if (ret < 0) {
+		wl1271_error("Couldnt set HW encryption");
+		goto out;
+	}
+
+out:
+	kfree(feature);
+	return ret;
+}
+
+int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map,
+		       size_t len)
+{
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx mem map");
+
+	ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time)
+{
+	struct acx_rx_msdu_lifetime *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx rx msdu life time");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->lifetime = life_time;
+	ret = wl1271_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("failed to set rx msdu life time: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter)
+{
+	struct acx_rx_config *rx_config;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx rx config");
+
+	rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
+	if (!rx_config) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	rx_config->config_options = config;
+	rx_config->filter_options = filter;
+
+	ret = wl1271_cmd_configure(wl, ACX_RX_CFG,
+				   rx_config, sizeof(*rx_config));
+	if (ret < 0) {
+		wl1271_warning("failed to set rx config: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(rx_config);
+	return ret;
+}
+
+int wl1271_acx_pd_threshold(struct wl1271 *wl)
+{
+	struct acx_packet_detection *pd;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx data pd threshold");
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* FIXME: threshold value not set */
+
+	ret = wl1271_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
+	if (ret < 0) {
+		wl1271_warning("failed to set pd threshold: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(pd);
+	return 0;
+}
+
+int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time)
+{
+	struct acx_slot *slot;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx slot");
+
+	slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+	if (!slot) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	slot->wone_index = STATION_WONE_INDEX;
+	slot->slot_time = slot_time;
+
+	ret = wl1271_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
+	if (ret < 0) {
+		wl1271_warning("failed to set slot time: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(slot);
+	return ret;
+}
+
+int wl1271_acx_group_address_tbl(struct wl1271 *wl)
+{
+	struct acx_dot11_grp_addr_tbl *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx group address tbl");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* MAC filtering */
+	acx->enabled = 0;
+	acx->num_groups = 0;
+	memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+
+	ret = wl1271_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("failed to set group addr table: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_service_period_timeout(struct wl1271 *wl)
+{
+	struct acx_rx_timeout *rx_timeout;
+	int ret;
+
+	rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
+	if (!rx_timeout) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	wl1271_debug(DEBUG_ACX, "acx service period timeout");
+
+	rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
+	rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
+
+	ret = wl1271_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
+				   rx_timeout, sizeof(*rx_timeout));
+	if (ret < 0) {
+		wl1271_warning("failed to set service period timeout: %d",
+			       ret);
+		goto out;
+	}
+
+out:
+	kfree(rx_timeout);
+	return ret;
+}
+
+int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
+{
+	struct acx_rts_threshold *rts;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx rts threshold");
+
+	rts = kzalloc(sizeof(*rts), GFP_KERNEL);
+	if (!rts) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	rts->threshold = rts_threshold;
+
+	ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
+	if (ret < 0) {
+		wl1271_warning("failed to set rts threshold: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(rts);
+	return ret;
+}
+
+int wl1271_acx_beacon_filter_opt(struct wl1271 *wl)
+{
+	struct acx_beacon_filter_option *beacon_filter;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx beacon filter opt");
+
+	beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
+	if (!beacon_filter) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	beacon_filter->enable = 0;
+	beacon_filter->max_num_beacons = 0;
+
+	ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
+				   beacon_filter, sizeof(*beacon_filter));
+	if (ret < 0) {
+		wl1271_warning("failed to set beacon filter opt: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(beacon_filter);
+	return ret;
+}
+
+int wl1271_acx_beacon_filter_table(struct wl1271 *wl)
+{
+	struct acx_beacon_filter_ie_table *ie_table;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx beacon filter table");
+
+	ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
+	if (!ie_table) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ie_table->num_ie = 0;
+	memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
+
+	ret = wl1271_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
+				   ie_table, sizeof(*ie_table));
+	if (ret < 0) {
+		wl1271_warning("failed to set beacon filter table: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(ie_table);
+	return ret;
+}
+
+int wl1271_acx_sg_enable(struct wl1271 *wl)
+{
+	struct acx_bt_wlan_coex *pta;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx sg enable");
+
+	pta = kzalloc(sizeof(*pta), GFP_KERNEL);
+	if (!pta) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pta->enable = SG_ENABLE;
+
+	ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
+	if (ret < 0) {
+		wl1271_warning("failed to set softgemini enable: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(pta);
+	return ret;
+}
+
+int wl1271_acx_sg_cfg(struct wl1271 *wl)
+{
+	struct acx_bt_wlan_coex_param *param;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx sg cfg");
+
+	param = kzalloc(sizeof(*param), GFP_KERNEL);
+	if (!param) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* BT-WLAN coext parameters */
+	param->min_rate = RATE_INDEX_24MBPS;
+	param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
+	param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
+	param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
+	param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
+	param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
+	param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
+	param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
+	param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
+	param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
+	param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
+	param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
+	param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
+	param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
+	param->antenna_type = PTA_ANTENNA_TYPE_DEF;
+	param->signal_type = PTA_SIGNALING_TYPE_DEF;
+	param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
+	param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
+	param->max_cts = PTA_MAX_NUM_CTS_DEF;
+	param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
+	param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
+	param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
+	param->wlan_elp_hp = PTA_ELP_HP_DEF;
+	param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
+	param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
+	param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
+	param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
+	param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
+
+	ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
+	if (ret < 0) {
+		wl1271_warning("failed to set sg config: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(param);
+	return ret;
+}
+
+int wl1271_acx_cca_threshold(struct wl1271 *wl)
+{
+	struct acx_energy_detection *detection;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx cca threshold");
+
+	detection = kzalloc(sizeof(*detection), GFP_KERNEL);
+	if (!detection) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
+	detection->tx_energy_detection = 0;
+
+	ret = wl1271_cmd_configure(wl, ACX_CCA_THRESHOLD,
+				   detection, sizeof(*detection));
+	if (ret < 0) {
+		wl1271_warning("failed to set cca threshold: %d", ret);
+		return ret;
+	}
+
+out:
+	kfree(detection);
+	return ret;
+}
+
+int wl1271_acx_bcn_dtim_options(struct wl1271 *wl)
+{
+	struct acx_beacon_broadcast *bb;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx bcn dtim options");
+
+	bb = kzalloc(sizeof(*bb), GFP_KERNEL);
+	if (!bb) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
+	bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
+	bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
+	bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
+
+	ret = wl1271_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
+	if (ret < 0) {
+		wl1271_warning("failed to set rx config: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(bb);
+	return ret;
+}
+
+int wl1271_acx_aid(struct wl1271 *wl, u16 aid)
+{
+	struct acx_aid *acx_aid;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx aid");
+
+	acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
+	if (!acx_aid) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx_aid->aid = aid;
+
+	ret = wl1271_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
+	if (ret < 0) {
+		wl1271_warning("failed to set aid: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx_aid);
+	return ret;
+}
+
+int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask)
+{
+	struct acx_event_mask *mask;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx event mbox mask");
+
+	mask = kzalloc(sizeof(*mask), GFP_KERNEL);
+	if (!mask) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* high event mask is unused */
+	mask->high_event_mask = 0xffffffff;
+
+	mask->event_mask = event_mask;
+
+	ret = wl1271_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
+				   mask, sizeof(*mask));
+	if (ret < 0) {
+		wl1271_warning("failed to set acx_event_mbox_mask: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(mask);
+	return ret;
+}
+
+int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble)
+{
+	struct acx_preamble *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx_set_preamble");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->preamble = preamble;
+
+	ret = wl1271_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("Setting of preamble failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_cts_protect(struct wl1271 *wl,
+			   enum acx_ctsprotect_type ctsprotect)
+{
+	struct acx_ctsprotect *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->ctsprotect = ctsprotect;
+
+	ret = wl1271_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("Setting of ctsprotect failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
+{
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx statistics");
+
+	ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats,
+				     sizeof(*stats));
+	if (ret < 0) {
+		wl1271_warning("acx statistics failed: %d", ret);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int wl1271_acx_rate_policies(struct wl1271 *wl)
+{
+	struct acx_rate_policy *acx;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx rate policies");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* configure one default (one-size-fits-all) rate class */
+	acx->rate_class_cnt = 1;
+	acx->rate_class[0].enabled_rates = ACX_RATE_MASK_ALL;
+	acx->rate_class[0].short_retry_limit = ACX_RATE_RETRY_LIMIT;
+	acx->rate_class[0].long_retry_limit = ACX_RATE_RETRY_LIMIT;
+	acx->rate_class[0].aflags = 0;
+
+	ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("Setting of rate policies failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_ac_cfg(struct wl1271 *wl)
+{
+	struct acx_ac_cfg *acx;
+	int i, ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx access category config");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * FIXME: Configure each AC with appropriate values (most suitable
+	 * values will probably be different for each AC.
+	 */
+	for (i = 0; i < WL1271_ACX_AC_COUNT; i++) {
+		acx->ac = i;
+
+		/*
+		 * FIXME: The following default values originate from
+		 * the TI reference driver. What do they mean?
+		 */
+		acx->cw_min = 15;
+		acx->cw_max = 63;
+		acx->aifsn = 3;
+		acx->reserved = 0;
+		acx->tx_op_limit = 0;
+
+		ret = wl1271_cmd_configure(wl, ACX_AC_CFG, acx, sizeof(*acx));
+		if (ret < 0) {
+			wl1271_warning("Setting of access category "
+				       "config: %d", ret);
+			goto out;
+		}
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_tid_cfg(struct wl1271 *wl)
+{
+	struct acx_tid_config *acx;
+	int i, ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx tid config");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* FIXME: configure each TID with a different AC reference */
+	for (i = 0; i < WL1271_ACX_TID_COUNT; i++) {
+		acx->queue_id = i;
+		acx->tsid = WL1271_ACX_AC_BE;
+		acx->ps_scheme = WL1271_ACX_PS_SCHEME_LEGACY;
+		acx->ack_policy = WL1271_ACX_ACK_POLICY_LEGACY;
+
+		ret = wl1271_cmd_configure(wl, ACX_TID_CFG, acx, sizeof(*acx));
+		if (ret < 0) {
+			wl1271_warning("Setting of tid config failed: %d", ret);
+			goto out;
+		}
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_frag_threshold(struct wl1271 *wl)
+{
+	struct acx_frag_threshold *acx;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx frag threshold");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
+	ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("Setting of frag threshold failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_tx_config_options(struct wl1271 *wl)
+{
+	struct acx_tx_config_options *acx;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_ACX, "acx tx config options");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->tx_compl_timeout = WL1271_ACX_TX_COMPL_TIMEOUT;
+	acx->tx_compl_threshold = WL1271_ACX_TX_COMPL_THRESHOLD;
+	ret = wl1271_cmd_configure(wl, ACX_TX_CONFIG_OPT, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("Setting of tx options failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_mem_cfg(struct wl1271 *wl)
+{
+	struct wl1271_acx_config_memory *mem_conf;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
+
+	mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
+	if (!mem_conf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* memory config */
+	mem_conf->num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
+	mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS;
+	mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS;
+	mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES;
+	mem_conf->total_tx_descriptors = ACX_TX_DESCRIPTORS;
+
+	ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
+				   sizeof(*mem_conf));
+	if (ret < 0) {
+		wl1271_warning("wl1271 mem config failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(mem_conf);
+	return ret;
+}
+
+int wl1271_acx_init_mem_config(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_mem_cfg(wl);
+	if (ret < 0)
+		return ret;
+
+	wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map),
+					  GFP_KERNEL);
+	if (!wl->target_mem_map) {
+		wl1271_error("couldn't allocate target memory map");
+		return -ENOMEM;
+	}
+
+	/* we now ask for the firmware built memory map */
+	ret = wl1271_acx_mem_map(wl, (void *)wl->target_mem_map,
+				 sizeof(struct wl1271_acx_mem_map));
+	if (ret < 0) {
+		wl1271_error("couldn't retrieve firmware memory map");
+		kfree(wl->target_mem_map);
+		wl->target_mem_map = NULL;
+		return ret;
+	}
+
+	/* initialize TX block book keeping */
+	wl->tx_blocks_available = wl->target_mem_map->num_tx_mem_blocks;
+	wl1271_debug(DEBUG_TX, "available tx blocks: %d",
+		     wl->tx_blocks_available);
+
+	return 0;
+}
+
+int wl1271_acx_init_rx_interrupt(struct wl1271 *wl)
+{
+	struct wl1271_acx_rx_config_opt *rx_conf;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config");
+
+	rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL);
+	if (!rx_conf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	rx_conf->threshold = WL1271_RX_INTR_THRESHOLD_DEF;
+	rx_conf->timeout = WL1271_RX_INTR_TIMEOUT_DEF;
+	rx_conf->mblk_threshold = USHORT_MAX; /* Disabled */
+	rx_conf->queue_type = RX_QUEUE_TYPE_RX_LOW_PRIORITY;
+
+	ret = wl1271_cmd_configure(wl, ACX_RX_CONFIG_OPT, rx_conf,
+				   sizeof(*rx_conf));
+	if (ret < 0) {
+		wl1271_warning("wl1271 rx config opt failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(rx_conf);
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
new file mode 100644
index 0000000..9068daa
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -0,0 +1,1221 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_ACX_H__
+#define __WL1271_ACX_H__
+
+#include "wl1271.h"
+#include "wl1271_cmd.h"
+
+/*************************************************************************
+
+    Host Interrupt Register (WiLink -> Host)
+
+**************************************************************************/
+/* HW Initiated interrupt Watchdog timer expiration */
+#define WL1271_ACX_INTR_WATCHDOG           BIT(0)
+/* Init sequence is done (masked interrupt, detection through polling only ) */
+#define WL1271_ACX_INTR_INIT_COMPLETE      BIT(1)
+/* Event was entered to Event MBOX #A*/
+#define WL1271_ACX_INTR_EVENT_A            BIT(2)
+/* Event was entered to Event MBOX #B*/
+#define WL1271_ACX_INTR_EVENT_B            BIT(3)
+/* Command processing completion*/
+#define WL1271_ACX_INTR_CMD_COMPLETE       BIT(4)
+/* Signaling the host on HW wakeup */
+#define WL1271_ACX_INTR_HW_AVAILABLE       BIT(5)
+/* The MISC bit is used for aggregation of RX, TxComplete and TX rate update */
+#define WL1271_ACX_INTR_DATA               BIT(6)
+/* Trace meassge on MBOX #A */
+#define WL1271_ACX_INTR_TRACE_A            BIT(7)
+/* Trace meassge on MBOX #B */
+#define WL1271_ACX_INTR_TRACE_B            BIT(8)
+
+#define WL1271_ACX_INTR_ALL		   0xFFFFFFFF
+#define WL1271_ACX_ALL_EVENTS_VECTOR       (WL1271_ACX_INTR_WATCHDOG      | \
+					    WL1271_ACX_INTR_INIT_COMPLETE | \
+					    WL1271_ACX_INTR_EVENT_A       | \
+					    WL1271_ACX_INTR_EVENT_B       | \
+					    WL1271_ACX_INTR_CMD_COMPLETE  | \
+					    WL1271_ACX_INTR_HW_AVAILABLE  | \
+					    WL1271_ACX_INTR_DATA)
+
+#define WL1271_INTR_MASK                   (WL1271_ACX_INTR_EVENT_A |	\
+					    WL1271_ACX_INTR_EVENT_B | \
+					    WL1271_ACX_INTR_DATA)
+
+/* Target's information element */
+struct acx_header {
+	struct wl1271_cmd_header cmd;
+
+	/* acx (or information element) header */
+	u16 id;
+
+	/* payload length (not including headers */
+	u16 len;
+};
+
+struct acx_error_counter {
+	struct acx_header header;
+
+	/* The number of PLCP errors since the last time this */
+	/* information element was interrogated. This field is */
+	/* automatically cleared when it is interrogated.*/
+	u32 PLCP_error;
+
+	/* The number of FCS errors since the last time this */
+	/* information element was interrogated. This field is */
+	/* automatically cleared when it is interrogated.*/
+	u32 FCS_error;
+
+	/* The number of MPDUs without PLCP header errors received*/
+	/* since the last time this information element was interrogated. */
+	/* This field is automatically cleared when it is interrogated.*/
+	u32 valid_frame;
+
+	/* the number of missed sequence numbers in the squentially */
+	/* values of frames seq numbers */
+	u32 seq_num_miss;
+} __attribute__ ((packed));
+
+struct acx_revision {
+	struct acx_header header;
+
+	/*
+	 * The WiLink firmware version, an ASCII string x.x.x.x,
+	 * that uniquely identifies the current firmware.
+	 * The left most digit is incremented each time a
+	 * significant change is made to the firmware, such as
+	 * code redesign or new platform support.
+	 * The second digit is incremented when major enhancements
+	 * are added or major fixes are made.
+	 * The third digit is incremented for each GA release.
+	 * The fourth digit is incremented for each build.
+	 * The first two digits identify a firmware release version,
+	 * in other words, a unique set of features.
+	 * The first three digits identify a GA release.
+	 */
+	char fw_version[20];
+
+	/*
+	 * This 4 byte field specifies the WiLink hardware version.
+	 * bits 0  - 15: Reserved.
+	 * bits 16 - 23: Version ID - The WiLink version ID
+	 *              (1 = first spin, 2 = second spin, and so on).
+	 * bits 24 - 31: Chip ID - The WiLink chip ID.
+	 */
+	u32 hw_version;
+} __attribute__ ((packed));
+
+enum wl1271_psm_mode {
+	/* Active mode */
+	WL1271_PSM_CAM = 0,
+
+	/* Power save mode */
+	WL1271_PSM_PS = 1,
+
+	/* Extreme low power */
+	WL1271_PSM_ELP = 2,
+};
+
+struct acx_sleep_auth {
+	struct acx_header header;
+
+	/* The sleep level authorization of the device. */
+	/* 0 - Always active*/
+	/* 1 - Power down mode: light / fast sleep*/
+	/* 2 - ELP mode: Deep / Max sleep*/
+	u8  sleep_auth;
+	u8  padding[3];
+} __attribute__ ((packed));
+
+enum {
+	HOSTIF_PCI_MASTER_HOST_INDIRECT,
+	HOSTIF_PCI_MASTER_HOST_DIRECT,
+	HOSTIF_SLAVE,
+	HOSTIF_PKT_RING,
+	HOSTIF_DONTCARE = 0xFF
+};
+
+#define DEFAULT_UCAST_PRIORITY          0
+#define DEFAULT_RX_Q_PRIORITY           0
+#define DEFAULT_NUM_STATIONS            1
+#define DEFAULT_RXQ_PRIORITY            0 /* low 0 .. 15 high  */
+#define DEFAULT_RXQ_TYPE                0x07    /* All frames, Data/Ctrl/Mgmt */
+#define TRACE_BUFFER_MAX_SIZE           256
+
+#define  DP_RX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_TX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_RX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_COMPLETE_TIME_OUT 20
+#define  FW_TX_CMPLT_BLOCK_SIZE 16
+
+#define TX_MSDU_LIFETIME_MIN       0
+#define TX_MSDU_LIFETIME_MAX       3000
+#define TX_MSDU_LIFETIME_DEF       512
+#define RX_MSDU_LIFETIME_MIN       0
+#define RX_MSDU_LIFETIME_MAX       0xFFFFFFFF
+#define RX_MSDU_LIFETIME_DEF       512000
+
+struct acx_rx_msdu_lifetime {
+	struct acx_header header;
+
+	/*
+	 * The maximum amount of time, in TU, before the
+	 * firmware discards the MSDU.
+	 */
+	u32 lifetime;
+} __attribute__ ((packed));
+
+/*
+ * RX Config Options Table
+ * Bit		Definition
+ * ===		==========
+ * 31:14		Reserved
+ * 13		Copy RX Status - when set, write three receive status words
+ *		to top of rx'd MPDUs.
+ *		When cleared, do not write three status words (added rev 1.5)
+ * 12		Reserved
+ * 11		RX Complete upon FCS error - when set, give rx complete
+ *		interrupt for FCS errors, after the rx filtering, e.g. unicast
+ *		frames not to us with FCS error will not generate an interrupt.
+ * 10		SSID Filter Enable - When set, the WiLink discards all beacon,
+ *	        probe request, and probe response frames with an SSID that does
+ *		not match the SSID specified by the host in the START/JOIN
+ *		command.
+ *		When clear, the WiLink receives frames with any SSID.
+ * 9		Broadcast Filter Enable - When set, the WiLink discards all
+ *		broadcast frames. When clear, the WiLink receives all received
+ *		broadcast frames.
+ * 8:6		Reserved
+ * 5		BSSID Filter Enable - When set, the WiLink discards any frames
+ *		with a BSSID that does not match the BSSID specified by the
+ *		host.
+ *		When clear, the WiLink receives frames from any BSSID.
+ * 4		MAC Addr Filter - When set, the WiLink discards any frames
+ *		with a destination address that does not match the MAC address
+ *		of the adaptor.
+ *		When clear, the WiLink receives frames destined to any MAC
+ *		address.
+ * 3		Promiscuous - When set, the WiLink receives all valid frames
+ *		(i.e., all frames that pass the FCS check).
+ *		When clear, only frames that pass the other filters specified
+ *		are received.
+ * 2		FCS - When set, the WiLink includes the FCS with the received
+ *		frame.
+ *		When cleared, the FCS is discarded.
+ * 1		PLCP header - When set, write all data from baseband to frame
+ *		buffer including PHY header.
+ * 0		Reserved - Always equal to 0.
+ *
+ * RX Filter Options Table
+ * Bit		Definition
+ * ===		==========
+ * 31:12		Reserved - Always equal to 0.
+ * 11		Association - When set, the WiLink receives all association
+ *		related frames (association request/response, reassocation
+ *		request/response, and disassociation). When clear, these frames
+ *		are discarded.
+ * 10		Auth/De auth - When set, the WiLink receives all authentication
+ *		and de-authentication frames. When clear, these frames are
+ *		discarded.
+ * 9		Beacon - When set, the WiLink receives all beacon frames.
+ *		When clear, these frames are discarded.
+ * 8		Contention Free - When set, the WiLink receives all contention
+ *		free frames.
+ *		When clear, these frames are discarded.
+ * 7		Control - When set, the WiLink receives all control frames.
+ *		When clear, these frames are discarded.
+ * 6		Data - When set, the WiLink receives all data frames.
+ *		When clear, these frames are discarded.
+ * 5		FCS Error - When set, the WiLink receives frames that have FCS
+ *		errors.
+ *		When clear, these frames are discarded.
+ * 4		Management - When set, the WiLink receives all management
+ *		frames.
+ *		When clear, these frames are discarded.
+ * 3		Probe Request - When set, the WiLink receives all probe request
+ *		frames.
+ *		When clear, these frames are discarded.
+ * 2		Probe Response - When set, the WiLink receives all probe
+ *		response frames.
+ *		When clear, these frames are discarded.
+ * 1		RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
+ *		frames.
+ *		When clear, these frames are discarded.
+ * 0		Rsvd Type/Sub Type - When set, the WiLink receives all frames
+ *		that have reserved frame types and sub types as defined by the
+ *		802.11 specification.
+ *		When clear, these frames are discarded.
+ */
+struct acx_rx_config {
+	struct acx_header header;
+
+	u32 config_options;
+	u32 filter_options;
+} __attribute__ ((packed));
+
+struct acx_packet_detection {
+	struct acx_header header;
+
+	u32 threshold;
+} __attribute__ ((packed));
+
+
+enum acx_slot_type {
+	SLOT_TIME_LONG = 0,
+	SLOT_TIME_SHORT = 1,
+	DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
+	MAX_SLOT_TIMES = 0xFF
+};
+
+#define STATION_WONE_INDEX 0
+
+struct acx_slot {
+	struct acx_header header;
+
+	u8 wone_index; /* Reserved */
+	u8 slot_time;
+	u8 reserved[6];
+} __attribute__ ((packed));
+
+
+#define ADDRESS_GROUP_MAX	(8)
+#define ADDRESS_GROUP_MAX_LEN	(ETH_ALEN * ADDRESS_GROUP_MAX)
+
+struct acx_dot11_grp_addr_tbl {
+	struct acx_header header;
+
+	u8 enabled;
+	u8 num_groups;
+	u8 pad[2];
+	u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+} __attribute__ ((packed));
+
+
+#define  RX_TIMEOUT_PS_POLL_MIN    0
+#define  RX_TIMEOUT_PS_POLL_MAX    (200000)
+#define  RX_TIMEOUT_PS_POLL_DEF    (15)
+#define  RX_TIMEOUT_UPSD_MIN       0
+#define  RX_TIMEOUT_UPSD_MAX       (200000)
+#define  RX_TIMEOUT_UPSD_DEF       (15)
+
+struct acx_rx_timeout {
+	struct acx_header header;
+
+	/*
+	 * The longest time the STA will wait to receive
+	 * traffic from the AP after a PS-poll has been
+	 * transmitted.
+	 */
+	u16 ps_poll_timeout;
+
+	/*
+	 * The longest time the STA will wait to receive
+	 * traffic from the AP after a frame has been sent
+	 * from an UPSD enabled queue.
+	 */
+	u16 upsd_timeout;
+} __attribute__ ((packed));
+
+#define RTS_THRESHOLD_MIN              0
+#define RTS_THRESHOLD_MAX              4096
+#define RTS_THRESHOLD_DEF              2347
+
+struct acx_rts_threshold {
+	struct acx_header header;
+
+	u16 threshold;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_beacon_filter_option {
+	struct acx_header header;
+
+	u8 enable;
+
+	/*
+	 * The number of beacons without the unicast TIM
+	 * bit set that the firmware buffers before
+	 * signaling the host about ready frames.
+	 * When set to 0 and the filter is enabled, beacons
+	 * without the unicast TIM bit set are dropped.
+	 */
+	u8 max_num_beacons;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+/*
+ * ACXBeaconFilterEntry (not 221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0				1               IE identifier
+ * 1               1               Treatment bit mask
+ *
+ * ACXBeaconFilterEntry (221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0               1               IE identifier
+ * 1               1               Treatment bit mask
+ * 2               3               OUI
+ * 5               1               Type
+ * 6               2               Version
+ *
+ *
+ * Treatment bit mask - The information element handling:
+ * bit 0 - The information element is compared and transferred
+ * in case of change.
+ * bit 1 - The information element is transferred to the host
+ * with each appearance or disappearance.
+ * Note that both bits can be set at the same time.
+ */
+#define	BEACON_FILTER_TABLE_MAX_IE_NUM		       (32)
+#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
+#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE	       (2)
+#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
+#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
+			    BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
+			   (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
+			    BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
+
+struct acx_beacon_filter_ie_table {
+	struct acx_header header;
+
+	u8 num_ie;
+	u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
+	u8 pad[3];
+} __attribute__ ((packed));
+
+enum {
+	SG_ENABLE = 0,
+	SG_DISABLE,
+	SG_SENSE_NO_ACTIVITY,
+	SG_SENSE_ACTIVE
+};
+
+struct acx_bt_wlan_coex {
+	struct acx_header header;
+
+	/*
+	 * 0 -> PTA enabled
+	 * 1 -> PTA disabled
+	 * 2 -> sense no active mode, i.e.
+	 *      an interrupt is sent upon
+	 *      BT activity.
+	 * 3 -> PTA is switched on in response
+	 *      to the interrupt sending.
+	 */
+	u8 enable;
+	u8 pad[3];
+} __attribute__ ((packed));
+
+#define PTA_ANTENNA_TYPE_DEF		  (0)
+#define PTA_BT_HP_MAXTIME_DEF		  (2000)
+#define PTA_WLAN_HP_MAX_TIME_DEF	  (5000)
+#define PTA_SENSE_DISABLE_TIMER_DEF	  (1350)
+#define PTA_PROTECTIVE_RX_TIME_DEF	  (1500)
+#define PTA_PROTECTIVE_TX_TIME_DEF	  (1500)
+#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
+#define PTA_SIGNALING_TYPE_DEF		  (1)
+#define PTA_AFH_LEVERAGE_ON_DEF		  (0)
+#define PTA_NUMBER_QUIET_CYCLE_DEF	  (0)
+#define PTA_MAX_NUM_CTS_DEF		  (3)
+#define PTA_NUMBER_OF_WLAN_PACKETS_DEF	  (2)
+#define PTA_NUMBER_OF_BT_PACKETS_DEF	  (2)
+#define PTA_PROTECTIVE_RX_TIME_FAST_DEF	  (1500)
+#define PTA_PROTECTIVE_TX_TIME_FAST_DEF	  (3000)
+#define PTA_CYCLE_TIME_FAST_DEF		  (8700)
+#define PTA_RX_FOR_AVALANCHE_DEF	  (5)
+#define PTA_ELP_HP_DEF			  (0)
+#define PTA_ANTI_STARVE_PERIOD_DEF	  (500)
+#define PTA_ANTI_STARVE_NUM_CYCLE_DEF	  (4)
+#define PTA_ALLOW_PA_SD_DEF		  (1)
+#define PTA_TIME_BEFORE_BEACON_DEF	  (6300)
+#define PTA_HPDM_MAX_TIME_DEF		  (1600)
+#define PTA_TIME_OUT_NEXT_WLAN_DEF	  (2550)
+#define PTA_AUTO_MODE_NO_CTS_DEF	  (0)
+#define PTA_BT_HP_RESPECTED_DEF		  (3)
+#define PTA_WLAN_RX_MIN_RATE_DEF	  (24)
+#define PTA_ACK_MODE_DEF		  (1)
+
+struct acx_bt_wlan_coex_param {
+	struct acx_header header;
+
+	/*
+	 * The minimum rate of a received WLAN packet in the STA,
+	 * during protective mode, of which a new BT-HP request
+	 * during this Rx will always be respected and gain the antenna.
+	 */
+	u32 min_rate;
+
+	/* Max time the BT HP will be respected. */
+	u16 bt_hp_max_time;
+
+	/* Max time the WLAN HP will be respected. */
+	u16 wlan_hp_max_time;
+
+	/*
+	 * The time between the last BT activity
+	 * and the moment when the sense mode returns
+	 * to SENSE_INACTIVE.
+	 */
+	u16 sense_disable_timer;
+
+	/* Time before the next BT HP instance */
+	u16 rx_time_bt_hp;
+	u16 tx_time_bt_hp;
+
+	/* range: 10-20000    default: 1500 */
+	u16 rx_time_bt_hp_fast;
+	u16 tx_time_bt_hp_fast;
+
+	/* range: 2000-65535  default: 8700 */
+	u16 wlan_cycle_fast;
+
+	/* range: 0 - 15000 (Msec) default: 1000 */
+	u16 bt_anti_starvation_period;
+
+	/* range 400-10000(Usec) default: 3000 */
+	u16 next_bt_lp_packet;
+
+	/* Deafult: worst case for BT DH5 traffic */
+	u16 wake_up_beacon;
+
+	/* range: 0-50000(Usec) default: 1050 */
+	u16 hp_dm_max_guard_time;
+
+	/*
+	 * This is to prevent both BT & WLAN antenna
+	 * starvation.
+	 * Range: 100-50000(Usec) default:2550
+	 */
+	u16 next_wlan_packet;
+
+	/* 0 -> shared antenna */
+	u8 antenna_type;
+
+	/*
+	 * 0 -> TI legacy
+	 * 1 -> Palau
+	 */
+	u8 signal_type;
+
+	/*
+	 * BT AFH status
+	 * 0 -> no AFH
+	 * 1 -> from dedicated GPIO
+	 * 2 -> AFH on (from host)
+	 */
+	u8 afh_leverage_on;
+
+	/*
+	 * The number of cycles during which no
+	 * TX will be sent after 1 cycle of RX
+	 * transaction in protective mode
+	 */
+	u8 quiet_cycle_num;
+
+	/*
+	 * The maximum number of CTSs that will
+	 * be sent for receiving RX packet in
+	 * protective mode
+	 */
+	u8 max_cts;
+
+	/*
+	 * The number of WLAN packets
+	 * transferred in common mode before
+	 * switching to BT.
+	 */
+	u8 wlan_packets_num;
+
+	/*
+	 * The number of BT packets
+	 * transferred in common mode before
+	 * switching to WLAN.
+	 */
+	u8 bt_packets_num;
+
+	/* range: 1-255  default: 5 */
+	u8 missed_rx_avalanche;
+
+	/* range: 0-1    default: 1 */
+	u8 wlan_elp_hp;
+
+	/* range: 0 - 15  default: 4 */
+	u8 bt_anti_starvation_cycles;
+
+	u8 ack_mode_dual_ant;
+
+	/*
+	 * Allow PA_SD assertion/de-assertion
+	 * during enabled BT activity.
+	 */
+	u8 pa_sd_enable;
+
+	/*
+	 * Enable/Disable PTA in auto mode:
+	 * Support Both Active & P.S modes
+	 */
+	u8 pta_auto_mode_enable;
+
+	/* range: 0 - 20  default: 1 */
+	u8 bt_hp_respected_num;
+} __attribute__ ((packed));
+
+#define CCA_THRSH_ENABLE_ENERGY_D       0x140A
+#define CCA_THRSH_DISABLE_ENERGY_D      0xFFEF
+
+struct acx_energy_detection {
+	struct acx_header header;
+
+	/* The RX Clear Channel Assessment threshold in the PHY */
+	u16 rx_cca_threshold;
+	u8 tx_energy_detection;
+	u8 pad;
+} __attribute__ ((packed));
+
+#define BCN_RX_TIMEOUT_DEF_VALUE        10000
+#define BROADCAST_RX_TIMEOUT_DEF_VALUE  20000
+#define RX_BROADCAST_IN_PS_DEF_VALUE    1
+#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
+
+struct acx_beacon_broadcast {
+	struct acx_header header;
+
+	u16 beacon_rx_timeout;
+	u16 broadcast_timeout;
+
+	/* Enables receiving of broadcast packets in PS mode */
+	u8 rx_broadcast_in_ps;
+
+	/* Consecutive PS Poll failures before updating the host */
+	u8 ps_poll_threshold;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_event_mask {
+	struct acx_header header;
+
+	u32 event_mask;
+	u32 high_event_mask; /* Unused */
+} __attribute__ ((packed));
+
+#define CFG_RX_FCS		BIT(2)
+#define CFG_RX_ALL_GOOD		BIT(3)
+#define CFG_UNI_FILTER_EN	BIT(4)
+#define CFG_BSSID_FILTER_EN	BIT(5)
+#define CFG_MC_FILTER_EN	BIT(6)
+#define CFG_MC_ADDR0_EN		BIT(7)
+#define CFG_MC_ADDR1_EN		BIT(8)
+#define CFG_BC_REJECT_EN	BIT(9)
+#define CFG_SSID_FILTER_EN	BIT(10)
+#define CFG_RX_INT_FCS_ERROR	BIT(11)
+#define CFG_RX_INT_ENCRYPTED	BIT(12)
+#define CFG_RX_WR_RX_STATUS	BIT(13)
+#define CFG_RX_FILTER_NULTI	BIT(14)
+#define CFG_RX_RESERVE		BIT(15)
+#define CFG_RX_TIMESTAMP_TSF	BIT(16)
+
+#define CFG_RX_RSV_EN		BIT(0)
+#define CFG_RX_RCTS_ACK		BIT(1)
+#define CFG_RX_PRSP_EN		BIT(2)
+#define CFG_RX_PREQ_EN		BIT(3)
+#define CFG_RX_MGMT_EN		BIT(4)
+#define CFG_RX_FCS_ERROR	BIT(5)
+#define CFG_RX_DATA_EN		BIT(6)
+#define CFG_RX_CTL_EN		BIT(7)
+#define CFG_RX_CF_EN		BIT(8)
+#define CFG_RX_BCN_EN		BIT(9)
+#define CFG_RX_AUTH_EN		BIT(10)
+#define CFG_RX_ASSOC_EN		BIT(11)
+
+#define SCAN_PASSIVE		BIT(0)
+#define SCAN_5GHZ_BAND		BIT(1)
+#define SCAN_TRIGGERED		BIT(2)
+#define SCAN_PRIORITY_HIGH	BIT(3)
+
+struct acx_feature_config {
+	struct acx_header header;
+
+	u32 options;
+	u32 data_flow_options;
+} __attribute__ ((packed));
+
+struct acx_current_tx_power {
+	struct acx_header header;
+
+	u8  current_tx_power;
+	u8  padding[3];
+} __attribute__ ((packed));
+
+enum acx_wake_up_event {
+	WAKE_UP_EVENT_BEACON_BITMAP	= 0x01, /* Wake on every Beacon*/
+	WAKE_UP_EVENT_DTIM_BITMAP	= 0x02,	/* Wake on every DTIM*/
+	WAKE_UP_EVENT_N_DTIM_BITMAP	= 0x04, /* Wake on every Nth DTIM */
+	WAKE_UP_EVENT_N_BEACONS_BITMAP	= 0x08, /* Wake on every Nth Beacon */
+	WAKE_UP_EVENT_BITS_MASK		= 0x0F
+};
+
+struct acx_wake_up_condition {
+	struct acx_header header;
+
+	u8 wake_up_event; /* Only one bit can be set */
+	u8 listen_interval;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_aid {
+	struct acx_header header;
+
+	/*
+	 * To be set when associated with an AP.
+	 */
+	u16 aid;
+	u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_preamble_type {
+	ACX_PREAMBLE_LONG = 0,
+	ACX_PREAMBLE_SHORT = 1
+};
+
+struct acx_preamble {
+	struct acx_header header;
+
+	/*
+	 * When set, the WiLink transmits the frames with a short preamble and
+	 * when cleared, the WiLink transmits the frames with a long preamble.
+	 */
+	u8 preamble;
+	u8 padding[3];
+} __attribute__ ((packed));
+
+enum acx_ctsprotect_type {
+	CTSPROTECT_DISABLE = 0,
+	CTSPROTECT_ENABLE = 1
+};
+
+struct acx_ctsprotect {
+	struct acx_header header;
+	u8 ctsprotect;
+	u8 padding[3];
+} __attribute__ ((packed));
+
+struct acx_tx_statistics {
+	u32 internal_desc_overflow;
+}  __attribute__ ((packed));
+
+struct acx_rx_statistics {
+	u32 out_of_mem;
+	u32 hdr_overflow;
+	u32 hw_stuck;
+	u32 dropped;
+	u32 fcs_err;
+	u32 xfr_hint_trig;
+	u32 path_reset;
+	u32 reset_counter;
+} __attribute__ ((packed));
+
+struct acx_dma_statistics {
+	u32 rx_requested;
+	u32 rx_errors;
+	u32 tx_requested;
+	u32 tx_errors;
+}  __attribute__ ((packed));
+
+struct acx_isr_statistics {
+	/* host command complete */
+	u32 cmd_cmplt;
+
+	/* fiqisr() */
+	u32 fiqs;
+
+	/* (INT_STS_ND & INT_TRIG_RX_HEADER) */
+	u32 rx_headers;
+
+	/* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
+	u32 rx_completes;
+
+	/* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
+	u32 rx_mem_overflow;
+
+	/* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
+	u32 rx_rdys;
+
+	/* irqisr() */
+	u32 irqs;
+
+	/* (INT_STS_ND & INT_TRIG_TX_PROC) */
+	u32 tx_procs;
+
+	/* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
+	u32 decrypt_done;
+
+	/* (INT_STS_ND & INT_TRIG_DMA0) */
+	u32 dma0_done;
+
+	/* (INT_STS_ND & INT_TRIG_DMA1) */
+	u32 dma1_done;
+
+	/* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
+	u32 tx_exch_complete;
+
+	/* (INT_STS_ND & INT_TRIG_COMMAND) */
+	u32 commands;
+
+	/* (INT_STS_ND & INT_TRIG_RX_PROC) */
+	u32 rx_procs;
+
+	/* (INT_STS_ND & INT_TRIG_PM_802) */
+	u32 hw_pm_mode_changes;
+
+	/* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
+	u32 host_acknowledges;
+
+	/* (INT_STS_ND & INT_TRIG_PM_PCI) */
+	u32 pci_pm;
+
+	/* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
+	u32 wakeups;
+
+	/* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
+	u32 low_rssi;
+} __attribute__ ((packed));
+
+struct acx_wep_statistics {
+	/* WEP address keys configured */
+	u32 addr_key_count;
+
+	/* default keys configured */
+	u32 default_key_count;
+
+	u32 reserved;
+
+	/* number of times that WEP key not found on lookup */
+	u32 key_not_found;
+
+	/* number of times that WEP key decryption failed */
+	u32 decrypt_fail;
+
+	/* WEP packets decrypted */
+	u32 packets;
+
+	/* WEP decrypt interrupts */
+	u32 interrupt;
+} __attribute__ ((packed));
+
+#define ACX_MISSED_BEACONS_SPREAD 10
+
+struct acx_pwr_statistics {
+	/* the amount of enters into power save mode (both PD & ELP) */
+	u32 ps_enter;
+
+	/* the amount of enters into ELP mode */
+	u32 elp_enter;
+
+	/* the amount of missing beacon interrupts to the host */
+	u32 missing_bcns;
+
+	/* the amount of wake on host-access times */
+	u32 wake_on_host;
+
+	/* the amount of wake on timer-expire */
+	u32 wake_on_timer_exp;
+
+	/* the number of packets that were transmitted with PS bit set */
+	u32 tx_with_ps;
+
+	/* the number of packets that were transmitted with PS bit clear */
+	u32 tx_without_ps;
+
+	/* the number of received beacons */
+	u32 rcvd_beacons;
+
+	/* the number of entering into PowerOn (power save off) */
+	u32 power_save_off;
+
+	/* the number of entries into power save mode */
+	u16 enable_ps;
+
+	/*
+	 * the number of exits from power save, not including failed PS
+	 * transitions
+	 */
+	u16 disable_ps;
+
+	/*
+	 * the number of times the TSF counter was adjusted because
+	 * of drift
+	 */
+	u32 fix_tsf_ps;
+
+	/* Gives statistics about the spread continuous missed beacons.
+	 * The 16 LSB are dedicated for the PS mode.
+	 * The 16 MSB are dedicated for the PS mode.
+	 * cont_miss_bcns_spread[0] - single missed beacon.
+	 * cont_miss_bcns_spread[1] - two continuous missed beacons.
+	 * cont_miss_bcns_spread[2] - three continuous missed beacons.
+	 * ...
+	 * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
+	*/
+	u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
+
+	/* the number of beacons in awake mode */
+	u32 rcvd_awake_beacons;
+} __attribute__ ((packed));
+
+struct acx_mic_statistics {
+	u32 rx_pkts;
+	u32 calc_failure;
+} __attribute__ ((packed));
+
+struct acx_aes_statistics {
+	u32 encrypt_fail;
+	u32 decrypt_fail;
+	u32 encrypt_packets;
+	u32 decrypt_packets;
+	u32 encrypt_interrupt;
+	u32 decrypt_interrupt;
+} __attribute__ ((packed));
+
+struct acx_event_statistics {
+	u32 heart_beat;
+	u32 calibration;
+	u32 rx_mismatch;
+	u32 rx_mem_empty;
+	u32 rx_pool;
+	u32 oom_late;
+	u32 phy_transmit_error;
+	u32 tx_stuck;
+} __attribute__ ((packed));
+
+struct acx_ps_statistics {
+	u32 pspoll_timeouts;
+	u32 upsd_timeouts;
+	u32 upsd_max_sptime;
+	u32 upsd_max_apturn;
+	u32 pspoll_max_apturn;
+	u32 pspoll_utilization;
+	u32 upsd_utilization;
+} __attribute__ ((packed));
+
+struct acx_rxpipe_statistics {
+	u32 rx_prep_beacon_drop;
+	u32 descr_host_int_trig_rx_data;
+	u32 beacon_buffer_thres_host_int_trig_rx_data;
+	u32 missed_beacon_host_int_trig_rx_data;
+	u32 tx_xfr_host_int_trig_rx_data;
+} __attribute__ ((packed));
+
+struct acx_statistics {
+	struct acx_header header;
+
+	struct acx_tx_statistics tx;
+	struct acx_rx_statistics rx;
+	struct acx_dma_statistics dma;
+	struct acx_isr_statistics isr;
+	struct acx_wep_statistics wep;
+	struct acx_pwr_statistics pwr;
+	struct acx_aes_statistics aes;
+	struct acx_mic_statistics mic;
+	struct acx_event_statistics event;
+	struct acx_ps_statistics ps;
+	struct acx_rxpipe_statistics rxpipe;
+} __attribute__ ((packed));
+
+#define ACX_MAX_RATE_CLASSES       8
+#define ACX_RATE_MASK_UNSPECIFIED  0
+#define ACX_RATE_MASK_ALL          0x1eff
+#define ACX_RATE_RETRY_LIMIT       10
+
+struct acx_rate_class {
+	u32 enabled_rates;
+	u8 short_retry_limit;
+	u8 long_retry_limit;
+	u8 aflags;
+	u8 reserved;
+};
+
+struct acx_rate_policy {
+	struct acx_header header;
+
+	u32 rate_class_cnt;
+	struct acx_rate_class rate_class[ACX_MAX_RATE_CLASSES];
+} __attribute__ ((packed));
+
+#define WL1271_ACX_AC_COUNT 4
+
+struct acx_ac_cfg {
+	struct acx_header header;
+	u8 ac;
+	u8 cw_min;
+	u16 cw_max;
+	u8 aifsn;
+	u8 reserved;
+	u16 tx_op_limit;
+} __attribute__ ((packed));
+
+enum wl1271_acx_ac {
+	WL1271_ACX_AC_BE = 0,
+	WL1271_ACX_AC_BK = 1,
+	WL1271_ACX_AC_VI = 2,
+	WL1271_ACX_AC_VO = 3,
+	WL1271_ACX_AC_CTS2SELF = 4,
+	WL1271_ACX_AC_ANY_TID = 0x1F,
+	WL1271_ACX_AC_INVALID = 0xFF,
+};
+
+enum wl1271_acx_ps_scheme {
+	WL1271_ACX_PS_SCHEME_LEGACY = 0,
+	WL1271_ACX_PS_SCHEME_UPSD_TRIGGER = 1,
+	WL1271_ACX_PS_SCHEME_LEGACY_PSPOLL = 2,
+	WL1271_ACX_PS_SCHEME_SAPSD = 3,
+};
+
+enum wl1271_acx_ack_policy {
+	WL1271_ACX_ACK_POLICY_LEGACY = 0,
+	WL1271_ACX_ACK_POLICY_NO_ACK = 1,
+	WL1271_ACX_ACK_POLICY_BLOCK = 2,
+};
+
+#define WL1271_ACX_TID_COUNT 7
+
+struct acx_tid_config {
+	struct acx_header header;
+	u8 queue_id;
+	u8 channel_type;
+	u8 tsid;
+	u8 ps_scheme;
+	u8 ack_policy;
+	u8 padding[3];
+	u32 apsd_conf[2];
+} __attribute__ ((packed));
+
+struct acx_frag_threshold {
+	struct acx_header header;
+	u16 frag_threshold;
+	u8 padding[2];
+} __attribute__ ((packed));
+
+#define WL1271_ACX_TX_COMPL_TIMEOUT   5
+#define WL1271_ACX_TX_COMPL_THRESHOLD 5
+
+struct acx_tx_config_options {
+	struct acx_header header;
+	u16 tx_compl_timeout;     /* msec */
+	u16 tx_compl_threshold;   /* number of packets */
+} __attribute__ ((packed));
+
+#define ACX_RX_MEM_BLOCKS     64
+#define ACX_TX_MIN_MEM_BLOCKS 64
+#define ACX_TX_DESCRIPTORS    32
+#define ACX_NUM_SSID_PROFILES 1
+
+struct wl1271_acx_config_memory {
+	struct acx_header header;
+
+	u8 rx_mem_block_num;
+	u8 tx_min_mem_block_num;
+	u8 num_stations;
+	u8 num_ssid_profiles;
+	u32 total_tx_descriptors;
+} __attribute__ ((packed));
+
+struct wl1271_acx_mem_map {
+	struct acx_header header;
+
+	void *code_start;
+	void *code_end;
+
+	void *wep_defkey_start;
+	void *wep_defkey_end;
+
+	void *sta_table_start;
+	void *sta_table_end;
+
+	void *packet_template_start;
+	void *packet_template_end;
+
+	/* Address of the TX result interface (control block) */
+	u32 tx_result;
+	u32 tx_result_queue_start;
+
+	void *queue_memory_start;
+	void *queue_memory_end;
+
+	u32 packet_memory_pool_start;
+	u32 packet_memory_pool_end;
+
+	void *debug_buffer1_start;
+	void *debug_buffer1_end;
+
+	void *debug_buffer2_start;
+	void *debug_buffer2_end;
+
+	/* Number of blocks FW allocated for TX packets */
+	u32 num_tx_mem_blocks;
+
+	/* Number of blocks FW allocated for RX packets */
+	u32 num_rx_mem_blocks;
+
+	/* the following 4 fields are valid in SLAVE mode only */
+	u8 *tx_cbuf;
+	u8 *rx_cbuf;
+	void *rx_ctrl;
+	void *tx_ctrl;
+} __attribute__ ((packed));
+
+enum wl1271_acx_rx_queue_type {
+	RX_QUEUE_TYPE_RX_LOW_PRIORITY,    /* All except the high priority */
+	RX_QUEUE_TYPE_RX_HIGH_PRIORITY,   /* Management and voice packets */
+	RX_QUEUE_TYPE_NUM,
+	RX_QUEUE_TYPE_MAX = USHORT_MAX
+};
+
+#define WL1271_RX_INTR_THRESHOLD_DEF  0       /* no pacing, send interrupt on
+					       * every event */
+#define WL1271_RX_INTR_THRESHOLD_MIN  0
+#define WL1271_RX_INTR_THRESHOLD_MAX  15
+
+#define WL1271_RX_INTR_TIMEOUT_DEF    5
+#define WL1271_RX_INTR_TIMEOUT_MIN    1
+#define WL1271_RX_INTR_TIMEOUT_MAX    100
+
+struct wl1271_acx_rx_config_opt {
+	struct acx_header header;
+
+	u16 mblk_threshold;
+	u16 threshold;
+	u16 timeout;
+	u8 queue_type;
+	u8 reserved;
+} __attribute__ ((packed));
+
+enum {
+	ACX_WAKE_UP_CONDITIONS      = 0x0002,
+	ACX_MEM_CFG                 = 0x0003,
+	ACX_SLOT                    = 0x0004,
+	ACX_AC_CFG                  = 0x0007,
+	ACX_MEM_MAP                 = 0x0008,
+	ACX_AID                     = 0x000A,
+	/* ACX_FW_REV is missing in the ref driver, but seems to work */
+	ACX_FW_REV                  = 0x000D,
+	ACX_MEDIUM_USAGE            = 0x000F,
+	ACX_RX_CFG                  = 0x0010,
+	ACX_TX_QUEUE_CFG            = 0x0011, /* FIXME: only used by wl1251 */
+	ACX_STATISTICS              = 0x0013, /* Debug API */
+	ACX_PWR_CONSUMPTION_STATISTICS = 0x0014,
+	ACX_FEATURE_CFG             = 0x0015,
+	ACX_TID_CFG                 = 0x001A,
+	ACX_PS_RX_STREAMING         = 0x001B,
+	ACX_BEACON_FILTER_OPT       = 0x001F,
+	ACX_NOISE_HIST              = 0x0021,
+	ACX_HDK_VERSION             = 0x0022, /* ??? */
+	ACX_PD_THRESHOLD            = 0x0023,
+	ACX_TX_CONFIG_OPT           = 0x0024,
+	ACX_CCA_THRESHOLD           = 0x0025,
+	ACX_EVENT_MBOX_MASK         = 0x0026,
+	ACX_CONN_MONIT_PARAMS       = 0x002D,
+	ACX_CONS_TX_FAILURE         = 0x002F,
+	ACX_BCN_DTIM_OPTIONS        = 0x0031,
+	ACX_SG_ENABLE               = 0x0032,
+	ACX_SG_CFG                  = 0x0033,
+	ACX_BEACON_FILTER_TABLE     = 0x0038,
+	ACX_ARP_IP_FILTER           = 0x0039,
+	ACX_ROAMING_STATISTICS_TBL  = 0x003B,
+	ACX_RATE_POLICY             = 0x003D,
+	ACX_CTS_PROTECTION          = 0x003E,
+	ACX_SLEEP_AUTH              = 0x003F,
+	ACX_PREAMBLE_TYPE	    = 0x0040,
+	ACX_ERROR_CNT               = 0x0041,
+	ACX_IBSS_FILTER		    = 0x0044,
+	ACX_SERVICE_PERIOD_TIMEOUT  = 0x0045,
+	ACX_TSF_INFO                = 0x0046,
+	ACX_CONFIG_PS_WMM           = 0x0049,
+	ACX_ENABLE_RX_DATA_FILTER   = 0x004A,
+	ACX_SET_RX_DATA_FILTER      = 0x004B,
+	ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
+	ACX_RX_CONFIG_OPT           = 0x004E,
+	ACX_FRAG_CFG                = 0x004F,
+	ACX_BET_ENABLE              = 0x0050,
+	ACX_RSSI_SNR_TRIGGER        = 0x0051,
+	ACX_RSSI_SNR_WEIGHTS        = 0x0051,
+	ACX_KEEP_ALIVE_MODE         = 0x0052,
+	ACX_SET_KEEP_ALIVE_CONFIG   = 0x0054,
+	ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
+	ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
+	ACX_PEER_HT_CAP             = 0x0057,
+	ACX_HT_BSS_OPERATION        = 0x0058,
+	ACX_COEX_ACTIVITY           = 0x0059,
+	DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
+	DOT11_CUR_TX_PWR            = 0x100D,
+	DOT11_RX_DOT11_MODE         = 0x1012,
+	DOT11_RTS_THRESHOLD         = 0x1013,
+	DOT11_GROUP_ADDRESS_TBL     = 0x1014,
+
+	MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
+
+	MAX_IE = 0xFFFF
+};
+
+
+int wl1271_acx_wake_up_conditions(struct wl1271 *wl, u8 wake_up_event,
+				  u8 listen_interval);
+int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth);
+int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len);
+int wl1271_acx_tx_power(struct wl1271 *wl, int power);
+int wl1271_acx_feature_cfg(struct wl1271 *wl);
+int wl1271_acx_mem_map(struct wl1271 *wl,
+		       struct acx_header *mem_map, size_t len);
+int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl, u32 life_time);
+int wl1271_acx_rx_config(struct wl1271 *wl, u32 config, u32 filter);
+int wl1271_acx_pd_threshold(struct wl1271 *wl);
+int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time);
+int wl1271_acx_group_address_tbl(struct wl1271 *wl);
+int wl1271_acx_service_period_timeout(struct wl1271 *wl);
+int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
+int wl1271_acx_beacon_filter_opt(struct wl1271 *wl);
+int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
+int wl1271_acx_sg_enable(struct wl1271 *wl);
+int wl1271_acx_sg_cfg(struct wl1271 *wl);
+int wl1271_acx_cca_threshold(struct wl1271 *wl);
+int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
+int wl1271_acx_aid(struct wl1271 *wl, u16 aid);
+int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask);
+int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
+int wl1271_acx_cts_protect(struct wl1271 *wl,
+			    enum acx_ctsprotect_type ctsprotect);
+int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
+int wl1271_acx_rate_policies(struct wl1271 *wl);
+int wl1271_acx_ac_cfg(struct wl1271 *wl);
+int wl1271_acx_tid_cfg(struct wl1271 *wl);
+int wl1271_acx_frag_threshold(struct wl1271 *wl);
+int wl1271_acx_tx_config_options(struct wl1271 *wl);
+int wl1271_acx_mem_cfg(struct wl1271 *wl);
+int wl1271_acx_init_mem_config(struct wl1271 *wl);
+int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
+
+#endif /* __WL1271_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
new file mode 100644
index 0000000..8228ef4
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -0,0 +1,541 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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/gpio.h>
+
+#include "wl1271_acx.h"
+#include "wl1271_reg.h"
+#include "wl1271_boot.h"
+#include "wl1271_spi.h"
+#include "wl1271_event.h"
+
+static struct wl1271_partition_set part_table[PART_TABLE_LEN] = {
+	[PART_DOWN] = {
+		.mem = {
+			.start = 0x00000000,
+			.size  = 0x000177c0
+		},
+		.reg = {
+			.start = REGISTERS_BASE,
+			.size  = 0x00008800
+		},
+	},
+
+	[PART_WORK] = {
+		.mem = {
+			.start = 0x00040000,
+			.size  = 0x00014fc0
+		},
+		.reg = {
+			.start = REGISTERS_BASE,
+			.size  = 0x0000b000
+		},
+	},
+
+	[PART_DRPW] = {
+		.mem = {
+			.start = 0x00040000,
+			.size  = 0x00014fc0
+		},
+		.reg = {
+			.start = DRPW_BASE,
+			.size  = 0x00006000
+		}
+	}
+};
+
+static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
+{
+	u32 cpu_ctrl;
+
+	/* 10.5.0 run the firmware (I) */
+	cpu_ctrl = wl1271_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+	/* 10.5.1 run the firmware (II) */
+	cpu_ctrl |= flag;
+	wl1271_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+}
+
+static void wl1271_boot_fw_version(struct wl1271 *wl)
+{
+	struct wl1271_static_data static_data;
+
+	wl1271_spi_mem_read(wl, wl->cmd_box_addr,
+			    &static_data, sizeof(static_data));
+
+	strncpy(wl->chip.fw_ver, static_data.fw_version,
+		sizeof(wl->chip.fw_ver));
+
+	/* make sure the string is NULL-terminated */
+	wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0';
+}
+
+static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
+					     size_t fw_data_len, u32 dest)
+{
+	int addr, chunk_num, partition_limit;
+	u8 *p;
+
+	/* whal_FwCtrl_LoadFwImageSm() */
+
+	wl1271_debug(DEBUG_BOOT, "starting firmware upload");
+
+	wl1271_debug(DEBUG_BOOT, "fw_data_len %zd chunk_size %d",
+		     fw_data_len, CHUNK_SIZE);
+
+
+	if ((fw_data_len % 4) != 0) {
+		wl1271_error("firmware length not multiple of four");
+		return -EIO;
+	}
+
+	wl1271_set_partition(wl, dest,
+			     part_table[PART_DOWN].mem.size,
+			     part_table[PART_DOWN].reg.start,
+			     part_table[PART_DOWN].reg.size);
+
+	/* 10.1 set partition limit and chunk num */
+	chunk_num = 0;
+	partition_limit = part_table[PART_DOWN].mem.size;
+
+	while (chunk_num < fw_data_len / CHUNK_SIZE) {
+		/* 10.2 update partition, if needed */
+		addr = dest + (chunk_num + 2) * CHUNK_SIZE;
+		if (addr > partition_limit) {
+			addr = dest + chunk_num * CHUNK_SIZE;
+			partition_limit = chunk_num * CHUNK_SIZE +
+				part_table[PART_DOWN].mem.size;
+
+			/* FIXME: Over 80 chars! */
+			wl1271_set_partition(wl,
+					     addr,
+					     part_table[PART_DOWN].mem.size,
+					     part_table[PART_DOWN].reg.start,
+					     part_table[PART_DOWN].reg.size);
+		}
+
+		/* 10.3 upload the chunk */
+		addr = dest + chunk_num * CHUNK_SIZE;
+		p = buf + chunk_num * CHUNK_SIZE;
+		wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
+			     p, addr);
+		wl1271_spi_mem_write(wl, addr, p, CHUNK_SIZE);
+
+		chunk_num++;
+	}
+
+	/* 10.4 upload the last chunk */
+	addr = dest + chunk_num * CHUNK_SIZE;
+	p = buf + chunk_num * CHUNK_SIZE;
+	wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x",
+		     fw_data_len % CHUNK_SIZE, p, addr);
+	wl1271_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+
+	return 0;
+}
+
+static int wl1271_boot_upload_firmware(struct wl1271 *wl)
+{
+	u32 chunks, addr, len;
+	u8 *fw;
+
+	fw = wl->fw;
+	chunks = be32_to_cpup((u32 *) fw);
+	fw += sizeof(u32);
+
+	wl1271_debug(DEBUG_BOOT, "firmware chunks to be uploaded: %u", chunks);
+
+	while (chunks--) {
+		addr = be32_to_cpup((u32 *) fw);
+		fw += sizeof(u32);
+		len = be32_to_cpup((u32 *) fw);
+		fw += sizeof(u32);
+
+		if (len > 300000) {
+			wl1271_info("firmware chunk too long: %u", len);
+			return -EINVAL;
+		}
+		wl1271_debug(DEBUG_BOOT, "chunk %d addr 0x%x len %u",
+			     chunks, addr, len);
+		wl1271_boot_upload_firmware_chunk(wl, fw, len, addr);
+		fw += len;
+	}
+
+	return 0;
+}
+
+static int wl1271_boot_upload_nvs(struct wl1271 *wl)
+{
+	size_t nvs_len, burst_len;
+	int i;
+	u32 dest_addr, val;
+	u8 *nvs_ptr, *nvs, *nvs_aligned;
+
+	nvs = wl->nvs;
+	if (nvs == NULL)
+		return -ENODEV;
+
+	nvs_ptr = nvs;
+
+	nvs_len = wl->nvs_len;
+
+	/* Update the device MAC address into the nvs */
+	nvs[11] = wl->mac_addr[0];
+	nvs[10] = wl->mac_addr[1];
+	nvs[6] = wl->mac_addr[2];
+	nvs[5] = wl->mac_addr[3];
+	nvs[4] = wl->mac_addr[4];
+	nvs[3] = wl->mac_addr[5];
+
+	/*
+	 * Layout before the actual NVS tables:
+	 * 1 byte : burst length.
+	 * 2 bytes: destination address.
+	 * n bytes: data to burst copy.
+	 *
+	 * This is ended by a 0 length, then the NVS tables.
+	 */
+
+	/* FIXME: Do we need to check here whether the LSB is 1? */
+	while (nvs_ptr[0]) {
+		burst_len = nvs_ptr[0];
+		dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
+
+		/* FIXME: Due to our new wl1271_translate_reg_addr function,
+		   we need to add the REGISTER_BASE to the destination */
+		dest_addr += REGISTERS_BASE;
+
+		/* We move our pointer to the data */
+		nvs_ptr += 3;
+
+		for (i = 0; i < burst_len; i++) {
+			val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+			       | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+			wl1271_debug(DEBUG_BOOT,
+				     "nvs burst write 0x%x: 0x%x",
+				     dest_addr, val);
+			wl1271_reg_write32(wl, dest_addr, val);
+
+			nvs_ptr += 4;
+			dest_addr += 4;
+		}
+	}
+
+	/*
+	 * We've reached the first zero length, the first NVS table
+	 * is 7 bytes further.
+	 */
+	nvs_ptr += 7;
+	nvs_len -= nvs_ptr - nvs;
+	nvs_len = ALIGN(nvs_len, 4);
+
+	/* FIXME: The driver sets the partition here, but this is not needed,
+	   since it sets to the same one as currently in use */
+	/* Now we must set the partition correctly */
+	wl1271_set_partition(wl,
+			     part_table[PART_WORK].mem.start,
+			     part_table[PART_WORK].mem.size,
+			     part_table[PART_WORK].reg.start,
+			     part_table[PART_WORK].reg.size);
+
+	/* Copy the NVS tables to a new block to ensure alignment */
+	nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
+
+	/* And finally we upload the NVS tables */
+	/* FIXME: In wl1271, we upload everything at once.
+	   No endianness handling needed here?! The ref driver doesn't do
+	   anything about it at this point */
+	wl1271_spi_mem_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len);
+
+	kfree(nvs_aligned);
+	return 0;
+}
+
+static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
+{
+	enable_irq(wl->irq);
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+			   WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
+	wl1271_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+}
+
+static int wl1271_boot_soft_reset(struct wl1271 *wl)
+{
+	unsigned long timeout;
+	u32 boot_data;
+
+	/* perform soft reset */
+	wl1271_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
+
+	/* SOFT_RESET is self clearing */
+	timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
+	while (1) {
+		boot_data = wl1271_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
+		wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
+		if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
+			break;
+
+		if (time_after(jiffies, timeout)) {
+			/* 1.2 check pWhalBus->uSelfClearTime if the
+			 * timeout was reached */
+			wl1271_error("soft reset timeout");
+			return -1;
+		}
+
+		udelay(SOFT_RESET_STALL_TIME);
+	}
+
+	/* disable Rx/Tx */
+	wl1271_reg_write32(wl, ENABLE, 0x0);
+
+	/* disable auto calibration on start*/
+	wl1271_reg_write32(wl, SPARE_A2, 0xffff);
+
+	return 0;
+}
+
+static int wl1271_boot_run_firmware(struct wl1271 *wl)
+{
+	int loop, ret;
+	u32 chip_id, interrupt;
+
+	wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
+
+	chip_id = wl1271_reg_read32(wl, CHIP_ID_B);
+
+	wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
+
+	if (chip_id != wl->chip.id) {
+		wl1271_error("chip id doesn't match after firmware boot");
+		return -EIO;
+	}
+
+	/* wait for init to complete */
+	loop = 0;
+	while (loop++ < INIT_LOOP) {
+		udelay(INIT_LOOP_DELAY);
+		interrupt = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+
+		if (interrupt == 0xffffffff) {
+			wl1271_error("error reading hardware complete "
+				     "init indication");
+			return -EIO;
+		}
+		/* check that ACX_INTR_INIT_COMPLETE is enabled */
+		else if (interrupt & WL1271_ACX_INTR_INIT_COMPLETE) {
+			wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+					   WL1271_ACX_INTR_INIT_COMPLETE);
+			break;
+		}
+	}
+
+	if (loop >= INIT_LOOP) {
+		wl1271_error("timeout waiting for the hardware to "
+			     "complete initialization");
+		return -EIO;
+	}
+
+	/* get hardware config command mail box */
+	wl->cmd_box_addr = wl1271_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
+
+	/* get hardware config event mail box */
+	wl->event_box_addr = wl1271_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+
+	/* set the working partition to its "running" mode offset */
+	wl1271_set_partition(wl,
+			     part_table[PART_WORK].mem.start,
+			     part_table[PART_WORK].mem.size,
+			     part_table[PART_WORK].reg.start,
+			     part_table[PART_WORK].reg.size);
+
+	wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
+		     wl->cmd_box_addr, wl->event_box_addr);
+
+	wl1271_boot_fw_version(wl);
+
+	/*
+	 * in case of full asynchronous mode the firmware event must be
+	 * ready to receive event from the command mailbox
+	 */
+
+	/* enable gpio interrupts */
+	wl1271_boot_enable_interrupts(wl);
+
+	/* unmask all mbox events  */
+	wl->event_mask = 0xffffffff;
+
+	ret = wl1271_event_unmask(wl);
+	if (ret < 0) {
+		wl1271_error("EVENT mask setting failed");
+		return ret;
+	}
+
+	wl1271_event_mbox_config(wl);
+
+	/* firmware startup completed */
+	return 0;
+}
+
+static int wl1271_boot_write_irq_polarity(struct wl1271 *wl)
+{
+	u32 polarity, status, i;
+
+	wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
+	wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_READ);
+
+	/* Wait until the command is complete (ie. bit 18 is set) */
+	for (i = 0; i < OCP_CMD_LOOP; i++) {
+		polarity = wl1271_reg_read32(wl, OCP_DATA_READ);
+		if (polarity & OCP_READY_MASK)
+			break;
+	}
+	if (i == OCP_CMD_LOOP) {
+		wl1271_error("OCP command timeout!");
+		return -EIO;
+	}
+
+	status = polarity & OCP_STATUS_MASK;
+	if (status != OCP_STATUS_OK) {
+		wl1271_error("OCP command failed (%d)", status);
+		return -EIO;
+	}
+
+	/* We use HIGH polarity, so unset the LOW bit */
+	polarity &= ~POLARITY_LOW;
+
+	wl1271_reg_write32(wl, OCP_POR_CTR, OCP_REG_POLARITY);
+	wl1271_reg_write32(wl, OCP_DATA_WRITE, polarity);
+	wl1271_reg_write32(wl, OCP_CMD, OCP_CMD_WRITE);
+
+	return 0;
+}
+
+int wl1271_boot(struct wl1271 *wl)
+{
+	int ret = 0;
+	u32 tmp, clk, pause;
+
+	if (REF_CLOCK == 0 || REF_CLOCK == 2)
+		/* ref clk: 19.2/38.4 */
+		clk = 0x3;
+	else if (REF_CLOCK == 1 || REF_CLOCK == 3)
+		/* ref clk: 26/52 */
+		clk = 0x5;
+
+	wl1271_reg_write32(wl, PLL_PARAMETERS, clk);
+
+	pause = wl1271_reg_read32(wl, PLL_PARAMETERS);
+
+	wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
+
+	pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be
+					   * WU_COUNTER_PAUSE_VAL instead of
+					   * 0x3ff (magic number ).  How does
+					   * this work?! */
+	pause |= WU_COUNTER_PAUSE_VAL;
+	wl1271_reg_write32(wl, WU_COUNTER_PAUSE, pause);
+
+	/* Continue the ELP wake up sequence */
+	wl1271_reg_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
+	udelay(500);
+
+	wl1271_set_partition(wl,
+			     part_table[PART_DRPW].mem.start,
+			     part_table[PART_DRPW].mem.size,
+			     part_table[PART_DRPW].reg.start,
+			     part_table[PART_DRPW].reg.size);
+
+	/* Read-modify-write DRPW_SCRATCH_START register (see next state)
+	   to be used by DRPw FW. The RTRIM value will be added by the FW
+	   before taking DRPw out of reset */
+
+	wl1271_debug(DEBUG_BOOT, "DRPW_SCRATCH_START %08x", DRPW_SCRATCH_START);
+	clk = wl1271_reg_read32(wl, DRPW_SCRATCH_START);
+
+	wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
+
+	/* 2 */
+	clk |= (REF_CLOCK << 1) << 4;
+	wl1271_reg_write32(wl, DRPW_SCRATCH_START, clk);
+
+	wl1271_set_partition(wl,
+			     part_table[PART_WORK].mem.start,
+			     part_table[PART_WORK].mem.size,
+			     part_table[PART_WORK].reg.start,
+			     part_table[PART_WORK].reg.size);
+
+	/* Disable interrupts */
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
+
+	ret = wl1271_boot_soft_reset(wl);
+	if (ret < 0)
+		goto out;
+
+	/* 2. start processing NVS file */
+	ret = wl1271_boot_upload_nvs(wl);
+	if (ret < 0)
+		goto out;
+
+	/* write firmware's last address (ie. it's length) to
+	 * ACX_EEPROMLESS_IND_REG */
+	wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
+
+	wl1271_reg_write32(wl, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG);
+
+	tmp = wl1271_reg_read32(wl, CHIP_ID_B);
+
+	wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
+
+	/* 6. read the EEPROM parameters */
+	tmp = wl1271_reg_read32(wl, SCR_PAD2);
+
+	ret = wl1271_boot_write_irq_polarity(wl);
+	if (ret < 0)
+		goto out;
+
+	/* FIXME: Need to check whether this is really what we want */
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+			   WL1271_ACX_ALL_EVENTS_VECTOR);
+
+	/* WL1271: The reference driver skips steps 7 to 10 (jumps directly
+	 * to upload_fw) */
+
+	ret = wl1271_boot_upload_firmware(wl);
+	if (ret < 0)
+		goto out;
+
+	/* 10.5 start firmware */
+	ret = wl1271_boot_run_firmware(wl);
+	if (ret < 0)
+		goto out;
+
+	/* set the wl1271 default filters */
+	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
+	wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
+
+	wl1271_event_mbox_config(wl);
+
+out:
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h
new file mode 100644
index 0000000..b0d8fb4
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __BOOT_H__
+#define __BOOT_H__
+
+#include "wl1271.h"
+
+int wl1271_boot(struct wl1271 *wl);
+
+#define WL1271_NO_SUBBANDS 8
+#define WL1271_NO_POWER_LEVELS 4
+#define WL1271_FW_VERSION_MAX_LEN 20
+
+struct wl1271_static_data {
+	u8 mac_address[ETH_ALEN];
+	u8 padding[2];
+	u8 fw_version[WL1271_FW_VERSION_MAX_LEN];
+	u32 hw_version;
+	u8 tx_power_table[WL1271_NO_SUBBANDS][WL1271_NO_POWER_LEVELS];
+};
+
+/* number of times we try to read the INIT interrupt */
+#define INIT_LOOP 20000
+
+/* delay between retries */
+#define INIT_LOOP_DELAY 50
+
+#define REF_CLOCK            2
+#define WU_COUNTER_PAUSE_VAL 0x3FF
+#define WELP_ARM_COMMAND_VAL 0x4
+
+#define OCP_CMD_LOOP  32
+
+#define OCP_CMD_WRITE 0x1
+#define OCP_CMD_READ  0x2
+
+#define OCP_READY_MASK  BIT(18)
+#define OCP_STATUS_MASK (BIT(16) | BIT(17))
+
+#define OCP_STATUS_NO_RESP    0x00000
+#define OCP_STATUS_OK         0x10000
+#define OCP_STATUS_REQ_FAILED 0x20000
+#define OCP_STATUS_RESP_ERROR 0x30000
+
+#define OCP_REG_POLARITY 0x30032
+
+#define CMD_MBOX_ADDRESS 0x407B4
+
+#define POLARITY_LOW BIT(1)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
new file mode 100644
index 0000000..2a4351f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -0,0 +1,813 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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/module.h>
+#include <linux/platform_device.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+
+#include "wl1271.h"
+#include "wl1271_reg.h"
+#include "wl1271_spi.h"
+#include "wl1271_acx.h"
+#include "wl12xx_80211.h"
+#include "wl1271_cmd.h"
+
+/*
+ * send command to firmware
+ *
+ * @wl: wl struct
+ * @id: command id
+ * @buf: buffer containing the command, must work with dma
+ * @len: length of the buffer
+ */
+int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
+{
+	struct wl1271_cmd_header *cmd;
+	unsigned long timeout;
+	u32 intr;
+	int ret = 0;
+
+	cmd = buf;
+	cmd->id = id;
+	cmd->status = 0;
+
+	WARN_ON(len % 4 != 0);
+
+	wl1271_spi_mem_write(wl, wl->cmd_box_addr, buf, len);
+
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+
+	timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
+
+	intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+	while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
+		if (time_after(jiffies, timeout)) {
+			wl1271_error("command complete timeout");
+			ret = -ETIMEDOUT;
+			goto out;
+		}
+
+		msleep(1);
+
+		intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+	}
+
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+			   WL1271_ACX_INTR_CMD_COMPLETE);
+
+out:
+	return ret;
+}
+
+int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
+{
+	struct wl1271_cmd_cal_channel_tune *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->test.id = TEST_CMD_CHANNEL_TUNE;
+
+	cmd->band = WL1271_CHANNEL_TUNE_BAND_2_4;
+	/* set up any channel, 7 is in the middle of the range */
+	cmd->channel = 7;
+
+	ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
+	if (ret < 0)
+		wl1271_warning("TEST_CMD_CHANNEL_TUNE failed");
+
+	kfree(cmd);
+	return ret;
+}
+
+int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
+{
+	struct wl1271_cmd_cal_update_ref_point *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT;
+
+	/* FIXME: still waiting for the correct values */
+	cmd->ref_power    = 0;
+	cmd->ref_detector = 0;
+
+	cmd->sub_band     = WL1271_PD_REFERENCE_POINT_BAND_B_G;
+
+	ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
+	if (ret < 0)
+		wl1271_warning("TEST_CMD_UPDATE_PD_REFERENCE_POINT failed");
+
+	kfree(cmd);
+	return ret;
+}
+
+int wl1271_cmd_cal_p2g(struct wl1271 *wl)
+{
+	struct wl1271_cmd_cal_p2g *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->test.id = TEST_CMD_P2G_CAL;
+
+	cmd->sub_band_mask = WL1271_CAL_P2G_BAND_B_G;
+
+	ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
+	if (ret < 0)
+		wl1271_warning("TEST_CMD_P2G_CAL failed");
+
+	kfree(cmd);
+	return ret;
+}
+
+int wl1271_cmd_cal(struct wl1271 *wl)
+{
+	/*
+	 * FIXME: we must make sure that we're not sleeping when calibration
+	 * is done
+	 */
+	int ret;
+
+	wl1271_notice("performing tx calibration");
+
+	ret = wl1271_cmd_cal_channel_tune(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_cal_update_ref_point(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_cal_p2g(wl);
+	if (ret < 0)
+		return ret;
+
+	return ret;
+}
+
+int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
+		    u16 beacon_interval, u8 wait)
+{
+	static bool do_cal = true;
+	unsigned long timeout;
+	struct wl1271_cmd_join *join;
+	int ret, i;
+	u8 *bssid;
+
+	/* FIXME: remove when we get calibration from the factory */
+	if (do_cal) {
+		ret = wl1271_cmd_cal(wl);
+		if (ret < 0)
+			wl1271_warning("couldn't calibrate");
+		else
+			do_cal = false;
+	}
+
+
+	join = kzalloc(sizeof(*join), GFP_KERNEL);
+	if (!join) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	wl1271_debug(DEBUG_CMD, "cmd join");
+
+	/* Reverse order BSSID */
+	bssid = (u8 *) &join->bssid_lsb;
+	for (i = 0; i < ETH_ALEN; i++)
+		bssid[i] = wl->bssid[ETH_ALEN - i - 1];
+
+	join->rx_config_options = wl->rx_config;
+	join->rx_filter_options = wl->rx_filter;
+
+	join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
+		RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
+
+	join->beacon_interval = beacon_interval;
+	join->dtim_interval = dtim_interval;
+	join->bss_type = bss_type;
+	join->channel = wl->channel;
+	join->ssid_len = wl->ssid_len;
+	memcpy(join->ssid, wl->ssid, wl->ssid_len);
+	join->ctrl = WL1271_JOIN_CMD_CTRL_TX_FLUSH;
+
+	/* increment the session counter */
+	wl->session_counter++;
+	if (wl->session_counter >= SESSION_COUNTER_MAX)
+		wl->session_counter = 0;
+
+	join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;
+
+
+	ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
+	if (ret < 0) {
+		wl1271_error("failed to initiate cmd join");
+		goto out_free;
+	}
+
+	timeout = msecs_to_jiffies(JOIN_TIMEOUT);
+
+	/*
+	 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
+	 * simplify locking we just sleep instead, for now
+	 */
+	if (wait)
+		msleep(10);
+
+out_free:
+	kfree(join);
+
+out:
+	return ret;
+}
+
+/**
+ * send test command to firmware
+ *
+ * @wl: wl struct
+ * @buf: buffer containing the command, with all headers, must work with dma
+ * @len: length of the buffer
+ * @answer: is answer needed
+ */
+int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
+{
+	int ret;
+
+	wl1271_debug(DEBUG_CMD, "cmd test");
+
+	ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len);
+
+	if (ret < 0) {
+		wl1271_warning("TEST command failed");
+		return ret;
+	}
+
+	if (answer) {
+		struct wl1271_command *cmd_answer;
+
+		/*
+		 * The test command got in, we can read the answer.
+		 * The answer would be a wl1271_command, where the
+		 * parameter array contains the actual answer.
+		 */
+		wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
+
+		cmd_answer = buf;
+
+		if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
+			wl1271_error("TEST command answer error: %d",
+				     cmd_answer->header.status);
+	}
+
+	return 0;
+}
+
+/**
+ * read acx from firmware
+ *
+ * @wl: wl struct
+ * @id: acx id
+ * @buf: buffer for the response, including all headers, must work with dma
+ * @len: lenght of buf
+ */
+int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
+{
+	struct acx_header *acx = buf;
+	int ret;
+
+	wl1271_debug(DEBUG_CMD, "cmd interrogate");
+
+	acx->id = id;
+
+	/* payload length, does not include any headers */
+	acx->len = len - sizeof(*acx);
+
+	ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_error("INTERROGATE command failed");
+		goto out;
+	}
+
+	/* the interrogate command got in, we can read the answer */
+	wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, len);
+
+	acx = buf;
+	if (acx->cmd.status != CMD_STATUS_SUCCESS)
+		wl1271_error("INTERROGATE command error: %d",
+			     acx->cmd.status);
+
+out:
+	return ret;
+}
+
+/**
+ * write acx value to firmware
+ *
+ * @wl: wl struct
+ * @id: acx id
+ * @buf: buffer containing acx, including all headers, must work with dma
+ * @len: length of buf
+ */
+int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
+{
+	struct acx_header *acx = buf;
+	int ret;
+
+	wl1271_debug(DEBUG_CMD, "cmd configure");
+
+	acx->id = id;
+
+	/* payload length, does not include any headers */
+	acx->len = len - sizeof(*acx);
+
+	ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len);
+	if (ret < 0) {
+		wl1271_warning("CONFIGURE command NOK");
+		return ret;
+	}
+
+	return 0;
+}
+
+int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
+{
+	struct cmd_enabledisable_path *cmd;
+	int ret;
+	u16 cmd_rx, cmd_tx;
+
+	wl1271_debug(DEBUG_CMD, "cmd data path");
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->channel = channel;
+
+	if (enable) {
+		cmd_rx = CMD_ENABLE_RX;
+		cmd_tx = CMD_ENABLE_TX;
+	} else {
+		cmd_rx = CMD_DISABLE_RX;
+		cmd_tx = CMD_DISABLE_TX;
+	}
+
+	ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1271_error("rx %s cmd for channel %d failed",
+			     enable ? "start" : "stop", channel);
+		goto out;
+	}
+
+	wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
+		     enable ? "start" : "stop", channel);
+
+	ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1271_error("tx %s cmd for channel %d failed",
+			     enable ? "start" : "stop", channel);
+		return ret;
+	}
+
+	wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
+		     enable ? "start" : "stop", channel);
+
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
+{
+	struct wl1271_cmd_ps_params *ps_params = NULL;
+	int ret = 0;
+
+	/* FIXME: this should be in ps.c */
+	ret = wl1271_acx_wake_up_conditions(wl, WAKE_UP_EVENT_DTIM_BITMAP,
+					    wl->listen_int);
+	if (ret < 0) {
+		wl1271_error("couldn't set wake up conditions");
+		goto out;
+	}
+
+	wl1271_debug(DEBUG_CMD, "cmd set ps mode");
+
+	ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
+	if (!ps_params) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ps_params->ps_mode = ps_mode;
+	ps_params->send_null_data = 1;
+	ps_params->retries = 5;
+	ps_params->hang_over_period = 128;
+	ps_params->null_data_rate = 1; /* 1 Mbps */
+
+	ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
+			      sizeof(*ps_params));
+	if (ret < 0) {
+		wl1271_error("cmd set_ps_mode failed");
+		goto out;
+	}
+
+out:
+	kfree(ps_params);
+	return ret;
+}
+
+int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
+			   size_t len)
+{
+	struct cmd_read_write_memory *cmd;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_CMD, "cmd read memory");
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	WARN_ON(len > MAX_READ_SIZE);
+	len = min_t(size_t, len, MAX_READ_SIZE);
+
+	cmd->addr = addr;
+	cmd->size = len;
+
+	ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1271_error("read memory command failed: %d", ret);
+		goto out;
+	}
+
+	/* the read command got in, we can now read the answer */
+	wl1271_spi_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
+
+	if (cmd->header.status != CMD_STATUS_SUCCESS)
+		wl1271_error("error in read command result: %d",
+			     cmd->header.status);
+
+	memcpy(answer, cmd->value, len);
+
+out:
+	kfree(cmd);
+	return ret;
+}
+
+int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
+		    u8 active_scan, u8 high_prio, u8 num_channels,
+		    u8 probe_requests)
+{
+
+	struct wl1271_cmd_trigger_scan_to *trigger = NULL;
+	struct wl1271_cmd_scan *params = NULL;
+	int i, ret;
+	u16 scan_options = 0;
+
+	if (wl->scanning)
+		return -EINVAL;
+
+	params = kzalloc(sizeof(*params), GFP_KERNEL);
+	if (!params)
+		return -ENOMEM;
+
+	params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
+	params->params.rx_filter_options =
+		cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
+
+	if (!active_scan)
+		scan_options |= WL1271_SCAN_OPT_PASSIVE;
+	if (high_prio)
+		scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH;
+	params->params.scan_options = scan_options;
+
+	params->params.num_channels = num_channels;
+	params->params.num_probe_requests = probe_requests;
+	params->params.tx_rate = cpu_to_le32(RATE_MASK_2MBPS);
+	params->params.tid_trigger = 0;
+	params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
+
+	for (i = 0; i < num_channels; i++) {
+		params->channels[i].min_duration =
+			cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
+		params->channels[i].max_duration =
+			cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
+		memset(&params->channels[i].bssid_lsb, 0xff, 4);
+		memset(&params->channels[i].bssid_msb, 0xff, 2);
+		params->channels[i].early_termination = 0;
+		params->channels[i].tx_power_att = WL1271_SCAN_CURRENT_TX_PWR;
+		params->channels[i].channel = i + 1;
+	}
+
+	if (len && ssid) {
+		params->params.ssid_len = len;
+		memcpy(params->params.ssid, ssid, len);
+	}
+
+	ret = wl1271_cmd_build_probe_req(wl, ssid, len);
+	if (ret < 0) {
+		wl1271_error("PROBE request template failed");
+		goto out;
+	}
+
+	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
+	if (!trigger) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* disable the timeout */
+	trigger->timeout = 0;
+
+	ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
+			      sizeof(*trigger));
+	if (ret < 0) {
+		wl1271_error("trigger scan to failed for hw scan");
+		goto out;
+	}
+
+	wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
+
+	wl->scanning = true;
+
+	ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+	if (ret < 0) {
+		wl1271_error("SCAN failed");
+		goto out;
+	}
+
+	wl1271_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
+
+	if (params->header.status != CMD_STATUS_SUCCESS) {
+		wl1271_error("Scan command error: %d",
+			     params->header.status);
+		wl->scanning = false;
+		ret = -EIO;
+		goto out;
+	}
+
+out:
+	kfree(params);
+	return ret;
+}
+
+int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
+			    void *buf, size_t buf_len)
+{
+	struct wl1271_cmd_template_set *cmd;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id);
+
+	WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE);
+	buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE);
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->len = cpu_to_le16(buf_len);
+	cmd->template_type = template_id;
+	cmd->enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
+	cmd->short_retry_limit = ACX_RATE_RETRY_LIMIT;
+	cmd->long_retry_limit = ACX_RATE_RETRY_LIMIT;
+
+	if (buf)
+		memcpy(cmd->template_data, buf, buf_len);
+
+	ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1271_warning("cmd set_template failed: %d", ret);
+		goto out_free;
+	}
+
+out_free:
+	kfree(cmd);
+
+out:
+	return ret;
+}
+
+static int wl1271_build_basic_rates(char *rates)
+{
+	u8 index = 0;
+
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+
+	return index;
+}
+
+static int wl1271_build_extended_rates(char *rates)
+{
+	u8 index = 0;
+
+	rates[index++] = IEEE80211_OFDM_RATE_6MB;
+	rates[index++] = IEEE80211_OFDM_RATE_9MB;
+	rates[index++] = IEEE80211_OFDM_RATE_12MB;
+	rates[index++] = IEEE80211_OFDM_RATE_18MB;
+	rates[index++] = IEEE80211_OFDM_RATE_24MB;
+	rates[index++] = IEEE80211_OFDM_RATE_36MB;
+	rates[index++] = IEEE80211_OFDM_RATE_48MB;
+	rates[index++] = IEEE80211_OFDM_RATE_54MB;
+
+	return index;
+}
+
+int wl1271_cmd_build_null_data(struct wl1271 *wl)
+{
+	struct wl12xx_null_data_template template;
+
+	if (!is_zero_ether_addr(wl->bssid)) {
+		memcpy(template.header.da, wl->bssid, ETH_ALEN);
+		memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
+	} else {
+		memset(template.header.da, 0xff, ETH_ALEN);
+		memset(template.header.bssid, 0xff, ETH_ALEN);
+	}
+
+	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+	template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+						IEEE80211_STYPE_NULLFUNC);
+
+	return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template,
+				       sizeof(template));
+
+}
+
+int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
+{
+	struct wl12xx_ps_poll_template template;
+
+	memcpy(template.bssid, wl->bssid, ETH_ALEN);
+	memcpy(template.ta, wl->mac_addr, ETH_ALEN);
+	template.aid = aid;
+	template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+
+	return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template,
+				       sizeof(template));
+
+}
+
+int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len)
+{
+	struct wl12xx_probe_req_template template;
+	struct wl12xx_ie_rates *rates;
+	char *ptr;
+	u16 size;
+
+	ptr = (char *)&template;
+	size = sizeof(struct ieee80211_header);
+
+	memset(template.header.da, 0xff, ETH_ALEN);
+	memset(template.header.bssid, 0xff, ETH_ALEN);
+	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+	template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+
+	/* IEs */
+	/* SSID */
+	template.ssid.header.id = WLAN_EID_SSID;
+	template.ssid.header.len = ssid_len;
+	if (ssid_len && ssid)
+		memcpy(template.ssid.ssid, ssid, ssid_len);
+	size += sizeof(struct wl12xx_ie_header) + ssid_len;
+	ptr += size;
+
+	/* Basic Rates */
+	rates = (struct wl12xx_ie_rates *)ptr;
+	rates->header.id = WLAN_EID_SUPP_RATES;
+	rates->header.len = wl1271_build_basic_rates(rates->rates);
+	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+	ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+	/* Extended rates */
+	rates = (struct wl12xx_ie_rates *)ptr;
+	rates->header.id = WLAN_EID_EXT_SUPP_RATES;
+	rates->header.len = wl1271_build_extended_rates(rates->rates);
+	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+	wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
+
+	return wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
+				       &template, size);
+}
+
+int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
+{
+	struct wl1271_cmd_set_keys *cmd;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	cmd->id = id;
+	cmd->key_action = KEY_SET_ID;
+	cmd->key_type = KEY_WEP;
+
+	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1271_warning("cmd set_default_wep_key failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(cmd);
+
+	return ret;
+}
+
+int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
+		       u8 key_size, const u8 *key, const u8 *addr)
+{
+	struct wl1271_cmd_set_keys *cmd;
+	int ret = 0;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (key_type != KEY_WEP)
+		memcpy(cmd->addr, addr, ETH_ALEN);
+
+	cmd->key_action = action;
+	cmd->key_size = key_size;
+	cmd->key_type = key_type;
+
+	/* we have only one SSID profile */
+	cmd->ssid_profile = 0;
+
+	cmd->id = id;
+
+	/* FIXME: this is from wl1251, needs to be checked */
+	if (key_type == KEY_TKIP) {
+		/*
+		 * We get the key in the following form:
+		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+		 * but the target is expecting:
+		 * TKIP - RX MIC - TX MIC
+		 */
+		memcpy(cmd->key, key, 16);
+		memcpy(cmd->key + 16, key + 24, 8);
+		memcpy(cmd->key + 24, key + 16, 8);
+
+	} else {
+		memcpy(cmd->key, key, key_size);
+	}
+
+	wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
+
+	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
+	if (ret < 0) {
+		wl1271_warning("could not set keys");
+		goto out;
+	}
+
+out:
+	kfree(cmd);
+
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
new file mode 100644
index 0000000..951a844
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -0,0 +1,464 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_CMD_H__
+#define __WL1271_CMD_H__
+
+#include "wl1271.h"
+
+struct acx_header;
+
+int wl1271_cmd_send(struct wl1271 *wl, u16 type, void *buf, size_t buf_len);
+int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
+		    u16 beacon_interval, u8 wait);
+int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
+int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len);
+int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len);
+int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable);
+int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode);
+int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
+			   size_t len);
+int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
+		    u8 active_scan, u8 high_prio, u8 num_channels,
+		    u8 probe_requests);
+int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
+			    void *buf, size_t buf_len);
+int wl1271_cmd_build_null_data(struct wl1271 *wl);
+int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
+int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len);
+int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
+int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
+		       u8 key_size, const u8 *key, const u8 *addr);
+
+enum wl1271_commands {
+	CMD_INTERROGATE     = 1,    /*use this to read information elements*/
+	CMD_CONFIGURE       = 2,    /*use this to write information elements*/
+	CMD_ENABLE_RX       = 3,
+	CMD_ENABLE_TX       = 4,
+	CMD_DISABLE_RX      = 5,
+	CMD_DISABLE_TX      = 6,
+	CMD_SCAN            = 8,
+	CMD_STOP_SCAN       = 9,
+	CMD_START_JOIN      = 11,
+	CMD_SET_KEYS        = 12,
+	CMD_READ_MEMORY     = 13,
+	CMD_WRITE_MEMORY    = 14,
+	CMD_SET_TEMPLATE    = 19,
+	CMD_TEST            = 23,
+	CMD_NOISE_HIST      = 28,
+	CMD_LNA_CONTROL     = 32,
+	CMD_SET_BCN_MODE    = 33,
+	CMD_MEASUREMENT      = 34,
+	CMD_STOP_MEASUREMENT = 35,
+	CMD_DISCONNECT       = 36,
+	CMD_SET_PS_MODE      = 37,
+	CMD_CHANNEL_SWITCH   = 38,
+	CMD_STOP_CHANNEL_SWICTH = 39,
+	CMD_AP_DISCOVERY     = 40,
+	CMD_STOP_AP_DISCOVERY = 41,
+	CMD_SPS_SCAN = 42,
+	CMD_STOP_SPS_SCAN = 43,
+	CMD_HEALTH_CHECK     = 45,
+	CMD_DEBUG            = 46,
+	CMD_TRIGGER_SCAN_TO  = 47,
+	CMD_CONNECTION_SCAN_CFG      = 48,
+	CMD_CONNECTION_SCAN_SSID_CFG = 49,
+	CMD_START_PERIODIC_SCAN      = 50,
+	CMD_STOP_PERIODIC_SCAN       = 51,
+	CMD_SET_STA_STATE            = 52,
+
+	NUM_COMMANDS,
+	MAX_COMMAND_ID = 0xFFFF,
+};
+
+#define MAX_CMD_PARAMS 572
+
+enum cmd_templ {
+	CMD_TEMPL_NULL_DATA = 0,
+	CMD_TEMPL_BEACON,
+	CMD_TEMPL_CFG_PROBE_REQ_2_4,
+	CMD_TEMPL_CFG_PROBE_REQ_5,
+	CMD_TEMPL_PROBE_RESPONSE,
+	CMD_TEMPL_QOS_NULL_DATA,
+	CMD_TEMPL_PS_POLL,
+	CMD_TEMPL_KLV,
+	CMD_TEMPL_DISCONNECT,
+	CMD_TEMPL_PROBE_REQ_2_4, /* for firmware internal use only */
+	CMD_TEMPL_PROBE_REQ_5,   /* for firmware internal use only */
+	CMD_TEMPL_BAR,           /* for firmware internal use only */
+	CMD_TEMPL_CTS,           /*
+				  * For CTS-to-self (FastCTS) mechanism
+				  * for BT/WLAN coexistence (SoftGemini). */
+	CMD_TEMPL_MAX = 0xff
+};
+
+/* unit ms */
+#define WL1271_COMMAND_TIMEOUT     2000
+#define WL1271_CMD_TEMPL_MAX_SIZE  252
+
+struct wl1271_cmd_header {
+	u16 id;
+	u16 status;
+	/* payload */
+	u8 data[0];
+} __attribute__ ((packed));
+
+#define WL1271_CMD_MAX_PARAMS 572
+
+struct wl1271_command {
+	struct wl1271_cmd_header header;
+	u8  parameters[WL1271_CMD_MAX_PARAMS];
+} __attribute__ ((packed));
+
+enum {
+	CMD_MAILBOX_IDLE		=  0,
+	CMD_STATUS_SUCCESS		=  1,
+	CMD_STATUS_UNKNOWN_CMD		=  2,
+	CMD_STATUS_UNKNOWN_IE		=  3,
+	CMD_STATUS_REJECT_MEAS_SG_ACTIVE	= 11,
+	CMD_STATUS_RX_BUSY		= 13,
+	CMD_STATUS_INVALID_PARAM		= 14,
+	CMD_STATUS_TEMPLATE_TOO_LARGE		= 15,
+	CMD_STATUS_OUT_OF_MEMORY		= 16,
+	CMD_STATUS_STA_TABLE_FULL		= 17,
+	CMD_STATUS_RADIO_ERROR		= 18,
+	CMD_STATUS_WRONG_NESTING		= 19,
+	CMD_STATUS_TIMEOUT		= 21, /* Driver internal use.*/
+	CMD_STATUS_FW_RESET		= 22, /* Driver internal use.*/
+	MAX_COMMAND_STATUS		= 0xff
+};
+
+
+/*
+ * CMD_READ_MEMORY
+ *
+ * The host issues this command to read the WiLink device memory/registers.
+ *
+ * Note: The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+/*
+ * CMD_WRITE_MEMORY
+ *
+ * The host issues this command to write the WiLink device memory/registers.
+ *
+ * The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+#define MAX_READ_SIZE 256
+
+struct cmd_read_write_memory {
+	struct wl1271_cmd_header header;
+
+	/* The address of the memory to read from or write to.*/
+	u32 addr;
+
+	/* The amount of data in bytes to read from or write to the WiLink
+	 * device.*/
+	u32 size;
+
+	/* The actual value read from or written to the Wilink. The source
+	   of this field is the Host in WRITE command or the Wilink in READ
+	   command. */
+	u8 value[MAX_READ_SIZE];
+};
+
+#define CMDMBOX_HEADER_LEN 4
+#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
+
+enum {
+	BSS_TYPE_IBSS = 0,
+	BSS_TYPE_STA_BSS = 2,
+	BSS_TYPE_AP_BSS = 3,
+	MAX_BSS_TYPE = 0xFF
+};
+
+#define WL1271_JOIN_CMD_CTRL_TX_FLUSH     0x80 /* Firmware flushes all Tx */
+#define WL1271_JOIN_CMD_TX_SESSION_OFFSET 1
+
+struct wl1271_cmd_join {
+	struct wl1271_cmd_header header;
+
+	u32 bssid_lsb;
+	u16 bssid_msb;
+	u16 beacon_interval; /* in TBTTs */
+	u32 rx_config_options;
+	u32 rx_filter_options;
+
+	/*
+	 * The target uses this field to determine the rate at
+	 * which to transmit control frame responses (such as
+	 * ACK or CTS frames).
+	 */
+	u32 basic_rate_set;
+	u8 dtim_interval;
+	/*
+	 * bits 0-2: This bitwise field specifies the type
+	 * of BSS to start or join (BSS_TYPE_*).
+	 * bit 4: Band - The radio band in which to join
+	 * or start.
+	 *  0 - 2.4GHz band
+	 *  1 - 5GHz band
+	 * bits 3, 5-7: Reserved
+	 */
+	u8 bss_type;
+	u8 channel;
+	u8 ssid_len;
+	u8 ssid[IW_ESSID_MAX_SIZE];
+	u8 ctrl; /* JOIN_CMD_CTRL_* */
+	u8 reserved[3];
+} __attribute__ ((packed));
+
+struct cmd_enabledisable_path {
+	struct wl1271_cmd_header header;
+
+	u8 channel;
+	u8 padding[3];
+} __attribute__ ((packed));
+
+struct wl1271_cmd_template_set {
+	struct wl1271_cmd_header header;
+
+	u16 len;
+	u8 template_type;
+	u8 index;  /* relevant only for KLV_TEMPLATE type */
+	u32 enabled_rates;
+	u8 short_retry_limit;
+	u8 long_retry_limit;
+	u8 aflags;
+	u8 reserved;
+	u8 template_data[WL1271_CMD_TEMPL_MAX_SIZE];
+} __attribute__ ((packed));
+
+#define TIM_ELE_ID    5
+#define PARTIAL_VBM_MAX    251
+
+struct wl1271_tim {
+	u8 identity;
+	u8 length;
+	u8 dtim_count;
+	u8 dtim_period;
+	u8 bitmap_ctrl;
+	u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
+} __attribute__ ((packed));
+
+enum wl1271_cmd_ps_mode {
+	STATION_ACTIVE_MODE,
+	STATION_POWER_SAVE_MODE
+};
+
+struct wl1271_cmd_ps_params {
+	struct wl1271_cmd_header header;
+
+	u8 ps_mode; /* STATION_* */
+	u8 send_null_data; /* Do we have to send NULL data packet ? */
+	u8 retries; /* Number of retires for the initial NULL data packet */
+
+	 /*
+	  * TUs during which the target stays awake after switching
+	  * to power save mode.
+	  */
+	u8 hang_over_period;
+	u32 null_data_rate;
+} __attribute__ ((packed));
+
+/* HW encryption keys */
+#define NUM_ACCESS_CATEGORIES_COPY 4
+#define MAX_KEY_SIZE 32
+
+/* When set, disable HW encryption */
+#define DF_ENCRYPTION_DISABLE      0x01
+/* When set, disable HW decryption */
+#define DF_SNIFF_MODE_ENABLE       0x80
+
+enum wl1271_cmd_key_action {
+	KEY_ADD_OR_REPLACE = 1,
+	KEY_REMOVE         = 2,
+	KEY_SET_ID         = 3,
+	MAX_KEY_ACTION     = 0xffff,
+};
+
+enum wl1271_cmd_key_type {
+	KEY_NONE = 0,
+	KEY_WEP  = 1,
+	KEY_TKIP = 2,
+	KEY_AES  = 3,
+	KEY_GEM  = 4
+};
+
+/* FIXME: Add description for key-types */
+
+struct wl1271_cmd_set_keys {
+	struct wl1271_cmd_header header;
+
+	/* Ignored for default WEP key */
+	u8 addr[ETH_ALEN];
+
+	/* key_action_e */
+	u16 key_action;
+
+	u16 reserved_1;
+
+	/* key size in bytes */
+	u8 key_size;
+
+	/* key_type_e */
+	u8 key_type;
+	u8 ssid_profile;
+
+	/*
+	 * TKIP, AES: frame's key id field.
+	 * For WEP default key: key id;
+	 */
+	u8 id;
+	u8 reserved_2[6];
+	u8 key[MAX_KEY_SIZE];
+	u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+	u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+} __attribute__ ((packed));
+
+
+#define WL1271_SCAN_MAX_CHANNELS       24
+#define WL1271_SCAN_DEFAULT_TAG        1
+#define WL1271_SCAN_CURRENT_TX_PWR     0
+#define WL1271_SCAN_OPT_ACTIVE         0
+#define WL1271_SCAN_OPT_PASSIVE	       1
+#define WL1271_SCAN_OPT_PRIORITY_HIGH  4
+#define WL1271_SCAN_CHAN_MIN_DURATION  30000  /* TU */
+#define WL1271_SCAN_CHAN_MAX_DURATION  60000  /* TU */
+
+struct basic_scan_params {
+	u32 rx_config_options;
+	u32 rx_filter_options;
+	/* Scan option flags (WL1271_SCAN_OPT_*) */
+	u16 scan_options;
+	/* Number of scan channels in the list (maximum 30) */
+	u8 num_channels;
+	/* This field indicates the number of probe requests to send
+	   per channel for an active scan */
+	u8 num_probe_requests;
+	/* Rate bit field for sending the probes */
+	u32 tx_rate;
+	u8 tid_trigger;
+	u8 ssid_len;
+	/* in order to align */
+	u8 padding1[2];
+	u8 ssid[IW_ESSID_MAX_SIZE];
+	/* Band to scan */
+	u8 band;
+	u8 use_ssid_list;
+	u8 scan_tag;
+	u8 padding2;
+} __attribute__ ((packed));
+
+struct basic_scan_channel_params {
+	/* Duration in TU to wait for frames on a channel for active scan */
+	u32 min_duration;
+	u32 max_duration;
+	u32 bssid_lsb;
+	u16 bssid_msb;
+	u8 early_termination;
+	u8 tx_power_att;
+	u8 channel;
+	/* FW internal use only! */
+	u8 dfs_candidate;
+	u8 activity_detected;
+	u8 pad;
+} __attribute__ ((packed));
+
+struct wl1271_cmd_scan {
+	struct wl1271_cmd_header header;
+
+	struct basic_scan_params params;
+	struct basic_scan_channel_params channels[WL1271_SCAN_MAX_CHANNELS];
+} __attribute__ ((packed));
+
+struct wl1271_cmd_trigger_scan_to {
+	struct wl1271_cmd_header header;
+
+	u32 timeout;
+};
+
+struct wl1271_cmd_test_header {
+	u8 id;
+	u8 padding[3];
+};
+
+enum wl1271_channel_tune_bands {
+	WL1271_CHANNEL_TUNE_BAND_2_4,
+	WL1271_CHANNEL_TUNE_BAND_5,
+	WL1271_CHANNEL_TUNE_BAND_4_9
+};
+
+#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0
+
+#define TEST_CMD_P2G_CAL                   0x02
+#define TEST_CMD_CHANNEL_TUNE              0x0d
+#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d
+
+struct wl1271_cmd_cal_channel_tune {
+	struct wl1271_cmd_header header;
+
+	struct wl1271_cmd_test_header test;
+
+	u8 band;
+	u8 channel;
+
+	u16 radio_status;
+} __attribute__ ((packed));
+
+struct wl1271_cmd_cal_update_ref_point {
+	struct wl1271_cmd_header header;
+
+	struct wl1271_cmd_test_header test;
+
+	s32 ref_power;
+	s32 ref_detector;
+	u8  sub_band;
+	u8  padding[3];
+} __attribute__ ((packed));
+
+#define MAX_TLV_LENGTH         400
+#define	MAX_NVS_VERSION_LENGTH 12
+
+#define WL1271_CAL_P2G_BAND_B_G BIT(0)
+
+struct wl1271_cmd_cal_p2g {
+	struct wl1271_cmd_header header;
+
+	struct wl1271_cmd_test_header test;
+
+	u16 len;
+	u8  buf[MAX_TLV_LENGTH];
+	u8  type;
+	u8  padding;
+
+	s16 radio_status;
+	u8  nvs_version[MAX_NVS_VERSION_LENGTH];
+
+	u8  sub_band_mask;
+	u8  padding2;
+} __attribute__ ((packed));
+
+#endif /* __WL1271_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
new file mode 100644
index 0000000..c1805e5
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -0,0 +1,518 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_debugfs.h"
+
+#include <linux/skbuff.h>
+
+#include "wl1271.h"
+#include "wl1271_acx.h"
+#include "wl1271_ps.h"
+
+/* ms */
+#define WL1271_DEBUGFS_STATS_LIFETIME 1000
+
+/* debugfs macros idea from mac80211 */
+
+#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)		\
+static ssize_t name## _read(struct file *file, char __user *userbuf,	\
+			    size_t count, loff_t *ppos)			\
+{									\
+	struct wl1271 *wl = file->private_data;				\
+	char buf[buflen];						\
+	int res;							\
+									\
+	res = scnprintf(buf, buflen, fmt "\n", ##value);		\
+	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
+}									\
+									\
+static const struct file_operations name## _ops = {			\
+	.read = name## _read,						\
+	.open = wl1271_open_file_generic,				\
+};
+
+#define DEBUGFS_ADD(name, parent)					\
+	wl->debugfs.name = debugfs_create_file(#name, 0400, parent,	\
+					       wl, &name## _ops);	\
+	if (IS_ERR(wl->debugfs.name)) {					\
+		ret = PTR_ERR(wl->debugfs.name);			\
+		wl->debugfs.name = NULL;				\
+		goto out;						\
+	}
+
+#define DEBUGFS_DEL(name)						\
+	do {								\
+		debugfs_remove(wl->debugfs.name);			\
+		wl->debugfs.name = NULL;				\
+	} while (0)
+
+#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt)			\
+static ssize_t sub## _ ##name## _read(struct file *file,		\
+				      char __user *userbuf,		\
+				      size_t count, loff_t *ppos)	\
+{									\
+	struct wl1271 *wl = file->private_data;				\
+	char buf[buflen];						\
+	int res;							\
+									\
+	wl1271_debugfs_update_stats(wl);				\
+									\
+	res = scnprintf(buf, buflen, fmt "\n",				\
+			wl->stats.fw_stats->sub.name);			\
+	return simple_read_from_buffer(userbuf, count, ppos, buf, res);	\
+}									\
+									\
+static const struct file_operations sub## _ ##name## _ops = {		\
+	.read = sub## _ ##name## _read,					\
+	.open = wl1271_open_file_generic,				\
+};
+
+#define DEBUGFS_FWSTATS_ADD(sub, name)				\
+	DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
+
+#define DEBUGFS_FWSTATS_DEL(sub, name)				\
+	DEBUGFS_DEL(sub## _ ##name)
+
+static void wl1271_debugfs_update_stats(struct wl1271 *wl)
+{
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	if (wl->state == WL1271_STATE_ON &&
+	    time_after(jiffies, wl->stats.fw_stats_update +
+		       msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) {
+		wl1271_acx_statistics(wl, wl->stats.fw_stats);
+		wl->stats.fw_stats_update = jiffies;
+	}
+
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+static int wl1271_open_file_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
+/* skipping wep.reserved */
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
+/* skipping cont_miss_bcns_spread for now */
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
+		     20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
+		      wl->stats.excessive_retries);
+
+static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	struct wl1271 *wl = file->private_data;
+	u32 queue_len;
+	char buf[20];
+	int res;
+
+	queue_len = skb_queue_len(&wl->tx_queue);
+
+	res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
+	return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+static const struct file_operations tx_queue_len_ops = {
+	.read = tx_queue_len_read,
+	.open = wl1271_open_file_generic,
+};
+
+static void wl1271_debugfs_delete_files(struct wl1271 *wl)
+{
+	DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
+
+	DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
+	DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
+	DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
+	DEBUGFS_FWSTATS_DEL(rx, dropped);
+	DEBUGFS_FWSTATS_DEL(rx, fcs_err);
+	DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
+	DEBUGFS_FWSTATS_DEL(rx, path_reset);
+	DEBUGFS_FWSTATS_DEL(rx, reset_counter);
+
+	DEBUGFS_FWSTATS_DEL(dma, rx_requested);
+	DEBUGFS_FWSTATS_DEL(dma, rx_errors);
+	DEBUGFS_FWSTATS_DEL(dma, tx_requested);
+	DEBUGFS_FWSTATS_DEL(dma, tx_errors);
+
+	DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
+	DEBUGFS_FWSTATS_DEL(isr, fiqs);
+	DEBUGFS_FWSTATS_DEL(isr, rx_headers);
+	DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
+	DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
+	DEBUGFS_FWSTATS_DEL(isr, irqs);
+	DEBUGFS_FWSTATS_DEL(isr, tx_procs);
+	DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
+	DEBUGFS_FWSTATS_DEL(isr, dma0_done);
+	DEBUGFS_FWSTATS_DEL(isr, dma1_done);
+	DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
+	DEBUGFS_FWSTATS_DEL(isr, commands);
+	DEBUGFS_FWSTATS_DEL(isr, rx_procs);
+	DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
+	DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
+	DEBUGFS_FWSTATS_DEL(isr, pci_pm);
+	DEBUGFS_FWSTATS_DEL(isr, wakeups);
+	DEBUGFS_FWSTATS_DEL(isr, low_rssi);
+
+	DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
+	DEBUGFS_FWSTATS_DEL(wep, default_key_count);
+	/* skipping wep.reserved */
+	DEBUGFS_FWSTATS_DEL(wep, key_not_found);
+	DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
+	DEBUGFS_FWSTATS_DEL(wep, packets);
+	DEBUGFS_FWSTATS_DEL(wep, interrupt);
+
+	DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
+	DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
+	DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
+	DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
+	DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
+	DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
+	DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
+	DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
+	DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
+	/* skipping cont_miss_bcns_spread for now */
+	DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
+
+	DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
+	DEBUGFS_FWSTATS_DEL(mic, calc_failure);
+
+	DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
+	DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
+	DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
+	DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
+	DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
+	DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
+
+	DEBUGFS_FWSTATS_DEL(event, heart_beat);
+	DEBUGFS_FWSTATS_DEL(event, calibration);
+	DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
+	DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
+	DEBUGFS_FWSTATS_DEL(event, rx_pool);
+	DEBUGFS_FWSTATS_DEL(event, oom_late);
+	DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
+	DEBUGFS_FWSTATS_DEL(event, tx_stuck);
+
+	DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
+	DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
+	DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
+	DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
+
+	DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
+	DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+	DEBUGFS_DEL(tx_queue_len);
+	DEBUGFS_DEL(retry_count);
+	DEBUGFS_DEL(excessive_retries);
+}
+
+static int wl1271_debugfs_add_files(struct wl1271 *wl)
+{
+	int ret = 0;
+
+	DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
+
+	DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
+	DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
+	DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
+	DEBUGFS_FWSTATS_ADD(rx, dropped);
+	DEBUGFS_FWSTATS_ADD(rx, fcs_err);
+	DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
+	DEBUGFS_FWSTATS_ADD(rx, path_reset);
+	DEBUGFS_FWSTATS_ADD(rx, reset_counter);
+
+	DEBUGFS_FWSTATS_ADD(dma, rx_requested);
+	DEBUGFS_FWSTATS_ADD(dma, rx_errors);
+	DEBUGFS_FWSTATS_ADD(dma, tx_requested);
+	DEBUGFS_FWSTATS_ADD(dma, tx_errors);
+
+	DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
+	DEBUGFS_FWSTATS_ADD(isr, fiqs);
+	DEBUGFS_FWSTATS_ADD(isr, rx_headers);
+	DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
+	DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
+	DEBUGFS_FWSTATS_ADD(isr, irqs);
+	DEBUGFS_FWSTATS_ADD(isr, tx_procs);
+	DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
+	DEBUGFS_FWSTATS_ADD(isr, dma0_done);
+	DEBUGFS_FWSTATS_ADD(isr, dma1_done);
+	DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
+	DEBUGFS_FWSTATS_ADD(isr, commands);
+	DEBUGFS_FWSTATS_ADD(isr, rx_procs);
+	DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
+	DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
+	DEBUGFS_FWSTATS_ADD(isr, pci_pm);
+	DEBUGFS_FWSTATS_ADD(isr, wakeups);
+	DEBUGFS_FWSTATS_ADD(isr, low_rssi);
+
+	DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
+	DEBUGFS_FWSTATS_ADD(wep, default_key_count);
+	/* skipping wep.reserved */
+	DEBUGFS_FWSTATS_ADD(wep, key_not_found);
+	DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
+	DEBUGFS_FWSTATS_ADD(wep, packets);
+	DEBUGFS_FWSTATS_ADD(wep, interrupt);
+
+	DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
+	DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
+	DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
+	DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
+	DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
+	DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
+	DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
+	DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
+	DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
+	/* skipping cont_miss_bcns_spread for now */
+	DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
+
+	DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
+	DEBUGFS_FWSTATS_ADD(mic, calc_failure);
+
+	DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
+	DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
+	DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
+	DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
+	DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
+	DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
+
+	DEBUGFS_FWSTATS_ADD(event, heart_beat);
+	DEBUGFS_FWSTATS_ADD(event, calibration);
+	DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
+	DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
+	DEBUGFS_FWSTATS_ADD(event, rx_pool);
+	DEBUGFS_FWSTATS_ADD(event, oom_late);
+	DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
+	DEBUGFS_FWSTATS_ADD(event, tx_stuck);
+
+	DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
+	DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
+	DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
+	DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
+
+	DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
+	DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
+	DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+	DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+	DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
+	DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
+
+out:
+	if (ret < 0)
+		wl1271_debugfs_delete_files(wl);
+
+	return ret;
+}
+
+void wl1271_debugfs_reset(struct wl1271 *wl)
+{
+	memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+	wl->stats.retry_count = 0;
+	wl->stats.excessive_retries = 0;
+}
+
+int wl1271_debugfs_init(struct wl1271 *wl)
+{
+	int ret;
+
+	wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+	if (IS_ERR(wl->debugfs.rootdir)) {
+		ret = PTR_ERR(wl->debugfs.rootdir);
+		wl->debugfs.rootdir = NULL;
+		goto err;
+	}
+
+	wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
+						       wl->debugfs.rootdir);
+
+	if (IS_ERR(wl->debugfs.fw_statistics)) {
+		ret = PTR_ERR(wl->debugfs.fw_statistics);
+		wl->debugfs.fw_statistics = NULL;
+		goto err_root;
+	}
+
+	wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
+				      GFP_KERNEL);
+
+	if (!wl->stats.fw_stats) {
+		ret = -ENOMEM;
+		goto err_fw;
+	}
+
+	wl->stats.fw_stats_update = jiffies;
+
+	ret = wl1271_debugfs_add_files(wl);
+
+	if (ret < 0)
+		goto err_file;
+
+	return 0;
+
+err_file:
+	kfree(wl->stats.fw_stats);
+	wl->stats.fw_stats = NULL;
+
+err_fw:
+	debugfs_remove(wl->debugfs.fw_statistics);
+	wl->debugfs.fw_statistics = NULL;
+
+err_root:
+	debugfs_remove(wl->debugfs.rootdir);
+	wl->debugfs.rootdir = NULL;
+
+err:
+	return ret;
+}
+
+void wl1271_debugfs_exit(struct wl1271 *wl)
+{
+	wl1271_debugfs_delete_files(wl);
+
+	kfree(wl->stats.fw_stats);
+	wl->stats.fw_stats = NULL;
+
+	debugfs_remove(wl->debugfs.fw_statistics);
+	wl->debugfs.fw_statistics = NULL;
+
+	debugfs_remove(wl->debugfs.rootdir);
+	wl->debugfs.rootdir = NULL;
+
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.h b/drivers/net/wireless/wl12xx/wl1271_debugfs.h
new file mode 100644
index 0000000..00a45b2
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.h
@@ -0,0 +1,33 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef WL1271_DEBUGFS_H
+#define WL1271_DEBUGFS_H
+
+#include "wl1271.h"
+
+int wl1271_debugfs_init(struct wl1271 *wl);
+void wl1271_debugfs_exit(struct wl1271 *wl);
+void wl1271_debugfs_reset(struct wl1271 *wl);
+
+#endif /* WL1271_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
new file mode 100644
index 0000000..f3afd4a
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -0,0 +1,125 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h"
+#include "wl1271_reg.h"
+#include "wl1271_spi.h"
+#include "wl1271_event.h"
+#include "wl1271_ps.h"
+
+static int wl1271_event_scan_complete(struct wl1271 *wl,
+				      struct event_mailbox *mbox)
+{
+	wl1271_debug(DEBUG_EVENT, "status: 0x%x",
+		     mbox->scheduled_scan_status);
+
+	if (wl->scanning) {
+		mutex_unlock(&wl->mutex);
+		ieee80211_scan_completed(wl->hw, false);
+		mutex_lock(&wl->mutex);
+		wl->scanning = false;
+	}
+
+	return 0;
+}
+
+static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
+{
+	wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
+	wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
+	wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
+}
+
+static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
+{
+	int ret;
+	u32 vector;
+
+	wl1271_event_mbox_dump(mbox);
+
+	vector = mbox->events_vector & ~(mbox->events_mask);
+	wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);
+
+	if (vector & SCAN_COMPLETE_EVENT_ID) {
+		ret = wl1271_event_scan_complete(wl, mbox);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (vector & BSS_LOSE_EVENT_ID) {
+		wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
+
+		if (wl->psm_requested && wl->psm) {
+			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+int wl1271_event_unmask(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+void wl1271_event_mbox_config(struct wl1271 *wl)
+{
+	wl->mbox_ptr[0] = wl1271_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+	wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
+
+	wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
+		     wl->mbox_ptr[0], wl->mbox_ptr[1]);
+}
+
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
+{
+	struct event_mailbox mbox;
+	int ret;
+
+	wl1271_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
+
+	if (mbox_num > 1)
+		return -EINVAL;
+
+	/* first we read the mbox descriptor */
+	wl1271_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+			    sizeof(struct event_mailbox));
+
+	/* process the descriptor */
+	ret = wl1271_event_process(wl, &mbox);
+	if (ret < 0)
+		return ret;
+
+	/* then we let the firmware know it can go on...*/
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+
+	return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h
new file mode 100644
index 0000000..2cdce7c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_event.h
@@ -0,0 +1,110 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_EVENT_H__
+#define __WL1271_EVENT_H__
+
+/*
+ * Mbox events
+ *
+ * The event mechanism is based on a pair of event buffers (buffers A and
+ * B) at fixed locations in the target's memory. The host processes one
+ * buffer while the other buffer continues to collect events. If the host
+ * is not processing events, an interrupt is issued to signal that a buffer
+ * is ready. Once the host is done with processing events from one buffer,
+ * it signals the target (with an ACK interrupt) that the event buffer is
+ * free.
+ */
+
+enum {
+	MEASUREMENT_START_EVENT_ID		 = BIT(8),
+	MEASUREMENT_COMPLETE_EVENT_ID		 = BIT(9),
+	SCAN_COMPLETE_EVENT_ID			 = BIT(10),
+	SCHEDULED_SCAN_COMPLETE_EVENT_ID	 = BIT(11),
+	AP_DISCOVERY_COMPLETE_EVENT_ID		 = BIT(12),
+	PS_REPORT_EVENT_ID			 = BIT(13),
+	PSPOLL_DELIVERY_FAILURE_EVENT_ID	 = BIT(14),
+	DISCONNECT_EVENT_COMPLETE_ID		 = BIT(15),
+	JOIN_EVENT_COMPLETE_ID			 = BIT(16),
+	CHANNEL_SWITCH_COMPLETE_EVENT_ID	 = BIT(17),
+	BSS_LOSE_EVENT_ID			 = BIT(18),
+	REGAINED_BSS_EVENT_ID			 = BIT(19),
+	ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID	 = BIT(20),
+	SOFT_GEMINI_SENSE_EVENT_ID		 = BIT(22),
+	SOFT_GEMINI_PREDICTION_EVENT_ID		 = BIT(23),
+	SOFT_GEMINI_AVALANCHE_EVENT_ID		 = BIT(24),
+	PLT_RX_CALIBRATION_COMPLETE_EVENT_ID	 = BIT(25),
+	DBG_EVENT_ID				 = BIT(26),
+	HEALTH_CHECK_REPLY_EVENT_ID		 = BIT(27),
+	PERIODIC_SCAN_COMPLETE_EVENT_ID		 = BIT(28),
+	PERIODIC_SCAN_REPORT_EVENT_ID		 = BIT(29),
+	BA_SESSION_TEAR_DOWN_EVENT_ID		 = BIT(30),
+	EVENT_MBOX_ALL_EVENT_ID			 = 0x7fffffff,
+};
+
+struct event_debug_report {
+	u8 debug_event_id;
+	u8 num_params;
+	u16 pad;
+	u32 report_1;
+	u32 report_2;
+	u32 report_3;
+} __attribute__ ((packed));
+
+#define NUM_OF_RSSI_SNR_TRIGGERS 8
+
+struct event_mailbox {
+	u32 events_vector;
+	u32 events_mask;
+	u32 reserved_1;
+	u32 reserved_2;
+
+	u8 dbg_event_id;
+	u8 num_relevant_params;
+	u16 reserved_3;
+	u32 event_report_p1;
+	u32 event_report_p2;
+	u32 event_report_p3;
+
+	u8 number_of_scan_results;
+	u8 scan_tag;
+	u8 reserved_4[2];
+	u32 compl_scheduled_scan_status;
+
+	u16 scheduled_scan_attended_channels;
+	u8 soft_gemini_sense_info;
+	u8 soft_gemini_protective_info;
+	s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
+	u8 channel_switch_status;
+	u8 scheduled_scan_status;
+	u8 ps_status;
+
+	u8 reserved_5[29];
+} __attribute__ ((packed));
+
+int wl1271_event_unmask(struct wl1271 *wl);
+void wl1271_event_mbox_config(struct wl1271 *wl);
+int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
new file mode 100644
index 0000000..490df21
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -0,0 +1,397 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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/kernel.h>
+#include <linux/module.h>
+
+#include "wl1271_init.h"
+#include "wl12xx_80211.h"
+#include "wl1271_acx.h"
+#include "wl1271_cmd.h"
+#include "wl1271_reg.h"
+
+static int wl1271_init_hwenc_config(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_feature_cfg(wl);
+	if (ret < 0) {
+		wl1271_warning("couldn't set feature config");
+		return ret;
+	}
+
+	ret = wl1271_cmd_set_default_wep_key(wl, wl->default_key);
+	if (ret < 0) {
+		wl1271_warning("couldn't set default key");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int wl1271_init_templates_config(struct wl1271 *wl)
+{
+	int ret;
+
+	/* send empty templates for fw memory reservation */
+	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL,
+				      sizeof(struct wl12xx_probe_req_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL,
+				      sizeof(struct wl12xx_null_data_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, NULL,
+				      sizeof(struct wl12xx_ps_poll_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, NULL,
+				      sizeof
+				      (struct wl12xx_qos_null_data_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, NULL,
+				      sizeof
+				      (struct wl12xx_probe_resp_template));
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, NULL,
+				      sizeof
+				      (struct wl12xx_beacon_template));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_init_rx_config(struct wl1271 *wl, u32 config, u32 filter)
+{
+	int ret;
+
+	ret = wl1271_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_acx_rx_config(wl, config, filter);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_init_phy_config(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_pd_threshold(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_acx_slot(wl, DEFAULT_SLOT_TIME);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_acx_group_address_tbl(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_acx_service_period_timeout(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_init_beacon_filter(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_beacon_filter_opt(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_acx_beacon_filter_table(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_init_pta(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_sg_enable(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_acx_sg_cfg(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_init_energy_detection(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_cca_threshold(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_init_beacon_broadcast(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_bcn_dtim_options(wl);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_init_general_parms(struct wl1271 *wl)
+{
+	struct wl1271_general_parms *gen_parms;
+	int ret;
+
+	gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
+	if (!gen_parms)
+		return -ENOMEM;
+
+	gen_parms->id = TEST_CMD_INI_FILE_GENERAL_PARAM;
+
+	gen_parms->ref_clk = REF_CLK_38_4_E;
+	/* FIXME: magic numbers */
+	gen_parms->settling_time = 5;
+	gen_parms->clk_valid_on_wakeup = 0;
+	gen_parms->dc2dcmode = 0;
+	gen_parms->single_dual_band = 0;
+	gen_parms->tx_bip_fem_autodetect = 1;
+	gen_parms->tx_bip_fem_manufacturer = 1;
+	gen_parms->settings = 1;
+
+	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
+	if (ret < 0) {
+		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
+		return ret;
+	}
+
+	kfree(gen_parms);
+	return 0;
+}
+
+static int wl1271_init_radio_parms(struct wl1271 *wl)
+{
+	/*
+	 * FIXME: All these magic numbers should be moved to some place where
+	 * they can be configured (separate file?)
+	 */
+
+	struct wl1271_radio_parms *radio_parms;
+	int ret;
+	u8 compensation[] = { 0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8, 0xfc, 0x00,
+			      0x08, 0x10, 0xf0, 0xf8, 0x00, 0x0a, 0x14 };
+
+	u8 tx_rate_limits_normal[]   = { 0x1e, 0x1f, 0x22, 0x24, 0x28, 0x29 };
+	u8 tx_rate_limits_degraded[] = { 0x1b, 0x1c, 0x1e, 0x20, 0x24, 0x25 };
+
+	u8 tx_channel_limits_11b[] = { 0x22, 0x50, 0x50, 0x50,
+				       0x50, 0x50, 0x50, 0x50,
+				       0x50, 0x50, 0x22, 0x50,
+				       0x22, 0x50 };
+
+	u8 tx_channel_limits_ofdm[] = { 0x20, 0x50, 0x50, 0x50,
+					0x50, 0x50, 0x50, 0x50,
+					0x50, 0x50, 0x20, 0x50,
+					0x20, 0x50 };
+
+	u8 tx_pdv_rate_offsets[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+	u8 tx_ibias[] = { 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x27 };
+
+	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
+	if (!radio_parms)
+		return -ENOMEM;
+
+	radio_parms->id = TEST_CMD_INI_FILE_RADIO_PARAM;
+
+	/* Static radio parameters */
+	radio_parms->rx_trace_loss = 10;
+	radio_parms->tx_trace_loss = 10;
+	memcpy(radio_parms->rx_rssi_and_proc_compens, compensation,
+	       sizeof(compensation));
+
+	/* We don't set the 5GHz -- N/A */
+
+	/* Dynamic radio parameters */
+	radio_parms->tx_ref_pd_voltage = cpu_to_le16(0x24e);
+	radio_parms->tx_ref_power = 0x78;
+	radio_parms->tx_offset_db = 0x0;
+
+	memcpy(radio_parms->tx_rate_limits_normal, tx_rate_limits_normal,
+	       sizeof(tx_rate_limits_normal));
+	memcpy(radio_parms->tx_rate_limits_degraded, tx_rate_limits_degraded,
+	       sizeof(tx_rate_limits_degraded));
+
+	memcpy(radio_parms->tx_channel_limits_11b, tx_channel_limits_11b,
+	       sizeof(tx_channel_limits_11b));
+	memcpy(radio_parms->tx_channel_limits_ofdm, tx_channel_limits_ofdm,
+	       sizeof(tx_channel_limits_ofdm));
+	memcpy(radio_parms->tx_pdv_rate_offsets, tx_pdv_rate_offsets,
+	       sizeof(tx_pdv_rate_offsets));
+	memcpy(radio_parms->tx_ibias, tx_ibias,
+	       sizeof(tx_ibias));
+
+	radio_parms->rx_fem_insertion_loss = 0x14;
+
+	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
+	if (ret < 0)
+		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
+
+	kfree(radio_parms);
+	return ret;
+}
+
+int wl1271_hw_init(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_init_general_parms(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_init_radio_parms(wl);
+	if (ret < 0)
+		return ret;
+
+	/* Template settings */
+	ret = wl1271_init_templates_config(wl);
+	if (ret < 0)
+		return ret;
+
+	/* Default memory configuration */
+	ret = wl1271_acx_init_mem_config(wl);
+	if (ret < 0)
+		return ret;
+
+	/* RX config */
+	ret = wl1271_init_rx_config(wl,
+				       RX_CFG_PROMISCUOUS | RX_CFG_TSF,
+				       RX_FILTER_OPTION_DEF);
+	/* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
+	   RX_FILTER_OPTION_FILTER_ALL); */
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* PHY layer config */
+	ret = wl1271_init_phy_config(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Beacon filtering */
+	ret = wl1271_init_beacon_filter(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Configure TX patch complete interrupt behavior */
+	ret = wl1271_acx_tx_config_options(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* RX complete interrupt pacing */
+	ret = wl1271_acx_init_rx_interrupt(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Bluetooth WLAN coexistence */
+	ret = wl1271_init_pta(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Energy detection */
+	ret = wl1271_init_energy_detection(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Beacons and boradcast settings */
+	ret = wl1271_init_beacon_broadcast(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Default fragmentation threshold */
+	ret = wl1271_acx_frag_threshold(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Default TID configuration */
+	ret = wl1271_acx_tid_cfg(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Default AC configuration */
+	ret = wl1271_acx_ac_cfg(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Configure TX rate classes */
+	ret = wl1271_acx_rate_policies(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Enable data path */
+	ret = wl1271_cmd_data_path(wl, wl->channel, 1);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Configure for ELP power saving */
+	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	/* Configure HW encryption */
+	ret = wl1271_init_hwenc_config(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
+	return 0;
+
+ out_free_memmap:
+	kfree(wl->target_mem_map);
+
+	return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.h b/drivers/net/wireless/wl12xx/wl1271_init.h
new file mode 100644
index 0000000..bd8ff0f
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_init.h
@@ -0,0 +1,115 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_INIT_H__
+#define __WL1271_INIT_H__
+
+#include "wl1271.h"
+
+int wl1271_hw_init_power_auth(struct wl1271 *wl);
+int wl1271_hw_init(struct wl1271 *wl);
+
+/* These are not really a TEST_CMD, but the ref driver uses them as such */
+#define TEST_CMD_INI_FILE_RADIO_PARAM   0x19
+#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E
+
+struct wl1271_general_parms {
+	u8 id;
+	u8 padding[3];
+
+	u8 ref_clk;
+	u8 settling_time;
+	u8 clk_valid_on_wakeup;
+	u8 dc2dcmode;
+	u8 single_dual_band;
+
+	u8 tx_bip_fem_autodetect;
+	u8 tx_bip_fem_manufacturer;
+	u8 settings;
+} __attribute__ ((packed));
+
+enum ref_clk_enum {
+	REF_CLK_19_2_E,
+	REF_CLK_26_E,
+	REF_CLK_38_4_E,
+	REF_CLK_52_E
+};
+
+#define RSSI_AND_PROCESS_COMPENSATION_SIZE 15
+#define NUMBER_OF_SUB_BANDS_5  7
+#define NUMBER_OF_RATE_GROUPS  6
+#define NUMBER_OF_CHANNELS_2_4 14
+#define NUMBER_OF_CHANNELS_5   35
+
+struct wl1271_radio_parms {
+	u8 id;
+	u8 padding[3];
+
+	/* Static radio parameters */
+	/* 2.4GHz */
+	u8 rx_trace_loss;
+	u8 tx_trace_loss;
+	s8 rx_rssi_and_proc_compens[RSSI_AND_PROCESS_COMPENSATION_SIZE];
+
+	/* 5GHz */
+	u8 rx_trace_loss_5[NUMBER_OF_SUB_BANDS_5];
+	u8 tx_trace_loss_5[NUMBER_OF_SUB_BANDS_5];
+	s8 rx_rssi_and_proc_compens_5[RSSI_AND_PROCESS_COMPENSATION_SIZE];
+
+	/* Dynamic radio parameters */
+	/* 2.4GHz */
+	s16 tx_ref_pd_voltage;
+	s8  tx_ref_power;
+	s8  tx_offset_db;
+
+	s8  tx_rate_limits_normal[NUMBER_OF_RATE_GROUPS];
+	s8  tx_rate_limits_degraded[NUMBER_OF_RATE_GROUPS];
+
+	s8  tx_channel_limits_11b[NUMBER_OF_CHANNELS_2_4];
+	s8  tx_channel_limits_ofdm[NUMBER_OF_CHANNELS_2_4];
+	s8  tx_pdv_rate_offsets[NUMBER_OF_RATE_GROUPS];
+
+	u8  tx_ibias[NUMBER_OF_RATE_GROUPS];
+	u8  rx_fem_insertion_loss;
+
+	u8 padding2;
+
+	/* 5GHz */
+	s16 tx_ref_pd_voltage_5[NUMBER_OF_SUB_BANDS_5];
+	s8  tx_ref_power_5[NUMBER_OF_SUB_BANDS_5];
+	s8  tx_offset_db_5[NUMBER_OF_SUB_BANDS_5];
+
+	s8  tx_rate_limits_normal_5[NUMBER_OF_RATE_GROUPS];
+	s8  tx_rate_limits_degraded_5[NUMBER_OF_RATE_GROUPS];
+
+	s8  tx_channel_limits_ofdm_5[NUMBER_OF_CHANNELS_5];
+	s8  tx_pdv_rate_offsets_5[NUMBER_OF_RATE_GROUPS];
+
+	/* FIXME: this is inconsistent with the types for 2.4GHz */
+	s8  tx_ibias_5[NUMBER_OF_RATE_GROUPS];
+	s8  rx_fem_insertion_loss_5[NUMBER_OF_SUB_BANDS_5];
+
+	u8 padding3[2];
+} __attribute__ ((packed));
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
new file mode 100644
index 0000000..27298b1
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -0,0 +1,1393 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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/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/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/spi/wl12xx.h>
+
+#include "wl1271.h"
+#include "wl12xx_80211.h"
+#include "wl1271_reg.h"
+#include "wl1271_spi.h"
+#include "wl1271_event.h"
+#include "wl1271_tx.h"
+#include "wl1271_rx.h"
+#include "wl1271_ps.h"
+#include "wl1271_init.h"
+#include "wl1271_debugfs.h"
+#include "wl1271_cmd.h"
+#include "wl1271_boot.h"
+
+static int wl1271_plt_init(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = wl1271_acx_init_mem_config(wl);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_cmd_data_path(wl, wl->channel, 1);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void wl1271_disable_interrupts(struct wl1271 *wl)
+{
+	disable_irq(wl->irq);
+}
+
+static void wl1271_power_off(struct wl1271 *wl)
+{
+	wl->set_power(false);
+}
+
+static void wl1271_power_on(struct wl1271 *wl)
+{
+	wl->set_power(true);
+}
+
+static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status)
+{
+	u32 total = 0;
+	int i;
+
+	/*
+	 * FIXME: Reading the FW status directly from the registers seems to
+	 * be the right thing to do, but it doesn't work.  And in the
+	 * reference driver, there is a workaround called
+	 * USE_SDIO_24M_WORKAROUND, which reads the status from memory
+	 * instead, so we do the same here.
+	 */
+
+	wl1271_spi_mem_read(wl, STATUS_MEM_ADDRESS, status, sizeof(*status));
+
+	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
+		     "drv_rx_counter = %d, tx_results_counter = %d)",
+		     status->intr,
+		     status->fw_rx_counter,
+		     status->drv_rx_counter,
+		     status->tx_results_counter);
+
+	/* update number of available TX blocks */
+	for (i = 0; i < NUM_TX_QUEUES; i++) {
+		u32 cnt = status->tx_released_blks[i] - wl->tx_blocks_freed[i];
+		wl->tx_blocks_freed[i] = status->tx_released_blks[i];
+		wl->tx_blocks_available += cnt;
+		total += cnt;
+	}
+
+	/* if more blocks are available now, schedule some tx work */
+	if (total && !skb_queue_empty(&wl->tx_queue))
+		schedule_work(&wl->tx_work);
+
+	/* update the host-chipset time offset */
+	wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime;
+}
+
+#define WL1271_IRQ_MAX_LOOPS 10
+static void wl1271_irq_work(struct work_struct *work)
+{
+	u32 intr, ctr = WL1271_IRQ_MAX_LOOPS;
+	int ret;
+	struct wl1271 *wl =
+		container_of(work, struct wl1271, irq_work);
+
+	mutex_lock(&wl->mutex);
+
+	wl1271_debug(DEBUG_IRQ, "IRQ work");
+
+	if (wl->state == WL1271_STATE_OFF)
+		goto out;
+
+	ret = wl1271_ps_elp_wakeup(wl, true);
+	if (ret < 0)
+		goto out;
+
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
+
+	intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+	if (!intr) {
+		wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
+		goto out_sleep;
+	}
+
+	intr &= WL1271_INTR_MASK;
+
+	do {
+		wl1271_fw_status(wl, wl->fw_status);
+
+
+		if (intr & (WL1271_ACX_INTR_EVENT_A |
+			    WL1271_ACX_INTR_EVENT_B)) {
+			wl1271_debug(DEBUG_IRQ,
+				     "WL1271_ACX_INTR_EVENT (0x%x)", intr);
+			if (intr & WL1271_ACX_INTR_EVENT_A)
+				wl1271_event_handle(wl, 0);
+			else
+				wl1271_event_handle(wl, 1);
+		}
+
+		if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
+			wl1271_debug(DEBUG_IRQ,
+				     "WL1271_ACX_INTR_INIT_COMPLETE");
+
+		if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
+			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
+
+		if (intr & WL1271_ACX_INTR_DATA) {
+			u8 tx_res_cnt = wl->fw_status->tx_results_counter -
+				wl->tx_results_count;
+
+			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
+
+			/* check for tx results */
+			if (tx_res_cnt)
+				wl1271_tx_complete(wl, tx_res_cnt);
+
+			wl1271_rx(wl, wl->fw_status);
+		}
+
+		intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+		intr &= WL1271_INTR_MASK;
+	} while (intr && --ctr);
+
+out_sleep:
+	wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+			   WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+static irqreturn_t wl1271_irq(int irq, void *cookie)
+{
+	struct wl1271 *wl;
+	unsigned long flags;
+
+	wl1271_debug(DEBUG_IRQ, "IRQ");
+
+	wl = cookie;
+
+	/* complete the ELP completion */
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	if (wl->elp_compl) {
+		complete(wl->elp_compl);
+		wl->elp_compl = NULL;
+	}
+
+	schedule_work(&wl->irq_work);
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static int wl1271_fetch_firmware(struct wl1271 *wl)
+{
+	const struct firmware *fw;
+	int ret;
+
+	ret = request_firmware(&fw, WL1271_FW_NAME, &wl->spi->dev);
+
+	if (ret < 0) {
+		wl1271_error("could not get firmware: %d", ret);
+		return ret;
+	}
+
+	if (fw->size % 4) {
+		wl1271_error("firmware size is not multiple of 32 bits: %zu",
+			     fw->size);
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	wl->fw_len = fw->size;
+	wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
+
+	if (!wl->fw) {
+		wl1271_error("could not allocate memory for the firmware");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(wl->fw, fw->data, wl->fw_len);
+
+	ret = 0;
+
+out:
+	release_firmware(fw);
+
+	return ret;
+}
+
+static int wl1271_fetch_nvs(struct wl1271 *wl)
+{
+	const struct firmware *fw;
+	int ret;
+
+	ret = request_firmware(&fw, WL1271_NVS_NAME, &wl->spi->dev);
+
+	if (ret < 0) {
+		wl1271_error("could not get nvs file: %d", ret);
+		return ret;
+	}
+
+	if (fw->size % 4) {
+		wl1271_error("nvs size is not multiple of 32 bits: %zu",
+			     fw->size);
+		ret = -EILSEQ;
+		goto out;
+	}
+
+	wl->nvs_len = fw->size;
+	wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
+
+	if (!wl->nvs) {
+		wl1271_error("could not allocate memory for the nvs file");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy(wl->nvs, fw->data, wl->nvs_len);
+
+	ret = 0;
+
+out:
+	release_firmware(fw);
+
+	return ret;
+}
+
+static void wl1271_fw_wakeup(struct wl1271 *wl)
+{
+	u32 elp_reg;
+
+	elp_reg = ELPCTRL_WAKE_UP;
+	wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+}
+
+static int wl1271_setup(struct wl1271 *wl)
+{
+	wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL);
+	if (!wl->fw_status)
+		return -ENOMEM;
+
+	wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
+	if (!wl->tx_res_if) {
+		kfree(wl->fw_status);
+		return -ENOMEM;
+	}
+
+	INIT_WORK(&wl->irq_work, wl1271_irq_work);
+	INIT_WORK(&wl->tx_work, wl1271_tx_work);
+	return 0;
+}
+
+static int wl1271_chip_wakeup(struct wl1271 *wl)
+{
+	int ret = 0;
+
+	wl1271_power_on(wl);
+	msleep(WL1271_POWER_ON_SLEEP);
+	wl1271_spi_reset(wl);
+	wl1271_spi_init(wl);
+
+	/* We don't need a real memory partition here, because we only want
+	 * to use the registers at this point. */
+	wl1271_set_partition(wl,
+			     0x00000000,
+			     0x00000000,
+			     REGISTERS_BASE,
+			     REGISTERS_DOWN_SIZE);
+
+	/* ELP module wake up */
+	wl1271_fw_wakeup(wl);
+
+	/* whal_FwCtrl_BootSm() */
+
+	/* 0. read chip id from CHIP_ID */
+	wl->chip.id = wl1271_reg_read32(wl, CHIP_ID_B);
+
+	/* 1. check if chip id is valid */
+
+	switch (wl->chip.id) {
+	case CHIP_ID_1271_PG10:
+		wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
+			       wl->chip.id);
+
+		ret = wl1271_setup(wl);
+		if (ret < 0)
+			goto out;
+		break;
+	case CHIP_ID_1271_PG20:
+		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
+			     wl->chip.id);
+
+		ret = wl1271_setup(wl);
+		if (ret < 0)
+			goto out;
+		break;
+	default:
+		wl1271_error("unsupported chip id: 0x%x", wl->chip.id);
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (wl->fw == NULL) {
+		ret = wl1271_fetch_firmware(wl);
+		if (ret < 0)
+			goto out;
+	}
+
+	/* No NVS from netlink, try to get it from the filesystem */
+	if (wl->nvs == NULL) {
+		ret = wl1271_fetch_nvs(wl);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void wl1271_filter_work(struct work_struct *work)
+{
+	struct wl1271 *wl =
+		container_of(work, struct wl1271, filter_work);
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	if (wl->state == WL1271_STATE_OFF)
+		goto out;
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	/* FIXME: replace the magic numbers with proper definitions */
+	ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
+	if (ret < 0)
+		goto out_sleep;
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+int wl1271_plt_start(struct wl1271 *wl)
+{
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	wl1271_notice("power up");
+
+	if (wl->state != WL1271_STATE_OFF) {
+		wl1271_error("cannot go into PLT state because not "
+			     "in off state: %d", wl->state);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl->state = WL1271_STATE_PLT;
+
+	ret = wl1271_chip_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1271_boot(wl);
+	if (ret < 0)
+		goto out;
+
+	wl1271_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
+
+	ret = wl1271_plt_init(wl);
+	if (ret < 0)
+		goto out;
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+int wl1271_plt_stop(struct wl1271 *wl)
+{
+	int ret = 0;
+
+	mutex_lock(&wl->mutex);
+
+	wl1271_notice("power down");
+
+	if (wl->state != WL1271_STATE_PLT) {
+		wl1271_error("cannot power down because not in PLT "
+			     "state: %d", wl->state);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	wl1271_disable_interrupts(wl);
+	wl1271_power_off(wl);
+
+	wl->state = WL1271_STATE_OFF;
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+
+static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+	struct wl1271 *wl = hw->priv;
+
+	skb_queue_tail(&wl->tx_queue, skb);
+
+	/*
+	 * The chip specific setup must run before the first TX packet -
+	 * before that, the tx_work will not be initialized!
+	 */
+
+	schedule_work(&wl->tx_work);
+
+	/*
+	 * The workqueue is slow to process the tx_queue and we need stop
+	 * the queue here, otherwise the queue will get too long.
+	 */
+	if (skb_queue_len(&wl->tx_queue) >= WL1271_TX_QUEUE_MAX_LENGTH) {
+		ieee80211_stop_queues(wl->hw);
+
+		/*
+		 * FIXME: this is racy, the variable is not properly
+		 * protected. Maybe fix this by removing the stupid
+		 * variable altogether and checking the real queue state?
+		 */
+		wl->tx_queue_stopped = true;
+	}
+
+	return NETDEV_TX_OK;
+}
+
+static int wl1271_op_start(struct ieee80211_hw *hw)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 start");
+
+	mutex_lock(&wl->mutex);
+
+	if (wl->state != WL1271_STATE_OFF) {
+		wl1271_error("cannot start because not in off state: %d",
+			     wl->state);
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = wl1271_chip_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1271_boot(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1271_hw_init(wl);
+	if (ret < 0)
+		goto out;
+
+	wl->state = WL1271_STATE_ON;
+
+	wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
+
+out:
+	if (ret < 0)
+		wl1271_power_off(wl);
+
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+static void wl1271_op_stop(struct ieee80211_hw *hw)
+{
+	struct wl1271 *wl = hw->priv;
+	int i;
+
+	wl1271_info("down");
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
+
+	mutex_lock(&wl->mutex);
+
+	WARN_ON(wl->state != WL1271_STATE_ON);
+
+	if (wl->scanning) {
+		mutex_unlock(&wl->mutex);
+		ieee80211_scan_completed(wl->hw, true);
+		mutex_lock(&wl->mutex);
+		wl->scanning = false;
+	}
+
+	wl->state = WL1271_STATE_OFF;
+
+	wl1271_disable_interrupts(wl);
+
+	mutex_unlock(&wl->mutex);
+
+	cancel_work_sync(&wl->irq_work);
+	cancel_work_sync(&wl->tx_work);
+	cancel_work_sync(&wl->filter_work);
+
+	mutex_lock(&wl->mutex);
+
+	/* let's notify MAC80211 about the remaining pending TX frames */
+	wl1271_tx_flush(wl);
+	wl1271_power_off(wl);
+
+	memset(wl->bssid, 0, ETH_ALEN);
+	memset(wl->ssid, 0, IW_ESSID_MAX_SIZE + 1);
+	wl->ssid_len = 0;
+	wl->listen_int = 1;
+	wl->bss_type = MAX_BSS_TYPE;
+
+	wl->rx_counter = 0;
+	wl->elp = false;
+	wl->psm = 0;
+	wl->tx_queue_stopped = false;
+	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
+	wl->tx_blocks_available = 0;
+	wl->tx_results_count = 0;
+	wl->tx_packets_count = 0;
+	wl->time_offset = 0;
+	wl->session_counter = 0;
+	for (i = 0; i < NUM_TX_QUEUES; i++)
+		wl->tx_blocks_freed[i] = 0;
+
+	wl1271_debugfs_reset(wl);
+	mutex_unlock(&wl->mutex);
+}
+
+static int wl1271_op_add_interface(struct ieee80211_hw *hw,
+				   struct ieee80211_if_init_conf *conf)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
+		     conf->type, conf->mac_addr);
+
+	mutex_lock(&wl->mutex);
+
+	switch (conf->type) {
+	case NL80211_IFTYPE_STATION:
+		wl->bss_type = BSS_TYPE_STA_BSS;
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		wl->bss_type = BSS_TYPE_IBSS;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* FIXME: what if conf->mac_addr changes? */
+
+out:
+	mutex_unlock(&wl->mutex);
+	return ret;
+}
+
+static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
+					 struct ieee80211_if_init_conf *conf)
+{
+	wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
+}
+
+#if 0
+static int wl1271_op_config_interface(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif,
+				      struct ieee80211_if_conf *conf)
+{
+	struct wl1271 *wl = hw->priv;
+	struct sk_buff *beacon;
+	int ret;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM",
+		     conf->bssid);
+	wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid,
+			  conf->ssid_len);
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+
+	ret = wl1271_cmd_build_null_data(wl);
+	if (ret < 0)
+		goto out_sleep;
+
+	wl->ssid_len = conf->ssid_len;
+	if (wl->ssid_len)
+		memcpy(wl->ssid, conf->ssid, wl->ssid_len);
+
+	if (wl->bss_type != BSS_TYPE_IBSS) {
+		/* FIXME: replace the magic numbers with proper definitions */
+		ret = wl1271_cmd_join(wl, wl->bss_type, 5, 100, 1);
+		if (ret < 0)
+			goto out_sleep;
+	}
+
+	if (conf->changed & IEEE80211_IFCC_BEACON) {
+		beacon = ieee80211_beacon_get(hw, vif);
+		ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,
+					      beacon->data, beacon->len);
+
+		if (ret < 0) {
+			dev_kfree_skb(beacon);
+			goto out_sleep;
+		}
+
+		ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE,
+					      beacon->data, beacon->len);
+
+		dev_kfree_skb(beacon);
+
+		if (ret < 0)
+			goto out_sleep;
+
+		/* FIXME: replace the magic numbers with proper definitions */
+		ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
+
+		if (ret < 0)
+			goto out_sleep;
+	}
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+#endif
+
+static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+	struct wl1271 *wl = hw->priv;
+	struct ieee80211_conf *conf = &hw->conf;
+	int channel, ret = 0;
+
+	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+		     channel,
+		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
+		     conf->power_level);
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	if (channel != wl->channel) {
+		u8 old_channel = wl->channel;
+		wl->channel = channel;
+
+		/* FIXME: use beacon interval provided by mac80211 */
+		ret = wl1271_cmd_join(wl, wl->bss_type, 1, 100, 0);
+		if (ret < 0) {
+			wl->channel = old_channel;
+			goto out_sleep;
+		}
+	}
+
+	ret = wl1271_cmd_build_null_data(wl);
+	if (ret < 0)
+		goto out_sleep;
+
+	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
+		wl1271_info("psm enabled");
+
+		wl->psm_requested = true;
+
+		/*
+		 * We enter PSM only if we're already associated.
+		 * If we're not, we'll enter it when joining an SSID,
+		 * through the bss_info_changed() hook.
+		 */
+		ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
+		   wl->psm_requested) {
+		wl1271_info("psm disabled");
+
+		wl->psm_requested = false;
+
+		if (wl->psm)
+			ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);
+	}
+
+	if (conf->power_level != wl->power_level) {
+		ret = wl1271_acx_tx_power(wl, conf->power_level);
+		if (ret < 0)
+			goto out;
+
+		wl->power_level = conf->power_level;
+	}
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
+				  FIF_ALLMULTI | \
+				  FIF_FCSFAIL | \
+				  FIF_BCN_PRBRESP_PROMISC | \
+				  FIF_CONTROL | \
+				  FIF_OTHER_BSS)
+
+static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
+				       unsigned int changed,
+				       unsigned int *total,u64 multicast)
+{
+	struct wl1271 *wl = hw->priv;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter");
+
+	*total &= WL1271_SUPPORTED_FILTERS;
+	changed &= WL1271_SUPPORTED_FILTERS;
+
+	if (changed == 0)
+		return;
+
+	/* FIXME: wl->rx_config and wl->rx_filter are not protected */
+	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
+	wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
+
+	/*
+	 * FIXME: workqueues need to be properly cancelled on stop(), for
+	 * now let's just disable changing the filter settings. They will
+	 * be updated any on config().
+	 */
+	/* schedule_work(&wl->filter_work); */
+}
+
+static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_sta *sta,
+			     struct ieee80211_key_conf *key_conf)
+{
+	struct wl1271 *wl = hw->priv;
+	const u8 *addr;
+	int ret;
+	u8 key_type;
+
+	static const u8 bcast_addr[ETH_ALEN] =
+		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 set key");
+
+	addr = sta ? sta->addr : bcast_addr;
+
+	wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
+	wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
+	wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
+		     key_conf->alg, key_conf->keyidx,
+		     key_conf->keylen, key_conf->flags);
+	wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);
+
+	if (is_zero_ether_addr(addr)) {
+		/* We dont support TX only encryption */
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out_unlock;
+
+	switch (key_conf->alg) {
+	case ALG_WEP:
+		key_type = KEY_WEP;
+
+		key_conf->hw_key_idx = key_conf->keyidx;
+		break;
+	case ALG_TKIP:
+		key_type = KEY_TKIP;
+
+		key_conf->hw_key_idx = key_conf->keyidx;
+		break;
+	case ALG_CCMP:
+		key_type = KEY_AES;
+
+		key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+		break;
+	default:
+		wl1271_error("Unknown key algo 0x%x", key_conf->alg);
+
+		ret = -EOPNOTSUPP;
+		goto out_sleep;
+	}
+
+	switch (cmd) {
+	case SET_KEY:
+		ret = wl1271_cmd_set_key(wl, KEY_ADD_OR_REPLACE,
+					 key_conf->keyidx, key_type,
+					 key_conf->keylen, key_conf->key,
+					 addr);
+		if (ret < 0) {
+			wl1271_error("Could not add or replace key");
+			goto out_sleep;
+		}
+		break;
+
+	case DISABLE_KEY:
+		ret = wl1271_cmd_set_key(wl, KEY_REMOVE,
+					 key_conf->keyidx, key_type,
+					 key_conf->keylen, key_conf->key,
+					 addr);
+		if (ret < 0) {
+			wl1271_error("Could not remove key");
+			goto out_sleep;
+		}
+		break;
+
+	default:
+		wl1271_error("Unsupported key cmd 0x%x", cmd);
+		ret = -EOPNOTSUPP;
+		goto out_sleep;
+
+		break;
+	}
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out_unlock:
+	mutex_unlock(&wl->mutex);
+
+out:
+	return ret;
+}
+
+static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
+			     struct cfg80211_scan_request *req)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret;
+	u8 *ssid = NULL;
+	size_t ssid_len = 0;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan");
+
+	if (req->n_ssids) {
+		ssid = req->ssids[0].ssid;
+		ssid_len = req->ssids[0].ssid_len;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1271_cmd_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
+
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1271_acx_rts_threshold(wl, (u16) value);
+	if (ret < 0)
+		wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret);
+
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
+static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_bss_conf *bss_conf,
+				       u32 changed)
+{
+	enum wl1271_cmd_ps_mode mode;
+	struct wl1271 *wl = hw->priv;
+	int ret;
+
+	wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	if (changed & BSS_CHANGED_ASSOC) {
+		if (bss_conf->assoc) {
+			wl->aid = bss_conf->aid;
+
+			ret = wl1271_cmd_build_ps_poll(wl, wl->aid);
+			if (ret < 0)
+				goto out_sleep;
+
+			ret = wl1271_acx_aid(wl, wl->aid);
+			if (ret < 0)
+				goto out_sleep;
+
+			/* If we want to go in PSM but we're not there yet */
+			if (wl->psm_requested && !wl->psm) {
+				mode = STATION_POWER_SAVE_MODE;
+				ret = wl1271_ps_set_mode(wl, mode);
+				if (ret < 0)
+					goto out_sleep;
+			}
+		}
+	}
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		if (bss_conf->use_short_slot)
+			ret = wl1271_acx_slot(wl, SLOT_TIME_SHORT);
+		else
+			ret = wl1271_acx_slot(wl, SLOT_TIME_LONG);
+		if (ret < 0) {
+			wl1271_warning("Set slot time failed %d", ret);
+			goto out_sleep;
+		}
+	}
+
+	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+		if (bss_conf->use_short_preamble)
+			wl1271_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
+		else
+			wl1271_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
+	}
+
+	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+		if (bss_conf->use_cts_prot)
+			ret = wl1271_acx_cts_protect(wl, CTSPROTECT_ENABLE);
+		else
+			ret = wl1271_acx_cts_protect(wl, CTSPROTECT_DISABLE);
+		if (ret < 0) {
+			wl1271_warning("Set ctsprotect failed %d", ret);
+			goto out_sleep;
+		}
+	}
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate wl1271_rates[] = {
+	{ .bitrate = 10,
+	  .hw_value = 0x1,
+	  .hw_value_short = 0x1, },
+	{ .bitrate = 20,
+	  .hw_value = 0x2,
+	  .hw_value_short = 0x2,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 55,
+	  .hw_value = 0x4,
+	  .hw_value_short = 0x4,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 110,
+	  .hw_value = 0x20,
+	  .hw_value_short = 0x20,
+	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+	{ .bitrate = 60,
+	  .hw_value = 0x8,
+	  .hw_value_short = 0x8, },
+	{ .bitrate = 90,
+	  .hw_value = 0x10,
+	  .hw_value_short = 0x10, },
+	{ .bitrate = 120,
+	  .hw_value = 0x40,
+	  .hw_value_short = 0x40, },
+	{ .bitrate = 180,
+	  .hw_value = 0x80,
+	  .hw_value_short = 0x80, },
+	{ .bitrate = 240,
+	  .hw_value = 0x200,
+	  .hw_value_short = 0x200, },
+	{ .bitrate = 360,
+	 .hw_value = 0x400,
+	 .hw_value_short = 0x400, },
+	{ .bitrate = 480,
+	  .hw_value = 0x800,
+	  .hw_value_short = 0x800, },
+	{ .bitrate = 540,
+	  .hw_value = 0x1000,
+	  .hw_value_short = 0x1000, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel wl1271_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 wl1271_band_2ghz = {
+	.channels = wl1271_channels,
+	.n_channels = ARRAY_SIZE(wl1271_channels),
+	.bitrates = wl1271_rates,
+	.n_bitrates = ARRAY_SIZE(wl1271_rates),
+};
+
+static const struct ieee80211_ops wl1271_ops = {
+	.start = wl1271_op_start,
+	.stop = wl1271_op_stop,
+	.add_interface = wl1271_op_add_interface,
+	.remove_interface = wl1271_op_remove_interface,
+	.config = wl1271_op_config,
+/* 	.config_interface = wl1271_op_config_interface, */
+	.configure_filter = wl1271_op_configure_filter,
+	.tx = wl1271_op_tx,
+	.set_key = wl1271_op_set_key,
+	.hw_scan = wl1271_op_hw_scan,
+	.bss_info_changed = wl1271_op_bss_info_changed,
+	.set_rts_threshold = wl1271_op_set_rts_threshold,
+};
+
+static int wl1271_register_hw(struct wl1271 *wl)
+{
+	int ret;
+
+	if (wl->mac80211_registered)
+		return 0;
+
+	SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+	ret = ieee80211_register_hw(wl->hw);
+	if (ret < 0) {
+		wl1271_error("unable to register mac80211 hw: %d", ret);
+		return ret;
+	}
+
+	wl->mac80211_registered = true;
+
+	wl1271_notice("loaded");
+
+	return 0;
+}
+
+static int wl1271_init_ieee80211(struct wl1271 *wl)
+{
+	/*
+	 * The tx descriptor buffer and the TKIP space.
+	 *
+	 * FIXME: add correct 1271 descriptor size
+	 */
+	wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE;
+
+	/* unit us */
+	/* FIXME: find a proper value */
+	wl->hw->channel_change_time = 10000;
+
+	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
+		IEEE80211_HW_NOISE_DBM;
+
+	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+	wl->hw->wiphy->max_scan_ssids = 1;
+	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz;
+
+	SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
+
+	return 0;
+}
+
+static void wl1271_device_release(struct device *dev)
+{
+
+}
+
+static struct platform_device wl1271_device = {
+	.name           = "wl1271",
+	.id             = -1,
+
+	/* device model insists to have a release function */
+	.dev            = {
+		.release = wl1271_device_release,
+	},
+};
+
+#define WL1271_DEFAULT_CHANNEL 0
+static int __devinit wl1271_probe(struct spi_device *spi)
+{
+	struct wl12xx_platform_data *pdata;
+	struct ieee80211_hw *hw;
+	struct wl1271 *wl;
+	int ret, i;
+	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
+
+	pdata = spi->dev.platform_data;
+	if (!pdata) {
+		wl1271_error("no platform data");
+		return -ENODEV;
+	}
+
+	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
+	if (!hw) {
+		wl1271_error("could not alloc ieee80211_hw");
+		return -ENOMEM;
+	}
+
+	wl = hw->priv;
+	memset(wl, 0, sizeof(*wl));
+
+	wl->hw = hw;
+	dev_set_drvdata(&spi->dev, wl);
+	wl->spi = spi;
+
+	skb_queue_head_init(&wl->tx_queue);
+
+	INIT_WORK(&wl->filter_work, wl1271_filter_work);
+	wl->channel = WL1271_DEFAULT_CHANNEL;
+	wl->scanning = false;
+	wl->default_key = 0;
+	wl->listen_int = 1;
+	wl->rx_counter = 0;
+	wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
+	wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
+	wl->elp = false;
+	wl->psm = 0;
+	wl->psm_requested = false;
+	wl->tx_queue_stopped = false;
+	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
+
+	/* We use the default power on sleep time until we know which chip
+	 * we're using */
+	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+		wl->tx_frames[i] = NULL;
+
+	spin_lock_init(&wl->wl_lock);
+
+	/*
+	 * In case our MAC address is not correctly set,
+	 * we use a random but Nokia MAC.
+	 */
+	memcpy(wl->mac_addr, nokia_oui, 3);
+	get_random_bytes(wl->mac_addr + 3, 3);
+
+	wl->state = WL1271_STATE_OFF;
+	mutex_init(&wl->mutex);
+
+	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
+	if (!wl->rx_descriptor) {
+		wl1271_error("could not allocate memory for rx descriptor");
+		ret = -ENOMEM;
+		goto out_free;
+	}
+
+	/* This is the only SPI value that we need to set here, the rest
+	 * comes from the board-peripherals file */
+	spi->bits_per_word = 32;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		wl1271_error("spi_setup failed");
+		goto out_free;
+	}
+
+	wl->set_power = pdata->set_power;
+	if (!wl->set_power) {
+		wl1271_error("set power function missing in platform data");
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	wl->irq = spi->irq;
+	if (wl->irq < 0) {
+		wl1271_error("irq missing in platform data");
+		ret = -ENODEV;
+		goto out_free;
+	}
+
+	ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
+	if (ret < 0) {
+		wl1271_error("request_irq() failed: %d", ret);
+		goto out_free;
+	}
+
+	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+	disable_irq(wl->irq);
+
+	ret = platform_device_register(&wl1271_device);
+	if (ret) {
+		wl1271_error("couldn't register platform device");
+		goto out_irq;
+	}
+	dev_set_drvdata(&wl1271_device.dev, wl);
+
+	ret = wl1271_init_ieee80211(wl);
+	if (ret)
+		goto out_platform;
+
+	ret = wl1271_register_hw(wl);
+	if (ret)
+		goto out_platform;
+
+	wl1271_debugfs_init(wl);
+
+	wl1271_notice("initialized");
+
+	return 0;
+
+ out_platform:
+	platform_device_unregister(&wl1271_device);
+
+ out_irq:
+	free_irq(wl->irq, wl);
+
+ out_free:
+	kfree(wl->rx_descriptor);
+	wl->rx_descriptor = NULL;
+
+	ieee80211_free_hw(hw);
+
+	return ret;
+}
+
+static int __devexit wl1271_remove(struct spi_device *spi)
+{
+	struct wl1271 *wl = dev_get_drvdata(&spi->dev);
+
+	ieee80211_unregister_hw(wl->hw);
+
+	wl1271_debugfs_exit(wl);
+	platform_device_unregister(&wl1271_device);
+	free_irq(wl->irq, wl);
+	kfree(wl->target_mem_map);
+	kfree(wl->fw);
+	wl->fw = NULL;
+	kfree(wl->nvs);
+	wl->nvs = NULL;
+
+	kfree(wl->rx_descriptor);
+	wl->rx_descriptor = NULL;
+
+	kfree(wl->fw_status);
+	kfree(wl->tx_res_if);
+
+	ieee80211_free_hw(wl->hw);
+
+	return 0;
+}
+
+
+static struct spi_driver wl1271_spi_driver = {
+	.driver = {
+		.name		= "wl1271",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+	},
+
+	.probe		= wl1271_probe,
+	.remove		= __devexit_p(wl1271_remove),
+};
+
+static int __init wl1271_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&wl1271_spi_driver);
+	if (ret < 0) {
+		wl1271_error("failed to register spi driver: %d", ret);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit wl1271_exit(void)
+{
+	spi_unregister_driver(&wl1271_spi_driver);
+
+	wl1271_notice("unloaded");
+}
+
+module_init(wl1271_init);
+module_exit(wl1271_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
new file mode 100644
index 0000000..1dc74b0
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -0,0 +1,142 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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 "wl1271_reg.h"
+#include "wl1271_ps.h"
+#include "wl1271_spi.h"
+
+#define WL1271_WAKEUP_TIMEOUT 500
+
+/* Routines to toggle sleep mode while in ELP */
+void wl1271_ps_elp_sleep(struct wl1271 *wl)
+{
+	/*
+	 * FIXME: due to a problem in the firmware (causing a firmware
+	 * crash), ELP entry is prevented below. Remove the "true" to
+	 * re-enable ELP entry.
+	 */
+	if (true || wl->elp || !wl->psm)
+		return;
+
+	/*
+	 * Go to ELP unless there is work already pending - pending work
+	 * will immediately wakeup the chipset anyway.
+	 */
+	if (!work_pending(&wl->irq_work) && !work_pending(&wl->tx_work)) {
+		wl1271_debug(DEBUG_PSM, "chip to elp");
+		wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+		wl->elp = true;
+	}
+}
+
+int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
+{
+	DECLARE_COMPLETION_ONSTACK(compl);
+	unsigned long flags;
+	int ret;
+	u32 start_time = jiffies;
+	bool pending = false;
+
+	if (!wl->elp)
+		return 0;
+
+	wl1271_debug(DEBUG_PSM, "waking up chip from elp");
+
+	/*
+	 * The spinlock is required here to synchronize both the work and
+	 * the completion variable in one entity.
+	 */
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	if (work_pending(&wl->irq_work) || chip_awake)
+		pending = true;
+	else
+		wl->elp_compl = &compl;
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+	wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+
+	if (!pending) {
+		ret = wait_for_completion_timeout(
+			&compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
+		if (ret == 0) {
+			wl1271_error("ELP wakeup timeout!");
+			ret = -ETIMEDOUT;
+			goto err;
+		} else if (ret < 0) {
+			wl1271_error("ELP wakeup completion error.");
+			goto err;
+		}
+	}
+
+	wl->elp = false;
+
+	wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
+		     jiffies_to_msecs(jiffies - start_time));
+	goto out;
+
+err:
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	wl->elp_compl = NULL;
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+	return ret;
+
+out:
+	return 0;
+}
+
+int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)
+{
+	int ret;
+
+	switch (mode) {
+	case STATION_POWER_SAVE_MODE:
+		wl1271_debug(DEBUG_PSM, "entering psm");
+		ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+		if (ret < 0)
+			return ret;
+
+		wl1271_ps_elp_sleep(wl);
+		if (ret < 0)
+			return ret;
+
+		wl->psm = 1;
+		break;
+	case STATION_ACTIVE_MODE:
+	default:
+		wl1271_debug(DEBUG_PSM, "leaving psm");
+		ret = wl1271_ps_elp_wakeup(wl, false);
+		if (ret < 0)
+			return ret;
+
+		ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+		if (ret < 0)
+			return ret;
+
+		wl->psm = 0;
+		break;
+	}
+
+	return ret;
+}
+
+
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
new file mode 100644
index 0000000..de2bd3c
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_PS_H__
+#define __WL1271_PS_H__
+
+#include "wl1271.h"
+#include "wl1271_acx.h"
+
+int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode);
+void wl1271_ps_elp_sleep(struct wl1271 *wl);
+int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
+
+
+#endif /* __WL1271_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h
new file mode 100644
index 0000000..f8ed4a4
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_reg.h
@@ -0,0 +1,758 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __REG_H__
+#define __REG_H__
+
+#include <linux/bitops.h>
+
+#define REGISTERS_BASE 0x00300000
+#define DRPW_BASE      0x00310000
+
+#define REGISTERS_DOWN_SIZE 0x00008800
+#define REGISTERS_WORK_SIZE 0x0000b000
+
+#define HW_ACCESS_ELP_CTRL_REG_ADDR         0x1FFFC
+#define STATUS_MEM_ADDRESS                  0x40400
+
+/* ELP register commands */
+#define ELPCTRL_WAKE_UP             0x1
+#define ELPCTRL_WAKE_UP_WLAN_READY  0x5
+#define ELPCTRL_SLEEP               0x0
+/* ELP WLAN_READY bit */
+#define ELPCTRL_WLAN_READY          0x2
+
+/*===============================================
+   Host Software Reset - 32bit RW
+ ------------------------------------------
+    [31:1] Reserved
+    0  SOFT_RESET Soft Reset  - When this bit is set,
+    it holds the Wlan hardware in a soft reset state.
+    This reset disables all MAC and baseband processor
+    clocks except the CardBus/PCI interface clock.
+    It also initializes all MAC state machines except
+    the host interface. It does not reload the
+    contents of the EEPROM. When this bit is cleared
+    (not self-clearing), the Wlan hardware
+    exits the software reset state.
+===============================================*/
+#define ACX_REG_SLV_SOFT_RESET         (REGISTERS_BASE + 0x0000)
+
+#define WL1271_SLV_REG_DATA            (REGISTERS_BASE + 0x0008)
+#define WL1271_SLV_REG_ADATA           (REGISTERS_BASE + 0x000c)
+#define WL1271_SLV_MEM_DATA            (REGISTERS_BASE + 0x0018)
+/*
+ * Interrupt registers.
+ * 64 bit interrupt sources registers ws ced.
+ * sme interupts were removed and new ones were added.
+ * Order was changed.
+ */
+#define FIQ_MASK                       (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_L                     (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_H                     (REGISTERS_BASE + 0x0404)
+#define FIQ_MASK_SET                   (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_L                 (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_H                 (REGISTERS_BASE + 0x040C)
+#define FIQ_MASK_CLR                   (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_H                 (REGISTERS_BASE + 0x0414)
+#define IRQ_MASK                       (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_L                     (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_H                     (REGISTERS_BASE + 0x041C)
+#define IRQ_MASK_SET                   (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_L                 (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_H                 (REGISTERS_BASE + 0x0424)
+#define IRQ_MASK_CLR                   (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_H                 (REGISTERS_BASE + 0x042C)
+#define ECPU_MASK                      (REGISTERS_BASE + 0x0448)
+#define FIQ_STS_L                      (REGISTERS_BASE + 0x044C)
+#define FIQ_STS_H                      (REGISTERS_BASE + 0x0450)
+#define IRQ_STS_L                      (REGISTERS_BASE + 0x0454)
+#define IRQ_STS_H                      (REGISTERS_BASE + 0x0458)
+#define INT_STS_ND                     (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_L                  (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_H                  (REGISTERS_BASE + 0x0468)
+#define INT_STS_CLR                    (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_L                  (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_H                  (REGISTERS_BASE + 0x04B8)
+#define INT_ACK                        (REGISTERS_BASE + 0x046C)
+#define INT_ACK_L                      (REGISTERS_BASE + 0x046C)
+#define INT_ACK_H                      (REGISTERS_BASE + 0x0470)
+#define INT_TRIG                       (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_L                     (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_H                     (REGISTERS_BASE + 0x0478)
+#define HOST_STS_L                     (REGISTERS_BASE + 0x045C)
+#define HOST_STS_H                     (REGISTERS_BASE + 0x0460)
+#define HOST_MASK                      (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_L                    (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_H                    (REGISTERS_BASE + 0x0434)
+#define HOST_MASK_SET                  (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_L                (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_H                (REGISTERS_BASE + 0x043C)
+#define HOST_MASK_CLR                  (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_L                (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_H                (REGISTERS_BASE + 0x0444)
+
+#define ACX_REG_INTERRUPT_TRIG         (REGISTERS_BASE + 0x0474)
+#define ACX_REG_INTERRUPT_TRIG_H       (REGISTERS_BASE + 0x0478)
+
+/* Host Interrupts*/
+#define HINT_MASK                      (REGISTERS_BASE + 0x0494)
+#define HINT_MASK_SET                  (REGISTERS_BASE + 0x0498)
+#define HINT_MASK_CLR                  (REGISTERS_BASE + 0x049C)
+#define HINT_STS_ND_MASKED             (REGISTERS_BASE + 0x04A0)
+/*1150 spec calls this HINT_STS_RAW*/
+#define HINT_STS_ND		       (REGISTERS_BASE + 0x04B0)
+#define HINT_STS_CLR                   (REGISTERS_BASE + 0x04A4)
+#define HINT_ACK                       (REGISTERS_BASE + 0x04A8)
+#define HINT_TRIG                      (REGISTERS_BASE + 0x04AC)
+
+/*=============================================
+  Host Interrupt Mask Register - 32bit (RW)
+  ------------------------------------------
+  Setting a bit in this register masks the
+  corresponding interrupt to the host.
+  0 - RX0		- Rx first dubble buffer Data Interrupt
+  1 - TXD		- Tx Data Interrupt
+  2 - TXXFR		- Tx Transfer Interrupt
+  3 - RX1		- Rx second dubble buffer Data Interrupt
+  4 - RXXFR		- Rx Transfer Interrupt
+  5 - EVENT_A	- Event Mailbox interrupt
+  6 - EVENT_B	- Event Mailbox interrupt
+  7 - WNONHST	- Wake On Host Interrupt
+  8 - TRACE_A	- Debug Trace interrupt
+  9 - TRACE_B	- Debug Trace interrupt
+ 10 - CDCMP		- Command Complete Interrupt
+ 11 -
+ 12 -
+ 13 -
+ 14 - ICOMP		- Initialization Complete Interrupt
+ 16 - SG SE		- Soft Gemini - Sense enable interrupt
+ 17 - SG SD		- Soft Gemini - Sense disable interrupt
+ 18 -			-
+ 19 -			-
+ 20 -			-
+ 21-			-
+ Default: 0x0001
+*==============================================*/
+#define ACX_REG_INTERRUPT_MASK         (REGISTERS_BASE + 0x04DC)
+
+/*=============================================
+  Host Interrupt Mask Set 16bit, (Write only)
+  ------------------------------------------
+ Setting a bit in this register sets
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+==============================================*/
+#define ACX_REG_HINT_MASK_SET          (REGISTERS_BASE + 0x04E0)
+
+/*=============================================
+  Host Interrupt Mask Clear 16bit,(Write only)
+  ------------------------------------------
+ Setting a bit in this register clears
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+=============================================*/
+#define ACX_REG_HINT_MASK_CLR          (REGISTERS_BASE + 0x04E4)
+
+/*=============================================
+  Host Interrupt Status Nondestructive Read
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register doesn't
+ effect its content.
+=============================================*/
+#define ACX_REG_INTERRUPT_NO_CLEAR     (REGISTERS_BASE + 0x04E8)
+
+/*=============================================
+  Host Interrupt Status Clear on Read  Register
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register clears it,
+ thus making all interrupts inactive.
+==============================================*/
+#define ACX_REG_INTERRUPT_CLEAR        (REGISTERS_BASE + 0x04F8)
+
+/*=============================================
+  Host Interrupt Acknowledge Register
+  16bit,(Write only)
+  ------------------------------------------
+ The host can set individual bits in this
+ register to clear (acknowledge) the corresp.
+ interrupt status bits in the HINT_STS_CLR and
+ HINT_STS_ND registers, thus making the
+ assotiated interrupt inactive. (0-no effect)
+==============================================*/
+#define ACX_REG_INTERRUPT_ACK          (REGISTERS_BASE + 0x04F0)
+
+#define RX_DRIVER_DUMMY_WRITE_ADDRESS  (REGISTERS_BASE + 0x0534)
+#define RX_DRIVER_COUNTER_ADDRESS      (REGISTERS_BASE + 0x0538)
+
+/* Device Configuration registers*/
+#define SOR_CFG                        (REGISTERS_BASE + 0x0800)
+
+/* Embedded ARM CPU Control */
+
+/*===============================================
+ Halt eCPU   - 32bit RW
+ ------------------------------------------
+ 0 HALT_ECPU Halt Embedded CPU - This bit is the
+ compliment of bit 1 (MDATA2) in the SOR_CFG register.
+ During a hardware reset, this bit holds
+ the inverse of MDATA2.
+ When downloading firmware from the host,
+ set this bit (pull down MDATA2).
+ The host clears this bit after downloading the firmware into
+ zero-wait-state SSRAM.
+ When loading firmware from Flash, clear this bit (pull up MDATA2)
+ so that the eCPU can run the bootloader code in Flash
+ HALT_ECPU eCPU State
+ --------------------
+ 1 halt eCPU
+ 0 enable eCPU
+ ===============================================*/
+#define ACX_REG_ECPU_CONTROL           (REGISTERS_BASE + 0x0804)
+
+#define HI_CFG                         (REGISTERS_BASE + 0x0808)
+
+/*===============================================
+ EEPROM Burst Read Start  - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0  ACX_EE_START -  EEPROM Burst Read Start 0
+ Setting this bit starts a burst read from
+ the external EEPROM.
+ If this bit is set (after reset) before an EEPROM read/write,
+ the burst read starts at EEPROM address 0.
+ Otherwise, it starts at the address
+ following the address of the previous access.
+ TheWlan hardware hardware clears this bit automatically.
+
+ Default: 0x00000000
+*================================================*/
+#define ACX_REG_EE_START               (REGISTERS_BASE + 0x080C)
+
+#define OCP_POR_CTR                    (REGISTERS_BASE + 0x09B4)
+#define OCP_DATA_WRITE                 (REGISTERS_BASE + 0x09B8)
+#define OCP_DATA_READ                  (REGISTERS_BASE + 0x09BC)
+#define OCP_CMD                        (REGISTERS_BASE + 0x09C0)
+
+#define WL1271_HOST_WR_ACCESS          (REGISTERS_BASE + 0x09F8)
+
+#define CHIP_ID_B                      (REGISTERS_BASE + 0x5674)
+
+#define CHIP_ID_1271_PG10              (0x4030101)
+#define CHIP_ID_1271_PG20              (0x4030111)
+
+#define ENABLE                         (REGISTERS_BASE + 0x5450)
+
+/* Power Management registers */
+#define ELP_CFG_MODE                   (REGISTERS_BASE + 0x5804)
+#define ELP_CMD                        (REGISTERS_BASE + 0x5808)
+#define PLL_CAL_TIME                   (REGISTERS_BASE + 0x5810)
+#define CLK_REQ_TIME                   (REGISTERS_BASE + 0x5814)
+#define CLK_BUF_TIME                   (REGISTERS_BASE + 0x5818)
+
+#define CFG_PLL_SYNC_CNT               (REGISTERS_BASE + 0x5820)
+
+/* Scratch Pad registers*/
+#define SCR_PAD0                       (REGISTERS_BASE + 0x5608)
+#define SCR_PAD1                       (REGISTERS_BASE + 0x560C)
+#define SCR_PAD2                       (REGISTERS_BASE + 0x5610)
+#define SCR_PAD3                       (REGISTERS_BASE + 0x5614)
+#define SCR_PAD4                       (REGISTERS_BASE + 0x5618)
+#define SCR_PAD4_SET                   (REGISTERS_BASE + 0x561C)
+#define SCR_PAD4_CLR                   (REGISTERS_BASE + 0x5620)
+#define SCR_PAD5                       (REGISTERS_BASE + 0x5624)
+#define SCR_PAD5_SET                   (REGISTERS_BASE + 0x5628)
+#define SCR_PAD5_CLR                   (REGISTERS_BASE + 0x562C)
+#define SCR_PAD6                       (REGISTERS_BASE + 0x5630)
+#define SCR_PAD7                       (REGISTERS_BASE + 0x5634)
+#define SCR_PAD8                       (REGISTERS_BASE + 0x5638)
+#define SCR_PAD9                       (REGISTERS_BASE + 0x563C)
+
+/* Spare registers*/
+#define SPARE_A1                       (REGISTERS_BASE + 0x0994)
+#define SPARE_A2                       (REGISTERS_BASE + 0x0998)
+#define SPARE_A3                       (REGISTERS_BASE + 0x099C)
+#define SPARE_A4                       (REGISTERS_BASE + 0x09A0)
+#define SPARE_A5                       (REGISTERS_BASE + 0x09A4)
+#define SPARE_A6                       (REGISTERS_BASE + 0x09A8)
+#define SPARE_A7                       (REGISTERS_BASE + 0x09AC)
+#define SPARE_A8                       (REGISTERS_BASE + 0x09B0)
+#define SPARE_B1                       (REGISTERS_BASE + 0x5420)
+#define SPARE_B2                       (REGISTERS_BASE + 0x5424)
+#define SPARE_B3                       (REGISTERS_BASE + 0x5428)
+#define SPARE_B4                       (REGISTERS_BASE + 0x542C)
+#define SPARE_B5                       (REGISTERS_BASE + 0x5430)
+#define SPARE_B6                       (REGISTERS_BASE + 0x5434)
+#define SPARE_B7                       (REGISTERS_BASE + 0x5438)
+#define SPARE_B8                       (REGISTERS_BASE + 0x543C)
+
+#define PLL_PARAMETERS                 (REGISTERS_BASE + 0x6040)
+#define WU_COUNTER_PAUSE               (REGISTERS_BASE + 0x6008)
+#define WELP_ARM_COMMAND               (REGISTERS_BASE + 0x6100)
+#define DRPW_SCRATCH_START             (DRPW_BASE + 0x002C)
+
+
+#define ACX_SLV_SOFT_RESET_BIT   BIT(1)
+#define ACX_REG_EEPROM_START_BIT BIT(1)
+
+/* Command/Information Mailbox Pointers */
+
+/*===============================================
+  Command Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the command mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to
+ find the location of the command mailbox.
+ The Wlan hardware initializes the command mailbox
+ pointer with the default address of the command mailbox.
+ The command mailbox pointer is not valid until after
+ the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_COMMAND_MAILBOX_PTR				(SCR_PAD0)
+
+/*===============================================
+  Information Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the information mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to find
+ the location of the information mailbox.
+ The Wlan hardware initializes the information mailbox pointer
+ with the default address of the information mailbox.
+ The information mailbox pointer is not valid
+ until after the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_EVENT_MAILBOX_PTR				(SCR_PAD1)
+
+
+/* Misc */
+
+#define REG_ENABLE_TX_RX				(ENABLE)
+/*
+ * Rx configuration (filter) information element
+ * ---------------------------------------------
+ */
+#define REG_RX_CONFIG				(RX_CFG)
+#define REG_RX_FILTER				(RX_FILTER_CFG)
+
+
+#define RX_CFG_ENABLE_PHY_HEADER_PLCP	 0x0002
+
+/* promiscuous - receives all valid frames */
+#define RX_CFG_PROMISCUOUS		 0x0008
+
+/* receives frames from any BSSID */
+#define RX_CFG_BSSID			 0x0020
+
+/* receives frames destined to any MAC address */
+#define RX_CFG_MAC			 0x0010
+
+#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC	 0x0010
+#define RX_CFG_ENABLE_ANY_DEST_MAC	 0x0000
+#define RX_CFG_ENABLE_ONLY_MY_BSSID	 0x0020
+#define RX_CFG_ENABLE_ANY_BSSID		 0x0000
+
+/* discards all broadcast frames */
+#define RX_CFG_DISABLE_BCAST		 0x0200
+
+#define RX_CFG_ENABLE_ONLY_MY_SSID	 0x0400
+#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
+#define RX_CFG_COPY_RX_STATUS		 0x2000
+#define RX_CFG_TSF			 0x10000
+
+#define RX_CONFIG_OPTION_ANY_DST_MY_BSS	 (RX_CFG_ENABLE_ANY_DEST_MAC | \
+					  RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_ANY_BSS	 (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+					  | RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+					  RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_MY_BSS	 (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+					  | RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_FOR_SCAN  (RX_CFG_ENABLE_PHY_HEADER_PLCP \
+				    | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
+				    | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
+
+#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_JOIN	 (RX_CFG_ENABLE_ONLY_MY_BSSID | \
+					  RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_IBSS_JOIN   (RX_CFG_ENABLE_ONLY_MY_SSID | \
+					  RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_FILTER_OPTION_DEF	      (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+				       | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
+				       | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
+
+#define RX_FILTER_OPTION_FILTER_ALL	 0
+
+#define RX_FILTER_OPTION_DEF_PRSP_BCN  (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
+					| CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
+
+#define RX_FILTER_OPTION_JOIN	     (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+				      | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
+				      | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
+				      | CFG_RX_PRSP_EN)
+
+
+/*===============================================
+  Phy regs
+ ===============================================*/
+#define ACX_PHY_ADDR_REG                SBB_ADDR
+#define ACX_PHY_DATA_REG                SBB_DATA
+#define ACX_PHY_CTRL_REG                SBB_CTL
+#define ACX_PHY_REG_WR_MASK             0x00000001ul
+#define ACX_PHY_REG_RD_MASK             0x00000002ul
+
+
+/*===============================================
+ EEPROM Read/Write Request 32bit RW
+ ------------------------------------------
+ 1 EE_READ - EEPROM Read Request 1 - Setting this bit
+ loads a single byte of data into the EE_DATA
+ register from the EEPROM location specified in
+ the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+ EE_DATA is valid when this bit is cleared.
+
+ 0 EE_WRITE  - EEPROM Write Request  - Setting this bit
+ writes a single byte of data from the EE_DATA register into the
+ EEPROM location specified in the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+*===============================================*/
+#define ACX_EE_CTL_REG                      EE_CTL
+#define EE_WRITE                            0x00000001ul
+#define EE_READ                             0x00000002ul
+
+/*===============================================
+  EEPROM Address  - 32bit RW
+  ------------------------------------------
+  This register specifies the address
+  within the EEPROM from/to which to read/write data.
+  ===============================================*/
+#define ACX_EE_ADDR_REG                     EE_ADDR
+
+/*===============================================
+  EEPROM Data  - 32bit RW
+  ------------------------------------------
+  This register either holds the read 8 bits of
+  data from the EEPROM or the write data
+  to be written to the EEPROM.
+  ===============================================*/
+#define ACX_EE_DATA_REG                     EE_DATA
+
+/*===============================================
+  EEPROM Base Address  - 32bit RW
+  ------------------------------------------
+  This register holds the upper nine bits
+  [23:15] of the 24-bit Wlan hardware memory
+  address for burst reads from EEPROM accesses.
+  The EEPROM provides the lower 15 bits of this address.
+  The MSB of the address from the EEPROM is ignored.
+  ===============================================*/
+#define ACX_EE_CFG                          EE_CFG
+
+/*===============================================
+  GPIO Output Values  -32bit, RW
+  ------------------------------------------
+  [31:16]  Reserved
+  [15: 0]  Specify the output values (at the output driver inputs) for
+  GPIO[15:0], respectively.
+  ===============================================*/
+#define ACX_GPIO_OUT_REG            GPIO_OUT
+#define ACX_MAX_GPIO_LINES          15
+
+/*===============================================
+  Contention window  -32bit, RW
+  ------------------------------------------
+  [31:26]  Reserved
+  [25:16]  Max (0x3ff)
+  [15:07]  Reserved
+  [06:00]  Current contention window value - default is 0x1F
+  ===============================================*/
+#define ACX_CONT_WIND_CFG_REG    CONT_WIND_CFG
+#define ACX_CONT_WIND_MIN_MASK   0x0000007f
+#define ACX_CONT_WIND_MAX        0x03ff0000
+
+/*
+ * Indirect slave register/memory registers
+ * ----------------------------------------
+ */
+#define HW_SLAVE_REG_ADDR_REG		0x00000004
+#define HW_SLAVE_REG_DATA_REG		0x00000008
+#define HW_SLAVE_REG_CTRL_REG		0x0000000c
+
+#define SLAVE_AUTO_INC				0x00010000
+#define SLAVE_NO_AUTO_INC			0x00000000
+#define SLAVE_HOST_LITTLE_ENDIAN	0x00000000
+
+#define HW_SLAVE_MEM_ADDR_REG		SLV_MEM_ADDR
+#define HW_SLAVE_MEM_DATA_REG		SLV_MEM_DATA
+#define HW_SLAVE_MEM_CTRL_REG		SLV_MEM_CTL
+#define HW_SLAVE_MEM_ENDIAN_REG		SLV_END_CTL
+
+#define HW_FUNC_EVENT_INT_EN		0x8000
+#define HW_FUNC_EVENT_MASK_REG		0x00000034
+
+#define ACX_MAC_TIMESTAMP_REG	(MAC_TIMESTAMP)
+
+/*===============================================
+  HI_CFG Interface Configuration Register Values
+  ------------------------------------------
+  ===============================================*/
+#define HI_CFG_UART_ENABLE          0x00000004
+#define HI_CFG_RST232_ENABLE        0x00000008
+#define HI_CFG_CLOCK_REQ_SELECT     0x00000010
+#define HI_CFG_HOST_INT_ENABLE      0x00000020
+#define HI_CFG_VLYNQ_OUTPUT_ENABLE  0x00000040
+#define HI_CFG_HOST_INT_ACTIVE_LOW  0x00000080
+#define HI_CFG_UART_TX_OUT_GPIO_15  0x00000100
+#define HI_CFG_UART_TX_OUT_GPIO_14  0x00000200
+#define HI_CFG_UART_TX_OUT_GPIO_7   0x00000400
+
+/*
+ * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
+ *       for platforms using active high interrupt level
+ */
+#ifdef USE_ACTIVE_HIGH
+#define HI_CFG_DEF_VAL              \
+	(HI_CFG_UART_ENABLE |        \
+	HI_CFG_RST232_ENABLE |      \
+	HI_CFG_CLOCK_REQ_SELECT |   \
+	HI_CFG_HOST_INT_ENABLE)
+#else
+#define HI_CFG_DEF_VAL              \
+	(HI_CFG_UART_ENABLE |        \
+	HI_CFG_RST232_ENABLE |      \
+	HI_CFG_CLOCK_REQ_SELECT |   \
+	HI_CFG_HOST_INT_ENABLE)
+
+#endif
+
+#define REF_FREQ_19_2                       0
+#define REF_FREQ_26_0                       1
+#define REF_FREQ_38_4                       2
+#define REF_FREQ_40_0                       3
+#define REF_FREQ_33_6                       4
+#define REF_FREQ_NUM                        5
+
+#define LUT_PARAM_INTEGER_DIVIDER           0
+#define LUT_PARAM_FRACTIONAL_DIVIDER        1
+#define LUT_PARAM_ATTN_BB                   2
+#define LUT_PARAM_ALPHA_BB                  3
+#define LUT_PARAM_STOP_TIME_BB              4
+#define LUT_PARAM_BB_PLL_LOOP_FILTER        5
+#define LUT_PARAM_NUM                       6
+
+#define ACX_EEPROMLESS_IND_REG              (SCR_PAD4)
+#define USE_EEPROM                          0
+#define SOFT_RESET_MAX_TIME                 1000000
+#define SOFT_RESET_STALL_TIME               1000
+#define NVS_DATA_BUNDARY_ALIGNMENT          4
+
+
+/* Firmware image load chunk size */
+#define CHUNK_SIZE          512
+
+/* Firmware image header size */
+#define FW_HDR_SIZE 8
+
+#define ECPU_CONTROL_HALT					0x00000101
+
+
+/******************************************************************************
+
+    CHANNELS, BAND & REG DOMAINS definitions
+
+******************************************************************************/
+
+
+enum {
+	RADIO_BAND_2_4GHZ = 0,  /* 2.4 Ghz band */
+	RADIO_BAND_5GHZ = 1,    /* 5 Ghz band */
+	RADIO_BAND_JAPAN_4_9_GHZ = 2,
+	DEFAULT_BAND = RADIO_BAND_2_4GHZ,
+	INVALID_BAND = 0xFE,
+	MAX_RADIO_BANDS = 0xFF
+};
+
+enum {
+	NO_RATE      = 0,
+	RATE_1MBPS   = 0x0A,
+	RATE_2MBPS   = 0x14,
+	RATE_5_5MBPS = 0x37,
+	RATE_6MBPS   = 0x0B,
+	RATE_9MBPS   = 0x0F,
+	RATE_11MBPS  = 0x6E,
+	RATE_12MBPS  = 0x0A,
+	RATE_18MBPS  = 0x0E,
+	RATE_22MBPS  = 0xDC,
+	RATE_24MBPS  = 0x09,
+	RATE_36MBPS  = 0x0D,
+	RATE_48MBPS  = 0x08,
+	RATE_54MBPS  = 0x0C
+};
+
+enum {
+	RATE_INDEX_1MBPS   =  0,
+	RATE_INDEX_2MBPS   =  1,
+	RATE_INDEX_5_5MBPS =  2,
+	RATE_INDEX_6MBPS   =  3,
+	RATE_INDEX_9MBPS   =  4,
+	RATE_INDEX_11MBPS  =  5,
+	RATE_INDEX_12MBPS  =  6,
+	RATE_INDEX_18MBPS  =  7,
+	RATE_INDEX_22MBPS  =  8,
+	RATE_INDEX_24MBPS  =  9,
+	RATE_INDEX_36MBPS  =  10,
+	RATE_INDEX_48MBPS  =  11,
+	RATE_INDEX_54MBPS  =  12,
+	RATE_INDEX_MAX     =  RATE_INDEX_54MBPS,
+	MAX_RATE_INDEX,
+	INVALID_RATE_INDEX = MAX_RATE_INDEX,
+	RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
+};
+
+enum {
+	RATE_MASK_1MBPS = 0x1,
+	RATE_MASK_2MBPS = 0x2,
+	RATE_MASK_5_5MBPS = 0x4,
+	RATE_MASK_11MBPS = 0x20,
+};
+
+#define SHORT_PREAMBLE_BIT   BIT(0) /* CCK or Barker depending on the rate */
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+enum {
+	CCK_LONG = 0,
+	CCK_SHORT = SHORT_PREAMBLE_BIT,
+	PBCC_LONG = PBCC_RATE_BIT,
+	PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
+	OFDM = OFDM_RATE_BIT
+};
+
+/******************************************************************************
+
+Transmit-Descriptor RATE-SET field definitions...
+
+Define a new "Rate-Set" for TX path that incorporates the
+Rate & Modulation info into a single 16-bit field.
+
+TxdRateSet_t:
+b15   - Indicates Preamble type (1=SHORT, 0=LONG).
+	Notes:
+	Must be LONG (0) for 1Mbps rate.
+	Does not apply (set to 0) for RevG-OFDM rates.
+b14   - Indicates PBCC encoding (1=PBCC, 0=not).
+	Notes:
+	Does not apply (set to 0) for rates 1 and 2 Mbps.
+	Does not apply (set to 0) for RevG-OFDM rates.
+b13    - Unused (set to 0).
+b12-b0 - Supported Rate indicator bits as defined below.
+
+******************************************************************************/
+
+
+#define TNETW1251_CHIP_ID_PG1_0         0x07010101
+#define TNETW1251_CHIP_ID_PG1_1         0x07020101
+#define TNETW1251_CHIP_ID_PG1_2	        0x07030101
+
+/*************************************************************************
+
+    Interrupt Trigger Register (Host -> WiLink)
+
+**************************************************************************/
+
+/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
+
+/*
+ * Host Command Interrupt. Setting this bit masks
+ * the interrupt that the host issues to inform
+ * the FW that it has sent a command
+ * to the Wlan hardware Command Mailbox.
+ */
+#define INTR_TRIG_CMD       BIT(0)
+
+/*
+ * Host Event Acknowlegde Interrupt. The host
+ * sets this bit to acknowledge that it received
+ * the unsolicited information from the event
+ * mailbox.
+ */
+#define INTR_TRIG_EVENT_ACK BIT(1)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * FW that a TX packet is in the XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_TX_PROC0 BIT(2)
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_RX_PROC0 BIT(3)
+
+#define INTR_TRIG_DEBUG_ACK BIT(4)
+
+#define INTR_TRIG_STATE_CHANGED BIT(5)
+
+
+/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_RX_PROC1 BIT(17)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * hardware that a TX packet is in the XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_TX_PROC1 BIT(18)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
new file mode 100644
index 0000000..ad8b690
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -0,0 +1,200 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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 "wl1271.h"
+#include "wl1271_acx.h"
+#include "wl1271_reg.h"
+#include "wl1271_rx.h"
+#include "wl1271_spi.h"
+
+static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status,
+				  u32 drv_rx_counter)
+{
+	return status->rx_pkt_descs[drv_rx_counter] & RX_MEM_BLOCK_MASK;
+}
+
+static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status,
+				 u32 drv_rx_counter)
+{
+	return (status->rx_pkt_descs[drv_rx_counter] & RX_BUF_SIZE_MASK) >>
+		RX_BUF_SIZE_SHIFT_DIV;
+}
+
+/* The values of this table must match the wl1271_rates[] array */
+static u8 wl1271_rx_rate_to_idx[] = {
+	/* MCS rates are used only with 11n */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS7 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS6 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS5 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS4 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS3 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS2 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS1 */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_MCS0 */
+
+	11,                         /* WL1271_RATE_54   */
+	10,                         /* WL1271_RATE_48   */
+	9,                          /* WL1271_RATE_36   */
+	8,                          /* WL1271_RATE_24   */
+
+	/* TI-specific rate */
+	WL1271_RX_RATE_UNSUPPORTED, /* WL1271_RATE_22   */
+
+	7,                          /* WL1271_RATE_18   */
+	6,                          /* WL1271_RATE_12   */
+	3,                          /* WL1271_RATE_11   */
+	5,                          /* WL1271_RATE_9    */
+	4,                          /* WL1271_RATE_6    */
+	2,                          /* WL1271_RATE_5_5  */
+	1,                          /* WL1271_RATE_2    */
+	0                           /* WL1271_RATE_1    */
+};
+
+static void wl1271_rx_status(struct wl1271 *wl,
+			     struct wl1271_rx_descriptor *desc,
+			     struct ieee80211_rx_status *status,
+			     u8 beacon)
+{
+	memset(status, 0, sizeof(struct ieee80211_rx_status));
+
+	if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
+		status->band = IEEE80211_BAND_2GHZ;
+	else
+		wl1271_warning("unsupported band 0x%x",
+			       desc->flags & WL1271_RX_DESC_BAND_MASK);
+
+	/*
+	 * FIXME: Add mactime handling.  For IBSS (ad-hoc) we need to get the
+	 * timestamp from the beacon (acx_tsf_info).  In BSS mode (infra) we
+	 * only need the mactime for monitor mode.  For now the mactime is
+	 * not valid, so RX_FLAG_TSFT should not be set
+	 */
+	status->signal = desc->rssi;
+
+	/* FIXME: Should this be optimized? */
+	status->qual = (desc->rssi - WL1271_RX_MIN_RSSI) * 100 /
+		(WL1271_RX_MAX_RSSI - WL1271_RX_MIN_RSSI);
+	status->qual = min(status->qual, 100);
+	status->qual = max(status->qual, 0);
+
+	/*
+	 * FIXME: In wl1251, the SNR should be divided by two.  In wl1271 we
+	 * need to divide by two for now, but TI has been discussing about
+	 * changing it.  This needs to be rechecked.
+	 */
+	status->noise = desc->rssi - (desc->snr >> 1);
+
+	status->freq = ieee80211_channel_to_frequency(desc->channel);
+
+	if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
+		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+
+		if (likely(!(desc->flags & WL1271_RX_DESC_DECRYPT_FAIL)))
+			status->flag |= RX_FLAG_DECRYPTED;
+
+		if (unlikely(desc->flags & WL1271_RX_DESC_MIC_FAIL))
+			status->flag |= RX_FLAG_MMIC_ERROR;
+	}
+
+	status->rate_idx = wl1271_rx_rate_to_idx[desc->rate];
+
+	if (status->rate_idx == WL1271_RX_RATE_UNSUPPORTED)
+		wl1271_warning("unsupported rate");
+}
+
+static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length)
+{
+	struct ieee80211_rx_status rx_status;
+	struct wl1271_rx_descriptor *desc;
+	struct sk_buff *skb;
+	u16 *fc;
+	u8 *buf;
+	u8 beacon = 0;
+
+	skb = dev_alloc_skb(length);
+	if (!skb) {
+		wl1271_error("Couldn't allocate RX frame");
+		return;
+	}
+
+	buf = skb_put(skb, length);
+	wl1271_spi_reg_read(wl, WL1271_SLV_MEM_DATA, buf, length, true);
+
+	/* the data read starts with the descriptor */
+	desc = (struct wl1271_rx_descriptor *) buf;
+
+	/* now we pull the descriptor out of the buffer */
+	skb_pull(skb, sizeof(*desc));
+
+	fc = (u16 *)skb->data;
+	if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
+		beacon = 1;
+
+	wl1271_rx_status(wl, desc, &rx_status, beacon);
+
+	wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+		     beacon ? "beacon" : "");
+
+	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+	ieee80211_rx(wl->hw, skb);
+}
+
+void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
+{
+	struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
+	u32 buf_size;
+	u32 fw_rx_counter  = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+	u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+	u32 mem_block;
+
+	while (drv_rx_counter != fw_rx_counter) {
+		mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
+		buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter);
+
+		if (buf_size == 0) {
+			wl1271_warning("received empty data");
+			break;
+		}
+
+		wl->rx_mem_pool_addr.addr =
+			(mem_block << 8) + wl_mem_map->packet_memory_pool_start;
+		wl->rx_mem_pool_addr.addr_extra =
+			wl->rx_mem_pool_addr.addr + 4;
+
+		/* Choose the block we want to read */
+		wl1271_spi_reg_write(wl, WL1271_SLV_REG_DATA,
+				     &wl->rx_mem_pool_addr,
+				     sizeof(wl->rx_mem_pool_addr), false);
+
+		wl1271_rx_handle_data(wl, buf_size);
+
+		wl->rx_counter++;
+		drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
+	}
+
+	wl1271_reg_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);
+
+	/* This is a workaround for some problems in the chip */
+	wl1271_reg_write32(wl, RX_DRIVER_DUMMY_WRITE_ADDRESS, 0x1);
+
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.h b/drivers/net/wireless/wl12xx/wl1271_rx.h
new file mode 100644
index 0000000..d1ca60e
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.h
@@ -0,0 +1,121 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_RX_H__
+#define __WL1271_RX_H__
+
+#include <linux/bitops.h>
+
+#define WL1271_RX_MAX_RSSI -30
+#define WL1271_RX_MIN_RSSI -95
+
+#define WL1271_RX_ALIGN_TO 4
+#define WL1271_RX_ALIGN(len) (((len) + WL1271_RX_ALIGN_TO - 1) & \
+			     ~(WL1271_RX_ALIGN_TO - 1))
+
+#define SHORT_PREAMBLE_BIT   BIT(0)
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+#define PLCP_HEADER_LENGTH 8
+#define RX_DESC_PACKETID_SHIFT 11
+#define RX_MAX_PACKET_ID 3
+
+#define NUM_RX_PKT_DESC_MOD_MASK   7
+#define WL1271_RX_RATE_UNSUPPORTED 0xFF
+
+#define RX_DESC_VALID_FCS         0x0001
+#define RX_DESC_MATCH_RXADDR1     0x0002
+#define RX_DESC_MCAST             0x0004
+#define RX_DESC_STAINTIM          0x0008
+#define RX_DESC_VIRTUAL_BM        0x0010
+#define RX_DESC_BCAST             0x0020
+#define RX_DESC_MATCH_SSID        0x0040
+#define RX_DESC_MATCH_BSSID       0x0080
+#define RX_DESC_ENCRYPTION_MASK   0x0300
+#define RX_DESC_MEASURMENT        0x0400
+#define RX_DESC_SEQNUM_MASK       0x1800
+#define	RX_DESC_MIC_FAIL	  0x2000
+#define	RX_DESC_DECRYPT_FAIL	  0x4000
+
+/*
+ * RX Descriptor flags:
+ *
+ * Bits 0-1 - band
+ * Bit  2   - STBC
+ * Bit  3   - A-MPDU
+ * Bit  4   - HT
+ * Bits 5-7 - encryption
+ */
+#define WL1271_RX_DESC_BAND_MASK    0x03
+#define WL1271_RX_DESC_ENCRYPT_MASK 0xE0
+
+#define WL1271_RX_DESC_BAND_BG      0x00
+#define WL1271_RX_DESC_BAND_J       0x01
+#define WL1271_RX_DESC_BAND_A       0x02
+
+#define WL1271_RX_DESC_STBC         BIT(2)
+#define WL1271_RX_DESC_A_MPDU       BIT(3)
+#define WL1271_RX_DESC_HT           BIT(4)
+
+#define WL1271_RX_DESC_ENCRYPT_WEP  0x20
+#define WL1271_RX_DESC_ENCRYPT_TKIP 0x40
+#define WL1271_RX_DESC_ENCRYPT_AES  0x60
+#define WL1271_RX_DESC_ENCRYPT_GEM  0x80
+
+/*
+ * RX Descriptor status
+ *
+ * Bits 0-2 - status
+ * Bits 3-7 - reserved
+ */
+#define WL1271_RX_DESC_STATUS_MASK      0x07
+
+#define WL1271_RX_DESC_SUCCESS          0x00
+#define WL1271_RX_DESC_DECRYPT_FAIL     0x01
+#define WL1271_RX_DESC_MIC_FAIL         0x02
+#define WL1271_RX_DESC_DRIVER_RX_Q_FAIL 0x03
+
+#define RX_MEM_BLOCK_MASK     0xFF
+#define RX_BUF_SIZE_MASK      0xFFF00
+#define RX_BUF_SIZE_SHIFT_DIV 6
+
+struct wl1271_rx_descriptor {
+	u16 length;
+	u8  status;
+	u8  flags;
+	u8  rate;
+	u8  channel;
+	s8  rssi;
+	u8  snr;
+	u32 timestamp;
+	u8  packet_class;
+	u8  process_id;
+	u8  pad_len;
+	u8  reserved;
+} __attribute__ ((packed));
+
+void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
new file mode 100644
index 0000000..4a12880
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -0,0 +1,382 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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/module.h>
+#include <linux/platform_device.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl1271.h"
+#include "wl12xx_80211.h"
+#include "wl1271_spi.h"
+
+static int wl1271_translate_reg_addr(struct wl1271 *wl, int addr)
+{
+	return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
+}
+
+static int wl1271_translate_mem_addr(struct wl1271 *wl, int addr)
+{
+	return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+}
+
+
+void wl1271_spi_reset(struct wl1271 *wl)
+{
+	u8 *cmd;
+	struct spi_transfer t;
+	struct spi_message m;
+
+	cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+	if (!cmd) {
+		wl1271_error("could not allocate cmd for spi reset");
+		return;
+	}
+
+	memset(&t, 0, sizeof(t));
+	spi_message_init(&m);
+
+	memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
+
+	t.tx_buf = cmd;
+	t.len = WSPI_INIT_CMD_LEN;
+	spi_message_add_tail(&t, &m);
+
+	spi_sync(wl->spi, &m);
+
+	wl1271_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+void wl1271_spi_init(struct wl1271 *wl)
+{
+	u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
+	struct spi_transfer t;
+	struct spi_message m;
+
+	cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+	if (!cmd) {
+		wl1271_error("could not allocate cmd for spi init");
+		return;
+	}
+
+	memset(crc, 0, sizeof(crc));
+	memset(&t, 0, sizeof(t));
+	spi_message_init(&m);
+
+	/*
+	 * Set WSPI_INIT_COMMAND
+	 * the data is being send from the MSB to LSB
+	 */
+	cmd[2] = 0xff;
+	cmd[3] = 0xff;
+	cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
+	cmd[0] = 0;
+	cmd[7] = 0;
+	cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
+	cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
+
+	if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
+		cmd[5] |=  WSPI_INIT_CMD_DIS_FIXEDBUSY;
+	else
+		cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
+
+	cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
+		| WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
+
+	crc[0] = cmd[1];
+	crc[1] = cmd[0];
+	crc[2] = cmd[7];
+	crc[3] = cmd[6];
+	crc[4] = cmd[5];
+
+	cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
+	cmd[4] |= WSPI_INIT_CMD_END;
+
+	t.tx_buf = cmd;
+	t.len = WSPI_INIT_CMD_LEN;
+	spi_message_add_tail(&t, &m);
+
+	spi_sync(wl->spi, &m);
+
+	wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+/* Set the SPI partitions to access the chip addresses
+ *
+ * There are two VIRTUAL (SPI) partitions (the memory partition and the
+ * registers partition), which are mapped to two different areas of the
+ * PHYSICAL (hardware) memory.  This function also makes other checks to
+ * ensure that the partitions are not overlapping.  In the diagram below, the
+ * memory partition comes before the register partition, but the opposite is
+ * also supported.
+ *
+ *                               PHYSICAL address
+ *                                     space
+ *
+ *                                    |    |
+ *                                 ...+----+--> mem_start
+ *          VIRTUAL address     ...   |    |
+ *               space       ...      |    | [PART_0]
+ *                        ...         |    |
+ * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
+ *               |    |         ...   |    |
+ *               |MEM |      ...      |    |
+ *               |    |   ...         |    |
+ *  part_size <--+----+...            |    | {unused area)
+ *               |    |   ...         |    |
+ *               |REG |      ...      |    |
+ *  part_size    |    |         ...   |    |
+ *      +     <--+----+...         ...+----+--> reg_start
+ *  reg_size              ...         |    |
+ *                           ...      |    | [PART_1]
+ *                              ...   |    |
+ *                                 ...+----+--> reg_start + reg_size
+ *                                    |    |
+ *
+ */
+int wl1271_set_partition(struct wl1271 *wl,
+			  u32 mem_start, u32 mem_size,
+			  u32 reg_start, u32 reg_size)
+{
+	struct wl1271_partition *partition;
+	struct spi_transfer t;
+	struct spi_message m;
+	size_t len, cmd_len;
+	u32 *cmd;
+	int addr;
+
+	cmd_len = sizeof(u32) + 2 * sizeof(struct wl1271_partition);
+	cmd = kzalloc(cmd_len, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	spi_message_init(&m);
+	memset(&t, 0, sizeof(t));
+
+	partition = (struct wl1271_partition *) (cmd + 1);
+	addr = HW_ACCESS_PART0_SIZE_ADDR;
+	len = 2 * sizeof(struct wl1271_partition);
+
+	*cmd |= WSPI_CMD_WRITE;
+	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+	wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+		     mem_start, mem_size);
+	wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+		     reg_start, reg_size);
+
+	/* Make sure that the two partitions together don't exceed the
+	 * address range */
+	if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
+		wl1271_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
+			     " address range.  Truncating partition[0].");
+		mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
+		wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	}
+
+	if ((mem_start < reg_start) &&
+	    ((mem_start + mem_size) > reg_start)) {
+		/* Guarantee that the memory partition doesn't overlap the
+		 * registers partition */
+		wl1271_debug(DEBUG_SPI, "End of partition[0] is "
+			     "overlapping partition[1].  Adjusted.");
+		mem_size = reg_start - mem_start;
+		wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	} else if ((reg_start < mem_start) &&
+		   ((reg_start + reg_size) > mem_start)) {
+		/* Guarantee that the register partition doesn't overlap the
+		 * memory partition */
+		wl1271_debug(DEBUG_SPI, "End of partition[1] is"
+			     " overlapping partition[0].  Adjusted.");
+		reg_size = mem_start - reg_start;
+		wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+			     mem_start, mem_size);
+		wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+			     reg_start, reg_size);
+	}
+
+	partition[0].start = mem_start;
+	partition[0].size  = mem_size;
+	partition[1].start = reg_start;
+	partition[1].size  = reg_size;
+
+	wl->physical_mem_addr = mem_start;
+	wl->physical_reg_addr = reg_start;
+
+	wl->virtual_mem_addr = 0;
+	wl->virtual_reg_addr = mem_size;
+
+	t.tx_buf = cmd;
+	t.len = cmd_len;
+	spi_message_add_tail(&t, &m);
+
+	spi_sync(wl->spi, &m);
+
+	kfree(cmd);
+
+	return 0;
+}
+
+void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
+		     size_t len, bool fixed)
+{
+	struct spi_transfer t[3];
+	struct spi_message m;
+	u8 *busy_buf;
+	u32 *cmd;
+
+	cmd = &wl->buffer_cmd;
+	busy_buf = wl->buffer_busyword;
+
+	*cmd = 0;
+	*cmd |= WSPI_CMD_READ;
+	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+	if (fixed)
+		*cmd |= WSPI_CMD_FIXED;
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = cmd;
+	t[0].len = 4;
+	spi_message_add_tail(&t[0], &m);
+
+	/* Busy and non busy words read */
+	t[1].rx_buf = busy_buf;
+	t[1].len = WL1271_BUSY_WORD_LEN;
+	spi_message_add_tail(&t[1], &m);
+
+	t[2].rx_buf = buf;
+	t[2].len = len;
+	spi_message_add_tail(&t[2], &m);
+
+	spi_sync(wl->spi, &m);
+
+	/* FIXME: check busy words */
+
+	wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd));
+	wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+}
+
+void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
+		      size_t len, bool fixed)
+{
+	struct spi_transfer t[2];
+	struct spi_message m;
+	u32 *cmd;
+
+	cmd = &wl->buffer_cmd;
+
+	*cmd = 0;
+	*cmd |= WSPI_CMD_WRITE;
+	*cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+	*cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+	if (fixed)
+		*cmd |= WSPI_CMD_FIXED;
+
+	spi_message_init(&m);
+	memset(t, 0, sizeof(t));
+
+	t[0].tx_buf = cmd;
+	t[0].len = sizeof(*cmd);
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].tx_buf = buf;
+	t[1].len = len;
+	spi_message_add_tail(&t[1], &m);
+
+	spi_sync(wl->spi, &m);
+
+	wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));
+	wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+}
+
+void wl1271_spi_mem_read(struct wl1271 *wl, int addr, void *buf,
+			 size_t len)
+{
+	int physical;
+
+	physical = wl1271_translate_mem_addr(wl, addr);
+
+	wl1271_spi_read(wl, physical, buf, len, false);
+}
+
+void wl1271_spi_mem_write(struct wl1271 *wl, int addr, void *buf,
+			  size_t len)
+{
+	int physical;
+
+	physical = wl1271_translate_mem_addr(wl, addr);
+
+	wl1271_spi_write(wl, physical, buf, len, false);
+}
+
+void wl1271_spi_reg_read(struct wl1271 *wl, int addr, void *buf, size_t len,
+			 bool fixed)
+{
+	int physical;
+
+	physical = wl1271_translate_reg_addr(wl, addr);
+
+	wl1271_spi_read(wl, physical, buf, len, fixed);
+}
+
+void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
+			  bool fixed)
+{
+	int physical;
+
+	physical = wl1271_translate_reg_addr(wl, addr);
+
+	wl1271_spi_write(wl, physical, buf, len, fixed);
+}
+
+u32 wl1271_mem_read32(struct wl1271 *wl, int addr)
+{
+	return wl1271_read32(wl, wl1271_translate_mem_addr(wl, addr));
+}
+
+void wl1271_mem_write32(struct wl1271 *wl, int addr, u32 val)
+{
+	wl1271_write32(wl, wl1271_translate_mem_addr(wl, addr), val);
+}
+
+u32 wl1271_reg_read32(struct wl1271 *wl, int addr)
+{
+	return wl1271_read32(wl, wl1271_translate_reg_addr(wl, addr));
+}
+
+void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val)
+{
+	wl1271_write32(wl, wl1271_translate_reg_addr(wl, addr), val);
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.h b/drivers/net/wireless/wl12xx/wl1271_spi.h
new file mode 100644
index 0000000..2c99684
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.h
@@ -0,0 +1,113 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_SPI_H__
+#define __WL1271_SPI_H__
+
+#include "wl1271_reg.h"
+
+#define HW_ACCESS_MEMORY_MAX_RANGE		0x1FFC0
+
+#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
+#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
+#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
+#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
+
+#define HW_ACCESS_REGISTER_SIZE             4
+
+#define HW_ACCESS_PRAM_MAX_RANGE		0x3c000
+
+#define WSPI_CMD_READ                 0x40000000
+#define WSPI_CMD_WRITE                0x00000000
+#define WSPI_CMD_FIXED                0x20000000
+#define WSPI_CMD_BYTE_LENGTH          0x1FFE0000
+#define WSPI_CMD_BYTE_LENGTH_OFFSET   17
+#define WSPI_CMD_BYTE_ADDR            0x0001FFFF
+
+#define WSPI_INIT_CMD_CRC_LEN       5
+
+#define WSPI_INIT_CMD_START         0x00
+#define WSPI_INIT_CMD_TX            0x40
+/* the extra bypass bit is sampled by the TNET as '1' */
+#define WSPI_INIT_CMD_BYPASS_BIT    0x80
+#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
+#define WSPI_INIT_CMD_EN_FIXEDBUSY  0x80
+#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
+#define WSPI_INIT_CMD_IOD           0x40
+#define WSPI_INIT_CMD_IP            0x20
+#define WSPI_INIT_CMD_CS            0x10
+#define WSPI_INIT_CMD_WS            0x08
+#define WSPI_INIT_CMD_WSPI          0x01
+#define WSPI_INIT_CMD_END           0x01
+
+#define WSPI_INIT_CMD_LEN           8
+
+#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
+		((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
+#define HW_ACCESS_WSPI_INIT_CMD_MASK  0
+
+
+/* Raw target IO, address is not translated */
+void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf,
+		      size_t len, bool fixed);
+void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf,
+		     size_t len, bool fixed);
+
+/* Memory target IO, address is tranlated to partition 0 */
+void wl1271_spi_mem_read(struct wl1271 *wl, int addr, void *buf, size_t len);
+void wl1271_spi_mem_write(struct wl1271 *wl, int addr, void *buf, size_t len);
+u32 wl1271_mem_read32(struct wl1271 *wl, int addr);
+void wl1271_mem_write32(struct wl1271 *wl, int addr, u32 val);
+
+/* Registers IO */
+void wl1271_spi_reg_read(struct wl1271 *wl, int addr, void *buf, size_t len,
+			 bool fixed);
+void wl1271_spi_reg_write(struct wl1271 *wl, int addr, void *buf, size_t len,
+			  bool fixed);
+u32 wl1271_reg_read32(struct wl1271 *wl, int addr);
+void wl1271_reg_write32(struct wl1271 *wl, int addr, u32 val);
+
+/* INIT and RESET words */
+void wl1271_spi_reset(struct wl1271 *wl);
+void wl1271_spi_init(struct wl1271 *wl);
+int wl1271_set_partition(struct wl1271 *wl,
+			 u32 part_start, u32 part_size,
+			 u32 reg_start,  u32 reg_size);
+
+static inline u32 wl1271_read32(struct wl1271 *wl, int addr)
+{
+	wl1271_spi_read(wl, addr, &wl->buffer_32,
+			sizeof(wl->buffer_32), false);
+
+	return wl->buffer_32;
+}
+
+static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
+{
+	wl->buffer_32 = val;
+	wl1271_spi_write(wl, addr, &wl->buffer_32,
+			 sizeof(wl->buffer_32), false);
+}
+
+#endif /* __WL1271_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
new file mode 100644
index 0000000..ff22125
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -0,0 +1,378 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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/kernel.h>
+#include <linux/module.h>
+
+#include "wl1271.h"
+#include "wl1271_spi.h"
+#include "wl1271_reg.h"
+#include "wl1271_ps.h"
+#include "wl1271_tx.h"
+
+static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb)
+{
+	int i;
+
+	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+		if (wl->tx_frames[i] == NULL) {
+			wl->tx_frames[i] = skb;
+			return i;
+		}
+
+	return -EBUSY;
+}
+
+static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra)
+{
+	struct wl1271_tx_hw_descr *desc;
+	u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
+	u32 total_blocks, excluded;
+	int id, ret = -EBUSY;
+
+	/* allocate free identifier for the packet */
+	id = wl1271_tx_id(wl, skb);
+	if (id < 0)
+		return id;
+
+	/* approximate the number of blocks required for this packet
+	   in the firmware */
+	/* FIXME: try to figure out what is done here and make it cleaner */
+	total_blocks = (skb->len) >> TX_HW_BLOCK_SHIFT_DIV;
+	excluded = (total_blocks << 2) + (skb->len & 0xff) + 34;
+	total_blocks += (excluded > 252) ? 2 : 1;
+	total_blocks += TX_HW_BLOCK_SPARE;
+
+	if (total_blocks <= wl->tx_blocks_available) {
+		desc = (struct wl1271_tx_hw_descr *)skb_push(
+			skb, total_len - skb->len);
+
+		desc->extra_mem_blocks = TX_HW_BLOCK_SPARE;
+		desc->total_mem_blocks = total_blocks;
+		desc->id = id;
+
+		wl->tx_blocks_available -= total_blocks;
+
+		ret = 0;
+
+		wl1271_debug(DEBUG_TX,
+			     "tx_allocate: size: %d, blocks: %d, id: %d",
+			     total_len, total_blocks, id);
+	} else
+		wl->tx_frames[id] = NULL;
+
+	return ret;
+}
+
+static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
+			      u32 extra, struct ieee80211_tx_info *control)
+{
+	struct wl1271_tx_hw_descr *desc;
+	int pad;
+
+	desc = (struct wl1271_tx_hw_descr *) skb->data;
+
+	/* configure packet life time */
+	desc->start_time = jiffies_to_usecs(jiffies) - wl->time_offset;
+	desc->life_time = TX_HW_MGMT_PKT_LIFETIME_TU;
+
+	/* configure the tx attributes */
+	desc->tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
+	/* FIXME: do we know the packet priority? can we identify mgmt
+	   packets, and use max prio for them at least? */
+	desc->tid = 0;
+	desc->aid = TX_HW_DEFAULT_AID;
+	desc->reserved = 0;
+
+	/* align the length (and store in terms of words) */
+	pad = WL1271_TX_ALIGN(skb->len);
+	desc->length = pad >> 2;
+
+	/* calculate number of padding bytes */
+	pad = pad - skb->len;
+	desc->tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
+
+	wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
+	return 0;
+}
+
+static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
+				 struct ieee80211_tx_info *control)
+{
+
+	struct wl1271_tx_hw_descr *desc;
+	int len;
+
+	/* FIXME: This is a workaround for getting non-aligned packets.
+	   This happens at least with EAPOL packets from the user space.
+	   Our DMA requires packets to be aligned on a 4-byte boundary.
+	*/
+	if (unlikely((long)skb->data & 0x03)) {
+		int offset = (4 - (long)skb->data) & 0x03;
+		wl1271_debug(DEBUG_TX, "skb offset %d", offset);
+
+		/* check whether the current skb can be used */
+		if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
+			unsigned char *src = skb->data;
+
+			/* align the buffer on a 4-byte boundary */
+			skb_reserve(skb, offset);
+			memmove(skb->data, src, skb->len);
+		} else {
+			wl1271_info("No handler, fixme!");
+			return -EINVAL;
+		}
+	}
+
+	len = WL1271_TX_ALIGN(skb->len);
+
+	/* perform a fixed address block write with the packet */
+	wl1271_spi_reg_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);
+
+	/* write packet new counter into the write access register */
+	wl->tx_packets_count++;
+	wl1271_reg_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);
+
+	desc = (struct wl1271_tx_hw_descr *) skb->data;
+	wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
+		     desc->id, skb, len, desc->length);
+
+	return 0;
+}
+
+/* caller must hold wl->mutex */
+static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *info;
+	u32 extra = 0;
+	int ret = 0;
+	u8 idx;
+
+	if (!skb)
+		return -EINVAL;
+
+	info = IEEE80211_SKB_CB(skb);
+
+	if (info->control.hw_key &&
+	    info->control.hw_key->alg == ALG_TKIP)
+		extra = WL1271_TKIP_IV_SPACE;
+
+	if (info->control.hw_key) {
+		idx = info->control.hw_key->hw_key_idx;
+
+		/* FIXME: do we have to do this if we're not using WEP? */
+		if (unlikely(wl->default_key != idx)) {
+			ret = wl1271_cmd_set_default_wep_key(wl, idx);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	ret = wl1271_tx_allocate(wl, skb, extra);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_tx_fill_hdr(wl, skb, extra, info);
+	if (ret < 0)
+		return ret;
+
+	ret = wl1271_tx_send_packet(wl, skb, info);
+	if (ret < 0)
+		return ret;
+
+	return ret;
+}
+
+void wl1271_tx_work(struct work_struct *work)
+{
+	struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
+	struct sk_buff *skb;
+	bool woken_up = false;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state == WL1271_STATE_OFF))
+		goto out;
+
+	while ((skb = skb_dequeue(&wl->tx_queue))) {
+		if (!woken_up) {
+			ret = wl1271_ps_elp_wakeup(wl, false);
+			if (ret < 0)
+				goto out;
+			woken_up = true;
+		}
+
+		ret = wl1271_tx_frame(wl, skb);
+		if (ret == -EBUSY) {
+			/* firmware buffer is full, stop queues */
+			wl1271_debug(DEBUG_TX, "tx_work: fw buffer full, "
+				     "stop queues");
+			ieee80211_stop_queues(wl->hw);
+			wl->tx_queue_stopped = true;
+			skb_queue_head(&wl->tx_queue, skb);
+			goto out;
+		} else if (ret < 0) {
+			dev_kfree_skb(skb);
+			goto out;
+		} else if (wl->tx_queue_stopped) {
+			/* firmware buffer has space, restart queues */
+			wl1271_debug(DEBUG_TX,
+				     "complete_packet: waking queues");
+			ieee80211_wake_queues(wl->hw);
+			wl->tx_queue_stopped = false;
+		}
+	}
+
+out:
+	if (woken_up)
+		wl1271_ps_elp_sleep(wl);
+
+	mutex_unlock(&wl->mutex);
+}
+
+static void wl1271_tx_complete_packet(struct wl1271 *wl,
+				      struct wl1271_tx_hw_res_descr *result)
+{
+
+	struct ieee80211_tx_info *info;
+	struct sk_buff *skb;
+	u32 header_len;
+	int id = result->id;
+
+	/* check for id legality */
+	if (id >= TX_HW_RESULT_QUEUE_LEN || wl->tx_frames[id] == NULL) {
+		wl1271_warning("TX result illegal id: %d", id);
+		return;
+	}
+
+	skb = wl->tx_frames[id];
+	info = IEEE80211_SKB_CB(skb);
+
+	/* update packet status */
+	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
+		if (result->status == TX_SUCCESS)
+			info->flags |= IEEE80211_TX_STAT_ACK;
+		if (result->status & TX_RETRY_EXCEEDED) {
+			/* FIXME */
+			/* info->status.excessive_retries = 1; */
+			wl->stats.excessive_retries++;
+		}
+	}
+
+	/* FIXME */
+	/* info->status.retry_count = result->ack_failures; */
+	wl->stats.retry_count += result->ack_failures;
+
+	/* get header len */
+	if (info->control.hw_key &&
+	    info->control.hw_key->alg == ALG_TKIP)
+		header_len = WL1271_TKIP_IV_SPACE +
+			sizeof(struct wl1271_tx_hw_descr);
+	else
+		header_len = sizeof(struct wl1271_tx_hw_descr);
+
+	wl1271_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
+		     " status 0x%x",
+		     result->id, skb, result->ack_failures,
+		     result->rate_class_index, result->status);
+
+	/* remove private header from packet */
+	skb_pull(skb, header_len);
+
+	/* return the packet to the stack */
+	ieee80211_tx_status(wl->hw, skb);
+	wl->tx_frames[result->id] = NULL;
+}
+
+/* Called upon reception of a TX complete interrupt */
+void wl1271_tx_complete(struct wl1271 *wl, u32 count)
+{
+	struct wl1271_acx_mem_map *memmap =
+		(struct wl1271_acx_mem_map *)wl->target_mem_map;
+	u32 i;
+
+	wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
+
+	/* read the tx results from the chipset */
+	wl1271_spi_mem_read(wl, memmap->tx_result,
+			    wl->tx_res_if, sizeof(*wl->tx_res_if));
+
+	/* verify that the result buffer is not getting overrun */
+	if (count > TX_HW_RESULT_QUEUE_LEN) {
+		wl1271_warning("TX result overflow from chipset: %d", count);
+		count = TX_HW_RESULT_QUEUE_LEN;
+	}
+
+	/* process the results */
+	for (i = 0; i < count; i++) {
+		struct wl1271_tx_hw_res_descr *result;
+		u8 offset = wl->tx_results_count & TX_HW_RESULT_QUEUE_LEN_MASK;
+
+		/* process the packet */
+		result =  &(wl->tx_res_if->tx_results_queue[offset]);
+		wl1271_tx_complete_packet(wl, result);
+
+		wl->tx_results_count++;
+	}
+
+	/* write host counter to chipset (to ack) */
+	wl1271_mem_write32(wl, memmap->tx_result +
+			   offsetof(struct wl1271_tx_hw_res_if,
+				    tx_result_host_counter),
+			   wl->tx_res_if->tx_result_fw_counter);
+}
+
+/* caller must hold wl->mutex */
+void wl1271_tx_flush(struct wl1271 *wl)
+{
+	int i;
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *info;
+
+	/* TX failure */
+/* 	control->flags = 0; FIXME */
+
+	while ((skb = skb_dequeue(&wl->tx_queue))) {
+		info = IEEE80211_SKB_CB(skb);
+
+		wl1271_debug(DEBUG_TX, "flushing skb 0x%p", skb);
+
+		if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+				continue;
+
+		ieee80211_tx_status(wl->hw, skb);
+	}
+
+	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+		if (wl->tx_frames[i] != NULL) {
+			skb = wl->tx_frames[i];
+			info = IEEE80211_SKB_CB(skb);
+
+			if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+				continue;
+
+			ieee80211_tx_status(wl->hw, skb);
+			wl->tx_frames[i] = NULL;
+		}
+}
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
new file mode 100644
index 0000000..4a61406
--- /dev/null
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -0,0 +1,130 @@
+/*
+ * This file is part of wl1271
+ *
+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Luciano Coelho <luciano.coelho@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
+ *
+ */
+
+#ifndef __WL1271_TX_H__
+#define __WL1271_TX_H__
+
+#define TX_HW_BLOCK_SPARE                2
+#define TX_HW_BLOCK_SHIFT_DIV            8
+
+#define TX_HW_MGMT_PKT_LIFETIME_TU       2000
+/* The chipset reference driver states, that the "aid" value 1
+ * is for infra-BSS, but is still always used */
+#define TX_HW_DEFAULT_AID                1
+
+#define TX_HW_ATTR_SAVE_RETRIES          BIT(0)
+#define TX_HW_ATTR_HEADER_PAD            BIT(1)
+#define TX_HW_ATTR_SESSION_COUNTER       (BIT(2) | BIT(3) | BIT(4))
+#define TX_HW_ATTR_RATE_POLICY           (BIT(5) | BIT(6) | BIT(7) | \
+					  BIT(8) | BIT(9))
+#define TX_HW_ATTR_LAST_WORD_PAD         (BIT(10) | BIT(11))
+#define TX_HW_ATTR_TX_CMPLT_REQ          BIT(12)
+
+#define TX_HW_ATTR_OFST_SAVE_RETRIES     0
+#define TX_HW_ATTR_OFST_HEADER_PAD       1
+#define TX_HW_ATTR_OFST_SESSION_COUNTER  2
+#define TX_HW_ATTR_OFST_RATE_POLICY      5
+#define TX_HW_ATTR_OFST_LAST_WORD_PAD    10
+#define TX_HW_ATTR_OFST_TX_CMPLT_REQ     12
+
+#define TX_HW_RESULT_QUEUE_LEN           16
+#define TX_HW_RESULT_QUEUE_LEN_MASK      0xf
+
+#define WL1271_TX_ALIGN_TO 4
+#define WL1271_TX_ALIGN(len) (((len) + WL1271_TX_ALIGN_TO - 1) & \
+			     ~(WL1271_TX_ALIGN_TO - 1))
+#define WL1271_TKIP_IV_SPACE 4
+
+struct wl1271_tx_hw_descr {
+	/* Length of packet in words, including descriptor+header+data */
+	u16 length;
+	/* Number of extra memory blocks to allocate for this packet in
+	   addition to the number of blocks derived from the packet length */
+	u8 extra_mem_blocks;
+	/* Total number of memory blocks allocated by the host for this packet.
+	   Must be equal or greater than the actual blocks number allocated by
+	   HW!! */
+	u8 total_mem_blocks;
+	/* Device time (in us) when the packet arrived to the driver */
+	u32 start_time;
+	/* Max delay in TUs until transmission. The last device time the
+	   packet can be transmitted is: startTime+(1024*LifeTime) */
+	u16 life_time;
+	/* Bitwise fields - see TX_ATTR... definitions above. */
+	u16 tx_attr;
+	/* Packet identifier used also in the Tx-Result. */
+	u8 id;
+	/* The packet TID value (as User-Priority) */
+	u8 tid;
+	/* Identifier of the remote STA in IBSS, 1 in infra-BSS */
+	u8 aid;
+	u8 reserved;
+} __attribute__ ((packed));
+
+enum wl1271_tx_hw_res_status {
+	TX_SUCCESS          = 0,
+	TX_HW_ERROR         = 1,
+	TX_DISABLED         = 2,
+	TX_RETRY_EXCEEDED   = 3,
+	TX_TIMEOUT          = 4,
+	TX_KEY_NOT_FOUND    = 5,
+	TX_PEER_NOT_FOUND   = 6,
+	TX_SESSION_MISMATCH = 7
+};
+
+struct wl1271_tx_hw_res_descr {
+	/* Packet Identifier - same value used in the Tx descriptor.*/
+	u8 id;
+	/* The status of the transmission, indicating success or one of
+	   several possible reasons for failure. */
+	u8 status;
+	/* Total air access duration including all retrys and overheads.*/
+	u16 medium_usage;
+	/* The time passed from host xfer to Tx-complete.*/
+	u32 fw_handling_time;
+	/* Total media delay
+	   (from 1st EDCA AIFS counter until TX Complete). */
+	u32 medium_delay;
+	/* LS-byte of last TKIP seq-num (saved per AC for recovery). */
+	u8 lsb_security_sequence_number;
+	/* Retry count - number of transmissions without successful ACK.*/
+	u8 ack_failures;
+	/* The rate that succeeded getting ACK
+	   (Valid only if status=SUCCESS). */
+	u8 rate_class_index;
+	/* for 4-byte alignment. */
+	u8 spare;
+} __attribute__ ((packed));
+
+struct wl1271_tx_hw_res_if {
+	u32 tx_result_fw_counter;
+	u32 tx_result_host_counter;
+	struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];
+} __attribute__ ((packed));
+
+void wl1271_tx_work(struct work_struct *work);
+void wl1271_tx_complete(struct wl1271 *wl, u32 count);
+void wl1271_tx_flush(struct wl1271 *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
deleted file mode 100644
index 4864143..0000000
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * This file is part of wl12xx
- *
- * Copyright (c) 1998-2007 Texas Instruments Incorporated
- * Copyright (C) 2008-2009 Nokia Corporation
- *
- * 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
- *
- */
-
-#ifndef __WL12XX_H__
-#define __WL12XX_H__
-
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <linux/bitops.h>
-#include <net/mac80211.h>
-
-#define DRIVER_NAME "wl12xx"
-#define DRIVER_PREFIX DRIVER_NAME ": "
-
-enum {
-	DEBUG_NONE	= 0,
-	DEBUG_IRQ	= BIT(0),
-	DEBUG_SPI	= BIT(1),
-	DEBUG_BOOT	= BIT(2),
-	DEBUG_MAILBOX	= BIT(3),
-	DEBUG_NETLINK	= BIT(4),
-	DEBUG_EVENT	= BIT(5),
-	DEBUG_TX	= BIT(6),
-	DEBUG_RX	= BIT(7),
-	DEBUG_SCAN	= BIT(8),
-	DEBUG_CRYPT	= BIT(9),
-	DEBUG_PSM	= BIT(10),
-	DEBUG_MAC80211	= BIT(11),
-	DEBUG_CMD	= BIT(12),
-	DEBUG_ACX	= BIT(13),
-	DEBUG_ALL	= ~0,
-};
-
-#define DEBUG_LEVEL (DEBUG_NONE)
-
-#define DEBUG_DUMP_LIMIT 1024
-
-#define wl12xx_error(fmt, arg...) \
-	printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
-
-#define wl12xx_warning(fmt, arg...) \
-	printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
-
-#define wl12xx_notice(fmt, arg...) \
-	printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl12xx_info(fmt, arg...) \
-	printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
-
-#define wl12xx_debug(level, fmt, arg...) \
-	do { \
-		if (level & DEBUG_LEVEL) \
-			printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
-	} while (0)
-
-#define wl12xx_dump(level, prefix, buf, len)	\
-	do { \
-		if (level & DEBUG_LEVEL) \
-			print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
-				       DUMP_PREFIX_OFFSET, 16, 1,	\
-				       buf,				\
-				       min_t(size_t, len, DEBUG_DUMP_LIMIT), \
-				       0);				\
-	} while (0)
-
-#define wl12xx_dump_ascii(level, prefix, buf, len)	\
-	do { \
-		if (level & DEBUG_LEVEL) \
-			print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
-				       DUMP_PREFIX_OFFSET, 16, 1,	\
-				       buf,				\
-				       min_t(size_t, len, DEBUG_DUMP_LIMIT), \
-				       true);				\
-	} while (0)
-
-#define WL12XX_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN |	\
-				  CFG_BSSID_FILTER_EN)
-
-#define WL12XX_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN |  \
-				  CFG_RX_MGMT_EN |  \
-				  CFG_RX_DATA_EN |  \
-				  CFG_RX_CTL_EN |   \
-				  CFG_RX_BCN_EN |   \
-				  CFG_RX_AUTH_EN |  \
-				  CFG_RX_ASSOC_EN)
-
-
-struct boot_attr {
-	u32 radio_type;
-	u8 mac_clock;
-	u8 arm_clock;
-	int firmware_debug;
-	u32 minor;
-	u32 major;
-	u32 bugfix;
-};
-
-enum wl12xx_state {
-	WL12XX_STATE_OFF,
-	WL12XX_STATE_ON,
-	WL12XX_STATE_PLT,
-};
-
-enum wl12xx_partition_type {
-	PART_DOWN,
-	PART_WORK,
-	PART_DRPW,
-
-	PART_TABLE_LEN
-};
-
-struct wl12xx_partition {
-	u32 size;
-	u32 start;
-};
-
-struct wl12xx_partition_set {
-	struct wl12xx_partition mem;
-	struct wl12xx_partition reg;
-};
-
-struct wl12xx;
-
-/* FIXME: I'm not sure about this structure name */
-struct wl12xx_chip {
-	u32 id;
-
-	const char *fw_filename;
-	const char *nvs_filename;
-
-	char fw_ver[21];
-
-	unsigned int power_on_sleep;
-	int intr_cmd_complete;
-	int intr_init_complete;
-
-	int (*op_upload_fw)(struct wl12xx *wl);
-	int (*op_upload_nvs)(struct wl12xx *wl);
-	int (*op_boot)(struct wl12xx *wl);
-	void (*op_set_ecpu_ctrl)(struct wl12xx *wl, u32 flag);
-	void (*op_target_enable_interrupts)(struct wl12xx *wl);
-	int (*op_hw_init)(struct wl12xx *wl);
-	int (*op_plt_init)(struct wl12xx *wl);
-
-	struct wl12xx_partition_set *p_table;
-	enum wl12xx_acx_int_reg *acx_reg_table;
-};
-
-struct wl12xx_stats {
-	struct acx_statistics *fw_stats;
-	unsigned long fw_stats_update;
-
-	unsigned int retry_count;
-	unsigned int excessive_retries;
-};
-
-struct wl12xx_debugfs {
-	struct dentry *rootdir;
-	struct dentry *fw_statistics;
-
-	struct dentry *tx_internal_desc_overflow;
-
-	struct dentry *rx_out_of_mem;
-	struct dentry *rx_hdr_overflow;
-	struct dentry *rx_hw_stuck;
-	struct dentry *rx_dropped;
-	struct dentry *rx_fcs_err;
-	struct dentry *rx_xfr_hint_trig;
-	struct dentry *rx_path_reset;
-	struct dentry *rx_reset_counter;
-
-	struct dentry *dma_rx_requested;
-	struct dentry *dma_rx_errors;
-	struct dentry *dma_tx_requested;
-	struct dentry *dma_tx_errors;
-
-	struct dentry *isr_cmd_cmplt;
-	struct dentry *isr_fiqs;
-	struct dentry *isr_rx_headers;
-	struct dentry *isr_rx_mem_overflow;
-	struct dentry *isr_rx_rdys;
-	struct dentry *isr_irqs;
-	struct dentry *isr_tx_procs;
-	struct dentry *isr_decrypt_done;
-	struct dentry *isr_dma0_done;
-	struct dentry *isr_dma1_done;
-	struct dentry *isr_tx_exch_complete;
-	struct dentry *isr_commands;
-	struct dentry *isr_rx_procs;
-	struct dentry *isr_hw_pm_mode_changes;
-	struct dentry *isr_host_acknowledges;
-	struct dentry *isr_pci_pm;
-	struct dentry *isr_wakeups;
-	struct dentry *isr_low_rssi;
-
-	struct dentry *wep_addr_key_count;
-	struct dentry *wep_default_key_count;
-	/* skipping wep.reserved */
-	struct dentry *wep_key_not_found;
-	struct dentry *wep_decrypt_fail;
-	struct dentry *wep_packets;
-	struct dentry *wep_interrupt;
-
-	struct dentry *pwr_ps_enter;
-	struct dentry *pwr_elp_enter;
-	struct dentry *pwr_missing_bcns;
-	struct dentry *pwr_wake_on_host;
-	struct dentry *pwr_wake_on_timer_exp;
-	struct dentry *pwr_tx_with_ps;
-	struct dentry *pwr_tx_without_ps;
-	struct dentry *pwr_rcvd_beacons;
-	struct dentry *pwr_power_save_off;
-	struct dentry *pwr_enable_ps;
-	struct dentry *pwr_disable_ps;
-	struct dentry *pwr_fix_tsf_ps;
-	/* skipping cont_miss_bcns_spread for now */
-	struct dentry *pwr_rcvd_awake_beacons;
-
-	struct dentry *mic_rx_pkts;
-	struct dentry *mic_calc_failure;
-
-	struct dentry *aes_encrypt_fail;
-	struct dentry *aes_decrypt_fail;
-	struct dentry *aes_encrypt_packets;
-	struct dentry *aes_decrypt_packets;
-	struct dentry *aes_encrypt_interrupt;
-	struct dentry *aes_decrypt_interrupt;
-
-	struct dentry *event_heart_beat;
-	struct dentry *event_calibration;
-	struct dentry *event_rx_mismatch;
-	struct dentry *event_rx_mem_empty;
-	struct dentry *event_rx_pool;
-	struct dentry *event_oom_late;
-	struct dentry *event_phy_transmit_error;
-	struct dentry *event_tx_stuck;
-
-	struct dentry *ps_pspoll_timeouts;
-	struct dentry *ps_upsd_timeouts;
-	struct dentry *ps_upsd_max_sptime;
-	struct dentry *ps_upsd_max_apturn;
-	struct dentry *ps_pspoll_max_apturn;
-	struct dentry *ps_pspoll_utilization;
-	struct dentry *ps_upsd_utilization;
-
-	struct dentry *rxpipe_rx_prep_beacon_drop;
-	struct dentry *rxpipe_descr_host_int_trig_rx_data;
-	struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
-	struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
-	struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
-
-	struct dentry *tx_queue_len;
-
-	struct dentry *retry_count;
-	struct dentry *excessive_retries;
-};
-
-struct wl12xx {
-	struct ieee80211_hw *hw;
-	bool mac80211_registered;
-
-	struct spi_device *spi;
-
-	void (*set_power)(bool enable);
-	int irq;
-
-	enum wl12xx_state state;
-	struct mutex mutex;
-
-	int physical_mem_addr;
-	int physical_reg_addr;
-	int virtual_mem_addr;
-	int virtual_reg_addr;
-
-	struct wl12xx_chip chip;
-
-	int cmd_box_addr;
-	int event_box_addr;
-	struct boot_attr boot_attr;
-
-	u8 *fw;
-	size_t fw_len;
-	u8 *nvs;
-	size_t nvs_len;
-
-	u8 bssid[ETH_ALEN];
-	u8 mac_addr[ETH_ALEN];
-	u8 bss_type;
-	u8 listen_int;
-	int channel;
-
-	void *target_mem_map;
-	struct acx_data_path_params_resp *data_path;
-
-	/* Number of TX packets transferred to the FW, modulo 16 */
-	u32 data_in_count;
-
-	/* Frames scheduled for transmission, not handled yet */
-	struct sk_buff_head tx_queue;
-	bool tx_queue_stopped;
-
-	struct work_struct tx_work;
-	struct work_struct filter_work;
-
-	/* Pending TX frames */
-	struct sk_buff *tx_frames[16];
-
-	/*
-	 * Index pointing to the next TX complete entry
-	 * in the cyclic XT complete array we get from
-	 * the FW.
-	 */
-	u32 next_tx_complete;
-
-	/* FW Rx counter */
-	u32 rx_counter;
-
-	/* Rx frames handled */
-	u32 rx_handled;
-
-	/* Current double buffer */
-	u32 rx_current_buffer;
-	u32 rx_last_id;
-
-	/* The target interrupt mask */
-	u32 intr_mask;
-	struct work_struct irq_work;
-
-	/* The mbox event mask */
-	u32 event_mask;
-
-	/* Mailbox pointers */
-	u32 mbox_ptr[2];
-
-	/* Are we currently scanning */
-	bool scanning;
-
-	/* Our association ID */
-	u16 aid;
-
-	/* Default key (for WEP) */
-	u32 default_key;
-
-	unsigned int tx_mgmt_frm_rate;
-	unsigned int tx_mgmt_frm_mod;
-
-	unsigned int rx_config;
-	unsigned int rx_filter;
-
-	/* is firmware in elp mode */
-	bool elp;
-
-	/* we can be in psm, but not in elp, we have to differentiate */
-	bool psm;
-
-	/* PSM mode requested */
-	bool psm_requested;
-
-	/* in dBm */
-	int power_level;
-
-	struct wl12xx_stats stats;
-	struct wl12xx_debugfs debugfs;
-};
-
-int wl12xx_plt_start(struct wl12xx *wl);
-int wl12xx_plt_stop(struct wl12xx *wl);
-
-#define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
-#define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
-#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
-
-#define WL12XX_DEFAULT_POWER_LEVEL 20
-
-#define WL12XX_TX_QUEUE_MAX_LENGTH 20
-
-/* Different chips need different sleep times after power on.  WL1271 needs
- * 200ms, WL1251 needs only 10ms.  By default we use 200ms, but as soon as we
- * know the chip ID, we change the sleep value in the wl12xx chip structure,
- * so in subsequent power ons, we don't waste more time then needed.  */
-#define WL12XX_DEFAULT_POWER_ON_SLEEP 200
-
-#define CHIP_ID_1251_PG10	           (0x7010101)
-#define CHIP_ID_1251_PG11	           (0x7020101)
-#define CHIP_ID_1251_PG12	           (0x7030101)
-#define CHIP_ID_1271_PG10	           (0x4030101)
-
-#endif
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index e3e96bb..4f1e0cf 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1333,7 +1333,8 @@ static void wl3501_tx_timeout(struct net_device *dev)
  *	    1 - Could not transmit (dev_queue_xmit will queue it)
  *		and try to sent it later
  */
-static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t wl3501_hard_start_xmit(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	int enabled, rc;
 	struct wl3501_card *this = netdev_priv(dev);
@@ -1348,7 +1349,6 @@ static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (rc) {
 		++dev->stats.tx_dropped;
 		netif_stop_queue(dev);
-		rc = NETDEV_TX_OK;
 	} else {
 		++dev->stats.tx_packets;
 		dev->stats.tx_bytes += skb->len;
@@ -1358,7 +1358,7 @@ static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			netif_stop_queue(dev);
 	}
 	spin_unlock_irqrestore(&this->lock, flags);
-	return rc;
+	return NETDEV_TX_OK;
 }
 
 static int wl3501_open(struct net_device *dev)
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 4430b8d..bc81974 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -779,7 +779,8 @@ static int zd1201_net_stop(struct net_device *dev)
 				(llc+snap+type+payload)
 		zd		1 null byte, zd1201 packet type
  */
-static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t zd1201_hard_start_xmit(struct sk_buff *skb,
+						struct net_device *dev)
 {
 	struct zd1201 *zd = netdev_priv(dev);
 	unsigned char *txbuf = zd->txdata;
@@ -789,7 +790,7 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (!zd->mac_enabled || zd->monitor) {
 		dev->stats.tx_dropped++;
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	netif_stop_queue(dev);
 
@@ -826,7 +827,7 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	kfree_skb(skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void zd1201_tx_timeout(struct net_device *dev)
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 2c813d8..5e110a2 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -1278,11 +1278,11 @@ int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
 	other_led = chip->link_led == LED1 ? LED2 : LED1;
 
 	switch (status) {
-	case LED_OFF:
+	case ZD_LED_OFF:
 		ioreqs[0].value = FW_LINK_OFF;
 		ioreqs[1].value = v[1] & ~(LED1|LED2);
 		break;
-	case LED_SCANNING:
+	case ZD_LED_SCANNING:
 		ioreqs[0].value = FW_LINK_OFF;
 		ioreqs[1].value = v[1] & ~other_led;
 		if (get_seconds() % 3 == 0) {
@@ -1291,7 +1291,7 @@ int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
 			ioreqs[1].value |= chip->link_led;
 		}
 		break;
-	case LED_ASSOCIATED:
+	case ZD_LED_ASSOCIATED:
 		ioreqs[0].value = FW_LINK_TX;
 		ioreqs[1].value = v[1] & ~other_led;
 		ioreqs[1].value |= chip->link_led;
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index ee42751..678c139 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -897,9 +897,9 @@ int zd_chip_lock_phy_regs(struct zd_chip *chip);
 int zd_chip_unlock_phy_regs(struct zd_chip *chip);
 
 enum led_status {
-	LED_OFF = 0,
-	LED_SCANNING = 1,
-	LED_ASSOCIATED = 2,
+	ZD_LED_OFF = 0,
+	ZD_LED_SCANNING = 1,
+	ZD_LED_ASSOCIATED = 2,
 };
 
 int zd_chip_control_leds(struct zd_chip *chip, enum led_status status);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 3bd3c77..6d66635 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -711,7 +711,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
 
 	memcpy(skb_put(skb, length), buffer, length);
 
-	ieee80211_rx_irqsafe(hw, skb, &stats);
+	memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
+	ieee80211_rx_irqsafe(hw, skb);
 	return 0;
 }
 
@@ -795,18 +796,40 @@ static void set_rx_filter_handler(struct work_struct *work)
 		dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r);
 }
 
+static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw,
+				   int mc_count, struct dev_addr_list *mclist)
+{
+	struct zd_mac *mac = zd_hw_mac(hw);
+	struct zd_mc_hash hash;
+	int i;
+
+	zd_mc_clear(&hash);
+
+	for (i = 0; i < mc_count; i++) {
+		if (!mclist)
+			break;
+		dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n", mclist->dmi_addr);
+		zd_mc_add_addr(&hash, mclist->dmi_addr);
+		mclist = mclist->next;
+	}
+
+	return hash.low | ((u64)hash.high << 32);
+}
+
 #define SUPPORTED_FIF_FLAGS \
 	(FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \
 	FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)
 static void zd_op_configure_filter(struct ieee80211_hw *hw,
 			unsigned int changed_flags,
 			unsigned int *new_flags,
-			int mc_count, struct dev_mc_list *mclist)
+			u64 multicast)
 {
-	struct zd_mc_hash hash;
+	struct zd_mc_hash hash = {
+		.low = multicast,
+		.high = multicast >> 32,
+	};
 	struct zd_mac *mac = zd_hw_mac(hw);
 	unsigned long flags;
-	int i;
 
 	/* Only deal with supported flags */
 	changed_flags &= SUPPORTED_FIF_FLAGS;
@@ -818,25 +841,16 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
 	if (!changed_flags)
 		return;
 
-	if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) {
+	if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI))
 		zd_mc_add_all(&hash);
-	} else {
-		zd_mc_clear(&hash);
-		for (i = 0; i < mc_count; i++) {
-			if (!mclist)
-				break;
-			dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n",
-				  mclist->dmi_addr);
-			zd_mc_add_addr(&hash, mclist->dmi_addr);
-			mclist = mclist->next;
-		}
-	}
 
 	spin_lock_irqsave(&mac->lock, flags);
 	mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL);
 	mac->pass_ctrl = !!(*new_flags & FIF_CONTROL);
 	mac->multicast_hash = hash;
 	spin_unlock_irqrestore(&mac->lock, flags);
+
+	/* XXX: these can be called here now, can sleep now! */
 	queue_work(zd_workqueue, &mac->set_multicast_hash_work);
 
 	if (changed_flags & FIF_CONTROL)
@@ -939,6 +953,7 @@ static const struct ieee80211_ops zd_ops = {
 	.add_interface		= zd_op_add_interface,
 	.remove_interface	= zd_op_remove_interface,
 	.config			= zd_op_config,
+	.prepare_multicast	= zd_op_prepare_multicast,
 	.configure_filter	= zd_op_configure_filter,
 	.bss_info_changed	= zd_op_bss_info_changed,
 	.get_tsf		= zd_op_get_tsf,
@@ -1012,7 +1027,7 @@ static void link_led_handler(struct work_struct *work)
 	spin_unlock_irq(&mac->lock);
 
 	r = zd_chip_control_leds(chip,
-		                 is_associated ? LED_ASSOCIATED : LED_SCANNING);
+		                 is_associated ? ZD_LED_ASSOCIATED : ZD_LED_SCANNING);
 	if (r)
 		dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
 
@@ -1037,5 +1052,5 @@ static void housekeeping_disable(struct zd_mac *mac)
 	dev_dbg_f(zd_mac_dev(mac), "\n");
 	cancel_rearming_delayed_workqueue(zd_workqueue,
 		&mac->housekeeping.link_led_work);
-	zd_chip_control_leds(&mac->chip, LED_OFF);
+	zd_chip_control_leds(&mac->chip, ZD_LED_OFF);
 }
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 0e6e446..3868884 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -36,58 +36,60 @@
 
 static struct usb_device_id usb_ids[] = {
 	/* ZD1211 */
+	{ USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0586, 0x3409), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x079b, 0x004a), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 },
 	{ USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 },
 	{ USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0b3b, 0x1630), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 },
 	{ USB_DEVICE(0x0df6, 0x9071), .driver_info = DEVICE_ZD1211 },
 	{ USB_DEVICE(0x0df6, 0x9075), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x079b, 0x004a), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x1740, 0x2000), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x157e, 0x3204), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0586, 0x3402), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0b3b, 0x5630), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0b05, 0x170c), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
 	{ USB_DEVICE(0x1435, 0x0711), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0586, 0x3409), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0b3b, 0x1630), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0586, 0x3401), .driver_info = DEVICE_ZD1211 },
 	{ USB_DEVICE(0x14ea, 0xab13), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
 	{ USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
-	{ USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x157e, 0x300b), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x157e, 0x3204), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x1740, 0x2000), .driver_info = DEVICE_ZD1211 },
+	{ USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 },
 	/* ZD1211B */
+	{ USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x054c, 0x0257), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0586, 0x340f), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0586, 0x3410), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x050d, 0x705c), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x083a, 0xe501), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x083a, 0xe503), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x083a, 0xe506), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0471, 0x1236), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0586, 0x340f), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0b05, 0x171b), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0586, 0x3410), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0baf, 0x0121), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x129b, 0x1667), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B },
-	{ USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x129b, 0x1667), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x13b1, 0x0024), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B },
 	/* "Driverless" devices that need ejecting */
 	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
 	{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 8d88dae..baa051d 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -51,7 +51,7 @@
 #include <xen/interface/memory.h>
 #include <xen/interface/grant_table.h>
 
-static struct ethtool_ops xennet_ethtool_ops;
+static const struct ethtool_ops xennet_ethtool_ops;
 
 struct netfront_cb {
 	struct page *page;
@@ -558,12 +558,12 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irq(&np->tx_lock);
 
-	return 0;
+	return NETDEV_TX_OK;
 
  drop:
 	dev->stats.tx_dropped++;
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int xennet_close(struct net_device *dev)
@@ -1627,7 +1627,7 @@ static void backend_changed(struct xenbus_device *dev,
 	}
 }
 
-static struct ethtool_ops xennet_ethtool_ops =
+static const struct ethtool_ops xennet_ethtool_ops =
 {
 	.set_tx_csum = ethtool_op_set_tx_csum,
 	.set_sg = xennet_set_sg,
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
new file mode 100644
index 0000000..dc22782
--- /dev/null
+++ b/drivers/net/xilinx_emaclite.c
@@ -0,0 +1,1040 @@
+/*
+ * Xilinx EmacLite Linux driver for the Xilinx Ethernet MAC Lite device.
+ *
+ * This is a new flat driver which is based on the original emac_lite
+ * driver from John Williams <john.williams@petalogix.com>.
+ *
+ * 2007-2009 (c) Xilinx, 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/module.h>
+#include <linux/uaccess.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/io.h>
+
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#define DRIVER_NAME "xilinx_emaclite"
+
+/* Register offsets for the EmacLite Core */
+#define XEL_TXBUFF_OFFSET 	0x0		/* Transmit Buffer */
+#define XEL_GIER_OFFSET		0x07F8		/* GIE Register */
+#define XEL_TSR_OFFSET		0x07FC		/* Tx status */
+#define XEL_TPLR_OFFSET		0x07F4		/* Tx packet length */
+
+#define XEL_RXBUFF_OFFSET	0x1000		/* Receive Buffer */
+#define XEL_RPLR_OFFSET		0x100C		/* Rx packet length */
+#define XEL_RSR_OFFSET		0x17FC		/* Rx status */
+
+#define XEL_BUFFER_OFFSET	0x0800		/* Next Tx/Rx buffer's offset */
+
+/* Global Interrupt Enable Register (GIER) Bit Masks */
+#define XEL_GIER_GIE_MASK	0x80000000 	/* Global Enable */
+
+/* Transmit Status Register (TSR) Bit Masks */
+#define XEL_TSR_XMIT_BUSY_MASK	 0x00000001 	/* Tx complete */
+#define XEL_TSR_PROGRAM_MASK	 0x00000002 	/* Program the MAC address */
+#define XEL_TSR_XMIT_IE_MASK	 0x00000008 	/* Tx interrupt enable bit */
+#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000 	/* Buffer is active, SW bit
+						 * only. This is not documented
+						 * in the HW spec */
+
+/* Define for programming the MAC address into the EmacLite */
+#define XEL_TSR_PROG_MAC_ADDR	(XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
+
+/* Receive Status Register (RSR) */
+#define XEL_RSR_RECV_DONE_MASK	0x00000001 	/* Rx complete */
+#define XEL_RSR_RECV_IE_MASK	0x00000008 	/* Rx interrupt enable bit */
+
+/* Transmit Packet Length Register (TPLR) */
+#define XEL_TPLR_LENGTH_MASK	0x0000FFFF 	/* Tx packet length */
+
+/* Receive Packet Length Register (RPLR) */
+#define XEL_RPLR_LENGTH_MASK	0x0000FFFF 	/* Rx packet length */
+
+#define XEL_HEADER_OFFSET	12 		/* Offset to length field */
+#define XEL_HEADER_SHIFT	16 		/* Shift value for length */
+
+/* General Ethernet Definitions */
+#define XEL_ARP_PACKET_SIZE		28 	/* Max ARP packet size */
+#define XEL_HEADER_IP_LENGTH_OFFSET	16 	/* IP Length Offset */
+
+
+
+#define TX_TIMEOUT		(60*HZ)		/* Tx timeout is 60 seconds. */
+#define ALIGNMENT		4
+
+/* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */
+#define BUFFER_ALIGN(adr) ((ALIGNMENT - ((u32) adr)) % ALIGNMENT)
+
+/**
+ * struct net_local - Our private per device data
+ * @ndev:		instance of the network device
+ * @tx_ping_pong:	indicates whether Tx Pong buffer is configured in HW
+ * @rx_ping_pong:	indicates whether Rx Pong buffer is configured in HW
+ * @next_tx_buf_to_use:	next Tx buffer to write to
+ * @next_rx_buf_to_use:	next Rx buffer to read from
+ * @base_addr:		base address of the Emaclite device
+ * @reset_lock:		lock used for synchronization
+ * @deferred_skb:	holds an skb (for transmission at a later time) when the
+ *			Tx buffer is not free
+ */
+struct net_local {
+
+	struct net_device *ndev;
+
+	bool tx_ping_pong;
+	bool rx_ping_pong;
+	u32 next_tx_buf_to_use;
+	u32 next_rx_buf_to_use;
+	void __iomem *base_addr;
+
+	spinlock_t reset_lock;
+	struct sk_buff *deferred_skb;
+};
+
+
+/*************************/
+/* EmacLite driver calls */
+/*************************/
+
+/**
+ * xemaclite_enable_interrupts - Enable the interrupts for the EmacLite device
+ * @drvdata:	Pointer to the Emaclite device private data
+ *
+ * This function enables the Tx and Rx interrupts for the Emaclite device along
+ * with the Global Interrupt Enable.
+ */
+static void xemaclite_enable_interrupts(struct net_local *drvdata)
+{
+	u32 reg_data;
+
+	/* Enable the Tx interrupts for the first Buffer */
+	reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET);
+	out_be32(drvdata->base_addr + XEL_TSR_OFFSET,
+		 reg_data | XEL_TSR_XMIT_IE_MASK);
+
+	/* Enable the Tx interrupts for the second Buffer if
+	 * configured in HW */
+	if (drvdata->tx_ping_pong != 0) {
+		reg_data = in_be32(drvdata->base_addr +
+				   XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
+		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+			 XEL_TSR_OFFSET,
+			 reg_data | XEL_TSR_XMIT_IE_MASK);
+	}
+
+	/* Enable the Rx interrupts for the first buffer */
+	reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET);
+	out_be32(drvdata->base_addr + XEL_RSR_OFFSET,
+		 reg_data | XEL_RSR_RECV_IE_MASK);
+
+	/* Enable the Rx interrupts for the second Buffer if
+	 * configured in HW */
+	if (drvdata->rx_ping_pong != 0) {
+		reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+				   XEL_RSR_OFFSET);
+		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+			 XEL_RSR_OFFSET,
+			 reg_data | XEL_RSR_RECV_IE_MASK);
+	}
+
+	/* Enable the Global Interrupt Enable */
+	out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK);
+}
+
+/**
+ * xemaclite_disable_interrupts - Disable the interrupts for the EmacLite device
+ * @drvdata:	Pointer to the Emaclite device private data
+ *
+ * This function disables the Tx and Rx interrupts for the Emaclite device,
+ * along with the Global Interrupt Enable.
+ */
+static void xemaclite_disable_interrupts(struct net_local *drvdata)
+{
+	u32 reg_data;
+
+	/* Disable the Global Interrupt Enable */
+	out_be32(drvdata->base_addr + XEL_GIER_OFFSET, XEL_GIER_GIE_MASK);
+
+	/* Disable the Tx interrupts for the first buffer */
+	reg_data = in_be32(drvdata->base_addr + XEL_TSR_OFFSET);
+	out_be32(drvdata->base_addr + XEL_TSR_OFFSET,
+		 reg_data & (~XEL_TSR_XMIT_IE_MASK));
+
+	/* Disable the Tx interrupts for the second Buffer
+	 * if configured in HW */
+	if (drvdata->tx_ping_pong != 0) {
+		reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+				   XEL_TSR_OFFSET);
+		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+			 XEL_TSR_OFFSET,
+			 reg_data & (~XEL_TSR_XMIT_IE_MASK));
+	}
+
+	/* Disable the Rx interrupts for the first buffer */
+	reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET);
+	out_be32(drvdata->base_addr + XEL_RSR_OFFSET,
+		 reg_data & (~XEL_RSR_RECV_IE_MASK));
+
+	/* Disable the Rx interrupts for the second buffer
+	 * if configured in HW */
+	if (drvdata->rx_ping_pong != 0) {
+
+		reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+				   XEL_RSR_OFFSET);
+		out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
+			 XEL_RSR_OFFSET,
+			 reg_data & (~XEL_RSR_RECV_IE_MASK));
+	}
+}
+
+/**
+ * xemaclite_aligned_write - Write from 16-bit aligned to 32-bit aligned address
+ * @src_ptr:	Void pointer to the 16-bit aligned source address
+ * @dest_ptr:	Pointer to the 32-bit aligned destination address
+ * @length:	Number bytes to write from source to destination
+ *
+ * This function writes data from a 16-bit aligned buffer to a 32-bit aligned
+ * address in the EmacLite device.
+ */
+static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr,
+				    unsigned length)
+{
+	u32 align_buffer;
+	u32 *to_u32_ptr;
+	u16 *from_u16_ptr, *to_u16_ptr;
+
+	to_u32_ptr = dest_ptr;
+	from_u16_ptr = (u16 *) src_ptr;
+	align_buffer = 0;
+
+	for (; length > 3; length -= 4) {
+		to_u16_ptr = (u16 *) ((void *) &align_buffer);
+		*to_u16_ptr++ = *from_u16_ptr++;
+		*to_u16_ptr++ = *from_u16_ptr++;
+
+		/* Output a word */
+		*to_u32_ptr++ = align_buffer;
+	}
+	if (length) {
+		u8 *from_u8_ptr, *to_u8_ptr;
+
+		/* Set up to output the remaining data */
+		align_buffer = 0;
+		to_u8_ptr = (u8 *) &align_buffer;
+		from_u8_ptr = (u8 *) from_u16_ptr;
+
+		/* Output the remaining data */
+		for (; length > 0; length--)
+			*to_u8_ptr++ = *from_u8_ptr++;
+
+		*to_u32_ptr = align_buffer;
+	}
+}
+
+/**
+ * xemaclite_aligned_read - Read from 32-bit aligned to 16-bit aligned buffer
+ * @src_ptr:	Pointer to the 32-bit aligned source address
+ * @dest_ptr:	Pointer to the 16-bit aligned destination address
+ * @length:	Number bytes to read from source to destination
+ *
+ * This function reads data from a 32-bit aligned address in the EmacLite device
+ * to a 16-bit aligned buffer.
+ */
+static void xemaclite_aligned_read(u32 *src_ptr, u8 *dest_ptr,
+				   unsigned length)
+{
+	u16 *to_u16_ptr, *from_u16_ptr;
+	u32 *from_u32_ptr;
+	u32 align_buffer;
+
+	from_u32_ptr = src_ptr;
+	to_u16_ptr = (u16 *) dest_ptr;
+
+	for (; length > 3; length -= 4) {
+		/* Copy each word into the temporary buffer */
+		align_buffer = *from_u32_ptr++;
+		from_u16_ptr = (u16 *)&align_buffer;
+
+		/* Read data from source */
+		*to_u16_ptr++ = *from_u16_ptr++;
+		*to_u16_ptr++ = *from_u16_ptr++;
+	}
+
+	if (length) {
+		u8 *to_u8_ptr, *from_u8_ptr;
+
+		/* Set up to read the remaining data */
+		to_u8_ptr = (u8 *) to_u16_ptr;
+		align_buffer = *from_u32_ptr++;
+		from_u8_ptr = (u8 *) &align_buffer;
+
+		/* Read the remaining data */
+		for (; length > 0; length--)
+			*to_u8_ptr = *from_u8_ptr;
+	}
+}
+
+/**
+ * xemaclite_send_data - Send an Ethernet frame
+ * @drvdata:	Pointer to the Emaclite device private data
+ * @data:	Pointer to the data to be sent
+ * @byte_count:	Total frame size, including header
+ *
+ * This function checks if the Tx buffer of the Emaclite device is free to send
+ * data. If so, it fills the Tx buffer with data for transmission. Otherwise, it
+ * returns an error.
+ *
+ * Return:	0 upon success or -1 if the buffer(s) are full.
+ *
+ * Note:	The maximum Tx packet size can not be more than Ethernet header
+ *		(14 Bytes) + Maximum MTU (1500 bytes). This is excluding FCS.
+ */
+static int xemaclite_send_data(struct net_local *drvdata, u8 *data,
+			       unsigned int byte_count)
+{
+	u32 reg_data;
+	void __iomem *addr;
+
+	/* Determine the expected Tx buffer address */
+	addr = drvdata->base_addr + drvdata->next_tx_buf_to_use;
+
+	/* If the length is too large, truncate it */
+	if (byte_count > ETH_FRAME_LEN)
+		byte_count = ETH_FRAME_LEN;
+
+	/* Check if the expected buffer is available */
+	reg_data = in_be32(addr + XEL_TSR_OFFSET);
+	if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK |
+	     XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
+
+		/* Switch to next buffer if configured */
+		if (drvdata->tx_ping_pong != 0)
+			drvdata->next_tx_buf_to_use ^= XEL_BUFFER_OFFSET;
+	} else if (drvdata->tx_ping_pong != 0) {
+		/* If the expected buffer is full, try the other buffer,
+		 * if it is configured in HW */
+
+		addr = (void __iomem __force *)((u32 __force)addr ^
+						 XEL_BUFFER_OFFSET);
+		reg_data = in_be32(addr + XEL_TSR_OFFSET);
+
+		if ((reg_data & (XEL_TSR_XMIT_BUSY_MASK |
+		     XEL_TSR_XMIT_ACTIVE_MASK)) != 0)
+			return -1; /* Buffers were full, return failure */
+	} else
+		return -1; /* Buffer was full, return failure */
+
+	/* Write the frame to the buffer */
+	xemaclite_aligned_write(data, (u32 __force *) addr, byte_count);
+
+	out_be32(addr + XEL_TPLR_OFFSET, (byte_count & XEL_TPLR_LENGTH_MASK));
+
+	/* Update the Tx Status Register to indicate that there is a
+	 * frame to send. Set the XEL_TSR_XMIT_ACTIVE_MASK flag which
+	 * is used by the interrupt handler to check whether a frame
+	 * has been transmitted */
+	reg_data = in_be32(addr + XEL_TSR_OFFSET);
+	reg_data |= (XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_XMIT_ACTIVE_MASK);
+	out_be32(addr + XEL_TSR_OFFSET, reg_data);
+
+	return 0;
+}
+
+/**
+ * xemaclite_recv_data - Receive a frame
+ * @drvdata:	Pointer to the Emaclite device private data
+ * @data:	Address where the data is to be received
+ *
+ * This function is intended to be called from the interrupt context or
+ * with a wrapper which waits for the receive frame to be available.
+ *
+ * Return:	Total number of bytes received
+ */
+static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data)
+{
+	void __iomem *addr;
+	u16 length, proto_type;
+	u32 reg_data;
+
+	/* Determine the expected buffer address */
+	addr = (drvdata->base_addr + drvdata->next_rx_buf_to_use);
+
+	/* Verify which buffer has valid data */
+	reg_data = in_be32(addr + XEL_RSR_OFFSET);
+
+	if ((reg_data & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
+		if (drvdata->rx_ping_pong != 0)
+			drvdata->next_rx_buf_to_use ^= XEL_BUFFER_OFFSET;
+	} else {
+		/* The instance is out of sync, try other buffer if other
+		 * buffer is configured, return 0 otherwise. If the instance is
+		 * out of sync, do not update the 'next_rx_buf_to_use' since it
+		 * will correct on subsequent calls */
+		if (drvdata->rx_ping_pong != 0)
+			addr = (void __iomem __force *)((u32 __force)addr ^
+							 XEL_BUFFER_OFFSET);
+		else
+			return 0;	/* No data was available */
+
+		/* Verify that buffer has valid data */
+		reg_data = in_be32(addr + XEL_RSR_OFFSET);
+		if ((reg_data & XEL_RSR_RECV_DONE_MASK) !=
+		     XEL_RSR_RECV_DONE_MASK)
+			return 0;	/* No data was available */
+	}
+
+	/* Get the protocol type of the ethernet frame that arrived */
+	proto_type = ((in_be32(addr + XEL_HEADER_OFFSET +
+			XEL_RXBUFF_OFFSET) >> XEL_HEADER_SHIFT) &
+			XEL_RPLR_LENGTH_MASK);
+
+	/* Check if received ethernet frame is a raw ethernet frame
+	 * or an IP packet or an ARP packet */
+	if (proto_type > (ETH_FRAME_LEN + ETH_FCS_LEN)) {
+
+		if (proto_type == ETH_P_IP) {
+			length = ((in_be32(addr +
+					XEL_HEADER_IP_LENGTH_OFFSET +
+					XEL_RXBUFF_OFFSET) >>
+					XEL_HEADER_SHIFT) &
+					XEL_RPLR_LENGTH_MASK);
+			length += ETH_HLEN + ETH_FCS_LEN;
+
+		} else if (proto_type == ETH_P_ARP)
+			length = XEL_ARP_PACKET_SIZE + ETH_HLEN + ETH_FCS_LEN;
+		else
+			/* Field contains type other than IP or ARP, use max
+			 * frame size and let user parse it */
+			length = ETH_FRAME_LEN + ETH_FCS_LEN;
+	} else
+		/* Use the length in the frame, plus the header and trailer */
+		length = proto_type + ETH_HLEN + ETH_FCS_LEN;
+
+	/* Read from the EmacLite device */
+	xemaclite_aligned_read((u32 __force *) (addr + XEL_RXBUFF_OFFSET),
+				data, length);
+
+	/* Acknowledge the frame */
+	reg_data = in_be32(addr + XEL_RSR_OFFSET);
+	reg_data &= ~XEL_RSR_RECV_DONE_MASK;
+	out_be32(addr + XEL_RSR_OFFSET, reg_data);
+
+	return length;
+}
+
+/**
+ * xemaclite_set_mac_address - Set the MAC address for this device
+ * @drvdata:	Pointer to the Emaclite device private data
+ * @address_ptr:Pointer to the MAC address (MAC address is a 48-bit value)
+ *
+ * Tx must be idle and Rx should be idle for deterministic results.
+ * It is recommended that this function should be called after the
+ * initialization and before transmission of any packets from the device.
+ * The MAC address can be programmed using any of the two transmit
+ * buffers (if configured).
+ */
+static void xemaclite_set_mac_address(struct net_local *drvdata,
+				      u8 *address_ptr)
+{
+	void __iomem *addr;
+	u32 reg_data;
+
+	/* Determine the expected Tx buffer address */
+	addr = drvdata->base_addr + drvdata->next_tx_buf_to_use;
+
+	xemaclite_aligned_write(address_ptr, (u32 __force *) addr, ETH_ALEN);
+
+	out_be32(addr + XEL_TPLR_OFFSET, ETH_ALEN);
+
+	/* Update the MAC address in the EmacLite */
+	reg_data = in_be32(addr + XEL_TSR_OFFSET);
+	out_be32(addr + XEL_TSR_OFFSET, reg_data | XEL_TSR_PROG_MAC_ADDR);
+
+	/* Wait for EmacLite to finish with the MAC address update */
+	while ((in_be32(addr + XEL_TSR_OFFSET) &
+		XEL_TSR_PROG_MAC_ADDR) != 0)
+		;
+}
+
+/**
+ * xemaclite_tx_timeout - Callback for Tx Timeout
+ * @dev:	Pointer to the network device
+ *
+ * This function is called when Tx time out occurs for Emaclite device.
+ */
+static void xemaclite_tx_timeout(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	unsigned long flags;
+
+	dev_err(&lp->ndev->dev, "Exceeded transmit timeout of %lu ms\n",
+		TX_TIMEOUT * 1000UL / HZ);
+
+	dev->stats.tx_errors++;
+
+	/* Reset the device */
+	spin_lock_irqsave(&lp->reset_lock, flags);
+
+	/* Shouldn't really be necessary, but shouldn't hurt */
+	netif_stop_queue(dev);
+
+	xemaclite_disable_interrupts(lp);
+	xemaclite_enable_interrupts(lp);
+
+	if (lp->deferred_skb) {
+		dev_kfree_skb(lp->deferred_skb);
+		lp->deferred_skb = NULL;
+		dev->stats.tx_errors++;
+	}
+
+	/* To exclude tx timeout */
+	dev->trans_start = 0xffffffff - TX_TIMEOUT - TX_TIMEOUT;
+
+	/* We're all ready to go. Start the queue */
+	netif_wake_queue(dev);
+	spin_unlock_irqrestore(&lp->reset_lock, flags);
+}
+
+/**********************/
+/* Interrupt Handlers */
+/**********************/
+
+/**
+ * xemaclite_tx_handler - Interrupt handler for frames sent
+ * @dev:	Pointer to the network device
+ *
+ * This function updates the number of packets transmitted and handles the
+ * deferred skb, if there is one.
+ */
+static void xemaclite_tx_handler(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+
+	dev->stats.tx_packets++;
+	if (lp->deferred_skb) {
+		if (xemaclite_send_data(lp,
+					(u8 *) lp->deferred_skb->data,
+					lp->deferred_skb->len) != 0)
+			return;
+		else {
+			dev->stats.tx_bytes += lp->deferred_skb->len;
+			dev_kfree_skb_irq(lp->deferred_skb);
+			lp->deferred_skb = NULL;
+			dev->trans_start = jiffies;
+			netif_wake_queue(dev);
+		}
+	}
+}
+
+/**
+ * xemaclite_rx_handler- Interrupt handler for frames received
+ * @dev:	Pointer to the network device
+ *
+ * This function allocates memory for a socket buffer, fills it with data
+ * received and hands it over to the TCP/IP stack.
+ */
+static void xemaclite_rx_handler(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct sk_buff *skb;
+	unsigned int align;
+	u32 len;
+
+	len = ETH_FRAME_LEN + ETH_FCS_LEN;
+	skb = dev_alloc_skb(len + ALIGNMENT);
+	if (!skb) {
+		/* Couldn't get memory. */
+		dev->stats.rx_dropped++;
+		dev_err(&lp->ndev->dev, "Could not allocate receive buffer\n");
+		return;
+	}
+
+	/*
+	 * A new skb should have the data halfword aligned, but this code is
+	 * here just in case that isn't true. Calculate how many
+	 * bytes we should reserve to get the data to start on a word
+	 * boundary */
+	align = BUFFER_ALIGN(skb->data);
+	if (align)
+		skb_reserve(skb, align);
+
+	skb_reserve(skb, 2);
+
+	len = xemaclite_recv_data(lp, (u8 *) skb->data);
+
+	if (!len) {
+		dev->stats.rx_errors++;
+		dev_kfree_skb_irq(skb);
+		return;
+	}
+
+	skb_put(skb, len);	/* Tell the skb how much data we got */
+	skb->dev = dev;		/* Fill out required meta-data */
+
+	skb->protocol = eth_type_trans(skb, dev);
+	skb->ip_summed = CHECKSUM_NONE;
+
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += len;
+
+	netif_rx(skb);		/* Send the packet upstream */
+}
+
+/**
+ * xemaclite_interrupt - Interrupt handler for this driver
+ * @irq:	Irq of the Emaclite device
+ * @dev_id:	Void pointer to the network device instance used as callback
+ *		reference
+ *
+ * This function handles the Tx and Rx interrupts of the EmacLite device.
+ */
+static irqreturn_t xemaclite_interrupt(int irq, void *dev_id)
+{
+	bool tx_complete = 0;
+	struct net_device *dev = dev_id;
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	void __iomem *base_addr = lp->base_addr;
+	u32 tx_status;
+
+	/* Check if there is Rx Data available */
+	if ((in_be32(base_addr + XEL_RSR_OFFSET) & XEL_RSR_RECV_DONE_MASK) ||
+			(in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_RSR_OFFSET)
+			 & XEL_RSR_RECV_DONE_MASK))
+
+		xemaclite_rx_handler(dev);
+
+	/* Check if the Transmission for the first buffer is completed */
+	tx_status = in_be32(base_addr + XEL_TSR_OFFSET);
+	if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
+		(tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {
+
+		tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK;
+		out_be32(base_addr + XEL_TSR_OFFSET, tx_status);
+
+		tx_complete = 1;
+	}
+
+	/* Check if the Transmission for the second buffer is completed */
+	tx_status = in_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET);
+	if (((tx_status & XEL_TSR_XMIT_BUSY_MASK) == 0) &&
+		(tx_status & XEL_TSR_XMIT_ACTIVE_MASK) != 0) {
+
+		tx_status &= ~XEL_TSR_XMIT_ACTIVE_MASK;
+		out_be32(base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET,
+			 tx_status);
+
+		tx_complete = 1;
+	}
+
+	/* If there was a Tx interrupt, call the Tx Handler */
+	if (tx_complete != 0)
+		xemaclite_tx_handler(dev);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * xemaclite_open - Open the network device
+ * @dev:	Pointer to the network device
+ *
+ * This function sets the MAC address, requests an IRQ and enables interrupts
+ * for the Emaclite device and starts the Tx queue.
+ */
+static int xemaclite_open(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	int retval;
+
+	/* Just to be safe, stop the device first */
+	xemaclite_disable_interrupts(lp);
+
+	/* Set the MAC address each time opened */
+	xemaclite_set_mac_address(lp, dev->dev_addr);
+
+	/* Grab the IRQ */
+	retval = request_irq(dev->irq, &xemaclite_interrupt, 0, dev->name, dev);
+	if (retval) {
+		dev_err(&lp->ndev->dev, "Could not allocate interrupt %d\n",
+			dev->irq);
+		return retval;
+	}
+
+	/* Enable Interrupts */
+	xemaclite_enable_interrupts(lp);
+
+	/* We're ready to go */
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/**
+ * xemaclite_close - Close the network device
+ * @dev:	Pointer to the network device
+ *
+ * This function stops the Tx queue, disables interrupts and frees the IRQ for
+ * the Emaclite device.
+ */
+static int xemaclite_close(struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+
+	netif_stop_queue(dev);
+	xemaclite_disable_interrupts(lp);
+	free_irq(dev->irq, dev);
+
+	return 0;
+}
+
+/**
+ * xemaclite_get_stats - Get the stats for the net_device
+ * @dev:	Pointer to the network device
+ *
+ * This function returns the address of the 'net_device_stats' structure for the
+ * given network device. This structure holds usage statistics for the network
+ * device.
+ *
+ * Return:	Pointer to the net_device_stats structure.
+ */
+static struct net_device_stats *xemaclite_get_stats(struct net_device *dev)
+{
+	return &dev->stats;
+}
+
+/**
+ * xemaclite_send - Transmit a frame
+ * @orig_skb:	Pointer to the socket buffer to be transmitted
+ * @dev:	Pointer to the network device
+ *
+ * This function checks if the Tx buffer of the Emaclite device is free to send
+ * data. If so, it fills the Tx buffer with data from socket buffer data,
+ * updates the stats and frees the socket buffer. The Tx completion is signaled
+ * by an interrupt. If the Tx buffer isn't free, then the socket buffer is
+ * deferred and the Tx queue is stopped so that the deferred socket buffer can
+ * be transmitted when the Emaclite device is free to transmit data.
+ *
+ * Return:	0, always.
+ */
+static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct sk_buff *new_skb;
+	unsigned int len;
+	unsigned long flags;
+
+	len = orig_skb->len;
+
+	new_skb = orig_skb;
+
+	spin_lock_irqsave(&lp->reset_lock, flags);
+	if (xemaclite_send_data(lp, (u8 *) new_skb->data, len) != 0) {
+		/* If the Emaclite Tx buffer is busy, stop the Tx queue and
+		 * defer the skb for transmission at a later point when the
+		 * current transmission is complete */
+		netif_stop_queue(dev);
+		lp->deferred_skb = new_skb;
+		spin_unlock_irqrestore(&lp->reset_lock, flags);
+		return 0;
+	}
+	spin_unlock_irqrestore(&lp->reset_lock, flags);
+
+	dev->stats.tx_bytes += len;
+	dev_kfree_skb(new_skb);
+	dev->trans_start = jiffies;
+
+	return 0;
+}
+
+/**
+ * xemaclite_ioctl - Perform IO Control operations on the network device
+ * @dev:	Pointer to the network device
+ * @rq:		Pointer to the interface request structure
+ * @cmd:	IOCTL command
+ *
+ * The only IOCTL operation supported by this function is setting the MAC
+ * address. An error is reported if any other operations are requested.
+ *
+ * Return:	0 to indicate success, or a negative error for failure.
+ */
+static int xemaclite_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct net_local *lp = (struct net_local *) netdev_priv(dev);
+	struct hw_addr_data *hw_addr = (struct hw_addr_data *) &rq->ifr_hwaddr;
+
+	switch (cmd) {
+	case SIOCETHTOOL:
+		return -EIO;
+
+	case SIOCSIFHWADDR:
+		dev_err(&lp->ndev->dev, "SIOCSIFHWADDR\n");
+
+		/* Copy MAC address in from user space */
+		copy_from_user((void __force *) dev->dev_addr,
+			       (void __user __force *) hw_addr,
+			       IFHWADDRLEN);
+		xemaclite_set_mac_address(lp, dev->dev_addr);
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+/**
+ * xemaclite_remove_ndev - Free the network device
+ * @ndev:	Pointer to the network device to be freed
+ *
+ * This function un maps the IO region of the Emaclite device and frees the net
+ * device.
+ */
+static void xemaclite_remove_ndev(struct net_device *ndev)
+{
+	if (ndev) {
+		struct net_local *lp = (struct net_local *) netdev_priv(ndev);
+
+		if (lp->base_addr)
+			iounmap((void __iomem __force *) (lp->base_addr));
+		free_netdev(ndev);
+	}
+}
+
+/**
+ * get_bool - Get a parameter from the OF device
+ * @ofdev:	Pointer to OF device structure
+ * @s:		Property to be retrieved
+ *
+ * This function looks for a property in the device node and returns the value
+ * of the property if its found or 0 if the property is not found.
+ *
+ * Return:	Value of the parameter if the parameter is found, or 0 otherwise
+ */
+static bool get_bool(struct of_device *ofdev, const char *s)
+{
+	u32 *p = (u32 *)of_get_property(ofdev->node, s, NULL);
+
+	if (p) {
+		return (bool)*p;
+	} else {
+		dev_warn(&ofdev->dev, "Parameter %s not found,"
+			"defaulting to false\n", s);
+		return 0;
+	}
+}
+
+static struct net_device_ops xemaclite_netdev_ops;
+
+/**
+ * xemaclite_of_probe - Probe method for the Emaclite device.
+ * @ofdev:	Pointer to OF device structure
+ * @match:	Pointer to the structure used for matching a device
+ *
+ * This function probes for the Emaclite device in the device tree.
+ * It initializes the driver data structure and the hardware, sets the MAC
+ * address and registers the network device.
+ *
+ * Return:	0, if the driver is bound to the Emaclite device, or
+ *		a negative error if there is failure.
+ */
+static int __devinit xemaclite_of_probe(struct of_device *ofdev,
+					const struct of_device_id *match)
+{
+	struct resource r_irq; /* Interrupt resources */
+	struct resource r_mem; /* IO mem resources */
+	struct net_device *ndev = NULL;
+	struct net_local *lp = NULL;
+	struct device *dev = &ofdev->dev;
+	const void *mac_address;
+
+	int rc = 0;
+
+	dev_info(dev, "Device Tree Probing\n");
+
+	/* Get iospace for the device */
+	rc = of_address_to_resource(ofdev->node, 0, &r_mem);
+	if (rc) {
+		dev_err(dev, "invalid address\n");
+		return rc;
+	}
+
+	/* Get IRQ for the device */
+	rc = of_irq_to_resource(ofdev->node, 0, &r_irq);
+	if (rc == NO_IRQ) {
+		dev_err(dev, "no IRQ found\n");
+		return rc;
+	}
+
+	/* Create an ethernet device instance */
+	ndev = alloc_etherdev(sizeof(struct net_local));
+	if (!ndev) {
+		dev_err(dev, "Could not allocate network device\n");
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(dev, ndev);
+
+	ndev->irq = r_irq.start;
+	ndev->mem_start = r_mem.start;
+	ndev->mem_end = r_mem.end;
+
+	lp = netdev_priv(ndev);
+	lp->ndev = ndev;
+
+	if (!request_mem_region(ndev->mem_start,
+				ndev->mem_end - ndev->mem_start + 1,
+				DRIVER_NAME)) {
+		dev_err(dev, "Couldn't lock memory region at %p\n",
+			(void *)ndev->mem_start);
+		rc = -EBUSY;
+		goto error2;
+	}
+
+	/* Get the virtual base address for the device */
+	lp->base_addr = ioremap(r_mem.start, r_mem.end - r_mem.start + 1);
+	if (NULL == lp->base_addr) {
+		dev_err(dev, "EmacLite: Could not allocate iomem\n");
+		rc = -EIO;
+		goto error1;
+	}
+
+	spin_lock_init(&lp->reset_lock);
+	lp->next_tx_buf_to_use = 0x0;
+	lp->next_rx_buf_to_use = 0x0;
+	lp->tx_ping_pong = get_bool(ofdev, "xlnx,tx-ping-pong");
+	lp->rx_ping_pong = get_bool(ofdev, "xlnx,rx-ping-pong");
+	mac_address = of_get_mac_address(ofdev->node);
+
+	if (mac_address)
+		/* Set the MAC address. */
+		memcpy(ndev->dev_addr, mac_address, 6);
+	else
+		dev_warn(dev, "No MAC address found\n");
+
+	/* Clear the Tx CSR's in case this is a restart */
+	out_be32(lp->base_addr + XEL_TSR_OFFSET, 0);
+	out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0);
+
+	/* Set the MAC address in the EmacLite device */
+	xemaclite_set_mac_address(lp, ndev->dev_addr);
+
+	dev_info(dev,
+		 "MAC address is now %2x:%2x:%2x:%2x:%2x:%2x\n",
+		 ndev->dev_addr[0], ndev->dev_addr[1],
+		 ndev->dev_addr[2], ndev->dev_addr[3],
+		 ndev->dev_addr[4], ndev->dev_addr[5]);
+
+	ndev->netdev_ops = &xemaclite_netdev_ops;
+	ndev->flags &= ~IFF_MULTICAST;
+	ndev->watchdog_timeo = TX_TIMEOUT;
+
+	/* Finally, register the device */
+	rc = register_netdev(ndev);
+	if (rc) {
+		dev_err(dev,
+			"Cannot register network device, aborting\n");
+		goto error1;
+	}
+
+	dev_info(dev,
+		 "Xilinx EmacLite at 0x%08X mapped to 0x%08X, irq=%d\n",
+		 (unsigned int __force)ndev->mem_start,
+		 (unsigned int __force)lp->base_addr, ndev->irq);
+	return 0;
+
+error1:
+	release_mem_region(ndev->mem_start, r_mem.end - r_mem.start + 1);
+
+error2:
+	xemaclite_remove_ndev(ndev);
+	return rc;
+}
+
+/**
+ * xemaclite_of_remove - Unbind the driver from the Emaclite device.
+ * @of_dev:	Pointer to OF device structure
+ *
+ * This function is called if a device is physically removed from the system or
+ * if the driver module is being unloaded. It frees any resources allocated to
+ * the device.
+ *
+ * Return:	0, always.
+ */
+static int __devexit xemaclite_of_remove(struct of_device *of_dev)
+{
+	struct device *dev = &of_dev->dev;
+	struct net_device *ndev = dev_get_drvdata(dev);
+
+	unregister_netdev(ndev);
+
+	release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1);
+
+	xemaclite_remove_ndev(ndev);
+
+	dev_set_drvdata(dev, NULL);
+
+	return 0;
+}
+
+static struct net_device_ops xemaclite_netdev_ops = {
+	.ndo_open		= xemaclite_open,
+	.ndo_stop		= xemaclite_close,
+	.ndo_start_xmit		= xemaclite_send,
+	.ndo_do_ioctl		= xemaclite_ioctl,
+	.ndo_tx_timeout		= xemaclite_tx_timeout,
+	.ndo_get_stats		= xemaclite_get_stats,
+};
+
+/* Match table for OF platform binding */
+static struct of_device_id xemaclite_of_match[] __devinitdata = {
+	{ .compatible = "xlnx,opb-ethernetlite-1.01.a", },
+	{ .compatible = "xlnx,opb-ethernetlite-1.01.b", },
+	{ .compatible = "xlnx,xps-ethernetlite-1.00.a", },
+	{ .compatible = "xlnx,xps-ethernetlite-2.00.a", },
+	{ .compatible = "xlnx,xps-ethernetlite-2.01.a", },
+	{ /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, xemaclite_of_match);
+
+static struct of_platform_driver xemaclite_of_driver = {
+	.name		= DRIVER_NAME,
+	.match_table	= xemaclite_of_match,
+	.probe		= xemaclite_of_probe,
+	.remove		= __devexit_p(xemaclite_of_remove),
+};
+
+/**
+ * xgpiopss_init - Initial driver registration call
+ *
+ * Return:	0 upon success, or a negative error upon failure.
+ */
+static int __init xemaclite_init(void)
+{
+	/* No kernel boot options used, we just need to register the driver */
+	return of_register_platform_driver(&xemaclite_of_driver);
+}
+
+/**
+ * xemaclite_cleanup - Driver un-registration call
+ */
+static void __exit xemaclite_cleanup(void)
+{
+	of_unregister_platform_driver(&xemaclite_of_driver);
+}
+
+module_init(xemaclite_init);
+module_exit(xemaclite_cleanup);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION("Xilinx Ethernet MAC Lite driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/xtsonic.c b/drivers/net/xtsonic.c
index 5a4ad15..0c44135 100644
--- a/drivers/net/xtsonic.c
+++ b/drivers/net/xtsonic.c
@@ -239,7 +239,7 @@ out:
  * Actually probing is superfluous but we're paranoid.
  */
 
-int __init xtsonic_probe(struct platform_device *pdev)
+int __devinit xtsonic_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
 	struct sonic_local *lp;
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index c2fd618..40ad0de 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -347,7 +347,8 @@ static int yellowfin_open(struct net_device *dev);
 static void yellowfin_timer(unsigned long data);
 static void yellowfin_tx_timeout(struct net_device *dev);
 static int yellowfin_init_ring(struct net_device *dev);
-static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb,
+					struct net_device *dev);
 static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance);
 static int yellowfin_rx(struct net_device *dev);
 static void yellowfin_error(struct net_device *dev, int intr_status);
@@ -816,7 +817,8 @@ static int yellowfin_init_ring(struct net_device *dev)
 	return 0;
 }
 
-static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
 	struct yellowfin_private *yp = netdev_priv(dev);
 	unsigned entry;
@@ -838,7 +840,7 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			if (skb_padto(skb, len)) {
 				yp->tx_skbuff[entry] = NULL;
 				netif_wake_queue(dev);
-				return 0;
+				return NETDEV_TX_OK;
 			}
 		}
 	}
@@ -892,7 +894,7 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_DEBUG "%s: Yellowfin transmit frame #%d queued in slot %d.\n",
 			   dev->name, yp->cur_tx, entry);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
@@ -1363,8 +1365,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 		return 0;
 
 	case SIOCSMIIREG:		/* Write MII PHY register. */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
 		if (data->phy_id == np->phys[0]) {
 			u16 value = data->val_in;
 			switch (data->reg_num) {
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index 0a6992d..a0384b6 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -156,7 +156,8 @@ struct netidblk {
 };
 
 static int	znet_open(struct net_device *dev);
-static int	znet_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t znet_send_packet(struct sk_buff *skb,
+				    struct net_device *dev);
 static irqreturn_t znet_interrupt(int irq, void *dev_id);
 static void	znet_rx(struct net_device *dev);
 static int	znet_close(struct net_device *dev);
@@ -534,7 +535,7 @@ static void znet_tx_timeout (struct net_device *dev)
 	netif_wake_queue (dev);
 }
 
-static int znet_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t znet_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
 	struct znet_private *znet = netdev_priv(dev);
@@ -546,7 +547,7 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev)
 
 	if (length < ETH_ZLEN) {
 		if (skb_padto(skb, ETH_ZLEN))
-			return 0;
+			return NETDEV_TX_OK;
 		length = ETH_ZLEN;
 	}
 
@@ -600,7 +601,7 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev)
 		  printk(KERN_DEBUG "%s: Transmitter queued, length %d.\n", dev->name, length);
 	}
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The ZNET interrupt handler. */
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 1ebd6b4..4a7f11d 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -8,6 +8,9 @@ obj-y		+= access.o bus.o probe.o remove.o pci.o quirks.o \
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_SYSFS) += slot.o
 
+obj-$(CONFIG_PCI_LEGACY) += legacy.o
+CFLAGS_legacy.o += -Wno-deprecated-declarations
+
 # Build PCI Express stuff if needed
 obj-$(CONFIG_PCIEPORTBUS) += pcie/
 
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 7b287cb..ab99783 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -33,6 +33,7 @@
 #include <linux/timer.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/tboot.h>
 
 #undef PREFIX
 #define PREFIX "DMAR:"
@@ -413,6 +414,12 @@ parse_dmar_table(void)
 	 */
 	dmar_table_detect();
 
+	/*
+	 * ACPI tables may not be DMA protected by tboot, so use DMAR copy
+	 * SINIT saved in SinitMleData in TXT heap (which is DMA protected)
+	 */
+	dmar_tbl = tboot_get_dmar_table(dmar_tbl);
+
 	dmar = (struct acpi_table_dmar *)dmar_tbl;
 	if (!dmar)
 		return -ENODEV;
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile
index 2aa117c..3625b09 100644
--- a/drivers/pci/hotplug/Makefile
+++ b/drivers/pci/hotplug/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_HOTPLUG_PCI_SGI)		+= sgi_hotplug.o
 # Link this last so it doesn't claim devices that have a real hotplug driver
 obj-$(CONFIG_HOTPLUG_PCI_FAKE)		+= fakephp.o
 
-pci_hotplug-objs	:=	pci_hotplug_core.o
+pci_hotplug-objs	:=	pci_hotplug_core.o pcihp_slot.o
 
 ifdef CONFIG_HOTPLUG_PCI_CPCI
 pci_hotplug-objs	+=	cpci_hotplug_core.o	\
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index eb15958..a73028e 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -41,7 +41,6 @@
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
 
 #define	METHOD_NAME__SUN	"_SUN"
-#define	METHOD_NAME__HPP	"_HPP"
 #define	METHOD_NAME_OSHP	"OSHP"
 
 static int debug_acpi;
@@ -215,80 +214,41 @@ acpi_run_hpx(acpi_handle handle, struct hotplug_params *hpx)
 static acpi_status
 acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
 {
-	acpi_status		status;
-	u8			nui[4];
-	struct acpi_buffer	ret_buf = { 0, NULL};
-	struct acpi_buffer	string = { ACPI_ALLOCATE_BUFFER, NULL };
-	union acpi_object	*ext_obj, *package;
-	int			i, len = 0;
-
-	acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
+	acpi_status status;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *package, *fields;
+	int i;
 
-	/* Clear the return buffer with zeros */
 	memset(hpp, 0, sizeof(struct hotplug_params));
 
-	/* get _hpp */
-	status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
-	switch (status) {
-	case AE_BUFFER_OVERFLOW:
-		ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
-		if (!ret_buf.pointer) {
-			printk(KERN_ERR "%s:%s alloc for _HPP fail\n",
-				__func__, (char *)string.pointer);
-			kfree(string.pointer);
-			return AE_NO_MEMORY;
-		}
-		status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
-				NULL, &ret_buf);
-		if (ACPI_SUCCESS(status))
-			break;
-	default:
-		if (ACPI_FAILURE(status)) {
-			pr_debug("%s:%s _HPP fail=0x%x\n", __func__,
-				(char *)string.pointer, status);
-			kfree(string.pointer);
-			return status;
-		}
-	}
+	status = acpi_evaluate_object(handle, "_HPP", NULL, &buffer);
+	if (ACPI_FAILURE(status))
+		return status;
 
-	ext_obj = (union acpi_object *) ret_buf.pointer;
-	if (ext_obj->type != ACPI_TYPE_PACKAGE) {
-		printk(KERN_ERR "%s:%s _HPP obj not a package\n", __func__,
-				(char *)string.pointer);
+	package = (union acpi_object *) buffer.pointer;
+	if (package->type != ACPI_TYPE_PACKAGE ||
+	    package->package.count != 4) {
 		status = AE_ERROR;
-		goto free_and_return;
+		goto exit;
 	}
 
-	len = ext_obj->package.count;
-	package = (union acpi_object *) ret_buf.pointer;
-	for ( i = 0; (i < len) || (i < 4); i++) {
-		ext_obj = (union acpi_object *) &package->package.elements[i];
-		switch (ext_obj->type) {
-		case ACPI_TYPE_INTEGER:
-			nui[i] = (u8)ext_obj->integer.value;
-			break;
-		default:
-			printk(KERN_ERR "%s:%s _HPP obj type incorrect\n",
-				__func__, (char *)string.pointer);
+	fields = package->package.elements;
+	for (i = 0; i < 4; i++) {
+		if (fields[i].type != ACPI_TYPE_INTEGER) {
 			status = AE_ERROR;
-			goto free_and_return;
+			goto exit;
 		}
 	}
 
 	hpp->t0 = &hpp->type0_data;
-	hpp->t0->cache_line_size = nui[0];
-	hpp->t0->latency_timer = nui[1];
-	hpp->t0->enable_serr = nui[2];
-	hpp->t0->enable_perr = nui[3];
-
-	pr_debug("  _HPP: cache_line_size=0x%x\n", hpp->t0->cache_line_size);
-	pr_debug("  _HPP: latency timer  =0x%x\n", hpp->t0->latency_timer);
-	pr_debug("  _HPP: enable SERR    =0x%x\n", hpp->t0->enable_serr);
-	pr_debug("  _HPP: enable PERR    =0x%x\n", hpp->t0->enable_perr);
+	hpp->t0->revision        = 1;
+	hpp->t0->cache_line_size = fields[0].integer.value;
+	hpp->t0->latency_timer   = fields[1].integer.value;
+	hpp->t0->enable_serr     = fields[2].integer.value;
+	hpp->t0->enable_perr     = fields[3].integer.value;
 
-free_and_return:
-	kfree(string.pointer);
-	kfree(ret_buf.pointer);
+exit:
+	kfree(buffer.pointer);
 	return status;
 }
 
@@ -322,20 +282,19 @@ static acpi_status acpi_run_oshp(acpi_handle handle)
 	return status;
 }
 
-/* acpi_get_hp_params_from_firmware
+/* pci_get_hp_params
  *
- * @bus - the pci_bus of the bus on which the device is newly added
+ * @dev - the pci_dev for which we want parameters
  * @hpp - allocated by the caller
  */
-acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
-		struct hotplug_params *hpp)
+int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp)
 {
-	acpi_status status = AE_NOT_FOUND;
+	acpi_status status;
 	acpi_handle handle, phandle;
 	struct pci_bus *pbus;
 
 	handle = NULL;
-	for (pbus = bus; pbus; pbus = pbus->parent) {
+	for (pbus = dev->bus; pbus; pbus = pbus->parent) {
 		handle = acpi_pci_get_bridge_handle(pbus);
 		if (handle)
 			break;
@@ -345,15 +304,15 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
 	 * _HPP settings apply to all child buses, until another _HPP is
 	 * encountered. If we don't find an _HPP for the input pci dev,
 	 * look for it in the parent device scope since that would apply to
-	 * this pci dev. If we don't find any _HPP, use hardcoded defaults
+	 * this pci dev.
 	 */
 	while (handle) {
 		status = acpi_run_hpx(handle, hpp);
 		if (ACPI_SUCCESS(status))
-			break;
+			return 0;
 		status = acpi_run_hpp(handle, hpp);
 		if (ACPI_SUCCESS(status))
-			break;
+			return 0;
 		if (acpi_is_root_bridge(handle))
 			break;
 		status = acpi_get_parent(handle, &phandle);
@@ -361,9 +320,9 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
 			break;
 		handle = phandle;
 	}
-	return status;
+	return -ENODEV;
 }
-EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
+EXPORT_SYMBOL_GPL(pci_get_hp_params);
 
 /**
  * acpi_get_hp_hw_control_from_firmware
@@ -500,18 +459,18 @@ check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv)
 
 /**
  * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots
- * @pbus - PCI bus to scan
+ * @handle - handle of the PCI bus to scan
  *
  * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise.
  */
-int acpi_pci_detect_ejectable(struct pci_bus *pbus)
+int acpi_pci_detect_ejectable(acpi_handle handle)
 {
-	acpi_handle handle;
 	int found = 0;
 
-	if (!(handle = acpi_pci_get_bridge_handle(pbus)))
-		return 0;
-	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
+	if (!handle)
+		return found;
+
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
 			    check_hotplug, (void *)&found, NULL);
 	return found;
 }
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index e68d5f2..7d938df 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -91,9 +91,6 @@ struct acpiphp_bridge {
 	/* PCI-to-PCI bridge device */
 	struct pci_dev *pci_dev;
 
-	/* ACPI 2.0 _HPP parameters */
-	struct hotplug_params hpp;
-
 	spinlock_t res_lock;
 };
 
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 0cb0f83..58d25a1 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -59,7 +59,7 @@ static DEFINE_SPINLOCK(ioapic_list_lock);
 
 static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
 static void acpiphp_sanitize_bus(struct pci_bus *bus);
-static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus);
+static void acpiphp_set_hpp_values(struct pci_bus *bus);
 static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
 
 /* callback routine to check for the existence of a pci dock device */
@@ -261,51 +261,21 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
 
 
 /* see if it's worth looking at this bridge */
-static int detect_ejectable_slots(struct pci_bus *pbus)
+static int detect_ejectable_slots(acpi_handle handle)
 {
-	int found = acpi_pci_detect_ejectable(pbus);
+	int found = acpi_pci_detect_ejectable(handle);
 	if (!found) {
-		acpi_handle bridge_handle = acpi_pci_get_bridge_handle(pbus);
-		if (!bridge_handle)
-			return 0;
-		acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge_handle, (u32)1,
+		acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
 				    is_pci_dock_device, (void *)&found, NULL);
 	}
 	return found;
 }
 
-
-/* decode ACPI 2.0 _HPP hot plug parameters */
-static void decode_hpp(struct acpiphp_bridge *bridge)
-{
-	acpi_status status;
-
-	status = acpi_get_hp_params_from_firmware(bridge->pci_bus, &bridge->hpp);
-	if (ACPI_FAILURE(status) ||
-	    !bridge->hpp.t0 || (bridge->hpp.t0->revision > 1)) {
-		/* use default numbers */
-		printk(KERN_WARNING
-		       "%s: Could not get hotplug parameters. Use defaults\n",
-		       __func__);
-		bridge->hpp.t0 = &bridge->hpp.type0_data;
-		bridge->hpp.t0->revision = 0;
-		bridge->hpp.t0->cache_line_size = 0x10;
-		bridge->hpp.t0->latency_timer = 0x40;
-		bridge->hpp.t0->enable_serr = 0;
-		bridge->hpp.t0->enable_perr = 0;
-	}
-}
-
-
-
 /* initialize miscellaneous stuff for both root and PCI-to-PCI bridge */
 static void init_bridge_misc(struct acpiphp_bridge *bridge)
 {
 	acpi_status status;
 
-	/* decode ACPI 2.0 _HPP (hot plug parameters) */
-	decode_hpp(bridge);
-
 	/* must be added to the list prior to calling register_slot */
 	list_add(&bridge->list, &bridge_list);
 
@@ -399,9 +369,10 @@ static inline void config_p2p_bridge_flags(struct acpiphp_bridge *bridge)
 
 
 /* allocate and initialize host bridge data structure */
-static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
+static void add_host_bridge(acpi_handle *handle)
 {
 	struct acpiphp_bridge *bridge;
+	struct acpi_pci_root *root = acpi_pci_find_root(handle);
 
 	bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
 	if (bridge == NULL)
@@ -410,7 +381,7 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
 	bridge->type = BRIDGE_TYPE_HOST;
 	bridge->handle = handle;
 
-	bridge->pci_bus = pci_bus;
+	bridge->pci_bus = root->bus;
 
 	spin_lock_init(&bridge->res_lock);
 
@@ -419,7 +390,7 @@ static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus)
 
 
 /* allocate and initialize PCI-to-PCI bridge data structure */
-static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
+static void add_p2p_bridge(acpi_handle *handle)
 {
 	struct acpiphp_bridge *bridge;
 
@@ -433,8 +404,8 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
 	bridge->handle = handle;
 	config_p2p_bridge_flags(bridge);
 
-	bridge->pci_dev = pci_dev_get(pci_dev);
-	bridge->pci_bus = pci_dev->subordinate;
+	bridge->pci_dev = acpi_get_pci_dev(handle);
+	bridge->pci_bus = bridge->pci_dev->subordinate;
 	if (!bridge->pci_bus) {
 		err("This is not a PCI-to-PCI bridge!\n");
 		goto err;
@@ -451,7 +422,7 @@ static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev)
 	init_bridge_misc(bridge);
 	return;
  err:
-	pci_dev_put(pci_dev);
+	pci_dev_put(bridge->pci_dev);
 	kfree(bridge);
 	return;
 }
@@ -462,39 +433,21 @@ static acpi_status
 find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv)
 {
 	acpi_status status;
-	acpi_handle dummy_handle;
-	unsigned long long tmp;
-	int device, function;
 	struct pci_dev *dev;
-	struct pci_bus *pci_bus = context;
-
-	status = acpi_get_handle(handle, "_ADR", &dummy_handle);
-	if (ACPI_FAILURE(status))
-		return AE_OK;		/* continue */
-
-	status = acpi_evaluate_integer(handle, "_ADR", NULL, &tmp);
-	if (ACPI_FAILURE(status)) {
-		dbg("%s: _ADR evaluation failure\n", __func__);
-		return AE_OK;
-	}
-
-	device = (tmp >> 16) & 0xffff;
-	function = tmp & 0xffff;
-
-	dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function));
 
+	dev = acpi_get_pci_dev(handle);
 	if (!dev || !dev->subordinate)
 		goto out;
 
 	/* check if this bridge has ejectable slots */
-	if ((detect_ejectable_slots(dev->subordinate) > 0)) {
+	if ((detect_ejectable_slots(handle) > 0)) {
 		dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev));
-		add_p2p_bridge(handle, dev);
+		add_p2p_bridge(handle);
 	}
 
 	/* search P2P bridges under this p2p bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, dev->subordinate, NULL);
+				     find_p2p_bridge, NULL, NULL);
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
 
@@ -509,9 +462,7 @@ static int add_bridge(acpi_handle handle)
 {
 	acpi_status status;
 	unsigned long long tmp;
-	int seg, bus;
 	acpi_handle dummy_handle;
-	struct pci_bus *pci_bus;
 
 	/* if the bridge doesn't have _STA, we assume it is always there */
 	status = acpi_get_handle(handle, "_STA", &dummy_handle);
@@ -526,36 +477,15 @@ static int add_bridge(acpi_handle handle)
 			return 0;
 	}
 
-	/* get PCI segment number */
-	status = acpi_evaluate_integer(handle, "_SEG", NULL, &tmp);
-
-	seg = ACPI_SUCCESS(status) ? tmp : 0;
-
-	/* get PCI bus number */
-	status = acpi_evaluate_integer(handle, "_BBN", NULL, &tmp);
-
-	if (ACPI_SUCCESS(status)) {
-		bus = tmp;
-	} else {
-		warn("can't get bus number, assuming 0\n");
-		bus = 0;
-	}
-
-	pci_bus = pci_find_bus(seg, bus);
-	if (!pci_bus) {
-		err("Can't find bus %04x:%02x\n", seg, bus);
-		return 0;
-	}
-
 	/* check if this bridge has ejectable slots */
-	if (detect_ejectable_slots(pci_bus) > 0) {
+	if (detect_ejectable_slots(handle) > 0) {
 		dbg("found PCI host-bus bridge with hot-pluggable slots\n");
-		add_host_bridge(handle, pci_bus);
+		add_host_bridge(handle);
 	}
 
 	/* search P2P bridges under this host bridge */
 	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1,
-				     find_p2p_bridge, pci_bus, NULL);
+				     find_p2p_bridge, NULL, NULL);
 
 	if (ACPI_FAILURE(status))
 		warn("find_p2p_bridge failed (error code = 0x%x)\n", status);
@@ -1083,7 +1013,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
 
 	pci_bus_assign_resources(bus);
 	acpiphp_sanitize_bus(bus);
-	acpiphp_set_hpp_values(slot->bridge->handle, bus);
+	acpiphp_set_hpp_values(bus);
 	list_for_each_entry(func, &slot->funcs, sibling)
 		acpiphp_configure_ioapics(func->handle);
 	pci_enable_bridges(bus);
@@ -1294,70 +1224,12 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge)
 	return retval;
 }
 
-static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge)
+static void acpiphp_set_hpp_values(struct pci_bus *bus)
 {
-	u16 pci_cmd, pci_bctl;
-	struct pci_dev *cdev;
-
-	/* Program hpp values for this device */
-	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
-			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
-			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
-		return;
-
-	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
-		return;
-
-	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
-			bridge->hpp.t0->cache_line_size);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER,
-			bridge->hpp.t0->latency_timer);
-	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
-	if (bridge->hpp.t0->enable_serr)
-		pci_cmd |= PCI_COMMAND_SERR;
-	else
-		pci_cmd &= ~PCI_COMMAND_SERR;
-	if (bridge->hpp.t0->enable_perr)
-		pci_cmd |= PCI_COMMAND_PARITY;
-	else
-		pci_cmd &= ~PCI_COMMAND_PARITY;
-	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
-
-	/* Program bridge control value and child devices */
-	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
-		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
-				bridge->hpp.t0->latency_timer);
-		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
-		if (bridge->hpp.t0->enable_serr)
-			pci_bctl |= PCI_BRIDGE_CTL_SERR;
-		else
-			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
-		if (bridge->hpp.t0->enable_perr)
-			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
-		else
-			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
-		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
-		if (dev->subordinate) {
-			list_for_each_entry(cdev, &dev->subordinate->devices,
-					bus_list)
-				program_hpp(cdev, bridge);
-		}
-	}
-}
-
-static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus)
-{
-	struct acpiphp_bridge bridge;
 	struct pci_dev *dev;
 
-	memset(&bridge, 0, sizeof(bridge));
-	bridge.handle = handle;
-	bridge.pci_bus = bus;
-	bridge.pci_dev = bus->self;
-	decode_hpp(&bridge);
 	list_for_each_entry(dev, &bus->devices, bus_list)
-		program_hpp(dev, &bridge);
-
+		pci_configure_slot(dev);
 }
 
 /*
@@ -1387,24 +1259,23 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
 /* Program resources in newly inserted bridge */
 static int acpiphp_configure_bridge (acpi_handle handle)
 {
-	struct pci_dev *dev;
 	struct pci_bus *bus;
 
-	dev = acpi_get_pci_dev(handle);
-	if (!dev) {
-		err("cannot get PCI domain and bus number for bridge\n");
-		return -EINVAL;
+	if (acpi_is_root_bridge(handle)) {
+		struct acpi_pci_root *root = acpi_pci_find_root(handle);
+		bus = root->bus;
+	} else {
+		struct pci_dev *pdev = acpi_get_pci_dev(handle);
+		bus = pdev->subordinate;
+		pci_dev_put(pdev);
 	}
 
-	bus = dev->bus;
-
 	pci_bus_size_bridges(bus);
 	pci_bus_assign_resources(bus);
 	acpiphp_sanitize_bus(bus);
-	acpiphp_set_hpp_values(handle, bus);
+	acpiphp_set_hpp_values(bus);
 	pci_enable_bridges(bus);
 	acpiphp_configure_ioapics(handle);
-	pci_dev_put(dev);
 	return 0;
 }
 
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 5c5043f..0325d98 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -86,7 +86,8 @@ static char *pci_bus_speed_strings[] = {
 	"66 MHz PCIX 533",	/* 0x11 */
 	"100 MHz PCIX 533",	/* 0x12 */
 	"133 MHz PCIX 533",	/* 0x13 */
-	"25 GBps PCI-E",	/* 0x14 */
+	"2.5 GT/s PCI-E",	/* 0x14 */
+	"5.0 GT/s PCI-E",	/* 0x15 */
 };
 
 #ifdef CONFIG_HOTPLUG_PCI_CPCI
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index e6cf096..36faa9a 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -237,17 +237,8 @@ static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
 		return retval;
 	return pciehp_acpi_slot_detection_check(dev);
 }
-
-static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
-			struct hotplug_params *hpp)
-{
-	if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
-		return -ENODEV;
-	return 0;
-}
 #else
 #define pciehp_firmware_init()				do {} while (0)
 #define pciehp_get_hp_hw_control_from_firmware(dev) 	0
-#define pciehp_get_hp_params_from_firmware(dev, hpp)    (-ENODEV)
 #endif 				/* CONFIG_ACPI */
 #endif				/* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 9604801..7163e6a 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -47,7 +47,7 @@ int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
 {
 	if (slot_detection_mode != PCIEHP_DETECT_ACPI)
 		return 0;
-	if (acpi_pci_detect_ejectable(dev->subordinate))
+	if (acpi_pci_detect_ejectable(DEVICE_ACPI_HANDLE(&dev->dev)))
 		return 0;
 	return -ENODEV;
 }
@@ -76,9 +76,9 @@ static int __init dummy_probe(struct pcie_device *dev)
 {
 	int pos;
 	u32 slot_cap;
+	acpi_handle handle;
 	struct slot *slot, *tmp;
 	struct pci_dev *pdev = dev->port;
-	struct pci_bus *pbus = pdev->subordinate;
 	/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
 	if (pciehp_get_hp_hw_control_from_firmware(pdev))
 		return -ENODEV;
@@ -94,7 +94,8 @@ static int __init dummy_probe(struct pcie_device *dev)
 			dup_slot_id++;
 	}
 	list_add_tail(&slot->slot_list, &dummy_slots);
-	if (!acpi_slot_detected && acpi_pci_detect_ejectable(pbus))
+	handle = DEVICE_ACPI_HANDLE(&pdev->dev);
+	if (!acpi_slot_detected && acpi_pci_detect_ejectable(handle))
 		acpi_slot_detected = 1;
 	return -ENODEV;         /* dummy driver always returns error */
 }
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 8aab8ed..b97cb4c 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -246,11 +246,6 @@ static int board_added(struct slot *p_slot)
 		goto err_exit;
 	}
 
-	/*
-	 * Some PCI Express root ports require fixup after hot-plug operation.
-	 */
-	if (pcie_mch_quirk)
-		pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
 	if (PWR_LED(ctrl))
   		p_slot->hpc_ops->green_led_on(p_slot);
 
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 5281325..271f917 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -693,7 +693,10 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
 
 	switch (lnk_cap & 0x000F) {
 	case 1:
-		lnk_speed = PCIE_2PT5GB;
+		lnk_speed = PCIE_2_5GB;
+		break;
+	case 2:
+		lnk_speed = PCIE_5_0GB;
 		break;
 	default:
 		lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
@@ -772,7 +775,10 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
 
 	switch (lnk_status & PCI_EXP_LNKSTA_CLS) {
 	case 1:
-		lnk_speed = PCIE_2PT5GB;
+		lnk_speed = PCIE_2_5GB;
+		break;
+	case 2:
+		lnk_speed = PCIE_5_0GB;
 		break;
 	default:
 		lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 10f9566..02e24d6 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -34,136 +34,6 @@
 #include "../pci.h"
 #include "pciehp.h"
 
-static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
-{
-	u16 pci_cmd, pci_bctl;
-
-	if (hpp->revision > 1) {
-		warn("Rev.%d type0 record not supported\n", hpp->revision);
-		return;
-	}
-
-	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
-	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
-	if (hpp->enable_serr)
-		pci_cmd |= PCI_COMMAND_SERR;
-	else
-		pci_cmd &= ~PCI_COMMAND_SERR;
-	if (hpp->enable_perr)
-		pci_cmd |= PCI_COMMAND_PARITY;
-	else
-		pci_cmd &= ~PCI_COMMAND_PARITY;
-	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
-
-	/* Program bridge control value */
-	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
-		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
-				      hpp->latency_timer);
-		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
-		if (hpp->enable_serr)
-			pci_bctl |= PCI_BRIDGE_CTL_SERR;
-		else
-			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
-		if (hpp->enable_perr)
-			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
-		else
-			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
-		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
-	}
-}
-
-static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
-{
-	int pos;
-	u16 reg16;
-	u32 reg32;
-
-	if (hpp->revision > 1) {
-		warn("Rev.%d type2 record not supported\n", hpp->revision);
-		return;
-	}
-
-	/* Find PCI Express capability */
-	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-	if (!pos)
-		return;
-
-	/* Initialize Device Control Register */
-	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
-	reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
-	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
-
-	/* Initialize Link Control Register */
-	if (dev->subordinate) {
-		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
-		reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
-			| hpp->pci_exp_lnkctl_or;
-		pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
-	}
-
-	/* Find Advanced Error Reporting Enhanced Capability */
-	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-	if (!pos)
-		return;
-
-	/* Initialize Uncorrectable Error Mask Register */
-	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
-	reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
-	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
-
-	/* Initialize Uncorrectable Error Severity Register */
-	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
-	reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
-	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
-
-	/* Initialize Correctable Error Mask Register */
-	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
-	reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
-	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
-
-	/* Initialize Advanced Error Capabilities and Control Register */
-	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
-	reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
-	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
-
-	/*
-	 * FIXME: The following two registers are not supported yet.
-	 *
-	 *   o Secondary Uncorrectable Error Severity Register
-	 *   o Secondary Uncorrectable Error Mask Register
-	 */
-}
-
-static void program_fw_provided_values(struct pci_dev *dev)
-{
-	struct pci_dev *cdev;
-	struct hotplug_params hpp;
-
-	/* Program hpp values for this device */
-	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
-			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
-			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
-		return;
-
-	if (pciehp_get_hp_params_from_firmware(dev, &hpp)) {
-		warn("Could not get hotplug parameters\n");
-		return;
-	}
-
-	if (hpp.t2)
-		program_hpp_type2(dev, hpp.t2);
-	if (hpp.t0)
-		program_hpp_type0(dev, hpp.t0);
-
-	/* Program child devices */
-	if (dev->subordinate) {
-		list_for_each_entry(cdev, &dev->subordinate->devices,
-				    bus_list)
-			program_fw_provided_values(cdev);
-	}
-}
-
 static int __ref pciehp_add_bridge(struct pci_dev *dev)
 {
 	struct pci_bus *parent = dev->bus;
@@ -226,7 +96,7 @@ int pciehp_configure_device(struct slot *p_slot)
 				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
 			pciehp_add_bridge(dev);
 		}
-		program_fw_provided_values(dev);
+		pci_configure_slot(dev);
 		pci_dev_put(dev);
 	}
 
@@ -285,11 +155,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)
 		}
 		pci_dev_put(temp);
 	}
-	/*
-	 * Some PCI Express root ports require fixup after hot-plug operation.
-	 */
-	if (pcie_mch_quirk)
-		pci_fixup_device(pci_fixup_final, p_slot->ctrl->pci_dev);
 
 	return rc;
 }
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c
new file mode 100644
index 0000000..cc8ec3a
--- /dev/null
+++ b/drivers/pci/hotplug/pcihp_slot.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 1995,2001 Compaq Computer Corporation
+ * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2001 IBM Corp.
+ * Copyright (C) 2003-2004 Intel Corporation
+ * (c) Copyright 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU 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.
+ */
+
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
+
+static struct hpp_type0 pci_default_type0 = {
+	.revision = 1,
+	.cache_line_size = 8,
+	.latency_timer = 0x40,
+	.enable_serr = 0,
+	.enable_perr = 0,
+};
+
+static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
+{
+	u16 pci_cmd, pci_bctl;
+
+	if (!hpp) {
+		/*
+		 * Perhaps we *should* use default settings for PCIe, but
+		 * pciehp didn't, so we won't either.
+		 */
+		if (dev->is_pcie)
+			return;
+		dev_info(&dev->dev, "using default PCI settings\n");
+		hpp = &pci_default_type0;
+	}
+
+	if (hpp->revision > 1) {
+		dev_warn(&dev->dev,
+			 "PCI settings rev %d not supported; using defaults\n",
+			 hpp->revision);
+		hpp = &pci_default_type0;
+	}
+
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, hpp->cache_line_size);
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp->latency_timer);
+	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+	if (hpp->enable_serr)
+		pci_cmd |= PCI_COMMAND_SERR;
+	else
+		pci_cmd &= ~PCI_COMMAND_SERR;
+	if (hpp->enable_perr)
+		pci_cmd |= PCI_COMMAND_PARITY;
+	else
+		pci_cmd &= ~PCI_COMMAND_PARITY;
+	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+
+	/* Program bridge control value */
+	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
+				      hpp->latency_timer);
+		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
+		if (hpp->enable_serr)
+			pci_bctl |= PCI_BRIDGE_CTL_SERR;
+		else
+			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
+		if (hpp->enable_perr)
+			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
+		else
+			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
+		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
+	}
+}
+
+static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
+{
+	if (hpp)
+		dev_warn(&dev->dev, "PCI-X settings not supported\n");
+}
+
+static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
+{
+	int pos;
+	u16 reg16;
+	u32 reg32;
+
+	if (!hpp)
+		return;
+
+	/* Find PCI Express capability */
+	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+	if (!pos)
+		return;
+
+	if (hpp->revision > 1) {
+		dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
+			 hpp->revision);
+		return;
+	}
+
+	/* Initialize Device Control Register */
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &reg16);
+	reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16);
+
+	/* Initialize Link Control Register */
+	if (dev->subordinate) {
+		pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &reg16);
+		reg16 = (reg16 & hpp->pci_exp_lnkctl_and)
+			| hpp->pci_exp_lnkctl_or;
+		pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16);
+	}
+
+	/* Find Advanced Error Reporting Enhanced Capability */
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+	if (!pos)
+		return;
+
+	/* Initialize Uncorrectable Error Mask Register */
+	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &reg32);
+	reg32 = (reg32 & hpp->unc_err_mask_and) | hpp->unc_err_mask_or;
+	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, reg32);
+
+	/* Initialize Uncorrectable Error Severity Register */
+	pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &reg32);
+	reg32 = (reg32 & hpp->unc_err_sever_and) | hpp->unc_err_sever_or;
+	pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, reg32);
+
+	/* Initialize Correctable Error Mask Register */
+	pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg32);
+	reg32 = (reg32 & hpp->cor_err_mask_and) | hpp->cor_err_mask_or;
+	pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg32);
+
+	/* Initialize Advanced Error Capabilities and Control Register */
+	pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
+	reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
+	pci_write_config_dword(dev, pos + PCI_ERR_CAP, reg32);
+
+	/*
+	 * FIXME: The following two registers are not supported yet.
+	 *
+	 *   o Secondary Uncorrectable Error Severity Register
+	 *   o Secondary Uncorrectable Error Mask Register
+	 */
+}
+
+void pci_configure_slot(struct pci_dev *dev)
+{
+	struct pci_dev *cdev;
+	struct hotplug_params hpp;
+	int ret;
+
+	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
+			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
+		return;
+
+	memset(&hpp, 0, sizeof(hpp));
+	ret = pci_get_hp_params(dev, &hpp);
+	if (ret)
+		dev_warn(&dev->dev, "no hotplug settings from platform\n");
+
+	program_hpp_type2(dev, hpp.t2);
+	program_hpp_type1(dev, hpp.t1);
+	program_hpp_type0(dev, hpp.t0);
+
+	if (dev->subordinate) {
+		list_for_each_entry(cdev, &dev->subordinate->devices,
+				    bus_list)
+			pci_configure_slot(cdev);
+	}
+}
+EXPORT_SYMBOL_GPL(pci_configure_slot);
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 974e924..bd588eb 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -188,21 +188,12 @@ static inline const char *slot_name(struct slot *slot)
 
 #ifdef CONFIG_ACPI
 #include <linux/pci-acpi.h>
-static inline int get_hp_params_from_firmware(struct pci_dev *dev,
-					      struct hotplug_params *hpp)
-{
-	if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp)))
-			return -ENODEV;
-	return 0;
-}
-
 static inline int get_hp_hw_control_from_firmware(struct pci_dev *dev)
 {
 	u32 flags = OSC_SHPC_NATIVE_HP_CONTROL;
 	return acpi_get_hp_hw_control_from_firmware(dev, flags);
 }
 #else
-#define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
 #define get_hp_hw_control_from_firmware(dev) (0)
 #endif
 
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index aa315e5..8c3d321 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -34,66 +34,6 @@
 #include "../pci.h"
 #include "shpchp.h"
 
-static void program_fw_provided_values(struct pci_dev *dev)
-{
-	u16 pci_cmd, pci_bctl;
-	struct pci_dev *cdev;
-	struct hotplug_params hpp;
-
-	/* Program hpp values for this device */
-	if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL ||
-			(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
-			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
-		return;
-
-	/* use default values if we can't get them from firmware */
-	if (get_hp_params_from_firmware(dev, &hpp) ||
-	    !hpp.t0 || (hpp.t0->revision > 1)) {
-		warn("Could not get hotplug parameters. Use defaults\n");
-		hpp.t0 = &hpp.type0_data;
-		hpp.t0->revision = 0;
-		hpp.t0->cache_line_size = 8;
-		hpp.t0->latency_timer = 0x40;
-		hpp.t0->enable_serr = 0;
-		hpp.t0->enable_perr = 0;
-	}
-
-	pci_write_config_byte(dev,
-			      PCI_CACHE_LINE_SIZE, hpp.t0->cache_line_size);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, hpp.t0->latency_timer);
-	pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
-	if (hpp.t0->enable_serr)
-		pci_cmd |= PCI_COMMAND_SERR;
-	else
-		pci_cmd &= ~PCI_COMMAND_SERR;
-	if (hpp.t0->enable_perr)
-		pci_cmd |= PCI_COMMAND_PARITY;
-	else
-		pci_cmd &= ~PCI_COMMAND_PARITY;
-	pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
-
-	/* Program bridge control value and child devices */
-	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
-		pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER,
-				hpp.t0->latency_timer);
-		pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl);
-		if (hpp.t0->enable_serr)
-			pci_bctl |= PCI_BRIDGE_CTL_SERR;
-		else
-			pci_bctl &= ~PCI_BRIDGE_CTL_SERR;
-		if (hpp.t0->enable_perr)
-			pci_bctl |= PCI_BRIDGE_CTL_PARITY;
-		else
-			pci_bctl &= ~PCI_BRIDGE_CTL_PARITY;
-		pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl);
-		if (dev->subordinate) {
-			list_for_each_entry(cdev, &dev->subordinate->devices,
-					bus_list)
-				program_fw_provided_values(cdev);
-		}
-	}
-}
-
 int __ref shpchp_configure_device(struct slot *p_slot)
 {
 	struct pci_dev *dev;
@@ -153,7 +93,7 @@ int __ref shpchp_configure_device(struct slot *p_slot)
 			child->subordinate = pci_do_scan_bus(child);
 			pci_bus_size_bridges(child);
 		}
-		program_fw_provided_values(dev);
+		pci_configure_slot(dev);
 		pci_dev_put(dev);
 	}
 
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 2314ad7..562221e 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -37,6 +37,7 @@
 #include <linux/iommu.h>
 #include <linux/intel-iommu.h>
 #include <linux/sysdev.h>
+#include <linux/tboot.h>
 #include <asm/cacheflush.h>
 #include <asm/iommu.h>
 #include "pci.h"
@@ -3183,12 +3184,22 @@ static int __init init_iommu_sysfs(void)
 int __init intel_iommu_init(void)
 {
 	int ret = 0;
+	int force_on = 0;
 
-	if (dmar_table_init())
+	/* VT-d is required for a TXT/tboot launch, so enforce that */
+	force_on = tboot_force_iommu();
+
+	if (dmar_table_init()) {
+		if (force_on)
+			panic("tboot: Failed to initialize DMAR table\n");
 		return 	-ENODEV;
+	}
 
-	if (dmar_dev_scope_init())
+	if (dmar_dev_scope_init()) {
+		if (force_on)
+			panic("tboot: Failed to initialize DMAR device scope\n");
 		return 	-ENODEV;
+	}
 
 	/*
 	 * Check the need for DMA-remapping initialization now.
@@ -3204,6 +3215,8 @@ int __init intel_iommu_init(void)
 
 	ret = init_dmars();
 	if (ret) {
+		if (force_on)
+			panic("tboot: Failed to initialize DMARs\n");
 		printk(KERN_ERR "IOMMU: dmar init failed\n");
 		put_iova_domain(&reserved_iova_list);
 		iommu_exit_mempool();
diff --git a/drivers/pci/legacy.c b/drivers/pci/legacy.c
new file mode 100644
index 0000000..871f65c
--- /dev/null
+++ b/drivers/pci/legacy.c
@@ -0,0 +1,34 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include "pci.h"
+
+/**
+ * pci_find_device - begin or continue searching for a PCI device by vendor/device id
+ * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
+ * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
+ * @from: Previous PCI device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI devices.  If a PCI device is found
+ * with a matching @vendor and @device, a pointer to its device structure is
+ * returned.  Otherwise, %NULL is returned.
+ * A new search is initiated by passing %NULL as the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from next device
+ * on the global list.
+ *
+ * NOTE: Do not use this function any more; use pci_get_device() instead, as
+ * the PCI device returned by this function can disappear at any moment in
+ * time.
+ */
+struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
+				struct pci_dev *from)
+{
+	struct pci_dev *pdev;
+
+	pci_dev_get(from);
+	pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
+	pci_dev_put(pdev);
+	return pdev;
+}
+EXPORT_SYMBOL(pci_find_device);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d986afb..f9cf317 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -16,9 +16,8 @@
 #include <linux/proc_fs.h>
 #include <linux/msi.h>
 #include <linux/smp.h>
-
-#include <asm/errno.h>
-#include <asm/io.h>
+#include <linux/errno.h>
+#include <linux/io.h>
 
 #include "pci.h"
 #include "msi.h"
@@ -272,7 +271,30 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
 	write_msi_msg_desc(desc, msg);
 }
 
-static int msi_free_irqs(struct pci_dev* dev);
+static void free_msi_irqs(struct pci_dev *dev)
+{
+	struct msi_desc *entry, *tmp;
+
+	list_for_each_entry(entry, &dev->msi_list, list) {
+		int i, nvec;
+		if (!entry->irq)
+			continue;
+		nvec = 1 << entry->msi_attrib.multiple;
+		for (i = 0; i < nvec; i++)
+			BUG_ON(irq_has_action(entry->irq + i));
+	}
+
+	arch_teardown_msi_irqs(dev);
+
+	list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
+		if (entry->msi_attrib.is_msix) {
+			if (list_is_last(&entry->list, &dev->msi_list))
+				iounmap(entry->mask_base);
+		}
+		list_del(&entry->list);
+		kfree(entry);
+	}
+}
 
 static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
 {
@@ -324,7 +346,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
 	if (!dev->msix_enabled)
 		return;
 	BUG_ON(list_empty(&dev->msi_list));
-	entry = list_entry(dev->msi_list.next, struct msi_desc, list);
+	entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
 	pos = entry->msi_attrib.pos;
 	pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
 
@@ -367,7 +389,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 	u16 control;
 	unsigned mask;
 
-   	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
 	msi_set_enable(dev, pos, 0);	/* Disable MSI during set up */
 
 	pci_read_config_word(dev, msi_control_reg(pos), &control);
@@ -376,12 +398,12 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 	if (!entry)
 		return -ENOMEM;
 
-	entry->msi_attrib.is_msix = 0;
-	entry->msi_attrib.is_64 = is_64bit_address(control);
-	entry->msi_attrib.entry_nr = 0;
-	entry->msi_attrib.maskbit = is_mask_bit_support(control);
-	entry->msi_attrib.default_irq = dev->irq;	/* Save IOAPIC IRQ */
-	entry->msi_attrib.pos = pos;
+	entry->msi_attrib.is_msix	= 0;
+	entry->msi_attrib.is_64		= is_64bit_address(control);
+	entry->msi_attrib.entry_nr	= 0;
+	entry->msi_attrib.maskbit	= is_mask_bit_support(control);
+	entry->msi_attrib.default_irq	= dev->irq;	/* Save IOAPIC IRQ */
+	entry->msi_attrib.pos		= pos;
 
 	entry->mask_pos = msi_mask_reg(pos, entry->msi_attrib.is_64);
 	/* All MSIs are unmasked by default, Mask them all */
@@ -396,7 +418,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 	ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
 	if (ret) {
 		msi_mask_irq(entry, mask, ~mask);
-		msi_free_irqs(dev);
+		free_msi_irqs(dev);
 		return ret;
 	}
 
@@ -409,44 +431,27 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
 	return 0;
 }
 
-/**
- * msix_capability_init - configure device's MSI-X capability
- * @dev: pointer to the pci_dev data structure of MSI-X device function
- * @entries: pointer to an array of struct msix_entry entries
- * @nvec: number of @entries
- *
- * Setup the MSI-X capability structure of device function with a
- * single MSI-X irq. A return of zero indicates the successful setup of
- * requested MSI-X entries with allocated irqs or non-zero for otherwise.
- **/
-static int msix_capability_init(struct pci_dev *dev,
-				struct msix_entry *entries, int nvec)
+static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos,
+							unsigned nr_entries)
 {
-	struct msi_desc *entry;
-	int pos, i, j, nr_entries, ret;
 	unsigned long phys_addr;
 	u32 table_offset;
- 	u16 control;
 	u8 bir;
-	void __iomem *base;
 
-   	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-	pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
-
-	/* Ensure MSI-X is disabled while it is set up */
-	control &= ~PCI_MSIX_FLAGS_ENABLE;
-	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
-
-	/* Request & Map MSI-X table region */
-	nr_entries = multi_msix_capable(control);
-
- 	pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
+	pci_read_config_dword(dev, msix_table_offset_reg(pos), &table_offset);
 	bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
 	table_offset &= ~PCI_MSIX_FLAGS_BIRMASK;
-	phys_addr = pci_resource_start (dev, bir) + table_offset;
-	base = ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
-	if (base == NULL)
-		return -ENOMEM;
+	phys_addr = pci_resource_start(dev, bir) + table_offset;
+
+	return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
+}
+
+static int msix_setup_entries(struct pci_dev *dev, unsigned pos,
+				void __iomem *base, struct msix_entry *entries,
+				int nvec)
+{
+	struct msi_desc *entry;
+	int i;
 
 	for (i = 0; i < nvec; i++) {
 		entry = alloc_msi_entry(dev);
@@ -454,41 +459,78 @@ static int msix_capability_init(struct pci_dev *dev,
 			if (!i)
 				iounmap(base);
 			else
-				msi_free_irqs(dev);
+				free_msi_irqs(dev);
 			/* No enough memory. Don't try again */
 			return -ENOMEM;
 		}
 
- 		j = entries[i].entry;
-		entry->msi_attrib.is_msix = 1;
-		entry->msi_attrib.is_64 = 1;
-		entry->msi_attrib.entry_nr = j;
-		entry->msi_attrib.default_irq = dev->irq;
-		entry->msi_attrib.pos = pos;
-		entry->mask_base = base;
+		entry->msi_attrib.is_msix	= 1;
+		entry->msi_attrib.is_64		= 1;
+		entry->msi_attrib.entry_nr	= entries[i].entry;
+		entry->msi_attrib.default_irq	= dev->irq;
+		entry->msi_attrib.pos		= pos;
+		entry->mask_base		= base;
 
 		list_add_tail(&entry->list, &dev->msi_list);
 	}
 
-	ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
-	if (ret < 0) {
-		/* If we had some success report the number of irqs
-		 * we succeeded in setting up. */
-		int avail = 0;
-		list_for_each_entry(entry, &dev->msi_list, list) {
-			if (entry->irq != 0) {
-				avail++;
-			}
-		}
+	return 0;
+}
 
-		if (avail != 0)
-			ret = avail;
+static void msix_program_entries(struct pci_dev *dev,
+					struct msix_entry *entries)
+{
+	struct msi_desc *entry;
+	int i = 0;
+
+	list_for_each_entry(entry, &dev->msi_list, list) {
+		int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE +
+						PCI_MSIX_ENTRY_VECTOR_CTRL;
+
+		entries[i].vector = entry->irq;
+		set_irq_msi(entry->irq, entry);
+		entry->masked = readl(entry->mask_base + offset);
+		msix_mask_irq(entry, 1);
+		i++;
 	}
+}
 
-	if (ret) {
-		msi_free_irqs(dev);
+/**
+ * msix_capability_init - configure device's MSI-X capability
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ * @entries: pointer to an array of struct msix_entry entries
+ * @nvec: number of @entries
+ *
+ * Setup the MSI-X capability structure of device function with a
+ * single MSI-X irq. A return of zero indicates the successful setup of
+ * requested MSI-X entries with allocated irqs or non-zero for otherwise.
+ **/
+static int msix_capability_init(struct pci_dev *dev,
+				struct msix_entry *entries, int nvec)
+{
+	int pos, ret;
+	u16 control;
+	void __iomem *base;
+
+	pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+	pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
+
+	/* Ensure MSI-X is disabled while it is set up */
+	control &= ~PCI_MSIX_FLAGS_ENABLE;
+	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
+
+	/* Request & Map MSI-X table region */
+	base = msix_map_region(dev, pos, multi_msix_capable(control));
+	if (!base)
+		return -ENOMEM;
+
+	ret = msix_setup_entries(dev, pos, base, entries, nvec);
+	if (ret)
 		return ret;
-	}
+
+	ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
+	if (ret)
+		goto error;
 
 	/*
 	 * Some devices require MSI-X to be enabled before we can touch the
@@ -498,16 +540,7 @@ static int msix_capability_init(struct pci_dev *dev,
 	control |= PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE;
 	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 
-	i = 0;
-	list_for_each_entry(entry, &dev->msi_list, list) {
-		entries[i].vector = entry->irq;
-		set_irq_msi(entry->irq, entry);
-		j = entries[i].entry;
-		entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
-						PCI_MSIX_ENTRY_VECTOR_CTRL);
-		msix_mask_irq(entry, 1);
-		i++;
-	}
+	msix_program_entries(dev, entries);
 
 	/* Set MSI-X enabled bits and unmask the function */
 	pci_intx_for_msi(dev, 0);
@@ -517,6 +550,27 @@ static int msix_capability_init(struct pci_dev *dev,
 	pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control);
 
 	return 0;
+
+error:
+	if (ret < 0) {
+		/*
+		 * If we had some success, report the number of irqs
+		 * we succeeded in setting up.
+		 */
+		struct msi_desc *entry;
+		int avail = 0;
+
+		list_for_each_entry(entry, &dev->msi_list, list) {
+			if (entry->irq != 0)
+				avail++;
+		}
+		if (avail != 0)
+			ret = avail;
+	}
+
+	free_msi_irqs(dev);
+
+	return ret;
 }
 
 /**
@@ -529,7 +583,7 @@ static int msix_capability_init(struct pci_dev *dev,
  * to determine if MSI/-X are supported for the device. If MSI/-X is
  * supported return 0, else return an error code.
  **/
-static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type)
+static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type)
 {
 	struct pci_bus *bus;
 	int ret;
@@ -546,8 +600,9 @@ static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type)
 	if (nvec < 1)
 		return -ERANGE;
 
-	/* Any bridge which does NOT route MSI transactions from it's
-	 * secondary bus to it's primary bus must set NO_MSI flag on
+	/*
+	 * Any bridge which does NOT route MSI transactions from its
+	 * secondary bus to its primary bus must set NO_MSI flag on
 	 * the secondary pci_bus.
 	 * We expect only arch-specific PCI host bus controller driver
 	 * or quirks for specific PCI bridges to be setting NO_MSI.
@@ -638,50 +693,16 @@ void pci_msi_shutdown(struct pci_dev *dev)
 	dev->irq = desc->msi_attrib.default_irq;
 }
 
-void pci_disable_msi(struct pci_dev* dev)
+void pci_disable_msi(struct pci_dev *dev)
 {
-	struct msi_desc *entry;
-
 	if (!pci_msi_enable || !dev || !dev->msi_enabled)
 		return;
 
 	pci_msi_shutdown(dev);
-
-	entry = list_entry(dev->msi_list.next, struct msi_desc, list);
-	if (entry->msi_attrib.is_msix)
-		return;
-
-	msi_free_irqs(dev);
+	free_msi_irqs(dev);
 }
 EXPORT_SYMBOL(pci_disable_msi);
 
-static int msi_free_irqs(struct pci_dev* dev)
-{
-	struct msi_desc *entry, *tmp;
-
-	list_for_each_entry(entry, &dev->msi_list, list) {
-		int i, nvec;
-		if (!entry->irq)
-			continue;
-		nvec = 1 << entry->msi_attrib.multiple;
-		for (i = 0; i < nvec; i++)
-			BUG_ON(irq_has_action(entry->irq + i));
-	}
-
-	arch_teardown_msi_irqs(dev);
-
-	list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
-		if (entry->msi_attrib.is_msix) {
-			if (list_is_last(&entry->list, &dev->msi_list))
-				iounmap(entry->mask_base);
-		}
-		list_del(&entry->list);
-		kfree(entry);
-	}
-
-	return 0;
-}
-
 /**
  * pci_msix_table_size - return the number of device's MSI-X table entries
  * @dev: pointer to the pci_dev data structure of MSI-X device function
@@ -714,13 +735,13 @@ int pci_msix_table_size(struct pci_dev *dev)
  * of irqs or MSI-X vectors available. Driver should use the returned value to
  * re-send its request.
  **/
-int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
+int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
 {
 	int status, nr_entries;
 	int i, j;
 
 	if (!entries)
- 		return -EINVAL;
+		return -EINVAL;
 
 	status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX);
 	if (status)
@@ -742,7 +763,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 	WARN_ON(!!dev->msix_enabled);
 
 	/* Check whether driver already requested for MSI irq */
-   	if (dev->msi_enabled) {
+	if (dev->msi_enabled) {
 		dev_info(&dev->dev, "can't enable MSI-X "
 		       "(MSI IRQ already assigned)\n");
 		return -EINVAL;
@@ -752,12 +773,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 }
 EXPORT_SYMBOL(pci_enable_msix);
 
-static void msix_free_all_irqs(struct pci_dev *dev)
-{
-	msi_free_irqs(dev);
-}
-
-void pci_msix_shutdown(struct pci_dev* dev)
+void pci_msix_shutdown(struct pci_dev *dev)
 {
 	struct msi_desc *entry;
 
@@ -774,14 +790,14 @@ void pci_msix_shutdown(struct pci_dev* dev)
 	pci_intx_for_msi(dev, 1);
 	dev->msix_enabled = 0;
 }
-void pci_disable_msix(struct pci_dev* dev)
+
+void pci_disable_msix(struct pci_dev *dev)
 {
 	if (!pci_msi_enable || !dev || !dev->msix_enabled)
 		return;
 
 	pci_msix_shutdown(dev);
-
-	msix_free_all_irqs(dev);
+	free_msi_irqs(dev);
 }
 EXPORT_SYMBOL(pci_disable_msix);
 
@@ -794,16 +810,13 @@ EXPORT_SYMBOL(pci_disable_msix);
  * allocated for this device function, are reclaimed to unused state,
  * which may be used later on.
  **/
-void msi_remove_pci_irq_vectors(struct pci_dev* dev)
+void msi_remove_pci_irq_vectors(struct pci_dev *dev)
 {
 	if (!pci_msi_enable || !dev)
- 		return;
-
-	if (dev->msi_enabled)
-		msi_free_irqs(dev);
+		return;
 
-	if (dev->msix_enabled)
-		msix_free_all_irqs(dev);
+	if (dev->msi_enabled || dev->msix_enabled)
+		free_msi_irqs(dev);
 }
 
 void pci_no_msi(void)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index ea15b05..33317df 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -109,15 +109,32 @@ static bool acpi_pci_can_wakeup(struct pci_dev *dev)
 	return handle ? acpi_bus_can_wakeup(handle) : false;
 }
 
+static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
+{
+	while (bus->parent) {
+		struct pci_dev *bridge = bus->self;
+		int ret;
+
+		ret = acpi_pm_device_sleep_wake(&bridge->dev, enable);
+		if (!ret || bridge->is_pcie)
+			return;
+		bus = bus->parent;
+	}
+
+	/* We have reached the root bus. */
+	if (bus->bridge)
+		acpi_pm_device_sleep_wake(bus->bridge, enable);
+}
+
 static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable)
 {
-	int error = acpi_pm_device_sleep_wake(&dev->dev, enable);
+	if (acpi_pci_can_wakeup(dev))
+		return acpi_pm_device_sleep_wake(&dev->dev, enable);
 
-	if (!error)
-		dev_printk(KERN_INFO, &dev->dev,
-				"wake-up capability %s by ACPI\n",
-				enable ? "enabled" : "disabled");
-	return error;
+	if (!dev->is_pcie)
+		acpi_pci_propagate_wakeup_enable(dev->bus, enable);
+
+	return 0;
 }
 
 static struct pci_platform_pm_ops acpi_pci_platform_pm = {
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f99bc7f..e5d47be 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -19,37 +19,98 @@
 #include <linux/cpu.h>
 #include "pci.h"
 
-/*
- * Dynamic device IDs are disabled for !CONFIG_HOTPLUG
- */
-
 struct pci_dynid {
 	struct list_head node;
 	struct pci_device_id id;
 };
 
-#ifdef CONFIG_HOTPLUG
+/**
+ * pci_add_dynid - add a new PCI device ID to this driver and re-probe devices
+ * @drv: target pci driver
+ * @vendor: PCI vendor ID
+ * @device: PCI device ID
+ * @subvendor: PCI subvendor ID
+ * @subdevice: PCI subdevice ID
+ * @class: PCI class
+ * @class_mask: PCI class mask
+ * @driver_data: private driver data
+ *
+ * Adds a new dynamic pci device ID to this driver and causes the
+ * driver to probe for all devices again.  @drv must have been
+ * registered prior to calling this function.
+ *
+ * CONTEXT:
+ * Does GFP_KERNEL allocation.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int pci_add_dynid(struct pci_driver *drv,
+		  unsigned int vendor, unsigned int device,
+		  unsigned int subvendor, unsigned int subdevice,
+		  unsigned int class, unsigned int class_mask,
+		  unsigned long driver_data)
+{
+	struct pci_dynid *dynid;
+	int retval;
+
+	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
+	if (!dynid)
+		return -ENOMEM;
+
+	dynid->id.vendor = vendor;
+	dynid->id.device = device;
+	dynid->id.subvendor = subvendor;
+	dynid->id.subdevice = subdevice;
+	dynid->id.class = class;
+	dynid->id.class_mask = class_mask;
+	dynid->id.driver_data = driver_data;
+
+	spin_lock(&drv->dynids.lock);
+	list_add_tail(&dynid->node, &drv->dynids.list);
+	spin_unlock(&drv->dynids.lock);
+
+	get_driver(&drv->driver);
+	retval = driver_attach(&drv->driver);
+	put_driver(&drv->driver);
+
+	return retval;
+}
+
+static void pci_free_dynids(struct pci_driver *drv)
+{
+	struct pci_dynid *dynid, *n;
 
+	spin_lock(&drv->dynids.lock);
+	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
+		list_del(&dynid->node);
+		kfree(dynid);
+	}
+	spin_unlock(&drv->dynids.lock);
+}
+
+/*
+ * Dynamic device ID manipulation via sysfs is disabled for !CONFIG_HOTPLUG
+ */
+#ifdef CONFIG_HOTPLUG
 /**
- * store_new_id - add a new PCI device ID to this driver and re-probe devices
+ * store_new_id - sysfs frontend to pci_add_dynid()
  * @driver: target device driver
  * @buf: buffer for scanning device ID data
  * @count: input size
  *
- * Adds a new dynamic pci device ID to this driver,
- * and causes the driver to probe for all devices again.
+ * Allow PCI IDs to be added to an existing driver via sysfs.
  */
 static ssize_t
 store_new_id(struct device_driver *driver, const char *buf, size_t count)
 {
-	struct pci_dynid *dynid;
 	struct pci_driver *pdrv = to_pci_driver(driver);
 	const struct pci_device_id *ids = pdrv->id_table;
 	__u32 vendor, device, subvendor=PCI_ANY_ID,
 		subdevice=PCI_ANY_ID, class=0, class_mask=0;
 	unsigned long driver_data=0;
 	int fields=0;
-	int retval=0;
+	int retval;
 
 	fields = sscanf(buf, "%x %x %x %x %x %x %lx",
 			&vendor, &device, &subvendor, &subdevice,
@@ -72,27 +133,8 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
 			return retval;
 	}
 
-	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
-	if (!dynid)
-		return -ENOMEM;
-
-	dynid->id.vendor = vendor;
-	dynid->id.device = device;
-	dynid->id.subvendor = subvendor;
-	dynid->id.subdevice = subdevice;
-	dynid->id.class = class;
-	dynid->id.class_mask = class_mask;
-	dynid->id.driver_data = driver_data;
-
-	spin_lock(&pdrv->dynids.lock);
-	list_add_tail(&dynid->node, &pdrv->dynids.list);
-	spin_unlock(&pdrv->dynids.lock);
-
-	if (get_driver(&pdrv->driver)) {
-		retval = driver_attach(&pdrv->driver);
-		put_driver(&pdrv->driver);
-	}
-
+	retval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice,
+			       class, class_mask, driver_data);
 	if (retval)
 		return retval;
 	return count;
@@ -145,19 +187,6 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count)
 }
 static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
 
-static void
-pci_free_dynids(struct pci_driver *drv)
-{
-	struct pci_dynid *dynid, *n;
-
-	spin_lock(&drv->dynids.lock);
-	list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
-		list_del(&dynid->node);
-		kfree(dynid);
-	}
-	spin_unlock(&drv->dynids.lock);
-}
-
 static int
 pci_create_newid_file(struct pci_driver *drv)
 {
@@ -186,7 +215,6 @@ static void pci_remove_removeid_file(struct pci_driver *drv)
 	driver_remove_file(&drv->driver, &driver_attr_remove_id);
 }
 #else /* !CONFIG_HOTPLUG */
-static inline void pci_free_dynids(struct pci_driver *drv) {}
 static inline int pci_create_newid_file(struct pci_driver *drv)
 {
 	return 0;
@@ -417,8 +445,6 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 	struct pci_driver * drv = pci_dev->driver;
 
-	pci_dev->state_saved = false;
-
 	if (drv && drv->suspend) {
 		pci_power_t prev = pci_dev->current_state;
 		int error;
@@ -514,7 +540,6 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
 static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
 {
 	pci_restore_standard_config(pci_dev);
-	pci_dev->state_saved = false;
 	pci_fixup_device(pci_fixup_resume_early, pci_dev);
 }
 
@@ -575,13 +600,11 @@ static void pci_pm_complete(struct device *dev)
 static int pci_pm_suspend(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_SUSPEND);
 
-	pci_dev->state_saved = false;
-
 	if (!pm) {
 		pci_pm_default_suspend(pci_dev);
 		goto Fixup;
@@ -613,7 +636,7 @@ static int pci_pm_suspend(struct device *dev)
 static int pci_pm_suspend_noirq(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
@@ -672,7 +695,7 @@ static int pci_pm_resume_noirq(struct device *dev)
 static int pci_pm_resume(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int error = 0;
 
 	/*
@@ -694,7 +717,7 @@ static int pci_pm_resume(struct device *dev)
 		pci_pm_reenable_device(pci_dev);
 	}
 
-	return 0;
+	return error;
 }
 
 #else /* !CONFIG_SUSPEND */
@@ -711,13 +734,11 @@ static int pci_pm_resume(struct device *dev)
 static int pci_pm_freeze(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_FREEZE);
 
-	pci_dev->state_saved = false;
-
 	if (!pm) {
 		pci_pm_default_suspend(pci_dev);
 		return 0;
@@ -780,7 +801,7 @@ static int pci_pm_thaw_noirq(struct device *dev)
 static int pci_pm_thaw(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int error = 0;
 
 	if (pci_has_legacy_pm_support(pci_dev))
@@ -793,19 +814,19 @@ static int pci_pm_thaw(struct device *dev)
 		pci_pm_reenable_device(pci_dev);
 	}
 
+	pci_dev->state_saved = false;
+
 	return error;
 }
 
 static int pci_pm_poweroff(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 
 	if (pci_has_legacy_pm_support(pci_dev))
 		return pci_legacy_suspend(dev, PMSG_HIBERNATE);
 
-	pci_dev->state_saved = false;
-
 	if (!pm) {
 		pci_pm_default_suspend(pci_dev);
 		goto Fixup;
@@ -872,7 +893,7 @@ static int pci_pm_restore_noirq(struct device *dev)
 static int pci_pm_restore(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int error = 0;
 
 	/*
@@ -910,7 +931,7 @@ static int pci_pm_restore(struct device *dev)
 
 #endif /* !CONFIG_HIBERNATION */
 
-struct dev_pm_ops pci_dev_pm_ops = {
+const struct dev_pm_ops pci_dev_pm_ops = {
 	.prepare = pci_pm_prepare,
 	.complete = pci_pm_complete,
 	.suspend = pci_pm_suspend,
@@ -1106,6 +1127,7 @@ static int __init pci_driver_init(void)
 
 postcore_initcall(pci_driver_init);
 
+EXPORT_SYMBOL_GPL(pci_add_dynid);
 EXPORT_SYMBOL(pci_match_id);
 EXPORT_SYMBOL(__pci_register_driver);
 EXPORT_SYMBOL(pci_unregister_driver);
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index 74fbec0..f7b68ca 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -19,8 +19,16 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 
+static char ids[1024] __initdata;
+
+module_param_string(ids, ids, sizeof(ids), 0);
+MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the stub driver, format is "
+		 "\"vendor:device[:subvendor[:subdevice[:class[:class_mask]]]]\""
+		 " and multiple comma separated entries can be specified");
+
 static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
+	dev_printk(KERN_INFO, &dev->dev, "claimed by stub\n");
 	return 0;
 }
 
@@ -32,7 +40,42 @@ static struct pci_driver stub_driver = {
 
 static int __init pci_stub_init(void)
 {
-	return pci_register_driver(&stub_driver);
+	char *p, *id;
+	int rc;
+
+	rc = pci_register_driver(&stub_driver);
+	if (rc)
+		return rc;
+
+	/* add ids specified in the module parameter */
+	p = ids;
+	while ((id = strsep(&p, ","))) {
+		unsigned int vendor, device, subvendor = PCI_ANY_ID,
+			subdevice = PCI_ANY_ID, class=0, class_mask=0;
+		int fields;
+
+		fields = sscanf(id, "%x:%x:%x:%x:%x:%x",
+				&vendor, &device, &subvendor, &subdevice,
+				&class, &class_mask);
+
+		if (fields < 2) {
+			printk(KERN_WARNING
+			       "pci-stub: invalid id string \"%s\"\n", id);
+			continue;
+		}
+
+		printk(KERN_INFO
+		       "pci-stub: add %04X:%04X sub=%04X:%04X cls=%08X/%08X\n",
+		       vendor, device, subvendor, subdevice, class, class_mask);
+
+		rc = pci_add_dynid(&stub_driver, vendor, device,
+				   subvendor, subdevice, class, class_mask, 0);
+		if (rc)
+			printk(KERN_WARNING
+			       "pci-stub: failed to add dynamic id (%d)\n", rc);
+	}
+
+	return 0;
 }
 
 static void __exit pci_stub_exit(void)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 85ebd02..0f6382f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -916,6 +916,24 @@ int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev)
 	return 0;
 }
 
+static ssize_t reset_store(struct device *dev,
+			   struct device_attribute *attr, const char *buf,
+			   size_t count)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	unsigned long val;
+	ssize_t result = strict_strtoul(buf, 0, &val);
+
+	if (result < 0)
+		return result;
+
+	if (val != 1)
+		return -EINVAL;
+	return pci_reset_function(pdev);
+}
+
+static struct device_attribute reset_attr = __ATTR(reset, 0200, NULL, reset_store);
+
 static int pci_create_capabilities_sysfs(struct pci_dev *dev)
 {
 	int retval;
@@ -943,7 +961,22 @@ static int pci_create_capabilities_sysfs(struct pci_dev *dev)
 	/* Active State Power Management */
 	pcie_aspm_create_sysfs_dev_files(dev);
 
+	if (!pci_probe_reset_function(dev)) {
+		retval = device_create_file(&dev->dev, &reset_attr);
+		if (retval)
+			goto error;
+		dev->reset_fn = 1;
+	}
 	return 0;
+
+error:
+	pcie_aspm_remove_sysfs_dev_files(dev);
+	if (dev->vpd && dev->vpd->attr) {
+		sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
+		kfree(dev->vpd->attr);
+	}
+
+	return retval;
 }
 
 int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
@@ -1037,6 +1070,10 @@ static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
 	}
 
 	pcie_aspm_remove_sysfs_dev_files(dev);
+	if (dev->reset_fn) {
+		device_remove_file(&dev->dev, &reset_attr);
+		dev->reset_fn = 0;
+	}
 }
 
 /**
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 7b70312..6edecff 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -41,6 +41,12 @@ int pci_domains_supported = 1;
 unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
 unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
 
+#define DEFAULT_HOTPLUG_IO_SIZE		(256)
+#define DEFAULT_HOTPLUG_MEM_SIZE	(2*1024*1024)
+/* pci=hpmemsize=nnM,hpiosize=nn can override this */
+unsigned long pci_hotplug_io_size  = DEFAULT_HOTPLUG_IO_SIZE;
+unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
+
 /**
  * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
  * @bus: pointer to PCI bus structure to search
@@ -848,6 +854,7 @@ pci_restore_state(struct pci_dev *dev)
 
 	if (!dev->state_saved)
 		return 0;
+
 	/* PCI Express register must be restored first */
 	pci_restore_pcie_state(dev);
 
@@ -869,6 +876,8 @@ pci_restore_state(struct pci_dev *dev)
 	pci_restore_msi_state(dev);
 	pci_restore_iov_state(dev);
 
+	dev->state_saved = false;
+
 	return 0;
 }
 
@@ -1214,30 +1223,40 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
  */
 int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable)
 {
-	int error = 0;
-	bool pme_done = false;
+	int ret = 0;
 
 	if (enable && !device_may_wakeup(&dev->dev))
 		return -EINVAL;
 
+	/* Don't do the same thing twice in a row for one device. */
+	if (!!enable == !!dev->wakeup_prepared)
+		return 0;
+
 	/*
 	 * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don
 	 * Anderson we should be doing PME# wake enable followed by ACPI wake
 	 * enable.  To disable wake-up we call the platform first, for symmetry.
 	 */
 
-	if (!enable && platform_pci_can_wakeup(dev))
-		error = platform_pci_sleep_wake(dev, false);
-
-	if (!enable || pci_pme_capable(dev, state)) {
-		pci_pme_active(dev, enable);
-		pme_done = true;
-	}
+	if (enable) {
+		int error;
 
-	if (enable && platform_pci_can_wakeup(dev))
+		if (pci_pme_capable(dev, state))
+			pci_pme_active(dev, true);
+		else
+			ret = 1;
 		error = platform_pci_sleep_wake(dev, true);
+		if (ret)
+			ret = error;
+		if (!ret)
+			dev->wakeup_prepared = true;
+	} else {
+		platform_pci_sleep_wake(dev, false);
+		pci_pme_active(dev, false);
+		dev->wakeup_prepared = false;
+	}
 
-	return pme_done ? 0 : error;
+	return ret;
 }
 
 /**
@@ -1356,6 +1375,7 @@ void pci_pm_init(struct pci_dev *dev)
 	int pm;
 	u16 pmc;
 
+	dev->wakeup_prepared = false;
 	dev->pm_cap = 0;
 
 	/* find PCI PM capability in list */
@@ -2262,6 +2282,22 @@ int __pci_reset_function(struct pci_dev *dev)
 EXPORT_SYMBOL_GPL(__pci_reset_function);
 
 /**
+ * pci_probe_reset_function - check whether the device can be safely reset
+ * @dev: PCI device to reset
+ *
+ * Some devices allow an individual function to be reset without affecting
+ * other functions in the same device.  The PCI device must be responsive
+ * to PCI config space in order to use this function.
+ *
+ * Returns 0 if the device function can be reset or negative if the
+ * device doesn't support resetting a single function.
+ */
+int pci_probe_reset_function(struct pci_dev *dev)
+{
+	return pci_dev_reset(dev, 1);
+}
+
+/**
  * pci_reset_function - quiesce and reset a PCI device function
  * @dev: PCI device to reset
  *
@@ -2504,6 +2540,50 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
 	return 0;
 }
 
+/**
+ * pci_set_vga_state - set VGA decode state on device and parents if requested
+ * @dev the PCI device
+ * @decode - true = enable decoding, false = disable decoding
+ * @command_bits PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY
+ * @change_bridge - traverse ancestors and change bridges
+ */
+int pci_set_vga_state(struct pci_dev *dev, bool decode,
+		      unsigned int command_bits, bool change_bridge)
+{
+	struct pci_bus *bus;
+	struct pci_dev *bridge;
+	u16 cmd;
+
+	WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	if (decode == true)
+		cmd |= command_bits;
+	else
+		cmd &= ~command_bits;
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+	if (change_bridge == false)
+		return 0;
+
+	bus = dev->bus;
+	while (bus) {
+		bridge = bus->self;
+		if (bridge) {
+			pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+					     &cmd);
+			if (decode == true)
+				cmd |= PCI_BRIDGE_CTL_VGA;
+			else
+				cmd &= ~PCI_BRIDGE_CTL_VGA;
+			pci_write_config_word(bridge, PCI_BRIDGE_CONTROL,
+					      cmd);
+		}
+		bus = bus->parent;
+	}
+	return 0;
+}
+
 #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
 static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
 spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED;
@@ -2672,6 +2752,10 @@ static int __init pci_setup(char *str)
 							strlen(str + 19));
 			} else if (!strncmp(str, "ecrc=", 5)) {
 				pcie_ecrc_get_policy(str + 5);
+			} else if (!strncmp(str, "hpiosize=", 9)) {
+				pci_hotplug_io_size = memparse(str + 9, &str);
+			} else if (!strncmp(str, "hpmemsize=", 10)) {
+				pci_hotplug_mem_size = memparse(str + 10, &str);
 			} else {
 				printk(KERN_ERR "PCI: Unknown option `%s'\n",
 						str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 5ff4d25..d92d195 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -16,6 +16,7 @@ extern void pci_cleanup_rom(struct pci_dev *dev);
 extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
 			 struct vm_area_struct *vma);
 #endif
+int pci_probe_reset_function(struct pci_dev *dev);
 
 /**
  * struct pci_platform_pm_ops - Firmware PM callbacks
@@ -133,7 +134,6 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
 	return (dev->no_d1d2 || parent_dstates);
 
 }
-extern int pcie_mch_quirk;
 extern struct device_attribute pci_dev_attrs[];
 extern struct device_attribute dev_attr_cpuaffinity;
 extern struct device_attribute dev_attr_cpulistaffinity;
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index d92ae21..62d15f6 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -22,11 +22,10 @@
 #include <linux/miscdevice.h>
 #include <linux/pci.h>
 #include <linux/fs.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include "aerdrv.h"
 
-struct aer_error_inj
-{
+struct aer_error_inj {
 	u8 bus;
 	u8 dev;
 	u8 fn;
@@ -38,8 +37,7 @@ struct aer_error_inj
 	u32 header_log3;
 };
 
-struct aer_error
-{
+struct aer_error {
 	struct list_head list;
 	unsigned int bus;
 	unsigned int devfn;
@@ -55,8 +53,7 @@ struct aer_error
 	u32 source_id;
 };
 
-struct pci_bus_ops
-{
+struct pci_bus_ops {
 	struct list_head list;
 	struct pci_bus *bus;
 	struct pci_ops *ops;
@@ -150,7 +147,7 @@ static u32 *find_pci_config_dword(struct aer_error *err, int where,
 		target = &err->header_log1;
 		break;
 	case PCI_ERR_HEADER_LOG+8:
-	        target = &err->header_log2;
+		target = &err->header_log2;
 		break;
 	case PCI_ERR_HEADER_LOG+12:
 		target = &err->header_log3;
@@ -258,8 +255,7 @@ static int pci_bus_set_aer_ops(struct pci_bus *bus)
 	bus_ops = NULL;
 out:
 	spin_unlock_irqrestore(&inject_lock, flags);
-	if (bus_ops)
-		kfree(bus_ops);
+	kfree(bus_ops);
 	return 0;
 }
 
@@ -401,10 +397,8 @@ static int aer_inject(struct aer_error_inj *einj)
 	else
 		ret = -EINVAL;
 out_put:
-	if (err_alloc)
-		kfree(err_alloc);
-	if (rperr_alloc)
-		kfree(rperr_alloc);
+	kfree(err_alloc);
+	kfree(rperr_alloc);
 	pci_dev_put(dev);
 	return ret;
 }
@@ -458,8 +452,7 @@ static void __exit aer_inject_exit(void)
 	}
 
 	spin_lock_irqsave(&inject_lock, flags);
-	list_for_each_entry_safe(err, err_next,
-				 &pci_bus_ops_list, list) {
+	list_for_each_entry_safe(err, err_next, &pci_bus_ops_list, list) {
 		list_del(&err->list);
 		kfree(err);
 	}
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 4770f13..10c0e62 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -38,7 +38,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
-static int __devinit aer_probe (struct pcie_device *dev);
+static int __devinit aer_probe(struct pcie_device *dev);
 static void aer_remove(struct pcie_device *dev);
 static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
 	enum pci_channel_state error);
@@ -47,7 +47,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
 
 static struct pci_error_handlers aer_error_handlers = {
 	.error_detected = aer_error_detected,
-	.resume = aer_error_resume,
+	.resume		= aer_error_resume,
 };
 
 static struct pcie_port_service_driver aerdriver = {
@@ -134,12 +134,12 @@ EXPORT_SYMBOL_GPL(aer_irq);
  *
  * Invoked when Root Port's AER service is loaded.
  **/
-static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev)
+static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
 {
 	struct aer_rpc *rpc;
 
-	if (!(rpc = kzalloc(sizeof(struct aer_rpc),
-		GFP_KERNEL)))
+	rpc = kzalloc(sizeof(struct aer_rpc), GFP_KERNEL);
+	if (!rpc)
 		return NULL;
 
 	/*
@@ -189,26 +189,28 @@ static void aer_remove(struct pcie_device *dev)
  *
  * Invoked when PCI Express bus loads AER service driver.
  **/
-static int __devinit aer_probe (struct pcie_device *dev)
+static int __devinit aer_probe(struct pcie_device *dev)
 {
 	int status;
 	struct aer_rpc *rpc;
 	struct device *device = &dev->device;
 
 	/* Init */
-	if ((status = aer_init(dev)))
+	status = aer_init(dev);
+	if (status)
 		return status;
 
 	/* Alloc rpc data structure */
-	if (!(rpc = aer_alloc_rpc(dev))) {
+	rpc = aer_alloc_rpc(dev);
+	if (!rpc) {
 		dev_printk(KERN_DEBUG, device, "alloc rpc failed\n");
 		aer_remove(dev);
 		return -ENOMEM;
 	}
 
 	/* Request IRQ ISR */
-	if ((status = request_irq(dev->irq, aer_irq, IRQF_SHARED, "aerdrv",
-				dev))) {
+	status = request_irq(dev->irq, aer_irq, IRQF_SHARED, "aerdrv", dev);
+	if (status) {
 		dev_printk(KERN_DEBUG, device, "request IRQ failed\n");
 		aer_remove(dev);
 		return status;
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index bbd7428..bd833ea 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -16,12 +16,9 @@
 #define AER_NONFATAL			0
 #define AER_FATAL			1
 #define AER_CORRECTABLE			2
-#define AER_UNCORRECTABLE		4
-#define AER_ERROR_MASK			0x001fffff
-#define AER_ERROR(d)			(d & AER_ERROR_MASK)
 
 /* Root Error Status Register Bits */
-#define ROOT_ERR_STATUS_MASKS			0x0f
+#define ROOT_ERR_STATUS_MASKS		0x0f
 
 #define SYSTEM_ERROR_INTR_ON_MESG_MASK	(PCI_EXP_RTCTL_SECEE|	\
 					PCI_EXP_RTCTL_SENFEE|	\
@@ -32,8 +29,6 @@
 #define ERR_COR_ID(d)			(d & 0xffff)
 #define ERR_UNCOR_ID(d)			(d >> 16)
 
-#define AER_SUCCESS			0
-#define AER_UNSUCCESS			1
 #define AER_ERROR_SOURCES_MAX		100
 
 #define AER_LOG_TLP_MASKS		(PCI_ERR_UNC_POISON_TLP|	\
@@ -43,13 +38,6 @@
 					PCI_ERR_UNC_UNX_COMP|		\
 					PCI_ERR_UNC_MALF_TLP)
 
-/* AER Error Info Flags */
-#define AER_TLP_HEADER_VALID_FLAG	0x00000001
-#define AER_MULTI_ERROR_VALID_FLAG	0x00000002
-
-#define ERR_CORRECTABLE_ERROR_MASK	0x000031c1
-#define ERR_UNCORRECTABLE_ERROR_MASK	0x001ff010
-
 struct header_log_regs {
 	unsigned int dw0;
 	unsigned int dw1;
@@ -61,11 +49,20 @@ struct header_log_regs {
 struct aer_err_info {
 	struct pci_dev *dev[AER_MAX_MULTI_ERR_DEVICES];
 	int error_dev_num;
-	u16 id;
-	int severity;			/* 0:NONFATAL | 1:FATAL | 2:COR */
-	int flags;
+
+	unsigned int id:16;
+
+	unsigned int severity:2;	/* 0:NONFATAL | 1:FATAL | 2:COR */
+	unsigned int __pad1:5;
+	unsigned int multi_error_valid:1;
+
+	unsigned int first_error:5;
+	unsigned int __pad2:2;
+	unsigned int tlp_header_valid:1;
+
 	unsigned int status;		/* COR/UNCOR Error Status */
-	struct header_log_regs tlp; 	/* TLP Header */
+	unsigned int mask;		/* COR/UNCOR Error Mask */
+	struct header_log_regs tlp;	/* TLP Header */
 };
 
 struct aer_err_source {
@@ -125,6 +122,7 @@ extern void aer_delete_rootport(struct aer_rpc *rpc);
 extern int aer_init(struct pcie_device *dev);
 extern void aer_isr(struct work_struct *work);
 extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
+extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info);
 extern irqreturn_t aer_irq(int irq, void *context);
 
 #ifdef CONFIG_ACPI
@@ -136,4 +134,4 @@ static inline int aer_osc_setup(struct pcie_device *pciedev)
 }
 #endif
 
-#endif //_AERDRV_H_
+#endif /* _AERDRV_H_ */
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 3d88727..9f5ccbe 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -49,10 +49,11 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev)
 		PCI_EXP_DEVCTL_NFERE |
 		PCI_EXP_DEVCTL_FERE |
 		PCI_EXP_DEVCTL_URRE;
-	pci_write_config_word(dev, pos+PCI_EXP_DEVCTL,
-			reg16);
+	pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, reg16);
+
 	return 0;
 }
+EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
 
 int pci_disable_pcie_error_reporting(struct pci_dev *dev)
 {
@@ -68,10 +69,11 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev)
 			PCI_EXP_DEVCTL_NFERE |
 			PCI_EXP_DEVCTL_FERE |
 			PCI_EXP_DEVCTL_URRE);
-	pci_write_config_word(dev, pos+PCI_EXP_DEVCTL,
-			reg16);
+	pci_write_config_word(dev, pos+PCI_EXP_DEVCTL, reg16);
+
 	return 0;
 }
+EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
 
 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 {
@@ -92,6 +94,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
 
 #if 0
 int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
@@ -110,7 +113,6 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
 }
 #endif  /*  0  */
 
-
 static int set_device_error_reporting(struct pci_dev *dev, void *data)
 {
 	bool enable = *((bool *)data);
@@ -164,8 +166,9 @@ static int add_error_device(struct aer_err_info *e_info, struct pci_dev *dev)
 		e_info->dev[e_info->error_dev_num] = dev;
 		e_info->error_dev_num++;
 		return 1;
-	} else
-		return 0;
+	}
+
+	return 0;
 }
 
 
@@ -193,7 +196,7 @@ static int find_device_iter(struct pci_dev *dev, void *data)
 		 * If there is no multiple error, we stop
 		 * or continue based on the id comparing.
 		 */
-		if (!(e_info->flags & AER_MULTI_ERROR_VALID_FLAG))
+		if (!e_info->multi_error_valid)
 			return result;
 
 		/*
@@ -233,24 +236,16 @@ static int find_device_iter(struct pci_dev *dev, void *data)
 	status = 0;
 	mask = 0;
 	if (e_info->severity == AER_CORRECTABLE) {
-		pci_read_config_dword(dev,
-				pos + PCI_ERR_COR_STATUS,
-				&status);
-		pci_read_config_dword(dev,
-				pos + PCI_ERR_COR_MASK,
-				&mask);
-		if (status & ERR_CORRECTABLE_ERROR_MASK & ~mask) {
+		pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status);
+		pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &mask);
+		if (status & ~mask) {
 			add_error_device(e_info, dev);
 			goto added;
 		}
 	} else {
-		pci_read_config_dword(dev,
-				pos + PCI_ERR_UNCOR_STATUS,
-				&status);
-		pci_read_config_dword(dev,
-				pos + PCI_ERR_UNCOR_MASK,
-				&mask);
-		if (status & ERR_UNCORRECTABLE_ERROR_MASK & ~mask) {
+		pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
+		pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, &mask);
+		if (status & ~mask) {
 			add_error_device(e_info, dev);
 			goto added;
 		}
@@ -259,7 +254,7 @@ static int find_device_iter(struct pci_dev *dev, void *data)
 	return 0;
 
 added:
-	if (e_info->flags & AER_MULTI_ERROR_VALID_FLAG)
+	if (e_info->multi_error_valid)
 		return 0;
 	else
 		return 1;
@@ -411,8 +406,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
 			pci_cleanup_aer_uncorrect_error_status(dev);
 			dev->error_state = pci_channel_io_normal;
 		}
-	}
-	else {
+	} else {
 		/*
 		 * If the error is reported by an end point, we think this
 		 * error is related to the upstream link of the end point.
@@ -473,7 +467,7 @@ static pci_ers_result_t reset_link(struct pcie_device *aerdev,
 	if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)
 		udev = dev;
 	else
-		udev= dev->bus->self;
+		udev = dev->bus->self;
 
 	data.is_downstream = 0;
 	data.aer_driver = NULL;
@@ -576,7 +570,7 @@ static pci_ers_result_t do_recovery(struct pcie_device *aerdev,
  *
  * Invoked when an error being detected by Root Port.
  */
-static void handle_error_source(struct pcie_device * aerdev,
+static void handle_error_source(struct pcie_device *aerdev,
 	struct pci_dev *dev,
 	struct aer_err_info *info)
 {
@@ -682,7 +676,7 @@ static void disable_root_aer(struct aer_rpc *rpc)
  *
  * Invoked by DPC handler to consume an error.
  */
-static struct aer_err_source* get_e_source(struct aer_rpc *rpc)
+static struct aer_err_source *get_e_source(struct aer_rpc *rpc)
 {
 	struct aer_err_source *e_source;
 	unsigned long flags;
@@ -702,32 +696,50 @@ static struct aer_err_source* get_e_source(struct aer_rpc *rpc)
 	return e_source;
 }
 
+/**
+ * get_device_error_info - read error status from dev and store it to info
+ * @dev: pointer to the device expected to have a error record
+ * @info: pointer to structure to store the error record
+ *
+ * Return 1 on success, 0 on error.
+ */
 static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 {
-	int pos;
+	int pos, temp;
+
+	info->status = 0;
+	info->tlp_header_valid = 0;
 
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
 
 	/* The device might not support AER */
 	if (!pos)
-		return AER_SUCCESS;
+		return 1;
 
 	if (info->severity == AER_CORRECTABLE) {
 		pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS,
 			&info->status);
-		if (!(info->status & ERR_CORRECTABLE_ERROR_MASK))
-			return AER_UNSUCCESS;
+		pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK,
+			&info->mask);
+		if (!(info->status & ~info->mask))
+			return 0;
 	} else if (dev->hdr_type & PCI_HEADER_TYPE_BRIDGE ||
 		info->severity == AER_NONFATAL) {
 
 		/* Link is still healthy for IO reads */
 		pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS,
 			&info->status);
-		if (!(info->status & ERR_UNCORRECTABLE_ERROR_MASK))
-			return AER_UNSUCCESS;
+		pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_MASK,
+			&info->mask);
+		if (!(info->status & ~info->mask))
+			return 0;
+
+		/* Get First Error Pointer */
+		pci_read_config_dword(dev, pos + PCI_ERR_CAP, &temp);
+		info->first_error = PCI_ERR_CAP_FEP(temp);
 
 		if (info->status & AER_LOG_TLP_MASKS) {
-			info->flags |= AER_TLP_HEADER_VALID_FLAG;
+			info->tlp_header_valid = 1;
 			pci_read_config_dword(dev,
 				pos + PCI_ERR_HEADER_LOG, &info->tlp.dw0);
 			pci_read_config_dword(dev,
@@ -739,7 +751,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
 		}
 	}
 
-	return AER_SUCCESS;
+	return 1;
 }
 
 static inline void aer_process_err_devices(struct pcie_device *p_device,
@@ -753,14 +765,14 @@ static inline void aer_process_err_devices(struct pcie_device *p_device,
 				e_info->id);
 	}
 
+	/* Report all before handle them, not to lost records by reset etc. */
 	for (i = 0; i < e_info->error_dev_num && e_info->dev[i]; i++) {
-		if (get_device_error_info(e_info->dev[i], e_info) ==
-				AER_SUCCESS) {
+		if (get_device_error_info(e_info->dev[i], e_info))
 			aer_print_error(e_info->dev[i], e_info);
-			handle_error_source(p_device,
-					e_info->dev[i],
-					e_info);
-		}
+	}
+	for (i = 0; i < e_info->error_dev_num && e_info->dev[i]; i++) {
+		if (get_device_error_info(e_info->dev[i], e_info))
+			handle_error_source(p_device, e_info->dev[i], e_info);
 	}
 }
 
@@ -806,7 +818,9 @@ static void aer_isr_one_error(struct pcie_device *p_device,
 		if (e_src->status &
 			(PCI_ERR_ROOT_MULTI_COR_RCV |
 			 PCI_ERR_ROOT_MULTI_UNCOR_RCV))
-			e_info->flags |= AER_MULTI_ERROR_VALID_FLAG;
+			e_info->multi_error_valid = 1;
+
+		aer_print_port_info(p_device->port, e_info);
 
 		find_source_device(p_device->port, e_info);
 		aer_process_err_devices(p_device, e_info);
@@ -863,10 +877,5 @@ int aer_init(struct pcie_device *dev)
 	if (aer_osc_setup(dev) && !forceload)
 		return -ENXIO;
 
-	return AER_SUCCESS;
+	return 0;
 }
-
-EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
-EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
-EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
-
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 0fc29ae..44acde7 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -27,69 +27,70 @@
 #define AER_AGENT_COMPLETER		2
 #define AER_AGENT_TRANSMITTER		3
 
-#define AER_AGENT_REQUESTER_MASK	(PCI_ERR_UNC_COMP_TIME|	\
-					PCI_ERR_UNC_UNSUP)
-
-#define AER_AGENT_COMPLETER_MASK	PCI_ERR_UNC_COMP_ABORT
-
-#define AER_AGENT_TRANSMITTER_MASK(t, e) (e & (PCI_ERR_COR_REP_ROLL| \
-	((t == AER_CORRECTABLE) ? PCI_ERR_COR_REP_TIMER: 0)))
+#define AER_AGENT_REQUESTER_MASK(t)	((t == AER_CORRECTABLE) ?	\
+	0 : (PCI_ERR_UNC_COMP_TIME|PCI_ERR_UNC_UNSUP))
+#define AER_AGENT_COMPLETER_MASK(t)	((t == AER_CORRECTABLE) ?	\
+	0 : PCI_ERR_UNC_COMP_ABORT)
+#define AER_AGENT_TRANSMITTER_MASK(t)	((t == AER_CORRECTABLE) ?	\
+	(PCI_ERR_COR_REP_ROLL|PCI_ERR_COR_REP_TIMER) : 0)
 
 #define AER_GET_AGENT(t, e)						\
-	((e & AER_AGENT_COMPLETER_MASK) ? AER_AGENT_COMPLETER :		\
-	(e & AER_AGENT_REQUESTER_MASK) ? AER_AGENT_REQUESTER :		\
-	(AER_AGENT_TRANSMITTER_MASK(t, e)) ? AER_AGENT_TRANSMITTER :	\
+	((e & AER_AGENT_COMPLETER_MASK(t)) ? AER_AGENT_COMPLETER :	\
+	(e & AER_AGENT_REQUESTER_MASK(t)) ? AER_AGENT_REQUESTER :	\
+	(e & AER_AGENT_TRANSMITTER_MASK(t)) ? AER_AGENT_TRANSMITTER :	\
 	AER_AGENT_RECEIVER)
 
-#define AER_PHYSICAL_LAYER_ERROR_MASK	PCI_ERR_COR_RCVR
-#define AER_DATA_LINK_LAYER_ERROR_MASK(t, e)	\
-		(PCI_ERR_UNC_DLP|		\
-		PCI_ERR_COR_BAD_TLP| 		\
-		PCI_ERR_COR_BAD_DLLP|		\
-		PCI_ERR_COR_REP_ROLL| 		\
-		((t == AER_CORRECTABLE) ?	\
-		PCI_ERR_COR_REP_TIMER: 0))
-
 #define AER_PHYSICAL_LAYER_ERROR	0
 #define AER_DATA_LINK_LAYER_ERROR	1
 #define AER_TRANSACTION_LAYER_ERROR	2
 
-#define AER_GET_LAYER_ERROR(t, e)				\
-	((e & AER_PHYSICAL_LAYER_ERROR_MASK) ?			\
-	AER_PHYSICAL_LAYER_ERROR :				\
-	(e & AER_DATA_LINK_LAYER_ERROR_MASK(t, e)) ?		\
-		AER_DATA_LINK_LAYER_ERROR : 			\
-		AER_TRANSACTION_LAYER_ERROR)
+#define AER_PHYSICAL_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ?	\
+	PCI_ERR_COR_RCVR : 0)
+#define AER_DATA_LINK_LAYER_ERROR_MASK(t) ((t == AER_CORRECTABLE) ?	\
+	(PCI_ERR_COR_BAD_TLP|						\
+	PCI_ERR_COR_BAD_DLLP|						\
+	PCI_ERR_COR_REP_ROLL|						\
+	PCI_ERR_COR_REP_TIMER) : PCI_ERR_UNC_DLP)
+
+#define AER_GET_LAYER_ERROR(t, e)					\
+	((e & AER_PHYSICAL_LAYER_ERROR_MASK(t)) ? AER_PHYSICAL_LAYER_ERROR : \
+	(e & AER_DATA_LINK_LAYER_ERROR_MASK(t)) ? AER_DATA_LINK_LAYER_ERROR : \
+	AER_TRANSACTION_LAYER_ERROR)
+
+#define AER_PR(info, pdev, fmt, args...)				\
+	printk("%s%s %s: " fmt, (info->severity == AER_CORRECTABLE) ?	\
+		KERN_WARNING : KERN_ERR, dev_driver_string(&pdev->dev),	\
+		dev_name(&pdev->dev), ## args)
 
 /*
  * AER error strings
  */
-static char* aer_error_severity_string[] = {
+static char *aer_error_severity_string[] = {
 	"Uncorrected (Non-Fatal)",
 	"Uncorrected (Fatal)",
 	"Corrected"
 };
 
-static char* aer_error_layer[] = {
+static char *aer_error_layer[] = {
 	"Physical Layer",
 	"Data Link Layer",
 	"Transaction Layer"
 };
-static char* aer_correctable_error_string[] = {
-	"Receiver Error        ",	/* Bit Position 0 	*/
+static char *aer_correctable_error_string[] = {
+	"Receiver Error        ",	/* Bit Position 0	*/
 	NULL,
 	NULL,
 	NULL,
 	NULL,
 	NULL,
-	"Bad TLP               ",	/* Bit Position 6 	*/
-	"Bad DLLP              ",	/* Bit Position 7 	*/
-	"RELAY_NUM Rollover    ",	/* Bit Position 8 	*/
+	"Bad TLP               ",	/* Bit Position 6	*/
+	"Bad DLLP              ",	/* Bit Position 7	*/
+	"RELAY_NUM Rollover    ",	/* Bit Position 8	*/
 	NULL,
 	NULL,
 	NULL,
-	"Replay Timer Timeout  ",	/* Bit Position 12 	*/
-	"Advisory Non-Fatal    ", 	/* Bit Position 13	*/
+	"Replay Timer Timeout  ",	/* Bit Position 12	*/
+	"Advisory Non-Fatal    ",	/* Bit Position 13	*/
 	NULL,
 	NULL,
 	NULL,
@@ -110,7 +111,7 @@ static char* aer_correctable_error_string[] = {
 	NULL,
 };
 
-static char* aer_uncorrectable_error_string[] = {
+static char *aer_uncorrectable_error_string[] = {
 	NULL,
 	NULL,
 	NULL,
@@ -123,10 +124,10 @@ static char* aer_uncorrectable_error_string[] = {
 	NULL,
 	NULL,
 	NULL,
-	"Poisoned TLP          ",	/* Bit Position 12 	*/
+	"Poisoned TLP          ",	/* Bit Position 12	*/
 	"Flow Control Protocol ",	/* Bit Position 13	*/
-	"Completion Timeout    ",	/* Bit Position 14 	*/
-	"Completer Abort       ",	/* Bit Position 15 	*/
+	"Completion Timeout    ",	/* Bit Position 14	*/
+	"Completer Abort       ",	/* Bit Position 15	*/
 	"Unexpected Completion ",	/* Bit Position 16	*/
 	"Receiver Overflow     ",	/* Bit Position 17	*/
 	"Malformed TLP         ",	/* Bit Position 18	*/
@@ -145,98 +146,69 @@ static char* aer_uncorrectable_error_string[] = {
 	NULL,
 };
 
-static char* aer_agent_string[] = {
+static char *aer_agent_string[] = {
 	"Receiver ID",
 	"Requester ID",
 	"Completer ID",
 	"Transmitter ID"
 };
 
-static char * aer_get_error_source_name(int severity,
-			unsigned int status,
-			char errmsg_buff[])
+static void __aer_print_error(struct aer_err_info *info, struct pci_dev *dev)
 {
-	int i;
-	char * errmsg = NULL;
+	int i, status;
+	char *errmsg = NULL;
+
+	status = (info->status & ~info->mask);
 
 	for (i = 0; i < 32; i++) {
 		if (!(status & (1 << i)))
 			continue;
 
-		if (severity == AER_CORRECTABLE)
+		if (info->severity == AER_CORRECTABLE)
 			errmsg = aer_correctable_error_string[i];
 		else
 			errmsg = aer_uncorrectable_error_string[i];
 
-		if (!errmsg) {
-			sprintf(errmsg_buff, "Unknown Error Bit %2d  ", i);
-			errmsg = errmsg_buff;
-		}
-
-		break;
+		if (errmsg)
+			AER_PR(info, dev, "   [%2d] %s%s\n", i, errmsg,
+				info->first_error == i ? " (First)" : "");
+		else
+			AER_PR(info, dev, "   [%2d] Unknown Error Bit%s\n", i,
+				info->first_error == i ? " (First)" : "");
 	}
-
-	return errmsg;
 }
 
-static DEFINE_SPINLOCK(logbuf_lock);
-static char errmsg_buff[100];
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 {
-	char * errmsg;
-	int err_layer, agent;
-	char * loglevel;
-
-	if (info->severity == AER_CORRECTABLE)
-		loglevel = KERN_WARNING;
-	else
-		loglevel = KERN_ERR;
-
-	printk("%s+------ PCI-Express Device Error ------+\n", loglevel);
-	printk("%sError Severity\t\t: %s\n", loglevel,
-		aer_error_severity_string[info->severity]);
-
-	if ( info->status == 0) {
-		printk("%sPCIE Bus Error type\t: (Unaccessible)\n", loglevel);
-		printk("%sUnaccessible Received\t: %s\n", loglevel,
-			info->flags & AER_MULTI_ERROR_VALID_FLAG ?
-				"Multiple" : "First");
-		printk("%sUnregistered Agent ID\t: %04x\n", loglevel,
-			(dev->bus->number << 8) | dev->devfn);
+	int id = ((dev->bus->number << 8) | dev->devfn);
+
+	if (info->status == 0) {
+		AER_PR(info, dev,
+			"PCIE Bus Error: severity=%s, type=Unaccessible, "
+			"id=%04x(Unregistered Agent ID)\n",
+			aer_error_severity_string[info->severity], id);
 	} else {
-		err_layer = AER_GET_LAYER_ERROR(info->severity, info->status);
-		printk("%sPCIE Bus Error type\t: %s\n", loglevel,
-			aer_error_layer[err_layer]);
-
-		spin_lock(&logbuf_lock);
-		errmsg = aer_get_error_source_name(info->severity,
-				info->status,
-				errmsg_buff);
-		printk("%s%s\t: %s\n", loglevel, errmsg,
-			info->flags & AER_MULTI_ERROR_VALID_FLAG ?
-				"Multiple" : "First");
-		spin_unlock(&logbuf_lock);
+		int layer, agent;
 
+		layer = AER_GET_LAYER_ERROR(info->severity, info->status);
 		agent = AER_GET_AGENT(info->severity, info->status);
-		printk("%s%s\t\t: %04x\n", loglevel,
-			aer_agent_string[agent],
-			(dev->bus->number << 8) | dev->devfn);
-
-		printk("%sVendorID=%04xh, DeviceID=%04xh,"
-			" Bus=%02xh, Device=%02xh, Function=%02xh\n",
-			loglevel,
-			dev->vendor,
-			dev->device,
-			dev->bus->number,
-			PCI_SLOT(dev->devfn),
-			PCI_FUNC(dev->devfn));
-
-		if (info->flags & AER_TLP_HEADER_VALID_FLAG) {
+
+		AER_PR(info, dev,
+			"PCIE Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
+			aer_error_severity_string[info->severity],
+			aer_error_layer[layer], id, aer_agent_string[agent]);
+
+		AER_PR(info, dev,
+			"  device [%04x:%04x] error status/mask=%08x/%08x\n",
+			dev->vendor, dev->device, info->status, info->mask);
+
+		__aer_print_error(info, dev);
+
+		if (info->tlp_header_valid) {
 			unsigned char *tlp = (unsigned char *) &info->tlp;
-			printk("%sTLP Header:\n", loglevel);
-			printk("%s%02x%02x%02x%02x %02x%02x%02x%02x"
+			AER_PR(info, dev, "  TLP Header:"
+				" %02x%02x%02x%02x %02x%02x%02x%02x"
 				" %02x%02x%02x%02x %02x%02x%02x%02x\n",
-				loglevel,
 				*(tlp + 3), *(tlp + 2), *(tlp + 1), *tlp,
 				*(tlp + 7), *(tlp + 6), *(tlp + 5), *(tlp + 4),
 				*(tlp + 11), *(tlp + 10), *(tlp + 9),
@@ -244,5 +216,15 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 				*(tlp + 13), *(tlp + 12));
 		}
 	}
+
+	if (info->id && info->error_dev_num > 1 && info->id == id)
+		AER_PR(info, dev,
+			"  Error of this Agent(%04x) is reported first\n", id);
 }
 
+void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
+{
+	dev_info(&dev->dev, "AER: %s%s error received: id=%04x\n",
+		info->multi_error_valid ? "Multiple " : "",
+		aer_error_severity_string[info->severity], info->id);
+}
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 3d27c97..f289ca9 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -26,6 +26,13 @@
 #endif
 #define MODULE_PARAM_PREFIX "pcie_aspm."
 
+/* Note: those are not register definitions */
+#define ASPM_STATE_L0S_UP	(1)	/* Upstream direction L0s state */
+#define ASPM_STATE_L0S_DW	(2)	/* Downstream direction L0s state */
+#define ASPM_STATE_L1		(4)	/* L1 state */
+#define ASPM_STATE_L0S		(ASPM_STATE_L0S_UP | ASPM_STATE_L0S_DW)
+#define ASPM_STATE_ALL		(ASPM_STATE_L0S | ASPM_STATE_L1)
+
 struct aspm_latency {
 	u32 l0s;			/* L0s latency (nsec) */
 	u32 l1;				/* L1 latency (nsec) */
@@ -40,17 +47,20 @@ struct pcie_link_state {
 	struct list_head link;		/* node in parent's children list */
 
 	/* ASPM state */
-	u32 aspm_support:2;		/* Supported ASPM state */
-	u32 aspm_enabled:2;		/* Enabled ASPM state */
-	u32 aspm_default:2;		/* Default ASPM state by BIOS */
+	u32 aspm_support:3;		/* Supported ASPM state */
+	u32 aspm_enabled:3;		/* Enabled ASPM state */
+	u32 aspm_capable:3;		/* Capable ASPM state with latency */
+	u32 aspm_default:3;		/* Default ASPM state by BIOS */
+	u32 aspm_disable:3;		/* Disabled ASPM state */
 
 	/* Clock PM state */
 	u32 clkpm_capable:1;		/* Clock PM capable? */
 	u32 clkpm_enabled:1;		/* Current Clock PM state */
 	u32 clkpm_default:1;		/* Default Clock PM state by BIOS */
 
-	/* Latencies */
-	struct aspm_latency latency;	/* Exit latency */
+	/* Exit latencies */
+	struct aspm_latency latency_up;	/* Upstream direction exit latency */
+	struct aspm_latency latency_dw;	/* Downstream direction exit latency */
 	/*
 	 * Endpoint acceptable latencies. A pcie downstream port only
 	 * has one slot under it, so at most there are 8 functions.
@@ -82,7 +92,7 @@ static int policy_to_aspm_state(struct pcie_link_state *link)
 		return 0;
 	case POLICY_POWERSAVE:
 		/* Enable ASPM L0s/L1 */
-		return PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
+		return ASPM_STATE_ALL;
 	case POLICY_DEFAULT:
 		return link->aspm_default;
 	}
@@ -164,18 +174,6 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist)
 	link->clkpm_capable = (blacklist) ? 0 : capable;
 }
 
-static bool pcie_aspm_downstream_has_switch(struct pcie_link_state *link)
-{
-	struct pci_dev *child;
-	struct pci_bus *linkbus = link->pdev->subordinate;
-
-	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		if (child->pcie_type == PCI_EXP_TYPE_UPSTREAM)
-			return true;
-	}
-	return false;
-}
-
 /*
  * pcie_aspm_configure_common_clock: check if the 2 ends of a link
  *   could use common clock. If they are, configure them to use the
@@ -288,71 +286,133 @@ static u32 calc_l1_acceptable(u32 encoding)
 	return (1000 << encoding);
 }
 
-static void pcie_aspm_get_cap_device(struct pci_dev *pdev, u32 *state,
-				     u32 *l0s, u32 *l1, u32 *enabled)
+struct aspm_register_info {
+	u32 support:2;
+	u32 enabled:2;
+	u32 latency_encoding_l0s;
+	u32 latency_encoding_l1;
+};
+
+static void pcie_get_aspm_reg(struct pci_dev *pdev,
+			      struct aspm_register_info *info)
 {
 	int pos;
 	u16 reg16;
-	u32 reg32, encoding;
+	u32 reg32;
 
-	*l0s = *l1 = *enabled = 0;
 	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 	pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &reg32);
-	*state = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
-	if (*state != PCIE_LINK_STATE_L0S &&
-	    *state != (PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_L0S))
-		*state = 0;
-	if (*state == 0)
+	info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
+	/* 00b and 10b are defined as "Reserved". */
+	if (info->support == PCIE_LINK_STATE_L1)
+		info->support = 0;
+	info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
+	info->latency_encoding_l1  = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
+	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
+	info->enabled = reg16 & PCI_EXP_LNKCTL_ASPMC;
+}
+
+static void pcie_aspm_check_latency(struct pci_dev *endpoint)
+{
+	u32 latency, l1_switch_latency = 0;
+	struct aspm_latency *acceptable;
+	struct pcie_link_state *link;
+
+	/* Device not in D0 doesn't need latency check */
+	if ((endpoint->current_state != PCI_D0) &&
+	    (endpoint->current_state != PCI_UNKNOWN))
 		return;
 
-	encoding = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
-	*l0s = calc_l0s_latency(encoding);
-	if (*state & PCIE_LINK_STATE_L1) {
-		encoding = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
-		*l1 = calc_l1_latency(encoding);
+	link = endpoint->bus->self->link_state;
+	acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
+
+	while (link) {
+		/* Check upstream direction L0s latency */
+		if ((link->aspm_capable & ASPM_STATE_L0S_UP) &&
+		    (link->latency_up.l0s > acceptable->l0s))
+			link->aspm_capable &= ~ASPM_STATE_L0S_UP;
+
+		/* Check downstream direction L0s latency */
+		if ((link->aspm_capable & ASPM_STATE_L0S_DW) &&
+		    (link->latency_dw.l0s > acceptable->l0s))
+			link->aspm_capable &= ~ASPM_STATE_L0S_DW;
+		/*
+		 * Check L1 latency.
+		 * Every switch on the path to root complex need 1
+		 * more microsecond for L1. Spec doesn't mention L0s.
+		 */
+		latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1);
+		if ((link->aspm_capable & ASPM_STATE_L1) &&
+		    (latency + l1_switch_latency > acceptable->l1))
+			link->aspm_capable &= ~ASPM_STATE_L1;
+		l1_switch_latency += 1000;
+
+		link = link->parent;
 	}
-	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
-	*enabled = reg16 & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
 }
 
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
-	u32 support, l0s, l1, enabled;
 	struct pci_dev *child, *parent = link->pdev;
 	struct pci_bus *linkbus = parent->subordinate;
+	struct aspm_register_info upreg, dwreg;
 
 	if (blacklist) {
-		/* Set support state to 0, so we will disable ASPM later */
-		link->aspm_support = 0;
-		link->aspm_default = 0;
-		link->aspm_enabled = PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1;
+		/* Set enabled/disable so that we will disable ASPM later */
+		link->aspm_enabled = ASPM_STATE_ALL;
+		link->aspm_disable = ASPM_STATE_ALL;
 		return;
 	}
 
 	/* Configure common clock before checking latencies */
 	pcie_aspm_configure_common_clock(link);
 
-	/* upstream component states */
-	pcie_aspm_get_cap_device(parent, &support, &l0s, &l1, &enabled);
-	link->aspm_support = support;
-	link->latency.l0s = l0s;
-	link->latency.l1 = l1;
-	link->aspm_enabled = enabled;
-
-	/* downstream component states, all functions have the same setting */
+	/* Get upstream/downstream components' register state */
+	pcie_get_aspm_reg(parent, &upreg);
 	child = list_entry(linkbus->devices.next, struct pci_dev, bus_list);
-	pcie_aspm_get_cap_device(child, &support, &l0s, &l1, &enabled);
-	link->aspm_support &= support;
-	link->latency.l0s = max_t(u32, link->latency.l0s, l0s);
-	link->latency.l1 = max_t(u32, link->latency.l1, l1);
+	pcie_get_aspm_reg(child, &dwreg);
 
-	if (!link->aspm_support)
-		return;
-
-	link->aspm_enabled &= link->aspm_support;
+	/*
+	 * Setup L0s state
+	 *
+	 * Note that we must not enable L0s in either direction on a
+	 * given link unless components on both sides of the link each
+	 * support L0s.
+	 */
+	if (dwreg.support & upreg.support & PCIE_LINK_STATE_L0S)
+		link->aspm_support |= ASPM_STATE_L0S;
+	if (dwreg.enabled & PCIE_LINK_STATE_L0S)
+		link->aspm_enabled |= ASPM_STATE_L0S_UP;
+	if (upreg.enabled & PCIE_LINK_STATE_L0S)
+		link->aspm_enabled |= ASPM_STATE_L0S_DW;
+	link->latency_up.l0s = calc_l0s_latency(upreg.latency_encoding_l0s);
+	link->latency_dw.l0s = calc_l0s_latency(dwreg.latency_encoding_l0s);
+
+	/* Setup L1 state */
+	if (upreg.support & dwreg.support & PCIE_LINK_STATE_L1)
+		link->aspm_support |= ASPM_STATE_L1;
+	if (upreg.enabled & dwreg.enabled & PCIE_LINK_STATE_L1)
+		link->aspm_enabled |= ASPM_STATE_L1;
+	link->latency_up.l1 = calc_l1_latency(upreg.latency_encoding_l1);
+	link->latency_dw.l1 = calc_l1_latency(dwreg.latency_encoding_l1);
+
+	/* Save default state */
 	link->aspm_default = link->aspm_enabled;
 
-	/* ENDPOINT states*/
+	/* Setup initial capable state. Will be updated later */
+	link->aspm_capable = link->aspm_support;
+	/*
+	 * If the downstream component has pci bridge function, don't
+	 * do ASPM for now.
+	 */
+	list_for_each_entry(child, &linkbus->devices, bus_list) {
+		if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) {
+			link->aspm_disable = ASPM_STATE_ALL;
+			break;
+		}
+	}
+
+	/* Get and check endpoint acceptable latencies */
 	list_for_each_entry(child, &linkbus->devices, bus_list) {
 		int pos;
 		u32 reg32, encoding;
@@ -365,109 +425,46 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 
 		pos = pci_find_capability(child, PCI_CAP_ID_EXP);
 		pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, &reg32);
+		/* Calculate endpoint L0s acceptable latency */
 		encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6;
 		acceptable->l0s = calc_l0s_acceptable(encoding);
-		if (link->aspm_support & PCIE_LINK_STATE_L1) {
-			encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
-			acceptable->l1 = calc_l1_acceptable(encoding);
-		}
-	}
-}
-
-/**
- * __pcie_aspm_check_state_one - check latency for endpoint device.
- * @endpoint: pointer to the struct pci_dev of endpoint device
- *
- * TBD: The latency from the endpoint to root complex vary per switch's
- * upstream link state above the device. Here we just do a simple check
- * which assumes all links above the device can be in L1 state, that
- * is we just consider the worst case. If switch's upstream link can't
- * be put into L0S/L1, then our check is too strictly.
- */
-static u32 __pcie_aspm_check_state_one(struct pci_dev *endpoint, u32 state)
-{
-	u32 l1_switch_latency = 0;
-	struct aspm_latency *acceptable;
-	struct pcie_link_state *link;
-
-	link = endpoint->bus->self->link_state;
-	state &= link->aspm_support;
-	acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)];
+		/* Calculate endpoint L1 acceptable latency */
+		encoding = (reg32 & PCI_EXP_DEVCAP_L1) >> 9;
+		acceptable->l1 = calc_l1_acceptable(encoding);
 
-	while (link && state) {
-		if ((state & PCIE_LINK_STATE_L0S) &&
-		    (link->latency.l0s > acceptable->l0s))
-			state &= ~PCIE_LINK_STATE_L0S;
-		if ((state & PCIE_LINK_STATE_L1) &&
-		    (link->latency.l1 + l1_switch_latency > acceptable->l1))
-			state &= ~PCIE_LINK_STATE_L1;
-		link = link->parent;
-		/*
-		 * Every switch on the path to root complex need 1
-		 * more microsecond for L1. Spec doesn't mention L0s.
-		 */
-		l1_switch_latency += 1000;
-	}
-	return state;
-}
-
-static u32 pcie_aspm_check_state(struct pcie_link_state *link, u32 state)
-{
-	pci_power_t power_state;
-	struct pci_dev *child;
-	struct pci_bus *linkbus = link->pdev->subordinate;
-
-	/* If no child, ignore the link */
-	if (list_empty(&linkbus->devices))
-		return state;
-
-	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		/*
-		 * If downstream component of a link is pci bridge, we
-		 * disable ASPM for now for the link
-		 */
-		if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
-			return 0;
-
-		if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT &&
-		     child->pcie_type != PCI_EXP_TYPE_LEG_END))
-			continue;
-		/* Device not in D0 doesn't need check latency */
-		power_state = child->current_state;
-		if (power_state == PCI_D1 || power_state == PCI_D2 ||
-		    power_state == PCI_D3hot || power_state == PCI_D3cold)
-			continue;
-		state = __pcie_aspm_check_state_one(child, state);
+		pcie_aspm_check_latency(child);
 	}
-	return state;
 }
 
-static void __pcie_aspm_config_one_dev(struct pci_dev *pdev, unsigned int state)
+static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val)
 {
 	u16 reg16;
 	int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 
 	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
 	reg16 &= ~0x3;
-	reg16 |= state;
+	reg16 |= val;
 	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
 }
 
-static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state)
+static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state)
 {
+	u32 upstream = 0, dwstream = 0;
 	struct pci_dev *child, *parent = link->pdev;
 	struct pci_bus *linkbus = parent->subordinate;
 
-	/* If no child, disable the link */
-	if (list_empty(&linkbus->devices))
-		state = 0;
-	/*
-	 * If the downstream component has pci bridge function, don't
-	 * do ASPM now.
-	 */
-	list_for_each_entry(child, &linkbus->devices, bus_list) {
-		if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
-			return;
+	/* Nothing to do if the link is already in the requested state */
+	state &= (link->aspm_capable & ~link->aspm_disable);
+	if (link->aspm_enabled == state)
+		return;
+	/* Convert ASPM state to upstream/downstream ASPM register state */
+	if (state & ASPM_STATE_L0S_UP)
+		dwstream |= PCIE_LINK_STATE_L0S;
+	if (state & ASPM_STATE_L0S_DW)
+		upstream |= PCIE_LINK_STATE_L0S;
+	if (state & ASPM_STATE_L1) {
+		upstream |= PCIE_LINK_STATE_L1;
+		dwstream |= PCIE_LINK_STATE_L1;
 	}
 	/*
 	 * Spec 2.0 suggests all functions should be configured the
@@ -475,67 +472,24 @@ static void __pcie_aspm_config_link(struct pcie_link_state *link, u32 state)
 	 * upstream component first and then downstream, and vice
 	 * versa for disabling ASPM L1. Spec doesn't mention L0S.
 	 */
-	if (state & PCIE_LINK_STATE_L1)
-		__pcie_aspm_config_one_dev(parent, state);
-
+	if (state & ASPM_STATE_L1)
+		pcie_config_aspm_dev(parent, upstream);
 	list_for_each_entry(child, &linkbus->devices, bus_list)
-		__pcie_aspm_config_one_dev(child, state);
-
-	if (!(state & PCIE_LINK_STATE_L1))
-		__pcie_aspm_config_one_dev(parent, state);
+		pcie_config_aspm_dev(child, dwstream);
+	if (!(state & ASPM_STATE_L1))
+		pcie_config_aspm_dev(parent, upstream);
 
 	link->aspm_enabled = state;
 }
 
-/* Check the whole hierarchy, and configure each link in the hierarchy */
-static void __pcie_aspm_configure_link_state(struct pcie_link_state *link,
-					     u32 state)
+static void pcie_config_aspm_path(struct pcie_link_state *link)
 {
-	struct pcie_link_state *leaf, *root = link->root;
-
-	state &= (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
-
-	/* Check all links who have specific root port link */
-	list_for_each_entry(leaf, &link_list, sibling) {
-		if (!list_empty(&leaf->children) || (leaf->root != root))
-			continue;
-		state = pcie_aspm_check_state(leaf, state);
-	}
-	/* Check root port link too in case it hasn't children */
-	state = pcie_aspm_check_state(root, state);
-	if (link->aspm_enabled == state)
-		return;
-	/*
-	 * We must change the hierarchy. See comments in
-	 * __pcie_aspm_config_link for the order
-	 **/
-	if (state & PCIE_LINK_STATE_L1) {
-		list_for_each_entry(leaf, &link_list, sibling) {
-			if (leaf->root == root)
-				__pcie_aspm_config_link(leaf, state);
-		}
-	} else {
-		list_for_each_entry_reverse(leaf, &link_list, sibling) {
-			if (leaf->root == root)
-				__pcie_aspm_config_link(leaf, state);
-		}
+	while (link) {
+		pcie_config_aspm_link(link, policy_to_aspm_state(link));
+		link = link->parent;
 	}
 }
 
-/*
- * pcie_aspm_configure_link_state: enable/disable PCI express link state
- * @pdev: the root port or switch downstream port
- */
-static void pcie_aspm_configure_link_state(struct pcie_link_state *link,
-					   u32 state)
-{
-	down_read(&pci_bus_sem);
-	mutex_lock(&aspm_lock);
-	__pcie_aspm_configure_link_state(link, state);
-	mutex_unlock(&aspm_lock);
-	up_read(&pci_bus_sem);
-}
-
 static void free_link_state(struct pcie_link_state *link)
 {
 	link->pdev->link_state = NULL;
@@ -570,10 +524,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
 	return 0;
 }
 
-static struct pcie_link_state *pcie_aspm_setup_link_state(struct pci_dev *pdev)
+static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
 {
 	struct pcie_link_state *link;
-	int blacklist = !!pcie_aspm_sanity_check(pdev);
 
 	link = kzalloc(sizeof(*link), GFP_KERNEL);
 	if (!link)
@@ -599,15 +552,7 @@ static struct pcie_link_state *pcie_aspm_setup_link_state(struct pci_dev *pdev)
 		link->root = link->parent->root;
 
 	list_add(&link->sibling, &link_list);
-
 	pdev->link_state = link;
-
-	/* Check ASPM capability */
-	pcie_aspm_cap_init(link, blacklist);
-
-	/* Check Clock PM capability */
-	pcie_clkpm_cap_init(link, blacklist);
-
 	return link;
 }
 
@@ -618,8 +563,8 @@ static struct pcie_link_state *pcie_aspm_setup_link_state(struct pci_dev *pdev)
  */
 void pcie_aspm_init_link_state(struct pci_dev *pdev)
 {
-	u32 state;
 	struct pcie_link_state *link;
+	int blacklist = !!pcie_aspm_sanity_check(pdev);
 
 	if (aspm_disabled || !pdev->is_pcie || pdev->link_state)
 		return;
@@ -637,47 +582,64 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
 		goto out;
 
 	mutex_lock(&aspm_lock);
-	link = pcie_aspm_setup_link_state(pdev);
+	link = alloc_pcie_link_state(pdev);
 	if (!link)
 		goto unlock;
 	/*
-	 * Setup initial ASPM state
-	 *
-	 * If link has switch, delay the link config. The leaf link
-	 * initialization will config the whole hierarchy. But we must
-	 * make sure BIOS doesn't set unsupported link state.
+	 * Setup initial ASPM state. Note that we need to configure
+	 * upstream links also because capable state of them can be
+	 * update through pcie_aspm_cap_init().
 	 */
-	if (pcie_aspm_downstream_has_switch(link)) {
-		state = pcie_aspm_check_state(link, link->aspm_default);
-		__pcie_aspm_config_link(link, state);
-	} else {
-		state = policy_to_aspm_state(link);
-		__pcie_aspm_configure_link_state(link, state);
-	}
+	pcie_aspm_cap_init(link, blacklist);
+	pcie_config_aspm_path(link);
 
 	/* Setup initial Clock PM state */
-	state = (link->clkpm_capable) ? policy_to_clkpm_state(link) : 0;
-	pcie_set_clkpm(link, state);
+	pcie_clkpm_cap_init(link, blacklist);
+	pcie_set_clkpm(link, policy_to_clkpm_state(link));
 unlock:
 	mutex_unlock(&aspm_lock);
 out:
 	up_read(&pci_bus_sem);
 }
 
+/* Recheck latencies and update aspm_capable for links under the root */
+static void pcie_update_aspm_capable(struct pcie_link_state *root)
+{
+	struct pcie_link_state *link;
+	BUG_ON(root->parent);
+	list_for_each_entry(link, &link_list, sibling) {
+		if (link->root != root)
+			continue;
+		link->aspm_capable = link->aspm_support;
+	}
+	list_for_each_entry(link, &link_list, sibling) {
+		struct pci_dev *child;
+		struct pci_bus *linkbus = link->pdev->subordinate;
+		if (link->root != root)
+			continue;
+		list_for_each_entry(child, &linkbus->devices, bus_list) {
+			if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT) &&
+			    (child->pcie_type != PCI_EXP_TYPE_LEG_END))
+				continue;
+			pcie_aspm_check_latency(child);
+		}
+	}
+}
+
 /* @pdev: the endpoint device */
 void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 {
 	struct pci_dev *parent = pdev->bus->self;
-	struct pcie_link_state *link_state = parent->link_state;
+	struct pcie_link_state *link, *root, *parent_link;
 
-	if (aspm_disabled || !pdev->is_pcie || !parent || !link_state)
+	if (aspm_disabled || !pdev->is_pcie || !parent || !parent->link_state)
 		return;
-	if (parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+	if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
+	    (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
 		return;
+
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
-
 	/*
 	 * All PCIe functions are in one slot, remove one function will remove
 	 * the whole slot, so just wait until we are the last function left.
@@ -685,13 +647,20 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
 	if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices))
 		goto out;
 
+	link = parent->link_state;
+	root = link->root;
+	parent_link = link->parent;
+
 	/* All functions are removed, so just disable ASPM for the link */
-	__pcie_aspm_config_one_dev(parent, 0);
-	list_del(&link_state->sibling);
-	list_del(&link_state->link);
+	pcie_config_aspm_link(link, 0);
+	list_del(&link->sibling);
+	list_del(&link->link);
 	/* Clock PM is for endpoint device */
+	free_link_state(link);
 
-	free_link_state(link_state);
+	/* Recheck latencies and configure upstream links */
+	pcie_update_aspm_capable(root);
+	pcie_config_aspm_path(parent_link);
 out:
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
@@ -700,18 +669,23 @@ out:
 /* @pdev: the root port or switch downstream port */
 void pcie_aspm_pm_state_change(struct pci_dev *pdev)
 {
-	struct pcie_link_state *link_state = pdev->link_state;
+	struct pcie_link_state *link = pdev->link_state;
 
-	if (aspm_disabled || !pdev->is_pcie || !pdev->link_state)
+	if (aspm_disabled || !pdev->is_pcie || !link)
 		return;
-	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
-		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+	if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
+	    (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))
 		return;
 	/*
-	 * devices changed PM state, we should recheck if latency meets all
-	 * functions' requirement
+	 * Devices changed PM state, we should recheck if latency
+	 * meets all functions' requirement
 	 */
-	pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled);
+	down_read(&pci_bus_sem);
+	mutex_lock(&aspm_lock);
+	pcie_update_aspm_capable(link->root);
+	pcie_config_aspm_path(link);
+	mutex_unlock(&aspm_lock);
+	up_read(&pci_bus_sem);
 }
 
 /*
@@ -721,7 +695,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev)
 void pci_disable_link_state(struct pci_dev *pdev, int state)
 {
 	struct pci_dev *parent = pdev->bus->self;
-	struct pcie_link_state *link_state;
+	struct pcie_link_state *link;
 
 	if (aspm_disabled || !pdev->is_pcie)
 		return;
@@ -733,12 +707,16 @@ void pci_disable_link_state(struct pci_dev *pdev, int state)
 
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
-	link_state = parent->link_state;
-	link_state->aspm_support &= ~state;
-	__pcie_aspm_configure_link_state(link_state, link_state->aspm_enabled);
+	link = parent->link_state;
+	if (state & PCIE_LINK_STATE_L0S)
+		link->aspm_disable |= ASPM_STATE_L0S;
+	if (state & PCIE_LINK_STATE_L1)
+		link->aspm_disable |= ASPM_STATE_L1;
+	pcie_config_aspm_link(link, policy_to_aspm_state(link));
+
 	if (state & PCIE_LINK_STATE_CLKPM) {
-		link_state->clkpm_capable = 0;
-		pcie_set_clkpm(link_state, 0);
+		link->clkpm_capable = 0;
+		pcie_set_clkpm(link, 0);
 	}
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
@@ -748,7 +726,7 @@ EXPORT_SYMBOL(pci_disable_link_state);
 static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
 {
 	int i;
-	struct pcie_link_state *link_state;
+	struct pcie_link_state *link;
 
 	for (i = 0; i < ARRAY_SIZE(policy_str); i++)
 		if (!strncmp(val, policy_str[i], strlen(policy_str[i])))
@@ -761,10 +739,9 @@ static int pcie_aspm_set_policy(const char *val, struct kernel_param *kp)
 	down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
 	aspm_policy = i;
-	list_for_each_entry(link_state, &link_list, sibling) {
-		__pcie_aspm_configure_link_state(link_state,
-			policy_to_aspm_state(link_state));
-		pcie_set_clkpm(link_state, policy_to_clkpm_state(link_state));
+	list_for_each_entry(link, &link_list, sibling) {
+		pcie_config_aspm_link(link, policy_to_aspm_state(link));
+		pcie_set_clkpm(link, policy_to_clkpm_state(link));
 	}
 	mutex_unlock(&aspm_lock);
 	up_read(&pci_bus_sem);
@@ -802,18 +779,28 @@ static ssize_t link_state_store(struct device *dev,
 		size_t n)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
-	int state;
+	struct pcie_link_state *link, *root = pdev->link_state->root;
+	u32 val = buf[0] - '0', state = 0;
 
-	if (n < 1)
+	if (n < 1 || val > 3)
 		return -EINVAL;
-	state = buf[0]-'0';
-	if (state >= 0 && state <= 3) {
-		/* setup link aspm state */
-		pcie_aspm_configure_link_state(pdev->link_state, state);
-		return n;
-	}
 
-	return -EINVAL;
+	/* Convert requested state to ASPM state */
+	if (val & PCIE_LINK_STATE_L0S)
+		state |= ASPM_STATE_L0S;
+	if (val & PCIE_LINK_STATE_L1)
+		state |= ASPM_STATE_L1;
+
+	down_read(&pci_bus_sem);
+	mutex_lock(&aspm_lock);
+	list_for_each_entry(link, &link_list, sibling) {
+		if (link->root != root)
+			continue;
+		pcie_config_aspm_link(link, state);
+	}
+	mutex_unlock(&aspm_lock);
+	up_read(&pci_bus_sem);
+	return n;
 }
 
 static ssize_t clk_ctl_show(struct device *dev,
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 13ffdc3..52f84fc 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -187,14 +187,9 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
  */
 static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
 {
-	struct pcie_port_data *port_data = pci_get_drvdata(dev);
 	int irq, interrupt_mode = PCIE_PORT_NO_IRQ;
 	int i;
 
-	/* Check MSI quirk */
-	if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk)
-		goto Fallback;
-
 	/* Try to use MSI-X if supported */
 	if (!pcie_port_enable_msix(dev, vectors, mask))
 		return PCIE_PORT_MSIX_MODE;
@@ -203,7 +198,6 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
 	if (!pci_enable_msi(dev))
 		interrupt_mode = PCIE_PORT_MSI_MODE;
 
- Fallback:
 	if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin)
 		interrupt_mode = PCIE_PORT_INTx_MODE;
 
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 091ce70..6df5c98 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -205,6 +205,7 @@ static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
 
 	/* If fatal, restore cfg space for possible link reset at upstream */
 	if (dev->error_state == pci_channel_io_frozen) {
+		dev->state_saved = true;
 		pci_restore_state(dev);
 		pcie_portdrv_restore_config(dev);
 		pci_enable_pcie_error_reporting(dev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 40e75f6..8105e32 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -235,7 +235,10 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			res->start = l64;
 			res->end = l64 + sz64;
 			dev_printk(KERN_DEBUG, &dev->dev,
-				"reg %x 64bit mmio: %pR\n", pos, res);
+				"reg %x %s: %pR\n", pos,
+				 (res->flags & IORESOURCE_PREFETCH) ?
+					"64bit mmio pref" : "64bit mmio",
+				 res);
 		}
 
 		res->flags |= IORESOURCE_MEM_64;
@@ -249,7 +252,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		res->end = l + sz;
 
 		dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos,
-			(res->flags & IORESOURCE_IO) ? "io port" : "32bit mmio",
+			(res->flags & IORESOURCE_IO) ? "io port" :
+			 ((res->flags & IORESOURCE_PREFETCH) ?
+				 "32bit mmio pref" : "32bit mmio"),
 			res);
 	}
 
@@ -692,6 +697,23 @@ static void set_pcie_port_type(struct pci_dev *pdev)
 	pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
 }
 
+static void set_pcie_hotplug_bridge(struct pci_dev *pdev)
+{
+	int pos;
+	u16 reg16;
+	u32 reg32;
+
+	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	if (!pos)
+		return;
+	pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
+	if (!(reg16 & PCI_EXP_FLAGS_SLOT))
+		return;
+	pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &reg32);
+	if (reg32 & PCI_EXP_SLTCAP_HPC)
+		pdev->is_hotplug_bridge = 1;
+}
+
 #define LEGACY_IO_RESOURCE	(IORESOURCE_IO | IORESOURCE_PCI_FIXED)
 
 /**
@@ -799,6 +821,7 @@ int pci_setup_device(struct pci_dev *dev)
 		pci_read_irq(dev);
 		dev->transparent = ((dev->class & 0xff) == 1);
 		pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
+		set_pcie_hotplug_bridge(dev);
 		break;
 
 	case PCI_HEADER_TYPE_CARDBUS:		    /* CardBus bridge header */
@@ -1009,6 +1032,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
 	/* Fix up broken headers */
 	pci_fixup_device(pci_fixup_header, dev);
 
+	/* Clear the state_saved flag. */
+	dev->state_saved = false;
+
 	/* Initialize various capabilities */
 	pci_init_capabilities(dev);
 
@@ -1061,8 +1087,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
 	if (dev && !dev->is_added)	/* new device? */
 		nr++;
 
-	if ((dev && dev->multifunction) ||
-	    (!dev && pcibios_scan_all_fns(bus, devfn))) {
+	if (dev && dev->multifunction) {
 		for (fn = 1; fn < 8; fn++) {
 			dev = pci_scan_single_device(bus, devfn + fn);
 			if (dev) {
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 85ce239..6099fac 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -31,8 +31,6 @@ int isa_dma_bridge_buggy;
 EXPORT_SYMBOL(isa_dma_bridge_buggy);
 int pci_pci_problems;
 EXPORT_SYMBOL(pci_pci_problems);
-int pcie_mch_quirk;
-EXPORT_SYMBOL(pcie_mch_quirk);
 
 #ifdef CONFIG_PCI_QUIRKS
 /*
@@ -1203,6 +1201,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
 			switch(dev->subsystem_device) {
 			case 0x00b8: /* Compaq Evo D510 CMT */
 			case 0x00b9: /* Compaq Evo D510 SFF */
+			case 0x00ba: /* Compaq Evo D510 USDT */
 				/* Motherboard doesn't have Host bridge
 				 * subvendor/subdevice IDs and on-board VGA
 				 * controller is disabled if an AGP card is
@@ -1501,7 +1500,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_EESSC,	quirk_a
 
 static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
 {
-	pcie_mch_quirk = 1;
+	pci_msi_off(pdev);
+	pdev->no_msi = 1;
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7520_MCH,	quirk_pcie_mch);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_E7320_MCH,	quirk_pcie_mch);
@@ -1569,10 +1569,8 @@ static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
 		return;
 
 	dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;
-
-	printk(KERN_INFO "PCI quirk: reroute interrupts for 0x%04x:0x%04x\n",
-			dev->vendor, dev->device);
-	return;
+	dev_info(&dev->dev, "rerouting interrupts for [%04x:%04x]\n",
+		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_80333_0,	quirk_reroute_to_boot_interrupts_intel);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_80333_1,	quirk_reroute_to_boot_interrupts_intel);
@@ -1614,8 +1612,8 @@ static void quirk_disable_intel_boot_interrupt(struct pci_dev *dev)
 	pci_config_word |= INTEL_6300_DISABLE_BOOT_IRQ;
 	pci_write_config_word(dev, INTEL_6300_IOAPIC_ABAR, pci_config_word);
 
-	printk(KERN_INFO "disabled boot interrupt on device 0x%04x:0x%04x\n",
-		dev->vendor, dev->device);
+	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ESB_10, 	quirk_disable_intel_boot_interrupt);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ESB_10, 	quirk_disable_intel_boot_interrupt);
@@ -1647,8 +1645,8 @@ static void quirk_disable_broadcom_boot_interrupt(struct pci_dev *dev)
 
 	pci_write_config_dword(dev, BC_HT1000_FEATURE_REG, pci_config_dword);
 
-	printk(KERN_INFO "disabled boot interrupts on PCI device"
-			"0x%04x:0x%04x\n", dev->vendor, dev->device);
+	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS,   PCI_DEVICE_ID_SERVERWORKS_HT1000SB, 	quirk_disable_broadcom_boot_interrupt);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS,   PCI_DEVICE_ID_SERVERWORKS_HT1000SB, 	quirk_disable_broadcom_boot_interrupt);
@@ -1678,8 +1676,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
 	pci_config_dword &= ~AMD_813X_NOIOAMODE;
 	pci_write_config_dword(dev, AMD_813X_MISC, pci_config_dword);
 
-	printk(KERN_INFO "disabled boot interrupts on PCI device "
-			"0x%04x:0x%04x\n", dev->vendor, dev->device);
+	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8131_BRIDGE, 	quirk_disable_amd_813x_boot_interrupt);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8132_BRIDGE, 	quirk_disable_amd_813x_boot_interrupt);
@@ -1695,14 +1693,13 @@ static void quirk_disable_amd_8111_boot_interrupt(struct pci_dev *dev)
 
 	pci_read_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, &pci_config_word);
 	if (!pci_config_word) {
-		printk(KERN_INFO "boot interrupts on PCI device 0x%04x:0x%04x "
-				"already disabled\n",
-				dev->vendor, dev->device);
+		dev_info(&dev->dev, "boot interrupts on device [%04x:%04x] "
+			 "already disabled\n", dev->vendor, dev->device);
 		return;
 	}
 	pci_write_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, 0);
-	printk(KERN_INFO "disabled boot interrupts on PCI device "
-			"0x%04x:0x%04x\n", dev->vendor, dev->device);
+	dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+		 dev->vendor, dev->device);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8111_SMBUS, 	quirk_disable_amd_8111_boot_interrupt);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD,   PCI_DEVICE_ID_AMD_8111_SMBUS, 	quirk_disable_amd_8111_boot_interrupt);
@@ -2384,8 +2381,10 @@ static void __devinit nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev)
 }
 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf);
 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
 
 static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
 {
@@ -2494,6 +2493,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150d, quirk_i82576_sriov);
 
 #endif	/* CONFIG_PCI_IOV */
 
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index e8cb505..ec41535 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -113,37 +113,6 @@ pci_find_next_bus(const struct pci_bus *from)
 	return b;
 }
 
-#ifdef CONFIG_PCI_LEGACY
-/**
- * pci_find_device - begin or continue searching for a PCI device by vendor/device id
- * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
- * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
- * @from: Previous PCI device found in search, or %NULL for new search.
- *
- * Iterates through the list of known PCI devices.  If a PCI device is found
- * with a matching @vendor and @device, a pointer to its device structure is
- * returned.  Otherwise, %NULL is returned.
- * A new search is initiated by passing %NULL as the @from argument.
- * Otherwise if @from is not %NULL, searches continue from next device
- * on the global list.
- *
- * NOTE: Do not use this function any more; use pci_get_device() instead, as
- * the PCI device returned by this function can disappear at any moment in
- * time.
- */
-struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
-				struct pci_dev *from)
-{
-	struct pci_dev *pdev;
-
-	pci_dev_get(from);
-	pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
-	pci_dev_put(pdev);
-	return pdev;
-}
-EXPORT_SYMBOL(pci_find_device);
-#endif /* CONFIG_PCI_LEGACY */
-
 /**
  * pci_get_slot - locate PCI device for a given PCI slot
  * @bus: PCI bus on which desired PCI device resides
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 7c443b4..cb1a027 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -309,7 +309,7 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon
    since these windows have 4K granularity and the IO ranges
    of non-bridge PCI devices are limited to 256 bytes.
    We must be careful with the ISA aliasing though. */
-static void pbus_size_io(struct pci_bus *bus)
+static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size)
 {
 	struct pci_dev *dev;
 	struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO);
@@ -336,6 +336,8 @@ static void pbus_size_io(struct pci_bus *bus)
 				size1 += r_size;
 		}
 	}
+	if (size < min_size)
+		size = min_size;
 /* To be fixed in 2.5: we should have sort of HAVE_ISA
    flag in the struct pci_bus. */
 #if defined(CONFIG_ISA) || defined(CONFIG_EISA)
@@ -354,7 +356,8 @@ static void pbus_size_io(struct pci_bus *bus)
 
 /* Calculate the size of the bus and minimal alignment which
    guarantees that all child resources fit in this size. */
-static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
+static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
+			 unsigned long type, resource_size_t min_size)
 {
 	struct pci_dev *dev;
 	resource_size_t min_align, align, size;
@@ -404,6 +407,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
 			mem64_mask &= r->flags & IORESOURCE_MEM_64;
 		}
 	}
+	if (size < min_size)
+		size = min_size;
 
 	align = 0;
 	min_align = 0;
@@ -483,6 +488,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
 	unsigned long mask, prefmask;
+	resource_size_t min_mem_size = 0, min_io_size = 0;
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		struct pci_bus *b = dev->subordinate;
@@ -512,8 +518,12 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
 
 	case PCI_CLASS_BRIDGE_PCI:
 		pci_bridge_check_ranges(bus);
+		if (bus->self->is_hotplug_bridge) {
+			min_io_size  = pci_hotplug_io_size;
+			min_mem_size = pci_hotplug_mem_size;
+		}
 	default:
-		pbus_size_io(bus);
+		pbus_size_io(bus, min_io_size);
 		/* If the bridge supports prefetchable range, size it
 		   separately. If it doesn't, or its prefetchable window
 		   has already been allocated by arch code, try
@@ -521,9 +531,11 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
 		   resources. */
 		mask = IORESOURCE_MEM;
 		prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
-		if (pbus_size_mem(bus, prefmask, prefmask))
+		if (pbus_size_mem(bus, prefmask, prefmask, min_mem_size))
 			mask = prefmask; /* Success, size non-prefetch only. */
-		pbus_size_mem(bus, mask, IORESOURCE_MEM);
+		else
+			min_mem_size += min_mem_size;
+		pbus_size_mem(bus, mask, IORESOURCE_MEM, min_mem_size);
 		break;
 	}
 }
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 88cdd1a..706f82d 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -119,6 +119,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
 
 	return err;
 }
+EXPORT_SYMBOL(pci_claim_resource);
 
 #ifdef CONFIG_PCI_QUIRKS
 void pci_disable_bridge_window(struct pci_dev *dev)
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index d6b4bd1..b1984ed 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -26,7 +26,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/tqueue.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 9627390..b43d47b 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -30,7 +30,6 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/kernel.h>
-#include <linux/tqueue.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 304ff6d..9f300d3 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -236,7 +236,6 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count)
 	if (!dynid)
 		return -ENOMEM;
 
-	INIT_LIST_HEAD(&dynid->node);
 	dynid->id.match_flags = match_flags;
 	dynid->id.manf_id = manf_id;
 	dynid->id.card_id = card_id;
@@ -246,7 +245,7 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count)
 	memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4);
 
 	spin_lock(&pdrv->dynids.lock);
-	list_add_tail(&pdrv->dynids.list, &dynid->node);
+	list_add_tail(&dynid->node, &pdrv->dynids.list);
 	spin_unlock(&pdrv->dynids.lock);
 
 	if (get_driver(&pdrv->drv)) {
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h
index 5554015..72188c4 100644
--- a/drivers/pcmcia/o2micro.h
+++ b/drivers/pcmcia/o2micro.h
@@ -48,6 +48,9 @@
 #ifndef PCI_DEVICE_ID_O2_6812
 #define PCI_DEVICE_ID_O2_6812		0x6872
 #endif
+#ifndef PCI_DEVICE_ID_O2_6933
+#define PCI_DEVICE_ID_O2_6933           0x6933
+#endif
 
 /* Additional PCI configuration registers */
 
@@ -154,6 +157,7 @@ static int o2micro_override(struct yenta_socket *socket)
 		case PCI_DEVICE_ID_O2_6812:
 		case PCI_DEVICE_ID_O2_6832:
 		case PCI_DEVICE_ID_O2_6836:
+ 		case PCI_DEVICE_ID_O2_6933:
 			dev_printk(KERN_INFO, &socket->dev->dev,
 				   "Yenta O2: old bridge, disabling read "
 				   "prefetch/write burst\n");
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 6095f8d..7b424e0 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -286,7 +286,7 @@ static int pccard_get_status(struct pcmcia_socket *s,
 	return 0;
 } /* pccard_get_status */
 
-int pccard_get_configuration_info(struct pcmcia_socket *s,
+static int pccard_get_configuration_info(struct pcmcia_socket *s,
 				  struct pcmcia_device *p_dev,
 				  config_info_t *config)
 {
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index f5d0ba8..d919e96 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -489,7 +489,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
 	pccard_io_map iomap;
 
 	if (!(s->state & SOCKET_PRESENT))
-		return -ENODEV;;
+		return -ENODEV;
 
 	if (req->IntType & INT_CARDBUS) {
 		ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
@@ -902,7 +902,7 @@ struct pcmcia_cfg_mem {
  *
  * pcmcia_loop_config() loops over all configuration options, and calls
  * the driver-specific conf_check() for each one, checking whether
- * it is a valid one.
+ * it is a valid one. Returns 0 on success or errorcode otherwise.
  */
 int pcmcia_loop_config(struct pcmcia_device *p_dev,
 		       int	(*conf_check)	(struct pcmcia_device *p_dev,
@@ -915,7 +915,7 @@ int pcmcia_loop_config(struct pcmcia_device *p_dev,
 	struct pcmcia_cfg_mem *cfg_mem;
 
 	tuple_t *tuple;
-	int ret = -ENODEV;
+	int ret;
 	unsigned int vcc;
 
 	cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 3ecd7c9..737fe5d 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -622,11 +622,12 @@ static int yenta_search_res(struct yenta_socket *socket, struct resource *res,
 
 static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end)
 {
-	struct resource *root, *res;
+	struct pci_dev *dev = socket->dev;
+	struct resource *res;
 	struct pci_bus_region region;
 	unsigned mask;
 
-	res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
+	res = dev->resource + PCI_BRIDGE_RESOURCES + nr;
 	/* Already allocated? */
 	if (res->parent)
 		return 0;
@@ -636,17 +637,16 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
 	if (type & IORESOURCE_IO)
 		mask = ~3;
 
-	res->name = socket->dev->subordinate->name;
+	res->name = dev->subordinate->name;
 	res->flags = type;
 
 	region.start = config_readl(socket, addr_start) & mask;
 	region.end = config_readl(socket, addr_end) | ~mask;
 	if (region.start && region.end > region.start && !override_bios) {
-		pcibios_bus_to_resource(socket->dev, res, &region);
-		root = pci_find_parent_resource(socket->dev, res);
-		if (root && (request_resource(root, res) == 0))
+		pcibios_bus_to_resource(dev, res, &region);
+		if (pci_claim_resource(dev, PCI_BRIDGE_RESOURCES + nr) == 0)
 			return 0;
-		dev_printk(KERN_INFO, &socket->dev->dev,
+		dev_printk(KERN_INFO, &dev->dev,
 			   "Preassigned resource %d busy or not available, "
 			   "reconfiguring...\n",
 			   nr);
@@ -672,7 +672,7 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
 			return 1;
 	}
 
-	dev_printk(KERN_INFO, &socket->dev->dev,
+	dev_printk(KERN_INFO, &dev->dev,
 		   "no resource of type %x available, trying to continue...\n",
 		   type);
 	res->start = res->end = res->flags = 0;
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index a2ad53e..af04f5b 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,7 +53,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
 
 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);
+static int hp_wmi_resume_handler(struct device *device);
 
 struct bios_args {
 	u32 signature;
@@ -94,14 +94,19 @@ static struct rfkill *wifi_rfkill;
 static struct rfkill *bluetooth_rfkill;
 static struct rfkill *wwan_rfkill;
 
+static struct dev_pm_ops hp_wmi_pm_ops = {
+	.resume  = hp_wmi_resume_handler,
+	.restore  = hp_wmi_resume_handler,
+};
+
 static struct platform_driver hp_wmi_driver = {
 	.driver = {
-		   .name = "hp-wmi",
-		   .owner = THIS_MODULE,
+		.name = "hp-wmi",
+		.owner = THIS_MODULE,
+		.pm = &hp_wmi_pm_ops,
 	},
 	.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)
@@ -512,7 +517,7 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
 	return 0;
 }
 
-static int hp_wmi_resume_handler(struct platform_device *device)
+static int hp_wmi_resume_handler(struct device *device)
 {
 	/*
 	 * Hardware state may have changed while suspended, so trigger
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 7e6b5a3..fc83783 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -55,12 +55,13 @@ __asm__(".text			\n"
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
-set_base(gdt[(selname) >> 3], (u32)(address)); \
-set_limit(gdt[(selname) >> 3], size); \
+	struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+	set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
+	set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
 } while(0)
 
-static struct desc_struct bad_bios_desc;
+static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
+			(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
 
 /*
  * At some point we want to use this stack frame pointer to unwind
@@ -476,19 +477,15 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
 	pnp_bios_callpoint.offset = header->fields.pm16offset;
 	pnp_bios_callpoint.segment = PNP_CS16;
 
-	bad_bios_desc.a = 0;
-	bad_bios_desc.b = 0x00409200;
-
-	set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
-	_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
 	for_each_possible_cpu(i) {
 		struct desc_struct *gdt = get_cpu_gdt_table(i);
 		if (!gdt)
 			continue;
-		set_base(gdt[GDT_ENTRY_PNPBIOS_CS32], &pnp_bios_callfunc);
-		set_base(gdt[GDT_ENTRY_PNPBIOS_CS16],
-			 __va(header->fields.pm16cseg));
-		set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
-			 __va(header->fields.pm16dseg));
+		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
+			 (unsigned long)&pnp_bios_callfunc);
+		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS16],
+			 (unsigned long)__va(header->fields.pm16cseg));
+		set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS],
+			 (unsigned long)__va(header->fields.pm16dseg));
 	}
 }
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
index 18066d5..af0afa1 100644
--- a/drivers/ps3/ps3stor_lib.c
+++ b/drivers/ps3/ps3stor_lib.c
@@ -23,6 +23,65 @@
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
 
+/*
+ * A workaround for flash memory I/O errors when the internal hard disk
+ * has not been formatted for OtherOS use.  Delay disk close until flash
+ * memory is closed.
+ */
+
+static struct ps3_flash_workaround {
+	int flash_open;
+	int disk_open;
+	struct ps3_system_bus_device *disk_sbd;
+} ps3_flash_workaround;
+
+static int ps3stor_open_hv_device(struct ps3_system_bus_device *sbd)
+{
+	int error = ps3_open_hv_device(sbd);
+
+	if (error)
+		return error;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_FLASH)
+		ps3_flash_workaround.flash_open = 1;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_DISK)
+		ps3_flash_workaround.disk_open = 1;
+
+	return 0;
+}
+
+static int ps3stor_close_hv_device(struct ps3_system_bus_device *sbd)
+{
+	int error;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_DISK
+		&& ps3_flash_workaround.disk_open
+		&& ps3_flash_workaround.flash_open) {
+		ps3_flash_workaround.disk_sbd = sbd;
+		return 0;
+	}
+
+	error = ps3_close_hv_device(sbd);
+
+	if (error)
+		return error;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_DISK)
+		ps3_flash_workaround.disk_open = 0;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_FLASH) {
+		ps3_flash_workaround.flash_open = 0;
+
+		if (ps3_flash_workaround.disk_sbd) {
+			ps3_close_hv_device(ps3_flash_workaround.disk_sbd);
+			ps3_flash_workaround.disk_open = 0;
+			ps3_flash_workaround.disk_sbd = NULL;
+		}
+	}
+
+	return 0;
+}
 
 static int ps3stor_probe_access(struct ps3_storage_device *dev)
 {
@@ -90,7 +149,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler)
 	int error, res, alignment;
 	enum ps3_dma_page_size page_size;
 
-	error = ps3_open_hv_device(&dev->sbd);
+	error = ps3stor_open_hv_device(&dev->sbd);
 	if (error) {
 		dev_err(&dev->sbd.core,
 			"%s:%u: ps3_open_hv_device failed %d\n", __func__,
@@ -166,7 +225,7 @@ fail_free_irq:
 fail_sb_event_receive_port_destroy:
 	ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq);
 fail_close_device:
-	ps3_close_hv_device(&dev->sbd);
+	ps3stor_close_hv_device(&dev->sbd);
 fail:
 	return error;
 }
@@ -193,7 +252,7 @@ void ps3stor_teardown(struct ps3_storage_device *dev)
 			"%s:%u: destroy event receive port failed %d\n",
 			__func__, __LINE__, error);
 
-	error = ps3_close_hv_device(&dev->sbd);
+	error = ps3stor_close_hv_device(&dev->sbd);
 	if (error)
 		dev_err(&dev->sbd.core,
 			"%s:%u: ps3_close_hv_device failed %d\n", __func__,
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index f431779..2dc42bb 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -82,6 +82,13 @@ config REGULATOR_TWL4030
 	  This driver supports the voltage regulators provided by
 	  this family of companion chips.
 
+config REGULATOR_WM831X
+	tristate "Wolfson Microelcronics WM831x PMIC regulators"
+	depends on MFD_WM831X
+	help
+	  Support the voltage and current regulators of the WM831x series
+	  of PMIC devices.
+
 config REGULATOR_WM8350
 	tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
 	depends on MFD_WM8350
@@ -117,4 +124,28 @@ config REGULATOR_LP3971
 	 Say Y here to support the voltage regulators and convertors
 	 on National Semiconductors LP3971 PMIC
 
+config REGULATOR_PCAP
+	tristate "PCAP2 regulator driver"
+	depends on EZX_PCAP
+	help
+	 This driver provides support for the voltage regulators of the
+	 PCAP2 PMIC.
+
+config REGULATOR_MC13783
+	tristate "Support regulators on Freescale MC13783 PMIC"
+	depends on MFD_MC13783
+	help
+	  Say y here to support the regulators found on the Freescale MC13783
+	  PMIC.
+
+config REGULATOR_AB3100
+	tristate "ST-Ericsson AB3100 Regulator functions"
+	depends on AB3100_CORE
+	default y if AB3100_CORE
+	help
+	 These regulators correspond to functionality in the
+	 AB3100 analog baseband dealing with power regulators
+	 for the system.
+
 endif
+
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 4d762c4..768b331 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -12,9 +12,15 @@ obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
+obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
+obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
+obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_DA903X)	+= da903x.o
 obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
+obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
+obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o
+obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
 
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
new file mode 100644
index 0000000..49aeee8
--- /dev/null
+++ b/drivers/regulator/ab3100.c
@@ -0,0 +1,700 @@
+/*
+ * drivers/regulator/ab3100.c
+ *
+ * Copyright (C) 2008-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Low-level control of the AB3100 IC Low Dropout (LDO)
+ * regulators, external regulator and buck converter
+ * Author: Mattias Wallin <mattias.wallin@stericsson.com>
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/mfd/ab3100.h>
+
+/* LDO registers and some handy masking definitions for AB3100 */
+#define AB3100_LDO_A		0x40
+#define AB3100_LDO_C		0x41
+#define AB3100_LDO_D		0x42
+#define AB3100_LDO_E		0x43
+#define AB3100_LDO_E_SLEEP	0x44
+#define AB3100_LDO_F		0x45
+#define AB3100_LDO_G		0x46
+#define AB3100_LDO_H		0x47
+#define AB3100_LDO_H_SLEEP_MODE	0
+#define AB3100_LDO_H_SLEEP_EN	2
+#define AB3100_LDO_ON		4
+#define AB3100_LDO_H_VSEL_AC	5
+#define AB3100_LDO_K		0x48
+#define AB3100_LDO_EXT		0x49
+#define AB3100_BUCK		0x4A
+#define AB3100_BUCK_SLEEP	0x4B
+#define AB3100_REG_ON_MASK	0x10
+
+/**
+ * struct ab3100_regulator
+ * A struct passed around the individual regulator functions
+ * @platform_device: platform device holding this regulator
+ * @ab3100: handle to the AB3100 parent chip
+ * @plfdata: AB3100 platform data passed in at probe time
+ * @regreg: regulator register number in the AB3100
+ * @fixed_voltage: a fixed voltage for this regulator, if this
+ *          0 the voltages array is used instead.
+ * @typ_voltages: an array of available typical voltages for
+ *          this regulator
+ * @voltages_len: length of the array of available voltages
+ */
+struct ab3100_regulator {
+	struct regulator_dev *rdev;
+	struct ab3100 *ab3100;
+	struct ab3100_platform_data *plfdata;
+	u8 regreg;
+	int fixed_voltage;
+	int const *typ_voltages;
+	u8 voltages_len;
+};
+
+/* The order in which registers are initialized */
+static const u8 ab3100_reg_init_order[AB3100_NUM_REGULATORS+2] = {
+	AB3100_LDO_A,
+	AB3100_LDO_C,
+	AB3100_LDO_E,
+	AB3100_LDO_E_SLEEP,
+	AB3100_LDO_F,
+	AB3100_LDO_G,
+	AB3100_LDO_H,
+	AB3100_LDO_K,
+	AB3100_LDO_EXT,
+	AB3100_BUCK,
+	AB3100_BUCK_SLEEP,
+	AB3100_LDO_D,
+};
+
+/* Preset (hardware defined) voltages for these regulators */
+#define LDO_A_VOLTAGE 2750000
+#define LDO_C_VOLTAGE 2650000
+#define LDO_D_VOLTAGE 2650000
+
+static const int const ldo_e_buck_typ_voltages[] = {
+	1800000,
+	1400000,
+	1300000,
+	1200000,
+	1100000,
+	1050000,
+	900000,
+};
+
+static const int const ldo_f_typ_voltages[] = {
+	1800000,
+	1400000,
+	1300000,
+	1200000,
+	1100000,
+	1050000,
+	2500000,
+	2650000,
+};
+
+static const int const ldo_g_typ_voltages[] = {
+	2850000,
+	2750000,
+	1800000,
+	1500000,
+};
+
+static const int const ldo_h_typ_voltages[] = {
+	2750000,
+	1800000,
+	1500000,
+	1200000,
+};
+
+static const int const ldo_k_typ_voltages[] = {
+	2750000,
+	1800000,
+};
+
+
+/* The regulator devices */
+static struct ab3100_regulator
+ab3100_regulators[AB3100_NUM_REGULATORS] = {
+	{
+		.regreg = AB3100_LDO_A,
+		.fixed_voltage = LDO_A_VOLTAGE,
+	},
+	{
+		.regreg = AB3100_LDO_C,
+		.fixed_voltage = LDO_C_VOLTAGE,
+	},
+	{
+		.regreg = AB3100_LDO_D,
+		.fixed_voltage = LDO_D_VOLTAGE,
+	},
+	{
+		.regreg = AB3100_LDO_E,
+		.typ_voltages = ldo_e_buck_typ_voltages,
+		.voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages),
+	},
+	{
+		.regreg = AB3100_LDO_F,
+		.typ_voltages = ldo_f_typ_voltages,
+		.voltages_len = ARRAY_SIZE(ldo_f_typ_voltages),
+	},
+	{
+		.regreg = AB3100_LDO_G,
+		.typ_voltages = ldo_g_typ_voltages,
+		.voltages_len = ARRAY_SIZE(ldo_g_typ_voltages),
+	},
+	{
+		.regreg = AB3100_LDO_H,
+		.typ_voltages = ldo_h_typ_voltages,
+		.voltages_len = ARRAY_SIZE(ldo_h_typ_voltages),
+	},
+	{
+		.regreg = AB3100_LDO_K,
+		.typ_voltages = ldo_k_typ_voltages,
+		.voltages_len = ARRAY_SIZE(ldo_k_typ_voltages),
+	},
+	{
+		.regreg = AB3100_LDO_EXT,
+		/* No voltages for the external regulator */
+	},
+	{
+		.regreg = AB3100_BUCK,
+		.typ_voltages = ldo_e_buck_typ_voltages,
+		.voltages_len = ARRAY_SIZE(ldo_e_buck_typ_voltages),
+	},
+};
+
+/*
+ * General functions for enable, disable and is_enabled used for
+ * LDO: A,C,E,F,G,H,K,EXT and BUCK
+ */
+static int ab3100_enable_regulator(struct regulator_dev *reg)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+	int err;
+	u8 regval;
+
+	err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg,
+						&regval);
+	if (err) {
+		dev_warn(&reg->dev, "failed to get regid %d value\n",
+			 abreg->regreg);
+		return err;
+	}
+
+	/* The regulator is already on, no reason to go further */
+	if (regval & AB3100_REG_ON_MASK)
+		return 0;
+
+	regval |= AB3100_REG_ON_MASK;
+
+	err = ab3100_set_register_interruptible(abreg->ab3100, abreg->regreg,
+						regval);
+	if (err) {
+		dev_warn(&reg->dev, "failed to set regid %d value\n",
+			 abreg->regreg);
+		return err;
+	}
+
+	/* Per-regulator power on delay from spec */
+	switch (abreg->regreg) {
+	case AB3100_LDO_A: /* Fallthrough */
+	case AB3100_LDO_C: /* Fallthrough */
+	case AB3100_LDO_D: /* Fallthrough */
+	case AB3100_LDO_E: /* Fallthrough */
+	case AB3100_LDO_H: /* Fallthrough */
+	case AB3100_LDO_K:
+		udelay(200);
+		break;
+	case AB3100_LDO_F:
+		udelay(600);
+		break;
+	case AB3100_LDO_G:
+		udelay(400);
+		break;
+	case AB3100_BUCK:
+		mdelay(1);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int ab3100_disable_regulator(struct regulator_dev *reg)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+	int err;
+	u8 regval;
+
+	/*
+	 * LDO D is a special regulator. When it is disabled, the entire
+	 * system is shut down. So this is handled specially.
+	 */
+	if (abreg->regreg == AB3100_LDO_D) {
+		int i;
+
+		dev_info(&reg->dev, "disabling LDO D - shut down system\n");
+		/*
+		 * Set regulators to default values, ignore any errors,
+		 * we're going DOWN
+		 */
+		for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
+			(void) ab3100_set_register_interruptible(abreg->ab3100,
+					ab3100_reg_init_order[i],
+					abreg->plfdata->reg_initvals[i]);
+		}
+
+		/* Setting LDO D to 0x00 cuts the power to the SoC */
+		return ab3100_set_register_interruptible(abreg->ab3100,
+							 AB3100_LDO_D, 0x00U);
+
+	}
+
+	/*
+	 * All other regulators are handled here
+	 */
+	err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg,
+						&regval);
+	if (err) {
+		dev_err(&reg->dev, "unable to get register 0x%x\n",
+			abreg->regreg);
+		return err;
+	}
+	regval &= ~AB3100_REG_ON_MASK;
+	return ab3100_set_register_interruptible(abreg->ab3100, abreg->regreg,
+						 regval);
+}
+
+static int ab3100_is_enabled_regulator(struct regulator_dev *reg)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+	u8 regval;
+	int err;
+
+	err = ab3100_get_register_interruptible(abreg->ab3100, abreg->regreg,
+						&regval);
+	if (err) {
+		dev_err(&reg->dev, "unable to get register 0x%x\n",
+			abreg->regreg);
+		return err;
+	}
+
+	return regval & AB3100_REG_ON_MASK;
+}
+
+static int ab3100_list_voltage_regulator(struct regulator_dev *reg,
+					 unsigned selector)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+
+	if (selector > abreg->voltages_len)
+		return -EINVAL;
+	return abreg->typ_voltages[selector];
+}
+
+static int ab3100_get_voltage_regulator(struct regulator_dev *reg)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+	u8 regval;
+	int err;
+
+	/* Return the voltage for fixed regulators immediately */
+	if (abreg->fixed_voltage)
+		return abreg->fixed_voltage;
+
+	/*
+	 * For variable types, read out setting and index into
+	 * supplied voltage list.
+	 */
+	err = ab3100_get_register_interruptible(abreg->ab3100,
+						abreg->regreg, &regval);
+	if (err) {
+		dev_warn(&reg->dev,
+			 "failed to get regulator value in register %02x\n",
+			 abreg->regreg);
+		return err;
+	}
+
+	/* The 3 highest bits index voltages */
+	regval &= 0xE0;
+	regval >>= 5;
+
+	if (regval > abreg->voltages_len) {
+		dev_err(&reg->dev,
+			"regulator register %02x contains an illegal voltage setting\n",
+			abreg->regreg);
+		return -EINVAL;
+	}
+
+	return abreg->typ_voltages[regval];
+}
+
+static int ab3100_get_best_voltage_index(struct regulator_dev *reg,
+				   int min_uV, int max_uV)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+	int i;
+	int bestmatch;
+	int bestindex;
+
+	/*
+	 * Locate the minimum voltage fitting the criteria on
+	 * this regulator. The switchable voltages are not
+	 * in strict falling order so we need to check them
+	 * all for the best match.
+	 */
+	bestmatch = INT_MAX;
+	bestindex = -1;
+	for (i = 0; i < abreg->voltages_len; i++) {
+		if (abreg->typ_voltages[i] <= max_uV &&
+		    abreg->typ_voltages[i] >= min_uV &&
+		    abreg->typ_voltages[i] < bestmatch) {
+			bestmatch = abreg->typ_voltages[i];
+			bestindex = i;
+		}
+	}
+
+	if (bestindex < 0) {
+		dev_warn(&reg->dev, "requested %d<=x<=%d uV, out of range!\n",
+			 min_uV, max_uV);
+		return -EINVAL;
+	}
+	return bestindex;
+}
+
+static int ab3100_set_voltage_regulator(struct regulator_dev *reg,
+					int min_uV, int max_uV)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+	u8 regval;
+	int err;
+	int bestindex;
+
+	bestindex = ab3100_get_best_voltage_index(reg, min_uV, max_uV);
+	if (bestindex < 0)
+		return bestindex;
+
+	err = ab3100_get_register_interruptible(abreg->ab3100,
+						abreg->regreg, &regval);
+	if (err) {
+		dev_warn(&reg->dev,
+			 "failed to get regulator register %02x\n",
+			 abreg->regreg);
+		return err;
+	}
+
+	/* The highest three bits control the variable regulators */
+	regval &= ~0xE0;
+	regval |= (bestindex << 5);
+
+	err = ab3100_set_register_interruptible(abreg->ab3100,
+						abreg->regreg, regval);
+	if (err)
+		dev_warn(&reg->dev, "failed to set regulator register %02x\n",
+			abreg->regreg);
+
+	return err;
+}
+
+static int ab3100_set_suspend_voltage_regulator(struct regulator_dev *reg,
+						int uV)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+	u8 regval;
+	int err;
+	int bestindex;
+	u8 targetreg;
+
+	if (abreg->regreg == AB3100_LDO_E)
+		targetreg = AB3100_LDO_E_SLEEP;
+	else if (abreg->regreg == AB3100_BUCK)
+		targetreg = AB3100_BUCK_SLEEP;
+	else
+		return -EINVAL;
+
+	/* LDO E and BUCK have special suspend voltages you can set */
+	bestindex = ab3100_get_best_voltage_index(reg, uV, uV);
+
+	err = ab3100_get_register_interruptible(abreg->ab3100,
+						targetreg, &regval);
+	if (err) {
+		dev_warn(&reg->dev,
+			 "failed to get regulator register %02x\n",
+			 targetreg);
+		return err;
+	}
+
+	/* The highest three bits control the variable regulators */
+	regval &= ~0xE0;
+	regval |= (bestindex << 5);
+
+	err = ab3100_set_register_interruptible(abreg->ab3100,
+						targetreg, regval);
+	if (err)
+		dev_warn(&reg->dev, "failed to set regulator register %02x\n",
+			abreg->regreg);
+
+	return err;
+}
+
+/*
+ * The external regulator can just define a fixed voltage.
+ */
+static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
+{
+	struct ab3100_regulator *abreg = reg->reg_data;
+
+	return abreg->plfdata->external_voltage;
+}
+
+static struct regulator_ops regulator_ops_fixed = {
+	.enable      = ab3100_enable_regulator,
+	.disable     = ab3100_disable_regulator,
+	.is_enabled  = ab3100_is_enabled_regulator,
+	.get_voltage = ab3100_get_voltage_regulator,
+};
+
+static struct regulator_ops regulator_ops_variable = {
+	.enable      = ab3100_enable_regulator,
+	.disable     = ab3100_disable_regulator,
+	.is_enabled  = ab3100_is_enabled_regulator,
+	.get_voltage = ab3100_get_voltage_regulator,
+	.set_voltage = ab3100_set_voltage_regulator,
+	.list_voltage = ab3100_list_voltage_regulator,
+};
+
+static struct regulator_ops regulator_ops_variable_sleepable = {
+	.enable      = ab3100_enable_regulator,
+	.disable     = ab3100_disable_regulator,
+	.is_enabled  = ab3100_is_enabled_regulator,
+	.get_voltage = ab3100_get_voltage_regulator,
+	.set_voltage = ab3100_set_voltage_regulator,
+	.set_suspend_voltage = ab3100_set_suspend_voltage_regulator,
+	.list_voltage = ab3100_list_voltage_regulator,
+};
+
+/*
+ * LDO EXT is an external regulator so it is really
+ * not possible to set any voltage locally here, AB3100
+ * is an on/off switch plain an simple. The external
+ * voltage is defined in the board set-up if any.
+ */
+static struct regulator_ops regulator_ops_external = {
+	.enable      = ab3100_enable_regulator,
+	.disable     = ab3100_disable_regulator,
+	.is_enabled  = ab3100_is_enabled_regulator,
+	.get_voltage = ab3100_get_voltage_regulator_external,
+};
+
+static struct regulator_desc
+ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
+	{
+		.name = "LDO_A",
+		.id   = AB3100_LDO_A,
+		.ops  = &regulator_ops_fixed,
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_C",
+		.id   = AB3100_LDO_C,
+		.ops  = &regulator_ops_fixed,
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_D",
+		.id   = AB3100_LDO_D,
+		.ops  = &regulator_ops_fixed,
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_E",
+		.id   = AB3100_LDO_E,
+		.ops  = &regulator_ops_variable_sleepable,
+		.n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages),
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_F",
+		.id   = AB3100_LDO_F,
+		.ops  = &regulator_ops_variable,
+		.n_voltages = ARRAY_SIZE(ldo_f_typ_voltages),
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_G",
+		.id   = AB3100_LDO_G,
+		.ops  = &regulator_ops_variable,
+		.n_voltages = ARRAY_SIZE(ldo_g_typ_voltages),
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_H",
+		.id   = AB3100_LDO_H,
+		.ops  = &regulator_ops_variable,
+		.n_voltages = ARRAY_SIZE(ldo_h_typ_voltages),
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_K",
+		.id   = AB3100_LDO_K,
+		.ops  = &regulator_ops_variable,
+		.n_voltages = ARRAY_SIZE(ldo_k_typ_voltages),
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "LDO_EXT",
+		.id   = AB3100_LDO_EXT,
+		.ops  = &regulator_ops_external,
+		.type = REGULATOR_VOLTAGE,
+	},
+	{
+		.name = "BUCK",
+		.id   = AB3100_BUCK,
+		.ops  = &regulator_ops_variable_sleepable,
+		.n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages),
+		.type = REGULATOR_VOLTAGE,
+	},
+};
+
+/*
+ * NOTE: the following functions are regulators pluralis - it is the
+ * binding to the AB3100 core driver and the parent platform device
+ * for all the different regulators.
+ */
+
+static int __init ab3100_regulators_probe(struct platform_device *pdev)
+{
+	struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
+	struct ab3100 *ab3100 = platform_get_drvdata(pdev);
+	int err = 0;
+	u8 data;
+	int i;
+
+	/* Check chip state */
+	err = ab3100_get_register_interruptible(ab3100,
+						AB3100_LDO_D, &data);
+	if (err) {
+		dev_err(&pdev->dev, "could not read initial status of LDO_D\n");
+		return err;
+	}
+	if (data & 0x10)
+		dev_notice(&pdev->dev,
+			   "chip is already in active mode (Warm start)\n");
+	else
+		dev_notice(&pdev->dev,
+			   "chip is in inactive mode (Cold start)\n");
+
+	/* Set up regulators */
+	for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
+		err = ab3100_set_register_interruptible(ab3100,
+					ab3100_reg_init_order[i],
+					plfdata->reg_initvals[i]);
+		if (err) {
+			dev_err(&pdev->dev, "regulator initialization failed with error %d\n",
+				err);
+			return err;
+		}
+	}
+
+	if (err) {
+		dev_err(&pdev->dev,
+			"LDO D regulator initialization failed with error %d\n",
+			err);
+		return err;
+	}
+
+	/* Register the regulators */
+	for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
+		struct ab3100_regulator *reg = &ab3100_regulators[i];
+		struct regulator_dev *rdev;
+
+		/*
+		 * Initialize per-regulator struct.
+		 * Inherit platform data, this comes down from the
+		 * i2c boarddata, from the machine. So if you want to
+		 * see what it looks like for a certain machine, go
+		 * into the machine I2C setup.
+		 */
+		reg->ab3100 = ab3100;
+		reg->plfdata = plfdata;
+
+		/*
+		 * Register the regulator, pass around
+		 * the ab3100_regulator struct
+		 */
+		rdev = regulator_register(&ab3100_regulator_desc[i],
+					  &pdev->dev,
+					  &plfdata->reg_constraints[i],
+					  reg);
+
+		if (IS_ERR(rdev)) {
+			err = PTR_ERR(rdev);
+			dev_err(&pdev->dev,
+				"%s: failed to register regulator %s err %d\n",
+				__func__, ab3100_regulator_desc[i].name,
+				err);
+			i--;
+			/* remove the already registered regulators */
+			while (i > 0) {
+				regulator_unregister(ab3100_regulators[i].rdev);
+				i--;
+			}
+			return err;
+		}
+
+		/* Then set a pointer back to the registered regulator */
+		reg->rdev = rdev;
+	}
+
+	return 0;
+}
+
+static int __exit ab3100_regulators_remove(struct platform_device *pdev)
+{
+	int i;
+
+	for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
+		struct ab3100_regulator *reg = &ab3100_regulators[i];
+
+		regulator_unregister(reg->rdev);
+	}
+	return 0;
+}
+
+static struct platform_driver ab3100_regulators_driver = {
+	.driver = {
+		.name  = "ab3100-regulators",
+		.owner = THIS_MODULE,
+	},
+	.probe = ab3100_regulators_probe,
+	.remove = __exit_p(ab3100_regulators_remove),
+};
+
+static __init int ab3100_regulators_init(void)
+{
+	return platform_driver_register(&ab3100_regulators_driver);
+}
+
+static __exit void ab3100_regulators_exit(void)
+{
+	platform_driver_register(&ab3100_regulators_driver);
+}
+
+subsys_initcall(ab3100_regulators_init);
+module_exit(ab3100_regulators_exit);
+
+MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
+MODULE_DESCRIPTION("AB3100 Regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ab3100-regulators");
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 98c3a74..91ba9bf 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1864,6 +1864,30 @@ int regulator_notifier_call_chain(struct regulator_dev *rdev,
 }
 EXPORT_SYMBOL_GPL(regulator_notifier_call_chain);
 
+/**
+ * regulator_mode_to_status - convert a regulator mode into a status
+ *
+ * @mode: Mode to convert
+ *
+ * Convert a regulator mode into a status.
+ */
+int regulator_mode_to_status(unsigned int mode)
+{
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		return REGULATOR_STATUS_FAST;
+	case REGULATOR_MODE_NORMAL:
+		return REGULATOR_STATUS_NORMAL;
+	case REGULATOR_MODE_IDLE:
+		return REGULATOR_STATUS_IDLE;
+	case REGULATOR_STATUS_STANDBY:
+		return REGULATOR_STATUS_STANDBY;
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(regulator_mode_to_status);
+
 /*
  * To avoid cluttering sysfs (and memory) with useless state, only
  * create attributes that can be meaningfully displayed.
diff --git a/drivers/regulator/mc13783.c b/drivers/regulator/mc13783.c
new file mode 100644
index 0000000..710211f
--- /dev/null
+++ b/drivers/regulator/mc13783.c
@@ -0,0 +1,410 @@
+/*
+ * Regulator Driver for Freescale MC13783 PMIC
+ *
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ *
+ * 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/mfd/mc13783-private.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/driver.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+struct mc13783_regulator {
+	struct regulator_desc desc;
+	int reg;
+	int enable_bit;
+};
+
+static struct regulator_ops mc13783_regulator_ops;
+
+static struct mc13783_regulator mc13783_regulators[] = {
+	[MC13783_SW_SW3] = {
+		.desc = {
+			.name	= "SW_SW3",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_SW_SW3,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_SWITCHERS_5,
+		.enable_bit = MC13783_SWCTRL_SW3_EN,
+	},
+	[MC13783_SW_PLL] = {
+		.desc = {
+			.name	= "SW_PLL",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_SW_PLL,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_SWITCHERS_4,
+		.enable_bit = MC13783_SWCTRL_PLL_EN,
+	},
+	[MC13783_REGU_VAUDIO] = {
+		.desc = {
+			.name	= "REGU_VAUDIO",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VAUDIO,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VAUDIO_EN,
+	},
+	[MC13783_REGU_VIOHI] = {
+		.desc = {
+			.name	= "REGU_VIOHI",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VIOHI,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VIOHI_EN,
+	},
+	[MC13783_REGU_VIOLO] = {
+		.desc = {
+			.name	= "REGU_VIOLO",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VIOLO,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VIOLO_EN,
+	},
+	[MC13783_REGU_VDIG] = {
+		.desc = {
+			.name	= "REGU_VDIG",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VDIG,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VDIG_EN,
+	},
+	[MC13783_REGU_VGEN] = {
+		.desc = {
+			.name	= "REGU_VGEN",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VGEN,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VGEN_EN,
+	},
+	[MC13783_REGU_VRFDIG] = {
+		.desc = {
+			.name	= "REGU_VRFDIG",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VRFDIG,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VRFDIG_EN,
+	},
+	[MC13783_REGU_VRFREF] = {
+		.desc = {
+			.name	= "REGU_VRFREF",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VRFREF,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VRFREF_EN,
+	},
+	[MC13783_REGU_VRFCP] = {
+		.desc = {
+			.name	= "REGU_VRFCP",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VRFCP,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_0,
+		.enable_bit = MC13783_REGCTRL_VRFCP_EN,
+	},
+	[MC13783_REGU_VSIM] = {
+		.desc = {
+			.name	= "REGU_VSIM",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VSIM,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VSIM_EN,
+	},
+	[MC13783_REGU_VESIM] = {
+		.desc = {
+			.name	= "REGU_VESIM",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VESIM,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VESIM_EN,
+	},
+	[MC13783_REGU_VCAM] = {
+		.desc = {
+			.name	= "REGU_VCAM",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VCAM,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VCAM_EN,
+	},
+	[MC13783_REGU_VRFBG] = {
+		.desc = {
+			.name	= "REGU_VRFBG",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VRFBG,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VRFBG_EN,
+	},
+	[MC13783_REGU_VVIB] = {
+		.desc = {
+			.name	= "REGU_VVIB",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VVIB,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VVIB_EN,
+	},
+	[MC13783_REGU_VRF1] = {
+		.desc = {
+			.name	= "REGU_VRF1",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VRF1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VRF1_EN,
+	},
+	[MC13783_REGU_VRF2] = {
+		.desc = {
+			.name	= "REGU_VRF2",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VRF2,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VRF2_EN,
+	},
+	[MC13783_REGU_VMMC1] = {
+		.desc = {
+			.name	= "REGU_VMMC1",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VMMC1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VMMC1_EN,
+	},
+	[MC13783_REGU_VMMC2] = {
+		.desc = {
+			.name	= "REGU_VMMC2",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_VMMC2,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_REGULATOR_MODE_1,
+		.enable_bit = MC13783_REGCTRL_VMMC2_EN,
+	},
+	[MC13783_REGU_GPO1] = {
+		.desc = {
+			.name	= "REGU_GPO1",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_GPO1,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO1_EN,
+	},
+	[MC13783_REGU_GPO2] = {
+		.desc = {
+			.name	= "REGU_GPO2",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_GPO2,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO2_EN,
+	},
+	[MC13783_REGU_GPO3] = {
+		.desc = {
+			.name	= "REGU_GPO3",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_GPO3,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO3_EN,
+	},
+	[MC13783_REGU_GPO4] = {
+		.desc = {
+			.name	= "REGU_GPO4",
+			.ops	= &mc13783_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.id	= MC13783_REGU_GPO4,
+			.owner	= THIS_MODULE,
+		},
+		.reg = MC13783_REG_POWER_MISCELLANEOUS,
+		.enable_bit = MC13783_REGCTRL_GPO4_EN,
+	},
+};
+
+struct mc13783_priv {
+	struct regulator_desc desc[ARRAY_SIZE(mc13783_regulators)];
+	struct mc13783 *mc13783;
+	struct regulator_dev *regulators[0];
+};
+
+static int mc13783_enable(struct regulator_dev *rdev)
+{
+	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
+			mc13783_regulators[id].enable_bit,
+			mc13783_regulators[id].enable_bit);
+}
+
+static int mc13783_disable(struct regulator_dev *rdev)
+{
+	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+	int id = rdev_get_id(rdev);
+
+	dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
+
+	return mc13783_set_bits(priv->mc13783, mc13783_regulators[id].reg,
+			mc13783_regulators[id].enable_bit, 0);
+}
+
+static int mc13783_is_enabled(struct regulator_dev *rdev)
+{
+	struct mc13783_priv *priv = rdev_get_drvdata(rdev);
+	int ret, id = rdev_get_id(rdev);
+	unsigned int val;
+
+	ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
+	if (ret)
+		return ret;
+
+	return (val & mc13783_regulators[id].enable_bit) != 0;
+}
+
+static struct regulator_ops mc13783_regulator_ops = {
+	.enable		= mc13783_enable,
+	.disable	= mc13783_disable,
+	.is_enabled	= mc13783_is_enabled,
+};
+
+static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
+{
+	struct mc13783_priv *priv;
+	struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent);
+	struct mc13783_regulator_init_data *init_data;
+	int i, ret;
+
+	dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id);
+
+	priv = kzalloc(sizeof(*priv) + mc13783->num_regulators * sizeof(void *),
+			GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->mc13783 = mc13783;
+
+	for (i = 0; i < mc13783->num_regulators; i++) {
+		init_data = &mc13783->regulators[i];
+		priv->regulators[i] = regulator_register(
+				&mc13783_regulators[init_data->id].desc,
+				&pdev->dev, init_data->init_data, priv);
+
+		if (IS_ERR(priv->regulators[i])) {
+			dev_err(&pdev->dev, "failed to register regulator %s\n",
+				mc13783_regulators[i].desc.name);
+			ret = PTR_ERR(priv->regulators[i]);
+			goto err;
+		}
+	}
+
+	platform_set_drvdata(pdev, priv);
+
+	return 0;
+err:
+	while (--i >= 0)
+		regulator_unregister(priv->regulators[i]);
+
+	kfree(priv);
+
+	return ret;
+}
+
+static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
+{
+	struct mc13783_priv *priv = platform_get_drvdata(pdev);
+	struct mc13783 *mc13783 = priv->mc13783;
+	int i;
+
+	for (i = 0; i < mc13783->num_regulators; i++)
+		regulator_unregister(priv->regulators[i]);
+
+	return 0;
+}
+
+static struct platform_driver mc13783_regulator_driver = {
+	.driver	= {
+		.name	= "mc13783-regulator",
+		.owner	= THIS_MODULE,
+	},
+	.remove		= __devexit_p(mc13783_regulator_remove),
+};
+
+static int __init mc13783_regulator_init(void)
+{
+	return platform_driver_probe(&mc13783_regulator_driver,
+			mc13783_regulator_probe);
+}
+subsys_initcall(mc13783_regulator_init);
+
+static void __exit mc13783_regulator_exit(void)
+{
+	platform_driver_unregister(&mc13783_regulator_driver);
+}
+module_exit(mc13783_regulator_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
+MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC");
+MODULE_ALIAS("platform:mc13783-regulator");
diff --git a/drivers/regulator/pcap-regulator.c b/drivers/regulator/pcap-regulator.c
new file mode 100644
index 0000000..33d7d89
--- /dev/null
+++ b/drivers/regulator/pcap-regulator.c
@@ -0,0 +1,318 @@
+/*
+ * PCAP2 Regulator Driver
+ *
+ * Copyright (c) 2009 Daniel Ribeiro <drwyrm@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.
+ */
+
+#include <linux/kernel.h>
+#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/mfd/ezx-pcap.h>
+
+static const u16 V1_table[] = {
+	2775, 1275, 1600, 1725, 1825, 1925, 2075, 2275,
+};
+
+static const u16 V2_table[] = {
+	2500, 2775,
+};
+
+static const u16 V3_table[] = {
+	1075, 1275, 1550, 1725, 1876, 1950, 2075, 2275,
+};
+
+static const u16 V4_table[] = {
+	1275, 1550, 1725, 1875, 1950, 2075, 2275, 2775,
+};
+
+static const u16 V5_table[] = {
+	1875, 2275, 2475, 2775,
+};
+
+static const u16 V6_table[] = {
+	2475, 2775,
+};
+
+static const u16 V7_table[] = {
+	1875, 2775,
+};
+
+#define V8_table V4_table
+
+static const u16 V9_table[] = {
+	1575, 1875, 2475, 2775,
+};
+
+static const u16 V10_table[] = {
+	5000,
+};
+
+static const u16 VAUX1_table[] = {
+	1875, 2475, 2775, 3000,
+};
+
+#define VAUX2_table VAUX1_table
+
+static const u16 VAUX3_table[] = {
+	1200, 1200, 1200, 1200, 1400, 1600, 1800, 2000,
+	2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600,
+};
+
+static const u16 VAUX4_table[] = {
+	1800, 1800, 3000, 5000,
+};
+
+static const u16 VSIM_table[] = {
+	1875, 3000,
+};
+
+static const u16 VSIM2_table[] = {
+	1875,
+};
+
+static const u16 VVIB_table[] = {
+	1300, 1800, 2000, 3000,
+};
+
+static const u16 SW1_table[] = {
+	900, 950, 1000, 1050, 1100, 1150, 1200, 1250,
+	1300, 1350, 1400, 1450, 1500, 1600, 1875, 2250,
+};
+
+#define SW2_table SW1_table
+
+static const u16 SW3_table[] = {
+	4000, 4500, 5000, 5500,
+};
+
+struct pcap_regulator {
+	const u8 reg;
+	const u8 en;
+	const u8 index;
+	const u8 stby;
+	const u8 lowpwr;
+	const u8 n_voltages;
+	const u16 *voltage_table;
+};
+
+#define NA 0xff
+
+#define VREG_INFO(_vreg, _reg, _en, _index, _stby, _lowpwr)		\
+	[_vreg]	= {							\
+		.reg		= _reg,					\
+		.en		= _en,					\
+		.index		= _index,				\
+		.stby		= _stby,				\
+		.lowpwr		= _lowpwr,				\
+		.n_voltages	= ARRAY_SIZE(_vreg##_table),		\
+		.voltage_table	= _vreg##_table,			\
+	}
+
+static struct pcap_regulator vreg_table[] = {
+	VREG_INFO(V1,    PCAP_REG_VREG1,   1,  2,  18, 0),
+	VREG_INFO(V2,    PCAP_REG_VREG1,   5,  6,  19, 22),
+	VREG_INFO(V3,    PCAP_REG_VREG1,   7,  8,  20, 23),
+	VREG_INFO(V4,    PCAP_REG_VREG1,   11, 12, 21, 24),
+	/* V5 STBY and LOWPWR are on PCAP_REG_VREG2 */
+	VREG_INFO(V5,    PCAP_REG_VREG1,   15, 16, 12, 19),
+
+	VREG_INFO(V6,    PCAP_REG_VREG2,   1,  2,  14, 20),
+	VREG_INFO(V7,    PCAP_REG_VREG2,   3,  4,  15, 21),
+	VREG_INFO(V8,    PCAP_REG_VREG2,   5,  6,  16, 22),
+	VREG_INFO(V9,    PCAP_REG_VREG2,   9,  10, 17, 23),
+	VREG_INFO(V10,   PCAP_REG_VREG2,   10, NA, 18, 24),
+
+	VREG_INFO(VAUX1, PCAP_REG_AUXVREG, 1,  2,  22, 23),
+	/* VAUX2 ... VSIM2 STBY and LOWPWR are on PCAP_REG_LOWPWR */
+	VREG_INFO(VAUX2, PCAP_REG_AUXVREG, 4,  5,  0,  1),
+	VREG_INFO(VAUX3, PCAP_REG_AUXVREG, 7,  8,  2,  3),
+	VREG_INFO(VAUX4, PCAP_REG_AUXVREG, 12, 13, 4,  5),
+	VREG_INFO(VSIM,  PCAP_REG_AUXVREG, 17, 18, NA, 6),
+	VREG_INFO(VSIM2, PCAP_REG_AUXVREG, 16, NA, NA, 7),
+	VREG_INFO(VVIB,  PCAP_REG_AUXVREG, 19, 20, NA, NA),
+
+	VREG_INFO(SW1,   PCAP_REG_SWCTRL,  1,  2,  NA, NA),
+	VREG_INFO(SW2,   PCAP_REG_SWCTRL,  6,  7,  NA, NA),
+	/* SW3 STBY is on PCAP_REG_AUXVREG */
+	VREG_INFO(SW3,   PCAP_REG_SWCTRL,  11, 12, 24, NA),
+
+	/* SWxS used to control SWx voltage on standby */
+/*	VREG_INFO(SW1S,  PCAP_REG_LOWPWR,  NA, 12, NA, NA),
+	VREG_INFO(SW2S,  PCAP_REG_LOWPWR,  NA, 20, NA, NA), */
+};
+
+static int pcap_regulator_set_voltage(struct regulator_dev *rdev,
+						int min_uV, int max_uV)
+{
+	struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
+	void *pcap = rdev_get_drvdata(rdev);
+	int uV;
+	u8 i;
+
+	/* the regulator doesn't support voltage switching */
+	if (vreg->n_voltages == 1)
+		return -EINVAL;
+
+	for (i = 0; i < vreg->n_voltages; i++) {
+		/* For V1 the first is not the best match */
+		if (i == 0 && rdev_get_id(rdev) == V1)
+			i = 1;
+		else if (i + 1 == vreg->n_voltages && rdev_get_id(rdev) == V1)
+			i = 0;
+
+		uV = vreg->voltage_table[i] * 1000;
+		if (min_uV <= uV && uV <= max_uV)
+			return ezx_pcap_set_bits(pcap, vreg->reg,
+					(vreg->n_voltages - 1) << vreg->index,
+					i << vreg->index);
+
+		if (i == 0 && rdev_get_id(rdev) == V1)
+			i = vreg->n_voltages - 1;
+	}
+
+	/* the requested voltage range is not supported by this regulator */
+	return -EINVAL;
+}
+
+static int pcap_regulator_get_voltage(struct regulator_dev *rdev)
+{
+	struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
+	void *pcap = rdev_get_drvdata(rdev);
+	u32 tmp;
+	int mV;
+
+	if (vreg->n_voltages == 1)
+		return vreg->voltage_table[0] * 1000;
+
+	ezx_pcap_read(pcap, vreg->reg, &tmp);
+	tmp = ((tmp >> vreg->index) & (vreg->n_voltages - 1));
+	mV = vreg->voltage_table[tmp];
+
+	return mV * 1000;
+}
+
+static int pcap_regulator_enable(struct regulator_dev *rdev)
+{
+	struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
+	void *pcap = rdev_get_drvdata(rdev);
+
+	if (vreg->en == NA)
+		return -EINVAL;
+
+	return ezx_pcap_set_bits(pcap, vreg->reg, 1 << vreg->en, 1 << vreg->en);
+}
+
+static int pcap_regulator_disable(struct regulator_dev *rdev)
+{
+	struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
+	void *pcap = rdev_get_drvdata(rdev);
+
+	if (vreg->en == NA)
+		return -EINVAL;
+
+	return ezx_pcap_set_bits(pcap, vreg->reg, 1 << vreg->en, 0);
+}
+
+static int pcap_regulator_is_enabled(struct regulator_dev *rdev)
+{
+	struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
+	void *pcap = rdev_get_drvdata(rdev);
+	u32 tmp;
+
+	if (vreg->en == NA)
+		return -EINVAL;
+
+	ezx_pcap_read(pcap, vreg->reg, &tmp);
+	return (tmp >> vreg->en) & 1;
+}
+
+static int pcap_regulator_list_voltage(struct regulator_dev *rdev,
+							unsigned int index)
+{
+	struct pcap_regulator *vreg = &vreg_table[rdev_get_id(rdev)];
+
+	return vreg->voltage_table[index] * 1000;
+}
+
+static struct regulator_ops pcap_regulator_ops = {
+	.list_voltage	= pcap_regulator_list_voltage,
+	.set_voltage	= pcap_regulator_set_voltage,
+	.get_voltage	= pcap_regulator_get_voltage,
+	.enable		= pcap_regulator_enable,
+	.disable	= pcap_regulator_disable,
+	.is_enabled	= pcap_regulator_is_enabled,
+};
+
+#define VREG(_vreg)						\
+	[_vreg]	= {						\
+		.name		= #_vreg,			\
+		.id		= _vreg,			\
+		.n_voltages	= ARRAY_SIZE(_vreg##_table),	\
+		.ops		= &pcap_regulator_ops,		\
+		.type		= REGULATOR_VOLTAGE,		\
+		.owner		= THIS_MODULE,			\
+	}
+
+static struct regulator_desc pcap_regulators[] = {
+	VREG(V1), VREG(V2), VREG(V3), VREG(V4), VREG(V5), VREG(V6), VREG(V7),
+	VREG(V8), VREG(V9), VREG(V10), VREG(VAUX1), VREG(VAUX2), VREG(VAUX3),
+	VREG(VAUX4), VREG(VSIM), VREG(VSIM2), VREG(VVIB), VREG(SW1), VREG(SW2),
+};
+
+static int __devinit pcap_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev;
+	void *pcap = dev_get_drvdata(pdev->dev.parent);
+
+	rdev = regulator_register(&pcap_regulators[pdev->id], &pdev->dev,
+				pdev->dev.platform_data, pcap);
+	if (IS_ERR(rdev))
+		return PTR_ERR(rdev);
+
+	platform_set_drvdata(pdev, rdev);
+
+	return 0;
+}
+
+static int __devexit pcap_regulator_remove(struct platform_device *pdev)
+{
+	struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+	regulator_unregister(rdev);
+
+	return 0;
+}
+
+static struct platform_driver pcap_regulator_driver = {
+	.driver = {
+		.name = "pcap-regulator",
+	},
+	.probe = pcap_regulator_probe,
+	.remove = __devexit_p(pcap_regulator_remove),
+};
+
+static int __init pcap_regulator_init(void)
+{
+	return platform_driver_register(&pcap_regulator_driver);
+}
+
+static void __exit pcap_regulator_exit(void)
+{
+	platform_driver_unregister(&pcap_regulator_driver);
+}
+
+subsys_initcall(pcap_regulator_init);
+module_exit(pcap_regulator_exit);
+
+MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>");
+MODULE_DESCRIPTION("PCAP2 Regulator Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
new file mode 100644
index 0000000..2eefc1a
--- /dev/null
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -0,0 +1,862 @@
+/*
+ * wm831x-dcdc.c  --  DC-DC buck convertor driver for the WM831x series
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/regulator.h>
+#include <linux/mfd/wm831x/pdata.h>
+
+#define WM831X_BUCKV_MAX_SELECTOR 0x68
+#define WM831X_BUCKP_MAX_SELECTOR 0x66
+
+#define WM831X_DCDC_MODE_FAST    0
+#define WM831X_DCDC_MODE_NORMAL  1
+#define WM831X_DCDC_MODE_IDLE    2
+#define WM831X_DCDC_MODE_STANDBY 3
+
+#define WM831X_DCDC_MAX_NAME 6
+
+/* Register offsets in control block */
+#define WM831X_DCDC_CONTROL_1     0
+#define WM831X_DCDC_CONTROL_2     1
+#define WM831X_DCDC_ON_CONFIG     2
+#define WM831X_DCDC_SLEEP_CONTROL 3
+
+/*
+ * Shared
+ */
+
+struct wm831x_dcdc {
+	char name[WM831X_DCDC_MAX_NAME];
+	struct regulator_desc desc;
+	int base;
+	struct wm831x *wm831x;
+	struct regulator_dev *regulator;
+};
+
+static int wm831x_dcdc_is_enabled(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+	int reg;
+
+	reg = wm831x_reg_read(wm831x, WM831X_DCDC_ENABLE);
+	if (reg < 0)
+		return reg;
+
+	if (reg & mask)
+		return 1;
+	else
+		return 0;
+}
+
+static int wm831x_dcdc_enable(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+
+	return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, mask);
+}
+
+static int wm831x_dcdc_disable(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+
+	return wm831x_set_bits(wm831x, WM831X_DCDC_ENABLE, mask, 0);
+}
+
+static unsigned int wm831x_dcdc_get_mode(struct regulator_dev *rdev)
+
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+	int val;
+
+	val = wm831x_reg_read(wm831x, reg);
+	if (val < 0)
+		return val;
+
+	val = (val & WM831X_DC1_ON_MODE_MASK) >> WM831X_DC1_ON_MODE_SHIFT;
+
+	switch (val) {
+	case WM831X_DCDC_MODE_FAST:
+		return REGULATOR_MODE_FAST;
+	case WM831X_DCDC_MODE_NORMAL:
+		return REGULATOR_MODE_NORMAL;
+	case WM831X_DCDC_MODE_STANDBY:
+		return REGULATOR_MODE_STANDBY;
+	case WM831X_DCDC_MODE_IDLE:
+		return REGULATOR_MODE_IDLE;
+	default:
+		BUG();
+	}
+}
+
+static int wm831x_dcdc_set_mode_int(struct wm831x *wm831x, int reg,
+				    unsigned int mode)
+{
+	int val;
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		val = WM831X_DCDC_MODE_FAST;
+		break;
+	case REGULATOR_MODE_NORMAL:
+		val = WM831X_DCDC_MODE_NORMAL;
+		break;
+	case REGULATOR_MODE_STANDBY:
+		val = WM831X_DCDC_MODE_STANDBY;
+		break;
+	case REGULATOR_MODE_IDLE:
+		val = WM831X_DCDC_MODE_IDLE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_MODE_MASK,
+			       val << WM831X_DC1_ON_MODE_SHIFT);
+}
+
+static int wm831x_dcdc_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+
+	return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
+}
+
+static int wm831x_dcdc_set_suspend_mode(struct regulator_dev *rdev,
+					unsigned int mode)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
+
+	return wm831x_dcdc_set_mode_int(wm831x, reg, mode);
+}
+
+static int wm831x_dcdc_get_status(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	int ret;
+
+	/* First, check for errors */
+	ret = wm831x_reg_read(wm831x, WM831X_DCDC_UV_STATUS);
+	if (ret < 0)
+		return ret;
+
+	if (ret & (1 << rdev_get_id(rdev))) {
+		dev_dbg(wm831x->dev, "DCDC%d under voltage\n",
+			rdev_get_id(rdev) + 1);
+		return REGULATOR_STATUS_ERROR;
+	}
+
+	/* DCDC1 and DCDC2 can additionally detect high voltage/current */
+	if (rdev_get_id(rdev) < 2) {
+		if (ret & (WM831X_DC1_OV_STS << rdev_get_id(rdev))) {
+			dev_dbg(wm831x->dev, "DCDC%d over voltage\n",
+				rdev_get_id(rdev) + 1);
+			return REGULATOR_STATUS_ERROR;
+		}
+
+		if (ret & (WM831X_DC1_HC_STS << rdev_get_id(rdev))) {
+			dev_dbg(wm831x->dev, "DCDC%d over current\n",
+				rdev_get_id(rdev) + 1);
+			return REGULATOR_STATUS_ERROR;
+		}
+	}
+
+	/* Is the regulator on? */
+	ret = wm831x_reg_read(wm831x, WM831X_DCDC_STATUS);
+	if (ret < 0)
+		return ret;
+	if (!(ret & (1 << rdev_get_id(rdev))))
+		return REGULATOR_STATUS_OFF;
+
+	/* TODO: When we handle hardware control modes so we can report the
+	 * current mode. */
+	return REGULATOR_STATUS_ON;
+}
+
+static irqreturn_t wm831x_dcdc_uv_irq(int irq, void *data)
+{
+	struct wm831x_dcdc *dcdc = data;
+
+	regulator_notifier_call_chain(dcdc->regulator,
+				      REGULATOR_EVENT_UNDER_VOLTAGE,
+				      NULL);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wm831x_dcdc_oc_irq(int irq, void *data)
+{
+	struct wm831x_dcdc *dcdc = data;
+
+	regulator_notifier_call_chain(dcdc->regulator,
+				      REGULATOR_EVENT_OVER_CURRENT,
+				      NULL);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * BUCKV specifics
+ */
+
+static int wm831x_buckv_list_voltage(struct regulator_dev *rdev,
+				      unsigned selector)
+{
+	if (selector <= 0x8)
+		return 600000;
+	if (selector <= WM831X_BUCKV_MAX_SELECTOR)
+		return 600000 + ((selector - 0x8) * 12500);
+	return -EINVAL;
+}
+
+static int wm831x_buckv_set_voltage_int(struct regulator_dev *rdev, int reg,
+					 int min_uV, int max_uV)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 vsel;
+
+	if (min_uV < 600000)
+		vsel = 0;
+	else if (min_uV <= 1800000)
+		vsel = ((min_uV - 600000) / 12500) + 8;
+	else
+		return -EINVAL;
+
+	if (wm831x_buckv_list_voltage(rdev, vsel) > max_uV)
+		return -EINVAL;
+
+	return wm831x_set_bits(wm831x, reg, WM831X_DC1_ON_VSEL_MASK, vsel);
+}
+
+static int wm831x_buckv_set_voltage(struct regulator_dev *rdev,
+				     int min_uV, int max_uV)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+
+	return wm831x_buckv_set_voltage_int(rdev, reg, min_uV, max_uV);
+}
+
+static int wm831x_buckv_set_suspend_voltage(struct regulator_dev *rdev,
+					     int uV)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
+
+	return wm831x_buckv_set_voltage_int(rdev, reg, uV, uV);
+}
+
+static int wm831x_buckv_get_voltage(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+	int val;
+
+	val = wm831x_reg_read(wm831x, reg);
+	if (val < 0)
+		return val;
+
+	return wm831x_buckv_list_voltage(rdev, val & WM831X_DC1_ON_VSEL_MASK);
+}
+
+/* Current limit options */
+static u16 wm831x_dcdc_ilim[] = {
+	125, 250, 375, 500, 625, 750, 875, 1000
+};
+
+static int wm831x_buckv_set_current_limit(struct regulator_dev *rdev,
+					   int min_uA, int max_uA)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(wm831x_dcdc_ilim); i++) {
+		if (max_uA <= wm831x_dcdc_ilim[i])
+			break;
+	}
+	if (i == ARRAY_SIZE(wm831x_dcdc_ilim))
+		return -EINVAL;
+
+	return wm831x_set_bits(wm831x, reg, WM831X_DC1_HC_THR_MASK, i);
+}
+
+static int wm831x_buckv_get_current_limit(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 reg = dcdc->base + WM831X_DCDC_CONTROL_2;
+	int val;
+
+	val = wm831x_reg_read(wm831x, reg);
+	if (val < 0)
+		return val;
+
+	return wm831x_dcdc_ilim[val & WM831X_DC1_HC_THR_MASK];
+}
+
+static struct regulator_ops wm831x_buckv_ops = {
+	.set_voltage = wm831x_buckv_set_voltage,
+	.get_voltage = wm831x_buckv_get_voltage,
+	.list_voltage = wm831x_buckv_list_voltage,
+	.set_suspend_voltage = wm831x_buckv_set_suspend_voltage,
+	.set_current_limit = wm831x_buckv_set_current_limit,
+	.get_current_limit = wm831x_buckv_get_current_limit,
+
+	.is_enabled = wm831x_dcdc_is_enabled,
+	.enable = wm831x_dcdc_enable,
+	.disable = wm831x_dcdc_disable,
+	.get_status = wm831x_dcdc_get_status,
+	.get_mode = wm831x_dcdc_get_mode,
+	.set_mode = wm831x_dcdc_set_mode,
+	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
+};
+
+static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
+	struct wm831x_dcdc *dcdc;
+	struct resource *res;
+	int ret, irq;
+
+	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
+
+	if (pdata == NULL || pdata->dcdc[id] == NULL)
+		return -ENODEV;
+
+	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
+	if (dcdc == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	dcdc->wm831x = wm831x;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	dcdc->base = res->start;
+
+	snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
+	dcdc->desc.name = dcdc->name;
+	dcdc->desc.id = id;
+	dcdc->desc.type = REGULATOR_VOLTAGE;
+	dcdc->desc.n_voltages = WM831X_BUCKV_MAX_SELECTOR + 1;
+	dcdc->desc.ops = &wm831x_buckv_ops;
+	dcdc->desc.owner = THIS_MODULE;
+
+	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
+					     pdata->dcdc[id], dcdc);
+	if (IS_ERR(dcdc->regulator)) {
+		ret = PTR_ERR(dcdc->regulator);
+		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	irq = platform_get_irq_byname(pdev, "UV");
+	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
+				 IRQF_TRIGGER_RISING, dcdc->name,
+				 dcdc);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
+			irq, ret);
+		goto err_regulator;
+	}
+
+	irq = platform_get_irq_byname(pdev, "HC");
+	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_oc_irq,
+				 IRQF_TRIGGER_RISING, dcdc->name,
+				 dcdc);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n",
+			irq, ret);
+		goto err_uv;
+	}
+
+	platform_set_drvdata(pdev, dcdc);
+
+	return 0;
+
+err_uv:
+	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+err_regulator:
+	regulator_unregister(dcdc->regulator);
+err:
+	kfree(dcdc);
+	return ret;
+}
+
+static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
+{
+	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+
+	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc);
+	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+	regulator_unregister(dcdc->regulator);
+	kfree(dcdc);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_buckv_driver = {
+	.probe = wm831x_buckv_probe,
+	.remove = __devexit_p(wm831x_buckv_remove),
+	.driver		= {
+		.name	= "wm831x-buckv",
+	},
+};
+
+/*
+ * BUCKP specifics
+ */
+
+static int wm831x_buckp_list_voltage(struct regulator_dev *rdev,
+				      unsigned selector)
+{
+	if (selector <= WM831X_BUCKP_MAX_SELECTOR)
+		return 850000 + (selector * 25000);
+	else
+		return -EINVAL;
+}
+
+static int wm831x_buckp_set_voltage_int(struct regulator_dev *rdev, int reg,
+					int min_uV, int max_uV)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 vsel;
+
+	if (min_uV <= 34000000)
+		vsel = (min_uV - 850000) / 25000;
+	else
+		return -EINVAL;
+
+	if (wm831x_buckp_list_voltage(rdev, vsel) > max_uV)
+		return -EINVAL;
+
+	return wm831x_set_bits(wm831x, reg, WM831X_DC3_ON_VSEL_MASK, vsel);
+}
+
+static int wm831x_buckp_set_voltage(struct regulator_dev *rdev,
+				    int min_uV, int max_uV)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+
+	return wm831x_buckp_set_voltage_int(rdev, reg, min_uV, max_uV);
+}
+
+static int wm831x_buckp_set_suspend_voltage(struct regulator_dev *rdev,
+					    int uV)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	u16 reg = dcdc->base + WM831X_DCDC_SLEEP_CONTROL;
+
+	return wm831x_buckp_set_voltage_int(rdev, reg, uV, uV);
+}
+
+static int wm831x_buckp_get_voltage(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	u16 reg = dcdc->base + WM831X_DCDC_ON_CONFIG;
+	int val;
+
+	val = wm831x_reg_read(wm831x, reg);
+	if (val < 0)
+		return val;
+
+	return wm831x_buckp_list_voltage(rdev, val & WM831X_DC3_ON_VSEL_MASK);
+}
+
+static struct regulator_ops wm831x_buckp_ops = {
+	.set_voltage = wm831x_buckp_set_voltage,
+	.get_voltage = wm831x_buckp_get_voltage,
+	.list_voltage = wm831x_buckp_list_voltage,
+	.set_suspend_voltage = wm831x_buckp_set_suspend_voltage,
+
+	.is_enabled = wm831x_dcdc_is_enabled,
+	.enable = wm831x_dcdc_enable,
+	.disable = wm831x_dcdc_disable,
+	.get_status = wm831x_dcdc_get_status,
+	.get_mode = wm831x_dcdc_get_mode,
+	.set_mode = wm831x_dcdc_set_mode,
+	.set_suspend_mode = wm831x_dcdc_set_suspend_mode,
+};
+
+static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
+	struct wm831x_dcdc *dcdc;
+	struct resource *res;
+	int ret, irq;
+
+	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
+
+	if (pdata == NULL || pdata->dcdc[id] == NULL)
+		return -ENODEV;
+
+	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
+	if (dcdc == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	dcdc->wm831x = wm831x;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	dcdc->base = res->start;
+
+	snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
+	dcdc->desc.name = dcdc->name;
+	dcdc->desc.id = id;
+	dcdc->desc.type = REGULATOR_VOLTAGE;
+	dcdc->desc.n_voltages = WM831X_BUCKP_MAX_SELECTOR + 1;
+	dcdc->desc.ops = &wm831x_buckp_ops;
+	dcdc->desc.owner = THIS_MODULE;
+
+	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
+					     pdata->dcdc[id], dcdc);
+	if (IS_ERR(dcdc->regulator)) {
+		ret = PTR_ERR(dcdc->regulator);
+		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	irq = platform_get_irq_byname(pdev, "UV");
+	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
+				 IRQF_TRIGGER_RISING, dcdc->name,
+				 dcdc);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
+			irq, ret);
+		goto err_regulator;
+	}
+
+	platform_set_drvdata(pdev, dcdc);
+
+	return 0;
+
+err_regulator:
+	regulator_unregister(dcdc->regulator);
+err:
+	kfree(dcdc);
+	return ret;
+}
+
+static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
+{
+	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+
+	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+	regulator_unregister(dcdc->regulator);
+	kfree(dcdc);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_buckp_driver = {
+	.probe = wm831x_buckp_probe,
+	.remove = __devexit_p(wm831x_buckp_remove),
+	.driver		= {
+		.name	= "wm831x-buckp",
+	},
+};
+
+/*
+ * DCDC boost convertors
+ */
+
+static int wm831x_boostp_get_status(struct regulator_dev *rdev)
+{
+	struct wm831x_dcdc *dcdc = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+	int ret;
+
+	/* First, check for errors */
+	ret = wm831x_reg_read(wm831x, WM831X_DCDC_UV_STATUS);
+	if (ret < 0)
+		return ret;
+
+	if (ret & (1 << rdev_get_id(rdev))) {
+		dev_dbg(wm831x->dev, "DCDC%d under voltage\n",
+			rdev_get_id(rdev) + 1);
+		return REGULATOR_STATUS_ERROR;
+	}
+
+	/* Is the regulator on? */
+	ret = wm831x_reg_read(wm831x, WM831X_DCDC_STATUS);
+	if (ret < 0)
+		return ret;
+	if (ret & (1 << rdev_get_id(rdev)))
+		return REGULATOR_STATUS_ON;
+	else
+		return REGULATOR_STATUS_OFF;
+}
+
+static struct regulator_ops wm831x_boostp_ops = {
+	.get_status = wm831x_boostp_get_status,
+
+	.is_enabled = wm831x_dcdc_is_enabled,
+	.enable = wm831x_dcdc_enable,
+	.disable = wm831x_dcdc_disable,
+};
+
+static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->dcdc);
+	struct wm831x_dcdc *dcdc;
+	struct resource *res;
+	int ret, irq;
+
+	dev_dbg(&pdev->dev, "Probing DCDC%d\n", id + 1);
+
+	if (pdata == NULL || pdata->dcdc[id] == NULL)
+		return -ENODEV;
+
+	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
+	if (dcdc == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	dcdc->wm831x = wm831x;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	dcdc->base = res->start;
+
+	snprintf(dcdc->name, sizeof(dcdc->name), "DCDC%d", id + 1);
+	dcdc->desc.name = dcdc->name;
+	dcdc->desc.id = id;
+	dcdc->desc.type = REGULATOR_VOLTAGE;
+	dcdc->desc.ops = &wm831x_boostp_ops;
+	dcdc->desc.owner = THIS_MODULE;
+
+	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
+					     pdata->dcdc[id], dcdc);
+	if (IS_ERR(dcdc->regulator)) {
+		ret = PTR_ERR(dcdc->regulator);
+		dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	irq = platform_get_irq_byname(pdev, "UV");
+	ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
+				 IRQF_TRIGGER_RISING, dcdc->name,
+				 dcdc);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
+			irq, ret);
+		goto err_regulator;
+	}
+
+	platform_set_drvdata(pdev, dcdc);
+
+	return 0;
+
+err_regulator:
+	regulator_unregister(dcdc->regulator);
+err:
+	kfree(dcdc);
+	return ret;
+}
+
+static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
+{
+	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
+	struct wm831x *wm831x = dcdc->wm831x;
+
+	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+	regulator_unregister(dcdc->regulator);
+	kfree(dcdc);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_boostp_driver = {
+	.probe = wm831x_boostp_probe,
+	.remove = __devexit_p(wm831x_boostp_remove),
+	.driver		= {
+		.name	= "wm831x-boostp",
+	},
+};
+
+/*
+ * External Power Enable
+ *
+ * These aren't actually DCDCs but look like them in hardware so share
+ * code.
+ */
+
+#define WM831X_EPE_BASE 6
+
+static struct regulator_ops wm831x_epe_ops = {
+	.is_enabled = wm831x_dcdc_is_enabled,
+	.enable = wm831x_dcdc_enable,
+	.disable = wm831x_dcdc_disable,
+	.get_status = wm831x_dcdc_get_status,
+};
+
+static __devinit int wm831x_epe_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->epe);
+	struct wm831x_dcdc *dcdc;
+	int ret;
+
+	dev_dbg(&pdev->dev, "Probing EPE%d\n", id + 1);
+
+	if (pdata == NULL || pdata->epe[id] == NULL)
+		return -ENODEV;
+
+	dcdc = kzalloc(sizeof(struct wm831x_dcdc), GFP_KERNEL);
+	if (dcdc == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	dcdc->wm831x = wm831x;
+
+	/* For current parts this is correct; probably need to revisit
+	 * in future.
+	 */
+	snprintf(dcdc->name, sizeof(dcdc->name), "EPE%d", id + 1);
+	dcdc->desc.name = dcdc->name;
+	dcdc->desc.id = id + WM831X_EPE_BASE; /* Offset in DCDC registers */
+	dcdc->desc.ops = &wm831x_epe_ops;
+	dcdc->desc.type = REGULATOR_VOLTAGE;
+	dcdc->desc.owner = THIS_MODULE;
+
+	dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev,
+					     pdata->epe[id], dcdc);
+	if (IS_ERR(dcdc->regulator)) {
+		ret = PTR_ERR(dcdc->regulator);
+		dev_err(wm831x->dev, "Failed to register EPE%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, dcdc);
+
+	return 0;
+
+err:
+	kfree(dcdc);
+	return ret;
+}
+
+static __devexit int wm831x_epe_remove(struct platform_device *pdev)
+{
+	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
+
+	regulator_unregister(dcdc->regulator);
+	kfree(dcdc);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_epe_driver = {
+	.probe = wm831x_epe_probe,
+	.remove = __devexit_p(wm831x_epe_remove),
+	.driver		= {
+		.name	= "wm831x-epe",
+	},
+};
+
+static int __init wm831x_dcdc_init(void)
+{
+	int ret;
+	ret = platform_driver_register(&wm831x_buckv_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x BUCKV driver: %d\n", ret);
+
+	ret = platform_driver_register(&wm831x_buckp_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x BUCKP driver: %d\n", ret);
+
+	ret = platform_driver_register(&wm831x_boostp_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x BOOST driver: %d\n", ret);
+
+	ret = platform_driver_register(&wm831x_epe_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x EPE driver: %d\n", ret);
+
+	return 0;
+}
+subsys_initcall(wm831x_dcdc_init);
+
+static void __exit wm831x_dcdc_exit(void)
+{
+	platform_driver_unregister(&wm831x_epe_driver);
+	platform_driver_unregister(&wm831x_boostp_driver);
+	platform_driver_unregister(&wm831x_buckp_driver);
+	platform_driver_unregister(&wm831x_buckv_driver);
+}
+module_exit(wm831x_dcdc_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown");
+MODULE_DESCRIPTION("WM831x DC-DC convertor driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-buckv");
+MODULE_ALIAS("platform:wm831x-buckp");
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
new file mode 100644
index 0000000..1d8d987
--- /dev/null
+++ b/drivers/regulator/wm831x-isink.c
@@ -0,0 +1,260 @@
+/*
+ * wm831x-isink.c  --  Current sink driver for the WM831x series
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/regulator.h>
+#include <linux/mfd/wm831x/pdata.h>
+
+#define WM831X_ISINK_MAX_NAME 7
+
+struct wm831x_isink {
+	char name[WM831X_ISINK_MAX_NAME];
+	struct regulator_desc desc;
+	int reg;
+	struct wm831x *wm831x;
+	struct regulator_dev *regulator;
+};
+
+static int wm831x_isink_enable(struct regulator_dev *rdev)
+{
+	struct wm831x_isink *isink = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = isink->wm831x;
+	int ret;
+
+	/* We have a two stage enable: first start the ISINK... */
+	ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA,
+			      WM831X_CS1_ENA);
+	if (ret != 0)
+		return ret;
+
+	/* ...then enable drive */
+	ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_DRIVE,
+			      WM831X_CS1_DRIVE);
+	if (ret != 0)
+		wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, 0);
+
+	return ret;
+
+}
+
+static int wm831x_isink_disable(struct regulator_dev *rdev)
+{
+	struct wm831x_isink *isink = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = isink->wm831x;
+	int ret;
+
+	ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_DRIVE, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = wm831x_set_bits(wm831x, isink->reg, WM831X_CS1_ENA, 0);
+	if (ret < 0)
+		return ret;
+
+	return ret;
+
+}
+
+static int wm831x_isink_is_enabled(struct regulator_dev *rdev)
+{
+	struct wm831x_isink *isink = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = isink->wm831x;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, isink->reg);
+	if (ret < 0)
+		return ret;
+
+	if ((ret & (WM831X_CS1_ENA | WM831X_CS1_DRIVE)) ==
+	    (WM831X_CS1_ENA | WM831X_CS1_DRIVE))
+		return 1;
+	else
+		return 0;
+}
+
+static int wm831x_isink_set_current(struct regulator_dev *rdev,
+				    int min_uA, int max_uA)
+{
+	struct wm831x_isink *isink = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = isink->wm831x;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(wm831x_isinkv_values); i++) {
+		int val = wm831x_isinkv_values[i];
+		if (min_uA >= val && val <= max_uA) {
+			ret = wm831x_set_bits(wm831x, isink->reg,
+					      WM831X_CS1_ISEL_MASK, i);
+			return ret;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int wm831x_isink_get_current(struct regulator_dev *rdev)
+{
+	struct wm831x_isink *isink = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = isink->wm831x;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, isink->reg);
+	if (ret < 0)
+		return ret;
+
+	ret &= WM831X_CS1_ISEL_MASK;
+	if (ret > WM831X_ISINK_MAX_ISEL)
+		ret = WM831X_ISINK_MAX_ISEL;
+
+	return wm831x_isinkv_values[ret];
+}
+
+static struct regulator_ops wm831x_isink_ops = {
+	.is_enabled = wm831x_isink_is_enabled,
+	.enable = wm831x_isink_enable,
+	.disable = wm831x_isink_disable,
+	.set_current_limit = wm831x_isink_set_current,
+	.get_current_limit = wm831x_isink_get_current,
+};
+
+static irqreturn_t wm831x_isink_irq(int irq, void *data)
+{
+	struct wm831x_isink *isink = data;
+
+	regulator_notifier_call_chain(isink->regulator,
+				      REGULATOR_EVENT_OVER_CURRENT,
+				      NULL);
+
+	return IRQ_HANDLED;
+}
+
+
+static __devinit int wm831x_isink_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	struct wm831x_isink *isink;
+	int id = pdev->id % ARRAY_SIZE(pdata->isink);
+	struct resource *res;
+	int ret, irq;
+
+	dev_dbg(&pdev->dev, "Probing ISINK%d\n", id + 1);
+
+	if (pdata == NULL || pdata->isink[id] == NULL)
+		return -ENODEV;
+
+	isink = kzalloc(sizeof(struct wm831x_isink), GFP_KERNEL);
+	if (isink == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	isink->reg = res->start;
+
+	/* For current parts this is correct; probably need to revisit
+	 * in future.
+	 */
+	snprintf(isink->name, sizeof(isink->name), "ISINK%d", id + 1);
+	isink->desc.name = isink->name;
+	isink->desc.id = id;
+	isink->desc.ops = &wm831x_isink_ops;
+	isink->desc.type = REGULATOR_CURRENT;
+	isink->desc.owner = THIS_MODULE;
+
+	isink->regulator = regulator_register(&isink->desc, &pdev->dev,
+					     pdata->isink[id], isink);
+	if (IS_ERR(isink->regulator)) {
+		ret = PTR_ERR(isink->regulator);
+		dev_err(wm831x->dev, "Failed to register ISINK%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	ret = wm831x_request_irq(wm831x, irq, wm831x_isink_irq,
+				 IRQF_TRIGGER_RISING, isink->name,
+				 isink);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request ISINK IRQ %d: %d\n",
+			irq, ret);
+		goto err_regulator;
+	}
+
+	platform_set_drvdata(pdev, isink);
+
+	return 0;
+
+err_regulator:
+	regulator_unregister(isink->regulator);
+err:
+	kfree(isink);
+	return ret;
+}
+
+static __devexit int wm831x_isink_remove(struct platform_device *pdev)
+{
+	struct wm831x_isink *isink = platform_get_drvdata(pdev);
+	struct wm831x *wm831x = isink->wm831x;
+
+	wm831x_free_irq(wm831x, platform_get_irq(pdev, 0), isink);
+
+	regulator_unregister(isink->regulator);
+	kfree(isink);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_isink_driver = {
+	.probe = wm831x_isink_probe,
+	.remove = __devexit_p(wm831x_isink_remove),
+	.driver		= {
+		.name	= "wm831x-isink",
+	},
+};
+
+static int __init wm831x_isink_init(void)
+{
+	int ret;
+	ret = platform_driver_register(&wm831x_isink_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x ISINK driver: %d\n", ret);
+
+	return ret;
+}
+subsys_initcall(wm831x_isink_init);
+
+static void __exit wm831x_isink_exit(void)
+{
+	platform_driver_unregister(&wm831x_isink_driver);
+}
+module_exit(wm831x_isink_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown");
+MODULE_DESCRIPTION("WM831x current sink driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-isink");
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
new file mode 100644
index 0000000..bb61aed
--- /dev/null
+++ b/drivers/regulator/wm831x-ldo.c
@@ -0,0 +1,852 @@
+/*
+ * wm831x-ldo.c  --  LDO driver for the WM831x series
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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/moduleparam.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/regulator.h>
+#include <linux/mfd/wm831x/pdata.h>
+
+#define WM831X_LDO_MAX_NAME 6
+
+#define WM831X_LDO_CONTROL       0
+#define WM831X_LDO_ON_CONTROL    1
+#define WM831X_LDO_SLEEP_CONTROL 2
+
+#define WM831X_ALIVE_LDO_ON_CONTROL    0
+#define WM831X_ALIVE_LDO_SLEEP_CONTROL 1
+
+struct wm831x_ldo {
+	char name[WM831X_LDO_MAX_NAME];
+	struct regulator_desc desc;
+	int base;
+	struct wm831x *wm831x;
+	struct regulator_dev *regulator;
+};
+
+/*
+ * Shared
+ */
+
+static int wm831x_ldo_is_enabled(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+	int reg;
+
+	reg = wm831x_reg_read(wm831x, WM831X_LDO_ENABLE);
+	if (reg < 0)
+		return reg;
+
+	if (reg & mask)
+		return 1;
+	else
+		return 0;
+}
+
+static int wm831x_ldo_enable(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+
+	return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, mask);
+}
+
+static int wm831x_ldo_disable(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+
+	return wm831x_set_bits(wm831x, WM831X_LDO_ENABLE, mask, 0);
+}
+
+static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
+{
+	struct wm831x_ldo *ldo = data;
+
+	regulator_notifier_call_chain(ldo->regulator,
+				      REGULATOR_EVENT_UNDER_VOLTAGE,
+				      NULL);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * General purpose LDOs
+ */
+
+#define WM831X_GP_LDO_SELECTOR_LOW 0xe
+#define WM831X_GP_LDO_MAX_SELECTOR 0x1f
+
+static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev,
+				      unsigned int selector)
+{
+	/* 0.9-1.6V in 50mV steps */
+	if (selector <= WM831X_GP_LDO_SELECTOR_LOW)
+		return 900000 + (selector * 50000);
+	/* 1.7-3.3V in 50mV steps */
+	if (selector <= WM831X_GP_LDO_MAX_SELECTOR)
+		return 1600000 + ((selector - WM831X_GP_LDO_SELECTOR_LOW)
+				  * 100000);
+	return -EINVAL;
+}
+
+static int wm831x_gp_ldo_set_voltage_int(struct regulator_dev *rdev, int reg,
+					 int min_uV, int max_uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int vsel, ret;
+
+	if (min_uV < 900000)
+		vsel = 0;
+	else if (min_uV < 1700000)
+		vsel = ((min_uV - 900000) / 50000);
+	else
+		vsel = ((min_uV - 1700000) / 100000)
+			+ WM831X_GP_LDO_SELECTOR_LOW + 1;
+
+	ret = wm831x_gp_ldo_list_voltage(rdev, vsel);
+	if (ret < 0)
+		return ret;
+	if (ret < min_uV || ret > max_uV)
+		return -EINVAL;
+
+	return wm831x_set_bits(wm831x, reg, WM831X_LDO1_ON_VSEL_MASK, vsel);
+}
+
+static int wm831x_gp_ldo_set_voltage(struct regulator_dev *rdev,
+				     int min_uV, int max_uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	int reg = ldo->base + WM831X_LDO_ON_CONTROL;
+
+	return wm831x_gp_ldo_set_voltage_int(rdev, reg, min_uV, max_uV);
+}
+
+static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
+					     int uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL;
+
+	return wm831x_gp_ldo_set_voltage_int(rdev, reg, uV, uV);
+}
+
+static int wm831x_gp_ldo_get_voltage(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int reg = ldo->base + WM831X_LDO_ON_CONTROL;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, reg);
+	if (ret < 0)
+		return ret;
+
+	ret &= WM831X_LDO1_ON_VSEL_MASK;
+
+	return wm831x_gp_ldo_list_voltage(rdev, ret);
+}
+
+static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int ctrl_reg = ldo->base + WM831X_LDO_CONTROL;
+	int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
+	unsigned int ret;
+
+	ret = wm831x_reg_read(wm831x, on_reg);
+	if (ret < 0)
+		return 0;
+
+	if (!(ret & WM831X_LDO1_ON_MODE))
+		return REGULATOR_MODE_NORMAL;
+
+	ret = wm831x_reg_read(wm831x, ctrl_reg);
+	if (ret < 0)
+		return 0;
+
+	if (ret & WM831X_LDO1_LP_MODE)
+		return REGULATOR_MODE_STANDBY;
+	else
+		return REGULATOR_MODE_IDLE;
+}
+
+static int wm831x_gp_ldo_set_mode(struct regulator_dev *rdev,
+				  unsigned int mode)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int ctrl_reg = ldo->base + WM831X_LDO_CONTROL;
+	int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
+	int ret;
+
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		ret = wm831x_set_bits(wm831x, on_reg,
+				      WM831X_LDO1_ON_MODE, 0);
+		if (ret < 0)
+			return ret;
+		break;
+
+	case REGULATOR_MODE_IDLE:
+		ret = wm831x_set_bits(wm831x, ctrl_reg,
+				      WM831X_LDO1_LP_MODE,
+				      WM831X_LDO1_LP_MODE);
+		if (ret < 0)
+			return ret;
+
+		ret = wm831x_set_bits(wm831x, on_reg,
+				      WM831X_LDO1_ON_MODE,
+				      WM831X_LDO1_ON_MODE);
+		if (ret < 0)
+			return ret;
+
+	case REGULATOR_MODE_STANDBY:
+		ret = wm831x_set_bits(wm831x, ctrl_reg,
+				      WM831X_LDO1_LP_MODE, 0);
+		if (ret < 0)
+			return ret;
+
+		ret = wm831x_set_bits(wm831x, on_reg,
+				      WM831X_LDO1_ON_MODE,
+				      WM831X_LDO1_ON_MODE);
+		if (ret < 0)
+			return ret;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int wm831x_gp_ldo_get_status(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+	int ret;
+
+	/* Is the regulator on? */
+	ret = wm831x_reg_read(wm831x, WM831X_LDO_STATUS);
+	if (ret < 0)
+		return ret;
+	if (!(ret & mask))
+		return REGULATOR_STATUS_OFF;
+
+	/* Is it reporting under voltage? */
+	ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS);
+	if (ret & mask)
+		return REGULATOR_STATUS_ERROR;
+
+	ret = wm831x_gp_ldo_get_mode(rdev);
+	if (ret < 0)
+		return ret;
+	else
+		return regulator_mode_to_status(ret);
+}
+
+static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
+						   int input_uV,
+						   int output_uV, int load_uA)
+{
+	if (load_uA < 20000)
+		return REGULATOR_MODE_STANDBY;
+	if (load_uA < 50000)
+		return REGULATOR_MODE_IDLE;
+	return REGULATOR_MODE_NORMAL;
+}
+
+
+static struct regulator_ops wm831x_gp_ldo_ops = {
+	.list_voltage = wm831x_gp_ldo_list_voltage,
+	.get_voltage = wm831x_gp_ldo_get_voltage,
+	.set_voltage = wm831x_gp_ldo_set_voltage,
+	.set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage,
+	.get_mode = wm831x_gp_ldo_get_mode,
+	.set_mode = wm831x_gp_ldo_set_mode,
+	.get_status = wm831x_gp_ldo_get_status,
+	.get_optimum_mode = wm831x_gp_ldo_get_optimum_mode,
+
+	.is_enabled = wm831x_ldo_is_enabled,
+	.enable = wm831x_ldo_enable,
+	.disable = wm831x_ldo_disable,
+};
+
+static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+	struct wm831x_ldo *ldo;
+	struct resource *res;
+	int ret, irq;
+
+	dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
+
+	if (pdata == NULL || pdata->ldo[id] == NULL)
+		return -ENODEV;
+
+	ldo = kzalloc(sizeof(struct wm831x_ldo), GFP_KERNEL);
+	if (ldo == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	ldo->wm831x = wm831x;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	ldo->base = res->start;
+
+	snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1);
+	ldo->desc.name = ldo->name;
+	ldo->desc.id = id;
+	ldo->desc.type = REGULATOR_VOLTAGE;
+	ldo->desc.n_voltages = WM831X_GP_LDO_MAX_SELECTOR + 1;
+	ldo->desc.ops = &wm831x_gp_ldo_ops;
+	ldo->desc.owner = THIS_MODULE;
+
+	ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
+					     pdata->ldo[id], ldo);
+	if (IS_ERR(ldo->regulator)) {
+		ret = PTR_ERR(ldo->regulator);
+		dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	irq = platform_get_irq_byname(pdev, "UV");
+	ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq,
+				 IRQF_TRIGGER_RISING, ldo->name,
+				 ldo);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
+			irq, ret);
+		goto err_regulator;
+	}
+
+	platform_set_drvdata(pdev, ldo);
+
+	return 0;
+
+err_regulator:
+	regulator_unregister(ldo->regulator);
+err:
+	kfree(ldo);
+	return ret;
+}
+
+static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev)
+{
+	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
+	struct wm831x *wm831x = ldo->wm831x;
+
+	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo);
+	regulator_unregister(ldo->regulator);
+	kfree(ldo);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_gp_ldo_driver = {
+	.probe = wm831x_gp_ldo_probe,
+	.remove = __devexit_p(wm831x_gp_ldo_remove),
+	.driver		= {
+		.name	= "wm831x-ldo",
+	},
+};
+
+/*
+ * Analogue LDOs
+ */
+
+
+#define WM831X_ALDO_SELECTOR_LOW 0xc
+#define WM831X_ALDO_MAX_SELECTOR 0x1f
+
+static int wm831x_aldo_list_voltage(struct regulator_dev *rdev,
+				      unsigned int selector)
+{
+	/* 1-1.6V in 50mV steps */
+	if (selector <= WM831X_ALDO_SELECTOR_LOW)
+		return 1000000 + (selector * 50000);
+	/* 1.7-3.5V in 50mV steps */
+	if (selector <= WM831X_ALDO_MAX_SELECTOR)
+		return 1600000 + ((selector - WM831X_ALDO_SELECTOR_LOW)
+				  * 100000);
+	return -EINVAL;
+}
+
+static int wm831x_aldo_set_voltage_int(struct regulator_dev *rdev, int reg,
+					 int min_uV, int max_uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int vsel, ret;
+
+	if (min_uV < 1000000)
+		vsel = 0;
+	else if (min_uV < 1700000)
+		vsel = ((min_uV - 1000000) / 50000);
+	else
+		vsel = ((min_uV - 1700000) / 100000)
+			+ WM831X_ALDO_SELECTOR_LOW + 1;
+
+	ret = wm831x_aldo_list_voltage(rdev, vsel);
+	if (ret < 0)
+		return ret;
+	if (ret < min_uV || ret > max_uV)
+		return -EINVAL;
+
+	return wm831x_set_bits(wm831x, reg, WM831X_LDO7_ON_VSEL_MASK, vsel);
+}
+
+static int wm831x_aldo_set_voltage(struct regulator_dev *rdev,
+				     int min_uV, int max_uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	int reg = ldo->base + WM831X_LDO_ON_CONTROL;
+
+	return wm831x_aldo_set_voltage_int(rdev, reg, min_uV, max_uV);
+}
+
+static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
+					     int uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	int reg = ldo->base + WM831X_LDO_SLEEP_CONTROL;
+
+	return wm831x_aldo_set_voltage_int(rdev, reg, uV, uV);
+}
+
+static int wm831x_aldo_get_voltage(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int reg = ldo->base + WM831X_LDO_ON_CONTROL;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, reg);
+	if (ret < 0)
+		return ret;
+
+	ret &= WM831X_LDO7_ON_VSEL_MASK;
+
+	return wm831x_aldo_list_voltage(rdev, ret);
+}
+
+static unsigned int wm831x_aldo_get_mode(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
+	unsigned int ret;
+
+	ret = wm831x_reg_read(wm831x, on_reg);
+	if (ret < 0)
+		return 0;
+
+	if (ret & WM831X_LDO7_ON_MODE)
+		return REGULATOR_MODE_IDLE;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int wm831x_aldo_set_mode(struct regulator_dev *rdev,
+				  unsigned int mode)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int ctrl_reg = ldo->base + WM831X_LDO_CONTROL;
+	int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
+	int ret;
+
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		ret = wm831x_set_bits(wm831x, on_reg,
+				      WM831X_LDO7_ON_MODE, 0);
+		if (ret < 0)
+			return ret;
+		break;
+
+	case REGULATOR_MODE_IDLE:
+		ret = wm831x_set_bits(wm831x, ctrl_reg,
+				      WM831X_LDO7_ON_MODE,
+				      WM831X_LDO7_ON_MODE);
+		if (ret < 0)
+			return ret;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int wm831x_aldo_get_status(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+	int ret;
+
+	/* Is the regulator on? */
+	ret = wm831x_reg_read(wm831x, WM831X_LDO_STATUS);
+	if (ret < 0)
+		return ret;
+	if (!(ret & mask))
+		return REGULATOR_STATUS_OFF;
+
+	/* Is it reporting under voltage? */
+	ret = wm831x_reg_read(wm831x, WM831X_LDO_UV_STATUS);
+	if (ret & mask)
+		return REGULATOR_STATUS_ERROR;
+
+	ret = wm831x_aldo_get_mode(rdev);
+	if (ret < 0)
+		return ret;
+	else
+		return regulator_mode_to_status(ret);
+}
+
+static struct regulator_ops wm831x_aldo_ops = {
+	.list_voltage = wm831x_aldo_list_voltage,
+	.get_voltage = wm831x_aldo_get_voltage,
+	.set_voltage = wm831x_aldo_set_voltage,
+	.set_suspend_voltage = wm831x_aldo_set_suspend_voltage,
+	.get_mode = wm831x_aldo_get_mode,
+	.set_mode = wm831x_aldo_set_mode,
+	.get_status = wm831x_aldo_get_status,
+
+	.is_enabled = wm831x_ldo_is_enabled,
+	.enable = wm831x_ldo_enable,
+	.disable = wm831x_ldo_disable,
+};
+
+static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+	struct wm831x_ldo *ldo;
+	struct resource *res;
+	int ret, irq;
+
+	dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
+
+	if (pdata == NULL || pdata->ldo[id] == NULL)
+		return -ENODEV;
+
+	ldo = kzalloc(sizeof(struct wm831x_ldo), GFP_KERNEL);
+	if (ldo == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	ldo->wm831x = wm831x;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	ldo->base = res->start;
+
+	snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1);
+	ldo->desc.name = ldo->name;
+	ldo->desc.id = id;
+	ldo->desc.type = REGULATOR_VOLTAGE;
+	ldo->desc.n_voltages = WM831X_ALDO_MAX_SELECTOR + 1;
+	ldo->desc.ops = &wm831x_aldo_ops;
+	ldo->desc.owner = THIS_MODULE;
+
+	ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
+					     pdata->ldo[id], ldo);
+	if (IS_ERR(ldo->regulator)) {
+		ret = PTR_ERR(ldo->regulator);
+		dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	irq = platform_get_irq_byname(pdev, "UV");
+	ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq,
+				 IRQF_TRIGGER_RISING, ldo->name,
+				 ldo);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
+			irq, ret);
+		goto err_regulator;
+	}
+
+	platform_set_drvdata(pdev, ldo);
+
+	return 0;
+
+err_regulator:
+	regulator_unregister(ldo->regulator);
+err:
+	kfree(ldo);
+	return ret;
+}
+
+static __devexit int wm831x_aldo_remove(struct platform_device *pdev)
+{
+	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
+	struct wm831x *wm831x = ldo->wm831x;
+
+	wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo);
+	regulator_unregister(ldo->regulator);
+	kfree(ldo);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_aldo_driver = {
+	.probe = wm831x_aldo_probe,
+	.remove = __devexit_p(wm831x_aldo_remove),
+	.driver		= {
+		.name	= "wm831x-aldo",
+	},
+};
+
+/*
+ * Alive LDO
+ */
+
+#define WM831X_ALIVE_LDO_MAX_SELECTOR 0xf
+
+static int wm831x_alive_ldo_list_voltage(struct regulator_dev *rdev,
+				      unsigned int selector)
+{
+	/* 0.8-1.55V in 50mV steps */
+	if (selector <= WM831X_ALIVE_LDO_MAX_SELECTOR)
+		return 800000 + (selector * 50000);
+	return -EINVAL;
+}
+
+static int wm831x_alive_ldo_set_voltage_int(struct regulator_dev *rdev,
+					    int reg,
+					    int min_uV, int max_uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int vsel, ret;
+
+	vsel = (min_uV - 800000) / 50000;
+
+	ret = wm831x_alive_ldo_list_voltage(rdev, vsel);
+	if (ret < 0)
+		return ret;
+	if (ret < min_uV || ret > max_uV)
+		return -EINVAL;
+
+	return wm831x_set_bits(wm831x, reg, WM831X_LDO11_ON_VSEL_MASK, vsel);
+}
+
+static int wm831x_alive_ldo_set_voltage(struct regulator_dev *rdev,
+				     int min_uV, int max_uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
+
+	return wm831x_alive_ldo_set_voltage_int(rdev, reg, min_uV, max_uV);
+}
+
+static int wm831x_alive_ldo_set_suspend_voltage(struct regulator_dev *rdev,
+					     int uV)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	int reg = ldo->base + WM831X_ALIVE_LDO_SLEEP_CONTROL;
+
+	return wm831x_alive_ldo_set_voltage_int(rdev, reg, uV, uV);
+}
+
+static int wm831x_alive_ldo_get_voltage(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int reg = ldo->base + WM831X_ALIVE_LDO_ON_CONTROL;
+	int ret;
+
+	ret = wm831x_reg_read(wm831x, reg);
+	if (ret < 0)
+		return ret;
+
+	ret &= WM831X_LDO11_ON_VSEL_MASK;
+
+	return wm831x_alive_ldo_list_voltage(rdev, ret);
+}
+
+static int wm831x_alive_ldo_get_status(struct regulator_dev *rdev)
+{
+	struct wm831x_ldo *ldo = rdev_get_drvdata(rdev);
+	struct wm831x *wm831x = ldo->wm831x;
+	int mask = 1 << rdev_get_id(rdev);
+	int ret;
+
+	/* Is the regulator on? */
+	ret = wm831x_reg_read(wm831x, WM831X_LDO_STATUS);
+	if (ret < 0)
+		return ret;
+	if (ret & mask)
+		return REGULATOR_STATUS_ON;
+	else
+		return REGULATOR_STATUS_OFF;
+}
+
+static struct regulator_ops wm831x_alive_ldo_ops = {
+	.list_voltage = wm831x_alive_ldo_list_voltage,
+	.get_voltage = wm831x_alive_ldo_get_voltage,
+	.set_voltage = wm831x_alive_ldo_set_voltage,
+	.set_suspend_voltage = wm831x_alive_ldo_set_suspend_voltage,
+	.get_status = wm831x_alive_ldo_get_status,
+
+	.is_enabled = wm831x_ldo_is_enabled,
+	.enable = wm831x_ldo_enable,
+	.disable = wm831x_ldo_disable,
+};
+
+static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
+	int id = pdev->id % ARRAY_SIZE(pdata->ldo);
+	struct wm831x_ldo *ldo;
+	struct resource *res;
+	int ret;
+
+	dev_dbg(&pdev->dev, "Probing LDO%d\n", id + 1);
+
+	if (pdata == NULL || pdata->ldo[id] == NULL)
+		return -ENODEV;
+
+	ldo = kzalloc(sizeof(struct wm831x_ldo), GFP_KERNEL);
+	if (ldo == NULL) {
+		dev_err(&pdev->dev, "Unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	ldo->wm831x = wm831x;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	ldo->base = res->start;
+
+	snprintf(ldo->name, sizeof(ldo->name), "LDO%d", id + 1);
+	ldo->desc.name = ldo->name;
+	ldo->desc.id = id;
+	ldo->desc.type = REGULATOR_VOLTAGE;
+	ldo->desc.n_voltages = WM831X_ALIVE_LDO_MAX_SELECTOR + 1;
+	ldo->desc.ops = &wm831x_alive_ldo_ops;
+	ldo->desc.owner = THIS_MODULE;
+
+	ldo->regulator = regulator_register(&ldo->desc, &pdev->dev,
+					     pdata->ldo[id], ldo);
+	if (IS_ERR(ldo->regulator)) {
+		ret = PTR_ERR(ldo->regulator);
+		dev_err(wm831x->dev, "Failed to register LDO%d: %d\n",
+			id + 1, ret);
+		goto err;
+	}
+
+	platform_set_drvdata(pdev, ldo);
+
+	return 0;
+
+err:
+	kfree(ldo);
+	return ret;
+}
+
+static __devexit int wm831x_alive_ldo_remove(struct platform_device *pdev)
+{
+	struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
+
+	regulator_unregister(ldo->regulator);
+	kfree(ldo);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_alive_ldo_driver = {
+	.probe = wm831x_alive_ldo_probe,
+	.remove = __devexit_p(wm831x_alive_ldo_remove),
+	.driver		= {
+		.name	= "wm831x-alive-ldo",
+	},
+};
+
+static int __init wm831x_ldo_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&wm831x_gp_ldo_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x GP LDO driver: %d\n", ret);
+
+	ret = platform_driver_register(&wm831x_aldo_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x ALDO driver: %d\n", ret);
+
+	ret = platform_driver_register(&wm831x_alive_ldo_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM831x alive LDO driver: %d\n",
+		       ret);
+
+	return 0;
+}
+subsys_initcall(wm831x_ldo_init);
+
+static void __exit wm831x_ldo_exit(void)
+{
+	platform_driver_unregister(&wm831x_alive_ldo_driver);
+	platform_driver_unregister(&wm831x_aldo_driver);
+	platform_driver_unregister(&wm831x_gp_ldo_driver);
+}
+module_exit(wm831x_ldo_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("WM831x LDO driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-ldo");
+MODULE_ALIAS("platform:wm831x-aldo");
+MODULE_ALIAS("platform:wm831x-aliveldo");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 81adbdb..73771b0 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -518,6 +518,16 @@ config RTC_DRV_V3020
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-v3020.
 
+config RTC_DRV_WM831X
+	tristate "Wolfson Microelectronics WM831x RTC"
+	depends on MFD_WM831X
+	help
+	  If you say yes here you will get support for the RTC subsystem
+	  of the Wolfson Microelectronics WM831X series PMICs.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called "rtc-wm831x".
+
 config RTC_DRV_WM8350
 	tristate "Wolfson Microelectronics WM8350 RTC"
 	depends on MFD_WM8350
@@ -535,6 +545,15 @@ config RTC_DRV_PCF50633
 	  If you say yes here you get support for the RTC subsystem of the
 	  NXP PCF50633 used in embedded systems.
 
+config RTC_DRV_AB3100
+	tristate "ST-Ericsson AB3100 RTC"
+	depends on AB3100_CORE
+	default y if AB3100_CORE
+	help
+	  Select this to enable the ST-Ericsson AB3100 Mixed Signal IC RTC
+	  support. This chip contains a battery- and capacitor-backed RTC.
+
+
 comment "on-CPU RTC drivers"
 
 config RTC_DRV_OMAP
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 3c0f2b2..5e152ff 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -17,6 +17,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
 
 # Keep the list ordered.
 
+obj-$(CONFIG_RTC_DRV_AB3100)	+= rtc-ab3100.o
 obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
 obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
 obj-$(CONFIG_RTC_DRV_AT91SAM9)	+= rtc-at91sam9.o
@@ -74,6 +75,7 @@ obj-$(CONFIG_RTC_DRV_TWL4030)	+= rtc-twl4030.o
 obj-$(CONFIG_RTC_DRV_TX4939)	+= rtc-tx4939.o
 obj-$(CONFIG_RTC_DRV_V3020)	+= rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)	+= rtc-vr41xx.o
+obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
 obj-$(CONFIG_RTC_DRV_PCF50633)	+= rtc-pcf50633.o
diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c
new file mode 100644
index 0000000..4704aac
--- /dev/null
+++ b/drivers/rtc/rtc-ab3100.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * RTC clock driver for the AB3100 Analog Baseband Chip
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/mfd/ab3100.h>
+
+/* Clock rate in Hz */
+#define AB3100_RTC_CLOCK_RATE	32768
+
+/*
+ * The AB3100 RTC registers. These are the same for
+ * AB3000 and AB3100.
+ * Control register:
+ * Bit 0: RTC Monitor cleared=0, active=1, if you set it
+ *        to 1 it remains active until RTC power is lost.
+ * Bit 1: 32 kHz Oscillator, 0 = on, 1 = bypass
+ * Bit 2: Alarm on, 0 = off, 1 = on
+ * Bit 3: 32 kHz buffer disabling, 0 = enabled, 1 = disabled
+ */
+#define AB3100_RTC		0x53
+/* default setting, buffer disabled, alarm on */
+#define RTC_SETTING		0x30
+/* Alarm when AL0-AL3 == TI0-TI3  */
+#define AB3100_AL0		0x56
+#define AB3100_AL1		0x57
+#define AB3100_AL2		0x58
+#define AB3100_AL3		0x59
+/* This 48-bit register that counts up at 32768 Hz */
+#define AB3100_TI0		0x5a
+#define AB3100_TI1		0x5b
+#define AB3100_TI2		0x5c
+#define AB3100_TI3		0x5d
+#define AB3100_TI4		0x5e
+#define AB3100_TI5		0x5f
+
+/*
+ * RTC clock functions and device struct declaration
+ */
+static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs)
+{
+	struct ab3100 *ab3100_data = dev_get_drvdata(dev);
+	u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2,
+		     AB3100_TI3, AB3100_TI4, AB3100_TI5};
+	unsigned char buf[6];
+	u64 fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2;
+	int err = 0;
+	int i;
+
+	buf[0] = (fat_time) & 0xFF;
+	buf[1] = (fat_time >> 8) & 0xFF;
+	buf[2] = (fat_time >> 16) & 0xFF;
+	buf[3] = (fat_time >> 24) & 0xFF;
+	buf[4] = (fat_time >> 32) & 0xFF;
+	buf[5] = (fat_time >> 40) & 0xFF;
+
+	for (i = 0; i < 6; i++) {
+		err = ab3100_set_register_interruptible(ab3100_data,
+							regs[i], buf[i]);
+		if (err)
+			return err;
+	}
+
+	/* Set the flag to mark that the clock is now set */
+	return ab3100_mask_and_set_register_interruptible(ab3100_data,
+							  AB3100_RTC,
+							  0xFE, 0x01);
+
+}
+
+static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct ab3100 *ab3100_data = dev_get_drvdata(dev);
+	unsigned long time;
+	u8 rtcval;
+	int err;
+
+	err = ab3100_get_register_interruptible(ab3100_data,
+						AB3100_RTC, &rtcval);
+	if (err)
+		return err;
+
+	if (!(rtcval & 0x01)) {
+		dev_info(dev, "clock not set (lost power)");
+		return -EINVAL;
+	} else {
+		u64 fat_time;
+		u8 buf[6];
+
+		/* Read out time registers */
+		err = ab3100_get_register_page_interruptible(ab3100_data,
+							     AB3100_TI0,
+							     buf, 6);
+		if (err != 0)
+			return err;
+
+		fat_time = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
+			((u64) buf[3] << 24) | ((u64) buf[2] << 16) |
+			((u64) buf[1] << 8) | (u64) buf[0];
+		time = (unsigned long) (fat_time /
+					(u64) (AB3100_RTC_CLOCK_RATE * 2));
+	}
+
+	rtc_time_to_tm(time, tm);
+
+	return rtc_valid_tm(tm);
+}
+
+static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct ab3100 *ab3100_data = dev_get_drvdata(dev);
+	unsigned long time;
+	u64 fat_time;
+	u8 buf[6];
+	u8 rtcval;
+	int err;
+
+	/* Figure out if alarm is enabled or not */
+	err = ab3100_get_register_interruptible(ab3100_data,
+						AB3100_RTC, &rtcval);
+	if (err)
+		return err;
+	if (rtcval & 0x04)
+		alarm->enabled = 1;
+	else
+		alarm->enabled = 0;
+	/* No idea how this could be represented */
+	alarm->pending = 0;
+	/* Read out alarm registers, only 4 bytes */
+	err = ab3100_get_register_page_interruptible(ab3100_data,
+						     AB3100_AL0, buf, 4);
+	if (err)
+		return err;
+	fat_time = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
+		((u64) buf[1] << 24) | ((u64) buf[0] << 16);
+	time = (unsigned long) (fat_time / (u64) (AB3100_RTC_CLOCK_RATE * 2));
+
+	rtc_time_to_tm(time, &alarm->time);
+
+	return rtc_valid_tm(&alarm->time);
+}
+
+static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	struct ab3100 *ab3100_data = dev_get_drvdata(dev);
+	u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3};
+	unsigned char buf[4];
+	unsigned long secs;
+	u64 fat_time;
+	int err;
+	int i;
+
+	rtc_tm_to_time(&alarm->time, &secs);
+	fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2;
+	buf[0] = (fat_time >> 16) & 0xFF;
+	buf[1] = (fat_time >> 24) & 0xFF;
+	buf[2] = (fat_time >> 32) & 0xFF;
+	buf[3] = (fat_time >> 40) & 0xFF;
+
+	/* Set the alarm */
+	for (i = 0; i < 4; i++) {
+		err = ab3100_set_register_interruptible(ab3100_data,
+							regs[i], buf[i]);
+		if (err)
+			return err;
+	}
+	/* Then enable the alarm */
+	return ab3100_mask_and_set_register_interruptible(ab3100_data,
+							  AB3100_RTC, ~(1 << 2),
+							  alarm->enabled << 2);
+}
+
+static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct ab3100 *ab3100_data = dev_get_drvdata(dev);
+
+	/*
+	 * It's not possible to enable/disable the alarm IRQ for this RTC.
+	 * It does not actually trigger any IRQ: instead its only function is
+	 * to power up the system, if it wasn't on. This will manifest as
+	 * a "power up cause" in the AB3100 power driver (battery charging etc)
+	 * and need to be handled there instead.
+	 */
+	if (enabled)
+		return ab3100_mask_and_set_register_interruptible(ab3100_data,
+						    AB3100_RTC, ~(1 << 2),
+						    1 << 2);
+	else
+		return ab3100_mask_and_set_register_interruptible(ab3100_data,
+						    AB3100_RTC, ~(1 << 2),
+						    0);
+}
+
+static const struct rtc_class_ops ab3100_rtc_ops = {
+	.read_time	= ab3100_rtc_read_time,
+	.set_mmss	= ab3100_rtc_set_mmss,
+	.read_alarm	= ab3100_rtc_read_alarm,
+	.set_alarm	= ab3100_rtc_set_alarm,
+	.alarm_irq_enable = ab3100_rtc_irq_enable,
+};
+
+static int __init ab3100_rtc_probe(struct platform_device *pdev)
+{
+	int err;
+	u8 regval;
+	struct rtc_device *rtc;
+	struct ab3100 *ab3100_data = platform_get_drvdata(pdev);
+
+	/* The first RTC register needs special treatment */
+	err = ab3100_get_register_interruptible(ab3100_data,
+						AB3100_RTC, &regval);
+	if (err) {
+		dev_err(&pdev->dev, "unable to read RTC register\n");
+		return -ENODEV;
+	}
+
+	if ((regval & 0xFE) != RTC_SETTING) {
+		dev_warn(&pdev->dev, "not default value in RTC reg 0x%x\n",
+			 regval);
+	}
+
+	if ((regval & 1) == 0) {
+		/*
+		 * Set bit to detect power loss.
+		 * This bit remains until RTC power is lost.
+		 */
+		regval = 1 | RTC_SETTING;
+		err = ab3100_set_register_interruptible(ab3100_data,
+							AB3100_RTC, regval);
+		/* Ignore any error on this write */
+	}
+
+	rtc = rtc_device_register("ab3100-rtc", &pdev->dev, &ab3100_rtc_ops,
+				  THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		err = PTR_ERR(rtc);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __exit ab3100_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+
+	rtc_device_unregister(rtc);
+	return 0;
+}
+
+static struct platform_driver ab3100_rtc_driver = {
+	.driver = {
+		.name = "ab3100-rtc",
+		.owner = THIS_MODULE,
+	},
+	.remove	 = __exit_p(ab3100_rtc_remove),
+};
+
+static int __init ab3100_rtc_init(void)
+{
+	return platform_driver_probe(&ab3100_rtc_driver,
+				     ab3100_rtc_probe);
+}
+
+static void __exit ab3100_rtc_exit(void)
+{
+	platform_driver_unregister(&ab3100_rtc_driver);
+}
+
+module_init(ab3100_rtc_init);
+module_exit(ab3100_rtc_exit);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
+MODULE_DESCRIPTION("AB3100 RTC Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index 1845566..d490628 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -1,26 +1,25 @@
 /*
  * Dallas DS1302 RTC Support
  *
- *  Copyright (C) 2002  David McCullough
- *  Copyright (C) 2003 - 2007  Paul Mundt
+ *  Copyright (C) 2002 David McCullough
+ *  Copyright (C) 2003 - 2007 Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
- * License version 2.  See the file "COPYING" in the main directory of
+ * License version 2. See the file "COPYING" in the main directory of
  * this archive for more details.
  */
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/time.h>
 #include <linux/rtc.h>
-#include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/bcd.h>
 #include <asm/rtc.h>
 
 #define DRV_NAME	"rtc-ds1302"
-#define DRV_VERSION	"0.1.0"
+#define DRV_VERSION	"0.1.1"
 
 #define	RTC_CMD_READ	0x81		/* Read command */
 #define	RTC_CMD_WRITE	0x80		/* Write command */
@@ -47,11 +46,6 @@
 #error "Add support for your platform"
 #endif
 
-struct ds1302_rtc {
-	struct rtc_device *rtc_dev;
-	spinlock_t lock;
-};
-
 static void ds1302_sendbits(unsigned int val)
 {
 	int i;
@@ -103,10 +97,6 @@ static void ds1302_writebyte(unsigned int addr, unsigned int val)
 
 static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	struct ds1302_rtc *rtc = dev_get_drvdata(dev);
-
-	spin_lock_irq(&rtc->lock);
-
 	tm->tm_sec	= bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
 	tm->tm_min	= bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
 	tm->tm_hour	= bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
@@ -118,26 +108,17 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
 	if (tm->tm_year < 70)
 		tm->tm_year += 100;
 
-	spin_unlock_irq(&rtc->lock);
-
 	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
 		"mday=%d, mon=%d, year=%d, wday=%d\n",
 		__func__,
 		tm->tm_sec, tm->tm_min, tm->tm_hour,
 		tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
 
-	if (rtc_valid_tm(tm) < 0)
-		dev_err(dev, "invalid date\n");
-
-	return 0;
+	return rtc_valid_tm(tm);
 }
 
 static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
-	struct ds1302_rtc *rtc = dev_get_drvdata(dev);
-
-	spin_lock_irq(&rtc->lock);
-
 	/* Stop RTC */
 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
 
@@ -152,8 +133,6 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	/* Start RTC */
 	ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
 
-	spin_unlock_irq(&rtc->lock);
-
 	return 0;
 }
 
@@ -170,9 +149,7 @@ static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
 		if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
 			return -EFAULT;
 
-		spin_lock_irq(&rtc->lock);
 		ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
-		spin_unlock_irq(&rtc->lock);
 		return 0;
 	}
 #endif
@@ -187,10 +164,9 @@ static struct rtc_class_ops ds1302_rtc_ops = {
 	.ioctl		= ds1302_rtc_ioctl,
 };
 
-static int __devinit ds1302_rtc_probe(struct platform_device *pdev)
+static int __init ds1302_rtc_probe(struct platform_device *pdev)
 {
-	struct ds1302_rtc *rtc;
-	int ret;
+	struct rtc_device *rtc;
 
 	/* Reset */
 	set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
@@ -200,37 +176,23 @@ static int __devinit ds1302_rtc_probe(struct platform_device *pdev)
 	if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42)
 		return -ENODEV;
 
-	rtc = kzalloc(sizeof(struct ds1302_rtc), GFP_KERNEL);
-	if (unlikely(!rtc))
-		return -ENOMEM;
-
-	spin_lock_init(&rtc->lock);
-	rtc->rtc_dev = rtc_device_register("ds1302", &pdev->dev,
+	rtc = rtc_device_register("ds1302", &pdev->dev,
 					   &ds1302_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtc_dev)) {
-		ret = PTR_ERR(rtc->rtc_dev);
-		goto out;
-	}
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
 
 	platform_set_drvdata(pdev, rtc);
 
 	return 0;
-out:
-	kfree(rtc);
-	return ret;
 }
 
 static int __devexit ds1302_rtc_remove(struct platform_device *pdev)
 {
-	struct ds1302_rtc *rtc = platform_get_drvdata(pdev);
-
-	if (likely(rtc->rtc_dev))
-		rtc_device_unregister(rtc->rtc_dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
 
+	rtc_device_unregister(rtc);
 	platform_set_drvdata(pdev, NULL);
 
-	kfree(rtc);
-
 	return 0;
 }
 
@@ -239,13 +201,12 @@ static struct platform_driver ds1302_platform_driver = {
 		.name	= DRV_NAME,
 		.owner	= THIS_MODULE,
 	},
-	.probe		= ds1302_rtc_probe,
-	.remove		= __devexit_p(ds1302_rtc_remove),
+	.remove		= __exit_p(ds1302_rtc_remove),
 };
 
 static int __init ds1302_rtc_init(void)
 {
-	return platform_driver_register(&ds1302_platform_driver);
+	return platform_driver_probe(&ds1302_platform_driver, ds1302_rtc_probe);
 }
 
 static void __exit ds1302_rtc_exit(void)
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 4f247e4..021b292 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -9,7 +9,7 @@
  *
  * Modifications from:
  *   CIH <cih@coventive.com>
- *   Nicolas Pitre <nico@cam.org>
+ *   Nicolas Pitre <nico@fluxnic.net>
  *   Andrew Christian <andrew.christian@hp.com>
  *
  * Converted to the RTC subsystem and Driver Model
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index d7310ad..e6ed540 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -29,7 +29,7 @@
 #include <asm/rtc.h>
 
 #define DRV_NAME	"sh-rtc"
-#define DRV_VERSION	"0.2.2"
+#define DRV_VERSION	"0.2.3"
 
 #define RTC_REG(r)	((r) * rtc_reg_size)
 
@@ -215,7 +215,7 @@ static irqreturn_t sh_rtc_shared(int irq, void *dev_id)
 	return IRQ_RETVAL(ret);
 }
 
-static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
+static int sh_rtc_irq_set_state(struct device *dev, int enable)
 {
 	struct sh_rtc *rtc = dev_get_drvdata(dev);
 	unsigned int tmp;
@@ -225,17 +225,22 @@ static inline void sh_rtc_setpie(struct device *dev, unsigned int enable)
 	tmp = readb(rtc->regbase + RCR2);
 
 	if (enable) {
+		rtc->periodic_freq |= PF_KOU;
 		tmp &= ~RCR2_PEF;	/* Clear PES bit */
 		tmp |= (rtc->periodic_freq & ~PF_HP);	/* Set PES2-0 */
-	} else
+	} else {
+		rtc->periodic_freq &= ~PF_KOU;
 		tmp &= ~(RCR2_PESMASK | RCR2_PEF);
+	}
 
 	writeb(tmp, rtc->regbase + RCR2);
 
 	spin_unlock_irq(&rtc->lock);
+
+	return 0;
 }
 
-static inline int sh_rtc_setfreq(struct device *dev, unsigned int freq)
+static int sh_rtc_irq_set_freq(struct device *dev, int freq)
 {
 	struct sh_rtc *rtc = dev_get_drvdata(dev);
 	int tmp, ret = 0;
@@ -278,10 +283,8 @@ static inline int sh_rtc_setfreq(struct device *dev, unsigned int freq)
 		ret = -ENOTSUPP;
 	}
 
-	if (ret == 0) {
+	if (ret == 0)
 		rtc->periodic_freq |= tmp;
-		rtc->rtc_dev->irq_freq = freq;
-	}
 
 	spin_unlock_irq(&rtc->lock);
 	return ret;
@@ -346,10 +349,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 	unsigned int ret = 0;
 
 	switch (cmd) {
-	case RTC_PIE_OFF:
-	case RTC_PIE_ON:
-		sh_rtc_setpie(dev, cmd == RTC_PIE_ON);
-		break;
 	case RTC_AIE_OFF:
 	case RTC_AIE_ON:
 		sh_rtc_setaie(dev, cmd == RTC_AIE_ON);
@@ -362,13 +361,6 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 		rtc->periodic_freq |= PF_OXS;
 		sh_rtc_setcie(dev, 1);
 		break;
-	case RTC_IRQP_READ:
-		ret = put_user(rtc->rtc_dev->irq_freq,
-			       (unsigned long __user *)arg);
-		break;
-	case RTC_IRQP_SET:
-		ret = sh_rtc_setfreq(dev, arg);
-		break;
 	default:
 		ret = -ENOIOCTLCMD;
 	}
@@ -602,28 +594,6 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
 	return 0;
 }
 
-static int sh_rtc_irq_set_state(struct device *dev, int enabled)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct sh_rtc *rtc = platform_get_drvdata(pdev);
-
-	if (enabled) {
-		rtc->periodic_freq |= PF_KOU;
-		return sh_rtc_ioctl(dev, RTC_PIE_ON, 0);
-	} else {
-		rtc->periodic_freq &= ~PF_KOU;
-		return sh_rtc_ioctl(dev, RTC_PIE_OFF, 0);
-	}
-}
-
-static int sh_rtc_irq_set_freq(struct device *dev, int freq)
-{
-	if (!is_power_of_2(freq))
-		return -EINVAL;
-
-	return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq);
-}
-
 static struct rtc_class_ops sh_rtc_ops = {
 	.ioctl		= sh_rtc_ioctl,
 	.read_time	= sh_rtc_read_time,
@@ -635,7 +605,7 @@ static struct rtc_class_ops sh_rtc_ops = {
 	.proc		= sh_rtc_proc,
 };
 
-static int __devinit sh_rtc_probe(struct platform_device *pdev)
+static int __init sh_rtc_probe(struct platform_device *pdev)
 {
 	struct sh_rtc *rtc;
 	struct resource *res;
@@ -702,13 +672,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 
 	clk_enable(rtc->clk);
 
-	rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
-					   &sh_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc->rtc_dev)) {
-		ret = PTR_ERR(rtc->rtc_dev);
-		goto err_unmap;
-	}
-
 	rtc->capabilities = RTC_DEF_CAPABILITIES;
 	if (pdev->dev.platform_data) {
 		struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data;
@@ -720,10 +683,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 		rtc->capabilities |= pinfo->capabilities;
 	}
 
-	rtc->rtc_dev->max_user_freq = 256;
-
-	platform_set_drvdata(pdev, rtc);
-
 	if (rtc->carry_irq <= 0) {
 		/* register shared periodic/carry/alarm irq */
 		ret = request_irq(rtc->periodic_irq, sh_rtc_shared,
@@ -767,13 +726,26 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
 		}
 	}
 
+	platform_set_drvdata(pdev, rtc);
+
 	/* everything disabled by default */
-	rtc->periodic_freq = 0;
-	rtc->rtc_dev->irq_freq = 0;
-	sh_rtc_setpie(&pdev->dev, 0);
+	sh_rtc_irq_set_freq(&pdev->dev, 0);
+	sh_rtc_irq_set_state(&pdev->dev, 0);
 	sh_rtc_setaie(&pdev->dev, 0);
 	sh_rtc_setcie(&pdev->dev, 0);
 
+	rtc->rtc_dev = rtc_device_register("sh", &pdev->dev,
+					   &sh_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc->rtc_dev)) {
+		ret = PTR_ERR(rtc->rtc_dev);
+		free_irq(rtc->periodic_irq, rtc);
+		free_irq(rtc->carry_irq, rtc);
+		free_irq(rtc->alarm_irq, rtc);
+		goto err_unmap;
+	}
+
+	rtc->rtc_dev->max_user_freq = 256;
+
 	/* reset rtc to epoch 0 if time is invalid */
 	if (rtc_read_time(rtc->rtc_dev, &r) < 0) {
 		rtc_time_to_tm(0, &r);
@@ -795,14 +767,13 @@ err_badres:
 	return ret;
 }
 
-static int __devexit sh_rtc_remove(struct platform_device *pdev)
+static int __exit sh_rtc_remove(struct platform_device *pdev)
 {
 	struct sh_rtc *rtc = platform_get_drvdata(pdev);
 
-	if (likely(rtc->rtc_dev))
-		rtc_device_unregister(rtc->rtc_dev);
+	rtc_device_unregister(rtc->rtc_dev);
+	sh_rtc_irq_set_state(&pdev->dev, 0);
 
-	sh_rtc_setpie(&pdev->dev, 0);
 	sh_rtc_setaie(&pdev->dev, 0);
 	sh_rtc_setcie(&pdev->dev, 0);
 
@@ -813,9 +784,8 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
 		free_irq(rtc->alarm_irq, rtc);
 	}
 
-	release_resource(rtc->res);
-
 	iounmap(rtc->regbase);
+	release_resource(rtc->res);
 
 	clk_disable(rtc->clk);
 	clk_put(rtc->clk);
@@ -867,13 +837,12 @@ static struct platform_driver sh_rtc_platform_driver = {
 		.owner	= THIS_MODULE,
 		.pm	= &sh_rtc_dev_pm_ops,
 	},
-	.probe		= sh_rtc_probe,
-	.remove		= __devexit_p(sh_rtc_remove),
+	.remove		= __exit_p(sh_rtc_remove),
 };
 
 static int __init sh_rtc_init(void)
 {
-	return platform_driver_register(&sh_rtc_platform_driver);
+	return platform_driver_probe(&sh_rtc_platform_driver, sh_rtc_probe);
 }
 
 static void __exit sh_rtc_exit(void)
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c
new file mode 100644
index 0000000..79795cd
--- /dev/null
+++ b/drivers/rtc/rtc-wm831x.c
@@ -0,0 +1,523 @@
+/*
+ *	Real Time Clock driver for Wolfson Microelectronics WM831x
+ *
+ *	Copyright (C) 2009 Wolfson Microelectronics PLC.
+ *
+ *  Author: Mark Brown <broonie@opensource.wolfsonmicro.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/kernel.h>
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/interrupt.h>
+#include <linux/ioctl.h>
+#include <linux/completion.h>
+#include <linux/mfd/wm831x/core.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+
+/*
+ * R16416 (0x4020) - RTC Write Counter
+ */
+#define WM831X_RTC_WR_CNT_MASK                  0xFFFF  /* RTC_WR_CNT - [15:0] */
+#define WM831X_RTC_WR_CNT_SHIFT                      0  /* RTC_WR_CNT - [15:0] */
+#define WM831X_RTC_WR_CNT_WIDTH                     16  /* RTC_WR_CNT - [15:0] */
+
+/*
+ * R16417 (0x4021) - RTC Time 1
+ */
+#define WM831X_RTC_TIME_MASK                    0xFFFF  /* RTC_TIME - [15:0] */
+#define WM831X_RTC_TIME_SHIFT                        0  /* RTC_TIME - [15:0] */
+#define WM831X_RTC_TIME_WIDTH                       16  /* RTC_TIME - [15:0] */
+
+/*
+ * R16418 (0x4022) - RTC Time 2
+ */
+#define WM831X_RTC_TIME_MASK                    0xFFFF  /* RTC_TIME - [15:0] */
+#define WM831X_RTC_TIME_SHIFT                        0  /* RTC_TIME - [15:0] */
+#define WM831X_RTC_TIME_WIDTH                       16  /* RTC_TIME - [15:0] */
+
+/*
+ * R16419 (0x4023) - RTC Alarm 1
+ */
+#define WM831X_RTC_ALM_MASK                     0xFFFF  /* RTC_ALM - [15:0] */
+#define WM831X_RTC_ALM_SHIFT                         0  /* RTC_ALM - [15:0] */
+#define WM831X_RTC_ALM_WIDTH                        16  /* RTC_ALM - [15:0] */
+
+/*
+ * R16420 (0x4024) - RTC Alarm 2
+ */
+#define WM831X_RTC_ALM_MASK                     0xFFFF  /* RTC_ALM - [15:0] */
+#define WM831X_RTC_ALM_SHIFT                         0  /* RTC_ALM - [15:0] */
+#define WM831X_RTC_ALM_WIDTH                        16  /* RTC_ALM - [15:0] */
+
+/*
+ * R16421 (0x4025) - RTC Control
+ */
+#define WM831X_RTC_VALID                        0x8000  /* RTC_VALID */
+#define WM831X_RTC_VALID_MASK                   0x8000  /* RTC_VALID */
+#define WM831X_RTC_VALID_SHIFT                      15  /* RTC_VALID */
+#define WM831X_RTC_VALID_WIDTH                       1  /* RTC_VALID */
+#define WM831X_RTC_SYNC_BUSY                    0x4000  /* RTC_SYNC_BUSY */
+#define WM831X_RTC_SYNC_BUSY_MASK               0x4000  /* RTC_SYNC_BUSY */
+#define WM831X_RTC_SYNC_BUSY_SHIFT                  14  /* RTC_SYNC_BUSY */
+#define WM831X_RTC_SYNC_BUSY_WIDTH                   1  /* RTC_SYNC_BUSY */
+#define WM831X_RTC_ALM_ENA                      0x0400  /* RTC_ALM_ENA */
+#define WM831X_RTC_ALM_ENA_MASK                 0x0400  /* RTC_ALM_ENA */
+#define WM831X_RTC_ALM_ENA_SHIFT                    10  /* RTC_ALM_ENA */
+#define WM831X_RTC_ALM_ENA_WIDTH                     1  /* RTC_ALM_ENA */
+#define WM831X_RTC_PINT_FREQ_MASK               0x0070  /* RTC_PINT_FREQ - [6:4] */
+#define WM831X_RTC_PINT_FREQ_SHIFT                   4  /* RTC_PINT_FREQ - [6:4] */
+#define WM831X_RTC_PINT_FREQ_WIDTH                   3  /* RTC_PINT_FREQ - [6:4] */
+
+/*
+ * R16422 (0x4026) - RTC Trim
+ */
+#define WM831X_RTC_TRIM_MASK                    0x03FF  /* RTC_TRIM - [9:0] */
+#define WM831X_RTC_TRIM_SHIFT                        0  /* RTC_TRIM - [9:0] */
+#define WM831X_RTC_TRIM_WIDTH                       10  /* RTC_TRIM - [9:0] */
+
+#define WM831X_SET_TIME_RETRIES	5
+#define WM831X_GET_TIME_RETRIES	5
+
+struct wm831x_rtc {
+	struct wm831x *wm831x;
+	struct rtc_device *rtc;
+	unsigned int alarm_enabled:1;
+};
+
+/*
+ * Read current time and date in RTC
+ */
+static int wm831x_rtc_readtime(struct device *dev, struct rtc_time *tm)
+{
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
+	struct wm831x *wm831x = wm831x_rtc->wm831x;
+	u16 time1[2], time2[2];
+	int ret;
+	int count = 0;
+
+	/* Has the RTC been programmed? */
+	ret = wm831x_reg_read(wm831x, WM831X_RTC_CONTROL);
+	if (ret < 0) {
+		dev_err(dev, "Failed to read RTC control: %d\n", ret);
+		return ret;
+	}
+	if (!(ret & WM831X_RTC_VALID)) {
+		dev_dbg(dev, "RTC not yet configured\n");
+		return -EINVAL;
+	}
+
+	/* Read twice to make sure we don't read a corrupt, partially
+	 * incremented, value.
+	 */
+	do {
+		ret = wm831x_bulk_read(wm831x, WM831X_RTC_TIME_1,
+				       2, time1);
+		if (ret != 0)
+			continue;
+
+		ret = wm831x_bulk_read(wm831x, WM831X_RTC_TIME_1,
+				       2, time2);
+		if (ret != 0)
+			continue;
+
+		if (memcmp(time1, time2, sizeof(time1)) == 0) {
+			u32 time = (time1[0] << 16) | time1[1];
+
+			rtc_time_to_tm(time, tm);
+			return rtc_valid_tm(tm);
+		}
+
+	} while (++count < WM831X_GET_TIME_RETRIES);
+
+	dev_err(dev, "Timed out reading current time\n");
+
+	return -EIO;
+}
+
+/*
+ * Set current time and date in RTC
+ */
+static int wm831x_rtc_set_mmss(struct device *dev, unsigned long time)
+{
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
+	struct wm831x *wm831x = wm831x_rtc->wm831x;
+	struct rtc_time new_tm;
+	unsigned long new_time;
+	int ret;
+	int count = 0;
+
+	ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_1,
+			       (time >> 16) & 0xffff);
+	if (ret < 0) {
+		dev_err(dev, "Failed to write TIME_1: %d\n", ret);
+		return ret;
+	}
+
+	ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_2, time & 0xffff);
+	if (ret < 0) {
+		dev_err(dev, "Failed to write TIME_2: %d\n", ret);
+		return ret;
+	}
+
+	/* Wait for the update to complete - should happen first time
+	 * round but be conservative.
+	 */
+	do {
+		msleep(1);
+
+		ret = wm831x_reg_read(wm831x, WM831X_RTC_CONTROL);
+		if (ret < 0)
+			ret = WM831X_RTC_SYNC_BUSY;
+	} while (!(ret & WM831X_RTC_SYNC_BUSY) &&
+		 ++count < WM831X_SET_TIME_RETRIES);
+
+	if (ret & WM831X_RTC_SYNC_BUSY) {
+		dev_err(dev, "Timed out writing RTC update\n");
+		return -EIO;
+	}
+
+	/* Check that the update was accepted; security features may
+	 * have caused the update to be ignored.
+	 */
+	ret = wm831x_rtc_readtime(dev, &new_tm);
+	if (ret < 0)
+		return ret;
+
+	ret = rtc_tm_to_time(&new_tm, &new_time);
+	if (ret < 0) {
+		dev_err(dev, "Failed to convert time: %d\n", ret);
+		return ret;
+	}
+
+	/* Allow a second of change in case of tick */
+	if (new_time - time > 1) {
+		dev_err(dev, "RTC update not permitted by hardware\n");
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+/*
+ * Read alarm time and date in RTC
+ */
+static int wm831x_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
+	int ret;
+	u16 data[2];
+	u32 time;
+
+	ret = wm831x_bulk_read(wm831x_rtc->wm831x, WM831X_RTC_ALARM_1,
+			       2, data);
+	if (ret != 0) {
+		dev_err(dev, "Failed to read alarm time: %d\n", ret);
+		return ret;
+	}
+
+	time = (data[0] << 16) | data[1];
+
+	rtc_time_to_tm(time, &alrm->time);
+
+	ret = wm831x_reg_read(wm831x_rtc->wm831x, WM831X_RTC_CONTROL);
+	if (ret < 0) {
+		dev_err(dev, "Failed to read RTC control: %d\n", ret);
+		return ret;
+	}
+
+	if (ret & WM831X_RTC_ALM_ENA)
+		alrm->enabled = 1;
+	else
+		alrm->enabled = 0;
+
+	return 0;
+}
+
+static int wm831x_rtc_stop_alarm(struct wm831x_rtc *wm831x_rtc)
+{
+	wm831x_rtc->alarm_enabled = 0;
+
+	return wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL,
+			       WM831X_RTC_ALM_ENA, 0);
+}
+
+static int wm831x_rtc_start_alarm(struct wm831x_rtc *wm831x_rtc)
+{
+	wm831x_rtc->alarm_enabled = 1;
+
+	return wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL,
+			       WM831X_RTC_ALM_ENA, WM831X_RTC_ALM_ENA);
+}
+
+static int wm831x_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
+	struct wm831x *wm831x = wm831x_rtc->wm831x;
+	int ret;
+	unsigned long time;
+
+	ret = rtc_tm_to_time(&alrm->time, &time);
+	if (ret < 0) {
+		dev_err(dev, "Failed to convert time: %d\n", ret);
+		return ret;
+	}
+
+	ret = wm831x_rtc_stop_alarm(wm831x_rtc);
+	if (ret < 0) {
+		dev_err(dev, "Failed to stop alarm: %d\n", ret);
+		return ret;
+	}
+
+	ret = wm831x_reg_write(wm831x, WM831X_RTC_ALARM_1,
+			       (time >> 16) & 0xffff);
+	if (ret < 0) {
+		dev_err(dev, "Failed to write ALARM_1: %d\n", ret);
+		return ret;
+	}
+
+	ret = wm831x_reg_write(wm831x, WM831X_RTC_ALARM_2, time & 0xffff);
+	if (ret < 0) {
+		dev_err(dev, "Failed to write ALARM_2: %d\n", ret);
+		return ret;
+	}
+
+	if (alrm->enabled) {
+		ret = wm831x_rtc_start_alarm(wm831x_rtc);
+		if (ret < 0) {
+			dev_err(dev, "Failed to start alarm: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int wm831x_rtc_alarm_irq_enable(struct device *dev,
+				       unsigned int enabled)
+{
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
+
+	if (enabled)
+		return wm831x_rtc_start_alarm(wm831x_rtc);
+	else
+		return wm831x_rtc_stop_alarm(wm831x_rtc);
+}
+
+static int wm831x_rtc_update_irq_enable(struct device *dev,
+					unsigned int enabled)
+{
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
+	int val;
+
+	if (enabled)
+		val = 1 << WM831X_RTC_PINT_FREQ_SHIFT;
+	else
+		val = 0;
+
+	return wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL,
+			       WM831X_RTC_PINT_FREQ_MASK, val);
+}
+
+static irqreturn_t wm831x_alm_irq(int irq, void *data)
+{
+	struct wm831x_rtc *wm831x_rtc = data;
+
+	rtc_update_irq(wm831x_rtc->rtc, 1, RTC_IRQF | RTC_AF);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t wm831x_per_irq(int irq, void *data)
+{
+	struct wm831x_rtc *wm831x_rtc = data;
+
+	rtc_update_irq(wm831x_rtc->rtc, 1, RTC_IRQF | RTC_UF);
+
+	return IRQ_HANDLED;
+}
+
+static const struct rtc_class_ops wm831x_rtc_ops = {
+	.read_time = wm831x_rtc_readtime,
+	.set_mmss = wm831x_rtc_set_mmss,
+	.read_alarm = wm831x_rtc_readalarm,
+	.set_alarm = wm831x_rtc_setalarm,
+	.alarm_irq_enable = wm831x_rtc_alarm_irq_enable,
+	.update_irq_enable = wm831x_rtc_update_irq_enable,
+};
+
+#ifdef CONFIG_PM
+/* Turn off the alarm if it should not be a wake source. */
+static int wm831x_rtc_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(&pdev->dev);
+	int ret, enable;
+
+	if (wm831x_rtc->alarm_enabled && device_may_wakeup(&pdev->dev))
+		enable = WM831X_RTC_ALM_ENA;
+	else
+		enable = 0;
+
+	ret = wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL,
+			      WM831X_RTC_ALM_ENA, enable);
+	if (ret != 0)
+		dev_err(&pdev->dev, "Failed to update RTC alarm: %d\n", ret);
+
+	return 0;
+}
+
+/* Enable the alarm if it should be enabled (in case it was disabled to
+ * prevent use as a wake source).
+ */
+static int wm831x_rtc_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(&pdev->dev);
+	int ret;
+
+	if (wm831x_rtc->alarm_enabled) {
+		ret = wm831x_rtc_start_alarm(wm831x_rtc);
+		if (ret != 0)
+			dev_err(&pdev->dev,
+				"Failed to restart RTC alarm: %d\n", ret);
+	}
+
+	return 0;
+}
+
+/* Unconditionally disable the alarm */
+static int wm831x_rtc_freeze(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(&pdev->dev);
+	int ret;
+
+	ret = wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL,
+			      WM831X_RTC_ALM_ENA, 0);
+	if (ret != 0)
+		dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n", ret);
+
+	return 0;
+}
+#else
+#define wm831x_rtc_suspend NULL
+#define wm831x_rtc_resume NULL
+#define wm831x_rtc_freeze NULL
+#endif
+
+static int wm831x_rtc_probe(struct platform_device *pdev)
+{
+	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
+	struct wm831x_rtc *wm831x_rtc;
+	int per_irq = platform_get_irq_byname(pdev, "PER");
+	int alm_irq = platform_get_irq_byname(pdev, "ALM");
+	int ret = 0;
+
+	wm831x_rtc = kzalloc(sizeof(*wm831x_rtc), GFP_KERNEL);
+	if (wm831x_rtc == NULL)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, wm831x_rtc);
+	wm831x_rtc->wm831x = wm831x;
+
+	ret = wm831x_reg_read(wm831x, WM831X_RTC_CONTROL);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to read RTC control: %d\n", ret);
+		goto err;
+	}
+	if (ret & WM831X_RTC_ALM_ENA)
+		wm831x_rtc->alarm_enabled = 1;
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	wm831x_rtc->rtc = rtc_device_register("wm831x", &pdev->dev,
+					      &wm831x_rtc_ops, THIS_MODULE);
+	if (IS_ERR(wm831x_rtc->rtc)) {
+		ret = PTR_ERR(wm831x_rtc->rtc);
+		goto err;
+	}
+
+	ret = wm831x_request_irq(wm831x, per_irq, wm831x_per_irq,
+				 IRQF_TRIGGER_RISING, "wm831x_rtc_per",
+				 wm831x_rtc);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request periodic IRQ %d: %d\n",
+			per_irq, ret);
+	}
+
+	ret = wm831x_request_irq(wm831x, alm_irq, wm831x_alm_irq,
+				 IRQF_TRIGGER_RISING, "wm831x_rtc_alm",
+				 wm831x_rtc);
+	if (ret != 0) {
+		dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n",
+			alm_irq, ret);
+	}
+
+	return 0;
+
+err:
+	kfree(wm831x_rtc);
+	return ret;
+}
+
+static int __devexit wm831x_rtc_remove(struct platform_device *pdev)
+{
+	struct wm831x_rtc *wm831x_rtc = platform_get_drvdata(pdev);
+	int per_irq = platform_get_irq_byname(pdev, "PER");
+	int alm_irq = platform_get_irq_byname(pdev, "ALM");
+
+	wm831x_free_irq(wm831x_rtc->wm831x, alm_irq, wm831x_rtc);
+	wm831x_free_irq(wm831x_rtc->wm831x, per_irq, wm831x_rtc);
+	rtc_device_unregister(wm831x_rtc->rtc);
+	kfree(wm831x_rtc);
+
+	return 0;
+}
+
+static struct dev_pm_ops wm831x_rtc_pm_ops = {
+	.suspend = wm831x_rtc_suspend,
+	.resume = wm831x_rtc_resume,
+
+	.freeze = wm831x_rtc_freeze,
+	.thaw = wm831x_rtc_resume,
+	.restore = wm831x_rtc_resume,
+
+	.poweroff = wm831x_rtc_suspend,
+};
+
+static struct platform_driver wm831x_rtc_driver = {
+	.probe = wm831x_rtc_probe,
+	.remove = __devexit_p(wm831x_rtc_remove),
+	.driver = {
+		.name = "wm831x-rtc",
+		.pm = &wm831x_rtc_pm_ops,
+	},
+};
+
+static int __init wm831x_rtc_init(void)
+{
+	return platform_driver_register(&wm831x_rtc_driver);
+}
+module_init(wm831x_rtc_init);
+
+static void __exit wm831x_rtc_exit(void)
+{
+	platform_driver_unregister(&wm831x_rtc_driver);
+}
+module_exit(wm831x_rtc_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("RTC driver for the WM831x series PMICs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-rtc");
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index e995123..393c73c 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -266,7 +266,7 @@ static struct attribute_group subch_attr_group = {
 	.attrs = subch_attrs,
 };
 
-static struct attribute_group *default_subch_attr_groups[] = {
+static const struct attribute_group *default_subch_attr_groups[] = {
 	&subch_attr_group,
 	NULL,
 };
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 0f95405..6527f3f 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -656,7 +656,7 @@ static struct attribute_group ccwdev_attr_group = {
 	.attrs = ccwdev_attrs,
 };
 
-static struct attribute_group *ccwdev_attr_groups[] = {
+static const struct attribute_group *ccwdev_attr_groups[] = {
 	&ccwdev_attr_group,
 	NULL,
 };
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index f370f8d..c63babe 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -350,6 +350,8 @@ claw_tx(struct sk_buff *skb, struct net_device *dev)
 	CLAW_DBF_TEXT_(4, trace, "clawtx%d", rc);
 	if (rc)
 		rc = NETDEV_TX_BUSY;
+	else
+		rc = NETDEV_TX_OK;
         return rc;
 }   /*  end of claw_tx */
 
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 222e473..c5b8387 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -164,7 +164,6 @@ void ctcm_unpack_skb(struct channel *ch, struct sk_buff *pskb)
 		priv->stats.rx_packets++;
 		priv->stats.rx_bytes += skblen;
 		netif_rx_ni(skb);
-		dev->last_rx = jiffies;
 		if (len > 0) {
 			skb_pull(pskb, header->length);
 			if (skb_tailroom(pskb) < LL_HEADER_LENGTH) {
@@ -880,7 +879,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 				"%s(%s): NULL sk_buff passed",
 					CTCM_FUNTAIL, dev->name);
 		priv->stats.tx_dropped++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (skb_headroom(skb) < (LL_HEADER_LENGTH + 2)) {
 		CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR,
@@ -888,7 +887,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 			CTCM_FUNTAIL, dev->name, LL_HEADER_LENGTH + 2);
 		dev_kfree_skb(skb);
 		priv->stats.tx_dropped++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/*
@@ -901,7 +900,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 		priv->stats.tx_dropped++;
 		priv->stats.tx_errors++;
 		priv->stats.tx_carrier_errors++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (ctcm_test_and_set_busy(dev))
@@ -910,7 +909,7 @@ static int ctcm_tx(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 	if (ctcm_transmit_skb(priv->channel[WRITE], skb) != 0)
 		return NETDEV_TX_BUSY;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* unmerged MPC variant of ctcm_tx */
@@ -1008,7 +1007,7 @@ done:
 	if (do_debug)
 		MPC_DBF_DEV_NAME(TRACE, dev, "exit");
 
-	return 0;	/* handle freeing of skb here */
+	return NETDEV_TX_OK;	/* handle freeing of skb here */
 }
 
 
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 8c67590..a70de9b 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1553,24 +1553,24 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
 		 struct net_device *dev)
 {
 	struct lcs_header *header;
-	int rc = 0;
+	int rc = NETDEV_TX_OK;
 
 	LCS_DBF_TEXT(5, trace, "hardxmit");
 	if (skb == NULL) {
 		card->stats.tx_dropped++;
 		card->stats.tx_errors++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (card->state != DEV_STATE_UP) {
 		dev_kfree_skb(skb);
 		card->stats.tx_dropped++;
 		card->stats.tx_errors++;
 		card->stats.tx_carrier_errors++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (skb->protocol == htons(ETH_P_IPV6)) {
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	netif_stop_queue(card->dev);
 	spin_lock(&card->lock);
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 87dff11..a4b2c57 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -676,7 +676,6 @@ static void netiucv_unpack_skb(struct iucv_connection *conn,
 		 * we must use netif_rx_ni() instead of netif_rx()
 		 */
 		netif_rx_ni(skb);
-		dev->last_rx = jiffies;
 		skb_pull(pskb, header->next);
 		skb_put(pskb, NETIUCV_HDRLEN);
 	}
@@ -1376,14 +1375,14 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
 	if (skb == NULL) {
 		IUCV_DBF_TEXT(data, 2, "netiucv_tx: skb is NULL\n");
 		privptr->stats.tx_dropped++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (skb_headroom(skb) < NETIUCV_HDRLEN) {
 		IUCV_DBF_TEXT(data, 2,
 			"netiucv_tx: skb_headroom < NETIUCV_HDRLEN\n");
 		dev_kfree_skb(skb);
 		privptr->stats.tx_dropped++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/**
@@ -1395,7 +1394,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
 		privptr->stats.tx_dropped++;
 		privptr->stats.tx_errors++;
 		privptr->stats.tx_carrier_errors++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	if (netiucv_test_and_set_busy(dev)) {
@@ -2160,7 +2159,7 @@ static struct attribute_group netiucv_drv_attr_group = {
 	.attrs = netiucv_drv_attrs,
 };
 
-static struct attribute_group *netiucv_drv_attr_groups[] = {
+static const struct attribute_group *netiucv_drv_attr_groups[] = {
 	&netiucv_drv_attr_group,
 	NULL,
 };
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 447e1d1..31a2b4e 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -435,6 +435,7 @@ struct qeth_qdio_out_q {
 	 * index of buffer to be filled by driver; state EMPTY or PACKING
 	 */
 	int next_buf_to_fill;
+	int sync_iqdio_error;
 	/*
 	 * number of buffers that are currently filled (PRIMED)
 	 * -> these buffers are hardware-owned
@@ -685,6 +686,14 @@ struct qeth_mc_mac {
 	int is_vmac;
 };
 
+struct qeth_skb_data {
+	__u32 magic;
+	int count;
+};
+
+#define QETH_SKB_MAGIC 0x71657468
+#define QETH_SIGA_CC2_RETRIES 3
+
 struct qeth_card {
 	struct list_head list;
 	enum qeth_card_states state;
@@ -834,7 +843,6 @@ int qeth_default_setadapterparms_cb(struct qeth_card *, struct qeth_reply *,
 int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
 	int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long),
 	void *reply_param);
-int qeth_get_cast_type(struct qeth_card *, struct sk_buff *);
 int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int);
 int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int);
 int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *,
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index d53621c..c4a42d9 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -927,8 +927,8 @@ out:
 	return;
 }
 
-static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
-		 struct qeth_qdio_out_buffer *buf)
+static void __qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
+		 struct qeth_qdio_out_buffer *buf, unsigned int qeth_skip_skb)
 {
 	int i;
 	struct sk_buff *skb;
@@ -937,11 +937,13 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
 	if (buf->buffer->element[0].flags & 0x40)
 		atomic_dec(&queue->set_pci_flags_count);
 
-	skb = skb_dequeue(&buf->skb_list);
-	while (skb) {
-		atomic_dec(&skb->users);
-		dev_kfree_skb_any(skb);
+	if (!qeth_skip_skb) {
 		skb = skb_dequeue(&buf->skb_list);
+		while (skb) {
+			atomic_dec(&skb->users);
+			dev_kfree_skb_any(skb);
+			skb = skb_dequeue(&buf->skb_list);
+		}
 	}
 	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i) {
 		if (buf->buffer->element[i].addr && buf->is_header[i])
@@ -957,6 +959,12 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
 	atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
 }
 
+static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
+		struct qeth_qdio_out_buffer *buf)
+{
+	__qeth_clear_output_buffer(queue, buf, 0);
+}
+
 void qeth_clear_qdio_buffers(struct qeth_card *card)
 {
 	int i, j;
@@ -1152,8 +1160,9 @@ static void qeth_core_sl_print(struct seq_file *m, struct service_level *slr)
 {
 	struct qeth_card *card = container_of(slr, struct qeth_card,
 					qeth_service_level);
-	seq_printf(m, "qeth: %s firmware level %s\n", CARD_BUS_ID(card),
-			card->info.mcl_level);
+	if (card->info.mcl_level[0])
+		seq_printf(m, "qeth: %s firmware level %s\n",
+			CARD_BUS_ID(card), card->info.mcl_level);
 }
 
 static struct qeth_card *qeth_alloc_card(void)
@@ -2685,6 +2694,13 @@ static int qeth_handle_send_error(struct qeth_card *card,
 	int sbalf15 = buffer->buffer->element[15].flags & 0xff;
 
 	QETH_DBF_TEXT(TRACE, 6, "hdsnderr");
+	if (card->info.type == QETH_CARD_TYPE_IQD) {
+		if (sbalf15 == 0) {
+			qdio_err = 0;
+		} else {
+			qdio_err = 1;
+		}
+	}
 	qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
 
 	if (!qdio_err)
@@ -2817,6 +2833,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
 		}
 	}
 
+	queue->sync_iqdio_error = 0;
 	queue->card->dev->trans_start = jiffies;
 	if (queue->card->options.performance_stats) {
 		queue->card->perf_stats.outbound_do_qdio_cnt++;
@@ -2832,6 +2849,10 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
 		queue->card->perf_stats.outbound_do_qdio_time +=
 			qeth_get_micros() -
 			queue->card->perf_stats.outbound_do_qdio_start_time;
+	if (rc > 0) {
+		if (!(rc & QDIO_ERROR_SIGA_BUSY))
+			queue->sync_iqdio_error = rc & 3;
+	}
 	if (rc) {
 		queue->card->stats.tx_errors += count;
 		/* ignore temporary SIGA errors without busy condition */
@@ -2899,6 +2920,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
 	struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
 	struct qeth_qdio_out_buffer *buffer;
 	int i;
+	unsigned qeth_send_err;
 
 	QETH_DBF_TEXT(TRACE, 6, "qdouhdl");
 	if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) {
@@ -2915,8 +2937,9 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
 	}
 	for (i = first_element; i < (first_element + count); ++i) {
 		buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
-		qeth_handle_send_error(card, buffer, qdio_error);
-		qeth_clear_output_buffer(queue, buffer);
+		qeth_send_err = qeth_handle_send_error(card, buffer, qdio_error);
+		__qeth_clear_output_buffer(queue, buffer,
+			(qeth_send_err == QETH_SEND_ERROR_RETRY) ? 1 : 0);
 	}
 	atomic_sub(count, &queue->used_buffers);
 	/* check if we need to do something on this outbound queue */
@@ -2930,55 +2953,6 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
 }
 EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);
 
-int qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
-{
-	int cast_type = RTN_UNSPEC;
-
-	if (card->info.type == QETH_CARD_TYPE_OSN)
-		return cast_type;
-
-	if (skb_dst(skb) && skb_dst(skb)->neighbour) {
-		cast_type = skb_dst(skb)->neighbour->type;
-		if ((cast_type == RTN_BROADCAST) ||
-		    (cast_type == RTN_MULTICAST) ||
-		    (cast_type == RTN_ANYCAST))
-			return cast_type;
-		else
-			return RTN_UNSPEC;
-	}
-	/* try something else */
-	if (skb->protocol == ETH_P_IPV6)
-		return (skb_network_header(skb)[24] == 0xff) ?
-				RTN_MULTICAST : 0;
-	else if (skb->protocol == ETH_P_IP)
-		return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ?
-				RTN_MULTICAST : 0;
-	/* ... */
-	if (!memcmp(skb->data, skb->dev->broadcast, 6))
-		return RTN_BROADCAST;
-	else {
-		u16 hdr_mac;
-
-		hdr_mac = *((u16 *)skb->data);
-		/* tr multicast? */
-		switch (card->info.link_type) {
-		case QETH_LINK_TYPE_HSTR:
-		case QETH_LINK_TYPE_LANE_TR:
-			if ((hdr_mac == QETH_TR_MAC_NC) ||
-			    (hdr_mac == QETH_TR_MAC_C))
-				return RTN_MULTICAST;
-			break;
-		/* eth or so multicast? */
-		default:
-		if ((hdr_mac == QETH_ETH_MAC_V4) ||
-			    (hdr_mac == QETH_ETH_MAC_V6))
-				return RTN_MULTICAST;
-		}
-	}
-	return cast_type;
-}
-EXPORT_SYMBOL_GPL(qeth_get_cast_type);
-
 int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
 			int ipv, int cast_type)
 {
@@ -3159,7 +3133,10 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
 		int offset, int hd_len)
 {
 	struct qeth_qdio_out_buffer *buffer;
+	struct sk_buff *skb1;
+	struct qeth_skb_data *retry_ctrl;
 	int index;
+	int rc;
 
 	/* spin until we get the queue ... */
 	while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
@@ -3178,6 +3155,25 @@ int qeth_do_send_packet_fast(struct qeth_card *card,
 	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
 	qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
 	qeth_flush_buffers(queue, index, 1);
+	if (queue->sync_iqdio_error == 2) {
+		skb1 = skb_dequeue(&buffer->skb_list);
+		while (skb1) {
+			atomic_dec(&skb1->users);
+			skb1 = skb_dequeue(&buffer->skb_list);
+		}
+		retry_ctrl = (struct qeth_skb_data *) &skb->cb[16];
+		if (retry_ctrl->magic != QETH_SKB_MAGIC) {
+			retry_ctrl->magic = QETH_SKB_MAGIC;
+			retry_ctrl->count = 0;
+		}
+		if (retry_ctrl->count < QETH_SIGA_CC2_RETRIES) {
+			retry_ctrl->count++;
+			rc = dev_queue_xmit(skb);
+		} else {
+			dev_kfree_skb_any(skb);
+			QETH_DBF_TEXT(QERR, 2, "qrdrop");
+		}
+	}
 	return 0;
 out:
 	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 568465d..33505c2 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -364,7 +364,7 @@ static ssize_t qeth_dev_layer2_show(struct device *dev,
 	if (!card)
 		return -EINVAL;
 
-	return sprintf(buf, "%i\n", card->options.layer2 ? 1:0);
+	return sprintf(buf, "%i\n", card->options.layer2);
 }
 
 static ssize_t qeth_dev_layer2_store(struct device *dev,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 691cecd..f4f3ca1 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -216,36 +216,16 @@ static void qeth_l2_del_all_mc(struct qeth_card *card)
 	spin_unlock_bh(&card->mclock);
 }
 
-static void qeth_l2_get_packet_type(struct qeth_card *card,
-			struct qeth_hdr *hdr, struct sk_buff *skb)
+static inline int qeth_l2_get_cast_type(struct qeth_card *card,
+			struct sk_buff *skb)
 {
-	__u16 hdr_mac;
-
-	if (!memcmp(skb->data + QETH_HEADER_SIZE,
-		    skb->dev->broadcast, 6)) {
-		/* broadcast? */
-		hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_BROADCAST;
-		return;
-	}
-	hdr_mac = *((__u16 *)skb->data);
-	/* tr multicast? */
-	switch (card->info.link_type) {
-	case QETH_LINK_TYPE_HSTR:
-	case QETH_LINK_TYPE_LANE_TR:
-		if ((hdr_mac == QETH_TR_MAC_NC) ||
-		    (hdr_mac == QETH_TR_MAC_C))
-			hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
-		else
-			hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST;
-		break;
-		/* eth or so multicast? */
-	default:
-		if ((hdr_mac == QETH_ETH_MAC_V4) ||
-		     (hdr_mac == QETH_ETH_MAC_V6))
-			hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_MULTICAST;
-		else
-			hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST;
-	}
+	if (card->info.type == QETH_CARD_TYPE_OSN)
+		return RTN_UNSPEC;
+	if (is_broadcast_ether_addr(skb->data))
+		return RTN_BROADCAST;
+	if (is_multicast_ether_addr(skb->data))
+		return RTN_MULTICAST;
+	return RTN_UNSPEC;
 }
 
 static void qeth_l2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
@@ -262,7 +242,7 @@ static void qeth_l2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
 	else if (cast_type == RTN_BROADCAST)
 		hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_BROADCAST;
 	else
-		qeth_l2_get_packet_type(card, hdr, skb);
+		hdr->hdr.l2.flags[2] |= QETH_LAYER2_FLAG_UNICAST;
 
 	hdr->hdr.l2.pkt_length = skb->len-QETH_HEADER_SIZE;
 	/* VSWITCH relies on the VLAN
@@ -469,7 +449,6 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
 			QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN);
 			continue;
 		}
-		card->dev->last_rx = jiffies;
 		card->stats.rx_packets++;
 		card->stats.rx_bytes += len;
 	}
@@ -672,7 +651,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct qeth_card *card = dev->ml_priv;
 	struct sk_buff *new_skb = skb;
 	int ipv = qeth_get_ip_version(skb);
-	int cast_type = qeth_get_cast_type(card, skb);
+	int cast_type = qeth_l2_get_cast_type(card, skb);
 	struct qeth_qdio_out_q *queue = card->qdio.out_qs
 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
 	int tx_bytes = skb->len;
@@ -744,6 +723,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		card->stats.tx_bytes += tx_bytes;
 		if (new_skb != skb)
 			dev_kfree_skb_any(skb);
+		rc = NETDEV_TX_OK;
 	} else {
 		if (data_offset >= 0)
 			kmem_cache_free(qeth_core_header_cache, hdr);
@@ -882,7 +862,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
 	return;
 }
 
-static struct ethtool_ops qeth_l2_ethtool_ops = {
+static const struct ethtool_ops qeth_l2_ethtool_ops = {
 	.get_link = ethtool_op_get_link,
 	.get_strings = qeth_core_get_strings,
 	.get_ethtool_stats = qeth_core_get_ethtool_stats,
@@ -891,7 +871,7 @@ static struct ethtool_ops qeth_l2_ethtool_ops = {
 	.get_settings = qeth_core_ethtool_get_settings,
 };
 
-static struct ethtool_ops qeth_l2_osn_ops = {
+static const struct ethtool_ops qeth_l2_osn_ops = {
 	.get_strings = qeth_core_get_strings,
 	.get_ethtool_stats = qeth_core_get_ethtool_stats,
 	.get_stats_count = qeth_core_get_stats_count,
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 5487240..073b6d3 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1987,7 +1987,6 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card,
 			continue;
 		}
 
-		card->dev->last_rx = jiffies;
 		card->stats.rx_packets++;
 		card->stats.rx_bytes += len;
 	}
@@ -2525,6 +2524,51 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 	return rc;
 }
 
+int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
+{
+	int cast_type = RTN_UNSPEC;
+
+	if (skb_dst(skb) && skb_dst(skb)->neighbour) {
+		cast_type = skb_dst(skb)->neighbour->type;
+		if ((cast_type == RTN_BROADCAST) ||
+		    (cast_type == RTN_MULTICAST) ||
+		    (cast_type == RTN_ANYCAST))
+			return cast_type;
+		else
+			return RTN_UNSPEC;
+	}
+	/* try something else */
+	if (skb->protocol == ETH_P_IPV6)
+		return (skb_network_header(skb)[24] == 0xff) ?
+				RTN_MULTICAST : 0;
+	else if (skb->protocol == ETH_P_IP)
+		return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ?
+				RTN_MULTICAST : 0;
+	/* ... */
+	if (!memcmp(skb->data, skb->dev->broadcast, 6))
+		return RTN_BROADCAST;
+	else {
+		u16 hdr_mac;
+
+		hdr_mac = *((u16 *)skb->data);
+		/* tr multicast? */
+		switch (card->info.link_type) {
+		case QETH_LINK_TYPE_HSTR:
+		case QETH_LINK_TYPE_LANE_TR:
+			if ((hdr_mac == QETH_TR_MAC_NC) ||
+			    (hdr_mac == QETH_TR_MAC_C))
+				return RTN_MULTICAST;
+			break;
+		/* eth or so multicast? */
+		default:
+		if ((hdr_mac == QETH_ETH_MAC_V4) ||
+			    (hdr_mac == QETH_ETH_MAC_V6))
+				return RTN_MULTICAST;
+		}
+	}
+	return cast_type;
+}
+
 static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
 		struct sk_buff *skb, int ipv, int cast_type)
 {
@@ -2650,7 +2694,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct qeth_card *card = dev->ml_priv;
 	struct sk_buff *new_skb = NULL;
 	int ipv = qeth_get_ip_version(skb);
-	int cast_type = qeth_get_cast_type(card, skb);
+	int cast_type = qeth_l3_get_cast_type(card, skb);
 	struct qeth_qdio_out_q *queue = card->qdio.out_qs
 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
 	int tx_bytes = skb->len;
@@ -2793,6 +2837,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 				card->perf_stats.sg_frags_sent += nr_frags + 1;
 			}
 		}
+		rc = NETDEV_TX_OK;
 	} else {
 		if (data_offset >= 0)
 			kmem_cache_free(qeth_core_header_cache, hdr);
@@ -2900,7 +2945,7 @@ static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
 	return 0;
 }
 
-static struct ethtool_ops qeth_l3_ethtool_ops = {
+static const struct ethtool_ops qeth_l3_ethtool_ops = {
 	.get_link = ethtool_op_get_link,
 	.get_tx_csum = ethtool_op_get_tx_csum,
 	.set_tx_csum = ethtool_op_set_tx_hw_csum,
@@ -3179,6 +3224,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
 	netif_carrier_on(card->dev);
 
 	qeth_set_allowed_threads(card, 0xffffffff, 0);
+	qeth_l3_set_ip_addr_list(card);
 	if (recover_flag == CARD_STATE_RECOVER) {
 		if (recovery_mode)
 			qeth_l3_open(card->dev);
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 2ccbd18..1be6bf7 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -42,6 +42,12 @@ static char *init_device;
 module_param_named(device, init_device, charp, 0400);
 MODULE_PARM_DESC(device, "specify initial device");
 
+static struct kmem_cache *zfcp_cache_hw_align(const char *name,
+					      unsigned long size)
+{
+	return kmem_cache_create(name, size, roundup_pow_of_two(size), 0, NULL);
+}
+
 static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter)
 {
 	int idx;
@@ -78,7 +84,7 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
 	struct zfcp_port *port;
 	struct zfcp_unit *unit;
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	read_lock_irq(&zfcp_data.config_lock);
 	adapter = zfcp_get_adapter_by_busid(busid);
 	if (adapter)
@@ -93,31 +99,23 @@ static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
 	unit = zfcp_unit_enqueue(port, lun);
 	if (IS_ERR(unit))
 		goto out_unit;
-	up(&zfcp_data.config_sema);
+	mutex_unlock(&zfcp_data.config_mutex);
 	ccw_device_set_online(adapter->ccw_device);
 
 	zfcp_erp_wait(adapter);
 	flush_work(&unit->scsi_work);
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	zfcp_unit_put(unit);
 out_unit:
 	zfcp_port_put(port);
 out_port:
 	zfcp_adapter_put(adapter);
 out_adapter:
-	up(&zfcp_data.config_sema);
+	mutex_unlock(&zfcp_data.config_mutex);
 	return;
 }
 
-static struct kmem_cache *zfcp_cache_create(int size, char *name)
-{
-	int align = 1;
-	while ((size - align) > 0)
-		align <<= 1;
-	return kmem_cache_create(name , size, align, 0, NULL);
-}
-
 static void __init zfcp_init_device_setup(char *devstr)
 {
 	char *token;
@@ -158,24 +156,27 @@ static int __init zfcp_module_init(void)
 {
 	int retval = -ENOMEM;
 
-	zfcp_data.fsf_req_qtcb_cache = zfcp_cache_create(
-			sizeof(struct zfcp_fsf_req_qtcb), "zfcp_fsf");
-	if (!zfcp_data.fsf_req_qtcb_cache)
+	zfcp_data.gpn_ft_cache = zfcp_cache_hw_align("zfcp_gpn",
+					sizeof(struct ct_iu_gpn_ft_req));
+	if (!zfcp_data.gpn_ft_cache)
 		goto out;
 
-	zfcp_data.sr_buffer_cache = zfcp_cache_create(
-			sizeof(struct fsf_status_read_buffer), "zfcp_sr");
+	zfcp_data.qtcb_cache = zfcp_cache_hw_align("zfcp_qtcb",
+					sizeof(struct fsf_qtcb));
+	if (!zfcp_data.qtcb_cache)
+		goto out_qtcb_cache;
+
+	zfcp_data.sr_buffer_cache = zfcp_cache_hw_align("zfcp_sr",
+					sizeof(struct fsf_status_read_buffer));
 	if (!zfcp_data.sr_buffer_cache)
 		goto out_sr_cache;
 
-	zfcp_data.gid_pn_cache = zfcp_cache_create(
-			sizeof(struct zfcp_gid_pn_data), "zfcp_gid");
+	zfcp_data.gid_pn_cache = zfcp_cache_hw_align("zfcp_gid",
+					sizeof(struct zfcp_gid_pn_data));
 	if (!zfcp_data.gid_pn_cache)
 		goto out_gid_cache;
 
-	zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq");
-
-	sema_init(&zfcp_data.config_sema, 1);
+	mutex_init(&zfcp_data.config_mutex);
 	rwlock_init(&zfcp_data.config_lock);
 
 	zfcp_data.scsi_transport_template =
@@ -209,7 +210,9 @@ out_transport:
 out_gid_cache:
 	kmem_cache_destroy(zfcp_data.sr_buffer_cache);
 out_sr_cache:
-	kmem_cache_destroy(zfcp_data.fsf_req_qtcb_cache);
+	kmem_cache_destroy(zfcp_data.qtcb_cache);
+out_qtcb_cache:
+	kmem_cache_destroy(zfcp_data.gpn_ft_cache);
 out:
 	return retval;
 }
@@ -263,7 +266,7 @@ static void zfcp_sysfs_unit_release(struct device *dev)
  * @port: pointer to port where unit is added
  * @fcp_lun: FCP LUN of unit to be enqueued
  * Returns: pointer to enqueued unit on success, ERR_PTR on error
- * Locks: config_sema must be held to serialize changes to the unit list
+ * Locks: config_mutex must be held to serialize changes to the unit list
  *
  * Sets up some unit internal structures and creates sysfs entry.
  */
@@ -271,6 +274,13 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
 {
 	struct zfcp_unit *unit;
 
+	read_lock_irq(&zfcp_data.config_lock);
+	if (zfcp_get_unit_by_lun(port, fcp_lun)) {
+		read_unlock_irq(&zfcp_data.config_lock);
+		return ERR_PTR(-EINVAL);
+	}
+	read_unlock_irq(&zfcp_data.config_lock);
+
 	unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL);
 	if (!unit)
 		return ERR_PTR(-ENOMEM);
@@ -282,8 +292,11 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
 	unit->port = port;
 	unit->fcp_lun = fcp_lun;
 
-	dev_set_name(&unit->sysfs_device, "0x%016llx",
-		     (unsigned long long) fcp_lun);
+	if (dev_set_name(&unit->sysfs_device, "0x%016llx",
+			 (unsigned long long) fcp_lun)) {
+		kfree(unit);
+		return ERR_PTR(-ENOMEM);
+	}
 	unit->sysfs_device.parent = &port->sysfs_device;
 	unit->sysfs_device.release = zfcp_sysfs_unit_release;
 	dev_set_drvdata(&unit->sysfs_device, unit);
@@ -299,20 +312,15 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
 	unit->latencies.cmd.channel.min = 0xFFFFFFFF;
 	unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
 
-	read_lock_irq(&zfcp_data.config_lock);
-	if (zfcp_get_unit_by_lun(port, fcp_lun)) {
-		read_unlock_irq(&zfcp_data.config_lock);
-		goto err_out_free;
+	if (device_register(&unit->sysfs_device)) {
+		put_device(&unit->sysfs_device);
+		return ERR_PTR(-EINVAL);
 	}
-	read_unlock_irq(&zfcp_data.config_lock);
-
-	if (device_register(&unit->sysfs_device))
-		goto err_out_free;
 
 	if (sysfs_create_group(&unit->sysfs_device.kobj,
 			       &zfcp_sysfs_unit_attrs)) {
 		device_unregister(&unit->sysfs_device);
-		return ERR_PTR(-EIO);
+		return ERR_PTR(-EINVAL);
 	}
 
 	zfcp_unit_get(unit);
@@ -327,10 +335,6 @@ struct zfcp_unit *zfcp_unit_enqueue(struct zfcp_port *port, u64 fcp_lun)
 	zfcp_port_get(port);
 
 	return unit;
-
-err_out_free:
-	kfree(unit);
-	return ERR_PTR(-EINVAL);
 }
 
 /**
@@ -353,37 +357,47 @@ void zfcp_unit_dequeue(struct zfcp_unit *unit)
 
 static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
 {
-	/* must only be called with zfcp_data.config_sema taken */
-	adapter->pool.fsf_req_erp =
-		mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache);
-	if (!adapter->pool.fsf_req_erp)
+	/* must only be called with zfcp_data.config_mutex taken */
+	adapter->pool.erp_req =
+		mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
+	if (!adapter->pool.erp_req)
+		return -ENOMEM;
+
+	adapter->pool.gid_pn_req =
+		mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
+	if (!adapter->pool.gid_pn_req)
 		return -ENOMEM;
 
-	adapter->pool.fsf_req_scsi =
-		mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache);
-	if (!adapter->pool.fsf_req_scsi)
+	adapter->pool.scsi_req =
+		mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
+	if (!adapter->pool.scsi_req)
 		return -ENOMEM;
 
-	adapter->pool.fsf_req_abort =
-		mempool_create_slab_pool(1, zfcp_data.fsf_req_qtcb_cache);
-	if (!adapter->pool.fsf_req_abort)
+	adapter->pool.scsi_abort =
+		mempool_create_kmalloc_pool(1, sizeof(struct zfcp_fsf_req));
+	if (!adapter->pool.scsi_abort)
 		return -ENOMEM;
 
-	adapter->pool.fsf_req_status_read =
+	adapter->pool.status_read_req =
 		mempool_create_kmalloc_pool(FSF_STATUS_READS_RECOM,
 					    sizeof(struct zfcp_fsf_req));
-	if (!adapter->pool.fsf_req_status_read)
+	if (!adapter->pool.status_read_req)
 		return -ENOMEM;
 
-	adapter->pool.data_status_read =
+	adapter->pool.qtcb_pool =
+		mempool_create_slab_pool(4, zfcp_data.qtcb_cache);
+	if (!adapter->pool.qtcb_pool)
+		return -ENOMEM;
+
+	adapter->pool.status_read_data =
 		mempool_create_slab_pool(FSF_STATUS_READS_RECOM,
 					 zfcp_data.sr_buffer_cache);
-	if (!adapter->pool.data_status_read)
+	if (!adapter->pool.status_read_data)
 		return -ENOMEM;
 
-	adapter->pool.data_gid_pn =
+	adapter->pool.gid_pn_data =
 		mempool_create_slab_pool(1, zfcp_data.gid_pn_cache);
-	if (!adapter->pool.data_gid_pn)
+	if (!adapter->pool.gid_pn_data)
 		return -ENOMEM;
 
 	return 0;
@@ -391,19 +405,21 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
 
 static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
 {
-	/* zfcp_data.config_sema must be held */
-	if (adapter->pool.fsf_req_erp)
-		mempool_destroy(adapter->pool.fsf_req_erp);
-	if (adapter->pool.fsf_req_scsi)
-		mempool_destroy(adapter->pool.fsf_req_scsi);
-	if (adapter->pool.fsf_req_abort)
-		mempool_destroy(adapter->pool.fsf_req_abort);
-	if (adapter->pool.fsf_req_status_read)
-		mempool_destroy(adapter->pool.fsf_req_status_read);
-	if (adapter->pool.data_status_read)
-		mempool_destroy(adapter->pool.data_status_read);
-	if (adapter->pool.data_gid_pn)
-		mempool_destroy(adapter->pool.data_gid_pn);
+	/* zfcp_data.config_mutex must be held */
+	if (adapter->pool.erp_req)
+		mempool_destroy(adapter->pool.erp_req);
+	if (adapter->pool.scsi_req)
+		mempool_destroy(adapter->pool.scsi_req);
+	if (adapter->pool.scsi_abort)
+		mempool_destroy(adapter->pool.scsi_abort);
+	if (adapter->pool.qtcb_pool)
+		mempool_destroy(adapter->pool.qtcb_pool);
+	if (adapter->pool.status_read_req)
+		mempool_destroy(adapter->pool.status_read_req);
+	if (adapter->pool.status_read_data)
+		mempool_destroy(adapter->pool.status_read_data);
+	if (adapter->pool.gid_pn_data)
+		mempool_destroy(adapter->pool.gid_pn_data);
 }
 
 /**
@@ -418,7 +434,7 @@ static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
 int zfcp_status_read_refill(struct zfcp_adapter *adapter)
 {
 	while (atomic_read(&adapter->stat_miss) > 0)
-		if (zfcp_fsf_status_read(adapter)) {
+		if (zfcp_fsf_status_read(adapter->qdio)) {
 			if (atomic_read(&adapter->stat_miss) >= 16) {
 				zfcp_erp_adapter_reopen(adapter, 0, "axsref1",
 							NULL);
@@ -446,6 +462,27 @@ static void zfcp_print_sl(struct seq_file *m, struct service_level *sl)
 		   adapter->fsf_lic_version);
 }
 
+static int zfcp_setup_adapter_work_queue(struct zfcp_adapter *adapter)
+{
+	char name[TASK_COMM_LEN];
+
+	snprintf(name, sizeof(name), "zfcp_q_%s",
+		 dev_name(&adapter->ccw_device->dev));
+	adapter->work_queue = create_singlethread_workqueue(name);
+
+	if (adapter->work_queue)
+		return 0;
+	return -ENOMEM;
+}
+
+static void zfcp_destroy_adapter_work_queue(struct zfcp_adapter *adapter)
+{
+	if (adapter->work_queue)
+		destroy_workqueue(adapter->work_queue);
+	adapter->work_queue = NULL;
+
+}
+
 /**
  * zfcp_adapter_enqueue - enqueue a new adapter to the list
  * @ccw_device: pointer to the struct cc_device
@@ -455,7 +492,7 @@ static void zfcp_print_sl(struct seq_file *m, struct service_level *sl)
  * Enqueues an adapter at the end of the adapter list in the driver data.
  * All adapter internal structures are set up.
  * Proc-fs entries are also created.
- * locks:	config_sema must be held to serialise changes to the adapter list
+ * locks: config_mutex must be held to serialize changes to the adapter list
  */
 int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 {
@@ -463,37 +500,37 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 
 	/*
 	 * Note: It is safe to release the list_lock, as any list changes
-	 * are protected by the config_sema, which must be held to get here
+	 * are protected by the config_mutex, which must be held to get here
 	 */
 
 	adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL);
 	if (!adapter)
 		return -ENOMEM;
 
-	adapter->gs = kzalloc(sizeof(struct zfcp_wka_ports), GFP_KERNEL);
-	if (!adapter->gs) {
-		kfree(adapter);
-		return -ENOMEM;
-	}
-
 	ccw_device->handler = NULL;
 	adapter->ccw_device = ccw_device;
 	atomic_set(&adapter->refcount, 0);
 
-	if (zfcp_qdio_allocate(adapter))
-		goto qdio_allocate_failed;
+	if (zfcp_qdio_setup(adapter))
+		goto qdio_failed;
 
 	if (zfcp_allocate_low_mem_buffers(adapter))
-		goto failed_low_mem_buffers;
+		goto low_mem_buffers_failed;
 
 	if (zfcp_reqlist_alloc(adapter))
-		goto failed_low_mem_buffers;
+		goto low_mem_buffers_failed;
 
-	if (zfcp_adapter_debug_register(adapter))
+	if (zfcp_dbf_adapter_register(adapter))
 		goto debug_register_failed;
 
+	if (zfcp_setup_adapter_work_queue(adapter))
+		goto work_queue_failed;
+
+	if (zfcp_fc_gs_setup(adapter))
+		goto generic_services_failed;
+
 	init_waitqueue_head(&adapter->remove_wq);
-	init_waitqueue_head(&adapter->erp_thread_wqh);
+	init_waitqueue_head(&adapter->erp_ready_wq);
 	init_waitqueue_head(&adapter->erp_done_wqh);
 
 	INIT_LIST_HEAD(&adapter->port_list_head);
@@ -502,20 +539,14 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 
 	spin_lock_init(&adapter->req_list_lock);
 
-	spin_lock_init(&adapter->hba_dbf_lock);
-	spin_lock_init(&adapter->san_dbf_lock);
-	spin_lock_init(&adapter->scsi_dbf_lock);
-	spin_lock_init(&adapter->rec_dbf_lock);
-	spin_lock_init(&adapter->req_q_lock);
-	spin_lock_init(&adapter->qdio_stat_lock);
-
 	rwlock_init(&adapter->erp_lock);
 	rwlock_init(&adapter->abort_lock);
 
-	sema_init(&adapter->erp_ready_sem, 0);
+	if (zfcp_erp_thread_setup(adapter))
+		goto erp_thread_failed;
 
 	INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
-	INIT_WORK(&adapter->scan_work, _zfcp_scan_ports_later);
+	INIT_WORK(&adapter->scan_work, _zfcp_fc_scan_ports_later);
 
 	adapter->service_level.seq_print = zfcp_print_sl;
 
@@ -529,20 +560,25 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 		goto sysfs_failed;
 
 	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status);
-	zfcp_fc_wka_ports_init(adapter);
 
 	if (!zfcp_adapter_scsi_register(adapter))
 		return 0;
 
 sysfs_failed:
-	zfcp_adapter_debug_unregister(adapter);
+	zfcp_erp_thread_kill(adapter);
+erp_thread_failed:
+	zfcp_fc_gs_destroy(adapter);
+generic_services_failed:
+	zfcp_destroy_adapter_work_queue(adapter);
+work_queue_failed:
+	zfcp_dbf_adapter_unregister(adapter->dbf);
 debug_register_failed:
 	dev_set_drvdata(&ccw_device->dev, NULL);
 	kfree(adapter->req_list);
-failed_low_mem_buffers:
+low_mem_buffers_failed:
 	zfcp_free_low_mem_buffers(adapter);
-qdio_allocate_failed:
-	zfcp_qdio_free(adapter);
+qdio_failed:
+	zfcp_qdio_destroy(adapter->qdio);
 	kfree(adapter);
 	return -ENOMEM;
 }
@@ -559,6 +595,7 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
 
 	cancel_work_sync(&adapter->scan_work);
 	cancel_work_sync(&adapter->stat_work);
+	zfcp_fc_wka_ports_force_offline(adapter->gs);
 	zfcp_adapter_scsi_unregister(adapter);
 	sysfs_remove_group(&adapter->ccw_device->dev.kobj,
 			   &zfcp_sysfs_adapter_attrs);
@@ -570,13 +607,15 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
 	if (!retval)
 		return;
 
-	zfcp_adapter_debug_unregister(adapter);
-	zfcp_qdio_free(adapter);
+	zfcp_fc_gs_destroy(adapter);
+	zfcp_erp_thread_kill(adapter);
+	zfcp_destroy_adapter_work_queue(adapter);
+	zfcp_dbf_adapter_unregister(adapter->dbf);
 	zfcp_free_low_mem_buffers(adapter);
+	zfcp_qdio_destroy(adapter->qdio);
 	kfree(adapter->req_list);
 	kfree(adapter->fc_stats);
 	kfree(adapter->stats_reset_data);
-	kfree(adapter->gs);
 	kfree(adapter);
 }
 
@@ -592,7 +631,7 @@ static void zfcp_sysfs_port_release(struct device *dev)
  * @status: initial status for the port
  * @d_id: destination id of the remote port to be enqueued
  * Returns: pointer to enqueued port on success, ERR_PTR on error
- * Locks: config_sema must be held to serialize changes to the port list
+ * Locks: config_mutex must be held to serialize changes to the port list
  *
  * All port internal structures are set up and the sysfs entry is generated.
  * d_id is used to enqueue ports with a well known address like the Directory
@@ -602,7 +641,13 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
 				     u32 status, u32 d_id)
 {
 	struct zfcp_port *port;
-	int retval;
+
+	read_lock_irq(&zfcp_data.config_lock);
+	if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
+		read_unlock_irq(&zfcp_data.config_lock);
+		return ERR_PTR(-EINVAL);
+	}
+	read_unlock_irq(&zfcp_data.config_lock);
 
 	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
 	if (!port)
@@ -610,7 +655,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
 
 	init_waitqueue_head(&port->remove_wq);
 	INIT_LIST_HEAD(&port->unit_list_head);
-	INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup);
+	INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
 	INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
 	INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
 
@@ -623,29 +668,24 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
 	atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
 	atomic_set(&port->refcount, 0);
 
-	dev_set_name(&port->sysfs_device, "0x%016llx",
-		     (unsigned long long)wwpn);
+	if (dev_set_name(&port->sysfs_device, "0x%016llx",
+			 (unsigned long long)wwpn)) {
+		kfree(port);
+		return ERR_PTR(-ENOMEM);
+	}
 	port->sysfs_device.parent = &adapter->ccw_device->dev;
-
 	port->sysfs_device.release = zfcp_sysfs_port_release;
 	dev_set_drvdata(&port->sysfs_device, port);
 
-	read_lock_irq(&zfcp_data.config_lock);
-	if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
-		read_unlock_irq(&zfcp_data.config_lock);
-		goto err_out_free;
+	if (device_register(&port->sysfs_device)) {
+		put_device(&port->sysfs_device);
+		return ERR_PTR(-EINVAL);
 	}
-	read_unlock_irq(&zfcp_data.config_lock);
 
-	if (device_register(&port->sysfs_device))
-		goto err_out_free;
-
-	retval = sysfs_create_group(&port->sysfs_device.kobj,
-				    &zfcp_sysfs_port_attrs);
-
-	if (retval) {
+	if (sysfs_create_group(&port->sysfs_device.kobj,
+			       &zfcp_sysfs_port_attrs)) {
 		device_unregister(&port->sysfs_device);
-		goto err_out;
+		return ERR_PTR(-EINVAL);
 	}
 
 	zfcp_port_get(port);
@@ -659,11 +699,6 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
 
 	zfcp_adapter_get(adapter);
 	return port;
-
-err_out_free:
-	kfree(port);
-err_out:
-	return ERR_PTR(-EINVAL);
 }
 
 /**
@@ -672,12 +707,11 @@ err_out:
  */
 void zfcp_port_dequeue(struct zfcp_port *port)
 {
-	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
 	write_lock_irq(&zfcp_data.config_lock);
 	list_del(&port->list);
 	write_unlock_irq(&zfcp_data.config_lock);
-	if (port->rport)
-		port->rport->dd_data = NULL;
+	wait_event(port->remove_wq, atomic_read(&port->refcount) == 0);
+	cancel_work_sync(&port->rport_work); /* usually not necessary */
 	zfcp_adapter_put(port->adapter);
 	sysfs_remove_group(&port->sysfs_device.kobj, &zfcp_sysfs_port_attrs);
 	device_unregister(&port->sysfs_device);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index d9da5c4..0c90f8e 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -18,12 +18,15 @@ static int zfcp_ccw_suspend(struct ccw_device *cdev)
 {
 	struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
 
-	down(&zfcp_data.config_sema);
+	if (!adapter)
+		return 0;
+
+	mutex_lock(&zfcp_data.config_mutex);
 
 	zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL);
 	zfcp_erp_wait(adapter);
 
-	up(&zfcp_data.config_sema);
+	mutex_unlock(&zfcp_data.config_mutex);
 
 	return 0;
 }
@@ -33,6 +36,9 @@ static int zfcp_ccw_activate(struct ccw_device *cdev)
 {
 	struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
 
+	if (!adapter)
+		return 0;
+
 	zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL,
 				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
@@ -63,25 +69,14 @@ int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter)
  * zfcp_ccw_probe - probe function of zfcp driver
  * @ccw_device: pointer to belonging ccw device
  *
- * This function gets called by the common i/o layer and sets up the initial
- * data structures for each fcp adapter, which was detected by the system.
- * Also the sysfs files for this adapter will be created by this function.
- * In addition the nameserver port will be added to the ports of the adapter
- * and its sysfs representation will be created too.
+ * This function gets called by the common i/o layer for each FCP
+ * device found on the current system. This is only a stub to make cio
+ * work: To only allocate adapter resources for devices actually used,
+ * the allocation is deferred to the first call to ccw_set_online.
  */
 static int zfcp_ccw_probe(struct ccw_device *ccw_device)
 {
-	int retval = 0;
-
-	down(&zfcp_data.config_sema);
-	if (zfcp_adapter_enqueue(ccw_device)) {
-		dev_err(&ccw_device->dev,
-			"Setting up data structures for the "
-			"FCP adapter failed\n");
-		retval = -EINVAL;
-	}
-	up(&zfcp_data.config_sema);
-	return retval;
+	return 0;
 }
 
 /**
@@ -102,8 +97,11 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
 	LIST_HEAD(port_remove_lh);
 
 	ccw_device_set_offline(ccw_device);
-	down(&zfcp_data.config_sema);
+
+	mutex_lock(&zfcp_data.config_mutex);
 	adapter = dev_get_drvdata(&ccw_device->dev);
+	if (!adapter)
+		goto out;
 
 	write_lock_irq(&zfcp_data.config_lock);
 	list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
@@ -129,29 +127,41 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
 	wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
 	zfcp_adapter_dequeue(adapter);
 
-	up(&zfcp_data.config_sema);
+out:
+	mutex_unlock(&zfcp_data.config_mutex);
 }
 
 /**
  * zfcp_ccw_set_online - set_online function of zfcp driver
  * @ccw_device: pointer to belonging ccw device
  *
- * This function gets called by the common i/o layer and sets an adapter
- * into state online. Setting an fcp device online means that it will be
- * registered with the SCSI stack, that the QDIO queues will be set up
- * and that the adapter will be opened (asynchronously).
+ * This function gets called by the common i/o layer and sets an
+ * adapter into state online.  The first call will allocate all
+ * adapter resources that will be retained until the device is removed
+ * via zfcp_ccw_remove.
+ *
+ * Setting an fcp device online means that it will be registered with
+ * the SCSI stack, that the QDIO queues will be set up and that the
+ * adapter will be opened.
  */
 static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
 {
 	struct zfcp_adapter *adapter;
-	int retval;
+	int ret = 0;
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	adapter = dev_get_drvdata(&ccw_device->dev);
 
-	retval = zfcp_erp_thread_setup(adapter);
-	if (retval)
-		goto out;
+	if (!adapter) {
+		ret = zfcp_adapter_enqueue(ccw_device);
+		if (ret) {
+			dev_err(&ccw_device->dev,
+				"Setting up data structures for the "
+				"FCP adapter failed\n");
+			goto out;
+		}
+		adapter = dev_get_drvdata(&ccw_device->dev);
+	}
 
 	/* initialize request counter */
 	BUG_ON(!zfcp_reqlist_isempty(adapter));
@@ -162,13 +172,11 @@ static int zfcp_ccw_set_online(struct ccw_device *ccw_device)
 	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
 				"ccsonl2", NULL);
 	zfcp_erp_wait(adapter);
-	up(&zfcp_data.config_sema);
-	flush_work(&adapter->scan_work);
-	return 0;
-
- out:
-	up(&zfcp_data.config_sema);
-	return retval;
+out:
+	mutex_unlock(&zfcp_data.config_mutex);
+	if (!ret)
+		flush_work(&adapter->scan_work);
+	return ret;
 }
 
 /**
@@ -182,12 +190,15 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
 {
 	struct zfcp_adapter *adapter;
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	adapter = dev_get_drvdata(&ccw_device->dev);
+	if (!adapter)
+		goto out;
+
 	zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
 	zfcp_erp_wait(adapter);
-	zfcp_erp_thread_kill(adapter);
-	up(&zfcp_data.config_sema);
+	mutex_unlock(&zfcp_data.config_mutex);
+out:
 	return 0;
 }
 
@@ -240,11 +251,12 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
 {
 	struct zfcp_adapter *adapter;
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	adapter = dev_get_drvdata(&cdev->dev);
 	zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
 	zfcp_erp_wait(adapter);
-	up(&zfcp_data.config_sema);
+	zfcp_erp_thread_kill(adapter);
+	mutex_unlock(&zfcp_data.config_mutex);
 }
 
 static struct ccw_driver zfcp_ccw_driver = {
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index b99b87c..215b707 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -3,7 +3,7 @@
  *
  * Debug traces for zfcp.
  *
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -11,6 +11,7 @@
 
 #include <linux/ctype.h>
 #include <asm/debug.h>
+#include "zfcp_dbf.h"
 #include "zfcp_ext.h"
 
 static u32 dbfsize = 4;
@@ -37,19 +38,6 @@ static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
 	}
 }
 
-/* FIXME: this duplicate this code in s390 debug feature */
-static void zfcp_dbf_timestamp(unsigned long long stck, struct timespec *time)
-{
-	unsigned long long sec;
-
-	stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
-	sec = stck >> 12;
-	do_div(sec, 1000000);
-	time->tv_sec = sec;
-	stck -= (sec * 1000000) << 12;
-	time->tv_nsec = ((stck * 1000) >> 12);
-}
-
 static void zfcp_dbf_tag(char **p, const char *label, const char *tag)
 {
 	int i;
@@ -106,7 +94,7 @@ static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
 	char *p = out_buf;
 
 	if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
-		zfcp_dbf_timestamp(entry->id.stck, &t);
+		stck_to_timespec(entry->id.stck, &t);
 		zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu",
 			     t.tv_sec, t.tv_nsec);
 		zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid);
@@ -119,13 +107,10 @@ static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
 	return p - out_buf;
 }
 
-/**
- * zfcp_hba_dbf_event_fsf_response - trace event for request completion
- * @fsf_req: request that has been completed
- */
-void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
+void _zfcp_dbf_hba_fsf_response(const char *tag2, int level,
+				struct zfcp_fsf_req *fsf_req,
+				struct zfcp_dbf *dbf)
 {
-	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fsf_qtcb *qtcb = fsf_req->qtcb;
 	union fsf_prot_status_qual *prot_status_qual =
 					&qtcb->prefix.prot_status_qual;
@@ -134,33 +119,14 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 	struct zfcp_port *port;
 	struct zfcp_unit *unit;
 	struct zfcp_send_els *send_els;
-	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
-	struct zfcp_hba_dbf_record_response *response = &rec->u.response;
-	int level;
+	struct zfcp_dbf_hba_record *rec = &dbf->hba_buf;
+	struct zfcp_dbf_hba_record_response *response = &rec->u.response;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->hba_lock, flags);
 	memset(rec, 0, sizeof(*rec));
 	strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
-
-	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
-	    (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
-		strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE);
-		level = 1;
-	} else if (qtcb->header.fsf_status != FSF_GOOD) {
-		strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE);
-		level = 1;
-	} else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
-		   (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {
-		strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);
-		level = 4;
-	} else if (qtcb->header.log_length) {
-		strncpy(rec->tag2, "qtcb", ZFCP_DBF_TAG_SIZE);
-		level = 5;
-	} else {
-		strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);
-		level = 6;
-	}
+	strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
 
 	response->fsf_command = fsf_req->fsf_command;
 	response->fsf_reqid = fsf_req->req_id;
@@ -173,9 +139,9 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 	memcpy(response->fsf_status_qual,
 	       fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
 	response->fsf_req_status = fsf_req->status;
-	response->sbal_first = fsf_req->sbal_first;
-	response->sbal_last = fsf_req->sbal_last;
-	response->sbal_response = fsf_req->sbal_response;
+	response->sbal_first = fsf_req->queue_req.sbal_first;
+	response->sbal_last = fsf_req->queue_req.sbal_last;
+	response->sbal_response = fsf_req->queue_req.sbal_response;
 	response->pool = fsf_req->pool != NULL;
 	response->erp_action = (unsigned long)fsf_req->erp_action;
 
@@ -224,7 +190,7 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 		break;
 	}
 
-	debug_event(adapter->hba_dbf, level, rec, sizeof(*rec));
+	debug_event(dbf->hba, level, rec, sizeof(*rec));
 
 	/* have fcp channel microcode fixed to use as little as possible */
 	if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) {
@@ -232,31 +198,25 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 		char *buf = (char *)qtcb + qtcb->header.log_start;
 		int len = qtcb->header.log_length;
 		for (; len && !buf[len - 1]; len--);
-		zfcp_dbf_hexdump(adapter->hba_dbf, rec, sizeof(*rec), level,
-				 buf, len);
+		zfcp_dbf_hexdump(dbf->hba, rec, sizeof(*rec), level, buf,
+				 len);
 	}
 
-	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+	spin_unlock_irqrestore(&dbf->hba_lock, flags);
 }
 
-/**
- * zfcp_hba_dbf_event_fsf_unsol - trace event for an unsolicited status buffer
- * @tag: tag indicating which kind of unsolicited status has been received
- * @adapter: adapter that has issued the unsolicited status buffer
- * @status_buffer: buffer containing payload of unsolicited status
- */
-void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
-				  struct fsf_status_read_buffer *status_buffer)
+void _zfcp_dbf_hba_fsf_unsol(const char *tag, int level, struct zfcp_dbf *dbf,
+			     struct fsf_status_read_buffer *status_buffer)
 {
-	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
+	struct zfcp_dbf_hba_record *rec = &dbf->hba_buf;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->hba_lock, flags);
 	memset(rec, 0, sizeof(*rec));
 	strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
 	strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
 
-	rec->u.status.failed = atomic_read(&adapter->stat_miss);
+	rec->u.status.failed = atomic_read(&dbf->adapter->stat_miss);
 	if (status_buffer != NULL) {
 		rec->u.status.status_type = status_buffer->status_type;
 		rec->u.status.status_subtype = status_buffer->status_subtype;
@@ -293,63 +253,61 @@ void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
 		       &status_buffer->payload, rec->u.status.payload_size);
 	}
 
-	debug_event(adapter->hba_dbf, 2, rec, sizeof(*rec));
-	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+	debug_event(dbf->hba, level, rec, sizeof(*rec));
+	spin_unlock_irqrestore(&dbf->hba_lock, flags);
 }
 
 /**
- * zfcp_hba_dbf_event_qdio - trace event for QDIO related failure
- * @adapter: adapter affected by this QDIO related event
+ * zfcp_dbf_hba_qdio - trace event for QDIO related failure
+ * @qdio: qdio structure affected by this QDIO related event
  * @qdio_error: as passed by qdio module
  * @sbal_index: first buffer with error condition, as passed by qdio module
  * @sbal_count: number of buffers affected, as passed by qdio module
  */
-void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter,
-			     unsigned int qdio_error, int sbal_index,
-			     int sbal_count)
+void zfcp_dbf_hba_qdio(struct zfcp_dbf *dbf, unsigned int qdio_error,
+		       int sbal_index, int sbal_count)
 {
-	struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf;
+	struct zfcp_dbf_hba_record *r = &dbf->hba_buf;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->hba_lock, flags);
 	memset(r, 0, sizeof(*r));
 	strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE);
 	r->u.qdio.qdio_error = qdio_error;
 	r->u.qdio.sbal_index = sbal_index;
 	r->u.qdio.sbal_count = sbal_count;
-	debug_event(adapter->hba_dbf, 0, r, sizeof(*r));
-	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+	debug_event(dbf->hba, 0, r, sizeof(*r));
+	spin_unlock_irqrestore(&dbf->hba_lock, flags);
 }
 
 /**
- * zfcp_hba_dbf_event_berr - trace event for bit error threshold
- * @adapter: adapter affected by this QDIO related event
+ * zfcp_dbf_hba_berr - trace event for bit error threshold
+ * @dbf: dbf structure affected by this QDIO related event
  * @req: fsf request
  */
-void zfcp_hba_dbf_event_berr(struct zfcp_adapter *adapter,
-			     struct zfcp_fsf_req *req)
+void zfcp_dbf_hba_berr(struct zfcp_dbf *dbf, struct zfcp_fsf_req *req)
 {
-	struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf;
+	struct zfcp_dbf_hba_record *r = &dbf->hba_buf;
 	struct fsf_status_read_buffer *sr_buf = req->data;
 	struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->hba_lock, flags);
 	memset(r, 0, sizeof(*r));
 	strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE);
 	memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload));
-	debug_event(adapter->hba_dbf, 0, r, sizeof(*r));
-	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
+	debug_event(dbf->hba, 0, r, sizeof(*r));
+	spin_unlock_irqrestore(&dbf->hba_lock, flags);
 }
-static void zfcp_hba_dbf_view_response(char **p,
-				       struct zfcp_hba_dbf_record_response *r)
+static void zfcp_dbf_hba_view_response(char **p,
+				       struct zfcp_dbf_hba_record_response *r)
 {
 	struct timespec t;
 
 	zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command);
 	zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
 	zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-	zfcp_dbf_timestamp(r->fsf_issued, &t);
+	stck_to_timespec(r->fsf_issued, &t);
 	zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
 	zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status);
 	zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status);
@@ -403,8 +361,8 @@ static void zfcp_hba_dbf_view_response(char **p,
 	}
 }
 
-static void zfcp_hba_dbf_view_status(char **p,
-				     struct zfcp_hba_dbf_record_status *r)
+static void zfcp_dbf_hba_view_status(char **p,
+				     struct zfcp_dbf_hba_record_status *r)
 {
 	zfcp_dbf_out(p, "failed", "0x%02x", r->failed);
 	zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type);
@@ -416,14 +374,14 @@ static void zfcp_hba_dbf_view_status(char **p,
 		      r->payload_size);
 }
 
-static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r)
+static void zfcp_dbf_hba_view_qdio(char **p, struct zfcp_dbf_hba_record_qdio *r)
 {
 	zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error);
 	zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index);
 	zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count);
 }
 
-static void zfcp_hba_dbf_view_berr(char **p, struct fsf_bit_error_payload *r)
+static void zfcp_dbf_hba_view_berr(char **p, struct fsf_bit_error_payload *r)
 {
 	zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count);
 	zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count);
@@ -447,10 +405,10 @@ static void zfcp_hba_dbf_view_berr(char **p, struct fsf_bit_error_payload *r)
 		     r->current_transmit_b2b_credit);
 }
 
-static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
+static int zfcp_dbf_hba_view_format(debug_info_t *id, struct debug_view *view,
 				    char *out_buf, const char *in_buf)
 {
-	struct zfcp_hba_dbf_record *r = (struct zfcp_hba_dbf_record *)in_buf;
+	struct zfcp_dbf_hba_record *r = (struct zfcp_dbf_hba_record *)in_buf;
 	char *p = out_buf;
 
 	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
@@ -461,45 +419,42 @@ static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
 		zfcp_dbf_tag(&p, "tag2", r->tag2);
 
 	if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
-		zfcp_hba_dbf_view_response(&p, &r->u.response);
+		zfcp_dbf_hba_view_response(&p, &r->u.response);
 	else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
-		zfcp_hba_dbf_view_status(&p, &r->u.status);
+		zfcp_dbf_hba_view_status(&p, &r->u.status);
 	else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
-		zfcp_hba_dbf_view_qdio(&p, &r->u.qdio);
+		zfcp_dbf_hba_view_qdio(&p, &r->u.qdio);
 	else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
-		zfcp_hba_dbf_view_berr(&p, &r->u.berr);
+		zfcp_dbf_hba_view_berr(&p, &r->u.berr);
 
 	if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0)
 		p += sprintf(p, "\n");
 	return p - out_buf;
 }
 
-static struct debug_view zfcp_hba_dbf_view = {
-	"structured",
-	NULL,
-	&zfcp_dbf_view_header,
-	&zfcp_hba_dbf_view_format,
-	NULL,
-	NULL
+static struct debug_view zfcp_dbf_hba_view = {
+	.name = "structured",
+	.header_proc = zfcp_dbf_view_header,
+	.format_proc = zfcp_dbf_hba_view_format,
 };
 
-static const char *zfcp_rec_dbf_tags[] = {
+static const char *zfcp_dbf_rec_tags[] = {
 	[ZFCP_REC_DBF_ID_THREAD] = "thread",
 	[ZFCP_REC_DBF_ID_TARGET] = "target",
 	[ZFCP_REC_DBF_ID_TRIGGER] = "trigger",
 	[ZFCP_REC_DBF_ID_ACTION] = "action",
 };
 
-static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
+static int zfcp_dbf_rec_view_format(debug_info_t *id, struct debug_view *view,
 				    char *buf, const char *_rec)
 {
-	struct zfcp_rec_dbf_record *r = (struct zfcp_rec_dbf_record *)_rec;
+	struct zfcp_dbf_rec_record *r = (struct zfcp_dbf_rec_record *)_rec;
 	char *p = buf;
 	char hint[ZFCP_DBF_ID_SIZE + 1];
 
 	memcpy(hint, r->id2, ZFCP_DBF_ID_SIZE);
 	hint[ZFCP_DBF_ID_SIZE] = 0;
-	zfcp_dbf_outs(&p, "tag", zfcp_rec_dbf_tags[r->id]);
+	zfcp_dbf_outs(&p, "tag", zfcp_dbf_rec_tags[r->id]);
 	zfcp_dbf_outs(&p, "hint", hint);
 	switch (r->id) {
 	case ZFCP_REC_DBF_ID_THREAD:
@@ -537,24 +492,22 @@ static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
 	return p - buf;
 }
 
-static struct debug_view zfcp_rec_dbf_view = {
-	"structured",
-	NULL,
-	&zfcp_dbf_view_header,
-	&zfcp_rec_dbf_view_format,
-	NULL,
-	NULL
+static struct debug_view zfcp_dbf_rec_view = {
+	.name = "structured",
+	.header_proc = zfcp_dbf_view_header,
+	.format_proc = zfcp_dbf_rec_view_format,
 };
 
 /**
- * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation
+ * zfcp_dbf_rec_thread - trace event related to recovery thread operation
  * @id2: identifier for event
- * @adapter: adapter
+ * @dbf: reference to dbf structure
  * This function assumes that the caller is holding erp_lock.
  */
-void zfcp_rec_dbf_event_thread(char *id2, struct zfcp_adapter *adapter)
+void zfcp_dbf_rec_thread(char *id2, struct zfcp_dbf *dbf)
 {
-	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
+	struct zfcp_adapter *adapter = dbf->adapter;
+	struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
 	unsigned long flags = 0;
 	struct list_head *entry;
 	unsigned ready = 0, running = 0, total;
@@ -565,41 +518,41 @@ void zfcp_rec_dbf_event_thread(char *id2, struct zfcp_adapter *adapter)
 		running++;
 	total = adapter->erp_total_count;
 
-	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->rec_lock, flags);
 	memset(r, 0, sizeof(*r));
 	r->id = ZFCP_REC_DBF_ID_THREAD;
 	memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
 	r->u.thread.total = total;
 	r->u.thread.ready = ready;
 	r->u.thread.running = running;
-	debug_event(adapter->rec_dbf, 6, r, sizeof(*r));
-	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
+	debug_event(dbf->rec, 6, r, sizeof(*r));
+	spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
 
 /**
- * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation
+ * zfcp_dbf_rec_thread - trace event related to recovery thread operation
  * @id2: identifier for event
  * @adapter: adapter
  * This function assumes that the caller does not hold erp_lock.
  */
-void zfcp_rec_dbf_event_thread_lock(char *id2, struct zfcp_adapter *adapter)
+void zfcp_dbf_rec_thread_lock(char *id2, struct zfcp_dbf *dbf)
 {
+	struct zfcp_adapter *adapter = dbf->adapter;
 	unsigned long flags;
 
 	read_lock_irqsave(&adapter->erp_lock, flags);
-	zfcp_rec_dbf_event_thread(id2, adapter);
+	zfcp_dbf_rec_thread(id2, dbf);
 	read_unlock_irqrestore(&adapter->erp_lock, flags);
 }
 
-static void zfcp_rec_dbf_event_target(char *id2, void *ref,
-				      struct zfcp_adapter *adapter,
-				      atomic_t *status, atomic_t *erp_count,
-				      u64 wwpn, u32 d_id, u64 fcp_lun)
+static void zfcp_dbf_rec_target(char *id2, void *ref, struct zfcp_dbf *dbf,
+				atomic_t *status, atomic_t *erp_count, u64 wwpn,
+				u32 d_id, u64 fcp_lun)
 {
-	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
+	struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->rec_lock, flags);
 	memset(r, 0, sizeof(*r));
 	r->id = ZFCP_REC_DBF_ID_TARGET;
 	memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
@@ -609,56 +562,57 @@ static void zfcp_rec_dbf_event_target(char *id2, void *ref,
 	r->u.target.d_id = d_id;
 	r->u.target.fcp_lun = fcp_lun;
 	r->u.target.erp_count = atomic_read(erp_count);
-	debug_event(adapter->rec_dbf, 3, r, sizeof(*r));
-	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
+	debug_event(dbf->rec, 3, r, sizeof(*r));
+	spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
 
 /**
- * zfcp_rec_dbf_event_adapter - trace event for adapter state change
+ * zfcp_dbf_rec_adapter - trace event for adapter state change
  * @id: identifier for trigger of state change
  * @ref: additional reference (e.g. request)
- * @adapter: adapter
+ * @dbf: reference to dbf structure
  */
-void zfcp_rec_dbf_event_adapter(char *id, void *ref,
-				struct zfcp_adapter *adapter)
+void zfcp_dbf_rec_adapter(char *id, void *ref, struct zfcp_dbf *dbf)
 {
-	zfcp_rec_dbf_event_target(id, ref, adapter, &adapter->status,
+	struct zfcp_adapter *adapter = dbf->adapter;
+
+	zfcp_dbf_rec_target(id, ref, dbf, &adapter->status,
 				  &adapter->erp_counter, 0, 0, 0);
 }
 
 /**
- * zfcp_rec_dbf_event_port - trace event for port state change
+ * zfcp_dbf_rec_port - trace event for port state change
  * @id: identifier for trigger of state change
  * @ref: additional reference (e.g. request)
  * @port: port
  */
-void zfcp_rec_dbf_event_port(char *id, void *ref, struct zfcp_port *port)
+void zfcp_dbf_rec_port(char *id, void *ref, struct zfcp_port *port)
 {
-	struct zfcp_adapter *adapter = port->adapter;
+	struct zfcp_dbf *dbf = port->adapter->dbf;
 
-	zfcp_rec_dbf_event_target(id, ref, adapter, &port->status,
+	zfcp_dbf_rec_target(id, ref, dbf, &port->status,
 				  &port->erp_counter, port->wwpn, port->d_id,
 				  0);
 }
 
 /**
- * zfcp_rec_dbf_event_unit - trace event for unit state change
+ * zfcp_dbf_rec_unit - trace event for unit state change
  * @id: identifier for trigger of state change
  * @ref: additional reference (e.g. request)
  * @unit: unit
  */
-void zfcp_rec_dbf_event_unit(char *id, void *ref, struct zfcp_unit *unit)
+void zfcp_dbf_rec_unit(char *id, void *ref, struct zfcp_unit *unit)
 {
 	struct zfcp_port *port = unit->port;
-	struct zfcp_adapter *adapter = port->adapter;
+	struct zfcp_dbf *dbf = port->adapter->dbf;
 
-	zfcp_rec_dbf_event_target(id, ref, adapter, &unit->status,
+	zfcp_dbf_rec_target(id, ref, dbf, &unit->status,
 				  &unit->erp_counter, port->wwpn, port->d_id,
 				  unit->fcp_lun);
 }
 
 /**
- * zfcp_rec_dbf_event_trigger - trace event for triggered error recovery
+ * zfcp_dbf_rec_trigger - trace event for triggered error recovery
  * @id2: identifier for error recovery trigger
  * @ref: additional reference (e.g. request)
  * @want: originally requested error recovery action
@@ -668,14 +622,15 @@ void zfcp_rec_dbf_event_unit(char *id, void *ref, struct zfcp_unit *unit)
  * @port: port
  * @unit: unit
  */
-void zfcp_rec_dbf_event_trigger(char *id2, void *ref, u8 want, u8 need,
-				void *action, struct zfcp_adapter *adapter,
-				struct zfcp_port *port, struct zfcp_unit *unit)
+void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action,
+			  struct zfcp_adapter *adapter, struct zfcp_port *port,
+			  struct zfcp_unit *unit)
 {
-	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
+	struct zfcp_dbf *dbf = adapter->dbf;
+	struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->rec_lock, flags);
 	memset(r, 0, sizeof(*r));
 	r->id = ZFCP_REC_DBF_ID_TRIGGER;
 	memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
@@ -692,22 +647,22 @@ void zfcp_rec_dbf_event_trigger(char *id2, void *ref, u8 want, u8 need,
 		r->u.trigger.us = atomic_read(&unit->status);
 		r->u.trigger.fcp_lun = unit->fcp_lun;
 	}
-	debug_event(adapter->rec_dbf, action ? 1 : 4, r, sizeof(*r));
-	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
+	debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r));
+	spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
 
 /**
- * zfcp_rec_dbf_event_action - trace event showing progress of recovery action
+ * zfcp_dbf_rec_action - trace event showing progress of recovery action
  * @id2: identifier
  * @erp_action: error recovery action struct pointer
  */
-void zfcp_rec_dbf_event_action(char *id2, struct zfcp_erp_action *erp_action)
+void zfcp_dbf_rec_action(char *id2, struct zfcp_erp_action *erp_action)
 {
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
+	struct zfcp_dbf *dbf = erp_action->adapter->dbf;
+	struct zfcp_dbf_rec_record *r = &dbf->rec_buf;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->rec_lock, flags);
 	memset(r, 0, sizeof(*r));
 	r->id = ZFCP_REC_DBF_ID_ACTION;
 	memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE);
@@ -715,26 +670,27 @@ void zfcp_rec_dbf_event_action(char *id2, struct zfcp_erp_action *erp_action)
 	r->u.action.status = erp_action->status;
 	r->u.action.step = erp_action->step;
 	r->u.action.fsf_req = (unsigned long)erp_action->fsf_req;
-	debug_event(adapter->rec_dbf, 5, r, sizeof(*r));
-	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
+	debug_event(dbf->rec, 5, r, sizeof(*r));
+	spin_unlock_irqrestore(&dbf->rec_lock, flags);
 }
 
 /**
- * zfcp_san_dbf_event_ct_request - trace event for issued CT request
+ * zfcp_dbf_san_ct_request - trace event for issued CT request
  * @fsf_req: request containing issued CT data
  */
-void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req)
 {
 	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
 	struct zfcp_wka_port *wka_port = ct->wka_port;
 	struct zfcp_adapter *adapter = wka_port->adapter;
+	struct zfcp_dbf *dbf = adapter->dbf;
 	struct ct_hdr *hdr = sg_virt(ct->req);
-	struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
-	struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
+	struct zfcp_dbf_san_record *r = &dbf->san_buf;
+	struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req;
 	int level = 3;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->san_lock, flags);
 	memset(r, 0, sizeof(*r));
 	strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
 	r->fsf_reqid = fsf_req->req_id;
@@ -749,28 +705,29 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
 	oct->max_res_size = hdr->max_res_size;
 	oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
 		       ZFCP_DBF_SAN_MAX_PAYLOAD);
-	debug_event(adapter->san_dbf, level, r, sizeof(*r));
-	zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
+	debug_event(dbf->san, level, r, sizeof(*r));
+	zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
 			 (void *)hdr + sizeof(struct ct_hdr), oct->len);
-	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+	spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
 /**
- * zfcp_san_dbf_event_ct_response - trace event for completion of CT request
+ * zfcp_dbf_san_ct_response - trace event for completion of CT request
  * @fsf_req: request containing CT response
  */
-void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req)
 {
 	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
 	struct zfcp_wka_port *wka_port = ct->wka_port;
 	struct zfcp_adapter *adapter = wka_port->adapter;
 	struct ct_hdr *hdr = sg_virt(ct->resp);
-	struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
-	struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
+	struct zfcp_dbf *dbf = adapter->dbf;
+	struct zfcp_dbf_san_record *r = &dbf->san_buf;
+	struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp;
 	int level = 3;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->san_lock, flags);
 	memset(r, 0, sizeof(*r));
 	strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
 	r->fsf_reqid = fsf_req->req_id;
@@ -785,22 +742,22 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
 	rct->max_res_size = hdr->max_res_size;
 	rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
 		       ZFCP_DBF_SAN_MAX_PAYLOAD);
-	debug_event(adapter->san_dbf, level, r, sizeof(*r));
-	zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
+	debug_event(dbf->san, level, r, sizeof(*r));
+	zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level,
 			 (void *)hdr + sizeof(struct ct_hdr), rct->len);
-	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+	spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
-static void zfcp_san_dbf_event_els(const char *tag, int level,
-				   struct zfcp_fsf_req *fsf_req, u32 s_id,
-				   u32 d_id, u8 ls_code, void *buffer,
-				   int buflen)
+static void zfcp_dbf_san_els(const char *tag, int level,
+			     struct zfcp_fsf_req *fsf_req, u32 s_id, u32 d_id,
+			     u8 ls_code, void *buffer, int buflen)
 {
 	struct zfcp_adapter *adapter = fsf_req->adapter;
-	struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
+	struct zfcp_dbf *dbf = adapter->dbf;
+	struct zfcp_dbf_san_record *rec = &dbf->san_buf;
 	unsigned long flags;
 
-	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->san_lock, flags);
 	memset(rec, 0, sizeof(*rec));
 	strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
 	rec->fsf_reqid = fsf_req->req_id;
@@ -808,45 +765,45 @@ static void zfcp_san_dbf_event_els(const char *tag, int level,
 	rec->s_id = s_id;
 	rec->d_id = d_id;
 	rec->u.els.ls_code = ls_code;
-	debug_event(adapter->san_dbf, level, rec, sizeof(*rec));
-	zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level,
+	debug_event(dbf->san, level, rec, sizeof(*rec));
+	zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level,
 			 buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
-	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+	spin_unlock_irqrestore(&dbf->san_lock, flags);
 }
 
 /**
- * zfcp_san_dbf_event_els_request - trace event for issued ELS
+ * zfcp_dbf_san_els_request - trace event for issued ELS
  * @fsf_req: request containing issued ELS
  */
-void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req)
 {
 	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
 
-	zfcp_san_dbf_event_els("oels", 2, fsf_req,
+	zfcp_dbf_san_els("oels", 2, fsf_req,
 			       fc_host_port_id(els->adapter->scsi_host),
 			       els->d_id, *(u8 *) sg_virt(els->req),
 			       sg_virt(els->req), els->req->length);
 }
 
 /**
- * zfcp_san_dbf_event_els_response - trace event for completed ELS
+ * zfcp_dbf_san_els_response - trace event for completed ELS
  * @fsf_req: request containing ELS response
  */
-void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req)
 {
 	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
 
-	zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id,
+	zfcp_dbf_san_els("rels", 2, fsf_req, els->d_id,
 			       fc_host_port_id(els->adapter->scsi_host),
 			       *(u8 *)sg_virt(els->req), sg_virt(els->resp),
 			       els->resp->length);
 }
 
 /**
- * zfcp_san_dbf_event_incoming_els - trace event for incomig ELS
+ * zfcp_dbf_san_incoming_els - trace event for incomig ELS
  * @fsf_req: request containing unsolicited status buffer with incoming ELS
  */
-void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
+void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req)
 {
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fsf_status_read_buffer *buf =
@@ -854,16 +811,16 @@ void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
 	int length = (int)buf->length -
 		     (int)((void *)&buf->payload - (void *)buf);
 
-	zfcp_san_dbf_event_els("iels", 1, fsf_req, buf->d_id,
+	zfcp_dbf_san_els("iels", 1, fsf_req, buf->d_id,
 			       fc_host_port_id(adapter->scsi_host),
 			       buf->payload.data[0], (void *)buf->payload.data,
 			       length);
 }
 
-static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
+static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view,
 				    char *out_buf, const char *in_buf)
 {
-	struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf;
+	struct zfcp_dbf_san_record *r = (struct zfcp_dbf_san_record *)in_buf;
 	char *p = out_buf;
 
 	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
@@ -876,7 +833,7 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
 	zfcp_dbf_out(&p, "d_id", "0x%06x", r->d_id);
 
 	if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
-		struct zfcp_san_dbf_record_ct_request *ct = &r->u.ct_req;
+		struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req;
 		zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
 		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
 		zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
@@ -884,7 +841,7 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
 		zfcp_dbf_out(&p, "options", "0x%02x", ct->options);
 		zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
 	} else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
-		struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp;
+		struct zfcp_dbf_san_record_ct_response *ct = &r->u.ct_resp;
 		zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code);
 		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
 		zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
@@ -894,35 +851,30 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
 	} else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
 		   strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
 		   strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
-		struct zfcp_san_dbf_record_els *els = &r->u.els;
+		struct zfcp_dbf_san_record_els *els = &r->u.els;
 		zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code);
 	}
 	return p - out_buf;
 }
 
-static struct debug_view zfcp_san_dbf_view = {
-	"structured",
-	NULL,
-	&zfcp_dbf_view_header,
-	&zfcp_san_dbf_view_format,
-	NULL,
-	NULL
+static struct debug_view zfcp_dbf_san_view = {
+	.name = "structured",
+	.header_proc = zfcp_dbf_view_header,
+	.format_proc = zfcp_dbf_san_view_format,
 };
 
-static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level,
-				struct zfcp_adapter *adapter,
-				struct scsi_cmnd *scsi_cmnd,
-				struct zfcp_fsf_req *fsf_req,
-				unsigned long old_req_id)
+void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
+		    struct zfcp_dbf *dbf, struct scsi_cmnd *scsi_cmnd,
+		    struct zfcp_fsf_req *fsf_req, unsigned long old_req_id)
 {
-	struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
+	struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;
 	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
 	unsigned long flags;
 	struct fcp_rsp_iu *fcp_rsp;
 	char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;
 	int offset = 0, buflen = 0;
 
-	spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);
+	spin_lock_irqsave(&dbf->scsi_lock, flags);
 	do {
 		memset(rec, 0, sizeof(*rec));
 		if (offset == 0) {
@@ -976,68 +928,20 @@ static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level,
 			dump->offset = offset;
 			dump->size = min(buflen - offset,
 					 (int)sizeof(struct
-						     zfcp_scsi_dbf_record) -
+						     zfcp_dbf_scsi_record) -
 					 (int)sizeof(struct zfcp_dbf_dump));
 			memcpy(dump->data, fcp_sns_info + offset, dump->size);
 			offset += dump->size;
 		}
-		debug_event(adapter->scsi_dbf, level, rec, sizeof(*rec));
+		debug_event(dbf->scsi, level, rec, sizeof(*rec));
 	} while (offset < buflen);
-	spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
-}
-
-/**
- * zfcp_scsi_dbf_event_result - trace event for SCSI command completion
- * @tag: tag indicating success or failure of SCSI command
- * @level: trace level applicable for this event
- * @adapter: adapter that has been used to issue the SCSI command
- * @scsi_cmnd: SCSI command pointer
- * @fsf_req: request used to issue SCSI command (might be NULL)
- */
-void zfcp_scsi_dbf_event_result(const char *tag, int level,
-				struct zfcp_adapter *adapter,
-				struct scsi_cmnd *scsi_cmnd,
-				struct zfcp_fsf_req *fsf_req)
-{
-	zfcp_scsi_dbf_event("rslt", tag, level, adapter, scsi_cmnd, fsf_req, 0);
+	spin_unlock_irqrestore(&dbf->scsi_lock, flags);
 }
 
-/**
- * zfcp_scsi_dbf_event_abort - trace event for SCSI command abort
- * @tag: tag indicating success or failure of abort operation
- * @adapter: adapter thas has been used to issue SCSI command to be aborted
- * @scsi_cmnd: SCSI command to be aborted
- * @new_fsf_req: request containing abort (might be NULL)
- * @old_req_id: identifier of request containg SCSI command to be aborted
- */
-void zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
-			       struct scsi_cmnd *scsi_cmnd,
-			       struct zfcp_fsf_req *new_fsf_req,
-			       unsigned long old_req_id)
-{
-	zfcp_scsi_dbf_event("abrt", tag, 1, adapter, scsi_cmnd, new_fsf_req,
-			    old_req_id);
-}
-
-/**
- * zfcp_scsi_dbf_event_devreset - trace event for Logical Unit or Target Reset
- * @tag: tag indicating success or failure of reset operation
- * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
- * @unit: unit that needs reset
- * @scsi_cmnd: SCSI command which caused this error recovery
- */
-void zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag,
-				  struct zfcp_unit *unit,
-				  struct scsi_cmnd *scsi_cmnd)
-{
-	zfcp_scsi_dbf_event(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1,
-			    unit->port->adapter, scsi_cmnd, NULL, 0);
-}
-
-static int zfcp_scsi_dbf_view_format(debug_info_t *id, struct debug_view *view,
+static int zfcp_dbf_scsi_view_format(debug_info_t *id, struct debug_view *view,
 				     char *out_buf, const char *in_buf)
 {
-	struct zfcp_scsi_dbf_record *r = (struct zfcp_scsi_dbf_record *)in_buf;
+	struct zfcp_dbf_scsi_record *r = (struct zfcp_dbf_scsi_record *)in_buf;
 	struct timespec t;
 	char *p = out_buf;
 
@@ -1059,7 +963,7 @@ static int zfcp_scsi_dbf_view_format(debug_info_t *id, struct debug_view *view,
 		zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid);
 	zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
 	zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
-	zfcp_dbf_timestamp(r->fsf_issued, &t);
+	stck_to_timespec(r->fsf_issued, &t);
 	zfcp_dbf_out(&p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
 
 	if (strncmp(r->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
@@ -1078,84 +982,96 @@ static int zfcp_scsi_dbf_view_format(debug_info_t *id, struct debug_view *view,
 	return p - out_buf;
 }
 
-static struct debug_view zfcp_scsi_dbf_view = {
-	"structured",
-	NULL,
-	&zfcp_dbf_view_header,
-	&zfcp_scsi_dbf_view_format,
-	NULL,
-	NULL
+static struct debug_view zfcp_dbf_scsi_view = {
+	.name = "structured",
+	.header_proc = zfcp_dbf_view_header,
+	.format_proc = zfcp_dbf_scsi_view_format,
 };
 
+static debug_info_t *zfcp_dbf_reg(const char *name, int level,
+				  struct debug_view *view, int size)
+{
+	struct debug_info *d;
+
+	d = debug_register(name, dbfsize, level, size);
+	if (!d)
+		return NULL;
+
+	debug_register_view(d, &debug_hex_ascii_view);
+	debug_register_view(d, view);
+	debug_set_level(d, level);
+
+	return d;
+}
+
 /**
  * zfcp_adapter_debug_register - registers debug feature for an adapter
  * @adapter: pointer to adapter for which debug features should be registered
  * return: -ENOMEM on error, 0 otherwise
  */
-int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
+int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter)
 {
 	char dbf_name[DEBUG_MAX_NAME_LEN];
+	struct zfcp_dbf *dbf;
+
+	dbf = kmalloc(sizeof(struct zfcp_dbf), GFP_KERNEL);
+	if (!dbf)
+		return -ENOMEM;
+
+	dbf->adapter = adapter;
+
+	spin_lock_init(&dbf->hba_lock);
+	spin_lock_init(&dbf->san_lock);
+	spin_lock_init(&dbf->scsi_lock);
+	spin_lock_init(&dbf->rec_lock);
 
 	/* debug feature area which records recovery activity */
 	sprintf(dbf_name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev));
-	adapter->rec_dbf = debug_register(dbf_name, dbfsize, 1,
-					  sizeof(struct zfcp_rec_dbf_record));
-	if (!adapter->rec_dbf)
-		goto failed;
-	debug_register_view(adapter->rec_dbf, &debug_hex_ascii_view);
-	debug_register_view(adapter->rec_dbf, &zfcp_rec_dbf_view);
-	debug_set_level(adapter->rec_dbf, 3);
+	dbf->rec = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_rec_view,
+				sizeof(struct zfcp_dbf_rec_record));
+	if (!dbf->rec)
+		goto err_out;
 
 	/* debug feature area which records HBA (FSF and QDIO) conditions */
 	sprintf(dbf_name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev));
-	adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
-					  sizeof(struct zfcp_hba_dbf_record));
-	if (!adapter->hba_dbf)
-		goto failed;
-	debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view);
-	debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view);
-	debug_set_level(adapter->hba_dbf, 3);
+	dbf->hba = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_hba_view,
+				sizeof(struct zfcp_dbf_hba_record));
+	if (!dbf->hba)
+		goto err_out;
 
 	/* debug feature area which records SAN command failures and recovery */
 	sprintf(dbf_name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev));
-	adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
-					  sizeof(struct zfcp_san_dbf_record));
-	if (!adapter->san_dbf)
-		goto failed;
-	debug_register_view(adapter->san_dbf, &debug_hex_ascii_view);
-	debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view);
-	debug_set_level(adapter->san_dbf, 6);
+	dbf->san = zfcp_dbf_reg(dbf_name, 6, &zfcp_dbf_san_view,
+				sizeof(struct zfcp_dbf_san_record));
+	if (!dbf->san)
+		goto err_out;
 
 	/* debug feature area which records SCSI command failures and recovery */
 	sprintf(dbf_name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev));
-	adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
-					   sizeof(struct zfcp_scsi_dbf_record));
-	if (!adapter->scsi_dbf)
-		goto failed;
-	debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view);
-	debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view);
-	debug_set_level(adapter->scsi_dbf, 3);
+	dbf->scsi = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_scsi_view,
+				 sizeof(struct zfcp_dbf_scsi_record));
+	if (!dbf->scsi)
+		goto err_out;
 
+	adapter->dbf = dbf;
 	return 0;
 
- failed:
-	zfcp_adapter_debug_unregister(adapter);
-
+err_out:
+	zfcp_dbf_adapter_unregister(dbf);
 	return -ENOMEM;
 }
 
 /**
  * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
- * @adapter: pointer to adapter for which debug features should be unregistered
+ * @dbf: pointer to dbf for which debug features should be unregistered
  */
-void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
+void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf)
 {
-	debug_unregister(adapter->scsi_dbf);
-	debug_unregister(adapter->san_dbf);
-	debug_unregister(adapter->hba_dbf);
-	debug_unregister(adapter->rec_dbf);
-	adapter->scsi_dbf = NULL;
-	adapter->san_dbf = NULL;
-	adapter->hba_dbf = NULL;
-	adapter->rec_dbf = NULL;
+	debug_unregister(dbf->scsi);
+	debug_unregister(dbf->san);
+	debug_unregister(dbf->hba);
+	debug_unregister(dbf->rec);
+	dbf->adapter->dbf = NULL;
+	kfree(dbf);
 }
+
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index a573f73..6b1461e 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -2,7 +2,7 @@
  * This file is part of the zfcp device driver for
  * FCP adapters for IBM System z9 and zSeries.
  *
- * Copyright IBM Corp. 2008, 2008
+ * Copyright IBM Corp. 2008, 2009
  *
  * This 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,9 @@
 #ifndef ZFCP_DBF_H
 #define ZFCP_DBF_H
 
+#include "zfcp_ext.h"
 #include "zfcp_fsf.h"
+#include "zfcp_def.h"
 
 #define ZFCP_DBF_TAG_SIZE      4
 #define ZFCP_DBF_ID_SIZE       7
@@ -35,13 +37,13 @@ struct zfcp_dbf_dump {
 	u8 data[];		/* dump data */
 } __attribute__ ((packed));
 
-struct zfcp_rec_dbf_record_thread {
+struct zfcp_dbf_rec_record_thread {
 	u32 total;
 	u32 ready;
 	u32 running;
 };
 
-struct zfcp_rec_dbf_record_target {
+struct zfcp_dbf_rec_record_target {
 	u64 ref;
 	u32 status;
 	u32 d_id;
@@ -50,7 +52,7 @@ struct zfcp_rec_dbf_record_target {
 	u32 erp_count;
 };
 
-struct zfcp_rec_dbf_record_trigger {
+struct zfcp_dbf_rec_record_trigger {
 	u8 want;
 	u8 need;
 	u32 as;
@@ -62,21 +64,21 @@ struct zfcp_rec_dbf_record_trigger {
 	u64 fcp_lun;
 };
 
-struct zfcp_rec_dbf_record_action {
+struct zfcp_dbf_rec_record_action {
 	u32 status;
 	u32 step;
 	u64 action;
 	u64 fsf_req;
 };
 
-struct zfcp_rec_dbf_record {
+struct zfcp_dbf_rec_record {
 	u8 id;
 	char id2[7];
 	union {
-		struct zfcp_rec_dbf_record_action action;
-		struct zfcp_rec_dbf_record_thread thread;
-		struct zfcp_rec_dbf_record_target target;
-		struct zfcp_rec_dbf_record_trigger trigger;
+		struct zfcp_dbf_rec_record_action action;
+		struct zfcp_dbf_rec_record_thread thread;
+		struct zfcp_dbf_rec_record_target target;
+		struct zfcp_dbf_rec_record_trigger trigger;
 	} u;
 };
 
@@ -87,7 +89,7 @@ enum {
 	ZFCP_REC_DBF_ID_TRIGGER,
 };
 
-struct zfcp_hba_dbf_record_response {
+struct zfcp_dbf_hba_record_response {
 	u32 fsf_command;
 	u64 fsf_reqid;
 	u32 fsf_seqno;
@@ -125,7 +127,7 @@ struct zfcp_hba_dbf_record_response {
 	} u;
 } __attribute__ ((packed));
 
-struct zfcp_hba_dbf_record_status {
+struct zfcp_dbf_hba_record_status {
 	u8 failed;
 	u32 status_type;
 	u32 status_subtype;
@@ -139,24 +141,24 @@ struct zfcp_hba_dbf_record_status {
 	u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
 } __attribute__ ((packed));
 
-struct zfcp_hba_dbf_record_qdio {
+struct zfcp_dbf_hba_record_qdio {
 	u32 qdio_error;
 	u8 sbal_index;
 	u8 sbal_count;
 } __attribute__ ((packed));
 
-struct zfcp_hba_dbf_record {
+struct zfcp_dbf_hba_record {
 	u8 tag[ZFCP_DBF_TAG_SIZE];
 	u8 tag2[ZFCP_DBF_TAG_SIZE];
 	union {
-		struct zfcp_hba_dbf_record_response response;
-		struct zfcp_hba_dbf_record_status status;
-		struct zfcp_hba_dbf_record_qdio qdio;
+		struct zfcp_dbf_hba_record_response response;
+		struct zfcp_dbf_hba_record_status status;
+		struct zfcp_dbf_hba_record_qdio qdio;
 		struct fsf_bit_error_payload berr;
 	} u;
 } __attribute__ ((packed));
 
-struct zfcp_san_dbf_record_ct_request {
+struct zfcp_dbf_san_record_ct_request {
 	u16 cmd_req_code;
 	u8 revision;
 	u8 gs_type;
@@ -166,7 +168,7 @@ struct zfcp_san_dbf_record_ct_request {
 	u32 len;
 } __attribute__ ((packed));
 
-struct zfcp_san_dbf_record_ct_response {
+struct zfcp_dbf_san_record_ct_response {
 	u16 cmd_rsp_code;
 	u8 revision;
 	u8 reason_code;
@@ -176,27 +178,27 @@ struct zfcp_san_dbf_record_ct_response {
 	u32 len;
 } __attribute__ ((packed));
 
-struct zfcp_san_dbf_record_els {
+struct zfcp_dbf_san_record_els {
 	u8 ls_code;
 	u32 len;
 } __attribute__ ((packed));
 
-struct zfcp_san_dbf_record {
+struct zfcp_dbf_san_record {
 	u8 tag[ZFCP_DBF_TAG_SIZE];
 	u64 fsf_reqid;
 	u32 fsf_seqno;
 	u32 s_id;
 	u32 d_id;
 	union {
-		struct zfcp_san_dbf_record_ct_request ct_req;
-		struct zfcp_san_dbf_record_ct_response ct_resp;
-		struct zfcp_san_dbf_record_els els;
+		struct zfcp_dbf_san_record_ct_request ct_req;
+		struct zfcp_dbf_san_record_ct_response ct_resp;
+		struct zfcp_dbf_san_record_els els;
 	} u;
 #define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
 	u8 payload[32];
 } __attribute__ ((packed));
 
-struct zfcp_scsi_dbf_record {
+struct zfcp_dbf_scsi_record {
 	u8 tag[ZFCP_DBF_TAG_SIZE];
 	u8 tag2[ZFCP_DBF_TAG_SIZE];
 	u32 scsi_id;
@@ -222,4 +224,127 @@ struct zfcp_scsi_dbf_record {
 	u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
 } __attribute__ ((packed));
 
+struct zfcp_dbf {
+	debug_info_t			*rec;
+	debug_info_t			*hba;
+	debug_info_t			*san;
+	debug_info_t			*scsi;
+	spinlock_t			rec_lock;
+	spinlock_t			hba_lock;
+	spinlock_t			san_lock;
+	spinlock_t			scsi_lock;
+	struct zfcp_dbf_rec_record	rec_buf;
+	struct zfcp_dbf_hba_record	hba_buf;
+	struct zfcp_dbf_san_record	san_buf;
+	struct zfcp_dbf_scsi_record	scsi_buf;
+	struct zfcp_adapter		*adapter;
+};
+
+static inline
+void zfcp_dbf_hba_fsf_resp(const char *tag2, int level,
+			   struct zfcp_fsf_req *req, struct zfcp_dbf *dbf)
+{
+	if (level <= dbf->hba->level)
+		_zfcp_dbf_hba_fsf_response(tag2, level, req, dbf);
+}
+
+/**
+ * zfcp_dbf_hba_fsf_response - trace event for request completion
+ * @fsf_req: request that has been completed
+ */
+static inline void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
+{
+	struct zfcp_dbf *dbf = req->adapter->dbf;
+	struct fsf_qtcb *qtcb = req->qtcb;
+
+	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
+	    (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
+		zfcp_dbf_hba_fsf_resp("perr", 1, req, dbf);
+
+	} else if (qtcb->header.fsf_status != FSF_GOOD) {
+		zfcp_dbf_hba_fsf_resp("ferr", 1, req, dbf);
+
+	} else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
+		   (req->fsf_command == FSF_QTCB_OPEN_LUN)) {
+		zfcp_dbf_hba_fsf_resp("open", 4, req, dbf);
+
+	} else if (qtcb->header.log_length) {
+		zfcp_dbf_hba_fsf_resp("qtcb", 5, req, dbf);
+
+	} else {
+		zfcp_dbf_hba_fsf_resp("norm", 6, req, dbf);
+	}
+ }
+
+/**
+ * zfcp_dbf_hba_fsf_unsol - trace event for an unsolicited status buffer
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @dbf: reference to dbf structure
+ * @status_buffer: buffer containing payload of unsolicited status
+ */
+static inline
+void zfcp_dbf_hba_fsf_unsol(const char *tag, struct zfcp_dbf *dbf,
+			    struct fsf_status_read_buffer *buf)
+{
+	int level = 2;
+
+	if (level <= dbf->hba->level)
+		_zfcp_dbf_hba_fsf_unsol(tag, level, dbf, buf);
+}
+
+static inline
+void zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
+		   struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
+		   struct zfcp_fsf_req *req, unsigned long old_id)
+{
+	if (level <= dbf->scsi->level)
+		_zfcp_dbf_scsi(tag, tag2, level, dbf, scmd, req, old_id);
+}
+
+/**
+ * zfcp_dbf_scsi_result - trace event for SCSI command completion
+ * @tag: tag indicating success or failure of SCSI command
+ * @level: trace level applicable for this event
+ * @adapter: adapter that has been used to issue the SCSI command
+ * @scmd: SCSI command pointer
+ * @fsf_req: request used to issue SCSI command (might be NULL)
+ */
+static inline
+void zfcp_dbf_scsi_result(const char *tag, int level, struct zfcp_dbf *dbf,
+			  struct scsi_cmnd *scmd, struct zfcp_fsf_req *fsf_req)
+{
+	zfcp_dbf_scsi("rslt", tag, level, dbf, scmd, fsf_req, 0);
+}
+
+/**
+ * zfcp_dbf_scsi_abort - trace event for SCSI command abort
+ * @tag: tag indicating success or failure of abort operation
+ * @adapter: adapter thas has been used to issue SCSI command to be aborted
+ * @scmd: SCSI command to be aborted
+ * @new_req: request containing abort (might be NULL)
+ * @old_id: identifier of request containg SCSI command to be aborted
+ */
+static inline
+void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf,
+			 struct scsi_cmnd *scmd, struct zfcp_fsf_req *new_req,
+			 unsigned long old_id)
+{
+	zfcp_dbf_scsi("abrt", tag, 1, dbf, scmd, new_req, old_id);
+}
+
+/**
+ * zfcp_dbf_scsi_devreset - trace event for Logical Unit or Target Reset
+ * @tag: tag indicating success or failure of reset operation
+ * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
+ * @unit: unit that needs reset
+ * @scsi_cmnd: SCSI command which caused this error recovery
+ */
+static inline
+void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
+			    struct scsi_cmnd *scsi_cmnd)
+{
+	zfcp_dbf_scsi(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1,
+			    unit->port->adapter->dbf, scsi_cmnd, NULL, 0);
+}
+
 #endif /* ZFCP_DBF_H */
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 49d0532..7da2fad 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -37,10 +37,8 @@
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
 #include <asm/sysinfo.h>
-#include "zfcp_dbf.h"
 #include "zfcp_fsf.h"
 
-
 /********************* GENERAL DEFINES *********************************/
 
 #define REQUEST_LIST_SIZE 128
@@ -75,9 +73,6 @@
 
 /*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
 
-/* timeout for name-server lookup (in seconds) */
-#define ZFCP_NS_GID_PN_TIMEOUT		10
-
 /* task attribute values in FCP-2 FCP_CMND IU */
 #define SIMPLE_Q	0
 #define HEAD_OF_Q	1
@@ -224,8 +219,6 @@ struct zfcp_ls_adisc {
 #define ZFCP_STATUS_ADAPTER_QDIOUP		0x00000002
 #define ZFCP_STATUS_ADAPTER_XCONFIG_OK		0x00000008
 #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT	0x00000010
-#define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP	0x00000020
-#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL	0x00000080
 #define ZFCP_STATUS_ADAPTER_ERP_PENDING		0x00000100
 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED	0x00000200
 
@@ -234,6 +227,7 @@ struct zfcp_ls_adisc {
 
 /* remote port status */
 #define ZFCP_STATUS_PORT_PHYS_OPEN		0x00000001
+#define ZFCP_STATUS_PORT_LINK_TEST		0x00000002
 
 /* well known address (WKA) port status*/
 enum zfcp_wka_status {
@@ -249,7 +243,6 @@ enum zfcp_wka_status {
 
 /* FSF request status (this does not have a common part) */
 #define ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT	0x00000002
-#define ZFCP_STATUS_FSFREQ_COMPLETED		0x00000004
 #define ZFCP_STATUS_FSFREQ_ERROR		0x00000008
 #define ZFCP_STATUS_FSFREQ_CLEANUP		0x00000010
 #define ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED	0x00000040
@@ -266,12 +259,14 @@ struct zfcp_fsf_req;
 
 /* holds various memory pools of an adapter */
 struct zfcp_adapter_mempool {
-	mempool_t *fsf_req_erp;
-	mempool_t *fsf_req_scsi;
-	mempool_t *fsf_req_abort;
-	mempool_t *fsf_req_status_read;
-	mempool_t *data_status_read;
-	mempool_t *data_gid_pn;
+	mempool_t *erp_req;
+	mempool_t *gid_pn_req;
+	mempool_t *scsi_req;
+	mempool_t *scsi_abort;
+	mempool_t *status_read_req;
+	mempool_t *status_read_data;
+	mempool_t *gid_pn_data;
+	mempool_t *qtcb_pool;
 };
 
 /*
@@ -305,6 +300,15 @@ struct ct_iu_gid_pn_resp {
 	u32 d_id;
 } __attribute__ ((packed));
 
+struct ct_iu_gpn_ft_req {
+	struct ct_hdr header;
+	u8 flags;
+	u8 domain_id_scope;
+	u8 area_id_scope;
+	u8 fc4_type;
+} __attribute__ ((packed));
+
+
 /**
  * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct
  * @wka_port: port where the request is sent to
@@ -312,7 +316,6 @@ struct ct_iu_gid_pn_resp {
  * @resp: scatter-gather list for response
  * @handler: handler function (called for response to the request)
  * @handler_data: data passed to handler function
- * @timeout: FSF timeout for this request
  * @completion: completion for synchronization purposes
  * @status: used to pass error status to calling function
  */
@@ -322,7 +325,6 @@ struct zfcp_send_ct {
 	struct scatterlist *resp;
 	void (*handler)(unsigned long);
 	unsigned long handler_data;
-	int timeout;
 	struct completion *completion;
 	int status;
 };
@@ -420,6 +422,29 @@ struct zfcp_latencies {
 	spinlock_t lock;
 };
 
+/** struct zfcp_qdio - basic QDIO data structure
+ * @resp_q: response queue
+ * @req_q: request queue
+ * @stat_lock: lock to protect req_q_util and req_q_time
+ * @req_q_lock; lock to serialize access to request queue
+ * @req_q_time: time of last fill level change
+ * @req_q_util: used for accounting
+ * @req_q_full: queue full incidents
+ * @req_q_wq: used to wait for SBAL availability
+ * @adapter: adapter used in conjunction with this QDIO structure
+ */
+struct zfcp_qdio {
+	struct zfcp_qdio_queue	resp_q;
+	struct zfcp_qdio_queue	req_q;
+	spinlock_t		stat_lock;
+	spinlock_t		req_q_lock;
+	unsigned long long	req_q_time;
+	u64			req_q_util;
+	atomic_t		req_q_full;
+	wait_queue_head_t	req_q_wq;
+	struct zfcp_adapter	*adapter;
+};
+
 struct zfcp_adapter {
 	atomic_t                refcount;          /* reference count */
 	wait_queue_head_t	remove_wq;         /* can be used to wait for
@@ -428,6 +453,7 @@ struct zfcp_adapter {
 	u64			peer_wwpn;	   /* P2P peer WWPN */
 	u32			peer_d_id;	   /* P2P peer D_ID */
 	struct ccw_device       *ccw_device;	   /* S/390 ccw device */
+	struct zfcp_qdio	*qdio;
 	u32			hydra_version;	   /* Hydra version */
 	u32			fsf_lic_version;
 	u32			adapter_features;  /* FCP channel features */
@@ -439,15 +465,7 @@ struct zfcp_adapter {
 	unsigned long		req_no;		   /* unique FSF req number */
 	struct list_head	*req_list;	   /* list of pending reqs */
 	spinlock_t		req_list_lock;	   /* request list lock */
-	struct zfcp_qdio_queue	req_q;		   /* request queue */
-	spinlock_t		req_q_lock;	   /* for operations on queue */
-	ktime_t			req_q_time; /* time of last fill level change */
-	u64			req_q_util; /* for accounting */
-	spinlock_t		qdio_stat_lock;
 	u32			fsf_req_seq_no;	   /* FSF cmnd seq number */
-	wait_queue_head_t	request_wq;	   /* can be used to wait for
-						      more avaliable SBALs */
-	struct zfcp_qdio_queue	resp_q;	   /* response queue */
 	rwlock_t		abort_lock;        /* Protects against SCSI
 						      stack abort/command
 						      completion races */
@@ -456,10 +474,9 @@ struct zfcp_adapter {
 	atomic_t		status;	           /* status of this adapter */
 	struct list_head	erp_ready_head;	   /* error recovery for this
 						      adapter/devices */
+	wait_queue_head_t	erp_ready_wq;
 	struct list_head	erp_running_head;
 	rwlock_t		erp_lock;
-	struct semaphore	erp_ready_sem;
-	wait_queue_head_t	erp_thread_wqh;
 	wait_queue_head_t	erp_done_wqh;
 	struct zfcp_erp_action	erp_action;	   /* pending error recovery */
         atomic_t                erp_counter;
@@ -467,27 +484,16 @@ struct zfcp_adapter {
 						      actions */
 	u32			erp_low_mem_count; /* nr of erp actions waiting
 						      for memory */
+	struct task_struct	*erp_thread;
 	struct zfcp_wka_ports	*gs;		   /* generic services */
-	debug_info_t		*rec_dbf;
-	debug_info_t		*hba_dbf;
-	debug_info_t		*san_dbf;          /* debug feature areas */
-	debug_info_t		*scsi_dbf;
-	spinlock_t		rec_dbf_lock;
-	spinlock_t		hba_dbf_lock;
-	spinlock_t		san_dbf_lock;
-	spinlock_t		scsi_dbf_lock;
-	struct zfcp_rec_dbf_record	rec_dbf_buf;
-	struct zfcp_hba_dbf_record	hba_dbf_buf;
-	struct zfcp_san_dbf_record	san_dbf_buf;
-	struct zfcp_scsi_dbf_record	scsi_dbf_buf;
+	struct zfcp_dbf		*dbf;		   /* debug traces */
 	struct zfcp_adapter_mempool	pool;      /* Adapter memory pools */
-	struct qdio_initialize  qdio_init_data;    /* for qdio_establish */
 	struct fc_host_statistics *fc_stats;
 	struct fsf_qtcb_bottom_port *stats_reset_data;
 	unsigned long		stats_reset;
 	struct work_struct	scan_work;
 	struct service_level	service_level;
-	atomic_t		qdio_outb_full;	   /* queue full incidents */
+	struct workqueue_struct	*work_queue;
 };
 
 struct zfcp_port {
@@ -531,36 +537,64 @@ struct zfcp_unit {
 	struct work_struct	scsi_work;
 };
 
-/* FSF request */
+/**
+ * struct zfcp_queue_req - queue related values for a request
+ * @sbal_number: number of free SBALs
+ * @sbal_first: first SBAL for this request
+ * @sbal_last: last SBAL for this request
+ * @sbal_limit: last possible SBAL for this request
+ * @sbale_curr: current SBALE at creation of this request
+ * @sbal_response: SBAL used in interrupt
+ * @qdio_outb_usage: usage of outbound queue
+ * @qdio_inb_usage: usage of inbound queue
+ */
+struct zfcp_queue_req {
+	u8		       sbal_number;
+	u8		       sbal_first;
+	u8		       sbal_last;
+	u8		       sbal_limit;
+	u8		       sbale_curr;
+	u8		       sbal_response;
+	u16		       qdio_outb_usage;
+	u16		       qdio_inb_usage;
+};
+
+/**
+ * struct zfcp_fsf_req - basic FSF request structure
+ * @list: list of FSF requests
+ * @req_id: unique request ID
+ * @adapter: adapter this request belongs to
+ * @queue_req: queue related values
+ * @completion: used to signal the completion of the request
+ * @status: status of the request
+ * @fsf_command: FSF command issued
+ * @qtcb: associated QTCB
+ * @seq_no: sequence number of this request
+ * @data: private data
+ * @timer: timer data of this request
+ * @erp_action: reference to erp action if request issued on behalf of ERP
+ * @pool: reference to memory pool if used for this request
+ * @issued: time when request was send (STCK)
+ * @unit: reference to unit if this request is a SCSI request
+ * @handler: handler which should be called to process response
+ */
 struct zfcp_fsf_req {
-	struct list_head       list;	       /* list of FSF requests */
-	unsigned long	       req_id;	       /* unique request ID */
-	struct zfcp_adapter    *adapter;       /* adapter request belongs to */
-	u8		       sbal_number;    /* nr of SBALs free for use */
-	u8		       sbal_first;     /* first SBAL for this request */
-	u8		       sbal_last;      /* last SBAL for this request */
-	u8		       sbal_limit;      /* last possible SBAL for
-						  this reuest */
-	u8		       sbale_curr;     /* current SBALE during creation
-						  of request */
-	u8			sbal_response;	/* SBAL used in interrupt */
-	wait_queue_head_t      completion_wq;  /* can be used by a routine
-						  to wait for completion */
-	u32			status;	       /* status of this request */
-	u32		       fsf_command;    /* FSF Command copy */
-	struct fsf_qtcb	       *qtcb;	       /* address of associated QTCB */
-	u32		       seq_no;         /* Sequence number of request */
-	void			*data;           /* private data of request */
-	struct timer_list     timer;	       /* used for erp or scsi er */
-	struct zfcp_erp_action *erp_action;    /* used if this request is
-						  issued on behalf of erp */
-	mempool_t	       *pool;	       /* used if request was alloacted
-						  from emergency pool */
-	unsigned long long     issued;         /* request sent time (STCK) */
-	struct zfcp_unit       *unit;
+	struct list_head	list;
+	unsigned long		req_id;
+	struct zfcp_adapter	*adapter;
+	struct zfcp_queue_req	queue_req;
+	struct completion	completion;
+	u32			status;
+	u32			fsf_command;
+	struct fsf_qtcb		*qtcb;
+	u32			seq_no;
+	void			*data;
+	struct timer_list	timer;
+	struct zfcp_erp_action	*erp_action;
+	mempool_t		*pool;
+	unsigned long long	issued;
+	struct zfcp_unit	*unit;
 	void			(*handler)(struct zfcp_fsf_req *);
-	u16			qdio_outb_usage;/* usage of outbound queue */
-	u16			qdio_inb_usage;	/* usage of inbound queue */
 };
 
 /* driver data */
@@ -570,18 +604,11 @@ struct zfcp_data {
 	rwlock_t                config_lock;        /* serialises changes
 						       to adapter/port/unit
 						       lists */
-	struct semaphore        config_sema;        /* serialises configuration
-						       changes */
-	struct kmem_cache	*fsf_req_qtcb_cache;
+	struct mutex		config_mutex;
+	struct kmem_cache	*gpn_ft_cache;
+	struct kmem_cache	*qtcb_cache;
 	struct kmem_cache	*sr_buffer_cache;
 	struct kmem_cache	*gid_pn_cache;
-	struct workqueue_struct	*work_queue;
-};
-
-/* struct used by memory pools for fsf_requests */
-struct zfcp_fsf_req_qtcb {
-	struct zfcp_fsf_req fsf_req;
-	struct fsf_qtcb qtcb;
 };
 
 /********************** ZFCP SPECIFIC DEFINES ********************************/
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index c75d6f3..73d366b 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -9,6 +9,7 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/kthread.h>
 #include "zfcp_ext.h"
 
 #define ZFCP_MAX_ERPS                   3
@@ -26,7 +27,6 @@ enum zfcp_erp_steps {
 	ZFCP_ERP_STEP_FSF_XCONFIG	= 0x0001,
 	ZFCP_ERP_STEP_PHYS_PORT_CLOSING	= 0x0010,
 	ZFCP_ERP_STEP_PORT_CLOSING	= 0x0100,
-	ZFCP_ERP_STEP_NAMESERVER_LOOKUP	= 0x0400,
 	ZFCP_ERP_STEP_PORT_OPENING	= 0x0800,
 	ZFCP_ERP_STEP_UNIT_CLOSING	= 0x1000,
 	ZFCP_ERP_STEP_UNIT_OPENING	= 0x2000,
@@ -75,9 +75,9 @@ static void zfcp_erp_action_ready(struct zfcp_erp_action *act)
 	struct zfcp_adapter *adapter = act->adapter;
 
 	list_move(&act->list, &act->adapter->erp_ready_head);
-	zfcp_rec_dbf_event_action("erardy1", act);
-	up(&adapter->erp_ready_sem);
-	zfcp_rec_dbf_event_thread("erardy2", adapter);
+	zfcp_dbf_rec_action("erardy1", act);
+	wake_up(&adapter->erp_ready_wq);
+	zfcp_dbf_rec_thread("erardy2", adapter->dbf);
 }
 
 static void zfcp_erp_action_dismiss(struct zfcp_erp_action *act)
@@ -150,6 +150,9 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
 		a_status = atomic_read(&adapter->status);
 		if (a_status & ZFCP_STATUS_COMMON_ERP_INUSE)
 			return 0;
+		if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) &&
+		    !(a_status & ZFCP_STATUS_COMMON_OPEN))
+			return 0; /* shutdown requested for closed adapter */
 	}
 
 	return need;
@@ -213,8 +216,7 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
 	int retval = 1, need;
 	struct zfcp_erp_action *act = NULL;
 
-	if (!(atomic_read(&adapter->status) &
-	      ZFCP_STATUS_ADAPTER_ERP_THREAD_UP))
+	if (!adapter->erp_thread)
 		return -EIO;
 
 	need = zfcp_erp_required_act(want, adapter, port, unit);
@@ -227,12 +229,11 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
 		goto out;
 	++adapter->erp_total_count;
 	list_add_tail(&act->list, &adapter->erp_ready_head);
-	up(&adapter->erp_ready_sem);
-	zfcp_rec_dbf_event_thread("eracte1", adapter);
+	wake_up(&adapter->erp_ready_wq);
+	zfcp_dbf_rec_thread("eracte1", adapter->dbf);
 	retval = 0;
  out:
-	zfcp_rec_dbf_event_trigger(id, ref, want, need, act,
-				   adapter, port, unit);
+	zfcp_dbf_rec_trigger(id, ref, want, need, act, adapter, port, unit);
 	return retval;
 }
 
@@ -443,28 +444,28 @@ static int status_change_clear(unsigned long mask, atomic_t *status)
 static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
 {
 	if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status))
-		zfcp_rec_dbf_event_adapter("eraubl1", NULL, adapter);
+		zfcp_dbf_rec_adapter("eraubl1", NULL, adapter->dbf);
 	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
 }
 
 static void zfcp_erp_port_unblock(struct zfcp_port *port)
 {
 	if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status))
-		zfcp_rec_dbf_event_port("erpubl1", NULL, port);
+		zfcp_dbf_rec_port("erpubl1", NULL, port);
 	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);
 }
 
 static void zfcp_erp_unit_unblock(struct zfcp_unit *unit)
 {
 	if (status_change_set(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status))
-		zfcp_rec_dbf_event_unit("eruubl1", NULL, unit);
+		zfcp_dbf_rec_unit("eruubl1", NULL, unit);
 	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);
 }
 
 static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
 {
 	list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
-	zfcp_rec_dbf_event_action("erator1", erp_action);
+	zfcp_dbf_rec_action("erator1", erp_action);
 }
 
 static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
@@ -480,13 +481,12 @@ static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
 		if (act->status & (ZFCP_STATUS_ERP_DISMISSED |
 				   ZFCP_STATUS_ERP_TIMEDOUT)) {
 			act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
-			zfcp_rec_dbf_event_action("erscf_1", act);
+			zfcp_dbf_rec_action("erscf_1", act);
 			act->fsf_req->erp_action = NULL;
 		}
 		if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
-			zfcp_rec_dbf_event_action("erscf_2", act);
-		if (act->fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |
-					    ZFCP_STATUS_FSFREQ_DISMISSED))
+			zfcp_dbf_rec_action("erscf_2", act);
+		if (act->fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
 			act->fsf_req = NULL;
 	} else
 		act->fsf_req = NULL;
@@ -604,9 +604,11 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter)
 
 static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act)
 {
-	if (zfcp_qdio_open(act->adapter))
+	struct zfcp_qdio *qdio = act->adapter->qdio;
+
+	if (zfcp_qdio_open(qdio))
 		return ZFCP_ERP_FAILED;
-	init_waitqueue_head(&act->adapter->request_wq);
+	init_waitqueue_head(&qdio->req_q_wq);
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &act->adapter->status);
 	return ZFCP_ERP_SUCCEEDED;
 }
@@ -641,9 +643,10 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
 			return ZFCP_ERP_FAILED;
 		}
 
-		zfcp_rec_dbf_event_thread_lock("erasfx1", adapter);
-		down(&adapter->erp_ready_sem);
-		zfcp_rec_dbf_event_thread_lock("erasfx2", adapter);
+		zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf);
+		wait_event(adapter->erp_ready_wq,
+			   !list_empty(&adapter->erp_ready_head));
+		zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf);
 		if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
 			break;
 
@@ -682,9 +685,10 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
 	if (ret)
 		return ZFCP_ERP_FAILED;
 
-	zfcp_rec_dbf_event_thread_lock("erasox1", adapter);
-	down(&adapter->erp_ready_sem);
-	zfcp_rec_dbf_event_thread_lock("erasox2", adapter);
+	zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf);
+	wait_event(adapter->erp_ready_wq,
+		   !list_empty(&adapter->erp_ready_head));
+	zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf);
 	if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
 		return ZFCP_ERP_FAILED;
 
@@ -711,10 +715,10 @@ static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act)
 	struct zfcp_adapter *adapter = act->adapter;
 
 	/* close queues to ensure that buffers are not accessed by adapter */
-	zfcp_qdio_close(adapter);
+	zfcp_qdio_close(adapter->qdio);
 	zfcp_fsf_req_dismiss_all(adapter);
 	adapter->fsf_req_seq_no = 0;
-	zfcp_fc_wka_port_force_offline(&adapter->gs->ds);
+	zfcp_fc_wka_ports_force_offline(adapter->gs);
 	/* all ports and units are closed */
 	zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL,
 				       ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
@@ -841,27 +845,6 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
 	return zfcp_erp_port_strategy_open_port(act);
 }
 
-void zfcp_erp_port_strategy_open_lookup(struct work_struct *work)
-{
-	int retval;
-	struct zfcp_port *port = container_of(work, struct zfcp_port,
-					      gid_pn_work);
-
-	retval = zfcp_fc_ns_gid_pn(&port->erp_action);
-	if (!retval) {
-		port->erp_action.step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
-		goto out;
-	}
-	if (retval == -ENOMEM) {
-		zfcp_erp_notify(&port->erp_action, ZFCP_STATUS_ERP_LOWMEM);
-		goto out;
-	}
-	/* all other error condtions */
-	zfcp_erp_notify(&port->erp_action, 0);
-out:
-	zfcp_port_put(port);
-}
-
 static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
 {
 	struct zfcp_adapter *adapter = act->adapter;
@@ -876,15 +859,11 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
 			return zfcp_erp_open_ptp_port(act);
 		if (!port->d_id) {
 			zfcp_port_get(port);
-			if (!queue_work(zfcp_data.work_queue,
+			if (!queue_work(adapter->work_queue,
 					&port->gid_pn_work))
 				zfcp_port_put(port);
-			return ZFCP_ERP_CONTINUES;
+			return ZFCP_ERP_EXIT;
 		}
-		/* fall through */
-	case ZFCP_ERP_STEP_NAMESERVER_LOOKUP:
-		if (!port->d_id)
-			return ZFCP_ERP_FAILED;
 		return zfcp_erp_port_strategy_open_port(act);
 
 	case ZFCP_ERP_STEP_PORT_OPENING:
@@ -1163,7 +1142,7 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
 	}
 
 	list_del(&erp_action->list);
-	zfcp_rec_dbf_event_action("eractd1", erp_action);
+	zfcp_dbf_rec_action("eractd1", erp_action);
 
 	switch (erp_action->action) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
@@ -1311,20 +1290,16 @@ static int zfcp_erp_thread(void *data)
 	struct list_head *next;
 	struct zfcp_erp_action *act;
 	unsigned long flags;
-	int ignore;
-
-	daemonize("zfcperp%s", dev_name(&adapter->ccw_device->dev));
-	/* Block all signals */
-	siginitsetinv(&current->blocked, 0);
-	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-	wake_up(&adapter->erp_thread_wqh);
 
-	while (!(atomic_read(&adapter->status) &
-		 ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) {
+	for (;;) {
+		zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf);
+		wait_event_interruptible(adapter->erp_ready_wq,
+			   !list_empty(&adapter->erp_ready_head) ||
+			   kthread_should_stop());
+		zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf);
 
-		zfcp_rec_dbf_event_thread_lock("erthrd1", adapter);
-		ignore = down_interruptible(&adapter->erp_ready_sem);
-		zfcp_rec_dbf_event_thread_lock("erthrd2", adapter);
+		if (kthread_should_stop())
+			break;
 
 		write_lock_irqsave(&adapter->erp_lock, flags);
 		next = adapter->erp_ready_head.next;
@@ -1339,9 +1314,6 @@ static int zfcp_erp_thread(void *data)
 		}
 	}
 
-	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-	wake_up(&adapter->erp_thread_wqh);
-
 	return 0;
 }
 
@@ -1353,18 +1325,17 @@ static int zfcp_erp_thread(void *data)
  */
 int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
 {
-	int retval;
+	struct task_struct *thread;
 
-	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-	retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
-	if (retval < 0) {
+	thread = kthread_run(zfcp_erp_thread, adapter, "zfcperp%s",
+			     dev_name(&adapter->ccw_device->dev));
+	if (IS_ERR(thread)) {
 		dev_err(&adapter->ccw_device->dev,
 			"Creating an ERP thread for the FCP device failed.\n");
-		return retval;
+		return PTR_ERR(thread);
 	}
-	wait_event(adapter->erp_thread_wqh,
-		   atomic_read(&adapter->status) &
-			ZFCP_STATUS_ADAPTER_ERP_THREAD_UP);
+
+	adapter->erp_thread = thread;
 	return 0;
 }
 
@@ -1379,16 +1350,10 @@ int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
  */
 void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
 {
-	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
-	up(&adapter->erp_ready_sem);
-	zfcp_rec_dbf_event_thread_lock("erthrk1", adapter);
-
-	wait_event(adapter->erp_thread_wqh,
-		   !(atomic_read(&adapter->status) &
-				ZFCP_STATUS_ADAPTER_ERP_THREAD_UP));
-
-	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
-			  &adapter->status);
+	kthread_stop(adapter->erp_thread);
+	adapter->erp_thread = NULL;
+	WARN_ON(!list_empty(&adapter->erp_ready_head));
+	WARN_ON(!list_empty(&adapter->erp_running_head));
 }
 
 /**
@@ -1456,11 +1421,11 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id,
 
 	if (set_or_clear == ZFCP_SET) {
 		if (status_change_set(mask, &adapter->status))
-			zfcp_rec_dbf_event_adapter(id, ref, adapter);
+			zfcp_dbf_rec_adapter(id, ref, adapter->dbf);
 		atomic_set_mask(mask, &adapter->status);
 	} else {
 		if (status_change_clear(mask, &adapter->status))
-			zfcp_rec_dbf_event_adapter(id, ref, adapter);
+			zfcp_dbf_rec_adapter(id, ref, adapter->dbf);
 		atomic_clear_mask(mask, &adapter->status);
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
 			atomic_set(&adapter->erp_counter, 0);
@@ -1490,11 +1455,11 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref,
 
 	if (set_or_clear == ZFCP_SET) {
 		if (status_change_set(mask, &port->status))
-			zfcp_rec_dbf_event_port(id, ref, port);
+			zfcp_dbf_rec_port(id, ref, port);
 		atomic_set_mask(mask, &port->status);
 	} else {
 		if (status_change_clear(mask, &port->status))
-			zfcp_rec_dbf_event_port(id, ref, port);
+			zfcp_dbf_rec_port(id, ref, port);
 		atomic_clear_mask(mask, &port->status);
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
 			atomic_set(&port->erp_counter, 0);
@@ -1519,11 +1484,11 @@ void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref,
 {
 	if (set_or_clear == ZFCP_SET) {
 		if (status_change_set(mask, &unit->status))
-			zfcp_rec_dbf_event_unit(id, ref, unit);
+			zfcp_dbf_rec_unit(id, ref, unit);
 		atomic_set_mask(mask, &unit->status);
 	} else {
 		if (status_change_clear(mask, &unit->status))
-			zfcp_rec_dbf_event_unit(id, ref, unit);
+			zfcp_dbf_rec_unit(id, ref, unit);
 		atomic_clear_mask(mask, &unit->status);
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) {
 			atomic_set(&unit->erp_counter, 0);
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 3044c60..36935bc 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -34,37 +34,31 @@ extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *);
 extern struct miscdevice zfcp_cfdc_misc;
 
 /* zfcp_dbf.c */
-extern int zfcp_adapter_debug_register(struct zfcp_adapter *);
-extern void zfcp_adapter_debug_unregister(struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_thread(char *, struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_thread_lock(char *, struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_adapter(char *, void *, struct zfcp_adapter *);
-extern void zfcp_rec_dbf_event_port(char *, void *, struct zfcp_port *);
-extern void zfcp_rec_dbf_event_unit(char *, void *, struct zfcp_unit *);
-extern void zfcp_rec_dbf_event_trigger(char *, void *, u8, u8, void *,
-				       struct zfcp_adapter *,
-				       struct zfcp_port *, struct zfcp_unit *);
-extern void zfcp_rec_dbf_event_action(char *, struct zfcp_erp_action *);
-extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
-extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
-					 struct fsf_status_read_buffer *);
-extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, unsigned int, int,
-				    int);
-extern void zfcp_hba_dbf_event_berr(struct zfcp_adapter *,
-				    struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *);
-extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *,
-				       struct scsi_cmnd *,
-				       struct zfcp_fsf_req *);
-extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
-				      struct scsi_cmnd *, struct zfcp_fsf_req *,
-				      unsigned long);
-extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
-					 struct scsi_cmnd *);
+extern int zfcp_dbf_adapter_register(struct zfcp_adapter *);
+extern void zfcp_dbf_adapter_unregister(struct zfcp_dbf *);
+extern void zfcp_dbf_rec_thread(char *, struct zfcp_dbf *);
+extern void zfcp_dbf_rec_thread_lock(char *, struct zfcp_dbf *);
+extern void zfcp_dbf_rec_adapter(char *, void *, struct zfcp_dbf *);
+extern void zfcp_dbf_rec_port(char *, void *, struct zfcp_port *);
+extern void zfcp_dbf_rec_unit(char *, void *, struct zfcp_unit *);
+extern void zfcp_dbf_rec_trigger(char *, void *, u8, u8, void *,
+				 struct zfcp_adapter *, struct zfcp_port *,
+				 struct zfcp_unit *);
+extern void zfcp_dbf_rec_action(char *, struct zfcp_erp_action *);
+extern void _zfcp_dbf_hba_fsf_response(const char *, int, struct zfcp_fsf_req *,
+				       struct zfcp_dbf *);
+extern void _zfcp_dbf_hba_fsf_unsol(const char *, int level, struct zfcp_dbf *,
+					  struct fsf_status_read_buffer *);
+extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int);
+extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_els_request(struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_els_response(struct zfcp_fsf_req *);
+extern void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *);
+extern void _zfcp_dbf_scsi(const char *, const char *, int, struct zfcp_dbf *,
+			   struct scsi_cmnd *, struct zfcp_fsf_req *,
+			   unsigned long);
 
 /* zfcp_erp.c */
 extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, char *,
@@ -96,22 +90,20 @@ extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, char *, void *);
 extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, char *,
 					    void *);
 extern void zfcp_erp_timeout_handler(unsigned long);
-extern void zfcp_erp_port_strategy_open_lookup(struct work_struct *);
 
 /* zfcp_fc.c */
-extern int zfcp_scan_ports(struct zfcp_adapter *);
-extern void _zfcp_scan_ports_later(struct work_struct *);
+extern int zfcp_fc_scan_ports(struct zfcp_adapter *);
+extern void _zfcp_fc_scan_ports_later(struct work_struct *);
 extern void zfcp_fc_incoming_els(struct zfcp_fsf_req *);
-extern int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *);
+extern void zfcp_fc_port_did_lookup(struct work_struct *);
 extern void zfcp_fc_plogi_evaluate(struct zfcp_port *, struct fsf_plogi *);
-extern void zfcp_test_link(struct zfcp_port *);
+extern void zfcp_fc_test_link(struct zfcp_port *);
 extern void zfcp_fc_link_test_work(struct work_struct *);
-extern void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *);
-extern void zfcp_fc_wka_ports_init(struct zfcp_adapter *);
+extern void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *);
+extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
+extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
 extern int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *);
 extern int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *);
-extern void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *);
-
 
 /* zfcp_fsf.c */
 extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
@@ -122,37 +114,39 @@ extern int zfcp_fsf_close_physical_port(struct zfcp_erp_action *);
 extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
 extern int zfcp_fsf_close_unit(struct zfcp_erp_action *);
 extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *);
-extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *,
+extern int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *,
 					      struct fsf_qtcb_bottom_config *);
 extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *);
-extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *,
+extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *,
 					    struct fsf_qtcb_bottom_port *);
 extern struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *,
 						  struct zfcp_fsf_cfdc *);
 extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
-extern int zfcp_fsf_status_read(struct zfcp_adapter *);
+extern int zfcp_fsf_status_read(struct zfcp_qdio *);
 extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
-extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
-			    struct zfcp_erp_action *);
+extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *);
 extern int zfcp_fsf_send_els(struct zfcp_send_els *);
 extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
 					  struct scsi_cmnd *);
-extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *);
 extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
 extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
 extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
 						       struct zfcp_unit *);
+extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int);
 
 /* zfcp_qdio.c */
-extern int zfcp_qdio_allocate(struct zfcp_adapter *);
-extern void zfcp_qdio_free(struct zfcp_adapter *);
-extern int zfcp_qdio_send(struct zfcp_fsf_req *);
-extern struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *);
-extern struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *);
-extern int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *, unsigned long,
+extern int zfcp_qdio_setup(struct zfcp_adapter *);
+extern void zfcp_qdio_destroy(struct zfcp_qdio *);
+extern int zfcp_qdio_send(struct zfcp_qdio *, struct zfcp_queue_req *);
+extern struct qdio_buffer_element
+	*zfcp_qdio_sbale_req(struct zfcp_qdio *, struct zfcp_queue_req *);
+extern struct qdio_buffer_element
+	*zfcp_qdio_sbale_curr(struct zfcp_qdio *, struct zfcp_queue_req *);
+extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *,
+				   struct zfcp_queue_req *, unsigned long,
 				   struct scatterlist *, int);
-extern int zfcp_qdio_open(struct zfcp_adapter *);
-extern void zfcp_qdio_close(struct zfcp_adapter *);
+extern int zfcp_qdio_open(struct zfcp_qdio *);
+extern void zfcp_qdio_close(struct zfcp_qdio *);
 
 /* zfcp_scsi.c */
 extern struct zfcp_data zfcp_data;
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 47daebf..722f22d 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -25,14 +25,6 @@ static u32 rscn_range_mask[] = {
 	[RSCN_FABRIC_ADDRESS]		= 0x000000,
 };
 
-struct ct_iu_gpn_ft_req {
-	struct ct_hdr header;
-	u8 flags;
-	u8 domain_id_scope;
-	u8 area_id_scope;
-	u8 fc4_type;
-} __attribute__ ((packed));
-
 struct gpn_ft_resp_acc {
 	u8 control;
 	u8 port_id[3];
@@ -65,7 +57,7 @@ struct zfcp_fc_ns_handler_data {
 	unsigned long handler_data;
 };
 
-static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)
+static int zfcp_fc_wka_port_get(struct zfcp_wka_port *wka_port)
 {
 	if (mutex_lock_interruptible(&wka_port->mutex))
 		return -ERESTARTSYS;
@@ -90,7 +82,7 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)
 	return -EIO;
 }
 
-static void zfcp_wka_port_offline(struct work_struct *work)
+static void zfcp_fc_wka_port_offline(struct work_struct *work)
 {
 	struct delayed_work *dw = to_delayed_work(work);
 	struct zfcp_wka_port *wka_port =
@@ -110,7 +102,7 @@ out:
 	mutex_unlock(&wka_port->mutex);
 }
 
-static void zfcp_wka_port_put(struct zfcp_wka_port *wka_port)
+static void zfcp_fc_wka_port_put(struct zfcp_wka_port *wka_port)
 {
 	if (atomic_dec_return(&wka_port->refcount) != 0)
 		return;
@@ -129,10 +121,10 @@ static void zfcp_fc_wka_port_init(struct zfcp_wka_port *wka_port, u32 d_id,
 	wka_port->status = ZFCP_WKA_PORT_OFFLINE;
 	atomic_set(&wka_port->refcount, 0);
 	mutex_init(&wka_port->mutex);
-	INIT_DELAYED_WORK(&wka_port->work, zfcp_wka_port_offline);
+	INIT_DELAYED_WORK(&wka_port->work, zfcp_fc_wka_port_offline);
 }
 
-void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
+static void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
 {
 	cancel_delayed_work_sync(&wka->work);
 	mutex_lock(&wka->mutex);
@@ -140,15 +132,13 @@ void zfcp_fc_wka_port_force_offline(struct zfcp_wka_port *wka)
 	mutex_unlock(&wka->mutex);
 }
 
-void zfcp_fc_wka_ports_init(struct zfcp_adapter *adapter)
+void zfcp_fc_wka_ports_force_offline(struct zfcp_wka_ports *gs)
 {
-	struct zfcp_wka_ports *gs = adapter->gs;
-
-	zfcp_fc_wka_port_init(&gs->ms, FC_FID_MGMT_SERV, adapter);
-	zfcp_fc_wka_port_init(&gs->ts, FC_FID_TIME_SERV, adapter);
-	zfcp_fc_wka_port_init(&gs->ds, FC_FID_DIR_SERV, adapter);
-	zfcp_fc_wka_port_init(&gs->as, FC_FID_ALIASES, adapter);
-	zfcp_fc_wka_port_init(&gs->ks, FC_FID_SEC_KEY, adapter);
+	zfcp_fc_wka_port_force_offline(&gs->ms);
+	zfcp_fc_wka_port_force_offline(&gs->ts);
+	zfcp_fc_wka_port_force_offline(&gs->ds);
+	zfcp_fc_wka_port_force_offline(&gs->as);
+	zfcp_fc_wka_port_force_offline(&gs->ks);
 }
 
 static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
@@ -160,7 +150,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) {
 		if ((port->d_id & range) == (elem->nport_did & range))
-			zfcp_test_link(port);
+			zfcp_fc_test_link(port);
 		if (!port->d_id)
 			zfcp_erp_port_reopen(port,
 					     ZFCP_STATUS_COMMON_ERP_FAILED,
@@ -241,7 +231,7 @@ void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
 		(struct fsf_status_read_buffer *) fsf_req->data;
 	unsigned int els_type = status_buffer->payload.data[0];
 
-	zfcp_san_dbf_event_incoming_els(fsf_req);
+	zfcp_dbf_san_incoming_els(fsf_req);
 	if (els_type == LS_PLOGI)
 		zfcp_fc_incoming_plogi(fsf_req);
 	else if (els_type == LS_LOGO)
@@ -281,19 +271,18 @@ static void zfcp_fc_ns_gid_pn_eval(unsigned long data)
 	port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK;
 }
 
-int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
+static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
 				     struct zfcp_gid_pn_data *gid_pn)
 {
-	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_fc_ns_handler_data compl_rec;
 	int ret;
 
 	/* setup parameters for send generic command */
-	gid_pn->port = erp_action->port;
+	gid_pn->port = port;
 	gid_pn->ct.wka_port = &adapter->gs->ds;
 	gid_pn->ct.handler = zfcp_fc_ns_handler;
 	gid_pn->ct.handler_data = (unsigned long) &compl_rec;
-	gid_pn->ct.timeout = ZFCP_NS_GID_PN_TIMEOUT;
 	gid_pn->ct.req = &gid_pn->req;
 	gid_pn->ct.resp = &gid_pn->resp;
 	sg_init_one(&gid_pn->req, &gid_pn->ct_iu_req,
@@ -308,13 +297,12 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
 	gid_pn->ct_iu_req.header.options = ZFCP_CT_SYNCHRONOUS;
 	gid_pn->ct_iu_req.header.cmd_rsp_code = ZFCP_CT_GID_PN;
 	gid_pn->ct_iu_req.header.max_res_size = ZFCP_CT_SIZE_ONE_PAGE / 4;
-	gid_pn->ct_iu_req.wwpn = erp_action->port->wwpn;
+	gid_pn->ct_iu_req.wwpn = port->wwpn;
 
 	init_completion(&compl_rec.done);
 	compl_rec.handler = zfcp_fc_ns_gid_pn_eval;
 	compl_rec.handler_data = (unsigned long) gid_pn;
-	ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.fsf_req_erp,
-			       erp_action);
+	ret = zfcp_fsf_send_ct(&gid_pn->ct, adapter->pool.gid_pn_req);
 	if (!ret)
 		wait_for_completion(&compl_rec.done);
 	return ret;
@@ -322,33 +310,56 @@ int static zfcp_fc_ns_gid_pn_request(struct zfcp_erp_action *erp_action,
 
 /**
  * zfcp_fc_ns_gid_pn_request - initiate GID_PN nameserver request
- * @erp_action: pointer to zfcp_erp_action where GID_PN request is needed
+ * @port: port where GID_PN request is needed
  * return: -ENOMEM on error, 0 otherwise
  */
-int zfcp_fc_ns_gid_pn(struct zfcp_erp_action *erp_action)
+static int zfcp_fc_ns_gid_pn(struct zfcp_port *port)
 {
 	int ret;
 	struct zfcp_gid_pn_data *gid_pn;
-	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_adapter *adapter = port->adapter;
 
-	gid_pn = mempool_alloc(adapter->pool.data_gid_pn, GFP_ATOMIC);
+	gid_pn = mempool_alloc(adapter->pool.gid_pn_data, GFP_ATOMIC);
 	if (!gid_pn)
 		return -ENOMEM;
 
 	memset(gid_pn, 0, sizeof(*gid_pn));
 
-	ret = zfcp_wka_port_get(&adapter->gs->ds);
+	ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
 	if (ret)
 		goto out;
 
-	ret = zfcp_fc_ns_gid_pn_request(erp_action, gid_pn);
+	ret = zfcp_fc_ns_gid_pn_request(port, gid_pn);
 
-	zfcp_wka_port_put(&adapter->gs->ds);
+	zfcp_fc_wka_port_put(&adapter->gs->ds);
 out:
-	mempool_free(gid_pn, adapter->pool.data_gid_pn);
+	mempool_free(gid_pn, adapter->pool.gid_pn_data);
 	return ret;
 }
 
+void zfcp_fc_port_did_lookup(struct work_struct *work)
+{
+	int ret;
+	struct zfcp_port *port = container_of(work, struct zfcp_port,
+					      gid_pn_work);
+
+	ret = zfcp_fc_ns_gid_pn(port);
+	if (ret) {
+		/* could not issue gid_pn for some reason */
+		zfcp_erp_adapter_reopen(port->adapter, 0, "fcgpn_1", NULL);
+		goto out;
+	}
+
+	if (!port->d_id) {
+		zfcp_erp_port_failed(port, "fcgpn_2", NULL);
+		goto out;
+	}
+
+	zfcp_erp_port_reopen(port, 0, "fcgpn_3", NULL);
+out:
+	zfcp_port_put(port);
+}
+
 /**
  * zfcp_fc_plogi_evaluate - evaluate PLOGI playload
  * @port: zfcp_port structure
@@ -404,6 +415,7 @@ static void zfcp_fc_adisc_handler(unsigned long data)
 	/* port is good, unblock rport without going through erp */
 	zfcp_scsi_schedule_rport_register(port);
  out:
+	atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
 	zfcp_port_put(port);
 	kfree(adisc);
 }
@@ -450,28 +462,36 @@ void zfcp_fc_link_test_work(struct work_struct *work)
 	port->rport_task = RPORT_DEL;
 	zfcp_scsi_rport_work(&port->rport_work);
 
+	/* only issue one test command at one time per port */
+	if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST)
+		goto out;
+
+	atomic_set_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
+
 	retval = zfcp_fc_adisc(port);
 	if (retval == 0)
 		return;
 
 	/* send of ADISC was not possible */
+	atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
 	zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
 
+out:
 	zfcp_port_put(port);
 }
 
 /**
- * zfcp_test_link - lightweight link test procedure
+ * zfcp_fc_test_link - lightweight link test procedure
  * @port: port to be tested
  *
  * Test status of a link to a remote port using the ELS command ADISC.
  * If there is a problem with the remote port, error recovery steps
  * will be triggered.
  */
-void zfcp_test_link(struct zfcp_port *port)
+void zfcp_fc_test_link(struct zfcp_port *port)
 {
 	zfcp_port_get(port);
-	if (!queue_work(zfcp_data.work_queue, &port->test_link_work))
+	if (!queue_work(port->adapter->work_queue, &port->test_link_work))
 		zfcp_port_put(port);
 }
 
@@ -479,7 +499,7 @@ static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num)
 {
 	struct scatterlist *sg = &gpn_ft->sg_req;
 
-	kfree(sg_virt(sg)); /* free request buffer */
+	kmem_cache_free(zfcp_data.gpn_ft_cache, sg_virt(sg));
 	zfcp_sg_free_table(gpn_ft->sg_resp, buf_num);
 
 	kfree(gpn_ft);
@@ -494,7 +514,7 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg_env(int buf_num)
 	if (!gpn_ft)
 		return NULL;
 
-	req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL);
+	req = kmem_cache_alloc(zfcp_data.gpn_ft_cache, GFP_KERNEL);
 	if (!req) {
 		kfree(gpn_ft);
 		gpn_ft = NULL;
@@ -511,9 +531,8 @@ out:
 }
 
 
-static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
-				  struct zfcp_adapter *adapter,
-				  int max_bytes)
+static int zfcp_fc_send_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
+			       struct zfcp_adapter *adapter, int max_bytes)
 {
 	struct zfcp_send_ct *ct = &gpn_ft->ct;
 	struct ct_iu_gpn_ft_req *req = sg_virt(&gpn_ft->sg_req);
@@ -536,19 +555,18 @@ static int zfcp_scan_issue_gpn_ft(struct zfcp_gpn_ft *gpn_ft,
 	ct->wka_port = &adapter->gs->ds;
 	ct->handler = zfcp_fc_ns_handler;
 	ct->handler_data = (unsigned long)&compl_rec;
-	ct->timeout = 10;
 	ct->req = &gpn_ft->sg_req;
 	ct->resp = gpn_ft->sg_resp;
 
 	init_completion(&compl_rec.done);
 	compl_rec.handler = NULL;
-	ret = zfcp_fsf_send_ct(ct, NULL, NULL);
+	ret = zfcp_fsf_send_ct(ct, NULL);
 	if (!ret)
 		wait_for_completion(&compl_rec.done);
 	return ret;
 }
 
-static void zfcp_validate_port(struct zfcp_port *port)
+static void zfcp_fc_validate_port(struct zfcp_port *port)
 {
 	struct zfcp_adapter *adapter = port->adapter;
 
@@ -568,7 +586,7 @@ static void zfcp_validate_port(struct zfcp_port *port)
 	zfcp_port_dequeue(port);
 }
 
-static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
+static int zfcp_fc_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
 {
 	struct zfcp_send_ct *ct = &gpn_ft->ct;
 	struct scatterlist *sg = gpn_ft->sg_resp;
@@ -595,7 +613,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
 		return -E2BIG;
 	}
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 
 	/* first entry is the header */
 	for (x = 1; x < max_entries && !last; x++) {
@@ -628,16 +646,16 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft, int max_entries)
 
 	zfcp_erp_wait(adapter);
 	list_for_each_entry_safe(port, tmp, &adapter->port_list_head, list)
-		zfcp_validate_port(port);
-	up(&zfcp_data.config_sema);
+		zfcp_fc_validate_port(port);
+	mutex_unlock(&zfcp_data.config_mutex);
 	return ret;
 }
 
 /**
- * zfcp_scan_ports - scan remote ports and attach new ports
+ * zfcp_fc_scan_ports - scan remote ports and attach new ports
  * @adapter: pointer to struct zfcp_adapter
  */
-int zfcp_scan_ports(struct zfcp_adapter *adapter)
+int zfcp_fc_scan_ports(struct zfcp_adapter *adapter)
 {
 	int ret, i;
 	struct zfcp_gpn_ft *gpn_ft;
@@ -652,7 +670,7 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
 	    fc_host_port_type(adapter->scsi_host) != FC_PORTTYPE_NPIV)
 		return 0;
 
-	ret = zfcp_wka_port_get(&adapter->gs->ds);
+	ret = zfcp_fc_wka_port_get(&adapter->gs->ds);
 	if (ret)
 		return ret;
 
@@ -663,9 +681,9 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
 	}
 
 	for (i = 0; i < 3; i++) {
-		ret = zfcp_scan_issue_gpn_ft(gpn_ft, adapter, max_bytes);
+		ret = zfcp_fc_send_gpn_ft(gpn_ft, adapter, max_bytes);
 		if (!ret) {
-			ret = zfcp_scan_eval_gpn_ft(gpn_ft, max_entries);
+			ret = zfcp_fc_eval_gpn_ft(gpn_ft, max_entries);
 			if (ret == -EAGAIN)
 				ssleep(1);
 			else
@@ -674,14 +692,14 @@ int zfcp_scan_ports(struct zfcp_adapter *adapter)
 	}
 	zfcp_free_sg_env(gpn_ft, buf_num);
 out:
-	zfcp_wka_port_put(&adapter->gs->ds);
+	zfcp_fc_wka_port_put(&adapter->gs->ds);
 	return ret;
 }
 
 
-void _zfcp_scan_ports_later(struct work_struct *work)
+void _zfcp_fc_scan_ports_later(struct work_struct *work)
 {
-	zfcp_scan_ports(container_of(work, struct zfcp_adapter, scan_work));
+	zfcp_fc_scan_ports(container_of(work, struct zfcp_adapter, scan_work));
 }
 
 struct zfcp_els_fc_job {
@@ -732,7 +750,7 @@ int zfcp_fc_execute_els_fc_job(struct fc_bsg_job *job)
 	els_fc_job->els.adapter = adapter;
 	if (rport) {
 		read_lock_irq(&zfcp_data.config_lock);
-		port = rport->dd_data;
+		port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
 		if (port)
 			els_fc_job->els.d_id = port->d_id;
 		read_unlock_irq(&zfcp_data.config_lock);
@@ -771,7 +789,7 @@ static void zfcp_fc_generic_ct_handler(unsigned long data)
 	job->state_flags = FC_RQST_STATE_DONE;
 	job->job_done(job);
 
-	zfcp_wka_port_put(ct_fc_job->ct.wka_port);
+	zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port);
 
 	kfree(ct_fc_job);
 }
@@ -817,7 +835,7 @@ int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job)
 		return -EINVAL; /* no such service */
 	}
 
-	ret = zfcp_wka_port_get(ct_fc_job->ct.wka_port);
+	ret = zfcp_fc_wka_port_get(ct_fc_job->ct.wka_port);
 	if (ret) {
 		kfree(ct_fc_job);
 		return ret;
@@ -825,16 +843,40 @@ int zfcp_fc_execute_ct_fc_job(struct fc_bsg_job *job)
 
 	ct_fc_job->ct.req = job->request_payload.sg_list;
 	ct_fc_job->ct.resp = job->reply_payload.sg_list;
-	ct_fc_job->ct.timeout = ZFCP_FSF_REQUEST_TIMEOUT;
 	ct_fc_job->ct.handler = zfcp_fc_generic_ct_handler;
 	ct_fc_job->ct.handler_data = (unsigned long) ct_fc_job;
 	ct_fc_job->ct.completion = NULL;
 	ct_fc_job->job = job;
 
-	ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL, NULL);
+	ret = zfcp_fsf_send_ct(&ct_fc_job->ct, NULL);
 	if (ret) {
 		kfree(ct_fc_job);
-		zfcp_wka_port_put(ct_fc_job->ct.wka_port);
+		zfcp_fc_wka_port_put(ct_fc_job->ct.wka_port);
 	}
 	return ret;
 }
+
+int zfcp_fc_gs_setup(struct zfcp_adapter *adapter)
+{
+	struct zfcp_wka_ports *wka_ports;
+
+	wka_ports = kzalloc(sizeof(struct zfcp_wka_ports), GFP_KERNEL);
+	if (!wka_ports)
+		return -ENOMEM;
+
+	adapter->gs = wka_ports;
+	zfcp_fc_wka_port_init(&wka_ports->ms, FC_FID_MGMT_SERV, adapter);
+	zfcp_fc_wka_port_init(&wka_ports->ts, FC_FID_TIME_SERV, adapter);
+	zfcp_fc_wka_port_init(&wka_ports->ds, FC_FID_DIR_SERV, adapter);
+	zfcp_fc_wka_port_init(&wka_ports->as, FC_FID_ALIASES, adapter);
+	zfcp_fc_wka_port_init(&wka_ports->ks, FC_FID_SEC_KEY, adapter);
+
+	return 0;
+}
+
+void zfcp_fc_gs_destroy(struct zfcp_adapter *adapter)
+{
+	kfree(adapter->gs);
+	adapter->gs = NULL;
+}
+
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 47795fb..f09c863 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -11,9 +11,7 @@
 
 #include <linux/blktrace_api.h>
 #include "zfcp_ext.h"
-
-#define ZFCP_REQ_AUTO_CLEANUP	0x00000002
-#define ZFCP_REQ_NO_QTCB	0x00000008
+#include "zfcp_dbf.h"
 
 static void zfcp_fsf_request_timeout_handler(unsigned long data)
 {
@@ -111,43 +109,15 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
 void zfcp_fsf_req_free(struct zfcp_fsf_req *req)
 {
 	if (likely(req->pool)) {
+		if (likely(req->qtcb))
+			mempool_free(req->qtcb, req->adapter->pool.qtcb_pool);
 		mempool_free(req, req->pool);
 		return;
 	}
 
-	if (req->qtcb) {
-		kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, req);
-		return;
-	}
-}
-
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
- * @adapter: pointer to struct zfcp_adapter
- *
- * Never ever call this without shutting down the adapter first.
- * Otherwise the adapter would continue using and corrupting s390 storage.
- * Included BUG_ON() call to ensure this is done.
- * ERP is supposed to be the only user of this function.
- */
-void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
-{
-	struct zfcp_fsf_req *req, *tmp;
-	unsigned long flags;
-	LIST_HEAD(remove_queue);
-	unsigned int i;
-
-	BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
-	spin_lock_irqsave(&adapter->req_list_lock, flags);
-	for (i = 0; i < REQUEST_LIST_SIZE; i++)
-		list_splice_init(&adapter->req_list[i], &remove_queue);
-	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
-
-	list_for_each_entry_safe(req, tmp, &remove_queue, list) {
-		list_del(&req->list);
-		req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
-		zfcp_fsf_req_complete(req);
-	}
+	if (likely(req->qtcb))
+		kmem_cache_free(zfcp_data.qtcb_cache, req->qtcb);
+	kfree(req);
 }
 
 static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
@@ -278,13 +248,13 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
 	struct fsf_status_read_buffer *sr_buf = req->data;
 
 	if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
-		zfcp_hba_dbf_event_fsf_unsol("dism", adapter, sr_buf);
-		mempool_free(sr_buf, adapter->pool.data_status_read);
+		zfcp_dbf_hba_fsf_unsol("dism", adapter->dbf, sr_buf);
+		mempool_free(sr_buf, adapter->pool.status_read_data);
 		zfcp_fsf_req_free(req);
 		return;
 	}
 
-	zfcp_hba_dbf_event_fsf_unsol("read", adapter, sr_buf);
+	zfcp_dbf_hba_fsf_unsol("read", adapter->dbf, sr_buf);
 
 	switch (sr_buf->status_type) {
 	case FSF_STATUS_READ_PORT_CLOSED:
@@ -299,7 +269,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
 		dev_warn(&adapter->ccw_device->dev,
 			 "The error threshold for checksum statistics "
 			 "has been exceeded\n");
-		zfcp_hba_dbf_event_berr(adapter, req);
+		zfcp_dbf_hba_berr(adapter->dbf, req);
 		break;
 	case FSF_STATUS_READ_LINK_DOWN:
 		zfcp_fsf_status_read_link_down(req);
@@ -331,11 +301,11 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
 		break;
 	}
 
-	mempool_free(sr_buf, adapter->pool.data_status_read);
+	mempool_free(sr_buf, adapter->pool.status_read_data);
 	zfcp_fsf_req_free(req);
 
 	atomic_inc(&adapter->stat_miss);
-	queue_work(zfcp_data.work_queue, &adapter->stat_work);
+	queue_work(adapter->work_queue, &adapter->stat_work);
 }
 
 static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req)
@@ -385,7 +355,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
 	struct fsf_qtcb *qtcb = req->qtcb;
 	union fsf_prot_status_qual *psq = &qtcb->prefix.prot_status_qual;
 
-	zfcp_hba_dbf_event_fsf_response(req);
+	zfcp_dbf_hba_fsf_response(req);
 
 	if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR |
@@ -458,7 +428,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
  * is called to process the completion status and trigger further
  * events related to the FSF request.
  */
-void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
+static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
 {
 	if (unlikely(req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
 		zfcp_fsf_status_read_handler(req);
@@ -472,23 +442,40 @@ void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
 
 	if (req->erp_action)
 		zfcp_erp_notify(req->erp_action, 0);
-	req->status |= ZFCP_STATUS_FSFREQ_COMPLETED;
 
 	if (likely(req->status & ZFCP_STATUS_FSFREQ_CLEANUP))
 		zfcp_fsf_req_free(req);
 	else
-	/* notify initiator waiting for the requests completion */
-	/*
-	 * FIXME: Race! We must not access fsf_req here as it might have been
-	 * cleaned up already due to the set ZFCP_STATUS_FSFREQ_COMPLETED
-	 * flag. It's an improbable case. But, we have the same paranoia for
-	 * the cleanup flag already.
-	 * Might better be handled using complete()?
-	 * (setting the flag and doing wakeup ought to be atomic
-	 *  with regard to checking the flag as long as waitqueue is
-	 *  part of the to be released structure)
-	 */
-		wake_up(&req->completion_wq);
+		complete(&req->completion);
+}
+
+/**
+ * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
+ * @adapter: pointer to struct zfcp_adapter
+ *
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
+ */
+void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
+{
+	struct zfcp_fsf_req *req, *tmp;
+	unsigned long flags;
+	LIST_HEAD(remove_queue);
+	unsigned int i;
+
+	BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
+	spin_lock_irqsave(&adapter->req_list_lock, flags);
+	for (i = 0; i < REQUEST_LIST_SIZE; i++)
+		list_splice_init(&adapter->req_list[i], &remove_queue);
+	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+
+	list_for_each_entry_safe(req, tmp, &remove_queue, list) {
+		list_del(&req->list);
+		req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+		zfcp_fsf_req_complete(req);
+	}
 }
 
 static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
@@ -650,79 +637,77 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
 	}
 }
 
-static int zfcp_fsf_sbal_check(struct zfcp_adapter *adapter)
+static int zfcp_fsf_sbal_check(struct zfcp_qdio *qdio)
 {
-	struct zfcp_qdio_queue *req_q = &adapter->req_q;
+	struct zfcp_qdio_queue *req_q = &qdio->req_q;
 
-	spin_lock_bh(&adapter->req_q_lock);
+	spin_lock_bh(&qdio->req_q_lock);
 	if (atomic_read(&req_q->count))
 		return 1;
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return 0;
 }
 
-static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
+static int zfcp_fsf_req_sbal_get(struct zfcp_qdio *qdio)
 {
+	struct zfcp_adapter *adapter = qdio->adapter;
 	long ret;
 
-	spin_unlock_bh(&adapter->req_q_lock);
-	ret = wait_event_interruptible_timeout(adapter->request_wq,
-			       zfcp_fsf_sbal_check(adapter), 5 * HZ);
+	spin_unlock_bh(&qdio->req_q_lock);
+	ret = wait_event_interruptible_timeout(qdio->req_q_wq,
+			       zfcp_fsf_sbal_check(qdio), 5 * HZ);
 	if (ret > 0)
 		return 0;
 	if (!ret) {
-		atomic_inc(&adapter->qdio_outb_full);
+		atomic_inc(&qdio->req_q_full);
 		/* assume hanging outbound queue, try queue recovery */
 		zfcp_erp_adapter_reopen(adapter, 0, "fsrsg_1", NULL);
 	}
 
-	spin_lock_bh(&adapter->req_q_lock);
+	spin_lock_bh(&qdio->req_q_lock);
 	return -EIO;
 }
 
-static struct zfcp_fsf_req *zfcp_fsf_alloc_noqtcb(mempool_t *pool)
+static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool)
 {
 	struct zfcp_fsf_req *req;
-	req = mempool_alloc(pool, GFP_ATOMIC);
-	if (!req)
+
+	if (likely(pool))
+		req = mempool_alloc(pool, GFP_ATOMIC);
+	else
+		req = kmalloc(sizeof(*req), GFP_ATOMIC);
+
+	if (unlikely(!req))
 		return NULL;
+
 	memset(req, 0, sizeof(*req));
 	req->pool = pool;
 	return req;
 }
 
-static struct zfcp_fsf_req *zfcp_fsf_alloc_qtcb(mempool_t *pool)
+static struct fsf_qtcb *zfcp_qtcb_alloc(mempool_t *pool)
 {
-	struct zfcp_fsf_req_qtcb *qtcb;
+	struct fsf_qtcb *qtcb;
 
 	if (likely(pool))
 		qtcb = mempool_alloc(pool, GFP_ATOMIC);
 	else
-		qtcb = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache,
-					GFP_ATOMIC);
+		qtcb = kmem_cache_alloc(zfcp_data.qtcb_cache, GFP_ATOMIC);
+
 	if (unlikely(!qtcb))
 		return NULL;
 
 	memset(qtcb, 0, sizeof(*qtcb));
-	qtcb->fsf_req.qtcb = &qtcb->qtcb;
-	qtcb->fsf_req.pool = pool;
-
-	return &qtcb->fsf_req;
+	return qtcb;
 }
 
-static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
-						u32 fsf_cmd, int req_flags,
-						mempool_t *pool)
+static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio,
+						u32 fsf_cmd, mempool_t *pool)
 {
 	struct qdio_buffer_element *sbale;
-
-	struct zfcp_fsf_req *req;
-	struct zfcp_qdio_queue *req_q = &adapter->req_q;
-
-	if (req_flags & ZFCP_REQ_NO_QTCB)
-		req = zfcp_fsf_alloc_noqtcb(pool);
-	else
-		req = zfcp_fsf_alloc_qtcb(pool);
+	struct zfcp_qdio_queue *req_q = &qdio->req_q;
+	struct zfcp_adapter *adapter = qdio->adapter;
+	struct zfcp_fsf_req *req = zfcp_fsf_alloc(pool);
 
 	if (unlikely(!req))
 		return ERR_PTR(-ENOMEM);
@@ -732,22 +717,32 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
 
 	INIT_LIST_HEAD(&req->list);
 	init_timer(&req->timer);
-	init_waitqueue_head(&req->completion_wq);
+	init_completion(&req->completion);
 
 	req->adapter = adapter;
 	req->fsf_command = fsf_cmd;
 	req->req_id = adapter->req_no;
-	req->sbal_number = 1;
-	req->sbal_first = req_q->first;
-	req->sbal_last = req_q->first;
-	req->sbale_curr = 1;
+	req->queue_req.sbal_number = 1;
+	req->queue_req.sbal_first = req_q->first;
+	req->queue_req.sbal_last = req_q->first;
+	req->queue_req.sbale_curr = 1;
 
-	sbale = zfcp_qdio_sbale_req(req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].addr = (void *) req->req_id;
 	sbale[0].flags |= SBAL_FLAGS0_COMMAND;
 
-	if (likely(req->qtcb)) {
-		req->qtcb->prefix.req_seq_no = req->adapter->fsf_req_seq_no;
+	if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) {
+		if (likely(pool))
+			req->qtcb = zfcp_qtcb_alloc(adapter->pool.qtcb_pool);
+		else
+			req->qtcb = zfcp_qtcb_alloc(NULL);
+
+		if (unlikely(!req->qtcb)) {
+			zfcp_fsf_req_free(req);
+			return ERR_PTR(-ENOMEM);
+		}
+
+		req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
 		req->qtcb->prefix.req_id = req->req_id;
 		req->qtcb->prefix.ulp_info = 26;
 		req->qtcb->prefix.qtcb_type = fsf_qtcb_type[req->fsf_command];
@@ -765,15 +760,13 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
 		return ERR_PTR(-EIO);
 	}
 
-	if (likely(req_flags & ZFCP_REQ_AUTO_CLEANUP))
-		req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
-
 	return req;
 }
 
 static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
 {
 	struct zfcp_adapter *adapter = req->adapter;
+	struct zfcp_qdio *qdio = adapter->qdio;
 	unsigned long	     flags;
 	int		     idx;
 	int		     with_qtcb = (req->qtcb != NULL);
@@ -784,9 +777,9 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
 	list_add_tail(&req->list, &adapter->req_list[idx]);
 	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
 
-	req->qdio_outb_usage = atomic_read(&adapter->req_q.count);
+	req->queue_req.qdio_outb_usage = atomic_read(&qdio->req_q.count);
 	req->issued = get_clock();
-	if (zfcp_qdio_send(req)) {
+	if (zfcp_qdio_send(qdio, &req->queue_req)) {
 		del_timer(&req->timer);
 		spin_lock_irqsave(&adapter->req_list_lock, flags);
 		/* lookup request again, list might have changed */
@@ -811,38 +804,37 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
  * @req_flags: request flags
  * Returns: 0 on success, ERROR otherwise
  */
-int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
+int zfcp_fsf_status_read(struct zfcp_qdio *qdio)
 {
+	struct zfcp_adapter *adapter = qdio->adapter;
 	struct zfcp_fsf_req *req;
 	struct fsf_status_read_buffer *sr_buf;
 	struct qdio_buffer_element *sbale;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS,
-				  ZFCP_REQ_NO_QTCB,
-				  adapter->pool.fsf_req_status_read);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_UNSOLICITED_STATUS,
+				  adapter->pool.status_read_req);
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
-	sbale[0].flags |= SBAL_FLAGS0_TYPE_STATUS;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY;
-	req->sbale_curr = 2;
+	req->queue_req.sbale_curr = 2;
 
-	sr_buf = mempool_alloc(adapter->pool.data_status_read, GFP_ATOMIC);
+	sr_buf = mempool_alloc(adapter->pool.status_read_data, GFP_ATOMIC);
 	if (!sr_buf) {
 		retval = -ENOMEM;
 		goto failed_buf;
 	}
 	memset(sr_buf, 0, sizeof(*sr_buf));
 	req->data = sr_buf;
-	sbale = zfcp_qdio_sbale_curr(req);
+	sbale = zfcp_qdio_sbale_curr(qdio, &req->queue_req);
 	sbale->addr = (void *) sr_buf;
 	sbale->length = sizeof(*sr_buf);
 
@@ -853,12 +845,12 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
 	goto out;
 
 failed_req_send:
-	mempool_free(sr_buf, adapter->pool.data_status_read);
+	mempool_free(sr_buf, adapter->pool.status_read_data);
 failed_buf:
 	zfcp_fsf_req_free(req);
-	zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
+	zfcp_dbf_hba_fsf_unsol("fail", adapter->dbf, NULL);
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -900,7 +892,7 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (fsq->word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			zfcp_test_link(unit->port);
+			zfcp_fc_test_link(unit->port);
 			/* fall through */
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -925,13 +917,13 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req = NULL;
-	struct zfcp_adapter *adapter = unit->port->adapter;
+	struct zfcp_qdio *qdio = unit->port->adapter->qdio;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
-				  0, adapter->pool.fsf_req_abort);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND,
+				  qdio->adapter->pool.scsi_abort);
 	if (IS_ERR(req)) {
 		req = NULL;
 		goto out;
@@ -941,7 +933,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
 		       ZFCP_STATUS_COMMON_UNBLOCKED)))
 		goto out_error_free;
 
-	sbale = zfcp_qdio_sbale_req(req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -959,7 +951,7 @@ out_error_free:
 	zfcp_fsf_req_free(req);
 	req = NULL;
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return req;
 }
 
@@ -976,7 +968,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
 
 	switch (header->fsf_status) {
         case FSF_GOOD:
-		zfcp_san_dbf_event_ct_response(req);
+		zfcp_dbf_san_ct_response(req);
 		send_ct->status = 0;
 		break;
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -1035,8 +1027,10 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
 				       struct scatterlist *sg_resp,
 				       int max_sbals)
 {
-	struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(req);
-	u32 feat = req->adapter->adapter_features;
+	struct zfcp_adapter *adapter = req->adapter;
+	struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(adapter->qdio,
+							       &req->queue_req);
+	u32 feat = adapter->adapter_features;
 	int bytes;
 
 	if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
@@ -1053,18 +1047,25 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
 		return 0;
 	}
 
-	bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
+	bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req,
+					SBAL_FLAGS0_TYPE_WRITE_READ,
 					sg_req, max_sbals);
 	if (bytes <= 0)
 		return -EIO;
 	req->qtcb->bottom.support.req_buf_length = bytes;
-	req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;
+	req->queue_req.sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;
 
-	bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
+	bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req,
+					SBAL_FLAGS0_TYPE_WRITE_READ,
 					sg_resp, max_sbals);
 	if (bytes <= 0)
 		return -EIO;
+
+	/* common settings for ct/gs and els requests */
 	req->qtcb->bottom.support.resp_buf_length = bytes;
+	req->qtcb->bottom.support.service_class = FSF_CLASS_3;
+	req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
+	zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10);
 
 	return 0;
 }
@@ -1073,27 +1074,26 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
  * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS)
  * @ct: pointer to struct zfcp_send_ct with data for request
  * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
- * @erp_action: if non-null the Generic Service request sent within ERP
  */
-int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
-		     struct zfcp_erp_action *erp_action)
+int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool)
 {
 	struct zfcp_wka_port *wka_port = ct->wka_port;
-	struct zfcp_adapter *adapter = wka_port->adapter;
+	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int ret = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC,
-				  ZFCP_REQ_AUTO_CLEANUP, pool);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_GENERIC, pool);
+
 	if (IS_ERR(req)) {
 		ret = PTR_ERR(req);
 		goto out;
 	}
 
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
 	ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp,
 					  FSF_MAX_SBALS_PER_REQ);
 	if (ret)
@@ -1101,18 +1101,9 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
 
 	req->handler = zfcp_fsf_send_ct_handler;
 	req->qtcb->header.port_handle = wka_port->handle;
-	req->qtcb->bottom.support.service_class = FSF_CLASS_3;
-	req->qtcb->bottom.support.timeout = ct->timeout;
 	req->data = ct;
 
-	zfcp_san_dbf_event_ct_request(req);
-
-	if (erp_action) {
-		erp_action->fsf_req = req;
-		req->erp_action = erp_action;
-		zfcp_fsf_start_erp_timer(req);
-	} else
-		zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
+	zfcp_dbf_san_ct_request(req);
 
 	ret = zfcp_fsf_req_send(req);
 	if (ret)
@@ -1122,10 +1113,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
 
 failed_send:
 	zfcp_fsf_req_free(req);
-	if (erp_action)
-		erp_action->fsf_req = NULL;
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return ret;
 }
 
@@ -1142,7 +1131,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
 
 	switch (header->fsf_status) {
 	case FSF_GOOD:
-		zfcp_san_dbf_event_els_response(req);
+		zfcp_dbf_san_els_response(req);
 		send_els->status = 0;
 		break;
 	case FSF_SERVICE_CLASS_NOT_SUPPORTED:
@@ -1152,7 +1141,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
 		switch (header->fsf_status_qual.word[0]){
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 			if (port && (send_els->ls_code != ZFCP_LS_ADISC))
-				zfcp_test_link(port);
+				zfcp_fc_test_link(port);
 			/*fall through */
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_RETRY_IF_POSSIBLE:
@@ -1188,35 +1177,32 @@ skip_fsfstatus:
 int zfcp_fsf_send_els(struct zfcp_send_els *els)
 {
 	struct zfcp_fsf_req *req;
-	struct zfcp_adapter *adapter = els->adapter;
-	struct fsf_qtcb_bottom_support *bottom;
+	struct zfcp_qdio *qdio = els->adapter->qdio;
 	int ret = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,
-				  ZFCP_REQ_AUTO_CLEANUP, NULL);
+
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_ELS, NULL);
+
 	if (IS_ERR(req)) {
 		ret = PTR_ERR(req);
 		goto out;
 	}
 
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
 	ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2);
 
 	if (ret)
 		goto failed_send;
 
-	bottom = &req->qtcb->bottom.support;
+	req->qtcb->bottom.support.d_id = els->d_id;
 	req->handler = zfcp_fsf_send_els_handler;
-	bottom->d_id = els->d_id;
-	bottom->service_class = FSF_CLASS_3;
-	bottom->timeout = 2 * R_A_TOV;
 	req->data = els;
 
-	zfcp_san_dbf_event_els_request(req);
+	zfcp_dbf_san_els_request(req);
 
-	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	ret = zfcp_fsf_req_send(req);
 	if (ret)
 		goto failed_send;
@@ -1226,7 +1212,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
 failed_send:
 	zfcp_fsf_req_free(req);
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return ret;
 }
 
@@ -1234,22 +1220,23 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req;
-	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
-	req = zfcp_fsf_req_create(adapter,
-				  FSF_QTCB_EXCHANGE_CONFIG_DATA,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA,
+				  qdio->adapter->pool.erp_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1269,29 +1256,29 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
-int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
+int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio,
 				       struct fsf_qtcb_bottom_config *data)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req = NULL;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out_unlock;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
-				  0, NULL);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA, NULL);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out_unlock;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 	req->handler = zfcp_fsf_exchange_config_data_handler;
@@ -1307,16 +1294,15 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
 
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	if (!retval)
-		wait_event(req->completion_wq,
-			   req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+		wait_for_completion(&req->completion);
 
 	zfcp_fsf_req_free(req);
 	return retval;
 
 out_unlock:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1327,26 +1313,28 @@ out_unlock:
  */
 int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
 {
+	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 	int retval = -EIO;
 
-	if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
+	if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
 		return -EOPNOTSUPP;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA,
+				  qdio->adapter->pool.erp_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1361,32 +1349,32 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
 /**
  * zfcp_fsf_exchange_port_data_sync - request information about local port
- * @adapter: pointer to struct zfcp_adapter
+ * @qdio: pointer to struct zfcp_qdio
  * @data: pointer to struct fsf_qtcb_bottom_port
  * Returns: 0 on success, error otherwise
  */
-int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
+int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio,
 				     struct fsf_qtcb_bottom_port *data)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req = NULL;
 	int retval = -EIO;
 
-	if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
+	if (!(qdio->adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
 		return -EOPNOTSUPP;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out_unlock;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0,
-				  NULL);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA, NULL);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out_unlock;
@@ -1395,24 +1383,24 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
 	if (data)
 		req->data = data;
 
-	sbale = zfcp_qdio_sbale_req(req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	req->handler = zfcp_fsf_exchange_port_data_handler;
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 
 	if (!retval)
-		wait_event(req->completion_wq,
-			   req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+		wait_for_completion(&req->completion);
+
 	zfcp_fsf_req_free(req);
 
 	return retval;
 
 out_unlock:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1498,25 +1486,25 @@ out:
 int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
 {
 	struct qdio_buffer_element *sbale;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_fsf_req *req;
+	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
 	struct zfcp_port *port = erp_action->port;
+	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter,
-				  FSF_QTCB_OPEN_PORT_WITH_DID,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
+				  qdio->adapter->pool.erp_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1535,7 +1523,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
 		zfcp_port_put(port);
 	}
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1569,23 +1557,24 @@ static void zfcp_fsf_close_port_handler(struct zfcp_fsf_req *req)
 int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
 {
 	struct qdio_buffer_element *sbale;
-	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
+				  qdio->adapter->pool.erp_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1602,7 +1591,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1645,24 +1634,24 @@ out:
 int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port)
 {
 	struct qdio_buffer_element *sbale;
-	struct zfcp_adapter *adapter = wka_port->adapter;
+	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter,
-				  FSF_QTCB_OPEN_PORT_WITH_DID,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
+				  qdio->adapter->pool.erp_req);
+
 	if (unlikely(IS_ERR(req))) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1675,7 +1664,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port)
 	if (retval)
 		zfcp_fsf_req_free(req);
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1700,23 +1689,24 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
 int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port)
 {
 	struct qdio_buffer_element *sbale;
-	struct zfcp_adapter *adapter = wka_port->adapter;
+	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
+				  qdio->adapter->pool.erp_req);
+
 	if (unlikely(IS_ERR(req))) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1729,7 +1719,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port)
 	if (retval)
 		zfcp_fsf_req_free(req);
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1791,23 +1781,24 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
 int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
 {
 	struct qdio_buffer_element *sbale;
-	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PHYSICAL_PORT,
+				  qdio->adapter->pool.erp_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -1824,7 +1815,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -1895,7 +1886,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req)
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			zfcp_test_link(unit->port);
+			zfcp_fc_test_link(unit->port);
 			/* fall through */
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -1964,22 +1955,24 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
 {
 	struct qdio_buffer_element *sbale;
 	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_qdio *qdio = adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_LUN,
+				  adapter->pool.erp_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -2000,7 +1993,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -2028,7 +2021,7 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req)
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (req->qtcb->header.fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			zfcp_test_link(unit->port);
+			zfcp_fc_test_link(unit->port);
 			/* fall through */
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -2049,22 +2042,24 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req)
 int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
 {
 	struct qdio_buffer_element *sbale;
-	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_qdio *qdio = erp_action->adapter->qdio;
 	struct zfcp_fsf_req *req;
 	int retval = -EIO;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_erp);
+
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_LUN,
+				  qdio->adapter->pool.erp_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
-	sbale = zfcp_qdio_sbale_req(req);
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -2082,7 +2077,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
 		erp_action->fsf_req = NULL;
 	}
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -2141,8 +2136,8 @@ static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
 	}
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
 		trace.flags |= ZFCP_BLK_REQ_ERROR;
-	trace.inb_usage = fsf_req->qdio_inb_usage;
-	trace.outb_usage = fsf_req->qdio_outb_usage;
+	trace.inb_usage = fsf_req->queue_req.qdio_inb_usage;
+	trace.outb_usage = fsf_req->queue_req.qdio_outb_usage;
 
 	blk_add_driver_data(req->q, req, &trace, sizeof(trace));
 }
@@ -2215,11 +2210,11 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
 	}
 skip_fsfstatus:
 	if (scpnt->result != 0)
-		zfcp_scsi_dbf_event_result("erro", 3, req->adapter, scpnt, req);
+		zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req);
 	else if (scpnt->retries > 0)
-		zfcp_scsi_dbf_event_result("retr", 4, req->adapter, scpnt, req);
+		zfcp_dbf_scsi_result("retr", 4, req->adapter->dbf, scpnt, req);
 	else
-		zfcp_scsi_dbf_event_result("norm", 6, req->adapter, scpnt, req);
+		zfcp_dbf_scsi_result("norm", 6, req->adapter->dbf, scpnt, req);
 
 	scpnt->host_scribble = NULL;
 	(scpnt->scsi_done) (scpnt);
@@ -2309,7 +2304,7 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		if (header->fsf_status_qual.word[0] ==
 		    FSF_SQ_INVOKE_LINK_TEST_PROCEDURE)
-			zfcp_test_link(unit->port);
+			zfcp_fc_test_link(unit->port);
 		req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 	}
@@ -2350,24 +2345,27 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
 	unsigned int sbtype = SBAL_FLAGS0_TYPE_READ;
 	int real_bytes, retval = -EIO;
 	struct zfcp_adapter *adapter = unit->port->adapter;
+	struct zfcp_qdio *qdio = adapter->qdio;
 
 	if (unlikely(!(atomic_read(&unit->status) &
 		       ZFCP_STATUS_COMMON_UNBLOCKED)))
 		return -EBUSY;
 
-	spin_lock(&adapter->req_q_lock);
-	if (atomic_read(&adapter->req_q.count) <= 0) {
-		atomic_inc(&adapter->qdio_outb_full);
+	spin_lock(&qdio->req_q_lock);
+	if (atomic_read(&qdio->req_q.count) <= 0) {
+		atomic_inc(&qdio->req_q_full);
 		goto out;
 	}
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND,
-				  ZFCP_REQ_AUTO_CLEANUP,
-				  adapter->pool.fsf_req_scsi);
+
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
+				  adapter->pool.scsi_req);
+
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
 		goto out;
 	}
 
+	req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
 	zfcp_unit_get(unit);
 	req->unit = unit;
 	req->data = scsi_cmnd;
@@ -2419,11 +2417,11 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
 	req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) +
 		fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32);
 
-	real_bytes = zfcp_qdio_sbals_from_sg(req, sbtype,
+	real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype,
 					     scsi_sglist(scsi_cmnd),
 					     FSF_MAX_SBALS_PER_REQ);
 	if (unlikely(real_bytes < 0)) {
-		if (req->sbal_number >= FSF_MAX_SBALS_PER_REQ) {
+		if (req->queue_req.sbal_number >= FSF_MAX_SBALS_PER_REQ) {
 			dev_err(&adapter->ccw_device->dev,
 				"Oversize data package, unit 0x%016Lx "
 				"on port 0x%016Lx closed\n",
@@ -2448,7 +2446,7 @@ failed_scsi_cmnd:
 	zfcp_fsf_req_free(req);
 	scsi_cmnd->host_scribble = NULL;
 out:
-	spin_unlock(&adapter->req_q_lock);
+	spin_unlock(&qdio->req_q_lock);
 	return retval;
 }
 
@@ -2463,17 +2461,19 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
 	struct qdio_buffer_element *sbale;
 	struct zfcp_fsf_req *req = NULL;
 	struct fcp_cmnd_iu *fcp_cmnd_iu;
-	struct zfcp_adapter *adapter = unit->port->adapter;
+	struct zfcp_qdio *qdio = unit->port->adapter->qdio;
 
 	if (unlikely(!(atomic_read(&unit->status) &
 		       ZFCP_STATUS_COMMON_UNBLOCKED)))
 		return NULL;
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
-	req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0,
-				  adapter->pool.fsf_req_scsi);
+
+	req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
+				  qdio->adapter->pool.scsi_req);
+
 	if (IS_ERR(req)) {
 		req = NULL;
 		goto out;
@@ -2489,7 +2489,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
 	req->qtcb->bottom.io.fcp_cmnd_length = 	sizeof(struct fcp_cmnd_iu) +
 						sizeof(u32);
 
-	sbale = zfcp_qdio_sbale_req(req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
 	sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -2504,7 +2504,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
 	zfcp_fsf_req_free(req);
 	req = NULL;
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 	return req;
 }
 
@@ -2522,6 +2522,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
 					   struct zfcp_fsf_cfdc *fsf_cfdc)
 {
 	struct qdio_buffer_element *sbale;
+	struct zfcp_qdio *qdio = adapter->qdio;
 	struct zfcp_fsf_req *req = NULL;
 	struct fsf_qtcb_bottom_support *bottom;
 	int direction, retval = -EIO, bytes;
@@ -2540,11 +2541,11 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
 		return ERR_PTR(-EINVAL);
 	}
 
-	spin_lock_bh(&adapter->req_q_lock);
-	if (zfcp_fsf_req_sbal_get(adapter))
+	spin_lock_bh(&qdio->req_q_lock);
+	if (zfcp_fsf_req_sbal_get(qdio))
 		goto out;
 
-	req = zfcp_fsf_req_create(adapter, fsf_cfdc->command, 0, NULL);
+	req = zfcp_fsf_req_create(qdio, fsf_cfdc->command, NULL);
 	if (IS_ERR(req)) {
 		retval = -EPERM;
 		goto out;
@@ -2552,14 +2553,15 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
 
 	req->handler = zfcp_fsf_control_file_handler;
 
-	sbale = zfcp_qdio_sbale_req(req);
+	sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
 	sbale[0].flags |= direction;
 
 	bottom = &req->qtcb->bottom.support;
 	bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
 	bottom->option = fsf_cfdc->option;
 
-	bytes = zfcp_qdio_sbals_from_sg(req, direction, fsf_cfdc->sg,
+	bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req,
+					direction, fsf_cfdc->sg,
 					FSF_MAX_SBALS_PER_REQ);
 	if (bytes != ZFCP_CFDC_MAX_SIZE) {
 		zfcp_fsf_req_free(req);
@@ -2569,12 +2571,53 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
 	zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
 	retval = zfcp_fsf_req_send(req);
 out:
-	spin_unlock_bh(&adapter->req_q_lock);
+	spin_unlock_bh(&qdio->req_q_lock);
 
 	if (!retval) {
-		wait_event(req->completion_wq,
-			   req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+		wait_for_completion(&req->completion);
 		return req;
 	}
 	return ERR_PTR(retval);
 }
+
+/**
+ * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO
+ * @adapter: pointer to struct zfcp_adapter
+ * @sbal_idx: response queue index of SBAL to be processed
+ */
+void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
+{
+	struct zfcp_adapter *adapter = qdio->adapter;
+	struct qdio_buffer *sbal = qdio->resp_q.sbal[sbal_idx];
+	struct qdio_buffer_element *sbale;
+	struct zfcp_fsf_req *fsf_req;
+	unsigned long flags, req_id;
+	int idx;
+
+	for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
+
+		sbale = &sbal->element[idx];
+		req_id = (unsigned long) sbale->addr;
+		spin_lock_irqsave(&adapter->req_list_lock, flags);
+		fsf_req = zfcp_reqlist_find(adapter, req_id);
+
+		if (!fsf_req)
+			/*
+			 * Unknown request means that we have potentially memory
+			 * corruption and must stop the machine immediately.
+			 */
+			panic("error: unknown req_id (%lx) on adapter %s.\n",
+			      req_id, dev_name(&adapter->ccw_device->dev));
+
+		list_del(&fsf_req->list);
+		spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+
+		fsf_req->queue_req.sbal_response = sbal_idx;
+		fsf_req->queue_req.qdio_inb_usage =
+			atomic_read(&qdio->resp_q.count);
+		zfcp_fsf_req_complete(fsf_req);
+
+		if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
+			break;
+	}
+}
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index df7f232..dcc7c1d 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -3,13 +3,14 @@
  *
  * Interface to the FSF support functions.
  *
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
  */
 
 #ifndef FSF_H
 #define FSF_H
 
 #include <linux/pfn.h>
+#include <linux/scatterlist.h>
 
 #define FSF_QTCB_CURRENT_VERSION		0x00000001
 
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index e0a2153..6c5228b 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -3,7 +3,7 @@
  *
  * Setup and helper functions to access QDIO.
  *
- * Copyright IBM Corporation 2002, 2008
+ * Copyright IBM Corporation 2002, 2009
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -34,29 +34,10 @@ zfcp_qdio_sbale(struct zfcp_qdio_queue *q, int sbal_idx, int sbale_idx)
 	return &q->sbal[sbal_idx]->element[sbale_idx];
 }
 
-/**
- * zfcp_qdio_free - free memory used by request- and resposne queue
- * @adapter: pointer to the zfcp_adapter structure
- */
-void zfcp_qdio_free(struct zfcp_adapter *adapter)
+static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id)
 {
-	struct qdio_buffer **sbal_req, **sbal_resp;
-	int p;
-
-	if (adapter->ccw_device)
-		qdio_free(adapter->ccw_device);
-
-	sbal_req = adapter->req_q.sbal;
-	sbal_resp = adapter->resp_q.sbal;
-
-	for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) {
-		free_page((unsigned long) sbal_req[p]);
-		free_page((unsigned long) sbal_resp[p]);
-	}
-}
+	struct zfcp_adapter *adapter = qdio->adapter;
 
-static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, char *id)
-{
 	dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
 
 	zfcp_erp_adapter_reopen(adapter,
@@ -75,72 +56,47 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
 }
 
 /* this needs to be called prior to updating the queue fill level */
-static void zfcp_qdio_account(struct zfcp_adapter *adapter)
+static inline void zfcp_qdio_account(struct zfcp_qdio *qdio)
 {
-	ktime_t now;
-	s64 span;
+	unsigned long long now, span;
 	int free, used;
 
-	spin_lock(&adapter->qdio_stat_lock);
-	now = ktime_get();
-	span = ktime_us_delta(now, adapter->req_q_time);
-	free = max(0, atomic_read(&adapter->req_q.count));
+	spin_lock(&qdio->stat_lock);
+	now = get_clock_monotonic();
+	span = (now - qdio->req_q_time) >> 12;
+	free = atomic_read(&qdio->req_q.count);
 	used = QDIO_MAX_BUFFERS_PER_Q - free;
-	adapter->req_q_util += used * span;
-	adapter->req_q_time = now;
-	spin_unlock(&adapter->qdio_stat_lock);
+	qdio->req_q_util += used * span;
+	qdio->req_q_time = now;
+	spin_unlock(&qdio->stat_lock);
 }
 
 static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
 			      int queue_no, int first, int count,
 			      unsigned long parm)
 {
-	struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm;
-	struct zfcp_qdio_queue *queue = &adapter->req_q;
+	struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
+	struct zfcp_qdio_queue *queue = &qdio->req_q;
 
 	if (unlikely(qdio_err)) {
-		zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
-		zfcp_qdio_handler_error(adapter, "qdireq1");
+		zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, first,
+					count);
+		zfcp_qdio_handler_error(qdio, "qdireq1");
 		return;
 	}
 
 	/* cleanup all SBALs being program-owned now */
 	zfcp_qdio_zero_sbals(queue->sbal, first, count);
 
-	zfcp_qdio_account(adapter);
+	zfcp_qdio_account(qdio);
 	atomic_add(count, &queue->count);
-	wake_up(&adapter->request_wq);
-}
-
-static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
-				  unsigned long req_id, int sbal_idx)
-{
-	struct zfcp_fsf_req *fsf_req;
-	unsigned long flags;
-
-	spin_lock_irqsave(&adapter->req_list_lock, flags);
-	fsf_req = zfcp_reqlist_find(adapter, req_id);
-
-	if (!fsf_req)
-		/*
-		 * Unknown request means that we have potentially memory
-		 * corruption and must stop the machine immediatly.
-		 */
-		panic("error: unknown request id (%lx) on adapter %s.\n",
-		      req_id, dev_name(&adapter->ccw_device->dev));
-
-	zfcp_reqlist_remove(adapter, fsf_req);
-	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
-
-	fsf_req->sbal_response = sbal_idx;
-	fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
-	zfcp_fsf_req_complete(fsf_req);
+	wake_up(&qdio->req_q_wq);
 }
 
-static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed)
+static void zfcp_qdio_resp_put_back(struct zfcp_qdio *qdio, int processed)
 {
-	struct zfcp_qdio_queue *queue = &adapter->resp_q;
-	struct ccw_device *cdev = adapter->ccw_device;
+	struct zfcp_qdio_queue *queue = &qdio->resp_q;
+	struct ccw_device *cdev = qdio->adapter->ccw_device;
 	u8 count, start = queue->first;
 	unsigned int retval;
 
@@ -162,14 +118,13 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
 			       int queue_no, int first, int count,
 			       unsigned long parm)
 {
-	struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm;
-	struct zfcp_qdio_queue *queue = &adapter->resp_q;
-	struct qdio_buffer_element *sbale;
-	int sbal_idx, sbale_idx, sbal_no;
+	struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
+	int sbal_idx, sbal_no;
 
 	if (unlikely(qdio_err)) {
-		zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
-		zfcp_qdio_handler_error(adapter, "qdires1");
+		zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, first,
+					count);
+		zfcp_qdio_handler_error(qdio, "qdires1");
 		return;
 	}
 
@@ -179,39 +134,27 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
 	 */
 	for (sbal_no = 0; sbal_no < count; sbal_no++) {
 		sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q;
-
 		/* go through all SBALEs of SBAL */
-		for (sbale_idx = 0; sbale_idx < QDIO_MAX_ELEMENTS_PER_BUFFER;
-		     sbale_idx++) {
-			sbale = zfcp_qdio_sbale(queue, sbal_idx, sbale_idx);
-			zfcp_qdio_reqid_check(adapter,
-					      (unsigned long) sbale->addr,
-					      sbal_idx);
-			if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
-				break;
-		};
-
-		if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY)))
-			dev_warn(&adapter->ccw_device->dev,
-				 "A QDIO protocol error occurred, "
-				 "operations continue\n");
+		zfcp_fsf_reqid_check(qdio, sbal_idx);
 	}
 
 	/*
 	 * put range of SBALs back to response queue
 	 * (including SBALs which have already been free before)
 	 */
-	zfcp_qdio_resp_put_back(adapter, count);
+	zfcp_qdio_resp_put_back(qdio, count);
 }
 
 /**
  * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req
- * @fsf_req: pointer to struct fsf_req
+ * @qdio: pointer to struct zfcp_qdio
+ * @q_rec: pointer to struct zfcp_queue_rec
  * Returns: pointer to qdio_buffer_element (SBALE) structure
  */
-struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
+struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_qdio *qdio,
+						struct zfcp_queue_req *q_req)
 {
-	return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0);
+	return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last, 0);
 }
 
 /**
@@ -219,74 +162,80 @@ struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
  * @fsf_req: pointer to struct fsf_req
  * Returns: pointer to qdio_buffer_element (SBALE) structure
  */
-struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req)
+struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio,
+						 struct zfcp_queue_req *q_req)
 {
-	return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last,
-			       req->sbale_curr);
+	return zfcp_qdio_sbale(&qdio->req_q, q_req->sbal_last,
+			       q_req->sbale_curr);
 }
 
-static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals)
+static void zfcp_qdio_sbal_limit(struct zfcp_qdio *qdio,
+				 struct zfcp_queue_req *q_req, int max_sbals)
 {
-	int count = atomic_read(&fsf_req->adapter->req_q.count);
+	int count = atomic_read(&qdio->req_q.count);
 	count = min(count, max_sbals);
-	fsf_req->sbal_limit = (fsf_req->sbal_first + count - 1)
+	q_req->sbal_limit = (q_req->sbal_first + count - 1)
 					% QDIO_MAX_BUFFERS_PER_Q;
 }
 
 static struct qdio_buffer_element *
-zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
+zfcp_qdio_sbal_chain(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req,
+		     unsigned long sbtype)
 {
 	struct qdio_buffer_element *sbale;
 
 	/* set last entry flag in current SBALE of current SBAL */
-	sbale = zfcp_qdio_sbale_curr(fsf_req);
+	sbale = zfcp_qdio_sbale_curr(qdio, q_req);
 	sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	/* don't exceed last allowed SBAL */
-	if (fsf_req->sbal_last == fsf_req->sbal_limit)
+	if (q_req->sbal_last == q_req->sbal_limit)
 		return NULL;
 
 	/* set chaining flag in first SBALE of current SBAL */
-	sbale = zfcp_qdio_sbale_req(fsf_req);
+	sbale = zfcp_qdio_sbale_req(qdio, q_req);
 	sbale->flags |= SBAL_FLAGS0_MORE_SBALS;
 
 	/* calculate index of next SBAL */
-	fsf_req->sbal_last++;
-	fsf_req->sbal_last %= QDIO_MAX_BUFFERS_PER_Q;
+	q_req->sbal_last++;
+	q_req->sbal_last %= QDIO_MAX_BUFFERS_PER_Q;
 
 	/* keep this requests number of SBALs up-to-date */
-	fsf_req->sbal_number++;
+	q_req->sbal_number++;
 
 	/* start at first SBALE of new SBAL */
-	fsf_req->sbale_curr = 0;
+	q_req->sbale_curr = 0;
 
 	/* set storage-block type for new SBAL */
-	sbale = zfcp_qdio_sbale_curr(fsf_req);
+	sbale = zfcp_qdio_sbale_curr(qdio, q_req);
 	sbale->flags |= sbtype;
 
 	return sbale;
 }
 
 static struct qdio_buffer_element *
-zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype)
+zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req,
+		     unsigned int sbtype)
 {
-	if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
-		return zfcp_qdio_sbal_chain(fsf_req, sbtype);
-	fsf_req->sbale_curr++;
-	return zfcp_qdio_sbale_curr(fsf_req);
+	if (q_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
+		return zfcp_qdio_sbal_chain(qdio, q_req, sbtype);
+	q_req->sbale_curr++;
+	return zfcp_qdio_sbale_curr(qdio, q_req);
 }
 
-static void zfcp_qdio_undo_sbals(struct zfcp_fsf_req *fsf_req)
+static void zfcp_qdio_undo_sbals(struct zfcp_qdio *qdio,
+				 struct zfcp_queue_req *q_req)
 {
-	struct qdio_buffer **sbal = fsf_req->adapter->req_q.sbal;
-	int first = fsf_req->sbal_first;
-	int last = fsf_req->sbal_last;
+	struct qdio_buffer **sbal = qdio->req_q.sbal;
+	int first = q_req->sbal_first;
+	int last = q_req->sbal_last;
 	int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) %
 		QDIO_MAX_BUFFERS_PER_Q + 1;
 	zfcp_qdio_zero_sbals(sbal, first, count);
 }
 
-static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
+static int zfcp_qdio_fill_sbals(struct zfcp_qdio *qdio,
+				struct zfcp_queue_req *q_req,
 				unsigned int sbtype, void *start_addr,
 				unsigned int total_length)
 {
@@ -297,10 +246,10 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
 	/* split segment up */
 	for (addr = start_addr, remaining = total_length; remaining > 0;
 	     addr += length, remaining -= length) {
-		sbale = zfcp_qdio_sbale_next(fsf_req, sbtype);
+		sbale = zfcp_qdio_sbale_next(qdio, q_req, sbtype);
 		if (!sbale) {
-			atomic_inc(&fsf_req->adapter->qdio_outb_full);
-			zfcp_qdio_undo_sbals(fsf_req);
+			atomic_inc(&qdio->req_q_full);
+			zfcp_qdio_undo_sbals(qdio, q_req);
 			return -EINVAL;
 		}
 
@@ -322,29 +271,31 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
  * @max_sbals: upper bound for number of SBALs to be used
  * Returns: number of bytes, or error (negativ)
  */
-int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
-			    struct scatterlist *sg, int max_sbals)
+int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio,
+			    struct zfcp_queue_req *q_req,
+			    unsigned long sbtype, struct scatterlist *sg,
+			    int max_sbals)
 {
 	struct qdio_buffer_element *sbale;
 	int retval, bytes = 0;
 
 	/* figure out last allowed SBAL */
-	zfcp_qdio_sbal_limit(fsf_req, max_sbals);
+	zfcp_qdio_sbal_limit(qdio, q_req, max_sbals);
 
 	/* set storage-block type for this request */
-	sbale = zfcp_qdio_sbale_req(fsf_req);
+	sbale = zfcp_qdio_sbale_req(qdio, q_req);
 	sbale->flags |= sbtype;
 
 	for (; sg; sg = sg_next(sg)) {
-		retval = zfcp_qdio_fill_sbals(fsf_req, sbtype, sg_virt(sg),
-					      sg->length);
+		retval = zfcp_qdio_fill_sbals(qdio, q_req, sbtype,
+					      sg_virt(sg), sg->length);
 		if (retval < 0)
 			return retval;
 		bytes += sg->length;
 	}
 
 	/* assume that no other SBALEs are to follow in the same SBAL */
-	sbale = zfcp_qdio_sbale_curr(fsf_req);
+	sbale = zfcp_qdio_sbale_curr(qdio, q_req);
 	sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
 
 	return bytes;
@@ -352,21 +303,22 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
 
 /**
  * zfcp_qdio_send - set PCI flag in first SBALE and send req to QDIO
- * @fsf_req: pointer to struct zfcp_fsf_req
+ * @qdio: pointer to struct zfcp_qdio
+ * @q_req: pointer to struct zfcp_queue_req
  * Returns: 0 on success, error otherwise
  */
-int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
+int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_queue_req *q_req)
 {
-	struct zfcp_adapter *adapter = fsf_req->adapter;
-	struct zfcp_qdio_queue *req_q = &adapter->req_q;
-	int first = fsf_req->sbal_first;
-	int count = fsf_req->sbal_number;
+	struct zfcp_qdio_queue *req_q = &qdio->req_q;
+	int first = q_req->sbal_first;
+	int count = q_req->sbal_number;
 	int retval;
 	unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
 
-	zfcp_qdio_account(adapter);
+	zfcp_qdio_account(qdio);
 
-	retval = do_QDIO(adapter->ccw_device, qdio_flags, 0, first, count);
+	retval = do_QDIO(qdio->adapter->ccw_device, qdio_flags, 0, first,
+			 count);
 	if (unlikely(retval)) {
 		zfcp_qdio_zero_sbals(req_q->sbal, first, count);
 		return retval;
@@ -379,63 +331,69 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
 	return 0;
 }
 
+
+static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
+				      struct zfcp_qdio *qdio)
+{
+
+	id->cdev = qdio->adapter->ccw_device;
+	id->q_format = QDIO_ZFCP_QFMT;
+	memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8);
+	ASCEBC(id->adapter_name, 8);
+	id->qib_param_field_format = 0;
+	id->qib_param_field = NULL;
+	id->input_slib_elements = NULL;
+	id->output_slib_elements = NULL;
+	id->no_input_qs = 1;
+	id->no_output_qs = 1;
+	id->input_handler = zfcp_qdio_int_resp;
+	id->output_handler = zfcp_qdio_int_req;
+	id->int_parm = (unsigned long) qdio;
+	id->flags = QDIO_INBOUND_0COPY_SBALS |
+		    QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
+	id->input_sbal_addr_array = (void **) (qdio->resp_q.sbal);
+	id->output_sbal_addr_array = (void **) (qdio->req_q.sbal);
+
+}
 /**
  * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data
  * @adapter: pointer to struct zfcp_adapter
  * Returns: -ENOMEM on memory allocation error or return value from
  *          qdio_allocate
  */
-int zfcp_qdio_allocate(struct zfcp_adapter *adapter)
+static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
 {
-	struct qdio_initialize *init_data;
+	struct qdio_initialize init_data;
 
-	if (zfcp_qdio_buffers_enqueue(adapter->req_q.sbal) ||
-		   zfcp_qdio_buffers_enqueue(adapter->resp_q.sbal))
+	if (zfcp_qdio_buffers_enqueue(qdio->req_q.sbal) ||
+	    zfcp_qdio_buffers_enqueue(qdio->resp_q.sbal))
 		return -ENOMEM;
 
-	init_data = &adapter->qdio_init_data;
-
-	init_data->cdev = adapter->ccw_device;
-	init_data->q_format = QDIO_ZFCP_QFMT;
-	memcpy(init_data->adapter_name, dev_name(&adapter->ccw_device->dev), 8);
-	ASCEBC(init_data->adapter_name, 8);
-	init_data->qib_param_field_format = 0;
-	init_data->qib_param_field = NULL;
-	init_data->input_slib_elements = NULL;
-	init_data->output_slib_elements = NULL;
-	init_data->no_input_qs = 1;
-	init_data->no_output_qs = 1;
-	init_data->input_handler = zfcp_qdio_int_resp;
-	init_data->output_handler = zfcp_qdio_int_req;
-	init_data->int_parm = (unsigned long) adapter;
-	init_data->flags = QDIO_INBOUND_0COPY_SBALS |
-			QDIO_OUTBOUND_0COPY_SBALS | QDIO_USE_OUTBOUND_PCIS;
-	init_data->input_sbal_addr_array =
-			(void **) (adapter->resp_q.sbal);
-	init_data->output_sbal_addr_array =
-			(void **) (adapter->req_q.sbal);
-
-	return qdio_allocate(init_data);
+	zfcp_qdio_setup_init_data(&init_data, qdio);
+
+	return qdio_allocate(&init_data);
 }
 
 /**
  * zfcp_close_qdio - close qdio queues for an adapter
+ * @qdio: pointer to structure zfcp_qdio
  */
-void zfcp_qdio_close(struct zfcp_adapter *adapter)
+void zfcp_qdio_close(struct zfcp_qdio *qdio)
 {
 	struct zfcp_qdio_queue *req_q;
 	int first, count;
 
-	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
+	if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
 		return;
 
 	/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
-	req_q = &adapter->req_q;
-	spin_lock_bh(&adapter->req_q_lock);
-	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-	spin_unlock_bh(&adapter->req_q_lock);
+	req_q = &qdio->req_q;
+	spin_lock_bh(&qdio->req_q_lock);
+	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status);
+	spin_unlock_bh(&qdio->req_q_lock);
 
-	qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
+	qdio_shutdown(qdio->adapter->ccw_device,
+		      QDIO_FLAG_CLEANUP_USING_CLEAR);
 
 	/* cleanup used outbound sbals */
 	count = atomic_read(&req_q->count);
@@ -446,50 +404,99 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
 	}
 	req_q->first = 0;
 	atomic_set(&req_q->count, 0);
-	adapter->resp_q.first = 0;
-	atomic_set(&adapter->resp_q.count, 0);
+	qdio->resp_q.first = 0;
+	atomic_set(&qdio->resp_q.count, 0);
 }
 
 /**
  * zfcp_qdio_open - prepare and initialize response queue
- * @adapter: pointer to struct zfcp_adapter
+ * @qdio: pointer to struct zfcp_qdio
  * Returns: 0 on success, otherwise -EIO
  */
-int zfcp_qdio_open(struct zfcp_adapter *adapter)
+int zfcp_qdio_open(struct zfcp_qdio *qdio)
 {
 	struct qdio_buffer_element *sbale;
+	struct qdio_initialize init_data;
+	struct ccw_device *cdev = qdio->adapter->ccw_device;
 	int cc;
 
-	if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)
+	if (atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)
 		return -EIO;
 
-	if (qdio_establish(&adapter->qdio_init_data))
+	zfcp_qdio_setup_init_data(&init_data, qdio);
+
+	if (qdio_establish(&init_data))
 		goto failed_establish;
 
-	if (qdio_activate(adapter->ccw_device))
+	if (qdio_activate(cdev))
 		goto failed_qdio;
 
 	for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) {
-		sbale = &(adapter->resp_q.sbal[cc]->element[0]);
+		sbale = &(qdio->resp_q.sbal[cc]->element[0]);
 		sbale->length = 0;
 		sbale->flags = SBAL_FLAGS_LAST_ENTRY;
 		sbale->addr = NULL;
 	}
 
-	if (do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_INPUT, 0, 0,
+	if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0,
 		     QDIO_MAX_BUFFERS_PER_Q))
 		goto failed_qdio;
 
 	/* set index of first avalable SBALS / number of available SBALS */
-	adapter->req_q.first = 0;
-	atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
+	qdio->req_q.first = 0;
+	atomic_set(&qdio->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
 
 	return 0;
 
 failed_qdio:
-	qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
+	qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
 failed_establish:
-	dev_err(&adapter->ccw_device->dev,
+	dev_err(&cdev->dev,
 		"Setting up the QDIO connection to the FCP adapter failed\n");
 	return -EIO;
 }
+
+void zfcp_qdio_destroy(struct zfcp_qdio *qdio)
+{
+	struct qdio_buffer **sbal_req, **sbal_resp;
+	int p;
+
+	if (!qdio)
+		return;
+
+	if (qdio->adapter->ccw_device)
+		qdio_free(qdio->adapter->ccw_device);
+
+	sbal_req = qdio->req_q.sbal;
+	sbal_resp = qdio->resp_q.sbal;
+
+	for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) {
+		free_page((unsigned long) sbal_req[p]);
+		free_page((unsigned long) sbal_resp[p]);
+	}
+
+	kfree(qdio);
+}
+
+int zfcp_qdio_setup(struct zfcp_adapter *adapter)
+{
+	struct zfcp_qdio *qdio;
+
+	qdio = kzalloc(sizeof(struct zfcp_qdio), GFP_KERNEL);
+	if (!qdio)
+		return -ENOMEM;
+
+	qdio->adapter = adapter;
+
+	if (zfcp_qdio_allocate(qdio)) {
+		zfcp_qdio_destroy(qdio);
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&qdio->req_q_lock);
+	spin_lock_init(&qdio->stat_lock);
+
+	adapter->qdio = qdio;
+	return 0;
+}
+
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 6925a17..3ff726a 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -9,8 +9,9 @@
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
-#include "zfcp_ext.h"
 #include <asm/atomic.h>
+#include "zfcp_ext.h"
+#include "zfcp_dbf.h"
 
 static unsigned int default_depth = 32;
 module_param_named(queue_depth, default_depth, uint, 0600);
@@ -52,11 +53,11 @@ static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
 
 static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
 {
+	struct zfcp_adapter *adapter =
+		(struct zfcp_adapter *) scpnt->device->host->hostdata[0];
 	set_host_byte(scpnt, result);
 	if ((scpnt->device != NULL) && (scpnt->device->host != NULL))
-		zfcp_scsi_dbf_event_result("fail", 4,
-			(struct zfcp_adapter*) scpnt->device->host->hostdata[0],
-			scpnt, NULL);
+		zfcp_dbf_scsi_result("fail", 4, adapter->dbf, scpnt, NULL);
 	/* return directly */
 	scpnt->scsi_done(scpnt);
 }
@@ -92,7 +93,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
 	scsi_result = fc_remote_port_chkready(rport);
 	if (unlikely(scsi_result)) {
 		scpnt->result = scsi_result;
-		zfcp_scsi_dbf_event_result("fail", 4, adapter, scpnt, NULL);
+		zfcp_dbf_scsi_result("fail", 4, adapter->dbf, scpnt, NULL);
 		scpnt->scsi_done(scpnt);
 		return 0;
 	}
@@ -180,8 +181,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 	spin_unlock(&adapter->req_list_lock);
 	if (!old_req) {
 		write_unlock_irqrestore(&adapter->abort_lock, flags);
-		zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL,
-					  old_reqid);
+		zfcp_dbf_scsi_abort("lte1", adapter->dbf, scpnt, NULL,
+				    old_reqid);
 		return FAILED; /* completion could be in progress */
 	}
 	old_req->data = NULL;
@@ -197,16 +198,15 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 		zfcp_erp_wait(adapter);
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
-			zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
-						  old_reqid);
+			zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL,
+					    old_reqid);
 			return SUCCESS;
 		}
 	}
 	if (!abrt_req)
 		return FAILED;
 
-	wait_event(abrt_req->completion_wq,
-		   abrt_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+	wait_for_completion(&abrt_req->completion);
 
 	if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED)
 		dbf_tag = "okay";
@@ -216,7 +216,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 		dbf_tag = "fail";
 		retval = FAILED;
 	}
-	zfcp_scsi_dbf_event_abort(dbf_tag, adapter, scpnt, abrt_req, old_reqid);
+	zfcp_dbf_scsi_abort(dbf_tag, adapter->dbf, scpnt, abrt_req, old_reqid);
 	zfcp_fsf_req_free(abrt_req);
 	return retval;
 }
@@ -225,7 +225,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
 {
 	struct zfcp_unit *unit = scpnt->device->hostdata;
 	struct zfcp_adapter *adapter = unit->port->adapter;
-	struct zfcp_fsf_req *fsf_req;
+	struct zfcp_fsf_req *fsf_req = NULL;
 	int retval = SUCCESS;
 	int retry = 3;
 
@@ -237,25 +237,23 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
 		zfcp_erp_wait(adapter);
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
-			zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit,
-						     scpnt);
+			zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt);
 			return SUCCESS;
 		}
 	}
 	if (!fsf_req)
 		return FAILED;
 
-	wait_event(fsf_req->completion_wq,
-		   fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+	wait_for_completion(&fsf_req->completion);
 
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
-		zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);
+		zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt);
 		retval = FAILED;
 	} else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) {
-		zfcp_scsi_dbf_event_devreset("nsup", tm_flags, unit, scpnt);
+		zfcp_dbf_scsi_devreset("nsup", tm_flags, unit, scpnt);
 		retval = FAILED;
 	} else
-		zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt);
+		zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt);
 
 	zfcp_fsf_req_free(fsf_req);
 	return retval;
@@ -430,7 +428,7 @@ static struct fc_host_statistics *zfcp_get_fc_host_stats(struct Scsi_Host *host)
 	if (!data)
 		return NULL;
 
-	ret = zfcp_fsf_exchange_port_data_sync(adapter, data);
+	ret = zfcp_fsf_exchange_port_data_sync(adapter->qdio, data);
 	if (ret) {
 		kfree(data);
 		return NULL;
@@ -459,7 +457,7 @@ static void zfcp_reset_fc_host_stats(struct Scsi_Host *shost)
 	if (!data)
 		return;
 
-	ret = zfcp_fsf_exchange_port_data_sync(adapter, data);
+	ret = zfcp_fsf_exchange_port_data_sync(adapter->qdio, data);
 	if (ret)
 		kfree(data);
 	else {
@@ -493,21 +491,6 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
 }
 
 /**
- * zfcp_scsi_dev_loss_tmo_callbk - Free any reference to rport
- * @rport: The rport that is about to be deleted.
- */
-static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
-{
-	struct zfcp_port *port;
-
-	write_lock_irq(&zfcp_data.config_lock);
-	port = rport->dd_data;
-	if (port)
-		port->rport = NULL;
-	write_unlock_irq(&zfcp_data.config_lock);
-}
-
-/**
  * zfcp_scsi_terminate_rport_io - Terminate all I/O on a rport
  * @rport: The FC rport where to teminate I/O
  *
@@ -518,9 +501,12 @@ static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport)
 static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
 {
 	struct zfcp_port *port;
+	struct Scsi_Host *shost = rport_to_shost(rport);
+	struct zfcp_adapter *adapter =
+		(struct zfcp_adapter *)shost->hostdata[0];
 
 	write_lock_irq(&zfcp_data.config_lock);
-	port = rport->dd_data;
+	port = zfcp_get_port_by_wwpn(adapter, rport->port_name);
 	if (port)
 		zfcp_port_get(port);
 	write_unlock_irq(&zfcp_data.config_lock);
@@ -552,7 +538,6 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)
 		return;
 	}
 
-	rport->dd_data = port;
 	rport->maxframe_size = port->maxframe_size;
 	rport->supported_classes = port->supported_classes;
 	port->rport = rport;
@@ -573,7 +558,7 @@ void zfcp_scsi_schedule_rport_register(struct zfcp_port *port)
 	zfcp_port_get(port);
 	port->rport_task = RPORT_ADD;
 
-	if (!queue_work(zfcp_data.work_queue, &port->rport_work))
+	if (!queue_work(port->adapter->work_queue, &port->rport_work))
 		zfcp_port_put(port);
 }
 
@@ -582,8 +567,11 @@ void zfcp_scsi_schedule_rport_block(struct zfcp_port *port)
 	zfcp_port_get(port);
 	port->rport_task = RPORT_DEL;
 
-	if (!queue_work(zfcp_data.work_queue, &port->rport_work))
-		zfcp_port_put(port);
+	if (port->rport && queue_work(port->adapter->work_queue,
+				      &port->rport_work))
+		return;
+
+	zfcp_port_put(port);
 }
 
 void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter)
@@ -662,7 +650,6 @@ struct fc_function_template zfcp_transport_functions = {
 	.reset_fc_host_stats = zfcp_reset_fc_host_stats,
 	.set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo,
 	.get_host_port_state = zfcp_get_host_port_state,
-	.dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk,
 	.terminate_rport_io = zfcp_scsi_terminate_rport_io,
 	.show_host_port_state = 1,
 	.bsg_request = zfcp_execute_fc_job,
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 0fe5cce..079a8cf 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -88,7 +88,7 @@ static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev,	       \
 	unsigned long val;						       \
 	int retval = 0;							       \
 									       \
-	down(&zfcp_data.config_sema);					       \
+	mutex_lock(&zfcp_data.config_mutex);				       \
 	if (atomic_read(&_feat->status) & ZFCP_STATUS_COMMON_REMOVE) {	       \
 		retval = -EBUSY;					       \
 		goto out;						       \
@@ -105,7 +105,7 @@ static ssize_t zfcp_sysfs_##_feat##_failed_store(struct device *dev,	       \
 				  _reopen_id, NULL);			       \
 	zfcp_erp_wait(_adapter);					       \
 out:									       \
-	up(&zfcp_data.config_sema);					       \
+	mutex_unlock(&zfcp_data.config_mutex);				       \
 	return retval ? retval : (ssize_t) count;			       \
 }									       \
 static ZFCP_DEV_ATTR(_feat, failed, S_IWUSR | S_IRUGO,			       \
@@ -126,7 +126,7 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
 	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE)
 		return -EBUSY;
 
-	ret = zfcp_scan_ports(adapter);
+	ret = zfcp_fc_scan_ports(adapter);
 	return ret ? ret : (ssize_t) count;
 }
 static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL,
@@ -142,7 +142,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
 	int retval = 0;
 	LIST_HEAD(port_remove_lh);
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_REMOVE) {
 		retval = -EBUSY;
 		goto out;
@@ -173,7 +173,7 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev,
 	zfcp_port_put(port);
 	zfcp_port_dequeue(port);
  out:
-	up(&zfcp_data.config_sema);
+	mutex_unlock(&zfcp_data.config_mutex);
 	return retval ? retval : (ssize_t) count;
 }
 static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL,
@@ -207,7 +207,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
 	u64 fcp_lun;
 	int retval = -EINVAL;
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
 		retval = -EBUSY;
 		goto out;
@@ -226,7 +226,7 @@ static ssize_t zfcp_sysfs_unit_add_store(struct device *dev,
 	zfcp_erp_wait(unit->port->adapter);
 	zfcp_unit_put(unit);
 out:
-	up(&zfcp_data.config_sema);
+	mutex_unlock(&zfcp_data.config_mutex);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_add, S_IWUSR, NULL, zfcp_sysfs_unit_add_store);
@@ -241,7 +241,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
 	int retval = 0;
 	LIST_HEAD(unit_remove_lh);
 
-	down(&zfcp_data.config_sema);
+	mutex_lock(&zfcp_data.config_mutex);
 	if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_REMOVE) {
 		retval = -EBUSY;
 		goto out;
@@ -282,7 +282,7 @@ static ssize_t zfcp_sysfs_unit_remove_store(struct device *dev,
 	zfcp_unit_put(unit);
 	zfcp_unit_dequeue(unit);
 out:
-	up(&zfcp_data.config_sema);
+	mutex_unlock(&zfcp_data.config_mutex);
 	return retval ? retval : (ssize_t) count;
 }
 static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store);
@@ -425,7 +425,7 @@ static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
 	if (!qtcb_port)
 		return -ENOMEM;
 
-	retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port);
+	retval = zfcp_fsf_exchange_port_data_sync(adapter->qdio, qtcb_port);
 	if (!retval)
 		retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util,
 				 qtcb_port->cb_util, qtcb_port->a_util);
@@ -451,7 +451,7 @@ static int zfcp_sysfs_adapter_ex_config(struct device *dev,
 	if (!qtcb_config)
 		return -ENOMEM;
 
-	retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
+	retval = zfcp_fsf_exchange_config_data_sync(adapter->qdio, qtcb_config);
 	if (!retval)
 		*stat_inf = qtcb_config->stat_info;
 
@@ -492,15 +492,15 @@ static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
 					      char *buf)
 {
 	struct Scsi_Host *scsi_host = class_to_shost(dev);
-	struct zfcp_adapter *adapter =
-		(struct zfcp_adapter *) scsi_host->hostdata[0];
+	struct zfcp_qdio *qdio =
+		((struct zfcp_adapter *) scsi_host->hostdata[0])->qdio;
 	u64 util;
 
-	spin_lock_bh(&adapter->qdio_stat_lock);
-	util = adapter->req_q_util;
-	spin_unlock_bh(&adapter->qdio_stat_lock);
+	spin_lock_bh(&qdio->stat_lock);
+	util = qdio->req_q_util;
+	spin_unlock_bh(&qdio->stat_lock);
 
-	return sprintf(buf, "%d %llu\n", atomic_read(&adapter->qdio_outb_full),
+	return sprintf(buf, "%d %llu\n", atomic_read(&qdio->req_q_full),
 		       (unsigned long long)util);
 }
 static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 9c23122..82bb3b2 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1811,6 +1811,12 @@ config ZFCP
           called zfcp. If you want to compile it as a module, say M here
           and read <file:Documentation/kbuild/modules.txt>.
 
+config SCSI_PMCRAID
+	tristate "PMC SIERRA Linux MaxRAID adapter support"
+	depends on PCI && SCSI
+	---help---
+	  This driver supports the PMC SIERRA MaxRAID adapters.
+
 config SCSI_SRP
 	tristate "SCSI RDMA Protocol helper library"
 	depends on SCSI && PCI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 25429ea..61a94af 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -130,6 +130,7 @@ obj-$(CONFIG_SCSI_MVSAS)	+= mvsas/
 obj-$(CONFIG_PS3_ROM)		+= ps3rom.o
 obj-$(CONFIG_SCSI_CXGB3_ISCSI)	+= libiscsi.o libiscsi_tcp.o cxgb3i/
 obj-$(CONFIG_SCSI_BNX2_ISCSI)	+= libiscsi.o bnx2i/
+obj-$(CONFIG_SCSI_PMCRAID)	+= pmcraid.o
 
 obj-$(CONFIG_ARM)		+= arm/
 
diff --git a/drivers/scsi/bnx2i/bnx2i_init.c b/drivers/scsi/bnx2i/bnx2i_init.c
index ae4b2d5..0c4210d 100644
--- a/drivers/scsi/bnx2i/bnx2i_init.c
+++ b/drivers/scsi/bnx2i/bnx2i_init.c
@@ -15,11 +15,10 @@
 
 static struct list_head adapter_list = LIST_HEAD_INIT(adapter_list);
 static u32 adapter_count;
-static int bnx2i_reg_device;
 
 #define DRV_MODULE_NAME		"bnx2i"
-#define DRV_MODULE_VERSION	"2.0.1d"
-#define DRV_MODULE_RELDATE	"Mar 25, 2009"
+#define DRV_MODULE_VERSION	"2.0.1e"
+#define DRV_MODULE_RELDATE	"June 22, 2009"
 
 static char version[] __devinitdata =
 		"Broadcom NetXtreme II iSCSI Driver " DRV_MODULE_NAME \
@@ -31,7 +30,7 @@ MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708/5709 iSCSI Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
-static DEFINE_RWLOCK(bnx2i_dev_lock);
+static DEFINE_MUTEX(bnx2i_dev_lock);
 
 unsigned int event_coal_div = 1;
 module_param(event_coal_div, int, 0664);
@@ -100,14 +99,14 @@ struct bnx2i_hba *get_adapter_list_head(void)
 	if (!adapter_count)
 		goto hba_not_found;
 
-	read_lock(&bnx2i_dev_lock);
+	mutex_lock(&bnx2i_dev_lock);
 	list_for_each_entry(tmp_hba, &adapter_list, link) {
 		if (tmp_hba->cnic && tmp_hba->cnic->cm_select_dev) {
 			hba = tmp_hba;
 			break;
 		}
 	}
-	read_unlock(&bnx2i_dev_lock);
+	mutex_unlock(&bnx2i_dev_lock);
 hba_not_found:
 	return hba;
 }
@@ -122,14 +121,14 @@ struct bnx2i_hba *bnx2i_find_hba_for_cnic(struct cnic_dev *cnic)
 {
 	struct bnx2i_hba *hba, *temp;
 
-	read_lock(&bnx2i_dev_lock);
+	mutex_lock(&bnx2i_dev_lock);
 	list_for_each_entry_safe(hba, temp, &adapter_list, link) {
 		if (hba->cnic == cnic) {
-			read_unlock(&bnx2i_dev_lock);
+			mutex_unlock(&bnx2i_dev_lock);
 			return hba;
 		}
 	}
-	read_unlock(&bnx2i_dev_lock);
+	mutex_unlock(&bnx2i_dev_lock);
 	return NULL;
 }
 
@@ -186,18 +185,17 @@ void bnx2i_stop(void *handle)
  */
 void bnx2i_register_device(struct bnx2i_hba *hba)
 {
+	int rc;
+
 	if (test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) ||
 	    test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
 		return;
 	}
 
-	hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba);
+	rc = hba->cnic->register_device(hba->cnic, CNIC_ULP_ISCSI, hba);
 
-	spin_lock(&hba->lock);
-	bnx2i_reg_device++;
-	spin_unlock(&hba->lock);
-
-	set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
+	if (!rc)
+		set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
 }
 
 
@@ -211,10 +209,10 @@ void bnx2i_reg_dev_all(void)
 {
 	struct bnx2i_hba *hba, *temp;
 
-	read_lock(&bnx2i_dev_lock);
+	mutex_lock(&bnx2i_dev_lock);
 	list_for_each_entry_safe(hba, temp, &adapter_list, link)
 		bnx2i_register_device(hba);
-	read_unlock(&bnx2i_dev_lock);
+	mutex_unlock(&bnx2i_dev_lock);
 }
 
 
@@ -234,10 +232,6 @@ static void bnx2i_unreg_one_device(struct bnx2i_hba *hba)
 
 	hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
 
-	spin_lock(&hba->lock);
-	bnx2i_reg_device--;
-	spin_unlock(&hba->lock);
-
 	/* ep_disconnect could come before NETDEV_DOWN, driver won't
 	 * see NETDEV_DOWN as it already unregistered itself.
 	 */
@@ -255,10 +249,10 @@ void bnx2i_unreg_dev_all(void)
 {
 	struct bnx2i_hba *hba, *temp;
 
-	read_lock(&bnx2i_dev_lock);
+	mutex_lock(&bnx2i_dev_lock);
 	list_for_each_entry_safe(hba, temp, &adapter_list, link)
 		bnx2i_unreg_one_device(hba);
-	read_unlock(&bnx2i_dev_lock);
+	mutex_unlock(&bnx2i_dev_lock);
 }
 
 
@@ -267,35 +261,34 @@ void bnx2i_unreg_dev_all(void)
  * @hba:	bnx2i adapter instance
  * @cnic:	cnic device handle
  *
- * Global resource lock and host adapter lock is held during critical sections
- *	below. This routine is called from cnic_register_driver() context and
- *	work horse thread which does majority of device specific initialization
+ * Global resource lock is held during critical sections below. This routine is
+ *	called from either cnic_register_driver() or device hot plug context and
+ *	and does majority of device specific initialization
  */
 static int bnx2i_init_one(struct bnx2i_hba *hba, struct cnic_dev *cnic)
 {
 	int rc;
 
-	read_lock(&bnx2i_dev_lock);
-	if (bnx2i_reg_device &&
-	    !test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
-		rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba);
-		if (rc)		/* duplicate registration */
-			printk(KERN_ERR "bnx2i- dev reg failed\n");
-
-		spin_lock(&hba->lock);
-		bnx2i_reg_device++;
+	mutex_lock(&bnx2i_dev_lock);
+	rc = cnic->register_device(cnic, CNIC_ULP_ISCSI, hba);
+	if (!rc) {
 		hba->age++;
-		spin_unlock(&hba->lock);
-
 		set_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
-	}
-	read_unlock(&bnx2i_dev_lock);
-
-	write_lock(&bnx2i_dev_lock);
-	list_add_tail(&hba->link, &adapter_list);
-	adapter_count++;
-	write_unlock(&bnx2i_dev_lock);
-	return 0;
+		list_add_tail(&hba->link, &adapter_list);
+		adapter_count++;
+	} else if (rc == -EBUSY) 	/* duplicate registration */
+		printk(KERN_ALERT "bnx2i, duplicate registration"
+				  "hba=%p, cnic=%p\n", hba, cnic);
+	else if (rc == -EAGAIN)
+		printk(KERN_ERR "bnx2i, driver not registered\n");
+	else if (rc == -EINVAL)
+		printk(KERN_ERR "bnx2i, invalid type %d\n", CNIC_ULP_ISCSI);
+	else
+		printk(KERN_ERR "bnx2i dev reg, unknown error, %d\n", rc);
+
+	mutex_unlock(&bnx2i_dev_lock);
+
+	return rc;
 }
 
 
@@ -343,19 +336,15 @@ void bnx2i_ulp_exit(struct cnic_dev *dev)
 				 "found, dev 0x%p\n", dev);
 		return;
 	}
-	write_lock(&bnx2i_dev_lock);
+	mutex_lock(&bnx2i_dev_lock);
 	list_del_init(&hba->link);
 	adapter_count--;
 
 	if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
 		hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
 		clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
-
-		spin_lock(&hba->lock);
-		bnx2i_reg_device--;
-		spin_unlock(&hba->lock);
 	}
-	write_unlock(&bnx2i_dev_lock);
+	mutex_unlock(&bnx2i_dev_lock);
 
 	bnx2i_free_hba(hba);
 }
@@ -377,6 +366,8 @@ static int __init bnx2i_mod_init(void)
 	if (!is_power_of_2(sq_size))
 		sq_size = roundup_pow_of_two(sq_size);
 
+	mutex_init(&bnx2i_dev_lock);
+
 	bnx2i_scsi_xport_template =
 			iscsi_register_transport(&bnx2i_iscsi_transport);
 	if (!bnx2i_scsi_xport_template) {
@@ -412,7 +403,7 @@ static void __exit bnx2i_mod_exit(void)
 {
 	struct bnx2i_hba *hba;
 
-	write_lock(&bnx2i_dev_lock);
+	mutex_lock(&bnx2i_dev_lock);
 	while (!list_empty(&adapter_list)) {
 		hba = list_entry(adapter_list.next, struct bnx2i_hba, link);
 		list_del(&hba->link);
@@ -421,14 +412,11 @@ static void __exit bnx2i_mod_exit(void)
 		if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
 			hba->cnic->unregister_device(hba->cnic, CNIC_ULP_ISCSI);
 			clear_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic);
-			bnx2i_reg_device--;
 		}
 
-		write_unlock(&bnx2i_dev_lock);
 		bnx2i_free_hba(hba);
-		write_lock(&bnx2i_dev_lock);
 	}
-	write_unlock(&bnx2i_dev_lock);
+	mutex_unlock(&bnx2i_dev_lock);
 
 	iscsi_unregister_transport(&bnx2i_iscsi_transport);
 	cnic_unregister_driver(CNIC_ULP_ISCSI);
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index f741219..9a7ba71 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -387,6 +387,7 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba)
 	bnx2i_ep = ep->dd_data;
 	INIT_LIST_HEAD(&bnx2i_ep->link);
 	bnx2i_ep->state = EP_STATE_IDLE;
+	bnx2i_ep->ep_iscsi_cid = (u16) -1;
 	bnx2i_ep->hba = hba;
 	bnx2i_ep->hba_age = hba->age;
 	hba->ofld_conns_active++;
@@ -1160,9 +1161,6 @@ static int bnx2i_task_xmit(struct iscsi_task *task)
 	struct bnx2i_cmd *cmd = task->dd_data;
 	struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr;
 
-	if (test_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state))
-		return -ENOTCONN;
-
 	if (!bnx2i_conn->is_bound)
 		return -ENOTCONN;
 
@@ -1653,15 +1651,18 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
 	struct iscsi_endpoint *ep;
 	int rc = 0;
 
-	if (shost)
+	if (shost) {
 		/* driver is given scsi host to work with */
 		hba = iscsi_host_priv(shost);
-	else
+		/* Register the device with cnic if not already done so */
+		bnx2i_register_device(hba);
+	} else
 		/*
 		 * check if the given destination can be reached through
 		 * a iscsi capable NetXtreme2 device
 		 */
 		hba = bnx2i_check_route(dst_addr);
+
 	if (!hba) {
 		rc = -ENOMEM;
 		goto check_busy;
@@ -1681,8 +1682,6 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
 		goto net_if_down;
 	}
 
-	bnx2i_ep->state = EP_STATE_IDLE;
-	bnx2i_ep->ep_iscsi_cid = (u16) -1;
 	bnx2i_ep->num_active_cmds = 0;
 	iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
 	if (iscsi_cid == -1) {
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 7b1633a..fe11c1d 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -353,6 +353,12 @@ ch_readconfig(scsi_changer *ch)
 	/* look up the devices of the data transfer elements */
 	ch->dt = kmalloc(ch->counts[CHET_DT]*sizeof(struct scsi_device),
 			 GFP_KERNEL);
+
+	if (!ch->dt) {
+		kfree(buffer);
+		return -ENOMEM;
+	}
+
 	for (elem = 0; elem < ch->counts[CHET_DT]; elem++) {
 		id  = -1;
 		lun = 0;
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index e79e181..63abb06 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -4,8 +4,7 @@
  * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422)
  * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002)
  *   by D. Gilbert and aeb (20020609)
- * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025
- * Update to SPC-4 T10/1713-D Rev 5a, 14 June 2006, D. Gilbert 20060702
+ * Update to SPC-4 T10/1713-D Rev 20, 22 May 2009, D. Gilbert 20090624
  */
 
 #include <linux/blkdev.h>
@@ -56,9 +55,9 @@ static const char * cdb_byte0_names[] = {
             "Read Buffer", 
 /* 3d-3f */ "Update Block", "Read Long(10)",  "Write Long(10)",
 /* 40-41 */ "Change Definition", "Write Same(10)",
-/* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support",
-            "Play audio(10)", "Get configuration", "Play audio msf",
-            "Play audio track/index",
+/* 42-48 */ "Unmap/Read sub-channel", "Read TOC/PMA/ATIP",
+	    "Read density support", "Play audio(10)", "Get configuration",
+	    "Play audio msf", "Play audio track/index",
 /* 49-4f */ "Play track relative(10)", "Get event status notification",
             "Pause/resume", "Log Select", "Log Sense", "Stop play/scan",
             NULL,
@@ -71,12 +70,13 @@ static const char * cdb_byte0_names[] = {
 /* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-/* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length",
+/* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, "Extended CDB",
+	    "Variable length",
 /* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy",
             "Receive copy results",
 /* 85-89 */ "ATA command pass through(16)", "Access control in",
 	    "Access control out", "Read(16)", "Memory Export Out(16)",
-/* 8a-8f */ "Write(16)", NULL, "Read attributes", "Write attributes",
+/* 8a-8f */ "Write(16)", "ORWrite", "Read attributes", "Write attributes",
             "Write and verify(16)", "Verify(16)",
 /* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)",
             "Lock/unlock cache(16)", "Write same(16)", NULL,
@@ -107,22 +107,24 @@ struct value_name_pair {
 };
 
 static const struct value_name_pair maint_in_arr[] = {
-	{0x5, "Report device identifier"},
+	{0x5, "Report identifying information"},
 	{0xa, "Report target port groups"},
 	{0xb, "Report aliases"},
 	{0xc, "Report supported operation codes"},
 	{0xd, "Report supported task management functions"},
 	{0xe, "Report priority"},
 	{0xf, "Report timestamp"},
+	{0x10, "Management protocol in"},
 };
 #define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr)
 
 static const struct value_name_pair maint_out_arr[] = {
-	{0x6, "Set device identifier"},
+	{0x6, "Set identifying information"},
 	{0xa, "Set target port groups"},
 	{0xb, "Change aliases"},
 	{0xe, "Set priority"},
-	{0xe, "Set timestamp"},
+	{0xf, "Set timestamp"},
+	{0x10, "Management protocol out"},
 };
 #define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr)
 
@@ -412,6 +414,7 @@ static const struct error_info additional[] =
 	{0x0004, "Beginning-of-partition/medium detected"},
 	{0x0005, "End-of-data detected"},
 	{0x0006, "I/O process terminated"},
+	{0x0007, "Programmable early warning detected"},
 	{0x0011, "Audio play operation in progress"},
 	{0x0012, "Audio play operation paused"},
 	{0x0013, "Audio play operation successfully completed"},
@@ -425,6 +428,7 @@ static const struct error_info additional[] =
 	{0x001B, "Set capacity operation in progress"},
 	{0x001C, "Verify operation in progress"},
 	{0x001D, "ATA pass through information available"},
+	{0x001E, "Conflicting SA creation request"},
 
 	{0x0100, "No index/sector signal"},
 
@@ -449,9 +453,12 @@ static const struct error_info additional[] =
 	{0x040B, "Logical unit not accessible, target port in standby state"},
 	{0x040C, "Logical unit not accessible, target port in unavailable "
 	 "state"},
+	{0x040D, "Logical unit not ready, structure check required"},
 	{0x0410, "Logical unit not ready, auxiliary memory not accessible"},
 	{0x0411, "Logical unit not ready, notify (enable spinup) required"},
 	{0x0412, "Logical unit not ready, offline"},
+	{0x0413, "Logical unit not ready, SA creation in progress"},
+	{0x0414, "Logical unit not ready, space allocation in progress"},
 
 	{0x0500, "Logical unit does not respond to selection"},
 
@@ -479,6 +486,9 @@ static const struct error_info additional[] =
 	{0x0B03, "Warning - background self-test failed"},
 	{0x0B04, "Warning - background pre-scan detected medium error"},
 	{0x0B05, "Warning - background medium scan detected medium error"},
+	{0x0B06, "Warning - non-volatile cache now volatile"},
+	{0x0B07, "Warning - degraded power to non-volatile cache"},
+	{0x0B08, "Warning - power loss expected"},
 
 	{0x0C00, "Write error"},
 	{0x0C01, "Write error - recovered with auto reallocation"},
@@ -593,6 +603,7 @@ static const struct error_info additional[] =
 	{0x1C02, "Grown defect list not found"},
 
 	{0x1D00, "Miscompare during verify operation"},
+	{0x1D01, "Miscompare verify of unmapped LBA"},
 
 	{0x1E00, "Recovered id with ECC correction"},
 
@@ -626,6 +637,7 @@ static const struct error_info additional[] =
 	{0x2405, "Security working key frozen"},
 	{0x2406, "Nonce not unique"},
 	{0x2407, "Nonce timestamp out of range"},
+	{0x2408, "Invalid XCDB"},
 
 	{0x2500, "Logical unit not supported"},
 
@@ -656,10 +668,12 @@ static const struct error_info additional[] =
 	{0x2704, "Persistent write protect"},
 	{0x2705, "Permanent write protect"},
 	{0x2706, "Conditional write protect"},
+	{0x2707, "Space allocation failed write protect"},
 
 	{0x2800, "Not ready to ready change, medium may have changed"},
 	{0x2801, "Import or export element accessed"},
 	{0x2802, "Format-layer may have changed"},
+	{0x2803, "Import/export element accessed, medium changed"},
 
 	{0x2900, "Power on, reset, or bus device reset occurred"},
 	{0x2901, "Power on occurred"},
@@ -680,11 +694,16 @@ static const struct error_info additional[] =
 	{0x2A07, "Implicit asymmetric access state transition failed"},
 	{0x2A08, "Priority changed"},
 	{0x2A09, "Capacity data has changed"},
+	{0x2A0A, "Error history I_T nexus cleared"},
+	{0x2A0B, "Error history snapshot released"},
+	{0x2A0C, "Error recovery attributes have changed"},
+	{0x2A0D, "Data encryption capabilities changed"},
 	{0x2A10, "Timestamp changed"},
 	{0x2A11, "Data encryption parameters changed by another i_t nexus"},
 	{0x2A12, "Data encryption parameters changed by vendor specific "
 		 "event"},
 	{0x2A13, "Data encryption key instance counter has changed"},
+	{0x2A14, "SA creation capabilities data has changed"},
 
 	{0x2B00, "Copy cannot execute since host cannot disconnect"},
 
@@ -723,6 +742,8 @@ static const struct error_info additional[] =
 	{0x300C, "WORM medium - overwrite attempted"},
 	{0x300D, "WORM medium - integrity check"},
 	{0x3010, "Medium not formatted"},
+	{0x3011, "Incompatible volume type"},
+	{0x3012, "Incompatible volume qualifier"},
 
 	{0x3100, "Medium format corrupted"},
 	{0x3101, "Format command failed"},
@@ -782,6 +803,10 @@ static const struct error_info additional[] =
 	{0x3B15, "Medium magazine unlocked"},
 	{0x3B16, "Mechanical positioning or changer error"},
 	{0x3B17, "Read past end of user object"},
+	{0x3B18, "Element disabled"},
+	{0x3B19, "Element enabled"},
+	{0x3B1A, "Data transfer device removed"},
+	{0x3B1B, "Data transfer device inserted"},
 
 	{0x3D00, "Invalid bits in identify message"},
 
@@ -882,6 +907,8 @@ static const struct error_info additional[] =
 	{0x5506, "Auxiliary memory out of space"},
 	{0x5507, "Quota error"},
 	{0x5508, "Maximum number of supplemental decryption keys exceeded"},
+	{0x5509, "Medium auxiliary memory not accessible"},
+	{0x550A, "Data currently unavailable"},
 
 	{0x5700, "Unable to recover table-of-contents"},
 
@@ -993,6 +1020,12 @@ static const struct error_info additional[] =
 	{0x5E02, "Standby condition activated by timer"},
 	{0x5E03, "Idle condition activated by command"},
 	{0x5E04, "Standby condition activated by command"},
+	{0x5E05, "Idle_b condition activated by timer"},
+	{0x5E06, "Idle_b condition activated by command"},
+	{0x5E07, "Idle_c condition activated by timer"},
+	{0x5E08, "Idle_c condition activated by command"},
+	{0x5E09, "Standby_y condition activated by timer"},
+	{0x5E0A, "Standby_y condition activated by command"},
 	{0x5E41, "Power state change to active"},
 	{0x5E42, "Power state change to idle"},
 	{0x5E43, "Power state change to standby"},
@@ -1091,7 +1124,28 @@ static const struct error_info additional[] =
 	{0x7403, "Incorrect data encryption key"},
 	{0x7404, "Cryptographic integrity validation failed"},
 	{0x7405, "Error decrypting data"},
+	{0x7406, "Unknown signature verification key"},
+	{0x7407, "Encryption parameters not useable"},
+	{0x7408, "Digital signature validation failure"},
+	{0x7409, "Encryption mode mismatch on read"},
+	{0x740A, "Encrypted block not raw read enabled"},
+	{0x740B, "Incorrect Encryption parameters"},
+	{0x740C, "Unable to decrypt parameter list"},
+	{0x740D, "Encryption algorithm disabled"},
+	{0x7410, "SA creation parameter value invalid"},
+	{0x7411, "SA creation parameter value rejected"},
+	{0x7412, "Invalid SA usage"},
+	{0x7421, "Data Encryption configuration prevented"},
+	{0x7430, "SA creation parameter not supported"},
+	{0x7440, "Authentication failed"},
+	{0x7461, "External data encryption key manager access error"},
+	{0x7462, "External data encryption key manager error"},
+	{0x7463, "External data encryption key not found"},
+	{0x7464, "External data encryption request not authorized"},
+	{0x746E, "External data encryption control timeout"},
+	{0x746F, "External data encryption control error"},
 	{0x7471, "Logical unit access not authorized"},
+	{0x7479, "Security conflict in translated device"},
 
 	{0, NULL}
 };
@@ -1103,12 +1157,12 @@ struct error_info2 {
 
 static const struct error_info2 additional2[] =
 {
-	{0x40,0x00,0x7f,"Ram failure (%x)"},
-	{0x40,0x80,0xff,"Diagnostic failure on component (%x)"},
-	{0x41,0x00,0xff,"Data path failure (%x)"},
-	{0x42,0x00,0xff,"Power-on or self-test failure (%x)"},
-	{0x4D,0x00,0xff,"Tagged overlapped commands (queue tag %x)"},
-	{0x70,0x00,0xff,"Decompression exception short algorithm id of %x"},
+	{0x40, 0x00, 0x7f, "Ram failure (%x)"},
+	{0x40, 0x80, 0xff, "Diagnostic failure on component (%x)"},
+	{0x41, 0x00, 0xff, "Data path failure (%x)"},
+	{0x42, 0x00, 0xff, "Power-on or self-test failure (%x)"},
+	{0x4D, 0x00, 0xff, "Tagged overlapped commands (task tag %x)"},
+	{0x70, 0x00, 0xff, "Decompression exception short algorithm id of %x"},
 	{0, 0, 0, NULL}
 };
 
@@ -1157,14 +1211,15 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq) {
 	int i;
 	unsigned short code = ((asc << 8) | ascq);
 
-	for (i=0; additional[i].text; i++)
+	for (i = 0; additional[i].text; i++)
 		if (additional[i].code12 == code)
 			return additional[i].text;
-	for (i=0; additional2[i].fmt; i++)
+	for (i = 0; additional2[i].fmt; i++) {
 		if (additional2[i].code1 == asc &&
-		    additional2[i].code2_min >= ascq &&
-		    additional2[i].code2_max <= ascq)
+		    ascq >= additional2[i].code2_min &&
+		    ascq <= additional2[i].code2_max)
 			return additional2[i].fmt;
+	}
 #endif
 	return NULL;
 }
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c
index a518f2e..3ee1cbc 100644
--- a/drivers/scsi/device_handler/scsi_dh.c
+++ b/drivers/scsi/device_handler/scsi_dh.c
@@ -153,12 +153,24 @@ static int scsi_dh_handler_attach(struct scsi_device *sdev,
 	if (sdev->scsi_dh_data) {
 		if (sdev->scsi_dh_data->scsi_dh != scsi_dh)
 			err = -EBUSY;
-	} else if (scsi_dh->attach)
+		else
+			kref_get(&sdev->scsi_dh_data->kref);
+	} else if (scsi_dh->attach) {
 		err = scsi_dh->attach(sdev);
-
+		if (!err) {
+			kref_init(&sdev->scsi_dh_data->kref);
+			sdev->scsi_dh_data->sdev = sdev;
+		}
+	}
 	return err;
 }
 
+static void __detach_handler (struct kref *kref)
+{
+	struct scsi_dh_data *scsi_dh_data = container_of(kref, struct scsi_dh_data, kref);
+	scsi_dh_data->scsi_dh->detach(scsi_dh_data->sdev);
+}
+
 /*
  * scsi_dh_handler_detach - Detach a device handler from a device
  * @sdev - SCSI device the device handler should be detached from
@@ -180,7 +192,7 @@ static void scsi_dh_handler_detach(struct scsi_device *sdev,
 		scsi_dh = sdev->scsi_dh_data->scsi_dh;
 
 	if (scsi_dh && scsi_dh->detach)
-		scsi_dh->detach(sdev);
+		kref_put(&sdev->scsi_dh_data->kref, __detach_handler);
 }
 
 /*
@@ -440,6 +452,39 @@ int scsi_dh_activate(struct request_queue *q)
 EXPORT_SYMBOL_GPL(scsi_dh_activate);
 
 /*
+ * scsi_dh_set_params - set the parameters for the device as per the
+ *      string specified in params.
+ * @q - Request queue that is associated with the scsi_device for
+ *      which the parameters to be set.
+ * @params - parameters in the following format
+ *      "no_of_params\0param1\0param2\0param3\0...\0"
+ *      for example, string for 2 parameters with value 10 and 21
+ *      is specified as "2\010\021\0".
+ */
+int scsi_dh_set_params(struct request_queue *q, const char *params)
+{
+	int err = -SCSI_DH_NOSYS;
+	unsigned long flags;
+	struct scsi_device *sdev;
+	struct scsi_device_handler *scsi_dh = NULL;
+
+	spin_lock_irqsave(q->queue_lock, flags);
+	sdev = q->queuedata;
+	if (sdev && sdev->scsi_dh_data)
+		scsi_dh = sdev->scsi_dh_data->scsi_dh;
+	if (scsi_dh && scsi_dh->set_params && get_device(&sdev->sdev_gendev))
+		err = 0;
+	spin_unlock_irqrestore(q->queue_lock, flags);
+
+	if (err)
+		return err;
+	err = scsi_dh->set_params(sdev, params);
+	put_device(&sdev->sdev_gendev);
+	return err;
+}
+EXPORT_SYMBOL_GPL(scsi_dh_set_params);
+
+/*
  * scsi_dh_handler_exist - Return TRUE(1) if a device handler exists for
  *	the given name. FALSE(0) otherwise.
  * @name - name of the device handler.
@@ -474,7 +519,6 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
 
 	if (!err) {
 		err = scsi_dh_handler_attach(sdev, scsi_dh);
-
 		put_device(&sdev->sdev_gendev);
 	}
 	return err;
@@ -505,10 +549,8 @@ void scsi_dh_detach(struct request_queue *q)
 		return;
 
 	if (sdev->scsi_dh_data) {
-		/* if sdev is not on internal list, detach */
 		scsi_dh = sdev->scsi_dh_data->scsi_dh;
-		if (!device_handler_match(scsi_dh, sdev))
-			scsi_dh_handler_detach(sdev, scsi_dh);
+		scsi_dh_handler_detach(sdev, scsi_dh);
 	}
 	put_device(&sdev->sdev_gendev);
 }
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index dba154c..b5cdefa 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -663,7 +663,7 @@ static int alua_activate(struct scsi_device *sdev)
 			goto out;
 	}
 
-	if (h->tpgs == TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED)
+	if (h->tpgs & TPGS_MODE_EXPLICIT && h->state != TPGS_STATE_OPTIMIZED)
 		err = alua_stpg(sdev, TPGS_STATE_OPTIMIZED, h);
 
 out:
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 0e572d2..0cffe84 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -561,6 +561,61 @@ done:
 
 	return result;
 }
+/*
+ * params - parameters in the following format
+ *      "no_of_params\0param1\0param2\0param3\0...\0"
+ *      for example, string for 2 parameters with value 10 and 21
+ *      is specified as "2\010\021\0".
+ */
+static int clariion_set_params(struct scsi_device *sdev, const char *params)
+{
+	struct clariion_dh_data *csdev = get_clariion_data(sdev);
+	unsigned int hr = 0, st = 0, argc;
+	const char *p = params;
+	int result = SCSI_DH_OK;
+
+	if ((sscanf(params, "%u", &argc) != 1) || (argc != 2))
+		return -EINVAL;
+
+	while (*p++)
+		;
+	if ((sscanf(p, "%u", &st) != 1) || (st > 1))
+		return -EINVAL;
+
+	while (*p++)
+		;
+	if ((sscanf(p, "%u", &hr) != 1) || (hr > 1))
+		return -EINVAL;
+
+	if (st)
+		csdev->flags |= CLARIION_SHORT_TRESPASS;
+	else
+		csdev->flags &= ~CLARIION_SHORT_TRESPASS;
+
+	if (hr)
+		csdev->flags |= CLARIION_HONOR_RESERVATIONS;
+	else
+		csdev->flags &= ~CLARIION_HONOR_RESERVATIONS;
+
+	/*
+	 * If this path is owned, we have to send a trespass command
+	 * with the new parameters. If not, simply return. Next trespass
+	 * command would use the parameters.
+	 */
+	if (csdev->lun_state != CLARIION_LUN_OWNED)
+		goto done;
+
+	csdev->lun_state = CLARIION_LUN_UNINITIALIZED;
+	result = send_trespass_cmd(sdev, csdev);
+	if (result != SCSI_DH_OK)
+		goto done;
+
+	/* Update status */
+	result = clariion_send_inquiry(sdev, csdev);
+
+done:
+	return result;
+}
 
 static const struct scsi_dh_devlist clariion_dev_list[] = {
 	{"DGC", "RAID"},
@@ -581,11 +636,9 @@ static struct scsi_device_handler clariion_dh = {
 	.check_sense	= clariion_check_sense,
 	.activate	= clariion_activate,
 	.prep_fn	= clariion_prep_fn,
+	.set_params	= clariion_set_params,
 };
 
-/*
- * TODO: need some interface so we can set trespass values
- */
 static int clariion_bus_attach(struct scsi_device *sdev)
 {
 	struct scsi_dh_data *scsi_dh_data;
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index fd0544f..11c8931 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -112,6 +112,7 @@ struct c9_inquiry {
 
 #define SUBSYS_ID_LEN	16
 #define SLOT_ID_LEN	2
+#define ARRAY_LABEL_LEN	31
 
 struct c4_inquiry {
 	u8	peripheral_info;
@@ -135,6 +136,8 @@ struct rdac_controller {
 		struct rdac_pg_legacy legacy;
 		struct rdac_pg_expanded expanded;
 	} mode_select;
+	u8	index;
+	u8	array_name[ARRAY_LABEL_LEN];
 };
 struct c8_inquiry {
 	u8	peripheral_info;
@@ -198,6 +201,31 @@ static const char *lun_state[] =
 static LIST_HEAD(ctlr_list);
 static DEFINE_SPINLOCK(list_lock);
 
+/*
+ * module parameter to enable rdac debug logging.
+ * 2 bits for each type of logging, only two types defined for now
+ * Can be enhanced if required at later point
+ */
+static int rdac_logging = 1;
+module_param(rdac_logging, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(rdac_logging, "A bit mask of rdac logging levels, "
+		"Default is 1 - failover logging enabled, "
+		"set it to 0xF to enable all the logs");
+
+#define RDAC_LOG_FAILOVER	0
+#define RDAC_LOG_SENSE		2
+
+#define RDAC_LOG_BITS		2
+
+#define RDAC_LOG_LEVEL(SHIFT)  \
+	((rdac_logging >> (SHIFT)) & ((1 << (RDAC_LOG_BITS)) - 1))
+
+#define RDAC_LOG(SHIFT, sdev, f, arg...) \
+do { \
+	if (unlikely(RDAC_LOG_LEVEL(SHIFT))) \
+		sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \
+} while (0);
+
 static inline struct rdac_dh_data *get_rdac_data(struct scsi_device *sdev)
 {
 	struct scsi_dh_data *scsi_dh_data = sdev->scsi_dh_data;
@@ -303,7 +331,8 @@ static void release_controller(struct kref *kref)
 	kfree(ctlr);
 }
 
-static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id)
+static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id,
+						char *array_name)
 {
 	struct rdac_controller *ctlr, *tmp;
 
@@ -324,6 +353,14 @@ static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id)
 	/* initialize fields of controller */
 	memcpy(ctlr->subsys_id, subsys_id, SUBSYS_ID_LEN);
 	memcpy(ctlr->slot_id, slot_id, SLOT_ID_LEN);
+	memcpy(ctlr->array_name, array_name, ARRAY_LABEL_LEN);
+
+	/* update the controller index */
+	if (slot_id[1] == 0x31)
+		ctlr->index = 0;
+	else
+		ctlr->index = 1;
+
 	kref_init(&ctlr->kref);
 	ctlr->use_ms10 = -1;
 	list_add(&ctlr->node, &ctlr_list);
@@ -363,9 +400,10 @@ done:
 	return err;
 }
 
-static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h)
+static int get_lun_info(struct scsi_device *sdev, struct rdac_dh_data *h,
+			char *array_name)
 {
-	int err;
+	int err, i;
 	struct c8_inquiry *inqp;
 
 	err = submit_inquiry(sdev, 0xC8, sizeof(struct c8_inquiry), h);
@@ -377,6 +415,11 @@ static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h)
 		    inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd')
 			return SCSI_DH_NOSYS;
 		h->lun = inqp->lun[7]; /* Uses only the last byte */
+
+		for(i=0; i<ARRAY_LABEL_LEN-1; ++i)
+			*(array_name+i) = inqp->array_user_label[(2*i)+1];
+
+		*(array_name+ARRAY_LABEL_LEN-1) = '\0';
 	}
 	return err;
 }
@@ -410,7 +453,7 @@ static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
 }
 
 static int initialize_controller(struct scsi_device *sdev,
-				 struct rdac_dh_data *h)
+				 struct rdac_dh_data *h, char *array_name)
 {
 	int err;
 	struct c4_inquiry *inqp;
@@ -418,7 +461,8 @@ static int initialize_controller(struct scsi_device *sdev,
 	err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h);
 	if (err == SCSI_DH_OK) {
 		inqp = &h->inq.c4;
-		h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id);
+		h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id,
+					array_name);
 		if (!h->ctlr)
 			err = SCSI_DH_RES_TEMP_UNAVAIL;
 	}
@@ -450,6 +494,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
 {
 	struct scsi_sense_hdr sense_hdr;
 	int err = SCSI_DH_IO, ret;
+	struct rdac_dh_data *h = get_rdac_data(sdev);
 
 	ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
 	if (!ret)
@@ -478,11 +523,14 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
 			err = SCSI_DH_RETRY;
 		break;
 	default:
-		sdev_printk(KERN_INFO, sdev,
-			    "MODE_SELECT failed with sense %02x/%02x/%02x.\n",
-			    sense_hdr.sense_key, sense_hdr.asc, sense_hdr.ascq);
+		break;
 	}
 
+	RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
+		"MODE_SELECT returned with sense %02x/%02x/%02x",
+		(char *) h->ctlr->array_name, h->ctlr->index,
+		sense_hdr.sense_key, sense_hdr.asc, sense_hdr.ascq);
+
 done:
 	return err;
 }
@@ -499,7 +547,9 @@ retry:
 	if (!rq)
 		goto done;
 
-	sdev_printk(KERN_INFO, sdev, "%s MODE_SELECT command.\n",
+	RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
+		"%s MODE_SELECT command",
+		(char *) h->ctlr->array_name, h->ctlr->index,
 		(retry_cnt == RDAC_RETRY_COUNT) ? "queueing" : "retrying");
 
 	err = blk_execute_rq(q, NULL, rq, 1);
@@ -509,8 +559,12 @@ retry:
 		if (err == SCSI_DH_RETRY && retry_cnt--)
 			goto retry;
 	}
-	if (err == SCSI_DH_OK)
+	if (err == SCSI_DH_OK) {
 		h->state = RDAC_STATE_ACTIVE;
+		RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
+				"MODE_SELECT completed",
+				(char *) h->ctlr->array_name, h->ctlr->index);
+	}
 
 done:
 	return err;
@@ -525,17 +579,6 @@ static int rdac_activate(struct scsi_device *sdev)
 	if (err != SCSI_DH_OK)
 		goto done;
 
-	if (!h->ctlr) {
-		err = initialize_controller(sdev, h);
-		if (err != SCSI_DH_OK)
-			goto done;
-	}
-
-	if (h->ctlr->use_ms10 == -1) {
-		err = set_mode_select(sdev, h);
-		if (err != SCSI_DH_OK)
-			goto done;
-	}
 	if (h->lun_state == RDAC_LUN_UNOWNED)
 		err = send_mode_select(sdev, h);
 done:
@@ -559,6 +602,12 @@ static int rdac_check_sense(struct scsi_device *sdev,
 				struct scsi_sense_hdr *sense_hdr)
 {
 	struct rdac_dh_data *h = get_rdac_data(sdev);
+
+	RDAC_LOG(RDAC_LOG_SENSE, sdev, "array %s, ctlr %d, "
+			"I/O returned with sense %02x/%02x/%02x",
+			(char *) h->ctlr->array_name, h->ctlr->index,
+			sense_hdr->sense_key, sense_hdr->asc, sense_hdr->ascq);
+
 	switch (sense_hdr->sense_key) {
 	case NOT_READY:
 		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x01)
@@ -628,11 +677,18 @@ static const struct scsi_dh_devlist rdac_dev_list[] = {
 	{"SGI", "IS"},
 	{"STK", "OPENstorage D280"},
 	{"SUN", "CSM200_R"},
+	{"SUN", "LCSM100_I"},
+	{"SUN", "LCSM100_S"},
+	{"SUN", "LCSM100_E"},
 	{"SUN", "LCSM100_F"},
 	{"DELL", "MD3000"},
 	{"DELL", "MD3000i"},
+	{"DELL", "MD32xx"},
+	{"DELL", "MD32xxi"},
 	{"LSI", "INF-01-00"},
 	{"ENGENIO", "INF-01-00"},
+	{"STK", "FLEXLINE 380"},
+	{"SUN", "CSM100_R_FC"},
 	{NULL, NULL},
 };
 
@@ -656,6 +712,7 @@ static int rdac_bus_attach(struct scsi_device *sdev)
 	struct rdac_dh_data *h;
 	unsigned long flags;
 	int err;
+	char array_name[ARRAY_LABEL_LEN];
 
 	scsi_dh_data = kzalloc(sizeof(struct scsi_device_handler *)
 			       + sizeof(*h) , GFP_KERNEL);
@@ -670,16 +727,24 @@ static int rdac_bus_attach(struct scsi_device *sdev)
 	h->lun = UNINITIALIZED_LUN;
 	h->state = RDAC_STATE_ACTIVE;
 
-	err = get_lun(sdev, h);
+	err = get_lun_info(sdev, h, array_name);
 	if (err != SCSI_DH_OK)
 		goto failed;
 
-	err = check_ownership(sdev, h);
+	err = initialize_controller(sdev, h, array_name);
 	if (err != SCSI_DH_OK)
 		goto failed;
 
+	err = check_ownership(sdev, h);
+	if (err != SCSI_DH_OK)
+		goto clean_ctlr;
+
+	err = set_mode_select(sdev, h);
+	if (err != SCSI_DH_OK)
+		goto clean_ctlr;
+
 	if (!try_module_get(THIS_MODULE))
-		goto failed;
+		goto clean_ctlr;
 
 	spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
 	sdev->scsi_dh_data = scsi_dh_data;
@@ -691,6 +756,9 @@ static int rdac_bus_attach(struct scsi_device *sdev)
 
 	return 0;
 
+clean_ctlr:
+	kref_put(&h->ctlr->kref, release_controller);
+
 failed:
 	kfree(scsi_dh_data);
 	sdev_printk(KERN_ERR, sdev, "%s: not attached\n",
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 0a5609b..704b8e0 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -49,9 +49,20 @@ MODULE_AUTHOR("Open-FCoE.org");
 MODULE_DESCRIPTION("FCoE");
 MODULE_LICENSE("GPL v2");
 
+/* Performance tuning parameters for fcoe */
+static unsigned int fcoe_ddp_min;
+module_param_named(ddp_min, fcoe_ddp_min, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ddp_min, "Minimum I/O size in bytes for "	\
+		 "Direct Data Placement (DDP).");
+
+DEFINE_MUTEX(fcoe_config_mutex);
+
+/* fcoe_percpu_clean completion.  Waiter protected by fcoe_create_mutex */
+static DECLARE_COMPLETION(fcoe_flush_completion);
+
 /* fcoe host list */
+/* must only by accessed under the RTNL mutex */
 LIST_HEAD(fcoe_hostlist);
-DEFINE_RWLOCK(fcoe_hostlist_lock);
 DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
 
 /* Function Prototypes */
@@ -66,12 +77,13 @@ static int fcoe_link_ok(struct fc_lport *lp);
 
 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
 static int fcoe_hostlist_add(const struct fc_lport *);
-static int fcoe_hostlist_remove(const struct fc_lport *);
 
 static void fcoe_check_wait_queue(struct fc_lport *, struct sk_buff *);
 static int fcoe_device_notification(struct notifier_block *, ulong, void *);
 static void fcoe_dev_setup(void);
 static void fcoe_dev_cleanup(void);
+static struct fcoe_interface *
+	fcoe_hostlist_lookup_port(const struct net_device *dev);
 
 /* notification function from net device */
 static struct notifier_block fcoe_notifier = {
@@ -132,6 +144,180 @@ static struct scsi_host_template fcoe_shost_template = {
 	.max_sectors = 0xffff,
 };
 
+static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
+			 struct packet_type *ptype,
+			 struct net_device *orig_dev);
+/**
+ * fcoe_interface_setup()
+ * @fcoe: new fcoe_interface
+ * @netdev : ptr to the associated netdevice struct
+ *
+ * Returns : 0 for success
+ * Locking: must be called with the RTNL mutex held
+ */
+static int fcoe_interface_setup(struct fcoe_interface *fcoe,
+				struct net_device *netdev)
+{
+	struct fcoe_ctlr *fip = &fcoe->ctlr;
+	struct netdev_hw_addr *ha;
+	u8 flogi_maddr[ETH_ALEN];
+
+	fcoe->netdev = netdev;
+
+	/* Do not support for bonding device */
+	if ((netdev->priv_flags & IFF_MASTER_ALB) ||
+	    (netdev->priv_flags & IFF_SLAVE_INACTIVE) ||
+	    (netdev->priv_flags & IFF_MASTER_8023AD)) {
+		return -EOPNOTSUPP;
+	}
+
+	/* look for SAN MAC address, if multiple SAN MACs exist, only
+	 * use the first one for SPMA */
+	rcu_read_lock();
+	for_each_dev_addr(netdev, ha) {
+		if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
+		    (is_valid_ether_addr(fip->ctl_src_addr))) {
+			memcpy(fip->ctl_src_addr, ha->addr, ETH_ALEN);
+			fip->spma = 1;
+			break;
+		}
+	}
+	rcu_read_unlock();
+
+	/* setup Source Mac Address */
+	if (!fip->spma)
+		memcpy(fip->ctl_src_addr, netdev->dev_addr, netdev->addr_len);
+
+	/*
+	 * Add FCoE MAC address as second unicast MAC address
+	 * or enter promiscuous mode if not capable of listening
+	 * for multiple unicast MACs.
+	 */
+	memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
+	dev_unicast_add(netdev, flogi_maddr);
+	if (fip->spma)
+		dev_unicast_add(netdev, fip->ctl_src_addr);
+	dev_mc_add(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+
+	/*
+	 * setup the receive function from ethernet driver
+	 * on the ethertype for the given device
+	 */
+	fcoe->fcoe_packet_type.func = fcoe_rcv;
+	fcoe->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
+	fcoe->fcoe_packet_type.dev = netdev;
+	dev_add_pack(&fcoe->fcoe_packet_type);
+
+	fcoe->fip_packet_type.func = fcoe_fip_recv;
+	fcoe->fip_packet_type.type = htons(ETH_P_FIP);
+	fcoe->fip_packet_type.dev = netdev;
+	dev_add_pack(&fcoe->fip_packet_type);
+
+	return 0;
+}
+
+static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb);
+static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new);
+static void fcoe_destroy_work(struct work_struct *work);
+
+/**
+ * fcoe_interface_create()
+ * @netdev: network interface
+ *
+ * Returns: pointer to a struct fcoe_interface or NULL on error
+ */
+static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev)
+{
+	struct fcoe_interface *fcoe;
+
+	fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL);
+	if (!fcoe) {
+		FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n");
+		return NULL;
+	}
+
+	dev_hold(netdev);
+	kref_init(&fcoe->kref);
+
+	/*
+	 * Initialize FIP.
+	 */
+	fcoe_ctlr_init(&fcoe->ctlr);
+	fcoe->ctlr.send = fcoe_fip_send;
+	fcoe->ctlr.update_mac = fcoe_update_src_mac;
+
+	fcoe_interface_setup(fcoe, netdev);
+
+	return fcoe;
+}
+
+/**
+ * fcoe_interface_cleanup() - clean up netdev configurations
+ * @fcoe:
+ *
+ * Caller must be holding the RTNL mutex
+ */
+void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
+{
+	struct net_device *netdev = fcoe->netdev;
+	struct fcoe_ctlr *fip = &fcoe->ctlr;
+	u8 flogi_maddr[ETH_ALEN];
+
+	/*
+	 * Don't listen for Ethernet packets anymore.
+	 * synchronize_net() ensures that the packet handlers are not running
+	 * on another CPU. dev_remove_pack() would do that, this calls the
+	 * unsyncronized version __dev_remove_pack() to avoid multiple delays.
+	 */
+	__dev_remove_pack(&fcoe->fcoe_packet_type);
+	__dev_remove_pack(&fcoe->fip_packet_type);
+	synchronize_net();
+
+	/* Delete secondary MAC addresses */
+	memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
+	dev_unicast_delete(netdev, flogi_maddr);
+	if (!is_zero_ether_addr(fip->data_src_addr))
+		dev_unicast_delete(netdev, fip->data_src_addr);
+	if (fip->spma)
+		dev_unicast_delete(netdev, fip->ctl_src_addr);
+	dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+}
+
+/**
+ * fcoe_interface_release() - fcoe_port kref release function
+ * @kref: embedded reference count in an fcoe_interface struct
+ */
+static void fcoe_interface_release(struct kref *kref)
+{
+	struct fcoe_interface *fcoe;
+	struct net_device *netdev;
+
+	fcoe = container_of(kref, struct fcoe_interface, kref);
+	netdev = fcoe->netdev;
+	/* tear-down the FCoE controller */
+	fcoe_ctlr_destroy(&fcoe->ctlr);
+	kfree(fcoe);
+	dev_put(netdev);
+}
+
+/**
+ * fcoe_interface_get()
+ * @fcoe:
+ */
+static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
+{
+	kref_get(&fcoe->kref);
+}
+
+/**
+ * fcoe_interface_put()
+ * @fcoe:
+ */
+static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
+{
+	kref_put(&fcoe->kref, fcoe_interface_release);
+}
+
 /**
  * fcoe_fip_recv - handle a received FIP frame.
  * @skb: the receive skb
@@ -145,10 +331,10 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
 			 struct packet_type *ptype,
 			 struct net_device *orig_dev)
 {
-	struct fcoe_softc *fc;
+	struct fcoe_interface *fcoe;
 
-	fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
-	fcoe_ctlr_recv(&fc->ctlr, skb);
+	fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type);
+	fcoe_ctlr_recv(&fcoe->ctlr, skb);
 	return 0;
 }
 
@@ -159,7 +345,7 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
  */
 static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
 {
-	skb->dev = fcoe_from_ctlr(fip)->real_dev;
+	skb->dev = fcoe_from_ctlr(fip)->netdev;
 	dev_queue_xmit(skb);
 }
 
@@ -174,13 +360,13 @@ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
  */
 static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
 {
-	struct fcoe_softc *fc;
+	struct fcoe_interface *fcoe;
 
-	fc = fcoe_from_ctlr(fip);
+	fcoe = fcoe_from_ctlr(fip);
 	rtnl_lock();
 	if (!is_zero_ether_addr(old))
-		dev_unicast_delete(fc->real_dev, old);
-	dev_unicast_add(fc->real_dev, new);
+		dev_unicast_delete(fcoe->netdev, old);
+	dev_unicast_add(fcoe->netdev, new);
 	rtnl_unlock();
 }
 
@@ -217,30 +403,6 @@ static int fcoe_lport_config(struct fc_lport *lp)
 }
 
 /**
- * fcoe_netdev_cleanup() - clean up netdev configurations
- * @fc: ptr to the fcoe_softc
- */
-void fcoe_netdev_cleanup(struct fcoe_softc *fc)
-{
-	u8 flogi_maddr[ETH_ALEN];
-
-	/* Don't listen for Ethernet packets anymore */
-	dev_remove_pack(&fc->fcoe_packet_type);
-	dev_remove_pack(&fc->fip_packet_type);
-
-	/* Delete secondary MAC addresses */
-	rtnl_lock();
-	memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
-	dev_unicast_delete(fc->real_dev, flogi_maddr);
-	if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
-		dev_unicast_delete(fc->real_dev, fc->ctlr.data_src_addr);
-	if (fc->ctlr.spma)
-		dev_unicast_delete(fc->real_dev, fc->ctlr.ctl_src_addr);
-	dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
-	rtnl_unlock();
-}
-
-/**
  * fcoe_queue_timer() - fcoe queue timer
  * @lp: the fc_lport pointer
  *
@@ -265,116 +427,53 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
 {
 	u32 mfs;
 	u64 wwnn, wwpn;
-	struct fcoe_softc *fc;
-	u8 flogi_maddr[ETH_ALEN];
-	struct netdev_hw_addr *ha;
+	struct fcoe_interface *fcoe;
+	struct fcoe_port *port;
 
 	/* Setup lport private data to point to fcoe softc */
-	fc = lport_priv(lp);
-	fc->ctlr.lp = lp;
-	fc->real_dev = netdev;
-	fc->phys_dev = netdev;
-
-	/* Require support for get_pauseparam ethtool op. */
-	if (netdev->priv_flags & IFF_802_1Q_VLAN)
-		fc->phys_dev = vlan_dev_real_dev(netdev);
-
-	/* Do not support for bonding device */
-	if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
-	    (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
-	    (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
-		return -EOPNOTSUPP;
-	}
+	port = lport_priv(lp);
+	fcoe = port->fcoe;
 
 	/*
 	 * Determine max frame size based on underlying device and optional
 	 * user-configured limit.  If the MFS is too low, fcoe_link_ok()
 	 * will return 0, so do this first.
 	 */
-	mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
-				   sizeof(struct fcoe_crc_eof));
+	mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
+			     sizeof(struct fcoe_crc_eof));
 	if (fc_set_mfs(lp, mfs))
 		return -EINVAL;
 
 	/* offload features support */
-	if (fc->real_dev->features & NETIF_F_SG)
+	if (netdev->features & NETIF_F_SG)
 		lp->sg_supp = 1;
 
-#ifdef NETIF_F_FCOE_CRC
 	if (netdev->features & NETIF_F_FCOE_CRC) {
 		lp->crc_offload = 1;
 		FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n");
 	}
-#endif
-#ifdef NETIF_F_FSO
 	if (netdev->features & NETIF_F_FSO) {
 		lp->seq_offload = 1;
 		lp->lso_max = netdev->gso_max_size;
 		FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n",
 				lp->lso_max);
 	}
-#endif
 	if (netdev->fcoe_ddp_xid) {
 		lp->lro_enabled = 1;
 		lp->lro_xid = netdev->fcoe_ddp_xid;
 		FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n",
 				lp->lro_xid);
 	}
-	skb_queue_head_init(&fc->fcoe_pending_queue);
-	fc->fcoe_pending_queue_active = 0;
-	setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp);
-
-	/* look for SAN MAC address, if multiple SAN MACs exist, only
-	 * use the first one for SPMA */
-	rcu_read_lock();
-	for_each_dev_addr(netdev, ha) {
-		if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
-		    (is_valid_ether_addr(fc->ctlr.ctl_src_addr))) {
-			memcpy(fc->ctlr.ctl_src_addr, ha->addr, ETH_ALEN);
-			fc->ctlr.spma = 1;
-			break;
-		}
-	}
-	rcu_read_unlock();
-
-	/* setup Source Mac Address */
-	if (!fc->ctlr.spma)
-		memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
-		       fc->real_dev->addr_len);
+	skb_queue_head_init(&port->fcoe_pending_queue);
+	port->fcoe_pending_queue_active = 0;
+	setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lp);
 
-	wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
+	wwnn = fcoe_wwn_from_mac(netdev->dev_addr, 1, 0);
 	fc_set_wwnn(lp, wwnn);
 	/* XXX - 3rd arg needs to be vlan id */
-	wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
+	wwpn = fcoe_wwn_from_mac(netdev->dev_addr, 2, 0);
 	fc_set_wwpn(lp, wwpn);
 
-	/*
-	 * Add FCoE MAC address as second unicast MAC address
-	 * or enter promiscuous mode if not capable of listening
-	 * for multiple unicast MACs.
-	 */
-	rtnl_lock();
-	memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
-	dev_unicast_add(fc->real_dev, flogi_maddr);
-	if (fc->ctlr.spma)
-		dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr);
-	dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
-	rtnl_unlock();
-
-	/*
-	 * setup the receive function from ethernet driver
-	 * on the ethertype for the given device
-	 */
-	fc->fcoe_packet_type.func = fcoe_rcv;
-	fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
-	fc->fcoe_packet_type.dev = fc->real_dev;
-	dev_add_pack(&fc->fcoe_packet_type);
-
-	fc->fip_packet_type.func = fcoe_fip_recv;
-	fc->fip_packet_type.type = htons(ETH_P_FIP);
-	fc->fip_packet_type.dev = fc->real_dev;
-	dev_add_pack(&fc->fip_packet_type);
-
 	return 0;
 }
 
@@ -415,86 +514,140 @@ static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
 	return 0;
 }
 
+/*
+ * fcoe_oem_match() - match for read types IO
+ * @fp: the fc_frame for new IO.
+ *
+ * Returns : true for read types IO, otherwise returns false.
+ */
+bool fcoe_oem_match(struct fc_frame *fp)
+{
+	return fc_fcp_is_read(fr_fsp(fp)) &&
+		(fr_fsp(fp)->data_len > fcoe_ddp_min);
+}
+
 /**
  * fcoe_em_config() - allocates em for this lport
- * @lp: the port that em is to allocated for
+ * @lp: the fcoe that em is to allocated for
  *
  * Returns : 0 on success
  */
 static inline int fcoe_em_config(struct fc_lport *lp)
 {
-	BUG_ON(lp->emp);
+	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_interface *fcoe = port->fcoe;
+	struct fcoe_interface *oldfcoe = NULL;
+	struct net_device *old_real_dev, *cur_real_dev;
+	u16 min_xid = FCOE_MIN_XID;
+	u16 max_xid = FCOE_MAX_XID;
 
-	lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
-				    FCOE_MIN_XID, FCOE_MAX_XID);
-	if (!lp->emp)
+	/*
+	 * Check if need to allocate an em instance for
+	 * offload exchange ids to be shared across all VN_PORTs/lport.
+	 */
+	if (!lp->lro_enabled || !lp->lro_xid || (lp->lro_xid >= max_xid)) {
+		lp->lro_xid = 0;
+		goto skip_oem;
+	}
+
+	/*
+	 * Reuse existing offload em instance in case
+	 * it is already allocated on real eth device
+	 */
+	if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN)
+		cur_real_dev = vlan_dev_real_dev(fcoe->netdev);
+	else
+		cur_real_dev = fcoe->netdev;
+
+	list_for_each_entry(oldfcoe, &fcoe_hostlist, list) {
+		if (oldfcoe->netdev->priv_flags & IFF_802_1Q_VLAN)
+			old_real_dev = vlan_dev_real_dev(oldfcoe->netdev);
+		else
+			old_real_dev = oldfcoe->netdev;
+
+		if (cur_real_dev == old_real_dev) {
+			fcoe->oem = oldfcoe->oem;
+			break;
+		}
+	}
+
+	if (fcoe->oem) {
+		if (!fc_exch_mgr_add(lp, fcoe->oem, fcoe_oem_match)) {
+			printk(KERN_ERR "fcoe_em_config: failed to add "
+			       "offload em:%p on interface:%s\n",
+			       fcoe->oem, fcoe->netdev->name);
+			return -ENOMEM;
+		}
+	} else {
+		fcoe->oem = fc_exch_mgr_alloc(lp, FC_CLASS_3,
+					    FCOE_MIN_XID, lp->lro_xid,
+					    fcoe_oem_match);
+		if (!fcoe->oem) {
+			printk(KERN_ERR "fcoe_em_config: failed to allocate "
+			       "em for offload exches on interface:%s\n",
+			       fcoe->netdev->name);
+			return -ENOMEM;
+		}
+	}
+
+	/*
+	 * Exclude offload EM xid range from next EM xid range.
+	 */
+	min_xid += lp->lro_xid + 1;
+
+skip_oem:
+	if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, min_xid, max_xid, NULL)) {
+		printk(KERN_ERR "fcoe_em_config: failed to "
+		       "allocate em on interface %s\n", fcoe->netdev->name);
 		return -ENOMEM;
+	}
 
 	return 0;
 }
 
 /**
  * fcoe_if_destroy() - FCoE software HBA tear-down function
- * @netdev: ptr to the associated net_device
- *
- * Returns: 0 if link is OK for use by FCoE.
+ * @lport: fc_lport to destroy
  */
-static int fcoe_if_destroy(struct net_device *netdev)
+static void fcoe_if_destroy(struct fc_lport *lport)
 {
-	struct fc_lport *lp = NULL;
-	struct fcoe_softc *fc;
-
-	BUG_ON(!netdev);
+	struct fcoe_port *port = lport_priv(lport);
+	struct fcoe_interface *fcoe = port->fcoe;
+	struct net_device *netdev = fcoe->netdev;
 
 	FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
 
-	lp = fcoe_hostlist_lookup(netdev);
-	if (!lp)
-		return -ENODEV;
-
-	fc = lport_priv(lp);
-
 	/* Logout of the fabric */
-	fc_fabric_logoff(lp);
+	fc_fabric_logoff(lport);
 
-	/* Remove the instance from fcoe's list */
-	fcoe_hostlist_remove(lp);
+	/* Cleanup the fc_lport */
+	fc_lport_destroy(lport);
+	fc_fcp_destroy(lport);
 
-	/* clean up netdev configurations */
-	fcoe_netdev_cleanup(fc);
+	/* Stop the transmit retry timer */
+	del_timer_sync(&port->timer);
 
-	/* tear-down the FCoE controller */
-	fcoe_ctlr_destroy(&fc->ctlr);
+	/* Free existing transmit skbs */
+	fcoe_clean_pending_queue(lport);
 
-	/* Cleanup the fc_lport */
-	fc_lport_destroy(lp);
-	fc_fcp_destroy(lp);
+	/* receives may not be stopped until after this */
+	fcoe_interface_put(fcoe);
+
+	/* Free queued packets for the per-CPU receive threads */
+	fcoe_percpu_clean(lport);
 
 	/* Detach from the scsi-ml */
-	fc_remove_host(lp->host);
-	scsi_remove_host(lp->host);
+	fc_remove_host(lport->host);
+	scsi_remove_host(lport->host);
 
 	/* There are no more rports or I/O, free the EM */
-	if (lp->emp)
-		fc_exch_mgr_free(lp->emp);
-
-	/* Free the per-CPU receive threads */
-	fcoe_percpu_clean(lp);
-
-	/* Free existing skbs */
-	fcoe_clean_pending_queue(lp);
-
-	/* Stop the timer */
-	del_timer_sync(&fc->timer);
+	fc_exch_mgr_free(lport);
 
 	/* Free memory used by statistical counters */
-	fc_lport_free_stats(lp);
-
-	/* Release the net_device and Scsi_Host */
-	dev_put(fc->real_dev);
-	scsi_host_put(lp->host);
+	fc_lport_free_stats(lport);
 
-	return 0;
+	/* Release the Scsi_Host */
+	scsi_host_put(lport->host);
 }
 
 /*
@@ -540,106 +693,96 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = {
 };
 
 /**
- * fcoe_if_create() - this function creates the fcoe interface
- * @netdev: pointer the associated netdevice
+ * fcoe_if_create() - this function creates the fcoe port
+ * @fcoe: fcoe_interface structure to create an fc_lport instance on
+ * @parent: device pointer to be the parent in sysfs for the SCSI host
  *
- * Creates fc_lport struct and scsi_host for lport, configures lport
- * and starts fabric login.
+ * Creates fc_lport struct and scsi_host for lport, configures lport.
  *
- * Returns : 0 on success
+ * Returns : The allocated fc_lport or an error pointer
  */
-static int fcoe_if_create(struct net_device *netdev)
+static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe,
+				       struct device *parent)
 {
 	int rc;
-	struct fc_lport *lp = NULL;
-	struct fcoe_softc *fc;
+	struct fc_lport *lport = NULL;
+	struct fcoe_port *port;
 	struct Scsi_Host *shost;
-
-	BUG_ON(!netdev);
+	struct net_device *netdev = fcoe->netdev;
 
 	FCOE_NETDEV_DBG(netdev, "Create Interface\n");
 
-	lp = fcoe_hostlist_lookup(netdev);
-	if (lp)
-		return -EEXIST;
-
 	shost = libfc_host_alloc(&fcoe_shost_template,
-				 sizeof(struct fcoe_softc));
+				 sizeof(struct fcoe_port));
 	if (!shost) {
 		FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
-	lp = shost_priv(shost);
-	fc = lport_priv(lp);
+	lport = shost_priv(shost);
+	port = lport_priv(lport);
+	port->lport = lport;
+	port->fcoe = fcoe;
+	INIT_WORK(&port->destroy_work, fcoe_destroy_work);
 
 	/* configure fc_lport, e.g., em */
-	rc = fcoe_lport_config(lp);
+	rc = fcoe_lport_config(lport);
 	if (rc) {
 		FCOE_NETDEV_DBG(netdev, "Could not configure lport for the "
 				"interface\n");
 		goto out_host_put;
 	}
 
-	/*
-	 * Initialize FIP.
-	 */
-	fcoe_ctlr_init(&fc->ctlr);
-	fc->ctlr.send = fcoe_fip_send;
-	fc->ctlr.update_mac = fcoe_update_src_mac;
-
 	/* configure lport network properties */
-	rc = fcoe_netdev_config(lp, netdev);
+	rc = fcoe_netdev_config(lport, netdev);
 	if (rc) {
 		FCOE_NETDEV_DBG(netdev, "Could not configure netdev for the "
 				"interface\n");
-		goto out_netdev_cleanup;
+		goto out_lp_destroy;
 	}
 
 	/* configure lport scsi host properties */
-	rc = fcoe_shost_config(lp, shost, &netdev->dev);
+	rc = fcoe_shost_config(lport, shost, parent);
 	if (rc) {
 		FCOE_NETDEV_DBG(netdev, "Could not configure shost for the "
 				"interface\n");
-		goto out_netdev_cleanup;
-	}
-
-	/* lport exch manager allocation */
-	rc = fcoe_em_config(lp);
-	if (rc) {
-		FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
-				"interface\n");
-		goto out_netdev_cleanup;
+		goto out_lp_destroy;
 	}
 
 	/* Initialize the library */
-	rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
+	rc = fcoe_libfc_config(lport, &fcoe_libfc_fcn_templ);
 	if (rc) {
 		FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the "
 				"interface\n");
 		goto out_lp_destroy;
 	}
 
-	/* add to lports list */
-	fcoe_hostlist_add(lp);
-
-	lp->boot_time = jiffies;
-
-	fc_fabric_login(lp);
-
-	if (!fcoe_link_ok(lp))
-		fcoe_ctlr_link_up(&fc->ctlr);
+	/*
+	 * fcoe_em_alloc() and fcoe_hostlist_add() both
+	 * need to be atomic with respect to other changes to the hostlist
+	 * since fcoe_em_alloc() looks for an existing EM
+	 * instance on host list updated by fcoe_hostlist_add().
+	 *
+	 * This is currently handled through the fcoe_config_mutex begin held.
+	 */
 
-	dev_hold(netdev);
+	/* lport exch manager allocation */
+	rc = fcoe_em_config(lport);
+	if (rc) {
+		FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the "
+				"interface\n");
+		goto out_lp_destroy;
+	}
 
-	return rc;
+	fcoe_interface_get(fcoe);
+	return lport;
 
 out_lp_destroy:
-	fc_exch_mgr_free(lp->emp); /* Free the EM */
-out_netdev_cleanup:
-	fcoe_netdev_cleanup(fc);
+	fc_exch_mgr_free(lport);
 out_host_put:
-	scsi_host_put(lp->host);
-	return rc;
+	scsi_host_put(lport->host);
+out:
+	return ERR_PTR(rc);
 }
 
 /**
@@ -669,6 +812,7 @@ static int __init fcoe_if_init(void)
 int __exit fcoe_if_exit(void)
 {
 	fc_release_transport(scsi_transport_fcoe_sw);
+	scsi_transport_fcoe_sw = NULL;
 	return 0;
 }
 
@@ -686,7 +830,7 @@ static void fcoe_percpu_thread_create(unsigned int cpu)
 	thread = kthread_create(fcoe_percpu_receive_thread,
 				(void *)p, "fcoethread/%d", cpu);
 
-	if (likely(!IS_ERR(p->thread))) {
+	if (likely(!IS_ERR(thread))) {
 		kthread_bind(thread, cpu);
 		wake_up_process(thread);
 
@@ -838,14 +982,13 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
 {
 	struct fc_lport *lp;
 	struct fcoe_rcv_info *fr;
-	struct fcoe_softc *fc;
+	struct fcoe_interface *fcoe;
 	struct fc_frame_header *fh;
 	struct fcoe_percpu_s *fps;
-	unsigned short oxid;
-	unsigned int cpu = 0;
+	unsigned int cpu;
 
-	fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
-	lp = fc->ctlr.lp;
+	fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type);
+	lp = fcoe->ctlr.lp;
 	if (unlikely(lp == NULL)) {
 		FCOE_NETDEV_DBG(dev, "Cannot find hba structure");
 		goto err2;
@@ -876,20 +1019,20 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
 	skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
 	fh = (struct fc_frame_header *) skb_transport_header(skb);
 
-	oxid = ntohs(fh->fh_ox_id);
-
 	fr = fcoe_dev_from_skb(skb);
 	fr->fr_dev = lp;
 	fr->ptype = ptype;
 
-#ifdef CONFIG_SMP
 	/*
-	 * The incoming frame exchange id(oxid) is ANDed with num of online
-	 * cpu bits to get cpu and then this cpu is used for selecting
-	 * a per cpu kernel thread from fcoe_percpu.
+	 * In case the incoming frame's exchange is originated from
+	 * the initiator, then received frame's exchange id is ANDed
+	 * with fc_cpu_mask bits to get the same cpu on which exchange
+	 * was originated, otherwise just use the current cpu.
 	 */
-	cpu = oxid & (num_online_cpus() - 1);
-#endif
+	if (ntoh24(fh->fh_f_ctl) & FC_FC_EX_CTX)
+		cpu = ntohs(fh->fh_ox_id) & fc_cpu_mask;
+	else
+		cpu = smp_processor_id();
 
 	fps = &per_cpu(fcoe_percpu, cpu);
 	spin_lock_bh(&fps->fcoe_rx_list.lock);
@@ -996,7 +1139,7 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
  * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
  * @fp: the fc_frame containing data to be checksummed
  *
- * This uses crc32() to calculate the crc for fc frame
+ * This uses crc32() to calculate the crc for port frame
  * Return   : 32 bit crc
  */
 u32 fcoe_fc_crc(struct fc_frame *fp)
@@ -1029,7 +1172,7 @@ u32 fcoe_fc_crc(struct fc_frame *fp)
 
 /**
  * fcoe_xmit() - FCoE frame transmit function
- * @lp:	the associated local port
+ * @lp:	the associated local fcoe
  * @fp: the fc_frame to be transmitted
  *
  * Return   : 0 for success
@@ -1046,13 +1189,13 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 	unsigned int hlen;		/* header length implies the version */
 	unsigned int tlen;		/* trailer length */
 	unsigned int elen;		/* eth header, may include vlan */
-	struct fcoe_softc *fc;
+	struct fcoe_port *port = lport_priv(lp);
+	struct fcoe_interface *fcoe = port->fcoe;
 	u8 sof, eof;
 	struct fcoe_hdr *hp;
 
 	WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
 
-	fc = lport_priv(lp);
 	fh = fc_frame_header_get(fp);
 	skb = fp_skb(fp);
 	wlen = skb->len / FCOE_WORD_TO_BYTE;
@@ -1063,7 +1206,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 	}
 
 	if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
-	    fcoe_ctlr_els_send(&fc->ctlr, skb))
+	    fcoe_ctlr_els_send(&fcoe->ctlr, skb))
 		return 0;
 
 	sof = fr_sof(fp);
@@ -1085,7 +1228,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 		crc = fcoe_fc_crc(fp);
 	}
 
-	/* copy fc crc and eof to the skb buff */
+	/* copy port crc and eof to the skb buff */
 	if (skb_is_nonlinear(skb)) {
 		skb_frag_t *frag;
 		if (fcoe_get_paged_crc_eof(skb, tlen)) {
@@ -1108,27 +1251,27 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 		cp = NULL;
 	}
 
-	/* adjust skb network/transport offsets to match mac/fcoe/fc */
+	/* adjust skb network/transport offsets to match mac/fcoe/port */
 	skb_push(skb, elen + hlen);
 	skb_reset_mac_header(skb);
 	skb_reset_network_header(skb);
 	skb->mac_len = elen;
 	skb->protocol = htons(ETH_P_FCOE);
-	skb->dev = fc->real_dev;
+	skb->dev = fcoe->netdev;
 
 	/* fill up mac and fcoe headers */
 	eh = eth_hdr(skb);
 	eh->h_proto = htons(ETH_P_FCOE);
-	if (fc->ctlr.map_dest)
+	if (fcoe->ctlr.map_dest)
 		fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
 	else
 		/* insert GW address */
-		memcpy(eh->h_dest, fc->ctlr.dest_addr, ETH_ALEN);
+		memcpy(eh->h_dest, fcoe->ctlr.dest_addr, ETH_ALEN);
 
-	if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN))
-		memcpy(eh->h_source, fc->ctlr.ctl_src_addr, ETH_ALEN);
+	if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN))
+		memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN);
 	else
-		memcpy(eh->h_source, fc->ctlr.data_src_addr, ETH_ALEN);
+		memcpy(eh->h_source, fcoe->ctlr.data_src_addr, ETH_ALEN);
 
 	hp = (struct fcoe_hdr *)(eh + 1);
 	memset(hp, 0, sizeof(*hp));
@@ -1136,7 +1279,6 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 		FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
 	hp->fcoe_sof = sof;
 
-#ifdef NETIF_F_FSO
 	/* fcoe lso, mss is in max_payload which is non-zero for FCP data */
 	if (lp->seq_offload && fr_max_payload(fp)) {
 		skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
@@ -1145,7 +1287,6 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 		skb_shinfo(skb)->gso_type = 0;
 		skb_shinfo(skb)->gso_size = 0;
 	}
-#endif
 	/* update tx stats: regardless if LLD fails */
 	stats = fc_lport_get_stats(lp);
 	stats->TxFrames++;
@@ -1153,7 +1294,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 
 	/* send down to lld */
 	fr_dev(fp) = lp;
-	if (fc->fcoe_pending_queue.qlen)
+	if (port->fcoe_pending_queue.qlen)
 		fcoe_check_wait_queue(lp, skb);
 	else if (fcoe_start_io(skb))
 		fcoe_check_wait_queue(lp, skb);
@@ -1162,6 +1303,15 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
 }
 
 /**
+ * fcoe_percpu_flush_done() - Indicate percpu queue flush completion.
+ * @skb: the skb being completed.
+ */
+static void fcoe_percpu_flush_done(struct sk_buff *skb)
+{
+	complete(&fcoe_flush_completion);
+}
+
+/**
  * fcoe_percpu_receive_thread() - recv thread per cpu
  * @arg: ptr to the fcoe per cpu struct
  *
@@ -1179,7 +1329,7 @@ int fcoe_percpu_receive_thread(void *arg)
 	struct fcoe_crc_eof crc_eof;
 	struct fc_frame *fp;
 	u8 *mac = NULL;
-	struct fcoe_softc *fc;
+	struct fcoe_port *port;
 	struct fcoe_hdr *hp;
 
 	set_user_nice(current, -20);
@@ -1200,7 +1350,8 @@ int fcoe_percpu_receive_thread(void *arg)
 		fr = fcoe_dev_from_skb(skb);
 		lp = fr->fr_dev;
 		if (unlikely(lp == NULL)) {
-			FCOE_NETDEV_DBG(skb->dev, "Invalid HBA Structure");
+			if (skb->destructor != fcoe_percpu_flush_done)
+				FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb");
 			kfree_skb(skb);
 			continue;
 		}
@@ -1215,7 +1366,7 @@ int fcoe_percpu_receive_thread(void *arg)
 		/*
 		 * Save source MAC address before discarding header.
 		 */
-		fc = lport_priv(lp);
+		port = lport_priv(lp);
 		if (skb_is_nonlinear(skb))
 			skb_linearize(skb);	/* not ideal */
 		mac = eth_hdr(skb)->h_source;
@@ -1277,7 +1428,7 @@ int fcoe_percpu_receive_thread(void *arg)
 		fh = fc_frame_header_get(fp);
 		if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
 		    fh->fh_type == FC_TYPE_FCP) {
-			fc_exch_recv(lp, lp->emp, fp);
+			fc_exch_recv(lp, fp);
 			continue;
 		}
 		if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
@@ -1293,12 +1444,12 @@ int fcoe_percpu_receive_thread(void *arg)
 			}
 			fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
 		}
-		if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
-		    fcoe_ctlr_recv_flogi(&fc->ctlr, fp, mac)) {
+		if (unlikely(port->fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
+		    fcoe_ctlr_recv_flogi(&port->fcoe->ctlr, fp, mac)) {
 			fc_frame_free(fp);
 			continue;
 		}
-		fc_exch_recv(lp, lp->emp, fp);
+		fc_exch_recv(lp, fp);
 	}
 	return 0;
 }
@@ -1318,46 +1469,46 @@ int fcoe_percpu_receive_thread(void *arg)
  */
 static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb)
 {
-	struct fcoe_softc *fc = lport_priv(lp);
+	struct fcoe_port *port = lport_priv(lp);
 	int rc;
 
-	spin_lock_bh(&fc->fcoe_pending_queue.lock);
+	spin_lock_bh(&port->fcoe_pending_queue.lock);
 
 	if (skb)
-		__skb_queue_tail(&fc->fcoe_pending_queue, skb);
+		__skb_queue_tail(&port->fcoe_pending_queue, skb);
 
-	if (fc->fcoe_pending_queue_active)
+	if (port->fcoe_pending_queue_active)
 		goto out;
-	fc->fcoe_pending_queue_active = 1;
+	port->fcoe_pending_queue_active = 1;
 
-	while (fc->fcoe_pending_queue.qlen) {
+	while (port->fcoe_pending_queue.qlen) {
 		/* keep qlen > 0 until fcoe_start_io succeeds */
-		fc->fcoe_pending_queue.qlen++;
-		skb = __skb_dequeue(&fc->fcoe_pending_queue);
+		port->fcoe_pending_queue.qlen++;
+		skb = __skb_dequeue(&port->fcoe_pending_queue);
 
-		spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+		spin_unlock_bh(&port->fcoe_pending_queue.lock);
 		rc = fcoe_start_io(skb);
-		spin_lock_bh(&fc->fcoe_pending_queue.lock);
+		spin_lock_bh(&port->fcoe_pending_queue.lock);
 
 		if (rc) {
-			__skb_queue_head(&fc->fcoe_pending_queue, skb);
+			__skb_queue_head(&port->fcoe_pending_queue, skb);
 			/* undo temporary increment above */
-			fc->fcoe_pending_queue.qlen--;
+			port->fcoe_pending_queue.qlen--;
 			break;
 		}
 		/* undo temporary increment above */
-		fc->fcoe_pending_queue.qlen--;
+		port->fcoe_pending_queue.qlen--;
 	}
 
-	if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
+	if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
 		lp->qfull = 0;
-	if (fc->fcoe_pending_queue.qlen && !timer_pending(&fc->timer))
-		mod_timer(&fc->timer, jiffies + 2);
-	fc->fcoe_pending_queue_active = 0;
+	if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer))
+		mod_timer(&port->timer, jiffies + 2);
+	port->fcoe_pending_queue_active = 0;
 out:
-	if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
+	if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
 		lp->qfull = 1;
-	spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+	spin_unlock_bh(&port->fcoe_pending_queue.lock);
 	return;
 }
 
@@ -1391,21 +1542,20 @@ static int fcoe_device_notification(struct notifier_block *notifier,
 				    ulong event, void *ptr)
 {
 	struct fc_lport *lp = NULL;
-	struct net_device *real_dev = ptr;
-	struct fcoe_softc *fc;
+	struct net_device *netdev = ptr;
+	struct fcoe_interface *fcoe;
+	struct fcoe_port *port;
 	struct fcoe_dev_stats *stats;
 	u32 link_possible = 1;
 	u32 mfs;
 	int rc = NOTIFY_OK;
 
-	read_lock(&fcoe_hostlist_lock);
-	list_for_each_entry(fc, &fcoe_hostlist, list) {
-		if (fc->real_dev == real_dev) {
-			lp = fc->ctlr.lp;
+	list_for_each_entry(fcoe, &fcoe_hostlist, list) {
+		if (fcoe->netdev == netdev) {
+			lp = fcoe->ctlr.lp;
 			break;
 		}
 	}
-	read_unlock(&fcoe_hostlist_lock);
 	if (lp == NULL) {
 		rc = NOTIFY_DONE;
 		goto out;
@@ -1420,21 +1570,27 @@ static int fcoe_device_notification(struct notifier_block *notifier,
 	case NETDEV_CHANGE:
 		break;
 	case NETDEV_CHANGEMTU:
-		mfs = fc->real_dev->mtu -
-			(sizeof(struct fcoe_hdr) +
-			 sizeof(struct fcoe_crc_eof));
+		mfs = netdev->mtu - (sizeof(struct fcoe_hdr) +
+				     sizeof(struct fcoe_crc_eof));
 		if (mfs >= FC_MIN_MAX_FRAME)
 			fc_set_mfs(lp, mfs);
 		break;
 	case NETDEV_REGISTER:
 		break;
+	case NETDEV_UNREGISTER:
+		list_del(&fcoe->list);
+		port = lport_priv(fcoe->ctlr.lp);
+		fcoe_interface_cleanup(fcoe);
+		schedule_work(&port->destroy_work);
+		goto out;
+		break;
 	default:
-		FCOE_NETDEV_DBG(real_dev, "Unknown event %ld "
+		FCOE_NETDEV_DBG(netdev, "Unknown event %ld "
 				"from netdev netlink\n", event);
 	}
 	if (link_possible && !fcoe_link_ok(lp))
-		fcoe_ctlr_link_up(&fc->ctlr);
-	else if (fcoe_ctlr_link_down(&fc->ctlr)) {
+		fcoe_ctlr_link_up(&fcoe->ctlr);
+	else if (fcoe_ctlr_link_down(&fcoe->ctlr)) {
 		stats = fc_lport_get_stats(lp);
 		stats->LinkFailureCount++;
 		fcoe_clean_pending_queue(lp);
@@ -1465,75 +1621,6 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer)
 }
 
 /**
- * fcoe_netdev_to_module_owner() - finds out the driver module of the netdev
- * @netdev: the target netdev
- *
- * Returns: ptr to the struct module, NULL for failure
- */
-static struct module *
-fcoe_netdev_to_module_owner(const struct net_device *netdev)
-{
-	struct device *dev;
-
-	if (!netdev)
-		return NULL;
-
-	dev = netdev->dev.parent;
-	if (!dev)
-		return NULL;
-
-	if (!dev->driver)
-		return NULL;
-
-	return dev->driver->owner;
-}
-
-/**
- * fcoe_ethdrv_get() - Hold the Ethernet driver
- * @netdev: the target netdev
- *
- * Holds the Ethernet driver module by try_module_get() for
- * the corresponding netdev.
- *
- * Returns: 0 for success
- */
-static int fcoe_ethdrv_get(const struct net_device *netdev)
-{
-	struct module *owner;
-
-	owner = fcoe_netdev_to_module_owner(netdev);
-	if (owner) {
-		FCOE_NETDEV_DBG(netdev, "Hold driver module %s\n",
-				module_name(owner));
-		return  try_module_get(owner);
-	}
-	return -ENODEV;
-}
-
-/**
- * fcoe_ethdrv_put() - Release the Ethernet driver
- * @netdev: the target netdev
- *
- * Releases the Ethernet driver module by module_put for
- * the corresponding netdev.
- *
- * Returns: 0 for success
- */
-static int fcoe_ethdrv_put(const struct net_device *netdev)
-{
-	struct module *owner;
-
-	owner = fcoe_netdev_to_module_owner(netdev);
-	if (owner) {
-		FCOE_NETDEV_DBG(netdev, "Release driver module %s\n",
-				module_name(owner));
-		module_put(owner);
-		return 0;
-	}
-	return -ENODEV;
-}
-
-/**
  * fcoe_destroy() - handles the destroy from sysfs
  * @buffer: expected to be an eth if name
  * @kp: associated kernel param
@@ -1542,34 +1629,57 @@ static int fcoe_ethdrv_put(const struct net_device *netdev)
  */
 static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
 {
-	int rc;
+	struct fcoe_interface *fcoe;
 	struct net_device *netdev;
+	int rc;
+
+	mutex_lock(&fcoe_config_mutex);
+#ifdef CONFIG_FCOE_MODULE
+	/*
+	 * Make sure the module has been initialized, and is not about to be
+	 * removed.  Module paramter sysfs files are writable before the
+	 * module_init function is called and after module_exit.
+	 */
+	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
+		rc = -ENODEV;
+		goto out_nodev;
+	}
+#endif
 
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev) {
 		rc = -ENODEV;
 		goto out_nodev;
 	}
-	/* look for existing lport */
-	if (!fcoe_hostlist_lookup(netdev)) {
+
+	rtnl_lock();
+	fcoe = fcoe_hostlist_lookup_port(netdev);
+	if (!fcoe) {
+		rtnl_unlock();
 		rc = -ENODEV;
 		goto out_putdev;
 	}
-	rc = fcoe_if_destroy(netdev);
-	if (rc) {
-		printk(KERN_ERR "fcoe: Failed to destroy interface (%s)\n",
-		       netdev->name);
-		rc = -EIO;
-		goto out_putdev;
-	}
-	fcoe_ethdrv_put(netdev);
-	rc = 0;
+	list_del(&fcoe->list);
+	fcoe_interface_cleanup(fcoe);
+	rtnl_unlock();
+	fcoe_if_destroy(fcoe->ctlr.lp);
 out_putdev:
 	dev_put(netdev);
 out_nodev:
+	mutex_unlock(&fcoe_config_mutex);
 	return rc;
 }
 
+static void fcoe_destroy_work(struct work_struct *work)
+{
+	struct fcoe_port *port;
+
+	port = container_of(work, struct fcoe_port, destroy_work);
+	mutex_lock(&fcoe_config_mutex);
+	fcoe_if_destroy(port->lport);
+	mutex_unlock(&fcoe_config_mutex);
+}
+
 /**
  * fcoe_create() - Handles the create call from sysfs
  * @buffer: expected to be an eth if name
@@ -1580,41 +1690,84 @@ out_nodev:
 static int fcoe_create(const char *buffer, struct kernel_param *kp)
 {
 	int rc;
+	struct fcoe_interface *fcoe;
+	struct fc_lport *lport;
 	struct net_device *netdev;
 
+	mutex_lock(&fcoe_config_mutex);
+#ifdef CONFIG_FCOE_MODULE
+	/*
+	 * Make sure the module has been initialized, and is not about to be
+	 * removed.  Module paramter sysfs files are writable before the
+	 * module_init function is called and after module_exit.
+	 */
+	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
+		rc = -ENODEV;
+		goto out_nodev;
+	}
+#endif
+
+	rtnl_lock();
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev) {
 		rc = -ENODEV;
 		goto out_nodev;
 	}
+
 	/* look for existing lport */
 	if (fcoe_hostlist_lookup(netdev)) {
 		rc = -EEXIST;
 		goto out_putdev;
 	}
-	fcoe_ethdrv_get(netdev);
 
-	rc = fcoe_if_create(netdev);
-	if (rc) {
+	fcoe = fcoe_interface_create(netdev);
+	if (!fcoe) {
+		rc = -ENOMEM;
+		goto out_putdev;
+	}
+
+	lport = fcoe_if_create(fcoe, &netdev->dev);
+	if (IS_ERR(lport)) {
 		printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
 		       netdev->name);
-		fcoe_ethdrv_put(netdev);
 		rc = -EIO;
-		goto out_putdev;
+		fcoe_interface_cleanup(fcoe);
+		goto out_free;
 	}
+
+	/* Make this the "master" N_Port */
+	fcoe->ctlr.lp = lport;
+
+	/* add to lports list */
+	fcoe_hostlist_add(lport);
+
+	/* start FIP Discovery and FLOGI */
+	lport->boot_time = jiffies;
+	fc_fabric_login(lport);
+	if (!fcoe_link_ok(lport))
+		fcoe_ctlr_link_up(&fcoe->ctlr);
+
 	rc = 0;
+out_free:
+	/*
+	 * Release from init in fcoe_interface_create(), on success lport
+	 * should be holding a reference taken in fcoe_if_create().
+	 */
+	fcoe_interface_put(fcoe);
 out_putdev:
 	dev_put(netdev);
 out_nodev:
+	rtnl_unlock();
+	mutex_unlock(&fcoe_config_mutex);
 	return rc;
 }
 
 module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
 __MODULE_PARM_TYPE(create, "string");
-MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
+MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in.");
 module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
 __MODULE_PARM_TYPE(destroy, "string");
-MODULE_PARM_DESC(destroy, "Destroy fcoe port");
+MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe");
 
 /**
  * fcoe_link_ok() - Check if link is ok for the fc_lport
@@ -1632,37 +1785,40 @@ MODULE_PARM_DESC(destroy, "Destroy fcoe port");
  */
 int fcoe_link_ok(struct fc_lport *lp)
 {
-	struct fcoe_softc *fc = lport_priv(lp);
-	struct net_device *dev = fc->real_dev;
+	struct fcoe_port *port = lport_priv(lp);
+	struct net_device *dev = port->fcoe->netdev;
 	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
-	int rc = 0;
 
-	if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
-		dev = fc->phys_dev;
-		if (dev->ethtool_ops->get_settings) {
-			dev->ethtool_ops->get_settings(dev, &ecmd);
-			lp->link_supported_speeds &=
-				~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
-			if (ecmd.supported & (SUPPORTED_1000baseT_Half |
-					      SUPPORTED_1000baseT_Full))
-				lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
-			if (ecmd.supported & SUPPORTED_10000baseT_Full)
-				lp->link_supported_speeds |=
-					FC_PORTSPEED_10GBIT;
-			if (ecmd.speed == SPEED_1000)
-				lp->link_speed = FC_PORTSPEED_1GBIT;
-			if (ecmd.speed == SPEED_10000)
-				lp->link_speed = FC_PORTSPEED_10GBIT;
-		}
-	} else
-		rc = -1;
+	if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
+	    (!dev_ethtool_get_settings(dev, &ecmd))) {
+		lp->link_supported_speeds &=
+			~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
+		if (ecmd.supported & (SUPPORTED_1000baseT_Half |
+				      SUPPORTED_1000baseT_Full))
+			lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+		if (ecmd.supported & SUPPORTED_10000baseT_Full)
+			lp->link_supported_speeds |=
+				FC_PORTSPEED_10GBIT;
+		if (ecmd.speed == SPEED_1000)
+			lp->link_speed = FC_PORTSPEED_1GBIT;
+		if (ecmd.speed == SPEED_10000)
+			lp->link_speed = FC_PORTSPEED_10GBIT;
 
-	return rc;
+		return 0;
+	}
+	return -1;
 }
 
 /**
  * fcoe_percpu_clean() - Clear the pending skbs for an lport
  * @lp: the fc_lport
+ *
+ * Must be called with fcoe_create_mutex held to single-thread completion.
+ *
+ * This flushes the pending skbs by adding a new skb to each queue and
+ * waiting until they are all freed.  This assures us that not only are
+ * there no packets that will be handled by the lport, but also that any
+ * threads already handling packet have returned.
  */
 void fcoe_percpu_clean(struct fc_lport *lp)
 {
@@ -1687,7 +1843,25 @@ void fcoe_percpu_clean(struct fc_lport *lp)
 				kfree_skb(skb);
 			}
 		}
+
+		if (!pp->thread || !cpu_online(cpu)) {
+			spin_unlock_bh(&pp->fcoe_rx_list.lock);
+			continue;
+		}
+
+		skb = dev_alloc_skb(0);
+		if (!skb) {
+			spin_unlock_bh(&pp->fcoe_rx_list.lock);
+			continue;
+		}
+		skb->destructor = fcoe_percpu_flush_done;
+
+		__skb_queue_tail(&pp->fcoe_rx_list, skb);
+		if (pp->fcoe_rx_list.qlen == 1)
+			wake_up_process(pp->thread);
 		spin_unlock_bh(&pp->fcoe_rx_list.lock);
+
+		wait_for_completion(&fcoe_flush_completion);
 	}
 }
 
@@ -1699,16 +1873,16 @@ void fcoe_percpu_clean(struct fc_lport *lp)
  */
 void fcoe_clean_pending_queue(struct fc_lport *lp)
 {
-	struct fcoe_softc  *fc = lport_priv(lp);
+	struct fcoe_port  *port = lport_priv(lp);
 	struct sk_buff *skb;
 
-	spin_lock_bh(&fc->fcoe_pending_queue.lock);
-	while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
-		spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+	spin_lock_bh(&port->fcoe_pending_queue.lock);
+	while ((skb = __skb_dequeue(&port->fcoe_pending_queue)) != NULL) {
+		spin_unlock_bh(&port->fcoe_pending_queue.lock);
 		kfree_skb(skb);
-		spin_lock_bh(&fc->fcoe_pending_queue.lock);
+		spin_lock_bh(&port->fcoe_pending_queue.lock);
 	}
-	spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+	spin_unlock_bh(&port->fcoe_pending_queue.lock);
 }
 
 /**
@@ -1725,24 +1899,21 @@ int fcoe_reset(struct Scsi_Host *shost)
 }
 
 /**
- * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
+ * fcoe_hostlist_lookup_port() - find the corresponding lport by a given device
  * @dev: this is currently ptr to net_device
  *
- * Returns: NULL or the located fcoe_softc
+ * Returns: NULL or the located fcoe_port
+ * Locking: must be called with the RNL mutex held
  */
-static struct fcoe_softc *
-fcoe_hostlist_lookup_softc(const struct net_device *dev)
+static struct fcoe_interface *
+fcoe_hostlist_lookup_port(const struct net_device *dev)
 {
-	struct fcoe_softc *fc;
+	struct fcoe_interface *fcoe;
 
-	read_lock(&fcoe_hostlist_lock);
-	list_for_each_entry(fc, &fcoe_hostlist, list) {
-		if (fc->real_dev == dev) {
-			read_unlock(&fcoe_hostlist_lock);
-			return fc;
-		}
+	list_for_each_entry(fcoe, &fcoe_hostlist, list) {
+		if (fcoe->netdev == dev)
+			return fcoe;
 	}
-	read_unlock(&fcoe_hostlist_lock);
 	return NULL;
 }
 
@@ -1751,14 +1922,14 @@ fcoe_hostlist_lookup_softc(const struct net_device *dev)
  * @netdev: ptr to net_device
  *
  * Returns: 0 for success
+ * Locking: must be called with the RTNL mutex held
  */
-struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
+static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
 {
-	struct fcoe_softc *fc;
-
-	fc = fcoe_hostlist_lookup_softc(netdev);
+	struct fcoe_interface *fcoe;
 
-	return (fc) ? fc->ctlr.lp : NULL;
+	fcoe = fcoe_hostlist_lookup_port(netdev);
+	return (fcoe) ? fcoe->ctlr.lp : NULL;
 }
 
 /**
@@ -1766,41 +1937,23 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
  * @lp: ptr to the fc_lport to be added
  *
  * Returns: 0 for success
+ * Locking: must be called with the RTNL mutex held
  */
-int fcoe_hostlist_add(const struct fc_lport *lp)
+static int fcoe_hostlist_add(const struct fc_lport *lport)
 {
-	struct fcoe_softc *fc;
-
-	fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
-	if (!fc) {
-		fc = lport_priv(lp);
-		write_lock_bh(&fcoe_hostlist_lock);
-		list_add_tail(&fc->list, &fcoe_hostlist);
-		write_unlock_bh(&fcoe_hostlist_lock);
+	struct fcoe_interface *fcoe;
+	struct fcoe_port *port;
+
+	fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport));
+	if (!fcoe) {
+		port = lport_priv(lport);
+		fcoe = port->fcoe;
+		list_add_tail(&fcoe->list, &fcoe_hostlist);
 	}
 	return 0;
 }
 
 /**
- * fcoe_hostlist_remove() - remove a lport from lports list
- * @lp: ptr to the fc_lport to be removed
- *
- * Returns: 0 for success
- */
-int fcoe_hostlist_remove(const struct fc_lport *lp)
-{
-	struct fcoe_softc *fc;
-
-	fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
-	BUG_ON(!fc);
-	write_lock_bh(&fcoe_hostlist_lock);
-	list_del(&fc->list);
-	write_unlock_bh(&fcoe_hostlist_lock);
-
-	return 0;
-}
-
-/**
  * fcoe_init() - fcoe module loading initialization
  *
  * Returns 0 on success, negative on failure
@@ -1811,8 +1964,7 @@ static int __init fcoe_init(void)
 	int rc = 0;
 	struct fcoe_percpu_s *p;
 
-	INIT_LIST_HEAD(&fcoe_hostlist);
-	rwlock_init(&fcoe_hostlist_lock);
+	mutex_lock(&fcoe_config_mutex);
 
 	for_each_possible_cpu(cpu) {
 		p = &per_cpu(fcoe_percpu, cpu);
@@ -1830,15 +1982,18 @@ static int __init fcoe_init(void)
 	/* Setup link change notification */
 	fcoe_dev_setup();
 
-	fcoe_if_init();
+	rc = fcoe_if_init();
+	if (rc)
+		goto out_free;
 
+	mutex_unlock(&fcoe_config_mutex);
 	return 0;
 
 out_free:
 	for_each_online_cpu(cpu) {
 		fcoe_percpu_thread_destroy(cpu);
 	}
-
+	mutex_unlock(&fcoe_config_mutex);
 	return rc;
 }
 module_init(fcoe_init);
@@ -1851,21 +2006,36 @@ module_init(fcoe_init);
 static void __exit fcoe_exit(void)
 {
 	unsigned int cpu;
-	struct fcoe_softc *fc, *tmp;
+	struct fcoe_interface *fcoe, *tmp;
+	struct fcoe_port *port;
+
+	mutex_lock(&fcoe_config_mutex);
 
 	fcoe_dev_cleanup();
 
 	/* releases the associated fcoe hosts */
-	list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
-		fcoe_if_destroy(fc->real_dev);
+	rtnl_lock();
+	list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) {
+		list_del(&fcoe->list);
+		port = lport_priv(fcoe->ctlr.lp);
+		fcoe_interface_cleanup(fcoe);
+		schedule_work(&port->destroy_work);
+	}
+	rtnl_unlock();
 
 	unregister_hotcpu_notifier(&fcoe_cpu_notifier);
 
-	for_each_online_cpu(cpu) {
+	for_each_online_cpu(cpu)
 		fcoe_percpu_thread_destroy(cpu);
-	}
 
-	/* detach from scsi transport */
+	mutex_unlock(&fcoe_config_mutex);
+
+	/* flush any asyncronous interface destroys,
+	 * this should happen after the netdev notifier is unregistered */
+	flush_scheduled_work();
+
+	/* detach from scsi transport
+	 * must happen after all destroys are done, therefor after the flush */
 	fcoe_if_exit();
 }
 module_exit(fcoe_exit);
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
index 0d724fa..ce7f60f 100644
--- a/drivers/scsi/fcoe/fcoe.h
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -37,8 +37,8 @@
 
 #define FCOE_MAX_OUTSTANDING_COMMANDS	1024
 
-#define FCOE_MIN_XID		0x0001	/* the min xid supported by fcoe_sw */
-#define FCOE_MAX_XID		0x07ef	/* the max xid supported by fcoe_sw */
+#define FCOE_MIN_XID		0x0000	/* the min xid supported by fcoe_sw */
+#define FCOE_MAX_XID		0x0FFF	/* the max xid supported by fcoe_sw */
 
 unsigned int fcoe_debug_logging;
 module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR);
@@ -53,7 +53,7 @@ do {                                                            	\
 		do {							\
 			CMD;						\
 		} while (0);						\
-} while (0);
+} while (0)
 
 #define FCOE_DBG(fmt, args...)						\
 	FCOE_CHECK_LOGGING(FCOE_LOGGING,				\
@@ -61,7 +61,7 @@ do {                                                            	\
 
 #define FCOE_NETDEV_DBG(netdev, fmt, args...)			\
 	FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING,			\
-			   printk(KERN_INFO "fcoe: %s" fmt,	\
+			   printk(KERN_INFO "fcoe: %s: " fmt,	\
 				  netdev->name, ##args);)
 
 /*
@@ -75,26 +75,36 @@ struct fcoe_percpu_s {
 };
 
 /*
- * the fcoe sw transport private data
+ * an FCoE interface, 1:1 with netdev
  */
-struct fcoe_softc {
+struct fcoe_interface {
 	struct list_head list;
-	struct net_device *real_dev;
-	struct net_device *phys_dev;		/* device with ethtool_ops */
+	struct net_device *netdev;
 	struct packet_type  fcoe_packet_type;
 	struct packet_type  fip_packet_type;
+	struct fcoe_ctlr ctlr;
+	struct fc_exch_mgr *oem;		/* offload exchange manager */
+	struct kref kref;
+};
+
+/*
+ * the FCoE private structure that's allocated along with the
+ * Scsi_Host and libfc fc_lport structures
+ */
+struct fcoe_port {
+	struct fcoe_interface *fcoe;
+	struct fc_lport *lport;
 	struct sk_buff_head fcoe_pending_queue;
 	u8	fcoe_pending_queue_active;
 	struct timer_list timer;		/* queue timer */
-	struct fcoe_ctlr ctlr;
+	struct work_struct destroy_work;	/* to prevent rtnl deadlocks */
 };
 
-#define fcoe_from_ctlr(fc) container_of(fc, struct fcoe_softc, ctlr)
+#define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr)
 
-static inline struct net_device *fcoe_netdev(
-	const struct fc_lport *lp)
+static inline struct net_device *fcoe_netdev(const struct fc_lport *lp)
 {
-	return ((struct fcoe_softc *)lport_priv(lp))->real_dev;
+	return ((struct fcoe_port *)lport_priv(lp))->fcoe->netdev;
 }
 
 #endif /* _FCOE_H_ */
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index f544340..11ae5c9 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -29,7 +29,6 @@
 #include <linux/ethtool.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
-#include <linux/netdevice.h>
 #include <linux/errno.h>
 #include <linux/bitops.h>
 #include <net/rtnetlink.h>
@@ -69,7 +68,7 @@ do {                                                            	\
 		do {							\
 			CMD;						\
 		} while (0);						\
-} while (0);
+} while (0)
 
 #define LIBFCOE_DBG(fmt, args...)					\
 	LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING,				\
@@ -148,13 +147,17 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
  */
 void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
 {
-	flush_work(&fip->recv_work);
+	cancel_work_sync(&fip->recv_work);
+	spin_lock_bh(&fip->fip_recv_list.lock);
+	__skb_queue_purge(&fip->fip_recv_list);
+	spin_unlock_bh(&fip->fip_recv_list.lock);
+
 	spin_lock_bh(&fip->lock);
 	fip->state = FIP_ST_DISABLED;
 	fcoe_ctlr_reset_fcfs(fip);
 	spin_unlock_bh(&fip->lock);
 	del_timer_sync(&fip->timer);
-	flush_work(&fip->link_work);
+	cancel_work_sync(&fip->link_work);
 }
 EXPORT_SYMBOL(fcoe_ctlr_destroy);
 
@@ -413,10 +416,18 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
 	struct fip_mac_desc *mac;
 	struct fcoe_fcf *fcf;
 	size_t dlen;
+	u16 fip_flags;
 
 	fcf = fip->sel_fcf;
 	if (!fcf)
 		return -ENODEV;
+
+	/* set flags according to both FCF and lport's capability on SPMA */
+	fip_flags = fcf->flags;
+	fip_flags &= fip->spma ? FIP_FL_SPMA | FIP_FL_FPMA : FIP_FL_FPMA;
+	if (!fip_flags)
+		return -ENODEV;
+
 	dlen = sizeof(struct fip_encaps) + skb->len;	/* len before push */
 	cap = (struct fip_encaps_head *)skb_push(skb, sizeof(*cap));
 
@@ -429,9 +440,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
 	cap->fip.fip_op = htons(FIP_OP_LS);
 	cap->fip.fip_subcode = FIP_SC_REQ;
 	cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
-	cap->fip.fip_flags = htons(FIP_FL_FPMA);
-	if (fip->spma)
-		cap->fip.fip_flags |= htons(FIP_FL_SPMA);
+	cap->fip.fip_flags = htons(fip_flags);
 
 	cap->encaps.fd_desc.fip_dtype = dtype;
 	cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
@@ -879,7 +888,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
 	stats->RxFrames++;
 	stats->RxWords += skb->len / FIP_BPW;
 
-	fc_exch_recv(lp, lp->emp, fp);
+	fc_exch_recv(lp, fp);
 	return;
 
 len_err:
@@ -1104,7 +1113,6 @@ static void fcoe_ctlr_timeout(unsigned long arg)
 	struct fcoe_fcf *sel;
 	struct fcoe_fcf *fcf;
 	unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
-	DECLARE_MAC_BUF(buf);
 	u8 send_ctlr_ka;
 	u8 send_port_ka;
 
@@ -1128,9 +1136,8 @@ static void fcoe_ctlr_timeout(unsigned long arg)
 		fcf = sel;		/* the old FCF may have been freed */
 		if (sel) {
 			printk(KERN_INFO "libfcoe: host%d: FIP selected "
-			       "Fibre-Channel Forwarder MAC %s\n",
-			       fip->lp->host->host_no,
-			       print_mac(buf, sel->fcf_mac));
+			       "Fibre-Channel Forwarder MAC %pM\n",
+			       fip->lp->host->host_no, sel->fcf_mac);
 			memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
 			fip->port_ka_time = jiffies +
 					    msecs_to_jiffies(FIP_VN_KA_PERIOD);
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c
index 07e6eed..50db3e3 100644
--- a/drivers/scsi/fnic/fnic_fcs.c
+++ b/drivers/scsi/fnic/fnic_fcs.c
@@ -115,7 +115,7 @@ void fnic_handle_frame(struct work_struct *work)
 		}
 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
 
-		fc_exch_recv(lp, lp->emp, fp);
+		fc_exch_recv(lp, fp);
 	}
 
 }
diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index 2c266c0..71c7bbe 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -671,14 +671,6 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
 	lp->link_up = 0;
 	lp->tt = fnic_transport_template;
 
-	lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
-				    FCPIO_HOST_EXCH_RANGE_START,
-				    FCPIO_HOST_EXCH_RANGE_END);
-	if (!lp->emp) {
-		err = -ENOMEM;
-		goto err_out_remove_scsi_host;
-	}
-
 	lp->max_retry_count = fnic->config.flogi_retries;
 	lp->max_rport_retry_count = fnic->config.plogi_retries;
 	lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
@@ -693,12 +685,18 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
 	fc_set_wwnn(lp, fnic->config.node_wwn);
 	fc_set_wwpn(lp, fnic->config.port_wwn);
 
-	fc_exch_init(lp);
 	fc_lport_init(lp);
+	fc_exch_init(lp);
 	fc_elsct_init(lp);
 	fc_rport_init(lp);
 	fc_disc_init(lp);
 
+	if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, FCPIO_HOST_EXCH_RANGE_START,
+			       FCPIO_HOST_EXCH_RANGE_END, NULL)) {
+		err = -ENOMEM;
+		goto err_out_remove_scsi_host;
+	}
+
 	fc_lport_config(lp);
 
 	if (fc_set_mfs(lp, fnic->config.maxdatafieldsize +
@@ -738,7 +736,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev,
 	return 0;
 
 err_out_free_exch_mgr:
-	fc_exch_mgr_free(lp->emp);
+	fc_exch_mgr_free(lp);
 err_out_remove_scsi_host:
 	fc_remove_host(fnic->lport->host);
 	scsi_remove_host(fnic->lport->host);
@@ -827,7 +825,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev)
 
 	fc_remove_host(fnic->lport->host);
 	scsi_remove_host(fnic->lport->host);
-	fc_exch_mgr_free(fnic->lport->emp);
+	fc_exch_mgr_free(fnic->lport);
 	vnic_dev_notify_unset(fnic->vdev);
 	fnic_free_vnic_resources(fnic);
 	fnic_free_intr(fnic);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 166d964..bb2c696 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -4217,7 +4217,7 @@ static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost)
 	if (!vhost->trace)
 		goto free_disc_buffer;
 
-	vhost->tgt_pool = mempool_create_kzalloc_pool(IBMVFC_TGT_MEMPOOL_SZ,
+	vhost->tgt_pool = mempool_create_kmalloc_pool(IBMVFC_TGT_MEMPOOL_SZ,
 						      sizeof(struct ibmvfc_target));
 
 	if (!vhost->tgt_pool) {
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 9928704..d9b0e9d 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -73,7 +73,6 @@
 #include <linux/of.h>
 #include <asm/firmware.h>
 #include <asm/vio.h>
-#include <asm/firmware.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 4b63dd6..163245a 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -1199,7 +1199,7 @@ struct ipr_ioa_cfg {
 
 	struct ata_host ata_host;
 	char ipr_cmd_label[8];
-#define IPR_CMD_LABEL		"ipr_cmnd"
+#define IPR_CMD_LABEL		"ipr_cmd"
 	struct ipr_cmnd *ipr_cmnd_list[IPR_NUM_CMD_BLKS];
 	u32 ipr_cmnd_list_dma[IPR_NUM_CMD_BLKS];
 };
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 518dbd9..2b1b834 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -99,6 +99,27 @@ static int iscsi_sw_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
 	return total_consumed;
 }
 
+/**
+ * iscsi_sw_sk_state_check - check socket state
+ * @sk: socket
+ *
+ * If the socket is in CLOSE or CLOSE_WAIT we should
+ * not close the connection if there is still some
+ * data pending.
+ */
+static inline int iscsi_sw_sk_state_check(struct sock *sk)
+{
+	struct iscsi_conn *conn = (struct iscsi_conn*)sk->sk_user_data;
+
+	if ((sk->sk_state == TCP_CLOSE_WAIT || sk->sk_state == TCP_CLOSE) &&
+	    !atomic_read(&sk->sk_rmem_alloc)) {
+		ISCSI_SW_TCP_DBG(conn, "TCP_CLOSE|TCP_CLOSE_WAIT\n");
+		iscsi_conn_failure(conn, ISCSI_ERR_TCP_CONN_CLOSE);
+		return -ECONNRESET;
+	}
+	return 0;
+}
+
 static void iscsi_sw_tcp_data_ready(struct sock *sk, int flag)
 {
 	struct iscsi_conn *conn = sk->sk_user_data;
@@ -117,6 +138,8 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk, int flag)
 	rd_desc.count = 1;
 	tcp_read_sock(sk, &rd_desc, iscsi_sw_tcp_recv);
 
+	iscsi_sw_sk_state_check(sk);
+
 	read_unlock(&sk->sk_callback_lock);
 
 	/* If we had to (atomically) map a highmem page,
@@ -137,13 +160,7 @@ static void iscsi_sw_tcp_state_change(struct sock *sk)
 	conn = (struct iscsi_conn*)sk->sk_user_data;
 	session = conn->session;
 
-	if ((sk->sk_state == TCP_CLOSE_WAIT ||
-	     sk->sk_state == TCP_CLOSE) &&
-	    !atomic_read(&sk->sk_rmem_alloc)) {
-		ISCSI_SW_TCP_DBG(conn, "iscsi_tcp_state_change: "
-				 "TCP_CLOSE|TCP_CLOSE_WAIT\n");
-		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
-	}
+	iscsi_sw_sk_state_check(sk);
 
 	tcp_conn = conn->dd_data;
 	tcp_sw_conn = tcp_conn->dd_data;
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c
index 6fabf66..c48799e 100644
--- a/drivers/scsi/libfc/fc_disc.c
+++ b/drivers/scsi/libfc/fc_disc.c
@@ -43,47 +43,14 @@
 #define FC_DISC_RETRY_LIMIT	3	/* max retries */
 #define FC_DISC_RETRY_DELAY	500UL	/* (msecs) delay */
 
-#define	FC_DISC_DELAY		3
-
 static void fc_disc_gpn_ft_req(struct fc_disc *);
 static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *);
-static int fc_disc_new_target(struct fc_disc *, struct fc_rport *,
-			      struct fc_rport_identifiers *);
-static void fc_disc_del_target(struct fc_disc *, struct fc_rport *);
-static void fc_disc_done(struct fc_disc *);
+static void fc_disc_done(struct fc_disc *, enum fc_disc_event);
 static void fc_disc_timeout(struct work_struct *);
-static void fc_disc_single(struct fc_disc *, struct fc_disc_port *);
+static int fc_disc_single(struct fc_lport *, struct fc_disc_port *);
 static void fc_disc_restart(struct fc_disc *);
 
 /**
- * fc_disc_lookup_rport() - lookup a remote port by port_id
- * @lport: Fibre Channel host port instance
- * @port_id: remote port port_id to match
- */
-struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport,
-				      u32 port_id)
-{
-	const struct fc_disc *disc = &lport->disc;
-	struct fc_rport *rport, *found = NULL;
-	struct fc_rport_libfc_priv *rdata;
-	int disc_found = 0;
-
-	list_for_each_entry(rdata, &disc->rports, peers) {
-		rport = PRIV_TO_RPORT(rdata);
-		if (rport->port_id == port_id) {
-			disc_found = 1;
-			found = rport;
-			break;
-		}
-	}
-
-	if (!disc_found)
-		found = NULL;
-
-	return found;
-}
-
-/**
  * fc_disc_stop_rports() - delete all the remote ports associated with the lport
  * @disc: The discovery job to stop rports on
  *
@@ -93,70 +60,17 @@ struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport,
 void fc_disc_stop_rports(struct fc_disc *disc)
 {
 	struct fc_lport *lport;
-	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rdata, *next;
+	struct fc_rport_priv *rdata, *next;
 
 	lport = disc->lport;
 
 	mutex_lock(&disc->disc_mutex);
-	list_for_each_entry_safe(rdata, next, &disc->rports, peers) {
-		rport = PRIV_TO_RPORT(rdata);
-		list_del(&rdata->peers);
-		lport->tt.rport_logoff(rport);
-	}
-
-	list_for_each_entry_safe(rdata, next, &disc->rogue_rports, peers) {
-		rport = PRIV_TO_RPORT(rdata);
-		lport->tt.rport_logoff(rport);
-	}
-
+	list_for_each_entry_safe(rdata, next, &disc->rports, peers)
+		lport->tt.rport_logoff(rdata);
 	mutex_unlock(&disc->disc_mutex);
 }
 
 /**
- * fc_disc_rport_callback() - Event handler for rport events
- * @lport: The lport which is receiving the event
- * @rport: The rport which the event has occured on
- * @event: The event that occured
- *
- * Locking Note: The rport lock should not be held when calling
- *		 this function.
- */
-static void fc_disc_rport_callback(struct fc_lport *lport,
-				   struct fc_rport *rport,
-				   enum fc_rport_event event)
-{
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-	struct fc_disc *disc = &lport->disc;
-
-	FC_DISC_DBG(disc, "Received a %d event for port (%6x)\n", event,
-		    rport->port_id);
-
-	switch (event) {
-	case RPORT_EV_CREATED:
-		if (disc) {
-			mutex_lock(&disc->disc_mutex);
-			list_add_tail(&rdata->peers, &disc->rports);
-			mutex_unlock(&disc->disc_mutex);
-		}
-		break;
-	case RPORT_EV_LOGO:
-	case RPORT_EV_FAILED:
-	case RPORT_EV_STOP:
-		mutex_lock(&disc->disc_mutex);
-		mutex_lock(&rdata->rp_mutex);
-		if (rdata->trans_state == FC_PORTSTATE_ROGUE)
-			list_del(&rdata->peers);
-		mutex_unlock(&rdata->rp_mutex);
-		mutex_unlock(&disc->disc_mutex);
-		break;
-	default:
-		break;
-	}
-
-}
-
-/**
  * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN)
  * @sp: Current sequence of the RSCN exchange
  * @fp: RSCN Frame
@@ -169,8 +83,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
 				  struct fc_disc *disc)
 {
 	struct fc_lport *lport;
-	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rdata;
 	struct fc_els_rscn *rp;
 	struct fc_els_rscn_page *pp;
 	struct fc_seq_els_data rjt_data;
@@ -224,10 +136,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
 				break;
 			}
 			dp->lp = lport;
-			dp->ids.port_id = ntoh24(pp->rscn_fid);
-			dp->ids.port_name = -1;
-			dp->ids.node_name = -1;
-			dp->ids.roles = FC_RPORT_ROLE_UNKNOWN;
+			dp->port_id = ntoh24(pp->rscn_fid);
 			list_add_tail(&dp->peers, &disc_ports);
 			break;
 		case ELS_ADDR_FMT_AREA:
@@ -240,6 +149,19 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
 		}
 	}
 	lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
+
+	/*
+	 * If not doing a complete rediscovery, do GPN_ID on
+	 * the individual ports mentioned in the list.
+	 * If any of these get an error, do a full rediscovery.
+	 * In any case, go through the list and free the entries.
+	 */
+	list_for_each_entry_safe(dp, next, &disc_ports, peers) {
+		list_del(&dp->peers);
+		if (!redisc)
+			redisc = fc_disc_single(lport, dp);
+		kfree(dp);
+	}
 	if (redisc) {
 		FC_DISC_DBG(disc, "RSCN received: rediscovering\n");
 		fc_disc_restart(disc);
@@ -247,16 +169,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp,
 		FC_DISC_DBG(disc, "RSCN received: not rediscovering. "
 			    "redisc %d state %d in_prog %d\n",
 			    redisc, lport->state, disc->pending);
-		list_for_each_entry_safe(dp, next, &disc_ports, peers) {
-			list_del(&dp->peers);
-			rport = lport->tt.rport_lookup(lport, dp->ids.port_id);
-			if (rport) {
-				rdata = rport->dd_data;
-				list_del(&rdata->peers);
-				lport->tt.rport_logoff(rport);
-			}
-			fc_disc_single(disc, dp);
-		}
 	}
 	fc_frame_free(fp);
 	return;
@@ -308,35 +220,34 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp,
  */
 static void fc_disc_restart(struct fc_disc *disc)
 {
-	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rdata, *next;
-	struct fc_lport *lport = disc->lport;
+	if (!disc->disc_callback)
+		return;
 
 	FC_DISC_DBG(disc, "Restarting discovery\n");
 
-	list_for_each_entry_safe(rdata, next, &disc->rports, peers) {
-		rport = PRIV_TO_RPORT(rdata);
-		list_del(&rdata->peers);
-		lport->tt.rport_logoff(rport);
-	}
-
 	disc->requested = 1;
-	if (!disc->pending)
-		fc_disc_gpn_ft_req(disc);
+	if (disc->pending)
+		return;
+
+	/*
+	 * Advance disc_id.  This is an arbitrary non-zero number that will
+	 * match the value in the fc_rport_priv after discovery for all
+	 * freshly-discovered remote ports.  Avoid wrapping to zero.
+	 */
+	disc->disc_id = (disc->disc_id + 2) | 1;
+	disc->retry_count = 0;
+	fc_disc_gpn_ft_req(disc);
 }
 
 /**
  * fc_disc_start() - Fibre Channel Target discovery
  * @lport: FC local port
- *
- * Returns non-zero if discovery cannot be started.
+ * @disc_callback: function to be called when discovery is complete
  */
 static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
 						enum fc_disc_event),
 			  struct fc_lport *lport)
 {
-	struct fc_rport *rport;
-	struct fc_rport_identifiers ids;
 	struct fc_disc *disc = &lport->disc;
 
 	/*
@@ -345,145 +256,47 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *,
 	 * and send the GPN_FT request.
 	 */
 	mutex_lock(&disc->disc_mutex);
-
 	disc->disc_callback = disc_callback;
-
-	/*
-	 * If not ready, or already running discovery, just set request flag.
-	 */
-	disc->requested = 1;
-
-	if (disc->pending) {
-		mutex_unlock(&disc->disc_mutex);
-		return;
-	}
-
-	/*
-	 * Handle point-to-point mode as a simple discovery
-	 * of the remote port. Yucky, yucky, yuck, yuck!
-	 */
-	rport = disc->lport->ptp_rp;
-	if (rport) {
-		ids.port_id = rport->port_id;
-		ids.port_name = rport->port_name;
-		ids.node_name = rport->node_name;
-		ids.roles = FC_RPORT_ROLE_UNKNOWN;
-		get_device(&rport->dev);
-
-		if (!fc_disc_new_target(disc, rport, &ids)) {
-			disc->event = DISC_EV_SUCCESS;
-			fc_disc_done(disc);
-		}
-		put_device(&rport->dev);
-	} else {
-		fc_disc_gpn_ft_req(disc);	/* get ports by FC-4 type */
-	}
-
+	fc_disc_restart(disc);
 	mutex_unlock(&disc->disc_mutex);
 }
 
-static struct fc_rport_operations fc_disc_rport_ops = {
-	.event_callback = fc_disc_rport_callback,
-};
-
-/**
- * fc_disc_new_target() - Handle new target found by discovery
- * @lport: FC local port
- * @rport: The previous FC remote port (NULL if new remote port)
- * @ids: Identifiers for the new FC remote port
- *
- * Locking Note: This function expects that the disc_mutex is locked
- *		 before it is called.
- */
-static int fc_disc_new_target(struct fc_disc *disc,
-			      struct fc_rport *rport,
-			      struct fc_rport_identifiers *ids)
-{
-	struct fc_lport *lport = disc->lport;
-	struct fc_rport_libfc_priv *rdata;
-	int error = 0;
-
-	if (rport && ids->port_name) {
-		if (rport->port_name == -1) {
-			/*
-			 * Set WWN and fall through to notify of create.
-			 */
-			fc_rport_set_name(rport, ids->port_name,
-					  rport->node_name);
-		} else if (rport->port_name != ids->port_name) {
-			/*
-			 * This is a new port with the same FCID as
-			 * a previously-discovered port.  Presumably the old
-			 * port logged out and a new port logged in and was
-			 * assigned the same FCID.  This should be rare.
-			 * Delete the old one and fall thru to re-create.
-			 */
-			fc_disc_del_target(disc, rport);
-			rport = NULL;
-		}
-	}
-	if (((ids->port_name != -1) || (ids->port_id != -1)) &&
-	    ids->port_id != fc_host_port_id(lport->host) &&
-	    ids->port_name != lport->wwpn) {
-		if (!rport) {
-			rport = lport->tt.rport_lookup(lport, ids->port_id);
-			if (!rport) {
-				struct fc_disc_port dp;
-				dp.lp = lport;
-				dp.ids.port_id = ids->port_id;
-				dp.ids.port_name = ids->port_name;
-				dp.ids.node_name = ids->node_name;
-				dp.ids.roles = ids->roles;
-				rport = lport->tt.rport_create(&dp);
-			}
-			if (!rport)
-				error = -ENOMEM;
-		}
-		if (rport) {
-			rdata = rport->dd_data;
-			rdata->ops = &fc_disc_rport_ops;
-			rdata->rp_state = RPORT_ST_INIT;
-			list_add_tail(&rdata->peers, &disc->rogue_rports);
-			lport->tt.rport_login(rport);
-		}
-	}
-	return error;
-}
-
-/**
- * fc_disc_del_target() - Delete a target
- * @disc: FC discovery context
- * @rport: The remote port to be removed
- */
-static void fc_disc_del_target(struct fc_disc *disc, struct fc_rport *rport)
-{
-	struct fc_lport *lport = disc->lport;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-	list_del(&rdata->peers);
-	lport->tt.rport_logoff(rport);
-}
-
 /**
  * fc_disc_done() - Discovery has been completed
  * @disc: FC discovery context
+ * @event: discovery completion status
+ *
  * Locking Note: This function expects that the disc mutex is locked before
  * it is called. The discovery callback is then made with the lock released,
  * and the lock is re-taken before returning from this function
  */
-static void fc_disc_done(struct fc_disc *disc)
+static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event)
 {
 	struct fc_lport *lport = disc->lport;
-	enum fc_disc_event event;
+	struct fc_rport_priv *rdata;
 
 	FC_DISC_DBG(disc, "Discovery complete\n");
 
-	event = disc->event;
-	disc->event = DISC_EV_NONE;
+	disc->pending = 0;
+	if (disc->requested) {
+		fc_disc_restart(disc);
+		return;
+	}
 
-	if (disc->requested)
-		fc_disc_gpn_ft_req(disc);
-	else
-		disc->pending = 0;
+	/*
+	 * Go through all remote ports.  If they were found in the latest
+	 * discovery, reverify or log them in.  Otherwise, log them out.
+	 * Skip ports which were never discovered.  These are the dNS port
+	 * and ports which were created by PLOGI.
+	 */
+	list_for_each_entry(rdata, &disc->rports, peers) {
+		if (!rdata->disc_id)
+			continue;
+		if (rdata->disc_id == disc->disc_id)
+			lport->tt.rport_login(rdata);
+		else
+			lport->tt.rport_logoff(rdata);
+	}
 
 	mutex_unlock(&disc->disc_mutex);
 	disc->disc_callback(lport, event);
@@ -522,11 +335,8 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp)
 			}
 			disc->retry_count++;
 			schedule_delayed_work(&disc->disc_work, delay);
-		} else {
-			/* exceeded retries */
-			disc->event = DISC_EV_FAILED;
-			fc_disc_done(disc);
-		}
+		} else
+			fc_disc_done(disc, DISC_EV_FAILED);
 	}
 }
 
@@ -555,7 +365,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc)
 	if (!fp)
 		goto err;
 
-	if (lport->tt.elsct_send(lport, NULL, fp,
+	if (lport->tt.elsct_send(lport, 0, fp,
 				 FC_NS_GPN_FT,
 				 fc_disc_gpn_ft_resp,
 				 disc, lport->e_d_tov))
@@ -565,10 +375,12 @@ err:
 }
 
 /**
- * fc_disc_gpn_ft_parse() - Parse the list of IDs and names resulting from a request
+ * fc_disc_gpn_ft_parse() - Parse the body of the dNS GPN_FT response.
  * @lport: Fibre Channel host port instance
  * @buf: GPN_FT response buffer
  * @len: size of response buffer
+ *
+ * Goes through the list of IDs and names resulting from a request.
  */
 static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
 {
@@ -578,11 +390,11 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
 	size_t plen;
 	size_t tlen;
 	int error = 0;
-	struct fc_disc_port dp;
-	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rdata;
+	struct fc_rport_identifiers ids;
+	struct fc_rport_priv *rdata;
 
 	lport = disc->lport;
+	disc->seq_count++;
 
 	/*
 	 * Handle partial name record left over from previous call.
@@ -591,6 +403,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
 	plen = len;
 	np = (struct fc_gpn_ft_resp *)bp;
 	tlen = disc->buf_len;
+	disc->buf_len = 0;
 	if (tlen) {
 		WARN_ON(tlen >= sizeof(*np));
 		plen = sizeof(*np) - tlen;
@@ -621,31 +434,25 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
 	 * After the first time through the loop, things return to "normal".
 	 */
 	while (plen >= sizeof(*np)) {
-		dp.lp = lport;
-		dp.ids.port_id = ntoh24(np->fp_fid);
-		dp.ids.port_name = ntohll(np->fp_wwpn);
-		dp.ids.node_name = -1;
-		dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
-
-		if ((dp.ids.port_id != fc_host_port_id(lport->host)) &&
-		    (dp.ids.port_name != lport->wwpn)) {
-			rport = lport->tt.rport_create(&dp);
-			if (rport) {
-				rdata = rport->dd_data;
-				rdata->ops = &fc_disc_rport_ops;
-				rdata->local_port = lport;
-				list_add_tail(&rdata->peers,
-					      &disc->rogue_rports);
-				lport->tt.rport_login(rport);
-			} else
+		ids.port_id = ntoh24(np->fp_fid);
+		ids.port_name = ntohll(np->fp_wwpn);
+
+		if (ids.port_id != fc_host_port_id(lport->host) &&
+		    ids.port_name != lport->wwpn) {
+			rdata = lport->tt.rport_create(lport, ids.port_id);
+			if (rdata) {
+				rdata->ids.port_name = ids.port_name;
+				rdata->disc_id = disc->disc_id;
+			} else {
 				printk(KERN_WARNING "libfc: Failed to allocate "
 				       "memory for the newly discovered port "
-				       "(%6x)\n", dp.ids.port_id);
+				       "(%6x)\n", ids.port_id);
+				error = -ENOMEM;
+			}
 		}
 
 		if (np->fp_flags & FC_NS_FID_LAST) {
-			disc->event = DISC_EV_SUCCESS;
-			fc_disc_done(disc);
+			fc_disc_done(disc, DISC_EV_SUCCESS);
 			len = 0;
 			break;
 		}
@@ -665,8 +472,6 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len)
 			memcpy(&disc->partial_buf, np, len);
 		}
 		disc->buf_len = (unsigned char) len;
-	} else {
-		disc->buf_len = 0;
 	}
 	return error;
 }
@@ -683,8 +488,7 @@ static void fc_disc_timeout(struct work_struct *work)
 					    struct fc_disc,
 					    disc_work.work);
 	mutex_lock(&disc->disc_mutex);
-	if (disc->requested && !disc->pending)
-		fc_disc_gpn_ft_req(disc);
+	fc_disc_gpn_ft_req(disc);
 	mutex_unlock(&disc->disc_mutex);
 }
 
@@ -703,10 +507,10 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
 	struct fc_disc *disc = disc_arg;
 	struct fc_ct_hdr *cp;
 	struct fc_frame_header *fh;
+	enum fc_disc_event event = DISC_EV_NONE;
 	unsigned int seq_cnt;
-	void *buf = NULL;
 	unsigned int len;
-	int error;
+	int error = 0;
 
 	mutex_lock(&disc->disc_mutex);
 	FC_DISC_DBG(disc, "Received a GPN_FT response\n");
@@ -721,77 +525,158 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp,
 	fh = fc_frame_header_get(fp);
 	len = fr_len(fp) - sizeof(*fh);
 	seq_cnt = ntohs(fh->fh_seq_cnt);
-	if (fr_sof(fp) == FC_SOF_I3 && seq_cnt == 0 &&
-	    disc->seq_count == 0) {
+	if (fr_sof(fp) == FC_SOF_I3 && seq_cnt == 0 && disc->seq_count == 0) {
 		cp = fc_frame_payload_get(fp, sizeof(*cp));
 		if (!cp) {
 			FC_DISC_DBG(disc, "GPN_FT response too short, len %d\n",
 				    fr_len(fp));
+			event = DISC_EV_FAILED;
 		} else if (ntohs(cp->ct_cmd) == FC_FS_ACC) {
 
 			/* Accepted, parse the response. */
-			buf = cp + 1;
 			len -= sizeof(*cp);
+			error = fc_disc_gpn_ft_parse(disc, cp + 1, len);
 		} else if (ntohs(cp->ct_cmd) == FC_FS_RJT) {
 			FC_DISC_DBG(disc, "GPN_FT rejected reason %x exp %x "
 				    "(check zoning)\n", cp->ct_reason,
 				    cp->ct_explan);
-			disc->event = DISC_EV_FAILED;
-			fc_disc_done(disc);
+			event = DISC_EV_FAILED;
+			if (cp->ct_reason == FC_FS_RJT_UNABL &&
+			    cp->ct_explan == FC_FS_EXP_FTNR)
+				event = DISC_EV_SUCCESS;
 		} else {
 			FC_DISC_DBG(disc, "GPN_FT unexpected response code "
 				    "%x\n", ntohs(cp->ct_cmd));
+			event = DISC_EV_FAILED;
 		}
-	} else if (fr_sof(fp) == FC_SOF_N3 &&
-		   seq_cnt == disc->seq_count) {
-		buf = fh + 1;
+	} else if (fr_sof(fp) == FC_SOF_N3 && seq_cnt == disc->seq_count) {
+		error = fc_disc_gpn_ft_parse(disc, fh + 1, len);
 	} else {
 		FC_DISC_DBG(disc, "GPN_FT unexpected frame - out of sequence? "
 			    "seq_cnt %x expected %x sof %x eof %x\n",
 			    seq_cnt, disc->seq_count, fr_sof(fp), fr_eof(fp));
+		event = DISC_EV_FAILED;
 	}
-	if (buf) {
-		error = fc_disc_gpn_ft_parse(disc, buf, len);
-		if (error)
-			fc_disc_error(disc, fp);
-		else
-			disc->seq_count++;
-	}
+	if (error)
+		fc_disc_error(disc, fp);
+	else if (event != DISC_EV_NONE)
+		fc_disc_done(disc, event);
 	fc_frame_free(fp);
-
 	mutex_unlock(&disc->disc_mutex);
 }
 
 /**
- * fc_disc_single() - Discover the directory information for a single target
- * @lport: FC local port
- * @dp: The port to rediscover
+ * fc_disc_gpn_id_resp() - Handle a response frame from Get Port Names (GPN_ID)
+ * @sp: exchange sequence
+ * @fp: response frame
+ * @rdata_arg: remote port private data
  *
- * Locking Note: This function expects that the disc_mutex is locked
- *		 before it is called.
+ * Locking Note: This function is called without disc mutex held.
  */
-static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp)
+static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
+				void *rdata_arg)
 {
+	struct fc_rport_priv *rdata = rdata_arg;
+	struct fc_rport_priv *new_rdata;
 	struct fc_lport *lport;
-	struct fc_rport *new_rport;
-	struct fc_rport_libfc_priv *rdata;
+	struct fc_disc *disc;
+	struct fc_ct_hdr *cp;
+	struct fc_ns_gid_pn *pn;
+	u64 port_name;
 
-	lport = disc->lport;
+	lport = rdata->local_port;
+	disc = &lport->disc;
 
-	if (dp->ids.port_id == fc_host_port_id(lport->host))
+	mutex_lock(&disc->disc_mutex);
+	if (PTR_ERR(fp) == -FC_EX_CLOSED)
 		goto out;
-
-	new_rport = lport->tt.rport_create(dp);
-	if (new_rport) {
-		rdata = new_rport->dd_data;
-		rdata->ops = &fc_disc_rport_ops;
-		kfree(dp);
-		list_add_tail(&rdata->peers, &disc->rogue_rports);
-		lport->tt.rport_login(new_rport);
+	if (IS_ERR(fp))
+		goto redisc;
+
+	cp = fc_frame_payload_get(fp, sizeof(*cp));
+	if (!cp)
+		goto redisc;
+	if (ntohs(cp->ct_cmd) == FC_FS_ACC) {
+		if (fr_len(fp) < sizeof(struct fc_frame_header) +
+		    sizeof(*cp) + sizeof(*pn))
+			goto redisc;
+		pn = (struct fc_ns_gid_pn *)(cp + 1);
+		port_name = get_unaligned_be64(&pn->fn_wwpn);
+		if (rdata->ids.port_name == -1)
+			rdata->ids.port_name = port_name;
+		else if (rdata->ids.port_name != port_name) {
+			FC_DISC_DBG(disc, "GPN_ID accepted.  WWPN changed. "
+				    "Port-id %x wwpn %llx\n",
+				    rdata->ids.port_id, port_name);
+			lport->tt.rport_logoff(rdata);
+
+			new_rdata = lport->tt.rport_create(lport,
+							   rdata->ids.port_id);
+			if (new_rdata) {
+				new_rdata->disc_id = disc->disc_id;
+				lport->tt.rport_login(new_rdata);
+			}
+			goto out;
+		}
+		rdata->disc_id = disc->disc_id;
+		lport->tt.rport_login(rdata);
+	} else if (ntohs(cp->ct_cmd) == FC_FS_RJT) {
+		FC_DISC_DBG(disc, "GPN_ID rejected reason %x exp %x\n",
+			    cp->ct_reason, cp->ct_explan);
+		lport->tt.rport_logoff(rdata);
+	} else {
+		FC_DISC_DBG(disc, "GPN_ID unexpected response code %x\n",
+			    ntohs(cp->ct_cmd));
+redisc:
+		fc_disc_restart(disc);
 	}
-	return;
 out:
-	kfree(dp);
+	mutex_unlock(&disc->disc_mutex);
+	kref_put(&rdata->kref, lport->tt.rport_destroy);
+}
+
+/**
+ * fc_disc_gpn_id_req() - Send Get Port Names by ID (GPN_ID) request
+ * @lport: local port
+ * @rdata: remote port private data
+ *
+ * Locking Note: This function expects that the disc_mutex is locked
+ *		 before it is called.
+ * On failure, an error code is returned.
+ */
+static int fc_disc_gpn_id_req(struct fc_lport *lport,
+			      struct fc_rport_priv *rdata)
+{
+	struct fc_frame *fp;
+
+	fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
+			    sizeof(struct fc_ns_fid));
+	if (!fp)
+		return -ENOMEM;
+	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, FC_NS_GPN_ID,
+				 fc_disc_gpn_id_resp, rdata, lport->e_d_tov))
+		return -ENOMEM;
+	kref_get(&rdata->kref);
+	return 0;
+}
+
+/**
+ * fc_disc_single() - Discover the directory information for a single target
+ * @lport: local port
+ * @dp: The port to rediscover
+ *
+ * Locking Note: This function expects that the disc_mutex is locked
+ *		 before it is called.
+ */
+static int fc_disc_single(struct fc_lport *lport, struct fc_disc_port *dp)
+{
+	struct fc_rport_priv *rdata;
+
+	rdata = lport->tt.rport_create(lport, dp->port_id);
+	if (!rdata)
+		return -ENOMEM;
+	rdata->disc_id = 0;
+	return fc_disc_gpn_id_req(lport, rdata);
 }
 
 /**
@@ -841,18 +726,12 @@ int fc_disc_init(struct fc_lport *lport)
 	if (!lport->tt.disc_recv_req)
 		lport->tt.disc_recv_req = fc_disc_recv_req;
 
-	if (!lport->tt.rport_lookup)
-		lport->tt.rport_lookup = fc_disc_lookup_rport;
-
 	disc = &lport->disc;
 	INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout);
 	mutex_init(&disc->disc_mutex);
 	INIT_LIST_HEAD(&disc->rports);
-	INIT_LIST_HEAD(&disc->rogue_rports);
 
 	disc->lport = lport;
-	disc->delay = FC_DISC_DELAY;
-	disc->event = DISC_EV_NONE;
 
 	return 0;
 }
diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c
index 5878b34..5cfa687 100644
--- a/drivers/scsi/libfc/fc_elsct.c
+++ b/drivers/scsi/libfc/fc_elsct.c
@@ -32,7 +32,7 @@
  * fc_elsct_send - sends ELS/CT frame
  */
 static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
-				    struct fc_rport *rport,
+				    u32 did,
 				    struct fc_frame *fp,
 				    unsigned int op,
 				    void (*resp)(struct fc_seq *,
@@ -41,16 +41,17 @@ static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
 				    void *arg, u32 timer_msec)
 {
 	enum fc_rctl r_ctl;
-	u32 did = FC_FID_NONE;
 	enum fc_fh_type fh_type;
 	int rc;
 
 	/* ELS requests */
 	if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS))
-		rc = fc_els_fill(lport, rport, fp, op, &r_ctl, &did, &fh_type);
-	else
+		rc = fc_els_fill(lport, did, fp, op, &r_ctl, &fh_type);
+	else {
 		/* CT requests */
-		rc = fc_ct_fill(lport, fp, op, &r_ctl, &did, &fh_type);
+		rc = fc_ct_fill(lport, did, fp, op, &r_ctl, &fh_type);
+		did = FC_FID_DIR_SERV;
+	}
 
 	if (rc)
 		return NULL;
@@ -69,3 +70,41 @@ int fc_elsct_init(struct fc_lport *lport)
 	return 0;
 }
 EXPORT_SYMBOL(fc_elsct_init);
+
+/**
+ * fc_els_resp_type() - return string describing ELS response for debug.
+ * @fp: frame pointer with possible error code.
+ */
+const char *fc_els_resp_type(struct fc_frame *fp)
+{
+	const char *msg;
+	if (IS_ERR(fp)) {
+		switch (-PTR_ERR(fp)) {
+		case FC_NO_ERR:
+			msg = "response no error";
+			break;
+		case FC_EX_TIMEOUT:
+			msg = "response timeout";
+			break;
+		case FC_EX_CLOSED:
+			msg = "response closed";
+			break;
+		default:
+			msg = "response unknown error";
+			break;
+		}
+	} else {
+		switch (fc_frame_payload_op(fp)) {
+		case ELS_LS_ACC:
+			msg = "accept";
+			break;
+		case ELS_LS_RJT:
+			msg = "reject";
+			break;
+		default:
+			msg = "response unknown ELS";
+			break;
+		}
+	}
+	return msg;
+}
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 145ab9b..c1c1574 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -32,6 +32,9 @@
 #include <scsi/libfc.h>
 #include <scsi/fc_encode.h>
 
+u16	fc_cpu_mask;		/* cpu mask for possible cpus */
+EXPORT_SYMBOL(fc_cpu_mask);
+static u16	fc_cpu_order;	/* 2's power to represent total possible cpus */
 static struct kmem_cache *fc_em_cachep;        /* cache for exchanges */
 
 /*
@@ -48,6 +51,20 @@ static struct kmem_cache *fc_em_cachep;        /* cache for exchanges */
  */
 
 /*
+ * Per cpu exchange pool
+ *
+ * This structure manages per cpu exchanges in array of exchange pointers.
+ * This array is allocated followed by struct fc_exch_pool memory for
+ * assigned range of exchanges to per cpu pool.
+ */
+struct fc_exch_pool {
+	u16		next_index;	/* next possible free exchange index */
+	u16		total_exches;	/* total allocated exchanges */
+	spinlock_t	lock;		/* exch pool lock */
+	struct list_head	ex_list;	/* allocated exchanges list */
+};
+
+/*
  * Exchange manager.
  *
  * This structure is the center for creating exchanges and sequences.
@@ -55,17 +72,13 @@ static struct kmem_cache *fc_em_cachep;        /* cache for exchanges */
  */
 struct fc_exch_mgr {
 	enum fc_class	class;		/* default class for sequences */
-	spinlock_t	em_lock;	/* exchange manager lock,
-					   must be taken before ex_lock */
-	u16		last_xid;	/* last allocated exchange ID */
+	struct kref	kref;		/* exchange mgr reference count */
 	u16		min_xid;	/* min exchange ID */
 	u16		max_xid;	/* max exchange ID */
-	u16		max_read;	/* max exchange ID for read */
-	u16		last_read;	/* last xid allocated for read */
-	u32	total_exches;		/* total allocated exchanges */
 	struct list_head	ex_list;	/* allocated exchanges list */
-	struct fc_lport	*lp;		/* fc device instance */
 	mempool_t	*ep_pool;	/* reserve ep's */
+	u16		pool_max_index;	/* max exch array index in exch pool */
+	struct fc_exch_pool *pool;	/* per cpu exch pool */
 
 	/*
 	 * currently exchange mgr stats are updated but not used.
@@ -80,10 +93,15 @@ struct fc_exch_mgr {
 		atomic_t seq_not_found;
 		atomic_t non_bls_resp;
 	} stats;
-	struct fc_exch **exches;	/* for exch pointers indexed by xid */
 };
 #define	fc_seq_exch(sp) container_of(sp, struct fc_exch, seq)
 
+struct fc_exch_mgr_anchor {
+	struct list_head ema_list;
+	struct fc_exch_mgr *mp;
+	bool (*match)(struct fc_frame *);
+};
+
 static void fc_exch_rrq(struct fc_exch *);
 static void fc_seq_ls_acc(struct fc_seq *);
 static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason,
@@ -167,8 +185,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp);
  * sequence allocation and deallocation must be locked.
  *  - exchange refcnt can be done atomicly without locks.
  *  - sequence allocation must be locked by exch lock.
- *  - If the em_lock and ex_lock must be taken at the same time, then the
- *    em_lock must be taken before the ex_lock.
+ *  - If the EM pool lock and ex_lock must be taken at the same time, then the
+ *    EM pool lock must be taken before the ex_lock.
  */
 
 /*
@@ -268,8 +286,6 @@ static void fc_exch_release(struct fc_exch *ep)
 		mp = ep->em;
 		if (ep->destructor)
 			ep->destructor(&ep->seq, ep->arg);
-		if (ep->lp->tt.exch_put)
-			ep->lp->tt.exch_put(ep->lp, mp, ep->xid);
 		WARN_ON(!(ep->esb_stat & ESB_ST_COMPLETE));
 		mempool_free(ep, mp->ep_pool);
 	}
@@ -299,17 +315,31 @@ static int fc_exch_done_locked(struct fc_exch *ep)
 	return rc;
 }
 
-static void fc_exch_mgr_delete_ep(struct fc_exch *ep)
+static inline struct fc_exch *fc_exch_ptr_get(struct fc_exch_pool *pool,
+					      u16 index)
 {
-	struct fc_exch_mgr *mp;
+	struct fc_exch **exches = (struct fc_exch **)(pool + 1);
+	return exches[index];
+}
 
-	mp = ep->em;
-	spin_lock_bh(&mp->em_lock);
-	WARN_ON(mp->total_exches <= 0);
-	mp->total_exches--;
-	mp->exches[ep->xid - mp->min_xid] = NULL;
+static inline void fc_exch_ptr_set(struct fc_exch_pool *pool, u16 index,
+				   struct fc_exch *ep)
+{
+	((struct fc_exch **)(pool + 1))[index] = ep;
+}
+
+static void fc_exch_delete(struct fc_exch *ep)
+{
+	struct fc_exch_pool *pool;
+
+	pool = ep->pool;
+	spin_lock_bh(&pool->lock);
+	WARN_ON(pool->total_exches <= 0);
+	pool->total_exches--;
+	fc_exch_ptr_set(pool, (ep->xid - ep->em->min_xid) >> fc_cpu_order,
+			NULL);
 	list_del(&ep->ex_list);
-	spin_unlock_bh(&mp->em_lock);
+	spin_unlock_bh(&pool->lock);
 	fc_exch_release(ep);	/* drop hold for exch in mp */
 }
 
@@ -322,7 +352,7 @@ static inline void fc_exch_timer_set_locked(struct fc_exch *ep,
 	if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
 		return;
 
-	FC_EXCH_DBG(ep, "Exchange timed out, notifying the upper layer\n");
+	FC_EXCH_DBG(ep, "Exchange timer armed\n");
 
 	if (schedule_delayed_work(&ep->timeout_work,
 				  msecs_to_jiffies(timer_msec)))
@@ -408,6 +438,8 @@ static void fc_exch_timeout(struct work_struct *work)
 	u32 e_stat;
 	int rc = 1;
 
+	FC_EXCH_DBG(ep, "Exchange timed out\n");
+
 	spin_lock_bh(&ep->ex_lock);
 	if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE))
 		goto unlock;
@@ -427,7 +459,7 @@ static void fc_exch_timeout(struct work_struct *work)
 			rc = fc_exch_done_locked(ep);
 		spin_unlock_bh(&ep->ex_lock);
 		if (!rc)
-			fc_exch_mgr_delete_ep(ep);
+			fc_exch_delete(ep);
 		if (resp)
 			resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg);
 		fc_seq_exch_abort(sp, 2 * ep->r_a_tov);
@@ -460,65 +492,20 @@ static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id)
 	return sp;
 }
 
-/*
- * fc_em_alloc_xid - returns an xid based on request type
- * @lp : ptr to associated lport
- * @fp : ptr to the assocated frame
+/**
+ * fc_exch_em_alloc() - allocate an exchange from a specified EM.
+ * @lport:	ptr to the local port
+ * @mp:		ptr to the exchange manager
  *
- * check the associated fc_fsp_pkt to get scsi command type and
- * command direction to decide from which range this exch id
- * will be allocated from.
- *
- * Returns : 0 or an valid xid
+ * Returns pointer to allocated fc_exch with exch lock held.
  */
-static u16 fc_em_alloc_xid(struct fc_exch_mgr *mp, const struct fc_frame *fp)
-{
-	u16 xid, min, max;
-	u16 *plast;
-	struct fc_exch *ep = NULL;
-
-	if (mp->max_read) {
-		if (fc_fcp_is_read(fr_fsp(fp))) {
-			min = mp->min_xid;
-			max = mp->max_read;
-			plast = &mp->last_read;
-		} else {
-			min = mp->max_read + 1;
-			max = mp->max_xid;
-			plast = &mp->last_xid;
-		}
-	} else {
-		min = mp->min_xid;
-		max = mp->max_xid;
-		plast = &mp->last_xid;
-	}
-	xid = *plast;
-	do {
-		xid = (xid == max) ? min : xid + 1;
-		ep = mp->exches[xid - mp->min_xid];
-	} while ((ep != NULL) && (xid != *plast));
-
-	if (unlikely(ep))
-		xid = 0;
-	else
-		*plast = xid;
-
-	return xid;
-}
-
-/*
- * fc_exch_alloc - allocate an exchange.
- * @mp : ptr to the exchange manager
- * @xid: input xid
- *
- * if xid is supplied zero then assign next free exchange ID
- * from exchange manager, otherwise use supplied xid.
- * Returns with exch lock held.
- */
-struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
-			      struct fc_frame *fp, u16 xid)
+static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport,
+					struct fc_exch_mgr *mp)
 {
 	struct fc_exch *ep;
+	unsigned int cpu;
+	u16 index;
+	struct fc_exch_pool *pool;
 
 	/* allocate memory for exchange */
 	ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC);
@@ -528,16 +515,17 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
 	}
 	memset(ep, 0, sizeof(*ep));
 
-	spin_lock_bh(&mp->em_lock);
-	/* alloc xid if input xid 0 */
-	if (!xid) {
-		/* alloc a new xid */
-		xid = fc_em_alloc_xid(mp, fp);
-		if (!xid) {
-			printk(KERN_WARNING "libfc: Failed to allocate an exhange\n");
+	cpu = smp_processor_id();
+	pool = per_cpu_ptr(mp->pool, cpu);
+	spin_lock_bh(&pool->lock);
+	index = pool->next_index;
+	/* allocate new exch from pool */
+	while (fc_exch_ptr_get(pool, index)) {
+		index = index == mp->pool_max_index ? 0 : index + 1;
+		if (index == pool->next_index)
 			goto err;
-		}
 	}
+	pool->next_index = index == mp->pool_max_index ? 0 : index + 1;
 
 	fc_exch_hold(ep);	/* hold for exch in mp */
 	spin_lock_init(&ep->ex_lock);
@@ -548,18 +536,19 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
 	 */
 	spin_lock_bh(&ep->ex_lock);
 
-	mp->exches[xid - mp->min_xid] = ep;
-	list_add_tail(&ep->ex_list, &mp->ex_list);
+	fc_exch_ptr_set(pool, index, ep);
+	list_add_tail(&ep->ex_list, &pool->ex_list);
 	fc_seq_alloc(ep, ep->seq_id++);
-	mp->total_exches++;
-	spin_unlock_bh(&mp->em_lock);
+	pool->total_exches++;
+	spin_unlock_bh(&pool->lock);
 
 	/*
 	 *  update exchange
 	 */
-	ep->oxid = ep->xid = xid;
+	ep->oxid = ep->xid = (index << fc_cpu_order | cpu) + mp->min_xid;
 	ep->em = mp;
-	ep->lp = mp->lp;
+	ep->pool = pool;
+	ep->lp = lport;
 	ep->f_ctl = FC_FC_FIRST_SEQ;	/* next seq is first seq */
 	ep->rxid = FC_XID_UNKNOWN;
 	ep->class = mp->class;
@@ -567,11 +556,36 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
 out:
 	return ep;
 err:
-	spin_unlock_bh(&mp->em_lock);
+	spin_unlock_bh(&pool->lock);
 	atomic_inc(&mp->stats.no_free_exch_xid);
 	mempool_free(ep, mp->ep_pool);
 	return NULL;
 }
+
+/**
+ * fc_exch_alloc() - allocate an exchange.
+ * @lport:	ptr to the local port
+ * @fp:		ptr to the FC frame
+ *
+ * This function walks the list of the exchange manager(EM)
+ * anchors to select a EM for new exchange allocation. The
+ * EM is selected having either a NULL match function pointer
+ * or call to match function returning true.
+ */
+struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp)
+{
+	struct fc_exch_mgr_anchor *ema;
+	struct fc_exch *ep;
+
+	list_for_each_entry(ema, &lport->ema_list, ema_list) {
+		if (!ema->match || ema->match(fp)) {
+			ep = fc_exch_em_alloc(lport, ema->mp);
+			if (ep)
+				return ep;
+		}
+	}
+	return NULL;
+}
 EXPORT_SYMBOL(fc_exch_alloc);
 
 /*
@@ -579,16 +593,18 @@ EXPORT_SYMBOL(fc_exch_alloc);
  */
 static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid)
 {
+	struct fc_exch_pool *pool;
 	struct fc_exch *ep = NULL;
 
 	if ((xid >= mp->min_xid) && (xid <= mp->max_xid)) {
-		spin_lock_bh(&mp->em_lock);
-		ep = mp->exches[xid - mp->min_xid];
+		pool = per_cpu_ptr(mp->pool, xid & fc_cpu_mask);
+		spin_lock_bh(&pool->lock);
+		ep = fc_exch_ptr_get(pool, (xid - mp->min_xid) >> fc_cpu_order);
 		if (ep) {
 			fc_exch_hold(ep);
 			WARN_ON(ep->xid != xid);
 		}
-		spin_unlock_bh(&mp->em_lock);
+		spin_unlock_bh(&pool->lock);
 	}
 	return ep;
 }
@@ -602,7 +618,7 @@ void fc_exch_done(struct fc_seq *sp)
 	rc = fc_exch_done_locked(ep);
 	spin_unlock_bh(&ep->ex_lock);
 	if (!rc)
-		fc_exch_mgr_delete_ep(ep);
+		fc_exch_delete(ep);
 }
 EXPORT_SYMBOL(fc_exch_done);
 
@@ -610,12 +626,14 @@ EXPORT_SYMBOL(fc_exch_done);
  * Allocate a new exchange as responder.
  * Sets the responder ID in the frame header.
  */
-static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
+static struct fc_exch *fc_exch_resp(struct fc_lport *lport,
+				    struct fc_exch_mgr *mp,
+				    struct fc_frame *fp)
 {
 	struct fc_exch *ep;
 	struct fc_frame_header *fh;
 
-	ep = mp->lp->tt.exch_get(mp->lp, fp);
+	ep = fc_exch_alloc(lport, fp);
 	if (ep) {
 		ep->class = fc_frame_class(fp);
 
@@ -641,7 +659,7 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 			ep->esb_stat &= ~ESB_ST_SEQ_INIT;
 
 		fc_exch_hold(ep);	/* hold for caller */
-		spin_unlock_bh(&ep->ex_lock);	/* lock from exch_get */
+		spin_unlock_bh(&ep->ex_lock);	/* lock from fc_exch_alloc */
 	}
 	return ep;
 }
@@ -651,7 +669,8 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
  * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold
  * on the ep that should be released by the caller.
  */
-static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp,
+static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_lport *lport,
+						 struct fc_exch_mgr *mp,
 						 struct fc_frame *fp)
 {
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
@@ -705,7 +724,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp,
 				reject = FC_RJT_RX_ID;
 				goto rel;
 			}
-			ep = fc_exch_resp(mp, fp);
+			ep = fc_exch_resp(lport, mp, fp);
 			if (!ep) {
 				reject = FC_RJT_EXCH_EST;	/* XXX */
 				goto out;
@@ -822,7 +841,6 @@ struct fc_seq *fc_seq_start_next(struct fc_seq *sp)
 	struct fc_exch *ep = fc_seq_exch(sp);
 
 	spin_lock_bh(&ep->ex_lock);
-	WARN_ON((ep->esb_stat & ESB_ST_COMPLETE) != 0);
 	sp = fc_seq_start_next_locked(sp);
 	spin_unlock_bh(&ep->ex_lock);
 
@@ -999,8 +1017,8 @@ static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp,
 	 */
 	memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3);
 	memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3);
-	fh->fh_ox_id = rx_fh->fh_rx_id;
-	fh->fh_rx_id = rx_fh->fh_ox_id;
+	fh->fh_ox_id = rx_fh->fh_ox_id;
+	fh->fh_rx_id = rx_fh->fh_rx_id;
 	fh->fh_seq_cnt = rx_fh->fh_seq_cnt;
 	fh->fh_r_ctl = FC_RCTL_BA_RJT;
 	fh->fh_type = FC_TYPE_BLS;
@@ -1097,7 +1115,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
 	enum fc_pf_rjt_reason reject;
 
 	fr_seq(fp) = NULL;
-	reject = fc_seq_lookup_recip(mp, fp);
+	reject = fc_seq_lookup_recip(lp, mp, fp);
 	if (reject == FC_RJT_NONE) {
 		sp = fr_seq(fp);	/* sequence will be held */
 		ep = fc_seq_exch(sp);
@@ -1123,7 +1141,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp,
 			lp->tt.lport_recv(lp, sp, fp);
 		fc_exch_release(ep);	/* release from lookup */
 	} else {
-		FC_EM_DBG(mp, "exch/seq lookup failed: reject %x\n", reject);
+		FC_LPORT_DBG(lp, "exch/seq lookup failed: reject %x\n", reject);
 		fc_frame_free(fp);
 	}
 }
@@ -1193,7 +1211,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 		WARN_ON(fc_seq_exch(sp) != ep);
 		spin_unlock_bh(&ep->ex_lock);
 		if (!rc)
-			fc_exch_mgr_delete_ep(ep);
+			fc_exch_delete(ep);
 	}
 
 	/*
@@ -1229,13 +1247,12 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp)
 	struct fc_seq *sp;
 
 	sp = fc_seq_lookup_orig(mp, fp);	/* doesn't hold sequence */
-	if (!sp) {
+
+	if (!sp)
 		atomic_inc(&mp->stats.xid_not_found);
-		FC_EM_DBG(mp, "seq lookup failed\n");
-	} else {
+	else
 		atomic_inc(&mp->stats.non_bls_resp);
-		FC_EM_DBG(mp, "non-BLS response to sequence");
-	}
+
 	fc_frame_free(fp);
 }
 
@@ -1304,7 +1321,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp)
 		rc = fc_exch_done_locked(ep);
 	spin_unlock_bh(&ep->ex_lock);
 	if (!rc)
-		fc_exch_mgr_delete_ep(ep);
+		fc_exch_delete(ep);
 
 	if (resp)
 		resp(sp, fp, ex_resp_arg);
@@ -1447,44 +1464,77 @@ static void fc_exch_reset(struct fc_exch *ep)
 	rc = fc_exch_done_locked(ep);
 	spin_unlock_bh(&ep->ex_lock);
 	if (!rc)
-		fc_exch_mgr_delete_ep(ep);
+		fc_exch_delete(ep);
 
 	if (resp)
 		resp(sp, ERR_PTR(-FC_EX_CLOSED), arg);
 }
 
-/*
- * Reset an exchange manager, releasing all sequences and exchanges.
- * If sid is non-zero, reset only exchanges we source from that FID.
- * If did is non-zero, reset only exchanges destined to that FID.
+/**
+ * fc_exch_pool_reset() - Resets an per cpu exches pool.
+ * @lport:	ptr to the local port
+ * @pool:	ptr to the per cpu exches pool
+ * @sid:	source FC ID
+ * @did:	destination FC ID
+ *
+ * Resets an per cpu exches pool, releasing its all sequences
+ * and exchanges. If sid is non-zero, then reset only exchanges
+ * we sourced from that FID. If did is non-zero, reset only
+ * exchanges destined to that FID.
  */
-void fc_exch_mgr_reset(struct fc_lport *lp, u32 sid, u32 did)
+static void fc_exch_pool_reset(struct fc_lport *lport,
+			       struct fc_exch_pool *pool,
+			       u32 sid, u32 did)
 {
 	struct fc_exch *ep;
 	struct fc_exch *next;
-	struct fc_exch_mgr *mp = lp->emp;
 
-	spin_lock_bh(&mp->em_lock);
+	spin_lock_bh(&pool->lock);
 restart:
-	list_for_each_entry_safe(ep, next, &mp->ex_list, ex_list) {
-		if ((sid == 0 || sid == ep->sid) &&
+	list_for_each_entry_safe(ep, next, &pool->ex_list, ex_list) {
+		if ((lport == ep->lp) &&
+		    (sid == 0 || sid == ep->sid) &&
 		    (did == 0 || did == ep->did)) {
 			fc_exch_hold(ep);
-			spin_unlock_bh(&mp->em_lock);
+			spin_unlock_bh(&pool->lock);
 
 			fc_exch_reset(ep);
 
 			fc_exch_release(ep);
-			spin_lock_bh(&mp->em_lock);
+			spin_lock_bh(&pool->lock);
 
 			/*
-			 * must restart loop incase while lock was down
-			 * multiple eps were released.
+			 * must restart loop incase while lock
+			 * was down multiple eps were released.
 			 */
 			goto restart;
 		}
 	}
-	spin_unlock_bh(&mp->em_lock);
+	spin_unlock_bh(&pool->lock);
+}
+
+/**
+ * fc_exch_mgr_reset() - Resets all EMs of a lport
+ * @lport:	ptr to the local port
+ * @sid:	source FC ID
+ * @did:	destination FC ID
+ *
+ * Reset all EMs of a lport, releasing its all sequences and
+ * exchanges. If sid is non-zero, then reset only exchanges
+ * we sourced from that FID. If did is non-zero, reset only
+ * exchanges destined to that FID.
+ */
+void fc_exch_mgr_reset(struct fc_lport *lport, u32 sid, u32 did)
+{
+	struct fc_exch_mgr_anchor *ema;
+	unsigned int cpu;
+
+	list_for_each_entry(ema, &lport->ema_list, ema_list) {
+		for_each_possible_cpu(cpu)
+			fc_exch_pool_reset(lport,
+					   per_cpu_ptr(ema->mp->pool, cpu),
+					   sid, did);
+	}
 }
 EXPORT_SYMBOL(fc_exch_mgr_reset);
 
@@ -1730,85 +1780,129 @@ reject:
 	fc_frame_free(fp);
 }
 
+struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
+					   struct fc_exch_mgr *mp,
+					   bool (*match)(struct fc_frame *))
+{
+	struct fc_exch_mgr_anchor *ema;
+
+	ema = kmalloc(sizeof(*ema), GFP_ATOMIC);
+	if (!ema)
+		return ema;
+
+	ema->mp = mp;
+	ema->match = match;
+	/* add EM anchor to EM anchors list */
+	list_add_tail(&ema->ema_list, &lport->ema_list);
+	kref_get(&mp->kref);
+	return ema;
+}
+EXPORT_SYMBOL(fc_exch_mgr_add);
+
+static void fc_exch_mgr_destroy(struct kref *kref)
+{
+	struct fc_exch_mgr *mp = container_of(kref, struct fc_exch_mgr, kref);
+
+	mempool_destroy(mp->ep_pool);
+	free_percpu(mp->pool);
+	kfree(mp);
+}
+
+void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema)
+{
+	/* remove EM anchor from EM anchors list */
+	list_del(&ema->ema_list);
+	kref_put(&ema->mp->kref, fc_exch_mgr_destroy);
+	kfree(ema);
+}
+EXPORT_SYMBOL(fc_exch_mgr_del);
+
 struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
 				      enum fc_class class,
-				      u16 min_xid, u16 max_xid)
+				      u16 min_xid, u16 max_xid,
+				      bool (*match)(struct fc_frame *))
 {
 	struct fc_exch_mgr *mp;
-	size_t len;
+	u16 pool_exch_range;
+	size_t pool_size;
+	unsigned int cpu;
+	struct fc_exch_pool *pool;
 
-	if (max_xid <= min_xid || min_xid == 0 || max_xid == FC_XID_UNKNOWN) {
+	if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN ||
+	    (min_xid & fc_cpu_mask) != 0) {
 		FC_LPORT_DBG(lp, "Invalid min_xid 0x:%x and max_xid 0x:%x\n",
 			     min_xid, max_xid);
 		return NULL;
 	}
 
 	/*
-	 * Memory need for EM
+	 * allocate memory for EM
 	 */
-#define xid_ok(i, m1, m2) (((i) >= (m1)) && ((i) <= (m2)))
-	len = (max_xid - min_xid + 1) * (sizeof(struct fc_exch *));
-	len += sizeof(struct fc_exch_mgr);
-
-	mp = kzalloc(len, GFP_ATOMIC);
+	mp = kzalloc(sizeof(struct fc_exch_mgr), GFP_ATOMIC);
 	if (!mp)
 		return NULL;
 
 	mp->class = class;
-	mp->total_exches = 0;
-	mp->exches = (struct fc_exch **)(mp + 1);
-	mp->lp = lp;
 	/* adjust em exch xid range for offload */
 	mp->min_xid = min_xid;
 	mp->max_xid = max_xid;
-	mp->last_xid = min_xid - 1;
-	mp->max_read = 0;
-	mp->last_read = 0;
-	if (lp->lro_enabled && xid_ok(lp->lro_xid, min_xid, max_xid)) {
-		mp->max_read = lp->lro_xid;
-		mp->last_read = min_xid - 1;
-		mp->last_xid = mp->max_read;
-	} else {
-		/* disable lro if no xid control over read */
-		lp->lro_enabled = 0;
-	}
-
-	INIT_LIST_HEAD(&mp->ex_list);
-	spin_lock_init(&mp->em_lock);
 
 	mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep);
 	if (!mp->ep_pool)
 		goto free_mp;
 
+	/*
+	 * Setup per cpu exch pool with entire exchange id range equally
+	 * divided across all cpus. The exch pointers array memory is
+	 * allocated for exch range per pool.
+	 */
+	pool_exch_range = (mp->max_xid - mp->min_xid + 1) / (fc_cpu_mask + 1);
+	mp->pool_max_index = pool_exch_range - 1;
+
+	/*
+	 * Allocate and initialize per cpu exch pool
+	 */
+	pool_size = sizeof(*pool) + pool_exch_range * sizeof(struct fc_exch *);
+	mp->pool = __alloc_percpu(pool_size, __alignof__(struct fc_exch_pool));
+	if (!mp->pool)
+		goto free_mempool;
+	for_each_possible_cpu(cpu) {
+		pool = per_cpu_ptr(mp->pool, cpu);
+		spin_lock_init(&pool->lock);
+		INIT_LIST_HEAD(&pool->ex_list);
+	}
+
+	kref_init(&mp->kref);
+	if (!fc_exch_mgr_add(lp, mp, match)) {
+		free_percpu(mp->pool);
+		goto free_mempool;
+	}
+
+	/*
+	 * Above kref_init() sets mp->kref to 1 and then
+	 * call to fc_exch_mgr_add incremented mp->kref again,
+	 * so adjust that extra increment.
+	 */
+	kref_put(&mp->kref, fc_exch_mgr_destroy);
 	return mp;
 
+free_mempool:
+	mempool_destroy(mp->ep_pool);
 free_mp:
 	kfree(mp);
 	return NULL;
 }
 EXPORT_SYMBOL(fc_exch_mgr_alloc);
 
-void fc_exch_mgr_free(struct fc_exch_mgr *mp)
+void fc_exch_mgr_free(struct fc_lport *lport)
 {
-	WARN_ON(!mp);
-	/*
-	 * The total exch count must be zero
-	 * before freeing exchange manager.
-	 */
-	WARN_ON(mp->total_exches != 0);
-	mempool_destroy(mp->ep_pool);
-	kfree(mp);
+	struct fc_exch_mgr_anchor *ema, *next;
+
+	list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list)
+		fc_exch_mgr_del(ema);
 }
 EXPORT_SYMBOL(fc_exch_mgr_free);
 
-struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp)
-{
-	if (!lp || !lp->emp)
-		return NULL;
-
-	return fc_exch_alloc(lp->emp, fp, 0);
-}
-EXPORT_SYMBOL(fc_exch_get);
 
 struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
 				struct fc_frame *fp,
@@ -1823,7 +1917,7 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
 	struct fc_frame_header *fh;
 	int rc = 1;
 
-	ep = lp->tt.exch_get(lp, fp);
+	ep = fc_exch_alloc(lp, fp);
 	if (!ep) {
 		fc_frame_free(fp);
 		return NULL;
@@ -1843,7 +1937,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp,
 	fc_exch_setup_hdr(ep, fp, ep->f_ctl);
 	sp->cnt++;
 
-	fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
+	if (ep->xid <= lp->lro_xid)
+		fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
 
 	if (unlikely(lp->tt.frame_send(lp, fp)))
 		goto err;
@@ -1860,7 +1955,7 @@ err:
 	rc = fc_exch_done_locked(ep);
 	spin_unlock_bh(&ep->ex_lock);
 	if (!rc)
-		fc_exch_mgr_delete_ep(ep);
+		fc_exch_delete(ep);
 	return NULL;
 }
 EXPORT_SYMBOL(fc_exch_seq_send);
@@ -1868,24 +1963,44 @@ EXPORT_SYMBOL(fc_exch_seq_send);
 /*
  * Receive a frame
  */
-void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
-		  struct fc_frame *fp)
+void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp)
 {
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
-	u32 f_ctl;
+	struct fc_exch_mgr_anchor *ema;
+	u32 f_ctl, found = 0;
+	u16 oxid;
 
 	/* lport lock ? */
-	if (!lp || !mp || (lp->state == LPORT_ST_NONE)) {
+	if (!lp || lp->state == LPORT_ST_DISABLED) {
 		FC_LPORT_DBG(lp, "Receiving frames for an lport that "
 			     "has not been initialized correctly\n");
 		fc_frame_free(fp);
 		return;
 	}
 
+	f_ctl = ntoh24(fh->fh_f_ctl);
+	oxid = ntohs(fh->fh_ox_id);
+	if (f_ctl & FC_FC_EX_CTX) {
+		list_for_each_entry(ema, &lp->ema_list, ema_list) {
+			if ((oxid >= ema->mp->min_xid) &&
+			    (oxid <= ema->mp->max_xid)) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (!found) {
+			FC_LPORT_DBG(lp, "Received response for out "
+				     "of range oxid:%hx\n", oxid);
+			fc_frame_free(fp);
+			return;
+		}
+	} else
+		ema = list_entry(lp->ema_list.prev, typeof(*ema), ema_list);
+
 	/*
 	 * If frame is marked invalid, just drop it.
 	 */
-	f_ctl = ntoh24(fh->fh_f_ctl);
 	switch (fr_eof(fp)) {
 	case FC_EOF_T:
 		if (f_ctl & FC_FC_END_SEQ)
@@ -1893,34 +2008,24 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
 		/* fall through */
 	case FC_EOF_N:
 		if (fh->fh_type == FC_TYPE_BLS)
-			fc_exch_recv_bls(mp, fp);
+			fc_exch_recv_bls(ema->mp, fp);
 		else if ((f_ctl & (FC_FC_EX_CTX | FC_FC_SEQ_CTX)) ==
 			 FC_FC_EX_CTX)
-			fc_exch_recv_seq_resp(mp, fp);
+			fc_exch_recv_seq_resp(ema->mp, fp);
 		else if (f_ctl & FC_FC_SEQ_CTX)
-			fc_exch_recv_resp(mp, fp);
+			fc_exch_recv_resp(ema->mp, fp);
 		else
-			fc_exch_recv_req(lp, mp, fp);
+			fc_exch_recv_req(lp, ema->mp, fp);
 		break;
 	default:
-		FC_EM_DBG(mp, "dropping invalid frame (eof %x)", fr_eof(fp));
+		FC_LPORT_DBG(lp, "dropping invalid frame (eof %x)", fr_eof(fp));
 		fc_frame_free(fp);
-		break;
 	}
 }
 EXPORT_SYMBOL(fc_exch_recv);
 
 int fc_exch_init(struct fc_lport *lp)
 {
-	if (!lp->tt.exch_get) {
-		/*
-		 *  exch_put() should be NULL if
-		 *  exch_get() is NULL
-		 */
-		WARN_ON(lp->tt.exch_put);
-		lp->tt.exch_get = fc_exch_get;
-	}
-
 	if (!lp->tt.seq_start_next)
 		lp->tt.seq_start_next = fc_seq_start_next;
 
@@ -1942,6 +2047,28 @@ int fc_exch_init(struct fc_lport *lp)
 	if (!lp->tt.seq_exch_abort)
 		lp->tt.seq_exch_abort = fc_seq_exch_abort;
 
+	/*
+	 * Initialize fc_cpu_mask and fc_cpu_order. The
+	 * fc_cpu_mask is set for nr_cpu_ids rounded up
+	 * to order of 2's * power and order is stored
+	 * in fc_cpu_order as this is later required in
+	 * mapping between an exch id and exch array index
+	 * in per cpu exch pool.
+	 *
+	 * This round up is required to align fc_cpu_mask
+	 * to exchange id's lower bits such that all incoming
+	 * frames of an exchange gets delivered to the same
+	 * cpu on which exchange originated by simple bitwise
+	 * AND operation between fc_cpu_mask and exchange id.
+	 */
+	fc_cpu_mask = 1;
+	fc_cpu_order = 0;
+	while (fc_cpu_mask < nr_cpu_ids) {
+		fc_cpu_mask <<= 1;
+		fc_cpu_order++;
+	}
+	fc_cpu_mask--;
+
 	return 0;
 }
 EXPORT_SYMBOL(fc_exch_init);
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index e303e0d..59a4408 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -507,33 +507,6 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
 	f_ctl = FC_FC_REL_OFF;
 	WARN_ON(!seq);
 
-	/*
-	 * If a get_page()/put_page() will fail, don't use sg lists
-	 * in the fc_frame structure.
-	 *
-	 * The put_page() may be long after the I/O has completed
-	 * in the case of FCoE, since the network driver does it
-	 * via free_skb().  See the test in free_pages_check().
-	 *
-	 * Test this case with 'dd </dev/zero >/dev/st0 bs=64k'.
-	 */
-	if (using_sg) {
-		for (sg = scsi_sglist(sc); sg; sg = sg_next(sg)) {
-			if (page_count(sg_page(sg)) == 0 ||
-			    (sg_page(sg)->flags & (1 << PG_lru |
-						   1 << PG_private |
-						   1 << PG_locked |
-						   1 << PG_active |
-						   1 << PG_slab |
-						   1 << PG_swapcache |
-						   1 << PG_writeback |
-						   1 << PG_reserved |
-						   1 << PG_buddy))) {
-				using_sg = 0;
-				break;
-			}
-		}
-	}
 	sg = scsi_sglist(sc);
 
 	while (remaining > 0 && sg) {
@@ -569,8 +542,6 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq,
 		}
 		sg_bytes = min(tlen, sg->length - offset);
 		if (using_sg) {
-			WARN_ON(skb_shinfo(fp_skb(fp))->nr_frags >
-				FC_FRAME_SG_LEN);
 			get_page(sg_page(sg));
 			skb_fill_page_desc(fp_skb(fp),
 					   skb_shinfo(fp_skb(fp))->nr_frags,
@@ -1337,7 +1308,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp)
 	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id,
 		       fc_host_port_id(rp->local_port->host), FC_TYPE_ELS,
 		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
-	if (lp->tt.elsct_send(lp, rport, fp, ELS_REC, fc_fcp_rec_resp,
+	if (lp->tt.elsct_send(lp, rport->port_id, fp, ELS_REC, fc_fcp_rec_resp,
 			      fsp, jiffies_to_msecs(FC_SCSI_REC_TOV))) {
 		fc_fcp_pkt_hold(fsp);		/* hold while REC outstanding */
 		return;
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 745fa55..bd2f771 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -113,7 +113,7 @@ static void fc_lport_enter_ready(struct fc_lport *);
 static void fc_lport_enter_logo(struct fc_lport *);
 
 static const char *fc_lport_state_names[] = {
-	[LPORT_ST_NONE] =     "none",
+	[LPORT_ST_DISABLED] = "disabled",
 	[LPORT_ST_FLOGI] =    "FLOGI",
 	[LPORT_ST_DNS] =      "dNS",
 	[LPORT_ST_RPN_ID] =   "RPN_ID",
@@ -133,57 +133,44 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp)
 /**
  * fc_lport_rport_callback() - Event handler for rport events
  * @lport: The lport which is receiving the event
- * @rport: The rport which the event has occured on
+ * @rdata: private remote port data
  * @event: The event that occured
  *
  * Locking Note: The rport lock should not be held when calling
  *		 this function.
  */
 static void fc_lport_rport_callback(struct fc_lport *lport,
-				    struct fc_rport *rport,
+				    struct fc_rport_priv *rdata,
 				    enum fc_rport_event event)
 {
 	FC_LPORT_DBG(lport, "Received a %d event for port (%6x)\n", event,
-		     rport->port_id);
+		     rdata->ids.port_id);
 
+	mutex_lock(&lport->lp_mutex);
 	switch (event) {
-	case RPORT_EV_CREATED:
-		if (rport->port_id == FC_FID_DIR_SERV) {
-			mutex_lock(&lport->lp_mutex);
-			if (lport->state == LPORT_ST_DNS) {
-				lport->dns_rp = rport;
-				fc_lport_enter_rpn_id(lport);
-			} else {
-				FC_LPORT_DBG(lport, "Received an CREATED event "
-					     "on port (%6x) for the directory "
-					     "server, but the lport is not "
-					     "in the DNS state, it's in the "
-					     "%d state", rport->port_id,
-					     lport->state);
-				lport->tt.rport_logoff(rport);
-			}
-			mutex_unlock(&lport->lp_mutex);
-		} else
-			FC_LPORT_DBG(lport, "Received an event for port (%6x) "
-				     "which is not the directory server\n",
-				     rport->port_id);
+	case RPORT_EV_READY:
+		if (lport->state == LPORT_ST_DNS) {
+			lport->dns_rp = rdata;
+			fc_lport_enter_rpn_id(lport);
+		} else {
+			FC_LPORT_DBG(lport, "Received an READY event "
+				     "on port (%6x) for the directory "
+				     "server, but the lport is not "
+				     "in the DNS state, it's in the "
+				     "%d state", rdata->ids.port_id,
+				     lport->state);
+			lport->tt.rport_logoff(rdata);
+		}
 		break;
 	case RPORT_EV_LOGO:
 	case RPORT_EV_FAILED:
 	case RPORT_EV_STOP:
-		if (rport->port_id == FC_FID_DIR_SERV) {
-			mutex_lock(&lport->lp_mutex);
-			lport->dns_rp = NULL;
-			mutex_unlock(&lport->lp_mutex);
-
-		} else
-			FC_LPORT_DBG(lport, "Received an event for port (%6x) "
-				     "which is not the directory server\n",
-				     rport->port_id);
+		lport->dns_rp = NULL;
 		break;
 	case RPORT_EV_NONE:
 		break;
 	}
+	mutex_unlock(&lport->lp_mutex);
 }
 
 /**
@@ -211,20 +198,13 @@ static void fc_lport_ptp_setup(struct fc_lport *lport,
 			       u32 remote_fid, u64 remote_wwpn,
 			       u64 remote_wwnn)
 {
-	struct fc_disc_port dp;
-
-	dp.lp = lport;
-	dp.ids.port_id = remote_fid;
-	dp.ids.port_name = remote_wwpn;
-	dp.ids.node_name = remote_wwnn;
-	dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
-
-	if (lport->ptp_rp) {
+	mutex_lock(&lport->disc.disc_mutex);
+	if (lport->ptp_rp)
 		lport->tt.rport_logoff(lport->ptp_rp);
-		lport->ptp_rp = NULL;
-	}
-
-	lport->ptp_rp = lport->tt.rport_create(&dp);
+	lport->ptp_rp = lport->tt.rport_create(lport, remote_fid);
+	lport->ptp_rp->ids.port_name = remote_wwpn;
+	lport->ptp_rp->ids.node_name = remote_wwnn;
+	mutex_unlock(&lport->disc.disc_mutex);
 
 	lport->tt.rport_login(lport->ptp_rp);
 
@@ -472,56 +452,6 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp,
 }
 
 /**
- * fc_lport_recv_adisc_req() - Handle received Address Discovery Request
- * @lport: Fibre Channel local port recieving the ADISC
- * @sp: current sequence in the ADISC exchange
- * @fp: ADISC request frame
- *
- * Locking Note: The lport lock is expected to be held before calling
- * this function.
- */
-static void fc_lport_recv_adisc_req(struct fc_seq *sp, struct fc_frame *in_fp,
-				    struct fc_lport *lport)
-{
-	struct fc_frame *fp;
-	struct fc_exch *ep = fc_seq_exch(sp);
-	struct fc_els_adisc *req, *rp;
-	struct fc_seq_els_data rjt_data;
-	size_t len;
-	u32 f_ctl;
-
-	FC_LPORT_DBG(lport, "Received ADISC request while in state %s\n",
-		     fc_lport_state(lport));
-
-	req = fc_frame_payload_get(in_fp, sizeof(*req));
-	if (!req) {
-		rjt_data.fp = NULL;
-		rjt_data.reason = ELS_RJT_LOGIC;
-		rjt_data.explan = ELS_EXPL_NONE;
-		lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
-	} else {
-		len = sizeof(*rp);
-		fp = fc_frame_alloc(lport, len);
-		if (fp) {
-			rp = fc_frame_payload_get(fp, len);
-			memset(rp, 0, len);
-			rp->adisc_cmd = ELS_LS_ACC;
-			rp->adisc_wwpn = htonll(lport->wwpn);
-			rp->adisc_wwnn = htonll(lport->wwnn);
-			hton24(rp->adisc_port_id,
-			       fc_host_port_id(lport->host));
-			sp = lport->tt.seq_start_next(sp);
-			f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
-			f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
-			fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
-				       FC_TYPE_ELS, f_ctl, 0);
-			lport->tt.seq_send(lport, sp, fp);
-		}
-	}
-	fc_frame_free(in_fp);
-}
-
-/**
  * fc_lport_recv_logo_req() - Handle received fabric LOGO request
  * @lport: Fibre Channel local port recieving the LOGO
  * @sp: current sequence in the LOGO exchange
@@ -550,7 +480,7 @@ int fc_fabric_login(struct fc_lport *lport)
 	int rc = -1;
 
 	mutex_lock(&lport->lp_mutex);
-	if (lport->state == LPORT_ST_NONE) {
+	if (lport->state == LPORT_ST_DISABLED) {
 		fc_lport_enter_reset(lport);
 		rc = 0;
 	}
@@ -637,12 +567,13 @@ EXPORT_SYMBOL(fc_fabric_logoff);
 int fc_lport_destroy(struct fc_lport *lport)
 {
 	mutex_lock(&lport->lp_mutex);
-	lport->state = LPORT_ST_NONE;
+	lport->state = LPORT_ST_DISABLED;
 	lport->link_up = 0;
 	lport->tt.frame_send = fc_frame_drop;
 	mutex_unlock(&lport->lp_mutex);
 
 	lport->tt.fcp_abort_io(lport);
+	lport->tt.disc_stop_final(lport);
 	lport->tt.exch_mgr_reset(lport, 0, 0);
 	return 0;
 }
@@ -722,7 +653,8 @@ static void fc_lport_enter_ready(struct fc_lport *lport)
 
 	fc_lport_state_enter(lport, LPORT_ST_READY);
 
-	lport->tt.disc_start(fc_lport_disc_callback, lport);
+	if (!lport->ptp_rp)
+		lport->tt.disc_start(fc_lport_disc_callback, lport);
 }
 
 /**
@@ -808,8 +740,6 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in,
 	fc_lport_ptp_setup(lport, remote_fid, remote_wwpn,
 			   get_unaligned_be64(&flp->fl_wwnn));
 
-	lport->tt.disc_start(fc_lport_disc_callback, lport);
-
 out:
 	sp = fr_seq(rx_fp);
 	fc_frame_free(rx_fp);
@@ -832,10 +762,6 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
 {
 	struct fc_frame_header *fh = fc_frame_header_get(fp);
 	void (*recv) (struct fc_seq *, struct fc_frame *, struct fc_lport *);
-	struct fc_rport *rport;
-	u32 s_id;
-	u32 d_id;
-	struct fc_seq_els_data rjt_data;
 
 	mutex_lock(&lport->lp_mutex);
 
@@ -844,11 +770,14 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
 	 * RSCN here.  These don't require a session.
 	 * Even if we had a session, it might not be ready.
 	 */
-	if (fh->fh_type == FC_TYPE_ELS && fh->fh_r_ctl == FC_RCTL_ELS_REQ) {
+	if (!lport->link_up)
+		fc_frame_free(fp);
+	else if (fh->fh_type == FC_TYPE_ELS &&
+		 fh->fh_r_ctl == FC_RCTL_ELS_REQ) {
 		/*
 		 * Check opcode.
 		 */
-		recv = NULL;
+		recv = lport->tt.rport_recv_req;
 		switch (fc_frame_payload_op(fp)) {
 		case ELS_FLOGI:
 			recv = fc_lport_recv_flogi_req;
@@ -870,34 +799,9 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp,
 		case ELS_RNID:
 			recv = fc_lport_recv_rnid_req;
 			break;
-		case ELS_ADISC:
-			recv = fc_lport_recv_adisc_req;
-			break;
 		}
 
-		if (recv)
-			recv(sp, fp, lport);
-		else {
-			/*
-			 * Find session.
-			 * If this is a new incoming PLOGI, we won't find it.
-			 */
-			s_id = ntoh24(fh->fh_s_id);
-			d_id = ntoh24(fh->fh_d_id);
-
-			rport = lport->tt.rport_lookup(lport, s_id);
-			if (rport)
-				lport->tt.rport_recv_req(sp, fp, rport);
-			else {
-				rjt_data.fp = NULL;
-				rjt_data.reason = ELS_RJT_UNAB;
-				rjt_data.explan = ELS_EXPL_NONE;
-				lport->tt.seq_els_rsp_send(sp,
-							   ELS_LS_RJT,
-							   &rjt_data);
-				fc_frame_free(fp);
-			}
-		}
+		recv(sp, fp, lport);
 	} else {
 		FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)\n",
 			     fr_eof(fp));
@@ -930,38 +834,61 @@ int fc_lport_reset(struct fc_lport *lport)
 EXPORT_SYMBOL(fc_lport_reset);
 
 /**
- * fc_rport_enter_reset() - Reset the local port
+ * fc_lport_reset_locked() - Reset the local port
  * @lport: Fibre Channel local port to be reset
  *
  * Locking Note: The lport lock is expected to be held before calling
  * this routine.
  */
-static void fc_lport_enter_reset(struct fc_lport *lport)
+static void fc_lport_reset_locked(struct fc_lport *lport)
 {
-	FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
-		     fc_lport_state(lport));
-
-	fc_lport_state_enter(lport, LPORT_ST_RESET);
-
 	if (lport->dns_rp)
 		lport->tt.rport_logoff(lport->dns_rp);
 
-	if (lport->ptp_rp) {
-		lport->tt.rport_logoff(lport->ptp_rp);
-		lport->ptp_rp = NULL;
-	}
+	lport->ptp_rp = NULL;
 
 	lport->tt.disc_stop(lport);
 
 	lport->tt.exch_mgr_reset(lport, 0, 0);
 	fc_host_fabric_name(lport->host) = 0;
 	fc_host_port_id(lport->host) = 0;
+}
 
+/**
+ * fc_lport_enter_reset() - Reset the local port
+ * @lport: Fibre Channel local port to be reset
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static void fc_lport_enter_reset(struct fc_lport *lport)
+{
+	FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
+		     fc_lport_state(lport));
+
+	fc_lport_state_enter(lport, LPORT_ST_RESET);
+	fc_lport_reset_locked(lport);
 	if (lport->link_up)
 		fc_lport_enter_flogi(lport);
 }
 
 /**
+ * fc_lport_enter_disabled() - disable the local port
+ * @lport: Fibre Channel local port to be reset
+ *
+ * Locking Note: The lport lock is expected to be held before calling
+ * this routine.
+ */
+static void fc_lport_enter_disabled(struct fc_lport *lport)
+{
+	FC_LPORT_DBG(lport, "Entered disabled state from %s state\n",
+		     fc_lport_state(lport));
+
+	fc_lport_state_enter(lport, LPORT_ST_DISABLED);
+	fc_lport_reset_locked(lport);
+}
+
+/**
  * fc_lport_error() - Handler for any errors
  * @lport: The fc_lport object
  * @fp: The frame pointer
@@ -992,7 +919,7 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
 			schedule_delayed_work(&lport->retry_work, delay);
 		} else {
 			switch (lport->state) {
-			case LPORT_ST_NONE:
+			case LPORT_ST_DISABLED:
 			case LPORT_ST_READY:
 			case LPORT_ST_RESET:
 			case LPORT_ST_RPN_ID:
@@ -1026,13 +953,13 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
 	struct fc_frame_header *fh;
 	struct fc_ct_hdr *ct;
 
+	FC_LPORT_DBG(lport, "Received a RFT_ID %s\n", fc_els_resp_type(fp));
+
 	if (fp == ERR_PTR(-FC_EX_CLOSED))
 		return;
 
 	mutex_lock(&lport->lp_mutex);
 
-	FC_LPORT_DBG(lport, "Received a RFT_ID response\n");
-
 	if (lport->state != LPORT_ST_RFT_ID) {
 		FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state "
 			     "%s\n", fc_lport_state(lport));
@@ -1080,13 +1007,13 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
 	struct fc_frame_header *fh;
 	struct fc_ct_hdr *ct;
 
+	FC_LPORT_DBG(lport, "Received a RPN_ID %s\n", fc_els_resp_type(fp));
+
 	if (fp == ERR_PTR(-FC_EX_CLOSED))
 		return;
 
 	mutex_lock(&lport->lp_mutex);
 
-	FC_LPORT_DBG(lport, "Received a RPN_ID response\n");
-
 	if (lport->state != LPORT_ST_RPN_ID) {
 		FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state "
 			     "%s\n", fc_lport_state(lport));
@@ -1132,13 +1059,13 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
 	struct fc_lport *lport = lp_arg;
 	u8 op;
 
+	FC_LPORT_DBG(lport, "Received a SCR %s\n", fc_els_resp_type(fp));
+
 	if (fp == ERR_PTR(-FC_EX_CLOSED))
 		return;
 
 	mutex_lock(&lport->lp_mutex);
 
-	FC_LPORT_DBG(lport, "Received a SCR response\n");
-
 	if (lport->state != LPORT_ST_SCR) {
 		FC_LPORT_DBG(lport, "Received a SCR response, but in state "
 			     "%s\n", fc_lport_state(lport));
@@ -1186,7 +1113,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport)
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, NULL, fp, ELS_SCR,
+	if (!lport->tt.elsct_send(lport, FC_FID_FCTRL, fp, ELS_SCR,
 				  fc_lport_scr_resp, lport, lport->e_d_tov))
 		fc_lport_error(lport, fp);
 }
@@ -1227,7 +1154,7 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RFT_ID,
+	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RFT_ID,
 				  fc_lport_rft_id_resp,
 				  lport, lport->e_d_tov))
 		fc_lport_error(lport, fp);
@@ -1256,7 +1183,7 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport)
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RPN_ID,
+	if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID,
 				  fc_lport_rpn_id_resp,
 				  lport, lport->e_d_tov))
 		fc_lport_error(lport, fp);
@@ -1275,28 +1202,21 @@ static struct fc_rport_operations fc_lport_rport_ops = {
  */
 static void fc_lport_enter_dns(struct fc_lport *lport)
 {
-	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rdata;
-	struct fc_disc_port dp;
-
-	dp.ids.port_id = FC_FID_DIR_SERV;
-	dp.ids.port_name = -1;
-	dp.ids.node_name = -1;
-	dp.ids.roles = FC_RPORT_ROLE_UNKNOWN;
-	dp.lp = lport;
+	struct fc_rport_priv *rdata;
 
 	FC_LPORT_DBG(lport, "Entered DNS state from %s state\n",
 		     fc_lport_state(lport));
 
 	fc_lport_state_enter(lport, LPORT_ST_DNS);
 
-	rport = lport->tt.rport_create(&dp);
-	if (!rport)
+	mutex_lock(&lport->disc.disc_mutex);
+	rdata = lport->tt.rport_create(lport, FC_FID_DIR_SERV);
+	mutex_unlock(&lport->disc.disc_mutex);
+	if (!rdata)
 		goto err;
 
-	rdata = rport->dd_data;
 	rdata->ops = &fc_lport_rport_ops;
-	lport->tt.rport_login(rport);
+	lport->tt.rport_login(rdata);
 	return;
 
 err:
@@ -1316,7 +1236,7 @@ static void fc_lport_timeout(struct work_struct *work)
 	mutex_lock(&lport->lp_mutex);
 
 	switch (lport->state) {
-	case LPORT_ST_NONE:
+	case LPORT_ST_DISABLED:
 	case LPORT_ST_READY:
 	case LPORT_ST_RESET:
 		WARN_ON(1);
@@ -1360,13 +1280,13 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
 	struct fc_lport *lport = lp_arg;
 	u8 op;
 
+	FC_LPORT_DBG(lport, "Received a LOGO %s\n", fc_els_resp_type(fp));
+
 	if (fp == ERR_PTR(-FC_EX_CLOSED))
 		return;
 
 	mutex_lock(&lport->lp_mutex);
 
-	FC_LPORT_DBG(lport, "Received a LOGO response\n");
-
 	if (lport->state != LPORT_ST_LOGO) {
 		FC_LPORT_DBG(lport, "Received a LOGO response, but in state "
 			     "%s\n", fc_lport_state(lport));
@@ -1382,7 +1302,7 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
 
 	op = fc_frame_payload_op(fp);
 	if (op == ELS_LS_ACC)
-		fc_lport_enter_reset(lport);
+		fc_lport_enter_disabled(lport);
 	else
 		fc_lport_error(lport, fp);
 
@@ -1415,8 +1335,8 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, NULL, fp, ELS_LOGO, fc_lport_logo_resp,
-				  lport, lport->e_d_tov))
+	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_LOGO,
+				  fc_lport_logo_resp, lport, lport->e_d_tov))
 		fc_lport_error(lport, fp);
 }
 
@@ -1442,13 +1362,13 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 	unsigned int e_d_tov;
 	u16 mfs;
 
+	FC_LPORT_DBG(lport, "Received a FLOGI %s\n", fc_els_resp_type(fp));
+
 	if (fp == ERR_PTR(-FC_EX_CLOSED))
 		return;
 
 	mutex_lock(&lport->lp_mutex);
 
-	FC_LPORT_DBG(lport, "Received a FLOGI response\n");
-
 	if (lport->state != LPORT_ST_FLOGI) {
 		FC_LPORT_DBG(lport, "Received a FLOGI response, but in state "
 			     "%s\n", fc_lport_state(lport));
@@ -1501,14 +1421,6 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 				fc_lport_enter_dns(lport);
 			}
 		}
-
-		if (flp) {
-			csp_flags = ntohs(flp->fl_csp.sp_features);
-			if ((csp_flags & FC_SP_FT_FPORT) == 0) {
-				lport->tt.disc_start(fc_lport_disc_callback,
-						     lport);
-			}
-		}
 	} else {
 		FC_LPORT_DBG(lport, "Bad FLOGI response\n");
 	}
@@ -1539,7 +1451,7 @@ void fc_lport_enter_flogi(struct fc_lport *lport)
 	if (!fp)
 		return fc_lport_error(lport, fp);
 
-	if (!lport->tt.elsct_send(lport, NULL, fp, ELS_FLOGI,
+	if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI,
 				  fc_lport_flogi_resp, lport, lport->e_d_tov))
 		fc_lport_error(lport, fp);
 }
@@ -1550,7 +1462,7 @@ int fc_lport_config(struct fc_lport *lport)
 	INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
 	mutex_init(&lport->lp_mutex);
 
-	fc_lport_state_enter(lport, LPORT_ST_NONE);
+	fc_lport_state_enter(lport, LPORT_ST_DISABLED);
 
 	fc_lport_add_fc4_type(lport, FC_TYPE_FCP);
 	fc_lport_add_fc4_type(lport, FC_TYPE_CT);
@@ -1588,6 +1500,7 @@ int fc_lport_init(struct fc_lport *lport)
 	if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT)
 		fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT;
 
+	INIT_LIST_HEAD(&lport->ema_list);
 	return 0;
 }
 EXPORT_SYMBOL(fc_lport_init);
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 7162385..03ea674 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -57,94 +57,114 @@
 
 struct workqueue_struct *rport_event_queue;
 
-static void fc_rport_enter_plogi(struct fc_rport *);
-static void fc_rport_enter_prli(struct fc_rport *);
-static void fc_rport_enter_rtv(struct fc_rport *);
-static void fc_rport_enter_ready(struct fc_rport *);
-static void fc_rport_enter_logo(struct fc_rport *);
-
-static void fc_rport_recv_plogi_req(struct fc_rport *,
+static void fc_rport_enter_plogi(struct fc_rport_priv *);
+static void fc_rport_enter_prli(struct fc_rport_priv *);
+static void fc_rport_enter_rtv(struct fc_rport_priv *);
+static void fc_rport_enter_ready(struct fc_rport_priv *);
+static void fc_rport_enter_logo(struct fc_rport_priv *);
+static void fc_rport_enter_adisc(struct fc_rport_priv *);
+
+static void fc_rport_recv_plogi_req(struct fc_lport *,
 				    struct fc_seq *, struct fc_frame *);
-static void fc_rport_recv_prli_req(struct fc_rport *,
+static void fc_rport_recv_prli_req(struct fc_rport_priv *,
 				   struct fc_seq *, struct fc_frame *);
-static void fc_rport_recv_prlo_req(struct fc_rport *,
+static void fc_rport_recv_prlo_req(struct fc_rport_priv *,
 				   struct fc_seq *, struct fc_frame *);
-static void fc_rport_recv_logo_req(struct fc_rport *,
+static void fc_rport_recv_logo_req(struct fc_lport *,
 				   struct fc_seq *, struct fc_frame *);
 static void fc_rport_timeout(struct work_struct *);
-static void fc_rport_error(struct fc_rport *, struct fc_frame *);
-static void fc_rport_error_retry(struct fc_rport *, struct fc_frame *);
+static void fc_rport_error(struct fc_rport_priv *, struct fc_frame *);
+static void fc_rport_error_retry(struct fc_rport_priv *, struct fc_frame *);
 static void fc_rport_work(struct work_struct *);
 
 static const char *fc_rport_state_names[] = {
-	[RPORT_ST_NONE] = "None",
 	[RPORT_ST_INIT] = "Init",
 	[RPORT_ST_PLOGI] = "PLOGI",
 	[RPORT_ST_PRLI] = "PRLI",
 	[RPORT_ST_RTV] = "RTV",
 	[RPORT_ST_READY] = "Ready",
 	[RPORT_ST_LOGO] = "LOGO",
+	[RPORT_ST_ADISC] = "ADISC",
+	[RPORT_ST_DELETE] = "Delete",
 };
 
-static void fc_rport_rogue_destroy(struct device *dev)
+/**
+ * fc_rport_lookup() - lookup a remote port by port_id
+ * @lport: Fibre Channel host port instance
+ * @port_id: remote port port_id to match
+ */
+static struct fc_rport_priv *fc_rport_lookup(const struct fc_lport *lport,
+					     u32 port_id)
 {
-	struct fc_rport *rport = dev_to_rport(dev);
-	FC_RPORT_DBG(rport, "Destroying rogue rport\n");
-	kfree(rport);
+	struct fc_rport_priv *rdata;
+
+	list_for_each_entry(rdata, &lport->disc.rports, peers)
+		if (rdata->ids.port_id == port_id &&
+		    rdata->rp_state != RPORT_ST_DELETE)
+			return rdata;
+	return NULL;
 }
 
-struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *dp)
+/**
+ * fc_rport_create() - Create a new remote port
+ * @lport:   The local port that the new remote port is for
+ * @port_id: The port ID for the new remote port
+ *
+ * Locking note:  must be called with the disc_mutex held.
+ */
+static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport,
+					     u32 port_id)
 {
-	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rdata;
-	rport = kzalloc(sizeof(*rport) + sizeof(*rdata), GFP_KERNEL);
+	struct fc_rport_priv *rdata;
 
-	if (!rport)
-		return NULL;
+	rdata = lport->tt.rport_lookup(lport, port_id);
+	if (rdata)
+		return rdata;
 
-	rdata = RPORT_TO_PRIV(rport);
+	rdata = kzalloc(sizeof(*rdata), GFP_KERNEL);
+	if (!rdata)
+		return NULL;
 
-	rport->dd_data = rdata;
-	rport->port_id = dp->ids.port_id;
-	rport->port_name = dp->ids.port_name;
-	rport->node_name = dp->ids.node_name;
-	rport->roles = dp->ids.roles;
-	rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
-	/*
-	 * Note: all this libfc rogue rport code will be removed for
-	 * upstream so it fine that this is really ugly and hacky right now.
-	 */
-	device_initialize(&rport->dev);
-	rport->dev.release = fc_rport_rogue_destroy;
+	rdata->ids.node_name = -1;
+	rdata->ids.port_name = -1;
+	rdata->ids.port_id = port_id;
+	rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;
 
+	kref_init(&rdata->kref);
 	mutex_init(&rdata->rp_mutex);
-	rdata->local_port = dp->lp;
-	rdata->trans_state = FC_PORTSTATE_ROGUE;
+	rdata->local_port = lport;
 	rdata->rp_state = RPORT_ST_INIT;
 	rdata->event = RPORT_EV_NONE;
 	rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
-	rdata->ops = NULL;
-	rdata->e_d_tov = dp->lp->e_d_tov;
-	rdata->r_a_tov = dp->lp->r_a_tov;
+	rdata->e_d_tov = lport->e_d_tov;
+	rdata->r_a_tov = lport->r_a_tov;
+	rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
 	INIT_DELAYED_WORK(&rdata->retry_work, fc_rport_timeout);
 	INIT_WORK(&rdata->event_work, fc_rport_work);
-	/*
-	 * For good measure, but not necessary as we should only
-	 * add REAL rport to the lport list.
-	 */
-	INIT_LIST_HEAD(&rdata->peers);
+	if (port_id != FC_FID_DIR_SERV)
+		list_add(&rdata->peers, &lport->disc.rports);
+	return rdata;
+}
+
+/**
+ * fc_rport_destroy() - free a remote port after last reference is released.
+ * @kref: pointer to kref inside struct fc_rport_priv
+ */
+static void fc_rport_destroy(struct kref *kref)
+{
+	struct fc_rport_priv *rdata;
 
-	return rport;
+	rdata = container_of(kref, struct fc_rport_priv, kref);
+	kfree(rdata);
 }
 
 /**
  * fc_rport_state() - return a string for the state the rport is in
- * @rport: The rport whose state we want to get a string for
+ * @rdata: remote port private data
  */
-static const char *fc_rport_state(struct fc_rport *rport)
+static const char *fc_rport_state(struct fc_rport_priv *rdata)
 {
 	const char *cp;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 
 	cp = fc_rport_state_names[rdata->rp_state];
 	if (!cp)
@@ -191,15 +211,14 @@ static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp,
 
 /**
  * fc_rport_state_enter() - Change the rport's state
- * @rport: The rport whose state should change
+ * @rdata: The rport whose state should change
  * @new: The new state of the rport
  *
  * Locking Note: Called with the rport lock held
  */
-static void fc_rport_state_enter(struct fc_rport *rport,
+static void fc_rport_state_enter(struct fc_rport_priv *rdata,
 				 enum fc_rport_state new)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	if (rdata->rp_state != new)
 		rdata->retries = 0;
 	rdata->rp_state = new;
@@ -208,147 +227,187 @@ static void fc_rport_state_enter(struct fc_rport *rport,
 static void fc_rport_work(struct work_struct *work)
 {
 	u32 port_id;
-	struct fc_rport_libfc_priv *rdata =
-		container_of(work, struct fc_rport_libfc_priv, event_work);
+	struct fc_rport_priv *rdata =
+		container_of(work, struct fc_rport_priv, event_work);
+	struct fc_rport_libfc_priv *rp;
 	enum fc_rport_event event;
-	enum fc_rport_trans_state trans_state;
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_rport_operations *rport_ops;
-	struct fc_rport *rport = PRIV_TO_RPORT(rdata);
+	struct fc_rport_identifiers ids;
+	struct fc_rport *rport;
 
 	mutex_lock(&rdata->rp_mutex);
 	event = rdata->event;
 	rport_ops = rdata->ops;
+	rport = rdata->rport;
 
-	if (event == RPORT_EV_CREATED) {
-		struct fc_rport *new_rport;
-		struct fc_rport_libfc_priv *new_rdata;
-		struct fc_rport_identifiers ids;
+	FC_RPORT_DBG(rdata, "work event %u\n", event);
 
-		ids.port_id = rport->port_id;
-		ids.roles = rport->roles;
-		ids.port_name = rport->port_name;
-		ids.node_name = rport->node_name;
+	switch (event) {
+	case RPORT_EV_READY:
+		ids = rdata->ids;
+		rdata->event = RPORT_EV_NONE;
+		kref_get(&rdata->kref);
+		mutex_unlock(&rdata->rp_mutex);
 
+		if (!rport)
+			rport = fc_remote_port_add(lport->host, 0, &ids);
+		if (!rport) {
+			FC_RPORT_DBG(rdata, "Failed to add the rport\n");
+			lport->tt.rport_logoff(rdata);
+			kref_put(&rdata->kref, lport->tt.rport_destroy);
+			return;
+		}
+		mutex_lock(&rdata->rp_mutex);
+		if (rdata->rport)
+			FC_RPORT_DBG(rdata, "rport already allocated\n");
+		rdata->rport = rport;
+		rport->maxframe_size = rdata->maxframe_size;
+		rport->supported_classes = rdata->supported_classes;
+
+		rp = rport->dd_data;
+		rp->local_port = lport;
+		rp->rp_state = rdata->rp_state;
+		rp->flags = rdata->flags;
+		rp->e_d_tov = rdata->e_d_tov;
+		rp->r_a_tov = rdata->r_a_tov;
 		mutex_unlock(&rdata->rp_mutex);
 
-		new_rport = fc_remote_port_add(lport->host, 0, &ids);
-		if (new_rport) {
-			/*
-			 * Switch from the rogue rport to the rport
-			 * returned by the FC class.
-			 */
-			new_rport->maxframe_size = rport->maxframe_size;
-
-			new_rdata = new_rport->dd_data;
-			new_rdata->e_d_tov = rdata->e_d_tov;
-			new_rdata->r_a_tov = rdata->r_a_tov;
-			new_rdata->ops = rdata->ops;
-			new_rdata->local_port = rdata->local_port;
-			new_rdata->flags = FC_RP_FLAGS_REC_SUPPORTED;
-			new_rdata->trans_state = FC_PORTSTATE_REAL;
-			mutex_init(&new_rdata->rp_mutex);
-			INIT_DELAYED_WORK(&new_rdata->retry_work,
-					  fc_rport_timeout);
-			INIT_LIST_HEAD(&new_rdata->peers);
-			INIT_WORK(&new_rdata->event_work, fc_rport_work);
-
-			fc_rport_state_enter(new_rport, RPORT_ST_READY);
-		} else {
-			printk(KERN_WARNING "libfc: Failed to allocate "
-			       " memory for rport (%6x)\n", ids.port_id);
-			event = RPORT_EV_FAILED;
+		if (rport_ops && rport_ops->event_callback) {
+			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
+			rport_ops->event_callback(lport, rdata, event);
 		}
-		if (rport->port_id != FC_FID_DIR_SERV)
-			if (rport_ops->event_callback)
-				rport_ops->event_callback(lport, rport,
-							  RPORT_EV_FAILED);
-		put_device(&rport->dev);
-		rport = new_rport;
-		rdata = new_rport->dd_data;
-		if (rport_ops->event_callback)
-			rport_ops->event_callback(lport, rport, event);
-	} else if ((event == RPORT_EV_FAILED) ||
-		   (event == RPORT_EV_LOGO) ||
-		   (event == RPORT_EV_STOP)) {
-		trans_state = rdata->trans_state;
+		kref_put(&rdata->kref, lport->tt.rport_destroy);
+		break;
+
+	case RPORT_EV_FAILED:
+	case RPORT_EV_LOGO:
+	case RPORT_EV_STOP:
+		port_id = rdata->ids.port_id;
 		mutex_unlock(&rdata->rp_mutex);
-		if (rport_ops->event_callback)
-			rport_ops->event_callback(lport, rport, event);
-		if (trans_state == FC_PORTSTATE_ROGUE)
-			put_device(&rport->dev);
-		else {
-			port_id = rport->port_id;
+
+		if (port_id != FC_FID_DIR_SERV) {
+			mutex_lock(&lport->disc.disc_mutex);
+			list_del(&rdata->peers);
+			mutex_unlock(&lport->disc.disc_mutex);
+		}
+
+		if (rport_ops && rport_ops->event_callback) {
+			FC_RPORT_DBG(rdata, "callback ev %d\n", event);
+			rport_ops->event_callback(lport, rdata, event);
+		}
+		cancel_delayed_work_sync(&rdata->retry_work);
+
+		/*
+		 * Reset any outstanding exchanges before freeing rport.
+		 */
+		lport->tt.exch_mgr_reset(lport, 0, port_id);
+		lport->tt.exch_mgr_reset(lport, port_id, 0);
+
+		if (rport) {
+			rp = rport->dd_data;
+			rp->rp_state = RPORT_ST_DELETE;
+			mutex_lock(&rdata->rp_mutex);
+			rdata->rport = NULL;
+			mutex_unlock(&rdata->rp_mutex);
 			fc_remote_port_delete(rport);
-			lport->tt.exch_mgr_reset(lport, 0, port_id);
-			lport->tt.exch_mgr_reset(lport, port_id, 0);
 		}
-	} else
+		kref_put(&rdata->kref, lport->tt.rport_destroy);
+		break;
+
+	default:
 		mutex_unlock(&rdata->rp_mutex);
+		break;
+	}
 }
 
 /**
  * fc_rport_login() - Start the remote port login state machine
- * @rport: Fibre Channel remote port
+ * @rdata: private remote port
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
  * function and then unlock the rport.
+ *
+ * This indicates the intent to be logged into the remote port.
+ * If it appears we are already logged in, ADISC is used to verify
+ * the setup.
  */
-int fc_rport_login(struct fc_rport *rport)
+int fc_rport_login(struct fc_rport_priv *rdata)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-
 	mutex_lock(&rdata->rp_mutex);
 
-	FC_RPORT_DBG(rport, "Login to port\n");
-
-	fc_rport_enter_plogi(rport);
-
+	switch (rdata->rp_state) {
+	case RPORT_ST_READY:
+		FC_RPORT_DBG(rdata, "ADISC port\n");
+		fc_rport_enter_adisc(rdata);
+		break;
+	default:
+		FC_RPORT_DBG(rdata, "Login to port\n");
+		fc_rport_enter_plogi(rdata);
+		break;
+	}
 	mutex_unlock(&rdata->rp_mutex);
 
 	return 0;
 }
 
 /**
+ * fc_rport_enter_delete() - schedule a remote port to be deleted.
+ * @rdata: private remote port
+ * @event: event to report as the reason for deletion
+ *
+ * Locking Note: Called with the rport lock held.
+ *
+ * Allow state change into DELETE only once.
+ *
+ * Call queue_work only if there's no event already pending.
+ * Set the new event so that the old pending event will not occur.
+ * Since we have the mutex, even if fc_rport_work() is already started,
+ * it'll see the new event.
+ */
+static void fc_rport_enter_delete(struct fc_rport_priv *rdata,
+				  enum fc_rport_event event)
+{
+	if (rdata->rp_state == RPORT_ST_DELETE)
+		return;
+
+	FC_RPORT_DBG(rdata, "Delete port\n");
+
+	fc_rport_state_enter(rdata, RPORT_ST_DELETE);
+
+	if (rdata->event == RPORT_EV_NONE)
+		queue_work(rport_event_queue, &rdata->event_work);
+	rdata->event = event;
+}
+
+/**
  * fc_rport_logoff() - Logoff and remove an rport
- * @rport: Fibre Channel remote port to be removed
+ * @rdata: private remote port
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
  * function and then unlock the rport.
  */
-int fc_rport_logoff(struct fc_rport *rport)
+int fc_rport_logoff(struct fc_rport_priv *rdata)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-
 	mutex_lock(&rdata->rp_mutex);
 
-	FC_RPORT_DBG(rport, "Remove port\n");
+	FC_RPORT_DBG(rdata, "Remove port\n");
 
-	if (rdata->rp_state == RPORT_ST_NONE) {
-		FC_RPORT_DBG(rport, "Port in NONE state, not removing\n");
+	if (rdata->rp_state == RPORT_ST_DELETE) {
+		FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
 		mutex_unlock(&rdata->rp_mutex);
 		goto out;
 	}
 
-	fc_rport_enter_logo(rport);
+	fc_rport_enter_logo(rdata);
 
 	/*
-	 * Change the state to NONE so that we discard
+	 * Change the state to Delete so that we discard
 	 * the response.
 	 */
-	fc_rport_state_enter(rport, RPORT_ST_NONE);
-
-	mutex_unlock(&rdata->rp_mutex);
-
-	cancel_delayed_work_sync(&rdata->retry_work);
-
-	mutex_lock(&rdata->rp_mutex);
-
-	rdata->event = RPORT_EV_STOP;
-	queue_work(rport_event_queue, &rdata->event_work);
-
+	fc_rport_enter_delete(rdata, RPORT_EV_STOP);
 	mutex_unlock(&rdata->rp_mutex);
 
 out:
@@ -357,26 +416,25 @@ out:
 
 /**
  * fc_rport_enter_ready() - The rport is ready
- * @rport: Fibre Channel remote port that is ready
+ * @rdata: private remote port
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
  */
-static void fc_rport_enter_ready(struct fc_rport *rport)
+static void fc_rport_enter_ready(struct fc_rport_priv *rdata)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-
-	fc_rport_state_enter(rport, RPORT_ST_READY);
+	fc_rport_state_enter(rdata, RPORT_ST_READY);
 
-	FC_RPORT_DBG(rport, "Port is Ready\n");
+	FC_RPORT_DBG(rdata, "Port is Ready\n");
 
-	rdata->event = RPORT_EV_CREATED;
-	queue_work(rport_event_queue, &rdata->event_work);
+	if (rdata->event == RPORT_EV_NONE)
+		queue_work(rport_event_queue, &rdata->event_work);
+	rdata->event = RPORT_EV_READY;
 }
 
 /**
  * fc_rport_timeout() - Handler for the retry_work timer.
- * @work: The work struct of the fc_rport_libfc_priv
+ * @work: The work struct of the fc_rport_priv
  *
  * Locking Note: Called without the rport lock held. This
  * function will hold the rport lock, call an _enter_*
@@ -384,63 +442,63 @@ static void fc_rport_enter_ready(struct fc_rport *rport)
  */
 static void fc_rport_timeout(struct work_struct *work)
 {
-	struct fc_rport_libfc_priv *rdata =
-		container_of(work, struct fc_rport_libfc_priv, retry_work.work);
-	struct fc_rport *rport = PRIV_TO_RPORT(rdata);
+	struct fc_rport_priv *rdata =
+		container_of(work, struct fc_rport_priv, retry_work.work);
 
 	mutex_lock(&rdata->rp_mutex);
 
 	switch (rdata->rp_state) {
 	case RPORT_ST_PLOGI:
-		fc_rport_enter_plogi(rport);
+		fc_rport_enter_plogi(rdata);
 		break;
 	case RPORT_ST_PRLI:
-		fc_rport_enter_prli(rport);
+		fc_rport_enter_prli(rdata);
 		break;
 	case RPORT_ST_RTV:
-		fc_rport_enter_rtv(rport);
+		fc_rport_enter_rtv(rdata);
 		break;
 	case RPORT_ST_LOGO:
-		fc_rport_enter_logo(rport);
+		fc_rport_enter_logo(rdata);
+		break;
+	case RPORT_ST_ADISC:
+		fc_rport_enter_adisc(rdata);
 		break;
 	case RPORT_ST_READY:
 	case RPORT_ST_INIT:
-	case RPORT_ST_NONE:
+	case RPORT_ST_DELETE:
 		break;
 	}
 
 	mutex_unlock(&rdata->rp_mutex);
-	put_device(&rport->dev);
 }
 
 /**
  * fc_rport_error() - Error handler, called once retries have been exhausted
- * @rport: The fc_rport object
+ * @rdata: private remote port
  * @fp: The frame pointer
  *
  * Locking Note: The rport lock is expected to be held before
  * calling this routine
  */
-static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
+static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-
-	FC_RPORT_DBG(rport, "Error %ld in state %s, retries %d\n",
-		     PTR_ERR(fp), fc_rport_state(rport), rdata->retries);
+	FC_RPORT_DBG(rdata, "Error %ld in state %s, retries %d\n",
+		     IS_ERR(fp) ? -PTR_ERR(fp) : 0,
+		     fc_rport_state(rdata), rdata->retries);
 
 	switch (rdata->rp_state) {
 	case RPORT_ST_PLOGI:
-	case RPORT_ST_PRLI:
 	case RPORT_ST_LOGO:
-		rdata->event = RPORT_EV_FAILED;
-		fc_rport_state_enter(rport, RPORT_ST_NONE);
-		queue_work(rport_event_queue,
-			   &rdata->event_work);
+		fc_rport_enter_delete(rdata, RPORT_EV_FAILED);
 		break;
 	case RPORT_ST_RTV:
-		fc_rport_enter_ready(rport);
+		fc_rport_enter_ready(rdata);
 		break;
-	case RPORT_ST_NONE:
+	case RPORT_ST_PRLI:
+	case RPORT_ST_ADISC:
+		fc_rport_enter_logo(rdata);
+		break;
+	case RPORT_ST_DELETE:
 	case RPORT_ST_READY:
 	case RPORT_ST_INIT:
 		break;
@@ -449,7 +507,7 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
 
 /**
  * fc_rport_error_retry() - Error handler when retries are desired
- * @rport: The fc_rport object
+ * @rdata: private remote port data
  * @fp: The frame pointer
  *
  * If the error was an exchange timeout retry immediately,
@@ -458,45 +516,43 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp)
  * Locking Note: The rport lock is expected to be held before
  * calling this routine
  */
-static void fc_rport_error_retry(struct fc_rport *rport, struct fc_frame *fp)
+static void fc_rport_error_retry(struct fc_rport_priv *rdata,
+				 struct fc_frame *fp)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	unsigned long delay = FC_DEF_E_D_TOV;
 
 	/* make sure this isn't an FC_EX_CLOSED error, never retry those */
 	if (PTR_ERR(fp) == -FC_EX_CLOSED)
-		return fc_rport_error(rport, fp);
+		return fc_rport_error(rdata, fp);
 
 	if (rdata->retries < rdata->local_port->max_rport_retry_count) {
-		FC_RPORT_DBG(rport, "Error %ld in state %s, retrying\n",
-			     PTR_ERR(fp), fc_rport_state(rport));
+		FC_RPORT_DBG(rdata, "Error %ld in state %s, retrying\n",
+			     PTR_ERR(fp), fc_rport_state(rdata));
 		rdata->retries++;
 		/* no additional delay on exchange timeouts */
 		if (PTR_ERR(fp) == -FC_EX_TIMEOUT)
 			delay = 0;
-		get_device(&rport->dev);
 		schedule_delayed_work(&rdata->retry_work, delay);
 		return;
 	}
 
-	return fc_rport_error(rport, fp);
+	return fc_rport_error(rdata, fp);
 }
 
 /**
  * fc_rport_plogi_recv_resp() - Handle incoming ELS PLOGI response
  * @sp: current sequence in the PLOGI exchange
  * @fp: response frame
- * @rp_arg: Fibre Channel remote port
+ * @rdata_arg: private remote port data
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
  * and then unlock the rport.
  */
 static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
-				void *rp_arg)
+				void *rdata_arg)
 {
-	struct fc_rport *rport = rp_arg;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
+	struct fc_rport_priv *rdata = rdata_arg;
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_els_flogi *plp = NULL;
 	unsigned int tov;
@@ -506,26 +562,26 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 
 	mutex_lock(&rdata->rp_mutex);
 
-	FC_RPORT_DBG(rport, "Received a PLOGI response\n");
+	FC_RPORT_DBG(rdata, "Received a PLOGI %s\n", fc_els_resp_type(fp));
 
 	if (rdata->rp_state != RPORT_ST_PLOGI) {
-		FC_RPORT_DBG(rport, "Received a PLOGI response, but in state "
-			     "%s\n", fc_rport_state(rport));
+		FC_RPORT_DBG(rdata, "Received a PLOGI response, but in state "
+			     "%s\n", fc_rport_state(rdata));
 		if (IS_ERR(fp))
 			goto err;
 		goto out;
 	}
 
 	if (IS_ERR(fp)) {
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 		goto err;
 	}
 
 	op = fc_frame_payload_op(fp);
 	if (op == ELS_LS_ACC &&
 	    (plp = fc_frame_payload_get(fp, sizeof(*plp))) != NULL) {
-		rport->port_name = get_unaligned_be64(&plp->fl_wwpn);
-		rport->node_name = get_unaligned_be64(&plp->fl_wwnn);
+		rdata->ids.port_name = get_unaligned_be64(&plp->fl_wwpn);
+		rdata->ids.node_name = get_unaligned_be64(&plp->fl_wwnn);
 
 		tov = ntohl(plp->fl_csp.sp_e_d_tov);
 		if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR)
@@ -537,75 +593,64 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
 		if (cssp_seq < csp_seq)
 			csp_seq = cssp_seq;
 		rdata->max_seq = csp_seq;
-		rport->maxframe_size =
-			fc_plogi_get_maxframe(plp, lport->mfs);
-
-		/*
-		 * If the rport is one of the well known addresses
-		 * we skip PRLI and RTV and go straight to READY.
-		 */
-		if (rport->port_id >= FC_FID_DOM_MGR)
-			fc_rport_enter_ready(rport);
-		else
-			fc_rport_enter_prli(rport);
+		rdata->maxframe_size = fc_plogi_get_maxframe(plp, lport->mfs);
+		fc_rport_enter_prli(rdata);
 	} else
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 
 out:
 	fc_frame_free(fp);
 err:
 	mutex_unlock(&rdata->rp_mutex);
-	put_device(&rport->dev);
+	kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
 }
 
 /**
  * fc_rport_enter_plogi() - Send Port Login (PLOGI) request to peer
- * @rport: Fibre Channel remote port to send PLOGI to
+ * @rdata: private remote port data
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
  */
-static void fc_rport_enter_plogi(struct fc_rport *rport)
+static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_frame *fp;
 
-	FC_RPORT_DBG(rport, "Port entered PLOGI state from %s state\n",
-		     fc_rport_state(rport));
+	FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
+		     fc_rport_state(rdata));
 
-	fc_rport_state_enter(rport, RPORT_ST_PLOGI);
+	fc_rport_state_enter(rdata, RPORT_ST_PLOGI);
 
-	rport->maxframe_size = FC_MIN_MAX_PAYLOAD;
+	rdata->maxframe_size = FC_MIN_MAX_PAYLOAD;
 	fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi));
 	if (!fp) {
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 		return;
 	}
 	rdata->e_d_tov = lport->e_d_tov;
 
-	if (!lport->tt.elsct_send(lport, rport, fp, ELS_PLOGI,
-				  fc_rport_plogi_resp, rport, lport->e_d_tov))
-		fc_rport_error_retry(rport, fp);
+	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PLOGI,
+				  fc_rport_plogi_resp, rdata, lport->e_d_tov))
+		fc_rport_error_retry(rdata, fp);
 	else
-		get_device(&rport->dev);
+		kref_get(&rdata->kref);
 }
 
 /**
  * fc_rport_prli_resp() - Process Login (PRLI) response handler
  * @sp: current sequence in the PRLI exchange
  * @fp: response frame
- * @rp_arg: Fibre Channel remote port
+ * @rdata_arg: private remote port data
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
  * and then unlock the rport.
  */
 static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
-			       void *rp_arg)
+			       void *rdata_arg)
 {
-	struct fc_rport *rport = rp_arg;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
+	struct fc_rport_priv *rdata = rdata_arg;
 	struct {
 		struct fc_els_prli prli;
 		struct fc_els_spp spp;
@@ -616,21 +661,24 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
 
 	mutex_lock(&rdata->rp_mutex);
 
-	FC_RPORT_DBG(rport, "Received a PRLI response\n");
+	FC_RPORT_DBG(rdata, "Received a PRLI %s\n", fc_els_resp_type(fp));
 
 	if (rdata->rp_state != RPORT_ST_PRLI) {
-		FC_RPORT_DBG(rport, "Received a PRLI response, but in state "
-			     "%s\n", fc_rport_state(rport));
+		FC_RPORT_DBG(rdata, "Received a PRLI response, but in state "
+			     "%s\n", fc_rport_state(rdata));
 		if (IS_ERR(fp))
 			goto err;
 		goto out;
 	}
 
 	if (IS_ERR(fp)) {
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 		goto err;
 	}
 
+	/* reinitialize remote port roles */
+	rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;
+
 	op = fc_frame_payload_op(fp);
 	if (op == ELS_LS_ACC) {
 		pp = fc_frame_payload_get(fp, sizeof(*pp));
@@ -640,90 +688,82 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
 				rdata->flags |= FC_RP_FLAGS_RETRY;
 		}
 
-		rport->supported_classes = FC_COS_CLASS3;
+		rdata->supported_classes = FC_COS_CLASS3;
 		if (fcp_parm & FCP_SPPF_INIT_FCN)
 			roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 		if (fcp_parm & FCP_SPPF_TARG_FCN)
 			roles |= FC_RPORT_ROLE_FCP_TARGET;
 
-		rport->roles = roles;
-		fc_rport_enter_rtv(rport);
+		rdata->ids.roles = roles;
+		fc_rport_enter_rtv(rdata);
 
 	} else {
-		FC_RPORT_DBG(rport, "Bad ELS response for PRLI command\n");
-		rdata->event = RPORT_EV_FAILED;
-		fc_rport_state_enter(rport, RPORT_ST_NONE);
-		queue_work(rport_event_queue, &rdata->event_work);
+		FC_RPORT_DBG(rdata, "Bad ELS response for PRLI command\n");
+		fc_rport_enter_delete(rdata, RPORT_EV_FAILED);
 	}
 
 out:
 	fc_frame_free(fp);
 err:
 	mutex_unlock(&rdata->rp_mutex);
-	put_device(&rport->dev);
+	kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
 }
 
 /**
  * fc_rport_logo_resp() - Logout (LOGO) response handler
  * @sp: current sequence in the LOGO exchange
  * @fp: response frame
- * @rp_arg: Fibre Channel remote port
+ * @rdata_arg: private remote port data
  *
  * Locking Note: This function will be called without the rport lock
  * held, but it will lock, call an _enter_* function or fc_rport_error
  * and then unlock the rport.
  */
 static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
-			       void *rp_arg)
+			       void *rdata_arg)
 {
-	struct fc_rport *rport = rp_arg;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
+	struct fc_rport_priv *rdata = rdata_arg;
 	u8 op;
 
 	mutex_lock(&rdata->rp_mutex);
 
-	FC_RPORT_DBG(rport, "Received a LOGO response\n");
+	FC_RPORT_DBG(rdata, "Received a LOGO %s\n", fc_els_resp_type(fp));
 
 	if (rdata->rp_state != RPORT_ST_LOGO) {
-		FC_RPORT_DBG(rport, "Received a LOGO response, but in state "
-			     "%s\n", fc_rport_state(rport));
+		FC_RPORT_DBG(rdata, "Received a LOGO response, but in state "
+			     "%s\n", fc_rport_state(rdata));
 		if (IS_ERR(fp))
 			goto err;
 		goto out;
 	}
 
 	if (IS_ERR(fp)) {
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 		goto err;
 	}
 
 	op = fc_frame_payload_op(fp);
-	if (op == ELS_LS_ACC) {
-		fc_rport_enter_rtv(rport);
-	} else {
-		FC_RPORT_DBG(rport, "Bad ELS response for LOGO command\n");
-		rdata->event = RPORT_EV_LOGO;
-		fc_rport_state_enter(rport, RPORT_ST_NONE);
-		queue_work(rport_event_queue, &rdata->event_work);
-	}
+	if (op != ELS_LS_ACC)
+		FC_RPORT_DBG(rdata, "Bad ELS response op %x for LOGO command\n",
+			     op);
+	fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
 
 out:
 	fc_frame_free(fp);
 err:
 	mutex_unlock(&rdata->rp_mutex);
-	put_device(&rport->dev);
+	kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
 }
 
 /**
  * fc_rport_enter_prli() - Send Process Login (PRLI) request to peer
- * @rport: Fibre Channel remote port to send PRLI to
+ * @rdata: private remote port data
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
  */
-static void fc_rport_enter_prli(struct fc_rport *rport)
+static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	struct fc_lport *lport = rdata->local_port;
 	struct {
 		struct fc_els_prli prli;
@@ -731,29 +771,38 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
 	} *pp;
 	struct fc_frame *fp;
 
-	FC_RPORT_DBG(rport, "Port entered PRLI state from %s state\n",
-		     fc_rport_state(rport));
+	/*
+	 * If the rport is one of the well known addresses
+	 * we skip PRLI and RTV and go straight to READY.
+	 */
+	if (rdata->ids.port_id >= FC_FID_DOM_MGR) {
+		fc_rport_enter_ready(rdata);
+		return;
+	}
+
+	FC_RPORT_DBG(rdata, "Port entered PRLI state from %s state\n",
+		     fc_rport_state(rdata));
 
-	fc_rport_state_enter(rport, RPORT_ST_PRLI);
+	fc_rport_state_enter(rdata, RPORT_ST_PRLI);
 
 	fp = fc_frame_alloc(lport, sizeof(*pp));
 	if (!fp) {
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, rport, fp, ELS_PRLI,
-				  fc_rport_prli_resp, rport, lport->e_d_tov))
-		fc_rport_error_retry(rport, fp);
+	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI,
+				  fc_rport_prli_resp, rdata, lport->e_d_tov))
+		fc_rport_error_retry(rdata, fp);
 	else
-		get_device(&rport->dev);
+		kref_get(&rdata->kref);
 }
 
 /**
  * fc_rport_els_rtv_resp() - Request Timeout Value response handler
  * @sp: current sequence in the RTV exchange
  * @fp: response frame
- * @rp_arg: Fibre Channel remote port
+ * @rdata_arg: private remote port data
  *
  * Many targets don't seem to support this.
  *
@@ -762,26 +811,25 @@ static void fc_rport_enter_prli(struct fc_rport *rport)
  * and then unlock the rport.
  */
 static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
-			      void *rp_arg)
+			      void *rdata_arg)
 {
-	struct fc_rport *rport = rp_arg;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
+	struct fc_rport_priv *rdata = rdata_arg;
 	u8 op;
 
 	mutex_lock(&rdata->rp_mutex);
 
-	FC_RPORT_DBG(rport, "Received a RTV response\n");
+	FC_RPORT_DBG(rdata, "Received a RTV %s\n", fc_els_resp_type(fp));
 
 	if (rdata->rp_state != RPORT_ST_RTV) {
-		FC_RPORT_DBG(rport, "Received a RTV response, but in state "
-			     "%s\n", fc_rport_state(rport));
+		FC_RPORT_DBG(rdata, "Received a RTV response, but in state "
+			     "%s\n", fc_rport_state(rdata));
 		if (IS_ERR(fp))
 			goto err;
 		goto out;
 	}
 
 	if (IS_ERR(fp)) {
-		fc_rport_error(rport, fp);
+		fc_rport_error(rdata, fp);
 		goto err;
 	}
 
@@ -807,184 +855,376 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
 		}
 	}
 
-	fc_rport_enter_ready(rport);
+	fc_rport_enter_ready(rdata);
 
 out:
 	fc_frame_free(fp);
 err:
 	mutex_unlock(&rdata->rp_mutex);
-	put_device(&rport->dev);
+	kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
 }
 
 /**
  * fc_rport_enter_rtv() - Send Request Timeout Value (RTV) request to peer
- * @rport: Fibre Channel remote port to send RTV to
+ * @rdata: private remote port data
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
  */
-static void fc_rport_enter_rtv(struct fc_rport *rport)
+static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
 {
 	struct fc_frame *fp;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	struct fc_lport *lport = rdata->local_port;
 
-	FC_RPORT_DBG(rport, "Port entered RTV state from %s state\n",
-		     fc_rport_state(rport));
+	FC_RPORT_DBG(rdata, "Port entered RTV state from %s state\n",
+		     fc_rport_state(rdata));
 
-	fc_rport_state_enter(rport, RPORT_ST_RTV);
+	fc_rport_state_enter(rdata, RPORT_ST_RTV);
 
 	fp = fc_frame_alloc(lport, sizeof(struct fc_els_rtv));
 	if (!fp) {
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, rport, fp, ELS_RTV,
-				     fc_rport_rtv_resp, rport, lport->e_d_tov))
-		fc_rport_error_retry(rport, fp);
+	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_RTV,
+				     fc_rport_rtv_resp, rdata, lport->e_d_tov))
+		fc_rport_error_retry(rdata, fp);
 	else
-		get_device(&rport->dev);
+		kref_get(&rdata->kref);
 }
 
 /**
  * fc_rport_enter_logo() - Send Logout (LOGO) request to peer
- * @rport: Fibre Channel remote port to send LOGO to
+ * @rdata: private remote port data
  *
  * Locking Note: The rport lock is expected to be held before calling
  * this routine.
  */
-static void fc_rport_enter_logo(struct fc_rport *rport)
+static void fc_rport_enter_logo(struct fc_rport_priv *rdata)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_frame *fp;
 
-	FC_RPORT_DBG(rport, "Port entered LOGO state from %s state\n",
-		     fc_rport_state(rport));
+	FC_RPORT_DBG(rdata, "Port entered LOGO state from %s state\n",
+		     fc_rport_state(rdata));
 
-	fc_rport_state_enter(rport, RPORT_ST_LOGO);
+	fc_rport_state_enter(rdata, RPORT_ST_LOGO);
 
 	fp = fc_frame_alloc(lport, sizeof(struct fc_els_logo));
 	if (!fp) {
-		fc_rport_error_retry(rport, fp);
+		fc_rport_error_retry(rdata, fp);
 		return;
 	}
 
-	if (!lport->tt.elsct_send(lport, rport, fp, ELS_LOGO,
-				  fc_rport_logo_resp, rport, lport->e_d_tov))
-		fc_rport_error_retry(rport, fp);
+	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_LOGO,
+				  fc_rport_logo_resp, rdata, lport->e_d_tov))
+		fc_rport_error_retry(rdata, fp);
 	else
-		get_device(&rport->dev);
+		kref_get(&rdata->kref);
 }
 
-
 /**
- * fc_rport_recv_req() - Receive a request from a rport
- * @sp: current sequence in the PLOGI exchange
+ * fc_rport_els_adisc_resp() - Address Discovery response handler
+ * @sp: current sequence in the ADISC exchange
  * @fp: response frame
- * @rp_arg: Fibre Channel remote port
+ * @rdata_arg: remote port private.
  *
- * Locking Note: Called without the rport lock held. This
- * function will hold the rport lock, call an _enter_*
- * function and then unlock the rport.
+ * Locking Note: This function will be called without the rport lock
+ * held, but it will lock, call an _enter_* function or fc_rport_error
+ * and then unlock the rport.
  */
-void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
-		       struct fc_rport *rport)
+static void fc_rport_adisc_resp(struct fc_seq *sp, struct fc_frame *fp,
+			      void *rdata_arg)
+{
+	struct fc_rport_priv *rdata = rdata_arg;
+	struct fc_els_adisc *adisc;
+	u8 op;
+
+	mutex_lock(&rdata->rp_mutex);
+
+	FC_RPORT_DBG(rdata, "Received a ADISC response\n");
+
+	if (rdata->rp_state != RPORT_ST_ADISC) {
+		FC_RPORT_DBG(rdata, "Received a ADISC resp but in state %s\n",
+			     fc_rport_state(rdata));
+		if (IS_ERR(fp))
+			goto err;
+		goto out;
+	}
+
+	if (IS_ERR(fp)) {
+		fc_rport_error(rdata, fp);
+		goto err;
+	}
+
+	/*
+	 * If address verification failed.  Consider us logged out of the rport.
+	 * Since the rport is still in discovery, we want to be
+	 * logged in, so go to PLOGI state.  Otherwise, go back to READY.
+	 */
+	op = fc_frame_payload_op(fp);
+	adisc = fc_frame_payload_get(fp, sizeof(*adisc));
+	if (op != ELS_LS_ACC || !adisc ||
+	    ntoh24(adisc->adisc_port_id) != rdata->ids.port_id ||
+	    get_unaligned_be64(&adisc->adisc_wwpn) != rdata->ids.port_name ||
+	    get_unaligned_be64(&adisc->adisc_wwnn) != rdata->ids.node_name) {
+		FC_RPORT_DBG(rdata, "ADISC error or mismatch\n");
+		fc_rport_enter_plogi(rdata);
+	} else {
+		FC_RPORT_DBG(rdata, "ADISC OK\n");
+		fc_rport_enter_ready(rdata);
+	}
+out:
+	fc_frame_free(fp);
+err:
+	mutex_unlock(&rdata->rp_mutex);
+	kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
+}
+
+/**
+ * fc_rport_enter_adisc() - Send Address Discover (ADISC) request to peer
+ * @rdata: remote port private data
+ *
+ * Locking Note: The rport lock is expected to be held before calling
+ * this routine.
+ */
+static void fc_rport_enter_adisc(struct fc_rport_priv *rdata)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	struct fc_lport *lport = rdata->local_port;
+	struct fc_frame *fp;
+
+	FC_RPORT_DBG(rdata, "sending ADISC from %s state\n",
+		     fc_rport_state(rdata));
 
+	fc_rport_state_enter(rdata, RPORT_ST_ADISC);
+
+	fp = fc_frame_alloc(lport, sizeof(struct fc_els_adisc));
+	if (!fp) {
+		fc_rport_error_retry(rdata, fp);
+		return;
+	}
+	if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_ADISC,
+				  fc_rport_adisc_resp, rdata, lport->e_d_tov))
+		fc_rport_error_retry(rdata, fp);
+	else
+		kref_get(&rdata->kref);
+}
+
+/**
+ * fc_rport_recv_adisc_req() - Handle incoming Address Discovery (ADISC) Request
+ * @rdata: remote port private
+ * @sp: current sequence in the ADISC exchange
+ * @in_fp: ADISC request frame
+ *
+ * Locking Note:  Called with the lport and rport locks held.
+ */
+static void fc_rport_recv_adisc_req(struct fc_rport_priv *rdata,
+				    struct fc_seq *sp, struct fc_frame *in_fp)
+{
+	struct fc_lport *lport = rdata->local_port;
+	struct fc_frame *fp;
+	struct fc_exch *ep = fc_seq_exch(sp);
+	struct fc_els_adisc *adisc;
+	struct fc_seq_els_data rjt_data;
+	u32 f_ctl;
+
+	FC_RPORT_DBG(rdata, "Received ADISC request\n");
+
+	adisc = fc_frame_payload_get(in_fp, sizeof(*adisc));
+	if (!adisc) {
+		rjt_data.fp = NULL;
+		rjt_data.reason = ELS_RJT_PROT;
+		rjt_data.explan = ELS_EXPL_INV_LEN;
+		lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
+		goto drop;
+	}
+
+	fp = fc_frame_alloc(lport, sizeof(*adisc));
+	if (!fp)
+		goto drop;
+	fc_adisc_fill(lport, fp);
+	adisc = fc_frame_payload_get(fp, sizeof(*adisc));
+	adisc->adisc_cmd = ELS_LS_ACC;
+	sp = lport->tt.seq_start_next(sp);
+	f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
+	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
+		       FC_TYPE_ELS, f_ctl, 0);
+	lport->tt.seq_send(lport, sp, fp);
+drop:
+	fc_frame_free(in_fp);
+}
+
+/**
+ * fc_rport_recv_els_req() - handle a validated ELS request.
+ * @lport: Fibre Channel local port
+ * @sp: current sequence in the PLOGI exchange
+ * @fp: response frame
+ *
+ * Handle incoming ELS requests that require port login.
+ * The ELS opcode has already been validated by the caller.
+ *
+ * Locking Note: Called with the lport lock held.
+ */
+static void fc_rport_recv_els_req(struct fc_lport *lport,
+				  struct fc_seq *sp, struct fc_frame *fp)
+{
+	struct fc_rport_priv *rdata;
 	struct fc_frame_header *fh;
 	struct fc_seq_els_data els_data;
-	u8 op;
-
-	mutex_lock(&rdata->rp_mutex);
 
 	els_data.fp = NULL;
-	els_data.explan = ELS_EXPL_NONE;
-	els_data.reason = ELS_RJT_NONE;
+	els_data.reason = ELS_RJT_UNAB;
+	els_data.explan = ELS_EXPL_PLOGI_REQD;
 
 	fh = fc_frame_header_get(fp);
 
-	if (fh->fh_r_ctl == FC_RCTL_ELS_REQ && fh->fh_type == FC_TYPE_ELS) {
-		op = fc_frame_payload_op(fp);
-		switch (op) {
-		case ELS_PLOGI:
-			fc_rport_recv_plogi_req(rport, sp, fp);
-			break;
-		case ELS_PRLI:
-			fc_rport_recv_prli_req(rport, sp, fp);
-			break;
-		case ELS_PRLO:
-			fc_rport_recv_prlo_req(rport, sp, fp);
-			break;
-		case ELS_LOGO:
-			fc_rport_recv_logo_req(rport, sp, fp);
-			break;
-		case ELS_RRQ:
-			els_data.fp = fp;
-			lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data);
-			break;
-		case ELS_REC:
-			els_data.fp = fp;
-			lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data);
-			break;
-		default:
-			els_data.reason = ELS_RJT_UNSUP;
-			lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data);
-			break;
-		}
+	mutex_lock(&lport->disc.disc_mutex);
+	rdata = lport->tt.rport_lookup(lport, ntoh24(fh->fh_s_id));
+	if (!rdata) {
+		mutex_unlock(&lport->disc.disc_mutex);
+		goto reject;
+	}
+	mutex_lock(&rdata->rp_mutex);
+	mutex_unlock(&lport->disc.disc_mutex);
+
+	switch (rdata->rp_state) {
+	case RPORT_ST_PRLI:
+	case RPORT_ST_RTV:
+	case RPORT_ST_READY:
+	case RPORT_ST_ADISC:
+		break;
+	default:
+		mutex_unlock(&rdata->rp_mutex);
+		goto reject;
+	}
+
+	switch (fc_frame_payload_op(fp)) {
+	case ELS_PRLI:
+		fc_rport_recv_prli_req(rdata, sp, fp);
+		break;
+	case ELS_PRLO:
+		fc_rport_recv_prlo_req(rdata, sp, fp);
+		break;
+	case ELS_ADISC:
+		fc_rport_recv_adisc_req(rdata, sp, fp);
+		break;
+	case ELS_RRQ:
+		els_data.fp = fp;
+		lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data);
+		break;
+	case ELS_REC:
+		els_data.fp = fp;
+		lport->tt.seq_els_rsp_send(sp, ELS_REC, &els_data);
+		break;
+	default:
+		fc_frame_free(fp);	/* can't happen */
+		break;
 	}
 
 	mutex_unlock(&rdata->rp_mutex);
+	return;
+
+reject:
+	lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data);
+	fc_frame_free(fp);
+}
+
+/**
+ * fc_rport_recv_req() - Handle a received ELS request from a rport
+ * @sp: current sequence in the PLOGI exchange
+ * @fp: response frame
+ * @lport: Fibre Channel local port
+ *
+ * Locking Note: Called with the lport lock held.
+ */
+void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
+		       struct fc_lport *lport)
+{
+	struct fc_seq_els_data els_data;
+
+	/*
+	 * Handle PLOGI and LOGO requests separately, since they
+	 * don't require prior login.
+	 * Check for unsupported opcodes first and reject them.
+	 * For some ops, it would be incorrect to reject with "PLOGI required".
+	 */
+	switch (fc_frame_payload_op(fp)) {
+	case ELS_PLOGI:
+		fc_rport_recv_plogi_req(lport, sp, fp);
+		break;
+	case ELS_LOGO:
+		fc_rport_recv_logo_req(lport, sp, fp);
+		break;
+	case ELS_PRLI:
+	case ELS_PRLO:
+	case ELS_ADISC:
+	case ELS_RRQ:
+	case ELS_REC:
+		fc_rport_recv_els_req(lport, sp, fp);
+		break;
+	default:
+		fc_frame_free(fp);
+		els_data.fp = NULL;
+		els_data.reason = ELS_RJT_UNSUP;
+		els_data.explan = ELS_EXPL_NONE;
+		lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &els_data);
+		break;
+	}
 }
 
 /**
  * fc_rport_recv_plogi_req() - Handle incoming Port Login (PLOGI) request
- * @rport: Fibre Channel remote port that initiated PLOGI
+ * @lport: local port
  * @sp: current sequence in the PLOGI exchange
  * @fp: PLOGI request frame
  *
- * Locking Note: The rport lock is exected to be held before calling
- * this function.
+ * Locking Note: The rport lock is held before calling this function.
  */
-static void fc_rport_recv_plogi_req(struct fc_rport *rport,
+static void fc_rport_recv_plogi_req(struct fc_lport *lport,
 				    struct fc_seq *sp, struct fc_frame *rx_fp)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-	struct fc_lport *lport = rdata->local_port;
+	struct fc_disc *disc;
+	struct fc_rport_priv *rdata;
 	struct fc_frame *fp = rx_fp;
 	struct fc_exch *ep;
 	struct fc_frame_header *fh;
 	struct fc_els_flogi *pl;
 	struct fc_seq_els_data rjt_data;
-	u32 sid;
-	u64 wwpn;
-	u64 wwnn;
-	enum fc_els_rjt_reason reject = 0;
-	u32 f_ctl;
-	rjt_data.fp = NULL;
+	u32 sid, f_ctl;
 
+	rjt_data.fp = NULL;
 	fh = fc_frame_header_get(fp);
+	sid = ntoh24(fh->fh_s_id);
 
-	FC_RPORT_DBG(rport, "Received PLOGI request while in state %s\n",
-		     fc_rport_state(rport));
+	FC_RPORT_ID_DBG(lport, sid, "Received PLOGI request\n");
 
-	sid = ntoh24(fh->fh_s_id);
 	pl = fc_frame_payload_get(fp, sizeof(*pl));
 	if (!pl) {
-		FC_RPORT_DBG(rport, "Received PLOGI too short\n");
-		WARN_ON(1);
-		/* XXX TBD: send reject? */
-		fc_frame_free(fp);
-		return;
+		FC_RPORT_ID_DBG(lport, sid, "Received PLOGI too short\n");
+		rjt_data.reason = ELS_RJT_PROT;
+		rjt_data.explan = ELS_EXPL_INV_LEN;
+		goto reject;
+	}
+
+	disc = &lport->disc;
+	mutex_lock(&disc->disc_mutex);
+	rdata = lport->tt.rport_create(lport, sid);
+	if (!rdata) {
+		mutex_unlock(&disc->disc_mutex);
+		rjt_data.reason = ELS_RJT_UNAB;
+		rjt_data.explan = ELS_EXPL_INSUF_RES;
+		goto reject;
 	}
-	wwpn = get_unaligned_be64(&pl->fl_wwpn);
-	wwnn = get_unaligned_be64(&pl->fl_wwnn);
+
+	mutex_lock(&rdata->rp_mutex);
+	mutex_unlock(&disc->disc_mutex);
+
+	rdata->ids.port_name = get_unaligned_be64(&pl->fl_wwpn);
+	rdata->ids.node_name = get_unaligned_be64(&pl->fl_wwnn);
 
 	/*
-	 * If the session was just created, possibly due to the incoming PLOGI,
+	 * If the rport was just created, possibly due to the incoming PLOGI,
 	 * set the state appropriately and accept the PLOGI.
 	 *
 	 * If we had also sent a PLOGI, and if the received PLOGI is from a
@@ -996,86 +1236,76 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport,
 	 */
 	switch (rdata->rp_state) {
 	case RPORT_ST_INIT:
-		FC_RPORT_DBG(rport, "Received PLOGI, wwpn %llx state INIT "
-			     "- reject\n", (unsigned long long)wwpn);
-		reject = ELS_RJT_UNSUP;
+		FC_RPORT_DBG(rdata, "Received PLOGI in INIT state\n");
 		break;
 	case RPORT_ST_PLOGI:
-		FC_RPORT_DBG(rport, "Received PLOGI in PLOGI state %d\n",
-			     rdata->rp_state);
-		if (wwpn < lport->wwpn)
-			reject = ELS_RJT_INPROG;
+		FC_RPORT_DBG(rdata, "Received PLOGI in PLOGI state\n");
+		if (rdata->ids.port_name < lport->wwpn) {
+			mutex_unlock(&rdata->rp_mutex);
+			rjt_data.reason = ELS_RJT_INPROG;
+			rjt_data.explan = ELS_EXPL_NONE;
+			goto reject;
+		}
 		break;
 	case RPORT_ST_PRLI:
 	case RPORT_ST_READY:
-		FC_RPORT_DBG(rport, "Received PLOGI in logged-in state %d "
+	case RPORT_ST_ADISC:
+		FC_RPORT_DBG(rdata, "Received PLOGI in logged-in state %d "
 			     "- ignored for now\n", rdata->rp_state);
 		/* XXX TBD - should reset */
 		break;
-	case RPORT_ST_NONE:
+	case RPORT_ST_DELETE:
 	default:
-		FC_RPORT_DBG(rport, "Received PLOGI in unexpected "
-			     "state %d\n", rdata->rp_state);
-		fc_frame_free(fp);
-		return;
-		break;
+		FC_RPORT_DBG(rdata, "Received PLOGI in unexpected state %d\n",
+			     rdata->rp_state);
+		fc_frame_free(rx_fp);
+		goto out;
 	}
 
-	if (reject) {
-		rjt_data.reason = reject;
-		rjt_data.explan = ELS_EXPL_NONE;
-		lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
-		fc_frame_free(fp);
-	} else {
-		fp = fc_frame_alloc(lport, sizeof(*pl));
-		if (fp == NULL) {
-			fp = rx_fp;
-			rjt_data.reason = ELS_RJT_UNAB;
-			rjt_data.explan = ELS_EXPL_NONE;
-			lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
-			fc_frame_free(fp);
-		} else {
-			sp = lport->tt.seq_start_next(sp);
-			WARN_ON(!sp);
-			fc_rport_set_name(rport, wwpn, wwnn);
-
-			/*
-			 * Get session payload size from incoming PLOGI.
-			 */
-			rport->maxframe_size =
-				fc_plogi_get_maxframe(pl, lport->mfs);
-			fc_frame_free(rx_fp);
-			fc_plogi_fill(lport, fp, ELS_LS_ACC);
-
-			/*
-			 * Send LS_ACC.	 If this fails,
-			 * the originator should retry.
-			 */
-			f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
-			f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
-			ep = fc_seq_exch(sp);
-			fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
-				       FC_TYPE_ELS, f_ctl, 0);
-			lport->tt.seq_send(lport, sp, fp);
-			if (rdata->rp_state == RPORT_ST_PLOGI)
-				fc_rport_enter_prli(rport);
-		}
-	}
+	/*
+	 * Get session payload size from incoming PLOGI.
+	 */
+	rdata->maxframe_size = fc_plogi_get_maxframe(pl, lport->mfs);
+	fc_frame_free(rx_fp);
+
+	/*
+	 * Send LS_ACC.	 If this fails, the originator should retry.
+	 */
+	sp = lport->tt.seq_start_next(sp);
+	if (!sp)
+		goto out;
+	fp = fc_frame_alloc(lport, sizeof(*pl));
+	if (!fp)
+		goto out;
+
+	fc_plogi_fill(lport, fp, ELS_LS_ACC);
+	f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
+	ep = fc_seq_exch(sp);
+	fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
+		       FC_TYPE_ELS, f_ctl, 0);
+	lport->tt.seq_send(lport, sp, fp);
+	fc_rport_enter_prli(rdata);
+out:
+	mutex_unlock(&rdata->rp_mutex);
+	return;
+
+reject:
+	lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
+	fc_frame_free(fp);
 }
 
 /**
  * fc_rport_recv_prli_req() - Handle incoming Process Login (PRLI) request
- * @rport: Fibre Channel remote port that initiated PRLI
+ * @rdata: private remote port data
  * @sp: current sequence in the PRLI exchange
  * @fp: PRLI request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
  */
-static void fc_rport_recv_prli_req(struct fc_rport *rport,
+static void fc_rport_recv_prli_req(struct fc_rport_priv *rdata,
 				   struct fc_seq *sp, struct fc_frame *rx_fp)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	struct fc_lport *lport = rdata->local_port;
 	struct fc_exch *ep;
 	struct fc_frame *fp;
@@ -1099,12 +1329,14 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
 
 	fh = fc_frame_header_get(rx_fp);
 
-	FC_RPORT_DBG(rport, "Received PRLI request while in state %s\n",
-		     fc_rport_state(rport));
+	FC_RPORT_DBG(rdata, "Received PRLI request while in state %s\n",
+		     fc_rport_state(rdata));
 
 	switch (rdata->rp_state) {
 	case RPORT_ST_PRLI:
+	case RPORT_ST_RTV:
 	case RPORT_ST_READY:
+	case RPORT_ST_ADISC:
 		reason = ELS_RJT_NONE;
 		break;
 	default:
@@ -1149,6 +1381,9 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
 		pp->prli.prli_len = htons(len);
 		len -= sizeof(struct fc_els_prli);
 
+		/* reinitialize remote port roles */
+		rdata->ids.roles = FC_RPORT_ROLE_UNKNOWN;
+
 		/*
 		 * Go through all the service parameter pages and build
 		 * response.  If plen indicates longer SPP than standard,
@@ -1169,12 +1404,12 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
 				fcp_parm = ntohl(rspp->spp_params);
 				if (fcp_parm * FCP_SPPF_RETRY)
 					rdata->flags |= FC_RP_FLAGS_RETRY;
-				rport->supported_classes = FC_COS_CLASS3;
+				rdata->supported_classes = FC_COS_CLASS3;
 				if (fcp_parm & FCP_SPPF_INIT_FCN)
 					roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 				if (fcp_parm & FCP_SPPF_TARG_FCN)
 					roles |= FC_RPORT_ROLE_FCP_TARGET;
-				rport->roles = roles;
+				rdata->ids.roles = roles;
 
 				spp->spp_params =
 					htonl(lport->service_params);
@@ -1204,9 +1439,10 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
 		 */
 		switch (rdata->rp_state) {
 		case RPORT_ST_PRLI:
-			fc_rport_enter_ready(rport);
+			fc_rport_enter_ready(rdata);
 			break;
 		case RPORT_ST_READY:
+		case RPORT_ST_ADISC:
 			break;
 		default:
 			break;
@@ -1217,17 +1453,17 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport,
 
 /**
  * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request
- * @rport: Fibre Channel remote port that initiated PRLO
+ * @rdata: private remote port data
  * @sp: current sequence in the PRLO exchange
  * @fp: PRLO request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
  */
-static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
+static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
+				   struct fc_seq *sp,
 				   struct fc_frame *fp)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
 	struct fc_lport *lport = rdata->local_port;
 
 	struct fc_frame_header *fh;
@@ -1235,13 +1471,8 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
 
 	fh = fc_frame_header_get(fp);
 
-	FC_RPORT_DBG(rport, "Received PRLO request while in state %s\n",
-		     fc_rport_state(rport));
-
-	if (rdata->rp_state == RPORT_ST_NONE) {
-		fc_frame_free(fp);
-		return;
-	}
+	FC_RPORT_DBG(rdata, "Received PRLO request while in state %s\n",
+		     fc_rport_state(rdata));
 
 	rjt_data.fp = NULL;
 	rjt_data.reason = ELS_RJT_UNAB;
@@ -1252,35 +1483,46 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp,
 
 /**
  * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request
- * @rport: Fibre Channel remote port that initiated LOGO
+ * @lport: local port.
  * @sp: current sequence in the LOGO exchange
  * @fp: LOGO request frame
  *
  * Locking Note: The rport lock is exected to be held before calling
  * this function.
  */
-static void fc_rport_recv_logo_req(struct fc_rport *rport, struct fc_seq *sp,
+static void fc_rport_recv_logo_req(struct fc_lport *lport,
+				   struct fc_seq *sp,
 				   struct fc_frame *fp)
 {
 	struct fc_frame_header *fh;
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-	struct fc_lport *lport = rdata->local_port;
-
-	fh = fc_frame_header_get(fp);
+	struct fc_rport_priv *rdata;
+	u32 sid;
 
-	FC_RPORT_DBG(rport, "Received LOGO request while in state %s\n",
-		     fc_rport_state(rport));
+	lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
 
-	if (rdata->rp_state == RPORT_ST_NONE) {
-		fc_frame_free(fp);
-		return;
-	}
+	fh = fc_frame_header_get(fp);
+	sid = ntoh24(fh->fh_s_id);
 
-	rdata->event = RPORT_EV_LOGO;
-	fc_rport_state_enter(rport, RPORT_ST_NONE);
-	queue_work(rport_event_queue, &rdata->event_work);
+	mutex_lock(&lport->disc.disc_mutex);
+	rdata = lport->tt.rport_lookup(lport, sid);
+	if (rdata) {
+		mutex_lock(&rdata->rp_mutex);
+		FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",
+			     fc_rport_state(rdata));
 
-	lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
+		/*
+		 * If the remote port was created due to discovery,
+		 * log back in.  It may have seen a stale RSCN about us.
+		 */
+		if (rdata->rp_state != RPORT_ST_DELETE && rdata->disc_id)
+			fc_rport_enter_plogi(rdata);
+		else
+			fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+		mutex_unlock(&rdata->rp_mutex);
+	} else
+		FC_RPORT_ID_DBG(lport, sid,
+				"Received LOGO from non-logged-in port\n");
+	mutex_unlock(&lport->disc.disc_mutex);
 	fc_frame_free(fp);
 }
 
@@ -1291,8 +1533,11 @@ static void fc_rport_flush_queue(void)
 
 int fc_rport_init(struct fc_lport *lport)
 {
+	if (!lport->tt.rport_lookup)
+		lport->tt.rport_lookup = fc_rport_lookup;
+
 	if (!lport->tt.rport_create)
-		lport->tt.rport_create = fc_rport_rogue_create;
+		lport->tt.rport_create = fc_rport_create;
 
 	if (!lport->tt.rport_login)
 		lport->tt.rport_login = fc_rport_login;
@@ -1306,6 +1551,9 @@ int fc_rport_init(struct fc_lport *lport)
 	if (!lport->tt.rport_flush_queue)
 		lport->tt.rport_flush_queue = fc_rport_flush_queue;
 
+	if (!lport->tt.rport_destroy)
+		lport->tt.rport_destroy = fc_rport_destroy;
+
 	return 0;
 }
 EXPORT_SYMBOL(fc_rport_init);
@@ -1327,8 +1575,8 @@ EXPORT_SYMBOL(fc_destroy_rport);
 
 void fc_rport_terminate_io(struct fc_rport *rport)
 {
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;
-	struct fc_lport *lport = rdata->local_port;
+	struct fc_rport_libfc_priv *rp = rport->dd_data;
+	struct fc_lport *lport = rp->local_port;
 
 	lport->tt.exch_mgr_reset(lport, 0, rport->port_id);
 	lport->tt.exch_mgr_reset(lport, rport->port_id, 0);
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index a751f62..8dc73c4 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -109,12 +109,9 @@ inline void iscsi_conn_queue_work(struct iscsi_conn *conn)
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_queue_work);
 
-void
-iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
+static void __iscsi_update_cmdsn(struct iscsi_session *session,
+				 uint32_t exp_cmdsn, uint32_t max_cmdsn)
 {
-	uint32_t max_cmdsn = be32_to_cpu(hdr->max_cmdsn);
-	uint32_t exp_cmdsn = be32_to_cpu(hdr->exp_cmdsn);
-
 	/*
 	 * standard specifies this check for when to update expected and
 	 * max sequence numbers
@@ -138,6 +135,12 @@ iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
 			iscsi_conn_queue_work(session->leadconn);
 	}
 }
+
+void iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
+{
+	__iscsi_update_cmdsn(session, be32_to_cpu(hdr->exp_cmdsn),
+			     be32_to_cpu(hdr->max_cmdsn));
+}
 EXPORT_SYMBOL_GPL(iscsi_update_cmdsn);
 
 /**
@@ -301,8 +304,6 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
 	hdr->flags = ISCSI_ATTR_SIMPLE;
 	int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
 	memcpy(task->lun, hdr->lun, sizeof(task->lun));
-	hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
-	session->cmdsn++;
 	hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
 	cmd_len = sc->cmd_len;
 	if (cmd_len < ISCSI_CDB_SIZE)
@@ -388,6 +389,8 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
 		return -EIO;
 
 	task->state = ISCSI_TASK_RUNNING;
+	hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn);
+	session->cmdsn++;
 
 	conn->scsicmd_pdus_cnt++;
 	ISCSI_DBG_SESSION(session, "iscsi prep [%s cid %d sc %p cdb 0x%x "
@@ -499,6 +502,31 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
 	__iscsi_put_task(task);
 }
 
+/**
+ * iscsi_complete_scsi_task - finish scsi task normally
+ * @task: iscsi task for scsi cmd
+ * @exp_cmdsn: expected cmd sn in cpu format
+ * @max_cmdsn: max cmd sn in cpu format
+ *
+ * This is used when drivers do not need or cannot perform
+ * lower level pdu processing.
+ *
+ * Called with session lock
+ */
+void iscsi_complete_scsi_task(struct iscsi_task *task,
+			      uint32_t exp_cmdsn, uint32_t max_cmdsn)
+{
+	struct iscsi_conn *conn = task->conn;
+
+	ISCSI_DBG_SESSION(conn->session, "[itt 0x%x]\n", task->itt);
+
+	conn->last_recv = jiffies;
+	__iscsi_update_cmdsn(conn->session, exp_cmdsn, max_cmdsn);
+	iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+}
+EXPORT_SYMBOL_GPL(iscsi_complete_scsi_task);
+
+
 /*
  * session lock must be held and if not called for a task that is
  * still pending or from the xmit thread, then xmit thread must
@@ -857,27 +885,102 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
 	}
 }
 
+static int iscsi_nop_out_rsp(struct iscsi_task *task,
+			     struct iscsi_nopin *nop, char *data, int datalen)
+{
+	struct iscsi_conn *conn = task->conn;
+	int rc = 0;
+
+	if (conn->ping_task != task) {
+		/*
+		 * If this is not in response to one of our
+		 * nops then it must be from userspace.
+		 */
+		if (iscsi_recv_pdu(conn->cls_conn, (struct iscsi_hdr *)nop,
+				   data, datalen))
+			rc = ISCSI_ERR_CONN_FAILED;
+	} else
+		mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout);
+	iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+	return rc;
+}
+
 static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 			       char *data, int datalen)
 {
 	struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
 	struct iscsi_hdr rejected_pdu;
+	int opcode, rc = 0;
 
 	conn->exp_statsn = be32_to_cpu(reject->statsn) + 1;
 
-	if (reject->reason == ISCSI_REASON_DATA_DIGEST_ERROR) {
-		if (ntoh24(reject->dlength) > datalen)
-			return ISCSI_ERR_PROTO;
+	if (ntoh24(reject->dlength) > datalen ||
+	    ntoh24(reject->dlength) < sizeof(struct iscsi_hdr)) {
+		iscsi_conn_printk(KERN_ERR, conn, "Cannot handle rejected "
+				  "pdu. Invalid data length (pdu dlength "
+				  "%u, datalen %d\n", ntoh24(reject->dlength),
+				  datalen);
+		return ISCSI_ERR_PROTO;
+	}
+	memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr));
+	opcode = rejected_pdu.opcode & ISCSI_OPCODE_MASK;
+
+	switch (reject->reason) {
+	case ISCSI_REASON_DATA_DIGEST_ERROR:
+		iscsi_conn_printk(KERN_ERR, conn,
+				  "pdu (op 0x%x itt 0x%x) rejected "
+				  "due to DataDigest error.\n",
+				  rejected_pdu.itt, opcode);
+		break;
+	case ISCSI_REASON_IMM_CMD_REJECT:
+		iscsi_conn_printk(KERN_ERR, conn,
+				  "pdu (op 0x%x itt 0x%x) rejected. Too many "
+				  "immediate commands.\n",
+				  rejected_pdu.itt, opcode);
+		/*
+		 * We only send one TMF at a time so if the target could not
+		 * handle it, then it should get fixed (RFC mandates that
+		 * a target can handle one immediate TMF per conn).
+		 *
+		 * For nops-outs, we could have sent more than one if
+		 * the target is sending us lots of nop-ins
+		 */
+		if (opcode != ISCSI_OP_NOOP_OUT)
+			return 0;
 
-		if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) {
-			memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr));
-			iscsi_conn_printk(KERN_ERR, conn,
-					  "pdu (op 0x%x) rejected "
-					  "due to DataDigest error.\n",
-					  rejected_pdu.opcode);
+		 if (rejected_pdu.itt == cpu_to_be32(ISCSI_RESERVED_TAG))
+			/*
+			 * nop-out in response to target's nop-out rejected.
+			 * Just resend.
+			 */
+			iscsi_send_nopout(conn,
+					  (struct iscsi_nopin*)&rejected_pdu);
+		else {
+			struct iscsi_task *task;
+			/*
+			 * Our nop as ping got dropped. We know the target
+			 * and transport are ok so just clean up
+			 */
+			task = iscsi_itt_to_task(conn, rejected_pdu.itt);
+			if (!task) {
+				iscsi_conn_printk(KERN_ERR, conn,
+						 "Invalid pdu reject. Could "
+						 "not lookup rejected task.\n");
+				rc = ISCSI_ERR_BAD_ITT;
+			} else
+				rc = iscsi_nop_out_rsp(task,
+					(struct iscsi_nopin*)&rejected_pdu,
+					NULL, 0);
 		}
+		break;
+	default:
+		iscsi_conn_printk(KERN_ERR, conn,
+				  "pdu (op 0x%x itt 0x%x) rejected. Reason "
+				  "code 0x%x\n", rejected_pdu.itt,
+				  rejected_pdu.opcode, reject->reason);
+		break;
 	}
-	return 0;
+	return rc;
 }
 
 /**
@@ -1038,15 +1141,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 		}
 		conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
 
-		if (conn->ping_task != task)
-			/*
-			 * If this is not in response to one of our
-			 * nops then it must be from userspace.
-			 */
-			goto recv_pdu;
-
-		mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout);
-		iscsi_complete_task(task, ISCSI_TASK_COMPLETED);
+		rc = iscsi_nop_out_rsp(task, (struct iscsi_nopin*)hdr,
+				       data, datalen);
 		break;
 	default:
 		rc = ISCSI_ERR_BAD_OPCODE;
@@ -1212,6 +1308,9 @@ static int iscsi_xmit_task(struct iscsi_conn *conn)
 	struct iscsi_task *task = conn->task;
 	int rc;
 
+	if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx))
+		return -ENODATA;
+
 	__iscsi_get_task(task);
 	spin_unlock_bh(&conn->session->lock);
 	rc = conn->session->tt->xmit_task(task);
@@ -1261,7 +1360,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
 	int rc = 0;
 
 	spin_lock_bh(&conn->session->lock);
-	if (unlikely(conn->suspend_tx)) {
+	if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
 		ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n");
 		spin_unlock_bh(&conn->session->lock);
 		return -ENODATA;
@@ -1270,7 +1369,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
 	if (conn->task) {
 		rc = iscsi_xmit_task(conn);
 	        if (rc)
-		        goto again;
+		        goto done;
 	}
 
 	/*
@@ -1290,7 +1389,7 @@ check_mgmt:
 		}
 		rc = iscsi_xmit_task(conn);
 		if (rc)
-			goto again;
+			goto done;
 	}
 
 	/* process pending command queue */
@@ -1311,14 +1410,14 @@ check_mgmt:
 				list_add_tail(&conn->task->running,
 					      &conn->cmdqueue);
 				conn->task = NULL;
-				goto again;
+				goto done;
 			} else
 				fail_scsi_task(conn->task, DID_ABORT);
 			continue;
 		}
 		rc = iscsi_xmit_task(conn);
 		if (rc)
-			goto again;
+			goto done;
 		/*
 		 * we could continuously get new task requests so
 		 * we need to check the mgmt queue for nops that need to
@@ -1344,16 +1443,14 @@ check_mgmt:
 		conn->task->state = ISCSI_TASK_RUNNING;
 		rc = iscsi_xmit_task(conn);
 		if (rc)
-			goto again;
+			goto done;
 		if (!list_empty(&conn->mgmtqueue))
 			goto check_mgmt;
 	}
 	spin_unlock_bh(&conn->session->lock);
 	return -ENODATA;
 
-again:
-	if (unlikely(conn->suspend_tx))
-		rc = -ENODATA;
+done:
 	spin_unlock_bh(&conn->session->lock);
 	return rc;
 }
@@ -1474,6 +1571,12 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 		goto fault;
 	}
 
+	if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
+		reason = FAILURE_SESSION_IN_RECOVERY;
+		sc->result = DID_REQUEUE;
+		goto fault;
+	}
+
 	if (iscsi_check_cmdsn_window_closed(conn)) {
 		reason = FAILURE_WINDOW_CLOSED;
 		goto reject;
@@ -1497,6 +1600,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 			}
 		}
 		if (session->tt->xmit_task(task)) {
+			session->cmdsn--;
 			reason = FAILURE_SESSION_NOT_READY;
 			goto prepd_reject;
 		}
@@ -1712,6 +1816,33 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, unsigned lun,
 	}
 }
 
+/**
+ * iscsi_suspend_queue - suspend iscsi_queuecommand
+ * @conn: iscsi conn to stop queueing IO on
+ *
+ * This grabs the session lock to make sure no one is in
+ * xmit_task/queuecommand, and then sets suspend to prevent
+ * new commands from being queued. This only needs to be called
+ * by offload drivers that need to sync a path like ep disconnect
+ * with the iscsi_queuecommand/xmit_task. To start IO again libiscsi
+ * will call iscsi_start_tx and iscsi_unblock_session when in FFP.
+ */
+void iscsi_suspend_queue(struct iscsi_conn *conn)
+{
+	spin_lock_bh(&conn->session->lock);
+	set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+	spin_unlock_bh(&conn->session->lock);
+}
+EXPORT_SYMBOL_GPL(iscsi_suspend_queue);
+
+/**
+ * iscsi_suspend_tx - suspend iscsi_data_xmit
+ * @conn: iscsi conn tp stop processing IO on.
+ *
+ * This function sets the suspend bit to prevent iscsi_data_xmit
+ * from sending new IO, and if work is queued on the xmit thread
+ * it will wait for it to be completed.
+ */
 void iscsi_suspend_tx(struct iscsi_conn *conn)
 {
 	struct Scsi_Host *shost = conn->session->host;
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c
index 2742ae8..9ad38e8 100644
--- a/drivers/scsi/libsrp.c
+++ b/drivers/scsi/libsrp.c
@@ -124,6 +124,7 @@ static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max,
 		dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma);
 		kfree(ring[i]);
 	}
+	kfree(ring);
 }
 
 int srp_target_alloc(struct srp_target *target, struct device *dev,
diff --git a/drivers/scsi/lpfc/Makefile b/drivers/scsi/lpfc/Makefile
index 1c28670..ad05d6e 100644
--- a/drivers/scsi/lpfc/Makefile
+++ b/drivers/scsi/lpfc/Makefile
@@ -28,4 +28,4 @@ obj-$(CONFIG_SCSI_LPFC) := lpfc.o
 
 lpfc-objs := lpfc_mem.o lpfc_sli.o lpfc_ct.o lpfc_els.o lpfc_hbadisc.o	\
 	lpfc_init.o lpfc_mbox.o lpfc_nportdisc.o lpfc_scsi.o lpfc_attr.o \
-	lpfc_vport.o lpfc_debugfs.o
+	lpfc_vport.o lpfc_debugfs.o lpfc_bsg.o
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 1877d98..aa10f79 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -312,6 +312,7 @@ struct lpfc_vport {
 #define FC_BYPASSED_MODE        0x20000	 /* NPort is in bypassed mode */
 #define FC_VPORT_NEEDS_REG_VPI	0x80000  /* Needs to have its vpi registered */
 #define FC_RSCN_DEFERRED	0x100000 /* A deferred RSCN being processed */
+#define FC_VPORT_NEEDS_INIT_VPI 0x200000 /* Need to INIT_VPI before FDISC */
 
 	uint32_t ct_flags;
 #define FC_CT_RFF_ID		0x1	 /* RFF_ID accepted by switch */
@@ -440,6 +441,12 @@ enum intr_type_t {
 	MSIX,
 };
 
+struct unsol_rcv_ct_ctx {
+	uint32_t ctxt_id;
+	uint32_t SID;
+	uint32_t oxid;
+};
+
 struct lpfc_hba {
 	/* SCSI interface function jump table entries */
 	int (*lpfc_new_scsi_buf)
@@ -525,6 +532,8 @@ struct lpfc_hba {
 #define FCP_XRI_ABORT_EVENT	0x20
 #define ELS_XRI_ABORT_EVENT	0x40
 #define ASYNC_EVENT		0x80
+#define LINK_DISABLED		0x100 /* Link disabled by user */
+#define FCF_DISC_INPROGRESS	0x200 /* FCF discovery in progress */
 	struct lpfc_dmabuf slim2p;
 
 	MAILBOX_t *mbox;
@@ -616,6 +625,8 @@ struct lpfc_hba {
 	uint32_t hbq_count;	        /* Count of configured HBQs */
 	struct hbq_s hbqs[LPFC_MAX_HBQS]; /* local copy of hbq indicies  */
 
+	uint32_t fcp_qidx;		/* next work queue to post work to */
+
 	unsigned long pci_bar0_map;     /* Physical address for PCI BAR0 */
 	unsigned long pci_bar1_map;     /* Physical address for PCI BAR1 */
 	unsigned long pci_bar2_map;     /* Physical address for PCI BAR2 */
@@ -682,6 +693,7 @@ struct lpfc_hba {
 	struct pci_pool *lpfc_mbuf_pool;
 	struct pci_pool *lpfc_hrb_pool;	/* header receive buffer pool */
 	struct pci_pool *lpfc_drb_pool; /* data receive buffer pool */
+	struct pci_pool *lpfc_hbq_pool;	/* SLI3 hbq buffer pool */
 	struct lpfc_dma_pool lpfc_mbuf_safety_pool;
 
 	mempool_t *mbox_mem_pool;
@@ -763,11 +775,18 @@ struct lpfc_hba {
 /* Maximum number of events that can be outstanding at any time*/
 #define LPFC_MAX_EVT_COUNT 512
 	atomic_t fast_event_count;
+	uint32_t fcoe_eventtag;
+	uint32_t fcoe_eventtag_at_fcf_scan;
 	struct lpfc_fcf fcf;
 	uint8_t fc_map[3];
 	uint8_t valid_vlan;
 	uint16_t vlan_id;
 	struct list_head fcf_conn_rec_list;
+
+	struct mutex ct_event_mutex; /* synchronize access to ct_ev_waiters */
+	struct list_head ct_ev_waiters;
+	struct unsol_rcv_ct_ctx ct_ctx[64];
+	uint32_t ctx_idx;
 };
 
 static inline struct Scsi_Host *
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index fc07be5..e1a30a1 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -394,7 +394,12 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
 	case LPFC_INIT_MBX_CMDS:
 	case LPFC_LINK_DOWN:
 	case LPFC_HBA_ERROR:
-		len += snprintf(buf + len, PAGE_SIZE-len, "Link Down\n");
+		if (phba->hba_flag & LINK_DISABLED)
+			len += snprintf(buf + len, PAGE_SIZE-len,
+				"Link Down - User disabled\n");
+		else
+			len += snprintf(buf + len, PAGE_SIZE-len,
+				"Link Down\n");
 		break;
 	case LPFC_LINK_UP:
 	case LPFC_CLEAR_LA:
@@ -4127,6 +4132,9 @@ struct fc_function_template lpfc_transport_functions = {
 	.vport_disable = lpfc_vport_disable,
 
 	.set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
+
+	.bsg_request = lpfc_bsg_request,
+	.bsg_timeout = lpfc_bsg_timeout,
 };
 
 struct fc_function_template lpfc_vport_transport_functions = {
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c
new file mode 100644
index 0000000..da6bf5a
--- /dev/null
+++ b/drivers/scsi/lpfc/lpfc_bsg.c
@@ -0,0 +1,904 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for         *
+ * Fibre Channel Host Bus Adapters.                                *
+ * Copyright (C) 2009 Emulex.  All rights reserved.                *
+ * EMULEX and SLI are trademarks of Emulex.                        *
+ * www.emulex.com                                                  *
+ *                                                                 *
+ * This program is free software; you can redistribute it and/or   *
+ * modify it under the terms of version 2 of the GNU General       *
+ * Public License as published by the Free Software Foundation.    *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
+ * more details, a copy of which can be found in the file COPYING  *
+ * included with this package.                                     *
+ *******************************************************************/
+
+#include <linux/interrupt.h>
+#include <linux/mempool.h>
+#include <linux/pci.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_fc.h>
+#include <scsi/scsi_bsg_fc.h>
+
+#include "lpfc_hw4.h"
+#include "lpfc_hw.h"
+#include "lpfc_sli.h"
+#include "lpfc_sli4.h"
+#include "lpfc_nl.h"
+#include "lpfc_disc.h"
+#include "lpfc_scsi.h"
+#include "lpfc.h"
+#include "lpfc_logmsg.h"
+#include "lpfc_crtn.h"
+#include "lpfc_vport.h"
+#include "lpfc_version.h"
+
+/**
+ * lpfc_bsg_rport_ct - send a CT command from a bsg request
+ * @job: fc_bsg_job to handle
+ */
+static int
+lpfc_bsg_rport_ct(struct fc_bsg_job *job)
+{
+	struct Scsi_Host *shost = job->shost;
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_rport_data *rdata = job->rport->dd_data;
+	struct lpfc_nodelist *ndlp = rdata->pnode;
+	struct ulp_bde64 *bpl = NULL;
+	uint32_t timeout;
+	struct lpfc_iocbq *cmdiocbq = NULL;
+	struct lpfc_iocbq *rspiocbq = NULL;
+	IOCB_t *cmd;
+	IOCB_t *rsp;
+	struct lpfc_dmabuf *bmp = NULL;
+	int request_nseg;
+	int reply_nseg;
+	struct scatterlist *sgel = NULL;
+	int numbde;
+	dma_addr_t busaddr;
+	int rc = 0;
+
+	/* in case no data is transferred */
+	job->reply->reply_payload_rcv_len = 0;
+
+	if (!lpfc_nlp_get(ndlp)) {
+		job->reply->result = -ENODEV;
+		return 0;
+	}
+
+	if (ndlp->nlp_flag & NLP_ELS_SND_MASK) {
+		rc = -ENODEV;
+		goto free_ndlp_exit;
+	}
+
+	spin_lock_irq(shost->host_lock);
+	cmdiocbq = lpfc_sli_get_iocbq(phba);
+	if (!cmdiocbq) {
+		rc = -ENOMEM;
+		spin_unlock_irq(shost->host_lock);
+		goto free_ndlp_exit;
+	}
+	cmd = &cmdiocbq->iocb;
+
+	rspiocbq = lpfc_sli_get_iocbq(phba);
+	if (!rspiocbq) {
+		rc = -ENOMEM;
+		goto free_cmdiocbq;
+	}
+	spin_unlock_irq(shost->host_lock);
+
+	rsp = &rspiocbq->iocb;
+
+	bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (!bmp) {
+		rc = -ENOMEM;
+		spin_lock_irq(shost->host_lock);
+		goto free_rspiocbq;
+	}
+
+	spin_lock_irq(shost->host_lock);
+	bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
+	if (!bmp->virt) {
+		rc = -ENOMEM;
+		goto free_bmp;
+	}
+	spin_unlock_irq(shost->host_lock);
+
+	INIT_LIST_HEAD(&bmp->list);
+	bpl = (struct ulp_bde64 *) bmp->virt;
+
+	request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
+				  job->request_payload.sg_cnt, DMA_TO_DEVICE);
+	for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
+		busaddr = sg_dma_address(sgel);
+		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+		bpl->tus.f.bdeSize = sg_dma_len(sgel);
+		bpl->tus.w = cpu_to_le32(bpl->tus.w);
+		bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+		bpl++;
+	}
+
+	reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list,
+				job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) {
+		busaddr = sg_dma_address(sgel);
+		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
+		bpl->tus.f.bdeSize = sg_dma_len(sgel);
+		bpl->tus.w = cpu_to_le32(bpl->tus.w);
+		bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+		bpl++;
+	}
+
+	cmd->un.genreq64.bdl.ulpIoTag32 = 0;
+	cmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
+	cmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
+	cmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+	cmd->un.genreq64.bdl.bdeSize =
+		(request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
+	cmd->ulpCommand = CMD_GEN_REQUEST64_CR;
+	cmd->un.genreq64.w5.hcsw.Fctl = (SI | LA);
+	cmd->un.genreq64.w5.hcsw.Dfctl = 0;
+	cmd->un.genreq64.w5.hcsw.Rctl = FC_UNSOL_CTL;
+	cmd->un.genreq64.w5.hcsw.Type = FC_COMMON_TRANSPORT_ULP;
+	cmd->ulpBdeCount = 1;
+	cmd->ulpLe = 1;
+	cmd->ulpClass = CLASS3;
+	cmd->ulpContext = ndlp->nlp_rpi;
+	cmd->ulpOwner = OWN_CHIP;
+	cmdiocbq->vport = phba->pport;
+	cmdiocbq->context1 = NULL;
+	cmdiocbq->context2 = NULL;
+	cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
+
+	timeout = phba->fc_ratov * 2;
+	job->dd_data = cmdiocbq;
+
+	rc = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq, rspiocbq,
+					timeout + LPFC_DRVR_TIMEOUT);
+
+	if (rc != IOCB_TIMEDOUT) {
+		pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+		pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+			     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	}
+
+	if (rc == IOCB_TIMEDOUT) {
+		lpfc_sli_release_iocbq(phba, rspiocbq);
+		rc = -EACCES;
+		goto free_ndlp_exit;
+	}
+
+	if (rc != IOCB_SUCCESS) {
+		rc = -EACCES;
+		goto free_outdmp;
+	}
+
+	if (rsp->ulpStatus) {
+		if (rsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+			switch (rsp->un.ulpWord[4] & 0xff) {
+			case IOERR_SEQUENCE_TIMEOUT:
+				rc = -ETIMEDOUT;
+				break;
+			case IOERR_INVALID_RPI:
+				rc = -EFAULT;
+				break;
+			default:
+				rc = -EACCES;
+				break;
+			}
+			goto free_outdmp;
+		}
+	} else
+		job->reply->reply_payload_rcv_len =
+			rsp->un.genreq64.bdl.bdeSize;
+
+free_outdmp:
+	spin_lock_irq(shost->host_lock);
+	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
+free_bmp:
+	kfree(bmp);
+free_rspiocbq:
+	lpfc_sli_release_iocbq(phba, rspiocbq);
+free_cmdiocbq:
+	lpfc_sli_release_iocbq(phba, cmdiocbq);
+	spin_unlock_irq(shost->host_lock);
+free_ndlp_exit:
+	lpfc_nlp_put(ndlp);
+
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	/* complete the job back to userspace */
+	job->job_done(job);
+
+	return 0;
+}
+
+/**
+ * lpfc_bsg_rport_els - send an ELS command from a bsg request
+ * @job: fc_bsg_job to handle
+ */
+static int
+lpfc_bsg_rport_els(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_rport_data *rdata = job->rport->dd_data;
+	struct lpfc_nodelist *ndlp = rdata->pnode;
+
+	uint32_t elscmd;
+	uint32_t cmdsize;
+	uint32_t rspsize;
+	struct lpfc_iocbq *rspiocbq;
+	struct lpfc_iocbq *cmdiocbq;
+	IOCB_t *rsp;
+	uint16_t rpi = 0;
+	struct lpfc_dmabuf *pcmd;
+	struct lpfc_dmabuf *prsp;
+	struct lpfc_dmabuf *pbuflist = NULL;
+	struct ulp_bde64 *bpl;
+	int iocb_status;
+	int request_nseg;
+	int reply_nseg;
+	struct scatterlist *sgel = NULL;
+	int numbde;
+	dma_addr_t busaddr;
+	int rc = 0;
+
+	/* in case no data is transferred */
+	job->reply->reply_payload_rcv_len = 0;
+
+	if (!lpfc_nlp_get(ndlp)) {
+		rc = -ENODEV;
+		goto out;
+	}
+
+	elscmd = job->request->rqst_data.r_els.els_code;
+	cmdsize = job->request_payload.payload_len;
+	rspsize = job->reply_payload.payload_len;
+	rspiocbq = lpfc_sli_get_iocbq(phba);
+	if (!rspiocbq) {
+		lpfc_nlp_put(ndlp);
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	rsp = &rspiocbq->iocb;
+	rpi = ndlp->nlp_rpi;
+
+	cmdiocbq = lpfc_prep_els_iocb(phba->pport, 1, cmdsize, 0, ndlp,
+				      ndlp->nlp_DID, elscmd);
+
+	if (!cmdiocbq) {
+		lpfc_sli_release_iocbq(phba, rspiocbq);
+		return -EIO;
+	}
+
+	job->dd_data = cmdiocbq;
+	pcmd = (struct lpfc_dmabuf *) cmdiocbq->context2;
+	prsp = (struct lpfc_dmabuf *) pcmd->list.next;
+
+	lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
+	kfree(pcmd);
+	lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
+	kfree(prsp);
+	cmdiocbq->context2 = NULL;
+
+	pbuflist = (struct lpfc_dmabuf *) cmdiocbq->context3;
+	bpl = (struct ulp_bde64 *) pbuflist->virt;
+
+	request_nseg = pci_map_sg(phba->pcidev, job->request_payload.sg_list,
+				  job->request_payload.sg_cnt, DMA_TO_DEVICE);
+
+	for_each_sg(job->request_payload.sg_list, sgel, request_nseg, numbde) {
+		busaddr = sg_dma_address(sgel);
+		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+		bpl->tus.f.bdeSize = sg_dma_len(sgel);
+		bpl->tus.w = cpu_to_le32(bpl->tus.w);
+		bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+		bpl++;
+	}
+
+	reply_nseg = pci_map_sg(phba->pcidev, job->reply_payload.sg_list,
+				job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	for_each_sg(job->reply_payload.sg_list, sgel, reply_nseg, numbde) {
+		busaddr = sg_dma_address(sgel);
+		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
+		bpl->tus.f.bdeSize = sg_dma_len(sgel);
+		bpl->tus.w = cpu_to_le32(bpl->tus.w);
+		bpl->addrLow = cpu_to_le32(putPaddrLow(busaddr));
+		bpl->addrHigh = cpu_to_le32(putPaddrHigh(busaddr));
+		bpl++;
+	}
+
+	cmdiocbq->iocb.un.elsreq64.bdl.bdeSize =
+		(request_nseg + reply_nseg) * sizeof(struct ulp_bde64);
+	cmdiocbq->iocb.ulpContext = rpi;
+	cmdiocbq->iocb_flag |= LPFC_IO_LIBDFC;
+	cmdiocbq->context1 = NULL;
+	cmdiocbq->context2 = NULL;
+
+	iocb_status = lpfc_sli_issue_iocb_wait(phba, LPFC_ELS_RING, cmdiocbq,
+					rspiocbq, (phba->fc_ratov * 2)
+					       + LPFC_DRVR_TIMEOUT);
+
+	/* release the new ndlp once the iocb completes */
+	lpfc_nlp_put(ndlp);
+	if (iocb_status != IOCB_TIMEDOUT) {
+		pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
+			     job->request_payload.sg_cnt, DMA_TO_DEVICE);
+		pci_unmap_sg(phba->pcidev, job->reply_payload.sg_list,
+			     job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
+	}
+
+	if (iocb_status == IOCB_SUCCESS) {
+		if (rsp->ulpStatus == IOSTAT_SUCCESS) {
+			job->reply->reply_payload_rcv_len =
+				rsp->un.elsreq64.bdl.bdeSize;
+			rc = 0;
+		} else if (rsp->ulpStatus == IOSTAT_LS_RJT) {
+			struct fc_bsg_ctels_reply *els_reply;
+			/* LS_RJT data returned in word 4 */
+			uint8_t *rjt_data = (uint8_t *)&rsp->un.ulpWord[4];
+
+			els_reply = &job->reply->reply_data.ctels_reply;
+			job->reply->result = 0;
+			els_reply->status = FC_CTELS_STATUS_REJECT;
+			els_reply->rjt_data.action = rjt_data[0];
+			els_reply->rjt_data.reason_code = rjt_data[1];
+			els_reply->rjt_data.reason_explanation = rjt_data[2];
+			els_reply->rjt_data.vendor_unique = rjt_data[3];
+		} else
+			rc = -EIO;
+	} else
+		rc = -EIO;
+
+	if (iocb_status != IOCB_TIMEDOUT)
+		lpfc_els_free_iocb(phba, cmdiocbq);
+
+	lpfc_sli_release_iocbq(phba, rspiocbq);
+
+out:
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	/* complete the job back to userspace */
+	job->job_done(job);
+
+	return 0;
+}
+
+struct lpfc_ct_event {
+	struct list_head node;
+	int ref;
+	wait_queue_head_t wq;
+
+	/* Event type and waiter identifiers */
+	uint32_t type_mask;
+	uint32_t req_id;
+	uint32_t reg_id;
+
+	/* next two flags are here for the auto-delete logic */
+	unsigned long wait_time_stamp;
+	int waiting;
+
+	/* seen and not seen events */
+	struct list_head events_to_get;
+	struct list_head events_to_see;
+};
+
+struct event_data {
+	struct list_head node;
+	uint32_t type;
+	uint32_t immed_dat;
+	void *data;
+	uint32_t len;
+};
+
+static struct lpfc_ct_event *
+lpfc_ct_event_new(int ev_reg_id, uint32_t ev_req_id)
+{
+	struct lpfc_ct_event *evt = kzalloc(sizeof(*evt), GFP_KERNEL);
+	if (!evt)
+		return NULL;
+
+	INIT_LIST_HEAD(&evt->events_to_get);
+	INIT_LIST_HEAD(&evt->events_to_see);
+	evt->req_id = ev_req_id;
+	evt->reg_id = ev_reg_id;
+	evt->wait_time_stamp = jiffies;
+	init_waitqueue_head(&evt->wq);
+
+	return evt;
+}
+
+static void
+lpfc_ct_event_free(struct lpfc_ct_event *evt)
+{
+	struct event_data *ed;
+
+	list_del(&evt->node);
+
+	while (!list_empty(&evt->events_to_get)) {
+		ed = list_entry(evt->events_to_get.next, typeof(*ed), node);
+		list_del(&ed->node);
+		kfree(ed->data);
+		kfree(ed);
+	}
+
+	while (!list_empty(&evt->events_to_see)) {
+		ed = list_entry(evt->events_to_see.next, typeof(*ed), node);
+		list_del(&ed->node);
+		kfree(ed->data);
+		kfree(ed);
+	}
+
+	kfree(evt);
+}
+
+static inline void
+lpfc_ct_event_ref(struct lpfc_ct_event *evt)
+{
+	evt->ref++;
+}
+
+static inline void
+lpfc_ct_event_unref(struct lpfc_ct_event *evt)
+{
+	if (--evt->ref < 0)
+		lpfc_ct_event_free(evt);
+}
+
+#define SLI_CT_ELX_LOOPBACK 0x10
+
+enum ELX_LOOPBACK_CMD {
+	ELX_LOOPBACK_XRI_SETUP,
+	ELX_LOOPBACK_DATA,
+};
+
+/**
+ * lpfc_bsg_ct_unsol_event - process an unsolicited CT command
+ * @phba:
+ * @pring:
+ * @piocbq:
+ *
+ * This function is called when an unsolicited CT command is received.  It
+ * forwards the event to any processes registerd to receive CT events.
+ */
+void
+lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+			struct lpfc_iocbq *piocbq)
+{
+	uint32_t evt_req_id = 0;
+	uint32_t cmd;
+	uint32_t len;
+	struct lpfc_dmabuf *dmabuf = NULL;
+	struct lpfc_ct_event *evt;
+	struct event_data *evt_dat = NULL;
+	struct lpfc_iocbq *iocbq;
+	size_t offset = 0;
+	struct list_head head;
+	struct ulp_bde64 *bde;
+	dma_addr_t dma_addr;
+	int i;
+	struct lpfc_dmabuf *bdeBuf1 = piocbq->context2;
+	struct lpfc_dmabuf *bdeBuf2 = piocbq->context3;
+	struct lpfc_hbq_entry *hbqe;
+	struct lpfc_sli_ct_request *ct_req;
+
+	INIT_LIST_HEAD(&head);
+	list_add_tail(&head, &piocbq->list);
+
+	if (piocbq->iocb.ulpBdeCount == 0 ||
+	    piocbq->iocb.un.cont64[0].tus.f.bdeSize == 0)
+		goto error_ct_unsol_exit;
+
+	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)
+		dmabuf = bdeBuf1;
+	else {
+		dma_addr = getPaddr(piocbq->iocb.un.cont64[0].addrHigh,
+				    piocbq->iocb.un.cont64[0].addrLow);
+		dmabuf = lpfc_sli_ringpostbuf_get(phba, pring, dma_addr);
+	}
+
+	ct_req = (struct lpfc_sli_ct_request *)dmabuf->virt;
+	evt_req_id = ct_req->FsType;
+	cmd = ct_req->CommandResponse.bits.CmdRsp;
+	len = ct_req->CommandResponse.bits.Size;
+	if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
+		lpfc_sli_ringpostbuf_put(phba, pring, dmabuf);
+
+	mutex_lock(&phba->ct_event_mutex);
+	list_for_each_entry(evt, &phba->ct_ev_waiters, node) {
+		if (evt->req_id != evt_req_id)
+			continue;
+
+		lpfc_ct_event_ref(evt);
+
+		evt_dat = kzalloc(sizeof(*evt_dat), GFP_KERNEL);
+		if (!evt_dat) {
+			lpfc_ct_event_unref(evt);
+			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+					"2614 Memory allocation failed for "
+					"CT event\n");
+			break;
+		}
+
+		mutex_unlock(&phba->ct_event_mutex);
+
+		if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
+			/* take accumulated byte count from the last iocbq */
+			iocbq = list_entry(head.prev, typeof(*iocbq), list);
+			evt_dat->len = iocbq->iocb.unsli3.rcvsli3.acc_len;
+		} else {
+			list_for_each_entry(iocbq, &head, list) {
+				for (i = 0; i < iocbq->iocb.ulpBdeCount; i++)
+					evt_dat->len +=
+					iocbq->iocb.un.cont64[i].tus.f.bdeSize;
+			}
+		}
+
+		evt_dat->data = kzalloc(evt_dat->len, GFP_KERNEL);
+		if (!evt_dat->data) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+					"2615 Memory allocation failed for "
+					"CT event data, size %d\n",
+					evt_dat->len);
+			kfree(evt_dat);
+			mutex_lock(&phba->ct_event_mutex);
+			lpfc_ct_event_unref(evt);
+			mutex_unlock(&phba->ct_event_mutex);
+			goto error_ct_unsol_exit;
+		}
+
+		list_for_each_entry(iocbq, &head, list) {
+			if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
+				bdeBuf1 = iocbq->context2;
+				bdeBuf2 = iocbq->context3;
+			}
+			for (i = 0; i < iocbq->iocb.ulpBdeCount; i++) {
+				int size = 0;
+				if (phba->sli3_options &
+				    LPFC_SLI3_HBQ_ENABLED) {
+					if (i == 0) {
+						hbqe = (struct lpfc_hbq_entry *)
+						  &iocbq->iocb.un.ulpWord[0];
+						size = hbqe->bde.tus.f.bdeSize;
+						dmabuf = bdeBuf1;
+					} else if (i == 1) {
+						hbqe = (struct lpfc_hbq_entry *)
+							&iocbq->iocb.unsli3.
+							sli3Words[4];
+						size = hbqe->bde.tus.f.bdeSize;
+						dmabuf = bdeBuf2;
+					}
+					if ((offset + size) > evt_dat->len)
+						size = evt_dat->len - offset;
+				} else {
+					size = iocbq->iocb.un.cont64[i].
+						tus.f.bdeSize;
+					bde = &iocbq->iocb.un.cont64[i];
+					dma_addr = getPaddr(bde->addrHigh,
+							    bde->addrLow);
+					dmabuf = lpfc_sli_ringpostbuf_get(phba,
+							pring, dma_addr);
+				}
+				if (!dmabuf) {
+					lpfc_printf_log(phba, KERN_ERR,
+						LOG_LIBDFC, "2616 No dmabuf "
+						"found for iocbq 0x%p\n",
+						iocbq);
+					kfree(evt_dat->data);
+					kfree(evt_dat);
+					mutex_lock(&phba->ct_event_mutex);
+					lpfc_ct_event_unref(evt);
+					mutex_unlock(&phba->ct_event_mutex);
+					goto error_ct_unsol_exit;
+				}
+				memcpy((char *)(evt_dat->data) + offset,
+				       dmabuf->virt, size);
+				offset += size;
+				if (evt_req_id != SLI_CT_ELX_LOOPBACK &&
+				    !(phba->sli3_options &
+				      LPFC_SLI3_HBQ_ENABLED)) {
+					lpfc_sli_ringpostbuf_put(phba, pring,
+								 dmabuf);
+				} else {
+					switch (cmd) {
+					case ELX_LOOPBACK_XRI_SETUP:
+						if (!(phba->sli3_options &
+						      LPFC_SLI3_HBQ_ENABLED))
+							lpfc_post_buffer(phba,
+									 pring,
+									 1);
+						else
+							lpfc_in_buf_free(phba,
+									dmabuf);
+						break;
+					default:
+						if (!(phba->sli3_options &
+						      LPFC_SLI3_HBQ_ENABLED))
+							lpfc_post_buffer(phba,
+									 pring,
+									 1);
+						break;
+					}
+				}
+			}
+		}
+
+		mutex_lock(&phba->ct_event_mutex);
+		if (phba->sli_rev == LPFC_SLI_REV4) {
+			evt_dat->immed_dat = phba->ctx_idx;
+			phba->ctx_idx = (phba->ctx_idx + 1) % 64;
+			phba->ct_ctx[evt_dat->immed_dat].oxid =
+						piocbq->iocb.ulpContext;
+			phba->ct_ctx[evt_dat->immed_dat].SID =
+				piocbq->iocb.un.rcvels.remoteID;
+		} else
+			evt_dat->immed_dat = piocbq->iocb.ulpContext;
+
+		evt_dat->type = FC_REG_CT_EVENT;
+		list_add(&evt_dat->node, &evt->events_to_see);
+		wake_up_interruptible(&evt->wq);
+		lpfc_ct_event_unref(evt);
+		if (evt_req_id == SLI_CT_ELX_LOOPBACK)
+			break;
+	}
+	mutex_unlock(&phba->ct_event_mutex);
+
+error_ct_unsol_exit:
+	if (!list_empty(&head))
+		list_del(&head);
+
+	return;
+}
+
+/**
+ * lpfc_bsg_set_event - process a SET_EVENT bsg vendor command
+ * @job: SET_EVENT fc_bsg_job
+ */
+static int
+lpfc_bsg_set_event(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct set_ct_event *event_req;
+	struct lpfc_ct_event *evt;
+	int rc = 0;
+
+	if (job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct set_ct_event)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2612 Received SET_CT_EVENT below minimum "
+				"size\n");
+		return -EINVAL;
+	}
+
+	event_req = (struct set_ct_event *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+
+	mutex_lock(&phba->ct_event_mutex);
+	list_for_each_entry(evt, &phba->ct_ev_waiters, node) {
+		if (evt->reg_id == event_req->ev_reg_id) {
+			lpfc_ct_event_ref(evt);
+			evt->wait_time_stamp = jiffies;
+			break;
+		}
+	}
+	mutex_unlock(&phba->ct_event_mutex);
+
+	if (&evt->node == &phba->ct_ev_waiters) {
+		/* no event waiting struct yet - first call */
+		evt = lpfc_ct_event_new(event_req->ev_reg_id,
+					event_req->ev_req_id);
+		if (!evt) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+					"2617 Failed allocation of event "
+					"waiter\n");
+			return -ENOMEM;
+		}
+
+		mutex_lock(&phba->ct_event_mutex);
+		list_add(&evt->node, &phba->ct_ev_waiters);
+		lpfc_ct_event_ref(evt);
+		mutex_unlock(&phba->ct_event_mutex);
+	}
+
+	evt->waiting = 1;
+	if (wait_event_interruptible(evt->wq,
+				     !list_empty(&evt->events_to_see))) {
+		mutex_lock(&phba->ct_event_mutex);
+		lpfc_ct_event_unref(evt); /* release ref */
+		lpfc_ct_event_unref(evt); /* delete */
+		mutex_unlock(&phba->ct_event_mutex);
+		rc = -EINTR;
+		goto set_event_out;
+	}
+
+	evt->wait_time_stamp = jiffies;
+	evt->waiting = 0;
+
+	mutex_lock(&phba->ct_event_mutex);
+	list_move(evt->events_to_see.prev, &evt->events_to_get);
+	lpfc_ct_event_unref(evt); /* release ref */
+	mutex_unlock(&phba->ct_event_mutex);
+
+set_event_out:
+	/* set_event carries no reply payload */
+	job->reply->reply_payload_rcv_len = 0;
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	/* complete the job back to userspace */
+	job->job_done(job);
+
+	return 0;
+}
+
+/**
+ * lpfc_bsg_get_event - process a GET_EVENT bsg vendor command
+ * @job: GET_EVENT fc_bsg_job
+ */
+static int
+lpfc_bsg_get_event(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct get_ct_event *event_req;
+	struct get_ct_event_reply *event_reply;
+	struct lpfc_ct_event *evt;
+	struct event_data *evt_dat = NULL;
+	int rc = 0;
+
+	if (job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct get_ct_event)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"2613 Received GET_CT_EVENT request below "
+				"minimum size\n");
+		return -EINVAL;
+	}
+
+	event_req = (struct get_ct_event *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+
+	event_reply = (struct get_ct_event_reply *)
+		job->reply->reply_data.vendor_reply.vendor_rsp;
+
+	mutex_lock(&phba->ct_event_mutex);
+	list_for_each_entry(evt, &phba->ct_ev_waiters, node) {
+		if (evt->reg_id == event_req->ev_reg_id) {
+			if (list_empty(&evt->events_to_get))
+				break;
+			lpfc_ct_event_ref(evt);
+			evt->wait_time_stamp = jiffies;
+			evt_dat = list_entry(evt->events_to_get.prev,
+					     struct event_data, node);
+			list_del(&evt_dat->node);
+			break;
+		}
+	}
+	mutex_unlock(&phba->ct_event_mutex);
+
+	if (!evt_dat) {
+		job->reply->reply_payload_rcv_len = 0;
+		rc = -ENOENT;
+		goto error_get_event_exit;
+	}
+
+	if (evt_dat->len > job->reply_payload.payload_len) {
+		evt_dat->len = job->reply_payload.payload_len;
+			lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+					"2618 Truncated event data at %d "
+					"bytes\n",
+					job->reply_payload.payload_len);
+	}
+
+	event_reply->immed_data = evt_dat->immed_dat;
+
+	if (evt_dat->len > 0)
+		job->reply->reply_payload_rcv_len =
+			sg_copy_from_buffer(job->reply_payload.sg_list,
+					    job->reply_payload.sg_cnt,
+					    evt_dat->data, evt_dat->len);
+	else
+		job->reply->reply_payload_rcv_len = 0;
+	rc = 0;
+
+	if (evt_dat)
+		kfree(evt_dat->data);
+	kfree(evt_dat);
+	mutex_lock(&phba->ct_event_mutex);
+	lpfc_ct_event_unref(evt);
+	mutex_unlock(&phba->ct_event_mutex);
+
+error_get_event_exit:
+	/* make error code available to userspace */
+	job->reply->result = rc;
+	/* complete the job back to userspace */
+	job->job_done(job);
+
+	return rc;
+}
+
+/**
+ * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
+ * @job: fc_bsg_job to handle
+ */
+static int
+lpfc_bsg_hst_vendor(struct fc_bsg_job *job)
+{
+	int command = job->request->rqst_data.h_vendor.vendor_cmd[0];
+
+	switch (command) {
+	case LPFC_BSG_VENDOR_SET_CT_EVENT:
+		return lpfc_bsg_set_event(job);
+		break;
+
+	case LPFC_BSG_VENDOR_GET_CT_EVENT:
+		return lpfc_bsg_get_event(job);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * lpfc_bsg_request - handle a bsg request from the FC transport
+ * @job: fc_bsg_job to handle
+ */
+int
+lpfc_bsg_request(struct fc_bsg_job *job)
+{
+	uint32_t msgcode;
+	int rc = -EINVAL;
+
+	msgcode = job->request->msgcode;
+
+	switch (msgcode) {
+	case FC_BSG_HST_VENDOR:
+		rc = lpfc_bsg_hst_vendor(job);
+		break;
+	case FC_BSG_RPT_ELS:
+		rc = lpfc_bsg_rport_els(job);
+		break;
+	case FC_BSG_RPT_CT:
+		rc = lpfc_bsg_rport_ct(job);
+		break;
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * lpfc_bsg_timeout - handle timeout of a bsg request from the FC transport
+ * @job: fc_bsg_job that has timed out
+ *
+ * This function just aborts the job's IOCB.  The aborted IOCB will return to
+ * the waiting function which will handle passing the error back to userspace
+ */
+int
+lpfc_bsg_timeout(struct fc_bsg_job *job)
+{
+	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)job->dd_data;
+	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
+
+	if (cmdiocb)
+		lpfc_sli_issue_abort_iotag(phba, pring, cmdiocb);
+
+	return 0;
+}
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index d2a9229..0830f37 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -21,9 +21,11 @@
 typedef int (*node_filter)(struct lpfc_nodelist *, void *);
 
 struct fc_rport;
-void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
+void lpfc_down_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
+void lpfc_sli_read_link_ste(struct lpfc_hba *);
+void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t);
 void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *);
-void lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
+int lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
 int lpfc_dump_fcoe_param(struct lpfc_hba *, struct lpfcMboxq *);
 void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
 void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
@@ -135,6 +137,9 @@ int lpfc_els_disc_adisc(struct lpfc_vport *);
 int lpfc_els_disc_plogi(struct lpfc_vport *);
 void lpfc_els_timeout(unsigned long);
 void lpfc_els_timeout_handler(struct lpfc_vport *);
+struct lpfc_iocbq *lpfc_prep_els_iocb(struct lpfc_vport *, uint8_t, uint16_t,
+				      uint8_t, struct lpfc_nodelist *,
+				      uint32_t, uint32_t);
 void lpfc_hb_timeout_handler(struct lpfc_hba *);
 
 void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
@@ -182,11 +187,12 @@ int lpfc_mbox_dev_check(struct lpfc_hba *);
 int lpfc_mbox_tmo_val(struct lpfc_hba *, int);
 void lpfc_init_vfi(struct lpfcMboxq *, struct lpfc_vport *);
 void lpfc_reg_vfi(struct lpfcMboxq *, struct lpfc_vport *, dma_addr_t);
-void lpfc_init_vpi(struct lpfcMboxq *, uint16_t);
+void lpfc_init_vpi(struct lpfc_hba *, struct lpfcMboxq *, uint16_t);
 void lpfc_unreg_vfi(struct lpfcMboxq *, uint16_t);
 void lpfc_reg_fcfi(struct lpfc_hba *, struct lpfcMboxq *);
 void lpfc_unreg_fcfi(struct lpfcMboxq *, uint16_t);
 void lpfc_resume_rpi(struct lpfcMboxq *, struct lpfc_nodelist *);
+int lpfc_check_pending_fcoe_event(struct lpfc_hba *, uint8_t);
 
 void lpfc_config_hbq(struct lpfc_hba *, uint32_t, struct lpfc_hbq_init *,
 	uint32_t , LPFC_MBOXQ_t *);
@@ -234,6 +240,7 @@ void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t,
 			struct lpfc_iocbq *, uint32_t);
 void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
+void lpfc_sli_bemem_bcopy(void *, void *, uint32_t);
 void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
 void lpfc_sli_flush_fcp_rings(struct lpfc_hba *);
 int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
@@ -360,3 +367,8 @@ void lpfc_start_fdiscs(struct lpfc_hba *phba);
 #define HBA_EVENT_LINK_UP                2
 #define HBA_EVENT_LINK_DOWN              3
 
+/* functions to support SGIOv4/bsg interface */
+int lpfc_bsg_request(struct fc_bsg_job *);
+int lpfc_bsg_timeout(struct fc_bsg_job *);
+void lpfc_bsg_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
+			     struct lpfc_iocbq *);
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 0e532f0..9df7ed3 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -97,6 +97,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 	struct list_head head;
 	struct lpfc_dmabuf *bdeBuf;
 
+	lpfc_bsg_ct_unsol_event(phba, pring, piocbq);
+
 	if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) {
 		lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
 	} else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) &&
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index f72fdf2..45337cd 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -146,7 +146,7 @@ lpfc_els_chk_latt(struct lpfc_vport *vport)
  *   Pointer to the newly allocated/prepared els iocb data structure
  *   NULL - when els iocb data structure allocation/preparation failed
  **/
-static struct lpfc_iocbq *
+struct lpfc_iocbq *
 lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
 		   uint16_t cmdSize, uint8_t retry,
 		   struct lpfc_nodelist *ndlp, uint32_t did,
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index ed46b24..e6a47e2 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -61,6 +61,7 @@ static uint8_t lpfcAlpaArray[] = {
 
 static void lpfc_disc_timeout_handler(struct lpfc_vport *);
 static void lpfc_disc_flush_list(struct lpfc_vport *vport);
+static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
 
 void
 lpfc_terminate_rport_io(struct fc_rport *rport)
@@ -1009,9 +1010,15 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 	spin_lock_irqsave(&phba->hbalock, flags);
 	phba->fcf.fcf_flag |= FCF_REGISTERED;
 	spin_unlock_irqrestore(&phba->hbalock, flags);
+	/* If there is a pending FCoE event, restart FCF table scan. */
+	if (lpfc_check_pending_fcoe_event(phba, 1)) {
+		mempool_free(mboxq, phba->mbox_mem_pool);
+		return;
+	}
 	if (vport->port_state != LPFC_FLOGI) {
 		spin_lock_irqsave(&phba->hbalock, flags);
 		phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 		lpfc_initial_flogi(vport);
 	}
@@ -1054,6 +1061,39 @@ lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record)
 }
 
 /**
+ * lpfc_sw_name_match - Check if the fcf switch name match.
+ * @fab_name: pointer to fabric name.
+ * @new_fcf_record: pointer to fcf record.
+ *
+ * This routine compare the fcf record's switch name with provided
+ * switch name. If the switch name are identical this function
+ * returns 1 else return 0.
+ **/
+static uint32_t
+lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record)
+{
+	if ((sw_name[0] ==
+		bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) &&
+	    (sw_name[1] ==
+		bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) &&
+	    (sw_name[2] ==
+		bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) &&
+	    (sw_name[3] ==
+		bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) &&
+	    (sw_name[4] ==
+		bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) &&
+	    (sw_name[5] ==
+		bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) &&
+	    (sw_name[6] ==
+		bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) &&
+	    (sw_name[7] ==
+		bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record)))
+		return 1;
+	else
+		return 0;
+}
+
+/**
  * lpfc_mac_addr_match - Check if the fcf mac address match.
  * @phba: pointer to lpfc hba data structure.
  * @new_fcf_record: pointer to fcf record.
@@ -1123,6 +1163,22 @@ lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record)
 		bf_get(lpfc_fcf_record_mac_5, new_fcf_record);
 	phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record);
 	phba->fcf.priority = new_fcf_record->fip_priority;
+	phba->fcf.switch_name[0] =
+		bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record);
+	phba->fcf.switch_name[1] =
+		bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record);
+	phba->fcf.switch_name[2] =
+		bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record);
+	phba->fcf.switch_name[3] =
+		bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record);
+	phba->fcf.switch_name[4] =
+		bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record);
+	phba->fcf.switch_name[5] =
+		bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record);
+	phba->fcf.switch_name[6] =
+		bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record);
+	phba->fcf.switch_name[7] =
+		bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record);
 }
 
 /**
@@ -1150,6 +1206,7 @@ lpfc_register_fcf(struct lpfc_hba *phba)
 	/* The FCF is already registered, start discovery */
 	if (phba->fcf.fcf_flag & FCF_REGISTERED) {
 		phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE);
+		phba->hba_flag &= ~FCF_DISC_INPROGRESS;
 		spin_unlock_irqrestore(&phba->hbalock, flags);
 		if (phba->pport->port_state != LPFC_FLOGI)
 			lpfc_initial_flogi(phba->pport);
@@ -1239,9 +1296,12 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
 
 		if ((conn_entry->conn_rec.flags & FCFCNCT_FBNM_VALID) &&
 			!lpfc_fab_name_match(conn_entry->conn_rec.fabric_name,
-				new_fcf_record))
+					     new_fcf_record))
+			continue;
+		if ((conn_entry->conn_rec.flags & FCFCNCT_SWNM_VALID) &&
+			!lpfc_sw_name_match(conn_entry->conn_rec.switch_name,
+					    new_fcf_record))
 			continue;
-
 		if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) {
 			/*
 			 * If the vlan bit map does not have the bit set for the
@@ -1336,6 +1396,60 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba,
 }
 
 /**
+ * lpfc_check_pending_fcoe_event - Check if there is pending fcoe event.
+ * @phba: pointer to lpfc hba data structure.
+ * @unreg_fcf: Unregister FCF if FCF table need to be re-scaned.
+ *
+ * This function check if there is any fcoe event pending while driver
+ * scan FCF entries. If there is any pending event, it will restart the
+ * FCF saning and return 1 else return 0.
+ */
+int
+lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf)
+{
+	LPFC_MBOXQ_t *mbox;
+	int rc;
+	/*
+	 * If the Link is up and no FCoE events while in the
+	 * FCF discovery, no need to restart FCF discovery.
+	 */
+	if ((phba->link_state  >= LPFC_LINK_UP) &&
+		(phba->fcoe_eventtag == phba->fcoe_eventtag_at_fcf_scan))
+		return 0;
+
+	spin_lock_irq(&phba->hbalock);
+	phba->fcf.fcf_flag &= ~FCF_AVAILABLE;
+	spin_unlock_irq(&phba->hbalock);
+
+	if (phba->link_state >= LPFC_LINK_UP)
+		lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST);
+
+	if (unreg_fcf) {
+		spin_lock_irq(&phba->hbalock);
+		phba->fcf.fcf_flag &= ~FCF_REGISTERED;
+		spin_unlock_irq(&phba->hbalock);
+		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+		if (!mbox) {
+			lpfc_printf_log(phba, KERN_ERR,
+				LOG_DISCOVERY|LOG_MBOX,
+				"2610 UNREG_FCFI mbox allocation failed\n");
+			return 1;
+		}
+		lpfc_unreg_fcfi(mbox, phba->fcf.fcfi);
+		mbox->vport = phba->pport;
+		mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl;
+		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
+		if (rc == MBX_NOT_FINISHED) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
+				"2611 UNREG_FCFI issue mbox failed\n");
+			mempool_free(mbox, phba->mbox_mem_pool);
+		}
+	}
+
+	return 1;
+}
+
+/**
  * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox.
  * @phba: pointer to lpfc hba data structure.
  * @mboxq: pointer to mailbox object.
@@ -1367,6 +1481,12 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 	unsigned long flags;
 	uint16_t vlan_id;
 
+	/* If there is pending FCoE event restart FCF table scan */
+	if (lpfc_check_pending_fcoe_event(phba, 0)) {
+		lpfc_sli4_mbox_cmd_free(phba, mboxq);
+		return;
+	}
+
 	/* Get the first SGE entry from the non-embedded DMA memory. This
 	 * routine only uses a single SGE.
 	 */
@@ -1424,7 +1544,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 	spin_lock_irqsave(&phba->hbalock, flags);
 	if (phba->fcf.fcf_flag & FCF_IN_USE) {
 		if (lpfc_fab_name_match(phba->fcf.fabric_name,
-			new_fcf_record) &&
+					new_fcf_record) &&
+		    lpfc_sw_name_match(phba->fcf.switch_name,
+					new_fcf_record) &&
 		    lpfc_mac_addr_match(phba, new_fcf_record)) {
 			phba->fcf.fcf_flag |= FCF_AVAILABLE;
 			spin_unlock_irqrestore(&phba->hbalock, flags);
@@ -1464,9 +1586,9 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
 		 * If there is a record with lower priority value for
 		 * the current FCF, use that record.
 		 */
-		if (lpfc_fab_name_match(phba->fcf.fabric_name, new_fcf_record)
-			&& (new_fcf_record->fip_priority <
-				phba->fcf.priority)) {
+		if (lpfc_fab_name_match(phba->fcf.fabric_name,
+					new_fcf_record) &&
+		    (new_fcf_record->fip_priority < phba->fcf.priority)) {
 			/* Use this FCF record */
 			lpfc_copy_fcf_record(phba, new_fcf_record);
 			phba->fcf.addr_mode = addr_mode;
@@ -1512,6 +1634,39 @@ out:
 }
 
 /**
+ * lpfc_init_vpi_cmpl - Completion handler for init_vpi mbox command.
+ * @phba: pointer to lpfc hba data structure.
+ * @mboxq: pointer to mailbox data structure.
+ *
+ * This function handles completion of init vpi mailbox command.
+ */
+static void
+lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
+{
+	struct lpfc_vport *vport = mboxq->vport;
+	if (mboxq->u.mb.mbxStatus) {
+		lpfc_printf_vlog(vport, KERN_ERR,
+				LOG_MBOX,
+				"2609 Init VPI mailbox failed 0x%x\n",
+				mboxq->u.mb.mbxStatus);
+		mempool_free(mboxq, phba->mbox_mem_pool);
+		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
+		return;
+	}
+	vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
+
+	if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
+		lpfc_initial_fdisc(vport);
+	else {
+		lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
+		lpfc_printf_vlog(vport, KERN_ERR,
+			LOG_ELS,
+			"2606 No NPIV Fabric support\n");
+	}
+	return;
+}
+
+/**
  * lpfc_start_fdiscs - send fdiscs for each vports on this port.
  * @phba: pointer to lpfc hba data structure.
  *
@@ -1523,6 +1678,8 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
 {
 	struct lpfc_vport **vports;
 	int i;
+	LPFC_MBOXQ_t *mboxq;
+	int rc;
 
 	vports = lpfc_create_vport_work_array(phba);
 	if (vports != NULL) {
@@ -1540,6 +1697,29 @@ lpfc_start_fdiscs(struct lpfc_hba *phba)
 						     FC_VPORT_LINKDOWN);
 				continue;
 			}
+			if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) {
+				mboxq = mempool_alloc(phba->mbox_mem_pool,
+					GFP_KERNEL);
+				if (!mboxq) {
+					lpfc_printf_vlog(vports[i], KERN_ERR,
+					LOG_MBOX, "2607 Failed to allocate "
+					"init_vpi mailbox\n");
+					continue;
+				}
+				lpfc_init_vpi(phba, mboxq, vports[i]->vpi);
+				mboxq->vport = vports[i];
+				mboxq->mbox_cmpl = lpfc_init_vpi_cmpl;
+				rc = lpfc_sli_issue_mbox(phba, mboxq,
+					MBX_NOWAIT);
+				if (rc == MBX_NOT_FINISHED) {
+					lpfc_printf_vlog(vports[i], KERN_ERR,
+					LOG_MBOX, "2608 Failed to issue "
+					"init_vpi mailbox\n");
+					mempool_free(mboxq,
+						phba->mbox_mem_pool);
+				}
+				continue;
+			}
 			if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
 				lpfc_initial_fdisc(vports[i]);
 			else {
@@ -1769,6 +1949,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
 			goto out;
 		}
 	} else {
+		vport->port_state = LPFC_VPORT_UNKNOWN;
 		/*
 		 * Add the driver's default FCF record at FCF index 0 now. This
 		 * is phase 1 implementation that support FCF index 0 and driver
@@ -1804,6 +1985,12 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
 		 * The driver is expected to do FIP/FCF. Call the port
 		 * and get the FCF Table.
 		 */
+		spin_lock_irq(&phba->hbalock);
+		if (phba->hba_flag & FCF_DISC_INPROGRESS) {
+			spin_unlock_irq(&phba->hbalock);
+			return;
+		}
+		spin_unlock_irq(&phba->hbalock);
 		rc = lpfc_sli4_read_fcf_record(phba,
 					LPFC_FCOE_FCF_GET_FIRST);
 		if (rc)
@@ -2113,13 +2300,15 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
 	LPFC_MBOXQ_t *pmb = NULL;
 	MAILBOX_t *mb;
 	struct static_vport_info *vport_info;
-	int rc, i;
+	int rc = 0, i;
 	struct fc_vport_identifiers vport_id;
 	struct fc_vport *new_fc_vport;
 	struct Scsi_Host *shost;
 	struct lpfc_vport *vport;
 	uint16_t offset = 0;
 	uint8_t *vport_buff;
+	struct lpfc_dmabuf *mp;
+	uint32_t byte_count = 0;
 
 	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!pmb) {
@@ -2142,7 +2331,9 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
 
 	vport_buff = (uint8_t *) vport_info;
 	do {
-		lpfc_dump_static_vport(phba, pmb, offset);
+		if (lpfc_dump_static_vport(phba, pmb, offset))
+			goto out;
+
 		pmb->vport = phba->pport;
 		rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO);
 
@@ -2155,17 +2346,30 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
 			goto out;
 		}
 
-		if (mb->un.varDmp.word_cnt >
-			sizeof(struct static_vport_info) - offset)
-			mb->un.varDmp.word_cnt =
-			sizeof(struct static_vport_info) - offset;
-
-		lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
-			vport_buff + offset,
-			mb->un.varDmp.word_cnt);
-		offset += mb->un.varDmp.word_cnt;
+		if (phba->sli_rev == LPFC_SLI_REV4) {
+			byte_count = pmb->u.mqe.un.mb_words[5];
+			mp = (struct lpfc_dmabuf *) pmb->context2;
+			if (byte_count > sizeof(struct static_vport_info) -
+					offset)
+				byte_count = sizeof(struct static_vport_info)
+					- offset;
+			memcpy(vport_buff + offset, mp->virt, byte_count);
+			offset += byte_count;
+		} else {
+			if (mb->un.varDmp.word_cnt >
+				sizeof(struct static_vport_info) - offset)
+				mb->un.varDmp.word_cnt =
+					sizeof(struct static_vport_info)
+						- offset;
+			byte_count = mb->un.varDmp.word_cnt;
+			lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
+				vport_buff + offset,
+				byte_count);
+
+			offset += byte_count;
+		}
 
-	} while (mb->un.varDmp.word_cnt &&
+	} while (byte_count &&
 		offset < sizeof(struct static_vport_info));
 
 
@@ -2198,7 +2402,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
 		if (!new_fc_vport) {
 			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
 				"0546 lpfc_create_static_vport failed to"
-				" create vport \n");
+				" create vport\n");
 			continue;
 		}
 
@@ -2207,16 +2411,15 @@ lpfc_create_static_vport(struct lpfc_hba *phba)
 	}
 
 out:
-	/*
-	 * If this is timed out command, setting NULL to context2 tell SLI
-	 * layer not to use this buffer.
-	 */
-	spin_lock_irq(&phba->hbalock);
-	pmb->context2 = NULL;
-	spin_unlock_irq(&phba->hbalock);
 	kfree(vport_info);
-	if (rc != MBX_TIMEOUT)
+	if (rc != MBX_TIMEOUT) {
+		if (pmb->context2) {
+			mp = (struct lpfc_dmabuf *) pmb->context2;
+			lpfc_mbuf_free(phba, mp->virt, mp->phys);
+			kfree(mp);
+		}
 		mempool_free(pmb, phba->mbox_mem_pool);
+	}
 
 	return;
 }
@@ -4360,7 +4563,7 @@ lpfc_read_fcoe_param(struct lpfc_hba *phba,
 	fcoe_param_hdr = (struct lpfc_fip_param_hdr *)
 		buff;
 	fcoe_param = (struct lpfc_fcoe_params *)
-		buff + sizeof(struct lpfc_fip_param_hdr);
+		(buff + sizeof(struct lpfc_fip_param_hdr));
 
 	if ((fcoe_param_hdr->parm_version != FIPP_VERSION) ||
 		(fcoe_param_hdr->length != FCOE_PARAM_LENGTH))
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 8a3a026..ccb2672 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -2496,8 +2496,8 @@ typedef struct {
 #define  DMP_VPORT_REGION_SIZE	 0x200
 #define  DMP_MBOX_OFFSET_WORD	 0x5
 
-#define  DMP_REGION_FCOEPARAM	 0x17   /* fcoe param region */
-#define  DMP_FCOEPARAM_RGN_SIZE	 0x400
+#define  DMP_REGION_23	 	 0x17   /* fcoe param  and port state region */
+#define  DMP_RGN23_SIZE	 	 0x400
 
 #define  WAKE_UP_PARMS_REGION_ID    4
 #define  WAKE_UP_PARMS_WORD_SIZE   15
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h
index 2995d12..3689eee 100644
--- a/drivers/scsi/lpfc/lpfc_hw4.h
+++ b/drivers/scsi/lpfc/lpfc_hw4.h
@@ -52,6 +52,31 @@ struct dma_address {
 	uint32_t addr_hi;
 };
 
+#define LPFC_SLIREV_CONF_WORD	0x58
+struct lpfc_sli_intf {
+	uint32_t word0;
+#define lpfc_sli_intf_iftype_MASK 	0x00000007
+#define lpfc_sli_intf_iftype_SHIFT	0
+#define lpfc_sli_intf_iftype_WORD	word0
+#define lpfc_sli_intf_rev_MASK 		0x0000000f
+#define lpfc_sli_intf_rev_SHIFT		4
+#define lpfc_sli_intf_rev_WORD		word0
+#define LPFC_SLIREV_CONF_SLI4	4
+#define lpfc_sli_intf_family_MASK 	0x000000ff
+#define lpfc_sli_intf_family_SHIFT	8
+#define lpfc_sli_intf_family_WORD	word0
+#define lpfc_sli_intf_feat1_MASK 	0x000000ff
+#define lpfc_sli_intf_feat1_SHIFT	16
+#define lpfc_sli_intf_feat1_WORD	word0
+#define lpfc_sli_intf_feat2_MASK 	0x0000001f
+#define lpfc_sli_intf_feat2_SHIFT	24
+#define lpfc_sli_intf_feat2_WORD	word0
+#define lpfc_sli_intf_valid_MASK 	0x00000007
+#define lpfc_sli_intf_valid_SHIFT	29
+#define lpfc_sli_intf_valid_WORD	word0
+#define LPFC_SLI_INTF_VALID		6
+};
+
 #define LPFC_SLI4_BAR0		1
 #define LPFC_SLI4_BAR1		2
 #define LPFC_SLI4_BAR2		4
@@ -1181,6 +1206,32 @@ struct fcf_record {
 #define lpfc_fcf_record_fcf_state_MASK		0x0000FFFF
 #define lpfc_fcf_record_fcf_state_WORD		word8
 	uint8_t vlan_bitmap[512];
+	uint32_t word137;
+#define lpfc_fcf_record_switch_name_0_SHIFT	0
+#define lpfc_fcf_record_switch_name_0_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_0_WORD	word137
+#define lpfc_fcf_record_switch_name_1_SHIFT	8
+#define lpfc_fcf_record_switch_name_1_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_1_WORD	word137
+#define lpfc_fcf_record_switch_name_2_SHIFT	16
+#define lpfc_fcf_record_switch_name_2_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_2_WORD	word137
+#define lpfc_fcf_record_switch_name_3_SHIFT	24
+#define lpfc_fcf_record_switch_name_3_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_3_WORD	word137
+	uint32_t word138;
+#define lpfc_fcf_record_switch_name_4_SHIFT	0
+#define lpfc_fcf_record_switch_name_4_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_4_WORD	word138
+#define lpfc_fcf_record_switch_name_5_SHIFT	8
+#define lpfc_fcf_record_switch_name_5_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_5_WORD	word138
+#define lpfc_fcf_record_switch_name_6_SHIFT	16
+#define lpfc_fcf_record_switch_name_6_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_6_WORD	word138
+#define lpfc_fcf_record_switch_name_7_SHIFT	24
+#define lpfc_fcf_record_switch_name_7_MASK	0x000000FF
+#define lpfc_fcf_record_switch_name_7_WORD	word138
 };
 
 struct lpfc_mbx_read_fcf_tbl {
@@ -1385,20 +1436,17 @@ struct lpfc_mbx_unreg_vfi {
 
 struct lpfc_mbx_resume_rpi {
 	uint32_t word1;
-#define lpfc_resume_rpi_rpi_SHIFT	0
-#define lpfc_resume_rpi_rpi_MASK	0x0000FFFF
-#define lpfc_resume_rpi_rpi_WORD	word1
+#define lpfc_resume_rpi_index_SHIFT	0
+#define lpfc_resume_rpi_index_MASK	0x0000FFFF
+#define lpfc_resume_rpi_index_WORD	word1
+#define lpfc_resume_rpi_ii_SHIFT	30
+#define lpfc_resume_rpi_ii_MASK		0x00000003
+#define lpfc_resume_rpi_ii_WORD		word1
+#define RESUME_INDEX_RPI		0
+#define RESUME_INDEX_VPI		1
+#define RESUME_INDEX_VFI		2
+#define RESUME_INDEX_FCFI		3
 	uint32_t event_tag;
-	uint32_t word3_rsvd;
-	uint32_t word4_rsvd;
-	uint32_t word5_rsvd;
-	uint32_t word6;
-#define lpfc_resume_rpi_vpi_SHIFT	0
-#define lpfc_resume_rpi_vpi_MASK	0x0000FFFF
-#define lpfc_resume_rpi_vpi_WORD	word6
-#define lpfc_resume_rpi_vfi_SHIFT	16
-#define lpfc_resume_rpi_vfi_MASK	0x0000FFFF
-#define lpfc_resume_rpi_vfi_WORD	word6
 };
 
 #define REG_FCF_INVALID_QID	0xFFFF
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index fc67cc6..562d8ce 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -211,7 +211,7 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
 		goto out_free_mbox;
 
 	do {
-		lpfc_dump_mem(phba, pmb, offset);
+		lpfc_dump_mem(phba, pmb, offset, DMP_REGION_VPD);
 		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
 
 		if (rc != MBX_SUCCESS) {
@@ -425,6 +425,9 @@ lpfc_config_port_post(struct lpfc_hba *phba)
 		return -EIO;
 	}
 
+	/* Check if the port is disabled */
+	lpfc_sli_read_link_ste(phba);
+
 	/* Reset the DFT_HBA_Q_DEPTH to the max xri  */
 	if (phba->cfg_hba_queue_depth > (mb->un.varRdConfig.max_xri+1))
 		phba->cfg_hba_queue_depth =
@@ -524,27 +527,46 @@ lpfc_config_port_post(struct lpfc_hba *phba)
 	/* Set up error attention (ERATT) polling timer */
 	mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL);
 
-	lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
-	pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
-	lpfc_set_loopback_flag(phba);
-	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
-	if (rc != MBX_SUCCESS) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+	if (phba->hba_flag & LINK_DISABLED) {
+		lpfc_printf_log(phba,
+			KERN_ERR, LOG_INIT,
+			"2598 Adapter Link is disabled.\n");
+		lpfc_down_link(phba, pmb);
+		pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+		if ((rc != MBX_SUCCESS) && (rc != MBX_BUSY)) {
+			lpfc_printf_log(phba,
+			KERN_ERR, LOG_INIT,
+			"2599 Adapter failed to issue DOWN_LINK"
+			" mbox command rc 0x%x\n", rc);
+
+			mempool_free(pmb, phba->mbox_mem_pool);
+			return -EIO;
+		}
+	} else {
+		lpfc_init_link(phba, pmb, phba->cfg_topology,
+			phba->cfg_link_speed);
+		pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
+		lpfc_set_loopback_flag(phba);
+		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
+		if (rc != MBX_SUCCESS) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"0454 Adapter failed to init, mbxCmd x%x "
 				"INIT_LINK, mbxStatus x%x\n",
 				mb->mbxCommand, mb->mbxStatus);
 
-		/* Clear all interrupt enable conditions */
-		writel(0, phba->HCregaddr);
-		readl(phba->HCregaddr); /* flush */
-		/* Clear all pending interrupts */
-		writel(0xffffffff, phba->HAregaddr);
-		readl(phba->HAregaddr); /* flush */
+			/* Clear all interrupt enable conditions */
+			writel(0, phba->HCregaddr);
+			readl(phba->HCregaddr); /* flush */
+			/* Clear all pending interrupts */
+			writel(0xffffffff, phba->HAregaddr);
+			readl(phba->HAregaddr); /* flush */
 
-		phba->link_state = LPFC_HBA_ERROR;
-		if (rc != MBX_BUSY)
-			mempool_free(pmb, phba->mbox_mem_pool);
-		return -EIO;
+			phba->link_state = LPFC_HBA_ERROR;
+			if (rc != MBX_BUSY)
+				mempool_free(pmb, phba->mbox_mem_pool);
+			return -EIO;
+		}
 	}
 	/* MBOX buffer will be freed in mbox compl */
 	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
@@ -558,7 +580,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
 				KERN_ERR,
 				LOG_INIT,
 				"0456 Adapter failed to issue "
-				"ASYNCEVT_ENABLE mbox status x%x \n.",
+				"ASYNCEVT_ENABLE mbox status x%x\n",
 				rc);
 		mempool_free(pmb, phba->mbox_mem_pool);
 	}
@@ -572,7 +594,7 @@ lpfc_config_port_post(struct lpfc_hba *phba)
 
 	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0435 Adapter failed "
-				"to get Option ROM version status x%x\n.", rc);
+				"to get Option ROM version status x%x\n", rc);
 		mempool_free(pmb, phba->mbox_mem_pool);
 	}
 
@@ -2133,6 +2155,8 @@ lpfc_online(struct lpfc_hba *phba)
 			vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
 			if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
 				vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+			if (phba->sli_rev == LPFC_SLI_REV4)
+				vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
 			spin_unlock_irq(shost->host_lock);
 		}
 		lpfc_destroy_vport_work_array(phba, vports);
@@ -2807,6 +2831,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
 	att_type = lpfc_sli4_parse_latt_type(phba, acqe_link);
 	if (att_type != AT_LINK_DOWN && att_type != AT_LINK_UP)
 		return;
+	phba->fcoe_eventtag = acqe_link->event_tag;
 	pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!pmb) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -2894,18 +2919,20 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
 	uint8_t event_type = bf_get(lpfc_acqe_fcoe_event_type, acqe_fcoe);
 	int rc;
 
+	phba->fcoe_eventtag = acqe_fcoe->event_tag;
 	switch (event_type) {
 	case LPFC_FCOE_EVENT_TYPE_NEW_FCF:
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
-			"2546 New FCF found index 0x%x tag 0x%x \n",
+			"2546 New FCF found index 0x%x tag 0x%x\n",
 			acqe_fcoe->fcf_index,
 			acqe_fcoe->event_tag);
 		/*
-		 * If the current FCF is in discovered state,
-		 * do nothing.
+		 * If the current FCF is in discovered state, or
+		 * FCF discovery is in progress do nothing.
 		 */
 		spin_lock_irq(&phba->hbalock);
-		if (phba->fcf.fcf_flag & FCF_DISCOVERED) {
+		if ((phba->fcf.fcf_flag & FCF_DISCOVERED) ||
+		   (phba->hba_flag & FCF_DISC_INPROGRESS)) {
 			spin_unlock_irq(&phba->hbalock);
 			break;
 		}
@@ -2922,7 +2949,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
 
 	case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
 		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-			"2548 FCF Table full count 0x%x tag 0x%x \n",
+			"2548 FCF Table full count 0x%x tag 0x%x\n",
 			bf_get(lpfc_acqe_fcoe_fcf_count, acqe_fcoe),
 			acqe_fcoe->event_tag);
 		break;
@@ -2930,7 +2957,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
 	case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
 		lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
 			"2549 FCF disconnected fron network index 0x%x"
-			" tag 0x%x \n", acqe_fcoe->fcf_index,
+			" tag 0x%x\n", acqe_fcoe->fcf_index,
 			acqe_fcoe->event_tag);
 		/* If the event is not for currently used fcf do nothing */
 		if (phba->fcf.fcf_indx != acqe_fcoe->fcf_index)
@@ -4130,8 +4157,7 @@ lpfc_hba_alloc(struct pci_dev *pdev)
 	/* Allocate memory for HBA structure */
 	phba = kzalloc(sizeof(struct lpfc_hba), GFP_KERNEL);
 	if (!phba) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"1417 Failed to allocate hba struct.\n");
+		dev_err(&pdev->dev, "failed to allocate hba struct\n");
 		return NULL;
 	}
 
@@ -4145,6 +4171,9 @@ lpfc_hba_alloc(struct pci_dev *pdev)
 		return NULL;
 	}
 
+	mutex_init(&phba->ct_event_mutex);
+	INIT_LIST_HEAD(&phba->ct_ev_waiters);
+
 	return phba;
 }
 
@@ -4489,23 +4518,6 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
 	if (!phba->sli4_hba.STAregaddr)
 		return -ENODEV;
 
-	/* With uncoverable error, log the error message and return error */
-	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
-	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
-	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
-		uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
-		uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
-		if (uerrlo_reg.word0 || uerrhi_reg.word0) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-					"1422 HBA Unrecoverable error: "
-					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
-					"online0_reg=0x%x, online1_reg=0x%x\n",
-					uerrlo_reg.word0, uerrhi_reg.word0,
-					onlnreg0, onlnreg1);
-		}
-		return -ENODEV;
-	}
-
 	/* Wait up to 30 seconds for the SLI Port POST done and ready */
 	for (i = 0; i < 3000; i++) {
 		sta_reg.word0 = readl(phba->sli4_hba.STAregaddr);
@@ -4545,6 +4557,23 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba)
 			bf_get(lpfc_scratchpad_featurelevel1, &scratchpad),
 			bf_get(lpfc_scratchpad_featurelevel2, &scratchpad));
 
+	/* With uncoverable error, log the error message and return error */
+	onlnreg0 = readl(phba->sli4_hba.ONLINE0regaddr);
+	onlnreg1 = readl(phba->sli4_hba.ONLINE1regaddr);
+	if ((onlnreg0 != LPFC_ONLINE_NERR) || (onlnreg1 != LPFC_ONLINE_NERR)) {
+		uerrlo_reg.word0 = readl(phba->sli4_hba.UERRLOregaddr);
+		uerrhi_reg.word0 = readl(phba->sli4_hba.UERRHIregaddr);
+		if (uerrlo_reg.word0 || uerrhi_reg.word0) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"1422 HBA Unrecoverable error: "
+					"uerr_lo_reg=0x%x, uerr_hi_reg=0x%x, "
+					"online0_reg=0x%x, online1_reg=0x%x\n",
+					uerrlo_reg.word0, uerrhi_reg.word0,
+					onlnreg0, onlnreg1);
+		}
+		return -ENODEV;
+	}
+
 	return port_error;
 }
 
@@ -7347,6 +7376,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid)
 	/* Perform post initialization setup */
 	lpfc_post_init_setup(phba);
 
+	/* Check if there are static vports to be created. */
+	lpfc_create_static_vport(phba);
+
 	return 0;
 
 out_disable_intr:
@@ -7636,19 +7668,17 @@ static int __devinit
 lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 {
 	int rc;
-	uint16_t dev_id;
+	struct lpfc_sli_intf intf;
 
-	if (pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id))
+	if (pci_read_config_dword(pdev, LPFC_SLIREV_CONF_WORD, &intf.word0))
 		return -ENODEV;
 
-	switch (dev_id) {
-	case PCI_DEVICE_ID_TIGERSHARK:
+	if ((bf_get(lpfc_sli_intf_valid, &intf) == LPFC_SLI_INTF_VALID) &&
+		(bf_get(lpfc_sli_intf_rev, &intf) == LPFC_SLIREV_CONF_SLI4))
 		rc = lpfc_pci_probe_one_s4(pdev, pid);
-		break;
-	default:
+	else
 		rc = lpfc_pci_probe_one_s3(pdev, pid);
-		break;
-	}
+
 	return rc;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 3423571..1ab4059 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -52,48 +52,85 @@
  * This routine prepares the mailbox command for dumping list of static
  * vports to be created.
  **/
-void
+int
 lpfc_dump_static_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
 		uint16_t offset)
 {
 	MAILBOX_t *mb;
-	void *ctx;
+	struct lpfc_dmabuf *mp;
 
 	mb = &pmb->u.mb;
-	ctx = pmb->context2;
 
 	/* Setup to dump vport info region */
 	memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
 	mb->mbxCommand = MBX_DUMP_MEMORY;
-	mb->un.varDmp.cv = 1;
 	mb->un.varDmp.type = DMP_NV_PARAMS;
 	mb->un.varDmp.entry_index = offset;
 	mb->un.varDmp.region_id = DMP_REGION_VPORT;
-	mb->un.varDmp.word_cnt = DMP_RSP_SIZE/sizeof(uint32_t);
-	mb->un.varDmp.co = 0;
-	mb->un.varDmp.resp_offset = 0;
-	pmb->context2 = ctx;
 	mb->mbxOwner = OWN_HOST;
 
-	return;
+	/* For SLI3 HBAs data is embedded in mailbox */
+	if (phba->sli_rev != LPFC_SLI_REV4) {
+		mb->un.varDmp.cv = 1;
+		mb->un.varDmp.word_cnt = DMP_RSP_SIZE/sizeof(uint32_t);
+		return 0;
+	}
+
+	/* For SLI4 HBAs driver need to allocate memory */
+	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (mp)
+		mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
+
+	if (!mp || !mp->virt) {
+		kfree(mp);
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+			"2605 lpfc_dump_static_vport: memory"
+			" allocation failed\n");
+		return 1;
+	}
+	memset(mp->virt, 0, LPFC_BPL_SIZE);
+	INIT_LIST_HEAD(&mp->list);
+	/* save address for completion */
+	pmb->context2 = (uint8_t *) mp;
+	mb->un.varWords[3] = putPaddrLow(mp->phys);
+	mb->un.varWords[4] = putPaddrHigh(mp->phys);
+	mb->un.varDmp.sli4_length = sizeof(struct static_vport_info);
+
+	return 0;
+}
+
+/**
+ * lpfc_down_link - Bring down HBAs link.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine prepares a mailbox command to bring down HBA link.
+ **/
+void
+lpfc_down_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+{
+	MAILBOX_t *mb;
+	memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
+	mb = &pmb->u.mb;
+	mb->mbxCommand = MBX_DOWN_LINK;
+	mb->mbxOwner = OWN_HOST;
 }
 
 /**
- * lpfc_dump_mem - Prepare a mailbox command for retrieving HBA's VPD memory
+ * lpfc_dump_mem - Prepare a mailbox command for reading a region.
  * @phba: pointer to lpfc hba data structure.
  * @pmb: pointer to the driver internal queue element for mailbox command.
- * @offset: offset for dumping VPD memory mailbox command.
+ * @offset: offset into the region.
+ * @region_id: config region id.
  *
  * The dump mailbox command provides a method for the device driver to obtain
  * various types of information from the HBA device.
  *
- * This routine prepares the mailbox command for dumping HBA Vital Product
- * Data (VPD) memory. This mailbox command is to be used for retrieving a
- * portion (DMP_RSP_SIZE bytes) of a HBA's VPD from the HBA at an address
- * offset specified by the offset parameter.
+ * This routine prepares the mailbox command for dumping HBA's config region.
  **/
 void
-lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
+lpfc_dump_mem(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, uint16_t offset,
+		uint16_t region_id)
 {
 	MAILBOX_t *mb;
 	void *ctx;
@@ -107,7 +144,7 @@ lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
 	mb->un.varDmp.cv = 1;
 	mb->un.varDmp.type = DMP_NV_PARAMS;
 	mb->un.varDmp.entry_index = offset;
-	mb->un.varDmp.region_id = DMP_REGION_VPD;
+	mb->un.varDmp.region_id = region_id;
 	mb->un.varDmp.word_cnt = (DMP_RSP_SIZE / sizeof (uint32_t));
 	mb->un.varDmp.co = 0;
 	mb->un.varDmp.resp_offset = 0;
@@ -1789,6 +1826,7 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
 
 /**
  * lpfc_init_vpi - Initialize the INIT_VPI mailbox command
+ * @phba: pointer to the hba structure to init the VPI for.
  * @mbox: pointer to lpfc mbox command to initialize.
  * @vpi: VPI to be initialized.
  *
@@ -1799,11 +1837,14 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
  * successful virtual NPort login.
  **/
 void
-lpfc_init_vpi(struct lpfcMboxq *mbox, uint16_t vpi)
+lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi)
 {
 	memset(mbox, 0, sizeof(*mbox));
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI);
-	bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi, vpi);
+	bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi,
+	       vpi + phba->vpi_base);
+	bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi,
+	       phba->pport->vfi + phba->vfi_base);
 }
 
 /**
@@ -1852,7 +1893,7 @@ lpfc_dump_fcoe_param(struct lpfc_hba *phba,
 		/* dump_fcoe_param failed to allocate memory */
 		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
 			"2569 lpfc_dump_fcoe_param: memory"
-			" allocation failed \n");
+			" allocation failed\n");
 		return 1;
 	}
 
@@ -1864,8 +1905,8 @@ lpfc_dump_fcoe_param(struct lpfc_hba *phba,
 
 	mb->mbxCommand = MBX_DUMP_MEMORY;
 	mb->un.varDmp.type = DMP_NV_PARAMS;
-	mb->un.varDmp.region_id = DMP_REGION_FCOEPARAM;
-	mb->un.varDmp.sli4_length = DMP_FCOEPARAM_RGN_SIZE;
+	mb->un.varDmp.region_id = DMP_REGION_23;
+	mb->un.varDmp.sli4_length = DMP_RGN23_SIZE;
 	mb->un.varWords[3] = putPaddrLow(mp->phys);
 	mb->un.varWords[4] = putPaddrHigh(mp->phys);
 	return 0;
@@ -1938,9 +1979,7 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
 	memset(mbox, 0, sizeof(*mbox));
 	resume_rpi = &mbox->u.mqe.un.resume_rpi;
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
-	bf_set(lpfc_resume_rpi_rpi, resume_rpi, ndlp->nlp_rpi);
-	bf_set(lpfc_resume_rpi_vpi, resume_rpi,
-	       ndlp->vport->vpi + ndlp->vport->phba->vpi_base);
-	bf_set(lpfc_resume_rpi_vfi, resume_rpi,
-	       ndlp->vport->vfi + ndlp->vport->phba->vfi_base);
+	bf_set(lpfc_resume_rpi_index, resume_rpi, ndlp->nlp_rpi);
+	bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
+	resume_rpi->event_tag = ndlp->phba->fc_eventTag;
 }
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index e198c91..a1b6db6 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -110,17 +110,28 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
 						sizeof(struct lpfc_nodelist));
 	if (!phba->nlp_mem_pool)
 		goto fail_free_mbox_pool;
-	phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool",
+
+	if (phba->sli_rev == LPFC_SLI_REV4) {
+		phba->lpfc_hrb_pool = pci_pool_create("lpfc_hrb_pool",
 					      phba->pcidev,
 					      LPFC_HDR_BUF_SIZE, align, 0);
-	if (!phba->lpfc_hrb_pool)
-		goto fail_free_nlp_mem_pool;
-	phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool",
+		if (!phba->lpfc_hrb_pool)
+			goto fail_free_nlp_mem_pool;
+
+		phba->lpfc_drb_pool = pci_pool_create("lpfc_drb_pool",
 					      phba->pcidev,
 					      LPFC_DATA_BUF_SIZE, align, 0);
-	if (!phba->lpfc_drb_pool)
-		goto fail_free_hbq_pool;
-
+		if (!phba->lpfc_drb_pool)
+			goto fail_free_hrb_pool;
+		phba->lpfc_hbq_pool = NULL;
+	} else {
+		phba->lpfc_hbq_pool = pci_pool_create("lpfc_hbq_pool",
+			phba->pcidev, LPFC_BPL_SIZE, align, 0);
+		if (!phba->lpfc_hbq_pool)
+			goto fail_free_nlp_mem_pool;
+		phba->lpfc_hrb_pool = NULL;
+		phba->lpfc_drb_pool = NULL;
+	}
 	/* vpi zero is reserved for the physical port so add 1 to max */
 	longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG;
 	phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL);
@@ -132,7 +143,7 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align)
  fail_free_dbq_pool:
 	pci_pool_destroy(phba->lpfc_drb_pool);
 	phba->lpfc_drb_pool = NULL;
- fail_free_hbq_pool:
+ fail_free_hrb_pool:
 	pci_pool_destroy(phba->lpfc_hrb_pool);
 	phba->lpfc_hrb_pool = NULL;
  fail_free_nlp_mem_pool:
@@ -176,11 +187,17 @@ lpfc_mem_free(struct lpfc_hba *phba)
 
 	/* Free HBQ pools */
 	lpfc_sli_hbqbuf_free_all(phba);
-	pci_pool_destroy(phba->lpfc_drb_pool);
+	if (phba->lpfc_drb_pool)
+		pci_pool_destroy(phba->lpfc_drb_pool);
 	phba->lpfc_drb_pool = NULL;
-	pci_pool_destroy(phba->lpfc_hrb_pool);
+	if (phba->lpfc_hrb_pool)
+		pci_pool_destroy(phba->lpfc_hrb_pool);
 	phba->lpfc_hrb_pool = NULL;
 
+	if (phba->lpfc_hbq_pool)
+		pci_pool_destroy(phba->lpfc_hbq_pool);
+	phba->lpfc_hbq_pool = NULL;
+
 	/* Free NLP memory pool */
 	mempool_destroy(phba->nlp_mem_pool);
 	phba->nlp_mem_pool = NULL;
@@ -380,7 +397,7 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba)
 	if (!hbqbp)
 		return NULL;
 
-	hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hrb_pool, GFP_KERNEL,
+	hbqbp->dbuf.virt = pci_pool_alloc(phba->lpfc_hbq_pool, GFP_KERNEL,
 					  &hbqbp->dbuf.phys);
 	if (!hbqbp->dbuf.virt) {
 		kfree(hbqbp);
@@ -405,7 +422,7 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba)
 void
 lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp)
 {
-	pci_pool_free(phba->lpfc_hrb_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys);
+	pci_pool_free(phba->lpfc_hbq_pool, hbqbp->dbuf.virt, hbqbp->dbuf.phys);
 	kfree(hbqbp);
 	return;
 }
diff --git a/drivers/scsi/lpfc/lpfc_nl.h b/drivers/scsi/lpfc/lpfc_nl.h
index 27d1a88..d655ed3 100644
--- a/drivers/scsi/lpfc/lpfc_nl.h
+++ b/drivers/scsi/lpfc/lpfc_nl.h
@@ -177,3 +177,23 @@ struct temp_event {
 	uint32_t data;
 };
 
+/* bsg definitions */
+#define LPFC_BSG_VENDOR_SET_CT_EVENT	1
+#define LPFC_BSG_VENDOR_GET_CT_EVENT	2
+
+struct set_ct_event {
+	uint32_t command;
+	uint32_t ev_req_id;
+	uint32_t ev_reg_id;
+};
+
+struct get_ct_event {
+	uint32_t command;
+	uint32_t ev_reg_id;
+	uint32_t ev_req_id;
+};
+
+struct get_ct_event_reply {
+	uint32_t immed_data;
+	uint32_t type;
+};
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index da59c4f..61d0897 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2142,7 +2142,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
 	} else if (resp_info & RESID_OVER) {
 		lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
 				 "9028 FCP command x%x residual overrun error. "
-				 "Data: x%x x%x \n", cmnd->cmnd[0],
+				 "Data: x%x x%x\n", cmnd->cmnd[0],
 				 scsi_bufflen(cmnd), scsi_get_resid(cmnd));
 		host_status = DID_ERROR;
 
@@ -2843,7 +2843,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 				dif_op_str[scsi_get_prot_op(cmnd)]);
 		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 				"9034 BLKGRD: CDB: %02x %02x %02x %02x %02x "
-				"%02x %02x %02x %02x %02x \n",
+				"%02x %02x %02x %02x %02x\n",
 				cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2],
 				cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5],
 				cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8],
@@ -2871,7 +2871,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 				dif_op_str[scsi_get_prot_op(cmnd)]);
 		lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG,
 				 "9039 BLKGRD: CDB: %02x %02x %02x %02x %02x "
-				 "%02x %02x %02x %02x %02x \n",
+				 "%02x %02x %02x %02x %02x\n",
 				 cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2],
 				 cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5],
 				 cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8],
@@ -3584,6 +3584,7 @@ struct scsi_host_template lpfc_template = {
 	.use_clustering		= ENABLE_CLUSTERING,
 	.shost_attrs		= lpfc_hba_attrs,
 	.max_sectors		= 0xFFFF,
+	.vendor_id		= LPFC_NL_VENDOR_ID,
 };
 
 struct scsi_host_template lpfc_vport_template = {
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index acc43b0..43cbe33 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -4139,7 +4139,7 @@ lpfc_sli4_read_fcoe_params(struct lpfc_hba *phba,
 		return -EIO;
 	}
 	data_length = mqe->un.mb_words[5];
-	if (data_length > DMP_FCOEPARAM_RGN_SIZE) {
+	if (data_length > DMP_RGN23_SIZE) {
 		lpfc_mbuf_free(phba, mp->virt, mp->phys);
 		kfree(mp);
 		return -EIO;
@@ -4304,7 +4304,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
 	 */
 	if (lpfc_sli4_read_fcoe_params(phba, mboxq))
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT,
-			"2570 Failed to read FCoE parameters \n");
+			"2570 Failed to read FCoE parameters\n");
 
 	/* Issue READ_REV to collect vpd and FW information. */
 	vpd_size = PAGE_SIZE;
@@ -4522,12 +4522,8 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
 	lpfc_sli4_rb_setup(phba);
 
 	/* Start the ELS watchdog timer */
-	/*
-	 * The driver for SLI4 is not yet ready to process timeouts
-	 * or interrupts.  Once it is, the comment bars can be removed.
-	 */
-	/* mod_timer(&vport->els_tmofunc,
-	 *           jiffies + HZ * (phba->fc_ratov*2)); */
+	mod_timer(&vport->els_tmofunc,
+		  jiffies + HZ * (phba->fc_ratov * 2));
 
 	/* Start heart beat timer */
 	mod_timer(&phba->hb_tmofunc,
@@ -4706,13 +4702,13 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox,
 
 	spin_lock_irqsave(&phba->hbalock, drvr_flag);
 	if (!pmbox) {
+		phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 		/* processing mbox queue from intr_handler */
 		if (unlikely(psli->sli_flag & LPFC_SLI_ASYNC_MBX_BLK)) {
 			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			return MBX_SUCCESS;
 		}
 		processing_queue = 1;
-		phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 		pmbox = lpfc_mbox_get(phba);
 		if (!pmbox) {
 			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
@@ -5279,6 +5275,18 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
 	unsigned long iflags;
 	int rc;
 
+	rc = lpfc_mbox_dev_check(phba);
+	if (unlikely(rc)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
+				"(%d):2544 Mailbox command x%x (x%x) "
+				"cannot issue Data: x%x x%x\n",
+				mboxq->vport ? mboxq->vport->vpi : 0,
+				mboxq->u.mb.mbxCommand,
+				lpfc_sli4_mbox_opcode_get(phba, mboxq),
+				psli->sli_flag, flag);
+		goto out_not_finished;
+	}
+
 	/* Detect polling mode and jump to a handler */
 	if (!phba->sli4_hba.intr_enable) {
 		if (flag == MBX_POLL)
@@ -5338,17 +5346,6 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq,
 				psli->sli_flag, flag);
 		goto out_not_finished;
 	}
-	rc = lpfc_mbox_dev_check(phba);
-	if (unlikely(rc)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
-				"(%d):2544 Mailbox command x%x (x%x) "
-				"cannot issue Data: x%x x%x\n",
-				mboxq->vport ? mboxq->vport->vpi : 0,
-				mboxq->u.mb.mbxCommand,
-				lpfc_sli4_mbox_opcode_get(phba, mboxq),
-				psli->sli_flag, flag);
-		goto out_not_finished;
-	}
 
 	/* Put the mailbox command to the driver internal FIFO */
 	psli->slistat.mbox_busy++;
@@ -5817,19 +5814,21 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
 /**
  * lpfc_sli4_scmd_to_wqidx_distr - scsi command to SLI4 WQ index distribution
  * @phba: Pointer to HBA context object.
- * @piocb: Pointer to command iocb.
  *
  * This routine performs a round robin SCSI command to SLI4 FCP WQ index
- * distribution.
+ * distribution.  This is called by __lpfc_sli_issue_iocb_s4() with the hbalock
+ * held.
  *
  * Return: index into SLI4 fast-path FCP queue index.
  **/
 static uint32_t
-lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba, struct lpfc_iocbq *piocb)
+lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba)
 {
-	static uint32_t fcp_qidx;
+	++phba->fcp_qidx;
+	if (phba->fcp_qidx >= phba->cfg_fcp_wq_count)
+		phba->fcp_qidx = 0;
 
-	return fcp_qidx++ % phba->cfg_fcp_wq_count;
+	return phba->fcp_qidx;
 }
 
 /**
@@ -6156,7 +6155,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
 		return IOCB_ERROR;
 
 	if (piocb->iocb_flag &  LPFC_IO_FCP) {
-		fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba, piocb);
+		fcp_wqidx = lpfc_sli4_scmd_to_wqidx_distr(phba);
 		if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[fcp_wqidx], &wqe))
 			return IOCB_ERROR;
 	} else {
@@ -6327,7 +6326,7 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
 			KERN_ERR,
 			LOG_SLI,
 			"0346 Ring %d handler: unexpected ASYNC_STATUS"
-			" evt_code 0x%x \n"
+			" evt_code 0x%x\n"
 			"W0  0x%08x W1  0x%08x W2  0x%08x W3  0x%08x\n"
 			"W4  0x%08x W5  0x%08x W6  0x%08x W7  0x%08x\n"
 			"W8  0x%08x W9  0x%08x W10 0x%08x W11 0x%08x\n"
@@ -6790,6 +6789,33 @@ lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt)
 
 
 /**
+ * lpfc_sli_bemem_bcopy - SLI memory copy function
+ * @srcp: Source memory pointer.
+ * @destp: Destination memory pointer.
+ * @cnt: Number of words required to be copied.
+ *
+ * This function is used for copying data between a data structure
+ * with big endian representation to local endianness.
+ * This function can be called with or without lock.
+ **/
+void
+lpfc_sli_bemem_bcopy(void *srcp, void *destp, uint32_t cnt)
+{
+	uint32_t *src = srcp;
+	uint32_t *dest = destp;
+	uint32_t ldata;
+	int i;
+
+	for (i = 0; i < (int)cnt; i += sizeof(uint32_t)) {
+		ldata = *src;
+		ldata = be32_to_cpu(ldata);
+		*dest = ldata;
+		src++;
+		dest++;
+	}
+}
+
+/**
  * lpfc_sli_ringpostbuf_put - Function to add a buffer to postbufq
  * @phba: Pointer to HBA context object.
  * @pring: Pointer to driver SLI ring object.
@@ -7678,12 +7704,6 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba)
 					"online0_reg=0x%x, online1_reg=0x%x\n",
 					uerr_sta_lo, uerr_sta_hi,
 					onlnreg0, onlnreg1);
-			/* TEMP: as the driver error recover logic is not
-			 * fully developed, we just log the error message
-			 * and the device error attention action is now
-			 * temporarily disabled.
-			 */
-			return 0;
 			phba->work_status[0] = uerr_sta_lo;
 			phba->work_status[1] = uerr_sta_hi;
 			/* Set the driver HA work bitmap */
@@ -9499,8 +9519,7 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint16_t imax)
 	eq->host_index = 0;
 	eq->hba_index = 0;
 
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, phba->mbox_mem_pool);
+	mempool_free(mbox, phba->mbox_mem_pool);
 	return status;
 }
 
@@ -9604,10 +9623,9 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq,
 	cq->queue_id = bf_get(lpfc_mbx_cq_create_q_id, &cq_create->u.response);
 	cq->host_index = 0;
 	cq->hba_index = 0;
-out:
 
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, phba->mbox_mem_pool);
+out:
+	mempool_free(mbox, phba->mbox_mem_pool);
 	return status;
 }
 
@@ -9712,8 +9730,7 @@ lpfc_mq_create(struct lpfc_hba *phba, struct lpfc_queue *mq,
 	/* link the mq onto the parent cq child list */
 	list_add_tail(&mq->list, &cq->child_list);
 out:
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, phba->mbox_mem_pool);
+	mempool_free(mbox, phba->mbox_mem_pool);
 	return status;
 }
 
@@ -9795,8 +9812,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq,
 	/* link the wq onto the parent cq child list */
 	list_add_tail(&wq->list, &cq->child_list);
 out:
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, phba->mbox_mem_pool);
+	mempool_free(mbox, phba->mbox_mem_pool);
 	return status;
 }
 
@@ -9970,8 +9986,7 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq,
 	list_add_tail(&drq->list, &cq->child_list);
 
 out:
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, phba->mbox_mem_pool);
+	mempool_free(mbox, phba->mbox_mem_pool);
 	return status;
 }
 
@@ -10026,8 +10041,7 @@ lpfc_eq_destroy(struct lpfc_hba *phba, struct lpfc_queue *eq)
 
 	/* Remove eq from any list */
 	list_del_init(&eq->list);
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, eq->phba->mbox_mem_pool);
+	mempool_free(mbox, eq->phba->mbox_mem_pool);
 	return status;
 }
 
@@ -10080,8 +10094,7 @@ lpfc_cq_destroy(struct lpfc_hba *phba, struct lpfc_queue *cq)
 	}
 	/* Remove cq from any list */
 	list_del_init(&cq->list);
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, cq->phba->mbox_mem_pool);
+	mempool_free(mbox, cq->phba->mbox_mem_pool);
 	return status;
 }
 
@@ -10134,8 +10147,7 @@ lpfc_mq_destroy(struct lpfc_hba *phba, struct lpfc_queue *mq)
 	}
 	/* Remove mq from any list */
 	list_del_init(&mq->list);
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, mq->phba->mbox_mem_pool);
+	mempool_free(mbox, mq->phba->mbox_mem_pool);
 	return status;
 }
 
@@ -10187,8 +10199,7 @@ lpfc_wq_destroy(struct lpfc_hba *phba, struct lpfc_queue *wq)
 	}
 	/* Remove wq from any list */
 	list_del_init(&wq->list);
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, wq->phba->mbox_mem_pool);
+	mempool_free(mbox, wq->phba->mbox_mem_pool);
 	return status;
 }
 
@@ -10258,8 +10269,7 @@ lpfc_rq_destroy(struct lpfc_hba *phba, struct lpfc_queue *hrq,
 	}
 	list_del_init(&hrq->list);
 	list_del_init(&drq->list);
-	if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, hrq->phba->mbox_mem_pool);
+	mempool_free(mbox, hrq->phba->mbox_mem_pool);
 	return status;
 }
 
@@ -10933,6 +10943,7 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
 	first_iocbq = lpfc_sli_get_iocbq(vport->phba);
 	if (first_iocbq) {
 		/* Initialize the first IOCB. */
+		first_iocbq->iocb.unsli3.rcvsli3.acc_len = 0;
 		first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
 		first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
 		first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id);
@@ -10945,6 +10956,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
 		first_iocbq->iocb.un.cont64[0].tus.f.bdeSize =
 							LPFC_DATA_BUF_SIZE;
 		first_iocbq->iocb.un.rcvels.remoteID = sid;
+		first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
+				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
 	}
 	iocbq = first_iocbq;
 	/*
@@ -10961,6 +10974,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
 			iocbq->iocb.ulpBdeCount++;
 			iocbq->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize =
 							LPFC_DATA_BUF_SIZE;
+			first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
+				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
 		} else {
 			iocbq = lpfc_sli_get_iocbq(vport->phba);
 			if (!iocbq) {
@@ -10978,6 +10993,8 @@ lpfc_prep_seq(struct lpfc_vport *vport, struct hbq_dmabuf *seq_dmabuf)
 			iocbq->iocb.ulpBdeCount = 1;
 			iocbq->iocb.un.cont64[0].tus.f.bdeSize =
 							LPFC_DATA_BUF_SIZE;
+			first_iocbq->iocb.unsli3.rcvsli3.acc_len +=
+				bf_get(lpfc_rcqe_length, &seq_dmabuf->rcqe);
 			iocbq->iocb.un.rcvels.remoteID = sid;
 			list_add_tail(&iocbq->list, &first_iocbq->list);
 		}
@@ -11324,7 +11341,7 @@ lpfc_sli4_init_vpi(struct lpfc_hba *phba, uint16_t vpi)
 	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mboxq)
 		return -ENOMEM;
-	lpfc_init_vpi(mboxq, vpi);
+	lpfc_init_vpi(phba, mboxq, vpi);
 	mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI);
 	rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo);
 	if (rc != MBX_TIMEOUT)
@@ -11519,6 +11536,7 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
 	uint32_t alloc_len, req_len;
 	struct lpfc_mbx_read_fcf_tbl *read_fcf;
 
+	phba->fcoe_eventtag_at_fcf_scan = phba->fcoe_eventtag;
 	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mboxq) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -11570,7 +11588,140 @@ lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index)
 	if (rc == MBX_NOT_FINISHED) {
 		lpfc_sli4_mbox_cmd_free(phba, mboxq);
 		error = -EIO;
-	} else
+	} else {
+		spin_lock_irq(&phba->hbalock);
+		phba->hba_flag |= FCF_DISC_INPROGRESS;
+		spin_unlock_irq(&phba->hbalock);
 		error = 0;
+	}
 	return error;
 }
+
+/**
+ * lpfc_sli_read_link_ste - Read region 23 to decide if link is disabled.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This function read region 23 and parse TLV for port status to
+ * decide if the user disaled the port. If the TLV indicates the
+ * port is disabled, the hba_flag is set accordingly.
+ **/
+void
+lpfc_sli_read_link_ste(struct lpfc_hba *phba)
+{
+	LPFC_MBOXQ_t *pmb = NULL;
+	MAILBOX_t *mb;
+	uint8_t *rgn23_data = NULL;
+	uint32_t offset = 0, data_size, sub_tlv_len, tlv_offset;
+	int rc;
+
+	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmb) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2600 lpfc_sli_read_serdes_param failed to"
+			" allocate mailbox memory\n");
+		goto out;
+	}
+	mb = &pmb->u.mb;
+
+	/* Get adapter Region 23 data */
+	rgn23_data = kzalloc(DMP_RGN23_SIZE, GFP_KERNEL);
+	if (!rgn23_data)
+		goto out;
+
+	do {
+		lpfc_dump_mem(phba, pmb, offset, DMP_REGION_23);
+		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
+
+		if (rc != MBX_SUCCESS) {
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+				"2601 lpfc_sli_read_link_ste failed to"
+				" read config region 23 rc 0x%x Status 0x%x\n",
+				rc, mb->mbxStatus);
+			mb->un.varDmp.word_cnt = 0;
+		}
+		/*
+		 * dump mem may return a zero when finished or we got a
+		 * mailbox error, either way we are done.
+		 */
+		if (mb->un.varDmp.word_cnt == 0)
+			break;
+		if (mb->un.varDmp.word_cnt > DMP_RGN23_SIZE - offset)
+			mb->un.varDmp.word_cnt = DMP_RGN23_SIZE - offset;
+
+		lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
+			rgn23_data + offset,
+			mb->un.varDmp.word_cnt);
+		offset += mb->un.varDmp.word_cnt;
+	} while (mb->un.varDmp.word_cnt && offset < DMP_RGN23_SIZE);
+
+	data_size = offset;
+	offset = 0;
+
+	if (!data_size)
+		goto out;
+
+	/* Check the region signature first */
+	if (memcmp(&rgn23_data[offset], LPFC_REGION23_SIGNATURE, 4)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2619 Config region 23 has bad signature\n");
+			goto out;
+	}
+	offset += 4;
+
+	/* Check the data structure version */
+	if (rgn23_data[offset] != LPFC_REGION23_VERSION) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"2620 Config region 23 has bad version\n");
+		goto out;
+	}
+	offset += 4;
+
+	/* Parse TLV entries in the region */
+	while (offset < data_size) {
+		if (rgn23_data[offset] == LPFC_REGION23_LAST_REC)
+			break;
+		/*
+		 * If the TLV is not driver specific TLV or driver id is
+		 * not linux driver id, skip the record.
+		 */
+		if ((rgn23_data[offset] != DRIVER_SPECIFIC_TYPE) ||
+		    (rgn23_data[offset + 2] != LINUX_DRIVER_ID) ||
+		    (rgn23_data[offset + 3] != 0)) {
+			offset += rgn23_data[offset + 1] * 4 + 4;
+			continue;
+		}
+
+		/* Driver found a driver specific TLV in the config region */
+		sub_tlv_len = rgn23_data[offset + 1] * 4;
+		offset += 4;
+		tlv_offset = 0;
+
+		/*
+		 * Search for configured port state sub-TLV.
+		 */
+		while ((offset < data_size) &&
+			(tlv_offset < sub_tlv_len)) {
+			if (rgn23_data[offset] == LPFC_REGION23_LAST_REC) {
+				offset += 4;
+				tlv_offset += 4;
+				break;
+			}
+			if (rgn23_data[offset] != PORT_STE_TYPE) {
+				offset += rgn23_data[offset + 1] * 4 + 4;
+				tlv_offset += rgn23_data[offset + 1] * 4 + 4;
+				continue;
+			}
+
+			/* This HBA contains PORT_STE configured */
+			if (!rgn23_data[offset + 2])
+				phba->hba_flag |= LINK_DISABLED;
+
+			goto out;
+		}
+	}
+out:
+	if (pmb)
+		mempool_free(pmb, phba->mbox_mem_pool);
+	kfree(rgn23_data);
+	return;
+}
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h
index 3b276b4..b5f4ba1 100644
--- a/drivers/scsi/lpfc/lpfc_sli4.h
+++ b/drivers/scsi/lpfc/lpfc_sli4.h
@@ -132,6 +132,7 @@ struct lpfc_sli4_link {
 
 struct lpfc_fcf {
 	uint8_t	 fabric_name[8];
+	uint8_t	 switch_name[8];
 	uint8_t  mac_addr[6];
 	uint16_t fcf_indx;
 	uint16_t fcfi;
@@ -150,6 +151,10 @@ struct lpfc_fcf {
 #define LPFC_REGION23_SIGNATURE "RG23"
 #define LPFC_REGION23_VERSION	1
 #define LPFC_REGION23_LAST_REC  0xff
+#define DRIVER_SPECIFIC_TYPE	0xA2
+#define LINUX_DRIVER_ID		0x20
+#define PORT_STE_TYPE		0x1
+
 struct lpfc_fip_param_hdr {
 	uint8_t type;
 #define FCOE_PARAM_TYPE		0xA0
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 41094e0..9ae20af 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.3"
+#define LPFC_DRIVER_VERSION "8.3.4"
 
 #define LPFC_DRIVER_NAME		"lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME	"lpfc:sp"
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index e0b4992..606efa7 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -313,22 +313,6 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
 		goto error_out;
 	}
 
-	/*
-	 * In SLI4, the vpi must be activated before it can be used
-	 * by the port.
-	 */
-	if (phba->sli_rev == LPFC_SLI_REV4) {
-		rc = lpfc_sli4_init_vpi(phba, vpi);
-		if (rc) {
-			lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
-					"1838 Failed to INIT_VPI on vpi %d "
-					"status %d\n", vpi, rc);
-			rc = VPORT_NORESOURCES;
-			lpfc_free_vpi(phba, vpi);
-			goto error_out;
-		}
-	}
-
 	/* Assign an unused board number */
 	if ((instance = lpfc_get_instance()) < 0) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
@@ -367,12 +351,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
 		goto error_out;
 	}
 
-	memcpy(vport->fc_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8);
-	memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.u.wwn, 8);
-	if (fc_vport->node_name != 0)
-		u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn);
-	if (fc_vport->port_name != 0)
-		u64_to_wwn(fc_vport->port_name, vport->fc_portname.u.wwn);
+	u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn);
+	u64_to_wwn(fc_vport->port_name, vport->fc_portname.u.wwn);
 
 	memcpy(&vport->fc_sparam.portName, vport->fc_portname.u.wwn, 8);
 	memcpy(&vport->fc_sparam.nodeName, vport->fc_nodename.u.wwn, 8);
@@ -404,7 +384,34 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
 	*(struct lpfc_vport **)fc_vport->dd_data = vport;
 	vport->fc_vport = fc_vport;
 
+	/*
+	 * In SLI4, the vpi must be activated before it can be used
+	 * by the port.
+	 */
+	if ((phba->sli_rev == LPFC_SLI_REV4) &&
+		(pport->vfi_state & LPFC_VFI_REGISTERED)) {
+		rc = lpfc_sli4_init_vpi(phba, vpi);
+		if (rc) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
+					"1838 Failed to INIT_VPI on vpi %d "
+					"status %d\n", vpi, rc);
+			rc = VPORT_NORESOURCES;
+			lpfc_free_vpi(phba, vpi);
+			goto error_out;
+		}
+	} else if (phba->sli_rev == LPFC_SLI_REV4) {
+		/*
+		 * Driver cannot INIT_VPI now. Set the flags to
+		 * init_vpi when reg_vfi complete.
+		 */
+		vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
+		lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
+		rc = VPORT_OK;
+		goto out;
+	}
+
 	if ((phba->link_state < LPFC_LINK_UP) ||
+	    (pport->port_state < LPFC_FABRIC_CFG_LINK) ||
 	    (phba->fc_topology == TOPOLOGY_LOOP)) {
 		lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
 		rc = VPORT_OK;
@@ -661,7 +668,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
 				lpfc_printf_log(vport->phba, KERN_WARNING,
 						LOG_VPORT,
 						"1829 CT command failed to "
-						"delete objects on fabric. \n");
+						"delete objects on fabric\n");
 		}
 		/* First look for the Fabric ndlp */
 		ndlp = lpfc_findnode_did(vport, Fabric_DID);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 35a1386..d95d2f2 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -94,7 +94,7 @@ _base_fault_reset_work(struct work_struct *work)
 	int rc;
 
 	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (ioc->ioc_reset_in_progress)
+	if (ioc->shost_recovery)
 		goto rearm_timer;
 	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
@@ -687,6 +687,14 @@ _base_unmask_interrupts(struct MPT2SAS_ADAPTER *ioc)
 	ioc->mask_interrupts = 0;
 }
 
+union reply_descriptor {
+	u64 word;
+	struct {
+		u32 low;
+		u32 high;
+	} u;
+};
+
 /**
  * _base_interrupt - MPT adapter (IOC) specific interrupt handler.
  * @irq: irq number (not used)
@@ -698,47 +706,38 @@ _base_unmask_interrupts(struct MPT2SAS_ADAPTER *ioc)
 static irqreturn_t
 _base_interrupt(int irq, void *bus_id)
 {
-	union reply_descriptor {
-		u64 word;
-		struct {
-			u32 low;
-			u32 high;
-		} u;
-	};
 	union reply_descriptor rd;
-	u32 post_index, post_index_next, completed_cmds;
+	u32 completed_cmds;
 	u8 request_desript_type;
 	u16 smid;
 	u8 cb_idx;
 	u32 reply;
 	u8 VF_ID;
-	int i;
 	struct MPT2SAS_ADAPTER *ioc = bus_id;
+	Mpi2ReplyDescriptorsUnion_t *rpf;
 
 	if (ioc->mask_interrupts)
 		return IRQ_NONE;
 
-	post_index = ioc->reply_post_host_index;
-	request_desript_type = ioc->reply_post_free[post_index].
-	    Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
+	rpf = &ioc->reply_post_free[ioc->reply_post_host_index];
+	request_desript_type = rpf->Default.ReplyFlags
+	     & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
 	if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
 		return IRQ_NONE;
 
 	completed_cmds = 0;
 	do {
-		rd.word = ioc->reply_post_free[post_index].Words;
+		rd.word = rpf->Words;
 		if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX)
 			goto out;
 		reply = 0;
 		cb_idx = 0xFF;
-		smid = le16_to_cpu(ioc->reply_post_free[post_index].
-		    Default.DescriptorTypeDependent1);
-		VF_ID = ioc->reply_post_free[post_index].
-		    Default.VF_ID;
+		smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1);
+		VF_ID = rpf->Default.VF_ID;
 		if (request_desript_type ==
 		    MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
-			reply = le32_to_cpu(ioc->reply_post_free[post_index].
-			    AddressReply.ReplyFrameAddress);
+			reply = le32_to_cpu
+				(rpf->AddressReply.ReplyFrameAddress);
 		} else if (request_desript_type ==
 		    MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER)
 			goto next;
@@ -765,21 +764,27 @@ _base_interrupt(int irq, void *bus_id)
 			    0 : ioc->reply_free_host_index + 1;
 			ioc->reply_free[ioc->reply_free_host_index] =
 			    cpu_to_le32(reply);
+			wmb();
 			writel(ioc->reply_free_host_index,
 			    &ioc->chip->ReplyFreeHostIndex);
-			wmb();
 		}
 
  next:
-		post_index_next = (post_index == (ioc->reply_post_queue_depth -
-		    1)) ? 0 : post_index + 1;
+
+		rpf->Words = ULLONG_MAX;
+		ioc->reply_post_host_index = (ioc->reply_post_host_index ==
+		    (ioc->reply_post_queue_depth - 1)) ? 0 :
+		    ioc->reply_post_host_index + 1;
 		request_desript_type =
-		    ioc->reply_post_free[post_index_next].Default.ReplyFlags
-		    & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
+		    ioc->reply_post_free[ioc->reply_post_host_index].Default.
+		    ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
 		completed_cmds++;
 		if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)
 			goto out;
-		post_index = post_index_next;
+		if (!ioc->reply_post_host_index)
+			rpf = ioc->reply_post_free;
+		else
+			rpf++;
 	} while (1);
 
  out:
@@ -787,19 +792,8 @@ _base_interrupt(int irq, void *bus_id)
 	if (!completed_cmds)
 		return IRQ_NONE;
 
-	/* reply post descriptor handling */
-	post_index_next = ioc->reply_post_host_index;
-	for (i = 0 ; i < completed_cmds; i++) {
-		post_index = post_index_next;
-		/* poison the reply post descriptor */
-		ioc->reply_post_free[post_index_next].Words = ULLONG_MAX;
-		post_index_next = (post_index ==
-		    (ioc->reply_post_queue_depth - 1))
-		    ? 0 : post_index + 1;
-	}
-	ioc->reply_post_host_index = post_index_next;
-	writel(post_index_next, &ioc->chip->ReplyPostHostIndex);
 	wmb();
+	writel(ioc->reply_post_host_index, &ioc->chip->ReplyPostHostIndex);
 	return IRQ_HANDLED;
 }
 
@@ -1542,6 +1536,8 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
 	   (ioc->bios_pg3.BiosVersion & 0x0000FF00) >> 8,
 	    ioc->bios_pg3.BiosVersion & 0x000000FF);
 
+	_base_display_dell_branding(ioc);
+
 	printk(MPT2SAS_INFO_FMT "Protocol=(", ioc->name);
 
 	if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_SCSI_INITIATOR) {
@@ -1554,8 +1550,6 @@ _base_display_ioc_capabilities(struct MPT2SAS_ADAPTER *ioc)
 		i++;
 	}
 
-	_base_display_dell_branding(ioc);
-
 	i = 0;
 	printk("), ");
 	printk("Capabilities=(");
@@ -1627,6 +1621,9 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
 	u32 iounit_pg1_flags;
 
 	mpt2sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
+	if (ioc->ir_firmware)
+		mpt2sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
+		    &ioc->manu_pg10);
 	mpt2sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
 	mpt2sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
 	mpt2sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8);
@@ -1647,7 +1644,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
 		iounit_pg1_flags |=
 		    MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING;
 	ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags);
-	mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, ioc->iounit_pg1);
+	mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1);
 }
 
 /**
@@ -3303,13 +3300,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
 	ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
 	ioc->tm_cmds.status = MPT2_CMD_NOT_USED;
 	mutex_init(&ioc->tm_cmds.mutex);
-	init_completion(&ioc->tm_cmds.done);
 
 	/* config page internal command bits */
 	ioc->config_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
 	ioc->config_cmds.status = MPT2_CMD_NOT_USED;
 	mutex_init(&ioc->config_cmds.mutex);
-	init_completion(&ioc->config_cmds.done);
 
 	/* ctl module internal command bits */
 	ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
@@ -3433,6 +3428,7 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
 		if (ioc->config_cmds.status & MPT2_CMD_PENDING) {
 			ioc->config_cmds.status |= MPT2_CMD_RESET;
 			mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid);
+			ioc->config_cmds.smid = USHORT_MAX;
 			complete(&ioc->config_cmds.done);
 		}
 		break;
@@ -3501,20 +3497,13 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
 	    __func__));
 
 	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (ioc->ioc_reset_in_progress) {
+	if (ioc->shost_recovery) {
 		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 		printk(MPT2SAS_ERR_FMT "%s: busy\n",
 		    ioc->name, __func__);
 		return -EBUSY;
 	}
-	ioc->ioc_reset_in_progress = 1;
 	ioc->shost_recovery = 1;
-	if (ioc->shost->shost_state == SHOST_RUNNING) {
-		/* set back to SHOST_RUNNING in mpt2sas_scsih.c */
-		scsi_host_set_state(ioc->shost, SHOST_RECOVERY);
-		printk(MPT2SAS_INFO_FMT "putting controller into "
-		    "SHOST_RECOVERY\n", ioc->name);
-	}
 	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	_base_reset_handler(ioc, MPT2_IOC_PRE_RESET);
@@ -3534,7 +3523,10 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
 	    ioc->name, __func__, ((r == 0) ? "SUCCESS" : "FAILED")));
 
 	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	ioc->ioc_reset_in_progress = 0;
+	ioc->shost_recovery = 0;
 	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+
+	if (!r)
+		_base_reset_handler(ioc, MPT2_IOC_RUNNING);
 	return r;
 }
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index acdcff1..2faab1e 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -69,10 +69,10 @@
 #define MPT2SAS_DRIVER_NAME		"mpt2sas"
 #define MPT2SAS_AUTHOR	"LSI Corporation <DL-MPTFusionLinux@lsi.com>"
 #define MPT2SAS_DESCRIPTION	"LSI MPT Fusion SAS 2.0 Device Driver"
-#define MPT2SAS_DRIVER_VERSION		"01.100.04.00"
+#define MPT2SAS_DRIVER_VERSION		"01.100.06.00"
 #define MPT2SAS_MAJOR_VERSION		01
 #define MPT2SAS_MINOR_VERSION		100
-#define MPT2SAS_BUILD_VERSION		04
+#define MPT2SAS_BUILD_VERSION		06
 #define MPT2SAS_RELEASE_VERSION		00
 
 /*
@@ -119,6 +119,7 @@
 #define MPT2_IOC_PRE_RESET		1 /* prior to host reset */
 #define MPT2_IOC_AFTER_RESET		2 /* just after host reset */
 #define MPT2_IOC_DONE_RESET		3 /* links re-initialized */
+#define MPT2_IOC_RUNNING		4 /* shost running */
 
 /*
  * logging format
@@ -196,6 +197,38 @@ struct MPT2SAS_TARGET {
  * @block: device is in SDEV_BLOCK state
  * @tlr_snoop_check: flag used in determining whether to disable TLR
  */
+
+/* OEM Identifiers */
+#define MFG10_OEM_ID_INVALID                   (0x00000000)
+#define MFG10_OEM_ID_DELL                      (0x00000001)
+#define MFG10_OEM_ID_FSC                       (0x00000002)
+#define MFG10_OEM_ID_SUN                       (0x00000003)
+#define MFG10_OEM_ID_IBM                       (0x00000004)
+
+/* GENERIC Flags 0*/
+#define MFG10_GF0_OCE_DISABLED                 (0x00000001)
+#define MFG10_GF0_R1E_DRIVE_COUNT              (0x00000002)
+#define MFG10_GF0_R10_DISPLAY                  (0x00000004)
+#define MFG10_GF0_SSD_DATA_SCRUB_DISABLE       (0x00000008)
+#define MFG10_GF0_SINGLE_DRIVE_R0              (0x00000010)
+
+/* OEM Specific Flags will come from OEM specific header files */
+typedef struct _MPI2_CONFIG_PAGE_MAN_10 {
+    MPI2_CONFIG_PAGE_HEADER Header;                                 /* 00h */
+    U8                      OEMIdentifier;                          /* 04h */
+    U8                      Reserved1;                              /* 05h */
+    U16                     Reserved2;                              /* 08h */
+    U32                     Reserved3;                              /* 0Ch */
+    U32                     GenericFlags0;                          /* 10h */
+    U32                     GenericFlags1;                          /* 14h */
+    U32                     Reserved4;                              /* 18h */
+    U32                     OEMSpecificFlags0;                      /* 1Ch */
+    U32                     OEMSpecificFlags1;                      /* 20h */
+    U32                     Reserved5[18];                          /* 24h-60h*/
+} MPI2_CONFIG_PAGE_MAN_10,
+  MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10,
+  Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t;
+
 struct MPT2SAS_DEVICE {
 	struct MPT2SAS_TARGET *sas_target;
 	unsigned int	lun;
@@ -431,7 +464,7 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
  * @fw_event_list: list of fw events
  * @aen_event_read_flag: event log was read
  * @broadcast_aen_busy: broadcast aen waiting to be serviced
- * @ioc_reset_in_progress: host reset in progress
+ * @shost_recovery: host reset in progress
  * @ioc_reset_in_progress_lock:
  * @ioc_link_reset_in_progress: phy/hard reset in progress
  * @ignore_loginfos: ignore loginfos during task managment
@@ -460,6 +493,7 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
  * @facts: static facts data
  * @pfacts: static port facts data
  * @manu_pg0: static manufacturing page 0
+ * @manu_pg10: static manufacturing page 10
  * @bios_pg2: static bios page 2
  * @bios_pg3: static bios page 3
  * @ioc_pg8: static ioc page 8
@@ -544,7 +578,6 @@ struct MPT2SAS_ADAPTER {
 	 /* misc flags */
 	int		aen_event_read_flag;
 	u8		broadcast_aen_busy;
-	u8		ioc_reset_in_progress;
 	u8		shost_recovery;
 	spinlock_t 	ioc_reset_in_progress_lock;
 	u8		ioc_link_reset_in_progress;
@@ -663,6 +696,7 @@ struct MPT2SAS_ADAPTER {
 	dma_addr_t	diag_buffer_dma[MPI2_DIAG_BUF_TYPE_COUNT];
 	u8		diag_buffer_status[MPI2_DIAG_BUF_TYPE_COUNT];
 	u32		unique_id[MPI2_DIAG_BUF_TYPE_COUNT];
+	Mpi2ManufacturingPage10_t manu_pg10;
 	u32		product_specific[MPI2_DIAG_BUF_TYPE_COUNT][23];
 	u32		diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
 };
@@ -734,6 +768,8 @@ void mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 re
 int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys);
 int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
     Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page);
+int mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc,
+    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage10_t *config_page);
 int mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
     *mpi_reply, Mpi2BiosPage2_t *config_page);
 int mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
@@ -749,7 +785,7 @@ int mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRep
 int mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
     *mpi_reply, Mpi2IOUnitPage1_t *config_page);
 int mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
-    *mpi_reply, Mpi2IOUnitPage1_t config_page);
+    *mpi_reply, Mpi2IOUnitPage1_t *config_page);
 int mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
     *mpi_reply, Mpi2SasIOUnitPage1_t *config_page, u16 sz);
 int mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
@@ -776,7 +812,6 @@ int mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
     u16 *volume_handle);
 int mpt2sas_config_get_volume_wwid(struct MPT2SAS_ADAPTER *ioc, u16 volume_handle,
     u64 *wwid);
-
 /* ctl shared API */
 extern struct device_attribute *mpt2sas_host_attrs[];
 extern struct device_attribute *mpt2sas_dev_attrs[];
@@ -798,9 +833,11 @@ int mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
     *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev);
 int mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
     *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev);
-void mpt2sas_transport_update_phy_link_change(struct MPT2SAS_ADAPTER *ioc, u16 handle,
+void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle,
    u16 attached_handle, u8 phy_number, u8 link_rate);
 extern struct sas_function_template mpt2sas_transport_functions;
 extern struct scsi_transport_template *mpt2sas_transport_template;
+extern int scsi_internal_device_block(struct scsi_device *sdev);
+extern int scsi_internal_device_unblock(struct scsi_device *sdev);
 
 #endif /* MPT2SAS_BASE_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index 6ddee16..ab8c560 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -72,15 +72,15 @@
 
 /**
  * struct config_request - obtain dma memory via routine
- * @config_page_sz: size
- * @config_page: virt pointer
- * @config_page_dma: phys pointer
+ * @sz: size
+ * @page: virt pointer
+ * @page_dma: phys pointer
  *
  */
 struct config_request{
-	u16			config_page_sz;
-	void			*config_page;
-	dma_addr_t		config_page_dma;
+	u16			sz;
+	void			*page;
+	dma_addr_t		page_dma;
 };
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -175,6 +175,55 @@ _config_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
 #endif
 
 /**
+ * _config_alloc_config_dma_memory - obtain physical memory
+ * @ioc: per adapter object
+ * @mem: struct config_request
+ *
+ * A wrapper for obtaining dma-able memory for config page request.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+static int
+_config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
+    struct config_request *mem)
+{
+	int r = 0;
+
+	if (mem->sz > ioc->config_page_sz) {
+		mem->page = dma_alloc_coherent(&ioc->pdev->dev, mem->sz,
+		    &mem->page_dma, GFP_KERNEL);
+		if (!mem->page) {
+			printk(MPT2SAS_ERR_FMT "%s: dma_alloc_coherent"
+			    " failed asking for (%d) bytes!!\n",
+			    ioc->name, __func__, mem->sz);
+			r = -ENOMEM;
+		}
+	} else { /* use tmp buffer if less than 512 bytes */
+		mem->page = ioc->config_page;
+		mem->page_dma = ioc->config_page_dma;
+	}
+	return r;
+}
+
+/**
+ * _config_free_config_dma_memory - wrapper to free the memory
+ * @ioc: per adapter object
+ * @mem: struct config_request
+ *
+ * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
+ *
+ * Returns 0 for success, non-zero for failure.
+ */
+static void
+_config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
+    struct config_request *mem)
+{
+	if (mem->sz > ioc->config_page_sz)
+		dma_free_coherent(&ioc->pdev->dev, mem->sz, mem->page,
+		    mem->page_dma);
+}
+
+/**
  * mpt2sas_config_done - config page completion routine
  * @ioc: per adapter object
  * @smid: system request message index
@@ -206,6 +255,7 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	_config_display_some_debug(ioc, smid, "config_done", mpi_reply);
 #endif
+	ioc->config_cmds.smid = USHORT_MAX;
 	complete(&ioc->config_cmds.done);
 }
 
@@ -215,7 +265,9 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
  * @mpi_request: request message frame
  * @mpi_reply: reply mf payload returned from firmware
  * @timeout: timeout in seconds
- * Context: sleep, the calling function needs to acquire the config_cmds.mutex
+ * @config_page: contents of the config page
+ * @config_page_sz: size of config page
+ * Context: sleep
  *
  * A generic API for config page requests to firmware.
  *
@@ -228,16 +280,17 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
  */
 static int
 _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
-    *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout)
+    *mpi_request, Mpi2ConfigReply_t *mpi_reply, int timeout,
+    void *config_page, u16 config_page_sz)
 {
 	u16 smid;
 	u32 ioc_state;
 	unsigned long timeleft;
 	Mpi2ConfigRequest_t *config_request;
 	int r;
-	u8 retry_count;
-	u8 issue_host_reset = 0;
+	u8 retry_count, issue_host_reset = 0;
 	u16 wait_state_count;
+	struct config_request mem;
 
 	mutex_lock(&ioc->config_cmds.mutex);
 	if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
@@ -246,12 +299,44 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
 		mutex_unlock(&ioc->config_cmds.mutex);
 		return -EAGAIN;
 	}
+
 	retry_count = 0;
+	memset(&mem, 0, sizeof(struct config_request));
+
+	if (config_page) {
+		mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
+		mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
+		mpi_request->Header.PageType = mpi_reply->Header.PageType;
+		mpi_request->Header.PageLength = mpi_reply->Header.PageLength;
+		mpi_request->ExtPageLength = mpi_reply->ExtPageLength;
+		mpi_request->ExtPageType = mpi_reply->ExtPageType;
+		if (mpi_request->Header.PageLength)
+			mem.sz = mpi_request->Header.PageLength * 4;
+		else
+			mem.sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
+		r = _config_alloc_config_dma_memory(ioc, &mem);
+		if (r != 0)
+			goto out;
+		if (mpi_request->Action ==
+		    MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT) {
+			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
+			    MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.sz,
+			    mem.page_dma);
+			memcpy(mem.page, config_page, min_t(u16, mem.sz,
+			    config_page_sz));
+		} else {
+			memset(config_page, 0, config_page_sz);
+			ioc->base_add_sg_single(&mpi_request->PageBufferSGE,
+			    MPT2_CONFIG_COMMON_SGLFLAGS | mem.sz, mem.page_dma);
+		}
+	}
 
  retry_config:
 	if (retry_count) {
-		if (retry_count > 2) /* attempt only 2 retries */
-			return -EFAULT;
+		if (retry_count > 2) { /* attempt only 2 retries */
+			r = -EFAULT;
+			goto free_mem;
+		}
 		printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n",
 		    ioc->name, __func__, retry_count);
 	}
@@ -262,8 +347,9 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
 			printk(MPT2SAS_ERR_FMT
 			    "%s: failed due to ioc not operational\n",
 			    ioc->name, __func__);
+			ioc->config_cmds.status = MPT2_CMD_NOT_USED;
 			r = -EFAULT;
-			goto out;
+			goto free_mem;
 		}
 		ssleep(1);
 		ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
@@ -279,8 +365,9 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
 	if (!smid) {
 		printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
 		    ioc->name, __func__);
+		ioc->config_cmds.status = MPT2_CMD_NOT_USED;
 		r = -EAGAIN;
-		goto out;
+		goto free_mem;
 	}
 
 	r = 0;
@@ -292,6 +379,7 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	_config_display_some_debug(ioc, smid, "config_request", NULL);
 #endif
+	init_completion(&ioc->config_cmds.done);
 	mpt2sas_base_put_smid_default(ioc, smid, config_request->VF_ID);
 	timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
 	    timeout*HZ);
@@ -303,22 +391,31 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
 		retry_count++;
 		if (ioc->config_cmds.smid == smid)
 			mpt2sas_base_free_smid(ioc, smid);
-		if ((ioc->shost_recovery) ||
-		    (ioc->config_cmds.status & MPT2_CMD_RESET))
+		if ((ioc->shost_recovery) || (ioc->config_cmds.status &
+		    MPT2_CMD_RESET))
 			goto retry_config;
 		issue_host_reset = 1;
 		r = -EFAULT;
-		goto out;
+		goto free_mem;
 	}
+
 	if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
 		memcpy(mpi_reply, ioc->config_cmds.reply,
 		    sizeof(Mpi2ConfigReply_t));
 	if (retry_count)
-		printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n",
-		    ioc->name, __func__);
-out:
+		printk(MPT2SAS_INFO_FMT "%s: retry (%d) completed!!\n",
+		    ioc->name, __func__, retry_count);
+	if (config_page && mpi_request->Action ==
+	    MPI2_CONFIG_ACTION_PAGE_READ_CURRENT)
+		memcpy(config_page, mem.page, min_t(u16, mem.sz,
+		    config_page_sz));
+ free_mem:
+	if (config_page)
+		_config_free_config_dma_memory(ioc, &mem);
+ out:
 	ioc->config_cmds.status = MPT2_CMD_NOT_USED;
 	mutex_unlock(&ioc->config_cmds.mutex);
+
 	if (issue_host_reset)
 		mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
 		    FORCE_BIG_HAMMER);
@@ -326,46 +423,43 @@ out:
 }
 
 /**
- * _config_alloc_config_dma_memory - obtain physical memory
+ * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
  * @ioc: per adapter object
- * @mem: struct config_request
- *
- * A wrapper for obtaining dma-able memory for config page request.
+ * @mpi_reply: reply mf payload returned from firmware
+ * @config_page: contents of the config page
+ * Context: sleep.
  *
  * Returns 0 for success, non-zero for failure.
  */
-static int
-_config_alloc_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
-    struct config_request *mem)
+int
+mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
+    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
 {
-	int r = 0;
+	Mpi2ConfigRequest_t mpi_request;
+	int r;
 
-	mem->config_page = pci_alloc_consistent(ioc->pdev, mem->config_page_sz,
-	    &mem->config_page_dma);
-	if (!mem->config_page)
-		r = -ENOMEM;
-	return r;
-}
+	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
+	mpi_request.Function = MPI2_FUNCTION_CONFIG;
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
+	mpi_request.Header.PageNumber = 0;
+	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
+	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
+	if (r)
+		goto out;
 
-/**
- * _config_free_config_dma_memory - wrapper to free the memory
- * @ioc: per adapter object
- * @mem: struct config_request
- *
- * A wrapper to free dma-able memory when using _config_alloc_config_dma_memory.
- *
- * Returns 0 for success, non-zero for failure.
- */
-static void
-_config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
-    struct config_request *mem)
-{
-	pci_free_consistent(ioc->pdev, mem->config_page_sz, mem->config_page,
-	    mem->config_page_dma);
+	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+	r = _config_request(ioc, &mpi_request, mpi_reply,
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
+ out:
+	return r;
 }
 
 /**
- * mpt2sas_config_get_manufacturing_pg0 - obtain manufacturing page 0
+ * mpt2sas_config_get_manufacturing_pg10 - obtain manufacturing page 10
  * @ioc: per adapter object
  * @mpi_reply: reply mf payload returned from firmware
  * @config_page: contents of the config page
@@ -374,53 +468,28 @@ _config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
  * Returns 0 for success, non-zero for failure.
  */
 int
-mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page)
+mpt2sas_config_get_manufacturing_pg10(struct MPT2SAS_ADAPTER *ioc,
+    Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage10_t *config_page)
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_MANUFACTURING;
-	mpi_request.Header.PageNumber = 0;
+	mpi_request.Header.PageNumber = 10;
 	mpi_request.Header.PageVersion = MPI2_MANUFACTURING0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2ManufacturingPage0_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -440,9 +509,7 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2BiosPage2_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -451,37 +518,14 @@ mpt2sas_config_get_bios_pg2(struct MPT2SAS_ADAPTER *ioc,
 	mpi_request.Header.PageVersion = MPI2_BIOSPAGE2_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2BiosPage2_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -501,9 +545,7 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2BiosPage3_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -512,37 +554,14 @@ mpt2sas_config_get_bios_pg3(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2BiosPage3_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -562,9 +581,7 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -573,37 +590,14 @@ mpt2sas_config_get_iounit_pg0(struct MPT2SAS_ADAPTER *ioc,
 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2IOUnitPage0_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -623,9 +617,7 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -634,37 +626,14 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2IOUnitPage1_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -680,11 +649,10 @@ mpt2sas_config_get_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
  */
 int
 mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
-    Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t config_page)
+    Mpi2ConfigReply_t *mpi_reply, Mpi2IOUnitPage1_t *config_page)
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -694,38 +662,14 @@ mpt2sas_config_set_iounit_pg1(struct MPT2SAS_ADAPTER *ioc,
 	mpi_request.Header.PageVersion = MPI2_IOUNITPAGE1_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-
-	memset(mem.config_page, 0, mem.config_page_sz);
-	memcpy(mem.config_page, &config_page,
-	    sizeof(Mpi2IOUnitPage1_t));
-
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_WRITE_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -745,9 +689,7 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2IOCPage8_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -756,37 +698,14 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SAS_ADAPTER *ioc,
 	mpi_request.Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2IOCPage8_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -808,9 +727,7 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -820,39 +737,15 @@ mpt2sas_config_get_sas_device_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageNumber = 0;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress = cpu_to_le32(form | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2SasDevicePage0_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -874,9 +767,7 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -886,39 +777,15 @@ mpt2sas_config_get_sas_device_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageNumber = 1;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress = cpu_to_le32(form | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2SasDevicePage1_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -936,11 +803,11 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 	u16 ioc_status;
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasIOUnitPage0_t config_page;
 
+	*num_phys = 0;
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -950,44 +817,20 @@ mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys)
 	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, &mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply.Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply.ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, &mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
+	    sizeof(Mpi2SasIOUnitPage0_t));
 	if (!r) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-			memcpy(&config_page, mem.config_page,
-			    min_t(u16, mem.config_page_sz,
-			    sizeof(Mpi2SasIOUnitPage0_t)));
+		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
 			*num_phys = config_page.NumPhys;
-		}
 	}
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
  out:
 	return r;
 }
@@ -1011,8 +854,7 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
-	memset(config_page, 0, sz);
+
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1022,37 +864,13 @@ mpt2sas_config_get_sas_iounit_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, sz, mem.config_page_sz));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  out:
 	return r;
 }
@@ -1076,9 +894,7 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sz);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1088,37 +904,13 @@ mpt2sas_config_get_sas_iounit_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_SASIOUNITPAGE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, sz, mem.config_page_sz));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  out:
 	return r;
 }
@@ -1140,9 +932,7 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1152,39 +942,15 @@ mpt2sas_config_get_expander_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_SASEXPANDER0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress = cpu_to_le32(form | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2ExpanderPage0_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -1207,9 +973,7 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1219,7 +983,7 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_SASEXPANDER1_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
@@ -1227,33 +991,9 @@ mpt2sas_config_get_expander_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	    cpu_to_le32(MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
 	    (phy_number << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2ExpanderPage1_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -1275,9 +1015,7 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1287,39 +1025,15 @@ mpt2sas_config_get_enclosure_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_SASENCLOSURE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress = cpu_to_le32(form | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2SasEnclosurePage0_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -1340,9 +1054,7 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1352,40 +1064,16 @@ mpt2sas_config_get_phy_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_SASPHY0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress =
 	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2SasPhyPage0_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -1406,9 +1094,7 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1418,40 +1104,16 @@ mpt2sas_config_get_phy_pg1(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_SASPHY1_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress =
 	    cpu_to_le32(MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | phy_number);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply->ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply->ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2SasPhyPage1_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -1474,9 +1136,7 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
-	memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1485,38 +1145,15 @@ mpt2sas_config_get_raid_volume_pg1(struct MPT2SAS_ADAPTER *ioc,
 	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress = cpu_to_le32(form | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2RaidVolPage1_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -1535,10 +1172,9 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
     u8 *num_pds)
 {
 	Mpi2ConfigRequest_t mpi_request;
-	Mpi2RaidVolPage0_t *config_page;
+	Mpi2RaidVolPage0_t config_page;
 	Mpi2ConfigReply_t mpi_reply;
 	int r;
-	struct config_request mem;
 	u16 ioc_status;
 
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
@@ -1550,43 +1186,23 @@ mpt2sas_config_get_number_pds(struct MPT2SAS_ADAPTER *ioc, u16 handle,
 	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, &mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress =
 	    cpu_to_le32(MPI2_RAID_VOLUME_PGAD_FORM_HANDLE | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply.Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply.Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply.Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, &mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, &config_page,
+	    sizeof(Mpi2RaidVolPage0_t));
 	if (!r) {
 		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
 		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_SUCCESS) {
-			config_page = mem.config_page;
-			*num_pds = config_page->NumPhysDisks;
-		}
+		if (ioc_status == MPI2_IOCSTATUS_SUCCESS)
+			*num_pds = config_page.NumPhysDisks;
 	}
 
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
  out:
 	return r;
 }
@@ -1610,10 +1226,8 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-	memset(config_page, 0, sz);
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_VOLUME;
@@ -1621,37 +1235,14 @@ mpt2sas_config_get_raid_volume_pg0(struct MPT2SAS_ADAPTER *ioc,
 	mpi_request.Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress = cpu_to_le32(form | handle);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, sz, mem.config_page_sz));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page, sz);
  out:
 	return r;
 }
@@ -1674,10 +1265,8 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 {
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
-	struct config_request mem;
 
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
-	memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
 	mpi_request.Header.PageType = MPI2_CONFIG_PAGETYPE_RAID_PHYSDISK;
@@ -1685,38 +1274,15 @@ mpt2sas_config_get_phys_disk_pg0(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigReply_t
 	mpi_request.Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress = cpu_to_le32(form | form_specific);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply->Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply->Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply->Header.PageType;
-	mpi_request.Header.PageLength = mpi_reply->Header.PageLength;
-	mem.config_page_sz = le16_to_cpu(mpi_reply->Header.PageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
 	r = _config_request(ioc, &mpi_request, mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
-	if (!r)
-		memcpy(config_page, mem.config_page,
-		    min_t(u16, mem.config_page_sz,
-		    sizeof(Mpi2RaidPhysDiskPage0_t)));
-
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    sizeof(*config_page));
  out:
 	return r;
 }
@@ -1734,11 +1300,10 @@ int
 mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
     u16 *volume_handle)
 {
-	Mpi2RaidConfigurationPage0_t *config_page;
+	Mpi2RaidConfigurationPage0_t *config_page = NULL;
 	Mpi2ConfigRequest_t mpi_request;
 	Mpi2ConfigReply_t mpi_reply;
-	int r, i;
-	struct config_request mem;
+	int r, i, config_page_sz;
 	u16 ioc_status;
 
 	*volume_handle = 0;
@@ -1751,40 +1316,27 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
 	mpi_request.Header.PageNumber = 0;
 	mpt2sas_base_build_zero_len_sge(ioc, &mpi_request.PageBufferSGE);
 	r = _config_request(ioc, &mpi_request, &mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, NULL, 0);
 	if (r)
 		goto out;
 
 	mpi_request.PageAddress =
 	    cpu_to_le32(MPI2_RAID_PGAD_FORM_ACTIVE_CONFIG);
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
-	mpi_request.Header.PageVersion = mpi_reply.Header.PageVersion;
-	mpi_request.Header.PageNumber = mpi_reply.Header.PageNumber;
-	mpi_request.Header.PageType = mpi_reply.Header.PageType;
-	mpi_request.ExtPageLength = mpi_reply.ExtPageLength;
-	mpi_request.ExtPageType = mpi_reply.ExtPageType;
-	mem.config_page_sz = le16_to_cpu(mpi_reply.ExtPageLength) * 4;
-	if (mem.config_page_sz > ioc->config_page_sz) {
-		r = _config_alloc_config_dma_memory(ioc, &mem);
-		if (r)
-			goto out;
-	} else {
-		mem.config_page_dma = ioc->config_page_dma;
-		mem.config_page = ioc->config_page;
-	}
-	ioc->base_add_sg_single(&mpi_request.PageBufferSGE,
-	    MPT2_CONFIG_COMMON_SGLFLAGS | mem.config_page_sz,
-	    mem.config_page_dma);
+	config_page_sz = (le16_to_cpu(mpi_reply.ExtPageLength) * 4);
+	config_page = kmalloc(config_page_sz, GFP_KERNEL);
+	if (!config_page)
+		goto out;
 	r = _config_request(ioc, &mpi_request, &mpi_reply,
-	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT);
+	    MPT2_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
+	    config_page_sz);
 	if (r)
 		goto out;
 
 	r = -1;
 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK;
 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
-		goto done;
-	config_page = mem.config_page;
+		goto out;
 	for (i = 0; i < config_page->NumElements; i++) {
 		if ((config_page->ConfigElement[i].ElementFlags &
 		    MPI2_RAIDCONFIG0_EFLAGS_MASK_ELEMENT_TYPE) !=
@@ -1795,15 +1347,11 @@ mpt2sas_config_get_volume_handle(struct MPT2SAS_ADAPTER *ioc, u16 pd_handle,
 			*volume_handle = le16_to_cpu(config_page->
 			    ConfigElement[i].VolDevHandle);
 			r = 0;
-			goto done;
+			goto out;
 		}
 	}
-
- done:
-	if (mem.config_page_sz > ioc->config_page_sz)
-		_config_free_config_dma_memory(ioc, &mem);
-
  out:
+	kfree(config_page);
 	return r;
 }
 
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 14e473d..c2a5101 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -1963,7 +1963,6 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
 {
 	enum block_state state;
 	long ret = -EINVAL;
-	unsigned long flags;
 
 	state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING :
 	    BLOCKING;
@@ -1989,13 +1988,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
 		    !ioc)
 			return -ENODEV;
 
-		spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-		if (ioc->shost_recovery) {
-			spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
-			    flags);
+		if (ioc->shost_recovery)
 			return -EAGAIN;
-		}
-		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 		if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
 			uarg = arg;
@@ -2098,7 +2092,6 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
 	struct mpt2_ioctl_command karg;
 	struct MPT2SAS_ADAPTER *ioc;
 	enum block_state state;
-	unsigned long flags;
 
 	if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32))
 		return -EINVAL;
@@ -2113,13 +2106,8 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
 	if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
 		return -ENODEV;
 
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (ioc->shost_recovery) {
-		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
-		    flags);
+	if (ioc->shost_recovery)
 		return -EAGAIN;
-	}
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
 	karg.hdr.ioc_number = karg32.hdr.ioc_number;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 2e9a444..774b345 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -103,7 +103,6 @@ struct sense_info {
 };
 
 
-#define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
 /**
  * struct fw_event_work - firmware event struct
  * @list: link list framework
@@ -1502,7 +1501,13 @@ _scsih_slave_configure(struct scsi_device *sdev)
 			break;
 		case MPI2_RAID_VOL_TYPE_RAID1E:
 			qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
-			r_level = "RAID1E";
+			if (ioc->manu_pg10.OEMIdentifier &&
+			    (ioc->manu_pg10.GenericFlags0 &
+			    MFG10_GF0_R10_DISPLAY) &&
+			    !(raid_device->num_pds % 2))
+				r_level = "RAID10";
+			else
+				r_level = "RAID1E";
 			break;
 		case MPI2_RAID_VOL_TYPE_RAID1:
 			qdepth = MPT2SAS_RAID_QUEUE_DEPTH;
@@ -1786,17 +1791,18 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
 	u32 ioc_state;
 	unsigned long timeleft;
 	u8 VF_ID = 0;
-	unsigned long flags;
 
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED ||
-	    ioc->shost_recovery) {
-		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+	if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
+		printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
+		    __func__, ioc->name);
+		return;
+	}
+
+	if (ioc->shost_recovery) {
 		printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
 		    __func__, ioc->name);
 		return;
 	}
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	ioc_state = mpt2sas_base_get_iocstate(ioc, 0);
 	if (ioc_state & MPI2_DOORBELL_USED) {
@@ -1830,6 +1836,7 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
 	mpi_request->TaskMID = cpu_to_le16(smid_task);
 	int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
 	mpt2sas_scsih_set_tm_flag(ioc, handle);
+	init_completion(&ioc->tm_cmds.done);
 	mpt2sas_base_put_smid_hi_priority(ioc, smid, VF_ID);
 	timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
 	mpt2sas_scsih_clear_tm_flag(ioc, handle);
@@ -2222,7 +2229,7 @@ _scsih_ublock_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 			    MPT2SAS_INFO_FMT "SDEV_RUNNING: "
 			    "handle(0x%04x)\n", ioc->name, handle));
 			sas_device_priv_data->block = 0;
-			scsi_device_set_state(sdev, SDEV_RUNNING);
+			scsi_internal_device_unblock(sdev);
 		}
 	}
 }
@@ -2251,7 +2258,7 @@ _scsih_block_io_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 			    MPT2SAS_INFO_FMT "SDEV_BLOCK: "
 			    "handle(0x%04x)\n", ioc->name, handle));
 			sas_device_priv_data->block = 1;
-			scsi_device_set_state(sdev, SDEV_BLOCK);
+			scsi_internal_device_block(sdev);
 		}
 	}
 }
@@ -2327,6 +2334,7 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
 	u16 handle;
 	u16 reason_code;
 	u8 phy_number;
+	u8 link_rate;
 
 	for (i = 0; i < event_data->NumEntries; i++) {
 		handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
@@ -2337,6 +2345,11 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
 		    MPI2_EVENT_SAS_TOPO_RC_MASK;
 		if (reason_code == MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING)
 			_scsih_block_io_device(ioc, handle);
+		if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
+			link_rate = event_data->PHY[i].LinkRate >> 4;
+			if (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)
+				_scsih_ublock_io_device(ioc, handle);
+		}
 	}
 }
 
@@ -2405,27 +2418,6 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
 }
 
 /**
- * _scsih_queue_rescan - queue a topology rescan from user context
- * @ioc: per adapter object
- *
- * Return nothing.
- */
-static void
-_scsih_queue_rescan(struct MPT2SAS_ADAPTER *ioc)
-{
-	struct fw_event_work *fw_event;
-
-	if (ioc->wait_for_port_enable_to_complete)
-		return;
-	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
-	if (!fw_event)
-		return;
-	fw_event->event = MPT2SAS_RESCAN_AFTER_HOST_RESET;
-	fw_event->ioc = ioc;
-	_scsih_fw_event_add(ioc, fw_event);
-}
-
-/**
  * _scsih_flush_running_cmds - completing outstanding commands.
  * @ioc: per adapter object
  *
@@ -2456,46 +2448,6 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
 }
 
 /**
- * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
- * @ioc: per adapter object
- * @reset_phase: phase
- *
- * The handler for doing any required cleanup or initialization.
- *
- * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
- * MPT2_IOC_DONE_RESET
- *
- * Return nothing.
- */
-void
-mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
-{
-	switch (reset_phase) {
-	case MPT2_IOC_PRE_RESET:
-		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
-		    "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
-		_scsih_fw_event_off(ioc);
-		break;
-	case MPT2_IOC_AFTER_RESET:
-		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
-		    "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
-		if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
-			ioc->tm_cmds.status |= MPT2_CMD_RESET;
-			mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
-			complete(&ioc->tm_cmds.done);
-		}
-		_scsih_fw_event_on(ioc);
-		_scsih_flush_running_cmds(ioc);
-		break;
-	case MPT2_IOC_DONE_RESET:
-		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
-		    "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
-		_scsih_queue_rescan(ioc);
-		break;
-	}
-}
-
-/**
  * _scsih_setup_eedp - setup MPI request for EEDP transfer
  * @scmd: pointer to scsi command object
  * @mpi_request: pointer to the SCSI_IO reqest message frame
@@ -2615,7 +2567,6 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
 	Mpi2SCSIIORequest_t *mpi_request;
 	u32 mpi_control;
 	u16 smid;
-	unsigned long flags;
 
 	scmd->scsi_done = done;
 	sas_device_priv_data = scmd->device->hostdata;
@@ -2634,13 +2585,10 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
 	}
 
 	/* see if we are busy with task managment stuff */
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (sas_target_priv_data->tm_busy ||
-	    ioc->shost_recovery || ioc->ioc_link_reset_in_progress) {
-		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+	if (sas_target_priv_data->tm_busy)
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+	else if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
 		return SCSI_MLQUEUE_HOST_BUSY;
-	}
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	if (scmd->sc_data_direction == DMA_FROM_DEVICE)
 		mpi_control = MPI2_SCSIIO_CONTROL_READ;
@@ -3189,25 +3137,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
 }
 
 /**
- * _scsih_link_change - process phy link changes
- * @ioc: per adapter object
- * @handle: phy handle
- * @attached_handle: valid for devices attached to link
- * @phy_number: phy number
- * @link_rate: new link rate
- * Context: user.
- *
- * Return nothing.
- */
-static void
-_scsih_link_change(struct MPT2SAS_ADAPTER *ioc, u16 handle, u16 attached_handle,
-   u8 phy_number, u8 link_rate)
-{
-	mpt2sas_transport_update_phy_link_change(ioc, handle, attached_handle,
-	    phy_number, link_rate);
-}
-
-/**
  * _scsih_sas_host_refresh - refreshing sas host object contents
  * @ioc: per adapter object
  * @update: update link information
@@ -3251,7 +3180,8 @@ _scsih_sas_host_refresh(struct MPT2SAS_ADAPTER *ioc, u8 update)
 			    le16_to_cpu(sas_iounit_pg0->PhyData[i].
 				ControllerDevHandle);
 			if (update)
-				_scsih_link_change(ioc,
+				mpt2sas_transport_update_links(
+				    ioc,
 				    ioc->sas_hba.phy[i].handle,
 				    le16_to_cpu(sas_iounit_pg0->PhyData[i].
 				    AttachedDevHandle), i,
@@ -3436,6 +3366,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 	if (!handle)
 		return -1;
 
+	if (ioc->shost_recovery)
+		return -1;
+
 	if ((mpt2sas_config_get_expander_pg0(ioc, &mpi_reply, &expander_pg0,
 	    MPI2_SAS_EXPAND_PGAD_FORM_HNDL, handle))) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -3572,6 +3505,9 @@ _scsih_expander_remove(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 	struct _sas_node *sas_expander;
 	unsigned long flags;
 
+	if (ioc->shost_recovery)
+		return;
+
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
 	sas_expander = mpt2sas_scsih_expander_find_by_handle(ioc, handle);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -3743,6 +3679,8 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 		mutex_unlock(&ioc->tm_cmds.mutex);
 		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "issue target reset "
 		    "done: handle(0x%04x)\n", ioc->name, device_handle));
+		if (ioc->shost_recovery)
+			goto out;
 	}
 
 	/* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
@@ -3765,6 +3703,9 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 	    le32_to_cpu(mpi_reply.IOCLogInfo)));
 
  out:
+
+	_scsih_ublock_io_device(ioc, handle);
+
 	mpt2sas_transport_port_remove(ioc, sas_device->sas_address,
 	    sas_device->parent_handle);
 
@@ -3908,6 +3849,8 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
 			    "expander event\n", ioc->name));
 			return;
 		}
+		if (ioc->shost_recovery)
+			return;
 		if (event_data->PHY[i].PhyStatus &
 		    MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
 			continue;
@@ -3923,9 +3866,10 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
 		case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
 			if (!parent_handle) {
 				if (phy_number < ioc->sas_hba.num_phys)
-					_scsih_link_change(ioc,
-					   ioc->sas_hba.phy[phy_number].handle,
-					   handle, phy_number, link_rate_);
+					mpt2sas_transport_update_links(
+					ioc,
+					ioc->sas_hba.phy[phy_number].handle,
+					handle, phy_number, link_rate_);
 			} else {
 				spin_lock_irqsave(&ioc->sas_node_lock, flags);
 				sas_expander =
@@ -3935,17 +3879,14 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
 				    flags);
 				if (sas_expander) {
 					if (phy_number < sas_expander->num_phys)
-						_scsih_link_change(ioc,
-						   sas_expander->
-						   phy[phy_number].handle,
-						   handle, phy_number,
-						   link_rate_);
+						mpt2sas_transport_update_links(
+						ioc,
+						sas_expander->
+						phy[phy_number].handle,
+						handle, phy_number,
+						link_rate_);
 				}
 			}
-			if (reason_code == MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED) {
-				if (link_rate_ >= MPI2_SAS_NEG_LINK_RATE_1_5)
-					_scsih_ublock_io_device(ioc, handle);
-			}
 			if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED) {
 				if (link_rate_ < MPI2_SAS_NEG_LINK_RATE_1_5)
 					break;
@@ -4455,7 +4396,7 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc,
 		return;
 	}
 
-	_scsih_link_change(ioc,
+	mpt2sas_transport_update_links(ioc,
 	    le16_to_cpu(sas_device_pg0.ParentDevHandle),
 	    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
 
@@ -4744,7 +4685,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
 			return;
 		}
 
-		_scsih_link_change(ioc,
+		mpt2sas_transport_update_links(ioc,
 		    le16_to_cpu(sas_device_pg0.ParentDevHandle),
 		    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
 
@@ -5156,22 +5097,9 @@ static void
 _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
 {
 	struct _sas_device *sas_device, *sas_device_next;
-	struct _sas_node *sas_expander, *sas_expander_next;
+	struct _sas_node *sas_expander;
 	struct _raid_device *raid_device, *raid_device_next;
-	unsigned long flags;
 
-	_scsih_search_responding_sas_devices(ioc);
-	_scsih_search_responding_raid_devices(ioc);
-	_scsih_search_responding_expanders(ioc);
-
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	ioc->shost_recovery = 0;
-	if (ioc->shost->shost_state == SHOST_RECOVERY) {
-		printk(MPT2SAS_INFO_FMT "putting controller into "
-		    "SHOST_RUNNING\n", ioc->name);
-		scsi_host_set_state(ioc->shost, SHOST_RUNNING);
-	}
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	list_for_each_entry_safe(sas_device, sas_device_next,
 	    &ioc->sas_device_list, list) {
@@ -5207,16 +5135,63 @@ _scsih_remove_unresponding_devices(struct MPT2SAS_ADAPTER *ioc)
 		_scsih_raid_device_remove(ioc, raid_device);
 	}
 
-	list_for_each_entry_safe(sas_expander, sas_expander_next,
-	    &ioc->sas_expander_list, list) {
+ retry_expander_search:
+	sas_expander = NULL;
+	list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) {
 		if (sas_expander->responding) {
 			sas_expander->responding = 0;
 			continue;
 		}
-		printk("\tremoving expander: handle(0x%04x), "
-		    " sas_addr(0x%016llx)\n", sas_expander->handle,
-		    (unsigned long long)sas_expander->sas_address);
 		_scsih_expander_remove(ioc, sas_expander->handle);
+		goto retry_expander_search;
+	}
+}
+
+/**
+ * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
+ * @ioc: per adapter object
+ * @reset_phase: phase
+ *
+ * The handler for doing any required cleanup or initialization.
+ *
+ * The reset phase can be MPT2_IOC_PRE_RESET, MPT2_IOC_AFTER_RESET,
+ * MPT2_IOC_DONE_RESET
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
+{
+	switch (reset_phase) {
+	case MPT2_IOC_PRE_RESET:
+		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+		    "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
+		_scsih_fw_event_off(ioc);
+		break;
+	case MPT2_IOC_AFTER_RESET:
+		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+		    "MPT2_IOC_AFTER_RESET\n", ioc->name, __func__));
+		if (ioc->tm_cmds.status & MPT2_CMD_PENDING) {
+			ioc->tm_cmds.status |= MPT2_CMD_RESET;
+			mpt2sas_base_free_smid(ioc, ioc->tm_cmds.smid);
+			complete(&ioc->tm_cmds.done);
+		}
+		_scsih_fw_event_on(ioc);
+		_scsih_flush_running_cmds(ioc);
+		break;
+	case MPT2_IOC_DONE_RESET:
+		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+		    "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
+		_scsih_sas_host_refresh(ioc, 0);
+		_scsih_search_responding_sas_devices(ioc);
+		_scsih_search_responding_raid_devices(ioc);
+		_scsih_search_responding_expanders(ioc);
+		break;
+	case MPT2_IOC_RUNNING:
+		dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+		    "MPT2_IOC_RUNNING\n", ioc->name, __func__));
+		_scsih_remove_unresponding_devices(ioc);
+		break;
 	}
 }
 
@@ -5236,14 +5211,6 @@ _firmware_event_work(struct work_struct *work)
 	unsigned long flags;
 	struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;
 
-	/* This is invoked by calling _scsih_queue_rescan(). */
-	if (fw_event->event == MPT2SAS_RESCAN_AFTER_HOST_RESET) {
-		_scsih_fw_event_free(ioc, fw_event);
-		_scsih_sas_host_refresh(ioc, 1);
-		_scsih_remove_unresponding_devices(ioc);
-		return;
-	}
-
 	/* the queue is being flushed so ignore this event */
 	spin_lock_irqsave(&ioc->fw_event_lock, flags);
 	if (ioc->fw_events_off || ioc->remove_host) {
@@ -5253,13 +5220,10 @@ _firmware_event_work(struct work_struct *work)
 	}
 	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
 
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
 	if (ioc->shost_recovery) {
-		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 		_scsih_fw_event_requeue(ioc, fw_event, 1000);
 		return;
 	}
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	switch (fw_event->event) {
 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
@@ -5461,6 +5425,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
 			if (!sas_device)
 				continue;
 			_scsih_remove_device(ioc, sas_device->handle);
+			if (ioc->shost_recovery)
+				return;
 			goto retry_device_search;
 		}
 	}
@@ -5482,6 +5448,8 @@ _scsih_expander_node_remove(struct MPT2SAS_ADAPTER *ioc,
 			if (!expander_sibling)
 				continue;
 			_scsih_expander_remove(ioc, expander_sibling->handle);
+			if (ioc->shost_recovery)
+				return;
 			goto retry_expander_search;
 		}
 	}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 686695b..742324a 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -140,11 +140,18 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
 	u32 device_info;
 	u32 ioc_status;
 
+	if (ioc->shost_recovery) {
+		printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
+		    __func__, ioc->name);
+		return -EFAULT;
+	}
+
 	if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
 	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
 		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+
 		    ioc->name, __FILE__, __LINE__, __func__);
-		return -1;
+		return -ENXIO;
 	}
 
 	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
@@ -153,7 +160,7 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
 		printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)"
 		    "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status,
 		     __FILE__, __LINE__, __func__);
-		return -1;
+		return -EIO;
 	}
 
 	memset(identify, 0, sizeof(identify));
@@ -288,21 +295,17 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
 	void *psge;
 	u32 sgl_flags;
 	u8 issue_reset = 0;
-	unsigned long flags;
 	void *data_out = NULL;
 	dma_addr_t data_out_dma;
 	u32 sz;
 	u64 *sas_address_le;
 	u16 wait_state_count;
 
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (ioc->ioc_reset_in_progress) {
-		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+	if (ioc->shost_recovery) {
 		printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
 		    __func__, ioc->name);
 		return -EFAULT;
 	}
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	mutex_lock(&ioc->transport_cmds.mutex);
 
@@ -789,7 +792,7 @@ mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
 }
 
 /**
- * mpt2sas_transport_update_phy_link_change - refreshing phy link changes and attached devices
+ * mpt2sas_transport_update_links - refreshing phy link changes
  * @ioc: per adapter object
  * @handle: handle to sas_host or expander
  * @attached_handle: attached device handle
@@ -799,13 +802,19 @@ mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy
  * Returns nothing.
  */
 void
-mpt2sas_transport_update_phy_link_change(struct MPT2SAS_ADAPTER *ioc,
+mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc,
     u16 handle, u16 attached_handle, u8 phy_number, u8 link_rate)
 {
 	unsigned long flags;
 	struct _sas_node *sas_node;
 	struct _sas_phy *mpt2sas_phy;
 
+	if (ioc->shost_recovery) {
+		printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
+			__func__, ioc->name);
+		return;
+	}
+
 	spin_lock_irqsave(&ioc->sas_node_lock, flags);
 	sas_node = _transport_sas_node_find_by_handle(ioc, handle);
 	spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -1025,7 +1034,6 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 	void *psge;
 	u32 sgl_flags;
 	u8 issue_reset = 0;
-	unsigned long flags;
 	dma_addr_t dma_addr_in = 0;
 	dma_addr_t dma_addr_out = 0;
 	u16 wait_state_count;
@@ -1045,14 +1053,11 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (ioc->ioc_reset_in_progress) {
-		spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+	if (ioc->shost_recovery) {
 		printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
 		    __func__, ioc->name);
 		return -EFAULT;
 	}
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 
 	rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex);
 	if (rc)
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 70b60ad..e32c344 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1713,7 +1713,7 @@ static int nsp_cs_config(struct pcmcia_device *link)
 
 	nsp_dbg(NSP_DEBUG_INIT, "in");
 
-	cfg_mem = kzalloc(sizeof(cfg_mem), GFP_KERNEL);
+	cfg_mem = kzalloc(sizeof(*cfg_mem), GFP_KERNEL);
 	if (!cfg_mem)
 		return -ENOMEM;
 	cfg_mem->data = data;
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
new file mode 100644
index 0000000..4302f06
--- /dev/null
+++ b/drivers/scsi/pmcraid.c
@@ -0,0 +1,5604 @@
+/*
+ * pmcraid.c -- driver for PMC Sierra MaxRAID controller adapters
+ *
+ * Written By: PMC Sierra Corporation
+ *
+ * Copyright (C) 2008, 2009 PMC Sierra 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 <linux/fs.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/blkdev.h>
+#include <linux/firmware.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/hdreg.h>
+#include <linux/version.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <linux/libata.h>
+#include <linux/mutex.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsicam.h>
+
+#include "pmcraid.h"
+
+/*
+ *   Module configuration parameters
+ */
+static unsigned int pmcraid_debug_log;
+static unsigned int pmcraid_disable_aen;
+static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST;
+
+/*
+ * Data structures to support multiple adapters by the LLD.
+ * pmcraid_adapter_count - count of configured adapters
+ */
+static atomic_t pmcraid_adapter_count = ATOMIC_INIT(0);
+
+/*
+ * Supporting user-level control interface through IOCTL commands.
+ * pmcraid_major - major number to use
+ * pmcraid_minor - minor number(s) to use
+ */
+static unsigned int pmcraid_major;
+static struct class *pmcraid_class;
+DECLARE_BITMAP(pmcraid_minor, PMCRAID_MAX_ADAPTERS);
+
+/*
+ * Module parameters
+ */
+MODULE_AUTHOR("PMC Sierra Corporation, anil_ravindranath@pmc-sierra.com");
+MODULE_DESCRIPTION("PMC Sierra MaxRAID Controller Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(PMCRAID_DRIVER_VERSION);
+
+module_param_named(log_level, pmcraid_log_level, uint, (S_IRUGO | S_IWUSR));
+MODULE_PARM_DESC(log_level,
+		 "Enables firmware error code logging, default :1 high-severity"
+		 " errors, 2: all errors including high-severity errors,"
+		 " 0: disables logging");
+
+module_param_named(debug, pmcraid_debug_log, uint, (S_IRUGO | S_IWUSR));
+MODULE_PARM_DESC(debug,
+		 "Enable driver verbose message logging. Set 1 to enable."
+		 "(default: 0)");
+
+module_param_named(disable_aen, pmcraid_disable_aen, uint, (S_IRUGO | S_IWUSR));
+MODULE_PARM_DESC(disable_aen,
+		 "Disable driver aen notifications to apps. Set 1 to disable."
+		 "(default: 0)");
+
+/* chip specific constants for PMC MaxRAID controllers (same for
+ * 0x5220 and 0x8010
+ */
+static struct pmcraid_chip_details pmcraid_chip_cfg[] = {
+	{
+	 .ioastatus = 0x0,
+	 .ioarrin = 0x00040,
+	 .mailbox = 0x7FC30,
+	 .global_intr_mask = 0x00034,
+	 .ioa_host_intr = 0x0009C,
+	 .ioa_host_intr_clr = 0x000A0,
+	 .ioa_host_mask = 0x7FC28,
+	 .ioa_host_mask_clr = 0x7FC28,
+	 .host_ioa_intr = 0x00020,
+	 .host_ioa_intr_clr = 0x00020,
+	 .transop_timeout = 300
+	 }
+};
+
+/*
+ * PCI device ids supported by pmcraid driver
+ */
+static struct pci_device_id pmcraid_pci_table[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_PMC, PCI_DEVICE_ID_PMC_MAXRAID),
+	  0, 0, (kernel_ulong_t)&pmcraid_chip_cfg[0]
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, pmcraid_pci_table);
+
+
+
+/**
+ * pmcraid_slave_alloc - Prepare for commands to a device
+ * @scsi_dev: scsi device struct
+ *
+ * This function is called by mid-layer prior to sending any command to the new
+ * device. Stores resource entry details of the device in scsi_device struct.
+ * Queuecommand uses the resource handle and other details to fill up IOARCB
+ * while sending commands to the device.
+ *
+ * Return value:
+ *	  0 on success / -ENXIO if device does not exist
+ */
+static int pmcraid_slave_alloc(struct scsi_device *scsi_dev)
+{
+	struct pmcraid_resource_entry *temp, *res = NULL;
+	struct pmcraid_instance *pinstance;
+	u8 target, bus, lun;
+	unsigned long lock_flags;
+	int rc = -ENXIO;
+	pinstance = shost_priv(scsi_dev->host);
+
+	/* Driver exposes VSET and GSCSI resources only; all other device types
+	 * are not exposed. Resource list is synchronized using resource lock
+	 * so any traversal or modifications to the list should be done inside
+	 * this lock
+	 */
+	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
+	list_for_each_entry(temp, &pinstance->used_res_q, queue) {
+
+		/* do not expose VSETs with order-ids >= 240 */
+		if (RES_IS_VSET(temp->cfg_entry)) {
+			target = temp->cfg_entry.unique_flags1;
+			if (target >= PMCRAID_MAX_VSET_TARGETS)
+				continue;
+			bus = PMCRAID_VSET_BUS_ID;
+			lun = 0;
+		} else if (RES_IS_GSCSI(temp->cfg_entry)) {
+			target = RES_TARGET(temp->cfg_entry.resource_address);
+			bus = PMCRAID_PHYS_BUS_ID;
+			lun = RES_LUN(temp->cfg_entry.resource_address);
+		} else {
+			continue;
+		}
+
+		if (bus == scsi_dev->channel &&
+		    target == scsi_dev->id &&
+		    lun == scsi_dev->lun) {
+			res = temp;
+			break;
+		}
+	}
+
+	if (res) {
+		res->scsi_dev = scsi_dev;
+		scsi_dev->hostdata = res;
+		res->change_detected = 0;
+		atomic_set(&res->read_failures, 0);
+		atomic_set(&res->write_failures, 0);
+		rc = 0;
+	}
+	spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
+	return rc;
+}
+
+/**
+ * pmcraid_slave_configure - Configures a SCSI device
+ * @scsi_dev: scsi device struct
+ *
+ * This fucntion is executed by SCSI mid layer just after a device is first
+ * scanned (i.e. it has responded to an INQUIRY). For VSET resources, the
+ * timeout value (default 30s) will be over-written to a higher value (60s)
+ * and max_sectors value will be over-written to 512. It also sets queue depth
+ * to host->cmd_per_lun value
+ *
+ * Return value:
+ *	  0 on success
+ */
+static int pmcraid_slave_configure(struct scsi_device *scsi_dev)
+{
+	struct pmcraid_resource_entry *res = scsi_dev->hostdata;
+
+	if (!res)
+		return 0;
+
+	/* LLD exposes VSETs and Enclosure devices only */
+	if (RES_IS_GSCSI(res->cfg_entry) &&
+	    scsi_dev->type != TYPE_ENCLOSURE)
+		return -ENXIO;
+
+	pmcraid_info("configuring %x:%x:%x:%x\n",
+		     scsi_dev->host->unique_id,
+		     scsi_dev->channel,
+		     scsi_dev->id,
+		     scsi_dev->lun);
+
+	if (RES_IS_GSCSI(res->cfg_entry)) {
+		scsi_dev->allow_restart = 1;
+	} else if (RES_IS_VSET(res->cfg_entry)) {
+		scsi_dev->allow_restart = 1;
+		blk_queue_rq_timeout(scsi_dev->request_queue,
+				     PMCRAID_VSET_IO_TIMEOUT);
+		blk_queue_max_sectors(scsi_dev->request_queue,
+				      PMCRAID_VSET_MAX_SECTORS);
+	}
+
+	if (scsi_dev->tagged_supported &&
+	    (RES_IS_GSCSI(res->cfg_entry) || RES_IS_VSET(res->cfg_entry))) {
+		scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth);
+		scsi_adjust_queue_depth(scsi_dev, MSG_SIMPLE_TAG,
+					scsi_dev->host->cmd_per_lun);
+	} else {
+		scsi_adjust_queue_depth(scsi_dev, 0,
+					scsi_dev->host->cmd_per_lun);
+	}
+
+	return 0;
+}
+
+/**
+ * pmcraid_slave_destroy - Unconfigure a SCSI device before removing it
+ *
+ * @scsi_dev: scsi device struct
+ *
+ * This is called by mid-layer before removing a device. Pointer assignments
+ * done in pmcraid_slave_alloc will be reset to NULL here.
+ *
+ * Return value
+ *   none
+ */
+static void pmcraid_slave_destroy(struct scsi_device *scsi_dev)
+{
+	struct pmcraid_resource_entry *res;
+
+	res = (struct pmcraid_resource_entry *)scsi_dev->hostdata;
+
+	if (res)
+		res->scsi_dev = NULL;
+
+	scsi_dev->hostdata = NULL;
+}
+
+/**
+ * pmcraid_change_queue_depth - Change the device's queue depth
+ * @scsi_dev: scsi device struct
+ * @depth: depth to set
+ *
+ * Return value
+ * 	actual depth set
+ */
+static int pmcraid_change_queue_depth(struct scsi_device *scsi_dev, int depth)
+{
+	if (depth > PMCRAID_MAX_CMD_PER_LUN)
+		depth = PMCRAID_MAX_CMD_PER_LUN;
+
+	scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev), depth);
+
+	return scsi_dev->queue_depth;
+}
+
+/**
+ * pmcraid_change_queue_type - Change the device's queue type
+ * @scsi_dev: scsi device struct
+ * @tag: type of tags to use
+ *
+ * Return value:
+ * 	actual queue type set
+ */
+static int pmcraid_change_queue_type(struct scsi_device *scsi_dev, int tag)
+{
+	struct pmcraid_resource_entry *res;
+
+	res = (struct pmcraid_resource_entry *)scsi_dev->hostdata;
+
+	if ((res) && scsi_dev->tagged_supported &&
+	    (RES_IS_GSCSI(res->cfg_entry) || RES_IS_VSET(res->cfg_entry))) {
+		scsi_set_tag_type(scsi_dev, tag);
+
+		if (tag)
+			scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth);
+		else
+			scsi_deactivate_tcq(scsi_dev, scsi_dev->queue_depth);
+	} else
+		tag = 0;
+
+	return tag;
+}
+
+
+/**
+ * pmcraid_init_cmdblk - initializes a command block
+ *
+ * @cmd: pointer to struct pmcraid_cmd to be initialized
+ * @index: if >=0 first time initialization; otherwise reinitialization
+ *
+ * Return Value
+ *	 None
+ */
+void pmcraid_init_cmdblk(struct pmcraid_cmd *cmd, int index)
+{
+	struct pmcraid_ioarcb *ioarcb = &(cmd->ioa_cb->ioarcb);
+	dma_addr_t dma_addr = cmd->ioa_cb_bus_addr;
+
+	if (index >= 0) {
+		/* first time initialization (called from  probe) */
+		u32 ioasa_offset =
+			offsetof(struct pmcraid_control_block, ioasa);
+
+		cmd->index = index;
+		ioarcb->response_handle = cpu_to_le32(index << 2);
+		ioarcb->ioarcb_bus_addr = cpu_to_le64(dma_addr);
+		ioarcb->ioasa_bus_addr = cpu_to_le64(dma_addr + ioasa_offset);
+		ioarcb->ioasa_len = cpu_to_le16(sizeof(struct pmcraid_ioasa));
+	} else {
+		/* re-initialization of various lengths, called once command is
+		 * processed by IOA
+		 */
+		memset(&cmd->ioa_cb->ioarcb.cdb, 0, PMCRAID_MAX_CDB_LEN);
+		ioarcb->request_flags0 = 0;
+		ioarcb->request_flags1 = 0;
+		ioarcb->cmd_timeout = 0;
+		ioarcb->ioarcb_bus_addr &= (~0x1FULL);
+		ioarcb->ioadl_bus_addr = 0;
+		ioarcb->ioadl_length = 0;
+		ioarcb->data_transfer_length = 0;
+		ioarcb->add_cmd_param_length = 0;
+		ioarcb->add_cmd_param_offset = 0;
+		cmd->ioa_cb->ioasa.ioasc = 0;
+		cmd->ioa_cb->ioasa.residual_data_length = 0;
+		cmd->u.time_left = 0;
+	}
+
+	cmd->cmd_done = NULL;
+	cmd->scsi_cmd = NULL;
+	cmd->release = 0;
+	cmd->completion_req = 0;
+	cmd->dma_handle = 0;
+	init_timer(&cmd->timer);
+}
+
+/**
+ * pmcraid_reinit_cmdblk - reinitialize a command block
+ *
+ * @cmd: pointer to struct pmcraid_cmd to be reinitialized
+ *
+ * Return Value
+ *	 None
+ */
+static void pmcraid_reinit_cmdblk(struct pmcraid_cmd *cmd)
+{
+	pmcraid_init_cmdblk(cmd, -1);
+}
+
+/**
+ * pmcraid_get_free_cmd - get a free cmd block from command block pool
+ * @pinstance: adapter instance structure
+ *
+ * Return Value:
+ *	returns pointer to cmd block or NULL if no blocks are available
+ */
+static struct pmcraid_cmd *pmcraid_get_free_cmd(
+	struct pmcraid_instance *pinstance
+)
+{
+	struct pmcraid_cmd *cmd = NULL;
+	unsigned long lock_flags;
+
+	/* free cmd block list is protected by free_pool_lock */
+	spin_lock_irqsave(&pinstance->free_pool_lock, lock_flags);
+
+	if (!list_empty(&pinstance->free_cmd_pool)) {
+		cmd = list_entry(pinstance->free_cmd_pool.next,
+				 struct pmcraid_cmd, free_list);
+		list_del(&cmd->free_list);
+	}
+	spin_unlock_irqrestore(&pinstance->free_pool_lock, lock_flags);
+
+	/* Initialize the command block before giving it the caller */
+	if (cmd != NULL)
+		pmcraid_reinit_cmdblk(cmd);
+	return cmd;
+}
+
+/**
+ * pmcraid_return_cmd - return a completed command block back into free pool
+ * @cmd: pointer to the command block
+ *
+ * Return Value:
+ *	nothing
+ */
+void pmcraid_return_cmd(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	unsigned long lock_flags;
+
+	spin_lock_irqsave(&pinstance->free_pool_lock, lock_flags);
+	list_add_tail(&cmd->free_list, &pinstance->free_cmd_pool);
+	spin_unlock_irqrestore(&pinstance->free_pool_lock, lock_flags);
+}
+
+/**
+ * pmcraid_read_interrupts -  reads IOA interrupts
+ *
+ * @pinstance: pointer to adapter instance structure
+ *
+ * Return value
+ *	 interrupts read from IOA
+ */
+static u32 pmcraid_read_interrupts(struct pmcraid_instance *pinstance)
+{
+	return ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
+}
+
+/**
+ * pmcraid_disable_interrupts - Masks and clears all specified interrupts
+ *
+ * @pinstance: pointer to per adapter instance structure
+ * @intrs: interrupts to disable
+ *
+ * Return Value
+ *	 None
+ */
+static void pmcraid_disable_interrupts(
+	struct pmcraid_instance *pinstance,
+	u32 intrs
+)
+{
+	u32 gmask = ioread32(pinstance->int_regs.global_interrupt_mask_reg);
+	u32 nmask = gmask | GLOBAL_INTERRUPT_MASK;
+
+	iowrite32(nmask, pinstance->int_regs.global_interrupt_mask_reg);
+	iowrite32(intrs, pinstance->int_regs.ioa_host_interrupt_clr_reg);
+	iowrite32(intrs, pinstance->int_regs.ioa_host_interrupt_mask_reg);
+	ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg);
+}
+
+/**
+ * pmcraid_enable_interrupts - Enables specified interrupts
+ *
+ * @pinstance: pointer to per adapter instance structure
+ * @intr: interrupts to enable
+ *
+ * Return Value
+ *	 None
+ */
+static void pmcraid_enable_interrupts(
+	struct pmcraid_instance *pinstance,
+	u32 intrs
+)
+{
+	u32 gmask = ioread32(pinstance->int_regs.global_interrupt_mask_reg);
+	u32 nmask = gmask & (~GLOBAL_INTERRUPT_MASK);
+
+	iowrite32(nmask, pinstance->int_regs.global_interrupt_mask_reg);
+	iowrite32(~intrs, pinstance->int_regs.ioa_host_interrupt_mask_reg);
+	ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg);
+
+	pmcraid_info("enabled interrupts global mask = %x intr_mask = %x\n",
+		ioread32(pinstance->int_regs.global_interrupt_mask_reg),
+		ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg));
+}
+
+/**
+ * pmcraid_reset_type - Determine the required reset type
+ * @pinstance: pointer to adapter instance structure
+ *
+ * IOA requires hard reset if any of the following conditions is true.
+ * 1. If HRRQ valid interrupt is not masked
+ * 2. IOA reset alert doorbell is set
+ * 3. If there are any error interrupts
+ */
+static void pmcraid_reset_type(struct pmcraid_instance *pinstance)
+{
+	u32 mask;
+	u32 intrs;
+	u32 alerts;
+
+	mask = ioread32(pinstance->int_regs.ioa_host_interrupt_mask_reg);
+	intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
+	alerts = ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
+
+	if ((mask & INTRS_HRRQ_VALID) == 0 ||
+	    (alerts & DOORBELL_IOA_RESET_ALERT) ||
+	    (intrs & PMCRAID_ERROR_INTERRUPTS)) {
+		pmcraid_info("IOA requires hard reset\n");
+		pinstance->ioa_hard_reset = 1;
+	}
+
+	/* If unit check is active, trigger the dump */
+	if (intrs & INTRS_IOA_UNIT_CHECK)
+		pinstance->ioa_unit_check = 1;
+}
+
+/**
+ * pmcraid_bist_done - completion function for PCI BIST
+ * @cmd: pointer to reset command
+ * Return Value
+ * 	none
+ */
+
+static void pmcraid_ioa_reset(struct pmcraid_cmd *);
+
+static void pmcraid_bist_done(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	unsigned long lock_flags;
+	int rc;
+	u16 pci_reg;
+
+	rc = pci_read_config_word(pinstance->pdev, PCI_COMMAND, &pci_reg);
+
+	/* If PCI config space can't be accessed wait for another two secs */
+	if ((rc != PCIBIOS_SUCCESSFUL || (!(pci_reg & PCI_COMMAND_MEMORY))) &&
+	    cmd->u.time_left > 0) {
+		pmcraid_info("BIST not complete, waiting another 2 secs\n");
+		cmd->timer.expires = jiffies + cmd->u.time_left;
+		cmd->u.time_left = 0;
+		cmd->timer.data = (unsigned long)cmd;
+		cmd->timer.function =
+			(void (*)(unsigned long))pmcraid_bist_done;
+		add_timer(&cmd->timer);
+	} else {
+		cmd->u.time_left = 0;
+		pmcraid_info("BIST is complete, proceeding with reset\n");
+		spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+		pmcraid_ioa_reset(cmd);
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+	}
+}
+
+/**
+ * pmcraid_start_bist - starts BIST
+ * @cmd: pointer to reset cmd
+ * Return Value
+ *   none
+ */
+static void pmcraid_start_bist(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	u32 doorbells, intrs;
+
+	/* proceed with bist and wait for 2 seconds */
+	iowrite32(DOORBELL_IOA_START_BIST,
+		pinstance->int_regs.host_ioa_interrupt_reg);
+	doorbells = ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
+	intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
+	pmcraid_info("doorbells after start bist: %x intrs: %x \n",
+		      doorbells, intrs);
+
+	cmd->u.time_left = msecs_to_jiffies(PMCRAID_BIST_TIMEOUT);
+	cmd->timer.data = (unsigned long)cmd;
+	cmd->timer.expires = jiffies + msecs_to_jiffies(PMCRAID_BIST_TIMEOUT);
+	cmd->timer.function = (void (*)(unsigned long))pmcraid_bist_done;
+	add_timer(&cmd->timer);
+}
+
+/**
+ * pmcraid_reset_alert_done - completion routine for reset_alert
+ * @cmd: pointer to command block used in reset sequence
+ * Return value
+ *  None
+ */
+static void pmcraid_reset_alert_done(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	u32 status = ioread32(pinstance->ioa_status);
+	unsigned long lock_flags;
+
+	/* if the critical operation in progress bit is set or the wait times
+	 * out, invoke reset engine to proceed with hard reset. If there is
+	 * some more time to wait, restart the timer
+	 */
+	if (((status & INTRS_CRITICAL_OP_IN_PROGRESS) == 0) ||
+	    cmd->u.time_left <= 0) {
+		pmcraid_info("critical op is reset proceeding with reset\n");
+		spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+		pmcraid_ioa_reset(cmd);
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+	} else {
+		pmcraid_info("critical op is not yet reset waiting again\n");
+		/* restart timer if some more time is available to wait */
+		cmd->u.time_left -= PMCRAID_CHECK_FOR_RESET_TIMEOUT;
+		cmd->timer.data = (unsigned long)cmd;
+		cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT;
+		cmd->timer.function =
+			(void (*)(unsigned long))pmcraid_reset_alert_done;
+		add_timer(&cmd->timer);
+	}
+}
+
+/**
+ * pmcraid_reset_alert - alerts IOA for a possible reset
+ * @cmd : command block to be used for reset sequence.
+ *
+ * Return Value
+ *	returns 0 if pci config-space is accessible and RESET_DOORBELL is
+ *	successfully written to IOA. Returns non-zero in case pci_config_space
+ *	is not accessible
+ */
+static void pmcraid_reset_alert(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	u32 doorbells;
+	int rc;
+	u16 pci_reg;
+
+	/* If we are able to access IOA PCI config space, alert IOA that we are
+	 * going to reset it soon. This enables IOA to preserv persistent error
+	 * data if any. In case memory space is not accessible, proceed with
+	 * BIST or slot_reset
+	 */
+	rc = pci_read_config_word(pinstance->pdev, PCI_COMMAND, &pci_reg);
+	if ((rc == PCIBIOS_SUCCESSFUL) && (pci_reg & PCI_COMMAND_MEMORY)) {
+
+		/* wait for IOA permission i.e until CRITICAL_OPERATION bit is
+		 * reset IOA doesn't generate any interrupts when CRITICAL
+		 * OPERATION bit is reset. A timer is started to wait for this
+		 * bit to be reset.
+		 */
+		cmd->u.time_left = PMCRAID_RESET_TIMEOUT;
+		cmd->timer.data = (unsigned long)cmd;
+		cmd->timer.expires = jiffies + PMCRAID_CHECK_FOR_RESET_TIMEOUT;
+		cmd->timer.function =
+			(void (*)(unsigned long))pmcraid_reset_alert_done;
+		add_timer(&cmd->timer);
+
+		iowrite32(DOORBELL_IOA_RESET_ALERT,
+			pinstance->int_regs.host_ioa_interrupt_reg);
+		doorbells =
+			ioread32(pinstance->int_regs.host_ioa_interrupt_reg);
+		pmcraid_info("doorbells after reset alert: %x\n", doorbells);
+	} else {
+		pmcraid_info("PCI config is not accessible starting BIST\n");
+		pinstance->ioa_state = IOA_STATE_IN_HARD_RESET;
+		pmcraid_start_bist(cmd);
+	}
+}
+
+/**
+ * pmcraid_timeout_handler -  Timeout handler for internally generated ops
+ *
+ * @cmd : pointer to command structure, that got timedout
+ *
+ * This function blocks host requests and initiates an adapter reset.
+ *
+ * Return value:
+ *   None
+ */
+static void pmcraid_timeout_handler(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	unsigned long lock_flags;
+
+	dev_err(&pinstance->pdev->dev,
+		"Adapter being reset due to command timeout.\n");
+
+	/* Command timeouts result in hard reset sequence. The command that got
+	 * timed out may be the one used as part of reset sequence. In this
+	 * case restart reset sequence using the same command block even if
+	 * reset is in progress. Otherwise fail this command and get a free
+	 * command block to restart the reset sequence.
+	 */
+	spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+	if (!pinstance->ioa_reset_in_progress) {
+		pinstance->ioa_reset_attempts = 0;
+		cmd = pmcraid_get_free_cmd(pinstance);
+
+		/* If we are out of command blocks, just return here itself.
+		 * Some other command's timeout handler can do the reset job
+		 */
+		if (cmd == NULL) {
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       lock_flags);
+			pmcraid_err("no free cmnd block for timeout handler\n");
+			return;
+		}
+
+		pinstance->reset_cmd = cmd;
+		pinstance->ioa_reset_in_progress = 1;
+	} else {
+		pmcraid_info("reset is already in progress\n");
+
+		if (pinstance->reset_cmd != cmd) {
+			/* This command should have been given to IOA, this
+			 * command will be completed by fail_outstanding_cmds
+			 * anyway
+			 */
+			pmcraid_err("cmd is pending but reset in progress\n");
+		}
+
+		/* If this command was being used as part of the reset
+		 * sequence, set cmd_done pointer to pmcraid_ioa_reset. This
+		 * causes fail_outstanding_commands not to return the command
+		 * block back to free pool
+		 */
+		if (cmd == pinstance->reset_cmd)
+			cmd->cmd_done = pmcraid_ioa_reset;
+
+	}
+
+	pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
+	scsi_block_requests(pinstance->host);
+	pmcraid_reset_alert(cmd);
+	spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+}
+
+/**
+ * pmcraid_internal_done - completion routine for internally generated cmds
+ *
+ * @cmd: command that got response from IOA
+ *
+ * Return Value:
+ *	 none
+ */
+static void pmcraid_internal_done(struct pmcraid_cmd *cmd)
+{
+	pmcraid_info("response internal cmd CDB[0] = %x ioasc = %x\n",
+		     cmd->ioa_cb->ioarcb.cdb[0],
+		     le32_to_cpu(cmd->ioa_cb->ioasa.ioasc));
+
+	/* Some of the internal commands are sent with callers blocking for the
+	 * response. Same will be indicated as part of cmd->completion_req
+	 * field. Response path needs to wake up any waiters waiting for cmd
+	 * completion if this flag is set.
+	 */
+	if (cmd->completion_req) {
+		cmd->completion_req = 0;
+		complete(&cmd->wait_for_completion);
+	}
+
+	/* most of the internal commands are completed by caller itself, so
+	 * no need to return the command block back to free pool until we are
+	 * required to do so (e.g once done with initialization).
+	 */
+	if (cmd->release) {
+		cmd->release = 0;
+		pmcraid_return_cmd(cmd);
+	}
+}
+
+/**
+ * pmcraid_reinit_cfgtable_done - done function for cfg table reinitialization
+ *
+ * @cmd: command that got response from IOA
+ *
+ * This routine is called after driver re-reads configuration table due to a
+ * lost CCN. It returns the command block back to free pool and schedules
+ * worker thread to add/delete devices into the system.
+ *
+ * Return Value:
+ *	 none
+ */
+static void pmcraid_reinit_cfgtable_done(struct pmcraid_cmd *cmd)
+{
+	pmcraid_info("response internal cmd CDB[0] = %x ioasc = %x\n",
+		     cmd->ioa_cb->ioarcb.cdb[0],
+		     le32_to_cpu(cmd->ioa_cb->ioasa.ioasc));
+
+	if (cmd->release) {
+		cmd->release = 0;
+		pmcraid_return_cmd(cmd);
+	}
+	pmcraid_info("scheduling worker for config table reinitialization\n");
+	schedule_work(&cmd->drv_inst->worker_q);
+}
+
+/**
+ * pmcraid_erp_done - Process completion of SCSI error response from device
+ * @cmd: pmcraid_command
+ *
+ * This function copies the sense buffer into the scsi_cmd struct and completes
+ * scsi_cmd by calling scsi_done function.
+ *
+ * Return value:
+ *  none
+ */
+static void pmcraid_erp_done(struct pmcraid_cmd *cmd)
+{
+	struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	u32 ioasc = le32_to_cpu(cmd->ioa_cb->ioasa.ioasc);
+
+	if (PMCRAID_IOASC_SENSE_KEY(ioasc) > 0) {
+		scsi_cmd->result |= (DID_ERROR << 16);
+		pmcraid_err("command CDB[0] = %x failed with IOASC: 0x%08X\n",
+			     cmd->ioa_cb->ioarcb.cdb[0], ioasc);
+	}
+
+	/* if we had allocated sense buffers for request sense, copy the sense
+	 * release the buffers
+	 */
+	if (cmd->sense_buffer != NULL) {
+		memcpy(scsi_cmd->sense_buffer,
+		       cmd->sense_buffer,
+		       SCSI_SENSE_BUFFERSIZE);
+		pci_free_consistent(pinstance->pdev,
+				    SCSI_SENSE_BUFFERSIZE,
+				    cmd->sense_buffer, cmd->sense_buffer_dma);
+		cmd->sense_buffer = NULL;
+		cmd->sense_buffer_dma = 0;
+	}
+
+	scsi_dma_unmap(scsi_cmd);
+	pmcraid_return_cmd(cmd);
+	scsi_cmd->scsi_done(scsi_cmd);
+}
+
+/**
+ * pmcraid_fire_command - sends an IOA command to adapter
+ *
+ * This function adds the given block into pending command list
+ * and returns without waiting
+ *
+ * @cmd : command to be sent to the device
+ *
+ * Return Value
+ *	None
+ */
+static void _pmcraid_fire_command(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	unsigned long lock_flags;
+
+	/* Add this command block to pending cmd pool. We do this prior to
+	 * writting IOARCB to ioarrin because IOA might complete the command
+	 * by the time we are about to add it to the list. Response handler
+	 * (isr/tasklet) looks for cmb block in the pending pending list.
+	 */
+	spin_lock_irqsave(&pinstance->pending_pool_lock, lock_flags);
+	list_add_tail(&cmd->free_list, &pinstance->pending_cmd_pool);
+	spin_unlock_irqrestore(&pinstance->pending_pool_lock, lock_flags);
+	atomic_inc(&pinstance->outstanding_cmds);
+
+	/* driver writes lower 32-bit value of IOARCB address only */
+	mb();
+	iowrite32(le32_to_cpu(cmd->ioa_cb->ioarcb.ioarcb_bus_addr),
+		  pinstance->ioarrin);
+}
+
+/**
+ * pmcraid_send_cmd - fires a command to IOA
+ *
+ * This function also sets up timeout function, and command completion
+ * function
+ *
+ * @cmd: pointer to the command block to be fired to IOA
+ * @cmd_done: command completion function, called once IOA responds
+ * @timeout: timeout to wait for this command completion
+ * @timeout_func: timeout handler
+ *
+ * Return value
+ *   none
+ */
+static void pmcraid_send_cmd(
+	struct pmcraid_cmd *cmd,
+	void (*cmd_done) (struct pmcraid_cmd *),
+	unsigned long timeout,
+	void (*timeout_func) (struct pmcraid_cmd *)
+)
+{
+	/* initialize done function */
+	cmd->cmd_done = cmd_done;
+
+	if (timeout_func) {
+		/* setup timeout handler */
+		cmd->timer.data = (unsigned long)cmd;
+		cmd->timer.expires = jiffies + timeout;
+		cmd->timer.function = (void (*)(unsigned long))timeout_func;
+		add_timer(&cmd->timer);
+	}
+
+	/* fire the command to IOA */
+	_pmcraid_fire_command(cmd);
+}
+
+/**
+ * pmcraid_ioa_shutdown - sends SHUTDOWN command to ioa
+ *
+ * @cmd: pointer to the command block used as part of reset sequence
+ *
+ * Return Value
+ *  None
+ */
+static void pmcraid_ioa_shutdown(struct pmcraid_cmd *cmd)
+{
+	pmcraid_info("response for Cancel CCN CDB[0] = %x ioasc = %x\n",
+		     cmd->ioa_cb->ioarcb.cdb[0],
+		     le32_to_cpu(cmd->ioa_cb->ioasa.ioasc));
+
+	/* Note that commands sent during reset require next command to be sent
+	 * to IOA. Hence reinit the done function as well as timeout function
+	 */
+	pmcraid_reinit_cmdblk(cmd);
+	cmd->ioa_cb->ioarcb.request_type = REQ_TYPE_IOACMD;
+	cmd->ioa_cb->ioarcb.resource_handle =
+		cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
+	cmd->ioa_cb->ioarcb.cdb[0] = PMCRAID_IOA_SHUTDOWN;
+	cmd->ioa_cb->ioarcb.cdb[1] = PMCRAID_SHUTDOWN_NORMAL;
+
+	/* fire shutdown command to hardware. */
+	pmcraid_info("firing normal shutdown command (%d) to IOA\n",
+		     le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle));
+
+	pmcraid_send_cmd(cmd, pmcraid_ioa_reset,
+			 PMCRAID_SHUTDOWN_TIMEOUT,
+			 pmcraid_timeout_handler);
+}
+
+/**
+ * pmcraid_identify_hrrq - registers host rrq buffers with IOA
+ * @cmd: pointer to command block to be used for identify hrrq
+ *
+ * Return Value
+ *	 0 in case of success, otherwise non-zero failure code
+ */
+
+static void pmcraid_querycfg(struct pmcraid_cmd *);
+
+static void pmcraid_identify_hrrq(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	int index = 0;
+	__be64 hrrq_addr = cpu_to_be64(pinstance->hrrq_start_bus_addr[index]);
+	u32 hrrq_size = cpu_to_be32(sizeof(u32) * PMCRAID_MAX_CMD);
+
+	pmcraid_reinit_cmdblk(cmd);
+
+	/* Initialize ioarcb */
+	ioarcb->request_type = REQ_TYPE_IOACMD;
+	ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
+
+	/* initialize the hrrq number where IOA will respond to this command */
+	ioarcb->hrrq_id = index;
+	ioarcb->cdb[0] = PMCRAID_IDENTIFY_HRRQ;
+	ioarcb->cdb[1] = index;
+
+	/* IOA expects 64-bit pci address to be written in B.E format
+	 * (i.e cdb[2]=MSByte..cdb[9]=LSB.
+	 */
+	pmcraid_info("HRRQ_IDENTIFY with hrrq:ioarcb => %llx:%llx\n",
+		     hrrq_addr, ioarcb->ioarcb_bus_addr);
+
+	memcpy(&(ioarcb->cdb[2]), &hrrq_addr, sizeof(hrrq_addr));
+	memcpy(&(ioarcb->cdb[10]), &hrrq_size, sizeof(hrrq_size));
+
+	/* Subsequent commands require HRRQ identification to be successful.
+	 * Note that this gets called even during reset from SCSI mid-layer
+	 * or tasklet
+	 */
+	pmcraid_send_cmd(cmd, pmcraid_querycfg,
+			 PMCRAID_INTERNAL_TIMEOUT,
+			 pmcraid_timeout_handler);
+}
+
+static void pmcraid_process_ccn(struct pmcraid_cmd *cmd);
+static void pmcraid_process_ldn(struct pmcraid_cmd *cmd);
+
+/**
+ * pmcraid_send_hcam_cmd - send an initialized command block(HCAM) to IOA
+ *
+ * @cmd: initialized command block pointer
+ *
+ * Return Value
+ *   none
+ */
+static void pmcraid_send_hcam_cmd(struct pmcraid_cmd *cmd)
+{
+	if (cmd->ioa_cb->ioarcb.cdb[1] == PMCRAID_HCAM_CODE_CONFIG_CHANGE)
+		atomic_set(&(cmd->drv_inst->ccn.ignore), 0);
+	else
+		atomic_set(&(cmd->drv_inst->ldn.ignore), 0);
+
+	pmcraid_send_cmd(cmd, cmd->cmd_done, 0, NULL);
+}
+
+/**
+ * pmcraid_init_hcam - send an initialized command block(HCAM) to IOA
+ *
+ * @pinstance: pointer to adapter instance structure
+ * @type: HCAM type
+ *
+ * Return Value
+ *   pointer to initialized pmcraid_cmd structure or NULL
+ */
+static struct pmcraid_cmd *pmcraid_init_hcam
+(
+	struct pmcraid_instance *pinstance,
+	u8 type
+)
+{
+	struct pmcraid_cmd *cmd;
+	struct pmcraid_ioarcb *ioarcb;
+	struct pmcraid_ioadl_desc *ioadl;
+	struct pmcraid_hostrcb *hcam;
+	void (*cmd_done) (struct pmcraid_cmd *);
+	dma_addr_t dma;
+	int rcb_size;
+
+	cmd = pmcraid_get_free_cmd(pinstance);
+
+	if (!cmd) {
+		pmcraid_err("no free command blocks for hcam\n");
+		return cmd;
+	}
+
+	if (type == PMCRAID_HCAM_CODE_CONFIG_CHANGE) {
+		rcb_size = sizeof(struct pmcraid_hcam_ccn);
+		cmd_done = pmcraid_process_ccn;
+		dma = pinstance->ccn.baddr + PMCRAID_AEN_HDR_SIZE;
+		hcam = &pinstance->ccn;
+	} else {
+		rcb_size = sizeof(struct pmcraid_hcam_ldn);
+		cmd_done = pmcraid_process_ldn;
+		dma = pinstance->ldn.baddr + PMCRAID_AEN_HDR_SIZE;
+		hcam = &pinstance->ldn;
+	}
+
+	/* initialize command pointer used for HCAM registration */
+	hcam->cmd = cmd;
+
+	ioarcb = &cmd->ioa_cb->ioarcb;
+	ioarcb->ioadl_bus_addr = cpu_to_le64((cmd->ioa_cb_bus_addr) +
+					offsetof(struct pmcraid_ioarcb,
+						add_data.u.ioadl[0]));
+	ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
+	ioadl = ioarcb->add_data.u.ioadl;
+
+	/* Initialize ioarcb */
+	ioarcb->request_type = REQ_TYPE_HCAM;
+	ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
+	ioarcb->cdb[0] = PMCRAID_HOST_CONTROLLED_ASYNC;
+	ioarcb->cdb[1] = type;
+	ioarcb->cdb[7] = (rcb_size >> 8) & 0xFF;
+	ioarcb->cdb[8] = (rcb_size) & 0xFF;
+
+	ioarcb->data_transfer_length = cpu_to_le32(rcb_size);
+
+	ioadl[0].flags |= cpu_to_le32(IOADL_FLAGS_READ_LAST);
+	ioadl[0].data_len = cpu_to_le32(rcb_size);
+	ioadl[0].address = cpu_to_le32(dma);
+
+	cmd->cmd_done = cmd_done;
+	return cmd;
+}
+
+/**
+ * pmcraid_send_hcam - Send an HCAM to IOA
+ * @pinstance: ioa config struct
+ * @type: HCAM type
+ *
+ * This function will send a Host Controlled Async command to IOA.
+ *
+ * Return value:
+ * 	none
+ */
+static void pmcraid_send_hcam(struct pmcraid_instance *pinstance, u8 type)
+{
+	struct pmcraid_cmd *cmd = pmcraid_init_hcam(pinstance, type);
+	pmcraid_send_hcam_cmd(cmd);
+}
+
+
+/**
+ * pmcraid_prepare_cancel_cmd - prepares a command block to abort another
+ *
+ * @cmd: pointer to cmd that is used as cancelling command
+ * @cmd_to_cancel: pointer to the command that needs to be cancelled
+ */
+static void pmcraid_prepare_cancel_cmd(
+	struct pmcraid_cmd *cmd,
+	struct pmcraid_cmd *cmd_to_cancel
+)
+{
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	__be64 ioarcb_addr = cmd_to_cancel->ioa_cb->ioarcb.ioarcb_bus_addr;
+
+	/* Get the resource handle to where the command to be aborted has been
+	 * sent.
+	 */
+	ioarcb->resource_handle = cmd_to_cancel->ioa_cb->ioarcb.resource_handle;
+	ioarcb->request_type = REQ_TYPE_IOACMD;
+	memset(ioarcb->cdb, 0, PMCRAID_MAX_CDB_LEN);
+	ioarcb->cdb[0] = PMCRAID_ABORT_CMD;
+
+	/* IOARCB address of the command to be cancelled is given in
+	 * cdb[2]..cdb[9] is Big-Endian format. Note that length bits in
+	 * IOARCB address are not masked.
+	 */
+	ioarcb_addr = cpu_to_be64(ioarcb_addr);
+	memcpy(&(ioarcb->cdb[2]), &ioarcb_addr, sizeof(ioarcb_addr));
+}
+
+/**
+ * pmcraid_cancel_hcam - sends ABORT task to abort a given HCAM
+ *
+ * @cmd: command to be used as cancelling command
+ * @type: HCAM type
+ * @cmd_done: op done function for the cancelling command
+ */
+static void pmcraid_cancel_hcam(
+	struct pmcraid_cmd *cmd,
+	u8 type,
+	void (*cmd_done) (struct pmcraid_cmd *)
+)
+{
+	struct pmcraid_instance *pinstance;
+	struct pmcraid_hostrcb  *hcam;
+
+	pinstance = cmd->drv_inst;
+	hcam =  (type == PMCRAID_HCAM_CODE_LOG_DATA) ?
+		&pinstance->ldn : &pinstance->ccn;
+
+	/* prepare for cancelling previous hcam command. If the HCAM is
+	 * currently not pending with IOA, we would have hcam->cmd as non-null
+	 */
+	if (hcam->cmd == NULL)
+		return;
+
+	pmcraid_prepare_cancel_cmd(cmd, hcam->cmd);
+
+	/* writing to IOARRIN must be protected by host_lock, as mid-layer
+	 * schedule queuecommand while we are doing this
+	 */
+	pmcraid_send_cmd(cmd, cmd_done,
+			 PMCRAID_INTERNAL_TIMEOUT,
+			 pmcraid_timeout_handler);
+}
+
+/**
+ * pmcraid_cancel_ccn - cancel CCN HCAM already registered with IOA
+ *
+ * @cmd: command block to be used for cancelling the HCAM
+ */
+static void pmcraid_cancel_ccn(struct pmcraid_cmd *cmd)
+{
+	pmcraid_info("response for Cancel LDN CDB[0] = %x ioasc = %x\n",
+		     cmd->ioa_cb->ioarcb.cdb[0],
+		     le32_to_cpu(cmd->ioa_cb->ioasa.ioasc));
+
+	pmcraid_reinit_cmdblk(cmd);
+
+	pmcraid_cancel_hcam(cmd,
+			    PMCRAID_HCAM_CODE_CONFIG_CHANGE,
+			    pmcraid_ioa_shutdown);
+}
+
+/**
+ * pmcraid_cancel_ldn - cancel LDN HCAM already registered with IOA
+ *
+ * @cmd: command block to be used for cancelling the HCAM
+ */
+static void pmcraid_cancel_ldn(struct pmcraid_cmd *cmd)
+{
+	pmcraid_cancel_hcam(cmd,
+			    PMCRAID_HCAM_CODE_LOG_DATA,
+			    pmcraid_cancel_ccn);
+}
+
+/**
+ * pmcraid_expose_resource - check if the resource can be exposed to OS
+ *
+ * @cfgte: pointer to configuration table entry of the resource
+ *
+ * Return value:
+ * 	true if resource can be added to midlayer, false(0) otherwise
+ */
+static int pmcraid_expose_resource(struct pmcraid_config_table_entry *cfgte)
+{
+	int retval = 0;
+
+	if (cfgte->resource_type == RES_TYPE_VSET)
+		retval = ((cfgte->unique_flags1 & 0xFF) < 0xFE);
+	else if (cfgte->resource_type == RES_TYPE_GSCSI)
+		retval = (RES_BUS(cfgte->resource_address) !=
+				PMCRAID_VIRTUAL_ENCL_BUS_ID);
+	return retval;
+}
+
+/* attributes supported by pmcraid_event_family */
+enum {
+	PMCRAID_AEN_ATTR_UNSPEC,
+	PMCRAID_AEN_ATTR_EVENT,
+	__PMCRAID_AEN_ATTR_MAX,
+};
+#define PMCRAID_AEN_ATTR_MAX (__PMCRAID_AEN_ATTR_MAX - 1)
+
+/* commands supported by pmcraid_event_family */
+enum {
+	PMCRAID_AEN_CMD_UNSPEC,
+	PMCRAID_AEN_CMD_EVENT,
+	__PMCRAID_AEN_CMD_MAX,
+};
+#define PMCRAID_AEN_CMD_MAX (__PMCRAID_AEN_CMD_MAX - 1)
+
+static struct genl_family pmcraid_event_family = {
+	.id = GENL_ID_GENERATE,
+	.name = "pmcraid",
+	.version = 1,
+	.maxattr = PMCRAID_AEN_ATTR_MAX
+};
+
+/**
+ * pmcraid_netlink_init - registers pmcraid_event_family
+ *
+ * Return value:
+ * 	0 if the pmcraid_event_family is successfully registered
+ * 	with netlink generic, non-zero otherwise
+ */
+static int pmcraid_netlink_init(void)
+{
+	int result;
+
+	result = genl_register_family(&pmcraid_event_family);
+
+	if (result)
+		return result;
+
+	pmcraid_info("registered NETLINK GENERIC group: %d\n",
+		     pmcraid_event_family.id);
+
+	return result;
+}
+
+/**
+ * pmcraid_netlink_release - unregisters pmcraid_event_family
+ *
+ * Return value:
+ * 	none
+ */
+static void pmcraid_netlink_release(void)
+{
+	genl_unregister_family(&pmcraid_event_family);
+}
+
+/**
+ * pmcraid_notify_aen - sends event msg to user space application
+ * @pinstance: pointer to adapter instance structure
+ * @type: HCAM type
+ *
+ * Return value:
+ *	0 if success, error value in case of any failure.
+ */
+static int pmcraid_notify_aen(struct pmcraid_instance *pinstance, u8 type)
+{
+	struct sk_buff *skb;
+	struct pmcraid_aen_msg *aen_msg;
+	void *msg_header;
+	int data_size, total_size;
+	int result;
+
+
+	if (type == PMCRAID_HCAM_CODE_LOG_DATA) {
+		aen_msg = pinstance->ldn.msg;
+		data_size = pinstance->ldn.hcam->data_len;
+	} else {
+		aen_msg = pinstance->ccn.msg;
+		data_size = pinstance->ccn.hcam->data_len;
+	}
+
+	data_size += sizeof(struct pmcraid_hcam_hdr);
+	aen_msg->hostno = (pinstance->host->unique_id << 16 |
+			   MINOR(pinstance->cdev.dev));
+	aen_msg->length = data_size;
+	data_size += sizeof(*aen_msg);
+
+	total_size = nla_total_size(data_size);
+	skb = genlmsg_new(total_size, GFP_ATOMIC);
+
+
+	if (!skb) {
+		pmcraid_err("Failed to allocate aen data SKB of size: %x\n",
+			     total_size);
+		return -ENOMEM;
+	}
+
+	/* add the genetlink message header */
+	msg_header = genlmsg_put(skb, 0, 0,
+				 &pmcraid_event_family, 0,
+				 PMCRAID_AEN_CMD_EVENT);
+	if (!msg_header) {
+		pmcraid_err("failed to copy command details\n");
+		nlmsg_free(skb);
+		return -ENOMEM;
+	}
+
+	result = nla_put(skb, PMCRAID_AEN_ATTR_EVENT, data_size, aen_msg);
+
+	if (result) {
+		pmcraid_err("failed to copy AEN attribute data \n");
+		nlmsg_free(skb);
+		return -EINVAL;
+	}
+
+	/* send genetlink multicast message to notify appplications */
+	result = genlmsg_end(skb, msg_header);
+
+	if (result < 0) {
+		pmcraid_err("genlmsg_end failed\n");
+		nlmsg_free(skb);
+		return result;
+	}
+
+	result =
+		genlmsg_multicast(skb, 0, pmcraid_event_family.id, GFP_ATOMIC);
+
+	/* If there are no listeners, genlmsg_multicast may return non-zero
+	 * value.
+	 */
+	if (result)
+		pmcraid_info("failed to send %s event message %x!\n",
+			type == PMCRAID_HCAM_CODE_LOG_DATA ? "LDN" : "CCN",
+			result);
+	return result;
+}
+
+/**
+ * pmcraid_handle_config_change - Handle a config change from the adapter
+ * @pinstance: pointer to per adapter instance structure
+ *
+ * Return value:
+ *  none
+ */
+static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance)
+{
+	struct pmcraid_config_table_entry *cfg_entry;
+	struct pmcraid_hcam_ccn *ccn_hcam;
+	struct pmcraid_cmd *cmd;
+	struct pmcraid_cmd *cfgcmd;
+	struct pmcraid_resource_entry *res = NULL;
+	u32 new_entry = 1;
+	unsigned long lock_flags;
+	unsigned long host_lock_flags;
+	int rc;
+
+	ccn_hcam = (struct pmcraid_hcam_ccn *)pinstance->ccn.hcam;
+	cfg_entry = &ccn_hcam->cfg_entry;
+
+	pmcraid_info
+		("CCN(%x): %x type: %x lost: %x flags: %x res: %x:%x:%x:%x\n",
+		 pinstance->ccn.hcam->ilid,
+		 pinstance->ccn.hcam->op_code,
+		 pinstance->ccn.hcam->notification_type,
+		 pinstance->ccn.hcam->notification_lost,
+		 pinstance->ccn.hcam->flags,
+		 pinstance->host->unique_id,
+		 RES_IS_VSET(*cfg_entry) ? PMCRAID_VSET_BUS_ID :
+		 (RES_IS_GSCSI(*cfg_entry) ? PMCRAID_PHYS_BUS_ID :
+			RES_BUS(cfg_entry->resource_address)),
+		 RES_IS_VSET(*cfg_entry) ? cfg_entry->unique_flags1 :
+			RES_TARGET(cfg_entry->resource_address),
+		 RES_LUN(cfg_entry->resource_address));
+
+
+	/* If this HCAM indicates a lost notification, read the config table */
+	if (pinstance->ccn.hcam->notification_lost) {
+		cfgcmd = pmcraid_get_free_cmd(pinstance);
+		if (cfgcmd) {
+			pmcraid_info("lost CCN, reading config table\b");
+			pinstance->reinit_cfg_table = 1;
+			pmcraid_querycfg(cfgcmd);
+		} else {
+			pmcraid_err("lost CCN, no free cmd for querycfg\n");
+		}
+		goto out_notify_apps;
+	}
+
+	/* If this resource is not going to be added to mid-layer, just notify
+	 * applications and return
+	 */
+	if (!pmcraid_expose_resource(cfg_entry))
+		goto out_notify_apps;
+
+	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
+	list_for_each_entry(res, &pinstance->used_res_q, queue) {
+		rc = memcmp(&res->cfg_entry.resource_address,
+			    &cfg_entry->resource_address,
+			    sizeof(cfg_entry->resource_address));
+		if (!rc) {
+			new_entry = 0;
+			break;
+		}
+	}
+
+	if (new_entry) {
+
+		/* If there are more number of resources than what driver can
+		 * manage, do not notify the applications about the CCN. Just
+		 * ignore this notifications and re-register the same HCAM
+		 */
+		if (list_empty(&pinstance->free_res_q)) {
+			spin_unlock_irqrestore(&pinstance->resource_lock,
+						lock_flags);
+			pmcraid_err("too many resources attached\n");
+			spin_lock_irqsave(pinstance->host->host_lock,
+					  host_lock_flags);
+			pmcraid_send_hcam(pinstance,
+					  PMCRAID_HCAM_CODE_CONFIG_CHANGE);
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       host_lock_flags);
+			return;
+		}
+
+		res = list_entry(pinstance->free_res_q.next,
+				 struct pmcraid_resource_entry, queue);
+
+		list_del(&res->queue);
+		res->scsi_dev = NULL;
+		res->reset_progress = 0;
+		list_add_tail(&res->queue, &pinstance->used_res_q);
+	}
+
+	memcpy(&res->cfg_entry, cfg_entry,
+		sizeof(struct pmcraid_config_table_entry));
+
+	if (pinstance->ccn.hcam->notification_type ==
+	    NOTIFICATION_TYPE_ENTRY_DELETED) {
+		if (res->scsi_dev) {
+			res->change_detected = RES_CHANGE_DEL;
+			res->cfg_entry.resource_handle =
+				PMCRAID_INVALID_RES_HANDLE;
+			schedule_work(&pinstance->worker_q);
+		} else {
+			/* This may be one of the non-exposed resources */
+			list_move_tail(&res->queue, &pinstance->free_res_q);
+		}
+	} else if (!res->scsi_dev) {
+		res->change_detected = RES_CHANGE_ADD;
+		schedule_work(&pinstance->worker_q);
+	}
+	spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
+
+out_notify_apps:
+
+	/* Notify configuration changes to registered applications.*/
+	if (!pmcraid_disable_aen)
+		pmcraid_notify_aen(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE);
+
+	cmd = pmcraid_init_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE);
+	if (cmd)
+		pmcraid_send_hcam_cmd(cmd);
+}
+
+/**
+ * pmcraid_get_error_info - return error string for an ioasc
+ * @ioasc: ioasc code
+ * Return Value
+ *	 none
+ */
+static struct pmcraid_ioasc_error *pmcraid_get_error_info(u32 ioasc)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(pmcraid_ioasc_error_table); i++) {
+		if (pmcraid_ioasc_error_table[i].ioasc_code == ioasc)
+			return &pmcraid_ioasc_error_table[i];
+	}
+	return NULL;
+}
+
+/**
+ * pmcraid_ioasc_logger - log IOASC information based user-settings
+ * @ioasc: ioasc code
+ * @cmd: pointer to command that resulted in 'ioasc'
+ */
+void pmcraid_ioasc_logger(u32 ioasc, struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_ioasc_error *error_info = pmcraid_get_error_info(ioasc);
+
+	if (error_info == NULL ||
+		cmd->drv_inst->current_log_level < error_info->log_level)
+		return;
+
+	/* log the error string */
+	pmcraid_err("cmd [%d] for resource %x failed with %x(%s)\n",
+		cmd->ioa_cb->ioarcb.cdb[0],
+		cmd->ioa_cb->ioarcb.resource_handle,
+		le32_to_cpu(ioasc), error_info->error_string);
+}
+
+/**
+ * pmcraid_handle_error_log - Handle a config change (error log) from the IOA
+ *
+ * @pinstance: pointer to per adapter instance structure
+ *
+ * Return value:
+ *  none
+ */
+static void pmcraid_handle_error_log(struct pmcraid_instance *pinstance)
+{
+	struct pmcraid_hcam_ldn *hcam_ldn;
+	u32 ioasc;
+
+	hcam_ldn = (struct pmcraid_hcam_ldn *)pinstance->ldn.hcam;
+
+	pmcraid_info
+		("LDN(%x): %x type: %x lost: %x flags: %x overlay id: %x\n",
+		 pinstance->ldn.hcam->ilid,
+		 pinstance->ldn.hcam->op_code,
+		 pinstance->ldn.hcam->notification_type,
+		 pinstance->ldn.hcam->notification_lost,
+		 pinstance->ldn.hcam->flags,
+		 pinstance->ldn.hcam->overlay_id);
+
+	/* log only the errors, no need to log informational log entries */
+	if (pinstance->ldn.hcam->notification_type !=
+	    NOTIFICATION_TYPE_ERROR_LOG)
+		return;
+
+	if (pinstance->ldn.hcam->notification_lost ==
+	    HOSTRCB_NOTIFICATIONS_LOST)
+		dev_err(&pinstance->pdev->dev, "Error notifications lost\n");
+
+	ioasc = le32_to_cpu(hcam_ldn->error_log.fd_ioasc);
+
+	if (ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET ||
+		ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER) {
+		dev_err(&pinstance->pdev->dev,
+			"UnitAttention due to IOA Bus Reset\n");
+		scsi_report_bus_reset(
+			pinstance->host,
+			RES_BUS(hcam_ldn->error_log.fd_ra));
+	}
+
+	return;
+}
+
+/**
+ * pmcraid_process_ccn - Op done function for a CCN.
+ * @cmd: pointer to command struct
+ *
+ * This function is the op done function for a configuration
+ * change notification
+ *
+ * Return value:
+ * none
+ */
+static void pmcraid_process_ccn(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	u32 ioasc = le32_to_cpu(cmd->ioa_cb->ioasa.ioasc);
+	unsigned long lock_flags;
+
+	pinstance->ccn.cmd = NULL;
+	pmcraid_return_cmd(cmd);
+
+	/* If driver initiated IOA reset happened while this hcam was pending
+	 * with IOA, or IOA bringdown sequence is in progress, no need to
+	 * re-register the hcam
+	 */
+	if (ioasc == PMCRAID_IOASC_IOA_WAS_RESET ||
+	    atomic_read(&pinstance->ccn.ignore) == 1) {
+		return;
+	} else if (ioasc) {
+		dev_err(&pinstance->pdev->dev,
+			"Host RCB (CCN) failed with IOASC: 0x%08X\n", ioasc);
+		spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+		pmcraid_send_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE);
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+	} else {
+		pmcraid_handle_config_change(pinstance);
+	}
+}
+
+/**
+ * pmcraid_process_ldn - op done function for an LDN
+ * @cmd: pointer to command block
+ *
+ * Return value
+ *   none
+ */
+static void pmcraid_initiate_reset(struct pmcraid_instance *);
+
+static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	struct pmcraid_hcam_ldn *ldn_hcam =
+			(struct pmcraid_hcam_ldn *)pinstance->ldn.hcam;
+	u32 ioasc = le32_to_cpu(cmd->ioa_cb->ioasa.ioasc);
+	u32 fd_ioasc = le32_to_cpu(ldn_hcam->error_log.fd_ioasc);
+	unsigned long lock_flags;
+
+	/* return the command block back to freepool */
+	pinstance->ldn.cmd = NULL;
+	pmcraid_return_cmd(cmd);
+
+	/* If driver initiated IOA reset happened while this hcam was pending
+	 * with IOA, no need to re-register the hcam as reset engine will do it
+	 * once reset sequence is complete
+	 */
+	if (ioasc == PMCRAID_IOASC_IOA_WAS_RESET ||
+	    atomic_read(&pinstance->ccn.ignore) == 1) {
+		return;
+	} else if (!ioasc) {
+		pmcraid_handle_error_log(pinstance);
+		if (fd_ioasc == PMCRAID_IOASC_NR_IOA_RESET_REQUIRED) {
+			spin_lock_irqsave(pinstance->host->host_lock,
+					  lock_flags);
+			pmcraid_initiate_reset(pinstance);
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       lock_flags);
+			return;
+		}
+	} else {
+		dev_err(&pinstance->pdev->dev,
+			"Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc);
+	}
+	/* send netlink message for HCAM notification if enabled */
+	if (!pmcraid_disable_aen)
+		pmcraid_notify_aen(pinstance, PMCRAID_HCAM_CODE_LOG_DATA);
+
+	cmd = pmcraid_init_hcam(pinstance, PMCRAID_HCAM_CODE_LOG_DATA);
+	if (cmd)
+		pmcraid_send_hcam_cmd(cmd);
+}
+
+/**
+ * pmcraid_register_hcams - register HCAMs for CCN and LDN
+ *
+ * @pinstance: pointer per adapter instance structure
+ *
+ * Return Value
+ *   none
+ */
+static void pmcraid_register_hcams(struct pmcraid_instance *pinstance)
+{
+	pmcraid_send_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE);
+	pmcraid_send_hcam(pinstance, PMCRAID_HCAM_CODE_LOG_DATA);
+}
+
+/**
+ * pmcraid_unregister_hcams - cancel HCAMs registered already
+ * @cmd: pointer to command used as part of reset sequence
+ */
+static void pmcraid_unregister_hcams(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+
+	/* During IOA bringdown, HCAM gets fired and tasklet proceeds with
+	 * handling hcam response though it is not necessary. In order to
+	 * prevent this, set 'ignore', so that bring-down sequence doesn't
+	 * re-send any more hcams
+	 */
+	atomic_set(&pinstance->ccn.ignore, 1);
+	atomic_set(&pinstance->ldn.ignore, 1);
+
+	/* If adapter reset was forced as part of runtime reset sequence,
+	 * start the reset sequence.
+	 */
+	if (pinstance->force_ioa_reset && !pinstance->ioa_bringdown) {
+		pinstance->force_ioa_reset = 0;
+		pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
+		pmcraid_reset_alert(cmd);
+		return;
+	}
+
+	/* Driver tries to cancel HCAMs by sending ABORT TASK for each HCAM
+	 * one after the other. So CCN cancellation will be triggered by
+	 * pmcraid_cancel_ldn itself.
+	 */
+	pmcraid_cancel_ldn(cmd);
+}
+
+/**
+ * pmcraid_reset_enable_ioa - re-enable IOA after a hard reset
+ * @pinstance: pointer to adapter instance structure
+ * Return Value
+ *  1 if TRANSITION_TO_OPERATIONAL is active, otherwise 0
+ */
+static void pmcraid_reinit_buffers(struct pmcraid_instance *);
+
+static int pmcraid_reset_enable_ioa(struct pmcraid_instance *pinstance)
+{
+	u32 intrs;
+
+	pmcraid_reinit_buffers(pinstance);
+	intrs = pmcraid_read_interrupts(pinstance);
+
+	pmcraid_enable_interrupts(pinstance, PMCRAID_PCI_INTERRUPTS);
+
+	if (intrs & INTRS_TRANSITION_TO_OPERATIONAL) {
+		iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
+			pinstance->int_regs.ioa_host_interrupt_mask_reg);
+		iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
+			pinstance->int_regs.ioa_host_interrupt_clr_reg);
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/**
+ * pmcraid_soft_reset - performs a soft reset and makes IOA become ready
+ * @cmd : pointer to reset command block
+ *
+ * Return Value
+ *	none
+ */
+static void pmcraid_soft_reset(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	u32 int_reg;
+	u32 doorbell;
+
+	/* There will be an interrupt when Transition to Operational bit is
+	 * set so tasklet would execute next reset task. The timeout handler
+	 * would re-initiate a reset
+	 */
+	cmd->cmd_done = pmcraid_ioa_reset;
+	cmd->timer.data = (unsigned long)cmd;
+	cmd->timer.expires = jiffies +
+			     msecs_to_jiffies(PMCRAID_TRANSOP_TIMEOUT);
+	cmd->timer.function = (void (*)(unsigned long))pmcraid_timeout_handler;
+
+	if (!timer_pending(&cmd->timer))
+		add_timer(&cmd->timer);
+
+	/* Enable destructive diagnostics on IOA if it is not yet in
+	 * operational state
+	 */
+	doorbell = DOORBELL_RUNTIME_RESET |
+		   DOORBELL_ENABLE_DESTRUCTIVE_DIAGS;
+
+	iowrite32(doorbell, pinstance->int_regs.host_ioa_interrupt_reg);
+	int_reg = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
+	pmcraid_info("Waiting for IOA to become operational %x:%x\n",
+		     ioread32(pinstance->int_regs.host_ioa_interrupt_reg),
+		     int_reg);
+}
+
+/**
+ * pmcraid_get_dump - retrieves IOA dump in case of Unit Check interrupt
+ *
+ * @pinstance: pointer to adapter instance structure
+ *
+ * Return Value
+ *	none
+ */
+static void pmcraid_get_dump(struct pmcraid_instance *pinstance)
+{
+	pmcraid_info("%s is not yet implemented\n", __func__);
+}
+
+/**
+ * pmcraid_fail_outstanding_cmds - Fails all outstanding ops.
+ * @pinstance: pointer to adapter instance structure
+ *
+ * This function fails all outstanding ops. If they are submitted to IOA
+ * already, it sends cancel all messages if IOA is still accepting IOARCBs,
+ * otherwise just completes the commands and returns the cmd blocks to free
+ * pool.
+ *
+ * Return value:
+ *	 none
+ */
+static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance)
+{
+	struct pmcraid_cmd *cmd, *temp;
+	unsigned long lock_flags;
+
+	/* pending command list is protected by pending_pool_lock. Its
+	 * traversal must be done as within this lock
+	 */
+	spin_lock_irqsave(&pinstance->pending_pool_lock, lock_flags);
+	list_for_each_entry_safe(cmd, temp, &pinstance->pending_cmd_pool,
+				 free_list) {
+		list_del(&cmd->free_list);
+		spin_unlock_irqrestore(&pinstance->pending_pool_lock,
+					lock_flags);
+		cmd->ioa_cb->ioasa.ioasc =
+			cpu_to_le32(PMCRAID_IOASC_IOA_WAS_RESET);
+		cmd->ioa_cb->ioasa.ilid =
+			cpu_to_be32(PMCRAID_DRIVER_ILID);
+
+		/* In case the command timer is still running */
+		del_timer(&cmd->timer);
+
+		/* If this is an IO command, complete it by invoking scsi_done
+		 * function. If this is one of the internal commands other
+		 * than pmcraid_ioa_reset and HCAM commands invoke cmd_done to
+		 * complete it
+		 */
+		if (cmd->scsi_cmd) {
+
+			struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
+			__le32 resp = cmd->ioa_cb->ioarcb.response_handle;
+
+			scsi_cmd->result |= DID_ERROR << 16;
+
+			scsi_dma_unmap(scsi_cmd);
+			pmcraid_return_cmd(cmd);
+
+
+			pmcraid_info("failing(%d) CDB[0] = %x result: %x\n",
+				     le32_to_cpu(resp) >> 2,
+				     cmd->ioa_cb->ioarcb.cdb[0],
+				     scsi_cmd->result);
+			scsi_cmd->scsi_done(scsi_cmd);
+		} else if (cmd->cmd_done == pmcraid_internal_done ||
+			   cmd->cmd_done == pmcraid_erp_done) {
+			cmd->cmd_done(cmd);
+		} else if (cmd->cmd_done != pmcraid_ioa_reset) {
+			pmcraid_return_cmd(cmd);
+		}
+
+		atomic_dec(&pinstance->outstanding_cmds);
+		spin_lock_irqsave(&pinstance->pending_pool_lock, lock_flags);
+	}
+
+	spin_unlock_irqrestore(&pinstance->pending_pool_lock, lock_flags);
+}
+
+/**
+ * pmcraid_ioa_reset - Implementation of IOA reset logic
+ *
+ * @cmd: pointer to the cmd block to be used for entire reset process
+ *
+ * This function executes most of the steps required for IOA reset. This gets
+ * called by user threads (modprobe/insmod/rmmod) timer, tasklet and midlayer's
+ * 'eh_' thread. Access to variables used for controling the reset sequence is
+ * synchronized using host lock. Various functions called during reset process
+ * would make use of a single command block, pointer to which is also stored in
+ * adapter instance structure.
+ *
+ * Return Value
+ *	 None
+ */
+static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	u8 reset_complete = 0;
+
+	pinstance->ioa_reset_in_progress = 1;
+
+	if (pinstance->reset_cmd != cmd) {
+		pmcraid_err("reset is called with different command block\n");
+		pinstance->reset_cmd = cmd;
+	}
+
+	pmcraid_info("reset_engine: state = %d, command = %p\n",
+		      pinstance->ioa_state, cmd);
+
+	switch (pinstance->ioa_state) {
+
+	case IOA_STATE_DEAD:
+		/* If IOA is offline, whatever may be the reset reason, just
+		 * return. callers might be waiting on the reset wait_q, wake
+		 * up them
+		 */
+		pmcraid_err("IOA is offline no reset is possible\n");
+		reset_complete = 1;
+		break;
+
+	case IOA_STATE_IN_BRINGDOWN:
+		/* we enter here, once ioa shutdown command is processed by IOA
+		 * Alert IOA for a possible reset. If reset alert fails, IOA
+		 * goes through hard-reset
+		 */
+		pmcraid_disable_interrupts(pinstance, ~0);
+		pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
+		pmcraid_reset_alert(cmd);
+		break;
+
+	case IOA_STATE_UNKNOWN:
+		/* We may be called during probe or resume. Some pre-processing
+		 * is required for prior to reset
+		 */
+		scsi_block_requests(pinstance->host);
+
+		/* If asked to reset while IOA was processing responses or
+		 * there are any error responses then IOA may require
+		 * hard-reset.
+		 */
+		if (pinstance->ioa_hard_reset == 0) {
+			if (ioread32(pinstance->ioa_status) &
+			    INTRS_TRANSITION_TO_OPERATIONAL) {
+				pmcraid_info("sticky bit set, bring-up\n");
+				pinstance->ioa_state = IOA_STATE_IN_BRINGUP;
+				pmcraid_reinit_cmdblk(cmd);
+				pmcraid_identify_hrrq(cmd);
+			} else {
+				pinstance->ioa_state = IOA_STATE_IN_SOFT_RESET;
+				pmcraid_soft_reset(cmd);
+			}
+		} else {
+			/* Alert IOA of a possible reset and wait for critical
+			 * operation in progress bit to reset
+			 */
+			pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
+			pmcraid_reset_alert(cmd);
+		}
+		break;
+
+	case IOA_STATE_IN_RESET_ALERT:
+		/* If critical operation in progress bit is reset or wait gets
+		 * timed out, reset proceeds with starting BIST on the IOA.
+		 * pmcraid_ioa_hard_reset keeps a count of reset attempts. If
+		 * they are 3 or more, reset engine marks IOA dead and returns
+		 */
+		pinstance->ioa_state = IOA_STATE_IN_HARD_RESET;
+		pmcraid_start_bist(cmd);
+		break;
+
+	case IOA_STATE_IN_HARD_RESET:
+		pinstance->ioa_reset_attempts++;
+
+		/* retry reset if we haven't reached maximum allowed limit */
+		if (pinstance->ioa_reset_attempts > PMCRAID_RESET_ATTEMPTS) {
+			pinstance->ioa_reset_attempts = 0;
+			pmcraid_err("IOA didn't respond marking it as dead\n");
+			pinstance->ioa_state = IOA_STATE_DEAD;
+			reset_complete = 1;
+			break;
+		}
+
+		/* Once either bist or pci reset is done, restore PCI config
+		 * space. If this fails, proceed with hard reset again
+		 */
+
+		if (pci_restore_state(pinstance->pdev)) {
+			pmcraid_info("config-space error resetting again\n");
+			pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
+			pmcraid_reset_alert(cmd);
+			break;
+		}
+
+		/* fail all pending commands */
+		pmcraid_fail_outstanding_cmds(pinstance);
+
+		/* check if unit check is active, if so extract dump */
+		if (pinstance->ioa_unit_check) {
+			pmcraid_info("unit check is active\n");
+			pinstance->ioa_unit_check = 0;
+			pmcraid_get_dump(pinstance);
+			pinstance->ioa_reset_attempts--;
+			pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
+			pmcraid_reset_alert(cmd);
+			break;
+		}
+
+		/* if the reset reason is to bring-down the ioa, we might be
+		 * done with the reset restore pci_config_space and complete
+		 * the reset
+		 */
+		if (pinstance->ioa_bringdown) {
+			pmcraid_info("bringing down the adapter\n");
+			pinstance->ioa_shutdown_type = SHUTDOWN_NONE;
+			pinstance->ioa_bringdown = 0;
+			pinstance->ioa_state = IOA_STATE_UNKNOWN;
+			reset_complete = 1;
+		} else {
+			/* bring-up IOA, so proceed with soft reset
+			 * Reinitialize hrrq_buffers and their indices also
+			 * enable interrupts after a pci_restore_state
+			 */
+			if (pmcraid_reset_enable_ioa(pinstance)) {
+				pinstance->ioa_state = IOA_STATE_IN_BRINGUP;
+				pmcraid_info("bringing up the adapter\n");
+				pmcraid_reinit_cmdblk(cmd);
+				pmcraid_identify_hrrq(cmd);
+			} else {
+				pinstance->ioa_state = IOA_STATE_IN_SOFT_RESET;
+				pmcraid_soft_reset(cmd);
+			}
+		}
+		break;
+
+	case IOA_STATE_IN_SOFT_RESET:
+		/* TRANSITION TO OPERATIONAL is on so start initialization
+		 * sequence
+		 */
+		pmcraid_info("In softreset proceeding with bring-up\n");
+		pinstance->ioa_state = IOA_STATE_IN_BRINGUP;
+
+		/* Initialization commands start with HRRQ identification. From
+		 * now on tasklet completes most of the commands as IOA is up
+		 * and intrs are enabled
+		 */
+		pmcraid_identify_hrrq(cmd);
+		break;
+
+	case IOA_STATE_IN_BRINGUP:
+		/* we are done with bringing up of IOA, change the ioa_state to
+		 * operational and wake up any waiters
+		 */
+		pinstance->ioa_state = IOA_STATE_OPERATIONAL;
+		reset_complete = 1;
+		break;
+
+	case IOA_STATE_OPERATIONAL:
+	default:
+		/* When IOA is operational and a reset is requested, check for
+		 * the reset reason. If reset is to bring down IOA, unregister
+		 * HCAMs and initiate shutdown; if adapter reset is forced then
+		 * restart reset sequence again
+		 */
+		if (pinstance->ioa_shutdown_type == SHUTDOWN_NONE &&
+		    pinstance->force_ioa_reset == 0) {
+			reset_complete = 1;
+		} else {
+			if (pinstance->ioa_shutdown_type != SHUTDOWN_NONE)
+				pinstance->ioa_state = IOA_STATE_IN_BRINGDOWN;
+			pmcraid_reinit_cmdblk(cmd);
+			pmcraid_unregister_hcams(cmd);
+		}
+		break;
+	}
+
+	/* reset will be completed if ioa_state is either DEAD or UNKNOWN or
+	 * OPERATIONAL. Reset all control variables used during reset, wake up
+	 * any waiting threads and let the SCSI mid-layer send commands. Note
+	 * that host_lock must be held before invoking scsi_report_bus_reset.
+	 */
+	if (reset_complete) {
+		pinstance->ioa_reset_in_progress = 0;
+		pinstance->ioa_reset_attempts = 0;
+		pinstance->reset_cmd = NULL;
+		pinstance->ioa_shutdown_type = SHUTDOWN_NONE;
+		pinstance->ioa_bringdown = 0;
+		pmcraid_return_cmd(cmd);
+
+		/* If target state is to bring up the adapter, proceed with
+		 * hcam registration and resource exposure to mid-layer.
+		 */
+		if (pinstance->ioa_state == IOA_STATE_OPERATIONAL)
+			pmcraid_register_hcams(pinstance);
+
+		wake_up_all(&pinstance->reset_wait_q);
+	}
+
+	return;
+}
+
+/**
+ * pmcraid_initiate_reset - initiates reset sequence. This is called from
+ * ISR/tasklet during error interrupts including IOA unit check. If reset
+ * is already in progress, it just returns, otherwise initiates IOA reset
+ * to bring IOA up to operational state.
+ *
+ * @pinstance: pointer to adapter instance structure
+ *
+ * Return value
+ *	 none
+ */
+static void pmcraid_initiate_reset(struct pmcraid_instance *pinstance)
+{
+	struct pmcraid_cmd *cmd;
+
+	/* If the reset is already in progress, just return, otherwise start
+	 * reset sequence and return
+	 */
+	if (!pinstance->ioa_reset_in_progress) {
+		scsi_block_requests(pinstance->host);
+		cmd = pmcraid_get_free_cmd(pinstance);
+
+		if (cmd == NULL) {
+			pmcraid_err("no cmnd blocks for initiate_reset\n");
+			return;
+		}
+
+		pinstance->ioa_shutdown_type = SHUTDOWN_NONE;
+		pinstance->reset_cmd = cmd;
+		pinstance->force_ioa_reset = 1;
+		pmcraid_ioa_reset(cmd);
+	}
+}
+
+/**
+ * pmcraid_reset_reload - utility routine for doing IOA reset either to bringup
+ *			  or bringdown IOA
+ * @pinstance: pointer adapter instance structure
+ * @shutdown_type: shutdown type to be used NONE, NORMAL or ABRREV
+ * @target_state: expected target state after reset
+ *
+ * Note: This command initiates reset and waits for its completion. Hence this
+ * should not be called from isr/timer/tasklet functions (timeout handlers,
+ * error response handlers and interrupt handlers).
+ *
+ * Return Value
+ *	 1 in case ioa_state is not target_state, 0 otherwise.
+ */
+static int pmcraid_reset_reload(
+	struct pmcraid_instance *pinstance,
+	u8 shutdown_type,
+	u8 target_state
+)
+{
+	struct pmcraid_cmd *reset_cmd = NULL;
+	unsigned long lock_flags;
+	int reset = 1;
+
+	spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+
+	if (pinstance->ioa_reset_in_progress) {
+		pmcraid_info("reset_reload: reset is already in progress\n");
+
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+
+		wait_event(pinstance->reset_wait_q,
+			   !pinstance->ioa_reset_in_progress);
+
+		spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+
+		if (pinstance->ioa_state == IOA_STATE_DEAD) {
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       lock_flags);
+			pmcraid_info("reset_reload: IOA is dead\n");
+			return reset;
+		} else if (pinstance->ioa_state == target_state) {
+			reset = 0;
+		}
+	}
+
+	if (reset) {
+		pmcraid_info("reset_reload: proceeding with reset\n");
+		scsi_block_requests(pinstance->host);
+		reset_cmd = pmcraid_get_free_cmd(pinstance);
+
+		if (reset_cmd == NULL) {
+			pmcraid_err("no free cmnd for reset_reload\n");
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       lock_flags);
+			return reset;
+		}
+
+		if (shutdown_type == SHUTDOWN_NORMAL)
+			pinstance->ioa_bringdown = 1;
+
+		pinstance->ioa_shutdown_type = shutdown_type;
+		pinstance->reset_cmd = reset_cmd;
+		pinstance->force_ioa_reset = reset;
+		pmcraid_info("reset_reload: initiating reset\n");
+		pmcraid_ioa_reset(reset_cmd);
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+		pmcraid_info("reset_reload: waiting for reset to complete\n");
+		wait_event(pinstance->reset_wait_q,
+			   !pinstance->ioa_reset_in_progress);
+
+		pmcraid_info("reset_reload: reset is complete !! \n");
+		scsi_unblock_requests(pinstance->host);
+		if (pinstance->ioa_state == target_state)
+			reset = 0;
+	}
+
+	return reset;
+}
+
+/**
+ * pmcraid_reset_bringdown - wrapper over pmcraid_reset_reload to bringdown IOA
+ *
+ * @pinstance: pointer to adapter instance structure
+ *
+ * Return Value
+ *	 whatever is returned from pmcraid_reset_reload
+ */
+static int pmcraid_reset_bringdown(struct pmcraid_instance *pinstance)
+{
+	return pmcraid_reset_reload(pinstance,
+				    SHUTDOWN_NORMAL,
+				    IOA_STATE_UNKNOWN);
+}
+
+/**
+ * pmcraid_reset_bringup - wrapper over pmcraid_reset_reload to bring up IOA
+ *
+ * @pinstance: pointer to adapter instance structure
+ *
+ * Return Value
+ *	 whatever is returned from pmcraid_reset_reload
+ */
+static int pmcraid_reset_bringup(struct pmcraid_instance *pinstance)
+{
+	return pmcraid_reset_reload(pinstance,
+				    SHUTDOWN_NONE,
+				    IOA_STATE_OPERATIONAL);
+}
+
+/**
+ * pmcraid_request_sense - Send request sense to a device
+ * @cmd: pmcraid command struct
+ *
+ * This function sends a request sense to a device as a result of a check
+ * condition. This method re-uses the same command block that failed earlier.
+ */
+static void pmcraid_request_sense(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+
+	/* allocate DMAable memory for sense buffers */
+	cmd->sense_buffer = pci_alloc_consistent(cmd->drv_inst->pdev,
+						 SCSI_SENSE_BUFFERSIZE,
+						 &cmd->sense_buffer_dma);
+
+	if (cmd->sense_buffer == NULL) {
+		pmcraid_err
+			("couldn't allocate sense buffer for request sense\n");
+		pmcraid_erp_done(cmd);
+		return;
+	}
+
+	/* re-use the command block */
+	memset(&cmd->ioa_cb->ioasa, 0, sizeof(struct pmcraid_ioasa));
+	memset(ioarcb->cdb, 0, PMCRAID_MAX_CDB_LEN);
+	ioarcb->request_flags0 = (SYNC_COMPLETE |
+				  NO_LINK_DESCS |
+				  INHIBIT_UL_CHECK);
+	ioarcb->request_type = REQ_TYPE_SCSI;
+	ioarcb->cdb[0] = REQUEST_SENSE;
+	ioarcb->cdb[4] = SCSI_SENSE_BUFFERSIZE;
+
+	ioarcb->ioadl_bus_addr = cpu_to_le64((cmd->ioa_cb_bus_addr) +
+					offsetof(struct pmcraid_ioarcb,
+						add_data.u.ioadl[0]));
+	ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
+
+	ioarcb->data_transfer_length = cpu_to_le32(SCSI_SENSE_BUFFERSIZE);
+
+	ioadl->address = cpu_to_le64(cmd->sense_buffer_dma);
+	ioadl->data_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE);
+	ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+
+	/* request sense might be called as part of error response processing
+	 * which runs in tasklets context. It is possible that mid-layer might
+	 * schedule queuecommand during this time, hence, writting to IOARRIN
+	 * must be protect by host_lock
+	 */
+	pmcraid_send_cmd(cmd, pmcraid_erp_done,
+			 PMCRAID_REQUEST_SENSE_TIMEOUT,
+			 pmcraid_timeout_handler);
+}
+
+/**
+ * pmcraid_cancel_all - cancel all outstanding IOARCBs as part of error recovery
+ * @cmd: command that failed
+ * @sense: true if request_sense is required after cancel all
+ *
+ * This function sends a cancel all to a device to clear the queue.
+ */
+static void pmcraid_cancel_all(struct pmcraid_cmd *cmd, u32 sense)
+{
+	struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	struct pmcraid_resource_entry *res = scsi_cmd->device->hostdata;
+	void (*cmd_done) (struct pmcraid_cmd *) = sense ? pmcraid_erp_done
+							: pmcraid_request_sense;
+
+	memset(ioarcb->cdb, 0, PMCRAID_MAX_CDB_LEN);
+	ioarcb->request_flags0 = SYNC_OVERRIDE;
+	ioarcb->request_type = REQ_TYPE_IOACMD;
+	ioarcb->cdb[0] = PMCRAID_CANCEL_ALL_REQUESTS;
+
+	if (RES_IS_GSCSI(res->cfg_entry))
+		ioarcb->cdb[1] = PMCRAID_SYNC_COMPLETE_AFTER_CANCEL;
+
+	ioarcb->ioadl_bus_addr = 0;
+	ioarcb->ioadl_length = 0;
+	ioarcb->data_transfer_length = 0;
+	ioarcb->ioarcb_bus_addr &= (~0x1FULL);
+
+	/* writing to IOARRIN must be protected by host_lock, as mid-layer
+	 * schedule queuecommand while we are doing this
+	 */
+	pmcraid_send_cmd(cmd, cmd_done,
+			 PMCRAID_REQUEST_SENSE_TIMEOUT,
+			 pmcraid_timeout_handler);
+}
+
+/**
+ * pmcraid_frame_auto_sense: frame fixed format sense information
+ *
+ * @cmd: pointer to failing command block
+ *
+ * Return value
+ *  none
+ */
+static void pmcraid_frame_auto_sense(struct pmcraid_cmd *cmd)
+{
+	u8 *sense_buf = cmd->scsi_cmd->sense_buffer;
+	struct pmcraid_resource_entry *res = cmd->scsi_cmd->device->hostdata;
+	struct pmcraid_ioasa *ioasa = &cmd->ioa_cb->ioasa;
+	u32 ioasc = le32_to_cpu(ioasa->ioasc);
+	u32 failing_lba = 0;
+
+	memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
+	cmd->scsi_cmd->result = SAM_STAT_CHECK_CONDITION;
+
+	if (RES_IS_VSET(res->cfg_entry) &&
+	    ioasc == PMCRAID_IOASC_ME_READ_ERROR_NO_REALLOC &&
+	    ioasa->u.vset.failing_lba_hi != 0) {
+
+		sense_buf[0] = 0x72;
+		sense_buf[1] = PMCRAID_IOASC_SENSE_KEY(ioasc);
+		sense_buf[2] = PMCRAID_IOASC_SENSE_CODE(ioasc);
+		sense_buf[3] = PMCRAID_IOASC_SENSE_QUAL(ioasc);
+
+		sense_buf[7] = 12;
+		sense_buf[8] = 0;
+		sense_buf[9] = 0x0A;
+		sense_buf[10] = 0x80;
+
+		failing_lba = le32_to_cpu(ioasa->u.vset.failing_lba_hi);
+
+		sense_buf[12] = (failing_lba & 0xff000000) >> 24;
+		sense_buf[13] = (failing_lba & 0x00ff0000) >> 16;
+		sense_buf[14] = (failing_lba & 0x0000ff00) >> 8;
+		sense_buf[15] = failing_lba & 0x000000ff;
+
+		failing_lba = le32_to_cpu(ioasa->u.vset.failing_lba_lo);
+
+		sense_buf[16] = (failing_lba & 0xff000000) >> 24;
+		sense_buf[17] = (failing_lba & 0x00ff0000) >> 16;
+		sense_buf[18] = (failing_lba & 0x0000ff00) >> 8;
+		sense_buf[19] = failing_lba & 0x000000ff;
+	} else {
+		sense_buf[0] = 0x70;
+		sense_buf[2] = PMCRAID_IOASC_SENSE_KEY(ioasc);
+		sense_buf[12] = PMCRAID_IOASC_SENSE_CODE(ioasc);
+		sense_buf[13] = PMCRAID_IOASC_SENSE_QUAL(ioasc);
+
+		if (ioasc == PMCRAID_IOASC_ME_READ_ERROR_NO_REALLOC) {
+			if (RES_IS_VSET(res->cfg_entry))
+				failing_lba =
+					le32_to_cpu(ioasa->u.
+						 vset.failing_lba_lo);
+			sense_buf[0] |= 0x80;
+			sense_buf[3] = (failing_lba >> 24) & 0xff;
+			sense_buf[4] = (failing_lba >> 16) & 0xff;
+			sense_buf[5] = (failing_lba >> 8) & 0xff;
+			sense_buf[6] = failing_lba & 0xff;
+		}
+
+		sense_buf[7] = 6; /* additional length */
+	}
+}
+
+/**
+ * pmcraid_error_handler - Error response handlers for a SCSI op
+ * @cmd: pointer to pmcraid_cmd that has failed
+ *
+ * This function determines whether or not to initiate ERP on the affected
+ * device. This is called from a tasklet, which doesn't hold any locks.
+ *
+ * Return value:
+ *	 0 it caller can complete the request, otherwise 1 where in error
+ *	 handler itself completes the request and returns the command block
+ *	 back to free-pool
+ */
+static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
+{
+	struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
+	struct pmcraid_resource_entry *res = scsi_cmd->device->hostdata;
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	struct pmcraid_ioasa *ioasa = &cmd->ioa_cb->ioasa;
+	u32 ioasc = le32_to_cpu(ioasa->ioasc);
+	u32 masked_ioasc = ioasc & PMCRAID_IOASC_SENSE_MASK;
+	u32 sense_copied = 0;
+
+	if (!res) {
+		pmcraid_info("resource pointer is NULL\n");
+		return 0;
+	}
+
+	/* If this was a SCSI read/write command keep count of errors */
+	if (SCSI_CMD_TYPE(scsi_cmd->cmnd[0]) == SCSI_READ_CMD)
+		atomic_inc(&res->read_failures);
+	else if (SCSI_CMD_TYPE(scsi_cmd->cmnd[0]) == SCSI_WRITE_CMD)
+		atomic_inc(&res->write_failures);
+
+	if (!RES_IS_GSCSI(res->cfg_entry) &&
+		masked_ioasc != PMCRAID_IOASC_HW_DEVICE_BUS_STATUS_ERROR) {
+		pmcraid_frame_auto_sense(cmd);
+	}
+
+	/* Log IOASC/IOASA information based on user settings */
+	pmcraid_ioasc_logger(ioasc, cmd);
+
+	switch (masked_ioasc) {
+
+	case PMCRAID_IOASC_AC_TERMINATED_BY_HOST:
+		scsi_cmd->result |= (DID_ABORT << 16);
+		break;
+
+	case PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE:
+	case PMCRAID_IOASC_HW_CANNOT_COMMUNICATE:
+		scsi_cmd->result |= (DID_NO_CONNECT << 16);
+		break;
+
+	case PMCRAID_IOASC_NR_SYNC_REQUIRED:
+		res->sync_reqd = 1;
+		scsi_cmd->result |= (DID_IMM_RETRY << 16);
+		break;
+
+	case PMCRAID_IOASC_ME_READ_ERROR_NO_REALLOC:
+		scsi_cmd->result |= (DID_PASSTHROUGH << 16);
+		break;
+
+	case PMCRAID_IOASC_UA_BUS_WAS_RESET:
+	case PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER:
+		if (!res->reset_progress)
+			scsi_report_bus_reset(pinstance->host,
+					      scsi_cmd->device->channel);
+		scsi_cmd->result |= (DID_ERROR << 16);
+		break;
+
+	case PMCRAID_IOASC_HW_DEVICE_BUS_STATUS_ERROR:
+		scsi_cmd->result |= PMCRAID_IOASC_SENSE_STATUS(ioasc);
+		res->sync_reqd = 1;
+
+		/* if check_condition is not active return with error otherwise
+		 * get/frame the sense buffer
+		 */
+		if (PMCRAID_IOASC_SENSE_STATUS(ioasc) !=
+		    SAM_STAT_CHECK_CONDITION &&
+		    PMCRAID_IOASC_SENSE_STATUS(ioasc) != SAM_STAT_ACA_ACTIVE)
+			return 0;
+
+		/* If we have auto sense data as part of IOASA pass it to
+		 * mid-layer
+		 */
+		if (ioasa->auto_sense_length != 0) {
+			short sense_len = ioasa->auto_sense_length;
+			int data_size = min_t(u16, le16_to_cpu(sense_len),
+					      SCSI_SENSE_BUFFERSIZE);
+
+			memcpy(scsi_cmd->sense_buffer,
+			       ioasa->sense_data,
+			       data_size);
+			sense_copied = 1;
+		}
+
+		if (RES_IS_GSCSI(res->cfg_entry)) {
+			pmcraid_cancel_all(cmd, sense_copied);
+		} else if (sense_copied) {
+			pmcraid_erp_done(cmd);
+			return 0;
+		} else  {
+			pmcraid_request_sense(cmd);
+		}
+
+		return 1;
+
+	case PMCRAID_IOASC_NR_INIT_CMD_REQUIRED:
+		break;
+
+	default:
+		if (PMCRAID_IOASC_SENSE_KEY(ioasc) > RECOVERED_ERROR)
+			scsi_cmd->result |= (DID_ERROR << 16);
+		break;
+	}
+	return 0;
+}
+
+/**
+ * pmcraid_reset_device - device reset handler functions
+ *
+ * @scsi_cmd: scsi command struct
+ * @modifier: reset modifier indicating the reset sequence to be performed
+ *
+ * This function issues a device reset to the affected device.
+ * A LUN reset will be sent to the device first. If that does
+ * not work, a target reset will be sent.
+ *
+ * Return value:
+ *	SUCCESS / FAILED
+ */
+static int pmcraid_reset_device(
+	struct scsi_cmnd *scsi_cmd,
+	unsigned long timeout,
+	u8 modifier
+)
+{
+	struct pmcraid_cmd *cmd;
+	struct pmcraid_instance *pinstance;
+	struct pmcraid_resource_entry *res;
+	struct pmcraid_ioarcb *ioarcb;
+	unsigned long lock_flags;
+	u32 ioasc;
+
+	pinstance =
+		(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
+	res = scsi_cmd->device->hostdata;
+
+	if (!res) {
+		pmcraid_err("reset_device: NULL resource pointer\n");
+		return FAILED;
+	}
+
+	/* If adapter is currently going through reset/reload, return failed.
+	 * This will force the mid-layer to call _eh_bus/host reset, which
+	 * will then go to sleep and wait for the reset to complete
+	 */
+	spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+	if (pinstance->ioa_reset_in_progress ||
+	    pinstance->ioa_state == IOA_STATE_DEAD) {
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+		return FAILED;
+	}
+
+	res->reset_progress = 1;
+	pmcraid_info("Resetting %s resource with addr %x\n",
+		     ((modifier & RESET_DEVICE_LUN) ? "LUN" :
+		     ((modifier & RESET_DEVICE_TARGET) ? "TARGET" : "BUS")),
+		     le32_to_cpu(res->cfg_entry.resource_address));
+
+	/* get a free cmd block */
+	cmd = pmcraid_get_free_cmd(pinstance);
+
+	if (cmd == NULL) {
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+		pmcraid_err("%s: no cmd blocks are available\n", __func__);
+		return FAILED;
+	}
+
+	ioarcb = &cmd->ioa_cb->ioarcb;
+	ioarcb->resource_handle = res->cfg_entry.resource_handle;
+	ioarcb->request_type = REQ_TYPE_IOACMD;
+	ioarcb->cdb[0] = PMCRAID_RESET_DEVICE;
+
+	/* Initialize reset modifier bits */
+	if (modifier)
+		modifier = ENABLE_RESET_MODIFIER | modifier;
+
+	ioarcb->cdb[1] = modifier;
+
+	init_completion(&cmd->wait_for_completion);
+	cmd->completion_req = 1;
+
+	pmcraid_info("cmd(CDB[0] = %x) for %x with index = %d\n",
+		     cmd->ioa_cb->ioarcb.cdb[0],
+		     le32_to_cpu(cmd->ioa_cb->ioarcb.resource_handle),
+		     le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle) >> 2);
+
+	pmcraid_send_cmd(cmd,
+			 pmcraid_internal_done,
+			 timeout,
+			 pmcraid_timeout_handler);
+
+	spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+
+	/* RESET_DEVICE command completes after all pending IOARCBs are
+	 * completed. Once this command is completed, pmcraind_internal_done
+	 * will wake up the 'completion' queue.
+	 */
+	wait_for_completion(&cmd->wait_for_completion);
+
+	/* complete the command here itself and return the command block
+	 * to free list
+	 */
+	pmcraid_return_cmd(cmd);
+	res->reset_progress = 0;
+	ioasc = le32_to_cpu(cmd->ioa_cb->ioasa.ioasc);
+
+	/* set the return value based on the returned ioasc */
+	return PMCRAID_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS;
+}
+
+/**
+ * _pmcraid_io_done - helper for pmcraid_io_done function
+ *
+ * @cmd: pointer to pmcraid command struct
+ * @reslen: residual data length to be set in the ioasa
+ * @ioasc: ioasc either returned by IOA or set by driver itself.
+ *
+ * This function is invoked by pmcraid_io_done to complete mid-layer
+ * scsi ops.
+ *
+ * Return value:
+ *	  0 if caller is required to return it to free_pool. Returns 1 if
+ *	  caller need not worry about freeing command block as error handler
+ *	  will take care of that.
+ */
+
+static int _pmcraid_io_done(struct pmcraid_cmd *cmd, int reslen, int ioasc)
+{
+	struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
+	int rc = 0;
+
+	scsi_set_resid(scsi_cmd, reslen);
+
+	pmcraid_info("response(%d) CDB[0] = %x ioasc:result: %x:%x\n",
+		le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle) >> 2,
+		cmd->ioa_cb->ioarcb.cdb[0],
+		ioasc, scsi_cmd->result);
+
+	if (PMCRAID_IOASC_SENSE_KEY(ioasc) != 0)
+		rc = pmcraid_error_handler(cmd);
+
+	if (rc == 0) {
+		scsi_dma_unmap(scsi_cmd);
+		scsi_cmd->scsi_done(scsi_cmd);
+	}
+
+	return rc;
+}
+
+/**
+ * pmcraid_io_done - SCSI completion function
+ *
+ * @cmd: pointer to pmcraid command struct
+ *
+ * This function is invoked by tasklet/mid-layer error handler to completing
+ * the SCSI ops sent from mid-layer.
+ *
+ * Return value
+ *	  none
+ */
+
+static void pmcraid_io_done(struct pmcraid_cmd *cmd)
+{
+	u32 ioasc = le32_to_cpu(cmd->ioa_cb->ioasa.ioasc);
+	u32 reslen = le32_to_cpu(cmd->ioa_cb->ioasa.residual_data_length);
+
+	if (_pmcraid_io_done(cmd, reslen, ioasc) == 0)
+		pmcraid_return_cmd(cmd);
+}
+
+/**
+ * pmcraid_abort_cmd - Aborts a single IOARCB already submitted to IOA
+ *
+ * @cmd: command block of the command to be aborted
+ *
+ * Return Value:
+ *	 returns pointer to command structure used as cancelling cmd
+ */
+static struct pmcraid_cmd *pmcraid_abort_cmd(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_cmd *cancel_cmd;
+	struct pmcraid_instance *pinstance;
+	struct pmcraid_resource_entry *res;
+
+	pinstance = (struct pmcraid_instance *)cmd->drv_inst;
+	res = cmd->scsi_cmd->device->hostdata;
+
+	cancel_cmd = pmcraid_get_free_cmd(pinstance);
+
+	if (cancel_cmd == NULL) {
+		pmcraid_err("%s: no cmd blocks are available\n", __func__);
+		return NULL;
+	}
+
+	pmcraid_prepare_cancel_cmd(cancel_cmd, cmd);
+
+	pmcraid_info("aborting command CDB[0]= %x with index = %d\n",
+		cmd->ioa_cb->ioarcb.cdb[0],
+		cmd->ioa_cb->ioarcb.response_handle >> 2);
+
+	init_completion(&cancel_cmd->wait_for_completion);
+	cancel_cmd->completion_req = 1;
+
+	pmcraid_info("command (%d) CDB[0] = %x for %x\n",
+		le32_to_cpu(cancel_cmd->ioa_cb->ioarcb.response_handle) >> 2,
+		cmd->ioa_cb->ioarcb.cdb[0],
+		le32_to_cpu(cancel_cmd->ioa_cb->ioarcb.resource_handle));
+
+	pmcraid_send_cmd(cancel_cmd,
+			 pmcraid_internal_done,
+			 PMCRAID_INTERNAL_TIMEOUT,
+			 pmcraid_timeout_handler);
+	return cancel_cmd;
+}
+
+/**
+ * pmcraid_abort_complete - Waits for ABORT TASK completion
+ *
+ * @cancel_cmd: command block use as cancelling command
+ *
+ * Return Value:
+ *	 returns SUCCESS if ABORT TASK has good completion
+ *	 otherwise FAILED
+ */
+static int pmcraid_abort_complete(struct pmcraid_cmd *cancel_cmd)
+{
+	struct pmcraid_resource_entry *res;
+	u32 ioasc;
+
+	wait_for_completion(&cancel_cmd->wait_for_completion);
+	res = cancel_cmd->u.res;
+	cancel_cmd->u.res = NULL;
+	ioasc = le32_to_cpu(cancel_cmd->ioa_cb->ioasa.ioasc);
+
+	/* If the abort task is not timed out we will get a Good completion
+	 * as sense_key, otherwise we may get one the following responses
+	 * due to subsquent bus reset or device reset. In case IOASC is
+	 * NR_SYNC_REQUIRED, set sync_reqd flag for the corresponding resource
+	 */
+	if (ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET ||
+	    ioasc == PMCRAID_IOASC_NR_SYNC_REQUIRED) {
+		if (ioasc == PMCRAID_IOASC_NR_SYNC_REQUIRED)
+			res->sync_reqd = 1;
+		ioasc = 0;
+	}
+
+	/* complete the command here itself */
+	pmcraid_return_cmd(cancel_cmd);
+	return PMCRAID_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS;
+}
+
+/**
+ * pmcraid_eh_abort_handler - entry point for aborting a single task on errors
+ *
+ * @scsi_cmd:   scsi command struct given by mid-layer. When this is called
+ *		mid-layer ensures that no other commands are queued. This
+ *		never gets called under interrupt, but a separate eh thread.
+ *
+ * Return value:
+ *	 SUCCESS / FAILED
+ */
+static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd)
+{
+	struct pmcraid_instance *pinstance;
+	struct pmcraid_cmd *cmd;
+	struct pmcraid_resource_entry *res;
+	unsigned long host_lock_flags;
+	unsigned long pending_lock_flags;
+	struct pmcraid_cmd *cancel_cmd = NULL;
+	int cmd_found = 0;
+	int rc = FAILED;
+
+	pinstance =
+		(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
+
+	dev_err(&pinstance->pdev->dev,
+		"I/O command timed out, aborting it.\n");
+
+	res = scsi_cmd->device->hostdata;
+
+	if (res == NULL)
+		return rc;
+
+	/* If we are currently going through reset/reload, return failed.
+	 * This will force the mid-layer to eventually call
+	 * pmcraid_eh_host_reset which will then go to sleep and wait for the
+	 * reset to complete
+	 */
+	spin_lock_irqsave(pinstance->host->host_lock, host_lock_flags);
+
+	if (pinstance->ioa_reset_in_progress ||
+	    pinstance->ioa_state == IOA_STATE_DEAD) {
+		spin_unlock_irqrestore(pinstance->host->host_lock,
+				       host_lock_flags);
+		return rc;
+	}
+
+	/* loop over pending cmd list to find cmd corresponding to this
+	 * scsi_cmd. Note that this command might not have been completed
+	 * already. locking: all pending commands are protected with
+	 * pending_pool_lock.
+	 */
+	spin_lock_irqsave(&pinstance->pending_pool_lock, pending_lock_flags);
+	list_for_each_entry(cmd, &pinstance->pending_cmd_pool, free_list) {
+
+		if (cmd->scsi_cmd == scsi_cmd) {
+			cmd_found = 1;
+			break;
+		}
+	}
+
+	spin_unlock_irqrestore(&pinstance->pending_pool_lock,
+				pending_lock_flags);
+
+	/* If the command to be aborted was given to IOA and still pending with
+	 * it, send ABORT_TASK to abort this and wait for its completion
+	 */
+	if (cmd_found)
+		cancel_cmd = pmcraid_abort_cmd(cmd);
+
+	spin_unlock_irqrestore(pinstance->host->host_lock,
+			       host_lock_flags);
+
+	if (cancel_cmd) {
+		cancel_cmd->u.res = cmd->scsi_cmd->device->hostdata;
+		rc = pmcraid_abort_complete(cancel_cmd);
+	}
+
+	return cmd_found ? rc : SUCCESS;
+}
+
+/**
+ * pmcraid_eh_xxxx_reset_handler - bus/target/device reset handler callbacks
+ *
+ * @scmd: pointer to scsi_cmd that was sent to the resource to be reset.
+ *
+ * All these routines invokve pmcraid_reset_device with appropriate parameters.
+ * Since these are called from mid-layer EH thread, no other IO will be queued
+ * to the resource being reset. However, control path (IOCTL) may be active so
+ * it is necessary to synchronize IOARRIN writes which pmcraid_reset_device
+ * takes care by locking/unlocking host_lock.
+ *
+ * Return value
+ * 	SUCCESS or FAILED
+ */
+static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
+{
+	pmcraid_err("Doing device reset due to an I/O command timeout.\n");
+	return pmcraid_reset_device(scmd,
+				    PMCRAID_INTERNAL_TIMEOUT,
+				    RESET_DEVICE_LUN);
+}
+
+static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
+{
+	pmcraid_err("Doing bus reset due to an I/O command timeout.\n");
+	return pmcraid_reset_device(scmd,
+				    PMCRAID_RESET_BUS_TIMEOUT,
+				    RESET_DEVICE_BUS);
+}
+
+static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
+{
+	pmcraid_err("Doing target reset due to an I/O command timeout.\n");
+	return pmcraid_reset_device(scmd,
+				    PMCRAID_INTERNAL_TIMEOUT,
+				    RESET_DEVICE_TARGET);
+}
+
+/**
+ * pmcraid_eh_host_reset_handler - adapter reset handler callback
+ *
+ * @scmd: pointer to scsi_cmd that was sent to a resource of adapter
+ *
+ * Initiates adapter reset to bring it up to operational state
+ *
+ * Return value
+ * 	SUCCESS or FAILED
+ */
+static int pmcraid_eh_host_reset_handler(struct scsi_cmnd *scmd)
+{
+	unsigned long interval = 10000; /* 10 seconds interval */
+	int waits = jiffies_to_msecs(PMCRAID_RESET_HOST_TIMEOUT) / interval;
+	struct pmcraid_instance *pinstance =
+		(struct pmcraid_instance *)(scmd->device->host->hostdata);
+
+
+	/* wait for an additional 150 seconds just in case firmware could come
+	 * up and if it could complete all the pending commands excluding the
+	 * two HCAM (CCN and LDN).
+	 */
+	while (waits--) {
+		if (atomic_read(&pinstance->outstanding_cmds) <=
+		    PMCRAID_MAX_HCAM_CMD)
+			return SUCCESS;
+		msleep(interval);
+	}
+
+	dev_err(&pinstance->pdev->dev,
+		"Adapter being reset due to an I/O command timeout.\n");
+	return pmcraid_reset_bringup(pinstance) == 0 ? SUCCESS : FAILED;
+}
+
+/**
+ * pmcraid_task_attributes - Translate SPI Q-Tags to task attributes
+ * @scsi_cmd:   scsi command struct
+ *
+ * Return value
+ *	  number of tags or 0 if the task is not tagged
+ */
+static u8 pmcraid_task_attributes(struct scsi_cmnd *scsi_cmd)
+{
+	char tag[2];
+	u8 rc = 0;
+
+	if (scsi_populate_tag_msg(scsi_cmd, tag)) {
+		switch (tag[0]) {
+		case MSG_SIMPLE_TAG:
+			rc = TASK_TAG_SIMPLE;
+			break;
+		case MSG_HEAD_TAG:
+			rc = TASK_TAG_QUEUE_HEAD;
+			break;
+		case MSG_ORDERED_TAG:
+			rc = TASK_TAG_ORDERED;
+			break;
+		};
+	}
+
+	return rc;
+}
+
+
+/**
+ * pmcraid_init_ioadls - initializes IOADL related fields in IOARCB
+ * @cmd: pmcraid command struct
+ * @sgcount: count of scatter-gather elements
+ *
+ * Return value
+ *   returns pointer pmcraid_ioadl_desc, initialized to point to internal
+ *   or external IOADLs
+ */
+struct pmcraid_ioadl_desc *
+pmcraid_init_ioadls(struct pmcraid_cmd *cmd, int sgcount)
+{
+	struct pmcraid_ioadl_desc *ioadl;
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	int ioadl_count = 0;
+
+	if (ioarcb->add_cmd_param_length)
+		ioadl_count = DIV_ROUND_UP(ioarcb->add_cmd_param_length, 16);
+	ioarcb->ioadl_length =
+		sizeof(struct pmcraid_ioadl_desc) * sgcount;
+
+	if ((sgcount + ioadl_count) > (ARRAY_SIZE(ioarcb->add_data.u.ioadl))) {
+		/* external ioadls start at offset 0x80 from control_block
+		 * structure, re-using 24 out of 27 ioadls part of IOARCB.
+		 * It is necessary to indicate to firmware that driver is
+		 * using ioadls to be treated as external to IOARCB.
+		 */
+		ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
+		ioarcb->ioadl_bus_addr =
+			cpu_to_le64((cmd->ioa_cb_bus_addr) +
+				offsetof(struct pmcraid_ioarcb,
+					add_data.u.ioadl[3]));
+		ioadl = &ioarcb->add_data.u.ioadl[3];
+	} else {
+		ioarcb->ioadl_bus_addr =
+			cpu_to_le64((cmd->ioa_cb_bus_addr) +
+				offsetof(struct pmcraid_ioarcb,
+					add_data.u.ioadl[ioadl_count]));
+
+		ioadl = &ioarcb->add_data.u.ioadl[ioadl_count];
+		ioarcb->ioarcb_bus_addr |=
+				DIV_ROUND_CLOSEST(sgcount + ioadl_count, 8);
+	}
+
+	return ioadl;
+}
+
+/**
+ * pmcraid_build_ioadl - Build a scatter/gather list and map the buffer
+ * @pinstance: pointer to adapter instance structure
+ * @cmd: pmcraid command struct
+ *
+ * This function is invoked by queuecommand entry point while sending a command
+ * to firmware. This builds ioadl descriptors and sets up ioarcb fields.
+ *
+ * Return value:
+ * 	0 on success or -1 on failure
+ */
+static int pmcraid_build_ioadl(
+	struct pmcraid_instance *pinstance,
+	struct pmcraid_cmd *cmd
+)
+{
+	int i, nseg;
+	struct scatterlist *sglist;
+
+	struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd;
+	struct pmcraid_ioarcb *ioarcb = &(cmd->ioa_cb->ioarcb);
+	struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+
+	u32 length = scsi_bufflen(scsi_cmd);
+
+	if (!length)
+		return 0;
+
+	nseg = scsi_dma_map(scsi_cmd);
+
+	if (nseg < 0) {
+		dev_err(&pinstance->pdev->dev, "scsi_map_dma failed!\n");
+		return -1;
+	} else if (nseg > PMCRAID_MAX_IOADLS) {
+		scsi_dma_unmap(scsi_cmd);
+		dev_err(&pinstance->pdev->dev,
+			"sg count is (%d) more than allowed!\n", nseg);
+		return -1;
+	}
+
+	/* Initialize IOARCB data transfer length fields */
+	if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE)
+		ioarcb->request_flags0 |= TRANSFER_DIR_WRITE;
+
+	ioarcb->request_flags0 |= NO_LINK_DESCS;
+	ioarcb->data_transfer_length = cpu_to_le32(length);
+	ioadl = pmcraid_init_ioadls(cmd, nseg);
+
+	/* Initialize IOADL descriptor addresses */
+	scsi_for_each_sg(scsi_cmd, sglist, nseg, i) {
+		ioadl[i].data_len = cpu_to_le32(sg_dma_len(sglist));
+		ioadl[i].address = cpu_to_le64(sg_dma_address(sglist));
+		ioadl[i].flags = 0;
+	}
+	/* setup last descriptor */
+	ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+
+	return 0;
+}
+
+/**
+ * pmcraid_free_sglist - Frees an allocated SG buffer list
+ * @sglist: scatter/gather list pointer
+ *
+ * Free a DMA'able memory previously allocated with pmcraid_alloc_sglist
+ *
+ * Return value:
+ * 	none
+ */
+static void pmcraid_free_sglist(struct pmcraid_sglist *sglist)
+{
+	int i;
+
+	for (i = 0; i < sglist->num_sg; i++)
+		__free_pages(sg_page(&(sglist->scatterlist[i])),
+			     sglist->order);
+
+	kfree(sglist);
+}
+
+/**
+ * pmcraid_alloc_sglist - Allocates memory for a SG list
+ * @buflen: buffer length
+ *
+ * Allocates a DMA'able buffer in chunks and assembles a scatter/gather
+ * list.
+ *
+ * Return value
+ * 	pointer to sglist / NULL on failure
+ */
+static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen)
+{
+	struct pmcraid_sglist *sglist;
+	struct scatterlist *scatterlist;
+	struct page *page;
+	int num_elem, i, j;
+	int sg_size;
+	int order;
+	int bsize_elem;
+
+	sg_size = buflen / (PMCRAID_MAX_IOADLS - 1);
+	order = (sg_size > 0) ? get_order(sg_size) : 0;
+	bsize_elem = PAGE_SIZE * (1 << order);
+
+	/* Determine the actual number of sg entries needed */
+	if (buflen % bsize_elem)
+		num_elem = (buflen / bsize_elem) + 1;
+	else
+		num_elem = buflen / bsize_elem;
+
+	/* Allocate a scatter/gather list for the DMA */
+	sglist = kzalloc(sizeof(struct pmcraid_sglist) +
+			 (sizeof(struct scatterlist) * (num_elem - 1)),
+			 GFP_KERNEL);
+
+	if (sglist == NULL)
+		return NULL;
+
+	scatterlist = sglist->scatterlist;
+	sg_init_table(scatterlist, num_elem);
+	sglist->order = order;
+	sglist->num_sg = num_elem;
+	sg_size = buflen;
+
+	for (i = 0; i < num_elem; i++) {
+		page = alloc_pages(GFP_KERNEL|GFP_DMA, order);
+		if (!page) {
+			for (j = i - 1; j >= 0; j--)
+				__free_pages(sg_page(&scatterlist[j]), order);
+			kfree(sglist);
+			return NULL;
+		}
+
+		sg_set_page(&scatterlist[i], page,
+			sg_size < bsize_elem ? sg_size : bsize_elem, 0);
+		sg_size -= bsize_elem;
+	}
+
+	return sglist;
+}
+
+/**
+ * pmcraid_copy_sglist - Copy user buffer to kernel buffer's SG list
+ * @sglist: scatter/gather list pointer
+ * @buffer: buffer pointer
+ * @len: buffer length
+ * @direction: data transfer direction
+ *
+ * Copy a user buffer into a buffer allocated by pmcraid_alloc_sglist
+ *
+ * Return value:
+ * 0 on success / other on failure
+ */
+static int pmcraid_copy_sglist(
+	struct pmcraid_sglist *sglist,
+	unsigned long buffer,
+	u32 len,
+	int direction
+)
+{
+	struct scatterlist *scatterlist;
+	void *kaddr;
+	int bsize_elem;
+	int i;
+	int rc = 0;
+
+	/* Determine the actual number of bytes per element */
+	bsize_elem = PAGE_SIZE * (1 << sglist->order);
+
+	scatterlist = sglist->scatterlist;
+
+	for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
+		if (direction == DMA_TO_DEVICE)
+			rc = __copy_from_user(kaddr,
+					      (void *)buffer,
+					      bsize_elem);
+		else
+			rc = __copy_to_user((void *)buffer, kaddr, bsize_elem);
+
+		kunmap(page);
+
+		if (rc) {
+			pmcraid_err("failed to copy user data into sg list\n");
+			return -EFAULT;
+		}
+
+		scatterlist[i].length = bsize_elem;
+	}
+
+	if (len % bsize_elem) {
+		struct page *page = sg_page(&scatterlist[i]);
+
+		kaddr = kmap(page);
+
+		if (direction == DMA_TO_DEVICE)
+			rc = __copy_from_user(kaddr,
+					      (void *)buffer,
+					      len % bsize_elem);
+		else
+			rc = __copy_to_user((void *)buffer,
+					    kaddr,
+					    len % bsize_elem);
+
+		kunmap(page);
+
+		scatterlist[i].length = len % bsize_elem;
+	}
+
+	if (rc) {
+		pmcraid_err("failed to copy user data into sg list\n");
+		rc = -EFAULT;
+	}
+
+	return rc;
+}
+
+/**
+ * pmcraid_queuecommand - Queue a mid-layer request
+ * @scsi_cmd: scsi command struct
+ * @done: done function
+ *
+ * This function queues a request generated by the mid-layer. Midlayer calls
+ * this routine within host->lock. Some of the functions called by queuecommand
+ * would use cmd block queue locks (free_pool_lock and pending_pool_lock)
+ *
+ * Return value:
+ *	  0 on success
+ *	  SCSI_MLQUEUE_DEVICE_BUSY if device is busy
+ *	  SCSI_MLQUEUE_HOST_BUSY if host is busy
+ */
+static int pmcraid_queuecommand(
+	struct scsi_cmnd *scsi_cmd,
+	void (*done) (struct scsi_cmnd *)
+)
+{
+	struct pmcraid_instance *pinstance;
+	struct pmcraid_resource_entry *res;
+	struct pmcraid_ioarcb *ioarcb;
+	struct pmcraid_cmd *cmd;
+	int rc = 0;
+
+	pinstance =
+		(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
+
+	scsi_cmd->scsi_done = done;
+	res = scsi_cmd->device->hostdata;
+	scsi_cmd->result = (DID_OK << 16);
+
+	/* if adapter is marked as dead, set result to DID_NO_CONNECT complete
+	 * the command
+	 */
+	if (pinstance->ioa_state == IOA_STATE_DEAD) {
+		pmcraid_info("IOA is dead, but queuecommand is scheduled\n");
+		scsi_cmd->result = (DID_NO_CONNECT << 16);
+		scsi_cmd->scsi_done(scsi_cmd);
+		return 0;
+	}
+
+	/* If IOA reset is in progress, can't queue the commands */
+	if (pinstance->ioa_reset_in_progress)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
+	/* initialize the command and IOARCB to be sent to IOA */
+	cmd = pmcraid_get_free_cmd(pinstance);
+
+	if (cmd == NULL) {
+		pmcraid_err("free command block is not available\n");
+		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+
+	cmd->scsi_cmd = scsi_cmd;
+	ioarcb = &(cmd->ioa_cb->ioarcb);
+	memcpy(ioarcb->cdb, scsi_cmd->cmnd, scsi_cmd->cmd_len);
+	ioarcb->resource_handle = res->cfg_entry.resource_handle;
+	ioarcb->request_type = REQ_TYPE_SCSI;
+
+	cmd->cmd_done = pmcraid_io_done;
+
+	if (RES_IS_GSCSI(res->cfg_entry) || RES_IS_VSET(res->cfg_entry)) {
+		if (scsi_cmd->underflow == 0)
+			ioarcb->request_flags0 |= INHIBIT_UL_CHECK;
+
+		if (res->sync_reqd) {
+			ioarcb->request_flags0 |= SYNC_COMPLETE;
+			res->sync_reqd = 0;
+		}
+
+		ioarcb->request_flags0 |= NO_LINK_DESCS;
+		ioarcb->request_flags1 |= pmcraid_task_attributes(scsi_cmd);
+
+		if (RES_IS_GSCSI(res->cfg_entry))
+			ioarcb->request_flags1 |= DELAY_AFTER_RESET;
+	}
+
+	rc = pmcraid_build_ioadl(pinstance, cmd);
+
+	pmcraid_info("command (%d) CDB[0] = %x for %x:%x:%x:%x\n",
+		     le32_to_cpu(ioarcb->response_handle) >> 2,
+		     scsi_cmd->cmnd[0], pinstance->host->unique_id,
+		     RES_IS_VSET(res->cfg_entry) ? PMCRAID_VSET_BUS_ID :
+			PMCRAID_PHYS_BUS_ID,
+		     RES_IS_VSET(res->cfg_entry) ?
+			res->cfg_entry.unique_flags1 :
+			RES_TARGET(res->cfg_entry.resource_address),
+		     RES_LUN(res->cfg_entry.resource_address));
+
+	if (likely(rc == 0)) {
+		_pmcraid_fire_command(cmd);
+	} else {
+		pmcraid_err("queuecommand could not build ioadl\n");
+		pmcraid_return_cmd(cmd);
+		rc = SCSI_MLQUEUE_HOST_BUSY;
+	}
+
+	return rc;
+}
+
+/**
+ * pmcraid_open -char node "open" entry, allowed only users with admin access
+ */
+static int pmcraid_chr_open(struct inode *inode, struct file *filep)
+{
+	struct pmcraid_instance *pinstance;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	/* Populate adapter instance * pointer for use by ioctl */
+	pinstance = container_of(inode->i_cdev, struct pmcraid_instance, cdev);
+	filep->private_data = pinstance;
+
+	return 0;
+}
+
+/**
+ * pmcraid_release - char node "release" entry point
+ */
+static int pmcraid_chr_release(struct inode *inode, struct file *filep)
+{
+	struct pmcraid_instance *pinstance =
+		((struct pmcraid_instance *)filep->private_data);
+
+	filep->private_data = NULL;
+	fasync_helper(-1, filep, 0, &pinstance->aen_queue);
+
+	return 0;
+}
+
+/**
+ * pmcraid_fasync - Async notifier registration from applications
+ *
+ * This function adds the calling process to a driver global queue. When an
+ * event occurs, SIGIO will be sent to all processes in this queue.
+ */
+static int pmcraid_chr_fasync(int fd, struct file *filep, int mode)
+{
+	struct pmcraid_instance *pinstance;
+	int rc;
+
+	pinstance = (struct pmcraid_instance *)filep->private_data;
+	mutex_lock(&pinstance->aen_queue_lock);
+	rc = fasync_helper(fd, filep, mode, &pinstance->aen_queue);
+	mutex_unlock(&pinstance->aen_queue_lock);
+
+	return rc;
+}
+
+
+/**
+ * pmcraid_build_passthrough_ioadls - builds SG elements for passthrough
+ * commands sent over IOCTL interface
+ *
+ * @cmd       : pointer to struct pmcraid_cmd
+ * @buflen    : length of the request buffer
+ * @direction : data transfer direction
+ *
+ * Return value
+ *  0 on sucess, non-zero error code on failure
+ */
+static int pmcraid_build_passthrough_ioadls(
+	struct pmcraid_cmd *cmd,
+	int buflen,
+	int direction
+)
+{
+	struct pmcraid_sglist *sglist = NULL;
+	struct scatterlist *sg = NULL;
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	struct pmcraid_ioadl_desc *ioadl;
+	int i;
+
+	sglist = pmcraid_alloc_sglist(buflen);
+
+	if (!sglist) {
+		pmcraid_err("can't allocate memory for passthrough SGls\n");
+		return -ENOMEM;
+	}
+
+	sglist->num_dma_sg = pci_map_sg(cmd->drv_inst->pdev,
+					sglist->scatterlist,
+					sglist->num_sg, direction);
+
+	if (!sglist->num_dma_sg || sglist->num_dma_sg > PMCRAID_MAX_IOADLS) {
+		dev_err(&cmd->drv_inst->pdev->dev,
+			"Failed to map passthrough buffer!\n");
+		pmcraid_free_sglist(sglist);
+		return -EIO;
+	}
+
+	cmd->sglist = sglist;
+	ioarcb->request_flags0 |= NO_LINK_DESCS;
+
+	ioadl = pmcraid_init_ioadls(cmd, sglist->num_dma_sg);
+
+	/* Initialize IOADL descriptor addresses */
+	for_each_sg(sglist->scatterlist, sg, sglist->num_dma_sg, i) {
+		ioadl[i].data_len = cpu_to_le32(sg_dma_len(sg));
+		ioadl[i].address = cpu_to_le64(sg_dma_address(sg));
+		ioadl[i].flags = 0;
+	}
+
+	/* setup the last descriptor */
+	ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+
+	return 0;
+}
+
+
+/**
+ * pmcraid_release_passthrough_ioadls - release passthrough ioadls
+ *
+ * @cmd: pointer to struct pmcraid_cmd for which ioadls were allocated
+ * @buflen: size of the request buffer
+ * @direction: data transfer direction
+ *
+ * Return value
+ *  0 on sucess, non-zero error code on failure
+ */
+static void pmcraid_release_passthrough_ioadls(
+	struct pmcraid_cmd *cmd,
+	int buflen,
+	int direction
+)
+{
+	struct pmcraid_sglist *sglist = cmd->sglist;
+
+	if (buflen > 0) {
+		pci_unmap_sg(cmd->drv_inst->pdev,
+			     sglist->scatterlist,
+			     sglist->num_sg,
+			     direction);
+		pmcraid_free_sglist(sglist);
+		cmd->sglist = NULL;
+	}
+}
+
+/**
+ * pmcraid_ioctl_passthrough - handling passthrough IOCTL commands
+ *
+ * @pinstance: pointer to adapter instance structure
+ * @cmd: ioctl code
+ * @arg: pointer to pmcraid_passthrough_buffer user buffer
+ *
+ * Return value
+ *  0 on sucess, non-zero error code on failure
+ */
+static long pmcraid_ioctl_passthrough(
+	struct pmcraid_instance *pinstance,
+	unsigned int ioctl_cmd,
+	unsigned int buflen,
+	unsigned long arg
+)
+{
+	struct pmcraid_passthrough_ioctl_buffer *buffer;
+	struct pmcraid_ioarcb *ioarcb;
+	struct pmcraid_cmd *cmd;
+	struct pmcraid_cmd *cancel_cmd;
+	unsigned long request_buffer;
+	unsigned long request_offset;
+	unsigned long lock_flags;
+	int request_size;
+	int buffer_size;
+	u8 access, direction;
+	int rc = 0;
+
+	/* If IOA reset is in progress, wait 10 secs for reset to complete */
+	if (pinstance->ioa_reset_in_progress) {
+		rc = wait_event_interruptible_timeout(
+				pinstance->reset_wait_q,
+				!pinstance->ioa_reset_in_progress,
+				msecs_to_jiffies(10000));
+
+		if (!rc)
+			return -ETIMEDOUT;
+		else if (rc < 0)
+			return -ERESTARTSYS;
+	}
+
+	/* If adapter is not in operational state, return error */
+	if (pinstance->ioa_state != IOA_STATE_OPERATIONAL) {
+		pmcraid_err("IOA is not operational\n");
+		return -ENOTTY;
+	}
+
+	buffer_size = sizeof(struct pmcraid_passthrough_ioctl_buffer);
+	buffer = kmalloc(buffer_size, GFP_KERNEL);
+
+	if (!buffer) {
+		pmcraid_err("no memory for passthrough buffer\n");
+		return -ENOMEM;
+	}
+
+	request_offset =
+	    offsetof(struct pmcraid_passthrough_ioctl_buffer, request_buffer);
+
+	request_buffer = arg + request_offset;
+
+	rc = __copy_from_user(buffer,
+			     (struct pmcraid_passthrough_ioctl_buffer *) arg,
+			     sizeof(struct pmcraid_passthrough_ioctl_buffer));
+	if (rc) {
+		pmcraid_err("ioctl: can't copy passthrough buffer\n");
+		rc = -EFAULT;
+		goto out_free_buffer;
+	}
+
+	request_size = buffer->ioarcb.data_transfer_length;
+
+	if (buffer->ioarcb.request_flags0 & TRANSFER_DIR_WRITE) {
+		access = VERIFY_READ;
+		direction = DMA_TO_DEVICE;
+	} else {
+		access = VERIFY_WRITE;
+		direction = DMA_FROM_DEVICE;
+	}
+
+	if (request_size > 0) {
+		rc = access_ok(access, arg, request_offset + request_size);
+
+		if (!rc) {
+			rc = -EFAULT;
+			goto out_free_buffer;
+		}
+	}
+
+	/* check if we have any additional command parameters */
+	if (buffer->ioarcb.add_cmd_param_length > PMCRAID_ADD_CMD_PARAM_LEN) {
+		rc = -EINVAL;
+		goto out_free_buffer;
+	}
+
+	cmd = pmcraid_get_free_cmd(pinstance);
+
+	if (!cmd) {
+		pmcraid_err("free command block is not available\n");
+		rc = -ENOMEM;
+		goto out_free_buffer;
+	}
+
+	cmd->scsi_cmd = NULL;
+	ioarcb = &(cmd->ioa_cb->ioarcb);
+
+	/* Copy the user-provided IOARCB stuff field by field */
+	ioarcb->resource_handle = buffer->ioarcb.resource_handle;
+	ioarcb->data_transfer_length = buffer->ioarcb.data_transfer_length;
+	ioarcb->cmd_timeout = buffer->ioarcb.cmd_timeout;
+	ioarcb->request_type = buffer->ioarcb.request_type;
+	ioarcb->request_flags0 = buffer->ioarcb.request_flags0;
+	ioarcb->request_flags1 = buffer->ioarcb.request_flags1;
+	memcpy(ioarcb->cdb, buffer->ioarcb.cdb, PMCRAID_MAX_CDB_LEN);
+
+	if (buffer->ioarcb.add_cmd_param_length) {
+		ioarcb->add_cmd_param_length =
+			buffer->ioarcb.add_cmd_param_length;
+		ioarcb->add_cmd_param_offset =
+			buffer->ioarcb.add_cmd_param_offset;
+		memcpy(ioarcb->add_data.u.add_cmd_params,
+			buffer->ioarcb.add_data.u.add_cmd_params,
+			buffer->ioarcb.add_cmd_param_length);
+	}
+
+	if (request_size) {
+		rc = pmcraid_build_passthrough_ioadls(cmd,
+						      request_size,
+						      direction);
+		if (rc) {
+			pmcraid_err("couldn't build passthrough ioadls\n");
+			goto out_free_buffer;
+		}
+	}
+
+	/* If data is being written into the device, copy the data from user
+	 * buffers
+	 */
+	if (direction == DMA_TO_DEVICE && request_size > 0) {
+		rc = pmcraid_copy_sglist(cmd->sglist,
+					 request_buffer,
+					 request_size,
+					 direction);
+		if (rc) {
+			pmcraid_err("failed to copy user buffer\n");
+			goto out_free_sglist;
+		}
+	}
+
+	/* passthrough ioctl is a blocking command so, put the user to sleep
+	 * until timeout. Note that a timeout value of 0 means, do timeout.
+	 */
+	cmd->cmd_done = pmcraid_internal_done;
+	init_completion(&cmd->wait_for_completion);
+	cmd->completion_req = 1;
+
+	pmcraid_info("command(%d) (CDB[0] = %x) for %x\n",
+		     le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle) >> 2,
+		     cmd->ioa_cb->ioarcb.cdb[0],
+		     le32_to_cpu(cmd->ioa_cb->ioarcb.resource_handle));
+
+	spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+	_pmcraid_fire_command(cmd);
+	spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+
+	/* If command timeout is specified put caller to wait till that time,
+	 * otherwise it would be blocking wait. If command gets timed out, it
+	 * will be aborted.
+	 */
+	if (buffer->ioarcb.cmd_timeout == 0) {
+		wait_for_completion(&cmd->wait_for_completion);
+	} else if (!wait_for_completion_timeout(
+			&cmd->wait_for_completion,
+			msecs_to_jiffies(buffer->ioarcb.cmd_timeout * 1000))) {
+
+		pmcraid_info("aborting cmd %d (CDB[0] = %x) due to timeout\n",
+			le32_to_cpu(cmd->ioa_cb->ioarcb.response_handle >> 2),
+			cmd->ioa_cb->ioarcb.cdb[0]);
+
+		rc = -ETIMEDOUT;
+		spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+		cancel_cmd = pmcraid_abort_cmd(cmd);
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+
+		if (cancel_cmd) {
+			wait_for_completion(&cancel_cmd->wait_for_completion);
+			pmcraid_return_cmd(cancel_cmd);
+		}
+
+		goto out_free_sglist;
+	}
+
+	/* If the command failed for any reason, copy entire IOASA buffer and
+	 * return IOCTL success. If copying IOASA to user-buffer fails, return
+	 * EFAULT
+	 */
+	if (le32_to_cpu(cmd->ioa_cb->ioasa.ioasc)) {
+
+		void *ioasa =
+		    (void *)(arg +
+		    offsetof(struct pmcraid_passthrough_ioctl_buffer, ioasa));
+
+		pmcraid_info("command failed with %x\n",
+			     le32_to_cpu(cmd->ioa_cb->ioasa.ioasc));
+		if (copy_to_user(ioasa, &cmd->ioa_cb->ioasa,
+				 sizeof(struct pmcraid_ioasa))) {
+			pmcraid_err("failed to copy ioasa buffer to user\n");
+			rc = -EFAULT;
+		}
+	}
+	/* If the data transfer was from device, copy the data onto user
+	 * buffers
+	 */
+	else if (direction == DMA_FROM_DEVICE && request_size > 0) {
+		rc = pmcraid_copy_sglist(cmd->sglist,
+					 request_buffer,
+					 request_size,
+					 direction);
+		if (rc) {
+			pmcraid_err("failed to copy user buffer\n");
+			rc = -EFAULT;
+		}
+	}
+
+out_free_sglist:
+	pmcraid_release_passthrough_ioadls(cmd, request_size, direction);
+	pmcraid_return_cmd(cmd);
+
+out_free_buffer:
+	kfree(buffer);
+
+	return rc;
+}
+
+
+
+
+/**
+ * pmcraid_ioctl_driver - ioctl handler for commands handled by driver itself
+ *
+ * @pinstance: pointer to adapter instance structure
+ * @cmd: ioctl command passed in
+ * @buflen: length of user_buffer
+ * @user_buffer: user buffer pointer
+ *
+ * Return Value
+ *   0 in case of success, otherwise appropriate error code
+ */
+static long pmcraid_ioctl_driver(
+	struct pmcraid_instance *pinstance,
+	unsigned int cmd,
+	unsigned int buflen,
+	void __user *user_buffer
+)
+{
+	int rc = -ENOSYS;
+
+	if (!access_ok(VERIFY_READ, user_buffer, _IOC_SIZE(cmd))) {
+		pmcraid_err("ioctl_driver: access fault in request buffer \n");
+		return -EFAULT;
+	}
+
+	switch (cmd) {
+	case PMCRAID_IOCTL_RESET_ADAPTER:
+		pmcraid_reset_bringup(pinstance);
+		rc = 0;
+		break;
+
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+/**
+ * pmcraid_check_ioctl_buffer - check for proper access to user buffer
+ *
+ * @cmd: ioctl command
+ * @arg: user buffer
+ * @hdr: pointer to kernel memory for pmcraid_ioctl_header
+ *
+ * Return Value
+ *	negetive error code if there are access issues, otherwise zero.
+ *	Upon success, returns ioctl header copied out of user buffer.
+ */
+
+static int pmcraid_check_ioctl_buffer(
+	int cmd,
+	void __user *arg,
+	struct pmcraid_ioctl_header *hdr
+)
+{
+	int rc = 0;
+	int access = VERIFY_READ;
+
+	if (copy_from_user(hdr, arg, sizeof(struct pmcraid_ioctl_header))) {
+		pmcraid_err("couldn't copy ioctl header from user buffer\n");
+		return -EFAULT;
+	}
+
+	/* check for valid driver signature */
+	rc = memcmp(hdr->signature,
+		    PMCRAID_IOCTL_SIGNATURE,
+		    sizeof(hdr->signature));
+	if (rc) {
+		pmcraid_err("signature verification failed\n");
+		return -EINVAL;
+	}
+
+	/* buffer length can't be negetive */
+	if (hdr->buffer_length < 0) {
+		pmcraid_err("ioctl: invalid buffer length specified\n");
+		return -EINVAL;
+	}
+
+	/* check for appropriate buffer access */
+	if ((_IOC_DIR(cmd) & _IOC_READ) == _IOC_READ)
+		access = VERIFY_WRITE;
+
+	rc = access_ok(access,
+		       (arg + sizeof(struct pmcraid_ioctl_header)),
+		       hdr->buffer_length);
+	if (!rc) {
+		pmcraid_err("access failed for user buffer of size %d\n",
+			     hdr->buffer_length);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/**
+ *  pmcraid_ioctl - char node ioctl entry point
+ */
+static long pmcraid_chr_ioctl(
+	struct file *filep,
+	unsigned int cmd,
+	unsigned long arg
+)
+{
+	struct pmcraid_instance *pinstance = NULL;
+	struct pmcraid_ioctl_header *hdr = NULL;
+	int retval = -ENOTTY;
+
+	hdr = kmalloc(GFP_KERNEL, sizeof(struct pmcraid_ioctl_header));
+
+	if (!hdr) {
+		pmcraid_err("faile to allocate memory for ioctl header\n");
+		return -ENOMEM;
+	}
+
+	retval = pmcraid_check_ioctl_buffer(cmd, (void *)arg, hdr);
+
+	if (retval) {
+		pmcraid_info("chr_ioctl: header check failed\n");
+		kfree(hdr);
+		return retval;
+	}
+
+	pinstance = (struct pmcraid_instance *)filep->private_data;
+
+	if (!pinstance) {
+		pmcraid_info("adapter instance is not found\n");
+		kfree(hdr);
+		return -ENOTTY;
+	}
+
+	switch (_IOC_TYPE(cmd)) {
+
+	case PMCRAID_PASSTHROUGH_IOCTL:
+		/* If ioctl code is to download microcode, we need to block
+		 * mid-layer requests.
+		 */
+		if (cmd == PMCRAID_IOCTL_DOWNLOAD_MICROCODE)
+			scsi_block_requests(pinstance->host);
+
+		retval = pmcraid_ioctl_passthrough(pinstance,
+						   cmd,
+						   hdr->buffer_length,
+						   arg);
+
+		if (cmd == PMCRAID_IOCTL_DOWNLOAD_MICROCODE)
+			scsi_unblock_requests(pinstance->host);
+		break;
+
+	case PMCRAID_DRIVER_IOCTL:
+		arg += sizeof(struct pmcraid_ioctl_header);
+		retval = pmcraid_ioctl_driver(pinstance,
+					      cmd,
+					      hdr->buffer_length,
+					      (void __user *)arg);
+		break;
+
+	default:
+		retval = -ENOTTY;
+		break;
+	}
+
+	kfree(hdr);
+
+	return retval;
+}
+
+/**
+ * File operations structure for management interface
+ */
+static const struct file_operations pmcraid_fops = {
+	.owner = THIS_MODULE,
+	.open = pmcraid_chr_open,
+	.release = pmcraid_chr_release,
+	.fasync = pmcraid_chr_fasync,
+	.unlocked_ioctl = pmcraid_chr_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = pmcraid_chr_ioctl,
+#endif
+};
+
+
+
+
+/**
+ * pmcraid_show_log_level - Display adapter's error logging level
+ * @dev: class device struct
+ * @buf: buffer
+ *
+ * Return value:
+ *  number of bytes printed to buffer
+ */
+static ssize_t pmcraid_show_log_level(
+	struct device *dev,
+	struct device_attribute *attr,
+	char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct pmcraid_instance *pinstance =
+		(struct pmcraid_instance *)shost->hostdata;
+	return snprintf(buf, PAGE_SIZE, "%d\n", pinstance->current_log_level);
+}
+
+/**
+ * pmcraid_store_log_level - Change the adapter's error logging level
+ * @dev: class device struct
+ * @buf: buffer
+ * @count: not used
+ *
+ * Return value:
+ *  number of bytes printed to buffer
+ */
+static ssize_t pmcraid_store_log_level(
+	struct device *dev,
+	struct device_attribute *attr,
+	const char *buf,
+	size_t count
+)
+{
+	struct Scsi_Host *shost;
+	struct pmcraid_instance *pinstance;
+	unsigned long val;
+
+	if (strict_strtoul(buf, 10, &val))
+		return -EINVAL;
+	/* log-level should be from 0 to 2 */
+	if (val > 2)
+		return -EINVAL;
+
+	shost = class_to_shost(dev);
+	pinstance = (struct pmcraid_instance *)shost->hostdata;
+	pinstance->current_log_level = val;
+
+	return strlen(buf);
+}
+
+static struct device_attribute pmcraid_log_level_attr = {
+	.attr = {
+		 .name = "log_level",
+		 .mode = S_IRUGO | S_IWUSR,
+		 },
+	.show = pmcraid_show_log_level,
+	.store = pmcraid_store_log_level,
+};
+
+/**
+ * pmcraid_show_drv_version - Display driver version
+ * @dev: class device struct
+ * @buf: buffer
+ *
+ * Return value:
+ *  number of bytes printed to buffer
+ */
+static ssize_t pmcraid_show_drv_version(
+	struct device *dev,
+	struct device_attribute *attr,
+	char *buf
+)
+{
+	return snprintf(buf, PAGE_SIZE, "version: %s, build date: %s\n",
+			PMCRAID_DRIVER_VERSION, PMCRAID_DRIVER_DATE);
+}
+
+static struct device_attribute pmcraid_driver_version_attr = {
+	.attr = {
+		 .name = "drv_version",
+		 .mode = S_IRUGO,
+		 },
+	.show = pmcraid_show_drv_version,
+};
+
+/**
+ * pmcraid_show_io_adapter_id - Display driver assigned adapter id
+ * @dev: class device struct
+ * @buf: buffer
+ *
+ * Return value:
+ *  number of bytes printed to buffer
+ */
+static ssize_t pmcraid_show_adapter_id(
+	struct device *dev,
+	struct device_attribute *attr,
+	char *buf
+)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct pmcraid_instance *pinstance =
+		(struct pmcraid_instance *)shost->hostdata;
+	u32 adapter_id = (pinstance->pdev->bus->number << 8) |
+		pinstance->pdev->devfn;
+	u32 aen_group = pmcraid_event_family.id;
+
+	return snprintf(buf, PAGE_SIZE,
+			"adapter id: %d\nminor: %d\naen group: %d\n",
+			adapter_id, MINOR(pinstance->cdev.dev), aen_group);
+}
+
+static struct device_attribute pmcraid_adapter_id_attr = {
+	.attr = {
+		 .name = "adapter_id",
+		 .mode = S_IRUGO | S_IWUSR,
+		 },
+	.show = pmcraid_show_adapter_id,
+};
+
+static struct device_attribute *pmcraid_host_attrs[] = {
+	&pmcraid_log_level_attr,
+	&pmcraid_driver_version_attr,
+	&pmcraid_adapter_id_attr,
+	NULL,
+};
+
+
+/* host template structure for pmcraid driver */
+static struct scsi_host_template pmcraid_host_template = {
+	.module = THIS_MODULE,
+	.name = PMCRAID_DRIVER_NAME,
+	.queuecommand = pmcraid_queuecommand,
+	.eh_abort_handler = pmcraid_eh_abort_handler,
+	.eh_bus_reset_handler = pmcraid_eh_bus_reset_handler,
+	.eh_target_reset_handler = pmcraid_eh_target_reset_handler,
+	.eh_device_reset_handler = pmcraid_eh_device_reset_handler,
+	.eh_host_reset_handler = pmcraid_eh_host_reset_handler,
+
+	.slave_alloc = pmcraid_slave_alloc,
+	.slave_configure = pmcraid_slave_configure,
+	.slave_destroy = pmcraid_slave_destroy,
+	.change_queue_depth = pmcraid_change_queue_depth,
+	.change_queue_type  = pmcraid_change_queue_type,
+	.can_queue = PMCRAID_MAX_IO_CMD,
+	.this_id = -1,
+	.sg_tablesize = PMCRAID_MAX_IOADLS,
+	.max_sectors = PMCRAID_IOA_MAX_SECTORS,
+	.cmd_per_lun = PMCRAID_MAX_CMD_PER_LUN,
+	.use_clustering = ENABLE_CLUSTERING,
+	.shost_attrs = pmcraid_host_attrs,
+	.proc_name = PMCRAID_DRIVER_NAME
+};
+
+/**
+ * pmcraid_isr_common - Common interrupt handler routine
+ *
+ * @pinstance: pointer to adapter instance
+ * @intrs: active interrupts (contents of ioa_host_interrupt register)
+ * @hrrq_id: Host RRQ index
+ *
+ * Return Value
+ *	none
+ */
+static void pmcraid_isr_common(
+	struct pmcraid_instance *pinstance,
+	u32 intrs,
+	int hrrq_id
+)
+{
+	u32 intrs_clear =
+		(intrs & INTRS_CRITICAL_OP_IN_PROGRESS) ? intrs
+							: INTRS_HRRQ_VALID;
+	iowrite32(intrs_clear,
+		  pinstance->int_regs.ioa_host_interrupt_clr_reg);
+	intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
+
+	/* hrrq valid bit was set, schedule tasklet to handle the response */
+	if (intrs_clear == INTRS_HRRQ_VALID)
+		tasklet_schedule(&(pinstance->isr_tasklet[hrrq_id]));
+}
+
+/**
+ * pmcraid_isr  - implements interrupt handling routine
+ *
+ * @irq: interrupt vector number
+ * @dev_id: pointer hrrq_vector
+ *
+ * Return Value
+ *	 IRQ_HANDLED if interrupt is handled or IRQ_NONE if ignored
+ */
+static irqreturn_t pmcraid_isr(int irq, void *dev_id)
+{
+	struct pmcraid_isr_param *hrrq_vector;
+	struct pmcraid_instance *pinstance;
+	unsigned long lock_flags;
+	u32 intrs;
+
+	/* In case of legacy interrupt mode where interrupts are shared across
+	 * isrs, it may be possible that the current interrupt is not from IOA
+	 */
+	if (!dev_id) {
+		printk(KERN_INFO "%s(): NULL host pointer\n", __func__);
+		return IRQ_NONE;
+	}
+
+	hrrq_vector = (struct pmcraid_isr_param *)dev_id;
+	pinstance = hrrq_vector->drv_inst;
+
+	/* Acquire the lock (currently host_lock) while processing interrupts.
+	 * This interval is small as most of the response processing is done by
+	 * tasklet without the lock.
+	 */
+	spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
+	intrs = pmcraid_read_interrupts(pinstance);
+
+	if (unlikely((intrs & PMCRAID_PCI_INTERRUPTS) == 0)) {
+		spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+		return IRQ_NONE;
+	}
+
+	/* Any error interrupts including unit_check, initiate IOA reset.
+	 * In case of unit check indicate to reset_sequence that IOA unit
+	 * checked and prepare for a dump during reset sequence
+	 */
+	if (intrs & PMCRAID_ERROR_INTERRUPTS) {
+
+		if (intrs & INTRS_IOA_UNIT_CHECK)
+			pinstance->ioa_unit_check = 1;
+
+		iowrite32(intrs,
+			  pinstance->int_regs.ioa_host_interrupt_clr_reg);
+		pmcraid_err("ISR: error interrupts: %x initiating reset\n",
+			    intrs);
+		intrs = ioread32(pinstance->int_regs.ioa_host_interrupt_reg);
+		pmcraid_initiate_reset(pinstance);
+	} else {
+		pmcraid_isr_common(pinstance, intrs, hrrq_vector->hrrq_id);
+	}
+
+	spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags);
+
+	return IRQ_HANDLED;
+}
+
+
+/**
+ * pmcraid_worker_function -  worker thread function
+ *
+ * @workp: pointer to struct work queue
+ *
+ * Return Value
+ *	 None
+ */
+
+static void pmcraid_worker_function(struct work_struct *workp)
+{
+	struct pmcraid_instance *pinstance;
+	struct pmcraid_resource_entry *res;
+	struct pmcraid_resource_entry *temp;
+	struct scsi_device *sdev;
+	unsigned long lock_flags;
+	unsigned long host_lock_flags;
+	u8 bus, target, lun;
+
+	pinstance = container_of(workp, struct pmcraid_instance, worker_q);
+	/* add resources only after host is added into system */
+	if (!atomic_read(&pinstance->expose_resources))
+		return;
+
+	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
+	list_for_each_entry_safe(res, temp, &pinstance->used_res_q, queue) {
+
+		if (res->change_detected == RES_CHANGE_DEL && res->scsi_dev) {
+			sdev = res->scsi_dev;
+
+			/* host_lock must be held before calling
+			 * scsi_device_get
+			 */
+			spin_lock_irqsave(pinstance->host->host_lock,
+					  host_lock_flags);
+			if (!scsi_device_get(sdev)) {
+				spin_unlock_irqrestore(
+						pinstance->host->host_lock,
+						host_lock_flags);
+				pmcraid_info("deleting %x from midlayer\n",
+					     res->cfg_entry.resource_address);
+				list_move_tail(&res->queue,
+						&pinstance->free_res_q);
+				spin_unlock_irqrestore(
+					&pinstance->resource_lock,
+					lock_flags);
+				scsi_remove_device(sdev);
+				scsi_device_put(sdev);
+				spin_lock_irqsave(&pinstance->resource_lock,
+						   lock_flags);
+				res->change_detected = 0;
+			} else {
+				spin_unlock_irqrestore(
+						pinstance->host->host_lock,
+						host_lock_flags);
+			}
+		}
+	}
+
+	list_for_each_entry(res, &pinstance->used_res_q, queue) {
+
+		if (res->change_detected == RES_CHANGE_ADD) {
+
+			if (!pmcraid_expose_resource(&res->cfg_entry))
+				continue;
+
+			if (RES_IS_VSET(res->cfg_entry)) {
+				bus = PMCRAID_VSET_BUS_ID;
+				target = res->cfg_entry.unique_flags1;
+				lun = PMCRAID_VSET_LUN_ID;
+			} else {
+				bus = PMCRAID_PHYS_BUS_ID;
+				target =
+				     RES_TARGET(
+					res->cfg_entry.resource_address);
+				lun = RES_LUN(res->cfg_entry.resource_address);
+			}
+
+			res->change_detected = 0;
+			spin_unlock_irqrestore(&pinstance->resource_lock,
+						lock_flags);
+			scsi_add_device(pinstance->host, bus, target, lun);
+			spin_lock_irqsave(&pinstance->resource_lock,
+					   lock_flags);
+		}
+	}
+
+	spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
+}
+
+/**
+ * pmcraid_tasklet_function - Tasklet function
+ *
+ * @instance: pointer to msix param structure
+ *
+ * Return Value
+ *	None
+ */
+void pmcraid_tasklet_function(unsigned long instance)
+{
+	struct pmcraid_isr_param *hrrq_vector;
+	struct pmcraid_instance *pinstance;
+	unsigned long hrrq_lock_flags;
+	unsigned long pending_lock_flags;
+	unsigned long host_lock_flags;
+	spinlock_t *lockp; /* hrrq buffer lock */
+	int id;
+	u32 intrs;
+	__le32 resp;
+
+	hrrq_vector = (struct pmcraid_isr_param *)instance;
+	pinstance = hrrq_vector->drv_inst;
+	id = hrrq_vector->hrrq_id;
+	lockp = &(pinstance->hrrq_lock[id]);
+	intrs = pmcraid_read_interrupts(pinstance);
+
+	/* If interrupts was as part of the ioa initialization, clear and mask
+	 * it. Delete the timer and wakeup the reset engine to proceed with
+	 * reset sequence
+	 */
+	if (intrs & INTRS_TRANSITION_TO_OPERATIONAL) {
+		iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
+			pinstance->int_regs.ioa_host_interrupt_mask_reg);
+		iowrite32(INTRS_TRANSITION_TO_OPERATIONAL,
+			pinstance->int_regs.ioa_host_interrupt_clr_reg);
+
+		if (pinstance->reset_cmd != NULL) {
+			del_timer(&pinstance->reset_cmd->timer);
+			spin_lock_irqsave(pinstance->host->host_lock,
+					  host_lock_flags);
+			pinstance->reset_cmd->cmd_done(pinstance->reset_cmd);
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       host_lock_flags);
+		}
+		return;
+	}
+
+	/* loop through each of the commands responded by IOA. Each HRRQ buf is
+	 * protected by its own lock. Traversals must be done within this lock
+	 * as there may be multiple tasklets running on multiple CPUs. Note
+	 * that the lock is held just for picking up the response handle and
+	 * manipulating hrrq_curr/toggle_bit values.
+	 */
+	spin_lock_irqsave(lockp, hrrq_lock_flags);
+
+	resp = le32_to_cpu(*(pinstance->hrrq_curr[id]));
+
+	while ((resp & HRRQ_TOGGLE_BIT) ==
+		pinstance->host_toggle_bit[id]) {
+
+		int cmd_index = resp >> 2;
+		struct pmcraid_cmd *cmd = NULL;
+
+		if (cmd_index < PMCRAID_MAX_CMD) {
+			cmd = pinstance->cmd_list[cmd_index];
+		} else {
+			/* In case of invalid response handle, initiate IOA
+			 * reset sequence.
+			 */
+			spin_unlock_irqrestore(lockp, hrrq_lock_flags);
+
+			pmcraid_err("Invalid response %d initiating reset\n",
+				    cmd_index);
+
+			spin_lock_irqsave(pinstance->host->host_lock,
+					  host_lock_flags);
+			pmcraid_initiate_reset(pinstance);
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       host_lock_flags);
+
+			spin_lock_irqsave(lockp, hrrq_lock_flags);
+			break;
+		}
+
+		if (pinstance->hrrq_curr[id] < pinstance->hrrq_end[id]) {
+			pinstance->hrrq_curr[id]++;
+		} else {
+			pinstance->hrrq_curr[id] = pinstance->hrrq_start[id];
+			pinstance->host_toggle_bit[id] ^= 1u;
+		}
+
+		spin_unlock_irqrestore(lockp, hrrq_lock_flags);
+
+		spin_lock_irqsave(&pinstance->pending_pool_lock,
+				   pending_lock_flags);
+		list_del(&cmd->free_list);
+		spin_unlock_irqrestore(&pinstance->pending_pool_lock,
+					pending_lock_flags);
+		del_timer(&cmd->timer);
+		atomic_dec(&pinstance->outstanding_cmds);
+
+		if (cmd->cmd_done == pmcraid_ioa_reset) {
+			spin_lock_irqsave(pinstance->host->host_lock,
+					  host_lock_flags);
+			cmd->cmd_done(cmd);
+			spin_unlock_irqrestore(pinstance->host->host_lock,
+					       host_lock_flags);
+		} else if (cmd->cmd_done != NULL) {
+			cmd->cmd_done(cmd);
+		}
+		/* loop over until we are done with all responses */
+		spin_lock_irqsave(lockp, hrrq_lock_flags);
+		resp = le32_to_cpu(*(pinstance->hrrq_curr[id]));
+	}
+
+	spin_unlock_irqrestore(lockp, hrrq_lock_flags);
+}
+
+/**
+ * pmcraid_unregister_interrupt_handler - de-register interrupts handlers
+ * @pinstance: pointer to adapter instance structure
+ *
+ * This routine un-registers registered interrupt handler and
+ * also frees irqs/vectors.
+ *
+ * Retun Value
+ *	None
+ */
+static
+void pmcraid_unregister_interrupt_handler(struct pmcraid_instance *pinstance)
+{
+	free_irq(pinstance->pdev->irq, &(pinstance->hrrq_vector[0]));
+}
+
+/**
+ * pmcraid_register_interrupt_handler - registers interrupt handler
+ * @pinstance: pointer to per-adapter instance structure
+ *
+ * Return Value
+ *	0 on success, non-zero error code otherwise.
+ */
+static int
+pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance)
+{
+	struct pci_dev *pdev = pinstance->pdev;
+
+	pinstance->hrrq_vector[0].hrrq_id = 0;
+	pinstance->hrrq_vector[0].drv_inst = pinstance;
+	pinstance->hrrq_vector[0].vector = 0;
+	pinstance->num_hrrq = 1;
+	return request_irq(pdev->irq, pmcraid_isr, IRQF_SHARED,
+			   PMCRAID_DRIVER_NAME, &pinstance->hrrq_vector[0]);
+}
+
+/**
+ * pmcraid_release_cmd_blocks - release buufers allocated for command blocks
+ * @pinstance: per adapter instance structure pointer
+ * @max_index: number of buffer blocks to release
+ *
+ * Return Value
+ *  None
+ */
+static void
+pmcraid_release_cmd_blocks(struct pmcraid_instance *pinstance, int max_index)
+{
+	int i;
+	for (i = 0; i < max_index; i++) {
+		kmem_cache_free(pinstance->cmd_cachep, pinstance->cmd_list[i]);
+		pinstance->cmd_list[i] = NULL;
+	}
+	kmem_cache_destroy(pinstance->cmd_cachep);
+	pinstance->cmd_cachep = NULL;
+}
+
+/**
+ * pmcraid_release_control_blocks - releases buffers alloced for control blocks
+ * @pinstance: pointer to per adapter instance structure
+ * @max_index: number of buffers (from 0 onwards) to release
+ *
+ * This function assumes that the command blocks for which control blocks are
+ * linked are not released.
+ *
+ * Return Value
+ *	 None
+ */
+static void
+pmcraid_release_control_blocks(
+	struct pmcraid_instance *pinstance,
+	int max_index
+)
+{
+	int i;
+
+	if (pinstance->control_pool == NULL)
+		return;
+
+	for (i = 0; i < max_index; i++) {
+		pci_pool_free(pinstance->control_pool,
+			      pinstance->cmd_list[i]->ioa_cb,
+			      pinstance->cmd_list[i]->ioa_cb_bus_addr);
+		pinstance->cmd_list[i]->ioa_cb = NULL;
+		pinstance->cmd_list[i]->ioa_cb_bus_addr = 0;
+	}
+	pci_pool_destroy(pinstance->control_pool);
+	pinstance->control_pool = NULL;
+}
+
+/**
+ * pmcraid_allocate_cmd_blocks - allocate memory for cmd block structures
+ * @pinstance - pointer to per adapter instance structure
+ *
+ * Allocates memory for command blocks using kernel slab allocator.
+ *
+ * Return Value
+ *	0 in case of success; -ENOMEM in case of failure
+ */
+static int __devinit
+pmcraid_allocate_cmd_blocks(struct pmcraid_instance *pinstance)
+{
+	int i;
+
+	sprintf(pinstance->cmd_pool_name, "pmcraid_cmd_pool_%d",
+		pinstance->host->unique_id);
+
+
+	pinstance->cmd_cachep = kmem_cache_create(
+					pinstance->cmd_pool_name,
+					sizeof(struct pmcraid_cmd), 0,
+					SLAB_HWCACHE_ALIGN, NULL);
+	if (!pinstance->cmd_cachep)
+		return -ENOMEM;
+
+	for (i = 0; i < PMCRAID_MAX_CMD; i++) {
+		pinstance->cmd_list[i] =
+			kmem_cache_alloc(pinstance->cmd_cachep, GFP_KERNEL);
+		if (!pinstance->cmd_list[i]) {
+			pmcraid_release_cmd_blocks(pinstance, i);
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
+/**
+ * pmcraid_allocate_control_blocks - allocates memory control blocks
+ * @pinstance : pointer to per adapter instance structure
+ *
+ * This function allocates PCI memory for DMAable buffers like IOARCB, IOADLs
+ * and IOASAs. This is called after command blocks are already allocated.
+ *
+ * Return Value
+ *  0 in case it can allocate all control blocks, otherwise -ENOMEM
+ */
+static int __devinit
+pmcraid_allocate_control_blocks(struct pmcraid_instance *pinstance)
+{
+	int i;
+
+	sprintf(pinstance->ctl_pool_name, "pmcraid_control_pool_%d",
+		pinstance->host->unique_id);
+
+	pinstance->control_pool =
+		pci_pool_create(pinstance->ctl_pool_name,
+				pinstance->pdev,
+				sizeof(struct pmcraid_control_block),
+				PMCRAID_IOARCB_ALIGNMENT, 0);
+
+	if (!pinstance->control_pool)
+		return -ENOMEM;
+
+	for (i = 0; i < PMCRAID_MAX_CMD; i++) {
+		pinstance->cmd_list[i]->ioa_cb =
+			pci_pool_alloc(
+				pinstance->control_pool,
+				GFP_KERNEL,
+				&(pinstance->cmd_list[i]->ioa_cb_bus_addr));
+
+		if (!pinstance->cmd_list[i]->ioa_cb) {
+			pmcraid_release_control_blocks(pinstance, i);
+			return -ENOMEM;
+		}
+		memset(pinstance->cmd_list[i]->ioa_cb, 0,
+			sizeof(struct pmcraid_control_block));
+	}
+	return 0;
+}
+
+/**
+ * pmcraid_release_host_rrqs - release memory allocated for hrrq buffer(s)
+ * @pinstance: pointer to per adapter instance structure
+ * @maxindex: size of hrrq buffer pointer array
+ *
+ * Return Value
+ *	None
+ */
+static void
+pmcraid_release_host_rrqs(struct pmcraid_instance *pinstance, int maxindex)
+{
+	int i;
+	for (i = 0; i < maxindex; i++) {
+
+		pci_free_consistent(pinstance->pdev,
+				    HRRQ_ENTRY_SIZE * PMCRAID_MAX_CMD,
+				    pinstance->hrrq_start[i],
+				    pinstance->hrrq_start_bus_addr[i]);
+
+		/* reset pointers and toggle bit to zeros */
+		pinstance->hrrq_start[i] = NULL;
+		pinstance->hrrq_start_bus_addr[i] = 0;
+		pinstance->host_toggle_bit[i] = 0;
+	}
+}
+
+/**
+ * pmcraid_allocate_host_rrqs - Allocate and initialize host RRQ buffers
+ * @pinstance: pointer to per adapter instance structure
+ *
+ * Return value
+ *	0 hrrq buffers are allocated, -ENOMEM otherwise.
+ */
+static int __devinit
+pmcraid_allocate_host_rrqs(struct pmcraid_instance *pinstance)
+{
+	int i;
+	int buf_count = PMCRAID_MAX_CMD / pinstance->num_hrrq;
+
+	for (i = 0; i < pinstance->num_hrrq; i++) {
+		int buffer_size = HRRQ_ENTRY_SIZE * buf_count;
+
+		pinstance->hrrq_start[i] =
+			pci_alloc_consistent(
+					pinstance->pdev,
+					buffer_size,
+					&(pinstance->hrrq_start_bus_addr[i]));
+
+		if (pinstance->hrrq_start[i] == 0) {
+			pmcraid_err("could not allocate host rrq: %d\n", i);
+			pmcraid_release_host_rrqs(pinstance, i);
+			return -ENOMEM;
+		}
+
+		memset(pinstance->hrrq_start[i], 0, buffer_size);
+		pinstance->hrrq_curr[i] = pinstance->hrrq_start[i];
+		pinstance->hrrq_end[i] =
+			pinstance->hrrq_start[i] + buf_count - 1;
+		pinstance->host_toggle_bit[i] = 1;
+		spin_lock_init(&pinstance->hrrq_lock[i]);
+	}
+	return 0;
+}
+
+/**
+ * pmcraid_release_hcams - release HCAM buffers
+ *
+ * @pinstance: pointer to per adapter instance structure
+ *
+ * Return value
+ *  none
+ */
+static void pmcraid_release_hcams(struct pmcraid_instance *pinstance)
+{
+	if (pinstance->ccn.msg != NULL) {
+		pci_free_consistent(pinstance->pdev,
+				    PMCRAID_AEN_HDR_SIZE +
+				    sizeof(struct pmcraid_hcam_ccn),
+				    pinstance->ccn.msg,
+				    pinstance->ccn.baddr);
+
+		pinstance->ccn.msg = NULL;
+		pinstance->ccn.hcam = NULL;
+		pinstance->ccn.baddr = 0;
+	}
+
+	if (pinstance->ldn.msg != NULL) {
+		pci_free_consistent(pinstance->pdev,
+				    PMCRAID_AEN_HDR_SIZE +
+				    sizeof(struct pmcraid_hcam_ldn),
+				    pinstance->ldn.msg,
+				    pinstance->ldn.baddr);
+
+		pinstance->ldn.msg = NULL;
+		pinstance->ldn.hcam = NULL;
+		pinstance->ldn.baddr = 0;
+	}
+}
+
+/**
+ * pmcraid_allocate_hcams - allocates HCAM buffers
+ * @pinstance : pointer to per adapter instance structure
+ *
+ * Return Value:
+ *   0 in case of successful allocation, non-zero otherwise
+ */
+static int pmcraid_allocate_hcams(struct pmcraid_instance *pinstance)
+{
+	pinstance->ccn.msg = pci_alloc_consistent(
+					pinstance->pdev,
+					PMCRAID_AEN_HDR_SIZE +
+					sizeof(struct pmcraid_hcam_ccn),
+					&(pinstance->ccn.baddr));
+
+	pinstance->ldn.msg = pci_alloc_consistent(
+					pinstance->pdev,
+					PMCRAID_AEN_HDR_SIZE +
+					sizeof(struct pmcraid_hcam_ldn),
+					&(pinstance->ldn.baddr));
+
+	if (pinstance->ldn.msg == NULL || pinstance->ccn.msg == NULL) {
+		pmcraid_release_hcams(pinstance);
+	} else {
+		pinstance->ccn.hcam =
+			(void *)pinstance->ccn.msg + PMCRAID_AEN_HDR_SIZE;
+		pinstance->ldn.hcam =
+			(void *)pinstance->ldn.msg + PMCRAID_AEN_HDR_SIZE;
+
+		atomic_set(&pinstance->ccn.ignore, 0);
+		atomic_set(&pinstance->ldn.ignore, 0);
+	}
+
+	return (pinstance->ldn.msg == NULL) ? -ENOMEM : 0;
+}
+
+/**
+ * pmcraid_release_config_buffers - release config.table buffers
+ * @pinstance: pointer to per adapter instance structure
+ *
+ * Return Value
+ *	 none
+ */
+static void pmcraid_release_config_buffers(struct pmcraid_instance *pinstance)
+{
+	if (pinstance->cfg_table != NULL &&
+	    pinstance->cfg_table_bus_addr != 0) {
+		pci_free_consistent(pinstance->pdev,
+				    sizeof(struct pmcraid_config_table),
+				    pinstance->cfg_table,
+				    pinstance->cfg_table_bus_addr);
+		pinstance->cfg_table = NULL;
+		pinstance->cfg_table_bus_addr = 0;
+	}
+
+	if (pinstance->res_entries != NULL) {
+		int i;
+
+		for (i = 0; i < PMCRAID_MAX_RESOURCES; i++)
+			list_del(&pinstance->res_entries[i].queue);
+		kfree(pinstance->res_entries);
+		pinstance->res_entries = NULL;
+	}
+
+	pmcraid_release_hcams(pinstance);
+}
+
+/**
+ * pmcraid_allocate_config_buffers - allocates DMAable memory for config table
+ * @pinstance : pointer to per adapter instance structure
+ *
+ * Return Value
+ *	0 for successful allocation, -ENOMEM for any failure
+ */
+static int __devinit
+pmcraid_allocate_config_buffers(struct pmcraid_instance *pinstance)
+{
+	int i;
+
+	pinstance->res_entries =
+			kzalloc(sizeof(struct pmcraid_resource_entry) *
+				PMCRAID_MAX_RESOURCES, GFP_KERNEL);
+
+	if (NULL == pinstance->res_entries) {
+		pmcraid_err("failed to allocate memory for resource table\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < PMCRAID_MAX_RESOURCES; i++)
+		list_add_tail(&pinstance->res_entries[i].queue,
+			      &pinstance->free_res_q);
+
+	pinstance->cfg_table =
+		pci_alloc_consistent(pinstance->pdev,
+				     sizeof(struct pmcraid_config_table),
+				     &pinstance->cfg_table_bus_addr);
+
+	if (NULL == pinstance->cfg_table) {
+		pmcraid_err("couldn't alloc DMA memory for config table\n");
+		pmcraid_release_config_buffers(pinstance);
+		return -ENOMEM;
+	}
+
+	if (pmcraid_allocate_hcams(pinstance)) {
+		pmcraid_err("could not alloc DMA memory for HCAMS\n");
+		pmcraid_release_config_buffers(pinstance);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * pmcraid_init_tasklets - registers tasklets for response handling
+ *
+ * @pinstance: pointer adapter instance structure
+ *
+ * Return value
+ *	none
+ */
+static void pmcraid_init_tasklets(struct pmcraid_instance *pinstance)
+{
+	int i;
+	for (i = 0; i < pinstance->num_hrrq; i++)
+		tasklet_init(&pinstance->isr_tasklet[i],
+			     pmcraid_tasklet_function,
+			     (unsigned long)&pinstance->hrrq_vector[i]);
+}
+
+/**
+ * pmcraid_kill_tasklets - destroys tasklets registered for response handling
+ *
+ * @pinstance: pointer to adapter instance structure
+ *
+ * Return value
+ *	none
+ */
+static void pmcraid_kill_tasklets(struct pmcraid_instance *pinstance)
+{
+	int i;
+	for (i = 0; i < pinstance->num_hrrq; i++)
+		tasklet_kill(&pinstance->isr_tasklet[i]);
+}
+
+/**
+ * pmcraid_init_buffers - allocates memory and initializes various structures
+ * @pinstance: pointer to per adapter instance structure
+ *
+ * This routine pre-allocates memory based on the type of block as below:
+ * cmdblocks(PMCRAID_MAX_CMD): kernel memory using kernel's slab_allocator,
+ * IOARCBs(PMCRAID_MAX_CMD)  : DMAable memory, using pci pool allocator
+ * config-table entries      : DMAable memory using pci_alloc_consistent
+ * HostRRQs                  : DMAable memory, using pci_alloc_consistent
+ *
+ * Return Value
+ *	 0 in case all of the blocks are allocated, -ENOMEM otherwise.
+ */
+static int __devinit pmcraid_init_buffers(struct pmcraid_instance *pinstance)
+{
+	int i;
+
+	if (pmcraid_allocate_host_rrqs(pinstance)) {
+		pmcraid_err("couldn't allocate memory for %d host rrqs\n",
+			     pinstance->num_hrrq);
+		return -ENOMEM;
+	}
+
+	if (pmcraid_allocate_config_buffers(pinstance)) {
+		pmcraid_err("couldn't allocate memory for config buffers\n");
+		pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
+		return -ENOMEM;
+	}
+
+	if (pmcraid_allocate_cmd_blocks(pinstance)) {
+		pmcraid_err("couldn't allocate memory for cmd blocks \n");
+		pmcraid_release_config_buffers(pinstance);
+		pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
+		return -ENOMEM;
+	}
+
+	if (pmcraid_allocate_control_blocks(pinstance)) {
+		pmcraid_err("couldn't allocate memory control blocks \n");
+		pmcraid_release_config_buffers(pinstance);
+		pmcraid_release_cmd_blocks(pinstance, PMCRAID_MAX_CMD);
+		pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
+		return -ENOMEM;
+	}
+
+	/* Initialize all the command blocks and add them to free pool. No
+	 * need to lock (free_pool_lock) as this is done in initialization
+	 * itself
+	 */
+	for (i = 0; i < PMCRAID_MAX_CMD; i++) {
+		struct pmcraid_cmd *cmdp = pinstance->cmd_list[i];
+		pmcraid_init_cmdblk(cmdp, i);
+		cmdp->drv_inst = pinstance;
+		list_add_tail(&cmdp->free_list, &pinstance->free_cmd_pool);
+	}
+
+	return 0;
+}
+
+/**
+ * pmcraid_reinit_buffers - resets various buffer pointers
+ * @pinstance: pointer to adapter instance
+ * Return value
+ * 	none
+ */
+static void pmcraid_reinit_buffers(struct pmcraid_instance *pinstance)
+{
+	int i;
+	int buffer_size = HRRQ_ENTRY_SIZE * PMCRAID_MAX_CMD;
+
+	for (i = 0; i < pinstance->num_hrrq; i++) {
+		memset(pinstance->hrrq_start[i], 0, buffer_size);
+		pinstance->hrrq_curr[i] = pinstance->hrrq_start[i];
+		pinstance->hrrq_end[i] =
+			pinstance->hrrq_start[i] + PMCRAID_MAX_CMD - 1;
+		pinstance->host_toggle_bit[i] = 1;
+	}
+}
+
+/**
+ * pmcraid_init_instance - initialize per instance data structure
+ * @pdev: pointer to pci device structure
+ * @host: pointer to Scsi_Host structure
+ * @mapped_pci_addr: memory mapped IOA configuration registers
+ *
+ * Return Value
+ *	 0 on success, non-zero in case of any failure
+ */
+static int __devinit pmcraid_init_instance(
+	struct pci_dev *pdev,
+	struct Scsi_Host *host,
+	void __iomem *mapped_pci_addr
+)
+{
+	struct pmcraid_instance *pinstance =
+		(struct pmcraid_instance *)host->hostdata;
+
+	pinstance->host = host;
+	pinstance->pdev = pdev;
+
+	/* Initialize register addresses */
+	pinstance->mapped_dma_addr = mapped_pci_addr;
+
+	/* Initialize chip-specific details */
+	{
+		struct pmcraid_chip_details *chip_cfg = pinstance->chip_cfg;
+		struct pmcraid_interrupts *pint_regs = &pinstance->int_regs;
+
+		pinstance->ioarrin = mapped_pci_addr + chip_cfg->ioarrin;
+
+		pint_regs->ioa_host_interrupt_reg =
+			mapped_pci_addr + chip_cfg->ioa_host_intr;
+		pint_regs->ioa_host_interrupt_clr_reg =
+			mapped_pci_addr + chip_cfg->ioa_host_intr_clr;
+		pint_regs->host_ioa_interrupt_reg =
+			mapped_pci_addr + chip_cfg->host_ioa_intr;
+		pint_regs->host_ioa_interrupt_clr_reg =
+			mapped_pci_addr + chip_cfg->host_ioa_intr_clr;
+
+		/* Current version of firmware exposes interrupt mask set
+		 * and mask clr registers through memory mapped bar0.
+		 */
+		pinstance->mailbox = mapped_pci_addr + chip_cfg->mailbox;
+		pinstance->ioa_status = mapped_pci_addr + chip_cfg->ioastatus;
+		pint_regs->ioa_host_interrupt_mask_reg =
+			mapped_pci_addr + chip_cfg->ioa_host_mask;
+		pint_regs->ioa_host_interrupt_mask_clr_reg =
+			mapped_pci_addr + chip_cfg->ioa_host_mask_clr;
+		pint_regs->global_interrupt_mask_reg =
+			mapped_pci_addr + chip_cfg->global_intr_mask;
+	};
+
+	pinstance->ioa_reset_attempts = 0;
+	init_waitqueue_head(&pinstance->reset_wait_q);
+
+	atomic_set(&pinstance->outstanding_cmds, 0);
+	atomic_set(&pinstance->expose_resources, 0);
+
+	INIT_LIST_HEAD(&pinstance->free_res_q);
+	INIT_LIST_HEAD(&pinstance->used_res_q);
+	INIT_LIST_HEAD(&pinstance->free_cmd_pool);
+	INIT_LIST_HEAD(&pinstance->pending_cmd_pool);
+
+	spin_lock_init(&pinstance->free_pool_lock);
+	spin_lock_init(&pinstance->pending_pool_lock);
+	spin_lock_init(&pinstance->resource_lock);
+	mutex_init(&pinstance->aen_queue_lock);
+
+	/* Work-queue (Shared) for deferred processing error handling */
+	INIT_WORK(&pinstance->worker_q, pmcraid_worker_function);
+
+	/* Initialize the default log_level */
+	pinstance->current_log_level = pmcraid_log_level;
+
+	/* Setup variables required for reset engine */
+	pinstance->ioa_state = IOA_STATE_UNKNOWN;
+	pinstance->reset_cmd = NULL;
+	return 0;
+}
+
+/**
+ * pmcraid_release_buffers - release per-adapter buffers allocated
+ *
+ * @pinstance: pointer to adapter soft state
+ *
+ * Return Value
+ * 	none
+ */
+static void pmcraid_release_buffers(struct pmcraid_instance *pinstance)
+{
+	pmcraid_release_config_buffers(pinstance);
+	pmcraid_release_control_blocks(pinstance, PMCRAID_MAX_CMD);
+	pmcraid_release_cmd_blocks(pinstance, PMCRAID_MAX_CMD);
+	pmcraid_release_host_rrqs(pinstance, pinstance->num_hrrq);
+
+}
+
+/**
+ * pmcraid_shutdown - shutdown adapter controller.
+ * @pdev: pci device struct
+ *
+ * Issues an adapter shutdown to the card waits for its completion
+ *
+ * Return value
+ *	  none
+ */
+static void pmcraid_shutdown(struct pci_dev *pdev)
+{
+	struct pmcraid_instance *pinstance = pci_get_drvdata(pdev);
+	pmcraid_reset_bringdown(pinstance);
+}
+
+
+/**
+ * pmcraid_get_minor - returns unused minor number from minor number bitmap
+ */
+static unsigned short pmcraid_get_minor(void)
+{
+	int minor;
+
+	minor = find_first_zero_bit(pmcraid_minor, sizeof(pmcraid_minor));
+	__set_bit(minor, pmcraid_minor);
+	return minor;
+}
+
+/**
+ * pmcraid_release_minor - releases given minor back to minor number bitmap
+ */
+static void pmcraid_release_minor(unsigned short minor)
+{
+	__clear_bit(minor, pmcraid_minor);
+}
+
+/**
+ * pmcraid_setup_chrdev - allocates a minor number and registers a char device
+ *
+ * @pinstance: pointer to adapter instance for which to register device
+ *
+ * Return value
+ *	0 in case of success, otherwise non-zero
+ */
+static int pmcraid_setup_chrdev(struct pmcraid_instance *pinstance)
+{
+	int minor;
+	int error;
+
+	minor = pmcraid_get_minor();
+	cdev_init(&pinstance->cdev, &pmcraid_fops);
+	pinstance->cdev.owner = THIS_MODULE;
+
+	error = cdev_add(&pinstance->cdev, MKDEV(pmcraid_major, minor), 1);
+
+	if (error)
+		pmcraid_release_minor(minor);
+	else
+		device_create(pmcraid_class, NULL, MKDEV(pmcraid_major, minor),
+			      NULL, "pmcsas%u", minor);
+	return error;
+}
+
+/**
+ * pmcraid_release_chrdev - unregisters per-adapter management interface
+ *
+ * @pinstance: pointer to adapter instance structure
+ *
+ * Return value
+ *  none
+ */
+static void pmcraid_release_chrdev(struct pmcraid_instance *pinstance)
+{
+	pmcraid_release_minor(MINOR(pinstance->cdev.dev));
+	device_destroy(pmcraid_class,
+		       MKDEV(pmcraid_major, MINOR(pinstance->cdev.dev)));
+	cdev_del(&pinstance->cdev);
+}
+
+/**
+ * pmcraid_remove - IOA hot plug remove entry point
+ * @pdev: pci device struct
+ *
+ * Return value
+ *	  none
+ */
+static void __devexit pmcraid_remove(struct pci_dev *pdev)
+{
+	struct pmcraid_instance *pinstance = pci_get_drvdata(pdev);
+
+	/* remove the management interface (/dev file) for this device */
+	pmcraid_release_chrdev(pinstance);
+
+	/* remove host template from scsi midlayer */
+	scsi_remove_host(pinstance->host);
+
+	/* block requests from mid-layer */
+	scsi_block_requests(pinstance->host);
+
+	/* initiate shutdown adapter */
+	pmcraid_shutdown(pdev);
+
+	pmcraid_disable_interrupts(pinstance, ~0);
+	flush_scheduled_work();
+
+	pmcraid_kill_tasklets(pinstance);
+	pmcraid_unregister_interrupt_handler(pinstance);
+	pmcraid_release_buffers(pinstance);
+	iounmap(pinstance->mapped_dma_addr);
+	pci_release_regions(pdev);
+	scsi_host_put(pinstance->host);
+	pci_disable_device(pdev);
+
+	return;
+}
+
+#ifdef CONFIG_PM
+/**
+ * pmcraid_suspend - driver suspend entry point for power management
+ * @pdev:   PCI device structure
+ * @state:  PCI power state to suspend routine
+ *
+ * Return Value - 0 always
+ */
+static int pmcraid_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct pmcraid_instance *pinstance = pci_get_drvdata(pdev);
+
+	pmcraid_shutdown(pdev);
+	pmcraid_disable_interrupts(pinstance, ~0);
+	pmcraid_kill_tasklets(pinstance);
+	pci_set_drvdata(pinstance->pdev, pinstance);
+	pmcraid_unregister_interrupt_handler(pinstance);
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+/**
+ * pmcraid_resume - driver resume entry point PCI power management
+ * @pdev: PCI device structure
+ *
+ * Return Value - 0 in case of success. Error code in case of any failure
+ */
+static int pmcraid_resume(struct pci_dev *pdev)
+{
+	struct pmcraid_instance *pinstance = pci_get_drvdata(pdev);
+	struct Scsi_Host *host = pinstance->host;
+	int rc;
+	int hrrqs;
+
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_restore_state(pdev);
+
+	rc = pci_enable_device(pdev);
+
+	if (rc) {
+		pmcraid_err("pmcraid: Enable device failed\n");
+		return rc;
+	}
+
+	pci_set_master(pdev);
+
+	if ((sizeof(dma_addr_t) == 4) ||
+	     pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
+	if (rc == 0)
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+
+	if (rc != 0) {
+		dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
+		goto disable_device;
+	}
+
+	atomic_set(&pinstance->outstanding_cmds, 0);
+	hrrqs = pinstance->num_hrrq;
+	rc = pmcraid_register_interrupt_handler(pinstance);
+
+	if (rc) {
+		pmcraid_err("resume: couldn't register interrupt handlers\n");
+		rc = -ENODEV;
+		goto release_host;
+	}
+
+	pmcraid_init_tasklets(pinstance);
+	pmcraid_enable_interrupts(pinstance, PMCRAID_PCI_INTERRUPTS);
+
+	/* Start with hard reset sequence which brings up IOA to operational
+	 * state as well as completes the reset sequence.
+	 */
+	pinstance->ioa_hard_reset = 1;
+
+	/* Start IOA firmware initialization and bring card to Operational
+	 * state.
+	 */
+	if (pmcraid_reset_bringup(pinstance)) {
+		pmcraid_err("couldn't initialize IOA \n");
+		rc = -ENODEV;
+		goto release_tasklets;
+	}
+
+	return 0;
+
+release_tasklets:
+	pmcraid_kill_tasklets(pinstance);
+	pmcraid_unregister_interrupt_handler(pinstance);
+
+release_host:
+	scsi_host_put(host);
+
+disable_device:
+	pci_disable_device(pdev);
+
+	return rc;
+}
+
+#else
+
+#define pmcraid_suspend NULL
+#define pmcraid_resume  NULL
+
+#endif /* CONFIG_PM */
+
+/**
+ * pmcraid_complete_ioa_reset - Called by either timer or tasklet during
+ * 	                        completion of the ioa reset
+ * @cmd: pointer to reset command block
+ */
+static void pmcraid_complete_ioa_reset(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	unsigned long flags;
+
+	spin_lock_irqsave(pinstance->host->host_lock, flags);
+	pmcraid_ioa_reset(cmd);
+	spin_unlock_irqrestore(pinstance->host->host_lock, flags);
+	scsi_unblock_requests(pinstance->host);
+	schedule_work(&pinstance->worker_q);
+}
+
+/**
+ * pmcraid_set_supported_devs - sends SET SUPPORTED DEVICES to IOAFP
+ *
+ * @cmd: pointer to pmcraid_cmd structure
+ *
+ * Return Value
+ *  0 for success or non-zero for failure cases
+ */
+static void pmcraid_set_supported_devs(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	void (*cmd_done) (struct pmcraid_cmd *) = pmcraid_complete_ioa_reset;
+
+	pmcraid_reinit_cmdblk(cmd);
+
+	ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
+	ioarcb->request_type = REQ_TYPE_IOACMD;
+	ioarcb->cdb[0] = PMCRAID_SET_SUPPORTED_DEVICES;
+	ioarcb->cdb[1] = ALL_DEVICES_SUPPORTED;
+
+	/* If this was called as part of resource table reinitialization due to
+	 * lost CCN, it is enough to return the command block back to free pool
+	 * as part of set_supported_devs completion function.
+	 */
+	if (cmd->drv_inst->reinit_cfg_table) {
+		cmd->drv_inst->reinit_cfg_table = 0;
+		cmd->release = 1;
+		cmd_done = pmcraid_reinit_cfgtable_done;
+	}
+
+	/* we will be done with the reset sequence after set supported devices,
+	 * setup the done function to return the command block back to free
+	 * pool
+	 */
+	pmcraid_send_cmd(cmd,
+			 cmd_done,
+			 PMCRAID_SET_SUP_DEV_TIMEOUT,
+			 pmcraid_timeout_handler);
+	return;
+}
+
+/**
+ * pmcraid_init_res_table - Initialize the resource table
+ * @cmd:  pointer to pmcraid command struct
+ *
+ * This function looks through the existing resource table, comparing
+ * it with the config table. This function will take care of old/new
+ * devices and schedule adding/removing them from the mid-layer
+ * as appropriate.
+ *
+ * Return value
+ *	 None
+ */
+static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	struct pmcraid_resource_entry *res, *temp;
+	struct pmcraid_config_table_entry *cfgte;
+	unsigned long lock_flags;
+	int found, rc, i;
+	LIST_HEAD(old_res);
+
+	if (pinstance->cfg_table->flags & MICROCODE_UPDATE_REQUIRED)
+		dev_err(&pinstance->pdev->dev, "Require microcode download\n");
+
+	/* resource list is protected by pinstance->resource_lock.
+	 * init_res_table can be called from probe (user-thread) or runtime
+	 * reset (timer/tasklet)
+	 */
+	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
+
+	list_for_each_entry_safe(res, temp, &pinstance->used_res_q, queue)
+		list_move_tail(&res->queue, &old_res);
+
+	for (i = 0; i < pinstance->cfg_table->num_entries; i++) {
+		cfgte = &pinstance->cfg_table->entries[i];
+
+		if (!pmcraid_expose_resource(cfgte))
+			continue;
+
+		found = 0;
+
+		/* If this entry was already detected and initialized */
+		list_for_each_entry_safe(res, temp, &old_res, queue) {
+
+			rc = memcmp(&res->cfg_entry.resource_address,
+				    &cfgte->resource_address,
+				    sizeof(cfgte->resource_address));
+			if (!rc) {
+				list_move_tail(&res->queue,
+						&pinstance->used_res_q);
+				found = 1;
+				break;
+			}
+		}
+
+		/* If this is new entry, initialize it and add it the queue */
+		if (!found) {
+
+			if (list_empty(&pinstance->free_res_q)) {
+				dev_err(&pinstance->pdev->dev,
+					"Too many devices attached\n");
+				break;
+			}
+
+			found = 1;
+			res = list_entry(pinstance->free_res_q.next,
+					 struct pmcraid_resource_entry, queue);
+
+			res->scsi_dev = NULL;
+			res->change_detected = RES_CHANGE_ADD;
+			res->reset_progress = 0;
+			list_move_tail(&res->queue, &pinstance->used_res_q);
+		}
+
+		/* copy new configuration table entry details into driver
+		 * maintained resource entry
+		 */
+		if (found) {
+			memcpy(&res->cfg_entry, cfgte,
+				sizeof(struct pmcraid_config_table_entry));
+			pmcraid_info("New res type:%x, vset:%x, addr:%x:\n",
+				 res->cfg_entry.resource_type,
+				 res->cfg_entry.unique_flags1,
+				 le32_to_cpu(res->cfg_entry.resource_address));
+		}
+	}
+
+	/* Detect any deleted entries, mark them for deletion from mid-layer */
+	list_for_each_entry_safe(res, temp, &old_res, queue) {
+
+		if (res->scsi_dev) {
+			res->change_detected = RES_CHANGE_DEL;
+			res->cfg_entry.resource_handle =
+				PMCRAID_INVALID_RES_HANDLE;
+			list_move_tail(&res->queue, &pinstance->used_res_q);
+		} else {
+			list_move_tail(&res->queue, &pinstance->free_res_q);
+		}
+	}
+
+	/* release the resource list lock */
+	spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
+	pmcraid_set_supported_devs(cmd);
+}
+
+/**
+ * pmcraid_querycfg - Send a Query IOA Config to the adapter.
+ * @cmd: pointer pmcraid_cmd struct
+ *
+ * This function sends a Query IOA Configuration command to the adapter to
+ * retrieve the IOA configuration table.
+ *
+ * Return value:
+ *	none
+ */
+static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
+{
+	struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb;
+	struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl;
+	struct pmcraid_instance *pinstance = cmd->drv_inst;
+	int cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table));
+
+	ioarcb->request_type = REQ_TYPE_IOACMD;
+	ioarcb->resource_handle = cpu_to_le32(PMCRAID_IOA_RES_HANDLE);
+
+	ioarcb->cdb[0] = PMCRAID_QUERY_IOA_CONFIG;
+
+	/* firmware requires 4-byte length field, specified in B.E format */
+	memcpy(&(ioarcb->cdb[10]), &cfg_table_size, sizeof(cfg_table_size));
+
+	/* Since entire config table can be described by single IOADL, it can
+	 * be part of IOARCB itself
+	 */
+	ioarcb->ioadl_bus_addr = cpu_to_le64((cmd->ioa_cb_bus_addr) +
+					offsetof(struct pmcraid_ioarcb,
+						add_data.u.ioadl[0]));
+	ioarcb->ioadl_length = cpu_to_le32(sizeof(struct pmcraid_ioadl_desc));
+	ioarcb->ioarcb_bus_addr &= ~(0x1FULL);
+
+	ioarcb->request_flags0 |= NO_LINK_DESCS;
+	ioarcb->data_transfer_length =
+		cpu_to_le32(sizeof(struct pmcraid_config_table));
+
+	ioadl = &(ioarcb->add_data.u.ioadl[0]);
+	ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+	ioadl->address = cpu_to_le64(pinstance->cfg_table_bus_addr);
+	ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_config_table));
+
+	pmcraid_send_cmd(cmd, pmcraid_init_res_table,
+			 PMCRAID_INTERNAL_TIMEOUT, pmcraid_timeout_handler);
+}
+
+
+/**
+ * pmcraid_probe - PCI probe entry pointer for PMC MaxRaid controller driver
+ * @pdev: pointer to pci device structure
+ * @dev_id: pointer to device ids structure
+ *
+ * Return Value
+ *	returns 0 if the device is claimed and successfully configured.
+ *	returns non-zero error code in case of any failure
+ */
+static int __devinit pmcraid_probe(
+	struct pci_dev *pdev,
+	const struct pci_device_id *dev_id
+)
+{
+	struct pmcraid_instance *pinstance;
+	struct Scsi_Host *host;
+	void __iomem *mapped_pci_addr;
+	int rc = PCIBIOS_SUCCESSFUL;
+
+	if (atomic_read(&pmcraid_adapter_count) >= PMCRAID_MAX_ADAPTERS) {
+		pmcraid_err
+			("maximum number(%d) of supported adapters reached\n",
+			 atomic_read(&pmcraid_adapter_count));
+		return -ENOMEM;
+	}
+
+	atomic_inc(&pmcraid_adapter_count);
+	rc = pci_enable_device(pdev);
+
+	if (rc) {
+		dev_err(&pdev->dev, "Cannot enable adapter\n");
+		atomic_dec(&pmcraid_adapter_count);
+		return rc;
+	}
+
+	dev_info(&pdev->dev,
+		"Found new IOA(%x:%x), Total IOA count: %d\n",
+		 pdev->vendor, pdev->device,
+		 atomic_read(&pmcraid_adapter_count));
+
+	rc = pci_request_regions(pdev, PMCRAID_DRIVER_NAME);
+
+	if (rc < 0) {
+		dev_err(&pdev->dev,
+			"Couldn't register memory range of registers\n");
+		goto out_disable_device;
+	}
+
+	mapped_pci_addr = pci_iomap(pdev, 0, 0);
+
+	if (!mapped_pci_addr) {
+		dev_err(&pdev->dev, "Couldn't map PCI registers memory\n");
+		rc = -ENOMEM;
+		goto out_release_regions;
+	}
+
+	pci_set_master(pdev);
+
+	/* Firmware requires the system bus address of IOARCB to be within
+	 * 32-bit addressable range though it has 64-bit IOARRIN register.
+	 * However, firmware supports 64-bit streaming DMA buffers, whereas
+	 * coherent buffers are to be 32-bit. Since pci_alloc_consistent always
+	 * returns memory within 4GB (if not, change this logic), coherent
+	 * buffers are within firmware acceptible address ranges.
+	 */
+	if ((sizeof(dma_addr_t) == 4) ||
+	    pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
+		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
+	/* firmware expects 32-bit DMA addresses for IOARRIN register; set 32
+	 * bit mask for pci_alloc_consistent to return addresses within 4GB
+	 */
+	if (rc == 0)
+		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+
+	if (rc != 0) {
+		dev_err(&pdev->dev, "Failed to set PCI DMA mask\n");
+		goto cleanup_nomem;
+	}
+
+	host = scsi_host_alloc(&pmcraid_host_template,
+				sizeof(struct pmcraid_instance));
+
+	if (!host) {
+		dev_err(&pdev->dev, "scsi_host_alloc failed!\n");
+		rc = -ENOMEM;
+		goto cleanup_nomem;
+	}
+
+	host->max_id = PMCRAID_MAX_NUM_TARGETS_PER_BUS;
+	host->max_lun = PMCRAID_MAX_NUM_LUNS_PER_TARGET;
+	host->unique_id = host->host_no;
+	host->max_channel = PMCRAID_MAX_BUS_TO_SCAN;
+	host->max_cmd_len = PMCRAID_MAX_CDB_LEN;
+
+	/* zero out entire instance structure */
+	pinstance = (struct pmcraid_instance *)host->hostdata;
+	memset(pinstance, 0, sizeof(*pinstance));
+
+	pinstance->chip_cfg =
+		(struct pmcraid_chip_details *)(dev_id->driver_data);
+
+	rc = pmcraid_init_instance(pdev, host, mapped_pci_addr);
+
+	if (rc < 0) {
+		dev_err(&pdev->dev, "failed to initialize adapter instance\n");
+		goto out_scsi_host_put;
+	}
+
+	pci_set_drvdata(pdev, pinstance);
+
+	/* Save PCI config-space for use following the reset */
+	rc = pci_save_state(pinstance->pdev);
+
+	if (rc != 0) {
+		dev_err(&pdev->dev, "Failed to save PCI config space\n");
+		goto out_scsi_host_put;
+	}
+
+	pmcraid_disable_interrupts(pinstance, ~0);
+
+	rc = pmcraid_register_interrupt_handler(pinstance);
+
+	if (rc) {
+		pmcraid_err("couldn't register interrupt handler\n");
+		goto out_scsi_host_put;
+	}
+
+	pmcraid_init_tasklets(pinstance);
+
+	/* allocate verious buffers used by LLD.*/
+	rc = pmcraid_init_buffers(pinstance);
+
+	if (rc) {
+		pmcraid_err("couldn't allocate memory blocks\n");
+		goto out_unregister_isr;
+	}
+
+	/* check the reset type required */
+	pmcraid_reset_type(pinstance);
+
+	pmcraid_enable_interrupts(pinstance, PMCRAID_PCI_INTERRUPTS);
+
+	/* Start IOA firmware initialization and bring card to Operational
+	 * state.
+	 */
+	pmcraid_info("starting IOA initialization sequence\n");
+	if (pmcraid_reset_bringup(pinstance)) {
+		pmcraid_err("couldn't initialize IOA \n");
+		rc = 1;
+		goto out_release_bufs;
+	}
+
+	/* Add adapter instance into mid-layer list */
+	rc = scsi_add_host(pinstance->host, &pdev->dev);
+	if (rc != 0) {
+		pmcraid_err("couldn't add host into mid-layer: %d\n", rc);
+		goto out_release_bufs;
+	}
+
+	scsi_scan_host(pinstance->host);
+
+	rc = pmcraid_setup_chrdev(pinstance);
+
+	if (rc != 0) {
+		pmcraid_err("couldn't create mgmt interface, error: %x\n",
+			     rc);
+		goto out_remove_host;
+	}
+
+	/* Schedule worker thread to handle CCN and take care of adding and
+	 * removing devices to OS
+	 */
+	atomic_set(&pinstance->expose_resources, 1);
+	schedule_work(&pinstance->worker_q);
+	return rc;
+
+out_remove_host:
+	scsi_remove_host(host);
+
+out_release_bufs:
+	pmcraid_release_buffers(pinstance);
+
+out_unregister_isr:
+	pmcraid_kill_tasklets(pinstance);
+	pmcraid_unregister_interrupt_handler(pinstance);
+
+out_scsi_host_put:
+	scsi_host_put(host);
+
+cleanup_nomem:
+	iounmap(mapped_pci_addr);
+
+out_release_regions:
+	pci_release_regions(pdev);
+
+out_disable_device:
+	atomic_dec(&pmcraid_adapter_count);
+	pci_set_drvdata(pdev, NULL);
+	pci_disable_device(pdev);
+	return -ENODEV;
+}
+
+/*
+ * PCI driver structure of pcmraid driver
+ */
+static struct pci_driver pmcraid_driver = {
+	.name = PMCRAID_DRIVER_NAME,
+	.id_table = pmcraid_pci_table,
+	.probe = pmcraid_probe,
+	.remove = pmcraid_remove,
+	.suspend = pmcraid_suspend,
+	.resume = pmcraid_resume,
+	.shutdown = pmcraid_shutdown
+};
+
+
+/**
+ * pmcraid_init - module load entry point
+ */
+static int __init pmcraid_init(void)
+{
+	dev_t dev;
+	int error;
+
+	pmcraid_info("%s Device Driver version: %s %s\n",
+			 PMCRAID_DRIVER_NAME,
+			 PMCRAID_DRIVER_VERSION, PMCRAID_DRIVER_DATE);
+
+	error = alloc_chrdev_region(&dev, 0,
+				    PMCRAID_MAX_ADAPTERS,
+				    PMCRAID_DEVFILE);
+
+	if (error) {
+		pmcraid_err("failed to get a major number for adapters\n");
+		goto out_init;
+	}
+
+	pmcraid_major = MAJOR(dev);
+	pmcraid_class = class_create(THIS_MODULE, PMCRAID_DEVFILE);
+
+	if (IS_ERR(pmcraid_class)) {
+		error = PTR_ERR(pmcraid_class);
+		pmcraid_err("failed to register with with sysfs, error = %x\n",
+			    error);
+		goto out_unreg_chrdev;
+	}
+
+
+	error = pmcraid_netlink_init();
+
+	if (error)
+		goto out_unreg_chrdev;
+
+	error = pci_register_driver(&pmcraid_driver);
+
+	if (error == 0)
+		goto out_init;
+
+	pmcraid_err("failed to register pmcraid driver, error = %x\n",
+		     error);
+	class_destroy(pmcraid_class);
+	pmcraid_netlink_release();
+
+out_unreg_chrdev:
+	unregister_chrdev_region(MKDEV(pmcraid_major, 0), PMCRAID_MAX_ADAPTERS);
+out_init:
+	return error;
+}
+
+/**
+ * pmcraid_exit - module unload entry point
+ */
+static void __exit pmcraid_exit(void)
+{
+	pmcraid_netlink_release();
+	class_destroy(pmcraid_class);
+	unregister_chrdev_region(MKDEV(pmcraid_major, 0),
+				 PMCRAID_MAX_ADAPTERS);
+	pci_unregister_driver(&pmcraid_driver);
+}
+
+module_init(pmcraid_init);
+module_exit(pmcraid_exit);
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h
new file mode 100644
index 0000000..614b3a7
--- /dev/null
+++ b/drivers/scsi/pmcraid.h
@@ -0,0 +1,1029 @@
+/*
+ * pmcraid.h -- PMC Sierra MaxRAID controller driver header file
+ *
+ * Copyright (C) 2008, 2009 PMC Sierra 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 _PMCRAID_H
+#define _PMCRAID_H
+
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/completion.h>
+#include <linux/list.h>
+#include <scsi/scsi.h>
+#include <linux/kref.h>
+#include <scsi/scsi_cmnd.h>
+#include <linux/cdev.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include <linux/connector.h>
+/*
+ * Driver name   : string representing the driver name
+ * Device file   : /dev file to be used for management interfaces
+ * Driver version: version string in major_version.minor_version.patch format
+ * Driver date   : date information in "Mon dd yyyy" format
+ */
+#define PMCRAID_DRIVER_NAME       	"PMC MaxRAID"
+#define PMCRAID_DEVFILE			"pmcsas"
+#define PMCRAID_DRIVER_VERSION    	"1.0.2"
+#define PMCRAID_DRIVER_DATE       	__DATE__
+
+/* Maximum number of adapters supported by current version of the driver */
+#define PMCRAID_MAX_ADAPTERS		1024
+
+/* Bit definitions as per firmware, bit position [0][1][2].....[31] */
+#define PMC_BIT8(n)          (1 << (7-n))
+#define PMC_BIT16(n)         (1 << (15-n))
+#define PMC_BIT32(n)         (1 << (31-n))
+
+/* PMC PCI vendor ID and device ID values */
+#define PCI_VENDOR_ID_PMC			0x11F8
+#define PCI_DEVICE_ID_PMC_MAXRAID		0x5220
+
+/*
+ * MAX_CMD          : maximum commands that can be outstanding with IOA
+ * MAX_IO_CMD       : command blocks available for IO commands
+ * MAX_HCAM_CMD     : command blocks avaibale for HCAMS
+ * MAX_INTERNAL_CMD : command blocks avaible for internal commands like reset
+ */
+#define PMCRAID_MAX_CMD				1024
+#define PMCRAID_MAX_IO_CMD			1020
+#define PMCRAID_MAX_HCAM_CMD			2
+#define PMCRAID_MAX_INTERNAL_CMD		2
+
+/* MAX_IOADLS       : max number of scatter-gather lists supported by IOA
+ * IOADLS_INTERNAL  : number of ioadls included as part of IOARCB.
+ * IOADLS_EXTERNAL  : number of ioadls allocated external to IOARCB
+ */
+#define PMCRAID_IOADLS_INTERNAL			 27
+#define PMCRAID_IOADLS_EXTERNAL			 37
+#define PMCRAID_MAX_IOADLS			 PMCRAID_IOADLS_INTERNAL
+
+/* HRRQ_ENTRY_SIZE  : size of hrrq buffer
+ * IOARCB_ALIGNMENT : alignment required for IOARCB
+ * IOADL_ALIGNMENT  : alignment requirement for IOADLs
+ * MSIX_VECTORS     : number of MSIX vectors supported
+ */
+#define HRRQ_ENTRY_SIZE                          sizeof(__le32)
+#define PMCRAID_IOARCB_ALIGNMENT                 32
+#define PMCRAID_IOADL_ALIGNMENT                  16
+#define PMCRAID_IOASA_ALIGNMENT                  4
+#define PMCRAID_NUM_MSIX_VECTORS                 1
+
+/* various other limits */
+#define PMCRAID_VENDOR_ID_LEN           	 8
+#define PMCRAID_PRODUCT_ID_LEN            	 16
+#define PMCRAID_SERIAL_NUM_LEN          	 8
+#define PMCRAID_LUN_LEN			         8
+#define PMCRAID_MAX_CDB_LEN                      16
+#define PMCRAID_DEVICE_ID_LEN			 8
+#define PMCRAID_SENSE_DATA_LEN			 256
+#define PMCRAID_ADD_CMD_PARAM_LEN		 48
+
+#define PMCRAID_MAX_BUS_TO_SCAN                  1
+#define PMCRAID_MAX_NUM_TARGETS_PER_BUS          256
+#define PMCRAID_MAX_NUM_LUNS_PER_TARGET          8
+
+/* IOA bus/target/lun number of IOA resources */
+#define PMCRAID_IOA_BUS_ID                       0xfe
+#define PMCRAID_IOA_TARGET_ID                    0xff
+#define PMCRAID_IOA_LUN_ID                       0xff
+#define PMCRAID_VSET_BUS_ID                      0x1
+#define PMCRAID_VSET_LUN_ID                      0x0
+#define PMCRAID_PHYS_BUS_ID                      0x0
+#define PMCRAID_VIRTUAL_ENCL_BUS_ID              0x8
+#define PMCRAID_MAX_VSET_TARGETS                 240
+#define PMCRAID_MAX_VSET_LUNS_PER_TARGET         8
+
+#define PMCRAID_IOA_MAX_SECTORS                  32767
+#define PMCRAID_VSET_MAX_SECTORS                 512
+#define PMCRAID_MAX_CMD_PER_LUN                  254
+
+/* Number of configuration table entries (resources) */
+#define PMCRAID_MAX_NUM_OF_VSETS                 240
+
+/* Todo : Check max limit for Phase 1 */
+#define PMCRAID_MAX_NUM_OF_PHY_DEVS              256
+
+/* MAX_NUM_OF_DEVS includes 1 FP, 1 Dummy Enclosure device */
+#define PMCRAID_MAX_NUM_OF_DEVS                        \
+    (PMCRAID_MAX_NUM_OF_VSETS + PMCRAID_MAX_NUM_OF_PHY_DEVS + 2)
+
+#define PMCRAID_MAX_RESOURCES                    PMCRAID_MAX_NUM_OF_DEVS
+
+/* Adapter Commands used by driver */
+#define PMCRAID_QUERY_RESOURCE_STATE             0xC2
+#define PMCRAID_RESET_DEVICE                     0xC3
+/* options to select reset target */
+#define ENABLE_RESET_MODIFIER                    0x80
+#define RESET_DEVICE_LUN                         0x40
+#define RESET_DEVICE_TARGET                      0x20
+#define RESET_DEVICE_BUS                         0x10
+
+#define PMCRAID_IDENTIFY_HRRQ                    0xC4
+#define PMCRAID_QUERY_IOA_CONFIG                 0xC5
+#define PMCRAID_QUERY_CMD_STATUS		 0xCB
+#define PMCRAID_ABORT_CMD                        0xC7
+
+/* CANCEL ALL command, provides option for setting SYNC_COMPLETE
+ * on the target resources for which commands got cancelled
+ */
+#define PMCRAID_CANCEL_ALL_REQUESTS		 0xCE
+#define PMCRAID_SYNC_COMPLETE_AFTER_CANCEL       PMC_BIT8(0)
+
+/* HCAM command and types of HCAM supported by IOA */
+#define PMCRAID_HOST_CONTROLLED_ASYNC            0xCF
+#define PMCRAID_HCAM_CODE_CONFIG_CHANGE          0x01
+#define PMCRAID_HCAM_CODE_LOG_DATA               0x02
+
+/* IOA shutdown command and various shutdown types */
+#define PMCRAID_IOA_SHUTDOWN                     0xF7
+#define PMCRAID_SHUTDOWN_NORMAL                  0x00
+#define PMCRAID_SHUTDOWN_PREPARE_FOR_NORMAL      0x40
+#define PMCRAID_SHUTDOWN_NONE                    0x100
+#define PMCRAID_SHUTDOWN_ABBREV                  0x80
+
+/* SET SUPPORTED DEVICES command and the option to select all the
+ * devices to be supported
+ */
+#define PMCRAID_SET_SUPPORTED_DEVICES            0xFB
+#define ALL_DEVICES_SUPPORTED                    PMC_BIT8(0)
+
+/* This option is used with SCSI WRITE_BUFFER command */
+#define PMCRAID_WR_BUF_DOWNLOAD_AND_SAVE         0x05
+
+/* IOASC Codes used by driver */
+#define PMCRAID_IOASC_SENSE_MASK                 0xFFFFFF00
+#define PMCRAID_IOASC_SENSE_KEY(ioasc)           ((ioasc) >> 24)
+#define PMCRAID_IOASC_SENSE_CODE(ioasc)          (((ioasc) & 0x00ff0000) >> 16)
+#define PMCRAID_IOASC_SENSE_QUAL(ioasc)          (((ioasc) & 0x0000ff00) >> 8)
+#define PMCRAID_IOASC_SENSE_STATUS(ioasc)        ((ioasc) & 0x000000ff)
+
+#define PMCRAID_IOASC_GOOD_COMPLETION			0x00000000
+#define PMCRAID_IOASC_NR_INIT_CMD_REQUIRED		0x02040200
+#define PMCRAID_IOASC_NR_IOA_RESET_REQUIRED		0x02048000
+#define PMCRAID_IOASC_NR_SYNC_REQUIRED			0x023F0000
+#define PMCRAID_IOASC_ME_READ_ERROR_NO_REALLOC		0x03110C00
+#define PMCRAID_IOASC_HW_CANNOT_COMMUNICATE		0x04050000
+#define PMCRAID_IOASC_HW_DEVICE_TIMEOUT			0x04080100
+#define PMCRAID_IOASC_HW_DEVICE_BUS_STATUS_ERROR	0x04448500
+#define PMCRAID_IOASC_HW_IOA_RESET_REQUIRED		0x04448600
+#define PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE        0x05250000
+#define PMCRAID_IOASC_AC_TERMINATED_BY_HOST		0x0B5A0000
+#define PMCRAID_IOASC_UA_BUS_WAS_RESET           	0x06290000
+#define PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER  	0x06298000
+
+/* Driver defined IOASCs */
+#define PMCRAID_IOASC_IOA_WAS_RESET              	0x10000001
+#define PMCRAID_IOASC_PCI_ACCESS_ERROR           	0x10000002
+
+/* Various timeout values (in milliseconds) used. If any of these are chip
+ * specific, move them to pmcraid_chip_details structure.
+ */
+#define PMCRAID_PCI_DEASSERT_TIMEOUT		2000
+#define PMCRAID_BIST_TIMEOUT			2000
+#define PMCRAID_AENWAIT_TIMEOUT			5000
+#define PMCRAID_TRANSOP_TIMEOUT			60000
+
+#define PMCRAID_RESET_TIMEOUT			(2 * HZ)
+#define PMCRAID_CHECK_FOR_RESET_TIMEOUT		((HZ / 10))
+#define PMCRAID_VSET_IO_TIMEOUT			(60 * HZ)
+#define PMCRAID_INTERNAL_TIMEOUT		(60 * HZ)
+#define PMCRAID_SHUTDOWN_TIMEOUT		(150 * HZ)
+#define PMCRAID_RESET_BUS_TIMEOUT		(60 * HZ)
+#define PMCRAID_RESET_HOST_TIMEOUT		(150 * HZ)
+#define PMCRAID_REQUEST_SENSE_TIMEOUT		(30 * HZ)
+#define PMCRAID_SET_SUP_DEV_TIMEOUT		(2 * 60 * HZ)
+
+/* structure to represent a scatter-gather element (IOADL descriptor) */
+struct pmcraid_ioadl_desc {
+	__le64 address;
+	__le32 data_len;
+	__u8  reserved[3];
+	__u8  flags;
+} __attribute__((packed, aligned(PMCRAID_IOADL_ALIGNMENT)));
+
+/* pmcraid_ioadl_desc.flags values */
+#define IOADL_FLAGS_CHAINED      PMC_BIT8(0)
+#define IOADL_FLAGS_LAST_DESC    PMC_BIT8(1)
+#define IOADL_FLAGS_READ_LAST    PMC_BIT8(1)
+#define IOADL_FLAGS_WRITE_LAST   PMC_BIT8(1)
+
+
+/* additional IOARCB data which can be CDB or additional request parameters
+ * or list of IOADLs. Firmware supports max of 512 bytes for IOARCB, hence then
+ * number of IOADLs are limted to 27. In case they are more than 27, they will
+ * be used in chained form
+ */
+struct pmcraid_ioarcb_add_data {
+	union {
+		struct pmcraid_ioadl_desc ioadl[PMCRAID_IOADLS_INTERNAL];
+		__u8 add_cmd_params[PMCRAID_ADD_CMD_PARAM_LEN];
+	} u;
+};
+
+/*
+ * IOA Request Control Block
+ */
+struct pmcraid_ioarcb {
+	__le64 ioarcb_bus_addr;
+	__le32 resource_handle;
+	__le32 response_handle;
+	__le64 ioadl_bus_addr;
+	__le32 ioadl_length;
+	__le32 data_transfer_length;
+	__le64 ioasa_bus_addr;
+	__le16 ioasa_len;
+	__le16 cmd_timeout;
+	__le16 add_cmd_param_offset;
+	__le16 add_cmd_param_length;
+	__le32 reserved1[2];
+	__le32 reserved2;
+	__u8  request_type;
+	__u8  request_flags0;
+	__u8  request_flags1;
+	__u8  hrrq_id;
+	__u8  cdb[PMCRAID_MAX_CDB_LEN];
+	struct pmcraid_ioarcb_add_data add_data;
+} __attribute__((packed, aligned(PMCRAID_IOARCB_ALIGNMENT)));
+
+/* well known resource handle values */
+#define PMCRAID_IOA_RES_HANDLE        0xffffffff
+#define PMCRAID_INVALID_RES_HANDLE    0
+
+/* pmcraid_ioarcb.request_type values */
+#define REQ_TYPE_SCSI                 0x00
+#define REQ_TYPE_IOACMD               0x01
+#define REQ_TYPE_HCAM                 0x02
+
+/* pmcraid_ioarcb.flags0 values */
+#define TRANSFER_DIR_WRITE            PMC_BIT8(0)
+#define INHIBIT_UL_CHECK              PMC_BIT8(2)
+#define SYNC_OVERRIDE                 PMC_BIT8(3)
+#define SYNC_COMPLETE                 PMC_BIT8(4)
+#define NO_LINK_DESCS                 PMC_BIT8(5)
+
+/* pmcraid_ioarcb.flags1 values */
+#define DELAY_AFTER_RESET             PMC_BIT8(0)
+#define TASK_TAG_SIMPLE               0x10
+#define TASK_TAG_ORDERED              0x20
+#define TASK_TAG_QUEUE_HEAD           0x30
+
+/* toggle bit offset in response handle */
+#define HRRQ_TOGGLE_BIT               0x01
+#define HRRQ_RESPONSE_BIT             0x02
+
+/* IOA Status Area */
+struct pmcraid_ioasa_vset {
+	__le32 failing_lba_hi;
+	__le32 failing_lba_lo;
+	__le32 reserved;
+} __attribute__((packed, aligned(4)));
+
+struct pmcraid_ioasa {
+	__le32 ioasc;
+	__le16 returned_status_length;
+	__le16 available_status_length;
+	__le32 residual_data_length;
+	__le32 ilid;
+	__le32 fd_ioasc;
+	__le32 fd_res_address;
+	__le32 fd_res_handle;
+	__le32 reserved;
+
+	/* resource specific sense information */
+	union {
+		struct pmcraid_ioasa_vset vset;
+	} u;
+
+	/* IOA autosense data */
+	__le16 auto_sense_length;
+	__le16 error_data_length;
+	__u8  sense_data[PMCRAID_SENSE_DATA_LEN];
+} __attribute__((packed, aligned(4)));
+
+#define PMCRAID_DRIVER_ILID           0xffffffff
+
+/* Config Table Entry per Resource */
+struct pmcraid_config_table_entry {
+	__u8  resource_type;
+	__u8  bus_protocol;
+	__le16 array_id;
+	__u8  common_flags0;
+	__u8  common_flags1;
+	__u8  unique_flags0;
+	__u8  unique_flags1;	/*also used as vset target_id */
+	__le32 resource_handle;
+	__le32 resource_address;
+	__u8  device_id[PMCRAID_DEVICE_ID_LEN];
+	__u8  lun[PMCRAID_LUN_LEN];
+} __attribute__((packed, aligned(4)));
+
+/* resource types (config_table_entry.resource_type values) */
+#define RES_TYPE_AF_DASD     0x00
+#define RES_TYPE_GSCSI       0x01
+#define RES_TYPE_VSET        0x02
+#define RES_TYPE_IOA_FP      0xFF
+
+#define RES_IS_IOA(res)      ((res).resource_type == RES_TYPE_IOA_FP)
+#define RES_IS_GSCSI(res)    ((res).resource_type == RES_TYPE_GSCSI)
+#define RES_IS_VSET(res)     ((res).resource_type == RES_TYPE_VSET)
+#define RES_IS_AFDASD(res)   ((res).resource_type == RES_TYPE_AF_DASD)
+
+/* bus_protocol values used by driver */
+#define RES_TYPE_VENCLOSURE  0x8
+
+/* config_table_entry.common_flags0 */
+#define MULTIPATH_RESOURCE   PMC_BIT32(0)
+
+/* unique_flags1 */
+#define IMPORT_MODE_MANUAL   PMC_BIT8(0)
+
+/* well known resource handle values */
+#define RES_HANDLE_IOA       0xFFFFFFFF
+#define RES_HANDLE_NONE      0x00000000
+
+/* well known resource address values */
+#define RES_ADDRESS_IOAFP    0xFEFFFFFF
+#define RES_ADDRESS_INVALID  0xFFFFFFFF
+
+/* BUS/TARGET/LUN values from resource_addrr */
+#define RES_BUS(res_addr)    (le32_to_cpu(res_addr) & 0xFF)
+#define RES_TARGET(res_addr) ((le32_to_cpu(res_addr) >> 16) & 0xFF)
+#define RES_LUN(res_addr)    0x0
+
+/* configuration table structure */
+struct pmcraid_config_table {
+	__le16 num_entries;
+	__u8  table_format;
+	__u8  reserved1;
+	__u8  flags;
+	__u8  reserved2[11];
+	struct pmcraid_config_table_entry entries[PMCRAID_MAX_RESOURCES];
+} __attribute__((packed, aligned(4)));
+
+/* config_table.flags value */
+#define MICROCODE_UPDATE_REQUIRED		PMC_BIT32(0)
+
+/*
+ * HCAM format
+ */
+#define PMCRAID_HOSTRCB_LDNSIZE 		4056
+
+/* Error log notification format */
+struct pmcraid_hostrcb_error {
+	__le32 fd_ioasc;
+	__le32 fd_ra;
+	__le32 fd_rh;
+	__le32 prc;
+	union {
+		__u8 data[PMCRAID_HOSTRCB_LDNSIZE];
+	} u;
+} __attribute__ ((packed, aligned(4)));
+
+struct pmcraid_hcam_hdr {
+	__u8  op_code;
+	__u8  notification_type;
+	__u8  notification_lost;
+	__u8  flags;
+	__u8  overlay_id;
+	__u8  reserved1[3];
+	__le32 ilid;
+	__le32 timestamp1;
+	__le32 timestamp2;
+	__le32 data_len;
+} __attribute__((packed, aligned(4)));
+
+#define PMCRAID_AEN_GROUP	0x3
+
+struct pmcraid_hcam_ccn {
+	struct pmcraid_hcam_hdr header;
+	struct pmcraid_config_table_entry cfg_entry;
+} __attribute__((packed, aligned(4)));
+
+struct pmcraid_hcam_ldn {
+	struct pmcraid_hcam_hdr header;
+	struct pmcraid_hostrcb_error error_log;
+} __attribute__((packed, aligned(4)));
+
+/* pmcraid_hcam.op_code values */
+#define HOSTRCB_TYPE_CCN			0xE1
+#define HOSTRCB_TYPE_LDN			0xE2
+
+/* pmcraid_hcam.notification_type values */
+#define NOTIFICATION_TYPE_ENTRY_CHANGED		0x0
+#define NOTIFICATION_TYPE_ENTRY_NEW		0x1
+#define NOTIFICATION_TYPE_ENTRY_DELETED		0x2
+#define NOTIFICATION_TYPE_ERROR_LOG		0x10
+#define NOTIFICATION_TYPE_INFORMATION_LOG	0x11
+
+#define HOSTRCB_NOTIFICATIONS_LOST		PMC_BIT8(0)
+
+/* pmcraid_hcam.flags values */
+#define HOSTRCB_INTERNAL_OP_ERROR		PMC_BIT8(0)
+#define HOSTRCB_ERROR_RESPONSE_SENT		PMC_BIT8(1)
+
+/* pmcraid_hcam.overlay_id values */
+#define HOSTRCB_OVERLAY_ID_08			0x08
+#define HOSTRCB_OVERLAY_ID_09			0x09
+#define HOSTRCB_OVERLAY_ID_11			0x11
+#define HOSTRCB_OVERLAY_ID_12			0x12
+#define HOSTRCB_OVERLAY_ID_13			0x13
+#define HOSTRCB_OVERLAY_ID_14			0x14
+#define HOSTRCB_OVERLAY_ID_16			0x16
+#define HOSTRCB_OVERLAY_ID_17			0x17
+#define HOSTRCB_OVERLAY_ID_20			0x20
+#define HOSTRCB_OVERLAY_ID_FF			0xFF
+
+/* Implementation specific card details */
+struct pmcraid_chip_details {
+	/* hardware register offsets */
+	unsigned long  ioastatus;
+	unsigned long  ioarrin;
+	unsigned long  mailbox;
+	unsigned long  global_intr_mask;
+	unsigned long  ioa_host_intr;
+	unsigned long  ioa_host_intr_clr;
+	unsigned long  ioa_host_mask;
+	unsigned long  ioa_host_mask_clr;
+	unsigned long  host_ioa_intr;
+	unsigned long  host_ioa_intr_clr;
+
+	/* timeout used during transitional to operational state */
+	unsigned long transop_timeout;
+};
+
+/* IOA to HOST doorbells (interrupts) */
+#define INTRS_TRANSITION_TO_OPERATIONAL		PMC_BIT32(0)
+#define INTRS_IOARCB_TRANSFER_FAILED		PMC_BIT32(3)
+#define INTRS_IOA_UNIT_CHECK			PMC_BIT32(4)
+#define INTRS_NO_HRRQ_FOR_CMD_RESPONSE		PMC_BIT32(5)
+#define INTRS_CRITICAL_OP_IN_PROGRESS		PMC_BIT32(6)
+#define INTRS_IO_DEBUG_ACK			PMC_BIT32(7)
+#define INTRS_IOARRIN_LOST			PMC_BIT32(27)
+#define INTRS_SYSTEM_BUS_MMIO_ERROR		PMC_BIT32(28)
+#define INTRS_IOA_PROCESSOR_ERROR		PMC_BIT32(29)
+#define INTRS_HRRQ_VALID			PMC_BIT32(30)
+#define INTRS_OPERATIONAL_STATUS		PMC_BIT32(0)
+
+/* Host to IOA Doorbells */
+#define DOORBELL_RUNTIME_RESET			PMC_BIT32(1)
+#define DOORBELL_IOA_RESET_ALERT		PMC_BIT32(7)
+#define DOORBELL_IOA_DEBUG_ALERT		PMC_BIT32(9)
+#define DOORBELL_ENABLE_DESTRUCTIVE_DIAGS	PMC_BIT32(8)
+#define DOORBELL_IOA_START_BIST			PMC_BIT32(23)
+#define DOORBELL_RESET_IOA			PMC_BIT32(31)
+
+/* Global interrupt mask register value */
+#define GLOBAL_INTERRUPT_MASK			0x4ULL
+
+#define PMCRAID_ERROR_INTERRUPTS	(INTRS_IOARCB_TRANSFER_FAILED | \
+					 INTRS_IOA_UNIT_CHECK | \
+					 INTRS_NO_HRRQ_FOR_CMD_RESPONSE | \
+					 INTRS_IOARRIN_LOST | \
+					 INTRS_SYSTEM_BUS_MMIO_ERROR | \
+					 INTRS_IOA_PROCESSOR_ERROR)
+
+#define PMCRAID_PCI_INTERRUPTS		(PMCRAID_ERROR_INTERRUPTS | \
+					 INTRS_HRRQ_VALID | \
+					 INTRS_CRITICAL_OP_IN_PROGRESS |\
+					 INTRS_TRANSITION_TO_OPERATIONAL)
+
+/* control_block, associated with each of the commands contains IOARCB, IOADLs
+ * memory for IOASA. Additional 3 * 16 bytes are allocated in order to support
+ * additional request parameters (of max size 48) any command.
+ */
+struct pmcraid_control_block {
+	struct pmcraid_ioarcb ioarcb;
+	struct pmcraid_ioadl_desc ioadl[PMCRAID_IOADLS_EXTERNAL + 3];
+	struct pmcraid_ioasa ioasa;
+} __attribute__ ((packed, aligned(PMCRAID_IOARCB_ALIGNMENT)));
+
+/* pmcraid_sglist - Scatter-gather list allocated for passthrough ioctls
+ */
+struct pmcraid_sglist {
+	u32 order;
+	u32 num_sg;
+	u32 num_dma_sg;
+	u32 buffer_len;
+	struct scatterlist scatterlist[1];
+};
+
+/* pmcraid_cmd - LLD representation of SCSI command */
+struct pmcraid_cmd {
+
+	/* Ptr and bus address of DMA.able control block for this command */
+	struct pmcraid_control_block *ioa_cb;
+	dma_addr_t ioa_cb_bus_addr;
+
+	/* sense buffer for REQUEST SENSE command if firmware is not sending
+	 * auto sense data
+	 */
+	dma_addr_t sense_buffer_dma;
+	dma_addr_t dma_handle;
+	u8 *sense_buffer;
+
+	/* pointer to mid layer structure of SCSI commands */
+	struct scsi_cmnd *scsi_cmd;
+
+	struct list_head free_list;
+	struct completion wait_for_completion;
+	struct timer_list timer;	/* needed for internal commands */
+	u32 timeout;			/* current timeout value */
+	u32 index;			/* index into the command list */
+	u8 completion_req;		/* for handling internal commands */
+	u8 release;			/* for handling completions */
+
+	void (*cmd_done) (struct pmcraid_cmd *);
+	struct pmcraid_instance *drv_inst;
+
+	struct pmcraid_sglist *sglist; /* used for passthrough IOCTLs */
+
+	/* scratch used during reset sequence */
+	union {
+		unsigned long time_left;
+		struct pmcraid_resource_entry *res;
+	} u;
+};
+
+/*
+ * Interrupt registers of IOA
+ */
+struct pmcraid_interrupts {
+	void __iomem *ioa_host_interrupt_reg;
+	void __iomem *ioa_host_interrupt_clr_reg;
+	void __iomem *ioa_host_interrupt_mask_reg;
+	void __iomem *ioa_host_interrupt_mask_clr_reg;
+	void __iomem *global_interrupt_mask_reg;
+	void __iomem *host_ioa_interrupt_reg;
+	void __iomem *host_ioa_interrupt_clr_reg;
+};
+
+/* ISR parameters LLD allocates (one for each MSI-X if enabled) vectors */
+struct pmcraid_isr_param {
+	u8 hrrq_id;			/* hrrq entry index */
+	u16 vector;			/* allocated msi-x vector */
+	struct pmcraid_instance *drv_inst;
+};
+
+/* AEN message header sent as part of event data to applications */
+struct pmcraid_aen_msg {
+	u32 hostno;
+	u32 length;
+	u8  reserved[8];
+	u8  data[0];
+};
+
+struct pmcraid_hostrcb {
+	struct pmcraid_instance *drv_inst;
+	struct pmcraid_aen_msg *msg;
+	struct pmcraid_hcam_hdr *hcam;	/* pointer to hcam buffer */
+	struct pmcraid_cmd  *cmd;       /* pointer to command block used */
+	dma_addr_t baddr;		/* system address of hcam buffer */
+	atomic_t ignore;		/* process HCAM response ? */
+};
+
+#define PMCRAID_AEN_HDR_SIZE	sizeof(struct pmcraid_aen_msg)
+
+
+
+/*
+ * Per adapter structure maintained by LLD
+ */
+struct pmcraid_instance {
+	/* Array of allowed-to-be-exposed resources, initialized from
+	 * Configutation Table, later updated with CCNs
+	 */
+	struct pmcraid_resource_entry *res_entries;
+
+	struct list_head free_res_q;	/* res_entries lists for easy lookup */
+	struct list_head used_res_q;	/* List of to be exposed resources */
+	spinlock_t resource_lock;	/* spinlock to protect resource list */
+
+	void __iomem *mapped_dma_addr;
+	void __iomem *ioa_status;	/* Iomapped IOA status register */
+	void __iomem *mailbox;		/* Iomapped mailbox register */
+	void __iomem *ioarrin;		/* IOmapped IOARR IN register */
+
+	struct pmcraid_interrupts int_regs;
+	struct pmcraid_chip_details *chip_cfg;
+
+	/* HostRCBs needed for HCAM */
+	struct pmcraid_hostrcb ldn;
+	struct pmcraid_hostrcb ccn;
+
+
+	/* Bus address of start of HRRQ */
+	dma_addr_t hrrq_start_bus_addr[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* Pointer to 1st entry of HRRQ */
+	__be32 *hrrq_start[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* Pointer to last entry of HRRQ */
+	__be32 *hrrq_end[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* Pointer to current pointer of hrrq */
+	__be32 *hrrq_curr[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* Lock for HRRQ access */
+	spinlock_t hrrq_lock[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* Expected toggle bit at host */
+	u8 host_toggle_bit[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* No of Reset IOA retries . IOA marked dead if threshold exceeds */
+	u8 ioa_reset_attempts;
+#define PMCRAID_RESET_ATTEMPTS 3
+
+	/* Wait Q for  threads to wait for Reset IOA completion */
+	wait_queue_head_t reset_wait_q;
+	struct pmcraid_cmd *reset_cmd;
+
+	/* structures for supporting SIGIO based AEN. */
+	struct fasync_struct *aen_queue;
+	struct mutex aen_queue_lock;	/* lock for aen subscribers list */
+	struct cdev cdev;
+
+	struct Scsi_Host *host;	/* mid layer interface structure handle */
+	struct pci_dev *pdev;	/* PCI device structure handle */
+
+	u8  current_log_level;	/* default level for logging IOASC errors */
+
+	u8  num_hrrq;		/* Number of interrupt vectors allocated */
+	dev_t dev;		/* Major-Minor numbers for Char device */
+
+	/* Used as ISR handler argument */
+	struct pmcraid_isr_param hrrq_vector[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* configuration table */
+	struct pmcraid_config_table *cfg_table;
+	dma_addr_t cfg_table_bus_addr;
+
+	/* structures related to command blocks */
+	struct kmem_cache *cmd_cachep;		/* cache for cmd blocks */
+	struct pci_pool *control_pool;		/* pool for control blocks */
+	char   cmd_pool_name[64];		/* name of cmd cache */
+	char   ctl_pool_name[64];		/* name of control cache */
+
+	struct pmcraid_cmd *cmd_list[PMCRAID_MAX_CMD];
+
+	struct list_head free_cmd_pool;
+	struct list_head pending_cmd_pool;
+	spinlock_t free_pool_lock;	 	/* free pool lock */
+	spinlock_t pending_pool_lock;	 	/* pending pool lock */
+
+	/* No of IO commands pending with FW */
+	atomic_t outstanding_cmds;
+
+	/* should add/delete resources to mid-layer now ?*/
+	atomic_t expose_resources;
+
+	/* Tasklet to handle deferred processing */
+	struct tasklet_struct isr_tasklet[PMCRAID_NUM_MSIX_VECTORS];
+
+	/* Work-queue (Shared) for deferred reset processing */
+	struct work_struct worker_q;
+
+
+	u32 ioa_state:4;	/* For IOA Reset sequence FSM */
+#define IOA_STATE_OPERATIONAL       0x0
+#define IOA_STATE_UNKNOWN           0x1
+#define IOA_STATE_DEAD              0x2
+#define IOA_STATE_IN_SOFT_RESET     0x3
+#define IOA_STATE_IN_HARD_RESET     0x4
+#define IOA_STATE_IN_RESET_ALERT    0x5
+#define IOA_STATE_IN_BRINGDOWN      0x6
+#define IOA_STATE_IN_BRINGUP        0x7
+
+	u32 ioa_reset_in_progress:1; /* true if IOA reset is in progress */
+	u32 ioa_hard_reset:1;	/* TRUE if Hard Reset is needed */
+	u32 ioa_unit_check:1;	/* Indicates Unit Check condition */
+	u32 ioa_bringdown:1;	/* whether IOA needs to be brought down */
+	u32 force_ioa_reset:1;  /* force adapter reset ? */
+	u32 reinit_cfg_table:1; /* reinit config table due to lost CCN */
+	u32 ioa_shutdown_type:2;/* shutdown type used during reset */
+#define SHUTDOWN_NONE               0x0
+#define SHUTDOWN_NORMAL             0x1
+#define SHUTDOWN_ABBREV             0x2
+
+};
+
+/* LLD maintained resource entry structure */
+struct pmcraid_resource_entry {
+	struct list_head queue;	/* link to "to be exposed" resources */
+	struct pmcraid_config_table_entry cfg_entry;
+	struct scsi_device *scsi_dev;	/* Link scsi_device structure */
+	atomic_t read_failures;		/* count of failed READ commands */
+	atomic_t write_failures;	/* count of failed WRITE commands */
+
+	/* To indicate add/delete/modify during CCN */
+	u8 change_detected;
+#define RES_CHANGE_ADD          0x1	/* add this to mid-layer */
+#define RES_CHANGE_DEL          0x2	/* remove this from mid-layer */
+
+	u8 reset_progress;      /* Device is resetting */
+
+	/*
+	 * When IOA asks for sync (i.e. IOASC = Not Ready, Sync Required), this
+	 * flag will be set, mid layer will be asked to retry. In the next
+	 * attempt, this flag will be checked in queuecommand() to set
+	 * SYNC_COMPLETE flag in IOARCB (flag_0).
+	 */
+	u8 sync_reqd;
+
+	/* target indicates the mapped target_id assigned to this resource if
+	 * this is VSET resource. For non-VSET resources this will be un-used
+	 * or zero
+	 */
+	u8 target;
+};
+
+/* Data structures used in IOASC error code logging */
+struct pmcraid_ioasc_error {
+	u32 ioasc_code;		/* IOASC code */
+	u8 log_level;		/* default log level assignment. */
+	char *error_string;
+};
+
+/* Initial log_level assignments for various IOASCs */
+#define IOASC_LOG_LEVEL_NONE	    0x0 /* no logging */
+#define IOASC_LOG_LEVEL_MUST        0x1	/* must log: all high-severity errors */
+#define IOASC_LOG_LEVEL_HARD        0x2	/* optional â€“ low severity errors */
+
+/* Error information maintained by LLD. LLD initializes the pmcraid_error_table
+ * statically.
+ */
+static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = {
+	{0x01180600, IOASC_LOG_LEVEL_MUST,
+	 "Recovered Error, soft media error, sector reassignment suggested"},
+	{0x015D0000, IOASC_LOG_LEVEL_MUST,
+	 "Recovered Error, failure prediction thresold exceeded"},
+	{0x015D9200, IOASC_LOG_LEVEL_MUST,
+	 "Recovered Error, soft Cache Card Battery error thresold"},
+	{0x015D9200, IOASC_LOG_LEVEL_MUST,
+	 "Recovered Error, soft Cache Card Battery error thresold"},
+	{0x02048000, IOASC_LOG_LEVEL_MUST,
+	 "Not Ready, IOA Reset Required"},
+	{0x02408500, IOASC_LOG_LEVEL_MUST,
+	 "Not Ready, IOA microcode download required"},
+	{0x03110B00, IOASC_LOG_LEVEL_MUST,
+	 "Medium Error, data unreadable, reassignment suggested"},
+	{0x03110C00, IOASC_LOG_LEVEL_MUST,
+	 "Medium Error, data unreadable do not reassign"},
+	{0x03310000, IOASC_LOG_LEVEL_MUST,
+	 "Medium Error, media corrupted"},
+	{0x04050000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, IOA can't communicate with device"},
+	{0x04080000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, device bus error"},
+	{0x04080000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, device bus is not functioning"},
+	{0x04118000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, IOA reserved area data check"},
+	{0x04118100, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, IOA reserved area invalid data pattern"},
+	{0x04118200, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, IOA reserved area LRC error"},
+	{0x04320000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, reassignment space exhausted"},
+	{0x04330000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, data transfer underlength error"},
+	{0x04330000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, data transfer overlength error"},
+	{0x04418000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, PCI bus error"},
+	{0x04440000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, device error"},
+	{0x04448300, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, undefined device response"},
+	{0x04448400, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, IOA microcode error"},
+	{0x04448600, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, IOA reset required"},
+	{0x04449200, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, hard Cache Fearuee Card Battery error"},
+	{0x0444A000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, failed device altered"},
+	{0x0444A200, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, data check after reassignment"},
+	{0x0444A300, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, LRC error after reassignment"},
+	{0x044A0000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, device bus error (msg/cmd phase)"},
+	{0x04670400, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, new device can't be used"},
+	{0x04678000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, invalid multiadapter configuration"},
+	{0x04678100, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, incorrect connection between enclosures"},
+	{0x04678200, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, connections exceed IOA design limits"},
+	{0x04678300, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, incorrect multipath connection"},
+	{0x04679000, IOASC_LOG_LEVEL_MUST,
+	 "Hardware Error, command to LUN failed"},
+	{0x064C8000, IOASC_LOG_LEVEL_HARD,
+	 "Unit Attention, cache exists for missing/failed device"},
+	{0x06670100, IOASC_LOG_LEVEL_HARD,
+	 "Unit Attention, incompatible exposed mode device"},
+	{0x06670600, IOASC_LOG_LEVEL_HARD,
+	 "Unit Attention, attachment of logical unit failed"},
+	{0x06678000, IOASC_LOG_LEVEL_MUST,
+	 "Unit Attention, cables exceed connective design limit"},
+	{0x06678300, IOASC_LOG_LEVEL_MUST,
+	 "Unit Attention, incomplete multipath connection between" \
+	 "IOA and enclosure"},
+	{0x06678400, IOASC_LOG_LEVEL_MUST,
+	 "Unit Attention, incomplete multipath connection between" \
+	 "device and enclosure"},
+	{0x06678500, IOASC_LOG_LEVEL_MUST,
+	 "Unit Attention, incomplete multipath connection between" \
+	 "IOA and remote IOA"},
+	{0x06678600, IOASC_LOG_LEVEL_HARD,
+	 "Unit Attention, missing remote IOA"},
+	{0x06679100, IOASC_LOG_LEVEL_HARD,
+	 "Unit Attention, enclosure doesn't support required multipath" \
+	 "function"},
+	{0x06698200, IOASC_LOG_LEVEL_HARD,
+	 "Unit Attention, corrupt array parity detected on device"},
+	{0x066B0200, IOASC_LOG_LEVEL_MUST,
+	 "Unit Attention, array exposed"},
+	{0x066B8200, IOASC_LOG_LEVEL_HARD,
+	 "Unit Attention, exposed array is still protected"},
+	{0x066B9200, IOASC_LOG_LEVEL_MUST,
+	 "Unit Attention, Multipath redundancy level got worse"},
+	{0x07270000, IOASC_LOG_LEVEL_HARD,
+	 "Data Protect, device is read/write protected by IOA"},
+	{0x07278000, IOASC_LOG_LEVEL_HARD,
+	 "Data Protect, IOA doesn't support device attribute"},
+	{0x07278100, IOASC_LOG_LEVEL_HARD,
+	 "Data Protect, NVRAM mirroring prohibited"},
+	{0x07278400, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, array is short 2 or more devices"},
+	{0x07278600, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, exposed array is short a required device"},
+	{0x07278700, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, array members not at required addresses"},
+	{0x07278800, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, exposed mode device resource address conflict"},
+	{0x07278900, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, incorrect resource address of exposed mode device"},
+	{0x07278A00, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, Array is missing a device and parity is out of sync"},
+	{0x07278B00, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, maximum number of arrays already exist"},
+	{0x07278C00, IOASC_LOG_LEVEL_HARD,
+	 "Data Protect, cannot locate cache data for device"},
+	{0x07278D00, IOASC_LOG_LEVEL_HARD,
+	 "Data Protect, cache data exits for a changed device"},
+	{0x07279100, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, detection of a device requiring format"},
+	{0x07279200, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, IOA exceeds maximum number of devices"},
+	{0x07279600, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, missing array, volume set is not functional"},
+	{0x07279700, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, single device for a volume set"},
+	{0x07279800, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, missing multiple devices for a volume set"},
+	{0x07279900, IOASC_LOG_LEVEL_HARD,
+	 "Data Protect, maximum number of volument sets already exists"},
+	{0x07279A00, IOASC_LOG_LEVEL_MUST,
+	 "Data Protect, other volume set problem"},
+};
+
+/* macros to help in debugging */
+#define pmcraid_err(...)  \
+	printk(KERN_ERR "MaxRAID: "__VA_ARGS__)
+
+#define pmcraid_info(...) \
+	if (pmcraid_debug_log) \
+		printk(KERN_INFO "MaxRAID: "__VA_ARGS__)
+
+/* check if given command is a SCSI READ or SCSI WRITE command */
+#define SCSI_READ_CMD           0x1	/* any of SCSI READ commands */
+#define SCSI_WRITE_CMD          0x2	/* any of SCSI WRITE commands */
+#define SCSI_CMD_TYPE(opcode) \
+({  u8 op = opcode; u8 __type = 0;\
+	if (op == READ_6 || op == READ_10 || op == READ_12 || op == READ_16)\
+		__type = SCSI_READ_CMD;\
+	else if (op == WRITE_6 || op == WRITE_10 || op == WRITE_12 || \
+		 op == WRITE_16)\
+		__type = SCSI_WRITE_CMD;\
+	__type;\
+})
+
+#define IS_SCSI_READ_WRITE(opcode) \
+({	u8 __type = SCSI_CMD_TYPE(opcode); \
+	(__type == SCSI_READ_CMD || __type == SCSI_WRITE_CMD) ? 1 : 0;\
+})
+
+
+/*
+ * pmcraid_ioctl_header - definition of header structure that preceeds all the
+ * buffers given as ioctl arguements.
+ *
+ * .signature           : always ASCII string, "PMCRAID"
+ * .reserved            : not used
+ * .buffer_length       : length of the buffer following the header
+ */
+struct pmcraid_ioctl_header {
+	u8  signature[8];
+	u32 reserved;
+	u32 buffer_length;
+};
+
+#define PMCRAID_IOCTL_SIGNATURE      "PMCRAID"
+
+
+/*
+ * pmcraid_event_details - defines AEN details that apps can retrieve from LLD
+ *
+ * .rcb_ccn - complete RCB of CCN
+ * .rcb_ldn - complete RCB of CCN
+ */
+struct pmcraid_event_details {
+	struct pmcraid_hcam_ccn rcb_ccn;
+	struct pmcraid_hcam_ldn rcb_ldn;
+};
+
+/*
+ * pmcraid_driver_ioctl_buffer - structure passed as argument to most of the
+ * PMC driver handled ioctls.
+ */
+struct pmcraid_driver_ioctl_buffer {
+	struct pmcraid_ioctl_header ioctl_header;
+	struct pmcraid_event_details event_details;
+};
+
+/*
+ * pmcraid_passthrough_ioctl_buffer - structure given as argument to
+ * passthrough(or firmware handled) IOCTL commands. Note that ioarcb requires
+ * 32-byte alignment so, it is necessary to pack this structure to avoid any
+ * holes between ioctl_header and passthrough buffer
+ *
+ * .ioactl_header : ioctl header
+ * .ioarcb        : filled-up ioarcb buffer, driver always reads this buffer
+ * .ioasa         : buffer for ioasa, driver fills this with IOASA from firmware
+ * .request_buffer: The I/O buffer (flat), driver reads/writes to this based on
+ *                  the transfer directions passed in ioarcb.flags0. Contents
+ *                  of this buffer are valid only when ioarcb.data_transfer_len
+ *                  is not zero.
+ */
+struct pmcraid_passthrough_ioctl_buffer {
+	struct pmcraid_ioctl_header ioctl_header;
+	struct pmcraid_ioarcb ioarcb;
+	struct pmcraid_ioasa  ioasa;
+	u8  request_buffer[1];
+} __attribute__ ((packed));
+
+/*
+ * keys to differentiate between driver handled IOCTLs and passthrough
+ * IOCTLs passed to IOA. driver determines the ioctl type using macro
+ * _IOC_TYPE
+ */
+#define PMCRAID_DRIVER_IOCTL         'D'
+#define PMCRAID_PASSTHROUGH_IOCTL    'F'
+
+#define DRV_IOCTL(n, size) \
+    _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_DRIVER_IOCTL, (n), (size))
+
+#define FMW_IOCTL(n, size) \
+    _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_PASSTHROUGH_IOCTL,  (n), (size))
+
+/*
+ * _ARGSIZE: macro that gives size of the argument type passed to an IOCTL cmd.
+ * This is to facilitate applications avoiding un-necessary memory allocations.
+ * For example, most of driver handled ioctls do not require ioarcb, ioasa.
+ */
+#define _ARGSIZE(arg) (sizeof(struct pmcraid_ioctl_header) + sizeof(arg))
+
+/* Driver handled IOCTL command definitions */
+
+#define PMCRAID_IOCTL_RESET_ADAPTER          \
+	DRV_IOCTL(5, sizeof(struct pmcraid_ioctl_header))
+
+/* passthrough/firmware handled commands */
+#define PMCRAID_IOCTL_PASSTHROUGH_COMMAND         \
+	FMW_IOCTL(1, sizeof(struct pmcraid_passthrough_ioctl_buffer))
+
+#define PMCRAID_IOCTL_DOWNLOAD_MICROCODE     \
+	FMW_IOCTL(2, sizeof(struct pmcraid_passthrough_ioctl_buffer))
+
+
+#endif /* _PMCRAID_H */
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 0f87962..fbcb82a 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1670,7 +1670,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
 
 	qla24xx_vport_disable(fc_vport, disable);
 
-	if (ql2xmultique_tag) {
+	if (ha->flags.cpu_affinity_enabled) {
 		req = ha->req_q_map[1];
 		goto vport_queue;
 	} else if (ql2xmaxqueues == 1 || !ha->npiv_info)
@@ -1736,6 +1736,11 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
 
 	qla24xx_deallocate_vp_id(vha);
 
+	mutex_lock(&ha->vport_lock);
+	ha->cur_vport_count--;
+	clear_bit(vha->vp_idx, ha->vp_idx_map);
+	mutex_unlock(&ha->vport_lock);
+
 	if (vha->timer_active) {
 		qla2x00_vp_stop_timer(vha);
 		DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p "
@@ -1743,7 +1748,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
 		    vha->host_no, vha->vp_idx, vha));
         }
 
-	if (vha->req->id && !ql2xmultique_tag) {
+	if (vha->req->id && !ha->flags.cpu_affinity_enabled) {
 		if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS)
 			qla_printk(KERN_WARNING, ha,
 				"Queue delete failed.\n");
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 00aa48d..2150618 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -189,6 +189,7 @@ struct req_que;
  */
 typedef struct srb {
 	struct fc_port *fcport;
+	uint32_t handle;
 
 	struct scsi_cmnd *cmd;		/* Linux SCSI command pkt */
 
@@ -196,6 +197,8 @@ typedef struct srb {
 
 	uint32_t request_sense_length;
 	uint8_t *request_sense_ptr;
+
+	void *ctx;
 } srb_t;
 
 /*
@@ -204,6 +207,28 @@ typedef struct srb {
 #define SRB_DMA_VALID		BIT_0	/* Command sent to ISP */
 
 /*
+ * SRB extensions.
+ */
+struct srb_ctx {
+#define SRB_LOGIN_CMD	1
+#define SRB_LOGOUT_CMD	2
+	uint16_t type;
+	struct timer_list timer;
+
+	void (*free)(srb_t *sp);
+	void (*timeout)(srb_t *sp);
+};
+
+struct srb_logio {
+	struct srb_ctx ctx;
+
+#define SRB_LOGIN_RETRIED	BIT_0
+#define SRB_LOGIN_COND_PLOGI	BIT_1
+#define SRB_LOGIN_SKIP_PRLI	BIT_2
+	uint16_t flags;
+};
+
+/*
  * ISP I/O Register Set structure definitions.
  */
 struct device_reg_2xxx {
@@ -1482,7 +1507,7 @@ typedef union {
 		uint8_t domain;
 		uint8_t area;
 		uint8_t al_pa;
-#elif __LITTLE_ENDIAN
+#elif defined(__LITTLE_ENDIAN)
 		uint8_t al_pa;
 		uint8_t area;
 		uint8_t domain;
@@ -1565,6 +1590,7 @@ typedef struct fc_port {
 #define FCF_FABRIC_DEVICE	BIT_0
 #define FCF_LOGIN_NEEDED	BIT_1
 #define FCF_TAPE_PRESENT	BIT_2
+#define FCF_FCP2_DEVICE		BIT_3
 
 /* No loop ID flag. */
 #define FC_NO_LOOP_ID		0x1000
@@ -2093,6 +2119,10 @@ struct qla_msix_entry {
 enum qla_work_type {
 	QLA_EVT_AEN,
 	QLA_EVT_IDC_ACK,
+	QLA_EVT_ASYNC_LOGIN,
+	QLA_EVT_ASYNC_LOGIN_DONE,
+	QLA_EVT_ASYNC_LOGOUT,
+	QLA_EVT_ASYNC_LOGOUT_DONE,
 };
 
 
@@ -2111,6 +2141,11 @@ struct qla_work_evt {
 #define QLA_IDC_ACK_REGS	7
 			uint16_t mb[QLA_IDC_ACK_REGS];
 		} idc_ack;
+		struct {
+			struct fc_port *fcport;
+#define QLA_LOGIO_LOGIN_RETRIED	BIT_0
+			u16 data[2];
+		} logio;
 	} u;
 };
 
@@ -2224,6 +2259,7 @@ struct qla_hw_data {
 		uint32_t	chip_reset_done		:1;
 		uint32_t	port0			:1;
 		uint32_t	running_gold_fw		:1;
+		uint32_t	cpu_affinity_enabled	:1;
 	} flags;
 
 	/* This spinlock is used to protect "io transactions", you must
@@ -2350,6 +2386,7 @@ struct qla_hw_data {
 				(ha)->flags.msix_enabled)
 #define IS_FAC_REQUIRED(ha)	(IS_QLA81XX(ha))
 #define IS_NOCACHE_VPD_TYPE(ha)	(IS_QLA81XX(ha))
+#define IS_ALOGIO_CAPABLE(ha)	(IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha))
 
 #define IS_IIDMA_CAPABLE(ha)    ((ha)->device_type & DT_IIDMA)
 #define IS_FWI2_CAPABLE(ha)     ((ha)->device_type & DT_FWI2)
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index dfde2dd..66a8da5 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1126,7 +1126,7 @@ struct vp_config_entry_24xx {
 	uint16_t id;
 	uint16_t reserved_4;
 	uint16_t hopct;
-	uint8_t reserved_5;
+	uint8_t reserved_5[2];
 };
 
 #define VP_RPT_ID_IOCB_TYPE	0x32	/* Report ID Acquisition entry. */
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 65b12d8..f3d1d1a 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -52,6 +52,14 @@ extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
 
 extern void qla84xx_put_chip(struct scsi_qla_host *);
 
+extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *,
+    uint16_t *);
+extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
+extern int qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *,
+    uint16_t *);
+extern int qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
+    uint16_t *);
+
 /*
  * Global Data in qla_os.c source file.
  */
@@ -76,6 +84,15 @@ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
 extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
     fc_host_event_code, u32);
 extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
+extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *,
+    uint16_t *);
+extern int qla2x00_post_async_login_done_work(struct scsi_qla_host *,
+    fc_port_t *, uint16_t *);
+extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
+    uint16_t *);
+extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
+    fc_port_t *, uint16_t *);
+
 extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
 
 extern void qla2x00_abort_fcport_cmds(fc_port_t *);
@@ -83,6 +100,8 @@ extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
 	struct qla_hw_data *);
 extern void qla2x00_free_host(struct scsi_qla_host *);
 extern void qla2x00_relogin(struct scsi_qla_host *);
+extern void qla2x00_do_work(struct scsi_qla_host *);
+
 /*
  * Global Functions in qla_mid.c source file.
  */
@@ -135,6 +154,7 @@ int qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
 						uint16_t, uint16_t, uint8_t);
 int __qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *,
 						uint16_t, uint16_t, uint8_t);
+extern int qla2x00_start_sp(srb_t *);
 
 /*
  * Global Function Prototypes in qla_mbx.c source file.
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 917534b..4647015 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -1674,6 +1674,10 @@ int
 qla2x00_fdmi_register(scsi_qla_host_t *vha)
 {
 	int rval;
+       struct qla_hw_data *ha = vha->hw;
+
+	if (IS_QLA2100(ha) || IS_QLA2200(ha))
+		return QLA_FUNCTION_FAILED;
 
 	rval = qla2x00_mgmt_svr_login(vha);
 	if (rval)
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index f2ce8e3..9e3eaac 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -40,6 +40,210 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
 static int qla84xx_init_chip(scsi_qla_host_t *);
 static int qla25xx_init_queues(struct qla_hw_data *);
 
+/* SRB Extensions ---------------------------------------------------------- */
+
+static void
+qla2x00_ctx_sp_timeout(unsigned long __data)
+{
+	srb_t *sp = (srb_t *)__data;
+	struct srb_ctx *ctx;
+	fc_port_t *fcport = sp->fcport;
+	struct qla_hw_data *ha = fcport->vha->hw;
+	struct req_que *req;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	req = ha->req_q_map[0];
+	req->outstanding_cmds[sp->handle] = NULL;
+	ctx = sp->ctx;
+	ctx->timeout(sp);
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+	ctx->free(sp);
+}
+
+static void
+qla2x00_ctx_sp_free(srb_t *sp)
+{
+	struct srb_ctx *ctx = sp->ctx;
+
+	kfree(ctx);
+	mempool_free(sp, sp->fcport->vha->hw->srb_mempool);
+}
+
+inline srb_t *
+qla2x00_get_ctx_sp(scsi_qla_host_t *vha, fc_port_t *fcport, size_t size,
+    unsigned long tmo)
+{
+	srb_t *sp;
+	struct qla_hw_data *ha = vha->hw;
+	struct srb_ctx *ctx;
+
+	sp = mempool_alloc(ha->srb_mempool, GFP_KERNEL);
+	if (!sp)
+		goto done;
+	ctx = kzalloc(size, GFP_KERNEL);
+	if (!ctx) {
+		mempool_free(sp, ha->srb_mempool);
+		goto done;
+	}
+
+	memset(sp, 0, sizeof(*sp));
+	sp->fcport = fcport;
+	sp->ctx = ctx;
+	ctx->free = qla2x00_ctx_sp_free;
+
+	init_timer(&ctx->timer);
+	if (!tmo)
+		goto done;
+	ctx->timer.expires = jiffies + tmo * HZ;
+	ctx->timer.data = (unsigned long)sp;
+	ctx->timer.function = qla2x00_ctx_sp_timeout;
+	add_timer(&ctx->timer);
+done:
+	return sp;
+}
+
+/* Asynchronous Login/Logout Routines -------------------------------------- */
+
+#define ELS_TMO_2_RATOV(ha) ((ha)->r_a_tov / 10 * 2)
+
+static void
+qla2x00_async_logio_timeout(srb_t *sp)
+{
+	fc_port_t *fcport = sp->fcport;
+	struct srb_logio *lio = sp->ctx;
+
+	DEBUG2(printk(KERN_WARNING
+	    "scsi(%ld:%x): Async-%s timeout.\n",
+	    fcport->vha->host_no, sp->handle,
+	    lio->ctx.type == SRB_LOGIN_CMD ? "login": "logout"));
+
+	if (lio->ctx.type == SRB_LOGIN_CMD)
+		qla2x00_post_async_logout_work(fcport->vha, fcport, NULL);
+}
+
+int
+qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
+    uint16_t *data)
+{
+	struct qla_hw_data *ha = vha->hw;
+	srb_t *sp;
+	struct srb_logio *lio;
+	int rval;
+
+	rval = QLA_FUNCTION_FAILED;
+	sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio),
+	    ELS_TMO_2_RATOV(ha) + 2);
+	if (!sp)
+		goto done;
+
+	lio = sp->ctx;
+	lio->ctx.type = SRB_LOGIN_CMD;
+	lio->ctx.timeout = qla2x00_async_logio_timeout;
+	lio->flags |= SRB_LOGIN_COND_PLOGI;
+	if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
+		lio->flags |= SRB_LOGIN_RETRIED;
+	rval = qla2x00_start_sp(sp);
+	if (rval != QLA_SUCCESS)
+		goto done_free_sp;
+
+	DEBUG2(printk(KERN_DEBUG
+	    "scsi(%ld:%x): Async-login - loop-id=%x portid=%02x%02x%02x "
+	    "retries=%d.\n", fcport->vha->host_no, sp->handle, fcport->loop_id,
+	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa,
+	    fcport->login_retry));
+	return rval;
+
+done_free_sp:
+	del_timer_sync(&lio->ctx.timer);
+	lio->ctx.free(sp);
+done:
+	return rval;
+}
+
+int
+qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
+{
+	struct qla_hw_data *ha = vha->hw;
+	srb_t *sp;
+	struct srb_logio *lio;
+	int rval;
+
+	rval = QLA_FUNCTION_FAILED;
+	sp = qla2x00_get_ctx_sp(vha, fcport, sizeof(struct srb_logio),
+	    ELS_TMO_2_RATOV(ha) + 2);
+	if (!sp)
+		goto done;
+
+	lio = sp->ctx;
+	lio->ctx.type = SRB_LOGOUT_CMD;
+	lio->ctx.timeout = qla2x00_async_logio_timeout;
+	rval = qla2x00_start_sp(sp);
+	if (rval != QLA_SUCCESS)
+		goto done_free_sp;
+
+	DEBUG2(printk(KERN_DEBUG
+	    "scsi(%ld:%x): Async-logout - loop-id=%x portid=%02x%02x%02x.\n",
+	    fcport->vha->host_no, sp->handle, fcport->loop_id,
+	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa));
+	return rval;
+
+done_free_sp:
+	del_timer_sync(&lio->ctx.timer);
+	lio->ctx.free(sp);
+done:
+	return rval;
+}
+
+int
+qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
+    uint16_t *data)
+{
+	int rval;
+	uint8_t opts = 0;
+
+	switch (data[0]) {
+	case MBS_COMMAND_COMPLETE:
+		if (fcport->flags & FCF_TAPE_PRESENT)
+			opts |= BIT_1;
+		rval = qla2x00_get_port_database(vha, fcport, opts);
+		if (rval != QLA_SUCCESS)
+			qla2x00_mark_device_lost(vha, fcport, 1, 0);
+		else
+			qla2x00_update_fcport(vha, fcport);
+		break;
+	case MBS_COMMAND_ERROR:
+		if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
+			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+		else
+			qla2x00_mark_device_lost(vha, fcport, 1, 0);
+		break;
+	case MBS_PORT_ID_USED:
+		fcport->loop_id = data[1];
+		qla2x00_post_async_login_work(vha, fcport, NULL);
+		break;
+	case MBS_LOOP_ID_USED:
+		fcport->loop_id++;
+		rval = qla2x00_find_new_loop_id(vha, fcport);
+		if (rval != QLA_SUCCESS) {
+			qla2x00_mark_device_lost(vha, fcport, 1, 0);
+			break;
+		}
+		qla2x00_post_async_login_work(vha, fcport, NULL);
+		break;
+	}
+	return QLA_SUCCESS;
+}
+
+int
+qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
+    uint16_t *data)
+{
+	qla2x00_mark_device_lost(vha, fcport, 1, 0);
+	return QLA_SUCCESS;
+}
+
 /****************************************************************************/
 /*                QLogic ISP2x00 Hardware Support Functions.                */
 /****************************************************************************/
@@ -987,7 +1191,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
 				    ha->phy_version);
 				if (rval != QLA_SUCCESS)
 					goto failed;
-
 				ha->flags.npiv_supported = 0;
 				if (IS_QLA2XXX_MIDTYPE(ha) &&
 					 (ha->fw_attributes & BIT_2)) {
@@ -1591,7 +1794,8 @@ qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
 	char *st, *en;
 	uint16_t index;
 	struct qla_hw_data *ha = vha->hw;
-	int use_tbl = !IS_QLA25XX(ha) && !IS_QLA81XX(ha);
+	int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
+	    !IS_QLA81XX(ha);
 
 	if (memcmp(model, BINZERO, len) != 0) {
 		strncpy(ha->model_number, model, len);
@@ -1978,7 +2182,7 @@ qla2x00_rport_del(void *data)
 	struct fc_rport *rport;
 
 	spin_lock_irq(fcport->vha->host->host_lock);
-	rport = fcport->drport;
+	rport = fcport->drport ? fcport->drport: fcport->rport;
 	fcport->drport = NULL;
 	spin_unlock_irq(fcport->vha->host->host_lock);
 	if (rport)
@@ -2345,8 +2549,7 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
 	struct fc_rport *rport;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (fcport->drport)
-		qla2x00_rport_del(fcport);
+	qla2x00_rport_del(fcport);
 
 	rport_ids.node_name = wwn_to_u64(fcport->node_name);
 	rport_ids.port_name = wwn_to_u64(fcport->port_name);
@@ -3039,6 +3242,12 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport,
 	rval = QLA_SUCCESS;
 	retry = 0;
 
+	if (IS_ALOGIO_CAPABLE(ha)) {
+		rval = qla2x00_post_async_login_work(vha, fcport, NULL);
+		if (!rval)
+			return rval;
+	}
+
 	rval = qla2x00_fabric_login(vha, fcport, next_loopid);
 	if (rval == QLA_SUCCESS) {
 		/* Send an ADISC to tape devices.*/
@@ -3133,7 +3342,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport,
 			} else {
 				fcport->port_type = FCT_TARGET;
 				if (mb[1] & BIT_1) {
-					fcport->flags |= FCF_TAPE_PRESENT;
+					fcport->flags |= FCF_FCP2_DEVICE;
 				}
 			}
 
@@ -3244,7 +3453,7 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
 	struct req_que *req;
 	struct rsp_que *rsp;
 
-	if (ql2xmultique_tag)
+	if (vha->hw->flags.cpu_affinity_enabled)
 		req = vha->hw->req_q_map[0];
 	else
 		req = vha->req;
@@ -3286,15 +3495,17 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
 }
 
 void
-qla2x00_update_fcports(scsi_qla_host_t *vha)
+qla2x00_update_fcports(scsi_qla_host_t *base_vha)
 {
 	fc_port_t *fcport;
+	struct scsi_qla_host *tvp, *vha;
 
 	/* Go with deferred removal of rport references. */
-	list_for_each_entry(fcport, &vha->vp_fcports, list)
-		if (fcport && fcport->drport &&
-		    atomic_read(&fcport->state) != FCS_UNCONFIGURED)
-			qla2x00_rport_del(fcport);
+	list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list)
+		list_for_each_entry(fcport, &vha->vp_fcports, list)
+			if (fcport && fcport->drport &&
+			    atomic_read(&fcport->state) != FCS_UNCONFIGURED)
+				qla2x00_rport_del(fcport);
 }
 
 /*
@@ -3331,8 +3542,6 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
 		if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
 			atomic_set(&vha->loop_state, LOOP_DOWN);
 			qla2x00_mark_all_devices_lost(vha, 0);
-			list_for_each_entry_safe(vp, tvp, &ha->vp_list, list)
-			       qla2x00_mark_all_devices_lost(vp, 0);
 		} else {
 			if (!atomic_read(&vha->loop_down_timer))
 				atomic_set(&vha->loop_down_timer,
@@ -4264,7 +4473,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
 		return -EINVAL;
 
 	rval = qla2x00_fw_ready(base_vha);
-	if (ql2xmultique_tag)
+	if (ha->flags.cpu_affinity_enabled)
 		req = ha->req_q_map[0];
 	else
 		req = vha->req;
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 13396be..c5ccac0 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -350,6 +350,7 @@ qla2x00_start_scsi(srb_t *sp)
 	/* Build command packet */
 	req->current_outstanding_cmd = handle;
 	req->outstanding_cmds[handle] = sp;
+	sp->handle = handle;
 	sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
 	req->cnt -= req_cnt;
 
@@ -778,6 +779,7 @@ qla24xx_start_scsi(srb_t *sp)
 	/* Build command packet. */
 	req->current_outstanding_cmd = handle;
 	req->outstanding_cmds[handle] = sp;
+	sp->handle = handle;
 	sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle;
 	req->cnt -= req_cnt;
 
@@ -852,9 +854,211 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
 	struct qla_hw_data *ha = sp->fcport->vha->hw;
 	int affinity = cmd->request->cpu;
 
-	if (ql2xmultique_tag && affinity >= 0 &&
+	if (ha->flags.cpu_affinity_enabled && affinity >= 0 &&
 		affinity < ha->max_rsp_queues - 1)
 		*rsp = ha->rsp_q_map[affinity + 1];
 	 else
 		*rsp = ha->rsp_q_map[0];
 }
+
+/* Generic Control-SRB manipulation functions. */
+
+static void *
+qla2x00_alloc_iocbs(srb_t *sp)
+{
+	scsi_qla_host_t	*vha = sp->fcport->vha;
+	struct qla_hw_data *ha = vha->hw;
+	struct req_que *req = ha->req_q_map[0];
+	device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
+	uint32_t index, handle;
+	request_t *pkt;
+	uint16_t cnt, req_cnt;
+
+	pkt = NULL;
+	req_cnt = 1;
+
+	/* Check for room in outstanding command list. */
+	handle = req->current_outstanding_cmd;
+	for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
+		handle++;
+		if (handle == MAX_OUTSTANDING_COMMANDS)
+			handle = 1;
+		if (!req->outstanding_cmds[handle])
+			break;
+	}
+	if (index == MAX_OUTSTANDING_COMMANDS)
+		goto queuing_error;
+
+	/* Check for room on request queue. */
+	if (req->cnt < req_cnt) {
+		if (ha->mqenable)
+			cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
+		else if (IS_FWI2_CAPABLE(ha))
+			cnt = RD_REG_DWORD(&reg->isp24.req_q_out);
+		else
+			cnt = qla2x00_debounce_register(
+			    ISP_REQ_Q_OUT(ha, &reg->isp));
+
+		if  (req->ring_index < cnt)
+			req->cnt = cnt - req->ring_index;
+		else
+			req->cnt = req->length -
+			    (req->ring_index - cnt);
+	}
+	if (req->cnt < req_cnt)
+		goto queuing_error;
+
+	/* Prep packet */
+	req->current_outstanding_cmd = handle;
+	req->outstanding_cmds[handle] = sp;
+	req->cnt -= req_cnt;
+
+	pkt = req->ring_ptr;
+	memset(pkt, 0, REQUEST_ENTRY_SIZE);
+	pkt->entry_count = req_cnt;
+	pkt->handle = handle;
+	sp->handle = handle;
+
+queuing_error:
+	return pkt;
+}
+
+static void
+qla2x00_start_iocbs(srb_t *sp)
+{
+	struct qla_hw_data *ha = sp->fcport->vha->hw;
+	struct req_que *req = ha->req_q_map[0];
+	device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
+	struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
+
+	/* Adjust ring index. */
+	req->ring_index++;
+	if (req->ring_index == req->length) {
+		req->ring_index = 0;
+		req->ring_ptr = req->ring;
+	} else
+		req->ring_ptr++;
+
+	/* Set chip new ring index. */
+	if (ha->mqenable) {
+		WRT_REG_DWORD(&reg->isp25mq.req_q_in, req->ring_index);
+		RD_REG_DWORD(&ioreg->hccr);
+	} else if (IS_FWI2_CAPABLE(ha)) {
+		WRT_REG_DWORD(&reg->isp24.req_q_in, req->ring_index);
+		RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
+	} else {
+		WRT_REG_WORD(ISP_REQ_Q_IN(ha, &reg->isp), req->ring_index);
+		RD_REG_WORD_RELAXED(ISP_REQ_Q_IN(ha, &reg->isp));
+	}
+}
+
+static void
+qla24xx_login_iocb(srb_t *sp, struct logio_entry_24xx *logio)
+{
+	struct srb_logio *lio = sp->ctx;
+
+	logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
+	logio->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
+	if (lio->flags & SRB_LOGIN_COND_PLOGI)
+		logio->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
+	if (lio->flags & SRB_LOGIN_SKIP_PRLI)
+		logio->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
+	logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+	logio->port_id[0] = sp->fcport->d_id.b.al_pa;
+	logio->port_id[1] = sp->fcport->d_id.b.area;
+	logio->port_id[2] = sp->fcport->d_id.b.domain;
+	logio->vp_index = sp->fcport->vp_idx;
+}
+
+static void
+qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx)
+{
+	struct qla_hw_data *ha = sp->fcport->vha->hw;
+	struct srb_logio *lio = sp->ctx;
+	uint16_t opts;
+
+	mbx->entry_type = MBX_IOCB_TYPE;;
+	SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
+	mbx->mb0 = cpu_to_le16(MBC_LOGIN_FABRIC_PORT);
+	opts = lio->flags & SRB_LOGIN_COND_PLOGI ? BIT_0: 0;
+	opts |= lio->flags & SRB_LOGIN_SKIP_PRLI ? BIT_1: 0;
+	if (HAS_EXTENDED_IDS(ha)) {
+		mbx->mb1 = cpu_to_le16(sp->fcport->loop_id);
+		mbx->mb10 = cpu_to_le16(opts);
+	} else {
+		mbx->mb1 = cpu_to_le16((sp->fcport->loop_id << 8) | opts);
+	}
+	mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
+	mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
+	    sp->fcport->d_id.b.al_pa);
+	mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx);
+}
+
+static void
+qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
+{
+	logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
+	logio->control_flags =
+	    cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
+	logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+	logio->port_id[0] = sp->fcport->d_id.b.al_pa;
+	logio->port_id[1] = sp->fcport->d_id.b.area;
+	logio->port_id[2] = sp->fcport->d_id.b.domain;
+	logio->vp_index = sp->fcport->vp_idx;
+}
+
+static void
+qla2x00_logout_iocb(srb_t *sp, struct mbx_entry *mbx)
+{
+	struct qla_hw_data *ha = sp->fcport->vha->hw;
+
+	mbx->entry_type = MBX_IOCB_TYPE;;
+	SET_TARGET_ID(ha, mbx->loop_id, sp->fcport->loop_id);
+	mbx->mb0 = cpu_to_le16(MBC_LOGOUT_FABRIC_PORT);
+	mbx->mb1 = HAS_EXTENDED_IDS(ha) ?
+	    cpu_to_le16(sp->fcport->loop_id):
+	    cpu_to_le16(sp->fcport->loop_id << 8);
+	mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain);
+	mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 |
+	    sp->fcport->d_id.b.al_pa);
+	mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx);
+	/* Implicit: mbx->mbx10 = 0. */
+}
+
+int
+qla2x00_start_sp(srb_t *sp)
+{
+	int rval;
+	struct qla_hw_data *ha = sp->fcport->vha->hw;
+	void *pkt;
+	struct srb_ctx *ctx = sp->ctx;
+	unsigned long flags;
+
+	rval = QLA_FUNCTION_FAILED;
+	spin_lock_irqsave(&ha->hardware_lock, flags);
+	pkt = qla2x00_alloc_iocbs(sp);
+	if (!pkt)
+		goto done;
+
+	rval = QLA_SUCCESS;
+	switch (ctx->type) {
+	case SRB_LOGIN_CMD:
+		IS_FWI2_CAPABLE(ha) ?
+		    qla24xx_login_iocb(sp, pkt):
+		    qla2x00_login_iocb(sp, pkt);
+		break;
+	case SRB_LOGOUT_CMD:
+		IS_FWI2_CAPABLE(ha) ?
+		    qla24xx_logout_iocb(sp, pkt):
+		    qla2x00_logout_iocb(sp, pkt);
+		break;
+	default:
+		break;
+	}
+
+	wmb();
+	qla2x00_start_iocbs(sp);
+done:
+	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 245e7af..b20a716 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -598,9 +598,54 @@ skip_rio:
 		break;
 
 	case MBA_PORT_UPDATE:		/* Port database update */
-		/* Only handle SCNs for our Vport index. */
-		if (vha->vp_idx && vha->vp_idx != (mb[3] & 0xff))
+		/*
+		 * Handle only global and vn-port update events
+		 *
+		 * Relevant inputs:
+		 * mb[1] = N_Port handle of changed port
+		 * OR 0xffff for global event
+		 * mb[2] = New login state
+		 * 7 = Port logged out
+		 * mb[3] = LSB is vp_idx, 0xff = all vps
+		 *
+		 * Skip processing if:
+		 *       Event is global, vp_idx is NOT all vps,
+		 *           vp_idx does not match
+		 *       Event is not global, vp_idx does not match
+		 */
+		if ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff)
+			|| (mb[1] != 0xffff)) {
+			if (vha->vp_idx != (mb[3] & 0xff))
+				break;
+		}
+
+		/* Global event -- port logout or port unavailable. */
+		if (mb[1] == 0xffff && mb[2] == 0x7) {
+			DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
+			    vha->host_no));
+			DEBUG(printk(KERN_INFO
+			    "scsi(%ld): Port unavailable %04x %04x %04x.\n",
+			    vha->host_no, mb[1], mb[2], mb[3]));
+
+			if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
+				atomic_set(&vha->loop_state, LOOP_DOWN);
+				atomic_set(&vha->loop_down_timer,
+				    LOOP_DOWN_TIME);
+				vha->device_flags |= DFLG_NO_CABLE;
+				qla2x00_mark_all_devices_lost(vha, 1);
+			}
+
+			if (vha->vp_idx) {
+				atomic_set(&vha->vp_state, VP_FAILED);
+				fc_vport_set_state(vha->fc_vport,
+				    FC_VPORT_FAILED);
+				qla2x00_mark_all_devices_lost(vha, 1);
+			}
+
+			vha->flags.management_server_logged_in = 0;
+			ha->link_data_rate = PORT_SPEED_UNKNOWN;
 			break;
+		}
 
 		/*
 		 * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
@@ -640,8 +685,9 @@ skip_rio:
 		if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags))
 			break;
 		/* Only handle SCNs for our Vport index. */
-		if (vha->vp_idx && vha->vp_idx != (mb[3] & 0xff))
+		if (ha->flags.npiv_supported && vha->vp_idx != (mb[3] & 0xff))
 			break;
+
 		DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
 		    vha->host_no));
 		DEBUG(printk(KERN_INFO
@@ -874,6 +920,249 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
 	}
 }
 
+static srb_t *
+qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
+    struct req_que *req, void *iocb)
+{
+	struct qla_hw_data *ha = vha->hw;
+	sts_entry_t *pkt = iocb;
+	srb_t *sp = NULL;
+	uint16_t index;
+
+	index = LSW(pkt->handle);
+	if (index >= MAX_OUTSTANDING_COMMANDS) {
+		qla_printk(KERN_WARNING, ha,
+		    "%s: Invalid completion handle (%x).\n", func, index);
+		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		goto done;
+	}
+	sp = req->outstanding_cmds[index];
+	if (!sp) {
+		qla_printk(KERN_WARNING, ha,
+		    "%s: Invalid completion handle (%x) -- timed-out.\n", func,
+		    index);
+		return sp;
+	}
+	if (sp->handle != index) {
+		qla_printk(KERN_WARNING, ha,
+		    "%s: SRB handle (%x) mismatch %x.\n", func, sp->handle,
+		    index);
+		return NULL;
+	}
+	req->outstanding_cmds[index] = NULL;
+done:
+	return sp;
+}
+
+static void
+qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
+    struct mbx_entry *mbx)
+{
+	const char func[] = "MBX-IOCB";
+	const char *type;
+	struct qla_hw_data *ha = vha->hw;
+	fc_port_t *fcport;
+	srb_t *sp;
+	struct srb_logio *lio;
+	uint16_t data[2];
+
+	sp = qla2x00_get_sp_from_handle(vha, func, req, mbx);
+	if (!sp)
+		return;
+
+	type = NULL;
+	lio = sp->ctx;
+	switch (lio->ctx.type) {
+	case SRB_LOGIN_CMD:
+		type = "login";
+		break;
+	case SRB_LOGOUT_CMD:
+		type = "logout";
+		break;
+	default:
+		qla_printk(KERN_WARNING, ha,
+		    "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
+		    lio->ctx.type);
+		return;
+	}
+
+	del_timer(&lio->ctx.timer);
+	fcport = sp->fcport;
+
+	data[0] = data[1] = 0;
+	if (mbx->entry_status) {
+		DEBUG2(printk(KERN_WARNING
+		    "scsi(%ld:%x): Async-%s error entry - entry-status=%x "
+		    "status=%x state-flag=%x status-flags=%x.\n",
+		    fcport->vha->host_no, sp->handle, type,
+		    mbx->entry_status, le16_to_cpu(mbx->status),
+		    le16_to_cpu(mbx->state_flags),
+		    le16_to_cpu(mbx->status_flags)));
+		DEBUG2(qla2x00_dump_buffer((uint8_t *)mbx, sizeof(*mbx)));
+
+		data[0] = MBS_COMMAND_ERROR;
+		data[1] = lio->flags & SRB_LOGIN_RETRIED ?
+		    QLA_LOGIO_LOGIN_RETRIED: 0;
+		goto done_post_logio_done_work;
+	}
+
+	if (!mbx->status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
+		DEBUG2(printk(KERN_DEBUG
+		    "scsi(%ld:%x): Async-%s complete - mbx1=%x.\n",
+		    fcport->vha->host_no, sp->handle, type,
+		    le16_to_cpu(mbx->mb1)));
+
+		data[0] = MBS_COMMAND_COMPLETE;
+		if (lio->ctx.type == SRB_LOGIN_CMD && le16_to_cpu(mbx->mb1) & BIT_1)
+			fcport->flags |= FCF_FCP2_DEVICE;
+
+		goto done_post_logio_done_work;
+	}
+
+	data[0] = le16_to_cpu(mbx->mb0);
+	switch (data[0]) {
+	case MBS_PORT_ID_USED:
+		data[1] = le16_to_cpu(mbx->mb1);
+		break;
+	case MBS_LOOP_ID_USED:
+		break;
+	default:
+		data[0] = MBS_COMMAND_ERROR;
+		data[1] = lio->flags & SRB_LOGIN_RETRIED ?
+		    QLA_LOGIO_LOGIN_RETRIED: 0;
+		break;
+	}
+
+	DEBUG2(printk(KERN_WARNING
+	    "scsi(%ld:%x): Async-%s failed - status=%x mb0=%x mb1=%x mb2=%x "
+	    "mb6=%x mb7=%x.\n",
+	    fcport->vha->host_no, sp->handle, type, le16_to_cpu(mbx->status),
+	    le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1),
+	    le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6),
+	    le16_to_cpu(mbx->mb7)));
+
+done_post_logio_done_work:
+	lio->ctx.type == SRB_LOGIN_CMD ?
+	    qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
+	    qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
+
+	lio->ctx.free(sp);
+}
+
+static void
+qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
+    struct logio_entry_24xx *logio)
+{
+	const char func[] = "LOGIO-IOCB";
+	const char *type;
+	struct qla_hw_data *ha = vha->hw;
+	fc_port_t *fcport;
+	srb_t *sp;
+	struct srb_logio *lio;
+	uint16_t data[2];
+	uint32_t iop[2];
+
+	sp = qla2x00_get_sp_from_handle(vha, func, req, logio);
+	if (!sp)
+		return;
+
+	type = NULL;
+	lio = sp->ctx;
+	switch (lio->ctx.type) {
+	case SRB_LOGIN_CMD:
+		type = "login";
+		break;
+	case SRB_LOGOUT_CMD:
+		type = "logout";
+		break;
+	default:
+		qla_printk(KERN_WARNING, ha,
+		    "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
+		    lio->ctx.type);
+		return;
+	}
+
+	del_timer(&lio->ctx.timer);
+	fcport = sp->fcport;
+
+	data[0] = data[1] = 0;
+	if (logio->entry_status) {
+		DEBUG2(printk(KERN_WARNING
+		    "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n",
+		    fcport->vha->host_no, sp->handle, type,
+		    logio->entry_status));
+		DEBUG2(qla2x00_dump_buffer((uint8_t *)logio, sizeof(*logio)));
+
+		data[0] = MBS_COMMAND_ERROR;
+		data[1] = lio->flags & SRB_LOGIN_RETRIED ?
+		    QLA_LOGIO_LOGIN_RETRIED: 0;
+		goto done_post_logio_done_work;
+	}
+
+	if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
+		DEBUG2(printk(KERN_DEBUG
+		    "scsi(%ld:%x): Async-%s complete - iop0=%x.\n",
+		    fcport->vha->host_no, sp->handle, type,
+		    le32_to_cpu(logio->io_parameter[0])));
+
+		data[0] = MBS_COMMAND_COMPLETE;
+		if (lio->ctx.type == SRB_LOGOUT_CMD)
+			goto done_post_logio_done_work;
+
+		iop[0] = le32_to_cpu(logio->io_parameter[0]);
+		if (iop[0] & BIT_4) {
+			fcport->port_type = FCT_TARGET;
+			if (iop[0] & BIT_8)
+				fcport->flags |= FCF_FCP2_DEVICE;
+		}
+		if (iop[0] & BIT_5)
+			fcport->port_type = FCT_INITIATOR;
+		if (logio->io_parameter[7] || logio->io_parameter[8])
+			fcport->supported_classes |= FC_COS_CLASS2;
+		if (logio->io_parameter[9] || logio->io_parameter[10])
+			fcport->supported_classes |= FC_COS_CLASS3;
+
+		goto done_post_logio_done_work;
+	}
+
+	iop[0] = le32_to_cpu(logio->io_parameter[0]);
+	iop[1] = le32_to_cpu(logio->io_parameter[1]);
+	switch (iop[0]) {
+	case LSC_SCODE_PORTID_USED:
+		data[0] = MBS_PORT_ID_USED;
+		data[1] = LSW(iop[1]);
+		break;
+	case LSC_SCODE_NPORT_USED:
+		data[0] = MBS_LOOP_ID_USED;
+		break;
+	case LSC_SCODE_CMD_FAILED:
+		if ((iop[1] & 0xff) == 0x05) {
+			data[0] = MBS_NOT_LOGGED_IN;
+			break;
+		}
+		/* Fall through. */
+	default:
+		data[0] = MBS_COMMAND_ERROR;
+		data[1] = lio->flags & SRB_LOGIN_RETRIED ?
+		    QLA_LOGIO_LOGIN_RETRIED: 0;
+		break;
+	}
+
+	DEBUG2(printk(KERN_WARNING
+	    "scsi(%ld:%x): Async-%s failed - comp=%x iop0=%x iop1=%x.\n",
+	    fcport->vha->host_no, sp->handle, type,
+	    le16_to_cpu(logio->comp_status),
+	    le32_to_cpu(logio->io_parameter[0]),
+	    le32_to_cpu(logio->io_parameter[1])));
+
+done_post_logio_done_work:
+	lio->ctx.type == SRB_LOGIN_CMD ?
+	    qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
+	    qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
+
+	lio->ctx.free(sp);
+}
+
 /**
  * qla2x00_process_response_queue() - Process response queue entries.
  * @ha: SCSI driver HA context
@@ -935,6 +1224,9 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
 		case STATUS_CONT_TYPE:
 			qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
 			break;
+		case MBX_IOCB_TYPE:
+			qla2x00_mbx_iocb_entry(vha, rsp->req,
+			    (struct mbx_entry *)pkt);
 		default:
 			/* Type Not Supported. */
 			DEBUG4(printk(KERN_WARNING
@@ -1223,6 +1515,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 					cp->device->id, cp->device->lun, resid,
 					scsi_bufflen(cp)));
 
+				scsi_set_resid(cp, resid);
 				cp->result = DID_ERROR << 16;
 				break;
 			}
@@ -1544,6 +1837,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
 			qla24xx_report_id_acquisition(vha,
 			    (struct vp_rpt_id_entry_24xx *)pkt);
 			break;
+		case LOGINOUT_PORT_IOCB_TYPE:
+			qla24xx_logio_entry(vha, rsp->req,
+			    (struct logio_entry_24xx *)pkt);
+			break;
 		default:
 			/* Type Not Supported. */
 			DEBUG4(printk(KERN_WARNING
@@ -1723,8 +2020,10 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
 
 	vha = qla25xx_get_host(rsp);
 	qla24xx_process_response_queue(vha, rsp);
-	WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
-
+	if (!ha->mqenable) {
+		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+		RD_REG_DWORD_RELAXED(&reg->hccr);
+	}
 	spin_unlock_irq(&ha->hardware_lock);
 
 	return IRQ_HANDLED;
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index fe69f30..b6202fe 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -1507,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
 
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
 
-	if (ql2xmultique_tag)
+	if (ha->flags.cpu_affinity_enabled)
 		req = ha->req_q_map[0];
 	else
 		req = vha->req;
@@ -2324,7 +2324,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
 	vha = fcport->vha;
 	ha = vha->hw;
 	req = vha->req;
-	if (ql2xmultique_tag)
+	if (ha->flags.cpu_affinity_enabled)
 		rsp = ha->rsp_q_map[tag + 1];
 	else
 		rsp = req->rsp;
@@ -2746,7 +2746,8 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
 	if (rptid_entry->format == 0) {
 		DEBUG15(printk("%s:format 0 : scsi(%ld) number of VPs setup %d,"
 			" number of VPs acquired %d\n", __func__, vha->host_no,
-			MSB(rptid_entry->vp_count), LSB(rptid_entry->vp_count)));
+			MSB(le16_to_cpu(rptid_entry->vp_count)),
+			LSB(le16_to_cpu(rptid_entry->vp_count))));
 		DEBUG15(printk("%s primary port id %02x%02x%02x\n", __func__,
 			rptid_entry->port_id[2], rptid_entry->port_id[1],
 			rptid_entry->port_id[0]));
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index cd78c50..42b799a 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -42,7 +42,6 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
 
 	set_bit(vp_id, ha->vp_idx_map);
 	ha->num_vhosts++;
-	ha->cur_vport_count++;
 	vha->vp_idx = vp_id;
 	list_add_tail(&vha->list, &ha->vp_list);
 	mutex_unlock(&ha->vport_lock);
@@ -58,7 +57,6 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
 	mutex_lock(&ha->vport_lock);
 	vp_id = vha->vp_idx;
 	ha->num_vhosts--;
-	ha->cur_vport_count--;
 	clear_bit(vp_id, ha->vp_idx_map);
 	list_del(&vha->list);
 	mutex_unlock(&ha->vport_lock);
@@ -235,7 +233,11 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
 			atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
 	}
 
-	/* To exclusively reset vport, we need to log it out first.*/
+	/*
+	 * To exclusively reset vport, we need to log it out first.  Note: this
+	 * control_vp can fail if ISP reset is already issued, this is
+	 * expected, as the vp would be already logged out due to ISP reset.
+	 */
 	if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
 		qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL);
 
@@ -247,18 +249,11 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
 static int
 qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
 {
-	struct qla_hw_data *ha = vha->hw;
-	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+	qla2x00_do_work(vha);
 
 	if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
 		/* VP acquired. complete port configuration */
-		if (atomic_read(&base_vha->loop_state) == LOOP_READY) {
-			qla24xx_configure_vp(vha);
-		} else {
-			set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
-			set_bit(VP_DPC_NEEDED, &base_vha->dpc_flags);
-		}
-
+		qla24xx_configure_vp(vha);
 		return 0;
 	}
 
@@ -309,6 +304,9 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
 
 	clear_bit(VP_DPC_NEEDED, &vha->dpc_flags);
 
+	if (!(ha->current_topology & ISP_CFG_F))
+		return;
+
 	list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
 		if (vp->vp_idx)
 			ret = qla2x00_do_dpc_vp(vp);
@@ -413,6 +411,11 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
 
 	vha->flags.init_done = 1;
 
+	mutex_lock(&ha->vport_lock);
+	set_bit(vha->vp_idx, ha->vp_idx_map);
+	ha->cur_vport_count++;
+	mutex_unlock(&ha->vport_lock);
+
 	return vha;
 
 create_vhost_failed:
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index f0396e7..b79fca7 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -287,9 +287,12 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
 	int ques, req, ret;
 	struct qla_hw_data *ha = vha->hw;
 
+	if (!(ha->fw_attributes & BIT_6)) {
+		qla_printk(KERN_INFO, ha,
+			"Firmware is not multi-queue capable\n");
+		goto fail;
+	}
 	if (ql2xmultique_tag) {
-		/* CPU affinity mode */
-		ha->wq = create_workqueue("qla2xxx_wq");
 		/* create a request queue for IO */
 		options |= BIT_7;
 		req = qla25xx_create_req_que(ha, options, 0, 0, -1,
@@ -299,6 +302,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
 				"Can't create request queue\n");
 			goto fail;
 		}
+		ha->wq = create_workqueue("qla2xxx_wq");
 		vha->req = ha->req_q_map[req];
 		options |= BIT_1;
 		for (ques = 1; ques < ha->max_rsp_queues; ques++) {
@@ -309,6 +313,8 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
 				goto fail2;
 			}
 		}
+		ha->flags.cpu_affinity_enabled = 1;
+
 		DEBUG2(qla_printk(KERN_INFO, ha,
 			"CPU affinity mode enabled, no. of response"
 			" queues:%d, no. of request queues:%d\n",
@@ -317,8 +323,13 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
 	return 0;
 fail2:
 	qla25xx_delete_queues(vha);
+	destroy_workqueue(ha->wq);
+	ha->wq = NULL;
 fail:
 	ha->mqenable = 0;
+	kfree(ha->req_q_map);
+	kfree(ha->rsp_q_map);
+	ha->max_req_queues = ha->max_rsp_queues = 1;
 	return 1;
 }
 
@@ -462,6 +473,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
 	sp->flags = 0;
 	CMD_SP(cmd) = (void *)sp;
 	cmd->scsi_done = done;
+	sp->ctx = NULL;
 
 	return sp;
 }
@@ -556,11 +568,8 @@ qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
 	unsigned long wait_iter = ABORT_WAIT_ITER;
 	int ret = QLA_SUCCESS;
 
-	while (CMD_SP(cmd)) {
+	while (CMD_SP(cmd) && wait_iter--) {
 		msleep(ABORT_POLLING_PERIOD);
-
-		if (--wait_iter)
-			break;
 	}
 	if (CMD_SP(cmd))
 		ret = QLA_FUNCTION_FAILED;
@@ -698,6 +707,8 @@ qla2x00_abort_fcport_cmds(fc_port_t *fcport)
 			continue;
 		if (sp->fcport != fcport)
 			continue;
+		if (sp->ctx)
+			continue;
 
 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
 		if (ha->isp_ops->abort_command(sp)) {
@@ -783,7 +794,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 
 		if (sp == NULL)
 			continue;
-
+		if (sp->ctx)
+			continue;
 		if (sp->cmd != cmd)
 			continue;
 
@@ -848,7 +860,8 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
 		sp = req->outstanding_cmds[cnt];
 		if (!sp)
 			continue;
-
+		if (sp->ctx)
+			continue;
 		if (vha->vp_idx != sp->fcport->vha->vp_idx)
 			continue;
 		match = 0;
@@ -1106,8 +1119,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 	struct fc_port *fcport;
 	struct qla_hw_data *ha = vha->hw;
 
-	if (ha->flags.enable_lip_full_login && !vha->vp_idx &&
-	    !IS_QLA81XX(ha)) {
+	if (ha->flags.enable_lip_full_login && !IS_QLA81XX(ha)) {
 		ret = qla2x00_full_login_lip(vha);
 		if (ret != QLA_SUCCESS) {
 			DEBUG2_3(printk("%s(%ld): failed: "
@@ -1120,7 +1132,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha)
 		qla2x00_wait_for_loop_ready(vha);
 	}
 
-	if (ha->flags.enable_lip_reset && !vha->vp_idx) {
+	if (ha->flags.enable_lip_reset) {
 		ret = qla2x00_lip_reset(vha);
 		if (ret != QLA_SUCCESS) {
 			DEBUG2_3(printk("%s(%ld): failed: "
@@ -1154,6 +1166,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
 	int que, cnt;
 	unsigned long flags;
 	srb_t *sp;
+	struct srb_ctx *ctx;
 	struct qla_hw_data *ha = vha->hw;
 	struct req_que *req;
 
@@ -1166,8 +1179,14 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
 			sp = req->outstanding_cmds[cnt];
 			if (sp) {
 				req->outstanding_cmds[cnt] = NULL;
-				sp->cmd->result = res;
-				qla2x00_sp_compl(ha, sp);
+				if (!sp->ctx) {
+					sp->cmd->result = res;
+					qla2x00_sp_compl(ha, sp);
+				} else {
+					ctx = sp->ctx;
+					del_timer_sync(&ctx->timer);
+					ctx->free(sp);
+				}
 			}
 		}
 	}
@@ -1193,6 +1212,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
 	scsi_qla_host_t *vha = shost_priv(sdev->host);
 	struct qla_hw_data *ha = vha->hw;
 	struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
+	fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
 	struct req_que *req = vha->req;
 
 	if (sdev->tagged_supported)
@@ -1201,6 +1221,8 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
 		scsi_deactivate_tcq(sdev, req->max_q_depth);
 
 	rport->dev_loss_tmo = ha->port_down_retry_count;
+	if (sdev->type == TYPE_TAPE)
+		fcport->flags |= FCF_TAPE_PRESENT;
 
 	return 0;
 }
@@ -1923,6 +1945,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	if (ret)
 		goto probe_init_failed;
 	/* Alloc arrays of request and response ring ptrs */
+que_init:
 	if (!qla2x00_alloc_queues(ha)) {
 		qla_printk(KERN_WARNING, ha,
 		"[ERROR] Failed to allocate memory for queue"
@@ -1959,11 +1982,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		goto probe_failed;
 	}
 
-	if (ha->mqenable)
-		if (qla25xx_setup_mode(base_vha))
+	if (ha->mqenable) {
+		if (qla25xx_setup_mode(base_vha)) {
 			qla_printk(KERN_WARNING, ha,
 				"Can't create queues, falling back to single"
 				" queue mode\n");
+			goto que_init;
+		}
+	}
 
 	if (ha->flags.running_gold_fw)
 		goto skip_dpc;
@@ -2155,17 +2181,19 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
     int defer)
 {
 	struct fc_rport *rport;
+	scsi_qla_host_t *base_vha;
 
 	if (!fcport->rport)
 		return;
 
 	rport = fcport->rport;
 	if (defer) {
+		base_vha = pci_get_drvdata(vha->hw->pdev);
 		spin_lock_irq(vha->host->host_lock);
 		fcport->drport = rport;
 		spin_unlock_irq(vha->host->host_lock);
-		set_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags);
-		qla2xxx_wake_dpc(vha);
+		set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
+		qla2xxx_wake_dpc(base_vha);
 	} else
 		fc_remote_port_delete(rport);
 }
@@ -2237,8 +2265,9 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
 	fc_port_t *fcport;
 
 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
-		if (vha->vp_idx != fcport->vp_idx)
+		if (vha->vp_idx != 0 && vha->vp_idx != fcport->vp_idx)
 			continue;
+
 		/*
 		 * No point in marking the device as lost, if the device is
 		 * already DEAD.
@@ -2246,10 +2275,12 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
 		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
 			continue;
 		if (atomic_read(&fcport->state) == FCS_ONLINE) {
-			atomic_set(&fcport->state, FCS_DEVICE_LOST);
-			qla2x00_schedule_rport_del(vha, fcport, defer);
-		} else
-			atomic_set(&fcport->state, FCS_DEVICE_LOST);
+			if (defer)
+				qla2x00_schedule_rport_del(vha, fcport, defer);
+			else if (vha->vp_idx == fcport->vp_idx)
+				qla2x00_schedule_rport_del(vha, fcport, defer);
+		}
+		atomic_set(&fcport->state, FCS_DEVICE_LOST);
 	}
 }
 
@@ -2598,7 +2629,31 @@ qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
 	return qla2x00_post_work(vha, e);
 }
 
-static void
+#define qla2x00_post_async_work(name, type)	\
+int qla2x00_post_async_##name##_work(		\
+    struct scsi_qla_host *vha,			\
+    fc_port_t *fcport, uint16_t *data)		\
+{						\
+	struct qla_work_evt *e;			\
+						\
+	e = qla2x00_alloc_work(vha, type);	\
+	if (!e)					\
+		return QLA_FUNCTION_FAILED;	\
+						\
+	e->u.logio.fcport = fcport;		\
+	if (data) {				\
+		e->u.logio.data[0] = data[0];	\
+		e->u.logio.data[1] = data[1];	\
+	}					\
+	return qla2x00_post_work(vha, e);	\
+}
+
+qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
+qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
+qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
+qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
+
+void
 qla2x00_do_work(struct scsi_qla_host *vha)
 {
 	struct qla_work_evt *e, *tmp;
@@ -2620,6 +2675,21 @@ qla2x00_do_work(struct scsi_qla_host *vha)
 		case QLA_EVT_IDC_ACK:
 			qla81xx_idc_ack(vha, e->u.idc_ack.mb);
 			break;
+		case QLA_EVT_ASYNC_LOGIN:
+			qla2x00_async_login(vha, e->u.logio.fcport,
+			    e->u.logio.data);
+			break;
+		case QLA_EVT_ASYNC_LOGIN_DONE:
+			qla2x00_async_login_done(vha, e->u.logio.fcport,
+			    e->u.logio.data);
+			break;
+		case QLA_EVT_ASYNC_LOGOUT:
+			qla2x00_async_logout(vha, e->u.logio.fcport);
+			break;
+		case QLA_EVT_ASYNC_LOGOUT_DONE:
+			qla2x00_async_logout_done(vha, e->u.logio.fcport,
+			    e->u.logio.data);
+			break;
 		}
 		if (e->flags & QLA_EVT_FLAG_FREE)
 			kfree(e);
@@ -2635,6 +2705,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
 	int status;
 	uint16_t        next_loopid = 0;
 	struct qla_hw_data *ha = vha->hw;
+	uint16_t data[2];
 
 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
 	/*
@@ -2644,6 +2715,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
 		if (atomic_read(&fcport->state) !=
 			FCS_ONLINE && fcport->login_retry) {
 
+			fcport->login_retry--;
 			if (fcport->flags & FCF_FABRIC_DEVICE) {
 				if (fcport->flags & FCF_TAPE_PRESENT)
 					ha->isp_ops->fabric_logout(vha,
@@ -2652,13 +2724,22 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
 							fcport->d_id.b.area,
 							fcport->d_id.b.al_pa);
 
-				status = qla2x00_fabric_login(vha, fcport,
-							&next_loopid);
+				if (IS_ALOGIO_CAPABLE(ha)) {
+					data[0] = 0;
+					data[1] = QLA_LOGIO_LOGIN_RETRIED;
+					status = qla2x00_post_async_login_work(
+					    vha, fcport, data);
+					if (status == QLA_SUCCESS)
+						continue;
+					/* Attempt a retry. */
+					status = 1;
+				} else
+					status = qla2x00_fabric_login(vha,
+					    fcport, &next_loopid);
 			} else
 				status = qla2x00_local_device_login(vha,
 								fcport);
 
-			fcport->login_retry--;
 			if (status == QLA_SUCCESS) {
 				fcport->old_loop_id = fcport->loop_id;
 
@@ -2831,6 +2912,9 @@ qla2x00_do_dpc(void *data)
 	 */
 	ha->dpc_active = 0;
 
+	/* Cleanup any residual CTX SRBs. */
+	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
+
 	return 0;
 }
 
@@ -2971,6 +3055,8 @@ qla2x00_timer(scsi_qla_host_t *vha)
 					sp = req->outstanding_cmds[index];
 					if (!sp)
 						continue;
+					if (sp->ctx)
+						continue;
 					sfcp = sp->fcport;
 					if (!(sfcp->flags & FCF_TAPE_PRESENT))
 						continue;
@@ -2987,8 +3073,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
 
 		/* if the loop has been down for 4 minutes, reinit adapter */
 		if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
-			if (!(vha->device_flags & DFLG_NO_CABLE) &&
-			    !vha->vp_idx) {
+			if (!(vha->device_flags & DFLG_NO_CABLE)) {
 				DEBUG(printk("scsi(%ld): Loop down - "
 				    "aborting ISP.\n",
 				    vha->host_no));
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 8436970..ac107a2 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.01-k4"
+#define QLA2XXX_VERSION      "8.03.01-k6"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	3
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 8025ee1..c196d55 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -227,11 +227,11 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
 	case SCS_DATA_UNDERRUN:
 	case SCS_DATA_OVERRUN:
 		if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) ||
-			(sts_entry->completionStatus == SCS_DATA_OVERRUN)) {
-			DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun, "
-				      "residual = 0x%x\n", ha->host_no,
+		     (sts_entry->completionStatus == SCS_DATA_OVERRUN)) {
+			DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun\n",
+				      ha->host_no,
 				      cmd->device->channel, cmd->device->id,
-				      cmd->device->lun, __func__, residual));
+				      cmd->device->lun, __func__));
 
 			cmd->result = DID_ERROR << 16;
 			break;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2de5f3a..b6e0307 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -994,7 +994,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer,
 	 * all the existing users tried this hard.
 	 */
 	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer,
-				  len + 4, NULL, 30 * HZ, 3, NULL);
+				  len, NULL, 30 * HZ, 3, NULL);
 	if (result)
 		return result;
 
@@ -1021,13 +1021,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 {
 	int i, result;
 	unsigned int len;
-	unsigned char *buf = kmalloc(259, GFP_KERNEL);
+	const unsigned int init_vpd_len = 255;
+	unsigned char *buf = kmalloc(init_vpd_len, GFP_KERNEL);
 
 	if (!buf)
 		return NULL;
 
 	/* Ask for all the pages supported by this device */
-	result = scsi_vpd_inquiry(sdev, buf, 0, 255);
+	result = scsi_vpd_inquiry(sdev, buf, 0, init_vpd_len);
 	if (result)
 		goto fail;
 
@@ -1050,12 +1051,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page)
 	 * Some pages are longer than 255 bytes.  The actual length of
 	 * the page is returned in the header.
 	 */
-	len = (buf[2] << 8) | buf[3];
-	if (len <= 255)
+	len = ((buf[2] << 8) | buf[3]) + 4;
+	if (len <= init_vpd_len)
 		return buf;
 
 	kfree(buf);
-	buf = kmalloc(len + 4, GFP_KERNEL);
+	buf = kmalloc(len, GFP_KERNEL);
 	result = scsi_vpd_inquiry(sdev, buf, page, len);
 	if (result)
 		goto fail;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index a168935..877204d 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -382,9 +382,13 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd)
 		 * who knows?  FIXME(eric)
 		 */
 		return SUCCESS;
+	case RESERVATION_CONFLICT:
+		/*
+		 * let issuer deal with this, it could be just fine
+		 */
+		return SUCCESS;
 	case BUSY:
 	case QUEUE_FULL:
-	case RESERVATION_CONFLICT:
 	default:
 		return FAILED;
 	}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index f3c4089..5987da8 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -896,9 +896,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 			scsi_print_result(cmd);
 			if (driver_byte(result) & DRIVER_SENSE)
 				scsi_print_sense("", cmd);
+			scsi_print_command(cmd);
 		}
-		blk_end_request_all(req, -EIO);
-		scsi_next_command(cmd);
+		if (blk_end_request_err(req, -EIO))
+			scsi_requeue_command(q, cmd);
+		else
+			scsi_next_command(cmd);
 		break;
 	case ACTION_REPREP:
 		/* Unprep the request and put it back at the head of the queue.
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 021e503..1fbf7c7 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -132,7 +132,7 @@ extern struct scsi_transport_template blank_transport_template;
 extern void __scsi_remove_device(struct scsi_device *);
 
 extern struct bus_type scsi_bus_type;
-extern struct attribute_group *scsi_sysfs_shost_attr_groups[];
+extern const struct attribute_group *scsi_sysfs_shost_attr_groups[];
 
 /* scsi_netlink.c */
 #ifdef CONFIG_SCSI_NETLINK
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 91482f2..fde5453 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -275,7 +275,7 @@ struct attribute_group scsi_shost_attr_group = {
 	.attrs =	scsi_sysfs_shost_attrs,
 };
 
-struct attribute_group *scsi_sysfs_shost_attr_groups[] = {
+const struct attribute_group *scsi_sysfs_shost_attr_groups[] = {
 	&scsi_shost_attr_group,
 	NULL
 };
@@ -745,7 +745,7 @@ static struct attribute_group scsi_sdev_attr_group = {
 	.attrs =	scsi_sdev_attrs,
 };
 
-static struct attribute_group *scsi_sdev_attr_groups[] = {
+static const struct attribute_group *scsi_sdev_attr_groups[] = {
 	&scsi_sdev_attr_group,
 	NULL
 };
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 292c02f..b98885d 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -291,7 +291,7 @@ static void fc_scsi_scan_rport(struct work_struct *work);
 #define FC_STARGET_NUM_ATTRS 	3
 #define FC_RPORT_NUM_ATTRS	10
 #define FC_VPORT_NUM_ATTRS	9
-#define FC_HOST_NUM_ATTRS	21
+#define FC_HOST_NUM_ATTRS	22
 
 struct fc_internal {
 	struct scsi_transport_template t;
@@ -3432,7 +3432,7 @@ fc_bsg_jobdone(struct fc_bsg_job *job)
 
 /**
  * fc_bsg_softirq_done - softirq done routine for destroying the bsg requests
- * @req:        BSG request that holds the job to be destroyed
+ * @rq:        BSG request that holds the job to be destroyed
  */
 static void fc_bsg_softirq_done(struct request *rq)
 {
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index b47240c..ad897df 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -36,6 +36,38 @@
 
 #define ISCSI_TRANSPORT_VERSION "2.0-870"
 
+static int dbg_session;
+module_param_named(debug_session, dbg_session, int,
+		   S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug_session,
+		 "Turn on debugging for sessions in scsi_transport_iscsi "
+		 "module. Set to 1 to turn on, and zero to turn off. Default "
+		 "is off.");
+
+static int dbg_conn;
+module_param_named(debug_conn, dbg_conn, int,
+		   S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug_conn,
+		 "Turn on debugging for connections in scsi_transport_iscsi "
+		 "module. Set to 1 to turn on, and zero to turn off. Default "
+		 "is off.");
+
+#define ISCSI_DBG_TRANS_SESSION(_session, dbg_fmt, arg...)		\
+	do {								\
+		if (dbg_session)					\
+			iscsi_cls_session_printk(KERN_INFO, _session,	\
+						 "%s: " dbg_fmt,	\
+						 __func__, ##arg);	\
+	} while (0);
+
+#define ISCSI_DBG_TRANS_CONN(_conn, dbg_fmt, arg...)			\
+	do {								\
+		if (dbg_conn)						\
+			iscsi_cls_conn_printk(KERN_INFO, _conn,		\
+					      "%s: " dbg_fmt,		\
+					      __func__, ##arg);	\
+	} while (0);
+
 struct iscsi_internal {
 	struct scsi_transport_template t;
 	struct iscsi_transport *iscsi_transport;
@@ -377,6 +409,7 @@ static void iscsi_session_release(struct device *dev)
 
 	shost = iscsi_session_to_shost(session);
 	scsi_host_put(shost);
+	ISCSI_DBG_TRANS_SESSION(session, "Completing session release\n");
 	kfree(session);
 }
 
@@ -441,6 +474,9 @@ static int iscsi_user_scan_session(struct device *dev, void *data)
 		return 0;
 
 	session = iscsi_dev_to_session(dev);
+
+	ISCSI_DBG_TRANS_SESSION(session, "Scanning session\n");
+
 	shost = iscsi_session_to_shost(session);
 	ihost = shost->shost_data;
 
@@ -448,8 +484,7 @@ static int iscsi_user_scan_session(struct device *dev, void *data)
 	spin_lock_irqsave(&session->lock, flags);
 	if (session->state != ISCSI_SESSION_LOGGED_IN) {
 		spin_unlock_irqrestore(&session->lock, flags);
-		mutex_unlock(&ihost->mutex);
-		return 0;
+		goto user_scan_exit;
 	}
 	id = session->target_id;
 	spin_unlock_irqrestore(&session->lock, flags);
@@ -462,7 +497,10 @@ static int iscsi_user_scan_session(struct device *dev, void *data)
 			scsi_scan_target(&session->dev, 0, id,
 					 scan_data->lun, 1);
 	}
+
+user_scan_exit:
 	mutex_unlock(&ihost->mutex);
+	ISCSI_DBG_TRANS_SESSION(session, "Completed session scan\n");
 	return 0;
 }
 
@@ -522,7 +560,9 @@ static void session_recovery_timedout(struct work_struct *work)
 	if (session->transport->session_recovery_timedout)
 		session->transport->session_recovery_timedout(session);
 
+	ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n");
 	scsi_target_unblock(&session->dev);
+	ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n");
 }
 
 static void __iscsi_unblock_session(struct work_struct *work)
@@ -534,6 +574,7 @@ static void __iscsi_unblock_session(struct work_struct *work)
 	struct iscsi_cls_host *ihost = shost->shost_data;
 	unsigned long flags;
 
+	ISCSI_DBG_TRANS_SESSION(session, "Unblocking session\n");
 	/*
 	 * The recovery and unblock work get run from the same workqueue,
 	 * so try to cancel it if it was going to run after this unblock.
@@ -553,6 +594,7 @@ static void __iscsi_unblock_session(struct work_struct *work)
 		if (scsi_queue_work(shost, &session->scan_work))
 			atomic_inc(&ihost->nr_scans);
 	}
+	ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking session\n");
 }
 
 /**
@@ -579,10 +621,12 @@ static void __iscsi_block_session(struct work_struct *work)
 				     block_work);
 	unsigned long flags;
 
+	ISCSI_DBG_TRANS_SESSION(session, "Blocking session\n");
 	spin_lock_irqsave(&session->lock, flags);
 	session->state = ISCSI_SESSION_FAILED;
 	spin_unlock_irqrestore(&session->lock, flags);
 	scsi_target_block(&session->dev);
+	ISCSI_DBG_TRANS_SESSION(session, "Completed SCSI target blocking\n");
 	queue_delayed_work(iscsi_eh_timer_workq, &session->recovery_work,
 			   session->recovery_tmo * HZ);
 }
@@ -602,6 +646,8 @@ static void __iscsi_unbind_session(struct work_struct *work)
 	struct iscsi_cls_host *ihost = shost->shost_data;
 	unsigned long flags;
 
+	ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
+
 	/* Prevent new scans and make sure scanning is not in progress */
 	mutex_lock(&ihost->mutex);
 	spin_lock_irqsave(&session->lock, flags);
@@ -616,6 +662,7 @@ static void __iscsi_unbind_session(struct work_struct *work)
 
 	scsi_remove_target(&session->dev);
 	iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION);
+	ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n");
 }
 
 struct iscsi_cls_session *
@@ -647,6 +694,8 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
 	device_initialize(&session->dev);
 	if (dd_size)
 		session->dd_data = &session[1];
+
+	ISCSI_DBG_TRANS_SESSION(session, "Completed session allocation\n");
 	return session;
 }
 EXPORT_SYMBOL_GPL(iscsi_alloc_session);
@@ -712,6 +761,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
 	spin_unlock_irqrestore(&sesslock, flags);
 
 	iscsi_session_event(session, ISCSI_KEVENT_CREATE_SESSION);
+	ISCSI_DBG_TRANS_SESSION(session, "Completed session adding\n");
 	return 0;
 
 release_host:
@@ -752,6 +802,7 @@ static void iscsi_conn_release(struct device *dev)
 	struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
 	struct device *parent = conn->dev.parent;
 
+	ISCSI_DBG_TRANS_CONN(conn, "Releasing conn\n");
 	kfree(conn);
 	put_device(parent);
 }
@@ -774,6 +825,8 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
 	unsigned long flags;
 	int err;
 
+	ISCSI_DBG_TRANS_SESSION(session, "Removing session\n");
+
 	spin_lock_irqsave(&sesslock, flags);
 	list_del(&session->sess_list);
 	spin_unlock_irqrestore(&sesslock, flags);
@@ -807,12 +860,15 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
 					 "for session. Error %d.\n", err);
 
 	transport_unregister_device(&session->dev);
+
+	ISCSI_DBG_TRANS_SESSION(session, "Completing session removal\n");
 	device_del(&session->dev);
 }
 EXPORT_SYMBOL_GPL(iscsi_remove_session);
 
 void iscsi_free_session(struct iscsi_cls_session *session)
 {
+	ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n");
 	iscsi_session_event(session, ISCSI_KEVENT_DESTROY_SESSION);
 	put_device(&session->dev);
 }
@@ -828,6 +884,7 @@ EXPORT_SYMBOL_GPL(iscsi_free_session);
 int iscsi_destroy_session(struct iscsi_cls_session *session)
 {
 	iscsi_remove_session(session);
+	ISCSI_DBG_TRANS_SESSION(session, "Completing session destruction\n");
 	iscsi_free_session(session);
 	return 0;
 }
@@ -885,6 +942,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
 	list_add(&conn->conn_list, &connlist);
 	conn->active = 1;
 	spin_unlock_irqrestore(&connlock, flags);
+
+	ISCSI_DBG_TRANS_CONN(conn, "Completed conn creation\n");
 	return conn;
 
 release_parent_ref:
@@ -912,6 +971,7 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
 	spin_unlock_irqrestore(&connlock, flags);
 
 	transport_unregister_device(&conn->dev);
+	ISCSI_DBG_TRANS_CONN(conn, "Completing conn destruction\n");
 	device_unregister(&conn->dev);
 	return 0;
 }
@@ -1200,6 +1260,9 @@ int iscsi_session_event(struct iscsi_cls_session *session,
 					 "Cannot notify userspace of session "
 					 "event %u. Check iscsi daemon\n",
 					 event);
+
+	ISCSI_DBG_TRANS_SESSION(session, "Completed handling event %d rc %d\n",
+				event, rc);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(iscsi_session_event);
@@ -1221,6 +1284,8 @@ iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep,
 	shost = iscsi_session_to_shost(session);
 	ev->r.c_session_ret.host_no = shost->host_no;
 	ev->r.c_session_ret.sid = session->sid;
+	ISCSI_DBG_TRANS_SESSION(session,
+				"Completed creating transport session\n");
 	return 0;
 }
 
@@ -1246,6 +1311,8 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev)
 
 	ev->r.c_conn_ret.sid = session->sid;
 	ev->r.c_conn_ret.cid = conn->cid;
+
+	ISCSI_DBG_TRANS_CONN(conn, "Completed creating transport conn\n");
 	return 0;
 }
 
@@ -1258,8 +1325,10 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev
 	if (!conn)
 		return -EINVAL;
 
+	ISCSI_DBG_TRANS_CONN(conn, "Destroying transport conn\n");
 	if (transport->destroy_conn)
 		transport->destroy_conn(conn);
+
 	return 0;
 }
 
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 0895d3c..fd47cb1 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -1692,10 +1692,6 @@ sas_attach_transport(struct sas_function_template *ft)
 	i->f = ft;
 
 	count = 0;
-	SETUP_PORT_ATTRIBUTE(num_phys);
-	i->host_attrs[count] = NULL;
-
-	count = 0;
 	SETUP_PHY_ATTRIBUTE(initiator_port_protocols);
 	SETUP_PHY_ATTRIBUTE(target_port_protocols);
 	SETUP_PHY_ATTRIBUTE(device_type);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b7b9fec..a89c421 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -2021,6 +2021,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
 
 	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
 		  sdp->removable ? "removable " : "");
+	put_device(&sdkp->dev);
 }
 
 /**
@@ -2106,6 +2107,7 @@ static int sd_probe(struct device *dev)
 
 	get_device(&sdp->sdev_gendev);
 
+	get_device(&sdkp->dev);	/* prevent release before async_schedule */
 	async_schedule(sd_probe_async, sdkp);
 
 	return 0;
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 4f618f4..55b034b 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -347,6 +347,97 @@ static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
 	return 0;
 }
 
+#define INIT_ALLOC_SIZE 32
+
+static void ses_enclosure_data_process(struct enclosure_device *edev,
+				       struct scsi_device *sdev,
+				       int create)
+{
+	u32 result;
+	unsigned char *buf = NULL, *type_ptr, *desc_ptr, *addl_desc_ptr = NULL;
+	int i, j, page7_len, len, components;
+	struct ses_device *ses_dev = edev->scratch;
+	int types = ses_dev->page1[10];
+	unsigned char *hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
+
+	if (!hdr_buf)
+		goto simple_populate;
+
+	/* re-read page 10 */
+	if (ses_dev->page10)
+		ses_recv_diag(sdev, 10, ses_dev->page10, ses_dev->page10_len);
+	/* Page 7 for the descriptors is optional */
+	result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE);
+	if (result)
+		goto simple_populate;
+
+	page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
+	/* add 1 for trailing '\0' we'll use */
+	buf = kzalloc(len + 1, GFP_KERNEL);
+	if (!buf)
+		goto simple_populate;
+	result = ses_recv_diag(sdev, 7, buf, len);
+	if (result) {
+ simple_populate:
+		kfree(buf);
+		buf = NULL;
+		desc_ptr = NULL;
+		len = 0;
+		page7_len = 0;
+	} else {
+		desc_ptr = buf + 8;
+		len = (desc_ptr[2] << 8) + desc_ptr[3];
+		/* skip past overall descriptor */
+		desc_ptr += len + 4;
+		if (ses_dev->page10)
+			addl_desc_ptr = ses_dev->page10 + 8;
+	}
+	type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
+	components = 0;
+	for (i = 0; i < types; i++, type_ptr += 4) {
+		for (j = 0; j < type_ptr[1]; j++) {
+			char *name = NULL;
+			struct enclosure_component *ecomp;
+
+			if (desc_ptr) {
+				if (desc_ptr >= buf + page7_len) {
+					desc_ptr = NULL;
+				} else {
+					len = (desc_ptr[2] << 8) + desc_ptr[3];
+					desc_ptr += 4;
+					/* Add trailing zero - pushes into
+					 * reserved space */
+					desc_ptr[len] = '\0';
+					name = desc_ptr;
+				}
+			}
+			if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
+			    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
+
+				if (create)
+					ecomp =	enclosure_component_register(edev,
+									     components++,
+									     type_ptr[0],
+									     name);
+				else
+					ecomp = &edev->component[components++];
+
+				if (!IS_ERR(ecomp) && addl_desc_ptr)
+					ses_process_descriptor(ecomp,
+							       addl_desc_ptr);
+			}
+			if (desc_ptr)
+				desc_ptr += len;
+
+			if (addl_desc_ptr)
+				addl_desc_ptr += addl_desc_ptr[1] + 2;
+
+		}
+	}
+	kfree(buf);
+	kfree(hdr_buf);
+}
+
 static void ses_match_to_enclosure(struct enclosure_device *edev,
 				   struct scsi_device *sdev)
 {
@@ -361,6 +452,8 @@ static void ses_match_to_enclosure(struct enclosure_device *edev,
 	if (!buf)
 		return;
 
+	ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
+
 	vpd_len = ((buf[2] << 8) | buf[3]) + 4;
 
 	desc = buf + 4;
@@ -395,28 +488,26 @@ static void ses_match_to_enclosure(struct enclosure_device *edev,
 	kfree(buf);
 }
 
-#define INIT_ALLOC_SIZE 32
-
 static int ses_intf_add(struct device *cdev,
 			struct class_interface *intf)
 {
 	struct scsi_device *sdev = to_scsi_device(cdev->parent);
 	struct scsi_device *tmp_sdev;
-	unsigned char *buf = NULL, *hdr_buf, *type_ptr, *desc_ptr = NULL,
-		*addl_desc_ptr = NULL;
+	unsigned char *buf = NULL, *hdr_buf, *type_ptr;
 	struct ses_device *ses_dev;
 	u32 result;
-	int i, j, types, len, page7_len = 0, components = 0;
+	int i, types, len, components = 0;
 	int err = -ENOMEM;
 	struct enclosure_device *edev;
 	struct ses_component *scomp = NULL;
 
 	if (!scsi_device_enclosure(sdev)) {
 		/* not an enclosure, but might be in one */
-		edev = enclosure_find(&sdev->host->shost_gendev);
-		if (edev) {
+		struct enclosure_device *prev = NULL;
+
+		while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
 			ses_match_to_enclosure(edev, sdev);
-			put_device(&edev->edev);
+			prev = edev;
 		}
 		return -ENODEV;
 	}
@@ -500,6 +591,7 @@ static int ses_intf_add(struct device *cdev,
 		ses_dev->page10_len = len;
 		buf = NULL;
 	}
+	kfree(hdr_buf);
 
 	scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
 	if (!scomp)
@@ -516,72 +608,7 @@ static int ses_intf_add(struct device *cdev,
 	for (i = 0; i < components; i++)
 		edev->component[i].scratch = scomp + i;
 
-	/* Page 7 for the descriptors is optional */
-	result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE);
-	if (result)
-		goto simple_populate;
-
-	page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
-	/* add 1 for trailing '\0' we'll use */
-	buf = kzalloc(len + 1, GFP_KERNEL);
-	if (!buf)
-		goto simple_populate;
-	result = ses_recv_diag(sdev, 7, buf, len);
-	if (result) {
- simple_populate:
-		kfree(buf);
-		buf = NULL;
-		desc_ptr = NULL;
-		addl_desc_ptr = NULL;
-	} else {
-		desc_ptr = buf + 8;
-		len = (desc_ptr[2] << 8) + desc_ptr[3];
-		/* skip past overall descriptor */
-		desc_ptr += len + 4;
-		if (ses_dev->page10)
-			addl_desc_ptr = ses_dev->page10 + 8;
-	}
-	type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11];
-	components = 0;
-	for (i = 0; i < types; i++, type_ptr += 4) {
-		for (j = 0; j < type_ptr[1]; j++) {
-			char *name = NULL;
-			struct enclosure_component *ecomp;
-
-			if (desc_ptr) {
-				if (desc_ptr >= buf + page7_len) {
-					desc_ptr = NULL;
-				} else {
-					len = (desc_ptr[2] << 8) + desc_ptr[3];
-					desc_ptr += 4;
-					/* Add trailing zero - pushes into
-					 * reserved space */
-					desc_ptr[len] = '\0';
-					name = desc_ptr;
-				}
-			}
-			if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
-			    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
-
-				ecomp =	enclosure_component_register(edev,
-							     components++,
-							     type_ptr[0],
-							     name);
-
-				if (!IS_ERR(ecomp) && addl_desc_ptr)
-					ses_process_descriptor(ecomp,
-							       addl_desc_ptr);
-			}
-			if (desc_ptr)
-				desc_ptr += len;
-
-			if (addl_desc_ptr)
-				addl_desc_ptr += addl_desc_ptr[1] + 2;
-
-		}
-	}
-	kfree(buf);
-	kfree(hdr_buf);
+	ses_enclosure_data_process(edev, sdev, 1);
 
 	/* see if there are any devices matching before
 	 * we found the enclosure */
@@ -615,17 +642,26 @@ static int ses_remove(struct device *dev)
 	return 0;
 }
 
-static void ses_intf_remove(struct device *cdev,
-			    struct class_interface *intf)
+static void ses_intf_remove_component(struct scsi_device *sdev)
+{
+	struct enclosure_device *edev, *prev = NULL;
+
+	while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
+		prev = edev;
+		if (!enclosure_remove_device(edev, &sdev->sdev_gendev))
+			break;
+	}
+	if (edev)
+		put_device(&edev->edev);
+}
+
+static void ses_intf_remove_enclosure(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = to_scsi_device(cdev->parent);
 	struct enclosure_device *edev;
 	struct ses_device *ses_dev;
 
-	if (!scsi_device_enclosure(sdev))
-		return;
-
-	edev = enclosure_find(cdev->parent);
+	/*  exact match to this enclosure */
+	edev = enclosure_find(&sdev->sdev_gendev, NULL);
 	if (!edev)
 		return;
 
@@ -643,6 +679,17 @@ static void ses_intf_remove(struct device *cdev,
 	enclosure_unregister(edev);
 }
 
+static void ses_intf_remove(struct device *cdev,
+			    struct class_interface *intf)
+{
+	struct scsi_device *sdev = to_scsi_device(cdev->parent);
+
+	if (!scsi_device_enclosure(sdev))
+		ses_intf_remove_component(sdev);
+	else
+		ses_intf_remove_enclosure(sdev);
+}
+
 static struct class_interface ses_interface = {
 	.add_dev	= ses_intf_add,
 	.remove_dev	= ses_intf_remove,
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9230402..4968c4c 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1811,7 +1811,7 @@ retry:
 	return 0;
 out:
 	for (i = 0; i < k; i++)
-		__free_pages(schp->pages[k], order);
+		__free_pages(schp->pages[i], order);
 
 	if (--order >= 0)
 		goto retry;
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 8d2a95c..09fa886 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -55,6 +55,7 @@ enum {
 	OIS	= 0x30,	/* MU_OUTBOUND_INTERRUPT_STATUS */
 	OIM	= 0x3c,	/* MU_OUTBOUND_INTERRUPT_MASK */
 
+	YIOA_STATUS				= 0x00,
 	YH2I_INT				= 0x20,
 	YINT_EN					= 0x34,
 	YI2H_INT				= 0x9c,
@@ -108,6 +109,10 @@ enum {
 
 	SS_HEAD_HANDSHAKE			= 0x80,
 
+	SS_H2I_INT_RESET			= 0x100,
+
+	SS_MU_OPERATIONAL			= 0x80000000,
+
 	STEX_CDB_LENGTH				= 16,
 	STATUS_VAR_LEN				= 128,
 
@@ -884,7 +889,7 @@ static void stex_ss_mu_intr(struct st_hba *hba)
 		tag = (u16)value;
 		if (unlikely(tag >= hba->host->can_queue)) {
 			printk(KERN_WARNING DRV_NAME
-					"(%s): invalid tag\n", pci_name(hba->pdev));
+				"(%s): invalid tag\n", pci_name(hba->pdev));
 			continue;
 		}
 
@@ -1040,16 +1045,27 @@ static int stex_ss_handshake(struct st_hba *hba)
 	void __iomem *base = hba->mmio_base;
 	struct st_msg_header *msg_h;
 	struct handshake_frame *h;
-	__le32 *scratch = hba->scratch;
+	__le32 *scratch;
 	u32 data;
 	unsigned long before;
 	int ret = 0;
 
-	h = (struct handshake_frame *)(hba->alloc_rq(hba));
-	msg_h = (struct st_msg_header *)h - 1;
+	before = jiffies;
+	while ((readl(base + YIOA_STATUS) & SS_MU_OPERATIONAL) == 0) {
+		if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) {
+			printk(KERN_ERR DRV_NAME
+				"(%s): firmware not operational\n",
+				pci_name(hba->pdev));
+			return -1;
+		}
+		msleep(1);
+	}
+
+	msg_h = (struct st_msg_header *)hba->dma_mem;
 	msg_h->handle = cpu_to_le64(hba->dma_handle);
 	msg_h->flag = SS_HEAD_HANDSHAKE;
 
+	h = (struct handshake_frame *)(msg_h + 1);
 	h->rb_phy = cpu_to_le64(hba->dma_handle);
 	h->req_sz = cpu_to_le16(hba->rq_size);
 	h->req_cnt = cpu_to_le16(hba->rq_count+1);
@@ -1205,6 +1221,13 @@ static void stex_hard_reset(struct st_hba *hba)
 			hba->pdev->saved_config_space[i]);
 }
 
+static void stex_ss_reset(struct st_hba *hba)
+{
+	writel(SS_H2I_INT_RESET, hba->mmio_base + YH2I_INT);
+	readl(hba->mmio_base + YH2I_INT);
+	ssleep(5);
+}
+
 static int stex_reset(struct scsi_cmnd *cmd)
 {
 	struct st_hba *hba;
@@ -1221,6 +1244,8 @@ static int stex_reset(struct scsi_cmnd *cmd)
 
 	if (hba->cardtype == st_shasta)
 		stex_hard_reset(hba);
+	else if (hba->cardtype == st_yel)
+		stex_ss_reset(hba);
 
 	if (hba->cardtype != st_yosemite) {
 		if (stex_handshake(hba)) {
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index cb6d85d..1e3d193 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -86,7 +86,7 @@ static void serial21285_enable_ms(struct uart_port *port)
 static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
 {
 	struct uart_port *port = dev_id;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	unsigned int status, ch, flag, rxs, max_count = 256;
 
 	status = *CSR_UARTFLG;
@@ -124,7 +124,7 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id)
 static irqreturn_t serial21285_tx_chars(int irq, void *dev_id)
 {
 	struct uart_port *port = dev_id;
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 	int count = 256;
 
 	if (port->x_char) {
@@ -235,8 +235,8 @@ serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
 	quot = uart_get_divisor(port, baud);
 
-	if (port->info && port->info->port.tty) {
-		struct tty_struct *tty = port->info->port.tty;
+	if (port->state && port->state->port.tty) {
+		struct tty_struct *tty = port->state->port.tty;
 		unsigned int b = port->uartclk / (16 * quot);
 		tty_encode_baud_rate(tty, b, b);
 	}
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index fb867a9..2209620 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1382,7 +1382,7 @@ static void serial8250_enable_ms(struct uart_port *port)
 static void
 receive_chars(struct uart_8250_port *up, unsigned int *status)
 {
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned char ch, lsr = *status;
 	int max_count = 256;
 	char flag;
@@ -1457,7 +1457,7 @@ ignore_char:
 
 static void transmit_chars(struct uart_8250_port *up)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 	int count;
 
 	if (up->port.x_char) {
@@ -1500,7 +1500,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
 	status |= up->msr_saved_flags;
 	up->msr_saved_flags = 0;
 	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
-	    up->port.info != NULL) {
+	    up->port.state != NULL) {
 		if (status & UART_MSR_TERI)
 			up->port.icount.rng++;
 		if (status & UART_MSR_DDSR)
@@ -1510,7 +1510,7 @@ static unsigned int check_modem_status(struct uart_8250_port *up)
 		if (status & UART_MSR_DCTS)
 			uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
 
-		wake_up_interruptible(&up->port.info->delta_msr_wait);
+		wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 	}
 
 	return status;
@@ -1677,7 +1677,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up)
 		INIT_LIST_HEAD(&up->list);
 		i->head = &up->list;
 		spin_unlock_irq(&i->lock);
-
+		irq_flags |= up->port.irqflags;
 		ret = request_irq(up->port.irq, serial8250_interrupt,
 				  irq_flags, "serial", i);
 		if (ret < 0)
@@ -1764,7 +1764,7 @@ static void serial8250_backup_timeout(unsigned long data)
 	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 	spin_unlock_irqrestore(&up->port.lock, flags);
 	if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
-	    (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) &&
+	    (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
 	    (lsr & UART_LSR_THRE)) {
 		iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
 		iir |= UART_IIR_THRI;
@@ -2026,7 +2026,7 @@ static int serial8250_startup(struct uart_port *port)
 		 * allow register changes to become visible.
 		 */
 		spin_lock_irqsave(&up->port.lock, flags);
-		if (up->port.flags & UPF_SHARE_IRQ)
+		if (up->port.irqflags & IRQF_SHARED)
 			disable_irq_nosync(up->port.irq);
 
 		wait_for_xmitr(up, UART_LSR_THRE);
@@ -2039,7 +2039,7 @@ static int serial8250_startup(struct uart_port *port)
 		iir = serial_in(up, UART_IIR);
 		serial_out(up, UART_IER, 0);
 
-		if (up->port.flags & UPF_SHARE_IRQ)
+		if (up->port.irqflags & IRQF_SHARED)
 			enable_irq(up->port.irq);
 		spin_unlock_irqrestore(&up->port.lock, flags);
 
@@ -2272,7 +2272,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
 	/*
 	 * Ask the core to calculate the divisor for us.
 	 */
-	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
+	baud = uart_get_baud_rate(port, termios, old,
+				  port->uartclk / 16 / 0xffff,
+				  port->uartclk / 16);
 	quot = serial8250_get_divisor(port, baud);
 
 	/*
@@ -2671,6 +2673,7 @@ static void __init serial8250_isa_init_ports(void)
 	     i++, up++) {
 		up->port.iobase   = old_serial_port[i].port;
 		up->port.irq      = irq_canonicalize(old_serial_port[i].irq);
+		up->port.irqflags = old_serial_port[i].irqflags;
 		up->port.uartclk  = old_serial_port[i].baud_base * 16;
 		up->port.flags    = old_serial_port[i].flags;
 		up->port.hub6     = old_serial_port[i].hub6;
@@ -2679,7 +2682,7 @@ static void __init serial8250_isa_init_ports(void)
 		up->port.regshift = old_serial_port[i].iomem_reg_shift;
 		set_io_from_upio(&up->port);
 		if (share_irqs)
-			up->port.flags |= UPF_SHARE_IRQ;
+			up->port.irqflags |= IRQF_SHARED;
 	}
 }
 
@@ -2869,6 +2872,7 @@ int __init early_serial_setup(struct uart_port *port)
 	p->iobase       = port->iobase;
 	p->membase      = port->membase;
 	p->irq          = port->irq;
+	p->irqflags     = port->irqflags;
 	p->uartclk      = port->uartclk;
 	p->fifosize     = port->fifosize;
 	p->regshift     = port->regshift;
@@ -2942,6 +2946,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 		port.iobase		= p->iobase;
 		port.membase		= p->membase;
 		port.irq		= p->irq;
+		port.irqflags		= p->irqflags;
 		port.uartclk		= p->uartclk;
 		port.regshift		= p->regshift;
 		port.iotype		= p->iotype;
@@ -2954,7 +2959,7 @@ static int __devinit serial8250_probe(struct platform_device *dev)
 		port.serial_out		= p->serial_out;
 		port.dev		= &dev->dev;
 		if (share_irqs)
-			port.flags |= UPF_SHARE_IRQ;
+			port.irqflags |= IRQF_SHARED;
 		ret = serial8250_register_port(&port);
 		if (ret < 0) {
 			dev_err(&dev->dev, "unable to register port at index %d "
@@ -3096,6 +3101,7 @@ int serial8250_register_port(struct uart_port *port)
 		uart->port.iobase       = port->iobase;
 		uart->port.membase      = port->membase;
 		uart->port.irq          = port->irq;
+		uart->port.irqflags     = port->irqflags;
 		uart->port.uartclk      = port->uartclk;
 		uart->port.fifosize     = port->fifosize;
 		uart->port.regshift     = port->regshift;
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 5202603..6e19ea3 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -25,6 +25,7 @@ struct old_serial_port {
 	unsigned char io_type;
 	unsigned char *iomem_base;
 	unsigned short iomem_reg_shift;
+	unsigned long irqflags;
 };
 
 /*
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6553833..03422ce 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -459,7 +459,7 @@ config SERIAL_SAMSUNG_UARTS
 	int
 	depends on ARM && PLAT_S3C
 	default 2 if ARCH_S3C2400
-	default 4 if ARCH_S3C64XX || CPU_S3C2443
+	default 4 if ARCH_S5PC1XX || ARCH_S3C64XX || CPU_S3C2443
 	default 3
 	help
 	  Select the number of available UART ports for the Samsung S3C
@@ -533,6 +533,13 @@ config SERIAL_S3C6400
 	  Serial port support for the Samsung S3C6400 and S3C6410
 	  SoCs
 
+config SERIAL_S5PC100
+	tristate "Samsung S5PC100 Serial port support"
+	depends on SERIAL_SAMSUNG && CPU_S5PC100
+	default y
+	help
+	  Serial port support for the Samsung S5PC100 SoCs
+
 config SERIAL_MAX3100
 	tristate "MAX3100 support"
 	depends on SPI
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index d5a2998..97f6fcc 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
 obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
 obj-$(CONFIG_SERIAL_S3C24A0) += s3c24a0.o
 obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
+obj-$(CONFIG_SERIAL_S5PC100) += s3c6400.o
 obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
 obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o
 obj-$(CONFIG_SERIAL_MUX) += mux.o
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 58a4879..429a8ae 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -117,7 +117,7 @@ static void pl010_enable_ms(struct uart_port *port)
 
 static void pl010_rx_chars(struct uart_amba_port *uap)
 {
-	struct tty_struct *tty = uap->port.info->port.tty;
+	struct tty_struct *tty = uap->port.state->port.tty;
 	unsigned int status, ch, flag, rsr, max_count = 256;
 
 	status = readb(uap->port.membase + UART01x_FR);
@@ -172,7 +172,7 @@ static void pl010_rx_chars(struct uart_amba_port *uap)
 
 static void pl010_tx_chars(struct uart_amba_port *uap)
 {
-	struct circ_buf *xmit = &uap->port.info->xmit;
+	struct circ_buf *xmit = &uap->port.state->xmit;
 	int count;
 
 	if (uap->port.x_char) {
@@ -225,7 +225,7 @@ static void pl010_modem_status(struct uart_amba_port *uap)
 	if (delta & UART01x_FR_CTS)
 		uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
 
-	wake_up_interruptible(&uap->port.info->delta_msr_wait);
+	wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
 }
 
 static irqreturn_t pl010_int(int irq, void *dev_id)
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index bf82e28..ef7adc8 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -124,7 +124,7 @@ static void pl011_enable_ms(struct uart_port *port)
 
 static void pl011_rx_chars(struct uart_amba_port *uap)
 {
-	struct tty_struct *tty = uap->port.info->port.tty;
+	struct tty_struct *tty = uap->port.state->port.tty;
 	unsigned int status, ch, flag, max_count = 256;
 
 	status = readw(uap->port.membase + UART01x_FR);
@@ -175,7 +175,7 @@ static void pl011_rx_chars(struct uart_amba_port *uap)
 
 static void pl011_tx_chars(struct uart_amba_port *uap)
 {
-	struct circ_buf *xmit = &uap->port.info->xmit;
+	struct circ_buf *xmit = &uap->port.state->xmit;
 	int count;
 
 	if (uap->port.x_char) {
@@ -226,7 +226,7 @@ static void pl011_modem_status(struct uart_amba_port *uap)
 	if (delta & UART01x_FR_CTS)
 		uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
 
-	wake_up_interruptible(&uap->port.info->delta_msr_wait);
+	wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
 }
 
 static irqreturn_t pl011_int(int irq, void *dev_id)
@@ -826,6 +826,28 @@ static int pl011_remove(struct amba_device *dev)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int pl011_suspend(struct amba_device *dev, pm_message_t state)
+{
+	struct uart_amba_port *uap = amba_get_drvdata(dev);
+
+	if (!uap)
+		return -EINVAL;
+
+	return uart_suspend_port(&amba_reg, &uap->port);
+}
+
+static int pl011_resume(struct amba_device *dev)
+{
+	struct uart_amba_port *uap = amba_get_drvdata(dev);
+
+	if (!uap)
+		return -EINVAL;
+
+	return uart_resume_port(&amba_reg, &uap->port);
+}
+#endif
+
 static struct amba_id pl011_ids[] __initdata = {
 	{
 		.id	= 0x00041011,
@@ -847,6 +869,10 @@ static struct amba_driver pl011_driver = {
 	.id_table	= pl011_ids,
 	.probe		= pl011_probe,
 	.remove		= pl011_remove,
+#ifdef CONFIG_PM
+	.suspend	= pl011_suspend,
+	.resume		= pl011_resume,
+#endif
 };
 
 static int __init pl011_init(void)
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 607d43a..3551c5c 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -427,7 +427,7 @@ static void atmel_rx_chars(struct uart_port *port)
  */
 static void atmel_tx_chars(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	if (port->x_char && UART_GET_CSR(port) & ATMEL_US_TXRDY) {
 		UART_PUT_CHAR(port, port->x_char);
@@ -560,7 +560,7 @@ static irqreturn_t atmel_interrupt(int irq, void *dev_id)
 static void atmel_tx_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 	struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
 	int count;
 
@@ -663,14 +663,14 @@ static void atmel_rx_from_ring(struct uart_port *port)
 	 * uart_start(), which takes the lock.
 	 */
 	spin_unlock(&port->lock);
-	tty_flip_buffer_push(port->info->port.tty);
+	tty_flip_buffer_push(port->state->port.tty);
 	spin_lock(&port->lock);
 }
 
 static void atmel_rx_from_dma(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	struct atmel_dma_buffer *pdc;
 	int rx_idx = atmel_port->pdc_rx_idx;
 	unsigned int head;
@@ -776,7 +776,7 @@ static void atmel_tasklet_func(unsigned long data)
 		if (status_change & ATMEL_US_CTS)
 			uart_handle_cts_change(port, !(status & ATMEL_US_CTS));
 
-		wake_up_interruptible(&port->info->delta_msr_wait);
+		wake_up_interruptible(&port->state->port.delta_msr_wait);
 
 		atmel_port->irq_status_prev = status;
 	}
@@ -795,7 +795,7 @@ static void atmel_tasklet_func(unsigned long data)
 static int atmel_startup(struct uart_port *port)
 {
 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	int retval;
 
 	/*
@@ -854,7 +854,7 @@ static int atmel_startup(struct uart_port *port)
 	}
 	if (atmel_use_dma_tx(port)) {
 		struct atmel_dma_buffer *pdc = &atmel_port->pdc_tx;
-		struct circ_buf *xmit = &port->info->xmit;
+		struct circ_buf *xmit = &port->state->xmit;
 
 		pdc->buf = xmit->buf;
 		pdc->dma_addr = dma_map_single(port->dev,
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index b4a7650..50abb7e 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -42,6 +42,10 @@
 # undef CONFIG_EARLY_PRINTK
 #endif
 
+#ifdef CONFIG_SERIAL_BFIN_MODULE
+# undef CONFIG_EARLY_PRINTK
+#endif
+
 /* UART name and device definitions */
 #define BFIN_SERIAL_NAME	"ttyBF"
 #define BFIN_SERIAL_MAJOR	204
@@ -140,7 +144,7 @@ static void bfin_serial_stop_tx(struct uart_port *port)
 {
 	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
 #ifdef CONFIG_SERIAL_BFIN_DMA
-	struct circ_buf *xmit = &uart->port.info->xmit;
+	struct circ_buf *xmit = &uart->port.state->xmit;
 #endif
 
 	while (!(UART_GET_LSR(uart) & TEMT))
@@ -167,7 +171,7 @@ static void bfin_serial_stop_tx(struct uart_port *port)
 static void bfin_serial_start_tx(struct uart_port *port)
 {
 	struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
-	struct tty_struct *tty = uart->port.info->port.tty;
+	struct tty_struct *tty = uart->port.state->port.tty;
 
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
 	if (uart->scts && !(bfin_serial_get_mctrl(&uart->port) & TIOCM_CTS)) {
@@ -239,10 +243,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
 			return;
 		}
 
-	if (!uart->port.info || !uart->port.info->port.tty)
+	if (!uart->port.state || !uart->port.state->port.tty)
 		return;
 #endif
-	tty = uart->port.info->port.tty;
+	tty = uart->port.state->port.tty;
 
 	if (ANOMALY_05000363) {
 		/* The BF533 (and BF561) family of processors have a nice anomaly
@@ -327,7 +331,7 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
 
 static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
 {
-	struct circ_buf *xmit = &uart->port.info->xmit;
+	struct circ_buf *xmit = &uart->port.state->xmit;
 
 	if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
 #ifdef CONFIG_BF54x
@@ -394,7 +398,7 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
 #ifdef CONFIG_SERIAL_BFIN_DMA
 static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 {
-	struct circ_buf *xmit = &uart->port.info->xmit;
+	struct circ_buf *xmit = &uart->port.state->xmit;
 
 	uart->tx_done = 0;
 
@@ -432,7 +436,7 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 
 static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
 {
-	struct tty_struct *tty = uart->port.info->port.tty;
+	struct tty_struct *tty = uart->port.state->port.tty;
 	int i, flg, status;
 
 	status = UART_GET_LSR(uart);
@@ -525,7 +529,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
 static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
 {
 	struct bfin_serial_port *uart = dev_id;
-	struct circ_buf *xmit = &uart->port.info->xmit;
+	struct circ_buf *xmit = &uart->port.state->xmit;
 
 #ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
 	if (uart->scts && !(bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
@@ -961,10 +965,10 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
 	int line = port->line;
 	unsigned short val;
 
-	if (line >= port->info->port.tty->driver->num)
+	if (line >= port->state->port.tty->driver->num)
 		return;
 
-	switch (port->info->port.tty->termios->c_line) {
+	switch (port->state->port.tty->termios->c_line) {
 	case N_IRDA:
 		val = UART_GET_GCTL(&bfin_serial_ports[line]);
 		val |= (IREN | RPOLC);
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index c108b1a..088bb35 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -178,7 +178,7 @@ static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
 static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
 {
 	struct sport_uart_port *up = dev_id;
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned int ch;
 
 	do {
@@ -205,7 +205,7 @@ static irqreturn_t sport_uart_tx_irq(int irq, void *dev_id)
 static irqreturn_t sport_uart_err_irq(int irq, void *dev_id)
 {
 	struct sport_uart_port *up = dev_id;
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned int stat = SPORT_GET_STAT(up);
 
 	/* Overflow in RX FIFO */
@@ -290,7 +290,7 @@ fail1:
 
 static void sport_uart_tx_chars(struct sport_uart_port *up)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 
 	if (SPORT_GET_STAT(up) & TXF)
 		return;
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 80e7642..b6acd19 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -93,7 +93,7 @@ static void clps711xuart_enable_ms(struct uart_port *port)
 static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
 {
 	struct uart_port *port = dev_id;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	unsigned int status, ch, flg;
 
 	status = clps_readl(SYSFLG(port));
@@ -147,7 +147,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id)
 static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id)
 {
 	struct uart_port *port = dev_id;
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 	int count;
 
 	if (port->x_char) {
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index f8df068..8d349b2 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -244,7 +244,7 @@ static void cpm_uart_int_rx(struct uart_port *port)
 	int i;
 	unsigned char ch;
 	u8 *cp;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
 	cbd_t __iomem *bdp;
 	u16 status;
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index 6042b87..57421d7 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -197,7 +197,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
 	while ((status = dz_in(dport, DZ_RBUF)) & DZ_DVAL) {
 		dport = &mux->dport[LINE(status)];
 		uport = &dport->port;
-		tty = uport->info->port.tty;	/* point to the proper dev */
+		tty = uport->state->port.tty;	/* point to the proper dev */
 
 		ch = UCHAR(status);		/* grab the char */
 		flag = TTY_NORMAL;
@@ -249,7 +249,7 @@ static inline void dz_receive_chars(struct dz_mux *mux)
 	}
 	for (i = 0; i < DZ_NB_PORT; i++)
 		if (lines_rx[i])
-			tty_flip_buffer_push(mux->dport[i].port.info->port.tty);
+			tty_flip_buffer_push(mux->dport[i].port.state->port.tty);
 }
 
 /*
@@ -268,7 +268,7 @@ static inline void dz_transmit_chars(struct dz_mux *mux)
 
 	status = dz_in(dport, DZ_CSR);
 	dport = &mux->dport[LINE(status)];
-	xmit = &dport->port.info->xmit;
+	xmit = &dport->port.state->xmit;
 
 	if (dport->port.x_char) {		/* XON/XOFF chars */
 		dz_out(dport, DZ_TDR, dport->port.x_char);
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index cd1b6a4..2d7feec 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -617,7 +617,7 @@ static void shutdown(struct icom_port *icom_port)
 	 * disable break condition
 	 */
 	cmdReg = readb(&icom_port->dram->CmdReg);
-	if ((cmdReg | CMD_SND_BREAK) == CMD_SND_BREAK) {
+	if (cmdReg & CMD_SND_BREAK) {
 		writeb(cmdReg & ~CMD_SND_BREAK, &icom_port->dram->CmdReg);
 	}
 }
@@ -627,7 +627,7 @@ static int icom_write(struct uart_port *port)
 	unsigned long data_count;
 	unsigned char cmdReg;
 	unsigned long offset;
-	int temp_tail = port->info->xmit.tail;
+	int temp_tail = port->state->xmit.tail;
 
 	trace(ICOM_PORT, "WRITE", 0);
 
@@ -638,11 +638,11 @@ static int icom_write(struct uart_port *port)
 	}
 
 	data_count = 0;
-	while ((port->info->xmit.head != temp_tail) &&
+	while ((port->state->xmit.head != temp_tail) &&
 	       (data_count <= XMIT_BUFF_SZ)) {
 
 		ICOM_PORT->xmit_buf[data_count++] =
-		    port->info->xmit.buf[temp_tail];
+		    port->state->xmit.buf[temp_tail];
 
 		temp_tail++;
 		temp_tail &= (UART_XMIT_SIZE - 1);
@@ -694,8 +694,8 @@ static inline void check_modem_status(struct icom_port *icom_port)
 			uart_handle_cts_change(&icom_port->uart_port,
 					       delta_status & ICOM_CTS);
 
-		wake_up_interruptible(&icom_port->uart_port.info->
-				      delta_msr_wait);
+		wake_up_interruptible(&icom_port->uart_port.state->
+				      port.delta_msr_wait);
 		old_status = status;
 	}
 	spin_unlock(&icom_port->uart_port.lock);
@@ -718,10 +718,10 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 		icom_port->uart_port.icount.tx += count;
 
 		for (i=0; i<count &&
-			!uart_circ_empty(&icom_port->uart_port.info->xmit); i++) {
+			!uart_circ_empty(&icom_port->uart_port.state->xmit); i++) {
 
-			icom_port->uart_port.info->xmit.tail++;
-			icom_port->uart_port.info->xmit.tail &=
+			icom_port->uart_port.state->xmit.tail++;
+			icom_port->uart_port.state->xmit.tail &=
 				(UART_XMIT_SIZE - 1);
 		}
 
@@ -735,7 +735,7 @@ static void xmit_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 static void recv_interrupt(u16 port_int_reg, struct icom_port *icom_port)
 {
 	short int count, rcv_buff;
-	struct tty_struct *tty = icom_port->uart_port.info->port.tty;
+	struct tty_struct *tty = icom_port->uart_port.state->port.tty;
 	unsigned short int status;
 	struct uart_icount *icount;
 	unsigned long offset;
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 5d7b58f..18130f1 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -67,21 +67,8 @@
 #define UBIR  0xa4 /* BRM Incremental Register */
 #define UBMR  0xa8 /* BRM Modulator Register */
 #define UBRC  0xac /* Baud Rate Count Register */
-#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2
-#define ONEMS 0xb0 /* One Millisecond register */
-#define UTS   0xb4 /* UART Test Register */
-#endif
-#ifdef CONFIG_ARCH_MX1
-#define BIPR1 0xb0 /* Incremental Preset Register 1 */
-#define BIPR2 0xb4 /* Incremental Preset Register 2 */
-#define BIPR3 0xb8 /* Incremental Preset Register 3 */
-#define BIPR4 0xbc /* Incremental Preset Register 4 */
-#define BMPR1 0xc0 /* BRM Modulator Register 1 */
-#define BMPR2 0xc4 /* BRM Modulator Register 2 */
-#define BMPR3 0xc8 /* BRM Modulator Register 3 */
-#define BMPR4 0xcc /* BRM Modulator Register 4 */
-#define UTS   0xd0 /* UART Test Register */
-#endif
+#define MX2_ONEMS 0xb0 /* One Millisecond register */
+#define UTS (cpu_is_mx1() ? 0xd0 : 0xb4) /* UART Test Register */
 
 /* UART Control Register Bit Fields.*/
 #define  URXD_CHARRDY    (1<<15)
@@ -101,12 +88,7 @@
 #define  UCR1_RTSDEN     (1<<5)	 /* RTS delta interrupt enable */
 #define  UCR1_SNDBRK     (1<<4)	 /* Send break */
 #define  UCR1_TDMAEN     (1<<3)	 /* Transmitter ready DMA enable */
-#ifdef CONFIG_ARCH_MX1
-#define  UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled */
-#endif
-#if defined CONFIG_ARCH_MX3 || defined CONFIG_ARCH_MX2
-#define  UCR1_UARTCLKEN  (0)	 /* not present on mx2/mx3 */
-#endif
+#define  MX1_UCR1_UARTCLKEN  (1<<2)	 /* UART clock enabled, mx1 only */
 #define  UCR1_DOZE       (1<<1)	 /* Doze */
 #define  UCR1_UARTEN     (1<<0)	 /* UART enabled */
 #define  UCR2_ESCI     	 (1<<15) /* Escape seq interrupt enable */
@@ -132,13 +114,9 @@
 #define  UCR3_RXDSEN	 (1<<6)  /* Receive status interrupt enable */
 #define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
 #define  UCR3_AWAKEN	 (1<<4)  /* Async wake interrupt enable */
-#ifdef CONFIG_ARCH_MX1
-#define  UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz, only on mx1 */
-#define  UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz, only on mx1 */
-#endif
-#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
-#define  UCR3_RXDMUXSEL	 (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
-#endif
+#define  MX1_UCR3_REF25 	 (1<<3)  /* Ref freq 25 MHz, only on mx1 */
+#define  MX1_UCR3_REF30 	 (1<<2)  /* Ref Freq 30 MHz, only on mx1 */
+#define  MX2_UCR3_RXDMUXSEL	 (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
 #define  UCR3_INVT  	 (1<<1)  /* Inverted Infrared transmission */
 #define  UCR3_BPEN  	 (1<<0)  /* Preset registers enable */
 #define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
@@ -186,12 +164,10 @@
 #define  UTS_SOFTRST	 (1<<0)	 /* Software reset */
 
 /* We've been assigned a range on the "Low-density serial ports" major */
-#ifdef CONFIG_ARCH_MXC
 #define SERIAL_IMX_MAJOR        207
 #define MINOR_START	        16
 #define DEV_NAME		"ttymxc"
 #define MAX_INTERNAL_IRQ	MXC_INTERNAL_IRQS
-#endif
 
 /*
  * This determines how often we check the modem status signals
@@ -248,7 +224,7 @@ static void imx_mctrl_check(struct imx_port *sport)
 	if (changed & TIOCM_CTS)
 		uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
 
-	wake_up_interruptible(&sport->port.info->delta_msr_wait);
+	wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
 }
 
 /*
@@ -260,7 +236,7 @@ static void imx_timeout(unsigned long data)
 	struct imx_port *sport = (struct imx_port *)data;
 	unsigned long flags;
 
-	if (sport->port.info) {
+	if (sport->port.state) {
 		spin_lock_irqsave(&sport->port.lock, flags);
 		imx_mctrl_check(sport);
 		spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -347,7 +323,7 @@ static void imx_enable_ms(struct uart_port *port)
 
 static inline void imx_transmit_buffer(struct imx_port *sport)
 {
-	struct circ_buf *xmit = &sport->port.info->xmit;
+	struct circ_buf *xmit = &sport->port.state->xmit;
 
 	while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) {
 		/* send xmit->buf[xmit->tail]
@@ -412,7 +388,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id)
 
 	writel(USR1_RTSD, sport->port.membase + USR1);
 	uart_handle_cts_change(&sport->port, !!val);
-	wake_up_interruptible(&sport->port.info->delta_msr_wait);
+	wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 	return IRQ_HANDLED;
@@ -421,7 +397,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id)
 static irqreturn_t imx_txint(int irq, void *dev_id)
 {
 	struct imx_port *sport = dev_id;
-	struct circ_buf *xmit = &sport->port.info->xmit;
+	struct circ_buf *xmit = &sport->port.state->xmit;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sport->port.lock,flags);
@@ -451,7 +427,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
 {
 	struct imx_port *sport = dev_id;
 	unsigned int rx,flg,ignored = 0;
-	struct tty_struct *tty = sport->port.info->port.tty;
+	struct tty_struct *tty = sport->port.state->port.tty;
 	unsigned long flags, temp;
 
 	spin_lock_irqsave(&sport->port.lock,flags);
@@ -706,11 +682,11 @@ static int imx_startup(struct uart_port *port)
 		}
 	}
 
-#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
-	temp = readl(sport->port.membase + UCR3);
-	temp |= UCR3_RXDMUXSEL;
-	writel(temp, sport->port.membase + UCR3);
-#endif
+	if (!cpu_is_mx1()) {
+		temp = readl(sport->port.membase + UCR3);
+		temp |= MX2_UCR3_RXDMUXSEL;
+		writel(temp, sport->port.membase + UCR3);
+	}
 
 	if (USE_IRDA(sport)) {
 		temp = readl(sport->port.membase + UCR4);
@@ -924,11 +900,11 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 	rational_best_approximation(16 * div * baud, sport->port.uartclk,
 		1 << 16, 1 << 16, &num, &denom);
 
-	if (port->info && port->info->port.tty) {
+	if (port->state && port->state->port.tty) {
 		tdiv64 = sport->port.uartclk;
 		tdiv64 *= num;
 		do_div(tdiv64, denom * 16 * div);
-		tty_encode_baud_rate(sport->port.info->port.tty,
+		tty_encode_baud_rate(sport->port.state->port.tty,
 				(speed_t)tdiv64, (speed_t)tdiv64);
 	}
 
@@ -942,9 +918,9 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
 	writel(num, sport->port.membase + UBIR);
 	writel(denom, sport->port.membase + UBMR);
 
-#ifdef ONEMS
-	writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS);
-#endif
+	if (!cpu_is_mx1())
+		writel(sport->port.uartclk / div / 1000,
+				sport->port.membase + MX2_ONEMS);
 
 	writel(old_ucr1, sport->port.membase + UCR1);
 
@@ -1074,17 +1050,20 @@ static void
 imx_console_write(struct console *co, const char *s, unsigned int count)
 {
 	struct imx_port *sport = imx_ports[co->index];
-	unsigned int old_ucr1, old_ucr2;
+	unsigned int old_ucr1, old_ucr2, ucr1;
 
 	/*
 	 *	First, save UCR1/2 and then disable interrupts
 	 */
-	old_ucr1 = readl(sport->port.membase + UCR1);
+	ucr1 = old_ucr1 = readl(sport->port.membase + UCR1);
 	old_ucr2 = readl(sport->port.membase + UCR2);
 
-	writel((old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) &
-		~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN),
-		sport->port.membase + UCR1);
+	if (cpu_is_mx1())
+		ucr1 |= MX1_UCR1_UARTCLKEN;
+	ucr1 |= UCR1_UARTEN;
+	ucr1 &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
+
+	writel(ucr1, sport->port.membase + UCR1);
 
 	writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2);
 
diff --git a/drivers/serial/ioc3_serial.c b/drivers/serial/ioc3_serial.c
index ae3699d..d8983dd 100644
--- a/drivers/serial/ioc3_serial.c
+++ b/drivers/serial/ioc3_serial.c
@@ -897,25 +897,25 @@ static void transmit_chars(struct uart_port *the_port)
 	char *start;
 	struct tty_struct *tty;
 	struct ioc3_port *port = get_ioc3_port(the_port);
-	struct uart_info *info;
+	struct uart_state *state;
 
 	if (!the_port)
 		return;
 	if (!port)
 		return;
 
-	info = the_port->info;
-	tty = info->port.tty;
+	state = the_port->state;
+	tty = state->port.tty;
 
-	if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
+	if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
 		/* Nothing to do or hw stopped */
 		set_notification(port, N_ALL_OUTPUT, 0);
 		return;
 	}
 
-	head = info->xmit.head;
-	tail = info->xmit.tail;
-	start = (char *)&info->xmit.buf[tail];
+	head = state->xmit.head;
+	tail = state->xmit.tail;
+	start = (char *)&state->xmit.buf[tail];
 
 	/* write out all the data or until the end of the buffer */
 	xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
@@ -928,14 +928,14 @@ static void transmit_chars(struct uart_port *the_port)
 			/* advance the pointers */
 			tail += result;
 			tail &= UART_XMIT_SIZE - 1;
-			info->xmit.tail = tail;
-			start = (char *)&info->xmit.buf[tail];
+			state->xmit.tail = tail;
+			start = (char *)&state->xmit.buf[tail];
 		}
 	}
-	if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS)
+	if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(the_port);
 
-	if (uart_circ_empty(&info->xmit)) {
+	if (uart_circ_empty(&state->xmit)) {
 		set_notification(port, N_OUTPUT_LOWAT, 0);
 	} else {
 		set_notification(port, N_OUTPUT_LOWAT, 1);
@@ -956,7 +956,7 @@ ioc3_change_speed(struct uart_port *the_port,
 	unsigned int cflag;
 	int baud;
 	int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
-	struct uart_info *info = the_port->info;
+	struct uart_state *state = the_port->state;
 
 	cflag = new_termios->c_cflag;
 
@@ -997,14 +997,14 @@ ioc3_change_speed(struct uart_port *the_port,
 
 	the_port->ignore_status_mask = N_ALL_INPUT;
 
-	info->port.tty->low_latency = 1;
+	state->port.tty->low_latency = 1;
 
-	if (I_IGNPAR(info->port.tty))
+	if (I_IGNPAR(state->port.tty))
 		the_port->ignore_status_mask &= ~(N_PARITY_ERROR
 						  | N_FRAMING_ERROR);
-	if (I_IGNBRK(info->port.tty)) {
+	if (I_IGNBRK(state->port.tty)) {
 		the_port->ignore_status_mask &= ~N_BREAK;
-		if (I_IGNPAR(info->port.tty))
+		if (I_IGNPAR(state->port.tty))
 			the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
 	}
 	if (!(cflag & CREAD)) {
@@ -1286,8 +1286,8 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len)
 						uart_handle_dcd_change
 							(port->ip_port, 0);
 						wake_up_interruptible
-						    (&the_port->info->
-						     delta_msr_wait);
+						    (&the_port->state->
+						     port.delta_msr_wait);
 					}
 
 					/* If we had any data to return, we
@@ -1392,21 +1392,21 @@ static int receive_chars(struct uart_port *the_port)
 	struct tty_struct *tty;
 	unsigned char ch[MAX_CHARS];
 	int read_count = 0, read_room, flip = 0;
-	struct uart_info *info = the_port->info;
+	struct uart_state *state = the_port->state;
 	struct ioc3_port *port = get_ioc3_port(the_port);
 	unsigned long pflags;
 
 	/* Make sure all the pointers are "good" ones */
-	if (!info)
+	if (!state)
 		return 0;
-	if (!info->port.tty)
+	if (!state->port.tty)
 		return 0;
 
 	if (!(port->ip_flags & INPUT_ENABLE))
 		return 0;
 
 	spin_lock_irqsave(&the_port->lock, pflags);
-	tty = info->port.tty;
+	tty = state->port.tty;
 
 	read_count = do_read(the_port, ch, MAX_CHARS);
 	if (read_count > 0) {
@@ -1491,7 +1491,7 @@ ioc3uart_intr_one(struct ioc3_submodule *is,
 				uart_handle_dcd_change(the_port,
 						shadow & SHADOW_DCD);
 				wake_up_interruptible
-				    (&the_port->info->delta_msr_wait);
+				    (&the_port->state->port.delta_msr_wait);
 			} else if ((port->ip_notify & N_DDCD)
 				   && !(shadow & SHADOW_DCD)) {
 				/* Flag delta DCD/no DCD */
@@ -1511,7 +1511,7 @@ ioc3uart_intr_one(struct ioc3_submodule *is,
 				uart_handle_cts_change(the_port, shadow
 						& SHADOW_CTS);
 				wake_up_interruptible
-				    (&the_port->info->delta_msr_wait);
+				    (&the_port->state->port.delta_msr_wait);
 			}
 		}
 
@@ -1721,14 +1721,14 @@ static void ic3_shutdown(struct uart_port *the_port)
 {
 	unsigned long port_flags;
 	struct ioc3_port *port;
-	struct uart_info *info;
+	struct uart_state *state;
 
 	port = get_ioc3_port(the_port);
 	if (!port)
 		return;
 
-	info = the_port->info;
-	wake_up_interruptible(&info->delta_msr_wait);
+	state = the_port->state;
+	wake_up_interruptible(&state->port.delta_msr_wait);
 
 	spin_lock_irqsave(&the_port->lock, port_flags);
 	set_notification(port, N_ALL, 0);
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index 6bab63c..2e02c30 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -930,7 +930,7 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir)
 
 	if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_VLD) {
 		printk(KERN_ERR
-			"PCI error address is 0x%lx, "
+			"PCI error address is 0x%llx, "
 				"master is serial port %c %s\n",
 		     (((uint64_t)readl(&port->ip_mem->pci_err_addr_h)
 							 << 32)
@@ -1627,25 +1627,25 @@ static void transmit_chars(struct uart_port *the_port)
 	char *start;
 	struct tty_struct *tty;
 	struct ioc4_port *port = get_ioc4_port(the_port, 0);
-	struct uart_info *info;
+	struct uart_state *state;
 
 	if (!the_port)
 		return;
 	if (!port)
 		return;
 
-	info = the_port->info;
-	tty = info->port.tty;
+	state = the_port->state;
+	tty = state->port.tty;
 
-	if (uart_circ_empty(&info->xmit) || uart_tx_stopped(the_port)) {
+	if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
 		/* Nothing to do or hw stopped */
 		set_notification(port, N_ALL_OUTPUT, 0);
 		return;
 	}
 
-	head = info->xmit.head;
-	tail = info->xmit.tail;
-	start = (char *)&info->xmit.buf[tail];
+	head = state->xmit.head;
+	tail = state->xmit.tail;
+	start = (char *)&state->xmit.buf[tail];
 
 	/* write out all the data or until the end of the buffer */
 	xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
@@ -1658,14 +1658,14 @@ static void transmit_chars(struct uart_port *the_port)
 			/* advance the pointers */
 			tail += result;
 			tail &= UART_XMIT_SIZE - 1;
-			info->xmit.tail = tail;
-			start = (char *)&info->xmit.buf[tail];
+			state->xmit.tail = tail;
+			start = (char *)&state->xmit.buf[tail];
 		}
 	}
-	if (uart_circ_chars_pending(&info->xmit) < WAKEUP_CHARS)
+	if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(the_port);
 
-	if (uart_circ_empty(&info->xmit)) {
+	if (uart_circ_empty(&state->xmit)) {
 		set_notification(port, N_OUTPUT_LOWAT, 0);
 	} else {
 		set_notification(port, N_OUTPUT_LOWAT, 1);
@@ -1686,7 +1686,7 @@ ioc4_change_speed(struct uart_port *the_port,
 	int baud, bits;
 	unsigned cflag;
 	int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
-	struct uart_info *info = the_port->info;
+	struct uart_state *state = the_port->state;
 
 	cflag = new_termios->c_cflag;
 
@@ -1738,14 +1738,14 @@ ioc4_change_speed(struct uart_port *the_port,
 
 	the_port->ignore_status_mask = N_ALL_INPUT;
 
-	info->port.tty->low_latency = 1;
+	state->port.tty->low_latency = 1;
 
-	if (I_IGNPAR(info->port.tty))
+	if (I_IGNPAR(state->port.tty))
 		the_port->ignore_status_mask &= ~(N_PARITY_ERROR
 						| N_FRAMING_ERROR);
-	if (I_IGNBRK(info->port.tty)) {
+	if (I_IGNBRK(state->port.tty)) {
 		the_port->ignore_status_mask &= ~N_BREAK;
-		if (I_IGNPAR(info->port.tty))
+		if (I_IGNPAR(state->port.tty))
 			the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
 	}
 	if (!(cflag & CREAD)) {
@@ -1784,7 +1784,7 @@ ioc4_change_speed(struct uart_port *the_port,
 static inline int ic4_startup_local(struct uart_port *the_port)
 {
 	struct ioc4_port *port;
-	struct uart_info *info;
+	struct uart_state *state;
 
 	if (!the_port)
 		return -1;
@@ -1793,7 +1793,7 @@ static inline int ic4_startup_local(struct uart_port *the_port)
 	if (!port)
 		return -1;
 
-	info = the_port->info;
+	state = the_port->state;
 
 	local_open(port);
 
@@ -1801,7 +1801,7 @@ static inline int ic4_startup_local(struct uart_port *the_port)
 	ioc4_set_proto(port, the_port->mapbase);
 
 	/* set the speed of the serial port */
-	ioc4_change_speed(the_port, info->port.tty->termios,
+	ioc4_change_speed(the_port, state->port.tty->termios,
 			  (struct ktermios *)0);
 
 	return 0;
@@ -1882,7 +1882,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
 				the_port = port->ip_port;
 				the_port->icount.dcd = 1;
 				wake_up_interruptible
-					    (&the_port-> info->delta_msr_wait);
+					    (&the_port->state->port.delta_msr_wait);
 			} else if ((port->ip_notify & N_DDCD)
 					&& !(shadow & IOC4_SHADOW_DCD)) {
 				/* Flag delta DCD/no DCD */
@@ -1904,7 +1904,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
 				the_port->icount.cts =
 					(shadow & IOC4_SHADOW_CTS) ? 1 : 0;
 				wake_up_interruptible
-					(&the_port->info->delta_msr_wait);
+					(&the_port->state->port.delta_msr_wait);
 			}
 		}
 
@@ -2236,8 +2236,8 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf,
 						   && port->ip_port) {
 						the_port->icount.dcd = 0;
 						wake_up_interruptible
-						    (&the_port->info->
-							delta_msr_wait);
+						    (&the_port->state->
+							port.delta_msr_wait);
 					}
 
 					/* If we had any data to return, we
@@ -2341,17 +2341,17 @@ static void receive_chars(struct uart_port *the_port)
 	unsigned char ch[IOC4_MAX_CHARS];
 	int read_count, request_count = IOC4_MAX_CHARS;
 	struct uart_icount *icount;
-	struct uart_info *info = the_port->info;
+	struct uart_state *state = the_port->state;
 	unsigned long pflags;
 
 	/* Make sure all the pointers are "good" ones */
-	if (!info)
+	if (!state)
 		return;
-	if (!info->port.tty)
+	if (!state->port.tty)
 		return;
 
 	spin_lock_irqsave(&the_port->lock, pflags);
-	tty = info->port.tty;
+	tty = state->port.tty;
 
 	request_count = tty_buffer_request_room(tty, IOC4_MAX_CHARS);
 
@@ -2430,19 +2430,19 @@ static void ic4_shutdown(struct uart_port *the_port)
 {
 	unsigned long port_flags;
 	struct ioc4_port *port;
-	struct uart_info *info;
+	struct uart_state *state;
 
 	port = get_ioc4_port(the_port, 0);
 	if (!port)
 		return;
 
-	info = the_port->info;
+	state = the_port->state;
 	port->ip_port = NULL;
 
-	wake_up_interruptible(&info->delta_msr_wait);
+	wake_up_interruptible(&state->port.delta_msr_wait);
 
-	if (info->port.tty)
-		set_bit(TTY_IO_ERROR, &info->port.tty->flags);
+	if (state->port.tty)
+		set_bit(TTY_IO_ERROR, &state->port.tty->flags);
 
 	spin_lock_irqsave(&the_port->lock, port_flags);
 	set_notification(port, N_ALL, 0);
@@ -2538,7 +2538,7 @@ static int ic4_startup(struct uart_port *the_port)
 	int retval;
 	struct ioc4_port *port;
 	struct ioc4_control *control;
-	struct uart_info *info;
+	struct uart_state *state;
 	unsigned long port_flags;
 
 	if (!the_port)
@@ -2546,7 +2546,7 @@ static int ic4_startup(struct uart_port *the_port)
 	port = get_ioc4_port(the_port, 1);
 	if (!port)
 		return -ENODEV;
-	info = the_port->info;
+	state = the_port->state;
 
 	control = port->ip_control;
 	if (!control) {
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c
index 0d9acbd..ebff4a1 100644
--- a/drivers/serial/ip22zilog.c
+++ b/drivers/serial/ip22zilog.c
@@ -256,9 +256,9 @@ static struct tty_struct *ip22zilog_receive_chars(struct uart_ip22zilog_port *up
 	unsigned int r1;
 
 	tty = NULL;
-	if (up->port.info != NULL &&
-	    up->port.info->port.tty != NULL)
-		tty = up->port.info->port.tty;
+	if (up->port.state != NULL &&
+	    up->port.state->port.tty != NULL)
+		tty = up->port.state->port.tty;
 
 	for (;;) {
 		ch = readb(&channel->control);
@@ -354,7 +354,7 @@ static void ip22zilog_status_handle(struct uart_ip22zilog_port *up,
 			uart_handle_cts_change(&up->port,
 					       (status & CTS));
 
-		wake_up_interruptible(&up->port.info->delta_msr_wait);
+		wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 	}
 
 	up->prev_status = status;
@@ -404,9 +404,9 @@ static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
 		return;
 	}
 
-	if (up->port.info == NULL)
+	if (up->port.state == NULL)
 		goto ack_tx_int;
-	xmit = &up->port.info->xmit;
+	xmit = &up->port.state->xmit;
 	if (uart_circ_empty(xmit))
 		goto ack_tx_int;
 	if (uart_tx_stopped(&up->port))
@@ -607,7 +607,7 @@ static void ip22zilog_start_tx(struct uart_port *port)
 		port->icount.tx++;
 		port->x_char = 0;
 	} else {
-		struct circ_buf *xmit = &port->info->xmit;
+		struct circ_buf *xmit = &port->state->xmit;
 
 		writeb(xmit->buf[xmit->tail], &channel->data);
 		ZSDELAY();
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 9dadaa1..b4b124e 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -989,7 +989,7 @@ static void neo_param(struct jsm_channel *ch)
 			{     50, B50     },
 		};
 
-		cflag = C_BAUD(ch->uart_port.info->port.tty);
+		cflag = C_BAUD(ch->uart_port.state->port.tty);
 		baud = 9600;
 		for (i = 0; i < ARRAY_SIZE(baud_rates); i++) {
 			if (baud_rates[i].cflag == cflag) {
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 00f4577..7439c03 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -147,7 +147,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
 	struct ktermios *termios;
 
 	spin_lock_irqsave(&port->lock, lock_flags);
-	termios = port->info->port.tty->termios;
+	termios = port->state->port.tty->termios;
 	if (ch == termios->c_cc[VSTART])
 		channel->ch_bd->bd_ops->send_start_character(channel);
 
@@ -245,7 +245,7 @@ static int jsm_tty_open(struct uart_port *port)
 	channel->ch_cached_lsr = 0;
 	channel->ch_stops_sent = 0;
 
-	termios = port->info->port.tty->termios;
+	termios = port->state->port.tty->termios;
 	channel->ch_c_cflag	= termios->c_cflag;
 	channel->ch_c_iflag	= termios->c_iflag;
 	channel->ch_c_oflag	= termios->c_oflag;
@@ -278,7 +278,7 @@ static void jsm_tty_close(struct uart_port *port)
 	jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
 
 	bd = channel->ch_bd;
-	ts = port->info->port.tty->termios;
+	ts = port->state->port.tty->termios;
 
 	channel->ch_flags &= ~(CH_STOPI);
 
@@ -530,7 +530,7 @@ void jsm_input(struct jsm_channel *ch)
 	if (!ch)
 		return;
 
-	tp = ch->uart_port.info->port.tty;
+	tp = ch->uart_port.state->port.tty;
 
 	bd = ch->ch_bd;
 	if(!bd)
@@ -849,7 +849,7 @@ int jsm_tty_write(struct uart_port *port)
 	u16 tail;
 	u16 tmask;
 	u32 remain;
-	int temp_tail = port->info->xmit.tail;
+	int temp_tail = port->state->xmit.tail;
 	struct jsm_channel *channel = (struct jsm_channel *)port;
 
 	tmask = WQUEUEMASK;
@@ -865,10 +865,10 @@ int jsm_tty_write(struct uart_port *port)
 	data_count = 0;
 	if (bufcount >= remain) {
 		bufcount -= remain;
-		while ((port->info->xmit.head != temp_tail) &&
+		while ((port->state->xmit.head != temp_tail) &&
 		(data_count < remain)) {
 			channel->ch_wqueue[head++] =
-			port->info->xmit.buf[temp_tail];
+			port->state->xmit.buf[temp_tail];
 
 			temp_tail++;
 			temp_tail &= (UART_XMIT_SIZE - 1);
@@ -880,10 +880,10 @@ int jsm_tty_write(struct uart_port *port)
 	data_count1 = 0;
 	if (bufcount > 0) {
 		remain = bufcount;
-		while ((port->info->xmit.head != temp_tail) &&
+		while ((port->state->xmit.head != temp_tail) &&
 			(data_count1 < remain)) {
 			channel->ch_wqueue[head++] =
-				port->info->xmit.buf[temp_tail];
+				port->state->xmit.buf[temp_tail];
 
 			temp_tail++;
 			temp_tail &= (UART_XMIT_SIZE - 1);
@@ -892,7 +892,7 @@ int jsm_tty_write(struct uart_port *port)
 		}
 	}
 
-	port->info->xmit.tail = temp_tail;
+	port->state->xmit.tail = temp_tail;
 
 	data_count += data_count1;
 	if (data_count) {
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 611c97a..bea5c21 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -286,7 +286,7 @@ static void m32r_sio_start_tx(struct uart_port *port)
 {
 #ifdef CONFIG_SERIAL_M32R_PLDSIO
 	struct uart_sio_port *up = (struct uart_sio_port *)port;
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 
 	if (!(up->ier & UART_IER_THRI)) {
 		up->ier |= UART_IER_THRI;
@@ -325,7 +325,7 @@ static void m32r_sio_enable_ms(struct uart_port *port)
 
 static void receive_chars(struct uart_sio_port *up, int *status)
 {
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned char ch;
 	unsigned char flag;
 	int max_count = 256;
@@ -398,7 +398,7 @@ static void receive_chars(struct uart_sio_port *up, int *status)
 
 static void transmit_chars(struct uart_sio_port *up)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 	int count;
 
 	if (up->port.x_char) {
diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c
index 9fd33e5..75ab006 100644
--- a/drivers/serial/max3100.c
+++ b/drivers/serial/max3100.c
@@ -184,7 +184,7 @@ static void max3100_timeout(unsigned long data)
 {
 	struct max3100_port *s = (struct max3100_port *)data;
 
-	if (s->port.info) {
+	if (s->port.state) {
 		max3100_dowork(s);
 		mod_timer(&s->timer, jiffies + s->poll_time);
 	}
@@ -261,7 +261,7 @@ static void max3100_work(struct work_struct *w)
 	int rxchars;
 	u16 tx, rx;
 	int conf, cconf, rts, crts;
-	struct circ_buf *xmit = &s->port.info->xmit;
+	struct circ_buf *xmit = &s->port.state->xmit;
 
 	dev_dbg(&s->spi->dev, "%s\n", __func__);
 
@@ -307,8 +307,8 @@ static void max3100_work(struct work_struct *w)
 			}
 		}
 
-		if (rxchars > 16 && s->port.info->port.tty != NULL) {
-			tty_flip_buffer_push(s->port.info->port.tty);
+		if (rxchars > 16 && s->port.state->port.tty != NULL) {
+			tty_flip_buffer_push(s->port.state->port.tty);
 			rxchars = 0;
 		}
 		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@ -320,8 +320,8 @@ static void max3100_work(struct work_struct *w)
 		  (!uart_circ_empty(xmit) &&
 		   !uart_tx_stopped(&s->port))));
 
-	if (rxchars > 0 && s->port.info->port.tty != NULL)
-		tty_flip_buffer_push(s->port.info->port.tty);
+	if (rxchars > 0 && s->port.state->port.tty != NULL)
+		tty_flip_buffer_push(s->port.state->port.tty);
 }
 
 static irqreturn_t max3100_irq(int irqno, void *dev_id)
@@ -429,7 +429,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios,
 	int baud = 0;
 	unsigned cflag;
 	u32 param_new, param_mask, parity = 0;
-	struct tty_struct *tty = s->port.info->port.tty;
+	struct tty_struct *tty = s->port.state->port.tty;
 
 	dev_dbg(&s->spi->dev, "%s\n", __func__);
 	if (!tty)
@@ -529,7 +529,7 @@ max3100_set_termios(struct uart_port *port, struct ktermios *termios,
 			MAX3100_STATUS_OE;
 
 	/* we are sending char from a workqueue so enable */
-	s->port.info->port.tty->low_latency = 1;
+	s->port.state->port.tty->low_latency = 1;
 
 	if (s->poll_time > 0)
 		del_timer_sync(&s->timer);
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 0eefb07..b443824 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -323,7 +323,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
 		uart_insert_char(port, status, MCFUART_USR_RXOVERRUN, ch, flag);
 	}
 
-	tty_flip_buffer_push(port->info->port.tty);
+	tty_flip_buffer_push(port->state->port.tty);
 }
 
 /****************************************************************************/
@@ -331,7 +331,7 @@ static void mcf_rx_chars(struct mcf_uart *pp)
 static void mcf_tx_chars(struct mcf_uart *pp)
 {
 	struct uart_port *port = &pp->port;
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	if (port->x_char) {
 		/* Send special char - probably flow control */
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index abbd146..d7bcd07 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -745,7 +745,7 @@ static struct uart_ops mpc52xx_uart_ops = {
 static inline int
 mpc52xx_uart_int_rx_chars(struct uart_port *port)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	unsigned char ch, flag;
 	unsigned short status;
 
@@ -812,7 +812,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
 static inline int
 mpc52xx_uart_int_tx_chars(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	/* Process out of band chars */
 	if (port->x_char) {
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index 61d3ade..b5496c2 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -936,7 +936,7 @@ static int serial_polled;
 static int mpsc_rx_intr(struct mpsc_port_info *pi)
 {
 	struct mpsc_rx_desc *rxre;
-	struct tty_struct *tty = pi->port.info->port.tty;
+	struct tty_struct *tty = pi->port.state->port.tty;
 	u32	cmdstat, bytes_in, i;
 	int	rc = 0;
 	u8	*bp;
@@ -1109,7 +1109,7 @@ static void mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr)
 
 static void mpsc_copy_tx_data(struct mpsc_port_info *pi)
 {
-	struct circ_buf *xmit = &pi->port.info->xmit;
+	struct circ_buf *xmit = &pi->port.state->xmit;
 	u8 *bp;
 	u32 i;
 
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c
index f7c24ba..b05c5aa 100644
--- a/drivers/serial/msm_serial.c
+++ b/drivers/serial/msm_serial.c
@@ -88,7 +88,7 @@ static void msm_enable_ms(struct uart_port *port)
 
 static void handle_rx(struct uart_port *port)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	unsigned int sr;
 
 	/*
@@ -136,7 +136,7 @@ static void handle_rx(struct uart_port *port)
 
 static void handle_tx(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 	struct msm_port *msm_port = UART_TO_MSM(port);
 	int sent_tx;
 
@@ -169,7 +169,7 @@ static void handle_delta_cts(struct uart_port *port)
 {
 	msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
 	port->icount.cts++;
-	wake_up_interruptible(&port->info->delta_msr_wait);
+	wake_up_interruptible(&port->state->port.delta_msr_wait);
 }
 
 static irqreturn_t msm_irq(int irq, void *dev_id)
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 953a5ff..7571aaa 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -199,7 +199,7 @@ static void mux_break_ctl(struct uart_port *port, int break_state)
 static void mux_write(struct uart_port *port)
 {
 	int count;
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	if(port->x_char) {
 		UART_PUT_CHAR(port, port->x_char);
@@ -243,7 +243,7 @@ static void mux_write(struct uart_port *port)
 static void mux_read(struct uart_port *port)
 {
 	int data;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	__u32 start_count = port->icount.rx;
 
 	while(1) {
diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c
index 3e5dda8..7735c9f 100644
--- a/drivers/serial/netx-serial.c
+++ b/drivers/serial/netx-serial.c
@@ -140,7 +140,7 @@ static void netx_enable_ms(struct uart_port *port)
 
 static inline void netx_transmit_buffer(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	if (port->x_char) {
 		writel(port->x_char, port->membase + UART_DR);
@@ -185,7 +185,7 @@ static unsigned int netx_tx_empty(struct uart_port *port)
 
 static void netx_txint(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
 		netx_stop_tx(port);
@@ -201,7 +201,7 @@ static void netx_txint(struct uart_port *port)
 static void netx_rxint(struct uart_port *port)
 {
 	unsigned char rx, flg, status;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 
 	while (!(readl(port->membase + UART_FR) & FR_RXFE)) {
 		rx = readl(port->membase + UART_DR);
diff --git a/drivers/serial/nwpserial.c b/drivers/serial/nwpserial.c
index 9e150b1..e1ab8ec 100644
--- a/drivers/serial/nwpserial.c
+++ b/drivers/serial/nwpserial.c
@@ -126,7 +126,7 @@ static void nwpserial_config_port(struct uart_port *port, int flags)
 static irqreturn_t nwpserial_interrupt(int irq, void *dev_id)
 {
 	struct nwpserial_port *up = dev_id;
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	irqreturn_t ret;
 	unsigned int iir;
 	unsigned char ch;
@@ -261,7 +261,7 @@ static void nwpserial_start_tx(struct uart_port *port)
 	struct nwpserial_port *up;
 	struct circ_buf *xmit;
 	up = container_of(port, struct nwpserial_port, port);
-	xmit  = &up->port.info->xmit;
+	xmit  = &up->port.state->xmit;
 
 	if (port->x_char) {
 		nwpserial_putchar(up, up->port.x_char);
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 9c1243f..0700cd1 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -242,12 +242,12 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
 	}
 
 	/* Sanity check, make sure the old bug is no longer happening */
-	if (uap->port.info == NULL || uap->port.info->port.tty == NULL) {
+	if (uap->port.state == NULL || uap->port.state->port.tty == NULL) {
 		WARN_ON(1);
 		(void)read_zsdata(uap);
 		return NULL;
 	}
-	tty = uap->port.info->port.tty;
+	tty = uap->port.state->port.tty;
 
 	while (1) {
 		error = 0;
@@ -369,7 +369,7 @@ static void pmz_status_handle(struct uart_pmac_port *uap)
 			uart_handle_cts_change(&uap->port,
 					       !(status & CTS));
 
-		wake_up_interruptible(&uap->port.info->delta_msr_wait);
+		wake_up_interruptible(&uap->port.state->port.delta_msr_wait);
 	}
 
 	if (status & BRK_ABRT)
@@ -420,9 +420,9 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap)
 		return;
 	}
 
-	if (uap->port.info == NULL)
+	if (uap->port.state == NULL)
 		goto ack_tx_int;
-	xmit = &uap->port.info->xmit;
+	xmit = &uap->port.state->xmit;
 	if (uart_circ_empty(xmit)) {
 		uart_write_wakeup(&uap->port);
 		goto ack_tx_int;
@@ -655,7 +655,7 @@ static void pmz_start_tx(struct uart_port *port)
 		port->icount.tx++;
 		port->x_char = 0;
 	} else {
-		struct circ_buf *xmit = &port->info->xmit;
+		struct circ_buf *xmit = &port->state->xmit;
 
 		write_zsdata(uap, xmit->buf[xmit->tail]);
 		zssync(uap);
@@ -1645,7 +1645,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
 	state = pmz_uart_reg.state + uap->port.line;
 
 	mutex_lock(&pmz_irq_mutex);
-	mutex_lock(&state->mutex);
+	mutex_lock(&state->port.mutex);
 
 	spin_lock_irqsave(&uap->port.lock, flags);
 
@@ -1676,7 +1676,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
 	/* Shut the chip down */
 	pmz_set_scc_power(uap, 0);
 
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&state->port.mutex);
 	mutex_unlock(&pmz_irq_mutex);
 
 	pmz_debug("suspend, switching complete\n");
@@ -1705,7 +1705,7 @@ static int pmz_resume(struct macio_dev *mdev)
 	state = pmz_uart_reg.state + uap->port.line;
 
 	mutex_lock(&pmz_irq_mutex);
-	mutex_lock(&state->mutex);
+	mutex_lock(&state->port.mutex);
 
 	spin_lock_irqsave(&uap->port.lock, flags);
 	if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) {
@@ -1737,7 +1737,7 @@ static int pmz_resume(struct macio_dev *mdev)
 	}
 
  bail:
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&state->port.mutex);
 	mutex_unlock(&pmz_irq_mutex);
 
 	/* Right now, we deal with delay by blocking here, I'll be
diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/serial/pnx8xxx_uart.c
index 1bb8f1b..0aa75a9 100644
--- a/drivers/serial/pnx8xxx_uart.c
+++ b/drivers/serial/pnx8xxx_uart.c
@@ -100,7 +100,7 @@ static void pnx8xxx_mctrl_check(struct pnx8xxx_port *sport)
 	if (changed & TIOCM_CTS)
 		uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
 
-	wake_up_interruptible(&sport->port.info->delta_msr_wait);
+	wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
 }
 
 /*
@@ -112,7 +112,7 @@ static void pnx8xxx_timeout(unsigned long data)
 	struct pnx8xxx_port *sport = (struct pnx8xxx_port *)data;
 	unsigned long flags;
 
-	if (sport->port.info) {
+	if (sport->port.state) {
 		spin_lock_irqsave(&sport->port.lock, flags);
 		pnx8xxx_mctrl_check(sport);
 		spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -181,7 +181,7 @@ static void pnx8xxx_enable_ms(struct uart_port *port)
 
 static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
 {
-	struct tty_struct *tty = sport->port.info->port.tty;
+	struct tty_struct *tty = sport->port.state->port.tty;
 	unsigned int status, ch, flg;
 
 	status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
@@ -243,7 +243,7 @@ static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
 
 static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport)
 {
-	struct circ_buf *xmit = &sport->port.info->xmit;
+	struct circ_buf *xmit = &sport->port.state->xmit;
 
 	if (sport->port.x_char) {
 		serial_out(sport, PNX8XXX_FIFO, sport->port.x_char);
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index a48a8a1..6443b7f 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -96,7 +96,7 @@ static void serial_pxa_stop_rx(struct uart_port *port)
 
 static inline void receive_chars(struct uart_pxa_port *up, int *status)
 {
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned int ch, flag;
 	int max_count = 256;
 
@@ -161,7 +161,7 @@ static inline void receive_chars(struct uart_pxa_port *up, int *status)
 
 static void transmit_chars(struct uart_pxa_port *up)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 	int count;
 
 	if (up->port.x_char) {
@@ -220,7 +220,7 @@ static inline void check_modem_status(struct uart_pxa_port *up)
 	if (status & UART_MSR_DCTS)
 		uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
 
-	wake_up_interruptible(&up->port.info->delta_msr_wait);
+	wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 }
 
 /*
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 94530f0..7f5e268 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -117,7 +117,7 @@ static void sa1100_mctrl_check(struct sa1100_port *sport)
 	if (changed & TIOCM_CTS)
 		uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
 
-	wake_up_interruptible(&sport->port.info->delta_msr_wait);
+	wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
 }
 
 /*
@@ -129,7 +129,7 @@ static void sa1100_timeout(unsigned long data)
 	struct sa1100_port *sport = (struct sa1100_port *)data;
 	unsigned long flags;
 
-	if (sport->port.info) {
+	if (sport->port.state) {
 		spin_lock_irqsave(&sport->port.lock, flags);
 		sa1100_mctrl_check(sport);
 		spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -189,7 +189,7 @@ static void sa1100_enable_ms(struct uart_port *port)
 static void
 sa1100_rx_chars(struct sa1100_port *sport)
 {
-	struct tty_struct *tty = sport->port.info->port.tty;
+	struct tty_struct *tty = sport->port.state->port.tty;
 	unsigned int status, ch, flg;
 
 	status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
@@ -239,7 +239,7 @@ sa1100_rx_chars(struct sa1100_port *sport)
 
 static void sa1100_tx_chars(struct sa1100_port *sport)
 {
-	struct circ_buf *xmit = &sport->port.info->xmit;
+	struct circ_buf *xmit = &sport->port.state->xmit;
 
 	if (sport->port.x_char) {
 		UART_PUT_CHAR(sport, sport->port.x_char);
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index c8851a0..1523e8d 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -196,7 +196,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id)
 {
 	struct s3c24xx_uart_port *ourport = dev_id;
 	struct uart_port *port = &ourport->port;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	unsigned int ufcon, ch, flag, ufstat, uerstat;
 	int max_count = 64;
 
@@ -281,7 +281,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id)
 {
 	struct s3c24xx_uart_port *ourport = id;
 	struct uart_port *port = &ourport->port;
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 	int count = 256;
 
 	if (port->x_char) {
@@ -992,10 +992,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
 		struct ktermios *termios;
 		struct tty_struct *tty;
 
-		if (uport->info == NULL)
+		if (uport->state == NULL)
 			goto exit;
 
-		tty = uport->info->port.tty;
+		tty = uport->state->port.tty;
 
 		if (tty == NULL)
 			goto exit;
diff --git a/drivers/serial/sb1250-duart.c b/drivers/serial/sb1250-duart.c
index 319e8b8..a2f2b32 100644
--- a/drivers/serial/sb1250-duart.c
+++ b/drivers/serial/sb1250-duart.c
@@ -384,13 +384,13 @@ static void sbd_receive_chars(struct sbd_port *sport)
 		uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag);
 	}
 
-	tty_flip_buffer_push(uport->info->port.tty);
+	tty_flip_buffer_push(uport->state->port.tty);
 }
 
 static void sbd_transmit_chars(struct sbd_port *sport)
 {
 	struct uart_port *uport = &sport->port;
-	struct circ_buf *xmit = &sport->port.info->xmit;
+	struct circ_buf *xmit = &sport->port.state->xmit;
 	unsigned int mask;
 	int stop_tx;
 
@@ -440,7 +440,7 @@ static void sbd_status_handle(struct sbd_port *sport)
 
 	if (delta & ((M_DUART_IN_PIN2_VAL | M_DUART_IN_PIN0_VAL) <<
 		     S_DUART_IN_PIN_CHNG))
-		wake_up_interruptible(&uport->info->delta_msr_wait);
+		wake_up_interruptible(&uport->state->port.delta_msr_wait);
 }
 
 static irqreturn_t sbd_interrupt(int irq, void *dev_id)
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c
index e0be11c..75038ad 100644
--- a/drivers/serial/sc26xx.c
+++ b/drivers/serial/sc26xx.c
@@ -140,8 +140,8 @@ static struct tty_struct *receive_chars(struct uart_port *port)
 	char flag;
 	u8 status;
 
-	if (port->info != NULL)		/* Unopened serial console */
-		tty = port->info->port.tty;
+	if (port->state != NULL)		/* Unopened serial console */
+		tty = port->state->port.tty;
 
 	while (limit-- > 0) {
 		status = READ_SC_PORT(port, SR);
@@ -190,10 +190,10 @@ static void transmit_chars(struct uart_port *port)
 {
 	struct circ_buf *xmit;
 
-	if (!port->info)
+	if (!port->state)
 		return;
 
-	xmit = &port->info->xmit;
+	xmit = &port->state->xmit;
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
 		sc26xx_disable_irq(port, IMR_TXRDY);
 		return;
@@ -316,7 +316,7 @@ static void sc26xx_stop_tx(struct uart_port *port)
 /* port->lock held by caller.  */
 static void sc26xx_start_tx(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	while (!uart_circ_empty(xmit)) {
 		if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) {
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index b0bb29d..2514d00 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -29,10 +29,10 @@
 #include <linux/console.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
-#include <linux/serial_core.h>
 #include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
+#include <linux/serial_core.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 
@@ -52,8 +52,6 @@ static struct lock_class_key port_lock_key;
 
 #define HIGH_BITS_OFFSET	((sizeof(long)-sizeof(int))*8)
 
-#define uart_users(state)	((state)->count + (state)->info.port.blocked_open)
-
 #ifdef CONFIG_SERIAL_CORE_CONSOLE
 #define uart_console(port)	((port)->cons && (port)->cons->index == (port)->line)
 #else
@@ -71,19 +69,19 @@ static void uart_change_pm(struct uart_state *state, int pm_state);
  */
 void uart_write_wakeup(struct uart_port *port)
 {
-	struct uart_info *info = port->info;
+	struct uart_state *state = port->state;
 	/*
 	 * This means you called this function _after_ the port was
 	 * closed.  No cookie for you.
 	 */
-	BUG_ON(!info);
-	tasklet_schedule(&info->tlet);
+	BUG_ON(!state);
+	tasklet_schedule(&state->tlet);
 }
 
 static void uart_stop(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port = state->uart_port;
 	unsigned long flags;
 
 	spin_lock_irqsave(&port->lock, flags);
@@ -94,9 +92,9 @@ static void uart_stop(struct tty_struct *tty)
 static void __uart_start(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port = state->uart_port;
 
-	if (!uart_circ_empty(&state->info.xmit) && state->info.xmit.buf &&
+	if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
 	    !tty->stopped && !tty->hw_stopped)
 		port->ops->start_tx(port);
 }
@@ -104,7 +102,7 @@ static void __uart_start(struct tty_struct *tty)
 static void uart_start(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port = state->uart_port;
 	unsigned long flags;
 
 	spin_lock_irqsave(&port->lock, flags);
@@ -115,7 +113,7 @@ static void uart_start(struct tty_struct *tty)
 static void uart_tasklet_action(unsigned long data)
 {
 	struct uart_state *state = (struct uart_state *)data;
-	tty_wakeup(state->info.port.tty);
+	tty_wakeup(state->port.tty);
 }
 
 static inline void
@@ -141,12 +139,12 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
  */
 static int uart_startup(struct uart_state *state, int init_hw)
 {
-	struct uart_info *info = &state->info;
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	unsigned long page;
 	int retval = 0;
 
-	if (info->flags & UIF_INITIALIZED)
+	if (port->flags & ASYNC_INITIALIZED)
 		return 0;
 
 	/*
@@ -154,26 +152,26 @@ static int uart_startup(struct uart_state *state, int init_hw)
 	 * once we have successfully opened the port.  Also set
 	 * up the tty->alt_speed kludge
 	 */
-	set_bit(TTY_IO_ERROR, &info->port.tty->flags);
+	set_bit(TTY_IO_ERROR, &port->tty->flags);
 
-	if (port->type == PORT_UNKNOWN)
+	if (uport->type == PORT_UNKNOWN)
 		return 0;
 
 	/*
 	 * Initialise and allocate the transmit and temporary
 	 * buffer.
 	 */
-	if (!info->xmit.buf) {
+	if (!state->xmit.buf) {
 		/* This is protected by the per port mutex */
 		page = get_zeroed_page(GFP_KERNEL);
 		if (!page)
 			return -ENOMEM;
 
-		info->xmit.buf = (unsigned char *) page;
-		uart_circ_clear(&info->xmit);
+		state->xmit.buf = (unsigned char *) page;
+		uart_circ_clear(&state->xmit);
 	}
 
-	retval = port->ops->startup(port);
+	retval = uport->ops->startup(uport);
 	if (retval == 0) {
 		if (init_hw) {
 			/*
@@ -185,20 +183,20 @@ static int uart_startup(struct uart_state *state, int init_hw)
 			 * Setup the RTS and DTR signals once the
 			 * port is open and ready to respond.
 			 */
-			if (info->port.tty->termios->c_cflag & CBAUD)
-				uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
+			if (port->tty->termios->c_cflag & CBAUD)
+				uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
 		}
 
-		if (info->flags & UIF_CTS_FLOW) {
-			spin_lock_irq(&port->lock);
-			if (!(port->ops->get_mctrl(port) & TIOCM_CTS))
-				info->port.tty->hw_stopped = 1;
-			spin_unlock_irq(&port->lock);
+		if (port->flags & ASYNC_CTS_FLOW) {
+			spin_lock_irq(&uport->lock);
+			if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS))
+				port->tty->hw_stopped = 1;
+			spin_unlock_irq(&uport->lock);
 		}
 
-		info->flags |= UIF_INITIALIZED;
+		set_bit(ASYNCB_INITIALIZED, &port->flags);
 
-		clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
+		clear_bit(TTY_IO_ERROR, &port->tty->flags);
 	}
 
 	if (retval && capable(CAP_SYS_ADMIN))
@@ -214,9 +212,9 @@ static int uart_startup(struct uart_state *state, int init_hw)
  */
 static void uart_shutdown(struct uart_state *state)
 {
-	struct uart_info *info = &state->info;
-	struct uart_port *port = state->port;
-	struct tty_struct *tty = info->port.tty;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
+	struct tty_struct *tty = port->tty;
 
 	/*
 	 * Set the TTY IO error marker
@@ -224,14 +222,12 @@ static void uart_shutdown(struct uart_state *state)
 	if (tty)
 		set_bit(TTY_IO_ERROR, &tty->flags);
 
-	if (info->flags & UIF_INITIALIZED) {
-		info->flags &= ~UIF_INITIALIZED;
-
+	if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) {
 		/*
 		 * Turn off DTR and RTS early.
 		 */
 		if (!tty || (tty->termios->c_cflag & HUPCL))
-			uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+			uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
 
 		/*
 		 * clear delta_msr_wait queue to avoid mem leaks: we may free
@@ -240,30 +236,30 @@ static void uart_shutdown(struct uart_state *state)
 		 * any outstanding file descriptors should be pointing at
 		 * hung_up_tty_fops now.
 		 */
-		wake_up_interruptible(&info->delta_msr_wait);
+		wake_up_interruptible(&port->delta_msr_wait);
 
 		/*
 		 * Free the IRQ and disable the port.
 		 */
-		port->ops->shutdown(port);
+		uport->ops->shutdown(uport);
 
 		/*
 		 * Ensure that the IRQ handler isn't running on another CPU.
 		 */
-		synchronize_irq(port->irq);
+		synchronize_irq(uport->irq);
 	}
 
 	/*
 	 * kill off our tasklet
 	 */
-	tasklet_kill(&info->tlet);
+	tasklet_kill(&state->tlet);
 
 	/*
 	 * Free the transmit buffer page.
 	 */
-	if (info->xmit.buf) {
-		free_page((unsigned long)info->xmit.buf);
-		info->xmit.buf = NULL;
+	if (state->xmit.buf) {
+		free_page((unsigned long)state->xmit.buf);
+		state->xmit.buf = NULL;
 	}
 }
 
@@ -430,15 +426,16 @@ EXPORT_SYMBOL(uart_get_divisor);
 static void
 uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
 {
-	struct tty_struct *tty = state->info.port.tty;
-	struct uart_port *port = state->port;
+	struct tty_port *port = &state->port;
+	struct tty_struct *tty = port->tty;
+	struct uart_port *uport = state->uart_port;
 	struct ktermios *termios;
 
 	/*
 	 * If we have no tty, termios, or the port does not exist,
 	 * then we can't set the parameters for this port.
 	 */
-	if (!tty || !tty->termios || port->type == PORT_UNKNOWN)
+	if (!tty || !tty->termios || uport->type == PORT_UNKNOWN)
 		return;
 
 	termios = tty->termios;
@@ -447,16 +444,16 @@ uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
 	 * Set flags based on termios cflag
 	 */
 	if (termios->c_cflag & CRTSCTS)
-		state->info.flags |= UIF_CTS_FLOW;
+		set_bit(ASYNCB_CTS_FLOW, &port->flags);
 	else
-		state->info.flags &= ~UIF_CTS_FLOW;
+		clear_bit(ASYNCB_CTS_FLOW, &port->flags);
 
 	if (termios->c_cflag & CLOCAL)
-		state->info.flags &= ~UIF_CHECK_CD;
+		clear_bit(ASYNCB_CHECK_CD, &port->flags);
 	else
-		state->info.flags |= UIF_CHECK_CD;
+		set_bit(ASYNCB_CHECK_CD, &port->flags);
 
-	port->ops->set_termios(port, termios, old_termios);
+	uport->ops->set_termios(uport, termios, old_termios);
 }
 
 static inline int
@@ -482,7 +479,7 @@ static int uart_put_char(struct tty_struct *tty, unsigned char ch)
 {
 	struct uart_state *state = tty->driver_data;
 
-	return __uart_put_char(state->port, &state->info.xmit, ch);
+	return __uart_put_char(state->uart_port, &state->xmit, ch);
 }
 
 static void uart_flush_chars(struct tty_struct *tty)
@@ -508,8 +505,8 @@ uart_write(struct tty_struct *tty, const unsigned char *buf, int count)
 		return -EL3HLT;
 	}
 
-	port = state->port;
-	circ = &state->info.xmit;
+	port = state->uart_port;
+	circ = &state->xmit;
 
 	if (!circ->buf)
 		return 0;
@@ -539,9 +536,9 @@ static int uart_write_room(struct tty_struct *tty)
 	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&state->port->lock, flags);
-	ret = uart_circ_chars_free(&state->info.xmit);
-	spin_unlock_irqrestore(&state->port->lock, flags);
+	spin_lock_irqsave(&state->uart_port->lock, flags);
+	ret = uart_circ_chars_free(&state->xmit);
+	spin_unlock_irqrestore(&state->uart_port->lock, flags);
 	return ret;
 }
 
@@ -551,9 +548,9 @@ static int uart_chars_in_buffer(struct tty_struct *tty)
 	unsigned long flags;
 	int ret;
 
-	spin_lock_irqsave(&state->port->lock, flags);
-	ret = uart_circ_chars_pending(&state->info.xmit);
-	spin_unlock_irqrestore(&state->port->lock, flags);
+	spin_lock_irqsave(&state->uart_port->lock, flags);
+	ret = uart_circ_chars_pending(&state->xmit);
+	spin_unlock_irqrestore(&state->uart_port->lock, flags);
 	return ret;
 }
 
@@ -572,11 +569,11 @@ static void uart_flush_buffer(struct tty_struct *tty)
 		return;
 	}
 
-	port = state->port;
+	port = state->uart_port;
 	pr_debug("uart_flush_buffer(%d) called\n", tty->index);
 
 	spin_lock_irqsave(&port->lock, flags);
-	uart_circ_clear(&state->info.xmit);
+	uart_circ_clear(&state->xmit);
 	if (port->ops->flush_buffer)
 		port->ops->flush_buffer(port);
 	spin_unlock_irqrestore(&port->lock, flags);
@@ -590,7 +587,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
 static void uart_send_xchar(struct tty_struct *tty, char ch)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port = state->uart_port;
 	unsigned long flags;
 
 	if (port->ops->send_xchar)
@@ -613,13 +610,13 @@ static void uart_throttle(struct tty_struct *tty)
 		uart_send_xchar(tty, STOP_CHAR(tty));
 
 	if (tty->termios->c_cflag & CRTSCTS)
-		uart_clear_mctrl(state->port, TIOCM_RTS);
+		uart_clear_mctrl(state->uart_port, TIOCM_RTS);
 }
 
 static void uart_unthrottle(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port = state->uart_port;
 
 	if (I_IXOFF(tty)) {
 		if (port->x_char)
@@ -635,35 +632,36 @@ static void uart_unthrottle(struct tty_struct *tty)
 static int uart_get_info(struct uart_state *state,
 			 struct serial_struct __user *retinfo)
 {
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	struct serial_struct tmp;
 
 	memset(&tmp, 0, sizeof(tmp));
 
 	/* Ensure the state we copy is consistent and no hardware changes
 	   occur as we go */
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 
-	tmp.type	    = port->type;
-	tmp.line	    = port->line;
-	tmp.port	    = port->iobase;
+	tmp.type	    = uport->type;
+	tmp.line	    = uport->line;
+	tmp.port	    = uport->iobase;
 	if (HIGH_BITS_OFFSET)
-		tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET;
-	tmp.irq		    = port->irq;
-	tmp.flags	    = port->flags;
-	tmp.xmit_fifo_size  = port->fifosize;
-	tmp.baud_base	    = port->uartclk / 16;
-	tmp.close_delay	    = state->close_delay / 10;
-	tmp.closing_wait    = state->closing_wait == USF_CLOSING_WAIT_NONE ?
+		tmp.port_high = (long) uport->iobase >> HIGH_BITS_OFFSET;
+	tmp.irq		    = uport->irq;
+	tmp.flags	    = uport->flags;
+	tmp.xmit_fifo_size  = uport->fifosize;
+	tmp.baud_base	    = uport->uartclk / 16;
+	tmp.close_delay	    = port->close_delay / 10;
+	tmp.closing_wait    = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ?
 				ASYNC_CLOSING_WAIT_NONE :
-				state->closing_wait / 10;
-	tmp.custom_divisor  = port->custom_divisor;
-	tmp.hub6	    = port->hub6;
-	tmp.io_type         = port->iotype;
-	tmp.iomem_reg_shift = port->regshift;
-	tmp.iomem_base      = (void *)(unsigned long)port->mapbase;
+				port->closing_wait / 10;
+	tmp.custom_divisor  = uport->custom_divisor;
+	tmp.hub6	    = uport->hub6;
+	tmp.io_type         = uport->iotype;
+	tmp.iomem_reg_shift = uport->regshift;
+	tmp.iomem_base      = (void *)(unsigned long)uport->mapbase;
 
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 
 	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
 		return -EFAULT;
@@ -674,7 +672,8 @@ static int uart_set_info(struct uart_state *state,
 			 struct serial_struct __user *newinfo)
 {
 	struct serial_struct new_serial;
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	unsigned long new_port;
 	unsigned int change_irq, change_port, closing_wait;
 	unsigned int old_custom_divisor, close_delay;
@@ -691,58 +690,58 @@ static int uart_set_info(struct uart_state *state,
 	new_serial.irq = irq_canonicalize(new_serial.irq);
 	close_delay = new_serial.close_delay * 10;
 	closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
-			USF_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
+			ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
 
 	/*
-	 * This semaphore protects state->count.  It is also
+	 * This semaphore protects port->count.  It is also
 	 * very useful to prevent opens.  Also, take the
 	 * port configuration semaphore to make sure that a
 	 * module insertion/removal doesn't change anything
 	 * under us.
 	 */
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 
-	change_irq  = !(port->flags & UPF_FIXED_PORT)
-		&& new_serial.irq != port->irq;
+	change_irq  = !(uport->flags & UPF_FIXED_PORT)
+		&& new_serial.irq != uport->irq;
 
 	/*
 	 * Since changing the 'type' of the port changes its resource
 	 * allocations, we should treat type changes the same as
 	 * IO port changes.
 	 */
-	change_port = !(port->flags & UPF_FIXED_PORT)
-		&& (new_port != port->iobase ||
-		    (unsigned long)new_serial.iomem_base != port->mapbase ||
-		    new_serial.hub6 != port->hub6 ||
-		    new_serial.io_type != port->iotype ||
-		    new_serial.iomem_reg_shift != port->regshift ||
-		    new_serial.type != port->type);
-
-	old_flags = port->flags;
+	change_port = !(uport->flags & UPF_FIXED_PORT)
+		&& (new_port != uport->iobase ||
+		    (unsigned long)new_serial.iomem_base != uport->mapbase ||
+		    new_serial.hub6 != uport->hub6 ||
+		    new_serial.io_type != uport->iotype ||
+		    new_serial.iomem_reg_shift != uport->regshift ||
+		    new_serial.type != uport->type);
+
+	old_flags = uport->flags;
 	new_flags = new_serial.flags;
-	old_custom_divisor = port->custom_divisor;
+	old_custom_divisor = uport->custom_divisor;
 
 	if (!capable(CAP_SYS_ADMIN)) {
 		retval = -EPERM;
 		if (change_irq || change_port ||
-		    (new_serial.baud_base != port->uartclk / 16) ||
-		    (close_delay != state->close_delay) ||
-		    (closing_wait != state->closing_wait) ||
+		    (new_serial.baud_base != uport->uartclk / 16) ||
+		    (close_delay != port->close_delay) ||
+		    (closing_wait != port->closing_wait) ||
 		    (new_serial.xmit_fifo_size &&
-		     new_serial.xmit_fifo_size != port->fifosize) ||
+		     new_serial.xmit_fifo_size != uport->fifosize) ||
 		    (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
 			goto exit;
-		port->flags = ((port->flags & ~UPF_USR_MASK) |
+		uport->flags = ((uport->flags & ~UPF_USR_MASK) |
 			       (new_flags & UPF_USR_MASK));
-		port->custom_divisor = new_serial.custom_divisor;
+		uport->custom_divisor = new_serial.custom_divisor;
 		goto check_and_exit;
 	}
 
 	/*
 	 * Ask the low level driver to verify the settings.
 	 */
-	if (port->ops->verify_port)
-		retval = port->ops->verify_port(port, &new_serial);
+	if (uport->ops->verify_port)
+		retval = uport->ops->verify_port(uport, &new_serial);
 
 	if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) ||
 	    (new_serial.baud_base < 9600))
@@ -757,7 +756,7 @@ static int uart_set_info(struct uart_state *state,
 		/*
 		 * Make sure that we are the sole user of this port.
 		 */
-		if (uart_users(state) > 1)
+		if (tty_port_users(port) > 1)
 			goto exit;
 
 		/*
@@ -771,31 +770,31 @@ static int uart_set_info(struct uart_state *state,
 		unsigned long old_iobase, old_mapbase;
 		unsigned int old_type, old_iotype, old_hub6, old_shift;
 
-		old_iobase = port->iobase;
-		old_mapbase = port->mapbase;
-		old_type = port->type;
-		old_hub6 = port->hub6;
-		old_iotype = port->iotype;
-		old_shift = port->regshift;
+		old_iobase = uport->iobase;
+		old_mapbase = uport->mapbase;
+		old_type = uport->type;
+		old_hub6 = uport->hub6;
+		old_iotype = uport->iotype;
+		old_shift = uport->regshift;
 
 		/*
 		 * Free and release old regions
 		 */
 		if (old_type != PORT_UNKNOWN)
-			port->ops->release_port(port);
+			uport->ops->release_port(uport);
 
-		port->iobase = new_port;
-		port->type = new_serial.type;
-		port->hub6 = new_serial.hub6;
-		port->iotype = new_serial.io_type;
-		port->regshift = new_serial.iomem_reg_shift;
-		port->mapbase = (unsigned long)new_serial.iomem_base;
+		uport->iobase = new_port;
+		uport->type = new_serial.type;
+		uport->hub6 = new_serial.hub6;
+		uport->iotype = new_serial.io_type;
+		uport->regshift = new_serial.iomem_reg_shift;
+		uport->mapbase = (unsigned long)new_serial.iomem_base;
 
 		/*
 		 * Claim and map the new regions
 		 */
-		if (port->type != PORT_UNKNOWN) {
-			retval = port->ops->request_port(port);
+		if (uport->type != PORT_UNKNOWN) {
+			retval = uport->ops->request_port(uport);
 		} else {
 			/* Always success - Jean II */
 			retval = 0;
@@ -806,19 +805,19 @@ static int uart_set_info(struct uart_state *state,
 		 * new port, try to restore the old settings.
 		 */
 		if (retval && old_type != PORT_UNKNOWN) {
-			port->iobase = old_iobase;
-			port->type = old_type;
-			port->hub6 = old_hub6;
-			port->iotype = old_iotype;
-			port->regshift = old_shift;
-			port->mapbase = old_mapbase;
-			retval = port->ops->request_port(port);
+			uport->iobase = old_iobase;
+			uport->type = old_type;
+			uport->hub6 = old_hub6;
+			uport->iotype = old_iotype;
+			uport->regshift = old_shift;
+			uport->mapbase = old_mapbase;
+			retval = uport->ops->request_port(uport);
 			/*
 			 * If we failed to restore the old settings,
 			 * we fail like this.
 			 */
 			if (retval)
-				port->type = PORT_UNKNOWN;
+				uport->type = PORT_UNKNOWN;
 
 			/*
 			 * We failed anyway.
@@ -830,45 +829,45 @@ static int uart_set_info(struct uart_state *state,
 	}
 
 	if (change_irq)
-		port->irq      = new_serial.irq;
-	if (!(port->flags & UPF_FIXED_PORT))
-		port->uartclk  = new_serial.baud_base * 16;
-	port->flags            = (port->flags & ~UPF_CHANGE_MASK) |
+		uport->irq      = new_serial.irq;
+	if (!(uport->flags & UPF_FIXED_PORT))
+		uport->uartclk  = new_serial.baud_base * 16;
+	uport->flags            = (uport->flags & ~UPF_CHANGE_MASK) |
 				 (new_flags & UPF_CHANGE_MASK);
-	port->custom_divisor   = new_serial.custom_divisor;
-	state->close_delay     = close_delay;
-	state->closing_wait    = closing_wait;
+	uport->custom_divisor   = new_serial.custom_divisor;
+	port->close_delay     = close_delay;
+	port->closing_wait    = closing_wait;
 	if (new_serial.xmit_fifo_size)
-		port->fifosize = new_serial.xmit_fifo_size;
-	if (state->info.port.tty)
-		state->info.port.tty->low_latency =
-			(port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+		uport->fifosize = new_serial.xmit_fifo_size;
+	if (port->tty)
+		port->tty->low_latency =
+			(uport->flags & UPF_LOW_LATENCY) ? 1 : 0;
 
  check_and_exit:
 	retval = 0;
-	if (port->type == PORT_UNKNOWN)
+	if (uport->type == PORT_UNKNOWN)
 		goto exit;
-	if (state->info.flags & UIF_INITIALIZED) {
-		if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
-		    old_custom_divisor != port->custom_divisor) {
+	if (port->flags & ASYNC_INITIALIZED) {
+		if (((old_flags ^ uport->flags) & UPF_SPD_MASK) ||
+		    old_custom_divisor != uport->custom_divisor) {
 			/*
 			 * If they're setting up a custom divisor or speed,
 			 * instead of clearing it, then bitch about it. No
 			 * need to rate-limit; it's CAP_SYS_ADMIN only.
 			 */
-			if (port->flags & UPF_SPD_MASK) {
+			if (uport->flags & UPF_SPD_MASK) {
 				char buf[64];
 				printk(KERN_NOTICE
 				       "%s sets custom speed on %s. This "
 				       "is deprecated.\n", current->comm,
-				       tty_name(state->info.port.tty, buf));
+				       tty_name(port->tty, buf));
 			}
 			uart_change_speed(state, NULL);
 		}
 	} else
 		retval = uart_startup(state, 1);
  exit:
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 	return retval;
 }
 
@@ -880,10 +879,11 @@ static int uart_set_info(struct uart_state *state,
 static int uart_get_lsr_info(struct uart_state *state,
 			     unsigned int __user *value)
 {
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	unsigned int result;
 
-	result = port->ops->tx_empty(port);
+	result = uport->ops->tx_empty(uport);
 
 	/*
 	 * If we're about to load something into the transmit
@@ -891,9 +891,9 @@ static int uart_get_lsr_info(struct uart_state *state,
 	 * avoid a race condition (depending on when the transmit
 	 * interrupt happens).
 	 */
-	if (port->x_char ||
-	    ((uart_circ_chars_pending(&state->info.xmit) > 0) &&
-	     !state->info.port.tty->stopped && !state->info.port.tty->hw_stopped))
+	if (uport->x_char ||
+	    ((uart_circ_chars_pending(&state->xmit) > 0) &&
+	     !port->tty->stopped && !port->tty->hw_stopped))
 		result &= ~TIOCSER_TEMT;
 
 	return put_user(result, value);
@@ -902,19 +902,20 @@ static int uart_get_lsr_info(struct uart_state *state,
 static int uart_tiocmget(struct tty_struct *tty, struct file *file)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct tty_port *port = &state->port;
+	struct uart_port *uport = state->uart_port;
 	int result = -EIO;
 
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 	if ((!file || !tty_hung_up_p(file)) &&
 	    !(tty->flags & (1 << TTY_IO_ERROR))) {
-		result = port->mctrl;
+		result = uport->mctrl;
 
-		spin_lock_irq(&port->lock);
-		result |= port->ops->get_mctrl(port);
-		spin_unlock_irq(&port->lock);
+		spin_lock_irq(&uport->lock);
+		result |= uport->ops->get_mctrl(uport);
+		spin_unlock_irq(&uport->lock);
 	}
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 
 	return result;
 }
@@ -924,36 +925,39 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
 	      unsigned int set, unsigned int clear)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	int ret = -EIO;
 
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 	if ((!file || !tty_hung_up_p(file)) &&
 	    !(tty->flags & (1 << TTY_IO_ERROR))) {
-		uart_update_mctrl(port, set, clear);
+		uart_update_mctrl(uport, set, clear);
 		ret = 0;
 	}
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 	return ret;
 }
 
 static int uart_break_ctl(struct tty_struct *tty, int break_state)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct tty_port *port = &state->port;
+	struct uart_port *uport = state->uart_port;
 
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 
-	if (port->type != PORT_UNKNOWN)
-		port->ops->break_ctl(port, break_state);
+	if (uport->type != PORT_UNKNOWN)
+		uport->ops->break_ctl(uport, break_state);
 
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 	return 0;
 }
 
 static int uart_do_autoconfig(struct uart_state *state)
 {
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	int flags, ret;
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -964,33 +968,33 @@ static int uart_do_autoconfig(struct uart_state *state)
 	 * changing, and hence any extra opens of the port while
 	 * we're auto-configuring.
 	 */
-	if (mutex_lock_interruptible(&state->mutex))
+	if (mutex_lock_interruptible(&port->mutex))
 		return -ERESTARTSYS;
 
 	ret = -EBUSY;
-	if (uart_users(state) == 1) {
+	if (tty_port_users(port) == 1) {
 		uart_shutdown(state);
 
 		/*
 		 * If we already have a port type configured,
 		 * we must release its resources.
 		 */
-		if (port->type != PORT_UNKNOWN)
-			port->ops->release_port(port);
+		if (uport->type != PORT_UNKNOWN)
+			uport->ops->release_port(uport);
 
 		flags = UART_CONFIG_TYPE;
-		if (port->flags & UPF_AUTO_IRQ)
+		if (uport->flags & UPF_AUTO_IRQ)
 			flags |= UART_CONFIG_IRQ;
 
 		/*
 		 * This will claim the ports resources if
 		 * a port is found.
 		 */
-		port->ops->config_port(port, flags);
+		uport->ops->config_port(uport, flags);
 
 		ret = uart_startup(state, 1);
 	}
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 	return ret;
 }
 
@@ -999,11 +1003,15 @@ static int uart_do_autoconfig(struct uart_state *state)
  * - mask passed in arg for lines of interest
  *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
  * Caller should use TIOCGICOUNT to see which one it was
+ *
+ * FIXME: This wants extracting into a common all driver implementation
+ * of TIOCMWAIT using tty_port.
  */
 static int
 uart_wait_modem_status(struct uart_state *state, unsigned long arg)
 {
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	DECLARE_WAITQUEUE(wait, current);
 	struct uart_icount cprev, cnow;
 	int ret;
@@ -1011,20 +1019,20 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg)
 	/*
 	 * note the counters on entry
 	 */
-	spin_lock_irq(&port->lock);
-	memcpy(&cprev, &port->icount, sizeof(struct uart_icount));
+	spin_lock_irq(&uport->lock);
+	memcpy(&cprev, &uport->icount, sizeof(struct uart_icount));
 
 	/*
 	 * Force modem status interrupts on
 	 */
-	port->ops->enable_ms(port);
-	spin_unlock_irq(&port->lock);
+	uport->ops->enable_ms(uport);
+	spin_unlock_irq(&uport->lock);
 
-	add_wait_queue(&state->info.delta_msr_wait, &wait);
+	add_wait_queue(&port->delta_msr_wait, &wait);
 	for (;;) {
-		spin_lock_irq(&port->lock);
-		memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
-		spin_unlock_irq(&port->lock);
+		spin_lock_irq(&uport->lock);
+		memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
+		spin_unlock_irq(&uport->lock);
 
 		set_current_state(TASK_INTERRUPTIBLE);
 
@@ -1048,7 +1056,7 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg)
 	}
 
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&state->info.delta_msr_wait, &wait);
+	remove_wait_queue(&port->delta_msr_wait, &wait);
 
 	return ret;
 }
@@ -1064,11 +1072,11 @@ static int uart_get_count(struct uart_state *state,
 {
 	struct serial_icounter_struct icount;
 	struct uart_icount cnow;
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
 
-	spin_lock_irq(&port->lock);
-	memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
-	spin_unlock_irq(&port->lock);
+	spin_lock_irq(&uport->lock);
+	memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
+	spin_unlock_irq(&uport->lock);
 
 	icount.cts         = cnow.cts;
 	icount.dsr         = cnow.dsr;
@@ -1093,6 +1101,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
 	   unsigned long arg)
 {
 	struct uart_state *state = tty->driver_data;
+	struct tty_port *port = &state->port;
 	void __user *uarg = (void __user *)arg;
 	int ret = -ENOIOCTLCMD;
 
@@ -1143,7 +1152,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
 	if (ret != -ENOIOCTLCMD)
 		goto out;
 
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 
 	if (tty_hung_up_p(filp)) {
 		ret = -EIO;
@@ -1160,14 +1169,14 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
 		break;
 
 	default: {
-		struct uart_port *port = state->port;
-		if (port->ops->ioctl)
-			ret = port->ops->ioctl(port, cmd, arg);
+		struct uart_port *uport = state->uart_port;
+		if (uport->ops->ioctl)
+			ret = uport->ops->ioctl(uport, cmd, arg);
 		break;
 	}
 	}
 out_up:
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 out:
 	return ret;
 }
@@ -1175,10 +1184,10 @@ out:
 static void uart_set_ldisc(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
 
-	if (port->ops->set_ldisc)
-		port->ops->set_ldisc(port);
+	if (uport->ops->set_ldisc)
+		uport->ops->set_ldisc(uport);
 }
 
 static void uart_set_termios(struct tty_struct *tty,
@@ -1207,7 +1216,7 @@ static void uart_set_termios(struct tty_struct *tty,
 
 	/* Handle transition to B0 status */
 	if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
-		uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR);
+		uart_clear_mctrl(state->uart_port, TIOCM_RTS | TIOCM_DTR);
 
 	/* Handle transition away from B0 status */
 	if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
@@ -1215,25 +1224,25 @@ static void uart_set_termios(struct tty_struct *tty,
 		if (!(cflag & CRTSCTS) ||
 		    !test_bit(TTY_THROTTLED, &tty->flags))
 			mask |= TIOCM_RTS;
-		uart_set_mctrl(state->port, mask);
+		uart_set_mctrl(state->uart_port, mask);
 	}
 
 	/* Handle turning off CRTSCTS */
 	if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
-		spin_lock_irqsave(&state->port->lock, flags);
+		spin_lock_irqsave(&state->uart_port->lock, flags);
 		tty->hw_stopped = 0;
 		__uart_start(tty);
-		spin_unlock_irqrestore(&state->port->lock, flags);
+		spin_unlock_irqrestore(&state->uart_port->lock, flags);
 	}
 
 	/* Handle turning on CRTSCTS */
 	if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
-		spin_lock_irqsave(&state->port->lock, flags);
-		if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) {
+		spin_lock_irqsave(&state->uart_port->lock, flags);
+		if (!(state->uart_port->ops->get_mctrl(state->uart_port) & TIOCM_CTS)) {
 			tty->hw_stopped = 1;
-			state->port->ops->stop_tx(state->port);
+			state->uart_port->ops->stop_tx(state->uart_port);
 		}
-		spin_unlock_irqrestore(&state->port->lock, flags);
+		spin_unlock_irqrestore(&state->uart_port->lock, flags);
 	}
 #if 0
 	/*
@@ -1244,7 +1253,7 @@ static void uart_set_termios(struct tty_struct *tty,
 	 */
 	if (!(old_termios->c_cflag & CLOCAL) &&
 	    (tty->termios->c_cflag & CLOCAL))
-		wake_up_interruptible(&info->port.open_wait);
+		wake_up_interruptible(&state->uart_port.open_wait);
 #endif
 }
 
@@ -1256,40 +1265,39 @@ static void uart_set_termios(struct tty_struct *tty,
 static void uart_close(struct tty_struct *tty, struct file *filp)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port;
+	struct tty_port *port;
+	struct uart_port *uport;
 
 	BUG_ON(!kernel_locked());
 
-	if (!state || !state->port)
-		return;
+	uport = state->uart_port;
+	port = &state->port;
 
-	port = state->port;
+	pr_debug("uart_close(%d) called\n", uport->line);
 
-	pr_debug("uart_close(%d) called\n", port->line);
-
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 
 	if (tty_hung_up_p(filp))
 		goto done;
 
-	if ((tty->count == 1) && (state->count != 1)) {
+	if ((tty->count == 1) && (port->count != 1)) {
 		/*
 		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  state->count should always
+		 * structure will be freed.  port->count should always
 		 * be one in these conditions.  If it's greater than
 		 * one, we've got real problems, since it means the
 		 * serial port won't be shutdown.
 		 */
 		printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, "
-		       "state->count is %d\n", state->count);
-		state->count = 1;
+		       "port->count is %d\n", port->count);
+		port->count = 1;
 	}
-	if (--state->count < 0) {
+	if (--port->count < 0) {
 		printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n",
-		       tty->name, state->count);
-		state->count = 0;
+		       tty->name, port->count);
+		port->count = 0;
 	}
-	if (state->count)
+	if (port->count)
 		goto done;
 
 	/*
@@ -1299,24 +1307,24 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	 */
 	tty->closing = 1;
 
-	if (state->closing_wait != USF_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, msecs_to_jiffies(state->closing_wait));
+	if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, msecs_to_jiffies(port->closing_wait));
 
 	/*
 	 * At this point, we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts.
 	 */
-	if (state->info.flags & UIF_INITIALIZED) {
+	if (port->flags & ASYNC_INITIALIZED) {
 		unsigned long flags;
 		spin_lock_irqsave(&port->lock, flags);
-		port->ops->stop_rx(port);
+		uport->ops->stop_rx(uport);
 		spin_unlock_irqrestore(&port->lock, flags);
 		/*
 		 * Before we drop DTR, make sure the UART transmitter
 		 * has completely drained; this is especially
 		 * important if there is a transmit FIFO!
 		 */
-		uart_wait_until_sent(tty, port->timeout);
+		uart_wait_until_sent(tty, uport->timeout);
 	}
 
 	uart_shutdown(state);
@@ -1325,29 +1333,29 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 	tty_ldisc_flush(tty);
 
 	tty->closing = 0;
-	state->info.port.tty = NULL;
+	tty_port_tty_set(port, NULL);
 
-	if (state->info.port.blocked_open) {
-		if (state->close_delay)
-			msleep_interruptible(state->close_delay);
-	} else if (!uart_console(port)) {
+	if (port->blocked_open) {
+		if (port->close_delay)
+			msleep_interruptible(port->close_delay);
+	} else if (!uart_console(uport)) {
 		uart_change_pm(state, 3);
 	}
 
 	/*
 	 * Wake up anyone trying to open this port.
 	 */
-	state->info.flags &= ~UIF_NORMAL_ACTIVE;
-	wake_up_interruptible(&state->info.port.open_wait);
+	clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
+	wake_up_interruptible(&port->open_wait);
 
- done:
-	mutex_unlock(&state->mutex);
+done:
+	mutex_unlock(&port->mutex);
 }
 
 static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_port *port = state->port;
+	struct uart_port *port = state->uart_port;
 	unsigned long char_time, expire;
 
 	if (port->type == PORT_UNKNOWN || port->fifosize == 0)
@@ -1412,22 +1420,22 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
 static void uart_hangup(struct tty_struct *tty)
 {
 	struct uart_state *state = tty->driver_data;
-	struct uart_info *info = &state->info;
+	struct tty_port *port = &state->port;
 
 	BUG_ON(!kernel_locked());
-	pr_debug("uart_hangup(%d)\n", state->port->line);
+	pr_debug("uart_hangup(%d)\n", state->uart_port->line);
 
-	mutex_lock(&state->mutex);
-	if (info->flags & UIF_NORMAL_ACTIVE) {
+	mutex_lock(&port->mutex);
+	if (port->flags & ASYNC_NORMAL_ACTIVE) {
 		uart_flush_buffer(tty);
 		uart_shutdown(state);
-		state->count = 0;
-		info->flags &= ~UIF_NORMAL_ACTIVE;
-		info->port.tty = NULL;
-		wake_up_interruptible(&info->port.open_wait);
-		wake_up_interruptible(&info->delta_msr_wait);
+		port->count = 0;
+		clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
+		tty_port_tty_set(port, NULL);
+		wake_up_interruptible(&port->open_wait);
+		wake_up_interruptible(&port->delta_msr_wait);
 	}
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 }
 
 /*
@@ -1438,8 +1446,8 @@ static void uart_hangup(struct tty_struct *tty)
  */
 static void uart_update_termios(struct uart_state *state)
 {
-	struct tty_struct *tty = state->info.port.tty;
-	struct uart_port *port = state->port;
+	struct tty_struct *tty = state->port.tty;
+	struct uart_port *port = state->uart_port;
 
 	if (uart_console(port) && port->cons->cflag) {
 		tty->termios->c_cflag = port->cons->cflag;
@@ -1473,27 +1481,27 @@ static int
 uart_block_til_ready(struct file *filp, struct uart_state *state)
 {
 	DECLARE_WAITQUEUE(wait, current);
-	struct uart_info *info = &state->info;
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
+	struct tty_port *port = &state->port;
 	unsigned int mctrl;
 
-	info->port.blocked_open++;
-	state->count--;
+	port->blocked_open++;
+	port->count--;
 
-	add_wait_queue(&info->port.open_wait, &wait);
+	add_wait_queue(&port->open_wait, &wait);
 	while (1) {
 		set_current_state(TASK_INTERRUPTIBLE);
 
 		/*
 		 * If we have been hung up, tell userspace/restart open.
 		 */
-		if (tty_hung_up_p(filp) || info->port.tty == NULL)
+		if (tty_hung_up_p(filp) || port->tty == NULL)
 			break;
 
 		/*
 		 * If the port has been closed, tell userspace/restart open.
 		 */
-		if (!(info->flags & UIF_INITIALIZED))
+		if (!(port->flags & ASYNC_INITIALIZED))
 			break;
 
 		/*
@@ -1506,8 +1514,8 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
 		 * have set TTY_IO_ERROR for a non-existant port.
 		 */
 		if ((filp->f_flags & O_NONBLOCK) ||
-		    (info->port.tty->termios->c_cflag & CLOCAL) ||
-		    (info->port.tty->flags & (1 << TTY_IO_ERROR)))
+		    (port->tty->termios->c_cflag & CLOCAL) ||
+		    (port->tty->flags & (1 << TTY_IO_ERROR)))
 			break;
 
 		/*
@@ -1515,37 +1523,37 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
 		 * not set RTS here - we want to make sure we catch
 		 * the data from the modem.
 		 */
-		if (info->port.tty->termios->c_cflag & CBAUD)
-			uart_set_mctrl(port, TIOCM_DTR);
+		if (port->tty->termios->c_cflag & CBAUD)
+			uart_set_mctrl(uport, TIOCM_DTR);
 
 		/*
 		 * and wait for the carrier to indicate that the
 		 * modem is ready for us.
 		 */
-		spin_lock_irq(&port->lock);
-		port->ops->enable_ms(port);
-		mctrl = port->ops->get_mctrl(port);
-		spin_unlock_irq(&port->lock);
+		spin_lock_irq(&uport->lock);
+		uport->ops->enable_ms(uport);
+		mctrl = uport->ops->get_mctrl(uport);
+		spin_unlock_irq(&uport->lock);
 		if (mctrl & TIOCM_CAR)
 			break;
 
-		mutex_unlock(&state->mutex);
+		mutex_unlock(&port->mutex);
 		schedule();
-		mutex_lock(&state->mutex);
+		mutex_lock(&port->mutex);
 
 		if (signal_pending(current))
 			break;
 	}
 	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&info->port.open_wait, &wait);
+	remove_wait_queue(&port->open_wait, &wait);
 
-	state->count++;
-	info->port.blocked_open--;
+	port->count++;
+	port->blocked_open--;
 
 	if (signal_pending(current))
 		return -ERESTARTSYS;
 
-	if (!info->port.tty || tty_hung_up_p(filp))
+	if (!port->tty || tty_hung_up_p(filp))
 		return -EAGAIN;
 
 	return 0;
@@ -1554,24 +1562,26 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
 static struct uart_state *uart_get(struct uart_driver *drv, int line)
 {
 	struct uart_state *state;
+	struct tty_port *port;
 	int ret = 0;
 
 	state = drv->state + line;
-	if (mutex_lock_interruptible(&state->mutex)) {
+	port = &state->port;
+	if (mutex_lock_interruptible(&port->mutex)) {
 		ret = -ERESTARTSYS;
 		goto err;
 	}
 
-	state->count++;
-	if (!state->port || state->port->flags & UPF_DEAD) {
+	port->count++;
+	if (!state->uart_port || state->uart_port->flags & UPF_DEAD) {
 		ret = -ENXIO;
 		goto err_unlock;
 	}
 	return state;
 
  err_unlock:
-	state->count--;
-	mutex_unlock(&state->mutex);
+	port->count--;
+	mutex_unlock(&port->mutex);
  err:
 	return ERR_PTR(ret);
 }
@@ -1590,6 +1600,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
 {
 	struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state;
 	struct uart_state *state;
+	struct tty_port *port;
 	int retval, line = tty->index;
 
 	BUG_ON(!kernel_locked());
@@ -1606,16 +1617,18 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
 
 	/*
 	 * We take the semaphore inside uart_get to guarantee that we won't
-	 * be re-entered while allocating the info structure, or while we
+	 * be re-entered while allocating the state structure, or while we
 	 * request any IRQs that the driver may need.  This also has the nice
 	 * side-effect that it delays the action of uart_hangup, so we can
-	 * guarantee that info->port.tty will always contain something reasonable.
+	 * guarantee that state->port.tty will always contain something
+	 * reasonable.
 	 */
 	state = uart_get(drv, line);
 	if (IS_ERR(state)) {
 		retval = PTR_ERR(state);
 		goto fail;
 	}
+	port = &state->port;
 
 	/*
 	 * Once we set tty->driver_data here, we are guaranteed that
@@ -1623,25 +1636,25 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
 	 * Any failures from here onwards should not touch the count.
 	 */
 	tty->driver_data = state;
-	state->port->info = &state->info;
-	tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
+	state->uart_port->state = state;
+	tty->low_latency = (state->uart_port->flags & UPF_LOW_LATENCY) ? 1 : 0;
 	tty->alt_speed = 0;
-	state->info.port.tty = tty;
+	tty_port_tty_set(port, tty);
 
 	/*
 	 * If the port is in the middle of closing, bail out now.
 	 */
 	if (tty_hung_up_p(filp)) {
 		retval = -EAGAIN;
-		state->count--;
-		mutex_unlock(&state->mutex);
+		port->count--;
+		mutex_unlock(&port->mutex);
 		goto fail;
 	}
 
 	/*
 	 * Make sure the device is in D0 state.
 	 */
-	if (state->count == 1)
+	if (port->count == 1)
 		uart_change_pm(state, 0);
 
 	/*
@@ -1654,18 +1667,18 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
 	 */
 	if (retval == 0)
 		retval = uart_block_til_ready(filp, state);
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 
 	/*
 	 * If this is the first open to succeed, adjust things to suit.
 	 */
-	if (retval == 0 && !(state->info.flags & UIF_NORMAL_ACTIVE)) {
-		state->info.flags |= UIF_NORMAL_ACTIVE;
+	if (retval == 0 && !(port->flags & ASYNC_NORMAL_ACTIVE)) {
+		set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
 
 		uart_update_termios(state);
 	}
 
- fail:
+fail:
 	return retval;
 }
 
@@ -1687,57 +1700,58 @@ static const char *uart_type(struct uart_port *port)
 static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
 {
 	struct uart_state *state = drv->state + i;
+	struct tty_port *port = &state->port;
 	int pm_state;
-	struct uart_port *port = state->port;
+	struct uart_port *uport = state->uart_port;
 	char stat_buf[32];
 	unsigned int status;
 	int mmio;
 
-	if (!port)
+	if (!uport)
 		return;
 
-	mmio = port->iotype >= UPIO_MEM;
+	mmio = uport->iotype >= UPIO_MEM;
 	seq_printf(m, "%d: uart:%s %s%08llX irq:%d",
-			port->line, uart_type(port),
+			uport->line, uart_type(uport),
 			mmio ? "mmio:0x" : "port:",
-			mmio ? (unsigned long long)port->mapbase
-			     : (unsigned long long) port->iobase,
-			port->irq);
+			mmio ? (unsigned long long)uport->mapbase
+			     : (unsigned long long)uport->iobase,
+			uport->irq);
 
-	if (port->type == PORT_UNKNOWN) {
+	if (uport->type == PORT_UNKNOWN) {
 		seq_putc(m, '\n');
 		return;
 	}
 
 	if (capable(CAP_SYS_ADMIN)) {
-		mutex_lock(&state->mutex);
+		mutex_lock(&port->mutex);
 		pm_state = state->pm_state;
 		if (pm_state)
 			uart_change_pm(state, 0);
-		spin_lock_irq(&port->lock);
-		status = port->ops->get_mctrl(port);
-		spin_unlock_irq(&port->lock);
+		spin_lock_irq(&uport->lock);
+		status = uport->ops->get_mctrl(uport);
+		spin_unlock_irq(&uport->lock);
 		if (pm_state)
 			uart_change_pm(state, pm_state);
-		mutex_unlock(&state->mutex);
+		mutex_unlock(&port->mutex);
 
 		seq_printf(m, " tx:%d rx:%d",
-				port->icount.tx, port->icount.rx);
-		if (port->icount.frame)
+				uport->icount.tx, uport->icount.rx);
+		if (uport->icount.frame)
 			seq_printf(m, " fe:%d",
-				port->icount.frame);
-		if (port->icount.parity)
+				uport->icount.frame);
+		if (uport->icount.parity)
 			seq_printf(m, " pe:%d",
-				port->icount.parity);
-		if (port->icount.brk)
+				uport->icount.parity);
+		if (uport->icount.brk)
 			seq_printf(m, " brk:%d",
-				port->icount.brk);
-		if (port->icount.overrun)
+				uport->icount.brk);
+		if (uport->icount.overrun)
 			seq_printf(m, " oe:%d",
-				port->icount.overrun);
+				uport->icount.overrun);
 
 #define INFOBIT(bit, str) \
-	if (port->mctrl & (bit)) \
+	if (uport->mctrl & (bit)) \
 		strncat(stat_buf, (str), sizeof(stat_buf) - \
 			strlen(stat_buf) - 2)
 #define STATBIT(bit, str) \
@@ -1958,7 +1972,7 @@ EXPORT_SYMBOL_GPL(uart_set_options);
 
 static void uart_change_pm(struct uart_state *state, int pm_state)
 {
-	struct uart_port *port = state->port;
+	struct uart_port *port = state->uart_port;
 
 	if (state->pm_state != pm_state) {
 		if (port->ops->pm)
@@ -1982,132 +1996,138 @@ static int serial_match_port(struct device *dev, void *data)
 	return dev->devt == devt; /* Actually, only one tty per port */
 }
 
-int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
+int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
 {
-	struct uart_state *state = drv->state + port->line;
+	struct uart_state *state = drv->state + uport->line;
+	struct tty_port *port = &state->port;
 	struct device *tty_dev;
-	struct uart_match match = {port, drv};
+	struct uart_match match = {uport, drv};
 
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 
-	if (!console_suspend_enabled && uart_console(port)) {
+	if (!console_suspend_enabled && uart_console(uport)) {
 		/* we're going to avoid suspending serial console */
-		mutex_unlock(&state->mutex);
+		mutex_unlock(&port->mutex);
 		return 0;
 	}
 
-	tty_dev = device_find_child(port->dev, &match, serial_match_port);
+	tty_dev = device_find_child(uport->dev, &match, serial_match_port);
 	if (device_may_wakeup(tty_dev)) {
-		enable_irq_wake(port->irq);
+		enable_irq_wake(uport->irq);
 		put_device(tty_dev);
-		mutex_unlock(&state->mutex);
+		mutex_unlock(&port->mutex);
 		return 0;
 	}
-	port->suspended = 1;
+	uport->suspended = 1;
 
-	if (state->info.flags & UIF_INITIALIZED) {
-		const struct uart_ops *ops = port->ops;
+	if (port->flags & ASYNC_INITIALIZED) {
+		const struct uart_ops *ops = uport->ops;
 		int tries;
 
-		state->info.flags = (state->info.flags & ~UIF_INITIALIZED)
-				     | UIF_SUSPENDED;
+		set_bit(ASYNCB_SUSPENDED, &port->flags);
+		clear_bit(ASYNCB_INITIALIZED, &port->flags);
 
-		spin_lock_irq(&port->lock);
-		ops->stop_tx(port);
-		ops->set_mctrl(port, 0);
-		ops->stop_rx(port);
-		spin_unlock_irq(&port->lock);
+		spin_lock_irq(&uport->lock);
+		ops->stop_tx(uport);
+		ops->set_mctrl(uport, 0);
+		ops->stop_rx(uport);
+		spin_unlock_irq(&uport->lock);
 
 		/*
 		 * Wait for the transmitter to empty.
 		 */
-		for (tries = 3; !ops->tx_empty(port) && tries; tries--)
+		for (tries = 3; !ops->tx_empty(uport) && tries; tries--)
 			msleep(10);
 		if (!tries)
 			printk(KERN_ERR "%s%s%s%d: Unable to drain "
 					"transmitter\n",
-			       port->dev ? dev_name(port->dev) : "",
-			       port->dev ? ": " : "",
+			       uport->dev ? dev_name(uport->dev) : "",
+			       uport->dev ? ": " : "",
 			       drv->dev_name,
-			       drv->tty_driver->name_base + port->line);
+			       drv->tty_driver->name_base + uport->line);
 
-		ops->shutdown(port);
+		ops->shutdown(uport);
 	}
 
 	/*
 	 * Disable the console device before suspending.
 	 */
-	if (uart_console(port))
-		console_stop(port->cons);
+	if (uart_console(uport))
+		console_stop(uport->cons);
 
 	uart_change_pm(state, 3);
 
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 
 	return 0;
 }
 
-int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
+int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
 {
-	struct uart_state *state = drv->state + port->line;
+	struct uart_state *state = drv->state + uport->line;
+	struct tty_port *port = &state->port;
 	struct device *tty_dev;
-	struct uart_match match = {port, drv};
+	struct uart_match match = {uport, drv};
+	struct ktermios termios;
 
-	mutex_lock(&state->mutex);
+	mutex_lock(&port->mutex);
 
-	if (!console_suspend_enabled && uart_console(port)) {
+	if (!console_suspend_enabled && uart_console(uport)) {
 		/* no need to resume serial console, it wasn't suspended */
-		mutex_unlock(&state->mutex);
+		/*
+		 * First try to use the console cflag setting.
+		 */
+		memset(&termios, 0, sizeof(struct ktermios));
+		termios.c_cflag = uport->cons->cflag;
+		/*
+		 * If that's unset, use the tty termios setting.
+		 */
+		if (termios.c_cflag == 0)
+			termios = *state->port.tty->termios;
+		else {
+			termios.c_ispeed = termios.c_ospeed =
+				tty_termios_input_baud_rate(&termios);
+			termios.c_ispeed = termios.c_ospeed =
+				tty_termios_baud_rate(&termios);
+		}
+		uport->ops->set_termios(uport, &termios, NULL);
+		mutex_unlock(&port->mutex);
 		return 0;
 	}
 
-	tty_dev = device_find_child(port->dev, &match, serial_match_port);
-	if (!port->suspended && device_may_wakeup(tty_dev)) {
-		disable_irq_wake(port->irq);
-		mutex_unlock(&state->mutex);
+	tty_dev = device_find_child(uport->dev, &match, serial_match_port);
+	if (!uport->suspended && device_may_wakeup(tty_dev)) {
+		disable_irq_wake(uport->irq);
+		mutex_unlock(&port->mutex);
 		return 0;
 	}
-	port->suspended = 0;
+	uport->suspended = 0;
 
 	/*
 	 * Re-enable the console device after suspending.
 	 */
-	if (uart_console(port)) {
-		struct ktermios termios;
-
-		/*
-		 * First try to use the console cflag setting.
-		 */
-		memset(&termios, 0, sizeof(struct ktermios));
-		termios.c_cflag = port->cons->cflag;
-
-		/*
-		 * If that's unset, use the tty termios setting.
-		 */
-		if (state->info.port.tty && termios.c_cflag == 0)
-			termios = *state->info.port.tty->termios;
-
+	if (uart_console(uport)) {
 		uart_change_pm(state, 0);
-		port->ops->set_termios(port, &termios, NULL);
-		console_start(port->cons);
+		uport->ops->set_termios(uport, &termios, NULL);
+		console_start(uport->cons);
 	}
 
-	if (state->info.flags & UIF_SUSPENDED) {
-		const struct uart_ops *ops = port->ops;
+	if (port->flags & ASYNC_SUSPENDED) {
+		const struct uart_ops *ops = uport->ops;
 		int ret;
 
 		uart_change_pm(state, 0);
-		spin_lock_irq(&port->lock);
-		ops->set_mctrl(port, 0);
-		spin_unlock_irq(&port->lock);
-		ret = ops->startup(port);
+		spin_lock_irq(&uport->lock);
+		ops->set_mctrl(uport, 0);
+		spin_unlock_irq(&uport->lock);
+		ret = ops->startup(uport);
 		if (ret == 0) {
 			uart_change_speed(state, NULL);
-			spin_lock_irq(&port->lock);
-			ops->set_mctrl(port, port->mctrl);
-			ops->start_tx(port);
-			spin_unlock_irq(&port->lock);
-			state->info.flags |= UIF_INITIALIZED;
+			spin_lock_irq(&uport->lock);
+			ops->set_mctrl(uport, uport->mctrl);
+			ops->start_tx(uport);
+			spin_unlock_irq(&uport->lock);
+			set_bit(ASYNCB_INITIALIZED, &port->flags);
 		} else {
 			/*
 			 * Failed to resume - maybe hardware went away?
@@ -2117,10 +2137,10 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
 			uart_shutdown(state);
 		}
 
-		state->info.flags &= ~UIF_SUSPENDED;
+		clear_bit(ASYNCB_SUSPENDED, &port->flags);
 	}
 
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 
 	return 0;
 }
@@ -2232,10 +2252,10 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)
 	int parity = 'n';
 	int flow = 'n';
 
-	if (!state || !state->port)
+	if (!state || !state->uart_port)
 		return -1;
 
-	port = state->port;
+	port = state->uart_port;
 	if (!(port->ops->poll_get_char && port->ops->poll_put_char))
 		return -1;
 
@@ -2253,10 +2273,10 @@ static int uart_poll_get_char(struct tty_driver *driver, int line)
 	struct uart_state *state = drv->state + line;
 	struct uart_port *port;
 
-	if (!state || !state->port)
+	if (!state || !state->uart_port)
 		return -1;
 
-	port = state->port;
+	port = state->uart_port;
 	return port->ops->poll_get_char(port);
 }
 
@@ -2266,10 +2286,10 @@ static void uart_poll_put_char(struct tty_driver *driver, int line, char ch)
 	struct uart_state *state = drv->state + line;
 	struct uart_port *port;
 
-	if (!state || !state->port)
+	if (!state || !state->uart_port)
 		return;
 
-	port = state->port;
+	port = state->uart_port;
 	port->ops->poll_put_char(port, ch);
 }
 #endif
@@ -2360,14 +2380,12 @@ int uart_register_driver(struct uart_driver *drv)
 	 */
 	for (i = 0; i < drv->nr; i++) {
 		struct uart_state *state = drv->state + i;
+		struct tty_port *port = &state->port;
 
-		state->close_delay     = 500;	/* .5 seconds */
-		state->closing_wait    = 30000;	/* 30 seconds */
-		mutex_init(&state->mutex);
-
-		tty_port_init(&state->info.port);
-		init_waitqueue_head(&state->info.delta_msr_wait);
-		tasklet_init(&state->info.tlet, uart_tasklet_action,
+		tty_port_init(port);
+		port->close_delay     = 500;	/* .5 seconds */
+		port->closing_wait    = 30000;	/* 30 seconds */
+		tasklet_init(&state->tlet, uart_tasklet_action,
 			     (unsigned long)state);
 	}
 
@@ -2415,62 +2433,64 @@ struct tty_driver *uart_console_device(struct console *co, int *index)
  *	level uart drivers to expand uart_port, rather than having yet
  *	more levels of structures.
  */
-int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
+int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
 {
 	struct uart_state *state;
+	struct tty_port *port;
 	int ret = 0;
 	struct device *tty_dev;
 
 	BUG_ON(in_interrupt());
 
-	if (port->line >= drv->nr)
+	if (uport->line >= drv->nr)
 		return -EINVAL;
 
-	state = drv->state + port->line;
+	state = drv->state + uport->line;
+	port = &state->port;
 
 	mutex_lock(&port_mutex);
-	mutex_lock(&state->mutex);
-	if (state->port) {
+	mutex_lock(&port->mutex);
+	if (state->uart_port) {
 		ret = -EINVAL;
 		goto out;
 	}
 
-	state->port = port;
+	state->uart_port = uport;
 	state->pm_state = -1;
 
-	port->cons = drv->cons;
-	port->info = &state->info;
+	uport->cons = drv->cons;
+	uport->state = state;
 
 	/*
 	 * If this port is a console, then the spinlock is already
 	 * initialised.
 	 */
-	if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) {
-		spin_lock_init(&port->lock);
-		lockdep_set_class(&port->lock, &port_lock_key);
+	if (!(uart_console(uport) && (uport->cons->flags & CON_ENABLED))) {
+		spin_lock_init(&uport->lock);
+		lockdep_set_class(&uport->lock, &port_lock_key);
 	}
 
-	uart_configure_port(drv, state, port);
+	uart_configure_port(drv, state, uport);
 
 	/*
 	 * Register the port whether it's detected or not.  This allows
 	 * setserial to be used to alter this ports parameters.
 	 */
-	tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev);
+	tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev);
 	if (likely(!IS_ERR(tty_dev))) {
 		device_init_wakeup(tty_dev, 1);
 		device_set_wakeup_enable(tty_dev, 0);
 	} else
 		printk(KERN_ERR "Cannot register tty device on line %d\n",
-		       port->line);
+		       uport->line);
 
 	/*
 	 * Ensure UPF_DEAD is not set.
 	 */
-	port->flags &= ~UPF_DEAD;
+	uport->flags &= ~UPF_DEAD;
 
  out:
-	mutex_unlock(&state->mutex);
+	mutex_unlock(&port->mutex);
 	mutex_unlock(&port_mutex);
 
 	return ret;
@@ -2485,16 +2505,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
  *	core driver.  No further calls will be made to the low-level code
  *	for this port.
  */
-int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
+int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
 {
-	struct uart_state *state = drv->state + port->line;
-	struct uart_info *info;
+	struct uart_state *state = drv->state + uport->line;
+	struct tty_port *port = &state->port;
 
 	BUG_ON(in_interrupt());
 
-	if (state->port != port)
+	if (state->uart_port != uport)
 		printk(KERN_ALERT "Removing wrong port: %p != %p\n",
-			state->port, port);
+			state->uart_port, uport);
 
 	mutex_lock(&port_mutex);
 
@@ -2502,37 +2522,35 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
 	 * Mark the port "dead" - this prevents any opens from
 	 * succeeding while we shut down the port.
 	 */
-	mutex_lock(&state->mutex);
-	port->flags |= UPF_DEAD;
-	mutex_unlock(&state->mutex);
+	mutex_lock(&port->mutex);
+	uport->flags |= UPF_DEAD;
+	mutex_unlock(&port->mutex);
 
 	/*
 	 * Remove the devices from the tty layer
 	 */
-	tty_unregister_device(drv->tty_driver, port->line);
+	tty_unregister_device(drv->tty_driver, uport->line);
 
-	info = &state->info;
-	if (info && info->port.tty)
-		tty_vhangup(info->port.tty);
+	if (port->tty)
+		tty_vhangup(port->tty);
 
 	/*
 	 * Free the port IO and memory resources, if any.
 	 */
-	if (port->type != PORT_UNKNOWN)
-		port->ops->release_port(port);
+	if (uport->type != PORT_UNKNOWN)
+		uport->ops->release_port(uport);
 
 	/*
 	 * Indicate that there isn't a port here anymore.
 	 */
-	port->type = PORT_UNKNOWN;
+	uport->type = PORT_UNKNOWN;
 
 	/*
 	 * Kill the tasklet, and free resources.
 	 */
-	if (info)
-		tasklet_kill(&info->tlet);
+	tasklet_kill(&state->tlet);
 
-	state->port = NULL;
+	state->uart_port = NULL;
 	mutex_unlock(&port_mutex);
 
 	return 0;
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 79c9c5f..a3bb490 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -868,11 +868,11 @@ static struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
 	PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
 	PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
-	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
+	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
@@ -883,10 +883,11 @@ static struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"),	/* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
-	PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "COMpad2.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
 	PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
-	PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
+	PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
 	PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100  1.00.",0x19ca78af,0xf964f42b),
 	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index e066563..2e71bbc 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -110,7 +110,11 @@ static struct console ks8695_console;
 static void ks8695uart_stop_tx(struct uart_port *port)
 {
 	if (tx_enabled(port)) {
-		disable_irq(KS8695_IRQ_UART_TX);
+		/* use disable_irq_nosync() and not disable_irq() to avoid self
+		 * imposed deadlock by not waiting for irq handler to end,
+		 * since this ks8695uart_stop_tx() is called from interrupt context.
+		 */
+		disable_irq_nosync(KS8695_IRQ_UART_TX);
 		tx_enable(port, 0);
 	}
 }
@@ -150,7 +154,7 @@ static void ks8695uart_disable_ms(struct uart_port *port)
 static irqreturn_t ks8695uart_rx_chars(int irq, void *dev_id)
 {
 	struct uart_port *port = dev_id;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	unsigned int status, ch, lsr, flg, max_count = 256;
 
 	status = UART_GET_LSR(port);		/* clears pending LSR interrupts */
@@ -206,7 +210,7 @@ ignore_char:
 static irqreturn_t ks8695uart_tx_chars(int irq, void *dev_id)
 {
 	struct uart_port *port = dev_id;
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 	unsigned int count;
 
 	if (port->x_char) {
@@ -262,7 +266,7 @@ static irqreturn_t ks8695uart_modem_status(int irq, void *dev_id)
 	if (status & URMS_URTERI)
 		port->icount.rng++;
 
-	wake_up_interruptible(&port->info->delta_msr_wait);
+	wake_up_interruptible(&port->state->port.delta_msr_wait);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index a7bf024..ea74470 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -138,7 +138,7 @@ static void lh7a40xuart_enable_ms (struct uart_port* port)
 
 static void lh7a40xuart_rx_chars (struct uart_port* port)
 {
-	struct tty_struct* tty = port->info->port.tty;
+	struct tty_struct* tty = port->state->port.tty;
 	int cbRxMax = 256;	/* (Gross) limit on receive */
 	unsigned int data;	/* Received data and status */
 	unsigned int flag;
@@ -184,7 +184,7 @@ static void lh7a40xuart_rx_chars (struct uart_port* port)
 
 static void lh7a40xuart_tx_chars (struct uart_port* port)
 {
-	struct circ_buf* xmit = &port->info->xmit;
+	struct circ_buf* xmit = &port->state->xmit;
 	int cbTxMax = port->fifosize;
 
 	if (port->x_char) {
@@ -241,7 +241,7 @@ static void lh7a40xuart_modem_status (struct uart_port* port)
 	if (delta & CTS)
 		uart_handle_cts_change (port, status & CTS);
 
-	wake_up_interruptible (&port->info->delta_msr_wait);
+	wake_up_interruptible (&port->state->port.delta_msr_wait);
 }
 
 static irqreturn_t lh7a40xuart_int (int irq, void* dev_id)
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 54dd16d..0f7cf4c 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -272,7 +272,7 @@ static void serial_txx9_initialize(struct uart_port *port)
 static inline void
 receive_chars(struct uart_txx9_port *up, unsigned int *status)
 {
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned char ch;
 	unsigned int disr = *status;
 	int max_count = 256;
@@ -348,7 +348,7 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status)
 
 static inline void transmit_chars(struct uart_txx9_port *up)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 	int count;
 
 	if (up->port.x_char) {
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 8e2feb5..85119fb 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -272,7 +272,8 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
 		__raw_writew(data, PSCR);
 	}
 }
-#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7763) || \
       defined(CONFIG_CPU_SUBTYPE_SH7780) || \
       defined(CONFIG_CPU_SUBTYPE_SH7785) || \
       defined(CONFIG_CPU_SUBTYPE_SH7786) || \
@@ -360,7 +361,7 @@ static inline int sci_rxroom(struct uart_port *port)
 
 static void sci_transmit_chars(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 	unsigned int stopped = uart_tx_stopped(port);
 	unsigned short status;
 	unsigned short ctrl;
@@ -425,7 +426,7 @@ static void sci_transmit_chars(struct uart_port *port)
 static inline void sci_receive_chars(struct uart_port *port)
 {
 	struct sci_port *sci_port = to_sci_port(port);
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	int i, count, copied = 0;
 	unsigned short status;
 	unsigned char flag;
@@ -545,7 +546,7 @@ static inline int sci_handle_errors(struct uart_port *port)
 {
 	int copied = 0;
 	unsigned short status = sci_in(port, SCxSR);
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 
 	if (status & SCxSR_ORER(port)) {
 		/* overrun error */
@@ -599,7 +600,7 @@ static inline int sci_handle_errors(struct uart_port *port)
 
 static inline int sci_handle_fifo_overrun(struct uart_port *port)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	int copied = 0;
 
 	if (port->type != PORT_SCIF)
@@ -622,7 +623,7 @@ static inline int sci_handle_breaks(struct uart_port *port)
 {
 	int copied = 0;
 	unsigned short status = sci_in(port, SCxSR);
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	struct sci_port *s = to_sci_port(port);
 
 	if (uart_handle_break(port))
@@ -662,10 +663,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port)
 static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
 {
 	struct uart_port *port = ptr;
+	unsigned long flags;
 
-	spin_lock_irq(&port->lock);
+	spin_lock_irqsave(&port->lock, flags);
 	sci_transmit_chars(port);
-	spin_unlock_irq(&port->lock);
+	spin_unlock_irqrestore(&port->lock, flags);
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 38072c1..3e2fcf9 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -112,6 +112,13 @@
 #elif defined(CONFIG_H8S2678)
 # define SCSCR_INIT(port)          0x30 /* TIE=0,RIE=0,TE=1,RE=1 */
 # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+# define SCSPTR0 0xfe4b0020
+# define SCSPTR1 0xfe4b0020
+# define SCSPTR2 0xfe4b0020
+# define SCIF_ORER 0x0001
+# define SCSCR_INIT(port)	0x38
+# define SCIF_ONLY
 #elif defined(CONFIG_CPU_SUBTYPE_SH7763)
 # define SCSPTR0 0xffe00024 /* 16 bit SCIF */
 # define SCSPTR1 0xffe08024 /* 16 bit SCIF */
@@ -562,6 +569,16 @@ static inline int sci_rxd_in(struct uart_port *port)
 		return ctrl_inw(SCSPTR2)&0x0001 ? 1 : 0; /* SCIF */
 	return 1;
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
+static inline int sci_rxd_in(struct uart_port *port)
+{
+	if (port->mapbase == 0xfe4b0000)
+		return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0;
+	if (port->mapbase == 0xfe4c0000)
+		return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0;
+	if (port->mapbase == 0xfe4d0000)
+		return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0;
+}
 #elif defined(CONFIG_CPU_SUBTYPE_SH7760)
 static inline int sci_rxd_in(struct uart_port *port)
 {
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index d5276c0..9794e0c 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -469,9 +469,9 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
 		return;
 	}
 
-	if (port->sc_port.info) {
+	if (port->sc_port.state) {
 		/* The serial_core stuffs are initilized, use them */
-		tty = port->sc_port.info->port.tty;
+		tty = port->sc_port.state->port.tty;
 	}
 	else {
 		/* Not registered yet - can't pass to tty layer.  */
@@ -550,9 +550,9 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw)
 
 	BUG_ON(!port->sc_is_asynch);
 
-	if (port->sc_port.info) {
+	if (port->sc_port.state) {
 		/* We're initilized, using serial core infrastructure */
-		xmit = &port->sc_port.info->xmit;
+		xmit = &port->sc_port.state->xmit;
 	} else {
 		/* Probably sn_sal_switch_to_asynch has been run but serial core isn't
 		 * initilized yet.  Just return.  Writes are going through
@@ -927,7 +927,7 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
 	/* We can't look at the xmit buffer if we're not registered with serial core
 	 *  yet.  So only do the fancy recovery after registering
 	 */
-	if (!port->sc_port.info) {
+	if (!port->sc_port.state) {
 		/* Not yet registered with serial core - simple case */
 		puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
 		return;
@@ -936,8 +936,8 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
 	/* somebody really wants this output, might be an
 	 * oops, kdb, panic, etc.  make sure they get it. */
 	if (spin_is_locked(&port->sc_port.lock)) {
-		int lhead = port->sc_port.info->xmit.head;
-		int ltail = port->sc_port.info->xmit.tail;
+		int lhead = port->sc_port.state->xmit.head;
+		int ltail = port->sc_port.state->xmit.tail;
 		int counter, got_lock = 0;
 
 		/*
@@ -962,13 +962,13 @@ sn_sal_console_write(struct console *co, const char *s, unsigned count)
 				break;
 			} else {
 				/* still locked */
-				if ((lhead != port->sc_port.info->xmit.head)
+				if ((lhead != port->sc_port.state->xmit.head)
 				    || (ltail !=
-					port->sc_port.info->xmit.tail)) {
+					port->sc_port.state->xmit.tail)) {
 					lhead =
-						port->sc_port.info->xmit.head;
+						port->sc_port.state->xmit.head;
 					ltail =
-						port->sc_port.info->xmit.tail;
+						port->sc_port.state->xmit.tail;
 					counter = 0;
 				}
 			}
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index 1df5325..d548652 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -184,8 +184,8 @@ static struct tty_struct *receive_chars(struct uart_port *port)
 {
 	struct tty_struct *tty = NULL;
 
-	if (port->info != NULL)		/* Unopened serial console */
-		tty = port->info->port.tty;
+	if (port->state != NULL)		/* Unopened serial console */
+		tty = port->state->port.tty;
 
 	if (sunhv_ops->receive_chars(port, tty))
 		sun_do_break();
@@ -197,10 +197,10 @@ static void transmit_chars(struct uart_port *port)
 {
 	struct circ_buf *xmit;
 
-	if (!port->info)
+	if (!port->state)
 		return;
 
-	xmit = &port->info->xmit;
+	xmit = &port->state->xmit;
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
 		return;
 
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index 0355efe..d1ad341 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -117,8 +117,8 @@ receive_chars(struct uart_sunsab_port *up,
 	int count = 0;
 	int i;
 
-	if (up->port.info != NULL)		/* Unopened serial console */
-		tty = up->port.info->port.tty;
+	if (up->port.state != NULL)		/* Unopened serial console */
+		tty = up->port.state->port.tty;
 
 	/* Read number of BYTES (Character + Status) available. */
 	if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
@@ -229,7 +229,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *);
 static void transmit_chars(struct uart_sunsab_port *up,
 			   union sab82532_irq_status *stat)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 	int i;
 
 	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) {
@@ -297,7 +297,7 @@ static void check_status(struct uart_sunsab_port *up,
 		up->port.icount.dsr++;
 	}
 
-	wake_up_interruptible(&up->port.info->delta_msr_wait);
+	wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 }
 
 static irqreturn_t sunsab_interrupt(int irq, void *dev_id)
@@ -429,7 +429,7 @@ static void sunsab_tx_idle(struct uart_sunsab_port *up)
 static void sunsab_start_tx(struct uart_port *port)
 {
 	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 	int i;
 
 	up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR);
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 47c6837..68d262b 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -311,7 +311,7 @@ static void sunsu_enable_ms(struct uart_port *port)
 static struct tty_struct *
 receive_chars(struct uart_sunsu_port *up, unsigned char *status)
 {
-	struct tty_struct *tty = up->port.info->port.tty;
+	struct tty_struct *tty = up->port.state->port.tty;
 	unsigned char ch, flag;
 	int max_count = 256;
 	int saw_console_brk = 0;
@@ -389,7 +389,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status)
 
 static void transmit_chars(struct uart_sunsu_port *up)
 {
-	struct circ_buf *xmit = &up->port.info->xmit;
+	struct circ_buf *xmit = &up->port.state->xmit;
 	int count;
 
 	if (up->port.x_char) {
@@ -441,7 +441,7 @@ static void check_modem_status(struct uart_sunsu_port *up)
 	if (status & UART_MSR_DCTS)
 		uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
 
-	wake_up_interruptible(&up->port.info->delta_msr_wait);
+	wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 }
 
 static irqreturn_t sunsu_serial_interrupt(int irq, void *dev_id)
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index e09d3ce..ef693ae 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -328,9 +328,9 @@ sunzilog_receive_chars(struct uart_sunzilog_port *up,
 	unsigned char ch, r1, flag;
 
 	tty = NULL;
-	if (up->port.info != NULL &&		/* Unopened serial console */
-	    up->port.info->port.tty != NULL)	/* Keyboard || mouse */
-		tty = up->port.info->port.tty;
+	if (up->port.state != NULL &&		/* Unopened serial console */
+	    up->port.state->port.tty != NULL)	/* Keyboard || mouse */
+		tty = up->port.state->port.tty;
 
 	for (;;) {
 
@@ -451,7 +451,7 @@ static void sunzilog_status_handle(struct uart_sunzilog_port *up,
 			uart_handle_cts_change(&up->port,
 					       (status & CTS));
 
-		wake_up_interruptible(&up->port.info->delta_msr_wait);
+		wake_up_interruptible(&up->port.state->port.delta_msr_wait);
 	}
 
 	up->prev_status = status;
@@ -501,9 +501,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
 		return;
 	}
 
-	if (up->port.info == NULL)
+	if (up->port.state == NULL)
 		goto ack_tx_int;
-	xmit = &up->port.info->xmit;
+	xmit = &up->port.state->xmit;
 	if (uart_circ_empty(xmit))
 		goto ack_tx_int;
 
@@ -705,7 +705,7 @@ static void sunzilog_start_tx(struct uart_port *port)
 		port->icount.tx++;
 		port->x_char = 0;
 	} else {
-		struct circ_buf *xmit = &port->info->xmit;
+		struct circ_buf *xmit = &port->state->xmit;
 
 		writeb(xmit->buf[xmit->tail], &channel->data);
 		ZSDELAY();
diff --git a/drivers/serial/timbuart.c b/drivers/serial/timbuart.c
index 063a313..34b31da 100644
--- a/drivers/serial/timbuart.c
+++ b/drivers/serial/timbuart.c
@@ -77,7 +77,7 @@ static void timbuart_flush_buffer(struct uart_port *port)
 
 static void timbuart_rx_chars(struct uart_port *port)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 
 	while (ioread32(port->membase + TIMBUART_ISR) & RXDP) {
 		u8 ch = ioread8(port->membase + TIMBUART_RXFIFO);
@@ -86,7 +86,7 @@ static void timbuart_rx_chars(struct uart_port *port)
 	}
 
 	spin_unlock(&port->lock);
-	tty_flip_buffer_push(port->info->port.tty);
+	tty_flip_buffer_push(port->state->port.tty);
 	spin_lock(&port->lock);
 
 	dev_dbg(port->dev, "%s - total read %d bytes\n",
@@ -95,7 +95,7 @@ static void timbuart_rx_chars(struct uart_port *port)
 
 static void timbuart_tx_chars(struct uart_port *port)
 {
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) &&
 		!uart_circ_empty(xmit)) {
@@ -118,7 +118,7 @@ static void timbuart_handle_tx_port(struct uart_port *port, u32 isr, u32 *ier)
 {
 	struct timbuart_port *uart =
 		container_of(port, struct timbuart_port, port);
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
 		return;
@@ -231,7 +231,7 @@ static void timbuart_mctrl_check(struct uart_port *port, u32 isr, u32 *ier)
 		iowrite32(CTS_DELTA, port->membase + TIMBUART_ISR);
 		cts = timbuart_get_mctrl(port);
 		uart_handle_cts_change(port, cts & TIOCM_CTS);
-		wake_up_interruptible(&port->info->delta_msr_wait);
+		wake_up_interruptible(&port->state->port.delta_msr_wait);
 	}
 
 	*ier |= CTS_DELTA;
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index 3317148..377f271 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -75,7 +75,7 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS];
 
 static int ulite_receive(struct uart_port *port, int stat)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	unsigned char ch = 0;
 	char flag = TTY_NORMAL;
 
@@ -125,7 +125,7 @@ static int ulite_receive(struct uart_port *port, int stat)
 
 static int ulite_transmit(struct uart_port *port, int stat)
 {
-	struct circ_buf *xmit  = &port->info->xmit;
+	struct circ_buf *xmit  = &port->state->xmit;
 
 	if (stat & ULITE_STATUS_TXFULL)
 		return 0;
@@ -154,17 +154,22 @@ static int ulite_transmit(struct uart_port *port, int stat)
 static irqreturn_t ulite_isr(int irq, void *dev_id)
 {
 	struct uart_port *port = dev_id;
-	int busy;
+	int busy, n = 0;
 
 	do {
 		int stat = readb(port->membase + ULITE_STATUS);
 		busy  = ulite_receive(port, stat);
 		busy |= ulite_transmit(port, stat);
+		n++;
 	} while (busy);
 
-	tty_flip_buffer_push(port->info->port.tty);
-
-	return IRQ_HANDLED;
+	/* work done? */
+	if (n > 1) {
+		tty_flip_buffer_push(port->state->port.tty);
+		return IRQ_HANDLED;
+	} else {
+		return IRQ_NONE;
+	}
 }
 
 static unsigned int ulite_tx_empty(struct uart_port *port)
@@ -221,7 +226,7 @@ static int ulite_startup(struct uart_port *port)
 	int ret;
 
 	ret = request_irq(port->irq, ulite_isr,
-			  IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "uartlite", port);
+			  IRQF_SHARED | IRQF_SAMPLE_RANDOM, "uartlite", port);
 	if (ret)
 		return ret;
 
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index e945e78..0c08f28 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -327,7 +327,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
 	unsigned char *p;
 	unsigned int count;
 	struct uart_port *port = &qe_port->port;
-	struct circ_buf *xmit = &port->info->xmit;
+	struct circ_buf *xmit = &port->state->xmit;
 
 	bdp = qe_port->rx_cur;
 
@@ -466,7 +466,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
 	int i;
 	unsigned char ch, *cp;
 	struct uart_port *port = &qe_port->port;
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	struct qe_bd *bdp;
 	u16 status;
 	unsigned int flg;
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index dac550e..3beb6ab 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -318,7 +318,7 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status)
 	char flag;
 	int max_count = RX_MAX_COUNT;
 
-	tty = port->info->port.tty;
+	tty = port->state->port.tty;
 	lsr = *status;
 
 	do {
@@ -386,7 +386,7 @@ static inline void check_modem_status(struct uart_port *port)
 	if (msr & UART_MSR_DCTS)
 		uart_handle_cts_change(port, msr & UART_MSR_CTS);
 
-	wake_up_interruptible(&port->info->delta_msr_wait);
+	wake_up_interruptible(&port->state->port.delta_msr_wait);
 }
 
 static inline void transmit_chars(struct uart_port *port)
@@ -394,7 +394,7 @@ static inline void transmit_chars(struct uart_port *port)
 	struct circ_buf *xmit;
 	int max_count = TX_MAX_COUNT;
 
-	xmit = &port->info->xmit;
+	xmit = &port->state->xmit;
 
 	if (port->x_char) {
 		siu_write(port, UART_TX, port->x_char);
diff --git a/drivers/serial/zs.c b/drivers/serial/zs.c
index d8c2809..1a7fd3e 100644
--- a/drivers/serial/zs.c
+++ b/drivers/serial/zs.c
@@ -602,12 +602,12 @@ static void zs_receive_chars(struct zs_port *zport)
 		uart_insert_char(uport, status, Rx_OVR, ch, flag);
 	}
 
-	tty_flip_buffer_push(uport->info->port.tty);
+	tty_flip_buffer_push(uport->state->port.tty);
 }
 
 static void zs_raw_transmit_chars(struct zs_port *zport)
 {
-	struct circ_buf *xmit = &zport->port.info->xmit;
+	struct circ_buf *xmit = &zport->port.state->xmit;
 
 	/* XON/XOFF chars.  */
 	if (zport->port.x_char) {
@@ -686,7 +686,7 @@ static void zs_status_handle(struct zs_port *zport, struct zs_port *zport_a)
 			uport->icount.rng++;
 
 		if (delta)
-			wake_up_interruptible(&uport->info->delta_msr_wait);
+			wake_up_interruptible(&uport->state->port.delta_msr_wait);
 
 		spin_lock(&scc->zlock);
 	}
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 3dd231a..559b5fe 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -77,7 +77,7 @@ static unsigned long ack_handle[NR_IRQS];
 static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
 {
 	struct irq_chip *chip = get_irq_chip(irq);
-	return (void *)((char *)chip - offsetof(struct intc_desc_int, chip));
+	return container_of(chip, struct intc_desc_int, chip);
 }
 
 static inline unsigned int set_field(unsigned int value,
@@ -95,16 +95,19 @@ static inline unsigned int set_field(unsigned int value,
 static void write_8(unsigned long addr, unsigned long h, unsigned long data)
 {
 	__raw_writeb(set_field(0, data, h), addr);
+	(void)__raw_readb(addr);	/* Defeat write posting */
 }
 
 static void write_16(unsigned long addr, unsigned long h, unsigned long data)
 {
 	__raw_writew(set_field(0, data, h), addr);
+	(void)__raw_readw(addr);	/* Defeat write posting */
 }
 
 static void write_32(unsigned long addr, unsigned long h, unsigned long data)
 {
 	__raw_writel(set_field(0, data, h), addr);
+	(void)__raw_readl(addr);	/* Defeat write posting */
 }
 
 static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
@@ -112,6 +115,7 @@ static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
 	unsigned long flags;
 	local_irq_save(flags);
 	__raw_writeb(set_field(__raw_readb(addr), data, h), addr);
+	(void)__raw_readb(addr);	/* Defeat write posting */
 	local_irq_restore(flags);
 }
 
@@ -120,6 +124,7 @@ static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
 	unsigned long flags;
 	local_irq_save(flags);
 	__raw_writew(set_field(__raw_readw(addr), data, h), addr);
+	(void)__raw_readw(addr);	/* Defeat write posting */
 	local_irq_restore(flags);
 }
 
@@ -128,6 +133,7 @@ static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
 	unsigned long flags;
 	local_irq_save(flags);
 	__raw_writel(set_field(__raw_readl(addr), data, h), addr);
+	(void)__raw_readl(addr);	/* Defeat write posting */
 	local_irq_restore(flags);
 }
 
@@ -657,16 +663,9 @@ static unsigned int __init save_reg(struct intc_desc_int *d,
 	return 0;
 }
 
-static unsigned char *intc_evt2irq_table;
-
-unsigned int intc_evt2irq(unsigned int vector)
+static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
 {
-	unsigned int irq = evt2irq(vector);
-
-	if (intc_evt2irq_table && intc_evt2irq_table[irq])
-		irq = intc_evt2irq_table[irq];
-
-	return irq;
+	generic_handle_irq((unsigned int)get_irq_data(irq));
 }
 
 void __init register_intc_controller(struct intc_desc *desc)
@@ -739,50 +738,48 @@ void __init register_intc_controller(struct intc_desc *desc)
 
 	BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
 
-	/* keep the first vector only if same enum is used multiple times */
+	/* register the vectors one by one */
 	for (i = 0; i < desc->nr_vectors; i++) {
 		struct intc_vect *vect = desc->vectors + i;
-		int first_irq = evt2irq(vect->vect);
+		unsigned int irq = evt2irq(vect->vect);
+		struct irq_desc *irq_desc;
 
 		if (!vect->enum_id)
 			continue;
 
+		irq_desc = irq_to_desc_alloc_node(irq, numa_node_id());
+		if (unlikely(!irq_desc)) {
+			pr_info("can't get irq_desc for %d\n", irq);
+			continue;
+		}
+
+		intc_register_irq(desc, d, vect->enum_id, irq);
+
 		for (k = i + 1; k < desc->nr_vectors; k++) {
 			struct intc_vect *vect2 = desc->vectors + k;
+			unsigned int irq2 = evt2irq(vect2->vect);
 
 			if (vect->enum_id != vect2->enum_id)
 				continue;
 
-			vect2->enum_id = 0;
-
-			if (!intc_evt2irq_table)
-				intc_evt2irq_table = kzalloc(NR_IRQS, GFP_NOWAIT);
-
-			if (!intc_evt2irq_table) {
-				pr_warning("intc: cannot allocate evt2irq!\n");
+			/*
+			 * In the case of multi-evt handling and sparse
+			 * IRQ support, each vector still needs to have
+			 * its own backing irq_desc.
+			 */
+			irq_desc = irq_to_desc_alloc_node(irq2, numa_node_id());
+			if (unlikely(!irq_desc)) {
+				pr_info("can't get irq_desc for %d\n", irq2);
 				continue;
 			}
 
-			intc_evt2irq_table[evt2irq(vect2->vect)] = first_irq;
-		}
-	}
-
-	/* register the vectors one by one */
-	for (i = 0; i < desc->nr_vectors; i++) {
-		struct intc_vect *vect = desc->vectors + i;
-		unsigned int irq = evt2irq(vect->vect);
-		struct irq_desc *irq_desc;
-
-		if (!vect->enum_id)
-			continue;
+			vect2->enum_id = 0;
 
-		irq_desc = irq_to_desc_alloc_node(irq, numa_node_id());
-		if (unlikely(!irq_desc)) {
-			printk(KERN_INFO "can not get irq_desc for %d\n", irq);
-			continue;
+			/* redirect this interrupts to the first one */
+			set_irq_chip_and_handler_name(irq2, &d->chip,
+					intc_redirect_irq, "redirect");
+			set_irq_data(irq2, (void *)irq);
 		}
-
-		intc_register_irq(desc, d, vect->enum_id, irq);
 	}
 }
 
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index da76797..c0f950a 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -38,14 +38,12 @@
 #include <linux/interrupt.h>
 #include <linux/spi/spi.h>
 #include <linux/workqueue.h>
-#include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl022.h>
 #include <linux/io.h>
-#include <linux/delay.h>
 
 /*
  * This macro is used to define some register default values.
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
index 540a294..2d8cc45 100644
--- a/drivers/ssb/Kconfig
+++ b/drivers/ssb/Kconfig
@@ -66,6 +66,20 @@ config SSB_PCMCIAHOST
 
 	  If unsure, say N
 
+config SSB_SDIOHOST_POSSIBLE
+	bool
+	depends on SSB && (MMC = y || MMC = SSB)
+	default y
+
+config SSB_SDIOHOST
+	bool "Support for SSB on SDIO-bus host"
+	depends on SSB_SDIOHOST_POSSIBLE
+	help
+	  Support for a Sonics Silicon Backplane on top
+	  of a SDIO device.
+
+	  If unsure, say N
+
 config SSB_SILENT
 	bool "No SSB kernel messages"
 	depends on SSB && EMBEDDED
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
index cfbb74f..656e58b 100644
--- a/drivers/ssb/Makefile
+++ b/drivers/ssb/Makefile
@@ -6,6 +6,7 @@ ssb-$(CONFIG_SSB_SPROM)			+= sprom.o
 # host support
 ssb-$(CONFIG_SSB_PCIHOST)		+= pci.o pcihost_wrapper.o
 ssb-$(CONFIG_SSB_PCMCIAHOST)		+= pcmcia.o
+ssb-$(CONFIG_SSB_SDIOHOST)		+= sdio.o
 
 # built-in drivers
 ssb-y					+= driver_chipcommon.o
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 4aaddee..64abd11 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -28,6 +28,21 @@ static void ssb_chipco_pll_write(struct ssb_chipcommon *cc,
 	chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value);
 }
 
+static void ssb_chipco_regctl_maskset(struct ssb_chipcommon *cc,
+				   u32 offset, u32 mask, u32 set)
+{
+	u32 value;
+
+	chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
+	chipco_write32(cc, SSB_CHIPCO_REGCTL_ADDR, offset);
+	chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
+	value = chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
+	value &= mask;
+	value |= set;
+	chipco_write32(cc, SSB_CHIPCO_REGCTL_DATA, value);
+	chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
+}
+
 struct pmu0_plltab_entry {
 	u16 freq;	/* Crystal frequency in kHz.*/
 	u8 xf;		/* Crystal frequency value for PMU control */
@@ -506,3 +521,82 @@ void ssb_pmu_init(struct ssb_chipcommon *cc)
 	ssb_pmu_pll_init(cc);
 	ssb_pmu_resources_init(cc);
 }
+
+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
+			     enum ssb_pmu_ldo_volt_id id, u32 voltage)
+{
+	struct ssb_bus *bus = cc->dev->bus;
+	u32 addr, shift, mask;
+
+	switch (bus->chip_id) {
+	case 0x4328:
+	case 0x5354:
+		switch (id) {
+		case LDO_VOLT1:
+			addr = 2;
+			shift = 25;
+			mask = 0xF;
+			break;
+		case LDO_VOLT2:
+			addr = 3;
+			shift = 1;
+			mask = 0xF;
+			break;
+		case LDO_VOLT3:
+			addr = 3;
+			shift = 9;
+			mask = 0xF;
+			break;
+		case LDO_PAREF:
+			addr = 3;
+			shift = 17;
+			mask = 0x3F;
+			break;
+		default:
+			SSB_WARN_ON(1);
+			return;
+		}
+		break;
+	case 0x4312:
+		if (SSB_WARN_ON(id != LDO_PAREF))
+			return;
+		addr = 0;
+		shift = 21;
+		mask = 0x3F;
+		break;
+	default:
+		return;
+	}
+
+	ssb_chipco_regctl_maskset(cc, addr, ~(mask << shift),
+				  (voltage & mask) << shift);
+}
+
+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
+{
+	struct ssb_bus *bus = cc->dev->bus;
+	int ldo;
+
+	switch (bus->chip_id) {
+	case 0x4312:
+		ldo = SSB_PMURES_4312_PA_REF_LDO;
+		break;
+	case 0x4328:
+		ldo = SSB_PMURES_4328_PA_REF_LDO;
+		break;
+	case 0x5354:
+		ldo = SSB_PMURES_5354_PA_REF_LDO;
+		break;
+	default:
+		return;
+	}
+
+	if (on)
+		chipco_set32(cc, SSB_CHIPCO_PMU_MINRES_MSK, 1 << ldo);
+	else
+		chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK, ~(1 << ldo));
+	chipco_read32(cc, SSB_CHIPCO_PMU_MINRES_MSK); //SPEC FIXME found via mmiotrace - dummy read?
+}
+
+EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
+EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 65a1ed9..579b114 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -17,6 +17,7 @@
 #include <linux/ssb/ssb_driver_gige.h>
 #include <linux/dma-mapping.h>
 #include <linux/pci.h>
+#include <linux/mmc/sdio_func.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -88,6 +89,25 @@ found:
 }
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
+#ifdef CONFIG_SSB_SDIOHOST
+struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
+{
+	struct ssb_bus *bus;
+
+	ssb_buses_lock();
+	list_for_each_entry(bus, &buses, list) {
+		if (bus->bustype == SSB_BUSTYPE_SDIO &&
+		    bus->host_sdio == func)
+			goto found;
+	}
+	bus = NULL;
+found:
+	ssb_buses_unlock();
+
+	return bus;
+}
+#endif /* CONFIG_SSB_SDIOHOST */
+
 int ssb_for_each_bus_call(unsigned long data,
 			  int (*func)(struct ssb_bus *bus, unsigned long data))
 {
@@ -469,6 +489,12 @@ static int ssb_devices_register(struct ssb_bus *bus)
 			dev->parent = &bus->host_pcmcia->dev;
 #endif
 			break;
+		case SSB_BUSTYPE_SDIO:
+#ifdef CONFIG_SSB_SDIO
+			sdev->irq = bus->host_sdio->dev.irq;
+			dev->parent = &bus->host_sdio->dev;
+#endif
+			break;
 		case SSB_BUSTYPE_SSB:
 			dev->dma_mask = &dev->coherent_dma_mask;
 			break;
@@ -724,12 +750,18 @@ static int ssb_bus_register(struct ssb_bus *bus,
 	err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
 	if (err)
 		goto out;
+
+	/* Init SDIO-host device (if any), before the scan */
+	err = ssb_sdio_init(bus);
+	if (err)
+		goto err_disable_xtal;
+
 	ssb_buses_lock();
 	bus->busnumber = next_busnumber;
 	/* Scan for devices (cores) */
 	err = ssb_bus_scan(bus, baseaddr);
 	if (err)
-		goto err_disable_xtal;
+		goto err_sdio_exit;
 
 	/* Init PCI-host device (if any) */
 	err = ssb_pci_init(bus);
@@ -776,6 +808,8 @@ err_pci_exit:
 	ssb_pci_exit(bus);
 err_unmap:
 	ssb_iounmap(bus);
+err_sdio_exit:
+	ssb_sdio_exit(bus);
 err_disable_xtal:
 	ssb_buses_unlock();
 	ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
@@ -825,6 +859,28 @@ int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
 EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
+#ifdef CONFIG_SSB_SDIOHOST
+int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
+			     unsigned int quirks)
+{
+	int err;
+
+	bus->bustype = SSB_BUSTYPE_SDIO;
+	bus->host_sdio = func;
+	bus->ops = &ssb_sdio_ops;
+	bus->quirks = quirks;
+
+	err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0);
+	if (!err) {
+		ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
+			   "SDIO device %s\n", sdio_func_id(func));
+	}
+
+	return err;
+}
+EXPORT_SYMBOL(ssb_bus_sdiobus_register);
+#endif /* CONFIG_SSB_PCMCIAHOST */
+
 int ssb_bus_ssbbus_register(struct ssb_bus *bus,
 			    unsigned long baseaddr,
 			    ssb_invariants_func_t get_invariants)
@@ -1358,8 +1414,10 @@ static int __init ssb_modinit(void)
 	ssb_buses_lock();
 	err = ssb_attach_queued_buses();
 	ssb_buses_unlock();
-	if (err)
+	if (err) {
 		bus_unregister(&ssb_bustype);
+		goto out;
+	}
 
 	err = b43_pci_ssb_bridge_init();
 	if (err) {
@@ -1375,7 +1433,7 @@ static int __init ssb_modinit(void)
 		/* don't fail SSB init because of this */
 		err = 0;
 	}
-
+out:
 	return err;
 }
 /* ssb must be initialized after PCI but before the ssb drivers.
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 40ea417..9e50896 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -169,8 +169,14 @@ err_pci:
 /* Get the word-offset for a SSB_SPROM_XXX define. */
 #define SPOFF(offset)	(((offset) - SSB_SPROM_BASE) / sizeof(u16))
 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
-#define SPEX(_outvar, _offset, _mask, _shift)	\
+#define SPEX16(_outvar, _offset, _mask, _shift)	\
 	out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
+#define SPEX32(_outvar, _offset, _mask, _shift)	\
+	out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
+			   in[SPOFF(_offset)]) & (_mask)) >> (_shift))
+#define SPEX(_outvar, _offset, _mask, _shift) \
+	SPEX16(_outvar, _offset, _mask, _shift)
+
 
 static inline u8 ssb_crc8(u8 crc, u8 data)
 {
@@ -474,12 +480,14 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
 
 	/* extract the MAC address */
 	for (i = 0; i < 3; i++) {
-		v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
+		v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
 		*(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
 	}
 	SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
 	SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
 	SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
+	SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
+	SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
 	SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
 	     SSB_SPROM8_ANTAVAIL_A_SHIFT);
 	SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
@@ -490,12 +498,55 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
 	SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
 	SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
 	     SSB_SPROM8_ITSSI_A_SHIFT);
+	SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
+	SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
+	     SSB_SPROM8_MAXP_AL_SHIFT);
 	SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
 	SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
 	     SSB_SPROM8_GPIOA_P1_SHIFT);
 	SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
 	SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
 	     SSB_SPROM8_GPIOB_P3_SHIFT);
+	SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
+	SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
+	     SSB_SPROM8_TRI5G_SHIFT);
+	SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
+	SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
+	     SSB_SPROM8_TRI5GH_SHIFT);
+	SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
+	SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
+	     SSB_SPROM8_RXPO5G_SHIFT);
+	SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
+	SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
+	     SSB_SPROM8_RSSISMC2G_SHIFT);
+	SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
+	     SSB_SPROM8_RSSISAV2G_SHIFT);
+	SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
+	     SSB_SPROM8_BXA2G_SHIFT);
+	SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
+	SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
+	     SSB_SPROM8_RSSISMC5G_SHIFT);
+	SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
+	     SSB_SPROM8_RSSISAV5G_SHIFT);
+	SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
+	     SSB_SPROM8_BXA5G_SHIFT);
+	SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
+	SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
+	SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
+	SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
+	SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
+	SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
+	SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
+	SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
+	SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
+	SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
+	SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
+	SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
+	SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
+	SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
+	SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
+	SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
+	SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
 
 	/* Extract the antenna gain values. */
 	SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
@@ -549,6 +600,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
 			ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
 				   "  revision %d detected. Will extract"
 				   " v1\n", out->revision);
+			out->revision = 1;
 			sprom_extract_r123(out, in);
 		}
 	}
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index 63ee5cf..b74212d 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -175,6 +175,9 @@ static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
 		} else
 			ssb_pcmcia_switch_segment(bus, 0);
 		break;
+	case SSB_BUSTYPE_SDIO:
+		offset += current_coreidx * SSB_CORE_SIZE;
+		return ssb_sdio_scan_read32(bus, offset);
 	}
 	return readl(bus->mmio + offset);
 }
@@ -188,6 +191,8 @@ static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
 		return ssb_pci_switch_coreidx(bus, coreidx);
 	case SSB_BUSTYPE_PCMCIA:
 		return ssb_pcmcia_switch_coreidx(bus, coreidx);
+	case SSB_BUSTYPE_SDIO:
+		return ssb_sdio_scan_switch_coreidx(bus, coreidx);
 	}
 	return 0;
 }
@@ -206,6 +211,8 @@ void ssb_iounmap(struct ssb_bus *bus)
 		SSB_BUG_ON(1); /* Can't reach this code. */
 #endif
 		break;
+	case SSB_BUSTYPE_SDIO:
+		break;
 	}
 	bus->mmio = NULL;
 	bus->mapped_device = NULL;
@@ -230,6 +237,10 @@ static void __iomem *ssb_ioremap(struct ssb_bus *bus,
 		SSB_BUG_ON(1); /* Can't reach this code. */
 #endif
 		break;
+	case SSB_BUSTYPE_SDIO:
+		/* Nothing to ioremap in the SDIO case, just fake it */
+		mmio = (void __iomem *)baseaddr;
+		break;
 	}
 
 	return mmio;
diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c
new file mode 100644
index 0000000..65a6080
--- /dev/null
+++ b/drivers/ssb/sdio.c
@@ -0,0 +1,610 @@
+/*
+ * Sonics Silicon Backplane
+ * SDIO-Hostbus related functions
+ *
+ * Copyright 2009 Albert Herranz <albert_herranz@yahoo.es>
+ *
+ * Based on drivers/ssb/pcmcia.c
+ * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ *
+ */
+
+#include <linux/ssb/ssb.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/etherdevice.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "ssb_private.h"
+
+/* Define the following to 1 to enable a printk on each coreswitch. */
+#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG		0
+
+
+/* Hardware invariants CIS tuples */
+#define SSB_SDIO_CIS			0x80
+#define  SSB_SDIO_CIS_SROMREV		0x00
+#define  SSB_SDIO_CIS_ID		0x01
+#define  SSB_SDIO_CIS_BOARDREV		0x02
+#define  SSB_SDIO_CIS_PA		0x03
+#define   SSB_SDIO_CIS_PA_PA0B0_LO	0
+#define   SSB_SDIO_CIS_PA_PA0B0_HI	1
+#define   SSB_SDIO_CIS_PA_PA0B1_LO	2
+#define   SSB_SDIO_CIS_PA_PA0B1_HI	3
+#define   SSB_SDIO_CIS_PA_PA0B2_LO	4
+#define   SSB_SDIO_CIS_PA_PA0B2_HI	5
+#define   SSB_SDIO_CIS_PA_ITSSI		6
+#define   SSB_SDIO_CIS_PA_MAXPOW	7
+#define  SSB_SDIO_CIS_OEMNAME		0x04
+#define  SSB_SDIO_CIS_CCODE		0x05
+#define  SSB_SDIO_CIS_ANTENNA		0x06
+#define  SSB_SDIO_CIS_ANTGAIN		0x07
+#define  SSB_SDIO_CIS_BFLAGS		0x08
+#define  SSB_SDIO_CIS_LEDS		0x09
+
+#define CISTPL_FUNCE_LAN_NODE_ID        0x04	/* same as in PCMCIA */
+
+
+/*
+ * Function 1 miscellaneous registers.
+ *
+ * Definitions match src/include/sbsdio.h from the
+ * Android Open Source Project
+ * http://android.git.kernel.org/?p=platform/system/wlan/broadcom.git
+ *
+ */
+#define SBSDIO_FUNC1_SBADDRLOW	0x1000a	/* SB Address window Low (b15) */
+#define SBSDIO_FUNC1_SBADDRMID	0x1000b	/* SB Address window Mid (b23-b16) */
+#define SBSDIO_FUNC1_SBADDRHIGH	0x1000c	/* SB Address window High (b24-b31) */
+
+/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
+#define SBSDIO_SBADDRLOW_MASK	0x80	/* Valid address bits in SBADDRLOW */
+#define SBSDIO_SBADDRMID_MASK	0xff	/* Valid address bits in SBADDRMID */
+#define SBSDIO_SBADDRHIGH_MASK	0xff	/* Valid address bits in SBADDRHIGH */
+
+#define SBSDIO_SB_OFT_ADDR_MASK	0x7FFF	/* sb offset addr is <= 15 bits, 32k */
+
+/* REVISIT: this flag doesn't seem to matter */
+#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x8000	/* forces 32-bit SB access */
+
+
+/*
+ * Address map within the SDIO function address space (128K).
+ *
+ *   Start   End     Description
+ *   ------- ------- ------------------------------------------
+ *   0x00000 0x0ffff selected backplane address window (64K)
+ *   0x10000 0x1ffff backplane control registers (max 64K)
+ *
+ * The current address window is configured by writing to registers
+ * SBADDRLOW, SBADDRMID and SBADDRHIGH.
+ *
+ * In order to access the contents of a 32-bit Silicon Backplane address
+ * the backplane address window must be first loaded with the highest
+ * 16 bits of the target address. Then, an access must be done to the
+ * SDIO function address space using the lower 15 bits of the address.
+ * Bit 15 of the address must be set when doing 32 bit accesses.
+ *
+ * 10987654321098765432109876543210
+ * WWWWWWWWWWWWWWWWW                 SB Address Window
+ *                 OOOOOOOOOOOOOOOO  Offset within SB Address Window
+ *                 a                 32-bit access flag
+ */
+
+
+/*
+ * SSB I/O via SDIO.
+ *
+ * NOTE: SDIO address @addr is 17 bits long (SDIO address space is 128K).
+ */
+
+static inline struct device *ssb_sdio_dev(struct ssb_bus *bus)
+{
+	return &bus->host_sdio->dev;
+}
+
+/* host claimed */
+static int ssb_sdio_writeb(struct ssb_bus *bus, unsigned int addr, u8 val)
+{
+	int error = 0;
+
+	sdio_writeb(bus->host_sdio, val, addr, &error);
+	if (unlikely(error)) {
+		dev_dbg(ssb_sdio_dev(bus), "%08X <- %02x, error %d\n",
+			addr, val, error);
+	}
+
+	return error;
+}
+
+#if 0
+static u8 ssb_sdio_readb(struct ssb_bus *bus, unsigned int addr)
+{
+	u8 val;
+	int error = 0;
+
+	val = sdio_readb(bus->host_sdio, addr, &error);
+	if (unlikely(error)) {
+		dev_dbg(ssb_sdio_dev(bus), "%08X -> %02x, error %d\n",
+			addr, val, error);
+	}
+
+	return val;
+}
+#endif
+
+/* host claimed */
+static int ssb_sdio_set_sbaddr_window(struct ssb_bus *bus, u32 address)
+{
+	int error;
+
+	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRLOW,
+				(address >> 8) & SBSDIO_SBADDRLOW_MASK);
+	if (error)
+		goto out;
+	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRMID,
+				(address >> 16) & SBSDIO_SBADDRMID_MASK);
+	if (error)
+		goto out;
+	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRHIGH,
+				(address >> 24) & SBSDIO_SBADDRHIGH_MASK);
+	if (error)
+		goto out;
+	bus->sdio_sbaddr = address;
+out:
+	if (error) {
+		dev_dbg(ssb_sdio_dev(bus), "failed to set address window"
+			" to 0x%08x, error %d\n", address, error);
+	}
+
+	return error;
+}
+
+/* for enumeration use only */
+u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
+{
+	u32 val;
+	int error;
+
+	sdio_claim_host(bus->host_sdio);
+	val = sdio_readl(bus->host_sdio, offset, &error);
+	sdio_release_host(bus->host_sdio);
+	if (unlikely(error)) {
+		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
+			bus->sdio_sbaddr >> 16, offset, val, error);
+	}
+
+	return val;
+}
+
+/* for enumeration use only */
+int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
+{
+	u32 sbaddr;
+	int error;
+
+	sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
+	sdio_claim_host(bus->host_sdio);
+	error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
+	sdio_release_host(bus->host_sdio);
+	if (error) {
+		dev_err(ssb_sdio_dev(bus), "failed to switch to core %u,"
+			" error %d\n", coreidx, error);
+		goto out;
+	}
+out:
+	return error;
+}
+
+/* host must be already claimed */
+int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
+{
+	u8 coreidx = dev->core_index;
+	u32 sbaddr;
+	int error = 0;
+
+	sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
+	if (unlikely(bus->sdio_sbaddr != sbaddr)) {
+#if SSB_VERBOSE_SDIOCORESWITCH_DEBUG
+		dev_info(ssb_sdio_dev(bus),
+			   "switching to %s core, index %d\n",
+			   ssb_core_name(dev->id.coreid), coreidx);
+#endif
+		error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
+		if (error) {
+			dev_dbg(ssb_sdio_dev(bus), "failed to switch to"
+				" core %u, error %d\n", coreidx, error);
+			goto out;
+		}
+		bus->mapped_device = dev;
+	}
+
+out:
+	return error;
+}
+
+static u8 ssb_sdio_read8(struct ssb_device *dev, u16 offset)
+{
+	struct ssb_bus *bus = dev->bus;
+	u8 val = 0xff;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev)))
+		goto out;
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+	val = sdio_readb(bus->host_sdio, offset, &error);
+	if (error) {
+		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %02x, error %d\n",
+			bus->sdio_sbaddr >> 16, offset, val, error);
+	}
+out:
+	sdio_release_host(bus->host_sdio);
+
+	return val;
+}
+
+static u16 ssb_sdio_read16(struct ssb_device *dev, u16 offset)
+{
+	struct ssb_bus *bus = dev->bus;
+	u16 val = 0xffff;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev)))
+		goto out;
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+	val = sdio_readw(bus->host_sdio, offset, &error);
+	if (error) {
+		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %04x, error %d\n",
+			bus->sdio_sbaddr >> 16, offset, val, error);
+	}
+out:
+	sdio_release_host(bus->host_sdio);
+
+	return val;
+}
+
+static u32 ssb_sdio_read32(struct ssb_device *dev, u16 offset)
+{
+	struct ssb_bus *bus = dev->bus;
+	u32 val = 0xffffffff;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev)))
+		goto out;
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+	offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
+	val = sdio_readl(bus->host_sdio, offset, &error);
+	if (error) {
+		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
+			bus->sdio_sbaddr >> 16, offset, val, error);
+	}
+out:
+	sdio_release_host(bus->host_sdio);
+
+	return val;
+}
+
+#ifdef CONFIG_SSB_BLOCKIO
+static void ssb_sdio_block_read(struct ssb_device *dev, void *buffer,
+				  size_t count, u16 offset, u8 reg_width)
+{
+	size_t saved_count = count;
+	struct ssb_bus *bus = dev->bus;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev))) {
+		error = -EIO;
+		memset(buffer, 0xff, count);
+		goto err_out;
+	}
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+
+	switch (reg_width) {
+	case sizeof(u8): {
+		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
+		break;
+	}
+	case sizeof(u16): {
+		SSB_WARN_ON(count & 1);
+		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
+		break;
+	}
+	case sizeof(u32): {
+		SSB_WARN_ON(count & 3);
+		offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
+		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
+		break;
+	}
+	default:
+		SSB_WARN_ON(1);
+	}
+	if (!error)
+		goto out;
+
+err_out:
+	dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
+		bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
+out:
+	sdio_release_host(bus->host_sdio);
+}
+#endif /* CONFIG_SSB_BLOCKIO */
+
+static void ssb_sdio_write8(struct ssb_device *dev, u16 offset, u8 val)
+{
+	struct ssb_bus *bus = dev->bus;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev)))
+		goto out;
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+	sdio_writeb(bus->host_sdio, val, offset, &error);
+	if (error) {
+		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %02x, error %d\n",
+			bus->sdio_sbaddr >> 16, offset, val, error);
+	}
+out:
+	sdio_release_host(bus->host_sdio);
+}
+
+static void ssb_sdio_write16(struct ssb_device *dev, u16 offset, u16 val)
+{
+	struct ssb_bus *bus = dev->bus;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev)))
+		goto out;
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+	sdio_writew(bus->host_sdio, val, offset, &error);
+	if (error) {
+		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %04x, error %d\n",
+			bus->sdio_sbaddr >> 16, offset, val, error);
+	}
+out:
+	sdio_release_host(bus->host_sdio);
+}
+
+static void ssb_sdio_write32(struct ssb_device *dev, u16 offset, u32 val)
+{
+	struct ssb_bus *bus = dev->bus;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev)))
+		goto out;
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+	offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
+	sdio_writel(bus->host_sdio, val, offset, &error);
+	if (error) {
+		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %08x, error %d\n",
+			bus->sdio_sbaddr >> 16, offset, val, error);
+	}
+	if (bus->quirks & SSB_QUIRK_SDIO_READ_AFTER_WRITE32)
+		sdio_readl(bus->host_sdio, 0, &error);
+out:
+	sdio_release_host(bus->host_sdio);
+}
+
+#ifdef CONFIG_SSB_BLOCKIO
+static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer,
+				   size_t count, u16 offset, u8 reg_width)
+{
+	size_t saved_count = count;
+	struct ssb_bus *bus = dev->bus;
+	int error = 0;
+
+	sdio_claim_host(bus->host_sdio);
+	if (unlikely(ssb_sdio_switch_core(bus, dev))) {
+		error = -EIO;
+		memset((void *)buffer, 0xff, count);
+		goto err_out;
+	}
+	offset |= bus->sdio_sbaddr & 0xffff;
+	offset &= SBSDIO_SB_OFT_ADDR_MASK;
+
+	switch (reg_width) {
+	case sizeof(u8):
+		error = sdio_writesb(bus->host_sdio, offset,
+				     (void *)buffer, count);
+		break;
+	case sizeof(u16):
+		SSB_WARN_ON(count & 1);
+		error = sdio_writesb(bus->host_sdio, offset,
+				     (void *)buffer, count);
+		break;
+	case sizeof(u32):
+		SSB_WARN_ON(count & 3);
+		offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
+		error = sdio_writesb(bus->host_sdio, offset,
+				     (void *)buffer, count);
+		break;
+	default:
+		SSB_WARN_ON(1);
+	}
+	if (!error)
+		goto out;
+
+err_out:
+	dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
+		bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
+out:
+	sdio_release_host(bus->host_sdio);
+}
+
+#endif /* CONFIG_SSB_BLOCKIO */
+
+/* Not "static", as it's used in main.c */
+const struct ssb_bus_ops ssb_sdio_ops = {
+	.read8		= ssb_sdio_read8,
+	.read16		= ssb_sdio_read16,
+	.read32		= ssb_sdio_read32,
+	.write8		= ssb_sdio_write8,
+	.write16	= ssb_sdio_write16,
+	.write32	= ssb_sdio_write32,
+#ifdef CONFIG_SSB_BLOCKIO
+	.block_read	= ssb_sdio_block_read,
+	.block_write	= ssb_sdio_block_write,
+#endif
+};
+
+#define GOTO_ERROR_ON(condition, description) do {	\
+	if (unlikely(condition)) {			\
+		error_description = description;	\
+		goto error;				\
+	}						\
+  } while (0)
+
+int ssb_sdio_get_invariants(struct ssb_bus *bus,
+			    struct ssb_init_invariants *iv)
+{
+	struct ssb_sprom *sprom = &iv->sprom;
+	struct ssb_boardinfo *bi = &iv->boardinfo;
+	const char *error_description = "none";
+	struct sdio_func_tuple *tuple;
+	void *mac;
+
+	memset(sprom, 0xFF, sizeof(*sprom));
+	sprom->boardflags_lo = 0;
+	sprom->boardflags_hi = 0;
+
+	tuple = bus->host_sdio->tuples;
+	while (tuple) {
+		switch (tuple->code) {
+		case 0x22: /* extended function */
+			switch (tuple->data[0]) {
+			case CISTPL_FUNCE_LAN_NODE_ID:
+				GOTO_ERROR_ON((tuple->size != 7) &&
+					      (tuple->data[1] != 6),
+					      "mac tpl size");
+				/* fetch the MAC address. */
+				mac = tuple->data + 2;
+				memcpy(sprom->il0mac, mac, ETH_ALEN);
+				memcpy(sprom->et1mac, mac, ETH_ALEN);
+				break;
+			default:
+				break;
+			}
+			break;
+		case 0x80: /* vendor specific tuple */
+			switch (tuple->data[0]) {
+			case SSB_SDIO_CIS_SROMREV:
+				GOTO_ERROR_ON(tuple->size != 2,
+					      "sromrev tpl size");
+				sprom->revision = tuple->data[1];
+				break;
+			case SSB_SDIO_CIS_ID:
+				GOTO_ERROR_ON((tuple->size != 5) &&
+					      (tuple->size != 7),
+					      "id tpl size");
+				bi->vendor = tuple->data[1] |
+					     (tuple->data[2]<<8);
+				break;
+			case SSB_SDIO_CIS_BOARDREV:
+				GOTO_ERROR_ON(tuple->size != 2,
+					      "boardrev tpl size");
+				sprom->board_rev = tuple->data[1];
+				break;
+			case SSB_SDIO_CIS_PA:
+				GOTO_ERROR_ON((tuple->size != 9) &&
+					      (tuple->size != 10),
+					      "pa tpl size");
+				sprom->pa0b0 = tuple->data[1] |
+					 ((u16)tuple->data[2] << 8);
+				sprom->pa0b1 = tuple->data[3] |
+					 ((u16)tuple->data[4] << 8);
+				sprom->pa0b2 = tuple->data[5] |
+					 ((u16)tuple->data[6] << 8);
+				sprom->itssi_a = tuple->data[7];
+				sprom->itssi_bg = tuple->data[7];
+				sprom->maxpwr_a = tuple->data[8];
+				sprom->maxpwr_bg = tuple->data[8];
+				break;
+			case SSB_SDIO_CIS_OEMNAME:
+				/* Not present */
+				break;
+			case SSB_SDIO_CIS_CCODE:
+				GOTO_ERROR_ON(tuple->size != 2,
+					      "ccode tpl size");
+				sprom->country_code = tuple->data[1];
+				break;
+			case SSB_SDIO_CIS_ANTENNA:
+				GOTO_ERROR_ON(tuple->size != 2,
+					      "ant tpl size");
+				sprom->ant_available_a = tuple->data[1];
+				sprom->ant_available_bg = tuple->data[1];
+				break;
+			case SSB_SDIO_CIS_ANTGAIN:
+				GOTO_ERROR_ON(tuple->size != 2,
+					      "antg tpl size");
+				sprom->antenna_gain.ghz24.a0 = tuple->data[1];
+				sprom->antenna_gain.ghz24.a1 = tuple->data[1];
+				sprom->antenna_gain.ghz24.a2 = tuple->data[1];
+				sprom->antenna_gain.ghz24.a3 = tuple->data[1];
+				sprom->antenna_gain.ghz5.a0 = tuple->data[1];
+				sprom->antenna_gain.ghz5.a1 = tuple->data[1];
+				sprom->antenna_gain.ghz5.a2 = tuple->data[1];
+				sprom->antenna_gain.ghz5.a3 = tuple->data[1];
+				break;
+			case SSB_SDIO_CIS_BFLAGS:
+				GOTO_ERROR_ON((tuple->size != 3) &&
+					      (tuple->size != 5),
+					      "bfl tpl size");
+				sprom->boardflags_lo = tuple->data[1] |
+						 ((u16)tuple->data[2] << 8);
+				break;
+			case SSB_SDIO_CIS_LEDS:
+				GOTO_ERROR_ON(tuple->size != 5,
+					      "leds tpl size");
+				sprom->gpio0 = tuple->data[1];
+				sprom->gpio1 = tuple->data[2];
+				sprom->gpio2 = tuple->data[3];
+				sprom->gpio3 = tuple->data[4];
+				break;
+			default:
+				break;
+			}
+			break;
+		default:
+			break;
+		}
+		tuple = tuple->next;
+	}
+
+	return 0;
+error:
+	dev_err(ssb_sdio_dev(bus), "failed to fetch device invariants: %s\n",
+		error_description);
+	return -ENODEV;
+}
+
+void ssb_sdio_exit(struct ssb_bus *bus)
+{
+	if (bus->bustype != SSB_BUSTYPE_SDIO)
+		return;
+	/* Nothing to do here. */
+}
+
+int ssb_sdio_init(struct ssb_bus *bus)
+{
+	if (bus->bustype != SSB_BUSTYPE_SDIO)
+		return 0;
+
+	bus->sdio_sbaddr = ~0;
+
+	return 0;
+}
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index 57fa482..2543356 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -114,6 +114,46 @@ static inline int ssb_pcmcia_init(struct ssb_bus *bus)
 }
 #endif /* CONFIG_SSB_PCMCIAHOST */
 
+/* sdio.c */
+#ifdef CONFIG_SSB_SDIOHOST
+extern int ssb_sdio_get_invariants(struct ssb_bus *bus,
+				     struct ssb_init_invariants *iv);
+
+extern u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset);
+extern int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev);
+extern int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx);
+extern int ssb_sdio_hardware_setup(struct ssb_bus *bus);
+extern void ssb_sdio_exit(struct ssb_bus *bus);
+extern int ssb_sdio_init(struct ssb_bus *bus);
+
+extern const struct ssb_bus_ops ssb_sdio_ops;
+#else /* CONFIG_SSB_SDIOHOST */
+static inline u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
+{
+	return 0;
+}
+static inline int ssb_sdio_switch_core(struct ssb_bus *bus,
+					 struct ssb_device *dev)
+{
+	return 0;
+}
+static inline int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
+{
+	return 0;
+}
+static inline int ssb_sdio_hardware_setup(struct ssb_bus *bus)
+{
+	return 0;
+}
+static inline void ssb_sdio_exit(struct ssb_bus *bus)
+{
+}
+static inline int ssb_sdio_init(struct ssb_bus *bus)
+{
+	return 0;
+}
+#endif /* CONFIG_SSB_SDIOHOST */
+
 
 /* scan.c */
 extern const char *ssb_core_name(u16 coreid);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 975ecdd..82b3489 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -45,14 +45,10 @@ source "drivers/staging/et131x/Kconfig"
 
 source "drivers/staging/slicoss/Kconfig"
 
-source "drivers/staging/sxg/Kconfig"
-
-source "drivers/staging/me4000/Kconfig"
-
-source "drivers/staging/meilhaus/Kconfig"
-
 source "drivers/staging/go7007/Kconfig"
 
+source "drivers/staging/cx25821/Kconfig"
+
 source "drivers/staging/usbip/Kconfig"
 
 source "drivers/staging/winbond/Kconfig"
@@ -61,8 +57,6 @@ source "drivers/staging/wlan-ng/Kconfig"
 
 source "drivers/staging/echo/Kconfig"
 
-source "drivers/staging/at76_usb/Kconfig"
-
 source "drivers/staging/poch/Kconfig"
 
 source "drivers/staging/agnx/Kconfig"
@@ -73,7 +67,7 @@ source "drivers/staging/rt2860/Kconfig"
 
 source "drivers/staging/rt2870/Kconfig"
 
-source "drivers/staging/rt3070/Kconfig"
+source "drivers/staging/rt3090/Kconfig"
 
 source "drivers/staging/comedi/Kconfig"
 
@@ -87,16 +81,16 @@ source "drivers/staging/rtl8187se/Kconfig"
 
 source "drivers/staging/rtl8192su/Kconfig"
 
-source "drivers/staging/rspiusb/Kconfig"
+source "drivers/staging/rtl8192e/Kconfig"
 
 source "drivers/staging/mimio/Kconfig"
 
 source "drivers/staging/frontier/Kconfig"
 
-source "drivers/staging/epl/Kconfig"
-
 source "drivers/staging/android/Kconfig"
 
+source "drivers/staging/dream/Kconfig"
+
 source "drivers/staging/dst/Kconfig"
 
 source "drivers/staging/pohmelfs/Kconfig"
@@ -109,8 +103,6 @@ source "drivers/staging/phison/Kconfig"
 
 source "drivers/staging/p9auth/Kconfig"
 
-source "drivers/staging/heci/Kconfig"
-
 source "drivers/staging/line6/Kconfig"
 
 source "drivers/gpu/drm/radeon/Kconfig"
@@ -119,13 +111,27 @@ source "drivers/staging/octeon/Kconfig"
 
 source "drivers/staging/serqt_usb2/Kconfig"
 
+source "drivers/staging/quatech_usb2/Kconfig"
+
 source "drivers/staging/vt6655/Kconfig"
 
-source "drivers/staging/cpc-usb/Kconfig"
+source "drivers/staging/vt6656/Kconfig"
 
-source "drivers/staging/pata_rdc/Kconfig"
+source "drivers/staging/cpc-usb/Kconfig"
 
 source "drivers/staging/udlfb/Kconfig"
 
+source "drivers/staging/hv/Kconfig"
+
+source "drivers/staging/vme/Kconfig"
+
+source "drivers/staging/rar/Kconfig"
+
+source "drivers/staging/sep/Kconfig"
+
+source "drivers/staging/iio/Kconfig"
+
+source "drivers/staging/cowloop/Kconfig"
+
 endif # !STAGING_EXCLUDE_BUILD
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 2241ae1..b1cad0d 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -5,43 +5,46 @@ obj-$(CONFIG_STAGING)		+= staging.o
 
 obj-$(CONFIG_ET131X)		+= et131x/
 obj-$(CONFIG_SLICOSS)		+= slicoss/
-obj-$(CONFIG_SXG)		+= sxg/
-obj-$(CONFIG_ME4000)		+= me4000/
-obj-$(CONFIG_MEILHAUS)		+= meilhaus/
 obj-$(CONFIG_VIDEO_GO7007)	+= go7007/
+obj-$(CONFIG_VIDEO_CX25821)	+= cx25821/
 obj-$(CONFIG_USB_IP_COMMON)	+= usbip/
 obj-$(CONFIG_W35UND)		+= winbond/
 obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
 obj-$(CONFIG_ECHO)		+= echo/
-obj-$(CONFIG_USB_ATMEL)		+= at76_usb/
 obj-$(CONFIG_POCH)		+= poch/
 obj-$(CONFIG_AGNX)		+= agnx/
 obj-$(CONFIG_OTUS)		+= otus/
 obj-$(CONFIG_RT2860)		+= rt2860/
 obj-$(CONFIG_RT2870)		+= rt2870/
-obj-$(CONFIG_RT3070)		+= rt3070/
+obj-$(CONFIG_RT3090)		+= rt3090/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_ASUS_OLED)		+= asus_oled/
 obj-$(CONFIG_PANEL)		+= panel/
 obj-$(CONFIG_ALTERA_PCIE_CHDMA)	+= altpciechdma/
 obj-$(CONFIG_RTL8187SE)		+= rtl8187se/
 obj-$(CONFIG_RTL8192SU)		+= rtl8192su/
-obj-$(CONFIG_USB_RSPI)		+= rspiusb/
+obj-$(CONFIG_RTL8192E)		+= rtl8192e/
 obj-$(CONFIG_INPUT_MIMIO)	+= mimio/
 obj-$(CONFIG_TRANZPORT)		+= frontier/
-obj-$(CONFIG_EPL)		+= epl/
 obj-$(CONFIG_ANDROID)		+= android/
+obj-$(CONFIG_ANDROID)		+= dream/
 obj-$(CONFIG_DST)		+= dst/
 obj-$(CONFIG_POHMELFS)		+= pohmelfs/
 obj-$(CONFIG_STLC45XX)		+= stlc45xx/
 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_QUATECH2)	+= serqt_usb2/
+obj-$(CONFIG_USB_SERIAL_QUATECH_USB2)	+= quatech_usb2/
 obj-$(CONFIG_OCTEON_ETHERNET)	+= octeon/
 obj-$(CONFIG_VT6655)		+= vt6655/
+obj-$(CONFIG_VT6656)		+= vt6656/
 obj-$(CONFIG_USB_CPC)		+= cpc-usb/
-obj-$(CONFIG_RDC_17F3101X)	+= pata_rdc/
 obj-$(CONFIG_FB_UDL)		+= udlfb/
+obj-$(CONFIG_HYPERV)		+= hv/
+obj-$(CONFIG_VME_BUS)		+= vme/
+obj-$(CONFIG_RAR_REGISTER)	+= rar/
+obj-$(CONFIG_DX_SEP)		+= sep/
+obj-$(CONFIG_IIO)		+= iio/
+obj-$(CONFIG_COWLOOP)		+= cowloop/
diff --git a/drivers/staging/agnx/pci.c b/drivers/staging/agnx/pci.c
index 1fe9870..32b5489 100644
--- a/drivers/staging/agnx/pci.c
+++ b/drivers/staging/agnx/pci.c
@@ -280,7 +280,7 @@ static void agnx_stop(struct ieee80211_hw *dev)
 	/* make sure hardware will not generate irq */
 	agnx_hw_reset(priv);
 	free_irq(priv->pdev->irq, dev);
-	flush_workqueue(priv->hw->workqueue);
+/*	flush_workqueue(priv->hw->workqueue); */
 /*	cancel_delayed_work_sync(&priv->periodic_work); */
 	unfill_rings(priv);
 	rings_free(priv);
diff --git a/drivers/staging/agnx/xmit.c b/drivers/staging/agnx/xmit.c
index 0e03408..42db410 100644
--- a/drivers/staging/agnx/xmit.c
+++ b/drivers/staging/agnx/xmit.c
@@ -384,7 +384,8 @@ void handle_rx_irq(struct agnx_priv *priv)
 /*			dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
 		} else
 			agnx_bug("Unknown packets type");
-		ieee80211_rx_irqsafe(priv->hw, skb, &status);
+		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+		ieee80211_rx_irqsafe(priv->hw, skb);
 		rx_desc_reinit(priv, i);
 
 	} while (priv->rx.idx++);
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
index 3724b8a..e0c5ba4 100644
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ b/drivers/staging/altpciechdma/altpciechdma.c
@@ -550,7 +550,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
 #if 0
 		*(u32 *)(buffer_virt + i) = i / PAGE_SIZE + 1;
 #else
-		*(u32 *)(buffer_virt + i) = (buffer_virt + i);
+		*(u32 *)(buffer_virt + i) = (u32)(unsigned long)(buffer_virt + i);
 #endif
 #if 0
   compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 17d89a8..99010d4 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -31,18 +31,21 @@
 #include <linux/sched.h>
 #include <linux/uaccess.h>
 #include <linux/vmalloc.h>
+
 #include "binder.h"
 
 static DEFINE_MUTEX(binder_lock);
+static DEFINE_MUTEX(binder_deferred_lock);
+
 static HLIST_HEAD(binder_procs);
+static HLIST_HEAD(binder_deferred_list);
+static HLIST_HEAD(binder_dead_nodes);
+
+static struct proc_dir_entry *binder_proc_dir_entry_root;
+static struct proc_dir_entry *binder_proc_dir_entry_proc;
 static struct binder_node *binder_context_mgr_node;
 static uid_t binder_context_mgr_uid = -1;
 static int binder_last_id;
-static struct proc_dir_entry *binder_proc_dir_entry_root;
-static struct proc_dir_entry *binder_proc_dir_entry_proc;
-static struct hlist_head binder_dead_nodes;
-static HLIST_HEAD(binder_deferred_list);
-static DEFINE_MUTEX(binder_deferred_lock);
 
 static int binder_read_proc_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data);
@@ -100,6 +103,12 @@ static int binder_set_stop_on_user_error(const char *val,
 module_param_call(stop_on_user_error, binder_set_stop_on_user_error,
 	param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO);
 
+#define binder_debug(mask, x...) \
+	do { \
+		if (binder_debug_mask & mask) \
+			printk(KERN_INFO x); \
+	} while (0)
+
 #define binder_user_error(x...) \
 	do { \
 		if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \
@@ -108,7 +117,7 @@ module_param_call(stop_on_user_error, binder_set_stop_on_user_error,
 			binder_stop_on_user_error = 2; \
 	} while (0)
 
-enum {
+enum binder_stat_types {
 	BINDER_STAT_PROC,
 	BINDER_STAT_THREAD,
 	BINDER_STAT_NODE,
@@ -128,6 +137,16 @@ struct binder_stats {
 
 static struct binder_stats binder_stats;
 
+static inline void binder_stats_deleted(enum binder_stat_types type)
+{
+	binder_stats.obj_deleted[type]++;
+}
+
+static inline void binder_stats_created(enum binder_stat_types type)
+{
+	binder_stats.obj_created[type]++;
+}
+
 struct binder_transaction_log_entry {
 	int debug_id;
 	int call_type;
@@ -145,8 +164,8 @@ struct binder_transaction_log {
 	int full;
 	struct binder_transaction_log_entry entry[32];
 };
-struct binder_transaction_log binder_transaction_log;
-struct binder_transaction_log binder_transaction_log_failed;
+static struct binder_transaction_log binder_transaction_log;
+static struct binder_transaction_log binder_transaction_log_failed;
 
 static struct binder_transaction_log_entry *binder_transaction_log_add(
 	struct binder_transaction_log *log)
@@ -237,7 +256,7 @@ struct binder_buffer {
 	uint8_t data[0];
 };
 
-enum {
+enum binder_deferred_state {
 	BINDER_DEFERRED_PUT_FILES    = 0x01,
 	BINDER_DEFERRED_FLUSH        = 0x02,
 	BINDER_DEFERRED_RELEASE      = 0x04,
@@ -320,7 +339,8 @@ struct binder_transaction {
 	uid_t	sender_euid;
 };
 
-static void binder_defer_work(struct binder_proc *proc, int defer);
+static void
+binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
 
 /*
  * copied from get_unused_fd_flags
@@ -468,9 +488,9 @@ static void binder_set_nice(long nice)
 		return;
 	}
 	min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur;
-	if (binder_debug_mask & BINDER_DEBUG_PRIORITY_CAP)
-		printk(KERN_INFO "binder: %d: nice value %ld not allowed use "
-		       "%ld instead\n", current->pid, nice, min_nice);
+	binder_debug(BINDER_DEBUG_PRIORITY_CAP,
+		     "binder: %d: nice value %ld not allowed use "
+		     "%ld instead\n", current->pid, nice, min_nice);
 	set_user_nice(current, min_nice);
 	if (min_nice < 20)
 		return;
@@ -500,9 +520,9 @@ static void binder_insert_free_buffer(struct binder_proc *proc,
 
 	new_buffer_size = binder_buffer_size(proc, new_buffer);
 
-	if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-		printk(KERN_INFO "binder: %d: add free buffer, size %zd, "
-		       "at %p\n", proc->pid, new_buffer_size, new_buffer);
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: add free buffer, size %zd, "
+		     "at %p\n", proc->pid, new_buffer_size, new_buffer);
 
 	while (*p) {
 		parent = *p;
@@ -579,9 +599,9 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate,
 	struct page **page;
 	struct mm_struct *mm;
 
-	if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-		printk(KERN_INFO "binder: %d: %s pages %p-%p\n",
-		       proc->pid, allocate ? "allocate" : "free", start, end);
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: %s pages %p-%p\n", proc->pid,
+		     allocate ? "allocate" : "free", start, end);
 
 	if (end <= start)
 		return 0;
@@ -696,10 +716,9 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
 
 	if (is_async &&
 	    proc->free_async_space < size + sizeof(struct binder_buffer)) {
-		if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-			printk(KERN_ERR
-			       "binder: %d: binder_alloc_buf size %zd failed, "
-			       "no async space left\n", proc->pid, size);
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+			     "binder: %d: binder_alloc_buf size %zd"
+			     "failed, no async space left\n", proc->pid, size);
 		return NULL;
 	}
 
@@ -727,9 +746,10 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
 		buffer = rb_entry(best_fit, struct binder_buffer, rb_node);
 		buffer_size = binder_buffer_size(proc, buffer);
 	}
-	if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-		printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd got buff"
-		       "er %p size %zd\n", proc->pid, size, buffer, buffer_size);
+
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: binder_alloc_buf size %zd got buff"
+		     "er %p size %zd\n", proc->pid, size, buffer, buffer_size);
 
 	has_page_addr =
 		(void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);
@@ -756,18 +776,18 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc,
 		new_buffer->free = 1;
 		binder_insert_free_buffer(proc, new_buffer);
 	}
-	if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-		printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd got "
-		       "%p\n", proc->pid, size, buffer);
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: binder_alloc_buf size %zd got "
+		     "%p\n", proc->pid, size, buffer);
 	buffer->data_size = data_size;
 	buffer->offsets_size = offsets_size;
 	buffer->async_transaction = is_async;
 	if (is_async) {
 		proc->free_async_space -= size + sizeof(struct binder_buffer);
-		if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC_ASYNC)
-			printk(KERN_INFO "binder: %d: binder_alloc_buf size %zd "
-			       "async free %zd\n", proc->pid, size,
-			       proc->free_async_space);
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
+			     "binder: %d: binder_alloc_buf size %zd "
+			     "async free %zd\n", proc->pid, size,
+			     proc->free_async_space);
 	}
 
 	return buffer;
@@ -797,9 +817,9 @@ static void binder_delete_free_buffer(struct binder_proc *proc,
 		free_page_start = 0;
 		if (buffer_end_page(prev) == buffer_end_page(buffer))
 			free_page_end = 0;
-		if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-			printk(KERN_INFO "binder: %d: merge free, buffer %p "
-			       "share page with %p\n", proc->pid, buffer, prev);
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+			     "binder: %d: merge free, buffer %p "
+			     "share page with %p\n", proc->pid, buffer, prev);
 	}
 
 	if (!list_is_last(&buffer->entry, &proc->buffers)) {
@@ -810,19 +830,19 @@ static void binder_delete_free_buffer(struct binder_proc *proc,
 			if (buffer_start_page(next) ==
 			    buffer_start_page(buffer))
 				free_page_start = 0;
-			if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-				printk(KERN_INFO "binder: %d: merge free, "
-				       "buffer %p share page with %p\n",
-				       proc->pid, buffer, prev);
+			binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+				     "binder: %d: merge free, buffer"
+				     " %p share page with %p\n", proc->pid,
+				     buffer, prev);
 		}
 	}
 	list_del(&buffer->entry);
 	if (free_page_start || free_page_end) {
-		if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-			printk(KERN_INFO "binder: %d: merge free, buffer %p do "
-			       "not share page%s%s with with %p or %p\n",
-			       proc->pid, buffer, free_page_start ? "" : " end",
-			       free_page_end ? "" : " start", prev, next);
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+			     "binder: %d: merge free, buffer %p do "
+			     "not share page%s%s with with %p or %p\n",
+			     proc->pid, buffer, free_page_start ? "" : " end",
+			     free_page_end ? "" : " start", prev, next);
 		binder_update_page_range(proc, 0, free_page_start ?
 			buffer_start_page(buffer) : buffer_end_page(buffer),
 			(free_page_end ? buffer_end_page(buffer) :
@@ -839,9 +859,10 @@ static void binder_free_buf(struct binder_proc *proc,
 
 	size = ALIGN(buffer->data_size, sizeof(void *)) +
 		ALIGN(buffer->offsets_size, sizeof(void *));
-	if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC)
-		printk(KERN_INFO "binder: %d: binder_free_buf %p size %zd buffer"
-		       "_size %zd\n", proc->pid, buffer, size, buffer_size);
+
+	binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+		     "binder: %d: binder_free_buf %p size %zd buffer"
+		     "_size %zd\n", proc->pid, buffer, size, buffer_size);
 
 	BUG_ON(buffer->free);
 	BUG_ON(size > buffer_size);
@@ -851,10 +872,11 @@ static void binder_free_buf(struct binder_proc *proc,
 
 	if (buffer->async_transaction) {
 		proc->free_async_space += size + sizeof(struct binder_buffer);
-		if (binder_debug_mask & BINDER_DEBUG_BUFFER_ALLOC_ASYNC)
-			printk(KERN_INFO "binder: %d: binder_free_buf size %zd "
-			       "async free %zd\n", proc->pid, size,
-			       proc->free_async_space);
+
+		binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC,
+			     "binder: %d: binder_free_buf size %zd "
+			     "async free %zd\n", proc->pid, size,
+			     proc->free_async_space);
 	}
 
 	binder_update_page_range(proc, 0,
@@ -925,7 +947,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc,
 	node = kzalloc(sizeof(*node), GFP_KERNEL);
 	if (node == NULL)
 		return NULL;
-	binder_stats.obj_created[BINDER_STAT_NODE]++;
+	binder_stats_created(BINDER_STAT_NODE);
 	rb_link_node(&node->rb_node, parent, p);
 	rb_insert_color(&node->rb_node, &proc->nodes);
 	node->debug_id = ++binder_last_id;
@@ -935,10 +957,10 @@ static struct binder_node *binder_new_node(struct binder_proc *proc,
 	node->work.type = BINDER_WORK_NODE;
 	INIT_LIST_HEAD(&node->work.entry);
 	INIT_LIST_HEAD(&node->async_todo);
-	if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-		printk(KERN_INFO "binder: %d:%d node %d u%p c%p created\n",
-		       proc->pid, current->pid, node->debug_id,
-		       node->ptr, node->cookie);
+	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+		     "binder: %d:%d node %d u%p c%p created\n",
+		     proc->pid, current->pid, node->debug_id,
+		     node->ptr, node->cookie);
 	return node;
 }
 
@@ -1003,15 +1025,17 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal)
 			list_del_init(&node->work.entry);
 			if (node->proc) {
 				rb_erase(&node->rb_node, &node->proc->nodes);
-				if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-					printk(KERN_INFO "binder: refless node %d deleted\n", node->debug_id);
+				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+					     "binder: refless node %d deleted\n",
+					     node->debug_id);
 			} else {
 				hlist_del(&node->dead_node);
-				if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-					printk(KERN_INFO "binder: dead node %d deleted\n", node->debug_id);
+				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+					     "binder: dead node %d deleted\n",
+					     node->debug_id);
 			}
 			kfree(node);
-			binder_stats.obj_deleted[BINDER_STAT_NODE]++;
+			binder_stats_deleted(BINDER_STAT_NODE);
 		}
 	}
 
@@ -1060,7 +1084,7 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
 	new_ref = kzalloc(sizeof(*ref), GFP_KERNEL);
 	if (new_ref == NULL)
 		return NULL;
-	binder_stats.obj_created[BINDER_STAT_REF]++;
+	binder_stats_created(BINDER_STAT_REF);
 	new_ref->debug_id = ++binder_last_id;
 	new_ref->proc = proc;
 	new_ref->node = node;
@@ -1091,25 +1115,27 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc,
 	rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc);
 	if (node) {
 		hlist_add_head(&new_ref->node_entry, &node->refs);
-		if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-			printk(KERN_INFO "binder: %d new ref %d desc %d for "
-				"node %d\n", proc->pid, new_ref->debug_id,
-				new_ref->desc, node->debug_id);
+
+		binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+			     "binder: %d new ref %d desc %d for "
+			     "node %d\n", proc->pid, new_ref->debug_id,
+			     new_ref->desc, node->debug_id);
 	} else {
-		if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-			printk(KERN_INFO "binder: %d new ref %d desc %d for "
-				"dead node\n", proc->pid, new_ref->debug_id,
-				new_ref->desc);
+		binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+			     "binder: %d new ref %d desc %d for "
+			     "dead node\n", proc->pid, new_ref->debug_id,
+			      new_ref->desc);
 	}
 	return new_ref;
 }
 
 static void binder_delete_ref(struct binder_ref *ref)
 {
-	if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-		printk(KERN_INFO "binder: %d delete ref %d desc %d for "
-			"node %d\n", ref->proc->pid, ref->debug_id,
-			ref->desc, ref->node->debug_id);
+	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+		     "binder: %d delete ref %d desc %d for "
+		     "node %d\n", ref->proc->pid, ref->debug_id,
+		     ref->desc, ref->node->debug_id);
+
 	rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc);
 	rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node);
 	if (ref->strong)
@@ -1117,16 +1143,16 @@ static void binder_delete_ref(struct binder_ref *ref)
 	hlist_del(&ref->node_entry);
 	binder_dec_node(ref->node, 0, 1);
 	if (ref->death) {
-		if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
-			printk(KERN_INFO "binder: %d delete ref %d desc %d "
-				"has death notification\n", ref->proc->pid,
-				ref->debug_id, ref->desc);
+		binder_debug(BINDER_DEBUG_DEAD_BINDER,
+			     "binder: %d delete ref %d desc %d "
+			     "has death notification\n", ref->proc->pid,
+			     ref->debug_id, ref->desc);
 		list_del(&ref->death->work.entry);
 		kfree(ref->death);
-		binder_stats.obj_deleted[BINDER_STAT_DEATH]++;
+		binder_stats_deleted(BINDER_STAT_DEATH);
 	}
 	kfree(ref);
-	binder_stats.obj_deleted[BINDER_STAT_REF]++;
+	binder_stats_deleted(BINDER_STAT_REF);
 }
 
 static int binder_inc_ref(struct binder_ref *ref, int strong,
@@ -1198,7 +1224,7 @@ static void binder_pop_transaction(struct binder_thread *target_thread,
 	if (t->buffer)
 		t->buffer->transaction = NULL;
 	kfree(t);
-	binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++;
+	binder_stats_deleted(BINDER_STAT_TRANSACTION);
 }
 
 static void binder_send_failed_reply(struct binder_transaction *t,
@@ -1216,9 +1242,11 @@ static void binder_send_failed_reply(struct binder_transaction *t,
 				target_thread->return_error = BR_OK;
 			}
 			if (target_thread->return_error == BR_OK) {
-				if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION)
-					printk(KERN_INFO "binder: send failed reply for transaction %d to %d:%d\n",
-					       t->debug_id, target_thread->proc->pid, target_thread->pid);
+				binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+					     "binder: send failed reply for "
+					     "transaction %d to %d:%d\n",
+					      t->debug_id, target_thread->proc->pid,
+					      target_thread->pid);
 
 				binder_pop_transaction(target_thread, t);
 				target_thread->return_error = error_code;
@@ -1234,29 +1262,100 @@ static void binder_send_failed_reply(struct binder_transaction *t,
 		} else {
 			struct binder_transaction *next = t->from_parent;
 
-			if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION)
-				printk(KERN_INFO "binder: send failed reply "
-					"for transaction %d, target dead\n",
-					t->debug_id);
+			binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+				     "binder: send failed reply "
+				     "for transaction %d, target dead\n",
+				     t->debug_id);
 
 			binder_pop_transaction(target_thread, t);
 			if (next == NULL) {
-				if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
-					printk(KERN_INFO "binder: reply failed,"
-						" no target thread at root\n");
+				binder_debug(BINDER_DEBUG_DEAD_BINDER,
+					     "binder: reply failed,"
+					     " no target thread at root\n");
 				return;
 			}
 			t = next;
-			if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
-				printk(KERN_INFO "binder: reply failed, no targ"
-					"et thread -- retry %d\n", t->debug_id);
+			binder_debug(BINDER_DEBUG_DEAD_BINDER,
+				     "binder: reply failed, no target "
+				     "thread -- retry %d\n", t->debug_id);
 		}
 	}
 }
 
 static void binder_transaction_buffer_release(struct binder_proc *proc,
 					      struct binder_buffer *buffer,
-					      size_t *failed_at);
+					      size_t *failed_at)
+{
+	size_t *offp, *off_end;
+	int debug_id = buffer->debug_id;
+
+	binder_debug(BINDER_DEBUG_TRANSACTION,
+		     "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
+		     proc->pid, buffer->debug_id,
+		     buffer->data_size, buffer->offsets_size, failed_at);
+
+	if (buffer->target_node)
+		binder_dec_node(buffer->target_node, 1, 0);
+
+	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
+	if (failed_at)
+		off_end = failed_at;
+	else
+		off_end = (void *)offp + buffer->offsets_size;
+	for (; offp < off_end; offp++) {
+		struct flat_binder_object *fp;
+		if (*offp > buffer->data_size - sizeof(*fp) ||
+		    buffer->data_size < sizeof(*fp) ||
+		    !IS_ALIGNED(*offp, sizeof(void *))) {
+			printk(KERN_ERR "binder: transaction release %d bad"
+					"offset %zd, size %zd\n", debug_id,
+					*offp, buffer->data_size);
+			continue;
+		}
+		fp = (struct flat_binder_object *)(buffer->data + *offp);
+		switch (fp->type) {
+		case BINDER_TYPE_BINDER:
+		case BINDER_TYPE_WEAK_BINDER: {
+			struct binder_node *node = binder_get_node(proc, fp->binder);
+			if (node == NULL) {
+				printk(KERN_ERR "binder: transaction release %d"
+				       " bad node %p\n", debug_id, fp->binder);
+				break;
+			}
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        node %d u%p\n",
+				     node->debug_id, node->ptr);
+			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
+		} break;
+		case BINDER_TYPE_HANDLE:
+		case BINDER_TYPE_WEAK_HANDLE: {
+			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			if (ref == NULL) {
+				printk(KERN_ERR "binder: transaction release %d"
+				       " bad handle %ld\n", debug_id,
+				       fp->handle);
+				break;
+			}
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        ref %d desc %d (node %d)\n",
+				     ref->debug_id, ref->desc, ref->node->debug_id);
+			binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
+		} break;
+
+		case BINDER_TYPE_FD:
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        fd %ld\n", fp->handle);
+			if (failed_at)
+				task_close_fd(proc, fp->handle);
+			break;
+
+		default:
+			printk(KERN_ERR "binder: transaction release %d bad "
+			       "object type %lx\n", debug_id, fp->type);
+			break;
+		}
+	}
+}
 
 static void binder_transaction(struct binder_proc *proc,
 			       struct binder_thread *thread,
@@ -1387,34 +1486,34 @@ static void binder_transaction(struct binder_proc *proc,
 		return_error = BR_FAILED_REPLY;
 		goto err_alloc_t_failed;
 	}
-	binder_stats.obj_created[BINDER_STAT_TRANSACTION]++;
+	binder_stats_created(BINDER_STAT_TRANSACTION);
 
 	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
 	if (tcomplete == NULL) {
 		return_error = BR_FAILED_REPLY;
 		goto err_alloc_tcomplete_failed;
 	}
-	binder_stats.obj_created[BINDER_STAT_TRANSACTION_COMPLETE]++;
+	binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
 
 	t->debug_id = ++binder_last_id;
 	e->debug_id = t->debug_id;
 
-	if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) {
-		if (reply)
-			printk(KERN_INFO "binder: %d:%d BC_REPLY %d -> %d:%d, "
-			       "data %p-%p size %zd-%zd\n",
-			       proc->pid, thread->pid, t->debug_id,
-			       target_proc->pid, target_thread->pid,
-			       tr->data.ptr.buffer, tr->data.ptr.offsets,
-			       tr->data_size, tr->offsets_size);
-		else
-			printk(KERN_INFO "binder: %d:%d BC_TRANSACTION %d -> "
-			       "%d - node %d, data %p-%p size %zd-%zd\n",
-			       proc->pid, thread->pid, t->debug_id,
-			       target_proc->pid, target_node->debug_id,
-			       tr->data.ptr.buffer, tr->data.ptr.offsets,
-			       tr->data_size, tr->offsets_size);
-	}
+	if (reply)
+		binder_debug(BINDER_DEBUG_TRANSACTION,
+			     "binder: %d:%d BC_REPLY %d -> %d:%d, "
+			     "data %p-%p size %zd-%zd\n",
+			     proc->pid, thread->pid, t->debug_id,
+			     target_proc->pid, target_thread->pid,
+			     tr->data.ptr.buffer, tr->data.ptr.offsets,
+			     tr->data_size, tr->offsets_size);
+	else
+		binder_debug(BINDER_DEBUG_TRANSACTION,
+			     "binder: %d:%d BC_TRANSACTION %d -> "
+			     "%d - node %d, data %p-%p size %zd-%zd\n",
+			     proc->pid, thread->pid, t->debug_id,
+			     target_proc->pid, target_node->debug_id,
+			     tr->data.ptr.buffer, tr->data.ptr.offsets,
+			     tr->data_size, tr->offsets_size);
 
 	if (!reply && !(tr->flags & TF_ONE_WAY))
 		t->from = thread;
@@ -1505,10 +1604,13 @@ static void binder_transaction(struct binder_proc *proc,
 			else
 				fp->type = BINDER_TYPE_WEAK_HANDLE;
 			fp->handle = ref->desc;
-			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, &thread->todo);
-			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-				printk(KERN_INFO "        node %d u%p -> ref %d desc %d\n",
-				       node->debug_id, node->ptr, ref->debug_id, ref->desc);
+			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
+				       &thread->todo);
+
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        node %d u%p -> ref %d desc %d\n",
+				     node->debug_id, node->ptr, ref->debug_id,
+				     ref->desc);
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
@@ -1529,9 +1631,10 @@ static void binder_transaction(struct binder_proc *proc,
 				fp->binder = ref->node->ptr;
 				fp->cookie = ref->node->cookie;
 				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
-				if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-					printk(KERN_INFO "        ref %d desc %d -> node %d u%p\n",
-					       ref->debug_id, ref->desc, ref->node->debug_id, ref->node->ptr);
+				binder_debug(BINDER_DEBUG_TRANSACTION,
+					     "        ref %d desc %d -> node %d u%p\n",
+					     ref->debug_id, ref->desc, ref->node->debug_id,
+					     ref->node->ptr);
 			} else {
 				struct binder_ref *new_ref;
 				new_ref = binder_get_ref_for_node(target_proc, ref->node);
@@ -1541,9 +1644,10 @@ static void binder_transaction(struct binder_proc *proc,
 				}
 				fp->handle = new_ref->desc;
 				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
-				if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-					printk(KERN_INFO "        ref %d desc %d -> ref %d desc %d (node %d)\n",
-					       ref->debug_id, ref->desc, new_ref->debug_id, new_ref->desc, ref->node->debug_id);
+				binder_debug(BINDER_DEBUG_TRANSACTION,
+					     "        ref %d desc %d -> ref %d desc %d (node %d)\n",
+					     ref->debug_id, ref->desc, new_ref->debug_id,
+					     new_ref->desc, ref->node->debug_id);
 			}
 		} break;
 
@@ -1579,8 +1683,8 @@ static void binder_transaction(struct binder_proc *proc,
 				goto err_get_unused_fd_failed;
 			}
 			task_fd_install(target_proc, target_fd, file);
-			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-				printk(KERN_INFO "        fd %ld -> %d\n", fp->handle, target_fd);
+			binder_debug(BINDER_DEBUG_TRANSACTION,
+				     "        fd %ld -> %d\n", fp->handle, target_fd);
 			/* TODO: fput? */
 			fp->handle = target_fd;
 		} break;
@@ -1632,21 +1736,20 @@ err_copy_data_failed:
 	binder_free_buf(target_proc, t->buffer);
 err_binder_alloc_buf_failed:
 	kfree(tcomplete);
-	binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++;
+	binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
 err_alloc_tcomplete_failed:
 	kfree(t);
-	binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++;
+	binder_stats_deleted(BINDER_STAT_TRANSACTION);
 err_alloc_t_failed:
 err_bad_call_stack:
 err_empty_call_stack:
 err_dead_binder:
 err_invalid_target_handle:
 err_no_context_mgr_node:
-	if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION)
-		printk(KERN_INFO "binder: %d:%d transaction failed %d, size"
-				"%zd-%zd\n",
-			   proc->pid, thread->pid, return_error,
-			   tr->data_size, tr->offsets_size);
+	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+		     "binder: %d:%d transaction failed %d, size %zd-%zd\n",
+		     proc->pid, thread->pid, return_error,
+		     tr->data_size, tr->offsets_size);
 
 	{
 		struct binder_transaction_log_entry *fe;
@@ -1662,76 +1765,6 @@ err_no_context_mgr_node:
 		thread->return_error = return_error;
 }
 
-static void binder_transaction_buffer_release(struct binder_proc *proc,
-					      struct binder_buffer *buffer,
-					      size_t *failed_at)
-{
-	size_t *offp, *off_end;
-	int debug_id = buffer->debug_id;
-
-	if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-		printk(KERN_INFO "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
-			   proc->pid, buffer->debug_id,
-			   buffer->data_size, buffer->offsets_size, failed_at);
-
-	if (buffer->target_node)
-		binder_dec_node(buffer->target_node, 1, 0);
-
-	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
-	if (failed_at)
-		off_end = failed_at;
-	else
-		off_end = (void *)offp + buffer->offsets_size;
-	for (; offp < off_end; offp++) {
-		struct flat_binder_object *fp;
-		if (*offp > buffer->data_size - sizeof(*fp) ||
-		    buffer->data_size < sizeof(*fp) ||
-		    !IS_ALIGNED(*offp, sizeof(void *))) {
-			printk(KERN_ERR "binder: transaction release %d bad"
-					"offset %zd, size %zd\n", debug_id, *offp, buffer->data_size);
-			continue;
-		}
-		fp = (struct flat_binder_object *)(buffer->data + *offp);
-		switch (fp->type) {
-		case BINDER_TYPE_BINDER:
-		case BINDER_TYPE_WEAK_BINDER: {
-			struct binder_node *node = binder_get_node(proc, fp->binder);
-			if (node == NULL) {
-				printk(KERN_ERR "binder: transaction release %d bad node %p\n", debug_id, fp->binder);
-				break;
-			}
-			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-				printk(KERN_INFO "        node %d u%p\n",
-				       node->debug_id, node->ptr);
-			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
-		} break;
-		case BINDER_TYPE_HANDLE:
-		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
-			if (ref == NULL) {
-				printk(KERN_ERR "binder: transaction release %d bad handle %ld\n", debug_id, fp->handle);
-				break;
-			}
-			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-				printk(KERN_INFO "        ref %d desc %d (node %d)\n",
-				       ref->debug_id, ref->desc, ref->node->debug_id);
-			binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
-		} break;
-
-		case BINDER_TYPE_FD:
-			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-				printk(KERN_INFO "        fd %ld\n", fp->handle);
-			if (failed_at)
-				task_close_fd(proc, fp->handle);
-			break;
-
-		default:
-			printk(KERN_ERR "binder: transaction release %d bad object type %lx\n", debug_id, fp->type);
-			break;
-		}
-	}
-}
-
 int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 			void __user *buffer, int size, signed long *consumed)
 {
@@ -1799,9 +1832,10 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 				binder_dec_ref(ref, 0);
 				break;
 			}
-			if (binder_debug_mask & BINDER_DEBUG_USER_REFS)
-				printk(KERN_INFO "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
-				       proc->pid, thread->pid, debug_string, ref->debug_id, ref->desc, ref->strong, ref->weak, ref->node->debug_id);
+			binder_debug(BINDER_DEBUG_USER_REFS,
+				     "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
+				     proc->pid, thread->pid, debug_string, ref->debug_id,
+				     ref->desc, ref->strong, ref->weak, ref->node->debug_id);
 			break;
 		}
 		case BC_INCREFS_DONE:
@@ -1859,9 +1893,11 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 				node->pending_weak_ref = 0;
 			}
 			binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0);
-			if (binder_debug_mask & BINDER_DEBUG_USER_REFS)
-				printk(KERN_INFO "binder: %d:%d %s node %d ls %d lw %d\n",
-				       proc->pid, thread->pid, cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", node->debug_id, node->local_strong_refs, node->local_weak_refs);
+			binder_debug(BINDER_DEBUG_USER_REFS,
+				     "binder: %d:%d %s node %d ls %d lw %d\n",
+				     proc->pid, thread->pid,
+				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
+				     node->debug_id, node->local_strong_refs, node->local_weak_refs);
 			break;
 		}
 		case BC_ATTEMPT_ACQUIRE:
@@ -1893,10 +1929,10 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 					proc->pid, thread->pid, data_ptr);
 				break;
 			}
-			if (binder_debug_mask & BINDER_DEBUG_FREE_BUFFER)
-				printk(KERN_INFO "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
-				       proc->pid, thread->pid, data_ptr, buffer->debug_id,
-				       buffer->transaction ? "active" : "finished");
+			binder_debug(BINDER_DEBUG_FREE_BUFFER,
+				     "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
+				     proc->pid, thread->pid, data_ptr, buffer->debug_id,
+				     buffer->transaction ? "active" : "finished");
 
 			if (buffer->transaction) {
 				buffer->transaction->buffer = NULL;
@@ -1926,9 +1962,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 		}
 
 		case BC_REGISTER_LOOPER:
-			if (binder_debug_mask & BINDER_DEBUG_THREADS)
-				printk(KERN_INFO "binder: %d:%d BC_REGISTER_LOOPER\n",
-				       proc->pid, thread->pid);
+			binder_debug(BINDER_DEBUG_THREADS,
+				     "binder: %d:%d BC_REGISTER_LOOPER\n",
+				     proc->pid, thread->pid);
 			if (thread->looper & BINDER_LOOPER_STATE_ENTERED) {
 				thread->looper |= BINDER_LOOPER_STATE_INVALID;
 				binder_user_error("binder: %d:%d ERROR:"
@@ -1948,9 +1984,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 			thread->looper |= BINDER_LOOPER_STATE_REGISTERED;
 			break;
 		case BC_ENTER_LOOPER:
-			if (binder_debug_mask & BINDER_DEBUG_THREADS)
-				printk(KERN_INFO "binder: %d:%d BC_ENTER_LOOPER\n",
-				       proc->pid, thread->pid);
+			binder_debug(BINDER_DEBUG_THREADS,
+				     "binder: %d:%d BC_ENTER_LOOPER\n",
+				     proc->pid, thread->pid);
 			if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) {
 				thread->looper |= BINDER_LOOPER_STATE_INVALID;
 				binder_user_error("binder: %d:%d ERROR:"
@@ -1961,9 +1997,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 			thread->looper |= BINDER_LOOPER_STATE_ENTERED;
 			break;
 		case BC_EXIT_LOOPER:
-			if (binder_debug_mask & BINDER_DEBUG_THREADS)
-				printk(KERN_INFO "binder: %d:%d BC_EXIT_LOOPER\n",
-				       proc->pid, thread->pid);
+			binder_debug(BINDER_DEBUG_THREADS,
+				     "binder: %d:%d BC_EXIT_LOOPER\n",
+				     proc->pid, thread->pid);
 			thread->looper |= BINDER_LOOPER_STATE_EXITED;
 			break;
 
@@ -1992,14 +2028,14 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 				break;
 			}
 
-			if (binder_debug_mask & BINDER_DEBUG_DEATH_NOTIFICATION)
-				printk(KERN_INFO "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
-				       proc->pid, thread->pid,
-				       cmd == BC_REQUEST_DEATH_NOTIFICATION ?
-				       "BC_REQUEST_DEATH_NOTIFICATION" :
-				       "BC_CLEAR_DEATH_NOTIFICATION",
-				       cookie, ref->debug_id, ref->desc,
-				       ref->strong, ref->weak, ref->node->debug_id);
+			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
+				     "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
+				     proc->pid, thread->pid,
+				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
+				     "BC_REQUEST_DEATH_NOTIFICATION" :
+				     "BC_CLEAR_DEATH_NOTIFICATION",
+				     cookie, ref->debug_id, ref->desc,
+				     ref->strong, ref->weak, ref->node->debug_id);
 
 			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
 				if (ref->death) {
@@ -2013,13 +2049,13 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 				death = kzalloc(sizeof(*death), GFP_KERNEL);
 				if (death == NULL) {
 					thread->return_error = BR_ERROR;
-					if (binder_debug_mask & BINDER_DEBUG_FAILED_TRANSACTION)
-						printk(KERN_INFO "binder: %d:%d "
-							"BC_REQUEST_DEATH_NOTIFICATION failed\n",
-							proc->pid, thread->pid);
+					binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+						     "binder: %d:%d "
+						     "BC_REQUEST_DEATH_NOTIFICATION failed\n",
+						     proc->pid, thread->pid);
 					break;
 				}
-				binder_stats.obj_created[BINDER_STAT_DEATH]++;
+				binder_stats_created(BINDER_STAT_DEATH);
 				INIT_LIST_HEAD(&death->work.entry);
 				death->cookie = cookie;
 				ref->death = death;
@@ -2082,9 +2118,9 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread,
 					break;
 				}
 			}
-			if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
-				printk(KERN_INFO "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n",
-				       proc->pid, thread->pid, cookie, death);
+			binder_debug(BINDER_DEBUG_DEAD_BINDER,
+				     "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n",
+				     proc->pid, thread->pid, cookie, death);
 			if (death == NULL) {
 				binder_user_error("binder: %d:%d BC_DEAD"
 					"_BINDER_DONE %p not found\n",
@@ -2240,13 +2276,13 @@ retry:
 			ptr += sizeof(uint32_t);
 
 			binder_stat_br(proc, thread, cmd);
-			if (binder_debug_mask & BINDER_DEBUG_TRANSACTION_COMPLETE)
-				printk(KERN_INFO "binder: %d:%d BR_TRANSACTION_COMPLETE\n",
-				       proc->pid, thread->pid);
+			binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE,
+				     "binder: %d:%d BR_TRANSACTION_COMPLETE\n",
+				     proc->pid, thread->pid);
 
 			list_del(&w->entry);
 			kfree(w);
-			binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++;
+			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
 		} break;
 		case BINDER_WORK_NODE: {
 			struct binder_node *node = container_of(w, struct binder_node, work);
@@ -2287,22 +2323,24 @@ retry:
 				ptr += sizeof(void *);
 
 				binder_stat_br(proc, thread, cmd);
-				if (binder_debug_mask & BINDER_DEBUG_USER_REFS)
-					printk(KERN_INFO "binder: %d:%d %s %d u%p c%p\n",
-					       proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie);
+				binder_debug(BINDER_DEBUG_USER_REFS,
+					     "binder: %d:%d %s %d u%p c%p\n",
+					     proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie);
 			} else {
 				list_del_init(&w->entry);
 				if (!weak && !strong) {
-					if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-						printk(KERN_INFO "binder: %d:%d node %d u%p c%p deleted\n",
-						       proc->pid, thread->pid, node->debug_id, node->ptr, node->cookie);
+					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+						     "binder: %d:%d node %d u%p c%p deleted\n",
+						     proc->pid, thread->pid, node->debug_id,
+						     node->ptr, node->cookie);
 					rb_erase(&node->rb_node, &proc->nodes);
 					kfree(node);
-					binder_stats.obj_deleted[BINDER_STAT_NODE]++;
+					binder_stats_deleted(BINDER_STAT_NODE);
 				} else {
-					if (binder_debug_mask & BINDER_DEBUG_INTERNAL_REFS)
-						printk(KERN_INFO "binder: %d:%d node %d u%p c%p state unchanged\n",
-						       proc->pid, thread->pid, node->debug_id, node->ptr, node->cookie);
+					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
+						     "binder: %d:%d node %d u%p c%p state unchanged\n",
+						     proc->pid, thread->pid, node->debug_id, node->ptr,
+						     node->cookie);
 				}
 			}
 		} break;
@@ -2323,18 +2361,18 @@ retry:
 			if (put_user(death->cookie, (void * __user *)ptr))
 				return -EFAULT;
 			ptr += sizeof(void *);
-			if (binder_debug_mask & BINDER_DEBUG_DEATH_NOTIFICATION)
-				printk(KERN_INFO "binder: %d:%d %s %p\n",
-				       proc->pid, thread->pid,
-				       cmd == BR_DEAD_BINDER ?
-				       "BR_DEAD_BINDER" :
-				       "BR_CLEAR_DEATH_NOTIFICATION_DONE",
-				       death->cookie);
+			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
+				     "binder: %d:%d %s %p\n",
+				      proc->pid, thread->pid,
+				      cmd == BR_DEAD_BINDER ?
+				      "BR_DEAD_BINDER" :
+				      "BR_CLEAR_DEATH_NOTIFICATION_DONE",
+				      death->cookie);
 
 			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) {
 				list_del(&w->entry);
 				kfree(death);
-				binder_stats.obj_deleted[BINDER_STAT_DEATH]++;
+				binder_stats_deleted(BINDER_STAT_DEATH);
 			} else
 				list_move(&w->entry, &proc->delivered_death);
 			if (cmd == BR_DEAD_BINDER)
@@ -2391,16 +2429,16 @@ retry:
 		ptr += sizeof(tr);
 
 		binder_stat_br(proc, thread, cmd);
-		if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)
-			printk(KERN_INFO "binder: %d:%d %s %d %d:%d, cmd %d"
-				"size %zd-%zd ptr %p-%p\n",
-			       proc->pid, thread->pid,
-			       (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
-							 "BR_REPLY",
-			       t->debug_id, t->from ? t->from->proc->pid : 0,
-			       t->from ? t->from->pid : 0, cmd,
-			       t->buffer->data_size, t->buffer->offsets_size,
-			       tr.data.ptr.buffer, tr.data.ptr.offsets);
+		binder_debug(BINDER_DEBUG_TRANSACTION,
+			     "binder: %d:%d %s %d %d:%d, cmd %d"
+			     "size %zd-%zd ptr %p-%p\n",
+			     proc->pid, thread->pid,
+			     (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
+			     "BR_REPLY",
+			     t->debug_id, t->from ? t->from->proc->pid : 0,
+			     t->from ? t->from->pid : 0, cmd,
+			     t->buffer->data_size, t->buffer->offsets_size,
+			     tr.data.ptr.buffer, tr.data.ptr.offsets);
 
 		list_del(&t->work.entry);
 		t->buffer->allow_user_free = 1;
@@ -2411,7 +2449,7 @@ retry:
 		} else {
 			t->buffer->transaction = NULL;
 			kfree(t);
-			binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++;
+			binder_stats_deleted(BINDER_STAT_TRANSACTION);
 		}
 		break;
 	}
@@ -2425,9 +2463,9 @@ done:
 	     BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */
 	     /*spawn a new thread if we leave this out */) {
 		proc->requested_threads++;
-		if (binder_debug_mask & BINDER_DEBUG_THREADS)
-			printk(KERN_INFO "binder: %d:%d BR_SPAWN_LOOPER\n",
-			       proc->pid, thread->pid);
+		binder_debug(BINDER_DEBUG_THREADS,
+			     "binder: %d:%d BR_SPAWN_LOOPER\n",
+			     proc->pid, thread->pid);
 		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
 			return -EFAULT;
 	}
@@ -2450,7 +2488,7 @@ static void binder_release_work(struct list_head *list)
 		} break;
 		case BINDER_WORK_TRANSACTION_COMPLETE: {
 			kfree(w);
-			binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++;
+			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
 		} break;
 		default:
 			break;
@@ -2480,7 +2518,7 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc)
 		thread = kzalloc(sizeof(*thread), GFP_KERNEL);
 		if (thread == NULL)
 			return NULL;
-		binder_stats.obj_created[BINDER_STAT_THREAD]++;
+		binder_stats_created(BINDER_STAT_THREAD);
 		thread->proc = proc;
 		thread->pid = current->pid;
 		init_waitqueue_head(&thread->wait);
@@ -2507,11 +2545,12 @@ static int binder_free_thread(struct binder_proc *proc,
 		send_reply = t;
 	while (t) {
 		active_transactions++;
-		if (binder_debug_mask & BINDER_DEBUG_DEAD_TRANSACTION)
-			printk(KERN_INFO "binder: release %d:%d transaction %d "
-			       "%s, still active\n", proc->pid, thread->pid,
-			       t->debug_id,
-			       (t->to_thread == thread) ? "in" : "out");
+		binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+			     "binder: release %d:%d transaction %d "
+			     "%s, still active\n", proc->pid, thread->pid,
+			     t->debug_id,
+			     (t->to_thread == thread) ? "in" : "out");
+
 		if (t->to_thread == thread) {
 			t->to_proc = NULL;
 			t->to_thread = NULL;
@@ -2530,7 +2569,7 @@ static int binder_free_thread(struct binder_proc *proc,
 		binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
 	binder_release_work(&thread->todo);
 	kfree(thread);
-	binder_stats.obj_deleted[BINDER_STAT_THREAD]++;
+	binder_stats_deleted(BINDER_STAT_THREAD);
 	return active_transactions;
 }
 
@@ -2596,9 +2635,11 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 			ret = -EFAULT;
 			goto err;
 		}
-		if (binder_debug_mask & BINDER_DEBUG_READ_WRITE)
-			printk(KERN_INFO "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
-			       proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, bwr.read_size, bwr.read_buffer);
+		binder_debug(BINDER_DEBUG_READ_WRITE,
+			     "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
+			     proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
+			     bwr.read_size, bwr.read_buffer);
+
 		if (bwr.write_size > 0) {
 			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
 			if (ret < 0) {
@@ -2618,9 +2659,10 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 				goto err;
 			}
 		}
-		if (binder_debug_mask & BINDER_DEBUG_READ_WRITE)
-			printk(KERN_INFO "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
-			       proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, bwr.read_consumed, bwr.read_size);
+		binder_debug(BINDER_DEBUG_READ_WRITE,
+			     "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
+			     proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
+			     bwr.read_consumed, bwr.read_size);
 		if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
 			ret = -EFAULT;
 			goto err;
@@ -2661,9 +2703,8 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		binder_context_mgr_node->has_weak_ref = 1;
 		break;
 	case BINDER_THREAD_EXIT:
-		if (binder_debug_mask & BINDER_DEBUG_THREADS)
-			printk(KERN_INFO "binder: %d:%d exit\n",
-			       proc->pid, thread->pid);
+		binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n",
+			     proc->pid, thread->pid);
 		binder_free_thread(proc, thread);
 		thread = NULL;
 		break;
@@ -2695,24 +2736,22 @@ err:
 static void binder_vma_open(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 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));
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "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,
-			(unsigned long)pgprot_val(vma->vm_page_prot));
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "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;
 	binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
 }
@@ -2733,12 +2772,11 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
 	if ((vma->vm_end - vma->vm_start) > SZ_4M)
 		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,
-			(unsigned long)pgprot_val(vma->vm_page_prot));
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "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;
@@ -2818,9 +2856,8 @@ static int binder_open(struct inode *nodp, struct file *filp)
 {
 	struct binder_proc *proc;
 
-	if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
-		printk(KERN_INFO "binder_open: %d:%d\n",
-		       current->group_leader->pid, current->pid);
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
+		     current->group_leader->pid, current->pid);
 
 	proc = kzalloc(sizeof(*proc), GFP_KERNEL);
 	if (proc == NULL)
@@ -2831,7 +2868,7 @@ static int binder_open(struct inode *nodp, struct file *filp)
 	init_waitqueue_head(&proc->wait);
 	proc->default_priority = task_nice(current);
 	mutex_lock(&binder_lock);
-	binder_stats.obj_created[BINDER_STAT_PROC]++;
+	binder_stats_created(BINDER_STAT_PROC);
 	hlist_add_head(&proc->proc_node, &binder_procs);
 	proc->pid = current->group_leader->pid;
 	INIT_LIST_HEAD(&proc->delivered_death);
@@ -2873,8 +2910,9 @@ static void binder_deferred_flush(struct binder_proc *proc)
 	}
 	wake_up_interruptible_all(&proc->wait);
 
-	if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
-		printk(KERN_INFO "binder_flush: %d woke %d threads\n", proc->pid, wake_count);
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "binder_flush: %d woke %d threads\n", proc->pid,
+		     wake_count);
 }
 
 static int binder_release(struct inode *nodp, struct file *filp)
@@ -2903,8 +2941,9 @@ static void binder_deferred_release(struct binder_proc *proc)
 
 	hlist_del(&proc->proc_node);
 	if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) {
-		if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
-			printk(KERN_INFO "binder_release: %d context_mgr_node gone\n", proc->pid);
+		binder_debug(BINDER_DEBUG_DEAD_BINDER,
+			     "binder_release: %d context_mgr_node gone\n",
+			     proc->pid);
 		binder_context_mgr_node = NULL;
 	}
 
@@ -2925,7 +2964,7 @@ static void binder_deferred_release(struct binder_proc *proc)
 		list_del_init(&node->work.entry);
 		if (hlist_empty(&node->refs)) {
 			kfree(node);
-			binder_stats.obj_deleted[BINDER_STAT_NODE]++;
+			binder_stats_deleted(BINDER_STAT_NODE);
 		} else {
 			struct binder_ref *ref;
 			int death = 0;
@@ -2947,10 +2986,10 @@ static void binder_deferred_release(struct binder_proc *proc)
 						BUG();
 				}
 			}
-			if (binder_debug_mask & BINDER_DEBUG_DEAD_BINDER)
-				printk(KERN_INFO "binder: node %d now dead, "
-				       "refs %d, death %d\n", node->debug_id,
-				       incoming_refs, death);
+			binder_debug(BINDER_DEBUG_DEAD_BINDER,
+				     "binder: node %d now dead, "
+				     "refs %d, death %d\n", node->debug_id,
+				     incoming_refs, death);
 		}
 	}
 	outgoing_refs = 0;
@@ -2979,20 +3018,18 @@ static void binder_deferred_release(struct binder_proc *proc)
 		buffers++;
 	}
 
-	binder_stats.obj_deleted[BINDER_STAT_PROC]++;
+	binder_stats_deleted(BINDER_STAT_PROC);
 
 	page_count = 0;
 	if (proc->pages) {
 		int i;
 		for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) {
 			if (proc->pages[i]) {
-				if (binder_debug_mask &
-				    BINDER_DEBUG_BUFFER_ALLOC)
-					printk(KERN_INFO
-					       "binder_release: %d: "
-					       "page %d at %p not freed\n",
-					       proc->pid, i,
-					       proc->buffer + i * PAGE_SIZE);
+				binder_debug(BINDER_DEBUG_BUFFER_ALLOC,
+					     "binder_release: %d: "
+					     "page %d at %p not freed\n",
+					     proc->pid, i,
+					     proc->buffer + i * PAGE_SIZE);
 				__free_page(proc->pages[i]);
 				page_count++;
 			}
@@ -3003,13 +3040,12 @@ static void binder_deferred_release(struct binder_proc *proc)
 
 	put_task_struct(proc->tsk);
 
-	if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
-		printk(KERN_INFO
-		       "binder_release: %d threads %d, nodes %d (ref %d), "
-		       "refs %d, active transactions %d, buffers %d, "
-		       "pages %d\n",
-		       proc->pid, threads, nodes, incoming_refs, outgoing_refs,
-		       active_transactions, buffers, page_count);
+	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
+		     "binder_release: %d threads %d, nodes %d (ref %d), "
+		     "refs %d, active transactions %d, buffers %d, "
+		     "pages %d\n",
+		     proc->pid, threads, nodes, incoming_refs, outgoing_refs,
+		     active_transactions, buffers, page_count);
 
 	kfree(proc);
 }
@@ -3055,7 +3091,8 @@ static void binder_deferred_func(struct work_struct *work)
 }
 static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
 
-static void binder_defer_work(struct binder_proc *proc, int defer)
+static void
+binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer)
 {
 	mutex_lock(&binder_deferred_lock);
 	proc->deferred_work |= defer;
diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c
index f934393..935d281 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -1,5 +1,21 @@
 /* drivers/misc/lowmemorykiller.c
  *
+ * The lowmemorykiller driver lets user-space specify a set of memory thresholds
+ * where processes with a range of oom_adj values will get killed. Specify the
+ * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
+ * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
+ * files take a comma separated list of numbers in ascending order.
+ *
+ * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
+ * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes
+ * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages
+ * and kill processes with a oom_adj value of 0 or higher when the free memory
+ * drops below 1024 pages.
+ *
+ * The driver considers memory used for caches to be free, but if a large
+ * percentage of the cached memory is locked this can be very inaccurate
+ * and processes may not get killed until the normal oom killer is triggered.
+ *
  * Copyright (C) 2007-2008 Google, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
@@ -19,12 +35,6 @@
 #include <linux/oom.h>
 #include <linux/sched.h>
 
-static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask);
-
-static struct shrinker lowmem_shrinker = {
-	.shrink = lowmem_shrink,
-	.seeks = DEFAULT_SEEKS * 16
-};
 static uint32_t lowmem_debug_level = 2;
 static int lowmem_adj[6] = {
 	0,
@@ -47,13 +57,6 @@ static int lowmem_minfree_size = 4;
 			printk(x);			\
 	} while (0)
 
-module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
-module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
-			 S_IRUGO | S_IWUSR);
-module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
-			 S_IRUGO | S_IWUSR);
-module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
-
 static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
 {
 	struct task_struct *p;
@@ -140,6 +143,11 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
 	return rem;
 }
 
+static struct shrinker lowmem_shrinker = {
+	.shrink = lowmem_shrink,
+	.seeks = DEFAULT_SEEKS * 16
+};
+
 static int __init lowmem_init(void)
 {
 	register_shrinker(&lowmem_shrinker);
@@ -151,6 +159,13 @@ static void __exit lowmem_exit(void)
 	unregister_shrinker(&lowmem_shrinker);
 }
 
+module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
+module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
+			 S_IRUGO | S_IWUSR);
+module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
+			 S_IRUGO | S_IWUSR);
+module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
+
 module_init(lowmem_init);
 module_exit(lowmem_exit);
 
diff --git a/drivers/staging/android/lowmemorykiller.txt b/drivers/staging/android/lowmemorykiller.txt
deleted file mode 100644
index bd5c0c0..0000000
--- a/drivers/staging/android/lowmemorykiller.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-The lowmemorykiller driver lets user-space specify a set of memory thresholds
-where processes with a range of oom_adj values will get killed. Specify the
-minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
-number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
-files take a comma separated list of numbers in ascending order.
-
-For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
-"1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes
-with a oom_adj value of 8 or higher when the free memory drops below 4096 pages
-and kill processes with a oom_adj value of 0 or higher when the free memory
-drops below 1024 pages.
-
-The driver considers memory used for caches to be free, but if a large
-percentage of the cached memory is locked this can be very inaccurate
-and processes may not get killed until the normal oom killer is triggered.
-
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 9270f5d..f4c2657 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -63,26 +63,31 @@ static uint start_off;
 
 module_param(start_off, uint, 0644);
 
-MODULE_PARM_DESC(start_off, "Set to 1 to switch off OLED display after it is attached");
+MODULE_PARM_DESC(start_off,
+		 "Set to 1 to switch off OLED display after it is attached");
 
-typedef enum {
+enum oled_pack_mode{
 	PACK_MODE_G1,
 	PACK_MODE_G50,
 	PACK_MODE_LAST
-} oled_pack_mode_t;
+};
 
 struct oled_dev_desc_str {
 	uint16_t		idVendor;
 	uint16_t		idProduct;
-	uint16_t		devWidth; // width of display
-	oled_pack_mode_t	packMode; // formula to be used while packing the picture
+	/* width of display */
+	uint16_t		devWidth;
+	/* formula to be used while packing the picture */
+	enum oled_pack_mode	packMode;
 	const char		*devDesc;
 };
 
 /* table of devices that work with this driver */
 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?)
+	/* Asus G1/G2 (and variants)*/
+	{ USB_DEVICE(0x0b05, 0x1726) },
+	/* Asus G50V (and possibly others - G70? G71?)*/
+	{ USB_DEVICE(0x0b05, 0x175b) },
 	{ },
 };
 
@@ -95,20 +100,6 @@ static struct oled_dev_desc_str oled_dev_desc_table[] = {
 
 MODULE_DEVICE_TABLE(usb, id_table);
 
-#define SETUP_PACKET_HEADER(packet, val1, val2, val3, val4, val5, val6, val7) \
-	do {					\
-		memset(packet, 0, sizeof(struct asus_oled_header));		\
-		packet->header.magic1 = 0x55;		\
-		packet->header.magic2 = 0xaa;		\
-		packet->header.flags = val1;		\
-		packet->header.value3 = val2;		\
-		packet->header.buffer1 = val3;		\
-		packet->header.buffer2 = val4;		\
-		packet->header.value6 = val5;		\
-		packet->header.value7 = val6;		\
-		packet->header.value8 = val7;		\
-	} while (0);
-
 struct asus_oled_header {
 	uint8_t		magic1;
 	uint8_t		magic2;
@@ -128,10 +119,10 @@ struct asus_oled_packet {
 } __attribute((packed));
 
 struct asus_oled_dev {
-	struct usb_device *	udev;
+	struct usb_device       *udev;
 	uint8_t			pic_mode;
 	uint16_t		dev_width;
-	oled_pack_mode_t	pack_mode;
+	enum oled_pack_mode	pack_mode;
 	size_t			height;
 	size_t			width;
 	size_t			x_shift;
@@ -144,12 +135,28 @@ struct asus_oled_dev {
 	struct device		*dev;
 };
 
+static void setup_packet_header(struct asus_oled_packet *packet, char flags,
+			 char value3, char buffer1, char buffer2, char value6,
+			 char value7, char value8)
+{
+	memset(packet, 0, sizeof(struct asus_oled_header));
+	packet->header.magic1 = 0x55;
+	packet->header.magic2 = 0xaa;
+	packet->header.flags = flags;
+	packet->header.value3 = value3;
+	packet->header.buffer1 = buffer1;
+	packet->header.buffer2 = buffer2;
+	packet->header.value6 = value6;
+	packet->header.value7 = value7;
+	packet->header.value8 = value8;
+}
+
 static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
 {
 	int a;
 	int retval;
 	int act_len;
-	struct asus_oled_packet * packet;
+	struct asus_oled_packet *packet;
 
 	packet = kzalloc(sizeof(struct asus_oled_packet), GFP_KERNEL);
 
@@ -158,7 +165,7 @@ static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
 		return;
 	}
 
-	SETUP_PACKET_HEADER(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
+	setup_packet_header(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
 
 	if (enabl)
 		packet->bitmap[0] = 0xaf;
@@ -182,29 +189,34 @@ static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
 	kfree(packet);
 }
 
-static ssize_t set_enabled(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_enabled(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct asus_oled_dev *odev = usb_get_intfdata(intf);
-	int temp = simple_strtoul(buf, NULL, 10);
+	int temp = strict_strtoul(buf, 10, NULL);
 
 	enable_oled(odev, temp);
 
 	return count;
 }
 
-static ssize_t class_set_enabled(struct device *device, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t class_set_enabled(struct device *device,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
-	struct asus_oled_dev *odev = (struct asus_oled_dev *) dev_get_drvdata(device);
+	struct asus_oled_dev *odev =
+		(struct asus_oled_dev *) dev_get_drvdata(device);
 
-	int temp = simple_strtoul(buf, NULL, 10);
+	int temp = strict_strtoul(buf, 10, NULL);
 
 	enable_oled(odev, temp);
 
 	return count;
 }
 
-static ssize_t get_enabled(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t get_enabled(struct device *dev, struct device_attribute *attr,
+			   char *buf)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 	struct asus_oled_dev *odev = usb_get_intfdata(intf);
@@ -212,15 +224,18 @@ static ssize_t get_enabled(struct device *dev, struct device_attribute *attr, ch
 	return sprintf(buf, "%d\n", odev->enabled);
 }
 
-static ssize_t class_get_enabled(struct device *device, struct device_attribute *attr, char *buf)
+static ssize_t class_get_enabled(struct device *device,
+				 struct device_attribute *attr, char *buf)
 {
-	struct asus_oled_dev *odev = (struct asus_oled_dev *) dev_get_drvdata(device);
+	struct asus_oled_dev *odev =
+		(struct asus_oled_dev *) dev_get_drvdata(device);
 
 	return sprintf(buf, "%d\n", odev->enabled);
 }
 
-static void send_packets(struct usb_device *udev, struct asus_oled_packet *packet,
-	char *buf, uint8_t p_type, size_t p_num)
+static void send_packets(struct usb_device *udev,
+			 struct asus_oled_packet *packet,
+			 char *buf, uint8_t p_type, size_t p_num)
 {
 	size_t i;
 	int act_len;
@@ -229,65 +244,76 @@ static void send_packets(struct usb_device *udev, struct asus_oled_packet *packe
 		int retval;
 
 		switch (p_type) {
-			case ASUS_OLED_ROLL:
-				SETUP_PACKET_HEADER(packet, 0x40, 0x80, p_num, i + 1, 0x00, 0x01, 0xff);
+		case ASUS_OLED_ROLL:
+			setup_packet_header(packet, 0x40, 0x80, p_num,
+					    i + 1, 0x00, 0x01, 0xff);
 			break;
-			case ASUS_OLED_STATIC:
-				SETUP_PACKET_HEADER(packet, 0x10 + i, 0x80, 0x01, 0x01, 0x00, 0x01, 0x00);
+		case ASUS_OLED_STATIC:
+			setup_packet_header(packet, 0x10 + i, 0x80, 0x01,
+					    0x01, 0x00, 0x01, 0x00);
 			break;
-			case ASUS_OLED_FLASH:
-				SETUP_PACKET_HEADER(packet, 0x10 + i, 0x80, 0x01, 0x01, 0x00, 0x00, 0xff);
+		case ASUS_OLED_FLASH:
+			setup_packet_header(packet, 0x10 + i, 0x80, 0x01,
+					    0x01, 0x00, 0x00, 0xff);
 			break;
 		}
 
-		memcpy(packet->bitmap, buf + (ASUS_OLED_PACKET_BUF_SIZE*i), ASUS_OLED_PACKET_BUF_SIZE);
+		memcpy(packet->bitmap, buf + (ASUS_OLED_PACKET_BUF_SIZE*i),
+		       ASUS_OLED_PACKET_BUF_SIZE);
 
-		retval = usb_bulk_msg(udev,
-			usb_sndctrlpipe(udev, 2),
-			packet,
-			sizeof(struct asus_oled_packet),
-			&act_len,
-			-1);
+		retval = usb_bulk_msg(udev, usb_sndctrlpipe(udev, 2),
+				      packet, sizeof(struct asus_oled_packet),
+				      &act_len, -1);
 
 		if (retval)
 			dev_dbg(&udev->dev, "retval = %d\n", retval);
 	}
 }
 
-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;
 
-	SETUP_PACKET_HEADER(packet, b1, b2, b3, b4, b5, b6, 0x00);
+	setup_packet_header(packet, b1, b2, b3, b4, b5, b6, 0x00);
 	memcpy(packet->bitmap, buf + offset, len);
 
 	retval = usb_bulk_msg(udev,
-			usb_sndctrlpipe(udev, 2),
-			packet,
-			sizeof(struct asus_oled_packet),
-			&act_len,
-			-1);
+			      usb_sndctrlpipe(udev, 2),
+			      packet,
+			      sizeof(struct asus_oled_packet),
+			      &act_len,
+			      -1);
 
 	if (retval)
 		dev_dbg(&udev->dev, "retval = %d\n", retval);
 }
 
 
-static void send_packets_g50(struct usb_device *udev, struct asus_oled_packet *packet, char *buf)
+static void send_packets_g50(struct usb_device *udev,
+			     struct asus_oled_packet *packet, char *buf)
 {
-	send_packet(udev, packet,     0, 0x100, buf, 0x10, 0x00, 0x02, 0x01, 0x00, 0x01);
-	send_packet(udev, packet, 0x100, 0x080, buf, 0x10, 0x00, 0x02, 0x02, 0x80, 0x00);
-
-	send_packet(udev, packet, 0x180, 0x100, buf, 0x11, 0x00, 0x03, 0x01, 0x00, 0x01);
-	send_packet(udev, packet, 0x280, 0x100, buf, 0x11, 0x00, 0x03, 0x02, 0x00, 0x01);
-	send_packet(udev, packet, 0x380, 0x080, buf, 0x11, 0x00, 0x03, 0x03, 0x80, 0x00);
+	send_packet(udev, packet,     0, 0x100, buf,
+		    0x10, 0x00, 0x02, 0x01, 0x00, 0x01);
+	send_packet(udev, packet, 0x100, 0x080, buf,
+		    0x10, 0x00, 0x02, 0x02, 0x80, 0x00);
+
+	send_packet(udev, packet, 0x180, 0x100, buf,
+		    0x11, 0x00, 0x03, 0x01, 0x00, 0x01);
+	send_packet(udev, packet, 0x280, 0x100, buf,
+		    0x11, 0x00, 0x03, 0x02, 0x00, 0x01);
+	send_packet(udev, packet, 0x380, 0x080, buf,
+		    0x11, 0x00, 0x03, 0x03, 0x80, 0x00);
 }
 
 
 static void send_data(struct asus_oled_dev *odev)
 {
 	size_t packet_num = odev->buf_size / ASUS_OLED_PACKET_BUF_SIZE;
-	struct asus_oled_packet * packet;
+	struct asus_oled_packet *packet;
 
 	packet = kzalloc(sizeof(struct asus_oled_packet), GFP_KERNEL);
 
@@ -297,20 +323,20 @@ static void send_data(struct asus_oled_dev *odev)
 	}
 
 	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.
+		/* When sending roll-mode data the display updated only
+		   first packet.  I have no idea why, but when static picture
+		   is sent just before rolling picture everything works fine. */
 		if (odev->pic_mode == ASUS_OLED_ROLL)
-			send_packets(odev->udev, packet, odev->buf, ASUS_OLED_STATIC, 2);
+			send_packets(odev->udev, packet, odev->buf,
+				     ASUS_OLED_STATIC, 2);
 
-		// Only ROLL mode can use more than 2 packets.
+		/* Only ROLL mode can use more than 2 packets.*/
 		if (odev->pic_mode != ASUS_OLED_ROLL && packet_num > 2)
 			packet_num = 2;
 
-		send_packets(odev->udev, packet, odev->buf, odev->pic_mode, packet_num);
-	}
-	else
-	if (odev->pack_mode == PACK_MODE_G50) {
+		send_packets(odev->udev, packet, odev->buf,
+			     odev->pic_mode, packet_num);
+	} else if (odev->pack_mode == PACK_MODE_G50) {
 		send_packets_g50(odev->udev, packet, odev->buf);
 	}
 
@@ -319,53 +345,55 @@ static void send_data(struct asus_oled_dev *odev)
 
 static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
 {
-	while (count-- > 0) {
-		if (val) {
-			size_t x = odev->buf_offs % odev->width;
-			size_t y = odev->buf_offs / odev->width;
-			size_t i;
-
-			x += odev->x_shift;
-			y += odev->y_shift;
-
-			switch (odev->pack_mode)
-			{
-				case PACK_MODE_G1:
-					// i = (x/128)*640 + 127 - x + (y/8)*128;
-					// This one for 128 is the same, but might be better for different widths?
-					i = (x/odev->dev_width)*640 + odev->dev_width - 1 - x + (y/8)*odev->dev_width;
-				break;
+	while (count-- > 0 && val) {
+		size_t x = odev->buf_offs % odev->width;
+		size_t y = odev->buf_offs / odev->width;
+		size_t i;
 
-				case PACK_MODE_G50:
-					i =  (odev->dev_width - 1 - x)/8 + y*odev->dev_width/8;
-				break;
+		x += odev->x_shift;
+		y += odev->y_shift;
+
+		switch (odev->pack_mode) {
+		case PACK_MODE_G1:
+			/* i = (x/128)*640 + 127 - x + (y/8)*128;
+			   This one for 128 is the same, but might be better
+			   for different widths? */
+			i = (x/odev->dev_width)*640 +
+				odev->dev_width - 1 - x +
+				(y/8)*odev->dev_width;
+			break;
 
-				default:
-					i = 0;
-					printk(ASUS_OLED_ERROR "Unknown OLED Pack Mode: %d!\n", odev->pack_mode);
-				break;
-			}
+		case PACK_MODE_G50:
+			i =  (odev->dev_width - 1 - x)/8 + y*odev->dev_width/8;
+			break;
 
-			if (i >= odev->buf_size) {
-				printk(ASUS_OLED_ERROR "Buffer overflow! Report a bug in the driver: offs: %d >= %d i: %d (x: %d y: %d)\n",
-					(int) odev->buf_offs, (int) odev->buf_size, (int) i, (int) x, (int) y);
-				return -EIO;
-			}
+		default:
+			i = 0;
+			printk(ASUS_OLED_ERROR "Unknown OLED Pack Mode: %d!\n",
+			       odev->pack_mode);
+			break;
+		}
 
-			switch (odev->pack_mode)
-			{
-				case PACK_MODE_G1:
-					odev->buf[i] &= ~(1<<(y%8));
-				break;
+		if (i >= odev->buf_size) {
+			printk(ASUS_OLED_ERROR "Buffer overflow! Report a bug:"
+			       "offs: %d >= %d i: %d (x: %d y: %d)\n",
+			       (int) odev->buf_offs, (int) odev->buf_size,
+			       (int) i, (int) x, (int) y);
+			return -EIO;
+		}
 
-				case PACK_MODE_G50:
-					odev->buf[i] &= ~(1<<(x%8));
-				break;
+		switch (odev->pack_mode) {
+		case PACK_MODE_G1:
+			odev->buf[i] &= ~(1<<(y%8));
+			break;
 
-				default:
-					// cannot get here; stops gcc complaining
-				;
-			}
+		case PACK_MODE_G50:
+			odev->buf[i] &= ~(1<<(x%8));
+			break;
+
+		default:
+			/* cannot get here; stops gcc complaining*/
+			;
 		}
 
 		odev->last_val = val;
@@ -375,7 +403,8 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
 	return 0;
 }
 
-static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, size_t count)
+static ssize_t odev_set_picture(struct asus_oled_dev *odev,
+				const char *buf, size_t count)
 {
 	size_t offs = 0, max_offs;
 
@@ -383,32 +412,31 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
 		return 0;
 
 	if (tolower(buf[0]) == 'b') {
-	    // binary mode, set the entire memory
+		/* binary mode, set the entire memory*/
 
-	    size_t i;
+		size_t i;
 
-	    odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
+		odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
 
-	    if (odev->buf)
-		    kfree(odev->buf);
-	    odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
+		kfree(odev->buf);
+		odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
 
-	    memset(odev->buf, 0xff, odev->buf_size);
+		memset(odev->buf, 0xff, odev->buf_size);
 
-	    for (i = 1; i < count && i <= 32 * 32; i++) {
-		odev->buf[i-1] = buf[i];
-		odev->buf_offs = i-1;
-	    }
+		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);
+		send_data(odev);
 
-	    return count;
+		return count;
 	}
 
 	if (buf[0] == '<') {
@@ -416,20 +444,21 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
 		size_t w = 0, h = 0;
 		size_t w_mem, h_mem;
 
-		if (count < 10 || buf[2] != ':') {
+		if (count < 10 || buf[2] != ':')
 			goto error_header;
-		}
+
 
 		switch (tolower(buf[1])) {
-			case ASUS_OLED_STATIC:
-			case ASUS_OLED_ROLL:
-			case ASUS_OLED_FLASH:
-				odev->pic_mode = buf[1];
-				break;
-			default:
-				printk(ASUS_OLED_ERROR "Wrong picture mode: '%c'.\n", buf[1]);
-				return -EIO;
-				break;
+		case ASUS_OLED_STATIC:
+		case ASUS_OLED_ROLL:
+		case ASUS_OLED_FLASH:
+			odev->pic_mode = buf[1];
+			break;
+		default:
+			printk(ASUS_OLED_ERROR "Wrong picture mode: '%c'.\n",
+			       buf[1]);
+			return -EIO;
+			break;
 		}
 
 		for (i = 3; i < count; ++i) {
@@ -438,11 +467,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
 
 				if (w > ASUS_OLED_MAX_WIDTH)
 					goto error_width;
-			}
-			else if (tolower(buf[i]) == 'x')
+			} else if (tolower(buf[i]) == 'x') {
 				break;
-			else
+			} else {
 				goto error_width;
+			}
 		}
 
 		for (++i; i < count; ++i) {
@@ -451,11 +480,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
 
 				if (h > ASUS_OLED_DISP_HEIGHT)
 					goto error_height;
-			}
-			else if (tolower(buf[i]) == '>')
+			} else if (tolower(buf[i]) == '>') {
 				break;
-			else
+			} else {
 				goto error_height;
+			}
 		}
 
 		if (w < 1 || w > ASUS_OLED_MAX_WIDTH)
@@ -481,8 +510,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
 
 		odev->buf_size = w_mem * h_mem / 8;
 
-		if (odev->buf)
-			kfree(odev->buf);
+		kfree(odev->buf);
 		odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
 
 		if (odev->buf == NULL) {
@@ -503,8 +531,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
 		if (odev->pic_mode == ASUS_OLED_FLASH) {
 			if (h < ASUS_OLED_DISP_HEIGHT/2)
 				odev->y_shift = (ASUS_OLED_DISP_HEIGHT/2 - h)/2;
-		}
-		else {
+		} else {
 			if (h < ASUS_OLED_DISP_HEIGHT)
 				odev->y_shift = (ASUS_OLED_DISP_HEIGHT - h)/2;
 		}
@@ -522,20 +549,21 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
 			ret = append_values(odev, 1, 1);
 			if (ret < 0)
 				return ret;
-		}
-		else if (buf[offs] == '0' || buf[offs] == ' ') {
+		} else if (buf[offs] == '0' || buf[offs] == ' ') {
 			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.
+		} 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)
 				ret = append_values(odev, odev->last_val,
-				      odev->width - (odev->buf_offs % odev->width));
-				if (ret < 0)
-					return ret;
+						    odev->width -
+						    (odev->buf_offs %
+						     odev->width));
+			if (ret < 0)
+				return ret;
 		}
 
 		offs++;
@@ -559,47 +587,52 @@ error_header:
 	return -EIO;
 }
 
-static ssize_t set_picture(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t set_picture(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
 {
 	struct usb_interface *intf = to_usb_interface(dev);
 
 	return odev_set_picture(usb_get_intfdata(intf), buf, count);
 }
 
-static ssize_t class_set_picture(struct device *device, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t class_set_picture(struct device *device,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
-	return odev_set_picture((struct asus_oled_dev *) dev_get_drvdata(device), buf, count);
+	return odev_set_picture((struct asus_oled_dev *)
+				dev_get_drvdata(device), buf, count);
 }
 
 #define ASUS_OLED_DEVICE_ATTR(_file)		dev_attr_asus_oled_##_file
 
-static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO, get_enabled, set_enabled);
+static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO,
+		   get_enabled, set_enabled);
 static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
 
-static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO, class_get_enabled, class_set_enabled);
+static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO,
+		   class_get_enabled, class_set_enabled);
 static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
 
-static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id)
+static int asus_oled_probe(struct usb_interface *interface,
+			   const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(interface);
 	struct asus_oled_dev *odev = NULL;
 	int retval = -ENOMEM;
 	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;
+	enum oled_pack_mode pack_mode = PACK_MODE_LAST;
+	const struct oled_dev_desc_str *dev_desc = oled_dev_desc_table;
 	const char *desc = NULL;
 
 	if (!id) {
-		// Even possible? Just to make sure...
+		/* Even possible? Just to make sure...*/
 		dev_err(&interface->dev, "No usb_device_id provided!\n");
 		return -ENODEV;
 	}
 
-	for (; dev_desc->idVendor; dev_desc++)
-	{
+	for (; dev_desc->idVendor; dev_desc++) {
 		if (dev_desc->idVendor == id->idVendor
-			&& dev_desc->idProduct == id->idProduct)
-		{
+		    && dev_desc->idProduct == id->idProduct) {
 			dev_width = dev_desc->devWidth;
 			desc = dev_desc->devDesc;
 			pack_mode = dev_desc->packMode;
@@ -608,7 +641,8 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
 	}
 
 	if (!desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
-		dev_err(&interface->dev, "Missing or incomplete device description!\n");
+		dev_err(&interface->dev,
+			"Missing or incomplete device description!\n");
 		return -ENODEV;
 	}
 
@@ -636,16 +670,18 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
 
 	usb_set_intfdata(interface, odev);
 
-	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;
 
-	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);
+				  NULL, "oled_%d", ++oled_num);
 
 	if (IS_ERR(odev->dev)) {
 		retval = PTR_ERR(odev->dev);
@@ -662,7 +698,9 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
 	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);
+	dev_info(&interface->dev,
+		 "Attached Asus OLED device: %s [width %u, pack_mode %d]\n",
+		 desc, odev->dev_width, odev->pack_mode);
 
 	if (start_off)
 		enable_oled(odev, 0);
@@ -703,8 +741,7 @@ static void asus_oled_disconnect(struct usb_interface *interface)
 
 	usb_put_dev(odev->udev);
 
-	if (odev->buf)
-		kfree(odev->buf);
+	kfree(odev->buf);
 
 	kfree(odev);
 
@@ -720,7 +757,8 @@ static struct usb_driver oled_driver = {
 
 static ssize_t version_show(struct class *dev, char *buf)
 {
-	return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n", ASUS_OLED_VERSION);
+	return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n",
+		       ASUS_OLED_VERSION);
 }
 
 static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
diff --git a/drivers/staging/at76_usb/Kconfig b/drivers/staging/at76_usb/Kconfig
deleted file mode 100644
index 8606f96..0000000
--- a/drivers/staging/at76_usb/Kconfig
+++ /dev/null
@@ -1,8 +0,0 @@
-config USB_ATMEL
-	tristate "Atmel at76c503/at76c505/at76c505a USB cards"
-	depends on WLAN_80211 && USB
-	default N
-	select FW_LOADER
-	---help---
-	  Enable support for USB Wireless devices using Atmel at76c503,
-	  at76c505 or at76c505a chips.
diff --git a/drivers/staging/at76_usb/Makefile b/drivers/staging/at76_usb/Makefile
deleted file mode 100644
index 6a47e88..0000000
--- a/drivers/staging/at76_usb/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_USB_ATMEL)		+= at76_usb.o
diff --git a/drivers/staging/at76_usb/TODO b/drivers/staging/at76_usb/TODO
deleted file mode 100644
index 0c7ed21..0000000
--- a/drivers/staging/at76_usb/TODO
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 3f303ae..0000000
--- a/drivers/staging/at76_usb/at76_usb.c
+++ /dev/null
@@ -1,5579 +0,0 @@
-/*
- * at76c503/at76c505 USB driver
- *
- * Copyright (c) 2002 - 2003 Oliver Kurth
- * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
- * Copyright (c) 2004 Nick Jones
- * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
- * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.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 file is part of the Berlios driver for WLAN USB devices based on the
- * Atmel AT76C503A/505/505A.
- *
- * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/usb.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <net/ieee80211_radiotap.h>
-#include <linux/firmware.h>
-#include <linux/leds.h>
-#include <linux/ieee80211.h>
-
-#include "at76_usb.h"
-
-/* Version information */
-#define DRIVER_NAME "at76_usb"
-#define DRIVER_VERSION	"0.17"
-#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
-
-/* at76_debug bits */
-#define DBG_PROGRESS		0x00000001	/* authentication/accociation */
-#define DBG_BSS_TABLE		0x00000002	/* show BSS table after scans */
-#define DBG_IOCTL		0x00000004	/* ioctl calls / settings */
-#define DBG_MAC_STATE		0x00000008	/* MAC state transitions */
-#define DBG_TX_DATA		0x00000010	/* tx header */
-#define DBG_TX_DATA_CONTENT	0x00000020	/* tx content */
-#define DBG_TX_MGMT		0x00000040	/* tx management */
-#define DBG_RX_DATA		0x00000080	/* rx data header */
-#define DBG_RX_DATA_CONTENT	0x00000100	/* rx data content */
-#define DBG_RX_MGMT		0x00000200	/* rx mgmt frame headers */
-#define DBG_RX_BEACON		0x00000400	/* rx beacon */
-#define DBG_RX_CTRL		0x00000800	/* rx control */
-#define DBG_RX_MGMT_CONTENT	0x00001000	/* rx mgmt content */
-#define DBG_RX_FRAGS		0x00002000	/* rx data fragment handling */
-#define DBG_DEVSTART		0x00004000	/* fw download, device start */
-#define DBG_URB			0x00008000	/* rx urb status, ... */
-#define DBG_RX_ATMEL_HDR	0x00010000	/* Atmel-specific Rx headers */
-#define DBG_PROC_ENTRY		0x00020000	/* procedure entries/exits */
-#define DBG_PM			0x00040000	/* power management settings */
-#define DBG_BSS_MATCH		0x00080000	/* BSS match failures */
-#define DBG_PARAMS		0x00100000	/* show configured parameters */
-#define DBG_WAIT_COMPLETE	0x00200000	/* command completion */
-#define DBG_RX_FRAGS_SKB	0x00400000	/* skb header of Rx fragments */
-#define DBG_BSS_TABLE_RM	0x00800000	/* purging bss table entries */
-#define DBG_MONITOR_MODE	0x01000000	/* monitor mode */
-#define DBG_MIB			0x02000000	/* dump all MIBs on startup */
-#define DBG_MGMT_TIMER		0x04000000	/* dump mgmt_timer ops */
-#define DBG_WE_EVENTS		0x08000000	/* dump wireless events */
-#define DBG_FW			0x10000000	/* firmware download */
-#define DBG_DFU			0x20000000	/* device firmware upgrade */
-
-#define DBG_DEFAULTS		0
-
-/* Use our own dbg macro */
-#define at76_dbg(bits, format, arg...) \
-	do { \
-		if (at76_debug & (bits)) \
-		printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
-	} while (0)
-
-static int at76_debug = DBG_DEFAULTS;
-
-/* Protect against concurrent firmware loading and parsing */
-static struct mutex fw_mutex;
-
-static struct fwentry firmwares[] = {
-	[0] = {""},
-	[BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"},
-	[BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"},
-	[BOARD_503] = {"atmel_at76c503-rfmd.bin"},
-	[BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"},
-	[BOARD_505] = {"atmel_at76c505-rfmd.bin"},
-	[BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"},
-	[BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"},
-	[BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"},
-};
-
-#define USB_DEVICE_DATA(__ops)	.driver_info = (kernel_ulong_t)(__ops)
-
-static struct usb_device_id dev_table[] = {
-	/*
-	 * at76c503-i3861
-	 */
-	/* Generic AT76C503/3861 device */
-	{USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Linksys WUSB11 v2.1/v2.6 */
-	{USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Netgear MA101 rev. A */
-	{USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Tekram U300C / Allnet ALL0193 */
-	{USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* HP HN210W J7801A */
-	{USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Sitecom/Z-Com/Zyxel M4Y-750 */
-	{USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Dynalink/Askey WLL013 (intersil) */
-	{USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
-	{USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* BenQ AWL300 */
-	{USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Addtron AWU-120, Compex WLU11 */
-	{USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Intel AP310 AnyPoint II USB */
-	{USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Dynalink L11U */
-	{USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* Arescom WL-210, FCC id 07J-GL2411USB */
-	{USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* I-O DATA WN-B11/USB */
-	{USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/* BT Voyager 1010 */
-	{USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)},
-	/*
-	 * at76c503-i3863
-	 */
-	/* Generic AT76C503/3863 device */
-	{USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)},
-	/* Samsung SWL-2100U */
-	{USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)},
-	/*
-	 * at76c503-rfmd
-	 */
-	/* Generic AT76C503/RFMD device */
-	{USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)},
-	/* Dynalink/Askey WLL013 (rfmd) */
-	{USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)},
-	/* Linksys WUSB11 v2.6 */
-	{USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)},
-	/* Network Everywhere NWU11B */
-	{USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)},
-	/* Netgear MA101 rev. B */
-	{USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)},
-	/* D-Link DWL-120 rev. E */
-	{USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)},
-	/* Actiontec 802UAT1, HWU01150-01UK */
-	{USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)},
-	/* AirVast W-Buddie WN210 */
-	{USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)},
-	/* Dick Smith Electronics XH1153 802.11b USB adapter */
-	{USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)},
-	/* CNet CNUSB611 */
-	{USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)},
-	/* FiberLine FL-WL200U */
-	{USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)},
-	/* BenQ AWL400 USB stick */
-	{USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)},
-	/* 3Com 3CRSHEW696 */
-	{USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)},
-	/* Siemens Santis ADSL WLAN USB adapter WLL 013 */
-	{USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)},
-	/* Belkin F5D6050, version 2 */
-	{USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)},
-	/* iBlitzz, BWU613 (not *B or *SB) */
-	{USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)},
-	/* Gigabyte GN-WLBM101 */
-	{USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)},
-	/* Planex GW-US11S */
-	{USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)},
-	/* Internal WLAN adapter in h5[4,5]xx series iPAQs */
-	{USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)},
-	/* Corega Wireless LAN USB-11 mini */
-	{USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)},
-	/* Corega Wireless LAN USB-11 mini2 */
-	{USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)},
-	/* Uniden PCW100 */
-	{USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)},
-	/*
-	 * at76c503-rfmd-acc
-	 */
-	/* SMC2664W */
-	{USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)},
-	/* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
-	{USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)},
-	/*
-	 * at76c505-rfmd
-	 */
-	/* Generic AT76C505/RFMD */
-	{USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
-	/*
-	 * at76c505-rfmd2958
-	 */
-	/* Generic AT76C505/RFMD, OvisLink WL-1130USB */
-	{USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
-	/* Fiberline FL-WL240U */
-	{USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)},
-	/* CNet CNUSB-611G */
-	{USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)},
-	/* Linksys WUSB11 v2.8 */
-	{USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)},
-	/* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
-	{USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)},
-	/* Corega WLAN USB Stick 11 */
-	{USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
-	/* Microstar MSI Box MS6978 */
-	{USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)},
-	/*
-	 * at76c505a-rfmd2958
-	 */
-	/* Generic AT76C505A device */
-	{USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)},
-	/* Generic AT76C505AS device */
-	{USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)},
-	/* Siemens Gigaset USB WLAN Adapter 11 */
-	{USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)},
-	/* OQO Model 01+ Internal Wi-Fi */
-	{USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)},
-	/*
-	 * at76c505amx-rfmd
-	 */
-	/* Generic AT76C505AMX device */
-	{USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
-	{}
-};
-
-MODULE_DEVICE_TABLE(usb, dev_table);
-
-/* Supported rates of this hardware, bit 7 marks basic rates */
-static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
-
-/* Frequency of each channel in MHz */
-static const long channel_frequency[] = {
-	2412, 2417, 2422, 2427, 2432, 2437, 2442,
-	2447, 2452, 2457, 2462, 2467, 2472, 2484
-};
-
-#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
-
-static const char *const preambles[] = { "long", "short", "auto" };
-
-static const char *const mac_states[] = {
-	[MAC_INIT] = "INIT",
-	[MAC_SCANNING] = "SCANNING",
-	[MAC_AUTH] = "AUTH",
-	[MAC_ASSOC] = "ASSOC",
-	[MAC_JOINING] = "JOINING",
-	[MAC_CONNECTED] = "CONNECTED",
-	[MAC_OWN_IBSS] = "OWN_IBSS"
-};
-
-/* Firmware download */
-/* DFU states */
-#define STATE_IDLE			0x00
-#define STATE_DETACH			0x01
-#define STATE_DFU_IDLE			0x02
-#define STATE_DFU_DOWNLOAD_SYNC		0x03
-#define STATE_DFU_DOWNLOAD_BUSY		0x04
-#define STATE_DFU_DOWNLOAD_IDLE		0x05
-#define STATE_DFU_MANIFEST_SYNC		0x06
-#define STATE_DFU_MANIFEST		0x07
-#define STATE_DFU_MANIFEST_WAIT_RESET	0x08
-#define STATE_DFU_UPLOAD_IDLE		0x09
-#define STATE_DFU_ERROR			0x0a
-
-/* DFU commands */
-#define DFU_DETACH			0
-#define DFU_DNLOAD			1
-#define DFU_UPLOAD			2
-#define DFU_GETSTATUS			3
-#define DFU_CLRSTATUS			4
-#define DFU_GETSTATE			5
-#define DFU_ABORT			6
-
-#define FW_BLOCK_SIZE 1024
-
-struct dfu_status {
-	unsigned char status;
-	unsigned char poll_timeout[3];
-	unsigned char state;
-	unsigned char string;
-} __attribute__((packed));
-
-static inline int at76_is_intersil(enum board_type board)
-{
-	return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
-}
-
-static inline int at76_is_503rfmd(enum board_type board)
-{
-	return (board == BOARD_503 || board == BOARD_503_ACC);
-}
-
-static inline int at76_is_505a(enum board_type board)
-{
-	return (board == BOARD_505A || board == BOARD_505AMX);
-}
-
-/* Load a block of the first (internal) part of the firmware */
-static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
-				  void *block, int size)
-{
-	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
-			       USB_TYPE_CLASS | USB_DIR_OUT |
-			       USB_RECIP_INTERFACE, blockno, 0, block, size,
-			       USB_CTRL_GET_TIMEOUT);
-}
-
-static int at76_dfu_get_status(struct usb_device *udev,
-			       struct dfu_status *status)
-{
-	int ret;
-
-	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
-			      USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
-			      0, 0, status, sizeof(struct dfu_status),
-			      USB_CTRL_GET_TIMEOUT);
-	return ret;
-}
-
-static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
-{
-	int ret;
-
-	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
-			      USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
-			      0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
-	return ret;
-}
-
-/* Convert timeout from the DFU status to jiffies */
-static inline unsigned long at76_get_timeout(struct dfu_status *s)
-{
-	return msecs_to_jiffies((s->poll_timeout[2] << 16)
-				| (s->poll_timeout[1] << 8)
-				| (s->poll_timeout[0]));
-}
-
-/* Load internal firmware from the buffer.  If manifest_sync_timeout > 0, use
- * its value in jiffies in the MANIFEST_SYNC state.  */
-static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
-				int manifest_sync_timeout)
-{
-	u8 *block;
-	struct dfu_status dfu_stat_buf;
-	int ret = 0;
-	int need_dfu_state = 1;
-	int is_done = 0;
-	u8 dfu_state = 0;
-	u32 dfu_timeout = 0;
-	int bsize = 0;
-	int blockno = 0;
-
-	at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
-		 manifest_sync_timeout);
-
-	if (!size) {
-		dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
-		return -EINVAL;
-	}
-
-	block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
-	if (!block)
-		return -ENOMEM;
-
-	do {
-		if (need_dfu_state) {
-			ret = at76_dfu_get_state(udev, &dfu_state);
-			if (ret < 0) {
-				dev_printk(KERN_ERR, &udev->dev,
-					   "cannot get DFU state: %d\n", ret);
-				goto exit;
-			}
-			need_dfu_state = 0;
-		}
-
-		switch (dfu_state) {
-		case STATE_DFU_DOWNLOAD_SYNC:
-			at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
-			ret = at76_dfu_get_status(udev, &dfu_stat_buf);
-			if (ret >= 0) {
-				dfu_state = dfu_stat_buf.state;
-				dfu_timeout = at76_get_timeout(&dfu_stat_buf);
-				need_dfu_state = 0;
-			} else
-				dev_printk(KERN_ERR, &udev->dev,
-					   "at76_dfu_get_status returned %d\n",
-					   ret);
-			break;
-
-		case STATE_DFU_DOWNLOAD_BUSY:
-			at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
-			need_dfu_state = 1;
-
-			at76_dbg(DBG_DFU, "DFU: Resetting device");
-			schedule_timeout_interruptible(dfu_timeout);
-			break;
-
-		case STATE_DFU_DOWNLOAD_IDLE:
-			at76_dbg(DBG_DFU, "DOWNLOAD...");
-			/* fall through */
-		case STATE_DFU_IDLE:
-			at76_dbg(DBG_DFU, "DFU IDLE");
-
-			bsize = min_t(int, size, FW_BLOCK_SIZE);
-			memcpy(block, buf, bsize);
-			at76_dbg(DBG_DFU, "int fw, size left = %5d, "
-				 "bsize = %4d, blockno = %2d", size, bsize,
-				 blockno);
-			ret =
-			    at76_load_int_fw_block(udev, blockno, block, bsize);
-			buf += bsize;
-			size -= bsize;
-			blockno++;
-
-			if (ret != bsize)
-				dev_printk(KERN_ERR, &udev->dev,
-					   "at76_load_int_fw_block "
-					   "returned %d\n", ret);
-			need_dfu_state = 1;
-			break;
-
-		case STATE_DFU_MANIFEST_SYNC:
-			at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
-
-			ret = at76_dfu_get_status(udev, &dfu_stat_buf);
-			if (ret < 0)
-				break;
-
-			dfu_state = dfu_stat_buf.state;
-			dfu_timeout = at76_get_timeout(&dfu_stat_buf);
-			need_dfu_state = 0;
-
-			/* override the timeout from the status response,
-			   needed for AT76C505A */
-			if (manifest_sync_timeout > 0)
-				dfu_timeout = manifest_sync_timeout;
-
-			at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
-			schedule_timeout_interruptible(dfu_timeout);
-			break;
-
-		case STATE_DFU_MANIFEST:
-			at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
-			is_done = 1;
-			break;
-
-		case STATE_DFU_MANIFEST_WAIT_RESET:
-			at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
-			is_done = 1;
-			break;
-
-		case STATE_DFU_UPLOAD_IDLE:
-			at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
-			break;
-
-		case STATE_DFU_ERROR:
-			at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
-			ret = -EPIPE;
-			break;
-
-		default:
-			at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
-			ret = -EINVAL;
-			break;
-		}
-	} while (!is_done && (ret >= 0));
-
-exit:
-	kfree(block);
-	if (ret >= 0)
-		ret = 0;
-
-	return ret;
-}
-
-/* Report that the scan results are ready */
-static inline void at76_iwevent_scan_complete(struct net_device *netdev)
-{
-	union iwreq_data wrqu;
-	wrqu.data.length = 0;
-	wrqu.data.flags = 0;
-	wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL);
-	at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name);
-}
-
-static inline void at76_iwevent_bss_connect(struct net_device *netdev,
-					    u8 *bssid)
-{
-	union iwreq_data wrqu;
-	wrqu.data.length = 0;
-	wrqu.data.flags = 0;
-	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
-	at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
-		 __func__);
-}
-
-static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
-{
-	union iwreq_data wrqu;
-	wrqu.data.length = 0;
-	wrqu.data.flags = 0;
-	memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
-	at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
-		 __func__);
-}
-
-#define HEX2STR_BUFFERS 4
-#define HEX2STR_MAX_LEN 64
-#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
-
-/* Convert binary data into hex string */
-static char *hex2str(void *buf, int len)
-{
-	static atomic_t a = ATOMIC_INIT(0);
-	static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
-	char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
-	char *obuf = ret;
-	u8 *ibuf = buf;
-
-	if (len > HEX2STR_MAX_LEN)
-		len = HEX2STR_MAX_LEN;
-
-	if (len <= 0) {
-		ret[0] = '\0';
-		return ret;
-	}
-
-	while (len--) {
-		*obuf++ = BIN2HEX(*ibuf >> 4);
-		*obuf++ = BIN2HEX(*ibuf & 0xf);
-		*obuf++ = '-';
-		ibuf++;
-	}
-	*(--obuf) = '\0';
-
-	return ret;
-}
-
-#define MAC2STR_BUFFERS 4
-
-static inline char *mac2str(u8 *mac)
-{
-	static atomic_t a = ATOMIC_INIT(0);
-	static char bufs[MAC2STR_BUFFERS][6 * 3];
-	char *str;
-
-	str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
-	sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
-		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-	return str;
-}
-
-/* LED trigger */
-static int tx_activity;
-static void at76_ledtrig_tx_timerfunc(unsigned long data);
-static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
-DEFINE_LED_TRIGGER(ledtrig_tx);
-
-static void at76_ledtrig_tx_timerfunc(unsigned long data)
-{
-	static int tx_lastactivity;
-
-	if (tx_lastactivity != tx_activity) {
-		tx_lastactivity = tx_activity;
-		led_trigger_event(ledtrig_tx, LED_FULL);
-		mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
-	} else
-		led_trigger_event(ledtrig_tx, LED_OFF);
-}
-
-static void at76_ledtrig_tx_activity(void)
-{
-	tx_activity++;
-	if (!timer_pending(&ledtrig_tx_timer))
-		mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
-}
-
-/* Check if the given ssid is hidden */
-static inline int at76_is_hidden_ssid(u8 *ssid, int length)
-{
-	static const u8 zeros[32];
-
-	if (length == 0)
-		return 1;
-
-	if (length == 1 && ssid[0] == ' ')
-		return 1;
-
-	return (memcmp(ssid, zeros, length) == 0);
-}
-
-static inline void at76_free_bss_list(struct at76_priv *priv)
-{
-	struct list_head *next, *ptr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->bss_list_spinlock, flags);
-
-	priv->curr_bss = NULL;
-
-	list_for_each_safe(ptr, next, &priv->bss_list) {
-		list_del(ptr);
-		kfree(list_entry(ptr, struct bss_info, list));
-	}
-
-	spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
-}
-
-static int at76_remap(struct usb_device *udev)
-{
-	int ret;
-	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
-			      USB_TYPE_VENDOR | USB_DIR_OUT |
-			      USB_RECIP_INTERFACE, 0, 0, NULL, 0,
-			      USB_CTRL_GET_TIMEOUT);
-	if (ret < 0)
-		return ret;
-	return 0;
-}
-
-static int at76_get_op_mode(struct usb_device *udev)
-{
-	int ret;
-	u8 saved;
-	u8 *op_mode;
-
-	op_mode = kmalloc(1, GFP_NOIO);
-	if (!op_mode)
-		return -ENOMEM;
-	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-			      USB_TYPE_VENDOR | USB_DIR_IN |
-			      USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
-			      USB_CTRL_GET_TIMEOUT);
-	saved = *op_mode;
-	kfree(op_mode);
-
-	if (ret < 0)
-		return ret;
-	else if (ret < 1)
-		return -EIO;
-	else
-		return saved;
-}
-
-/* Load a block of the second ("external") part of the firmware */
-static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
-					 void *block, int size)
-{
-	return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
-			       USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
-			       0x0802, blockno, block, size,
-			       USB_CTRL_GET_TIMEOUT);
-}
-
-static inline int at76_get_hw_cfg(struct usb_device *udev,
-				  union at76_hwcfg *buf, int buf_size)
-{
-	return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-			       USB_TYPE_VENDOR | USB_DIR_IN |
-			       USB_RECIP_INTERFACE, 0x0a02, 0,
-			       buf, buf_size, USB_CTRL_GET_TIMEOUT);
-}
-
-/* Intersil boards use a different "value" for GetHWConfig requests */
-static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
-					   union at76_hwcfg *buf, int buf_size)
-{
-	return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-			       USB_TYPE_VENDOR | USB_DIR_IN |
-			       USB_RECIP_INTERFACE, 0x0902, 0,
-			       buf, buf_size, USB_CTRL_GET_TIMEOUT);
-}
-
-/* Get the hardware configuration for the adapter and put it to the appropriate
- * fields of 'priv' (the GetHWConfig request and interpretation of the result
- * depends on the board type) */
-static int at76_get_hw_config(struct at76_priv *priv)
-{
-	int ret;
-	union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
-
-	if (!hwcfg)
-		return -ENOMEM;
-
-	if (at76_is_intersil(priv->board_type)) {
-		ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
-					       sizeof(hwcfg->i));
-		if (ret < 0)
-			goto exit;
-		memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
-		priv->regulatory_domain = hwcfg->i.regulatory_domain;
-	} else if (at76_is_503rfmd(priv->board_type)) {
-		ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
-		if (ret < 0)
-			goto exit;
-		memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
-		priv->regulatory_domain = hwcfg->r3.regulatory_domain;
-	} else {
-		ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
-		if (ret < 0)
-			goto exit;
-		memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
-		priv->regulatory_domain = hwcfg->r5.regulatory_domain;
-	}
-
-exit:
-	kfree(hwcfg);
-	if (ret < 0)
-		printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-static struct reg_domain const *at76_get_reg_domain(u16 code)
-{
-	int i;
-	static struct reg_domain const fd_tab[] = {
-		{0x10, "FCC (USA)", 0x7ff},	/* ch 1-11 */
-		{0x20, "IC (Canada)", 0x7ff},	/* ch 1-11 */
-		{0x30, "ETSI (most of Europe)", 0x1fff},	/* ch 1-13 */
-		{0x31, "Spain", 0x600},	/* ch 10-11 */
-		{0x32, "France", 0x1e00},	/* ch 10-13 */
-		{0x40, "MKK (Japan)", 0x2000},	/* ch 14 */
-		{0x41, "MKK1 (Japan)", 0x3fff},	/* ch 1-14 */
-		{0x50, "Israel", 0x3fc},	/* ch 3-9 */
-		{0x00, "<unknown>", 0xffffffff}	/* ch 1-32 */
-	};
-
-	/* Last entry is fallback for unknown domain code */
-	for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
-		if (code == fd_tab[i].code)
-			break;
-
-	return &fd_tab[i];
-}
-
-static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
-			       int buf_size)
-{
-	int ret;
-
-	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
-			      USB_TYPE_VENDOR | USB_DIR_IN |
-			      USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
-			      USB_CTRL_GET_TIMEOUT);
-	if (ret >= 0 && ret != buf_size)
-		return -EIO;
-	return ret;
-}
-
-/* Return positive number for status, negative for an error */
-static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
-{
-	u8 *stat_buf;
-	int ret;
-
-	stat_buf = kmalloc(40, GFP_NOIO);
-	if (!stat_buf)
-		return -ENOMEM;
-
-	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
-			      USB_TYPE_VENDOR | USB_DIR_IN |
-			      USB_RECIP_INTERFACE, cmd, 0, stat_buf,
-			      40, USB_CTRL_GET_TIMEOUT);
-	if (ret >= 0)
-		ret = stat_buf[5];
-	kfree(stat_buf);
-
-	return ret;
-}
-
-static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
-				 int buf_size)
-{
-	int ret;
-	struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
-					       buf_size, GFP_KERNEL);
-
-	if (!cmd_buf)
-		return -ENOMEM;
-
-	cmd_buf->cmd = cmd;
-	cmd_buf->reserved = 0;
-	cmd_buf->size = cpu_to_le16(buf_size);
-	memcpy(cmd_buf->data, buf, buf_size);
-
-	ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
-			      USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
-			      0, 0, cmd_buf,
-			      sizeof(struct at76_command) + buf_size,
-			      USB_CTRL_GET_TIMEOUT);
-	kfree(cmd_buf);
-	return ret;
-}
-
-#define MAKE_CMD_STATUS_CASE(c)	case (c): return #c
-static const char *at76_get_cmd_status_string(u8 cmd_status)
-{
-	switch (cmd_status) {
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
-		MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
-	}
-
-	return "UNKNOWN";
-}
-
-/* Wait until the command is completed */
-static int at76_wait_completion(struct at76_priv *priv, int cmd)
-{
-	int status = 0;
-	unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
-
-	do {
-		status = at76_get_cmd_status(priv->udev, cmd);
-		if (status < 0) {
-			printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
-			       priv->netdev->name, status);
-			break;
-		}
-
-		at76_dbg(DBG_WAIT_COMPLETE,
-			 "%s: Waiting on cmd %d, status = %d (%s)",
-			 priv->netdev->name, cmd, status,
-			 at76_get_cmd_status_string(status));
-
-		if (status != CMD_STATUS_IN_PROGRESS
-		    && status != CMD_STATUS_IDLE)
-			break;
-
-		schedule_timeout_interruptible(HZ / 10);	/* 100 ms */
-		if (time_after(jiffies, timeout)) {
-			printk(KERN_ERR
-			       "%s: completion timeout for command %d\n",
-			       priv->netdev->name, cmd);
-			status = -ETIMEDOUT;
-			break;
-		}
-	} while (1);
-
-	return status;
-}
-
-static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
-{
-	int ret;
-
-	ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
-				    offsetof(struct set_mib_buffer,
-					     data) + buf->size);
-	if (ret < 0)
-		return ret;
-
-	ret = at76_wait_completion(priv, CMD_SET_MIB);
-	if (ret != CMD_STATUS_COMPLETE) {
-		printk(KERN_INFO
-		       "%s: set_mib: at76_wait_completion failed "
-		       "with %d\n", priv->netdev->name, ret);
-		ret = -EIO;
-	}
-
-	return ret;
-}
-
-/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
-static int at76_set_radio(struct at76_priv *priv, int enable)
-{
-	int ret;
-	int cmd;
-
-	if (priv->radio_on == enable)
-		return 0;
-
-	cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
-
-	ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
-	if (ret < 0)
-		printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
-		       priv->netdev->name, cmd, ret);
-	else
-		ret = 1;
-
-	priv->radio_on = enable;
-	return ret;
-}
-
-/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
-static int at76_set_pm_mode(struct at76_priv *priv)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_MAC_MGMT;
-	priv->mib_buf.size = 1;
-	priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
-	priv->mib_buf.data.byte = priv->pm_mode;
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-/* Set the association id for power save mode */
-static int at76_set_associd(struct at76_priv *priv, u16 id)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_MAC_MGMT;
-	priv->mib_buf.size = 2;
-	priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
-	priv->mib_buf.data.word = cpu_to_le16(id);
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-/* Set the listen interval for power save mode */
-static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_MAC;
-	priv->mib_buf.size = 2;
-	priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
-	priv->mib_buf.data.word = cpu_to_le16(interval);
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR
-		       "%s: set_mib (listen_interval) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-static int at76_set_preamble(struct at76_priv *priv, u8 type)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_LOCAL;
-	priv->mib_buf.size = 1;
-	priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
-	priv->mib_buf.data.byte = type;
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-static int at76_set_frag(struct at76_priv *priv, u16 size)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_MAC;
-	priv->mib_buf.size = 2;
-	priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
-	priv->mib_buf.data.word = cpu_to_le16(size);
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-static int at76_set_rts(struct at76_priv *priv, u16 size)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_MAC;
-	priv->mib_buf.size = 2;
-	priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
-	priv->mib_buf.data.word = cpu_to_le16(size);
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_LOCAL;
-	priv->mib_buf.size = 1;
-	priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
-	priv->mib_buf.data.byte = onoff;
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-static int at76_add_mac_address(struct at76_priv *priv, void *addr)
-{
-	int ret = 0;
-
-	priv->mib_buf.type = MIB_MAC_ADDR;
-	priv->mib_buf.size = ETH_ALEN;
-	priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
-	memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	return ret;
-}
-
-static void at76_dump_mib_mac_addr(struct at76_priv *priv)
-{
-	int i;
-	int ret;
-	struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
-					 GFP_KERNEL);
-
-	if (!m)
-		return;
-
-	ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
-			   sizeof(struct mib_mac_addr));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
-		 priv->netdev->name,
-		 mac2str(m->mac_addr), m->res[0], m->res[1]);
-	for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
-		at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
-			 "status %d", priv->netdev->name, i,
-			 mac2str(m->group_addr[i]), m->group_addr_status[i]);
-exit:
-	kfree(m);
-}
-
-static void at76_dump_mib_mac_wep(struct at76_priv *priv)
-{
-	int i;
-	int ret;
-	int key_len;
-	struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
-
-	if (!m)
-		return;
-
-	ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
-			   sizeof(struct mib_mac_wep));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
-		 "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
-		 "encr_level %u key %d", priv->netdev->name,
-		 m->privacy_invoked, m->wep_default_key_id,
-		 m->wep_key_mapping_len, m->exclude_unencrypted,
-		 le32_to_cpu(m->wep_icv_error_count),
-		 le32_to_cpu(m->wep_excluded_count), m->encryption_level,
-		 m->wep_default_key_id);
-
-	key_len = (m->encryption_level == 1) ?
-	    WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
-
-	for (i = 0; i < WEP_KEYS; i++)
-		at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
-			 priv->netdev->name, i,
-			 hex2str(m->wep_default_keyvalue[i], key_len));
-exit:
-	kfree(m);
-}
-
-static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
-{
-	int ret;
-	struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
-					 GFP_KERNEL);
-
-	if (!m)
-		return;
-
-	ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
-			   sizeof(struct mib_mac_mgmt));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
-		 "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
-		 "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
-		 "current_bssid %s current_essid %s current_bss_type %d "
-		 "pm_mode %d ibss_change %d res %d "
-		 "multi_domain_capability_implemented %d "
-		 "international_roaming %d country_string %.3s",
-		 priv->netdev->name, le16_to_cpu(m->beacon_period),
-		 le16_to_cpu(m->CFP_max_duration),
-		 le16_to_cpu(m->medium_occupancy_limit),
-		 le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
-		 m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
-		 m->CFP_period, mac2str(m->current_bssid),
-		 hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
-		 m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
-		 m->res, m->multi_domain_capability_implemented,
-		 m->multi_domain_capability_enabled, m->country_string);
-exit:
-	kfree(m);
-}
-
-static void at76_dump_mib_mac(struct at76_priv *priv)
-{
-	int ret;
-	struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
-
-	if (!m)
-		return;
-
-	ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
-		 "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
-		 "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
-		 "scan_type %d scan_channel %d probe_delay %u "
-		 "min_channel_time %d max_channel_time %d listen_int %d "
-		 "desired_ssid %s desired_bssid %s desired_bsstype %d",
-		 priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime),
-		 le32_to_cpu(m->max_rx_lifetime),
-		 le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
-		 le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
-		 m->short_retry_time, m->long_retry_time, m->scan_type,
-		 m->scan_channel, le16_to_cpu(m->probe_delay),
-		 le16_to_cpu(m->min_channel_time),
-		 le16_to_cpu(m->max_channel_time),
-		 le16_to_cpu(m->listen_interval),
-		 hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
-		 mac2str(m->desired_bssid), m->desired_bsstype);
-exit:
-	kfree(m);
-}
-
-static void at76_dump_mib_phy(struct at76_priv *priv)
-{
-	int ret;
-	struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
-
-	if (!m)
-		return;
-
-	ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
-		 "sifs_time %d preamble_length %d plcp_header_length %d "
-		 "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
-		 "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
-		 "phy_type %d current_reg_domain %d",
-		 priv->netdev->name, le32_to_cpu(m->ed_threshold),
-		 le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
-		 le16_to_cpu(m->preamble_length),
-		 le16_to_cpu(m->plcp_header_length),
-		 le16_to_cpu(m->mpdu_max_length),
-		 le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
-		 m->operation_rate_set[1], m->operation_rate_set[2],
-		 m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
-		 m->phy_type, m->current_reg_domain);
-exit:
-	kfree(m);
-}
-
-static void at76_dump_mib_local(struct at76_priv *priv)
-{
-	int ret;
-	struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
-
-	if (!m)
-		return;
-
-	ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
-		 "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
-		 "preamble_type %d", priv->netdev->name, m->beacon_enable,
-		 m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
-		 m->preamble_type);
-exit:
-	kfree(m);
-}
-
-static void at76_dump_mib_mdomain(struct at76_priv *priv)
-{
-	int ret;
-	struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
-
-	if (!m)
-		return;
-
-	ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
-			   sizeof(struct mib_mdomain));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
-		 priv->netdev->name,
-		 hex2str(m->channel_list, sizeof(m->channel_list)));
-
-	at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
-		 priv->netdev->name,
-		 hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
-exit:
-	kfree(m);
-}
-
-static int at76_get_current_bssid(struct at76_priv *priv)
-{
-	int ret = 0;
-	struct mib_mac_mgmt *mac_mgmt =
-	    kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
-
-	if (!mac_mgmt) {
-		ret = -ENOMEM;
-		goto exit;
-	}
-
-	ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt,
-			   sizeof(struct mib_mac_mgmt));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
-		       priv->netdev->name, ret);
-		goto error;
-	}
-	memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN);
-	printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name,
-	       mac2str(priv->bssid));
-error:
-	kfree(mac_mgmt);
-exit:
-	return ret;
-}
-
-static int at76_get_current_channel(struct at76_priv *priv)
-{
-	int ret = 0;
-	struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
-
-	if (!phy) {
-		ret = -ENOMEM;
-		goto exit;
-	}
-	ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n",
-		       priv->netdev->name, ret);
-		goto error;
-	}
-	priv->channel = phy->channel_id;
-error:
-	kfree(phy);
-exit:
-	return ret;
-}
-
-/**
- * at76_start_scan - start a scan
- *
- * @use_essid - use the configured ESSID in non passive mode
- */
-static int at76_start_scan(struct at76_priv *priv, int use_essid)
-{
-	struct at76_req_scan scan;
-
-	memset(&scan, 0, sizeof(struct at76_req_scan));
-	memset(scan.bssid, 0xff, ETH_ALEN);
-
-	if (use_essid) {
-		memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE);
-		scan.essid_size = priv->essid_size;
-	} else
-		scan.essid_size = 0;
-
-	/* jal: why should we start at a certain channel? we do scan the whole
-	   range allowed by reg domain. */
-	scan.channel = priv->channel;
-
-	/* atmelwlandriver differs between scan type 0 and 1 (active/passive)
-	   For ad-hoc mode, it uses type 0 only. */
-	scan.scan_type = priv->scan_mode;
-
-	/* INFO: For probe_delay, not multiplying by 1024 as this will be
-	   slightly less than min_channel_time
-	   (per spec: probe delay < min. channel time) */
-	scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
-	scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
-	scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
-	scan.international_scan = 0;
-
-	/* other values are set to 0 for type 0 */
-
-	at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
-		 "channel = %d, probe_delay = %d, scan_min_time = %d, "
-		 "scan_max_time = %d)",
-		 priv->netdev->name, use_essid,
-		 scan.international_scan, scan.channel,
-		 le16_to_cpu(scan.probe_delay),
-		 le16_to_cpu(scan.min_channel_time),
-		 le16_to_cpu(scan.max_channel_time));
-
-	return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
-}
-
-/* Enable monitor mode */
-static int at76_start_monitor(struct at76_priv *priv)
-{
-	struct at76_req_scan scan;
-	int ret;
-
-	memset(&scan, 0, sizeof(struct at76_req_scan));
-	memset(scan.bssid, 0xff, ETH_ALEN);
-
-	scan.channel = priv->channel;
-	scan.scan_type = SCAN_TYPE_PASSIVE;
-	scan.international_scan = 0;
-
-	ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
-	if (ret >= 0)
-		ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
-
-	return ret;
-}
-
-static int at76_start_ibss(struct at76_priv *priv)
-{
-	struct at76_req_ibss bss;
-	int ret;
-
-	WARN_ON(priv->mac_state != MAC_OWN_IBSS);
-	if (priv->mac_state != MAC_OWN_IBSS)
-		return -EBUSY;
-
-	memset(&bss, 0, sizeof(struct at76_req_ibss));
-	memset(bss.bssid, 0xff, ETH_ALEN);
-	memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE);
-	bss.essid_size = priv->essid_size;
-	bss.bss_type = ADHOC_MODE;
-	bss.channel = priv->channel;
-
-	ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss,
-				    sizeof(struct at76_req_ibss));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: start_ibss failed: %d\n",
-		       priv->netdev->name, ret);
-		return ret;
-	}
-
-	ret = at76_wait_completion(priv, CMD_START_IBSS);
-	if (ret != CMD_STATUS_COMPLETE) {
-		printk(KERN_ERR "%s: start_ibss failed to complete, %d\n",
-		       priv->netdev->name, ret);
-		return ret;
-	}
-
-	ret = at76_get_current_bssid(priv);
-	if (ret < 0)
-		return ret;
-
-	ret = at76_get_current_channel(priv);
-	if (ret < 0)
-		return ret;
-
-	/* not sure what this is good for ??? */
-	priv->mib_buf.type = MIB_MAC_MGMT;
-	priv->mib_buf.size = 1;
-	priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
-	priv->mib_buf.data.byte = 0;
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0) {
-		printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
-		       priv->netdev->name, ret);
-		return ret;
-	}
-
-	netif_carrier_on(priv->netdev);
-	netif_start_queue(priv->netdev);
-	return 0;
-}
-
-/* Request card to join BSS in managed or ad-hoc mode */
-static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr)
-{
-	struct at76_req_join join;
-
-	BUG_ON(!ptr);
-
-	memset(&join, 0, sizeof(struct at76_req_join));
-	memcpy(join.bssid, ptr->bssid, ETH_ALEN);
-	memcpy(join.essid, ptr->ssid, ptr->ssid_len);
-	join.essid_size = ptr->ssid_len;
-	join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2);
-	join.channel = ptr->channel;
-	join.timeout = cpu_to_le16(2000);
-
-	at76_dbg(DBG_PROGRESS,
-		 "%s join addr %s ssid %s type %d ch %d timeout %d",
-		 priv->netdev->name, mac2str(join.bssid), join.essid,
-		 join.bss_type, join.channel, le16_to_cpu(join.timeout));
-	return at76_set_card_command(priv->udev, CMD_JOIN, &join,
-				     sizeof(struct at76_req_join));
-}
-
-/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
-   likely to compensate a flaw in the AT76C503A USB part ... */
-static inline int at76_calc_padding(int wlen)
-{
-	/* add the USB TX header */
-	wlen += AT76_TX_HDRLEN;
-
-	wlen = wlen % 64;
-
-	if (wlen < 50)
-		return 50 - wlen;
-
-	if (wlen >= 61)
-		return 64 + 50 - wlen;
-
-	return 0;
-}
-
-/* We are doing a lot of things here in an interrupt. Need
-   a bh handler (Watching TV with a TV card is probably
-   a good test: if you see flickers, we are doing too much.
-   Currently I do see flickers... even with our tasklet :-( )
-   Maybe because the bttv driver and usb-uhci use the same interrupt
-*/
-/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
- * solve everything.. (alex) */
-static void at76_rx_callback(struct urb *urb)
-{
-	struct at76_priv *priv = urb->context;
-
-	priv->rx_tasklet.data = (unsigned long)urb;
-	tasklet_schedule(&priv->rx_tasklet);
-	return;
-}
-
-static void at76_tx_callback(struct urb *urb)
-{
-	struct at76_priv *priv = urb->context;
-	struct net_device_stats *stats = &priv->stats;
-	unsigned long flags;
-	struct at76_tx_buffer *mgmt_buf;
-	int ret;
-
-	switch (urb->status) {
-	case 0:
-		stats->tx_packets++;
-		break;
-	case -ENOENT:
-	case -ECONNRESET:
-		/* urb has been unlinked */
-		return;
-	default:
-		at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
-			 __func__, urb->status);
-		stats->tx_errors++;
-		break;
-	}
-
-	spin_lock_irqsave(&priv->mgmt_spinlock, flags);
-	mgmt_buf = priv->next_mgmt_bulk;
-	priv->next_mgmt_bulk = NULL;
-	spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
-
-	if (!mgmt_buf) {
-		netif_wake_queue(priv->netdev);
-		return;
-	}
-
-	/* we don't copy the padding bytes, but add them
-	   to the length */
-	memcpy(priv->bulk_out_buffer, mgmt_buf,
-	       le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN);
-	usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
-			  priv->bulk_out_buffer,
-			  le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding +
-			  AT76_TX_HDRLEN, at76_tx_callback, priv);
-	ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
-	if (ret)
-		printk(KERN_ERR "%s: error in tx submit urb: %d\n",
-		       priv->netdev->name, ret);
-
-	kfree(mgmt_buf);
-}
-
-/* Send a management frame on bulk-out.  txbuf->wlength must be set */
-static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf)
-{
-	unsigned long flags;
-	int ret;
-	int urb_status;
-	void *oldbuf = NULL;
-
-	netif_carrier_off(priv->netdev);	/* stop netdev watchdog */
-	netif_stop_queue(priv->netdev);	/* stop tx data packets */
-
-	spin_lock_irqsave(&priv->mgmt_spinlock, flags);
-
-	urb_status = priv->tx_urb->status;
-	if (urb_status == -EINPROGRESS) {
-		/* cannot transmit now, put in the queue */
-		oldbuf = priv->next_mgmt_bulk;
-		priv->next_mgmt_bulk = txbuf;
-	}
-	spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
-
-	if (oldbuf) {
-		/* a data/mgmt tx is already pending in the URB -
-		   if this is no error in some situations we must
-		   implement a queue or silently modify the old msg */
-		printk(KERN_ERR "%s: removed pending mgmt buffer %s\n",
-		       priv->netdev->name, hex2str(oldbuf, 64));
-		kfree(oldbuf);
-		return 0;
-	}
-
-	txbuf->tx_rate = TX_RATE_1MBIT;
-	txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength));
-	memset(txbuf->reserved, 0, sizeof(txbuf->reserved));
-
-	if (priv->next_mgmt_bulk)
-		printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n",
-		       priv->netdev->name, urb_status);
-
-	at76_dbg(DBG_TX_MGMT,
-		 "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
-		 priv->netdev->name, le16_to_cpu(txbuf->wlength),
-		 txbuf->tx_rate, txbuf->padding,
-		 hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength)));
-
-	/* txbuf was not consumed above -> send mgmt msg immediately */
-	memcpy(priv->bulk_out_buffer, txbuf,
-	       le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN);
-	usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
-			  priv->bulk_out_buffer,
-			  le16_to_cpu(txbuf->wlength) + txbuf->padding +
-			  AT76_TX_HDRLEN, at76_tx_callback, priv);
-	ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
-	if (ret)
-		printk(KERN_ERR "%s: error in tx submit urb: %d\n",
-		       priv->netdev->name, ret);
-
-	kfree(txbuf);
-
-	return ret;
-}
-
-/* Go to the next information element */
-static inline void next_ie(struct ieee80211_info_element **ie)
-{
-	*ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
-}
-
-/* Challenge is the challenge string (in TLV format)
-   we got with seq_nr 2 for shared secret authentication only and
-   send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
-   otherwise it is NULL */
-static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss,
-			 int seq_nr, struct ieee80211_info_element *challenge)
-{
-	struct at76_tx_buffer *tx_buffer;
-	struct ieee80211_hdr_3addr *mgmt;
-	struct ieee80211_auth *req;
-	int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
-		       AUTH_FRAME_SIZE + 1 + 1 + challenge->len);
-
-	BUG_ON(!bss);
-	BUG_ON(seq_nr == 3 && !challenge);
-	tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
-	if (!tx_buffer)
-		return -ENOMEM;
-
-	req = (struct ieee80211_auth *)tx_buffer->packet;
-	mgmt = &req->header;
-
-	/* make wireless header */
-	/* first auth msg is not encrypted, only the second (seq_nr == 3) */
-	mgmt->frame_ctl =
-	    cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
-			(seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
-
-	mgmt->duration_id = cpu_to_le16(0x8000);
-	memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
-	memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
-	memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
-	mgmt->seq_ctl = cpu_to_le16(0);
-
-	req->algorithm = cpu_to_le16(priv->auth_mode);
-	req->transaction = cpu_to_le16(seq_nr);
-	req->status = cpu_to_le16(0);
-
-	if (seq_nr == 3)
-		memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
-
-	/* init. at76_priv tx header */
-	tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN);
-	at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
-		 priv->netdev->name, mac2str(mgmt->addr3),
-		 le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction));
-	if (seq_nr == 3)
-		at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
-			 priv->netdev->name, hex2str(req->info_element, 18));
-
-	/* either send immediately (if no data tx is pending
-	   or put it in pending list */
-	return at76_tx_mgmt(priv, tx_buffer);
-}
-
-static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
-{
-	struct at76_tx_buffer *tx_buffer;
-	struct ieee80211_hdr_3addr *mgmt;
-	struct ieee80211_assoc_request *req;
-	struct ieee80211_info_element *ie;
-	char *essid;
-	int essid_len;
-	u16 capa;
-
-	BUG_ON(!bss);
-
-	tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
-	if (!tx_buffer)
-		return -ENOMEM;
-
-	req = (struct ieee80211_assoc_request *)tx_buffer->packet;
-	mgmt = &req->header;
-	ie = req->info_element;
-
-	/* make wireless header */
-	mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-				      IEEE80211_STYPE_ASSOC_REQ);
-
-	mgmt->duration_id = cpu_to_le16(0x8000);
-	memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
-	memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
-	memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
-	mgmt->seq_ctl = cpu_to_le16(0);
-
-	/* we must set the Privacy bit in the capabilities to assure an
-	   Agere-based AP with optional WEP transmits encrypted frames
-	   to us.  AP only set the Privacy bit in their capabilities
-	   if WEP is mandatory in the BSS! */
-	capa = bss->capa;
-	if (priv->wep_enabled)
-		capa |= WLAN_CAPABILITY_PRIVACY;
-	if (priv->preamble_type != PREAMBLE_TYPE_LONG)
-		capa |= WLAN_CAPABILITY_SHORT_PREAMBLE;
-	req->capability = cpu_to_le16(capa);
-
-	req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
-
-	/* write TLV data elements */
-
-	ie->id = WLAN_EID_SSID;
-	ie->len = bss->ssid_len;
-	memcpy(ie->data, bss->ssid, bss->ssid_len);
-	next_ie(&ie);
-
-	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 */
-
-	/* init. at76_priv tx header */
-	tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
-
-	ie = req->info_element;
-	essid = ie->data;
-	essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
-
-	next_ie(&ie);		/* points to IE of rates now */
-	at76_dbg(DBG_TX_MGMT,
-		 "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s",
-		 priv->netdev->name, mac2str(mgmt->addr3),
-		 le16_to_cpu(req->capability), essid_len, essid,
-		 hex2str(ie->data, ie->len));
-
-	/* either send immediately (if no data tx is pending
-	   or put it in pending list */
-	return at76_tx_mgmt(priv, tx_buffer);
-}
-
-/* We got to check the bss_list for old entries */
-static void at76_bss_list_timeout(unsigned long par)
-{
-	struct at76_priv *priv = (struct at76_priv *)par;
-	unsigned long flags;
-	struct list_head *lptr, *nptr;
-	struct bss_info *ptr;
-
-	spin_lock_irqsave(&priv->bss_list_spinlock, flags);
-
-	list_for_each_safe(lptr, nptr, &priv->bss_list) {
-
-		ptr = list_entry(lptr, struct bss_info, list);
-
-		if (ptr != priv->curr_bss
-		    && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) {
-			at76_dbg(DBG_BSS_TABLE_RM,
-				 "%s: bss_list: removing old BSS %s ch %d",
-				 priv->netdev->name, mac2str(ptr->bssid),
-				 ptr->channel);
-			list_del(&ptr->list);
-			kfree(ptr);
-		}
-	}
-	spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
-	/* restart the timer */
-	mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
-}
-
-static inline void at76_set_mac_state(struct at76_priv *priv,
-				      enum mac_state mac_state)
-{
-	at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
-		 mac_states[mac_state]);
-	priv->mac_state = mac_state;
-}
-
-static void at76_dump_bss_table(struct at76_priv *priv)
-{
-	struct bss_info *ptr;
-	unsigned long flags;
-	struct list_head *lptr;
-
-	spin_lock_irqsave(&priv->bss_list_spinlock, flags);
-
-	at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
-		 priv->curr_bss);
-
-	list_for_each(lptr, &priv->bss_list) {
-		ptr = list_entry(lptr, struct bss_info, list);
-		at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s "
-			 "(%s) capa 0x%04x rates %s rssi %d link %d noise %d",
-			 ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len,
-			 ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len),
-			 ptr->capa, hex2str(ptr->rates, ptr->rates_len),
-			 ptr->rssi, ptr->link_qual, ptr->noise_level);
-	}
-	spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
-}
-
-/* Called upon successful association to mark interface as connected */
-static void at76_work_assoc_done(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      work_assoc_done);
-
-	mutex_lock(&priv->mtx);
-
-	WARN_ON(priv->mac_state != MAC_ASSOC);
-	WARN_ON(!priv->curr_bss);
-	if (priv->mac_state != MAC_ASSOC || !priv->curr_bss)
-		goto exit;
-
-	if (priv->iw_mode == IW_MODE_INFRA) {
-		if (priv->pm_mode != AT76_PM_OFF) {
-			/* calculate the listen interval in units of
-			   beacon intervals of the curr_bss */
-			u32 pm_period_beacon = (priv->pm_period >> 10) /
-			    priv->curr_bss->beacon_interval;
-
-			pm_period_beacon = max(pm_period_beacon, 2u);
-			pm_period_beacon = min(pm_period_beacon, 0xffffu);
-
-			at76_dbg(DBG_PM,
-				 "%s: pm_mode %d assoc id 0x%x listen int %d",
-				 priv->netdev->name, priv->pm_mode,
-				 priv->assoc_id, pm_period_beacon);
-
-			at76_set_associd(priv, priv->assoc_id);
-			at76_set_listen_interval(priv, (u16)pm_period_beacon);
-		}
-		schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
-	}
-	at76_set_pm_mode(priv);
-
-	netif_carrier_on(priv->netdev);
-	netif_wake_queue(priv->netdev);
-	at76_set_mac_state(priv, MAC_CONNECTED);
-	at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid);
-	at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
-		 priv->netdev->name, mac2str(priv->curr_bss->bssid));
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-/* We only store the new mac address in netdev struct,
-   it gets set when the netdev is opened. */
-static int at76_set_mac_address(struct net_device *netdev, void *addr)
-{
-	struct sockaddr *mac = addr;
-	memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
-	return 1;
-}
-
-static struct net_device_stats *at76_get_stats(struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	return &priv->stats;
-}
-
-static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
-		 priv->wstats.qual.qual, priv->wstats.qual.level,
-		 priv->wstats.qual.noise, priv->wstats.qual.updated);
-
-	return &priv->wstats;
-}
-
-static void at76_set_multicast(struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int promisc;
-
-	promisc = ((netdev->flags & IFF_PROMISC) != 0);
-	if (promisc != priv->promisc) {
-		/* This gets called in interrupt, must reschedule */
-		priv->promisc = promisc;
-		schedule_work(&priv->work_set_promisc);
-	}
-}
-
-/* Stop all network activity, flush all pending tasks */
-static void at76_quiesce(struct at76_priv *priv)
-{
-	unsigned long flags;
-
-	netif_stop_queue(priv->netdev);
-	netif_carrier_off(priv->netdev);
-
-	at76_set_mac_state(priv, MAC_INIT);
-
-	cancel_delayed_work(&priv->dwork_get_scan);
-	cancel_delayed_work(&priv->dwork_beacon);
-	cancel_delayed_work(&priv->dwork_auth);
-	cancel_delayed_work(&priv->dwork_assoc);
-	cancel_delayed_work(&priv->dwork_restart);
-
-	spin_lock_irqsave(&priv->mgmt_spinlock, flags);
-	kfree(priv->next_mgmt_bulk);
-	priv->next_mgmt_bulk = NULL;
-	spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
-}
-
-/*******************************************************************************
- * at76_priv implementations of iw_handler functions:
- */
-static int at76_iw_handler_commit(struct net_device *netdev,
-				  struct iw_request_info *info,
-				  void *null, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
-		 __func__);
-
-	if (priv->mac_state != MAC_INIT)
-		at76_quiesce(priv);
-
-	/* Wait half second before the restart to process subsequent
-	 * requests from the same iwconfig in a single restart */
-	schedule_delayed_work(&priv->dwork_restart, HZ / 2);
-
-	return 0;
-}
-
-static int at76_iw_handler_get_name(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    char *name, char *extra)
-{
-	strcpy(name, "IEEE 802.11b");
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
-	return 0;
-}
-
-static int at76_iw_handler_set_freq(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    struct iw_freq *freq, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int chan = -1;
-	int ret = -EIWCOMMIT;
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d",
-		 netdev->name, freq->m, freq->e);
-
-	if ((freq->e == 0) && (freq->m <= 1000))
-		/* Setting by channel number */
-		chan = freq->m;
-	else {
-		/* Setting by frequency - search the table */
-		int mult = 1;
-		int i;
-
-		for (i = 0; i < (6 - freq->e); i++)
-			mult *= 10;
-
-		for (i = 0; i < NUM_CHANNELS; i++) {
-			if (freq->m == (channel_frequency[i] * mult))
-				chan = i + 1;
-		}
-	}
-
-	if (chan < 1 || !priv->domain)
-		/* non-positive channels are invalid
-		 * we need a domain info to set the channel
-		 * either that or an invalid frequency was
-		 * provided by the user */
-		ret = -EINVAL;
-	else if (!(priv->domain->channel_map & (1 << (chan - 1)))) {
-		printk(KERN_INFO "%s: channel %d not allowed for domain %s\n",
-		       priv->netdev->name, chan, priv->domain->name);
-		ret = -EINVAL;
-	}
-
-	if (ret == -EIWCOMMIT) {
-		priv->channel = chan;
-		at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
-			 chan);
-	}
-
-	return ret;
-}
-
-static int at76_iw_handler_get_freq(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    struct iw_freq *freq, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	freq->m = priv->channel;
-	freq->e = 0;
-
-	if (priv->channel)
-		at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d",
-			 netdev->name, channel_frequency[priv->channel - 1], 6);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
-		 priv->channel);
-
-	return 0;
-}
-
-static int at76_iw_handler_set_mode(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    __u32 *mode, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
-
-	if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
-	    (*mode != IW_MODE_MONITOR))
-		return -EINVAL;
-
-	priv->iw_mode = *mode;
-	if (priv->iw_mode != IW_MODE_INFRA)
-		priv->pm_mode = AT76_PM_OFF;
-
-	return -EIWCOMMIT;
-}
-
-static int at76_iw_handler_get_mode(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    __u32 *mode, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	*mode = priv->iw_mode;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
-
-	return 0;
-}
-
-static int at76_iw_handler_get_range(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_point *data, char *extra)
-{
-	/* inspired by atmel.c */
-	struct at76_priv *priv = netdev_priv(netdev);
-	struct iw_range *range = (struct iw_range *)extra;
-	int i;
-
-	data->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(struct iw_range));
-
-	/* TODO: range->throughput = xxxxxx; */
-
-	range->min_nwid = 0x0000;
-	range->max_nwid = 0x0000;
-
-	/* this driver doesn't maintain sensitivity information */
-	range->sensitivity = 0;
-
-	range->max_qual.qual = 100;
-	range->max_qual.level = 100;
-	range->max_qual.noise = 0;
-	range->max_qual.updated = IW_QUAL_NOISE_INVALID;
-
-	range->avg_qual.qual = 50;
-	range->avg_qual.level = 50;
-	range->avg_qual.noise = 0;
-	range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
-
-	range->bitrate[0] = 1000000;
-	range->bitrate[1] = 2000000;
-	range->bitrate[2] = 5500000;
-	range->bitrate[3] = 11000000;
-	range->num_bitrates = 4;
-
-	range->min_rts = 0;
-	range->max_rts = MAX_RTS_THRESHOLD;
-
-	range->min_frag = MIN_FRAG_THRESHOLD;
-	range->max_frag = MAX_FRAG_THRESHOLD;
-
-	range->pmp_flags = IW_POWER_PERIOD;
-	range->pmt_flags = IW_POWER_ON;
-	range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R;
-
-	range->encoding_size[0] = WEP_SMALL_KEY_LEN;
-	range->encoding_size[1] = WEP_LARGE_KEY_LEN;
-	range->num_encoding_sizes = 2;
-	range->max_encoding_tokens = WEP_KEYS;
-
-	/* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
-	   - take this for all (ignore antenna gains) */
-	range->txpower[0] = 15;
-	range->num_txpower = 1;
-	range->txpower_capa = IW_TXPOW_DBM;
-
-	range->we_version_source = WIRELESS_EXT;
-	range->we_version_compiled = WIRELESS_EXT;
-
-	/* same as the values used in atmel.c */
-	range->retry_capa = IW_RETRY_LIMIT;
-	range->retry_flags = IW_RETRY_LIMIT;
-	range->r_time_flags = 0;
-	range->min_retry = 1;
-	range->max_retry = 255;
-
-	range->num_channels = NUM_CHANNELS;
-	range->num_frequency = 0;
-
-	for (i = 0; i < NUM_CHANNELS; i++) {
-		/* test if channel map bit is raised */
-		if (priv->domain->channel_map & (0x1 << i)) {
-			range->num_frequency += 1;
-
-			range->freq[i].i = i + 1;
-			range->freq[i].m = channel_frequency[i] * 100000;
-			range->freq[i].e = 1;	/* freq * 10^1 */
-		}
-	}
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
-
-	return 0;
-}
-
-static int at76_iw_handler_set_spy(struct net_device *netdev,
-				   struct iw_request_info *info,
-				   struct iw_point *data, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = 0;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
-		 netdev->name, data->length);
-
-	spin_lock_bh(&priv->spy_spinlock);
-	ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data,
-				 extra);
-	spin_unlock_bh(&priv->spy_spinlock);
-
-	return ret;
-}
-
-static int at76_iw_handler_get_spy(struct net_device *netdev,
-				   struct iw_request_info *info,
-				   struct iw_point *data, char *extra)
-{
-
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = 0;
-
-	spin_lock_bh(&priv->spy_spinlock);
-	ret = iw_handler_get_spy(priv->netdev, info,
-				 (union iwreq_data *)data, extra);
-	spin_unlock_bh(&priv->spy_spinlock);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
-		 netdev->name, data->length);
-
-	return ret;
-}
-
-static int at76_iw_handler_set_thrspy(struct net_device *netdev,
-				      struct iw_request_info *info,
-				      struct iw_point *data, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
-		 netdev->name, data->length);
-
-	spin_lock_bh(&priv->spy_spinlock);
-	ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
-				    extra);
-	spin_unlock_bh(&priv->spy_spinlock);
-
-	return ret;
-}
-
-static int at76_iw_handler_get_thrspy(struct net_device *netdev,
-				      struct iw_request_info *info,
-				      struct iw_point *data, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret;
-
-	spin_lock_bh(&priv->spy_spinlock);
-	ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
-				    extra);
-	spin_unlock_bh(&priv->spy_spinlock);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
-		 netdev->name, data->length);
-
-	return ret;
-}
-
-static int at76_iw_handler_set_wap(struct net_device *netdev,
-				   struct iw_request_info *info,
-				   struct sockaddr *ap_addr, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
-		 mac2str(ap_addr->sa_data));
-
-	/* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
-	   chosen any or auto AP preference */
-	if (is_broadcast_ether_addr(ap_addr->sa_data)
-	    || is_zero_ether_addr(ap_addr->sa_data))
-		priv->wanted_bssid_valid = 0;
-	else {
-		/* user wants to set a preferred AP address */
-		priv->wanted_bssid_valid = 1;
-		memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
-	}
-
-	return -EIWCOMMIT;
-}
-
-static int at76_iw_handler_get_wap(struct net_device *netdev,
-				   struct iw_request_info *info,
-				   struct sockaddr *ap_addr, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	ap_addr->sa_family = ARPHRD_ETHER;
-	memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
-		 mac2str(ap_addr->sa_data));
-
-	return 0;
-}
-
-static int at76_iw_handler_set_scan(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    union iwreq_data *wrqu, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = 0;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
-
-	if (mutex_lock_interruptible(&priv->mtx))
-		return -EINTR;
-
-	if (!netif_running(netdev)) {
-		ret = -ENETDOWN;
-		goto exit;
-	}
-
-	/* jal: we don't allow "iwlist ethX scan" while we are
-	   in monitor mode */
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		ret = -EBUSY;
-		goto exit;
-	}
-
-	/* Discard old scan results */
-	if ((jiffies - priv->last_scan) > (20 * HZ))
-		priv->scan_state = SCAN_IDLE;
-	priv->last_scan = jiffies;
-
-	/* Initiate a scan command */
-	if (priv->scan_state == SCAN_IN_PROGRESS) {
-		ret = -EBUSY;
-		goto exit;
-	}
-
-	priv->scan_state = SCAN_IN_PROGRESS;
-
-	at76_quiesce(priv);
-
-	/* Try to do passive or active scan if WE asks as. */
-	if (wrqu->data.length
-	    && wrqu->data.length == sizeof(struct iw_scan_req)) {
-		struct iw_scan_req *req = (struct iw_scan_req *)extra;
-
-		if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
-			priv->scan_mode = SCAN_TYPE_PASSIVE;
-		else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
-			priv->scan_mode = SCAN_TYPE_ACTIVE;
-
-		/* Sanity check values? */
-		if (req->min_channel_time > 0)
-			priv->scan_min_time = req->min_channel_time;
-
-		if (req->max_channel_time > 0)
-			priv->scan_max_time = req->max_channel_time;
-	}
-
-	/* change to scanning state */
-	at76_set_mac_state(priv, MAC_SCANNING);
-	schedule_work(&priv->work_start_scan);
-
-exit:
-	mutex_unlock(&priv->mtx);
-	return ret;
-}
-
-static int at76_iw_handler_get_scan(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    struct iw_point *data, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	unsigned long flags;
-	struct list_head *lptr, *nptr;
-	struct bss_info *curr_bss;
-	struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
-	char *curr_val, *curr_pos = extra;
-	int i;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
-
-	if (!iwe)
-		return -ENOMEM;
-
-	if (priv->scan_state != SCAN_COMPLETED) {
-		/* scan not yet finished */
-		kfree(iwe);
-		return -EAGAIN;
-	}
-
-	spin_lock_irqsave(&priv->bss_list_spinlock, flags);
-
-	list_for_each_safe(lptr, nptr, &priv->bss_list) {
-		curr_bss = list_entry(lptr, struct bss_info, list);
-
-		iwe->cmd = SIOCGIWAP;
-		iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
-		memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
-		curr_pos = iwe_stream_add_event(info, curr_pos,
-						extra + IW_SCAN_MAX_DATA, iwe,
-						IW_EV_ADDR_LEN);
-
-		iwe->u.data.length = curr_bss->ssid_len;
-		iwe->cmd = SIOCGIWESSID;
-		iwe->u.data.flags = 1;
-
-		curr_pos = iwe_stream_add_point(info, curr_pos,
-						extra + IW_SCAN_MAX_DATA, iwe,
-						curr_bss->ssid);
-
-		iwe->cmd = SIOCGIWMODE;
-		iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
-		    IW_MODE_ADHOC :
-		    (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
-		    IW_MODE_MASTER : IW_MODE_AUTO;
-		/* IW_MODE_AUTO = 0 which I thought is
-		 * the most logical value to return in this case */
-		curr_pos = iwe_stream_add_event(info, curr_pos,
-						extra + IW_SCAN_MAX_DATA, iwe,
-						IW_EV_UINT_LEN);
-
-		iwe->cmd = SIOCGIWFREQ;
-		iwe->u.freq.m = curr_bss->channel;
-		iwe->u.freq.e = 0;
-		curr_pos = iwe_stream_add_event(info, curr_pos,
-						extra + IW_SCAN_MAX_DATA, iwe,
-						IW_EV_FREQ_LEN);
-
-		iwe->cmd = SIOCGIWENCODE;
-		if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY)
-			iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-		else
-			iwe->u.data.flags = IW_ENCODE_DISABLED;
-
-		iwe->u.data.length = 0;
-		curr_pos = iwe_stream_add_point(info, curr_pos,
-						extra + IW_SCAN_MAX_DATA, iwe,
-						NULL);
-
-		/* Add quality statistics */
-		iwe->cmd = IWEVQUAL;
-		iwe->u.qual.noise = 0;
-		iwe->u.qual.updated =
-		    IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
-		iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
-		if (iwe->u.qual.level > 100)
-			iwe->u.qual.level = 100;
-		if (at76_is_intersil(priv->board_type))
-			iwe->u.qual.qual = curr_bss->link_qual;
-		else {
-			iwe->u.qual.qual = 0;
-			iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
-		}
-		/* Add new value to event */
-		curr_pos = iwe_stream_add_event(info, curr_pos,
-						extra + IW_SCAN_MAX_DATA, iwe,
-						IW_EV_QUAL_LEN);
-
-		/* Rate: stuffing multiple values in a single event requires
-		 * a bit more of magic - Jean II */
-		curr_val = curr_pos + IW_EV_LCP_LEN;
-
-		iwe->cmd = SIOCGIWRATE;
-		/* Those two flags are ignored... */
-		iwe->u.bitrate.fixed = 0;
-		iwe->u.bitrate.disabled = 0;
-		/* Max 8 values */
-		for (i = 0; i < curr_bss->rates_len; i++) {
-			/* Bit rate given in 500 kb/s units (+ 0x80) */
-			iwe->u.bitrate.value =
-			    ((curr_bss->rates[i] & 0x7f) * 500000);
-			/* Add new value to event */
-			curr_val = iwe_stream_add_value(info, curr_pos,
-							curr_val,
-							extra +
-							IW_SCAN_MAX_DATA, iwe,
-							IW_EV_PARAM_LEN);
-		}
-
-		/* Check if we added any event */
-		if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
-			curr_pos = curr_val;
-
-		/* more information may be sent back using IWECUSTOM */
-
-	}
-
-	spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
-
-	data->length = (curr_pos - extra);
-	data->flags = 0;
-
-	kfree(iwe);
-	return 0;
-}
-
-static int at76_iw_handler_set_essid(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_point *data, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
-
-	if (data->flags) {
-		memcpy(priv->essid, extra, data->length);
-		priv->essid_size = data->length;
-	} else
-		priv->essid_size = 0;	/* Use any SSID */
-
-	return -EIWCOMMIT;
-}
-
-static int at76_iw_handler_get_essid(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_point *data, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	if (priv->essid_size) {
-		/* not the ANY ssid in priv->essid */
-		data->flags = 1;
-		data->length = priv->essid_size;
-		memcpy(extra, priv->essid, data->length);
-	} else {
-		/* the ANY ssid was specified */
-		if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) {
-			/* report the SSID we have found */
-			data->flags = 1;
-			data->length = priv->curr_bss->ssid_len;
-			memcpy(extra, priv->curr_bss->ssid, data->length);
-		} else {
-			/* report ANY back */
-			data->flags = 0;
-			data->length = 0;
-		}
-	}
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
-		 data->length, extra);
-
-	return 0;
-}
-
-static int at76_iw_handler_set_rate(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    struct iw_param *bitrate, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = -EIWCOMMIT;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
-		 bitrate->value);
-
-	switch (bitrate->value) {
-	case -1:
-		priv->txrate = TX_RATE_AUTO;
-		break;		/* auto rate */
-	case 1000000:
-		priv->txrate = TX_RATE_1MBIT;
-		break;
-	case 2000000:
-		priv->txrate = TX_RATE_2MBIT;
-		break;
-	case 5500000:
-		priv->txrate = TX_RATE_5_5MBIT;
-		break;
-	case 11000000:
-		priv->txrate = TX_RATE_11MBIT;
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	return ret;
-}
-
-static int at76_iw_handler_get_rate(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    struct iw_param *bitrate, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = 0;
-
-	switch (priv->txrate) {
-		/* return max rate if RATE_AUTO */
-	case TX_RATE_AUTO:
-		bitrate->value = 11000000;
-		break;
-	case TX_RATE_1MBIT:
-		bitrate->value = 1000000;
-		break;
-	case TX_RATE_2MBIT:
-		bitrate->value = 2000000;
-		break;
-	case TX_RATE_5_5MBIT:
-		bitrate->value = 5500000;
-		break;
-	case TX_RATE_11MBIT:
-		bitrate->value = 11000000;
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
-	bitrate->disabled = 0;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
-		 bitrate->value);
-
-	return ret;
-}
-
-static int at76_iw_handler_set_rts(struct net_device *netdev,
-				   struct iw_request_info *info,
-				   struct iw_param *rts, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = -EIWCOMMIT;
-	int rthr = rts->value;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
-		 netdev->name, rts->value, (rts->disabled) ? "true" : "false");
-
-	if (rts->disabled)
-		rthr = MAX_RTS_THRESHOLD;
-
-	if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
-		ret = -EINVAL;
-	else
-		priv->rts_threshold = rthr;
-
-	return ret;
-}
-
-static int at76_iw_handler_get_rts(struct net_device *netdev,
-				   struct iw_request_info *info,
-				   struct iw_param *rts, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	rts->value = priv->rts_threshold;
-	rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
-	rts->fixed = 1;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
-		 netdev->name, rts->value, (rts->disabled) ? "true" : "false");
-
-	return 0;
-}
-
-static int at76_iw_handler_set_frag(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    struct iw_param *frag, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = -EIWCOMMIT;
-	int fthr = frag->value;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
-		 netdev->name, frag->value,
-		 (frag->disabled) ? "true" : "false");
-
-	if (frag->disabled)
-		fthr = MAX_FRAG_THRESHOLD;
-
-	if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD))
-		ret = -EINVAL;
-	else
-		priv->frag_threshold = fthr & ~0x1;	/* get an even value */
-
-	return ret;
-}
-
-static int at76_iw_handler_get_frag(struct net_device *netdev,
-				    struct iw_request_info *info,
-				    struct iw_param *frag, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	frag->value = priv->frag_threshold;
-	frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
-	frag->fixed = 1;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
-		 netdev->name, frag->value,
-		 (frag->disabled) ? "true" : "false");
-
-	return 0;
-}
-
-static int at76_iw_handler_get_txpow(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_param *power, char *extra)
-{
-	power->value = 15;
-	power->fixed = 1;	/* No power control */
-	power->disabled = 0;
-	power->flags = IW_TXPOW_DBM;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
-		 power->value);
-
-	return 0;
-}
-
-/* jal: short retry is handled by the firmware (at least 0.90.x),
-   while long retry is not (?) */
-static int at76_iw_handler_set_retry(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_param *retry, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = -EIWCOMMIT;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
-		 netdev->name, retry->disabled, retry->flags, retry->value);
-
-	if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
-		if ((retry->flags & IW_RETRY_MIN) ||
-		    !(retry->flags & IW_RETRY_MAX))
-			priv->short_retry_limit = retry->value;
-		else
-			ret = -EINVAL;
-	} else
-		ret = -EINVAL;
-
-	return ret;
-}
-
-/* Adapted (ripped) from atmel.c */
-static int at76_iw_handler_get_retry(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_param *retry, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
-
-	retry->disabled = 0;	/* Can't be disabled */
-	retry->flags = IW_RETRY_LIMIT;
-	retry->value = priv->short_retry_limit;
-
-	return 0;
-}
-
-static int at76_iw_handler_set_encode(struct net_device *netdev,
-				      struct iw_request_info *info,
-				      struct iw_point *encoding, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
-	int len = encoding->length;
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
-		 "pointer %p len %d", netdev->name, encoding->flags,
-		 encoding->pointer, encoding->length);
-	at76_dbg(DBG_IOCTL,
-		 "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
-		 "auth_mode %s", netdev->name,
-		 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id,
-		 (priv->auth_mode ==
-		  WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
-
-	/* take the old default key if index is invalid */
-	if ((index < 0) || (index >= WEP_KEYS))
-		index = priv->wep_key_id;
-
-	if (len > 0) {
-		if (len > WEP_LARGE_KEY_LEN)
-			len = WEP_LARGE_KEY_LEN;
-
-		memset(priv->wep_keys[index], 0, WEP_KEY_LEN);
-		memcpy(priv->wep_keys[index], extra, len);
-		priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
-		    WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
-		priv->wep_enabled = 1;
-	}
-
-	priv->wep_key_id = index;
-	priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
-
-	if (encoding->flags & IW_ENCODE_RESTRICTED)
-		priv->auth_mode = WLAN_AUTH_SHARED_KEY;
-	if (encoding->flags & IW_ENCODE_OPEN)
-		priv->auth_mode = WLAN_AUTH_OPEN;
-
-	at76_dbg(DBG_IOCTL,
-		 "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
-		 "key_len %d auth_mode %s", netdev->name,
-		 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
-		 priv->wep_keys_len[priv->wep_key_id],
-		 (priv->auth_mode ==
-		  WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
-
-	return -EIWCOMMIT;
-}
-
-static int at76_iw_handler_get_encode(struct net_device *netdev,
-				      struct iw_request_info *info,
-				      struct iw_point *encoding, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
-
-	if ((index < 0) || (index >= WEP_KEYS))
-		index = priv->wep_key_id;
-
-	encoding->flags =
-	    (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
-	    IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
-
-	if (!priv->wep_enabled)
-		encoding->flags |= IW_ENCODE_DISABLED;
-
-	if (encoding->pointer) {
-		encoding->length = priv->wep_keys_len[index];
-
-		memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
-
-		encoding->flags |= (index + 1);
-	}
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
-		 "pointer %p len %d", netdev->name, encoding->flags,
-		 encoding->pointer, encoding->length);
-	at76_dbg(DBG_IOCTL,
-		 "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
-		 "key_len %d auth_mode %s", netdev->name,
-		 (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
-		 priv->wep_keys_len[priv->wep_key_id],
-		 (priv->auth_mode ==
-		  WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
-
-	return 0;
-}
-
-static int at76_iw_handler_set_power(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_param *prq, char *extra)
-{
-	int err = -EIWCOMMIT;
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_IOCTL,
-		 "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x",
-		 netdev->name, (prq->disabled) ? "true" : "false", prq->flags,
-		 prq->value);
-
-	if (prq->disabled)
-		priv->pm_mode = AT76_PM_OFF;
-	else {
-		switch (prq->flags & IW_POWER_MODE) {
-		case IW_POWER_ALL_R:
-		case IW_POWER_ON:
-			break;
-		default:
-			err = -EINVAL;
-			goto exit;
-		}
-		if (prq->flags & IW_POWER_PERIOD)
-			priv->pm_period = prq->value;
-
-		if (prq->flags & IW_POWER_TIMEOUT) {
-			err = -EINVAL;
-			goto exit;
-		}
-		priv->pm_mode = AT76_PM_ON;
-	}
-exit:
-	return err;
-}
-
-static int at76_iw_handler_get_power(struct net_device *netdev,
-				     struct iw_request_info *info,
-				     struct iw_param *power, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	power->disabled = (priv->pm_mode == AT76_PM_OFF);
-	if (!power->disabled) {
-		power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R;
-		power->value = priv->pm_period;
-	}
-
-	at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x",
-		 netdev->name, power->disabled ? "disabled" : "enabled",
-		 power->flags, power->value);
-
-	return 0;
-}
-
-/*******************************************************************************
- * Private IOCTLS
- */
-static int at76_iw_set_short_preamble(struct net_device *netdev,
-				      struct iw_request_info *info, char *name,
-				      char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int val = *((int *)name);
-	int ret = -EIWCOMMIT;
-
-	at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
-		 netdev->name, val);
-
-	if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
-		ret = -EINVAL;
-	else
-		priv->preamble_type = val;
-
-	return ret;
-}
-
-static int at76_iw_get_short_preamble(struct net_device *netdev,
-				      struct iw_request_info *info,
-				      union iwreq_data *wrqu, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
-		 preambles[priv->preamble_type], priv->preamble_type);
-	return 0;
-}
-
-static int at76_iw_set_debug(struct net_device *netdev,
-			     struct iw_request_info *info,
-			     struct iw_point *data, char *extra)
-{
-	char *ptr;
-	u32 val;
-
-	if (data->length > 0) {
-		val = simple_strtol(extra, &ptr, 0);
-
-		if (ptr == extra)
-			val = DBG_DEFAULTS;
-
-		at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x",
-			 netdev->name, data->length, extra, val);
-	} else
-		val = DBG_DEFAULTS;
-
-	at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
-		 netdev->name, at76_debug, val);
-
-	/* jal: some more output to pin down lockups */
-	at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d "
-		 "carrier_ok %d", netdev->name, netif_running(netdev),
-		 netif_queue_stopped(netdev), netif_carrier_ok(netdev));
-
-	at76_debug = val;
-
-	return 0;
-}
-
-static int at76_iw_get_debug(struct net_device *netdev,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra)
-{
-	snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
-	return 0;
-}
-
-static int at76_iw_set_powersave_mode(struct net_device *netdev,
-				      struct iw_request_info *info, char *name,
-				      char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int val = *((int *)name);
-	int ret = -EIWCOMMIT;
-
-	at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)",
-		 netdev->name, val,
-		 val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" :
-		 val == AT76_PM_SMART ? "smart save" : "<invalid>");
-	if (val < AT76_PM_OFF || val > AT76_PM_SMART)
-		ret = -EINVAL;
-	else
-		priv->pm_mode = val;
-
-	return ret;
-}
-
-static int at76_iw_get_powersave_mode(struct net_device *netdev,
-				      struct iw_request_info *info,
-				      union iwreq_data *wrqu, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int *param = (int *)extra;
-
-	param[0] = priv->pm_mode;
-	return 0;
-}
-
-static int at76_iw_set_scan_times(struct net_device *netdev,
-				  struct iw_request_info *info, char *name,
-				  char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int mint = *((int *)name);
-	int maxt = *((int *)name + 1);
-	int ret = -EIWCOMMIT;
-
-	at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d",
-		 netdev->name, mint, maxt);
-	if (mint <= 0 || maxt <= 0 || mint > maxt)
-		ret = -EINVAL;
-	else {
-		priv->scan_min_time = mint;
-		priv->scan_max_time = maxt;
-	}
-
-	return ret;
-}
-
-static int at76_iw_get_scan_times(struct net_device *netdev,
-				  struct iw_request_info *info,
-				  union iwreq_data *wrqu, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int *param = (int *)extra;
-
-	param[0] = priv->scan_min_time;
-	param[1] = priv->scan_max_time;
-	return 0;
-}
-
-static int at76_iw_set_scan_mode(struct net_device *netdev,
-				 struct iw_request_info *info, char *name,
-				 char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int val = *((int *)name);
-	int ret = -EIWCOMMIT;
-
-	at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s",
-		 netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
-		 (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
-
-	if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
-		ret = -EINVAL;
-	else
-		priv->scan_mode = val;
-
-	return ret;
-}
-
-static int at76_iw_get_scan_mode(struct net_device *netdev,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int *param = (int *)extra;
-
-	param[0] = priv->scan_mode;
-	return 0;
-}
-
-#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
-
-/* Standard wireless handlers */
-static const iw_handler at76_handlers[] = {
-	AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit),
-	AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name),
-	AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq),
-	AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq),
-	AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode),
-	AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode),
-	AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range),
-	AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy),
-	AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy),
-	AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy),
-	AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy),
-	AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap),
-	AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap),
-	AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan),
-	AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan),
-	AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid),
-	AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid),
-	AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate),
-	AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate),
-	AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts),
-	AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts),
-	AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag),
-	AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag),
-	AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow),
-	AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry),
-	AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry),
-	AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode),
-	AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode),
-	AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power),
-	AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power)
-};
-
-#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
-
-/* Private wireless handlers */
-static const iw_handler at76_priv_handlers[] = {
-	AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble),
-	AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble),
-	AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug),
-	AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug),
-	AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode),
-	AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode),
-	AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times),
-	AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times),
-	AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode),
-	AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode),
-};
-
-/* Names and arguments of private wireless handlers */
-static const struct iw_priv_args at76_priv_args[] = {
-	/* 0 - long, 1 - short */
-	{AT76_SET_SHORT_PREAMBLE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
-
-	{AT76_GET_SHORT_PREAMBLE,
-	 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
-
-	/* we must pass the new debug mask as a string, because iwpriv cannot
-	 * parse hex numbers starting with 0x :-(  */
-	{AT76_SET_DEBUG,
-	 IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"},
-
-	{AT76_GET_DEBUG,
-	 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
-
-	/* 1 - active, 2 - power save, 3 - smart power save */
-	{AT76_SET_POWERSAVE_MODE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"},
-
-	{AT76_GET_POWERSAVE_MODE,
-	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
-
-	/* min_channel_time, max_channel_time */
-	{AT76_SET_SCAN_TIMES,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"},
-
-	{AT76_GET_SCAN_TIMES,
-	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
-
-	/* 0 - active, 1 - passive scan */
-	{AT76_SET_SCAN_MODE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"},
-
-	{AT76_GET_SCAN_MODE,
-	 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
-};
-
-static const struct iw_handler_def at76_handler_def = {
-	.num_standard = ARRAY_SIZE(at76_handlers),
-	.num_private = ARRAY_SIZE(at76_priv_handlers),
-	.num_private_args = ARRAY_SIZE(at76_priv_args),
-	.standard = at76_handlers,
-	.private = at76_priv_handlers,
-	.private_args = at76_priv_args,
-	.get_wireless_stats = at76_get_wireless_stats,
-};
-
-static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
-
-/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
- * a SNAP OID of 0 (0x00, 0x00, 0x00) */
-static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-
-static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	struct net_device_stats *stats = &priv->stats;
-	int ret = 0;
-	int wlen;
-	int submit_len;
-	struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
-	struct ieee80211_hdr_3addr *i802_11_hdr =
-	    (struct ieee80211_hdr_3addr *)tx_buffer->packet;
-	u8 *payload = i802_11_hdr->payload;
-	struct ethhdr *eh = (struct ethhdr *)skb->data;
-
-	if (netif_queue_stopped(netdev)) {
-		printk(KERN_ERR "%s: %s called while netdev is stopped\n",
-		       netdev->name, __func__);
-		/* skip this packet */
-		dev_kfree_skb(skb);
-		return 0;
-	}
-
-	if (priv->tx_urb->status == -EINPROGRESS) {
-		printk(KERN_ERR "%s: %s called while tx urb is pending\n",
-		       netdev->name, __func__);
-		/* skip this packet */
-		dev_kfree_skb(skb);
-		return 0;
-	}
-
-	if (skb->len < ETH_HLEN) {
-		printk(KERN_ERR "%s: %s: skb too short (%d)\n",
-		       netdev->name, __func__, skb->len);
-		dev_kfree_skb(skb);
-		return 0;
-	}
-
-	at76_ledtrig_tx_activity();	/* tell ledtrigger we send a packet */
-
-	/* we can get rid of memcpy if we set netdev->hard_header_len to
-	   reserve enough space, but we would need to keep the skb around */
-
-	if (ntohs(eh->h_proto) <= ETH_DATA_LEN) {
-		/* this is a 802.3 packet */
-		if (skb->len >= ETH_HLEN + sizeof(rfc1042sig)
-		    && skb->data[ETH_HLEN] == rfc1042sig[0]
-		    && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) {
-			/* higher layer delivered SNAP header - keep it */
-			memcpy(payload, skb->data + ETH_HLEN,
-			       skb->len - ETH_HLEN);
-			wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN;
-		} else {
-			printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet "
-			       "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n",
-			       priv->netdev->name, skb->data[ETH_HLEN],
-			       skb->data[ETH_HLEN + 1],
-			       skb->data[ETH_HLEN + 2]);
-			dev_kfree_skb(skb);
-			return 0;
-		}
-	} else {
-		/* add RFC 1042 header in front */
-		memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
-		memcpy(payload + sizeof(rfc1042sig), &eh->h_proto,
-		       skb->len - offsetof(struct ethhdr, h_proto));
-		wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len -
-		    offsetof(struct ethhdr, h_proto);
-	}
-
-	/* make wireless header */
-	i802_11_hdr->frame_ctl =
-	    cpu_to_le16(IEEE80211_FTYPE_DATA |
-			(priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
-			(priv->iw_mode ==
-			 IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
-
-	if (priv->iw_mode == IW_MODE_ADHOC) {
-		memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN);
-		memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
-		memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN);
-	} else if (priv->iw_mode == IW_MODE_INFRA) {
-		memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN);
-		memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
-		memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN);
-	}
-
-	i802_11_hdr->duration_id = cpu_to_le16(0);
-	i802_11_hdr->seq_ctl = cpu_to_le16(0);
-
-	/* setup 'Atmel' header */
-	tx_buffer->wlength = cpu_to_le16(wlen);
-	tx_buffer->tx_rate = priv->txrate;
-	/* for broadcast destination addresses, the firmware 0.100.x
-	   seems to choose the highest rate set with CMD_STARTUP in
-	   basic_rate_set replacing this value */
-
-	memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
-
-	tx_buffer->padding = at76_calc_padding(wlen);
-	submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding;
-
-	at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name,
-		 hex2str(skb->data, 32));
-	at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s",
-		 priv->netdev->name,
-		 le16_to_cpu(tx_buffer->wlength),
-		 tx_buffer->padding, tx_buffer->tx_rate,
-		 hex2str(i802_11_hdr, sizeof(*i802_11_hdr)));
-	at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name,
-		 hex2str(payload, 48));
-
-	/* send stuff */
-	netif_stop_queue(netdev);
-	netdev->trans_start = jiffies;
-
-	usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
-			  submit_len, at76_tx_callback, priv);
-	ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
-	if (ret) {
-		stats->tx_errors++;
-		printk(KERN_ERR "%s: error in tx submit urb: %d\n",
-		       netdev->name, ret);
-		if (ret == -EINVAL)
-			printk(KERN_ERR
-			       "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
-			       priv->netdev->name, priv->tx_urb,
-			       priv->tx_urb->hcpriv, priv->tx_urb->complete);
-	} else
-		stats->tx_bytes += skb->len;
-
-	dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
-}
-
-static void at76_tx_timeout(struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	if (!priv)
-		return;
-	dev_warn(&netdev->dev, "tx timeout.");
-
-	usb_unlink_urb(priv->tx_urb);
-	priv->stats.tx_errors++;
-}
-
-static int at76_submit_rx_urb(struct at76_priv *priv)
-{
-	int ret;
-	int size;
-	struct sk_buff *skb = priv->rx_skb;
-
-	if (!priv->rx_urb) {
-		printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
-		       priv->netdev->name, __func__);
-		return -EFAULT;
-	}
-
-	if (!skb) {
-		skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
-		if (!skb) {
-			printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
-			       priv->netdev->name);
-			ret = -ENOMEM;
-			goto exit;
-		}
-		priv->rx_skb = skb;
-	} else {
-		skb_push(skb, skb_headroom(skb));
-		skb_trim(skb, 0);
-	}
-
-	size = skb_tailroom(skb);
-	usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
-			  skb_put(skb, size), size, at76_rx_callback, priv);
-	ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
-	if (ret < 0) {
-		if (ret == -ENODEV)
-			at76_dbg(DBG_DEVSTART,
-				 "usb_submit_urb returned -ENODEV");
-		else
-			printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
-			       priv->netdev->name, ret);
-	}
-
-exit:
-	if (ret < 0 && ret != -ENODEV)
-		printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
-		       "driver and/or power cycle the device\n",
-		       priv->netdev->name);
-
-	return ret;
-}
-
-static int at76_open(struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	int ret = 0;
-
-	at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__);
-
-	if (mutex_lock_interruptible(&priv->mtx))
-		return -EINTR;
-
-	/* if netdev->dev_addr != priv->mac_addr we must
-	   set the mac address in the device ! */
-	if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) {
-		if (at76_add_mac_address(priv, netdev->dev_addr) >= 0)
-			at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
-				 netdev->name, mac2str(netdev->dev_addr));
-	}
-
-	priv->scan_state = SCAN_IDLE;
-	priv->last_scan = jiffies;
-
-	ret = at76_submit_rx_urb(priv);
-	if (ret < 0) {
-		printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
-		       netdev->name, ret);
-		goto error;
-	}
-
-	schedule_delayed_work(&priv->dwork_restart, 0);
-
-	at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__);
-error:
-	mutex_unlock(&priv->mtx);
-	return ret < 0 ? ret : 0;
-}
-
-static int at76_stop(struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__);
-
-	if (mutex_lock_interruptible(&priv->mtx))
-		return -EINTR;
-
-	at76_quiesce(priv);
-
-	if (!priv->device_unplugged) {
-		/* We are called by "ifconfig ethX down", not because the
-		 * device is not available anymore. */
-		at76_set_radio(priv, 0);
-
-		/* We unlink rx_urb because at76_open() re-submits it.
-		 * If unplugged, at76_delete_device() takes care of it. */
-		usb_kill_urb(priv->rx_urb);
-	}
-
-	/* free the bss_list */
-	at76_free_bss_list(priv);
-
-	mutex_unlock(&priv->mtx);
-	at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__);
-
-	return 0;
-}
-
-static void at76_ethtool_get_drvinfo(struct net_device *netdev,
-				     struct ethtool_drvinfo *info)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-
-	strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
-	strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
-
-	usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info));
-
-	snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d",
-		 priv->fw_version.major, priv->fw_version.minor,
-		 priv->fw_version.patch, priv->fw_version.build);
-}
-
-static u32 at76_ethtool_get_link(struct net_device *netdev)
-{
-	struct at76_priv *priv = netdev_priv(netdev);
-	return priv->mac_state == MAC_CONNECTED;
-}
-
-static struct ethtool_ops at76_ethtool_ops = {
-	.get_drvinfo = at76_ethtool_get_drvinfo,
-	.get_link = at76_ethtool_get_link,
-};
-
-/* Download external firmware */
-static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
-{
-	int ret;
-	int op_mode;
-	int blockno = 0;
-	int bsize;
-	u8 *block;
-	u8 *buf = fwe->extfw;
-	int size = fwe->extfw_size;
-
-	if (!buf || !size)
-		return -ENOENT;
-
-	op_mode = at76_get_op_mode(udev);
-	at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
-
-	if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
-		dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
-			   op_mode);
-		return -EINVAL;
-	}
-
-	block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
-	if (!block)
-		return -ENOMEM;
-
-	at76_dbg(DBG_DEVSTART, "downloading external firmware");
-
-	/* for fw >= 0.100, the device needs an extra empty block */
-	do {
-		bsize = min_t(int, size, FW_BLOCK_SIZE);
-		memcpy(block, buf, bsize);
-		at76_dbg(DBG_DEVSTART,
-			 "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
-			 size, bsize, blockno);
-		ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
-		if (ret != bsize) {
-			dev_printk(KERN_ERR, &udev->dev,
-				   "loading %dth firmware block failed: %d\n",
-				   blockno, ret);
-			goto exit;
-		}
-		buf += bsize;
-		size -= bsize;
-		blockno++;
-	} while (bsize > 0);
-
-	if (at76_is_505a(fwe->board_type)) {
-		at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
-		schedule_timeout_interruptible(HZ / 5 + 1);
-	}
-
-exit:
-	kfree(block);
-	if (ret < 0)
-		dev_printk(KERN_ERR, &udev->dev,
-			   "downloading external firmware failed: %d\n", ret);
-	return ret;
-}
-
-/* Download internal firmware */
-static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
-{
-	int ret;
-	int need_remap = !at76_is_505a(fwe->board_type);
-
-	ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
-				   need_remap ? 0 : 2 * HZ);
-
-	if (ret < 0) {
-		dev_printk(KERN_ERR, &udev->dev,
-			   "downloading internal fw failed with %d\n", ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_DEVSTART, "sending REMAP");
-
-	/* no REMAP for 505A (see SF driver) */
-	if (need_remap) {
-		ret = at76_remap(udev);
-		if (ret < 0) {
-			dev_printk(KERN_ERR, &udev->dev,
-				   "sending REMAP failed with %d\n", ret);
-			goto exit;
-		}
-	}
-
-	at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
-	schedule_timeout_interruptible(2 * HZ + 1);
-	usb_reset_device(udev);
-
-exit:
-	return ret;
-}
-
-static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr)
-{
-	/* common criteria for both modi */
-
-	int ret = (priv->essid_size == 0 /* ANY ssid */  ||
-		   (priv->essid_size == ptr->ssid_len &&
-		    !memcmp(priv->essid, ptr->ssid, ptr->ssid_len)));
-	if (!ret)
-		at76_dbg(DBG_BSS_MATCH,
-			 "%s bss table entry %p: essid didn't match",
-			 priv->netdev->name, ptr);
-	return ret;
-}
-
-static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr)
-{
-	int ret;
-
-	if (priv->iw_mode == IW_MODE_ADHOC)
-		ret = ptr->capa & WLAN_CAPABILITY_IBSS;
-	else
-		ret = ptr->capa & WLAN_CAPABILITY_ESS;
-	if (!ret)
-		at76_dbg(DBG_BSS_MATCH,
-			 "%s bss table entry %p: mode didn't match",
-			 priv->netdev->name, ptr);
-	return ret;
-}
-
-static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr)
-{
-	int i;
-
-	for (i = 0; i < ptr->rates_len; i++) {
-		u8 rate = ptr->rates[i];
-
-		if (!(rate & 0x80))
-			continue;
-
-		/* this is a basic rate we have to support
-		   (see IEEE802.11, ch. 7.3.2.2) */
-		if (rate != (0x80 | hw_rates[0])
-		    && rate != (0x80 | hw_rates[1])
-		    && rate != (0x80 | hw_rates[2])
-		    && rate != (0x80 | hw_rates[3])) {
-			at76_dbg(DBG_BSS_MATCH,
-				 "%s: bss table entry %p: basic rate %02x not "
-				 "supported", priv->netdev->name, ptr, rate);
-			return 0;
-		}
-	}
-
-	/* if we use short preamble, the bss must support it */
-	if (priv->preamble_type == PREAMBLE_TYPE_SHORT &&
-	    !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
-		at76_dbg(DBG_BSS_MATCH,
-			 "%s: %p does not support short preamble",
-			 priv->netdev->name, ptr);
-		return 0;
-	} else
-		return 1;
-}
-
-static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr)
-{
-	if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) {
-		/* we have disabled WEP, but the BSS signals privacy */
-		at76_dbg(DBG_BSS_MATCH,
-			 "%s: bss table entry %p: requires encryption",
-			 priv->netdev->name, ptr);
-		return 0;
-	}
-	/* otherwise if the BSS does not signal privacy it may well
-	   accept encrypted packets from us ... */
-	return 1;
-}
-
-static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr)
-{
-	if (!priv->wanted_bssid_valid ||
-	    !compare_ether_addr(ptr->bssid, priv->wanted_bssid))
-		return 1;
-
-	at76_dbg(DBG_BSS_MATCH,
-		 "%s: requested bssid - %s does not match",
-		 priv->netdev->name, mac2str(priv->wanted_bssid));
-	at76_dbg(DBG_BSS_MATCH,
-		 "      AP bssid - %s of bss table entry %p",
-		 mac2str(ptr->bssid), ptr);
-	return 0;
-}
-
-/**
- * at76_match_bss - try to find a matching bss in priv->bss
- *
- * last - last bss tried
- *
- * last == NULL signals a new round starting with priv->bss_list.next
- * this function must be called inside an acquired priv->bss_list_spinlock
- * otherwise the timeout on bss may remove the newly chosen entry
- */
-static struct bss_info *at76_match_bss(struct at76_priv *priv,
-				       struct bss_info *last)
-{
-	struct bss_info *ptr = NULL;
-	struct list_head *curr;
-
-	curr = last ? last->list.next : priv->bss_list.next;
-	while (curr != &priv->bss_list) {
-		ptr = list_entry(curr, struct bss_info, list);
-		if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr)
-		    && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr)
-		    && at76_match_bssid(priv, ptr))
-			break;
-		curr = curr->next;
-	}
-
-	if (curr == &priv->bss_list)
-		ptr = NULL;
-	/* otherwise ptr points to the struct bss_info we have chosen */
-
-	at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name,
-		 __func__, ptr);
-	return ptr;
-}
-
-/* Start joining a matching BSS, or create own IBSS */
-static void at76_work_join(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      work_join);
-	int ret;
-	unsigned long flags;
-
-	mutex_lock(&priv->mtx);
-
-	WARN_ON(priv->mac_state != MAC_JOINING);
-	if (priv->mac_state != MAC_JOINING)
-		goto exit;
-
-	/* secure the access to priv->curr_bss ! */
-	spin_lock_irqsave(&priv->bss_list_spinlock, flags);
-	priv->curr_bss = at76_match_bss(priv, priv->curr_bss);
-	spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
-
-	if (!priv->curr_bss) {
-		/* here we haven't found a matching (i)bss ... */
-		if (priv->iw_mode == IW_MODE_ADHOC) {
-			at76_set_mac_state(priv, MAC_OWN_IBSS);
-			at76_start_ibss(priv);
-			goto exit;
-		}
-		/* haven't found a matching BSS in infra mode - try again */
-		at76_set_mac_state(priv, MAC_SCANNING);
-		schedule_work(&priv->work_start_scan);
-		goto exit;
-	}
-
-	ret = at76_join_bss(priv, priv->curr_bss);
-	if (ret < 0) {
-		printk(KERN_ERR "%s: join_bss failed with %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	ret = at76_wait_completion(priv, CMD_JOIN);
-	if (ret != CMD_STATUS_COMPLETE) {
-		if (ret != CMD_STATUS_TIME_OUT)
-			printk(KERN_ERR "%s: join_bss completed with %d\n",
-			       priv->netdev->name, ret);
-		else
-			printk(KERN_INFO "%s: join_bss ssid %s timed out\n",
-			       priv->netdev->name,
-			       mac2str(priv->curr_bss->bssid));
-
-		/* retry next BSS immediately */
-		schedule_work(&priv->work_join);
-		goto exit;
-	}
-
-	/* here we have joined the (I)BSS */
-	if (priv->iw_mode == IW_MODE_ADHOC) {
-		struct bss_info *bptr = priv->curr_bss;
-		at76_set_mac_state(priv, MAC_CONNECTED);
-		/* get ESSID, BSSID and channel for priv->curr_bss */
-		priv->essid_size = bptr->ssid_len;
-		memcpy(priv->essid, bptr->ssid, bptr->ssid_len);
-		memcpy(priv->bssid, bptr->bssid, ETH_ALEN);
-		priv->channel = bptr->channel;
-		at76_iwevent_bss_connect(priv->netdev, bptr->bssid);
-		netif_carrier_on(priv->netdev);
-		netif_start_queue(priv->netdev);
-		/* just to be sure */
-		cancel_delayed_work(&priv->dwork_get_scan);
-		cancel_delayed_work(&priv->dwork_auth);
-		cancel_delayed_work(&priv->dwork_assoc);
-	} else {
-		/* send auth req */
-		priv->retries = AUTH_RETRIES;
-		at76_set_mac_state(priv, MAC_AUTH);
-		at76_auth_req(priv, priv->curr_bss, 1, NULL);
-		at76_dbg(DBG_MGMT_TIMER,
-			 "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
-		schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
-	}
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-/* Reap scan results */
-static void at76_dwork_get_scan(struct work_struct *work)
-{
-	int status;
-	int ret;
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      dwork_get_scan.work);
-
-	mutex_lock(&priv->mtx);
-	WARN_ON(priv->mac_state != MAC_SCANNING);
-	if (priv->mac_state != MAC_SCANNING)
-		goto exit;
-
-	status = at76_get_cmd_status(priv->udev, CMD_SCAN);
-	if (status < 0) {
-		printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n",
-		       priv->netdev->name, __func__, status);
-		status = CMD_STATUS_IN_PROGRESS;
-		/* INFO: Hope it was a one off error - if not, scanning
-		   further down the line and stop this cycle */
-	}
-	at76_dbg(DBG_PROGRESS,
-		 "%s %s: got cmd_status %d (state %s, need_any %d)",
-		 priv->netdev->name, __func__, status,
-		 mac_states[priv->mac_state], priv->scan_need_any);
-
-	if (status != CMD_STATUS_COMPLETE) {
-		if ((status != CMD_STATUS_IN_PROGRESS) &&
-		    (status != CMD_STATUS_IDLE))
-			printk(KERN_ERR "%s: %s: Bad scan status: %s\n",
-			       priv->netdev->name, __func__,
-			       at76_get_cmd_status_string(status));
-
-		/* the first cmd status after scan start is always a IDLE ->
-		   start the timer to poll again until COMPLETED */
-		at76_dbg(DBG_MGMT_TIMER,
-			 "%s:%d: starting mgmt_timer for %d ticks",
-			 __func__, __LINE__, SCAN_POLL_INTERVAL);
-		schedule_delayed_work(&priv->dwork_get_scan,
-				      SCAN_POLL_INTERVAL);
-		goto exit;
-	}
-
-	if (at76_debug & DBG_BSS_TABLE)
-		at76_dump_bss_table(priv);
-
-	if (priv->scan_need_any) {
-		ret = at76_start_scan(priv, 0);
-		if (ret < 0)
-			printk(KERN_ERR
-			       "%s: %s: start_scan (ANY) failed with %d\n",
-			       priv->netdev->name, __func__, ret);
-		at76_dbg(DBG_MGMT_TIMER,
-			 "%s:%d: starting mgmt_timer for %d ticks", __func__,
-			 __LINE__, SCAN_POLL_INTERVAL);
-		schedule_delayed_work(&priv->dwork_get_scan,
-				      SCAN_POLL_INTERVAL);
-		priv->scan_need_any = 0;
-	} else {
-		priv->scan_state = SCAN_COMPLETED;
-		/* report the end of scan to user space */
-		at76_iwevent_scan_complete(priv->netdev);
-		at76_set_mac_state(priv, MAC_JOINING);
-		schedule_work(&priv->work_join);
-	}
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-/* Handle loss of beacons from the AP */
-static void at76_dwork_beacon(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      dwork_beacon.work);
-
-	mutex_lock(&priv->mtx);
-	if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA)
-		goto exit;
-
-	/* We haven't received any beacons from out AP for BEACON_TIMEOUT */
-	printk(KERN_INFO "%s: lost beacon bssid %s\n",
-	       priv->netdev->name, mac2str(priv->curr_bss->bssid));
-
-	netif_carrier_off(priv->netdev);
-	netif_stop_queue(priv->netdev);
-	at76_iwevent_bss_disconnect(priv->netdev);
-	at76_set_mac_state(priv, MAC_SCANNING);
-	schedule_work(&priv->work_start_scan);
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-/* Handle authentication response timeout */
-static void at76_dwork_auth(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      dwork_auth.work);
-
-	mutex_lock(&priv->mtx);
-	WARN_ON(priv->mac_state != MAC_AUTH);
-	if (priv->mac_state != MAC_AUTH)
-		goto exit;
-
-	at76_dbg(DBG_PROGRESS, "%s: authentication response timeout",
-		 priv->netdev->name);
-
-	if (priv->retries-- >= 0) {
-		at76_auth_req(priv, priv->curr_bss, 1, NULL);
-		at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
-			 __func__, __LINE__);
-		schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
-	} else {
-		/* try to get next matching BSS */
-		at76_set_mac_state(priv, MAC_JOINING);
-		schedule_work(&priv->work_join);
-	}
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-/* Handle association response timeout */
-static void at76_dwork_assoc(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      dwork_assoc.work);
-
-	mutex_lock(&priv->mtx);
-	WARN_ON(priv->mac_state != MAC_ASSOC);
-	if (priv->mac_state != MAC_ASSOC)
-		goto exit;
-
-	at76_dbg(DBG_PROGRESS, "%s: association response timeout",
-		 priv->netdev->name);
-
-	if (priv->retries-- >= 0) {
-		at76_assoc_req(priv, priv->curr_bss);
-		at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
-			 __func__, __LINE__);
-		schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
-	} else {
-		/* try to get next matching BSS */
-		at76_set_mac_state(priv, MAC_JOINING);
-		schedule_work(&priv->work_join);
-	}
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-/* Read new bssid in ad-hoc mode */
-static void at76_work_new_bss(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      work_new_bss);
-	int ret;
-	struct mib_mac_mgmt mac_mgmt;
-
-	mutex_lock(&priv->mtx);
-
-	ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt,
-			   sizeof(struct mib_mac_mgmt));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
-		       priv->netdev->name, ret);
-		goto exit;
-	}
-
-	at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change);
-	memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN);
-	at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid));
-
-	at76_iwevent_bss_connect(priv->netdev, priv->bssid);
-
-	priv->mib_buf.type = MIB_MAC_MGMT;
-	priv->mib_buf.size = 1;
-	priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
-	priv->mib_buf.data.byte = 0;
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
-		       priv->netdev->name, ret);
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-static int at76_startup_device(struct at76_priv *priv)
-{
-	struct at76_card_config *ccfg = &priv->card_config;
-	int ret;
-
-	at76_dbg(DBG_PARAMS,
-		 "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
-		 "keylen %d", priv->netdev->name, priv->essid_size, priv->essid,
-		 hex2str(priv->essid, IW_ESSID_MAX_SIZE),
-		 priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
-		 priv->channel, priv->wep_enabled ? "enabled" : "disabled",
-		 priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
-	at76_dbg(DBG_PARAMS,
-		 "%s param: preamble %s rts %d retry %d frag %d "
-		 "txrate %s auth_mode %d", priv->netdev->name,
-		 preambles[priv->preamble_type], priv->rts_threshold,
-		 priv->short_retry_limit, priv->frag_threshold,
-		 priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
-		 TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
-		 TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
-		 TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
-		 TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
-	at76_dbg(DBG_PARAMS,
-		 "%s param: pm_mode %d pm_period %d auth_mode %s "
-		 "scan_times %d %d scan_mode %s",
-		 priv->netdev->name, priv->pm_mode, priv->pm_period,
-		 priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
-		 priv->scan_min_time, priv->scan_max_time,
-		 priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
-
-	memset(ccfg, 0, sizeof(struct at76_card_config));
-	ccfg->promiscuous_mode = 0;
-	ccfg->short_retry_limit = priv->short_retry_limit;
-
-	if (priv->wep_enabled) {
-		if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
-			ccfg->encryption_type = 2;
-		else
-			ccfg->encryption_type = 1;
-
-		/* jal: always exclude unencrypted if WEP is active */
-		ccfg->exclude_unencrypted = 1;
-	} else {
-		ccfg->exclude_unencrypted = 0;
-		ccfg->encryption_type = 0;
-	}
-
-	ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
-	ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
-
-	memcpy(ccfg->basic_rate_set, hw_rates, 4);
-	/* jal: really needed, we do a set_mib for autorate later ??? */
-	ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
-	ccfg->channel = priv->channel;
-	ccfg->privacy_invoked = priv->wep_enabled;
-	memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
-	ccfg->ssid_len = priv->essid_size;
-
-	ccfg->wep_default_key_id = priv->wep_key_id;
-	memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN);
-
-	ccfg->short_preamble = priv->preamble_type;
-	ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
-
-	ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
-				    sizeof(struct at76_card_config));
-	if (ret < 0) {
-		printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
-		       priv->netdev->name, ret);
-		return ret;
-	}
-
-	at76_wait_completion(priv, CMD_STARTUP);
-
-	/* remove BSSID from previous run */
-	memset(priv->bssid, 0, ETH_ALEN);
-
-	if (at76_set_radio(priv, 1) == 1)
-		at76_wait_completion(priv, CMD_RADIO_ON);
-
-	ret = at76_set_preamble(priv, priv->preamble_type);
-	if (ret < 0)
-		return ret;
-
-	ret = at76_set_frag(priv, priv->frag_threshold);
-	if (ret < 0)
-		return ret;
-
-	ret = at76_set_rts(priv, priv->rts_threshold);
-	if (ret < 0)
-		return ret;
-
-	ret = at76_set_autorate_fallback(priv,
-					 priv->txrate == TX_RATE_AUTO ? 1 : 0);
-	if (ret < 0)
-		return ret;
-
-	ret = at76_set_pm_mode(priv);
-	if (ret < 0)
-		return ret;
-
-	if (at76_debug & DBG_MIB) {
-		at76_dump_mib_mac(priv);
-		at76_dump_mib_mac_addr(priv);
-		at76_dump_mib_mac_mgmt(priv);
-		at76_dump_mib_mac_wep(priv);
-		at76_dump_mib_mdomain(priv);
-		at76_dump_mib_phy(priv);
-		at76_dump_mib_local(priv);
-	}
-
-	return 0;
-}
-
-/* Restart the interface */
-static void at76_dwork_restart(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      dwork_restart.work);
-
-	mutex_lock(&priv->mtx);
-
-	netif_carrier_off(priv->netdev);	/* stop netdev watchdog */
-	netif_stop_queue(priv->netdev);	/* stop tx data packets */
-
-	at76_startup_device(priv);
-
-	if (priv->iw_mode != IW_MODE_MONITOR) {
-		priv->netdev->type = ARPHRD_ETHER;
-		at76_set_mac_state(priv, MAC_SCANNING);
-		schedule_work(&priv->work_start_scan);
-	} else {
-		priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
-		at76_start_monitor(priv);
-	}
-
-	mutex_unlock(&priv->mtx);
-}
-
-/* Initiate scanning */
-static void at76_work_start_scan(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      work_start_scan);
-	int ret;
-
-	mutex_lock(&priv->mtx);
-
-	WARN_ON(priv->mac_state != MAC_SCANNING);
-	if (priv->mac_state != MAC_SCANNING)
-		goto exit;
-
-	/* only clear the bss list when a scan is actively initiated,
-	 * otherwise simply rely on at76_bss_list_timeout */
-	if (priv->scan_state == SCAN_IN_PROGRESS) {
-		at76_free_bss_list(priv);
-		priv->scan_need_any = 1;
-	} else
-		priv->scan_need_any = 0;
-
-	ret = at76_start_scan(priv, 1);
-
-	if (ret < 0)
-		printk(KERN_ERR "%s: %s: start_scan failed with %d\n",
-		       priv->netdev->name, __func__, ret);
-	else {
-		at76_dbg(DBG_MGMT_TIMER,
-			 "%s:%d: starting mgmt_timer for %d ticks",
-			 __func__, __LINE__, SCAN_POLL_INTERVAL);
-		schedule_delayed_work(&priv->dwork_get_scan,
-				      SCAN_POLL_INTERVAL);
-	}
-
-exit:
-	mutex_unlock(&priv->mtx);
-}
-
-/* Enable or disable promiscuous mode */
-static void at76_work_set_promisc(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      work_set_promisc);
-	int ret = 0;
-
-	mutex_lock(&priv->mtx);
-
-	priv->mib_buf.type = MIB_LOCAL;
-	priv->mib_buf.size = 1;
-	priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
-	priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
-
-	ret = at76_set_mib(priv, &priv->mib_buf);
-	if (ret < 0)
-		printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
-		       priv->netdev->name, ret);
-
-	mutex_unlock(&priv->mtx);
-}
-
-/* Submit Rx urb back to the device */
-static void at76_work_submit_rx(struct work_struct *work)
-{
-	struct at76_priv *priv = container_of(work, struct at76_priv,
-					      work_submit_rx);
-
-	mutex_lock(&priv->mtx);
-	at76_submit_rx_urb(priv);
-	mutex_unlock(&priv->mtx);
-}
-
-/* We got an association response */
-static void at76_rx_mgmt_assoc(struct at76_priv *priv,
-			       struct at76_rx_buffer *buf)
-{
-	struct ieee80211_assoc_response *resp =
-	    (struct ieee80211_assoc_response *)buf->packet;
-	u16 assoc_id = le16_to_cpu(resp->aid);
-	u16 status = le16_to_cpu(resp->status);
-
-	at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status "
-		 "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name,
-		 mac2str(resp->header.addr3), le16_to_cpu(resp->capability),
-		 status, assoc_id, hex2str(resp->info_element->data,
-					   resp->info_element->len));
-
-	if (priv->mac_state != MAC_ASSOC) {
-		printk(KERN_INFO "%s: AssocResp in state %s ignored\n",
-		       priv->netdev->name, mac_states[priv->mac_state]);
-		return;
-	}
-
-	BUG_ON(!priv->curr_bss);
-
-	cancel_delayed_work(&priv->dwork_assoc);
-	if (status == WLAN_STATUS_SUCCESS) {
-		struct bss_info *ptr = priv->curr_bss;
-		priv->assoc_id = assoc_id & 0x3fff;
-		/* update iwconfig params */
-		memcpy(priv->bssid, ptr->bssid, ETH_ALEN);
-		memcpy(priv->essid, ptr->ssid, ptr->ssid_len);
-		priv->essid_size = ptr->ssid_len;
-		priv->channel = ptr->channel;
-		schedule_work(&priv->work_assoc_done);
-	} else {
-		at76_set_mac_state(priv, MAC_JOINING);
-		schedule_work(&priv->work_join);
-	}
-}
-
-/* Process disassociation request from the AP */
-static void at76_rx_mgmt_disassoc(struct at76_priv *priv,
-				  struct at76_rx_buffer *buf)
-{
-	struct ieee80211_disassoc *resp =
-	    (struct ieee80211_disassoc *)buf->packet;
-	struct ieee80211_hdr_3addr *mgmt = &resp->header;
-
-	at76_dbg(DBG_RX_MGMT,
-		 "%s: rx DisAssoc bssid %s reason 0x%04x destination %s",
-		 priv->netdev->name, mac2str(mgmt->addr3),
-		 le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
-
-	/* We are not connected, ignore */
-	if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT
-	    || !priv->curr_bss)
-		return;
-
-	/* Not our BSSID, ignore */
-	if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
-		return;
-
-	/* Not for our STA and not broadcast, ignore */
-	if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
-	    && !is_broadcast_ether_addr(mgmt->addr1))
-		return;
-
-	if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED
-	    && priv->mac_state != MAC_JOINING) {
-		printk(KERN_INFO "%s: DisAssoc in state %s ignored\n",
-		       priv->netdev->name, mac_states[priv->mac_state]);
-		return;
-	}
-
-	if (priv->mac_state == MAC_CONNECTED) {
-		netif_carrier_off(priv->netdev);
-		netif_stop_queue(priv->netdev);
-		at76_iwevent_bss_disconnect(priv->netdev);
-	}
-	cancel_delayed_work(&priv->dwork_get_scan);
-	cancel_delayed_work(&priv->dwork_beacon);
-	cancel_delayed_work(&priv->dwork_auth);
-	cancel_delayed_work(&priv->dwork_assoc);
-	at76_set_mac_state(priv, MAC_JOINING);
-	schedule_work(&priv->work_join);
-}
-
-static void at76_rx_mgmt_auth(struct at76_priv *priv,
-			      struct at76_rx_buffer *buf)
-{
-	struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet;
-	struct ieee80211_hdr_3addr *mgmt = &resp->header;
-	int seq_nr = le16_to_cpu(resp->transaction);
-	int alg = le16_to_cpu(resp->algorithm);
-	int status = le16_to_cpu(resp->status);
-
-	at76_dbg(DBG_RX_MGMT,
-		 "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
-		 "destination %s", priv->netdev->name, mac2str(mgmt->addr3),
-		 alg, seq_nr, status, mac2str(mgmt->addr1));
-
-	if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2)
-		at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
-			 priv->netdev->name, hex2str(resp->info_element, 18));
-
-	if (priv->mac_state != MAC_AUTH) {
-		printk(KERN_INFO "%s: ignored AuthFrame in state %s\n",
-		       priv->netdev->name, mac_states[priv->mac_state]);
-		return;
-	}
-	if (priv->auth_mode != alg) {
-		printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n",
-		       priv->netdev->name, alg);
-		return;
-	}
-
-	BUG_ON(!priv->curr_bss);
-
-	/* Not our BSSID or not for our STA, ignore */
-	if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)
-	    || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1))
-		return;
-
-	cancel_delayed_work(&priv->dwork_auth);
-	if (status != WLAN_STATUS_SUCCESS) {
-		/* try to join next bss */
-		at76_set_mac_state(priv, MAC_JOINING);
-		schedule_work(&priv->work_join);
-		return;
-	}
-
-	if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) {
-		priv->retries = ASSOC_RETRIES;
-		at76_set_mac_state(priv, MAC_ASSOC);
-		at76_assoc_req(priv, priv->curr_bss);
-		at76_dbg(DBG_MGMT_TIMER,
-			 "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
-		schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
-		return;
-	}
-
-	WARN_ON(seq_nr != 2);
-	at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element);
-	at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__,
-		 __LINE__);
-	schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
-}
-
-static void at76_rx_mgmt_deauth(struct at76_priv *priv,
-				struct at76_rx_buffer *buf)
-{
-	struct ieee80211_disassoc *resp =
-	    (struct ieee80211_disassoc *)buf->packet;
-	struct ieee80211_hdr_3addr *mgmt = &resp->header;
-
-	at76_dbg(DBG_RX_MGMT | DBG_PROGRESS,
-		 "%s: rx DeAuth bssid %s reason 0x%04x destination %s",
-		 priv->netdev->name, mac2str(mgmt->addr3),
-		 le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
-
-	if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC
-	    && priv->mac_state != MAC_CONNECTED) {
-		printk(KERN_INFO "%s: DeAuth in state %s ignored\n",
-		       priv->netdev->name, mac_states[priv->mac_state]);
-		return;
-	}
-
-	BUG_ON(!priv->curr_bss);
-
-	/* Not our BSSID, ignore */
-	if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
-		return;
-
-	/* Not for our STA and not broadcast, ignore */
-	if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
-	    && !is_broadcast_ether_addr(mgmt->addr1))
-		return;
-
-	if (priv->mac_state == MAC_CONNECTED)
-		at76_iwevent_bss_disconnect(priv->netdev);
-
-	at76_set_mac_state(priv, MAC_JOINING);
-	schedule_work(&priv->work_join);
-	cancel_delayed_work(&priv->dwork_get_scan);
-	cancel_delayed_work(&priv->dwork_beacon);
-	cancel_delayed_work(&priv->dwork_auth);
-	cancel_delayed_work(&priv->dwork_assoc);
-}
-
-static void at76_rx_mgmt_beacon(struct at76_priv *priv,
-				struct at76_rx_buffer *buf)
-{
-	int varpar_len;
-	/* beacon content */
-	struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet;
-	struct ieee80211_hdr_3addr *mgmt = &bdata->header;
-
-	struct list_head *lptr;
-	struct bss_info *match;	/* entry matching addr3 with its bssid */
-	int new_entry = 0;
-	int len;
-	struct ieee80211_info_element *ie;
-	int have_ssid = 0;
-	int have_rates = 0;
-	int have_channel = 0;
-	int keep_going = 1;
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->bss_list_spinlock, flags);
-	if (priv->mac_state == MAC_CONNECTED) {
-		/* in state MAC_CONNECTED we use the mgmt_timer to control
-		   the beacon of the BSS */
-		BUG_ON(!priv->curr_bss);
-
-		if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) {
-			/* We got our AP's beacon, defer the timeout handler.
-			   Kill pending work first, as schedule_delayed_work()
-			   won't do it. */
-			cancel_delayed_work(&priv->dwork_beacon);
-			schedule_delayed_work(&priv->dwork_beacon,
-					      BEACON_TIMEOUT);
-			priv->curr_bss->rssi = buf->rssi;
-			priv->beacons_received++;
-			goto exit;
-		}
-	}
-
-	/* look if we have this BSS already in the list */
-	match = NULL;
-
-	if (!list_empty(&priv->bss_list)) {
-		list_for_each(lptr, &priv->bss_list) {
-			struct bss_info *bss_ptr =
-			    list_entry(lptr, struct bss_info, list);
-			if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) {
-				match = bss_ptr;
-				break;
-			}
-		}
-	}
-
-	if (!match) {
-		/* BSS not in the list - append it */
-		match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC);
-		if (!match) {
-			at76_dbg(DBG_BSS_TABLE,
-				 "%s: cannot kmalloc new bss info (%zd byte)",
-				 priv->netdev->name, sizeof(struct bss_info));
-			goto exit;
-		}
-		new_entry = 1;
-		list_add_tail(&match->list, &priv->bss_list);
-	}
-
-	match->capa = le16_to_cpu(bdata->capability);
-	match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
-	match->rssi = buf->rssi;
-	match->link_qual = buf->link_quality;
-	match->noise_level = buf->noise_level;
-	memcpy(match->bssid, mgmt->addr3, ETH_ALEN);
-	at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name,
-		 mac2str(match->bssid));
-
-	ie = bdata->info_element;
-
-	/* length of var length beacon parameters */
-	varpar_len = min_t(int, le16_to_cpu(buf->wlength) -
-			   sizeof(struct ieee80211_beacon),
-			   BEACON_MAX_DATA_LENGTH);
-
-	/* This routine steps through the bdata->data array to get
-	 * some useful information about the access point.
-	 * Currently, this implementation supports receipt of: SSID,
-	 * supported transfer rates and channel, in any order, with some
-	 * tolerance for intermittent unknown codes (although this
-	 * functionality may not be necessary as the useful information will
-	 * usually arrive in consecutively, but there have been some
-	 * reports of some of the useful information fields arriving in a
-	 * different order).
-	 * It does not support any more IE types although MFIE_TYPE_TIM may
-	 * be supported (on my AP at least).
-	 * The bdata->data array is about 1500 bytes long but only ~36 of those
-	 * bytes are useful, hence the have_ssid etc optimizations. */
-
-	while (keep_going &&
-	       ((&ie->data[ie->len] - (u8 *)bdata->info_element) <=
-		varpar_len)) {
-
-		switch (ie->id) {
-
-		case WLAN_EID_SSID:
-			if (have_ssid)
-				break;
-
-			len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
-
-			/* we copy only if this is a new entry,
-			   or the incoming SSID is not a hidden SSID. This
-			   will protect us from overwriting a real SSID read
-			   in a ProbeResponse with a hidden one from a
-			   following beacon. */
-			if (!new_entry && at76_is_hidden_ssid(ie->data, len)) {
-				have_ssid = 1;
-				break;
-			}
-
-			match->ssid_len = len;
-			memcpy(match->ssid, ie->data, len);
-			at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s",
-				 priv->netdev->name, len, match->ssid);
-			have_ssid = 1;
-			break;
-
-		case WLAN_EID_SUPP_RATES:
-			if (have_rates)
-				break;
-
-			match->rates_len =
-			    min_t(int, sizeof(match->rates), ie->len);
-			memcpy(match->rates, ie->data, match->rates_len);
-			have_rates = 1;
-			at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s",
-				 priv->netdev->name,
-				 hex2str(ie->data, ie->len));
-			break;
-
-		case WLAN_EID_DS_PARAMS:
-			if (have_channel)
-				break;
-
-			match->channel = ie->data[0];
-			have_channel = 1;
-			at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
-				 priv->netdev->name, match->channel);
-			break;
-
-		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,
-				 hex2str(ie->data, ie->len));
-			break;
-		}
-
-		/* advance to the next informational element */
-		next_ie(&ie);
-
-		/* Optimization: after all, the bdata->data array is
-		 * varpar_len bytes long, whereas we get all of the useful
-		 * information after only ~36 bytes, this saves us a lot of
-		 * time (and trouble as the remaining portion of the array
-		 * could be full of junk)
-		 * Comment this out if you want to see what other information
-		 * comes from the AP - although little of it may be useful */
-	}
-
-	at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
-		 priv->netdev->name);
-
-	match->last_rx = jiffies;	/* record last rx of beacon */
-
-exit:
-	spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
-}
-
-/* Calculate the link level from a given rx_buffer */
-static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf,
-			    struct iw_quality *qual)
-{
-	/* just a guess for now, might be different for other chips */
-	int max_rssi = 42;
-
-	qual->level = (buf->rssi * 100 / max_rssi);
-	if (qual->level > 100)
-		qual->level = 100;
-	qual->updated |= IW_QUAL_LEVEL_UPDATED;
-}
-
-/* Calculate the link quality from a given rx_buffer */
-static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf,
-			   struct iw_quality *qual)
-{
-	if (at76_is_intersil(priv->board_type))
-		qual->qual = buf->link_quality;
-	else {
-		unsigned long elapsed;
-
-		/* Update qual at most once a second */
-		elapsed = jiffies - priv->beacons_last_qual;
-		if (elapsed < 1 * HZ)
-			return;
-
-		qual->qual = qual->level * priv->beacons_received *
-		    msecs_to_jiffies(priv->beacon_period) / elapsed;
-
-		priv->beacons_last_qual = jiffies;
-		priv->beacons_received = 0;
-	}
-	qual->qual = (qual->qual > 100) ? 100 : qual->qual;
-	qual->updated |= IW_QUAL_QUAL_UPDATED;
-}
-
-/* Calculate the noise quality from a given rx_buffer */
-static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf,
-			    struct iw_quality *qual)
-{
-	qual->noise = 0;
-	qual->updated |= IW_QUAL_NOISE_INVALID;
-}
-
-static void at76_update_wstats(struct at76_priv *priv,
-			       struct at76_rx_buffer *buf)
-{
-	struct iw_quality *qual = &priv->wstats.qual;
-
-	if (buf->rssi && priv->mac_state == MAC_CONNECTED) {
-		qual->updated = 0;
-		at76_calc_level(priv, buf, qual);
-		at76_calc_qual(priv, buf, qual);
-		at76_calc_noise(priv, buf, qual);
-	} else {
-		qual->qual = 0;
-		qual->level = 0;
-		qual->noise = 0;
-		qual->updated = IW_QUAL_ALL_INVALID;
-	}
-}
-
-static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf)
-{
-	struct ieee80211_hdr_3addr *mgmt =
-	    (struct ieee80211_hdr_3addr *)buf->packet;
-	u16 framectl = le16_to_cpu(mgmt->frame_ctl);
-
-	/* update wstats */
-	if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) {
-		/* jal: this is a dirty hack needed by Tim in ad-hoc mode */
-		/* Data packets always seem to have a 0 link level, so we
-		   only read link quality info from management packets.
-		   Atmel driver actually averages the present, and previous
-		   values, we just present the raw value at the moment - TJS */
-		if (priv->iw_mode == IW_MODE_ADHOC
-		    || (priv->curr_bss
-			&& !compare_ether_addr(mgmt->addr3,
-					       priv->curr_bss->bssid)))
-			at76_update_wstats(priv, buf);
-	}
-
-	at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s",
-		 priv->netdev->name, framectl,
-		 hex2str(mgmt, le16_to_cpu(buf->wlength)));
-
-	switch (framectl & IEEE80211_FCTL_STYPE) {
-	case IEEE80211_STYPE_BEACON:
-	case IEEE80211_STYPE_PROBE_RESP:
-		at76_rx_mgmt_beacon(priv, buf);
-		break;
-
-	case IEEE80211_STYPE_ASSOC_RESP:
-		at76_rx_mgmt_assoc(priv, buf);
-		break;
-
-	case IEEE80211_STYPE_DISASSOC:
-		at76_rx_mgmt_disassoc(priv, buf);
-		break;
-
-	case IEEE80211_STYPE_AUTH:
-		at76_rx_mgmt_auth(priv, buf);
-		break;
-
-	case IEEE80211_STYPE_DEAUTH:
-		at76_rx_mgmt_deauth(priv, buf);
-		break;
-
-	default:
-		printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
-		       priv->netdev->name, framectl);
-	}
-
-	return;
-}
-
-/* Convert the 802.11 header into an ethernet-style header, make skb
- * ready for consumption by netif_rx() */
-static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
-{
-	struct ieee80211_hdr_3addr *i802_11_hdr;
-	struct ethhdr *eth_hdr_p;
-	u8 *src_addr;
-	u8 *dest_addr;
-
-	i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
-
-	/* That would be the ethernet header if the hardware converted
-	 * the frame for us.  Make sure the source and the destination
-	 * match the 802.11 header.  Which hardware does it? */
-	eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN);
-
-	dest_addr = i802_11_hdr->addr1;
-	if (iw_mode == IW_MODE_ADHOC)
-		src_addr = i802_11_hdr->addr2;
-	else
-		src_addr = i802_11_hdr->addr3;
-
-	if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) &&
-	    !compare_ether_addr(eth_hdr_p->h_dest, dest_addr))
-		/* Yes, we already have an ethernet header */
-		skb_reset_mac_header(skb);
-	else {
-		u16 len;
-
-		/* Need to build an ethernet header */
-		if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
-			/* SNAP frame - decapsulate, keep proto */
-			skb_push(skb, offsetof(struct ethhdr, h_proto) -
-				 sizeof(rfc1042sig));
-			len = 0;
-		} else {
-			/* 802.3 frame, proto is length */
-			len = skb->len;
-			skb_push(skb, ETH_HLEN);
-		}
-
-		skb_reset_mac_header(skb);
-		eth_hdr_p = eth_hdr(skb);
-		/* This needs to be done in this order (eth_hdr_p->h_dest may
-		 * overlap src_addr) */
-		memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
-		memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
-		if (len)
-			eth_hdr_p->h_proto = htons(len);
-	}
-
-	skb->protocol = eth_type_trans(skb, skb->dev);
-}
-
-/* Check for fragmented data in priv->rx_skb. If the packet was no fragment
-   or it was the last of a fragment set a skb containing the whole packet
-   is returned for further processing. Otherwise we get NULL and are
-   done and the packet is either stored inside the fragment buffer
-   or thrown away.  Every returned skb starts with the ieee802_11 header
-   and contains _no_ FCS at the end */
-static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv)
-{
-	struct sk_buff *skb = priv->rx_skb;
-	struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
-	struct ieee80211_hdr_3addr *i802_11_hdr =
-	    (struct ieee80211_hdr_3addr *)buf->packet;
-	/* seq_ctrl, fragment_number, sequence number of new packet */
-	u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
-	u16 fragnr = sctl & 0xf;
-	u16 seqnr = sctl >> 4;
-	u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
-
-	/* Length including the IEEE802.11 header, but without the trailing
-	 * FCS and without the Atmel Rx header */
-	int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN;
-
-	/* where does the data payload start in skb->data ? */
-	u8 *data = i802_11_hdr->payload;
-
-	/* length of payload, excl. the trailing FCS */
-	int data_len = length - IEEE80211_3ADDR_LEN;
-
-	int i;
-	struct rx_data_buf *bptr, *optr;
-	unsigned long oldest = ~0UL;
-
-	at76_dbg(DBG_RX_FRAGS,
-		 "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
-		 "length %d data %d: %s ...", priv->netdev->name, frame_ctl,
-		 mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len,
-		 hex2str(data, 32));
-
-	at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
-		 "tail %p end %p len %d", priv->netdev->name, skb->head,
-		 skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
-		 skb->len);
-
-	if (data_len < 0) {
-		/* make sure data starts in the buffer */
-		printk(KERN_INFO "%s: data frame too short\n",
-		       priv->netdev->name);
-		return NULL;
-	}
-
-	WARN_ON(length <= AT76_RX_HDRLEN);
-	if (length <= AT76_RX_HDRLEN)
-		return NULL;
-
-	/* remove the at76_rx_buffer header - we don't need it anymore */
-	/* we need the IEEE802.11 header (for the addresses) if this packet
-	   is the first of a chain */
-	skb_pull(skb, AT76_RX_HDRLEN);
-
-	/* remove FCS at end */
-	skb_trim(skb, length);
-
-	at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
-		 "end %p len %d data %p data_len %d", priv->netdev->name,
-		 skb->head, skb->data, skb_tail_pointer(skb),
-		 skb_end_pointer(skb), skb->len, data, data_len);
-
-	if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
-		/* unfragmented packet received */
-		/* Use a new skb for the next receive */
-		priv->rx_skb = NULL;
-		at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name);
-		return skb;
-	}
-
-	/* look if we've got a chain for the sender address.
-	   afterwards optr points to first free or the oldest entry,
-	   or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
-	   sender address */
-	/* determining the oldest entry doesn't cope with jiffies wrapping
-	   but I don't care to delete a young entry at these rare moments ... */
-
-	bptr = priv->rx_data;
-	optr = NULL;
-	for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) {
-		if (!bptr->skb) {
-			optr = bptr;
-			oldest = 0UL;
-			continue;
-		}
-
-		if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender))
-			break;
-
-		if (!optr) {
-			optr = bptr;
-			oldest = bptr->last_rx;
-		} else if (bptr->last_rx < oldest)
-			optr = bptr;
-	}
-
-	if (i < NR_RX_DATA_BUF) {
-
-		at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) "
-			 "matched sender addr",
-			 priv->netdev->name, i, bptr->seqnr, bptr->fragnr);
-
-		/* bptr points to an entry for the sender address */
-		if (bptr->seqnr == seqnr) {
-			int left;
-			/* the fragment has the current sequence number */
-			if (((bptr->fragnr + 1) & 0xf) != fragnr) {
-				/* wrong fragment number -> ignore it */
-				/* is & 0xf necessary above ??? */
-				at76_dbg(DBG_RX_FRAGS,
-					 "%s: frag nr mismatch: %d + 1 != %d",
-					 priv->netdev->name, bptr->fragnr,
-					 fragnr);
-				return NULL;
-			}
-			bptr->last_rx = jiffies;
-			/* the next following fragment number ->
-			   add the data at the end */
-
-			/* for test only ??? */
-			left = skb_tailroom(bptr->skb);
-			if (left < data_len)
-				printk(KERN_INFO
-				       "%s: only %d byte free (need %d)\n",
-				       priv->netdev->name, left, data_len);
-			else
-				memcpy(skb_put(bptr->skb, data_len), data,
-				       data_len);
-
-			bptr->fragnr = fragnr;
-			if (frame_ctl & IEEE80211_FCTL_MOREFRAGS)
-				return NULL;
-
-			/* this was the last fragment - send it */
-			skb = bptr->skb;
-			bptr->skb = NULL;	/* free the entry */
-			at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
-				 priv->netdev->name, seqnr);
-			return skb;
-		}
-
-		/* got another sequence number */
-		if (fragnr == 0) {
-			/* it's the start of a new chain - replace the
-			   old one by this */
-			/* bptr->sender has the correct value already */
-			at76_dbg(DBG_RX_FRAGS,
-				 "%s: start of new seq %d, removing old seq %d",
-				 priv->netdev->name, seqnr, bptr->seqnr);
-			bptr->seqnr = seqnr;
-			bptr->fragnr = 0;
-			bptr->last_rx = jiffies;
-			/* swap bptr->skb and priv->rx_skb */
-			skb = bptr->skb;
-			bptr->skb = priv->rx_skb;
-			priv->rx_skb = skb;
-		} else {
-			/* it from the middle of a new chain ->
-			   delete the old entry and skip the new one */
-			at76_dbg(DBG_RX_FRAGS,
-				 "%s: middle of new seq %d (%d) "
-				 "removing old seq %d",
-				 priv->netdev->name, seqnr, fragnr,
-				 bptr->seqnr);
-			dev_kfree_skb(bptr->skb);
-			bptr->skb = NULL;
-		}
-		return NULL;
-	}
-
-	/* if we didn't find a chain for the sender address, optr
-	   points either to the first free or the oldest entry */
-
-	if (fragnr != 0) {
-		/* this is not the begin of a fragment chain ... */
-		at76_dbg(DBG_RX_FRAGS,
-			 "%s: no chain for non-first fragment (%d)",
-			 priv->netdev->name, fragnr);
-		return NULL;
-	}
-
-	BUG_ON(!optr);
-	if (optr->skb) {
-		/* swap the skb's */
-		skb = optr->skb;
-		optr->skb = priv->rx_skb;
-		priv->rx_skb = skb;
-
-		at76_dbg(DBG_RX_FRAGS,
-			 "%s: free old contents: sender %s seq/frag %d/%d",
-			 priv->netdev->name, mac2str(optr->sender),
-			 optr->seqnr, optr->fragnr);
-
-	} else {
-		/* take the skb from priv->rx_skb */
-		optr->skb = priv->rx_skb;
-		/* let at76_submit_rx_urb() allocate a new skb */
-		priv->rx_skb = NULL;
-
-		at76_dbg(DBG_RX_FRAGS, "%s: use a free entry",
-			 priv->netdev->name);
-	}
-	memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
-	optr->seqnr = seqnr;
-	optr->fragnr = 0;
-	optr->last_rx = jiffies;
-
-	return NULL;
-}
-
-/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */
-static void at76_rx_data(struct at76_priv *priv)
-{
-	struct net_device *netdev = priv->netdev;
-	struct net_device_stats *stats = &priv->stats;
-	struct sk_buff *skb = priv->rx_skb;
-	struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
-	struct ieee80211_hdr_3addr *i802_11_hdr;
-	int length = le16_to_cpu(buf->wlength);
-
-	at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name,
-		 hex2str(skb->data, AT76_RX_HDRLEN));
-
-	at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s",
-		 hex2str(skb->data + AT76_RX_HDRLEN, length));
-
-	skb = at76_check_for_rx_frags(priv);
-	if (!skb)
-		return;
-
-	/* Atmel header and the FCS are already removed */
-	i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
-
-	skb->dev = netdev;
-	skb->ip_summed = CHECKSUM_NONE;	/* TODO: should check CRC */
-
-	if (is_broadcast_ether_addr(i802_11_hdr->addr1)) {
-		if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast))
-			skb->pkt_type = PACKET_BROADCAST;
-		else
-			skb->pkt_type = PACKET_MULTICAST;
-	} else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr))
-		skb->pkt_type = PACKET_OTHERHOST;
-
-	at76_ieee80211_to_eth(skb, priv->iw_mode);
-
-	netdev->last_rx = jiffies;
-	netif_rx(skb);
-	stats->rx_packets++;
-	stats->rx_bytes += length;
-
-	return;
-}
-
-static void at76_rx_monitor_mode(struct at76_priv *priv)
-{
-	struct at76_rx_radiotap *rt;
-	u8 *payload;
-	int skblen;
-	struct net_device *netdev = priv->netdev;
-	struct at76_rx_buffer *buf =
-	    (struct at76_rx_buffer *)priv->rx_skb->data;
-	/* length including the IEEE802.11 header and the trailing FCS,
-	   but not at76_rx_buffer */
-	int length = le16_to_cpu(buf->wlength);
-	struct sk_buff *skb = priv->rx_skb;
-	struct net_device_stats *stats = &priv->stats;
-
-	if (length < IEEE80211_FCS_LEN) {
-		/* buffer contains no data */
-		at76_dbg(DBG_MONITOR_MODE,
-			 "%s: MONITOR MODE: rx skb without data",
-			 priv->netdev->name);
-		return;
-	}
-
-	skblen = sizeof(struct at76_rx_radiotap) + length;
-
-	skb = dev_alloc_skb(skblen);
-	if (!skb) {
-		printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap "
-		       "header returned NULL\n", priv->netdev->name);
-		return;
-	}
-
-	skb_put(skb, skblen);
-
-	rt = (struct at76_rx_radiotap *)skb->data;
-	payload = skb->data + sizeof(struct at76_rx_radiotap);
-
-	rt->rt_hdr.it_version = 0;
-	rt->rt_hdr.it_pad = 0;
-	rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap));
-	rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT);
-
-	rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time));
-	rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80);
-	rt->rt_signal = buf->rssi;
-	rt->rt_noise = buf->noise_level;
-	rt->rt_flags = IEEE80211_RADIOTAP_F_FCS;
-	if (buf->fragmentation)
-		rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG;
-
-	memcpy(payload, buf->packet, length);
-	skb->dev = netdev;
-	skb->ip_summed = CHECKSUM_NONE;
-	skb_reset_mac_header(skb);
-	skb->pkt_type = PACKET_OTHERHOST;
-	skb->protocol = htons(ETH_P_802_2);
-
-	netdev->last_rx = jiffies;
-	netif_rx(skb);
-	stats->rx_packets++;
-	stats->rx_bytes += length;
-}
-
-/* Check if we spy on the sender address in buf and update stats */
-static void at76_iwspy_update(struct at76_priv *priv,
-			      struct at76_rx_buffer *buf)
-{
-	struct ieee80211_hdr_3addr *hdr =
-	    (struct ieee80211_hdr_3addr *)buf->packet;
-	struct iw_quality qual;
-
-	/* We can only set the level here */
-	qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
-	qual.level = 0;
-	qual.noise = 0;
-	at76_calc_level(priv, buf, &qual);
-
-	spin_lock_bh(&priv->spy_spinlock);
-
-	if (priv->spy_data.spy_number > 0)
-		wireless_spy_update(priv->netdev, hdr->addr2, &qual);
-
-	spin_unlock_bh(&priv->spy_spinlock);
-}
-
-static void at76_rx_tasklet(unsigned long param)
-{
-	struct urb *urb = (struct urb *)param;
-	struct at76_priv *priv = urb->context;
-	struct net_device *netdev = priv->netdev;
-	struct at76_rx_buffer *buf;
-	struct ieee80211_hdr_3addr *i802_11_hdr;
-	u16 frame_ctl;
-
-	if (priv->device_unplugged) {
-		at76_dbg(DBG_DEVSTART, "device unplugged");
-		if (urb)
-			at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
-		return;
-	}
-
-	if (!priv->rx_skb || !netdev || !priv->rx_skb->data)
-		return;
-
-	buf = (struct at76_rx_buffer *)priv->rx_skb->data;
-
-	i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
-
-	frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
-
-	if (urb->status != 0) {
-		if (urb->status != -ENOENT && urb->status != -ECONNRESET)
-			at76_dbg(DBG_URB,
-				 "%s %s: - nonzero Rx bulk status received: %d",
-				 __func__, netdev->name, urb->status);
-		return;
-	}
-
-	at76_dbg(DBG_RX_ATMEL_HDR,
-		 "%s: rx frame: rate %d rssi %d noise %d link %d %s",
-		 priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level,
-		 buf->link_quality, hex2str(i802_11_hdr, 48));
-	if (priv->iw_mode == IW_MODE_MONITOR) {
-		at76_rx_monitor_mode(priv);
-		goto exit;
-	}
-
-	/* there is a new bssid around, accept it: */
-	if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) {
-		at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
-		schedule_work(&priv->work_new_bss);
-	}
-
-	switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
-	case IEEE80211_FTYPE_DATA:
-		at76_rx_data(priv);
-		break;
-
-	case IEEE80211_FTYPE_MGMT:
-		/* jal: TODO: find out if we can update iwspy also on
-		   other frames than management (might depend on the
-		   radio chip / firmware version !) */
-
-		at76_iwspy_update(priv, buf);
-
-		at76_rx_mgmt(priv, buf);
-		break;
-
-	case IEEE80211_FTYPE_CTL:
-		at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x",
-			 priv->netdev->name, frame_ctl);
-		break;
-
-	default:
-		printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
-		       priv->netdev->name, frame_ctl);
-	}
-exit:
-	at76_submit_rx_urb(priv);
-}
-
-/* Load firmware into kernel memory and parse it */
-static struct fwentry *at76_load_firmware(struct usb_device *udev,
-					  enum board_type board_type)
-{
-	int ret;
-	char *str;
-	struct at76_fw_header *fwh;
-	struct fwentry *fwe = &firmwares[board_type];
-
-	mutex_lock(&fw_mutex);
-
-	if (fwe->loaded) {
-		at76_dbg(DBG_FW, "re-using previously loaded fw");
-		goto exit;
-	}
-
-	at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
-	ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
-	if (ret < 0) {
-		dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
-			   fwe->fwname);
-		dev_printk(KERN_ERR, &udev->dev,
-			   "you may need to download the firmware from "
-			   "http://developer.berlios.de/projects/at76c503a/");
-		goto exit;
-	}
-
-	at76_dbg(DBG_FW, "got it.");
-	fwh = (struct at76_fw_header *)(fwe->fw->data);
-
-	if (fwe->fw->size <= sizeof(*fwh)) {
-		dev_printk(KERN_ERR, &udev->dev,
-			   "firmware is too short (0x%zx)\n", fwe->fw->size);
-		goto exit;
-	}
-
-	/* CRC currently not checked */
-	fwe->board_type = le32_to_cpu(fwh->board_type);
-	if (fwe->board_type != board_type) {
-		dev_printk(KERN_ERR, &udev->dev,
-			   "board type mismatch, requested %u, got %u\n",
-			   board_type, fwe->board_type);
-		goto exit;
-	}
-
-	fwe->fw_version.major = fwh->major;
-	fwe->fw_version.minor = fwh->minor;
-	fwe->fw_version.patch = fwh->patch;
-	fwe->fw_version.build = fwh->build;
-
-	str = (char *)fwh + le32_to_cpu(fwh->str_offset);
-	fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
-	fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
-	fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
-	fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
-
-	fwe->loaded = 1;
-
-	dev_printk(KERN_DEBUG, &udev->dev,
-		   "using firmware %s (version %d.%d.%d-%d)\n",
-		   fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
-
-	at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
-		 le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
-		 le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
-	at76_dbg(DBG_DEVSTART, "firmware id %s", str);
-
-exit:
-	mutex_unlock(&fw_mutex);
-
-	if (fwe->loaded)
-		return fwe;
-	else
-		return NULL;
-}
-
-/* Allocate network device and initialize private data */
-static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
-{
-	struct net_device *netdev;
-	struct at76_priv *priv;
-	int i;
-
-	/* allocate memory for our device state and initialize it */
-	netdev = alloc_etherdev(sizeof(struct at76_priv));
-	if (!netdev) {
-		dev_printk(KERN_ERR, &udev->dev, "out of memory\n");
-		return NULL;
-	}
-
-	priv = netdev_priv(netdev);
-
-	priv->udev = udev;
-	priv->netdev = netdev;
-
-	mutex_init(&priv->mtx);
-	INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done);
-	INIT_WORK(&priv->work_join, at76_work_join);
-	INIT_WORK(&priv->work_new_bss, at76_work_new_bss);
-	INIT_WORK(&priv->work_start_scan, at76_work_start_scan);
-	INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
-	INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
-	INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart);
-	INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan);
-	INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon);
-	INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth);
-	INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc);
-
-	spin_lock_init(&priv->mgmt_spinlock);
-	priv->next_mgmt_bulk = NULL;
-	priv->mac_state = MAC_INIT;
-
-	/* initialize empty BSS list */
-	priv->curr_bss = NULL;
-	INIT_LIST_HEAD(&priv->bss_list);
-	spin_lock_init(&priv->bss_list_spinlock);
-
-	init_timer(&priv->bss_list_timer);
-	priv->bss_list_timer.data = (unsigned long)priv;
-	priv->bss_list_timer.function = at76_bss_list_timeout;
-
-	spin_lock_init(&priv->spy_spinlock);
-
-	/* mark all rx data entries as unused */
-	for (i = 0; i < NR_RX_DATA_BUF; i++)
-		priv->rx_data[i].skb = NULL;
-
-	priv->rx_tasklet.func = at76_rx_tasklet;
-	priv->rx_tasklet.data = 0;
-
-	priv->pm_mode = AT76_PM_OFF;
-	priv->pm_period = 0;
-
-	return priv;
-}
-
-static int at76_alloc_urbs(struct at76_priv *priv,
-			   struct usb_interface *interface)
-{
-	struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
-	int i;
-	int buffer_size;
-	struct usb_host_interface *iface_desc;
-
-	at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
-
-	at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
-		 interface->altsetting[0].desc.bNumEndpoints);
-
-	ep_in = NULL;
-	ep_out = NULL;
-	iface_desc = interface->cur_altsetting;
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
-		endpoint = &iface_desc->endpoint[i].desc;
-
-		at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
-			 __func__, i, endpoint->bEndpointAddress,
-			 endpoint->bmAttributes);
-
-		if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
-			ep_in = endpoint;
-
-		if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
-			ep_out = endpoint;
-	}
-
-	if (!ep_in || !ep_out) {
-		dev_printk(KERN_ERR, &interface->dev,
-			   "bulk endpoints missing\n");
-		return -ENXIO;
-	}
-
-	priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
-	priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
-
-	priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
-	priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!priv->rx_urb || !priv->tx_urb) {
-		dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
-		return -ENOMEM;
-	}
-
-	buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
-	priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
-	if (!priv->bulk_out_buffer) {
-		dev_printk(KERN_ERR, &interface->dev,
-			   "cannot allocate output buffer\n");
-		return -ENOMEM;
-	}
-
-	at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
-
-	return 0;
-}
-
-static const struct net_device_ops at76_netdev_ops = {
-	.ndo_open		= at76_open,
-	.ndo_stop		= at76_stop,
-	.ndo_get_stats		= at76_get_stats,
-	.ndo_start_xmit		= at76_tx,
-	.ndo_tx_timeout		= at76_tx_timeout,
-	.ndo_set_multicast_list	= at76_set_multicast,
-	.ndo_set_mac_address	= at76_set_mac_address,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_change_mtu		= eth_change_mtu,
-};
-
-/* Register network device and initialize the hardware */
-static int at76_init_new_device(struct at76_priv *priv,
-				struct usb_interface *interface)
-{
-	struct net_device *netdev = priv->netdev;
-	int ret;
-
-	/* set up the endpoint information */
-	/* check out the endpoints */
-
-	at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
-		 interface->cur_altsetting->desc.bNumEndpoints);
-
-	ret = at76_alloc_urbs(priv, interface);
-	if (ret < 0)
-		goto exit;
-
-	/* MAC address */
-	ret = at76_get_hw_config(priv);
-	if (ret < 0) {
-		dev_printk(KERN_ERR, &interface->dev,
-			   "cannot get MAC address\n");
-		goto exit;
-	}
-
-	priv->domain = at76_get_reg_domain(priv->regulatory_domain);
-	/* init. netdev->dev_addr */
-	memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN);
-
-	priv->channel = DEF_CHANNEL;
-	priv->iw_mode = IW_MODE_INFRA;
-	priv->rts_threshold = DEF_RTS_THRESHOLD;
-	priv->frag_threshold = DEF_FRAG_THRESHOLD;
-	priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
-	priv->txrate = TX_RATE_AUTO;
-	priv->preamble_type = PREAMBLE_TYPE_LONG;
-	priv->beacon_period = 100;
-	priv->beacons_last_qual = jiffies;
-	priv->auth_mode = WLAN_AUTH_OPEN;
-	priv->scan_min_time = DEF_SCAN_MIN_TIME;
-	priv->scan_max_time = DEF_SCAN_MAX_TIME;
-	priv->scan_mode = SCAN_TYPE_ACTIVE;
-
-	netdev->flags &= ~IFF_MULTICAST;	/* not yet or never */
-	netdev->netdev_ops = &at76_netdev_ops;
-	netdev->ethtool_ops = &at76_ethtool_ops;
-
-	/* Add pointers to enable iwspy support. */
-	priv->wireless_data.spy_data = &priv->spy_data;
-	netdev->wireless_data = &priv->wireless_data;
-
-	netdev->watchdog_timeo = 2 * HZ;
-	netdev->wireless_handlers = &at76_handler_def;
-	dev_alloc_name(netdev, "wlan%d");
-
-	ret = register_netdev(priv->netdev);
-	if (ret) {
-		dev_printk(KERN_ERR, &interface->dev,
-			   "cannot register netdevice (status %d)!\n", ret);
-		goto exit;
-	}
-	priv->netdev_registered = 1;
-
-	printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
-	       netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr),
-	       priv->fw_version.major, priv->fw_version.minor,
-	       priv->fw_version.patch, priv->fw_version.build);
-	printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name,
-	       priv->regulatory_domain, priv->domain->name);
-
-	/* we let this timer run the whole time this driver instance lives */
-	mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
-
-exit:
-	return ret;
-}
-
-static void at76_delete_device(struct at76_priv *priv)
-{
-	int i;
-
-	at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
-
-	/* The device is gone, don't bother turning it off */
-	priv->device_unplugged = 1;
-
-	if (priv->netdev_registered)
-		unregister_netdev(priv->netdev);
-
-	/* assuming we used keventd, it must quiesce too */
-	flush_scheduled_work();
-
-	kfree(priv->bulk_out_buffer);
-
-	if (priv->tx_urb) {
-		usb_kill_urb(priv->tx_urb);
-		usb_free_urb(priv->tx_urb);
-	}
-	if (priv->rx_urb) {
-		usb_kill_urb(priv->rx_urb);
-		usb_free_urb(priv->rx_urb);
-	}
-
-	at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
-
-	kfree_skb(priv->rx_skb);
-
-	at76_free_bss_list(priv);
-	del_timer_sync(&priv->bss_list_timer);
-	cancel_delayed_work(&priv->dwork_get_scan);
-	cancel_delayed_work(&priv->dwork_beacon);
-	cancel_delayed_work(&priv->dwork_auth);
-	cancel_delayed_work(&priv->dwork_assoc);
-
-	if (priv->mac_state == MAC_CONNECTED)
-		at76_iwevent_bss_disconnect(priv->netdev);
-
-	for (i = 0; i < NR_RX_DATA_BUF; i++)
-		if (priv->rx_data[i].skb) {
-			dev_kfree_skb(priv->rx_data[i].skb);
-			priv->rx_data[i].skb = NULL;
-		}
-	usb_put_dev(priv->udev);
-
-	at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__);
-	free_netdev(priv->netdev);	/* priv is in netdev */
-
-	at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
-}
-
-static int at76_probe(struct usb_interface *interface,
-		      const struct usb_device_id *id)
-{
-	int ret;
-	struct at76_priv *priv;
-	struct fwentry *fwe;
-	struct usb_device *udev;
-	int op_mode;
-	int need_ext_fw = 0;
-	struct mib_fw_version fwv;
-	int board_type = (int)id->driver_info;
-
-	udev = usb_get_dev(interface_to_usbdev(interface));
-
-	/* Load firmware into kernel memory */
-	fwe = at76_load_firmware(udev, board_type);
-	if (!fwe) {
-		ret = -ENOENT;
-		goto error;
-	}
-
-	op_mode = at76_get_op_mode(udev);
-
-	at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
-
-	/* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
-	   we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
-
-	if (op_mode == OPMODE_HW_CONFIG_MODE) {
-		dev_printk(KERN_ERR, &interface->dev,
-			   "cannot handle a device in HW_CONFIG_MODE\n");
-		ret = -EBUSY;
-		goto error;
-	}
-
-	if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
-	    && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
-		/* download internal firmware part */
-		dev_printk(KERN_DEBUG, &interface->dev,
-			   "downloading internal firmware\n");
-		ret = at76_load_internal_fw(udev, fwe);
-		if (ret < 0) {
-			dev_printk(KERN_ERR, &interface->dev,
-				   "error %d downloading internal firmware\n",
-				   ret);
-			goto error;
-		}
-		usb_put_dev(udev);
-		return ret;
-	}
-
-	/* Internal firmware already inside the device.  Get firmware
-	 * version to test if external firmware is loaded.
-	 * This works only for newer firmware, e.g. the Intersil 0.90.x
-	 * says "control timeout on ep0in" and subsequent
-	 * at76_get_op_mode() fail too :-( */
-
-	/* if version >= 0.100.x.y or device with built-in flash we can
-	 * query the device for the fw version */
-	if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
-	    || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
-		ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
-		if (ret < 0 || (fwv.major | fwv.minor) == 0)
-			need_ext_fw = 1;
-	} else
-		/* No way to check firmware version, reload to be sure */
-		need_ext_fw = 1;
-
-	if (need_ext_fw) {
-		dev_printk(KERN_DEBUG, &interface->dev,
-			   "downloading external firmware\n");
-
-		ret = at76_load_external_fw(udev, fwe);
-		if (ret)
-			goto error;
-
-		/* Re-check firmware version */
-		ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
-		if (ret < 0) {
-			dev_printk(KERN_ERR, &interface->dev,
-				   "error %d getting firmware version\n", ret);
-			goto error;
-		}
-	}
-
-	priv = at76_alloc_new_device(udev);
-	if (!priv) {
-		ret = -ENOMEM;
-		goto error;
-	}
-
-	SET_NETDEV_DEV(priv->netdev, &interface->dev);
-	usb_set_intfdata(interface, priv);
-
-	memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
-	priv->board_type = board_type;
-
-	ret = at76_init_new_device(priv, interface);
-	if (ret < 0)
-		at76_delete_device(priv);
-
-	return ret;
-
-error:
-	usb_put_dev(udev);
-	return ret;
-}
-
-static void at76_disconnect(struct usb_interface *interface)
-{
-	struct at76_priv *priv;
-
-	priv = usb_get_intfdata(interface);
-	usb_set_intfdata(interface, NULL);
-
-	/* Disconnect after loading internal firmware */
-	if (!priv)
-		return;
-
-	printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
-	at76_delete_device(priv);
-	dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
-}
-
-/* Structure for registering this driver with the USB subsystem */
-static struct usb_driver at76_driver = {
-	.name = DRIVER_NAME,
-	.probe = at76_probe,
-	.disconnect = at76_disconnect,
-	.id_table = dev_table,
-};
-
-static int __init at76_mod_init(void)
-{
-	int result;
-
-	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
-
-	mutex_init(&fw_mutex);
-
-	/* register this driver with the USB subsystem */
-	result = usb_register(&at76_driver);
-	if (result < 0)
-		printk(KERN_ERR DRIVER_NAME
-		       ": usb_register failed (status %d)\n", result);
-
-	led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
-	return result;
-}
-
-static void __exit at76_mod_exit(void)
-{
-	int i;
-
-	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
-	usb_deregister(&at76_driver);
-	for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
-		if (firmwares[i].fw)
-			release_firmware(firmwares[i].fw);
-	}
-	led_trigger_unregister_simple(ledtrig_tx);
-}
-
-module_param_named(debug, at76_debug, int, 0600);
-MODULE_PARM_DESC(debug, "Debugging level");
-
-module_init(at76_mod_init);
-module_exit(at76_mod_exit);
-
-MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
-MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
-MODULE_AUTHOR("Alex <alex@foogod.com>");
-MODULE_AUTHOR("Nick Jones");
-MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
-MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
deleted file mode 100644
index 6d60c6e..0000000
--- a/drivers/staging/at76_usb/at76_usb.h
+++ /dev/null
@@ -1,706 +0,0 @@
-/*
- * Copyright (c) 2002,2003 Oliver Kurth
- *	     (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
- *	     (c) 2007 Guido Guenther <agx@sigxcpu.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 driver was based on information from the Sourceforge driver
- * released and maintained by Atmel:
- *
- *  http://sourceforge.net/projects/atmelwlandriver/
- *
- * Although the code was completely re-written,
- * it would have been impossible without Atmel's decision to
- * release an Open Source driver (unfortunately the firmware was
- * kept binary only). Thanks for that decision to Atmel!
- */
-
-#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,
-	BOARD_503_ISL3863 = 2,
-	BOARD_503 = 3,
-	BOARD_503_ACC = 4,
-	BOARD_505 = 5,
-	BOARD_505_2958 = 6,
-	BOARD_505A = 7,
-	BOARD_505AMX = 8
-};
-
-/* our private ioctl's */
-/* preamble length (0 - long, 1 - short, 2 - auto) */
-#define AT76_SET_SHORT_PREAMBLE		(SIOCIWFIRSTPRIV + 0)
-#define AT76_GET_SHORT_PREAMBLE		(SIOCIWFIRSTPRIV + 1)
-/* which debug channels are enabled */
-#define AT76_SET_DEBUG			(SIOCIWFIRSTPRIV + 2)
-#define AT76_GET_DEBUG			(SIOCIWFIRSTPRIV + 3)
-/* power save mode (incl. the Atmel proprietary smart save mode) */
-#define AT76_SET_POWERSAVE_MODE		(SIOCIWFIRSTPRIV + 4)
-#define AT76_GET_POWERSAVE_MODE		(SIOCIWFIRSTPRIV + 5)
-/* min and max channel times for scan */
-#define AT76_SET_SCAN_TIMES		(SIOCIWFIRSTPRIV + 6)
-#define AT76_GET_SCAN_TIMES		(SIOCIWFIRSTPRIV + 7)
-/* scan mode (0 - active, 1 - passive) */
-#define AT76_SET_SCAN_MODE		(SIOCIWFIRSTPRIV + 8)
-#define AT76_GET_SCAN_MODE		(SIOCIWFIRSTPRIV + 9)
-
-#define CMD_STATUS_IDLE				0x00
-#define CMD_STATUS_COMPLETE			0x01
-#define CMD_STATUS_UNKNOWN			0x02
-#define CMD_STATUS_INVALID_PARAMETER		0x03
-#define CMD_STATUS_FUNCTION_NOT_SUPPORTED	0x04
-#define CMD_STATUS_TIME_OUT			0x07
-#define CMD_STATUS_IN_PROGRESS			0x08
-#define CMD_STATUS_HOST_FAILURE			0xff
-#define CMD_STATUS_SCAN_FAILED			0xf0
-
-/* answers to get op mode */
-#define OPMODE_NONE				0x00
-#define OPMODE_NORMAL_NIC_WITH_FLASH		0x01
-#define OPMODE_HW_CONFIG_MODE			0x02
-#define OPMODE_DFU_MODE_WITH_FLASH		0x03
-#define OPMODE_NORMAL_NIC_WITHOUT_FLASH		0x04
-
-#define CMD_SET_MIB		0x01
-#define CMD_GET_MIB		0x02
-#define CMD_SCAN		0x03
-#define CMD_JOIN		0x04
-#define CMD_START_IBSS		0x05
-#define CMD_RADIO_ON		0x06
-#define CMD_RADIO_OFF		0x07
-#define CMD_STARTUP		0x0B
-
-#define MIB_LOCAL		0x01
-#define MIB_MAC_ADDR		0x02
-#define MIB_MAC			0x03
-#define MIB_MAC_MGMT		0x05
-#define MIB_MAC_WEP		0x06
-#define MIB_PHY			0x07
-#define MIB_FW_VERSION		0x08
-#define MIB_MDOMAIN		0x09
-
-#define ADHOC_MODE		1
-#define INFRASTRUCTURE_MODE	2
-
-/* values for struct mib_local, field preamble_type */
-#define PREAMBLE_TYPE_LONG	0
-#define PREAMBLE_TYPE_SHORT	1
-#define PREAMBLE_TYPE_AUTO	2
-
-/* values for tx_rate */
-#define TX_RATE_1MBIT		0
-#define TX_RATE_2MBIT		1
-#define TX_RATE_5_5MBIT 	2
-#define TX_RATE_11MBIT		3
-#define TX_RATE_AUTO		4
-
-/* power management modes */
-#define AT76_PM_OFF		1
-#define AT76_PM_ON		2
-#define AT76_PM_SMART		3
-
-struct hwcfg_r505 {
-	u8 cr39_values[14];
-	u8 reserved1[14];
-	u8 bb_cr[14];
-	u8 pidvid[4];
-	u8 mac_addr[ETH_ALEN];
-	u8 regulatory_domain;
-	u8 reserved2[14];
-	u8 cr15_values[14];
-	u8 reserved3[3];
-} __attribute__((packed));
-
-struct hwcfg_rfmd {
-	u8 cr20_values[14];
-	u8 cr21_values[14];
-	u8 bb_cr[14];
-	u8 pidvid[4];
-	u8 mac_addr[ETH_ALEN];
-	u8 regulatory_domain;
-	u8 low_power_values[14];
-	u8 normal_power_values[14];
-	u8 reserved1[3];
-} __attribute__((packed));
-
-struct hwcfg_intersil {
-	u8 mac_addr[ETH_ALEN];
-	u8 cr31_values[14];
-	u8 cr58_values[14];
-	u8 pidvid[4];
-	u8 regulatory_domain;
-	u8 reserved[1];
-} __attribute__((packed));
-
-union at76_hwcfg {
-	struct hwcfg_intersil i;
-	struct hwcfg_rfmd r3;
-	struct hwcfg_r505 r5;
-};
-
-#define WEP_SMALL_KEY_LEN	(40 / 8)
-#define WEP_LARGE_KEY_LEN	(104 / 8)
-
-struct at76_card_config {
-	u8 exclude_unencrypted;
-	u8 promiscuous_mode;
-	u8 short_retry_limit;
-	u8 encryption_type;
-	__le16 rts_threshold;
-	__le16 fragmentation_threshold;	/* 256..2346 */
-	u8 basic_rate_set[4];
-	u8 auto_rate_fallback;	/* 0,1 */
-	u8 channel;
-	u8 privacy_invoked;
-	u8 wep_default_key_id;	/* 0..3 */
-	u8 current_ssid[32];
-	u8 wep_default_key_value[4][WEP_KEY_LEN];
-	u8 ssid_len;
-	u8 short_preamble;
-	__le16 beacon_period;
-} __attribute__((packed));
-
-struct at76_command {
-	u8 cmd;
-	u8 reserved;
-	__le16 size;
-	u8 data[0];
-} __attribute__((packed));
-
-/* Length of Atmel-specific Rx header before 802.11 frame */
-#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
-
-struct at76_rx_buffer {
-	__le16 wlength;
-	u8 rx_rate;
-	u8 newbss;
-	u8 fragmentation;
-	u8 rssi;
-	u8 link_quality;
-	u8 noise_level;
-	__le32 rx_time;
-	u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
-} __attribute__((packed));
-
-/* Length of Atmel-specific Tx header before 802.11 frame */
-#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
-
-struct at76_tx_buffer {
-	__le16 wlength;
-	u8 tx_rate;
-	u8 padding;
-	u8 reserved[4];
-	u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
-} __attribute__((packed));
-
-/* defines for scan_type below */
-#define SCAN_TYPE_ACTIVE	0
-#define SCAN_TYPE_PASSIVE	1
-
-struct at76_req_scan {
-	u8 bssid[ETH_ALEN];
-	u8 essid[32];
-	u8 scan_type;
-	u8 channel;
-	__le16 probe_delay;
-	__le16 min_channel_time;
-	__le16 max_channel_time;
-	u8 essid_size;
-	u8 international_scan;
-} __attribute__((packed));
-
-struct at76_req_ibss {
-	u8 bssid[ETH_ALEN];
-	u8 essid[32];
-	u8 bss_type;
-	u8 channel;
-	u8 essid_size;
-	u8 reserved[3];
-} __attribute__((packed));
-
-struct at76_req_join {
-	u8 bssid[ETH_ALEN];
-	u8 essid[32];
-	u8 bss_type;
-	u8 channel;
-	__le16 timeout;
-	u8 essid_size;
-	u8 reserved;
-} __attribute__((packed));
-
-struct set_mib_buffer {
-	u8 type;
-	u8 size;
-	u8 index;
-	u8 reserved;
-	union {
-		u8 byte;
-		__le16 word;
-		u8 addr[ETH_ALEN];
-	} data;
-} __attribute__((packed));
-
-struct mib_local {
-	u16 reserved0;
-	u8 beacon_enable;
-	u8 txautorate_fallback;
-	u8 reserved1;
-	u8 ssid_size;
-	u8 promiscuous_mode;
-	u16 reserved2;
-	u8 preamble_type;
-	u16 reserved3;
-} __attribute__((packed));
-
-struct mib_mac_addr {
-	u8 mac_addr[ETH_ALEN];
-	u8 res[2];		/* ??? */
-	u8 group_addr[4][ETH_ALEN];
-	u8 group_addr_status[4];
-} __attribute__((packed));
-
-struct mib_mac {
-	__le32 max_tx_msdu_lifetime;
-	__le32 max_rx_lifetime;
-	__le16 frag_threshold;
-	__le16 rts_threshold;
-	__le16 cwmin;
-	__le16 cwmax;
-	u8 short_retry_time;
-	u8 long_retry_time;
-	u8 scan_type;		/* active or passive */
-	u8 scan_channel;
-	__le16 probe_delay;	/* delay before ProbeReq in active scan, RO */
-	__le16 min_channel_time;
-	__le16 max_channel_time;
-	__le16 listen_interval;
-	u8 desired_ssid[32];
-	u8 desired_bssid[ETH_ALEN];
-	u8 desired_bsstype;	/* ad-hoc or infrastructure */
-	u8 reserved2;
-} __attribute__((packed));
-
-struct mib_mac_mgmt {
-	__le16 beacon_period;
-	__le16 CFP_max_duration;
-	__le16 medium_occupancy_limit;
-	__le16 station_id;	/* assoc id */
-	__le16 ATIM_window;
-	u8 CFP_mode;
-	u8 privacy_option_implemented;
-	u8 DTIM_period;
-	u8 CFP_period;
-	u8 current_bssid[ETH_ALEN];
-	u8 current_essid[32];
-	u8 current_bss_type;
-	u8 power_mgmt_mode;
-	/* rfmd and 505 */
-	u8 ibss_change;
-	u8 res;
-	u8 multi_domain_capability_implemented;
-	u8 multi_domain_capability_enabled;
-	u8 country_string[3];
-	u8 reserved[3];
-} __attribute__((packed));
-
-struct mib_mac_wep {
-	u8 privacy_invoked;	/* 0 disable encr., 1 enable encr */
-	u8 wep_default_key_id;
-	u8 wep_key_mapping_len;
-	u8 exclude_unencrypted;
-	__le32 wep_icv_error_count;
-	__le32 wep_excluded_count;
-	u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
-	u8 encryption_level;	/* 1 for 40bit, 2 for 104bit encryption */
-} __attribute__((packed));
-
-struct mib_phy {
-	__le32 ed_threshold;
-
-	__le16 slot_time;
-	__le16 sifs_time;
-	__le16 preamble_length;
-	__le16 plcp_header_length;
-	__le16 mpdu_max_length;
-	__le16 cca_mode_supported;
-
-	u8 operation_rate_set[4];
-	u8 channel_id;
-	u8 current_cca_mode;
-	u8 phy_type;
-	u8 current_reg_domain;
-} __attribute__((packed));
-
-struct mib_fw_version {
-	u8 major;
-	u8 minor;
-	u8 patch;
-	u8 build;
-} __attribute__((packed));
-
-struct mib_mdomain {
-	u8 tx_powerlevel[14];
-	u8 channel_list[14];	/* 0 for invalid channels */
-} __attribute__((packed));
-
-struct at76_fw_header {
-	__le32 crc;		/* CRC32 of the whole image */
-	__le32 board_type;	/* firmware compatibility code */
-	u8 build;		/* firmware build number */
-	u8 patch;		/* firmware patch level */
-	u8 minor;		/* firmware minor version */
-	u8 major;		/* firmware major version */
-	__le32 str_offset;	/* offset of the copyright string */
-	__le32 int_fw_offset;	/* internal firmware image offset */
-	__le32 int_fw_len;	/* internal firmware image length */
-	__le32 ext_fw_offset;	/* external firmware image offset */
-	__le32 ext_fw_len;	/* external firmware image length */
-} __attribute__((packed));
-
-enum mac_state {
-	MAC_INIT,
-	MAC_SCANNING,
-	MAC_AUTH,
-	MAC_ASSOC,
-	MAC_JOINING,
-	MAC_CONNECTED,
-	MAC_OWN_IBSS
-};
-
-/* a description of a regulatory domain and the allowed channels */
-struct reg_domain {
-	u16 code;
-	char const *name;
-	u32 channel_map;	/* if bit N is set, channel (N+1) is allowed */
-};
-
-/* how long do we keep a (I)BSS in the bss_list in jiffies
-   this should be long enough for the user to retrieve the table
-   (by iwlist ?) after the device started, because all entries from
-   other channels than the one the device locks on get removed, too */
-#define BSS_LIST_TIMEOUT	(120 * HZ)
-/* struct to store BSS info found during scan */
-#define BSS_LIST_MAX_RATE_LEN	32	/* 32 rates should be enough ... */
-
-struct bss_info {
-	struct list_head list;
-
-	u8 bssid[ETH_ALEN];	/* bssid */
-	u8 ssid[IW_ESSID_MAX_SIZE];	/* essid */
-	u8 ssid_len;		/* length of ssid above */
-	u8 channel;
-	u16 capa;		/* BSS capabilities */
-	u16 beacon_interval;	/* beacon interval, Kus (1024 microseconds) */
-	u8 rates[BSS_LIST_MAX_RATE_LEN];	/* supported rates in units of
-						   500 kbps, ORed with 0x80 for
-						   basic rates */
-	u8 rates_len;
-
-	/* quality of received beacon */
-	u8 rssi;
-	u8 link_qual;
-	u8 noise_level;
-
-	unsigned long last_rx;	/* time (jiffies) of last beacon received */
-};
-
-/* a rx data buffer to collect rx fragments */
-struct rx_data_buf {
-	u8 sender[ETH_ALEN];	/* sender address */
-	u16 seqnr;		/* sequence number */
-	u16 fragnr;		/* last fragment received */
-	unsigned long last_rx;	/* jiffies of last rx */
-	struct sk_buff *skb;	/* == NULL if entry is free */
-};
-
-#define NR_RX_DATA_BUF		8
-
-/* Data for one loaded firmware file */
-struct fwentry {
-	const char *const fwname;
-	const struct firmware *fw;
-	int extfw_size;
-	int intfw_size;
-	/* pointer to loaded firmware, no need to free */
-	u8 *extfw;		/* external firmware, extfw_size bytes long */
-	u8 *intfw;		/* internal firmware, intfw_size bytes long */
-	enum board_type board_type;	/* board type */
-	struct mib_fw_version fw_version;
-	int loaded;		/* Loaded and parsed successfully */
-};
-
-struct at76_priv {
-	struct usb_device *udev;	/* USB device pointer */
-	struct net_device *netdev;	/* net device pointer */
-	struct net_device_stats stats;	/* net device stats */
-	struct iw_statistics wstats;	/* wireless stats */
-
-	struct sk_buff *rx_skb;	/* skbuff for receiving data */
-	void *bulk_out_buffer;	/* buffer for sending data */
-
-	struct urb *tx_urb;	/* URB for sending data */
-	struct urb *rx_urb;	/* URB for receiving data */
-
-	unsigned int tx_pipe;	/* bulk out pipe */
-	unsigned int rx_pipe;	/* bulk in pipe */
-
-	struct mutex mtx;	/* locks this structure */
-
-	/* work queues */
-	struct work_struct work_assoc_done;
-	struct work_struct work_join;
-	struct work_struct work_new_bss;
-	struct work_struct work_start_scan;
-	struct work_struct work_set_promisc;
-	struct work_struct work_submit_rx;
-	struct delayed_work dwork_restart;
-	struct delayed_work dwork_get_scan;
-	struct delayed_work dwork_beacon;
-	struct delayed_work dwork_auth;
-	struct delayed_work dwork_assoc;
-
-	struct tasklet_struct rx_tasklet;
-
-	/* the WEP stuff */
-	int wep_enabled;	/* 1 if WEP is enabled */
-	int wep_key_id;		/* key id to be used */
-	u8 wep_keys[WEP_KEYS][WEP_KEY_LEN];	/* the four WEP keys,
-						   5 or 13 bytes are used */
-	u8 wep_keys_len[WEP_KEYS];	/* the length of the above keys */
-
-	int channel;
-	int iw_mode;
-	u8 bssid[ETH_ALEN];
-	u8 essid[IW_ESSID_MAX_SIZE];
-	int essid_size;
-	int radio_on;
-	int promisc;
-
-	int preamble_type;	/* 0 - long, 1 - short, 2 - auto */
-	int auth_mode;		/* authentication type: 0 open, 1 shared key */
-	int txrate;		/* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
-	int frag_threshold;	/* threshold for fragmentation of tx packets */
-	int rts_threshold;	/* threshold for RTS mechanism */
-	int short_retry_limit;
-
-	int scan_min_time;	/* scan min channel time */
-	int scan_max_time;	/* scan max channel time */
-	int scan_mode;		/* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
-	int scan_need_any;	/* if set, need to scan for any ESSID */
-
-	/* the list we got from scanning */
-	spinlock_t bss_list_spinlock;	/* protects bss_list operations */
-	struct list_head bss_list;	/* list of BSS we got beacons from */
-	struct timer_list bss_list_timer;	/* timer to purge old entries
-						   from bss_list */
-	struct bss_info *curr_bss;	/* current BSS */
-	u16 assoc_id;		/* current association ID, if associated */
-
-	u8 wanted_bssid[ETH_ALEN];
-	int wanted_bssid_valid;	/* != 0 if wanted_bssid is to be used */
-
-	/* some data for infrastructure mode only */
-	spinlock_t mgmt_spinlock;	/* this spinlock protects access to
-					   next_mgmt_bulk */
-
-	struct at76_tx_buffer *next_mgmt_bulk;	/* pending management msg to
-						   send via bulk out */
-	enum mac_state mac_state;
-	enum {
-		SCAN_IDLE,
-		SCAN_IN_PROGRESS,
-		SCAN_COMPLETED
-	} scan_state;
-	time_t last_scan;
-
-	int retries;		/* remaining retries in case of timeout when
-				 * sending AuthReq or AssocReq */
-	u8 pm_mode;		/* power management mode */
-	u32 pm_period;		/* power management period in microseconds */
-
-	struct reg_domain const *domain;	/* reg domain description */
-
-	/* iwspy support */
-	spinlock_t spy_spinlock;
-	struct iw_spy_data spy_data;
-
-	struct iw_public_data wireless_data;
-
-	/* These fields contain HW config provided by the device (not all of
-	 * these fields are used by all board types) */
-	u8 mac_addr[ETH_ALEN];
-	u8 regulatory_domain;
-
-	struct at76_card_config card_config;
-
-	/* store rx fragments until complete */
-	struct rx_data_buf rx_data[NR_RX_DATA_BUF];
-
-	enum board_type board_type;
-	struct mib_fw_version fw_version;
-
-	unsigned int device_unplugged:1;
-	unsigned int netdev_registered:1;
-	struct set_mib_buffer mib_buf;	/* global buffer for set_mib calls */
-
-	/* beacon counting */
-	int beacon_period;	/* period of mgmt beacons, Kus */
-	int beacons_received;
-	unsigned long beacons_last_qual;	/* time we restarted counting
-						   beacons */
-};
-
-struct at76_rx_radiotap {
-	struct ieee80211_radiotap_header rt_hdr;
-	__le64 rt_tsft;
-	u8 rt_flags;
-	u8 rt_rate;
-	s8 rt_signal;
-	s8 rt_noise;
-};
-
-#define AT76_RX_RADIOTAP_PRESENT		  \
-	((1 << IEEE80211_RADIOTAP_TSFT)		| \
-	(1 << IEEE80211_RADIOTAP_FLAGS)		| \
-	(1 << IEEE80211_RADIOTAP_RATE)		| \
-	(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)	| \
-	(1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
-
-#define BEACON_MAX_DATA_LENGTH	1500
-
-/* the maximum size of an AssocReq packet */
-#define ASSOCREQ_MAX_SIZE \
-  (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \
-   1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4)
-
-/* for shared secret auth, add the challenge text size */
-#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth))
-
-/* Maximal number of AuthReq retries */
-#define AUTH_RETRIES		3
-
-/* Maximal number of AssocReq retries */
-#define ASSOC_RETRIES		3
-
-/* Beacon timeout in managed mode when we are connected */
-#define BEACON_TIMEOUT		(10 * HZ)
-
-/* Timeout for authentication response */
-#define AUTH_TIMEOUT		(1 * HZ)
-
-/* Timeout for association response */
-#define ASSOC_TIMEOUT		(1 * HZ)
-
-/* Polling interval when scan is running */
-#define SCAN_POLL_INTERVAL	(HZ / 4)
-
-/* Command completion timeout */
-#define CMD_COMPLETION_TIMEOUT	(5 * HZ)
-
-#define DEF_RTS_THRESHOLD	1536
-#define DEF_FRAG_THRESHOLD	1536
-#define DEF_SHORT_RETRY_LIMIT	8
-#define DEF_CHANNEL		10
-#define DEF_SCAN_MIN_TIME	10
-#define DEF_SCAN_MAX_TIME	120
-
-#define MAX_RTS_THRESHOLD	(MAX_FRAG_THRESHOLD + 1)
-
-/* the max padding size for tx in bytes (see calc_padding) */
-#define MAX_PADDING_SIZE	53
-
-#endif				/* _AT76_USB_H */
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
index eec9c99..94c5d27 100644
--- a/drivers/staging/b3dfg/b3dfg.c
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -632,18 +632,15 @@ static void transfer_complete(struct b3dfg_dev *fgdev)
 	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");
+
+	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);
 	}
 }
 
@@ -663,19 +660,15 @@ static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
 	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 */
-		}
+	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, "cannot setup DMA, no buffer\n");
+		dev_err(dev, "frame mismatch, got %d, expected %d\n",
+			idx, fgdev->cur_dma_frame_idx + 2);
+
+		/* FIXME: handle dropped triplets here */
 	}
 
 	return need_ack;
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 8101cea..957b640 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -121,10 +121,10 @@ extern "C" {
 #define TRIG_BOGUS	0x0001	/* do the motions */
 #define TRIG_DITHER	0x0002	/* enable dithering */
 #define TRIG_DEGLITCH	0x0004	/* enable deglitching */
-/*#define TRIG_RT       0x0008 */	/* perform op in real time */
+	/*#define TRIG_RT       0x0008 *//* perform op in real time */
 #define TRIG_CONFIG	0x0010	/* perform configuration, not triggering */
 #define TRIG_WAKE_EOS	0x0020	/* wake up on end-of-scan events */
-/*#define TRIG_WRITE    0x0040*/	/* write to bidirectional devices */
+	/*#define TRIG_WRITE    0x0040*//* write to bidirectional devices */
 
 /* command flags */
 /* These flags are used in comedi_cmd structures */
@@ -199,93 +199,91 @@ extern "C" {
 #define SDF_LSAMPL	0x10000000	/* subdevice uses 32-bit samples */
 #define SDF_PACKED	0x20000000	/* subdevice can do packed DIO */
 /* re recyle these flags for PWM */
-#define SDF_PWM_COUNTER SDF_MODE0       /* PWM can automatically switch off */
-#define SDF_PWM_HBRIDGE SDF_MODE1       /* PWM is signed (H-bridge) */
-
-
+#define SDF_PWM_COUNTER SDF_MODE0	/* PWM can automatically switch off */
+#define SDF_PWM_HBRIDGE SDF_MODE1	/* PWM is signed (H-bridge) */
 
 /* subdevice types */
 
-enum comedi_subdevice_type {
-	COMEDI_SUBD_UNUSED,	/* unused by driver */
-	COMEDI_SUBD_AI,	/* analog input */
-	COMEDI_SUBD_AO,	/* analog output */
-	COMEDI_SUBD_DI,	/* digital input */
-	COMEDI_SUBD_DO,	/* digital output */
-	COMEDI_SUBD_DIO,	/* digital input/output */
-	COMEDI_SUBD_COUNTER,	/* counter */
-	COMEDI_SUBD_TIMER,	/* timer */
-	COMEDI_SUBD_MEMORY,	/* memory, EEPROM, DPRAM */
-	COMEDI_SUBD_CALIB,	/* calibration DACs */
-	COMEDI_SUBD_PROC,	/* processor, DSP */
-	COMEDI_SUBD_SERIAL,	/* serial IO */
-	COMEDI_SUBD_PWM         /* PWM */
-};
+	enum comedi_subdevice_type {
+		COMEDI_SUBD_UNUSED,	/* unused by driver */
+		COMEDI_SUBD_AI,	/* analog input */
+		COMEDI_SUBD_AO,	/* analog output */
+		COMEDI_SUBD_DI,	/* digital input */
+		COMEDI_SUBD_DO,	/* digital output */
+		COMEDI_SUBD_DIO,	/* digital input/output */
+		COMEDI_SUBD_COUNTER,	/* counter */
+		COMEDI_SUBD_TIMER,	/* timer */
+		COMEDI_SUBD_MEMORY,	/* memory, EEPROM, DPRAM */
+		COMEDI_SUBD_CALIB,	/* calibration DACs */
+		COMEDI_SUBD_PROC,	/* processor, DSP */
+		COMEDI_SUBD_SERIAL,	/* serial IO */
+		COMEDI_SUBD_PWM	/* PWM */
+	};
 
 /* configuration instructions */
 
-enum configuration_ids {
-	INSN_CONFIG_DIO_INPUT = 0,
-	INSN_CONFIG_DIO_OUTPUT = 1,
-	INSN_CONFIG_DIO_OPENDRAIN = 2,
-	INSN_CONFIG_ANALOG_TRIG = 16,
+	enum configuration_ids {
+		INSN_CONFIG_DIO_INPUT = 0,
+		INSN_CONFIG_DIO_OUTPUT = 1,
+		INSN_CONFIG_DIO_OPENDRAIN = 2,
+		INSN_CONFIG_ANALOG_TRIG = 16,
 /*	INSN_CONFIG_WAVEFORM = 17, */
 /*	INSN_CONFIG_TRIG = 18, */
 /*	INSN_CONFIG_COUNTER = 19, */
-	INSN_CONFIG_ALT_SOURCE = 20,
-	INSN_CONFIG_DIGITAL_TRIG = 21,
-	INSN_CONFIG_BLOCK_SIZE = 22,
-	INSN_CONFIG_TIMER_1 = 23,
-	INSN_CONFIG_FILTER = 24,
-	INSN_CONFIG_CHANGE_NOTIFY = 25,
-
-	 /*ALPHA*/ INSN_CONFIG_SERIAL_CLOCK = 26,
-	INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
-	INSN_CONFIG_DIO_QUERY = 28,
-	INSN_CONFIG_PWM_OUTPUT = 29,
-	INSN_CONFIG_GET_PWM_OUTPUT = 30,
-	INSN_CONFIG_ARM = 31,
-	INSN_CONFIG_DISARM = 32,
-	INSN_CONFIG_GET_COUNTER_STATUS = 33,
-	INSN_CONFIG_RESET = 34,
-	INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,	/* Use CTR as single pulsegenerator */
-	INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,	/* Use CTR as pulsetraingenerator */
-	INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,	/* Use the counter as encoder */
-	INSN_CONFIG_SET_GATE_SRC = 2001,	/* Set gate source */
-	INSN_CONFIG_GET_GATE_SRC = 2002,	/* Get gate source */
-	INSN_CONFIG_SET_CLOCK_SRC = 2003,	/* Set master clock source */
-	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 = 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,
-	INSN_CONFIG_SET_ROUTING = 4099,
-	INSN_CONFIG_GET_ROUTING = 4109,
+		INSN_CONFIG_ALT_SOURCE = 20,
+		INSN_CONFIG_DIGITAL_TRIG = 21,
+		INSN_CONFIG_BLOCK_SIZE = 22,
+		INSN_CONFIG_TIMER_1 = 23,
+		INSN_CONFIG_FILTER = 24,
+		INSN_CONFIG_CHANGE_NOTIFY = 25,
+
+		 /*ALPHA*/ INSN_CONFIG_SERIAL_CLOCK = 26,
+		INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
+		INSN_CONFIG_DIO_QUERY = 28,
+		INSN_CONFIG_PWM_OUTPUT = 29,
+		INSN_CONFIG_GET_PWM_OUTPUT = 30,
+		INSN_CONFIG_ARM = 31,
+		INSN_CONFIG_DISARM = 32,
+		INSN_CONFIG_GET_COUNTER_STATUS = 33,
+		INSN_CONFIG_RESET = 34,
+		INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,	/* Use CTR as single pulsegenerator */
+		INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,	/* Use CTR as pulsetraingenerator */
+		INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,	/* Use the counter as encoder */
+		INSN_CONFIG_SET_GATE_SRC = 2001,	/* Set gate source */
+		INSN_CONFIG_GET_GATE_SRC = 2002,	/* Get gate source */
+		INSN_CONFIG_SET_CLOCK_SRC = 2003,	/* Set master clock source */
+		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 = 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,
+		INSN_CONFIG_SET_ROUTING = 4099,
+		INSN_CONFIG_GET_ROUTING = 4109,
 /* PWM */
-	INSN_CONFIG_PWM_SET_PERIOD = 5000,   /* sets frequency */
-	INSN_CONFIG_PWM_GET_PERIOD = 5001,   /* gets frequency */
-	INSN_CONFIG_GET_PWM_STATUS = 5002,          /* is it running? */
-	INSN_CONFIG_PWM_SET_H_BRIDGE = 5003, /* sets H bridge: duty cycle and sign bit for a relay  at the same time*/
-	INSN_CONFIG_PWM_GET_H_BRIDGE = 5004  /* gets H bridge data: duty cycle and the sign bit */
-};
-
-enum comedi_io_direction {
-	COMEDI_INPUT = 0,
-	COMEDI_OUTPUT = 1,
-	COMEDI_OPENDRAIN = 2
-};
-
-enum comedi_support_level {
-	COMEDI_UNKNOWN_SUPPORT = 0,
-	COMEDI_SUPPORTED,
-	COMEDI_UNSUPPORTED
-};
+		INSN_CONFIG_PWM_SET_PERIOD = 5000,	/* sets frequency */
+		INSN_CONFIG_PWM_GET_PERIOD = 5001,	/* gets frequency */
+		INSN_CONFIG_GET_PWM_STATUS = 5002,	/* is it running? */
+		INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,	/* sets H bridge: duty cycle and sign bit for a relay  at the same time */
+		INSN_CONFIG_PWM_GET_H_BRIDGE = 5004	/* gets H bridge data: duty cycle and the sign bit */
+	};
+
+	enum comedi_io_direction {
+		COMEDI_INPUT = 0,
+		COMEDI_OUTPUT = 1,
+		COMEDI_OPENDRAIN = 2
+	};
+
+	enum comedi_support_level {
+		COMEDI_UNKNOWN_SUPPORT = 0,
+		COMEDI_SUPPORTED,
+		COMEDI_UNSUPPORTED
+	};
 
 /* ioctls */
 
@@ -309,133 +307,132 @@ enum comedi_support_level {
 
 /* structures */
 
-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 */
-	short *data;	/* data list, size depends on subd flags */
-	unsigned int n;	/* number of scans */
-	unsigned int trigsrc;
-	unsigned int trigvar;
-	unsigned int trigvar1;
-	unsigned int data_len;
-	unsigned int unused[3];
-};
-
-struct comedi_insn {
-	unsigned int insn;
-	unsigned int n;
-	unsigned int *data;
-	unsigned int subdev;
-	unsigned int chanspec;
-	unsigned int unused[3];
-};
-
-struct comedi_insnlist {
-	unsigned int n_insns;
-	struct comedi_insn *insns;
-};
-
-struct comedi_cmd {
-	unsigned int subdev;
-	unsigned int flags;
-
-	unsigned int start_src;
-	unsigned int start_arg;
-
-	unsigned int scan_begin_src;
-	unsigned int scan_begin_arg;
-
-	unsigned int convert_src;
-	unsigned int convert_arg;
-
-	unsigned int scan_end_src;
-	unsigned int scan_end_arg;
-
-	unsigned int stop_src;
-	unsigned int stop_arg;
-
-	unsigned int *chanlist;	/* channel/range list */
-	unsigned int chanlist_len;
-
-	short *data;	/* data list, size depends on subd flags */
-	unsigned int data_len;
-};
-
-struct comedi_chaninfo {
-	unsigned int subdev;
-	unsigned int *maxdata_list;
-	unsigned int *flaglist;
-	unsigned int *rangelist;
-	unsigned int unused[4];
-};
-
-struct comedi_rangeinfo {
-	unsigned int range_type;
-	void *range_ptr;
-};
-
-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 {
-	unsigned int type;
-	unsigned int n_chan;
-	unsigned int subd_flags;
-	unsigned int timer_type;
-	unsigned int len_chanlist;
-	unsigned int maxdata;
-	unsigned int flags;	/* channel flags */
-	unsigned int range_type;	/* lookup in kernel */
-	unsigned int settling_time_0;
-	unsigned insn_bits_support;	/* see support_level enum for values*/
-	unsigned int unused[8];
-};
-
-struct comedi_devinfo {
-	unsigned int version_code;
-	unsigned int n_subdevs;
-	char driver_name[COMEDI_NAMELEN];
-	char board_name[COMEDI_NAMELEN];
-	int read_subdevice;
-	int write_subdevice;
-	int unused[30];
-};
-
-struct comedi_devconfig {
-	char board_name[COMEDI_NAMELEN];
-	int options[COMEDI_NDEVCONFOPTS];
-};
-
-struct comedi_bufconfig {
-	unsigned int subdevice;
-	unsigned int flags;
-
-	unsigned int maximum_size;
-	unsigned int size;
-
-	unsigned int unused[4];
-};
-
-struct comedi_bufinfo {
-	unsigned int subdevice;
-	unsigned int bytes_read;
-
-	unsigned int buf_write_ptr;
-	unsigned int buf_read_ptr;
-	unsigned int buf_write_count;
-	unsigned int buf_read_count;
-
-	unsigned int bytes_written;
-
-	unsigned int unused[4];
-};
+	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 */
+		short *data;	/* data list, size depends on subd flags */
+		unsigned int n;	/* number of scans */
+		unsigned int trigsrc;
+		unsigned int trigvar;
+		unsigned int trigvar1;
+		unsigned int data_len;
+		unsigned int unused[3];
+	};
+
+	struct comedi_insn {
+		unsigned int insn;
+		unsigned int n;
+		unsigned int *data;
+		unsigned int subdev;
+		unsigned int chanspec;
+		unsigned int unused[3];
+	};
+
+	struct comedi_insnlist {
+		unsigned int n_insns;
+		struct comedi_insn *insns;
+	};
+
+	struct comedi_cmd {
+		unsigned int subdev;
+		unsigned int flags;
+
+		unsigned int start_src;
+		unsigned int start_arg;
+
+		unsigned int scan_begin_src;
+		unsigned int scan_begin_arg;
+
+		unsigned int convert_src;
+		unsigned int convert_arg;
+
+		unsigned int scan_end_src;
+		unsigned int scan_end_arg;
+
+		unsigned int stop_src;
+		unsigned int stop_arg;
+
+		unsigned int *chanlist;	/* channel/range list */
+		unsigned int chanlist_len;
+
+		short *data;	/* data list, size depends on subd flags */
+		unsigned int data_len;
+	};
+
+	struct comedi_chaninfo {
+		unsigned int subdev;
+		unsigned int *maxdata_list;
+		unsigned int *flaglist;
+		unsigned int *rangelist;
+		unsigned int unused[4];
+	};
+
+	struct comedi_rangeinfo {
+		unsigned int range_type;
+		void *range_ptr;
+	};
+
+	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 {
+		unsigned int type;
+		unsigned int n_chan;
+		unsigned int subd_flags;
+		unsigned int timer_type;
+		unsigned int len_chanlist;
+		unsigned int maxdata;
+		unsigned int flags;	/* channel flags */
+		unsigned int range_type;	/* lookup in kernel */
+		unsigned int settling_time_0;
+		unsigned insn_bits_support;	/* see support_level enum for values */
+		unsigned int unused[8];
+	};
+
+	struct comedi_devinfo {
+		unsigned int version_code;
+		unsigned int n_subdevs;
+		char driver_name[COMEDI_NAMELEN];
+		char board_name[COMEDI_NAMELEN];
+		int read_subdevice;
+		int write_subdevice;
+		int unused[30];
+	};
+
+	struct comedi_devconfig {
+		char board_name[COMEDI_NAMELEN];
+		int options[COMEDI_NDEVCONFOPTS];
+	};
+
+	struct comedi_bufconfig {
+		unsigned int subdevice;
+		unsigned int flags;
+
+		unsigned int maximum_size;
+		unsigned int size;
+
+		unsigned int unused[4];
+	};
+
+	struct comedi_bufinfo {
+		unsigned int subdevice;
+		unsigned int bytes_read;
+
+		unsigned int buf_write_ptr;
+		unsigned int buf_read_ptr;
+		unsigned int buf_write_count;
+		unsigned int buf_read_count;
+
+		unsigned int bytes_written;
+
+		unsigned int unused[4];
+	};
 
 /* range stuff */
 
@@ -486,298 +483,284 @@ struct comedi_bufinfo {
 
 */
 
-enum i8254_mode {
-	I8254_MODE0 = (0 << 1),	/* Interrupt on terminal count */
-	I8254_MODE1 = (1 << 1),	/* Hardware retriggerable one-shot */
-	I8254_MODE2 = (2 << 1),	/* Rate generator */
-	I8254_MODE3 = (3 << 1),	/* Square wave mode */
-	I8254_MODE4 = (4 << 1),	/* Software triggered strobe */
-	I8254_MODE5 = (5 << 1),	/* Hardware triggered strobe (retriggerable) */
-	I8254_BCD = 1,	/* use binary-coded decimal instead of binary (pretty useless) */
-	I8254_BINARY = 0
-};
-
-static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel)
-{
-	if (pfi_channel < 10)
-		return 0x1 + pfi_channel;
-	else
-		return 0xb + pfi_channel;
-}
-static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel)
-{
-	if (rtsi_channel < 7)
-		return 0xb + rtsi_channel;
-	else
-		return 0x1b;
-}
+	enum i8254_mode {
+		I8254_MODE0 = (0 << 1),	/* Interrupt on terminal count */
+		I8254_MODE1 = (1 << 1),	/* Hardware retriggerable one-shot */
+		I8254_MODE2 = (2 << 1),	/* Rate generator */
+		I8254_MODE3 = (3 << 1),	/* Square wave mode */
+		I8254_MODE4 = (4 << 1),	/* Software triggered strobe */
+		I8254_MODE5 = (5 << 1),	/* Hardware triggered strobe (retriggerable) */
+		I8254_BCD = 1,	/* use binary-coded decimal instead of binary (pretty useless) */
+		I8254_BINARY = 0
+	};
+
+	static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel) {
+		if (pfi_channel < 10)
+			return 0x1 + pfi_channel;
+		else
+			return 0xb + pfi_channel;
+	} static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel) {
+		if (rtsi_channel < 7)
+			return 0xb + rtsi_channel;
+		else
+			return 0x1b;
+	}
 /* mode bits for NI general-purpose counters, set with
  * INSN_CONFIG_SET_COUNTER_MODE */
 #define NI_GPCT_COUNTING_MODE_SHIFT 16
 #define NI_GPCT_INDEX_PHASE_BITSHIFT 20
 #define NI_GPCT_COUNTING_DIRECTION_SHIFT 24
-enum ni_gpct_mode_bits {
-	NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
-	NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
-	NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
-	NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
-	NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
-	NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
-	NI_GPCT_STOP_MODE_MASK = 0x60,
-	NI_GPCT_STOP_ON_GATE_BITS = 0x00,
-	NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
-	NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
-	NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
-	NI_GPCT_OUTPUT_MODE_MASK = 0x300,
-	NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
-	NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
-	NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
-	NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
-	NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
-	NI_GPCT_DISARM_AT_TC_BITS = 0x400,
-	NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
-	NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
-	NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
-	NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
-	NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
-	NI_GPCT_COUNTING_MODE_NORMAL_BITS =
-		0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
-	NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =
-		0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
-	NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =
-		0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
-	NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =
-		0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
-	NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =
-		0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
-	NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =
-		0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
-	NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-	NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =
-		0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-	NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =
-		0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-	NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =
-		0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-	NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =
-		0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-	NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
-	NI_GPCT_COUNTING_DIRECTION_MASK =
-		0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-	NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =
-		0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-	NI_GPCT_COUNTING_DIRECTION_UP_BITS =
-		0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-	NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =
-		0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-	NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =
-		0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-	NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
-	NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
-	NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
-	NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
-	NI_GPCT_OR_GATE_BIT = 0x10000000,
-	NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
-};
+	enum ni_gpct_mode_bits {
+		NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
+		NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
+		NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
+		NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
+		NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
+		NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
+		NI_GPCT_STOP_MODE_MASK = 0x60,
+		NI_GPCT_STOP_ON_GATE_BITS = 0x00,
+		NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
+		NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
+		NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
+		NI_GPCT_OUTPUT_MODE_MASK = 0x300,
+		NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
+		NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
+		NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
+		NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
+		NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
+		NI_GPCT_DISARM_AT_TC_BITS = 0x400,
+		NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
+		NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
+		NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
+		NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
+		NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
+		NI_GPCT_COUNTING_MODE_NORMAL_BITS =
+		    0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
+		NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =
+		    0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
+		NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =
+		    0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
+		NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =
+		    0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
+		NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =
+		    0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
+		NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =
+		    0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
+		NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+		NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =
+		    0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+		NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =
+		    0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+		NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =
+		    0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+		NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =
+		    0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+		NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
+		NI_GPCT_COUNTING_DIRECTION_MASK =
+		    0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+		NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =
+		    0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+		NI_GPCT_COUNTING_DIRECTION_UP_BITS =
+		    0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+		NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =
+		    0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+		NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =
+		    0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+		NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
+		NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
+		NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
+		NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
+		NI_GPCT_OR_GATE_BIT = 0x10000000,
+		NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
+	};
 
 /* Bits for setting a clock source with
  * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */
-enum ni_gpct_clock_source_bits {
-	NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
-	NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
-	NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
-	NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
-	NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
-	NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
-	NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
-	NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,	/* NI 660x-specific */
-	NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
-	NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
-	NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
-	NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
-	NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
-	NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000, /* divide source by 2 */
-	NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000, /* divide source by 8 */
-	NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
-};
-static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n)
-{
-	/* NI 660x-specific */
-	return 0x10 + n;
-}
-static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n)
-{
-	return 0x18 + n;
-}
-static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n)
-{
-	/* no pfi on NI 660x */
-	return 0x20 + n;
-}
+	enum ni_gpct_clock_source_bits {
+		NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
+		NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
+		NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
+		NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
+		NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
+		NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
+		NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
+		NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,	/* NI 660x-specific */
+		NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
+		NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
+		NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
+		NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
+		NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
+		NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000,	/* divide source by 2 */
+		NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,	/* divide source by 8 */
+		NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
+	};
+	static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n) {
+		/* NI 660x-specific */
+		return 0x10 + n;
+	}
+	static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n) {
+		return 0x18 + n;
+	}
+	static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n) {
+		/* no pfi on NI 660x */
+		return 0x20 + n;
+	}
 
 /* Possibilities for setting a gate source with
 INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
 May be bitwise-or'd with CR_EDGE or CR_INVERT. */
-enum ni_gpct_gate_select {
-	/* m-series gates */
-	NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
-	NI_GPCT_AI_START2_GATE_SELECT = 0x12,
-	NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
-	NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
-	NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
-	NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
-	NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
-	NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
-	/* more gates for 660x */
-	NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
-	NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
-	/* more gates for 660x "second gate" */
-	NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
-	NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
-	/* m-series "second gate" sources are unknown,
-	   we should add them here with an offset of 0x300 when known. */
-	NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
-};
-static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n)
-{
-	return 0x102 + n;
-}
-static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n)
-{
-	return NI_USUAL_RTSI_SELECT(n);
-}
-static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n)
-{
-	return NI_USUAL_PFI_SELECT(n);
-}
-static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)
-{
-	return 0x202 + n;
-}
+	enum ni_gpct_gate_select {
+		/* m-series gates */
+		NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
+		NI_GPCT_AI_START2_GATE_SELECT = 0x12,
+		NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
+		NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
+		NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
+		NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
+		NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
+		NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
+		/* more gates for 660x */
+		NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
+		NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
+		/* more gates for 660x "second gate" */
+		NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
+		NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
+		/* m-series "second gate" sources are unknown,
+		   we should add them here with an offset of 0x300 when known. */
+		NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
+	};
+	static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n) {
+		return 0x102 + n;
+	}
+	static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n) {
+		return NI_USUAL_RTSI_SELECT(n);
+	}
+	static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n) {
+		return NI_USUAL_PFI_SELECT(n);
+	}
+	static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n) {
+		return 0x202 + n;
+	}
 
 /* Possibilities for setting a source with
 INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */
-enum ni_gpct_other_index {
-	NI_GPCT_SOURCE_ENCODER_A,
-	NI_GPCT_SOURCE_ENCODER_B,
-	NI_GPCT_SOURCE_ENCODER_Z
-};
-enum ni_gpct_other_select {
-	/* m-series gates */
-	/* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
-	NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
-};
-static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)
-{
-	return NI_USUAL_PFI_SELECT(n);
-}
+	enum ni_gpct_other_index {
+		NI_GPCT_SOURCE_ENCODER_A,
+		NI_GPCT_SOURCE_ENCODER_B,
+		NI_GPCT_SOURCE_ENCODER_Z
+	};
+	enum ni_gpct_other_select {
+		/* m-series gates */
+		/* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
+		NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
+	};
+	static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n) {
+		return NI_USUAL_PFI_SELECT(n);
+	}
 
 /* start sources for ni general-purpose counters for use with
 INSN_CONFIG_ARM */
-enum ni_gpct_arm_source {
-	NI_GPCT_ARM_IMMEDIATE = 0x0,
-	NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1,	/* Start both the counter and
-						   the adjacent paired counter
-						   simultaneously */
-	/* NI doesn't document bits for selecting hardware arm triggers.  If
-	 * the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least
-	 * significant bits (3 bits for 660x or 5 bits for m-series) through to
-	 * the hardware.  This will at least allow someone to figure out what
-	 * the bits do later. */
-	NI_GPCT_ARM_UNKNOWN = 0x1000,
-};
+	enum ni_gpct_arm_source {
+		NI_GPCT_ARM_IMMEDIATE = 0x0,
+		NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1,	/* Start both the counter and
+							   the adjacent paired counter
+							   simultaneously */
+		/* NI doesn't document bits for selecting hardware arm triggers.  If
+		 * the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least
+		 * significant bits (3 bits for 660x or 5 bits for m-series) through to
+		 * the hardware.  This will at least allow someone to figure out what
+		 * the bits do later. */
+		NI_GPCT_ARM_UNKNOWN = 0x1000,
+	};
 
 /* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */
-enum ni_gpct_filter_select {
-	NI_GPCT_FILTER_OFF = 0x0,
-	NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
-	NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
-	NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
-	NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
-	NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
-	NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
-};
+	enum ni_gpct_filter_select {
+		NI_GPCT_FILTER_OFF = 0x0,
+		NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
+		NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
+		NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
+		NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
+		NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
+		NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
+	};
 
 /* PFI digital filtering options for ni m-series for use with
  * INSN_CONFIG_FILTER. */
-enum ni_pfi_filter_select {
-	NI_PFI_FILTER_OFF = 0x0,
-	NI_PFI_FILTER_125ns = 0x1,
-	NI_PFI_FILTER_6425ns = 0x2,
-	NI_PFI_FILTER_2550us = 0x3
-};
+	enum ni_pfi_filter_select {
+		NI_PFI_FILTER_OFF = 0x0,
+		NI_PFI_FILTER_125ns = 0x1,
+		NI_PFI_FILTER_6425ns = 0x2,
+		NI_PFI_FILTER_2550us = 0x3
+	};
 
 /* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */
-enum ni_mio_clock_source {
-	NI_MIO_INTERNAL_CLOCK = 0,
-	NI_MIO_RTSI_CLOCK = 1,	/* doesn't work for m-series, use
-				   NI_MIO_PLL_RTSI_CLOCK() */
-	/* the NI_MIO_PLL_* sources are m-series only */
-	NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
-	NI_MIO_PLL_PXI10_CLOCK = 3,
-	NI_MIO_PLL_RTSI0_CLOCK = 4
-};
-static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel)
-{
-	return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;
-}
+	enum ni_mio_clock_source {
+		NI_MIO_INTERNAL_CLOCK = 0,
+		NI_MIO_RTSI_CLOCK = 1,	/* doesn't work for m-series, use
+					   NI_MIO_PLL_RTSI_CLOCK() */
+		/* the NI_MIO_PLL_* sources are m-series only */
+		NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
+		NI_MIO_PLL_PXI10_CLOCK = 3,
+		NI_MIO_PLL_RTSI0_CLOCK = 4
+	};
+	static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel) {
+		return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;
+	}
 
 /* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
  The numbers assigned are not arbitrary, they correspond to the bits required
  to program the board. */
-enum ni_rtsi_routing {
-	NI_RTSI_OUTPUT_ADR_START1 = 0,
-	NI_RTSI_OUTPUT_ADR_START2 = 1,
-	NI_RTSI_OUTPUT_SCLKG = 2,
-	NI_RTSI_OUTPUT_DACUPDN = 3,
-	NI_RTSI_OUTPUT_DA_START1 = 4,
-	NI_RTSI_OUTPUT_G_SRC0 = 5,
-	NI_RTSI_OUTPUT_G_GATE0 = 6,
-	NI_RTSI_OUTPUT_RGOUT0 = 7,
-	NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
-	NI_RTSI_OUTPUT_RTSI_OSC = 12	/* pre-m-series always have RTSI clock
-					   on line 7 */
-};
-static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)
-{
-	return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;
-}
+	enum ni_rtsi_routing {
+		NI_RTSI_OUTPUT_ADR_START1 = 0,
+		NI_RTSI_OUTPUT_ADR_START2 = 1,
+		NI_RTSI_OUTPUT_SCLKG = 2,
+		NI_RTSI_OUTPUT_DACUPDN = 3,
+		NI_RTSI_OUTPUT_DA_START1 = 4,
+		NI_RTSI_OUTPUT_G_SRC0 = 5,
+		NI_RTSI_OUTPUT_G_GATE0 = 6,
+		NI_RTSI_OUTPUT_RGOUT0 = 7,
+		NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
+		NI_RTSI_OUTPUT_RTSI_OSC = 12	/* pre-m-series always have RTSI clock
+						   on line 7 */
+	};
+	static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n) {
+		return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;
+	}
 
 /* Signals which can be routed to an NI PFI pin on an m-series board with
  * INSN_CONFIG_SET_ROUTING.  These numbers are also returned by
  * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing
  * cannot be changed.  The numbers assigned are not arbitrary, they correspond
  * to the bits required to program the board. */
-enum ni_pfi_routing {
-	NI_PFI_OUTPUT_PFI_DEFAULT = 0,
-	NI_PFI_OUTPUT_AI_START1 = 1,
-	NI_PFI_OUTPUT_AI_START2 = 2,
-	NI_PFI_OUTPUT_AI_CONVERT = 3,
-	NI_PFI_OUTPUT_G_SRC1 = 4,
-	NI_PFI_OUTPUT_G_GATE1 = 5,
-	NI_PFI_OUTPUT_AO_UPDATE_N = 6,
-	NI_PFI_OUTPUT_AO_START1 = 7,
-	NI_PFI_OUTPUT_AI_START_PULSE = 8,
-	NI_PFI_OUTPUT_G_SRC0 = 9,
-	NI_PFI_OUTPUT_G_GATE0 = 10,
-	NI_PFI_OUTPUT_EXT_STROBE = 11,
-	NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
-	NI_PFI_OUTPUT_GOUT0 = 13,
-	NI_PFI_OUTPUT_GOUT1 = 14,
-	NI_PFI_OUTPUT_FREQ_OUT = 15,
-	NI_PFI_OUTPUT_PFI_DO = 16,
-	NI_PFI_OUTPUT_I_ATRIG = 17,
-	NI_PFI_OUTPUT_RTSI0 = 18,
-	NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
-	NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
-	NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
-	NI_PFI_OUTPUT_CDI_SAMPLE = 29,
-	NI_PFI_OUTPUT_CDO_UPDATE = 30
-};
-static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)
-{
-	return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;
-}
+	enum ni_pfi_routing {
+		NI_PFI_OUTPUT_PFI_DEFAULT = 0,
+		NI_PFI_OUTPUT_AI_START1 = 1,
+		NI_PFI_OUTPUT_AI_START2 = 2,
+		NI_PFI_OUTPUT_AI_CONVERT = 3,
+		NI_PFI_OUTPUT_G_SRC1 = 4,
+		NI_PFI_OUTPUT_G_GATE1 = 5,
+		NI_PFI_OUTPUT_AO_UPDATE_N = 6,
+		NI_PFI_OUTPUT_AO_START1 = 7,
+		NI_PFI_OUTPUT_AI_START_PULSE = 8,
+		NI_PFI_OUTPUT_G_SRC0 = 9,
+		NI_PFI_OUTPUT_G_GATE0 = 10,
+		NI_PFI_OUTPUT_EXT_STROBE = 11,
+		NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
+		NI_PFI_OUTPUT_GOUT0 = 13,
+		NI_PFI_OUTPUT_GOUT1 = 14,
+		NI_PFI_OUTPUT_FREQ_OUT = 15,
+		NI_PFI_OUTPUT_PFI_DO = 16,
+		NI_PFI_OUTPUT_I_ATRIG = 17,
+		NI_PFI_OUTPUT_RTSI0 = 18,
+		NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
+		NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
+		NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
+		NI_PFI_OUTPUT_CDI_SAMPLE = 29,
+		NI_PFI_OUTPUT_CDO_UPDATE = 30
+	};
+	static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel) {
+		return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;
+	}
 
 /* Signals which can be routed to output on a NI PFI pin on a 660x board
  with INSN_CONFIG_SET_ROUTING.  The numbers assigned are
@@ -785,72 +768,67 @@ static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)
  to program the board.  Lines 0 to 7 can only be set to
  NI_660X_PFI_OUTPUT_DIO.  Lines 32 to 39 can only be set to
  NI_660X_PFI_OUTPUT_COUNTER. */
-enum ni_660x_pfi_routing {
-	NI_660X_PFI_OUTPUT_COUNTER = 1,	/* counter */
-	NI_660X_PFI_OUTPUT_DIO = 2,	/* static digital output */
-};
+	enum ni_660x_pfi_routing {
+		NI_660X_PFI_OUTPUT_COUNTER = 1,	/* counter */
+		NI_660X_PFI_OUTPUT_DIO = 2,	/* static digital output */
+	};
 
 /* NI External Trigger lines.  These values are not arbitrary, but are related
  * to the bits required to program the board (offset by 1 for historical
  * reasons). */
-static inline unsigned NI_EXT_PFI(unsigned pfi_channel)
-{
-	return NI_USUAL_PFI_SELECT(pfi_channel) - 1;
-}
-static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel)
-{
-	return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;
-}
+	static inline unsigned NI_EXT_PFI(unsigned pfi_channel) {
+		return NI_USUAL_PFI_SELECT(pfi_channel) - 1;
+	}
+	static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel) {
+		return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;
+	}
 
 /* status bits for INSN_CONFIG_GET_COUNTER_STATUS */
-enum comedi_counter_status_flags {
-	COMEDI_COUNTER_ARMED = 0x1,
-	COMEDI_COUNTER_COUNTING = 0x2,
-	COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
-};
+	enum comedi_counter_status_flags {
+		COMEDI_COUNTER_ARMED = 0x1,
+		COMEDI_COUNTER_COUNTING = 0x2,
+		COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
+	};
 
 /* Clock sources for CDIO subdevice on NI m-series boards.  Used as the
  * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd
  * with CR_INVERT to change polarity. */
-enum ni_m_series_cdio_scan_begin_src {
-	NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
-	NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
-	NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
-	NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
-	NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
-	NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
-	NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
-	NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
-	NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
-	NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
-};
-static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
-{
-	return NI_USUAL_PFI_SELECT(pfi_channel);
-}
-static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
-{
-	return NI_USUAL_RTSI_SELECT(rtsi_channel);
-}
+	enum ni_m_series_cdio_scan_begin_src {
+		NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
+		NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
+		NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
+		NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
+		NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
+		NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
+		NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
+		NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
+		NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
+		NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
+	};
+	static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) {
+		return NI_USUAL_PFI_SELECT(pfi_channel);
+	}
+	static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned
+							   rtsi_channel) {
+		return NI_USUAL_RTSI_SELECT(rtsi_channel);
+	}
 
 /* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
  * boards.  These scan begin sources can also be bitwise-or'd with CR_INVERT to
  * change polarity. */
-static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
-{
-	return NI_USUAL_PFI_SELECT(pfi_channel);
-}
-static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
-{
-	return NI_USUAL_RTSI_SELECT(rtsi_channel);
-}
+	static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel) {
+		return NI_USUAL_PFI_SELECT(pfi_channel);
+	}
+	static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel) {
+		return NI_USUAL_RTSI_SELECT(rtsi_channel);
+	}
 
 /* Bits for setting a clock source with
  * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */
-enum ni_freq_out_clock_source_bits {
-	NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC,	/* 10 MHz */
-	NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC	/* 100 KHz */
-};
+	enum ni_freq_out_clock_source_bits {
+		NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC,	/* 10 MHz */
+		NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC	/* 100 KHz */
+	};
 
 /* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
  * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 1b9c2a7..9810e37 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -51,7 +51,7 @@
 struct comedi32_chaninfo_struct {
 	unsigned int subdev;
 	compat_uptr_t maxdata_list;	/* 32-bit 'unsigned int *' */
-	compat_uptr_t flaglist;		/* 32-bit 'unsigned int *' */
+	compat_uptr_t flaglist;	/* 32-bit 'unsigned int *' */
 	compat_uptr_t rangelist;	/* 32-bit 'unsigned int *' */
 	unsigned int unused[4];
 };
@@ -74,16 +74,16 @@ struct comedi32_cmd_struct {
 	unsigned int scan_end_arg;
 	unsigned int stop_src;
 	unsigned int stop_arg;
-	compat_uptr_t chanlist;		/* 32-bit 'unsigned int *' */
+	compat_uptr_t chanlist;	/* 32-bit 'unsigned int *' */
 	unsigned int chanlist_len;
-	compat_uptr_t data;		/* 32-bit 'short *' */
+	compat_uptr_t data;	/* 32-bit 'short *' */
 	unsigned int data_len;
 };
 
 struct comedi32_insn_struct {
 	unsigned int insn;
 	unsigned int n;
-	compat_uptr_t data;		/* 32-bit 'unsigned int *' */
+	compat_uptr_t data;	/* 32-bit 'unsigned int *' */
 	unsigned int subdev;
 	unsigned int chanspec;
 	unsigned int unused[3];
@@ -91,19 +91,19 @@ struct comedi32_insn_struct {
 
 struct comedi32_insnlist_struct {
 	unsigned int n_insns;
-	compat_uptr_t insns;		/* 32-bit 'struct comedi_insn *' */
+	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)
+			    unsigned long arg)
 {
 	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);
+		int rc = (int)(*file->f_op->unlocked_ioctl) (file, cmd, arg);
 		if (rc == -ENOIOCTLCMD)
 			rc = -ENOTTY;
 		return rc;
@@ -112,8 +112,8 @@ static int translated_ioctl(struct file *file, unsigned int cmd,
 	if (file->f_op->ioctl) {
 		int rc;
 		lock_kernel();
-		rc = (*file->f_op->ioctl)(file->f_dentry->d_inode,
-				file, cmd, arg);
+		rc = (*file->f_op->ioctl) (file->f_dentry->d_inode,
+					   file, cmd, arg);
 		unlock_kernel();
 		return rc;
 	}
@@ -136,8 +136,7 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
 
 	/* Copy chaninfo structure.  Ignore unused members. */
 	if (!access_ok(VERIFY_READ, chaninfo32, sizeof(*chaninfo32))
-			|| !access_ok(VERIFY_WRITE, chaninfo,
-				sizeof(*chaninfo))) {
+	    || !access_ok(VERIFY_WRITE, chaninfo, sizeof(*chaninfo))) {
 		return -EFAULT;
 	}
 	err = 0;
@@ -171,8 +170,7 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
 
 	/* Copy rangeinfo structure. */
 	if (!access_ok(VERIFY_READ, rangeinfo32, sizeof(*rangeinfo32))
-			|| !access_ok(VERIFY_WRITE, rangeinfo,
-				sizeof(*rangeinfo))) {
+	    || !access_ok(VERIFY_WRITE, rangeinfo, sizeof(*rangeinfo))) {
 		return -EFAULT;
 	}
 	err = 0;
@@ -184,12 +182,12 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
 		return -EFAULT;
 
 	return translated_ioctl(file, COMEDI_RANGEINFO,
-			(unsigned long)rangeinfo);
+				(unsigned long)rangeinfo);
 }
 
 /* Copy 32-bit cmd structure to native cmd structure. */
-static int get_compat_cmd(struct comedi_cmd __user *cmd,
-		struct comedi32_cmd_struct __user *cmd32)
+static int get_compat_cmd(struct comedi_cmd __user * cmd,
+			  struct comedi32_cmd_struct __user * cmd32)
 {
 	int err;
 	union {
@@ -199,7 +197,7 @@ static int get_compat_cmd(struct comedi_cmd __user *cmd,
 
 	/* Copy cmd structure. */
 	if (!access_ok(VERIFY_READ, cmd32, sizeof(*cmd32))
-			|| !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) {
+	    || !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) {
 		return -EFAULT;
 	}
 	err = 0;
@@ -239,7 +237,8 @@ static int get_compat_cmd(struct comedi_cmd __user *cmd,
 }
 
 /* Copy native cmd structure to 32-bit cmd structure. */
-static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct 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;
@@ -249,7 +248,7 @@ static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct comed
 	/* (Could use ptr_to_compat() to set them, but that wasn't implemented
 	 * until kernel version 2.6.11.) */
 	if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd))
-			|| !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) {
+	    || !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) {
 		return -EFAULT;
 	}
 	err = 0;
@@ -329,8 +328,8 @@ static int compat_cmdtest(struct file *file, unsigned long arg)
 }
 
 /* Copy 32-bit insn structure to native insn structure. */
-static int get_compat_insn(struct comedi_insn __user *insn,
-		struct comedi32_insn_struct __user *insn32)
+static int get_compat_insn(struct comedi_insn __user * insn,
+			   struct comedi32_insn_struct __user * insn32)
 {
 	int err;
 	union {
@@ -341,7 +340,7 @@ static int get_compat_insn(struct comedi_insn __user *insn,
 	/* 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);
@@ -385,7 +384,7 @@ static int compat_insnlist(struct file *file, unsigned long arg)
 
 	/* Allocate user memory to copy insnlist and insns into. */
 	s = compat_alloc_user_space(offsetof(struct combined_insnlist,
-				insn[n_insns]));
+					     insn[n_insns]));
 
 	/* Set native insnlist structure. */
 	if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist))) {
@@ -404,7 +403,7 @@ static int compat_insnlist(struct file *file, unsigned long arg)
 	}
 
 	return translated_ioctl(file, COMEDI_INSNLIST,
-			(unsigned long)&s->insnlist);
+				(unsigned long)&s->insnlist);
 }
 
 /* Handle 32-bit COMEDI_INSN ioctl. */
@@ -427,7 +426,7 @@ static int compat_insn(struct file *file, unsigned long arg)
 /* Process untranslated ioctl. */
 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
 static inline int raw_ioctl(struct file *file, unsigned int cmd,
-		unsigned long arg)
+			    unsigned long arg)
 {
 	int rc;
 
@@ -477,8 +476,7 @@ static inline int raw_ioctl(struct file *file, unsigned int cmd,
 
 /* compat_ioctl file operation. */
 /* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
-long comedi_compat_ioctl(struct file *file, unsigned int cmd,
-		unsigned long arg)
+long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	return raw_ioctl(file, cmd, arg);
 }
@@ -497,7 +495,7 @@ long comedi_compat_ioctl(struct file *file, unsigned int cmd,
 
 /* Handler for all 32-bit ioctl codes registered by this driver. */
 static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
-		struct file *file)
+			struct file *file)
 {
 	int rc;
 
@@ -515,27 +513,27 @@ static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
 
 struct ioctl32_map {
 	unsigned int cmd;
-	int (*handler)(unsigned int, unsigned int, unsigned long,
+	int (*handler) (unsigned int, unsigned int, unsigned long,
 			struct file *);
 	int registered;
 };
 
 static struct ioctl32_map comedi_ioctl32_map[] = {
-	{ COMEDI_DEVCONFIG, mapped_ioctl, 0 },
-	{ COMEDI_DEVINFO, mapped_ioctl, 0 },
-	{ COMEDI_SUBDINFO, mapped_ioctl, 0 },
-	{ COMEDI_BUFCONFIG, mapped_ioctl, 0 },
-	{ COMEDI_BUFINFO, mapped_ioctl, 0 },
-	{ COMEDI_LOCK, mapped_ioctl, 0 },
-	{ COMEDI_UNLOCK, mapped_ioctl, 0 },
-	{ COMEDI_CANCEL, mapped_ioctl, 0 },
-	{ COMEDI_POLL, mapped_ioctl, 0 },
-	{ COMEDI32_CHANINFO, mapped_ioctl, 0 },
-	{ COMEDI32_RANGEINFO, mapped_ioctl, 0 },
-	{ COMEDI32_CMD, mapped_ioctl, 0 },
-	{ COMEDI32_CMDTEST, mapped_ioctl, 0 },
-	{ COMEDI32_INSNLIST, mapped_ioctl, 0 },
-	{ COMEDI32_INSN, mapped_ioctl, 0 },
+	{COMEDI_DEVCONFIG, mapped_ioctl, 0},
+	{COMEDI_DEVINFO, mapped_ioctl, 0},
+	{COMEDI_SUBDINFO, mapped_ioctl, 0},
+	{COMEDI_BUFCONFIG, mapped_ioctl, 0},
+	{COMEDI_BUFINFO, mapped_ioctl, 0},
+	{COMEDI_LOCK, mapped_ioctl, 0},
+	{COMEDI_UNLOCK, mapped_ioctl, 0},
+	{COMEDI_CANCEL, mapped_ioctl, 0},
+	{COMEDI_POLL, mapped_ioctl, 0},
+	{COMEDI32_CHANINFO, mapped_ioctl, 0},
+	{COMEDI32_RANGEINFO, mapped_ioctl, 0},
+	{COMEDI32_CMD, mapped_ioctl, 0},
+	{COMEDI32_CMDTEST, mapped_ioctl, 0},
+	{COMEDI32_INSNLIST, mapped_ioctl, 0},
+	{COMEDI32_INSN, mapped_ioctl, 0},
 };
 
 #define NUM_IOCTL32_MAPS ARRAY_SIZE(comedi_ioctl32_map)
@@ -547,13 +545,13 @@ void comedi_register_ioctl32(void)
 
 	for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
 		rc = register_ioctl32_conversion(comedi_ioctl32_map[n].cmd,
-				comedi_ioctl32_map[n].handler);
+						 comedi_ioctl32_map[n].handler);
 		if (rc) {
 			printk(KERN_WARNING
-					"comedi: failed to register 32-bit "
-					"compatible ioctl handler for 0x%X - "
-					"expect bad things to happen!\n",
-					comedi_ioctl32_map[n].cmd);
+			       "comedi: failed to register 32-bit "
+			       "compatible ioctl handler for 0x%X - "
+			       "expect bad things to happen!\n",
+			       comedi_ioctl32_map[n].cmd);
 		}
 		comedi_ioctl32_map[n].registered = !rc;
 	}
@@ -566,15 +564,16 @@ void comedi_unregister_ioctl32(void)
 
 	for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
 		if (comedi_ioctl32_map[n].registered) {
-			rc = unregister_ioctl32_conversion(
-					comedi_ioctl32_map[n].cmd,
-					comedi_ioctl32_map[n].handler);
+			rc = unregister_ioctl32_conversion(comedi_ioctl32_map
+							   [n].cmd,
+							   comedi_ioctl32_map
+							   [n].handler);
 			if (rc) {
 				printk(KERN_ERR
-					"comedi: failed to unregister 32-bit "
-					"compatible ioctl handler for 0x%X - "
-					"expect kernel Oops!\n",
-					comedi_ioctl32_map[n].cmd);
+				       "comedi: failed to unregister 32-bit "
+				       "compatible ioctl handler for 0x%X - "
+				       "expect kernel Oops!\n",
+				       comedi_ioctl32_map[n].cmd);
 			} else {
 				comedi_ioctl32_map[n].registered = 0;
 			}
@@ -582,6 +581,6 @@ void comedi_unregister_ioctl32(void)
 	}
 }
 
-#endif	/* HAVE_COMPAT_IOCTL */
+#endif /* HAVE_COMPAT_IOCTL */
 
-#endif	/* CONFIG_COMPAT */
+#endif /* CONFIG_COMPAT */
diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h
index 0ca0164..fd0f8a3 100644
--- a/drivers/staging/comedi/comedi_compat32.h
+++ b/drivers/staging/comedi/comedi_compat32.h
@@ -28,14 +28,14 @@
 #define _COMEDI_COMPAT32_H
 
 #include <linux/compat.h>
-#include <linux/fs.h>	/* For HAVE_COMPAT_IOCTL and HAVE_UNLOCKED_IOCTL */
+#include <linux/fs.h>		/* For HAVE_COMPAT_IOCTL and HAVE_UNLOCKED_IOCTL */
 
 #ifdef CONFIG_COMPAT
 
 #ifdef HAVE_COMPAT_IOCTL
 
 extern long comedi_compat_ioctl(struct file *file, unsigned int cmd,
-		unsigned long arg);
+				unsigned long arg);
 #define comedi_register_ioctl32() do {} while (0)
 #define comedi_unregister_ioctl32() do {} while (0)
 
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 640f65c..f54bb9b 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -68,26 +68,33 @@ 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];
+*comedi_file_info_table[COMEDI_NUM_MINORS];
 
-static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *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(struct comedi_device *dev, struct comedi_subdinfo *arg,
-			     void *file);
-static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg);
+static int do_devinfo_ioctl(struct comedi_device *dev,
+			    struct comedi_devinfo *arg, struct file *file);
+static int do_subdinfo_ioctl(struct comedi_device *dev,
+			     struct comedi_subdinfo *arg, 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_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);
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd,
+			 void *file);
 
-extern void do_become_nonbusy(struct comedi_device *dev, struct 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);
@@ -202,7 +209,8 @@ done:
 	writes:
 		none
 */
-static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg)
+static int do_devconfig_ioctl(struct comedi_device *dev,
+			      struct comedi_devconfig *arg)
 {
 	struct comedi_devconfig it;
 	int ret;
@@ -342,8 +350,8 @@ copyback:
 		devinfo structure
 
 */
-static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
-			    struct file *file)
+static int do_devinfo_ioctl(struct comedi_device *dev,
+			    struct comedi_devinfo *arg, struct file *file)
 {
 	struct comedi_devinfo devinfo;
 	const unsigned minor = iminor(file->f_dentry->d_inode);
@@ -392,14 +400,16 @@ static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *ar
 		array of subdevice info structures at arg
 
 */
-static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
-			     void *file)
+static int do_subdinfo_ioctl(struct comedi_device *dev,
+			     struct comedi_subdinfo *arg, void *file)
 {
 	int ret, i;
 	struct comedi_subdinfo *tmp, *us;
 	struct comedi_subdevice *s;
 
-	tmp = kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo), GFP_KERNEL);
+	tmp =
+	    kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo),
+		    GFP_KERNEL);
 	if (!tmp)
 		return -ENOMEM;
 
@@ -472,7 +482,8 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *
 		arrays at elements of chaninfo structure
 
 */
-static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg)
+static int do_chaninfo_ioctl(struct comedi_device *dev,
+			     struct comedi_chaninfo *arg)
 {
 	struct comedi_subdevice *s;
 	struct comedi_chaninfo it;
@@ -514,7 +525,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *
 		}
 #if 0
 		if (copy_to_user(it.rangelist, s->range_type_list,
-				 s->n_chan*sizeof(unsigned int)))
+				 s->n_chan * sizeof(unsigned int)))
 			return -EFAULT;
 #endif
 	}
@@ -589,8 +600,8 @@ copyback:
 	return 0;
 }
 
-static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
-		      void *file);
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
+		      unsigned int *data, void *file);
 /*
  * 	COMEDI_INSNLIST
  * 	synchronous instructions
@@ -626,7 +637,8 @@ static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
 		goto error;
 	}
 
-	insns = kmalloc(sizeof(struct 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;
@@ -678,7 +690,8 @@ error:
 	return i;
 }
 
-static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data)
+static int check_insn_config_length(struct comedi_insn *insn,
+				    unsigned int *data)
 {
 	if (insn->n < 1)
 		return -EINVAL;
@@ -725,22 +738,22 @@ static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data
 		if (insn->n == 5)
 			return 0;
 		break;
-	/* by default we allow the insn since we don't have checks for
-	 * all possible cases yet */
+		/* by default we allow the insn since we don't have checks for
+		 * all possible cases yet */
 	default:
 		printk("comedi: no check for data length of config insn id "
-			  "%i is implemented.\n"
-			  " Add a check to %s in %s.\n"
-			  " Assuming n=%i is correct.\n", data[0], __func__,
-			  __FILE__, insn->n);
+		       "%i is implemented.\n"
+		       " Add a check to %s in %s.\n"
+		       " Assuming n=%i is correct.\n", data[0], __func__,
+		       __FILE__, insn->n);
 		return 0;
 		break;
 	}
 	return -EINVAL;
 }
 
-static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
-		      void *file)
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
+		      unsigned int *data, void *file)
 {
 	struct comedi_subdevice *s;
 	int ret = 0;
@@ -920,7 +933,8 @@ static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file)
 	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(unsigned int))) {
+		if (copy_from_user
+		    (data, insn.data, insn.n * sizeof(unsigned int))) {
 			ret = -EFAULT;
 			goto error;
 		}
@@ -929,7 +943,8 @@ static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file)
 	if (ret < 0)
 		goto error;
 	if (insn.insn & INSN_MASK_READ) {
-		if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) {
+		if (copy_to_user
+		    (insn.data, data, insn.n * sizeof(unsigned int))) {
 			ret = -EFAULT;
 			goto error;
 		}
@@ -1202,7 +1217,8 @@ cleanup:
 
 */
 
-static int do_lock_ioctl(struct 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;
@@ -1246,7 +1262,8 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file
 	This function isn't protected by the semaphore, since
 	we already own the lock.
 */
-static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg,
+			   void *file)
 {
 	struct comedi_subdevice *s;
 
@@ -1286,7 +1303,8 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *fi
 		nothing
 
 */
-static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg,
+			   void *file)
 {
 	struct comedi_subdevice *s;
 
@@ -1322,7 +1340,8 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *fi
 		nothing
 
 */
-static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg,
+			 void *file)
 {
 	struct comedi_subdevice *s;
 
@@ -1371,7 +1390,7 @@ void comedi_unmap(struct vm_area_struct *area)
 }
 
 static struct vm_operations_struct comedi_vm_ops = {
-	.close =	comedi_unmap,
+	.close = comedi_unmap,
 };
 
 static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1428,10 +1447,10 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
 	n_pages = size >> PAGE_SHIFT;
 	for (i = 0; i < n_pages; ++i) {
 		if (remap_pfn_range(vma, start,
-				    page_to_pfn(virt_to_page(async->
-							     buf_page_list[i].
-							     virt_addr)),
-				    PAGE_SIZE, PAGE_SHARED)) {
+				    page_to_pfn(virt_to_page
+						(async->buf_page_list
+						 [i].virt_addr)), PAGE_SIZE,
+				    PAGE_SHARED)) {
 			retval = -EAGAIN;
 			goto done;
 		}
@@ -1449,7 +1468,7 @@ done:
 	return retval;
 }
 
-static unsigned int comedi_poll(struct file *file, poll_table *wait)
+static unsigned int comedi_poll(struct file *file, poll_table * wait)
 {
 	unsigned int mask = 0;
 	const unsigned minor = iminor(file->f_dentry->d_inode);
@@ -1496,7 +1515,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
 }
 
 static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
-			    loff_t *offset)
+			    loff_t * offset)
 {
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
@@ -1598,7 +1617,7 @@ done:
 }
 
 static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
-			   loff_t *offset)
+			   loff_t * offset)
 {
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
@@ -1729,7 +1748,8 @@ static int comedi_open(struct inode *inode, struct file *file)
 	const unsigned minor = iminor(inode);
 	struct comedi_device_file_info *dev_file_info =
 	    comedi_get_device_file_info(minor);
-	struct comedi_device *dev = dev_file_info ? dev_file_info->device : NULL;
+	struct comedi_device *dev =
+	    dev_file_info ? dev_file_info->device : NULL;
 
 	if (dev == NULL) {
 		DPRINTK("invalid minor number\n");
@@ -1846,22 +1866,22 @@ static int comedi_fasync(int fd, struct file *file, int on)
 }
 
 const struct file_operations comedi_fops = {
-      .owner =		THIS_MODULE,
+	.owner = THIS_MODULE,
 #ifdef HAVE_UNLOCKED_IOCTL
-      .unlocked_ioctl =	comedi_unlocked_ioctl,
+	.unlocked_ioctl = comedi_unlocked_ioctl,
 #else
-      .ioctl =		comedi_ioctl,
+	.ioctl = comedi_ioctl,
 #endif
 #ifdef HAVE_COMPAT_IOCTL
-      .compat_ioctl =	comedi_compat_ioctl,
+	.compat_ioctl = comedi_compat_ioctl,
 #endif
-      .open =		comedi_open,
-      .release =	comedi_close,
-      .read =		comedi_read,
-      .write =		comedi_write,
-      .mmap =		comedi_mmap,
-      .poll =		comedi_poll,
-      .fasync =		comedi_fasync,
+	.open = comedi_open,
+	.release = comedi_close,
+	.read = comedi_read,
+	.write = comedi_write,
+	.mmap = comedi_mmap,
+	.poll = comedi_poll,
+	.fasync = comedi_fasync,
 };
 
 struct class *comedi_class;
@@ -1952,7 +1972,6 @@ static void __exit comedi_cleanup(void)
 	for (i = 0; i < COMEDI_NUM_MINORS; ++i)
 		BUG_ON(comedi_file_info_table[i]);
 
-
 	class_destroy(comedi_class);
 	cdev_del(&comedi_cdev);
 	unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
@@ -1981,8 +2000,9 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
 	if ((comedi_get_subdevice_runflags(s) & SRF_RUNNING) == 0)
 		return;
 
-	if (s->async->
-	    events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) {
+	if (s->
+	    async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+			     COMEDI_CB_OVERFLOW)) {
 		runflags_mask |= SRF_RUNNING;
 	}
 	/* remember if an error event has occured, so an error
@@ -2000,12 +2020,10 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
 		if (comedi_get_subdevice_runflags(s) & SRF_USER) {
 			wake_up_interruptible(&async->wait_head);
 			if (s->subdev_flags & SDF_CMD_READ) {
-				kill_fasync(&dev->async_queue, SIGIO,
-					    POLL_IN);
+				kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
 			}
 			if (s->subdev_flags & SDF_CMD_WRITE) {
-				kill_fasync(&dev->async_queue, SIGIO,
-					    POLL_OUT);
+				kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
 			}
 		} else {
 			if (async->cb_func)
@@ -2103,7 +2121,8 @@ int comedi_alloc_board_minor(struct device *hardware_device)
 		comedi_device_cleanup(info->device);
 		kfree(info->device);
 		kfree(info);
-		printk(KERN_ERR "comedi: error: ran out of minor numbers for board device files.\n");
+		printk(KERN_ERR
+		       "comedi: error: ran out of minor numbers for board device files.\n");
 		return -EBUSY;
 	}
 	info->device->minor = i;
@@ -2115,29 +2134,33 @@ int comedi_alloc_board_minor(struct device *hardware_device)
 	dev_set_drvdata(csdev, info);
 	retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_max_read_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_max_read_buffer_kb.attr.name);
 		comedi_free_board_minor(i);
 		return retval;
 	}
 	retval = device_create_file(csdev, &dev_attr_read_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_read_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_read_buffer_kb.attr.name);
 		comedi_free_board_minor(i);
 		return retval;
 	}
 	retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_max_write_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_max_write_buffer_kb.attr.name);
 		comedi_free_board_minor(i);
 		return retval;
 	}
 	retval = device_create_file(csdev, &dev_attr_write_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_write_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_write_buffer_kb.attr.name);
 		comedi_free_board_minor(i);
 		return retval;
 	}
@@ -2194,7 +2217,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev,
 	spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
 	if (i == COMEDI_NUM_MINORS) {
 		kfree(info);
-		printk(KERN_ERR "comedi: error: ran out of minor numbers for board device files.\n");
+		printk(KERN_ERR
+		       "comedi: error: ran out of minor numbers for board device files.\n");
 		return -EBUSY;
 	}
 	s->minor = i;
@@ -2207,29 +2231,33 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev,
 	dev_set_drvdata(csdev, info);
 	retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_max_read_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_max_read_buffer_kb.attr.name);
 		comedi_free_subdevice_minor(s);
 		return retval;
 	}
 	retval = device_create_file(csdev, &dev_attr_read_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_read_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_read_buffer_kb.attr.name);
 		comedi_free_subdevice_minor(s);
 		return retval;
 	}
 	retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_max_write_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_max_write_buffer_kb.attr.name);
 		comedi_free_subdevice_minor(s);
 		return retval;
 	}
 	retval = device_create_file(csdev, &dev_attr_write_buffer_kb);
 	if (retval) {
-		printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
-			dev_attr_write_buffer_kb.attr.name);
+		printk(KERN_ERR
+		       "comedi: failed to create sysfs attribute file \"%s\".\n",
+		       dev_attr_write_buffer_kb.attr.name);
 		comedi_free_subdevice_minor(s);
 		return retval;
 	}
@@ -2295,7 +2323,7 @@ static int resize_async_buffer(struct comedi_device *dev,
 		return -EINVAL;
 
 	/* make sure buffer is an integral number of pages
-		* (we round up) */
+	 * (we round up) */
 	new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
 
 	retval = comedi_buf_alloc(dev, s, new_size);
@@ -2324,16 +2352,16 @@ static ssize_t show_max_read_buffer_kb(struct device *dev,
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
 	unsigned max_buffer_size_kb = 0;
 	struct comedi_subdevice *const read_subdevice =
-					comedi_get_read_subdevice(info);
+	    comedi_get_read_subdevice(info);
 
 	mutex_lock(&info->device->mutex);
 	if (read_subdevice &&
 	    (read_subdevice->subdev_flags & SDF_CMD_READ) &&
 	    read_subdevice->async) {
 		max_buffer_size_kb = read_subdevice->async->max_bufsize /
-					bytes_per_kibi;
+		    bytes_per_kibi;
 	}
-	retval =  snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
+	retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
 	mutex_unlock(&info->device->mutex);
 
 	return retval;
@@ -2347,14 +2375,14 @@ static ssize_t store_max_read_buffer_kb(struct device *dev,
 	unsigned long new_max_size_kb;
 	uint64_t new_max_size;
 	struct comedi_subdevice *const read_subdevice =
-					comedi_get_read_subdevice(info);
+	    comedi_get_read_subdevice(info);
 
 	if (strict_strtoul(buf, 10, &new_max_size_kb))
 		return -EINVAL;
-	if (new_max_size_kb != (uint32_t)new_max_size_kb)
+	if (new_max_size_kb != (uint32_t) new_max_size_kb)
 		return -EINVAL;
-	new_max_size = ((uint64_t)new_max_size_kb) * bytes_per_kibi;
-	if (new_max_size != (uint32_t)new_max_size)
+	new_max_size = ((uint64_t) new_max_size_kb) * bytes_per_kibi;
+	if (new_max_size != (uint32_t) new_max_size)
 		return -EINVAL;
 
 	mutex_lock(&info->device->mutex);
@@ -2372,9 +2400,8 @@ static ssize_t store_max_read_buffer_kb(struct device *dev,
 
 static struct device_attribute dev_attr_max_read_buffer_kb = {
 	.attr = {
-			.name = "max_read_buffer_kb",
-			.mode = S_IRUGO | S_IWUSR
-		},
+		 .name = "max_read_buffer_kb",
+		 .mode = S_IRUGO | S_IWUSR},
 	.show = &show_max_read_buffer_kb,
 	.store = &store_max_read_buffer_kb
 };
@@ -2386,16 +2413,16 @@ static ssize_t show_read_buffer_kb(struct device *dev,
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
 	unsigned buffer_size_kb = 0;
 	struct comedi_subdevice *const read_subdevice =
-					comedi_get_read_subdevice(info);
+	    comedi_get_read_subdevice(info);
 
 	mutex_lock(&info->device->mutex);
 	if (read_subdevice &&
-		(read_subdevice->subdev_flags & SDF_CMD_READ) &&
-		read_subdevice->async) {
+	    (read_subdevice->subdev_flags & SDF_CMD_READ) &&
+	    read_subdevice->async) {
 		buffer_size_kb = read_subdevice->async->prealloc_bufsz /
-					bytes_per_kibi;
+		    bytes_per_kibi;
 	}
-	retval =  snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
+	retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
 	mutex_unlock(&info->device->mutex);
 
 	return retval;
@@ -2410,14 +2437,14 @@ static ssize_t store_read_buffer_kb(struct device *dev,
 	uint64_t new_size;
 	int retval;
 	struct comedi_subdevice *const read_subdevice =
-					comedi_get_read_subdevice(info);
+	    comedi_get_read_subdevice(info);
 
 	if (strict_strtoul(buf, 10, &new_size_kb))
 		return -EINVAL;
-	if (new_size_kb != (uint32_t)new_size_kb)
+	if (new_size_kb != (uint32_t) new_size_kb)
 		return -EINVAL;
-	new_size = ((uint64_t)new_size_kb) * bytes_per_kibi;
-	if (new_size != (uint32_t)new_size)
+	new_size = ((uint64_t) new_size_kb) * bytes_per_kibi;
+	if (new_size != (uint32_t) new_size)
 		return -EINVAL;
 
 	mutex_lock(&info->device->mutex);
@@ -2438,9 +2465,8 @@ static ssize_t store_read_buffer_kb(struct device *dev,
 
 static struct device_attribute dev_attr_read_buffer_kb = {
 	.attr = {
-			.name = "read_buffer_kb",
-			.mode = S_IRUGO | S_IWUSR | S_IWGRP
-		},
+		 .name = "read_buffer_kb",
+		 .mode = S_IRUGO | S_IWUSR | S_IWGRP},
 	.show = &show_read_buffer_kb,
 	.store = &store_read_buffer_kb
 };
@@ -2453,16 +2479,16 @@ static ssize_t show_max_write_buffer_kb(struct device *dev,
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
 	unsigned max_buffer_size_kb = 0;
 	struct comedi_subdevice *const write_subdevice =
-					comedi_get_write_subdevice(info);
+	    comedi_get_write_subdevice(info);
 
 	mutex_lock(&info->device->mutex);
 	if (write_subdevice &&
 	    (write_subdevice->subdev_flags & SDF_CMD_WRITE) &&
 	    write_subdevice->async) {
 		max_buffer_size_kb = write_subdevice->async->max_bufsize /
-					bytes_per_kibi;
+		    bytes_per_kibi;
 	}
-	retval =  snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
+	retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
 	mutex_unlock(&info->device->mutex);
 
 	return retval;
@@ -2476,14 +2502,14 @@ static ssize_t store_max_write_buffer_kb(struct device *dev,
 	unsigned long new_max_size_kb;
 	uint64_t new_max_size;
 	struct comedi_subdevice *const write_subdevice =
-					comedi_get_write_subdevice(info);
+	    comedi_get_write_subdevice(info);
 
 	if (strict_strtoul(buf, 10, &new_max_size_kb))
 		return -EINVAL;
-	if (new_max_size_kb != (uint32_t)new_max_size_kb)
+	if (new_max_size_kb != (uint32_t) new_max_size_kb)
 		return -EINVAL;
-	new_max_size = ((uint64_t)new_max_size_kb) * bytes_per_kibi;
-	if (new_max_size != (uint32_t)new_max_size)
+	new_max_size = ((uint64_t) new_max_size_kb) * bytes_per_kibi;
+	if (new_max_size != (uint32_t) new_max_size)
 		return -EINVAL;
 
 	mutex_lock(&info->device->mutex);
@@ -2501,9 +2527,8 @@ static ssize_t store_max_write_buffer_kb(struct device *dev,
 
 static struct device_attribute dev_attr_max_write_buffer_kb = {
 	.attr = {
-			.name = "max_write_buffer_kb",
-			.mode = S_IRUGO | S_IWUSR
-		},
+		 .name = "max_write_buffer_kb",
+		 .mode = S_IRUGO | S_IWUSR},
 	.show = &show_max_write_buffer_kb,
 	.store = &store_max_write_buffer_kb
 };
@@ -2515,16 +2540,16 @@ static ssize_t show_write_buffer_kb(struct device *dev,
 	struct comedi_device_file_info *info = dev_get_drvdata(dev);
 	unsigned buffer_size_kb = 0;
 	struct comedi_subdevice *const write_subdevice =
-					comedi_get_write_subdevice(info);
+	    comedi_get_write_subdevice(info);
 
 	mutex_lock(&info->device->mutex);
 	if (write_subdevice &&
 	    (write_subdevice->subdev_flags & SDF_CMD_WRITE) &&
 	    write_subdevice->async) {
 		buffer_size_kb = write_subdevice->async->prealloc_bufsz /
-					bytes_per_kibi;
+		    bytes_per_kibi;
 	}
-	retval =  snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
+	retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
 	mutex_unlock(&info->device->mutex);
 
 	return retval;
@@ -2539,14 +2564,14 @@ static ssize_t store_write_buffer_kb(struct device *dev,
 	uint64_t new_size;
 	int retval;
 	struct comedi_subdevice *const write_subdevice =
-					comedi_get_write_subdevice(info);
+	    comedi_get_write_subdevice(info);
 
 	if (strict_strtoul(buf, 10, &new_size_kb))
 		return -EINVAL;
-	if (new_size_kb != (uint32_t)new_size_kb)
+	if (new_size_kb != (uint32_t) new_size_kb)
 		return -EINVAL;
-	new_size = ((uint64_t)new_size_kb) * bytes_per_kibi;
-	if (new_size != (uint32_t)new_size)
+	new_size = ((uint64_t) new_size_kb) * bytes_per_kibi;
+	if (new_size != (uint32_t) new_size)
 		return -EINVAL;
 
 	mutex_lock(&info->device->mutex);
@@ -2557,7 +2582,7 @@ static ssize_t store_write_buffer_kb(struct device *dev,
 		return -EINVAL;
 	}
 	retval = resize_async_buffer(info->device, write_subdevice,
-		write_subdevice->async, new_size);
+				     write_subdevice->async, new_size);
 	mutex_unlock(&info->device->mutex);
 
 	if (retval < 0)
@@ -2567,9 +2592,8 @@ static ssize_t store_write_buffer_kb(struct device *dev,
 
 static struct device_attribute dev_attr_write_buffer_kb = {
 	.attr = {
-			.name = "write_buffer_kb",
-			.mode = S_IRUGO | S_IWUSR | S_IWGRP
-		},
+		 .name = "write_buffer_kb",
+		 .mode = S_IRUGO | S_IWUSR | S_IWGRP},
 	.show = &show_write_buffer_kb,
 	.store = &store_write_buffer_kb
 };
diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c
index a732e34..87803e6 100644
--- a/drivers/staging/comedi/comedi_ksyms.c
+++ b/drivers/staging/comedi/comedi_ksyms.c
@@ -22,9 +22,6 @@
 */
 
 #define __NO_VERSION__
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
 
 #include "comedidev.h"
 
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 89af44a..e8a5f7d 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -156,28 +156,30 @@ struct comedi_subdevice {
 
 	unsigned int *chanlist;	/* driver-owned chanlist (not used) */
 
-	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 (*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) (struct comedi_device *, struct comedi_subdevice *);
-	int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *, struct comedi_cmd *);
+	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) (struct comedi_device *dev, struct comedi_subdevice *s,
-		unsigned long new_size);
+	int (*buf_change) (struct comedi_device * dev,
+			   struct comedi_subdevice * s, unsigned long new_size);
 
-	void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, void *data,
-		unsigned int num_bytes, unsigned int start_chan_index);
+	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;
@@ -231,7 +233,7 @@ struct comedi_async {
 	int (*cb_func) (unsigned int flags, void *);
 	void *cb_arg;
 
-	int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
+	int (*inttrig) (struct comedi_device * dev, struct comedi_subdevice * s,
 			unsigned int x);
 };
 
@@ -281,8 +283,8 @@ struct comedi_device {
 
 	struct fasync_struct *async_queue;
 
-	void (*open) (struct comedi_device *dev);
-	void (*close) (struct comedi_device *dev);
+	void (*open) (struct comedi_device * dev);
+	void (*close) (struct comedi_device * dev);
 };
 
 struct comedi_device_file_info {
@@ -316,8 +318,9 @@ static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
 
 struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
 
-static inline struct comedi_subdevice *comedi_get_read_subdevice(
-				const struct comedi_device_file_info *info)
+static inline struct comedi_subdevice *comedi_get_read_subdevice(const struct
+								 comedi_device_file_info
+								 *info)
 {
 	if (info->read_subdevice)
 		return info->read_subdevice;
@@ -326,8 +329,9 @@ static inline struct comedi_subdevice *comedi_get_read_subdevice(
 	return info->device->read_subdev;
 }
 
-static inline struct comedi_subdevice *comedi_get_write_subdevice(
-				const struct comedi_device_file_info *info)
+static inline struct comedi_subdevice *comedi_get_write_subdevice(const struct
+								  comedi_device_file_info
+								  *info)
 {
 	if (info->write_subdevice)
 		return info->write_subdevice;
@@ -337,7 +341,8 @@ static inline struct comedi_subdevice *comedi_get_write_subdevice(
 }
 
 void comedi_device_detach(struct comedi_device *dev);
-int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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 *);
 
@@ -346,8 +351,8 @@ void cleanup_polling(void);
 void start_polling(struct comedi_device *);
 void stop_polling(struct comedi_device *);
 
-int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long
-	new_size);
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
+		     unsigned long new_size);
 
 #ifdef CONFIG_PROC_FS
 void comedi_proc_init(void);
@@ -356,6 +361,7 @@ void comedi_proc_cleanup(void);
 static inline void comedi_proc_init(void)
 {
 }
+
 static inline void comedi_proc_cleanup(void)
 {
 }
@@ -378,10 +384,10 @@ enum subdevice_runflags {
 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 bits);
 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);
+	       struct comedi_insn *insn, unsigned int *data);
 
 /* range stuff */
 
@@ -421,7 +427,8 @@ static inline int alloc_subdevices(struct comedi_device *dev,
 
 	dev->n_subdevices = num_subdevices;
 	dev->subdevices =
-		kcalloc(num_subdevices, sizeof(struct 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) {
@@ -451,7 +458,8 @@ static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
 
 /* 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(struct 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);
@@ -467,21 +475,23 @@ 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(struct comedi_async *async);
-unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes);
+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 int nbytes);
 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);
+			  const void *source, unsigned int num_bytes);
 void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
-	void *destination, unsigned int num_bytes);
+			    void *destination, unsigned int num_bytes);
 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(struct comedi_async *async)
 {
 	return async->buf_read_alloc_count - async->buf_read_count;
@@ -516,25 +526,26 @@ static inline void *comedi_aux_data(int options[], int n)
 
 int comedi_alloc_board_minor(struct device *hardware_device);
 void comedi_free_board_minor(unsigned minor);
-int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct 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 */
+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);
 
 #ifdef CONFIG_COMEDI_PCI_DRIVERS
-	#define CONFIG_COMEDI_PCI
+#define CONFIG_COMEDI_PCI
 #endif
 #ifdef CONFIG_COMEDI_PCI_DRIVERS_MODULE
-	#define CONFIG_COMEDI_PCI
+#define CONFIG_COMEDI_PCI
 #endif
 #ifdef CONFIG_COMEDI_PCMCIA_DRIVERS
-	#define CONFIG_COMEDI_PCMCIA
+#define CONFIG_COMEDI_PCMCIA
 #endif
 #ifdef CONFIG_COMEDI_PCMCIA_DRIVERS_MODULE
-	#define CONFIG_COMEDI_PCMCIA
+#define CONFIG_COMEDI_PCMCIA
 #endif
 
 #endif /* _COMEDIDEV_H */
diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h
index c272931..3918d53 100644
--- a/drivers/staging/comedi/comedilib.h
+++ b/drivers/staging/comedi/comedilib.h
@@ -58,29 +58,31 @@ int comedi_fileno(void *dev);
 
 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);
+			     unsigned int mask, int (*cb) (unsigned int,
+							   void *), void *arg);
 
 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);
+		      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);
+		     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(void *dev, unsigned int subdev,
-	unsigned int chan, unsigned int range, unsigned int aref,
-	unsigned int *data, unsigned int nano_sec);
+			  unsigned int chan, unsigned int range,
+			  unsigned int aref);
+int comedi_data_read_delayed(void *dev, unsigned int subdev, unsigned int chan,
+			     unsigned int range, unsigned int aref,
+			     unsigned int *data, unsigned int nano_sec);
 int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int io);
+		      unsigned int io);
 int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int *val);
+		    unsigned int *val);
 int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int val);
+		     unsigned int val);
 int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
-	unsigned int *bits);
+			unsigned int *bits);
 int comedi_get_n_subdevices(void *dev);
 int comedi_get_version_code(void *dev);
 const char *comedi_get_driver_name(void *dev);
@@ -89,31 +91,29 @@ 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(void *dev, unsigned int subdevice, unsigned int
-	chan);
+				int chan);
+int comedi_get_n_ranges(void *dev, unsigned int subdevice, unsigned int chan);
 int comedi_do_insn(void *dev, struct comedi_insn *insn);
 int comedi_poll(void *dev, unsigned int subdev);
 
 /* DEPRECATED functions */
-int comedi_get_rangetype(void *dev, unsigned int subdevice,
-	unsigned int chan);
+int comedi_get_rangetype(void *dev, unsigned int subdevice, unsigned int chan);
 
 /* ALPHA functions */
 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);
+		      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);
+			      unsigned int buf_user_count);
 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);
+			    unsigned int num_bytes);
 int comedi_mark_buffer_written(void *d, unsigned int subdevice,
-	unsigned int num_bytes);
+			       unsigned int num_bytes);
 int comedi_get_buffer_contents(void *dev, unsigned int subdevice);
 int comedi_get_buffer_offset(void *dev, unsigned int subdevice);
 
@@ -135,53 +135,56 @@ int comedi_unlock(unsigned int minor, unsigned int subdev);
 
 int comedi_cancel(unsigned int minor, unsigned int subdev);
 int comedi_register_callback(unsigned int minor, unsigned int subdev,
-	unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
+			     unsigned int mask, int (*cb) (unsigned int,
+							   void *), void *arg);
 
 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_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, unsigned int 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, unsigned int *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);
+		      unsigned int io);
 int comedi_dio_read(unsigned int dev, unsigned int subdev, unsigned int chan,
-	unsigned int *val);
+		    unsigned int *val);
 int comedi_dio_write(unsigned int dev, unsigned int subdev, unsigned int chan,
-	unsigned int val);
+		     unsigned int val);
 int comedi_dio_bitfield(unsigned int dev, unsigned int subdev,
-	unsigned int mask, unsigned int *bits);
+			unsigned int mask, unsigned int *bits);
 int comedi_get_n_subdevices(unsigned int dev);
 int comedi_get_version_code(unsigned int dev);
 char *comedi_get_driver_name(unsigned int dev);
 char *comedi_get_board_name(unsigned int minor);
 int comedi_get_subdevice_type(unsigned int minor, unsigned int subdevice);
 int comedi_find_subdevice_by_type(unsigned int minor, int type,
-	unsigned int subd);
+				  unsigned int subd);
 int comedi_get_n_channels(unsigned int minor, unsigned int subdevice);
 unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
-	int chan);
+				int chan);
 int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, unsigned int
-	chan);
+			chan);
 int comedi_do_insn(unsigned int minor, struct comedi_insn *insn);
 int comedi_poll(unsigned int minor, unsigned int subdev);
 
 /* DEPRECATED functions */
 int comedi_get_rangetype(unsigned int minor, unsigned int subdevice,
-	unsigned int chan);
+			 unsigned int chan);
 
 /* ALPHA functions */
 unsigned int comedi_get_subdevice_flags(unsigned int minor, unsigned int
-	subdevice);
+					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, struct comedi_krange *krange);
+		      chan, unsigned int range, struct comedi_krange *krange);
 unsigned int comedi_get_buf_head_pos(unsigned int minor, unsigned int
-	subdevice);
+				     subdevice);
 int comedi_set_user_int_count(unsigned int minor, unsigned int subdevice,
-	unsigned int buf_user_count);
+			      unsigned int buf_user_count);
 int comedi_map(unsigned int minor, unsigned int subdev, void **ptr);
 int comedi_unmap(unsigned int minor, unsigned int subdev);
 
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 42a0257..dc53aee 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -48,13 +48,14 @@
 #include <asm/system.h>
 
 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 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);
+		     unsigned long new_size);
 
 struct comedi_driver *comedi_drivers;
 
@@ -123,7 +124,8 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	for (driv = comedi_drivers; driv; driv = driv->next) {
 		if (!try_module_get(driv->module)) {
-			printk("comedi: failed to increment module count, skipping\n");
+			printk
+			    ("comedi: failed to increment module count, skipping\n");
 			continue;
 		}
 		if (driv->num_names) {
@@ -195,16 +197,20 @@ int comedi_driver_unregister(struct comedi_driver *driver)
 
 	/* 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);
+		struct comedi_device_file_info *dev_file_info =
+		    comedi_get_device_file_info(i);
 		struct comedi_device *dev;
 
-		if (dev_file_info == NULL) continue;
+		if (dev_file_info == NULL)
+			continue;
 		dev = dev_file_info->device;
 
 		mutex_lock(&dev->mutex);
 		if (dev->attached && dev->driver == driver) {
 			if (dev->use_count)
-				printk("BUG! detaching device with use_count=%d\n", dev->use_count);
+				printk
+				    ("BUG! detaching device with use_count=%d\n",
+				     dev->use_count);
 			comedi_device_detach(dev);
 		}
 		mutex_unlock(&dev->mutex);
@@ -242,10 +248,11 @@ static int postconfig(struct comedi_device *dev)
 
 		if (s->do_cmd) {
 			BUG_ON((s->subdev_flags & (SDF_CMD_READ |
-				SDF_CMD_WRITE)) == 0);
+						   SDF_CMD_WRITE)) == 0);
 			BUG_ON(!s->do_cmdtest);
 
-			async = kzalloc(sizeof(struct 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,7 +305,7 @@ static int postconfig(struct comedi_device *dev)
 }
 
 /*  generic recognize function for drivers that register their supported board names */
-void *comedi_recognize(struct comedi_driver * driv, const char *name)
+void *comedi_recognize(struct comedi_driver *driv, const char *name)
 {
 	unsigned i;
 	const char *const *name_ptr = driv->board_name;
@@ -306,8 +313,8 @@ void *comedi_recognize(struct comedi_driver * driv, const char *name)
 		if (strcmp(*name_ptr, name) == 0)
 			return (void *)name_ptr;
 		name_ptr =
-			(const char *const *)((const char *)name_ptr +
-			driv->offset);
+		    (const char *const *)((const char *)name_ptr +
+					  driv->offset);
 	}
 
 	return NULL;
@@ -319,7 +326,7 @@ void comedi_report_boards(struct comedi_driver *driv)
 	const char *const *name_ptr;
 
 	printk("comedi: valid board names for %s driver are:\n",
-		driv->driver_name);
+	       driv->driver_name);
 
 	name_ptr = driv->board_name;
 	for (i = 0; i < driv->num_names; i++) {
@@ -337,13 +344,14 @@ static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+	       struct comedi_insn *insn, unsigned int *data)
 {
 	return -EINVAL;
 }
 
-static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int insn_rw_emulate_bits(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	struct comedi_insn new_insn;
 	int ret;
@@ -351,7 +359,7 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevi
 
 	unsigned chan = CR_CHAN(insn->chanspec);
 	const unsigned base_bitfield_channel =
-		(chan < channels_per_bitfield) ? 0 : chan;
+	    (chan < channels_per_bitfield) ? 0 : chan;
 	unsigned int new_data[2];
 	memset(new_data, 0, sizeof(new_data));
 	memset(&new_insn, 0, sizeof(new_insn));
@@ -379,7 +387,7 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevi
 	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;
@@ -394,7 +402,7 @@ static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
 			pte = *ptep;
 			if (pte_present(pte)) {
 				ret = (unsigned long)
-					page_address(pte_page(pte));
+				    page_address(pte_page(pte));
 				ret |= (adr & (PAGE_SIZE - 1));
 			}
 		}
@@ -413,7 +421,7 @@ static inline unsigned long kvirt_to_kva(unsigned long adr)
 }
 
 int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned long new_size)
+		     unsigned long new_size)
 {
 	struct comedi_async *async = s->async;
 
@@ -434,18 +442,22 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 		unsigned i;
 		for (i = 0; i < async->n_buf_pages; ++i) {
 			if (async->buf_page_list[i].virt_addr) {
-				mem_map_unreserve(virt_to_page(async->
-						buf_page_list[i].virt_addr));
+				mem_map_unreserve(virt_to_page
+						  (async->buf_page_list[i].
+						   virt_addr));
 				if (s->async_dma_dir != DMA_NONE) {
 					dma_free_coherent(dev->hw_dev,
-						PAGE_SIZE,
-						async->buf_page_list[i].
-						virt_addr,
-						async->buf_page_list[i].
-						dma_addr);
+							  PAGE_SIZE,
+							  async->
+							  buf_page_list
+							  [i].virt_addr,
+							  async->
+							  buf_page_list
+							  [i].dma_addr);
 				} else {
-					free_page((unsigned long)async->
-						buf_page_list[i].virt_addr);
+					free_page((unsigned long)
+						  async->buf_page_list[i].
+						  virt_addr);
 				}
 			}
 		}
@@ -460,66 +472,69 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 		struct page **pages = NULL;
 
 		async->buf_page_list =
-			vmalloc(sizeof(struct comedi_buf_page) * n_pages);
+		    vmalloc(sizeof(struct comedi_buf_page) * n_pages);
 		if (async->buf_page_list) {
 			memset(async->buf_page_list, 0,
-				sizeof(struct comedi_buf_page) * n_pages);
+			       sizeof(struct comedi_buf_page) * n_pages);
 			pages = vmalloc(sizeof(struct page *) * n_pages);
 		}
 		if (pages) {
 			for (i = 0; i < n_pages; i++) {
 				if (s->async_dma_dir != DMA_NONE) {
 					async->buf_page_list[i].virt_addr =
-						dma_alloc_coherent(dev->hw_dev,
-						PAGE_SIZE,
-						&async->buf_page_list[i].
-						dma_addr,
-						GFP_KERNEL | __GFP_COMP);
+					    dma_alloc_coherent(dev->hw_dev,
+							       PAGE_SIZE,
+							       &async->
+							       buf_page_list
+							       [i].dma_addr,
+							       GFP_KERNEL |
+							       __GFP_COMP);
 				} else {
 					async->buf_page_list[i].virt_addr =
-						(void *)
-						get_zeroed_page(GFP_KERNEL);
+					    (void *)
+					    get_zeroed_page(GFP_KERNEL);
 				}
 				if (async->buf_page_list[i].virt_addr == NULL) {
 					break;
 				}
-				mem_map_reserve(virt_to_page(async->
-						buf_page_list[i].virt_addr));
+				mem_map_reserve(virt_to_page
+						(async->buf_page_list[i].
+						 virt_addr));
 				pages[i] =
-					virt_to_page(async->buf_page_list[i].
-					virt_addr);
+				    virt_to_page(async->
+						 buf_page_list[i].virt_addr);
 			}
 		}
 		if (i == n_pages) {
 			async->prealloc_buf =
-				vmap(pages, n_pages, VM_MAP,
-				PAGE_KERNEL_NOCACHE);
-		}
-		if (pages) {
-			vfree(pages);
+			    vmap(pages, n_pages, VM_MAP, PAGE_KERNEL_NOCACHE);
 		}
+		vfree(pages);
+
 		if (async->prealloc_buf == NULL) {
 			/* Some allocation failed above. */
 			if (async->buf_page_list) {
 				for (i = 0; i < n_pages; i++) {
 					if (async->buf_page_list[i].virt_addr ==
-						NULL) {
+					    NULL) {
 						break;
 					}
-					mem_map_unreserve(virt_to_page(async->
-							buf_page_list[i].
-							virt_addr));
+					mem_map_unreserve(virt_to_page
+							  (async->buf_page_list
+							   [i].virt_addr));
 					if (s->async_dma_dir != DMA_NONE) {
 						dma_free_coherent(dev->hw_dev,
-							PAGE_SIZE,
-							async->buf_page_list[i].
-							virt_addr,
-							async->buf_page_list[i].
-							dma_addr);
+								  PAGE_SIZE,
+								  async->
+								  buf_page_list
+								  [i].virt_addr,
+								  async->
+								  buf_page_list
+								  [i].dma_addr);
 					} else {
-						free_page((unsigned long)async->
-							buf_page_list[i].
-							virt_addr);
+						free_page((unsigned long)
+							  async->buf_page_list
+							  [i].virt_addr);
 					}
 				}
 				vfree(async->buf_page_list);
@@ -536,7 +551,8 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 
 /* munging is applied to data by core as it passes between user
  * and kernel space */
-unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes)
+unsigned int comedi_buf_munge(struct comedi_async *async,
+			      unsigned int num_bytes)
 {
 	struct comedi_subdevice *s = async->subdevice;
 	unsigned int count = 0;
@@ -555,15 +571,15 @@ unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes
 		block_size = num_bytes - count;
 		if (block_size < 0) {
 			printk("%s: %s: bug! block_size is negative\n",
-				__FILE__, __func__);
+			       __FILE__, __func__);
 			break;
 		}
 		if ((int)(async->munge_ptr + block_size -
-				async->prealloc_bufsz) > 0)
+			  async->prealloc_bufsz) > 0)
 			block_size = async->prealloc_bufsz - async->munge_ptr;
 
 		s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
-			block_size, async->munge_chan);
+			 block_size, async->munge_chan);
 
 		smp_wmb();	/* barrier insures data is munged in buffer before munge_count is incremented */
 
@@ -598,7 +614,8 @@ unsigned int comedi_buf_write_n_available(struct comedi_async *async)
 }
 
 /* allocates chunk for the writer from free buffer space */
-unsigned int comedi_buf_write_alloc(struct 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;
 
@@ -614,7 +631,7 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nby
 
 /* allocates nothing unless it can completely fulfill the request */
 unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
-	unsigned int nbytes)
+					   unsigned int nbytes)
 {
 	unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
 
@@ -632,8 +649,9 @@ unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
 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) {
-		printk("comedi: attempted to write-free more bytes than have been write-allocated.\n");
+		  async->buf_write_alloc_count) > 0) {
+		printk
+		    ("comedi: attempted to write-free more bytes than have been write-allocated.\n");
 		nbytes = async->buf_write_alloc_count - async->buf_write_count;
 	}
 	async->buf_write_count += nbytes;
@@ -649,7 +667,7 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
 unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes)
 {
 	if ((int)(async->buf_read_alloc_count + nbytes - async->munge_count) >
-		0) {
+	    0) {
 		nbytes = async->munge_count - async->buf_read_alloc_count;
 	}
 	async->buf_read_alloc_count += nbytes;
@@ -665,8 +683,9 @@ 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 */
 	smp_mb();
 	if ((int)(async->buf_read_count + nbytes -
-			async->buf_read_alloc_count) > 0) {
-		printk("comedi: attempted to read-free more bytes than have been read-allocated.\n");
+		  async->buf_read_alloc_count) > 0) {
+		printk
+		    ("comedi: attempted to read-free more bytes than have been read-allocated.\n");
 		nbytes = async->buf_read_alloc_count - async->buf_read_count;
 	}
 	async->buf_read_count += nbytes;
@@ -676,7 +695,7 @@ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes)
 }
 
 void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
-	const void *data, unsigned int num_bytes)
+			  const void *data, unsigned int num_bytes)
 {
 	unsigned int write_ptr = async->buf_write_ptr + offset;
 
@@ -701,7 +720,7 @@ void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
 }
 
 void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
-	void *dest, unsigned int nbytes)
+			    void *dest, unsigned int nbytes)
 {
 	void *src;
 	unsigned int read_ptr = async->buf_read_ptr + offset;
@@ -748,7 +767,7 @@ int comedi_buf_get(struct comedi_async *async, short *x)
 	if (n < sizeof(short))
 		return 0;
 	comedi_buf_read_alloc(async, sizeof(short));
-	*x = *(short *) (async->prealloc_buf + async->buf_read_ptr);
+	*x = *(short *)(async->prealloc_buf + async->buf_read_ptr);
 	comedi_buf_read_free(async, sizeof(short));
 	return 1;
 }
@@ -761,7 +780,7 @@ int comedi_buf_put(struct comedi_async *async, short x)
 		async->events |= COMEDI_CB_ERROR;
 		return 0;
 	}
-	*(short *) (async->prealloc_buf + async->buf_write_ptr) = x;
+	*(short *)(async->prealloc_buf + async->buf_write_ptr) = x;
 	comedi_buf_write_free(async, sizeof(short));
 	return 1;
 }
@@ -785,7 +804,8 @@ void comedi_reset_async_buf(struct comedi_async *async)
 	async->events = 0;
 }
 
-int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options)
+int comedi_auto_config(struct device *hardware_device, const char *board_name,
+		       const int *options, unsigned num_options)
 {
 	struct comedi_devconfig it;
 	int minor;
@@ -799,7 +819,8 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
 	}
 
 	minor = comedi_alloc_board_minor(hardware_device);
-	if (minor < 0) return minor;
+	if (minor < 0)
+		return minor;
 
 	private_data = kmalloc(sizeof(unsigned), GFP_KERNEL);
 	if (private_data == NULL) {
@@ -822,8 +843,7 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
 	mutex_unlock(&dev_file_info->device->mutex);
 
 cleanup:
-	if (retval < 0)
-	{
+	if (retval < 0) {
 		kfree(private_data);
 		comedi_free_board_minor(minor);
 	}
@@ -833,7 +853,8 @@ cleanup:
 void comedi_auto_unconfig(struct device *hardware_device)
 {
 	unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device);
-	if (minor == NULL) return;
+	if (minor == NULL)
+		return;
 
 	BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS);
 
@@ -860,8 +881,7 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
 	comedi_auto_unconfig(&pcidev->dev);
 }
 
-int comedi_usb_auto_config(struct usb_device *usbdev,
-	const char *board_name)
+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);
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
index ad467ac..c2ea2d9 100644
--- a/drivers/staging/comedi/drivers/8253.h
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -29,8 +29,10 @@
 #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)
+						      unsigned int *d1,
+						      unsigned int *d2,
+						      unsigned int *nanosec,
+						      int round_mode)
 {
 	int divider;
 	int div1, div2;
@@ -78,8 +80,10 @@ static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
 }
 
 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)
+						   unsigned int *d1,
+						   unsigned int *d2,
+						   unsigned int *nanosec,
+						   int round_mode)
 {
 	int div1, div2;
 	int base;
@@ -118,8 +122,10 @@ static inline void i8253_cascade_ns_to_timer_power(int i8253_osc_base,
 }
 
 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 *d1,
+						  unsigned int *d2,
+						  unsigned int *nanosec,
+						  int round_mode)
 {
 	unsigned int divider;
 	unsigned int div1, div2;
@@ -136,12 +142,11 @@ static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
 	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) {
+	    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;
 	}
 
@@ -158,10 +163,10 @@ static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
 	if (start < 2)
 		start = 2;
 	for (div1 = start; div1 <= divider / div1 + 1 && div1 <= max_count;
-		div1++) {
+	     div1++) {
 		for (div2 = divider / div1;
-			div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
-			div2++) {
+		     div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
+		     div2++) {
 			ns = i8253_osc_base * div1 * div2;
 			if (ns <= *nanosec && ns > ns_glb) {
 				ns_glb = ns;
@@ -229,7 +234,8 @@ static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
 #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 counter_number, unsigned int count,
+			     unsigned int mode)
 {
 	unsigned int byte;
 
@@ -255,7 +261,8 @@ static inline int i8254_load(unsigned long base_address, unsigned int regshift,
 }
 
 static inline int i8254_mm_load(void *base_address, unsigned int regshift,
-	unsigned int counter_number, unsigned int count, unsigned int mode)
+				unsigned int counter_number, unsigned int count,
+				unsigned int mode)
 {
 	unsigned int byte;
 
@@ -282,7 +289,7 @@ static inline int i8254_mm_load(void *base_address, unsigned int regshift,
 
 /* 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 counter_number)
 {
 	unsigned int byte;
 	int ret;
@@ -303,7 +310,7 @@ static inline int i8254_read(unsigned long base_address, unsigned int regshift,
 }
 
 static inline int i8254_mm_read(void *base_address, unsigned int regshift,
-	unsigned int counter_number)
+				unsigned int counter_number)
 {
 	unsigned int byte;
 	int ret;
@@ -325,7 +332,8 @@ static inline int i8254_mm_read(void *base_address, unsigned int regshift,
 
 /* 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 regshift,
+			       unsigned int counter_number, unsigned int count)
 {
 	unsigned int byte;
 
@@ -339,7 +347,9 @@ static inline void i8254_write(unsigned long base_address,
 }
 
 static inline void i8254_mm_write(void *base_address,
-	unsigned int regshift, unsigned int counter_number, unsigned int count)
+				  unsigned int regshift,
+				  unsigned int counter_number,
+				  unsigned int count)
 {
 	unsigned int byte;
 
@@ -360,7 +370,8 @@ static inline void i8254_mm_write(void *base_address,
  *   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 regshift,
+				 unsigned int counter_number, unsigned int mode)
 {
 	unsigned int byte;
 
@@ -378,7 +389,9 @@ static inline int i8254_set_mode(unsigned long base_address,
 }
 
 static inline int i8254_mm_set_mode(void *base_address,
-	unsigned int regshift, unsigned int counter_number, unsigned int mode)
+				    unsigned int regshift,
+				    unsigned int counter_number,
+				    unsigned int mode)
 {
 	unsigned int byte;
 
@@ -396,18 +409,20 @@ static inline int i8254_mm_set_mode(void *base_address,
 }
 
 static inline int i8254_status(unsigned long base_address,
-	unsigned int regshift, unsigned int counter_number)
+			       unsigned int regshift,
+			       unsigned int counter_number)
 {
 	outb(0xE0 | (2 << counter_number),
-		base_address + (i8254_control_reg << regshift));
+	     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)
+				  unsigned int regshift,
+				  unsigned int counter_number)
 {
 	writeb(0xE0 | (2 << counter_number),
-		base_address + (i8254_control_reg << regshift));
+	       base_address + (i8254_control_reg << regshift));
 	return readb(base_address + (counter_number << regshift));
 }
 
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
index bdc3957..0a50864 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -105,7 +105,8 @@ struct subdev_8255_struct {
 #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_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",
@@ -116,9 +117,10 @@ static struct comedi_driver driver_8255 = {
 
 COMEDI_INITCLEANUP(driver_8255);
 
-static void do_config(struct comedi_device *dev, struct comedi_subdevice * s);
+static void do_config(struct comedi_device *dev, struct comedi_subdevice *s);
 
-void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice * s)
+void subdev_8255_interrupt(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	short d;
 
@@ -143,8 +145,9 @@ static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
 	}
 }
 
-static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice * s,
-	struct comedi_insn *insn, unsigned int *data)
+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];
@@ -152,13 +155,13 @@ static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *
 
 		if (data[0] & 0xff)
 			CALLBACK_FUNC(1, _8255_DATA, s->state & 0xff,
-				CALLBACK_ARG);
+				      CALLBACK_ARG);
 		if (data[0] & 0xff00)
 			CALLBACK_FUNC(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
-				CALLBACK_ARG);
+				      CALLBACK_ARG);
 		if (data[0] & 0xff0000)
 			CALLBACK_FUNC(1, _8255_DATA + 2,
-				(s->state >> 16) & 0xff, CALLBACK_ARG);
+				      (s->state >> 16) & 0xff, CALLBACK_ARG);
 	}
 
 	data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
@@ -168,8 +171,9 @@ static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *
 	return 2;
 }
 
-static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice * s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -205,7 +209,7 @@ static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subd
 	return 1;
 }
 
-static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
+static void do_config(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int config;
 
@@ -222,8 +226,9 @@ static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
 	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)
+static int subdev_8255_cmdtest(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_cmd *cmd)
 {
 	int err = 0;
 	unsigned int tmp;
@@ -297,22 +302,25 @@ static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 	return 0;
 }
 
-static int subdev_8255_cmd(struct comedi_device *dev, struct comedi_subdevice * s)
+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)
+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)
+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;
@@ -340,8 +348,9 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice * s, int
 	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 subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
+			 int (*cb) (int, int, int, unsigned long),
+			 unsigned long arg)
 {
 	int ret;
 
@@ -358,7 +367,7 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice * s,
 	return 0;
 }
 
-void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
+void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	if (s->private) {
 		/* this test does nothing, so comment it out
@@ -376,7 +385,8 @@ void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
 
  */
 
-static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+static int dev_8255_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	int ret;
 	unsigned long iobase;
@@ -410,7 +420,7 @@ static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig *
 			dev->subdevices[i].type = COMEDI_SUBD_UNUSED;
 		} else {
 			subdev_8255_init(dev, dev->subdevices + i, NULL,
-				iobase);
+					 iobase);
 		}
 	}
 
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
index 5457c6b..02c5a36 100644
--- a/drivers/staging/comedi/drivers/8255.h
+++ b/drivers/staging/comedi/drivers/8255.h
@@ -29,16 +29,20 @@
 #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 (*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);
+			 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);
+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)
+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");
 
@@ -48,7 +52,7 @@ static inline int subdev_8255_init(struct comedi_device *dev, struct comedi_subd
 }
 
 static inline void subdev_8255_cleanup(struct comedi_device *dev,
-	struct comedi_subdevice *s)
+				       struct comedi_subdevice *s)
 {
 }
 
diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c
index 5b986aa..c3652ef 100644
--- a/drivers/staging/comedi/drivers/acl7225b.c
+++ b/drivers/staging/comedi/drivers/acl7225b.c
@@ -22,7 +22,8 @@ Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
 #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_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it);
 static int acl7225b_detach(struct comedi_device *dev);
 
 struct boardtype {
@@ -50,8 +51,9 @@ static struct comedi_driver driver_acl7225b = {
 
 COMEDI_INITCLEANUP(driver_acl7225b);
 
-static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice * s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -64,26 +66,28 @@ static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice *
 		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);
+		     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)
+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);
+	    (inb(dev->iobase + (unsigned long)s->private + 1) << 8);
 
 	return 2;
 }
 
-static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+static int acl7225b_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int iobase, iorange;
@@ -91,7 +95,7 @@ static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig *
 	iobase = it->options[0];
 	iorange = this_board->io_range;
 	printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor,
-		this_board->name, iobase);
+	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "acl7225b")) {
 		printk("I/O port conflict\n");
 		return -EIO;
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
index d288289..f96b128 100644
--- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
@@ -261,6 +261,9 @@ void v_pci_card_list_init(unsigned short pci_vendor, char display)
 			pci_vendor = i_ADDIDATADeviceID[i_Count];
 			if (pcidev->vendor == pci_vendor) {
 				amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+				if (amcc == NULL)
+					continue;
+
 				memset(amcc, 0, sizeof(*amcc));
 
 				amcc->pcidev = pcidev;
diff --git a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
index b76f877..49141b3 100644
--- a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
+++ b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
@@ -254,6 +254,9 @@ void v_pci_card_list_init(unsigned short pci_vendor, char display)
 	pci_for_each_dev(pcidev) {
 		if (pcidev->vendor == pci_vendor) {
 			amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+			if (amcc == NULL)
+				continue;
+
 			memset(amcc, 0, sizeof(*amcc));
 
 			amcc->pcidev = pcidev;
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index 9b53255..010697f 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -2669,7 +2669,7 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
 			err++;
 			printk("\nThe Delay time base selection is in error\n");
 		}
-		if (ui_DelayTime < 1 && ui_DelayTime > 1023) {
+		if (ui_DelayTime < 1 || ui_DelayTime > 1023) {
 			err++;
 			printk("\nThe Delay time value is in error\n");
 		}
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
index b4807fc..8e1befc 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -66,23 +66,23 @@ struct pci6208_board {
 
 static const struct pci6208_board pci6208_boards[] = {
 	/*{
-	.name = "pci6208v",
-	.dev_id = 0x6208,      // not sure
-	.ao_chans = 8
-	   // ,	.ao_bits = 16
+	   .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 = "pci6216v",
+	   .dev_id = 0x6208,      // not sure
+	   .ao_chans = 16
+	   // , .ao_bits = 16
 	   }, */
 	{
-	.name = "pci6208a",
-	.dev_id = 0x6208,
-	.ao_chans = 8
-			/* ,	.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
@@ -90,8 +90,9 @@ static const struct pci6208_board pci6208_boards[] = {
 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}
+	{
+	PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	0}
 };
 
 MODULE_DEVICE_TABLE(pci, pci6208_pci_table);
@@ -107,7 +108,8 @@ struct pci6208_private {
 
 #define devpriv ((struct pci6208_private *)dev->private)
 
-static int pci6208_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int pci6208_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it);
 static int pci6208_detach(struct comedi_device *dev);
 
 static struct comedi_driver driver_pci6208 = {
@@ -122,13 +124,15 @@ 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);
+		  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_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, */
@@ -140,7 +144,8 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
  * in the driver structure, dev->board_ptr contains that
  * address.
  */
-static int pci6208_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pci6208_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int retval;
@@ -217,8 +222,9 @@ static int pci6208_detach(struct comedi_device *dev)
 	return 0;
 }
 
-static int pci6208_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -242,8 +248,9 @@ static int pci6208_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
 
 /* 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)
+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);
@@ -309,8 +316,8 @@ static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
 	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)) {
+	     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 < ARRAY_SIZE(pci6208_boards); i++) {
 				if (pci6208_boards[i].dev_id == pci_dev->device) {
@@ -318,9 +325,9 @@ static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
 					if ((bus != 0) || (slot != 0)) {
 						/*  are we on the wrong bus/slot? */
 						if (pci_dev->bus->number
-							!= bus ||
-							PCI_SLOT(pci_dev->devfn)
-							!= slot) {
+						    != bus ||
+						    PCI_SLOT(pci_dev->devfn)
+						    != slot) {
 							continue;
 						}
 					}
@@ -332,16 +339,16 @@ static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
 	}
 
 	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
-		dev->minor, bus, slot);
+	       dev->minor, bus, slot);
 	return -EIO;
 
-      found:
+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);
+	       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) */
@@ -355,13 +362,15 @@ 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)
+		  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);
+		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]. */
@@ -369,14 +378,14 @@ pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
 	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);
+	       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);
+	       dev_minor, io_base, io_range);
 
 	*io_base_ptr = io_base;
 	/* devpriv->io_range = io_range; */
diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c
index d2f23a8..4de6fad 100644
--- a/drivers/staging/comedi/drivers/adl_pci7296.c
+++ b/drivers/staging/comedi/drivers/adl_pci7296.c
@@ -49,9 +49,10 @@ Configuration Options:
 #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}
+	{
+	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);
@@ -61,10 +62,10 @@ struct adl_pci7296_private {
 	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_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",
@@ -73,7 +74,8 @@ static struct comedi_driver driver_adl_pci7296 = {
 	.detach = adl_pci7296_detach,
 };
 
-static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int adl_pci7296_attach(struct comedi_device *dev,
+			      struct comedi_devconfig *it)
 {
 	struct pci_dev *pcidev;
 	struct comedi_subdevice *s;
@@ -94,21 +96,23 @@ static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig
 		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)) {
+	     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) {
+		    pcidev->device == PCI_DEVICE_ID_PCI7296) {
 			if (bus || slot) {
 				/* requested particular bus/slot */
 				if (pcidev->bus->number != bus
-					|| PCI_SLOT(pcidev->devfn) != slot) {
+				    || 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);
+				printk
+				    ("comedi%d: Failed to enable PCI device and request regions\n",
+				     dev->minor);
 				return -EIO;
 			}
 
@@ -118,23 +122,26 @@ static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig
 			/*  four 8255 digital io subdevices */
 			s = dev->subdevices + 0;
 			subdev_8255_init(dev, s, NULL,
-				(unsigned long)(dev->iobase));
+					 (unsigned long)(dev->iobase));
 
 			s = dev->subdevices + 1;
 			ret = subdev_8255_init(dev, s, NULL,
-				(unsigned long)(dev->iobase + PORT2A));
+					       (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));
+					       (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));
+					       (unsigned long)(dev->iobase +
+							       PORT4A));
 			if (ret < 0)
 				return ret;
 
@@ -145,7 +152,7 @@ static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig
 	}
 
 	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
-		dev->minor, bus, slot);
+	       dev->minor, bus, slot);
 	return -EIO;
 }
 
diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c
index 78becbd..e0844c6 100644
--- a/drivers/staging/comedi/drivers/adl_pci7432.c
+++ b/drivers/staging/comedi/drivers/adl_pci7432.c
@@ -44,9 +44,10 @@ Configuration Options:
 #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}
+	{
+	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);
@@ -58,7 +59,8 @@ struct adl_pci7432_private {
 
 #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_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",
@@ -69,15 +71,20 @@ static struct comedi_driver driver_adl_pci7432 = {
 
 /* 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_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_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)
+static int adl_pci7432_attach(struct comedi_device *dev,
+			      struct comedi_devconfig *it)
 {
 	struct pci_dev *pcidev;
 	struct comedi_subdevice *s;
@@ -97,21 +104,23 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
 		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)) {
+	     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) {
+		    pcidev->device == PCI_DEVICE_ID_PCI7432) {
 			if (bus || slot) {
 				/* requested particular bus/slot */
 				if (pcidev->bus->number != bus
-					|| PCI_SLOT(pcidev->devfn) != slot) {
+				    || 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);
+				printk
+				    ("comedi%d: Failed to enable PCI device and request regions\n",
+				     dev->minor);
 				return -EIO;
 			}
 			dev->iobase = pci_resource_start(pcidev, 2);
@@ -120,7 +129,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
 			s = dev->subdevices + 0;
 			s->type = COMEDI_SUBD_DI;
 			s->subdev_flags =
-				SDF_READABLE | SDF_GROUND | SDF_COMMON;
+			    SDF_READABLE | SDF_GROUND | SDF_COMMON;
 			s->n_chan = 32;
 			s->maxdata = 1;
 			s->len_chanlist = 32;
@@ -131,7 +140,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
 			s = dev->subdevices + 1;
 			s->type = COMEDI_SUBD_DO;
 			s->subdev_flags =
-				SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+			    SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
 			s->n_chan = 32;
 			s->maxdata = 1;
 			s->len_chanlist = 32;
@@ -146,7 +155,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
 	}
 
 	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
-		dev->minor, bus, slot);
+	       dev->minor, bus, slot);
 	return -EIO;
 }
 
@@ -164,8 +173,10 @@ static int adl_pci7432_detach(struct comedi_device *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)
+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]);
@@ -178,14 +189,16 @@ static int adl_pci7432_do_insn_bits(struct comedi_device *dev, struct comedi_sub
 		s->state |= (data[0] & data[1]);
 
 		printk("comedi: out: %8x on iobase %4lx\n", s->state,
-			dev->iobase + PCI7432_DO);
+		       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)
+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]);
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
index 2d7d68a..43745ec 100644
--- a/drivers/staging/comedi/drivers/adl_pci8164.c
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -56,9 +56,10 @@ Configuration Options:
 #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}
+	{
+	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);
@@ -70,7 +71,8 @@ struct adl_pci8164_private {
 
 #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_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",
@@ -79,31 +81,48 @@ static struct comedi_driver driver_adl_pci8164 = {
 	.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_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_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_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_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_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_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);
+				       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);
+				       struct comedi_subdevice *s,
+				       struct comedi_insn *insn,
+				       unsigned int *data);
 
-static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int adl_pci8164_attach(struct comedi_device *dev,
+			      struct comedi_devconfig *it)
 {
 	struct pci_dev *pcidev;
 	struct comedi_subdevice *s;
@@ -123,21 +142,23 @@ static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig
 		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)) {
+	     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) {
+		    pcidev->device == PCI_DEVICE_ID_PCI8164) {
 			if (bus || slot) {
 				/* requested particular bus/slot */
 				if (pcidev->bus->number != bus
-					|| PCI_SLOT(pcidev->devfn) != slot) {
+				    || 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);
+				printk
+				    ("comedi%d: Failed to enable PCI device and request regions\n",
+				     dev->minor);
 				return -EIO;
 			}
 			dev->iobase = pci_resource_start(pcidev, 2);
@@ -190,7 +211,7 @@ static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig
 	}
 
 	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
-		dev->minor, bus, slot);
+	       dev->minor, bus, slot);
 	return -EIO;
 }
 
@@ -216,8 +237,7 @@ static void adl_pci8164_insn_read(struct comedi_device *dev,
 				  struct comedi_subdevice *s,
 				  struct comedi_insn *insn,
 				  unsigned int *data,
-				  char *action,
-				  unsigned short offset)
+				  char *action, unsigned short offset)
 {
 	int axis, axis_reg;
 	char *axisname;
@@ -247,8 +267,8 @@ static void adl_pci8164_insn_read(struct comedi_device *dev,
 	}
 
 	data[0] = inw(dev->iobase + axis_reg + offset);
-	printk("comedi: pci8164 %s read -> %04X:%04X on axis %s\n", action, data[0],
-		data[1], axisname);
+	printk("comedi: pci8164 %s read -> %04X:%04X on axis %s\n", action,
+	       data[0], data[1], axisname);
 }
 
 static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
@@ -260,22 +280,28 @@ static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
 	return 2;
 }
 
-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_ssts(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      struct comedi_insn *insn,
+				      unsigned int *data)
 {
 	adl_pci8164_insn_read(dev, s, insn, data, "SSTS", PCI8164_SSTS);
 	return 2;
 }
 
-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_buf0(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      struct comedi_insn *insn,
+				      unsigned int *data)
 {
 	adl_pci8164_insn_read(dev, s, insn, data, "BUF0", PCI8164_BUF0);
 	return 2;
 }
 
-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_read_buf1(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      struct comedi_insn *insn,
+				      unsigned int *data)
 {
 	adl_pci8164_insn_read(dev, s, insn, data, "BUF1", PCI8164_BUF1);
 	return 2;
@@ -286,11 +312,10 @@ static int adl_pci8164_insn_read_buf1(struct comedi_device *dev, struct comedi_s
  * const to the data for outw()
  */
 static void adl_pci8164_insn_out(struct comedi_device *dev,
-					struct comedi_subdevice *s,
-					struct comedi_insn *insn,
-					unsigned int *data,
-					char *action,
-					unsigned short offset)
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data,
+				 char *action, unsigned short offset)
 {
 	unsigned int axis, axis_reg;
 
@@ -327,30 +352,37 @@ static void adl_pci8164_insn_out(struct comedi_device *dev,
 
 }
 
-
-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_cmd(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      struct comedi_insn *insn,
+				      unsigned int *data)
 {
 	adl_pci8164_insn_out(dev, s, insn, data, "CMD", PCI8164_CMD);
 	return 2;
 }
 
-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_otp(struct comedi_device *dev,
+				      struct comedi_subdevice *s,
+				      struct comedi_insn *insn,
+				      unsigned int *data)
 {
 	adl_pci8164_insn_out(dev, s, insn, data, "OTP", PCI8164_OTP);
 	return 2;
 }
 
 static int adl_pci8164_insn_write_buf0(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				       struct comedi_subdevice *s,
+				       struct comedi_insn *insn,
+				       unsigned int *data)
 {
 	adl_pci8164_insn_out(dev, s, insn, data, "BUF0", PCI8164_BUF0);
 	return 2;
 }
 
 static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				       struct comedi_subdevice *s,
+				       struct comedi_insn *insn,
+				       unsigned int *data)
 {
 	adl_pci8164_insn_out(dev, s, insn, data, "BUF1", PCI8164_BUF1);
 	return 2;
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
index 0ac722e..da172a5 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -264,27 +264,32 @@ TODO:
 
 /*  Function prototypes */
 
-static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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 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)
-		}
+	 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}
+	{
+	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);
@@ -309,17 +314,17 @@ struct pci9111_board {
 
 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}
+	 .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 \
@@ -379,9 +384,11 @@ struct pci9111_private_data {
 #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)
+				      bool LINTi1_enable,
+				      bool LINTi1_active_high,
+				      bool LINTi2_enable,
+				      bool LINTi2_active_high,
+				      bool interrupt_enable)
 {
 	int flags = 0;
 
@@ -409,16 +416,19 @@ static void plx9050_interrupt_control(unsigned long io_base,
 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_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_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);
+				 PCI9111_8254_READ_LOAD_LSB_MSB |
+				 PCI9111_8254_MODE_2 |
+				 PCI9111_8254_BINARY_COUNTER);
 
 	udelay(1);
 
@@ -433,7 +443,7 @@ enum pci9111_trigger_sources {
 };
 
 static void pci9111_trigger_source_set(struct comedi_device *dev,
-	enum pci9111_trigger_sources source)
+				       enum pci9111_trigger_sources source)
 {
 	int flags;
 
@@ -491,7 +501,8 @@ enum pci9111_ISC1_sources {
 };
 
 static void pci9111_interrupt_source_set(struct comedi_device *dev,
-	enum pci9111_ISC0_sources irq_0_source, enum pci9111_ISC1_sources irq_1_source)
+					 enum pci9111_ISC0_sources irq_0_source,
+					 enum pci9111_ISC1_sources irq_1_source)
 {
 	int flags;
 
@@ -514,12 +525,13 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev,
 
 #undef AI_DO_CMD_DEBUG
 
-static int pci9111_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+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);
+				  true, false);
 
 	pci9111_trigger_source_set(dev, software);
 
@@ -543,19 +555,19 @@ static int pci9111_ai_cancel(struct comedi_device *dev, struct comedi_subdevice
 
 static int
 pci9111_ai_do_cmd_test(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd)
+		       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;
+	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);
+				  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);
@@ -569,21 +581,21 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 		error++;
 
 	if ((cmd->scan_begin_src != TRIG_TIMER) &&
-		(cmd->scan_begin_src != TRIG_FOLLOW) &&
-		(cmd->scan_begin_src != TRIG_EXT))
+	    (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))) {
+	    !((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))) {
+	    !((cmd->scan_begin_src == TRIG_EXT) ||
+	      (cmd->scan_begin_src == TRIG_FOLLOW))) {
 		error++;
 	}
 
@@ -613,7 +625,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 	}
 
 	if ((cmd->convert_src == TRIG_TIMER) &&
-		(cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
+	    (cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
 		cmd->convert_arg = board->ai_acquisition_period_min_ns;
 		error++;
 	}
@@ -623,7 +635,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 	}
 
 	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)) {
 		cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
 		error++;
 	}
@@ -637,7 +649,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 	}
 
 	if ((cmd->scan_end_src == TRIG_COUNT) &&
-		(cmd->scan_end_arg != cmd->chanlist_len)) {
+	    (cmd->scan_end_arg != cmd->chanlist_len)) {
 		cmd->scan_end_arg = cmd->chanlist_len;
 		error++;
 	}
@@ -659,9 +671,10 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 	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);
+					       &(dev_private->timer_divisor_1),
+					       &(dev_private->timer_divisor_2),
+					       &(cmd->convert_arg),
+					       cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->convert_arg)
 			error++;
 	}
@@ -679,7 +692,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 		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;
+				    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;
@@ -706,27 +719,27 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 			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");
+						     "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");
+						     "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");
+						     "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)) {
+			     (board->ai_channel_nbr - 1))
+			    || (CR_CHAN(cmd->chanlist[0]) < 0)) {
 				comedi_error(dev,
-					"channel number is out of limits\n");
+					     "channel number is out of limits\n");
 				error++;
 			}
 		}
@@ -741,13 +754,14 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
 
 /*  Analog input command */
 
-static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subdevice)
+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");
+			     "no irq assigned for PCI9111, cannot do hardware conversion");
 		return -1;
 	}
 	/*  Set channel scan limit */
@@ -772,7 +786,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
 	switch (async_cmd->stop_src) {
 	case TRIG_COUNT:
 		dev_private->stop_counter =
-			async_cmd->stop_arg * async_cmd->chanlist_len;
+		    async_cmd->stop_arg * async_cmd->chanlist_len;
 		dev_private->stop_is_none = 0;
 		break;
 
@@ -792,28 +806,29 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
 	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);
+					       &(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);
+		       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);
+					     irq_on_timer_tick);
 		pci9111_trigger_source_set(dev, timer_pacer);
 		plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
-			false, true, true);
+					  false, true, true);
 
 		dev_private->scan_delay =
-			(async_cmd->scan_begin_arg / (async_cmd->convert_arg *
-				async_cmd->chanlist_len)) - 1;
+		    (async_cmd->scan_begin_arg / (async_cmd->convert_arg *
+						  async_cmd->chanlist_len)) - 1;
 
 		break;
 
@@ -822,9 +837,9 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
 		pci9111_trigger_source_set(dev, external);
 		pci9111_fifo_reset();
 		pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
-			irq_on_timer_tick);
+					     irq_on_timer_tick);
 		plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
-			false, true, true);
+					  false, true, true);
 
 		break;
 
@@ -837,45 +852,47 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
 	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);
+	    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());
+	       pci9111_trigger_and_autoscan_get());
 	printk(PCI9111_DRIVER_NAME ": irq source     = %2x\n",
-		pci9111_interrupt_and_fifo_get());
+	       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);
+	       dev_private->stop_counter);
 	printk(PCI9111_DRIVER_NAME ": scan delay     = %d\n",
-		dev_private->scan_delay);
+	       dev_private->scan_delay);
 	printk(PCI9111_DRIVER_NAME ": chanlist_len   = %d\n",
-		dev_private->chanlist_len);
+	       dev_private->chanlist_len);
 	printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n",
-		dev_private->chunk_num_samples);
+	       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)
+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;
+	    ((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;
+			    (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;
+			    ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
+			    PCI9111_AI_RESOLUTION_2_CMP_BIT;
 	}
 }
 
@@ -905,18 +922,12 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
 
 	/*  Check if we are source of interrupt */
 	intcsr = inb(dev_private->lcr_io_base +
-		PLX9050_REGISTER_INTERRUPT_CONTROL);
+		     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))))) {
+	      && (((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) */
 		spin_unlock_irqrestore(&dev->spinlock, irq_flags);
@@ -924,12 +935,11 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
 	}
 
 	if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
-		(PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
+	    (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
 		/*  Interrupt comes from fifo_half-full signal */
 
 		if (pci9111_is_fifo_full()) {
-			spin_unlock_irqrestore(&dev->spinlock,
-				irq_flags);
+			spin_unlock_irqrestore(&dev->spinlock, irq_flags);
 			comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
 			pci9111_interrupt_clear();
 			pci9111_ai_cancel(dev, subdevice);
@@ -948,73 +958,70 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
 #endif
 
 			num_samples =
-				PCI9111_FIFO_HALF_SIZE >
-				dev_private->stop_counter
-				&& !dev_private->stop_is_none ? dev_private->
-				stop_counter : PCI9111_FIFO_HALF_SIZE;
+			    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);
+			     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));
+				    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) {
+					    dev_private->chanlist_len) {
 						to_read =
-							dev_private->
-							chanlist_len -
-							dev_private->
-							chunk_counter;
+						    dev_private->chanlist_len -
+						    dev_private->chunk_counter;
 
 						if (to_read >
-							num_samples - position)
+						    num_samples - position)
 							to_read =
-								num_samples -
-								position;
+							    num_samples -
+							    position;
 
 						bytes_written +=
-							cfc_write_array_to_buffer
-							(subdevice,
-							dev_private->
-							ai_bounce_buffer +
-							position,
-							to_read *
-							sizeof(short));
+						    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;
+						    dev_private->chunk_num_samples
+						    -
+						    dev_private->chunk_counter;
 						if (to_read >
-							num_samples - position)
+						    num_samples - position)
 							to_read =
-								num_samples -
-								position;
+							    num_samples -
+							    position;
 
 						bytes_written +=
-							sizeof(short) *
-							to_read;
+						    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_num_samples)
 						dev_private->chunk_counter = 0;
 				}
 			}
 
 			dev_private->stop_counter -=
-				bytes_written / sizeof(short);
+			    bytes_written / sizeof(short);
 		}
 	}
 
@@ -1044,17 +1051,18 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
 #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)
+				struct comedi_subdevice *subdevice,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int resolution =
-		((struct pci9111_board *) dev->board_ptr)->ai_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);
+	       CR_CHAN((&insn->chanspec)[0]),
+	       CR_RANGE((&insn->chanspec)[0]), insn->n);
 #endif
 
 	pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));
@@ -1080,7 +1088,7 @@ static int pci9111_ai_insn_read(struct comedi_device *dev,
 		pci9111_fifo_reset();
 		return -ETIME;
 
-	      conversion_done:
+conversion_done:
 
 		if (resolution == PCI9111_HR_AI_RESOLUTION) {
 			data[i] = pci9111_hr_ai_get_data();
@@ -1091,8 +1099,8 @@ static int pci9111_ai_insn_read(struct comedi_device *dev,
 
 #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());
+	       pci9111_ai_channel_get(),
+	       pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
 #endif
 
 	return i;
@@ -1102,7 +1110,8 @@ static int pci9111_ai_insn_read(struct comedi_device *dev,
 
 static int
 pci9111_ao_insn_write(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+		      struct comedi_subdevice *s, struct comedi_insn *insn,
+		      unsigned int *data)
 {
 	int i;
 
@@ -1117,7 +1126,8 @@ pci9111_ao_insn_write(struct comedi_device *dev,
 /*  Analog output readback */
 
 static int pci9111_ao_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 
@@ -1135,7 +1145,8 @@ static int pci9111_ao_insn_read(struct comedi_device *dev,
 /*  Digital inputs */
 
 static int pci9111_di_insn_bits(struct comedi_device *dev,
-	struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
+				struct comedi_subdevice *subdevice,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int bits;
 
@@ -1148,7 +1159,8 @@ static int pci9111_di_insn_bits(struct comedi_device *dev,
 /*  Digital outputs */
 
 static int pci9111_do_insn_bits(struct comedi_device *dev,
-	struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
+				struct comedi_subdevice *subdevice,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int bits;
 
@@ -1181,7 +1193,7 @@ 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);
+				  true, false);
 
 	pci9111_trigger_source_set(dev, software);
 	pci9111_pretrigger_set(dev, false);
@@ -1201,7 +1213,8 @@ static int pci9111_reset(struct comedi_device *dev)
 /*       - Register PCI device */
 /*       - Declare device driver capability */
 
-static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+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;
@@ -1217,29 +1230,29 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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)) {
+	     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) {
+				    pci_device->device) {
 					/*  was a particular bus/slot requested? */
 					if ((it->options[0] != 0)
-						|| (it->options[1] != 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]) {
+						    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;
+					board =
+					    (struct pci9111_board *)
+					    dev->board_ptr;
 					dev_private->pci_device = pci_device;
 					goto found;
 				}
@@ -1248,17 +1261,17 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	}
 
 	printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
-		dev->minor, it->options[0], it->options[1]);
+	       dev->minor, it->options[0], it->options[1]);
 	return -EIO;
 
-      found:
+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);
+	       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. */
 
@@ -1270,11 +1283,15 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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);
+	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);
+		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]. */
@@ -1283,7 +1300,7 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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->minor, io_base, io_range);
 
 	dev->iobase = io_base;
 	dev->board_name = board->name;
@@ -1301,7 +1318,7 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		if (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);
+			       dev->minor, pci_device->irq);
 			return -EINVAL;
 		}
 	}
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 65f522b..1ee4b6a 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -154,32 +154,33 @@ Configuration options:
 #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)
-	}
+							     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)
-	}
+							  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_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it);
 static int pci9118_detach(struct comedi_device *dev);
 
 struct boardtype {
@@ -204,28 +205,29 @@ struct boardtype {
 };
 
 static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
-	{PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0}
+	{
+	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},
+	 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},
+	 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},
+	 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))
@@ -309,27 +311,34 @@ struct pci9118_private {
 ==============================================================================
 */
 
-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 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 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);
+				  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)
+static int pci9118_insn_read_ai(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 
 	int n, timeout;
@@ -358,15 +367,14 @@ static int pci9118_insn_read_ai(struct comedi_device *dev, struct comedi_subdevi
 		outl(0, dev->iobase + PCI9118_DELFIFO);	/*  flush FIFO */
 		return -ETIME;
 
-	      conv_finish:
+conv_finish:
 		if (devpriv->ai16bits) {
 			data[n] =
-				(inl(dev->iobase +
-					PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
+			    (inl(dev->iobase +
+				 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
 		} else {
 			data[n] =
-				(inw(dev->iobase +
-					PCI9118_AD_DATA) >> 4) & 0xfff;
+			    (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
 		}
 	}
 
@@ -378,8 +386,9 @@ static int pci9118_insn_read_ai(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci9118_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
 
@@ -401,8 +410,9 @@ static int pci9118_insn_write_ao(struct comedi_device *dev, struct comedi_subdev
 /*
 ==============================================================================
 */
-static int pci9118_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int pci9118_insn_read_ao(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int n, chan;
 
@@ -416,8 +426,9 @@ static int pci9118_insn_read_ao(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci9118_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
 
@@ -427,8 +438,9 @@ static int pci9118_insn_bits_di(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci9118_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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];
@@ -446,29 +458,31 @@ static int pci9118_insn_bits_do(struct comedi_device *dev, struct comedi_subdevi
 static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
 {
 	devpriv->AdFunctionReg =
-		AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+	    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);
+	     dev->iobase + PCI9118_CNT0);
 	outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
-		dev->iobase + PCI9118_CNT0);
+	     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)
+					  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;
+	    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;
+	    devpriv->ai_add_back;
 
 	for (i = 0; i < num_samples; i++) {
 		if (devpriv->ai_act_dmapos >= start_pos &&
-			devpriv->ai_act_dmapos < stop_pos) {
+		    devpriv->ai_act_dmapos < stop_pos) {
 			dma_buffer[j++] = dma_buffer[i];
 		}
 		devpriv->ai_act_dmapos++;
@@ -482,18 +496,20 @@ static unsigned int defragment_dma_buffer(struct comedi_device *dev,
 ==============================================================================
 */
 static unsigned int move_block_from_dma(struct comedi_device *dev,
-	struct comedi_subdevice *s, short *dma_buffer, unsigned int num_samples)
+					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) / 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));
+	    cfc_write_array_to_buffer(s, dma_buffer,
+				      num_samples * sizeof(short));
 	if (num_bytes < num_samples * sizeof(short))
 		return -1;
 	return 0;
@@ -503,7 +519,8 @@ static unsigned int move_block_from_dma(struct comedi_device *dev,
 ==============================================================================
 */
 static char pci9118_decode_error_status(struct comedi_device *dev,
-	struct comedi_subdevice *s, unsigned char m)
+					struct comedi_subdevice *s,
+					unsigned char m)
 {
 	if (m & 0x100) {
 		comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
@@ -511,7 +528,7 @@ static char pci9118_decode_error_status(struct comedi_device *dev,
 	}
 	if (m & 0x008) {
 		comedi_error(dev,
-			"A/D Burst Mode Overrun Status (Fatal Error!)");
+			     "A/D Burst Mode Overrun Status (Fatal Error!)");
 		devpriv->ai_maskerr &= ~0x008L;
 	}
 	if (m & 0x004) {
@@ -532,8 +549,10 @@ static char pci9118_decode_error_status(struct comedi_device *dev,
 	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)
+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;
@@ -553,8 +572,10 @@ static void pci9118_ai_munge(struct comedi_device *dev, struct comedi_subdevice
 ==============================================================================
 */
 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)
+					   struct comedi_subdevice *s,
+					   unsigned short int_adstat,
+					   unsigned int int_amcc,
+					   unsigned short int_daq)
 {
 	register short sampl;
 
@@ -570,9 +591,9 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
 	if (devpriv->ai16bits == 0) {
 		if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {	/*  data dropout! */
 			printk
-				("comedi: A/D  SAMPL - data dropout: received channel %d, expected %d!\n",
-				sampl & 0x000f,
-				devpriv->chanlist[s->async->cur_chan]);
+			    ("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);
@@ -599,9 +620,11 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
 /*
 ==============================================================================
 */
-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)
+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;
 
@@ -632,11 +655,11 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, struct comedi_su
 	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);
+		     devpriv->iobase_a + AMCC_OP_REG_MWAR);
 		outl(devpriv->dmabuf_use_size[next_dma_buf],
-			devpriv->iobase_a + AMCC_OP_REG_MWTC);
+		     devpriv->iobase_a + AMCC_OP_REG_MWTC);
 		devpriv->dmabuf_used_size[next_dma_buf] =
-			devpriv->dmabuf_use_size[next_dma_buf];
+		    devpriv->dmabuf_use_size[next_dma_buf];
 		if (devpriv->ai_do == 4)
 			interrupt_pci9118_ai_mode4_switch(dev);
 	}
@@ -646,8 +669,8 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, struct comedi_su
 /* 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);
+				    devpriv->dmabuf_virt[devpriv->dma_actbuf],
+				    samplesinbuf);
 		m = m - sampls;	/*  m= how many samples was transfered */
 	}
 /* DPRINTK("YYY\n"); */
@@ -662,9 +685,9 @@ static void interrupt_pci9118_ai_dma(struct comedi_device *dev, struct comedi_su
 		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);
+		     devpriv->iobase_a + AMCC_OP_REG_MWAR);
 		outl(devpriv->dmabuf_use_size[0],
-			devpriv->iobase_a + AMCC_OP_REG_MWTC);
+		     devpriv->iobase_a + AMCC_OP_REG_MWTC);
 		if (devpriv->ai_do == 4)
 			interrupt_pci9118_ai_mode4_switch(dev);
 	}
@@ -700,18 +723,18 @@ static irqreturn_t interrupt_pci9118(int irq, void *d)
 			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;
+					    ~START_AI_EXT;
 					if (!(devpriv->ai12_startstop &
-							STOP_AI_EXT))
+					      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);
+					     dev->iobase + PCI9118_ADCNTRL);
 				} else {
-					if (devpriv->
-						ai12_startstop & STOP_AI_EXT) {
+					if (devpriv->ai12_startstop &
+					    STOP_AI_EXT) {
 						devpriv->ai12_startstop &=
-							~STOP_AI_EXT;
+						    ~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 */
 					}
@@ -719,7 +742,7 @@ static irqreturn_t interrupt_pci9118(int irq, void *d)
 			}
 
 		(devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
-			int_amcc, int_daq);
+					int_amcc, int_daq);
 
 	}
 	return IRQ_HANDLED;
@@ -728,8 +751,8 @@ static irqreturn_t interrupt_pci9118(int irq, void *d)
 /*
 ==============================================================================
 */
-static int pci9118_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+static int pci9118_ai_inttrig(struct comedi_device *dev,
+			      struct comedi_subdevice *s, unsigned int trignum)
 {
 	if (trignum != devpriv->ai_inttrig_start)
 		return -EINVAL;
@@ -741,7 +764,7 @@ static int pci9118_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice
 	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->ai_divisor2);
 		devpriv->AdControlReg |= AdControl_SoftG;
 	}
 	outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
@@ -752,8 +775,9 @@ static int pci9118_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice
 /*
 ==============================================================================
 */
-static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int pci9118_ai_cmdtest(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp, divisor1, divisor2;
@@ -799,21 +823,21 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	/* 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_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_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_EXT && cmd->convert_src != TRIG_NOW) {
 		cmd->convert_src = TRIG_TIMER;
 		err++;
 	}
@@ -824,8 +848,8 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	}
 
 	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 &&
+	    cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
 		cmd->stop_src = TRIG_COUNT;
 		err++;
 	}
@@ -841,13 +865,13 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	}
 
 	if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
-		(!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
+	    (!(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 | TRIG_EXT)))) {
 		cmd->convert_src = TRIG_TIMER;
 		err++;
 	}
@@ -875,7 +899,7 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 		}
 
 	if ((cmd->scan_begin_src == TRIG_TIMER) &&
-		(cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
+	    (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;
@@ -938,8 +962,7 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 	if ((cmd->scan_end_arg % cmd->chanlist_len)) {
 		cmd->scan_end_arg =
-			cmd->chanlist_len * (cmd->scan_end_arg /
-			cmd->chanlist_len);
+		    cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
 		err++;
 	}
 
@@ -952,8 +975,8 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 		tmp = cmd->scan_begin_arg;
 /* 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);
+					  &divisor2, &cmd->scan_begin_arg,
+					  cmd->flags & TRIG_ROUND_MASK);
 /* 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;
@@ -964,31 +987,31 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	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);
+					  &divisor2, &cmd->convert_arg,
+					  cmd->flags & TRIG_ROUND_MASK);
 /* 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) {
+		    && 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)) {
+				    this_board->ai_ns_min *
+				    (cmd->scan_end_arg + 2)) {
 					cmd->scan_begin_arg =
-						this_board->ai_ns_min *
-						(cmd->scan_end_arg + 2);
+					    this_board->ai_ns_min *
+					    (cmd->scan_end_arg + 2);
 /* 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->convert_arg * cmd->chanlist_len) {
 					cmd->scan_begin_arg =
-						cmd->convert_arg *
-						cmd->chanlist_len;
+					    cmd->convert_arg *
+					    cmd->chanlist_len;
 /* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */
 					err++;
 				}
@@ -1001,7 +1024,7 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 	if (cmd->chanlist)
 		if (!check_channel_list(dev, s, cmd->chanlist_len,
-				cmd->chanlist, 0, 0))
+					cmd->chanlist, 0, 0))
 			return 5;	/*  incorrect channels list */
 
 	return 0;
@@ -1034,19 +1057,22 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
 			/*  uff, too short DMA buffer, disable EOS support! */
 			devpriv->ai_flags &= (~TRIG_WAKE_EOS);
 			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);
+			    ("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);
+			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) {
 				printk
-					("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
-					dev->minor, dmalen0);
+				    ("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
+				     dev->minor, dmalen0);
 				dmalen0 = 4;
 			}
 		}
@@ -1056,19 +1082,22 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
 			/*  uff, too short DMA buffer, disable EOS support! */
 			devpriv->ai_flags &= (~TRIG_WAKE_EOS);
 			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);
+			    ("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);
+			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) {
 				printk
-					("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
-					dev->minor, dmalen1);
+				    ("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
+				     dev->minor, dmalen1);
 				dmalen1 = 4;
 			}
 		}
@@ -1080,15 +1109,15 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
 		/*  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 / (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 / (devpriv->ai_n_realscanlen << 1)) *
+		    (devpriv->ai_n_realscanlen << 1);
 		dmalen1 &= ~3L;
 		if (!dmalen1)
 			dmalen1 = i;	/*  uff. very long scan? */
@@ -1096,23 +1125,25 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
 		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);
+			    ((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;
+				    (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))
+				    ((devpriv->ai_n_realscanlen << 1) *
+				     devpriv->ai_scans - dmalen0))
 					dmalen1 =
-						(devpriv->
-						ai_n_realscanlen << 1) *
-						devpriv->ai_scans - dmalen0;
+					    (devpriv->ai_n_realscanlen << 1) *
+					    devpriv->ai_scans - dmalen0;
 				DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
 					dmalen1);
 				dmalen1 &= ~3L;
@@ -1131,16 +1162,16 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
 #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);
+		    (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);
+		    (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->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
 		devpriv->dmabuf_panic_size[1] =
-			(devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
+		    (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
 	}
 #endif
 
@@ -1149,12 +1180,12 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
 	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);
+	     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);
+		 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");
@@ -1164,7 +1195,8 @@ static int Compute_and_setup_dma(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-static int pci9118_ai_docmd_sampl(struct comedi_device *dev, struct comedi_subdevice *s)
+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);
@@ -1183,7 +1215,7 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, struct comedi_subde
 		return -EIO;
 	default:
 		comedi_error(dev,
-			"pci9118_ai_docmd_sampl() mode number bug!\n");
+			     "pci9118_ai_docmd_sampl() mode number bug!\n");
 		return -EIO;
 	};
 
@@ -1204,7 +1236,7 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, struct comedi_subde
 		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->ai_divisor2);
 			devpriv->AdControlReg |= AdControl_SoftG;
 		}
 		outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
@@ -1217,7 +1249,8 @@ static int pci9118_ai_docmd_sampl(struct comedi_device *dev, struct comedi_subde
 /*
 ==============================================================================
 */
-static int pci9118_ai_docmd_dma(struct comedi_device *dev, struct comedi_subdevice *s)
+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);
@@ -1226,34 +1259,34 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev, struct comedi_subdevi
 	switch (devpriv->ai_do) {
 	case 1:
 		devpriv->AdControlReg |=
-			((AdControl_TmrTr | AdControl_Dma) & 0xff);
+		    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
 		break;
 	case 2:
 		devpriv->AdControlReg |=
-			((AdControl_TmrTr | AdControl_Dma) & 0xff);
+		    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
 		devpriv->AdFunctionReg =
-			AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
-			AdFunction_BS;
+		    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);
+		    ((AdControl_ExtM | AdControl_Dma) & 0xff);
 		devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
 		break;
 	case 4:
 		devpriv->AdControlReg |=
-			((AdControl_TmrTr | AdControl_Dma) & 0xff);
+		    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
 		devpriv->AdFunctionReg =
-			AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+		    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);
+		     dev->iobase + PCI9118_CNT0);
 		outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
-			dev->iobase + PCI9118_CNT0);
+		     dev->iobase + PCI9118_CNT0);
 		devpriv->AdFunctionReg |= AdFunction_Start;
 		break;
 	default:
@@ -1268,14 +1301,14 @@ static int pci9118_ai_docmd_dma(struct comedi_device *dev, struct comedi_subdevi
 	devpriv->int_ai_func = interrupt_pci9118_ai_dma;	/* transfer function */
 
 	outl(0x02000000 | AINT_WRITE_COMPL,
-		devpriv->iobase_a + AMCC_OP_REG_INTCSR);
+	     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->ai_divisor2);
 			devpriv->AdControlReg |= AdControl_SoftG;
 		}
 		outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
@@ -1338,7 +1371,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	/*  use sample&hold signal? */
 	if (cmd->convert_src == TRIG_NOW) {
 		devpriv->usessh = 1;
-	}			/*  yes */
+	} /*  yes */
 	else {
 		devpriv->usessh = 0;
 	}			/*  no */
@@ -1354,7 +1387,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	if (devpriv->master) {
 		devpriv->usedma = 1;
 		if ((cmd->flags & TRIG_WAKE_EOS) &&
-			(devpriv->ai_n_scanlen == 1)) {
+		    (devpriv->ai_n_scanlen == 1)) {
 			if (cmd->convert_src == TRIG_NOW) {
 				devpriv->ai_add_back = 1;
 			}
@@ -1363,8 +1396,8 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			}
 		}
 		if ((cmd->flags & TRIG_WAKE_EOS) &&
-			(devpriv->ai_n_scanlen & 1) &&
-			(devpriv->ai_n_scanlen > 1)) {
+		    (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 */
@@ -1392,16 +1425,16 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			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_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 */
-
+	}
+	/*  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);
+	    (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,
@@ -1411,13 +1444,13 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	/*  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))
+				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))
+				devpriv->ai_chanlist, 0, devpriv->ai_add_front,
+				devpriv->ai_add_back, devpriv->usedma,
+				devpriv->useeoshandle))
 		return -EINVAL;
 
 	/*  compute timers settings */
@@ -1429,32 +1462,36 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			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);
+				      &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!");
+				     "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);
+				      &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)) {
+	    && (cmd->convert_src == TRIG_EXT)) {
 		devpriv->ai_do = 3;
 	}
 
@@ -1486,8 +1523,9 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 /*
 ==============================================================================
 */
-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 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;
 
@@ -1498,9 +1536,8 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 	}
 	if ((frontadd + n_chan + backadd) > s->len_chanlist) {
 		printk
-			("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
-			dev->minor, n_chan,
-			s->len_chanlist - frontadd - backadd);
+		    ("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
+		     dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
 		return 0;
 	}
 
@@ -1511,22 +1548,21 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 	if (n_chan > 1)
 		for (i = 1; i < n_chan; i++) {	/*  check S.E/diff */
 			if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
-				(differencial)) {
+			    (differencial)) {
 				comedi_error(dev,
-					"Differencial and single ended inputs cann't be mixtured!");
+					     "Differencial and single ended inputs cann't be mixtured!");
 				return 0;
 			}
 			if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
-				(bipolar)) {
+			    (bipolar)) {
 				comedi_error(dev,
-					"Bipolar and unipolar ranges cann't be mixtured!");
+					     "Bipolar and unipolar ranges cann't be mixtured!");
 				return 0;
 			}
 			if ((!devpriv->usemux) & (differencial) &
-				(CR_CHAN(chanlist[i]) >=
-					this_board->n_aichand)) {
+			    (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
 				comedi_error(dev,
-					"If AREF_DIFF is used then is available only first 8 channels!");
+					     "If AREF_DIFF is used then is available only first 8 channels!");
 				return 0;
 			}
 		}
@@ -1537,14 +1573,17 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 /*
 ==============================================================================
 */
-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)
+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);
+	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;
@@ -1625,7 +1664,7 @@ static int setup_channel_list(struct comedi_device *dev, struct comedi_subdevice
 	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;
+			    (CR_CHAN(chanlist[i]) & 0xf) << rot;
 		}
 		devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma];	/*  for 32bit oerations */
 		useeos = 2;
@@ -1652,18 +1691,22 @@ static int setup_channel_list(struct comedi_device *dev, struct comedi_subdevice
   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)
+				  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);
+	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);
+					  tim2, flags & TRIG_ROUND_NEAREST);
 		DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
 			devpriv->i8254_osc_base, *div1, *div2, *tim1);
 		break;
@@ -1710,8 +1753,8 @@ static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
 /*
 ==============================================================================
 */
-static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
-	unsigned int divisor2)
+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);
@@ -1760,7 +1803,8 @@ 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 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 */
@@ -1835,7 +1879,8 @@ static int pci9118_reset(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pci9118_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int ret, pages, i;
@@ -1848,8 +1893,7 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	unsigned char pci_bus, pci_slot, pci_func;
 	u16 u16w;
 
-	printk("comedi%d: adl_pci9118: board=%s", dev->minor,
-		this_board->name);
+	printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name);
 
 	opt_bus = it->options[0];
 	opt_slot = it->options[1];
@@ -1869,12 +1913,13 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	errstr = "not found!";
 	pcidev = NULL;
 	while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
-				this_board->device_id, pcidev))) {
+						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))
+			    || opt_slot != PCI_SLOT(pcidev->devfn))
 				continue;	/* no match */
 		}
 		/*
@@ -1882,7 +1927,8 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		 * Enable PCI device and request regions.
 		 */
 		if (comedi_pci_enable(pcidev, "adl_pci9118")) {
-			errstr = "failed to enable PCI device and request regions!";
+			errstr =
+			    "failed to enable PCI device and request regions!";
 			continue;
 		}
 		break;
@@ -1891,7 +1937,7 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	if (!pcidev) {
 		if (opt_bus || opt_slot) {
 			printk(" - Card at b:s %d:%d %s\n",
-				opt_bus, opt_slot, errstr);
+			       opt_bus, opt_slot, errstr);
 		} else {
 			printk(" - Card %s\n", errstr);
 		}
@@ -1910,7 +1956,7 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	iobase_9 = pci_resource_start(pcidev, 2);
 
 	printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot,
-		pci_func, iobase_9, iobase_a);
+	       pci_func, iobase_9, iobase_a);
 
 	dev->iobase = iobase_9;
 	dev->board_name = this_board->name;
@@ -1926,7 +1972,7 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
 				"ADLink PCI-9118", dev)) {
 			printk(", unable to allocate IRQ %d, DISABLING IT",
-				irq);
+			       irq);
 			irq = 0;	/* Can't use IRQ */
 		} else {
 			printk(", irq=%u", irq);
@@ -1942,8 +1988,8 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		for (i = 0; i < 2; i++) {
 			for (pages = 4; pages >= 0; pages--) {
 				devpriv->dmabuf_virt[i] =
-					(short *) __get_free_pages(GFP_KERNEL,
-								   pages);
+				    (short *)__get_free_pages(GFP_KERNEL,
+							      pages);
 				if (devpriv->dmabuf_virt[i])
 					break;
 			}
@@ -1951,10 +1997,10 @@ static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it
 				devpriv->dmabuf_pages[i] = pages;
 				devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
 				devpriv->dmabuf_samples[i] =
-					devpriv->dmabuf_size[i] >> 1;
+				    devpriv->dmabuf_size[i] >> 1;
 				devpriv->dmabuf_hw[i] =
-					virt_to_bus((void *)devpriv->
-					dmabuf_virt[i]);
+				    virt_to_bus((void *)
+						devpriv->dmabuf_virt[i]);
 			}
 		}
 		if (!devpriv->dmabuf_virt[0]) {
@@ -2090,10 +2136,10 @@ static int pci9118_detach(struct comedi_device *dev)
 		}
 		if (devpriv->dmabuf_virt[0])
 			free_pages((unsigned long)devpriv->dmabuf_virt[0],
-				devpriv->dmabuf_pages[0]);
+				   devpriv->dmabuf_pages[0]);
 		if (devpriv->dmabuf_virt[1])
 			free_pages((unsigned long)devpriv->dmabuf_virt[1],
-				devpriv->dmabuf_pages[1]);
+				   devpriv->dmabuf_pages[1]);
 	}
 
 	return 0;
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
index d09d149..c5ed8bb 100644
--- a/drivers/staging/comedi/drivers/adq12b.c
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -62,7 +62,6 @@ If you do not specify any options, they will default to
        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
@@ -101,39 +100,39 @@ If you do not specify any options, they will default to
 
 /* 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)
-}};
+								  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)
-}};
-
-
+								   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;
+	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
-        }
+	{
+	 .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",
@@ -147,11 +146,11 @@ static const struct adq12b_board adq12b_boards[] = {
 #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;
+	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)
@@ -162,21 +161,28 @@ struct adq12b_private {
  * 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_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:      ARRAY_SIZE(adq12b_boards),
+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:ARRAY_SIZE(adq12b_boards),
 };
 
-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);
+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
@@ -186,109 +192,108 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, struct comedi_subdevic
  */
 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;
+	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;
+	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;
+	if (alloc_private(dev, sizeof(struct adq12b_private)) < 0)
+		return -ENOMEM;
 
 /* fill in devpriv structure */
-        devpriv->unipolar = unipolar;
-        devpriv->differential = differential;
+	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;
-
+	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;
+	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.
@@ -299,14 +304,14 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
  */
 static int adq12b_detach(struct comedi_device *dev)
 {
-        if (dev->iobase)
-          release_region(dev->iobase, ADQ12B_SIZE);
+	if (dev->iobase)
+		release_region(dev->iobase, ADQ12B_SIZE);
 
-        kfree(devpriv);
+	kfree(devpriv);
 
-        printk("comedi%d: adq12b: removed\n", dev->minor);
+	printk("comedi%d: adq12b: removed\n", dev->minor);
 
-        return 0;
+	return 0;
 }
 
 /*
@@ -314,79 +319,83 @@ static int adq12b_detach(struct comedi_device *dev)
  * mode.
  */
 
-static int adq12b_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+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);
-          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 {
+	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);
+		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 {
 /* udelay(1); */
-	    status = inb(dev->iobase + ADQ12B_STINR);
-            status = status & ADQ12B_EOC;
-          } while (status == 0 && ++i < TIMEOUT);
+			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);
+		/* read data */
+		hi = inb(dev->iobase + ADQ12B_ADHIG);
+		lo = inb(dev->iobase + ADQ12B_ADLOW);
 
-          /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status,  hi, lo); */
-          data[n] = (hi << 8) | lo;
+		/* 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;
+	/* 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)
+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));
+	/* only bits 0-4 have information about digital inputs */
+	data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f));
 
-        return 2;
+	return 2;
 }
 
-
-static int adq12b_do_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)
 {
-        int channel;
+	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);
+		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]);
-        }
+	/* 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;
+	data[1] = devpriv->digital_state;
 
-        return 2;
+	return 2;
 }
 
-
 /*
  * A convenient macro that defines init_module() and cleanup_module(),
  * as necessary.
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
index 0b56c14..f0ae4c0 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -124,67 +124,69 @@ Configuration options:
 #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)
-	}
+							  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 };
+    { 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)
-	}
+							   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 };
+    { 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)
-	}
+							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)
-	}
+							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),
-	}
+							   UNI_RANGE(5),
+							   UNI_RANGE(10),
+							   }
 };
 
-static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int pci1710_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it);
 static int pci1710_detach(struct comedi_device *dev);
 
 struct boardtype {
@@ -209,49 +211,50 @@ struct boardtype {
 };
 
 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}
+	{
+	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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
 };
@@ -292,7 +295,7 @@ struct pci1710_private {
 	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 */
+	short *ai_data;		/*  data buffer */
 	unsigned int ai_timer1;	/*  timers */
 	unsigned int ai_timer2;
 	short ao_data[4];	/*  data output buffer */
@@ -306,14 +309,18 @@ struct pci1710_private {
 ==============================================================================
 */
 
-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 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 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,
@@ -324,8 +331,9 @@ static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x040
 /*
 ==============================================================================
 */
-static int pci171x_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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
@@ -364,10 +372,12 @@ static int pci171x_insn_read_ai(struct comedi_device *dev, struct comedi_subdevi
 		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);
+		DPRINTK
+		    ("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n",
+		     n);
 		return -ETIME;
 
-	      conv_finish:
+conv_finish:
 #ifdef PCI171x_PARANOIDCHECK
 		idata = inw(dev->iobase + PCI171x_AD_DATA);
 		if (this_board->cardtype != TYPE_PCI1713)
@@ -392,8 +402,9 @@ static int pci171x_insn_read_ai(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci171x_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
 
@@ -423,8 +434,9 @@ static int pci171x_insn_write_ao(struct comedi_device *dev, struct comedi_subdev
 /*
 ==============================================================================
 */
-static int pci171x_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int pci171x_insn_read_ao(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int n, chan;
 
@@ -438,8 +450,9 @@ static int pci171x_insn_read_ao(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci171x_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
 
@@ -449,8 +462,9 @@ static int pci171x_insn_bits_di(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci171x_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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];
@@ -465,8 +479,10 @@ static int pci171x_insn_bits_do(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci171x_insn_counter_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -487,8 +503,10 @@ static int pci171x_insn_counter_read(struct comedi_device *dev, struct comedi_su
 /*
 ==============================================================================
 */
-static int pci171x_insn_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
 
@@ -515,7 +533,9 @@ static int pci171x_insn_counter_write(struct comedi_device *dev, struct comedi_s
 ==============================================================================
 */
 static int pci171x_insn_counter_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				       struct comedi_subdevice *s,
+				       struct comedi_insn *insn,
+				       unsigned int *data)
 {
 #ifdef unused
 	/* This doesn't work like a normal Comedi counter config */
@@ -550,8 +570,9 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
 /*
 ==============================================================================
 */
-static int pci1720_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
 
@@ -596,8 +617,8 @@ static void interrupt_pci1710_every_sample(void *d)
 	}
 	if (m & Status_FF) {
 		printk
-			("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
-			dev->minor, m);
+		    ("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);
@@ -613,16 +634,17 @@ static void interrupt_pci1710_every_sample(void *d)
 		DPRINTK("%04x:", sampl);
 		if (this_board->cardtype != TYPE_PCI1713)
 			if ((sampl & 0xf000) !=
-				devpriv->act_chanlist[s->async->cur_chan]) {
+			    devpriv->act_chanlist[s->async->cur_chan]) {
 				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);
+				    ("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_CB_EOA | COMEDI_CB_ERROR;
 				comedi_event(dev, s);
 				return;
 			}
@@ -631,7 +653,7 @@ static void interrupt_pci1710_every_sample(void *d)
 		comedi_buf_put(s->async, sampl & 0x0fff);
 #else
 		comedi_buf_put(s->async,
-			inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
+			       inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
 #endif
 		++s->async->cur_chan;
 
@@ -641,7 +663,10 @@ static void interrupt_pci1710_every_sample(void *d)
 
 		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: 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);
@@ -661,8 +686,8 @@ static void interrupt_pci1710_every_sample(void *d)
 /*
 ==============================================================================
 */
-static int move_block_from_fifo(struct comedi_device *dev, struct comedi_subdevice *s,
-	int n, int turn)
+static int move_block_from_fifo(struct comedi_device *dev,
+				struct comedi_subdevice *s, int n, int turn)
 {
 	int i, j;
 #ifdef PCI171x_PARANOIDCHECK
@@ -677,22 +702,21 @@ static int move_block_from_fifo(struct comedi_device *dev, struct comedi_subdevi
 		if (this_board->cardtype != TYPE_PCI1713)
 			if ((sampl & 0xf000) != devpriv->act_chanlist[j]) {
 				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);
+				    ("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_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);
+			       inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
 #endif
 		j++;
 		if (j >= devpriv->ai_n_chan) {
@@ -717,7 +741,7 @@ static void interrupt_pci1710_half_fifo(void *d)
 	m = inw(dev->iobase + PCI171x_STATUS);
 	if (!(m & Status_FH)) {
 		printk("comedi%d: A/D FIFO not half full! (%4x)\n",
-			dev->minor, m);
+		       dev->minor, m);
 		pci171x_ai_cancel(dev, s);
 		s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 		comedi_event(dev, s);
@@ -725,8 +749,8 @@ static void interrupt_pci1710_half_fifo(void *d)
 	}
 	if (m & Status_FF) {
 		printk
-			("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
-			dev->minor, m);
+		    ("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);
@@ -804,7 +828,7 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
 ==============================================================================
 */
 static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
-	struct comedi_subdevice *s)
+				     struct comedi_subdevice *s)
 {
 	unsigned int divisor1, divisor2;
 	unsigned int seglen;
@@ -814,11 +838,11 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
 	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
 
 	seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
-		devpriv->ai_n_chan);
+				    devpriv->ai_n_chan);
 	if (seglen < 1)
 		return -EINVAL;
 	setup_channel_list(dev, s, devpriv->ai_chanlist,
-		devpriv->ai_n_chan, seglen);
+			   devpriv->ai_n_chan, seglen);
 
 	outb(0, dev->iobase + PCI171x_CLRFIFO);
 	outb(0, dev->iobase + PCI171x_CLRINT);
@@ -840,7 +864,7 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
 
 	if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1)) {
 		devpriv->neverending_ai = 1;
-	}			/* well, user want neverending */
+	} /* well, user want neverending */
 	else {
 		devpriv->neverending_ai = 0;
 	}
@@ -853,16 +877,19 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
 		if (mode == 2) {
 			devpriv->ai_et_CntrlReg = devpriv->CntrlReg;
 			devpriv->CntrlReg &=
-				~(Control_PACER | Control_ONEFH | Control_GATE);
+			    ~(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);
+					  &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 */
@@ -889,21 +916,22 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
 static void pci171x_cmdtest_out(int e, struct comedi_cmd *cmd)
 {
 	printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
-		cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+	       cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
 	printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
-		cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+	       cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
 	printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
-		cmd->scan_end_src);
+	       cmd->scan_end_src);
 	printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
-		e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+	       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)
+static int pci171x_ai_cmdtest(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp, divisor1, divisor2;
@@ -943,7 +971,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 #ifdef PCI171X_EXTDEBUG
 		pci171x_cmdtest_out(1, cmd);
 #endif
-		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", err);
+		DPRINTK
+		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n",
+		     err);
 		return 1;
 	}
 
@@ -974,7 +1004,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 #ifdef PCI171X_EXTDEBUG
 		pci171x_cmdtest_out(2, cmd);
 #endif
-		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", err);
+		DPRINTK
+		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n",
+		     err);
 		return 2;
 	}
 
@@ -1030,7 +1062,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 #ifdef PCI171X_EXTDEBUG
 		pci171x_cmdtest_out(3, cmd);
 #endif
-		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", err);
+		DPRINTK
+		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n",
+		     err);
 		return 3;
 	}
 
@@ -1039,8 +1073,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	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);
+					  &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)
@@ -1048,7 +1082,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	}
 
 	if (err) {
-		DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n", err);
+		DPRINTK
+		    ("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n",
+		     err);
 		return 4;
 	}
 
@@ -1056,7 +1092,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 	if (cmd->chanlist) {
 		if (!check_channel_list(dev, s, cmd->chanlist,
-				cmd->chanlist_len))
+					cmd->chanlist_len))
 			return 5;	/*  incorrect channels list */
 	}
 
@@ -1090,7 +1126,8 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		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);
+							 TRIG_EXT ? 2 : 1, dev,
+							 s);
 		}
 		if (cmd->convert_src == TRIG_EXT) {	/*  mode 3 */
 			return pci171x_ai_docmd_and_mode(3, dev, s);
@@ -1106,8 +1143,9 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
  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)
+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;
@@ -1128,18 +1166,18 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 			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");
+						     "Odd channel can't be differential input!\n");
 					return 0;
 				}
 			nowmustbechan =
-				(CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+			    (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 :-( */
 				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]));
+				    ("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 */
@@ -1149,13 +1187,13 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 			/* 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]) {
 				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]));
+				    ("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 */
 			}
 		}
@@ -1165,8 +1203,10 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 	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)
+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;
 
@@ -1185,14 +1225,14 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevic
 		outw(range, dev->iobase + PCI171x_RANGE);	/* select gain */
 #ifdef PCI171x_PARANOIDCHECK
 		devpriv->act_chanlist[i] =
-			(CR_CHAN(chanlist[i]) << 12) & 0xf000;
+		    (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);
+	    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),
@@ -1202,8 +1242,8 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevic
 /*
 ==============================================================================
 */
-static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
-	unsigned int divisor2)
+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);
@@ -1222,7 +1262,8 @@ static void start_pacer(struct comedi_device *dev, int mode, unsigned int diviso
 /*
 ==============================================================================
 */
-static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int pci171x_ai_cancel(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n");
 
@@ -1318,7 +1359,8 @@ static int pci1710_reset(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pci1710_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int ret, subdev, n_subdevices;
@@ -1347,36 +1389,35 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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)
-				{
+						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;
+			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))
+			    || opt_slot != PCI_SLOT(pcidev->devfn))
 				continue;	/* no match */
 		}
 		/*
-		* Look for device that isn't in use.
-		* Enable PCI device and request regions.
-		*/
+		 * 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!";
+			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 */
@@ -1387,7 +1428,7 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	if (!pcidev) {
 		if (opt_bus || opt_slot) {
 			printk(" - Card at b:s %d:%d %s\n",
-				opt_bus, opt_slot, errstr);
+			       opt_bus, opt_slot, errstr);
 		} else {
 			printk(" - Card %s\n", errstr);
 		}
@@ -1401,7 +1442,7 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	iobase = pci_resource_start(pcidev, 2);
 
 	printk(", b:s:f=%d:%d:%d, io=0x%4lx", pci_bus, pci_slot, pci_func,
-		iobase);
+	       iobase);
 
 	dev->iobase = iobase;
 
@@ -1434,8 +1475,8 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
 					IRQF_SHARED, "Advantech PCI-1710",
 					dev)) {
 				printk
-					(", unable to allocate IRQ %d, DISABLING IT",
-					irq);
+				    (", unable to allocate IRQ %d, DISABLING IT",
+				     irq);
 				irq = 0;	/* Can't use IRQ */
 			} else {
 				printk(", irq=%u", irq);
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
index e1994a5..6b0b7ed 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -95,8 +95,8 @@ TODO:
 /* static unsigned short pci_list_builded=0;      =1 list of card is know */
 
 static const struct comedi_lrange range_pci1723 = { 1, {
-			BIP_RANGE(10)
-	}
+							BIP_RANGE(10)
+							}
 };
 
 /*
@@ -116,23 +116,24 @@ struct pci1723_board {
 
 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,
-		},
+	 .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}
+	{
+	PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	0}
 };
 
 MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
@@ -143,7 +144,8 @@ MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
  * 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_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))
@@ -189,7 +191,7 @@ static int pci1723_reset(struct comedi_device *dev)
 		/*  set all ranges to +/- 10V */
 		devpriv->da_range[i] = 0;
 		outw(((devpriv->da_range[i] << 4) | i),
-			PCI1723_RANGE_CALIBRATION_MODE);
+		     PCI1723_RANGE_CALIBRATION_MODE);
 	}
 
 	outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE);	/*  update ranges */
@@ -202,8 +204,9 @@ static int pci1723_reset(struct comedi_device *dev)
 	return 0;
 }
 
-static int pci1723_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int pci1723_insn_read_ao(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int n, chan;
 
@@ -218,8 +221,9 @@ static int pci1723_insn_read_ao(struct comedi_device *dev, struct comedi_subdevi
 /*
   analog data output;
 */
-static int pci1723_ao_write_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -238,8 +242,9 @@ static int pci1723_ao_write_winsn(struct comedi_device *dev, struct comedi_subde
 /*
   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)
+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;
@@ -278,8 +283,9 @@ static int pci1723_dio_insn_config(struct comedi_device *dev, struct comedi_subd
 /*
   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)
+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];
@@ -294,7 +300,8 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
  * 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)
+static int pci1723_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int ret, subdev, n_subdevices;
@@ -304,8 +311,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	int opt_bus, opt_slot;
 	const char *errstr;
 
-	printk("comedi%d: adv_pci1723: board=%s", dev->minor,
-		this_board->name);
+	printk("comedi%d: adv_pci1723: board=%s", dev->minor, this_board->name);
 
 	opt_bus = it->options[0];
 	opt_slot = it->options[1];
@@ -321,12 +327,12 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	pcidev = NULL;
 	while (NULL != (pcidev =
 			pci_get_device(PCI_VENDOR_ID_ADVANTECH,
-				this_board->device_id, pcidev))) {
+				       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))
+			    || opt_slot != PCI_SLOT(pcidev->devfn))
 				continue;	/* no match */
 		}
 		/*
@@ -334,7 +340,8 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		 * Enable PCI device and request regions.
 		 */
 		if (comedi_pci_enable(pcidev, "adv_pci1723")) {
-			errstr = "failed to enable PCI device and request regions!";
+			errstr =
+			    "failed to enable PCI device and request regions!";
 			continue;
 		}
 		break;
@@ -343,7 +350,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	if (!pcidev) {
 		if (opt_bus || opt_slot) {
 			printk(" - Card at b:s %d:%d %s\n",
-				opt_bus, opt_slot, errstr);
+			       opt_bus, opt_slot, errstr);
 		} else {
 			printk(" - Card %s\n", errstr);
 		}
@@ -356,7 +363,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	iobase = pci_resource_start(pcidev, 2);
 
 	printk(", b:s:f=%d:%d:%d, io=0x%4x", pci_bus, pci_slot, pci_func,
-		iobase);
+	       iobase);
 
 	dev->iobase = iobase;
 
@@ -416,7 +423,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		s = dev->subdevices + subdev;
 		s->type = COMEDI_SUBD_DIO;
 		s->subdev_flags =
-			SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+		    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;
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
index 5a8c0a3..61d35fe 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -84,13 +84,13 @@ enum hw_io_access {
 #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 */
+#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 */
@@ -183,7 +183,8 @@ enum hw_io_access {
 
 #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_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it);
 static int pci_dio_detach(struct comedi_device *dev);
 
 struct diosubd_data {
@@ -207,117 +208,118 @@ struct dio_boardtype {
 };
 
 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}
+	{
+	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,
-		},
+	 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},
+	 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},
+	 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,
-        },
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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}
+	 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))
@@ -357,8 +359,9 @@ static struct pci_dio_private *pci_priv = NULL;	/* list of allocated cards */
 /*
 ==============================================================================
 */
-static int pci_dio_insn_bits_di_b(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -374,8 +377,9 @@ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, struct comedi_subde
 /*
 ==============================================================================
 */
-static int pci_dio_insn_bits_di_w(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -390,8 +394,9 @@ static int pci_dio_insn_bits_di_w(struct comedi_device *dev, struct comedi_subde
 /*
 ==============================================================================
 */
-static int pci_dio_insn_bits_do_b(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -401,7 +406,7 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev, struct comedi_subde
 		s->state |= (data[0] & data[1]);
 		for (i = 0; i < d->regs; i++)
 			outb((s->state >> (8 * i)) & 0xff,
-				dev->iobase + d->addr + i);
+			     dev->iobase + d->addr + i);
 	}
 	data[1] = s->state;
 
@@ -411,8 +416,9 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev, struct comedi_subde
 /*
 ==============================================================================
 */
-static int pci_dio_insn_bits_do_w(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -422,7 +428,7 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, struct comedi_subde
 		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);
+			     dev->iobase + d->addr + 2 * i);
 	}
 	data[1] = s->state;
 
@@ -433,7 +439,8 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, struct comedi_subde
 ==============================================================================
 */
 static int pci1760_unchecked_mbxrequest(struct comedi_device *dev,
-	unsigned char *omb, unsigned char *imb, int repeats)
+					unsigned char *omb, unsigned char *imb,
+					int repeats)
 {
 	int cnt, tout, ok = 0;
 
@@ -472,11 +479,11 @@ static int pci1760_clear_imb2(struct comedi_device *dev)
 }
 
 static int pci1760_mbxrequest(struct comedi_device *dev,
-	unsigned char *omb, unsigned char *imb)
+			      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");
+			     "bug! this function should not be used for CMD_ClearIMB2 command");
 		return -EINVAL;
 	}
 	if (inb(dev->iobase + IMB2) == omb[2]) {
@@ -491,8 +498,9 @@ static int pci1760_mbxrequest(struct comedi_device *dev,
 /*
 ==============================================================================
 */
-static int pci1760_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
 
@@ -502,8 +510,9 @@ static int pci1760_insn_bits_di(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci1760_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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] = {
@@ -530,8 +539,9 @@ static int pci1760_insn_bits_do(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pci1760_insn_cnt_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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] = {
@@ -555,8 +565,9 @@ static int pci1760_insn_cnt_read(struct comedi_device *dev, struct comedi_subdev
 /*
 ==============================================================================
 */
-static int pci1760_insn_cnt_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -570,7 +581,7 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev, struct comedi_subde
 	unsigned char imb[4];
 
 	if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) {	/*  Set reset value if different */
-		ret =  pci1760_mbxrequest(dev, omb, imb);
+		ret = pci1760_mbxrequest(dev, omb, imb);
 		if (!ret)
 			return ret;
 		devpriv->CntResValue[chan] = data[0] & 0xffff;
@@ -697,11 +708,11 @@ static int pci_dio_reset(struct comedi_device *dev)
 		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 */
+		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:
@@ -756,7 +767,8 @@ static int pci_dio_reset(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-static int pci1760_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pci1760_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int subdev = 0;
@@ -809,7 +821,7 @@ static int pci1760_attach(struct comedi_device *dev, struct comedi_devconfig *it
 ==============================================================================
 */
 static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s,
-	const struct diosubd_data *d, int subdev)
+			  const struct diosubd_data *d, int subdev)
 {
 	s->type = COMEDI_SUBD_DI;
 	s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags;
@@ -836,7 +848,7 @@ static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s,
 ==============================================================================
 */
 static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
-	const struct diosubd_data *d, int subdev)
+			  const struct diosubd_data *d, int subdev)
 {
 	s->type = COMEDI_SUBD_DO;
 	s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
@@ -863,8 +875,9 @@ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
 /*
 ==============================================================================
 */
-static int CheckAndAllocCard(struct comedi_device *dev, struct comedi_devconfig *it,
-	struct pci_dev *pcidev)
+static int CheckAndAllocCard(struct comedi_device *dev,
+			     struct comedi_devconfig *it,
+			     struct pci_dev *pcidev)
 {
 	struct pci_dio_private *pr, *prev;
 
@@ -889,7 +902,8 @@ static int CheckAndAllocCard(struct comedi_device *dev, struct comedi_devconfig
 /*
 ==============================================================================
 */
-static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pci_dio_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int ret, subdev, n_subdevices, i, j;
@@ -905,8 +919,8 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	}
 
 	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)) {
+	     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)
@@ -917,13 +931,13 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
 			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]) {
+				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 					continue;
 				}
 			}
 			ret = CheckAndAllocCard(dev, it, pcidev);
-			if (ret != 1) continue;
+			if (ret != 1)
+				continue;
 			dev->board_ptr = boardtypes + i;
 			break;
 		}
@@ -932,20 +946,19 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	}
 
 	if (!dev->board_ptr) {
-		printk
-			(", Error: Requested type of the card was not found!\n");
+		printk(", Error: Requested type of the card was not found!\n");
 		return -EIO;
 	}
 
 	if (comedi_pci_enable(pcidev, driver_pci_dio.driver_name)) {
 		printk
-			(", Error: Can't enable PCI device and request regions!\n");
+		    (", Error: Can't enable PCI device and request regions!\n");
 		return -EIO;
 	}
 	iobase = pci_resource_start(pcidev, this_board->main_pci_region);
 	printk(", b:s:f=%d:%d:%d, io=0x%4lx",
-		pcidev->bus->number, PCI_SLOT(pcidev->devfn),
-		PCI_FUNC(pcidev->devfn), iobase);
+	       pcidev->bus->number, PCI_SLOT(pcidev->devfn),
+	       PCI_FUNC(pcidev->devfn), iobase);
 
 	dev->iobase = iobase;
 	dev->board_name = this_board->name;
@@ -994,8 +1007,9 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		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);
+					 dev->iobase +
+					 this_board->sdio[i].addr +
+					 SIZE_8255 * j);
 			subdev++;
 		}
 
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
index 72283ae..c4cac66 100644
--- a/drivers/staging/comedi/drivers/aio_aio12_8.c
+++ b/drivers/staging/comedi/drivers/aio_aio12_8.c
@@ -77,7 +77,7 @@ struct aio12_8_boardtype {
 
 static const struct aio12_8_boardtype board_types[] = {
 	{
-	.name = "aio_aio12_8"},
+	 .name = "aio_aio12_8"},
 };
 
 #define	thisboard	((const struct aio12_8_boardtype  *) dev->board_ptr)
@@ -88,13 +88,14 @@ struct aio12_8_private {
 
 #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)
+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);
+	    ADC_MODE_NORMAL |
+	    (CR_RANGE(insn->chanspec) << 3) | CR_CHAN(insn->chanspec);
 
 	/* read status to clear EOC latch */
 	inb(dev->iobase + AIO12_8_STATUS);
@@ -107,7 +108,7 @@ static int aio_aio12_8_ai_read(struct comedi_device *dev, struct comedi_subdevic
 
 		/*  Wait for conversion to complete */
 		while (timeout &&
-			!(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) {
+		       !(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) {
 			timeout--;
 			printk("timeout %d\n", timeout);
 			udelay(1);
@@ -122,8 +123,9 @@ static int aio_aio12_8_ai_read(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int aio_aio12_8_ao_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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)];
@@ -133,8 +135,9 @@ static int aio_aio12_8_ao_read(struct comedi_device *dev, struct comedi_subdevic
 	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)
+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);
@@ -154,14 +157,15 @@ static int aio_aio12_8_ao_write(struct comedi_device *dev, struct comedi_subdevi
 static const struct comedi_lrange range_aio_aio12_8 = {
 	4,
 	{
-			UNI_RANGE(5),
-			BIP_RANGE(5),
-			UNI_RANGE(10),
-			BIP_RANGE(10),
-		}
+	 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)
+static int aio_aio12_8_attach(struct comedi_device *dev,
+			      struct comedi_devconfig *it)
 {
 	int iobase;
 	struct comedi_subdevice *s;
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
index d062f86..3857fd5 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -52,9 +52,9 @@ struct aio_iiro_16_board {
 
 static const struct aio_iiro_16_board aio_iiro_16_boards[] = {
 	{
-	.name = "aio_iiro_16",
-	.di = 16,
-	.do_ = 16},
+	 .name = "aio_iiro_16",
+	 .di = 16,
+	 .do_ = 16},
 };
 
 #define	thisboard	((const struct aio_iiro_16_board *) dev->board_ptr)
@@ -67,7 +67,8 @@ struct aio_iiro_16_private {
 
 #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_attach(struct comedi_device *dev,
+			      struct comedi_devconfig *it);
 
 static int aio_iiro_16_detach(struct comedi_device *dev);
 
@@ -82,12 +83,17 @@ static struct comedi_driver driver_aio_iiro_16 = {
 };
 
 static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+					  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);
+					   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)
+static int aio_iiro_16_attach(struct comedi_device *dev,
+			      struct comedi_devconfig *it)
 {
 	int iobase;
 	struct comedi_subdevice *s;
@@ -143,7 +149,9 @@ static int aio_iiro_16_detach(struct comedi_device *dev)
 }
 
 static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+					   struct comedi_subdevice *s,
+					   struct comedi_insn *insn,
+					   unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -153,7 +161,7 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
 		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);
+		     dev->iobase + AIO_IIRO_16_RELAY_8_15);
 	}
 
 	data[1] = s->state;
@@ -162,7 +170,9 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
 }
 
 static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+					  struct comedi_subdevice *s,
+					  struct comedi_insn *insn,
+					  unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
index 7446800..69ab281 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -290,60 +290,60 @@ struct dio200_board {
 
 static const struct dio200_board dio200_boards[] = {
 	{
-	.name = "pc212e",
-	.bustype = isa_bustype,
-	.model = pc212e_model,
-	.layout = pc212_layout,
-		},
+	 .name = "pc212e",
+	 .bustype = isa_bustype,
+	 .model = pc212e_model,
+	 .layout = pc212_layout,
+	 },
 	{
-	.name = "pc214e",
-	.bustype = isa_bustype,
-	.model = pc214e_model,
-	.layout = pc214_layout,
-		},
+	 .name = "pc214e",
+	 .bustype = isa_bustype,
+	 .model = pc214e_model,
+	 .layout = pc214_layout,
+	 },
 	{
-	.name = "pc215e",
-	.bustype = isa_bustype,
-	.model = pc215e_model,
-	.layout = pc215_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,
-		},
+	 .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 = "pc218e",
+	 .bustype = isa_bustype,
+	 .model = pc218e_model,
+	 .layout = pc218_layout,
+	 },
 	{
-	.name = "pc272e",
-	.bustype = isa_bustype,
-	.model = pc272e_model,
-	.layout = pc272_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,
-		},
+	 .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 */
-		},
+	 .name = DIO200_DRIVER_NAME,
+	 .devid = PCI_DEVICE_ID_INVALID,
+	 .bustype = pci_bustype,
+	 .model = anypci_model,	/* wildcard */
+	 },
 #endif
 };
 
@@ -367,51 +367,51 @@ struct dio200_layout_struct {
 
 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,
-		},
+			  .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,
-		},
+			  .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,
-		},
+			  .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,
-		},
+			  .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,
-		},
+			  .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,
+			  },
 };
 
 /*
@@ -420,11 +420,12 @@ static const struct dio200_layout_struct dio200_layouts[] = {
 
 #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}
+	{
+	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);
@@ -475,7 +476,8 @@ struct dio200_subdev_intr {
  * 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_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,
@@ -500,7 +502,7 @@ COMEDI_INITCLEANUP(driver_amplc_dio200);
 #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_p)
 {
 	struct pci_dev *pci_dev = NULL;
 
@@ -508,13 +510,13 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot,
 
 	/* 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)) {
+	     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))
+			    || slot != PCI_SLOT(pci_dev->devfn))
 				continue;
 		}
 		if (thisboard->model == anypci_model) {
@@ -545,11 +547,11 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot,
 	/* 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);
+		       "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);
+		       dev->minor, thisboard->name);
 	}
 	return -EIO;
 }
@@ -564,7 +566,7 @@ 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);
+		       minor, from, extent);
 		return -EIO;
 	}
 	return 0;
@@ -574,8 +576,9 @@ dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
  * '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)
+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;
 
@@ -593,7 +596,8 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 /*
  * Called to stop acquisition for an 'INTERRUPT' subdevice.
  */
-static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s)
+static void dio200_stop_intr(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
 
@@ -607,7 +611,8 @@ static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice
 /*
  * Called to start acquisition for an 'INTERRUPT' subdevice.
  */
-static int dio200_start_intr(struct comedi_device *dev, struct comedi_subdevice *s)
+static int dio200_start_intr(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	unsigned int n;
 	unsigned isn_bits;
@@ -644,7 +649,7 @@ static int dio200_start_intr(struct comedi_device *dev, struct comedi_subdevice
  */
 static int
 dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+			  unsigned int trignum)
 {
 	struct dio200_subdev_intr *subpriv;
 	unsigned long flags;
@@ -673,7 +678,8 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
  * 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)
+static int dio200_handle_read_intr(struct comedi_device *dev,
+				   struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
 	unsigned triggered;
@@ -699,7 +705,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
 		 */
 		cur_enabled = subpriv->enabled_isns;
 		while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
-					& ~triggered)) != 0) {
+				   & ~triggered)) != 0) {
 			triggered |= intstat;
 			cur_enabled &= ~triggered;
 			outb(cur_enabled, subpriv->iobase);
@@ -748,12 +754,12 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
 				/* Write the scan to the buffer. */
 				if (comedi_buf_put(s->async, val)) {
 					s->async->events |= (COMEDI_CB_BLOCK |
-						COMEDI_CB_EOS);
+							     COMEDI_CB_EOS);
 				} else {
 					/* Error!  Stop acquisition.  */
 					dio200_stop_intr(dev, s);
 					s->async->events |= COMEDI_CB_ERROR
-						| COMEDI_CB_OVERFLOW;
+					    | COMEDI_CB_OVERFLOW;
 					comedi_error(dev, "buffer overflow");
 				}
 
@@ -764,9 +770,9 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
 						subpriv->stopcount--;
 						if (subpriv->stopcount == 0) {
 							s->async->events |=
-								COMEDI_CB_EOA;
+							    COMEDI_CB_EOA;
 							dio200_stop_intr(dev,
-								s);
+									 s);
 						}
 					}
 				}
@@ -785,7 +791,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
 /*
  * 'cancel' function for an 'INTERRUPT' subdevice.
  */
-static int dio200_subdev_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int dio200_subdev_intr_cancel(struct comedi_device *dev,
+				     struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
 	unsigned long flags;
@@ -803,8 +810,8 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev, struct comedi_su
  * '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)
+dio200_subdev_intr_cmdtest(struct comedi_device *dev,
+			   struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	unsigned int tmp;
@@ -909,7 +916,8 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 /*
  * 'do_cmd' function for an 'INTERRUPT' subdevice.
  */
-static int dio200_subdev_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+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;
@@ -956,14 +964,15 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, struct comedi_subde
  */
 static int
 dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned long iobase, unsigned valid_isns, int has_int_sce)
+			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);
+		       dev->minor);
 		return -ENOMEM;
 	}
 	subpriv->iobase = iobase;
@@ -1000,7 +1009,8 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
  * This function cleans up an 'INTERRUPT' subdevice.
  */
 static void
-dio200_subdev_intr_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
+dio200_subdev_intr_cleanup(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
 
@@ -1023,7 +1033,8 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
 
 	if (devpriv->intr_sd >= 0) {
 		handled = dio200_handle_read_intr(dev,
-			dev->subdevices + devpriv->intr_sd);
+						  dev->subdevices +
+						  devpriv->intr_sd);
 	} else {
 		handled = 0;
 	}
@@ -1036,7 +1047,7 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
  */
 static int
 dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			struct comedi_insn *insn, unsigned int *data)
 {
 	struct dio200_subdev_8254 *subpriv = s->private;
 	int chan = CR_CHAN(insn->chanspec);
@@ -1051,7 +1062,7 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
  */
 static int
 dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	struct dio200_subdev_8254 *subpriv = s->private;
 	int chan = CR_CHAN(insn->chanspec);
@@ -1065,8 +1076,8 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
  * 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)
+dio200_set_gate_src(struct dio200_subdev_8254 *subpriv,
+		    unsigned int counter_number, unsigned int gate_src)
 {
 	unsigned char byte;
 
@@ -1088,7 +1099,8 @@ dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_num
  * Get gate source for an '8254' counter subdevice channel.
  */
 static int
-dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_number)
+dio200_get_gate_src(struct dio200_subdev_8254 *subpriv,
+		    unsigned int counter_number)
 {
 	if (!subpriv->has_clk_gat_sce)
 		return -1;
@@ -1102,8 +1114,8 @@ dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_num
  * 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)
+dio200_set_clock_src(struct dio200_subdev_8254 *subpriv,
+		     unsigned int counter_number, unsigned int clock_src)
 {
 	unsigned char byte;
 
@@ -1125,8 +1137,8 @@ dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_nu
  * 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)
+dio200_get_clock_src(struct dio200_subdev_8254 *subpriv,
+		     unsigned int counter_number, unsigned int *period_ns)
 {
 	unsigned clock_src;
 
@@ -1145,7 +1157,7 @@ dio200_get_clock_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_nu
  */
 static int
 dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	struct dio200_subdev_8254 *subpriv = s->private;
 	int ret;
@@ -1197,7 +1209,8 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
  */
 static int
 dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned long iobase, unsigned offset, int has_clk_gat_sce)
+			unsigned long iobase, unsigned offset,
+			int has_clk_gat_sce)
 {
 	struct dio200_subdev_8254 *subpriv;
 	unsigned int chan;
@@ -1205,7 +1218,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
 	subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
 	if (!subpriv) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return -ENOMEM;
 	}
 
@@ -1224,16 +1237,16 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
 		/* Derive CLK_SCE and GAT_SCE register offsets from
 		 * 8254 offset. */
 		subpriv->clk_sce_iobase =
-			DIO200_XCLK_SCE + (offset >> 3) + iobase;
+		    DIO200_XCLK_SCE + (offset >> 3) + iobase;
 		subpriv->gat_sce_iobase =
-			DIO200_XGAT_SCE + (offset >> 3) + 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);
+			       I8254_MODE0 | I8254_BINARY);
 		if (subpriv->has_clk_gat_sce) {
 			/* Gate source 0 is VCC (logic 1). */
 			dio200_set_gate_src(subpriv, chan, 0);
@@ -1249,7 +1262,8 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
  * This function cleans up an '8254' counter subdevice.
  */
 static void
-dio200_subdev_8254_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
+dio200_subdev_8254_cleanup(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	struct dio200_subdev_intr *subpriv = s->private;
 
@@ -1280,12 +1294,12 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	int ret;
 
 	printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
-		DIO200_DRIVER_NAME);
+	       DIO200_DRIVER_NAME);
 
 	ret = alloc_private(dev, sizeof(struct dio200_private));
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 
@@ -1310,8 +1324,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 #endif
 	default:
 		printk(KERN_ERR
-			"comedi%d: %s: BUG! cannot determine board type!\n",
-			dev->minor, DIO200_DRIVER_NAME);
+		       "comedi%d: %s: BUG! cannot determine board type!\n",
+		       dev->minor, DIO200_DRIVER_NAME);
 		return -EINVAL;
 		break;
 	}
@@ -1324,8 +1338,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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);
+			       "comedi%d: error! cannot enable PCI device and request regions!\n",
+			       dev->minor);
 			return ret;
 		}
 		iobase = pci_resource_start(pci_dev, 2);
@@ -1345,7 +1359,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = alloc_subdevices(dev, layout->n_subdevs);
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 
@@ -1355,7 +1369,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		case sd_8254:
 			/* counter subdevice (8254) */
 			ret = dio200_subdev_8254_init(dev, s, iobase,
-				layout->sdinfo[n], layout->has_clk_gat_sce);
+						      layout->sdinfo[n],
+						      layout->has_clk_gat_sce);
 			if (ret < 0) {
 				return ret;
 			}
@@ -1363,7 +1378,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		case sd_8255:
 			/* digital i/o subdevice (8255) */
 			ret = subdev_8255_init(dev, s, 0,
-				iobase + layout->sdinfo[n]);
+					       iobase + layout->sdinfo[n]);
 			if (ret < 0) {
 				return ret;
 			}
@@ -1372,8 +1387,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			/* 'INTERRUPT' subdevice */
 			if (irq) {
 				ret = dio200_subdev_intr_init(dev, s,
-					iobase + DIO200_INT_SCE,
-					layout->sdinfo[n], layout->has_int_sce);
+							      iobase +
+							      DIO200_INT_SCE,
+							      layout->sdinfo[n],
+							      layout->
+							      has_int_sce);
 				if (ret < 0) {
 					return ret;
 				}
@@ -1403,8 +1421,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			dev->irq = irq;
 		} else {
 			printk(KERN_WARNING
-				"comedi%d: warning! irq %u unavailable!\n",
-				dev->minor, irq);
+			       "comedi%d: warning! irq %u unavailable!\n",
+			       dev->minor, irq);
 		}
 	}
 
@@ -1441,7 +1459,7 @@ static int dio200_detach(struct comedi_device *dev)
 	unsigned n;
 
 	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
-		DIO200_DRIVER_NAME);
+	       DIO200_DRIVER_NAME);
 
 	if (dev->irq) {
 		free_irq(dev->irq, dev);
@@ -1482,7 +1500,7 @@ static int dio200_detach(struct comedi_device *dev)
 	}
 	if (dev->board_name) {
 		printk(KERN_INFO "comedi%d: %s removed\n",
-			dev->minor, dev->board_name);
+		       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
index 48d7ccb..1032a81 100644
--- a/drivers/staging/comedi/drivers/amplc_pc236.c
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -107,36 +107,37 @@ struct pc236_board {
 };
 static const struct pc236_board pc236_boards[] = {
 	{
-	.name = "pc36at",
-	.fancy_name = "PC36AT",
-	.bustype = isa_bustype,
-	.model = pc36at_model,
-		},
+	 .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,
-		},
+	 .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 */
-		},
+	 .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}
+	{
+	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);
@@ -186,16 +187,20 @@ COMEDI_INITCLEANUP(driver_amplc_pc236);
 #endif
 
 static int pc236_request_region(unsigned minor, unsigned long from,
-	unsigned long extent);
+				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 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);
 
 /*
@@ -205,7 +210,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d);
 #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_p)
 {
 	struct pci_dev *pci_dev = NULL;
 
@@ -213,13 +218,13 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot,
 
 	/* 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)) {
+	     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))
+			    || slot != PCI_SLOT(pci_dev->devfn))
 				continue;
 		}
 		if (thisboard->model == anypci_model) {
@@ -250,11 +255,11 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot,
 	/* 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);
+		       "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);
+		       dev->minor, thisboard->name);
 	}
 	return -EIO;
 }
@@ -279,7 +284,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	int ret;
 
 	printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
-		PC236_DRIVER_NAME);
+	       PC236_DRIVER_NAME);
 /*
  * Allocate the private structure area.  alloc_private() is a
  * convenient macro defined in comedidev.h.
@@ -287,7 +292,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = alloc_private(dev, sizeof(struct pc236_private));
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 	/* Process options. */
@@ -311,8 +316,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 #endif /* CONFIG_COMEDI_PCI */
 	default:
 		printk(KERN_ERR
-			"comedi%d: %s: BUG! cannot determine board type!\n",
-			dev->minor, PC236_DRIVER_NAME);
+		       "comedi%d: %s: BUG! cannot determine board type!\n",
+		       dev->minor, PC236_DRIVER_NAME);
 		return -EINVAL;
 		break;
 	}
@@ -329,8 +334,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME);
 		if (ret < 0) {
 			printk(KERN_ERR
-				"comedi%d: error! cannot enable PCI device and request regions!\n",
-				dev->minor);
+			       "comedi%d: error! cannot enable PCI device and request regions!\n",
+			       dev->minor);
 			return ret;
 		}
 		devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
@@ -353,7 +358,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = alloc_subdevices(dev, 2);
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 
@@ -362,7 +367,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = subdev_8255_init(dev, s, NULL, iobase);
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 	s = dev->subdevices + 1;
@@ -416,7 +421,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 static int pc236_detach(struct comedi_device *dev)
 {
 	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
-		PC236_DRIVER_NAME);
+	       PC236_DRIVER_NAME);
 	if (devpriv) {
 		pc236_intr_disable(dev);
 	}
@@ -442,7 +447,7 @@ static int pc236_detach(struct comedi_device *dev)
 	}
 	if (dev->board_name) {
 		printk(KERN_INFO "comedi%d: %s removed\n",
-			dev->minor, dev->board_name);
+		       dev->minor, dev->board_name);
 	}
 	return 0;
 }
@@ -452,11 +457,11 @@ static int pc236_detach(struct comedi_device *dev)
  * if there is a conflict.
  */
 static int pc236_request_region(unsigned minor, unsigned long from,
-	unsigned long extent)
+				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);
+		       minor, from, extent);
 		return -EIO;
 	}
 	return 0;
@@ -516,13 +521,13 @@ static int pc236_intr_check(struct comedi_device *dev)
 #ifdef CONFIG_COMEDI_PCI
 		if (devpriv->lcr_iobase) {
 			if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR)
-					& PLX9052_INTCSR_LI1STAT_MASK)
-				== PLX9052_INTCSR_LI1STAT_INACTIVE) {
+			     & 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);
+				     devpriv->lcr_iobase + PLX9052_INTCSR);
 			}
 		}
 #endif
@@ -536,8 +541,9 @@ static int pc236_intr_check(struct comedi_device *dev)
  * 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)
+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;
@@ -547,8 +553,9 @@ static int pc236_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s
  * 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)
+static int pc236_intr_cmdtest(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -635,7 +642,8 @@ static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 /*
  * Subdevice 1 cancel command.
  */
-static int pc236_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int pc236_intr_cancel(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	pc236_intr_disable(dev);
 
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
index 730b677..c62a7e1 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -74,36 +74,37 @@ struct pc263_board {
 };
 static const struct pc263_board pc263_boards[] = {
 	{
-	.name = "pc263",
-	.fancy_name = "PC263",
-	.bustype = isa_bustype,
-	.model = pc263_model,
-		},
+	 .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,
-		},
+	 .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 */
-		},
+	 .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}
+	{
+	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);
@@ -145,11 +146,13 @@ static struct comedi_driver driver_amplc_pc263 = {
 };
 
 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);
+				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,
@@ -158,7 +161,7 @@ static int pc263_dio_insn_config(struct comedi_device *dev, struct comedi_subdev
 #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_p)
 {
 	struct pci_dev *pci_dev = NULL;
 
@@ -166,13 +169,13 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot,
 
 	/* 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)) {
+	     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))
+			    || slot != PCI_SLOT(pci_dev->devfn))
 				continue;
 		}
 		if (thisboard->model == anypci_model) {
@@ -203,11 +206,11 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot,
 	/* 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);
+		       "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);
+		       dev->minor, thisboard->name);
 	}
 	return -EIO;
 }
@@ -230,7 +233,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	int ret;
 
 	printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
-		PC263_DRIVER_NAME);
+	       PC263_DRIVER_NAME);
 /*
  * Allocate the private structure area.  alloc_private() is a
  * convenient macro defined in comedidev.h.
@@ -239,7 +242,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = alloc_private(dev, sizeof(struct pc263_private));
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 #endif
@@ -261,8 +264,8 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 #endif /* CONFIG_COMEDI_PCI */
 	default:
 		printk(KERN_ERR
-			"comedi%d: %s: BUG! cannot determine board type!\n",
-			dev->minor, PC263_DRIVER_NAME);
+		       "comedi%d: %s: BUG! cannot determine board type!\n",
+		       dev->minor, PC263_DRIVER_NAME);
 		return -EINVAL;
 		break;
 	}
@@ -278,8 +281,8 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME);
 		if (ret < 0) {
 			printk(KERN_ERR
-				"comedi%d: error! cannot enable PCI device and request regions!\n",
-				dev->minor);
+			       "comedi%d: error! cannot enable PCI device and request regions!\n",
+			       dev->minor);
 			return ret;
 		}
 		iobase = pci_resource_start(pci_dev, 2);
@@ -300,7 +303,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = alloc_subdevices(dev, 1);
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 
@@ -344,7 +347,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 static int pc263_detach(struct comedi_device *dev)
 {
 	printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
-		PC263_DRIVER_NAME);
+	       PC263_DRIVER_NAME);
 
 #ifdef CONFIG_COMEDI_PCI
 	if (devpriv)
@@ -366,7 +369,7 @@ static int pc263_detach(struct comedi_device *dev)
 	}
 	if (dev->board_name) {
 		printk(KERN_INFO "comedi%d: %s removed\n",
-			dev->minor, dev->board_name);
+		       dev->minor, dev->board_name);
 	}
 	return 0;
 }
@@ -376,11 +379,11 @@ static int pc263_detach(struct comedi_device *dev)
  * if there is a conflict.
  */
 static int pc263_request_region(unsigned minor, unsigned long from,
-	unsigned long extent)
+				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);
+		       minor, from, extent);
 		return -EIO;
 	}
 	return 0;
@@ -391,8 +394,9 @@ static int pc263_request_region(unsigned minor, unsigned long from,
  * 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)
+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;
@@ -416,8 +420,9 @@ static int pc263_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 	return 2;
 }
 
-static int pc263_dio_insn_config(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)
 {
 	if (insn->n != 1)
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
index d1a64e8..d983687 100644
--- a/drivers/staging/comedi/drivers/amplc_pci224.c
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -283,15 +283,15 @@ Caveats:
 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),
-		}
+	 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] = {
@@ -309,9 +309,9 @@ static const unsigned short hwrange_pci224_internal[8] = {
 static const struct comedi_lrange range_pci224_external = {
 	2,
 	{
-			RANGE_ext(-1, 1),	/* bipolar [-Vref,+Vref] */
-			RANGE_ext(0, 1),	/* unipolar [0,+Vref] */
-		}
+	 RANGE_ext(-1, 1),	/* bipolar [-Vref,+Vref] */
+	 RANGE_ext(0, 1),	/* unipolar [0,+Vref] */
+	 }
 };
 
 static const unsigned short hwrange_pci224_external[2] = {
@@ -324,8 +324,8 @@ static const unsigned short hwrange_pci224_external[2] = {
 static const struct comedi_lrange range_pci234_ext2 = {
 	1,
 	{
-			RANGE_ext(-2, 2),
-		}
+	 RANGE_ext(-2, 2),
+	 }
 };
 
 /* The hardware selectable Vref external range for PCI234
@@ -333,8 +333,8 @@ static const struct comedi_lrange range_pci234_ext2 = {
 static const struct comedi_lrange range_pci234_ext = {
 	1,
 	{
-			RANGE_ext(-1, 1),
-		}
+	 RANGE_ext(-1, 1),
+	 }
 };
 
 /* This serves for all the PCI234 ranges. */
@@ -358,24 +358,24 @@ struct pci224_board {
 
 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 = "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 = "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 */
-		},
+	 .name = DRIVER_NAME,
+	 .devid = PCI_DEVICE_ID_INVALID,
+	 .model = any_model,	/* wildcard */
+	 },
 };
 
 /*
@@ -383,11 +383,12 @@ static const struct pci224_board pci224_boards[] = {
  */
 
 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}
+	{
+	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);
@@ -428,7 +429,8 @@ struct pci224_private {
  * 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_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,
@@ -446,7 +448,8 @@ 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)
+pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
+		   unsigned int data)
 {
 	unsigned short mangled;
 
@@ -456,9 +459,10 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int
 	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));
+				  (PCI224_DACCON_POLAR_MASK |
+				   PCI224_DACCON_VREF_MASK));
 	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
-		dev->iobase + PCI224_DACCON);
+	     dev->iobase + PCI224_DACCON);
 	/*
 	 * Mangle the data.  The hardware expects:
 	 * - bipolar: 16-bit 2's complement
@@ -466,7 +470,7 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int
 	 */
 	mangled = (unsigned short)data << (16 - thisboard->ao_bits);
 	if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
-		PCI224_DACCON_POLAR_BI) {
+	    PCI224_DACCON_POLAR_BI) {
 		mangled ^= 0x8000;
 	}
 	/* Write mangled data to the FIFO. */
@@ -480,7 +484,7 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int
  */
 static int
 pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		     struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan, range;
@@ -507,7 +511,7 @@ pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
  */
 static int
 pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan;
@@ -526,7 +530,7 @@ pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
  */
 static void
 pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
-	unsigned int *nanosec, int round_mode)
+			   unsigned int *nanosec, int round_mode)
 {
 	i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
 }
@@ -534,7 +538,8 @@ pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
 /*
  * Kills a command running on the AO subdevice.
  */
-static void pci224_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pci224_ao_stop(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	unsigned long flags;
 
@@ -565,16 +570,19 @@ static void pci224_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s
 	/* 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);
+				  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);
+	     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)
+static void pci224_ao_start(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned long flags;
@@ -601,7 +609,8 @@ static void pci224_ao_start(struct comedi_device *dev, struct comedi_subdevice *
 /*
  * Handles interrupts from the DAC FIFO.
  */
-static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subdevice *s)
+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;
@@ -630,8 +639,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
 	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) {
+		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;
@@ -656,7 +664,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
 			pci224_ao_stop(dev, s);
 			s->async->events |= COMEDI_CB_OVERFLOW;
 			printk(KERN_ERR "comedi%d: "
-				"AO buffer underrun\n", dev->minor);
+			       "AO buffer underrun\n", dev->minor);
 		}
 	}
 	/* Determine how many new scans can be put in the FIFO. */
@@ -670,11 +678,10 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
 	/* Process scans. */
 	for (n = 0; n < num_scans; n++) {
 		cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
-			bytes_per_scan);
+					   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);
+			outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
+			     dev->iobase + PCI224_DACDATA);
 		}
 	}
 	if (!devpriv->ao_stop_continuous) {
@@ -685,14 +692,13 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
 			 * until FIFO is empty.
 			 */
 			devpriv->daccon = COMBINE(devpriv->daccon,
-				PCI224_DACCON_FIFOINTR_EMPTY,
-				PCI224_DACCON_FIFOINTR_MASK);
-			outw(devpriv->daccon,
-				dev->iobase + PCI224_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) {
+	    PCI224_DACCON_TRIG_NONE) {
 		unsigned short trig;
 
 		/*
@@ -718,7 +724,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
 			}
 		}
 		devpriv->daccon = COMBINE(devpriv->daccon, trig,
-			PCI224_DACCON_TRIG_MASK);
+					  PCI224_DACCON_TRIG_MASK);
 		outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
 	}
 	if (s->async->events) {
@@ -731,7 +737,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
  */
 static int
 pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+			unsigned int trignum)
 {
 	if (trignum != 0)
 		return -EINVAL;
@@ -750,7 +756,8 @@ pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
  * 'do_cmdtest' function for AO subdevice.
  */
 static int
-pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd)
+pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+		  struct comedi_cmd *cmd)
 {
 	int err = 0;
 	unsigned int tmp;
@@ -828,13 +835,13 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
 		/* Force to external trigger 0. */
 		if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
 			cmd->start_arg = COMBINE(cmd->start_arg, 0,
-				~CR_FLAGS_MASK);
+						 ~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);
+						 CR_FLAGS_MASK & ~CR_EDGE);
 			err++;
 		}
 		break;
@@ -859,14 +866,16 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
 		/* 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);
+						      ~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) {
+		     ~(CR_EDGE | CR_INVERT)) != 0) {
 			cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
-				CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+						      CR_FLAGS_MASK & ~(CR_EDGE
+									|
+									CR_INVERT));
 			err++;
 		}
 		break;
@@ -892,13 +901,13 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
 		/* Force to external trigger 0. */
 		if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
 			cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
-				~CR_FLAGS_MASK);
+						~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);
+						CR_FLAGS_MASK & ~CR_EDGE);
 		}
 		break;
 	case TRIG_NONE:
@@ -935,14 +944,14 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
 		/* Be careful to avoid overflow! */
 		div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
 		div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
-			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) {
+			    cmd->scan_begin_arg < TIMEBASE_10MHZ) {
 				/* Overflow! */
 				cmd->scan_begin_arg = MAX_SCAN_PERIOD;
 			}
@@ -951,7 +960,8 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
 			div1 = devpriv->cached_div1;
 			div2 = devpriv->cached_div2;
 			pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
-				&cmd->scan_begin_arg, round_mode);
+						   &cmd->scan_begin_arg,
+						   round_mode);
 			devpriv->cached_div1 = div1;
 			devpriv->cached_div2 = div2;
 		}
@@ -1061,12 +1071,15 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	 * 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));
+				  (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);
+	     dev->iobase + PCI224_DACCON);
 
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		unsigned int div1, div2, round;
@@ -1089,7 +1102,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		/* Be careful to avoid overflow! */
 		div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
 		div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
-			TIMEBASE_10MHZ;
+		    TIMEBASE_10MHZ;
 		if (div2 <= 0x10000) {
 			/* A single timer will suffice. */
 			if (div2 < 2)
@@ -1101,7 +1114,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			div1 = devpriv->cached_div1;
 			div2 = devpriv->cached_div2;
 			pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
-				&ns, round_mode);
+						   &ns, round_mode);
 		}
 
 		/*
@@ -1110,25 +1123,25 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		 */
 		/* Make sure Z2-0 is gated on.  */
 		outb(GAT_CONFIG(0, GAT_VCC),
-			devpriv->iobase1 + PCI224_ZGAT_SCE);
+		     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);
+			     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);
+			     devpriv->iobase1 + PCI224_ZGAT_SCE);
 			/* Z2-2 needs 10 MHz clock. */
 			outb(CLK_CONFIG(2, CLK_10MHZ),
-				devpriv->iobase1 + PCI224_ZCLK_SCE);
+			     devpriv->iobase1 + PCI224_ZCLK_SCE);
 			/* Load Z2-2 mode (2) and counter (div1). */
 			i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
-				2, div1, 2);
+				   2, div1, 2);
 			/* Z2-0 is clocked from Z2-2's output. */
 			outb(CLK_CONFIG(0, CLK_OUTNM1),
-				devpriv->iobase1 + PCI224_ZCLK_SCE);
+			     devpriv->iobase1 + PCI224_ZCLK_SCE);
 		}
 		/* Load Z2-0 mode (2) and counter (div2). */
 		i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
@@ -1174,7 +1187,8 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 /*
  * 'cancel' function for AO subdevice.
  */
-static int pci224_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int pci224_ao_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	pci224_ao_stop(dev, s);
 	return 0;
@@ -1184,8 +1198,8 @@ static int pci224_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *
  * '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)
+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;
@@ -1198,7 +1212,7 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *dat
 	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) {
+	     PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
 		/* Unipolar */
 		offset = 0;
 	} else {
@@ -1253,7 +1267,7 @@ static irqreturn_t pci224_interrupt(int irq, void *d)
 		spin_lock_irqsave(&devpriv->ao_spinlock, flags);
 		if (curenab != devpriv->intsce) {
 			outb(devpriv->intsce,
-				devpriv->iobase1 + PCI224_INT_SCE);
+			     devpriv->iobase1 + PCI224_INT_SCE);
 		}
 		devpriv->intr_running = 0;
 		spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
@@ -1267,7 +1281,7 @@ static irqreturn_t pci224_interrupt(int irq, void *d)
  */
 static int
 pci224_find_pci(struct comedi_device *dev, int bus, int slot,
-	struct pci_dev **pci_dev_p)
+		struct pci_dev **pci_dev_p)
 {
 	struct pci_dev *pci_dev = NULL;
 
@@ -1275,13 +1289,13 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot,
 
 	/* 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)) {
+	     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))
+			    || slot != PCI_SLOT(pci_dev->devfn))
 				continue;
 		}
 		if (thisboard->model == any_model) {
@@ -1310,11 +1324,11 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot,
 	/* 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);
+		       "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);
+		       dev->minor, thisboard->name);
 	}
 	return -EIO;
 }
@@ -1341,7 +1355,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = alloc_private(dev, sizeof(struct pci224_private));
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 
@@ -1353,8 +1367,8 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
 	if (ret < 0) {
 		printk(KERN_ERR
-			"comedi%d: error! cannot enable PCI device "
-			"and request regions!\n", dev->minor);
+		       "comedi%d: error! cannot enable PCI device "
+		       "and request regions!\n", dev->minor);
 		return ret;
 	}
 	spin_lock_init(&devpriv->ao_spinlock);
@@ -1365,21 +1379,21 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	/* Allocate readback buffer for AO channels. */
 	devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
-		thisboard->ao_chans, GFP_KERNEL);
+				       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);
+					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);
+					 thisboard->ao_chans, GFP_KERNEL);
 	if (!devpriv->ao_scan_order) {
 		return -ENOMEM;
 	}
@@ -1393,15 +1407,16 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+			   PCI224_DACCON_FIFOENAB |
+			   PCI224_DACCON_FIFOINTR_EMPTY);
 	outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
-		dev->iobase + PCI224_DACCON);
+	     dev->iobase + PCI224_DACCON);
 
 	/* Allocate subdevices.  There is only one!  */
 	ret = alloc_subdevices(dev, 1);
 	if (ret < 0) {
 		printk(KERN_ERR "comedi%d: error! out of memory!\n",
-			dev->minor);
+		       dev->minor);
 		return ret;
 	}
 
@@ -1427,22 +1442,22 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		const struct comedi_lrange **range_table_list;
 
 		s->range_table_list = range_table_list =
-			kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
-			GFP_KERNEL);
+		    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]);
+				       "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) {
+			    it->options[3 + n] == 1) {
 				if (it->options[2] == 1) {
 					range_table_list[n] = &range_pci234_ext;
 				} else {
@@ -1451,7 +1466,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			} else {
 				if (it->options[2] == 1) {
 					range_table_list[n] =
-						&range_pci234_ext2;
+					    &range_pci234_ext2;
 				} else {
 					range_table_list[n] = &range_bipolar10;
 				}
@@ -1466,9 +1481,8 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		} 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]);
+				       "bad options[2]=%d\n",
+				       dev->minor, DRIVER_NAME, it->options[2]);
 			}
 			s->range_table = &range_pci224_internal;
 			devpriv->hwrange = hwrange_pci224_internal;
@@ -1482,7 +1496,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 				  DRIVER_NAME, dev);
 		if (ret < 0) {
 			printk(KERN_ERR "comedi%d: error! "
-				"unable to allocate irq %u\n", dev->minor, irq);
+			       "unable to allocate irq %u\n", dev->minor, irq);
 			return ret;
 		} else {
 			dev->irq = irq;
@@ -1545,7 +1559,7 @@ static int pci224_detach(struct comedi_device *dev)
 	}
 	if (dev->board_name) {
 		printk(KERN_INFO "comedi%d: %s removed\n",
-			dev->minor, dev->board_name);
+		       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
index 21133f0..091a1a5 100644
--- a/drivers/staging/comedi/drivers/amplc_pci230.c
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -457,62 +457,63 @@ struct pci230_board {
 };
 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 = "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 = "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 = "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 = "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,
-		},
+	 .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}
+	{
+	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 n_pci230_boards ARRAY_SIZE(pci230_boards)
 #define thisboard ((const struct pci230_board *)dev->board_ptr)
 
 /* this structure is for data unique to this hardware driver.  If
@@ -571,14 +572,14 @@ static const unsigned int pci230_timebase[8] = {
 
 /* 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)
-	}
+							  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. */
@@ -589,9 +590,9 @@ 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)
-	}
+							  UNI_RANGE(10),
+							  BIP_RANGE(10)
+							  }
 };
 
 /* PCI230 daccon bipolar flag for each analogue output range. */
@@ -603,7 +604,8 @@ static const unsigned char pci230_ao_bipolar[2] = { 0, 1 };
  * 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_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",
@@ -617,35 +619,48 @@ static struct comedi_driver driver_amplc_pci230 = {
 
 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 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);
+				    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);
-static int pci230_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd);
+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_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 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);
+	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). */
@@ -661,7 +676,7 @@ static short pci230_ai_read(struct comedi_device *dev)
 }
 
 static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
-	short datum)
+						    short datum)
 {
 	/* If a bipolar range was specified, mangle it (straight binary->twos
 	 * complement). */
@@ -676,26 +691,28 @@ static inline unsigned short pci230_ao_mangle_datum(struct comedi_device *dev,
 	return (unsigned short)datum;
 }
 
-static inline void pci230_ao_write_nofifo(struct comedi_device *dev, short datum,
-	unsigned int chan)
+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));
+								? PCI230_DACOUT1
+								:
+								PCI230_DACOUT2));
 }
 
 static inline void pci230_ao_write_fifo(struct comedi_device *dev, short datum,
-	unsigned int chan)
+					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);
+	     dev->iobase + PCI230P2_DACDATA);
 }
 
 /*
@@ -713,7 +730,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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]);
+	       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. */
@@ -726,12 +743,12 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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)) {
+	     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))
+			    it->options[1] != PCI_SLOT(pci_dev->devfn))
 				continue;
 		}
 		if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
@@ -748,7 +765,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 						 * First check length of
 						 * registers. */
 						if (pci_resource_len(pci_dev, 3)
-							< 32) {
+						    < 32) {
 							/* Not a '+' model. */
 							continue;
 						}
@@ -790,7 +807,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 	if (!pci_dev) {
 		printk("comedi%d: No %s card found\n", dev->minor,
-			thisboard->name);
+		       thisboard->name);
 		return -EIO;
 	}
 	devpriv->pci_dev = pci_dev;
@@ -803,7 +820,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* 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);
+		       "and request regions\n", dev->minor);
 		return -EIO;
 	}
 
@@ -813,7 +830,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+	       dev->minor, dev->board_name, iobase1, iobase2);
 
 	devpriv->iobase1 = iobase1;
 	dev->iobase = iobase2;
@@ -829,9 +846,9 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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);
+			       "- got %u, need %u\n", dev->minor,
+			       dev->board_name, devpriv->hwver,
+			       thisboard->min_hwver);
 			return -EIO;
 		}
 		if (devpriv->hwver > 0) {
@@ -844,7 +861,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 				extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
 			}
 			if ((thisboard->ao_chans > 0)
-				&& (devpriv->hwver >= 2)) {
+			    && (devpriv->hwver >= 2)) {
 				/* Enable DAC FIFO functionality. */
 				extfunc |= PCI230P2_EXTFUNC_DACFIFO;
 			}
@@ -854,8 +871,8 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			/* 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);
+			     | PCI230P2_DAC_FIFO_RESET,
+			     dev->iobase + PCI230_DACCON);
 			/* Clear DAC FIFO channel enable register. */
 			outw(0, dev->iobase + PCI230P2_DACEN);
 			/* Disable DAC FIFO. */
@@ -869,23 +886,23 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* Set ADC to a reasonable state. */
 	devpriv->adcg = 0;
 	devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
-		| PCI230_ADC_IR_BIP;
+	    | 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);
+	     dev->iobase + PCI230_ADCCON);
 
 	/* Register the interrupt handler. */
 	irq_hdl = 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);
+		       "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);
+		       devpriv->pci_dev->irq);
 	}
 
 	/*
@@ -941,7 +958,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* digital i/o subdevice */
 	if (thisboard->have_dio) {
 		rc = subdev_8255_init(dev, s, NULL,
-			(devpriv->iobase1 + PCI230_PPI_X_BASE));
+				      (devpriv->iobase1 + PCI230_PPI_X_BASE));
 		if (rc < 0)
 			return rc;
 	} else {
@@ -985,7 +1002,7 @@ static int pci230_detach(struct comedi_device *dev)
 }
 
 static int get_resources(struct comedi_device *dev, unsigned int res_mask,
-	unsigned char owner)
+			 unsigned char owner)
 {
 	int ok;
 	unsigned int i;
@@ -997,7 +1014,7 @@ static int get_resources(struct comedi_device *dev, unsigned int res_mask,
 	claimed = 0;
 	spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
 	for (b = 1, i = 0; (i < NUM_RESOURCES)
-		&& (res_mask != 0); b <<= 1, i++) {
+	     && (res_mask != 0); b <<= 1, i++) {
 		if ((res_mask & b) != 0) {
 			res_mask &= ~b;
 			if (devpriv->res_owner[i] == OWNER_NONE) {
@@ -1007,7 +1024,7 @@ static int get_resources(struct comedi_device *dev, unsigned int res_mask,
 				for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
 					if ((claimed & b) != 0) {
 						devpriv->res_owner[i]
-							= OWNER_NONE;
+						    = OWNER_NONE;
 						claimed &= ~b;
 					}
 				}
@@ -1020,14 +1037,14 @@ static int get_resources(struct comedi_device *dev, unsigned int res_mask,
 	return ok;
 }
 
-static inline int get_one_resource(struct comedi_device *dev, unsigned int resource,
-	unsigned char owner)
+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 char owner)
 {
 	unsigned int i;
 	unsigned int b;
@@ -1035,7 +1052,7 @@ static void put_resources(struct comedi_device *dev, unsigned int res_mask,
 
 	spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
 	for (b = 1, i = 0; (i < NUM_RESOURCES)
-		&& (res_mask != 0); b <<= 1, i++) {
+	     && (res_mask != 0); b <<= 1, i++) {
 		if ((res_mask & b) != 0) {
 			res_mask &= ~b;
 			if (devpriv->res_owner[i] == owner) {
@@ -1046,13 +1063,14 @@ static void put_resources(struct comedi_device *dev, unsigned int res_mask,
 	spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
 }
 
-static inline void put_one_resource(struct comedi_device *dev, unsigned int resource,
-	unsigned char owner)
+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)
+static inline void put_all_resources(struct comedi_device *dev,
+				     unsigned char owner)
 {
 	put_resources(dev, (1U << NUM_RESOURCES) - 1, owner);
 }
@@ -1060,8 +1078,9 @@ static inline void put_all_resources(struct comedi_device *dev, unsigned char ow
 /*
  *  COMEDI_SUBD_AI instruction;
  */
-static int pci230_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -1112,7 +1131,7 @@ static int pci230_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 		adccon |= PCI230_ADC_IM_SE;
 	}
 	devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
-		| (pci230_ai_gain[range] << gainshift);
+	    | (pci230_ai_gain[range] << gainshift);
 	if (devpriv->ai_bipolar) {
 		adccon |= PCI230_ADC_IR_BIP;
 	} else {
@@ -1135,9 +1154,9 @@ static int pci230_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 		/* 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_MODE0);
 		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
-			I8254_MODE1);
+			       I8254_MODE1);
 
 #define TIMEOUT 100
 		/* wait for conversion to end */
@@ -1165,8 +1184,9 @@ static int pci230_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 /*
  *  COMEDI_SUBD_AO instructions;
  */
-static int pci230_ao_winsn(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)
 {
 	int i;
 	int chan, range;
@@ -1193,8 +1213,9 @@ static int pci230_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s
 
 /* 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)
+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);
@@ -1205,8 +1226,8 @@ static int pci230_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 	return i;
 }
 
-static int pci230_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int pci230_ao_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	unsigned int tmp;
@@ -1317,17 +1338,16 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 		/* 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);
+						      ~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) {
+		     & (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));
+			    COMBINE(cmd->scan_begin_arg, 0,
+				    CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
 			err++;
 		}
 		break;
@@ -1361,7 +1381,7 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	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);
+					  cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
@@ -1419,7 +1439,8 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 }
 
 static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
-	struct comedi_subdevice *s, unsigned int trig_num)
+					struct comedi_subdevice *s,
+					unsigned int trig_num)
 {
 	unsigned long irqflags;
 
@@ -1431,16 +1452,16 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
 		/* Perform scan. */
 		if (devpriv->hwver < 2) {
 			/* Not using DAC FIFO. */
-			spin_unlock_irqrestore(&devpriv->
-				ao_stop_spinlock, irqflags);
+			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);
-			spin_unlock_irqrestore(&devpriv->
-				ao_stop_spinlock, irqflags);
+			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. */
@@ -1450,7 +1471,8 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev,
 	return 1;
 }
 
-static void pci230_ao_start(struct comedi_device *dev, struct comedi_subdevice *s)
+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;
@@ -1499,7 +1521,8 @@ static void pci230_ao_start(struct comedi_device *dev, struct comedi_subdevice *
 				break;
 			}
 			devpriv->daccon = (devpriv->daccon
-				& ~PCI230P2_DAC_TRIG_MASK) | scantrig;
+					   & ~PCI230P2_DAC_TRIG_MASK) |
+			    scantrig;
 			outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
 
 		}
@@ -1509,17 +1532,17 @@ static void pci230_ao_start(struct comedi_device *dev, struct comedi_subdevice *
 				/* Not using DAC FIFO. */
 				/* Enable CT1 timer interrupt. */
 				spin_lock_irqsave(&devpriv->isr_spinlock,
-					irqflags);
+						  irqflags);
 				devpriv->int_en |= PCI230_INT_ZCLK_CT1;
 				devpriv->ier |= PCI230_INT_ZCLK_CT1;
 				outb(devpriv->ier,
-					devpriv->iobase1 + PCI230_INT_SCE);
-				spin_unlock_irqrestore(&devpriv->
-					isr_spinlock, irqflags);
+				     devpriv->iobase1 + PCI230_INT_SCE);
+				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);
+			     devpriv->iobase1 + PCI230_ZGAT_SCE);
 			break;
 		case TRIG_INT:
 			async->inttrig = pci230_ao_inttrig_scan_begin;
@@ -1527,19 +1550,19 @@ static void pci230_ao_start(struct comedi_device *dev, struct comedi_subdevice *
 		}
 		if (devpriv->hwver >= 2) {
 			/* Using DAC FIFO.  Enable DAC FIFO interrupt. */
-			spin_lock_irqsave(&devpriv->isr_spinlock,
-				irqflags);
+			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);
 			spin_unlock_irqrestore(&devpriv->isr_spinlock,
-				irqflags);
+					       irqflags);
 		}
 	}
 }
 
-static int pci230_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trig_num)
+static int pci230_ao_inttrig_start(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   unsigned int trig_num)
 {
 	if (trig_num != 0)
 		return -EINVAL;
@@ -1600,24 +1623,25 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		 * 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;
+		    | 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);
+	    & ~(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);
+		     devpriv->iobase1 + PCI230_ZGAT_SCE);
 		pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
-			cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+					cmd->scan_begin_arg,
+					cmd->flags & TRIG_ROUND_MASK);
 	}
 
 	/* N.B. cmd->start_src == TRIG_INT */
@@ -1637,7 +1661,7 @@ static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
 	}
 	min_scan_period = chanlist_len * cmd->convert_arg;
 	if ((min_scan_period < chanlist_len)
-		|| (min_scan_period < cmd->convert_arg)) {
+	    || (min_scan_period < cmd->convert_arg)) {
 		/* Arithmetic overflow. */
 		min_scan_period = UINT_MAX;
 		err++;
@@ -1650,8 +1674,8 @@ static int pci230_ai_check_scan_period(struct comedi_cmd *cmd)
 	return !err;
 }
 
-static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int pci230_ai_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	unsigned int tmp;
@@ -1679,7 +1703,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	 * 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;
+		    | TRIG_EXT;
 	} else {
 		cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
 	}
@@ -1723,7 +1747,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	/* 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))
+	    && (cmd->convert_src != TRIG_TIMER))
 		err++;
 
 	if (err)
@@ -1788,17 +1812,17 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 			/* Trigger number must be 0. */
 			if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
 				cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
-					~CR_FLAGS_MASK);
+							   ~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) {
+			    != CR_EDGE) {
 				/* Set CR_EDGE, preserve CR_INVERT. */
 				cmd->convert_arg =
-					COMBINE(cmd->start_arg, (CR_EDGE | 0),
-					CR_FLAGS_MASK & ~CR_INVERT);
+				    COMBINE(cmd->start_arg, (CR_EDGE | 0),
+					    CR_FLAGS_MASK & ~CR_INVERT);
 				err++;
 			}
 		} else {
@@ -1836,13 +1860,13 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 		 * 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);
+						      ~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);
+						      CR_FLAGS_MASK & ~CR_EDGE);
 			err++;
 		}
 	} else if (cmd->scan_begin_src == TRIG_TIMER) {
@@ -1867,7 +1891,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	if (cmd->convert_src == TRIG_TIMER) {
 		tmp = cmd->convert_arg;
 		pci230_ns_to_single_timer(&cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+					  cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->convert_arg)
 			err++;
 	}
@@ -1876,11 +1900,11 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 		/* 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);
+					  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);
+						  TRIG_ROUND_UP);
 			pci230_ai_check_scan_period(cmd);
 		}
 		if (tmp != cmd->scan_begin_arg)
@@ -1921,20 +1945,19 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 			 * differential.  (These are remapped in software.  In
 			 * hardware, only the even channels are available.) */
 			if ((aref == AREF_DIFF)
-				&& (chan >= (s->n_chan / 2))) {
+			    && (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 == 0)) {
 					subseq_len = n;
 				}
 				if ((subseq_len > 0)
-					&& (cmd->chanlist[n] !=
-						cmd->chanlist[n %
-							subseq_len])) {
+				    && (cmd->chanlist[n] !=
+					cmd->chanlist[n % subseq_len])) {
 					errors |= seq_err;
 				}
 				/* Channels must have same AREF. */
@@ -1948,8 +1971,8 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 				/* Single-ended channel pairs must have same
 				 * range.  */
 				if ((aref != AREF_DIFF)
-					&& (((chan ^ prev_chan) & ~1) == 0)
-					&& (range != prev_range)) {
+				    && (((chan ^ prev_chan) & ~1) == 0)
+				    && (range != prev_range)) {
 					errors |= rangepair_err;
 				}
 			}
@@ -1983,7 +2006,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 			 * does, and we can't tell them apart!
 			 */
 			if ((subseq_len > 1)
-				&& (CR_CHAN(cmd->chanlist[0]) != 0)) {
+			    && (CR_CHAN(cmd->chanlist[0]) != 0)) {
 				errors |= buggy_chan0_err;
 			}
 		}
@@ -2021,11 +2044,11 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 			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);
+				       "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);
 			}
 		}
 	}
@@ -2037,7 +2060,7 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 }
 
 static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
-	struct comedi_subdevice *s)
+						struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int scanlen = cmd->scan_end_arg;
@@ -2050,13 +2073,12 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
 		wake = scanlen - devpriv->ai_scan_pos;
 	} else {
 		if (devpriv->ai_continuous
-			|| (devpriv->ai_scan_count
-				>= PCI230_ADC_FIFOLEVEL_HALFFULL)
-			|| (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+		    || (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;
+			    - devpriv->ai_scan_pos;
 		}
 	}
 	if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
@@ -2080,8 +2102,9 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev,
 	}
 }
 
-static int pci230_ai_inttrig_convert(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trig_num)
+static int pci230_ai_inttrig_convert(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     unsigned int trig_num)
 {
 	unsigned long irqflags;
 
@@ -2095,36 +2118,35 @@ static int pci230_ai_inttrig_convert(struct comedi_device *dev, struct comedi_su
 		/* 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_MODE0);
 		i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
-			I8254_MODE1);
+			       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_ADC_IM_DIF)
+		    && (devpriv->hwver == 0)) {
 			/* PCI230/260 in differential mode */
 			delayus = 8;
 		} else {
 			/* single-ended or PCI230+/260+ */
 			delayus = 4;
 		}
-		spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
-			irqflags);
+		spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
 		udelay(delayus);
 	} else {
-		spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
-			irqflags);
+		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)
+					struct comedi_subdevice *s,
+					unsigned int trig_num)
 {
 	unsigned long irqflags;
 	unsigned char zgat;
@@ -2145,7 +2167,8 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev,
 	return 1;
 }
 
-static void pci230_ai_start(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pci230_ai_start(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	unsigned long irqflags;
 	unsigned short conv;
@@ -2203,7 +2226,7 @@ static void pci230_ai_start(struct comedi_device *dev, struct comedi_subdevice *
 			break;
 		}
 		devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
-			| conv;
+		    | conv;
 		outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
 		if (cmd->convert_src == TRIG_INT) {
 			async->inttrig = pci230_ai_inttrig_convert;
@@ -2267,11 +2290,11 @@ static void pci230_ai_start(struct comedi_device *dev, struct comedi_subdevice *
 					 * gated on to start counting. */
 					zgat = GAT_CONFIG(1, GAT_VCC);
 					outb(zgat, devpriv->iobase1
-						+ PCI230_ZGAT_SCE);
+					     + PCI230_ZGAT_SCE);
 					break;
 				case TRIG_INT:
 					async->inttrig =
-						pci230_ai_inttrig_scan_begin;
+					    pci230_ai_inttrig_scan_begin;
 					break;
 				}
 			}
@@ -2282,8 +2305,9 @@ static void pci230_ai_start(struct comedi_device *dev, struct comedi_subdevice *
 	}
 }
 
-static int pci230_ai_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trig_num)
+static int pci230_ai_inttrig_start(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   unsigned int trig_num)
 {
 	if (trig_num != 0)
 		return -EINVAL;
@@ -2394,7 +2418,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			adcen |= 1 << chan;
 		}
 		devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
-			| (pci230_ai_gain[range] << gainshift);
+		    | (pci230_ai_gain[range] << gainshift);
 	}
 
 	/* Set channel scan list. */
@@ -2439,7 +2463,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		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);
+					cmd->flags & TRIG_ROUND_MASK);
 		if (cmd->scan_begin_src != TRIG_FOLLOW) {
 			/*
 			 * Set up monostable on CT0 output for scan timing.  A
@@ -2456,8 +2480,9 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			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);
+						((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
@@ -2468,8 +2493,10 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 				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);
+							cmd->scan_begin_arg,
+							cmd->
+							flags &
+							TRIG_ROUND_MASK);
 			}
 		}
 	}
@@ -2485,7 +2512,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
-	unsigned int round_mode)
+			      unsigned int round_mode)
 {
 	uint64_t div;
 	unsigned int rem;
@@ -2510,7 +2537,7 @@ static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
 /* 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 round_mode)
 {
 	unsigned int clk_src, cnt;
 
@@ -2535,7 +2562,8 @@ static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
 }
 
 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 mode, uint64_t ns,
+				    unsigned int round)
 {
 	unsigned int clk_src;
 	unsigned int count;
@@ -2556,7 +2584,7 @@ static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct,
 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);
+		       I8254_MODE1);
 	/* Counter ct, 8254 mode 1, initial count not written. */
 }
 
@@ -2564,7 +2592,7 @@ static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct)
 static irqreturn_t pci230_interrupt(int irq, void *d)
 {
 	unsigned char status_int, valid_status_int;
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 	unsigned long irqflags;
 
@@ -2624,7 +2652,8 @@ static irqreturn_t pci230_interrupt(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pci230_handle_ao_nofifo(struct comedi_device *dev,
+				    struct comedi_subdevice *s)
 {
 	short data;
 	int i, ret;
@@ -2661,7 +2690,8 @@ static void pci230_handle_ao_nofifo(struct comedi_device *dev, struct comedi_sub
 
 /* 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)
+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;
@@ -2699,7 +2729,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, struct comedi_subdev
 		 * (otherwise there will be loads of "DAC FIFO not half full"
 		 * interrupts). */
 		if ((num_scans == 0)
-			&& ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
+		    && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
 			comedi_error(dev, "AO buffer underrun");
 			events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
 		}
@@ -2728,7 +2758,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, struct comedi_subdev
 
 				comedi_buf_get(async, &datum);
 				pci230_ao_write_fifo(dev, datum,
-					CR_CHAN(cmd->chanlist[i]));
+						     CR_CHAN(cmd->chanlist[i]));
 			}
 		}
 		events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
@@ -2739,10 +2769,11 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, struct comedi_subdev
 				 * to FIFO.  Set FIFO interrupt trigger level
 				 * to 'empty'. */
 				devpriv->daccon = (devpriv->daccon
-					& ~PCI230P2_DAC_INT_FIFO_MASK)
-					| PCI230P2_DAC_INT_FIFO_EMPTY;
+						   &
+						   ~PCI230P2_DAC_INT_FIFO_MASK)
+				    | PCI230P2_DAC_INT_FIFO_EMPTY;
 				outw(devpriv->daccon,
-					dev->iobase + PCI230_DACCON);
+				     dev->iobase + PCI230_DACCON);
 			}
 		}
 		/* Check if FIFO underrun occurred while writing to FIFO. */
@@ -2753,7 +2784,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, struct comedi_subdev
 		}
 	}
 	if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
-		!= 0) {
+	    != 0) {
 		/* Stopping AO due to completion or error. */
 		pci230_ao_stop(dev, s);
 		running = 0;
@@ -2764,7 +2795,8 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, struct comedi_subdev
 	return running;
 }
 
-static void pci230_handle_ai(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pci230_handle_ai(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	unsigned int events = 0;
 	unsigned int status_fifo;
@@ -2780,11 +2812,11 @@ static void pci230_handle_ai(struct comedi_device *dev, struct comedi_subdevice
 	} else if (devpriv->ai_scan_count == 0) {
 		todo = 0;
 	} else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
-		|| (scanlen > 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;
+		    - devpriv->ai_scan_pos;
 		if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) {
 			todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
 		}
@@ -2817,7 +2849,7 @@ static void pci230_handle_ai(struct comedi_device *dev, struct comedi_subdevice
 				if (devpriv->hwver > 0) {
 					/* Read PCI230+/260+ ADC FIFO level. */
 					fifoamount = inw(dev->iobase
-						+ PCI230P_ADCFFLEV);
+							 + PCI230P_ADCFFLEV);
 					if (fifoamount == 0) {
 						/* Shouldn't happen. */
 						break;
@@ -2854,7 +2886,7 @@ static void pci230_handle_ai(struct comedi_device *dev, struct comedi_subdevice
 	async->events |= events;
 
 	if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
-				COMEDI_CB_OVERFLOW)) != 0) {
+			      COMEDI_CB_OVERFLOW)) != 0) {
 		/* disable hardware conversions */
 		pci230_ai_stop(dev, s);
 	} else {
@@ -2863,7 +2895,8 @@ static void pci230_handle_ai(struct comedi_device *dev, struct comedi_subdevice
 	}
 }
 
-static void pci230_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pci230_ao_stop(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	unsigned long irqflags;
 	unsigned char intsrc;
@@ -2910,21 +2943,23 @@ static void pci230_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s
 		 * disable FIFO. */
 		devpriv->daccon &= PCI230_DAC_OR_MASK;
 		outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
-			| PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
-			dev->iobase + PCI230_DACCON);
+		     | 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)
+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)
+static void pci230_ai_stop(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	unsigned long irqflags;
 	struct comedi_cmd *cmd;
@@ -2964,15 +2999,17 @@ static void pci230_ai_stop(struct comedi_device *dev, struct comedi_subdevice *s
 	/* 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;
+					      | PCI230_ADC_IM_MASK)) |
+	    PCI230_ADC_TRIG_NONE;
 	outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
-		dev->iobase + PCI230_ADCCON);
+	     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)
+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
index b204793..abb0532 100644
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -97,7 +97,8 @@ union encvaluetype {
 
 #define C6XDIGIO_TIME_OUT 20
 
-static int c6xdigio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -114,28 +115,28 @@ static void C6X_pwmInit(unsigned long baseAddr)
 
 	WriteByteToHwPort(baseAddr, 0x70);
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (timeout < C6XDIGIO_TIME_OUT)) {
 		timeout++;
 	}
 
 	WriteByteToHwPort(baseAddr, 0x74);
 	timeout = 0;
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (timeout < C6XDIGIO_TIME_OUT)) {
 		timeout++;
 	}
 
 	WriteByteToHwPort(baseAddr, 0x70);
 	timeout = 0;
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (timeout < C6XDIGIO_TIME_OUT)) {
 		timeout++;
 	}
 
 	WriteByteToHwPort(baseAddr, 0x0);
 	timeout = 0;
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (timeout < C6XDIGIO_TIME_OUT)) {
 		timeout++;
 	}
 
@@ -315,38 +316,41 @@ static void C6X_encResetAll(unsigned long baseAddr)
 
 	WriteByteToHwPort(baseAddr, 0x68);
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (timeout < C6XDIGIO_TIME_OUT)) {
 		timeout++;
 	}
 	WriteByteToHwPort(baseAddr, 0x6C);
 	timeout = 0;
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (timeout < C6XDIGIO_TIME_OUT)) {
 		timeout++;
 	}
 	WriteByteToHwPort(baseAddr, 0x68);
 	timeout = 0;
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (timeout < C6XDIGIO_TIME_OUT)) {
 		timeout++;
 	}
 	WriteByteToHwPort(baseAddr, 0x0);
 	timeout = 0;
 	while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
-		&& (timeout < C6XDIGIO_TIME_OUT)) {
+	       && (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)
+				   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)
+				    struct comedi_subdevice *s,
+				    struct comedi_insn *insn,
+				    unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -375,12 +379,13 @@ static int c6xdigio_pwmo_insn_write(struct comedi_device *dev,
 /* { */
 /* int i; */
 /* int chan = CR_CHAN(insn->chanspec); */
-/*  *//* C6X_encResetAll( dev->iobase ); */
-/*  *//* return insn->n; */
+      /*  *//* 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)
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 	/*   printk("c6xdigio_ei__insn_read %x\n", insn->n); */
 	int n;
@@ -415,9 +420,9 @@ static void board_init(struct comedi_device *dev)
 
 static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
 	/* Standard LPT Printer Port */
-	{.id = "PNP0400", .driver_data = 0},
+	{.id = "PNP0400",.driver_data = 0},
 	/* ECP Printer Port */
-	{.id = "PNP0401", .driver_data = 0},
+	{.id = "PNP0401",.driver_data = 0},
 	{}
 };
 
@@ -426,7 +431,8 @@ static struct pnp_driver c6xdigio_pnp_driver = {
 	.id_table = c6xdigio_pnp_tbl,
 };
 
-static int c6xdigio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int c6xdigio_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	int result = 0;
 	unsigned long iobase;
@@ -478,7 +484,7 @@ static int c6xdigio_attach(struct comedi_device *dev, struct comedi_devconfig *i
 	s->range_table = &range_unknown;
 
 	/*           s = dev->subdevices + 2; */
-	      /* pwm output subdevice */
+	/* pwm output subdevice */
 	/*       s->type = COMEDI_SUBD_COUNTER;  // Not sure what to put here */
 	/*       s->subdev_flags = SDF_WRITEABLE; */
 	/*       s->n_chan = 1; */
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 7af245b..12d12b4 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -62,23 +62,23 @@ struct das16cs_board {
 };
 static const struct das16cs_board das16cs_boards[] = {
 	{
-	.device_id = 0x0000,/* unknown */
-	.name = "PC-CARD DAS16/16",
-	.n_ao_chans = 0,
-		},
+	 .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 = 0x0039,
+	 .name = "PC-CARD DAS16/16-AO",
+	 .n_ao_chans = 2,
+	 },
 	{
-	.device_id = 0x4009,
-	.name = "PCM-DAS16s/16",
-	.n_ao_chans = 0,
-		},
+	 .device_id = 0x4009,
+	 .name = "PCM-DAS16s/16",
+	 .n_ao_chans = 0,
+	 },
 };
 
-#define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0]))
+#define n_boards ARRAY_SIZE(das16cs_boards)
 #define thisboard ((const struct das16cs_board *)dev->board_ptr)
 
 struct das16cs_private {
@@ -90,7 +90,8 @@ struct das16cs_private {
 };
 #define devpriv ((struct das16cs_private *)dev->private)
 
-static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -102,31 +103,43 @@ static struct comedi_driver driver_das16cs = {
 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),
-	}
+							   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);
-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 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)
 {
@@ -140,15 +153,15 @@ static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
 	tuple.DesiredTuple = CISTPL_MANFID;
 	tuple.Attributes = TUPLE_RETURN_COMMON;
 	if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
-		(pcmcia_get_tuple_data(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)
+static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
+						 struct pcmcia_device *link)
 {
 	int id;
 	int i;
@@ -166,7 +179,8 @@ static const struct das16cs_board *das16cs_probe(struct comedi_device * dev,
 	return NULL;
 }
 
-static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int das16cs_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct pcmcia_device *link;
 	struct comedi_subdevice *s;
@@ -287,8 +301,9 @@ static irqreturn_t das16cs_interrupt(int irq, void *d)
  * "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)
+static int das16cs_ai_rinsn(struct comedi_device *dev,
+			    struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int to;
@@ -334,8 +349,9 @@ 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)
+static int das16cs_ai_cmdtest(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -381,7 +397,7 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 	/* note that mutual compatiblity is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
-		cmd->scan_begin_src != TRIG_EXT)
+	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
 	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
 		err++;
@@ -463,7 +479,8 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 		tmp = cmd->scan_begin_arg;
 		i8253_cascade_ns_to_timer(100, &div1, &div2,
-			&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+					  &cmd->scan_begin_arg,
+					  cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
@@ -472,14 +489,15 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 		tmp = cmd->convert_arg;
 		i8253_cascade_ns_to_timer(100, &div1, &div2,
-			&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+					  &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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->scan_end_arg;
+			    cmd->convert_arg * cmd->scan_end_arg;
 			err++;
 		}
 	}
@@ -490,8 +508,9 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	return 0;
 }
 
-static int das16cs_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -536,8 +555,9 @@ static int das16cs_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
 
 /* 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)
+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);
@@ -553,8 +573,9 @@ static int das16cs_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
  * 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)
+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;
@@ -573,8 +594,9 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 	return 2;
 }
 
-static int das16cs_dio_insn_config(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)
 {
 	int chan = CR_CHAN(insn->chanspec);
 	int bits;
@@ -593,8 +615,7 @@ static int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subd
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -611,14 +632,17 @@ static int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subd
 	return insn->n;
 }
 
-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_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)
+static int das16cs_timer_insn_config(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     struct comedi_insn *insn,
+				     unsigned int *data)
 {
 	return -EINVAL;
 }
@@ -650,7 +674,7 @@ 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)";
+    "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
@@ -739,7 +763,7 @@ 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;
+		((struct local_info_t *)link->priv)->stop = 1;
 		das16cs_pcmcia_release(link);
 	}
 	/* This points to the parent struct local_info_t struct */
@@ -853,7 +877,7 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
 		/* If we got this far, we're cool! */
 		break;
 
-	      next_entry:
+next_entry:
 		last_fn = GetNextTuple;
 
 		last_ret = pcmcia_get_next_tuple(link, &tuple);
@@ -893,20 +917,20 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x",
-		dev->node.dev_name, link->conf.ConfigIndex);
+	       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);
+		       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);
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
 	printk("\n");
 
 	return;
 
-      cs_failed:
+cs_failed:
 	cs_error(link, last_fn, last_ret);
 	das16cs_pcmcia_release(link);
 }				/* das16cs_pcmcia_config */
@@ -953,7 +977,7 @@ struct pcmcia_driver das16cs_driver = {
 	.id_table = das16cs_id_table,
 	.owner = THIS_MODULE,
 	.drv = {
-			.name = dev_info,
+		.name = dev_info,
 		},
 };
 
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index 702de15..f3e66c4 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -156,6 +156,7 @@ 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));
@@ -200,41 +201,41 @@ static inline unsigned int DAC_DATA_REG(unsigned int channel)
 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)
-		}
+	 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)
-		}
+	 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),
-		}
+	 BIP_RANGE(5),
+	 BIP_RANGE(10),
+	 UNI_RANGE(5),
+	 UNI_RANGE(10),
+	 }
 };
 
 enum trimpot_model {
@@ -260,131 +261,132 @@ struct cb_pcidas_board {
 
 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-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-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-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-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-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-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-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,
-		},
+	 .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,
+	 },
 };
 
 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}
+	{
+	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);
@@ -438,7 +440,8 @@ struct cb_pcidas_private {
  * 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_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",
@@ -447,55 +450,75 @@ static struct comedi_driver driver_cb_pcidas = {
 	.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 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);
+			  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 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);
 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 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);
+				    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 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);
+			     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);
+			      uint8_t value);
 static int nvram_read(struct comedi_device *dev, unsigned int address,
-	uint8_t *data);
+		      uint8_t * data);
 
 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
 {
@@ -506,7 +529,8 @@ static inline unsigned int cal_enable_bits(struct comedi_device *dev)
  * 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)
+static int cb_pcidas_attach(struct comedi_device *dev,
+			    struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	struct pci_dev *pcidev;
@@ -527,8 +551,8 @@ static int cb_pcidas_attach(struct comedi_device *dev, struct comedi_devconfig *
 	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)) {
+	     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;
@@ -540,8 +564,7 @@ static int cb_pcidas_attach(struct comedi_device *dev, struct comedi_devconfig *
 			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]) {
+				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 					continue;
 				}
 			}
@@ -552,13 +575,13 @@ static int cb_pcidas_attach(struct comedi_device *dev, struct comedi_devconfig *
 	}
 
 	printk("No supported ComputerBoards/MeasurementComputing card found on "
-		"requested position\n");
+	       "requested position\n");
 	return -EIO;
 
-      found:
+found:
 
 	printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
-		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+	       pcidev->bus->number, PCI_SLOT(pcidev->devfn));
 
 	/*
 	 * Enable PCI device and reserve I/O ports.
@@ -572,20 +595,20 @@ static int cb_pcidas_attach(struct comedi_device *dev, struct comedi_devconfig *
 	 * their base address.
 	 */
 	devpriv->s5933_config =
-		pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
+	    pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
 	devpriv->control_status =
-		pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
+	    pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
 	devpriv->adc_fifo =
-		pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
+	    pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
 	devpriv->pacer_counter_dio =
-		pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
+	    pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
 	if (thisboard->ao_nchan) {
 		devpriv->ao_registers =
-			pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
+		    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);
+	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
 
 	/*  get irq */
 	if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
@@ -700,11 +723,11 @@ static int cb_pcidas_attach(struct comedi_device *dev, struct comedi_devconfig *
 	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;
+	    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);
+	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
 
 	return 1;
 }
@@ -725,11 +748,10 @@ static int cb_pcidas_detach(struct comedi_device *dev)
 		if (devpriv->s5933_config) {
 			/*  disable and clear interrupts on amcc s5933 */
 			outl(INTCSR_INBOX_INTR_STATUS,
-				devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+			     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
 #ifdef CB_PCIDAS_DEBUG
 			printk("detaching, incsr is 0x%x\n",
-				inl(devpriv->s5933_config +
-					AMCC_OP_REG_INTCSR));
+			       inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR));
 #endif
 		}
 	}
@@ -751,8 +773,9 @@ static int cb_pcidas_detach(struct comedi_device *dev)
  * "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)
+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;
@@ -761,7 +784,7 @@ static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice
 	/*  enable calibration input if appropriate */
 	if (insn->chanspec & CR_ALT_SOURCE) {
 		outw(cal_enable_bits(dev),
-			devpriv->control_status + CALIBRATION_REG);
+		     devpriv->control_status + CALIBRATION_REG);
 		channel = 0;
 	} else {
 		outw(0, devpriv->control_status + CALIBRATION_REG);
@@ -769,7 +792,7 @@ static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice
 	}
 	/*  set mux limits and gain */
 	bits = BEGIN_SCAN(channel) |
-		END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
+	    END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
 	/*  set unipolar/bipolar */
 	if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
 		bits |= UNIP;
@@ -803,7 +826,8 @@ static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice
 	return n;
 }
 
-static int ai_config_calibration_source(struct comedi_device *dev, unsigned int *data)
+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];
@@ -819,7 +843,7 @@ static int ai_config_calibration_source(struct comedi_device *dev, unsigned int
 }
 
 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int id = data[0];
 
@@ -835,8 +859,10 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 /* 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)
+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;
@@ -845,9 +871,9 @@ static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, struct comedi_su
 	channel = CR_CHAN(insn->chanspec);
 	spin_lock_irqsave(&dev->spinlock, flags);
 	devpriv->ao_control_bits &=
-		~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
+	    ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
 	devpriv->ao_control_bits |=
-		DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
+	    DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
@@ -860,8 +886,9 @@ static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, struct comedi_su
 }
 
 /* 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)
+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;
@@ -873,11 +900,13 @@ static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, struct comedi_subd
 	channel = CR_CHAN(insn->chanspec);
 	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;
+	    ~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;
+	    DACEN | DAC_RANGE(channel,
+			      CR_RANGE(insn->
+				       chanspec)) | DAC_CHAN_EN(channel) |
+	    DAC_START;
 	outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
@@ -891,16 +920,19 @@ static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, struct comedi_subd
 
 /* 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)
+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)
+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;
@@ -914,16 +946,18 @@ static int eeprom_read_insn(struct comedi_device *dev, struct comedi_subdevice *
 	return 1;
 }
 
-static int caldac_write_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)
 {
 	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)
+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)];
 
@@ -939,26 +973,28 @@ static int dac08_write(struct comedi_device *dev, unsigned int value)
 	devpriv->dac08_value = value;
 
 	outw(cal_enable_bits(dev) | (value & 0xff),
-		devpriv->control_status + CALIBRATION_REG);
+	     devpriv->control_status + CALIBRATION_REG);
 	udelay(1);
 	outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
-		devpriv->control_status + CALIBRATION_REG);
+	     devpriv->control_status + CALIBRATION_REG);
 	udelay(1);
 	outw(cal_enable_bits(dev) | (value & 0xff),
-		devpriv->control_status + CALIBRATION_REG);
+	     devpriv->control_status + CALIBRATION_REG);
 	udelay(1);
 
 	return 1;
 }
 
-static int dac08_write_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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)
+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;
 
@@ -966,7 +1002,7 @@ static int dac08_read_insn(struct comedi_device *dev, struct comedi_subdevice *s
 }
 
 static int cb_pcidas_trimpot_write(struct comedi_device *dev,
-	unsigned int channel, unsigned int value)
+				   unsigned int channel, unsigned int value)
 {
 	if (devpriv->trimpot_value[channel] == value)
 		return 1;
@@ -988,16 +1024,18 @@ static int cb_pcidas_trimpot_write(struct comedi_device *dev,
 	return 1;
 }
 
-static int trimpot_write_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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)
+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);
 
@@ -1006,8 +1044,9 @@ static int trimpot_read_insn(struct comedi_device *dev, struct comedi_subdevice
 	return 1;
 }
 
-static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -1055,11 +1094,11 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	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)
+	    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)
+	    cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
 		err++;
 	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 		err++;
@@ -1070,8 +1109,7 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	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))
+	    (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
 		err++;
 
 	if (err)
@@ -1086,9 +1124,9 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		if (cmd->scan_begin_arg <
-			thisboard->ai_speed * cmd->chanlist_len) {
+		    thisboard->ai_speed * cmd->chanlist_len) {
 			cmd->scan_begin_arg =
-				thisboard->ai_speed * cmd->chanlist_len;
+			    thisboard->ai_speed * cmd->chanlist_len;
 			err++;
 		}
 	}
@@ -1119,16 +1157,20 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	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);
+					       &(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);
+					       &(devpriv->divisor1),
+					       &(devpriv->divisor2),
+					       &(cmd->convert_arg),
+					       cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->convert_arg)
 			err++;
 	}
@@ -1142,14 +1184,14 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 		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) {
+			    (start_chan + i) % s->n_chan) {
 				comedi_error(dev,
-					"entries in chanlist must be consecutive channels, counting upwards\n");
+					     "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");
+					     "entries in chanlist must all have the same gain\n");
 				err++;
 			}
 		}
@@ -1161,7 +1203,8 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	return 0;
 }
 
-static int cb_pcidas_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+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;
@@ -1177,8 +1220,8 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *
 
 	/*  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]));
+	    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;
@@ -1199,10 +1242,10 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *
 	/*  load counters */
 	if (cmd->convert_src == TRIG_TIMER)
 		cb_pcidas_load_counters(dev, &cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+					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);
+					cmd->flags & TRIG_ROUND_MASK);
 
 	/*  set number of conversions */
 	if (cmd->stop_src == TRIG_COUNT) {
@@ -1225,7 +1268,7 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *
 #endif
 	/*  enable (and clear) interrupts */
 	outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
-		devpriv->control_status + INT_ADCFIFO);
+	     devpriv->control_status + INT_ADCFIFO);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
 	/*  set start trigger and burst mode */
@@ -1248,8 +1291,9 @@ static int cb_pcidas_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -1294,7 +1338,7 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	/* 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_EXT)
 		err++;
 	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 		err++;
@@ -1336,8 +1380,10 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	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);
+					       &(devpriv->ao_divisor1),
+					       &(devpriv->ao_divisor2),
+					       &(cmd->scan_begin_arg),
+					       cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
@@ -1348,9 +1394,9 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	/*  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) {
+		    CR_CHAN(cmd->chanlist[1]) != 1) {
 			comedi_error(dev,
-				"channels must be ordered channel 0, channel 1 in chanlist\n");
+				     "channels must be ordered channel 0, channel 1 in chanlist\n");
 			err++;
 		}
 	}
@@ -1361,7 +1407,8 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	return 0;
 }
 
-static int cb_pcidas_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+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;
@@ -1373,10 +1420,11 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *
 	for (i = 0; i < cmd->chanlist_len; i++) {
 		/*  enable channel */
 		devpriv->ao_control_bits |=
-			DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
+		    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]));
+						      CR_RANGE(cmd->
+							       chanlist[i]));
 	}
 
 	/*  disable analog out before settings pacer source and count values */
@@ -1389,14 +1437,16 @@ static int cb_pcidas_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *
 	/*  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);
+					       &(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);
+			   devpriv->ao_divisor1, 2);
 		i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
-			devpriv->ao_divisor2, 2);
+			   devpriv->ao_divisor2, 2);
 	}
 	/*  set number of conversions */
 	if (cmd->stop_src == TRIG_COUNT) {
@@ -1441,7 +1491,7 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
 		num_points = devpriv->ao_count;
 
 	num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
-		num_points * sizeof(short));
+					       num_points * sizeof(short));
 	num_points = num_bytes / sizeof(short);
 
 	if (cmd->stop_src == TRIG_COUNT) {
@@ -1458,14 +1508,13 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
 #endif
 	/*  enable and clear interrupts */
 	outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
-		devpriv->control_status + INT_ADCFIFO);
+	     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
-	printk("comedi: sent 0x%x to dac control\n",
-		devpriv->ao_control_bits);
+	printk("comedi: sent 0x%x to dac control\n", devpriv->ao_control_bits);
 #endif
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
@@ -1476,7 +1525,7 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
 
 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->read_subdev;
 	struct comedi_async *async;
 	int status, s5933_status;
@@ -1505,7 +1554,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
 	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);
+	     devpriv->s5933_config + AMCC_OP_REG_INTCSR);
 
 	status = inw(devpriv->control_status + INT_ADCFIFO);
 #ifdef CB_PCIDAS_DEBUG
@@ -1524,13 +1573,13 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
 		/*  read data */
 		num_samples = half_fifo;
 		if (async->cmd.stop_src == TRIG_COUNT &&
-			num_samples > devpriv->count) {
+		    num_samples > devpriv->count) {
 			num_samples = devpriv->count;
 		}
 		insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
-			num_samples);
+		     num_samples);
 		cfc_write_array_to_buffer(s, devpriv->ai_buffer,
-			num_samples * sizeof(short));
+					  num_samples * sizeof(short));
 		devpriv->count -= num_samples;
 		if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
 			async->events |= COMEDI_CB_EOA;
@@ -1539,14 +1588,14 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
 		/*  clear half-full interrupt latch */
 		spin_lock_irqsave(&dev->spinlock, flags);
 		outw(devpriv->adc_fifo_bits | INT,
-			devpriv->control_status + INT_ADCFIFO);
+		     devpriv->control_status + INT_ADCFIFO);
 		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)
+					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 */
@@ -1558,15 +1607,15 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
 		/*  clear not-empty interrupt latch */
 		spin_lock_irqsave(&dev->spinlock, flags);
 		outw(devpriv->adc_fifo_bits | INT,
-			devpriv->control_status + INT_ADCFIFO);
+		     devpriv->control_status + INT_ADCFIFO);
 		spin_unlock_irqrestore(&dev->spinlock, flags);
 	} else if (status & EOAI) {
 		comedi_error(dev,
-			"bug! encountered end of aquisition interrupt?");
+			     "bug! encountered end of aquisition interrupt?");
 		/*  clear EOA interrupt latch */
 		spin_lock_irqsave(&dev->spinlock, flags);
 		outw(devpriv->adc_fifo_bits | EOAI,
-			devpriv->control_status + INT_ADCFIFO);
+		     devpriv->control_status + INT_ADCFIFO);
 		spin_unlock_irqrestore(&dev->spinlock, flags);
 	}
 	/* check for fifo overflow */
@@ -1575,7 +1624,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
 		/*  clear overflow interrupt latch */
 		spin_lock_irqsave(&dev->spinlock, flags);
 		outw(devpriv->adc_fifo_bits | LADFUL,
-			devpriv->control_status + INT_ADCFIFO);
+		     devpriv->control_status + INT_ADCFIFO);
 		spin_unlock_irqrestore(&dev->spinlock, flags);
 		cb_pcidas_cancel(dev, s);
 		async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
@@ -1601,12 +1650,12 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
 		/*  clear dac empty interrupt latch */
 		spin_lock_irqsave(&dev->spinlock, flags);
 		outw(devpriv->adc_fifo_bits | DAEMI,
-			devpriv->control_status + INT_ADCFIFO);
+		     devpriv->control_status + INT_ADCFIFO);
 		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)) {
+			    (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;
@@ -1619,11 +1668,11 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
 		/*  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)
+		    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));
+		    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) {
@@ -1631,11 +1680,11 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
 		}
 		/*  write data to board's fifo */
 		outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
-			num_points);
+		      num_points);
 		/*  clear half-full interrupt latch */
 		spin_lock_irqsave(&dev->spinlock, flags);
 		outw(devpriv->adc_fifo_bits | DAHFI,
-			devpriv->control_status + INT_ADCFIFO);
+		     devpriv->control_status + INT_ADCFIFO);
 		spin_unlock_irqrestore(&dev->spinlock, flags);
 	}
 
@@ -1643,7 +1692,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
 }
 
 /* cancel analog input command */
-static int cb_pcidas_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int cb_pcidas_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	unsigned long flags;
 
@@ -1681,21 +1731,23 @@ static int cb_pcidas_ao_cancel(struct comedi_device *dev,
 }
 
 static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns,
-	int rounding_flags)
+				    int rounding_flags)
 {
 	i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
-		&(devpriv->divisor2), ns, rounding_flags & TRIG_ROUND_MASK);
+				       &(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);
+		   devpriv->divisor1, 2);
 	i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
-		devpriv->divisor2, 2);
+		   devpriv->divisor2, 2);
 }
 
 static void write_calibration_bitstream(struct comedi_device *dev,
-	unsigned int register_bits, unsigned int bitstream,
-	unsigned int bitstream_length)
+					unsigned int register_bits,
+					unsigned int bitstream,
+					unsigned int bitstream_length)
 {
 	static const int write_delay = 1;
 	unsigned int bit;
@@ -1711,7 +1763,7 @@ static void write_calibration_bitstream(struct comedi_device *dev,
 }
 
 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
-	uint8_t value)
+			     uint8_t value)
 {
 	static const int num_caldac_channels = 8;
 	static const int bitstream_length = 11;
@@ -1729,11 +1781,11 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
 	devpriv->caldac_value[address] = value;
 
 	write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
-		bitstream_length);
+				    bitstream_length);
 
 	udelay(caldac_8800_udelay);
 	outw(cal_enable_bits(dev) | SELECT_8800_BIT,
-		devpriv->control_status + CALIBRATION_REG);
+	     devpriv->control_status + CALIBRATION_REG);
 	udelay(caldac_8800_udelay);
 	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
 
@@ -1752,7 +1804,7 @@ static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
 	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
 
 	write_calibration_bitstream(dev, register_bits, bitstream,
-		bitstream_length);
+				    bitstream_length);
 
 	udelay(ad7376_udelay);
 	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
@@ -1764,7 +1816,7 @@ static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
  * ch 0 : adc gain
  * ch 1 : adc postgain offset */
 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
-	uint8_t value)
+			      uint8_t value)
 {
 	static const int bitstream_length = 10;
 	unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
@@ -1776,7 +1828,7 @@ static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
 	outw(register_bits, devpriv->control_status + CALIBRATION_REG);
 
 	write_calibration_bitstream(dev, register_bits, bitstream,
-		bitstream_length);
+				    bitstream_length);
 
 	udelay(ad8402_udelay);
 	outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
@@ -1791,15 +1843,16 @@ static int wait_for_nvram_ready(unsigned long s5933_base_addr)
 
 	for (i = 0; i < timeout; i++) {
 		if ((inb(s5933_base_addr +
-					AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
-			== 0)
+			 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
+		    == 0)
 			return 0;
 		udelay(1);
 	}
 	return -1;
 }
 
-static int nvram_read(struct comedi_device *dev, unsigned int address, uint8_t *data)
+static int nvram_read(struct comedi_device *dev, unsigned int address,
+		      uint8_t * data)
 {
 	unsigned long iobase = devpriv->s5933_config;
 
@@ -1807,10 +1860,10 @@ static int nvram_read(struct comedi_device *dev, unsigned int address, uint8_t *
 		return -ETIMEDOUT;
 
 	outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
-		iobase + AMCC_OP_REG_MCSR_NVCMD);
+	     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);
+	     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);
 
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 210b462..82295e0 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -152,10 +152,12 @@ 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));
@@ -269,10 +271,12 @@ 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;
@@ -370,10 +374,12 @@ 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;
@@ -394,6 +400,7 @@ 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) */
@@ -404,90 +411,91 @@ static inline uint8_t attenuate_bit(unsigned int channel)
 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)
-		}
+	 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),
-		}
+	 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),
-		}
+	 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),
-		}
+	 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),
-		}
+	 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),
-		}
+	 BIP_RANGE(5),
+	 BIP_RANGE(10),
+	 UNI_RANGE(5),
+	 UNI_RANGE(10),
+	 }
 };
+
 static const int ao_range_code_64xx[] = {
 	0x0,
 	0x1,
@@ -498,9 +506,10 @@ static const int ao_range_code_64xx[] = {
 static const struct comedi_lrange ao_ranges_60xx = {
 	1,
 	{
-			BIP_RANGE(10),
-		}
+	 BIP_RANGE(10),
+	 }
 };
+
 static const int ao_range_code_60xx[] = {
 	0x0,
 };
@@ -508,10 +517,11 @@ static const int ao_range_code_60xx[] = {
 static const struct comedi_lrange ao_ranges_6030 = {
 	2,
 	{
-			BIP_RANGE(10),
-			UNI_RANGE(10),
-		}
+	 BIP_RANGE(10),
+	 UNI_RANGE(10),
+	 }
 };
+
 static const int ao_range_code_6030[] = {
 	0x0,
 	0x2,
@@ -520,10 +530,11 @@ static const int ao_range_code_6030[] = {
 static const struct comedi_lrange ao_ranges_4020 = {
 	2,
 	{
-			BIP_RANGE(5),
-			BIP_RANGE(10),
-		}
+	 BIP_RANGE(5),
+	 BIP_RANGE(10),
+	 }
 };
+
 static const int ao_range_code_4020[] = {
 	0x1,
 	0x0,
@@ -597,458 +608,478 @@ 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/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-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/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/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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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,
-		},
+	 .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-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/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/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/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/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/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,
-		},
+	 .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
 };
 
 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}
+	{
+	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)
+static inline struct pcidas64_board *board(const struct comedi_device *dev)
 {
-	return (struct pcidas64_board *) dev->board_ptr;
+	return (struct pcidas64_board *)dev->board_ptr;
 }
 
 static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev,
-	int use_differential)
+					      int use_differential)
 {
 	if ((board(dev)->layout == LAYOUT_64XX && !use_differential) ||
-		(board(dev)->layout == LAYOUT_60XX && use_differential))
+	    (board(dev)->layout == LAYOUT_60XX && use_differential))
 		return ADC_SE_DIFF_BIT;
 	else
 		return 0;
@@ -1107,11 +1138,10 @@ struct pcidas64_private {
 	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)
+static inline struct pcidas64_private *priv(struct comedi_device *dev)
 {
 	return dev->private;
 }
@@ -1132,76 +1162,86 @@ static struct comedi_driver driver_cb_pcidas = {
 };
 
 static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+		    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);
+			  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);
+		    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);
+		      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_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);
+		      struct comedi_cmd *cmd);
 static irqreturn_t handle_interrupt(int irq, void *d);
 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);
+		    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);
+		    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);
+			  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);
+			 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);
+		      const uint8_t * data, unsigned int length);
 static void caldac_write(struct comedi_device *dev, unsigned int channel,
-	unsigned int value);
+			 unsigned int value);
 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
-	uint8_t value);
+			     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 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 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);
+				      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 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);
+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)
+				       unsigned int range_index)
 {
 	const struct comedi_krange *range =
-		&board(dev)->ai_range_table->range[range_index];
+	    &board(dev)->ai_range_table->range[range_index];
 	unsigned int bits = 0;
 
 	switch (range->max) {
@@ -1242,7 +1282,7 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev,
 }
 
 static unsigned int hw_revision(const struct comedi_device *dev,
-	uint16_t hw_status_bits)
+				uint16_t hw_status_bits)
 {
 	if (board(dev)->layout == LAYOUT_4020)
 		return (hw_status_bits >> 13) & 0x7;
@@ -1250,8 +1290,9 @@ static unsigned int hw_revision(const struct comedi_device *dev,
 	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)
+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];
 
@@ -1276,38 +1317,38 @@ static void init_plx9080(struct comedi_device *dev)
 	void *plx_iobase = priv(dev)->plx9080_iobase;
 
 	priv(dev)->plx_control_bits =
-		readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG);
+	    readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG);
 
 	/*  plx9080 dump */
 	DEBUG_PRINT(" plx interrupt status 0x%x\n",
-		readl(plx_iobase + PLX_INTRCS_REG));
+		    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));
+		    readl(plx_iobase + PLX_MARB_REG));
 	DEBUG_PRINT(" plx region0 reg 0x%x\n",
-		readl(plx_iobase + PLX_REGION0_REG));
+		    readl(plx_iobase + PLX_REGION0_REG));
 	DEBUG_PRINT(" plx region1 reg 0x%x\n",
-		readl(plx_iobase + PLX_REGION1_REG));
+		    readl(plx_iobase + PLX_REGION1_REG));
 
 	DEBUG_PRINT(" plx revision 0x%x\n",
-		readl(plx_iobase + PLX_REVISION_REG));
+		    readl(plx_iobase + PLX_REVISION_REG));
 	DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
-		readl(plx_iobase + PLX_DMA0_MODE_REG));
+		    readl(plx_iobase + PLX_DMA0_MODE_REG));
 	DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
-		readl(plx_iobase + PLX_DMA1_MODE_REG));
+		    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));
+		    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));
+		    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));
+		    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));
+		    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));
+		    readb(plx_iobase + PLX_DMA0_CS_REG));
 	DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
-		readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+		    readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
 	DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
 
 #ifdef __BIG_ENDIAN
@@ -1352,10 +1393,10 @@ static void init_plx9080(struct comedi_device *dev)
 
 	/*  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;
+	    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);
+	       priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
 }
 
 /* Allocate and initialize the subdevice structures.
@@ -1405,8 +1446,7 @@ static int setup_subdevices(struct comedi_device *dev)
 	if (board(dev)->ao_nchan) {
 		s->type = COMEDI_SUBD_AO;
 		s->subdev_flags =
-			SDF_READABLE | SDF_WRITABLE | SDF_GROUND |
-			SDF_CMD_WRITE;
+		    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;
@@ -1452,14 +1492,14 @@ static int setup_subdevices(struct comedi_device *dev)
 	if (board(dev)->has_8255) {
 		if (board(dev)->layout == LAYOUT_4020) {
 			dio_8255_iobase =
-				priv(dev)->main_iobase + I8255_4020_REG;
+			    priv(dev)->main_iobase + I8255_4020_REG;
 			subdev_8255_init(dev, s, dio_callback_4020,
-				(unsigned long)dio_8255_iobase);
+					 (unsigned long)dio_8255_iobase);
 		} else {
 			dio_8255_iobase =
-				priv(dev)->dio_counter_iobase + DIO_8255_OFFSET;
+			    priv(dev)->dio_counter_iobase + DIO_8255_OFFSET;
 			subdev_8255_init(dev, s, dio_callback,
-				(unsigned long)dio_8255_iobase);
+					 (unsigned long)dio_8255_iobase);
 		}
 	} else
 		s->type = COMEDI_SUBD_UNUSED;
@@ -1527,7 +1567,7 @@ 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);
+	       priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
 }
 
 static void init_stc_registers(struct comedi_device *dev)
@@ -1541,7 +1581,7 @@ static void init_stc_registers(struct comedi_device *dev)
 	if (1)
 		priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
 	writew(priv(dev)->adc_control1_bits,
-		priv(dev)->main_iobase + ADC_CONTROL1_REG);
+	       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);
@@ -1551,7 +1591,7 @@ static void init_stc_registers(struct comedi_device *dev)
 		bits |= INTERNAL_CLOCK_4020_BITS;
 	priv(dev)->hw_config_bits |= bits;
 	writew(priv(dev)->hw_config_bits,
-		priv(dev)->main_iobase + HW_CONFIG_REG);
+	       priv(dev)->main_iobase + HW_CONFIG_REG);
 
 	writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG);
 	writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
@@ -1561,13 +1601,13 @@ static void init_stc_registers(struct comedi_device *dev)
 	/*  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);
+				   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;
+	    EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
 	writew(priv(dev)->intr_enable_bits,
-		priv(dev)->main_iobase + INTR_ENABLE_REG);
+	       priv(dev)->main_iobase + INTR_ENABLE_REG);
 
 	disable_ai_pacing(dev);
 };
@@ -1579,8 +1619,8 @@ int alloc_and_init_dma_members(struct comedi_device *dev)
 	/*  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]);
+		    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;
 		}
@@ -1588,9 +1628,10 @@ int alloc_and_init_dma_members(struct comedi_device *dev)
 	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]);
+			    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;
 			}
@@ -1598,61 +1639,65 @@ int alloc_and_init_dma_members(struct comedi_device *dev)
 	}
 	/*  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);
+	    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);
+		    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);
+		    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);
+			    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]);
+		    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);
+			    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);
+			    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);
+		    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]);
+			    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);
+			    cpu_to_le32(priv(dev)->local0_iobase +
+					DAC_FIFO_REG);
 			priv(dev)->ao_dma_desc[i].transfer_size =
-				cpu_to_le32(0);
+			    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);
+			    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;
@@ -1661,9 +1706,9 @@ int alloc_and_init_dma_members(struct comedi_device *dev)
 static inline void warn_external_queue(struct comedi_device *dev)
 {
 	comedi_error(dev,
-		"AO command and AI external channel queue cannot be used simultaneously.");
+		     "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)");
+		     "Use internal AI channel queue (channels must be consecutive and use same range/aref)");
 }
 
 /*
@@ -1690,8 +1735,8 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
  */
 
 	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)) {
+	     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;
@@ -1703,8 +1748,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			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]) {
+				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 					continue;
 				}
 			}
@@ -1717,16 +1761,17 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	if (dev->board_ptr == NULL) {
-		printk("No supported ComputerBoards/MeasurementComputing card found\n");
+		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));
+	       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");
+		       " failed to enable PCI device and request regions\n");
 		return -EIO;
 	}
 	pci_set_master(pcidev);
@@ -1735,23 +1780,25 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	dev->board_name = board(dev)->name;
 
 	priv(dev)->plx9080_phys_iobase =
-		pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+	    pci_resource_start(pcidev, PLX9080_BADDRINDEX);
 	priv(dev)->main_phys_iobase =
-		pci_resource_start(pcidev, MAIN_BADDRINDEX);
+	    pci_resource_start(pcidev, MAIN_BADDRINDEX);
 	priv(dev)->dio_counter_phys_iobase =
-		pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
+	    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));
+					    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));
+	    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) {
+	    || !priv(dev)->dio_counter_iobase) {
 		printk(" failed to remap io memory\n");
 		return -ENOMEM;
 	}
@@ -1759,27 +1806,25 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+		    priv(dev)->dio_counter_iobase);
 
 	/*  figure out what local addresses are */
 	local_range =
-		readl(priv(dev)->plx9080_iobase +
-		PLX_LAS0RNG_REG) & LRNG_MEM_MASK;
+	    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;
+	    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;
+	    ((uint32_t) priv(dev)->main_phys_iobase & ~local_range) |
+	    local_decode;
 	local_range =
-		readl(priv(dev)->plx9080_iobase +
-		PLX_LAS1RNG_REG) & LRNG_MEM_MASK;
+	    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;
+	    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;
+	    ((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);
@@ -1789,7 +1834,7 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		return retval;
 
 	priv(dev)->hw_revision =
-		hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG));
+	    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);
@@ -1840,32 +1885,40 @@ static int detach(struct comedi_device *dev)
 			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]);
+							    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]);
+							    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);
+						    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);
+						    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);
 			}
@@ -1879,7 +1932,7 @@ static int detach(struct comedi_device *dev)
 }
 
 static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int bits = 0, n, i;
 	unsigned int channel, range, aref;
@@ -1901,14 +1954,14 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	else
 		priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
 	writew(priv(dev)->adc_control1_bits,
-		priv(dev)->main_iobase + ADC_CONTROL1_REG);
+	       priv(dev)->main_iobase + ADC_CONTROL1_REG);
 	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);
+		       priv(dev)->main_iobase + HW_CONFIG_REG);
 
 		/*  ALT_SOURCE is internal calibration reference */
 		if (insn->chanspec & CR_ALT_SOURCE) {
@@ -1920,9 +1973,9 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 			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);
+			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);
@@ -1938,7 +1991,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 		bits |= adc_chan_bits(channel);
 		/*  set stop channel */
 		writew(adc_chan_bits(channel),
-			priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+		       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 {
@@ -1948,8 +2001,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 		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);
+			    adc_src_4020_bits(priv(dev)->calibration_source);
 		} else {	/* select BNC inputs */
 			priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
 		}
@@ -1958,20 +2010,20 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 			priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel);
 		else
 			priv(dev)->i2c_cal_range_bits &=
-				~attenuate_bit(channel);
+			    ~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));
+				  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);
+		       priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
 		writew(2,
-			priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+		       priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
 	}
 
 	for (n = 0; n < insn->n; n++) {
@@ -1981,7 +2033,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 
 		/* 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);
+		       priv(dev)->main_iobase + ADC_CONVERT_REG);
 
 		/*  wait for data */
 		for (i = 0; i < timeout; i++) {
@@ -1989,7 +2041,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 			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))
+					  ADC_WRITE_PNTR_REG))
 					break;
 			} else {
 				if (pipe_full_bits(bits))
@@ -2005,17 +2057,18 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 		}
 		if (board(dev)->layout == LAYOUT_4020)
 			data[n] =
-				readl(priv(dev)->dio_counter_iobase +
-				ADC_FIFO_REG) & 0xffff;
+			    readl(priv(dev)->dio_counter_iobase +
+				  ADC_FIFO_REG) & 0xffff;
 		else
 			data[n] =
-				readw(priv(dev)->main_iobase + PIPE1_READ_REG);
+			    readw(priv(dev)->main_iobase + PIPE1_READ_REG);
 	}
 
 	return n;
 }
 
-static int ai_config_calibration_source(struct comedi_device *dev, unsigned int *data)
+static int ai_config_calibration_source(struct comedi_device *dev,
+					unsigned int *data)
 {
 	unsigned int source = data[1];
 	int num_calibration_sources;
@@ -2046,8 +2099,7 @@ static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
 
 	if (requested_block_size) {
 		fifo_size =
-			requested_block_size * fifo->num_segments /
-			bytes_in_sample;
+		    requested_block_size * fifo->num_segments / bytes_in_sample;
 
 		retval = set_ai_fifo_size(dev, fifo_size);
 		if (retval < 0)
@@ -2062,7 +2114,8 @@ static int ai_config_block_size(struct comedi_device *dev, unsigned int *data)
 	return 2;
 }
 
-static int ai_config_master_clock_4020(struct comedi_device *dev, unsigned int *data)
+static int ai_config_master_clock_4020(struct comedi_device *dev,
+				       unsigned int *data)
 {
 	unsigned int divisor = data[4];
 	int retval = 0;
@@ -2104,7 +2157,7 @@ static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data)
 }
 
 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int id = data[0];
 
@@ -2126,7 +2179,7 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+		      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -2181,21 +2234,21 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	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)
+	    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)
+	    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)
+	    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)
+	    cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
 		err++;
 
 	if (err)
@@ -2217,10 +2270,10 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 			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->scan_begin_arg =
-						cmd->convert_arg *
-						cmd->chanlist_len;
+					    cmd->convert_arg *
+					    cmd->chanlist_len;
 					err++;
 				}
 			}
@@ -2279,7 +2332,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		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");
+					     "all elements in chanlist must use the same analog reference");
 				err++;
 				break;
 			}
@@ -2289,16 +2342,16 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 			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) {
+				    first_channel + i) {
 					comedi_error(dev,
-						"chanlist must use consecutive channels");
+						     "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");
+					     "chanlist cannot be 3 channels long, use 1, 2, or 4 channels");
 				err++;
 			}
 		}
@@ -2321,7 +2374,8 @@ static int use_hw_sample_counter(struct comedi_cmd *cmd)
 		return 0;
 }
 
-static void setup_sample_counters(struct comedi_device *dev, struct comedi_cmd *cmd)
+static void setup_sample_counters(struct comedi_device *dev,
+				  struct comedi_cmd *cmd)
 {
 	if (cmd->stop_src == TRIG_COUNT) {
 		/*  set software count */
@@ -2330,9 +2384,9 @@ static void setup_sample_counters(struct comedi_device *dev, struct comedi_cmd *
 	/*  load hardware conversion counter */
 	if (use_hw_sample_counter(cmd)) {
 		writew(cmd->stop_arg & 0xffff,
-			priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+		       priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
 		writew((cmd->stop_arg >> 16) & 0xff,
-			priv(dev)->main_iobase + ADC_COUNT_UPPER_REG);
+		       priv(dev)->main_iobase + ADC_COUNT_UPPER_REG);
 	} else {
 		writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
 	}
@@ -2343,8 +2397,8 @@ 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;
+	    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);
 
@@ -2360,12 +2414,12 @@ static void disable_ai_pacing(struct comedi_device *dev)
 	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);
+	       priv(dev)->main_iobase + ADC_CONTROL1_REG);
 	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);
+	       priv(dev)->main_iobase + ADC_CONTROL0_REG);
 }
 
 static void disable_ai_interrupts(struct comedi_device *dev)
@@ -2374,23 +2428,24 @@ static void disable_ai_interrupts(struct comedi_device *dev)
 
 	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;
+	    ~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);
+	       priv(dev)->main_iobase + INTR_ENABLE_REG);
 	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)
+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;
+	    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 */
@@ -2400,27 +2455,28 @@ static void enable_ai_interrupts(struct comedi_device *dev, const struct 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);
+	       priv(dev)->main_iobase + INTR_ENABLE_REG);
 	DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 }
 
 static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev,
-	const struct comedi_cmd *cmd)
+					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)
+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;
+			 (cmd->convert_arg * (cmd->chanlist_len - 1)))
+		    / TIMER_BASE;
 		break;
 	case TRIG_FOLLOW:
 		count = cmd->convert_arg / TIMER_BASE;
@@ -2432,7 +2488,8 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, struct comedi_cm
 	return count - 3;
 }
 
-static uint32_t ai_convert_counter_4020(struct comedi_device *dev, struct comedi_cmd *cmd)
+static uint32_t ai_convert_counter_4020(struct comedi_device *dev,
+					struct comedi_cmd *cmd)
 {
 	unsigned int divisor;
 
@@ -2454,7 +2511,7 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev, struct comedi
 }
 
 static void select_master_clock_4020(struct comedi_device *dev,
-	const struct comedi_cmd *cmd)
+				     const struct comedi_cmd *cmd)
 {
 	/*  select internal/external master clock */
 	priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
@@ -2469,10 +2526,11 @@ static void select_master_clock_4020(struct comedi_device *dev,
 		priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
 	}
 	writew(priv(dev)->hw_config_bits,
-		priv(dev)->main_iobase + HW_CONFIG_REG);
+	       priv(dev)->main_iobase + HW_CONFIG_REG);
 }
 
-static void select_master_clock(struct comedi_device *dev, const struct comedi_cmd *cmd)
+static void select_master_clock(struct comedi_device *dev,
+				const struct comedi_cmd *cmd)
 {
 	switch (board(dev)->layout) {
 	case LAYOUT_4020:
@@ -2483,7 +2541,8 @@ static void select_master_clock(struct comedi_device *dev, const struct comedi_c
 	}
 }
 
-static inline void dma_start_sync(struct comedi_device *dev, unsigned int channel)
+static inline void dma_start_sync(struct comedi_device *dev,
+				  unsigned int channel)
 {
 	unsigned long flags;
 
@@ -2491,12 +2550,12 @@ static inline void dma_start_sync(struct comedi_device *dev, unsigned int channe
 	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);
+		       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);
+		       PLX_CLEAR_DMA_INTR_BIT,
+		       priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 }
 
@@ -2517,17 +2576,17 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd)
 
 	/*  load lower 16 bits of convert interval */
 	writew(convert_counter & 0xffff,
-		priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+	       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);
+	       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);
+	       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);
+	       priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
 	DEBUG_PRINT("scan counter 0x%x\n", scan_counter);
 }
 
@@ -2536,10 +2595,10 @@ 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)
+		    CR_CHAN(cmd->chanlist[i]) + 1)
 			return 0;
 		if (CR_RANGE(cmd->chanlist[i + 1]) !=
-			CR_RANGE(cmd->chanlist[i]))
+		    CR_RANGE(cmd->chanlist[i]))
 			return 0;
 		if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
 			return 0;
@@ -2547,7 +2606,8 @@ static int use_internal_queue_6xxx(const struct comedi_cmd *cmd)
 	return 1;
 }
 
-static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cmd *cmd)
+static int setup_channel_queue(struct comedi_device *dev,
+			       const struct comedi_cmd *cmd)
 {
 	unsigned short bits;
 	int i;
@@ -2556,25 +2616,26 @@ static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cm
 		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);
+			       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]));
+						   CR_RANGE(cmd->chanlist[0]));
 			/*  set single-ended / differential */
 			bits |= se_diff_bit_6xxx(dev,
-				CR_AREF(cmd->chanlist[0]) == AREF_DIFF);
+						 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);
+			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);
+			       priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
 		} else {
 			/*  use external queue */
 			if (dev->write_subdev && dev->write_subdev->busy) {
@@ -2583,36 +2644,40 @@ static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cm
 			}
 			priv(dev)->hw_config_bits |= EXT_QUEUE_BIT;
 			writew(priv(dev)->hw_config_bits,
-				priv(dev)->main_iobase + HW_CONFIG_REG);
+			       priv(dev)->main_iobase + HW_CONFIG_REG);
 			/*  clear DAC buffer to prevent weird interactions */
 			writew(0,
-				priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+			       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]));
+				bits |=
+				    adc_chan_bits(CR_CHAN(cmd->chanlist[i]));
 				/*  set gain */
 				bits |= ai_range_bits_6xxx(dev,
-					CR_RANGE(cmd->chanlist[i]));
+							   CR_RANGE(cmd->
+								    chanlist
+								    [i]));
 				/*  set single-ended / differential */
 				bits |= se_diff_bit_6xxx(dev,
-					CR_AREF(cmd->chanlist[i]) == AREF_DIFF);
+							 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;
+					    QUEUE_EOSEQ_BIT;
 				writew(bits,
-					priv(dev)->main_iobase +
-					ADC_QUEUE_FIFO_REG);
+				       priv(dev)->main_iobase +
+				       ADC_QUEUE_FIFO_REG);
 				DEBUG_PRINT
-					("wrote 0x%x to external channel queue\n",
-					bits);
+				    ("wrote 0x%x to external channel queue\n",
+				     bits);
 			}
 			/* doing a queue clear is not specified in board docs,
 			 * but required for reliable operation */
@@ -2622,7 +2687,7 @@ static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cm
 		}
 	} else {
 		unsigned short old_cal_range_bits =
-			priv(dev)->i2c_cal_range_bits;
+		    priv(dev)->i2c_cal_range_bits;
 
 		priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
 		/* select BNC inputs */
@@ -2634,23 +2699,24 @@ static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cm
 
 			if (range == 0)
 				priv(dev)->i2c_cal_range_bits |=
-					attenuate_bit(channel);
+				    attenuate_bit(channel);
 			else
 				priv(dev)->i2c_cal_range_bits &=
-					~attenuate_bit(channel);
+				    ~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));
+				  sizeof(i2c_data));
 		}
 	}
 	return 0;
 }
 
 static inline void load_first_dma_descriptor(struct comedi_device *dev,
-	unsigned int dma_channel, unsigned int descriptor_bits)
+					     unsigned int dma_channel,
+					     unsigned int descriptor_bits)
 {
 	/* The transfer size, pci address, and local address registers
 	 * are supposedly unused during chained dma,
@@ -2659,20 +2725,20 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev,
 	 * block.  Initializing them to zero seems to fix the problem. */
 	if (dma_channel) {
 		writel(0,
-			priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
+		       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);
+		       priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
 		writel(descriptor_bits,
-			priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
+		       priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
 	} else {
 		writel(0,
-			priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+		       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);
+		       priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
 		writel(descriptor_bits,
-			priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+		       priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
 	}
 }
 
@@ -2719,14 +2785,15 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			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]));
+		    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]));
+		    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);
+	       priv(dev)->main_iobase + ADC_CONTROL1_REG);
 	DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
@@ -2734,20 +2801,21 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
 
 	if ((cmd->flags & TRIG_WAKE_EOS) == 0 ||
-		board(dev)->layout == LAYOUT_4020) {
+	    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));
+			    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);
+					  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);
 	}
@@ -2807,11 +2875,9 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
 	do {
 		/*  get least significant 15 bits */
 		read_index =
-			readw(priv(dev)->main_iobase +
-			ADC_READ_PNTR_REG) & 0x7fff;
+		    readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
 		write_index =
-			readw(priv(dev)->main_iobase +
-			ADC_WRITE_PNTR_REG) & 0x7fff;
+		    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
@@ -2824,11 +2890,12 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
 		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);
+			    read_segment, write_segment, read_index,
+			    write_index);
 
 		if (read_segment != write_segment)
 			num_samples =
-				priv(dev)->ai_fifo_segment_length - read_index;
+			    priv(dev)->ai_fifo_segment_length - read_index;
 		else
 			num_samples = write_index - read_index;
 
@@ -2850,7 +2917,8 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev)
 
 		for (i = 0; i < num_samples; i++) {
 			cfc_write_to_buffer(s,
-				readw(priv(dev)->main_iobase + ADC_FIFO_REG));
+					    readw(priv(dev)->main_iobase +
+						  ADC_FIFO_REG));
 		}
 
 	} while (read_segment != write_segment);
@@ -2870,9 +2938,9 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
 	unsigned int max_transfer = 100000;
 	uint32_t fifo_data;
 	int write_code =
-		readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
+	    readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
 	int read_code =
-		readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
+	    readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
 
 	if (cmd->stop_src == TRIG_COUNT) {
 		if (max_transfer > priv(dev)->ai_count) {
@@ -2888,8 +2956,7 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev)
 			i++;
 		}
 		read_code =
-			readw(priv(dev)->main_iobase +
-			ADC_READ_PNTR_REG) & 0x7fff;
+		    readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
 	}
 	priv(dev)->ai_count -= i;
 }
@@ -2913,19 +2980,18 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
 
 	if (channel)
 		pci_addr_reg =
-			priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+		    priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
 	else
 		pci_addr_reg =
-			priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_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++) {
+	     (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) {
@@ -2934,15 +3000,16 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
 			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_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));
+		    (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]);
+			    (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
@@ -2950,7 +3017,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
 }
 
 void handle_ai_interrupt(struct comedi_device *dev, unsigned short status,
-	unsigned int plx_status)
+			 unsigned int plx_status)
 {
 	struct comedi_subdevice *s = dev->read_subdev;
 	struct comedi_async *async = s->async;
@@ -2968,7 +3035,7 @@ void handle_ai_interrupt(struct comedi_device *dev, unsigned short status,
 	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);
+		       priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
 		DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
 
 		if (dma1_status & PLX_DMA_EN_BIT) {
@@ -2983,9 +3050,9 @@ void handle_ai_interrupt(struct comedi_device *dev, unsigned short status,
 
 	/*  drain fifo with pio */
 	if ((status & ADC_DONE_BIT) ||
-		((cmd->flags & TRIG_WAKE_EOS) &&
-			(status & ADC_INTR_PENDING_BIT) &&
-			(board(dev)->layout != LAYOUT_4020))) {
+	    ((cmd->flags & TRIG_WAKE_EOS) &&
+	     (status & ADC_INTR_PENDING_BIT) &&
+	     (board(dev)->layout != LAYOUT_4020))) {
 		DEBUG_PRINT("pio fifo drain\n");
 		spin_lock_irqsave(&dev->spinlock, flags);
 		if (priv(dev)->ai_cmd_running) {
@@ -2996,7 +3063,7 @@ void handle_ai_interrupt(struct comedi_device *dev, unsigned short status,
 	}
 	/*  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))) {
+	    (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) {
 		async->events |= COMEDI_CB_EOA;
 	}
 
@@ -3026,14 +3093,15 @@ static int last_ao_dma_load_completed(struct comedi_device *dev)
 		return 0;
 
 	transfer_address =
-		readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+	    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)
+static int ao_stopped_by_error(struct comedi_device *dev,
+			       const struct comedi_cmd *cmd)
 {
 	if (cmd->stop_src == TRIG_NONE)
 		return 1;
@@ -3047,10 +3115,10 @@ static int ao_stopped_by_error(struct comedi_device *dev, const struct comedi_cm
 }
 
 static inline int ao_dma_needs_restart(struct comedi_device *dev,
-	unsigned short dma_status)
+				       unsigned short dma_status)
 {
 	if ((dma_status & PLX_DMA_DONE_BIT) == 0 ||
-		(dma_status & PLX_DMA_EN_BIT) == 0)
+	    (dma_status & PLX_DMA_EN_BIT) == 0)
 		return 0;
 	if (last_ao_dma_load_completed(dev))
 		return 0;
@@ -3063,7 +3131,7 @@ 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);
+	    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);
@@ -3071,8 +3139,8 @@ static void restart_ao_dma(struct comedi_device *dev)
 	dma_start_sync(dev, 0);
 }
 
-static void handle_ao_interrupt(struct comedi_device *dev, unsigned short status,
-	unsigned int plx_status)
+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;
@@ -3091,12 +3159,12 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned short status
 	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))
+		    && !(dma0_status & PLX_DMA_DONE_BIT))
 			writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT,
-				priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+			       priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 		else
 			writeb(PLX_CLEAR_DMA_INTR_BIT,
-				priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+			       priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 		spin_unlock_irqrestore(&dev->spinlock, flags);
 		DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
 		if (dma0_status & PLX_DMA_EN_BIT) {
@@ -3114,11 +3182,11 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned short status
 		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));
+			    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));
+			    readl(priv(dev)->plx9080_iobase +
+				  PLX_DMA0_PCI_ADDRESS_REG));
 	}
 	cfc_handle_events(dev, s);
 }
@@ -3141,7 +3209,7 @@ static irqreturn_t handle_interrupt(int irq, void *d)
 	 * interrupt handler */
 	if (dev->attached == 0) {
 		DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring",
-			status);
+			    status);
 		return IRQ_HANDLED;
 	}
 	handle_ai_interrupt(dev, status, plx_status);
@@ -3192,7 +3260,7 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 	int range = CR_RANGE(insn->chanspec);
@@ -3203,14 +3271,14 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	/*  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);
+	       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));
+		       priv(dev)->main_iobase + dac_lsb_4020_reg(chan));
 		writew((data[0] >> 8) & 0xf,
-			priv(dev)->main_iobase + dac_msb_4020_reg(chan));
+		       priv(dev)->main_iobase + dac_msb_4020_reg(chan));
 	} else {
 		writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan));
 	}
@@ -3221,18 +3289,20 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 1;
 }
 
-static int ao_readback_insn(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)
 {
 	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)
+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;
+	    WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
 
 	if (cmd->start_src == TRIG_EXT) {
 		bits |= WAVEFORM_TRIG_EXT_BITS;
@@ -3249,7 +3319,8 @@ static void set_dac_control0_reg(struct comedi_device *dev, const struct comedi_
 	writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG);
 }
 
-static void set_dac_control1_reg(struct comedi_device *dev, const struct comedi_cmd *cmd)
+static void set_dac_control1_reg(struct comedi_device *dev,
+				 const struct comedi_cmd *cmd)
 {
 	int i;
 
@@ -3259,14 +3330,15 @@ static void set_dac_control1_reg(struct comedi_device *dev, const struct comedi_
 		channel = CR_CHAN(cmd->chanlist[i]);
 		range = CR_RANGE(cmd->chanlist[i]);
 		set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel,
-			range);
+				   range);
 	}
 	priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT;
 	writew(priv(dev)->dac_control1_bits,
-		priv(dev)->main_iobase + DAC_CONTROL1_REG);
+	       priv(dev)->main_iobase + DAC_CONTROL1_REG);
 }
 
-static void set_dac_select_reg(struct comedi_device *dev, const struct comedi_cmd *cmd)
+static void set_dac_select_reg(struct comedi_device *dev,
+			       const struct comedi_cmd *cmd)
 {
 	uint16_t bits;
 	unsigned int first_channel, last_channel;
@@ -3281,7 +3353,8 @@ static void set_dac_select_reg(struct comedi_device *dev, const struct comedi_cm
 	writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG);
 }
 
-static void set_dac_interval_regs(struct comedi_device *dev, const struct comedi_cmd *cmd)
+static void set_dac_interval_regs(struct comedi_device *dev,
+				  const struct comedi_cmd *cmd)
 {
 	unsigned int divisor;
 
@@ -3294,13 +3367,13 @@ static void set_dac_interval_regs(struct comedi_device *dev, const struct comedi
 		divisor = max_counter_value;
 	}
 	writew(divisor & 0xffff,
-		priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
+	       priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
 	writew((divisor >> 16) & 0xff,
-		priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
+	       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)
+				       const struct comedi_cmd *cmd)
 {
 	unsigned int num_bytes, buffer_index, prev_buffer_index;
 	unsigned int next_bits;
@@ -3309,7 +3382,7 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
 	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]);
+		    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)
@@ -3324,9 +3397,11 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
 	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_buffer[buffer_index],
+					       num_bytes);
 	priv(dev)->ao_dma_desc[buffer_index].transfer_size =
-		cpu_to_le32(num_bytes);
+	    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;
@@ -3348,7 +3423,7 @@ 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;
+	    priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
 	unsigned int buffer_index;
 
 	do {
@@ -3356,10 +3431,10 @@ static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
 		/* 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)
+		    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);
@@ -3377,13 +3452,14 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
 
 	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 / 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);
+					       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)->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)
@@ -3427,7 +3503,7 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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);
+				  PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
 
 	set_dac_control1_reg(dev, cmd);
 	s->async->inttrig = ao_inttrig;
@@ -3436,7 +3512,7 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trig_num)
+		      unsigned int trig_num)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
 	int retval;
@@ -3459,7 +3535,7 @@ static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+		      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -3502,14 +3578,14 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	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)
+	    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)
+	    cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
 		err++;
 
 	if (err)
@@ -3523,9 +3599,9 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 			err++;
 		}
 		if (get_ao_divisor(cmd->scan_begin_arg,
-				cmd->flags) > max_counter_value) {
+				   cmd->flags) > max_counter_value) {
 			cmd->scan_begin_arg =
-				(max_counter_value + 2) * TIMER_BASE;
+			    (max_counter_value + 2) * TIMER_BASE;
 			err++;
 		}
 	}
@@ -3547,8 +3623,7 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	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;
+		    get_divisor(cmd->scan_begin_arg, cmd->flags) * TIMER_BASE;
 		if (tmp_arg != cmd->scan_begin_arg)
 			err++;
 	}
@@ -3561,7 +3636,7 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 		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");
+					     "chanlist must use consecutive channels");
 				err++;
 				break;
 			}
@@ -3603,7 +3678,7 @@ static int dio_callback_4020(int dir, int port, int data, unsigned long iobase)
 }
 
 static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int bits;
 
@@ -3616,7 +3691,7 @@ static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	data[0] &= 0xf;
 	/*  zero bits we are going to change */
@@ -3631,8 +3706,9 @@ static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 2;
 }
 
-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_config_insn(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int mask;
 
@@ -3653,19 +3729,19 @@ static int dio_60xx_config_insn(struct comedi_device *dev, struct comedi_subdevi
 	}
 
 	writeb(s->io_bits,
-		priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
+	       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)
+			  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);
+		       priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
 	}
 
 	data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
@@ -3674,7 +3750,7 @@ static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static void caldac_write(struct comedi_device *dev, unsigned int channel,
-	unsigned int value)
+			 unsigned int value)
 {
 	priv(dev)->caldac_state[channel] = value;
 
@@ -3691,8 +3767,9 @@ static void caldac_write(struct comedi_device *dev, unsigned int channel,
 	}
 }
 
-static int calib_write_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)
 {
 	int channel = CR_CHAN(insn->chanspec);
 
@@ -3706,8 +3783,9 @@ static int calib_write_insn(struct comedi_device *dev, struct comedi_subdevice *
 	return 1;
 }
 
-static int calib_read_insn(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)
 {
 	unsigned int channel = CR_CHAN(insn->chanspec);
 
@@ -3717,7 +3795,7 @@ static int calib_read_insn(struct comedi_device *dev, struct comedi_subdevice *s
 }
 
 static void ad8402_write(struct comedi_device *dev, unsigned int channel,
-	unsigned int value)
+			 unsigned int value)
 {
 	static const int bitstream_length = 10;
 	unsigned int bit, register_bits;
@@ -3739,7 +3817,7 @@ static void ad8402_write(struct comedi_device *dev, unsigned int channel,
 		writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
 		udelay(ad8402_udelay);
 		writew(register_bits | SERIAL_CLOCK_BIT,
-			priv(dev)->main_iobase + CALIBRATION_REG);
+		       priv(dev)->main_iobase + CALIBRATION_REG);
 	}
 
 	udelay(ad8402_udelay);
@@ -3747,8 +3825,9 @@ static void ad8402_write(struct comedi_device *dev, unsigned int channel,
 }
 
 /* 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)
+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);
 
@@ -3764,8 +3843,9 @@ static int ad8402_write_insn(struct comedi_device *dev, struct comedi_subdevice
 	return 1;
 }
 
-static int ad8402_read_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)
 {
 	unsigned int channel = CR_CHAN(insn->chanspec);
 
@@ -3781,7 +3861,7 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
 	unsigned int bitstream = (read_command << 8) | address;
 	unsigned int bit;
 	void *const plx_control_addr =
-		priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+	    priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
 	uint16_t value;
 	static const int value_length = 16;
 	static const int eeprom_udelay = 1;
@@ -3836,8 +3916,9 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address)
 	return value;
 }
 
-static int eeprom_read_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)
 {
 	data[0] = read_eeprom(dev, CR_CHAN(insn->chanspec));
 
@@ -3853,7 +3934,7 @@ 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;
+	    max_counter_value + min_convert_divisor;
 	static const int min_scan_divisor_4020 = 2;
 	unsigned long long max_scan_divisor, min_scan_divisor;
 
@@ -3862,7 +3943,7 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 			cmd->convert_arg = 0;
 		} else {
 			convert_divisor =
-				get_divisor(cmd->convert_arg, cmd->flags);
+			    get_divisor(cmd->convert_arg, cmd->flags);
 			if (convert_divisor > max_convert_divisor)
 				convert_divisor = max_convert_divisor;
 			if (convert_divisor < min_convert_divisor)
@@ -3878,8 +3959,8 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 			/*  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;
+			    (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;
@@ -3931,7 +4012,8 @@ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
 	num_fifo_entries = num_samples / fifo->sample_packing_ratio;
 
 	retval = set_ai_fifo_segment_length(dev,
-		num_fifo_entries / fifo->num_segments);
+					    num_fifo_entries /
+					    fifo->num_segments);
 	if (retval < 0)
 		return retval;
 
@@ -3946,12 +4028,12 @@ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples)
 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;
+	    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)
+				      unsigned int num_entries)
 {
 	static const int increment_size = 0x100;
 	const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
@@ -3970,12 +4052,12 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev,
 	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)->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);
+		    priv(dev)->ai_fifo_segment_length);
 
 	return priv(dev)->ai_fifo_segment_length;
 }
@@ -4002,7 +4084,7 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev,
 */
 
 static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
-	uint8_t value)
+			     uint8_t value)
 {
 	static const int num_caldac_channels = 8;
 	static const int bitstream_length = 11;
@@ -4033,8 +4115,8 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
 }
 
 /* 4020 caldacs */
-static int caldac_i2c_write(struct comedi_device *dev, unsigned int caldac_channel,
-	unsigned int value)
+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;
@@ -4108,8 +4190,8 @@ static void i2c_set_sda(struct comedi_device *dev, int state)
 		priv(dev)->plx_control_bits &= ~data_bit;
 		writel(priv(dev)->plx_control_bits, plx_control_addr);
 		udelay(i2c_high_udelay);
-	} else			/*  set data line low */
-	{
+	} else {		/*  set data line low */
+
 		priv(dev)->plx_control_bits |= data_bit;
 		writel(priv(dev)->plx_control_bits, plx_control_addr);
 		udelay(i2c_low_udelay);
@@ -4127,8 +4209,8 @@ static void i2c_set_scl(struct comedi_device *dev, int state)
 		priv(dev)->plx_control_bits &= ~clock_bit;
 		writel(priv(dev)->plx_control_bits, plx_control_addr);
 		udelay(i2c_high_udelay);
-	} else			/*  set clock line low */
-	{
+	} else {		/*  set clock line low */
+
 		priv(dev)->plx_control_bits |= clock_bit;
 		writel(priv(dev)->plx_control_bits, plx_control_addr);
 		udelay(i2c_low_udelay);
@@ -4180,7 +4262,7 @@ static void i2c_stop(struct comedi_device *dev)
 }
 
 static void i2c_write(struct comedi_device *dev, unsigned int address,
-	const uint8_t *data, unsigned int length)
+		      const uint8_t * data, unsigned int length)
 {
 	unsigned int i;
 	uint8_t bitstream;
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
index 8f36294..7a5d46e 100644
--- a/drivers/staging/comedi/drivers/cb_pcidda.c
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -115,13 +115,13 @@ Please report success/failure with other different cards to
 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),
-		}
+	 BIP_RANGE(10),
+	 BIP_RANGE(5),
+	 BIP_RANGE(2.5),
+	 UNI_RANGE(10),
+	 UNI_RANGE(5),
+	 UNI_RANGE(2.5),
+	 }
 };
 
 /*
@@ -147,63 +147,64 @@ struct cb_pcidda_board {
 
 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-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-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-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-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-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,
-		},
+	 .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}
+	{
+	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);
@@ -239,11 +240,13 @@ struct cb_pcidda_private {
  */
 #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_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_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); */
@@ -251,11 +254,11 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_subdevice
 
 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);
+				 unsigned int num_bits);
 static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
-	unsigned int address);
+					  unsigned int address);
 static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
-	unsigned int range);
+				unsigned int range);
 
 /*
  * The struct comedi_driver structure tells the Comedi core module
@@ -274,7 +277,8 @@ static struct comedi_driver driver_cb_pcidda = {
  * 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)
+static int cb_pcidda_attach(struct comedi_device *dev,
+			    struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	struct pci_dev *pcidev;
@@ -294,29 +298,29 @@ static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *
 	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)) {
+	     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]) {
+				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 					continue;
 				}
 			}
 			for (index = 0; index < N_BOARDS; index++) {
 				if (cb_pcidda_boards[index].device_id ==
-					pcidev->device) {
+				    pcidev->device) {
 					goto found;
 				}
 			}
 		}
 	}
 	if (!pcidev) {
-		printk("Not a ComputerBoards/MeasurementComputing card on requested position\n");
+		printk
+		    ("Not a ComputerBoards/MeasurementComputing card on requested position\n");
 		return -EIO;
 	}
-      found:
+found:
 	devpriv->pci_dev = pcidev;
 	dev->board_ptr = cb_pcidda_boards + index;
 	/*  "thisboard" macro can be used from here. */
@@ -326,7 +330,8 @@ static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *
 	 * 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");
+		printk
+		    ("cb_pcidda: failed to enable PCI device and request regions\n");
 		return -EIO;
 	}
 
@@ -334,14 +339,17 @@ static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *
  * Allocate the I/O ports.
  */
 	devpriv->digitalio =
-		pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
+	    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");
+		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.
@@ -423,7 +431,8 @@ static int cb_pcidda_detach(struct comedi_device *dev)
  * I will program this later... ;-)
  */
 #if 0
-static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+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);
@@ -442,8 +451,9 @@ static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *
 #endif
 
 #if 0
-static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -489,7 +499,7 @@ static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 
 	/* note that mutual compatiblity is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER
-		&& cmd->scan_begin_src != TRIG_EXT)
+	    && cmd->scan_begin_src != TRIG_EXT)
 		err++;
 	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
 		err++;
@@ -569,21 +579,21 @@ static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	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);
+				      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);
+				      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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->scan_end_arg;
+			    cmd->convert_arg * cmd->scan_end_arg;
 			err++;
 		}
 	}
@@ -608,8 +618,9 @@ static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
 }
 #endif
 
-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_ao_winsn(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int command;
 	unsigned int channel, range;
@@ -676,7 +687,7 @@ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
 
 /* lowlevel write to eeprom/dac */
 static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
-	unsigned int num_bits)
+				 unsigned int num_bits)
 {
 	int i;
 
@@ -692,7 +703,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
 
 /* 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 address)
 {
 	unsigned int i;
 	unsigned int cal2_bits;
@@ -725,8 +736,9 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
 }
 
 /* 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)
+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;
@@ -787,14 +799,14 @@ static unsigned int fine_offset_channel(unsigned int ao_channel)
 
 /* 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)
+					  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)
+					unsigned int range)
 {
 	return 0x8 + 2 * range + 12 * ao_channel;
 }
@@ -813,7 +825,7 @@ static unsigned int eeprom_fine_byte(unsigned int word)
 
 /* 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 range)
 {
 	unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
 
@@ -822,27 +834,27 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
 
 	/*  get values from eeprom data */
 	coarse_offset =
-		eeprom_coarse_byte(devpriv->
-		eeprom_data[offset_eeprom_address(channel, range)]);
+	    eeprom_coarse_byte(devpriv->eeprom_data
+			       [offset_eeprom_address(channel, range)]);
 	fine_offset =
-		eeprom_fine_byte(devpriv->
-		eeprom_data[offset_eeprom_address(channel, range)]);
+	    eeprom_fine_byte(devpriv->eeprom_data
+			     [offset_eeprom_address(channel, range)]);
 	coarse_gain =
-		eeprom_coarse_byte(devpriv->
-		eeprom_data[gain_eeprom_address(channel, range)]);
+	    eeprom_coarse_byte(devpriv->eeprom_data
+			       [gain_eeprom_address(channel, range)]);
 	fine_gain =
-		eeprom_fine_byte(devpriv->
-		eeprom_data[gain_eeprom_address(channel, range)]);
+	    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);
+			       coarse_offset_channel(channel), coarse_offset);
 	cb_pcidda_write_caldac(dev, caldac_number(channel),
-		fine_offset_channel(channel), fine_offset);
+			       fine_offset_channel(channel), fine_offset);
 	cb_pcidda_write_caldac(dev, caldac_number(channel),
-		coarse_gain_channel(channel), coarse_gain);
+			       coarse_gain_channel(channel), coarse_gain);
 	cb_pcidda_write_caldac(dev, caldac_number(channel),
-		fine_gain_channel(channel), fine_gain);
+			       fine_gain_channel(channel), fine_gain);
 }
 
 /*
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
index dc70127..4d10bc3 100644
--- a/drivers/staging/comedi/drivers/cb_pcidio.c
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -63,23 +63,23 @@ struct pcidio_board {
 
 static const struct pcidio_board pcidio_boards[] = {
 	{
-	.name = "pci-dio24",
-	.n_8255 = 1,
-	.pcicontroler_badrindex = 1,
-	.dioregs_badrindex = 2,
-		},
+	 .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-dio24h",
+	 .n_8255 = 1,
+	 .pcicontroler_badrindex = 1,
+	 .dioregs_badrindex = 2,
+	 },
 	{
-	.name = "pci-dio48h",
-	.n_8255 = 2,
-	.pcicontroler_badrindex = 0,
-	.dioregs_badrindex = 1,
-		},
+	 .name = "pci-dio48h",
+	 .n_8255 = 2,
+	 .pcicontroler_badrindex = 0,
+	 .dioregs_badrindex = 1,
+	 },
 };
 
 /* This is used by modprobe to translate PCI IDs to drivers.  Should
@@ -87,10 +87,11 @@ static const struct pcidio_board pcidio_boards[] = {
 /* 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}
+	{
+	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);
@@ -127,7 +128,8 @@ struct pcidio_private {
  * 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_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",
@@ -197,15 +199,13 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
  */
 
 	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)) {
+	     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 < ARRAY_SIZE(pcidio_boards);
-			index++) {
+		for (index = 0; index < ARRAY_SIZE(pcidio_boards); index++) {
 			if (pcidio_pci_table[index].device != pcidev->device)
 				continue;
 
@@ -213,8 +213,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			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]) {
+				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 					continue;
 				}
 			}
@@ -224,10 +223,10 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	printk("No supported ComputerBoards/MeasurementComputing card found on "
-		"requested position\n");
+	       "requested position\n");
 	return -EIO;
 
-      found:
+found:
 
 /*
  * Initialize dev->board_name.  Note that we can use the "thisboard"
@@ -237,16 +236,17 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	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));
+	       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");
+		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);
+	    =
+	    pci_resource_start(devpriv->pci_dev,
+			       pcidio_boards[index].dioregs_badrindex);
 
 /*
  * Allocate the subdevice structures.  alloc_subdevice() is a
@@ -257,9 +257,9 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	for (i = 0; i < thisboard->n_8255; i++) {
 		subdev_8255_init(dev, dev->subdevices + i,
-			NULL, devpriv->dio_reg_base + i * 4);
+				 NULL, devpriv->dio_reg_base + i * 4);
 		printk(" subdev %d: base = 0x%lx\n", i,
-			devpriv->dio_reg_base + i * 4);
+		       devpriv->dio_reg_base + i * 4);
 	}
 
 	printk("attached\n");
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index 57d250c..cbbca05 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -103,29 +103,31 @@ struct cb_pcimdas_board {
 
 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,
+	 .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}
+	{
+	PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{
+	0}
 };
 
 MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
@@ -176,7 +178,8 @@ struct cb_pcimdas_private {
  * 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_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",
@@ -185,12 +188,15 @@ static struct comedi_driver driver_cb_pcimdas = {
 	.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);
+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
@@ -198,7 +204,8 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, struct comedi_subdevic
  * in the driver structure, dev->board_ptr contains that
  * address.
  */
-static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int cb_pcimdas_attach(struct comedi_device *dev,
+			     struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	struct pci_dev *pcidev;
@@ -219,22 +226,21 @@ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig
 	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)) {
+	     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)
+			    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]) {
+				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 					continue;
 				}
 			}
@@ -245,13 +251,13 @@ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig
 	}
 
 	printk("No supported ComputerBoards/MeasurementComputing card found on "
-		"requested position\n");
+	       "requested position\n");
 	return -EIO;
 
-      found:
+found:
 
 	printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,
-		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+	       pcidev->bus->number, PCI_SLOT(pcidev->devfn));
 
 	/*  Warn about non-tested features */
 	switch (thisboard->device_id) {
@@ -259,7 +265,7 @@ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig
 		break;
 	default:
 		printk("THIS CARD IS UNSUPPORTED.\n"
-			"PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
+		       "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
 	};
 
 	if (comedi_pci_enable(pcidev, "cb_pcimdas")) {
@@ -373,8 +379,9 @@ static int cb_pcimdas_detach(struct comedi_device *dev)
  * "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)
+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;
@@ -438,8 +445,9 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-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_winsn(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -466,8 +474,9 @@ static int cb_pcimdas_ao_winsn(struct comedi_device *dev, struct comedi_subdevic
 
 /* 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)
+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);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
index 57bb118..980fa0a 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdda.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -118,16 +118,16 @@ enum DIO_METHODS {
 
 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,
-		}
+	 .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,
+	 }
 };
 
 /*
@@ -143,9 +143,10 @@ static const struct board_struct boards[] = {
 /* 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}
+	{
+	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);
@@ -190,15 +191,15 @@ static struct comedi_driver cb_pcimdda_driver = {
 
 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. :) ) ");
+		   "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);
+		    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);
+		    struct comedi_insn *insn, unsigned int *data);
 
 /*---------------------------------------------------------------------------
   HELPER FUNCTION DECLARATIONS
@@ -207,7 +208,7 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 /* returns a maxdata value for a given n_bits */
 static inline unsigned int figure_out_maxdata(int bits)
 {
-	return ((unsigned int) 1 << bits) - 1;
+	return ((unsigned int)1 << bits) - 1;
 }
 
 /*
@@ -344,7 +345,7 @@ static int detach(struct comedi_device *dev)
 
 		if (devpriv->attached_successfully && thisboard)
 			printk("comedi%d: %s: detached\n", dev->minor,
-				thisboard->name);
+			       thisboard->name);
 
 	}
 
@@ -352,7 +353,7 @@ static int detach(struct comedi_device *dev)
 }
 
 static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -391,7 +392,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
    applications, I would imagine.
 */
 static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -431,8 +432,8 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
 	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)) {
+	     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;
@@ -444,8 +445,7 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
 			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]) {
+				    PCI_SLOT(pcidev->devfn) != it->options[1]) {
 					continue;
 				}
 			}
@@ -454,20 +454,21 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
 			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");
+				printk
+				    ("cb_pcimdda: Failed to enable PCI device and request regions\n");
 				return -EIO;
 			}
 			registers =
-				pci_resource_start(devpriv->pci_dev,
-				REGS_BADRINDEX);
+			    pci_resource_start(devpriv->pci_dev,
+					       REGS_BADRINDEX);
 			devpriv->registers = registers;
 			devpriv->dio_registers
-				= devpriv->registers + thisboard->dio_offset;
+			    = devpriv->registers + thisboard->dio_offset;
 			return 0;
 		}
 	}
 
 	printk("cb_pcimdda: No supported ComputerBoards/MeasurementComputing "
-		"card found at the requested position\n");
+	       "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 45cd41f..cf39a24 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -132,8 +132,8 @@ struct BondingBoard {
 
 static const struct BondingBoard bondingBoards[] = {
 	{
-		.name =	MODULE_NAME,
-	},
+	 .name = MODULE_NAME,
+	 },
 };
 
 /*
@@ -176,7 +176,8 @@ struct Private {
  * the board, and also about the kernel module that contains
  * the device code.
  */
-static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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(struct comedi_device *dev, struct comedi_devconfig *it);
@@ -186,10 +187,10 @@ static void doDevUnconfig(struct comedi_device *dev);
 static void *Realloc(const void *ptr, size_t len, size_t old_len);
 
 static struct comedi_driver driver_bonding = {
-      .driver_name =	MODULE_NAME,
-      .module =		THIS_MODULE,
-      .attach =		bonding_attach,
-      .detach =		bonding_detach,
+	.driver_name = MODULE_NAME,
+	.module = THIS_MODULE,
+	.attach = bonding_attach,
+	.detach = bonding_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
@@ -208,15 +209,18 @@ static struct comedi_driver driver_bonding = {
 	 * the type of board in software.  ISA PnP, PCI, and PCMCIA
 	 * devices are such boards.
 	 */
-      .board_name =	&bondingBoards[0].name,
-      .offset =		sizeof(struct BondingBoard),
-      .num_names =	ARRAY_SIZE(bondingBoards),
+	.board_name = &bondingBoards[0].name,
+	.offset = sizeof(struct BondingBoard),
+	.num_names = ARRAY_SIZE(bondingBoards),
 };
 
-static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+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);
+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,7 +228,8 @@ static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subd
  * in the driver structure, dev->board_ptr contains that
  * address.
  */
-static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int bonding_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 
@@ -293,7 +298,8 @@ static int bonding_detach(struct comedi_device *dev)
  * 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(struct comedi_device *dev, struct comedi_subdevice *s,
+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(unsigned int)*8)
@@ -317,14 +323,14 @@ static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 
 		/* Argh, we have >= LSAMPL_BITS chans.. take all bits */
 		if (bdev->nchans >= LSAMPL_BITS)
-			subdevMask = (unsigned int) (-1);
+			subdevMask = (unsigned int)(-1);
 
 		writeMask = (data[0] >> num_done) & subdevMask;
 		dataBits = (data[1] >> num_done) & subdevMask;
 
 		/* Read/Write the new digital lines */
 		if (comedi_dio_bitfield(bdev->dev, bdev->subdev, writeMask,
-				&dataBits) != 2)
+					&dataBits) != 2)
 			return -EINVAL;
 
 		/* Make room for the new bits in data[1], the return value */
@@ -340,7 +346,8 @@ static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 	return insn->n;
 }
 
-static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+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;
@@ -366,7 +373,7 @@ static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subd
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -435,7 +442,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
 
 		/* Do DIO, as that's all we support now.. */
 		while ((sdev = comedi_find_subdevice_by_type(d, COMEDI_SUBD_DIO,
-					sdev + 1)) > -1) {
+							     sdev + 1)) > -1) {
 			nchans = comedi_get_n_channels(d, sdev);
 			if (nchans <= 0) {
 				ERROR("comedi_get_n_channels() returned %d "
@@ -465,8 +472,8 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
 			/* ergh.. ugly.. we need to realloc :(  */
 			tmp = devpriv->ndevs * sizeof(bdev);
 			devpriv->devs =
-				Realloc(devpriv->devs,
-				++devpriv->ndevs * sizeof(bdev), tmp);
+			    Realloc(devpriv->devs,
+				    ++devpriv->ndevs * sizeof(bdev), tmp);
 			if (!devpriv->devs) {
 				ERROR("Could not allocate memory. "
 				      "Out of memory?");
@@ -478,10 +485,9 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
 	/** Append dev:subdev to devpriv->name */
 				char buf[20];
 				int left =
-					MAX_BOARD_NAME - strlen(devpriv->name) -
-					1;
+				    MAX_BOARD_NAME - strlen(devpriv->name) - 1;
 				snprintf(buf, sizeof(buf), "%d:%d ", dev->minor,
-					bdev->subdev);
+					 bdev->subdev);
 				buf[sizeof(buf) - 1] = 0;
 				strncat(devpriv->name, buf, left);
 			}
diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c
index 8ab8e73..f781154 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.c
+++ b/drivers/staging/comedi/drivers/comedi_fc.c
@@ -42,8 +42,8 @@ static void increment_scan_progress(struct comedi_subdevice *subd,
 }
 
 /* Writes an array of data points to comedi's buffer */
-unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data,
-				       unsigned int num_bytes)
+unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
+				       void *data, unsigned int num_bytes)
 {
 	struct comedi_async *async = subd->async;
 	unsigned int retval;
@@ -65,10 +65,11 @@ unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data
 
 	return num_bytes;
 }
+
 EXPORT_SYMBOL(cfc_write_array_to_buffer);
 
-unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, void *data,
-					unsigned int num_bytes)
+unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
+					void *data, unsigned int num_bytes)
 {
 	struct comedi_async *async = subd->async;
 
@@ -83,9 +84,11 @@ unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, void *dat
 
 	return num_bytes;
 }
+
 EXPORT_SYMBOL(cfc_read_array_from_buffer);
 
-unsigned int cfc_handle_events(struct comedi_device *dev, struct comedi_subdevice *subd)
+unsigned int cfc_handle_events(struct comedi_device *dev,
+			       struct comedi_subdevice *subd)
 {
 	unsigned int events = subd->async->events;
 
@@ -99,6 +102,7 @@ unsigned int cfc_handle_events(struct comedi_device *dev, struct comedi_subdevic
 
 	return events;
 }
+
 EXPORT_SYMBOL(cfc_handle_events);
 
 MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h
index 494ae3f..4b2cfd3 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.h
+++ b/drivers/staging/comedi/drivers/comedi_fc.h
@@ -40,8 +40,8 @@ static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *subd,
 	return cfc_write_array_to_buffer(subd, &data, sizeof(data));
 };
 
-static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *subd,
-						    unsigned int 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));
 };
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index f42897d..043afe4 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -91,13 +91,14 @@ pin, which can be used to wake up tasks.
 #define PARPORT_B 1
 #define PARPORT_C 2
 
-static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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,
-      .detach =		parport_detach,
+	.driver_name = "comedi_parport",
+	.module = THIS_MODULE,
+	.attach = parport_attach,
+	.detach = parport_detach,
 };
 
 COMEDI_INITCLEANUP(driver_parport);
@@ -124,7 +125,8 @@ static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 2;
 }
 
-static int parport_insn_config_a(struct comedi_device *dev, struct comedi_subdevice *s,
+static int parport_insn_config_a(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
 				 struct comedi_insn *insn, unsigned int *data)
 {
 	if (data[0]) {
@@ -168,7 +170,8 @@ static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 2;
 }
 
-static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s,
+static int parport_intr_insn(struct comedi_device *dev,
+			     struct comedi_subdevice *s,
 			     struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n < 1)
@@ -178,7 +181,8 @@ static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice
 	return 2;
 }
 
-static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+static int parport_intr_cmdtest(struct comedi_device *dev,
+				struct comedi_subdevice *s,
 				struct comedi_cmd *cmd)
 {
 	int err = 0;
@@ -253,7 +257,8 @@ static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	return 0;
 }
 
-static int parport_intr_cmd(struct comedi_device *dev, struct 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);
@@ -263,7 +268,8 @@ static int parport_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int parport_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int parport_intr_cancel(struct comedi_device *dev,
+			       struct comedi_subdevice *s)
 {
 	printk(KERN_DEBUG "parport_intr_cancel()\n");
 
@@ -292,7 +298,8 @@ static irqreturn_t parport_interrupt(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int parport_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	int ret;
 	unsigned int irq;
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 9b8cf62..ef83a1a 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -69,11 +69,11 @@ struct waveform_board {
 
 static const struct waveform_board waveform_boards[] = {
 	{
-		.name =		"comedi_test",
-		.ai_chans =	N_CHANS,
-		.ai_bits =	16,
-		.have_dio =	0,
-	},
+	 .name = "comedi_test",
+	 .ai_chans = N_CHANS,
+	 .ai_bits = 16,
+	 .have_dio = 0,
+	 },
 };
 
 #define thisboard ((const struct waveform_board *)dev->board_ptr)
@@ -84,7 +84,7 @@ struct waveform_private {
 	struct timeval last;	/* time at which last timer interrupt occured */
 	unsigned int uvolt_amplitude;	/* waveform amplitude in microvolts */
 	unsigned long usec_period;	/* waveform period in microseconds */
-	unsigned long usec_current; /* current time (modulo waveform period) */
+	unsigned long usec_current;	/* current time (modulo waveform period) */
 	unsigned long usec_remainder;	/* usec since last scan; */
 	unsigned long ai_count;	/* number of conversions remaining */
 	unsigned int scan_period;	/* scan period in usec */
@@ -94,36 +94,42 @@ struct waveform_private {
 };
 #define devpriv ((struct waveform_private *)dev->private)
 
-static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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,
-      .detach =		waveform_detach,
-      .board_name =	&waveform_boards[0].name,
-      .offset =		sizeof(struct waveform_board),
-      .num_names =	ARRAY_SIZE(waveform_boards),
+	.driver_name = "comedi_test",
+	.module = THIS_MODULE,
+	.attach = waveform_attach,
+	.detach = waveform_detach,
+	.board_name = &waveform_boards[0].name,
+	.offset = sizeof(struct waveform_board),
+	.num_names = ARRAY_SIZE(waveform_boards),
 };
 
 COMEDI_INITCLEANUP(driver_waveform);
 
-static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+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,
+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,
+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);
+			   unsigned long current_time);
 static short fake_squarewave(struct comedi_device *dev, unsigned int range,
-			       unsigned long current_time);
-static short fake_flatline(struct comedi_device *dev, unsigned int range,
 			     unsigned long current_time);
+static short fake_flatline(struct comedi_device *dev, unsigned int range,
+			   unsigned long current_time);
 static short fake_waveform(struct comedi_device *dev, unsigned int channel,
-			     unsigned int range, unsigned long current_time);
+			   unsigned int range, unsigned long current_time);
 
 /* 1000 nanosec in a microsec */
 static const int nano_per_micro = 1000;
@@ -132,9 +138,9 @@ static const int nano_per_micro = 1000;
 static const struct comedi_lrange waveform_ai_ranges = {
 	2,
 	{
-			BIP_RANGE(10),
-			BIP_RANGE(5),
-		}
+	 BIP_RANGE(10),
+	 BIP_RANGE(5),
+	 }
 };
 
 /*
@@ -144,7 +150,7 @@ static const struct comedi_lrange waveform_ai_ranges = {
 */
 static void waveform_ai_interrupt(unsigned long arg)
 {
-	struct comedi_device *dev = (struct comedi_device *) arg;
+	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;
@@ -156,27 +162,34 @@ static void waveform_ai_interrupt(unsigned long arg)
 	do_gettimeofday(&now);
 
 	elapsed_time =
-		1000000 * (now.tv_sec - devpriv->last.tv_sec) + now.tv_usec -
-		devpriv->last.tv_usec;
+	    1000000 * (now.tv_sec - devpriv->last.tv_sec) + now.tv_usec -
+	    devpriv->last.tv_usec;
 	devpriv->last = now;
 	num_scans =
-		(devpriv->usec_remainder + elapsed_time) / devpriv->scan_period;
+	    (devpriv->usec_remainder + elapsed_time) / devpriv->scan_period;
 	devpriv->usec_remainder =
-		(devpriv->usec_remainder + elapsed_time) % devpriv->scan_period;
+	    (devpriv->usec_remainder + elapsed_time) % devpriv->scan_period;
 	async->events = 0;
 
 	for (i = 0; i < num_scans; i++) {
 		for (j = 0; j < cmd->chanlist_len; j++) {
 			cfc_write_to_buffer(dev->read_subdev,
-				fake_waveform(dev, CR_CHAN(cmd->chanlist[j]),
-					CR_RANGE(cmd->chanlist[j]),
-					devpriv->usec_current +
-					i * devpriv->scan_period +
-					j * devpriv->convert_period));
+					    fake_waveform(dev,
+							  CR_CHAN(cmd->
+								  chanlist[j]),
+							  CR_RANGE(cmd->
+								   chanlist[j]),
+							  devpriv->
+							  usec_current +
+							  i *
+							  devpriv->scan_period +
+							  j *
+							  devpriv->
+							  convert_period));
 		}
 		devpriv->ai_count++;
 		if (cmd->stop_src == TRIG_COUNT
-			&& devpriv->ai_count >= cmd->stop_arg) {
+		    && devpriv->ai_count >= cmd->stop_arg) {
 			async->events |= COMEDI_CB_EOA;
 			break;
 		}
@@ -193,7 +206,8 @@ static void waveform_ai_interrupt(unsigned long arg)
 	comedi_event(dev, dev->read_subdev);
 }
 
-static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int waveform_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int amplitude = it->options[0];
@@ -255,8 +269,8 @@ static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *i
 	devpriv->timer.data = (unsigned long)dev;
 
 	printk(KERN_INFO "comedi%d: comedi_test: "
-		"%i microvolt, %li microsecond waveform attached\n", dev->minor,
-		devpriv->uvolt_amplitude, devpriv->usec_period);
+	       "%i microvolt, %li microsecond waveform attached\n", dev->minor,
+	       devpriv->uvolt_amplitude, devpriv->usec_period);
 	return 1;
 }
 
@@ -270,7 +284,8 @@ static int waveform_detach(struct comedi_device *dev)
 	return 0;
 }
 
-static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+static int waveform_ai_cmdtest(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
 			       struct comedi_cmd *cmd)
 {
 	int err = 0;
@@ -336,10 +351,10 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 			err++;
 		}
 		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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->chanlist_len;
+			    cmd->convert_arg * cmd->chanlist_len;
 			err++;
 		}
 	}
@@ -377,8 +392,8 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 		tmp = cmd->scan_begin_arg;
 		/* round to nearest microsec */
 		cmd->scan_begin_arg =
-			nano_per_micro * ((tmp +
-				(nano_per_micro / 2)) / nano_per_micro);
+		    nano_per_micro * ((tmp +
+				       (nano_per_micro / 2)) / nano_per_micro);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
@@ -386,8 +401,8 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 		tmp = cmd->convert_arg;
 		/* round to nearest microsec */
 		cmd->convert_arg =
-			nano_per_micro * ((tmp +
-				(nano_per_micro / 2)) / nano_per_micro);
+		    nano_per_micro * ((tmp +
+				       (nano_per_micro / 2)) / nano_per_micro);
 		if (tmp != cmd->convert_arg)
 			err++;
 	}
@@ -398,13 +413,14 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 	return 0;
 }
 
-static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int waveform_ai_cmd(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
 
 	if (cmd->flags & TRIG_RT) {
 		comedi_error(dev,
-			"commands at RT priority not supported in this driver");
+			     "commands at RT priority not supported in this driver");
 		return -1;
 	}
 
@@ -430,7 +446,8 @@ static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s
 	return 0;
 }
 
-static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int waveform_ai_cancel(struct comedi_device *dev,
+			      struct comedi_subdevice *s)
 {
 	devpriv->timer_running = 0;
 	del_timer(&devpriv->timer);
@@ -438,12 +455,13 @@ static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice
 }
 
 static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index,
-			     unsigned long current_time)
+			   unsigned long current_time)
 {
 	struct comedi_subdevice *s = dev->read_subdev;
 	unsigned int offset = s->maxdata / 2;
 	u64 value;
-	const struct 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;
@@ -458,13 +476,16 @@ static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index,
 
 	return offset + value;
 }
-static short fake_squarewave(struct comedi_device *dev, unsigned int range_index,
-			       unsigned long current_time)
+
+static short fake_squarewave(struct comedi_device *dev,
+			     unsigned int range_index,
+			     unsigned long current_time)
 {
 	struct comedi_subdevice *s = dev->read_subdev;
 	unsigned int offset = s->maxdata / 2;
 	u64 value;
-	const struct 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;
@@ -478,14 +499,14 @@ static short fake_squarewave(struct comedi_device *dev, unsigned int range_index
 }
 
 static short fake_flatline(struct comedi_device *dev, unsigned int range_index,
-			     unsigned long current_time)
+			   unsigned long current_time)
 {
 	return dev->read_subdev->maxdata / 2;
 }
 
 /* generates a different waveform depending on what channel is read */
 static short fake_waveform(struct comedi_device *dev, unsigned int channel,
-			     unsigned int range, unsigned long current_time)
+			   unsigned int range, unsigned long current_time)
 {
 	enum {
 		SAWTOOTH_CHAN,
@@ -505,7 +526,8 @@ static short fake_waveform(struct comedi_device *dev, unsigned int channel,
 	return fake_flatline(dev, range, current_time);
 }
 
-static int waveform_ai_insn_read(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)
 {
 	int i, chan = CR_CHAN(insn->chanspec);
@@ -516,7 +538,8 @@ static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdev
 	return insn->n;
 }
 
-static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+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
index 6c58e99..b16d652 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -57,9 +57,10 @@ static const struct contec_board contec_boards[] = {
 
 #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}
+	{
+	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);
@@ -75,7 +76,8 @@ struct contec_private {
 
 #define devpriv ((struct contec_private *)dev->private)
 
-static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -85,14 +87,16 @@ static struct comedi_driver driver_contec = {
 };
 
 /* 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);
+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);
+			  struct comedi_cmd *cmd);
 
 static int contec_ns_to_timer(unsigned int *ns, int round);
 #endif
@@ -113,22 +117,22 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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)) {
+	     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) {
+		    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)) {
+				    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");
+				printk
+				    ("error enabling PCI device and request regions!\n");
 				return -EIO;
 			}
 			dev->iobase = pci_resource_start(pcidev, 0);
@@ -180,7 +184,7 @@ static int contec_detach(struct comedi_device *dev)
 
 #if 0
 static int contec_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+			  struct comedi_cmd *cmd)
 {
 	printk("contec_cmdtest called\n");
 	return 0;
@@ -192,8 +196,9 @@ static int contec_ns_to_timer(unsigned int *ns, int round)
 }
 #endif
 
-static int contec_do_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)
 {
 
 	printk("contec_do_insn_bits called\n");
@@ -206,14 +211,15 @@ static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 		s->state &= ~data[0];
 		s->state |= data[0] & data[1];
 		printk("  out: %d on %lx\n", s->state,
-			dev->iobase + thisboard->out_offs);
+		       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)
+static int contec_di_insn_bits(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 
 	printk("contec_di_insn_bits called\n");
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
index d4526c6..078ec27 100644
--- a/drivers/staging/comedi/drivers/daqboard2000.c
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -107,13 +107,10 @@ Configuration options:
 		  |    	   +---------------- 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"
@@ -147,25 +144,32 @@ Configuration options:
 
 /* 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)
-	}
+								 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)
-	}
+								RANGE(-10, 10)
+								}
 };
 
 struct daqboard2000_hw {
@@ -297,7 +301,8 @@ struct daqboard2000_hw {
 #define DAQBOARD2000_PosRefDacSelect             0x0100
 #define DAQBOARD2000_NegRefDacSelect             0x0000
 
-static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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 = {
@@ -320,8 +325,9 @@ static const struct daq200_boardtype boardtypes[] = {
 #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}
+	{
+	0x1616, 0x0409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	0}
 };
 
 MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table);
@@ -394,17 +400,18 @@ static void setup_sampling(struct comedi_device *dev, int chan, int gain)
 	writeAcqScanListEntry(dev, word3);
 }
 
-static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
+	    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. */
@@ -436,9 +443,8 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_su
 			/* udelay(2); */
 		}
 		for (timeout = 0; timeout < 20; timeout++) {
-			if (fpga->
-				acqControl &
-				DAQBOARD2000_AcqResultsFIFOHasValidData) {
+			if (fpga->acqControl &
+			    DAQBOARD2000_AcqResultsFIFOHasValidData) {
 				break;
 			}
 			/* udelay(2); */
@@ -451,8 +457,10 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_su
 	return i;
 }
 
-static int daqboard2000_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -464,8 +472,10 @@ static int daqboard2000_ao_insn_read(struct comedi_device *dev, struct comedi_su
 	return i;
 }
 
-static int daqboard2000_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -521,7 +531,7 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev)
 	writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
 	udelay(10000);
 	writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
-	udelay(10000);	/* Not in the original code, but I like symmetry... */
+	udelay(10000);		/* Not in the original code, but I like symmetry... */
 }
 
 static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
@@ -550,14 +560,14 @@ static int daqboard2000_writeCPLD(struct comedi_device *dev, int data)
 	udelay(10);
 	writew(data, devpriv->daq + 0x1000);
 	if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
-		DAQBOARD2000_CPLD_INIT) {
+	    DAQBOARD2000_CPLD_INIT) {
 		result = 1;
 	}
 	return result;
 }
 
 static int initialize_daqboard2000(struct comedi_device *dev,
-	unsigned char *cpld_array, int len)
+				   unsigned char *cpld_array, int len)
 {
 	int result = -EIO;
 	/* Read the serial EEPROM control register */
@@ -585,7 +595,7 @@ static int initialize_daqboard2000(struct comedi_device *dev,
 		if (daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) {
 			for (i = 0; i < len; i++) {
 				if (cpld_array[i] == 0xff
-					&& cpld_array[i + 1] == 0x20) {
+				    && cpld_array[i + 1] == 0x20) {
 #ifdef DEBUG_EEPROM
 					printk("Preamble found at %d\n", i);
 #endif
@@ -594,8 +604,7 @@ static int initialize_daqboard2000(struct comedi_device *dev,
 			}
 			for (; i < len; i += 2) {
 				int data =
-					(cpld_array[i] << 8) + cpld_array[i +
-					1];
+				    (cpld_array[i] << 8) + cpld_array[i + 1];
 				if (!daqboard2000_writeCPLD(dev, data)) {
 					break;
 				}
@@ -702,7 +711,7 @@ rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sb
 */
 
 static int daqboard2000_8255_cb(int dir, int port, int data,
-	unsigned long ioaddr)
+				unsigned long ioaddr)
 {
 	int result = 0;
 	if (dir) {
@@ -718,7 +727,8 @@ static int daqboard2000_8255_cb(int dir, int port, int data,
 	return result;
 }
 
-static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int daqboard2000_attach(struct comedi_device *dev,
+			       struct comedi_devconfig *it)
 {
 	int result = 0;
 	struct comedi_subdevice *s;
@@ -737,21 +747,20 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
 		return -ENOMEM;
 	}
 	for (card = pci_get_device(0x1616, 0x0409, NULL);
-		card != NULL;
-		card = pci_get_device(0x1616, 0x0409, card)) {
+	     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) {
+			    PCI_SLOT(card->devfn) != slot) {
 				continue;
 			}
 		}
-		break;  /* found one */
+		break;		/* found one */
 	}
 	if (!card) {
 		if (bus || slot)
 			printk(" no daqboard2000 found at bus/slot: %d/%d\n",
-				bus, slot);
+			       bus, slot);
 		else
 			printk(" no daqboard2000 found\n");
 		return -EIO;
@@ -759,8 +768,8 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
 		u32 id;
 		int i;
 		devpriv->pci_dev = card;
-		id = ((u32) card->subsystem_device << 16) | card->
-			subsystem_vendor;
+		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);
@@ -768,7 +777,9 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
 			}
 		}
 		if (!dev->board_ptr) {
-			printk(" unknown subsystem id %08x (pretend it is an ids2)", id);
+			printk
+			    (" unknown subsystem id %08x (pretend it is an ids2)",
+			     id);
 			dev->board_ptr = boardtypes;
 		}
 	}
@@ -780,9 +791,9 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
 	}
 	devpriv->got_regions = 1;
 	devpriv->plx =
-		ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
+	    ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
 	devpriv->daq =
-		ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
+	    ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
 	if (!devpriv->plx || !devpriv->daq) {
 		return -ENOMEM;
 	}
@@ -844,10 +855,10 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
 
 	s = dev->subdevices + 2;
 	result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
-		(unsigned long)(dev->iobase + 0x40));
+				  (unsigned long)(dev->iobase + 0x40));
 
 	printk("\n");
-      out:
+out:
 	return result;
 }
 
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index c20cd8f..f425833 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -155,60 +155,66 @@ driver.
 /* 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);
+			  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);
+			  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);
+			  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);
+			       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)
-	}
+							  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),
-	}
+							   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)
-	}
+							  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
 
@@ -234,7 +240,7 @@ static const struct comedi_lrange *const das08_ai_lranges[] = {
 };
 
 static const int das08_pgh_gainlist[] =
-	{ 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 };
+    { 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 };
 
@@ -248,260 +254,261 @@ static const int *const das08_gainlists[] = {
 
 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 = "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-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-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-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-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-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-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 = "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 */
-		},
+	 .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,
-		},
+	 .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 */
-		},
+	 .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 = "das08/f",
+	 },
 	{
-	.name = "das08jr",
-		},
+	 .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 */
-		},
+	 .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 = "das48-pga",	/*  cio-das48-pga.pdf */
+	 },
 	{
-	.name = "das08-pga-g2",	/*  a KM board */
-		},
+	 .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,
-		},
+	 .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,
-		},
+	 .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}
+	{
+	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);
@@ -513,7 +520,7 @@ MODULE_DEVICE_TABLE(pci, das08_pci_table);
 #define TIMEOUT 100000
 
 static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int i, n;
 	int chan;
@@ -538,7 +545,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 		/* set gain/range */
 		range = CR_RANGE(insn->chanspec);
 		outb(devpriv->pg_gainlist[range],
-			dev->iobase + DAS08AO_GAIN_CONTROL);
+		     dev->iobase + DAS08AO_GAIN_CONTROL);
 	}
 
 	for (n = 0; n < insn->n; n++) {
@@ -580,7 +587,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	data[0] = 0;
 	data[1] = DAS08_IP(inb(dev->iobase + DAS08_STATUS));
@@ -589,7 +596,7 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int wbits;
 
@@ -611,8 +618,9 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 2;
 }
 
-static int das08jr_di_rbits(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)
 {
 	data[0] = 0;
 	data[1] = inb(dev->iobase + DAS08JR_DIO);
@@ -620,8 +628,9 @@ static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *
 	return 2;
 }
 
-static int das08jr_do_wbits(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)
 {
 	/*  null bits we are going to set */
 	devpriv->do_bits &= ~data[0];
@@ -634,8 +643,9 @@ static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *
 	return 2;
 }
 
-static int das08jr_ao_winsn(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)
 {
 	int n;
 	int lsb, msb;
@@ -668,8 +678,9 @@ static int das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
  * 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)
+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;
@@ -716,7 +727,7 @@ static unsigned int i8254_read_channel_low(unsigned int base, int chan)
 }
 
 static void i8254_write_channel_low(unsigned int base, int chan,
-	unsigned int value)
+				    unsigned int value)
 {
 	unsigned int msb, lsb;
 
@@ -740,7 +751,7 @@ static unsigned int i8254_read_channel(struct i8254_struct *st, int channel)
 }
 
 static void i8254_write_channel(struct i8254_struct *st, int channel,
-	unsigned int value)
+				unsigned int value)
 {
 	int chan = st->logic2phys[channel];
 
@@ -755,13 +766,13 @@ static void i8254_initialize(struct i8254_struct *st)
 }
 
 static void i8254_set_mode_low(unsigned int base, int channel,
-	unsigned int mode)
+			       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)
+			   unsigned int mode)
 {
 	int chan = st->logic2phys[channel];
 
@@ -782,8 +793,9 @@ static unsigned int i8254_read_status(struct i8254_struct *st, int 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)
+static int das08_counter_read(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = insn->chanspec;
 
@@ -794,8 +806,9 @@ static int das08_counter_read(struct comedi_device *dev, struct comedi_subdevice
 	return 1;
 }
 
-static int das08_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int das08_counter_write(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = insn->chanspec;
 
@@ -805,8 +818,9 @@ static int das08_counter_write(struct comedi_device *dev, struct comedi_subdevic
 	return 1;
 }
 
-static int das08_counter_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int das08_counter_config(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = insn->chanspec;
 
@@ -835,8 +849,7 @@ static struct comedi_driver driver_das08 = {
 	.attach = das08_attach,
 	.detach = das08_common_detach,
 	.board_name = &das08_boards[0].name,
-	.num_names = sizeof(das08_boards) /
-		sizeof(struct das08_board_struct),
+	.num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct),
 	.offset = sizeof(struct das08_board_struct),
 };
 
@@ -921,7 +934,8 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
 	/* 8255 */
 	if (thisboard->i8255_offset != 0) {
 		subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase +
-				thisboard->i8255_offset));
+							       thisboard->
+							       i8255_offset));
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
 	}
@@ -943,8 +957,8 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
 		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;
+		    devpriv->i8254.mode[1] =
+		    devpriv->i8254.mode[2] = I8254_MODE0 | I8254_BINARY;
 		i8254_initialize(&devpriv->i8254);
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
@@ -972,19 +986,19 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 #ifdef CONFIG_COMEDI_PCI
 		if (it->options[0] || it->options[1]) {
 			printk("bus %i slot %i ",
-				it->options[0], it->options[1]);
+			       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)) {
+		     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) {
+			    && 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]) {
+					    && PCI_SLOT(pdev->devfn) ==
+					    it->options[1]) {
 						break;
 					}
 				} else {
@@ -999,7 +1013,8 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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");
+			printk
+			    (" Error enabling PCI device and requesting regions\n");
 			return -EIO;
 		}
 		/*  read base addresses */
@@ -1018,10 +1033,10 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		/* Enable local interrupt 1 and pci interrupt */
 		outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR);
 #endif
-#else	/* CONFIG_COMEDI_PCI */
+#else /* CONFIG_COMEDI_PCI */
 		printk("this driver has not been built with PCI support.\n");
 		return -EINVAL;
-#endif	/* CONFIG_COMEDI_PCI */
+#endif /* CONFIG_COMEDI_PCI */
 	} else {
 		iobase = it->options[0];
 	}
@@ -1042,7 +1057,6 @@ int das08_common_detach(struct comedi_device *dev)
 		if (dev->iobase)
 			release_region(dev->iobase, thisboard->iosize);
 	}
-
 #ifdef CONFIG_COMEDI_PCI
 	if (devpriv) {
 		if (devpriv->pdev) {
diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h
index 7cdb3fc..35d2660 100644
--- a/drivers/staging/comedi/drivers/das08.h
+++ b/drivers/staging/comedi/drivers/das08.h
@@ -28,7 +28,8 @@ 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 };
+	das08_pgm
+};
 
 struct das08_board_struct {
 	const char *name;
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
index 8e44641..9cab21e 100644
--- a/drivers/staging/comedi/drivers/das08_cs.c
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -56,7 +56,8 @@ 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 int das08_cs_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it);
 
 static struct comedi_driver driver_das08_cs = {
 	.driver_name = "das08_cs",
@@ -64,12 +65,12 @@ static struct comedi_driver driver_das08_cs = {
 	.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),
+	.num_names = ARRAY_SIZE(das08_cs_boards),
 	.offset = sizeof(struct das08_board_struct),
 };
 
-static int das08_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int das08_cs_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	int ret;
 	unsigned long iobase;
@@ -122,7 +123,7 @@ 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)";
+    "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
@@ -226,7 +227,7 @@ 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;
+		((struct local_info_t *)link->priv)->stop = 1;
 		das08_pcmcia_release(link);
 	}
 
@@ -356,7 +357,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
 		/* If we got this far, we're cool! */
 		break;
 
-	      next_entry:
+next_entry:
 		last_fn = GetNextTuple;
 
 		last_ret = pcmcia_get_next_tuple(link, &tuple);
@@ -391,20 +392,20 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x",
-		dev->node.dev_name, link->conf.ConfigIndex);
+	       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);
+		       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);
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
 	printk("\n");
 
 	return;
 
-      cs_failed:
+cs_failed:
 	cs_error(link, last_fn, last_ret);
 	das08_pcmcia_release(link);
 
@@ -470,7 +471,7 @@ struct pcmcia_driver das08_cs_driver = {
 	.id_table = das08_cs_id_table,
 	.owner = THIS_MODULE,
 	.drv = {
-			.name = dev_info,
+		.name = dev_info,
 		},
 };
 
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
index 59af86a..10a87e6 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -238,61 +238,67 @@ static const int sample_size = 2;	/*  size in bytes of a sample from board */
 #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),
-	}
+							    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),
-	}
+							     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),
-	}
+							    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),
-	}
+							     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),
-	}
+							/*  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),
-	}
+							   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,
@@ -307,6 +313,7 @@ static const int *const das16_gainlists[] = {
 	das1600_gainlist,
 	das1600_gainlist,
 };
+
 static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
 	&range_unknown,
 	&range_das16jr,
@@ -314,6 +321,7 @@ static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
 	&range_das1x01_unip,
 	&range_das1x02_unip,
 };
+
 static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
 	&range_unknown,
 	&range_das16jr,
@@ -328,20 +336,23 @@ struct munge_info {
 };
 
 static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+			  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);
+			  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);
+			  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);
+			  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);
+			  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_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);
@@ -349,10 +360,10 @@ 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);
+				    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);
+						struct comedi_cmd cmd);
 
 static void reg_dump(struct comedi_device *dev);
 
@@ -376,324 +387,324 @@ struct das16_board {
 
 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-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-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 = "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",	/*  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/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 = "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 = "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 = "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 = "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-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-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-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-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-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 = "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-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/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-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-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/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-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},
+	 .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/330i",	/*  ? */
+	 },
 	{
-	.name = "das16/jr/ctr5",	/*  ? */
-		},
+	 .name = "das16/jr/ctr5",	/*  ? */
+	 },
 	{
-	.name = "cio-das16/m1/16",	/*  cio-das16_m1_16.pdf, this board is a bit quirky, no dma */
-		},
+	 .name = "cio-das16/m1/16",	/*  cio-das16_m1_16.pdf, this board is a bit quirky, no dma */
+	 },
 #endif
 };
 
@@ -717,6 +728,7 @@ 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 */
@@ -742,7 +754,7 @@ struct das16_private_struct {
 #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)
+			  struct comedi_cmd *cmd)
 {
 	int err = 0, tmp;
 	int gain, start_chan, i;
@@ -787,11 +799,11 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 
 	/* 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)
+	    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)
+	    cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
 		err++;
 	if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
 		err++;
@@ -826,9 +838,9 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 	/*  check against maximum frequency */
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		if (cmd->scan_begin_arg <
-			thisboard->ai_speed * cmd->chanlist_len) {
+		    thisboard->ai_speed * cmd->chanlist_len) {
 			cmd->scan_begin_arg =
-				thisboard->ai_speed * cmd->chanlist_len;
+			    thisboard->ai_speed * cmd->chanlist_len;
 			err++;
 		}
 	}
@@ -853,16 +865,20 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 		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);
+					       &(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);
+					       &(devpriv->divisor1),
+					       &(devpriv->divisor2),
+					       &(cmd->convert_arg),
+					       cmd->flags & TRIG_ROUND_MASK);
 		err += (tmp != cmd->convert_arg);
 	}
 	if (err)
@@ -874,14 +890,14 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 		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) {
+			    (start_chan + i) % s->n_chan) {
 				comedi_error(dev,
-					"entries in chanlist must be consecutive channels, counting upwards\n");
+					     "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");
+					     "entries in chanlist must all have the same gain\n");
 				err++;
 			}
 		}
@@ -901,19 +917,19 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 	int range;
 
 	if (devpriv->dma_chan == 0 || (dev->irq == 0
-			&& devpriv->timer_mode == 0)) {
+				       && devpriv->timer_mode == 0)) {
 		comedi_error(dev,
-			"irq (or use of 'timer mode') dma required to execute comedi_cmd");
+			     "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");
+			     "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);
+	    cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
 
 	/*  disable conversions for das1600 mode */
 	if (thisboard->size > 0x400) {
@@ -929,13 +945,13 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 	if (thisboard->ai_pg != das16_pg_none) {
 		range = CR_RANGE(cmd->chanlist[0]);
 		outb((das16_gainlists[thisboard->ai_pg])[range],
-			dev->iobase + DAS16_GAIN);
+		     dev->iobase + DAS16_GAIN);
 	}
 
 	/* set counter mode and counts */
 	cmd->convert_arg =
-		das16_set_pacer(dev, cmd->convert_arg,
-		cmd->flags & TRIG_ROUND_MASK);
+	    das16_set_pacer(dev, cmd->convert_arg,
+			    cmd->flags & TRIG_ROUND_MASK);
 	DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
 
 	/* enable counters */
@@ -960,7 +976,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
 	clear_dma_ff(devpriv->dma_chan);
 	devpriv->current_buffer = 0;
 	set_dma_addr(devpriv->dma_chan,
-		devpriv->dma_buffer_addr[devpriv->current_buffer]);
+		     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);
@@ -1031,7 +1047,7 @@ static void das16_reset(struct comedi_device *dev)
 }
 
 static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int i, n;
 	int range;
@@ -1051,7 +1067,7 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	if (thisboard->ai_pg != das16_pg_none) {
 		range = CR_RANGE(insn->chanspec);
 		outb((das16_gainlists[thisboard->ai_pg])[range],
-			dev->iobase + DAS16_GAIN);
+		     dev->iobase + DAS16_GAIN);
 	}
 
 	for (n = 0; n < insn->n; n++) {
@@ -1079,7 +1095,7 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int bits;
 
@@ -1091,7 +1107,7 @@ static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int wbits;
 
@@ -1111,7 +1127,7 @@ static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int lsb, msb;
@@ -1154,7 +1170,7 @@ static irqreturn_t das16_dma_interrupt(int irq, void *d)
 
 static void das16_timer_interrupt(unsigned long arg)
 {
-	struct comedi_device *dev = (struct comedi_device *) arg;
+	struct comedi_device *dev = (struct comedi_device *)arg;
 
 	das16_interrupt(dev);
 
@@ -1191,7 +1207,7 @@ static int disable_dma_on_even(struct comedi_device *dev)
 	}
 	if (i == disable_limit) {
 		comedi_error(dev,
-			"failed to get an even dma transfer, could be trouble.");
+			     "failed to get an even dma transfer, could be trouble.");
 	}
 	return residue;
 }
@@ -1248,13 +1264,13 @@ static void das16_interrupt(struct comedi_device *dev)
 
 	/*  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)
 		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]);
+			     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) */
@@ -1267,16 +1283,17 @@ static void das16_interrupt(struct comedi_device *dev)
 	spin_unlock_irqrestore(&dev->spinlock, spin_flags);
 
 	cfc_write_array_to_buffer(s,
-		devpriv->dma_buffer[buffer_index], num_bytes);
+				  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)
+				    int rounding_flags)
 {
 	i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
-		&(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
+				       &(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);
@@ -1295,12 +1312,12 @@ static void reg_dump(struct comedi_device *dev)
 	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));
+		    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));
+		    inb(dev->iobase + DAS1600_STATUS_B));
 }
 
 static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -1331,7 +1348,7 @@ static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+		       thisboard->id);
 	}
 
 	return 0;
@@ -1393,8 +1410,9 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/*  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");
+		    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;
 		}
 	}
@@ -1411,20 +1429,20 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		}
 	} else {
 		printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
-			iobase, iobase + 0x0f,
-			iobase + 0x400,
-			iobase + 0x400 + (thisboard->size & 0x3ff));
+		       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);
+			       iobase, iobase + 0x0f);
 			return -EIO;
 		}
 		if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
-				"das16")) {
+				    "das16")) {
 			release_region(iobase, 0x10);
 			printk(" I/O port conflict:  0x%04lx-0x%04lx\n",
-				iobase + 0x400,
-				iobase + 0x400 + (thisboard->size & 0x3ff));
+			       iobase + 0x400,
+			       iobase + 0x400 + (thisboard->size & 0x3ff));
 			return -EIO;
 		}
 	}
@@ -1470,13 +1488,16 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		int i;
 		for (i = 0; i < 2; i++) {
 			devpriv->dma_buffer[i] = pci_alloc_consistent(NULL,
-				DAS16_DMA_SIZE, &devpriv->dma_buffer_addr[i]);
+								      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);
+			       dma_chan);
 			return -EINVAL;
 		}
 		devpriv->dma_chan = dma_chan;
@@ -1494,11 +1515,11 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	/*  get any user-defined input range */
 	if (thisboard->ai_pg == das16_pg_none &&
-		(it->options[4] || it->options[5])) {
+	    (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);
+		    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;
@@ -1510,8 +1531,8 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+		    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;
@@ -1612,7 +1633,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* 8255 */
 	if (thisboard->i8255_offset != 0) {
 		subdev_8255_init(dev, s, NULL, (dev->iobase +
-				thisboard->i8255_offset));
+						thisboard->i8255_offset));
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
 	}
@@ -1646,8 +1667,9 @@ static int das16_detach(struct comedi_device *dev)
 		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]);
+						    devpriv->dma_buffer[i],
+						    devpriv->
+						    dma_buffer_addr[i]);
 		}
 		if (devpriv->dma_chan)
 			free_dma(devpriv->dma_chan);
@@ -1666,7 +1688,7 @@ static int das16_detach(struct comedi_device *dev)
 		} else {
 			release_region(dev->iobase, 0x10);
 			release_region(dev->iobase + 0x400,
-				thisboard->size & 0x3ff);
+				       thisboard->size & 0x3ff);
 		}
 	}
 
@@ -1677,7 +1699,7 @@ 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)
+						struct comedi_cmd cmd)
 {
 	unsigned int size;
 	unsigned int freq;
@@ -1717,8 +1739,10 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
 	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)
+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;
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
index 3da8bf4..c403d88 100644
--- a/drivers/staging/comedi/drivers/das16m1.c
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -120,36 +120,41 @@ irq can be omitted, although the cmd interface will not work without it.
 
 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),
-		}
+	 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_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);
 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 unsigned int das16m1_set_pacer(struct comedi_device *dev,
+				      unsigned int ns, int round_flag);
 
 static int das16m1_irq_bits(unsigned int irq);
 
@@ -160,12 +165,13 @@ struct das16m1_board {
 
 static const struct das16m1_board das16m1_boards[] = {
 	{
-	.name = "cio-das16/m1",	/*  CIO-DAS16_M1.pdf */
-	.ai_speed = 1000,	/*  1MHz max speed */
-		},
+	 .name = "cio-das16/m1",	/*  CIO-DAS16_M1.pdf */
+	 .ai_speed = 1000,	/*  1MHz max speed */
+	 },
 };
 
-static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -199,8 +205,8 @@ 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)
+static int das16m1_cmd_test(struct comedi_device *dev,
+			    struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	unsigned int err = 0, tmp, i;
 
@@ -289,8 +295,10 @@ static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *
 		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);
+					       &(devpriv->divisor1),
+					       &(devpriv->divisor2),
+					       &(cmd->convert_arg),
+					       cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->convert_arg)
 			err++;
 	}
@@ -304,13 +312,13 @@ static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *
 			/*  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");
+					     " 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");
+				     "chanlist must be of even length or length 1");
 			err++;
 		}
 	}
@@ -321,7 +329,8 @@ static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
+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;
@@ -345,20 +354,20 @@ static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *
 	/* 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);
+	    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]));
+		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);
+	    das16m1_set_pacer(dev, cmd->convert_arg,
+			      cmd->flags & TRIG_ROUND_MASK);
 
 	/*  set control & status register */
 	byte = 0;
@@ -392,8 +401,9 @@ static int das16m1_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 	return 0;
 }
 
-static int das16m1_ai_rinsn(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)
 {
 	int i, n;
 	int byte;
@@ -405,8 +415,8 @@ static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *
 
 	/* setup channel/gain queue */
 	outb(0, dev->iobase + DAS16M1_QUEUE_ADDR);
-	byte = Q_CHAN(CR_CHAN(insn->chanspec)) | Q_RANGE(CR_RANGE(insn->
-			chanspec));
+	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++) {
@@ -429,8 +439,9 @@ static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *
 	return n;
 }
 
-static int das16m1_di_rbits(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)
 {
 	unsigned int bits;
 
@@ -441,8 +452,9 @@ static int das16m1_di_rbits(struct comedi_device *dev, struct comedi_subdevice *
 	return 2;
 }
 
-static int das16m1_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int das16m1_do_wbits(struct comedi_device *dev,
+			    struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int wbits;
 
@@ -552,7 +564,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
 	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));
+				  num_samples * sizeof(short));
 	devpriv->adc_count += num_samples;
 
 	if (cmd->stop_src == TRIG_COUNT) {
@@ -577,17 +589,18 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
 /* 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)
+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);
+				       &(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);
+		   2);
 	i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2,
-		2);
+		   2);
 
 	return ns;
 }
@@ -634,7 +647,8 @@ static int das16m1_irq_bits(unsigned int irq)
  *   1  IRQ
  */
 
-static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int das16m1_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int ret;
@@ -652,14 +666,14 @@ static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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);
+	       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)) {
+			    driver_das16m1.driver_name)) {
 		release_region(iobase, DAS16M1_SIZE);
 		printk(" I/O port conflict\n");
 		return -EIO;
@@ -682,7 +696,7 @@ static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		printk(", no irq\n");
 	} else {
 		printk(", invalid irq\n"
-			" valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
+		       " valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
index a343408..6ea59cc 100644
--- a/drivers/staging/comedi/drivers/das1800.c
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -181,33 +181,44 @@ enum {
 	das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
 };
 
-static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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 int das1800_cancel(struct comedi_device *dev,
+			  struct comedi_subdevice *s);
 static irqreturn_t das1800_interrupt(int irq, void *d);
-static int das1800_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s);
+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_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);
+					  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);
+					  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);
@@ -217,29 +228,29 @@ static unsigned int suggest_transfer_size(struct comedi_cmd *cmd);
 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),
-		}
+	 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),
-		}
+	 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 {
@@ -260,203 +271,203 @@ struct das1800_board {
  */
 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",
+	 .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-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",
+	 .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-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",
+	 .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-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-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-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",
+	 .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-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",
+	 .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-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",
+	 .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-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-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-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-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,
-		},
+	 .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,
+	 },
 };
 
 /*
@@ -490,8 +501,8 @@ struct das1800_private {
 static const struct comedi_lrange range_ao_1 = {
 	1,
 	{
-			RANGE(-10, 10),
-		}
+	 RANGE(-10, 10),
+	 }
 };
 
 /* analog out range for 'ao' boards */
@@ -522,7 +533,7 @@ static struct comedi_driver driver_das1800 = {
 COMEDI_INITCLEANUP(driver_das1800);
 
 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
-	unsigned int dma1)
+			    unsigned int dma1)
 {
 	unsigned long flags;
 
@@ -550,8 +561,8 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
 			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");
+			       " Dual dma only allows the following combinations:\n"
+			       " dma 5,6 / 6,7 / or 7,5\n");
 			return -EINVAL;
 			break;
 		}
@@ -564,7 +575,7 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
 		if (dma1) {
 			if (request_dma(dma1, driver_das1800.driver_name)) {
 				printk(" failed to allocate dma channel %i\n",
-					dma1);
+				       dma1);
 				return -EINVAL;
 			}
 			devpriv->dma1 = dma1;
@@ -575,7 +586,7 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
 		devpriv->dma_current_buf = devpriv->ai_buf0;
 		if (dma1) {
 			devpriv->ai_buf1 =
-				kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+			    kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
 			if (devpriv->ai_buf1 == NULL)
 				return -ENOMEM;
 		}
@@ -591,7 +602,8 @@ static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
 	return 0;
 }
 
-static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int das1800_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	unsigned long iobase = it->options[0];
@@ -607,7 +619,7 @@ static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		return -ENOMEM;
 
 	printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
-		iobase);
+	       iobase);
 	if (irq) {
 		printk(", irq %u", irq);
 		if (dma0) {
@@ -625,7 +637,9 @@ static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it
 
 	/* 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);
+		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;
@@ -643,8 +657,10 @@ static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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);
+				    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;
@@ -694,7 +710,7 @@ static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it
 
 	if (devpriv->ai_buf0 == NULL) {
 		devpriv->ai_buf0 =
-			kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
+		    kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
 		if (devpriv->ai_buf0 == NULL)
 			return -ENOMEM;
 	}
@@ -759,7 +775,7 @@ static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	if (thisboard->ao_ability == 1) {
 		/*  select 'update' dac channel for baseAddress + 0x0 */
 		outb(DAC(thisboard->ao_n_chan - 1),
-			dev->iobase + DAS1800_SELECT);
+		     dev->iobase + DAS1800_SELECT);
 		outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
 	}
 
@@ -787,7 +803,7 @@ static int das1800_detach(struct comedi_device *dev)
 	}
 
 	printk("comedi%d: %s: remove\n", dev->minor,
-		driver_das1800.driver_name);
+	       driver_das1800.driver_name);
 
 	return 0;
 };
@@ -800,42 +816,45 @@ static int das1800_probe(struct comedi_device *dev)
 	int board;
 
 	id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;	/* get id bits */
-	board = ((struct das1800_board *) dev->board_ptr) - das1800_boards;
+	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) {
+		    board == das1701st_da || board == das1702st_da) {
 			printk(" Board model: %s\n",
-				das1800_boards[board].name);
+			       das1800_boards[board].name);
 			return board;
 		}
-		printk(" Board model (probed, not recommended): das-1800st-da series\n");
+		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);
+			       das1800_boards[board].name);
 			return board;
 		}
-		printk(" Board model (probed, not recommended): das-1802hr-da\n");
+		printk
+		    (" Board model (probed, not recommended): das-1802hr-da\n");
 		return das1802hr;
 		break;
 	case 0x5:
 		if (board == das1801ao || board == das1802ao ||
-			board == das1701ao || board == das1702ao) {
+		    board == das1701ao || board == das1702ao) {
 			printk(" Board model: %s\n",
-				das1800_boards[board].name);
+			       das1800_boards[board].name);
 			return board;
 		}
-		printk(" Board model (probed, not recommended): das-1800ao series\n");
+		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);
+			       das1800_boards[board].name);
 			return board;
 		}
 		printk(" Board model (probed, not recommended): das-1802hr\n");
@@ -843,32 +862,37 @@ static int das1800_probe(struct comedi_device *dev)
 		break;
 	case 0x7:
 		if (board == das1801st || board == das1802st ||
-			board == das1701st || board == das1702st) {
+		    board == das1701st || board == das1702st) {
 			printk(" Board model: %s\n",
-				das1800_boards[board].name);
+			       das1800_boards[board].name);
 			return board;
 		}
-		printk(" Board model (probed, not recommended): das-1800st series\n");
+		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);
+			       das1800_boards[board].name);
 			return board;
 		}
-		printk(" Board model (probed, not recommended): das-1800hc series\n");
+		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);
+		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)
+static int das1800_ai_poll(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	unsigned long flags;
 
@@ -963,18 +987,18 @@ static void das1800_ai_handler(struct comedi_device *dev)
 	return;
 }
 
-static void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int status)
+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);
+				  devpriv->dma_current_buf);
 	/*  re-enable  dma channel */
 	set_dma_addr(devpriv->dma_current,
-		virt_to_bus(devpriv->dma_current_buf));
+		     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);
@@ -999,14 +1023,14 @@ static void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevic
 }
 
 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
-	uint16_t sample)
+					    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)
+static void munge_data(struct comedi_device *dev, uint16_t * array,
+		       unsigned int num_elements)
 {
 	unsigned int i;
 	int unipolar;
@@ -1024,8 +1048,9 @@ static void munge_data(struct comedi_device *dev, uint16_t *array,
 
 /* 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)
+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;
@@ -1054,14 +1079,15 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_s
 
 /* 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)
+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);
+				  devpriv->dma_current_buf);
 
 	if (dual_dma) {
 		/*  switch to other channel and flush it */
@@ -1073,7 +1099,7 @@ static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice
 			devpriv->dma_current_buf = devpriv->ai_buf0;
 		}
 		das1800_flush_dma_channel(dev, s, devpriv->dma_current,
-			devpriv->dma_current_buf);
+					  devpriv->dma_current_buf);
 	}
 
 	release_dma_lock(flags);
@@ -1085,7 +1111,7 @@ static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice
 }
 
 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
-	struct comedi_subdevice *s)
+					  struct comedi_subdevice *s)
 {
 	int numPoints = 0;	/* number of points to read */
 	struct comedi_cmd *cmd = &s->async->cmd;
@@ -1097,14 +1123,14 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev,
 	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]));
+				  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)
+					  struct comedi_subdevice *s)
 {
 	short dpnt;
 	int unipolar;
@@ -1140,8 +1166,9 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 /* test analog input cmd */
-static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int das1800_ai_do_cmdtest(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -1185,17 +1212,17 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdev
 	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)
+	    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)
+	    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)
+	    cmd->convert_src != TRIG_TIMER)
 		err++;
 
 	if (err)
@@ -1250,9 +1277,11 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdev
 			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);
+						       &(devpriv->divisor1),
+						       &(devpriv->divisor2),
+						       &(cmd->convert_arg),
+						       cmd->
+						       flags & TRIG_ROUND_MASK);
 			if (tmp_arg != cmd->convert_arg)
 				err++;
 		}
@@ -1261,27 +1290,32 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdev
 			/*  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);
+			    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->scan_begin_arg =
-						cmd->convert_arg *
-						cmd->chanlist_len;
+					    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);
+							       &(devpriv->
+								 divisor1),
+							       &(devpriv->
+								 divisor2),
+							       &(cmd->
+								 scan_begin_arg),
+							       cmd->
+							       flags &
+							       TRIG_ROUND_MASK);
 				if (tmp_arg != cmd->scan_begin_arg)
 					err++;
 			}
@@ -1297,7 +1331,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdev
 		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");
+					     "unipolar and bipolar ranges cannot be mixed in the chanlist");
 				err++;
 				break;
 			}
@@ -1394,9 +1428,11 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
 		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);
+						       &(devpriv->divisor1),
+						       &(devpriv->divisor2),
+						       &(cmd.convert_arg),
+						       cmd.
+						       flags & TRIG_ROUND_MASK);
 			if (das1800_set_frequency(dev) < 0) {
 				return -1;
 			}
@@ -1405,8 +1441,9 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
 	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);
+					       &(devpriv->divisor2),
+					       &(cmd.scan_begin_arg),
+					       cmd.flags & TRIG_ROUND_MASK);
 		if (das1800_set_frequency(dev) < 0) {
 			return -1;
 		}
@@ -1478,9 +1515,9 @@ static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
 	/* 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);
+		    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 */
@@ -1490,7 +1527,8 @@ static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
 }
 
 /* analog input do_cmd */
-static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int das1800_ai_do_cmd(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	int ret;
 	int control_a, control_c;
@@ -1499,7 +1537,7 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
 
 	if (!dev->irq) {
 		comedi_error(dev,
-			"no irq assigned for das-1800, cannot do hardware conversions");
+			     "no irq assigned for das-1800, cannot do hardware conversions");
 		return -1;
 	}
 
@@ -1542,7 +1580,7 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
 	if (control_c & BMDE) {
 		/*  program conversion period with number of microseconds minus 1 */
 		outb(cmd.convert_arg / 1000 - 1,
-			dev->iobase + DAS1800_BURST_RATE);
+		     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 */
@@ -1553,8 +1591,9 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
 }
 
 /* read analog input */
-static int das1800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -1613,8 +1652,9 @@ static int das1800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *
 }
 
 /* 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)
+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); */
@@ -1642,8 +1682,9 @@ static int das1800_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
 }
 
 /* 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)
+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;
@@ -1653,8 +1694,9 @@ static int das1800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *
 }
 
 /* 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)
+static int das1800_do_wbits(struct comedi_device *dev,
+			    struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int wbits;
 
@@ -1679,11 +1721,11 @@ static int das1800_set_frequency(struct comedi_device *dev)
 
 	/*  counter 1, mode 2 */
 	if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
-			2))
+		       2))
 		err++;
 	/*  counter 2, mode 2 */
 	if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
-			2))
+		       2))
 		err++;
 	if (err)
 		return -1;
@@ -1736,7 +1778,7 @@ static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
 		break;
 	case TRIG_TIMER:
 		size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
-			sample_size;
+		    sample_size;
 		break;
 	default:
 		size = DMA_BUF_SIZE;
@@ -1747,7 +1789,7 @@ static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
 	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)
+	    cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
 		max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
 
 	if (size > max_size)
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
index 0114eb9..92487f5 100644
--- a/drivers/staging/comedi/drivers/das6402.c
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -99,7 +99,8 @@ This driver has suffered bitrot.
 #define	C2 0x80
 #define	RWLH 0x30
 
-static int das6402_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -117,7 +118,8 @@ struct das6402_private {
 };
 #define devpriv ((struct das6402_private *)dev->private)
 
-static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subdevice *s);
+static void das6402_ai_fifo_dregs(struct comedi_device *dev,
+				  struct comedi_subdevice *s);
 
 static void das6402_setcounter(struct comedi_device *dev)
 {
@@ -163,7 +165,7 @@ static irqreturn_t intr_handler(int irq, void *d)
 	}
 #ifdef DEBUG
 	printk("das6402: interrupt! das6402_irqcount=%i\n",
-		devpriv->das6402_irqcount);
+	       devpriv->das6402_irqcount);
 	printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2));
 #endif
 
@@ -174,7 +176,7 @@ static irqreturn_t intr_handler(int irq, void *d)
 		outb(0x07, dev->iobase + 8);	/* clears all flip-flops */
 #ifdef DEBUG
 		printk("das6402: Got %i samples\n\n",
-			devpriv->das6402_wordsread - diff);
+		       devpriv->das6402_wordsread - diff);
 #endif
 		s->async->events |= COMEDI_CB_EOA;
 		comedi_event(dev, s);
@@ -196,7 +198,8 @@ static void das6402_ai_fifo_read(struct comedi_device *dev, short *data, int n)
 }
 #endif
 
-static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
+static void das6402_ai_fifo_dregs(struct comedi_device *dev,
+				  struct comedi_subdevice *s)
 {
 	while (1) {
 		if (!(inb(dev->iobase + 8) & 0x01))
@@ -205,7 +208,8 @@ static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subde
 	}
 }
 
-static int das6402_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int das6402_ai_cancel(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	/*
 	 *  This function should reset the board from whatever condition it
@@ -227,8 +231,8 @@ static int das6402_ai_cancel(struct comedi_device *dev, struct comedi_subdevice
 }
 
 #ifdef unused
-static int das6402_ai_mode2(struct comedi_device *dev, struct comedi_subdevice *s,
-	comedi_trig *it)
+static int das6402_ai_mode2(struct comedi_device *dev,
+			    struct comedi_subdevice *s, comedi_trig * it)
 {
 	devpriv->das6402_ignoreirq = 1;
 
@@ -300,7 +304,8 @@ static int das6402_detach(struct comedi_device *dev)
 	return 0;
 }
 
-static int das6402_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int das6402_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	unsigned int irq;
 	unsigned long iobase;
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
index 70e9d69..ecb97cd 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -118,114 +118,114 @@ struct das800_board {
 static const struct comedi_lrange range_das800_ai = {
 	1,
 	{
-			RANGE(-5, 5),
-		}
+	 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),
-		}
+	 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),
-		}
+	 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),
-		}
+	 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),
-		}
+	 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 = "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 = "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 = "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 = "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 = "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",
+	 .ai_speed = 20000,
+	 .ai_range = &range_das802_ai,
+	 .resolution = 12,
+	 },
 	{
-	.name = "cio-das802/16",
-	.ai_speed = 10000,
-	.ai_range = &range_das80216_ai,
-	.resolution = 16,
-		},
+	 .name = "cio-das802/16",
+	 .ai_speed = 10000,
+	 .ai_range = &range_das80216_ai,
+	 .resolution = 16,
+	 },
 };
 
 /*
@@ -243,7 +243,8 @@ struct das800_private {
 
 #define devpriv ((struct das800_private *)dev->private)
 
-static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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);
 
@@ -260,15 +261,20 @@ static struct comedi_driver driver_das800 = {
 static irqreturn_t das800_interrupt(int irq, void *d);
 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_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);
 
@@ -330,7 +336,7 @@ static int das800_probe(struct comedi_device *dev)
 		break;
 	default:
 		printk(" Board model: probe returned 0x%x (unknown)\n",
-			id_bits);
+		       id_bits);
 		return board;
 		break;
 	}
@@ -429,7 +435,7 @@ static irqreturn_t das800_interrupt(int irq, void *d)
 		 * 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);
+		     dev->iobase + DAS800_CONTROL1);
 		spin_unlock_irqrestore(&dev->spinlock, irq_flags);
 		/* otherwise, stop taking data */
 	} else {
@@ -585,8 +591,9 @@ static void disable_das800(struct comedi_device *dev)
 	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)
+static int das800_ai_do_cmdtest(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -676,8 +683,9 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 		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);
+					       &(devpriv->divisor2),
+					       &(cmd->convert_arg),
+					       cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->convert_arg)
 			err++;
 	}
@@ -691,14 +699,14 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 		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) {
+			    (startChan + i) % N_CHAN_AI) {
 				comedi_error(dev,
-					"entries in chanlist must be consecutive channels, counting upwards\n");
+					     "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");
+					     "entries in chanlist must all have the same gain\n");
 				err++;
 			}
 		}
@@ -710,7 +718,8 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	return 0;
 }
 
-static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int das800_ai_do_cmd(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	int startChan, endChan, scan, gain;
 	int conv_bits;
@@ -719,7 +728,7 @@ static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
 
 	if (!dev->irq) {
 		comedi_error(dev,
-			"no irq assigned for das-800, cannot do hardware conversions");
+			     "no irq assigned for das-800, cannot do hardware conversions");
 		return -1;
 	}
 
@@ -767,8 +776,10 @@ static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
 		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);
+					       &(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;
@@ -789,8 +800,9 @@ static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int das800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -843,8 +855,9 @@ static int das800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 	return n;
 }
 
-static int das800_di_rbits(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)
 {
 	unsigned int bits;
 
@@ -856,8 +869,9 @@ static int das800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s
 	return 2;
 }
 
-static int das800_do_wbits(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)
 {
 	int wbits;
 	unsigned long irq_flags;
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
index 573cbe7..aeec1ee 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -168,11 +168,11 @@ Configuration Options:
 static const struct comedi_lrange dmm32at_airanges = {
 	4,
 	{
-			UNI_RANGE(10),
-			UNI_RANGE(5),
-			BIP_RANGE(10),
-			BIP_RANGE(5),
-		}
+	 UNI_RANGE(10),
+	 UNI_RANGE(5),
+	 BIP_RANGE(10),
+	 BIP_RANGE(5),
+	 }
 };
 
 /* register values for above ranges */
@@ -189,11 +189,11 @@ static const unsigned char dmm32at_rangebits[] = {
 static const struct comedi_lrange dmm32at_aoranges = {
 	4,
 	{
-			UNI_RANGE(10),
-			UNI_RANGE(5),
-			BIP_RANGE(10),
-			BIP_RANGE(5),
-		}
+	 UNI_RANGE(10),
+	 UNI_RANGE(5),
+	 BIP_RANGE(10),
+	 BIP_RANGE(5),
+	 }
 };
 
 /*
@@ -214,16 +214,16 @@ struct dmm32at_board {
 };
 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,
-		},
+	 .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,
+	 },
 };
 
 /*
@@ -259,7 +259,8 @@ struct dmm32at_private {
  * 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_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",
@@ -290,20 +291,29 @@ static struct comedi_driver driver_dmm32at = {
 };
 
 /* 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_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);
 void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec);
@@ -314,7 +324,8 @@ void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec);
  * in the driver structure, dev->board_ptr contains that
  * address.
  */
-static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int dmm32at_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	int ret;
 	struct comedi_subdevice *s;
@@ -369,12 +380,12 @@ static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	airback = dmm_inb(dev, DMM32AT_AIRBACK);
 
 	printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
-		ailo, aihi, fifostat);
+	       ailo, aihi, fifostat);
 	printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
-		aistat, intstat, airback);
+	       aistat, intstat, airback);
 
 	if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
-		(aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
+	    (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
 		printk("dmmat32: board detection failed\n");
 		return -EIO;
 	}
@@ -450,7 +461,7 @@ static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		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;
+		    DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE;
 		dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
 
 		/* set up the subdevice */
@@ -497,8 +508,9 @@ static int dmm32at_detach(struct comedi_device *dev)
  * mode.
  */
 
-static int dmm32at_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -568,8 +580,9 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *
 	return n;
 }
 
-static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int dmm32at_ai_cmdtest(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -618,7 +631,7 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 	/* note that mutual compatiblity is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
-		cmd->scan_begin_src != TRIG_EXT)
+	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
 	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
 		err++;
@@ -703,21 +716,21 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	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);
+				    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);
+				    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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->scan_end_arg;
+			    cmd->convert_arg * cmd->scan_end_arg;
 			err++;
 		}
 	}
@@ -733,14 +746,14 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 		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) {
+			    (start_chan + i) % s->n_chan) {
 				comedi_error(dev,
-					"entries in chanlist must be consecutive channels, counting upwards\n");
+					     "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");
+					     "entries in chanlist must all have the same gain\n");
 				err++;
 			}
 		}
@@ -822,7 +835,8 @@ 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_ai_cancel(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	devpriv->ai_scans_left = 1;
 	return 0;
@@ -893,8 +907,9 @@ static int dmm32at_ns_to_timer(unsigned int *ns, int round)
 	return *ns;
 }
 
-static int dmm32at_ao_winsn(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)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -936,8 +951,9 @@ static int dmm32at_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
 
 /* 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)
+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);
@@ -953,8 +969,9 @@ static int dmm32at_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
  * 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)
+static int dmm32at_dio_insn_bits(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned char diobits;
 
@@ -975,7 +992,7 @@ static int dmm32at_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 
 	/* if either part of dio is set for output */
 	if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
-		((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
+	    ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
 		diobits = (s->state & 0x00ff0000) >> 16;
 		dmm_outb(dev, DMM32AT_DIOC, diobits);
 	}
@@ -1006,8 +1023,9 @@ static int dmm32at_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 	return 2;
 }
 
-static int dmm32at_dio_insn_config(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)
 {
 	unsigned char chanbit;
 	int chan = CR_CHAN(insn->chanspec);
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
index 25a9b21..7b9af5d 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -88,7 +88,8 @@ Configuration options:
 #define DT2801_STATUS		1
 #define DT2801_CMD		1
 
-static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -102,37 +103,57 @@ 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),
-	}
+								      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),
-	}
+								      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),
-	}
+								       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),
-	}
+								       RANGE(0,
+									     10),
+								       RANGE(0,
+									     1),
+								       RANGE(0,
+									     0.1),
+								       RANGE(0,
+									     0.02),
+								       }
 };
 
 struct dt2801_board {
@@ -146,75 +167,74 @@ struct dt2801_board {
 	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",
+	 .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-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 = "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",
+	 .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 = "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 = "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 = "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},
+	 .name = "dt2809",
+	 .boardcode = 0xb0,
+	 .ad_diff = 0,
+	 .ad_chan = 8,
+	 .adbits = 12,
+	 .adrangetype = 1,
+	 .dabits = 12},
 };
 
 #define boardtype (*(const struct dt2801_board *)dev->board_ptr)
@@ -227,16 +247,21 @@ struct dt2801_private {
 
 #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);
+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
@@ -299,7 +324,8 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
 		}
 #if 0
 		if (stat & DT_S_READY) {
-			printk("dt2801: ready flag set (bad!) in dt2801_writedata()\n");
+			printk
+			    ("dt2801: ready flag set (bad!) in dt2801_writedata()\n");
 			return -EIO;
 		}
 #endif
@@ -353,7 +379,8 @@ static int dt2801_writecmd(struct comedi_device *dev, int command)
 
 	stat = inb_p(dev->iobase + DT2801_STATUS);
 	if (stat & DT_S_COMPOSITE_ERROR) {
-		printk("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
+		printk
+		    ("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
 	}
 	if (!(stat & DT_S_READY)) {
 		printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
@@ -463,8 +490,8 @@ 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;
+		    &range_dt2801_ai_pgl_unipolar :
+		    &range_dt2801_ai_pgl_bipolar;
 	case 1:
 		return (opt) ? &range_unipolar10 : &range_bipolar10;
 	case 2:
@@ -510,10 +537,10 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			goto havetype;
 	}
 	printk("dt2801: unrecognized board code=0x%02x, contact author\n",
-		board_code);
+	       board_code);
 	type = 0;
 
-      havetype:
+havetype:
 	dev->board_ptr = boardtypes + type;
 	printk("dt2801: %s at port 0x%lx", boardtype.name, iobase);
 
@@ -579,7 +606,7 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	s->insn_config = dt2801_dio_insn_config;
 
 	ret = 0;
-      out:
+out:
 	printk("\n");
 
 	return ret;
@@ -611,8 +638,9 @@ static int dt2801_error(struct comedi_device *dev, int stat)
 	return -EIO;
 }
 
-static int dt2801_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -633,16 +661,18 @@ static int dt2801_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return i;
 }
 
-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_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)
+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));
@@ -653,8 +683,9 @@ static int dt2801_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 	return 1;
 }
 
-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_bits(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int which = 0;
 
@@ -677,8 +708,9 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	return 2;
 }
 
-static int dt2801_dio_insn_config(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)
 {
 	int which = 0;
 
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
index 7853902..51ef695 100644
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -53,46 +53,95 @@ Configuration options:
 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)
-	}
+									 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)
-	}
+									  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)
-	}
+									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)
-	}
+									 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)
-	}
+									  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)
-	}
+									RANGE
+									(-5, 5),
+									RANGE
+									(-0.5,
+									 0.5),
+									RANGE
+									(-0.05,
+									 0.05),
+									RANGE
+									(-0.01,
+									 0.01)
+									}
 };
 
 /*
@@ -202,20 +251,21 @@ struct dt2811_board {
 
 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,
-		},
+	 &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,
-		},
+	 &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_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",
@@ -230,15 +280,18 @@ static struct comedi_driver driver_dt2811 = {
 COMEDI_INITCLEANUP(driver_dt2811);
 
 static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+			  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);
+			  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 };
 
@@ -349,7 +402,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		irqs = probe_irq_on();
 
 		outb(DT2811_CLRERROR | DT2811_INTENB,
-			dev->iobase + DT2811_ADCSR);
+		     dev->iobase + DT2811_ADCSR);
 		outb(0, dev->iobase + DT2811_ADGCR);
 
 		udelay(100);
@@ -368,7 +421,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			i = inb(dev->iobase + DT2811_ADDATHI);
 			printk("(irq = %d)\n", irq);
 			ret = request_irq(irq, dt2811_interrupt, 0,
-				driver_name, dev);
+					  driver_name, dev);
 			if (ret < 0)
 				return -EIO;
 			dev->irq = irq;
@@ -500,7 +553,7 @@ static int dt2811_detach(struct comedi_device *dev)
 }
 
 static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 	int timeout = DT2811_TIMEOUT;
@@ -510,7 +563,7 @@ static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 		outb(chan, dev->iobase + DT2811_ADGCR);
 
 		while (timeout
-			&& inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY)
+		       && inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY)
 			timeout--;
 		if (!timeout)
 			return -ETIME;
@@ -526,7 +579,7 @@ static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 #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)
+int dt2811_adtrig(kdev_t minor, comedi_adtrig * adtrig)
 {
 	struct comedi_device *dev = comedi_devices + minor;
 
@@ -537,7 +590,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig)
 	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(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); *//* not neccessary */
 		outb(dev->curadchan, dev->iobase + DT2811_ADGCR);
 		do_gettimeofday(&trigtime);
 		break;
@@ -551,7 +604,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig)
 #endif
 
 static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan;
@@ -561,15 +614,16 @@ static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 	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);
+		     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)
+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;
@@ -583,8 +637,9 @@ static int dt2811_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return i;
 }
 
-static int dt2811_di_insn_bits(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)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -594,8 +649,9 @@ static int dt2811_di_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 	return 2;
 }
 
-static int dt2811_do_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)
 {
 	if (insn->n != 2)
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
index 5906ddd..0364bbf 100644
--- a/drivers/staging/comedi/drivers/dt2814.c
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -60,7 +60,8 @@ addition, the clock does not seem to be very accurate.
 #define DT2814_ENB 0x10
 #define DT2814_CHANMASK 0x0f
 
-static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -84,8 +85,9 @@ struct dt2814_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)
+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;
@@ -135,8 +137,8 @@ static int dt2814_ns_to_timer(unsigned int *ns, unsigned int flags)
 	return i;
 }
 
-static int dt2814_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int dt2814_ai_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -234,8 +236,8 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	int trigvar;
 
 	trigvar =
-		dt2814_ns_to_timer(&cmd->scan_begin_arg,
-		cmd->flags & TRIG_ROUND_MASK);
+	    dt2814_ns_to_timer(&cmd->scan_begin_arg,
+			       cmd->flags & TRIG_ROUND_MASK);
 
 	chan = CR_CHAN(cmd->chanlist[0]);
 
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
index b42dec6..d1db93c 100644
--- a/drivers/staging/comedi/drivers/dt2815.c
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -62,12 +62,15 @@ Configuration options:
 #include <linux/delay.h>
 
 static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
-			RANGE_mA(0, 32)
-	}
+								     RANGE_mA(0,
+									      32)
+								     }
 };
+
 static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
-			RANGE_mA(4, 20)
-	}
+								     RANGE_mA(4,
+									      20)
+								     }
 };
 
 #define DT2815_SIZE 2
@@ -75,7 +78,8 @@ static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
 #define DT2815_DATA 0
 #define DT2815_STATUS 1
 
-static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -94,7 +98,6 @@ struct dt2815_private {
 	unsigned int ao_readback[8];
 };
 
-
 #define devpriv ((struct dt2815_private *)dev->private)
 
 static int dt2815_wait_for_status(struct comedi_device *dev, int status)
@@ -108,8 +111,9 @@ static int dt2815_wait_for_status(struct comedi_device *dev, int status)
 	return status;
 }
 
-static int dt2815_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -122,7 +126,7 @@ static int dt2815_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 }
 
 static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -136,8 +140,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 		status = dt2815_wait_for_status(dev, 0x00);
 		if (status != 0) {
 			printk
-				("dt2815: failed to write low byte on %d reason %x\n",
-				chan, status);
+			    ("dt2815: failed to write low byte on %d reason %x\n",
+			     chan, status);
 			return -EBUSY;
 		}
 
@@ -146,8 +150,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 		status = dt2815_wait_for_status(dev, 0x10);
 		if (status != 0x10) {
 			printk
-				("dt2815: failed to write high byte on %d reason %x\n",
-				chan, status);
+			    ("dt2815: failed to write high byte on %d reason %x\n",
+			     chan, status);
 			return -EBUSY;
 		}
 		devpriv->ao_readback[chan] = data[i];
@@ -212,12 +216,12 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	s->range_table_list = devpriv->range_type_list;
 
 	current_range_type = (it->options[3])
-		? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
+	    ? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
 	voltage_range_type = (it->options[2])
-		? &range_bipolar5 : &range_unipolar5;
+	    ? &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;
+		    ? current_range_type : voltage_range_type;
 	}
 
 	/* Init the 2815 */
@@ -236,7 +240,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			break;
 		} else if (status != 0x00) {
 			printk("dt2815: unexpected status 0x%x (@t=%d)\n",
-				status, i);
+			       status, i);
 			if (status & 0x60) {
 				outb(0x00, dev->iobase + DT2815_STATUS);
 			}
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
index b36f856..54e0dea 100644
--- a/drivers/staging/comedi/drivers/dt2817.c
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -47,7 +47,8 @@ Configuration options:
 #define DT2817_CR 0
 #define DT2817_DATA 1
 
-static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -58,8 +59,9 @@ static struct comedi_driver driver_dt2817 = {
 
 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)
+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;
@@ -96,8 +98,9 @@ static int dt2817_dio_insn_config(struct comedi_device *dev, struct comedi_subde
 	return 1;
 }
 
-static int dt2817_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int dt2817_dio_insn_bits(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int changed;
 
@@ -115,13 +118,13 @@ static int dt2817_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 			outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
 		if (changed & 0x0000ff00)
 			outb((s->state >> 8) & 0xff,
-				dev->iobase + DT2817_DATA + 1);
+			     dev->iobase + DT2817_DATA + 1);
 		if (changed & 0x00ff0000)
 			outb((s->state >> 16) & 0xff,
-				dev->iobase + DT2817_DATA + 2);
+			     dev->iobase + DT2817_DATA + 2);
 		if (changed & 0xff000000)
 			outb((s->state >> 24) & 0xff,
-				dev->iobase + DT2817_DATA + 3);
+			     dev->iobase + DT2817_DATA + 3);
 	}
 	data[1] = inb(dev->iobase + DT2817_DATA + 0);
 	data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
index 22b7304..a4c96c0 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -155,46 +155,78 @@ Notes:
 #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)
-	}
+								     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)
-	}
+								      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),
-	}
+								    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),
-	}
+								     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)
-	}
+								     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)
-	}
+								      RANGE(0,
+									    10),
+								      RANGE(0,
+									    1),
+								      RANGE(0,
+									    0.1),
+								      RANGE(0,
+									    0.02)
+								      }
 };
 
 struct dt282x_board {
@@ -217,7 +249,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt2821-f",
 	 .adbits = 12,
 	 .adchan_se = 16,
@@ -226,7 +258,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt2821-g",
 	 .adbits = 12,
 	 .adchan_se = 16,
@@ -235,7 +267,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt2823",
 	 .adbits = 16,
 	 .adchan_se = 0,
@@ -244,16 +276,16 @@ static const struct dt282x_board boardtypes[] = {
 	 .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,
-	},
+	 .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,
@@ -262,7 +294,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 1,
 	 .dachan = 0,
 	 .dabits = 0,
-	},
+	 },
 	{.name = "dt2825",
 	 .adbits = 12,
 	 .adchan_se = 16,
@@ -271,7 +303,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 1,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt2827",
 	 .adbits = 16,
 	 .adchan_se = 0,
@@ -280,7 +312,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt2828",
 	 .adbits = 12,
 	 .adchan_se = 4,
@@ -289,7 +321,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt2829",
 	 .adbits = 16,
 	 .adchan_se = 8,
@@ -298,7 +330,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 2,
 	 .dabits = 16,
-	},
+	 },
 	{.name = "dt21-ez",
 	 .adbits = 12,
 	 .adchan_se = 16,
@@ -307,7 +339,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt23-ez",
 	 .adbits = 16,
 	 .adchan_se = 16,
@@ -316,7 +348,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 0,
 	 .dabits = 0,
-	},
+	 },
 	{.name = "dt24-ez",
 	 .adbits = 12,
 	 .adchan_se = 16,
@@ -325,7 +357,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 0,
 	 .dachan = 0,
 	 .dabits = 0,
-	},
+	 },
 	{.name = "dt24-ez-pgl",
 	 .adbits = 12,
 	 .adchan_se = 16,
@@ -334,7 +366,7 @@ static const struct dt282x_board boardtypes[] = {
 	 .ispgl = 1,
 	 .dachan = 0,
 	 .dabits = 0,
-	},
+	 },
 };
 
 #define n_boardtypes sizeof(boardtypes)/sizeof(struct dt282x_board)
@@ -394,7 +426,8 @@ struct dt282x_private {
 		if (_i){b}				\
 	}while (0)
 
-static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -411,15 +444,17 @@ 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_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 nbytes)
 {
 	unsigned int i;
 	unsigned short mask = (1 << boardtype.adbits) - 1;
@@ -628,7 +663,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
 		int ret;
 		short data;
 
-		data = (short) inw(dev->iobase + DT2821_ADDAT);
+		data = (short)inw(dev->iobase + DT2821_ADDAT);
 		data &= (1 << boardtype.adbits) - 1;
 		if (devpriv->ad_2scomp) {
 			data ^= 1 << (boardtype.adbits - 1);
@@ -654,7 +689,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
 }
 
 static void dt282x_load_changain(struct comedi_device *dev, int n,
-	unsigned int *chanlist)
+				 unsigned int *chanlist)
 {
 	unsigned int i;
 	unsigned int chan, range;
@@ -674,8 +709,9 @@ static void dt282x_load_changain(struct comedi_device *dev, int n,
  *      - 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)
+static int dt282x_ai_insn_read(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 
@@ -686,18 +722,15 @@ static int dt282x_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	dt282x_load_changain(dev, 1, &insn->chanspec);
 
 	update_supcsr(DT2821_PRLD);
-	wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
-		return -ETIME;
-		);
+	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;
-			);
+			 return -ETIME;);
 
 		data[i] =
-			inw(dev->iobase +
+		    inw(dev->iobase +
 			DT2821_ADDAT) & ((1 << boardtype.adbits) - 1);
 		if (devpriv->ad_2scomp)
 			data[i] ^= (1 << (boardtype.adbits - 1));
@@ -706,8 +739,8 @@ static int dt282x_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return i;
 }
 
-static int dt282x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int dt282x_ai_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -746,7 +779,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 	/* 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_EXT)
 		err++;
 	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 		err++;
@@ -825,7 +858,7 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (devpriv->usedma == 0) {
 		comedi_error(dev,
-			"driver requires 2 dma channels to execute command");
+			     "driver requires 2 dma channels to execute command");
 		return -EIO;
 	}
 
@@ -865,9 +898,7 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	update_adcsr(0);
 
 	update_supcsr(DT2821_PRLD);
-	wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
-		return -ETIME;
-		);
+	wait_for(!mux_busy(), comedi_error(dev, "timeout\n"); return -ETIME;);
 
 	if (cmd->scan_begin_src == TRIG_FOLLOW) {
 		update_supcsr(DT2821_STRIG);
@@ -887,7 +918,8 @@ static void dt282x_disable_dma(struct comedi_device *dev)
 	}
 }
 
-static int dt282x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int dt282x_ai_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	dt282x_disable_dma(dev);
 
@@ -937,16 +969,18 @@ static int dt282x_ns_to_timer(int *nanosec, int round_mode)
  *      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)
+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)
+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;
@@ -978,8 +1012,8 @@ static int dt282x_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 	return 1;
 }
 
-static int dt282x_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int dt282x_ao_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -1029,7 +1063,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 		cmd->start_arg = 0;
 		err++;
 	}
-	if (cmd->scan_begin_arg < 5000 /* XXX unknown */) {
+	if (cmd->scan_begin_arg < 5000 /* XXX unknown */ ) {
 		cmd->scan_begin_arg = 5000;
 		err++;
 	}
@@ -1069,8 +1103,8 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 
 }
 
-static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int x)
+static int dt282x_ao_inttrig(struct comedi_device *dev,
+			     struct comedi_subdevice *s, unsigned int x)
 {
 	int size;
 
@@ -1078,7 +1112,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice
 		return -EINVAL;
 
 	size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf,
-		devpriv->dma_maxsize);
+					  devpriv->dma_maxsize);
 	if (size == 0) {
 		printk("dt282x: AO underrun\n");
 		return -EPIPE;
@@ -1086,7 +1120,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice
 	prep_ao_dma(dev, 0, size);
 
 	size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
-		devpriv->dma_maxsize);
+					  devpriv->dma_maxsize);
 	if (size == 0) {
 		printk("dt282x: AO underrun\n");
 		return -EPIPE;
@@ -1106,7 +1140,7 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (devpriv->usedma == 0) {
 		comedi_error(dev,
-			"driver requires 2 dma channels to execute command");
+			     "driver requires 2 dma channels to execute command");
 		return -EIO;
 	}
 
@@ -1132,7 +1166,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	return 0;
 }
 
-static int dt282x_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int dt282x_ao_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	dt282x_disable_dma(dev);
 
@@ -1145,8 +1180,9 @@ static int dt282x_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int dt282x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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];
@@ -1159,8 +1195,9 @@ static int dt282x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	return 2;
 }
 
-static int dt282x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int dt282x_dio_insn_config(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 	int mask;
 
@@ -1190,10 +1227,12 @@ static const struct comedi_lrange *const ai_range_table[] = {
 	&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) {
@@ -1206,6 +1245,7 @@ static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
 		return ai_range_table[x];
 	}
 }
+
 static const struct comedi_lrange *const ao_range_table[] = {
 	&range_bipolar10,
 	&range_unipolar10,
@@ -1213,6 +1253,7 @@ static const struct comedi_lrange *const ao_range_table[] = {
 	&range_unipolar5,
 	&range_bipolar2_5
 };
+
 static const struct comedi_lrange *opt_ao_range_lkup(int x)
 {
 	if (x < 0 || x >= 5)
@@ -1264,23 +1305,23 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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));
+	       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)) {
+	     != 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;
 	}
@@ -1302,7 +1343,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 		irq = probe_irq_off(irqs);
 		restore_flags(flags);
-		if (0 /* error */) {
+		if (0 /* error */ ) {
 			printk(" error probing irq (bad)");
 		}
 	}
@@ -1330,7 +1371,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		return ret;
 
 	ret = dt282x_grab_dma(dev, it->options[opt_dma1],
-		it->options[opt_dma2]);
+			      it->options[opt_dma2]);
 	if (ret < 0)
 		return ret;
 
@@ -1344,10 +1385,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* ai subdevice */
 	s->type = COMEDI_SUBD_AI;
 	s->subdev_flags = SDF_READABLE | SDF_CMD_READ |
-		((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
+	    ((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
 	s->n_chan =
-		(it->options[opt_diff]) ? boardtype.adchan_di : boardtype.
-		adchan_se;
+	    (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;
@@ -1355,7 +1395,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	s->maxdata = (1 << boardtype.adbits) - 1;
 	s->len_chanlist = 16;
 	s->range_table =
-		opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
+	    opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
 	devpriv->ad_2scomp = it->options[opt_ai_twos];
 
 	s++;
@@ -1375,9 +1415,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		s->len_chanlist = 2;
 		s->range_table_list = devpriv->darangelist;
 		devpriv->darangelist[0] =
-			opt_ao_range_lkup(it->options[opt_ao0_range]);
+		    opt_ao_range_lkup(it->options[opt_ao0_range]);
 		devpriv->darangelist[1] =
-			opt_ao_range_lkup(it->options[opt_ao1_range]);
+		    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 {
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
index 2af8b59..bbbef79 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -68,18 +68,19 @@ AO commands are not supported.
 #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)
-	}
+							  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)
-	}
+							      RANGE(-10, 10),
+							      RANGE(-1, 1),
+							      RANGE(-0.1, 0.1),
+							      RANGE(-0.02, 0.02)
+							      }
 };
 
 struct dt3k_boardtype {
@@ -94,7 +95,6 @@ struct dt3k_boardtype {
 	int dabits;
 };
 
-
 static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	{.name = "dt3001",
 	 .device_id = 0x22,
@@ -104,7 +104,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	 .ai_speed = 3000,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt3001-pgl",
 	 .device_id = 0x27,
 	 .adchan = 16,
@@ -113,7 +113,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	 .ai_speed = 3000,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt3002",
 	 .device_id = 0x23,
 	 .adchan = 32,
@@ -122,7 +122,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	 .ai_speed = 3000,
 	 .dachan = 0,
 	 .dabits = 0,
-	},
+	 },
 	{.name = "dt3003",
 	 .device_id = 0x24,
 	 .adchan = 64,
@@ -131,7 +131,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	 .ai_speed = 3000,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt3003-pgl",
 	 .device_id = 0x28,
 	 .adchan = 64,
@@ -140,7 +140,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	 .ai_speed = 3000,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
+	 },
 	{.name = "dt3004",
 	 .device_id = 0x25,
 	 .adchan = 16,
@@ -149,8 +149,8 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	 .ai_speed = 10000,
 	 .dachan = 2,
 	 .dabits = 12,
-	},
-        {.name = "dt3005",		/* a.k.a. 3004-200 */
+	 },
+	{.name = "dt3005",	/* a.k.a. 3004-200 */
 	 .device_id = 0x26,
 	 .adchan = 16,
 	 .adbits = 16,
@@ -158,21 +158,22 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
 	 .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}
+	{
+	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);
@@ -276,7 +277,8 @@ struct dt3k_private {
 
 #define devpriv ((struct dt3k_private *)dev->private)
 
-static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -287,10 +289,12 @@ static struct comedi_driver driver_dt3000 = {
 
 COMEDI_PCI_INITCLEANUP(driver_dt3000, dt3k_pci_table);
 
-static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s);
+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);
+			    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
@@ -319,8 +323,9 @@ static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
 	return -ETIME;
 }
 
-static unsigned int dt3k_readsingle(struct comedi_device *dev, unsigned int subsys,
-	unsigned int chan, unsigned int gain)
+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);
 
@@ -333,7 +338,7 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev, unsigned int subs
 }
 
 static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys,
-	unsigned int chan, unsigned int data)
+			     unsigned int chan, unsigned int data)
 {
 	writew(subsys, devpriv->io_addr + DPR_SubSys);
 
@@ -388,6 +393,7 @@ static char *intr_flags[] = {
 	"AdFull", "AdSwError", "AdHwError", "DaEmpty",
 	"DaSwError", "DaHwError", "CtDone", "CmDone",
 };
+
 static void debug_intr_flags(unsigned int flags)
 {
 	int i;
@@ -401,7 +407,8 @@ static void debug_intr_flags(unsigned int flags)
 }
 #endif
 
-static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s)
+static void dt3k_ai_empty_fifo(struct comedi_device *dev,
+			       struct comedi_subdevice *s)
 {
 	int front;
 	int rear;
@@ -430,8 +437,8 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevic
 	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)
+static int dt3k_ai_cmdtest(struct comedi_device *dev,
+			   struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -528,7 +535,7 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	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);
+				 cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	} else {
@@ -537,14 +544,14 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	if (cmd->convert_src == TRIG_TIMER) {
 		tmp = cmd->convert_arg;
 		dt3k_ns_to_timer(50, &cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+				 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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->scan_end_arg;
+			    cmd->convert_arg * cmd->scan_end_arg;
 			err++;
 		}
 	} else {
@@ -558,7 +565,7 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 }
 
 static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
-	unsigned int round_mode)
+			    unsigned int round_mode)
 {
 	int divider, base, prescale;
 
@@ -608,7 +615,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		range = CR_RANGE(cmd->chanlist[i]);
 
 		writew((range << 6) | chan,
-			devpriv->io_addr + DPR_ADC_buffer + i);
+		       devpriv->io_addr + DPR_ADC_buffer + i);
 	}
 	aref = CR_AREF(cmd->chanlist[0]);
 
@@ -617,7 +624,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (cmd->convert_src == TRIG_TIMER) {
 		divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+					   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));
@@ -628,7 +635,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+					    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));
@@ -650,7 +657,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	ret = dt3k_send_cmd(dev, CMD_CONFIG);
 
 	writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
-		devpriv->io_addr + DPR_Int_Mask);
+	       devpriv->io_addr + DPR_Int_Mask);
 
 	debug_n_ints = 0;
 
@@ -673,7 +680,7 @@ static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	unsigned int chan, gain, aref;
@@ -691,7 +698,7 @@ static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int dt3k_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	unsigned int chan;
@@ -705,8 +712,9 @@ static int dt3k_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return i;
 }
 
-static int dt3k_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -734,8 +742,9 @@ static void dt3k_dio_config(struct comedi_device *dev, int bits)
 	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)
+static int dt3k_dio_insn_config(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 	int mask;
 
@@ -750,9 +759,9 @@ static int dt3k_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->io_bits & (1 << CR_CHAN(insn->
-					chanspec))) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (s->
+		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
+		    COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -765,8 +774,9 @@ static int dt3k_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
 	return insn->n;
 }
 
-static int dt3k_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -781,8 +791,9 @@ static int dt3k_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 	return 2;
 }
 
-static int dt3k_mem_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -925,8 +936,8 @@ static int dt_pci_probe(struct comedi_device *dev, int bus, int slot)
 	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)) {
+		    (pcidev->bus->number == bus &&
+		     PCI_SLOT(pcidev->devfn) == slot)) {
 			break;
 		}
 	}
@@ -961,7 +972,7 @@ static int setup_pci(struct comedi_device *dev)
 		return -ENOMEM;
 #if DEBUG
 	printk("0x%08llx mapped to %p, ",
-		(unsigned long long)devpriv->phys_addr, devpriv->io_addr);
+	       (unsigned long long)devpriv->phys_addr, devpriv->io_addr);
 #endif
 
 	return 0;
@@ -972,15 +983,17 @@ 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)) {
+	     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);
+		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 cc4c046..312f4f2 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -89,9 +89,9 @@ for my needs.
 #define F020_MASK_DACxCN_DACxEN		0x80
 
 enum {
-				/* A/D  D/A  DI  DO  CT */
+	/* A/D  D/A  DI  DO  CT */
 	DT9812_DEVID_DT9812_10,	/*  8    2   8   8   1  +/- 10V */
-	DT9812_DEVID_DT9812_2PT5,/* 8    2   8   8   1  0-2.44V */
+	DT9812_DEVID_DT9812_2PT5,	/* 8    2   8   8   1  0-2.44V */
 #if 0
 	DT9812_DEVID_DT9813,	/*  16   2   4   4   1  +/- 10V */
 	DT9812_DEVID_DT9814	/*  24   2   0   0   1  +/- 10V */
@@ -266,7 +266,7 @@ static DECLARE_MUTEX(dt9812_mutex);
 
 static struct usb_device_id dt9812_table[] = {
 	{USB_DEVICE(0x0867, 0x9812)},
-	{ }			/* Terminating entry */
+	{}			/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, dt9812_table);
@@ -301,23 +301,23 @@ struct slot_dt9812 {
 };
 
 static const struct comedi_lrange dt9812_10_ain_range = { 1, {
-			BIP_RANGE(10),
-	}
+							      BIP_RANGE(10),
+							      }
 };
 
 static const struct comedi_lrange dt9812_2pt5_ain_range = { 1, {
-			UNI_RANGE(2.5),
-	}
+								UNI_RANGE(2.5),
+								}
 };
 
 static const struct comedi_lrange dt9812_10_aout_range = { 1, {
-			BIP_RANGE(10),
-	}
+							       BIP_RANGE(10),
+							       }
 };
 
 static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, {
-			UNI_RANGE(2.5),
-	}
+								 UNI_RANGE(2.5),
+								 }
 };
 
 static struct slot_dt9812 dt9812[DT9812_NUM_SLOTS];
@@ -346,7 +346,7 @@ static int dt9812_read_info(struct usb_dt9812 *dev, int offset, void *buf,
 
 	cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
 	cmd.u.flash_data_info.address =
-		cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
+	    cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
 	cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size);
 
 	/* DT9812 only responds to 32 byte writes!! */
@@ -365,7 +365,7 @@ static int dt9812_read_info(struct usb_dt9812 *dev, int offset, void *buf,
 }
 
 static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count,
-					  u8 *address, u8 *value)
+					  u8 * address, u8 * value)
 {
 	struct dt9812_usb_cmd cmd;
 	int i, count, retval;
@@ -391,8 +391,8 @@ static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count,
 }
 
 static int dt9812_write_multiple_registers(struct usb_dt9812 *dev,
-					   int reg_count, u8 *address,
-					   u8 *value)
+					   int reg_count, u8 * address,
+					   u8 * value)
 {
 	struct dt9812_usb_cmd cmd;
 	int i, count, retval;
@@ -430,7 +430,7 @@ static int dt9812_rmw_multiple_registers(struct usb_dt9812 *dev, int reg_count,
 	return retval;
 }
 
-static int dt9812_digital_in(struct slot_dt9812 *slot, u8 *bits)
+static int dt9812_digital_in(struct slot_dt9812 *slot, u8 * bits)
 {
 	int result = -ENODEV;
 
@@ -449,7 +449,7 @@ static int dt9812_digital_in(struct slot_dt9812 *slot, u8 *bits)
 			 */
 			*bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
 			/* printk("%2.2x, %2.2x -> %2.2x\n",
-				  value[0], value[1], *bits); */
+			   value[0], value[1], *bits); */
 		}
 	}
 	up(&slot->mutex);
@@ -476,7 +476,7 @@ static int dt9812_digital_out(struct slot_dt9812 *slot, u8 bits)
 	return result;
 }
 
-static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 *bits)
+static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 * bits)
 {
 	int result = -ENODEV;
 
@@ -516,8 +516,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
 
 	rmw->address = F020_SFR_ADC0CF;
 	rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 |
-			F020_MASK_ADC0CF_AMP0GN1 |
-			F020_MASK_ADC0CF_AMP0GN0;
+	    F020_MASK_ADC0CF_AMP0GN1 | F020_MASK_ADC0CF_AMP0GN0;
 	switch (gain) {
 		/*
 		 * 000 -> Gain =  1
@@ -529,7 +528,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
 		 */
 	case DT9812_GAIN_0PT5:
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 ||
-				F020_MASK_ADC0CF_AMP0GN1;
+		    F020_MASK_ADC0CF_AMP0GN1;
 		break;
 	case DT9812_GAIN_1:
 		rmw->or_value = 0x00;
@@ -542,7 +541,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
 		break;
 	case DT9812_GAIN_8:
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 ||
-				F020_MASK_ADC0CF_AMP0GN0;
+		    F020_MASK_ADC0CF_AMP0GN0;
 		break;
 	case DT9812_GAIN_16:
 		rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
@@ -553,7 +552,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
 	}
 }
 
-static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 *value,
+static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 * value,
 			    enum dt9812_gain gain)
 {
 	struct dt9812_rmw_byte rmw[3];
@@ -620,7 +619,7 @@ exit:
 }
 
 static int dt9812_analog_out_shadow(struct slot_dt9812 *slot, int channel,
-				    u16 *value)
+				    u16 * value)
 {
 	int result = -ENODEV;
 
@@ -729,32 +728,32 @@ static int dt9812_probe(struct usb_interface *interface,
 			direction = USB_DIR_IN;
 			dev->message_pipe.addr = endpoint->bEndpointAddress;
 			dev->message_pipe.size =
-					le16_to_cpu(endpoint->wMaxPacketSize);
+			    le16_to_cpu(endpoint->wMaxPacketSize);
 
 			break;
 		case 1:
 			direction = USB_DIR_OUT;
 			dev->command_write.addr = endpoint->bEndpointAddress;
 			dev->command_write.size =
-					le16_to_cpu(endpoint->wMaxPacketSize);
+			    le16_to_cpu(endpoint->wMaxPacketSize);
 			break;
 		case 2:
 			direction = USB_DIR_IN;
 			dev->command_read.addr = endpoint->bEndpointAddress;
 			dev->command_read.size =
-					le16_to_cpu(endpoint->wMaxPacketSize);
+			    le16_to_cpu(endpoint->wMaxPacketSize);
 			break;
 		case 3:
 			direction = USB_DIR_OUT;
 			dev->write_stream.addr = endpoint->bEndpointAddress;
 			dev->write_stream.size =
-					le16_to_cpu(endpoint->wMaxPacketSize);
+			    le16_to_cpu(endpoint->wMaxPacketSize);
 			break;
 		case 4:
 			direction = USB_DIR_IN;
 			dev->read_stream.addr = endpoint->bEndpointAddress;
 			dev->read_stream.size =
-					le16_to_cpu(endpoint->wMaxPacketSize);
+			    le16_to_cpu(endpoint->wMaxPacketSize);
 			break;
 		}
 		if ((endpoint->bEndpointAddress & USB_DIR_IN) != direction) {
@@ -786,8 +785,7 @@ static int dt9812_probe(struct usb_interface *interface,
 		retval = -ENODEV;
 		goto error;
 	}
-	if (dt9812_read_info(dev, 3, &dev->product,
-			     sizeof(dev->product)) != 0) {
+	if (dt9812_read_info(dev, 3, &dev->product, sizeof(dev->product)) != 0) {
 		err("Failed to read product.");
 		retval = -ENODEV;
 		goto error;
@@ -940,8 +938,9 @@ static void dt9812_comedi_open(struct comedi_device *dev)
 	up(&devpriv->slot->mutex);
 }
 
-static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-			   struct comedi_insn *insn, unsigned int *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 +951,9 @@ static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 	return n;
 }
 
-static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-			   struct comedi_insn *insn, unsigned int *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,9 @@ static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s
 	return n;
 }
 
-static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-			   struct comedi_insn *insn, unsigned int *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 +986,9 @@ static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 	return n;
 }
 
-static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-			   struct comedi_insn *insn, unsigned int *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 +1001,9 @@ static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 	return n;
 }
 
-static int dt9812_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-			   struct comedi_insn *insn, unsigned int *data)
+static int dt9812_ao_winsn(struct comedi_device *dev,
+			   struct comedi_subdevice *s, struct comedi_insn *insn,
+			   unsigned int *data)
 {
 	int n;
 
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
index b8657c4..8fca180 100644
--- a/drivers/staging/comedi/drivers/fl512.c
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -32,14 +32,14 @@ struct fl512_private {
 #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),
-	}
+						      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);
@@ -55,17 +55,20 @@ static struct comedi_driver driver_fl512 = {
 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);
+			 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);
+				  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)
+			 struct comedi_subdevice *s, struct comedi_insn *insn,
+			 unsigned int *data)
 {
 	int n;
 	unsigned int lo_byte, hi_byte;
@@ -90,7 +93,8 @@ static int fl512_ai_insn(struct comedi_device *dev,
  * 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)
+			 struct comedi_subdevice *s, struct comedi_insn *insn,
+			 unsigned int *data)
 {
 	int n;
 	int chan = CR_CHAN(insn->chanspec);	/* get chan to write */
@@ -111,7 +115,8 @@ static int fl512_ao_insn(struct comedi_device *dev,
  * DA port
  */
 static int fl512_ao_insn_readback(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	int chan = CR_CHAN(insn->chanspec);
@@ -130,7 +135,7 @@ 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) */
+					   Analog in, Analog out, ( not made ->and Digital IO) */
 
 	iobase = it->options[0];
 	printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index b156ae7..0bb3016 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -58,7 +58,7 @@ 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);
+			 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);
 static int dio_config_block_size(struct comedi_device *dev, unsigned int *data);
@@ -149,7 +149,7 @@ enum board_control_bits {
 	TEST_MODE_ENABLE_BIT = 0x80000000,
 };
 uint32_t command_discrete_output_bits(unsigned int channel, int output,
-	int output_value)
+				      int output_value)
 {
 	uint32_t bits = 0;
 
@@ -193,11 +193,13 @@ 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;
@@ -268,33 +270,33 @@ struct hpdi_board {
 	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,
-		},
+	 .name = "pci-hpdi32",
+	 .device_id = PCI_DEVICE_ID_PLX_9080,
+	 .subdevice_id = 0x2400,
+	 },
 #if 0
 	{
-	.name = "pxi-hpdi32",
-	.device_id = 0x9656,
-	.subdevice_id = 0x2705,
-		},
+	 .name = "pxi-hpdi32",
+	 .device_id = 0x9656,
+	 .subdevice_id = 0x2705,
+	 },
 #endif
 };
 
 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}
+	{
+	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)
+static inline struct hpdi_board *board(const struct comedi_device *dev)
 {
-	return (struct hpdi_board *) dev->board_ptr;
+	return (struct hpdi_board *)dev->board_ptr;
 }
 
 struct hpdi_private {
@@ -321,8 +323,7 @@ struct hpdi_private {
 	unsigned dio_config_output:1;
 };
 
-
-static inline struct hpdi_private *priv(struct comedi_device * dev)
+static inline struct hpdi_private *priv(struct comedi_device *dev)
 {
 	return dev->private;
 }
@@ -336,8 +337,9 @@ static struct comedi_driver driver_hpdi = {
 
 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)
+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:
@@ -350,8 +352,7 @@ static int dio_config_insn(struct comedi_device *dev, struct comedi_subdevice *s
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			priv(dev)->
-			dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    priv(dev)->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	case INSN_CONFIG_BLOCK_SIZE:
@@ -377,29 +378,29 @@ static void init_plx9080(struct comedi_device *dev)
 
 	/*  plx9080 dump */
 	DEBUG_PRINT(" plx interrupt status 0x%x\n",
-		readl(plx_iobase + PLX_INTRCS_REG));
+		    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));
+		    readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
 
 	DEBUG_PRINT(" plx revision 0x%x\n",
-		readl(plx_iobase + PLX_REVISION_REG));
+		    readl(plx_iobase + PLX_REVISION_REG));
 	DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
-		readl(plx_iobase + PLX_DMA0_MODE_REG));
+		    readl(plx_iobase + PLX_DMA0_MODE_REG));
 	DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
-		readl(plx_iobase + PLX_DMA1_MODE_REG));
+		    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));
+		    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));
+		    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));
+		    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));
+		    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));
+		    readb(plx_iobase + PLX_DMA0_CS_REG));
 	DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
-		readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+		    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;
@@ -448,7 +449,7 @@ static int setup_subdevices(struct comedi_device *dev)
 /*	dev->write_subdev = s; */
 	s->type = COMEDI_SUBD_DIO;
 	s->subdev_flags =
-		SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
+	    SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
 	s->n_chan = 32;
 	s->len_chanlist = 32;
 	s->maxdata = 1;
@@ -469,21 +470,21 @@ static int init_hpdi(struct comedi_device *dev)
 	udelay(10);
 
 	writel(almost_empty_bits(32) | almost_full_bits(32),
-		priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
+	       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)->hpdi_iobase + TX_PROG_ALMOST_REG);
 
 	priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
-			TX_FIFO_SIZE_REG));
+						  TX_FIFO_SIZE_REG));
 	priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
-			RX_FIFO_SIZE_REG));
+						  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;
+	    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;
@@ -491,11 +492,11 @@ static int init_hpdi(struct comedi_device *dev)
 
 /* 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 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;
+	    PLX_XFER_LOCAL_TO_PCI;
 	unsigned int i;
 
 	if (transfer_size > DMA_BUFFER_SIZE)
@@ -506,26 +507,26 @@ static int setup_dma_descriptors(struct comedi_device *dev,
 
 	DEBUG_PRINT(" transfer_size %i\n", transfer_size);
 	DEBUG_PRINT(" descriptors at 0x%lx\n",
-		(unsigned long)priv(dev)->dma_desc_phys_addr);
+		    (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++) {
+	     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);
+		    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);
+		    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);
+		    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));
+		    priv(dev)->dio_buffer[buffer_index] +
+		    (buffer_offset / sizeof(uint32_t));
 
 		buffer_offset += transfer_size;
 		if (transfer_size + buffer_offset > DMA_BUFFER_SIZE) {
@@ -535,17 +536,18 @@ static int setup_dma_descriptors(struct comedi_device *dev,
 
 		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);
+			    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);
+			    (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);
+	    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);
+		    (unsigned long)priv(dev)->dma_desc[i - 1].next);
 
 	priv(dev)->block_size = transfer_size;
 
@@ -567,14 +569,15 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	for (i = 0; i < ARRAY_SIZE(hpdi_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);
+						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])
+				    PCI_SLOT(pcidev->devfn) != it->options[1])
 					continue;
 			}
 			if (pcidev) {
@@ -590,11 +593,11 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
-		pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+	       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");
+		       " failed enable PCI device and request regions\n");
 		return -EIO;
 	}
 	pci_set_master(pcidev);
@@ -603,15 +606,17 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	dev->board_name = board(dev)->name;
 
 	priv(dev)->plx9080_phys_iobase =
-		pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+	    pci_resource_start(pcidev, PLX9080_BADDRINDEX);
 	priv(dev)->hpdi_phys_iobase =
-		pci_resource_start(pcidev, HPDI_BADDRINDEX);
+	    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));
+					    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;
@@ -635,16 +640,18 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/*  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]);
+		    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]);
+			    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);
+						   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;
@@ -681,18 +688,21 @@ static int hpdi_detach(struct comedi_device *dev)
 			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]);
+							    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);
+						    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);
 			}
@@ -719,7 +729,7 @@ static int dio_config_block_size(struct comedi_device *dev, unsigned int *data)
 }
 
 static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+		       struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -805,7 +815,7 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 			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");
+					     "chanlist must be channels 0 to 31 in order");
 				err++;
 				break;
 			}
@@ -819,7 +829,7 @@ static int di_cmd_test(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)
+			 struct comedi_cmd *cmd)
 {
 	if (priv(dev)->dio_config_output) {
 		return -EINVAL;
@@ -828,10 +838,10 @@ static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static inline void hpdi_writel(struct comedi_device *dev, uint32_t bits,
-	unsigned int offset)
+			       unsigned int offset)
 {
 	writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
-		priv(dev)->hpdi_iobase + offset);
+	       priv(dev)->hpdi_iobase + offset);
 }
 
 static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -857,16 +867,16 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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;
+	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 */
 	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);
+	       priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 	spin_unlock_irqrestore(&dev->spinlock, flags);
 
 	if (cmd->stop_src == TRIG_COUNT)
@@ -876,10 +886,10 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	/*  clear over/under run status flags */
 	writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
-		priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+	       priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
 	/*  enable interrupts */
 	writel(intr_bit(RX_FULL_INTR),
-		priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+	       priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
 
 	DEBUG_PRINT("hpdi: starting rx\n");
 	hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
@@ -905,22 +915,21 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
 
 	if (channel)
 		pci_addr_reg =
-			priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+		    priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
 	else
 		pci_addr_reg =
-			priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_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++) {
+	     (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) {
@@ -929,13 +938,15 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
 			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)->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);
+			    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 */
@@ -969,14 +980,14 @@ static irqreturn_t handle_interrupt(int irq, void *d)
 	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);
+		       priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
 	}
 	/*  spin lock makes sure noone else changes plx dma control reg */
 	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);
+		       priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 
 		DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
 		if (dma0_status & PLX_DMA_EN_BIT) {
@@ -989,10 +1000,9 @@ static irqreturn_t handle_interrupt(int irq, void *d)
 	/*  spin lock makes sure noone else changes plx dma control reg */
 	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 */
+	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);
+		       priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
 		DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
 
 		DEBUG_PRINT(" cleared dma ch1 interrupt\n");
@@ -1010,8 +1020,8 @@ static irqreturn_t handle_interrupt(int irq, void *d)
 		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));
+			    (int)readb(priv(dev)->plx9080_iobase +
+				       PLX_DMA0_CS_REG));
 	}
 
 	if (hpdi_board_status & RX_UNDERRUN_BIT) {
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 984f995..7a67fff 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -110,11 +110,11 @@ Options:
 
 /*  Define analogue range */
 static const struct comedi_lrange range_analog = { 4, {
-			UNI_RANGE(5),
-			UNI_RANGE(10),
-			BIP_RANGE(5),
-			BIP_RANGE(10)
-	}
+						       UNI_RANGE(5),
+						       UNI_RANGE(10),
+						       BIP_RANGE(5),
+						       BIP_RANGE(10)
+						       }
 };
 
 static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
@@ -124,7 +124,8 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
 	Forward declarations
 ==============================================================================
 */
-static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int icp_multi_attach(struct comedi_device *dev,
+			    struct comedi_devconfig *it);
 static int icp_multi_detach(struct comedi_device *dev);
 
 /*
@@ -155,33 +156,33 @@ struct 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 */
+	 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 */
 };
 
 #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(struct boardtype),
+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(struct boardtype),
 };
 
 COMEDI_INITCLEANUP(driver_icp_multi);
@@ -199,9 +200,9 @@ struct icp_multi_private {
 	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 *ai_data;		/*  data buffer */
 	short ao_data[4];	/*  data output buffer */
-	short di_data;	/*  Digital input data */
+	short di_data;		/*  Digital input data */
 	unsigned int do_data;	/*  Remember digital output data */
 };
 
@@ -215,11 +216,13 @@ struct icp_multi_private {
 */
 
 #if 0
-static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int *chanlist, unsigned int n_chan);
+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(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);
 static int icp_multi_reset(struct comedi_device *dev);
 
 /*
@@ -246,8 +249,9 @@ static int icp_multi_reset(struct comedi_device *dev);
 
 ==============================================================================
 */
-static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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;
 
@@ -267,42 +271,42 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subde
 
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp_multi A ST=%4x IO=%p\n",
-		readw(devpriv->io_addr + ICP_MULTI_ADC_CSR),
-		devpriv->io_addr + ICP_MULTI_ADC_CSR);
+	       readw(devpriv->io_addr + ICP_MULTI_ADC_CSR),
+	       devpriv->io_addr + ICP_MULTI_ADC_CSR);
 #endif
 
 	for (n = 0; n < insn->n; n++) {
 		/*  Set start ADC bit */
 		devpriv->AdcCmdStatus |= ADC_ST;
 		writew(devpriv->AdcCmdStatus,
-			devpriv->io_addr + ICP_MULTI_ADC_CSR);
+		       devpriv->io_addr + ICP_MULTI_ADC_CSR);
 		devpriv->AdcCmdStatus &= ~ADC_ST;
 
 #ifdef ICP_MULTI_EXTDEBUG
 		printk("icp multi B n=%d ST=%4x\n", n,
-			readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
+		       readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
 #endif
 
 		udelay(1);
 
 #ifdef ICP_MULTI_EXTDEBUG
 		printk("icp multi C n=%d ST=%4x\n", n,
-			readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
+		       readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
 #endif
 
 		/*  Wait for conversion to complete, or get fed up waiting */
 		timeout = 100;
 		while (timeout--) {
 			if (!(readw(devpriv->io_addr +
-						ICP_MULTI_ADC_CSR) & ADC_BSY))
+				    ICP_MULTI_ADC_CSR) & ADC_BSY))
 				goto conv_finish;
 
 #ifdef ICP_MULTI_EXTDEBUG
 			if (!(timeout % 10))
 				printk("icp multi D n=%d tm=%d ST=%4x\n", n,
-					timeout,
-					readw(devpriv->io_addr +
-						ICP_MULTI_ADC_CSR));
+				       timeout,
+				       readw(devpriv->io_addr +
+					     ICP_MULTI_ADC_CSR));
 #endif
 
 			udelay(1);
@@ -318,19 +322,21 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subde
 		/*  Clear interrupt status */
 		devpriv->IntStatus |= ADC_READY;
 		writew(devpriv->IntStatus,
-			devpriv->io_addr + ICP_MULTI_INT_STAT);
+		       devpriv->io_addr + ICP_MULTI_INT_STAT);
 
 		/*  Clear data received */
 		data[n] = 0;
 
 #ifdef ICP_MULTI_EXTDEBUG
-		printk("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", n);
+		printk
+		    ("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n",
+		     n);
 #endif
 		return -ETIME;
 
-	      conv_finish:
+conv_finish:
 		data[n] =
-			(readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
+		    (readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
 	}
 
 	/*  Disable interrupt */
@@ -365,8 +371,9 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subde
 
 ==============================================================================
 */
-static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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;
 
@@ -401,15 +408,15 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subd
 		timeout = 100;
 		while (timeout--) {
 			if (!(readw(devpriv->io_addr +
-						ICP_MULTI_DAC_CSR) & DAC_BSY))
+				    ICP_MULTI_DAC_CSR) & DAC_BSY))
 				goto dac_ready;
 
 #ifdef ICP_MULTI_EXTDEBUG
 			if (!(timeout % 10))
 				printk("icp multi A n=%d tm=%d ST=%4x\n", n,
-					timeout,
-					readw(devpriv->io_addr +
-						ICP_MULTI_DAC_CSR));
+				       timeout,
+				       readw(devpriv->io_addr +
+					     ICP_MULTI_DAC_CSR));
 #endif
 
 			udelay(1);
@@ -425,24 +432,26 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subd
 		/*  Clear interrupt status */
 		devpriv->IntStatus |= DAC_READY;
 		writew(devpriv->IntStatus,
-			devpriv->io_addr + ICP_MULTI_INT_STAT);
+		       devpriv->io_addr + ICP_MULTI_INT_STAT);
 
 		/*  Clear data received */
 		devpriv->ao_data[chan] = 0;
 
 #ifdef ICP_MULTI_EXTDEBUG
-		printk("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n);
+		printk
+		    ("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n",
+		     n);
 #endif
 		return -ETIME;
 
-	      dac_ready:
+dac_ready:
 		/*  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 */
 		devpriv->DacCmdStatus |= DAC_ST;
 		writew(devpriv->DacCmdStatus,
-			devpriv->io_addr + ICP_MULTI_DAC_CSR);
+		       devpriv->io_addr + ICP_MULTI_DAC_CSR);
 		devpriv->DacCmdStatus &= ~DAC_ST;
 
 		/*  Save analogue output data */
@@ -473,8 +482,9 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subd
 
 ==============================================================================
 */
-static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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;
 
@@ -506,8 +516,9 @@ static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subde
 
 ==============================================================================
 */
-static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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);
 
@@ -532,8 +543,9 @@ static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subde
 
 ==============================================================================
 */
-static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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");
@@ -574,8 +586,9 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subde
 
 ==============================================================================
 */
-static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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;
 }
@@ -598,8 +611,10 @@ static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subd
 
 ==============================================================================
 */
-static int icp_multi_insn_write_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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;
 }
@@ -626,7 +641,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
 
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp multi EDBG: BGN: interrupt_service_icp_multi(%d,...)\n",
-		irq);
+	       irq);
 #endif
 
 	/*  Is this interrupt from our board? */
@@ -637,7 +652,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
 
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("icp multi EDBG: interrupt_service_icp_multi() ST: %4x\n",
-		readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
+	       readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
 #endif
 
 	/*  Determine which interrupt is active & handle it */
@@ -690,8 +705,9 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
 
 ==============================================================================
 */
-static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int *chanlist, unsigned int n_chan)
+static int check_channel_list(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      unsigned int *chanlist, unsigned int n_chan)
 {
 	unsigned int i;
 
@@ -709,13 +725,13 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 		if (CR_AREF(chanlist[i]) == AREF_DIFF) {
 			if (CR_CHAN(chanlist[i]) > this_board->n_aichand) {
 				comedi_error(dev,
-					"Incorrect differential ai channel number");
+					     "Incorrect differential ai channel number");
 				return 0;
 			}
 		} else {
 			if (CR_CHAN(chanlist[i]) > this_board->n_aichan) {
 				comedi_error(dev,
-					"Incorrect ai channel number");
+					     "Incorrect ai channel number");
 				return 0;
 			}
 		}
@@ -744,8 +760,9 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 
 ==============================================================================
 */
-static void setup_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 i, range, chanprog;
 	unsigned int diff;
@@ -788,11 +805,11 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevic
 
 		/* Output channel, range, mode to ICP Multi */
 		writew(devpriv->AdcCmdStatus,
-			devpriv->io_addr + ICP_MULTI_ADC_CSR);
+		       devpriv->io_addr + ICP_MULTI_ADC_CSR);
 
 #ifdef ICP_MULTI_EXTDEBUG
 		printk("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
-			devpriv->act_chanlist[i]);
+		       devpriv->act_chanlist[i]);
 #endif
 	}
 
@@ -840,7 +857,7 @@ static int icp_multi_reset(struct comedi_device *dev)
 
 			/*  Output to command / status register */
 			writew(devpriv->DacCmdStatus,
-				devpriv->io_addr + ICP_MULTI_DAC_CSR);
+			       devpriv->io_addr + ICP_MULTI_DAC_CSR);
 
 			/*  Delay to allow DAC time to recover */
 			udelay(1);
@@ -871,7 +888,8 @@ static int icp_multi_reset(struct comedi_device *dev)
 
 ==============================================================================
 */
-static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int icp_multi_attach(struct comedi_device *dev,
+			    struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int ret, subdev, n_subdevices;
@@ -891,15 +909,15 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
 	if (pci_list_builded++ == 0) {
 		pci_card_list_init(PCI_VENDOR_ID_ICP,
 #ifdef ICP_MULTI_EXTDEBUG
-			1
+				   1
 #else
-			0
+				   0
 #endif
-			);
+		    );
 	}
 
 	printk("Anne's comedi%d: icp_multi: board=%s", dev->minor,
-		this_board->name);
+	       this_board->name);
 
 	card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
 					 this_board->device_id, it->options[0],
@@ -911,7 +929,7 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
 	devpriv->card = card;
 
 	if ((pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0],
-				&irq)) < 0) {
+			   &irq)) < 0) {
 		printk(" - Can't get configuration data!\n");
 		return -EIO;
 	}
@@ -920,7 +938,7 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
 	devpriv->phys_iobase = iobase;
 
 	printk(", b:s:f=%d:%d:%d, io=0x%8llx \n", pci_bus, pci_slot, pci_func,
-		(unsigned long long)iobase);
+	       (unsigned long long)iobase);
 
 	devpriv->io_addr = ioremap(iobase, ICP_MULTI_SIZE);
 
@@ -930,7 +948,7 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
 	}
 #ifdef ICP_MULTI_EXTDEBUG
 	printk("0x%08llx mapped to %p, ", (unsigned long long)iobase,
-		devpriv->io_addr);
+	       devpriv->io_addr);
 #endif
 
 	dev->board_name = this_board->name;
@@ -957,7 +975,9 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
 		if (irq) {
 			if (request_irq(irq, interrupt_service_icp_multi,
 					IRQF_SHARED, "Inova Icp Multi", dev)) {
-				printk(", unable to allocate IRQ %u, DISABLING IT", irq);
+				printk
+				    (", unable to allocate IRQ %u, DISABLING IT",
+				     irq);
 				irq = 0;	/* Can't use IRQ */
 			} else
 				printk(", irq=%u", irq);
diff --git a/drivers/staging/comedi/drivers/icp_multi.h b/drivers/staging/comedi/drivers/icp_multi.h
index 354ba8f..8caadc6 100644
--- a/drivers/staging/comedi/drivers/icp_multi.h
+++ b/drivers/staging/comedi/drivers/icp_multi.h
@@ -36,20 +36,26 @@ struct pcilst_struct *inova_devices;
 static void pci_card_list_init(unsigned short pci_vendor, char display);
 static void pci_card_list_cleanup(unsigned short pci_vendor);
 static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
-	vendor_id, unsigned short device_id);
+							  vendor_id,
+							  unsigned short
+							  device_id);
 static int 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);
+					  unsigned short device_id,
+					  unsigned short pci_bus,
+					  unsigned short pci_slot,
+					  struct pcilst_struct **card);
 static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
-	unsigned short device_id, unsigned short pci_bus,
-	unsigned short pci_slot);
+						       unsigned short device_id,
+						       unsigned short pci_bus,
+						       unsigned short pci_slot);
 
 static int pci_card_alloc(struct pcilst_struct *amcc);
 static int pci_card_free(struct pcilst_struct *amcc);
 static void pci_card_list_display(void);
 static int 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);
+			 unsigned char *pci_bus, unsigned char *pci_slot,
+			 unsigned char *pci_func, resource_size_t * io_addr,
+			 unsigned int *irq);
 
 /****************************************************************************/
 
@@ -64,12 +70,13 @@ static void pci_card_list_init(unsigned short pci_vendor, char display)
 	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)) {
+	     pcidev != NULL;
+	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
 		if (pcidev->vendor == pci_vendor) {
 			inova = kmalloc(sizeof(*inova), GFP_KERNEL);
 			if (!inova) {
-				printk("icp_multi: pci_card_list_init: allocation failed\n");
+				printk
+				    ("icp_multi: pci_card_list_init: allocation failed\n");
 				pci_dev_put(pcidev);
 				break;
 			}
@@ -93,7 +100,7 @@ static void pci_card_list_init(unsigned short pci_vendor, char display)
 			 * pci_card_alloc. */
 			for (i = 0; i < 5; i++)
 				inova->io_addr[i] =
-					pci_resource_start(pcidev, i);
+				    pci_resource_start(pcidev, i);
 			inova->irq = pcidev->irq;
 		}
 	}
@@ -120,14 +127,16 @@ static void pci_card_list_cleanup(unsigned short pci_vendor)
 /****************************************************************************/
 /* find first unused card with this device_id */
 static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
-	vendor_id, unsigned short device_id)
+							  vendor_id,
+							  unsigned short
+							  device_id)
 {
 	struct pcilst_struct *inova, *next;
 
 	for (inova = inova_devices; inova; inova = next) {
 		next = inova->next;
 		if ((!inova->used) && (inova->device == device_id)
-			&& (inova->vendor == vendor_id))
+		    && (inova->vendor == vendor_id))
 			return inova;
 
 	}
@@ -138,8 +147,10 @@ static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
 /****************************************************************************/
 /* find card on requested position */
 static int 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)
+					  unsigned short device_id,
+					  unsigned short pci_bus,
+					  unsigned short pci_slot,
+					  struct pcilst_struct **card)
 {
 	struct pcilst_struct *inova, *next;
 
@@ -147,8 +158,8 @@ static int find_free_pci_card_by_position(unsigned short vendor_id,
 	for (inova = inova_devices; inova; inova = next) {
 		next = inova->next;
 		if ((inova->vendor == vendor_id) && (inova->device == device_id)
-			&& (inova->pci_bus == pci_bus)
-			&& (inova->pci_slot == pci_slot)) {
+		    && (inova->pci_bus == pci_bus)
+		    && (inova->pci_slot == pci_slot)) {
 			if (!(inova->used)) {
 				*card = inova;
 				return 0;	/* ok, card is found */
@@ -211,7 +222,13 @@ static void pci_card_list_display(void)
 
 	for (inova = inova_devices; inova; inova = next) {
 		next = inova->next;
-		printk("%2d   %2d   %2d  0x%4x 0x%4x   0x%8llx 0x%8llx  %2u  %2d\n", inova->pci_bus, inova->pci_slot, inova->pci_func, inova->vendor, inova->device, (unsigned long long)inova->io_addr[0], (unsigned long long)inova->io_addr[2], inova->irq, inova->used);
+		printk
+		    ("%2d   %2d   %2d  0x%4x 0x%4x   0x%8llx 0x%8llx  %2u  %2d\n",
+		     inova->pci_bus, inova->pci_slot, inova->pci_func,
+		     inova->vendor, inova->device,
+		     (unsigned long long)inova->io_addr[0],
+		     (unsigned long long)inova->io_addr[2], inova->irq,
+		     inova->used);
 
 	}
 }
@@ -219,8 +236,9 @@ static void pci_card_list_display(void)
 /****************************************************************************/
 /* return all card information for driver */
 static int pci_card_data(struct pcilst_struct *inova,
-	unsigned char *pci_bus, unsigned char *pci_slot,
-	unsigned char *pci_func, resource_size_t * io_addr, unsigned int *irq)
+			 unsigned char *pci_bus, unsigned char *pci_slot,
+			 unsigned char *pci_func, resource_size_t * io_addr,
+			 unsigned int *irq)
 {
 	int i;
 
@@ -238,8 +256,9 @@ static int pci_card_data(struct pcilst_struct *inova,
 /****************************************************************************/
 /* select and alloc card */
 static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
-	unsigned short device_id, unsigned short pci_bus,
-	unsigned short pci_slot)
+						       unsigned short device_id,
+						       unsigned short pci_bus,
+						       unsigned short pci_slot)
 {
 	struct pcilst_struct *card;
 	int err;
@@ -253,16 +272,17 @@ static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
 		}
 	} else {
 		switch (find_free_pci_card_by_position(vendor_id, device_id,
-				pci_bus, pci_slot, &card)) {
+						       pci_bus, pci_slot,
+						       &card)) {
 		case 1:
 			printk
-				(" - Card not found on requested position b:s %d:%d!\n",
-				pci_bus, pci_slot);
+			    (" - Card not found on requested position b:s %d:%d!\n",
+			     pci_bus, pci_slot);
 			return NULL;
 		case 2:
 			printk
-				(" - Card on requested position is used b:s %d:%d!\n",
-				pci_bus, pci_slot);
+			    (" - Card on requested position is used b:s %d:%d!\n",
+			     pci_bus, pci_slot);
 			return NULL;
 		}
 	}
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index a90d65f..24df245 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -154,11 +154,11 @@ struct pci20xxx_private {
 	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_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it);
 static int pci20xxx_detach(struct comedi_device *dev);
 
 static struct comedi_driver driver_pci20xxx = {
@@ -169,10 +169,11 @@ static struct comedi_driver driver_pci20xxx = {
 };
 
 static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s,
-	int opt0, int opt1);
+			 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);
+			 int opt0, int opt1);
+static int pci20xxx_dio_init(struct comedi_device *dev,
+			     struct comedi_subdevice *s);
 
 /*
   options[0]	Board base address
@@ -201,7 +202,8 @@ static int pci20xxx_dio_init(struct comedi_device *dev, struct comedi_subdevice
 		1 == unipolar 10V  (0V -- +10V)
 		2 == bipolar 5V  (-5V -- +5V)
 */
-static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pci20xxx_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	unsigned char i;
 	int ret;
@@ -223,7 +225,9 @@ static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *i
 	/* 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);
+		printk
+		    (" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n",
+		     devpriv->ioaddr);
 		return -EINVAL;
 	}
 	printk("comedi%d:\n", dev->minor);
@@ -237,22 +241,24 @@ static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *i
 		switch (id) {
 		case PCI20006_ID:
 			sdp->pci20006.iobase =
-				devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
+			    devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
 			pci20006_init(dev, s, it->options[2 * i + 2],
-				it->options[2 * i + 3]);
+				      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;
+			    devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
 			pci20341_init(dev, s, it->options[2 * i + 2],
-				it->options[2 * i + 3]);
+				      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);
+			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;
@@ -275,10 +281,12 @@ static int pci20xxx_detach(struct comedi_device *dev)
 
 /* 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 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,
@@ -287,7 +295,7 @@ static const struct comedi_lrange *pci20006_range_list[] = {
 };
 
 static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s,
-	int opt0, int opt1)
+			 int opt0, int opt1)
 {
 	union pci20xxx_subdev_private *sdp = s->private;
 
@@ -311,8 +319,9 @@ static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 0;
 }
 
-static int pci20006_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
 
@@ -321,8 +330,9 @@ static int pci20006_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	return 1;
 }
 
-static int pci20006_insn_write(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)
 {
 	union pci20xxx_subdev_private *sdp = s->private;
 	int hi, lo;
@@ -354,15 +364,17 @@ static int pci20006_insn_write(struct comedi_device *dev, struct comedi_subdevic
 
 /* PCI20341M */
 
-static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+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 range_bipolar0_025 =
+    { 1, {BIP_RANGE(0.025)} };
 
 static const struct comedi_lrange *const pci20341_ranges[] = {
 	&range_bipolar5,
@@ -372,7 +384,7 @@ static const struct comedi_lrange *const pci20341_ranges[] = {
 };
 
 static int pci20341_init(struct comedi_device *dev, struct comedi_subdevice *s,
-	int opt0, int opt1)
+			 int opt0, int opt1)
 {
 	union pci20xxx_subdev_private *sdp = s->private;
 	int option;
@@ -402,10 +414,11 @@ static int pci20341_init(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 0;
 }
 
-static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
+	union pci20xxx_subdev_private *sdp = s->private;
 	unsigned int i = 0, j = 0;
 	int lo, hi;
 	unsigned char eoc;	/* end of conversion */
@@ -414,7 +427,7 @@ static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice
 
 	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);
+	    | 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);
@@ -434,13 +447,15 @@ static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice
 			eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
 		}
 		if (j >= 100) {
-			printk("comedi%d:  pci20xxx: AI interrupt channel %i polling exit !\n", dev->minor, i);
+			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 */
+		data[i] = (short)((boarddata + 0x8000) & 0xffff);	/* board-data -> comedi-data */
 	}
 
 	return i;
@@ -448,14 +463,19 @@ static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice
 
 /* 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);
+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)
+static int pci20xxx_dio_init(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 
 	s->type = COMEDI_SUBD_DIO;
@@ -474,8 +494,10 @@ static int pci20xxx_dio_init(struct comedi_device *dev, struct comedi_subdevice
 	return 0;
 }
 
-static int pci20xxx_dio_insn_config(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)
 {
 	int mask, bits;
 
@@ -499,8 +521,9 @@ static int pci20xxx_dio_insn_config(struct comedi_device *dev, struct comedi_sub
 	return 1;
 }
 
-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_bits(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int mask = data[0];
 
@@ -510,16 +533,16 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subde
 	mask &= s->io_bits;
 	if (mask & 0x000000ff)
 		writeb((s->state >> 0) & 0xff,
-			devpriv->ioaddr + PCI20000_DIO_0);
+		       devpriv->ioaddr + PCI20000_DIO_0);
 	if (mask & 0x0000ff00)
 		writeb((s->state >> 8) & 0xff,
-			devpriv->ioaddr + PCI20000_DIO_1);
+		       devpriv->ioaddr + PCI20000_DIO_1);
 	if (mask & 0x00ff0000)
 		writeb((s->state >> 16) & 0xff,
-			devpriv->ioaddr + PCI20000_DIO_2);
+		       devpriv->ioaddr + PCI20000_DIO_2);
 	if (mask & 0xff000000)
 		writeb((s->state >> 24) & 0xff,
-			devpriv->ioaddr + PCI20000_DIO_3);
+		       devpriv->ioaddr + PCI20000_DIO_3);
 
 	data[1] = readb(devpriv->ioaddr + PCI20000_DIO_0);
 	data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
@@ -529,7 +552,8 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subde
 	return 2;
 }
 
-static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pci20xxx_dio_config(struct comedi_device *dev,
+				struct comedi_subdevice *s)
 {
 	unsigned char control_01;
 	unsigned char control_23;
@@ -543,7 +567,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
 		/* output port 0 */
 		control_01 &= PCI20000_DIO_EOC;
 		buffer = (buffer & (~(DIO_BE << DIO_PS_0))) | (DIO_BO <<
-			DIO_PS_0);
+							       DIO_PS_0);
 	} else {
 		/* input port 0 */
 		control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_EIC;
@@ -553,7 +577,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
 		/* output port 1 */
 		control_01 &= PCI20000_DIO_OOC;
 		buffer = (buffer & (~(DIO_BE << DIO_PS_1))) | (DIO_BO <<
-			DIO_PS_1);
+							       DIO_PS_1);
 	} else {
 		/* input port 1 */
 		control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_OIC;
@@ -563,7 +587,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
 		/* output port 2 */
 		control_23 &= PCI20000_DIO_EOC;
 		buffer = (buffer & (~(DIO_BE << DIO_PS_2))) | (DIO_BO <<
-			DIO_PS_2);
+							       DIO_PS_2);
 	} else {
 		/* input port 2 */
 		control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_EIC;
@@ -573,7 +597,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
 		/* output port 3 */
 		control_23 &= PCI20000_DIO_OOC;
 		buffer = (buffer & (~(DIO_BE << DIO_PS_3))) | (DIO_BO <<
-			DIO_PS_3);
+							       DIO_PS_3);
 	} else {
 		/* input port 3 */
 		control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_OIC;
@@ -598,7 +622,8 @@ static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s)
 	writeb((s->state >> 24) & 0xff, devpriv->ioaddr + PCI20000_DIO_3);
 }
 
-static unsigned int pci20xxx_di(struct comedi_device *dev, struct comedi_subdevice *s)
+static unsigned int pci20xxx_di(struct comedi_device *dev,
+				struct comedi_subdevice *s)
 {
 	/* XXX same note as above */
 	unsigned int bits;
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index e3c3adc..14bf29b 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -56,7 +56,8 @@ Devices: [JR3] PCI force sensor board (jr3_pci)
 #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_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 = {
@@ -67,15 +68,16 @@ static struct comedi_driver driver_jr3_pci = {
 };
 
 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}
+	{
+	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);
@@ -89,14 +91,12 @@ struct jr3_pci_dev_private {
 	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;
@@ -124,7 +124,7 @@ struct jr3_pci_subdev_private {
 /* Hotplug firmware loading stuff */
 
 typedef int comedi_firmware_callback(struct comedi_device *dev,
-				     const u8 *data, size_t size);
+				     const u8 * data, size_t size);
 
 static int comedi_load_firmware(struct comedi_device *dev, char *name,
 				comedi_firmware_callback cb)
@@ -143,7 +143,7 @@ static int comedi_load_firmware(struct comedi_device *dev, char *name,
 		strcat(firmware_path, prefix);
 		strcat(firmware_path, name);
 		result = request_firmware(&fw, firmware_path,
-			&devpriv->pci_dev->dev);
+					  &devpriv->pci_dev->dev);
 		if (result == 0) {
 			if (!cb)
 				result = -EINVAL;
@@ -178,7 +178,7 @@ struct transform_t {
 };
 
 static void set_transforms(volatile struct jr3_channel *channel,
-	struct transform_t transf, short num)
+			   struct transform_t transf, short num)
 {
 	int i;
 
@@ -197,7 +197,8 @@ static void set_transforms(volatile struct jr3_channel *channel,
 	}
 }
 
-static void use_transform(volatile struct jr3_channel *channel, short transf_num)
+static void use_transform(volatile struct jr3_channel *channel,
+			  short transf_num)
 {
 	set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
 }
@@ -222,12 +223,12 @@ struct six_axis_t {
 };
 
 static void set_full_scales(volatile struct jr3_channel *channel,
-	struct six_axis_t full_scale)
+			    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);
+	       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);
@@ -237,7 +238,8 @@ static void set_full_scales(volatile struct jr3_channel *channel,
 	set_s16(&channel->command_word0, 0x0a00);
 }
 
-static struct six_axis_t get_min_full_scales(volatile struct jr3_channel *channel)
+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);
@@ -249,7 +251,8 @@ static struct six_axis_t get_min_full_scales(volatile struct jr3_channel *channe
 	return result;
 }
 
-static struct six_axis_t get_max_full_scales(volatile struct jr3_channel *channel)
+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);
@@ -261,8 +264,9 @@ static struct six_axis_t get_max_full_scales(volatile struct jr3_channel *channe
 	return result;
 }
 
-static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -277,9 +281,8 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 
 		result = insn->n;
 		if (p->state != state_jr3_done ||
-			(get_u16(&p->channel->
-					errors) & (watch_dog | watch_dog2 |
-					sensor_change))) {
+		    (get_u16(&p->channel->errors) & (watch_dog | watch_dog2 |
+						     sensor_change))) {
 			/* No sensor or sensor changed */
 			if (p->state == state_jr3_done) {
 				/* Restart polling */
@@ -299,59 +302,51 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 					int F = 0;
 					switch (axis) {
 					case 0:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								fx);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].fx);
 						}
 						break;
 					case 1:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								fy);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].fy);
 						}
 						break;
 					case 2:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								fz);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].fz);
 						}
 						break;
 					case 3:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								mx);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].mx);
 						}
 						break;
 					case 4:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								my);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].my);
 						}
 						break;
 					case 5:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								mz);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].mz);
 						}
 						break;
 					case 6:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								v1);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].v1);
 						}
 						break;
 					case 7:{
-							F = get_s16(&p->
-								channel->
-								filter[filter].
-								v2);
+							F = get_s16
+							    (&p->channel->filter
+							     [filter].v2);
 						}
 						break;
 					}
@@ -362,14 +357,14 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 					data[i] = 0;
 				} else {
 					data[i] =
-						get_u16(&p->channel->model_no);
+					    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);
+					    get_u16(&p->channel->serial_no);
 				}
 			}
 		}
@@ -389,12 +384,12 @@ static void jr3_pci_open(struct comedi_device *dev)
 		p = dev->subdevices[i].private;
 		if (p) {
 			printk("serial: %p %d (%d)\n", p, p->serial_no,
-				p->channel_no);
+			       p->channel_no);
 		}
 	}
 }
 
-int read_idm_word(const u8 *data, size_t size, int *pos, unsigned int *val)
+int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
 {
 	int result = 0;
 	if (pos != 0 && val != 0) {
@@ -416,8 +411,8 @@ int read_idm_word(const u8 *data, size_t size, int *pos, unsigned int *val)
 	return result;
 }
 
-static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
-	size_t size)
+static int jr3_download_firmware(struct comedi_device *dev, const u8 * data,
+				 size_t size)
 {
 	/*
 	 * IDM file format is:
@@ -461,24 +456,23 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
 			while (more) {
 				unsigned int count, addr;
 				more = more
-					&& read_idm_word(data, size, &pos,
-					&count);
+				    && read_idm_word(data, size, &pos, &count);
 				if (more && count == 0xffff) {
 					break;
 				}
 				more = more
-					&& read_idm_word(data, size, &pos,
-					&addr);
+				    && read_idm_word(data, size, &pos, &addr);
 				printk("Loading#%d %4.4x bytes at %4.4x\n", i,
-					count, addr);
+				       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);
+						    && read_idm_word(data,
+								     size, &pos,
+								     &data1);
 						count--;
 						/* printk("jr3_data, not tested\n"); */
 						/* jr3[addr + 0x20000 * pnum] = data1; */
@@ -487,21 +481,23 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
 						unsigned int data1, data2;
 
 						more = more
-							&& read_idm_word(data,
-							size, &pos, &data1);
+						    && read_idm_word(data,
+								     size, &pos,
+								     &data1);
 						more = more
-							&& read_idm_word(data,
-							size, &pos, &data2);
+						    && read_idm_word(data, size,
+								     &pos,
+								     &data2);
 						count -= 2;
 						if (more) {
-							set_u16(&p->iobase->
-								channel[i].
-								program_low
+							set_u16(&p->
+								iobase->channel
+								[i].program_low
 								[addr], data1);
 							udelay(1);
-							set_u16(&p->iobase->
-								channel[i].
-								program_high
+							set_u16(&p->
+								iobase->channel
+								[i].program_high
 								[addr], data2);
 							udelay(1);
 
@@ -538,7 +534,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 				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) {
+				    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.
@@ -547,7 +543,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 				} else {
 					p->retries = 0;
 					p->state =
-						state_jr3_init_wait_for_offset;
+					    state_jr3_init_wait_for_offset;
 					result = poll_delay_min_max(1000, 2000);
 				}
 			}
@@ -561,40 +557,44 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 					struct transform_t transf;
 
 					p->model_no =
-						get_u16(&channel->model_no);
+					    get_u16(&channel->model_no);
 					p->serial_no =
-						get_u16(&channel->serial_no);
+					    get_u16(&channel->serial_no);
 
-					printk("Setting transform for channel %d\n", p->channel_no);
+					printk
+					    ("Setting transform for channel %d\n",
+					     p->channel_no);
 					printk("Sensor Model     = %i\n",
-						p->model_no);
+					       p->model_no);
 					printk("Sensor Serial    = %i\n",
-						p->serial_no);
+					       p->serial_no);
 
 					/*  Transformation all zeros */
 					transf.link[0].link_type =
-						(enum link_types)0;
+					    (enum link_types)0;
 					transf.link[0].link_amount = 0;
 					transf.link[1].link_type =
-						(enum link_types)0;
+					    (enum link_types)0;
 					transf.link[1].link_amount = 0;
 					transf.link[2].link_type =
-						(enum link_types)0;
+					    (enum link_types)0;
 					transf.link[2].link_amount = 0;
 					transf.link[3].link_type =
-						(enum link_types)0;
+					    (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;
+					    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));
+					printk
+					    ("state_jr3_init_transform_complete complete = %d\n",
+					     is_complete(channel));
 					result = poll_delay_min_max(20, 100);
 				} else {
 					/*  Set full scale */
@@ -602,7 +602,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 					struct six_axis_t max_full_scale;
 
 					min_full_scale =
-						get_min_full_scales(channel);
+					    get_min_full_scales(channel);
 					printk("Obtained Min. Full Scales:\n");
 					printk("%i   ", (min_full_scale).fx);
 					printk("%i   ", (min_full_scale).fy);
@@ -613,7 +613,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 					printk("\n");
 
 					max_full_scale =
-						get_max_full_scales(channel);
+					    get_max_full_scales(channel);
 					printk("Obtained Max. Full Scales:\n");
 					printk("%i   ", (max_full_scale).fx);
 					printk("%i   ", (max_full_scale).fy);
@@ -624,17 +624,19 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 					printk("\n");
 
 					set_full_scales(channel,
-						max_full_scale);
+							max_full_scale);
 
 					p->state =
-						state_jr3_init_set_full_scale_complete;
+					    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));
+					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;
@@ -642,32 +644,29 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 					/*  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;
+					    -get_s16(&full_scale->fx) * 1000;
 					p->range[0].range.max =
-						get_s16(&full_scale->fx) * 1000;
+					    get_s16(&full_scale->fx) * 1000;
 					p->range[1].range.min =
-						-get_s16(&full_scale->fy) *
-						1000;
+					    -get_s16(&full_scale->fy) * 1000;
 					p->range[1].range.max =
-						get_s16(&full_scale->fy) * 1000;
+					    get_s16(&full_scale->fy) * 1000;
 					p->range[2].range.min =
-						-get_s16(&full_scale->fz) *
-						1000;
+					    -get_s16(&full_scale->fz) * 1000;
 					p->range[2].range.max =
-						get_s16(&full_scale->fz) * 1000;
+					    get_s16(&full_scale->fz) * 1000;
 					p->range[3].range.min =
-						-get_s16(&full_scale->mx) * 100;
+					    -get_s16(&full_scale->mx) * 100;
 					p->range[3].range.max =
-						get_s16(&full_scale->mx) * 100;
+					    get_s16(&full_scale->mx) * 100;
 					p->range[4].range.min =
-						-get_s16(&full_scale->my) * 100;
+					    -get_s16(&full_scale->my) * 100;
 					p->range[4].range.max =
-						get_s16(&full_scale->my) * 100;
+					    get_s16(&full_scale->my) * 100;
 					p->range[5].range.min =
-						-get_s16(&full_scale->mz) * 100;
+					    -get_s16(&full_scale->mz) * 100;
 					p->range[5].range.max =
-						get_s16(&full_scale->mz) * 100;
+					    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;	/*  ?? */
@@ -679,27 +678,38 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 						int i;
 						for (i = 0; i < 9; i++) {
 							printk("%d %d - %d\n",
-								i,
-								p->range[i].
-								range.min,
-								p->range[i].
-								range.max);
+							       i,
+							       p->
+							       range[i].range.
+							       min,
+							       p->
+							       range[i].range.
+							       max);
 						}
 					}
 
 					use_offset(channel, 0);
 					p->state =
-						state_jr3_init_use_offset_complete;
+					    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));
+					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));
+					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);
@@ -730,7 +740,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
 static void jr3_pci_poll_dev(unsigned long data)
 {
 	unsigned long flags;
-	struct comedi_device *dev = (struct comedi_device *) data;
+	struct comedi_device *dev = (struct comedi_device *)data;
 	struct jr3_pci_dev_private *devpriv = dev->private;
 	unsigned long now;
 	int delay;
@@ -741,15 +751,16 @@ static void jr3_pci_poll_dev(unsigned long data)
 	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;
+		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);
+			    jiffies + msecs_to_jiffies(sub_delay.min);
 			subdevpriv->next_time_max =
-				jiffies + msecs_to_jiffies(sub_delay.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
@@ -765,7 +776,8 @@ static void jr3_pci_poll_dev(unsigned long data)
 	add_timer(&devpriv->timer);
 }
 
-static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int jr3_pci_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	int result = 0;
 	struct pci_dev *card = NULL;
@@ -779,7 +791,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 
 	if (sizeof(struct jr3_channel) != 0xc00) {
 		printk("sizeof(struct jr3_channel) = %x [expected %x]\n",
-			(unsigned)sizeof(struct jr3_channel), 0xc00);
+		       (unsigned)sizeof(struct jr3_channel), 0xc00);
 		return -EINVAL;
 	}
 
@@ -822,7 +834,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 					/* Take first available card */
 					break;
 				} else if (opt_bus == card->bus->number &&
-					opt_slot == PCI_SLOT(card->devfn)) {
+					   opt_slot == PCI_SLOT(card->devfn)) {
 					/* Take requested card */
 					break;
 				}
@@ -843,7 +855,8 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	}
 
 	devpriv->pci_enabled = 1;
-	devpriv->iobase = ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t));
+	devpriv->iobase =
+	    ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t));
 	result = alloc_subdevices(dev, devpriv->n_channels);
 	if (result < 0)
 		goto out;
@@ -855,7 +868,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		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);
+		    kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
 		if (dev->subdevices[i].private) {
 			struct jr3_pci_subdev_private *p;
 			int j;
@@ -863,9 +876,9 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 			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, devpriv->iobase,
+			       ((char *)(p->channel) -
+				(char *)(devpriv->iobase)));
 			p->channel_no = i;
 			for (j = 0; j < 8; j++) {
 				int k;
@@ -875,7 +888,8 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 				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];
+					    (struct comedi_lrange *)&p->
+					    range[j];
 					p->maxdata_list[j + k * 8] = 0x7fff;
 				}
 			}
@@ -884,15 +898,15 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 			p->range[8].range.max = 65536;
 
 			p->range_table_list[56] =
-				(struct comedi_lrange *) &p->range[8];
+			    (struct comedi_lrange *)&p->range[8];
 			p->range_table_list[57] =
-				(struct comedi_lrange *) &p->range[8];
+			    (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;
+			    p->range_table_list;
 			dev->subdevices[i].maxdata = 0;
 			dev->subdevices[i].maxdata_list = p->maxdata_list;
 		}
@@ -922,8 +936,8 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	msleep_interruptible(25);
 	for (i = 0; i < 0x18; i++) {
 		printk("%c",
-			get_u16(&devpriv->iobase->channel[0].data.
-				copyright[i]) >> 8);
+		       get_u16(&devpriv->iobase->channel[0].
+			       data.copyright[i]) >> 8);
 	}
 
 	/*  Start card timer */
@@ -939,7 +953,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
 	add_timer(&devpriv->timer);
 
-      out:
+out:
 	return result;
 }
 
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
index 4f4bfb2..a146961 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.h
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -2,22 +2,22 @@
  * is 16 bits, but aligned on a 32 bit PCI boundary
  */
 
-static inline u16 get_u16(volatile const u32 *p)
+static inline u16 get_u16(volatile const u32 * p)
 {
 	return (u16) readl(p);
 }
 
-static inline void set_u16(volatile u32 *p, u16 val)
+static inline void set_u16(volatile u32 * p, u16 val)
 {
 	writel(val, p);
 }
 
-static inline s16 get_s16(volatile const s32 *p)
+static inline s16 get_s16(volatile const s32 * p)
 {
 	return (s16) readl(p);
 }
 
-static inline void set_s16(volatile s32 *p, s16 val)
+static inline void set_s16(volatile s32 * p, s16 val)
 {
 	writel(val, p);
 }
@@ -304,7 +304,7 @@ struct jr3_channel {
 	/* not set a full scale. */
 
 	struct six_axis_array default_FS;	/* offset 0x0068 */
-	s32 reserved3;	/* offset 0x006e */
+	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
@@ -341,7 +341,7 @@ struct jr3_channel {
 	 */
 
 	struct six_axis_array min_full_scale;	/* offset 0x0070 */
-	s32 reserved4;	/* offset 0x0076 */
+	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
@@ -354,7 +354,7 @@ struct jr3_channel {
 	/*  min_full_scale (pg. 9) for more details. */
 
 	struct six_axis_array max_full_scale;	/* offset 0x0078 */
-	s32 reserved5;	/* offset 0x007e */
+	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
@@ -398,14 +398,14 @@ struct jr3_channel {
 	 * offset # command (pg. 34). It can vary between 0 and 15.
 	 */
 
-	s32 offset_num;	/* offset 0x008e */
+	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 */
+	u32 vect_axes;		/* offset 0x008f */
 
 	/* Filter0 is the decoupled, unfiltered data from the JR3 sensor.
 	 * This data has had the offsets removed.
@@ -465,7 +465,7 @@ struct jr3_channel {
 	 */
 
 	s32 near_sat_value;	/* offset 0x00e0 */
-	s32 sat_value;	/* offset 0x00e1 */
+	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
@@ -486,7 +486,7 @@ struct jr3_channel {
 
 	s32 rate_address;	/* offset 0x00e2 */
 	u32 rate_divisor;	/* offset 0x00e3 */
-	u32 rate_count;	/* offset 0x00e4 */
+	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
@@ -543,14 +543,14 @@ struct jr3_channel {
 	 * Issues section on pg. 49 for more details.
 	 */
 
-	u32 count_x;	/* offset 0x00ef */
+	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 warnings;		/* offset 0x00f0 */
 	u32 errors;		/* offset 0x00f1 */
 
 	/* Threshold_bits is a word containing the bits that are set by the
@@ -565,7 +565,7 @@ struct jr3_channel {
 	 * description for cal_crc_bad (pg. 21) for more information.
 	 */
 
-	s32 last_CRC;	/* offset 0x00f3 */
+	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.
@@ -591,16 +591,16 @@ struct jr3_channel {
 	 * different sensor configurations.
 	 */
 
-	u32 serial_no;	/* offset 0x00f8 */
-	u32 model_no;	/* offset 0x00f9 */
+	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 */
+	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
@@ -627,7 +627,7 @@ struct jr3_channel {
 
 	u32 units;		/* offset 0x00fc */
 	s32 bits;		/* offset 0x00fd */
-	s32 channels;	/* offset 0x00fe */
+	s32 channels;		/* offset 0x00fe */
 
 	/* Thickness specifies the overall thickness of the sensor from
 	 * flange to flange. The engineering units for this value are
@@ -636,7 +636,7 @@ struct jr3_channel {
 	 * transformation from the center of the sensor to either flange.
 	 */
 
-	s32 thickness;	/* offset 0x00ff */
+	s32 thickness;		/* offset 0x00ff */
 
 	/* Load_envelopes is a table containing the load envelope
 	 * descriptions. There are 16 possible load envelope slots in the
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
index b49aed5..c145e82 100644
--- a/drivers/staging/comedi/drivers/ke_counter.c
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -52,9 +52,10 @@ 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}
+	{
+	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);
@@ -69,13 +70,12 @@ struct cnt_board_struct {
 	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}
+	 .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))
@@ -87,7 +87,6 @@ struct cnt_device_private {
 	struct pci_dev *pcidev;
 };
 
-
 #define devpriv ((struct cnt_device_private *)dev->private)
 
 static struct comedi_driver cnt_driver = {
@@ -104,18 +103,19 @@ COMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table);
 /* 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)
+		     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);
+	     dev->iobase + chan * 0x20 + 0x10);
 	outb((unsigned char)((data[0] >> 16) & 0xff),
-		dev->iobase + chan * 0x20 + 0x0c);
+	     dev->iobase + chan * 0x20 + 0x0c);
 	outb((unsigned char)((data[0] >> 8) & 0xff),
-		dev->iobase + chan * 0x20 + 0x08);
+	     dev->iobase + chan * 0x20 + 0x08);
 	outb((unsigned char)((data[0] >> 0) & 0xff),
-		dev->iobase + chan * 0x20 + 0x04);
+	     dev->iobase + chan * 0x20 + 0x04);
 
 	/* return the number of samples written */
 	return 1;
@@ -124,7 +124,8 @@ static int cnt_winsn(struct comedi_device *dev,
 /*-- counter read -----------------------------------------------------------*/
 
 static int cnt_rinsn(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+		     struct comedi_subdevice *s, struct comedi_insn *insn,
+		     unsigned int *data)
 {
 	unsigned char a0, a1, a2, a3, a4;
 	int chan = CR_CHAN(insn->chanspec);
@@ -140,7 +141,7 @@ static int cnt_rinsn(struct comedi_device *dev,
 	if (a4 > 0)
 		result = result - s->maxdata;
 
-	*data = (unsigned int) result;
+	*data = (unsigned int)result;
 
 	/* return the number of samples read */
 	return 1;
@@ -163,49 +164,51 @@ static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	/* 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)) {
+	     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) {
+				    pci_device->device) {
 					/* was a particular bus/slot requested? */
 					if ((it->options[0] != 0)
-						|| (it->options[1] != 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]) {
+						    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;
+					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]);
+	       dev->minor, it->options[0], it->options[1]);
 	return -EIO;
 
-      found:
+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));
+	       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 */
 	error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME);
 	if (error < 0) {
-		printk("comedi%d: failed to enable PCI device and request regions!\n", dev->minor);
+		printk
+		    ("comedi%d: failed to enable PCI device and request regions!\n",
+		     dev->minor);
 		return error;
 	}
 
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index 2368458..6079913 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -71,24 +71,21 @@ broken.
   ===========================================================================*/
 
 static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
-	{PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{0}
+	{
+	PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	0}
 };
 
 MODULE_DEVICE_TABLE(pci, me4000_pci_table);
@@ -119,13 +116,14 @@ static const struct me4000_board me4000_boards[] = {
 /*-----------------------------------------------------------------------------
   Comedi function prototypes
   ---------------------------------------------------------------------------*/
-static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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,
+driver_name:"me4000",
+module:THIS_MODULE,
+attach:me4000_attach,
+detach:me4000_detach,
 };
 
 /*-----------------------------------------------------------------------------
@@ -133,7 +131,8 @@ static struct comedi_driver driver_me4000 = {
   ---------------------------------------------------------------------------*/
 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_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);
@@ -142,80 +141,95 @@ static int xilinx_download(struct comedi_device *dev);
 static int reset_board(struct comedi_device *dev);
 
 static int me4000_dio_insn_bits(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
 
 static int me4000_dio_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
 
 static int cnt_reset(struct comedi_device *dev, unsigned int channel);
 
 static int cnt_config(struct comedi_device *dev,
-	unsigned int channel, unsigned int mode);
+		      unsigned int channel, unsigned int mode);
 
 static int me4000_cnt_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data);
 
 static int me4000_cnt_insn_write(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
 
 static int me4000_cnt_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
 
 static int me4000_ai_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data);
+			       struct comedi_subdevice *subdevice,
+			       struct comedi_insn *insn, unsigned int *data);
 
-static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+static int me4000_ai_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s);
 
 static int ai_check_chanlist(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd);
+			     struct comedi_subdevice *s,
+			     struct 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);
+			     struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd,
+			     unsigned int *init_ticks,
+			     unsigned int *scan_ticks,
+			     unsigned int *chan_ticks);
 
 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);
+		      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(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd);
+			     struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd);
 
 static irqreturn_t me4000_ai_isr(int irq, void *dev_id);
 
 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd);
+				 struct comedi_subdevice *s,
+				 struct comedi_cmd *cmd);
 
-static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int me4000_ai_do_cmd(struct comedi_device *dev,
+			    struct comedi_subdevice *s);
 
 static int me4000_ao_insn_write(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data);
 
 static int me4000_ao_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data);
 
 /*-----------------------------------------------------------------------------
   Meilhaus inline functions
   ---------------------------------------------------------------------------*/
 
 static inline void me4000_outb(struct comedi_device *dev, unsigned char value,
-	unsigned long port)
+			       unsigned long port)
 {
 	PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
 	outb(value, port);
 }
 
 static inline void me4000_outl(struct comedi_device *dev, unsigned long value,
-	unsigned long port)
+			       unsigned long port)
 {
 	PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
 	outl(value, port);
 }
 
-static inline unsigned long me4000_inl(struct 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);
@@ -223,7 +237,8 @@ static inline unsigned long me4000_inl(struct comedi_device *dev, unsigned long
 	return value;
 }
 
-static inline unsigned char me4000_inb(struct 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);
@@ -234,18 +249,18 @@ static inline unsigned char me4000_inb(struct comedi_device *dev, unsigned long
 static const struct comedi_lrange me4000_ai_range = {
 	4,
 	{
-			UNI_RANGE(2.5),
-			UNI_RANGE(10),
-			BIP_RANGE(2.5),
-			BIP_RANGE(10),
-		}
+	 UNI_RANGE(2.5),
+	 UNI_RANGE(10),
+	 BIP_RANGE(2.5),
+	 BIP_RANGE(10),
+	 }
 };
 
 static const struct comedi_lrange me4000_ao_range = {
 	1,
 	{
-			BIP_RANGE(10),
-		}
+	 BIP_RANGE(10),
+	 }
 };
 
 static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -276,7 +291,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (thisboard->ai.count) {
 		s->type = COMEDI_SUBD_AI;
 		s->subdev_flags =
-			SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
+		    SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
 		s->n_chan = thisboard->ai.count;
 		s->maxdata = 0xFFFF;	/*  16 bit ADC */
 		s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
@@ -286,7 +301,9 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		if (info->irq > 0) {
 			if (request_irq(info->irq, me4000_ai_isr,
 					IRQF_SHARED, "ME-4000", dev)) {
-				printk("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n", dev->minor);
+				printk
+				    ("comedi%d: me4000: me4000_attach(): Unable to allocate irq\n",
+				     dev->minor);
 			} else {
 				dev->read_subdev = s;
 				s->subdev_flags |= SDF_CMD_READ;
@@ -296,8 +313,8 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			}
 		} else {
 			printk(KERN_WARNING
-				"comedi%d: me4000: me4000_attach(): No interrupt available\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_attach(): No interrupt available\n",
+			       dev->minor);
 		}
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
@@ -346,7 +363,7 @@ static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (!me4000_inl(dev, info->dio_context.dir_reg)) {
 		s->io_bits |= 0xFF;
 		me4000_outl(dev, ME4000_DIO_CTRL_BIT_MODE_0,
-			info->dio_context.dir_reg);
+			    info->dio_context.dir_reg);
 	}
 
     /*=========================================================================
@@ -386,28 +403,28 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	 * 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)) {
+	     pci_device != NULL;
+	     pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
 		if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
 			for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
 				if (me4000_boards[i].device_id ==
-					pci_device->device) {
+				    pci_device->device) {
 					/* Was a particular bus/slot requested? */
 					if ((it->options[0] != 0)
-						|| (it->options[1] != 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]) {
+						    it->options[0]
+						    ||
+						    PCI_SLOT(pci_device->devfn)
+						    != it->options[1]) {
 							continue;
 						}
 					}
 					dev->board_ptr = me4000_boards + i;
-					board = (struct me4000_board *) dev->
-						board_ptr;
+					board =
+					    (struct me4000_board *)
+					    dev->board_ptr;
 					info->pci_dev_p = pci_device;
 					goto found;
 				}
@@ -416,16 +433,16 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	printk(KERN_ERR
-		"comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
-		dev->minor, it->options[0], it->options[1]);
+	       "comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n",
+	       dev->minor, it->options[0], it->options[1]);
 	return -ENODEV;
 
-      found:
+found:
 
 	printk(KERN_INFO
-		"comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
-		dev->minor, me4000_boards[i].name, pci_device->bus->number,
-		PCI_SLOT(pci_device->devfn));
+	       "comedi%d: me4000: me4000_probe(): Found %s at PCI bus %d, slot %d\n",
+	       dev->minor, me4000_boards[i].name, pci_device->bus->number,
+	       PCI_SLOT(pci_device->devfn));
 
 	/* Set data in device structure */
 	dev->board_name = board->name;
@@ -434,8 +451,8 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = comedi_pci_enable(pci_device, dev->board_name);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Cannot enable PCI device and request I/O regions\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Cannot enable PCI device and request I/O regions\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -443,16 +460,16 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = get_registers(dev, pci_device);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Cannot get registers\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Cannot get registers\n",
+		       dev->minor);
 		return result;
 	}
 	/* Initialize board info */
 	result = init_board_info(dev, pci_device);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Cannot init baord info\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Cannot init baord info\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -460,8 +477,8 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = init_ao_context(dev);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Cannot init ao context\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Cannot init ao context\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -469,8 +486,8 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = init_ai_context(dev);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Cannot init ai context\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Cannot init ai context\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -478,8 +495,8 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = init_dio_context(dev);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Cannot init dio context\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Cannot init dio context\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -487,8 +504,8 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = init_cnt_context(dev);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Cannot init cnt context\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Cannot init cnt context\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -496,8 +513,8 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = xilinx_download(dev);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Can't download firmware\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Can't download firmware\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -505,8 +522,8 @@ static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
 	result = reset_board(dev);
 	if (result) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_probe(): Can't reset board\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_probe(): Can't reset board\n",
+		       dev->minor);
 		return result;
 	}
 
@@ -523,8 +540,8 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
 	info->plx_regbase = pci_resource_start(pci_dev_p, 1);
 	if (info->plx_regbase == 0) {
 		printk(KERN_ERR
-			"comedi%d: me4000: get_registers(): PCI base address 1 is not available\n",
-			dev->minor);
+		       "comedi%d: me4000: get_registers(): PCI base address 1 is not available\n",
+		       dev->minor);
 		return -ENODEV;
 	}
 	info->plx_regbase_size = pci_resource_len(pci_dev_p, 1);
@@ -534,8 +551,8 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
 	info->me4000_regbase = pci_resource_start(pci_dev_p, 2);
 	if (info->me4000_regbase == 0) {
 		printk(KERN_ERR
-			"comedi%d: me4000: get_registers(): PCI base address 2 is not available\n",
-			dev->minor);
+		       "comedi%d: me4000: get_registers(): PCI base address 2 is not available\n",
+		       dev->minor);
 		return -ENODEV;
 	}
 	info->me4000_regbase_size = pci_resource_len(pci_dev_p, 2);
@@ -545,8 +562,8 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
 	info->timer_regbase = pci_resource_start(pci_dev_p, 3);
 	if (info->timer_regbase == 0) {
 		printk(KERN_ERR
-			"comedi%d: me4000: get_registers(): PCI base address 3 is not available\n",
-			dev->minor);
+		       "comedi%d: me4000: get_registers(): PCI base address 3 is not available\n",
+		       dev->minor);
 		return -ENODEV;
 	}
 	info->timer_regbase_size = pci_resource_len(pci_dev_p, 3);
@@ -556,8 +573,8 @@ static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
 	info->program_regbase = pci_resource_start(pci_dev_p, 5);
 	if (info->program_regbase == 0) {
 		printk(KERN_ERR
-			"comedi%d: me4000: get_registers(): PCI base address 5 is not available\n",
-			dev->minor);
+		       "comedi%d: me4000: get_registers(): PCI base address 5 is not available\n",
+		       dev->minor);
 		return -ENODEV;
 	}
 	info->program_regbase_size = pci_resource_len(pci_dev_p, 5);
@@ -610,67 +627,67 @@ static int init_ao_context(struct comedi_device *dev)
 		switch (i) {
 		case 0:
 			info->ao_context[i].ctrl_reg =
-				info->me4000_regbase + ME4000_AO_00_CTRL_REG;
+			    info->me4000_regbase + ME4000_AO_00_CTRL_REG;
 			info->ao_context[i].status_reg =
-				info->me4000_regbase + ME4000_AO_00_STATUS_REG;
+			    info->me4000_regbase + ME4000_AO_00_STATUS_REG;
 			info->ao_context[i].fifo_reg =
-				info->me4000_regbase + ME4000_AO_00_FIFO_REG;
+			    info->me4000_regbase + ME4000_AO_00_FIFO_REG;
 			info->ao_context[i].single_reg =
-				info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
+			    info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
 			info->ao_context[i].timer_reg =
-				info->me4000_regbase + ME4000_AO_00_TIMER_REG;
+			    info->me4000_regbase + ME4000_AO_00_TIMER_REG;
 			info->ao_context[i].irq_status_reg =
-				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
 			info->ao_context[i].preload_reg =
-				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
 			break;
 		case 1:
 			info->ao_context[i].ctrl_reg =
-				info->me4000_regbase + ME4000_AO_01_CTRL_REG;
+			    info->me4000_regbase + ME4000_AO_01_CTRL_REG;
 			info->ao_context[i].status_reg =
-				info->me4000_regbase + ME4000_AO_01_STATUS_REG;
+			    info->me4000_regbase + ME4000_AO_01_STATUS_REG;
 			info->ao_context[i].fifo_reg =
-				info->me4000_regbase + ME4000_AO_01_FIFO_REG;
+			    info->me4000_regbase + ME4000_AO_01_FIFO_REG;
 			info->ao_context[i].single_reg =
-				info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
+			    info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
 			info->ao_context[i].timer_reg =
-				info->me4000_regbase + ME4000_AO_01_TIMER_REG;
+			    info->me4000_regbase + ME4000_AO_01_TIMER_REG;
 			info->ao_context[i].irq_status_reg =
-				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
 			info->ao_context[i].preload_reg =
-				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
 			break;
 		case 2:
 			info->ao_context[i].ctrl_reg =
-				info->me4000_regbase + ME4000_AO_02_CTRL_REG;
+			    info->me4000_regbase + ME4000_AO_02_CTRL_REG;
 			info->ao_context[i].status_reg =
-				info->me4000_regbase + ME4000_AO_02_STATUS_REG;
+			    info->me4000_regbase + ME4000_AO_02_STATUS_REG;
 			info->ao_context[i].fifo_reg =
-				info->me4000_regbase + ME4000_AO_02_FIFO_REG;
+			    info->me4000_regbase + ME4000_AO_02_FIFO_REG;
 			info->ao_context[i].single_reg =
-				info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
+			    info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
 			info->ao_context[i].timer_reg =
-				info->me4000_regbase + ME4000_AO_02_TIMER_REG;
+			    info->me4000_regbase + ME4000_AO_02_TIMER_REG;
 			info->ao_context[i].irq_status_reg =
-				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
 			info->ao_context[i].preload_reg =
-				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
 			break;
 		case 3:
 			info->ao_context[i].ctrl_reg =
-				info->me4000_regbase + ME4000_AO_03_CTRL_REG;
+			    info->me4000_regbase + ME4000_AO_03_CTRL_REG;
 			info->ao_context[i].status_reg =
-				info->me4000_regbase + ME4000_AO_03_STATUS_REG;
+			    info->me4000_regbase + ME4000_AO_03_STATUS_REG;
 			info->ao_context[i].fifo_reg =
-				info->me4000_regbase + ME4000_AO_03_FIFO_REG;
+			    info->me4000_regbase + ME4000_AO_03_FIFO_REG;
 			info->ao_context[i].single_reg =
-				info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
+			    info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
 			info->ao_context[i].timer_reg =
-				info->me4000_regbase + ME4000_AO_03_TIMER_REG;
+			    info->me4000_regbase + ME4000_AO_03_TIMER_REG;
 			info->ao_context[i].irq_status_reg =
-				info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
 			info->ao_context[i].preload_reg =
-				info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
 			break;
 		default:
 			break;
@@ -689,27 +706,27 @@ static int init_ai_context(struct comedi_device *dev)
 
 	info->ai_context.ctrl_reg = info->me4000_regbase + ME4000_AI_CTRL_REG;
 	info->ai_context.status_reg =
-		info->me4000_regbase + ME4000_AI_STATUS_REG;
+	    info->me4000_regbase + ME4000_AI_STATUS_REG;
 	info->ai_context.channel_list_reg =
-		info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
+	    info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
 	info->ai_context.data_reg = info->me4000_regbase + ME4000_AI_DATA_REG;
 	info->ai_context.chan_timer_reg =
-		info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
+	    info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
 	info->ai_context.chan_pre_timer_reg =
-		info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
+	    info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
 	info->ai_context.scan_timer_low_reg =
-		info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
+	    info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
 	info->ai_context.scan_timer_high_reg =
-		info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
+	    info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
 	info->ai_context.scan_pre_timer_low_reg =
-		info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
+	    info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
 	info->ai_context.scan_pre_timer_high_reg =
-		info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
+	    info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
 	info->ai_context.start_reg = info->me4000_regbase + ME4000_AI_START_REG;
 	info->ai_context.irq_status_reg =
-		info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+	    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
 	info->ai_context.sample_counter_reg =
-		info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
+	    info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
 
 	return 0;
 }
@@ -722,13 +739,13 @@ static int init_dio_context(struct comedi_device *dev)
 	info->dio_context.dir_reg = info->me4000_regbase + ME4000_DIO_DIR_REG;
 	info->dio_context.ctrl_reg = info->me4000_regbase + ME4000_DIO_CTRL_REG;
 	info->dio_context.port_0_reg =
-		info->me4000_regbase + ME4000_DIO_PORT_0_REG;
+	    info->me4000_regbase + ME4000_DIO_PORT_0_REG;
 	info->dio_context.port_1_reg =
-		info->me4000_regbase + ME4000_DIO_PORT_1_REG;
+	    info->me4000_regbase + ME4000_DIO_PORT_1_REG;
 	info->dio_context.port_2_reg =
-		info->me4000_regbase + ME4000_DIO_PORT_2_REG;
+	    info->me4000_regbase + ME4000_DIO_PORT_2_REG;
 	info->dio_context.port_3_reg =
-		info->me4000_regbase + ME4000_DIO_PORT_3_REG;
+	    info->me4000_regbase + ME4000_DIO_PORT_3_REG;
 
 	return 0;
 }
@@ -740,11 +757,11 @@ static int init_cnt_context(struct comedi_device *dev)
 
 	info->cnt_context.ctrl_reg = info->timer_regbase + ME4000_CNT_CTRL_REG;
 	info->cnt_context.counter_0_reg =
-		info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
+	    info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
 	info->cnt_context.counter_1_reg =
-		info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
+	    info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
 	info->cnt_context.counter_2_reg =
-		info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
+	    info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
 
 	return 0;
 }
@@ -783,8 +800,8 @@ static int xilinx_download(struct comedi_device *dev)
 	udelay(20);
 	if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
 		printk(KERN_ERR
-			"comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
-			dev->minor);
+		       "comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
+		       dev->minor);
 		return -EIO;
 	}
 
@@ -794,12 +811,12 @@ static int xilinx_download(struct comedi_device *dev)
 	outl(value, info->plx_regbase + PLX_ICR);
 	if (FIRMWARE_NOT_AVAILABLE) {
 		comedi_error(dev,
-			"xilinx firmware unavailable due to licensing, aborting");
+			     "xilinx firmware unavailable due to licensing, aborting");
 		return -EIO;
 	} else {
 		/* Download Xilinx firmware */
 		size = (xilinx_firm[0] << 24) + (xilinx_firm[1] << 16) +
-			(xilinx_firm[2] << 8) + xilinx_firm[3];
+		    (xilinx_firm[2] << 8) + xilinx_firm[3];
 		udelay(10);
 
 		for (idx = 0; idx < size; idx++) {
@@ -809,8 +826,8 @@ static int xilinx_download(struct comedi_device *dev)
 			/* Check if BUSY flag is low */
 			if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
 				printk(KERN_ERR
-					"comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n",
-					dev->minor, idx);
+				       "comedi%d: me4000: xilinx_download(): Xilinx is still busy (idx = %d)\n",
+				       dev->minor, idx);
 				return -EIO;
 			}
 		}
@@ -820,11 +837,11 @@ static int xilinx_download(struct comedi_device *dev)
 	if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
 	} else {
 		printk(KERN_ERR
-			"comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
-			dev->minor);
+		       "comedi%d: me4000: xilinx_download(): DONE flag is not set\n",
+		       dev->minor);
 		printk(KERN_ERR
-			"comedi%d: me4000: xilinx_download(): Download not succesful\n",
-			dev->minor);
+		       "comedi%d: me4000: xilinx_download(): Download not succesful\n",
+		       dev->minor);
 		return -EIO;
 	}
 
@@ -851,44 +868,44 @@ static int reset_board(struct comedi_device *dev)
 
 	/* 0x8000 to the DACs means an output voltage of 0V */
 	me4000_outl(dev, 0x8000,
-		info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
+		    info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
 	me4000_outl(dev, 0x8000,
-		info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
+		    info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
 	me4000_outl(dev, 0x8000,
-		info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
+		    info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
 	me4000_outl(dev, 0x8000,
-		info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
+		    info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
 
 	/* Set both stop bits in the analog input control register */
 	me4000_outl(dev,
-		ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
-		info->me4000_regbase + ME4000_AI_CTRL_REG);
+		    ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
+		    info->me4000_regbase + ME4000_AI_CTRL_REG);
 
 	/* Set both stop bits in the analog output control register */
 	me4000_outl(dev,
-		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		info->me4000_regbase + ME4000_AO_00_CTRL_REG);
+		    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+		    info->me4000_regbase + ME4000_AO_00_CTRL_REG);
 	me4000_outl(dev,
-		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		info->me4000_regbase + ME4000_AO_01_CTRL_REG);
+		    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+		    info->me4000_regbase + ME4000_AO_01_CTRL_REG);
 	me4000_outl(dev,
-		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		info->me4000_regbase + ME4000_AO_02_CTRL_REG);
+		    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+		    info->me4000_regbase + ME4000_AO_02_CTRL_REG);
 	me4000_outl(dev,
-		ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		info->me4000_regbase + ME4000_AO_03_CTRL_REG);
+		    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+		    info->me4000_regbase + ME4000_AO_03_CTRL_REG);
 
 	/* Enable interrupts on the PLX */
 	me4000_outl(dev, 0x43, info->plx_regbase + PLX_INTCSR);
 
 	/* Set the adustment register for AO demux */
 	me4000_outl(dev, ME4000_AO_DEMUX_ADJUST_VALUE,
-		info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
+		    info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
 
 	/* Set digital I/O direction for port 0 to output on isolated versions */
 	if (!(me4000_inl(dev, info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
 		me4000_outl(dev, 0x1,
-			info->me4000_regbase + ME4000_DIO_CTRL_REG);
+			    info->me4000_regbase + ME4000_DIO_CTRL_REG);
 	}
 
 	return 0;
@@ -915,7 +932,8 @@ static int me4000_detach(struct comedi_device *dev)
   ===========================================================================*/
 
 static int me4000_ai_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
+			       struct comedi_subdevice *subdevice,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 
 	int chan = CR_CHAN(insn->chanspec);
@@ -932,8 +950,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 		return 0;
 	} else if (insn->n > 1) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
-			dev->minor, insn->n);
+		       "comedi%d: me4000: me4000_ai_insn_read(): Invalid instruction length %d\n",
+		       dev->minor, insn->n);
 		return -EINVAL;
 	}
 
@@ -952,8 +970,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_insn_read(): Invalid range specified\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
@@ -962,8 +980,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 	case AREF_COMMON:
 		if (chan >= thisboard->ai.count) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
+			       dev->minor);
 			return -EINVAL;
 		}
 		entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED | chan;
@@ -972,23 +990,23 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 	case AREF_DIFF:
 		if (rang == 0 || rang == 1) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_insn_read(): Range must be bipolar when aref = diff\n",
+			       dev->minor);
 			return -EINVAL;
 		}
 
 		if (chan >= thisboard->ai.diff_count) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_insn_read(): Analog input is not available\n",
+			       dev->minor);
 			return -EINVAL;
 		}
 		entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL | chan;
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_insn_read(): Invalid aref specified\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
@@ -997,13 +1015,13 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 	/* Clear channel list, data fifo and both stop bits */
 	tmp = me4000_inl(dev, info->ai_context.ctrl_reg);
 	tmp &= ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
-		ME4000_AI_CTRL_BIT_DATA_FIFO |
-		ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
+		 ME4000_AI_CTRL_BIT_DATA_FIFO |
+		 ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
 	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
 
 	/* Set the acquisition mode to single */
 	tmp &= ~(ME4000_AI_CTRL_BIT_MODE_0 | ME4000_AI_CTRL_BIT_MODE_1 |
-		ME4000_AI_CTRL_BIT_MODE_2);
+		 ME4000_AI_CTRL_BIT_MODE_2);
 	me4000_outl(dev, tmp, info->ai_context.ctrl_reg);
 
 	/* Enable channel list and data fifo */
@@ -1016,18 +1034,19 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 	/* Set the timer to maximum sample rate */
 	me4000_outl(dev, ME4000_AI_MIN_TICKS, info->ai_context.chan_timer_reg);
 	me4000_outl(dev, ME4000_AI_MIN_TICKS,
-		info->ai_context.chan_pre_timer_reg);
+		    info->ai_context.chan_pre_timer_reg);
 
 	/* Start conversion by dummy read */
 	me4000_inl(dev, info->ai_context.start_reg);
 
 	/* Wait until ready */
 	udelay(10);
-	if (!(me4000_inl(dev, info->ai_context.
-				status_reg) & ME4000_AI_STATUS_BIT_EF_DATA)) {
+	if (!
+	    (me4000_inl(dev, info->ai_context.status_reg) &
+	     ME4000_AI_STATUS_BIT_EF_DATA)) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_insn_read(): Value not available after wait\n",
+		       dev->minor);
 		return -EIO;
 	}
 
@@ -1038,7 +1057,8 @@ static int me4000_ai_insn_read(struct comedi_device *dev,
 	return 1;
 }
 
-static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int me4000_ai_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	unsigned long tmp;
 
@@ -1056,7 +1076,7 @@ static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *
 }
 
 static int ai_check_chanlist(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd)
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int aref;
 	int i;
@@ -1066,24 +1086,24 @@ static int ai_check_chanlist(struct comedi_device *dev,
 	/* Check whether a channel list is available */
 	if (!cmd->chanlist_len) {
 		printk(KERN_ERR
-			"comedi%d: me4000: ai_check_chanlist(): No channel list available\n",
-			dev->minor);
+		       "comedi%d: me4000: ai_check_chanlist(): No channel list available\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
 	/* Check the channel list size */
 	if (cmd->chanlist_len > ME4000_AI_CHANNEL_LIST_COUNT) {
 		printk(KERN_ERR
-			"comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n",
-			dev->minor);
+		       "comedi%d: me4000: ai_check_chanlist(): Channel list is to large\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
 	/* Check the pointer */
 	if (!cmd->chanlist) {
 		printk(KERN_ERR
-			"comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n",
-			dev->minor);
+		       "comedi%d: me4000: ai_check_chanlist(): NULL pointer to channel list\n",
+		       dev->minor);
 		return -EFAULT;
 	}
 
@@ -1092,8 +1112,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
 	for (i = 0; i < cmd->chanlist_len; i++) {
 		if (CR_AREF(cmd->chanlist[i]) != aref) {
 			printk(KERN_ERR
-				"comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n",
-				dev->minor);
+			       "comedi%d: me4000: ai_check_chanlist(): Mode is not equal for all entries\n",
+			       dev->minor);
 			return -EINVAL;
 		}
 	}
@@ -1102,10 +1122,10 @@ static int ai_check_chanlist(struct comedi_device *dev,
 	if (aref == SDF_DIFF) {
 		for (i = 0; i < cmd->chanlist_len; i++) {
 			if (CR_CHAN(cmd->chanlist[i]) >=
-				thisboard->ai.diff_count) {
+			    thisboard->ai.diff_count) {
 				printk(KERN_ERR
-					"comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
-					dev->minor);
+				       "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
+				       dev->minor);
 				return -EINVAL;
 			}
 		}
@@ -1113,8 +1133,8 @@ static int ai_check_chanlist(struct comedi_device *dev,
 		for (i = 0; i < cmd->chanlist_len; i++) {
 			if (CR_CHAN(cmd->chanlist[i]) >= thisboard->ai.count) {
 				printk(KERN_ERR
-					"comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
-					dev->minor);
+				       "comedi%d: me4000: ai_check_chanlist(): Channel number to high\n",
+				       dev->minor);
 				return -EINVAL;
 			}
 		}
@@ -1124,10 +1144,10 @@ static int ai_check_chanlist(struct comedi_device *dev,
 	if (aref == SDF_DIFF) {
 		for (i = 0; i < cmd->chanlist_len; i++) {
 			if (CR_RANGE(cmd->chanlist[i]) != 1 &&
-				CR_RANGE(cmd->chanlist[i]) != 2) {
+			    CR_RANGE(cmd->chanlist[i]) != 2) {
 				printk(KERN_ERR
-					"comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
-					dev->minor);
+				       "comedi%d: me4000: ai_check_chanlist(): Bipolar is not selected in differential mode\n",
+				       dev->minor);
 				return -EINVAL;
 			}
 		}
@@ -1137,10 +1157,10 @@ static int ai_check_chanlist(struct comedi_device *dev,
 }
 
 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)
+			     struct comedi_subdevice *s,
+			     struct comedi_cmd *cmd,
+			     unsigned int *init_ticks,
+			     unsigned int *scan_ticks, unsigned int *chan_ticks)
 {
 
 	int rest;
@@ -1153,7 +1173,7 @@ static int ai_round_cmd_args(struct comedi_device *dev,
 
 	PDEBUG("ai_round_cmd_arg(): start_arg = %d\n", cmd->start_arg);
 	PDEBUG("ai_round_cmd_arg(): scan_begin_arg = %d\n",
-		cmd->scan_begin_arg);
+	       cmd->scan_begin_arg);
 	PDEBUG("ai_round_cmd_arg(): convert_arg = %d\n", cmd->convert_arg);
 
 	if (cmd->start_arg) {
@@ -1203,19 +1223,19 @@ static int ai_round_cmd_args(struct comedi_device *dev,
 }
 
 static void ai_write_timer(struct comedi_device *dev,
-	unsigned int init_ticks,
-	unsigned int scan_ticks, unsigned int chan_ticks)
+			   unsigned int init_ticks,
+			   unsigned int scan_ticks, unsigned int chan_ticks)
 {
 
 	CALL_PDEBUG("In ai_write_timer()\n");
 
 	me4000_outl(dev, init_ticks - 1,
-		info->ai_context.scan_pre_timer_low_reg);
+		    info->ai_context.scan_pre_timer_low_reg);
 	me4000_outl(dev, 0x0, info->ai_context.scan_pre_timer_high_reg);
 
 	if (scan_ticks) {
 		me4000_outl(dev, scan_ticks - 1,
-			info->ai_context.scan_timer_low_reg);
+			    info->ai_context.scan_timer_low_reg);
 		me4000_outl(dev, 0x0, info->ai_context.scan_timer_high_reg);
 	}
 
@@ -1224,10 +1244,10 @@ static void ai_write_timer(struct comedi_device *dev,
 }
 
 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)
+		      struct comedi_subdevice *s,
+		      struct comedi_cmd *cmd,
+		      unsigned int init_ticks,
+		      unsigned int scan_ticks, unsigned int chan_ticks)
 {
 
 	unsigned long tmp = 0;
@@ -1242,42 +1262,42 @@ static int ai_prepare(struct comedi_device *dev,
 
 	/* Start sources */
 	if ((cmd->start_src == TRIG_EXT &&
-			cmd->scan_begin_src == TRIG_TIMER &&
-			cmd->convert_src == TRIG_TIMER) ||
-		(cmd->start_src == TRIG_EXT &&
-			cmd->scan_begin_src == TRIG_FOLLOW &&
-			cmd->convert_src == TRIG_TIMER)) {
+	     cmd->scan_begin_src == TRIG_TIMER &&
+	     cmd->convert_src == TRIG_TIMER) ||
+	    (cmd->start_src == TRIG_EXT &&
+	     cmd->scan_begin_src == TRIG_FOLLOW &&
+	     cmd->convert_src == TRIG_TIMER)) {
 		tmp = ME4000_AI_CTRL_BIT_MODE_1 |
-			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
-			ME4000_AI_CTRL_BIT_DATA_FIFO;
+		    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
+		    ME4000_AI_CTRL_BIT_DATA_FIFO;
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_EXT &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_EXT &&
+		   cmd->convert_src == TRIG_TIMER) {
 		tmp = ME4000_AI_CTRL_BIT_MODE_2 |
-			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
-			ME4000_AI_CTRL_BIT_DATA_FIFO;
+		    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
+		    ME4000_AI_CTRL_BIT_DATA_FIFO;
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_EXT &&
-		cmd->convert_src == TRIG_EXT) {
+		   cmd->scan_begin_src == TRIG_EXT &&
+		   cmd->convert_src == TRIG_EXT) {
 		tmp = ME4000_AI_CTRL_BIT_MODE_0 |
-			ME4000_AI_CTRL_BIT_MODE_1 |
-			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
-			ME4000_AI_CTRL_BIT_DATA_FIFO;
+		    ME4000_AI_CTRL_BIT_MODE_1 |
+		    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
+		    ME4000_AI_CTRL_BIT_DATA_FIFO;
 	} else {
 		tmp = ME4000_AI_CTRL_BIT_MODE_0 |
-			ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
-			ME4000_AI_CTRL_BIT_DATA_FIFO;
+		    ME4000_AI_CTRL_BIT_CHANNEL_FIFO |
+		    ME4000_AI_CTRL_BIT_DATA_FIFO;
 	}
 
 	/* Stop triggers */
 	if (cmd->stop_src == TRIG_COUNT) {
 		me4000_outl(dev, cmd->chanlist_len * cmd->stop_arg,
-			info->ai_context.sample_counter_reg);
+			    info->ai_context.sample_counter_reg);
 		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
 	} else if (cmd->stop_src == TRIG_NONE &&
-		cmd->scan_end_src == TRIG_COUNT) {
+		   cmd->scan_end_src == TRIG_COUNT) {
 		me4000_outl(dev, cmd->scan_end_arg,
-			info->ai_context.sample_counter_reg);
+			    info->ai_context.sample_counter_reg);
 		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ;
 	} else {
 		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
@@ -1293,7 +1313,7 @@ static int ai_prepare(struct comedi_device *dev,
 }
 
 static int ai_write_chanlist(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd)
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	unsigned int entry;
 	unsigned int chan;
@@ -1332,7 +1352,8 @@ static int ai_write_chanlist(struct comedi_device *dev,
 	return 0;
 }
 
-static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int me4000_ai_do_cmd(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	int err;
 	unsigned int init_ticks = 0;
@@ -1349,7 +1370,7 @@ static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
 
 	/* Round the timer arguments */
 	err = ai_round_cmd_args(dev,
-		s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
+				s, cmd, &init_ticks, &scan_ticks, &chan_ticks);
 	if (err)
 		return err;
 
@@ -1377,7 +1398,8 @@ static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
  * So I tried to adopt this scheme.
  */
 static int me4000_ai_do_cmd_test(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd)
+				 struct comedi_subdevice *s,
+				 struct comedi_cmd *cmd)
 {
 
 	unsigned int init_ticks;
@@ -1390,28 +1412,28 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 	PDEBUG("me4000_ai_do_cmd_test(): subdev         = %d\n", cmd->subdev);
 	PDEBUG("me4000_ai_do_cmd_test(): flags          = %08X\n", cmd->flags);
 	PDEBUG("me4000_ai_do_cmd_test(): start_src      = %08X\n",
-		cmd->start_src);
+	       cmd->start_src);
 	PDEBUG("me4000_ai_do_cmd_test(): start_arg      = %d\n",
-		cmd->start_arg);
+	       cmd->start_arg);
 	PDEBUG("me4000_ai_do_cmd_test(): scan_begin_src = %08X\n",
-		cmd->scan_begin_src);
+	       cmd->scan_begin_src);
 	PDEBUG("me4000_ai_do_cmd_test(): scan_begin_arg = %d\n",
-		cmd->scan_begin_arg);
+	       cmd->scan_begin_arg);
 	PDEBUG("me4000_ai_do_cmd_test(): convert_src    = %08X\n",
-		cmd->convert_src);
+	       cmd->convert_src);
 	PDEBUG("me4000_ai_do_cmd_test(): convert_arg    = %d\n",
-		cmd->convert_arg);
+	       cmd->convert_arg);
 	PDEBUG("me4000_ai_do_cmd_test(): scan_end_src   = %08X\n",
-		cmd->scan_end_src);
+	       cmd->scan_end_src);
 	PDEBUG("me4000_ai_do_cmd_test(): scan_end_arg   = %d\n",
-		cmd->scan_end_arg);
+	       cmd->scan_end_arg);
 	PDEBUG("me4000_ai_do_cmd_test(): stop_src       = %08X\n",
-		cmd->stop_src);
+	       cmd->stop_src);
 	PDEBUG("me4000_ai_do_cmd_test(): stop_arg       = %d\n", cmd->stop_arg);
 	PDEBUG("me4000_ai_do_cmd_test(): chanlist       = %d\n",
-		(unsigned int)cmd->chanlist);
+	       (unsigned int)cmd->chanlist);
 	PDEBUG("me4000_ai_do_cmd_test(): chanlist_len   = %d\n",
-		cmd->chanlist_len);
+	       cmd->chanlist_len);
 
 	/* Only rounding flags are implemented */
 	cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN;
@@ -1432,8 +1454,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start source\n",
+		       dev->minor);
 		cmd->start_src = TRIG_NOW;
 		err++;
 	}
@@ -1448,8 +1470,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan begin source\n",
+		       dev->minor);
 		cmd->scan_begin_src = TRIG_FOLLOW;
 		err++;
 	}
@@ -1463,8 +1485,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert source\n",
+		       dev->minor);
 		cmd->convert_src = TRIG_TIMER;
 		err++;
 	}
@@ -1478,8 +1500,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end source\n",
+		       dev->minor);
 		cmd->scan_end_src = TRIG_NONE;
 		err++;
 	}
@@ -1493,8 +1515,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop source\n",
+		       dev->minor);
 		cmd->stop_src = TRIG_NONE;
 		err++;
 	}
@@ -1505,27 +1527,27 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 	 * Stage 2. Check for trigger source conflicts.
 	 */
 	if (cmd->start_src == TRIG_NOW &&
-		cmd->scan_begin_src == TRIG_TIMER &&
-		cmd->convert_src == TRIG_TIMER) {
+	    cmd->scan_begin_src == TRIG_TIMER &&
+	    cmd->convert_src == TRIG_TIMER) {
 	} else if (cmd->start_src == TRIG_NOW &&
-		cmd->scan_begin_src == TRIG_FOLLOW &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_FOLLOW &&
+		   cmd->convert_src == TRIG_TIMER) {
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_TIMER &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_TIMER &&
+		   cmd->convert_src == TRIG_TIMER) {
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_FOLLOW &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_FOLLOW &&
+		   cmd->convert_src == TRIG_TIMER) {
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_EXT &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_EXT &&
+		   cmd->convert_src == TRIG_TIMER) {
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_EXT &&
-		cmd->convert_src == TRIG_EXT) {
+		   cmd->scan_begin_src == TRIG_EXT &&
+		   cmd->convert_src == TRIG_EXT) {
 	} else {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start trigger combination\n",
+		       dev->minor);
 		cmd->start_src = TRIG_NOW;
 		cmd->scan_begin_src = TRIG_FOLLOW;
 		cmd->convert_src = TRIG_TIMER;
@@ -1534,15 +1556,15 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 
 	if (cmd->stop_src == TRIG_NONE && cmd->scan_end_src == TRIG_NONE) {
 	} else if (cmd->stop_src == TRIG_COUNT &&
-		cmd->scan_end_src == TRIG_NONE) {
+		   cmd->scan_end_src == TRIG_NONE) {
 	} else if (cmd->stop_src == TRIG_NONE &&
-		cmd->scan_end_src == TRIG_COUNT) {
+		   cmd->scan_end_src == TRIG_COUNT) {
 	} else if (cmd->stop_src == TRIG_COUNT &&
-		cmd->scan_end_src == TRIG_COUNT) {
+		   cmd->scan_end_src == TRIG_COUNT) {
 	} else {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop trigger combination\n",
+		       dev->minor);
 		cmd->stop_src = TRIG_NONE;
 		cmd->scan_end_src = TRIG_NONE;
 		err++;
@@ -1555,29 +1577,29 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 	 */
 	if (cmd->chanlist_len < 1) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): No channel list\n",
+		       dev->minor);
 		cmd->chanlist_len = 1;
 		err++;
 	}
 	if (init_ticks < 66) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Start arg to low\n",
+		       dev->minor);
 		cmd->start_arg = 2000;
 		err++;
 	}
 	if (scan_ticks && scan_ticks < 67) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Scan begin arg to low\n",
+		       dev->minor);
 		cmd->scan_begin_arg = 2031;
 		err++;
 	}
 	if (chan_ticks < 66) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_ai_do_cmd_test(): Convert arg to low\n",
+		       dev->minor);
 		cmd->convert_arg = 2000;
 		err++;
 	}
@@ -1589,123 +1611,123 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 	 * Stage 4. Check for argument conflicts.
 	 */
 	if (cmd->start_src == TRIG_NOW &&
-		cmd->scan_begin_src == TRIG_TIMER &&
-		cmd->convert_src == TRIG_TIMER) {
+	    cmd->scan_begin_src == TRIG_TIMER &&
+	    cmd->convert_src == TRIG_TIMER) {
 
 		/* Check timer arguments */
 		if (init_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
+			       dev->minor);
 			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);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
+			       dev->minor);
 			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);
+			       "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 */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_NOW &&
-		cmd->scan_begin_src == TRIG_FOLLOW &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_FOLLOW &&
+		   cmd->convert_src == TRIG_TIMER) {
 
 		/* Check timer arguments */
 		if (init_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
+			       dev->minor);
 			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);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
+			       dev->minor);
 			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_TIMER &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_TIMER &&
+		   cmd->convert_src == TRIG_TIMER) {
 
 		/* Check timer arguments */
 		if (init_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
+			       dev->minor);
 			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);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
+			       dev->minor);
 			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);
+			       "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 */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_FOLLOW &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_FOLLOW &&
+		   cmd->convert_src == TRIG_TIMER) {
 
 		/* Check timer arguments */
 		if (init_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
+			       dev->minor);
 			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);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
+			       dev->minor);
 			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_EXT &&
-		cmd->convert_src == TRIG_TIMER) {
+		   cmd->scan_begin_src == TRIG_EXT &&
+		   cmd->convert_src == TRIG_TIMER) {
 
 		/* Check timer arguments */
 		if (init_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
+			       dev->minor);
 			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);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
+			       dev->minor);
 			cmd->convert_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
 	} else if (cmd->start_src == TRIG_EXT &&
-		cmd->scan_begin_src == TRIG_EXT &&
-		cmd->convert_src == TRIG_EXT) {
+		   cmd->scan_begin_src == TRIG_EXT &&
+		   cmd->convert_src == TRIG_EXT) {
 
 		/* Check timer arguments */
 		if (init_ticks < ME4000_AI_MIN_TICKS) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
+			       dev->minor);
 			cmd->start_arg = 2000;	/*  66 ticks at least */
 			err++;
 		}
@@ -1713,8 +1735,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 	if (cmd->stop_src == TRIG_COUNT) {
 		if (cmd->stop_arg == 0) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid stop arg\n",
+			       dev->minor);
 			cmd->stop_arg = 1;
 			err++;
 		}
@@ -1722,8 +1744,8 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev,
 	if (cmd->scan_end_src == TRIG_COUNT) {
 		if (cmd->scan_end_arg == 0) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
+			       dev->minor);
 			cmd->scan_end_arg = 1;
 			err++;
 		}
@@ -1764,40 +1786,40 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 	/* Check if irq number is right */
 	if (irq != ai_context->irq) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n",
-			dev->minor, irq);
+		       "comedi%d: me4000: me4000_ai_isr(): Incorrect interrupt num: %d\n",
+		       dev->minor, irq);
 		return IRQ_HANDLED;
 	}
 
 	if (me4000_inl(dev,
-			ai_context->
-			irq_status_reg) & ME4000_IRQ_STATUS_BIT_AI_HF) {
+		       ai_context->irq_status_reg) &
+	    ME4000_IRQ_STATUS_BIT_AI_HF) {
 		ISR_PDEBUG
-			("me4000_ai_isr(): Fifo half full interrupt occured\n");
+		    ("me4000_ai_isr(): Fifo half full interrupt occured\n");
 
 		/* Read status register to find out what happened */
 		tmp = me4000_inl(dev, ai_context->ctrl_reg);
 
 		if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-			!(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
-			(tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
+		    !(tmp & ME4000_AI_STATUS_BIT_HF_DATA) &&
+		    (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
 			ISR_PDEBUG("me4000_ai_isr(): Fifo full\n");
 			c = ME4000_AI_FIFO_COUNT;
 
 			/* FIFO overflow, so stop conversion and disable all interrupts */
 			tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
 			tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
-				ME4000_AI_CTRL_BIT_SC_IRQ);
+				 ME4000_AI_CTRL_BIT_SC_IRQ);
 			me4000_outl(dev, tmp, ai_context->ctrl_reg);
 
 			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_isr(): FIFO overflow\n",
+			       dev->minor);
 		} else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
-			&& !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-			&& (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
+			   && !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
+			   && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
 			ISR_PDEBUG("me4000_ai_isr(): Fifo half full\n");
 
 			s->async->events |= COMEDI_CB_BLOCK;
@@ -1805,21 +1827,21 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 			c = ME4000_AI_FIFO_COUNT / 2;
 		} else {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_isr(): Can't determine state of fifo\n",
+			       dev->minor);
 			c = 0;
 
 			/* Undefined state, so stop conversion and disable all interrupts */
 			tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
 			tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
-				ME4000_AI_CTRL_BIT_SC_IRQ);
+				 ME4000_AI_CTRL_BIT_SC_IRQ);
 			me4000_outl(dev, tmp, ai_context->ctrl_reg);
 
 			s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n",
-				dev->minor);
+			       "comedi%d: me4000: me4000_ai_isr(): Undefined FIFO state\n",
+			       dev->minor);
 		}
 
 		ISR_PDEBUG("me4000_ai_isr(): Try to read %d values\n", c);
@@ -1833,14 +1855,14 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 				/* Buffer overflow, so stop conversion and disable all interrupts */
 				tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
 				tmp &= ~(ME4000_AI_CTRL_BIT_HF_IRQ |
-					ME4000_AI_CTRL_BIT_SC_IRQ);
+					 ME4000_AI_CTRL_BIT_SC_IRQ);
 				me4000_outl(dev, tmp, ai_context->ctrl_reg);
 
 				s->async->events |= COMEDI_CB_OVERFLOW;
 
 				printk(KERN_ERR
-					"comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
-					dev->minor);
+				       "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
+				       dev->minor);
 
 				break;
 			}
@@ -1855,10 +1877,9 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 	}
 
 	if (me4000_inl(dev,
-			ai_context->
-			irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
+		       ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
 		ISR_PDEBUG
-			("me4000_ai_isr(): Sample counter interrupt occured\n");
+		    ("me4000_ai_isr(): Sample counter interrupt occured\n");
 
 		s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOA;
 
@@ -1876,8 +1897,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 
 			if (!comedi_buf_put(s->async, lval)) {
 				printk(KERN_ERR
-					"comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
-					dev->minor);
+				       "comedi%d: me4000: me4000_ai_isr(): Buffer overflow\n",
+				       dev->minor);
 				s->async->events |= COMEDI_CB_OVERFLOW;
 				break;
 			}
@@ -1885,7 +1906,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
 
 		/* Work is done, so reset the interrupt */
 		ISR_PDEBUG
-			("me4000_ai_isr(): Reset interrupt from sample counter\n");
+		    ("me4000_ai_isr(): Reset interrupt from sample counter\n");
 		tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
 		me4000_outl(dev, tmp, ai_context->ctrl_reg);
 		tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
@@ -1905,7 +1926,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
   ===========================================================================*/
 
 static int me4000_ao_insn_write(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 
 	int chan = CR_CHAN(insn->chanspec);
@@ -1919,29 +1941,29 @@ static int me4000_ao_insn_write(struct comedi_device *dev,
 		return 0;
 	} else if (insn->n > 1) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
-			dev->minor, insn->n);
+		       "comedi%d: me4000: me4000_ao_insn_write(): Invalid instruction length %d\n",
+		       dev->minor, insn->n);
 		return -EINVAL;
 	}
 
 	if (chan >= thisboard->ao.count) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
-			dev->minor, insn->n);
+		       "comedi%d: me4000: me4000_ao_insn_write(): Invalid channel %d\n",
+		       dev->minor, insn->n);
 		return -EINVAL;
 	}
 
 	if (rang != 0) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
-			dev->minor, insn->n);
+		       "comedi%d: me4000: me4000_ao_insn_write(): Invalid range %d\n",
+		       dev->minor, insn->n);
 		return -EINVAL;
 	}
 
 	if (aref != AREF_GROUND && aref != AREF_COMMON) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
-			dev->minor, insn->n);
+		       "comedi%d: me4000: me4000_ao_insn_write(): Invalid aref %d\n",
+		       dev->minor, insn->n);
 		return -EINVAL;
 	}
 
@@ -1963,14 +1985,17 @@ static int me4000_ao_insn_write(struct comedi_device *dev,
 }
 
 static int me4000_ao_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
 	if (insn->n == 0) {
 		return 0;
 	} else if (insn->n > 1) {
-		printk("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n", dev->minor);
+		printk
+		    ("comedi%d: me4000: me4000_ao_insn_read(): Invalid instruction length\n",
+		     dev->minor);
 		return -EINVAL;
 	}
 
@@ -1984,7 +2009,8 @@ static int me4000_ao_insn_read(struct comedi_device *dev,
   ===========================================================================*/
 
 static int me4000_dio_insn_bits(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 
 	CALL_PDEBUG("In me4000_dio_insn_bits()\n");
@@ -1994,7 +2020,9 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
 		return 0;
 
 	if (insn->n != 2) {
-		printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
+		printk
+		    ("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n",
+		     dev->minor);
 		return -EINVAL;
 	}
 
@@ -2014,28 +2042,29 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
 
 		/* Write out the new digital output lines */
 		me4000_outl(dev, (s->state >> 0) & 0xFF,
-			info->dio_context.port_0_reg);
+			    info->dio_context.port_0_reg);
 		me4000_outl(dev, (s->state >> 8) & 0xFF,
-			info->dio_context.port_1_reg);
+			    info->dio_context.port_1_reg);
 		me4000_outl(dev, (s->state >> 16) & 0xFF,
-			info->dio_context.port_2_reg);
+			    info->dio_context.port_2_reg);
 		me4000_outl(dev, (s->state >> 24) & 0xFF,
-			info->dio_context.port_3_reg);
+			    info->dio_context.port_3_reg);
 	}
 
 	/* On return, data[1] contains the value of
 	   the digital input and output lines. */
 	data[1] =
-		((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
-		((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
-		((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
-		((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
+	    ((me4000_inl(dev, info->dio_context.port_0_reg) & 0xFF) << 0) |
+	    ((me4000_inl(dev, info->dio_context.port_1_reg) & 0xFF) << 8) |
+	    ((me4000_inl(dev, info->dio_context.port_2_reg) & 0xFF) << 16) |
+	    ((me4000_inl(dev, info->dio_context.port_3_reg) & 0xFF) << 24);
 
 	return 2;
 }
 
 static int me4000_dio_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned long tmp;
 	int chan = CR_CHAN(insn->chanspec);
@@ -2044,8 +2073,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
 
 	if (data[0] == INSN_CONFIG_DIO_QUERY) {
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 	}
 
@@ -2063,7 +2091,7 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
 		if (chan < 8) {
 			s->io_bits |= 0xFF;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-				ME4000_DIO_CTRL_BIT_MODE_1);
+				 ME4000_DIO_CTRL_BIT_MODE_1);
 			tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
 		} else if (chan < 16) {
 			/*
@@ -2075,17 +2103,17 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
 
 			s->io_bits |= 0xFF00;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-				ME4000_DIO_CTRL_BIT_MODE_3);
+				 ME4000_DIO_CTRL_BIT_MODE_3);
 			tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
 		} else if (chan < 24) {
 			s->io_bits |= 0xFF0000;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-				ME4000_DIO_CTRL_BIT_MODE_5);
+				 ME4000_DIO_CTRL_BIT_MODE_5);
 			tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
 		} else if (chan < 32) {
 			s->io_bits |= 0xFF000000;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-				ME4000_DIO_CTRL_BIT_MODE_7);
+				 ME4000_DIO_CTRL_BIT_MODE_7);
 			tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
 		} else {
 			return -EINVAL;
@@ -2101,19 +2129,19 @@ static int me4000_dio_insn_config(struct comedi_device *dev,
 
 			s->io_bits &= ~0xFF;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-				ME4000_DIO_CTRL_BIT_MODE_1);
+				 ME4000_DIO_CTRL_BIT_MODE_1);
 		} else if (chan < 16) {
 			s->io_bits &= ~0xFF00;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-				ME4000_DIO_CTRL_BIT_MODE_3);
+				 ME4000_DIO_CTRL_BIT_MODE_3);
 		} else if (chan < 24) {
 			s->io_bits &= ~0xFF0000;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-				ME4000_DIO_CTRL_BIT_MODE_5);
+				 ME4000_DIO_CTRL_BIT_MODE_5);
 		} else if (chan < 32) {
 			s->io_bits &= ~0xFF000000;
 			tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-				ME4000_DIO_CTRL_BIT_MODE_7);
+				 ME4000_DIO_CTRL_BIT_MODE_7);
 		} else {
 			return -EINVAL;
 		}
@@ -2151,8 +2179,8 @@ static int cnt_reset(struct comedi_device *dev, unsigned int channel)
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: cnt_reset(): Invalid channel\n",
-			dev->minor);
+		       "comedi%d: me4000: cnt_reset(): Invalid channel\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
@@ -2160,7 +2188,7 @@ static int cnt_reset(struct comedi_device *dev, unsigned int channel)
 }
 
 static int cnt_config(struct comedi_device *dev, unsigned int channel,
-	unsigned int mode)
+		      unsigned int mode)
 {
 	int tmp = 0;
 
@@ -2178,8 +2206,8 @@ static int cnt_config(struct comedi_device *dev, unsigned int channel,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: cnt_config(): Invalid channel\n",
-			dev->minor);
+		       "comedi%d: me4000: cnt_config(): Invalid channel\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
@@ -2204,8 +2232,8 @@ static int cnt_config(struct comedi_device *dev, unsigned int channel,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: cnt_config(): Invalid counter mode\n",
-			dev->minor);
+		       "comedi%d: me4000: cnt_config(): Invalid counter mode\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
@@ -2217,7 +2245,8 @@ static int cnt_config(struct comedi_device *dev, unsigned int channel,
 }
 
 static int me4000_cnt_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 
 	int err;
@@ -2228,8 +2257,8 @@ static int me4000_cnt_insn_config(struct comedi_device *dev,
 	case GPCT_RESET:
 		if (insn->n != 1) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
-				dev->minor, insn->n);
+			       "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
+			       dev->minor, insn->n);
 			return -EINVAL;
 		}
 
@@ -2240,8 +2269,8 @@ static int me4000_cnt_insn_config(struct comedi_device *dev,
 	case GPCT_SET_OPERATION:
 		if (insn->n != 2) {
 			printk(KERN_ERR
-				"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
-				dev->minor, insn->n);
+			       "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction length%d\n",
+			       dev->minor, insn->n);
 			return -EINVAL;
 		}
 
@@ -2251,8 +2280,8 @@ static int me4000_cnt_insn_config(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
-			dev->minor);
+		       "comedi%d: me4000: me4000_cnt_insn_config(): Invalid instruction\n",
+		       dev->minor);
 		return -EINVAL;
 	}
 
@@ -2260,7 +2289,8 @@ static int me4000_cnt_insn_config(struct comedi_device *dev,
 }
 
 static int me4000_cnt_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 
 	unsigned short tmp;
@@ -2272,8 +2302,8 @@ static int me4000_cnt_insn_read(struct comedi_device *dev,
 
 	if (insn->n > 1) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
-			dev->minor, insn->n);
+		       "comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
+		       dev->minor, insn->n);
 		return -EINVAL;
 	}
 
@@ -2298,8 +2328,8 @@ static int me4000_cnt_insn_read(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
-			dev->minor, insn->chanspec);
+		       "comedi%d: me4000: me4000_cnt_insn_read(): Invalid channel %d\n",
+		       dev->minor, insn->chanspec);
 		return -EINVAL;
 	}
 
@@ -2307,7 +2337,8 @@ static int me4000_cnt_insn_read(struct comedi_device *dev,
 }
 
 static int me4000_cnt_insn_write(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 
 	unsigned short tmp;
@@ -2318,8 +2349,8 @@ static int me4000_cnt_insn_write(struct comedi_device *dev,
 		return 0;
 	} else if (insn->n > 1) {
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
-			dev->minor, insn->n);
+		       "comedi%d: me4000: me4000_cnt_insn_write(): Invalid instruction length %d\n",
+		       dev->minor, insn->n);
 		return -EINVAL;
 	}
 
@@ -2344,8 +2375,8 @@ static int me4000_cnt_insn_write(struct comedi_device *dev,
 		break;
 	default:
 		printk(KERN_ERR
-			"comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
-			dev->minor, insn->chanspec);
+		       "comedi%d: me4000: me4000_cnt_insn_write(): Invalid channel %d\n",
+		       dev->minor, insn->chanspec);
 		return -EINVAL;
 	}
 
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index f21ceca..2cda7ad 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -151,46 +151,47 @@ static int me_detach(struct comedi_device *dev);
 static const struct comedi_lrange me2000_ai_range = {
 	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)
-	}
+	 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 struct comedi_lrange me2600_ai_range = {
 	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)
-		}
+	 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 struct comedi_lrange me2600_ao_range = {
 	3,
 	{
-			BIP_RANGE(10),
-			BIP_RANGE(5),
-			UNI_RANGE(10)
-		}
+	 BIP_RANGE(10),
+	 BIP_RANGE(5),
+	 UNI_RANGE(10)
+	 }
 };
 
 static DEFINE_PCI_DEVICE_TABLE(me_pci_table) = {
-	{PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		0},
-	{PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		0},
-	{0}
+	{
+	PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID, PCI_ANY_ID,
+		    PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID, PCI_ANY_ID,
+		    PCI_ANY_ID, 0, 0, 0}, {
+	0}
 };
 
 MODULE_DEVICE_TABLE(pci, me_pci_table);
@@ -212,48 +213,48 @@ struct me_board {
 
 static const struct me_board me_boards[] = {
 	{
-		/* -- ME-2600i -- */
-		.name = 		ME_DRIVER_NAME,
-		.device_id =		ME2600_DEVICE_ID,
-		/* Analog Output */
-		.ao_channel_nbr =	4,
-		.ao_resolution =	12,
-		.ao_resolution_mask =	0x0fff,
-		.ao_range_list =	&me2600_ao_range,
-		.ai_channel_nbr =	16,
-		/* Analog Input */
-		.ai_resolution =	12,
-		.ai_resolution_mask =	0x0fff,
-		.ai_range_list =	&me2600_ai_range,
-		.dio_channel_nbr =	32,
-		},
+	 /* -- ME-2600i -- */
+	 .name = ME_DRIVER_NAME,
+	 .device_id = ME2600_DEVICE_ID,
+	 /* Analog Output */
+	 .ao_channel_nbr = 4,
+	 .ao_resolution = 12,
+	 .ao_resolution_mask = 0x0fff,
+	 .ao_range_list = &me2600_ao_range,
+	 .ai_channel_nbr = 16,
+	 /* Analog Input */
+	 .ai_resolution = 12,
+	 .ai_resolution_mask = 0x0fff,
+	 .ai_range_list = &me2600_ai_range,
+	 .dio_channel_nbr = 32,
+	 },
 	{
-		/* -- ME-2000i -- */
-		.name =			ME_DRIVER_NAME,
-		.device_id =		ME2000_DEVICE_ID,
-		/* Analog Output */
-		.ao_channel_nbr =	0,
-		.ao_resolution =	0,
-		.ao_resolution_mask =	0,
-		.ao_range_list =	NULL,
-		.ai_channel_nbr =	16,
-		/* Analog Input */
-		.ai_resolution =	12,
-		.ai_resolution_mask =	0x0fff,
-		.ai_range_list =	&me2000_ai_range,
-		.dio_channel_nbr =	32,
-		}
+	 /* -- ME-2000i -- */
+	 .name = ME_DRIVER_NAME,
+	 .device_id = ME2000_DEVICE_ID,
+	 /* Analog Output */
+	 .ao_channel_nbr = 0,
+	 .ao_resolution = 0,
+	 .ao_resolution_mask = 0,
+	 .ao_range_list = NULL,
+	 .ai_channel_nbr = 16,
+	 /* Analog Input */
+	 .ai_resolution = 12,
+	 .ai_resolution_mask = 0x0fff,
+	 .ai_range_list = &me2000_ai_range,
+	 .dio_channel_nbr = 32,
+	 }
 };
 
 #define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board))
 
-
 static struct comedi_driver me_driver = {
-      .driver_name =	ME_DRIVER_NAME,
-      .module =		THIS_MODULE,
-      .attach =		me_attach,
-      .detach =		me_detach,
+	.driver_name = ME_DRIVER_NAME,
+	.module = THIS_MODULE,
+	.attach = me_attach,
+	.detach = me_detach,
 };
+
 COMEDI_PCI_INITCLEANUP(me_driver, me_pci_table);
 
 /* Private data structure */
@@ -292,7 +293,8 @@ static inline void sleep(unsigned sec)
  *
  * ------------------------------------------------------------------
  */
-static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+static int me_dio_insn_config(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
 			      struct comedi_insn *insn, unsigned int *data)
 {
 	int bits;
@@ -305,7 +307,7 @@ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
 		/* Enable Port A */
 		dev_private->control_2 |= ENABLE_PORT_A;
 		writew(dev_private->control_2,
-			dev_private->me_regbase + ME_CONTROL_2);
+		       dev_private->me_regbase + ME_CONTROL_2);
 	} else {		/* Port B in use */
 
 		bits = 0xffff0000;
@@ -313,7 +315,7 @@ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
 		/* Enable Port B */
 		dev_private->control_2 |= ENABLE_PORT_B;
 		writew(dev_private->control_2,
-			dev_private->me_regbase + ME_CONTROL_2);
+		       dev_private->me_regbase + ME_CONTROL_2);
 	}
 
 	if (data[0]) {
@@ -328,7 +330,8 @@ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
 }
 
 /* Digital instant input/outputs */
-static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+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];
@@ -338,7 +341,7 @@ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
 	mask &= s->io_bits;
 	if (mask & 0x0000ffff) {	/* Port A */
 		writew((s->state & 0xffff),
-			dev_private->me_regbase + ME_DIO_PORT_A);
+		       dev_private->me_regbase + ME_DIO_PORT_A);
 	} else {
 		data[1] &= ~0x0000ffff;
 		data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_A);
@@ -346,7 +349,7 @@ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
 
 	if (mask & 0xffff0000) {	/* Port B */
 		writew(((s->state >> 16) & 0xffff),
-			dev_private->me_regbase + ME_DIO_PORT_B);
+		       dev_private->me_regbase + ME_DIO_PORT_B);
 	} else {
 		data[1] &= ~0xffff0000;
 		data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_B) << 16;
@@ -364,7 +367,8 @@ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
  */
 
 /* Analog instant input */
-static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *subdevice,
+static int me_ai_insn_read(struct comedi_device *dev,
+			   struct comedi_subdevice *subdevice,
 			   struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned short value;
@@ -414,8 +418,8 @@ static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s
 	/* get value from ADC fifo */
 	if (i) {
 		data[0] =
-			(readw(dev_private->me_regbase +
-				ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF;
+		    (readw(dev_private->me_regbase +
+			   ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF;
 	} else {
 		printk(KERN_ERR "comedi%d: Cannot get single value\n",
 		       dev->minor);
@@ -450,14 +454,15 @@ static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 /* Test analog input command */
-static int me_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
-			     struct 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(struct comedi_device *dev, struct comedi_subdevice *subdevice)
+static int me_ai_do_cmd(struct comedi_device *dev,
+			struct comedi_subdevice *subdevice)
 {
 	return 0;
 }
@@ -471,7 +476,8 @@ static int me_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subd
  */
 
 /* Analog instant output */
-static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+static int me_ao_insn_write(struct comedi_device *dev,
+			    struct comedi_subdevice *s,
 			    struct comedi_insn *insn, unsigned int *data)
 {
 	int chan;
@@ -495,13 +501,13 @@ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *
 		dev_private->dac_control &= ~(0x0880 >> chan);
 		if (rang == 0)
 			dev_private->dac_control |=
-				((DAC_BIPOLAR_A | DAC_GAIN_1_A) >> chan);
+			    ((DAC_BIPOLAR_A | DAC_GAIN_1_A) >> chan);
 		else if (rang == 1)
 			dev_private->dac_control |=
-				((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);
+			    ((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);
 	}
 	writew(dev_private->dac_control,
-		dev_private->me_regbase + ME_DAC_CONTROL);
+	       dev_private->me_regbase + ME_DAC_CONTROL);
 
 	/* Update dac-control register */
 	readw(dev_private->me_regbase + ME_DAC_CONTROL_UPDATE);
@@ -510,7 +516,7 @@ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *
 	for (i = 0; i < insn->n; i++) {
 		chan = CR_CHAN((&insn->chanspec)[i]);
 		writew((data[0] & s->maxdata),
-			dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
+		       dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
 		dev_private->ao_readback[chan] = (data[0] & s->maxdata);
 	}
 
@@ -521,14 +527,15 @@ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *
 }
 
 /* Analog output readback */
-static int me_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-			   struct comedi_insn *insn, unsigned int *data)
+static int me_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[CR_CHAN((&insn->chanspec)[i])];
+		    dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])];
 	}
 
 	return 1;
@@ -575,9 +582,9 @@ static int me2600_xilinx_download(struct comedi_device *dev,
 	if (length < 16)
 		return -EINVAL;
 	file_length = (((unsigned int)me2600_firmware[0] & 0xff) << 24) +
-		      (((unsigned int)me2600_firmware[1] & 0xff) << 16) +
-		      (((unsigned int)me2600_firmware[2] & 0xff) << 8) +
-		      ((unsigned int)me2600_firmware[3] & 0xff);
+	    (((unsigned int)me2600_firmware[1] & 0xff) << 16) +
+	    (((unsigned int)me2600_firmware[2] & 0xff) << 8) +
+	    ((unsigned int)me2600_firmware[3] & 0xff);
 
 	/*
 	 * Loop for writing firmware byte by byte to xilinx
@@ -585,7 +592,7 @@ static int me2600_xilinx_download(struct comedi_device *dev,
 	 */
 	for (i = 0; i < file_length; i++)
 		writeb((me2600_firmware[16 + i] & 0xff),
-			dev_private->me_regbase + 0x0);
+		       dev_private->me_regbase + 0x0);
 
 	/* Write 5 dummy values to xilinx */
 	for (i = 0; i < 5; i++)
@@ -653,33 +660,32 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	/* 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)) {
+	     pci_device != NULL;
+	     pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
 		if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
 			for (i = 0; i < me_board_nbr; i++) {
 				if (me_boards[i].device_id ==
-					pci_device->device) {
+				    pci_device->device) {
 					/*
 					 * was a particular bus/slot requested?
 					 */
 					if ((it->options[0] != 0)
-						|| (it->options[1] != 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]) {
+						    it->options[0]
+						    ||
+						    PCI_SLOT(pci_device->devfn)
+						    != it->options[1]) {
 							continue;
 						}
 					}
 
 					dev->board_ptr = me_boards + i;
-					board = (struct me_board *) dev->
-						board_ptr;
+					board =
+					    (struct me_board *)dev->board_ptr;
 					dev_private->pci_device = pci_device;
 					goto found;
 				}
@@ -694,8 +700,8 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 found:
 	printk(KERN_INFO "comedi%d: found %s at PCI bus %d, slot %d\n",
-		dev->minor, me_boards[i].name,
-		pci_device->bus->number, PCI_SLOT(pci_device->devfn));
+	       dev->minor, me_boards[i].name,
+	       pci_device->bus->number, PCI_SLOT(pci_device->devfn));
 
 	/* Enable PCI device and request PCI regions */
 	if (comedi_pci_enable(pci_device, ME_DRIVER_NAME) < 0) {
@@ -711,7 +717,7 @@ found:
 	plx_regbase_tmp = pci_resource_start(pci_device, 0);
 	plx_regbase_size_tmp = pci_resource_len(pci_device, 0);
 	dev_private->plx_regbase =
-		ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
+	    ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
 	dev_private->plx_regbase_size = plx_regbase_size_tmp;
 	if (!dev_private->plx_regbase) {
 		printk("comedi%d: Failed to remap I/O memory\n", dev->minor);
@@ -736,18 +742,21 @@ found:
 			swap_regbase_tmp = regbase_tmp;
 
 			result = pci_write_config_dword(pci_device,
-				PCI_BASE_ADDRESS_0, plx_regbase_tmp);
+							PCI_BASE_ADDRESS_0,
+							plx_regbase_tmp);
 			if (result != PCIBIOS_SUCCESSFUL)
 				return -EIO;
 
 			result = pci_write_config_dword(pci_device,
-				PCI_BASE_ADDRESS_5, swap_regbase_tmp);
+							PCI_BASE_ADDRESS_5,
+							swap_regbase_tmp);
 			if (result != PCIBIOS_SUCCESSFUL)
 				return -EIO;
 		} else {
 			plx_regbase_tmp -= 0x80;
 			result = pci_write_config_dword(pci_device,
-				PCI_BASE_ADDRESS_0, plx_regbase_tmp);
+							PCI_BASE_ADDRESS_0,
+							plx_regbase_tmp);
 			if (result != PCIBIOS_SUCCESSFUL)
 				return -EIO;
 		}
@@ -822,7 +831,8 @@ found:
 	subdevice->insn_config = me_dio_insn_config;
 	subdevice->io_bits = 0;
 
-	printk(KERN_INFO "comedi%d: "ME_DRIVER_NAME" attached.\n", dev->minor);
+	printk(KERN_INFO "comedi%d: " ME_DRIVER_NAME " attached.\n",
+	       dev->minor);
 	return 0;
 }
 
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index 22a4029..e652f3b 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -73,8 +73,8 @@ void mite_init(void)
 	struct mite_struct *mite;
 
 	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)) {
+	     pcidev != NULL;
+	     pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
 		if (pcidev->vendor == PCI_VENDOR_ID_NATINST) {
 			unsigned i;
 
@@ -99,14 +99,19 @@ void mite_init(void)
 
 static void dump_chip_signature(u32 csigr_bits)
 {
-	printk("mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n", mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits), mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
-	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));
+	printk
+	    ("mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n",
+	     mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits),
+	     mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
+	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 fcr_bits = readl(mite->mite_io_addr +
-		MITE_FCR(channel));
+	unsigned fcr_bits = readl(mite->mite_io_addr + MITE_FCR(channel));
 	unsigned empty_count = (fcr_bits >> 16) & 0xff;
 	unsigned full_count = fcr_bits & 0xff;
 	return empty_count + full_count;
@@ -134,7 +139,7 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
 		return -ENOMEM;
 	}
 	printk("MITE:0x%08llx mapped to %p ",
-		(unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);
+	       (unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);
 
 	addr = pci_resource_start(mite->pcidev, 1);
 	mite->daq_phys_addr = addr;
@@ -146,19 +151,18 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
 		return -ENOMEM;
 	}
 	printk("DAQ:0x%08llx mapped to %p\n",
-		(unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);
+	       (unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);
 
 	if (use_iodwbsr_1) {
 		writel(0, mite->mite_io_addr + MITE_IODWBSR);
 		printk("mite: using I/O Window Base Size register 1\n");
-		writel(mite->
-			daq_phys_addr | WENAB |
-			MITE_IODWBSR_1_WSIZE_bits(length),
-			mite->mite_io_addr + MITE_IODWBSR_1);
+		writel(mite->daq_phys_addr | WENAB |
+		       MITE_IODWBSR_1_WSIZE_bits(length),
+		       mite->mite_io_addr + MITE_IODWBSR_1);
 		writel(0, mite->mite_io_addr + MITE_IODWCR_1);
 	} else {
 		writel(mite->daq_phys_addr | WENAB,
-			mite->mite_io_addr + MITE_IODWBSR);
+		       mite->mite_io_addr + MITE_IODWBSR);
 	}
 	/* make sure dma bursts work.  I got this from running a bus analyzer
 	   on a pxi-6281 and a pxi-6713.  6713 powered up with register value
@@ -167,15 +171,17 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
 	   then does a bitwise-or of 0x600 with it and writes it back.
 	 */
 	unknown_dma_burst_bits =
-		readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
+	    readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
 	unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS;
 	writel(unknown_dma_burst_bits,
-		mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
+	       mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
 
 	csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
 	mite->num_channels = mite_csigr_dmac(csigr_bits);
 	if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
-		printk("mite: bug? chip claims to have %i dma channels.  Setting to %i.\n", mite->num_channels, MAX_MITE_DMA_CHANNELS);
+		printk
+		    ("mite: bug? chip claims to have %i dma channels.  Setting to %i.\n",
+		     mite->num_channels, MAX_MITE_DMA_CHANNELS);
 		mite->num_channels = MAX_MITE_DMA_CHANNELS;
 	}
 	dump_chip_signature(csigr_bits);
@@ -183,9 +189,9 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
 		writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i));
 		/* disable interrupts */
 		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
-			CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
-			CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
-			mite->mite_io_addr + MITE_CHCR(i));
+		       CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
+		       CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
+		       mite->mite_io_addr + MITE_CHCR(i));
 	}
 	mite->fifo_size = mite_fifo_size(mite, 0);
 	printk("mite: fifo size is %i.\n", mite->fifo_size);
@@ -250,8 +256,10 @@ void mite_list_devices(void)
 }
 
 struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
-	struct mite_dma_descriptor_ring *ring, unsigned min_channel,
-	unsigned max_channel)
+						   struct
+						   mite_dma_descriptor_ring
+						   *ring, unsigned min_channel,
+						   unsigned max_channel)
 {
 	int i;
 	unsigned long flags;
@@ -284,10 +292,10 @@ void mite_release_channel(struct mite_channel *mite_chan)
 /* disable all channel's interrupts (do it after disarm/reset so
 MITE_CHCR reg isn't changed while dma is still active!) */
 		writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE |
-			CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE |
-			CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
-			CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
-			mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
+		       CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE |
+		       CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
+		       CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
+		       mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
 		mite->channel_allocated[mite_chan->channel] = 0;
 		mite_chan->ring = NULL;
 		mmiowb();
@@ -317,15 +325,18 @@ void mite_dma_arm(struct mite_channel *mite_chan)
 
 /**************************************/
 
-int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async * async)
+int mite_buf_change(struct mite_dma_descriptor_ring *ring,
+		    struct comedi_async *async)
 {
 	unsigned int n_links;
 	int i;
 
 	if (ring->descriptors) {
 		dma_free_coherent(ring->hw_dev,
-			ring->n_links * sizeof(struct mite_dma_descriptor),
-			ring->descriptors, ring->descriptors_dma_addr);
+				  ring->n_links *
+				  sizeof(struct mite_dma_descriptor),
+				  ring->descriptors,
+				  ring->descriptors_dma_addr);
 	}
 	ring->descriptors = NULL;
 	ring->descriptors_dma_addr = 0;
@@ -339,9 +350,9 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *
 	MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links);
 
 	ring->descriptors =
-		dma_alloc_coherent(ring->hw_dev,
-		n_links * sizeof(struct mite_dma_descriptor),
-		&ring->descriptors_dma_addr, GFP_KERNEL);
+	    dma_alloc_coherent(ring->hw_dev,
+			       n_links * sizeof(struct mite_dma_descriptor),
+			       &ring->descriptors_dma_addr, GFP_KERNEL);
 	if (!ring->descriptors) {
 		printk("mite: ring buffer allocation failed\n");
 		return -ENOMEM;
@@ -351,13 +362,14 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *
 	for (i = 0; i < n_links; i++) {
 		ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE);
 		ring->descriptors[i].addr =
-			cpu_to_le32(async->buf_page_list[i].dma_addr);
+		    cpu_to_le32(async->buf_page_list[i].dma_addr);
 		ring->descriptors[i].next =
-			cpu_to_le32(ring->descriptors_dma_addr + (i +
-				1) * sizeof(struct mite_dma_descriptor));
+		    cpu_to_le32(ring->descriptors_dma_addr + (i +
+							      1) *
+				sizeof(struct mite_dma_descriptor));
 	}
 	ring->descriptors[n_links - 1].next =
-		cpu_to_le32(ring->descriptors_dma_addr);
+	    cpu_to_le32(ring->descriptors_dma_addr);
 	/* barrier is meant to insure that all the writes to the dma descriptors
 	   have completed before the dma controller is commanded to read them */
 	smp_wmb();
@@ -365,7 +377,7 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *
 }
 
 void mite_prep_dma(struct mite_channel *mite_chan,
-	unsigned int num_device_bits, unsigned int num_memory_bits)
+		   unsigned int num_device_bits, unsigned int num_memory_bits)
 {
 	unsigned int chor, chcr, mcr, dcr, lkcr;
 	struct mite_struct *mite = mite_chan->mite;
@@ -378,7 +390,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
 
 	/* short link chaining mode */
 	chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE |
-		CHCR_BURSTEN;
+	    CHCR_BURSTEN;
 	/*
 	 * Link Complete Interrupt: interrupt every time a link
 	 * in MITE_RING is completed. This can generate a lot of
@@ -413,8 +425,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
 		mcr |= CR_PSIZE32;
 		break;
 	default:
-		printk
-			("mite: bug! invalid mem bit width for dma transfer\n");
+		printk("mite: bug! invalid mem bit width for dma transfer\n");
 		break;
 	}
 	writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel));
@@ -433,8 +444,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
 		dcr |= CR_PSIZE32;
 		break;
 	default:
-		printk
-			("mite: bug! invalid dev bit width for dma transfer\n");
+		printk("mite: bug! invalid dev bit width for dma transfer\n");
 		break;
 	}
 	writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel));
@@ -448,7 +458,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
 
 	/* starting address for link chaining */
 	writel(mite_chan->ring->descriptors_dma_addr,
-		mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
+	       mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
 
 	MDPRINTK("exit mite_prep_dma\n");
 }
@@ -459,15 +469,15 @@ u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
 	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;
+		     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)
+u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
 {
 	u32 device_byte_count;
 
@@ -476,7 +486,7 @@ u32 mite_bytes_written_to_memory_lb(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 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
 {
 	u32 in_transit_count;
 
@@ -485,7 +495,7 @@ u32 mite_bytes_written_to_memory_ub(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 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
 {
 	u32 device_byte_count;
 
@@ -494,7 +504,7 @@ u32 mite_bytes_read_from_memory_lb(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 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan)
 {
 	u32 in_transit_count;
 
@@ -511,7 +521,7 @@ unsigned mite_dma_tcr(struct mite_channel *mite_chan)
 	lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
 	tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel));
 	MDPRINTK("mite_dma_tcr ch%i, lkar=0x%08x tcr=%d\n", mite_chan->channel,
-		lkar, tcr);
+		 lkar, tcr);
 
 	return tcr;
 }
@@ -526,7 +536,8 @@ void mite_dma_disarm(struct mite_channel *mite_chan)
 	writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
 }
 
-int mite_sync_input_dma(struct mite_channel *mite_chan, struct 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;
@@ -538,7 +549,7 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * as
 
 	nbytes = mite_bytes_written_to_memory_lb(mite_chan);
 	if ((int)(mite_bytes_written_to_memory_ub(mite_chan) -
-			old_alloc_count) > 0) {
+		  old_alloc_count) > 0) {
 		printk("mite: DMA overwrite of free area\n");
 		async->events |= COMEDI_CB_OVERFLOW;
 		return -1;
@@ -561,24 +572,25 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * as
 	return 0;
 }
 
-int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async)
+int mite_sync_output_dma(struct mite_channel *mite_chan,
+			 struct comedi_async *async)
 {
 	int count;
 	u32 nbytes_ub, nbytes_lb;
 	unsigned int old_alloc_count;
 	u32 stop_count =
-		async->cmd.stop_arg * cfc_bytes_per_scan(async->subdevice);
+	    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 */
 	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 &&
-		(int)(nbytes_lb - stop_count) > 0)
+	    (int)(nbytes_lb - stop_count) > 0)
 		nbytes_lb = stop_count;
 	nbytes_ub = mite_bytes_read_from_memory_ub(mite_chan);
 	if (async->cmd.stop_src == TRIG_COUNT &&
-		(int)(nbytes_ub - stop_count) > 0)
+	    (int)(nbytes_ub - stop_count) > 0)
 		nbytes_ub = stop_count;
 	if ((int)(nbytes_ub - old_alloc_count) > 0) {
 		printk("mite: DMA underrun\n");
@@ -607,7 +619,7 @@ unsigned mite_get_status(struct mite_channel *mite_chan)
 	if (status & CHSR_DONE) {
 		mite_chan->done = 1;
 		writel(CHOR_CLRDONE,
-			mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
+		       mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
 	}
 	mmiowb();
 	spin_unlock_irqrestore(&mite->lock, flags);
@@ -703,7 +715,7 @@ static const char *const mite_CHSR_strings[] = {
 void mite_dump_regs(struct mite_channel *mite_chan)
 {
 	unsigned long mite_io_addr =
-		(unsigned long)mite_chan->mite->mite_io_addr;
+	    (unsigned long)mite_chan->mite->mite_io_addr;
 	unsigned long addr = 0;
 	unsigned long temp = 0;
 
@@ -712,37 +724,37 @@ void mite_dump_regs(struct mite_channel *mite_chan)
 
 	addr = mite_io_addr + MITE_CHOR(channel);
 	printk("mite status[CHOR]at 0x%08lx =0x%08lx\n", addr, temp =
-		readl(addr));
+	       readl(addr));
 	mite_decode(mite_CHOR_strings, temp);
 	addr = mite_io_addr + MITE_CHCR(channel);
 	printk("mite status[CHCR]at 0x%08lx =0x%08lx\n", addr, temp =
-		readl(addr));
+	       readl(addr));
 	mite_decode(mite_CHCR_strings, temp);
 	addr = mite_io_addr + MITE_TCR(channel);
 	printk("mite status[TCR] at 0x%08lx =0x%08x\n", addr, readl(addr));
 	addr = mite_io_addr + MITE_MCR(channel);
 	printk("mite status[MCR] at 0x%08lx =0x%08lx\n", addr, temp =
-		readl(addr));
+	       readl(addr));
 	mite_decode(mite_MCR_strings, temp);
 
 	addr = mite_io_addr + MITE_MAR(channel);
 	printk("mite status[MAR] at 0x%08lx =0x%08x\n", addr, readl(addr));
 	addr = mite_io_addr + MITE_DCR(channel);
 	printk("mite status[DCR] at 0x%08lx =0x%08lx\n", addr, temp =
-		readl(addr));
+	       readl(addr));
 	mite_decode(mite_DCR_strings, temp);
 	addr = mite_io_addr + MITE_DAR(channel);
 	printk("mite status[DAR] at 0x%08lx =0x%08x\n", addr, readl(addr));
 	addr = mite_io_addr + MITE_LKCR(channel);
 	printk("mite status[LKCR]at 0x%08lx =0x%08lx\n", addr, temp =
-		readl(addr));
+	       readl(addr));
 	mite_decode(mite_LKCR_strings, temp);
 	addr = mite_io_addr + MITE_LKAR(channel);
 	printk("mite status[LKAR]at 0x%08lx =0x%08x\n", addr, readl(addr));
 
 	addr = mite_io_addr + MITE_CHSR(channel);
 	printk("mite status[CHSR]at 0x%08lx =0x%08lx\n", addr, temp =
-		readl(addr));
+	       readl(addr));
 	mite_decode(mite_CHSR_strings, temp);
 	addr = mite_io_addr + MITE_FCR(channel);
 	printk("mite status[FCR] at 0x%08lx =0x%08x\n\n", addr, readl(addr));
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index 3194231..0518fad 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -80,10 +80,11 @@ struct mite_struct {
 };
 
 static inline struct mite_dma_descriptor_ring *mite_alloc_ring(struct
-	mite_struct *mite)
+							       mite_struct
+							       *mite)
 {
 	struct mite_dma_descriptor_ring *ring =
-		kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL);
+	    kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL);
 	if (ring == NULL)
 		return ring;
 	ring->hw_dev = get_device(&mite->pcidev->dev);
@@ -102,9 +103,10 @@ static inline void mite_free_ring(struct mite_dma_descriptor_ring *ring)
 	if (ring) {
 		if (ring->descriptors) {
 			dma_free_coherent(ring->hw_dev,
-				ring->n_links *
-				sizeof(struct mite_dma_descriptor),
-				ring->descriptors, ring->descriptors_dma_addr);
+					  ring->n_links *
+					  sizeof(struct mite_dma_descriptor),
+					  ring->descriptors,
+					  ring->descriptors_dma_addr);
 		}
 		put_device(ring->hw_dev);
 		kfree(ring);
@@ -117,6 +119,7 @@ static inline unsigned int mite_irq(struct mite_struct *mite)
 {
 	return mite->pcidev->irq;
 };
+
 static inline unsigned int mite_device_id(struct mite_struct *mite)
 {
 	return mite->pcidev->device;
@@ -129,21 +132,29 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1);
 void mite_unsetup(struct mite_struct *mite);
 void mite_list_devices(void);
 struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
-	struct mite_dma_descriptor_ring *ring, unsigned min_channel,
-	unsigned max_channel);
+						   struct
+						   mite_dma_descriptor_ring
+						   *ring, unsigned min_channel,
+						   unsigned max_channel);
 static inline struct mite_channel *mite_request_channel(struct mite_struct
-	*mite, struct mite_dma_descriptor_ring *ring)
+							*mite,
+							struct
+							mite_dma_descriptor_ring
+							*ring)
 {
 	return mite_request_channel_in_range(mite, ring, 0,
-		mite->num_channels - 1);
+					     mite->num_channels - 1);
 }
+
 void mite_release_channel(struct mite_channel *mite_chan);
 
 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, struct comedi_async * async);
-int mite_sync_output_dma(struct mite_channel *mite_chan, struct 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,16 +164,16 @@ unsigned mite_get_status(struct mite_channel *mite_chan);
 int mite_done(struct mite_channel *mite_chan);
 
 #if 0
-unsigned long mite_ll_from_kvmem(struct mite_struct *mite, struct comedi_async * async,
-	int len);
+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);
+		  int dir);
 #endif
 
 void mite_prep_dma(struct mite_channel *mite_chan,
-	unsigned int num_device_bits, unsigned int num_memory_bits);
+		   unsigned int num_device_bits, unsigned int num_memory_bits);
 int mite_buf_change(struct mite_dma_descriptor_ring *ring,
-	struct comedi_async *async);
+		    struct comedi_async *async);
 
 #ifdef DEBUG_MITE
 void mite_print_chsr(unsigned int chsr);
@@ -185,72 +196,88 @@ enum mite_registers {
 	MITE_PCI_CONFIG_OFFSET = 0x300,
 	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;
 };
 
@@ -275,22 +302,27 @@ static inline int mite_csigr_version(u32 csigr_bits)
 {
 	return csigr_bits & 0xf;
 };
+
 static inline int mite_csigr_type(u32 csigr_bits)
 {				/*  original mite = 0, minimite = 1 */
 	return (csigr_bits >> 4) & 0xf;
 };
+
 static inline int mite_csigr_mmode(u32 csigr_bits)
 {				/*  mite mode, minimite = 1 */
 	return (csigr_bits >> 8) & 0x3;
 };
+
 static inline int mite_csigr_imode(u32 csigr_bits)
 {				/*  cpu port interface mode, pci = 0x3 */
 	return (csigr_bits >> 12) & 0x3;
 };
+
 static inline int mite_csigr_dmac(u32 csigr_bits)
 {				/*  number of dma channels */
 	return (csigr_bits >> 16) & 0xf;
 };
+
 static inline int mite_csigr_wpdep(u32 csigr_bits)
 {				/*  write post fifo depth */
 	unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7;
@@ -299,10 +331,12 @@ static inline int mite_csigr_wpdep(u32 csigr_bits)
 	else
 		return 1 << (wpdep_bits - 1);
 };
+
 static inline int mite_csigr_wins(u32 csigr_bits)
 {
 	return (csigr_bits >> 24) & 0x1f;
 };
+
 static inline int mite_csigr_iowins(u32 csigr_bits)
 {				/*  number of io windows */
 	return (csigr_bits >> 29) & 0x7;
@@ -366,9 +400,9 @@ enum MITE_CHCR_bits {
 	CHCR_LINKSHORT = (4 << 0),
 	CHCR_LINKLONG = (5 << 0),
 	CHCRPON =
-		(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
-		CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
-		CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE),
+	    (CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
+	     CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
+	     CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE),
 };
 
 enum ConfigRegister_bits {
@@ -390,12 +424,14 @@ static inline int CR_REQS(int source)
 {
 	return (source & 0x7) << 16;
 };
+
 static inline int CR_REQSDRQ(unsigned drq_line)
 {
 	/* This also works on m-series when
 	   using channels (drq_line) 4 or 5. */
 	return CR_REQS((drq_line & 0x3) | 0x4);
 }
+
 static inline int CR_RL(unsigned int retry_limit)
 {
 	int value = 0;
@@ -447,7 +483,7 @@ enum CHSR_bits {
 static inline void mite_dma_reset(struct mite_channel *mite_chan)
 {
 	writel(CHOR_DMARESET | CHOR_FRESET,
-		mite_chan->mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
+	       mite_chan->mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
 };
 
 #endif
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
index 4a0e647..cb4da2a 100644
--- a/drivers/staging/comedi/drivers/mpc624.c
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -125,28 +125,29 @@ 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)
-		}
+	 /*  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)
-		}
+	 /*  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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int mpc624_detach(struct comedi_device *dev);
 /* ---------------------------------------------------------------------------- */
 static struct comedi_driver driver_mpc624 = {
@@ -157,8 +158,9 @@ static struct comedi_driver driver_mpc624 = {
 };
 
 /* ---------------------------------------------------------------------------- */
-static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+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)
 {
@@ -222,7 +224,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		break;
 	default:
 		printk
-			("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
+		    ("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
 		devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
 	}
 
@@ -270,8 +272,9 @@ static int mpc624_detach(struct comedi_device *dev)
 /* 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)
+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;
@@ -316,16 +319,15 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 			outb(0, dev->iobase + MPC624_ADC);
 			udelay(1);
 
-			if (data_out & (1 << 31))	/*  the next bit is a 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);
 				udelay(1);
 				/*  Set the clock high */
 				outb(MPC624_ADSCK | MPC624_ADSDI,
-					dev->iobase + MPC624_ADC);
-			} else	/*  the next bit is a 0 */
-			{
+				     dev->iobase + MPC624_ADC);
+			} else {	/*  the next bit is a 0 */
+
 				/*  Set the ADSDI line (send to MPC624) */
 				outb(0, dev->iobase + MPC624_ADC);
 				udelay(1);
@@ -336,8 +338,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 			udelay(1);
 			data_in <<= 1;
 			data_in |=
-				(inb(dev->iobase +
-					MPC624_ADC) & MPC624_ADSDO) >> 4;
+			    (inb(dev->iobase + MPC624_ADC) & MPC624_ADSDO) >> 4;
 			udelay(1);
 
 			data_out <<= 1;
@@ -358,12 +359,11 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 
 		if (data_in & MPC624_EOC_BIT)
 			printk("MPC624: EOC bit is set (data_in=%lu)!",
-				data_in);
+			       data_in);
 		if (data_in & MPC624_DMY_BIT)
 			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);
+		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. */
diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c
index c7ee3ef..440a144 100644
--- a/drivers/staging/comedi/drivers/mpc8260cpm.c
+++ b/drivers/staging/comedi/drivers/mpc8260cpm.c
@@ -46,7 +46,8 @@ struct mpc8260cpm_private {
 
 #define devpriv ((struct mpc8260cpm_private *)dev->private)
 
-static int mpc8260cpm_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -57,12 +58,15 @@ static struct comedi_driver driver_mpc8260cpm = {
 
 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_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)
+static int mpc8260cpm_attach(struct comedi_device *dev,
+			     struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int i;
@@ -114,8 +118,9 @@ static unsigned long *cpm_pdat(int port)
 	}
 }
 
-static int mpc8260cpm_dio_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -157,8 +162,9 @@ static int mpc8260cpm_dio_config(struct comedi_device *dev, struct comedi_subdev
 	return 1;
 }
 
-static int mpc8260cpm_dio_bits(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)
 {
 	int port;
 	unsigned long *p;
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
index f7cce6c..5d6af9c 100644
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -83,7 +83,8 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3)
 
 #define MULTIQ3_TIMEOUT 30
 
-static int multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -99,8 +100,9 @@ struct multiq3_private {
 };
 #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)
+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;
@@ -108,7 +110,7 @@ static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 
 	chan = CR_CHAN(insn->chanspec);
 	outw(MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3),
-		dev->iobase + MULTIQ3_CONTROL);
+	     dev->iobase + MULTIQ3_CONTROL);
 
 	for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
 		if (inw(dev->iobase + MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC)
@@ -121,7 +123,7 @@ static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 		outw(0, dev->iobase + MULTIQ3_AD_CS);
 		for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
 			if (inw(dev->iobase +
-					MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
+				MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
 				break;
 		}
 		if (i == MULTIQ3_TIMEOUT)
@@ -135,8 +137,9 @@ static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 	return n;
 }
 
-static int multiq3_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -148,15 +151,16 @@ static int multiq3_ao_insn_read(struct comedi_device *dev, struct comedi_subdevi
 	return i;
 }
 
-static int multiq3_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
+		     dev->iobase + MULTIQ3_CONTROL);
 		outw(data[i], dev->iobase + MULTIQ3_DAC_DATA);
 		outw(MULTIQ3_CONTROL_MUST, dev->iobase + MULTIQ3_CONTROL);
 
@@ -166,8 +170,9 @@ static int multiq3_ao_insn_write(struct comedi_device *dev, struct comedi_subdev
 	return i;
 }
 
-static int multiq3_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -177,8 +182,9 @@ static int multiq3_di_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	return 2;
 }
 
-static int multiq3_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -192,8 +198,10 @@ static int multiq3_do_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	return 2;
 }
 
-static int multiq3_encoder_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -218,7 +226,7 @@ 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);
+		    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);
@@ -236,7 +244,8 @@ static void encoder_reset(struct comedi_device *dev)
    options[2] - number of encoder chips installed
  */
 
-static int multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int multiq3_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	int result = 0;
 	unsigned long iobase;
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
index 67adc97..b37ef37 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -76,7 +76,8 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800
 #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_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",
@@ -93,22 +94,23 @@ struct ni6527_board {
 
 static const struct ni6527_board ni6527_boards[] = {
 	{
-	.dev_id = 0x2b20,
-	.name = "pci-6527",
-		},
+	 .dev_id = 0x2b20,
+	 .name = "pci-6527",
+	 },
 	{
-	.dev_id = 0x2b10,
-	.name = "pxi-6527",
-		},
+	 .dev_id = 0x2b10,
+	 .name = "pxi-6527",
+	 },
 };
 
-#define n_ni6527_boards (sizeof(ni6527_boards)/sizeof(ni6527_boards[0]))
+#define n_ni6527_boards ARRAY_SIZE(ni6527_boards)
 #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}
+	{
+	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);
@@ -123,8 +125,9 @@ struct ni6527_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)
+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;
@@ -141,17 +144,14 @@ static int ni6527_di_insn_config(struct comedi_device *dev, struct comedi_subdev
 
 		if (interval != devpriv->filter_interval) {
 			writeb(interval & 0xff,
-				devpriv->mite->daq_io_addr +
-				Filter_Interval(0));
+			       devpriv->mite->daq_io_addr + Filter_Interval(0));
 			writeb((interval >> 8) & 0xff,
-				devpriv->mite->daq_io_addr +
-				Filter_Interval(1));
+			       devpriv->mite->daq_io_addr + Filter_Interval(1));
 			writeb((interval >> 16) & 0x0f,
-				devpriv->mite->daq_io_addr +
-				Filter_Interval(2));
+			       devpriv->mite->daq_io_addr + Filter_Interval(2));
 
 			writeb(ClrInterval,
-				devpriv->mite->daq_io_addr + Clear_Register);
+			       devpriv->mite->daq_io_addr + Clear_Register);
 
 			devpriv->filter_interval = interval;
 		}
@@ -162,17 +162,18 @@ static int ni6527_di_insn_config(struct comedi_device *dev, struct comedi_subdev
 	}
 
 	writeb(devpriv->filter_enable,
-		devpriv->mite->daq_io_addr + Filter_Enable(0));
+	       devpriv->mite->daq_io_addr + Filter_Enable(0));
 	writeb(devpriv->filter_enable >> 8,
-		devpriv->mite->daq_io_addr + Filter_Enable(1));
+	       devpriv->mite->daq_io_addr + Filter_Enable(1));
 	writeb(devpriv->filter_enable >> 16,
-		devpriv->mite->daq_io_addr + Filter_Enable(2));
+	       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)
+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;
@@ -184,8 +185,9 @@ static int ni6527_di_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 	return 2;
 }
 
-static int ni6527_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -197,15 +199,15 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 		 * but in Comedi, it is represented by 0. */
 		if (data[0] & 0x0000ff) {
 			writeb((s->state ^ 0xff),
-				devpriv->mite->daq_io_addr + Port_Register(3));
+			       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));
+			       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));
+			       devpriv->mite->daq_io_addr + Port_Register(5));
 		}
 	}
 	data[1] = s->state;
@@ -226,7 +228,7 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
 		return IRQ_NONE;
 
 	writeb(ClrEdge | ClrOverflow,
-		devpriv->mite->daq_io_addr + Clear_Register);
+	       devpriv->mite->daq_io_addr + Clear_Register);
 
 	comedi_buf_put(s->async, 0);
 	s->async->events |= COMEDI_CB_EOS;
@@ -234,8 +236,9 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static int ni6527_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int ni6527_intr_cmdtest(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -310,28 +313,31 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 	return 0;
 }
 
-static int ni6527_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+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);
+	       devpriv->mite->daq_io_addr + Clear_Register);
 	writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
-		MasterInterruptEnable | EdgeIntEnable,
-		devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+	       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)
+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)
+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;
@@ -340,8 +346,9 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev, struct comedi_subdev
 	return 2;
 }
 
-static int ni6527_intr_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -349,18 +356,18 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, struct comedi_subd
 		return -EINVAL;
 
 	writeb(data[1],
-		devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
+	       devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
 	writeb(data[1] >> 8,
-		devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
+	       devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
 	writeb(data[1] >> 16,
-		devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
+	       devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
 
 	writeb(data[2],
-		devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
+	       devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
 	writeb(data[2] >> 8,
-		devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
+	       devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
 	writeb(data[2] >> 16,
-		devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
+	       devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
 
 	return 2;
 }
@@ -430,7 +437,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
 
 	writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
-		devpriv->mite->daq_io_addr + Clear_Register);
+	       devpriv->mite->daq_io_addr + Clear_Register);
 	writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
 
 	ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
@@ -449,7 +456,7 @@ 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);
+		       devpriv->mite->daq_io_addr + Master_Interrupt_Control);
 	}
 
 	if (dev->irq) {
@@ -473,7 +480,7 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot)
 			continue;
 		if (bus || slot) {
 			if (bus != mite->pcidev->bus->number ||
-				slot != PCI_SLOT(mite->pcidev->devfn))
+			    slot != PCI_SLOT(mite->pcidev->devfn))
 				continue;
 		}
 		for (i = 0; i < n_ni6527_boards; i++) {
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index 3570850..6b118c1 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -66,18 +66,22 @@ 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;
@@ -103,7 +107,8 @@ static inline unsigned Filter_Enable(unsigned port)
 #define OverflowIntEnable		0x02
 #define EdgeIntEnable			0x01
 
-static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -124,161 +129,165 @@ struct ni_65xx_board {
 
 static const struct ni_65xx_board ni_65xx_boards[] = {
 	{
-	.dev_id = 0x7085,
-	.name = "pci-6509",
-	.num_dio_ports = 12,
-	.invert_outputs = 0},
+	 .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 = 0x1710,
+	 .name = "pxi-6509",
+	 .num_dio_ports = 12,
+	 .invert_outputs = 0},
 	{
-	.dev_id = 0x7124,
-	.name = "pci-6510",
-	.num_di_ports = 4},
+	 .dev_id = 0x7124,
+	 .name = "pci-6510",
+	 .num_di_ports = 4},
 	{
-	.dev_id = 0x70c3,
-	.name = "pci-6511",
-	.num_di_ports = 8},
+	 .dev_id = 0x70c3,
+	 .name = "pci-6511",
+	 .num_di_ports = 8},
 	{
-	.dev_id = 0x70d3,
-	.name = "pxi-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 = 0x70cc,
+	 .name = "pci-6512",
+	 .num_do_ports = 8},
 	{
-	.dev_id = 0x70d2,
-	.name = "pxi-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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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,
-		},
+	 .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)
+#define n_ni_65xx_boards ARRAY_SIZE(ni_65xx_boards)
+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)
+
+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}
+	{
+	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);
@@ -291,7 +300,7 @@ struct ni_65xx_private {
 	unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
 };
 
-static inline struct ni_65xx_private *private(struct comedi_device * dev)
+static inline struct ni_65xx_private *private(struct comedi_device *dev)
 {
 	return dev->private;
 }
@@ -300,14 +309,16 @@ struct ni_65xx_subdevice_private {
 	unsigned base_port;
 };
 
-static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice * subdev)
+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);
+	    kzalloc(sizeof(struct ni_65xx_subdevice_private), GFP_KERNEL);
 	if (subdev_private == NULL)
 		return NULL;
 	return subdev_private;
@@ -315,12 +326,13 @@ static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void)
 
 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)
+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);
+	    sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
 
 	if (data[0] != INSN_CONFIG_FILTER)
 		return -EINVAL;
@@ -328,41 +340,42 @@ static int ni_65xx_config_filter(struct comedi_device *dev, struct comedi_subdev
 		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;
+		    (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)->mite->daq_io_addr +
+			       Filter_Interval);
 			private(dev)->filter_interval = interval;
 		}
 
 		private(dev)->filter_enable[port] |=
-			1 << (chan % ni_65xx_channels_per_port);
+		    1 << (chan % ni_65xx_channels_per_port);
 	} else {
 		private(dev)->filter_enable[port] &=
-			~(1 << (chan % ni_65xx_channels_per_port));
+		    ~(1 << (chan % ni_65xx_channels_per_port));
 	}
 
 	writeb(private(dev)->filter_enable[port],
-		private(dev)->mite->daq_io_addr + 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)
+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));
+	    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);
@@ -393,8 +406,9 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev, struct comedi_subd
 	return -EINVAL;
 }
 
-static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -405,8 +419,8 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 	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;
+		    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;
@@ -431,18 +445,17 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 			unsigned bits;
 			private(dev)->output_bits[port] &= ~port_mask;
 			private(dev)->output_bits[port] |=
-				port_data & port_mask;
+			    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));
+			       private(dev)->mite->daq_io_addr +
+			       Port_Data(port));
 /* printk("wrote 0x%x to port %i\n", bits, port); */
 		}
 		port_read_bits =
-			readb(private(dev)->mite->daq_io_addr +
-			Port_Data(port));
+		    readb(private(dev)->mite->daq_io_addr + Port_Data(port));
 /* printk("read 0x%x from port %i\n", port_read_bits, port); */
 		if (bitshift > 0) {
 			port_read_bits <<= bitshift;
@@ -468,7 +481,7 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d)
 		return IRQ_NONE;
 
 	writeb(ClrEdge | ClrOverflow,
-		private(dev)->mite->daq_io_addr + Clear_Register);
+	       private(dev)->mite->daq_io_addr + Clear_Register);
 
 	comedi_buf_put(s->async, 0);
 	s->async->events |= COMEDI_CB_EOS;
@@ -476,8 +489,9 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static int ni_65xx_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -552,29 +566,32 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevi
 	return 0;
 }
 
-static int ni_65xx_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+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);
+	       private(dev)->mite->daq_io_addr + Clear_Register);
 	writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
-		MasterInterruptEnable | EdgeIntEnable,
-		private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+	       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)
+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);
+	       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)
+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;
@@ -583,8 +600,10 @@ static int ni_65xx_intr_insn_bits(struct comedi_device *dev, struct comedi_subde
 	return 2;
 }
 
-static int ni_65xx_intr_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -592,35 +611,36 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, struct comedi_sub
 		return -EINVAL;
 
 	writeb(data[1],
-		private(dev)->mite->daq_io_addr +
-		Rising_Edge_Detection_Enable(0));
+	       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));
+	       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));
+	       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));
+	       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));
+	       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));
+	       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));
+	       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));
+	       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)
+static int ni_65xx_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	unsigned i;
@@ -647,7 +667,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	printk(" %s", dev->board_name);
 
 	printk(" ID=0x%02x",
-		readb(private(dev)->mite->daq_io_addr + ID_Register));
+	       readb(private(dev)->mite->daq_io_addr + ID_Register));
 
 	ret = alloc_subdevices(dev, 4);
 	if (ret < 0)
@@ -658,7 +678,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		s->type = COMEDI_SUBD_DI;
 		s->subdev_flags = SDF_READABLE;
 		s->n_chan =
-			board(dev)->num_di_ports * ni_65xx_channels_per_port;
+		    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;
@@ -676,7 +696,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		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;
+		    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;
@@ -693,7 +713,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		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;
+		    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;
@@ -705,8 +725,8 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		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));
+			       private(dev)->mite->daq_io_addr +
+			       Port_Select(i));
 		}
 	} else {
 		s->type = COMEDI_SUBD_UNUSED;
@@ -727,18 +747,18 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
 
 	for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) {
 		writeb(0x00,
-			private(dev)->mite->daq_io_addr + Filter_Enable(i));
+		       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));
+			       private(dev)->mite->daq_io_addr + Port_Data(i));
 		else
 			writeb(0x00,
-				private(dev)->mite->daq_io_addr + Port_Data(i));
+			       private(dev)->mite->daq_io_addr + Port_Data(i));
 	}
 	writeb(ClrEdge | ClrOverflow,
-		private(dev)->mite->daq_io_addr + Clear_Register);
+	       private(dev)->mite->daq_io_addr + Clear_Register);
 	writeb(0x00,
-		private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+	       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);
@@ -758,10 +778,10 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
 static int ni_65xx_detach(struct comedi_device *dev)
 {
 	if (private(dev) && private(dev)->mite
-		&& private(dev)->mite->daq_io_addr) {
+	    && private(dev)->mite->daq_io_addr) {
 		writeb(0x00,
-			private(dev)->mite->daq_io_addr +
-			Master_Interrupt_Control);
+		       private(dev)->mite->daq_io_addr +
+		       Master_Interrupt_Control);
 	}
 
 	if (dev->irq) {
@@ -793,7 +813,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot)
 			continue;
 		if (bus || slot) {
 			if (bus != mite->pcidev->bus->number ||
-				slot != PCI_SLOT(mite->pcidev->devfn))
+			    slot != PCI_SLOT(mite->pcidev->devfn))
 				continue;
 		}
 		for (i = 0; i < n_ni_65xx_boards; i++) {
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
index 11e9b04..404d3c5 100644
--- a/drivers/staging/comedi/drivers/ni_660x.c
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -201,7 +201,6 @@ struct NI_660xRegisterData {
 	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},
@@ -316,21 +315,25 @@ static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
 	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)
+					      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)
+					     unsigned input_select)
 {
 	return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
 }
@@ -341,6 +344,7 @@ 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,
 };
@@ -349,11 +353,13 @@ 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);
@@ -388,36 +394,37 @@ struct ni_660x_board {
 
 static const struct ni_660x_board ni_660x_boards[] = {
 	{
-	.dev_id = 0x2c60,
-	.name = "PCI-6601",
-	.n_chips = 1,
-		},
+	 .dev_id = 0x2c60,
+	 .name = "PCI-6601",
+	 .n_chips = 1,
+	 },
 	{
-	.dev_id = 0x1310,
-	.name = "PCI-6602",
-	.n_chips = 2,
-		},
+	 .dev_id = 0x1310,
+	 .name = "PCI-6602",
+	 .n_chips = 2,
+	 },
 	{
-	.dev_id = 0x1360,
-	.name = "PXI-6602",
-	.n_chips = 2,
-		},
+	 .dev_id = 0x1360,
+	 .name = "PXI-6602",
+	 .n_chips = 2,
+	 },
 	{
-	.dev_id = 0x2cc0,
-	.name = "PXI-6608",
-	.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}
+	{
+	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);
@@ -436,24 +443,26 @@ struct ni_660x_private {
 	unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
 };
 
-static inline struct ni_660x_private *private(struct comedi_device * dev)
+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)
+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]))
+#define n_ni_660x_boards ARRAY_SIZE(ni_660x_boards)
 
-static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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 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",
@@ -466,21 +475,28 @@ 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);
+				   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);
+			      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);
+				    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);
+			      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);
+				   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);
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data);
 
 static inline unsigned ni_660x_num_counters(struct comedi_device *dev)
 {
@@ -697,7 +713,7 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
 		break;
 	default:
 		printk("%s: unhandled register 0x%x in switch.\n",
-			__func__, reg);
+		       __func__, reg);
 		BUG();
 		return 0;
 		break;
@@ -706,11 +722,12 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
 }
 
 static inline void ni_660x_write_register(struct comedi_device *dev,
-	unsigned chip_index, unsigned bits, enum NI_660x_Register reg)
+					  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;
+	    private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+	    registerData[reg].offset;
 
 	switch (registerData[reg].size) {
 	case DATA_2B:
@@ -721,18 +738,19 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
 		break;
 	default:
 		printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
-			__FILE__, __func__, reg);
+		       __FILE__, __func__, reg);
 		BUG();
 		break;
 	}
 }
 
 static inline unsigned ni_660x_read_register(struct comedi_device *dev,
-	unsigned chip_index, enum NI_660x_Register reg)
+					     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;
+	    private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+	    registerData[reg].offset;
 
 	switch (registerData[reg].size) {
 	case DATA_2B:
@@ -743,7 +761,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
 		break;
 	default:
 		printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
-			__FILE__, __func__, reg);
+		       __FILE__, __func__, reg);
 		BUG();
 		break;
 	}
@@ -751,65 +769,72 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
 }
 
 static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
-	enum ni_gpct_register reg)
+				   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);
+			       ni_660x_register);
 }
 
 static unsigned ni_gpct_read_register(struct ni_gpct *counter,
-	enum ni_gpct_register reg)
+				      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);
+				     ni_660x_register);
 }
 
-static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private * priv,
-	struct ni_gpct *counter)
+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 mite_channel,
+					   struct ni_gpct *counter)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
 	private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
-		~dma_select_mask(mite_channel);
+	    ~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));
+	    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);
+			       private(dev)->
+			       dma_configuration_soft_copies
+			       [counter->chip_index] |
+			       dma_reset_bit(mite_channel), DMAConfigRegister);
 	mmiowb();
 	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 mite_channel,
+					     struct ni_gpct *counter)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
 	private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
-		~dma_select_mask(mite_channel);
+	    ~dma_select_mask(mite_channel);
 	private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
-		dma_select_bits(mite_channel, dma_selection_none);
+	    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);
+			       private(dev)->
+			       dma_configuration_soft_copies
+			       [counter->chip_index], DMAConfigRegister);
 	mmiowb();
 	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)
+					struct ni_gpct *counter,
+					enum comedi_io_direction direction)
 {
 	unsigned long flags;
 	struct mite_channel *mite_chan;
@@ -817,13 +842,12 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev,
 	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));
+	    mite_request_channel(private(dev)->mite, mite_ring(private(dev),
+							       counter));
 	if (mite_chan == NULL) {
-		spin_unlock_irqrestore(&private(dev)->mite_channel_lock,
-			flags);
+		spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
 		comedi_error(dev,
-			"failed to reserve mite dma channel for counter.");
+			     "failed to reserve mite dma channel for counter.");
 		return -EBUSY;
 	}
 	mite_chan->dir = direction;
@@ -833,7 +857,8 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev,
 	return 0;
 }
 
-void ni_660x_release_mite_channel(struct comedi_device *dev, struct ni_gpct *counter)
+void ni_660x_release_mite_channel(struct comedi_device *dev,
+				  struct ni_gpct *counter)
 {
 	unsigned long flags;
 
@@ -858,7 +883,7 @@ static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
 	if (retval) {
 		comedi_error(dev,
-			"no dma channel available for use by counter");
+			     "no dma channel available for use by counter");
 		return retval;
 	}
 	ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
@@ -867,8 +892,8 @@ static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	return retval;
 }
 
-static int ni_660x_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+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);
 
@@ -893,19 +918,18 @@ static void set_tio_counterswap(struct comedi_device *dev, int chipset)
 	 */
 	if (chipset)
 		ni_660x_write_register(dev, chipset, CounterSwap,
-			ClockConfigRegister);
+				       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)
+					  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)) {
+		if (s->async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+					COMEDI_CB_OVERFLOW)) {
 			ni_660x_cancel(dev, s);
 		}
 		comedi_event(dev, s);
@@ -943,13 +967,14 @@ static int ni_660x_input_poll(struct comedi_device *dev,
 	return comedi_buf_read_n_available(s->async);
 }
 
-static int ni_660x_buf_change(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned long new_size)
+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);
+			      s->async);
 	if (ret < 0)
 		return ret;
 
@@ -982,7 +1007,7 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
 	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);
+			    mite_alloc_ring(private(dev)->mite);
 			if (private(dev)->mite_rings[i][j] == NULL) {
 				return -ENOMEM;
 			}
@@ -1003,7 +1028,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev)
 	}
 }
 
-static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int ni_660x_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int ret;
@@ -1056,8 +1082,11 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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));
+							     &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) {
@@ -1065,8 +1094,8 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		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 */ ;
+			    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;
@@ -1082,9 +1111,9 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
 			s->private = &private(dev)->counter_dev->counters[i];
 
 			private(dev)->counter_dev->counters[i].chip_index =
-				i / counters_per_chip;
+			    i / counters_per_chip;
 			private(dev)->counter_dev->counters[i].counter_index =
-				i % counters_per_chip;
+			    i % counters_per_chip;
 		} else {
 			s->type = COMEDI_SUBD_UNUSED;
 		}
@@ -1100,7 +1129,7 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
 			ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
 		else
 			ni_660x_set_pfi_routing(dev, i,
-				pfi_output_select_counter);
+						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
@@ -1119,7 +1148,7 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	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);
+			       GlobalInterruptConfigRegister);
 	printk("attached\n");
 	return 0;
 }
@@ -1145,7 +1174,7 @@ static int ni_660x_detach(struct comedi_device *dev)
 
 static int
 ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		   struct comedi_insn *insn, unsigned int *data)
 {
 	return ni_tio_rinsn(subdev_to_counter(s), insn, data);
 }
@@ -1158,27 +1187,27 @@ static void init_tio_chip(struct comedi_device *dev, int chipset)
 	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);
+		    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)
-	{
+			       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)
+			 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)
+			      struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data)
 {
 	return ni_tio_winsn(subdev_to_counter(s), insn, data);
 }
@@ -1193,7 +1222,7 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
 			continue;
 		if (bus || slot) {
 			if (bus != mite->pcidev->bus->number ||
-				slot != PCI_SLOT(mite->pcidev->devfn))
+			    slot != PCI_SLOT(mite->pcidev->devfn))
 				continue;
 		}
 
@@ -1211,7 +1240,8 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
 }
 
 static int ni_660x_dio_insn_bits(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
 
@@ -1225,13 +1255,14 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev,
 	/* 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);
+	    (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 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;
@@ -1240,33 +1271,41 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_ch
 	unsigned active_bits;
 	unsigned idle_bits;
 
-	if (board (dev)->n_chips > 1) {
+	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) {
+		    pfi_channel >= counter_4_7_first_pfi &&
+		    pfi_channel <= counter_4_7_last_pfi) {
 			active_chipset = 1;
 			idle_chipset = 0;
-		}else {
+		} 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 =
+		    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));
+		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 =
+	    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));
+	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)
+				   unsigned source)
 {
 	if (source > num_pfi_output_selects)
 		return -EINVAL;
@@ -1284,18 +1323,21 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
 	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]);
+					  private(dev)->
+					  pfi_output_selects[chan]);
 	return 0;
 }
 
-static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned chan)
+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)
+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);
@@ -1304,7 +1346,8 @@ static void ni660x_config_filter(struct comedi_device *dev, unsigned pfi_channel
 }
 
 static int ni_660x_dio_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				   struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
@@ -1317,7 +1360,8 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev,
 	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]);
+					  private(dev)->
+					  pfi_output_selects[chan]);
 		break;
 	case INSN_CONFIG_DIO_INPUT:
 		private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
@@ -1325,9 +1369,8 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev,
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(private(dev)->
-			pfi_direction_bits & (((uint64_t) 1) << chan)) ?
-			COMEDI_OUTPUT : COMEDI_INPUT;
+		    (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]);
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
index 71f7d3a..9b43547 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -70,30 +70,32 @@ struct ni_670x_board {
 
 static const struct ni_670x_board ni_670x_boards[] = {
 	{
-	.dev_id = 0x2c90,
-	.name = "PCI-6703",
-	.ao_chans = 16,
-	.ao_bits = 16,
-		},
+	 .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 = 0x1920,
+	 .name = "PXI-6704",
+	 .ao_chans = 32,
+	 .ao_bits = 16,
+	 },
 	{
-	.dev_id = 0x1290,
-	.name = "PCI-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}
+	{
+	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);
@@ -108,11 +110,11 @@ struct ni_670x_private {
 	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]))
+#define n_ni_670x_boards ARRAY_SIZE(ni_670x_boards)
 
-static int ni_670x_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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 = {
@@ -128,16 +130,22 @@ 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)
+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;
@@ -175,7 +183,7 @@ static int ni_670x_attach(struct comedi_device *dev, struct comedi_devconfig *it
 		const struct comedi_lrange **range_table_list;
 
 		range_table_list = kmalloc(sizeof(struct comedi_lrange *) * 32,
-			GFP_KERNEL);
+					   GFP_KERNEL);
 		if (!range_table_list)
 			return -ENOMEM;
 		s->range_table_list = range_table_list;
@@ -223,8 +231,9 @@ static int ni_670x_detach(struct comedi_device *dev)
 	return 0;
 }
 
-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_winsn(struct comedi_device *dev,
+			    struct comedi_subdevice *s,
+			    struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -249,8 +258,9 @@ static int ni_670x_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
 	return i;
 }
 
-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_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);
@@ -261,8 +271,9 @@ static int ni_670x_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
 	return i;
 }
 
-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_bits(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -273,7 +284,7 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 		s->state &= ~data[0];
 		s->state |= data[0] & data[1];
 		writel(s->state,
-			devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
+		       devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
 	}
 
 	/* on return, data[1] contains the value of the digital
@@ -283,8 +294,9 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
 	return 2;
 }
 
-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_dio_insn_config(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
@@ -297,8 +309,7 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev, struct comedi_subd
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -320,7 +331,7 @@ static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot)
 			continue;
 		if (bus || slot) {
 			if (bus != mite->pcidev->bus->number
-				|| slot != PCI_SLOT(mite->pcidev->devfn))
+			    || slot != PCI_SLOT(mite->pcidev->devfn))
 				continue;
 		}
 
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
index 45c6809..dd75dfb 100644
--- a/drivers/staging/comedi/drivers/ni_at_a2150.c
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -131,25 +131,25 @@ struct a2150_board {
 static const struct comedi_lrange range_a2150 = {
 	1,
 	{
-			RANGE(-2.828, 2.828),
-		}
+	 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-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,
-		},
+	 .name = "at-a2150s",
+	 .clock = {62500, 50000, 41667, 0},
+	 .num_clocks = 3,
+	 .ai_speed = 41667,
+	 },
 };
 
 /*
@@ -167,7 +167,6 @@ struct a2150_private {
 	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);
@@ -182,16 +181,17 @@ static struct comedi_driver driver_a2150 = {
 };
 
 static irqreturn_t a2150_interrupt(int irq, void *d);
-static int a2150_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd);
+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);
+			  struct comedi_insn *insn, unsigned int *data);
 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
-	int flags);
+			    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);
+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.
@@ -335,7 +335,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	int i;
 
 	printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name,
-		iobase);
+	       iobase);
 	if (irq) {
 		printk(", irq %u", irq);
 	} else {
@@ -391,7 +391,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		}
 		devpriv->dma = dma;
 		devpriv->dma_buffer =
-			kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
+		    kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
 		if (devpriv->dma_buffer == NULL)
 			return -ENOMEM;
 
@@ -441,7 +441,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		udelay(1000);
 	}
 	if (i == timeout) {
-		printk(" timed out waiting for offset calibration to complete\n");
+		printk
+		    (" timed out waiting for offset calibration to complete\n");
 		return -ETIME;
 	}
 	devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
@@ -488,8 +489,8 @@ static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 	return 0;
 }
 
-static int a2150_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int a2150_ai_cmdtest(struct comedi_device *dev,
+			    struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -589,25 +590,24 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *
 		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");
+					     "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");
+				     "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");
+				     "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]))
-		{
+		    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");
+				     "channels 0/1 and 2/3 must have the same analog reference");
 			err++;
 		}
 	}
@@ -628,12 +628,12 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (!dev->irq || !devpriv->dma) {
 		comedi_error(dev,
-			" irq and dma required, cannot do hardware conversions");
+			     " 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");
+			     " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
 		return -1;
 	}
 	/*  clear fifo and reset triggering circuitry */
@@ -641,7 +641,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	/* setup chanlist */
 	if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
-			cmd->chanlist_len) < 0)
+			       cmd->chanlist_len) < 0)
 		return -1;
 
 	/*  setup ac/dc coupling */
@@ -673,14 +673,14 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	/*  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;
+	    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]);
+	    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);
@@ -700,8 +700,8 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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)) {
+	    (old_config_bits & CLOCK_MASK) !=
+	    (devpriv->config_bits & CLOCK_MASK)) {
 		/*  set trigger source to delay trigger */
 		trigger_bits |= DELAY_TRIGGER_BITS;
 	} else {
@@ -730,7 +730,7 @@ 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)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	unsigned int i, n;
 	static const int timeout = 100000;
@@ -804,7 +804,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 /* 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 flags)
 {
 	int lub, glb, temp;
 	int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
@@ -866,19 +866,20 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
 	devpriv->config_bits &= ~CLOCK_MASK;
 	if (*period == lub) {
 		devpriv->config_bits |=
-			CLOCK_SELECT_BITS(lub_index) |
-			CLOCK_DIVISOR_BITS(lub_divisor_shift);
+		    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);
+		    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)
+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;
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
index 4e8bf9e..8adb237 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -158,13 +158,13 @@ struct atao_board {
 
 static const struct atao_board atao_boards[] = {
 	{
-	.name = "ai-ao-6",
-	.n_ao_chans = 6,
-		},
+	 .name = "ai-ao-6",
+	 .n_ao_chans = 6,
+	 },
 	{
-	.name = "ai-ao-10",
-	.n_ao_chans = 10,
-		},
+	 .name = "ai-ao-10",
+	 .n_ao_chans = 10,
+	 },
 };
 
 #define thisboard ((struct atao_board *)dev->board_ptr)
@@ -198,17 +198,21 @@ 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);
+			 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);
+			 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)
 {
@@ -324,7 +328,7 @@ 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)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -348,7 +352,7 @@ static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -359,8 +363,9 @@ static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return i;
 }
 
-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_bits(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -376,8 +381,9 @@ static int atao_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 	return 2;
 }
 
-static int atao_dio_insn_config(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)
 {
 	int chan = CR_CHAN(insn->chanspec);
 	unsigned int mask, bit;
@@ -401,8 +407,7 @@ static int atao_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -421,8 +426,9 @@ static int atao_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
  * 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)
+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++) {
@@ -431,8 +437,9 @@ static int atao_calib_insn_read(struct comedi_device *dev, struct comedi_subdevi
 	return insn->n;
 }
 
-static int atao_calib_insn_write(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)
 {
 	unsigned int bitstring, bit;
 	unsigned int chan = CR_CHAN(insn->chanspec);
@@ -441,13 +448,13 @@ static int atao_calib_insn_write(struct comedi_device *dev, struct comedi_subdev
 
 	for (bit = 1 << (11 - 1); bit; bit >>= 1) {
 		outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
-			dev->iobase + ATAO_CFG2);
+		     dev->iobase + ATAO_CFG2);
 		outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
-			dev->iobase + ATAO_CFG2);
+		     dev->iobase + ATAO_CFG2);
 	}
 	/* strobe the appropriate caldac */
 	outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
-		dev->iobase + ATAO_CFG2);
+	     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
index 8839447..8ead311 100644
--- a/drivers/staging/comedi/drivers/ni_atmio.c
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -117,159 +117,159 @@ are not supported.
 
 static const struct ni_board_struct 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},
-		},
+	 .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},
-		},
+	 .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,
-		},
+	 .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,
-		},
+	 .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},
-		},
+	 .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,
-		},
+	 .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,
-		},
+	 .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,
-		}
+	 .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 };
+    { -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7 };
 
 #define interrupt_pin(a)	(ni_irqpin[(a)])
 
@@ -279,8 +279,7 @@ static const int ni_irqpin[] =
 
 struct ni_private {
 	struct pnp_dev *isapnp_dev;
-	NI_PRIVATE_COMMON
-};
+ NI_PRIVATE_COMMON};
 #define devpriv ((struct ni_private *)dev->private)
 
 /* How we access registers */
@@ -330,17 +329,18 @@ static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
 }
 
 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 = "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_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",
@@ -378,14 +378,17 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
 
 	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);
+					  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);
+			printk
+			    ("ni_atmio: %s found but already active, skipping.\n",
+			     ni_boards[i].name);
 			continue;
 		}
 		if (pnp_activate_dev(isapnp_dev) < 0) {
@@ -393,7 +396,7 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
 			return -EAGAIN;
 		}
 		if (!pnp_port_valid(isapnp_dev, 0)
-			|| !pnp_irq_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;
@@ -406,7 +409,8 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
 	return 0;
 }
 
-static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int ni_atmio_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	struct pnp_dev *isapnp_dev;
 	int ret;
@@ -455,7 +459,7 @@ static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *i
 		printk(" board fingerprint:");
 		for (i = 0; i < 16; i += 2) {
 			printk(" %04x %02x", inw(dev->iobase + i),
-				inb(dev->iobase + i + 1));
+			       inb(dev->iobase + i + 1));
 		}
 	}
 #endif
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
index 1a8c2ab..901833d 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -112,27 +112,31 @@ struct atmio16_board_t {
 
 static const struct atmio16_board_t atmio16_boards[] = {
 	{
-	.name = "atmio16",
-	.has_8255 = 0,
-		},
+	 .name = "atmio16",
+	 .has_8255 = 0,
+	 },
 	{
-	.name = "atmio16d",
-	.has_8255 = 1,
-		},
+	 .name = "atmio16d",
+	 .has_8255 = 1,
+	 },
 };
 
-#define n_atmio16_boards sizeof(atmio16_boards)/sizeof(atmio16_boards[0])
+#define n_atmio16_boards ARRAY_SIZE(atmio16_boards)
 
 #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_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);
-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 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);
 
@@ -151,27 +155,39 @@ 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)
-	}
+								       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)
-	}
+								      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)
-	}
+								     UNI_RANGE
+								     (10),
+								     UNI_RANGE
+								     (1),
+								     UNI_RANGE
+								     (0.1),
+								     UNI_RANGE
+								     (0.02)
+								     }
 };
 
 /* private data struct */
@@ -271,8 +287,9 @@ static irqreturn_t atmio16d_interrupt(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static int atmio16d_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int atmio16d_ai_cmdtest(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_cmd *cmd)
 {
 	int err = 0, tmp;
 #ifdef DEBUG1
@@ -310,8 +327,8 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 	/* 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)
+	    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++;
@@ -372,7 +389,8 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
 	return 0;
 }
 
-static int atmio16d_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+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;
@@ -418,10 +436,10 @@ static int atmio16d_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s
 	} else if (cmd->convert_arg < 655360000) {
 		base_clock = CLOCK_100_KHZ;
 		timer = cmd->convert_arg / 10000;
-	} else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */) {
+	} else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */ ) {
 		base_clock = CLOCK_10_KHZ;
 		timer = cmd->convert_arg / 100000;
-	} else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */) {
+	} else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */ ) {
 		base_clock = CLOCK_1_KHZ;
 		timer = cmd->convert_arg / 1000000;
 	}
@@ -466,10 +484,10 @@ static int atmio16d_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s
 		tmp = sample_count & 0xFFFF;
 		if ((tmp == 0) || (tmp == 1)) {
 			outw((sample_count >> 16) & 0xFFFF,
-				dev->iobase + AM9513A_DATA_REG);
+			     dev->iobase + AM9513A_DATA_REG);
 		} else {
 			outw(((sample_count >> 16) & 0xFFFF) + 1,
-				dev->iobase + AM9513A_DATA_REG);
+			     dev->iobase + AM9513A_DATA_REG);
 		}
 		outw(0xFF70, dev->iobase + AM9513A_COM_REG);
 		devpriv->com_reg_1_state |= COMREG1_1632CNT;
@@ -486,10 +504,10 @@ static int atmio16d_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s
 		} 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 */) {
+		} 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 */) {
+		} else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */ ) {
 			base_clock = CLOCK_1_KHZ;
 			timer = cmd->scan_begin_arg / 1000000;
 		}
@@ -522,7 +540,8 @@ static int atmio16d_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s
 }
 
 /* This will cancel a running acquisition operation */
-static int atmio16d_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int atmio16d_ai_cancel(struct comedi_device *dev,
+			      struct comedi_subdevice *s)
 {
 	reset_atmio16d(dev);
 
@@ -530,8 +549,9 @@ static int atmio16d_ai_cancel(struct comedi_device *dev, struct comedi_subdevice
 }
 
 /* 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)
+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;
@@ -589,8 +609,9 @@ static int atmio16d_ai_insn_read(struct comedi_device *dev, struct comedi_subdev
 	return i;
 }
 
-static int atmio16d_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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
@@ -604,8 +625,9 @@ static int atmio16d_ao_insn_read(struct comedi_device *dev, struct comedi_subdev
 	return i;
 }
 
-static int atmio16d_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -639,8 +661,9 @@ static int atmio16d_ao_insn_write(struct comedi_device *dev, struct comedi_subde
 	return i;
 }
 
-static int atmio16d_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -655,8 +678,10 @@ static int atmio16d_dio_insn_bits(struct comedi_device *dev, struct comedi_subde
 	return 2;
 }
 
-static int atmio16d_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -709,7 +734,8 @@ static int atmio16d_dio_insn_config(struct comedi_device *dev, struct comedi_sub
    options[12] - dac1 coding
  */
 
-static int atmio16d_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int atmio16d_attach(struct comedi_device *dev,
+			   struct comedi_devconfig *it)
 {
 	unsigned int irq;
 	unsigned long iobase;
@@ -843,7 +869,7 @@ static int atmio16d_attach(struct comedi_device *dev, struct comedi_devconfig *i
 	s->n_chan = 0;
 	s->maxdata = 0
 #endif
-		printk("\n");
+	    printk("\n");
 
 	return 0;
 }
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index e349482..6a77976 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -56,7 +56,8 @@ 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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int dio700_detach(struct comedi_device *dev);
 
 enum dio700_bustype { pcmcia_bustype };
@@ -74,17 +75,17 @@ struct dio700_board {
 
 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 = "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,
-		},
+	 .name = "ni_daq_700",
+	 .device_id = 0x4743,	/*  0x10b is manufacturer id, 0x4743 is device id */
+	 .bustype = pcmcia_bustype,
+	 .have_dio = 1,
+	 },
 };
 
 /*
@@ -97,7 +98,6 @@ 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 = {
@@ -156,8 +156,9 @@ static int subdev_700_cb(int dir, int port, int data, unsigned long arg)
 	}
 }
 
-static int subdev_700_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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];
@@ -165,7 +166,7 @@ static int subdev_700_insn(struct comedi_device *dev, struct comedi_subdevice *s
 
 		if (data[0] & 0xff)
 			CALLBACK_FUNC(1, _700_DATA, s->state & 0xff,
-				CALLBACK_ARG);
+				      CALLBACK_ARG);
 	}
 
 	data[1] = s->state & 0xff;
@@ -174,8 +175,9 @@ static int subdev_700_insn(struct comedi_device *dev, struct comedi_subdevice *s
 	return 2;
 }
 
-static int subdev_700_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int subdev_700_insn_config(struct comedi_device *dev,
+				  struct comedi_subdevice *s,
+				  struct comedi_insn *insn, unsigned int *data)
 {
 
 	switch (data[0]) {
@@ -185,9 +187,9 @@ static int subdev_700_insn_config(struct comedi_device *dev, struct comedi_subde
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->io_bits & (1 << CR_CHAN(insn->
-					chanspec))) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (s->
+		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
+		    COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -202,8 +204,9 @@ static void do_config(struct comedi_device *dev, struct comedi_subdevice *s)
 	return;
 }
 
-static int subdev_700_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int subdev_700_cmdtest(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	unsigned int tmp;
@@ -284,15 +287,16 @@ static int subdev_700_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	return 0;
 }
 
-static int subdev_700_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+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)
+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;
@@ -321,7 +325,8 @@ int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, int (
 }
 
 int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
-	int (*cb) (int, int, int, unsigned long), unsigned long arg)
+			int (*cb) (int, int, int, unsigned long),
+			unsigned long arg)
 {
 	int ret;
 
@@ -383,7 +388,7 @@ static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		break;
 	}
 	printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
-		thisboard->name, iobase);
+	       thisboard->name, iobase);
 #ifdef incomplete
 	if (irq) {
 		printk(", irq %u", irq);
@@ -553,7 +558,7 @@ static void dio700_cs_detach(struct pcmcia_device *link)
 	DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
 
 	if (link->dev_node) {
-		((struct local_info_t *) link->priv)->stop = 1;
+		((struct local_info_t *)link->priv)->stop = 1;
 		dio700_release(link);
 	}
 
@@ -609,7 +614,7 @@ static void dio700_config(struct pcmcia_device *link)
 	}
 
 	last_ret = pcmcia_parse_tuple(&tuple, &parse);
-	 if (last_ret) {
+	if (last_ret) {
 		cs_error(link, ParseTuple, last_ret);
 		goto cs_failed;
 	}
@@ -681,7 +686,7 @@ static void dio700_config(struct pcmcia_device *link)
 
 		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
 			cistpl_mem_t *mem =
-				(cfg->mem.nwin) ? &cfg->mem : &dflt.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;
@@ -699,7 +704,7 @@ static void dio700_config(struct pcmcia_device *link)
 		/* If we got this far, we're cool! */
 		break;
 
-	      next_entry:
+next_entry:
 
 		last_ret = pcmcia_get_next_tuple(link, &tuple);
 		if (last_ret) {
@@ -742,23 +747,23 @@ static void dio700_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x",
-		dev->node.dev_name, link->conf.ConfigIndex);
+	       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);
+		       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);
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
 	if (link->win)
 		printk(", mem 0x%06lx-0x%06lx", req.Base,
-			req.Base + req.Size - 1);
+		       req.Base + req.Size - 1);
 	printk("\n");
 
 	return;
 
-      cs_failed:
+cs_failed:
 	printk(KERN_INFO "ni_daq_700 cs failed");
 	dio700_release(link);
 
@@ -819,7 +824,7 @@ struct pcmcia_driver dio700_cs_driver = {
 	.id_table = dio700_cs_ids,
 	.owner = THIS_MODULE,
 	.drv = {
-			.name = dev_info,
+		.name = dev_info,
 		},
 };
 
@@ -836,6 +841,7 @@ 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;
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index a8ac02f..b06e81c 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -37,7 +37,7 @@ This is just a wrapper around the 8255.o driver to properly handle
 the PCMCIA interface.
 */
 
-/* #define LABPC_DEBUG */   /*  enable debugging messages */
+			    /* #define LABPC_DEBUG *//*  enable debugging messages */
 #undef LABPC_DEBUG
 
 #include <linux/interrupt.h>
@@ -74,17 +74,17 @@ struct dio24_board_struct {
 
 static const struct dio24_board_struct dio24_boards[] = {
 	{
-	.name = "daqcard-dio24",
-	.device_id = 0x475c,/*  0x10b is manufacturer id, 0x475c is device id */
-	.bustype = pcmcia_bustype,
-	.have_dio = 1,
-		},
+	 .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,
-		},
+	 .name = "ni_daq_dio24",
+	 .device_id = 0x475c,	/*  0x10b is manufacturer id, 0x475c is device id */
+	 .bustype = pcmcia_bustype,
+	 .have_dio = 1,
+	 },
 };
 
 /*
@@ -97,7 +97,6 @@ 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 = {
@@ -140,7 +139,7 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		break;
 	}
 	printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
-		thisboard->name, iobase);
+	       thisboard->name, iobase);
 #ifdef incomplete
 	if (irq) {
 		printk(", irq %u", irq);
@@ -310,7 +309,7 @@ static void dio24_cs_detach(struct pcmcia_device *link)
 	DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
 
 	if (link->dev_node) {
-		((struct local_info_t *) link->priv)->stop = 1;
+		((struct local_info_t *)link->priv)->stop = 1;
 		dio24_release(link);
 	}
 
@@ -439,7 +438,7 @@ static void dio24_config(struct pcmcia_device *link)
 
 		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
 			cistpl_mem_t *mem =
-				(cfg->mem.nwin) ? &cfg->mem : &dflt.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;
@@ -457,7 +456,7 @@ static void dio24_config(struct pcmcia_device *link)
 		/* If we got this far, we're cool! */
 		break;
 
-	      next_entry:
+next_entry:
 
 		last_ret = pcmcia_get_next_tuple(link, &tuple);
 		if (last_ret) {
@@ -500,23 +499,23 @@ static void dio24_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x",
-		dev->node.dev_name, link->conf.ConfigIndex);
+	       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);
+		       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);
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
 	if (link->win)
 		printk(", mem 0x%06lx-0x%06lx", req.Base,
-			req.Base + req.Size - 1);
+		       req.Base + req.Size - 1);
 	printk("\n");
 
 	return;
 
-      cs_failed:
+cs_failed:
 	printk(KERN_INFO "Fallo");
 	dio24_release(link);
 
@@ -576,7 +575,7 @@ struct pcmcia_driver dio24_cs_driver = {
 	.id_table = dio24_cs_ids,
 	.owner = THIS_MODULE,
 	.drv = {
-			.name = dev_info,
+		.name = dev_info,
 		},
 };
 
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index 30e11f4..dc3f398 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -171,40 +171,46 @@ 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_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);
+			  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);
+			  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);
+			  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);
+				  unsigned long arg);
 static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
-	unsigned int num_bits);
+			     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);
+				      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);
+				       unsigned int address,
+				       unsigned int value);
 static void write_caldac(struct comedi_device *dev, unsigned int channel,
-	unsigned int value);
+			 unsigned int value);
 
 enum scan_mode {
 	MODE_SINGLE_CHAN,
@@ -254,26 +260,27 @@ static const int labpc_plus_ai_gain_bits[NUM_LABPC_PLUS_AI_RANGES] = {
 	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),
-		}
+	 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
@@ -312,24 +319,25 @@ const int labpc_1200_ai_gain_bits[NUM_LABPC_1200_AI_RANGES] = {
 	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),
-		}
+	 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 */
@@ -337,9 +345,9 @@ const struct comedi_lrange range_labpc_1200_ai = {
 static const struct comedi_lrange range_labpc_ao = {
 	2,
 	{
-			BIP_RANGE(5),
-			UNI_RANGE(10),
-		}
+	 BIP_RANGE(5),
+	 UNI_RANGE(10),
+	 }
 };
 
 /* functions that do inb/outb and readb/writeb so we can use
@@ -348,14 +356,17 @@ 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);
@@ -363,60 +374,60 @@ static inline void labpc_writeb(unsigned int byte, unsigned long address)
 
 static const struct labpc_board_struct 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-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-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,
-		},
+	 .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,
-		},
+	 .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,
-		},
+	 .name = DRV_NAME,
+	 .bustype = pci_bustype,
+	 },
 #endif
 };
 
@@ -442,26 +453,28 @@ static struct comedi_driver driver_labpc = {
 
 #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}
+	{
+	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)
+				     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);
+				     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)
+			unsigned int irq, unsigned int dma_chan)
 {
 	struct comedi_subdevice *s;
 	int i;
@@ -469,7 +482,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
 	short lsb, msb;
 
 	printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
-		iobase);
+	       iobase);
 	if (irq) {
 		printk(", irq %u", irq);
 	}
@@ -486,7 +499,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
 	if (thisboard->bustype == isa_bustype) {
 		/* check if io addresses are available */
 		if (!request_region(iobase, LABPC_SIZE,
-				driver_labpc.driver_name)) {
+				    driver_labpc.driver_name)) {
 			printk("I/O port conflict\n");
 			return -EIO;
 		}
@@ -507,9 +520,9 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
 	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);
+				    dev->iobase + COMMAND5_REG);
 		devpriv->write_byte(devpriv->command6_bits,
-			dev->iobase + COMMAND6_REG);
+				    dev->iobase + COMMAND6_REG);
 	}
 
 	/* grab our IRQ */
@@ -532,14 +545,14 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
 	} else if (dma_chan) {
 		/*  allocate dma buffer */
 		devpriv->dma_buffer =
-			kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
+		    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);
+			       dma_chan);
 			return -EINVAL;
 		}
 		devpriv->dma_chan = dma_chan;
@@ -559,8 +572,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
 	dev->read_subdev = s;
 	s->type = COMEDI_SUBD_AI;
 	s->subdev_flags =
-		SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF |
-		SDF_CMD_READ;
+	    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 */
@@ -599,7 +611,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
 	/*  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));
+				 (unsigned long)(dev->iobase + DIO_BASE_REG));
 	else
 		subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG);
 
@@ -681,7 +693,8 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 #endif
 		break;
 	case pcmcia_bustype:
-		printk(" this driver does not support pcmcia cards, use ni_labpc_cs.o\n");
+		printk
+		    (" this driver does not support pcmcia cards, use ni_labpc_cs.o\n");
 		return -EINVAL;
 		break;
 	default:
@@ -705,7 +718,7 @@ static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
 		/*  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))
+			    || slot != PCI_SLOT(mite->pcidev->devfn))
 				continue;
 		}
 		for (i = 0; i < driver_labpc.num_names; i++) {
@@ -795,7 +808,7 @@ static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
 }
 
 static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
-	const struct comedi_cmd *cmd)
+				     const struct comedi_cmd *cmd)
 {
 	int mode, channel, range, aref, i;
 
@@ -810,7 +823,7 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
 	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");
+				     "ni_labpc: chanlist too long for single channel interval mode\n");
 			return 1;
 		}
 	}
@@ -825,22 +838,22 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
 		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");
+					     "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");
+					     "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) {
+			    cmd->chanlist_len - i - 1) {
 				comedi_error(dev,
-					"channel scanning order specified in chanlist is not supported by hardware.\n");
+					     "channel scanning order specified in chanlist is not supported by hardware.\n");
 				return 1;
 			}
 			break;
@@ -852,13 +865,13 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
 
 		if (CR_RANGE(cmd->chanlist[i]) != range) {
 			comedi_error(dev,
-				"entries in chanlist must all have the same range\n");
+				     "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");
+				     "entries in chanlist must all have the same reference\n");
 			return 1;
 		}
 	}
@@ -883,7 +896,7 @@ static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd)
 		return 0;
 
 	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
-		cmd->scan_begin_src == TRIG_TIMER)
+	    cmd->scan_begin_src == TRIG_TIMER)
 		return cmd->scan_begin_arg;
 
 	return cmd->convert_arg;
@@ -895,7 +908,7 @@ static void labpc_set_ai_convert_period(struct comedi_cmd *cmd, unsigned int ns)
 		return;
 
 	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
-		cmd->scan_begin_src == TRIG_TIMER) {
+	    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;
@@ -909,7 +922,7 @@ static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd)
 		return 0;
 
 	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
-		cmd->convert_src == TRIG_TIMER)
+	    cmd->convert_src == TRIG_TIMER)
 		return 0;
 
 	return cmd->scan_begin_arg;
@@ -921,14 +934,14 @@ static void labpc_set_ai_scan_period(struct comedi_cmd *cmd, unsigned int ns)
 		return;
 
 	if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
-		cmd->convert_src == TRIG_TIMER)
+	    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)
+static int labpc_ai_cmdtest(struct comedi_device *dev,
+			    struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp, tmp2;
@@ -972,13 +985,13 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *
 	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)
+	    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)
+	    cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
 		err++;
 
 	/*  can't have external stop and start triggers at once */
@@ -1012,16 +1025,16 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *
 	/*  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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->chanlist_len;
+			    cmd->convert_arg * cmd->chanlist_len;
 			err++;
 		}
 		if (cmd->scan_begin_arg <
-			thisboard->ai_speed * cmd->chanlist_len) {
+		    thisboard->ai_speed * cmd->chanlist_len) {
 			cmd->scan_begin_arg =
-				thisboard->ai_speed * cmd->chanlist_len;
+			    thisboard->ai_speed * cmd->chanlist_len;
 			err++;
 		}
 	}
@@ -1099,27 +1112,27 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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);
+					 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);
+				    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) {
+	    /*  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)) {
+		   /*  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;
@@ -1154,7 +1167,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			devpriv->command6_bits &= ~ADC_SCAN_UP_BIT;
 		/*  write to register */
 		devpriv->write_byte(devpriv->command6_bits,
-			dev->iobase + COMMAND6_REG);
+				    dev->iobase + COMMAND6_REG);
 	}
 
 	/* setup channel list, etc (command1 register) */
@@ -1171,13 +1184,13 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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) {
+	    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 */
 		udelay(1);
 		devpriv->write_byte(devpriv->command1_bits,
-			dev->iobase + COMMAND1_REG);
+				    dev->iobase + COMMAND1_REG);
 	}
 	/*  setup any external triggering/pacing (command4 register) */
 	devpriv->command4_bits = 0;
@@ -1196,17 +1209,17 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
 
 	devpriv->write_byte(cmd->chanlist_len,
-		dev->iobase + INTERVAL_COUNT_REG);
+			    dev->iobase + INTERVAL_COUNT_REG);
 	/*  load count */
 	devpriv->write_byte(INTERVAL_LOAD_BITS,
-		dev->iobase + INTERVAL_LOAD_REG);
+			    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);
+					 0, devpriv->divisor_b0, 3);
 		if (ret < 0) {
 			comedi_error(dev, "error loading counter b0");
 			return -1;
@@ -1216,20 +1229,20 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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);
+					 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);
+				    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);
+					 1, devpriv->divisor_b1, 2);
 		if (ret < 0) {
 			comedi_error(dev, "error loading counter b1");
 			return -1;
@@ -1246,14 +1259,13 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		 * count and address get set correctly */
 		clear_dma_ff(devpriv->dma_chan);
 		set_dma_addr(devpriv->dma_chan,
-			virt_to_bus(devpriv->dma_buffer));
+			     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->count * sample_size < devpriv->dma_transfer_size) {
 			devpriv->dma_transfer_size =
-				devpriv->count * sample_size;
+			    devpriv->count * sample_size;
 		}
 		set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
 		enable_dma(devpriv->dma_chan);
@@ -1330,12 +1342,12 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
 	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);
+		    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)) {
+				      OVERRUN_BIT | DATA_AVAIL_BIT)) == 0
+	    && (devpriv->status2_bits & A1_TC_BIT) == 0
+	    && (devpriv->status2_bits & FNHF_BIT)) {
 		return IRQ_NONE;
 	}
 
@@ -1351,8 +1363,8 @@ static irqreturn_t labpc_interrupt(int irq, void *d)
 	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)) {
+		    (thisboard->register_layout == labpc_1200_layout
+		     && devpriv->status2_bits & A1_TC_BIT)) {
 			handle_isa_dma(dev);
 		}
 	} else
@@ -1405,7 +1417,7 @@ static int labpc_drain_fifo(struct comedi_device *dev)
 	devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
 
 	for (i = 0; (devpriv->status1_bits & DATA_AVAIL_BIT) && i < timeout;
-		i++) {
+	     i++) {
 		/*  quit if we have all the data we want */
 		if (async->cmd.stop_src == TRIG_COUNT) {
 			if (devpriv->count == 0)
@@ -1417,7 +1429,7 @@ static int labpc_drain_fifo(struct comedi_device *dev)
 		data = (msb << 8) | lsb;
 		cfc_write_to_buffer(dev->read_subdev, data);
 		devpriv->status1_bits =
-			devpriv->read_byte(dev->iobase + STATUS1_REG);
+		    devpriv->read_byte(dev->iobase + STATUS1_REG);
 	}
 	if (i == timeout) {
 		comedi_error(dev, "ai timeout, fifo never empties");
@@ -1502,7 +1514,7 @@ static void labpc_drain_dregs(struct comedi_device *dev)
 }
 
 static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int i, n;
 	int chan, range;
@@ -1549,7 +1561,7 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 		devpriv->command6_bits &= ~A1_INTR_EN_BIT;
 		/*  write to register */
 		devpriv->write_byte(devpriv->command6_bits,
-			dev->iobase + COMMAND6_REG);
+				    dev->iobase + COMMAND6_REG);
 	}
 	/*  setup command4 register */
 	devpriv->command4_bits = 0;
@@ -1570,7 +1582,7 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 
 		for (i = 0; i < timeout; i++) {
 			if (devpriv->read_byte(dev->iobase +
-					STATUS1_REG) & DATA_AVAIL_BIT)
+					       STATUS1_REG) & DATA_AVAIL_BIT)
 				break;
 			udelay(1);
 		}
@@ -1588,7 +1600,7 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 
 /* analog output insn */
 static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int channel, range;
 	unsigned long flags;
@@ -1613,7 +1625,7 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 			devpriv->command6_bits &= ~DAC_UNIP_BIT(channel);
 		/*  write to register */
 		devpriv->write_byte(devpriv->command6_bits,
-			dev->iobase + COMMAND6_REG);
+				    dev->iobase + COMMAND6_REG);
 	}
 	/*  send data */
 	lsb = data[0] & 0xff;
@@ -1629,23 +1641,25 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 
 /* analog output readback insn */
 static int labpc_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  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)
+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)
+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);
 
@@ -1653,23 +1667,26 @@ static int labpc_calib_write_insn(struct comedi_device *dev, struct comedi_subde
 	return 1;
 }
 
-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_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)
+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)");
+		printk
+		    ("eeprom writes are only allowed to channels 16 through 127 (the pointer and user areas)");
 		return -EINVAL;
 	}
 
@@ -1715,7 +1732,7 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 	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;
+		    (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)
@@ -1728,25 +1745,25 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 		default:
 		case TRIG_ROUND_NEAREST:
 			devpriv->divisor_a0 =
-				(labpc_ai_convert_period(cmd) +
-				(base_period / 2)) / base_period;
+			    (labpc_ai_convert_period(cmd) +
+			     (base_period / 2)) / base_period;
 			devpriv->divisor_b1 =
-				(labpc_ai_scan_period(cmd) +
-				(base_period / 2)) / base_period;
+			    (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;
+			    (labpc_ai_convert_period(cmd) + (base_period -
+							     1)) / base_period;
 			devpriv->divisor_b1 =
-				(labpc_ai_scan_period(cmd) + (base_period -
-					1)) / base_period;
+			    (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;
+			    labpc_ai_convert_period(cmd) / base_period;
 			devpriv->divisor_b1 =
-				labpc_ai_scan_period(cmd) / base_period;
+			    labpc_ai_scan_period(cmd) / base_period;
 			break;
 		}
 		/*  make sure a0 and b1 values are acceptable */
@@ -1760,9 +1777,9 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 			devpriv->divisor_b1 = max_counter_value;
 		/*  write corrected timings to command */
 		labpc_set_ai_convert_period(cmd,
-			base_period * devpriv->divisor_a0);
+					    base_period * devpriv->divisor_a0);
 		labpc_set_ai_scan_period(cmd,
-			base_period * devpriv->divisor_b1);
+					 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;
@@ -1770,8 +1787,10 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 		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);
+					       &(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;
@@ -1779,14 +1798,16 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
 		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);
+					       &(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)
+				  unsigned long iobase)
 {
 	if (dir) {
 		writeb(data, (void *)(iobase + port));
@@ -1798,7 +1819,7 @@ static int labpc_dio_mem_callback(int dir, int port, int data,
 
 /* lowlevel write to eeprom/dac */
 static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
-	unsigned int value_width)
+			     unsigned int value_width)
 {
 	int i;
 
@@ -1812,12 +1833,12 @@ static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
 			devpriv->command5_bits &= ~SDATA_BIT;
 		udelay(1);
 		devpriv->write_byte(devpriv->command5_bits,
-			dev->iobase + COMMAND5_REG);
+				    dev->iobase + COMMAND5_REG);
 		/*  set clock to load bit */
 		devpriv->command5_bits |= SCLOCK_BIT;
 		udelay(1);
 		devpriv->write_byte(devpriv->command5_bits,
-			dev->iobase + COMMAND5_REG);
+				    dev->iobase + COMMAND5_REG);
 	}
 }
 
@@ -1833,16 +1854,16 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
 		devpriv->command5_bits |= SCLOCK_BIT;
 		udelay(1);
 		devpriv->write_byte(devpriv->command5_bits,
-			dev->iobase + COMMAND5_REG);
+				    dev->iobase + COMMAND5_REG);
 		/*  clear clock bit */
 		devpriv->command5_bits &= ~SCLOCK_BIT;
 		udelay(1);
 		devpriv->write_byte(devpriv->command5_bits,
-			dev->iobase + COMMAND5_REG);
+				    dev->iobase + COMMAND5_REG);
 		/*  read bits most significant bit first */
 		udelay(1);
 		devpriv->status2_bits =
-			devpriv->read_byte(dev->iobase + STATUS2_REG);
+		    devpriv->read_byte(dev->iobase + STATUS2_REG);
 		if (devpriv->status2_bits & EEPROM_OUT_BIT) {
 			value |= 1 << (value_width - i);
 		}
@@ -1851,7 +1872,8 @@ static unsigned int labpc_serial_in(struct comedi_device *dev)
 	return value;
 }
 
-static unsigned int labpc_eeprom_read(struct comedi_device *dev, unsigned int address)
+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 */
@@ -1881,7 +1903,7 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev, unsigned int ad
 }
 
 static unsigned int labpc_eeprom_write(struct comedi_device *dev,
-	unsigned int address, unsigned int value)
+				       unsigned int address, unsigned int value)
 {
 	const int write_enable_instruction = 0x6;
 	const int write_instruction = 0x2;
@@ -1893,7 +1915,7 @@ static unsigned int labpc_eeprom_write(struct comedi_device *dev,
 	/*  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)
+		    0)
 			break;
 	}
 	if (i == timeout) {
@@ -1967,7 +1989,7 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
 
 /* writes to 8 bit calibration dacs */
 static void write_caldac(struct comedi_device *dev, unsigned int channel,
-	unsigned int value)
+			 unsigned int value)
 {
 	if (value == devpriv->caldac[channel])
 		return;
@@ -1975,7 +1997,7 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel,
 
 	/*  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;
+	    ~CALDAC_LOAD_BIT & ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
 	udelay(1);
 	devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
 
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
index c5d2d21..8259634 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.h
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -30,7 +30,8 @@
 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 };
+	isa_dma_transfer
+};
 
 struct labpc_board_struct {
 	const char *name;
@@ -75,7 +76,7 @@ struct labpc_private {
 };
 
 int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
-	unsigned int irq, unsigned int dma);
+			unsigned int irq, unsigned int dma);
 int labpc_common_detach(struct comedi_device *dev);
 
 extern const int labpc_1200_is_unipolar[];
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index fb56c03..57aecfa 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -60,7 +60,7 @@ NI manuals:
 */
 
 #undef LABPC_DEBUG
-/* #define LABPC_DEBUG */   /*  enable debugging messages */
+			    /* #define LABPC_DEBUG *//*  enable debugging messages */
 
 #include "../comedidev.h"
 
@@ -83,32 +83,32 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it);
 
 static const struct labpc_board_struct 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,
-		},
+	 .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,
-		},
+	 .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,
+	 },
 };
 
 /*
@@ -165,7 +165,7 @@ 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";
+    "ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -287,7 +287,7 @@ static void labpc_cs_detach(struct pcmcia_device *link)
 	   detach().
 	 */
 	if (link->dev_node) {
-		((struct local_info_t *) link->priv)->stop = 1;
+		((struct local_info_t *)link->priv)->stop = 1;
 		labpc_release(link);
 	}
 
@@ -409,7 +409,7 @@ static void labpc_config(struct pcmcia_device *link)
 
 		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
 			cistpl_mem_t *mem =
-				(cfg->mem.nwin) ? &cfg->mem : &dflt.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;
@@ -428,7 +428,7 @@ static void labpc_config(struct pcmcia_device *link)
 		/* If we got this far, we're cool! */
 		break;
 
-	      next_entry:
+next_entry:
 		last_ret = pcmcia_get_next_tuple(link, &tuple);
 		if (last_ret) {
 			cs_error(link, GetNextTuple, last_ret);
@@ -470,23 +470,23 @@ static void labpc_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x",
-		dev->node.dev_name, link->conf.ConfigIndex);
+	       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);
+		       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);
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
 	if (link->win)
 		printk(", mem 0x%06lx-0x%06lx", req.Base,
-			req.Base + req.Size - 1);
+		       req.Base + req.Size - 1);
 	printk("\n");
 
 	return;
 
-      cs_failed:
+cs_failed:
 	labpc_release(link);
 
 }				/* labpc_config */
@@ -545,7 +545,7 @@ struct pcmcia_driver labpc_cs_driver = {
 	.id_table = labpc_cs_ids,
 	.owner = THIS_MODULE,
 	.drv = {
-			.name = dev_info,
+		.name = dev_info,
 		},
 };
 
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index d727d75..e3ffb06 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -77,110 +77,128 @@ 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},
+			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},
+			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},
+			  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),
-	}
+							 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),
-	}
+								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),
-	}
+								   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),
-	}
+								 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),
-	}
+							     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),
-	}
+							     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),
-	}
+							     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),
-	}
+							     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),
-	}
+							    RANGE(-10, 10),
+							    RANGE(0, 10),
+							    RANGE_ext(-1, 1),
+							    RANGE_ext(0, 1),
+							    }
 };
 
 static const struct comedi_lrange *const ni_range_lkup[] = {
@@ -194,46 +212,64 @@ static const struct comedi_lrange *const ni_range_lkup[] = {
 	[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_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 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);
+			  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);
+					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 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);
@@ -252,53 +288,62 @@ static void ni_mio_print_status_b(int status);
 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);
+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);
+			 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);
+			 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_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 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);
+				  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);
+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);
+				       unsigned int reg_select_bits);
 #endif
 static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
-	unsigned int reg_select_bits);
+				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_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);
+			       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);
 
@@ -355,14 +400,14 @@ enum timebase_nanoseconds {
 static const int num_adc_stages_611x = 3;
 
 static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
-	unsigned ai_mite_status);
+			       unsigned ai_mite_status);
 static void handle_b_interrupt(struct comedi_device *dev, unsigned short status,
-	unsigned ao_mite_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 bit_mask, unsigned bit_values)
 {
 	unsigned long flags;
 
@@ -372,19 +417,19 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
 		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);
+				    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);
+				    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);
+				    IO_Bidirection_Pin_Register);
 		break;
 	case AI_AO_Select:
 		devpriv->ai_ao_select_reg &= ~bit_mask;
@@ -397,8 +442,7 @@ static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
 		ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
 		break;
 	default:
-		printk("Warning %s() called with invalid register\n",
-			__func__);
+		printk("Warning %s() called with invalid register\n", __func__);
 		printk("reg is %d\n", reg);
 		break;
 	}
@@ -418,8 +462,8 @@ static inline void ni_set_ai_dma_channel(struct comedi_device *dev, int channel)
 
 	if (channel >= 0) {
 		bitfield =
-			(ni_stc_dma_channel_select_bitfield(channel) <<
-			AI_DMA_Select_Shift) & AI_DMA_Select_Mask;
+		    (ni_stc_dma_channel_select_bitfield(channel) <<
+		     AI_DMA_Select_Shift) & AI_DMA_Select_Mask;
 	} else {
 		bitfield = 0;
 	}
@@ -433,8 +477,8 @@ static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel)
 
 	if (channel >= 0) {
 		bitfield =
-			(ni_stc_dma_channel_select_bitfield(channel) <<
-			AO_DMA_Select_Shift) & AO_DMA_Select_Mask;
+		    (ni_stc_dma_channel_select_bitfield(channel) <<
+		     AO_DMA_Select_Shift) & AO_DMA_Select_Mask;
 	} else {
 		bitfield = 0;
 	}
@@ -443,7 +487,8 @@ static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel)
 
 /* 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 gpct_index,
+					   int mite_channel)
 {
 	unsigned bitfield;
 
@@ -453,11 +498,12 @@ static inline void ni_set_gpct_dma_channel(struct comedi_device *dev,
 		bitfield = 0;
 	}
 	ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index),
-		bitfield);
+			bitfield);
 }
 
 /* negative mite_channel means no channel */
-static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, int mite_channel)
+static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
+					  int mite_channel)
 {
 	unsigned long flags;
 
@@ -468,8 +514,8 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, int mite_ch
 		   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_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();
@@ -483,12 +529,11 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev)
 	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);
+	    mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
 	if (devpriv->ai_mite_chan == NULL) {
-		spin_unlock_irqrestore(&devpriv->mite_channel_lock,
-			flags);
+		spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 		comedi_error(dev,
-			"failed to reserve mite dma channel for analog input.");
+			     "failed to reserve mite dma channel for analog input.");
 		return -EBUSY;
 	}
 	devpriv->ai_mite_chan->dir = COMEDI_INPUT;
@@ -504,12 +549,11 @@ static int ni_request_ao_mite_channel(struct comedi_device *dev)
 	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);
+	    mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
 	if (devpriv->ao_mite_chan == NULL) {
-		spin_unlock_irqrestore(&devpriv->mite_channel_lock,
-			flags);
+		spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 		comedi_error(dev,
-			"failed to reserve mite dma channel for analog outut.");
+			     "failed to reserve mite dma channel for analog outut.");
 		return -EBUSY;
 	}
 	devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
@@ -519,7 +563,8 @@ static int ni_request_ao_mite_channel(struct comedi_device *dev)
 }
 
 static int ni_request_gpct_mite_channel(struct comedi_device *dev,
-	unsigned gpct_index, enum comedi_io_direction direction)
+					unsigned gpct_index,
+					enum comedi_io_direction direction)
 {
 	unsigned long flags;
 	struct mite_channel *mite_chan;
@@ -528,18 +573,17 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev,
 	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]);
+	    mite_request_channel(devpriv->mite,
+				 devpriv->gpct_mite_ring[gpct_index]);
 	if (mite_chan == NULL) {
-		spin_unlock_irqrestore(&devpriv->mite_channel_lock,
-			flags);
+		spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 		comedi_error(dev,
-			"failed to reserve mite dma channel for counter.");
+			     "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);
+				mite_chan);
 	ni_set_gpct_dma_channel(dev, gpct_index, mite_chan->channel);
 	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 	return 0;
@@ -555,12 +599,11 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev)
 	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);
+	    mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
 	if (devpriv->cdo_mite_chan == NULL) {
-		spin_unlock_irqrestore(&devpriv->mite_channel_lock,
-			flags);
+		spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 		comedi_error(dev,
-			"failed to reserve mite dma channel for correlated digital outut.");
+			     "failed to reserve mite dma channel for correlated digital outut.");
 		return -EBUSY;
 	}
 	devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
@@ -600,7 +643,8 @@ static void ni_release_ao_mite_channel(struct comedi_device *dev)
 #endif /*  PCIDMA */
 }
 
-void ni_release_gpct_mite_channel(struct comedi_device *dev, unsigned gpct_index)
+void ni_release_gpct_mite_channel(struct comedi_device *dev,
+				  unsigned gpct_index)
 {
 #ifdef PCIDMA
 	unsigned long flags;
@@ -609,11 +653,12 @@ void ni_release_gpct_mite_channel(struct comedi_device *dev, unsigned gpct_index
 	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;
+		    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);
+		ni_tio_set_mite_channel(&devpriv->
+					counter_dev->counters[gpct_index],
+					NULL);
 		mite_release_channel(mite_chan);
 	}
 	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -638,7 +683,7 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev)
 /* 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)
+					  unsigned gpct_index, short enable)
 {
 	if (boardtype.reg_type & ni_reg_m_series_mask)
 		return;
@@ -646,19 +691,19 @@ static void ni_e_series_enable_second_irq(struct comedi_device *dev,
 	case 0:
 		if (enable) {
 			devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable,
-				Second_IRQ_A_Enable_Register);
+					    Second_IRQ_A_Enable_Register);
 		} else {
 			devpriv->stc_writew(dev, 0,
-				Second_IRQ_A_Enable_Register);
+					    Second_IRQ_A_Enable_Register);
 		}
 		break;
 	case 1:
 		if (enable) {
 			devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable,
-				Second_IRQ_B_Enable_Register);
+					    Second_IRQ_B_Enable_Register);
 		} else {
 			devpriv->stc_writew(dev, 0,
-				Second_IRQ_B_Enable_Register);
+					    Second_IRQ_B_Enable_Register);
 		}
 		break;
 	default:
@@ -684,11 +729,11 @@ static void ni_clear_ai_fifo(struct comedi_device *dev)
 			/* 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);
+					    AI_Command_1_Register);
 			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
-				AI_Command_1_Register);
+					    AI_Command_1_Register);
 			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
-				AI_Command_1_Register);
+					    AI_Command_1_Register);
 #endif
 		}
 	}
@@ -709,7 +754,8 @@ static uint32_t win_in2(struct comedi_device *dev, int reg)
 }
 
 #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)
+static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
+				  int addr)
 {
 	unsigned long flags;
 
@@ -719,7 +765,8 @@ static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data, int
 	spin_unlock_irqrestore(&devpriv->window_lock, flags);
 }
 
-static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data, int addr)
+static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data,
+				  int addr)
 {
 	unsigned long flags;
 
@@ -751,8 +798,8 @@ static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr)
 *
 * value should only be 1 or 0.
 */
-static inline void ni_set_bits(struct comedi_device *dev, int reg, unsigned bits,
-	unsigned value)
+static inline void ni_set_bits(struct comedi_device *dev, int reg,
+			       unsigned bits, unsigned value)
 {
 	unsigned bit_values;
 
@@ -792,17 +839,17 @@ static irqreturn_t ni_E_interrupt(int irq, void *d)
 			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));
+				       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));
+				       mite->mite_io_addr +
+				       MITE_CHOR(devpriv->
+						 ao_mite_chan->channel));
 		}
 		spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
 	}
@@ -833,7 +880,8 @@ static void ni_sync_ai_dma(struct comedi_device *dev)
 	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 }
 
-static void mite_handle_b_linkc(struct mite_struct *mite, struct comedi_device * dev)
+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;
@@ -907,9 +955,9 @@ static void shutdown_ai_command(struct comedi_device *dev)
 
 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))
-	{
+	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);
@@ -932,13 +980,14 @@ static void ni_event(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static void handle_gpct_interrupt(struct comedi_device *dev,
-	unsigned short counter_index)
+				  unsigned short counter_index)
 {
 #ifdef PCIDMA
-	struct comedi_subdevice *s = dev->subdevices + NI_GPCT_SUBDEV(counter_index);
+	struct comedi_subdevice *s =
+	    dev->subdevices + NI_GPCT_SUBDEV(counter_index);
 
 	ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
-		s);
+				s);
 	if (s->async->events)
 		ni_event(dev, s);
 #endif
@@ -966,7 +1015,7 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
 }
 
 static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
-	unsigned ai_mite_status)
+			       unsigned ai_mite_status)
 {
 	struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
 
@@ -976,8 +1025,8 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
 
 #ifdef DEBUG_INTERRUPT
 	printk
-		("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n",
-		status, ai_mite_status);
+	    ("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
@@ -986,11 +1035,11 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
 	}
 
 	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)) {
+			       CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+			       CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
 		printk
-			("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
-			ai_mite_status);
+		    ("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); */
@@ -999,23 +1048,23 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
 
 	/* 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)) {
+		      AI_SC_TC_St | AI_START1_St)) {
 		if (status == 0xffff) {
 			printk
-				("ni_mio_common: a_status=0xffff.  Card removed?\n");
+			    ("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;
+				    COMEDI_CB_ERROR | COMEDI_CB_EOA;
 				ni_event(dev, s);
 			}
 			return;
 		}
 		if (status & (AI_Overrun_St | AI_Overflow_St |
-				AI_SC_TC_Error_St)) {
+			      AI_SC_TC_Error_St)) {
 			printk("ni_mio_common: ai error a_status=%04x\n",
-				status);
+			       status);
 			ni_mio_print_status_a(status);
 
 			shutdown_ai_command(dev);
@@ -1047,7 +1096,7 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
 			ni_handle_fifo_half_full(dev);
 			if ((devpriv->stc_readw(dev,
 						AI_Status_1_Register) &
-					AI_FIFO_Half_Full_St) == 0)
+			     AI_FIFO_Half_Full_St) == 0)
 				break;
 		}
 	}
@@ -1063,8 +1112,8 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
 	status = devpriv->stc_readw(dev, AI_Status_1_Register);
 	if (status & Interrupt_A_St) {
 		printk
-			("handle_a_interrupt: didn't clear interrupt? status=0x%x\n",
-			status);
+		    ("handle_a_interrupt: didn't clear interrupt? status=0x%x\n",
+		     status);
 	}
 #endif
 }
@@ -1097,14 +1146,14 @@ static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
 		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)
+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
 	printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
-		b_status, ao_mite_status);
+	       b_status, ao_mite_status);
 	ni_mio_print_status_b(b_status);
 #endif
 
@@ -1115,11 +1164,11 @@ static void handle_b_interrupt(struct comedi_device *dev, unsigned short b_statu
 	}
 
 	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)) {
+			       CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+			       CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
 		printk
-			("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
-			ao_mite_status);
+		    ("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;
 	}
@@ -1129,14 +1178,15 @@ static void handle_b_interrupt(struct comedi_device *dev, unsigned short b_statu
 		return;
 	if (b_status & AO_Overrun_St) {
 		printk
-			("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",
-			b_status, devpriv->stc_readw(dev,
-				AO_Status_2_Register));
+		    ("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));
+		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
@@ -1147,8 +1197,8 @@ static void handle_b_interrupt(struct comedi_device *dev, unsigned short b_statu
 		if (!ret) {
 			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);
+				    AO_FIFO_Interrupt_Enable |
+				    AO_Error_Interrupt_Enable, 0);
 			s->async->events |= COMEDI_CB_OVERFLOW;
 		}
 	}
@@ -1203,7 +1253,8 @@ static void ni_mio_print_status_b(int status)
 
 #ifndef PCIDMA
 
-static void ni_ao_fifo_load(struct comedi_device *dev, struct comedi_subdevice *s, int n)
+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;
@@ -1262,7 +1313,8 @@ static void ni_ao_fifo_load(struct comedi_device *dev, struct comedi_subdevice *
  *  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)
+static int ni_ao_fifo_half_empty(struct comedi_device *dev,
+				 struct comedi_subdevice *s)
 {
 	int n;
 
@@ -1283,7 +1335,8 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, struct comedi_subdev
 	return 1;
 }
 
-static int ni_ao_prep_fifo(struct comedi_device *dev, struct comedi_subdevice *s)
+static int ni_ao_prep_fifo(struct comedi_device *dev,
+			   struct comedi_subdevice *s)
 {
 	int n;
 
@@ -1306,7 +1359,8 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, struct comedi_subdevice *s
 	return n;
 }
 
-static void ni_ai_fifo_read(struct comedi_device *dev, struct comedi_subdevice *s, int 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;
@@ -1349,17 +1403,18 @@ static void ni_ai_fifo_read(struct comedi_device *dev, struct comedi_subdevice *
 		}
 	} else {
 		if (n > sizeof(devpriv->ai_fifo_buffer) /
-			sizeof(devpriv->ai_fifo_buffer[0])) {
+		    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);
+			    ni_readw(ADC_FIFO_Data_Register);
 		}
 		cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
-			n * sizeof(devpriv->ai_fifo_buffer[0]));
+					  n *
+					  sizeof(devpriv->ai_fifo_buffer[0]));
 	}
 }
 
@@ -1387,19 +1442,18 @@ static int ni_ai_drain_dma(struct comedi_device *dev)
 		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)
+			     AI_FIFO_Empty_St)
+			    && mite_bytes_in_transit(devpriv->ai_mite_chan) ==
+			    0)
 				break;
 			udelay(5);
 		}
 		if (i == timeout) {
+			printk("ni_mio_common: wait for dma drain timed out\n");
 			printk
-				("ni_mio_common: wait for dma drain timed out\n");
-			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));
+			    ("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;
 		}
 	}
@@ -1423,8 +1477,8 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
 
 	if (boardtype.reg_type == ni_reg_611x) {
 		while ((devpriv->stc_readw(dev,
-					AI_Status_1_Register) &
-				AI_FIFO_Empty_St) == 0) {
+					   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 */
@@ -1453,24 +1507,26 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev)
 
 	} else {
 		fifo_empty =
-			devpriv->stc_readw(dev,
-			AI_Status_1_Register) & AI_FIFO_Empty_St;
+		    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++) {
+			     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;
+				    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);
+				    ni_readw(ADC_FIFO_Data_Register);
 			}
 			cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
-				i * sizeof(devpriv->ai_fifo_buffer[0]));
+						  i *
+						  sizeof(devpriv->
+							 ai_fifo_buffer[0]));
 		}
 	}
 }
@@ -1513,7 +1569,8 @@ static void get_last_sample_6143(struct comedi_device *dev)
 }
 
 static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
-	void *data, unsigned int num_bytes, unsigned int chan_index)
+			void *data, unsigned int num_bytes,
+			unsigned int chan_index)
 {
 	struct comedi_async *async = s->async;
 	unsigned int i;
@@ -1620,13 +1677,13 @@ 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);
+			    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);
+		    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);
 
@@ -1635,51 +1692,60 @@ static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	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);
+			    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);
+				    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);
+				    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);
+				    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);
+			    AI_CONVERT_Output_Select
+			    (AI_CONVERT_Output_Enable_High);
 		else
 			ai_output_control_bits |=
-				AI_CONVERT_Output_Select
-				(AI_CONVERT_Output_Enable_Low);
+			    AI_CONVERT_Output_Select
+			    (AI_CONVERT_Output_Enable_Low);
 		devpriv->stc_writew(dev, ai_output_control_bits,
-			AI_Output_Control_Register);
+				    AI_Output_Control_Register);
 	}
 	/* the following registers should not be changed, because there
 	 * are no backup registers in devpriv.  If you want to change
@@ -1716,8 +1782,9 @@ static int ni_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 	return count;
 }
 
-static int ni_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -1733,31 +1800,31 @@ static int ni_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s
 	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);
+					    AI_Command_1_Register);
 			udelay(1);
 		}
 		for (n = 0; n < insn->n; n++) {
 			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
-				AI_Command_1_Register);
+					    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;
+					    & 0xffff;
 					break;
 				}
 				if (!(devpriv->stc_readw(dev,
-							AI_Status_1_Register) &
-						AI_FIFO_Empty_St)) {
+							 AI_Status_1_Register) &
+				      AI_FIFO_Empty_St)) {
 					d = ni_readl(ADC_FIFO_Data_611x) &
-						0xffff;
+					    0xffff;
 					break;
 				}
 			}
 			if (i == NI_TIMEOUT) {
 				printk
-					("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
+				    ("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
 				return -ETIME;
 			}
 			d += signbits;
@@ -1766,7 +1833,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s
 	} 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);
+					    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;
@@ -1779,7 +1846,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s
 			}
 			if (i == NI_TIMEOUT) {
 				printk
-					("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
+				    ("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
 				return -ETIME;
 			}
 			data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
@@ -1787,21 +1854,21 @@ static int ni_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s
 	} else {
 		for (n = 0; n < insn->n; n++) {
 			devpriv->stc_writew(dev, AI_CONVERT_Pulse,
-				AI_Command_1_Register);
+					    AI_Command_1_Register);
 			for (i = 0; i < NI_TIMEOUT; i++) {
 				if (!(devpriv->stc_readw(dev,
-							AI_Status_1_Register) &
-						AI_FIFO_Empty_St))
+							 AI_Status_1_Register) &
+				      AI_FIFO_Empty_St))
 					break;
 			}
 			if (i == NI_TIMEOUT) {
 				printk
-					("ni_mio_common: timeout in ni_ai_insn_read\n");
+				    ("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;
+				    ni_readl(M_Offset_AI_FIFO_Data) & mask;
 			} else {
 				d = ni_readw(ADC_FIFO_Data_Register);
 				d += signbits;	/* subtle: needs to be short addition */
@@ -1818,8 +1885,8 @@ void ni_prime_channelgain_list(struct comedi_device *dev)
 	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)) {
+					 AI_Status_1_Register) &
+		      AI_FIFO_Empty_St)) {
 			devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
 			return;
 		}
@@ -1829,7 +1896,8 @@ void ni_prime_channelgain_list(struct comedi_device *dev)
 }
 
 static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
-	unsigned int n_chan, unsigned int *list)
+					      unsigned int n_chan,
+					      unsigned int *list)
 {
 	unsigned int chan, range, aref;
 	unsigned int i;
@@ -1849,11 +1917,11 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
 		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);
+		    (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;
@@ -1876,22 +1944,22 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
 		switch (aref) {
 		case AREF_DIFF:
 			config_bits |=
-				MSeries_AI_Config_Channel_Type_Differential_Bits;
+			    MSeries_AI_Config_Channel_Type_Differential_Bits;
 			break;
 		case AREF_COMMON:
 			config_bits |=
-				MSeries_AI_Config_Channel_Type_Common_Ref_Bits;
+			    MSeries_AI_Config_Channel_Type_Common_Ref_Bits;
 			break;
 		case AREF_GROUND:
 			config_bits |=
-				MSeries_AI_Config_Channel_Type_Ground_Ref_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);
+		    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;
@@ -1933,8 +2001,8 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
  *   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)
+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;
@@ -1947,9 +2015,9 @@ static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_c
 		return;
 	}
 	if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x)
-		&& (boardtype.reg_type != ni_reg_6143)) {
+	    && (boardtype.reg_type != ni_reg_6143)) {
 		if (devpriv->changain_state
-			&& devpriv->changain_spec == list[0]) {
+		    && devpriv->changain_spec == list[0]) {
 			/*  ready to go. */
 			return;
 		}
@@ -1964,25 +2032,23 @@ static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_c
 	/*  Set up Calibration mode if required */
 	if (boardtype.reg_type == ni_reg_6143) {
 		if ((list[0] & CR_ALT_SOURCE)
-			&& !devpriv->ai_calib_source_enabled) {
+		    && !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_RelayOn,
+				  Calibration_Channel_6143);
 			ni_writew(devpriv->ai_calib_source,
-				Calibration_Channel_6143);
+				  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) {
+			   && 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_RelayOff,
+				  Calibration_Channel_6143);
 			ni_writew(devpriv->ai_calib_source,
-				Calibration_Channel_6143);
+				  Calibration_Channel_6143);
 			devpriv->ai_calib_source_enabled = 0;
 			msleep_interruptible(100);	/*  Allow relays to change */
 		}
@@ -1991,7 +2057,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_c
 	offset = 1 << (boardtype.adbits - 1);
 	for (i = 0; i < n_chan; i++) {
 		if ((boardtype.reg_type != ni_reg_6143)
-			&& (list[i] & CR_ALT_SOURCE)) {
+		    && (list[i] & CR_ALT_SOURCE)) {
 			chan = devpriv->ai_calib_source;
 		} else {
 			chan = CR_CHAN(list[i]);
@@ -2011,7 +2077,7 @@ static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_c
 		if ((list[i] & CR_ALT_SOURCE)) {
 			if (boardtype.reg_type == ni_reg_611x)
 				ni_writew(CR_CHAN(list[i]) & 0x0003,
-					Calibration_Channel_Select_611x);
+					  Calibration_Channel_Select_611x);
 		} else {
 			if (boardtype.reg_type == ni_reg_611x)
 				aref = AREF_DIFF;
@@ -2048,13 +2114,13 @@ static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_c
 
 	/* prime the channel/gain list */
 	if ((boardtype.reg_type != ni_reg_611x)
-		&& (boardtype.reg_type != ni_reg_6143)) {
+	    && (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 round_mode)
 {
 	int divider;
 	switch (round_mode) {
@@ -2078,7 +2144,7 @@ static unsigned ni_timer_to_ns(const struct comedi_device *dev, int timer)
 }
 
 static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev,
-	unsigned num_channels)
+					 unsigned num_channels)
 {
 	switch (boardtype.reg_type) {
 	case ni_reg_611x:
@@ -2094,7 +2160,7 @@ static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev,
 }
 
 static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+			 struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -2119,7 +2185,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	tmp = cmd->convert_src;
 	sources = TRIG_TIMER | TRIG_EXT;
 	if ((boardtype.reg_type == ni_reg_611x)
-		|| (boardtype.reg_type == ni_reg_6143))
+	    || (boardtype.reg_type == ni_reg_6143))
 		sources |= TRIG_NOW;
 	cmd->convert_src &= sources;
 	if (!cmd->convert_src || tmp != cmd->convert_src)
@@ -2142,14 +2208,14 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 
 	/* 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)
+	    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)
+	    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)
+	    cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
 		err++;
 	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 		err++;
@@ -2179,10 +2245,11 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	}
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev,
-				cmd->chanlist_len)) {
+								   cmd->
+								   chanlist_len))
+		{
 			cmd->scan_begin_arg =
-				ni_min_ai_scan_period_ns(dev,
-				cmd->chanlist_len);
+			    ni_min_ai_scan_period_ns(dev, cmd->chanlist_len);
 			err++;
 		}
 		if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) {
@@ -2208,7 +2275,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	}
 	if (cmd->convert_src == TRIG_TIMER) {
 		if ((boardtype.reg_type == ni_reg_611x)
-			|| (boardtype.reg_type == ni_reg_6143)) {
+		    || (boardtype.reg_type == ni_reg_6143)) {
 			if (cmd->convert_arg != 0) {
 				cmd->convert_arg = 0;
 				err++;
@@ -2274,27 +2341,31 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	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));
+		    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)) {
+		    && (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));
+			    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) {
 				cmd->scan_begin_arg =
-					cmd->convert_arg * cmd->scan_end_arg;
+				    cmd->convert_arg * cmd->scan_end_arg;
 				err++;
 			}
 		}
@@ -2332,27 +2403,28 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	 * 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);
+			    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);
+				    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);
+			    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);
+					    AI_Trigger_Select_Register);
 			break;
 		}
 	}
@@ -2363,7 +2435,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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)) {
+	    || (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;
@@ -2371,7 +2443,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		start_stop_select |= AI_STOP_Select(19);	/*  ai configuration memory */
 	}
 	devpriv->stc_writew(dev, start_stop_select,
-		AI_START_STOP_Select_Register);
+			    AI_START_STOP_Select_Register);
 
 	devpriv->ai_cmd2 = 0;
 	switch (cmd->stop_src) {
@@ -2397,7 +2469,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			/*  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;
+				    AI_STOP_Polarity | AI_STOP_Edge;
 		}
 		break;
 	case TRIG_NONE:
@@ -2433,7 +2505,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		 */
 		start_stop_select |= AI_START_Edge | AI_START_Sync;
 		devpriv->stc_writew(dev, start_stop_select,
-			AI_START_STOP_Select_Register);
+				    AI_START_STOP_Select_Register);
 
 		mode2 |= AI_SI_Reload_Mode(0);
 		/* AI_SI_Initial_Load_Source=A */
@@ -2443,7 +2515,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 		/* load SI */
 		timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
-			TRIG_ROUND_NEAREST);
+				       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;
@@ -2454,13 +2526,13 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		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))
+		    (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));
+		    AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
 		devpriv->stc_writew(dev, start_stop_select,
-			AI_START_STOP_Select_Register);
+				    AI_START_STOP_Select_Register);
 		break;
 	}
 
@@ -2471,7 +2543,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			timer = 1;
 		else
 			timer = ni_ns_to_timer(dev, cmd->convert_arg,
-				TRIG_ROUND_NEAREST);
+					       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);
 
@@ -2505,14 +2577,14 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 		/* interrupt on FIFO, errors, SC_TC */
 		interrupt_a_enable |= AI_Error_Interrupt_Enable |
-			AI_SC_TC_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)) {
+		    || (devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
 			/* wake on end-of-scan */
 			devpriv->aimode = AIMODE_SCAN;
 		} else {
@@ -2524,24 +2596,24 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			/*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);
+					    AI_Mode_3_Register);
 #else
 			devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
-				AI_Mode_3_Register);
+					    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);
+					    AI_Mode_3_Register);
 			break;
 		case AIMODE_SCAN:
 #ifdef PCIDMA
 			devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
-				AI_Mode_3_Register);
+					    AI_Mode_3_Register);
 #else
 			devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
-				AI_Mode_3_Register);
+					    AI_Mode_3_Register);
 #endif
 			interrupt_a_enable |= AI_STOP_Interrupt_Enable;
 			break;
@@ -2552,10 +2624,10 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		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);
+			    interrupt_a_enable, 1);
 
 		MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",
-			devpriv->int_a_enable_reg);
+			 devpriv->int_a_enable_reg);
 	} else {
 		/* interrupt on nothing */
 		ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
@@ -2570,14 +2642,14 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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);
+				    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);
+				    AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm |
+				    AI_SC_Arm, AI_Command_1_Register);
 		break;
 	}
 
@@ -2594,7 +2666,7 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	case TRIG_NOW:
 		/* AI_START1_Pulse */
 		devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
-			AI_Command_2_Register);
+				    AI_Command_2_Register);
 		s->async->inttrig = NULL;
 		break;
 	case TRIG_EXT:
@@ -2611,23 +2683,26 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+			 unsigned int trignum)
 {
 	if (trignum != 0)
 		return -EINVAL;
 
 	devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
-		AI_Command_2_Register);
+			    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_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)
+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;
@@ -2666,7 +2741,7 @@ static int ni_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice
 			devpriv->ai_calib_source = calib_source;
 			if (boardtype.reg_type == ni_reg_611x) {
 				ni_writeb(calib_source_adjust,
-					Cal_Gain_Select_611x);
+					  Cal_Gain_Select_611x);
 			}
 		}
 		return 2;
@@ -2677,8 +2752,10 @@ static int ni_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice
 	return -EINVAL;
 }
 
-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_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;
@@ -2730,8 +2807,7 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev, struct comedi_sub
 			a = data[4];
 			b = data[3];
 			modebits =
-				((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >>
-				4);
+			    ((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >> 4);
 		}
 		devpriv->atrig_low = a;
 		devpriv->atrig_high = b;
@@ -2776,7 +2852,8 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev, struct comedi_sub
 
 /* 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)
+			void *data, unsigned int num_bytes,
+			unsigned int chan_index)
 {
 	struct comedi_async *async = s->async;
 	unsigned int range;
@@ -2799,8 +2876,9 @@ static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 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)
+					  struct comedi_subdevice *s,
+					  unsigned int chanspec[],
+					  unsigned int n_chans, int timed)
 {
 	unsigned int range;
 	unsigned int chan;
@@ -2811,7 +2889,8 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
 	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(devpriv->ao_conf[i],
+				  M_Offset_AO_Config_Bank(i));
 			ni_writeb(0xf, M_Offset_AO_Waveform_Order(i));
 		}
 	}
@@ -2834,16 +2913,16 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
 		case 4000000:
 			conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
 			ni_writeb(MSeries_Attenuate_x5_Bit,
-				M_Offset_AO_Reference_Attenuation(chan));
+				  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));
+				  M_Offset_AO_Reference_Attenuation(chan));
 			break;
 		default:
 			printk("%s: bug! unhandled ao reference voltage\n",
-				__func__);
+			       __func__);
 			break;
 		}
 		switch (krange->max + krange->min) {
@@ -2855,7 +2934,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
 			break;
 		default:
 			printk("%s: bug! unhandled ao offset voltage\n",
-				__func__);
+			       __func__);
 			break;
 		}
 		if (timed)
@@ -2867,8 +2946,10 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
 	return invert;
 }
 
-static int ni_old_ao_config_chanlist(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int chanspec[], unsigned int n_chans)
+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;
@@ -2902,7 +2983,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, struct comedi_su
 		/* analog reference */
 		/* AREF_OTHER connects AO ground to AI ground, i think */
 		conf |= (CR_AREF(chanspec[i]) ==
-			AREF_OTHER) ? AO_Ground_Ref : 0;
+			 AREF_OTHER) ? AO_Ground_Ref : 0;
 
 		ni_writew(conf, AO_Configuration);
 		devpriv->ao_conf[chan] = conf;
@@ -2910,25 +2991,30 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, struct comedi_su
 	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)
+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);
+						      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)
+
+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)
+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;
@@ -2941,13 +3027,14 @@ static int ni_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *
 		ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
 	} else
 		ni_writew(data[0] ^ invert,
-			(chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
+			  (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)
+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;
@@ -2963,16 +3050,17 @@ static int ni_ao_insn_write_671x(struct comedi_device *dev, struct comedi_subdev
 	return 1;
 }
 
-static int ni_ao_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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])
-		{
+		switch (data[1]) {
 		case COMEDI_OUTPUT:
 			data[2] = 1 + boardtype.ao_fifo_depth * sizeof(short);
-			if (devpriv->mite) data[2] += devpriv->mite->fifo_size;
+			if (devpriv->mite)
+				data[2] += devpriv->mite->fifo_size;
 			break;
 		case COMEDI_INPUT:
 			data[2] = 0;
@@ -2990,7 +3078,7 @@ static int ni_ao_insn_config(struct comedi_device *dev, struct comedi_subdevice
 }
 
 static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+			 unsigned int trignum)
 {
 	int ret;
 	int interrupt_b_bits;
@@ -3006,7 +3094,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 	s->async->inttrig = NULL;
 
 	ni_set_bits(dev, Interrupt_B_Enable_Register,
-		AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
+		    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);
@@ -3027,35 +3115,34 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
 #endif
 
 	devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
-		AO_Mode_3_Register);
+			    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++) {
 		udelay(1);
 		if ((devpriv->stc_readw(dev,
 					Joint_Status_2_Register) &
-				AO_TMRDACWRs_In_Progress_St) == 0)
+		     AO_TMRDACWRs_In_Progress_St) == 0)
 			break;
 	}
 	if (i == timeout) {
 		comedi_error(dev,
-			"timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
+			     "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);
+			    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->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);
+			    AO_Command_2_Register);
 
 	return 0;
 }
@@ -3104,18 +3191,20 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	case TRIG_INT:
 	case TRIG_NOW:
 		devpriv->ao_trigger_select &=
-			~(AO_START1_Polarity | AO_START1_Select(-1));
+		    ~(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);
+				    AO_Trigger_Select_Register);
 		break;
 	case TRIG_EXT:
-                devpriv->ao_trigger_select = AO_START1_Select(CR_CHAN(cmd->start_arg)+1);
+		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) */
+			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);
+			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();
@@ -3137,17 +3226,19 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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)
-		{
+		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);
+					    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:
@@ -3162,21 +3253,21 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	}
 
 	devpriv->ao_mode1 &=
-		~(AO_UI_Source_Select(0x1f) | AO_UI_Source_Polarity |
-		AO_UPDATE_Source_Select(0x1f) | AO_UPDATE_Source_Polarity);
+	    ~(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);
+		    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);
+		    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;
@@ -3188,34 +3279,34 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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);
+	    ~(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);
+				    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)) {
+		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]));
+			bits |=
+			    AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]));
 		}
-		devpriv->stc_writew(dev, bits,
-			AO_Output_Control_Register);
+		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);
+			    AO_Command_1_Register);
 
 	devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error;
 	devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
@@ -3230,7 +3321,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
 
 	bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
-		AO_TMRDACWR_Pulse_Width;
+	    AO_TMRDACWR_Pulse_Width;
 	if (boardtype.ao_fifo_depth)
 		bits |= AO_FIFO_Enable;
 	else
@@ -3249,9 +3340,9 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (cmd->stop_src == TRIG_COUNT) {
 		devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack,
-			Interrupt_B_Ack_Register);
+				    Interrupt_B_Ack_Register);
 		ni_set_bits(dev, Interrupt_B_Enable_Register,
-			AO_BC_TC_Interrupt_Enable, 1);
+			    AO_BC_TC_Interrupt_Enable, 1);
 	}
 
 	s->async->inttrig = &ni_ao_inttrig;
@@ -3260,7 +3351,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+			 struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -3365,9 +3456,11 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	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));
+		    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++;
 	}
@@ -3398,7 +3491,7 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
 	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);
+			    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;
@@ -3416,12 +3509,11 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
 	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);
+			    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)
-		{
+		for (i = 0; i < s->n_chan; ++i) {
 			immediate_bits |= 1 << i;
 		}
 		ao_win_out(immediate_bits, AO_Immediate_671x);
@@ -3434,12 +3526,13 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
 
 /* digital io */
 
-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_config(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data)
 {
 #ifdef DEBUG_DIO
 	printk("ni_dio_insn_config() chan=%d io=%d\n",
-		CR_CHAN(insn->chanspec), data[0]);
+	       CR_CHAN(insn->chanspec), data[0]);
 #endif
 	switch (data[0]) {
 	case INSN_CONFIG_DIO_OUTPUT:
@@ -3450,9 +3543,9 @@ static int ni_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->io_bits & (1 << CR_CHAN(insn->
-					chanspec))) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (s->
+		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
+		    COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -3466,8 +3559,9 @@ static int ni_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
 	return 1;
 }
 
-static int ni_dio_insn_bits(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)
 {
 #ifdef DEBUG_DIO
 	printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
@@ -3478,7 +3572,7 @@ static int ni_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
 		/* 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)
+		    && devpriv->serial_interval_ns)
 			return -EBUSY;
 
 		s->state &= ~data[0];
@@ -3486,7 +3580,7 @@ static int ni_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
 		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);
+				    DIO_Output_Register);
 	}
 	data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
 
@@ -3494,11 +3588,13 @@ static int ni_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
 }
 
 static int ni_m_series_dio_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				       struct comedi_subdevice *s,
+				       struct comedi_insn *insn,
+				       unsigned int *data)
 {
 #ifdef DEBUG_DIO
 	printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
-		CR_CHAN(insn->chanspec), data[0]);
+	       CR_CHAN(insn->chanspec), data[0]);
 #endif
 	switch (data[0]) {
 	case INSN_CONFIG_DIO_OUTPUT:
@@ -3509,9 +3605,9 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->io_bits & (1 << CR_CHAN(insn->
-					chanspec))) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (s->
+		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
+		    COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -3523,12 +3619,14 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev,
 	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)
+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
 	printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0],
-		data[1]);
+	       data[1]);
 #endif
 	if (insn->n != 2)
 		return -EINVAL;
@@ -3542,8 +3640,8 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev, struct comedi_su
 	return 2;
 }
 
-static int ni_cdio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int ni_cdio_cmdtest(struct comedi_device *dev,
+			   struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -3606,7 +3704,7 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	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);
+				     CR_INVERT);
 		if (tmp != cmd->scan_begin_arg) {
 			err++;
 		}
@@ -3661,8 +3759,8 @@ static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	switch (cmd->scan_begin_src) {
 	case TRIG_EXT:
 		cdo_mode_bits |=
-			CR_CHAN(cmd->
-			scan_begin_arg) & CDO_Sample_Source_Select_Mask;
+		    CR_CHAN(cmd->scan_begin_arg) &
+		    CDO_Sample_Source_Select_Mask;
 		break;
 	default:
 		BUG();
@@ -3677,7 +3775,7 @@ static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		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");
+			     "attempted to run digital output command with no lines configured as outputs");
 		return -EIO;
 	}
 	retval = ni_request_cdo_mite_channel(dev);
@@ -3689,7 +3787,7 @@ static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+			  unsigned int trignum)
 {
 #ifdef PCIDMA
 	unsigned long flags;
@@ -3732,16 +3830,17 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *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);
+		  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);
+		  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);
@@ -3766,11 +3865,11 @@ static void handle_cdio_interrupt(struct comedi_device *dev)
 	spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
 	if (devpriv->cdo_mite_chan) {
 		unsigned cdo_mite_status =
-			mite_get_status(devpriv->cdo_mite_chan);
+		    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));
+			       devpriv->mite->mite_io_addr +
+			       MITE_CHOR(devpriv->cdo_mite_chan->channel));
 		}
 		mite_sync_output_dma(devpriv->cdo_mite_chan, s->async);
 	}
@@ -3786,14 +3885,15 @@ static void handle_cdio_interrupt(struct comedi_device *dev)
 	if (cdio_status & CDO_FIFO_Empty_Bit) {
 /* printk("cdio fifo empty\n"); */
 		ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
-			M_Offset_CDIO_Command);
+			  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)
+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;
@@ -3813,7 +3913,7 @@ static int ni_serial_insn_config(struct comedi_device *dev, struct comedi_subdev
 		if (data[1] == SERIAL_DISABLED) {
 			devpriv->serial_hw_mode = 0;
 			devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
-				DIO_Software_Serial_Control);
+						  DIO_Software_Serial_Control);
 			data[1] = SERIAL_DISABLED;
 			devpriv->serial_interval_ns = data[1];
 		} else if (data[1] <= SERIAL_600NS) {
@@ -3827,13 +3927,13 @@ static int ni_serial_insn_config(struct comedi_device *dev, struct comedi_subdev
 		} 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;
+			    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;
+			    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
@@ -3842,16 +3942,16 @@ static int ni_serial_insn_config(struct comedi_device *dev, struct comedi_subdev
 			devpriv->serial_interval_ns = data[1];
 		} else {
 			devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
-				DIO_Software_Serial_Control);
+						  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);
+				    DIO_Control_Register);
 		devpriv->stc_writew(dev, devpriv->clock_and_fout,
-			Clock_and_FOUT_Register);
+				    Clock_and_FOUT_Register);
 		return 1;
 
 		break;
@@ -3866,10 +3966,10 @@ static int ni_serial_insn_config(struct comedi_device *dev, struct comedi_subdev
 
 		if (devpriv->serial_hw_mode) {
 			err = ni_serial_hw_readwrite8(dev, s, byte_out,
-				&byte_in);
+						      &byte_in);
 		} else if (devpriv->serial_interval_ns > 0) {
 			err = ni_serial_sw_readwrite8(dev, s, byte_out,
-				&byte_in);
+						      &byte_in);
 		} else {
 			printk("ni_serial_insn_config: serial disabled!\n");
 			return -EINVAL;
@@ -3886,8 +3986,10 @@ static int ni_serial_insn_config(struct comedi_device *dev, struct comedi_subdev
 
 }
 
-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_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;
@@ -3912,14 +4014,14 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, struct comedi_subd
 
 	/* 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) {
+		devpriv->stc_readw(dev,
+				   Joint_Status_1_Register)) &
+	       DIO_Serial_IO_In_Progress_St) {
 		/* Delay one bit per loop */
 		udelay((devpriv->serial_interval_ns + 999) / 1000);
 		if (--count < 0) {
 			printk
-				("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
+			    ("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
 			err = -ETIME;
 			goto Error;
 		}
@@ -3936,14 +4038,16 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, struct comedi_subd
 #endif
 	}
 
-      Error:
+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)
+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;
 
@@ -3963,25 +4067,26 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, struct comedi_subd
 			devpriv->dio_output |= DIO_SDOUT;
 		}
 		devpriv->stc_writew(dev, devpriv->dio_output,
-			DIO_Output_Register);
+				    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);
+				    DIO_Control_Register);
 
 		udelay((devpriv->serial_interval_ns + 999) / 2000);
 
 		devpriv->dio_control &= ~DIO_Software_Serial_Control;
 		devpriv->stc_writew(dev, devpriv->dio_control,
-			DIO_Control_Register);
+				    DIO_Control_Register);
 
 		udelay((devpriv->serial_interval_ns + 999) / 2000);
 
 		/* Input current bit */
 		if (devpriv->stc_readw(dev,
-				DIO_Parallel_Input_Register) & DIO_SDIN) {
+				       DIO_Parallel_Input_Register) & DIO_SDIN)
+		{
 /*			printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
 			input |= mask;
 		}
@@ -4010,10 +4115,9 @@ static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int i;
 
-	for (i = 0; i < s->n_chan; i++)
-	{
+	for (i = 0; i < s->n_chan; i++) {
 		ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
-			AO_Configuration_2_67xx);
+			       AO_Configuration_2_67xx);
 	}
 	ao_win_out(0x0, AO_Later_Single_Point_Updates);
 }
@@ -4102,7 +4206,7 @@ static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
 		break;
 	default:
 		printk("%s: unhandled register 0x%x in switch.\n",
-			__func__, reg);
+		       __func__, reg);
 		BUG();
 		return 0;
 		break;
@@ -4111,16 +4215,16 @@ static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
 }
 
 static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
-	enum ni_gpct_register reg)
+				   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;
+	    G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable;
 	static const unsigned gpct_interrupt_b_enable_mask =
-		G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable;
+	    G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable;
 
 	switch (reg) {
 		/* m-series-only registers */
@@ -4162,12 +4266,12 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
 	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);
+				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);
+				gpct_interrupt_b_enable_mask, bits);
 		break;
 	case NITIO_G01_Joint_Reset_Reg:
 		BUG_ON(bits & ~gpct_joint_reset_mask);
@@ -4179,7 +4283,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
 }
 
 static unsigned ni_gpct_read_register(struct ni_gpct *counter,
-	enum ni_gpct_register reg)
+				      enum ni_gpct_register reg)
 {
 	struct comedi_device *dev = counter->counter_dev->dev;
 	unsigned stc_register;
@@ -4211,27 +4315,30 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter,
 }
 
 static int ni_freq_out_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+				 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)
+				  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);
+			    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);
+			    Clock_and_FOUT_Register);
 	return insn->n;
 }
 
-static int ni_set_freq_out_clock(struct comedi_device *dev, unsigned int clock_source)
+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:
@@ -4244,12 +4351,13 @@ static int ni_set_freq_out_clock(struct comedi_device *dev, unsigned int clock_s
 		return -EINVAL;
 	}
 	devpriv->stc_writew(dev, devpriv->clock_and_fout,
-		Clock_and_FOUT_Register);
+			    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)
+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;
@@ -4260,8 +4368,9 @@ static void ni_get_freq_out_clock(struct comedi_device *dev, unsigned int *clock
 	}
 }
 
-static int ni_freq_out_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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:
@@ -4312,7 +4421,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (boardtype.n_adchan) {
 		s->type = COMEDI_SUBD_AI;
 		s->subdev_flags =
-			SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
+		    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)
@@ -4387,7 +4496,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
 	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 */ ;
+		    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;
@@ -4463,7 +4572,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
 		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));
+				  M_Offset_PFI_Output_Select(i + 1));
 		}
 	} else {
 		s->n_chan = 10;
@@ -4517,15 +4626,17 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
 		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);
+							&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 */ ;
+		    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;
@@ -4561,32 +4672,33 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
 	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;
+		    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;
+		    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);
+			    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);
+				    (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 */
@@ -4600,7 +4712,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
 		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));
+				  M_Offset_AO_Reference_Attenuation(channel));
 		}
 		ni_writeb(0x0, M_Offset_AO_Calibration);
 	}
@@ -4611,7 +4723,7 @@ static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
 
 static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
 {
-	struct comedi_device *dev = (struct comedi_device *) arg;
+	struct comedi_device *dev = (struct comedi_device *)arg;
 
 	if (dir) {
 		ni_writeb(data, Port_A + 2 * port);
@@ -4625,8 +4737,9 @@ static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
 	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)
+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));
 
@@ -4646,9 +4759,9 @@ static int ni_read_eeprom(struct comedi_device *dev, int addr)
 	ni_writeb(0x04, Serial_Command);
 	for (bit = 0x8000; bit; bit >>= 1) {
 		ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
-			Serial_Command);
+			  Serial_Command);
 		ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
-			Serial_Command);
+			  Serial_Command);
 	}
 	bitstring = 0;
 	for (bit = 0x80; bit; bit >>= 1) {
@@ -4662,7 +4775,9 @@ static int ni_read_eeprom(struct comedi_device *dev, int addr)
 }
 
 static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+					struct comedi_subdevice *s,
+					struct comedi_insn *insn,
+					unsigned int *data)
 {
 	data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
 
@@ -4676,8 +4791,9 @@ static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
 	return 3;
 }
 
-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_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]) {
@@ -4685,16 +4801,16 @@ static int ni_m_series_pwm_config(struct comedi_device *dev, struct comedi_subde
 		switch (data[1]) {
 		case TRIG_ROUND_NEAREST:
 			up_count =
-				(data[2] +
-				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			    (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;
+			    (data[2] + devpriv->clock_ns -
+			     1) / devpriv->clock_ns;
 			break;
 		default:
 			return -EINVAL;
@@ -4703,30 +4819,30 @@ static int ni_m_series_pwm_config(struct comedi_device *dev, struct comedi_subde
 		switch (data[3]) {
 		case TRIG_ROUND_NEAREST:
 			down_count =
-				(data[4] +
-				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			    (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;
+			    (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]) {
+		    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);
+			  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;
@@ -4741,8 +4857,9 @@ static int ni_m_series_pwm_config(struct comedi_device *dev, struct comedi_subde
 	return 0;
 }
 
-static int ni_6143_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)
 {
 	unsigned up_count, down_count;
 	switch (data[0]) {
@@ -4750,16 +4867,16 @@ static int ni_6143_pwm_config(struct comedi_device *dev, struct comedi_subdevice
 		switch (data[1]) {
 		case TRIG_ROUND_NEAREST:
 			up_count =
-				(data[2] +
-				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			    (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;
+			    (data[2] + devpriv->clock_ns -
+			     1) / devpriv->clock_ns;
 			break;
 		default:
 			return -EINVAL;
@@ -4768,23 +4885,23 @@ static int ni_6143_pwm_config(struct comedi_device *dev, struct comedi_subdevice
 		switch (data[3]) {
 		case TRIG_ROUND_NEAREST:
 			down_count =
-				(data[4] +
-				devpriv->clock_ns / 2) / devpriv->clock_ns;
+			    (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;
+			    (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]) {
+		    down_count * devpriv->clock_ns != data[4]) {
 			data[2] = up_count * devpriv->clock_ns;
 			data[4] = down_count * devpriv->clock_ns;
 			return -EAGAIN;
@@ -4808,16 +4925,18 @@ 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)
+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)
+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)];
 
@@ -4884,7 +5003,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
 			type = boardtype.caldac[i];
 			for (j = 0; j < caldacs[type].n_chans; j++) {
 				maxdata_list[chan] =
-					(1 << caldacs[type].n_bits) - 1;
+				    (1 << caldacs[type].n_bits) - 1;
 				chan++;
 			}
 		}
@@ -4948,8 +5067,8 @@ static int pack_mb88341(int addr, int val, int *bitstring)
 	 */
 	addr++;
 	*bitstring = ((addr & 0x1) << 11) |
-		((addr & 0x2) << 9) |
-		((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
+	    ((addr & 0x2) << 9) |
+	    ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
 	return 12;
 }
 
@@ -4993,11 +5112,11 @@ static int GPCT_G_Watch(struct comedi_device *dev, int chan)
 
 	devpriv->gpct_command[chan] &= ~G_Save_Trace;
 	devpriv->stc_writew(dev, devpriv->gpct_command[chan],
-		G_Command_Register(chan));
+			    G_Command_Register(chan));
 
 	devpriv->gpct_command[chan] |= G_Save_Trace;
 	devpriv->stc_writew(dev, devpriv->gpct_command[chan],
-		G_Command_Register(chan));
+			    G_Command_Register(chan));
 
 	/* This procedure is used because the two registers cannot
 	 * be read atomically. */
@@ -5021,37 +5140,37 @@ static void GPCT_Reset(struct comedi_device *dev, int 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);
+			    G0_TC_Interrupt_Enable, 0);
 		ni_set_bits(dev, Interrupt_A_Enable_Register,
-			G0_Gate_Interrupt_Enable, 0);
+			    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);
+				    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);
+				    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);
+			    G1_TC_Interrupt_Enable, 0);
 		ni_set_bits(dev, Interrupt_B_Enable_Register,
-			G0_Gate_Interrupt_Enable, 0);
+			    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);
+				    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);
+				    Analog_Trigger_Etc_Register);
 		break;
 	};
 
@@ -5062,9 +5181,9 @@ static void GPCT_Reset(struct comedi_device *dev, int chan)
 	devpriv->gpct_command[chan] |= G_Synchronized_Gate;
 
 	devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
-		G_Mode_Register(chan));
+			    G_Mode_Register(chan));
 	devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
-		G_Input_Select_Register(chan));
+			    G_Input_Select_Register(chan));
 	devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
 
 	/* printk("exit GPCT_Reset\n"); */
@@ -5072,22 +5191,25 @@ static void GPCT_Reset(struct comedi_device *dev, int chan)
 
 #endif
 
-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_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)
+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)
+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);
@@ -5101,10 +5223,10 @@ static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 /* const struct comedi_cmd *cmd = &s->async->cmd; */
 
 	retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
-		COMEDI_INPUT);
+					      COMEDI_INPUT);
 	if (retval) {
 		comedi_error(dev,
-			"no dma channel available for use by counter");
+			     "no dma channel available for use by counter");
 		return retval;
 	}
 	ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
@@ -5116,8 +5238,8 @@ static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	return retval;
 }
 
-static int ni_gpct_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+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;
@@ -5150,7 +5272,7 @@ static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
  */
 
 static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
-	unsigned source)
+				       unsigned source)
 {
 	unsigned pfi_reg_index;
 	unsigned array_offset;
@@ -5159,16 +5281,16 @@ static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
 	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);
+	    ~MSeries_PFI_Output_Select_Mask(chan);
 	devpriv->pfi_output_select_reg[array_offset] |=
-		MSeries_PFI_Output_Select_Bits(chan, source);
+	    MSeries_PFI_Output_Select_Bits(chan, source);
 	ni_writew(devpriv->pfi_output_select_reg[array_offset],
-		M_Offset_PFI_Output_Select(pfi_reg_index));
+		  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)
+				  unsigned source)
 {
 	/*  pre-m-series boards have fixed signals on pfi pins */
 	if (source != ni_old_get_pfi_routing(dev, chan))
@@ -5177,7 +5299,7 @@ static int ni_old_set_pfi_routing(struct comedi_device *dev, unsigned chan,
 }
 
 static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan,
-	unsigned source)
+			      unsigned source)
 {
 	if (boardtype.reg_type & ni_reg_m_series_mask)
 		return ni_m_series_set_pfi_routing(dev, chan, source);
@@ -5185,11 +5307,14 @@ static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan,
 		return ni_old_set_pfi_routing(dev, chan, source);
 }
 
-static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev, unsigned chan)
+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]);
+						devpriv->
+						pfi_output_select_reg
+						[array_offset]);
 }
 
 static unsigned ni_old_get_pfi_routing(struct comedi_device *dev, unsigned chan)
@@ -5242,7 +5367,7 @@ static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
 }
 
 static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
-	enum ni_pfi_filter_select filter)
+			    enum ni_pfi_filter_select filter)
 {
 	unsigned bits;
 	if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
@@ -5255,8 +5380,9 @@ static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
 	return 0;
 }
 
-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_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;
@@ -5270,8 +5396,9 @@ static int ni_pfi_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
 	return 2;
 }
 
-static int ni_pfi_insn_config(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)
 {
 	unsigned int chan;
 
@@ -5289,9 +5416,8 @@ static int ni_pfi_insn_config(struct comedi_device *dev, struct comedi_subdevice
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(devpriv->
-			io_bidirection_pin_reg & (1 << chan)) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (devpriv->io_bidirection_pin_reg & (1 << chan)) ?
+		    COMEDI_OUTPUT : COMEDI_INPUT;
 		return 0;
 		break;
 	case INSN_CONFIG_SET_ROUTING:
@@ -5325,23 +5451,26 @@ static void ni_rtsi_init(struct comedi_device *dev)
 	}
 	/*  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);
+	    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);
+			    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);
+	    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);
+		    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);
+			    RTSI_Trig_B_Output_Register);
 
 /*
 * Sets the source and direction of the 4 on board lines
@@ -5349,8 +5478,9 @@ 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_bits(struct comedi_device *dev,
+			     struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -5363,8 +5493,9 @@ static int ni_rtsi_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 /* 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 *freq_divider,
+					 unsigned *freq_multiplier,
+					 unsigned *actual_period_ns)
 {
 	unsigned div;
 	unsigned best_div = 1;
@@ -5383,9 +5514,9 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
 	for (div = 1; div <= max_div; ++div) {
 		for (mult = 1; mult <= max_mult; ++mult) {
 			unsigned new_period_ps =
-				(reference_picosec * div) / mult;
+			    (reference_picosec * div) / mult;
 			if (abs(new_period_ps - target_picosec) <
-				abs(best_period_picosec - target_picosec)) {
+			    abs(best_period_picosec - target_picosec)) {
 				best_period_picosec = new_period_ps;
 				best_div = div;
 				best_mult = mult;
@@ -5393,15 +5524,14 @@ static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
 		}
 	}
 	if (best_period_picosec == 0) {
-		printk("%s: bug, failed to find pll parameters\n",
-			__func__);
+		printk("%s: bug, failed to find pll parameters\n", __func__);
 		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;
+	    (best_period_picosec * fudge_factor_80_to_20Mhz +
+	     (pico_per_nano / 2)) / pico_per_nano;
 	return 0;
 }
 
@@ -5413,8 +5543,8 @@ static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
 		return 7;
 }
 
-static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned source,
-	unsigned period_ns)
+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;
@@ -5429,34 +5559,36 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned s
 	/*  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) {
 		printk
-			("%s: you must specify an input clock frequency between %i and %i nanosec "
-			"for the phased-lock loop.\n", __func__,
-			min_period_ns, max_period_ns);
+		    ("%s: you must specify an input clock frequency between %i and %i nanosec "
+		     "for the phased-lock loop.\n", __func__,
+		     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);
+			    RTSI_Trig_Direction_Register);
 	pll_control_bits =
-		MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
+	    MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
 	devpriv->clock_and_fout2 |=
-		MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit;
+	    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;
+		    MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
 		retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
-			&freq_multiplier, &devpriv->clock_ns);
+						       &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;
+		    MSeries_PLL_In_Source_Select_PXI_Clock10;
 		retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
-			&freq_multiplier, &devpriv->clock_ns);
+						       &freq_multiplier,
+						       &devpriv->clock_ns);
 		if (retval < 0)
 			return retval;
 		break;
@@ -5465,20 +5597,22 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned s
 			unsigned rtsi_channel;
 			static const unsigned max_rtsi_channel = 7;
 			for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
-				++rtsi_channel) {
+			     ++rtsi_channel) {
 				if (source ==
-					NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) {
+				    NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) {
 					devpriv->clock_and_fout2 |=
-						MSeries_PLL_In_Source_Select_RTSI_Bits
-						(rtsi_channel);
+					    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);
+							       &freq_divider,
+							       &freq_multiplier,
+							       &devpriv->
+							       clock_ns);
 			if (retval < 0)
 				return retval;
 		}
@@ -5486,8 +5620,8 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned s
 	}
 	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);
+	    MSeries_PLL_Divisor_Bits(freq_divider) |
+	    MSeries_PLL_Multiplier_Bits(freq_multiplier);
 
 	/* printk("using divider=%i, multiplier=%i for PLL. pll_control_bits = 0x%x\n",
 	 * freq_divider, freq_multiplier, pll_control_bits); */
@@ -5503,45 +5637,46 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned s
 	}
 	if (i == timeout) {
 		printk
-			("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
-			__func__, source, period_ns);
+		    ("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
+		     __func__, source, period_ns);
 		return -ETIMEDOUT;
 	}
 	return 3;
 }
 
 static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
-	unsigned period_ns)
+			       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);
+				    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);
+			    ~(MSeries_Timebase1_Select_Bit |
+			      MSeries_Timebase3_Select_Bit);
 			ni_writew(devpriv->clock_and_fout2,
-				M_Offset_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);
+							       period_ns);
 		} else {
 			if (source == NI_MIO_RTSI_CLOCK) {
 				devpriv->rtsi_trig_direction_reg |=
-					Use_RTSI_Clock_Bit;
+				    Use_RTSI_Clock_Bit;
 				devpriv->stc_writew(dev,
-					devpriv->rtsi_trig_direction_reg,
-					RTSI_Trig_Direction_Register);
+						    devpriv->
+						    rtsi_trig_direction_reg,
+						    RTSI_Trig_Direction_Register);
 				if (period_ns == 0) {
 					printk
-						("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
-						__func__);
+					    ("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
+					     __func__);
 					return -EINVAL;
 				} else {
 					devpriv->clock_ns = period_ns;
@@ -5555,7 +5690,7 @@ static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
 }
 
 static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
-	unsigned source)
+				       unsigned source)
 {
 	if (chan >= num_configurable_rtsi_channels(dev)) {
 		if (chan == old_RTSI_clock_channel) {
@@ -5563,9 +5698,8 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
 				return 1;
 			else {
 				printk
-					("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
-					__func__, chan,
-					old_RTSI_clock_channel);
+				    ("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
+				     __func__, chan, old_RTSI_clock_channel);
 				return 0;
 			}
 		}
@@ -5596,22 +5730,22 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
 }
 
 static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
-	unsigned source)
+			       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);
+		    RTSI_Trig_Output_Bits(chan, source);
 		devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
-			RTSI_Trig_A_Output_Register);
+				    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);
+		    RTSI_Trig_Output_Bits(chan, source);
 		devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
-			RTSI_Trig_B_Output_Register);
+				    RTSI_Trig_B_Output_Register);
 	}
 	return 2;
 }
@@ -5620,10 +5754,10 @@ 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);
+					       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);
+					       devpriv->rtsi_trig_b_output_reg);
 	} else {
 		if (chan == old_RTSI_clock_channel)
 			return NI_RTSI_OUTPUT_RTSI_OSC;
@@ -5632,53 +5766,54 @@ static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan)
 	}
 }
 
-static int ni_rtsi_insn_config(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)
 {
 	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);
+			    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;
+			    Drive_RTSI_Clock_Bit;
 		}
 		devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
-			RTSI_Trig_Direction_Register);
+				    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);
+			    ~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;
+			    ~Drive_RTSI_Clock_Bit;
 		}
 		devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
-			RTSI_Trig_Direction_Register);
+				    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;
+			    (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;
+			    (devpriv->rtsi_trig_direction_reg &
+			     Drive_RTSI_Clock_Bit)
+			    ? INSN_CONFIG_DIO_OUTPUT : INSN_CONFIG_DIO_INPUT;
 		}
 		return 2;
 		break;
@@ -5751,12 +5886,12 @@ static void cs5529_command(struct comedi_device *dev, unsigned short value)
 
 /* write to cs5529 register */
 static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
-	unsigned int reg_select_bits)
+				unsigned int reg_select_bits)
 {
 	ni_ao_win_outw(dev, ((value >> 16) & 0xff),
-		CAL_ADC_Config_Data_High_Word_67xx);
+		       CAL_ADC_Config_Data_High_Word_67xx);
 	ni_ao_win_outw(dev, (value & 0xffff),
-		CAL_ADC_Config_Data_Low_Word_67xx);
+		       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))
@@ -5766,7 +5901,7 @@ static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
 #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 reg_select_bits)
 {
 	unsigned int value;
 
@@ -5775,7 +5910,8 @@ static unsigned int cs5529_config_read(struct comedi_device *dev,
 	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;
+			       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;
 }
@@ -5790,18 +5926,18 @@ static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data)
 	retval = cs5529_wait_for_idle(dev);
 	if (retval) {
 		comedi_error(dev,
-			"timeout or signal in cs5529_do_conversion()");
+			     "timeout or signal in cs5529_do_conversion()");
 		return -ETIME;
 	}
 	status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
 	if (status & CSS_OSC_DETECT) {
 		printk
-			("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
+		    ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
 		return -EIO;
 	}
 	if (status & CSS_OVERRANGE) {
 		printk
-			("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
+		    ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
 	}
 	if (data) {
 		*data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
@@ -5811,8 +5947,9 @@ static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data)
 	return 0;
 }
 
-static int cs5529_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -5840,29 +5977,28 @@ static int cs5529_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 static int init_cs5529(struct comedi_device *dev)
 {
 	unsigned int config_bits =
-		CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+	    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);
+			    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);
+			    CSCMD_CONFIG_REGISTER);
 	if (cs5529_wait_for_idle(dev))
 		comedi_error(dev, "timeout or signal in init_cs5529()\n");
 #endif
 #ifdef NI_CS5529_DEBUG
 	printk("config: 0x%x\n", cs5529_config_read(dev,
-		CSCMD_CONFIG_REGISTER));
-	printk("gain: 0x%x\n", cs5529_config_read(dev,
-		CSCMD_GAIN_REGISTER));
+						    CSCMD_CONFIG_REGISTER));
+	printk("gain: 0x%x\n", cs5529_config_read(dev, CSCMD_GAIN_REGISTER));
 	printk("offset: 0x%x\n", cs5529_config_read(dev,
-		CSCMD_OFFSET_REGISTER));
+						    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
index 4d408d4..b732296 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -82,7 +82,7 @@ static const struct ni_board_struct ni_boards[] = {
 	 .num_p0_dio_channels = 8,
 	 .has_8255 = 0,
 	 .caldac = {dac8800, dac8043},
-	},
+	 },
 	{.device_id = 0x010c,
 	 .name = "DAQCard-ai-16e-4",
 	 .n_adchan = 16,
@@ -98,7 +98,7 @@ static const struct ni_board_struct ni_boards[] = {
 	 .num_p0_dio_channels = 8,
 	 .has_8255 = 0,
 	 .caldac = {mb88341},	/* verified */
-	},
+	 },
 	{.device_id = 0x02c4,
 	 .name = "DAQCard-6062E",
 	 .n_adchan = 16,
@@ -116,7 +116,7 @@ static const struct ni_board_struct ni_boards[] = {
 	 .num_p0_dio_channels = 8,
 	 .has_8255 = 0,
 	 .caldac = {ad8804_debug},	/* verified */
-	},
+	 },
 	{.device_id = 0x075e,
 	 .name = "DAQCard-6024E",	/* specs incorrect! */
 	 .n_adchan = 16,
@@ -134,7 +134,7 @@ static const struct ni_board_struct ni_boards[] = {
 	 .num_p0_dio_channels = 8,
 	 .has_8255 = 0,
 	 .caldac = {ad8804_debug},
-	},
+	 },
 	{.device_id = 0x0245,
 	 .name = "DAQCard-6036E",	/* specs incorrect! */
 	 .n_adchan = 16,
@@ -152,7 +152,7 @@ static const struct ni_board_struct ni_boards[] = {
 	 .num_p0_dio_channels = 8,
 	 .has_8255 = 0,
 	 .caldac = {ad8804_debug},
-	},
+	 },
 #if 0
 	{.device_id = 0x0000,	/* unknown */
 	 .name = "DAQCard-6715",
@@ -162,7 +162,7 @@ static const struct ni_board_struct ni_boards[] = {
 	 .ao_671x = 8192,
 	 .num_p0_dio_channels = 8,
 	 .caldac = {mb88341, mb88341},
-	},
+	 },
 #endif
 	/* N.B. Update ni_mio_cs_ids[] when entries added above. */
 };
@@ -227,7 +227,8 @@ static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr)
 	return ret;
 }
 
-static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -238,7 +239,8 @@ static struct comedi_driver driver_ni_mio_cs = {
 
 #include "ni_mio_common.c"
 
-static int ni_getboardtype(struct comedi_device *dev, struct pcmcia_device *link);
+static int ni_getboardtype(struct comedi_device *dev,
+			   struct pcmcia_device *link);
 
 /* clean up allocated resources */
 /* called when driver is removed */
@@ -266,6 +268,7 @@ static dev_node_t dev_node = {
 	COMEDI_MAJOR, 0,
 	NULL
 };
+
 static int cs_attach(struct pcmcia_device *link)
 {
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
@@ -340,7 +343,7 @@ static void mio_cs_config(struct pcmcia_device *link)
 	tuple.DesiredTuple = CISTPL_MANFID;
 	tuple.Attributes = TUPLE_RETURN_COMMON;
 	if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
-		(pcmcia_get_tuple_data(link, &tuple) == 0)) {
+	    (pcmcia_get_tuple_data(link, &tuple) == 0)) {
 		manfid = le16_to_cpu(buf[0]);
 		prodid = le16_to_cpu(buf[1]);
 	}
@@ -373,7 +376,7 @@ static void mio_cs_config(struct pcmcia_device *link)
 #endif
 	link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
 	link->io.IOAddrLines =
-		parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
+	    parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
 	link->io.NumPorts2 = 0;
 
 	{
@@ -421,7 +424,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	irq = link->irq.AssignedIRQ;
 
 	printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
-		dev->minor, dev->driver->driver_name, dev->iobase, irq);
+	       dev->minor, dev->driver->driver_name, dev->iobase, irq);
 
 #if 0
 	{
@@ -430,7 +433,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		printk(" board fingerprint:");
 		for (i = 0; i < 32; i += 2) {
 			printk(" %04x %02x", inw(dev->iobase + i),
-				inb(dev->iobase + i + 1));
+			       inb(dev->iobase + i + 1));
 		}
 		printk("\n");
 		printk(" board fingerprint (windowed):");
@@ -447,7 +450,7 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	dev->board_name = boardtype.name;
 
 	ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
-				 "ni_mio_cs", dev);
+			  "ni_mio_cs", dev);
 	if (ret < 0) {
 		printk(" irq not available\n");
 		return -EINVAL;
@@ -484,14 +487,15 @@ static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
 	tuple.DesiredTuple = CISTPL_MANFID;
 	tuple.Attributes = TUPLE_RETURN_COMMON;
 	if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
-		(pcmcia_get_tuple_data(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)
+static int ni_getboardtype(struct comedi_device *dev,
+			   struct pcmcia_device *link)
 {
 	int id;
 	int i;
@@ -532,7 +536,7 @@ struct pcmcia_driver ni_mio_cs_driver = {
 	.id_table = ni_mio_cs_ids,
 	.owner = THIS_MODULE,
 	.drv = {
-			.name = dev_info,
+		.name = dev_info,
 		},
 };
 
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 6b86a39..52b2eca 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -212,6 +212,7 @@ static inline unsigned primary_DMAChannel_bits(unsigned channel)
 {
 	return channel & 0x3;
 }
+
 static inline unsigned secondary_DMAChannel_bits(unsigned channel)
 {
 	return (channel << 2) & 0xc;
@@ -290,7 +291,8 @@ enum FPGA_Control_Bits {
 
 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 int ni_pcidio_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s);
 
 static struct comedi_driver driver_pcidio = {
 	.driver_name = "ni_pcidio",
@@ -310,83 +312,84 @@ struct nidio_board {
 
 static const struct nidio_board nidio_boards[] = {
 	{
-	.dev_id = 0x1150,
-	.name = "pci-dio-32hs",
-	.n_8255 = 0,
-	.is_diodaq = 1,
-		},
+	 .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 = 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 = 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 = 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 = 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 = 0x13c0,
+	 .name = "pxi-6508",
+	 .n_8255 = 4,
+	 .is_diodaq = 0,
+	 },
 	{
-	.dev_id = 0x0400,
-	.name = "pci-6503",
-	.n_8255 = 1,
-	.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 = 0x1250,
+	 .name = "pci-6503b",
+	 .n_8255 = 1,
+	 .is_diodaq = 0,
+	 },
 	{
-	.dev_id = 0x17d0,
-	.name = "pci-6503x",
-	.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,
-		},
+	 .dev_id = 0x1800,
+	 .name = "pxi-6503",
+	 .n_8255 = 1,
+	 .is_diodaq = 0,
+	 },
 };
 
-#define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
+#define n_nidio_boards ARRAY_SIZE(nidio_boards)
 #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}
+	{
+	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);
@@ -402,14 +405,16 @@ struct nidio96_private {
 };
 #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_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 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);
+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);
@@ -426,16 +431,16 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
 	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);
+	    mite_request_channel_in_range(devpriv->mite,
+					  devpriv->di_mite_ring, 1, 2);
 	if (devpriv->di_mite_chan == NULL) {
 		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);
+	       secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
+	       devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
 	mmiowb();
 	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 	return 0;
@@ -452,8 +457,8 @@ static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
 		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);
+		       secondary_DMAChannel_bits(0),
+		       devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
 		mmiowb();
 	}
 	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -471,9 +476,9 @@ static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
 
 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))
-	{
+	if (s->
+	    async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+			     COMEDI_CB_OVERFLOW)) {
 		ni_pcidio_cancel(dev, s);
 	}
 	comedi_event(dev, s);
@@ -503,7 +508,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 	}
 
 	status = readb(devpriv->mite->daq_io_addr +
-		Interrupt_And_Window_Status);
+		       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",
@@ -525,13 +530,13 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 	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->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)) {
+				 CHSR_DRQ1 | CHSR_MRDY)) {
 			DPRINTK("unknown mite interrupt, disabling IRQ\n");
 			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 			disable_irq(dev->irq);
@@ -544,8 +549,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 		if (work > 20) {
 			DPRINTK("too much work in interrupt\n");
 			writeb(0x00,
-				devpriv->mite->daq_io_addr +
-				Master_DMA_And_Interrupt_Control);
+			       devpriv->mite->daq_io_addr +
+			       Master_DMA_And_Interrupt_Control);
 			break;
 		}
 
@@ -558,20 +563,20 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 				if (work > 100) {
 					DPRINTK("too much work in interrupt\n");
 					writeb(0x00,
-						devpriv->mite->daq_io_addr +
-						Master_DMA_And_Interrupt_Control);
+					       devpriv->mite->daq_io_addr +
+					       Master_DMA_And_Interrupt_Control);
 					goto out;
 				}
 				AuxData =
-					readl(devpriv->mite->daq_io_addr +
-					Group_1_FIFO);
+				    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);
+					      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); */
@@ -583,8 +588,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 		if (flags & CountExpired) {
 			DPRINTK("CountExpired\n");
 			writeb(ClearExpired,
-				devpriv->mite->daq_io_addr +
-				Group_1_Second_Clear);
+			       devpriv->mite->daq_io_addr +
+			       Group_1_Second_Clear);
 			async->events |= COMEDI_CB_EOA;
 
 			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
@@ -592,21 +597,21 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 		} else if (flags & Waited) {
 			DPRINTK("Waited\n");
 			writeb(ClearWaited,
-				devpriv->mite->daq_io_addr +
-				Group_1_First_Clear);
+			       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);
+			       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);
+			       devpriv->mite->daq_io_addr +
+			       Group_1_First_Clear);
 			async->events |= COMEDI_CB_EOA;
 		}
 #if 0
@@ -614,26 +619,26 @@ static irqreturn_t nidio_interrupt(int irq, void *d)
 			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);
+			       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);
+			       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:
+out:
 	ni_pcidio_event(dev, s);
 #if 0
 	if (!tag) {
 		writeb(0x03,
-			devpriv->mite->daq_io_addr +
-			Master_DMA_And_Interrupt_Control);
+		       devpriv->mite->daq_io_addr +
+		       Master_DMA_And_Interrupt_Control);
 	}
 #endif
 	return IRQ_HANDLED;
@@ -644,6 +649,7 @@ 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;
@@ -656,10 +662,12 @@ static void ni_pcidio_print_flags(unsigned int flags)
 	}
 	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;
@@ -675,7 +683,7 @@ static void ni_pcidio_print_status(unsigned int flags)
 #endif
 
 #ifdef unused
-static void debug_int(struct comedi_device * dev)
+static void debug_int(struct comedi_device *dev)
 {
 	int a, b;
 	static int n_int = 0;
@@ -704,8 +712,9 @@ static void debug_int(struct comedi_device * dev)
 }
 #endif
 
-static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
-	struct comedi_insn * insn, unsigned int * data)
+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;
@@ -718,9 +727,9 @@ static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subde
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->io_bits & (1 << CR_CHAN(insn->
-					chanspec))) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (s->
+		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
+		    COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
@@ -731,8 +740,9 @@ static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subde
 	return 1;
 }
 
-static int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
-	struct comedi_insn * insn, unsigned int * data)
+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;
@@ -746,8 +756,8 @@ static int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevi
 	return 2;
 }
 
-static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
-	struct comedi_cmd * cmd)
+static int ni_pcidio_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -788,7 +798,7 @@ static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice
 	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)
+	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
 
 	if (err)
@@ -844,7 +854,7 @@ static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice
 	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);
+				      cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
@@ -878,7 +888,7 @@ static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
 	return divider;
 }
 
-static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
 
@@ -891,11 +901,11 @@ static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s
 
 		/* set transfer width a 32 bits */
 		writeb(TransferWidth(0) | TransferLength(0),
-			devpriv->mite->daq_io_addr + Transfer_Size_Control);
+		       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);
+		       devpriv->mite->daq_io_addr + Transfer_Size_Control);
 	}
 
 	/* protocol configuration */
@@ -909,8 +919,8 @@ static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s
 		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);
+					     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);
@@ -942,14 +952,14 @@ static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s
 
 	if (cmd->stop_src == TRIG_COUNT) {
 		writel(cmd->stop_arg,
-			devpriv->mite->daq_io_addr + Transfer_Count);
+		       devpriv->mite->daq_io_addr + Transfer_Count);
 	} else {
 		/* XXX */
 	}
 
 #ifdef USE_DMA
 	writeb(ClearPrimaryTC | ClearSecondaryTC,
-		devpriv->mite->daq_io_addr + Group_1_First_Clear);
+	       devpriv->mite->daq_io_addr + Group_1_First_Clear);
 
 	{
 		int retval = setup_mite_dma(dev, s);
@@ -967,7 +977,7 @@ static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s
 
 	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
 	writeb(0x03,
-		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+	       devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
 
 	if (cmd->stop_src == TRIG_NONE) {
 		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
@@ -977,7 +987,7 @@ static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s
 	if (cmd->start_src == TRIG_NOW) {
 		/* start */
 		writeb(devpriv->OpModeBits,
-			devpriv->mite->daq_io_addr + OpMode);
+		       devpriv->mite->daq_io_addr + OpMode);
 		s->async->inttrig = NULL;
 	} else {
 		/* TRIG_INT */
@@ -988,7 +998,7 @@ static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s
 	return 0;
 }
 
-static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
 {
 	int retval;
 
@@ -1004,8 +1014,8 @@ static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
-	unsigned int trignum)
+static int ni_pcidio_inttrig(struct comedi_device *dev,
+			     struct comedi_subdevice *s, unsigned int trignum)
 {
 	if (trignum != 0)
 		return -EINVAL;
@@ -1016,17 +1026,18 @@ static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice
 	return 1;
 }
 
-static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+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);
+	       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)
+static int ni_pcidio_change(struct comedi_device *dev,
+			    struct comedi_subdevice *s, unsigned long new_size)
 {
 	int ret;
 
@@ -1039,50 +1050,53 @@ static int ni_pcidio_change(struct comedi_device * dev, struct comedi_subdevice
 	return 0;
 }
 
-static int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * data,
-	int data_len)
+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);
+	       devpriv->mite->daq_io_addr + Firmware_Control_Register);
 	writew(0xc0 | fpga_index,
-		devpriv->mite->daq_io_addr + Firmware_Control_Register);
+	       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) {
+	     (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);
+		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);
+	       devpriv->mite->daq_io_addr + Firmware_Control_Register);
 	for (i = 0;
-		readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
-		0x3 && i < timeout; ++i) {
+	     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);
+		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);
+		       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) {
+		     (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);
+			       fpga_index);
 			return -EIO;
 		}
 		if (need_resched())
@@ -1092,12 +1106,12 @@ static int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * d
 	return 0;
 }
 
-static int pci_6534_reset_fpga(struct comedi_device * dev, int fpga_index)
+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)
+static int pci_6534_reset_fpgas(struct comedi_device *dev)
 {
 	int ret;
 	int i;
@@ -1111,7 +1125,7 @@ static int pci_6534_reset_fpgas(struct comedi_device * dev)
 	return ret;
 }
 
-static void pci_6534_init_main_fpga(struct comedi_device * dev)
+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);
@@ -1121,7 +1135,7 @@ static void pci_6534_init_main_fpga(struct comedi_device * dev)
 	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
 }
 
-static int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
+static int pci_6534_upload_firmware(struct comedi_device *dev, int options[])
 {
 	int ret;
 	void *main_fpga_data, *scarab_a_data, *scarab_b_data;
@@ -1151,7 +1165,7 @@ static int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
 	return 0;
 }
 
-static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	int i;
@@ -1198,22 +1212,23 @@ static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it
 	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)));
+					 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));
+		       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;
+		    SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
+		    SDF_CMD_READ;
 		s->n_chan = 32;
 		s->range_table = &range_digital;
 		s->maxdata = 1;
@@ -1232,8 +1247,8 @@ static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it
 
 		/* disable interrupts on board */
 		writeb(0x00,
-			devpriv->mite->daq_io_addr +
-			Master_DMA_And_Interrupt_Control);
+		       devpriv->mite->daq_io_addr +
+		       Master_DMA_And_Interrupt_Control);
 
 		ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
 				  "ni_pcidio", dev);
@@ -1248,7 +1263,7 @@ static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it
 	return 0;
 }
 
-static int nidio_detach(struct comedi_device * dev)
+static int nidio_detach(struct comedi_device *dev)
 {
 	int i;
 
@@ -1272,7 +1287,7 @@ static int nidio_detach(struct comedi_device * dev)
 	return 0;
 }
 
-static int nidio_find_device(struct comedi_device * dev, int bus, int slot)
+static int nidio_find_device(struct comedi_device *dev, int bus, int slot)
 {
 	struct mite_struct *mite;
 	int i;
@@ -1282,7 +1297,7 @@ static int nidio_find_device(struct comedi_device * dev, int bus, int slot)
 			continue;
 		if (bus || slot) {
 			if (bus != mite->pcidev->bus->number ||
-				slot != PCI_SLOT(mite->pcidev->devfn))
+			    slot != PCI_SLOT(mite->pcidev->devfn))
 				continue;
 		}
 		for (i = 0; i < n_nidio_boards; i++) {
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index 1d04b75..19d8755 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -130,58 +130,59 @@ Bugs:
 
 /* 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}
+	{
+	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);
@@ -194,1020 +195,1023 @@ MODULE_DEVICE_TABLE(pci, ni_pci_table);
  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)
-	}
+							     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)
-	}
+							     RANGE(-10, 10),
+							     RANGE(-5, 5),
+							     RANGE_ext(-1, 1)
+							     }
 };
+
 static const struct comedi_lrange range_ni_M_622x_ao = { 1, {
-			RANGE(-10, 10),
-	}
+							     RANGE(-10, 10),
+							     }
 };
 
 static const struct ni_board_struct 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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},
-		},
+	 .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},
-		},
+	 .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 */
-		},
+	 .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 */
-		},
+	 .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 = 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 = 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 = 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 = 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},
-		},
+	 .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},
-		},
+	 .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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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},
-		},
+	 .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])))
+#define n_pcimio_boards ARRAY_SIZE(ni_boards)
 
-static int pcimio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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,
@@ -1219,8 +1223,7 @@ static struct comedi_driver driver_pcimio = {
 COMEDI_PCI_INITCLEANUP(driver_pcimio, ni_pci_table)
 
 struct ni_private {
-	NI_PRIVATE_COMMON
-};
+NI_PRIVATE_COMMON};
 #define devpriv ((struct ni_private *)dev->private)
 
 /* How we access registers */
@@ -1265,7 +1268,8 @@ static uint16_t e_series_win_in(struct comedi_device *dev, int reg)
 	return ret;
 }
 
-static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, int reg)
+static void m_series_stc_writew(struct comedi_device *dev, uint16_t data,
+				int reg)
 {
 	unsigned offset;
 	switch (reg) {
@@ -1350,8 +1354,8 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, int re
 		break;
 	case DIO_Control_Register:
 		printk
-			("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n",
-			__func__, reg);
+		    ("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n",
+		     __func__, reg);
 		return;
 		break;
 	case G_Autoincrement_Register(0):
@@ -1412,7 +1416,7 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, int re
 		   and M_Offset_SCXI_Serial_Data_Out (8 bit) */
 	default:
 		printk("%s: bug! unhandled register=0x%x in switch.\n",
-			__func__, reg);
+		       __func__, reg);
 		BUG();
 		return;
 		break;
@@ -1447,7 +1451,7 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
 		break;
 	default:
 		printk("%s: bug! unhandled register=0x%x in switch.\n",
-			__func__, reg);
+		       __func__, reg);
 		BUG();
 		return 0;
 		break;
@@ -1455,7 +1459,8 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg)
 	return ni_readw(offset);
 }
 
-static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, int reg)
+static void m_series_stc_writel(struct comedi_device *dev, uint32_t data,
+				int reg)
 {
 	unsigned offset;
 	switch (reg) {
@@ -1488,7 +1493,7 @@ static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, int re
 		break;
 	default:
 		printk("%s: bug! unhandled register=0x%x in switch.\n",
-			__func__, reg);
+		       __func__, reg);
 		BUG();
 		return;
 		break;
@@ -1514,7 +1519,7 @@ static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
 		break;
 	default:
 		printk("%s: bug! unhandled register=0x%x in switch.\n",
-			__func__, reg);
+		       __func__, reg);
 		BUG();
 		return 0;
 		break;
@@ -1530,16 +1535,19 @@ static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg)
 #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 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)
 {
@@ -1557,13 +1565,14 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev)
 	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);
+	       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;
+		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);
@@ -1593,7 +1602,7 @@ static void init_6143(struct comedi_device *dev)
 	/*  Strobe Relay disable bit */
 	devpriv->ai_calib_source_enabled = 0;
 	ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff,
-		Calibration_Channel_6143);
+		  Calibration_Channel_6143);
 	ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
 }
 
@@ -1710,7 +1719,7 @@ static int pcimio_find_device(struct comedi_device *dev, int bus, int slot)
 			continue;
 		if (bus || slot) {
 			if (bus != mite->pcidev->bus->number ||
-				slot != PCI_SLOT(mite->pcidev->devfn))
+			    slot != PCI_SLOT(mite->pcidev->devfn))
 				continue;
 		}
 
@@ -1728,8 +1737,8 @@ static int pcimio_find_device(struct comedi_device *dev, int bus, int slot)
 	return -EIO;
 }
 
-static int pcimio_ai_change(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned long new_size)
+static int pcimio_ai_change(struct comedi_device *dev,
+			    struct comedi_subdevice *s, unsigned long new_size)
 {
 	int ret;
 
@@ -1740,8 +1749,8 @@ static int pcimio_ai_change(struct comedi_device *dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int pcimio_ao_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)
 {
 	int ret;
 
@@ -1752,8 +1761,9 @@ static int pcimio_ao_change(struct comedi_device *dev, struct comedi_subdevice *
 	return 0;
 }
 
-static int pcimio_gpct0_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)
 {
 	int ret;
 
@@ -1764,8 +1774,9 @@ static int pcimio_gpct0_change(struct comedi_device *dev, struct comedi_subdevic
 	return 0;
 }
 
-static int pcimio_gpct1_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)
 {
 	int ret;
 
@@ -1776,8 +1787,8 @@ static int pcimio_gpct1_change(struct comedi_device *dev, struct comedi_subdevic
 	return 0;
 }
 
-static int pcimio_dio_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)
 {
 	int ret;
 
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
index fcaedb3..504ea71 100644
--- a/drivers/staging/comedi/drivers/ni_stc.h
+++ b/drivers/staging/comedi/drivers/ni_stc.h
@@ -339,8 +339,7 @@ static inline unsigned RTSI_Output_Bit(unsigned channel, int is_mseries)
 		max_channel = 6;
 	}
 	if (channel > max_channel) {
-		printk("%s: bug, invalid RTSI_channel=%i\n", __func__,
-			channel);
+		printk("%s: bug, invalid RTSI_channel=%i\n", __func__, channel);
 		return 0;
 	}
 	return 1 << (base_bit_shift + channel);
@@ -369,7 +368,7 @@ enum ai_convert_output_selection {
 	AI_CONVERT_Output_Enable_High = 3
 };
 static unsigned AI_CONVERT_Output_Select(enum ai_convert_output_selection
-	selection)
+					 selection)
 {
 	return selection & 0x3;
 }
@@ -530,10 +529,11 @@ 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)
+					     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);
@@ -541,7 +541,7 @@ static inline unsigned RTSI_Trig_Output_Mask(unsigned rtsi_channel)
 
 /* inverse to RTSI_Trig_Output_Bits() */
 static inline unsigned RTSI_Trig_Output_Source(unsigned rtsi_channel,
-	unsigned bits)
+					       unsigned bits)
 {
 	return (bits >> ((rtsi_channel % 4) * 4)) & 0xf;
 };
@@ -566,7 +566,7 @@ enum ao_update_output_selection {
 	AO_Update_Output_Enable_High = 3
 };
 static unsigned AO_UPDATE_Output_Select(enum ao_update_output_selection
-	selection)
+					selection)
 {
 	return selection & 0x3;
 }
@@ -730,13 +730,15 @@ static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel)
 	BUG();
 	return 0;
 }
+
 static inline unsigned GPCT_DMA_Select_Bits(unsigned gpct_index,
-	unsigned mite_channel)
+					    unsigned mite_channel)
 {
 	BUG_ON(gpct_index > 1);
 	return ni_stc_dma_channel_select_bitfield(mite_channel) << (4 *
-		gpct_index);
+								    gpct_index);
 }
+
 static inline unsigned GPCT_DMA_Select_Mask(unsigned gpct_index)
 {
 	BUG_ON(gpct_index > 1);
@@ -839,6 +841,7 @@ static inline unsigned int DACx_Direct_Data_671x(int channel)
 {
 	return channel;
 }
+
 enum AO_Misc_611x_Bits {
 	CLEAR_WG = 1,
 };
@@ -870,10 +873,12 @@ 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,
@@ -898,8 +903,9 @@ enum cs5529_status_bits {
 */
 
 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 };
+	    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
 };
@@ -1064,18 +1070,22 @@ 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[] = {
@@ -1090,6 +1100,7 @@ static inline int M_Offset_Static_AI_Control(int i)
 	}
 	return offset[i];
 };
+
 static inline int M_Offset_AO_Reference_Attenuation(int channel)
 {
 	int offset[] = {
@@ -1104,11 +1115,12 @@ static inline int M_Offset_AO_Reference_Attenuation(int channel)
 	}
 	return offset[channel];
 };
+
 static inline unsigned M_Offset_PFI_Output_Select(unsigned n)
 {
 	if (n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) {
 		printk("%s: invalid pfi output select register=%i\n",
-			__func__, n);
+		       __func__, n);
 		return M_Offset_PFI_Output_Select_1;
 	}
 	return M_Offset_PFI_Output_Select_1 + (n - 1) * 2;
@@ -1130,8 +1142,9 @@ 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 channel)
 {
 	unsigned bits = channel & 0x30;
 	if (reg_type == ni_reg_622x) {
@@ -1140,6 +1153,7 @@ static inline unsigned MSeries_AI_Config_Bank_Bits(enum ni_reg_type reg_type,
 	}
 	return bits;
 }
+
 static inline unsigned MSeries_AI_Config_Gain_Bits(unsigned range)
 {
 	return (range & 0x7) << 9;
@@ -1159,11 +1173,11 @@ enum MSeries_Clock_and_Fout2_Bits {
 	MSeries_RTSI_10MHz_Bit = 0x80
 };
 static inline unsigned MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned
-	RTSI_channel)
+							      RTSI_channel)
 {
 	if (RTSI_channel > 7) {
 		printk("%s: bug, invalid RTSI_channel=%i\n", __func__,
-			RTSI_channel);
+		       RTSI_channel);
 		return 0;
 	}
 	if (RTSI_channel == 7)
@@ -1183,18 +1197,18 @@ static inline unsigned MSeries_PLL_Divisor_Bits(unsigned divisor)
 {
 	static const unsigned max_divisor = 0x10;
 	if (divisor < 1 || divisor > max_divisor) {
-		printk("%s: bug, invalid divisor=%i\n", __func__,
-			divisor);
+		printk("%s: bug, invalid divisor=%i\n", __func__, 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) {
 		printk("%s: bug, invalid multiplier=%i\n", __func__,
-			multiplier);
+		       multiplier);
 		return 0;
 	}
 	return multiplier & 0xff;
@@ -1217,15 +1231,17 @@ enum MSeries_AI_Config_FIFO_Bypass_Bits {
 	MSeries_AI_Bypass_Config_FIFO_Bit = 0x80000000
 };
 static inline unsigned MSeries_AI_Bypass_Cal_Sel_Pos_Bits(int
-	calibration_source)
+							  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)
+							  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;
@@ -1260,15 +1276,16 @@ 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)
+						      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)
+							unsigned bits)
 {
 	return (bits >> ((channel % 3) * 5)) & 0x1f;
 };
@@ -1285,11 +1302,12 @@ 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)
+						      unsigned filter)
 {
 	return (filter << (channel *
-			2)) & MSeries_PFI_Filter_Select_Mask(channel);
+			   2)) & MSeries_PFI_Filter_Select_Mask(channel);
 }
 
 enum CDIO_DMA_Select_Bits {
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
index 785553d..13e5b26 100644
--- a/drivers/staging/comedi/drivers/ni_tio.c
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -51,7 +51,7 @@ TODO:
 #include "ni_tio_internal.h"
 
 static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
-	unsigned generic_clock_source);
+				       unsigned generic_clock_source);
 static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter);
 
 MODULE_AUTHOR("Comedi <comedi@comedi.org>");
@@ -59,7 +59,8 @@ 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)
+								   ni_gpct_variant
+								   variant)
 {
 	switch (variant) {
 	case ni_gpct_variant_e_series:
@@ -77,8 +78,10 @@ static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum
 	}
 	return 0;
 }
+
 static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum
-	ni_gpct_variant variant)
+								ni_gpct_variant
+								variant)
 {
 	switch (variant) {
 	case ni_gpct_variant_e_series:
@@ -96,8 +99,10 @@ static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum
 	}
 	return 0;
 }
+
 static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum
-	ni_gpct_variant variant)
+								ni_gpct_variant
+								variant)
 {
 	switch (variant) {
 	case ni_gpct_variant_e_series:
@@ -115,8 +120,10 @@ static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum
 	}
 	return 0;
 }
+
 static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum
-	ni_gpct_variant variant)
+								   ni_gpct_variant
+								   variant)
 {
 	switch (variant) {
 	case ni_gpct_variant_e_series:
@@ -151,6 +158,7 @@ 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)
 {
@@ -179,6 +187,7 @@ static inline unsigned NI_M_Series_PFI_Clock(unsigned 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)
 {
@@ -202,6 +211,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);
@@ -225,6 +235,7 @@ static inline unsigned NI_M_Series_RTSI_Gate_Select(unsigned n)
 		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);
@@ -237,6 +248,7 @@ 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;
@@ -256,6 +268,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);
@@ -263,7 +276,7 @@ static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n)
 }
 
 static const unsigned int counter_status_mask =
-	COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
+    COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
 
 static int __init ni_tio_init_module(void)
 {
@@ -278,17 +291,26 @@ 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)
+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);
+	    kzalloc(sizeof(struct ni_gpct_device), GFP_KERNEL);
 	if (counter_dev == NULL)
 		return NULL;
 	counter_dev->dev = dev;
@@ -298,7 +320,7 @@ struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device * dev,
 	spin_lock_init(&counter_dev->regs_lock);
 	BUG_ON(num_counters == 0);
 	counter_dev->counters =
-		kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL);
+	    kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL);
 	if (counter_dev->counters == NULL) {
 		kfree(counter_dev);
 		return NULL;
@@ -320,7 +342,7 @@ void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
 }
 
 static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
-	*counter_dev)
+						*counter_dev)
 {
 	switch (counter_dev->variant) {
 	case ni_gpct_variant_e_series:
@@ -340,7 +362,7 @@ static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
 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));
+		       NITIO_Gxx_Joint_Reset_Reg(counter->counter_index));
 }
 
 void ni_tio_init_counter(struct ni_gpct *counter)
@@ -350,49 +372,59 @@ void ni_tio_init_counter(struct ni_gpct *counter)
 	ni_tio_reset_count_and_disarm(counter);
 	/* initialize counter registers */
 	counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] =
-		0x0;
+	    0x0;
 	write_register(counter,
-		counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->
-				counter_index)],
-		NITIO_Gi_Autoincrement_Reg(counter->counter_index));
+		       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);
+			~0, Gi_Synchronize_Gate_Bit);
 	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), ~0,
-		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_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));
+		       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);
+			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);
+				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;
+		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));
+			       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);
+			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);
+			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));
+					    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))
@@ -405,16 +437,18 @@ 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);
+	    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));
+								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) {
+				     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:
@@ -428,14 +462,14 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
 	   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)) {
+	    (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));
+				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);
+				Gi_Alternate_Sync_Bit(counter_dev->variant),
+				0x0);
 	}
 }
 
@@ -447,10 +481,10 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
 	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;
+	    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;
@@ -469,29 +503,31 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
 		break;
 	}
 	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
-		mode_reg_mask, mode_reg_values);
+			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;
+		    (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;
+		    ((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);
+				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);
+			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;
@@ -500,9 +536,9 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
 		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);
+			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;
 }
@@ -535,32 +571,33 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
 				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);
+					    (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;
+					    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);
+					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);
+				  NITIO_Gi_Command_Reg(counter->counter_index),
+				  0, 0, command_transient_bits);
 	return 0;
 }
 
@@ -569,7 +606,7 @@ 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;
+	    clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
 
 	switch (clock_select_bits) {
 	case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
@@ -604,7 +641,7 @@ static unsigned ni_660x_source_select_bits(unsigned int clock_source)
 			break;
 		for (i = 0; i <= ni_660x_max_source_pin; ++i) {
 			if (clock_select_bits ==
-				NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
+			    NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
 				ni_660x_clock = NI_660x_Source_Pin_Clock(i);
 				break;
 			}
@@ -623,7 +660,7 @@ 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;
+	    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;
@@ -670,7 +707,7 @@ static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
 		if (i <= ni_m_series_max_pfi_channel)
 			break;
 		printk("invalid clock source 0x%lx\n",
-			(unsigned long)clock_source);
+		       (unsigned long)clock_source);
 		BUG();
 		ni_m_series_clock = 0;
 		break;
@@ -679,11 +716,11 @@ static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
 };
 
 static void ni_tio_set_source_subselect(struct ni_gpct *counter,
-	unsigned int clock_source)
+					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);
+	    NITIO_Gi_Second_Gate_Reg(counter->counter_index);
 
 	if (counter_dev->variant != ni_gpct_variant_m_series)
 		return;
@@ -704,11 +741,12 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter,
 		break;
 	}
 	write_register(counter, counter_dev->regs[second_gate_reg],
-		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)
+				unsigned int clock_source,
+				unsigned int period_ns)
 {
 	struct ni_gpct_device *counter_dev = counter->counter_dev;
 	unsigned input_select_bits = 0;
@@ -722,7 +760,7 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter,
 	case ni_gpct_variant_e_series:
 	case ni_gpct_variant_m_series:
 		input_select_bits |=
-			ni_m_series_source_select_bits(clock_source);
+		    ni_m_series_source_select_bits(clock_source);
 		break;
 	default:
 		BUG();
@@ -731,13 +769,13 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter,
 	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);
+			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;
+		    clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
 		unsigned counting_mode_bits = 0;
 
 		switch (prescaling_mode) {
@@ -745,21 +783,22 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter,
 			break;
 		case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
 			counting_mode_bits |=
-				Gi_Prescale_X2_Bit(counter_dev->variant);
+			    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);
+			    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);
+				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);
@@ -770,12 +809,15 @@ 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));
+								 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)
+				 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;
@@ -788,13 +830,14 @@ 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);
+	    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;
+							    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:
@@ -804,10 +847,10 @@ static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
 		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)
+		if (counter_dev->regs[second_gate_reg] &
+		    Gi_Source_Subselect_Bit)
 			clock_source =
-				NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
+			    NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
 		else
 			clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
 		break;
@@ -815,8 +858,8 @@ static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
 		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)
+		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;
@@ -856,9 +899,10 @@ 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;
+							    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:
@@ -894,7 +938,7 @@ static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
 		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);
+				    NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
 				break;
 			}
 		}
@@ -925,7 +969,7 @@ static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
 }
 
 static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
-	unsigned generic_clock_source)
+				       unsigned generic_clock_source)
 {
 	uint64_t clock_period_ps;
 
@@ -965,7 +1009,8 @@ static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
 }
 
 static void ni_tio_get_clock_src(struct ni_gpct *counter,
-	unsigned int *clock_source, unsigned int *period_ns)
+				 unsigned int *clock_source,
+				 unsigned int *period_ns)
 {
 	static const unsigned pico_per_nano = 1000;
 	uint64_t temp64;
@@ -976,7 +1021,7 @@ static void ni_tio_get_clock_src(struct ni_gpct *counter,
 }
 
 static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
-	unsigned int gate_source)
+					    unsigned int gate_source)
 {
 	const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask;
 	unsigned mode_values = 0;
@@ -990,10 +1035,11 @@ static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
 		mode_values |= Gi_Level_Gating_Bits;
 	}
 	ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
-		mode_mask, mode_values);
+			mode_mask, mode_values);
 }
 
-static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_source)
+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 */
@@ -1015,7 +1061,7 @@ static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_sou
 		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;
+				    selected_gate & selected_gate_mask;
 				break;
 			}
 		}
@@ -1024,7 +1070,7 @@ static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_sou
 		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;
+				    selected_gate & selected_gate_mask;
 				break;
 			}
 		}
@@ -1034,13 +1080,14 @@ static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_sou
 		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));
+			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)
+				      unsigned int gate_source)
 {
 	const unsigned selected_gate = CR_CHAN(gate_source);
 	/* bits of selected_gate that may be meaningful to input select register */
@@ -1063,7 +1110,7 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter,
 		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;
+				    selected_gate & selected_gate_mask;
 				break;
 			}
 		}
@@ -1072,7 +1119,7 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter,
 		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;
+				    selected_gate & selected_gate_mask;
 				break;
 			}
 		}
@@ -1082,18 +1129,18 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter,
 		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));
+			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)
+				   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);
+	    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;
@@ -1107,18 +1154,18 @@ static int ni_660x_set_second_gate(struct ni_gpct *counter,
 	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;
+		    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;
+		    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;
+				    selected_second_gate &
+				    selected_second_gate_mask;
 				break;
 			}
 		}
@@ -1126,10 +1173,10 @@ static int ni_660x_set_second_gate(struct ni_gpct *counter,
 			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_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
 				ni_660x_second_gate_select =
-					selected_second_gate &
-					selected_second_gate_mask;
+				    selected_second_gate &
+				    selected_second_gate_mask;
 				break;
 			}
 		}
@@ -1141,18 +1188,18 @@ static int ni_660x_set_second_gate(struct ni_gpct *counter,
 	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);
+	    Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select);
 	write_register(counter, counter_dev->regs[second_gate_reg],
-		second_gate_reg);
+		       second_gate_reg);
 	return 0;
 }
 
 static int ni_m_series_set_second_gate(struct ni_gpct *counter,
-	unsigned int gate_source)
+				       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);
+	    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;
@@ -1163,31 +1210,33 @@ static int ni_m_series_set_second_gate(struct ni_gpct *counter,
 	switch (selected_second_gate) {
 	default:
 		ni_m_series_second_gate_select =
-			selected_second_gate & selected_second_gate_mask;
+		    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);
+	    Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select);
 	write_register(counter, counter_dev->regs[second_gate_reg],
-		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)
+			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);
+	    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);
+					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);
@@ -1209,23 +1258,23 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
 			return -EINVAL;
 		if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
 			counter_dev->regs[second_gate_reg] &=
-				~Gi_Second_Gate_Mode_Bit;
+			    ~Gi_Second_Gate_Mode_Bit;
 			write_register(counter,
-				counter_dev->regs[second_gate_reg],
-				second_gate_reg);
+				       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;
+			    Gi_Second_Gate_Polarity_Bit;
 		} else {
 			counter_dev->regs[second_gate_reg] &=
-				~Gi_Second_Gate_Polarity_Bit;
+			    ~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);
+							   gate_source);
 			break;
 		case ni_gpct_variant_660x:
 			return ni_660x_set_second_gate(counter, gate_source);
@@ -1243,7 +1292,7 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
 }
 
 static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
-	unsigned int source)
+				unsigned int source)
 {
 	struct ni_gpct_device *counter_dev = counter->counter_dev;
 
@@ -1280,7 +1329,7 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
 }
 
 static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
-	ni_660x_gate_select)
+							  ni_660x_gate_select)
 {
 	unsigned i;
 
@@ -1311,7 +1360,7 @@ static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
 			break;
 		for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
 			if (ni_660x_gate_select ==
-				NI_660x_Gate_Pin_Gate_Select(i)) {
+			    NI_660x_Gate_Pin_Gate_Select(i)) {
 				return NI_GPCT_GATE_PIN_GATE_SELECT(i);
 				break;
 			}
@@ -1325,7 +1374,7 @@ static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
 };
 
 static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
-	ni_m_series_gate_select)
+							      ni_m_series_gate_select)
 {
 	unsigned i;
 
@@ -1357,7 +1406,7 @@ static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
 	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)) {
+			    NI_M_Series_RTSI_Gate_Select(i)) {
 				return NI_GPCT_RTSI_GATE_SELECT(i);
 				break;
 			}
@@ -1366,7 +1415,7 @@ static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
 			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)) {
+			    NI_M_Series_PFI_Gate_Select(i)) {
 				return NI_GPCT_PFI_GATE_SELECT(i);
 				break;
 			}
@@ -1380,7 +1429,7 @@ static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
 };
 
 static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
-	ni_660x_gate_select)
+							   ni_660x_gate_select)
 {
 	unsigned i;
 
@@ -1406,7 +1455,7 @@ static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
 	default:
 		for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
 			if (ni_660x_gate_select ==
-				NI_660x_RTSI_Second_Gate_Select(i)) {
+			    NI_660x_RTSI_Second_Gate_Select(i)) {
 				return NI_GPCT_RTSI_GATE_SELECT(i);
 				break;
 			}
@@ -1415,7 +1464,7 @@ static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
 			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)) {
+			    NI_660x_Up_Down_Pin_Second_Gate_Select(i)) {
 				return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
 				break;
 			}
@@ -1429,7 +1478,7 @@ static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
 };
 
 static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned
-	ni_m_series_gate_select)
+							       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. */
@@ -1442,39 +1491,41 @@ static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned
 };
 
 static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
-	unsigned int *gate_source)
+			       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));
+							NITIO_Gi_Mode_Reg
+							(counter->
+							 counter_index));
 	const unsigned second_gate_reg =
-		NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+	    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) {
+		    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;
+			    (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);
+			    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);
+			    ni_660x_first_gate_to_generic_gate_source
+			    (gate_select_bits);
 			break;
 		default:
 			BUG();
@@ -1489,36 +1540,35 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
 		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) {
+		    || (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;
+			    (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);
+			    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);
+			    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) {
+		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 */
@@ -1534,7 +1584,7 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
 }
 
 int ni_tio_insn_config(struct ni_gpct *counter,
-	struct comedi_insn *insn, unsigned int *data)
+		       struct comedi_insn *insn, unsigned int *data)
 {
 	switch (data[0]) {
 	case INSN_CONFIG_SET_COUNTER_MODE:
@@ -1578,7 +1628,8 @@ int ni_tio_insn_config(struct ni_gpct *counter,
 	return -EINVAL;
 }
 
-int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+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);
@@ -1591,26 +1642,27 @@ int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned in
 	switch (channel) {
 	case 0:
 		ni_tio_set_bits(counter,
-			NITIO_Gi_Command_Reg(counter->counter_index),
-			Gi_Save_Trace_Bit, 0);
+				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);
+				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));
+		    read_register(counter,
+				  NITIO_Gi_SW_Save_Reg(counter->counter_index));
 		second_read =
-			read_register(counter,
-			NITIO_Gi_SW_Save_Reg(counter->counter_index));
+		    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));
+			    read_register(counter,
+					  NITIO_Gi_SW_Save_Reg(counter->
+							       counter_index));
 		else
 			correct_read = first_read;
 		data[0] = correct_read;
@@ -1618,13 +1670,13 @@ int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned in
 		break;
 	case 1:
 		data[0] =
-			counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->
-				counter_index)];
+		    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)];
+		    counter_dev->
+		    regs[NITIO_Gi_LoadB_Reg(counter->counter_index)];
 		break;
 	};
 	return 0;
@@ -1633,7 +1685,8 @@ int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned in
 static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
 {
 	const unsigned bits = read_register(counter,
-		NITIO_Gxx_Status_Reg(counter->counter_index));
+					    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);
@@ -1642,7 +1695,8 @@ static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
 	}
 }
 
-int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+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);
@@ -1657,22 +1711,23 @@ int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned in
 		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);
+					  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];
+		    data[0];
 		write_register(counter, data[0],
-			NITIO_Gi_LoadA_Reg(counter->counter_index));
+			       NITIO_Gi_LoadA_Reg(counter->counter_index));
 		break;
 	case 2:
 		counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] =
-			data[0];
+		    data[0];
 		write_register(counter, data[0],
-			NITIO_Gi_LoadB_Reg(counter->counter_index));
+			       NITIO_Gi_LoadB_Reg(counter->counter_index));
 		break;
 	default:
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
index 3aacfe2..b058820 100644
--- a/drivers/staging/comedi/drivers/ni_tio.h
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -120,10 +120,10 @@ struct ni_gpct {
 
 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);
+	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;
@@ -131,31 +131,42 @@ struct ni_gpct_device {
 	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 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);
+			struct comedi_insn *insn, unsigned int *data);
 extern int ni_tio_insn_config(struct ni_gpct *counter,
-	struct comedi_insn *insn, unsigned int *data);
+			      struct comedi_insn *insn, unsigned int *data);
 extern int ni_tio_winsn(struct ni_gpct *counter,
-	struct comedi_insn *insn, unsigned int *data);
+			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_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);
+				    struct comedi_subdevice *s);
 extern void ni_tio_set_mite_channel(struct ni_gpct *counter,
-	struct mite_channel *mite_chan);
+				    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);
+					   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)
+static inline struct ni_gpct *subdev_to_counter(struct comedi_subdevice *s)
 {
 	return s->private;
 }
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
index 920dd22..c4ca537 100644
--- a/drivers/staging/comedi/drivers/ni_tio_internal.h
+++ b/drivers/staging/comedi/drivers/ni_tio_internal.h
@@ -27,7 +27,7 @@
 #include "ni_tio.h"
 
 static inline enum ni_gpct_register NITIO_Gi_Autoincrement_Reg(unsigned
-	counter_index)
+							       counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -72,7 +72,7 @@ static inline enum ni_gpct_register NITIO_Gi_Command_Reg(unsigned counter_index)
 }
 
 static inline enum ni_gpct_register NITIO_Gi_Counting_Mode_Reg(unsigned
-	counter_index)
+							       counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -95,7 +95,7 @@ static inline enum ni_gpct_register NITIO_Gi_Counting_Mode_Reg(unsigned
 }
 
 static inline enum ni_gpct_register NITIO_Gi_Input_Select_Reg(unsigned
-	counter_index)
+							      counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -118,7 +118,7 @@ static inline enum ni_gpct_register NITIO_Gi_Input_Select_Reg(unsigned
 }
 
 static inline enum ni_gpct_register NITIO_Gxx_Joint_Reset_Reg(unsigned
-	counter_index)
+							      counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -137,7 +137,7 @@ static inline enum ni_gpct_register NITIO_Gxx_Joint_Reset_Reg(unsigned
 }
 
 static inline enum ni_gpct_register NITIO_Gxx_Joint_Status1_Reg(unsigned
-	counter_index)
+								counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -156,7 +156,7 @@ static inline enum ni_gpct_register NITIO_Gxx_Joint_Status1_Reg(unsigned
 }
 
 static inline enum ni_gpct_register NITIO_Gxx_Joint_Status2_Reg(unsigned
-	counter_index)
+								counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -363,7 +363,7 @@ static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index)
 }
 
 static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg(int
-	counter_index)
+								       counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -408,7 +408,7 @@ static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index)
 }
 
 static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg(int
-	counter_index)
+								  counter_index)
 {
 	switch (counter_index) {
 	case 0:
@@ -542,7 +542,7 @@ enum Gi_Second_Gate_Bits {
 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;
+	    Gi_Second_Gate_Select_Mask;
 }
 
 enum Gxx_Status_Bits {
@@ -569,31 +569,36 @@ static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index)
 		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)
+							   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)
@@ -616,7 +621,7 @@ enum Gxx_Joint_Status2_Bits {
 	G1_Permanent_Stale_Bit = 0x8000
 };
 static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned
-	counter_index)
+								 counter_index)
 {
 	if (counter_index % 2)
 		return G1_Permanent_Stale_Bit;
@@ -649,6 +654,7 @@ static inline unsigned Gi_Gate_Error_Confirm_Bit(unsigned counter_index)
 		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)
@@ -689,21 +695,22 @@ static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index)
 }
 
 static inline void write_register(struct ni_gpct *counter, unsigned bits,
-	enum ni_gpct_register reg)
+				  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)
+				     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)
+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:
@@ -721,8 +728,10 @@ static inline int ni_tio_counting_mode_registers_present(
 }
 
 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)
+					     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;
@@ -732,8 +741,8 @@ static inline void ni_tio_set_bits_transient(struct ni_gpct *counter,
 	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);
+		       counter_dev->regs[register_index] | transient_bit_values,
+		       register_index);
 	mmiowb();
 	spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
 }
@@ -742,11 +751,11 @@ static inline void ni_tio_set_bits_transient(struct ni_gpct *counter,
 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)
+				   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);
+				  0x0);
 }
 
 /* ni_tio_get_soft_copy( ) is for safely reading the software copy of a register
@@ -754,7 +763,8 @@ 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)
+					    enum ni_gpct_register
+					    register_index)
 {
 	struct ni_gpct_device *counter_dev = counter->counter_dev;
 	unsigned long flags;
@@ -769,6 +779,6 @@ static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter,
 
 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);
+			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
index 5be1e1a..b0d44b5 100644
--- a/drivers/staging/comedi/drivers/ni_tiocmd.c
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -56,7 +56,7 @@ 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)
+				 short read_not_write)
 {
 	struct ni_gpct_device *counter_dev = counter->counter_dev;
 	unsigned input_select_bits = 0;
@@ -69,9 +69,9 @@ static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
 		}
 	}
 	ni_tio_set_bits(counter,
-		NITIO_Gi_Input_Select_Reg(counter->counter_index),
-		Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq,
-		input_select_bits);
+			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;
@@ -88,16 +88,18 @@ static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
 				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);
+					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)
+static int ni_tio_input_inttrig(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				unsigned int trignum)
 {
 	unsigned long flags;
 	int retval = 0;
@@ -143,7 +145,7 @@ static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async)
 		break;
 	}
 	ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
-		Gi_Save_Trace_Bit, 0);
+			Gi_Save_Trace_Bit, 0);
 	ni_tio_configure_dma(counter, 1, 1);
 	switch (cmd->start_src) {
 	case TRIG_NOW:
@@ -169,7 +171,8 @@ static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async)
 	return retval;
 }
 
-static int ni_tio_output_cmd(struct ni_gpct *counter, struct comedi_async *async)
+static int ni_tio_output_cmd(struct ni_gpct *counter,
+			     struct comedi_async *async)
 {
 	printk("ni_tio: output commands not yet implemented.\n");
 	return -ENOTSUPP;
@@ -200,9 +203,12 @@ static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async)
 	}
 	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));
+				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;
 }
@@ -216,7 +222,7 @@ int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async)
 	spin_lock_irqsave(&counter->lock, flags);
 	if (counter->mite_chan == NULL) {
 		printk
-			("ni_tio: commands only supported with DMA.  Interrupt-driven commands not yet implemented.\n");
+		    ("ni_tio: commands only supported with DMA.  Interrupt-driven commands not yet implemented.\n");
 		retval = -EIO;
 	} else {
 		retval = ni_tio_cmd_setup(counter, async);
@@ -232,7 +238,7 @@ int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async)
 	return retval;
 }
 
-int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd)
+int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -275,15 +281,15 @@ int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd)
 	/* 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)
+	    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)
+	    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)
+	    cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
 		err++;
 	if (cmd->stop_src != TRIG_NONE)
 		err++;
@@ -350,8 +356,9 @@ int ni_tio_cancel(struct ni_gpct *counter)
 	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);
+			NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
+			Gi_Gate_Interrupt_Enable_Bit(counter->counter_index),
+			0x0);
 	return 0;
 }
 
@@ -372,8 +379,8 @@ static int should_ack_gate(struct ni_gpct *counter)
 		spin_lock_irqsave(&counter->lock, flags);
 		{
 			if (counter->mite_chan == NULL ||
-				counter->mite_chan->dir != COMEDI_INPUT ||
-				(mite_done(counter->mite_chan))) {
+			    counter->mite_chan->dir != COMEDI_INPUT ||
+			    (mite_done(counter->mite_chan))) {
 				retval = 1;
 			}
 		}
@@ -384,12 +391,17 @@ static int should_ack_gate(struct ni_gpct *counter)
 }
 
 void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
-	int *tc_error, int *perm_stale_data, int *stale_data)
+				    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));
+							NITIO_Gxx_Status_Reg
+							(counter->
+							 counter_index));
 	const unsigned short gi_status = read_register(counter,
-		NITIO_Gi_Status_Reg(counter->counter_index));
+						       NITIO_Gi_Status_Reg
+						       (counter->
+							counter_index));
 	unsigned ack = 0;
 
 	if (gate_error)
@@ -407,7 +419,7 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *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) {
+			    ni_gpct_variant_660x) {
 				*gate_error = 1;
 			}
 		}
@@ -426,28 +438,30 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
 	}
 	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) {
+			       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)) {
+				  NITIO_Gxx_Joint_Status2_Reg
+				  (counter->counter_index)) &
+		    Gi_Permanent_Stale_Bit(counter->counter_index)) {
 			printk("%s: Gi_Permanent_Stale_Data detected.\n",
-				__FUNCTION__);
+			       __FUNCTION__);
 			if (perm_stale_data)
 				*perm_stale_data = 1;
 		}
 	}
 }
 
-void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice * s)
+void ni_tio_handle_interrupt(struct ni_gpct *counter,
+			     struct comedi_subdevice *s)
 {
 	unsigned gpct_mite_status;
 	unsigned long flags;
@@ -456,7 +470,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice *
 	int perm_stale_data;
 
 	ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
-		&perm_stale_data, NULL);
+				       &perm_stale_data, NULL);
 	if (gate_error) {
 		printk("%s: Gi_Gate_Error detected.\n", __FUNCTION__);
 		s->async->events |= COMEDI_CB_OVERFLOW;
@@ -468,8 +482,9 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice *
 	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) {
+				  NITIO_Gi_DMA_Status_Reg
+				  (counter->counter_index)) & Gi_DRQ_Error_Bit)
+		{
 			printk("%s: Gi_DRQ_Error detected.\n", __FUNCTION__);
 			s->async->events |= COMEDI_CB_OVERFLOW;
 		}
@@ -485,15 +500,15 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice *
 	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));
+		       counter->mite_chan->mite->mite_io_addr +
+		       MITE_CHOR(counter->mite_chan->channel));
 	}
 	mite_sync_input_dma(counter->mite_chan, s->async);
 	spin_unlock_irqrestore(&counter->lock, flags);
 }
 
 void ni_tio_set_mite_channel(struct ni_gpct *counter,
-	struct mite_channel *mite_chan)
+			     struct mite_channel *mite_chan)
 {
 	unsigned long flags;
 
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
index 7b72b7a..dd9db06 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -89,39 +89,41 @@ supported.
 #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)
-	}
+							   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)
-	}
+							      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)
-	}
+							     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)
+							     }
 };
 
 /*
@@ -146,7 +148,6 @@ struct pcl711_board {
 	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},
@@ -157,7 +158,8 @@ static const struct pcl711_board boardtypes[] = {
 #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_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",
@@ -183,7 +185,6 @@ struct pcl711_private {
 	unsigned int divisor2;
 };
 
-
 #define devpriv ((struct pcl711_private *)dev->private)
 
 static irqreturn_t pcl711_interrupt(int irq, void *d)
@@ -246,7 +247,7 @@ static void pcl711_set_changain(struct comedi_device *dev, int chan)
 }
 
 static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int i, n;
 	int hi, lo;
@@ -275,7 +276,7 @@ static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 		printk("comedi%d: pcl711: A/D timeout\n", dev->minor);
 		return -ETIME;
 
-	      ok:
+ok:
 		lo = inb(dev->iobase + PCL711_AD_LO);
 
 		data[n] = ((hi & 0xf) << 8) | lo;
@@ -284,8 +285,8 @@ static int pcl711_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return n;
 }
 
-static int pcl711_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int pcl711_ai_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int tmp;
 	int err = 0;
@@ -322,7 +323,7 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	/* step 2 */
 
 	if (cmd->scan_begin_src != TRIG_TIMER &&
-		cmd->scan_begin_src != TRIG_EXT)
+	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
 	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 		err++;
@@ -374,8 +375,10 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	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);
+					       &devpriv->divisor1,
+					       &devpriv->divisor2,
+					       &cmd->scan_begin_arg,
+					       cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
@@ -405,7 +408,8 @@ static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		 */
 
 		i8253_cascade_ns_to_timer(i8253_osc_base, &timer1, &timer2,
-			&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
+					  &cmd->scan_begin_arg,
+					  TRIG_ROUND_NEAREST);
 
 		outb(0x74, dev->iobase + PCL711_CTRCTL);
 		outb(timer1 & 0xff, dev->iobase + PCL711_CTR1);
@@ -433,16 +437,16 @@ static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
    analog output
 */
 static int pcl711_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  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));
+		     dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO));
 		outb((data[n] >> 8),
-			dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI));
+		     dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI));
 
 		devpriv->ao_readback[chan] = data[n];
 	}
@@ -450,8 +454,9 @@ static int pcl711_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return n;
 }
 
-static int pcl711_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -465,21 +470,23 @@ static int pcl711_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 }
 
 /* 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)
+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);
+	    (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)
+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;
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
index 699daff..df1f4ef 100644
--- a/drivers/staging/comedi/drivers/pcl724.c
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -56,7 +56,8 @@ See the source for configuration details.
 
 /* #define PCL724_IRQ   1  no IRQ support now */
 
-static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int pcl724_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcl724_detach(struct comedi_device *dev);
 
 struct pcl724_board {
@@ -70,7 +71,6 @@ struct pcl724_board {
 	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,},
@@ -108,7 +108,7 @@ static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
 }
 
 static int subdev_8255mapped_cb(int dir, int port, int data,
-	unsigned long iobase)
+				unsigned long iobase)
 {
 	int movport = SIZE_8255 * (iobase >> 12);
 
@@ -136,10 +136,10 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	iobase = it->options[0];
 	iorange = this_board->io_range;
 	if ((this_board->can_have96) && ((it->options[1] == 1)
-			|| (it->options[1] == 96)))
+					 || (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);
+	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "pcl724")) {
 		printk("I/O port conflict\n");
 		return -EIO;
@@ -156,14 +156,15 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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 %u is out of allowed range, DISABLING IT",
+				     irq);
 				irq = 0;	/* Bad IRQ */
 			} else {
-				if (request_irq(irq, interrupt_pcl724, 0, "pcl724", dev)) {
+				if (request_irq
+				    (irq, interrupt_pcl724, 0, "pcl724", dev)) {
 					printk
-						(", unable to allocate IRQ %u, DISABLING IT",
-						irq);
+					    (", unable to allocate IRQ %u, DISABLING IT",
+					     irq);
 					irq = 0;	/* Can't use IRQ */
 				} else {
 					printk(", irq=%u", irq);
@@ -179,7 +180,7 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	n_subdevices = this_board->numofports;
 	if ((this_board->can_have96) && ((it->options[1] == 1)
-			|| (it->options[1] == 96)))
+					 || (it->options[1] == 96)))
 		n_subdevices = 4;	/*  PCL-724 in 96 DIO configuration */
 
 	ret = alloc_subdevices(dev, n_subdevices);
@@ -189,12 +190,14 @@ static int pcl724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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));
+					 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));
+					 subdev_8255_cb,
+					 (unsigned long)(dev->iobase +
+							 SIZE_8255 * i));
 	};
 
 	return 0;
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c
index 1347624..1da4941 100644
--- a/drivers/staging/comedi/drivers/pcl725.c
+++ b/drivers/staging/comedi/drivers/pcl725.c
@@ -20,7 +20,8 @@ Devices: [Advantech] PCL-725 (pcl725)
 #define PCL725_DO 0
 #define PCL725_DI 1
 
-static int pcl725_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -32,7 +33,7 @@ static struct comedi_driver driver_pcl725 = {
 COMEDI_INITCLEANUP(driver_pcl725);
 
 static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -49,7 +50,7 @@ static int pcl725_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int pcl725_di_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
index 149e75f..ccadd09 100644
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -111,7 +111,8 @@ static const struct comedi_lrange *const rangelist_728[] = {
 	&range_4_20mA, &range_0_20mA
 };
 
-static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int pcl726_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcl726_detach(struct comedi_device *dev);
 
 struct pcl726_board {
@@ -129,23 +130,22 @@ struct pcl726_board {
 	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],},
+	 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],},
+	 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],},
+	 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],},
+	 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],},
+	 0, 0, 0, 0,
+	 &rangelist_728[0],},
 };
 
 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl726_board))
@@ -173,7 +173,7 @@ struct pcl726_private {
 #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)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	int hi, lo;
 	int n;
@@ -197,8 +197,9 @@ static int pcl726_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return n;
 }
 
-static int pcl726_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -209,20 +210,22 @@ static int pcl726_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int pcl726_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
+	    (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)
+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;
@@ -254,7 +257,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	iobase = it->options[0];
 	iorange = this_board->io_range;
 	printk("comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor,
-		this_board->name, iobase);
+	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "pcl726")) {
 		printk("I/O port conflict\n");
 		return -EIO;
@@ -281,15 +284,15 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		if (irq) {	/* we want to use IRQ */
 			if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
 				printk
-					(", IRQ %d is out of allowed range, DISABLING IT",
-					irq);
+				    (", IRQ %d is out of allowed range, DISABLING IT",
+				     irq);
 				irq = 0;	/* Bad IRQ */
 			} else {
 				if (request_irq(irq, interrupt_pcl818, 0,
 						"pcl726", dev)) {
 					printk
-						(", unable to allocate IRQ %d, DISABLING IT",
-						irq);
+					    (", unable to allocate IRQ %d, DISABLING IT",
+					     irq);
 					irq = 0;	/* Can't use IRQ */
 				} else {
 					printk(", irq=%d", irq);
@@ -322,12 +325,14 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 		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);
+			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->rangelist[i]->range[0].max)
 			devpriv->bipolar[i] = 1;	/* bipolar range */
 	}
 
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
index 408cbff..c9859c9 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -26,7 +26,8 @@ The ACL-7130 card have an 8254 timer/counter not supported by this driver.
 #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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcl730_detach(struct comedi_device *dev);
 
 struct pcl730_board {
@@ -35,7 +36,6 @@ struct pcl730_board {
 	unsigned int io_range;	/*  len of I/O space */
 };
 
-
 static const struct pcl730_board boardtypes[] = {
 	{"pcl730", PCL730_SIZE,},
 	{"iso730", PCL730_SIZE,},
@@ -58,7 +58,7 @@ static struct comedi_driver driver_pcl730 = {
 COMEDI_INITCLEANUP(driver_pcl730);
 
 static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -69,10 +69,10 @@ static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 	}
 	if (data[0] & 0x00ff)
 		outb(s->state & 0xff,
-			dev->iobase + ((unsigned long)s->private));
+		     dev->iobase + ((unsigned long)s->private));
 	if (data[0] & 0xff00)
 		outb((s->state >> 8),
-			dev->iobase + ((unsigned long)s->private) + 1);
+		     dev->iobase + ((unsigned long)s->private) + 1);
 
 	data[1] = s->state;
 
@@ -80,13 +80,13 @@ static int pcl730_do_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int pcl730_di_insn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			  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);
+	    (inb(dev->iobase + ((unsigned long)s->private) + 1) << 8);
 
 	return 2;
 }
@@ -100,7 +100,7 @@ static int pcl730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	iobase = it->options[0];
 	iorange = this_board->io_range;
 	printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
-		this_board->name, iobase);
+	       this_board->name, iobase);
 	if (!request_region(iobase, iorange, "pcl730")) {
 		printk("I/O port conflict\n");
 		return -EIO;
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
index dd91fe9..0b51a48 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -161,139 +161,159 @@ Options for ACL-8113, ISO-813:
 #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),
-	}
+							    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),
-	}
+							     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),
-	}
+							       BIP_RANGE(1.25),
+							       }
 };
+
 static const struct comedi_lrange range812_bipolar0_625 = { 1, {
-			BIP_RANGE(0.625),
-	}
+								BIP_RANGE
+								(0.625),
+								}
 };
+
 static const struct comedi_lrange range812_bipolar0_3125 = { 1, {
-			BIP_RANGE(0.3125),
-	}
+								 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),
-	}
+							   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),
-	}
+							    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),
-	}
+							    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),
-	}
+							      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),
-	}
+							    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),
-	}
+							      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),
-	}
+							     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),
-	}
+							       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),
-	}
+							     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),
-	}
+							       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),
-	}
+							     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),
-	}
+							      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),
-	}
+							   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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcl812_detach(struct comedi_device *dev);
 
 struct pcl812_board {
@@ -316,62 +336,61 @@ struct pcl812_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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 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},
+	 10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+	 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
 };
 
 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl812_board))
@@ -410,7 +429,7 @@ struct pcl812_private {
 	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 */
+	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 */
@@ -424,22 +443,24 @@ struct pcl812_private {
 	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 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)
+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;
@@ -457,12 +478,12 @@ static int pcl812_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 			udelay(1);
 		}
 		printk
-			("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
-			dev->minor, dev->board_name, dev->iobase);
+		    ("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:
+conv_finish:
 		data[n] = ((hi & 0xf) << 8) | inb(dev->iobase + PCL812_AD_LO);
 	}
 	outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
@@ -472,8 +493,9 @@ static int pcl812_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 /*
 ==============================================================================
 */
-static int acl8216_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -490,16 +512,15 @@ static int acl8216_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 			udelay(1);
 		}
 		printk
-			("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
-			dev->minor, dev->board_name, dev->iobase);
+		    ("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:
+conv_finish:
 		data[n] =
-			(inb(dev->iobase +
-				PCL812_AD_HI) << 8) | inb(dev->iobase +
-			PCL812_AD_LO);
+		    (inb(dev->iobase +
+			 PCL812_AD_HI) << 8) | inb(dev->iobase + PCL812_AD_LO);
 	}
 	outb(0, dev->iobase + PCL812_MODE);
 	return n;
@@ -508,17 +529,18 @@ static int acl8216_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pcl812_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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));
+		     dev->iobase + (chan ? PCL812_DA2_LO : PCL812_DA1_LO));
 		outb((data[i] >> 8) & 0x0f,
-			dev->iobase + (chan ? PCL812_DA2_HI : PCL812_DA1_HI));
+		     dev->iobase + (chan ? PCL812_DA2_HI : PCL812_DA1_HI));
 		devpriv->ao_readback[chan] = data[i];
 	}
 
@@ -528,8 +550,9 @@ static int pcl812_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static int pcl812_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -544,8 +567,9 @@ static int pcl812_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 /*
 ==============================================================================
 */
-static int pcl812_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -559,8 +583,9 @@ static int pcl812_di_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 /*
 ==============================================================================
 */
-static int pcl812_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -583,21 +608,21 @@ static int pcl812_do_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 static void pcl812_cmdtest_out(int e, struct comedi_cmd *cmd)
 {
 	printk("pcl812 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
-		cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+	       cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
 	printk("pcl812 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
-		cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+	       cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
 	printk("pcl812 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
-		cmd->scan_end_src);
+	       cmd->scan_end_src);
 	printk("pcl812 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
-		cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+	       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)
+static int pcl812_ai_cmdtest(struct comedi_device *dev,
+			     struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp, divisor1, divisor2;
@@ -641,8 +666,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 #ifdef PCL812_EXTDEBUG
 		pcl812_cmdtest_out(1, cmd);
 		printk
-			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=1\n",
-			err);
+		    ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=1\n",
+		     err);
 #endif
 		return 1;
 	}
@@ -683,8 +708,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 #ifdef PCL812_EXTDEBUG
 		pcl812_cmdtest_out(2, cmd);
 		printk
-			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=2\n",
-			err);
+		    ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=2\n",
+		     err);
 #endif
 		return 2;
 	}
@@ -741,8 +766,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 #ifdef PCL812_EXTDEBUG
 		pcl812_cmdtest_out(3, cmd);
 		printk
-			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=3\n",
-			err);
+		    ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=3\n",
+		     err);
 #endif
 		return 3;
 	}
@@ -752,8 +777,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	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);
+					  &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)
@@ -763,8 +788,8 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	if (err) {
 #ifdef PCL812_EXTDEBUG
 		printk
-			("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=4\n",
-			err);
+		    ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=4\n",
+		     err);
 #endif
 		return 4;
 	}
@@ -806,15 +831,16 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		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);
+					  &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);
+	       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 */
@@ -851,19 +877,19 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	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->ai_n_chan * sizeof(short);
 			devpriv->dmabytestomove[1] =
-				devpriv->ai_n_chan * sizeof(short);
+			    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;
+				    devpriv->ai_data_len;
 			if (devpriv->ai_data_len < devpriv->hwdmasize[1])
 				devpriv->dmabytestomove[1] =
-					devpriv->ai_data_len;
+				    devpriv->ai_data_len;
 			if (devpriv->ai_neverending) {
 				devpriv->dma_runs_to_end = 1;
 			} else {
@@ -872,7 +898,7 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 				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->last_dma_run;
 				devpriv->dma_runs_to_end--;
 			}
 		}
@@ -894,10 +920,10 @@ static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		enable_dma(devpriv->dma);
 #ifdef PCL812_EXTDEBUG
 		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);
+		    ("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
 	}
 
@@ -955,8 +981,8 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
 
 	if (err) {
 		printk
-			("comedi%d: pcl812: (%s at 0x%lx) A/D cmd IRQ without DRDY!\n",
-			dev->minor, dev->board_name, dev->iobase);
+		    ("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);
@@ -964,8 +990,8 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
 	}
 
 	comedi_buf_put(s->async,
-		((inb(dev->iobase + PCL812_AD_HI) << 8) | inb(dev->iobase +
-				PCL812_AD_LO)) & mask);
+		       ((inb(dev->iobase + PCL812_AD_HI) << 8) |
+			inb(dev->iobase + PCL812_AD_LO)) & mask);
 
 	outb(0, dev->iobase + PCL812_CLRINT);	/* clear INT request */
 
@@ -985,8 +1011,9 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
 /*
 ==============================================================================
 */
-static void transfer_from_dma_buf(struct comedi_device *dev, struct comedi_subdevice *s,
-	short *ptr, unsigned int bufptr, unsigned int len)
+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;
 
@@ -1022,9 +1049,9 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
 #ifdef PCL812_EXTDEBUG
 	printk("pcl812 EDBG: BGN: interrupt_pcl812_ai_dma(...)\n");
 #endif
-	ptr = (short *) devpriv->dmabuf[devpriv->next_dma_buf];
+	ptr = (short *)devpriv->dmabuf[devpriv->next_dma_buf];
 	len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
-		devpriv->ai_poll_ptr;
+	    devpriv->ai_poll_ptr;
 
 	devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
 	disable_dma(devpriv->dma);
@@ -1033,11 +1060,12 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
 	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]);
+			      devpriv->dmabytestomove[devpriv->next_dma_buf]);
 	} else {
 		if (devpriv->dma_runs_to_end) {
 			set_dma_count(devpriv->dma,
-				devpriv->dmabytestomove[devpriv->next_dma_buf]);
+				      devpriv->dmabytestomove[devpriv->
+							      next_dma_buf]);
 		} else {
 			set_dma_count(devpriv->dma, devpriv->last_dma_run);
 		}
@@ -1111,8 +1139,9 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 	}
 
 	transfer_from_dma_buf(dev, s,
-		(void *)devpriv->dmabuf[1 - devpriv->next_dma_buf],
-		devpriv->ai_poll_ptr, top2);
+			      (void *)devpriv->dmabuf[1 -
+						      devpriv->next_dma_buf],
+			      devpriv->ai_poll_ptr, top2);
 
 	devpriv->ai_poll_ptr = top1;	/*  new buffer position */
 
@@ -1124,14 +1153,15 @@ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 /*
 ==============================================================================
 */
-static void setup_range_channel(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int rangechan, char wait)
+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))
+	    && (gain_reg == devpriv->old_gain_reg))
 		return;		/*  we can return, no change */
 
 	devpriv->old_chan_reg = chan_reg;
@@ -1160,12 +1190,12 @@ static void setup_range_channel(struct comedi_device *dev, struct comedi_subdevi
 /*
 ==============================================================================
 */
-static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
-	unsigned int divisor2)
+static void start_pacer(struct comedi_device *dev, int mode,
+			unsigned int divisor1, unsigned int divisor2)
 {
 #ifdef PCL812_EXTDEBUG
 	printk("pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode, divisor1,
-		divisor2);
+	       divisor2);
 #endif
 	outb(0xb4, dev->iobase + PCL812_CTRCTL);
 	outb(0x74, dev->iobase + PCL812_CTRCTL);
@@ -1205,7 +1235,8 @@ static void free_resources(struct comedi_device *dev)
 /*
 ==============================================================================
 */
-static int pcl812_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int pcl812_ai_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 #ifdef PCL812_EXTDEBUG
 	printk("pcl812 EDBG: BGN: pcl812_ai_cancel(...)\n");
@@ -1279,7 +1310,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	iobase = it->options[0];
 	printk("comedi%d: pcl812:  board=%s, ioport=0x%03lx", dev->minor,
-		this_board->name, iobase);
+	       this_board->name, iobase);
 
 	if (!request_region(iobase, this_board->io_range, "pcl812")) {
 		printk("I/O port conflict\n");
@@ -1300,11 +1331,16 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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);
+				printk
+				    (", IRQ %u is out of allowed range, DISABLING IT",
+				     irq);
 				irq = 0;	/* Bad IRQ */
 			} else {
-				if (request_irq(irq, interrupt_pcl812, 0, "pcl812", dev)) {
-					printk(", unable to allocate IRQ %u, DISABLING IT", irq);
+				if (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);
@@ -1353,7 +1389,7 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);
 		devpriv->hwdmasize[1] = PAGE_SIZE * (1 << pages);
 	}
-      no_dma:
+no_dma:
 
 	n_subdevices = 0;
 	if (this_board->n_aichan > 0)
@@ -1450,7 +1486,9 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			default:
 				s->range_table = &range_bipolar10;
 				break;
-				printk(", incorrect range number %d, changing to 0 (+/-10V)", it->options[4]);
+				printk
+				    (", incorrect range number %d, changing to 0 (+/-10V)",
+				     it->options[4]);
 				break;
 			}
 			break;
@@ -1478,7 +1516,9 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			default:
 				s->range_table = &range_iso813_1_ai;
 				break;
-				printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+				printk
+				    (", incorrect range number %d, changing to 0 ",
+				     it->options[1]);
 				break;
 			}
 			break;
@@ -1501,7 +1541,9 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			default:
 				s->range_table = &range_acl8113_1_ai;
 				break;
-				printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+				printk
+				    (", incorrect range number %d, changing to 0 ",
+				     it->options[1]);
 				break;
 			}
 			break;
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
index 19465c1..fa24145 100644
--- a/drivers/staging/comedi/drivers/pcl816.c
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -91,16 +91,17 @@ Configuration Options:
 #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),
-	}
+						       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 */
@@ -122,33 +123,33 @@ struct pcl816_board {
 	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},
+	 &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},
+	 &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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcl816_detach(struct comedi_device *dev);
 
 #ifdef unused
@@ -209,29 +210,32 @@ struct pcl816_private {
 #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);
+					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_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)
+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;
@@ -253,12 +257,12 @@ static int pcl816_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 		timeout = 100;
 		while (timeout--) {
 			if (!(inb(dev->iobase + PCL816_STATUS) &
-					PCL816_STATUS_DRDY_MASK)) {
+			      PCL816_STATUS_DRDY_MASK)) {
 				/*  return read value */
 				data[n] =
-					((inb(dev->iobase +
-							PCL816_AD_HI) << 8) |
-					(inb(dev->iobase + PCL816_AD_LO)));
+				    ((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;
@@ -291,7 +295,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
 
 	while (timeout--) {
 		if (!(inb(dev->iobase + PCL816_STATUS) &
-				PCL816_STATUS_DRDY_MASK))
+		      PCL816_STATUS_DRDY_MASK))
 			break;
 		udelay(1);
 	}
@@ -334,8 +338,9 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
 ==============================================================================
    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)
+static void transfer_from_dma_buf(struct comedi_device *dev,
+				  struct comedi_subdevice *s, short *ptr,
+				  unsigned int bufptr, unsigned int len)
 {
 	int i;
 
@@ -346,7 +351,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, struct comedi_subde
 		comedi_buf_put(s->async, ptr[bufptr++]);
 
 		if (++devpriv->ai_act_chanlist_pos >=
-			devpriv->ai_act_chanlist_len) {
+		    devpriv->ai_act_chanlist_len) {
 			devpriv->ai_act_chanlist_pos = 0;
 			devpriv->ai_act_scan++;
 		}
@@ -381,10 +386,11 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
 		dma_flags = claim_dma_lock();
 /* clear_dma_ff (devpriv->dma); */
 		set_dma_addr(devpriv->dma,
-			devpriv->hwdmaptr[devpriv->next_dma_buf]);
+			     devpriv->hwdmaptr[devpriv->next_dma_buf]);
 		if (devpriv->dma_runs_to_end) {
 			set_dma_count(devpriv->dma,
-				devpriv->hwdmasize[devpriv->next_dma_buf]);
+				      devpriv->hwdmasize[devpriv->
+							 next_dma_buf]);
 		} else {
 			set_dma_count(devpriv->dma, devpriv->last_dma_run);
 		}
@@ -395,7 +401,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
 	devpriv->dma_runs_to_end--;
 	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
 
-	ptr = (short *) devpriv->dmabuf[this_dma_buf];
+	ptr = (short *)devpriv->dmabuf[this_dma_buf];
 
 	len = (devpriv->hwdmasize[0] >> 1) - devpriv->ai_poll_ptr;
 	bufptr = devpriv->ai_poll_ptr;
@@ -430,7 +436,7 @@ static irqreturn_t interrupt_pcl816(int irq, void *d)
 
 	outb(0, dev->iobase + PCL816_CLRINT);	/* clear INT request */
 	if ((!dev->irq) | (!devpriv->irq_free) | (!devpriv->irq_blocked) |
-		(!devpriv->int816_mode)) {
+	    (!devpriv->int816_mode)) {
 		if (devpriv->irq_was_now_closed) {
 			devpriv->irq_was_now_closed = 0;
 			/*  comedi_error(dev,"last IRQ.."); */
@@ -450,26 +456,26 @@ static irqreturn_t interrupt_pcl816(int irq, void *d)
 static void pcl816_cmdtest_out(int e, struct comedi_cmd *cmd)
 {
 	printk("pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
-		cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+	       cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
 	printk("pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
-		cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+	       cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
 	printk("pcl816 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
-		cmd->scan_end_src);
+	       cmd->scan_end_src);
 	printk("pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
-		cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+	       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)
+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(printk("pcl816 pcl812_ai_cmdtest\n");
-		pcl816_cmdtest_out(-1, cmd););
+	DEBUG(printk("pcl816 pcl812_ai_cmdtest\n"); pcl816_cmdtest_out(-1, cmd);
+	    );
 
 	/* step 1: make sure trigger sources are trivially valid */
 	tmp = cmd->start_src;
@@ -582,8 +588,9 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	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);
+					  &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)
@@ -619,8 +626,8 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			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);
+					  &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;
@@ -634,7 +641,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
 
 	if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
-			cmd->chanlist_len))
+					  cmd->chanlist_len))
 		return -EINVAL;
 	udelay(1);
 
@@ -732,8 +739,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 	}
 
 	transfer_from_dma_buf(dev, s,
-		(short *) devpriv->dmabuf[devpriv->next_dma_buf],
-		devpriv->ai_poll_ptr, top2);
+			      (short *)devpriv->dmabuf[devpriv->next_dma_buf],
+			      devpriv->ai_poll_ptr, top2);
 
 	devpriv->ai_poll_ptr = top1;	/*  new buffer position */
 	spin_unlock_irqrestore(&dev->spinlock, flags);
@@ -745,7 +752,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 ==============================================================================
  cancel any mode 1-4 AI
 */
-static int pcl816_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int pcl816_ai_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 /* DEBUG(printk("pcl816_ai_cancel()\n");) */
 
@@ -781,9 +789,8 @@ static int pcl816_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *
 		}
 	}
 
-	DEBUG(printk("comedi: pcl816_ai_cancel() successful\n");
-		)
-		return 0;
+	DEBUG(printk("comedi: pcl816_ai_cancel() successful\n");)
+	    return 0;
 }
 
 /*
@@ -836,7 +843,7 @@ static void pcl816_reset(struct comedi_device *dev)
 */
 static void
 start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
-	unsigned int divisor2)
+	    unsigned int divisor2)
 {
 	outb(0x32, dev->iobase + PCL816_CTRCTL);
 	outb(0xff, dev->iobase + PCL816_CTR0);
@@ -865,8 +872,9 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
  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)
+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;
@@ -882,18 +890,17 @@ check_and_setup_channel_list(struct comedi_device *dev, struct comedi_subdevice
 		for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
 			/*  build part of chanlist */
 			DEBUG(printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]),
-					CR_RANGE(chanlist[i]));
-				)
-				if (chanlist[0] == 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;
+			    (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
 			if (nowmustbechan != CR_CHAN(chanlist[i])) {
 				/*  channel list isn't continous :-( */
 				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]));
+				    ("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 */
@@ -901,20 +908,19 @@ check_and_setup_channel_list(struct comedi_device *dev, struct comedi_subdevice
 
 		for (i = 0, segpos = 0; i < chanlen; i++) {	/*  check whole chanlist */
 			DEBUG(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]) {
+				     CR_CHAN(chansegment[i % seglen]),
+				     CR_RANGE(chansegment[i % seglen]),
+				     CR_CHAN(chanlist[i]),
+				     CR_RANGE(chanlist[i]));)
+			    if (chanlist[i] != chansegment[i % seglen]) {
 				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]));
+				    ("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 */
 			}
 		}
@@ -997,7 +1003,7 @@ static void free_resources(struct comedi_device *dev)
 		if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
 			if (devpriv->rtc_iobase)
 				release_region(devpriv->rtc_iobase,
-					devpriv->rtc_iosize);
+					       devpriv->rtc_iosize);
 		}
 #endif
 	}
@@ -1027,7 +1033,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* claim our I/O space */
 	iobase = it->options[0];
 	printk("comedi%d: pcl816:  board=%s, ioport=0x%03lx", dev->minor,
-		this_board->name, iobase);
+	       this_board->name, iobase);
 
 	if (!request_region(iobase, this_board->io_range, "pcl816")) {
 		printk("I/O port conflict\n");
@@ -1055,14 +1061,15 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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 %u is out of allowed range, DISABLING IT",
+				     irq);
 				irq = 0;	/* Bad IRQ */
 			} else {
-				if (request_irq(irq, interrupt_pcl816, 0, "pcl816", dev)) {
+				if (request_irq
+				    (irq, interrupt_pcl816, 0, "pcl816", dev)) {
 					printk
-						(", unable to allocate IRQ %u, DISABLING IT",
-						irq);
+					    (", unable to allocate IRQ %u, DISABLING IT",
+					     irq);
 					irq = 0;	/* Can't use IRQ */
 				} else {
 					printk(", irq=%u", irq);
@@ -1087,7 +1094,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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)"))
+					    "pcl816 (RTC)"))
 				goto no_rtc;
 		}
 		devpriv->rtc_iobase = RTC_PORT(0);
@@ -1095,7 +1102,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		RTC_lock++;
 #ifdef UNTESTED_CODE
 		if (!request_irq(RTC_IRQ, interrupt_pcl816_ai_mode13_dma_rtc, 0,
-				"pcl816 DMA (RTC)", dev)) {
+				 "pcl816 DMA (RTC)", dev)) {
 			devpriv->dma_rtc = 1;
 			devpriv->rtc_irq = RTC_IRQ;
 			printk(", dma_irq=%u", devpriv->rtc_irq);
@@ -1104,7 +1111,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			if (RTC_lock == 0) {
 				if (devpriv->rtc_iobase)
 					release_region(devpriv->rtc_iobase,
-						devpriv->rtc_iosize);
+						       devpriv->rtc_iosize);
 			}
 			devpriv->rtc_iobase = 0;
 			devpriv->rtc_iosize = 0;
@@ -1115,7 +1122,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	}
 
-      no_rtc:
+no_rtc:
 #endif
 	/* grab our DMA */
 	dma = 0;
@@ -1157,17 +1164,17 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
 			if (!devpriv->dmabuf[1]) {
 				printk
-					(", unable to allocate DMA buffer, FAIL!\n");
+				    (", unable to allocate DMA buffer, FAIL!\n");
 				return -EBUSY;
 			}
 			devpriv->dmapages[1] = pages;
 			devpriv->hwdmaptr[1] =
-				virt_to_bus((void *)devpriv->dmabuf[1]);
+			    virt_to_bus((void *)devpriv->dmabuf[1]);
 			devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
 		}
 	}
 
-      no_dma:
+no_dma:
 
 /*  if (this_board->n_aochan > 0)
     subdevs[1] = COMEDI_SUBD_AO;
@@ -1241,9 +1248,8 @@ case COMEDI_SUBD_DO:
  */
 static int pcl816_detach(struct comedi_device *dev)
 {
-	DEBUG(printk("comedi%d: pcl816: remove\n", dev->minor);
-		)
-		free_resources(dev);
+	DEBUG(printk("comedi%d: pcl816: remove\n", dev->minor);)
+	    free_resources(dev);
 #ifdef unused
 	if (devpriv->dma_rtc)
 		RTC_lock--;
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 039a77a..e95229b 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -195,56 +195,58 @@ A word or two about DMA. Driver support DMA operations at two ways:
 #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),
-	}
+							   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),
-	}
+							     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),
-	}
+							     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),
-	}
+							     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_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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcl818_detach(struct comedi_device *dev);
 
 #ifdef unused
@@ -273,30 +275,29 @@ struct pcl818_board {
 	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},
+	 &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},
+	 &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},
+	 &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},
+	 &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},
+	 &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},
+	 &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 ? */ },
+	 &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+	 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ },
 };
 
 #define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl818_board))
@@ -353,7 +354,7 @@ struct pcl818_private {
 	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 */
+	short *ai_data;		/*  data buffer */
 	unsigned int ai_timer1;	/*  timers */
 	unsigned int ai_timer2;
 	struct comedi_subdevice *sub_ai;	/*  ptr to AI subdevice */
@@ -361,7 +362,6 @@ struct pcl818_private {
 	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
 };
@@ -372,14 +372,18 @@ static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0
 /*
 ==============================================================================
 */
-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);
+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);
@@ -391,8 +395,9 @@ static int rtc_setfreq_irq(int freq);
 ==============================================================================
    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)
+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;
@@ -425,9 +430,9 @@ static int pcl818_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 		outb(0, dev->iobase + PCL818_CLRINT);
 		return -EIO;
 
-	      conv_finish:
+conv_finish:
 		data[n] = ((inb(dev->iobase + PCL818_AD_HI) << 4) |
-			(inb(dev->iobase + PCL818_AD_LO) >> 4));
+			   (inb(dev->iobase + PCL818_AD_LO) >> 4));
 	}
 
 	return n;
@@ -438,8 +443,9 @@ static int pcl818_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
    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)
+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);
@@ -451,8 +457,9 @@ static int pcl818_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int pcl818_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -460,9 +467,9 @@ static int pcl818_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 	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));
+		     (chan ? PCL718_DA2_LO : PCL818_DA_LO));
 		outb((data[n] & 0x0ff0) >> 4, dev->iobase +
-			(chan ? PCL718_DA2_HI : PCL818_DA_HI));
+		     (chan ? PCL718_DA2_HI : PCL818_DA_HI));
 	}
 
 	return n;
@@ -474,14 +481,15 @@ static int pcl818_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 
    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)
+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);
+	    (inb(dev->iobase + PCL818_DI_HI) << 8);
 
 	return 2;
 }
@@ -492,8 +500,9 @@ static int pcl818_di_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 
    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)
+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;
@@ -533,16 +542,16 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
 	comedi_event(dev, s);
 	return IRQ_HANDLED;
 
-      conv_finish:
+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! */
 		printk
-			("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
-			(low & 0xf),
-			devpriv->act_chanlist[devpriv->act_chanlist_pos]);
+		    ("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);
@@ -581,10 +590,11 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
 		set_dma_mode(devpriv->dma, DMA_MODE_READ);
 		flags = claim_dma_lock();
 		set_dma_addr(devpriv->dma,
-			devpriv->hwdmaptr[devpriv->next_dma_buf]);
+			     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]);
+				      devpriv->hwdmasize[devpriv->
+							 next_dma_buf]);
 		} else {
 			set_dma_count(devpriv->dma, devpriv->last_dma_run);
 		}
@@ -595,7 +605,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
 
 	devpriv->dma_runs_to_end--;
 	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
-	ptr = (short *) devpriv->dmabuf[1 - devpriv->next_dma_buf];
+	ptr = (short *)devpriv->dmabuf[1 - devpriv->next_dma_buf];
 
 	len = devpriv->hwdmasize[0] >> 1;
 	bufptr = 0;
@@ -603,11 +613,10 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
 	for (i = 0; i < len; i++) {
 		if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	/*  dropout! */
 			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);
+			    ("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);
@@ -649,7 +658,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
 	unsigned long tmp;
 	unsigned int top1, top2, i, bufptr;
 	long ofs_dats;
-	short *dmabuf = (short *) devpriv->dmabuf[0];
+	short *dmabuf = (short *)devpriv->dmabuf[0];
 
 	/* outb(2,0x378); */
 	switch (devpriv->ai_mode) {
@@ -657,7 +666,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
 	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);
+			  jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
 
 		for (i = 0; i < 10; i++) {
 			top1 = get_dma_residue(devpriv->dma);
@@ -694,13 +703,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
 		for (i = 0; i < ofs_dats; i++) {
 			if ((dmabuf[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	/*  dropout! */
 				printk
-					("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",
-					(dmabuf[bufptr] & 0xf),
-					devpriv->act_chanlist[devpriv->
-						act_chanlist_pos]);
+				    ("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_CB_EOA | COMEDI_CB_ERROR;
 				comedi_event(dev, s);
 				return IRQ_HANDLED;
 			}
@@ -776,10 +785,9 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
 		lo = inb(dev->iobase + PCL818_FI_DATALO);
 		if ((lo & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {	/*  dropout! */
 			printk
-				("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n",
-				(lo & 0xf),
-				devpriv->act_chanlist[devpriv->
-					act_chanlist_pos]);
+			    ("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);
@@ -822,9 +830,9 @@ static irqreturn_t interrupt_pcl818(int irq, void *d)
 
 	if (devpriv->irq_blocked && devpriv->irq_was_now_closed) {
 		if ((devpriv->neverending_ai || (!devpriv->neverending_ai &&
-						devpriv->ai_act_scan > 0)) &&
-				(devpriv->ai_mode == INT_TYPE_AI1_DMA ||
-				 devpriv->ai_mode == INT_TYPE_AI3_DMA)) {
+						 devpriv->ai_act_scan > 0)) &&
+		    (devpriv->ai_mode == INT_TYPE_AI1_DMA ||
+		     devpriv->ai_mode == INT_TYPE_AI3_DMA)) {
 			/* The cleanup from ai_cancel() has been delayed
 			   until now because the card doesn't seem to like
 			   being reprogrammed while a DMA transfer is in
@@ -863,7 +871,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d)
 	outb(0, dev->iobase + PCL818_CLRINT);	/* clear INT request */
 
 	if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked)
-		|| (!devpriv->ai_mode)) {
+	    || (!devpriv->ai_mode)) {
 		comedi_error(dev, "bad IRQ!");
 		return IRQ_NONE;
 	}
@@ -877,7 +885,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d)
    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)
+				    struct comedi_subdevice *s)
 {
 	unsigned int flags;
 	unsigned int bytes;
@@ -918,7 +926,7 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev,
    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)
+				    struct comedi_subdevice *s)
 {
 	unsigned int flags;
 	short *pole;
@@ -931,13 +939,13 @@ static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev,
 	release_dma_lock(flags);
 	enable_dma(devpriv->dma);
 	devpriv->last_top_dma = 0;	/* devpriv->hwdmasize[0]; */
-	pole = (short *) devpriv->dmabuf[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;
+	    jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100;
 	devpriv->rtc_irq_timer.data = (unsigned long)dev;
 	devpriv->rtc_irq_timer.function = rtc_dropped_irq;
 
@@ -959,7 +967,7 @@ static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev,
    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_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
 	int divisor1, divisor2;
@@ -977,11 +985,11 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
 	start_pacer(dev, -1, 0, 0);	/*  stop pacer */
 
 	seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
-		devpriv->ai_n_chan);
+				    devpriv->ai_n_chan);
 	if (seglen < 1)
 		return -EINVAL;
 	setup_channel_list(dev, s, devpriv->ai_chanlist,
-		devpriv->ai_n_chan, seglen);
+			   devpriv->ai_n_chan, seglen);
 
 	udelay(1);
 
@@ -998,7 +1006,8 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
 
 	if (mode == 1) {
 		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
-			&divisor2, &cmd->convert_arg, TRIG_ROUND_NEAREST);
+					  &divisor2, &cmd->convert_arg,
+					  TRIG_ROUND_NEAREST);
 		if (divisor1 == 1) {	/* PCL718/818 crash if any divisor is set to 1 */
 			divisor1 = 2;
 			divisor2 /= 2;
@@ -1034,11 +1043,13 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
 			if (mode == 1) {
 				devpriv->ai_mode = INT_TYPE_AI1_INT;
 				/* Pacer+IRQ */
-				outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);
+				outb(0x83 | (dev->irq << 4),
+				     dev->iobase + PCL818_CONTROL);
 			} else {
 				devpriv->ai_mode = INT_TYPE_AI3_INT;
 				/* Ext trig+IRQ */
-				outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL);
+				outb(0x82 | (dev->irq << 4),
+				     dev->iobase + PCL818_CONTROL);
 			}
 		} else {
 			/* FIFO */
@@ -1075,8 +1086,8 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev,
    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)
+static int pcl818_ao_mode13(int mode, struct comedi_device *dev,
+			    struct comedi_subdevice *s, comedi_trig * it)
 {
 	int divisor1, divisor2;
 
@@ -1099,7 +1110,8 @@ static int pcl818_ao_mode13(int mode, struct comedi_device *dev, struct comedi_s
 
 	if (mode == 1) {
 		i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
-			&divisor2, &it->trigvar, TRIG_ROUND_NEAREST);
+					  &divisor2, &it->trigvar,
+					  TRIG_ROUND_NEAREST);
 		if (divisor1 == 1) {	/* PCL818 crash if any divisor is set to 1 */
 			divisor1 = 2;
 			divisor2 /= 2;
@@ -1128,8 +1140,8 @@ static int pcl818_ao_mode13(int mode, struct comedi_device *dev, struct comedi_s
 ==============================================================================
    ANALOG OUTPUT MODE 1, 818 cards
 */
-static int pcl818_ao_mode1(struct comedi_device *dev, struct comedi_subdevice *s,
-	comedi_trig *it)
+static int pcl818_ao_mode1(struct comedi_device *dev,
+			   struct comedi_subdevice *s, comedi_trig * it)
 {
 	return pcl818_ao_mode13(1, dev, s, it);
 }
@@ -1138,8 +1150,8 @@ static int pcl818_ao_mode1(struct comedi_device *dev, struct comedi_subdevice *s
 ==============================================================================
    ANALOG OUTPUT MODE 3, 818 cards
 */
-static int pcl818_ao_mode3(struct comedi_device *dev, struct comedi_subdevice *s,
-	comedi_trig *it)
+static int pcl818_ao_mode3(struct comedi_device *dev,
+			   struct comedi_subdevice *s, comedi_trig * it)
 {
 	return pcl818_ao_mode13(3, dev, s, it);
 }
@@ -1150,8 +1162,8 @@ static int pcl818_ao_mode3(struct comedi_device *dev, struct comedi_subdevice *s
 ==============================================================================
  Start/stop pacer onboard pacer
 */
-static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
-	unsigned int divisor2)
+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);
@@ -1170,8 +1182,9 @@ static void start_pacer(struct comedi_device *dev, int mode, unsigned int diviso
  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)
+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;
@@ -1196,12 +1209,12 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 			if (chanlist[0] == chanlist[i])
 				break;
 			nowmustbechan =
-				(CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+			    (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
 			if (nowmustbechan != CR_CHAN(chanlist[i])) {	/*  channel list isn't continous :-( */
 				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]));
+				    ("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 */
@@ -1213,13 +1226,13 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 			/* 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]) {
 				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]));
+				    ("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 */
 			}
 		}
@@ -1230,8 +1243,10 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
 	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)
+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;
 
@@ -1248,7 +1263,8 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevic
 
 	/* select channel interval to scan */
 	outb(devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen -
-				1] << 4), dev->iobase + PCL818_MUX);
+							       1] << 4),
+	     dev->iobase + PCL818_MUX);
 }
 
 /*
@@ -1268,7 +1284,7 @@ static int check_single_ended(unsigned int port)
 ==============================================================================
 */
 static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+		      struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp, divisor1, divisor2;
@@ -1386,8 +1402,8 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 	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);
+					  &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)
@@ -1402,7 +1418,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
 
 	if (cmd->chanlist) {
 		if (!check_channel_list(dev, s, cmd->chanlist,
-				cmd->chanlist_len))
+					cmd->chanlist_len))
 			return 5;	/*  incorrect channels list */
 	}
 
@@ -1451,7 +1467,8 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 ==============================================================================
  cancel any mode 1-4 AI
 */
-static int pcl818_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int pcl818_ai_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	if (devpriv->irq_blocked > 0) {
 		printk("pcl818_ai_cancel()\n");
@@ -1467,8 +1484,8 @@ static int pcl818_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *
 		case INT_TYPE_AI1_DMA:
 		case INT_TYPE_AI3_DMA:
 			if (devpriv->neverending_ai ||
-					(!devpriv->neverending_ai &&
-					 devpriv->ai_act_scan > 0)) {
+			    (!devpriv->neverending_ai &&
+			     devpriv->ai_act_scan > 0)) {
 				/* wait for running dma transfer to end, do cleanup in interrupt */
 				goto end;
 			}
@@ -1503,7 +1520,7 @@ static int pcl818_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *
 		}
 	}
 
-      end:
+end:
 	printk("pcl818_ai_cancel() end\n");
 	return 0;
 }
@@ -1612,7 +1629,7 @@ static void rtc_dropped_irq(unsigned long data)
 	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);
+			  jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
 		save_flags(flags);
 		cli();
 		tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);	/* restart */
@@ -1674,7 +1691,7 @@ static void free_resources(struct comedi_device *dev)
 		if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
 			if (devpriv->rtc_iobase)
 				release_region(devpriv->rtc_iobase,
-					devpriv->rtc_iosize);
+					       devpriv->rtc_iosize);
 		}
 		if (devpriv->dma_rtc)
 			RTC_lock--;
@@ -1710,7 +1727,7 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* claim our I/O space */
 	iobase = it->options[0];
 	printk("comedi%d: pcl818:  board=%s, ioport=0x%03lx",
-		dev->minor, this_board->name, iobase);
+	       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;
@@ -1737,14 +1754,15 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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 %u is out of allowed range, DISABLING IT",
+				     irq);
 				irq = 0;	/* Bad IRQ */
 			} else {
-				if (request_irq(irq, interrupt_pcl818, 0, "pcl818", dev)) {
+				if (request_irq
+				    (irq, interrupt_pcl818, 0, "pcl818", dev)) {
 					printk
-						(", unable to allocate IRQ %u, DISABLING IT",
-						irq);
+					    (", unable to allocate IRQ %u, DISABLING IT",
+					     irq);
 					irq = 0;	/* Can't use IRQ */
 				} else {
 					printk(", irq=%u", irq);
@@ -1769,14 +1787,14 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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)"))
+					    "pcl818 (RTC)"))
 				goto no_rtc;
 		}
 		devpriv->rtc_iobase = RTC_PORT(0);
 		devpriv->rtc_iosize = RTC_IO_EXTENT;
 		RTC_lock++;
 		if (!request_irq(RTC_IRQ, interrupt_pcl818_ai_mode13_dma_rtc, 0,
-				"pcl818 DMA (RTC)", dev)) {
+				 "pcl818 DMA (RTC)", dev)) {
 			devpriv->dma_rtc = 1;
 			devpriv->rtc_irq = RTC_IRQ;
 			printk(", dma_irq=%u", devpriv->rtc_irq);
@@ -1785,14 +1803,14 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			if (RTC_lock == 0) {
 				if (devpriv->rtc_iobase)
 					release_region(devpriv->rtc_iobase,
-						devpriv->rtc_iosize);
+						       devpriv->rtc_iosize);
 			}
 			devpriv->rtc_iobase = 0;
 			devpriv->rtc_iosize = 0;
 		}
 	}
 
-      no_rtc:
+no_rtc:
 #endif
 	/* grab our DMA */
 	dma = 0;
@@ -1829,17 +1847,17 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
 			if (!devpriv->dmabuf[1]) {
 				printk
-					(", unable to allocate DMA buffer, FAIL!\n");
+				    (", unable to allocate DMA buffer, FAIL!\n");
 				return -EBUSY;
 			}
 			devpriv->dmapages[1] = pages;
 			devpriv->hwdmaptr[1] =
-				virt_to_bus((void *)devpriv->dmabuf[1]);
+			    virt_to_bus((void *)devpriv->dmabuf[1]);
 			devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
 		}
 	}
 
-      no_dma:
+no_dma:
 
 	ret = alloc_subdevices(dev, 4);
 	if (ret < 0)
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
index a5d6b1d..5281182 100644
--- a/drivers/staging/comedi/drivers/pcm3724.c
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -62,7 +62,8 @@ Copy/pasted/hacked from pcm724.c
 #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_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it);
 static int pcm3724_detach(struct comedi_device *dev);
 
 struct pcm3724_board {
@@ -143,8 +144,8 @@ static int compute_buffer(int config, int devno, struct comedi_subdevice *s)
 	return config;
 }
 
-static void do_3724_config(struct comedi_device *dev, struct comedi_subdevice *s,
-	int chanspec)
+static void do_3724_config(struct comedi_device *dev,
+			   struct comedi_subdevice *s, int chanspec)
 {
 	int config;
 	int buffer_config;
@@ -177,14 +178,15 @@ static void do_3724_config(struct comedi_device *dev, struct comedi_subdevice *s
 	outb(config, port_8255_cfg);
 }
 
-static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, int chanspec)
+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);
+	priv = (struct priv_pcm3724 *)(dev->private);
 
 	mask = 1 << CR_CHAN(chanspec);
 	if (s == dev->subdevices) {	/*  subdev 0 */
@@ -215,8 +217,9 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, i
 }
 
 /* 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)
+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;
@@ -252,7 +255,8 @@ static int subdev_3724_insn_config(struct comedi_device *dev, struct comedi_subd
 	return 1;
 }
 
-static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pcm3724_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	unsigned long iobase;
 	unsigned int iorange;
@@ -265,11 +269,11 @@ static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	if (ret < 0)
 		return -ENOMEM;
 
-	((struct priv_pcm3724 *) (dev->private))->dio_1 = 0;
-	((struct priv_pcm3724 *) (dev->private))->dio_2 = 0;
+	((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);
+	       this_board->name, iobase);
 	if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
 		printk("I/O port conflict\n");
 		return -EIO;
@@ -287,7 +291,7 @@ static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it
 
 	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));
+				 (unsigned long)(dev->iobase + SIZE_8255 * i));
 		((dev->subdevices) + i)->insn_config = subdev_3724_insn_config;
 	};
 	return 0;
diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c
index ae90ea4..9e4adbd 100644
--- a/drivers/staging/comedi/drivers/pcm3730.c
+++ b/drivers/staging/comedi/drivers/pcm3730.c
@@ -28,7 +28,8 @@ Configuration options:
 #define PCM3730_DIB 2
 #define PCM3730_DIC 3
 
-static int pcm3730_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -39,8 +40,9 @@ static struct comedi_driver driver_pcm3730 = {
 
 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)
+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;
@@ -54,8 +56,9 @@ static int pcm3730_do_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	return 2;
 }
 
-static int pcm3730_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -63,7 +66,8 @@ static int pcm3730_di_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	return 2;
 }
 
-static int pcm3730_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pcm3730_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 	unsigned long iobase;
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index 9bb2669..acac670 100644
--- a/drivers/staging/comedi/drivers/pcmad.c
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -59,17 +59,17 @@ struct pcmad_board_struct {
 };
 static const struct pcmad_board_struct pcmad_boards[] = {
 	{
-	.name = "pcmad12",
-	.n_ai_bits = 12,
-		},
+	 .name = "pcmad12",
+	 .n_ai_bits = 12,
+	 },
 	{
-	.name = "pcmad16",
-	.n_ai_bits = 16,
-		},
+	 .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]))
+#define n_pcmad_boards ARRAY_SIZE(pcmad_boards)
 
 struct pcmad_priv_struct {
 	int differential;
@@ -93,8 +93,9 @@ 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)
+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;
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
index 6e172a6..7133eb0 100644
--- a/drivers/staging/comedi/drivers/pcmda12.c
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -76,14 +76,14 @@ struct pcmda12_board {
 static const struct comedi_lrange pcmda12_ranges = {
 	3,
 	{
-			UNI_RANGE(5), UNI_RANGE(10), BIP_RANGE(5)
-		}
+	 UNI_RANGE(5), UNI_RANGE(10), BIP_RANGE(5)
+	 }
 };
 
 static const struct pcmda12_board pcmda12_boards[] = {
 	{
-	.name = "pcmda12",
-		},
+	 .name = "pcmda12",
+	 },
 };
 
 /*
@@ -97,7 +97,6 @@ struct pcmda12_private {
 	int simultaneous_xfer_mode;
 };
 
-
 #define devpriv ((struct pcmda12_private *)(dev->private))
 
 /*
@@ -106,7 +105,8 @@ struct pcmda12_private {
  * 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_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);
@@ -140,9 +140,9 @@ static struct comedi_driver driver = {
 };
 
 static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+		    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);
+		    struct comedi_insn *insn, unsigned int *data);
 
 /*
  * Attach is called by the Comedi core to configure the driver
@@ -150,14 +150,15 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  * in the driver structure, dev->board_ptr contains that
  * address.
  */
-static int pcmda12_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+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" : "");
+	       iobase, it->options[1] ? "simultaneous xfer mode enabled" : "");
 
 	if (!request_region(iobase, IOSIZE, driver.driver_name)) {
 		printk("I/O port conflict\n");
@@ -241,7 +242,7 @@ static void zero_chans(struct comedi_device *dev)
 }
 
 static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -283,7 +284,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
    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)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
index cdf501a..d812c2c 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -139,15 +139,16 @@ Configuration Options:
 #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 *);
+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 *);
+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
@@ -168,30 +169,30 @@ struct pcmmio_board {
 };
 
 static const struct comedi_lrange ranges_ai =
-	{ 4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0.,
-		10.)}
+    { 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)}
+    { 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},
+	 .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},
 };
 
 /*
@@ -264,7 +265,8 @@ struct pcmmio_private {
  * 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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcmmio_detach(struct comedi_device *dev);
 
 static struct comedi_driver driver = {
@@ -295,17 +297,19 @@ static struct comedi_driver driver = {
 	.num_names = ARRAY_SIZE(pcmmio_boards),
 };
 
-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 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);
 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);
+			  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 */
@@ -325,7 +329,7 @@ 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;
+	    thisasic_chanct = 0;
 	unsigned long iobase;
 	unsigned int irq[MAX_ASICS];
 
@@ -333,12 +337,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	irq[0] = it->options[1];
 
 	printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
-		iobase);
+	       iobase);
 
 	dev->iobase = iobase;
 
 	if (!iobase || !request_region(iobase,
-			thisboard->total_iosize, driver.driver_name)) {
+				       thisboard->total_iosize,
+				       driver.driver_name)) {
 		printk("I/O port conflict\n");
 		return -EIO;
 	}
@@ -361,7 +366,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	for (asic = 0; asic < MAX_ASICS; ++asic) {
 		devpriv->asics[asic].num = asic;
 		devpriv->asics[asic].iobase =
-			dev->iobase + 16 + asic * ASIC_IOSIZE;
+		    dev->iobase + 16 + asic * ASIC_IOSIZE;
 		devpriv->asics[asic].irq = 0;	/* this gets actually set at the end of
 						   this function when we
 						   request_irqs */
@@ -372,7 +377,8 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+	    kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private),
+		    GFP_KERNEL);
 	if (!devpriv->sprivs) {
 		printk("cannot allocate subdevice private data structures\n");
 		return -ENOMEM;
@@ -452,11 +458,11 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 				thisasic_chanct = 0;
 			}
 			subpriv->iobases[byte_no] =
-				devpriv->asics[asic].iobase + port;
+			    devpriv->asics[asic].iobase + port;
 
 			if (thisasic_chanct <
-				CHANS_PER_PORT * INTR_PORTS_PER_ASIC
-				&& subpriv->dio.intr.asic < 0) {
+			    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;
@@ -464,13 +470,12 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 				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->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;
+				    subpriv->dio.intr.num_asic_chans;
 			}
 			thisasic_chanct += CHANS_PER_PORT;
 		}
@@ -489,8 +494,8 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
 		if (irq[asic]
-			&& request_irq(irq[asic], interrupt_pcmmio,
-				IRQF_SHARED, thisboard->name, dev)) {
+		    && request_irq(irq[asic], interrupt_pcmmio,
+				   IRQF_SHARED, thisboard->name, dev)) {
 			int i;
 			/* unroll the allocated irqs.. */
 			for (i = asic - 1; i >= 0; --i) {
@@ -550,8 +555,9 @@ static int pcmmio_detach(struct comedi_device *dev)
  * 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)
+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)
@@ -578,20 +584,23 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	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;
+		    /* 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;
+		    /* 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);
+		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) {
@@ -624,11 +633,12 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
  * 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)
+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;
+	    chan % 8;
 	unsigned long ioaddr;
 	unsigned char byte;
 
@@ -672,8 +682,7 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, struct comedi_subde
 	case INSN_CONFIG_DIO_QUERY:
 		/* retreive from shadow register */
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 
@@ -706,7 +715,7 @@ static void init_asics(struct comedi_device *dev)
 			/* now clear all the paged registers */
 			switch_page(dev, asic, page);
 			for (reg = FIRST_PAGED_REG;
-				reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+			     reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
 				outb(0, baseaddr + reg);
 		}
 
@@ -734,7 +743,7 @@ static void switch_page(struct comedi_device *dev, int asic, int page)
 
 	/* now write out the shadow register */
 	outb(devpriv->asics[asic].pagelock,
-		devpriv->asics[asic].iobase + REG_PAGELOCK);
+	     devpriv->asics[asic].iobase + REG_PAGELOCK);
 }
 
 #ifdef notused
@@ -748,7 +757,7 @@ static void lock_port(struct comedi_device *dev, int asic, int port)
 	devpriv->asics[asic].pagelock |= 0x1 << port;
 	/* now write out the shadow register */
 	outb(devpriv->asics[asic].pagelock,
-		devpriv->asics[asic].iobase + REG_PAGELOCK);
+	     devpriv->asics[asic].iobase + REG_PAGELOCK);
 	return;
 }
 
@@ -761,14 +770,14 @@ static void unlock_port(struct comedi_device *dev, int asic, int port)
 	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);
+	     devpriv->asics[asic].iobase + REG_PAGELOCK);
 }
 #endif /* notused */
 
 static irqreturn_t interrupt_pcmmio(int irq, void *d)
 {
 	int asic, got1 = 0;
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	for (asic = 0; asic < MAX_ASICS; ++asic) {
 		if (irq == devpriv->asics[asic].irq) {
@@ -778,124 +787,130 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 			/* it is an interrupt for ASIC #asic */
 			unsigned char int_pend;
 
-			spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
+			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) {
+				     ++port) {
 					if (int_pend & (0x1 << port)) {
 						unsigned char
-							io_lines_with_edges = 0;
+						    io_lines_with_edges = 0;
 						switch_page(dev, asic,
-							PAGE_INT_ID);
+							    PAGE_INT_ID);
 						io_lines_with_edges =
-							inb(iobase +
+						    inb(iobase +
 							REG_INT_ID0 + port);
 
 						if (io_lines_with_edges)
 							/* clear pending interrupt */
 							outb(0, iobase +
-								REG_INT_ID0 +
-								port);
+							     REG_INT_ID0 +
+							     port);
 
 						triggered |=
-							io_lines_with_edges <<
-							port * 8;
+						    io_lines_with_edges <<
+						    port * 8;
 					}
 				}
 
 				++got1;
 			}
 
-			spin_unlock_irqrestore(&devpriv->asics[asic].  spinlock, flags);
+			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);
+				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) {
+				     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;
 
-						spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+						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;
+							    ((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;
+								    ch, len;
 
-								len = s->async->
-									cmd.
-									chanlist_len;
+								len =
+								    s->
+								    async->cmd.chanlist_len;
 								for (n = 0;
-									n < len;
-									n++) {
+								     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])) {
+								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);
+									    (dev,
+									     s);
 								}
 
 								/* Check for end of acquisition. */
-								if (!subpriv->
-									dio.
-									intr.
-									continuous)
-								{
+								if (!subpriv->dio.intr.continuous) {
 									/* stop_src == TRIG_COUNT */
 									if (subpriv->dio.intr.stop_count > 0) {
-										subpriv->
-											dio.
-											intr.
-											stop_count--;
+										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);
+											    (dev,
+											     s);
 										}
 									}
 								}
 							}
 						}
 
-						spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+						spin_unlock_irqrestore
+						    (&subpriv->dio.intr.
+						     spinlock, flags);
 
 						if (oldevents !=
-							s->async->events) {
+						    s->async->events) {
 							comedi_event(dev, s);
 						}
 
@@ -911,7 +926,8 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static void pcmmio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pcmmio_stop_intr(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	int nports, firstport, asic, port;
 
@@ -931,7 +947,8 @@ static void pcmmio_stop_intr(struct comedi_device *dev, struct comedi_subdevice
 	}
 }
 
-static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s)
+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! */
@@ -944,7 +961,7 @@ static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice
 		struct comedi_cmd *cmd = &s->async->cmd;
 
 		asic = subpriv->dio.intr.asic;
-		if (asic  < 0)
+		if (asic < 0)
 			return 1;	/* not an interrupt
 					   subdev */
 		subpriv->dio.intr.enabled_mask = 0;
@@ -955,12 +972,13 @@ static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice
 			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]);
+					     || 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;
+			 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. */
@@ -976,16 +994,17 @@ static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice
 		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;
+			    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);
+			     devpriv->asics[asic].iobase + REG_ENAB0 + port);
 			switch_page(dev, asic, PAGE_POL);
 			outb(pol,
-				devpriv->asics[asic].iobase + REG_ENAB0 + port);
+			     devpriv->asics[asic].iobase + REG_ENAB0 + port);
 		}
 	}
 	return 0;
@@ -1008,7 +1027,7 @@ static int pcmmio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
  */
 static int
 pcmmio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+			  unsigned int trignum)
 {
 	unsigned long flags;
 	int event = 0;
@@ -1075,7 +1094,8 @@ 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)
+pcmmio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+	       struct comedi_cmd *cmd)
 {
 	return comedi_pcm_cmdtest(dev, s, cmd);
 }
@@ -1091,7 +1111,7 @@ static int adc_wait_ready(unsigned long iobase)
 
 /* 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)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	unsigned long iobase = subpriv->iobase;
@@ -1110,8 +1130,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	/* 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);
+		    CR_RANGE(insn->chanspec), aref = CR_AREF(insn->chanspec);
 		unsigned char command_byte = 0;
 		unsigned iooffset = 0;
 		short sample, adc_adjust = 0;
@@ -1155,7 +1174,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	for (n = 0; n < insn->n; n++) {
@@ -1185,17 +1204,17 @@ static int wait_dac_ready(unsigned long iobase)
 }
 
 static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+		    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);
+		    CR_RANGE(insn->chanspec);
 		if (chan < s->n_chan) {
 			unsigned char command_byte = 0, range_byte =
-				range & ((1 << 4) - 1);
+			    range & ((1 << 4) - 1);
 			if (chan >= 4)
 				chan -= 4, iooffset += 4;
 			/* set the range.. */
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 81ee7cd..c1ae20f 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -156,15 +156,15 @@ struct pcmuio_board {
 
 static const struct pcmuio_board pcmuio_boards[] = {
 	{
-	.name = "pcmuio48",
-	.num_asics = 1,
-	.num_ports = 6,
-		},
+	 .name = "pcmuio48",
+	 .num_asics = 1,
+	 .num_ports = 6,
+	 },
 	{
-	.name = "pcmuio96",
-	.num_asics = 2,
-	.num_ports = 12,
-		},
+	 .name = "pcmuio96",
+	 .num_asics = 2,
+	 .num_ports = 12,
+	 },
 };
 
 /*
@@ -223,7 +223,8 @@ struct pcmuio_private {
  * 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_attach(struct comedi_device *dev,
+			 struct comedi_devconfig *it);
 static int pcmuio_detach(struct comedi_device *dev);
 
 static struct comedi_driver driver = {
@@ -254,17 +255,19 @@ static struct comedi_driver driver = {
 	.num_names = ARRAY_SIZE(pcmuio_boards),
 };
 
-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 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);
 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);
+			  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 */
@@ -292,13 +295,13 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	irq[1] = it->options[2];
 
 	printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
-		iobase);
+	       iobase);
 
 	dev->iobase = iobase;
 
 	if (!iobase || !request_region(iobase,
-			thisboard->num_asics * ASIC_IOSIZE,
-			driver.driver_name)) {
+				       thisboard->num_asics * ASIC_IOSIZE,
+				       driver.driver_name)) {
 		printk("I/O port conflict\n");
 		return -EIO;
 	}
@@ -330,7 +333,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+	    kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private),
+		    GFP_KERNEL);
 	if (!devpriv->sprivs) {
 		printk("cannot allocate subdevice private data structures\n");
 		return -ENOMEM;
@@ -377,11 +381,11 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 				thisasic_chanct = 0;
 			}
 			subpriv->iobases[byte_no] =
-				devpriv->asics[asic].iobase + port;
+			    devpriv->asics[asic].iobase + port;
 
 			if (thisasic_chanct <
-				CHANS_PER_PORT * INTR_PORTS_PER_ASIC
-				&& subpriv->intr.asic < 0) {
+			    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;
@@ -389,7 +393,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 				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;
+				    s->n_chan - subpriv->intr.first_chan;
 				dev->read_subdev = s;
 				s->subdev_flags |= SDF_CMD_READ;
 				s->cancel = pcmuio_cancel;
@@ -414,8 +418,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
 		if (irq[asic]
-			&& request_irq(irq[asic], interrupt_pcmuio,
-				IRQF_SHARED, thisboard->name, dev)) {
+		    && request_irq(irq[asic], interrupt_pcmuio,
+				   IRQF_SHARED, thisboard->name, dev)) {
 			int i;
 			/* unroll the allocated irqs.. */
 			for (i = asic - 1; i >= 0; --i) {
@@ -475,8 +479,9 @@ static int pcmuio_detach(struct comedi_device *dev)
  * 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)
+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)
@@ -503,20 +508,23 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	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;
+		    /* 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;
+		    /* 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);
+		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) {
@@ -549,11 +557,12 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
  * 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)
+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;
+	    chan % 8;
 	unsigned long ioaddr;
 	unsigned char byte;
 
@@ -597,8 +606,7 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, struct comedi_subde
 	case INSN_CONFIG_DIO_QUERY:
 		/* retreive from shadow register */
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 
@@ -631,7 +639,7 @@ static void init_asics(struct comedi_device *dev)
 			/* now clear all the paged registers */
 			switch_page(dev, asic, page);
 			for (reg = FIRST_PAGED_REG;
-				reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+			     reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
 				outb(0, baseaddr + reg);
 		}
 
@@ -659,7 +667,7 @@ static void switch_page(struct comedi_device *dev, int asic, int page)
 
 	/* now write out the shadow register */
 	outb(devpriv->asics[asic].pagelock,
-		dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+	     dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
 }
 
 #ifdef notused
@@ -673,7 +681,7 @@ static void lock_port(struct comedi_device *dev, int asic, int port)
 	devpriv->asics[asic].pagelock |= 0x1 << port;
 	/* now write out the shadow register */
 	outb(devpriv->asics[asic].pagelock,
-		dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+	     dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
 }
 
 static void unlock_port(struct comedi_device *dev, int asic, int port)
@@ -685,14 +693,14 @@ static void unlock_port(struct comedi_device *dev, int asic, int port)
 	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);
+	     dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
 }
 #endif /* notused */
 
 static irqreturn_t interrupt_pcmuio(int irq, void *d)
 {
 	int asic, got1 = 0;
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	for (asic = 0; asic < MAX_ASICS; ++asic) {
 		if (irq == devpriv->asics[asic].irq) {
@@ -702,121 +710,130 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
 			/* it is an interrupt for ASIC #asic */
 			unsigned char int_pend;
 
-			spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags);
+			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) {
+				     ++port) {
 					if (int_pend & (0x1 << port)) {
 						unsigned char
-							io_lines_with_edges = 0;
+						    io_lines_with_edges = 0;
 						switch_page(dev, asic,
-							PAGE_INT_ID);
+							    PAGE_INT_ID);
 						io_lines_with_edges =
-							inb(iobase +
+						    inb(iobase +
 							REG_INT_ID0 + port);
 
 						if (io_lines_with_edges)
 							/* clear pending interrupt */
 							outb(0, iobase +
-								REG_INT_ID0 +
-								port);
+							     REG_INT_ID0 +
+							     port);
 
 						triggered |=
-							io_lines_with_edges <<
-							port * 8;
+						    io_lines_with_edges <<
+						    port * 8;
 					}
 				}
 
 				++got1;
 			}
 
-			spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags);
+			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);
+				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) {
+				     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;
 
-						spin_lock_irqsave (&subpriv->intr.spinlock, flags);
+						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;
+							    ((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;
+								    ch, len;
 
-								len = s->async->
-									cmd.
-									chanlist_len;
+								len =
+								    s->
+								    async->cmd.chanlist_len;
 								for (n = 0;
-									n < len;
-									n++) {
+								     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])) {
+								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);
+									    (dev,
+									     s);
 								}
 
 								/* Check for end of acquisition. */
-								if (!subpriv->
-									intr.
-									continuous)
-								{
+								if (!subpriv->intr.continuous) {
 									/* stop_src == TRIG_COUNT */
 									if (subpriv->intr.stop_count > 0) {
-										subpriv->
-											intr.
-											stop_count--;
+										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);
+											    (dev,
+											     s);
 										}
 									}
 								}
 							}
 						}
 
-						spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+						spin_unlock_irqrestore
+						    (&subpriv->intr.spinlock,
+						     flags);
 
 						if (oldevents !=
-							s->async->events) {
+						    s->async->events) {
 							comedi_event(dev, s);
 						}
 
@@ -832,7 +849,8 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d)
 	return IRQ_HANDLED;
 }
 
-static void pcmuio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s)
+static void pcmuio_stop_intr(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	int nports, firstport, asic, port;
 
@@ -852,7 +870,8 @@ static void pcmuio_stop_intr(struct comedi_device *dev, struct comedi_subdevice
 	}
 }
 
-static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s)
+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! */
@@ -876,27 +895,29 @@ static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice
 			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]);
+					     || CR_RANGE(cmd->
+							 chanlist[n]) ? 1U : 0U)
+				    << CR_CHAN(cmd->chanlist[n]);
 			}
 		}
 		bits &= ((0x1 << subpriv->intr.num_asic_chans) -
-			1) << subpriv->intr.first_chan;
+			 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;
+			    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);
+			     devpriv->asics[asic].iobase + REG_ENAB0 + port);
 			switch_page(dev, asic, PAGE_POL);
 			outb(pol,
-				devpriv->asics[asic].iobase + REG_ENAB0 + port);
+			     devpriv->asics[asic].iobase + REG_ENAB0 + port);
 		}
 	}
 	return 0;
@@ -919,7 +940,7 @@ static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
  */
 static int
 pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+			  unsigned int trignum)
 {
 	unsigned long flags;
 	int event = 0;
@@ -986,7 +1007,8 @@ 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)
+pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+	       struct comedi_cmd *cmd)
 {
 	return comedi_pcm_cmdtest(dev, s, cmd);
 }
diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h
index e4bbd5d..53bcdb7 100644
--- a/drivers/staging/comedi/drivers/plx9080.h
+++ b/drivers/staging/comedi/drivers/plx9080.h
@@ -404,8 +404,8 @@ static inline int plx9080_abort_dma(void *iobase, unsigned int channel)
 	}
 	if (i == timeout) {
 		printk
-			("plx9080: cancel() timed out waiting for dma %i done clear\n",
-			channel);
+		    ("plx9080: cancel() timed out waiting for dma %i done clear\n",
+		     channel);
 		return -ETIMEDOUT;
 	}
 	/*  disable and abort channel */
@@ -418,8 +418,8 @@ static inline int plx9080_abort_dma(void *iobase, unsigned int channel)
 	}
 	if (i == timeout) {
 		printk
-			("plx9080: cancel() timed out waiting for dma %i done set\n",
-			channel);
+		    ("plx9080: cancel() timed out waiting for dma %i done set\n",
+		     channel);
 		return -ETIMEDOUT;
 	}
 
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
index 47850bd..d23e588 100644
--- a/drivers/staging/comedi/drivers/poc.c
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -44,14 +44,16 @@ Configuration options:
 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);
+			 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 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;
@@ -60,47 +62,47 @@ struct boarddef_struct {
 	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 *);
+	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 = "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 = "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,
-		},
+	 .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 n_boards ARRAY_SIZE(boards)
 #define this_board ((const struct boarddef_struct *)dev->board_ptr)
 
 static struct comedi_driver driver_poc = {
@@ -121,7 +123,7 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	iobase = it->options[0];
 	printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
-		this_board->name, iobase);
+	       this_board->name, iobase);
 
 	dev->board_name = this_board->name;
 
@@ -133,7 +135,9 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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);
+		printk
+		    ("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
+		     iobase, iobase + iosize - 1);
 		return -EIO;
 	}
 	dev->iobase = iobase;
@@ -171,12 +175,12 @@ 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)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int chan;
 
 	chan = CR_CHAN(insn->chanspec);
-	data[0] = ((unsigned int *) dev->private)[chan];
+	data[0] = ((unsigned int *)dev->private)[chan];
 
 	return 1;
 }
@@ -186,14 +190,14 @@ static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 #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)
+			  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];
+	((unsigned int *)dev->private)[chan] = data[0];
 	output = data[0];
 #ifdef wrong
 	/*  convert to complementary binary if range is bipolar */
@@ -208,8 +212,9 @@ static int dac02_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return 1;
 }
 
-static int pcl733_insn_bits(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)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -222,8 +227,9 @@ static int pcl733_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
 	return 2;
 }
 
-static int pcl734_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)
 {
 	if (insn->n != 2)
 		return -EINVAL;
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 85b53c9..f63bdc3 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -184,11 +184,11 @@ static struct local_info_t *dev_table[MAX_DEV] = { NULL, /* ... */  };
  */
 
 static const struct comedi_lrange range_daqp_ai = { 4, {
-			BIP_RANGE(10),
-			BIP_RANGE(5),
-			BIP_RANGE(2.5),
-			BIP_RANGE(1.25)
-	}
+							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)} };
@@ -211,7 +211,7 @@ static struct comedi_driver driver_daqp = {
 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));
+	       inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
 }
 
 static void hex_dump(char *str, void *ptr, int len)
@@ -236,7 +236,7 @@ static void hex_dump(char *str, void *ptr, int len)
 
 static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-	struct local_info_t *local = (struct local_info_t *) s->private;
+	struct local_info_t *local = (struct local_info_t *)s->private;
 
 	if (local->stop) {
 		return -EIO;
@@ -264,7 +264,7 @@ static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 
 static void daqp_interrupt(int irq, void *dev_id)
 {
-	struct local_info_t *local = (struct local_info_t *) dev_id;
+	struct local_info_t *local = (struct local_info_t *)dev_id;
 	struct comedi_device *dev;
 	struct comedi_subdevice *s;
 	int loop_limit = 10000;
@@ -272,7 +272,7 @@ static void daqp_interrupt(int irq, void *dev_id)
 
 	if (local == NULL) {
 		printk(KERN_WARNING
-			"daqp_interrupt(): irq %d for unknown device.\n", irq);
+		       "daqp_interrupt(): irq %d for unknown device.\n", irq);
 		return;
 	}
 
@@ -284,20 +284,20 @@ static void daqp_interrupt(int irq, void *dev_id)
 
 	if (!dev->attached) {
 		printk(KERN_WARNING
-			"daqp_interrupt(): struct comedi_device not yet attached.\n");
+		       "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");
+		       "daqp_interrupt(): NULL comedi_subdevice.\n");
 		return;
 	}
 
-	if ((struct local_info_t *) s->private != local) {
+	if ((struct local_info_t *)s->private != local) {
 		printk(KERN_WARNING
-			"daqp_interrupt(): invalid comedi_subdevice.\n");
+		       "daqp_interrupt(): invalid comedi_subdevice.\n");
 		return;
 	}
 
@@ -311,13 +311,13 @@ static void daqp_interrupt(int irq, void *dev_id)
 	case buffer:
 
 		while (!((status = inb(dev->iobase + DAQP_STATUS))
-				& DAQP_STATUS_FIFO_EMPTY)) {
+			 & DAQP_STATUS_FIFO_EMPTY)) {
 
 			short data;
 
 			if (status & DAQP_STATUS_DATA_LOST) {
 				s->async->events |=
-					COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
+				    COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
 				printk("daqp: data lost\n");
 				daqp_ai_cancel(dev, s);
 				break;
@@ -348,7 +348,7 @@ static void daqp_interrupt(int irq, void *dev_id)
 
 		if (loop_limit <= 0) {
 			printk(KERN_WARNING
-				"loop_limit reached in daqp_interrupt()\n");
+			       "loop_limit reached in daqp_interrupt()\n");
 			daqp_ai_cancel(dev, s);
 			s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 		}
@@ -361,10 +361,11 @@ static void daqp_interrupt(int irq, void *dev_id)
 
 /* 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)
+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;
+	struct local_info_t *local = (struct local_info_t *)s->private;
 	int i;
 	int v;
 	int counter = 10000;
@@ -384,7 +385,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	/* Program one scan list entry */
 
 	v = DAQP_SCANLIST_CHANNEL(CR_CHAN(insn->chanspec))
-		| DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec));
+	    | DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec));
 
 	if (CR_AREF(insn->chanspec) == AREF_DIFF) {
 		v |= DAQP_SCANLIST_DIFFERENTIAL;
@@ -402,7 +403,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	/* Set trigger */
 
 	v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL
-		| DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
+	    | DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
 
 	outb(v, dev->iobase + DAQP_CONTROL);
 
@@ -411,7 +412,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	 */
 
 	while (--counter
-		&& (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+	       && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
 	if (!counter) {
 		printk("daqp: couldn't clear interrupts in status register\n");
 		return -1;
@@ -427,7 +428,7 @@ static int daqp_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 
 		/* Start conversion */
 		outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
-			dev->iobase + DAQP_COMMAND);
+		     dev->iobase + DAQP_COMMAND);
 
 		/* Wait for interrupt service routine to unblock semaphore */
 		/* Maybe could use a timeout here, but it's interruptible */
@@ -467,8 +468,8 @@ static int daqp_ns_to_timer(unsigned int *ns, int round)
  * the command passes.
  */
 
-static int daqp_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int daqp_ai_cmdtest(struct comedi_device *dev,
+			   struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -507,7 +508,7 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 
 	/* note that mutual compatiblity is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
-		cmd->scan_begin_src != TRIG_FOLLOW)
+	    cmd->scan_begin_src != TRIG_FOLLOW)
 		err++;
 	if (cmd->convert_src != TRIG_NOW && cmd->convert_src != TRIG_TIMER)
 		err++;
@@ -528,7 +529,7 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 #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) {
 		cmd->scan_begin_arg = MAX_SPEED;
 		err++;
 	}
@@ -539,8 +540,7 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	 */
 
 	if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_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++;
 	}
 
@@ -574,7 +574,7 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	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);
+				 cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
@@ -582,7 +582,7 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	if (cmd->convert_src == TRIG_TIMER) {
 		tmp = cmd->convert_arg;
 		daqp_ns_to_timer(&cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+				 cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->convert_arg)
 			err++;
 	}
@@ -595,7 +595,7 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 
 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 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;
@@ -631,14 +631,14 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (cmd->convert_src == TRIG_TIMER) {
 		int counter = daqp_ns_to_timer(&cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+					       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);
+					       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);
@@ -654,7 +654,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		/* Program one scan list entry */
 
 		v = DAQP_SCANLIST_CHANNEL(CR_CHAN(chanspec))
-			| DAQP_SCANLIST_GAIN(CR_RANGE(chanspec));
+		    | DAQP_SCANLIST_GAIN(CR_RANGE(chanspec));
 
 		if (CR_AREF(chanspec) == AREF_DIFF) {
 			v |= DAQP_SCANLIST_DIFFERENTIAL;
@@ -765,7 +765,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	/* Set trigger */
 
 	v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL
-		| DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
+	    | DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
 
 	outb(v, dev->iobase + DAQP_CONTROL);
 
@@ -774,7 +774,7 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	 */
 
 	while (--counter
-		&& (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+	       && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
 	if (!counter) {
 		printk("daqp: couldn't clear interrupts in status register\n");
 		return -1;
@@ -786,17 +786,18 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	/* Start conversion */
 	outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
-		dev->iobase + DAQP_COMMAND);
+	     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)
+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;
+	struct local_info_t *local = (struct local_info_t *)s->private;
 	int d;
 	unsigned int chan;
 
@@ -820,10 +821,11 @@ static int daqp_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice
 
 /* Digital input routine */
 
-static int daqp_di_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
+	struct local_info_t *local = (struct local_info_t *)s->private;
 
 	if (local->stop) {
 		return -EIO;
@@ -836,10 +838,11 @@ static int daqp_di_insn_read(struct comedi_device *dev, struct comedi_subdevice
 
 /* Digital output routine */
 
-static int daqp_do_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
+	struct local_info_t *local = (struct local_info_t *)s->private;
 
 	if (local->stop) {
 		return -EIO;
@@ -866,7 +869,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	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]);
+		       dev->minor, it->options[0]);
 		return -EIO;
 	}
 
@@ -899,7 +902,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 					break;
 			i++;
 			if ((i < tuple.TupleDataLen - 4)
-				&& (strncmp(buf + i, "DAQP", 4) == 0)) {
+			    && (strncmp(buf + i, "DAQP", 4) == 0)) {
 				strncpy(local->board_name, buf + i,
 					sizeof(local->board_name));
 			}
@@ -913,7 +916,7 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		return ret;
 
 	printk("comedi%d: attaching daqp%d (io 0x%04lx)\n",
-		dev->minor, it->options[0], dev->iobase);
+	       dev->minor, it->options[0], dev->iobase);
 
 	s = dev->subdevices + 0;
 	dev->read_subdev = s;
@@ -1234,7 +1237,7 @@ static void daqp_cs_config(struct pcmcia_device *link)
 		/* If we got this far, we're cool! */
 		break;
 
-	      next_entry:
+next_entry:
 		last_ret = pcmcia_get_next_tuple(link, &tuple);
 		if (last_ret) {
 			cs_error(link, GetNextTuple, last_ret);
@@ -1280,20 +1283,20 @@ static void daqp_cs_config(struct pcmcia_device *link)
 
 	/* Finally, report what we've done */
 	printk(KERN_INFO "%s: index 0x%02x",
-		dev->node.dev_name, link->conf.ConfigIndex);
+	       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);
+		       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);
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
 	printk("\n");
 
 	return;
 
-      cs_failed:
+cs_failed:
 	daqp_cs_release(link);
 
 }				/* daqp_cs_config */
@@ -1354,7 +1357,7 @@ struct pcmcia_driver daqp_cs_driver = {
 	.id_table = daqp_cs_id_table,
 	.owner = THIS_MODULE,
 	.drv = {
-			.name = dev_info,
+		.name = dev_info,
 		},
 };
 
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 243ee76..f35cce5 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -198,70 +198,100 @@ Configuration options:
   The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
 */
 static const struct comedi_lrange rtd_ai_7520_range = { 18, {
-			/* +-5V input range gain steps */
-			BIP_RANGE(5.0),
-			BIP_RANGE(5.0 / 2),
-			BIP_RANGE(5.0 / 4),
-			BIP_RANGE(5.0 / 8),
-			BIP_RANGE(5.0 / 16),
-			BIP_RANGE(5.0 / 32),
-			/* +-10V input range gain steps */
-			BIP_RANGE(10.0),
-			BIP_RANGE(10.0 / 2),
-			BIP_RANGE(10.0 / 4),
-			BIP_RANGE(10.0 / 8),
-			BIP_RANGE(10.0 / 16),
-			BIP_RANGE(10.0 / 32),
-			/* +10V input range gain steps */
-			UNI_RANGE(10.0),
-			UNI_RANGE(10.0 / 2),
-			UNI_RANGE(10.0 / 4),
-			UNI_RANGE(10.0 / 8),
-			UNI_RANGE(10.0 / 16),
-			UNI_RANGE(10.0 / 32),
-
-	}
+							     /* +-5V input range gain steps */
+							     BIP_RANGE(5.0),
+							     BIP_RANGE(5.0 / 2),
+							     BIP_RANGE(5.0 / 4),
+							     BIP_RANGE(5.0 / 8),
+							     BIP_RANGE(5.0 /
+								       16),
+							     BIP_RANGE(5.0 /
+								       32),
+							     /* +-10V input range gain steps */
+							     BIP_RANGE(10.0),
+							     BIP_RANGE(10.0 /
+								       2),
+							     BIP_RANGE(10.0 /
+								       4),
+							     BIP_RANGE(10.0 /
+								       8),
+							     BIP_RANGE(10.0 /
+								       16),
+							     BIP_RANGE(10.0 /
+								       32),
+							     /* +10V input range gain steps */
+							     UNI_RANGE(10.0),
+							     UNI_RANGE(10.0 /
+								       2),
+							     UNI_RANGE(10.0 /
+								       4),
+							     UNI_RANGE(10.0 /
+								       8),
+							     UNI_RANGE(10.0 /
+								       16),
+							     UNI_RANGE(10.0 /
+								       32),
+
+							     }
 };
 
 /* PCI4520 has two more gains (6 more entries) */
 static const struct comedi_lrange rtd_ai_4520_range = { 24, {
-			/* +-5V input range gain steps */
-			BIP_RANGE(5.0),
-			BIP_RANGE(5.0 / 2),
-			BIP_RANGE(5.0 / 4),
-			BIP_RANGE(5.0 / 8),
-			BIP_RANGE(5.0 / 16),
-			BIP_RANGE(5.0 / 32),
-			BIP_RANGE(5.0 / 64),
-			BIP_RANGE(5.0 / 128),
-			/* +-10V input range gain steps */
-			BIP_RANGE(10.0),
-			BIP_RANGE(10.0 / 2),
-			BIP_RANGE(10.0 / 4),
-			BIP_RANGE(10.0 / 8),
-			BIP_RANGE(10.0 / 16),
-			BIP_RANGE(10.0 / 32),
-			BIP_RANGE(10.0 / 64),
-			BIP_RANGE(10.0 / 128),
-			/* +10V input range gain steps */
-			UNI_RANGE(10.0),
-			UNI_RANGE(10.0 / 2),
-			UNI_RANGE(10.0 / 4),
-			UNI_RANGE(10.0 / 8),
-			UNI_RANGE(10.0 / 16),
-			UNI_RANGE(10.0 / 32),
-			UNI_RANGE(10.0 / 64),
-			UNI_RANGE(10.0 / 128),
-	}
+							     /* +-5V input range gain steps */
+							     BIP_RANGE(5.0),
+							     BIP_RANGE(5.0 / 2),
+							     BIP_RANGE(5.0 / 4),
+							     BIP_RANGE(5.0 / 8),
+							     BIP_RANGE(5.0 /
+								       16),
+							     BIP_RANGE(5.0 /
+								       32),
+							     BIP_RANGE(5.0 /
+								       64),
+							     BIP_RANGE(5.0 /
+								       128),
+							     /* +-10V input range gain steps */
+							     BIP_RANGE(10.0),
+							     BIP_RANGE(10.0 /
+								       2),
+							     BIP_RANGE(10.0 /
+								       4),
+							     BIP_RANGE(10.0 /
+								       8),
+							     BIP_RANGE(10.0 /
+								       16),
+							     BIP_RANGE(10.0 /
+								       32),
+							     BIP_RANGE(10.0 /
+								       64),
+							     BIP_RANGE(10.0 /
+								       128),
+							     /* +10V input range gain steps */
+							     UNI_RANGE(10.0),
+							     UNI_RANGE(10.0 /
+								       2),
+							     UNI_RANGE(10.0 /
+								       4),
+							     UNI_RANGE(10.0 /
+								       8),
+							     UNI_RANGE(10.0 /
+								       16),
+							     UNI_RANGE(10.0 /
+								       32),
+							     UNI_RANGE(10.0 /
+								       64),
+							     UNI_RANGE(10.0 /
+								       128),
+							     }
 };
 
 /* Table order matches range values */
 static const struct comedi_lrange rtd_ao_range = { 4, {
-			RANGE(0, 5),
-			RANGE(0, 10),
-			RANGE(-5, 5),
-			RANGE(-10, 10),
-	}
+						       RANGE(0, 5),
+						       RANGE(0, 10),
+						       RANGE(-5, 5),
+						       RANGE(-10, 10),
+						       }
 };
 
 /*
@@ -279,29 +309,30 @@ struct rtdBoard {
 
 static const struct rtdBoard rtd520Boards[] = {
 	{
-	.name = "DM7520",
-	.device_id = 0x7520,
-	.aiChans = 16,
-	.aiBits = 12,
-	.aiMaxGain = 32,
-	.range10Start = 6,
-	.rangeUniStart = 12,
-		},
+	 .name = "DM7520",
+	 .device_id = 0x7520,
+	 .aiChans = 16,
+	 .aiBits = 12,
+	 .aiMaxGain = 32,
+	 .range10Start = 6,
+	 .rangeUniStart = 12,
+	 },
 	{
-	.name = "PCI4520",
-	.device_id = 0x4520,
-	.aiChans = 16,
-	.aiBits = 12,
-	.aiMaxGain = 128,
-	.range10Start = 8,
-	.rangeUniStart = 16,
-		},
+	 .name = "PCI4520",
+	 .device_id = 0x4520,
+	 .aiChans = 16,
+	 .aiBits = 12,
+	 .aiMaxGain = 128,
+	 .range10Start = 8,
+	 .rangeUniStart = 16,
+	 },
 };
 
 static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
-	{PCI_VENDOR_ID_RTD, 0x7520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_RTD, 0x4520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0}
+	{
+	PCI_VENDOR_ID_RTD, 0x7520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	PCI_VENDOR_ID_RTD, 0x4520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
+	0}
 };
 
 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
@@ -692,17 +723,19 @@ static struct comedi_driver rtd520Driver = {
 };
 
 static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+			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);
+			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);
+			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);
+			  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); */
@@ -747,31 +780,29 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	 * Probe the device to determine what device in the series it is.
 	 */
 	for (pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, NULL);
-		pcidev != NULL;
-		pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, pcidev)) {
+	     pcidev != NULL;
+	     pcidev = pci_get_device(PCI_VENDOR_ID_RTD, PCI_ANY_ID, pcidev)) {
 		int i;
 
 		if (it->options[0] || it->options[1]) {
 			if (pcidev->bus->number != it->options[0]
-				|| PCI_SLOT(pcidev->devfn) !=
-				it->options[1]) {
+			    || PCI_SLOT(pcidev->devfn) != it->options[1]) {
 				continue;
 			}
 		}
-		for (i = 0; i < ARRAY_SIZE(rtd520Boards); ++i)
-		{
-			if (pcidev->device == rtd520Boards[i].device_id)
-			{
+		for (i = 0; i < ARRAY_SIZE(rtd520Boards); ++i) {
+			if (pcidev->device == rtd520Boards[i].device_id) {
 				dev->board_ptr = &rtd520Boards[i];
 				break;
 			}
 		}
-		if (dev->board_ptr) break;	/* found one */
+		if (dev->board_ptr)
+			break;	/* found one */
 	}
 	if (!pcidev) {
 		if (it->options[0] && it->options[1]) {
 			printk("No RTD card at bus=%d slot=%d.\n",
-				it->options[0], it->options[1]);
+			       it->options[0], it->options[1]);
 		} else {
 			printk("No RTD card found.\n");
 		}
@@ -813,16 +844,16 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		/*uint32_t epld_version; */
 
 		pci_read_config_word(devpriv->pci_dev, PCI_REVISION_ID,
-			&revision);
+				     &revision);
 		DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision);
 
 		pci_read_config_byte(devpriv->pci_dev,
-			PCI_LATENCY_TIMER, &pci_latency);
+				     PCI_LATENCY_TIMER, &pci_latency);
 		if (pci_latency < 32) {
 			printk("%s: PCI latency changed from %d to %d\n",
-				dev->board_name, pci_latency, 32);
+			       dev->board_name, pci_latency, 32);
 			pci_write_config_byte(devpriv->pci_dev,
-				PCI_LATENCY_TIMER, 32);
+					      PCI_LATENCY_TIMER, 32);
 		} else {
 			DPRINTK("rtd520: PCI latency = %d\n", pci_latency);
 		}
@@ -854,8 +885,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* analog input subdevice */
 	s->type = COMEDI_SUBD_AI;
 	s->subdev_flags =
-		SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF |
-		SDF_CMD_READ;
+	    SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ;
 	s->n_chan = thisboard->aiChans;
 	s->maxdata = (1 << thisboard->aiBits) - 1;
 	if (thisboard->aiMaxGain <= 32) {
@@ -868,7 +898,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	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 */
@@ -901,7 +931,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	/* initialize board, per RTD spec */
 	/* also, initialize shadow registers */
 	RtdResetBoard(dev);
-	udelay(100);	/* needed? */
+	udelay(100);		/* needed? */
 	RtdPlxInterruptWrite(dev, 0);
 	RtdInterruptMask(dev, 0);	/* and sets shadow */
 	RtdInterruptClearMask(dev, ~0);	/* and sets shadow */
@@ -921,11 +951,11 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	/* check if our interrupt is available and get it */
 	ret = request_irq(devpriv->pci_dev->irq, rtd_interrupt,
-				 IRQF_SHARED, DRV_NAME, dev);
+			  IRQF_SHARED, DRV_NAME, dev);
 
 	if (ret < 0) {
 		printk("Could not get interrupt! (%u)\n",
-			devpriv->pci_dev->irq);
+		       devpriv->pci_dev->irq);
 		return ret;
 	}
 	dev->irq = devpriv->pci_dev->irq;
@@ -948,9 +978,11 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 		for (index = 0; index < DMA_CHAIN_COUNT; index++) {
 			devpriv->dma0Buff[index] =
-				pci_alloc_consistent(devpriv->pci_dev,
-				sizeof(u16) * devpriv->fifoLen / 2,
-				&devpriv->dma0BuffPhysAddr[index]);
+			    pci_alloc_consistent(devpriv->pci_dev,
+						 sizeof(u16) *
+						 devpriv->fifoLen / 2,
+						 &devpriv->
+						 dma0BuffPhysAddr[index]);
 			if (devpriv->dma0Buff[index] == NULL) {
 				ret = -ENOMEM;
 				goto rtd_attach_die_error;
@@ -962,21 +994,23 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 		/* setup DMA descriptor ring (use cpu_to_le32 for byte ordering?) */
 		devpriv->dma0Chain =
-			pci_alloc_consistent(devpriv->pci_dev,
-			sizeof(struct plx_dma_desc) * DMA_CHAIN_COUNT,
-			&devpriv->dma0ChainPhysAddr);
+		    pci_alloc_consistent(devpriv->pci_dev,
+					 sizeof(struct plx_dma_desc) *
+					 DMA_CHAIN_COUNT,
+					 &devpriv->dma0ChainPhysAddr);
 		for (index = 0; index < DMA_CHAIN_COUNT; index++) {
 			devpriv->dma0Chain[index].pci_start_addr =
-				devpriv->dma0BuffPhysAddr[index];
+			    devpriv->dma0BuffPhysAddr[index];
 			devpriv->dma0Chain[index].local_start_addr =
-				DMALADDR_ADC;
+			    DMALADDR_ADC;
 			devpriv->dma0Chain[index].transfer_size =
-				sizeof(u16) * devpriv->fifoLen / 2;
+			    sizeof(u16) * devpriv->fifoLen / 2;
 			devpriv->dma0Chain[index].next =
-				(devpriv->dma0ChainPhysAddr + ((index +
-						1) % (DMA_CHAIN_COUNT))
-				* sizeof(devpriv->dma0Chain[0]))
-				| DMA_TRANSFER_BITS;
+			    (devpriv->dma0ChainPhysAddr + ((index +
+							    1) %
+							   (DMA_CHAIN_COUNT))
+			     * sizeof(devpriv->dma0Chain[0]))
+			    | DMA_TRANSFER_BITS;
 			/*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n",
 			   index,
 			   ((long)devpriv->dma0ChainPhysAddr
@@ -1014,17 +1048,18 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	for (index = 0; index < DMA_CHAIN_COUNT; index++) {
 		if (NULL != devpriv->dma0Buff[index]) {	/* free buffer memory */
 			pci_free_consistent(devpriv->pci_dev,
-				sizeof(u16) * devpriv->fifoLen / 2,
-				devpriv->dma0Buff[index],
-				devpriv->dma0BuffPhysAddr[index]);
+					    sizeof(u16) * devpriv->fifoLen / 2,
+					    devpriv->dma0Buff[index],
+					    devpriv->dma0BuffPhysAddr[index]);
 			devpriv->dma0Buff[index] = NULL;
 		}
 	}
 	if (NULL != devpriv->dma0Chain) {
 		pci_free_consistent(devpriv->pci_dev,
-			sizeof(struct plx_dma_desc)
-			* DMA_CHAIN_COUNT,
-			devpriv->dma0Chain, devpriv->dma0ChainPhysAddr);
+				    sizeof(struct plx_dma_desc)
+				    * DMA_CHAIN_COUNT,
+				    devpriv->dma0Chain,
+				    devpriv->dma0ChainPhysAddr);
 		devpriv->dma0Chain = NULL;
 	}
 #endif /* USE_DMA */
@@ -1032,7 +1067,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	if (dev->irq) {
 		/* disable interrupt controller */
 		RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
-			& ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E));
+				     & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E));
 		free_irq(dev->irq, dev);
 	}
 
@@ -1070,7 +1105,11 @@ static int rtd_detach(struct comedi_device *dev)
 	DPRINTK("comedi%d: rtd520: removing (%ld ints)\n",
 		dev->minor, (devpriv ? devpriv->intCount : 0L));
 	if (devpriv && devpriv->lcfg) {
-		DPRINTK("(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n", 0xffff & RtdInterruptStatus(dev), 0xffff & RtdInterruptOverrunStatus(dev), (0xffff & RtdFifoStatus(dev)) ^ 0x6666);
+		DPRINTK
+		    ("(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n",
+		     0xffff & RtdInterruptStatus(dev),
+		     0xffff & RtdInterruptOverrunStatus(dev),
+		     (0xffff & RtdFifoStatus(dev)) ^ 0x6666);
 	}
 
 	if (devpriv) {
@@ -1093,16 +1132,19 @@ static int rtd_detach(struct comedi_device *dev)
 		for (index = 0; index < DMA_CHAIN_COUNT; index++) {
 			if (NULL != devpriv->dma0Buff[index]) {
 				pci_free_consistent(devpriv->pci_dev,
-					sizeof(u16) * devpriv->fifoLen / 2,
-					devpriv->dma0Buff[index],
-					devpriv->dma0BuffPhysAddr[index]);
+						    sizeof(u16) *
+						    devpriv->fifoLen / 2,
+						    devpriv->dma0Buff[index],
+						    devpriv->
+						    dma0BuffPhysAddr[index]);
 				devpriv->dma0Buff[index] = NULL;
 			}
 		}
 		if (NULL != devpriv->dma0Chain) {
 			pci_free_consistent(devpriv->pci_dev,
-				sizeof(struct plx_dma_desc) * DMA_CHAIN_COUNT,
-				devpriv->dma0Chain, devpriv->dma0ChainPhysAddr);
+					    sizeof(struct plx_dma_desc) *
+					    DMA_CHAIN_COUNT, devpriv->dma0Chain,
+					    devpriv->dma0ChainPhysAddr);
 			devpriv->dma0Chain = NULL;
 		}
 #endif /* USE_DMA */
@@ -1111,7 +1153,8 @@ static int rtd_detach(struct comedi_device *dev)
 		if (dev->irq) {
 			/* disable interrupt controller */
 			RtdPlxInterruptWrite(dev, RtdPlxInterruptRead(dev)
-				& ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E));
+					     & ~(ICS_PLIE | ICS_DMA0_E |
+						 ICS_DMA1_E));
 			free_irq(dev->irq, dev);
 		}
 
@@ -1142,7 +1185,7 @@ static int rtd_detach(struct comedi_device *dev)
   Convert a single comedi channel-gain entry to a RTD520 table entry
 */
 static unsigned short rtdConvertChanGain(struct comedi_device *dev,
-	unsigned int comediChan, int chanIndex)
+					 unsigned int comediChan, int chanIndex)
 {				/* index in channel list */
 	unsigned int chan, range, aref;
 	unsigned short r = 0;
@@ -1192,7 +1235,7 @@ static unsigned short rtdConvertChanGain(struct comedi_device *dev,
   Setup the channel-gain table from a comedi list
 */
 static void rtd_load_channelgain_list(struct comedi_device *dev,
-	unsigned int n_chan, unsigned int *list)
+				      unsigned int n_chan, unsigned int *list)
 {
 	if (n_chan > 1) {	/* setup channel gain table */
 		int ii;
@@ -1200,7 +1243,7 @@ static void rtd_load_channelgain_list(struct comedi_device *dev,
 		RtdEnableCGT(dev, 1);	/* enable table */
 		for (ii = 0; ii < n_chan; ii++) {
 			RtdWriteCGTable(dev, rtdConvertChanGain(dev, list[ii],
-					ii));
+								ii));
 		}
 	} else {		/* just use the channel gain latch */
 		RtdEnableCGT(dev, 0);	/* disable table, enable latch */
@@ -1232,16 +1275,15 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev)
 			break;
 		}
 	}
-	if (i == limit)
-	{
+	if (i == limit) {
 		printk("\ncomedi: %s: failed to probe fifo size.\n", DRV_NAME);
 		return -EIO;
 	}
 	RtdAdcClearFifo(dev);
-	if (fifo_size != 0x400 && fifo_size != 0x2000)
-	{
-		printk("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
-			DRV_NAME, fifo_size);
+	if (fifo_size != 0x400 && fifo_size != 0x2000) {
+		printk
+		    ("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
+		     DRV_NAME, fifo_size);
 		return -EIO;
 	}
 	return fifo_size;
@@ -1256,7 +1298,8 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev)
   select, delay, then read.
  */
 static int rtd_ai_rinsn(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			struct comedi_subdevice *s, struct comedi_insn *insn,
+			unsigned int *data)
 {
 	int n, ii;
 	int stat;
@@ -1283,7 +1326,9 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
 			WAIT_QUIETLY;
 		}
 		if (ii >= RTD_ADC_TIMEOUT) {
-			DPRINTK("rtd520: Error: ADC never finished! FifoStatus=0x%x\n", stat ^ 0x6666);
+			DPRINTK
+			    ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n",
+			     stat ^ 0x6666);
 			return -ETIMEDOUT;
 		}
 
@@ -1308,7 +1353,8 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
 
   The manual claims that we can do a lword read, but it doesn't work here.
 */
-static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int count)
+static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
+		     int count)
 {
 	int ii;
 
@@ -1384,7 +1430,7 @@ void abort_dma(struct comedi_device *dev, unsigned int channel)
 	/* unsigned long flags; */
 
 	dma_cs_addr = (unsigned long)devpriv->lcfg
-		+ ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
+	    + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
 
 	/*  spinlock for plx dma control/status reg */
 	/* spin_lock_irqsave( &dev->spinlock, flags ); */
@@ -1404,30 +1450,29 @@ void abort_dma(struct comedi_device *dev, unsigned int channel)
 	}
 	if (status & PLX_DMA_DONE_BIT) {
 		printk("rtd520: Timeout waiting for dma %i done clear\n",
-			channel);
+		       channel);
 		goto abortDmaExit;
 	}
 
 	/* disable channel (required) */
 	writeb(0, dma_cs_addr);
-	udelay(1);	/* needed?? */
+	udelay(1);		/* needed?? */
 	/* set abort bit for channel */
 	writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
 
 	/*  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;
-		ii++) {
+	     (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) {
 		status = readb(dma_cs_addr);
 		WAIT_QUIETLY;
 	}
 	if ((status & PLX_DMA_DONE_BIT) == 0) {
 		printk("rtd520: Timeout waiting for dma %i done set\n",
-			channel);
+		       channel);
 	}
 
-      abortDmaExit:
+abortDmaExit:
 	/* spin_unlock_irqrestore( &dev->spinlock, flags ); */
 }
 
@@ -1495,8 +1540,8 @@ static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
   The data conversion may someday happen in a "bottom half".
 */
 static irqreturn_t rtd_interrupt(int irq,	/* interrupt number (ignored) */
-	void *d)		/* our data */
-{				/* cpu context (ignored) */
+				 void *d)
+{				/* our data *//* cpu context (ignored) */
 	struct comedi_device *dev = d;	/* must be called "dev" for devpriv */
 	u16 status;
 	u16 fifoStatus;
@@ -1520,20 +1565,22 @@ static irqreturn_t rtd_interrupt(int irq,	/* interrupt number (ignored) */
 
 		if (istatus & ICS_DMA0_A) {
 			if (ai_process_dma(dev, s) < 0) {
-				DPRINTK("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n", devpriv->aiCount);
+				DPRINTK
+				    ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n",
+				     devpriv->aiCount);
 				RtdDma0Control(dev,
-					(devpriv->
-						dma0Control &
+					       (devpriv->dma0Control &
 						~PLX_DMA_START_BIT)
-					| PLX_CLEAR_DMA_INTR_BIT);
+					       | PLX_CLEAR_DMA_INTR_BIT);
 				goto abortTransfer;
 			}
 
 			/*DPRINTK ("rtd520: DMA transfer: %ld to go, istatus %x\n",
 			   devpriv->aiCount, istatus); */
 			RtdDma0Control(dev,
-				(devpriv->dma0Control & ~PLX_DMA_START_BIT)
-				| PLX_CLEAR_DMA_INTR_BIT);
+				       (devpriv->
+					dma0Control & ~PLX_DMA_START_BIT)
+				       | PLX_CLEAR_DMA_INTR_BIT);
 			if (0 == devpriv->aiCount) {	/* counted down */
 				DPRINTK("rtd520: Samples Done (DMA).\n");
 				goto transferDone;
@@ -1560,7 +1607,9 @@ static irqreturn_t rtd_interrupt(int irq,	/* interrupt number (ignored) */
 			/*DPRINTK("rtd520: Sample int, reading 1/2FIFO.  fifo_status 0x%x\n",
 			   (fifoStatus ^ 0x6666) & 0x7777); */
 			if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) {
-				DPRINTK("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n", devpriv->aiCount);
+				DPRINTK
+				    ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n",
+				     devpriv->aiCount);
 				goto abortTransfer;
 			}
 			if (0 == devpriv->aiCount) {	/* counted down */
@@ -1573,24 +1622,32 @@ static irqreturn_t rtd_interrupt(int irq,	/* interrupt number (ignored) */
 			   devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777); */
 			if (fifoStatus & FS_ADC_NOT_EMPTY) {	/* 1 -> not empty */
 				if (ai_read_n(dev, s, devpriv->transCount) < 0) {
-					DPRINTK("rtd520: comedi read buffer overflow (N) with %ld to go!\n", devpriv->aiCount);
+					DPRINTK
+					    ("rtd520: comedi read buffer overflow (N) with %ld to go!\n",
+					     devpriv->aiCount);
 					goto abortTransfer;
 				}
 				if (0 == devpriv->aiCount) {	/* counted down */
-					DPRINTK("rtd520: Samples Done (N). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777);
+					DPRINTK
+					    ("rtd520: Samples Done (N). fifo_status was 0x%x\n",
+					     (fifoStatus ^ 0x6666) & 0x7777);
 					goto transferDone;
 				}
 				comedi_event(dev, s);
 			}
 		} else {	/* wait for 1/2 FIFO (old) */
-			DPRINTK("rtd520: Sample int.  Wait for 1/2. fifo_status 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777);
+			DPRINTK
+			    ("rtd520: Sample int.  Wait for 1/2. fifo_status 0x%x\n",
+			     (fifoStatus ^ 0x6666) & 0x7777);
 		}
 	} else {
 		DPRINTK("rtd520: unknown interrupt source!\n");
 	}
 
 	if (0xffff & RtdInterruptOverrunStatus(dev)) {	/* interrupt overrun */
-		DPRINTK("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n", devpriv->aiCount, 0xffff & RtdInterruptOverrunStatus(dev));
+		DPRINTK
+		    ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n",
+		     devpriv->aiCount, 0xffff & RtdInterruptOverrunStatus(dev));
 		goto abortTransfer;
 	}
 
@@ -1599,13 +1656,13 @@ static irqreturn_t rtd_interrupt(int irq,	/* interrupt number (ignored) */
 	RtdInterruptClear(dev);
 	return IRQ_HANDLED;
 
-      abortTransfer:
+abortTransfer:
 	RtdAdcClearFifo(dev);	/* clears full flag */
 	s->async->events |= COMEDI_CB_ERROR;
 	devpriv->aiCount = 0;	/* stop and don't transfer any more */
 	/* fall into transferDone */
 
-      transferDone:
+transferDone:
 	RtdPacerStopSource(dev, 0);	/* stop on SOFTWARE stop */
 	RtdPacerStop(dev);	/* Stop PACER */
 	RtdAdcConversionSource(dev, 0);	/* software trigger only */
@@ -1613,7 +1670,7 @@ static irqreturn_t rtd_interrupt(int irq,	/* interrupt number (ignored) */
 #ifdef USE_DMA
 	if (devpriv->flags & DMA0_ACTIVE) {
 		RtdPlxInterruptWrite(dev,	/* disable any more interrupts */
-			RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
+				     RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
 		abort_dma(dev, 0);
 		devpriv->flags &= ~DMA0_ACTIVE;
 		/* if Using DMA, then we should have read everything by now */
@@ -1639,7 +1696,10 @@ static irqreturn_t rtd_interrupt(int irq,	/* interrupt number (ignored) */
 	RtdInterruptClear(dev);
 
 	fifoStatus = RtdFifoStatus(dev);	/* DEBUG */
-	DPRINTK("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n", devpriv->intCount, status, 0xffff & RtdInterruptOverrunStatus(dev));
+	DPRINTK
+	    ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n",
+	     devpriv->intCount, status,
+	     0xffff & RtdInterruptOverrunStatus(dev));
 
 	return IRQ_HANDLED;
 }
@@ -1666,7 +1726,7 @@ static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 */
 
 static int rtd_ai_cmdtest(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd)
+			  struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -1710,7 +1770,7 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
 	   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) {
+	    cmd->scan_begin_src != TRIG_EXT) {
 		err++;
 	}
 	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) {
@@ -1737,26 +1797,26 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
 			if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) {
 				cmd->scan_begin_arg = RTD_MAX_SPEED_1;
 				rtd_ns_to_timer(&cmd->scan_begin_arg,
-					TRIG_ROUND_UP);
+						TRIG_ROUND_UP);
 				err++;
 			}
 			if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) {
 				cmd->scan_begin_arg = RTD_MIN_SPEED_1;
 				rtd_ns_to_timer(&cmd->scan_begin_arg,
-					TRIG_ROUND_DOWN);
+						TRIG_ROUND_DOWN);
 				err++;
 			}
 		} else {
 			if (cmd->scan_begin_arg < RTD_MAX_SPEED) {
 				cmd->scan_begin_arg = RTD_MAX_SPEED;
 				rtd_ns_to_timer(&cmd->scan_begin_arg,
-					TRIG_ROUND_UP);
+						TRIG_ROUND_UP);
 				err++;
 			}
 			if (cmd->scan_begin_arg > RTD_MIN_SPEED) {
 				cmd->scan_begin_arg = RTD_MIN_SPEED;
 				rtd_ns_to_timer(&cmd->scan_begin_arg,
-					TRIG_ROUND_DOWN);
+						TRIG_ROUND_DOWN);
 				err++;
 			}
 		}
@@ -1774,26 +1834,26 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
 			if (cmd->convert_arg < RTD_MAX_SPEED_1) {
 				cmd->convert_arg = RTD_MAX_SPEED_1;
 				rtd_ns_to_timer(&cmd->convert_arg,
-					TRIG_ROUND_UP);
+						TRIG_ROUND_UP);
 				err++;
 			}
 			if (cmd->convert_arg > RTD_MIN_SPEED_1) {
 				cmd->convert_arg = RTD_MIN_SPEED_1;
 				rtd_ns_to_timer(&cmd->convert_arg,
-					TRIG_ROUND_DOWN);
+						TRIG_ROUND_DOWN);
 				err++;
 			}
 		} else {
 			if (cmd->convert_arg < RTD_MAX_SPEED) {
 				cmd->convert_arg = RTD_MAX_SPEED;
 				rtd_ns_to_timer(&cmd->convert_arg,
-					TRIG_ROUND_UP);
+						TRIG_ROUND_UP);
 				err++;
 			}
 			if (cmd->convert_arg > RTD_MIN_SPEED) {
 				cmd->convert_arg = RTD_MIN_SPEED;
 				rtd_ns_to_timer(&cmd->convert_arg,
-					TRIG_ROUND_DOWN);
+						TRIG_ROUND_DOWN);
 				err++;
 			}
 		}
@@ -1836,7 +1896,7 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		tmp = cmd->scan_begin_arg;
 		rtd_ns_to_timer(&cmd->scan_begin_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+				cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg) {
 			err++;
 		}
@@ -1844,15 +1904,15 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
 	if (cmd->convert_src == TRIG_TIMER) {
 		tmp = cmd->convert_arg;
 		rtd_ns_to_timer(&cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+				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))) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->scan_end_arg;
+			    cmd->convert_arg * cmd->scan_end_arg;
 			err++;
 		}
 	}
@@ -1883,7 +1943,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 #ifdef USE_DMA
 	if (devpriv->flags & DMA0_ACTIVE) {	/* cancel anything running */
 		RtdPlxInterruptWrite(dev,	/* disable any more interrupts */
-			RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
+				     RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
 		abort_dma(dev, 0);
 		devpriv->flags &= ~DMA0_ACTIVE;
 		if (RtdPlxInterruptRead(dev) & ICS_DMA0_A) {	/*clear pending int */
@@ -1929,17 +1989,17 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		} else {
 			/* arrange to transfer data periodically */
 			devpriv->transCount
-				=
-				(TRANS_TARGET_PERIOD * cmd->chanlist_len) /
-				cmd->scan_begin_arg;
+			    =
+			    (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
+			    cmd->scan_begin_arg;
 			if (devpriv->transCount < cmd->chanlist_len) {
 				/* tranfer after each scan (and avoid 0) */
 				devpriv->transCount = cmd->chanlist_len;
 			} else {	/* make a multiple of scan length */
 				devpriv->transCount =
-					(devpriv->transCount +
-					cmd->chanlist_len - 1)
-					/ cmd->chanlist_len;
+				    (devpriv->transCount +
+				     cmd->chanlist_len - 1)
+				    / cmd->chanlist_len;
 				devpriv->transCount *= cmd->chanlist_len;
 			}
 			devpriv->flags |= SEND_EOS;
@@ -1953,7 +2013,10 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			RtdAboutCounter(dev, devpriv->transCount - 1);
 		}
 
-		DPRINTK("rtd520: scanLen=%d tranferCount=%d fifoLen=%d\n  scanTime(ns)=%d flags=0x%x\n", cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen, cmd->scan_begin_arg, devpriv->flags);
+		DPRINTK
+		    ("rtd520: scanLen=%d tranferCount=%d fifoLen=%d\n  scanTime(ns)=%d flags=0x%x\n",
+		     cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen,
+		     cmd->scan_begin_arg, devpriv->flags);
 	} else {		/* unknown timing, just use 1/2 FIFO */
 		devpriv->transCount = 0;
 		devpriv->flags &= ~SEND_EOS;
@@ -1968,7 +2031,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	case TRIG_COUNT:	/* stop after N scans */
 		devpriv->aiCount = cmd->stop_arg * cmd->chanlist_len;
 		if ((devpriv->transCount > 0)
-			&& (devpriv->transCount > devpriv->aiCount)) {
+		    && (devpriv->transCount > devpriv->aiCount)) {
 			devpriv->transCount = devpriv->aiCount;
 		}
 		break;
@@ -1986,7 +2049,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	switch (cmd->scan_begin_src) {
 	case TRIG_TIMER:	/* periodic scanning */
 		timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
-			TRIG_ROUND_NEAREST);
+					TRIG_ROUND_NEAREST);
 		/* set PACER clock */
 		/*DPRINTK ("rtd520: loading %d into pacer\n", timer); */
 		RtdPacerCounter(dev, timer);
@@ -2007,7 +2070,7 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	case TRIG_TIMER:	/* periodic */
 		if (cmd->chanlist_len > 1) {	/* only needed for multi-channel */
 			timer = rtd_ns_to_timer(&cmd->convert_arg,
-				TRIG_ROUND_NEAREST);
+						TRIG_ROUND_NEAREST);
 			/* setup BURST clock */
 			/*DPRINTK ("rtd520: loading %d into burst\n", timer); */
 			RtdBurstCounter(dev, timer);
@@ -2042,11 +2105,11 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		devpriv->dma0Offset = 0;
 		RtdDma0Mode(dev, DMA_MODE_BITS);
 		RtdDma0Next(dev,	/* point to first block */
-			devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next);
+			    devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next);
 		RtdDma0Source(dev, DMAS_ADFIFO_HALF_FULL);	/* set DMA trigger source */
 
 		RtdPlxInterruptWrite(dev,	/* enable interrupt */
-			RtdPlxInterruptRead(dev) | ICS_DMA0_E);
+				     RtdPlxInterruptRead(dev) | ICS_DMA0_E);
 		/* Must be 2 steps.  See PLX app note about "Starting a DMA transfer" */
 		RtdDma0Control(dev, PLX_DMA_EN_BIT);	/* enable DMA (clear INTR?) */
 		RtdDma0Control(dev, PLX_DMA_EN_BIT | PLX_DMA_START_BIT);	/*start DMA */
@@ -2079,13 +2142,16 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 #ifdef USE_DMA
 	if (devpriv->flags & DMA0_ACTIVE) {
 		RtdPlxInterruptWrite(dev,	/* disable any more interrupts */
-			RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
+				     RtdPlxInterruptRead(dev) & ~ICS_DMA0_E);
 		abort_dma(dev, 0);
 		devpriv->flags &= ~DMA0_ACTIVE;
 	}
 #endif /* USE_DMA */
 	status = RtdInterruptStatus(dev);
-	DPRINTK("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n", devpriv->intCount, status, 0xffff & RtdInterruptOverrunStatus(dev));
+	DPRINTK
+	    ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n",
+	     devpriv->intCount, status,
+	     0xffff & RtdInterruptOverrunStatus(dev));
 	return 0;
 }
 
@@ -2096,7 +2162,7 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
   Note: you have to check if the value is larger than the counter range!
 */
 static int rtd_ns_to_timer_base(unsigned int *nanosec,	/* desired period (in ns) */
-	int round_mode, int base)
+				int round_mode, int base)
 {				/* clock period (in ns) */
 	int divider;
 
@@ -2136,7 +2202,8 @@ static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
   Output one (or more) analog values to a single port as fast as possible.
 */
 static int rtd_ao_winsn(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			struct comedi_subdevice *s, struct comedi_insn *insn,
+			unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -2155,14 +2222,16 @@ static int rtd_ao_winsn(struct comedi_device *dev,
 		/* 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 */
 			val = data[i] << 3;
 		}
 
-		DPRINTK("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n", chan, range, data[i], val);
+		DPRINTK
+		    ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n",
+		     chan, range, data[i], val);
 
 		/* a typical programming sequence */
 		RtdDacFifoPut(dev, chan, val);	/* put the value in */
@@ -2174,12 +2243,14 @@ static int rtd_ao_winsn(struct comedi_device *dev,
 			stat = RtdFifoStatus(dev);
 			/* 1 -> not empty */
 			if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
-					FS_DAC2_NOT_EMPTY))
+				    FS_DAC2_NOT_EMPTY))
 				break;
 			WAIT_QUIETLY;
 		}
 		if (ii >= RTD_DAC_TIMEOUT) {
-			DPRINTK("rtd520: Error: DAC never finished! FifoStatus=0x%x\n", stat ^ 0x6666);
+			DPRINTK
+			    ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n",
+			     stat ^ 0x6666);
 			return -ETIMEDOUT;
 		}
 	}
@@ -2191,7 +2262,8 @@ static int rtd_ao_winsn(struct comedi_device *dev,
 /* 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(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			struct comedi_subdevice *s, struct comedi_insn *insn,
+			unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -2214,7 +2286,8 @@ static int rtd_ao_rinsn(struct comedi_device *dev,
  * comedi core can convert between insn_bits and insn_read/write
  */
 static int rtd_dio_insn_bits(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			     struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data)
 {
 	if (insn->n != 2)
 		return -EINVAL;
@@ -2241,7 +2314,8 @@ static int rtd_dio_insn_bits(struct comedi_device *dev,
   Configure one bit on a IO port as Input or Output (hence the name :-).
 */
 static int rtd_dio_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
@@ -2258,8 +2332,7 @@ static int rtd_dio_insn_config(struct comedi_device *dev,
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
index f1b7e02..2c9d05b 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -98,25 +98,38 @@ Configuration options:
 #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)
-	}
+								     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)
-	}
+								    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)
-	}
+								   UNI_RANGE
+								   (10),
+								   UNI_RANGE(1),
+								   UNI_RANGE
+								   (0.1),
+								   UNI_RANGE
+								   (0.02)
+								   }
 };
 
 struct rti800_board {
@@ -132,7 +145,8 @@ static const struct rti800_board boardtypes[] = {
 
 #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_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",
@@ -181,8 +195,9 @@ static irqreturn_t rti800_interrupt(int irq, void *dev)
 /* 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)
+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;
@@ -233,8 +248,9 @@ static int rti800_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return i;
 }
 
-static int rti800_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -245,8 +261,9 @@ static int rti800_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return i;
 }
 
-static int rti800_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -258,15 +275,16 @@ static int rti800_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 			d ^= 0x800;
 		}
 		outb(d & 0xff,
-			dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
+		     dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
 		outb(d >> 8,
-			dev->iobase + (chan ? RTI800_DAC1HI : RTI800_DAC0HI));
+		     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)
+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;
@@ -274,8 +292,9 @@ static int rti800_di_insn_bits(struct comedi_device *dev, struct comedi_subdevic
 	return 2;
 }
 
-static int rti800_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -326,10 +345,10 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 #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));
+	       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);
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
index fffde45..2f75c73 100644
--- a/drivers/staging/comedi/drivers/rti802.c
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -47,7 +47,8 @@ Configuration Options:
 #define RTI802_DATALOW 1
 #define RTI802_DATAHIGH 2
 
-static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+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",
@@ -68,8 +69,9 @@ struct rti802_private {
 
 #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)
+static int rti802_ao_insn_read(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 
@@ -79,8 +81,9 @@ static int rti802_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return i;
 }
 
-static int rti802_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -113,7 +116,7 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	dev->board_name = "rti802";
 
 	if (alloc_subdevices(dev, 1) < 0
-		|| alloc_private(dev, sizeof(struct rti802_private))) {
+	    || alloc_private(dev, sizeof(struct rti802_private))) {
 		return -ENOMEM;
 	}
 
@@ -129,10 +132,10 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	for (i = 0; i < 8; i++) {
 		devpriv->dac_coding[i] = (it->options[3 + 2 * i])
-			? (dac_straight)
-			: (dac_2comp);
+		    ? (dac_straight)
+		    : (dac_2comp);
 		devpriv->range_type_list[i] = (it->options[2 + 2 * i])
-			? &range_unipolar10 : &range_bipolar10;
+		    ? &range_unipolar10 : &range_bipolar10;
 	}
 
 	printk("\n");
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
index d9509d7..b89e1ec 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -169,15 +169,15 @@ struct s526_board {
 
 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,
-		}
+	 .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))
@@ -247,24 +247,30 @@ static struct comedi_driver driver_s526 = {
 	.num_names = ARRAY_SIZE(s526_boards),
 };
 
-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_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);
+			 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);
+			 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);
+			 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
@@ -424,7 +430,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	n = 0;
 	printk("Mode reg=0x%04x, 0x%04lx\n", cmReg.value, ADDR_CHAN_REG(REG_C0M,
-			n));
+									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)));
@@ -455,7 +461,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	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])));
+		       inw(ADDR_REG(s526_ports[i])));
 	}
 	return 1;
 }
@@ -478,8 +484,9 @@ static int s526_detach(struct comedi_device *dev)
 	return 0;
 }
 
-static int s526_gpct_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+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);
@@ -502,8 +509,9 @@ static int s526_gpct_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
 	return i;
 }
 
-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_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;
@@ -513,7 +521,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdev
 
 	for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) {
 		devpriv->s526_gpct_config[subdev_channel].data[i] =
-			insn->data[i];
+		    insn->data[i];
 /* printk("data[%d]=%x\n", i, insn->data[i]); */
 	}
 
@@ -529,32 +537,32 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdev
 		 */
 		printk("s526: GPCT_INSN_CONFIG: Configuring Encoder\n");
 		devpriv->s526_gpct_config[subdev_channel].app =
-			PositionMeasurement;
+		    PositionMeasurement;
 
 #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	= 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));
+		/*  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(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(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) */
+		outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel));	/*  Reset RCAP (fires one-shot) */
 
 #endif
 
@@ -604,20 +612,20 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdev
 			cmReg.reg.autoLoadResetRcap = 4;	/*  Auto load with INDEX^ */
 
 		/*  Set Counter Mode Register */
-		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		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);
+		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);
+		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);
+			value = (short)(insn->data[3] & 0xFFFF);
 			outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
 		}
 		/*  Reset the counter if it is software preload */
@@ -638,37 +646,37 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdev
 		 */
 		printk("s526: GPCT_INSN_CONFIG: Configuring SPG\n");
 		devpriv->s526_gpct_config[subdev_channel].app =
-			SinglePulseGeneration;
+		    SinglePulseGeneration;
 
 		/*  Set Counter Mode Register */
-		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		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);
+		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);
+		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.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);
+		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);
+		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);
+			value = (short)(insn->data[3] & 0xFFFF);
 			outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
 		}
 		break;
@@ -683,37 +691,37 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdev
 		 */
 		printk("s526: GPCT_INSN_CONFIG: Configuring PTG\n");
 		devpriv->s526_gpct_config[subdev_channel].app =
-			PulseTrainGeneration;
+		    PulseTrainGeneration;
 
 		/*  Set Counter Mode Register */
-		cmReg.value = (short) (insn->data[1] & 0xFFFF);
+		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);
+		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);
+		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.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);
+		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);
+		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);
+			value = (short)(insn->data[3] & 0xFFFF);
 			outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
 		}
 		break;
@@ -727,8 +735,9 @@ static int s526_gpct_insn_config(struct comedi_device *dev, struct comedi_subdev
 	return insn->n;
 }
 
-static int s526_gpct_winsn(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)
 {
 	int subdev_channel = CR_CHAN(insn->chanspec);	/*  Unpack chanspec */
 	short value;
@@ -741,14 +750,14 @@ static int s526_gpct_winsn(struct comedi_device *dev, struct comedi_subdevice *s
 	case PositionMeasurement:
 		printk("S526: INSN_WRITE: PM\n");
 		outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
-				subdev_channel));
+							     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));
+							     subdev_channel));
 		outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
 		break;
 
@@ -762,22 +771,25 @@ static int s526_gpct_winsn(struct comedi_device *dev, struct comedi_subdevice *s
 		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];
+			    insn->data[0];
 			(devpriv->s526_gpct_config[subdev_channel]).data[1] =
-				insn->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");
+			printk
+			    ("s526: INSN_WRITE: PTG: Problem with Pulse params\n");
 			return -EINVAL;
 		}
 
-		value = (short) ((*data >> 16) & 0xFFFF);
+		value = (short)((*data >> 16) & 0xFFFF);
 		outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
-		value = (short) (*data & 0xFFFF);
+		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);
+		printk
+		    ("s526: INSN_WRITE: Functionality %d not implemented yet\n",
+		     devpriv->s526_gpct_config[subdev_channel].app);
 		return -EINVAL;
 		break;
 	}
@@ -786,8 +798,9 @@ static int s526_gpct_winsn(struct comedi_device *dev, struct comedi_subdevice *s
 }
 
 #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)
+static int s526_ai_insn_config(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int result = -EINVAL;
 
@@ -820,7 +833,7 @@ static int s526_ai_insn_config(struct comedi_device *dev, struct comedi_subdevic
  * mode.
  */
 static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int n, i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -831,7 +844,7 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	/* 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;
+	    ((1 << 5) << chan) | (chan << 1) | 0x0001;
 
 	/* convert n samples */
 	for (n = 0; n < insn->n; n++) {
@@ -853,7 +866,7 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 			/* printk() should be used instead of printk()
 			 * whenever the code can be called from real-time. */
 			printk("s526: ADC(0x%04x) timeout\n",
-				inw(ADDR_REG(REG_ISR)));
+			       inw(ADDR_REG(REG_ISR)));
 			return -ETIMEDOUT;
 		}
 
@@ -870,7 +883,7 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -899,7 +912,7 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 /* 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)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -915,8 +928,9 @@ static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  * 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)
+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;
@@ -940,8 +954,9 @@ static int s526_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 	return 2;
 }
 
-static int s526_dio_insn_config(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)
 {
 	int chan = CR_CHAN(insn->chanspec);
 	short value;
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 5d9bab3..80d2787 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -96,15 +96,15 @@ struct s626_board {
 
 static const struct s626_board s626_boards[] = {
 	{
-	.name = "s626",
-	.ai_chans = S626_ADC_CHANNELS,
-	.ai_bits = 14,
-	.ao_chans = S626_DAC_CHANNELS,
-	.ao_bits = 13,
-	.dio_chans = S626_DIO_CHANNELS,
-	.dio_banks = S626_DIO_BANKS,
-	.enc_chans = S626_ENCODER_CHANNELS,
-		}
+	 .name = "s626",
+	 .ai_chans = S626_ADC_CHANNELS,
+	 .ai_bits = 14,
+	 .ao_chans = S626_DAC_CHANNELS,
+	 .ao_bits = 13,
+	 .dio_chans = S626_DIO_CHANNELS,
+	 .dio_banks = S626_DIO_BANKS,
+	 .enc_chans = S626_ENCODER_CHANNELS,
+	 }
 };
 
 #define thisboard ((const struct s626_board *)dev->board_ptr)
@@ -149,7 +149,7 @@ struct s626_private {
 	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 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;
@@ -227,37 +227,45 @@ static struct dio_private *dio_private_word[]={
 COMEDI_PCI_INITCLEANUP_NOMODULE(driver_s626, s626_pci_table);
 
 /* 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_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_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_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);
+			 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);
+			 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);
+			      unsigned int mask);
 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_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, struct comedi_cmd *cmd);
-static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum);
+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);
 static unsigned int s626_ai_reg_to_uint(int data);
 /* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data); */
@@ -266,10 +274,10 @@ static unsigned int s626_ai_reg_to_uint(int data);
 
 /* internal routines */
 static void s626_dio_init(struct comedi_device *dev);
-static void ResetADC(struct comedi_device *dev, uint8_t *ppl);
+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);
+			 uint8_t DacData);
 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);
@@ -279,22 +287,23 @@ 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(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize);
+			uint16_t wdata);
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
+		      size_t bsize);
 
 /*  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(*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. */
@@ -306,31 +315,36 @@ struct enc_private {
 #define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
 
 /* counters routines */
-static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick);
+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(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
-	uint16_t DisableIntSrc);
-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 void SetMode_A(struct comedi_device *dev, struct enc_private *k,
+		      uint16_t Setup, uint16_t DisableIntSrc);
+static void SetMode_B(struct comedi_device *dev, struct enc_private *k,
+		      uint16_t Setup, uint16_t DisableIntSrc);
+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);
+			   uint16_t value);
 /* 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 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);
+			uint16_t IntSource);
 static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
-	uint16_t IntSource);
+			uint16_t IntSource);
 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 ) ; */
@@ -343,7 +357,8 @@ static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k);
 /* 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 Preload(struct comedi_device *dev, struct enc_private *k,
+		    uint32_t value);
 static void CountersInit(struct comedi_device *dev);
 /* end internal routines */
 
@@ -360,101 +375,101 @@ static void CountersInit(struct comedi_device *dev);
 /* 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),
-		},
+	 .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),
+	 },
 	{
-	.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),
-		},
+	 .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),
+	 },
 	{
-	.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),
-		},
+	 .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),
+	 },
 	{
-	.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),
-		},
+	 .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),
+	 },
 	{
-	.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),
-		},
+	 .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),
+	 },
 	{
-	.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),
-		},
+	 .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),
+	 },
 };
 
 /*  enab/disable a function or test status bit(s) that are accessed */
@@ -485,9 +500,9 @@ static struct enc_private enc_private_data[] = {
 #define I2C_B0(ATTR, VAL)	(((ATTR) << 2) | ((VAL) <<  8))
 
 static const struct comedi_lrange s626_range_table = { 2, {
-			RANGE(-5, 5),
-			RANGE(-10, 10),
-	}
+							   RANGE(-5, 5),
+							   RANGE(-10, 10),
+							   }
 };
 
 static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
@@ -512,8 +527,9 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	for (i = 0; i < (ARRAY_SIZE(s626_pci_table) - 1) && !pdev; i++) {
 		ids = &s626_pci_table[i];
 		do {
-			pdev = pci_get_subsys(ids->vendor, ids->device, ids->subvendor,
-					      ids->subdevice, pdev);
+			pdev = pci_get_subsys(ids->vendor, ids->device,
+					      ids->subvendor, ids->subdevice,
+					      pdev);
 
 			if ((it->options[0] || it->options[1]) && pdev) {
 				/* matches requested bus/slot */
@@ -560,7 +576,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		devpriv->allocatedBuf = 0;
 
 		devpriv->ANABuf.LogicalBase =
-			pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
+		    pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
 
 		if (devpriv->ANABuf.LogicalBase == NULL) {
 			printk("s626_attach: DMA Memory mapping error\n");
@@ -569,12 +585,15 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 		devpriv->ANABuf.PhysicalBase = appdma;
 
-		DEBUG("s626_attach: AllocDMAB ADC Logical=%p, bsize=%d, Physical=0x%x\n", devpriv->ANABuf.LogicalBase, DMABUF_SIZE, (uint32_t) devpriv->ANABuf.PhysicalBase);
+		DEBUG
+		    ("s626_attach: AllocDMAB ADC Logical=%p, bsize=%d, Physical=0x%x\n",
+		     devpriv->ANABuf.LogicalBase, DMABUF_SIZE,
+		     (uint32_t) devpriv->ANABuf.PhysicalBase);
 
 		devpriv->allocatedBuf++;
 
 		devpriv->RPSBuf.LogicalBase =
-			pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,  &appdma);
+		    pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
 
 		if (devpriv->RPSBuf.LogicalBase == NULL) {
 			printk("s626_attach: DMA Memory mapping error\n");
@@ -583,7 +602,10 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 		devpriv->RPSBuf.PhysicalBase = appdma;
 
-		DEBUG("s626_attach: AllocDMAB RPS Logical=%p, bsize=%d, Physical=0x%x\n", devpriv->RPSBuf.LogicalBase, DMABUF_SIZE, (uint32_t) devpriv->RPSBuf.PhysicalBase);
+		DEBUG
+		    ("s626_attach: AllocDMAB RPS Logical=%p, bsize=%d, Physical=0x%x\n",
+		     devpriv->RPSBuf.LogicalBase, DMABUF_SIZE,
+		     (uint32_t) devpriv->RPSBuf.PhysicalBase);
 
 		devpriv->allocatedBuf++;
 
@@ -612,7 +634,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	DEBUG("s626_attach: -- it opts  %d,%d -- \n",
-		it->options[0], it->options[1]);
+	      it->options[0], it->options[1]);
 
 	s = dev->subdevices + 0;
 	/* analog input subdevice */
@@ -701,20 +723,22 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		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 */
+		       /*  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_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 */
@@ -725,22 +749,22 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		/*  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.
-     *
-     * 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.
-     */
+		/* 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.
+		 */
 
 		/*     devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */
 		/*  DeviceType (0xA0) */
@@ -755,8 +779,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		/*  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)
-			;
+		while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) ;
 		/*  and wait for upload to complete. */
 
 		/* Per SAA7146 data sheet, write to STATUS reg twice to
@@ -765,8 +788,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			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))
-				;
+			while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
 			/* and wait for upload to complete. */
 		}
 
@@ -847,8 +869,8 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		 * enabled. */
 
 		pPhysBuf =
-			devpriv->ANABuf.PhysicalBase +
-			(DAC_WDMABUF_OS * sizeof(uint32_t));
+		    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. */
@@ -856,8 +878,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		/* 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;
+		    (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
@@ -942,7 +963,8 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 		 * charger, and reset the watchdog interval selector to zero.
 		 */
 		WriteMISC2(dev, (uint16_t) (DEBIread(dev,
-					LP_RDMISC2) & MISC2_BATT_ENABLE));
+						     LP_RDMISC2) &
+					    MISC2_BATT_ENABLE));
 
 		/*  Initialize the digital I/O subsystem. */
 		s626_dio_init(dev);
@@ -952,7 +974,7 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor,
-		(uint32_t) devpriv->base_addr);
+	      (uint32_t) devpriv->base_addr);
 
 	return 1;
 }
@@ -1035,10 +1057,11 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 			/* 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");
+				printk
+				    ("s626_irq_handler: cfc_write_to_buffer error!\n");
 
 			DEBUG("s626_irq_handler: ai channel %d acquired: %d\n",
-				i, tempdata);
+			      i, tempdata);
 		}
 
 		/* end of scan occurs */
@@ -1060,7 +1083,9 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 		}
 
 		if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) {
-			DEBUG("s626_irq_handler: enable interrupt on dio channel %d\n", cmd->scan_begin_arg);
+			DEBUG
+			    ("s626_irq_handler: enable interrupt on dio channel %d\n",
+			     cmd->scan_begin_arg);
 
 			s626_dio_set_irq(dev, cmd->scan_begin_arg);
 
@@ -1084,102 +1109,120 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 			irqbit = 0;
 			/* read interrupt type */
 			irqbit = DEBIread(dev,
-				((struct dio_private *) (dev->subdevices + 2 +
-						group)->private)->RDCapFlg);
+					  ((struct dio_private *)(dev->
+								  subdevices +
+								  2 +
+								  group)->
+					   private)->RDCapFlg);
 
 			/* 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);
+				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 */
 					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);
+							(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. */
 						MC_ENABLE(P_MC1, MC1_ERPS1);
 
-						DEBUG("s626_irq_handler: aquisition start triggered!!!\n");
+						DEBUG
+						    ("s626_irq_handler: aquisition start triggered!!!\n");
 
 						if (cmd->scan_begin_src ==
-							TRIG_EXT) {
-							DEBUG("s626_ai_cmd: enable interrupt on dio channel %d\n", cmd->scan_begin_arg);
+						    TRIG_EXT) {
+							DEBUG
+							    ("s626_ai_cmd: enable interrupt on dio channel %d\n",
+							     cmd->
+							     scan_begin_arg);
 
 							s626_dio_set_irq(dev,
-								cmd->
-								scan_begin_arg);
+									 cmd->scan_begin_arg);
 
-							DEBUG("s626_irq_handler: External scan trigger is set!!!\n");
+							DEBUG
+							    ("s626_irq_handler: External scan trigger is set!!!\n");
 						}
 					}
 					if ((irqbit >> (cmd->scan_begin_arg -
-								(16 * group)))
-						== 1
-						&& cmd->scan_begin_src ==
-						TRIG_EXT) {
-						DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->scan_begin_arg);
+							(16 * group)))
+					    == 1
+					    && cmd->scan_begin_src ==
+					    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. */
 						MC_ENABLE(P_MC2, MC2_ADC_RPS);
 
-						DEBUG("s626_irq_handler: scan triggered!!! %d\n", devpriv->ai_sample_count);
+						DEBUG
+						    ("s626_irq_handler: scan triggered!!! %d\n",
+						     devpriv->ai_sample_count);
 						if (cmd->convert_src ==
-							TRIG_EXT) {
+						    TRIG_EXT) {
 
-							DEBUG("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", cmd->convert_arg - (16 * group), group);
+							DEBUG
+							    ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",
+							     cmd->convert_arg -
+							     (16 * group),
+							     group);
 
-							devpriv->
-								ai_convert_count
-								=
-								cmd->
-								chanlist_len;
+							devpriv->ai_convert_count
+							    = cmd->chanlist_len;
 
 							s626_dio_set_irq(dev,
-								cmd->
-								convert_arg);
+									 cmd->convert_arg);
 
-							DEBUG("s626_irq_handler: External convert trigger is set!!!\n");
+							DEBUG
+							    ("s626_irq_handler: External convert trigger is set!!!\n");
 						}
 
 						if (cmd->convert_src ==
-							TRIG_TIMER) {
+						    TRIG_TIMER) {
 							k = &encpriv[5];
-							devpriv->
-								ai_convert_count
-								=
-								cmd->
-								chanlist_len;
+							devpriv->ai_convert_count
+							    = cmd->chanlist_len;
 							k->SetEnable(dev, k,
-								CLKENAB_ALWAYS);
+								     CLKENAB_ALWAYS);
 						}
 					}
 					if ((irqbit >> (cmd->convert_arg -
-								(16 * group)))
-						== 1
-						&& cmd->convert_src ==
-						TRIG_EXT) {
-						DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->convert_arg);
+							(16 * group)))
+					    == 1
+					    && cmd->convert_src == 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. */
 						MC_ENABLE(P_MC2, MC2_ADC_RPS);
 
-						DEBUG("s626_irq_handler: adc convert triggered!!!\n");
+						DEBUG
+						    ("s626_irq_handler: adc convert triggered!!!\n");
 
 						devpriv->ai_convert_count--;
 
 						if (devpriv->ai_convert_count >
-							0) {
+						    0) {
 
-							DEBUG("s626_ai_cmd: enable interrupt on dio channel %d group %d\n", cmd->convert_arg - (16 * group), group);
+							DEBUG
+							    ("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",
+							     cmd->convert_arg -
+							     (16 * group),
+							     group);
 
 							s626_dio_set_irq(dev,
-								cmd->
-								convert_arg);
+									 cmd->convert_arg);
 
-							DEBUG("s626_irq_handler: External trigger is set!!!\n");
+							DEBUG
+							    ("s626_irq_handler: External trigger is set!!!\n");
 						}
 					}
 				}
@@ -1192,38 +1235,43 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 
 		/* check interrupt on counters */
 		DEBUG("s626_irq_handler: check counters interrupt %d\n",
-			irqbit);
+		      irqbit);
 
 		if (irqbit & IRQ_COINT1A) {
-			DEBUG("s626_irq_handler: interrupt on counter 1A overflow\n");
+			DEBUG
+			    ("s626_irq_handler: interrupt on counter 1A overflow\n");
 			k = &encpriv[0];
 
 			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT2A) {
-			DEBUG("s626_irq_handler: interrupt on counter 2A overflow\n");
+			DEBUG
+			    ("s626_irq_handler: interrupt on counter 2A overflow\n");
 			k = &encpriv[1];
 
 			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT3A) {
-			DEBUG("s626_irq_handler: interrupt on counter 3A overflow\n");
+			DEBUG
+			    ("s626_irq_handler: interrupt on counter 3A overflow\n");
 			k = &encpriv[2];
 
 			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT1B) {
-			DEBUG("s626_irq_handler: interrupt on counter 1B overflow\n");
+			DEBUG
+			    ("s626_irq_handler: interrupt on counter 1B overflow\n");
 			k = &encpriv[3];
 
 			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 		}
 		if (irqbit & IRQ_COINT2B) {
-			DEBUG("s626_irq_handler: interrupt on counter 2B overflow\n");
+			DEBUG
+			    ("s626_irq_handler: interrupt on counter 2B overflow\n");
 			k = &encpriv[4];
 
 			/* clear interrupt capture flag */
@@ -1235,7 +1283,9 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 					k->SetEnable(dev, k, CLKENAB_INDEX);
 
 				if (cmd->convert_src == TRIG_TIMER) {
-					DEBUG("s626_irq_handler: conver timer trigger!!! %d\n", devpriv->ai_convert_count);
+					DEBUG
+					    ("s626_irq_handler: conver timer trigger!!! %d\n",
+					     devpriv->ai_convert_count);
 
 					/*  Trigger ADC scan loop start by setting RPS Signal 0. */
 					MC_ENABLE(P_MC2, MC2_ADC_RPS);
@@ -1243,21 +1293,24 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
 			}
 		}
 		if (irqbit & IRQ_COINT3B) {
-			DEBUG("s626_irq_handler: interrupt on counter 3B overflow\n");
+			DEBUG
+			    ("s626_irq_handler: interrupt on counter 3B overflow\n");
 			k = &encpriv[5];
 
 			/* clear interrupt capture flag */
 			k->ResetCapFlags(dev, k);
 
 			if (cmd->scan_begin_src == TRIG_TIMER) {
-				DEBUG("s626_irq_handler: scan timer trigger!!!\n");
+				DEBUG
+				    ("s626_irq_handler: scan timer trigger!!!\n");
 
 				/*  Trigger ADC scan loop start by setting RPS Signal 0. */
 				MC_ENABLE(P_MC2, MC2_ADC_RPS);
 			}
 
 			if (cmd->convert_src == TRIG_TIMER) {
-				DEBUG("s626_irq_handler: convert timer trigger is set\n");
+				DEBUG
+				    ("s626_irq_handler: convert timer trigger is set\n");
 				k = &encpriv[4];
 				devpriv->ai_convert_count = cmd->chanlist_len;
 				k->SetEnable(dev, k, CLKENAB_ALWAYS);
@@ -1317,7 +1370,7 @@ static int s626_detach(struct comedi_device *dev)
 /*
  * this functions build the RPS program for hardware driven acquistion
  */
-void ResetADC(struct comedi_device *dev, uint8_t *ppl)
+void ResetADC(struct comedi_device *dev, uint8_t * ppl)
 {
 	register uint32_t *pRPS;
 	uint32_t JmpAdrs;
@@ -1371,14 +1424,14 @@ void ResetADC(struct comedi_device *dev, uint8_t *ppl)
 	 * 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);
+		    (*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
+				   GSEL_BIPOLAR10V);
 
 		/*  Switch ADC analog gain. */
 		*pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);	/*  Write DEBI command */
@@ -1418,9 +1471,9 @@ void ResetADC(struct comedi_device *dev, uint8_t *ppl)
 		 * instruction prefetch pipeline.
 		 */
 		JmpAdrs =
-			(uint32_t) devpriv->RPSBuf.PhysicalBase +
-			(uint32_t) ((unsigned long)pRPS -
-			(unsigned long)devpriv->RPSBuf.LogicalBase);
+		    (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. */
@@ -1450,8 +1503,8 @@ void ResetADC(struct comedi_device *dev, uint8_t *ppl)
 		/*  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);
+		    (uint32_t) devpriv->ANABuf.PhysicalBase +
+		    (devpriv->AdcItems << 2);
 
 		/*  If this slot's EndOfPollList flag is set, all channels have */
 		/*  now been processed. */
@@ -1490,8 +1543,7 @@ void ResetADC(struct comedi_device *dev, uint8_t *ppl)
 	/*  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);
+	    (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. */
@@ -1509,8 +1561,9 @@ void ResetADC(struct comedi_device *dev, uint8_t *ppl)
 }
 
 /* TO COMPLETE, IF NECESSARY */
-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_insn_config(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 
 	return -EINVAL;
@@ -1546,8 +1599,9 @@ static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevic
 /*   return i; */
 /* } */
 
-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_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);
@@ -1555,7 +1609,7 @@ static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	uint32_t GpioImage;
 	int n;
 
- /* interrupt call test  */
+	/* 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
@@ -1597,8 +1651,7 @@ static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 		/*  shift into FB BUFFER 1 register. */
 
 		/*  Wait for ADC done. */
-		while (!(RR7146(P_PSR) & PSR_GPIO2))
-			;
+		while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
 
 		/*  Fetch ADC data. */
 		if (n != 0)
@@ -1630,8 +1683,7 @@ static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	/*  Wait for the data to arrive in FB BUFFER 1 register. */
 
 	/*  Wait for ADC done. */
-	while (!(RR7146(P_PSR) & PSR_GPIO2))
-		;
+	while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
 
 	/*  Fetch ADC data from audio interface's input shift register. */
 
@@ -1644,7 +1696,7 @@ static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	return n;
 }
 
-static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
+static int s626_ai_load_polllist(uint8_t * ppl, struct comedi_cmd *cmd)
 {
 
 	int n;
@@ -1655,13 +1707,14 @@ static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
 		else
 			ppl[n] = (CR_CHAN((cmd->chanlist)[n])) | (RANGE_10V);
 	}
-	ppl[n - 1] |= EOPL;
+	if (n != 0)
+		ppl[n - 1] |= EOPL;
 
 	return n;
 }
 
-static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-	unsigned int trignum)
+static int s626_ai_inttrig(struct comedi_device *dev,
+			   struct comedi_subdevice *s, unsigned int trignum)
 {
 	if (trignum != 0)
 		return -EINVAL;
@@ -1691,7 +1744,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (devpriv->ai_cmd_running) {
 		printk("s626_ai_cmd: Another ai_cmd is running %d\n",
-			dev->minor);
+		       dev->minor);
 		return -EBUSY;
 	}
 	/* disable interrupt */
@@ -1717,7 +1770,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 	if (dev->irq == 0) {
 		comedi_error(dev,
-			"s626_ai_cmd: cannot run command without an irq");
+			     "s626_ai_cmd: cannot run command without an irq");
 		return -EIO;
 	}
 
@@ -1732,14 +1785,14 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		/*  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);
+					cmd->flags & TRIG_ROUND_MASK);
 
 		/* load timer value and enable interrupt */
 		s626_timer_load(dev, k, tick);
 		k->SetEnable(dev, k, CLKENAB_ALWAYS);
 
 		DEBUG("s626_ai_cmd: scan trigger timer is set with value %d\n",
-			tick);
+		      tick);
 
 		break;
 	case TRIG_EXT:
@@ -1759,18 +1812,20 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		/*  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);
+					cmd->flags & TRIG_ROUND_MASK);
 
 		/* 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);
+		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 */
 		if (cmd->scan_begin_src != TRIG_EXT
-			&& cmd->start_src == TRIG_EXT)
+		    && cmd->start_src == TRIG_EXT)
 			s626_dio_set_irq(dev, cmd->convert_arg);
 
 		DEBUG("s626_ai_cmd: External convert trigger is set!!!\n");
@@ -1825,8 +1880,8 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	return 0;
 }
 
-static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct 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;
@@ -1873,11 +1928,11 @@ static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 
 	/* note that mutual compatiblity is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
-		cmd->scan_begin_src != TRIG_EXT
-		&& cmd->scan_begin_src != TRIG_FOLLOW)
+	    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)
+	    cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
 		err++;
 	if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 		err++;
@@ -1970,21 +2025,21 @@ static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	if (cmd->scan_begin_src == TRIG_TIMER) {
 		tmp = cmd->scan_begin_arg;
 		s626_ns_to_timer((int *)&cmd->scan_begin_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+				 cmd->flags & TRIG_ROUND_MASK);
 		if (tmp != cmd->scan_begin_arg)
 			err++;
 	}
 	if (cmd->convert_src == TRIG_TIMER) {
 		tmp = cmd->convert_arg;
 		s626_ns_to_timer((int *)&cmd->convert_arg,
-			cmd->flags & TRIG_ROUND_MASK);
+				 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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->scan_end_arg;
+			    cmd->convert_arg * cmd->scan_end_arg;
 			err++;
 		}
 	}
@@ -2037,7 +2092,7 @@ static int s626_ns_to_timer(int *nanosec, int round_mode)
 }
 
 static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 
 	int i;
@@ -2056,7 +2111,7 @@ static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 }
 
 static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 
@@ -2101,8 +2156,9 @@ static void s626_dio_init(struct comedi_device *dev)
  * 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(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)
 {
 
 	/* Length of data must be 2 (mask and new data, see below) */
@@ -2110,7 +2166,9 @@ static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 		return 0;
 
 	if (insn->n != 2) {
-		printk("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n", dev->minor);
+		printk
+		    ("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n",
+		     dev->minor);
 		return -EINVAL;
 	}
 
@@ -2137,16 +2195,17 @@ static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 	return 2;
 }
 
-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_insn_config(struct comedi_device *dev,
+				struct comedi_subdevice *s,
+				struct comedi_insn *insn, unsigned int *data)
 {
 
 	switch (data[0]) {
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->io_bits & (1 << CR_CHAN(insn->
-					chanspec))) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (s->
+		     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
+		    COMEDI_INPUT;
 		return insn->n;
 		break;
 	case COMEDI_INPUT:
@@ -2174,50 +2233,55 @@ static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
 	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);
+	      chan - (16 * group), group);
 
 	/* set channel to capture positive edge */
 	status = DEBIread(dev,
-		((struct dio_private *) (dev->subdevices + 2 +
-				group)->private)->RDEdgSel);
+			  ((struct dio_private *)(dev->subdevices + 2 +
+						  group)->private)->RDEdgSel);
 	DEBIwrite(dev,
-		((struct dio_private *) (dev->subdevices + 2 +
-				group)->private)->WREdgSel, bitmask | status);
+		  ((struct dio_private *)(dev->subdevices + 2 +
+					  group)->private)->WREdgSel,
+		  bitmask | status);
 
 	/* enable interrupt on selected channel */
 	status = DEBIread(dev,
-		((struct dio_private *) (dev->subdevices + 2 +
-				group)->private)->RDIntSel);
+			  ((struct dio_private *)(dev->subdevices + 2 +
+						  group)->private)->RDIntSel);
 	DEBIwrite(dev,
-		((struct dio_private *) (dev->subdevices + 2 +
-				group)->private)->WRIntSel, bitmask | status);
+		  ((struct dio_private *)(dev->subdevices + 2 +
+					  group)->private)->WRIntSel,
+		  bitmask | status);
 
 	/* enable edge capture write command */
 	DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
 
 	/* enable edge capture on selected channel */
 	status = DEBIread(dev,
-		((struct dio_private *) (dev->subdevices + 2 +
-				group)->private)->RDCapSel);
+			  ((struct dio_private *)(dev->subdevices + 2 +
+						  group)->private)->RDCapSel);
 	DEBIwrite(dev,
-		((struct dio_private *) (dev->subdevices + 2 +
-				group)->private)->WRCapSel, bitmask | status);
+		  ((struct dio_private *)(dev->subdevices + 2 +
+					  group)->private)->WRCapSel,
+		  bitmask | status);
 
 	return 0;
 }
 
 static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
-	unsigned int mask)
+			      unsigned int mask)
 {
-	DEBUG("s626_dio_reset_irq: disable  interrupt on dio channel %d group %d\n", mask, group);
+	DEBUG
+	    ("s626_dio_reset_irq: disable  interrupt on dio channel %d group %d\n",
+	     mask, group);
 
 	/* disable edge capture write command */
 	DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
 
 	/* enable edge capture on selected channel */
 	DEBIwrite(dev,
-		((struct dio_private *) (dev->subdevices + 2 +
-				group)->private)->WRCapSel, mask);
+		  ((struct dio_private *)(dev->subdevices + 2 +
+					  group)->private)->WRCapSel, mask);
 
 	return 0;
 }
@@ -2232,8 +2296,9 @@ static int s626_dio_clear_irq(struct comedi_device *dev)
 	for (group = 0; group < S626_DIO_BANKS; group++) {
 		/* clear pending events and interrupt */
 		DEBIwrite(dev,
-			((struct dio_private *) (dev->subdevices + 2 +
-					group)->private)->WRCapSel, 0xffff);
+			  ((struct dio_private *)(dev->subdevices + 2 +
+						  group)->private)->WRCapSel,
+			  0xffff);
 	}
 
 	return 0;
@@ -2242,17 +2307,18 @@ static int s626_dio_clear_irq(struct comedi_device *dev)
 /* 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(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *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. */
-		(CLKENAB_INDEX << BF_CLKENAB);
+	    /*  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 */
 	uint16_t valueSrclatch = LATCHSRC_AB_READ;
@@ -2272,15 +2338,16 @@ static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevi
 	return insn->n;
 }
 
-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_read(struct comedi_device *dev,
+			      struct comedi_subdevice *s,
+			      struct comedi_insn *insn, unsigned int *data)
 {
 
 	int n;
 	struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
 
 	DEBUG("s626_enc_insn_read: encoder read channel %d \n",
-		CR_CHAN(insn->chanspec));
+	      CR_CHAN(insn->chanspec));
 
 	for (n = 0; n < insn->n; n++)
 		data[n] = ReadLatch(dev, k);
@@ -2290,14 +2357,15 @@ static int s626_enc_insn_read(struct comedi_device *dev, struct comedi_subdevice
 	return n;
 }
 
-static int s626_enc_insn_write(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)
 {
 
 	struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
 
 	DEBUG("s626_enc_insn_write: encoder write channel %d \n",
-		CR_CHAN(insn->chanspec));
+	      CR_CHAN(insn->chanspec));
 
 	/*  Set the preload register */
 	Preload(dev, k, data[0]);
@@ -2313,16 +2381,17 @@ static int s626_enc_insn_write(struct comedi_device *dev, struct comedi_subdevic
 	return 1;
 }
 
-static void s626_timer_load(struct comedi_device *dev, struct 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. */
-		(CLKENAB_INDEX << BF_CLKENAB);
+	    /*  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; */
 
@@ -2357,7 +2426,7 @@ static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
 
 /*  TrimDac LogicalChan-to-EepromAdrs mapping table. */
 static uint8_t trimadrs[] =
-	{ 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
+    { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
 
 static void LoadTrimDACs(struct comedi_device *dev)
 {
@@ -2369,7 +2438,7 @@ static void LoadTrimDACs(struct comedi_device *dev)
 }
 
 static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
-	uint8_t DacData)
+			 uint8_t DacData)
 {
 	uint32_t chan;
 
@@ -2416,22 +2485,26 @@ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
 	/*  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)
+			 | I2C_B1(I2C_ATTRSTOP, addr)
 			 /* Byte1 = EEPROM internal target address. */
-			| I2C_B0(I2C_ATTRNOP, 0))) {	/*  Byte0 = Not sent. */
+			 | 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. */
+	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");
@@ -2451,12 +2524,10 @@ static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
 	/*  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)
-		;
+	while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) ;
 
 	/*  Return non-zero if I2C error occured. */
 	return RR7146(P_I2CCTRL) & I2C_ERR;
@@ -2570,8 +2641,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
 	 * Done by polling the DMAC enable flag; this flag is automatically
 	 * cleared when the transfer has finished.
 	 */
-	while ((RR7146(P_MC1) & MC1_A2OUT) != 0)
-		;
+	while ((RR7146(P_MC1) & MC1_A2OUT) != 0) ;
 
 	/* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
 
@@ -2588,8 +2658,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
 	 * finished transferring the DAC's data DWORD from the output FIFO
 	 * to the output buffer register.
 	 */
-	while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0)
-		;
+	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,
@@ -2625,8 +2694,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
 		 * 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)
-			;
+		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,
@@ -2642,8 +2710,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val)
 	 * the next DAC write.  This is detected when FB_BUFFER2 MSB changes
 	 * from 0x00 to 0xFF.
 	 */
-	while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0)
-		;
+	while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) ;
 }
 
 static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
@@ -2682,12 +2749,10 @@ static void DEBItransfer(struct comedi_device *dev)
 
 	/*  Wait for completion of upload from shadow RAM to DEBI control */
 	/*  register. */
-	while (!MC_TEST(P_MC2, MC2_UPLD_DEBI))
-		;
+	while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) ;
 
 	/*  Wait until DEBI transfer is done. */
-	while (RR7146(P_PSR) & PSR_DEBI_S)
-		;
+	while (RR7146(P_PSR) & PSR_DEBI_S) ;
 }
 
 /*  Write a value to a gate array register. */
@@ -2707,7 +2772,7 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
  * or'd with the masked original.
  */
 static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
-	uint16_t wdata)
+			uint16_t wdata)
 {
 
 	/*  Copy target gate array register into P_DEBIAD register. */
@@ -2724,7 +2789,8 @@ static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
 	DEBItransfer(dev);	/*  Execute the DEBI Write transfer. */
 }
 
-static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize)
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma,
+		      size_t bsize)
 {
 	void *vbptr;
 	dma_addr_t vpptr;
@@ -2742,7 +2808,7 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t
 		pdma->PhysicalBase = 0;
 
 		DEBUG("CloseDMAB(): Logical=%p, bsize=%d, Physical=0x%x\n",
-			vbptr, bsize, (uint32_t) vpptr);
+		      vbptr, bsize, (uint32_t) vpptr);
 	}
 }
 
@@ -2781,13 +2847,13 @@ static uint32_t ReadLatch(struct comedi_device *dev, struct 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);
+		    CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
 }
 
 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);
+		    CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
 }
 
 /*  Return counter setup in a format (COUNTER_SETUP) that is consistent */
@@ -2806,26 +2872,25 @@ static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
 	/*  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. */
+		 |((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. */
+			  |((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. */
-				(MULT_X1 << STDBIT_CLKMULT) :
-				((cra >> (CRABIT_CLKMULT_A -
-							STDBIT_CLKMULT)) &
-					STDMSK_CLKMULT)));
+			  |((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 setup;
@@ -2844,27 +2909,27 @@ static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
 	/*  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>. */
+		 |((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>). */
+			  |(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>). */
+			  |(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. */
+			  |((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 setup;
@@ -2877,8 +2942,8 @@ static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
  * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
  */
 
-static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
-	uint16_t DisableIntSrc)
+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;
@@ -2886,15 +2951,15 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t
 
 	/*  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. */
+	       |((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. */
+	       | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)));	/*  Clock enable is passed through. */
 
 	/*  Force IntSrc to Disabled if DisableIntSrc is asserted. */
 	if (!DisableIntSrc)
 		cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
-				CRABIT_INTSRC_A));
+						    CRABIT_INTSRC_A));
 
 	/*  Populate all mode-dependent attributes of CRA & CRB images. */
 	switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
@@ -2903,25 +2968,25 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t
 
 	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. */
+			|((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. */
-				(MULT_X1 << CRABIT_CLKMULT_A) :
-				((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
-						STDBIT_CLKMULT))));
+			|(((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. */
 	if (~setup & STDMSK_INDXSRC)
 		cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
-				STDBIT_INDXPOL));
+						     STDBIT_INDXPOL));
 
 	/*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
 	/*  enable mask to indicate the counter interrupt is disabled. */
@@ -2932,11 +2997,11 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t
 	/*  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);
+		    (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb);
 }
 
-static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
-	uint16_t DisableIntSrc)
+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;
@@ -2946,44 +3011,44 @@ static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t
 	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. */
+	       | ((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. */
 	if (!DisableIntSrc)
 		crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
-				CRBBIT_INTSRC_B));
+						    CRBBIT_INTSRC_B));
 
 	/*  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. */
+			|((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. */
+			|(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. */
+			|((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. */
+			|(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. */
-				(MULT_X1 << CRBBIT_CLKMULT_B) :
-				((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
-						STDBIT_CLKMULT))));
+			|(((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. */
 	if (~setup & STDMSK_INDXSRC)
 		crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
-				CRBBIT_INDXPOL_B));
+						     CRBBIT_INDXPOL_B));
 
 	/*  If IntSrc has been forced to Disabled, update the MISC2 interrupt */
 	/*  enable mask to indicate the counter interrupt is disabled. */
@@ -2993,25 +3058,27 @@ static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t
 	/*  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);
+		    (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. */
 
-static void SetEnable_A(struct comedi_device *dev, struct 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,
-		(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)),
-		(uint16_t) (enab << CRBBIT_CLKENAB_A));
+		    (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)),
+		    (uint16_t) (enab << CRBBIT_CLKENAB_A));
 }
 
-static void SetEnable_B(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)
 {
 	DEBIreplace(dev, k->MyCRB,
-		(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
-		(uint16_t) (enab << CRBBIT_CLKENAB_B));
+		    (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
+		    (uint16_t) (enab << CRBBIT_CLKENAB_B));
 }
 
 static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
@@ -3029,12 +3096,13 @@ static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
  * latches B.
  */
 
-static void SetLatchSource(struct comedi_device *dev, struct 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,
-		(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)),
-		(uint16_t) (value << CRBBIT_LATCHSRC));
+		    (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)),
+		    (uint16_t) (value << CRBBIT_LATCHSRC));
 
 	DEBUG("SetLatchSource: SetLatchSource exit \n");
 }
@@ -3052,17 +3120,19 @@ static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uin
  * 2=OverflowA (B counters only), 3=disabled.
  */
 
-static void SetLoadTrig_A(struct comedi_device *dev, struct 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));
+		    (uint16_t) (Trig << CRABIT_LOADSRC_A));
 }
 
-static void SetLoadTrig_B(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)
 {
 	DEBIreplace(dev, k->MyCRB,
-		(uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
-		(uint16_t) (Trig << CRBBIT_LOADSRC_B));
+		    (uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
+		    (uint16_t) (Trig << CRBBIT_LOADSRC_B));
 }
 
 static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
@@ -3081,24 +3151,24 @@ static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
  */
 
 static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
-	uint16_t IntSource)
+			uint16_t IntSource)
 {
 	/*  Reset any pending counter overflow or index captures. */
 	DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
-		CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
+		    CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
 
 	/*  Program counter interrupt source. */
 	DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
-		(uint16_t) (IntSource << CRABIT_INTSRC_A));
+		    (uint16_t) (IntSource << CRABIT_INTSRC_A));
 
 	/*  Update MISC2 interrupt enable mask. */
 	devpriv->CounterIntEnabs =
-		(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
-		MyEventBits[IntSource];
+	    (devpriv->CounterIntEnabs & ~k->
+	     MyEventBits[3]) | k->MyEventBits[IntSource];
 }
 
 static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
-	uint16_t IntSource)
+			uint16_t IntSource)
 {
 	uint16_t crb;
 
@@ -3107,17 +3177,17 @@ static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
 
 	/*  Reset any pending counter overflow or index captures. */
 	DEBIwrite(dev, k->MyCRB,
-		(uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
+		  (uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
 
 	/*  Program counter interrupt source. */
 	DEBIwrite(dev, k->MyCRB,
-		(uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
-				CRBBIT_INTSRC_B)));
+		  (uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
+							  CRBBIT_INTSRC_B)));
 
 	/*  Update MISC2 interrupt enable mask. */
 	devpriv->CounterIntEnabs =
-		(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
-		MyEventBits[IntSource];
+	    (devpriv->CounterIntEnabs & ~k->
+	     MyEventBits[3]) | k->MyEventBits[IntSource];
 }
 
 static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
@@ -3216,13 +3286,14 @@ static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
 
 /*  Write value into counter preload register. */
 
-static void Preload(struct comedi_device *dev, struct 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. */
 	DEBUG("Preload: preload step 1\n");
 	DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
-		(uint16_t) (value >> 16));
+		  (uint16_t) (value >> 16));
 }
 
 static void CountersInit(struct comedi_device *dev)
@@ -3230,13 +3301,13 @@ static void CountersInit(struct comedi_device *dev)
 	int chan;
 	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 */
+	    /*  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. */
 	for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 27ae02b..1d04922 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -134,17 +134,17 @@
 #define DAC_WDMABUF_OS		ADC_DMABUF_DWORDS
 
 /*  Interrupt enab bit in ISR and IER. */
-#define IRQ_GPIO3		0x00000040  /*  IRQ enable for GPIO3. */
+#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 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 */
 
 /*  RPS command codes. */
 #define RPS_CLRSIGNAL		0x00000000	/*  CLEAR SIGNAL */
@@ -438,7 +438,6 @@
 						/*  tri-state. */
 #define EOS		     	0x00000001	/*  End of superframe. */
 
-
 /*  I2C configuration constants. */
 #define I2C_CLKSEL		0x0400
 /* I2C bit rate = PCIclk/480 = 68.75 KHz. */
@@ -729,7 +728,6 @@
 #define STDMSK_CLKMULT		((uint16_t)(3 << STDBIT_CLKMULT))
 #define STDMSK_CLKENAB		((uint16_t)(1 << STDBIT_CLKENAB))
 
-
 /* typedef struct indexCounter */
 /* { */
 /*   unsigned int ao; */
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index db18b11..a219679 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -52,7 +52,7 @@ struct serial2002_board {
 
 static const struct serial2002_board serial2002_boards[] = {
 	{
-	.name = "serial2002"}
+	 .name = "serial2002"}
 };
 
 /*
@@ -67,7 +67,6 @@ struct serial2002_range_table_t {
 	struct comedi_krange range;
 };
 
-
 struct serial2002_private {
 
 	int port;		/*  /dev/ttyS<port> */
@@ -82,14 +81,14 @@ struct serial2002_private {
 	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_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",
@@ -101,16 +100,21 @@ struct comedi_driver driver_serial2002 = {
 	.num_names = ARRAY_SIZE(serial2002_boards),
 };
 
-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);
+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;
@@ -184,28 +188,28 @@ static int tty_read(struct file *f, int timeout)
 
 				mask = f->f_op->poll(f, &table.pt);
 				if (mask & (POLLRDNORM | POLLRDBAND | POLLIN |
-						POLLHUP | POLLERR)) {
+					    POLLHUP | POLLERR)) {
 					break;
 				}
 				do_gettimeofday(&now);
 				elapsed =
-					(1000000 * (now.tv_sec - start.tv_sec) +
-					now.tv_usec - start.tv_usec);
+				    (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);
+						   elapsed) * HZ) / 10000);
 			}
 			poll_freewait(&table);
 			{
-			  unsigned char ch;
+				unsigned char ch;
 
-			  f->f_pos = 0;
-			  if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
-			    result = 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 */
@@ -348,8 +352,7 @@ static struct serial_data serial_read(struct file *f, int timeout)
 				}
 			} else {
 				result.value =
-					(result.
-					value << 2) | ((data & 0x60) >> 5);
+				    (result.value << 2) | ((data & 0x60) >> 5);
 				result.kind = is_channel;
 			}
 			result.index = data & 0x1f;
@@ -364,7 +367,7 @@ 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);
+		    ((data.value << 5) & 0x20) | (data.index & 0x1f);
 		tty_write(f, &ch, 1);
 	} else {
 		unsigned char ch[6];
@@ -401,7 +404,7 @@ static void serial_2002_open(struct comedi_device *dev)
 	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));
+		       PTR_ERR(devpriv->tty));
 	} else {
 		struct config_t {
 
@@ -443,7 +446,7 @@ static void serial_2002_open(struct comedi_device *dev)
 
 			data = serial_read(devpriv->tty, 1000);
 			if (data.kind != is_channel || data.index != 31
-				|| !(data.value & 0xe0)) {
+			    || !(data.value & 0xe0)) {
 				break;
 			} else {
 				int command, channel, kind;
@@ -479,77 +482,92 @@ static void serial_2002_open(struct comedi_device *dev)
 					cur_config[channel].kind = kind;
 					switch (command) {
 					case 0:{
-							cur_config[channel].
-								bits =
-								(data.
-								value >> 10) &
-								0x3f;
+							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;
+							unit =
+							    (data.value >> 10) &
+							    0x7;
+							sign =
+							    (data.value >> 13) &
+							    0x1;
+							min =
+							    (data.value >> 14) &
+							    0xfffff;
 
 							switch (unit) {
 							case 0:{
-									min = min * 1000000;
+									min =
+									    min
+									    *
+									    1000000;
 								}
 								break;
 							case 1:{
-									min = min * 1000;
+									min =
+									    min
+									    *
+									    1000;
 								}
 								break;
 							case 2:{
-									min = min * 1;
+									min =
+									    min
+									    * 1;
 								}
 								break;
 							}
 							if (sign) {
 								min = -min;
 							}
-							cur_config[channel].
-								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;
+							unit =
+							    (data.value >> 10) &
+							    0x7;
+							sign =
+							    (data.value >> 13) &
+							    0x1;
+							max =
+							    (data.value >> 14) &
+							    0xfffff;
 
 							switch (unit) {
 							case 0:{
-									max = max * 1000000;
+									max =
+									    max
+									    *
+									    1000000;
 								}
 								break;
 							case 1:{
-									max = max * 1000;
+									max =
+									    max
+									    *
+									    1000;
 								}
 								break;
 							case 2:{
-									max = max * 1;
+									max =
+									    max
+									    * 1;
 								}
 								break;
 							}
 							if (sign) {
 								max = -max;
 							}
-							cur_config[channel].
-								max = max;
+							cur_config[channel].max
+							    = max;
 						}
 						break;
 					}
@@ -604,7 +622,8 @@ static void serial_2002_open(struct comedi_device *dev)
 			}
 			if (c) {
 				struct comedi_subdevice *s;
-				const struct comedi_lrange **range_table_list = NULL;
+				const struct comedi_lrange **range_table_list =
+				    NULL;
 				unsigned int *maxdata_list;
 				int j, chan;
 
@@ -620,17 +639,18 @@ static void serial_2002_open(struct comedi_device *dev)
 					kfree(s->maxdata_list);
 				}
 				s->maxdata_list = maxdata_list =
-					kmalloc(sizeof(unsigned int) * s->n_chan,
-					GFP_KERNEL);
+				    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);
+					    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) {
@@ -640,17 +660,17 @@ static void serial_2002_open(struct comedi_device *dev)
 						if (range) {
 							range[j].length = 1;
 							range[j].range.min =
-								c[j].min;
+							    c[j].min;
 							range[j].range.max =
-								c[j].max;
+							    c[j].max;
 							range_table_list[chan] =
-								(const struct
-								comedi_lrange *)
-								&range[j];
+							    (const struct
+							     comedi_lrange *)
+							    &range[j];
 						}
 						maxdata_list[chan] =
-							((long long)1 << c[j].
-							bits) - 1;
+						    ((long long)1 << c[j].bits)
+						    - 1;
 						chan++;
 					}
 				}
@@ -666,8 +686,9 @@ static void serial_2002_close(struct comedi_device *dev)
 	}
 }
 
-static int serial2002_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int serial2002_di_rinsn(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	int chan;
@@ -688,8 +709,9 @@ static int serial2002_di_rinsn(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int serial2002_do_winsn(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)
 {
 	int n;
 	int chan;
@@ -706,8 +728,9 @@ static int serial2002_do_winsn(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int serial2002_ai_rinsn(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)
 {
 	int n;
 	int chan;
@@ -728,8 +751,9 @@ static int serial2002_ai_rinsn(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int serial2002_ao_winsn(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)
 {
 	int n;
 	int chan;
@@ -747,8 +771,9 @@ static int serial2002_ao_winsn(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int serial2002_ao_rinsn(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)
 {
 	int n;
 	int chan = CR_CHAN(insn->chanspec);
@@ -760,8 +785,9 @@ static int serial2002_ao_rinsn(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int serial2002_ei_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+static int serial2002_ei_rinsn(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 	int n;
 	int chan;
@@ -782,7 +808,8 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, struct comedi_subdevic
 	return n;
 }
 
-static int serial2002_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int serial2002_attach(struct comedi_device *dev,
+			     struct comedi_devconfig *it)
 {
 	struct comedi_subdevice *s;
 
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
index 07f580a..3dee62a 100644
--- a/drivers/staging/comedi/drivers/skel.c
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -97,17 +97,17 @@ struct skel_board {
 
 static const struct skel_board skel_boards[] = {
 	{
-	.name = "skel-100",
-	.ai_chans = 16,
-	.ai_bits = 12,
-	.have_dio = 1,
-		},
+	 .name = "skel-100",
+	 .ai_chans = 16,
+	 .ai_bits = 12,
+	 .have_dio = 1,
+	 },
 	{
-	.name = "skel-200",
-	.ai_chans = 8,
-	.ai_bits = 16,
-	.have_dio = 0,
-		},
+	 .name = "skel-200",
+	 .ai_chans = 8,
+	 .ai_bits = 16,
+	 .have_dio = 0,
+	 },
 };
 
 /* This is used by modprobe to translate PCI IDs to drivers.  Should
@@ -116,9 +116,10 @@ static const struct skel_board skel_boards[] = {
  * 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}
+	{
+	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);
@@ -185,17 +186,19 @@ static struct comedi_driver driver_skel = {
 };
 
 static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data);
+			 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);
+			 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);
+			 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);
 
 /*
@@ -304,7 +307,7 @@ static int skel_detach(struct comedi_device *dev)
  * mode.
  */
 static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int n, i;
 	unsigned int d;
@@ -351,8 +354,8 @@ static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	return n;
 }
 
-static int skel_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_cmd *cmd)
+static int skel_ai_cmdtest(struct comedi_device *dev,
+			   struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
 	int err = 0;
 	int tmp;
@@ -398,7 +401,7 @@ static int skel_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 
 	/* note that mutual compatiblity is not an issue here */
 	if (cmd->scan_begin_src != TRIG_TIMER &&
-		cmd->scan_begin_src != TRIG_EXT)
+	    cmd->scan_begin_src != TRIG_EXT)
 		err++;
 	if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
 		err++;
@@ -478,21 +481,21 @@ static int skel_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
 	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);
+				 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);
+				 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) {
 			cmd->scan_begin_arg =
-				cmd->convert_arg * cmd->scan_end_arg;
+			    cmd->convert_arg * cmd->scan_end_arg;
 			err++;
 		}
 	}
@@ -521,7 +524,7 @@ static int skel_ns_to_timer(unsigned int *ns, int round)
 }
 
 static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
-	struct comedi_insn *insn, unsigned int *data)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -542,7 +545,7 @@ static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 /* 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)
+			 struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
 	int chan = CR_CHAN(insn->chanspec);
@@ -558,8 +561,9 @@ static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
  * 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)
+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;
@@ -583,8 +587,9 @@ static int skel_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
 	return 2;
 }
 
-static int skel_dio_insn_config(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)
 {
 	int chan = CR_CHAN(insn->chanspec);
 
@@ -601,8 +606,7 @@ static int skel_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
index 13c29bb..4918fbf 100644
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -61,11 +61,11 @@ struct dnp_board {
 
 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,
-		},
+	 .name = "dnp-1486",
+	 .ai_chans = 16,
+	 .ai_bits = 12,
+	 .have_dio = 1,
+	 },
 };
 
 /* Useful for shorthand access to the particular board structure ----------- */
@@ -76,7 +76,6 @@ struct dnp_private_data {
 
 };
 
-
 /* Shorthand macro for faster access to the private data ------------------- */
 #define devpriv ((dnp_private *)dev->private)
 
@@ -98,17 +97,19 @@ static struct comedi_driver driver_dnp = {
 	.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.      */
+	.offset = sizeof(struct dnp_board),	/* like ISA-PnP, PCI or PCMCIA.      */
 	.num_names = ARRAY_SIZE(dnp_boards),
 };
 
 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);
+			     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);
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data);
 
 /* ------------------------------------------------------------------------- */
 /* Attach is called by comedi core to configure the driver for a particular  */
@@ -202,7 +203,8 @@ static int dnp_detach(struct comedi_device *dev)
 /* ------------------------------------------------------------------------- */
 
 static int dnp_dio_insn_bits(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			     struct comedi_subdevice *s,
+			     struct comedi_insn *insn, unsigned int *data)
 {
 
 	if (insn->n != 2)
@@ -219,18 +221,18 @@ static int dnp_dio_insn_bits(struct comedi_device *dev,
 
 		outb(PADR, CSCIR);
 		outb((inb(CSCDR)
-				& ~(u8) (data[0] & 0x0000FF))
-			| (u8) (data[1] & 0x0000FF), 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);
+		      & ~(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);
+		      & ~(u8) ((data[0] & 0x0F0000) >> 12))
+		     | (u8) ((data[1] & 0x0F0000) >> 12), CSCDR);
 	}
 
 	/* on return, data[1] contains the value of the digital input lines.       */
@@ -252,7 +254,8 @@ static int dnp_dio_insn_bits(struct comedi_device *dev,
 /* ------------------------------------------------------------------------- */
 
 static int dnp_dio_insn_config(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
+			       struct comedi_subdevice *s,
+			       struct comedi_insn *insn, unsigned int *data)
 {
 
 	u8 register_buffer;
@@ -265,8 +268,7 @@ static int dnp_dio_insn_config(struct comedi_device *dev,
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT :
-			COMEDI_INPUT;
+		    (inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		return insn->n;
 		break;
 	default:
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
index 96bb15c..75a9a62 100644
--- a/drivers/staging/comedi/drivers/unioxx5.c
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -80,25 +80,29 @@ struct unioxx5_subd_priv {
 	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_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 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_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);
 
@@ -111,7 +115,8 @@ static struct comedi_driver unioxx5_driver = {
 
 COMEDI_INITCLEANUP(unioxx5_driver);
 
-static int unioxx5_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int unioxx5_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
 {
 	int iobase, i, n_subd;
 	int id, num, ba;
@@ -136,7 +141,7 @@ static int unioxx5_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	/* 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");
+		       "your card must has at least 2 'g01' subdevices\n");
 		return -1;
 	}
 
@@ -148,7 +153,7 @@ static int unioxx5_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	/* 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)
+					  dev->minor) < 0)
 			return -1;
 	}
 
@@ -156,8 +161,9 @@ static int unioxx5_attach(struct comedi_device *dev, struct comedi_devconfig *it
 	return 0;
 }
 
-static int unioxx5_subdev_read(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)
 {
 	struct unioxx5_subd_priv *usp = subdev->private;
 	int channel, type;
@@ -176,8 +182,9 @@ static int unioxx5_subdev_read(struct comedi_device *dev, struct comedi_subdevic
 	return 1;
 }
 
-static int unioxx5_subdev_write(struct comedi_device *dev, struct comedi_subdevice *subdev,
-	struct comedi_insn *insn, unsigned int *data)
+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;
@@ -197,8 +204,9 @@ static int unioxx5_subdev_write(struct comedi_device *dev, struct comedi_subdevi
 }
 
 /* for digital modules only */
-static int unioxx5_insn_config(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)
 {
 	int channel_offset, flags, channel = CR_CHAN(insn->chanspec), type;
 	struct unioxx5_subd_priv *usp = subdev->private;
@@ -208,16 +216,16 @@ static int unioxx5_insn_config(struct comedi_device *dev, struct comedi_subdevic
 
 	if (type != MODULE_DIGITAL) {
 		printk(KERN_ERR
-			"comedi%d: channel configuration accessible only for digital modules\n",
-			dev->minor);
+		       "comedi%d: channel configuration accessible only for digital modules\n",
+		       dev->minor);
 		return -1;
 	}
 
 	channel_offset = __unioxx5_define_chan_offset(channel);
 	if (channel_offset < 0) {
 		printk(KERN_ERR
-			"comedi%d: undefined channel %d. channel range is 0 .. 23\n",
-			dev->minor, channel);
+		       "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+		       dev->minor, channel);
 		return -1;
 	}
 
@@ -265,8 +273,8 @@ static int unioxx5_detach(struct comedi_device *dev)
 }
 
 /* initializing subdevice with given address */
-static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, int subdev_iobase,
-	int minor)
+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;
@@ -276,7 +284,7 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, int subdev_iob
 		return -EIO;
 	}
 
-	usp = (struct unioxx5_subd_priv *) kzalloc(sizeof(*usp), GFP_KERNEL);
+	usp = (struct unioxx5_subd_priv *)kzalloc(sizeof(*usp), GFP_KERNEL);
 
 	if (usp == NULL) {
 		printk(KERN_ERR "comedi%d: erorr! --> out of memory!\n", minor);
@@ -332,8 +340,8 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, int subdev_iob
 	return 0;
 }
 
-static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, unsigned int *data,
-	int channel, int minor)
+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);
@@ -341,8 +349,8 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, unsigned int *
 	channel_offset = __unioxx5_define_chan_offset(channel);
 	if (channel_offset < 0) {
 		printk(KERN_ERR
-			"comedi%d: undefined channel %d. channel range is 0 .. 23\n",
-			minor, channel);
+		       "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+		       minor, channel);
 		return 0;
 	}
 
@@ -360,16 +368,16 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, unsigned int *
 }
 
 /* function for digital reading */
-static int __unioxx5_digital_read(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)
 {
 	int channel_offset, mask = 1 << (channel & 0x07);
 
 	channel_offset = __unioxx5_define_chan_offset(channel);
 	if (channel_offset < 0) {
 		printk(KERN_ERR
-			"comedi%d: undefined channel %d. channel range is 0 .. 23\n",
-			minor, channel);
+		       "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+		       minor, channel);
 		return 0;
 	}
 
@@ -400,8 +408,8 @@ static void __unioxx5_digital_config(struct unioxx5_subd_priv *usp, int mode)
 }
 #endif
 
-static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, unsigned int *data,
-	int channel, int minor)
+static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp,
+				  unsigned int *data, int channel, int minor)
 {
 	int module, i;
 
@@ -411,8 +419,8 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, unsigned int *d
 	/* 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]);
+		       "comedi%d: module in position %d with id 0x%0x is for input only!\n",
+		       minor, module, usp->usp_module_type[module]);
 		return 0;
 	}
 
@@ -435,8 +443,8 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, unsigned int *d
 	return 1;
 }
 
-static int __unioxx5_analog_read(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)
 {
 	int module_no, read_ch;
 	char control;
@@ -447,8 +455,8 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, unsigned int *da
 	/* 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]);
+		       "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;
 	}
 
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 171a6f2..cca4e86 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -215,17 +215,23 @@ sampling rate. If you sample two channels you get 4kHz and so on.
 /**************************************************/
 /* comedi constants */
 static const struct comedi_lrange range_usbdux_ai_range = { 4, {
-			BIP_RANGE(4.096),
-			BIP_RANGE(4.096 / 2),
-			UNI_RANGE(4.096),
-			UNI_RANGE(4.096 / 2)
-	}
+								BIP_RANGE
+								(4.096),
+								BIP_RANGE(4.096
+									  / 2),
+								UNI_RANGE
+								(4.096),
+								UNI_RANGE(4.096
+									  / 2)
+								}
 };
 
 static const struct comedi_lrange range_usbdux_ao_range = { 2, {
-			BIP_RANGE(4.096),
-			UNI_RANGE(4.096),
-	}
+								BIP_RANGE
+								(4.096),
+								UNI_RANGE
+								(4.096),
+								}
 };
 
 /*
@@ -363,7 +369,8 @@ static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
  * This will cancel a running acquisition operation.
  * This is called by comedi but never from inside the driver.
  */
-static int usbdux_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+static int usbdux_ai_cancel(struct comedi_device *dev,
+			    struct comedi_subdevice *s)
 {
 	struct usbduxsub *this_usbduxsub;
 	int res = 0;
@@ -407,7 +414,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
 	case 0:
 		/* copy the result in the transfer buffer */
 		memcpy(this_usbduxsub->inBuffer,
-			urb->transfer_buffer, SIZEINBUF);
+		       urb->transfer_buffer, SIZEINBUF);
 		break;
 	case -EILSEQ:
 		/* error in the ISOchronous data */
@@ -510,13 +517,12 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
 		/* transfer data */
 		if (CR_RANGE(s->async->cmd.chanlist[i]) <= 1) {
 			err = comedi_buf_put
-				(s->async,
-				 le16_to_cpu(this_usbduxsub->
-					     inBuffer[i]) ^ 0x800);
+			    (s->async,
+			     le16_to_cpu(this_usbduxsub->inBuffer[i]) ^ 0x800);
 		} else {
 			err = comedi_buf_put
-				(s->async,
-				 le16_to_cpu(this_usbduxsub->inBuffer[i]));
+			    (s->async,
+			     le16_to_cpu(this_usbduxsub->inBuffer[i]));
 		}
 		if (unlikely(err == 0)) {
 			/* buffer overflow */
@@ -566,7 +572,8 @@ static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
 }
 
 /* force unlink, is called by comedi */
-static int usbdux_ao_cancel(struct comedi_device *dev, struct 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;
@@ -659,7 +666,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
 		}
 		/* transmit data to the USB bus */
 		((uint8_t *) (urb->transfer_buffer))[0] =
-			s->async->cmd.chanlist_len;
+		    s->async->cmd.chanlist_len;
 		for (i = 0; i < s->async->cmd.chanlist_len; i++) {
 			short temp;
 			if (i >= NUMOUTCHANNELS)
@@ -667,7 +674,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
 
 			/* pointer to the DA */
 			datap =
-			       (&(((int8_t *)urb->transfer_buffer)[i * 3 + 1]));
+			    (&(((int8_t *) urb->transfer_buffer)[i * 3 + 1]));
 			/* get the data from comedi */
 			ret = comedi_buf_get(s->async, &temp);
 			datap[0] = temp;
@@ -783,32 +790,30 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
 }
 
 static int usbduxsub_upload(struct usbduxsub *usbduxsub,
-			    uint8_t *local_transfer_buffer,
+			    uint8_t * local_transfer_buffer,
 			    unsigned int startAddr, unsigned int len)
 {
 	int errcode;
 
 	errcode = usb_control_msg(usbduxsub->usbdev,
-			usb_sndctrlpipe(usbduxsub->usbdev, 0),
-			/* brequest, firmware */
-			USBDUXSUB_FIRMWARE,
-			/* bmRequestType */
-			VENDOR_DIR_OUT,
-			/* value */
-			startAddr,
-			/* index */
-			0x0000,
-			/* our local safe buffer */
-			local_transfer_buffer,
-			/* length */
-			len,
-			/* timeout */
-			EZTIMEOUT);
-	dev_dbg(&usbduxsub->interface->dev,
-		"comedi_: result=%d\n", errcode);
+				  usb_sndctrlpipe(usbduxsub->usbdev, 0),
+				  /* brequest, firmware */
+				  USBDUXSUB_FIRMWARE,
+				  /* bmRequestType */
+				  VENDOR_DIR_OUT,
+				  /* value */
+				  startAddr,
+				  /* index */
+				  0x0000,
+				  /* our local safe buffer */
+				  local_transfer_buffer,
+				  /* length */
+				  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");
+		dev_err(&usbduxsub->interface->dev, "comedi_: upload failed\n");
 		return errcode;
 	}
 	return 0;
@@ -817,8 +822,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
 #define FIRMWARE_MAX_LEN 0x2000
 
 static int firmwareUpload(struct usbduxsub *usbduxsub,
-			  const u8 *firmwareBinary,
-			  int sizeFirmware)
+			  const u8 * firmwareBinary, int sizeFirmware)
 {
 	int ret;
 	uint8_t *fwBuf;
@@ -826,7 +830,7 @@ static int firmwareUpload(struct usbduxsub *usbduxsub,
 	if (!firmwareBinary)
 		return 0;
 
-	if (sizeFirmware>FIRMWARE_MAX_LEN) {
+	if (sizeFirmware > FIRMWARE_MAX_LEN) {
 		dev_err(&usbduxsub->interface->dev,
 			"comedi_: usbdux firmware binary it too large for FX2.\n");
 		return -ENOMEM;
@@ -839,7 +843,7 @@ static int firmwareUpload(struct usbduxsub *usbduxsub,
 			"comedi_: mem alloc for firmware failed\n");
 		return -ENOMEM;
 	}
-	memcpy(fwBuf,firmwareBinary,sizeFirmware);
+	memcpy(fwBuf, firmwareBinary, sizeFirmware);
 
 	ret = usbduxsub_stop(usbduxsub);
 	if (ret < 0) {
@@ -925,8 +929,8 @@ static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
 	return 0;
 }
 
-static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-			     struct 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;
@@ -978,8 +982,8 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	 * 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)
+	    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++;
@@ -1021,8 +1025,8 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 			/* now calc the real sampling rate with all the
 			 * rounding errors */
 			tmpTimer =
-				((unsigned int)(cmd->scan_begin_arg / 125000)) *
-				125000;
+			    ((unsigned int)(cmd->scan_begin_arg / 125000)) *
+			    125000;
 			if (cmd->scan_begin_arg != tmpTimer) {
 				cmd->scan_begin_arg = tmpTimer;
 				err++;
@@ -1038,7 +1042,7 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 			 * calc the real sampling rate with the rounding errors
 			 */
 			tmpTimer = ((unsigned int)(cmd->scan_begin_arg /
-					1000000)) * 1000000;
+						   1000000)) * 1000000;
 			if (cmd->scan_begin_arg != tmpTimer) {
 				cmd->scan_begin_arg = tmpTimer;
 				err++;
@@ -1097,7 +1101,7 @@ static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type)
 	this_usbduxsub->dux_commands[0] = cmd_type;
 #ifdef NOISY_DUX_DEBUGBUG
 	printk(KERN_DEBUG "comedi%d: usbdux: dux_commands: ",
-		this_usbduxsub->comedidev->minor);
+	       this_usbduxsub->comedidev->minor);
 	for (result = 0; result < SIZEOFDUXBUFFER; result++)
 		printk(" %02x", this_usbduxsub->dux_commands[result]);
 	printk("\n");
@@ -1145,8 +1149,8 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
 	return -EFAULT;
 }
 
-static int usbdux_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-			     unsigned int trignum)
+static int usbdux_ai_inttrig(struct comedi_device *dev,
+			     struct comedi_subdevice *s, unsigned int trignum)
 {
 	int ret;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1231,7 +1235,7 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 			break;
 		}
 		this_usbduxsub->dux_commands[i + 2] =
-			create_adc_command(chan, range);
+		    create_adc_command(chan, range);
 	}
 
 	dev_dbg(&this_usbduxsub->interface->dev,
@@ -1254,10 +1258,11 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		/* find a power of 2 for the interval */
 		while ((this_usbduxsub->ai_interval) < (cmd->chanlist_len)) {
 			this_usbduxsub->ai_interval =
-				(this_usbduxsub->ai_interval) * 2;
+			    (this_usbduxsub->ai_interval) * 2;
 		}
 		this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
-			(this_usbduxsub->ai_interval));
+								  (this_usbduxsub->
+								   ai_interval));
 	} else {
 		/* interval always 1ms */
 		this_usbduxsub->ai_interval = 1;
@@ -1305,7 +1310,8 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 }
 
 /* Mode 0 is used to get a single conversion on demand */
-static int usbdux_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+static int usbdux_ai_insn_read(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
 			       struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
@@ -1366,7 +1372,8 @@ static int usbdux_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
 /************************************/
 /* analog out */
 
-static int usbdux_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+static int usbdux_ao_insn_read(struct comedi_device *dev,
+			       struct comedi_subdevice *s,
 			       struct comedi_insn *insn, unsigned int *data)
 {
 	int i;
@@ -1388,7 +1395,8 @@ static int usbdux_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
 	return i;
 }
 
-static int usbdux_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+static int usbdux_ao_insn_write(struct comedi_device *dev,
+				struct comedi_subdevice *s,
 				struct comedi_insn *insn, unsigned int *data)
 {
 	int i, err;
@@ -1423,7 +1431,7 @@ static int usbdux_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 		this_usbduxsub->dux_commands[1] = 1;
 		/* one 16 bit value */
 		*((int16_t *) (this_usbduxsub->dux_commands + 2)) =
-			cpu_to_le16(data[i]);
+		    cpu_to_le16(data[i]);
 		this_usbduxsub->outBuffer[chan] = data[i];
 		/* channel number */
 		this_usbduxsub->dux_commands[4] = (chan << 6);
@@ -1438,8 +1446,8 @@ static int usbdux_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
 	return i;
 }
 
-static int usbdux_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
-			     unsigned int trignum)
+static int usbdux_ao_inttrig(struct comedi_device *dev,
+			     struct comedi_subdevice *s, unsigned int trignum)
 {
 	int ret;
 	struct usbduxsub *this_usbduxsub = dev->private;
@@ -1479,8 +1487,8 @@ static int usbdux_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice
 	return 1;
 }
 
-static int usbdux_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
-			     struct 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;
@@ -1552,8 +1560,8 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
 	 * 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)
+	    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++;
@@ -1690,7 +1698,7 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		/* high speed also scans everything at once */
 		if (0) {	/* (this_usbduxsub->high_speed) */
 			this_usbduxsub->ao_sample_count =
-				(cmd->stop_arg) * (cmd->scan_end_arg);
+			    (cmd->stop_arg) * (cmd->scan_end_arg);
 		} else {
 			/* there's no scan as the scan has been */
 			/* perf inside the FX2 */
@@ -1726,7 +1734,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	return 0;
 }
 
-static int usbdux_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+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);
@@ -1745,8 +1754,7 @@ static int usbdux_dio_insn_config(struct comedi_device *dev, struct comedi_subde
 		break;
 	case INSN_CONFIG_DIO_QUERY:
 		data[1] =
-			(s->
-			io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+		    (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
 		break;
 	default:
 		return -EINVAL;
@@ -1757,7 +1765,8 @@ static int usbdux_dio_insn_config(struct comedi_device *dev, struct comedi_subde
 	return insn->n;
 }
 
-static int usbdux_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+static int usbdux_dio_insn_bits(struct comedi_device *dev,
+				struct comedi_subdevice *s,
 				struct comedi_insn *insn, unsigned int *data)
 {
 
@@ -1767,7 +1776,6 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 	if (!this_usbduxsub)
 		return -EFAULT;
 
-
 	if (insn->n != 2)
 		return -EINVAL;
 
@@ -1804,7 +1812,8 @@ static int usbdux_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
 }
 
 /* reads the 4 counters, only two are used just now */
-static int usbdux_counter_read(struct comedi_device *dev, struct comedi_subdevice *s,
+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;
@@ -1838,7 +1847,8 @@ static int usbdux_counter_read(struct comedi_device *dev, struct comedi_subdevic
 	return 1;
 }
 
-static int usbdux_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
+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;
@@ -1868,7 +1878,8 @@ static int usbdux_counter_write(struct comedi_device *dev, struct comedi_subdevi
 	return 1;
 }
 
-static int usbdux_counter_config(struct comedi_device *dev, struct comedi_subdevice *s,
+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 */
@@ -1905,14 +1916,14 @@ static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
 	if (do_unlink)
 		ret = usbduxsub_unlink_PwmURBs(this_usbduxsub);
 
-
 	this_usbduxsub->pwm_cmd_running = 0;
 
 	return ret;
 }
 
 /* force unlink - is called by comedi */
-static int usbdux_pwm_cancel(struct comedi_device *dev, struct 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;
@@ -2010,10 +2021,11 @@ static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
 
 	/* in case of a resubmission after an unlink... */
 	usb_fill_bulk_urb(usbduxsub->urbPwm,
-		usbduxsub->usbdev,
-		usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
-		usbduxsub->urbPwm->transfer_buffer,
-		usbduxsub->sizePwmBuf, usbduxsub_pwm_irq, usbduxsub->comedidev);
+			  usbduxsub->usbdev,
+			  usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP),
+			  usbduxsub->urbPwm->transfer_buffer,
+			  usbduxsub->sizePwmBuf, usbduxsub_pwm_irq,
+			  usbduxsub->comedidev);
 
 	errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC);
 	if (errFlag) {
@@ -2025,8 +2037,8 @@ static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
 	return 0;
 }
 
-static int usbdux_pwm_period(struct comedi_device *dev, struct comedi_subdevice *s,
-			     unsigned int 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;
@@ -2037,11 +2049,11 @@ static int usbdux_pwm_period(struct comedi_device *dev, struct comedi_subdevice
 			dev->minor);
 		return -EAGAIN;
 	} else {
-		fx2delay = period / ((int)(6*512*(1.0/0.033))) - 6;
+		fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6;
 		if (fx2delay > 255) {
 			dev_err(&this_usbduxsub->interface->dev,
 				"comedi%d: period %d for pwm is too low.\n",
-			       dev->minor, period);
+				dev->minor, period);
 			return -EAGAIN;
 		}
 	}
@@ -2053,7 +2065,8 @@ static int usbdux_pwm_period(struct comedi_device *dev, struct comedi_subdevice
 }
 
 /* is called from insn so there's no need to do all the sanity checks */
-static int usbdux_pwm_start(struct comedi_device *dev, struct 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;
@@ -2085,8 +2098,9 @@ static int usbdux_pwm_start(struct comedi_device *dev, struct comedi_subdevice *
 }
 
 /* generates the bit pattern for PWM with the optional sign bit */
-static int usbdux_pwm_pattern(struct comedi_device *dev, struct comedi_subdevice *s,
-			      int channel, unsigned int value, unsigned int 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;
@@ -2126,7 +2140,8 @@ static int usbdux_pwm_pattern(struct comedi_device *dev, struct comedi_subdevice
 	return 1;
 }
 
-static int usbdux_pwm_write(struct comedi_device *dev, struct comedi_subdevice *s,
+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;
@@ -2147,19 +2162,20 @@ static int usbdux_pwm_write(struct comedi_device *dev, struct comedi_subdevice *
 	 * normal operation
 	 * relay sign 0 by default
 	 */
-	return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec),
-				  data[0], 0);
+	return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0);
 }
 
-static int usbdux_pwm_read(struct comedi_device *x1, struct comedi_subdevice *x2,
-			   struct comedi_insn *x3, unsigned int *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(struct comedi_device *dev, struct comedi_subdevice *s,
+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;
@@ -2249,10 +2265,10 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
 		}
 		for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) {
 			if (usbduxsub_tmp->urbOut[i]->transfer_buffer) {
-				kfree(usbduxsub_tmp->urbOut[i]->
-					transfer_buffer);
+				kfree(usbduxsub_tmp->
+				      urbOut[i]->transfer_buffer);
 				usbduxsub_tmp->urbOut[i]->transfer_buffer =
-					NULL;
+				    NULL;
 			}
 			if (usbduxsub_tmp->urbOut[i]) {
 				usb_kill_urb(usbduxsub_tmp->urbOut[i]);
@@ -2310,8 +2326,7 @@ static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
 
 	if (ret) {
 		dev_err(&usbdev->dev,
-			"Could not upload firmware (err=%d)\n",
-			ret);
+			"Could not upload firmware (err=%d)\n", ret);
 		return;
 	}
 	comedi_usb_auto_config(usbdev, BOARDNAME);
@@ -2365,7 +2380,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 
 	/* test if it is high speed (USB 2.0) */
 	usbduxsub[index].high_speed =
-		(usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
+	    (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH);
 
 	/* create space for the commands of the DA converter */
 	usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL);
@@ -2429,8 +2444,8 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 		usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL;
 
 	usbduxsub[index].urbIn =
-		kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers,
-		GFP_KERNEL);
+	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers,
+		    GFP_KERNEL);
 	if (!(usbduxsub[index].urbIn)) {
 		dev_err(dev, "comedi_: usbdux: Could not alloc. urbIn array\n");
 		tidy_up(&(usbduxsub[index]));
@@ -2452,10 +2467,10 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 		/* and ONLY then the urb should be submitted */
 		usbduxsub[index].urbIn[i]->context = NULL;
 		usbduxsub[index].urbIn[i]->pipe =
-			usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
+		    usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP);
 		usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP;
 		usbduxsub[index].urbIn[i]->transfer_buffer =
-			kzalloc(SIZEINBUF, GFP_KERNEL);
+		    kzalloc(SIZEINBUF, GFP_KERNEL);
 		if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) {
 			dev_err(dev, "comedi_: usbdux%d: "
 				"could not alloc. transb.\n", index);
@@ -2477,8 +2492,8 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 		usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL;
 
 	usbduxsub[index].urbOut =
-		kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers,
-		GFP_KERNEL);
+	    kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers,
+		    GFP_KERNEL);
 	if (!(usbduxsub[index].urbOut)) {
 		dev_err(dev, "comedi_: usbdux: "
 			"Could not alloc. urbOut array\n");
@@ -2501,10 +2516,10 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 		/* and ONLY then the urb should be submitted */
 		usbduxsub[index].urbOut[i]->context = NULL;
 		usbduxsub[index].urbOut[i]->pipe =
-			usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
+		    usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP);
 		usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP;
 		usbduxsub[index].urbOut[i]->transfer_buffer =
-			kzalloc(SIZEOUTBUF, GFP_KERNEL);
+		    kzalloc(SIZEOUTBUF, GFP_KERNEL);
 		if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) {
 			dev_err(dev, "comedi_: usbdux%d: "
 				"could not alloc. transb.\n", index);
@@ -2517,7 +2532,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 		usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF;
 		usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0;
 		usbduxsub[index].urbOut[i]->iso_frame_desc[0].length =
-			SIZEOUTBUF;
+		    SIZEOUTBUF;
 		if (usbduxsub[index].high_speed) {
 			/* uframes */
 			usbduxsub[index].urbOut[i]->interval = 8;
@@ -2540,7 +2555,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 			return -ENOMEM;
 		}
 		usbduxsub[index].urbPwm->transfer_buffer =
-			kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
+		    kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL);
 		if (!(usbduxsub[index].urbPwm->transfer_buffer)) {
 			dev_err(dev, "comedi_: usbdux%d: "
 				"could not alloc. transb. for pwm\n", index);
@@ -2568,8 +2583,6 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
 				      usbduxsub + index,
 				      usbdux_firmware_request_complete_handler);
 
-
-
 	if (ret) {
 		dev_err(dev, "Could not load firmware (err=%d)\n", ret);
 		return ret;
@@ -2592,8 +2605,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf)
 		return;
 	}
 	if (usbduxsub_tmp->usbdev != udev) {
-		dev_err(&intf->dev,
-			"comedi_: BUG! called with wrong ptr!!!\n");
+		dev_err(&intf->dev, "comedi_: BUG! called with wrong ptr!!!\n");
 		return;
 	}
 	comedi_usb_auto_unconfig(udev);
@@ -2641,7 +2653,7 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	/* trying to upload the firmware into the chip */
 	if (comedi_aux_data(it->options, 0) &&
-		it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
+	    it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
 		firmwareUpload(udev, comedi_aux_data(it->options, 0),
 			       it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
 	}
@@ -2667,8 +2679,8 @@ static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 	}
 
 	dev_info(&udev->interface->dev,
-		"comedi%d: usb-device %d is attached to comedi.\n",
-		dev->minor, index);
+		 "comedi%d: usb-device %d is attached to comedi.\n",
+		 dev->minor, index);
 	/* private structure is also simply the usb-structure */
 	dev->private = udev;
 
@@ -2779,14 +2791,14 @@ static int usbdux_detach(struct comedi_device *dev)
 
 	if (!dev) {
 		printk(KERN_ERR
-			"comedi?: usbdux: detach without dev variable...\n");
+		       "comedi?: usbdux: detach without dev variable...\n");
 		return -EFAULT;
 	}
 
 	usbduxsub_tmp = dev->private;
 	if (!usbduxsub_tmp) {
 		printk(KERN_ERR
-			"comedi?: usbdux: detach without ptr to usbduxsub[]\n");
+		       "comedi?: usbdux: detach without ptr to usbduxsub[]\n");
 		return -EFAULT;
 	}
 
@@ -2807,16 +2819,16 @@ static int usbdux_detach(struct comedi_device *dev)
 
 /* main driver struct */
 static struct comedi_driver driver_usbdux = {
-      .driver_name =	"usbdux",
-      .module =		THIS_MODULE,
-      .attach =		usbdux_attach,
-      .detach =		usbdux_detach,
+	.driver_name = "usbdux",
+	.module = THIS_MODULE,
+	.attach = usbdux_attach,
+	.detach = usbdux_detach,
 };
 
 /* Table with the USB-devices: just now only testing IDs */
 static struct usb_device_id usbduxsub_table[] = {
-	{USB_DEVICE(0x13d8, 0x0001) },
-	{USB_DEVICE(0x13d8, 0x0002) },
+	{USB_DEVICE(0x13d8, 0x0001)},
+	{USB_DEVICE(0x13d8, 0x0002)},
 	{}			/* Terminating entry */
 };
 
@@ -2824,10 +2836,10 @@ MODULE_DEVICE_TABLE(usb, usbduxsub_table);
 
 /* The usbduxsub-driver */
 static struct usb_driver usbduxsub_driver = {
-      .name =		BOARDNAME,
-      .probe =		usbduxsub_probe,
-      .disconnect =	usbduxsub_disconnect,
-      .id_table =	usbduxsub_table,
+	.name = BOARDNAME,
+	.probe = usbduxsub_probe,
+	.disconnect = usbduxsub_disconnect,
+	.id_table = usbduxsub_table,
 };
 
 /* Can't use the nice macro as I have also to initialise the USB */
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 939b53f..d143222 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -50,7 +50,6 @@
 #include "comedi_fc.h"
 #include "../comedidev.h"
 
-
 #define DRIVER_VERSION "v1.0"
 #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
 #define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
@@ -161,7 +160,7 @@
  * comedi constants
  */
 static const struct comedi_lrange range_usbduxfast_ai_range = {
-	2, { BIP_RANGE(0.75), BIP_RANGE(0.5) }
+	2, {BIP_RANGE(0.75), BIP_RANGE(0.5)}
 };
 
 /*
@@ -171,22 +170,22 @@ static const struct comedi_lrange range_usbduxfast_ai_range = {
  * one sub device just now: A/D
  */
 struct usbduxfastsub_s {
-	int attached;			/* is attached? */
-	int probed;			/* is it associated with a subdevice? */
+	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 */
+	struct urb *urbIn;	/* BULK-transfer handling: urb */
 	int8_t *transfer_buffer;
-	int16_t *insnBuffer;		/* input buffer for single insn */
-	int ifnum;			/* interface number */
+	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 */
+						   context */
 	short int ai_cmd_running;	/* asynchronous command is running */
-	short int ai_continous;		/* continous aquisition */
+	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 */
+	uint8_t *dux_commands;	/* commands */
+	int ignore;		/* counter which ignores the first
+				   buffers */
 	struct semaphore sem;
 };
 
@@ -217,7 +216,7 @@ static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
 
 #ifdef CONFIG_COMEDI_DEBUG
 	printk(KERN_DEBUG "comedi%d: usbduxfast: dux_commands: ",
-		udfs->comedidev->minor);
+	       udfs->comedidev->minor);
 	for (tmp = 0; tmp < SIZEOFDUXBUFFER; tmp++)
 		printk(" %02x", udfs->dux_commands[tmp]);
 	printk("\n");
@@ -228,7 +227,7 @@ static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
 			   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);
+		       "the usb-device, err=%d\n", udfs->comedidev->minor, tmp);
 	return tmp;
 }
 
@@ -258,8 +257,7 @@ static int usbduxfastsub_unlink_InURBs(struct usbduxfastsub_s *udfs)
  * 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)
+static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink)
 {
 	int ret = 0;
 
@@ -267,7 +265,6 @@ static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs,
 		printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n");
 		return -EFAULT;
 	}
-
 #ifdef CONFIG_COMEDI_DEBUG
 	printk(KERN_DEBUG "comedi: usbduxfast_ai_stop\n");
 #endif
@@ -275,7 +272,7 @@ static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs,
 	udfs->ai_cmd_running = 0;
 
 	if (do_unlink)
-		ret = usbduxfastsub_unlink_InURBs(udfs); /* stop aquistion */
+		ret = usbduxfastsub_unlink_InURBs(udfs);	/* stop aquistion */
 
 	return ret;
 }
@@ -284,7 +281,8 @@ static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs,
  * 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)
+static int usbduxfast_ai_cancel(struct comedi_device *dev,
+				struct comedi_subdevice *s)
 {
 	struct usbduxfastsub_s *udfs;
 	int ret;
@@ -402,9 +400,9 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
 				 * received
 				 */
 				cfc_write_array_to_buffer(s,
-					urb->transfer_buffer,
-					udfs->ai_sample_count
-					* sizeof(uint16_t));
+							  urb->transfer_buffer,
+							  udfs->ai_sample_count
+							  * sizeof(uint16_t));
 				usbduxfast_ai_stop(udfs, 0);
 				/* tell comedi that the acquistion is over */
 				s->async->events |= COMEDI_CB_EOA;
@@ -439,7 +437,7 @@ static void usbduxfastsub_ai_Irq(struct urb *urb)
 	err = usb_submit_urb(urb, GFP_ATOMIC);
 	if (err < 0) {
 		printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d",
-			udfs->comedidev->minor, err);
+		       udfs->comedidev->minor, err);
 		s->async->events |= COMEDI_CB_EOA;
 		s->async->events |= COMEDI_CB_ERROR;
 		comedi_event(udfs->comedidev, s);
@@ -454,15 +452,13 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
 
 	/* 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 */
+	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;
@@ -478,15 +474,12 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
 
 	/* 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 */
+	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");
@@ -497,25 +490,23 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
 }
 
 static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
-	unsigned char *local_transfer_buffer,
-	unsigned int startAddr, unsigned int len)
+				unsigned char *local_transfer_buffer,
+				unsigned int startAddr, unsigned int len)
 {
 	int ret;
 
 #ifdef CONFIG_COMEDI_DEBUG
 	printk(KERN_DEBUG "comedi: usbduxfast: uploading %d bytes", len);
 	printk(KERN_DEBUG " to addr %d, first byte=%d.\n",
-		startAddr, local_transfer_buffer[0]);
+	       startAddr, local_transfer_buffer[0]);
 #endif
-	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 */
+	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(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret);
@@ -544,7 +535,7 @@ int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
 #ifdef CONFIG_COMEDI_DEBUG
 	printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
 	       "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
-		udfs->urbIn->dev);
+	       udfs->urbIn->dev);
 #endif
 	ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
 	if (ret) {
@@ -556,7 +547,8 @@ int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
 }
 
 static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
-	struct comedi_subdevice *s, struct comedi_cmd *cmd)
+				 struct comedi_subdevice *s,
+				 struct comedi_cmd *cmd)
 {
 	int err = 0, stop_mask = 0;
 	long int steps, tmp;
@@ -608,16 +600,16 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
 	 */
 
 	if (cmd->start_src != TRIG_NOW &&
-		cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_INT)
+	    cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_INT)
 		err++;
 	if (cmd->scan_begin_src != TRIG_TIMER &&
-		cmd->scan_begin_src != TRIG_FOLLOW &&
-		cmd->scan_begin_src != TRIG_EXT)
+	    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)
+	    cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
 		err++;
 
 	/* can't have external stop and start triggers at once */
@@ -698,7 +690,8 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
 }
 
 static int usbduxfast_ai_inttrig(struct comedi_device *dev,
-	struct comedi_subdevice *s, unsigned int trignum)
+				 struct comedi_subdevice *s,
+				 unsigned int trignum)
 {
 	int ret;
 	struct usbduxfastsub_s *udfs = dev->private;
@@ -749,7 +742,8 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev,
 #define OUTBASE	(1+0x10)
 #define LOGBASE	(1+0x18)
 
-static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
+static int usbduxfast_ai_cmd(struct comedi_device *dev,
+			     struct comedi_subdevice *s)
 {
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int chan, gain, rngmask = 0xff;
@@ -797,7 +791,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 				return -EINVAL;
 			}
 			if ((gain != CR_RANGE(cmd->chanlist[i]))
-				&& (cmd->chanlist_len > 3)) {
+			    && (cmd->chanlist_len > 3)) {
 				printk(KERN_ERR "comedi%d: the gain must be"
 				       " the same for all channels.\n",
 				       dev->minor);
@@ -835,7 +829,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 		return -EINVAL;
 	}
 	if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
-		&& (cmd->chanlist_len != 16)) {
+	    && (cmd->chanlist_len != 16)) {
 		printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only"
 		       " with 1 or 16 channels possible.\n", dev->minor);
 		up(&udfs->sem);
@@ -865,17 +859,17 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 		/* 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;
+			udfs->dux_commands[LENBASE + 0] = 0x01;
 			/* deceision state w/o data */
-			udfs->dux_commands[OPBASE+0] = 0x01;
-			udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+			udfs->dux_commands[OPBASE + 0] = 0x01;
+			udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
 			/* RDY0 = 0 */
-			udfs->dux_commands[LOGBASE+0] = 0x00;
+			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;
+			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) {
@@ -888,30 +882,33 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 				 */
 
 				/* branch back to state 1 */
-				udfs->dux_commands[LENBASE+1] = 0x89;
+				udfs->dux_commands[LENBASE + 1] = 0x89;
 				/* deceision state with data */
-				udfs->dux_commands[OPBASE+1] = 0x03;
-				udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+				udfs->dux_commands[OPBASE + 1] = 0x03;
+				udfs->dux_commands[OUTBASE + 1] =
+				    0xFF & rngmask;
 				/* doesn't matter */
-				udfs->dux_commands[LOGBASE+1] = 0xFF;
+				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;
+				udfs->dux_commands[LENBASE + 1] = steps - 1;
 				/* data */
-				udfs->dux_commands[OPBASE+1] = 0x02;
-				udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+				udfs->dux_commands[OPBASE + 1] = 0x02;
+				udfs->dux_commands[OUTBASE + 1] =
+				    0xFF & rngmask;
 				/* doesn't matter */
-				udfs->dux_commands[LOGBASE+1] = 0;
+				udfs->dux_commands[LOGBASE + 1] = 0;
 				/* branch back to state 1 */
-				udfs->dux_commands[LENBASE+2] = 0x09;
+				udfs->dux_commands[LENBASE + 2] = 0x09;
 				/* deceision state w/o data */
-				udfs->dux_commands[OPBASE+2] = 0x01;
-				udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+				udfs->dux_commands[OPBASE + 2] = 0x01;
+				udfs->dux_commands[OUTBASE + 2] =
+				    0xFF & rngmask;
 				/* doesn't matter */
-				udfs->dux_commands[LOGBASE+2] = 0xFF;
+				udfs->dux_commands[LOGBASE + 2] = 0xFF;
 			}
 		} else {
 			/*
@@ -923,26 +920,26 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 			steps = steps - 1;
 
 			/* 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;
+			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 */
-			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;
+			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 */
 
 			/* branch back to state 1 */
-			udfs->dux_commands[LENBASE+3] = 0x09;
+			udfs->dux_commands[LENBASE + 3] = 0x09;
 			/* deceision state w data */
-			udfs->dux_commands[OPBASE+3] = 0x03;
-			udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+			udfs->dux_commands[OPBASE + 3] = 0x03;
+			udfs->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
 			/* doesn't matter */
-			udfs->dux_commands[LOGBASE+3] = 0xFF;
+			udfs->dux_commands[LOGBASE + 3] = 0xFF;
 		}
 		break;
 
@@ -957,11 +954,11 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 		else
 			rngmask = 0xff;
 
-		udfs->dux_commands[LENBASE+0] = 1;
+		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;
+		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;
@@ -972,23 +969,23 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 			rngmask = 0xff;
 
 		/* do the first part of the delay */
-		udfs->dux_commands[LENBASE+1] = steps_tmp / 2;
-		udfs->dux_commands[OPBASE+1] = 0;
+		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;
+		udfs->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
+		udfs->dux_commands[LOGBASE + 1] = 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;
+		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;
 
-		udfs->dux_commands[LENBASE+3] = 1;
+		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;
+		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
@@ -1002,22 +999,22 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 			rngmask = 0xff;
 
 		/* do the first part of the delay */
-		udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
-		udfs->dux_commands[OPBASE+4] = 0;
+		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;
+		udfs->dux_commands[OUTBASE + 4] = (0xFF - 0x02) & rngmask;
+		udfs->dux_commands[LOGBASE + 4] = 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;
+		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:
@@ -1033,12 +1030,12 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 			 * commit data to the FIFO and do the first part
 			 * of the delay
 			 */
-			udfs->dux_commands[LENBASE+j*2] = steps / 2;
+			udfs->dux_commands[LENBASE + j * 2] = steps / 2;
 			/* data */
-			udfs->dux_commands[OPBASE+j*2] = 0x02;
+			udfs->dux_commands[OPBASE + j * 2] = 0x02;
 			/* no change */
-			udfs->dux_commands[OUTBASE+j*2] = 0xFF & rngmask;
-			udfs->dux_commands[LOGBASE+j*2] = 0;
+			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;
@@ -1046,23 +1043,25 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 				rngmask = 0xff;
 
 			/* do the second part of the delay */
-			udfs->dux_commands[LENBASE+j*2+1] = steps - steps / 2;
+			udfs->dux_commands[LENBASE + j * 2 + 1] =
+			    steps - steps / 2;
 			/* no data */
-			udfs->dux_commands[OPBASE+j*2+1] = 0;
+			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;
+			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: */
 		steps_tmp = steps - 2;
 
 		/* commit data to the FIFO and do the first part of the delay */
-		udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
+		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;
+		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;
@@ -1070,17 +1069,17 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 			rngmask = 0xff;
 
 		/* do the second part of the delay */
-		udfs->dux_commands[LENBASE+5] = steps_tmp - steps_tmp / 2;
+		udfs->dux_commands[LENBASE + 5] = steps_tmp - steps_tmp / 2;
 		/* no data */
-		udfs->dux_commands[OPBASE+5] = 0;
+		udfs->dux_commands[OPBASE + 5] = 0;
 		/* reset */
-		udfs->dux_commands[OUTBASE+5] = (0xFF - 0x02) & rngmask;
-		udfs->dux_commands[LOGBASE+5] = 0;
+		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;
+		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)
@@ -1094,55 +1093,57 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 			 */
 
 			/* branch back to state 0 */
-			udfs->dux_commands[LENBASE+0] = 0x01;
+			udfs->dux_commands[LENBASE + 0] = 0x01;
 			/* deceision state w/o data */
-			udfs->dux_commands[OPBASE+0] = 0x01;
+			udfs->dux_commands[OPBASE + 0] = 0x01;
 			/* reset */
-			udfs->dux_commands[OUTBASE+0] = (0xFF-0x02) & rngmask;
+			udfs->dux_commands[OUTBASE + 0] =
+			    (0xFF - 0x02) & rngmask;
 			/* RDY0 = 0 */
-			udfs->dux_commands[LOGBASE+0] = 0x00;
+			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;
+			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;
+			udfs->dux_commands[OUTBASE + 0] =
+			    (0xFF - 0x02) & rngmask;
+			udfs->dux_commands[LOGBASE + 0] = 0;
 		}
 
 		/* commit data to the FIFO */
-		udfs->dux_commands[LENBASE+1] = 1;
+		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;
+		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 */
 		steps = steps - 2;
 
 		/* 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;
+		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 */
-		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;
+		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;
 
 		/* branch back to state 1 */
-		udfs->dux_commands[LENBASE+4] = 0x09;
+		udfs->dux_commands[LENBASE + 4] = 0x09;
 		/* deceision state w/o data */
-		udfs->dux_commands[OPBASE+4] = 0x01;
-		udfs->dux_commands[OUTBASE+4] = 0xFF & rngmask;
+		udfs->dux_commands[OPBASE + 4] = 0x01;
+		udfs->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
 		/* doesn't matter */
-		udfs->dux_commands[LOGBASE+4] = 0xFF;
+		udfs->dux_commands[LOGBASE + 4] = 0xFF;
 
 		break;
 
@@ -1166,7 +1167,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
 		return result;
 	}
 	if (cmd->stop_src == TRIG_COUNT) {
-		udfs->ai_sample_count =	cmd->stop_arg * cmd->scan_end_arg;
+		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, "
@@ -1209,7 +1210,8 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice
  * 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)
+				   struct comedi_subdevice *s,
+				   struct comedi_insn *insn, unsigned int *data)
 {
 	int i, j, n, actual_length;
 	int chan, range, rngmask;
@@ -1248,43 +1250,43 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 		rngmask = 0xff;
 
 	/* commit data to the FIFO */
-	udfs->dux_commands[LENBASE+0] = 1;
+	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;
+	udfs->dux_commands[OPBASE + 0] = 0x02;
+	udfs->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
+	udfs->dux_commands[LOGBASE + 0] = 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;
-
-	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;
-
-	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;
-
-	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;
+	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;
+
+	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;
+
+	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;
+
+	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;
 
 	/* 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 + 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;
+	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(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
@@ -1310,7 +1312,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 				   &actual_length, 10000);
 		if (err < 0) {
 			printk(KERN_ERR "comedi%d: insn timeout. No data.\n",
-				dev->minor);
+			       dev->minor);
 			up(&udfs->sem);
 			return err;
 		}
@@ -1323,7 +1325,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 				   &actual_length, 10000);
 		if (err < 0) {
 			printk(KERN_ERR "comedi%d: insn data error: %d\n",
-				dev->minor, err);
+			       dev->minor, err);
 			up(&udfs->sem);
 			return err;
 		}
@@ -1346,8 +1348,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev,
 #define FIRMWARE_MAX_LEN 0x2000
 
 static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
-			  const u8 *firmwareBinary,
-			  int sizeFirmware)
+			  const u8 * firmwareBinary, int sizeFirmware)
 {
 	int ret;
 	uint8_t *fwBuf;
@@ -1355,7 +1356,7 @@ static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
 	if (!firmwareBinary)
 		return 0;
 
-	if (sizeFirmware>FIRMWARE_MAX_LEN) {
+	if (sizeFirmware > FIRMWARE_MAX_LEN) {
 		dev_err(&usbduxfastsub->interface->dev,
 			"comedi_: usbduxfast firmware binary it too large for FX2.\n");
 		return -ENOMEM;
@@ -1368,7 +1369,7 @@ static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
 			"comedi_: mem alloc for firmware failed\n");
 		return -ENOMEM;
 	}
-	memcpy(fwBuf,firmwareBinary,sizeFirmware);
+	memcpy(fwBuf, firmwareBinary, sizeFirmware);
 
 	ret = usbduxfastsub_stop(usbduxfastsub);
 	if (ret < 0) {
@@ -1396,8 +1397,6 @@ static int firmwareUpload(struct usbduxfastsub_s *usbduxfastsub,
 	return 0;
 }
 
-
-
 static void tidy_up(struct usbduxfastsub_s *udfs)
 {
 #ifdef CONFIG_COMEDI_DEBUG
@@ -1433,8 +1432,8 @@ static void tidy_up(struct usbduxfastsub_s *udfs)
 	udfs->ai_cmd_running = 0;
 }
 
-static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw,
-							 void *context)
+static void usbduxfast_firmware_request_complete_handler(const struct firmware
+							 *fw, void *context)
 {
 	struct usbduxfastsub_s *usbduxfastsub_tmp = context;
 	struct usb_device *usbdev = usbduxfastsub_tmp->usbdev;
@@ -1451,8 +1450,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware *
 
 	if (ret) {
 		dev_err(&usbdev->dev,
-			"Could not upload firmware (err=%d)\n",
-			ret);
+			"Could not upload firmware (err=%d)\n", ret);
 		return;
 	}
 
@@ -1463,7 +1461,7 @@ static void usbduxfast_firmware_request_complete_handler(const struct firmware *
  * allocate memory for the urbs and initialise them
  */
 static int usbduxfastsub_probe(struct usb_interface *uinterf,
-	const struct usb_device_id *id)
+			       const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(uinterf);
 	int i;
@@ -1539,7 +1537,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
 	}
 	/* setting to alternate setting 1: enabling bulk ep */
 	i = usb_set_interface(usbduxfastsub[index].usbdev,
-		usbduxfastsub[index].ifnum, 1);
+			      usbduxfastsub[index].ifnum, 1);
 	if (i < 0) {
 		printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to "
 		       "alternate setting 1.\n", index);
@@ -1575,8 +1573,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf,
 				      usbduxfast_firmware_request_complete_handler);
 
 	if (ret) {
-		dev_err(&udev->dev, "could not load firmware (err=%d)\n",
-			ret);
+		dev_err(&udev->dev, "could not load firmware (err=%d)\n", ret);
 		return ret;
 	}
 
@@ -1618,7 +1615,8 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf)
 /*
  * is called when comedi-config is called
  */
-static int usbduxfast_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int usbduxfast_attach(struct comedi_device *dev,
+			     struct comedi_devconfig *it)
 {
 	int ret;
 	int index;
@@ -1725,7 +1723,6 @@ static int usbduxfast_detach(struct comedi_device *dev)
 		       "variable...\n");
 		return -EFAULT;
 	}
-
 #ifdef CONFIG_COMEDI_DEBUG
 	printk(KERN_DEBUG "comedi%d: usbduxfast: detach usb device\n",
 	       dev->minor);
@@ -1760,10 +1757,10 @@ static int usbduxfast_detach(struct comedi_device *dev)
  * main driver struct
  */
 static struct comedi_driver driver_usbduxfast = {
-	.driver_name	= "usbduxfast",
-	.module		= THIS_MODULE,
-	.attach		= usbduxfast_attach,
-	.detach		= usbduxfast_detach
+	.driver_name = "usbduxfast",
+	.module = THIS_MODULE,
+	.attach = usbduxfast_attach,
+	.detach = usbduxfast_detach
 };
 
 /*
@@ -1771,9 +1768,9 @@ static struct comedi_driver driver_usbduxfast = {
  */
 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(0x13d8, 0x0010)},	/* real ID */
+	{USB_DEVICE(0x13d8, 0x0011)},	/* real ID */
+	{}			/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, usbduxfastsub_table);
@@ -1783,12 +1780,12 @@ MODULE_DEVICE_TABLE(usb, usbduxfastsub_table);
  */
 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
 };
 
 /*
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 9de43b5..c335040 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -76,19 +76,19 @@ enum {
 };
 
 static struct usb_device_id vmk80xx_id_table[] = {
-	{ USB_DEVICE(0x10cf, 0x5500), .driver_info = DEVICE_VMK8055 },
-	{ USB_DEVICE(0x10cf, 0x5501), .driver_info = DEVICE_VMK8055 },
-	{ USB_DEVICE(0x10cf, 0x5502), .driver_info = DEVICE_VMK8055 },
-	{ USB_DEVICE(0x10cf, 0x5503), .driver_info = DEVICE_VMK8055 },
-	{ USB_DEVICE(0x10cf, 0x8061), .driver_info = DEVICE_VMK8061 },
-	{ USB_DEVICE(0x10cf, 0x8062), .driver_info = DEVICE_VMK8061 },
-	{ USB_DEVICE(0x10cf, 0x8063), .driver_info = DEVICE_VMK8061 },
-	{ USB_DEVICE(0x10cf, 0x8064), .driver_info = DEVICE_VMK8061 },
-	{ USB_DEVICE(0x10cf, 0x8065), .driver_info = DEVICE_VMK8061 },
-	{ USB_DEVICE(0x10cf, 0x8066), .driver_info = DEVICE_VMK8061 },
-	{ USB_DEVICE(0x10cf, 0x8067), .driver_info = DEVICE_VMK8061 },
-	{ USB_DEVICE(0x10cf, 0x8068), .driver_info = DEVICE_VMK8061 },
-	{ } /* terminating entry */
+	{USB_DEVICE(0x10cf, 0x5500),.driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x5501),.driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x5502),.driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x5503),.driver_info = DEVICE_VMK8055},
+	{USB_DEVICE(0x10cf, 0x8061),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8062),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8063),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8064),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8065),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8066),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8067),.driver_info = DEVICE_VMK8061},
+	{USB_DEVICE(0x10cf, 0x8068),.driver_info = DEVICE_VMK8061},
+	{}			/* terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, vmk80xx_id_table);
@@ -120,19 +120,19 @@ MODULE_DEVICE_TABLE(usb, vmk80xx_id_table);
 #define VMK8055_CMD_WRT_AD      0x05
 
 #define VMK8061_CMD_RD_AI       0x00
-#define VMK8061_CMR_RD_ALL_AI   0x01    /* !non-active! */
+#define VMK8061_CMR_RD_ALL_AI   0x01	/* !non-active! */
 #define VMK8061_CMD_SET_AO      0x02
-#define VMK8061_CMD_SET_ALL_AO  0x03    /* !non-active! */
+#define VMK8061_CMD_SET_ALL_AO  0x03	/* !non-active! */
 #define VMK8061_CMD_OUT_PWM     0x04
 #define VMK8061_CMD_RD_DI       0x05
-#define VMK8061_CMD_DO          0x06    /* !non-active! */
+#define VMK8061_CMD_DO          0x06	/* !non-active! */
 #define VMK8061_CMD_CLR_DO      0x07
 #define VMK8061_CMD_SET_DO      0x08
-#define VMK8061_CMD_RD_CNT      0x09    /* TODO: completely pointless? */
-#define VMK8061_CMD_RST_CNT     0x0a    /* TODO: completely pointless? */
-#define VMK8061_CMD_RD_VERSION  0x0b    /* internal usage */
-#define VMK8061_CMD_RD_JMP_STAT 0x0c    /* TODO: not implemented yet */
-#define VMK8061_CMD_RD_PWR_STAT 0x0d    /* internal usage */
+#define VMK8061_CMD_RD_CNT      0x09	/* TODO: completely pointless? */
+#define VMK8061_CMD_RST_CNT     0x0a	/* TODO: completely pointless? */
+#define VMK8061_CMD_RD_VERSION  0x0b	/* internal usage */
+#define VMK8061_CMD_RD_JMP_STAT 0x0c	/* TODO: not implemented yet */
+#define VMK8061_CMD_RD_PWR_STAT 0x0d	/* internal usage */
 #define VMK8061_CMD_RD_DO       0x0e
 #define VMK8061_CMD_RD_AO       0x0f
 #define VMK8061_CMD_RD_PWM      0x10
@@ -153,15 +153,15 @@ MODULE_DEVICE_TABLE(usb, vmk80xx_id_table);
 #undef CONFIG_VMK80XX_DEBUG
 
 #ifdef CONFIG_VMK80XX_DEBUG
- static int dbgvm = 1;
+static int dbgvm = 1;
 #else
- static int dbgvm;
+static int dbgvm;
 #endif
 
 #ifdef CONFIG_COMEDI_DEBUG
- static int dbgcm = 1;
+static int dbgcm = 1;
 #else
- static int dbgcm;
+static int dbgcm;
 #endif
 
 #define dbgvm(fmt, arg...)                     \
@@ -182,33 +182,33 @@ enum vmk80xx_model {
 };
 
 struct firmware_version {
-	unsigned char ic3_vers[32]; /* USB-Controller */
-	unsigned char ic6_vers[32]; /* CPU */
+	unsigned char ic3_vers[32];	/* USB-Controller */
+	unsigned char ic6_vers[32];	/* CPU */
 };
 
 static const struct comedi_lrange vmk8055_range = {
-	1, { UNI_RANGE(5) }
+	1, {UNI_RANGE(5)}
 };
 
 static const struct comedi_lrange vmk8061_range = {
-	2, { UNI_RANGE(5), UNI_RANGE(10) }
+	2, {UNI_RANGE(5), UNI_RANGE(10)}
 };
 
 struct vmk80xx_board {
 	const char *name;
 	enum vmk80xx_model model;
 	const struct comedi_lrange *range;
-	__u8   ai_chans;
+	__u8 ai_chans;
 	__le16 ai_bits;
-	__u8   ao_chans;
+	__u8 ao_chans;
 	__le16 ao_bits;
-	__u8   di_chans;
+	__u8 di_chans;
 	__le16 di_bits;
-	__u8   do_chans;
+	__u8 do_chans;
 	__le16 do_bits;
-	__u8   cnt_chans;
+	__u8 cnt_chans;
 	__le16 cnt_bits;
-	__u8   pwm_chans;
+	__u8 pwm_chans;
 	__le16 pwm_bits;
 };
 
@@ -253,8 +253,7 @@ static void vmk80xx_tx_callback(struct urb *urb)
 	dbgvm("vmk80xx: %s\n", __func__);
 
 	if (stat && !(stat == -ENOENT
-		 ||   stat == -ECONNRESET
-		 ||   stat == -ESHUTDOWN))
+		      || stat == -ECONNRESET || stat == -ESHUTDOWN))
 		dbgcm("comedi#: vmk80xx: %s - nonzero urb status (%d)\n",
 		      __func__, stat);
 
@@ -319,10 +318,8 @@ static int vmk80xx_check_data_link(struct vmk80xx_usb *dev)
 	/* Check that IC6 (PIC16F871) is powered and
 	 * running and the data link between IC3 and
 	 * IC6 is working properly */
-	usb_bulk_msg(dev->udev, tx_pipe, tx, 1, NULL,
-		     dev->ep_tx->bInterval);
-	usb_bulk_msg(dev->udev, rx_pipe, rx, 2, NULL,
-		     HZ * 10);
+	usb_bulk_msg(dev->udev, tx_pipe, tx, 1, NULL, dev->ep_tx->bInterval);
+	usb_bulk_msg(dev->udev, rx_pipe, rx, 2, NULL, HZ * 10);
 
 	return (int)rx[1];
 }
@@ -342,16 +339,14 @@ static void vmk80xx_read_eeprom(struct vmk80xx_usb *dev, int flag)
 
 	/* Read the firmware version info of IC3 and
 	 * IC6 from the internal EEPROM of the IC */
-	usb_bulk_msg(dev->udev, tx_pipe, tx,  1, NULL,
-		     dev->ep_tx->bInterval);
-	usb_bulk_msg(dev->udev, rx_pipe, rx, 64, &cnt,
-		     HZ * 10);
+	usb_bulk_msg(dev->udev, tx_pipe, tx, 1, NULL, dev->ep_tx->bInterval);
+	usb_bulk_msg(dev->udev, rx_pipe, rx, 64, &cnt, HZ * 10);
 
 	rx[cnt] = '\0';
 
 	if (flag & IC3_VERSION)
-		strncpy(dev->fw.ic3_vers, rx +  1, 24);
-	else /* IC6_VERSION */
+		strncpy(dev->fw.ic3_vers, rx + 1, 24);
+	else			/* IC6_VERSION */
 		strncpy(dev->fw.ic6_vers, rx + 25, 24);
 }
 
@@ -397,7 +392,7 @@ static void vmk80xx_build_int_urb(struct urb *urb, int flag)
 	unsigned int pipe;
 	unsigned char *buf;
 	size_t size;
-	void (*callback)(struct urb *);
+	void (*callback) (struct urb *);
 	int ival;
 
 	dbgvm("vmk80xx: %s\n", __func__);
@@ -409,7 +404,7 @@ static void vmk80xx_build_int_urb(struct urb *urb, int flag)
 		size = le16_to_cpu(dev->ep_rx->wMaxPacketSize);
 		callback = vmk80xx_rx_callback;
 		ival = dev->ep_rx->bInterval;
-	} else { /* URB_SND_FLAG */
+	} else {		/* URB_SND_FLAG */
 		tx_addr = dev->ep_tx->bEndpointAddress;
 		pipe = usb_sndintpipe(dev->udev, tx_addr);
 		buf = dev->usb_tx_buf;
@@ -418,8 +413,7 @@ static void vmk80xx_build_int_urb(struct urb *urb, int flag)
 		ival = dev->ep_tx->bInterval;
 	}
 
-	usb_fill_int_urb(urb, dev->udev, pipe, buf,
-			 size, callback, dev, ival);
+	usb_fill_int_urb(urb, dev->udev, pipe, buf, size, callback, dev, ival);
 }
 
 static void vmk80xx_do_bulk_msg(struct vmk80xx_usb *dev)
@@ -444,8 +438,7 @@ static void vmk80xx_do_bulk_msg(struct vmk80xx_usb *dev)
 
 	usb_bulk_msg(dev->udev, tx_pipe, dev->usb_tx_buf,
 		     size, NULL, dev->ep_tx->bInterval);
-	usb_bulk_msg(dev->udev, rx_pipe, dev->usb_rx_buf,
-		     size, NULL, HZ * 10);
+	usb_bulk_msg(dev->udev, rx_pipe, dev->usb_rx_buf, size, NULL, HZ * 10);
 
 	clear_bit(TRANS_OUT_BUSY, &dev->flags);
 	clear_bit(TRANS_IN_BUSY, &dev->flags);
@@ -464,7 +457,8 @@ static int vmk80xx_read_packet(struct vmk80xx_usb *dev)
 	/* Only useful for interrupt transfers */
 	if (test_bit(TRANS_IN_BUSY, &dev->flags))
 		if (wait_event_interruptible(dev->read_wait,
-			!test_bit(TRANS_IN_BUSY, &dev->flags)))
+					     !test_bit(TRANS_IN_BUSY,
+						       &dev->flags)))
 			return -ERESTART;
 
 	if (dev->board.model == VMK8061_MODEL) {
@@ -510,7 +504,8 @@ static int vmk80xx_write_packet(struct vmk80xx_usb *dev, int cmd)
 
 	if (test_bit(TRANS_OUT_BUSY, &dev->flags))
 		if (wait_event_interruptible(dev->write_wait,
-			!test_bit(TRANS_OUT_BUSY, &dev->flags)))
+					     !test_bit(TRANS_OUT_BUSY,
+						       &dev->flags)))
 			return -ERESTART;
 
 	if (dev->board.model == VMK8061_MODEL) {
@@ -607,7 +602,7 @@ static int vmk80xx_ai_rinsn(struct comedi_device *cdev,
 
 		/* VMK8061_MODEL */
 		data[n] = dev->usb_rx_buf[reg[0]] + 256 *
-			  dev->usb_rx_buf[reg[1]];
+		    dev->usb_rx_buf[reg[1]];
 	}
 
 	up(&dev->limit_sem);
@@ -638,7 +633,7 @@ static int vmk80xx_ao_winsn(struct comedi_device *cdev,
 		else
 			reg = VMK8055_AO2_REG;
 		break;
-	default: /* NOTE: avoid compiler warnings */
+	default:		/* NOTE: avoid compiler warnings */
 		cmd = VMK8061_CMD_SET_AO;
 		reg = VMK8061_AO_REG;
 		dev->usb_tx_buf[VMK8061_CH_REG] = chan;
@@ -680,7 +675,7 @@ static int vmk80xx_ao_rinsn(struct comedi_device *cdev,
 		if (vmk80xx_read_packet(dev))
 			break;
 
-		data[n] = dev->usb_rx_buf[reg+chan];
+		data[n] = dev->usb_rx_buf[reg + chan];
 	}
 
 	up(&dev->limit_sem);
@@ -855,8 +850,8 @@ static int vmk80xx_cnt_rinsn(struct comedi_device *cdev,
 		}
 
 		/* VMK8061_MODEL */
-		data[n] = dev->usb_rx_buf[reg[0]*(chan+1)+1]
-		  + 256 * dev->usb_rx_buf[reg[1]*2+2];
+		data[n] = dev->usb_rx_buf[reg[0] * (chan + 1) + 1]
+		    + 256 * dev->usb_rx_buf[reg[1] * 2 + 2];
 	}
 
 	up(&dev->limit_sem);
@@ -941,7 +936,7 @@ static int vmk80xx_cnt_winsn(struct comedi_device *cdev,
 		if (((val + 1) * val) < debtime * 1000 / 115)
 			val += 1;
 
-		dev->usb_tx_buf[6+chan] = val;
+		dev->usb_tx_buf[6 + chan] = val;
 
 		if (vmk80xx_write_packet(dev, cmd))
 			break;
@@ -975,8 +970,7 @@ static int vmk80xx_pwm_rinsn(struct comedi_device *cdev,
 		if (vmk80xx_read_packet(dev))
 			break;
 
-		data[n] = dev->usb_rx_buf[reg[0]] + 4 *
-			  dev->usb_rx_buf[reg[1]];
+		data[n] = dev->usb_rx_buf[reg[0]] + 4 * dev->usb_rx_buf[reg[1]];
 	}
 
 	up(&dev->limit_sem);
@@ -1309,8 +1303,7 @@ vmk80xx_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
 	if (dev->board.model == VMK8061_MODEL) {
 		vmk80xx_read_eeprom(dev, IC3_VERSION);
-		printk(KERN_INFO "comedi#: vmk80xx: %s\n",
-		       dev->fw.ic3_vers);
+		printk(KERN_INFO "comedi#: vmk80xx: %s\n", dev->fw.ic3_vers);
 
 		if (vmk80xx_check_data_link(dev)) {
 			vmk80xx_read_eeprom(dev, IC6_VERSION);
@@ -1368,17 +1361,17 @@ static void vmk80xx_disconnect(struct usb_interface *intf)
 /* TODO: Add support for suspend, resume, pre_reset,
  * post_reset and flush */
 static struct usb_driver vmk80xx_driver = {
-	.name       = "vmk80xx",
-	.probe      = vmk80xx_probe,
+	.name = "vmk80xx",
+	.probe = vmk80xx_probe,
 	.disconnect = vmk80xx_disconnect,
-	.id_table   = vmk80xx_id_table
+	.id_table = vmk80xx_id_table
 };
 
 static struct comedi_driver driver_vmk80xx = {
-	.module      = THIS_MODULE,
+	.module = THIS_MODULE,
 	.driver_name = "vmk80xx",
-	.attach      = vmk80xx_attach,
-	.detach      = vmk80xx_detach
+	.attach = vmk80xx_attach,
+	.detach = vmk80xx_detach
 };
 
 static int __init vmk80xx_init(void)
diff --git a/drivers/staging/comedi/kcomedilib/data.c b/drivers/staging/comedi/kcomedilib/data.c
index d808556..aefc41a 100644
--- a/drivers/staging/comedi/kcomedilib/data.c
+++ b/drivers/staging/comedi/kcomedilib/data.c
@@ -29,7 +29,7 @@
 #include <linux/delay.h>
 
 int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, unsigned int data)
+		      unsigned int range, unsigned int aref, unsigned int data)
 {
 	struct comedi_insn insn;
 
@@ -44,7 +44,7 @@ int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
 }
 
 int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int range, unsigned int aref, unsigned int *data)
+		     unsigned int range, unsigned int aref, unsigned int *data)
 {
 	struct comedi_insn insn;
 
@@ -59,7 +59,8 @@ int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
 }
 
 int comedi_data_read_hint(void *dev, unsigned int subdev,
-	unsigned int chan, unsigned int range, unsigned int aref)
+			  unsigned int chan, unsigned int range,
+			  unsigned int aref)
 {
 	struct comedi_insn insn;
 	unsigned int dummy_data;
@@ -75,8 +76,9 @@ int comedi_data_read_hint(void *dev, unsigned int subdev,
 }
 
 int comedi_data_read_delayed(void *dev, unsigned int subdev,
-	unsigned int chan, unsigned int range, unsigned int aref,
-	unsigned int *data, unsigned int nano_sec)
+			     unsigned int chan, unsigned int range,
+			     unsigned int aref, 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 8595567..30192f3 100644
--- a/drivers/staging/comedi/kcomedilib/dio.c
+++ b/drivers/staging/comedi/kcomedilib/dio.c
@@ -27,7 +27,7 @@
 #include <linux/string.h>
 
 int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int io)
+		      unsigned int io)
 {
 	struct comedi_insn insn;
 
@@ -42,7 +42,7 @@ int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
 }
 
 int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int *val)
+		    unsigned int *val)
 {
 	struct comedi_insn insn;
 
@@ -57,7 +57,7 @@ int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
 }
 
 int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
-	unsigned int val)
+		     unsigned int val)
 {
 	struct comedi_insn insn;
 
@@ -72,7 +72,7 @@ int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
 }
 
 int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
-	unsigned int *bits)
+			unsigned int *bits)
 {
 	struct comedi_insn insn;
 	unsigned int data[2];
diff --git a/drivers/staging/comedi/kcomedilib/get.c b/drivers/staging/comedi/kcomedilib/get.c
index b6b726a..6d84187 100644
--- a/drivers/staging/comedi/kcomedilib/get.c
+++ b/drivers/staging/comedi/kcomedilib/get.c
@@ -28,7 +28,7 @@
 
 int comedi_get_n_subdevices(void *d)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	return dev->n_subdevices;
 }
@@ -38,23 +38,23 @@ int comedi_get_version_code(void *d)
 	return COMEDI_VERSION_CODE;
 }
 
-const char *comedi_get_driver_name(void * d)
+const char *comedi_get_driver_name(void *d)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	return dev->driver->driver_name;
 }
 
-const char *comedi_get_board_name(void * d)
+const char *comedi_get_board_name(void *d)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	return dev->board_name;
 }
 
 int comedi_get_subdevice_type(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->type;
@@ -62,7 +62,7 @@ int comedi_get_subdevice_type(void *d, unsigned int subdevice)
 
 unsigned int comedi_get_subdevice_flags(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->subdev_flags;
@@ -70,7 +70,7 @@ unsigned int comedi_get_subdevice_flags(void *d, unsigned int subdevice)
 
 int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	if (subd > dev->n_subdevices)
 		return -ENODEV;
@@ -84,7 +84,7 @@ int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd)
 
 int comedi_get_n_channels(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->n_chan;
@@ -92,16 +92,16 @@ int comedi_get_n_channels(void *d, unsigned int subdevice)
 
 int comedi_get_len_chanlist(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	return s->len_chanlist;
 }
 
 unsigned int comedi_get_maxdata(void *d, unsigned int subdevice,
-	unsigned int chan)
+				unsigned int chan)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 
 	if (s->maxdata_list)
@@ -111,10 +111,9 @@ unsigned int comedi_get_maxdata(void *d, unsigned int subdevice,
 }
 
 #ifdef KCOMEDILIB_DEPRECATED
-int comedi_get_rangetype(void *d, unsigned int subdevice,
-	unsigned int chan)
+int comedi_get_rangetype(void *d, unsigned int subdevice, unsigned int chan)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	int ret;
 
@@ -132,7 +131,7 @@ int comedi_get_rangetype(void *d, unsigned int subdevice,
 
 int comedi_get_n_ranges(void *d, unsigned int subdevice, unsigned int chan)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	int ret;
 
@@ -149,9 +148,9 @@ int comedi_get_n_ranges(void *d, unsigned int subdevice, unsigned int chan)
  * ALPHA (non-portable)
 */
 int comedi_get_krange(void *d, unsigned int subdevice, unsigned int chan,
-	unsigned int range, struct comedi_krange *krange)
+		      unsigned int range, struct comedi_krange *krange)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	const struct comedi_lrange *lr;
 
@@ -173,7 +172,7 @@ int comedi_get_krange(void *d, unsigned int subdevice, unsigned int chan,
 */
 unsigned int comedi_get_buf_head_pos(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	struct comedi_async *async;
 
@@ -186,7 +185,7 @@ unsigned int comedi_get_buf_head_pos(void *d, unsigned int subdevice)
 
 int comedi_get_buffer_contents(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	struct comedi_async *async;
 	unsigned int num_bytes;
@@ -204,9 +203,9 @@ int comedi_get_buffer_contents(void *d, unsigned int subdevice)
  * ALPHA
 */
 int comedi_set_user_int_count(void *d, unsigned int subdevice,
-	unsigned int buf_user_count)
+			      unsigned int buf_user_count)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	struct comedi_async *async;
 	int num_bytes;
@@ -225,9 +224,9 @@ int comedi_set_user_int_count(void *d, unsigned int subdevice,
 }
 
 int comedi_mark_buffer_read(void *d, unsigned int subdevice,
-	unsigned int num_bytes)
+			    unsigned int num_bytes)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	struct comedi_async *async;
 
@@ -244,9 +243,9 @@ int comedi_mark_buffer_read(void *d, unsigned int subdevice,
 }
 
 int comedi_mark_buffer_written(void *d, unsigned int subdevice,
-	unsigned int num_bytes)
+			       unsigned int num_bytes)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	struct comedi_async *async;
 	int bytes_written;
@@ -265,7 +264,7 @@ int comedi_mark_buffer_written(void *d, unsigned int subdevice,
 
 int comedi_get_buffer_size(void *d, unsigned int subdev)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdev;
 	struct comedi_async *async;
 
@@ -280,7 +279,7 @@ int comedi_get_buffer_size(void *d, unsigned int subdev)
 
 int comedi_get_buffer_offset(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices + subdevice;
 	struct comedi_async *async;
 
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index b39ea7c..6552ef6 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -67,7 +67,7 @@ void *comedi_open(const char *filename)
 	if (!try_module_get(dev->driver->module))
 		return NULL;
 
-	return (void *) dev;
+	return (void *)dev;
 }
 
 void *comedi_open_old(unsigned int minor)
@@ -86,12 +86,12 @@ void *comedi_open_old(unsigned int minor)
 	if (dev == NULL || !dev->attached)
 		return NULL;
 
-	return (void *) dev;
+	return (void *)dev;
 }
 
 int comedi_close(void *d)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	module_put(dev->driver->module);
 
@@ -115,7 +115,7 @@ char *comedi_strerror(int err)
 
 int comedi_fileno(void *d)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 
 	/* return something random */
 	return dev->minor;
@@ -123,7 +123,7 @@ int comedi_fileno(void *d)
 
 int comedi_command(void *d, struct comedi_cmd *cmd)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
 	unsigned runflags;
@@ -159,7 +159,7 @@ int comedi_command(void *d, struct comedi_cmd *cmd)
 
 int comedi_command_test(void *d, struct comedi_cmd *cmd)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 
 	if (cmd->subdev >= dev->n_subdevices)
@@ -181,7 +181,7 @@ int comedi_command_test(void *d, struct comedi_cmd *cmd)
  */
 int comedi_do_insn(void *d, struct comedi_insn *insn)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 	int ret = 0;
 
@@ -214,7 +214,7 @@ int comedi_do_insn(void *d, struct comedi_insn *insn)
 			}
 			if (insn->subdev >= dev->n_subdevices) {
 				printk("%d not usable subdevice\n",
-					insn->subdev);
+				       insn->subdev);
 				ret = -EINVAL;
 				break;
 			}
@@ -296,7 +296,7 @@ int comedi_do_insn(void *d, struct comedi_insn *insn)
 		goto error;
 	}
 #endif
-      error:
+error:
 
 	return ret;
 }
@@ -322,7 +322,7 @@ int comedi_do_insn(void *d, struct comedi_insn *insn)
 */
 int comedi_lock(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 	unsigned long flags;
 	int ret = 0;
@@ -365,7 +365,7 @@ int comedi_lock(void *d, unsigned int subdevice)
 */
 int comedi_unlock(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 	unsigned long flags;
 	struct comedi_async *async;
@@ -417,7 +417,7 @@ int comedi_unlock(void *d, unsigned int subdevice)
 */
 int comedi_cancel(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 	int ret = 0;
 
@@ -456,9 +456,10 @@ int comedi_cancel(void *d, unsigned int subdevice)
    registration of callback functions
  */
 int comedi_register_callback(void *d, unsigned int subdevice,
-	unsigned int mask, int (*cb) (unsigned int, void *), void *arg)
+			     unsigned int mask, int (*cb) (unsigned int,
+							   void *), void *arg)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 	struct comedi_async *async;
 
@@ -494,7 +495,7 @@ int comedi_register_callback(void *d, unsigned int subdevice,
 
 int comedi_poll(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s = dev->subdevices;
 	struct comedi_async *async;
 
@@ -521,7 +522,7 @@ int comedi_poll(void *d, unsigned int subdevice)
 /* WARNING: not portable */
 int comedi_map(void *d, unsigned int subdevice, void *ptr)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 
 	if (subdevice >= dev->n_subdevices)
@@ -543,7 +544,7 @@ int comedi_map(void *d, unsigned int subdevice, void *ptr)
 /* WARNING: not portable */
 int comedi_unmap(void *d, unsigned int subdevice)
 {
-	struct comedi_device *dev = (struct comedi_device *) d;
+	struct comedi_device *dev = (struct comedi_device *)d;
 	struct comedi_subdevice *s;
 
 	if (subdevice >= dev->n_subdevices)
diff --git a/drivers/staging/comedi/kcomedilib/ksyms.c b/drivers/staging/comedi/kcomedilib/ksyms.c
index 314765d..19293d1 100644
--- a/drivers/staging/comedi/kcomedilib/ksyms.c
+++ b/drivers/staging/comedi/kcomedilib/ksyms.c
@@ -21,10 +21,6 @@
 
 */
 
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
-
 #include "../comedi.h"
 #include "../comedilib.h"
 #include "../comedidev.h"
diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c
index 36ae2cd..5a22fe6 100644
--- a/drivers/staging/comedi/proc.c
+++ b/drivers/staging/comedi/proc.c
@@ -34,12 +34,12 @@
 /* #include <linux/string.h> */
 
 int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
-	int *eof, void *data);
+			int *eof, void *data);
 
 extern struct comedi_driver *comedi_drivers;
 
 int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
-	int *eof, void *data)
+			int *eof, void *data)
 {
 	int i;
 	int devices_q = 0;
@@ -47,12 +47,13 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
 	struct comedi_driver *driv;
 
 	l += sprintf(buf + l,
-		"comedi version " COMEDI_RELEASE "\n"
-		"format string: %s\n",
-		"\"%2d: %-20s %-20s %4d\",i,driver_name,board_name,n_subdevices");
+		     "comedi version " COMEDI_RELEASE "\n"
+		     "format string: %s\n",
+		     "\"%2d: %-20s %-20s %4d\",i,driver_name,board_name,n_subdevices");
 
 	for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
-		struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
+		struct comedi_device_file_info *dev_file_info =
+		    comedi_get_device_file_info(i);
 		struct comedi_device *dev;
 
 		if (dev_file_info == NULL)
@@ -62,9 +63,9 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
 		if (dev->attached) {
 			devices_q = 1;
 			l += sprintf(buf + l, "%2d: %-20s %-20s %4d\n",
-				i,
-				dev->driver->driver_name,
-				dev->board_name, dev->n_subdevices);
+				     i,
+				     dev->driver->driver_name,
+				     dev->board_name, dev->n_subdevices);
 		}
 	}
 	if (!devices_q)
@@ -74,8 +75,8 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
 		l += sprintf(buf + l, "%s:\n", driv->driver_name);
 		for (i = 0; i < driv->num_names; i++) {
 			l += sprintf(buf + l, " %s\n",
-				*(char **)((char *)driv->board_name +
-					i * driv->offset));
+				     *(char **)((char *)driv->board_name +
+						i * driv->offset));
 		}
 		if (!driv->num_names)
 			l += sprintf(buf + l, " %s\n", driv->driver_name);
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
index 445909e..8313dfc 100644
--- a/drivers/staging/comedi/range.c
+++ b/drivers/staging/comedi/range.c
@@ -78,7 +78,7 @@ int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg)
 	}
 
 	if (copy_to_user(it.range_ptr, lr->range,
-			sizeof(struct comedi_krange) * lr->length))
+			 sizeof(struct comedi_krange) * lr->length))
 		return -EFAULT;
 
 	return 0;
@@ -128,11 +128,12 @@ int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist)
 	if (s->range_table) {
 		for (i = 0; i < n; i++)
 			if (CR_CHAN(chanlist[i]) >= s->n_chan ||
-				CR_RANGE(chanlist[i]) >= s->range_table->length
-				|| aref_invalid(s, chanlist[i])) {
-				printk("bad chanlist[%d]=0x%08x n_chan=%d range length=%d\n",
-					i, chanlist[i], s->n_chan,
-					s->range_table->length);
+			    CR_RANGE(chanlist[i]) >= s->range_table->length
+			    || aref_invalid(s, chanlist[i])) {
+				printk
+				    ("bad chanlist[%d]=0x%08x n_chan=%d range length=%d\n",
+				     i, chanlist[i], s->n_chan,
+				     s->range_table->length);
 #if 0
 				for (i = 0; i < n; i++)
 					printk("[%d]=0x%08x\n", i, chanlist[i]);
@@ -143,11 +144,11 @@ int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist)
 		for (i = 0; i < n; i++) {
 			chan = CR_CHAN(chanlist[i]);
 			if (chan >= s->n_chan ||
-				CR_RANGE(chanlist[i]) >=
-				s->range_table_list[chan]->length
-				|| aref_invalid(s, chanlist[i])) {
+			    CR_RANGE(chanlist[i]) >=
+			    s->range_table_list[chan]->length
+			    || aref_invalid(s, chanlist[i])) {
 				printk("bad chanlist[%d]=0x%08x\n", i,
-					chanlist[i]);
+				       chanlist[i]);
 				return -EINVAL;
 			}
 		}
diff --git a/drivers/staging/cowloop/Kconfig b/drivers/staging/cowloop/Kconfig
new file mode 100644
index 0000000..58d2a23
--- /dev/null
+++ b/drivers/staging/cowloop/Kconfig
@@ -0,0 +1,16 @@
+config COWLOOP
+	tristate "copy-on-write pseudo Block Driver"
+	depends on BLOCK
+	default n
+	---help---
+	  Cowloop is a "copy-on-write" pseudo block driver. It can be
+	  stacked on top of a "real" block driver, and catches all write
+	  operations on their way from the file systems layer above to
+	  the real driver below, effectively shielding the lower driver
+	  from those write accesses. The requests are then diverted to
+	  an ordinary file, located somewhere else (configurable). Later
+	  read requests are checked to see whether they can be serviced
+	  by the "real" block driver below, or must be pulled in from
+	  the diverted location. More information and userspace tools to
+	  use the driver are on the project's website
+	  http://www.ATComputing.nl/cowloop/
diff --git a/drivers/staging/cowloop/Makefile b/drivers/staging/cowloop/Makefile
new file mode 100644
index 0000000..2b6b81a
--- /dev/null
+++ b/drivers/staging/cowloop/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_COWLOOP)	+= cowloop.o
diff --git a/drivers/staging/cowloop/TODO b/drivers/staging/cowloop/TODO
new file mode 100644
index 0000000..9399d1c
--- /dev/null
+++ b/drivers/staging/cowloop/TODO
@@ -0,0 +1,11 @@
+TODO:
+	- checkpatch.pl cleanups
+	- run sparse to ensure clean
+	- fix up 32/64bit ioctl issues
+	- move proc file usage to debugfs
+	- audit ioctls
+	- add documentation
+	- get linux-fsdevel to review it
+
+Please send patches to "H.J. Thomassen" <hjt@ATComputing.nl> and
+Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/cowloop/cowloop.c b/drivers/staging/cowloop/cowloop.c
new file mode 100644
index 0000000..a71c743
--- /dev/null
+++ b/drivers/staging/cowloop/cowloop.c
@@ -0,0 +1,2842 @@
+/*
+**       COWLOOP block device driver (2.6 kernel compliant)
+** =======================================================================
+** Read-write loop-driver with copy-on-write functionality.
+**
+** Synopsis:
+**
+**     modprobe cowloop [maxcows=..] [rdofile=..... cowfile=.... [option=r]]
+**
+** Definition of number of configured cowdevices:
+**   maxcows=	number of configured cowdevices (default: 16)
+** (do not confuse this with MAXCOWS: absolute maximum as compiled)
+**
+** One pair of filenames can be supplied during insmod/modprobe to open
+** the first cowdevice:
+**   rdofile=	read-only file (or filesystem)
+**   cowfile=	storage-space for modified blocks of read-only file(system)
+**   option=r	repair cowfile automatically if it appears to be dirty
+**
+** Other cowdevices can be activated via the command "cowdev"
+** whenever the cowloop-driver is loaded.
+**
+** The read-only file may be of type 'regular' or 'block-device'.
+**
+** The cowfile must be of type 'regular'.
+** If an existing regular file is used as cowfile, its contents will be
+** used again for the current read-only file. When the cowfile has not been
+** closed properly during a previous session (i.e. rmmod cowloop), the
+** cowloop-driver refuses to open it unless the parameter "option=r" is
+** specified.
+**
+** Layout of cowfile:
+**
+** 	+-----------------------------+
+**	|       cow head block        |   MAPUNIT bytes
+**	|-----------------------------|
+**	|                             |   MAPUNIT bytes
+**	|---                       ---|
+**	|                             |   MAPUNIT bytes
+**	|---                       ---|
+**	|      used-block bitmap      |   MAPUNIT bytes
+**	|-----------------------------|
+**	|  gap to align start-offset  |
+**	|        to 4K multiple       |
+**	|-----------------------------|  <---- start-offset cow blocks
+**	|                             |
+**      |    written cow blocks       |   MAPUNIT bytes
+**      |          .....              |
+**
+** 	cowhead block:
+**   	  - contains general info about the rdofile which is related
+** 	    to this cowfile
+**
+** 	used-block bitmap:
+** 	  - contains one bit per block with a size of MAPUNIT bytes
+** 	  - bit-value '1' = block has been written on cow
+** 	              '0' = block unused on cow
+** 	  - total bitmap rounded to multiples of MAPUNIT
+**
+** ============================================================================
+** Author:             Gerlof Langeveld - AT Computing (March 2003)
+** Current maintainer: Hendrik-Jan Thomassen - AT Computing (Summer 2006)
+** Email:              hjt@ATComputing.nl
+** ----------------------------------------------------------------------------
+** Copyright (C) 2003-2009 AT Consultancy
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+** See the GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+** ----------------------------------------------------------------------------
+**
+** Major modifications:
+**
+** 	200405	Ported to kernel-version 2.6		Hendrik-Jan Thomassen
+**	200405	Added cowhead to cowfile to garantee
+**		consistency with read-only file		Gerlof Langeveld
+**	200405	Postponed flushing of bitmaps to improve
+**		performance. 				Gerlof Langeveld
+**	200405	Inline recovery for dirty cowfiles.	Gerlof Langeveld
+**	200502	Redesign to support more cowdevices.	Gerlof Langeveld
+**	200502	Support devices/file > 2 Gbytes.	Gerlof Langeveld
+**	200507	Check for free space to expand cowfile.	Gerlof Langeveld
+**	200902  Upgrade for kernel 2.6.28               Hendrik-Jan Thomassen
+**
+** Inspired by
+**    loop.c  by Theodore Ts'o and
+**    cloop.c by Paul `Rusty' Russell & Klaus Knopper.
+**
+** Design-considerations:
+**
+**   For the first experiments with the cowloop-driver, the request-queue
+**   made use of the do_generic_file_read() which worked fine except
+**   in combination with the cloop-driver; that combination
+**   resulted in a non-interruptible hangup of the system during
+**   heavy load. Other experiments using the `make_request' interface also
+**   resulted in unpredictable system hangups (with proper use of spinlocks).
+**
+**   To overcome these problems, the cowloop-driver starts a kernel-thread
+**   for every active cowdevice.
+**   All read- and write-request on the read-only file and copy-on-write file
+**   are handled in the context of that thread.
+**   A scheme has been designed to wakeup the kernel-thread as
+**   soon as I/O-requests are available in the request-queue; this thread
+**   handles the requests one-by-one by calling the proper read- or
+**   write-function related to the open read-only file or copy-on-write file.
+**   When all pending requests have been handled, the kernel-thread goes
+**   back to sleep-state.
+**   This approach requires some additional context-switches; however the
+**   performance loss during heavy I/O is less than 3%.
+**
+** -------------------------------------------------------------------------*/
+/* The following is the cowloop package version number. It must be
+   identical to the content of the include-file "version.h" that is
+   used in all supporting utilities:                                  */
+char revision[] = "$Revision: 3.1 $"; /* cowlo_init_module() has
+			     assumptions about this string's format   */
+
+/* Note that the following numbers are *not* the cowloop package version
+   numbers, but separate revision history numbers to track the
+   modifications of this particular source file:                      */
+/* $Log: cowloop.c,v $
+**
+** Revision 1.30  2009/02/08 hjt
+** Integrated earlier fixes
+** Upgraded to kernel 2.6.28 (thanks Jerome Poulin)
+**
+** Revision 1.29  2006/12/03 22:12:00  hjt
+** changed 'cowdevlock' from spinlock to semaphore, to avoid
+** "scheduling while atomic". Contributed by Juergen Christ.
+** Added version.h again
+**
+** Revision 1.28  2006/08/16 16:00:00  hjt
+** malloc each individual cowloopdevice struct separately
+**
+** Revision 1.27  2006/03/14 14:57:03  root
+** Removed include version.h
+**
+** Revision 1.26  2005/08/08 11:22:48  root
+** Implement possibility to close a cow file or reopen a cowfile read-only.
+**
+** Revision 1.25  2005/08/03 14:00:39  root
+** Added modinfo info to driver.
+**
+** Revision 1.24  2005/07/21 06:14:53  root
+** Cosmetic changes source code.
+**
+** Revision 1.23  2005/07/20 13:07:32  root
+** Supply ioctl to write watchdog program to react on lack of cowfile space.
+**
+** Revision 1.22  2005/07/20 07:53:34  root
+** Regular verification of free space in filesystem holding the cowfile
+** (give warnings whenever space is almost exhausted).
+** Terminology change: checksum renamed to fingerprint.
+**
+** Revision 1.21  2005/07/19 09:21:52  root
+** Removing maximum limit of 16 Gb per cowdevice.
+**
+** Revision 1.20  2005/07/19 07:50:33  root
+** Minor bugfixes and cosmetic changes.
+**
+** Revision 1.19  2005/06/10 12:29:55  root
+** Removed lock/unlock operation from cowlo_open().
+**
+** Revision 1.18  2005/05/09 12:56:26  root
+** Allow a cowdevice to be open more than once
+** (needed for support of ReiserFS and XFS).
+**
+** Revision 1.17  2005/03/17 14:36:16  root
+** Fixed some license issues.
+**
+** Revision 1.16  2005/03/07 14:42:05  root
+** Only allow one parallel open per cowdevice.
+**
+** Revision 1.15  2005/02/18 11:52:04  gerlof
+** Redesign to support more than one cowdevice > 2 Gb space.
+**
+** Revision 1.14  2004/08/17 14:19:16  gerlof
+** Modified output of /proc/cowloop.
+**
+** Revision 1.13  2004/08/16 07:21:10  gerlof
+** Separate statistical counter for read on rdofile and cowfile.
+**
+** Revision 1.12  2004/08/11 06:52:11  gerlof
+** Modified messages.
+**
+** Revision 1.11  2004/08/11 06:44:11  gerlof
+** Modified log messages.
+**
+** Revision 1.10  2004/08/10 12:27:27  gerlof
+** Cosmetic changes.
+**
+** Revision 1.9  2004/08/09 11:43:37  gerlof
+** Removed double definition of major number (COWMAJOR).
+**
+** Revision 1.8  2004/08/09 08:03:39  gerlof
+** Cleanup of messages.
+**
+** Revision 1.7  2004/05/27 06:37:33  gerlof
+** Modified /proc message.
+**
+** Revision 1.6  2004/05/26 21:23:28  gerlof
+** Modified /proc output.
+**
+** Revision 1.5  2004/05/26 13:23:34  gerlof
+** Support cowsync to force flushing the bitmaps and cowhead.
+**
+** Revision 1.4  2004/05/26 11:11:10  gerlof
+** Updated the comment to the actual situation.
+**
+** Revision 1.3  2004/05/26 10:50:00  gerlof
+** Implemented recovery-option.
+**
+** Revision 1.2  2004/05/25 15:14:41  gerlof
+** Modified bitmap flushing strategy.
+**
+*/
+
+#define COWMAJOR	241
+
+// #define COWDEBUG
+
+#ifdef 	COWDEBUG
+#define DEBUGP		printk
+#define DCOW		KERN_ALERT
+#else
+#define DEBUGP(format, x...)
+#endif
+
+#include <linux/types.h>
+#include <linux/autoconf.h>
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/stat.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+#include <asm/uaccess.h>
+#include <linux/proc_fs.h>
+#include <linux/blkdev.h>
+#include <linux/buffer_head.h>
+#include <linux/hdreg.h>
+#include <linux/genhd.h>
+#include <linux/statfs.h>
+
+#include "cowloop.h"
+
+MODULE_LICENSE("GPL");
+/* MODULE_AUTHOR("Gerlof Langeveld <gerlof@ATComputing.nl>");     obsolete address */
+MODULE_AUTHOR("Hendrik-Jan Thomassen <hjt@ATComputing.nl>"); /* current maintainer */
+MODULE_DESCRIPTION("Copy-on-write loop driver");
+MODULE_PARM_DESC(maxcows, " Number of configured cowdevices (default 16)");
+MODULE_PARM_DESC(rdofile, " Read-only file for /dev/cow/0");
+MODULE_PARM_DESC(cowfile, " Cowfile for /dev/cow/0");
+MODULE_PARM_DESC(option, "  Repair cowfile if inconsistent: option=r");
+
+#define DEVICE_NAME	"cow"
+
+#define	DFLCOWS		16		/* default cowloop devices	*/
+
+static int maxcows = DFLCOWS;
+module_param(maxcows, int, 0);
+static char *rdofile = "";
+module_param(rdofile, charp, 0);
+static char *cowfile = "";
+module_param(cowfile, charp, 0);
+static char *option = "";
+module_param(option, charp, 0);
+
+/*
+** per cowdevice several bitmap chunks are allowed of MAPCHUNKSZ each
+**
+** each bitmap chunk can describe MAPCHUNKSZ * 8 * MAPUNIT bytes of data
+** suppose:
+**	MAPCHUNKSZ 4096 and MAPUNIT 1024 --> 4096 * 8 * 1024 = 32 Mb per chunk
+*/
+#define	MAPCHUNKSZ	4096	/* #bytes per bitmap chunk  (do not change)  */
+
+#define SPCMINBLK	100	/* space threshold to give warning messages  */
+#define SPCDFLINTVL	16	/* once every SPCDFLINTVL writes to cowfile, */
+				/* available space in filesystem is checked  */
+
+#define	CALCMAP(x)	((x)/(MAPCHUNKSZ*8))
+#define	CALCBYTE(x)	(((x)%(MAPCHUNKSZ*8))>>3)
+#define	CALCBIT(x)	((x)&7)
+
+#define ALLCOW		1
+#define ALLRDO		2
+#define MIXEDUP		3
+
+static char	allzeroes[MAPUNIT];
+
+/*
+** administration per cowdevice (pair of cowfile/rdofile)
+*/
+
+/* bit-values for state */
+#define	COWDEVOPEN	0x01	/* cowdevice opened                          */
+#define	COWRWCOWOPEN	0x02	/* cowfile opened read-write                 */
+#define	COWRDCOWOPEN	0x04	/* cowfile opened read-only                  */
+#define	COWWATCHDOG	0x08 	/* ioctl for watchdog cowfile space active   */
+
+#define	COWCOWOPEN	(COWRWCOWOPEN|COWRDCOWOPEN)
+
+struct cowloop_device
+{
+	/*
+	** current status
+	*/
+	int		state;			/* bit-values (see above)    */
+	int		opencnt;		/* # opens for cowdevice     */
+
+        /*
+	** open file pointers
+	*/
+        struct file  	*rdofp,   *cowfp;	/* open file pointers        */
+	char		*rdoname, *cowname;	/* file names                */
+
+	/*
+	** request queue administration
+	*/
+	struct request_queue	*rqueue;
+	spinlock_t		rqlock;
+	struct gendisk		*gd;
+
+	/*
+	** administration about read-only file
+	*/
+	unsigned int	     numblocks;	/* # blocks input file in MAPUNIT    */
+	unsigned int	     blocksz;   /* minimum unit to access this dev   */
+	unsigned long	     fingerprint; /* fingerprint of current rdofile  */
+	struct block_device  *belowdev;	/* block device below us             */
+	struct gendisk       *belowgd;  /* gendisk for blk dev below us      */
+	struct request_queue *belowq;	/* req. queue of blk dev below us    */
+
+	/*
+	** bitmap administration to register which blocks are modified
+	*/
+	long int	mapsize;	/* total size of bitmap (bytes)      */
+	long int	mapremain;	/* remaining bytes in last bitmap    */
+	int		mapcount;       /* number of bitmaps in use          */
+	char 		**mapcache;	/* area with pointers to bitmaps     */
+
+	char		*iobuf;		/* databuffer of MAPUNIT bytes       */
+	struct cowhead	*cowhead;	/* buffer containing cowhead         */
+
+	/*
+	** administration for interface with the kernel-thread
+	*/
+	int		pid;		/* pid==0: no thread available       */
+	struct request	*req;		/* request to be handled now         */
+	wait_queue_head_t waitq;	/* wait-Q: thread waits for work     */
+	char		closedown;	/* boolean: thread exit required     */
+	char		qfilled;	/* boolean: I/O request pending      */
+	char		iobusy;		/* boolean: req under treatment      */
+
+	/*
+	** administration to keep track of free space in cowfile filesystem
+	*/
+	unsigned long	blksize;	/* block size of fs (bytes)          */
+	unsigned long	blktotal;	/* recent total space in fs (blocks) */
+	unsigned long	blkavail;	/* recent free  space in fs (blocks) */
+
+	wait_queue_head_t watchq;	/* wait-Q: watcher awaits threshold  */
+	unsigned long	watchthresh;	/* threshold of watcher (blocks)     */
+
+	/*
+	** statistical counters
+	*/
+	unsigned long	rdoreads;	/* number of  read-actions rdo       */
+	unsigned long	cowreads;	/* number of  read-actions cow       */
+	unsigned long	cowwrites;	/* number of write-actions           */
+	unsigned long	nrcowblocks;	/* number of blocks in use on cow    */
+};
+
+static struct cowloop_device	**cowdevall;	/* ptr to ptrs to all cowdevices */
+static struct semaphore 	cowdevlock;	/* generic lock for cowdevs      */
+
+static struct gendisk		*cowctlgd;	/* gendisk control channel       */
+static spinlock_t		cowctlrqlock;   /* for req.q. of ctrl. channel   */
+
+/*
+** private directory /proc/cow
+*/
+struct proc_dir_entry	*cowlo_procdir;
+
+/*
+** function prototypes
+*/
+static long int cowlo_do_request (struct request *req);
+static void	cowlo_sync       (void);
+static int	cowlo_checkio    (struct cowloop_device *,         int, loff_t);
+static int	cowlo_readmix    (struct cowloop_device *, void *, int, loff_t);
+static int	cowlo_writemix   (struct cowloop_device *, void *, int, loff_t);
+static long int cowlo_readrdo    (struct cowloop_device *, void *, int, loff_t);
+static long int cowlo_readcow    (struct cowloop_device *, void *, int, loff_t);
+static long int cowlo_readcowraw (struct cowloop_device *, void *, int, loff_t);
+static long int cowlo_writecow   (struct cowloop_device *, void *, int, loff_t);
+static long int cowlo_writecowraw(struct cowloop_device *, void *, int, loff_t);
+static int      cowlo_ioctl      (struct block_device *, fmode_t,
+           			 		unsigned int, unsigned long);
+static int	cowlo_makepair    (struct cowpair __user *);
+static int	cowlo_removepair  (unsigned long  __user *);
+static int	cowlo_watch       (struct cowpair __user *);
+static int	cowlo_cowctl      (unsigned long  __user *, int);
+static int	cowlo_openpair    (char *, char *, int, int);
+static int 	cowlo_closepair   (struct cowloop_device *);
+static int	cowlo_openrdo     (struct cowloop_device *, char *);
+static int	cowlo_opencow     (struct cowloop_device *, char *, int);
+static void	cowlo_undo_openrdo(struct cowloop_device *);
+static void	cowlo_undo_opencow(struct cowloop_device *);
+
+/*****************************************************************************/
+/* System call handling                                                      */
+/*****************************************************************************/
+
+/*
+** handle system call open()/mount()
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int cowlo_open(struct block_device *bdev, fmode_t mode)
+{
+	struct inode *inode = bdev->bd_inode;
+
+	if (!inode)
+		return -EINVAL;
+
+	if (imajor(inode) != COWMAJOR) {
+		printk(KERN_WARNING
+		       "cowloop - unexpected major %d\n", imajor(inode));
+		return -ENODEV;
+	}
+
+	switch (iminor(inode)) {
+	   case COWCTL:
+		DEBUGP(DCOW"cowloop - open %d control\n", COWCTL);
+		break;
+
+	   default:
+		DEBUGP(DCOW"cowloop - open minor %d\n", iminor(inode));
+
+		if ( iminor(inode) >= maxcows )
+			return -ENODEV;
+
+		if ( !((cowdevall[iminor(inode)])->state & COWDEVOPEN) )
+			return -ENODEV;
+
+		(cowdevall[iminor(inode)])->opencnt++;
+	}
+
+	return 0;
+}
+
+/*
+** handle system call close()/umount()
+**
+** returns:
+** 	0   - okay
+*/
+static int cowlo_release(struct gendisk *gd, fmode_t mode)
+{
+	struct block_device *bdev;
+	struct inode *inode;
+
+	bdev = bdget_disk(gd, 0);
+	inode = bdev->bd_inode;
+	if (!inode)
+		return 0;
+
+	DEBUGP(DCOW"cowloop - release (close) minor %d\n", iminor(inode));
+
+	if ( iminor(inode) != COWCTL)
+		(cowdevall[iminor(inode)])->opencnt--;
+
+	return 0;
+}
+
+/*
+** handle system call ioctl()
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int cowlo_ioctl(struct block_device *bdev, fmode_t mode,
+		       unsigned int cmd, unsigned long arg)
+{
+	struct hd_geometry	geo;
+	struct inode *inode = bdev->bd_inode;
+
+	DEBUGP(DCOW "cowloop - ioctl cmd %x\n", cmd);
+
+	switch ( iminor(inode) ) {
+
+	   /*
+	   ** allowed via control device only
+	   */
+	   case COWCTL:
+		switch (cmd) {
+		   /*
+		   ** write all bitmap chunks and cowheaders to cowfiles
+		   */
+		   case COWSYNC:
+			down(&cowdevlock);
+			cowlo_sync();
+			up(&cowdevlock);
+			return 0;
+
+		   /*
+		   ** open a new cowdevice (pair of rdofile/cowfile)
+		   */
+		   case COWMKPAIR:
+			return cowlo_makepair((void __user *)arg);
+
+		   /*
+		   ** close a cowdevice (pair of rdofile/cowfile)
+		   */
+		   case COWRMPAIR:
+			return cowlo_removepair((void __user *)arg);
+
+		   /*
+		   ** watch free space of filesystem containing cowfile
+		   */
+		   case COWWATCH:
+			return cowlo_watch((void __user *)arg);
+
+		   /*
+		   ** close cowfile for active device
+		   */
+		   case COWCLOSE:
+			return cowlo_cowctl((void __user *)arg, COWCLOSE);
+
+		   /*
+		   ** reopen cowfile read-only for active device
+		   */
+		   case COWRDOPEN:
+			return cowlo_cowctl((void __user *)arg, COWRDOPEN);
+
+		   default:
+			return -EINVAL;
+		} /* end of switch on command */
+
+	   /*
+	   ** allowed for any other cowdevice
+	   */
+	   default:
+		switch (cmd) {
+		   /*
+		   ** HDIO_GETGEO must be supported for fdisk, etc
+		   */
+		   case HDIO_GETGEO:
+			geo.cylinders = 0;
+			geo.heads     = 0;
+			geo.sectors   = 0;
+
+			if (copy_to_user((void __user *)arg, &geo, sizeof geo))
+				return -EFAULT;
+			return 0;
+
+		   default:
+			return -EINVAL;
+		} /* end of switch on ioctl-cmd code parameter */
+	} /* end of switch on minor number */
+}
+
+static struct block_device_operations cowlo_fops =
+{
+	.owner	 =     THIS_MODULE,
+        .open    =     cowlo_open,	/* called upon open  */
+        .release =     cowlo_release,	/* called upon close */
+        .ioctl   =     cowlo_ioctl,     /* called upon ioctl */
+};
+
+/*
+** handle ioctl-command COWMKPAIR:
+**	open a new cowdevice (pair of rdofile/cowfile) on-the-fly
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_makepair(struct cowpair __user *arg)
+{
+	int		i, rv=0;
+	struct cowpair	cowpair;
+	unsigned char	*cowpath;
+	unsigned char	*rdopath;
+
+	/*
+	** retrieve info about pathnames
+	*/
+	if ( copy_from_user(&cowpair, arg, sizeof cowpair) )
+		return -EFAULT;
+
+	if ( (MAJOR(cowpair.device) != COWMAJOR) && (cowpair.device != ANYDEV) )
+		return -EINVAL;
+
+	if ( (MINOR(cowpair.device) >= maxcows)  && (cowpair.device != ANYDEV) )
+		return -EINVAL;
+
+	/*
+	** retrieve pathname strings
+	*/
+	if ( (cowpair.cowflen > PATH_MAX) || (cowpair.rdoflen > PATH_MAX) )
+		return -ENAMETOOLONG;
+
+	if ( !(cowpath = kmalloc(cowpair.cowflen+1, GFP_KERNEL)) )
+		return -ENOMEM;
+
+	if ( copy_from_user(cowpath, (void __user *)cowpair.cowfile,
+	                                            cowpair.cowflen) ) {
+		kfree(cowpath);
+		return -EFAULT;
+	}
+	*(cowpath+cowpair.cowflen) = 0;
+
+	if ( !(rdopath = kmalloc(cowpair.rdoflen+1, GFP_KERNEL)) ) {
+		kfree(cowpath);
+		return -ENOMEM;
+	}
+
+	if ( copy_from_user(rdopath, (void __user *)cowpair.rdofile,
+	                                            cowpair.rdoflen) ) {
+		kfree(rdopath);
+		kfree(cowpath);
+		return -EFAULT;
+	}
+	*(rdopath+cowpair.rdoflen) = 0;
+
+	/*
+	** open new cowdevice
+	*/
+	if ( cowpair.device == ANYDEV) {
+		/*
+		** search first unused minor
+		*/
+		for (i=0, rv=-EBUSY; i < maxcows; i++) {
+			if ( !((cowdevall[i])->state & COWDEVOPEN) ) {
+				rv = cowlo_openpair(rdopath, cowpath, 0, i);
+				break;
+			}
+		}
+
+		if (rv) { 		/* open failed? */
+			kfree(rdopath);
+			kfree(cowpath);
+			return rv;
+		}
+
+		/*
+		** return newly allocated cowdevice to user space
+		*/
+		cowpair.device = MKDEV(COWMAJOR, i);
+
+		if ( copy_to_user(arg, &cowpair, sizeof cowpair)) {
+			kfree(rdopath);
+			kfree(cowpath);
+			return -EFAULT;
+		}
+	} else { 		/* specific minor requested */
+		if ( (rv = cowlo_openpair(rdopath, cowpath, 0,
+						MINOR(cowpair.device)))) {
+			kfree(rdopath);
+			kfree(cowpath);
+			return rv;
+		}
+	}
+
+	return 0;
+}
+
+/*
+** handle ioctl-command COWRMPAIR:
+** 	deactivate an existing cowdevice (pair of rdofile/cowfile) on-the-fly
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_removepair(unsigned long __user *arg)
+{
+	unsigned long		cowdevice;
+	struct cowloop_device	*cowdev;
+
+	/*
+	** retrieve info about device to be removed
+	*/
+	if ( copy_from_user(&cowdevice, arg, sizeof cowdevice))
+		return -EFAULT;
+
+	/*
+	** verify major-minor number
+	*/
+	if ( MAJOR(cowdevice) != COWMAJOR)
+		return -EINVAL;
+
+	if ( MINOR(cowdevice) >= maxcows)
+		return -EINVAL;
+
+	cowdev = cowdevall[MINOR(cowdevice)];
+
+	if ( !(cowdev->state & COWDEVOPEN) )
+		return -ENODEV;
+
+	/*
+	** synchronize bitmaps and close cowdevice
+	*/
+	if (cowdev->state & COWRWCOWOPEN) {
+		down(&cowdevlock);
+		cowlo_sync();
+		up(&cowdevlock);
+	}
+
+	return cowlo_closepair(cowdev);
+}
+
+/*
+** handle ioctl-command COWWATCH:
+**	watch the free space of the filesystem containing a cowfile
+**      of an open cowdevice
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_watch(struct cowpair __user *arg)
+{
+	struct cowloop_device	*cowdev;
+	struct cowwatch		cowwatch;
+
+	/*
+	** retrieve structure holding info
+	*/
+	if ( copy_from_user(&cowwatch, arg, sizeof cowwatch))
+		return -EFAULT;
+
+	/*
+	** verify if cowdevice exists and is currently open
+	*/
+	if ( MINOR(cowwatch.device) >= maxcows)
+		return -EINVAL;
+
+	cowdev = cowdevall[MINOR(cowwatch.device)];
+
+	if ( !(cowdev->state & COWDEVOPEN) )
+		return -ENODEV;
+
+	/*
+	** if the WATCHWAIT-option is set, wait until the indicated
+	** threshold is reached (only one waiter allowed)
+	*/
+	if (cowwatch.flags & WATCHWAIT) {
+		/*
+		** check if already another waiter active
+		** for this cowdevice
+		*/
+		if (cowdev->state & COWWATCHDOG)
+			return -EAGAIN;
+
+		cowdev->state |= COWWATCHDOG;
+
+		cowdev->watchthresh = (unsigned long long)
+		                      cowwatch.threshold /
+				      (cowdev->blksize / 1024);
+
+		if (wait_event_interruptible(cowdev->watchq,
+		                    cowdev->watchthresh >= cowdev->blkavail)) {
+			cowdev->state &= ~COWWATCHDOG;
+			return EINTR;
+		}
+
+		cowdev->state &= ~COWWATCHDOG;
+	}
+
+	cowwatch.totalkb = (unsigned long long)cowdev->blktotal *
+	                                       cowdev->blksize / 1024;
+	cowwatch.availkb = (unsigned long long)cowdev->blkavail *
+	                                       cowdev->blksize / 1024;
+
+	if ( copy_to_user(arg, &cowwatch, sizeof cowwatch))
+		return -EFAULT;
+
+	return 0;
+}
+
+/*
+** handle ioctl-commands COWCLOSE and COWRDOPEN:
+**	COWCLOSE  - close the cowfile while the cowdevice remains open;
+**                  this allows an unmount of the filesystem on which
+**                  the cowfile resides
+**	COWRDOPEN - close the cowfile and reopen it for read-only;
+**                  this allows a remount read-ony of the filesystem
+**                  on which the cowfile resides
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_cowctl(unsigned long __user *arg, int cmd)
+{
+	struct cowloop_device	*cowdev;
+	unsigned long		cowdevice;
+
+	/*
+	** retrieve info about device to be removed
+	*/
+	if ( copy_from_user(&cowdevice, arg, sizeof cowdevice))
+		return -EFAULT;
+
+	/*
+	** verify major-minor number
+	*/
+	if ( MAJOR(cowdevice) != COWMAJOR)
+		return -EINVAL;
+
+	if ( MINOR(cowdevice) >= maxcows)
+		return -EINVAL;
+
+	cowdev = cowdevall[MINOR(cowdevice)];
+
+	if ( !(cowdev->state & COWDEVOPEN) )
+		return -ENODEV;
+
+	/*
+	** synchronize bitmaps and close cowfile
+	*/
+	if (cowdev->state & COWRWCOWOPEN) {
+		down(&cowdevlock);
+		cowlo_sync();
+		up(&cowdevlock);
+	}
+
+	/*
+	** handle specific ioctl-command
+	*/
+	switch (cmd) {
+	   case COWRDOPEN:
+		/*
+		** if the cowfile is still opened read-write
+		*/
+		if (cowdev->state & COWRWCOWOPEN) {
+			/*
+			** close the cowfile
+			*/
+  			if (cowdev->cowfp)
+		  		filp_close(cowdev->cowfp, 0);
+
+			cowdev->state &= ~COWRWCOWOPEN;
+
+			/*
+			** open again for read-only
+			*/
+			cowdev->cowfp = filp_open(cowdev->cowname,
+		                          O_RDONLY|O_LARGEFILE, 0600);
+
+			if ( (cowdev->cowfp == NULL) || IS_ERR(cowdev->cowfp) ) {
+				printk(KERN_ERR
+				     "cowloop - failed to reopen cowfile %s\n",
+				     cowdev->cowname);
+				return -EINVAL;
+			}
+
+			/*
+			** mark cowfile open for read-only
+			*/
+			cowdev->state |= COWRDCOWOPEN;
+		} else {
+			return -EINVAL;
+		}
+		break;
+
+	   case COWCLOSE:
+		/*
+		** if the cowfile is still open
+		*/
+		if (cowdev->state & COWCOWOPEN) {
+			/*
+			** close the cowfile
+			*/
+  			if (cowdev->cowfp)
+		  		filp_close(cowdev->cowfp, 0);
+
+			cowdev->state &= ~COWCOWOPEN;
+		}
+	}
+
+	return 0;
+}
+
+
+/*****************************************************************************/
+/* Handling of I/O-requests for a cowdevice                                  */
+/*****************************************************************************/
+
+/*
+** function to be called by core-kernel to handle the I/O-requests
+** in the queue
+*/
+static void cowlo_request(struct request_queue *q)
+{
+	struct request		*req;
+	struct cowloop_device	*cowdev;
+
+	DEBUGP(DCOW "cowloop - request function called....\n");
+
+	while((req = blk_peek_request(q)) != NULL) {
+		DEBUGP(DCOW "cowloop - got next request\n");
+
+		if (! blk_fs_request(req)) {
+               		 /* this is not a normal file system request */
+                	__blk_end_request_cur(req, -EIO);
+                	continue;
+        	}
+		cowdev = req->rq_disk->private_data;
+
+		if (cowdev->iobusy)
+			return;
+		else
+			cowdev->iobusy = 1;
+
+		/*
+		** when no kernel-thread is available, the request will
+		** produce an I/O-error
+		*/
+		if (!cowdev->pid) {
+			printk(KERN_ERR"cowloop - no thread available\n");
+			__blk_end_request_cur(req, -EIO);	/* request failed */
+			cowdev->iobusy	= 0;
+			continue;
+		}
+
+		/*
+		** handle I/O-request in the context of the kernel-thread
+		*/
+		cowdev->req 	= req;
+		cowdev->qfilled	= 1;
+
+		wake_up_interruptible_sync(&cowdev->waitq);
+
+		/*
+		** get out of this function now while the I/O-request is
+		** under treatment of the kernel-thread; this function
+		** will be called again after the current I/O-request has
+		** been finished by the thread
+		*/
+		return;
+	}
+}
+
+/*
+** daemon-process (kernel-thread) executes this function
+*/
+static int
+cowlo_daemon(struct cowloop_device *cowdev)
+{
+	int	rv;
+	int     minor;
+	char	myname[16];
+
+	for (minor = 0; minor < maxcows; minor++) {
+		if (cowdev == cowdevall[minor]) break;
+	}
+	sprintf(myname, "cowloopd%d", minor);
+
+        daemonize(myname);
+
+	while (!cowdev->closedown) {
+		/*
+		** sleep while waiting for an I/O request;
+		** note that no non-interruptible wait has been used
+		** because the non-interruptible version of
+		** a *synchronous* wake_up does not exist (any more)
+		*/
+		if (wait_event_interruptible(cowdev->waitq, cowdev->qfilled)){
+			flush_signals(current); /* ignore signal-based wakeup */
+			continue;
+		}
+
+		if (cowdev->closedown)		/* module will be unloaded ? */{
+			cowdev->pid = 0;
+			return 0;
+		}
+
+		/*
+		** woken up by the I/O-request handler:	treat requested I/O
+		*/
+		cowdev->qfilled = 0;
+
+		rv = cowlo_do_request(cowdev->req);
+
+		/*
+		** reacquire the queue-spinlock for manipulating
+		** the request-queue and dequeue the request
+		*/
+		spin_lock_irq(&cowdev->rqlock);
+
+		__blk_end_request_cur(cowdev->req, rv);
+		cowdev->iobusy = 0;
+
+		/*
+		** initiate the next request from the queue
+		*/
+		cowlo_request(cowdev->rqueue);
+
+		spin_unlock_irq(&cowdev->rqlock);
+	}
+	return 0;
+}
+
+/*
+** function to be called in the context of the kernel thread
+** to handle the queued I/O-requests
+**
+** returns:
+** 	0   - fail
+**      1   - success
+*/
+static long int
+cowlo_do_request(struct request *req)
+{
+	unsigned long		len;
+	long int		rv;
+	loff_t 			offset;
+	struct cowloop_device	*cowdev = req->rq_disk->private_data;
+
+	/*
+	** calculate some variables which are needed later on
+	*/
+	len     =          blk_rq_cur_sectors(req) << 9;
+	offset  = (loff_t) blk_rq_pos(req)         << 9;
+
+	DEBUGP(DCOW"cowloop - req cmd=%d offset=%lld len=%lu addr=%p\n",
+				*(req->cmd), offset, len, req->buffer);
+
+	/*
+	** handle READ- or WRITE-request
+	*/
+	switch (rq_data_dir(req)) {
+	   /**********************************************************/
+	   case READ:
+		switch ( cowlo_checkio(cowdev, len, offset) ) {
+		   case ALLCOW:
+			rv = cowlo_readcow(cowdev, req->buffer, len, offset);
+			break;
+
+		   case ALLRDO:
+			rv = cowlo_readrdo(cowdev, req->buffer, len, offset);
+			break;
+
+	   	   case MIXEDUP:
+			rv = cowlo_readmix(cowdev, req->buffer, len, offset);
+			break;
+
+		   default:
+			rv = 0;	/* never happens */
+		}
+		break;
+
+	   /**********************************************************/
+	   case WRITE:
+		switch ( cowlo_checkio(cowdev, len, offset) ) {
+		   case ALLCOW:
+			/*
+			** straight-forward write will do...
+			*/
+			DEBUGP(DCOW"cowloop - write straight ");
+
+			rv = cowlo_writecow(cowdev, req->buffer, len, offset);
+			break;	/* from switch */
+
+		   case ALLRDO:
+			if ( (len & MUMASK) == 0) {
+				DEBUGP(DCOW"cowloop - write straight ");
+
+				rv = cowlo_writecow(cowdev, req->buffer,
+								len, offset);
+				break;
+			}
+
+	   	   case MIXEDUP:
+			rv = cowlo_writemix(cowdev, req->buffer, len, offset);
+			break;
+
+		   default:
+			rv = 0;	/* never happens */
+		}
+		break;
+
+	   default:
+		printk(KERN_ERR
+		       "cowloop - unrecognized command %d\n", *(req->cmd));
+		rv = 0;
+	}
+
+	return (rv <= 0 ? 0 : 1);
+}
+
+/*
+** check for a given I/O-request if all underlying blocks
+** (with size MAPUNIT) are either in the read-only file or in
+** the cowfile (or a combination of the two)
+**
+** returns:
+** 	ALLRDO  - all underlying blocks in rdofile
+**      ALLCOW  - all underlying blocks in cowfile
+**      MIXEDUP - underlying blocks partly in rdofile and partly in cowfile
+*/
+static int
+cowlo_checkio(struct cowloop_device *cowdev, int len, loff_t offset)
+{
+	unsigned long	mapnum, bytenum, bitnum, blocknr, partlen;
+	long int	totcnt, cowcnt;
+	char		*mc;
+
+	/*
+	** notice that the requested block might cross
+	** a blocksize boundary while one of the concerned
+	** blocks resides in the read-only file and another
+	** one in the copy-on-write file; in that case the
+        ** request will be broken up into pieces
+	*/
+	if ( (len <= MAPUNIT) &&
+	     (MAPUNIT - (offset & MUMASK) <= len) ) {
+		/*
+		** easy situation:
+		** requested data-block entirely fits within
+		** the mapunit used for the bitmap
+		** check if that block is located in rdofile or
+		** cowfile
+		*/
+		blocknr = offset >> MUSHIFT;
+
+		mapnum  = CALCMAP (blocknr);
+		bytenum = CALCBYTE(blocknr);
+		bitnum  = CALCBIT (blocknr);
+
+		if (*(*(cowdev->mapcache+mapnum)+bytenum)&(1<<bitnum))
+			return ALLCOW;
+		else
+			return ALLRDO;
+	}
+
+	/*
+	** less easy situation:
+	** the requested data-block does not fit within the mapunit
+	** used for the bitmap
+	** check if *all* underlying blocks involved reside on the rdofile
+       	** or the cowfile (so still no breakup required)
+	*/
+	for (cowcnt=totcnt=0; len > 0; len-=partlen, offset+=partlen, totcnt++){
+		/*
+		** calculate blocknr of involved block
+		*/
+		blocknr = offset >> MUSHIFT;
+
+		/*
+		** calculate partial length for this transfer
+		*/
+		partlen = MAPUNIT - (offset & MUMASK);
+		if (partlen > len)
+			partlen = len;
+
+		/*
+		** is this block located in the cowfile
+		*/
+		mapnum  = CALCMAP (blocknr);
+		bytenum = CALCBYTE(blocknr);
+		bitnum  = CALCBIT (blocknr);
+
+		mc	= *(cowdev->mapcache+mapnum);
+
+		if (*(mc+bytenum)&(1<<bitnum))
+			cowcnt++;;
+
+		DEBUGP(DCOW
+		       "cowloop - check %lu - map %lu, byte %lu, bit %lu, "
+		       "cowcnt %ld, totcnt %ld %02x %p\n",
+			blocknr, mapnum, bytenum, bitnum, cowcnt, totcnt,
+			*(mc+bytenum), mc);
+	}
+
+	if (cowcnt == 0)	/* all involved blocks on rdofile? */
+		return ALLRDO;
+
+	if (cowcnt == totcnt)	/* all involved blocks on cowfile? */
+		return ALLCOW;
+
+	/*
+	** situation somewhat more complicated:
+	** involved underlying blocks spread over both files
+	*/
+	return MIXEDUP;
+}
+
+/*
+** read requested chunk partly from rdofile and partly from cowfile
+**
+** returns:
+** 	0   - fail
+**      1   - success
+*/
+static int
+cowlo_readmix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
+{
+	unsigned long	mapnum, bytenum, bitnum, blocknr, partlen;
+	long int	rv;
+	char		*mc;
+
+	/*
+	** complicated approach: breakup required of read-request
+	*/
+	for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) {
+		/*
+		** calculate blocknr of entire block
+		*/
+		blocknr = offset >> MUSHIFT;
+
+		/*
+		** calculate partial length for this transfer
+		*/
+		partlen = MAPUNIT - (offset & MUMASK);
+		if (partlen > len)
+			partlen = len;
+
+		/*
+		** is this block located in the cowfile
+		*/
+		mapnum  = CALCMAP (blocknr);
+		bytenum = CALCBYTE(blocknr);
+		bitnum  = CALCBIT (blocknr);
+		mc	= *(cowdev->mapcache+mapnum);
+
+		if (*(mc+bytenum)&(1<<bitnum)) {
+			/*
+			** read (partial) block from cowfile
+			*/
+			DEBUGP(DCOW"cowloop - split read "
+				"cow partlen=%ld off=%lld\n", partlen, offset);
+
+			if (cowlo_readcow(cowdev, buf, partlen, offset) <= 0)
+				rv = 0;
+		} else {
+			/*
+			** read (partial) block from rdofile
+			*/
+			DEBUGP(DCOW"cowloop - split read "
+				"rdo partlen=%ld off=%lld\n", partlen, offset);
+
+			if (cowlo_readrdo(cowdev, buf, partlen, offset) <= 0)
+				rv = 0;
+		}
+	}
+
+	return rv;
+}
+
+/*
+** chunk to be written to the cowfile needs pieces to be
+** read from the rdofile
+**
+** returns:
+** 	0   - fail
+**      1   - success
+*/
+static int
+cowlo_writemix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
+{
+	unsigned long	mapnum, bytenum, bitnum, blocknr, partlen;
+	long int	rv;
+	char		*mc;
+
+	/*
+	** somewhat more complicated stuff is required:
+	** if the request is larger than one underlying
+	** block or is spread over two underlying blocks,
+	** split the request into pieces; if a block does not
+	** start at a block boundary, take care that
+	** surrounding data is read first (if needed),
+	** fit the new data in and write it as a full block
+	*/
+	for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) {
+		/*
+		** calculate partial length for this transfer
+		*/
+		partlen = MAPUNIT - (offset & MUMASK);
+		if (partlen > len)
+			partlen = len;
+
+		/*
+		** calculate blocknr of entire block
+		*/
+		blocknr = offset >> MUSHIFT;
+
+		/*
+		** has this block been written before?
+		*/
+		mapnum  = CALCMAP (blocknr);
+		bytenum = CALCBYTE(blocknr);
+		bitnum  = CALCBIT (blocknr);
+		mc	= *(cowdev->mapcache+mapnum);
+
+		if (*(mc+bytenum)&(1<<bitnum)) {
+			/*
+			** block has been written before;
+			** write transparantly to cowfile
+			*/
+			DEBUGP(DCOW
+			       "cowloop - splitwr transp\n");
+
+			if (cowlo_writecow(cowdev, buf, partlen, offset) <= 0)
+				rv = 0;
+		} else {
+			/*
+			** block has never been written before,
+			** so read entire block from
+			** read-only file first, unless
+			** a full block is requested to
+			** be written
+			*/
+			if (partlen < MAPUNIT) {
+				if (cowlo_readrdo(cowdev, cowdev->iobuf,
+				      MAPUNIT, (loff_t)blocknr << MUSHIFT) <= 0)
+					rv = 0;
+			}
+
+			/*
+			** transfer modified part into
+			** the block just read
+			*/
+			memcpy(cowdev->iobuf + (offset & MUMASK), buf, partlen);
+
+			/*
+			** write entire block to cowfile
+			*/
+			DEBUGP(DCOW"cowloop - split "
+				"partlen=%ld off=%lld\n",
+				partlen, (loff_t)blocknr << MUSHIFT);
+
+			if (cowlo_writecow(cowdev, cowdev->iobuf, MAPUNIT,
+					     (loff_t)blocknr << MUSHIFT) <= 0)
+				rv = 0;
+		}
+	}
+
+	return rv;
+}
+
+/*****************************************************************************/
+/* I/O-support for read-only file and copy-on-write file                     */
+/*****************************************************************************/
+
+/*
+** read data from the read-only file
+**
+** return-value: similar to user-mode read
+*/
+static long int
+cowlo_readrdo(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
+{
+	long int	rv;
+	mm_segment_t	old_fs;
+	loff_t		saveoffset = offset;
+
+	DEBUGP(DCOW"cowloop - readrdo called\n");
+
+        old_fs = get_fs();
+	set_fs( get_ds() );
+	rv = cowdev->rdofp->f_op->read(cowdev->rdofp, buf, len, &offset);
+        set_fs(old_fs);
+
+	if (rv < len) {
+		printk(KERN_WARNING "cowloop - read-failure %ld on rdofile"
+		                    "- offset=%lld len=%d\n",
+					rv, saveoffset, len);
+	}
+
+	cowdev->rdoreads++;
+	return rv;
+}
+
+/*
+** read cowfile from a modified offset, i.e. skipping the bitmap and cowhead
+**
+** return-value: similar to user-mode read
+*/
+static long int
+cowlo_readcow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
+{
+	DEBUGP(DCOW"cowloop - readcow called\n");
+
+	offset += cowdev->cowhead->doffset;
+
+	return cowlo_readcowraw(cowdev, buf, len, offset);
+}
+
+/*
+** read cowfile from an absolute offset
+**
+** return-value: similar to user-mode read
+*/
+static long int
+cowlo_readcowraw(struct cowloop_device *cowdev,
+					void *buf, int len, loff_t offset)
+{
+	long int	rv;
+	mm_segment_t	old_fs;
+	loff_t		saveoffset = offset;
+
+	DEBUGP(DCOW"cowloop - readcowraw called\n");
+
+	/*
+	** be sure that cowfile is opened for read-write
+	*/
+	if ( !(cowdev->state & COWCOWOPEN) ) {
+		 printk(KERN_WARNING
+		        "cowloop - read request from cowfile refused\n");
+
+		return -EBADF;
+	}
+
+	/*
+	** issue low level read
+	*/
+        old_fs = get_fs();
+	set_fs( get_ds() );
+	rv = cowdev->cowfp->f_op->read(cowdev->cowfp, buf, len, &offset);
+        set_fs(old_fs);
+
+	if (rv < len) {
+		printk(KERN_WARNING
+		       "cowloop - read-failure %ld on cowfile"
+		       "- offset=%lld len=%d\n", rv, saveoffset, len);
+	}
+
+	cowdev->cowreads++;
+	return rv;
+}
+
+/*
+** write cowfile from a modified offset, i.e. skipping the bitmap and cowhead
+**
+** if a block is written for the first time while its contents consists
+** of binary zeroes only, the concerning bitmap is flushed to the cowfile
+**
+** return-value: similar to user-mode write
+*/
+static long int
+cowlo_writecow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
+{
+	long int	rv;
+	unsigned long	mapnum=0, mapbyte=0, mapbit=0, cowblock=0, partlen;
+	char		*tmpptr,  *mapptr = NULL;
+	loff_t		tmpoffset, mapoffset = 0;
+
+	DEBUGP(DCOW"cowloop - writecow called\n");
+
+	/*
+	** be sure that cowfile is opened for read-write
+	*/
+	if ( !(cowdev->state & COWRWCOWOPEN) ) {
+		 printk(KERN_WARNING
+		        "cowloop - Write request to cowfile refused\n");
+
+		return -EBADF;
+	}
+
+	/*
+	** write the entire block to the cowfile
+	*/
+	tmpoffset = offset + cowdev->cowhead->doffset;
+
+	rv = cowlo_writecowraw(cowdev, buf, len, tmpoffset);
+
+	/*
+	** verify if enough space available on filesystem holding
+	** the cowfile
+	**   - when the last write failed (might be caused by lack of space)
+	**   - when a watcher is active (to react adequatly)
+	**   - when the previous check indicated fs was almost full
+	**   - with regular intervals
+	*/
+	if ( (rv <= 0)				       ||
+	     (cowdev->state        & COWWATCHDOG)      ||
+	     (cowdev->blkavail / 2 < SPCDFLINTVL)      ||
+	     (cowdev->cowwrites    % SPCDFLINTVL == 0) ) {
+		struct kstatfs		ks;
+
+		if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0){
+			if (ks.f_bavail <= SPCMINBLK) {
+				switch (ks.f_bavail) {
+				   case 0:
+				   case 1:
+				   case 2:
+				   case 3:
+					printk(KERN_ALERT
+					       "cowloop - "
+					       "ALERT: cowfile full!\n");
+					break;
+
+				   default:
+					printk(KERN_WARNING
+					       "cowloop - cowfile almost "
+					       "full (only %llu Kb free)\n",
+						(unsigned long long)
+                                                ks.f_bsize * ks.f_bavail /1024);
+				}
+			}
+
+			cowdev->blktotal = ks.f_blocks;
+			cowdev->blkavail = ks.f_bavail;
+
+			/*
+			** wakeup watcher if threshold has been reached
+			*/
+			if ( (cowdev->state & COWWATCHDOG) &&
+			    (cowdev->watchthresh >= cowdev->blkavail) ) {
+				wake_up_interruptible(&cowdev->watchq);
+			}
+		}
+	}
+
+	if (rv <= 0)
+		return rv;
+
+	DEBUGP(DCOW"cowloop - block written\n");
+
+	/*
+	** check if block(s) is/are written to the cowfile
+	** for the first time; if so, adapt the bitmap
+	*/
+	for (; len > 0; len-=partlen, offset+=partlen, buf+=partlen) {
+		/*
+		** calculate partial length for this transfer
+		*/
+		partlen = MAPUNIT - (offset & MUMASK);
+		if (partlen > len)
+			partlen = len;
+
+		/*
+		** calculate bitnr of written chunk of cowblock
+		*/
+		cowblock = offset >> MUSHIFT;
+
+		mapnum   = CALCMAP (cowblock);
+		mapbyte  = CALCBYTE(cowblock);
+		mapbit   = CALCBIT (cowblock);
+
+		if (*(*(cowdev->mapcache+mapnum)+mapbyte) & (1<<mapbit))
+			continue;	/* already written before */
+
+	       	/*
+		** if the block is written for the first time,
+		** the corresponding bit should be set in the bitmap
+		*/
+		*(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit);
+
+		cowdev->nrcowblocks++;
+
+		DEBUGP(DCOW"cowloop - bitupdate blk=%ld map=%ld "
+		        "byte=%ld bit=%ld\n",
+			cowblock, mapnum, mapbyte, mapbit);
+
+		/*
+		** check if the cowhead in the cowfile is currently
+		** marked clean; if so, mark it dirty and flush it
+		*/
+		if ( !(cowdev->cowhead->flags &= COWDIRTY)) {
+			cowdev->cowhead->flags	|= COWDIRTY;
+
+			cowlo_writecowraw(cowdev, cowdev->cowhead,
+							MAPUNIT, (loff_t)0);
+		}
+
+		/*
+		** if the written datablock contained binary zeroes,
+		** the bitmap block should be marked to be flushed to disk
+		** (blocks containing all zeroes cannot be recovered by
+		** the cowrepair-program later on if cowloop is not properly
+		** removed via rmmod)
+		*/
+		if ( memcmp(buf, allzeroes, partlen) ) /* not all zeroes? */
+			continue;                      /* no flush needed */
+
+		/*
+		** calculate positions of bitmap block to be flushed
+		** - pointer of bitmap block in memory
+		** - offset  of bitmap block in cowfile
+		*/
+		tmpptr    = *(cowdev->mapcache+mapnum) + (mapbyte & (~MUMASK));
+		tmpoffset = (loff_t) MAPUNIT + mapnum * MAPCHUNKSZ +
+		                                       (mapbyte & (~MUMASK));
+
+		/*
+		** flush a bitmap block at the moment that all bits have
+		** been set in that block, i.e. at the moment that we
+		** switch to another bitmap block
+		*/
+		if ( (mapoffset != 0) && (mapoffset != tmpoffset) ) {
+			if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT,
+							mapoffset) < 0) {
+				printk(KERN_WARNING
+				       "cowloop - write-failure on bitmap - "
+				       "blk=%ld map=%ld byte=%ld bit=%ld\n",
+				  	cowblock, mapnum, mapbyte, mapbit);
+			}
+
+			DEBUGP(DCOW"cowloop - bitmap blk written %lld\n",
+								mapoffset);
+		}
+
+		/*
+		** remember offset in cowfile and offset in memory
+		** for bitmap to be flushed; flushing will be done
+		** as soon as all updates in this bitmap block have
+		** been done
+		*/
+		mapoffset = tmpoffset;
+		mapptr    = tmpptr;
+	}
+
+	/*
+	** any new block written containing binary zeroes?
+	*/
+	if (mapoffset) {
+		if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT, mapoffset) < 0) {
+			printk(KERN_WARNING
+			       "cowloop - write-failure on bitmap - "
+			       "blk=%ld map=%ld byte=%ld bit=%ld\n",
+			       cowblock, mapnum, mapbyte, mapbit);
+		}
+
+		DEBUGP(DCOW"cowloop - bitmap block written %lld\n", mapoffset);
+	}
+
+	return rv;
+}
+
+/*
+** write cowfile from an absolute offset
+**
+** return-value: similar to user-mode write
+*/
+static long int
+cowlo_writecowraw(struct cowloop_device *cowdev,
+					void *buf, int len, loff_t offset)
+{
+	long int	rv;
+	mm_segment_t	old_fs;
+	loff_t		saveoffset = offset;
+
+	DEBUGP(DCOW"cowloop - writecowraw called\n");
+
+	/*
+	** be sure that cowfile is opened for read-write
+	*/
+	if ( !(cowdev->state & COWRWCOWOPEN) ) {
+		 printk(KERN_WARNING
+		        "cowloop - write request to cowfile refused\n");
+
+		return -EBADF;
+	}
+
+	/*
+	** issue low level write
+	*/
+        old_fs = get_fs();
+	set_fs( get_ds() );
+	rv = cowdev->cowfp->f_op->write(cowdev->cowfp, buf, len, &offset);
+        set_fs(old_fs);
+
+	if (rv < len) {
+		printk(KERN_WARNING
+		       "cowloop - write-failure %ld on cowfile"
+		       "- offset=%lld len=%d\n", rv, saveoffset, len);
+	}
+
+	cowdev->cowwrites++;
+	return rv;
+}
+
+
+/*
+** readproc-function: called when the corresponding /proc-file is read
+*/
+static int
+cowlo_readproc(char *buf, char **start, off_t pos, int cnt, int *eof, void *p)
+{
+	struct cowloop_device *cowdev = p;
+
+	revision[sizeof revision - 3] = '\0';
+
+	return sprintf(buf,
+		"   cowloop version: %9s\n\n"
+		"      device state: %s%s%s%s\n"
+		"   number of opens: %9d\n"
+		"     pid of thread: %9d\n\n"
+		"    read-only file: %9s\n"
+		"          rdoreads: %9lu\n\n"
+		"copy-on-write file: %9s\n"
+		"     state cowfile: %9s\n"
+		"     bitmap-blocks: %9lu (of %d bytes)\n"
+		"  cowblocks in use: %9lu (of %d bytes)\n"
+		"          cowreads: %9lu\n"
+		"         cowwrites: %9lu\n",
+			&revision[11],
+
+			cowdev->state & COWDEVOPEN   ? "devopen "   : "",
+			cowdev->state & COWRWCOWOPEN ? "cowopenrw " : "",
+			cowdev->state & COWRDCOWOPEN ? "cowopenro " : "",
+			cowdev->state & COWWATCHDOG  ? "watchdog "  : "",
+
+			cowdev->opencnt,
+			cowdev->pid,
+			cowdev->rdoname,
+			cowdev->rdoreads,
+			cowdev->cowname,
+			cowdev->cowhead->flags & COWDIRTY ? "dirty":"clean",
+			cowdev->mapsize >> MUSHIFT, MAPUNIT,
+			cowdev->nrcowblocks, MAPUNIT,
+			cowdev->cowreads,
+			cowdev->cowwrites);
+}
+
+/*****************************************************************************/
+/* Setup and destroy cowdevices                                              */
+/*****************************************************************************/
+
+/*
+** open and prepare a cowdevice (rdofile and cowfile) and allocate bitmaps
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_openpair(char *rdof, char *cowf, int autorecover, int minor)
+{
+	long int		rv;
+	struct cowloop_device	*cowdev = cowdevall[minor];
+	struct kstatfs		ks;
+
+	down(&cowdevlock);
+
+	/*
+	** requested device exists?
+	*/
+	if (minor >= maxcows) {
+		up(&cowdevlock);
+		return -ENODEV;
+	}
+
+	/*
+	** requested device already assigned to cowdevice?
+	*/
+	if (cowdev->state & COWDEVOPEN) {
+		up(&cowdevlock);
+		return -EBUSY;
+	}
+
+	/*
+	** initialize administration
+	*/
+	memset(cowdev, 0, sizeof *cowdev);
+
+	spin_lock_init     (&cowdev->rqlock);
+	init_waitqueue_head(&cowdev->waitq);
+	init_waitqueue_head(&cowdev->watchq);
+
+	/*
+	** open the read-only file
+	*/
+	DEBUGP(DCOW"cowloop - call openrdo....\n");
+
+	if ( (rv = cowlo_openrdo(cowdev, rdof)) ) {
+		cowlo_undo_openrdo(cowdev);
+		up(&cowdevlock);
+		return rv;
+	}
+
+	/*
+	** open the cowfile
+	*/
+	DEBUGP(DCOW"cowloop - call opencow....\n");
+
+	if ( (rv = cowlo_opencow(cowdev, cowf, autorecover)) ) {
+		cowlo_undo_openrdo(cowdev);
+		cowlo_undo_opencow(cowdev);
+		up(&cowdevlock);
+		return rv;
+	}
+
+	/*
+	** administer total and available size of filesystem holding cowfile
+	*/
+	if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0) {
+		cowdev->blksize  = ks.f_bsize;
+		cowdev->blktotal = ks.f_blocks;
+		cowdev->blkavail = ks.f_bavail;
+	} else {
+		cowdev->blksize  = 1024;	/* avoid division by zero */
+	}
+
+	/*
+	** flush the (recovered) bitmaps and cowhead to the cowfile
+	*/
+	DEBUGP(DCOW"cowloop - call cowsync....\n");
+
+	cowlo_sync();
+
+	/*
+	** allocate gendisk for the cow device
+	*/
+	DEBUGP(DCOW"cowloop - alloc disk....\n");
+
+	if ((cowdev->gd = alloc_disk(1)) == NULL) {
+		printk(KERN_WARNING
+		       "cowloop - unable to alloc_disk for cowloop\n");
+
+		cowlo_undo_openrdo(cowdev);
+		cowlo_undo_opencow(cowdev);
+		up(&cowdevlock);
+		return -ENOMEM;
+	}
+
+	cowdev->gd->major        = COWMAJOR;
+	cowdev->gd->first_minor  = minor;
+	cowdev->gd->minors       = 1;
+	cowdev->gd->fops         = &cowlo_fops;
+	cowdev->gd->private_data = cowdev;
+	sprintf(cowdev->gd->disk_name, "%s%d", DEVICE_NAME, minor);
+
+	/* in .5 Kb units */
+	set_capacity(cowdev->gd, (cowdev->numblocks*(MAPUNIT/512)));
+
+	DEBUGP(DCOW"cowloop - init request queue....\n");
+
+	if ((cowdev->rqueue = blk_init_queue(cowlo_request, &cowdev->rqlock))
+								== NULL) {
+		printk(KERN_WARNING
+		       "cowloop - unable to get request queue for cowloop\n");
+
+		del_gendisk(cowdev->gd);
+		cowlo_undo_openrdo(cowdev);
+		cowlo_undo_opencow(cowdev);
+		up(&cowdevlock);
+		return -EINVAL;
+	}
+
+	blk_queue_logical_block_size(cowdev->rqueue, cowdev->blocksz);
+	cowdev->gd->queue = cowdev->rqueue;
+
+	/*
+	** start kernel thread to handle requests
+	*/
+	DEBUGP(DCOW"cowloop - kickoff daemon....\n");
+
+	cowdev->pid = kernel_thread((int (*)(void *))cowlo_daemon, cowdev, 0);
+
+	/*
+	** create a file below directory /proc/cow for this new cowdevice
+	*/
+	if (cowlo_procdir) {
+		char 	tmpname[64];
+
+		sprintf(tmpname, "%d", minor);
+
+		create_proc_read_entry(tmpname, 0 , cowlo_procdir,
+						cowlo_readproc, cowdev);
+	}
+
+	cowdev->state	|= COWDEVOPEN;
+
+	cowdev->rdoname = rdof;
+	cowdev->cowname = cowf;
+
+	/*
+	** enable the new disk; this triggers the first request!
+	*/
+	DEBUGP(DCOW"cowloop - call add_disk....\n");
+
+	add_disk(cowdev->gd);
+
+	up(&cowdevlock);
+	return 0;
+}
+
+/*
+** close a cowdevice (pair of rdofile/cowfile) and release memory
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_closepair(struct cowloop_device *cowdev)
+{
+	int minor;
+
+	down(&cowdevlock);
+
+	/*
+	** if cowdevice is not activated at all, refuse
+	*/
+	if ( !(cowdev->state & COWDEVOPEN) ) {
+		up(&cowdevlock);
+		return -ENODEV;
+	}
+
+	/*
+	** if this cowdevice is still open, refuse
+	*/
+	if (cowdev->opencnt > 0) {
+		up(&cowdevlock);
+		return -EBUSY;
+	}
+
+	up(&cowdevlock);
+
+	/*
+	** wakeup watcher (if any)
+	*/
+	if (cowdev->state & COWWATCHDOG) {
+		cowdev->watchthresh = cowdev->blkavail;
+		wake_up_interruptible(&cowdev->watchq);
+	}
+
+	/*
+	** wakeup kernel-thread to be able to exit
+	** and wait until it has exited
+	*/
+	cowdev->closedown = 1;
+	cowdev->qfilled   = 1;
+	wake_up_interruptible(&cowdev->waitq);
+
+       	while (cowdev->pid)
+               	schedule();
+
+	del_gendisk(cowdev->gd);  /* revert the alloc_disk() */
+	put_disk(cowdev->gd);     /* revert the add_disk()   */
+
+	if (cowlo_procdir) {
+		char 	tmpname[64];
+
+		for (minor = 0; minor < maxcows; minor++) {
+			if (cowdev == cowdevall[minor]) break;
+		}
+		sprintf(tmpname, "%d", minor);
+
+		remove_proc_entry(tmpname, cowlo_procdir);
+	}
+
+	blk_cleanup_queue(cowdev->rqueue);
+
+	/*
+	** release memory for filenames if these names have
+	** been allocated dynamically
+	*/
+	if ( (cowdev->cowname) && (cowdev->cowname != cowfile))
+		kfree(cowdev->cowname);
+
+	if ( (cowdev->rdoname) && (cowdev->rdoname != rdofile))
+		kfree(cowdev->rdoname);
+
+	cowlo_undo_openrdo(cowdev);
+	cowlo_undo_opencow(cowdev);
+
+	cowdev->state &= ~COWDEVOPEN;
+
+	return 0;
+}
+
+/*
+** open the read-only file
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_openrdo(struct cowloop_device *cowdev, char *rdof)
+{
+	struct file	*f;
+	struct inode	*inode;
+	long int	i, nrval;
+
+	DEBUGP(DCOW"cowloop - openrdo called\n");
+
+	/*
+	** open the read-only file
+	*/
+        if(*rdof == '\0') {
+     	     	printk(KERN_ERR
+		       "cowloop - specify name for read-only file\n\n");
+         	return -EINVAL;
+        }
+
+	f = filp_open(rdof, O_RDONLY|O_LARGEFILE, 0);
+
+	if ( (f == NULL) || IS_ERR(f) ) {
+		printk(KERN_ERR
+		       "cowloop - open of rdofile %s failed\n", rdof);
+		return -EINVAL;
+	}
+
+	cowdev->rdofp = f;
+
+	inode = f->f_dentry->d_inode;
+
+	if ( !S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode) ) {
+		printk(KERN_ERR
+		       "cowloop - %s not regular file or blockdev\n", rdof);
+		return -EINVAL;
+	}
+
+	DEBUGP(DCOW"cowloop - determine size rdo....\n");
+
+	/*
+	** determine block-size and total size of read-only file
+	*/
+	if (S_ISREG(inode->i_mode)) {
+		/*
+		** read-only file is a regular file
+		*/
+		cowdev->blocksz   = 512;	/* other value fails */
+		cowdev->numblocks = inode->i_size >> MUSHIFT;
+
+		if (inode->i_size & MUMASK) {
+			printk(KERN_WARNING
+			       "cowloop - rdofile %s truncated to multiple "
+			       "of %d bytes\n", rdof, MAPUNIT);
+		}
+
+		DEBUGP(DCOW"cowloop - RO=regular: numblocks=%d, blocksz=%d\n",
+			cowdev->numblocks, cowdev->blocksz);
+	} else {
+		/*
+		** read-only file is a block device
+		*/
+		cowdev->belowdev  = inode->i_bdev;
+		cowdev->belowgd   = cowdev->belowdev->bd_disk; /* gendisk */
+
+		if (cowdev->belowdev->bd_part) {
+			cowdev->numblocks = cowdev->belowdev->bd_part->nr_sects
+								/ (MAPUNIT/512);
+		}
+
+		if (cowdev->belowgd) {
+			cowdev->belowq = cowdev->belowgd->queue;
+
+			if (cowdev->numblocks == 0) {
+				cowdev->numblocks = get_capacity(cowdev->belowgd)
+                         					/ (MAPUNIT/512);
+			}
+		}
+
+
+		if (cowdev->belowq)
+			cowdev->blocksz = queue_logical_block_size(cowdev->belowq);
+
+		if (cowdev->blocksz == 0)
+			cowdev->blocksz = BLOCK_SIZE; /* default 2^10 */
+
+		DEBUGP(DCOW"cowloop - numblocks=%d, "
+		           "blocksz=%d, belowgd=%p, belowq=%p\n",
+		  	cowdev->numblocks, cowdev->blocksz,
+			cowdev->belowgd, cowdev->belowq);
+
+		DEBUGP(DCOW"cowloop - belowdev.bd_block_size=%d\n",
+		  	cowdev->belowdev->bd_block_size);
+	}
+
+	if (cowdev->numblocks == 0) {
+		printk(KERN_ERR "cowloop - %s has no contents\n", rdof);
+		return -EINVAL;
+	}
+
+	/*
+	** reserve space in memory as generic I/O buffer
+	*/
+	cowdev->iobuf  = kmalloc(MAPUNIT, GFP_KERNEL);
+
+	if (!cowdev->iobuf) {
+		printk(KERN_ERR
+		       "cowloop - cannot get space for buffer %d\n", MAPUNIT);
+		return -ENOMEM;
+	}
+
+	DEBUGP(DCOW"cowloop - determine fingerprint rdo....\n");
+
+	/*
+	** determine fingerprint for read-only file
+	** 	calculate fingerprint from first four datablocks
+	**	which do not contain binary zeroes
+	*/
+	for (i=0, cowdev->fingerprint=0, nrval=0;
+			(nrval < 4)&&(i < cowdev->numblocks); i++) {
+		int 		j;
+		unsigned char	cs;
+
+		/*
+		** read next block
+		*/
+		if (cowlo_readrdo(cowdev, cowdev->iobuf, MAPUNIT,
+						(loff_t)i << MUSHIFT) < 1)
+			break;
+
+		/*
+		** calculate fingerprint by adding all byte-values
+		*/
+		for (j=0, cs=0; j < MAPUNIT; j++)
+			cs += *(cowdev->iobuf+j);
+
+		if (cs == 0)	/* block probably contained zeroes */
+			continue;
+
+		/*
+		** shift byte-value to proper place in final fingerprint
+		*/
+		cowdev->fingerprint |= cs << (nrval*8);
+		nrval++;
+	}
+
+	return 0;
+}
+
+/*
+** undo memory allocs and file opens issued so far
+** related to the read-only file
+*/
+static void
+cowlo_undo_openrdo(struct cowloop_device *cowdev)
+{
+	if(cowdev->iobuf);
+		kfree(cowdev->iobuf);
+
+	if (cowdev->rdofp)
+  		filp_close(cowdev->rdofp, 0);
+}
+
+/*
+** open the cowfile
+**
+** returns:
+** 	0   - okay
+**    < 0   - error value
+*/
+static int
+cowlo_opencow(struct cowloop_device *cowdev, char *cowf, int autorecover)
+{
+	long int		i, rv;
+	int			minor;
+	unsigned long		nb;
+	struct file		*f;
+	struct inode		*inode;
+	loff_t			offset;
+	struct cowloop_device	*cowtmp;
+
+	DEBUGP(DCOW"cowloop - opencow called\n");
+
+	/*
+	** open copy-on-write file (read-write)
+	*/
+        if (cowf[0] == '\0') {
+          	printk(KERN_ERR
+                 "cowloop - specify name of copy-on-write file\n\n");
+         	return -EINVAL;
+        }
+
+	f = filp_open(cowf, O_RDWR|O_LARGEFILE, 0600);
+
+	if ( (f == NULL) || IS_ERR(f) ) {
+		/*
+		** non-existing cowfile: try to create
+		*/
+		f = filp_open(cowf, O_RDWR|O_CREAT|O_LARGEFILE, 0600);
+
+		if ( (f == NULL) || IS_ERR(f) ) {
+			printk(KERN_ERR
+		       	  "cowloop - failed to open file %s for read-write\n\n",
+		       						cowf);
+			return -EINVAL;
+	 	}
+	}
+
+	cowdev->cowfp = f;
+
+	inode = f->f_dentry->d_inode;
+
+	if (!S_ISREG(inode->i_mode)) {
+		printk(KERN_ERR "cowloop - %s is not regular file\n", cowf);
+		return -EINVAL;
+	}
+
+	/*
+	** check if this cowfile is already in use for another cowdevice
+	*/
+	for (minor = 0; minor < maxcows; minor++) {
+
+		cowtmp = cowdevall[minor];
+
+		if ( !(cowtmp->state & COWDEVOPEN) )
+			continue;
+
+		if (cowtmp == cowdev)
+			continue;
+
+		if (cowtmp->cowfp->f_dentry->d_inode == f->f_dentry->d_inode) {
+			printk(KERN_ERR
+			       "cowloop - %s: already in use as cow\n", cowf);
+			return -EBUSY;
+		}
+	}
+
+	/*
+	** mark cowfile open for read-write
+	*/
+	cowdev->state |= COWRWCOWOPEN;
+
+	/*
+	** calculate size (in bytes) for total bitmap in cowfile;
+	** when the size of the cowhead block is added, the start-offset
+	** for the modified data blocks can be found
+	*/
+	nb = cowdev->numblocks;
+
+	if (nb%8)		/* transform #bits to #bytes */
+		nb+=8;  	/* rounded if necessary      */
+	nb /= 8;
+
+	if (nb & MUMASK)	/* round up #bytes to MAPUNIT chunks */
+		cowdev->mapsize = ( (nb>>MUSHIFT) +1) << MUSHIFT;
+	else
+		cowdev->mapsize = nb;
+
+	/*
+	** reserve space in memory for the cowhead
+	*/
+	cowdev->cowhead = kmalloc(MAPUNIT, GFP_KERNEL);
+
+	if (!cowdev->cowhead) {
+		printk(KERN_ERR "cowloop - cannot get space for cowhead %d\n",
+								     MAPUNIT);
+		return -ENOMEM;
+	}
+
+	memset(cowdev->cowhead, 0, MAPUNIT);
+
+	DEBUGP(DCOW"cowloop - prepare cowhead....\n");
+
+	/*
+	** check if the cowfile exists or should be created
+	*/
+	if (inode->i_size != 0) {
+		/*
+		** existing cowfile: read the cow head
+		*/
+		if (inode->i_size < MAPUNIT) {
+			printk(KERN_ERR
+			       "cowloop - existing cowfile %s too small\n",
+				cowf);
+			return -EINVAL;
+		}
+
+		cowlo_readcowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0);
+
+		/*
+		** verify if the existing file is really a cowfile
+		*/
+		if (cowdev->cowhead->magic != COWMAGIC) {
+			printk(KERN_ERR
+			       "cowloop - cowfile %s has incorrect format\n",
+				cowf);
+			return -EINVAL;
+		}
+
+		/*
+		** verify the cowhead version of the cowfile
+		*/
+		if (cowdev->cowhead->version > COWVERSION) {
+			printk(KERN_ERR
+			       "cowloop - cowfile %s newer than this driver\n",
+				cowf);
+			return -EINVAL;
+		}
+
+		/*
+		** make sure that this is not a packed cowfile
+		*/
+		if (cowdev->cowhead->flags & COWPACKED) {
+			printk(KERN_ERR
+			    "cowloop - packed cowfile %s not accepted\n", cowf);
+			return -EINVAL;
+		}
+
+		/*
+		** verify if the cowfile has been properly closed
+		*/
+		if (cowdev->cowhead->flags & COWDIRTY) {
+			/*
+			** cowfile was not properly closed;
+			** check if automatic recovery is required
+			** (actual recovery will be done later on)
+			*/
+			if (!autorecover) {
+				printk(KERN_ERR
+				       "cowloop - cowfile %s is dirty "
+				       "(not properly closed by rmmod?)\n",
+					cowf);
+				printk(KERN_ERR
+				       "cowloop - run cowrepair or specify "
+				       "'option=r' to recover\n");
+				return -EINVAL;
+			}
+		}
+
+		/*
+		** verify if the cowfile is really related to this rdofile
+		*/
+		if (cowdev->cowhead->rdoblocks != cowdev->numblocks) {
+			printk(KERN_ERR
+		       	       "cowloop - cowfile %s (size %lld) not related "
+		       	       "to rdofile (size %lld)\n",
+				cowf,
+				(long long)cowdev->cowhead->rdoblocks <<MUSHIFT,
+				(long long)cowdev->numblocks <<MUSHIFT);
+			return -EINVAL;
+		}
+
+		if (cowdev->cowhead->rdofingerprint != cowdev->fingerprint) {
+			printk(KERN_ERR
+		       	     "cowloop - cowfile %s not related to rdofile "
+			     " (fingerprint err - rdofile modified?)\n", cowf);
+			return -EINVAL;
+		}
+	} else {
+		/*
+		** new cowfile: determine the minimal size (cowhead+bitmap)
+		*/
+		offset = (loff_t) MAPUNIT + cowdev->mapsize - 1;
+
+		if ( cowlo_writecowraw(cowdev, "", 1, offset) < 1) {
+			printk(KERN_ERR
+			       "cowloop - cannot set cowfile to size %lld\n",
+				offset+1);
+			return -EINVAL;
+		}
+
+		/*
+		** prepare new cowhead
+		*/
+		cowdev->cowhead->magic		= COWMAGIC;
+		cowdev->cowhead->version	= COWVERSION;
+		cowdev->cowhead->mapunit	= MAPUNIT;
+		cowdev->cowhead->mapsize	= cowdev->mapsize;
+		cowdev->cowhead->rdoblocks	= cowdev->numblocks;
+		cowdev->cowhead->rdofingerprint	= cowdev->fingerprint;
+		cowdev->cowhead->cowused	= 0;
+
+		/*
+		** calculate start offset of data in cowfile,
+		** rounded up to multiple of 4K to avoid
+		** unnecessary disk-usage for written datablocks in
+		** the sparsed cowfile on e.g. 4K filesystems
+		*/
+		cowdev->cowhead->doffset =
+			((MAPUNIT+cowdev->mapsize+4095)>>12)<<12;
+	}
+
+	cowdev->cowhead->flags	= 0;
+
+	DEBUGP(DCOW"cowloop - reserve space bitmap....\n");
+
+	/*
+	** reserve space in memory for the entire bitmap and
+	** fill it with the bitmap-data from disk; the entire
+	** bitmap is allocated in several chunks because kmalloc
+	** has restrictions regarding the allowed size per kmalloc
+	*/
+	cowdev->mapcount = (cowdev->mapsize+MAPCHUNKSZ-1)/MAPCHUNKSZ;
+
+	/*
+	** the size of every bitmap chunk will be MAPCHUNKSZ bytes, except for
+	** the last bitmap chunk: calculate remaining size for this chunk
+	*/
+	if (cowdev->mapsize % MAPCHUNKSZ == 0)
+		cowdev->mapremain = MAPCHUNKSZ;
+	else
+		cowdev->mapremain = cowdev->mapsize % MAPCHUNKSZ;
+
+	/*
+	** allocate space to store all pointers for the bitmap-chunks
+	** (initialize area with zeroes to allow proper undo)
+	*/
+	cowdev->mapcache = kmalloc(cowdev->mapcount * sizeof(char *),
+								GFP_KERNEL);
+	if (!cowdev->mapcache) {
+		printk(KERN_ERR
+		       "cowloop - can not allocate space for bitmap ptrs\n");
+		return -ENOMEM;
+	}
+
+	memset(cowdev->mapcache, 0, cowdev->mapcount * sizeof(char *));
+
+	/*
+	** allocate space to store the bitmap-chunks themselves
+	*/
+	for (i=0; i < cowdev->mapcount; i++) {
+		if (i < (cowdev->mapcount-1))
+			*(cowdev->mapcache+i) = kmalloc(MAPCHUNKSZ, GFP_KERNEL);
+		else
+			*(cowdev->mapcache+i) = kmalloc(cowdev->mapremain,
+						                  GFP_KERNEL);
+
+		if (*(cowdev->mapcache+i) == NULL) {
+			printk(KERN_ERR "cowloop - no space for bitmapchunk %ld"
+					" totmapsz=%ld, mapcnt=%d mapunit=%d\n",
+					i, cowdev->mapsize, cowdev->mapcount,
+					MAPUNIT);
+			return -ENOMEM;
+		}
+	}
+
+	DEBUGP(DCOW"cowloop - read bitmap from cow....\n");
+
+	/*
+	** read the entire bitmap from the cowfile into the in-memory cache;
+	** count the number of blocks that are in use already
+	** (statistical purposes)
+	*/
+	for (i=0, offset=MAPUNIT; i < cowdev->mapcount;
+					i++, offset+=MAPCHUNKSZ) {
+		unsigned long	numbytes;
+
+		if (i < (cowdev->mapcount-1))
+			/*
+			** full bitmap chunk
+			*/
+			numbytes = MAPCHUNKSZ;
+		else
+			/*
+			** last bitmap chunk: might be partly filled
+			*/
+			numbytes = cowdev->mapremain;
+
+		cowlo_readcowraw(cowdev, *(cowdev->mapcache+i),
+							numbytes, offset);
+	}
+
+	/*
+	** if the cowfile was dirty and automatic recovery is required,
+	** reconstruct a proper bitmap in memory now
+	*/
+	if (cowdev->cowhead->flags & COWDIRTY) {
+		unsigned long long	blocknum;
+		char			databuf[MAPUNIT];
+		unsigned long		mapnum, mapbyte, mapbit;
+
+		printk(KERN_NOTICE "cowloop - recover dirty cowfile %s....\n",
+							cowf);
+
+		/*
+		** read all data blocks
+		*/
+		for (blocknum=0, rv=1, offset=0;
+			cowlo_readcow(cowdev, databuf, MAPUNIT, offset) > 0;
+			blocknum++, offset += MAPUNIT) {
+
+			/*
+			** if this datablock contains real data (not binary
+			** zeroes), set the corresponding bit in the bitmap
+			*/
+			if ( memcmp(databuf, allzeroes, MAPUNIT) == 0)
+				continue;
+
+			mapnum  = CALCMAP (blocknum);
+			mapbyte = CALCBYTE(blocknum);
+			mapbit  = CALCBIT (blocknum);
+
+			*(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit);
+		}
+
+		printk(KERN_NOTICE "cowloop - cowfile recovery completed\n");
+	}
+
+	/*
+	** count all bits set in the bitmaps for statistical purposes
+	*/
+	for (i=0, cowdev->nrcowblocks = 0; i < cowdev->mapcount; i++) {
+		long	numbytes;
+		char	*p;
+
+		if (i < (cowdev->mapcount-1))
+			numbytes = MAPCHUNKSZ;
+		else
+			numbytes = cowdev->mapremain;
+
+		p = *(cowdev->mapcache+i);
+
+		for (numbytes--; numbytes >= 0; numbytes--, p++) {
+			/*
+			** for only eight checks the following construction
+			** is faster than a loop-construction
+			*/
+			if ((*p) & 0x01)	cowdev->nrcowblocks++;
+			if ((*p) & 0x02)	cowdev->nrcowblocks++;
+			if ((*p) & 0x04)	cowdev->nrcowblocks++;
+			if ((*p) & 0x08)	cowdev->nrcowblocks++;
+			if ((*p) & 0x10)	cowdev->nrcowblocks++;
+			if ((*p) & 0x20)	cowdev->nrcowblocks++;
+			if ((*p) & 0x40)	cowdev->nrcowblocks++;
+			if ((*p) & 0x80)	cowdev->nrcowblocks++;
+		}
+	}
+
+	/*
+	** consistency-check for number of bits set in bitmap
+	*/
+	if ( !(cowdev->cowhead->flags & COWDIRTY) &&
+	    (cowdev->cowhead->cowused != cowdev->nrcowblocks) ) {
+		printk(KERN_ERR "cowloop - inconsistent cowfile admi\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*
+** undo memory allocs and file opens issued so far
+** related to the cowfile
+*/
+static void
+cowlo_undo_opencow(struct cowloop_device *cowdev)
+{
+	int	i;
+
+	if (cowdev->mapcache) {
+		for (i=0; i < cowdev->mapcount; i++) {
+			if (*(cowdev->mapcache+i) != NULL)
+				kfree( *(cowdev->mapcache+i) );
+		}
+
+		kfree(cowdev->mapcache);
+	}
+
+	if (cowdev->cowhead)
+		kfree(cowdev->cowhead);
+
+	if ( (cowdev->state & COWCOWOPEN) && (cowdev->cowfp) )
+  		filp_close(cowdev->cowfp, 0);
+
+	/*
+	** mark cowfile closed
+	*/
+	cowdev->state &= ~COWCOWOPEN;
+}
+
+/*
+** flush the entire bitmap and the cowhead (clean) to the cowfile
+**
+** must be called with the cowdevices-lock set
+*/
+static void
+cowlo_sync(void)
+{
+	int			i, minor;
+	loff_t			offset;
+	struct cowloop_device	*cowdev;
+
+	for (minor=0; minor < maxcows;  minor++) {
+		cowdev = cowdevall[minor];
+		if ( ! (cowdev->state & COWRWCOWOPEN) )
+			continue;
+
+		for (i=0, offset=MAPUNIT; i < cowdev->mapcount;
+					i++, offset += MAPCHUNKSZ) {
+			unsigned long	numbytes;
+
+			if (i < (cowdev->mapcount-1))
+				/*
+				** full bitmap chunk
+				*/
+				numbytes = MAPCHUNKSZ;
+			else
+				/*
+				** last bitmap chunk: might be partly filled
+				*/
+				numbytes = cowdev->mapremain;
+
+			DEBUGP(DCOW
+			       "cowloop - flushing bitmap %2d (%3ld Kb)\n",
+							i, numbytes/1024);
+
+			if (cowlo_writecowraw(cowdev, *(cowdev->mapcache+i),
+						numbytes, offset) < numbytes) {
+				break;
+			}
+		}
+
+		/*
+		** flush clean up-to-date cowhead to cowfile
+		*/
+		cowdev->cowhead->cowused	 = cowdev->nrcowblocks;
+		cowdev->cowhead->flags		&= ~COWDIRTY;
+
+		DEBUGP(DCOW "cowloop - flushing cowhead (%3d Kb)\n",
+							MAPUNIT/1024);
+
+		cowlo_writecowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0);
+	}
+}
+
+/*****************************************************************************/
+/* Module loading/unloading                                                  */
+/*****************************************************************************/
+
+/*
+** called during insmod/modprobe
+*/
+static int __init
+cowlo_init_module(void)
+{
+	int	rv;
+	int	minor, uptocows;
+
+        revision[sizeof revision - 3] = '\0';
+
+        printk(KERN_NOTICE "cowloop - (C) 2009 ATComputing.nl - version: %s\n", &revision[11]);
+        printk(KERN_NOTICE "cowloop - info: www.ATComputing.nl/cowloop\n");
+
+	memset(allzeroes, 0, MAPUNIT);
+
+	/*
+	** Setup administration for all possible cowdevices.
+        ** Note that their minor numbers go from 0 to MAXCOWS-1 inclusive
+        ** and minor == MAXCOWS-1 is reserved for the control device.
+	*/
+	if ((maxcows < 1) || (maxcows > MAXCOWS)) {
+		printk(KERN_WARNING
+		       "cowloop - maxcows exceeds maximum of %d\n", MAXCOWS);
+
+                maxcows = DFLCOWS;
+        }
+
+	/* allocate room for a table with a pointer to each cowloop_device: */
+        if ( (cowdevall = kmalloc(maxcows * sizeof(struct cowloop_device *),
+							GFP_KERNEL)) == NULL) {
+		printk(KERN_WARNING
+		        "cowloop - can not alloc table for %d devs\n", maxcows);
+		uptocows = 0;
+		rv = -ENOMEM;
+		goto error_out;
+	}
+	memset(cowdevall, 0, maxcows * sizeof(struct cowloop_device *));
+	/* then hook an actual cowloop_device struct to each pointer: */
+	for (minor=0; minor < maxcows; minor++) {
+		if ((cowdevall[minor] = kmalloc(sizeof(struct cowloop_device),
+						GFP_KERNEL)) == NULL) {
+			printk(KERN_WARNING
+		           "cowloop - can not alloc admin-struct for dev no %d\n", minor);
+
+			uptocows = minor; /* this is how far we got.... */
+			rv = -ENOMEM;
+			goto error_out;
+		}
+        	memset(cowdevall[minor], 0, sizeof(struct cowloop_device));
+	}
+	uptocows = maxcows; /* we got all devices */
+
+	sema_init(&cowdevlock, 1);
+
+	/*
+	** register cowloop module
+	*/
+	if ( register_blkdev(COWMAJOR, DEVICE_NAME) < 0) {
+		printk(KERN_WARNING
+		    "cowloop - unable to get major %d for cowloop\n", COWMAJOR);
+		rv = -EIO;
+		goto error_out;
+	}
+
+	/*
+	** create a directory below /proc to allocate a file
+	** for each cowdevice that is allocated later on
+	*/
+	cowlo_procdir = proc_mkdir("cow", NULL);
+
+	/*
+	** check if a cowdevice has to be opened during insmod/modprobe;
+	** two parameters should be specified then: rdofile= and cowfile=
+	*/
+	if( (rdofile[0] != '\0') && (cowfile[0] != '\0') ) {
+		char	*po = option;
+		int	wantrecover = 0;
+
+		/*
+		** check if automatic recovery is wanted
+		*/
+		while (*po) {
+			if (*po == 'r') {
+				wantrecover = 1;
+				break;
+                        }
+			po++;
+		}
+
+		/*
+		** open new cowdevice with minor number 0
+		*/
+		if ( (rv = cowlo_openpair(rdofile, cowfile, wantrecover, 0))) {
+			remove_proc_entry("cow", NULL);
+			unregister_blkdev(COWMAJOR, DEVICE_NAME);
+			goto error_out;
+		}
+        } else {
+		/*
+		** check if only one parameter has been specified
+		*/
+		if( (rdofile[0] != '\0') || (cowfile[0] != '\0') ) {
+			printk(KERN_ERR
+			       "cowloop - only one filename specified\n");
+			remove_proc_entry("cow", NULL);
+			unregister_blkdev(COWMAJOR, DEVICE_NAME);
+			rv = -EINVAL;
+			goto error_out;
+		}
+	}
+
+	/*
+	** allocate fake disk as control channel to handle the requests
+	** to activate and deactivate cowdevices dynamically
+	*/
+	if (!(cowctlgd = alloc_disk(1))) {
+		printk(KERN_WARNING
+		       "cowloop - unable to alloc_disk for cowctl\n");
+
+		remove_proc_entry("cow", NULL);
+		(void) cowlo_closepair(cowdevall[0]);
+		unregister_blkdev(COWMAJOR, DEVICE_NAME);
+		rv = -ENOMEM;
+		goto error_out;
+	}
+
+	spin_lock_init(&cowctlrqlock);
+	cowctlgd->major        = COWMAJOR;
+	cowctlgd->first_minor  = COWCTL;
+	cowctlgd->minors       = 1;
+	cowctlgd->fops         = &cowlo_fops;
+	cowctlgd->private_data = NULL;
+	/* the device has capacity 0, so there will be no q-requests */
+	cowctlgd->queue = blk_init_queue(NULL, &cowctlrqlock);
+	sprintf(cowctlgd->disk_name, "cowctl");
+	set_capacity(cowctlgd, 0);
+
+	add_disk(cowctlgd);
+
+        printk(KERN_NOTICE "cowloop - number of configured cowdevices: %d\n",
+								maxcows);
+	if (rdofile[0] != '\0') {
+	    printk(KERN_NOTICE "cowloop - initialized on rdofile=%s\n",
+								rdofile);
+	} else {
+	    printk(KERN_NOTICE "cowloop - initialized without rdofile yet\n");
+	}
+	return 0;
+
+error_out:
+	for (minor=0; minor < uptocows ; minor++) {
+		kfree(cowdevall[minor]);
+	}
+	kfree(cowdevall);
+	return rv;
+}
+
+/*
+** called during rmmod
+*/
+static void __exit
+cowlo_cleanup_module(void)
+{
+	int	minor;
+
+	/*
+	** flush bitmaps and cowheads to the cowfiles
+	*/
+	down(&cowdevlock);
+	cowlo_sync();
+	up(&cowdevlock);
+
+	/*
+	** close all cowdevices
+	*/
+	for (minor=0; minor < maxcows;  minor++)
+		(void) cowlo_closepair(cowdevall[minor]);
+
+	unregister_blkdev(COWMAJOR, DEVICE_NAME);
+
+	/*
+	** get rid of /proc/cow and unregister the driver
+	*/
+	remove_proc_entry("cow", NULL);
+
+	for (minor = 0; minor < maxcows; minor++) {
+		kfree(cowdevall[minor]);
+	}
+	kfree(cowdevall);
+
+	del_gendisk(cowctlgd);  /* revert the alloc_disk() */
+	put_disk   (cowctlgd);  /* revert the add_disk()   */
+	blk_cleanup_queue(cowctlgd->queue); /* cleanup the empty queue */
+
+	printk(KERN_NOTICE "cowloop - unloaded\n");
+}
+
+module_init(cowlo_init_module);
+module_exit(cowlo_cleanup_module);
diff --git a/drivers/staging/cowloop/cowloop.h b/drivers/staging/cowloop/cowloop.h
new file mode 100644
index 0000000..bbd4a35
--- /dev/null
+++ b/drivers/staging/cowloop/cowloop.h
@@ -0,0 +1,66 @@
+/*
+** DO NOT MODIFY THESE VALUES (would make old cowfiles unusable)
+*/
+#define	MAPUNIT		1024		/* blocksize for bit in bitmap       */
+#define	MUSHIFT		10		/* bitshift  for bit in bitmap       */
+#define	MUMASK		0x3ff		/* bitmask   for bit in bitmap       */
+
+#define	COWMAGIC	0x574f437f	/* byte-swapped '7f C O W'           */
+#define	COWDIRTY	0x01
+#define	COWPACKED	0x02
+#define	COWVERSION	1
+
+struct cowhead
+{
+	int		magic;		/* identifies a cowfile              */
+	short		version;	/* version of cowhead                */
+	short		flags;    	/* flags indicating status           */
+	unsigned long	mapunit;	/* blocksize per bit in bitmap       */
+	unsigned long	mapsize;	/* total size of bitmap (bytes)      */
+	unsigned long	doffset;	/* start-offset datablocks in cow    */
+	unsigned long	rdoblocks;	/* size of related read-only file    */
+	unsigned long	rdofingerprint;	/* fingerprint of read-only file     */
+	unsigned long	cowused;	/* number of datablocks used in cow  */
+};
+
+#define COWDEVDIR	"/dev/cow/"
+#define COWDEVICE	COWDEVDIR "%ld"
+#define COWCONTROL	COWDEVDIR "ctl"
+
+#define MAXCOWS		1024
+#define COWCTL		(MAXCOWS-1)	/* minor number of /dev/cow/ctl     */
+
+#define COWPROCDIR	"/proc/cow/"
+#define COWPROCFILE	COWPROCDIR "%d"
+
+/*
+** ioctl related stuff
+*/
+#define ANYDEV		((unsigned long)-1)
+
+struct cowpair
+{
+	unsigned char	*rdofile;	/* pathname of the rdofile           */
+	unsigned char	*cowfile;	/* pathname of the cowfile           */
+	unsigned short	rdoflen;	/* length of rdofile pathname        */
+	unsigned short	cowflen;	/* length of cowfile pathname        */
+	unsigned long	device;		/* requested/returned device number  */
+};
+
+struct cowwatch
+{
+	int      	flags;		/* request flags                     */
+	unsigned long	device;		/* requested device number           */
+	unsigned long	threshold;	/* continue if free Kb < threshold   */
+	unsigned long	totalkb;	/* ret: total filesystem size (Kb)   */
+	unsigned long	availkb;	/* ret: free  filesystem size (Kb)   */
+};
+
+#define	WATCHWAIT	0x01		/* block until threshold reached     */
+
+#define	COWSYNC		_IO  ('C', 1)
+#define	COWMKPAIR	_IOW ('C', 2, struct cowpair)
+#define	COWRMPAIR	_IOW ('C', 3, unsigned long)
+#define	COWWATCH	_IOW ('C', 4, struct cowwatch)
+#define	COWCLOSE	_IOW ('C', 5, unsigned long)
+#define	COWRDOPEN	_IOW ('C', 6, unsigned long)
diff --git a/drivers/staging/cpc-usb/TODO b/drivers/staging/cpc-usb/TODO
index 000e8bb..9b1752f 100644
--- a/drivers/staging/cpc-usb/TODO
+++ b/drivers/staging/cpc-usb/TODO
@@ -5,5 +5,6 @@ kernel:
 	- remove proc code
 	- tie into CAN socket interfaces if possible
 	- figure out sane userspace api
+	- use linux's error codes
 
 Send patches to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/cpc-usb/cpc-usb_drv.c b/drivers/staging/cpc-usb/cpc-usb_drv.c
index 9bf3f98..c5eca46 100644
--- a/drivers/staging/cpc-usb/cpc-usb_drv.c
+++ b/drivers/staging/cpc-usb/cpc-usb_drv.c
@@ -28,7 +28,6 @@
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 
-#include <linux/version.h>
 
 #include <linux/proc_fs.h>
 
diff --git a/drivers/staging/cpc-usb/cpc.h b/drivers/staging/cpc-usb/cpc.h
index ed8cb34..b2fda5d 100644
--- a/drivers/staging/cpc-usb/cpc.h
+++ b/drivers/staging/cpc-usb/cpc.h
@@ -10,243 +10,223 @@
 #ifndef CPC_HEADER
 #define CPC_HEADER
 
-// the maximum length of the union members within a CPC_MSG
-// this value can be defined by the customer, but has to be
-// >= 64 bytes
-// however, if not defined before, we set a length of 64 byte
+/*
+ * the maximum length of the union members within a CPC_MSG
+ * this value can be defined by the customer, but has to be
+ * >= 64 bytes
+ * however, if not defined before, we set a length of 64 byte
+ */
 #if !defined(CPC_MSG_LEN) || (CPC_MSG_LEN < 64)
 #undef CPC_MSG_LEN
 #define CPC_MSG_LEN 64
 #endif
 
-// check the operating system used
-#ifdef _WIN32 // running a Windows OS
-
-// define basic types on Windows platforms
-#ifdef _MSC_VER // Visual Studio
-	typedef unsigned __int8 u8;
-	typedef unsigned __int16 u16;
-	typedef unsigned __int32 u32;
-#else // Borland Compiler
-	typedef unsigned char u8;
-	typedef unsigned short u16;
-	typedef unsigned int u32;
-#endif
-	// on Windows OS we use a byte alignment of 1
-	#pragma pack(push, 1)
-
-	// set the calling conventions for the library function calls
-	#define CALL_CONV __stdcall
-#else
-	// Kernel headers already define this types
-	#ifndef __KERNEL__
-		// define basic types
-		typedef unsigned char u8;
-		typedef unsigned short u16;
-		typedef unsigned int u32;
-	#endif
-
-	// Linux does not use this calling convention
-	#define CALL_CONV
-#endif
-
-// Transmission of events from CPC interfaces to PC can be individually
-// controlled per event type. Default state is: don't transmit
-// Control values are constructed by bit-or of Subject and Action
-// and passed to CPC_Control()
+/*
+ * Transmission of events from CPC interfaces to PC can be individually
+ * controlled per event type. Default state is: don't transmit
+ * Control values are constructed by bit-or of Subject and Action
+ * and passed to CPC_Control()
+ */
 
-// Control-Values for CPC_Control() Command Subject Selection
+/* Control-Values for CPC_Control() Command Subject Selection */
 #define CONTR_CAN_Message 0x04
 #define CONTR_Busload	  0x08
 #define	CONTR_CAN_State	  0x0C
 #define	CONTR_SendAck	  0x10
 #define	CONTR_Filter	  0x14
-#define CONTR_CmdQueue    0x18	// reserved, do not use
+#define CONTR_CmdQueue    0x18	/* reserved, do not use */
 #define CONTR_BusError    0x1C
 
-// Control Command Actions
+/* Control Command Actions */
 #define CONTR_CONT_OFF    0
 #define CONTR_CONT_ON     1
 #define CONTR_SING_ON     2
-// CONTR_SING_ON doesn't change CONTR_CONT_ON state, so it should be
-// read as: transmit at least once
+/*
+ * CONTR_SING_ON doesn't change CONTR_CONT_ON state, so it should be
+ * read as: transmit at least once
+ */
 
-// defines for confirmed request
+/* defines for confirmed request */
 #define DO_NOT_CONFIRM 0
 #define DO_CONFIRM     1
 
-// event flags
+/* event flags */
 #define EVENT_READ 0x01
 #define EVENT_WRITE 0x02
 
-// Messages from CPC to PC contain a message object type field.
-// The following message types are sent by CPC and can be used in
-// handlers, others should be ignored.
-#define CPC_MSG_T_RESYNC        0 // Normally to be ignored
-#define CPC_MSG_T_CAN           1 // CAN data frame
-#define CPC_MSG_T_BUSLOAD       2 // Busload message
-#define CPC_MSG_T_STRING        3 // Normally to be ignored
-#define CPC_MSG_T_CONTI         4 // Normally to be ignored
-#define CPC_MSG_T_MEM           7 // Normally not to be handled
-#define	CPC_MSG_T_RTR           8 // CAN remote frame
-#define CPC_MSG_T_TXACK	        9 // Send acknowledge
-#define CPC_MSG_T_POWERUP      10 // Power-up message
-#define	CPC_MSG_T_CMD_NO       11 // Normally to be ignored
-#define	CPC_MSG_T_CAN_PRMS     12 // Actual CAN parameters
-#define	CPC_MSG_T_ABORTED      13 // Command aborted message
-#define	CPC_MSG_T_CANSTATE     14 // CAN state message
-#define CPC_MSG_T_RESET        15 // used to reset CAN-Controller
-#define	CPC_MSG_T_XCAN         16 // XCAN data frame
-#define CPC_MSG_T_XRTR         17 // XCAN remote frame
-#define CPC_MSG_T_INFO         18 // information strings
-#define CPC_MSG_T_CONTROL      19 // used for control of interface/driver behaviour
-#define CPC_MSG_T_CONFIRM      20 // response type for confirmed requests
-#define CPC_MSG_T_OVERRUN      21 // response type for overrun conditions
-#define CPC_MSG_T_KEEPALIVE    22 // response type for keep alive conditions
-#define CPC_MSG_T_CANERROR     23 // response type for bus error conditions
-#define CPC_MSG_T_DISCONNECTED 24 // response type for a disconnected interface
-#define CPC_MSG_T_ERR_COUNTER  25 // RX/TX error counter of CAN controller
-
-#define CPC_MSG_T_FIRMWARE    100 // response type for USB firmware download
-
-// Messages from the PC to the CPC interface contain a command field
-// Most of the command types are wrapped by the library functions and have therefore
-// normally not to be used.
-// However, programmers who wish to circumvent the library and talk directly
-// to the drivers (mainly Linux programmers) can use the following
-// command types:
-
-#define CPC_CMD_T_CAN                 1	// CAN data frame
-#define CPC_CMD_T_CONTROL             3	// used for control of interface/driver behaviour
-#define	CPC_CMD_T_CAN_PRMS            6	// set CAN parameters
-#define	CPC_CMD_T_CLEARBUF            8	// clears input queue; this is depricated, use CPC_CMD_T_CLEAR_MSG_QUEUE instead
-#define	CPC_CMD_T_INQ_CAN_PARMS      11	// inquire actual CAN parameters
-#define	CPC_CMD_T_FILTER_PRMS        12	// set filter parameter
-#define	CPC_CMD_T_RTR                13	// CAN remote frame
-#define	CPC_CMD_T_CANSTATE           14	// CAN state message
-#define	CPC_CMD_T_XCAN               15	// XCAN data frame
-#define CPC_CMD_T_XRTR               16	// XCAN remote frame
-#define CPC_CMD_T_RESET              17	// used to reset CAN-Controller
-#define CPC_CMD_T_INQ_INFO           18	// miscellanous information strings
-#define CPC_CMD_T_OPEN_CHAN          19	// open a channel
-#define CPC_CMD_T_CLOSE_CHAN         20	// close a channel
-#define CPC_CMD_T_CNTBUF             21	// this is depricated, use CPC_CMD_T_INQ_MSG_QUEUE_CNT instead
-#define CPC_CMD_T_CAN_EXIT          200 // exit the CAN (disable interrupts; reset bootrate; reset output_cntr; mode = 1)
-
-#define CPC_CMD_T_INQ_MSG_QUEUE_CNT  CPC_CMD_T_CNTBUF   // inquires the count of elements in the message queue
-#define CPC_CMD_T_INQ_ERR_COUNTER    25	                // request the CAN controllers error counter
-#define	CPC_CMD_T_CLEAR_MSG_QUEUE    CPC_CMD_T_CLEARBUF // clear CPC_MSG queue
-#define	CPC_CMD_T_CLEAR_CMD_QUEUE    28	                // clear CPC_CMD queue
-#define CPC_CMD_T_FIRMWARE          100                 // reserved, must not be used
-#define CPC_CMD_T_USB_RESET         101                 // reserved, must not be used
-#define CPC_CMD_T_WAIT_NOTIFY       102                 // reserved, must not be used
-#define CPC_CMD_T_WAIT_SETUP        103                 // reserved, must not be used
-#define	CPC_CMD_T_ABORT             255                 // Normally not to be used
-
-// definitions for CPC_MSG_T_INFO
-// information sources
+/*
+ * Messages from CPC to PC contain a message object type field.
+ * The following message types are sent by CPC and can be used in
+ * handlers, others should be ignored.
+ */
+#define CPC_MSG_T_RESYNC        0 /* Normally to be ignored */
+#define CPC_MSG_T_CAN           1 /* CAN data frame */
+#define CPC_MSG_T_BUSLOAD       2 /* Busload message */
+#define CPC_MSG_T_STRING        3 /* Normally to be ignored */
+#define CPC_MSG_T_CONTI         4 /* Normally to be ignored */
+#define CPC_MSG_T_MEM           7 /* Normally not to be handled */
+#define	CPC_MSG_T_RTR           8 /* CAN remote frame */
+#define CPC_MSG_T_TXACK	        9 /* Send acknowledge */
+#define CPC_MSG_T_POWERUP      10 /* Power-up message */
+#define	CPC_MSG_T_CMD_NO       11 /* Normally to be ignored */
+#define	CPC_MSG_T_CAN_PRMS     12 /* Actual CAN parameters */
+#define	CPC_MSG_T_ABORTED      13 /* Command aborted message */
+#define	CPC_MSG_T_CANSTATE     14 /* CAN state message */
+#define CPC_MSG_T_RESET        15 /* used to reset CAN-Controller */
+#define	CPC_MSG_T_XCAN         16 /* XCAN data frame */
+#define CPC_MSG_T_XRTR         17 /* XCAN remote frame */
+#define CPC_MSG_T_INFO         18 /* information strings */
+#define CPC_MSG_T_CONTROL      19 /* used for control of interface/driver behaviour */
+#define CPC_MSG_T_CONFIRM      20 /* response type for confirmed requests */
+#define CPC_MSG_T_OVERRUN      21 /* response type for overrun conditions */
+#define CPC_MSG_T_KEEPALIVE    22 /* response type for keep alive conditions */
+#define CPC_MSG_T_CANERROR     23 /* response type for bus error conditions */
+#define CPC_MSG_T_DISCONNECTED 24 /* response type for a disconnected interface */
+#define CPC_MSG_T_ERR_COUNTER  25 /* RX/TX error counter of CAN controller */
+
+#define CPC_MSG_T_FIRMWARE    100 /* response type for USB firmware download */
+
+/*
+ * Messages from the PC to the CPC interface contain a command field
+ * Most of the command types are wrapped by the library functions and have therefore
+ * normally not to be used.
+ * However, programmers who wish to circumvent the library and talk directly
+ * to the drivers (mainly Linux programmers) can use the following
+ * command types:
+ */
+#define CPC_CMD_T_CAN                 1	/* CAN data frame */
+#define CPC_CMD_T_CONTROL             3	/* used for control of interface/driver behaviour */
+#define	CPC_CMD_T_CAN_PRMS            6	/* set CAN parameters */
+#define	CPC_CMD_T_CLEARBUF            8	/* clears input queue; this is depricated, use CPC_CMD_T_CLEAR_MSG_QUEUE instead */
+#define	CPC_CMD_T_INQ_CAN_PARMS      11	/* inquire actual CAN parameters */
+#define	CPC_CMD_T_FILTER_PRMS        12	/* set filter parameter */
+#define	CPC_CMD_T_RTR                13	/* CAN remote frame */
+#define	CPC_CMD_T_CANSTATE           14	/* CAN state message */
+#define	CPC_CMD_T_XCAN               15	/* XCAN data frame */
+#define CPC_CMD_T_XRTR               16	/* XCAN remote frame */
+#define CPC_CMD_T_RESET              17	/* used to reset CAN-Controller */
+#define CPC_CMD_T_INQ_INFO           18	/* miscellanous information strings */
+#define CPC_CMD_T_OPEN_CHAN          19	/* open a channel */
+#define CPC_CMD_T_CLOSE_CHAN         20	/* close a channel */
+#define CPC_CMD_T_CNTBUF             21	/* this is depricated, use CPC_CMD_T_INQ_MSG_QUEUE_CNT instead */
+#define CPC_CMD_T_CAN_EXIT          200 /* exit the CAN (disable interrupts; reset bootrate; reset output_cntr; mode = 1) */
+
+#define CPC_CMD_T_INQ_MSG_QUEUE_CNT  CPC_CMD_T_CNTBUF   /* inquires the count of elements in the message queue */
+#define CPC_CMD_T_INQ_ERR_COUNTER    25	                /* request the CAN controllers error counter */
+#define	CPC_CMD_T_CLEAR_MSG_QUEUE    CPC_CMD_T_CLEARBUF /* clear CPC_MSG queue */
+#define	CPC_CMD_T_CLEAR_CMD_QUEUE    28	                /* clear CPC_CMD queue */
+#define CPC_CMD_T_FIRMWARE          100                 /* reserved, must not be used */
+#define CPC_CMD_T_USB_RESET         101                 /* reserved, must not be used */
+#define CPC_CMD_T_WAIT_NOTIFY       102                 /* reserved, must not be used */
+#define CPC_CMD_T_WAIT_SETUP        103                 /* reserved, must not be used */
+#define	CPC_CMD_T_ABORT             255                 /* Normally not to be used */
+
+/* definitions for CPC_MSG_T_INFO information sources */
 #define CPC_INFOMSG_T_UNKNOWN_SOURCE 0
 #define CPC_INFOMSG_T_INTERFACE      1
 #define CPC_INFOMSG_T_DRIVER         2
 #define CPC_INFOMSG_T_LIBRARY        3
 
-// information types
+/* information types */
 #define CPC_INFOMSG_T_UNKNOWN_TYPE   0
 #define CPC_INFOMSG_T_VERSION        1
 #define CPC_INFOMSG_T_SERIAL         2
 
-// definitions for controller types
-#define PCA82C200   1 // Philips basic CAN controller, replaced by SJA1000
-#define SJA1000     2 // Philips basic CAN controller
-#define AN82527     3 // Intel full CAN controller
-#define M16C_BASIC  4 // M16C controller running in basic CAN (not full CAN) mode
-
-// channel open error codes
-#define CPC_ERR_NO_FREE_CHANNEL            -1	// no more free space within the channel array
-#define CPC_ERR_CHANNEL_ALREADY_OPEN       -2	// the channel is already open
-#define CPC_ERR_CHANNEL_NOT_ACTIVE         -3	// access to a channel not active failed
-#define CPC_ERR_NO_DRIVER_PRESENT          -4	// no driver at the location searched by the library
-#define CPC_ERR_NO_INIFILE_PRESENT         -5	// the library could not find the inifile
-#define CPC_ERR_WRONG_PARAMETERS           -6	// wrong parameters in the inifile
-#define CPC_ERR_NO_INTERFACE_PRESENT       -7	// 1. The specified interface is not connected
-						// 2. The interface (mostly CPC-USB) was disconnected upon operation
-#define CPC_ERR_NO_MATCHING_CHANNEL        -8	// the driver couldn't find a matching channel
-#define CPC_ERR_NO_BUFFER_AVAILABLE        -9	// the driver couldn't allocate buffer for messages
-#define CPC_ERR_NO_INTERRUPT               -10	// the requested interrupt couldn't be claimed
-#define CPC_ERR_NO_MATCHING_INTERFACE      -11	// no interface type related to this channel was found
-#define CPC_ERR_NO_RESOURCES               -12	// the requested resources could not be claimed
-#define CPC_ERR_SOCKET                     -13	// error concerning TCP sockets
-
-// init error codes
-#define CPC_ERR_WRONG_CONTROLLER_TYPE      -14	// wrong CAN controller type within initialization
-#define CPC_ERR_NO_RESET_MODE              -15	// the controller could not be set into reset mode
-#define CPC_ERR_NO_CAN_ACCESS              -16	// the CAN controller could not be accessed
-
-// transmit error codes
-#define CPC_ERR_CAN_WRONG_ID               -20	// the provided CAN id is too big
-#define CPC_ERR_CAN_WRONG_LENGTH           -21	// the provided CAN length is too long
-#define CPC_ERR_CAN_NO_TRANSMIT_BUF        -22	// the transmit buffer was occupied
-#define CPC_ERR_CAN_TRANSMIT_TIMEOUT       -23	// The message could not be sent within a
-						// specified time
-
-// other error codes
-#define CPC_ERR_SERVICE_NOT_SUPPORTED      -30	// the requested service is not supported by the interface
-#define CPC_ERR_IO_TRANSFER                -31	// a transmission error down to the driver occurred
-#define CPC_ERR_TRANSMISSION_FAILED        -32	// a transmission error down to the interface occurred
-#define CPC_ERR_TRANSMISSION_TIMEOUT       -33	// a timeout occurred within transmission to the interface
-#define CPC_ERR_OP_SYS_NOT_SUPPORTED       -35	// the operating system is not supported
-#define CPC_ERR_UNKNOWN                    -40	// an unknown error ocurred (mostly IOCTL errors)
-
-#define CPC_ERR_LOADING_DLL                -50	// the library 'cpcwin.dll' could not be loaded
-#define CPC_ERR_ASSIGNING_FUNCTION         -51	// the specified function could not be assigned
-#define CPC_ERR_DLL_INITIALIZATION         -52	// the DLL was not initialized correctly
-#define CPC_ERR_MISSING_LICFILE            -55	// the file containing the licenses does not exist
-#define CPC_ERR_MISSING_LICENSE            -56	// a required license was not found
-
-// CAN state bit values. Ignore any bits not listed
+/* definitions for controller types */
+#define PCA82C200   1 /* Philips basic CAN controller, replaced by SJA1000 */
+#define SJA1000     2 /* Philips basic CAN controller */
+#define AN82527     3 /* Intel full CAN controller */
+#define M16C_BASIC  4 /* M16C controller running in basic CAN (not full CAN) mode */
+
+/* channel open error codes */
+#define CPC_ERR_NO_FREE_CHANNEL            -1	/* no more free space within the channel array */
+#define CPC_ERR_CHANNEL_ALREADY_OPEN       -2	/* the channel is already open */
+#define CPC_ERR_CHANNEL_NOT_ACTIVE         -3	/* access to a channel not active failed */
+#define CPC_ERR_NO_DRIVER_PRESENT          -4	/* no driver at the location searched by the library */
+#define CPC_ERR_NO_INIFILE_PRESENT         -5	/* the library could not find the inifile */
+#define CPC_ERR_WRONG_PARAMETERS           -6	/* wrong parameters in the inifile */
+#define CPC_ERR_NO_INTERFACE_PRESENT       -7	/* 1. The specified interface is not connected */
+						/* 2. The interface (mostly CPC-USB) was disconnected upon operation */
+#define CPC_ERR_NO_MATCHING_CHANNEL        -8	/* the driver couldn't find a matching channel */
+#define CPC_ERR_NO_BUFFER_AVAILABLE        -9	/* the driver couldn't allocate buffer for messages */
+#define CPC_ERR_NO_INTERRUPT               -10	/* the requested interrupt couldn't be claimed */
+#define CPC_ERR_NO_MATCHING_INTERFACE      -11	/* no interface type related to this channel was found */
+#define CPC_ERR_NO_RESOURCES               -12	/* the requested resources could not be claimed */
+#define CPC_ERR_SOCKET                     -13	/* error concerning TCP sockets */
+
+/* init error codes */
+#define CPC_ERR_WRONG_CONTROLLER_TYPE      -14	/* wrong CAN controller type within initialization */
+#define CPC_ERR_NO_RESET_MODE              -15	/* the controller could not be set into reset mode */
+#define CPC_ERR_NO_CAN_ACCESS              -16	/* the CAN controller could not be accessed */
+
+/* transmit error codes */
+#define CPC_ERR_CAN_WRONG_ID               -20	/* the provided CAN id is too big */
+#define CPC_ERR_CAN_WRONG_LENGTH           -21	/* the provided CAN length is too long */
+#define CPC_ERR_CAN_NO_TRANSMIT_BUF        -22	/* the transmit buffer was occupied */
+#define CPC_ERR_CAN_TRANSMIT_TIMEOUT       -23	/* The message could not be sent within a */
+						/* specified time */
+
+/* other error codes */
+#define CPC_ERR_SERVICE_NOT_SUPPORTED      -30	/* the requested service is not supported by the interface */
+#define CPC_ERR_IO_TRANSFER                -31	/* a transmission error down to the driver occurred */
+#define CPC_ERR_TRANSMISSION_FAILED        -32	/* a transmission error down to the interface occurred */
+#define CPC_ERR_TRANSMISSION_TIMEOUT       -33	/* a timeout occurred within transmission to the interface */
+#define CPC_ERR_OP_SYS_NOT_SUPPORTED       -35	/* the operating system is not supported */
+#define CPC_ERR_UNKNOWN                    -40	/* an unknown error ocurred (mostly IOCTL errors) */
+
+#define CPC_ERR_LOADING_DLL                -50	/* the library 'cpcwin.dll' could not be loaded */
+#define CPC_ERR_ASSIGNING_FUNCTION         -51	/* the specified function could not be assigned */
+#define CPC_ERR_DLL_INITIALIZATION         -52	/* the DLL was not initialized correctly */
+#define CPC_ERR_MISSING_LICFILE            -55	/* the file containing the licenses does not exist */
+#define CPC_ERR_MISSING_LICENSE            -56	/* a required license was not found */
+
+/* CAN state bit values. Ignore any bits not listed */
 #define CPC_CAN_STATE_BUSOFF     0x80
 #define CPC_CAN_STATE_ERROR      0x40
 
-// Mask to help ignore undefined bits
+/* Mask to help ignore undefined bits */
 #define CPC_CAN_STATE_MASK       0xc0
 
-// CAN-Message representation in a CPC_MSG
-// Message object type is CPC_MSG_T_CAN or CPC_MSG_T_RTR
-// or CPC_MSG_T_XCAN or CPC_MSG_T_XRTR
+/*
+ * CAN-Message representation in a CPC_MS
+ * Message object type is CPC_MSG_T_CAN or CPC_MSG_T_RTR
+ * or CPC_MSG_T_XCAN or CPC_MSG_T_XRTR
+ */
 typedef struct CPC_CAN_MSG {
 	u32 id;
 	u8 length;
 	u8 msg[8];
 } CPC_CAN_MSG_T;
 
-
-// representation of the CAN parameters for the PCA82C200 controller
+/* representation of the CAN parameters for the PCA82C200 controller */
 typedef struct CPC_PCA82C200_PARAMS {
-	u8 acc_code;	// Acceptance-code for receive, Standard: 0
-	u8 acc_mask;	// Acceptance-mask for receive, Standard: 0xff (everything)
-	u8 btr0;	// Bus-timing register 0
-	u8 btr1;	// Bus-timing register 1
-	u8 outp_contr;	// Output-control register
+	u8 acc_code;	/* Acceptance-code for receive, Standard: 0 */
+	u8 acc_mask;	/* Acceptance-mask for receive, Standard: 0xff (everything) */
+	u8 btr0;	/* Bus-timing register 0 */
+	u8 btr1;	/* Bus-timing register 1 */
+	u8 outp_contr;	/* Output-control register */
 } CPC_PCA82C200_PARAMS_T;
 
-// representation of the CAN parameters for the SJA1000 controller
+/* representation of the CAN parameters for the SJA1000 controller */
 typedef struct CPC_SJA1000_PARAMS {
-	u8 mode;	// enables single or dual acceptance filtering
-	u8 acc_code0;	// Acceptance-code for receive, Standard: 0
+	u8 mode;	/* enables single or dual acceptance filtering */
+	u8 acc_code0;	/* Acceptance-code for receive, Standard: 0 */
 	u8 acc_code1;
 	u8 acc_code2;
 	u8 acc_code3;
-	u8 acc_mask0;	// Acceptance-mask for receive, Standard: 0xff (everything)
+	u8 acc_mask0;	/* Acceptance-mask for receive, Standard: 0xff (everything) */
 	u8 acc_mask1;
 	u8 acc_mask2;
 	u8 acc_mask3;
-	u8 btr0;	// Bus-timing register 0
-	u8 btr1;	// Bus-timing register 1
-	u8 outp_contr;	// Output-control register
+	u8 btr0;	/* Bus-timing register 0 */
+	u8 btr1;	/* Bus-timing register 1 */
+	u8 outp_contr;	/* Output-control register */
 } CPC_SJA1000_PARAMS_T;
 
-// representation of the CAN parameters for the M16C controller
-// in basic CAN mode (means no full CAN)
+/*
+ * representation of the CAN parameters for the M16C controller
+ * in basic CAN mode (means no full CAN)
+ */
 typedef struct CPC_M16C_BASIC_PARAMS {
 	u8 con0;
 	u8 con1;
@@ -267,9 +247,9 @@ typedef struct CPC_M16C_BASIC_PARAMS {
 	u8 acc_ext_mask3;
 } CPC_M16C_BASIC_PARAMS_T;
 
-// CAN params message representation
+/* CAN params message representation */
 typedef struct CPC_CAN_PARAMS {
-	u8 cc_type;	// represents the controller type
+	u8 cc_type;	/* represents the controller type */
 	union {
 		CPC_M16C_BASIC_PARAMS_T m16c_basic;
 		CPC_SJA1000_PARAMS_T sja1000;
@@ -277,111 +257,108 @@ typedef struct CPC_CAN_PARAMS {
 	} cc_params;
 } CPC_CAN_PARAMS_T;
 
-// the following structures are slightly different for Windows and Linux
-// To be able to use the 'Select' mechanism with Linux the application
-// needs to know the devices file desciptor.
-// This mechanism is not implemented within Windows and the file descriptor
-// is therefore not needed
-#ifdef _WIN32
-
-// CAN init params message representation
-typedef struct CPC_INIT_PARAMS {
-	CPC_CAN_PARAMS_T canparams;
-} CPC_INIT_PARAMS_T;
-
-#else// Linux
-
-// CHAN init params representation
+/* CHAN init params representation */
 typedef struct CPC_CHAN_PARAMS {
 	int fd;
 } CPC_CHAN_PARAMS_T;
 
-// CAN init params message representation
+/* CAN init params message representation */
 typedef struct CPC_INIT_PARAMS {
 	CPC_CHAN_PARAMS_T chanparams;
 	CPC_CAN_PARAMS_T canparams;
 } CPC_INIT_PARAMS_T;
 
-#endif
-
-// structure for confirmed message handling
+/* structure for confirmed message handling */
 typedef struct CPC_CONFIRM {
-	u8 result; // error code
+	u8 result; /* error code */
 } CPC_CONFIRM_T;
 
-// structure for information requests
+/* structure for information requests */
 typedef struct CPC_INFO {
-	u8 source;                 // interface, driver or library
-	u8 type;                   // version or serial number
-	char msg[CPC_MSG_LEN - 2]; // string holding the requested information
+	u8 source;                 /* interface, driver or library */
+	u8 type;                   /* version or serial number */
+	char msg[CPC_MSG_LEN - 2]; /* string holding the requested information */
 } CPC_INFO_T;
 
-// OVERRUN ///////////////////////////////////////
-// In general two types of overrun may occur.
-// A hardware overrun, where the CAN controller
-// lost a message, because the interrupt was
-// not handled before the next messgae comes in.
-// Or a software overrun, where i.e. a received
-// message could not be stored in the CPC_MSG
-// buffer.
-
-// After a software overrun has occurred
-// we wait until we have CPC_OVR_GAP slots
-// free in the CPC_MSG buffer.
+/*
+ * OVERRUN
+ * In general two types of overrun may occur.
+ * A hardware overrun, where the CAN controller
+ * lost a message, because the interrupt was
+ * not handled before the next messgae comes in.
+ * Or a software overrun, where i.e. a received
+ * message could not be stored in the CPC_MSG
+ * buffer.
+ */
+
+/* After a software overrun has occurred
+ * we wait until we have CPC_OVR_GAP slots
+ * free in the CPC_MSG buffer.
+ */
 #define CPC_OVR_GAP               10
 
-// Two types of software overrun may occur.
-// A received CAN message or a CAN state event
-// can cause an overrun.
-// Note: A CPC_CMD which would normally store
-// its result immediately in the CPC_MSG
-// queue may fail, because the message queue is full.
-// This will not generate an overrun message, but
-// will halt command execution, until this command
-// is able to store its message in the message queue.
+/*
+ * Two types of software overrun may occur.
+ * A received CAN message or a CAN state event
+ * can cause an overrun.
+ * Note: A CPC_CMD which would normally store
+ * its result immediately in the CPC_MSG
+ * queue may fail, because the message queue is full.
+ * This will not generate an overrun message, but
+ * will halt command execution, until this command
+ * is able to store its message in the message queue.
+ */
 #define CPC_OVR_EVENT_CAN       0x01
 #define CPC_OVR_EVENT_CANSTATE  0x02
 #define CPC_OVR_EVENT_BUSERROR  0x04
 
-// If the CAN controller lost a message
-// we indicate it with the highest bit
-// set in the count field.
+/*
+ * If the CAN controller lost a message
+ * we indicate it with the highest bit
+ * set in the count field.
+ */
 #define CPC_OVR_HW              0x80
 
-// structure for overrun conditions
+/* structure for overrun conditions */
 typedef struct {
 	u8 event;
 	u8 count;
 } CPC_OVERRUN_T;
 
-// CAN errors ////////////////////////////////////
-// Each CAN controller type has different
-// registers to record errors.
-// Therefor a structure containing the specific
-// errors is set up for each controller here
+/*
+ * CAN errors
+ * Each CAN controller type has different
+ * registers to record errors.
+ * Therefor a structure containing the specific
+ * errors is set up for each controller here
+ */
 
-// SJA1000 error structure
-// see the SJA1000 datasheet for detailed
-// explanation of the registers
+/*
+ * SJA1000 error structure
+ * see the SJA1000 datasheet for detailed
+ * explanation of the registers
+ */
 typedef struct CPC_SJA1000_CAN_ERROR {
-	u8 ecc;   // error capture code register
-	u8 rxerr; // RX error counter register
-	u8 txerr; // TX error counter register
+	u8 ecc;   /* error capture code register */
+	u8 rxerr; /* RX error counter register */
+	u8 txerr; /* TX error counter register */
 } CPC_SJA1000_CAN_ERROR_T;
 
-// M16C error structure
-// see the M16C datasheet for detailed
-// explanation of the registers
+/*
+ * M16C error structure
+ * see the M16C datasheet for detailed
+ * explanation of the registers
+ */
 typedef struct CPC_M16C_CAN_ERROR {
-	u8 tbd;	// to be defined
+	u8 tbd;	/* to be defined */
 } CPC_M16C_CAN_ERROR_T;
 
-// structure for CAN error conditions
+/* structure for CAN error conditions */
 #define  CPC_CAN_ECODE_ERRFRAME   0x01
 typedef struct CPC_CAN_ERROR {
 	u8 ecode;
 	struct {
-		u8 cc_type; // CAN controller type
+		u8 cc_type; /* CAN controller type */
 		union {
 			CPC_SJA1000_CAN_ERROR_T sja1000;
 			CPC_M16C_CAN_ERROR_T m16c;
@@ -389,36 +366,40 @@ typedef struct CPC_CAN_ERROR {
 	} cc;
 } CPC_CAN_ERROR_T;
 
-// Structure containing RX/TX error counter.
-// This structure is used to request the
-// values of the CAN controllers TX and RX
-// error counter.
+/*
+ * Structure containing RX/TX error counter.
+ * This structure is used to request the
+ * values of the CAN controllers TX and RX
+ * error counter.
+ */
 typedef struct CPC_CAN_ERR_COUNTER {
 	u8 rx;
 	u8 tx;
 } CPC_CAN_ERR_COUNTER_T;
 
-// If this flag is set, transmissions from PC to CPC are protected against loss
+/* If this flag is set, transmissions from PC to CPC are protected against loss */
 #define CPC_SECURE_TO_CPC	0x01
 
-// If this flag is set, transmissions from CPC to PC are protected against loss
+/* If this flag is set, transmissions from CPC to PC are protected against loss */
 #define CPC_SECURE_TO_PC	0x02
 
-// If this flag is set, the CAN-transmit buffer is checked to be free before sending a message
+/* If this flag is set, the CAN-transmit buffer is checked to be free before sending a message */
 #define CPC_SECURE_SEND		0x04
 
-// If this flag is set, the transmission complete flag is checked
-// after sending a message
-// THIS IS CURRENTLY ONLY IMPLEMENTED IN THE PASSIVE INTERFACE DRIVERS
+/*
+ * If this flag is set, the transmission complete flag is checked
+ * after sending a message
+ * THIS IS CURRENTLY ONLY IMPLEMENTED IN THE PASSIVE INTERFACE DRIVERS
+ */
 #define CPC_SECURE_TRANSMIT	0x08
 
-// main message type used between library and application
+/* main message type used between library and application */
 typedef struct CPC_MSG {
-	u8 type;	// type of message
-	u8 length;	// length of data within union 'msg'
-	u8 msgid;	// confirmation handle
-	u32 ts_sec;	// timestamp in seconds
-	u32 ts_nsec;	// timestamp in nano seconds
+	u8 type;	/* type of message */
+	u8 length;	/* length of data within union 'msg' */
+	u8 msgid;	/* confirmation handle */
+	u32 ts_sec;	/* timestamp in seconds */
+	u32 ts_nsec;	/* timestamp in nano seconds */
 	union {
 		u8 generic[CPC_MSG_LEN];
 		CPC_CAN_MSG_T canmsg;
@@ -433,8 +414,4 @@ typedef struct CPC_MSG {
 	} msg;
 } CPC_MSG_T;
 
-#ifdef _WIN32
-#pragma pack(pop)		// reset the byte alignment
-#endif
-
-#endif				// CPC_HEADER
+#endif /* CPC_HEADER */
diff --git a/drivers/staging/cpc-usb/cpc_int.h b/drivers/staging/cpc-usb/cpc_int.h
index a0d60c0..38674e9 100644
--- a/drivers/staging/cpc-usb/cpc_int.h
+++ b/drivers/staging/cpc-usb/cpc_int.h
@@ -39,10 +39,10 @@ typedef void (*chan_write_byte_t) (void *chan, unsigned int reg,
 typedef unsigned char (*chan_read_byte_t) (void *chan, unsigned int reg);
 
 typedef struct CPC_CHAN {
-	void __iomem * canBase;	// base address of SJA1000
-	chan_read_byte_t read_byte;	// CAN controller read access routine
-	chan_write_byte_t write_byte;	// CAN controller write access routine
-	CPC_MSG_T *buf;		// buffer for CPC msg
+	void __iomem * canBase;	/* base address of SJA1000 */
+	chan_read_byte_t read_byte;	/* CAN controller read access routine */
+	chan_write_byte_t write_byte;	/* CAN controller write access routine */
+	CPC_MSG_T *buf;		/* buffer for CPC msg */
 	unsigned int iidx;
 	unsigned int oidx;
 	unsigned int WnR;
diff --git a/drivers/staging/cpc-usb/cpcusb.h b/drivers/staging/cpc-usb/cpcusb.h
index e5273dd..6bdf30b 100644
--- a/drivers/staging/cpc-usb/cpcusb.h
+++ b/drivers/staging/cpc-usb/cpcusb.h
@@ -75,7 +75,7 @@ typedef struct CPC_USB {
 #define CPC_DRIVER_VERSION "0.724"
 #define CPC_DRIVER_SERIAL  "not applicable"
 
-#define OBUF_SIZE 255		// 4096
+#define OBUF_SIZE 255		/* 4096 */
 
 /* read timeouts -- RD_NAK_TIMEOUT * RD_EXPIRE = Number of seconds */
 #define RD_NAK_TIMEOUT (10*HZ)	/* Default number of X seconds to wait */
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
new file mode 100644
index 0000000..df7756a
--- /dev/null
+++ b/drivers/staging/cx25821/Kconfig
@@ -0,0 +1,34 @@
+config VIDEO_CX25821
+	tristate "Conexant cx25821 support"
+	depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
+	select I2C_ALGOBIT
+	select VIDEO_BTCX
+	select VIDEO_TVEEPROM
+	select VIDEO_IR
+	select VIDEOBUF_DVB
+	select VIDEOBUF_DMA_SG
+	select VIDEO_CX25840
+	select VIDEO_CX2341X
+	---help---
+	  This is a video4linux driver for Conexant 25821 based
+	  TV cards.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cx25821
+
+config VIDEO_CX25821_ALSA
+	tristate "Conexant 25821 DMA audio support"
+	depends on VIDEO_CX25821 && SND && EXPERIMENTAL
+	select SND_PCM
+	---help---
+	  This is a video4linux driver for direct (DMA) audio on
+	  Conexant 25821 based capture cards using ALSA.
+
+	  It only works with boards with function 01 enabled.
+	  To check if your board supports, use lspci -n.
+	  If supported, you should see 14f1:8801 or 14f1:8811
+	  PCI device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cx25821-alsa.
+
diff --git a/drivers/staging/cx25821/Makefile b/drivers/staging/cx25821/Makefile
new file mode 100644
index 0000000..10f87f0
--- /dev/null
+++ b/drivers/staging/cx25821/Makefile
@@ -0,0 +1,14 @@
+cx25821-objs	:= cx25821-core.o cx25821-cards.o cx25821-i2c.o cx25821-gpio.o 				\
+				cx25821-medusa-video.o cx25821-video.o cx25821-video0.o cx25821-video1.o    \
+				cx25821-video2.o cx25821-video3.o cx25821-video4.o cx25821-video5.o         \
+				cx25821-video6.o cx25821-video7.o cx25821-vidups9.o cx25821-vidups10.o      \
+				cx25821-audups11.o cx25821-video-upstream.o cx25821-video-upstream-ch2.o 	\
+				cx25821-audio-upstream.o cx25821-videoioctl.o
+
+obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
+obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+EXTRA_CFLAGS += -Idrivers/media/common/tuners
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/staging/cx25821/README b/drivers/staging/cx25821/README
new file mode 100644
index 0000000..a9ba50b
--- /dev/null
+++ b/drivers/staging/cx25821/README
@@ -0,0 +1,6 @@
+Todo:
+	- checkpatch.pl cleanups
+	- sparse cleanups
+
+Please send patches to linux-media@vger.kernel.org
+
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
new file mode 100644
index 0000000..e0eef12
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -0,0 +1,789 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *	Based on SAA713x ALSA driver and CX88 driver
+ *
+ *   This program is free software; 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
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU 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/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <linux/dma-mapping.h>
+#include <linux/pci.h>
+
+#include <asm/delay.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/control.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "cx25821.h"
+#include "cx25821-reg.h"
+
+#define AUDIO_SRAM_CHANNEL	SRAM_CH08
+
+#define dprintk(level,fmt, arg...)	if (debug >= level) \
+	printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
+
+#define dprintk_core(level,fmt, arg...)	if (debug >= level) \
+	printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
+
+/****************************************************************************
+	Data type declarations - Can be moded to a header file later
+ ****************************************************************************/
+
+static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
+static int devno;
+
+struct cx25821_audio_dev {
+	struct cx25821_dev *dev;
+	struct cx25821_dmaqueue q;
+
+	/* pci i/o */
+	struct pci_dev *pci;
+
+	/* audio controls */
+	int irq;
+
+	struct snd_card *card;
+
+	unsigned long iobase;
+	spinlock_t reg_lock;
+	atomic_t count;
+
+	unsigned int dma_size;
+	unsigned int period_size;
+	unsigned int num_periods;
+
+	struct videobuf_dmabuf *dma_risc;
+
+	struct cx25821_buffer *buf;
+
+	struct snd_pcm_substream *substream;
+};
+typedef struct cx25821_audio_dev snd_cx25821_card_t;
+
+
+/****************************************************************************
+			Module global static vars
+ ****************************************************************************/
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
+static int enable[SNDRV_CARDS] = { 1,[1 ... (SNDRV_CARDS - 1)] = 1 };
+
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s).");
+
+/****************************************************************************
+				Module macros
+ ****************************************************************************/
+
+MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards");
+MODULE_AUTHOR("Hiep Huynh");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Conexant,25821}");	//"{{Conexant,23881},"
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
+
+/****************************************************************************
+			Module specific funtions
+ ****************************************************************************/
+/* Constants taken from cx88-reg.h */
+#define AUD_INT_DN_RISCI1       (1 <<  0)
+#define AUD_INT_UP_RISCI1       (1 <<  1)
+#define AUD_INT_RDS_DN_RISCI1   (1 <<  2)
+#define AUD_INT_DN_RISCI2       (1 <<  4)	/* yes, 3 is skipped */
+#define AUD_INT_UP_RISCI2       (1 <<  5)
+#define AUD_INT_RDS_DN_RISCI2   (1 <<  6)
+#define AUD_INT_DN_SYNC         (1 << 12)
+#define AUD_INT_UP_SYNC         (1 << 13)
+#define AUD_INT_RDS_DN_SYNC     (1 << 14)
+#define AUD_INT_OPC_ERR         (1 << 16)
+#define AUD_INT_BER_IRQ         (1 << 20)
+#define AUD_INT_MCHG_IRQ        (1 << 21)
+#define GP_COUNT_CONTROL_RESET	0x3
+
+#define PCI_MSK_AUD_EXT   (1 <<  4)
+#define PCI_MSK_AUD_INT   (1 <<  3)
+/*
+ * BOARD Specific: Sets audio DMA
+ */
+
+static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
+{
+	struct cx25821_buffer *buf = chip->buf;
+	struct cx25821_dev *dev = chip->dev;
+	struct sram_channel *audio_ch =
+	    &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
+	u32 tmp = 0;
+
+	// enable output on the GPIO 0 for the MCLK ADC (Audio)
+	cx25821_set_gpiopin_direction(chip->dev, 0, 0);
+
+	/* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
+	cx_clear(AUD_INT_DMA_CTL,
+		 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
+
+	/* setup fifo + format - out channel */
+	cx25821_sram_channel_setup_audio(chip->dev, audio_ch, buf->bpl,
+					 buf->risc.dma);
+
+	/* sets bpl size */
+	cx_write(AUD_A_LNGTH, buf->bpl);
+
+	/* reset counter */
+	cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);	//GP_COUNT_CONTROL_RESET = 0x3
+	atomic_set(&chip->count, 0);
+
+	//Set the input mode to 16-bit
+	tmp = cx_read(AUD_A_CFG);
+	cx_write(AUD_A_CFG,
+		 tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
+		 FLD_AUD_CLK_ENABLE);
+
+	//printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d "
+	//      "byte buffer\n", buf->bpl, audio_ch->cmds_start, cx_read(audio_ch->cmds_start + 12)>>1,
+	//      chip->num_periods, buf->bpl * chip->num_periods);
+
+	/* Enables corresponding bits at AUD_INT_STAT */
+	cx_write(AUD_A_INT_MSK,
+		 FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC |
+		 FLD_AUD_DST_OPC_ERR);
+
+	/* Clean any pending interrupt bits already set */
+	cx_write(AUD_A_INT_STAT, ~0);
+
+	/* enable audio irqs */
+	cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT);
+
+	// Turn on audio downstream fifo and risc enable 0x101
+	tmp = cx_read(AUD_INT_DMA_CTL);
+	cx_set(AUD_INT_DMA_CTL,
+	       tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
+
+	mdelay(100);
+	return 0;
+}
+
+/*
+ * BOARD Specific: Resets audio DMA
+ */
+static int _cx25821_stop_audio_dma(snd_cx25821_card_t * chip)
+{
+	struct cx25821_dev *dev = chip->dev;
+
+	/* stop dma */
+	cx_clear(AUD_INT_DMA_CTL,
+		 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
+
+	/* disable irqs */
+	cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
+	cx_clear(AUD_A_INT_MSK,
+		 AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 |
+		 AUD_INT_DN_RISCI1);
+
+	return 0;
+}
+
+#define MAX_IRQ_LOOP 50
+
+/*
+ * BOARD Specific: IRQ dma bits
+ */
+static char *cx25821_aud_irqs[32] = {
+	"dn_risci1", "up_risci1", "rds_dn_risc1",	/* 0-2 */
+	NULL,			/* reserved */
+	"dn_risci2", "up_risci2", "rds_dn_risc2",	/* 4-6 */
+	NULL,			/* reserved */
+	"dnf_of", "upf_uf", "rds_dnf_uf",	/* 8-10 */
+	NULL,			/* reserved */
+	"dn_sync", "up_sync", "rds_dn_sync",	/* 12-14 */
+	NULL,			/* reserved */
+	"opc_err", "par_err", "rip_err",	/* 16-18 */
+	"pci_abort", "ber_irq", "mchg_irq"	/* 19-21 */
+};
+
+/*
+ * BOARD Specific: Threats IRQ audio specific calls
+ */
+static void cx25821_aud_irq(snd_cx25821_card_t * chip, u32 status, u32 mask)
+{
+	struct cx25821_dev *dev = chip->dev;
+
+	if (0 == (status & mask)) {
+		return;
+	}
+
+	cx_write(AUD_A_INT_STAT, status);
+	if (debug > 1 || (status & mask & ~0xff))
+		cx25821_print_irqbits(dev->name, "irq aud",
+				      cx25821_aud_irqs,
+				      ARRAY_SIZE(cx25821_aud_irqs), status,
+				      mask);
+
+	/* risc op code error */
+	if (status & AUD_INT_OPC_ERR) {
+		printk(KERN_WARNING "WARNING %s/1: Audio risc op code error\n",
+		       dev->name);
+
+		cx_clear(AUD_INT_DMA_CTL,
+			 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
+		cx25821_sram_channel_dump_audio(dev,
+						&cx25821_sram_channels
+						[AUDIO_SRAM_CHANNEL]);
+	}
+	if (status & AUD_INT_DN_SYNC) {
+		printk(KERN_WARNING "WARNING %s: Downstream sync error!\n",
+		       dev->name);
+		cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
+		return;
+	}
+
+	/* risc1 downstream */
+	if (status & AUD_INT_DN_RISCI1) {
+		atomic_set(&chip->count, cx_read(AUD_A_GPCNT));
+		snd_pcm_period_elapsed(chip->substream);
+	}
+}
+
+/*
+ * BOARD Specific: Handles IRQ calls
+ */
+static irqreturn_t cx25821_irq(int irq, void *dev_id)
+{
+	snd_cx25821_card_t *chip = dev_id;
+	struct cx25821_dev *dev = chip->dev;
+	u32 status, pci_status;
+	u32 audint_status, audint_mask;
+	int loop, handled = 0;
+	int audint_count = 0;
+
+	audint_status = cx_read(AUD_A_INT_STAT);
+	audint_mask = cx_read(AUD_A_INT_MSK);
+	audint_count = cx_read(AUD_A_GPCNT);
+	status = cx_read(PCI_INT_STAT);
+
+	for (loop = 0; loop < 1; loop++) {
+		status = cx_read(PCI_INT_STAT);
+		if (0 == status) {
+			status = cx_read(PCI_INT_STAT);
+			audint_status = cx_read(AUD_A_INT_STAT);
+			audint_mask = cx_read(AUD_A_INT_MSK);
+
+			if (status) {
+				handled = 1;
+				cx_write(PCI_INT_STAT, status);
+
+				cx25821_aud_irq(chip, audint_status,
+						audint_mask);
+				break;
+			} else
+				goto out;
+		}
+
+		handled = 1;
+		cx_write(PCI_INT_STAT, status);
+
+		cx25821_aud_irq(chip, audint_status, audint_mask);
+	}
+
+	pci_status = cx_read(PCI_INT_STAT);
+
+	if (handled)
+		cx_write(PCI_INT_STAT, pci_status);
+
+      out:
+	return IRQ_RETVAL(handled);
+}
+
+static int dsp_buffer_free(snd_cx25821_card_t * chip)
+{
+	BUG_ON(!chip->dma_size);
+
+	dprintk(2, "Freeing buffer\n");
+	videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc);
+	videobuf_dma_free(chip->dma_risc);
+	btcx_riscmem_free(chip->pci, &chip->buf->risc);
+	kfree(chip->buf);
+
+	chip->dma_risc = NULL;
+	chip->dma_size = 0;
+
+	return 0;
+}
+
+/****************************************************************************
+				ALSA PCM Interface
+ ****************************************************************************/
+
+/*
+ * Digital hardware definition
+ */
+#define DEFAULT_FIFO_SIZE	384
+static struct snd_pcm_hardware snd_cx25821_digital_hw = {
+	.info = SNDRV_PCM_INFO_MMAP |
+	    SNDRV_PCM_INFO_INTERLEAVED |
+	    SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE,
+
+	.rates = SNDRV_PCM_RATE_48000,
+	.rate_min = 48000,
+	.rate_max = 48000,
+	.channels_min = 2,
+	.channels_max = 2,
+	/* Analog audio output will be full of clicks and pops if there
+	   are not exactly four lines in the SRAM FIFO buffer.  */
+	.period_bytes_min = DEFAULT_FIFO_SIZE / 3,
+	.period_bytes_max = DEFAULT_FIFO_SIZE / 3,
+	.periods_min = 1,
+	.periods_max = AUDIO_LINE_SIZE,
+	.buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE),	//128*128 = 16384 = 1024 * 16
+};
+
+/*
+ * audio pcm capture open callback
+ */
+static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
+{
+	snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	int err;
+	unsigned int bpl = 0;
+
+	if (!chip) {
+		printk(KERN_ERR "DEBUG: cx25821 can't find device struct."
+		       " Can't proceed with open\n");
+		return -ENODEV;
+	}
+
+	err =
+	    snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
+	if (err < 0)
+		goto _error;
+
+	chip->substream = substream;
+
+	runtime->hw = snd_cx25821_digital_hw;
+
+	if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size !=
+	    DEFAULT_FIFO_SIZE) {
+		bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3;	//since there are 3 audio Clusters
+		bpl &= ~7;	/* must be multiple of 8 */
+
+		if (bpl > AUDIO_LINE_SIZE) {
+			bpl = AUDIO_LINE_SIZE;
+		}
+		runtime->hw.period_bytes_min = bpl;
+		runtime->hw.period_bytes_max = bpl;
+	}
+
+	return 0;
+      _error:
+	dprintk(1, "Error opening PCM!\n");
+	return err;
+}
+
+/*
+ * audio close callback
+ */
+static int snd_cx25821_close(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+/*
+ * hw_params callback
+ */
+static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
+{
+	snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
+	struct videobuf_dmabuf *dma;
+
+	struct cx25821_buffer *buf;
+	int ret;
+
+	if (substream->runtime->dma_area) {
+		dsp_buffer_free(chip);
+		substream->runtime->dma_area = NULL;
+	}
+
+	chip->period_size = params_period_bytes(hw_params);
+	chip->num_periods = params_periods(hw_params);
+	chip->dma_size = chip->period_size * params_periods(hw_params);
+
+	BUG_ON(!chip->dma_size);
+	BUG_ON(chip->num_periods & (chip->num_periods - 1));
+
+	buf = videobuf_sg_alloc(sizeof(*buf));
+	if (NULL == buf)
+		return -ENOMEM;
+
+	if (chip->period_size > AUDIO_LINE_SIZE) {
+		chip->period_size = AUDIO_LINE_SIZE;
+	}
+
+	buf->vb.memory = V4L2_MEMORY_MMAP;
+	buf->vb.field = V4L2_FIELD_NONE;
+	buf->vb.width = chip->period_size;
+	buf->bpl = chip->period_size;
+	buf->vb.height = chip->num_periods;
+	buf->vb.size = chip->dma_size;
+
+	dma = videobuf_to_dma(&buf->vb);
+	videobuf_dma_init(dma);
+
+	ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
+				       (PAGE_ALIGN(buf->vb.size) >>
+					PAGE_SHIFT));
+	if (ret < 0)
+		goto error;
+
+	ret = videobuf_sg_dma_map(&chip->pci->dev, dma);
+	if (ret < 0)
+		goto error;
+
+	ret =
+	    cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
+					  buf->vb.width, buf->vb.height, 1);
+	if (ret < 0) {
+		printk(KERN_INFO
+		       "DEBUG: ERROR after cx25821_risc_databuffer_audio() \n");
+		goto error;
+	}
+
+	/* Loop back to start of program */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	buf->vb.state = VIDEOBUF_PREPARED;
+
+	chip->buf = buf;
+	chip->dma_risc = dma;
+
+	substream->runtime->dma_area = chip->dma_risc->vmalloc;
+	substream->runtime->dma_bytes = chip->dma_size;
+	substream->runtime->dma_addr = 0;
+
+	return 0;
+
+      error:
+	kfree(buf);
+	return ret;
+}
+
+/*
+ * hw free callback
+ */
+static int snd_cx25821_hw_free(struct snd_pcm_substream *substream)
+{
+	snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
+
+	if (substream->runtime->dma_area) {
+		dsp_buffer_free(chip);
+		substream->runtime->dma_area = NULL;
+	}
+
+	return 0;
+}
+
+/*
+ * prepare callback
+ */
+static int snd_cx25821_prepare(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+/*
+ * trigger callback
+ */
+static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream,
+				    int cmd)
+{
+	snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
+	int err = 0;
+
+	/* Local interrupts are already disabled by ALSA */
+	spin_lock(&chip->reg_lock);
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		err = _cx25821_start_audio_dma(chip);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		err = _cx25821_stop_audio_dma(chip);
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	spin_unlock(&chip->reg_lock);
+
+	return err;
+}
+
+/*
+ * pointer callback
+ */
+static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream
+					     *substream)
+{
+	snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	u16 count;
+
+	count = atomic_read(&chip->count);
+
+	return runtime->period_size * (count & (runtime->periods - 1));
+}
+
+/*
+ * page callback (needed for mmap)
+ */
+static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
+				     unsigned long offset)
+{
+	void *pageptr = substream->runtime->dma_area + offset;
+
+	return vmalloc_to_page(pageptr);
+}
+
+/*
+ * operators
+ */
+static struct snd_pcm_ops snd_cx25821_pcm_ops = {
+	.open = snd_cx25821_pcm_open,
+	.close = snd_cx25821_close,
+	.ioctl = snd_pcm_lib_ioctl,
+	.hw_params = snd_cx25821_hw_params,
+	.hw_free = snd_cx25821_hw_free,
+	.prepare = snd_cx25821_prepare,
+	.trigger = snd_cx25821_card_trigger,
+	.pointer = snd_cx25821_pointer,
+	.page = snd_cx25821_page,
+};
+
+/*
+ * ALSA create a PCM device:  Called when initializing the board. Sets up the name and hooks up
+ *  the callbacks
+ */
+static int snd_cx25821_pcm(snd_cx25821_card_t * chip, int device, char *name)
+{
+	struct snd_pcm *pcm;
+	int err;
+
+	err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
+	if (err < 0) {
+		printk(KERN_INFO "ERROR: FAILED snd_pcm_new() in %s\n",
+		       __func__);
+		return err;
+	}
+	pcm->private_data = chip;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, name);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops);
+
+	return 0;
+}
+
+/****************************************************************************
+			Basic Flow for Sound Devices
+ ****************************************************************************/
+
+/*
+ * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
+ * Only boards with eeprom and byte 1 at eeprom=1 have it
+ */
+
+static struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = {
+	{0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
+
+/*
+ * Not used in the function snd_cx25821_dev_free so removing
+ * from the file.
+ */
+/*
+static int snd_cx25821_free(snd_cx25821_card_t *chip)
+{
+	if (chip->irq >= 0)
+		free_irq(chip->irq, chip);
+
+	cx25821_dev_unregister(chip->dev);
+	pci_disable_device(chip->pci);
+
+	return 0;
+}
+*/
+
+/*
+ * Component Destructor
+ */
+static void snd_cx25821_dev_free(struct snd_card *card)
+{
+	snd_cx25821_card_t *chip = card->private_data;
+
+	//snd_cx25821_free(chip);
+	snd_card_free(chip->card);
+}
+
+/*
+ * Alsa Constructor - Component probe
+ */
+static int cx25821_audio_initdev(struct cx25821_dev *dev)
+{
+	struct snd_card *card;
+	snd_cx25821_card_t *chip;
+	int err;
+
+	if (devno >= SNDRV_CARDS) {
+		printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n",
+		       __func__);
+		return (-ENODEV);
+	}
+
+	if (!enable[devno]) {
+		++devno;
+		printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
+		return (-ENOENT);
+	}
+
+	err = snd_card_create(index[devno], id[devno], THIS_MODULE,
+			 sizeof(snd_cx25821_card_t), &card);
+	if (err < 0) {
+		printk(KERN_INFO
+		       "DEBUG ERROR: cannot create snd_card_new in %s\n",
+		       __func__);
+		return err;
+	}
+
+	strcpy(card->driver, "cx25821");
+
+	/* Card "creation" */
+	card->private_free = snd_cx25821_dev_free;
+	chip = (snd_cx25821_card_t *) card->private_data;
+	spin_lock_init(&chip->reg_lock);
+
+	chip->dev = dev;
+	chip->card = card;
+	chip->pci = dev->pci;
+	chip->iobase = pci_resource_start(dev->pci, 0);
+
+	chip->irq = dev->pci->irq;
+
+	err = request_irq(dev->pci->irq, cx25821_irq,
+			  IRQF_SHARED | IRQF_DISABLED, chip->dev->name, chip);
+
+	if (err < 0) {
+		printk(KERN_ERR "ERROR %s: can't get IRQ %d for ALSA\n",
+		       chip->dev->name, dev->pci->irq);
+		goto error;
+	}
+
+	if ((err = snd_cx25821_pcm(chip, 0, "cx25821 Digital")) < 0) {
+		printk(KERN_INFO
+		       "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
+		       __func__);
+		goto error;
+	}
+
+	snd_card_set_dev(card, &chip->pci->dev);
+
+	strcpy(card->shortname, "cx25821");
+	sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,
+		chip->iobase, chip->irq);
+	strcpy(card->mixername, "CX25821");
+
+	printk(KERN_INFO "%s/%i: ALSA support for cx25821 boards\n",
+	       card->driver, devno);
+
+	err = snd_card_register(card);
+	if (err < 0) {
+		printk(KERN_INFO "DEBUG ERROR: cannot register sound card %s\n",
+		       __func__);
+		goto error;
+	}
+
+	snd_cx25821_cards[devno] = card;
+
+	devno++;
+	return 0;
+
+      error:
+	snd_card_free(card);
+	return err;
+}
+
+/****************************************************************************
+				LINUX MODULE INIT
+ ****************************************************************************/
+static void cx25821_audio_fini(void)
+{
+	snd_card_free(snd_cx25821_cards[0]);
+}
+
+/*
+ * Module initializer
+ *
+ * Loops through present saa7134 cards, and assigns an ALSA device
+ * to each one
+ *
+ */
+static int cx25821_alsa_init(void)
+{
+	struct cx25821_dev *dev = NULL;
+	struct list_head *list;
+
+	list_for_each(list, &cx25821_devlist) {
+		dev = list_entry(list, struct cx25821_dev, devlist);
+		cx25821_audio_initdev(dev);
+	}
+
+	if (dev == NULL)
+		printk(KERN_INFO
+		       "cx25821 ERROR ALSA: no cx25821 cards found\n");
+
+	return 0;
+
+}
+
+late_initcall(cx25821_alsa_init);
+module_exit(cx25821_audio_fini);
+
+/* ----------------------------------------------------------- */
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
new file mode 100644
index 0000000..ddddf65
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -0,0 +1,804 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.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.
+ */
+
+#include "cx25821-video.h"
+#include "cx25821-audio-upstream.h"
+
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+
+MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
+MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
+MODULE_LICENSE("GPL");
+
+static int _intr_msk =
+    FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC |
+    FLD_AUD_SRC_OPC_ERR;
+
+int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
+					      struct sram_channel *ch,
+					      unsigned int bpl, u32 risc)
+{
+	unsigned int i, lines;
+	u32 cdt;
+
+	if (ch->cmds_start == 0) {
+		cx_write(ch->ptr1_reg, 0);
+		cx_write(ch->ptr2_reg, 0);
+		cx_write(ch->cnt2_reg, 0);
+		cx_write(ch->cnt1_reg, 0);
+		return 0;
+	}
+
+	bpl = (bpl + 7) & ~7;	/* alignment */
+	cdt = ch->cdt;
+	lines = ch->fifo_size / bpl;
+
+	if (lines > 3) {
+		lines = 3;
+	}
+
+	BUG_ON(lines < 2);
+
+	/* write CDT */
+	for (i = 0; i < lines; i++) {
+		cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
+		cx_write(cdt + 16 * i + 4, 0);
+		cx_write(cdt + 16 * i + 8, 0);
+		cx_write(cdt + 16 * i + 12, 0);
+	}
+
+	/* write CMDS */
+	cx_write(ch->cmds_start + 0, risc);
+
+	cx_write(ch->cmds_start + 4, 0);
+	cx_write(ch->cmds_start + 8, cdt);
+	cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW);
+	cx_write(ch->cmds_start + 16, ch->ctrl_start);
+
+	//IQ size
+	cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW);
+
+	for (i = 24; i < 80; i += 4)
+		cx_write(ch->cmds_start + i, 0);
+
+	/* fill registers */
+	cx_write(ch->ptr1_reg, ch->fifo_start);
+	cx_write(ch->ptr2_reg, cdt);
+	cx_write(ch->cnt2_reg, AUDIO_CDT_SIZE_QW);
+	cx_write(ch->cnt1_reg, AUDIO_CLUSTER_SIZE_QW - 1);
+
+	return 0;
+}
+
+static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
+						 __le32 * rp,
+						 dma_addr_t databuf_phys_addr,
+						 unsigned int bpl,
+						 int fifo_enable)
+{
+	unsigned int line;
+	struct sram_channel *sram_ch =
+	    &dev->sram_channels[dev->_audio_upstream_channel_select];
+	int offset = 0;
+
+	/* scan lines */
+	for (line = 0; line < LINES_PER_AUDIO_BUFFER; line++) {
+		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
+		*(rp++) = cpu_to_le32(databuf_phys_addr + offset);
+		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+
+		// Check if we need to enable the FIFO after the first 3 lines
+		// For the upstream audio channel, the risc engine will enable the FIFO.
+		if (fifo_enable && line == 2) {
+			*(rp++) = RISC_WRITECR;
+			*(rp++) = sram_ch->dma_ctl;
+			*(rp++) = sram_ch->fld_aud_fifo_en;
+			*(rp++) = 0x00000020;
+		}
+
+		offset += AUDIO_LINE_SIZE;
+	}
+
+	return rp;
+}
+
+int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
+				       struct pci_dev *pci,
+				       unsigned int bpl, unsigned int lines)
+{
+	__le32 *rp;
+	int fifo_enable = 0;
+	int frame = 0, i = 0;
+	int frame_size = AUDIO_DATA_BUF_SZ;
+	int databuf_offset = 0;
+	int risc_flag = RISC_CNT_INC;
+	dma_addr_t risc_phys_jump_addr;
+
+	/* Virtual address of Risc buffer program */
+	rp = dev->_risc_virt_addr;
+
+	/* sync instruction */
+	*(rp++) = cpu_to_le32(RISC_RESYNC | AUDIO_SYNC_LINE);
+
+	for (frame = 0; frame < NUM_AUDIO_FRAMES; frame++) {
+		databuf_offset = frame_size * frame;
+
+		if (frame == 0) {
+			fifo_enable = 1;
+			risc_flag = RISC_CNT_RESET;
+		} else {
+			fifo_enable = 0;
+			risc_flag = RISC_CNT_INC;
+		}
+
+		//Calculate physical jump address
+		if ((frame + 1) == NUM_AUDIO_FRAMES) {
+			risc_phys_jump_addr =
+			    dev->_risc_phys_start_addr +
+			    RISC_SYNC_INSTRUCTION_SIZE;
+		} else {
+			risc_phys_jump_addr =
+			    dev->_risc_phys_start_addr +
+			    RISC_SYNC_INSTRUCTION_SIZE +
+			    AUDIO_RISC_DMA_BUF_SIZE * (frame + 1);
+		}
+
+		rp = cx25821_risc_field_upstream_audio(dev, rp,
+						       dev->
+						       _audiodata_buf_phys_addr
+						       + databuf_offset, bpl,
+						       fifo_enable);
+
+		if (USE_RISC_NOOP_AUDIO) {
+			for (i = 0; i < NUM_NO_OPS; i++) {
+				*(rp++) = cpu_to_le32(RISC_NOOP);
+			}
+		}
+
+		// Loop to (Nth)FrameRISC or to Start of Risc program & generate IRQ
+		*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
+		*(rp++) = cpu_to_le32(risc_phys_jump_addr);
+		*(rp++) = cpu_to_le32(0);
+
+		//Recalculate virtual address based on frame index
+		rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 +
+		    (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
+	}
+
+	return 0;
+}
+
+void cx25821_free_memory_audio(struct cx25821_dev *dev)
+{
+	if (dev->_risc_virt_addr) {
+		pci_free_consistent(dev->pci, dev->_audiorisc_size,
+				    dev->_risc_virt_addr, dev->_risc_phys_addr);
+		dev->_risc_virt_addr = NULL;
+	}
+
+	if (dev->_audiodata_buf_virt_addr) {
+		pci_free_consistent(dev->pci, dev->_audiodata_buf_size,
+				    dev->_audiodata_buf_virt_addr,
+				    dev->_audiodata_buf_phys_addr);
+		dev->_audiodata_buf_virt_addr = NULL;
+	}
+}
+
+void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
+{
+	struct sram_channel *sram_ch =
+	    &dev->sram_channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B];
+	u32 tmp = 0;
+
+	if (!dev->_audio_is_running) {
+		printk
+		    ("cx25821: No audio file is currently running so return!\n");
+		return;
+	}
+	//Disable RISC interrupts
+	cx_write(sram_ch->int_msk, 0);
+
+	//Turn OFF risc and fifo enable in AUD_DMA_CNTRL
+	tmp = cx_read(sram_ch->dma_ctl);
+	cx_write(sram_ch->dma_ctl,
+		 tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en));
+
+	//Clear data buffer memory
+	if (dev->_audiodata_buf_virt_addr)
+		memset(dev->_audiodata_buf_virt_addr, 0,
+		       dev->_audiodata_buf_size);
+
+	dev->_audio_is_running = 0;
+	dev->_is_first_audio_frame = 0;
+	dev->_audioframe_count = 0;
+	dev->_audiofile_status = END_OF_FILE;
+
+	if (dev->_irq_audio_queues) {
+		kfree(dev->_irq_audio_queues);
+		dev->_irq_audio_queues = NULL;
+	}
+
+	if (dev->_audiofilename != NULL)
+		kfree(dev->_audiofilename);
+}
+
+void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
+{
+	if (dev->_audio_is_running) {
+		cx25821_stop_upstream_audio(dev);
+	}
+
+	cx25821_free_memory_audio(dev);
+}
+
+int cx25821_get_audio_data(struct cx25821_dev *dev,
+			   struct sram_channel *sram_ch)
+{
+	struct file *myfile;
+	int frame_index_temp = dev->_audioframe_index;
+	int i = 0;
+	int line_size = AUDIO_LINE_SIZE;
+	int frame_size = AUDIO_DATA_BUF_SZ;
+	int frame_offset = frame_size * frame_index_temp;
+	ssize_t vfs_read_retval = 0;
+	char mybuf[line_size];
+	loff_t file_offset = dev->_audioframe_count * frame_size;
+	loff_t pos;
+	mm_segment_t old_fs;
+
+	if (dev->_audiofile_status == END_OF_FILE)
+		return 0;
+
+	myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
+
+	if (IS_ERR(myfile)) {
+		const int open_errno = -PTR_ERR(myfile);
+		printk("%s(): ERROR opening file(%s) with errno = %d! \n",
+		       __func__, dev->_audiofilename, open_errno);
+		return PTR_ERR(myfile);
+	} else {
+		if (!(myfile->f_op)) {
+			printk("%s: File has no file operations registered!\n",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		if (!myfile->f_op->read) {
+			printk("%s: File has no READ operations registered! \n",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		pos = myfile->f_pos;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		for (i = 0; i < dev->_audio_lines_count; i++) {
+			pos = file_offset;
+
+			vfs_read_retval =
+			    vfs_read(myfile, mybuf, line_size, &pos);
+
+			if (vfs_read_retval > 0 && vfs_read_retval == line_size
+			    && dev->_audiodata_buf_virt_addr != NULL) {
+				memcpy((void *)(dev->_audiodata_buf_virt_addr +
+						frame_offset / 4), mybuf,
+				       vfs_read_retval);
+			}
+
+			file_offset += vfs_read_retval;
+			frame_offset += vfs_read_retval;
+
+			if (vfs_read_retval < line_size) {
+				printk(KERN_INFO
+				       "Done: exit %s() since no more bytes to read from Audio file.\n",
+				       __func__);
+				break;
+			}
+		}
+
+		if (i > 0)
+			dev->_audioframe_count++;
+
+		dev->_audiofile_status =
+		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+
+		set_fs(old_fs);
+		filp_close(myfile, NULL);
+	}
+
+	return 0;
+}
+
+static void cx25821_audioups_handler(struct work_struct *work)
+{
+	struct cx25821_dev *dev =
+	    container_of(work, struct cx25821_dev, _audio_work_entry);
+
+	if (!dev) {
+		printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
+		       __func__);
+		return;
+	}
+
+	cx25821_get_audio_data(dev,
+			       &dev->sram_channels[dev->
+						   _audio_upstream_channel_select]);
+}
+
+int cx25821_openfile_audio(struct cx25821_dev *dev,
+			   struct sram_channel *sram_ch)
+{
+	struct file *myfile;
+	int i = 0, j = 0;
+	int line_size = AUDIO_LINE_SIZE;
+	ssize_t vfs_read_retval = 0;
+	char mybuf[line_size];
+	loff_t pos;
+	loff_t offset = (unsigned long)0;
+	mm_segment_t old_fs;
+
+	myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
+
+	if (IS_ERR(myfile)) {
+		const int open_errno = -PTR_ERR(myfile);
+		printk("%s(): ERROR opening file(%s) with errno = %d! \n",
+		       __func__, dev->_audiofilename, open_errno);
+		return PTR_ERR(myfile);
+	} else {
+		if (!(myfile->f_op)) {
+			printk("%s: File has no file operations registered! \n",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		if (!myfile->f_op->read) {
+			printk("%s: File has no READ operations registered! \n",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		pos = myfile->f_pos;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
+			for (i = 0; i < dev->_audio_lines_count; i++) {
+				pos = offset;
+
+				vfs_read_retval =
+				    vfs_read(myfile, mybuf, line_size, &pos);
+
+				if (vfs_read_retval > 0
+				    && vfs_read_retval == line_size
+				    && dev->_audiodata_buf_virt_addr != NULL) {
+					memcpy((void *)(dev->
+							_audiodata_buf_virt_addr
+							+ offset / 4), mybuf,
+					       vfs_read_retval);
+				}
+
+				offset += vfs_read_retval;
+
+				if (vfs_read_retval < line_size) {
+					printk(KERN_INFO
+					       "Done: exit %s() since no more bytes to read from Audio file.\n",
+					       __func__);
+					break;
+				}
+			}
+
+			if (i > 0) {
+				dev->_audioframe_count++;
+			}
+
+			if (vfs_read_retval < line_size) {
+				break;
+			}
+		}
+
+		dev->_audiofile_status =
+		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+
+		set_fs(old_fs);
+		myfile->f_pos = 0;
+		filp_close(myfile, NULL);
+	}
+
+	return 0;
+}
+
+static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
+						 struct sram_channel *sram_ch,
+						 int bpl)
+{
+	int ret = 0;
+	dma_addr_t dma_addr;
+	dma_addr_t data_dma_addr;
+
+	cx25821_free_memory_audio(dev);
+
+	dev->_risc_virt_addr =
+	    pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size,
+				 &dma_addr);
+	dev->_risc_virt_start_addr = dev->_risc_virt_addr;
+	dev->_risc_phys_start_addr = dma_addr;
+	dev->_risc_phys_addr = dma_addr;
+	dev->_audiorisc_size = dev->audio_upstream_riscbuf_size;
+
+	if (!dev->_risc_virt_addr) {
+		printk
+		    ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
+		return -ENOMEM;
+	}
+	//Clear out memory at address
+	memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size);
+
+	//For Audio Data buffer allocation
+	dev->_audiodata_buf_virt_addr =
+	    pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size,
+				 &data_dma_addr);
+	dev->_audiodata_buf_phys_addr = data_dma_addr;
+	dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
+
+	if (!dev->_audiodata_buf_virt_addr) {
+		printk
+		    ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning. \n");
+		return -ENOMEM;
+	}
+	//Clear out memory at address
+	memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size);
+
+	ret = cx25821_openfile_audio(dev, sram_ch);
+	if (ret < 0)
+		return ret;
+
+	//Creating RISC programs
+	ret =
+	    cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
+					       dev->_audio_lines_count);
+	if (ret < 0) {
+		printk(KERN_DEBUG
+		       "cx25821 ERROR creating audio upstream RISC programs! \n");
+		goto error;
+	}
+
+	return 0;
+
+      error:
+	return ret;
+}
+
+int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
+			       u32 status)
+{
+	int i = 0;
+	u32 int_msk_tmp;
+	struct sram_channel *channel = &dev->sram_channels[chan_num];
+	dma_addr_t risc_phys_jump_addr;
+	__le32 *rp;
+
+	if (status & FLD_AUD_SRC_RISCI1) {
+		//Get interrupt_index of the program that interrupted
+		u32 prog_cnt = cx_read(channel->gpcnt);
+
+		//Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
+		cx_write(channel->int_msk, 0);
+		cx_write(channel->int_stat, cx_read(channel->int_stat));
+
+		spin_lock(&dev->slock);
+
+		while (prog_cnt != dev->_last_index_irq) {
+			//Update _last_index_irq
+			if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1)) {
+				dev->_last_index_irq++;
+			} else {
+				dev->_last_index_irq = 0;
+			}
+
+			dev->_audioframe_index = dev->_last_index_irq;
+
+			queue_work(dev->_irq_audio_queues,
+				   &dev->_audio_work_entry);
+		}
+
+		if (dev->_is_first_audio_frame) {
+			dev->_is_first_audio_frame = 0;
+
+			if (dev->_risc_virt_start_addr != NULL) {
+				risc_phys_jump_addr =
+				    dev->_risc_phys_start_addr +
+				    RISC_SYNC_INSTRUCTION_SIZE +
+				    AUDIO_RISC_DMA_BUF_SIZE;
+
+				rp = cx25821_risc_field_upstream_audio(dev,
+								       dev->
+								       _risc_virt_start_addr
+								       + 1,
+								       dev->
+								       _audiodata_buf_phys_addr,
+								       AUDIO_LINE_SIZE,
+								       FIFO_DISABLE);
+
+				if (USE_RISC_NOOP_AUDIO) {
+					for (i = 0; i < NUM_NO_OPS; i++) {
+						*(rp++) =
+						    cpu_to_le32(RISC_NOOP);
+					}
+				}
+				// Jump to 2nd Audio Frame
+				*(rp++) =
+				    cpu_to_le32(RISC_JUMP | RISC_IRQ1 |
+						RISC_CNT_RESET);
+				*(rp++) = cpu_to_le32(risc_phys_jump_addr);
+				*(rp++) = cpu_to_le32(0);
+			}
+		}
+
+		spin_unlock(&dev->slock);
+	} else {
+		if (status & FLD_AUD_SRC_OF)
+			printk("%s: Audio Received Overflow Error Interrupt!\n",
+			       __func__);
+
+		if (status & FLD_AUD_SRC_SYNC)
+			printk("%s: Audio Received Sync Error Interrupt!\n",
+			       __func__);
+
+		if (status & FLD_AUD_SRC_OPC_ERR)
+			printk("%s: Audio Received OpCode Error Interrupt!\n",
+			       __func__);
+
+		// Read and write back the interrupt status register to clear our bits
+		cx_write(channel->int_stat, cx_read(channel->int_stat));
+	}
+
+	if (dev->_audiofile_status == END_OF_FILE) {
+		printk("cx25821: EOF Channel Audio Framecount = %d\n",
+		       dev->_audioframe_count);
+		return -1;
+	}
+	//ElSE, set the interrupt mask register, re-enable irq.
+	int_msk_tmp = cx_read(channel->int_msk);
+	cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
+
+	return 0;
+}
+
+static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
+{
+	struct cx25821_dev *dev = dev_id;
+	u32 msk_stat, audio_status;
+	int handled = 0;
+	struct sram_channel *sram_ch;
+
+	if (!dev)
+		return -1;
+
+	sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select];
+
+	msk_stat = cx_read(sram_ch->int_mstat);
+	audio_status = cx_read(sram_ch->int_stat);
+
+	// Only deal with our interrupt
+	if (audio_status) {
+		handled =
+		    cx25821_audio_upstream_irq(dev,
+					       dev->
+					       _audio_upstream_channel_select,
+					       audio_status);
+	}
+
+	if (handled < 0) {
+		cx25821_stop_upstream_audio(dev);
+	} else {
+		handled += handled;
+	}
+
+	return IRQ_RETVAL(handled);
+}
+
+static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
+				     struct sram_channel *sram_ch)
+{
+	int count = 0;
+	u32 tmp;
+
+	do {
+		//Wait 10 microsecond before checking to see if the FIFO is turned ON.
+		udelay(10);
+
+		tmp = cx_read(sram_ch->dma_ctl);
+
+		if (count++ > 1000)	//10 millisecond timeout
+		{
+			printk
+			    ("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
+			     __func__);
+			return;
+		}
+
+	} while (!(tmp & sram_ch->fld_aud_fifo_en));
+
+}
+
+int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
+				     struct sram_channel *sram_ch)
+{
+	u32 tmp = 0;
+	int err = 0;
+
+	// Set the physical start address of the RISC program in the initial program counter(IPC) member of the CMDS.
+	cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr);
+	cx_write(sram_ch->cmds_start + 4, 0);	/* Risc IPC High 64 bits 63-32 */
+
+	/* reset counter */
+	cx_write(sram_ch->gpcnt_ctl, 3);
+
+	//Set the line length       (It looks like we do not need to set the line length)
+	cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);
+
+	//Set the input mode to 16-bit
+	tmp = cx_read(sram_ch->aud_cfg);
+	tmp |=
+	    FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
+	    FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
+	cx_write(sram_ch->aud_cfg, tmp);
+
+	// Read and write back the interrupt status register to clear it
+	tmp = cx_read(sram_ch->int_stat);
+	cx_write(sram_ch->int_stat, tmp);
+
+	// Clear our bits from the interrupt status register.
+	cx_write(sram_ch->int_stat, _intr_msk);
+
+	//Set the interrupt mask register, enable irq.
+	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
+	tmp = cx_read(sram_ch->int_msk);
+	cx_write(sram_ch->int_msk, tmp |= _intr_msk);
+
+	err =
+	    request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
+			IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+	if (err < 0) {
+		printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
+		       dev->pci->irq);
+		goto fail_irq;
+	}
+
+	// Start the DMA  engine
+	tmp = cx_read(sram_ch->dma_ctl);
+	cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en);
+
+	dev->_audio_is_running = 1;
+	dev->_is_first_audio_frame = 1;
+
+	// The fifo_en bit turns on by the first Risc program
+	cx25821_wait_fifo_enable(dev, sram_ch);
+
+	return 0;
+
+      fail_irq:
+	cx25821_dev_unregister(dev);
+	return err;
+}
+
+int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
+{
+	struct sram_channel *sram_ch;
+	int retval = 0;
+	int err = 0;
+	int str_length = 0;
+
+	if (dev->_audio_is_running) {
+		printk("Audio Channel is still running so return!\n");
+		return 0;
+	}
+
+	dev->_audio_upstream_channel_select = channel_select;
+	sram_ch = &dev->sram_channels[channel_select];
+
+	//Work queue
+	INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
+	dev->_irq_audio_queues =
+	    create_singlethread_workqueue("cx25821_audioworkqueue");
+
+	if (!dev->_irq_audio_queues) {
+		printk
+		    ("cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
+		return -ENOMEM;
+	}
+
+	dev->_last_index_irq = 0;
+	dev->_audio_is_running = 0;
+	dev->_audioframe_count = 0;
+	dev->_audiofile_status = RESET_STATUS;
+	dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
+	_line_size = AUDIO_LINE_SIZE;
+
+	if (dev->input_audiofilename) {
+		str_length = strlen(dev->input_audiofilename);
+		dev->_audiofilename =
+		    (char *)kmalloc(str_length + 1, GFP_KERNEL);
+
+		if (!dev->_audiofilename)
+			goto error;
+
+		memcpy(dev->_audiofilename, dev->input_audiofilename,
+		       str_length + 1);
+
+		//Default if filename is empty string
+		if (strcmp(dev->input_audiofilename, "") == 0) {
+			dev->_audiofilename = "/root/audioGOOD.wav";
+		}
+	} else {
+		str_length = strlen(_defaultAudioName);
+		dev->_audiofilename =
+		    (char *)kmalloc(str_length + 1, GFP_KERNEL);
+
+		if (!dev->_audiofilename)
+			goto error;
+
+		memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1);
+	}
+
+	retval =
+	    cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, _line_size,
+						      0);
+
+	dev->audio_upstream_riscbuf_size =
+	    AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
+	    RISC_SYNC_INSTRUCTION_SIZE;
+	dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
+
+	//Allocating buffers and prepare RISC program
+	retval =
+	    cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
+	if (retval < 0) {
+		printk(KERN_ERR
+		       "%s: Failed to set up Audio upstream buffers!\n",
+		       dev->name);
+		goto error;
+	}
+	//Start RISC engine
+	cx25821_start_audio_dma_upstream(dev, sram_ch);
+
+	return 0;
+
+      error:
+	cx25821_dev_unregister(dev);
+
+	return err;
+}
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/staging/cx25821/cx25821-audio-upstream.h
new file mode 100644
index 0000000..ca987ad
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.h
@@ -0,0 +1,57 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.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.
+ */
+
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#define NUM_AUDIO_PROGS       8
+#define NUM_AUDIO_FRAMES      8
+#define END_OF_FILE           0
+#define IN_PROGRESS           1
+#define RESET_STATUS          -1
+#define FIFO_DISABLE          0
+#define FIFO_ENABLE           1
+#define NUM_NO_OPS            4
+
+#define RISC_READ_INSTRUCTION_SIZE      12
+#define RISC_JUMP_INSTRUCTION_SIZE      12
+#define RISC_WRITECR_INSTRUCTION_SIZE   16
+#define RISC_SYNC_INSTRUCTION_SIZE      4
+#define DWORD_SIZE                      4
+#define AUDIO_SYNC_LINE                 4
+
+#define LINES_PER_AUDIO_BUFFER      15
+#define AUDIO_LINE_SIZE             128
+#define AUDIO_DATA_BUF_SZ           (AUDIO_LINE_SIZE * LINES_PER_AUDIO_BUFFER)
+
+#define USE_RISC_NOOP_AUDIO   1
+
+#ifdef USE_RISC_NOOP_AUDIO
+#define AUDIO_RISC_DMA_BUF_SIZE    ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
+#endif
+
+#ifndef USE_RISC_NOOP_AUDIO
+#define AUDIO_RISC_DMA_BUF_SIZE    ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
+#endif
+
+static int _line_size;
+char *_defaultAudioName = "/root/audioGOOD.wav";
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h
new file mode 100644
index 0000000..503f42f
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio.h
@@ -0,0 +1,57 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#ifndef __CX25821_AUDIO_H__
+#define __CX25821_AUDIO_H__
+
+#define USE_RISC_NOOP               1
+#define LINES_PER_BUFFER            15
+#define AUDIO_LINE_SIZE             128
+
+//Number of buffer programs to use at once.
+#define NUMBER_OF_PROGRAMS  8
+
+//Max size of the RISC program for a buffer. - worst case is 2 writes per line
+// Space is also added for the 4 no-op instructions added on the end.
+
+#ifndef USE_RISC_NOOP
+#define MAX_BUFFER_PROGRAM_SIZE     \
+    (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4)
+#endif
+
+// MAE 12 July 2005 Try to use NOOP RISC instruction instead
+#ifdef USE_RISC_NOOP
+#define MAX_BUFFER_PROGRAM_SIZE     \
+    (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4)
+#endif
+
+//Sizes of various instructions in bytes.  Used when adding instructions.
+#define RISC_WRITE_INSTRUCTION_SIZE 12
+#define RISC_JUMP_INSTRUCTION_SIZE  12
+#define RISC_SKIP_INSTRUCTION_SIZE  4
+#define RISC_SYNC_INSTRUCTION_SIZE  4
+#define RISC_WRITECR_INSTRUCTION_SIZE  16
+#define RISC_NOOP_INSTRUCTION_SIZE 4
+
+#define MAX_AUDIO_DMA_BUFFER_SIZE (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
+
+#endif
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
new file mode 100644
index 0000000..f78b891
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -0,0 +1,434 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH11];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH11]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH11]
+		    && h->video_dev[SRAM_CH11]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = 10;
+	fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO11))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO11)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	//cx_write(channel11->dma_ctl, 0);
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO11)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO11);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO11)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO11);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->width = f->fmt.pix.width;
+	fh->height = f->fmt.pix.height;
+	fh->vidq.field = f->fmt.pix.field;
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+	return 0;
+}
+
+static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
+				   unsigned long arg)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+	int command = 0;
+	struct upstream_user_struct *data_from_user;
+
+	data_from_user = (struct upstream_user_struct *)arg;
+
+	if (!data_from_user) {
+		printk
+		    ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
+		     __func__);
+		return 0;
+	}
+
+	command = data_from_user->command;
+
+	if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) {
+		return 0;
+	}
+
+	dev->input_filename = data_from_user->input_filename;
+	dev->input_audiofilename = data_from_user->input_filename;
+	dev->vid_stdname = data_from_user->vid_stdname;
+	dev->pixel_format = data_from_user->pixel_format;
+	dev->channel_select = data_from_user->channel_select;
+	dev->command = data_from_user->command;
+
+	switch (command) {
+	case UPSTREAM_START_AUDIO:
+		cx25821_start_upstream_audio(dev, data_from_user);
+		break;
+
+	case UPSTREAM_STOP_AUDIO:
+		cx25821_stop_upstream_audio(dev);
+		break;
+	}
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct cx25821_fh *fh = priv;
+	return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+	return 0;
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl_upstream11,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template11 = {
+	.name = "cx25821-audioupstream",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-biffuncs.h b/drivers/staging/cx25821/cx25821-biffuncs.h
new file mode 100644
index 0000000..9326a7c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-biffuncs.h
@@ -0,0 +1,45 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#ifndef _BITFUNCS_H
+#define _BITFUNCS_H
+
+#define SetBit(Bit)  (1 << Bit)
+
+inline u8 getBit(u32 sample, u8 index)
+{
+	return (u8) ((sample >> index) & 1);
+}
+
+inline u32 clearBitAtPos(u32 value, u8 bit)
+{
+	return value & ~(1 << bit);
+}
+
+inline u32 setBitAtPos(u32 sample, u8 bit)
+{
+	sample |= (1 << bit);
+	return sample;
+
+}
+
+#endif
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/staging/cx25821/cx25821-cards.c
new file mode 100644
index 0000000..4d0b9ea
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -0,0 +1,70 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *	Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <media/cx25840.h>
+
+#include "cx25821.h"
+#include "tuner-xc2028.h"
+
+// board config info
+
+struct cx25821_board cx25821_boards[] = {
+	[UNKNOWN_BOARD] = {
+			   .name = "UNKNOWN/GENERIC",
+			   // Ensure safe default for unknown boards
+			   .clk_freq = 0,
+			   },
+
+	[CX25821_BOARD] = {
+			   .name = "CX25821",
+			   .portb = CX25821_RAW,
+			   .portc = CX25821_264,
+			   .input[0].type = CX25821_VMUX_COMPOSITE,
+			   },
+
+};
+
+const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards);
+
+struct cx25821_subid cx25821_subids[] = {
+	{
+	 .subvendor = 0x14f1,
+	 .subdevice = 0x0920,
+	 .card = CX25821_BOARD,
+	 },
+};
+
+void cx25821_card_setup(struct cx25821_dev *dev)
+{
+	static u8 eeprom[256];
+
+	if (dev->i2c_bus[0].i2c_rc == 0) {
+		dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
+		tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
+			      sizeof(eeprom));
+	}
+}
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
new file mode 100644
index 0000000..8aceae5
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -0,0 +1,1551 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include <linux/i2c.h>
+#include "cx25821.h"
+#include "cx25821-sram.h"
+#include "cx25821-video.h"
+
+MODULE_DESCRIPTION("Driver for Athena cards");
+MODULE_AUTHOR("Shu Lin - Hiep Huynh");
+MODULE_LICENSE("GPL");
+
+struct list_head cx25821_devlist;
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
+
+static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
+module_param_array(card, int, NULL, 0444);
+MODULE_PARM_DESC(card, "card type");
+
+static unsigned int cx25821_devcount = 0;
+
+static DEFINE_MUTEX(devlist);
+LIST_HEAD(cx25821_devlist);
+
+struct sram_channel cx25821_sram_channels[] = {
+	[SRAM_CH00] = {
+		       .i = SRAM_CH00,
+		       .name = "VID A",
+		       .cmds_start = VID_A_DOWN_CMDS,
+		       .ctrl_start = VID_A_IQ,
+		       .cdt = VID_A_CDT,
+		       .fifo_start = VID_A_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA1_PTR1,
+		       .ptr2_reg = DMA1_PTR2,
+		       .cnt1_reg = DMA1_CNT1,
+		       .cnt2_reg = DMA1_CNT2,
+		       .int_msk = VID_A_INT_MSK,
+		       .int_stat = VID_A_INT_STAT,
+		       .int_mstat = VID_A_INT_MSTAT,
+		       .dma_ctl = VID_DST_A_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_A_GPCNT_CTL,
+		       .gpcnt = VID_DST_A_GPCNT,
+		       .vip_ctl = VID_DST_A_VIP_CTL,
+		       .pix_frmt = VID_DST_A_PIX_FRMT,
+		       },
+
+	[SRAM_CH01] = {
+		       .i = SRAM_CH01,
+		       .name = "VID B",
+		       .cmds_start = VID_B_DOWN_CMDS,
+		       .ctrl_start = VID_B_IQ,
+		       .cdt = VID_B_CDT,
+		       .fifo_start = VID_B_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA2_PTR1,
+		       .ptr2_reg = DMA2_PTR2,
+		       .cnt1_reg = DMA2_CNT1,
+		       .cnt2_reg = DMA2_CNT2,
+		       .int_msk = VID_B_INT_MSK,
+		       .int_stat = VID_B_INT_STAT,
+		       .int_mstat = VID_B_INT_MSTAT,
+		       .dma_ctl = VID_DST_B_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_B_GPCNT_CTL,
+		       .gpcnt = VID_DST_B_GPCNT,
+		       .vip_ctl = VID_DST_B_VIP_CTL,
+		       .pix_frmt = VID_DST_B_PIX_FRMT,
+		       },
+
+	[SRAM_CH02] = {
+		       .i = SRAM_CH02,
+		       .name = "VID C",
+		       .cmds_start = VID_C_DOWN_CMDS,
+		       .ctrl_start = VID_C_IQ,
+		       .cdt = VID_C_CDT,
+		       .fifo_start = VID_C_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA3_PTR1,
+		       .ptr2_reg = DMA3_PTR2,
+		       .cnt1_reg = DMA3_CNT1,
+		       .cnt2_reg = DMA3_CNT2,
+		       .int_msk = VID_C_INT_MSK,
+		       .int_stat = VID_C_INT_STAT,
+		       .int_mstat = VID_C_INT_MSTAT,
+		       .dma_ctl = VID_DST_C_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_C_GPCNT_CTL,
+		       .gpcnt = VID_DST_C_GPCNT,
+		       .vip_ctl = VID_DST_C_VIP_CTL,
+		       .pix_frmt = VID_DST_C_PIX_FRMT,
+		       },
+
+	[SRAM_CH03] = {
+		       .i = SRAM_CH03,
+		       .name = "VID D",
+		       .cmds_start = VID_D_DOWN_CMDS,
+		       .ctrl_start = VID_D_IQ,
+		       .cdt = VID_D_CDT,
+		       .fifo_start = VID_D_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA4_PTR1,
+		       .ptr2_reg = DMA4_PTR2,
+		       .cnt1_reg = DMA4_CNT1,
+		       .cnt2_reg = DMA4_CNT2,
+		       .int_msk = VID_D_INT_MSK,
+		       .int_stat = VID_D_INT_STAT,
+		       .int_mstat = VID_D_INT_MSTAT,
+		       .dma_ctl = VID_DST_D_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_D_GPCNT_CTL,
+		       .gpcnt = VID_DST_D_GPCNT,
+		       .vip_ctl = VID_DST_D_VIP_CTL,
+		       .pix_frmt = VID_DST_D_PIX_FRMT,
+		       },
+
+	[SRAM_CH04] = {
+		       .i = SRAM_CH04,
+		       .name = "VID E",
+		       .cmds_start = VID_E_DOWN_CMDS,
+		       .ctrl_start = VID_E_IQ,
+		       .cdt = VID_E_CDT,
+		       .fifo_start = VID_E_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA5_PTR1,
+		       .ptr2_reg = DMA5_PTR2,
+		       .cnt1_reg = DMA5_CNT1,
+		       .cnt2_reg = DMA5_CNT2,
+		       .int_msk = VID_E_INT_MSK,
+		       .int_stat = VID_E_INT_STAT,
+		       .int_mstat = VID_E_INT_MSTAT,
+		       .dma_ctl = VID_DST_E_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_E_GPCNT_CTL,
+		       .gpcnt = VID_DST_E_GPCNT,
+		       .vip_ctl = VID_DST_E_VIP_CTL,
+		       .pix_frmt = VID_DST_E_PIX_FRMT,
+		       },
+
+	[SRAM_CH05] = {
+		       .i = SRAM_CH05,
+		       .name = "VID F",
+		       .cmds_start = VID_F_DOWN_CMDS,
+		       .ctrl_start = VID_F_IQ,
+		       .cdt = VID_F_CDT,
+		       .fifo_start = VID_F_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA6_PTR1,
+		       .ptr2_reg = DMA6_PTR2,
+		       .cnt1_reg = DMA6_CNT1,
+		       .cnt2_reg = DMA6_CNT2,
+		       .int_msk = VID_F_INT_MSK,
+		       .int_stat = VID_F_INT_STAT,
+		       .int_mstat = VID_F_INT_MSTAT,
+		       .dma_ctl = VID_DST_F_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_F_GPCNT_CTL,
+		       .gpcnt = VID_DST_F_GPCNT,
+		       .vip_ctl = VID_DST_F_VIP_CTL,
+		       .pix_frmt = VID_DST_F_PIX_FRMT,
+		       },
+
+	[SRAM_CH06] = {
+		       .i = SRAM_CH06,
+		       .name = "VID G",
+		       .cmds_start = VID_G_DOWN_CMDS,
+		       .ctrl_start = VID_G_IQ,
+		       .cdt = VID_G_CDT,
+		       .fifo_start = VID_G_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA7_PTR1,
+		       .ptr2_reg = DMA7_PTR2,
+		       .cnt1_reg = DMA7_CNT1,
+		       .cnt2_reg = DMA7_CNT2,
+		       .int_msk = VID_G_INT_MSK,
+		       .int_stat = VID_G_INT_STAT,
+		       .int_mstat = VID_G_INT_MSTAT,
+		       .dma_ctl = VID_DST_G_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_G_GPCNT_CTL,
+		       .gpcnt = VID_DST_G_GPCNT,
+		       .vip_ctl = VID_DST_G_VIP_CTL,
+		       .pix_frmt = VID_DST_G_PIX_FRMT,
+		       },
+
+	[SRAM_CH07] = {
+		       .i = SRAM_CH07,
+		       .name = "VID H",
+		       .cmds_start = VID_H_DOWN_CMDS,
+		       .ctrl_start = VID_H_IQ,
+		       .cdt = VID_H_CDT,
+		       .fifo_start = VID_H_DOWN_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA8_PTR1,
+		       .ptr2_reg = DMA8_PTR2,
+		       .cnt1_reg = DMA8_CNT1,
+		       .cnt2_reg = DMA8_CNT2,
+		       .int_msk = VID_H_INT_MSK,
+		       .int_stat = VID_H_INT_STAT,
+		       .int_mstat = VID_H_INT_MSTAT,
+		       .dma_ctl = VID_DST_H_DMA_CTL,
+		       .gpcnt_ctl = VID_DST_H_GPCNT_CTL,
+		       .gpcnt = VID_DST_H_GPCNT,
+		       .vip_ctl = VID_DST_H_VIP_CTL,
+		       .pix_frmt = VID_DST_H_PIX_FRMT,
+		       },
+
+	[SRAM_CH08] = {
+		       .name = "audio from",
+		       .cmds_start = AUD_A_DOWN_CMDS,
+		       .ctrl_start = AUD_A_IQ,
+		       .cdt = AUD_A_CDT,
+		       .fifo_start = AUD_A_DOWN_CLUSTER_1,
+		       .fifo_size = AUDIO_CLUSTER_SIZE * 3,
+		       .ptr1_reg = DMA17_PTR1,
+		       .ptr2_reg = DMA17_PTR2,
+		       .cnt1_reg = DMA17_CNT1,
+		       .cnt2_reg = DMA17_CNT2,
+		       },
+
+	[SRAM_CH09] = {
+		       .i = SRAM_CH09,
+		       .name = "VID Upstream I",
+		       .cmds_start = VID_I_UP_CMDS,
+		       .ctrl_start = VID_I_IQ,
+		       .cdt = VID_I_CDT,
+		       .fifo_start = VID_I_UP_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA15_PTR1,
+		       .ptr2_reg = DMA15_PTR2,
+		       .cnt1_reg = DMA15_CNT1,
+		       .cnt2_reg = DMA15_CNT2,
+		       .int_msk = VID_I_INT_MSK,
+		       .int_stat = VID_I_INT_STAT,
+		       .int_mstat = VID_I_INT_MSTAT,
+		       .dma_ctl = VID_SRC_I_DMA_CTL,
+		       .gpcnt_ctl = VID_SRC_I_GPCNT_CTL,
+		       .gpcnt = VID_SRC_I_GPCNT,
+
+		       .vid_fmt_ctl = VID_SRC_I_FMT_CTL,
+		       .vid_active_ctl1 = VID_SRC_I_ACTIVE_CTL1,
+		       .vid_active_ctl2 = VID_SRC_I_ACTIVE_CTL2,
+		       .vid_cdt_size = VID_SRC_I_CDT_SZ,
+		       .irq_bit = 8,
+		       },
+
+	[SRAM_CH10] = {
+		       .i = SRAM_CH10,
+		       .name = "VID Upstream J",
+		       .cmds_start = VID_J_UP_CMDS,
+		       .ctrl_start = VID_J_IQ,
+		       .cdt = VID_J_CDT,
+		       .fifo_start = VID_J_UP_CLUSTER_1,
+		       .fifo_size = (VID_CLUSTER_SIZE << 2),
+		       .ptr1_reg = DMA16_PTR1,
+		       .ptr2_reg = DMA16_PTR2,
+		       .cnt1_reg = DMA16_CNT1,
+		       .cnt2_reg = DMA16_CNT2,
+		       .int_msk = VID_J_INT_MSK,
+		       .int_stat = VID_J_INT_STAT,
+		       .int_mstat = VID_J_INT_MSTAT,
+		       .dma_ctl = VID_SRC_J_DMA_CTL,
+		       .gpcnt_ctl = VID_SRC_J_GPCNT_CTL,
+		       .gpcnt = VID_SRC_J_GPCNT,
+
+		       .vid_fmt_ctl = VID_SRC_J_FMT_CTL,
+		       .vid_active_ctl1 = VID_SRC_J_ACTIVE_CTL1,
+		       .vid_active_ctl2 = VID_SRC_J_ACTIVE_CTL2,
+		       .vid_cdt_size = VID_SRC_J_CDT_SZ,
+		       .irq_bit = 9,
+		       },
+
+	[SRAM_CH11] = {
+		       .i = SRAM_CH11,
+		       .name = "Audio Upstream Channel B",
+		       .cmds_start = AUD_B_UP_CMDS,
+		       .ctrl_start = AUD_B_IQ,
+		       .cdt = AUD_B_CDT,
+		       .fifo_start = AUD_B_UP_CLUSTER_1,
+		       .fifo_size = (AUDIO_CLUSTER_SIZE * 3),
+		       .ptr1_reg = DMA22_PTR1,
+		       .ptr2_reg = DMA22_PTR2,
+		       .cnt1_reg = DMA22_CNT1,
+		       .cnt2_reg = DMA22_CNT2,
+		       .int_msk = AUD_B_INT_MSK,
+		       .int_stat = AUD_B_INT_STAT,
+		       .int_mstat = AUD_B_INT_MSTAT,
+		       .dma_ctl = AUD_INT_DMA_CTL,
+		       .gpcnt_ctl = AUD_B_GPCNT_CTL,
+		       .gpcnt = AUD_B_GPCNT,
+		       .aud_length = AUD_B_LNGTH,
+		       .aud_cfg = AUD_B_CFG,
+		       .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN,
+		       .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN,
+		       .irq_bit = 11,
+		       },
+};
+
+struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00];
+struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01];
+struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02];
+struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03];
+struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04];
+struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05];
+struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06];
+struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07];
+struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09];
+struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10];
+struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11];
+
+struct cx25821_dmaqueue mpegq;
+
+static int cx25821_risc_decode(u32 risc)
+{
+	static char *instr[16] = {
+		[RISC_SYNC >> 28] = "sync",
+		[RISC_WRITE >> 28] = "write",
+		[RISC_WRITEC >> 28] = "writec",
+		[RISC_READ >> 28] = "read",
+		[RISC_READC >> 28] = "readc",
+		[RISC_JUMP >> 28] = "jump",
+		[RISC_SKIP >> 28] = "skip",
+		[RISC_WRITERM >> 28] = "writerm",
+		[RISC_WRITECM >> 28] = "writecm",
+		[RISC_WRITECR >> 28] = "writecr",
+	};
+	static int incr[16] = {
+		[RISC_WRITE >> 28] = 3,
+		[RISC_JUMP >> 28] = 3,
+		[RISC_SKIP >> 28] = 1,
+		[RISC_SYNC >> 28] = 1,
+		[RISC_WRITERM >> 28] = 3,
+		[RISC_WRITECM >> 28] = 3,
+		[RISC_WRITECR >> 28] = 4,
+	};
+	static char *bits[] = {
+		"12", "13", "14", "resync",
+		"cnt0", "cnt1", "18", "19",
+		"20", "21", "22", "23",
+		"irq1", "irq2", "eol", "sol",
+	};
+	int i;
+
+	printk("0x%08x [ %s", risc,
+	       instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
+	for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
+		if (risc & (1 << (i + 12)))
+			printk(" %s", bits[i]);
+	}
+	printk(" count=%d ]\n", risc & 0xfff);
+	return incr[risc >> 28] ? incr[risc >> 28] : 1;
+}
+
+static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
+{
+	struct cx25821_i2c *bus = i2c_adap->algo_data;
+	struct cx25821_dev *dev = bus->dev;
+	return cx_read(bus->reg_stat) & 0x01;
+}
+
+void cx_i2c_read_print(struct cx25821_dev *dev, u32 reg, const char *reg_string)
+{
+	int tmp = 0;
+	u32 value = 0;
+
+	value = cx25821_i2c_read(&dev->i2c_bus[0], reg, &tmp);
+}
+
+static void cx25821_registers_init(struct cx25821_dev *dev)
+{
+	u32 tmp;
+
+	// enable RUN_RISC in Pecos
+	cx_write(DEV_CNTRL2, 0x20);
+
+	// Set the master PCI interrupt masks to enable video, audio, MBIF, and GPIO interrupts
+	// I2C interrupt masking is handled by the I2C objects themselves.
+	cx_write(PCI_INT_MSK, 0x2001FFFF);
+
+	tmp = cx_read(RDR_TLCTL0);
+	tmp &= ~FLD_CFG_RCB_CK_EN;	// Clear the RCB_CK_EN bit
+	cx_write(RDR_TLCTL0, tmp);
+
+	// PLL-A setting for the Audio Master Clock
+	cx_write(PLL_A_INT_FRAC, 0x9807A58B);
+
+	// PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1
+	cx_write(PLL_A_POST_STAT_BIST, 0x8000019C);
+
+	// clear reset bit [31]
+	tmp = cx_read(PLL_A_INT_FRAC);
+	cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
+
+	// PLL-B setting for Mobilygen Host Bus Interface
+	cx_write(PLL_B_INT_FRAC, 0x9883A86F);
+
+	// PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0
+	cx_write(PLL_B_POST_STAT_BIST, 0x8000018D);
+
+	// clear reset bit [31]
+	tmp = cx_read(PLL_B_INT_FRAC);
+	cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
+
+	// PLL-C setting for video upstream channel
+	cx_write(PLL_C_INT_FRAC, 0x96A0EA3F);
+
+	// PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0
+	cx_write(PLL_C_POST_STAT_BIST, 0x80000103);
+
+	// clear reset bit [31]
+	tmp = cx_read(PLL_C_INT_FRAC);
+	cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
+
+	// PLL-D setting for audio upstream channel
+	cx_write(PLL_D_INT_FRAC, 0x98757F5B);
+
+	// PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0
+	cx_write(PLL_D_POST_STAT_BIST, 0x80000113);
+
+	// clear reset bit [31]
+	tmp = cx_read(PLL_D_INT_FRAC);
+	cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
+
+	// This selects the PLL C clock source for the video upstream channel I and J
+	tmp = cx_read(VID_CH_CLK_SEL);
+	cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
+
+	// 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
+	//select 656/VIP DST for downstream Channel A - C
+	tmp = cx_read(VID_CH_MODE_SEL);
+	//cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
+	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
+
+	// enables 656 port I and J as output
+	tmp = cx_read(CLK_RST);
+	tmp |= FLD_USE_ALT_PLL_REF;	// use external ALT_PLL_REF pin as its reference clock instead
+	cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE));
+
+	mdelay(100);
+}
+
+int cx25821_sram_channel_setup(struct cx25821_dev *dev,
+			       struct sram_channel *ch,
+			       unsigned int bpl, u32 risc)
+{
+	unsigned int i, lines;
+	u32 cdt;
+
+	if (ch->cmds_start == 0) {
+		cx_write(ch->ptr1_reg, 0);
+		cx_write(ch->ptr2_reg, 0);
+		cx_write(ch->cnt2_reg, 0);
+		cx_write(ch->cnt1_reg, 0);
+		return 0;
+	}
+
+	bpl = (bpl + 7) & ~7;	/* alignment */
+	cdt = ch->cdt;
+	lines = ch->fifo_size / bpl;
+
+	if (lines > 4) {
+		lines = 4;
+	}
+
+	BUG_ON(lines < 2);
+
+	cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	cx_write(8 + 4, 8);
+	cx_write(8 + 8, 0);
+
+	/* write CDT */
+	for (i = 0; i < lines; i++) {
+		cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
+		cx_write(cdt + 16 * i + 4, 0);
+		cx_write(cdt + 16 * i + 8, 0);
+		cx_write(cdt + 16 * i + 12, 0);
+	}
+
+	//init the first cdt buffer
+	for (i = 0; i < 128; i++)
+		cx_write(ch->fifo_start + 4 * i, i);
+
+	/* write CMDS */
+	if (ch->jumponly) {
+		cx_write(ch->cmds_start + 0, 8);
+	} else {
+		cx_write(ch->cmds_start + 0, risc);
+	}
+
+	cx_write(ch->cmds_start + 4, 0);	/* 64 bits 63-32 */
+	cx_write(ch->cmds_start + 8, cdt);
+	cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
+	cx_write(ch->cmds_start + 16, ch->ctrl_start);
+
+	if (ch->jumponly)
+		cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
+	else
+		cx_write(ch->cmds_start + 20, 64 >> 2);
+
+	for (i = 24; i < 80; i += 4)
+		cx_write(ch->cmds_start + i, 0);
+
+	/* fill registers */
+	cx_write(ch->ptr1_reg, ch->fifo_start);
+	cx_write(ch->ptr2_reg, cdt);
+	cx_write(ch->cnt2_reg, (lines * 16) >> 3);
+	cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
+
+	return 0;
+}
+
+int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
+				     struct sram_channel *ch,
+				     unsigned int bpl, u32 risc)
+{
+	unsigned int i, lines;
+	u32 cdt;
+
+	if (ch->cmds_start == 0) {
+		cx_write(ch->ptr1_reg, 0);
+		cx_write(ch->ptr2_reg, 0);
+		cx_write(ch->cnt2_reg, 0);
+		cx_write(ch->cnt1_reg, 0);
+		return 0;
+	}
+
+	bpl = (bpl + 7) & ~7;	/* alignment */
+	cdt = ch->cdt;
+	lines = ch->fifo_size / bpl;
+
+	if (lines > 3) {
+		lines = 3;	//for AUDIO
+	}
+
+	BUG_ON(lines < 2);
+
+	cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	cx_write(8 + 4, 8);
+	cx_write(8 + 8, 0);
+
+	/* write CDT */
+	for (i = 0; i < lines; i++) {
+		cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
+		cx_write(cdt + 16 * i + 4, 0);
+		cx_write(cdt + 16 * i + 8, 0);
+		cx_write(cdt + 16 * i + 12, 0);
+	}
+
+	/* write CMDS */
+	if (ch->jumponly) {
+		cx_write(ch->cmds_start + 0, 8);
+	} else {
+		cx_write(ch->cmds_start + 0, risc);
+	}
+
+	cx_write(ch->cmds_start + 4, 0);	/* 64 bits 63-32 */
+	cx_write(ch->cmds_start + 8, cdt);
+	cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
+	cx_write(ch->cmds_start + 16, ch->ctrl_start);
+
+	//IQ size
+	if (ch->jumponly) {
+		cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
+	} else {
+		cx_write(ch->cmds_start + 20, 64 >> 2);
+	}
+
+	//zero out
+	for (i = 24; i < 80; i += 4)
+		cx_write(ch->cmds_start + i, 0);
+
+	/* fill registers */
+	cx_write(ch->ptr1_reg, ch->fifo_start);
+	cx_write(ch->ptr2_reg, cdt);
+	cx_write(ch->cnt2_reg, (lines * 16) >> 3);
+	cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
+
+	return 0;
+}
+
+void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
+{
+	static char *name[] = {
+		"init risc lo",
+		"init risc hi",
+		"cdt base",
+		"cdt size",
+		"iq base",
+		"iq size",
+		"risc pc lo",
+		"risc pc hi",
+		"iq wr ptr",
+		"iq rd ptr",
+		"cdt current",
+		"pci target lo",
+		"pci target hi",
+		"line / byte",
+	};
+	u32 risc;
+	unsigned int i, j, n;
+
+	printk(KERN_WARNING "%s: %s - dma channel status dump\n", dev->name,
+	       ch->name);
+	for (i = 0; i < ARRAY_SIZE(name); i++)
+		printk(KERN_WARNING "cmds + 0x%2x:   %-15s: 0x%08x\n", i * 4,
+		       name[i], cx_read(ch->cmds_start + 4 * i));
+
+	j = i * 4;
+	for (i = 0; i < 4;) {
+		risc = cx_read(ch->cmds_start + 4 * (i + 14));
+		printk(KERN_WARNING "cmds + 0x%2x:   risc%d: ", j + i * 4, i);
+		i += cx25821_risc_decode(risc);
+	}
+
+	for (i = 0; i < (64 >> 2); i += n) {
+		risc = cx_read(ch->ctrl_start + 4 * i);
+		/* No consideration for bits 63-32 */
+
+		printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
+		       ch->ctrl_start + 4 * i, i);
+		n = cx25821_risc_decode(risc);
+		for (j = 1; j < n; j++) {
+			risc = cx_read(ch->ctrl_start + 4 * (i + j));
+			printk(KERN_WARNING
+			       "ctrl + 0x%2x :   iq %x: 0x%08x [ arg #%d ]\n",
+			       4 * (i + j), i + j, risc, j);
+		}
+	}
+
+	printk(KERN_WARNING "        :   fifo: 0x%08x -> 0x%x\n",
+	       ch->fifo_start, ch->fifo_start + ch->fifo_size);
+	printk(KERN_WARNING "        :   ctrl: 0x%08x -> 0x%x\n",
+	       ch->ctrl_start, ch->ctrl_start + 6 * 16);
+	printk(KERN_WARNING "        :   ptr1_reg: 0x%08x\n",
+	       cx_read(ch->ptr1_reg));
+	printk(KERN_WARNING "        :   ptr2_reg: 0x%08x\n",
+	       cx_read(ch->ptr2_reg));
+	printk(KERN_WARNING "        :   cnt1_reg: 0x%08x\n",
+	       cx_read(ch->cnt1_reg));
+	printk(KERN_WARNING "        :   cnt2_reg: 0x%08x\n",
+	       cx_read(ch->cnt2_reg));
+}
+
+void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
+				     struct sram_channel *ch)
+{
+	static char *name[] = {
+		"init risc lo",
+		"init risc hi",
+		"cdt base",
+		"cdt size",
+		"iq base",
+		"iq size",
+		"risc pc lo",
+		"risc pc hi",
+		"iq wr ptr",
+		"iq rd ptr",
+		"cdt current",
+		"pci target lo",
+		"pci target hi",
+		"line / byte",
+	};
+
+	u32 risc, value, tmp;
+	unsigned int i, j, n;
+
+	printk(KERN_INFO "\n%s: %s - dma Audio channel status dump\n",
+	       dev->name, ch->name);
+
+	for (i = 0; i < ARRAY_SIZE(name); i++)
+		printk(KERN_INFO "%s: cmds + 0x%2x:   %-15s: 0x%08x\n",
+		       dev->name, i * 4, name[i],
+		       cx_read(ch->cmds_start + 4 * i));
+
+	j = i * 4;
+	for (i = 0; i < 4;) {
+		risc = cx_read(ch->cmds_start + 4 * (i + 14));
+		printk(KERN_WARNING "cmds + 0x%2x:   risc%d: ", j + i * 4, i);
+		i += cx25821_risc_decode(risc);
+	}
+
+	for (i = 0; i < (64 >> 2); i += n) {
+		risc = cx_read(ch->ctrl_start + 4 * i);
+		/* No consideration for bits 63-32 */
+
+		printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
+		       ch->ctrl_start + 4 * i, i);
+		n = cx25821_risc_decode(risc);
+
+		for (j = 1; j < n; j++) {
+			risc = cx_read(ch->ctrl_start + 4 * (i + j));
+			printk(KERN_WARNING
+			       "ctrl + 0x%2x :   iq %x: 0x%08x [ arg #%d ]\n",
+			       4 * (i + j), i + j, risc, j);
+		}
+	}
+
+	printk(KERN_WARNING "        :   fifo: 0x%08x -> 0x%x\n",
+	       ch->fifo_start, ch->fifo_start + ch->fifo_size);
+	printk(KERN_WARNING "        :   ctrl: 0x%08x -> 0x%x\n",
+	       ch->ctrl_start, ch->ctrl_start + 6 * 16);
+	printk(KERN_WARNING "        :   ptr1_reg: 0x%08x\n",
+	       cx_read(ch->ptr1_reg));
+	printk(KERN_WARNING "        :   ptr2_reg: 0x%08x\n",
+	       cx_read(ch->ptr2_reg));
+	printk(KERN_WARNING "        :   cnt1_reg: 0x%08x\n",
+	       cx_read(ch->cnt1_reg));
+	printk(KERN_WARNING "        :   cnt2_reg: 0x%08x\n",
+	       cx_read(ch->cnt2_reg));
+
+	for (i = 0; i < 4; i++) {
+		risc = cx_read(ch->cmds_start + 56 + (i * 4));
+		printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
+	}
+
+	//read data from the first cdt buffer
+	risc = cx_read(AUD_A_CDT);
+	printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
+	for (i = 0; i < 8; i++) {
+		n = cx_read(risc + i * 4);
+		printk(KERN_WARNING "0x%x ", n);
+	}
+	printk(KERN_WARNING "\n\n");
+
+	value = cx_read(CLK_RST);
+	CX25821_INFO(" CLK_RST = 0x%x \n\n", value);
+
+	value = cx_read(PLL_A_POST_STAT_BIST);
+	CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x \n\n", value);
+	value = cx_read(PLL_A_INT_FRAC);
+	CX25821_INFO(" PLL_A_INT_FRAC = 0x%x \n\n", value);
+
+	value = cx_read(PLL_B_POST_STAT_BIST);
+	CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x \n\n", value);
+	value = cx_read(PLL_B_INT_FRAC);
+	CX25821_INFO(" PLL_B_INT_FRAC = 0x%x \n\n", value);
+
+	value = cx_read(PLL_C_POST_STAT_BIST);
+	CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x \n\n", value);
+	value = cx_read(PLL_C_INT_FRAC);
+	CX25821_INFO(" PLL_C_INT_FRAC = 0x%x \n\n", value);
+
+	value = cx_read(PLL_D_POST_STAT_BIST);
+	CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x \n\n", value);
+	value = cx_read(PLL_D_INT_FRAC);
+	CX25821_INFO(" PLL_D_INT_FRAC = 0x%x \n\n", value);
+
+	value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
+	CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x \n\n", value);
+}
+
+static void cx25821_shutdown(struct cx25821_dev *dev)
+{
+	int i;
+
+	/* disable RISC controller */
+	cx_write(DEV_CNTRL2, 0);
+
+	/* Disable Video A/B activity */
+	for (i = 0; i < VID_CHANNEL_NUM; i++) {
+		cx_write(dev->sram_channels[i].dma_ctl, 0);
+		cx_write(dev->sram_channels[i].int_msk, 0);
+	}
+
+	for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
+	     i++) {
+		cx_write(dev->sram_channels[i].dma_ctl, 0);
+		cx_write(dev->sram_channels[i].int_msk, 0);
+	}
+
+	/* Disable Audio activity */
+	cx_write(AUD_INT_DMA_CTL, 0);
+
+	/* Disable Serial port */
+	cx_write(UART_CTL, 0);
+
+	/* Disable Interrupts */
+	cx_write(PCI_INT_MSK, 0);
+	cx_write(AUD_A_INT_MSK, 0);
+}
+
+void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
+			      u32 format)
+{
+	struct sram_channel *ch;
+
+	if (channel_select <= 7 && channel_select >= 0) {
+		ch = &cx25821_sram_channels[channel_select];
+		cx_write(ch->pix_frmt, format);
+		dev->pixel_formats[channel_select] = format;
+	}
+}
+
+static void cx25821_set_vip_mode(struct cx25821_dev *dev,
+				 struct sram_channel *ch)
+{
+	cx_write(ch->pix_frmt, PIXEL_FRMT_422);
+	cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1);
+}
+
+static void cx25821_initialize(struct cx25821_dev *dev)
+{
+	int i;
+
+	dprintk(1, "%s()\n", __func__);
+
+	cx25821_shutdown(dev);
+	cx_write(PCI_INT_STAT, 0xffffffff);
+
+	for (i = 0; i < VID_CHANNEL_NUM; i++)
+		cx_write(dev->sram_channels[i].int_stat, 0xffffffff);
+
+	cx_write(AUD_A_INT_STAT, 0xffffffff);
+	cx_write(AUD_B_INT_STAT, 0xffffffff);
+	cx_write(AUD_C_INT_STAT, 0xffffffff);
+	cx_write(AUD_D_INT_STAT, 0xffffffff);
+	cx_write(AUD_E_INT_STAT, 0xffffffff);
+
+	cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
+	cx_write(PAD_CTRL, 0x12);	//for I2C
+	cx25821_registers_init(dev);	//init Pecos registers
+	mdelay(100);
+
+	for (i = 0; i < VID_CHANNEL_NUM; i++) {
+		cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
+		cx25821_sram_channel_setup(dev, &dev->sram_channels[i], 1440,
+					   0);
+		dev->pixel_formats[i] = PIXEL_FRMT_422;
+		dev->use_cif_resolution[i] = FALSE;
+	}
+
+	//Probably only affect Downstream
+	for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
+	     i++) {
+		cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
+	}
+
+	cx25821_sram_channel_setup_audio(dev, &dev->sram_channels[SRAM_CH08],
+					 128, 0);
+
+	cx25821_gpio_init(dev);
+}
+
+static int get_resources(struct cx25821_dev *dev)
+{
+	if (request_mem_region
+	    (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0),
+	     dev->name))
+		return 0;
+
+	printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
+	       dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
+
+	return -EBUSY;
+}
+
+static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
+{
+	dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
+
+	printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", __func__,
+	       dev->hwrevision);
+}
+
+static void cx25821_iounmap(struct cx25821_dev *dev)
+{
+	if (dev == NULL)
+		return;
+
+	/* Releasing IO memory */
+	if (dev->lmmio != NULL) {
+		CX25821_INFO("Releasing lmmio.\n");
+		iounmap(dev->lmmio);
+		dev->lmmio = NULL;
+	}
+}
+
+static int cx25821_dev_setup(struct cx25821_dev *dev)
+{
+	int io_size = 0, i;
+
+	struct video_device *video_template[] = {
+		&cx25821_video_template0,
+		&cx25821_video_template1,
+		&cx25821_video_template2,
+		&cx25821_video_template3,
+		&cx25821_video_template4,
+		&cx25821_video_template5,
+		&cx25821_video_template6,
+		&cx25821_video_template7,
+		&cx25821_video_template9,
+		&cx25821_video_template10,
+		&cx25821_video_template11,
+		&cx25821_videoioctl_template,
+	};
+
+	printk(KERN_INFO "\n***********************************\n");
+	printk(KERN_INFO "cx25821 set up\n");
+	printk(KERN_INFO "***********************************\n\n");
+
+	mutex_init(&dev->lock);
+
+	atomic_inc(&dev->refcount);
+
+	dev->nr = ++cx25821_devcount;
+	sprintf(dev->name, "cx25821[%d]", dev->nr);
+
+	mutex_lock(&devlist);
+	list_add_tail(&dev->devlist, &cx25821_devlist);
+	mutex_unlock(&devlist);
+
+	strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
+	strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
+
+	if (dev->pci->device != 0x8210) {
+		printk(KERN_INFO
+		       "%s() Exiting. Incorrect Hardware device = 0x%02x\n",
+		       __func__, dev->pci->device);
+		return -1;
+	} else {
+		printk(KERN_INFO "Athena Hardware device = 0x%02x\n",
+		       dev->pci->device);
+	}
+
+	/* Apply a sensible clock frequency for the PCIe bridge */
+	dev->clk_freq = 28000000;
+	dev->sram_channels = cx25821_sram_channels;
+
+	if (dev->nr > 1) {
+		CX25821_INFO("dev->nr > 1!");
+	}
+
+	/* board config */
+	dev->board = 1;		//card[dev->nr];
+	dev->_max_num_decoders = MAX_DECODERS;
+
+	dev->pci_bus = dev->pci->bus->number;
+	dev->pci_slot = PCI_SLOT(dev->pci->devfn);
+	dev->pci_irqmask = 0x001f00;
+
+	/* External Master 1 Bus */
+	dev->i2c_bus[0].nr = 0;
+	dev->i2c_bus[0].dev = dev;
+	dev->i2c_bus[0].reg_stat = I2C1_STAT;
+	dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
+	dev->i2c_bus[0].reg_addr = I2C1_ADDR;
+	dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
+	dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
+	dev->i2c_bus[0].i2c_period = (0x07 << 24);	/* 1.95MHz */
+
+
+	if (get_resources(dev) < 0) {
+		printk(KERN_ERR "%s No more PCIe resources for "
+		       "subsystem: %04x:%04x\n",
+		       dev->name, dev->pci->subsystem_vendor,
+		       dev->pci->subsystem_device);
+
+		cx25821_devcount--;
+		return -ENODEV;
+	}
+
+	/* PCIe stuff */
+	dev->base_io_addr = pci_resource_start(dev->pci, 0);
+	io_size = pci_resource_len(dev->pci, 0);
+
+	if (!dev->base_io_addr) {
+		CX25821_ERR("No PCI Memory resources, exiting!\n");
+		return -ENODEV;
+	}
+
+	dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
+
+	if (!dev->lmmio) {
+		CX25821_ERR
+		    ("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
+		cx25821_iounmap(dev);
+		return -ENOMEM;
+	}
+
+	dev->bmmio = (u8 __iomem *) dev->lmmio;
+
+	printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+	       dev->name, dev->pci->subsystem_vendor,
+	       dev->pci->subsystem_device, cx25821_boards[dev->board].name,
+	       dev->board, card[dev->nr] == dev->board ?
+	       "insmod option" : "autodetected");
+
+	/* init hardware */
+	cx25821_initialize(dev);
+
+	cx25821_i2c_register(&dev->i2c_bus[0]);
+//  cx25821_i2c_register(&dev->i2c_bus[1]);
+//  cx25821_i2c_register(&dev->i2c_bus[2]);
+
+	CX25821_INFO("i2c register! bus->i2c_rc = %d\n",
+		     dev->i2c_bus[0].i2c_rc);
+
+	cx25821_card_setup(dev);
+	medusa_video_init(dev);
+
+	for (i = 0; i < VID_CHANNEL_NUM; i++) {
+		if (cx25821_video_register(dev, i, video_template[i]) < 0) {
+			printk(KERN_ERR
+			       "%s() Failed to register analog video adapters on VID channel %d\n",
+			       __func__, i);
+		}
+	}
+
+	for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
+	     i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
+		//Since we don't have template8 for Audio Downstream
+		if (cx25821_video_register(dev, i, video_template[i - 1]) < 0) {
+			printk(KERN_ERR
+			       "%s() Failed to register analog video adapters for Upstream channel %d.\n",
+			       __func__, i);
+		}
+	}
+
+	// register IOCTL device
+	dev->ioctl_dev =
+	    cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH],
+			      "video");
+
+	if (video_register_device
+	    (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
+		cx25821_videoioctl_unregister(dev);
+		printk(KERN_ERR
+		       "%s() Failed to register video adapter for IOCTL so releasing.\n",
+		       __func__);
+	}
+
+	cx25821_dev_checkrevision(dev);
+	CX25821_INFO("cx25821 setup done!\n");
+
+	return 0;
+}
+
+void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
+				      struct upstream_user_struct *up_data)
+{
+	dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0;
+
+	dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
+	medusa_set_videostandard(dev);
+
+	cx25821_vidupstream_init_ch1(dev, dev->channel_select,
+				     dev->pixel_format);
+}
+
+void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
+				      struct upstream_user_struct *up_data)
+{
+	dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0;
+
+	dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
+	medusa_set_videostandard(dev);
+
+	cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2,
+				     dev->pixel_format_ch2);
+}
+
+void cx25821_start_upstream_audio(struct cx25821_dev *dev,
+				  struct upstream_user_struct *up_data)
+{
+	cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B);
+}
+
+void cx25821_dev_unregister(struct cx25821_dev *dev)
+{
+	int i;
+
+	if (!dev->base_io_addr)
+		return;
+
+	cx25821_free_mem_upstream_ch1(dev);
+	cx25821_free_mem_upstream_ch2(dev);
+	cx25821_free_mem_upstream_audio(dev);
+
+	release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
+
+	if (!atomic_dec_and_test(&dev->refcount))
+		return;
+
+	for (i = 0; i < VID_CHANNEL_NUM; i++)
+		cx25821_video_unregister(dev, i);
+
+	for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
+	     i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
+		cx25821_video_unregister(dev, i);
+	}
+
+	cx25821_videoioctl_unregister(dev);
+
+	cx25821_i2c_unregister(&dev->i2c_bus[0]);
+	cx25821_iounmap(dev);
+}
+
+static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
+				  unsigned int offset, u32 sync_line,
+				  unsigned int bpl, unsigned int padding,
+				  unsigned int lines)
+{
+	struct scatterlist *sg;
+	unsigned int line, todo;
+
+	/* sync instruction */
+	if (sync_line != NO_SYNC_LINE) {
+		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
+	}
+
+	/* scan lines */
+	sg = sglist;
+	for (line = 0; line < lines; line++) {
+		while (offset && offset >= sg_dma_len(sg)) {
+			offset -= sg_dma_len(sg);
+			sg++;
+		}
+		if (bpl <= sg_dma_len(sg) - offset) {
+			/* fits into current chunk */
+			*(rp++) =
+			    cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | bpl);
+			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
+			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+			offset += bpl;
+		} else {
+			/* scanline needs to be split */
+			todo = bpl;
+			*(rp++) =
+			    cpu_to_le32(RISC_WRITE | RISC_SOL |
+					(sg_dma_len(sg) - offset));
+			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
+			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+			todo -= (sg_dma_len(sg) - offset);
+			offset = 0;
+			sg++;
+			while (todo > sg_dma_len(sg)) {
+				*(rp++) =
+				    cpu_to_le32(RISC_WRITE | sg_dma_len(sg));
+				*(rp++) = cpu_to_le32(sg_dma_address(sg));
+				*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+				todo -= sg_dma_len(sg);
+				sg++;
+			}
+			*(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
+			*(rp++) = cpu_to_le32(sg_dma_address(sg));
+			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+			offset += todo;
+		}
+
+		offset += padding;
+	}
+
+	return rp;
+}
+
+int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+			struct scatterlist *sglist, unsigned int top_offset,
+			unsigned int bottom_offset, unsigned int bpl,
+			unsigned int padding, unsigned int lines)
+{
+	u32 instructions;
+	u32 fields;
+	__le32 *rp;
+	int rc;
+
+	fields = 0;
+	if (UNSET != top_offset)
+		fields++;
+	if (UNSET != bottom_offset)
+		fields++;
+
+	/* estimate risc mem: worst case is one write per page border +
+	   one write per scan line + syncs + jump (all 2 dwords).  Padding
+	   can cause next bpl to start close to a page border.  First DMA
+	   region may be smaller than PAGE_SIZE */
+	/* write and jump need and extra dword */
+	instructions =
+	    fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
+	instructions += 2;
+	rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
+
+	if (rc < 0)
+		return rc;
+
+	/* write risc instructions */
+	rp = risc->cpu;
+
+	if (UNSET != top_offset) {
+		rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding,
+					lines);
+	}
+
+	if (UNSET != bottom_offset) {
+		rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl,
+					padding, lines);
+	}
+
+	/* save pointer to jmp instruction address */
+	risc->jmp = rp;
+	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
+
+	return 0;
+}
+
+static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist,
+					unsigned int offset, u32 sync_line,
+					unsigned int bpl, unsigned int padding,
+					unsigned int lines, unsigned int lpi)
+{
+	struct scatterlist *sg;
+	unsigned int line, todo, sol;
+
+	/* sync instruction */
+	if (sync_line != NO_SYNC_LINE)
+		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
+
+	/* scan lines */
+	sg = sglist;
+	for (line = 0; line < lines; line++) {
+		while (offset && offset >= sg_dma_len(sg)) {
+			offset -= sg_dma_len(sg);
+			sg++;
+		}
+
+		if (lpi && line > 0 && !(line % lpi))
+			sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
+		else
+			sol = RISC_SOL;
+
+		if (bpl <= sg_dma_len(sg) - offset) {
+			/* fits into current chunk */
+			*(rp++) =
+			    cpu_to_le32(RISC_WRITE | sol | RISC_EOL | bpl);
+			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
+			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+			offset += bpl;
+		} else {
+			/* scanline needs to be split */
+			todo = bpl;
+			*(rp++) = cpu_to_le32(RISC_WRITE | sol |
+					      (sg_dma_len(sg) - offset));
+			*(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
+			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+			todo -= (sg_dma_len(sg) - offset);
+			offset = 0;
+			sg++;
+			while (todo > sg_dma_len(sg)) {
+				*(rp++) = cpu_to_le32(RISC_WRITE |
+						      sg_dma_len(sg));
+				*(rp++) = cpu_to_le32(sg_dma_address(sg));
+				*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+				todo -= sg_dma_len(sg);
+				sg++;
+			}
+			*(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
+			*(rp++) = cpu_to_le32(sg_dma_address(sg));
+			*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+			offset += todo;
+		}
+		offset += padding;
+	}
+
+	return rp;
+}
+
+int cx25821_risc_databuffer_audio(struct pci_dev *pci,
+				  struct btcx_riscmem *risc,
+				  struct scatterlist *sglist,
+				  unsigned int bpl,
+				  unsigned int lines, unsigned int lpi)
+{
+	u32 instructions;
+	__le32 *rp;
+	int rc;
+
+	/* estimate risc mem: worst case is one write per page border +
+	   one write per scan line + syncs + jump (all 2 dwords).  Here
+	   there is no padding and no sync.  First DMA region may be smaller
+	   than PAGE_SIZE */
+	/* Jump and write need an extra dword */
+	instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
+	instructions += 1;
+
+	if ((rc = btcx_riscmem_alloc(pci, risc, instructions * 12)) < 0)
+		return rc;
+
+	/* write risc instructions */
+	rp = risc->cpu;
+	rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
+				      lines, lpi);
+
+	/* save pointer to jmp instruction address */
+	risc->jmp = rp;
+	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
+	return 0;
+}
+
+int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
+			 u32 reg, u32 mask, u32 value)
+{
+	__le32 *rp;
+	int rc;
+
+	rc = btcx_riscmem_alloc(pci, risc, 4 * 16);
+
+	if (rc < 0)
+		return rc;
+
+	/* write risc instructions */
+	rp = risc->cpu;
+
+	*(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1);
+	*(rp++) = cpu_to_le32(reg);
+	*(rp++) = cpu_to_le32(value);
+	*(rp++) = cpu_to_le32(mask);
+	*(rp++) = cpu_to_le32(RISC_JUMP);
+	*(rp++) = cpu_to_le32(risc->dma);
+	*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+	return 0;
+}
+
+void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
+{
+	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
+
+	BUG_ON(in_interrupt());
+	videobuf_waiton(&buf->vb, 0, 0);
+	videobuf_dma_unmap(q, dma);
+	videobuf_dma_free(dma);
+	btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static irqreturn_t cx25821_irq(int irq, void *dev_id)
+{
+	struct cx25821_dev *dev = dev_id;
+	u32 pci_status, pci_mask;
+	u32 vid_status;
+	int i, handled = 0;
+	u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+
+	pci_status = cx_read(PCI_INT_STAT);
+	pci_mask = cx_read(PCI_INT_MSK);
+
+	if (pci_status == 0)
+		goto out;
+
+	for (i = 0; i < VID_CHANNEL_NUM; i++) {
+		if (pci_status & mask[i]) {
+			vid_status = cx_read(dev->sram_channels[i].int_stat);
+
+			if (vid_status)
+				handled +=
+				    cx25821_video_irq(dev, i, vid_status);
+
+			cx_write(PCI_INT_STAT, mask[i]);
+		}
+	}
+
+      out:
+	return IRQ_RETVAL(handled);
+}
+
+void cx25821_print_irqbits(char *name, char *tag, char **strings,
+			   int len, u32 bits, u32 mask)
+{
+	unsigned int i;
+
+	printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
+
+	for (i = 0; i < len; i++) {
+		if (!(bits & (1 << i)))
+			continue;
+		if (strings[i])
+			printk(" %s", strings[i]);
+		else
+			printk(" %d", i);
+		if (!(mask & (1 << i)))
+			continue;
+		printk("*");
+	}
+	printk("\n");
+}
+
+struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci)
+{
+	struct cx25821_dev *dev = pci_get_drvdata(pci);
+	return dev;
+}
+
+static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
+				     const struct pci_device_id *pci_id)
+{
+	struct cx25821_dev *dev;
+	int err = 0;
+
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+	if (NULL == dev)
+		return -ENOMEM;
+
+	err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+	if (err < 0)
+		goto fail_free;
+
+	/* pci init */
+	dev->pci = pci_dev;
+	if (pci_enable_device(pci_dev)) {
+		err = -EIO;
+
+		printk(KERN_INFO "pci enable failed! ");
+
+		goto fail_unregister_device;
+	}
+
+	printk(KERN_INFO "cx25821 Athena pci enable ! \n");
+
+	if (cx25821_dev_setup(dev) < 0) {
+		err = -EINVAL;
+		goto fail_unregister_device;
+	}
+
+	/* print pci info */
+	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
+	printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
+	       "latency: %d, mmio: 0x%llx\n", dev->name,
+	       pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
+	       dev->pci_lat, (unsigned long long)dev->base_io_addr);
+
+	pci_set_master(pci_dev);
+	if (!pci_dma_supported(pci_dev, 0xffffffff)) {
+		printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
+		err = -EIO;
+		goto fail_irq;
+	}
+
+	err =
+	    request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED | IRQF_DISABLED,
+			dev->name, dev);
+
+	if (err < 0) {
+		printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
+		       pci_dev->irq);
+		goto fail_irq;
+	}
+
+	return 0;
+
+      fail_irq:
+	printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ ! \n");
+	cx25821_dev_unregister(dev);
+
+      fail_unregister_device:
+	v4l2_device_unregister(&dev->v4l2_dev);
+
+      fail_free:
+	kfree(dev);
+	return err;
+}
+
+static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
+{
+	struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+	struct cx25821_dev *dev = get_cx25821(v4l2_dev);
+
+	cx25821_shutdown(dev);
+	pci_disable_device(pci_dev);
+
+	/* unregister stuff */
+	if (pci_dev->irq)
+		free_irq(pci_dev->irq, dev);
+
+	mutex_lock(&devlist);
+	list_del(&dev->devlist);
+	mutex_unlock(&devlist);
+
+	cx25821_dev_unregister(dev);
+	v4l2_device_unregister(v4l2_dev);
+	kfree(dev);
+}
+
+static struct pci_device_id cx25821_pci_tbl[] = {
+	{
+	 /* CX25821 Athena */
+	 .vendor = 0x14f1,
+	 .device = 0x8210,
+	 .subvendor = 0x14f1,
+	 .subdevice = 0x0920,
+	 },
+	{
+	 /* --- end of list --- */
+	 }
+};
+
+MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl);
+
+static struct pci_driver cx25821_pci_driver = {
+	.name = "cx25821",
+	.id_table = cx25821_pci_tbl,
+	.probe = cx25821_initdev,
+	.remove = __devexit_p(cx25821_finidev),
+	/* TODO */
+	.suspend = NULL,
+	.resume = NULL,
+};
+
+static int cx25821_init(void)
+{
+	INIT_LIST_HEAD(&cx25821_devlist);
+	printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
+	       (CX25821_VERSION_CODE >> 16) & 0xff,
+	       (CX25821_VERSION_CODE >> 8) & 0xff, CX25821_VERSION_CODE & 0xff);
+	return pci_register_driver(&cx25821_pci_driver);
+}
+
+static void cx25821_fini(void)
+{
+	pci_unregister_driver(&cx25821_pci_driver);
+}
+
+EXPORT_SYMBOL(cx25821_devlist);
+EXPORT_SYMBOL(cx25821_sram_channels);
+EXPORT_SYMBOL(cx25821_print_irqbits);
+EXPORT_SYMBOL(cx25821_dev_get);
+EXPORT_SYMBOL(cx25821_dev_unregister);
+EXPORT_SYMBOL(cx25821_sram_channel_setup);
+EXPORT_SYMBOL(cx25821_sram_channel_dump);
+EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
+EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
+EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
+EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
+
+module_init(cx25821_init);
+module_exit(cx25821_fini);
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/staging/cx25821/cx25821-gpio.c
new file mode 100644
index 0000000..e8a37b4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.c
@@ -0,0 +1,98 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#include "cx25821.h"
+
+/********************* GPIO stuffs *********************/
+void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
+				   int pin_number, int pin_logic_value)
+{
+	int bit = pin_number;
+	u32 gpio_oe_reg = GPIO_LO_OE;
+	u32 gpio_register = 0;
+	u32 value = 0;
+
+	// Check for valid pinNumber
+	if (pin_number >= 47)
+		return;
+
+	if (pin_number > 31) {
+		bit = pin_number - 31;
+		gpio_oe_reg = GPIO_HI_OE;
+	}
+	// Here we will make sure that the GPIOs 0 and 1 are output. keep the rest as is
+	gpio_register = cx_read(gpio_oe_reg);
+
+	if (pin_logic_value == 1) {
+		value = gpio_register | Set_GPIO_Bit(bit);
+	} else {
+		value = gpio_register & Clear_GPIO_Bit(bit);
+	}
+
+	cx_write(gpio_oe_reg, value);
+}
+
+static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
+					   int pin_number, int pin_logic_value)
+{
+	int bit = pin_number;
+	u32 gpio_reg = GPIO_LO;
+	u32 value = 0;
+
+	// Check for valid pinNumber
+	if (pin_number >= 47)
+		return;
+
+	cx25821_set_gpiopin_direction(dev, pin_number, 0);	// change to output direction
+
+	if (pin_number > 31) {
+		bit = pin_number - 31;
+		gpio_reg = GPIO_HI;
+	}
+
+	value = cx_read(gpio_reg);
+
+	if (pin_logic_value == 0) {
+		value &= Clear_GPIO_Bit(bit);
+	} else {
+		value |= Set_GPIO_Bit(bit);
+	}
+
+	cx_write(gpio_reg, value);
+}
+
+void cx25821_gpio_init(struct cx25821_dev *dev)
+{
+	if (dev == NULL) {
+		return;
+	}
+
+	switch (dev->board) {
+	case CX25821_BOARD_CONEXANT_ATHENA10:
+	default:
+		//set GPIO 5 to select the path for Medusa/Athena
+		cx25821_set_gpiopin_logicvalue(dev, 5, 1);
+		mdelay(20);
+		break;
+	}
+
+}
diff --git a/drivers/staging/cx25821/cx25821-gpio.h b/drivers/staging/cx25821/cx25821-gpio.h
new file mode 100644
index 0000000..ca07644
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.h
@@ -0,0 +1,2 @@
+
+void cx25821_gpio_init(struct athena_dev *dev);
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
new file mode 100644
index 0000000..f4f2681
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -0,0 +1,419 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *	Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821.h"
+#include <linux/i2c.h>
+
+static unsigned int i2c_debug;
+module_param(i2c_debug, int, 0644);
+MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
+
+static unsigned int i2c_scan = 0;
+module_param(i2c_scan, int, 0444);
+MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
+
+#define dprintk(level, fmt, arg...)\
+	do { if (i2c_debug >= level)\
+		printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
+	} while (0)
+
+#define I2C_WAIT_DELAY 32
+#define I2C_WAIT_RETRY 64
+
+#define I2C_EXTEND  (1 << 3)
+#define I2C_NOSTOP  (1 << 4)
+
+static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
+{
+	struct cx25821_i2c *bus = i2c_adap->algo_data;
+	struct cx25821_dev *dev = bus->dev;
+	return cx_read(bus->reg_stat) & 0x01;
+}
+
+static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
+{
+	struct cx25821_i2c *bus = i2c_adap->algo_data;
+	struct cx25821_dev *dev = bus->dev;
+	return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
+}
+
+static int i2c_wait_done(struct i2c_adapter *i2c_adap)
+{
+	int count;
+
+	for (count = 0; count < I2C_WAIT_RETRY; count++) {
+		if (!i2c_is_busy(i2c_adap))
+			break;
+		udelay(I2C_WAIT_DELAY);
+	}
+
+	if (I2C_WAIT_RETRY == count)
+		return 0;
+
+	return 1;
+}
+
+static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
+			 const struct i2c_msg *msg, int joined_rlen)
+{
+	struct cx25821_i2c *bus = i2c_adap->algo_data;
+	struct cx25821_dev *dev = bus->dev;
+	u32 wdata, addr, ctrl;
+	int retval, cnt;
+
+	if (joined_rlen)
+		dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__,
+			msg->len, joined_rlen);
+	else
+		dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
+
+	/* Deal with i2c probe functions with zero payload */
+	if (msg->len == 0) {
+		cx_write(bus->reg_addr, msg->addr << 25);
+		cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
+
+		if (!i2c_wait_done(i2c_adap))
+			return -EIO;
+
+		if (!i2c_slave_did_ack(i2c_adap))
+			return -EIO;
+
+		dprintk(1, "%s() returns 0\n", __func__);
+		return 0;
+	}
+
+	/* dev, reg + first byte */
+	addr = (msg->addr << 25) | msg->buf[0];
+	wdata = msg->buf[0];
+
+	ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
+
+	if (msg->len > 1)
+		ctrl |= I2C_NOSTOP | I2C_EXTEND;
+	else if (joined_rlen)
+		ctrl |= I2C_NOSTOP;
+
+	cx_write(bus->reg_addr, addr);
+	cx_write(bus->reg_wdata, wdata);
+	cx_write(bus->reg_ctrl, ctrl);
+
+	retval = i2c_wait_done(i2c_adap);
+	if (retval < 0)
+		goto err;
+
+	if (retval == 0)
+		goto eio;
+
+	if (i2c_debug) {
+		if (!(ctrl & I2C_NOSTOP))
+			printk(" >\n");
+	}
+
+	for (cnt = 1; cnt < msg->len; cnt++) {
+		/* following bytes */
+		wdata = msg->buf[cnt];
+		ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
+
+		if (cnt < msg->len - 1)
+			ctrl |= I2C_NOSTOP | I2C_EXTEND;
+		else if (joined_rlen)
+			ctrl |= I2C_NOSTOP;
+
+		cx_write(bus->reg_addr, addr);
+		cx_write(bus->reg_wdata, wdata);
+		cx_write(bus->reg_ctrl, ctrl);
+
+		retval = i2c_wait_done(i2c_adap);
+		if (retval < 0)
+			goto err;
+
+		if (retval == 0)
+			goto eio;
+
+		if (i2c_debug) {
+			dprintk(1, " %02x", msg->buf[cnt]);
+			if (!(ctrl & I2C_NOSTOP))
+				dprintk(1, " >\n");
+		}
+	}
+
+	return msg->len;
+
+      eio:
+	retval = -EIO;
+      err:
+	if (i2c_debug)
+		printk(KERN_ERR " ERR: %d\n", retval);
+	return retval;
+}
+
+static int i2c_readbytes(struct i2c_adapter *i2c_adap,
+			 const struct i2c_msg *msg, int joined)
+{
+	struct cx25821_i2c *bus = i2c_adap->algo_data;
+	struct cx25821_dev *dev = bus->dev;
+	u32 ctrl, cnt;
+	int retval;
+
+	if (i2c_debug && !joined)
+		dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len);
+
+	/* Deal with i2c probe functions with zero payload */
+	if (msg->len == 0) {
+		cx_write(bus->reg_addr, msg->addr << 25);
+		cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
+		if (!i2c_wait_done(i2c_adap))
+			return -EIO;
+		if (!i2c_slave_did_ack(i2c_adap))
+			return -EIO;
+
+		dprintk(1, "%s() returns 0\n", __func__);
+		return 0;
+	}
+
+	if (i2c_debug) {
+		if (joined)
+			dprintk(1, " R");
+		else
+			dprintk(1, " <R %02x", (msg->addr << 1) + 1);
+	}
+
+	for (cnt = 0; cnt < msg->len; cnt++) {
+
+		ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
+
+		if (cnt < msg->len - 1)
+			ctrl |= I2C_NOSTOP | I2C_EXTEND;
+
+		cx_write(bus->reg_addr, msg->addr << 25);
+		cx_write(bus->reg_ctrl, ctrl);
+
+		retval = i2c_wait_done(i2c_adap);
+		if (retval < 0)
+			goto err;
+		if (retval == 0)
+			goto eio;
+		msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
+
+		if (i2c_debug) {
+			dprintk(1, " %02x", msg->buf[cnt]);
+			if (!(ctrl & I2C_NOSTOP))
+				dprintk(1, " >\n");
+		}
+	}
+
+	return msg->len;
+      eio:
+	retval = -EIO;
+      err:
+	if (i2c_debug)
+		printk(KERN_ERR " ERR: %d\n", retval);
+	return retval;
+}
+
+static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
+{
+	struct cx25821_i2c *bus = i2c_adap->algo_data;
+	struct cx25821_dev *dev = bus->dev;
+	int i, retval = 0;
+
+	dprintk(1, "%s(num = %d)\n", __func__, num);
+
+	for (i = 0; i < num; i++) {
+		dprintk(1, "%s(num = %d) addr = 0x%02x  len = 0x%x\n",
+			__func__, num, msgs[i].addr, msgs[i].len);
+
+		if (msgs[i].flags & I2C_M_RD) {
+			/* read */
+			retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
+		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
+			   msgs[i].addr == msgs[i + 1].addr) {
+			/* write then read from same address */
+			retval =
+			    i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len);
+
+			if (retval < 0)
+				goto err;
+			i++;
+			retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
+		} else {
+			/* write */
+			retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
+		}
+
+		if (retval < 0)
+			goto err;
+	}
+	return num;
+
+      err:
+	return retval;
+}
+
+
+static u32 cx25821_functionality(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_SMBUS_EMUL |
+	    I2C_FUNC_I2C |
+	    I2C_FUNC_SMBUS_WORD_DATA |
+	    I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
+}
+
+static struct i2c_algorithm cx25821_i2c_algo_template = {
+	.master_xfer = i2c_xfer,
+	.functionality = cx25821_functionality,
+};
+
+static struct i2c_adapter cx25821_i2c_adap_template = {
+	.name = "cx25821",
+	.owner = THIS_MODULE,
+	.algo = &cx25821_i2c_algo_template,
+};
+
+static struct i2c_client cx25821_i2c_client_template = {
+	.name = "cx25821 internal",
+};
+
+/* init + register i2c algo-bit adapter */
+int cx25821_i2c_register(struct cx25821_i2c *bus)
+{
+	struct cx25821_dev *dev = bus->dev;
+
+	dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
+
+	memcpy(&bus->i2c_adap, &cx25821_i2c_adap_template,
+	       sizeof(bus->i2c_adap));
+	memcpy(&bus->i2c_algo, &cx25821_i2c_algo_template,
+	       sizeof(bus->i2c_algo));
+	memcpy(&bus->i2c_client, &cx25821_i2c_client_template,
+	       sizeof(bus->i2c_client));
+
+	bus->i2c_adap.dev.parent = &dev->pci->dev;
+
+	strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
+
+	bus->i2c_algo.data = bus;
+	bus->i2c_adap.algo_data = bus;
+	i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
+	i2c_add_adapter(&bus->i2c_adap);
+
+	bus->i2c_client.adapter = &bus->i2c_adap;
+
+	//set up the I2c
+	bus->i2c_client.addr = (0x88 >> 1);
+
+	return bus->i2c_rc;
+}
+
+int cx25821_i2c_unregister(struct cx25821_i2c *bus)
+{
+	i2c_del_adapter(&bus->i2c_adap);
+	return 0;
+}
+
+void cx25821_av_clk(struct cx25821_dev *dev, int enable)
+{
+	/* write 0 to bus 2 addr 0x144 via i2x_xfer() */
+	char buffer[3];
+	struct i2c_msg msg;
+	dprintk(1, "%s(enabled = %d)\n", __func__, enable);
+
+	/* Register 0x144 */
+	buffer[0] = 0x01;
+	buffer[1] = 0x44;
+	if (enable == 1)
+		buffer[2] = 0x05;
+	else
+		buffer[2] = 0x00;
+
+	msg.addr = 0x44;
+	msg.flags = I2C_M_TEN;
+	msg.len = 3;
+	msg.buf = buffer;
+
+	i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
+}
+
+int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
+{
+	struct i2c_client *client = &bus->i2c_client;
+	int retval = 0;
+	int v = 0;
+	u8 addr[2] = { 0, 0 };
+	u8 buf[4] = { 0, 0, 0, 0 };
+
+	struct i2c_msg msgs[2] = {
+		{
+		 .addr = client->addr,
+		 .flags = 0,
+		 .len = 2,
+		 .buf = addr,
+		 }, {
+		     .addr = client->addr,
+		     .flags = I2C_M_RD,
+		     .len = 4,
+		     .buf = buf,
+		     }
+	};
+
+	addr[0] = (reg_addr >> 8);
+	addr[1] = (reg_addr & 0xff);
+	msgs[0].addr = 0x44;
+	msgs[1].addr = 0x44;
+
+	retval = i2c_xfer(client->adapter, msgs, 2);
+
+	v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+	*value = v;
+
+	return v;
+}
+
+int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value)
+{
+	struct i2c_client *client = &bus->i2c_client;
+	int retval = 0;
+	u8 buf[6] = { 0, 0, 0, 0, 0, 0 };
+
+	struct i2c_msg msgs[1] = {
+		{
+		 .addr = client->addr,
+		 .flags = 0,
+		 .len = 6,
+		 .buf = buf,
+		 }
+	};
+
+	buf[0] = reg_addr >> 8;
+	buf[1] = reg_addr & 0xff;
+	buf[5] = (value >> 24) & 0xff;
+	buf[4] = (value >> 16) & 0xff;
+	buf[3] = (value >> 8) & 0xff;
+	buf[2] = value & 0xff;
+	client->flags = 0;
+	msgs[0].addr = 0x44;
+
+	retval = i2c_xfer(client->adapter, msgs, 1);
+
+	return retval;
+}
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/staging/cx25821/cx25821-medusa-defines.h
new file mode 100644
index 0000000..b0d216b
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-defines.h
@@ -0,0 +1,51 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#ifndef _MEDUSA_DEF_H_
+#define _MEDUSA_DEF_H_
+
+// Video deocder that we supported
+#define VDEC_A		0
+#define VDEC_B		1
+#define VDEC_C		2
+#define VDEC_D		3
+#define VDEC_E		4
+#define VDEC_F		5
+#define VDEC_G		6
+#define VDEC_H		7
+
+//#define AUTO_SWITCH_BIT[]  = { 8, 9, 10, 11, 12, 13, 14, 15 };
+
+// The following bit position enables automatic source switching for decoder A-H.
+// Display index per camera.
+//#define VDEC_INDEX[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
+
+// Select input bit to video decoder A-H.
+//#define CH_SRC_SEL_BIT[] = {24, 25, 26, 27, 28, 29, 30, 31};
+
+// end of display sequence
+#define END_OF_SEQ					0xF;
+
+// registry string size
+#define MAX_REGISTRY_SZ					40;
+
+#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/staging/cx25821/cx25821-medusa-reg.h
new file mode 100644
index 0000000..12c90f8
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-reg.h
@@ -0,0 +1,455 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#ifndef __MEDUSA_REGISTERS__
+#define __MEDUSA_REGISTERS__
+
+// Serial Slave Registers
+#define	HOST_REGISTER1				0x0000
+#define	HOST_REGISTER2				0x0001
+
+// Chip Configuration Registers
+#define	CHIP_CTRL					0x0100
+#define	AFE_AB_CTRL					0x0104
+#define	AFE_CD_CTRL					0x0108
+#define	AFE_EF_CTRL					0x010C
+#define	AFE_GH_CTRL					0x0110
+#define	DENC_AB_CTRL				0x0114
+#define	BYP_AB_CTRL					0x0118
+#define	MON_A_CTRL					0x011C
+#define	DISP_SEQ_A					0x0120
+#define	DISP_SEQ_B					0x0124
+#define	DISP_AB_CNT					0x0128
+#define	DISP_CD_CNT					0x012C
+#define	DISP_EF_CNT					0x0130
+#define	DISP_GH_CNT					0x0134
+#define	DISP_IJ_CNT					0x0138
+#define	PIN_OE_CTRL					0x013C
+#define	PIN_SPD_CTRL				0x0140
+#define	PIN_SPD_CTRL2				0x0144
+#define	IRQ_STAT_CTRL				0x0148
+#define	POWER_CTRL_AB				0x014C
+#define	POWER_CTRL_CD				0x0150
+#define	POWER_CTRL_EF				0x0154
+#define	POWER_CTRL_GH				0x0158
+#define	TUNE_CTRL					0x015C
+#define	BIAS_CTRL					0x0160
+#define	AFE_AB_DIAG_CTRL			0x0164
+#define	AFE_CD_DIAG_CTRL			0x0168
+#define	AFE_EF_DIAG_CTRL			0x016C
+#define	AFE_GH_DIAG_CTRL			0x0170
+#define	PLL_AB_DIAG_CTRL			0x0174
+#define	PLL_CD_DIAG_CTRL			0x0178
+#define	PLL_EF_DIAG_CTRL			0x017C
+#define	PLL_GH_DIAG_CTRL			0x0180
+#define	TEST_CTRL					0x0184
+#define	BIST_STAT					0x0188
+#define	BIST_STAT2					0x018C
+#define	BIST_VID_PLL_AB_STAT		0x0190
+#define	BIST_VID_PLL_CD_STAT		0x0194
+#define	BIST_VID_PLL_EF_STAT		0x0198
+#define	BIST_VID_PLL_GH_STAT		0x019C
+#define	DLL_DIAG_CTRL				0x01A0
+#define	DEV_CH_ID_CTRL				0x01A4
+#define	ABIST_CTRL_STATUS			0x01A8
+#define	ABIST_FREQ					0x01AC
+#define	ABIST_GOERT_SHIFT			0x01B0
+#define	ABIST_COEF12				0x01B4
+#define	ABIST_COEF34				0x01B8
+#define	ABIST_COEF56				0x01BC
+#define	ABIST_COEF7_SNR				0x01C0
+#define	ABIST_ADC_CAL				0x01C4
+#define	ABIST_BIN1_VGA0				0x01C8
+#define	ABIST_BIN2_VGA1				0x01CC
+#define	ABIST_BIN3_VGA2				0x01D0
+#define	ABIST_BIN4_VGA3				0x01D4
+#define	ABIST_BIN5_VGA4				0x01D8
+#define	ABIST_BIN6_VGA5				0x01DC
+#define	ABIST_BIN7_VGA6				0x0x1E0
+#define	ABIST_CLAMP_A				0x0x1E4
+#define	ABIST_CLAMP_B				0x0x1E8
+#define	ABIST_CLAMP_C				0x01EC
+#define	ABIST_CLAMP_D				0x01F0
+#define	ABIST_CLAMP_E				0x01F4
+#define	ABIST_CLAMP_F				0x01F8
+
+//              Digital Video Encoder A Registers
+#define	DENC_A_REG_1					0x0200
+#define	DENC_A_REG_2					0x0204
+#define	DENC_A_REG_3					0x0208
+#define	DENC_A_REG_4					0x020C
+#define	DENC_A_REG_5					0x0210
+#define	DENC_A_REG_6					0x0214
+#define	DENC_A_REG_7					0x0218
+#define	DENC_A_REG_8					0x021C
+
+//      Digital Video Encoder B Registers
+#define	DENC_B_REG_1					0x0300
+#define	DENC_B_REG_2					0x0304
+#define	DENC_B_REG_3					0x0308
+#define	DENC_B_REG_4					0x030C
+#define	DENC_B_REG_5					0x0310
+#define	DENC_B_REG_6					0x0314
+#define	DENC_B_REG_7					0x0318
+#define	DENC_B_REG_8					0x031C
+
+//              Video Decoder A Registers
+#define	MODE_CTRL						0x1000
+#define	OUT_CTRL1						0x1004
+#define	OUT_CTRL_NS						0x1008
+#define	GEN_STAT						0x100C
+#define	INT_STAT_MASK					0x1010
+#define	LUMA_CTRL						0x1014
+#define	CHROMA_CTRL						0x1018
+#define	CRUSH_CTRL						0x101C
+#define	HORIZ_TIM_CTRL					0x1020
+#define	VERT_TIM_CTRL					0x1024
+#define	MISC_TIM_CTRL					0x1028
+#define	FIELD_COUNT						0x102C
+#define	HSCALE_CTRL						0x1030
+#define	VSCALE_CTRL						0x1034
+#define	MAN_VGA_CTRL					0x1038
+#define	MAN_AGC_CTRL					0x103C
+#define	DFE_CTRL1						0x1040
+#define	DFE_CTRL2						0x1044
+#define	DFE_CTRL3						0x1048
+#define	PLL_CTRL						0x104C
+#define	PLL_CTRL_FAST					0x1050
+#define	HTL_CTRL						0x1054
+#define	SRC_CFG							0x1058
+#define	SC_STEP_SIZE					0x105C
+#define	SC_CONVERGE_CTRL				0x1060
+#define	SC_LOOP_CTRL					0x1064
+#define	COMB_2D_HFS_CFG					0x1068
+#define	COMB_2D_HFD_CFG					0x106C
+#define	COMB_2D_LF_CFG					0x1070
+#define	COMB_2D_BLEND					0x1074
+#define	COMB_MISC_CTRL					0x1078
+#define	COMB_FLAT_THRESH_CTRL			0x107C
+#define	COMB_TEST						0x1080
+#define	BP_MISC_CTRL					0x1084
+#define	VCR_DET_CTRL					0x1088
+#define	NOISE_DET_CTRL					0x108C
+#define	COMB_FLAT_NOISE_CTRL			0x1090
+#define	VERSION							0x11F8
+#define	SOFT_RST_CTRL					0x11FC
+
+//      Video Decoder B Registers
+#define	VDEC_B_MODE_CTRL				0x1200
+#define	VDEC_B_OUT_CTRL1				0x1204
+#define	VDEC_B_OUT_CTRL_NS				0x1208
+#define	VDEC_B_GEN_STAT					0x120C
+#define	VDEC_B_INT_STAT_MASK			0x1210
+#define	VDEC_B_LUMA_CTRL				0x1214
+#define	VDEC_B_CHROMA_CTRL				0x1218
+#define	VDEC_B_CRUSH_CTRL				0x121C
+#define	VDEC_B_HORIZ_TIM_CTRL			0x1220
+#define	VDEC_B_VERT_TIM_CTRL			0x1224
+#define	VDEC_B_MISC_TIM_CTRL			0x1228
+#define	VDEC_B_FIELD_COUNT				0x122C
+#define	VDEC_B_HSCALE_CTRL				0x1230
+#define	VDEC_B_VSCALE_CTRL				0x1234
+#define	VDEC_B_MAN_VGA_CTRL				0x1238
+#define	VDEC_B_MAN_AGC_CTRL				0x123C
+#define	VDEC_B_DFE_CTRL1				0x1240
+#define	VDEC_B_DFE_CTRL2				0x1244
+#define	VDEC_B_DFE_CTRL3				0x1248
+#define	VDEC_B_PLL_CTRL					0x124C
+#define	VDEC_B_PLL_CTRL_FAST			0x1250
+#define	VDEC_B_HTL_CTRL					0x1254
+#define	VDEC_B_SRC_CFG					0x1258
+#define	VDEC_B_SC_STEP_SIZE				0x125C
+#define	VDEC_B_SC_CONVERGE_CTRL			0x1260
+#define	VDEC_B_SC_LOOP_CTRL				0x1264
+#define	VDEC_B_COMB_2D_HFS_CFG			0x1268
+#define	VDEC_B_COMB_2D_HFD_CFG			0x126C
+#define	VDEC_B_COMB_2D_LF_CFG			0x1270
+#define	VDEC_B_COMB_2D_BLEND			0x1274
+#define	VDEC_B_COMB_MISC_CTRL			0x1278
+#define	VDEC_B_COMB_FLAT_THRESH_CTRL	0x127C
+#define	VDEC_B_COMB_TEST				0x1280
+#define	VDEC_B_BP_MISC_CTRL				0x1284
+#define	VDEC_B_VCR_DET_CTRL				0x1288
+#define	VDEC_B_NOISE_DET_CTRL			0x128C
+#define	VDEC_B_COMB_FLAT_NOISE_CTRL		0x1290
+#define	VDEC_B_VERSION					0x13F8
+#define	VDEC_B_SOFT_RST_CTRL			0x13FC
+
+// Video Decoder C Registers
+#define	VDEC_C_MODE_CTRL				0x1400
+#define	VDEC_C_OUT_CTRL1				0x1404
+#define	VDEC_C_OUT_CTRL_NS				0x1408
+#define	VDEC_C_GEN_STAT					0x140C
+#define	VDEC_C_INT_STAT_MASK			0x1410
+#define VDEC_C_LUMA_CTRL				0x1414
+#define VDEC_C_CHROMA_CTRL				0x1418
+#define	VDEC_C_CRUSH_CTRL				0x141C
+#define	VDEC_C_HORIZ_TIM_CTRL			0x1420
+#define	VDEC_C_VERT_TIM_CTRL			0x1424
+#define	VDEC_C_MISC_TIM_CTRL			0x1428
+#define	VDEC_C_FIELD_COUNT				0x142C
+#define	VDEC_C_HSCALE_CTRL				0x1430
+#define	VDEC_C_VSCALE_CTRL				0x1434
+#define	VDEC_C_MAN_VGA_CTRL				0x1438
+#define	VDEC_C_MAN_AGC_CTRL				0x143C
+#define	VDEC_C_DFE_CTRL1				0x1440
+#define	VDEC_C_DFE_CTRL2				0x1444
+#define	VDEC_C_DFE_CTRL3				0x1448
+#define	VDEC_C_PLL_CTRL					0x144C
+#define	VDEC_C_PLL_CTRL_FAST			0x1450
+#define	VDEC_C_HTL_CTRL					0x1454
+#define	VDEC_C_SRC_CFG					0x1458
+#define	VDEC_C_SC_STEP_SIZE				0x145C
+#define	VDEC_C_SC_CONVERGE_CTRL			0x1460
+#define	VDEC_C_SC_LOOP_CTRL				0x1464
+#define	VDEC_C_COMB_2D_HFS_CFG			0x1468
+#define	VDEC_C_COMB_2D_HFD_CFG			0x146C
+#define	VDEC_C_COMB_2D_LF_CFG			0x1470
+#define	VDEC_C_COMB_2D_BLEND			0x1474
+#define	VDEC_C_COMB_MISC_CTRL			0x1478
+#define	VDEC_C_COMB_FLAT_THRESH_CTRL	0x147C
+#define	VDEC_C_COMB_TEST				0x1480
+#define	VDEC_C_BP_MISC_CTRL				0x1484
+#define	VDEC_C_VCR_DET_CTRL				0x1488
+#define	VDEC_C_NOISE_DET_CTRL			0x148C
+#define	VDEC_C_COMB_FLAT_NOISE_CTRL		0x1490
+#define	VDEC_C_VERSION					0x15F8
+#define	VDEC_C_SOFT_RST_CTRL			0x15FC
+
+// Video Decoder D Registers
+#define VDEC_D_MODE_CTRL				0x1600
+#define VDEC_D_OUT_CTRL1				0x1604
+#define VDEC_D_OUT_CTRL_NS				0x1608
+#define VDEC_D_GEN_STAT					0x160C
+#define VDEC_D_INT_STAT_MASK			0x1610
+#define VDEC_D_LUMA_CTRL				0x1614
+#define VDEC_D_CHROMA_CTRL				0x1618
+#define VDEC_D_CRUSH_CTRL				0x161C
+#define VDEC_D_HORIZ_TIM_CTRL			0x1620
+#define VDEC_D_VERT_TIM_CTRL			0x1624
+#define VDEC_D_MISC_TIM_CTRL			0x1628
+#define VDEC_D_FIELD_COUNT				0x162C
+#define VDEC_D_HSCALE_CTRL				0x1630
+#define VDEC_D_VSCALE_CTRL				0x1634
+#define VDEC_D_MAN_VGA_CTRL				0x1638
+#define VDEC_D_MAN_AGC_CTRL				0x163C
+#define VDEC_D_DFE_CTRL1				0x1640
+#define VDEC_D_DFE_CTRL2				0x1644
+#define VDEC_D_DFE_CTRL3				0x1648
+#define VDEC_D_PLL_CTRL					0x164C
+#define VDEC_D_PLL_CTRL_FAST			0x1650
+#define VDEC_D_HTL_CTRL					0x1654
+#define VDEC_D_SRC_CFG					0x1658
+#define VDEC_D_SC_STEP_SIZE				0x165C
+#define VDEC_D_SC_CONVERGE_CTRL			0x1660
+#define VDEC_D_SC_LOOP_CTRL				0x1664
+#define VDEC_D_COMB_2D_HFS_CFG			0x1668
+#define VDEC_D_COMB_2D_HFD_CFG			0x166C
+#define VDEC_D_COMB_2D_LF_CFG			0x1670
+#define VDEC_D_COMB_2D_BLEND			0x1674
+#define VDEC_D_COMB_MISC_CTRL			0x1678
+#define VDEC_D_COMB_FLAT_THRESH_CTRL	0x167C
+#define VDEC_D_COMB_TEST				0x1680
+#define VDEC_D_BP_MISC_CTRL				0x1684
+#define VDEC_D_VCR_DET_CTRL				0x1688
+#define VDEC_D_NOISE_DET_CTRL			0x168C
+#define VDEC_D_COMB_FLAT_NOISE_CTRL		0x1690
+#define VDEC_D_VERSION					0x17F8
+#define VDEC_D_SOFT_RST_CTRL			0x17FC
+
+// Video Decoder E Registers
+#define	VDEC_E_MODE_CTRL				0x1800
+#define	VDEC_E_OUT_CTRL1				0x1804
+#define	VDEC_E_OUT_CTRL_NS				0x1808
+#define	VDEC_E_GEN_STAT					0x180C
+#define	VDEC_E_INT_STAT_MASK			0x1810
+#define	VDEC_E_LUMA_CTRL				0x1814
+#define	VDEC_E_CHROMA_CTRL				0x1818
+#define	VDEC_E_CRUSH_CTRL				0x181C
+#define	VDEC_E_HORIZ_TIM_CTRL			0x1820
+#define	VDEC_E_VERT_TIM_CTRL			0x1824
+#define	VDEC_E_MISC_TIM_CTRL			0x1828
+#define	VDEC_E_FIELD_COUNT				0x182C
+#define	VDEC_E_HSCALE_CTRL				0x1830
+#define	VDEC_E_VSCALE_CTRL				0x1834
+#define	VDEC_E_MAN_VGA_CTRL				0x1838
+#define	VDEC_E_MAN_AGC_CTRL				0x183C
+#define	VDEC_E_DFE_CTRL1				0x1840
+#define	VDEC_E_DFE_CTRL2				0x1844
+#define	VDEC_E_DFE_CTRL3				0x1848
+#define	VDEC_E_PLL_CTRL					0x184C
+#define	VDEC_E_PLL_CTRL_FAST			0x1850
+#define	VDEC_E_HTL_CTRL					0x1854
+#define	VDEC_E_SRC_CFG					0x1858
+#define	VDEC_E_SC_STEP_SIZE				0x185C
+#define	VDEC_E_SC_CONVERGE_CTRL			0x1860
+#define	VDEC_E_SC_LOOP_CTRL				0x1864
+#define	VDEC_E_COMB_2D_HFS_CFG			0x1868
+#define	VDEC_E_COMB_2D_HFD_CFG			0x186C
+#define	VDEC_E_COMB_2D_LF_CFG			0x1870
+#define	VDEC_E_COMB_2D_BLEND			0x1874
+#define	VDEC_E_COMB_MISC_CTRL			0x1878
+#define	VDEC_E_COMB_FLAT_THRESH_CTRL	0x187C
+#define	VDEC_E_COMB_TEST				0x1880
+#define	VDEC_E_BP_MISC_CTRL				0x1884
+#define	VDEC_E_VCR_DET_CTRL				0x1888
+#define	VDEC_E_NOISE_DET_CTRL			0x188C
+#define	VDEC_E_COMB_FLAT_NOISE_CTRL		0x1890
+#define	VDEC_E_VERSION					0x19F8
+#define	VDEC_E_SOFT_RST_CTRL			0x19FC
+
+// Video Decoder F Registers
+#define	VDEC_F_MODE_CTRL				0x1A00
+#define	VDEC_F_OUT_CTRL1				0x1A04
+#define	VDEC_F_OUT_CTRL_NS				0x1A08
+#define	VDEC_F_GEN_STAT					0x1A0C
+#define	VDEC_F_INT_STAT_MASK			0x1A10
+#define	VDEC_F_LUMA_CTRL				0x1A14
+#define	VDEC_F_CHROMA_CTRL				0x1A18
+#define	VDEC_F_CRUSH_CTRL				0x1A1C
+#define	VDEC_F_HORIZ_TIM_CTRL			0x1A20
+#define	VDEC_F_VERT_TIM_CTRL			0x1A24
+#define	VDEC_F_MISC_TIM_CTRL			0x1A28
+#define	VDEC_F_FIELD_COUNT				0x1A2C
+#define	VDEC_F_HSCALE_CTRL				0x1A30
+#define	VDEC_F_VSCALE_CTRL				0x1A34
+#define	VDEC_F_MAN_VGA_CTRL				0x1A38
+#define	VDEC_F_MAN_AGC_CTRL				0x1A3C
+#define	VDEC_F_DFE_CTRL1				0x1A40
+#define	VDEC_F_DFE_CTRL2				0x1A44
+#define	VDEC_F_DFE_CTRL3				0x1A48
+#define	VDEC_F_PLL_CTRL					0x1A4C
+#define	VDEC_F_PLL_CTRL_FAST			0x1A50
+#define	VDEC_F_HTL_CTRL					0x1A54
+#define	VDEC_F_SRC_CFG					0x1A58
+#define	VDEC_F_SC_STEP_SIZE				0x1A5C
+#define	VDEC_F_SC_CONVERGE_CTRL			0x1A60
+#define	VDEC_F_SC_LOOP_CTRL				0x1A64
+#define	VDEC_F_COMB_2D_HFS_CFG			0x1A68
+#define	VDEC_F_COMB_2D_HFD_CFG			0x1A6C
+#define	VDEC_F_COMB_2D_LF_CFG			0x1A70
+#define	VDEC_F_COMB_2D_BLEND			0x1A74
+#define	VDEC_F_COMB_MISC_CTRL			0x1A78
+#define	VDEC_F_COMB_FLAT_THRESH_CTRL	0x1A7C
+#define	VDEC_F_COMB_TEST				0x1A80
+#define	VDEC_F_BP_MISC_CTRL				0x1A84
+#define	VDEC_F_VCR_DET_CTRL				0x1A88
+#define	VDEC_F_NOISE_DET_CTRL			0x1A8C
+#define	VDEC_F_COMB_FLAT_NOISE_CTRL		0x1A90
+#define	VDEC_F_VERSION					0x1BF8
+#define	VDEC_F_SOFT_RST_CTRL			0x1BFC
+
+// Video Decoder G Registers
+#define	VDEC_G_MODE_CTRL				0x1C00
+#define	VDEC_G_OUT_CTRL1				0x1C04
+#define	VDEC_G_OUT_CTRL_NS				0x1C08
+#define	VDEC_G_GEN_STAT					0x1C0C
+#define	VDEC_G_INT_STAT_MASK			0x1C10
+#define	VDEC_G_LUMA_CTRL				0x1C14
+#define	VDEC_G_CHROMA_CTRL				0x1C18
+#define	VDEC_G_CRUSH_CTRL				0x1C1C
+#define	VDEC_G_HORIZ_TIM_CTRL			0x1C20
+#define	VDEC_G_VERT_TIM_CTRL			0x1C24
+#define	VDEC_G_MISC_TIM_CTRL			0x1C28
+#define	VDEC_G_FIELD_COUNT				0x1C2C
+#define	VDEC_G_HSCALE_CTRL				0x1C30
+#define	VDEC_G_VSCALE_CTRL				0x1C34
+#define	VDEC_G_MAN_VGA_CTRL				0x1C38
+#define	VDEC_G_MAN_AGC_CTRL				0x1C3C
+#define	VDEC_G_DFE_CTRL1				0x1C40
+#define	VDEC_G_DFE_CTRL2				0x1C44
+#define	VDEC_G_DFE_CTRL3				0x1C48
+#define	VDEC_G_PLL_CTRL					0x1C4C
+#define	VDEC_G_PLL_CTRL_FAST			0x1C50
+#define	VDEC_G_HTL_CTRL					0x1C54
+#define	VDEC_G_SRC_CFG					0x1C58
+#define	VDEC_G_SC_STEP_SIZE				0x1C5C
+#define	VDEC_G_SC_CONVERGE_CTRL			0x1C60
+#define	VDEC_G_SC_LOOP_CTRL				0x1C64
+#define	VDEC_G_COMB_2D_HFS_CFG			0x1C68
+#define	VDEC_G_COMB_2D_HFD_CFG			0x1C6C
+#define	VDEC_G_COMB_2D_LF_CFG			0x1C70
+#define	VDEC_G_COMB_2D_BLEND			0x1C74
+#define	VDEC_G_COMB_MISC_CTRL			0x1C78
+#define	VDEC_G_COMB_FLAT_THRESH_CTRL	0x1C7C
+#define	VDEC_G_COMB_TEST				0x1C80
+#define	VDEC_G_BP_MISC_CTRL				0x1C84
+#define	VDEC_G_VCR_DET_CTRL				0x1C88
+#define	VDEC_G_NOISE_DET_CTRL			0x1C8C
+#define	VDEC_G_COMB_FLAT_NOISE_CTRL		0x1C90
+#define	VDEC_G_VERSION					0x1DF8
+#define	VDEC_G_SOFT_RST_CTRL			0x1DFC
+
+//              Video Decoder H Registers
+#define	VDEC_H_MODE_CTRL				0x1E00
+#define	VDEC_H_OUT_CTRL1				0x1E04
+#define	VDEC_H_OUT_CTRL_NS				0x1E08
+#define	VDEC_H_GEN_STAT					0x1E0C
+#define	VDEC_H_INT_STAT_MASK			0x1E1E
+#define	VDEC_H_LUMA_CTRL				0x1E14
+#define	VDEC_H_CHROMA_CTRL				0x1E18
+#define	VDEC_H_CRUSH_CTRL				0x1E1C
+#define	VDEC_H_HORIZ_TIM_CTRL			0x1E20
+#define	VDEC_H_VERT_TIM_CTRL			0x1E24
+#define	VDEC_H_MISC_TIM_CTRL			0x1E28
+#define	VDEC_H_FIELD_COUNT				0x1E2C
+#define	VDEC_H_HSCALE_CTRL				0x1E30
+#define	VDEC_H_VSCALE_CTRL				0x1E34
+#define	VDEC_H_MAN_VGA_CTRL				0x1E38
+#define	VDEC_H_MAN_AGC_CTRL				0x1E3C
+#define	VDEC_H_DFE_CTRL1				0x1E40
+#define	VDEC_H_DFE_CTRL2				0x1E44
+#define	VDEC_H_DFE_CTRL3				0x1E48
+#define	VDEC_H_PLL_CTRL					0x1E4C
+#define	VDEC_H_PLL_CTRL_FAST			0x1E50
+#define	VDEC_H_HTL_CTRL					0x1E54
+#define	VDEC_H_SRC_CFG					0x1E58
+#define	VDEC_H_SC_STEP_SIZE				0x1E5C
+#define	VDEC_H_SC_CONVERGE_CTRL			0x1E60
+#define	VDEC_H_SC_LOOP_CTRL				0x1E64
+#define	VDEC_H_COMB_2D_HFS_CFG			0x1E68
+#define	VDEC_H_COMB_2D_HFD_CFG			0x1E6C
+#define	VDEC_H_COMB_2D_LF_CFG			0x1E70
+#define	VDEC_H_COMB_2D_BLEND			0x1E74
+#define	VDEC_H_COMB_MISC_CTRL			0x1E78
+#define	VDEC_H_COMB_FLAT_THRESH_CTRL	0x1E7C
+#define	VDEC_H_COMB_TEST				0x1E80
+#define	VDEC_H_BP_MISC_CTRL				0x1E84
+#define	VDEC_H_VCR_DET_CTRL				0x1E88
+#define	VDEC_H_NOISE_DET_CTRL			0x1E8C
+#define	VDEC_H_COMB_FLAT_NOISE_CTRL		0x1E90
+#define	VDEC_H_VERSION					0x1FF8
+#define	VDEC_H_SOFT_RST_CTRL			0x1FFC
+
+//*****************************************************************************
+// LUMA_CTRL register fields
+#define VDEC_A_BRITE_CTRL				0x1014
+#define VDEC_A_CNTRST_CTRL       		0x1015
+#define VDEC_A_PEAK_SEL          		0x1016
+
+//*****************************************************************************
+// CHROMA_CTRL register fields
+#define VDEC_A_USAT_CTRL         		0x1018
+#define VDEC_A_VSAT_CTRL         		0x1019
+#define VDEC_A_HUE_CTRL          		0x101A
+
+#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
new file mode 100644
index 0000000..e4df813
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -0,0 +1,869 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#include "cx25821.h"
+#include "cx25821-medusa-video.h"
+#include "cx25821-biffuncs.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//medusa_enable_bluefield_output()
+//
+// Enable the generation of blue filed output if no video
+//
+static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
+					   int enable)
+{
+	int ret_val = 1;
+	u32 value = 0;
+	u32 tmp = 0;
+	int out_ctrl = OUT_CTRL1;
+	int out_ctrl_ns = OUT_CTRL_NS;
+
+	switch (channel) {
+	default:
+	case VDEC_A:
+		break;
+	case VDEC_B:
+		out_ctrl = VDEC_B_OUT_CTRL1;
+		out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
+		break;
+	case VDEC_C:
+		out_ctrl = VDEC_C_OUT_CTRL1;
+		out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
+		break;
+	case VDEC_D:
+		out_ctrl = VDEC_D_OUT_CTRL1;
+		out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
+		break;
+	case VDEC_E:
+		out_ctrl = VDEC_E_OUT_CTRL1;
+		out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
+		return;
+	case VDEC_F:
+		out_ctrl = VDEC_F_OUT_CTRL1;
+		out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
+		return;
+	case VDEC_G:
+		out_ctrl = VDEC_G_OUT_CTRL1;
+		out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
+		return;
+	case VDEC_H:
+		out_ctrl = VDEC_H_OUT_CTRL1;
+		out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
+		return;
+	}
+
+	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
+	value &= 0xFFFFFF7F;	// clear BLUE_FIELD_EN
+	if (enable)
+		value |= 0x00000080;	// set BLUE_FIELD_EN
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
+
+	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
+	value &= 0xFFFFFF7F;
+	if (enable)
+		value |= 0x00000080;	// set BLUE_FIELD_EN
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
+}
+
+static int medusa_initialize_ntsc(struct cx25821_dev *dev)
+{
+	int ret_val = 0;
+	int i = 0;
+	u32 value = 0;
+	u32 tmp = 0;
+
+	mutex_lock(&dev->lock);
+
+	for (i = 0; i < MAX_DECODERS; i++) {
+		// set video format NTSC-M
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
+				     &tmp);
+		value &= 0xFFFFFFF0;
+		value |= 0x10001;	// enable the fast locking mode bit[16]
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
+				      value);
+
+		// resolution NTSC 720x480
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     HORIZ_TIM_CTRL + (0x200 * i), &tmp);
+		value &= 0x00C00C00;
+		value |= 0x612D0074;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      HORIZ_TIM_CTRL + (0x200 * i), value);
+
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     VERT_TIM_CTRL + (0x200 * i), &tmp);
+		value &= 0x00C00C00;
+		value |= 0x1C1E001A;	// vblank_cnt + 2 to get camera ID
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      VERT_TIM_CTRL + (0x200 * i), value);
+
+		// chroma subcarrier step size
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      SC_STEP_SIZE + (0x200 * i), 0x43E00000);
+
+		// enable VIP optional active
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     OUT_CTRL_NS + (0x200 * i), &tmp);
+		value &= 0xFFFBFFFF;
+		value |= 0x00040000;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      OUT_CTRL_NS + (0x200 * i), value);
+
+		// enable VIP optional active (VIP_OPT_AL) for direct output.
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
+				     &tmp);
+		value &= 0xFFFBFFFF;
+		value |= 0x00040000;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
+				      value);
+
+		// clear VPRES_VERT_EN bit, fixes the chroma run away problem
+		// when the input switching rate < 16 fields
+		//
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     MISC_TIM_CTRL + (0x200 * i), &tmp);
+		value = setBitAtPos(value, 14);	// disable special play detection
+		value = clearBitAtPos(value, 15);
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      MISC_TIM_CTRL + (0x200 * i), value);
+
+		// set vbi_gate_en to 0
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
+				     &tmp);
+		value = clearBitAtPos(value, 29);
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
+				      value);
+
+		// Enable the generation of blue field output if no video
+		medusa_enable_bluefield_output(dev, i, 1);
+	}
+
+	for (i = 0; i < MAX_ENCODERS; i++) {
+		// NTSC hclock
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_1 + (0x100 * i), &tmp);
+		value &= 0xF000FC00;
+		value |= 0x06B402D0;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_1 + (0x100 * i), value);
+
+		// burst begin and burst end
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_2 + (0x100 * i), &tmp);
+		value &= 0xFF000000;
+		value |= 0x007E9054;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_2 + (0x100 * i), value);
+
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_3 + (0x100 * i), &tmp);
+		value &= 0xFC00FE00;
+		value |= 0x00EC00F0;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_3 + (0x100 * i), value);
+
+		// set NTSC vblank, no phase alternation, 7.5 IRE pedestal
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_4 + (0x100 * i), &tmp);
+		value &= 0x00FCFFFF;
+		value |= 0x13020000;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_4 + (0x100 * i), value);
+
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_5 + (0x100 * i), &tmp);
+		value &= 0xFFFF0000;
+		value |= 0x0000E575;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_5 + (0x100 * i), value);
+
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
+
+		// Subcarrier Increment
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
+	}
+
+	//set picture resolutions
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);	//0 - 720
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);	//0 - 480
+
+	// set Bypass input format to NTSC 525 lines
+	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
+	value |= 0x00080200;
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
+
+	mutex_unlock(&dev->lock);
+
+	return ret_val;
+}
+
+static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
+{
+	int ret_val = -1;
+	u32 value = 0, tmp = 0;
+
+	// Setup for 2D threshold
+	ret_val =
+	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec),
+			      0x20002861);
+	ret_val =
+	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec),
+			      0x20002861);
+	ret_val =
+	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec),
+			      0x200A1023);
+
+	// Setup flat chroma and luma thresholds
+	value =
+	    cx25821_i2c_read(&dev->i2c_bus[0],
+			     COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
+	value &= 0x06230000;
+	ret_val =
+	    cx25821_i2c_write(&dev->i2c_bus[0],
+			      COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
+
+	// set comb 2D blend
+	ret_val =
+	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec),
+			      0x210F0F0F);
+
+	// COMB MISC CONTROL
+	ret_val =
+	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec),
+			      0x41120A7F);
+
+	return ret_val;
+}
+
+static int medusa_initialize_pal(struct cx25821_dev *dev)
+{
+	int ret_val = 0;
+	int i = 0;
+	u32 value = 0;
+	u32 tmp = 0;
+
+	mutex_lock(&dev->lock);
+
+	for (i = 0; i < MAX_DECODERS; i++) {
+		// set video format PAL-BDGHI
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
+				     &tmp);
+		value &= 0xFFFFFFF0;
+		value |= 0x10004;	// enable the fast locking mode bit[16]
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
+				      value);
+
+		// resolution PAL 720x576
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     HORIZ_TIM_CTRL + (0x200 * i), &tmp);
+		value &= 0x00C00C00;
+		value |= 0x632D007D;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      HORIZ_TIM_CTRL + (0x200 * i), value);
+
+		// vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     VERT_TIM_CTRL + (0x200 * i), &tmp);
+		value &= 0x00C00C00;
+		value |= 0x28240026;	// vblank_cnt + 2 to get camera ID
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      VERT_TIM_CTRL + (0x200 * i), value);
+
+		// chroma subcarrier step size
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
+
+		// enable VIP optional active
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     OUT_CTRL_NS + (0x200 * i), &tmp);
+		value &= 0xFFFBFFFF;
+		value |= 0x00040000;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      OUT_CTRL_NS + (0x200 * i), value);
+
+		// enable VIP optional active (VIP_OPT_AL) for direct output.
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
+				     &tmp);
+		value &= 0xFFFBFFFF;
+		value |= 0x00040000;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
+				      value);
+
+		// clear VPRES_VERT_EN bit, fixes the chroma run away problem
+		// when the input switching rate < 16 fields
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     MISC_TIM_CTRL + (0x200 * i), &tmp);
+		value = setBitAtPos(value, 14);	// disable special play detection
+		value = clearBitAtPos(value, 15);
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      MISC_TIM_CTRL + (0x200 * i), value);
+
+		// set vbi_gate_en to 0
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
+				     &tmp);
+		value = clearBitAtPos(value, 29);
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
+				      value);
+
+		medusa_PALCombInit(dev, i);
+
+		// Enable the generation of blue field output if no video
+		medusa_enable_bluefield_output(dev, i, 1);
+	}
+
+	for (i = 0; i < MAX_ENCODERS; i++) {
+		// PAL hclock
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_1 + (0x100 * i), &tmp);
+		value &= 0xF000FC00;
+		value |= 0x06C002D0;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_1 + (0x100 * i), value);
+
+		// burst begin and burst end
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_2 + (0x100 * i), &tmp);
+		value &= 0xFF000000;
+		value |= 0x007E9754;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_2 + (0x100 * i), value);
+
+		// hblank and vactive
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_3 + (0x100 * i), &tmp);
+		value &= 0xFC00FE00;
+		value |= 0x00FC0120;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_3 + (0x100 * i), value);
+
+		// set PAL vblank, phase alternation, 0 IRE pedestal
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_4 + (0x100 * i), &tmp);
+		value &= 0x00FCFFFF;
+		value |= 0x14010000;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_4 + (0x100 * i), value);
+
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     DENC_A_REG_5 + (0x100 * i), &tmp);
+		value &= 0xFFFF0000;
+		value |= 0x0000F078;
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_5 + (0x100 * i), value);
+
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
+
+		// Subcarrier Increment
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
+	}
+
+	//set picture resolutions
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);	//0 - 720
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);	//0 - 576
+
+	// set Bypass input format to PAL 625 lines
+	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
+	value &= 0xFFF7FDFF;
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
+
+	mutex_unlock(&dev->lock);
+
+	return ret_val;
+}
+
+int medusa_set_videostandard(struct cx25821_dev *dev)
+{
+	int status = STATUS_SUCCESS;
+	u32 value = 0, tmp = 0;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) {
+		status = medusa_initialize_pal(dev);
+	} else {
+		status = medusa_initialize_ntsc(dev);
+	}
+
+	// Enable DENC_A output
+	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
+	value = setBitAtPos(value, 4);
+	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
+
+	// Enable DENC_B output
+	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
+	value = setBitAtPos(value, 4);
+	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
+
+	return status;
+}
+
+void medusa_set_resolution(struct cx25821_dev *dev, int width,
+			   int decoder_select)
+{
+	int decoder = 0;
+	int decoder_count = 0;
+	int ret_val = 0;
+	u32 hscale = 0x0;
+	u32 vscale = 0x0;
+	const int MAX_WIDTH = 720;
+
+	mutex_lock(&dev->lock);
+
+	// validate the width - cannot be negative
+	if (width > MAX_WIDTH) {
+		printk
+		    ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n",
+		     __func__, width, MAX_WIDTH);
+		width = MAX_WIDTH;
+	}
+
+	if (decoder_select <= 7 && decoder_select >= 0) {
+		decoder = decoder_select;
+		decoder_count = decoder_select + 1;
+	} else {
+		decoder = 0;
+		decoder_count = _num_decoders;
+	}
+
+	switch (width) {
+	case 320:
+		hscale = 0x13E34B;
+		vscale = 0x0;
+		break;
+
+	case 352:
+		hscale = 0x10A273;
+		vscale = 0x0;
+		break;
+
+	case 176:
+		hscale = 0x3115B2;
+		vscale = 0x1E00;
+		break;
+
+	case 160:
+		hscale = 0x378D84;
+		vscale = 0x1E00;
+		break;
+
+	default:		//720
+		hscale = 0x0;
+		vscale = 0x0;
+		break;
+	}
+
+	for (; decoder < decoder_count; decoder++) {
+		// write scaling values for each decoder
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      HSCALE_CTRL + (0x200 * decoder), hscale);
+		ret_val =
+		    cx25821_i2c_write(&dev->i2c_bus[0],
+				      VSCALE_CTRL + (0x200 * decoder), vscale);
+	}
+
+	mutex_unlock(&dev->lock);
+}
+
+static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
+				       int duration)
+{
+	int ret_val = 0;
+	u32 fld_cnt = 0;
+	u32 tmp = 0;
+	u32 disp_cnt_reg = DISP_AB_CNT;
+
+	mutex_lock(&dev->lock);
+
+	// no support
+	if (decoder < VDEC_A && decoder > VDEC_H) {
+		mutex_unlock(&dev->lock);
+		return;
+	}
+
+	switch (decoder) {
+	default:
+		break;
+	case VDEC_C:
+	case VDEC_D:
+		disp_cnt_reg = DISP_CD_CNT;
+		break;
+	case VDEC_E:
+	case VDEC_F:
+		disp_cnt_reg = DISP_EF_CNT;
+		break;
+	case VDEC_G:
+	case VDEC_H:
+		disp_cnt_reg = DISP_GH_CNT;
+		break;
+	}
+
+	_display_field_cnt[decoder] = duration;
+
+	// update hardware
+	fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
+
+	if (!(decoder % 2))	// EVEN decoder
+	{
+		fld_cnt &= 0xFFFF0000;
+		fld_cnt |= duration;
+	} else {
+		fld_cnt &= 0x0000FFFF;
+		fld_cnt |= ((u32) duration) << 16;
+	}
+
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
+
+	mutex_unlock(&dev->lock);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Map to Medusa register setting
+static int mapM(int srcMin,
+		int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal)
+{
+	int numerator;
+	int denominator;
+	int quotient;
+
+	if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax)) {
+		return -1;
+	}
+	// This is the overall expression used:
+	// *dstVal = (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
+	// but we need to account for rounding so below we use the modulus
+	// operator to find the remainder and increment if necessary.
+	numerator = (srcVal - srcMin) * (dstMax - dstMin);
+	denominator = srcMax - srcMin;
+	quotient = numerator / denominator;
+
+	if (2 * (numerator % denominator) >= denominator) {
+		quotient++;
+	}
+
+	*dstVal = quotient + dstMin;
+
+	return 0;
+}
+
+static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
+{
+	unsigned char temp;
+
+	if (numeric >= 0)
+		return numeric;
+	else {
+		temp = ~(abs(numeric) & 0xFF);
+		temp += 1;
+		return temp;
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
+{
+	int ret_val = 0;
+	int value = 0;
+	u32 val = 0, tmp = 0;
+
+	mutex_lock(&dev->lock);
+	if ((brightness > VIDEO_PROCAMP_MAX)
+	    || (brightness < VIDEO_PROCAMP_MIN)) {
+		mutex_unlock(&dev->lock);
+		return -1;
+	}
+	ret_val =
+	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
+		 SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
+	value = convert_to_twos(value, 8);
+	val =
+	    cx25821_i2c_read(&dev->i2c_bus[0],
+			     VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
+	val &= 0xFFFFFF00;
+	ret_val |=
+	    cx25821_i2c_write(&dev->i2c_bus[0],
+			      VDEC_A_BRITE_CTRL + (0x200 * decoder),
+			      val | value);
+	mutex_unlock(&dev->lock);
+	return ret_val;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
+{
+	int ret_val = 0;
+	int value = 0;
+	u32 val = 0, tmp = 0;
+
+	mutex_lock(&dev->lock);
+
+	if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
+		mutex_unlock(&dev->lock);
+		return -1;
+	}
+
+	ret_val =
+	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
+		 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
+	val =
+	    cx25821_i2c_read(&dev->i2c_bus[0],
+			     VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
+	val &= 0xFFFFFF00;
+	ret_val |=
+	    cx25821_i2c_write(&dev->i2c_bus[0],
+			      VDEC_A_CNTRST_CTRL + (0x200 * decoder),
+			      val | value);
+
+	mutex_unlock(&dev->lock);
+	return ret_val;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
+{
+	int ret_val = 0;
+	int value = 0;
+	u32 val = 0, tmp = 0;
+
+	mutex_lock(&dev->lock);
+
+	if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
+		mutex_unlock(&dev->lock);
+		return -1;
+	}
+
+	ret_val =
+	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN,
+		 SIGNED_BYTE_MAX, &value);
+
+	value = convert_to_twos(value, 8);
+	val =
+	    cx25821_i2c_read(&dev->i2c_bus[0],
+			     VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
+	val &= 0xFFFFFF00;
+
+	ret_val |=
+	    cx25821_i2c_write(&dev->i2c_bus[0],
+			      VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
+
+	mutex_unlock(&dev->lock);
+	return ret_val;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
+{
+	int ret_val = 0;
+	int value = 0;
+	u32 val = 0, tmp = 0;
+
+	mutex_lock(&dev->lock);
+
+	if ((saturation > VIDEO_PROCAMP_MAX)
+	    || (saturation < VIDEO_PROCAMP_MIN)) {
+		mutex_unlock(&dev->lock);
+		return -1;
+	}
+
+	ret_val =
+	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
+		 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
+
+	val =
+	    cx25821_i2c_read(&dev->i2c_bus[0],
+			     VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
+	val &= 0xFFFFFF00;
+	ret_val |=
+	    cx25821_i2c_write(&dev->i2c_bus[0],
+			      VDEC_A_USAT_CTRL + (0x200 * decoder),
+			      val | value);
+
+	val =
+	    cx25821_i2c_read(&dev->i2c_bus[0],
+			     VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
+	val &= 0xFFFFFF00;
+	ret_val |=
+	    cx25821_i2c_write(&dev->i2c_bus[0],
+			      VDEC_A_VSAT_CTRL + (0x200 * decoder),
+			      val | value);
+
+	mutex_unlock(&dev->lock);
+	return ret_val;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Program the display sequence and monitor output.
+//
+int medusa_video_init(struct cx25821_dev *dev)
+{
+	u32 value = 0, tmp = 0;
+	int ret_val = 0;
+	int i = 0;
+
+	mutex_lock(&dev->lock);
+
+	_num_decoders = dev->_max_num_decoders;
+
+	// disable Auto source selection on all video decoders
+	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
+	value &= 0xFFFFF0FF;
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
+
+	if (ret_val < 0) {
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+	// Turn off Master source switch enable
+	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
+	value &= 0xFFFFFFDF;
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
+
+	if (ret_val < 0) {
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&dev->lock);
+
+	for (i = 0; i < _num_decoders; i++) {
+		medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
+	}
+
+	mutex_lock(&dev->lock);
+
+	// Select monitor as DENC A input, power up the DAC
+	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
+	value &= 0xFF70FF70;
+	value |= 0x00090008;	// set en_active
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
+
+	if (ret_val < 0) {
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+	// enable input is VIP/656
+	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
+	value |= 0x00040100;	// enable VIP
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
+
+	if (ret_val < 0) {
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+	// select AFE clock to output mode
+	value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
+	value &= 0x83FFFFFF;
+	ret_val =
+	    cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
+			      value | 0x10000000);
+
+	if (ret_val < 0) {
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+	// Turn on all of the data out and control output pins.
+	value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
+	value &= 0xFEF0FE00;
+	if (_num_decoders == MAX_DECODERS) {
+		// Note: The octal board does not support control pins(bit16-19).
+		// These bits are ignored in the octal board.
+		value |= 0x010001F8;	// disable VDEC A-C port, default to Mobilygen Interface
+	} else {
+		value |= 0x010F0108;	// disable VDEC A-C port, default to Mobilygen Interface
+	}
+
+	value |= 7;
+	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
+	if (ret_val < 0) {
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&dev->lock);
+
+	ret_val = medusa_set_videostandard(dev);
+
+	if (ret_val < 0) {
+		mutex_unlock(&dev->lock);
+		return -EINVAL;
+	}
+
+	return 1;
+}
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/staging/cx25821/cx25821-medusa-video.h
new file mode 100644
index 0000000..2fab4b2
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.h
@@ -0,0 +1,49 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#ifndef _MEDUSA_VIDEO_H
+#define _MEDUSA_VIDEO_H
+
+#include "cx25821-medusa-defines.h"
+
+// Color control constants
+#define VIDEO_PROCAMP_MIN                 0
+#define VIDEO_PROCAMP_MAX                 10000
+#define UNSIGNED_BYTE_MIN                 0
+#define UNSIGNED_BYTE_MAX                 0xFF
+#define SIGNED_BYTE_MIN                   -128
+#define SIGNED_BYTE_MAX                   127
+
+// Default video color settings
+#define SHARPNESS_DEFAULT                 50
+#define SATURATION_DEFAULT              5000
+#define BRIGHTNESS_DEFAULT              6200
+#define CONTRAST_DEFAULT                5000
+#define HUE_DEFAULT                     5000
+
+unsigned short _num_decoders;
+unsigned short _num_cameras;
+
+unsigned int _video_standard;
+int _display_field_cnt[MAX_DECODERS];
+
+#endif
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/staging/cx25821/cx25821-reg.h
new file mode 100644
index 0000000..7241e7e
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-reg.h
@@ -0,0 +1,1592 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#ifndef __CX25821_REGISTERS__
+#define __CX25821_REGISTERS__
+
+/* Risc Instructions */
+#define RISC_CNT_INC	 0x00010000
+#define RISC_CNT_RESET	 0x00030000
+#define RISC_IRQ1		 0x01000000
+#define RISC_IRQ2		 0x02000000
+#define RISC_EOL		 0x04000000
+#define RISC_SOL		 0x08000000
+#define RISC_WRITE		 0x10000000
+#define RISC_SKIP		 0x20000000
+#define RISC_JUMP		 0x70000000
+#define RISC_SYNC		 0x80000000
+#define RISC_RESYNC		 0x80008000
+#define RISC_READ		 0x90000000
+#define RISC_WRITERM	 0xB0000000
+#define RISC_WRITECM	 0xC0000000
+#define RISC_WRITECR	 0xD0000000
+#define RISC_WRITEC		 0x50000000
+#define RISC_READC		 0xA0000000
+
+#define RISC_SYNC_ODD		 0x00000000
+#define RISC_SYNC_EVEN		 0x00000200
+#define RISC_SYNC_ODD_VBI	 0x00000006
+#define RISC_SYNC_EVEN_VBI	 0x00000207
+#define RISC_NOOP			 0xF0000000
+
+//*****************************************************************************
+// ASB SRAM
+//*****************************************************************************
+#define  TX_SRAM                   0x000000	// Transmit SRAM
+
+//*****************************************************************************
+#define  RX_RAM                    0x010000	// Receive SRAM
+
+//*****************************************************************************
+// Application Layer (AL)
+//*****************************************************************************
+#define  DEV_CNTRL2                0x040000	// Device control
+#define  FLD_RUN_RISC              0x00000020
+
+//*****************************************************************************
+#define  PCI_INT_MSK               0x040010	// PCI interrupt mask
+#define  PCI_INT_STAT              0x040014	// PCI interrupt status
+#define  PCI_INT_MSTAT             0x040018	// PCI interrupt masked status
+#define  FLD_HAMMERHEAD_INT        (1 << 27)
+#define  FLD_UART_INT              (1 << 26)
+#define  FLD_IRQN_INT              (1 << 25)
+#define  FLD_TM_INT                (1 << 28)
+#define  FLD_I2C_3_RACK            (1 << 27)
+#define  FLD_I2C_3_INT             (1 << 26)
+#define  FLD_I2C_2_RACK            (1 << 25)
+#define  FLD_I2C_2_INT             (1 << 24)
+#define  FLD_I2C_1_RACK            (1 << 23)
+#define  FLD_I2C_1_INT             (1 << 22)
+
+#define  FLD_APB_DMA_BERR_INT      (1 << 21)
+#define  FLD_AL_WR_BERR_INT        (1 << 20)
+#define  FLD_AL_RD_BERR_INT        (1 << 19)
+#define  FLD_RISC_WR_BERR_INT      (1 << 18)
+#define  FLD_RISC_RD_BERR_INT      (1 << 17)
+
+#define  FLD_VID_I_INT             (1 << 8)
+#define  FLD_VID_H_INT             (1 << 7)
+#define  FLD_VID_G_INT             (1 << 6)
+#define  FLD_VID_F_INT             (1 << 5)
+#define  FLD_VID_E_INT             (1 << 4)
+#define  FLD_VID_D_INT             (1 << 3)
+#define  FLD_VID_C_INT             (1 << 2)
+#define  FLD_VID_B_INT             (1 << 1)
+#define  FLD_VID_A_INT             (1 << 0)
+
+//*****************************************************************************
+#define  VID_A_INT_MSK             0x040020	// Video A interrupt mask
+#define  VID_A_INT_STAT            0x040024	// Video A interrupt status
+#define  VID_A_INT_MSTAT           0x040028	// Video A interrupt masked status
+#define  VID_A_INT_SSTAT           0x04002C	// Video A interrupt set status
+
+//*****************************************************************************
+#define  VID_B_INT_MSK             0x040030	// Video B interrupt mask
+#define  VID_B_INT_STAT            0x040034	// Video B interrupt status
+#define  VID_B_INT_MSTAT           0x040038	// Video B interrupt masked status
+#define  VID_B_INT_SSTAT           0x04003C	// Video B interrupt set status
+
+//*****************************************************************************
+#define  VID_C_INT_MSK             0x040040	// Video C interrupt mask
+#define  VID_C_INT_STAT            0x040044	// Video C interrupt status
+#define  VID_C_INT_MSTAT           0x040048	// Video C interrupt masked status
+#define  VID_C_INT_SSTAT           0x04004C	// Video C interrupt set status
+
+//*****************************************************************************
+#define  VID_D_INT_MSK             0x040050	// Video D interrupt mask
+#define  VID_D_INT_STAT            0x040054	// Video D interrupt status
+#define  VID_D_INT_MSTAT           0x040058	// Video D interrupt masked status
+#define  VID_D_INT_SSTAT           0x04005C	// Video D interrupt set status
+
+//*****************************************************************************
+#define  VID_E_INT_MSK             0x040060	// Video E interrupt mask
+#define  VID_E_INT_STAT            0x040064	// Video E interrupt status
+#define  VID_E_INT_MSTAT           0x040068	// Video E interrupt masked status
+#define  VID_E_INT_SSTAT           0x04006C	// Video E interrupt set status
+
+//*****************************************************************************
+#define  VID_F_INT_MSK             0x040070	// Video F interrupt mask
+#define  VID_F_INT_STAT            0x040074	// Video F interrupt status
+#define  VID_F_INT_MSTAT           0x040078	// Video F interrupt masked status
+#define  VID_F_INT_SSTAT           0x04007C	// Video F interrupt set status
+
+//*****************************************************************************
+#define  VID_G_INT_MSK             0x040080	// Video G interrupt mask
+#define  VID_G_INT_STAT            0x040084	// Video G interrupt status
+#define  VID_G_INT_MSTAT           0x040088	// Video G interrupt masked status
+#define  VID_G_INT_SSTAT           0x04008C	// Video G interrupt set status
+
+//*****************************************************************************
+#define  VID_H_INT_MSK             0x040090	// Video H interrupt mask
+#define  VID_H_INT_STAT            0x040094	// Video H interrupt status
+#define  VID_H_INT_MSTAT           0x040098	// Video H interrupt masked status
+#define  VID_H_INT_SSTAT           0x04009C	// Video H interrupt set status
+
+//*****************************************************************************
+#define  VID_I_INT_MSK             0x0400A0	// Video I interrupt mask
+#define  VID_I_INT_STAT            0x0400A4	// Video I interrupt status
+#define  VID_I_INT_MSTAT           0x0400A8	// Video I interrupt masked status
+#define  VID_I_INT_SSTAT           0x0400AC	// Video I interrupt set status
+
+//*****************************************************************************
+#define  VID_J_INT_MSK             0x0400B0	// Video J interrupt mask
+#define  VID_J_INT_STAT            0x0400B4	// Video J interrupt status
+#define  VID_J_INT_MSTAT           0x0400B8	// Video J interrupt masked status
+#define  VID_J_INT_SSTAT           0x0400BC	// Video J interrupt set status
+
+#define  FLD_VID_SRC_OPC_ERR       0x00020000
+#define  FLD_VID_DST_OPC_ERR       0x00010000
+#define  FLD_VID_SRC_SYNC          0x00002000
+#define  FLD_VID_DST_SYNC          0x00001000
+#define  FLD_VID_SRC_UF            0x00000200
+#define  FLD_VID_DST_OF            0x00000100
+#define  FLD_VID_SRC_RISC2         0x00000020
+#define  FLD_VID_DST_RISC2         0x00000010
+#define  FLD_VID_SRC_RISC1         0x00000002
+#define  FLD_VID_DST_RISC1         0x00000001
+#define  FLD_VID_SRC_ERRORS		FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF
+#define  FLD_VID_DST_ERRORS		FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF
+
+//*****************************************************************************
+#define  AUD_A_INT_MSK             0x0400C0	// Audio Int interrupt mask
+#define  AUD_A_INT_STAT            0x0400C4	// Audio Int interrupt status
+#define  AUD_A_INT_MSTAT           0x0400C8	// Audio Int interrupt masked status
+#define  AUD_A_INT_SSTAT           0x0400CC	// Audio Int interrupt set status
+
+//*****************************************************************************
+#define  AUD_B_INT_MSK             0x0400D0	// Audio Int interrupt mask
+#define  AUD_B_INT_STAT            0x0400D4	// Audio Int interrupt status
+#define  AUD_B_INT_MSTAT           0x0400D8	// Audio Int interrupt masked status
+#define  AUD_B_INT_SSTAT           0x0400DC	// Audio Int interrupt set status
+
+//*****************************************************************************
+#define  AUD_C_INT_MSK             0x0400E0	// Audio Int interrupt mask
+#define  AUD_C_INT_STAT            0x0400E4	// Audio Int interrupt status
+#define  AUD_C_INT_MSTAT           0x0400E8	// Audio Int interrupt masked status
+#define  AUD_C_INT_SSTAT           0x0400EC	// Audio Int interrupt set status
+
+//*****************************************************************************
+#define  AUD_D_INT_MSK             0x0400F0	// Audio Int interrupt mask
+#define  AUD_D_INT_STAT            0x0400F4	// Audio Int interrupt status
+#define  AUD_D_INT_MSTAT           0x0400F8	// Audio Int interrupt masked status
+#define  AUD_D_INT_SSTAT           0x0400FC	// Audio Int interrupt set status
+
+//*****************************************************************************
+#define  AUD_E_INT_MSK             0x040100	// Audio Int interrupt mask
+#define  AUD_E_INT_STAT            0x040104	// Audio Int interrupt status
+#define  AUD_E_INT_MSTAT           0x040108	// Audio Int interrupt masked status
+#define  AUD_E_INT_SSTAT           0x04010C	// Audio Int interrupt set status
+
+#define  FLD_AUD_SRC_OPC_ERR       0x00020000
+#define  FLD_AUD_DST_OPC_ERR       0x00010000
+#define  FLD_AUD_SRC_SYNC          0x00002000
+#define  FLD_AUD_DST_SYNC          0x00001000
+#define  FLD_AUD_SRC_OF            0x00000200
+#define  FLD_AUD_DST_OF            0x00000100
+#define  FLD_AUD_SRC_RISCI2        0x00000020
+#define  FLD_AUD_DST_RISCI2        0x00000010
+#define  FLD_AUD_SRC_RISCI1        0x00000002
+#define  FLD_AUD_DST_RISCI1        0x00000001
+
+//*****************************************************************************
+#define  MBIF_A_INT_MSK             0x040110	// MBIF Int interrupt mask
+#define  MBIF_A_INT_STAT            0x040114	// MBIF Int interrupt status
+#define  MBIF_A_INT_MSTAT           0x040118	// MBIF Int interrupt masked status
+#define  MBIF_A_INT_SSTAT           0x04011C	// MBIF Int interrupt set status
+
+//*****************************************************************************
+#define  MBIF_B_INT_MSK             0x040120	// MBIF Int interrupt mask
+#define  MBIF_B_INT_STAT            0x040124	// MBIF Int interrupt status
+#define  MBIF_B_INT_MSTAT           0x040128	// MBIF Int interrupt masked status
+#define  MBIF_B_INT_SSTAT           0x04012C	// MBIF Int interrupt set status
+
+#define  FLD_MBIF_DST_OPC_ERR       0x00010000
+#define  FLD_MBIF_DST_SYNC          0x00001000
+#define  FLD_MBIF_DST_OF            0x00000100
+#define  FLD_MBIF_DST_RISCI2        0x00000010
+#define  FLD_MBIF_DST_RISCI1        0x00000001
+
+//*****************************************************************************
+#define  AUD_EXT_INT_MSK           0x040060	// Audio Ext interrupt mask
+#define  AUD_EXT_INT_STAT          0x040064	// Audio Ext interrupt status
+#define  AUD_EXT_INT_MSTAT         0x040068	// Audio Ext interrupt masked status
+#define  AUD_EXT_INT_SSTAT         0x04006C	// Audio Ext interrupt set status
+#define  FLD_AUD_EXT_OPC_ERR       0x00010000
+#define  FLD_AUD_EXT_SYNC          0x00001000
+#define  FLD_AUD_EXT_OF            0x00000100
+#define  FLD_AUD_EXT_RISCI2        0x00000010
+#define  FLD_AUD_EXT_RISCI1        0x00000001
+
+//*****************************************************************************
+#define  GPIO_LO                   0x110010	// Lower  of GPIO pins [31:0]
+#define  GPIO_HI                   0x110014	// Upper WORD  of GPIO pins [47:31]
+
+#define  GPIO_LO_OE                0x110018	// Lower  of GPIO output enable [31:0]
+#define  GPIO_HI_OE                0x11001C	// Upper word  of GPIO output enable [47:32]
+
+#define  GPIO_LO_INT_MSK           0x11003C	// GPIO interrupt mask
+#define  GPIO_LO_INT_STAT          0x110044	// GPIO interrupt status
+#define  GPIO_LO_INT_MSTAT         0x11004C	// GPIO interrupt masked status
+#define  GPIO_LO_ISM_SNS           0x110054	// GPIO interrupt sensitivity
+#define  GPIO_LO_ISM_POL           0x11005C	// GPIO interrupt polarity
+
+#define  GPIO_HI_INT_MSK           0x110040	// GPIO interrupt mask
+#define  GPIO_HI_INT_STAT          0x110048	// GPIO interrupt status
+#define  GPIO_HI_INT_MSTAT         0x110050	// GPIO interrupt masked status
+#define  GPIO_HI_ISM_SNS           0x110058	// GPIO interrupt sensitivity
+#define  GPIO_HI_ISM_POL           0x110060	// GPIO interrupt polarity
+
+#define  FLD_GPIO43_INT            (1 << 11)
+#define  FLD_GPIO42_INT            (1 << 10)
+#define  FLD_GPIO41_INT            (1 << 9)
+#define  FLD_GPIO40_INT            (1 << 8)
+
+#define  FLD_GPIO9_INT             (1 << 9)
+#define  FLD_GPIO8_INT             (1 << 8)
+#define  FLD_GPIO7_INT             (1 << 7)
+#define  FLD_GPIO6_INT             (1 << 6)
+#define  FLD_GPIO5_INT             (1 << 5)
+#define  FLD_GPIO4_INT             (1 << 4)
+#define  FLD_GPIO3_INT             (1 << 3)
+#define  FLD_GPIO2_INT             (1 << 2)
+#define  FLD_GPIO1_INT             (1 << 1)
+#define  FLD_GPIO0_INT             (1 << 0)
+
+//*****************************************************************************
+#define  TC_REQ                    0x040090	// Rider PCI Express traFFic class request
+
+//*****************************************************************************
+#define  TC_REQ_SET                0x040094	// Rider PCI Express traFFic class request set
+
+//*****************************************************************************
+// Rider
+//*****************************************************************************
+
+// PCI Compatible Header
+//*****************************************************************************
+#define  RDR_CFG0                  0x050000
+#define  RDR_VENDOR_DEVICE_ID_CFG  0x050000
+
+//*****************************************************************************
+#define  RDR_CFG1                  0x050004
+
+//*****************************************************************************
+#define  RDR_CFG2                  0x050008
+
+//*****************************************************************************
+#define  RDR_CFG3                  0x05000C
+
+//*****************************************************************************
+#define  RDR_CFG4                  0x050010
+
+//*****************************************************************************
+#define  RDR_CFG5                  0x050014
+
+//*****************************************************************************
+#define  RDR_CFG6                  0x050018
+
+//*****************************************************************************
+#define  RDR_CFG7                  0x05001C
+
+//*****************************************************************************
+#define  RDR_CFG8                  0x050020
+
+//*****************************************************************************
+#define  RDR_CFG9                  0x050024
+
+//*****************************************************************************
+#define  RDR_CFGA                  0x050028
+
+//*****************************************************************************
+#define  RDR_CFGB                  0x05002C
+#define  RDR_SUSSYSTEM_ID_CFG      0x05002C
+
+//*****************************************************************************
+#define  RDR_CFGC                  0x050030
+
+//*****************************************************************************
+#define  RDR_CFGD                  0x050034
+
+//*****************************************************************************
+#define  RDR_CFGE                  0x050038
+
+//*****************************************************************************
+#define  RDR_CFGF                  0x05003C
+
+//*****************************************************************************
+// PCI-Express Capabilities
+//*****************************************************************************
+#define  RDR_PECAP                 0x050040
+
+//*****************************************************************************
+#define  RDR_PEDEVCAP              0x050044
+
+//*****************************************************************************
+#define  RDR_PEDEVSC               0x050048
+
+//*****************************************************************************
+#define  RDR_PELINKCAP             0x05004C
+
+//*****************************************************************************
+#define  RDR_PELINKSC              0x050050
+
+//*****************************************************************************
+#define  RDR_PMICAP                0x050080
+
+//*****************************************************************************
+#define  RDR_PMCSR                 0x050084
+
+//*****************************************************************************
+#define  RDR_VPDCAP                0x050090
+
+//*****************************************************************************
+#define  RDR_VPDDATA               0x050094
+
+//*****************************************************************************
+#define  RDR_MSICAP                0x0500A0
+
+//*****************************************************************************
+#define  RDR_MSIARL                0x0500A4
+
+//*****************************************************************************
+#define  RDR_MSIARU                0x0500A8
+
+//*****************************************************************************
+#define  RDR_MSIDATA               0x0500AC
+
+//*****************************************************************************
+// PCI Express Extended Capabilities
+//*****************************************************************************
+#define  RDR_AERXCAP               0x050100
+
+//*****************************************************************************
+#define  RDR_AERUESTA              0x050104
+
+//*****************************************************************************
+#define  RDR_AERUEMSK              0x050108
+
+//*****************************************************************************
+#define  RDR_AERUESEV              0x05010C
+
+//*****************************************************************************
+#define  RDR_AERCESTA              0x050110
+
+//*****************************************************************************
+#define  RDR_AERCEMSK              0x050114
+
+//*****************************************************************************
+#define  RDR_AERCC                 0x050118
+
+//*****************************************************************************
+#define  RDR_AERHL0                0x05011C
+
+//*****************************************************************************
+#define  RDR_AERHL1                0x050120
+
+//*****************************************************************************
+#define  RDR_AERHL2                0x050124
+
+//*****************************************************************************
+#define  RDR_AERHL3                0x050128
+
+//*****************************************************************************
+#define  RDR_VCXCAP                0x050200
+
+//*****************************************************************************
+#define  RDR_VCCAP1                0x050204
+
+//*****************************************************************************
+#define  RDR_VCCAP2                0x050208
+
+//*****************************************************************************
+#define  RDR_VCSC                  0x05020C
+
+//*****************************************************************************
+#define  RDR_VCR0_CAP              0x050210
+
+//*****************************************************************************
+#define  RDR_VCR0_CTRL             0x050214
+
+//*****************************************************************************
+#define  RDR_VCR0_STAT             0x050218
+
+//*****************************************************************************
+#define  RDR_VCR1_CAP              0x05021C
+
+//*****************************************************************************
+#define  RDR_VCR1_CTRL             0x050220
+
+//*****************************************************************************
+#define  RDR_VCR1_STAT             0x050224
+
+//*****************************************************************************
+#define  RDR_VCR2_CAP              0x050228
+
+//*****************************************************************************
+#define  RDR_VCR2_CTRL             0x05022C
+
+//*****************************************************************************
+#define  RDR_VCR2_STAT             0x050230
+
+//*****************************************************************************
+#define  RDR_VCR3_CAP              0x050234
+
+//*****************************************************************************
+#define  RDR_VCR3_CTRL             0x050238
+
+//*****************************************************************************
+#define  RDR_VCR3_STAT             0x05023C
+
+//*****************************************************************************
+#define  RDR_VCARB0                0x050240
+
+//*****************************************************************************
+#define  RDR_VCARB1                0x050244
+
+//*****************************************************************************
+#define  RDR_VCARB2                0x050248
+
+//*****************************************************************************
+#define  RDR_VCARB3                0x05024C
+
+//*****************************************************************************
+#define  RDR_VCARB4                0x050250
+
+//*****************************************************************************
+#define  RDR_VCARB5                0x050254
+
+//*****************************************************************************
+#define  RDR_VCARB6                0x050258
+
+//*****************************************************************************
+#define  RDR_VCARB7                0x05025C
+
+//*****************************************************************************
+#define  RDR_RDRSTAT0              0x050300
+
+//*****************************************************************************
+#define  RDR_RDRSTAT1              0x050304
+
+//*****************************************************************************
+#define  RDR_RDRCTL0               0x050308
+
+//*****************************************************************************
+#define  RDR_RDRCTL1               0x05030C
+
+//*****************************************************************************
+// Transaction Layer Registers
+//*****************************************************************************
+#define  RDR_TLSTAT0               0x050310
+
+//*****************************************************************************
+#define  RDR_TLSTAT1               0x050314
+
+//*****************************************************************************
+#define  RDR_TLCTL0                0x050318
+#define  FLD_CFG_UR_CPL_MODE       0x00000040
+#define  FLD_CFG_CORR_ERR_QUITE    0x00000020
+#define  FLD_CFG_RCB_CK_EN         0x00000010
+#define  FLD_CFG_BNDRY_CK_EN       0x00000008
+#define  FLD_CFG_BYTE_EN_CK_EN     0x00000004
+#define  FLD_CFG_RELAX_ORDER_MSK   0x00000002
+#define  FLD_CFG_TAG_ORDER_EN      0x00000001
+
+//*****************************************************************************
+#define  RDR_TLCTL1                0x05031C
+
+//*****************************************************************************
+#define  RDR_REQRCAL               0x050320
+
+//*****************************************************************************
+#define  RDR_REQRCAU               0x050324
+
+//*****************************************************************************
+#define  RDR_REQEPA                0x050328
+
+//*****************************************************************************
+#define  RDR_REQCTRL               0x05032C
+
+//*****************************************************************************
+#define  RDR_REQSTAT               0x050330
+
+//*****************************************************************************
+#define  RDR_TL_TEST               0x050334
+
+//*****************************************************************************
+#define  RDR_VCR01_CTL             0x050348
+
+//*****************************************************************************
+#define  RDR_VCR23_CTL             0x05034C
+
+//*****************************************************************************
+#define  RDR_RX_VCR0_FC            0x050350
+
+//*****************************************************************************
+#define  RDR_RX_VCR1_FC            0x050354
+
+//*****************************************************************************
+#define  RDR_RX_VCR2_FC            0x050358
+
+//*****************************************************************************
+#define  RDR_RX_VCR3_FC            0x05035C
+
+//*****************************************************************************
+// Data Link Layer Registers
+//*****************************************************************************
+#define  RDR_DLLSTAT               0x050360
+
+//*****************************************************************************
+#define  RDR_DLLCTRL               0x050364
+
+//*****************************************************************************
+#define  RDR_REPLAYTO              0x050368
+
+//*****************************************************************************
+#define  RDR_ACKLATTO              0x05036C
+
+//*****************************************************************************
+// MAC Layer Registers
+//*****************************************************************************
+#define  RDR_MACSTAT0              0x050380
+
+//*****************************************************************************
+#define  RDR_MACSTAT1              0x050384
+
+//*****************************************************************************
+#define  RDR_MACCTRL0              0x050388
+
+//*****************************************************************************
+#define  RDR_MACCTRL1              0x05038C
+
+//*****************************************************************************
+#define  RDR_MACCTRL2              0x050390
+
+//*****************************************************************************
+#define  RDR_MAC_LB_DATA           0x050394
+
+//*****************************************************************************
+#define  RDR_L0S_EXIT_LAT          0x050398
+
+//*****************************************************************************
+// DMAC
+//*****************************************************************************
+#define  DMA1_PTR1                 0x100000	// DMA Current Ptr : Ch#1
+
+//*****************************************************************************
+#define  DMA2_PTR1                 0x100004	// DMA Current Ptr : Ch#2
+
+//*****************************************************************************
+#define  DMA3_PTR1                 0x100008	// DMA Current Ptr : Ch#3
+
+//*****************************************************************************
+#define  DMA4_PTR1                 0x10000C	// DMA Current Ptr : Ch#4
+
+//*****************************************************************************
+#define  DMA5_PTR1                 0x100010	// DMA Current Ptr : Ch#5
+
+//*****************************************************************************
+#define  DMA6_PTR1                 0x100014	// DMA Current Ptr : Ch#6
+
+//*****************************************************************************
+#define  DMA7_PTR1                 0x100018	// DMA Current Ptr : Ch#7
+
+//*****************************************************************************
+#define  DMA8_PTR1                 0x10001C	// DMA Current Ptr : Ch#8
+
+//*****************************************************************************
+#define  DMA9_PTR1                 0x100020	// DMA Current Ptr : Ch#9
+
+//*****************************************************************************
+#define  DMA10_PTR1                0x100024	// DMA Current Ptr : Ch#10
+
+//*****************************************************************************
+#define  DMA11_PTR1                0x100028	// DMA Current Ptr : Ch#11
+
+//*****************************************************************************
+#define  DMA12_PTR1                0x10002C	// DMA Current Ptr : Ch#12
+
+//*****************************************************************************
+#define  DMA13_PTR1                0x100030	// DMA Current Ptr : Ch#13
+
+//*****************************************************************************
+#define  DMA14_PTR1                0x100034	// DMA Current Ptr : Ch#14
+
+//*****************************************************************************
+#define  DMA15_PTR1                0x100038	// DMA Current Ptr : Ch#15
+
+//*****************************************************************************
+#define  DMA16_PTR1                0x10003C	// DMA Current Ptr : Ch#16
+
+//*****************************************************************************
+#define  DMA17_PTR1                0x100040	// DMA Current Ptr : Ch#17
+
+//*****************************************************************************
+#define  DMA18_PTR1                0x100044	// DMA Current Ptr : Ch#18
+
+//*****************************************************************************
+#define  DMA19_PTR1                0x100048	// DMA Current Ptr : Ch#19
+
+//*****************************************************************************
+#define  DMA20_PTR1                0x10004C	// DMA Current Ptr : Ch#20
+
+//*****************************************************************************
+#define  DMA21_PTR1                0x100050	// DMA Current Ptr : Ch#21
+
+//*****************************************************************************
+#define  DMA22_PTR1                0x100054	// DMA Current Ptr : Ch#22
+
+//*****************************************************************************
+#define  DMA23_PTR1                0x100058	// DMA Current Ptr : Ch#23
+
+//*****************************************************************************
+#define  DMA24_PTR1                0x10005C	// DMA Current Ptr : Ch#24
+
+//*****************************************************************************
+#define  DMA25_PTR1                0x100060	// DMA Current Ptr : Ch#25
+
+//*****************************************************************************
+#define  DMA26_PTR1                0x100064	// DMA Current Ptr : Ch#26
+
+//*****************************************************************************
+#define  DMA1_PTR2                 0x100080	// DMA Tab Ptr : Ch#1
+
+//*****************************************************************************
+#define  DMA2_PTR2                 0x100084	// DMA Tab Ptr : Ch#2
+
+//*****************************************************************************
+#define  DMA3_PTR2                 0x100088	// DMA Tab Ptr : Ch#3
+
+//*****************************************************************************
+#define  DMA4_PTR2                 0x10008C	// DMA Tab Ptr : Ch#4
+
+//*****************************************************************************
+#define  DMA5_PTR2                 0x100090	// DMA Tab Ptr : Ch#5
+
+//*****************************************************************************
+#define  DMA6_PTR2                 0x100094	// DMA Tab Ptr : Ch#6
+
+//*****************************************************************************
+#define  DMA7_PTR2                 0x100098	// DMA Tab Ptr : Ch#7
+
+//*****************************************************************************
+#define  DMA8_PTR2                 0x10009C	// DMA Tab Ptr : Ch#8
+
+//*****************************************************************************
+#define  DMA9_PTR2                 0x1000A0	// DMA Tab Ptr : Ch#9
+
+//*****************************************************************************
+#define  DMA10_PTR2                0x1000A4	// DMA Tab Ptr : Ch#10
+
+//*****************************************************************************
+#define  DMA11_PTR2                0x1000A8	// DMA Tab Ptr : Ch#11
+
+//*****************************************************************************
+#define  DMA12_PTR2                0x1000AC	// DMA Tab Ptr : Ch#12
+
+//*****************************************************************************
+#define  DMA13_PTR2                0x1000B0	// DMA Tab Ptr : Ch#13
+
+//*****************************************************************************
+#define  DMA14_PTR2                0x1000B4	// DMA Tab Ptr : Ch#14
+
+//*****************************************************************************
+#define  DMA15_PTR2                0x1000B8	// DMA Tab Ptr : Ch#15
+
+//*****************************************************************************
+#define  DMA16_PTR2                0x1000BC	// DMA Tab Ptr : Ch#16
+
+//*****************************************************************************
+#define  DMA17_PTR2                0x1000C0	// DMA Tab Ptr : Ch#17
+
+//*****************************************************************************
+#define  DMA18_PTR2                0x1000C4	// DMA Tab Ptr : Ch#18
+
+//*****************************************************************************
+#define  DMA19_PTR2                0x1000C8	// DMA Tab Ptr : Ch#19
+
+//*****************************************************************************
+#define  DMA20_PTR2                0x1000CC	// DMA Tab Ptr : Ch#20
+
+//*****************************************************************************
+#define  DMA21_PTR2                0x1000D0	// DMA Tab Ptr : Ch#21
+
+//*****************************************************************************
+#define  DMA22_PTR2                0x1000D4	// DMA Tab Ptr : Ch#22
+
+//*****************************************************************************
+#define  DMA23_PTR2                0x1000D8	// DMA Tab Ptr : Ch#23
+
+//*****************************************************************************
+#define  DMA24_PTR2                0x1000DC	// DMA Tab Ptr : Ch#24
+
+//*****************************************************************************
+#define  DMA25_PTR2                0x1000E0	// DMA Tab Ptr : Ch#25
+
+//*****************************************************************************
+#define  DMA26_PTR2                0x1000E4	// DMA Tab Ptr : Ch#26
+
+//*****************************************************************************
+#define  DMA1_CNT1                 0x100100	// DMA BuFFer Size : Ch#1
+
+//*****************************************************************************
+#define  DMA2_CNT1                 0x100104	// DMA BuFFer Size : Ch#2
+
+//*****************************************************************************
+#define  DMA3_CNT1                 0x100108	// DMA BuFFer Size : Ch#3
+
+//*****************************************************************************
+#define  DMA4_CNT1                 0x10010C	// DMA BuFFer Size : Ch#4
+
+//*****************************************************************************
+#define  DMA5_CNT1                 0x100110	// DMA BuFFer Size : Ch#5
+
+//*****************************************************************************
+#define  DMA6_CNT1                 0x100114	// DMA BuFFer Size : Ch#6
+
+//*****************************************************************************
+#define  DMA7_CNT1                 0x100118	// DMA BuFFer Size : Ch#7
+
+//*****************************************************************************
+#define  DMA8_CNT1                 0x10011C	// DMA BuFFer Size : Ch#8
+
+//*****************************************************************************
+#define  DMA9_CNT1                 0x100120	// DMA BuFFer Size : Ch#9
+
+//*****************************************************************************
+#define  DMA10_CNT1                0x100124	// DMA BuFFer Size : Ch#10
+
+//*****************************************************************************
+#define  DMA11_CNT1                0x100128	// DMA BuFFer Size : Ch#11
+
+//*****************************************************************************
+#define  DMA12_CNT1                0x10012C	// DMA BuFFer Size : Ch#12
+
+//*****************************************************************************
+#define  DMA13_CNT1                0x100130	// DMA BuFFer Size : Ch#13
+
+//*****************************************************************************
+#define  DMA14_CNT1                0x100134	// DMA BuFFer Size : Ch#14
+
+//*****************************************************************************
+#define  DMA15_CNT1                0x100138	// DMA BuFFer Size : Ch#15
+
+//*****************************************************************************
+#define  DMA16_CNT1                0x10013C	// DMA BuFFer Size : Ch#16
+
+//*****************************************************************************
+#define  DMA17_CNT1                0x100140	// DMA BuFFer Size : Ch#17
+
+//*****************************************************************************
+#define  DMA18_CNT1                0x100144	// DMA BuFFer Size : Ch#18
+
+//*****************************************************************************
+#define  DMA19_CNT1                0x100148	// DMA BuFFer Size : Ch#19
+
+//*****************************************************************************
+#define  DMA20_CNT1                0x10014C	// DMA BuFFer Size : Ch#20
+
+//*****************************************************************************
+#define  DMA21_CNT1                0x100150	// DMA BuFFer Size : Ch#21
+
+//*****************************************************************************
+#define  DMA22_CNT1                0x100154	// DMA BuFFer Size : Ch#22
+
+//*****************************************************************************
+#define  DMA23_CNT1                0x100158	// DMA BuFFer Size : Ch#23
+
+//*****************************************************************************
+#define  DMA24_CNT1                0x10015C	// DMA BuFFer Size : Ch#24
+
+//*****************************************************************************
+#define  DMA25_CNT1                0x100160	// DMA BuFFer Size : Ch#25
+
+//*****************************************************************************
+#define  DMA26_CNT1                0x100164	// DMA BuFFer Size : Ch#26
+
+//*****************************************************************************
+#define  DMA1_CNT2                 0x100180	// DMA Table Size : Ch#1
+
+//*****************************************************************************
+#define  DMA2_CNT2                 0x100184	// DMA Table Size : Ch#2
+
+//*****************************************************************************
+#define  DMA3_CNT2                 0x100188	// DMA Table Size : Ch#3
+
+//*****************************************************************************
+#define  DMA4_CNT2                 0x10018C	// DMA Table Size : Ch#4
+
+//*****************************************************************************
+#define  DMA5_CNT2                 0x100190	// DMA Table Size : Ch#5
+
+//*****************************************************************************
+#define  DMA6_CNT2                 0x100194	// DMA Table Size : Ch#6
+
+//*****************************************************************************
+#define  DMA7_CNT2                 0x100198	// DMA Table Size : Ch#7
+
+//*****************************************************************************
+#define  DMA8_CNT2                 0x10019C	// DMA Table Size : Ch#8
+
+//*****************************************************************************
+#define  DMA9_CNT2                 0x1001A0	// DMA Table Size : Ch#9
+
+//*****************************************************************************
+#define  DMA10_CNT2                0x1001A4	// DMA Table Size : Ch#10
+
+//*****************************************************************************
+#define  DMA11_CNT2                0x1001A8	// DMA Table Size : Ch#11
+
+//*****************************************************************************
+#define  DMA12_CNT2                0x1001AC	// DMA Table Size : Ch#12
+
+//*****************************************************************************
+#define  DMA13_CNT2                0x1001B0	// DMA Table Size : Ch#13
+
+//*****************************************************************************
+#define  DMA14_CNT2                0x1001B4	// DMA Table Size : Ch#14
+
+//*****************************************************************************
+#define  DMA15_CNT2                0x1001B8	// DMA Table Size : Ch#15
+
+//*****************************************************************************
+#define  DMA16_CNT2                0x1001BC	// DMA Table Size : Ch#16
+
+//*****************************************************************************
+#define  DMA17_CNT2                0x1001C0	// DMA Table Size : Ch#17
+
+//*****************************************************************************
+#define  DMA18_CNT2                0x1001C4	// DMA Table Size : Ch#18
+
+//*****************************************************************************
+#define  DMA19_CNT2                0x1001C8	// DMA Table Size : Ch#19
+
+//*****************************************************************************
+#define  DMA20_CNT2                0x1001CC	// DMA Table Size : Ch#20
+
+//*****************************************************************************
+#define  DMA21_CNT2                0x1001D0	// DMA Table Size : Ch#21
+
+//*****************************************************************************
+#define  DMA22_CNT2                0x1001D4	// DMA Table Size : Ch#22
+
+//*****************************************************************************
+#define  DMA23_CNT2                0x1001D8	// DMA Table Size : Ch#23
+
+//*****************************************************************************
+#define  DMA24_CNT2                0x1001DC	// DMA Table Size : Ch#24
+
+//*****************************************************************************
+#define  DMA25_CNT2                0x1001E0	// DMA Table Size : Ch#25
+
+//*****************************************************************************
+#define  DMA26_CNT2                0x1001E4	// DMA Table Size : Ch#26
+
+//*****************************************************************************
+ // ITG
+//*****************************************************************************
+#define  TM_CNT_LDW                0x110000	// Timer : Counter low
+
+//*****************************************************************************
+#define  TM_CNT_UW                 0x110004	// Timer : Counter high word
+
+//*****************************************************************************
+#define  TM_LMT_LDW                0x110008	// Timer : Limit low
+
+//*****************************************************************************
+#define  TM_LMT_UW                 0x11000C	// Timer : Limit high word
+
+//*****************************************************************************
+#define  GP0_IO                    0x110010	// GPIO output enables data I/O
+#define  FLD_GP_OE                 0x00FF0000	// GPIO: GP_OE output enable
+#define  FLD_GP_IN                 0x0000FF00	// GPIO: GP_IN status
+#define  FLD_GP_OUT                0x000000FF	// GPIO: GP_OUT control
+
+//*****************************************************************************
+#define  GPIO_ISM                  0x110014	// GPIO interrupt sensitivity mode
+#define  FLD_GP_ISM_SNS            0x00000070
+#define  FLD_GP_ISM_POL            0x00000007
+
+//*****************************************************************************
+#define  SOFT_RESET                0x11001C	// Output system reset reg
+#define  FLD_PECOS_SOFT_RESET      0x00000001
+
+//*****************************************************************************
+#define  MC416_RWD                 0x110020	// MC416 GPIO[18:3] pin
+#define  MC416_OEN                 0x110024	// Output enable of GPIO[18:3]
+#define  MC416_CTL                 0x110028
+
+//*****************************************************************************
+#define  ALT_PIN_OUT_SEL           0x11002C	// Alternate GPIO output select
+
+#define  FLD_ALT_GPIO_OUT_SEL      0xF0000000
+// 0          Disabled <-- default
+// 1          GPIO[0]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+// 8          ATT_IF
+
+#define  FLD_AUX_PLL_CLK_ALT_SEL   0x0F000000
+// 0          AUX_PLL_CLK<-- default
+// 1          GPIO[2]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+
+#define  FLD_IR_TX_ALT_SEL         0x00F00000
+// 0          IR_TX <-- default
+// 1          GPIO[1]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+
+#define  FLD_IR_RX_ALT_SEL         0x000F0000
+// 0          IR_RX <-- default
+// 1          GPIO[0]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+
+#define  FLD_GPIO10_ALT_SEL        0x0000F000
+// 0          GPIO[10] <-- default
+// 1          GPIO[0]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+
+#define  FLD_GPIO2_ALT_SEL         0x00000F00
+// 0          GPIO[2] <-- default
+// 1          GPIO[1]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+
+#define  FLD_GPIO1_ALT_SEL         0x000000F0
+// 0          GPIO[1] <-- default
+// 1          GPIO[0]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+
+#define  FLD_GPIO0_ALT_SEL         0x0000000F
+// 0          GPIO[0] <-- default
+// 1          GPIO[1]
+// 2          GPIO[10]
+// 3          VIP_656_DATA_VAL
+// 4          VIP_656_DATA[0]
+// 5          VIP_656_CLK
+// 6          VIP_656_DATA_EXT[1]
+// 7          VIP_656_DATA_EXT[0]
+
+#define  ALT_PIN_IN_SEL            0x110030	// Alternate GPIO input select
+
+#define  FLD_GPIO10_ALT_IN_SEL     0x0000F000
+// 0          GPIO[10] <-- default
+// 1          IR_RX
+// 2          IR_TX
+// 3          AUX_PLL_CLK
+// 4          IF_ATT_SEL
+// 5          GPIO[0]
+// 6          GPIO[1]
+// 7          GPIO[2]
+
+#define  FLD_GPIO2_ALT_IN_SEL      0x00000F00
+// 0          GPIO[2] <-- default
+// 1          IR_RX
+// 2          IR_TX
+// 3          AUX_PLL_CLK
+// 4          IF_ATT_SEL
+
+#define  FLD_GPIO1_ALT_IN_SEL      0x000000F0
+// 0          GPIO[1] <-- default
+// 1          IR_RX
+// 2          IR_TX
+// 3          AUX_PLL_CLK
+// 4          IF_ATT_SEL
+
+#define  FLD_GPIO0_ALT_IN_SEL      0x0000000F
+// 0          GPIO[0] <-- default
+// 1          IR_RX
+// 2          IR_TX
+// 3          AUX_PLL_CLK
+// 4          IF_ATT_SEL
+
+//*****************************************************************************
+#define  TEST_BUS_CTL1             0x110040	// Test bus control register #1
+
+//*****************************************************************************
+#define  TEST_BUS_CTL2             0x110044	// Test bus control register #2
+
+//*****************************************************************************
+#define  CLK_DELAY                 0x110048	// Clock delay
+#define  FLD_MOE_CLK_DIS           0x80000000	// Disable MoE clock
+
+//*****************************************************************************
+#define  PAD_CTRL                  0x110068	// Pad drive strength control
+
+//*****************************************************************************
+#define  MBIST_CTRL                0x110050	// SRAM memory built-in self test control
+
+//*****************************************************************************
+#define  MBIST_STAT                0x110054	// SRAM memory built-in self test status
+
+//*****************************************************************************
+// PLL registers
+//*****************************************************************************
+#define  PLL_A_INT_FRAC            0x110088
+#define  PLL_A_POST_STAT_BIST      0x11008C
+#define  PLL_B_INT_FRAC            0x110090
+#define  PLL_B_POST_STAT_BIST      0x110094
+#define  PLL_C_INT_FRAC            0x110098
+#define  PLL_C_POST_STAT_BIST      0x11009C
+#define  PLL_D_INT_FRAC            0x1100A0
+#define  PLL_D_POST_STAT_BIST      0x1100A4
+
+#define  CLK_RST                   0x11002C
+#define  FLD_VID_I_CLK_NOE         0x00001000
+#define  FLD_VID_J_CLK_NOE         0x00002000
+#define  FLD_USE_ALT_PLL_REF       0x00004000
+
+#define  VID_CH_MODE_SEL           0x110078
+#define  VID_CH_CLK_SEL            0x11007C
+
+//*****************************************************************************
+#define  VBI_A_DMA                 0x130008	// VBI A DMA data port
+
+//*****************************************************************************
+#define  VID_A_VIP_CTL             0x130080	// Video A VIP format control
+#define  FLD_VIP_MODE              0x00000001
+
+//*****************************************************************************
+#define  VID_A_PIXEL_FRMT          0x130084	// Video A pixel format
+#define  FLD_VID_A_GAMMA_DIS       0x00000008
+#define  FLD_VID_A_FORMAT          0x00000007
+#define  FLD_VID_A_GAMMA_FACTOR    0x00000010
+
+//*****************************************************************************
+#define  VID_A_VBI_CTL             0x130088	// Video A VBI miscellaneous control
+#define  FLD_VID_A_VIP_EXT         0x00000003
+
+//*****************************************************************************
+#define  VID_B_DMA                 0x130100	// Video B DMA data port
+
+//*****************************************************************************
+#define  VBI_B_DMA                 0x130108	// VBI B DMA data port
+
+//*****************************************************************************
+#define  VID_B_SRC_SEL             0x130144	// Video B source select
+#define  FLD_VID_B_SRC_SEL         0x00000000
+
+//*****************************************************************************
+#define  VID_B_LNGTH               0x130150	// Video B line length
+#define  FLD_VID_B_LN_LNGTH        0x00000FFF
+
+//*****************************************************************************
+#define  VID_B_VIP_CTL             0x130180	// Video B VIP format control
+
+//*****************************************************************************
+#define  VID_B_PIXEL_FRMT          0x130184	// Video B pixel format
+#define  FLD_VID_B_GAMMA_DIS       0x00000008
+#define  FLD_VID_B_FORMAT          0x00000007
+#define  FLD_VID_B_GAMMA_FACTOR    0x00000010
+
+//*****************************************************************************
+#define  VID_C_DMA                 0x130200	// Video C DMA data port
+
+//*****************************************************************************
+#define  VID_C_LNGTH               0x130250	// Video C line length
+#define  FLD_VID_C_LN_LNGTH        0x00000FFF
+
+//*****************************************************************************
+// Video Destination Channels
+//*****************************************************************************
+
+#define  VID_DST_A_GPCNT           0x130020	// Video A general purpose counter
+#define  VID_DST_B_GPCNT           0x130120	// Video B general purpose counter
+#define  VID_DST_C_GPCNT           0x130220	// Video C general purpose counter
+#define  VID_DST_D_GPCNT           0x130320	// Video D general purpose counter
+#define  VID_DST_E_GPCNT           0x130420	// Video E general purpose counter
+#define  VID_DST_F_GPCNT           0x130520	// Video F general purpose counter
+#define  VID_DST_G_GPCNT           0x130620	// Video G general purpose counter
+#define  VID_DST_H_GPCNT           0x130720	// Video H general purpose counter
+
+//*****************************************************************************
+
+#define  VID_DST_A_GPCNT_CTL       0x130030	// Video A general purpose control
+#define  VID_DST_B_GPCNT_CTL       0x130130	// Video B general purpose control
+#define  VID_DST_C_GPCNT_CTL       0x130230	// Video C general purpose control
+#define  VID_DST_D_GPCNT_CTL       0x130330	// Video D general purpose control
+#define  VID_DST_E_GPCNT_CTL       0x130430	// Video E general purpose control
+#define  VID_DST_F_GPCNT_CTL       0x130530	// Video F general purpose control
+#define  VID_DST_G_GPCNT_CTL       0x130630	// Video G general purpose control
+#define  VID_DST_H_GPCNT_CTL       0x130730	// Video H general purpose control
+
+//*****************************************************************************
+
+#define  VID_DST_A_DMA_CTL         0x130040	// Video A DMA control
+#define  VID_DST_B_DMA_CTL         0x130140	// Video B DMA control
+#define  VID_DST_C_DMA_CTL         0x130240	// Video C DMA control
+#define  VID_DST_D_DMA_CTL         0x130340	// Video D DMA control
+#define  VID_DST_E_DMA_CTL         0x130440	// Video E DMA control
+#define  VID_DST_F_DMA_CTL         0x130540	// Video F DMA control
+#define  VID_DST_G_DMA_CTL         0x130640	// Video G DMA control
+#define  VID_DST_H_DMA_CTL         0x130740	// Video H DMA control
+
+#define  FLD_VID_RISC_EN           0x00000010
+#define  FLD_VID_FIFO_EN           0x00000001
+
+//*****************************************************************************
+
+#define  VID_DST_A_VIP_CTL         0x130080	// Video A VIP control
+#define  VID_DST_B_VIP_CTL         0x130180	// Video B VIP control
+#define  VID_DST_C_VIP_CTL         0x130280	// Video C VIP control
+#define  VID_DST_D_VIP_CTL         0x130380	// Video D VIP control
+#define  VID_DST_E_VIP_CTL         0x130480	// Video E VIP control
+#define  VID_DST_F_VIP_CTL         0x130580	// Video F VIP control
+#define  VID_DST_G_VIP_CTL         0x130680	// Video G VIP control
+#define  VID_DST_H_VIP_CTL         0x130780	// Video H VIP control
+
+//*****************************************************************************
+
+#define  VID_DST_A_PIX_FRMT        0x130084	// Video A Pixel format
+#define  VID_DST_B_PIX_FRMT        0x130184	// Video B Pixel format
+#define  VID_DST_C_PIX_FRMT        0x130284	// Video C Pixel format
+#define  VID_DST_D_PIX_FRMT        0x130384	// Video D Pixel format
+#define  VID_DST_E_PIX_FRMT        0x130484	// Video E Pixel format
+#define  VID_DST_F_PIX_FRMT        0x130584	// Video F Pixel format
+#define  VID_DST_G_PIX_FRMT        0x130684	// Video G Pixel format
+#define  VID_DST_H_PIX_FRMT        0x130784	// Video H Pixel format
+
+//*****************************************************************************
+// Video Source Channels
+//*****************************************************************************
+
+#define  VID_SRC_A_GPCNT_CTL       0x130804	// Video A general purpose control
+#define  VID_SRC_B_GPCNT_CTL       0x130904	// Video B general purpose control
+#define  VID_SRC_C_GPCNT_CTL       0x130A04	// Video C general purpose control
+#define  VID_SRC_D_GPCNT_CTL       0x130B04	// Video D general purpose control
+#define  VID_SRC_E_GPCNT_CTL       0x130C04	// Video E general purpose control
+#define  VID_SRC_F_GPCNT_CTL       0x130D04	// Video F general purpose control
+#define  VID_SRC_I_GPCNT_CTL       0x130E04	// Video I general purpose control
+#define  VID_SRC_J_GPCNT_CTL       0x130F04	// Video J general purpose control
+
+//*****************************************************************************
+
+#define  VID_SRC_A_GPCNT           0x130808	// Video A general purpose counter
+#define  VID_SRC_B_GPCNT           0x130908	// Video B general purpose counter
+#define  VID_SRC_C_GPCNT           0x130A08	// Video C general purpose counter
+#define  VID_SRC_D_GPCNT           0x130B08	// Video D general purpose counter
+#define  VID_SRC_E_GPCNT           0x130C08	// Video E general purpose counter
+#define  VID_SRC_F_GPCNT           0x130D08	// Video F general purpose counter
+#define  VID_SRC_I_GPCNT           0x130E08	// Video I general purpose counter
+#define  VID_SRC_J_GPCNT           0x130F08	// Video J general purpose counter
+
+//*****************************************************************************
+
+#define  VID_SRC_A_DMA_CTL         0x13080C	// Video A DMA control
+#define  VID_SRC_B_DMA_CTL         0x13090C	// Video B DMA control
+#define  VID_SRC_C_DMA_CTL         0x130A0C	// Video C DMA control
+#define  VID_SRC_D_DMA_CTL         0x130B0C	// Video D DMA control
+#define  VID_SRC_E_DMA_CTL         0x130C0C	// Video E DMA control
+#define  VID_SRC_F_DMA_CTL         0x130D0C	// Video F DMA control
+#define  VID_SRC_I_DMA_CTL         0x130E0C	// Video I DMA control
+#define  VID_SRC_J_DMA_CTL         0x130F0C	// Video J DMA control
+
+#define  FLD_APB_RISC_EN           0x00000010
+#define  FLD_APB_FIFO_EN           0x00000001
+
+//*****************************************************************************
+
+#define  VID_SRC_A_FMT_CTL         0x130810	// Video A format control
+#define  VID_SRC_B_FMT_CTL         0x130910	// Video B format control
+#define  VID_SRC_C_FMT_CTL         0x130A10	// Video C format control
+#define  VID_SRC_D_FMT_CTL         0x130B10	// Video D format control
+#define  VID_SRC_E_FMT_CTL         0x130C10	// Video E format control
+#define  VID_SRC_F_FMT_CTL         0x130D10	// Video F format control
+#define  VID_SRC_I_FMT_CTL         0x130E10	// Video I format control
+#define  VID_SRC_J_FMT_CTL         0x130F10	// Video J format control
+
+//*****************************************************************************
+
+#define  VID_SRC_A_ACTIVE_CTL1     0x130814	// Video A active control      1
+#define  VID_SRC_B_ACTIVE_CTL1     0x130914	// Video B active control      1
+#define  VID_SRC_C_ACTIVE_CTL1     0x130A14	// Video C active control      1
+#define  VID_SRC_D_ACTIVE_CTL1     0x130B14	// Video D active control      1
+#define  VID_SRC_E_ACTIVE_CTL1     0x130C14	// Video E active control      1
+#define  VID_SRC_F_ACTIVE_CTL1     0x130D14	// Video F active control      1
+#define  VID_SRC_I_ACTIVE_CTL1     0x130E14	// Video I active control      1
+#define  VID_SRC_J_ACTIVE_CTL1     0x130F14	// Video J active control      1
+
+//*****************************************************************************
+
+#define  VID_SRC_A_ACTIVE_CTL2     0x130818	// Video A active control      2
+#define  VID_SRC_B_ACTIVE_CTL2     0x130918	// Video B active control      2
+#define  VID_SRC_C_ACTIVE_CTL2     0x130A18	// Video C active control      2
+#define  VID_SRC_D_ACTIVE_CTL2     0x130B18	// Video D active control      2
+#define  VID_SRC_E_ACTIVE_CTL2     0x130C18	// Video E active control      2
+#define  VID_SRC_F_ACTIVE_CTL2     0x130D18	// Video F active control      2
+#define  VID_SRC_I_ACTIVE_CTL2     0x130E18	// Video I active control      2
+#define  VID_SRC_J_ACTIVE_CTL2     0x130F18	// Video J active control      2
+
+//*****************************************************************************
+
+#define  VID_SRC_A_CDT_SZ          0x13081C	// Video A CDT size
+#define  VID_SRC_B_CDT_SZ          0x13091C	// Video B CDT size
+#define  VID_SRC_C_CDT_SZ          0x130A1C	// Video C CDT size
+#define  VID_SRC_D_CDT_SZ          0x130B1C	// Video D CDT size
+#define  VID_SRC_E_CDT_SZ          0x130C1C	// Video E CDT size
+#define  VID_SRC_F_CDT_SZ          0x130D1C	// Video F CDT size
+#define  VID_SRC_I_CDT_SZ          0x130E1C	// Video I CDT size
+#define  VID_SRC_J_CDT_SZ          0x130F1C	// Video J CDT size
+
+//*****************************************************************************
+// Audio I/F
+//*****************************************************************************
+#define  AUD_DST_A_DMA             0x140000	// Audio Int A DMA data port
+#define  AUD_SRC_A_DMA             0x140008	// Audio Int A DMA data port
+
+#define  AUD_A_GPCNT               0x140010	// Audio Int A gp counter
+#define  FLD_AUD_A_GP_CNT          0x0000FFFF
+
+#define  AUD_A_GPCNT_CTL           0x140014	// Audio Int A gp control
+
+#define  AUD_A_LNGTH               0x140018	// Audio Int A line length
+
+#define  AUD_A_CFG                 0x14001C	// Audio Int A configuration
+
+//*****************************************************************************
+#define  AUD_DST_B_DMA             0x140100	// Audio Int B DMA data port
+#define  AUD_SRC_B_DMA             0x140108	// Audio Int B DMA data port
+
+#define  AUD_B_GPCNT               0x140110	// Audio Int B gp counter
+#define  FLD_AUD_B_GP_CNT          0x0000FFFF
+
+#define  AUD_B_GPCNT_CTL           0x140114	// Audio Int B gp control
+
+#define  AUD_B_LNGTH               0x140118	// Audio Int B line length
+
+#define  AUD_B_CFG                 0x14011C	// Audio Int B configuration
+
+//*****************************************************************************
+#define  AUD_DST_C_DMA             0x140200	// Audio Int C DMA data port
+#define  AUD_SRC_C_DMA             0x140208	// Audio Int C DMA data port
+
+#define  AUD_C_GPCNT               0x140210	// Audio Int C gp counter
+#define  FLD_AUD_C_GP_CNT          0x0000FFFF
+
+#define  AUD_C_GPCNT_CTL           0x140214	// Audio Int C gp control
+
+#define  AUD_C_LNGTH               0x140218	// Audio Int C line length
+
+#define  AUD_C_CFG                 0x14021C	// Audio Int C configuration
+
+//*****************************************************************************
+#define  AUD_DST_D_DMA             0x140300	// Audio Int D DMA data port
+#define  AUD_SRC_D_DMA             0x140308	// Audio Int D DMA data port
+
+#define  AUD_D_GPCNT               0x140310	// Audio Int D gp counter
+#define  FLD_AUD_D_GP_CNT          0x0000FFFF
+
+#define  AUD_D_GPCNT_CTL           0x140314	// Audio Int D gp control
+
+#define  AUD_D_LNGTH               0x140318	// Audio Int D line length
+
+#define  AUD_D_CFG                 0x14031C	// Audio Int D configuration
+
+//*****************************************************************************
+#define  AUD_SRC_E_DMA             0x140400	// Audio Int E DMA data port
+
+#define  AUD_E_GPCNT               0x140410	// Audio Int E gp counter
+#define  FLD_AUD_E_GP_CNT          0x0000FFFF
+
+#define  AUD_E_GPCNT_CTL           0x140414	// Audio Int E gp control
+
+#define  AUD_E_CFG                 0x14041C	// Audio Int E configuration
+
+//*****************************************************************************
+
+#define  FLD_AUD_DST_LN_LNGTH      0x00000FFF
+
+#define  FLD_AUD_DST_PK_MODE       0x00004000
+
+#define  FLD_AUD_CLK_ENABLE        0x00000200
+
+#define  FLD_AUD_MASTER_MODE       0x00000002
+
+#define  FLD_AUD_SONY_MODE         0x00000001
+
+#define  FLD_AUD_CLK_SELECT_PLL_D  0x00001800
+
+#define  FLD_AUD_DST_ENABLE        0x00020000
+
+#define  FLD_AUD_SRC_ENABLE        0x00010000
+
+//*****************************************************************************
+#define  AUD_INT_DMA_CTL           0x140500	// Audio Int DMA control
+
+#define  FLD_AUD_SRC_E_RISC_EN     0x00008000
+#define  FLD_AUD_SRC_C_RISC_EN     0x00004000
+#define  FLD_AUD_SRC_B_RISC_EN     0x00002000
+#define  FLD_AUD_SRC_A_RISC_EN     0x00001000
+
+#define  FLD_AUD_DST_D_RISC_EN     0x00000800
+#define  FLD_AUD_DST_C_RISC_EN     0x00000400
+#define  FLD_AUD_DST_B_RISC_EN     0x00000200
+#define  FLD_AUD_DST_A_RISC_EN     0x00000100
+
+#define  FLD_AUD_SRC_E_FIFO_EN     0x00000080
+#define  FLD_AUD_SRC_C_FIFO_EN     0x00000040
+#define  FLD_AUD_SRC_B_FIFO_EN     0x00000020
+#define  FLD_AUD_SRC_A_FIFO_EN     0x00000010
+
+#define  FLD_AUD_DST_D_FIFO_EN     0x00000008
+#define  FLD_AUD_DST_C_FIFO_EN     0x00000004
+#define  FLD_AUD_DST_B_FIFO_EN     0x00000002
+#define  FLD_AUD_DST_A_FIFO_EN     0x00000001
+
+//*****************************************************************************
+//
+//                   Mobilygen Interface Registers
+//
+//*****************************************************************************
+// Mobilygen Interface A
+//*****************************************************************************
+#define  MB_IF_A_DMA               0x150000	// MBIF A DMA data port
+#define  MB_IF_A_GPCN              0x150008	// MBIF A GP counter
+#define  MB_IF_A_GPCN_CTRL         0x15000C
+#define  MB_IF_A_DMA_CTRL          0x150010
+#define  MB_IF_A_LENGTH            0x150014
+#define  MB_IF_A_HDMA_XFER_SZ      0x150018
+#define  MB_IF_A_HCMD              0x15001C
+#define  MB_IF_A_HCONFIG           0x150020
+#define  MB_IF_A_DATA_STRUCT_0     0x150024
+#define  MB_IF_A_DATA_STRUCT_1     0x150028
+#define  MB_IF_A_DATA_STRUCT_2     0x15002C
+#define  MB_IF_A_DATA_STRUCT_3     0x150030
+#define  MB_IF_A_DATA_STRUCT_4     0x150034
+#define  MB_IF_A_DATA_STRUCT_5     0x150038
+#define  MB_IF_A_DATA_STRUCT_6     0x15003C
+#define  MB_IF_A_DATA_STRUCT_7     0x150040
+#define  MB_IF_A_DATA_STRUCT_8     0x150044
+#define  MB_IF_A_DATA_STRUCT_9     0x150048
+#define  MB_IF_A_DATA_STRUCT_A     0x15004C
+#define  MB_IF_A_DATA_STRUCT_B     0x150050
+#define  MB_IF_A_DATA_STRUCT_C     0x150054
+#define  MB_IF_A_DATA_STRUCT_D     0x150058
+#define  MB_IF_A_DATA_STRUCT_E     0x15005C
+#define  MB_IF_A_DATA_STRUCT_F     0x150060
+//*****************************************************************************
+// Mobilygen Interface B
+//*****************************************************************************
+#define  MB_IF_B_DMA               0x160000	// MBIF A DMA data port
+#define  MB_IF_B_GPCN              0x160008	// MBIF A GP counter
+#define  MB_IF_B_GPCN_CTRL         0x16000C
+#define  MB_IF_B_DMA_CTRL          0x160010
+#define  MB_IF_B_LENGTH            0x160014
+#define  MB_IF_B_HDMA_XFER_SZ      0x160018
+#define  MB_IF_B_HCMD              0x16001C
+#define  MB_IF_B_HCONFIG           0x160020
+#define  MB_IF_B_DATA_STRUCT_0     0x160024
+#define  MB_IF_B_DATA_STRUCT_1     0x160028
+#define  MB_IF_B_DATA_STRUCT_2     0x16002C
+#define  MB_IF_B_DATA_STRUCT_3     0x160030
+#define  MB_IF_B_DATA_STRUCT_4     0x160034
+#define  MB_IF_B_DATA_STRUCT_5     0x160038
+#define  MB_IF_B_DATA_STRUCT_6     0x16003C
+#define  MB_IF_B_DATA_STRUCT_7     0x160040
+#define  MB_IF_B_DATA_STRUCT_8     0x160044
+#define  MB_IF_B_DATA_STRUCT_9     0x160048
+#define  MB_IF_B_DATA_STRUCT_A     0x16004C
+#define  MB_IF_B_DATA_STRUCT_B     0x160050
+#define  MB_IF_B_DATA_STRUCT_C     0x160054
+#define  MB_IF_B_DATA_STRUCT_D     0x160058
+#define  MB_IF_B_DATA_STRUCT_E     0x16005C
+#define  MB_IF_B_DATA_STRUCT_F     0x160060
+
+// MB_DMA_CTRL
+#define  FLD_MB_IF_RISC_EN         0x00000010
+#define  FLD_MB_IF_FIFO_EN         0x00000001
+
+// MB_LENGTH
+#define  FLD_MB_IF_LN_LNGTH        0x00000FFF
+
+// MB_HCMD register
+#define  FLD_MB_HCMD_H_GO          0x80000000
+#define  FLD_MB_HCMD_H_BUSY        0x40000000
+#define  FLD_MB_HCMD_H_DMA_HOLD    0x10000000
+#define  FLD_MB_HCMD_H_DMA_BUSY    0x08000000
+#define  FLD_MB_HCMD_H_DMA_TYPE    0x04000000
+#define  FLD_MB_HCMD_H_DMA_XACT    0x02000000
+#define  FLD_MB_HCMD_H_RW_N        0x01000000
+#define  FLD_MB_HCMD_H_ADDR        0x00FF0000
+#define  FLD_MB_HCMD_H_DATA        0x0000FFFF
+
+//*****************************************************************************
+// I2C #1
+//*****************************************************************************
+#define  I2C1_ADDR                 0x180000	// I2C #1 address
+#define  FLD_I2C_DADDR             0xfe000000	// RW [31:25] I2C Device Address
+						 // RO [24] reserved
+//*****************************************************************************
+#define  FLD_I2C_SADDR             0x00FFFFFF	// RW [23:0]  I2C Sub-address
+
+//*****************************************************************************
+#define  I2C1_WDATA                0x180004	// I2C #1 write data
+#define  FLD_I2C_WDATA             0xFFFFFFFF	// RW [31:0]
+
+//*****************************************************************************
+#define  I2C1_CTRL                 0x180008	// I2C #1 control
+#define  FLD_I2C_PERIOD            0xFF000000	// RW [31:24]
+#define  FLD_I2C_SCL_IN            0x00200000	// RW [21]
+#define  FLD_I2C_SDA_IN            0x00100000	// RW [20]
+						 // RO [19:18] reserved
+#define  FLD_I2C_SCL_OUT           0x00020000	// RW [17]
+#define  FLD_I2C_SDA_OUT           0x00010000	// RW [16]
+						 // RO [15] reserved
+#define  FLD_I2C_DATA_LEN          0x00007000	// RW [14:12]
+#define  FLD_I2C_SADDR_INC         0x00000800	// RW [11]
+						 // RO [10:9] reserved
+#define  FLD_I2C_SADDR_LEN         0x00000300	// RW [9:8]
+						 // RO [7:6] reserved
+#define  FLD_I2C_SOFT              0x00000020	// RW [5]
+#define  FLD_I2C_NOSTOP            0x00000010	// RW [4]
+#define  FLD_I2C_EXTEND            0x00000008	// RW [3]
+#define  FLD_I2C_SYNC              0x00000004	// RW [2]
+#define  FLD_I2C_READ_SA           0x00000002	// RW [1]
+#define  FLD_I2C_READ_WRN          0x00000001	// RW [0]
+
+//*****************************************************************************
+#define  I2C1_RDATA                0x18000C	// I2C #1 read data
+#define  FLD_I2C_RDATA             0xFFFFFFFF	// RO [31:0]
+
+//*****************************************************************************
+#define  I2C1_STAT                 0x180010	// I2C #1 status
+#define  FLD_I2C_XFER_IN_PROG      0x00000002	// RO [1]
+#define  FLD_I2C_RACK              0x00000001	// RO [0]
+
+//*****************************************************************************
+// I2C #2
+//*****************************************************************************
+#define  I2C2_ADDR                 0x190000	// I2C #2 address
+
+//*****************************************************************************
+#define  I2C2_WDATA                0x190004	// I2C #2 write data
+
+//*****************************************************************************
+#define  I2C2_CTRL                 0x190008	// I2C #2 control
+
+//*****************************************************************************
+#define  I2C2_RDATA                0x19000C	// I2C #2 read data
+
+//*****************************************************************************
+#define  I2C2_STAT                 0x190010	// I2C #2 status
+
+//*****************************************************************************
+// I2C #3
+//*****************************************************************************
+#define  I2C3_ADDR                 0x1A0000	// I2C #3 address
+
+//*****************************************************************************
+#define  I2C3_WDATA                0x1A0004	// I2C #3 write data
+
+//*****************************************************************************
+#define  I2C3_CTRL                 0x1A0008	// I2C #3 control
+
+//*****************************************************************************
+#define  I2C3_RDATA                0x1A000C	// I2C #3 read data
+
+//*****************************************************************************
+#define  I2C3_STAT                 0x1A0010	// I2C #3 status
+
+//*****************************************************************************
+// UART
+//*****************************************************************************
+#define  UART_CTL                  0x1B0000	// UART Control Register
+#define  FLD_LOOP_BACK_EN          (1 << 7)	// RW field - default 0
+#define  FLD_RX_TRG_SZ             (3 << 2)	// RW field - default 0
+#define  FLD_RX_EN                 (1 << 1)	// RW field - default 0
+#define  FLD_TX_EN                 (1 << 0)	// RW field - default 0
+
+//*****************************************************************************
+#define  UART_BRD                  0x1B0004	// UART Baud Rate Divisor
+#define  FLD_BRD                   0x0000FFFF	// RW field - default 0x197
+
+//*****************************************************************************
+#define  UART_DBUF                 0x1B0008	// UART Tx/Rx Data BuFFer
+#define  FLD_DB                    0xFFFFFFFF	// RW field - default 0
+
+//*****************************************************************************
+#define  UART_ISR                  0x1B000C	// UART Interrupt Status
+#define  FLD_RXD_TIMEOUT_EN        (1 << 7)	// RW field - default 0
+#define  FLD_FRM_ERR_EN            (1 << 6)	// RW field - default 0
+#define  FLD_RXD_RDY_EN            (1 << 5)	// RW field - default 0
+#define  FLD_TXD_EMPTY_EN          (1 << 4)	// RW field - default 0
+#define  FLD_RXD_OVERFLOW          (1 << 3)	// RW field - default 0
+#define  FLD_FRM_ERR               (1 << 2)	// RW field - default 0
+#define  FLD_RXD_RDY               (1 << 1)	// RW field - default 0
+#define  FLD_TXD_EMPTY             (1 << 0)	// RW field - default 0
+
+//*****************************************************************************
+#define  UART_CNT                  0x1B0010	// UART Tx/Rx FIFO Byte Count
+#define  FLD_TXD_CNT               (0x1F << 8)	// RW field - default 0
+#define  FLD_RXD_CNT               (0x1F << 0)	// RW field - default 0
+
+//*****************************************************************************
+// Motion Detection
+#define  MD_CH0_GRID_BLOCK_YCNT    0x170014
+#define  MD_CH1_GRID_BLOCK_YCNT    0x170094
+#define  MD_CH2_GRID_BLOCK_YCNT    0x170114
+#define  MD_CH3_GRID_BLOCK_YCNT    0x170194
+#define  MD_CH4_GRID_BLOCK_YCNT    0x170214
+#define  MD_CH5_GRID_BLOCK_YCNT    0x170294
+#define  MD_CH6_GRID_BLOCK_YCNT    0x170314
+#define  MD_CH7_GRID_BLOCK_YCNT    0x170394
+
+#define PIXEL_FRMT_422    4
+#define PIXEL_FRMT_411    5
+#define PIXEL_FRMT_Y8     6
+
+#define PIXEL_ENGINE_VIP1 0
+#define PIXEL_ENGINE_VIP2 1
+
+#endif //Athena_REGISTERS
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/staging/cx25821/cx25821-sram.h
new file mode 100644
index 0000000..bd677ee
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-sram.h
@@ -0,0 +1,261 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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.
+ */
+
+#ifndef __ATHENA_SRAM_H__
+#define __ATHENA_SRAM_H__
+
+//#define RX_SRAM_START_SIZE        = 0;  //  Start of reserved SRAM
+#define VID_CMDS_SIZE             80	//  Video CMDS size in bytes
+#define AUDIO_CMDS_SIZE           80	//  AUDIO CMDS size in bytes
+#define MBIF_CMDS_SIZE            80	//  MBIF  CMDS size in bytes
+
+//#define RX_SRAM_POOL_START_SIZE   = 0;  //  Start of useable RX SRAM for buffers
+#define VID_IQ_SIZE               64	//  VID instruction queue size in bytes
+#define MBIF_IQ_SIZE              64
+#define AUDIO_IQ_SIZE             64	//  AUD instruction queue size in bytes
+
+#define VID_CDT_SIZE              64	//  VID cluster descriptor table size in bytes
+#define MBIF_CDT_SIZE             64	//  MBIF/HBI cluster descriptor table size in bytes
+#define AUDIO_CDT_SIZE            48	//  AUD cluster descriptor table size in bytes
+
+//#define RX_SRAM_POOL_FREE_SIZE    = 16; //  Start of available RX SRAM
+//#define RX_SRAM_END_SIZE          = 0;  //  End of RX SRAM
+
+//#define TX_SRAM_POOL_START_SIZE   = 0;  //  Start of transmit pool SRAM
+//#define MSI_DATA_SIZE             = 64; //  Reserved (MSI Data, RISC working stora
+
+#define VID_CLUSTER_SIZE          1440	//  VID cluster data line
+#define AUDIO_CLUSTER_SIZE        128	//  AUDIO cluster data line
+#define MBIF_CLUSTER_SIZE         1440	//  MBIF/HBI cluster data line
+
+//#define TX_SRAM_POOL_FREE_SIZE    = 704;    //  Start of available TX SRAM
+//#define TX_SRAM_END_SIZE          = 0;      //  End of TX SRAM
+
+// Receive SRAM
+#define RX_SRAM_START             0x10000
+#define VID_A_DOWN_CMDS           0x10000
+#define VID_B_DOWN_CMDS           0x10050
+#define VID_C_DOWN_CMDS           0x100A0
+#define VID_D_DOWN_CMDS           0x100F0
+#define VID_E_DOWN_CMDS           0x10140
+#define VID_F_DOWN_CMDS           0x10190
+#define VID_G_DOWN_CMDS           0x101E0
+#define VID_H_DOWN_CMDS           0x10230
+#define VID_A_UP_CMDS             0x10280
+#define VID_B_UP_CMDS             0x102D0
+#define VID_C_UP_CMDS             0x10320
+#define VID_D_UP_CMDS             0x10370
+#define VID_E_UP_CMDS             0x103C0
+#define VID_F_UP_CMDS             0x10410
+#define VID_I_UP_CMDS             0x10460
+#define VID_J_UP_CMDS             0x104B0
+#define AUD_A_DOWN_CMDS           0x10500
+#define AUD_B_DOWN_CMDS           0x10550
+#define AUD_C_DOWN_CMDS           0x105A0
+#define AUD_D_DOWN_CMDS           0x105F0
+#define AUD_A_UP_CMDS             0x10640
+#define AUD_B_UP_CMDS             0x10690
+#define AUD_C_UP_CMDS             0x106E0
+#define AUD_E_UP_CMDS             0x10730
+#define MBIF_A_DOWN_CMDS          0x10780
+#define MBIF_B_DOWN_CMDS          0x107D0
+#define DMA_SCRATCH_PAD           0x10820	// Scratch pad area from 0x10820 to 0x10B40
+
+//#define RX_SRAM_POOL_START        = 0x105B0;
+
+#define VID_A_IQ                  0x11000
+#define VID_B_IQ                  0x11040
+#define VID_C_IQ                  0x11080
+#define VID_D_IQ                  0x110C0
+#define VID_E_IQ                  0x11100
+#define VID_F_IQ                  0x11140
+#define VID_G_IQ                  0x11180
+#define VID_H_IQ                  0x111C0
+#define VID_I_IQ                  0x11200
+#define VID_J_IQ                  0x11240
+#define AUD_A_IQ                  0x11280
+#define AUD_B_IQ                  0x112C0
+#define AUD_C_IQ                  0x11300
+#define AUD_D_IQ                  0x11340
+#define AUD_E_IQ                  0x11380
+#define MBIF_A_IQ                 0x11000
+#define MBIF_B_IQ                 0x110C0
+
+#define VID_A_CDT                 0x10C00
+#define VID_B_CDT                 0x10C40
+#define VID_C_CDT                 0x10C80
+#define VID_D_CDT                 0x10CC0
+#define VID_E_CDT                 0x10D00
+#define VID_F_CDT                 0x10D40
+#define VID_G_CDT                 0x10D80
+#define VID_H_CDT                 0x10DC0
+#define VID_I_CDT                 0x10E00
+#define VID_J_CDT                 0x10E40
+#define AUD_A_CDT                 0x10E80
+#define AUD_B_CDT                 0x10EB0
+#define AUD_C_CDT                 0x10EE0
+#define AUD_D_CDT                 0x10F10
+#define AUD_E_CDT                 0x10F40
+#define MBIF_A_CDT                0x10C00
+#define MBIF_B_CDT                0x10CC0
+
+// Cluster Buffer for RX
+#define VID_A_UP_CLUSTER_1        0x11400
+#define VID_A_UP_CLUSTER_2        0x119A0
+#define VID_A_UP_CLUSTER_3        0x11F40
+#define VID_A_UP_CLUSTER_4        0x124E0
+
+#define VID_B_UP_CLUSTER_1        0x12A80
+#define VID_B_UP_CLUSTER_2        0x13020
+#define VID_B_UP_CLUSTER_3        0x135C0
+#define VID_B_UP_CLUSTER_4        0x13B60
+
+#define VID_C_UP_CLUSTER_1        0x14100
+#define VID_C_UP_CLUSTER_2        0x146A0
+#define VID_C_UP_CLUSTER_3        0x14C40
+#define VID_C_UP_CLUSTER_4        0x151E0
+
+#define VID_D_UP_CLUSTER_1        0x15780
+#define VID_D_UP_CLUSTER_2        0x15D20
+#define VID_D_UP_CLUSTER_3        0x162C0
+#define VID_D_UP_CLUSTER_4        0x16860
+
+#define VID_E_UP_CLUSTER_1        0x16E00
+#define VID_E_UP_CLUSTER_2        0x173A0
+#define VID_E_UP_CLUSTER_3        0x17940
+#define VID_E_UP_CLUSTER_4        0x17EE0
+
+#define VID_F_UP_CLUSTER_1        0x18480
+#define VID_F_UP_CLUSTER_2        0x18A20
+#define VID_F_UP_CLUSTER_3        0x18FC0
+#define VID_F_UP_CLUSTER_4        0x19560
+
+#define VID_I_UP_CLUSTER_1        0x19B00
+#define VID_I_UP_CLUSTER_2        0x1A0A0
+#define VID_I_UP_CLUSTER_3        0x1A640
+#define VID_I_UP_CLUSTER_4        0x1ABE0
+
+#define VID_J_UP_CLUSTER_1        0x1B180
+#define VID_J_UP_CLUSTER_2        0x1B720
+#define VID_J_UP_CLUSTER_3        0x1BCC0
+#define VID_J_UP_CLUSTER_4        0x1C260
+
+#define AUD_A_UP_CLUSTER_1        0x1C800
+#define AUD_A_UP_CLUSTER_2        0x1C880
+#define AUD_A_UP_CLUSTER_3        0x1C900
+
+#define AUD_B_UP_CLUSTER_1        0x1C980
+#define AUD_B_UP_CLUSTER_2        0x1CA00
+#define AUD_B_UP_CLUSTER_3        0x1CA80
+
+#define AUD_C_UP_CLUSTER_1        0x1CB00
+#define AUD_C_UP_CLUSTER_2        0x1CB80
+#define AUD_C_UP_CLUSTER_3        0x1CC00
+
+#define AUD_E_UP_CLUSTER_1        0x1CC80
+#define AUD_E_UP_CLUSTER_2        0x1CD00
+#define AUD_E_UP_CLUSTER_3        0x1CD80
+
+#define RX_SRAM_POOL_FREE         0x1CE00
+#define RX_SRAM_END               0x1D000
+
+// Free Receive SRAM    144 Bytes
+
+// Transmit SRAM
+#define TX_SRAM_POOL_START        0x00000
+
+#define VID_A_DOWN_CLUSTER_1      0x00040
+#define VID_A_DOWN_CLUSTER_2      0x005E0
+#define VID_A_DOWN_CLUSTER_3      0x00B80
+#define VID_A_DOWN_CLUSTER_4      0x01120
+
+#define VID_B_DOWN_CLUSTER_1      0x016C0
+#define VID_B_DOWN_CLUSTER_2      0x01C60
+#define VID_B_DOWN_CLUSTER_3      0x02200
+#define VID_B_DOWN_CLUSTER_4      0x027A0
+
+#define VID_C_DOWN_CLUSTER_1      0x02D40
+#define VID_C_DOWN_CLUSTER_2      0x032E0
+#define VID_C_DOWN_CLUSTER_3      0x03880
+#define VID_C_DOWN_CLUSTER_4      0x03E20
+
+#define VID_D_DOWN_CLUSTER_1      0x043C0
+#define VID_D_DOWN_CLUSTER_2      0x04960
+#define VID_D_DOWN_CLUSTER_3      0x04F00
+#define VID_D_DOWN_CLUSTER_4      0x054A0
+
+#define VID_E_DOWN_CLUSTER_1      0x05a40
+#define VID_E_DOWN_CLUSTER_2      0x05FE0
+#define VID_E_DOWN_CLUSTER_3      0x06580
+#define VID_E_DOWN_CLUSTER_4      0x06B20
+
+#define VID_F_DOWN_CLUSTER_1      0x070C0
+#define VID_F_DOWN_CLUSTER_2      0x07660
+#define VID_F_DOWN_CLUSTER_3      0x07C00
+#define VID_F_DOWN_CLUSTER_4      0x081A0
+
+#define VID_G_DOWN_CLUSTER_1      0x08740
+#define VID_G_DOWN_CLUSTER_2      0x08CE0
+#define VID_G_DOWN_CLUSTER_3      0x09280
+#define VID_G_DOWN_CLUSTER_4      0x09820
+
+#define VID_H_DOWN_CLUSTER_1      0x09DC0
+#define VID_H_DOWN_CLUSTER_2      0x0A360
+#define VID_H_DOWN_CLUSTER_3      0x0A900
+#define VID_H_DOWN_CLUSTER_4      0x0AEA0
+
+#define AUD_A_DOWN_CLUSTER_1      0x0B500
+#define AUD_A_DOWN_CLUSTER_2      0x0B580
+#define AUD_A_DOWN_CLUSTER_3      0x0B600
+
+#define AUD_B_DOWN_CLUSTER_1      0x0B680
+#define AUD_B_DOWN_CLUSTER_2      0x0B700
+#define AUD_B_DOWN_CLUSTER_3      0x0B780
+
+#define AUD_C_DOWN_CLUSTER_1      0x0B800
+#define AUD_C_DOWN_CLUSTER_2      0x0B880
+#define AUD_C_DOWN_CLUSTER_3      0x0B900
+
+#define AUD_D_DOWN_CLUSTER_1      0x0B980
+#define AUD_D_DOWN_CLUSTER_2      0x0BA00
+#define AUD_D_DOWN_CLUSTER_3      0x0BA80
+
+#define TX_SRAM_POOL_FREE         0x0BB00
+#define TX_SRAM_END               0x0C000
+
+#define BYTES_TO_DWORDS(bcount) ((bcount) >> 2)
+#define BYTES_TO_QWORDS(bcount) ((bcount) >> 3)
+#define BYTES_TO_OWORDS(bcount) ((bcount) >> 4)
+
+#define VID_IQ_SIZE_DW             BYTES_TO_DWORDS(VID_IQ_SIZE)
+#define VID_CDT_SIZE_QW            BYTES_TO_QWORDS(VID_CDT_SIZE)
+#define VID_CLUSTER_SIZE_OW        BYTES_TO_OWORDS(VID_CLUSTER_SIZE)
+
+#define AUDIO_IQ_SIZE_DW           BYTES_TO_DWORDS(AUDIO_IQ_SIZE)
+#define AUDIO_CDT_SIZE_QW          BYTES_TO_QWORDS(AUDIO_CDT_SIZE)
+#define AUDIO_CLUSTER_SIZE_QW      BYTES_TO_QWORDS(AUDIO_CLUSTER_SIZE)
+
+#define MBIF_IQ_SIZE_DW            BYTES_TO_DWORDS(MBIF_IQ_SIZE)
+#define MBIF_CDT_SIZE_QW           BYTES_TO_QWORDS(MBIF_CDT_SIZE)
+#define MBIF_CLUSTER_SIZE_OW       BYTES_TO_OWORDS(MBIF_CLUSTER_SIZE)
+
+#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
new file mode 100644
index 0000000..c8905e0
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -0,0 +1,835 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.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.
+ */
+
+#include "cx25821-video.h"
+#include "cx25821-video-upstream-ch2.h"
+
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <asm/uaccess.h>
+
+MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
+MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
+MODULE_LICENSE("GPL");
+
+static int _intr_msk =
+    FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
+
+static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev,
+					      __le32 * rp, unsigned int offset,
+					      unsigned int bpl, u32 sync_line,
+					      unsigned int lines,
+					      int fifo_enable, int field_type)
+{
+	unsigned int line, i;
+	int dist_betwn_starts = bpl * 2;
+
+	*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
+
+	if (USE_RISC_NOOP_VIDEO) {
+		for (i = 0; i < NUM_NO_OPS; i++) {
+			*(rp++) = cpu_to_le32(RISC_NOOP);
+		}
+	}
+
+	/* scan lines */
+	for (line = 0; line < lines; line++) {
+		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
+		*(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset);
+		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+
+		if ((lines <= NTSC_FIELD_HEIGHT)
+		    || (line < (NTSC_FIELD_HEIGHT - 1))
+		    || !(dev->_isNTSC_ch2)) {
+			offset += dist_betwn_starts;
+		}
+	}
+
+	return rp;
+}
+
+static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
+					       __le32 * rp,
+					       dma_addr_t databuf_phys_addr,
+					       unsigned int offset,
+					       u32 sync_line, unsigned int bpl,
+					       unsigned int lines,
+					       int fifo_enable, int field_type)
+{
+	unsigned int line, i;
+	struct sram_channel *sram_ch =
+	    &dev->sram_channels[dev->_channel2_upstream_select];
+	int dist_betwn_starts = bpl * 2;
+
+	/* sync instruction */
+	if (sync_line != NO_SYNC_LINE) {
+		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
+	}
+
+	if (USE_RISC_NOOP_VIDEO) {
+		for (i = 0; i < NUM_NO_OPS; i++) {
+			*(rp++) = cpu_to_le32(RISC_NOOP);
+		}
+	}
+
+	/* scan lines */
+	for (line = 0; line < lines; line++) {
+		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
+		*(rp++) = cpu_to_le32(databuf_phys_addr + offset);
+		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+
+		if ((lines <= NTSC_FIELD_HEIGHT)
+		    || (line < (NTSC_FIELD_HEIGHT - 1))
+		    || !(dev->_isNTSC_ch2)) {
+			offset += dist_betwn_starts;
+		}
+
+		// check if we need to enable the FIFO after the first 4 lines
+		// For the upstream video channel, the risc engine will enable the FIFO.
+		if (fifo_enable && line == 3) {
+			*(rp++) = RISC_WRITECR;
+			*(rp++) = sram_ch->dma_ctl;
+			*(rp++) = FLD_VID_FIFO_EN;
+			*(rp++) = 0x00000001;
+		}
+	}
+
+	return rp;
+}
+
+int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
+				     struct pci_dev *pci,
+				     unsigned int top_offset, unsigned int bpl,
+				     unsigned int lines)
+{
+	__le32 *rp;
+	int fifo_enable = 0;
+	int singlefield_lines = lines >> 1;	//get line count for single field
+	int odd_num_lines = singlefield_lines;
+	int frame = 0;
+	int frame_size = 0;
+	int databuf_offset = 0;
+	int risc_program_size = 0;
+	int risc_flag = RISC_CNT_RESET;
+	unsigned int bottom_offset = bpl;
+	dma_addr_t risc_phys_jump_addr;
+
+	if (dev->_isNTSC_ch2) {
+		odd_num_lines = singlefield_lines + 1;
+		risc_program_size = FRAME1_VID_PROG_SIZE;
+		frame_size =
+		    (bpl ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
+		    FRAME_SIZE_NTSC_Y422;
+	} else {
+		risc_program_size = PAL_VID_PROG_SIZE;
+		frame_size =
+		    (bpl ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
+	}
+
+	/* Virtual address of Risc buffer program */
+	rp = dev->_dma_virt_addr_ch2;
+
+	for (frame = 0; frame < NUM_FRAMES; frame++) {
+		databuf_offset = frame_size * frame;
+
+		if (UNSET != top_offset) {
+			fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
+			rp = cx25821_risc_field_upstream_ch2(dev, rp,
+							     dev->
+							     _data_buf_phys_addr_ch2
+							     + databuf_offset,
+							     top_offset, 0, bpl,
+							     odd_num_lines,
+							     fifo_enable,
+							     ODD_FIELD);
+		}
+
+		fifo_enable = FIFO_DISABLE;
+
+		//Even field
+		rp = cx25821_risc_field_upstream_ch2(dev, rp,
+						     dev->
+						     _data_buf_phys_addr_ch2 +
+						     databuf_offset,
+						     bottom_offset, 0x200, bpl,
+						     singlefield_lines,
+						     fifo_enable, EVEN_FIELD);
+
+		if (frame == 0) {
+			risc_flag = RISC_CNT_RESET;
+			risc_phys_jump_addr =
+			    dev->_dma_phys_start_addr_ch2 + risc_program_size;
+		} else {
+			risc_flag = RISC_CNT_INC;
+			risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
+		}
+
+		// Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
+		*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
+		*(rp++) = cpu_to_le32(risc_phys_jump_addr);
+		*(rp++) = cpu_to_le32(0);
+	}
+
+	return 0;
+}
+
+void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
+{
+	struct sram_channel *sram_ch =
+	    &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_J];
+	u32 tmp = 0;
+
+	if (!dev->_is_running_ch2) {
+		printk
+		    ("cx25821: No video file is currently running so return!\n");
+		return;
+	}
+	//Disable RISC interrupts
+	tmp = cx_read(sram_ch->int_msk);
+	cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
+
+	//Turn OFF risc and fifo
+	tmp = cx_read(sram_ch->dma_ctl);
+	cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
+
+	//Clear data buffer memory
+	if (dev->_data_buf_virt_addr_ch2)
+		memset(dev->_data_buf_virt_addr_ch2, 0,
+		       dev->_data_buf_size_ch2);
+
+	dev->_is_running_ch2 = 0;
+	dev->_is_first_frame_ch2 = 0;
+	dev->_frame_count_ch2 = 0;
+	dev->_file_status_ch2 = END_OF_FILE;
+
+	if (dev->_irq_queues_ch2) {
+		kfree(dev->_irq_queues_ch2);
+		dev->_irq_queues_ch2 = NULL;
+	}
+
+	if (dev->_filename_ch2 != NULL)
+		kfree(dev->_filename_ch2);
+
+	tmp = cx_read(VID_CH_MODE_SEL);
+	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
+}
+
+void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
+{
+	if (dev->_is_running_ch2) {
+		cx25821_stop_upstream_video_ch2(dev);
+	}
+
+	if (dev->_dma_virt_addr_ch2) {
+		pci_free_consistent(dev->pci, dev->_risc_size_ch2,
+				    dev->_dma_virt_addr_ch2,
+				    dev->_dma_phys_addr_ch2);
+		dev->_dma_virt_addr_ch2 = NULL;
+	}
+
+	if (dev->_data_buf_virt_addr_ch2) {
+		pci_free_consistent(dev->pci, dev->_data_buf_size_ch2,
+				    dev->_data_buf_virt_addr_ch2,
+				    dev->_data_buf_phys_addr_ch2);
+		dev->_data_buf_virt_addr_ch2 = NULL;
+	}
+}
+
+int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+{
+	struct file *myfile;
+	int frame_index_temp = dev->_frame_index_ch2;
+	int i = 0;
+	int line_size =
+	    (dev->_pixel_format_ch2 ==
+	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	int frame_size = 0;
+	int frame_offset = 0;
+	ssize_t vfs_read_retval = 0;
+	char mybuf[line_size];
+	loff_t file_offset;
+	loff_t pos;
+	mm_segment_t old_fs;
+
+	if (dev->_file_status_ch2 == END_OF_FILE)
+		return 0;
+
+	if (dev->_isNTSC_ch2) {
+		frame_size =
+		    (line_size ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
+		    FRAME_SIZE_NTSC_Y422;
+	} else {
+		frame_size =
+		    (line_size ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
+	}
+
+	frame_offset = (frame_index_temp > 0) ? frame_size : 0;
+	file_offset = dev->_frame_count_ch2 * frame_size;
+
+	myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
+
+	if (IS_ERR(myfile)) {
+		const int open_errno = -PTR_ERR(myfile);
+		printk("%s(): ERROR opening file(%s) with errno = %d! \n",
+		       __func__, dev->_filename_ch2, open_errno);
+		return PTR_ERR(myfile);
+	} else {
+		if (!(myfile->f_op)) {
+			printk("%s: File has no file operations registered!",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		if (!myfile->f_op->read) {
+			printk("%s: File has no READ operations registered!",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		pos = myfile->f_pos;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		for (i = 0; i < dev->_lines_count_ch2; i++) {
+			pos = file_offset;
+
+			vfs_read_retval =
+			    vfs_read(myfile, mybuf, line_size, &pos);
+
+			if (vfs_read_retval > 0 && vfs_read_retval == line_size
+			    && dev->_data_buf_virt_addr_ch2 != NULL) {
+				memcpy((void *)(dev->_data_buf_virt_addr_ch2 +
+						frame_offset / 4), mybuf,
+				       vfs_read_retval);
+			}
+
+			file_offset += vfs_read_retval;
+			frame_offset += vfs_read_retval;
+
+			if (vfs_read_retval < line_size) {
+				printk(KERN_INFO
+				       "Done: exit %s() since no more bytes to read from Video file.\n",
+				       __func__);
+				break;
+			}
+		}
+
+		if (i > 0)
+			dev->_frame_count_ch2++;
+
+		dev->_file_status_ch2 =
+		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+
+		set_fs(old_fs);
+		filp_close(myfile, NULL);
+	}
+
+	return 0;
+}
+
+static void cx25821_vidups_handler_ch2(struct work_struct *work)
+{
+	struct cx25821_dev *dev =
+	    container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
+
+	if (!dev) {
+		printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
+		       __func__);
+		return;
+	}
+
+	cx25821_get_frame_ch2(dev,
+			      &dev->sram_channels[dev->
+						  _channel2_upstream_select]);
+}
+
+int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+{
+	struct file *myfile;
+	int i = 0, j = 0;
+	int line_size =
+	    (dev->_pixel_format_ch2 ==
+	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	ssize_t vfs_read_retval = 0;
+	char mybuf[line_size];
+	loff_t pos;
+	loff_t offset = (unsigned long)0;
+	mm_segment_t old_fs;
+
+	myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
+
+	if (IS_ERR(myfile)) {
+		const int open_errno = -PTR_ERR(myfile);
+		printk("%s(): ERROR opening file(%s) with errno = %d! \n",
+		       __func__, dev->_filename_ch2, open_errno);
+		return PTR_ERR(myfile);
+	} else {
+		if (!(myfile->f_op)) {
+			printk("%s: File has no file operations registered!",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		if (!myfile->f_op->read) {
+			printk
+			    ("%s: File has no READ operations registered!  Returning.",
+			     __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		pos = myfile->f_pos;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		for (j = 0; j < NUM_FRAMES; j++) {
+			for (i = 0; i < dev->_lines_count_ch2; i++) {
+				pos = offset;
+
+				vfs_read_retval =
+				    vfs_read(myfile, mybuf, line_size, &pos);
+
+				if (vfs_read_retval > 0
+				    && vfs_read_retval == line_size
+				    && dev->_data_buf_virt_addr_ch2 != NULL) {
+					memcpy((void *)(dev->
+							_data_buf_virt_addr_ch2
+							+ offset / 4), mybuf,
+					       vfs_read_retval);
+				}
+
+				offset += vfs_read_retval;
+
+				if (vfs_read_retval < line_size) {
+					printk(KERN_INFO
+					       "Done: exit %s() since no more bytes to read from Video file.\n",
+					       __func__);
+					break;
+				}
+			}
+
+			if (i > 0)
+				dev->_frame_count_ch2++;
+
+			if (vfs_read_retval < line_size) {
+				break;
+			}
+		}
+
+		dev->_file_status_ch2 =
+		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+
+		set_fs(old_fs);
+		myfile->f_pos = 0;
+		filp_close(myfile, NULL);
+	}
+
+	return 0;
+}
+
+static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
+					       struct sram_channel *sram_ch,
+					       int bpl)
+{
+	int ret = 0;
+	dma_addr_t dma_addr;
+	dma_addr_t data_dma_addr;
+
+	if (dev->_dma_virt_addr_ch2 != NULL) {
+		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
+				    dev->_dma_virt_addr_ch2,
+				    dev->_dma_phys_addr_ch2);
+	}
+
+	dev->_dma_virt_addr_ch2 =
+	    pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
+				 &dma_addr);
+	dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
+	dev->_dma_phys_start_addr_ch2 = dma_addr;
+	dev->_dma_phys_addr_ch2 = dma_addr;
+	dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
+
+	if (!dev->_dma_virt_addr_ch2) {
+		printk
+		    ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
+		return -ENOMEM;
+	}
+
+	//Iniitize at this address until n bytes to 0
+	memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2);
+
+	if (dev->_data_buf_virt_addr_ch2 != NULL) {
+		pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2,
+				    dev->_data_buf_virt_addr_ch2,
+				    dev->_data_buf_phys_addr_ch2);
+	}
+	//For Video Data buffer allocation
+	dev->_data_buf_virt_addr_ch2 =
+	    pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2,
+				 &data_dma_addr);
+	dev->_data_buf_phys_addr_ch2 = data_dma_addr;
+	dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
+
+	if (!dev->_data_buf_virt_addr_ch2) {
+		printk
+		    ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
+		return -ENOMEM;
+	}
+
+	//Initialize at this address until n bytes to 0
+	memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2);
+
+	ret = cx25821_openfile_ch2(dev, sram_ch);
+	if (ret < 0)
+		return ret;
+
+	//Creating RISC programs
+	ret =
+	    cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
+					     dev->_lines_count_ch2);
+	if (ret < 0) {
+		printk(KERN_INFO
+		       "cx25821: Failed creating Video Upstream Risc programs! \n");
+		goto error;
+	}
+
+	return 0;
+
+      error:
+	return ret;
+}
+
+int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
+				   u32 status)
+{
+	u32 int_msk_tmp;
+	struct sram_channel *channel = &dev->sram_channels[chan_num];
+	int singlefield_lines = NTSC_FIELD_HEIGHT;
+	int line_size_in_bytes = Y422_LINE_SZ;
+	int odd_risc_prog_size = 0;
+	dma_addr_t risc_phys_jump_addr;
+	__le32 *rp;
+
+	if (status & FLD_VID_SRC_RISC1) {
+		// We should only process one program per call
+		u32 prog_cnt = cx_read(channel->gpcnt);
+
+		//Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
+		int_msk_tmp = cx_read(channel->int_msk);
+		cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
+		cx_write(channel->int_stat, _intr_msk);
+
+		spin_lock(&dev->slock);
+
+		dev->_frame_index_ch2 = prog_cnt;
+
+		queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2);
+
+		if (dev->_is_first_frame_ch2) {
+			dev->_is_first_frame_ch2 = 0;
+
+			if (dev->_isNTSC_ch2) {
+				singlefield_lines += 1;
+				odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
+			} else {
+				singlefield_lines = PAL_FIELD_HEIGHT;
+				odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
+			}
+
+			if (dev->_dma_virt_start_addr_ch2 != NULL) {
+				line_size_in_bytes =
+				    (dev->_pixel_format_ch2 ==
+				     PIXEL_FRMT_411) ? Y411_LINE_SZ :
+				    Y422_LINE_SZ;
+				risc_phys_jump_addr =
+				    dev->_dma_phys_start_addr_ch2 +
+				    odd_risc_prog_size;
+
+				rp = cx25821_update_riscprogram_ch2(dev,
+								    dev->
+								    _dma_virt_start_addr_ch2,
+								    TOP_OFFSET,
+								    line_size_in_bytes,
+								    0x0,
+								    singlefield_lines,
+								    FIFO_DISABLE,
+								    ODD_FIELD);
+
+				// Jump to Even Risc program of 1st Frame
+				*(rp++) = cpu_to_le32(RISC_JUMP);
+				*(rp++) = cpu_to_le32(risc_phys_jump_addr);
+				*(rp++) = cpu_to_le32(0);
+			}
+		}
+
+		spin_unlock(&dev->slock);
+	}
+
+	if (dev->_file_status_ch2 == END_OF_FILE) {
+		printk("cx25821: EOF Channel 2 Framecount = %d\n",
+		       dev->_frame_count_ch2);
+		return -1;
+	}
+	//ElSE, set the interrupt mask register, re-enable irq.
+	int_msk_tmp = cx_read(channel->int_msk);
+	cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
+
+	return 0;
+}
+
+static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
+{
+	struct cx25821_dev *dev = dev_id;
+	u32 msk_stat, vid_status;
+	int handled = 0;
+	int channel_num = 0;
+	struct sram_channel *sram_ch;
+
+	if (!dev)
+		return -1;
+
+	channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
+
+	sram_ch = &dev->sram_channels[channel_num];
+
+	msk_stat = cx_read(sram_ch->int_mstat);
+	vid_status = cx_read(sram_ch->int_stat);
+
+	// Only deal with our interrupt
+	if (vid_status) {
+		handled =
+		    cx25821_video_upstream_irq_ch2(dev, channel_num,
+						   vid_status);
+	}
+
+	if (handled < 0) {
+		cx25821_stop_upstream_video_ch2(dev);
+	} else {
+		handled += handled;
+	}
+
+	return IRQ_RETVAL(handled);
+}
+
+static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
+					struct sram_channel *ch, int pix_format)
+{
+	int width = WIDTH_D1;
+	int height = dev->_lines_count_ch2;
+	int num_lines, odd_num_lines;
+	u32 value;
+	int vip_mode = PIXEL_ENGINE_VIP1;
+
+	value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
+	value &= 0xFFFFFFEF;
+	value |= dev->_isNTSC_ch2 ? 0 : 0x10;
+	cx_write(ch->vid_fmt_ctl, value);
+
+	// set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
+	cx_write(ch->vid_active_ctl1, width);
+
+	num_lines = (height / 2) & 0x3FF;
+	odd_num_lines = num_lines;
+
+	if (dev->_isNTSC_ch2) {
+		odd_num_lines += 1;
+	}
+
+	value = (num_lines << 16) | odd_num_lines;
+
+	// set number of active lines in field 0 (top) and field 1 (bottom)
+	cx_write(ch->vid_active_ctl2, value);
+
+	cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
+}
+
+int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
+					 struct sram_channel *sram_ch)
+{
+	u32 tmp = 0;
+	int err = 0;
+
+	// 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
+	tmp = cx_read(VID_CH_MODE_SEL);
+	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
+
+	// Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
+	cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2);
+	cx_write(sram_ch->cmds_start + 4, 0);	/* Risc IPC High 64 bits 63-32 */
+
+	/* reset counter */
+	cx_write(sram_ch->gpcnt_ctl, 3);
+
+	// Clear our bits from the interrupt status register.
+	cx_write(sram_ch->int_stat, _intr_msk);
+
+	//Set the interrupt mask register, enable irq.
+	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
+	tmp = cx_read(sram_ch->int_msk);
+	cx_write(sram_ch->int_msk, tmp |= _intr_msk);
+
+	err =
+	    request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
+			IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+	if (err < 0) {
+		printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
+		       dev->pci->irq);
+		goto fail_irq;
+	}
+	// Start the DMA  engine
+	tmp = cx_read(sram_ch->dma_ctl);
+	cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
+
+	dev->_is_running_ch2 = 1;
+	dev->_is_first_frame_ch2 = 1;
+
+	return 0;
+
+      fail_irq:
+	cx25821_dev_unregister(dev);
+	return err;
+}
+
+int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
+				 int pixel_format)
+{
+	struct sram_channel *sram_ch;
+	u32 tmp;
+	int retval = 0;
+	int err = 0;
+	int data_frame_size = 0;
+	int risc_buffer_size = 0;
+	int str_length = 0;
+
+	if (dev->_is_running_ch2) {
+		printk("Video Channel is still running so return!\n");
+		return 0;
+	}
+
+	dev->_channel2_upstream_select = channel_select;
+	sram_ch = &dev->sram_channels[channel_select];
+
+	INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
+	dev->_irq_queues_ch2 =
+	    create_singlethread_workqueue("cx25821_workqueue2");
+
+	if (!dev->_irq_queues_ch2) {
+		printk
+		    ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
+		return -ENOMEM;
+	}
+	// 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
+	tmp = cx_read(VID_CH_MODE_SEL);
+	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
+
+	dev->_is_running_ch2 = 0;
+	dev->_frame_count_ch2 = 0;
+	dev->_file_status_ch2 = RESET_STATUS;
+	dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
+	dev->_pixel_format_ch2 = pixel_format;
+	dev->_line_size_ch2 =
+	    (dev->_pixel_format_ch2 ==
+	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
+	data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
+	risc_buffer_size =
+	    dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
+
+	if (dev->input_filename_ch2) {
+		str_length = strlen(dev->input_filename_ch2);
+		dev->_filename_ch2 =
+		    (char *)kmalloc(str_length + 1, GFP_KERNEL);
+
+		if (!dev->_filename_ch2)
+			goto error;
+
+		memcpy(dev->_filename_ch2, dev->input_filename_ch2,
+		       str_length + 1);
+	} else {
+		str_length = strlen(dev->_defaultname_ch2);
+		dev->_filename_ch2 =
+		    (char *)kmalloc(str_length + 1, GFP_KERNEL);
+
+		if (!dev->_filename_ch2)
+			goto error;
+
+		memcpy(dev->_filename_ch2, dev->_defaultname_ch2,
+		       str_length + 1);
+	}
+
+	//Default if filename is empty string
+	if (strcmp(dev->input_filename_ch2, "") == 0) {
+		if (dev->_isNTSC_ch2) {
+			dev->_filename_ch2 =
+			    (dev->_pixel_format_ch2 ==
+			     PIXEL_FRMT_411) ? "/root/vid411.yuv" :
+			    "/root/vidtest.yuv";
+		} else {
+			dev->_filename_ch2 =
+			    (dev->_pixel_format_ch2 ==
+			     PIXEL_FRMT_411) ? "/root/pal411.yuv" :
+			    "/root/pal422.yuv";
+		}
+	}
+
+	retval =
+	    cx25821_sram_channel_setup_upstream(dev, sram_ch,
+						dev->_line_size_ch2, 0);
+
+	/* setup fifo + format */
+	cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2);
+
+	dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
+	dev->upstream_databuf_size_ch2 = data_frame_size * 2;
+
+	//Allocating buffers and prepare RISC program
+	retval =
+	    cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
+						dev->_line_size_ch2);
+	if (retval < 0) {
+		printk(KERN_ERR
+		       "%s: Failed to set up Video upstream buffers!\n",
+		       dev->name);
+		goto error;
+	}
+
+	cx25821_start_video_dma_upstream_ch2(dev, sram_ch);
+
+	return 0;
+
+      error:
+	cx25821_dev_unregister(dev);
+
+	return err;
+}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
new file mode 100644
index 0000000..73feea1
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
@@ -0,0 +1,101 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.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.
+ */
+
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#define OPEN_FILE_1           0
+#define NUM_PROGS             8
+#define NUM_FRAMES            2
+#define ODD_FIELD             0
+#define EVEN_FIELD            1
+#define TOP_OFFSET            0
+#define FIFO_DISABLE          0
+#define FIFO_ENABLE           1
+#define TEST_FRAMES           5
+#define END_OF_FILE           0
+#define IN_PROGRESS           1
+#define RESET_STATUS          -1
+#define NUM_NO_OPS            5
+
+// PAL and NTSC line sizes and number of lines.
+#define WIDTH_D1              720
+#define NTSC_LINES_PER_FRAME  480
+#define PAL_LINES_PER_FRAME   576
+#define PAL_LINE_SZ           1440
+#define Y422_LINE_SZ          1440
+#define Y411_LINE_SZ          1080
+#define NTSC_FIELD_HEIGHT     240
+#define NTSC_ODD_FLD_LINES    241
+#define PAL_FIELD_HEIGHT      288
+
+#define FRAME_SIZE_NTSC_Y422    (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
+#define FRAME_SIZE_NTSC_Y411    (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
+#define FRAME_SIZE_PAL_Y422     (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
+#define FRAME_SIZE_PAL_Y411     (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
+
+#define NTSC_DATA_BUF_SZ        (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
+#define PAL_DATA_BUF_SZ         (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
+
+#define RISC_WRITECR_INSTRUCTION_SIZE   16
+#define RISC_SYNC_INSTRUCTION_SIZE      4
+#define JUMP_INSTRUCTION_SIZE           12
+#define MAXSIZE_NO_OPS                  36
+#define DWORD_SIZE                      4
+
+#define USE_RISC_NOOP_VIDEO   1
+
+#ifdef USE_RISC_NOOP_VIDEO
+#define PAL_US_VID_PROG_SIZE      ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE +   \
+				    RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+
+#define PAL_RISC_BUF_SIZE         (2 * PAL_US_VID_PROG_SIZE)
+
+#define PAL_VID_PROG_SIZE         ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				    RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
+
+#define ODD_FLD_PAL_PROG_SIZE     ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
+				    RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+
+#define NTSC_US_VID_PROG_SIZE     ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
+				    JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+
+#define NTSC_RISC_BUF_SIZE        (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
+
+#define FRAME1_VID_PROG_SIZE      ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				    RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
+#define ODD_FLD_NTSC_PROG_SIZE    ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
+				    RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+#endif
+
+#ifndef USE_RISC_NOOP_VIDEO
+#define PAL_US_VID_PROG_SIZE      ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
+#define PAL_RISC_BUF_SIZE         ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE) )
+#define PAL_VID_PROG_SIZE         ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				    RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
+#define ODD_FLD_PAL_PROG_SIZE     ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
+#define ODD_FLD_NTSC_PROG_SIZE    ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
+#define NTSC_US_VID_PROG_SIZE     ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
+#define NTSC_RISC_BUF_SIZE        (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
+#define FRAME1_VID_PROG_SIZE      ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				    RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
+#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
new file mode 100644
index 0000000..3d7dd3f
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -0,0 +1,894 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.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.
+ */
+
+#include "cx25821-video.h"
+#include "cx25821-video-upstream.h"
+
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <asm/uaccess.h>
+
+MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
+MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
+MODULE_LICENSE("GPL");
+
+static int _intr_msk =
+    FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
+
+int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
+					struct sram_channel *ch,
+					unsigned int bpl, u32 risc)
+{
+	unsigned int i, lines;
+	u32 cdt;
+
+	if (ch->cmds_start == 0) {
+		cx_write(ch->ptr1_reg, 0);
+		cx_write(ch->ptr2_reg, 0);
+		cx_write(ch->cnt2_reg, 0);
+		cx_write(ch->cnt1_reg, 0);
+		return 0;
+	}
+
+	bpl = (bpl + 7) & ~7;	/* alignment */
+	cdt = ch->cdt;
+	lines = ch->fifo_size / bpl;
+
+	if (lines > 4) {
+		lines = 4;
+	}
+
+	BUG_ON(lines < 2);
+
+	/* write CDT */
+	for (i = 0; i < lines; i++) {
+		cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
+		cx_write(cdt + 16 * i + 4, 0);
+		cx_write(cdt + 16 * i + 8, 0);
+		cx_write(cdt + 16 * i + 12, 0);
+	}
+
+	/* write CMDS */
+	cx_write(ch->cmds_start + 0, risc);
+
+	cx_write(ch->cmds_start + 4, 0);
+	cx_write(ch->cmds_start + 8, cdt);
+	cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
+	cx_write(ch->cmds_start + 16, ch->ctrl_start);
+
+	cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
+
+	for (i = 24; i < 80; i += 4)
+		cx_write(ch->cmds_start + i, 0);
+
+	/* fill registers */
+	cx_write(ch->ptr1_reg, ch->fifo_start);
+	cx_write(ch->ptr2_reg, cdt);
+	cx_write(ch->cnt2_reg, (lines * 16) >> 3);
+	cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
+
+	return 0;
+}
+
+static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
+					  __le32 * rp, unsigned int offset,
+					  unsigned int bpl, u32 sync_line,
+					  unsigned int lines, int fifo_enable,
+					  int field_type)
+{
+	unsigned int line, i;
+	int dist_betwn_starts = bpl * 2;
+
+	*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
+
+	if (USE_RISC_NOOP_VIDEO) {
+		for (i = 0; i < NUM_NO_OPS; i++) {
+			*(rp++) = cpu_to_le32(RISC_NOOP);
+		}
+	}
+
+	/* scan lines */
+	for (line = 0; line < lines; line++) {
+		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
+		*(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset);
+		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+
+		if ((lines <= NTSC_FIELD_HEIGHT)
+		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
+			offset += dist_betwn_starts;
+		}
+	}
+
+	return rp;
+}
+
+static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
+					   dma_addr_t databuf_phys_addr,
+					   unsigned int offset, u32 sync_line,
+					   unsigned int bpl, unsigned int lines,
+					   int fifo_enable, int field_type)
+{
+	unsigned int line, i;
+	struct sram_channel *sram_ch =
+	    &dev->sram_channels[dev->_channel_upstream_select];
+	int dist_betwn_starts = bpl * 2;
+
+	/* sync instruction */
+	if (sync_line != NO_SYNC_LINE) {
+		*(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
+	}
+
+	if (USE_RISC_NOOP_VIDEO) {
+		for (i = 0; i < NUM_NO_OPS; i++) {
+			*(rp++) = cpu_to_le32(RISC_NOOP);
+		}
+	}
+
+	/* scan lines */
+	for (line = 0; line < lines; line++) {
+		*(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
+		*(rp++) = cpu_to_le32(databuf_phys_addr + offset);
+		*(rp++) = cpu_to_le32(0);	/* bits 63-32 */
+
+		if ((lines <= NTSC_FIELD_HEIGHT)
+		    || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
+			offset += dist_betwn_starts;	//to skip the other field line
+		}
+
+		// check if we need to enable the FIFO after the first 4 lines
+		// For the upstream video channel, the risc engine will enable the FIFO.
+		if (fifo_enable && line == 3) {
+			*(rp++) = RISC_WRITECR;
+			*(rp++) = sram_ch->dma_ctl;
+			*(rp++) = FLD_VID_FIFO_EN;
+			*(rp++) = 0x00000001;
+		}
+	}
+
+	return rp;
+}
+
+int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
+				 struct pci_dev *pci,
+				 unsigned int top_offset,
+				 unsigned int bpl, unsigned int lines)
+{
+	__le32 *rp;
+	int fifo_enable = 0;
+	int singlefield_lines = lines >> 1;	//get line count for single field
+	int odd_num_lines = singlefield_lines;
+	int frame = 0;
+	int frame_size = 0;
+	int databuf_offset = 0;
+	int risc_program_size = 0;
+	int risc_flag = RISC_CNT_RESET;
+	unsigned int bottom_offset = bpl;
+	dma_addr_t risc_phys_jump_addr;
+
+	if (dev->_isNTSC) {
+		odd_num_lines = singlefield_lines + 1;
+		risc_program_size = FRAME1_VID_PROG_SIZE;
+		frame_size =
+		    (bpl ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
+		    FRAME_SIZE_NTSC_Y422;
+	} else {
+		risc_program_size = PAL_VID_PROG_SIZE;
+		frame_size =
+		    (bpl ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
+	}
+
+	/* Virtual address of Risc buffer program */
+	rp = dev->_dma_virt_addr;
+
+	for (frame = 0; frame < NUM_FRAMES; frame++) {
+		databuf_offset = frame_size * frame;
+
+		if (UNSET != top_offset) {
+			fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
+			rp = cx25821_risc_field_upstream(dev, rp,
+							 dev->
+							 _data_buf_phys_addr +
+							 databuf_offset,
+							 top_offset, 0, bpl,
+							 odd_num_lines,
+							 fifo_enable,
+							 ODD_FIELD);
+		}
+
+		fifo_enable = FIFO_DISABLE;
+
+		//Even Field
+		rp = cx25821_risc_field_upstream(dev, rp,
+						 dev->_data_buf_phys_addr +
+						 databuf_offset, bottom_offset,
+						 0x200, bpl, singlefield_lines,
+						 fifo_enable, EVEN_FIELD);
+
+		if (frame == 0) {
+			risc_flag = RISC_CNT_RESET;
+			risc_phys_jump_addr =
+			    dev->_dma_phys_start_addr + risc_program_size;
+		} else {
+			risc_phys_jump_addr = dev->_dma_phys_start_addr;
+			risc_flag = RISC_CNT_INC;
+		}
+
+		// Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
+		*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
+		*(rp++) = cpu_to_le32(risc_phys_jump_addr);
+		*(rp++) = cpu_to_le32(0);
+	}
+
+	return 0;
+}
+
+void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
+{
+	struct sram_channel *sram_ch =
+	    &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_I];
+	u32 tmp = 0;
+
+	if (!dev->_is_running) {
+		printk
+		    ("cx25821: No video file is currently running so return!\n");
+		return;
+	}
+	//Disable RISC interrupts
+	tmp = cx_read(sram_ch->int_msk);
+	cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
+
+	//Turn OFF risc and fifo enable
+	tmp = cx_read(sram_ch->dma_ctl);
+	cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
+
+	//Clear data buffer memory
+	if (dev->_data_buf_virt_addr)
+		memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
+
+	dev->_is_running = 0;
+	dev->_is_first_frame = 0;
+	dev->_frame_count = 0;
+	dev->_file_status = END_OF_FILE;
+
+	if (dev->_irq_queues) {
+		kfree(dev->_irq_queues);
+		dev->_irq_queues = NULL;
+	}
+
+	if (dev->_filename != NULL)
+		kfree(dev->_filename);
+
+	tmp = cx_read(VID_CH_MODE_SEL);
+	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
+}
+
+void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
+{
+	if (dev->_is_running) {
+		cx25821_stop_upstream_video_ch1(dev);
+	}
+
+	if (dev->_dma_virt_addr) {
+		pci_free_consistent(dev->pci, dev->_risc_size,
+				    dev->_dma_virt_addr, dev->_dma_phys_addr);
+		dev->_dma_virt_addr = NULL;
+	}
+
+	if (dev->_data_buf_virt_addr) {
+		pci_free_consistent(dev->pci, dev->_data_buf_size,
+				    dev->_data_buf_virt_addr,
+				    dev->_data_buf_phys_addr);
+		dev->_data_buf_virt_addr = NULL;
+	}
+}
+
+int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+{
+	struct file *myfile;
+	int frame_index_temp = dev->_frame_index;
+	int i = 0;
+	int line_size =
+	    (dev->_pixel_format ==
+	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	int frame_size = 0;
+	int frame_offset = 0;
+	ssize_t vfs_read_retval = 0;
+	char mybuf[line_size];
+	loff_t file_offset;
+	loff_t pos;
+	mm_segment_t old_fs;
+
+	if (dev->_file_status == END_OF_FILE)
+		return 0;
+
+	if (dev->_isNTSC) {
+		frame_size =
+		    (line_size ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
+		    FRAME_SIZE_NTSC_Y422;
+	} else {
+		frame_size =
+		    (line_size ==
+		     Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
+	}
+
+	frame_offset = (frame_index_temp > 0) ? frame_size : 0;
+	file_offset = dev->_frame_count * frame_size;
+
+	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
+
+	if (IS_ERR(myfile)) {
+		const int open_errno = -PTR_ERR(myfile);
+		printk("%s(): ERROR opening file(%s) with errno = %d! \n",
+		       __func__, dev->_filename, open_errno);
+		return PTR_ERR(myfile);
+	} else {
+		if (!(myfile->f_op)) {
+			printk("%s: File has no file operations registered!",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		if (!myfile->f_op->read) {
+			printk("%s: File has no READ operations registered!",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		pos = myfile->f_pos;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		for (i = 0; i < dev->_lines_count; i++) {
+			pos = file_offset;
+
+			vfs_read_retval =
+			    vfs_read(myfile, mybuf, line_size, &pos);
+
+			if (vfs_read_retval > 0 && vfs_read_retval == line_size
+			    && dev->_data_buf_virt_addr != NULL) {
+				memcpy((void *)(dev->_data_buf_virt_addr +
+						frame_offset / 4), mybuf,
+				       vfs_read_retval);
+			}
+
+			file_offset += vfs_read_retval;
+			frame_offset += vfs_read_retval;
+
+			if (vfs_read_retval < line_size) {
+				printk(KERN_INFO
+				       "Done: exit %s() since no more bytes to read from Video file.\n",
+				       __func__);
+				break;
+			}
+		}
+
+		if (i > 0)
+			dev->_frame_count++;
+
+		dev->_file_status =
+		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+
+		set_fs(old_fs);
+		filp_close(myfile, NULL);
+	}
+
+	return 0;
+}
+
+static void cx25821_vidups_handler(struct work_struct *work)
+{
+	struct cx25821_dev *dev =
+	    container_of(work, struct cx25821_dev, _irq_work_entry);
+
+	if (!dev) {
+		printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
+		       __func__);
+		return;
+	}
+
+	cx25821_get_frame(dev,
+			  &dev->sram_channels[dev->_channel_upstream_select]);
+}
+
+int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
+{
+	struct file *myfile;
+	int i = 0, j = 0;
+	int line_size =
+	    (dev->_pixel_format ==
+	     PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
+	ssize_t vfs_read_retval = 0;
+	char mybuf[line_size];
+	loff_t pos;
+	loff_t offset = (unsigned long)0;
+	mm_segment_t old_fs;
+
+	myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
+
+	if (IS_ERR(myfile)) {
+		const int open_errno = -PTR_ERR(myfile);
+		printk("%s(): ERROR opening file(%s) with errno = %d! \n",
+		       __func__, dev->_filename, open_errno);
+		return PTR_ERR(myfile);
+	} else {
+		if (!(myfile->f_op)) {
+			printk("%s: File has no file operations registered!",
+			       __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		if (!myfile->f_op->read) {
+			printk
+			    ("%s: File has no READ operations registered!  Returning.",
+			     __func__);
+			filp_close(myfile, NULL);
+			return -EIO;
+		}
+
+		pos = myfile->f_pos;
+		old_fs = get_fs();
+		set_fs(KERNEL_DS);
+
+		for (j = 0; j < NUM_FRAMES; j++) {
+			for (i = 0; i < dev->_lines_count; i++) {
+				pos = offset;
+
+				vfs_read_retval =
+				    vfs_read(myfile, mybuf, line_size, &pos);
+
+				if (vfs_read_retval > 0
+				    && vfs_read_retval == line_size
+				    && dev->_data_buf_virt_addr != NULL) {
+					memcpy((void *)(dev->
+							_data_buf_virt_addr +
+							offset / 4), mybuf,
+					       vfs_read_retval);
+				}
+
+				offset += vfs_read_retval;
+
+				if (vfs_read_retval < line_size) {
+					printk(KERN_INFO
+					       "Done: exit %s() since no more bytes to read from Video file.\n",
+					       __func__);
+					break;
+				}
+			}
+
+			if (i > 0)
+				dev->_frame_count++;
+
+			if (vfs_read_retval < line_size) {
+				break;
+			}
+		}
+
+		dev->_file_status =
+		    (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
+
+		set_fs(old_fs);
+		myfile->f_pos = 0;
+		filp_close(myfile, NULL);
+	}
+
+	return 0;
+}
+
+int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
+				    struct sram_channel *sram_ch, int bpl)
+{
+	int ret = 0;
+	dma_addr_t dma_addr;
+	dma_addr_t data_dma_addr;
+
+	if (dev->_dma_virt_addr != NULL) {
+		pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
+				    dev->_dma_virt_addr, dev->_dma_phys_addr);
+	}
+
+	dev->_dma_virt_addr =
+	    pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size,
+				 &dma_addr);
+	dev->_dma_virt_start_addr = dev->_dma_virt_addr;
+	dev->_dma_phys_start_addr = dma_addr;
+	dev->_dma_phys_addr = dma_addr;
+	dev->_risc_size = dev->upstream_riscbuf_size;
+
+	if (!dev->_dma_virt_addr) {
+		printk
+		    ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
+		return -ENOMEM;
+	}
+
+	//Clear memory at address
+	memset(dev->_dma_virt_addr, 0, dev->_risc_size);
+
+	if (dev->_data_buf_virt_addr != NULL) {
+		pci_free_consistent(dev->pci, dev->upstream_databuf_size,
+				    dev->_data_buf_virt_addr,
+				    dev->_data_buf_phys_addr);
+	}
+	//For Video Data buffer allocation
+	dev->_data_buf_virt_addr =
+	    pci_alloc_consistent(dev->pci, dev->upstream_databuf_size,
+				 &data_dma_addr);
+	dev->_data_buf_phys_addr = data_dma_addr;
+	dev->_data_buf_size = dev->upstream_databuf_size;
+
+	if (!dev->_data_buf_virt_addr) {
+		printk
+		    ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
+		return -ENOMEM;
+	}
+
+	//Clear memory at address
+	memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
+
+	ret = cx25821_openfile(dev, sram_ch);
+	if (ret < 0)
+		return ret;
+
+	//Create RISC programs
+	ret =
+	    cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
+					 dev->_lines_count);
+	if (ret < 0) {
+		printk(KERN_INFO
+		       "cx25821: Failed creating Video Upstream Risc programs! \n");
+		goto error;
+	}
+
+	return 0;
+
+      error:
+	return ret;
+}
+
+int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
+			       u32 status)
+{
+	u32 int_msk_tmp;
+	struct sram_channel *channel = &dev->sram_channels[chan_num];
+	int singlefield_lines = NTSC_FIELD_HEIGHT;
+	int line_size_in_bytes = Y422_LINE_SZ;
+	int odd_risc_prog_size = 0;
+	dma_addr_t risc_phys_jump_addr;
+	__le32 *rp;
+
+	if (status & FLD_VID_SRC_RISC1) {
+		// We should only process one program per call
+		u32 prog_cnt = cx_read(channel->gpcnt);
+
+		//Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
+		int_msk_tmp = cx_read(channel->int_msk);
+		cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
+		cx_write(channel->int_stat, _intr_msk);
+
+		spin_lock(&dev->slock);
+
+		dev->_frame_index = prog_cnt;
+
+		queue_work(dev->_irq_queues, &dev->_irq_work_entry);
+
+		if (dev->_is_first_frame) {
+			dev->_is_first_frame = 0;
+
+			if (dev->_isNTSC) {
+				singlefield_lines += 1;
+				odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
+			} else {
+				singlefield_lines = PAL_FIELD_HEIGHT;
+				odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
+			}
+
+			if (dev->_dma_virt_start_addr != NULL) {
+				line_size_in_bytes =
+				    (dev->_pixel_format ==
+				     PIXEL_FRMT_411) ? Y411_LINE_SZ :
+				    Y422_LINE_SZ;
+				risc_phys_jump_addr =
+				    dev->_dma_phys_start_addr +
+				    odd_risc_prog_size;
+
+				rp = cx25821_update_riscprogram(dev,
+								dev->
+								_dma_virt_start_addr,
+								TOP_OFFSET,
+								line_size_in_bytes,
+								0x0,
+								singlefield_lines,
+								FIFO_DISABLE,
+								ODD_FIELD);
+
+				// Jump to Even Risc program of 1st Frame
+				*(rp++) = cpu_to_le32(RISC_JUMP);
+				*(rp++) = cpu_to_le32(risc_phys_jump_addr);
+				*(rp++) = cpu_to_le32(0);
+			}
+		}
+
+		spin_unlock(&dev->slock);
+	} else {
+		if (status & FLD_VID_SRC_UF)
+			printk
+			    ("%s: Video Received Underflow Error Interrupt!\n",
+			     __func__);
+
+		if (status & FLD_VID_SRC_SYNC)
+			printk("%s: Video Received Sync Error Interrupt!\n",
+			       __func__);
+
+		if (status & FLD_VID_SRC_OPC_ERR)
+			printk("%s: Video Received OpCode Error Interrupt!\n",
+			       __func__);
+	}
+
+	if (dev->_file_status == END_OF_FILE) {
+		printk("cx25821: EOF Channel 1 Framecount = %d\n",
+		       dev->_frame_count);
+		return -1;
+	}
+	//ElSE, set the interrupt mask register, re-enable irq.
+	int_msk_tmp = cx_read(channel->int_msk);
+	cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
+
+	return 0;
+}
+
+static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
+{
+	struct cx25821_dev *dev = dev_id;
+	u32 msk_stat, vid_status;
+	int handled = 0;
+	int channel_num = 0;
+	struct sram_channel *sram_ch;
+
+	if (!dev)
+		return -1;
+
+	channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
+
+	sram_ch = &dev->sram_channels[channel_num];
+
+	msk_stat = cx_read(sram_ch->int_mstat);
+	vid_status = cx_read(sram_ch->int_stat);
+
+	// Only deal with our interrupt
+	if (vid_status) {
+		handled =
+		    cx25821_video_upstream_irq(dev, channel_num, vid_status);
+	}
+
+	if (handled < 0) {
+		cx25821_stop_upstream_video_ch1(dev);
+	} else {
+		handled += handled;
+	}
+
+	return IRQ_RETVAL(handled);
+}
+
+void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
+			     int pix_format)
+{
+	int width = WIDTH_D1;
+	int height = dev->_lines_count;
+	int num_lines, odd_num_lines;
+	u32 value;
+	int vip_mode = OUTPUT_FRMT_656;
+
+	value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
+	value &= 0xFFFFFFEF;
+	value |= dev->_isNTSC ? 0 : 0x10;
+	cx_write(ch->vid_fmt_ctl, value);
+
+	// set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
+	cx_write(ch->vid_active_ctl1, width);
+
+	num_lines = (height / 2) & 0x3FF;
+	odd_num_lines = num_lines;
+
+	if (dev->_isNTSC) {
+		odd_num_lines += 1;
+	}
+
+	value = (num_lines << 16) | odd_num_lines;
+
+	// set number of active lines in field 0 (top) and field 1 (bottom)
+	cx_write(ch->vid_active_ctl2, value);
+
+	cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
+}
+
+int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
+				     struct sram_channel *sram_ch)
+{
+	u32 tmp = 0;
+	int err = 0;
+
+	// 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
+	tmp = cx_read(VID_CH_MODE_SEL);
+	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
+
+	// Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
+	cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
+	cx_write(sram_ch->cmds_start + 4, 0);	/* Risc IPC High 64 bits 63-32 */
+
+	/* reset counter */
+	cx_write(sram_ch->gpcnt_ctl, 3);
+
+	// Clear our bits from the interrupt status register.
+	cx_write(sram_ch->int_stat, _intr_msk);
+
+	//Set the interrupt mask register, enable irq.
+	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
+	tmp = cx_read(sram_ch->int_msk);
+	cx_write(sram_ch->int_msk, tmp |= _intr_msk);
+
+	err =
+	    request_irq(dev->pci->irq, cx25821_upstream_irq,
+			IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+	if (err < 0) {
+		printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
+		       dev->pci->irq);
+		goto fail_irq;
+	}
+
+	// Start the DMA  engine
+	tmp = cx_read(sram_ch->dma_ctl);
+	cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
+
+	dev->_is_running = 1;
+	dev->_is_first_frame = 1;
+
+	return 0;
+
+      fail_irq:
+	cx25821_dev_unregister(dev);
+	return err;
+}
+
+int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
+				 int pixel_format)
+{
+	struct sram_channel *sram_ch;
+	u32 tmp;
+	int retval = 0;
+	int err = 0;
+	int data_frame_size = 0;
+	int risc_buffer_size = 0;
+	int str_length = 0;
+
+	if (dev->_is_running) {
+		printk("Video Channel is still running so return!\n");
+		return 0;
+	}
+
+	dev->_channel_upstream_select = channel_select;
+	sram_ch = &dev->sram_channels[channel_select];
+
+	INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
+	dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
+
+	if (!dev->_irq_queues) {
+		printk
+		    ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
+		return -ENOMEM;
+	}
+	// 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
+	tmp = cx_read(VID_CH_MODE_SEL);
+	cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
+
+	dev->_is_running = 0;
+	dev->_frame_count = 0;
+	dev->_file_status = RESET_STATUS;
+	dev->_lines_count = dev->_isNTSC ? 480 : 576;
+	dev->_pixel_format = pixel_format;
+	dev->_line_size =
+	    (dev->_pixel_format ==
+	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
+	data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
+	risc_buffer_size =
+	    dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
+
+	if (dev->input_filename) {
+		str_length = strlen(dev->input_filename);
+		dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
+
+		if (!dev->_filename)
+			goto error;
+
+		memcpy(dev->_filename, dev->input_filename, str_length + 1);
+	} else {
+		str_length = strlen(dev->_defaultname);
+		dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
+
+		if (!dev->_filename)
+			goto error;
+
+		memcpy(dev->_filename, dev->_defaultname, str_length + 1);
+	}
+
+	//Default if filename is empty string
+	if (strcmp(dev->input_filename, "") == 0) {
+		if (dev->_isNTSC) {
+			dev->_filename =
+			    (dev->_pixel_format ==
+			     PIXEL_FRMT_411) ? "/root/vid411.yuv" :
+			    "/root/vidtest.yuv";
+		} else {
+			dev->_filename =
+			    (dev->_pixel_format ==
+			     PIXEL_FRMT_411) ? "/root/pal411.yuv" :
+			    "/root/pal422.yuv";
+		}
+	}
+
+	dev->_is_running = 0;
+	dev->_frame_count = 0;
+	dev->_file_status = RESET_STATUS;
+	dev->_lines_count = dev->_isNTSC ? 480 : 576;
+	dev->_pixel_format = pixel_format;
+	dev->_line_size =
+	    (dev->_pixel_format ==
+	     PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
+
+	retval =
+	    cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size,
+						0);
+
+	/* setup fifo + format */
+	cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
+
+	dev->upstream_riscbuf_size = risc_buffer_size * 2;
+	dev->upstream_databuf_size = data_frame_size * 2;
+
+	//Allocating buffers and prepare RISC program
+	retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
+	if (retval < 0) {
+		printk(KERN_ERR
+		       "%s: Failed to set up Video upstream buffers!\n",
+		       dev->name);
+		goto error;
+	}
+
+	cx25821_start_video_dma_upstream(dev, sram_ch);
+
+	return 0;
+
+      error:
+	cx25821_dev_unregister(dev);
+
+	return err;
+}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/staging/cx25821/cx25821-video-upstream.h
new file mode 100644
index 0000000..cc9f938
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.h
@@ -0,0 +1,109 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <hiep.huynh@conexant.com>, <shu.lin@conexant.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.
+ */
+
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#define OUTPUT_FRMT_656       0
+#define OPEN_FILE_1           0
+#define NUM_PROGS             8
+#define NUM_FRAMES            2
+#define ODD_FIELD             0
+#define EVEN_FIELD            1
+#define TOP_OFFSET            0
+#define FIFO_DISABLE          0
+#define FIFO_ENABLE           1
+#define TEST_FRAMES           5
+#define END_OF_FILE           0
+#define IN_PROGRESS           1
+#define RESET_STATUS          -1
+#define NUM_NO_OPS            5
+
+// PAL and NTSC line sizes and number of lines.
+#define WIDTH_D1              720
+#define NTSC_LINES_PER_FRAME  480
+#define PAL_LINES_PER_FRAME   576
+#define PAL_LINE_SZ           1440
+#define Y422_LINE_SZ          1440
+#define Y411_LINE_SZ          1080
+#define NTSC_FIELD_HEIGHT     240
+#define NTSC_ODD_FLD_LINES    241
+#define PAL_FIELD_HEIGHT      288
+
+#define FRAME_SIZE_NTSC_Y422    (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
+#define FRAME_SIZE_NTSC_Y411    (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
+#define FRAME_SIZE_PAL_Y422     (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
+#define FRAME_SIZE_PAL_Y411     (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
+
+#define NTSC_DATA_BUF_SZ        (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
+#define PAL_DATA_BUF_SZ         (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
+
+#define RISC_WRITECR_INSTRUCTION_SIZE   16
+#define RISC_SYNC_INSTRUCTION_SIZE      4
+#define JUMP_INSTRUCTION_SIZE           12
+#define MAXSIZE_NO_OPS                  36
+#define DWORD_SIZE                      4
+
+#define USE_RISC_NOOP_VIDEO   1
+
+#ifdef USE_RISC_NOOP_VIDEO
+#define PAL_US_VID_PROG_SIZE        ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE +   \
+				      RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+
+#define PAL_RISC_BUF_SIZE           (2 * PAL_US_VID_PROG_SIZE)
+
+#define PAL_VID_PROG_SIZE           ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				      RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
+
+#define ODD_FLD_PAL_PROG_SIZE       ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
+				      RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+
+#define ODD_FLD_NTSC_PROG_SIZE      ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
+				      RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+
+#define NTSC_US_VID_PROG_SIZE       ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
+				      JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
+
+#define NTSC_RISC_BUF_SIZE          (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
+
+#define FRAME1_VID_PROG_SIZE        ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				      RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
+
+#endif
+
+#ifndef USE_RISC_NOOP_VIDEO
+#define PAL_US_VID_PROG_SIZE        ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
+				      RISC_SYNC_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
+
+#define PAL_RISC_BUF_SIZE           (2 * PAL_US_VID_PROG_SIZE)
+
+#define PAL_VID_PROG_SIZE           ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				      RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
+
+#define ODD_FLD_PAL_PROG_SIZE       ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
+#define ODD_FLD_NTSC_PROG_SIZE      ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
+
+#define NTSC_US_VID_PROG_SIZE       ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
+#define NTSC_RISC_BUF_SIZE          ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
+#define FRAME1_VID_PROG_SIZE        ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
+				      RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
+#endif
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
new file mode 100644
index 0000000..8834bc8
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -0,0 +1,1299 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
+MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
+MODULE_LICENSE("GPL");
+
+static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
+static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
+
+module_param_array(video_nr, int, NULL, 0444);
+module_param_array(radio_nr, int, NULL, 0444);
+
+MODULE_PARM_DESC(video_nr, "video device numbers");
+MODULE_PARM_DESC(radio_nr, "radio device numbers");
+
+static unsigned int video_debug = VIDEO_DEBUG;
+module_param(video_debug, int, 0644);
+MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
+
+static unsigned int irq_debug;
+module_param(irq_debug, int, 0644);
+MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
+
+unsigned int vid_limit = 16;
+module_param(vid_limit, int, 0644);
+MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
+
+static void init_controls(struct cx25821_dev *dev, int chan_num);
+
+#define FORMAT_FLAGS_PACKED       0x01
+
+struct cx25821_fmt formats[] = {
+	{
+	 .name = "8 bpp, gray",
+	 .fourcc = V4L2_PIX_FMT_GREY,
+	 .depth = 8,
+	 .flags = FORMAT_FLAGS_PACKED,
+	 }, {
+	     .name = "4:1:1, packed, Y41P",
+	     .fourcc = V4L2_PIX_FMT_Y41P,
+	     .depth = 12,
+	     .flags = FORMAT_FLAGS_PACKED,
+	     }, {
+		 .name = "4:2:2, packed, YUYV",
+		 .fourcc = V4L2_PIX_FMT_YUYV,
+		 .depth = 16,
+		 .flags = FORMAT_FLAGS_PACKED,
+		 }, {
+		     .name = "4:2:2, packed, UYVY",
+		     .fourcc = V4L2_PIX_FMT_UYVY,
+		     .depth = 16,
+		     .flags = FORMAT_FLAGS_PACKED,
+		     }, {
+			 .name = "4:2:0, YUV",
+			 .fourcc = V4L2_PIX_FMT_YUV420,
+			 .depth = 12,
+			 .flags = FORMAT_FLAGS_PACKED,
+			 },
+};
+
+int get_format_size(void)
+{
+	return ARRAY_SIZE(formats);
+}
+
+struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
+{
+	unsigned int i;
+
+	if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) {
+		return formats + 1;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(formats); i++)
+		if (formats[i].fourcc == fourcc)
+			return formats + i;
+
+	printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
+	return NULL;
+}
+
+void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
+{
+	struct cx25821_buffer *buf;
+	struct list_head *item;
+	dprintk(1, "%s()\n", __func__);
+
+	if (!list_empty(&q->active)) {
+		list_for_each(item, &q->active)
+		    buf = list_entry(item, struct cx25821_buffer, vb.queue);
+	}
+
+	if (!list_empty(&q->queued)) {
+		list_for_each(item, &q->queued)
+		    buf = list_entry(item, struct cx25821_buffer, vb.queue);
+	}
+
+}
+
+void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
+			  u32 count)
+{
+	struct cx25821_buffer *buf;
+	int bc;
+
+	for (bc = 0;; bc++) {
+		if (list_empty(&q->active)) {
+			dprintk(1, "bc=%d (=0: active empty)\n", bc);
+			break;
+		}
+
+		buf =
+		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
+
+		/* count comes from the hw and it is 16bit wide --
+		 * this trick handles wrap-arounds correctly for
+		 * up to 32767 buffers in flight... */
+		if ((s16) (count - buf->count) < 0) {
+			break;
+		}
+
+		do_gettimeofday(&buf->vb.ts);
+		buf->vb.state = VIDEOBUF_DONE;
+		list_del(&buf->vb.queue);
+		wake_up(&buf->vb.done);
+	}
+
+	if (list_empty(&q->active))
+		del_timer(&q->timeout);
+	else
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+	if (bc != 1)
+		printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
+		       __func__, bc);
+}
+
+#ifdef TUNER_FLAG
+int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
+{
+	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
+		(unsigned int)norm, v4l2_norm_to_name(norm));
+
+	dev->tvnorm = norm;
+
+	/* Tell the internal A/V decoder */
+	cx25821_call_all(dev, core, s_std, norm);
+
+	return 0;
+}
+#endif
+
+struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
+				       struct pci_dev *pci,
+				       struct video_device *template,
+				       char *type)
+{
+	struct video_device *vfd;
+	dprintk(1, "%s()\n", __func__);
+
+	vfd = video_device_alloc();
+	if (NULL == vfd)
+		return NULL;
+	*vfd = *template;
+	vfd->minor = -1;
+	vfd->v4l2_dev = &dev->v4l2_dev;
+	vfd->release = video_device_release;
+	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
+		 cx25821_boards[dev->board].name);
+	return vfd;
+}
+
+/*
+static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
+{
+    int i;
+
+    if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
+	return -EINVAL;
+    for (i = 0; i < CX25821_CTLS; i++)
+	if (cx25821_ctls[i].v.id == qctrl->id)
+	    break;
+    if (i == CX25821_CTLS) {
+	*qctrl = no_ctl;
+	return 0;
+    }
+    *qctrl = cx25821_ctls[i].v;
+    return 0;
+}
+*/
+
+// resource management
+int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
+{
+	dprintk(1, "%s()\n", __func__);
+	if (fh->resources & bit)
+		/* have it already allocated */
+		return 1;
+
+	/* is it free? */
+	mutex_lock(&dev->lock);
+	if (dev->resources & bit) {
+		/* no, someone else uses it */
+		mutex_unlock(&dev->lock);
+		return 0;
+	}
+	/* it's free, grab it */
+	fh->resources |= bit;
+	dev->resources |= bit;
+	dprintk(1, "res: get %d\n", bit);
+	mutex_unlock(&dev->lock);
+	return 1;
+}
+
+int res_check(struct cx25821_fh *fh, unsigned int bit)
+{
+	return fh->resources & bit;
+}
+
+int res_locked(struct cx25821_dev *dev, unsigned int bit)
+{
+	return dev->resources & bit;
+}
+
+void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
+{
+	BUG_ON((fh->resources & bits) != bits);
+	dprintk(1, "%s()\n", __func__);
+
+	mutex_lock(&dev->lock);
+	fh->resources &= ~bits;
+	dev->resources &= ~bits;
+	dprintk(1, "res: put %d\n", bits);
+	mutex_unlock(&dev->lock);
+}
+
+int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
+{
+	struct v4l2_routing route;
+	memset(&route, 0, sizeof(route));
+
+	dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
+		__func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
+		INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
+	dev->input = input;
+
+	route.input = INPUT(input)->vmux;
+
+	/* Tell the internal A/V decoder */
+	cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
+
+	return 0;
+}
+
+int cx25821_start_video_dma(struct cx25821_dev *dev,
+			    struct cx25821_dmaqueue *q,
+			    struct cx25821_buffer *buf,
+			    struct sram_channel *channel)
+{
+	int tmp = 0;
+
+	/* setup fifo + format */
+	cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
+
+	/* reset counter */
+	cx_write(channel->gpcnt_ctl, 3);
+	q->count = 1;
+
+	/* enable irq */
+	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
+	cx_set(channel->int_msk, 0x11);
+
+	/* start dma */
+	cx_write(channel->dma_ctl, 0x11);	/* FIFO and RISC enable */
+
+	/* make sure upstream setting if any is reversed */
+	tmp = cx_read(VID_CH_MODE_SEL);
+	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
+
+	return 0;
+}
+
+int cx25821_restart_video_queue(struct cx25821_dev *dev,
+				struct cx25821_dmaqueue *q,
+				struct sram_channel *channel)
+{
+	struct cx25821_buffer *buf, *prev;
+	struct list_head *item;
+
+	if (!list_empty(&q->active)) {
+		buf =
+		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
+
+		cx25821_start_video_dma(dev, q, buf, channel);
+
+		list_for_each(item, &q->active) {
+			buf = list_entry(item, struct cx25821_buffer, vb.queue);
+			buf->count = q->count++;
+		}
+
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		return 0;
+	}
+
+	prev = NULL;
+	for (;;) {
+		if (list_empty(&q->queued))
+			return 0;
+
+		buf =
+		    list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
+
+		if (NULL == prev) {
+			list_move_tail(&buf->vb.queue, &q->active);
+			cx25821_start_video_dma(dev, q, buf, channel);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		} else if (prev->vb.width == buf->vb.width &&
+			   prev->vb.height == buf->vb.height &&
+			   prev->fmt == buf->fmt) {
+			list_move_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+			prev->risc.jmp[2] = cpu_to_le32(0);	/* Bits 63 - 32 */
+		} else {
+			return 0;
+		}
+		prev = buf;
+	}
+}
+
+void cx25821_vid_timeout(unsigned long data)
+{
+	struct cx25821_data *timeout_data = (struct cx25821_data *)data;
+	struct cx25821_dev *dev = timeout_data->dev;
+	struct sram_channel *channel = timeout_data->channel;
+	struct cx25821_dmaqueue *q = &dev->vidq[channel->i];
+	struct cx25821_buffer *buf;
+	unsigned long flags;
+
+	//cx25821_sram_channel_dump(dev, channel);
+	cx_clear(channel->dma_ctl, 0x11);
+
+	spin_lock_irqsave(&dev->slock, flags);
+	while (!list_empty(&q->active)) {
+		buf =
+		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
+		list_del(&buf->vb.queue);
+
+		buf->vb.state = VIDEOBUF_ERROR;
+		wake_up(&buf->vb.done);
+	}
+
+	cx25821_restart_video_queue(dev, q, channel);
+	spin_unlock_irqrestore(&dev->slock, flags);
+}
+
+int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
+{
+	u32 count = 0;
+	int handled = 0;
+	u32 mask;
+	struct sram_channel *channel = &dev->sram_channels[chan_num];
+
+	mask = cx_read(channel->int_msk);
+	if (0 == (status & mask))
+		return handled;
+
+	cx_write(channel->int_stat, status);
+
+	/* risc op code error */
+	if (status & (1 << 16)) {
+		printk(KERN_WARNING "%s, %s: video risc op code error\n",
+		       dev->name, channel->name);
+		cx_clear(channel->dma_ctl, 0x11);
+		cx25821_sram_channel_dump(dev, channel);
+	}
+
+	/* risc1 y */
+	if (status & FLD_VID_DST_RISC1) {
+		spin_lock(&dev->slock);
+		count = cx_read(channel->gpcnt);
+		cx25821_video_wakeup(dev, &dev->vidq[channel->i], count);
+		spin_unlock(&dev->slock);
+		handled++;
+	}
+
+	/* risc2 y */
+	if (status & 0x10) {
+		dprintk(2, "stopper video\n");
+		spin_lock(&dev->slock);
+		cx25821_restart_video_queue(dev, &dev->vidq[channel->i],
+					    channel);
+		spin_unlock(&dev->slock);
+		handled++;
+	}
+	return handled;
+}
+
+void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
+{
+	if (dev->ioctl_dev) {
+		if (dev->ioctl_dev->minor != -1)
+			video_unregister_device(dev->ioctl_dev);
+		else
+			video_device_release(dev->ioctl_dev);
+
+		dev->ioctl_dev = NULL;
+	}
+}
+
+void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
+{
+	cx_clear(PCI_INT_MSK, 1);
+
+	if (dev->video_dev[chan_num]) {
+		if (-1 != dev->video_dev[chan_num]->minor)
+			video_unregister_device(dev->video_dev[chan_num]);
+		else
+			video_device_release(dev->video_dev[chan_num]);
+
+		dev->video_dev[chan_num] = NULL;
+
+		btcx_riscmem_free(dev->pci, &dev->vidq[chan_num].stopper);
+
+		printk(KERN_WARNING "device %d released!\n", chan_num);
+	}
+
+}
+
+int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
+			   struct video_device *video_template)
+{
+	int err;
+
+	spin_lock_init(&dev->slock);
+
+	//printk(KERN_WARNING "Channel %d\n", chan_num);
+
+#ifdef TUNER_FLAG
+	dev->tvnorm = video_template->current_norm;
+#endif
+
+	/* init video dma queues */
+	dev->timeout_data[chan_num].dev = dev;
+	dev->timeout_data[chan_num].channel = &dev->sram_channels[chan_num];
+	INIT_LIST_HEAD(&dev->vidq[chan_num].active);
+	INIT_LIST_HEAD(&dev->vidq[chan_num].queued);
+	dev->vidq[chan_num].timeout.function = cx25821_vid_timeout;
+	dev->vidq[chan_num].timeout.data =
+	    (unsigned long)&dev->timeout_data[chan_num];
+	init_timer(&dev->vidq[chan_num].timeout);
+	cx25821_risc_stopper(dev->pci, &dev->vidq[chan_num].stopper,
+			     dev->sram_channels[chan_num].dma_ctl, 0x11, 0);
+
+	/* register v4l devices */
+	dev->video_dev[chan_num] =
+	    cx25821_vdev_init(dev, dev->pci, video_template, "video");
+	err =
+	    video_register_device(dev->video_dev[chan_num], VFL_TYPE_GRABBER,
+				  video_nr[dev->nr]);
+
+	if (err < 0) {
+		goto fail_unreg;
+	}
+	//set PCI interrupt
+	cx_set(PCI_INT_MSK, 0xff);
+
+	/* initial device configuration */
+	mutex_lock(&dev->lock);
+#ifdef TUNER_FLAG
+	cx25821_set_tvnorm(dev, dev->tvnorm);
+#endif
+	mutex_unlock(&dev->lock);
+
+	init_controls(dev, chan_num);
+
+	return 0;
+
+      fail_unreg:
+	cx25821_video_unregister(dev, chan_num);
+	return err;
+}
+
+int buffer_setup(struct videobuf_queue *q, unsigned int *count,
+		 unsigned int *size)
+{
+	struct cx25821_fh *fh = q->priv_data;
+
+	*size = fh->fmt->depth * fh->width * fh->height >> 3;
+
+	if (0 == *count)
+		*count = 32;
+
+	while (*size * *count > vid_limit * 1024 * 1024)
+		(*count)--;
+
+	return 0;
+}
+
+int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
+		   enum v4l2_field field)
+{
+	struct cx25821_fh *fh = q->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	int rc, init_buffer = 0;
+	u32 line0_offset, line1_offset;
+	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
+	int bpl_local = LINE_SIZE_D1;
+	int channel_opened = 0;
+
+	BUG_ON(NULL == fh->fmt);
+	if (fh->width < 48 || fh->width > 720 ||
+	    fh->height < 32 || fh->height > 576)
+		return -EINVAL;
+
+	buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+
+	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+		return -EINVAL;
+
+	if (buf->fmt != fh->fmt ||
+	    buf->vb.width != fh->width ||
+	    buf->vb.height != fh->height || buf->vb.field != field) {
+		buf->fmt = fh->fmt;
+		buf->vb.width = fh->width;
+		buf->vb.height = fh->height;
+		buf->vb.field = field;
+		init_buffer = 1;
+	}
+
+	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+		init_buffer = 1;
+		rc = videobuf_iolock(q, &buf->vb, NULL);
+		if (0 != rc) {
+			printk(KERN_DEBUG "videobuf_iolock failed!\n");
+			goto fail;
+		}
+	}
+
+	dprintk(1, "init_buffer=%d\n", init_buffer);
+
+	if (init_buffer) {
+
+		channel_opened = dev->channel_opened;
+		channel_opened = (channel_opened < 0
+				  || channel_opened > 7) ? 7 : channel_opened;
+
+		if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411)
+			buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
+		else
+			buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
+
+		if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411) {
+			bpl_local = buf->bpl;
+		} else {
+			bpl_local = buf->bpl;	//Default
+
+			if (channel_opened >= 0 && channel_opened <= 7) {
+				if (dev->use_cif_resolution[channel_opened]) {
+					if (dev->tvnorm & V4L2_STD_PAL_BG
+					    || dev->tvnorm & V4L2_STD_PAL_DK)
+						bpl_local = 352 << 1;
+					else
+						bpl_local =
+						    dev->
+						    cif_width[channel_opened] <<
+						    1;
+				}
+			}
+		}
+
+		switch (buf->vb.field) {
+		case V4L2_FIELD_TOP:
+			cx25821_risc_buffer(dev->pci, &buf->risc,
+					    dma->sglist, 0, UNSET,
+					    buf->bpl, 0, buf->vb.height);
+			break;
+		case V4L2_FIELD_BOTTOM:
+			cx25821_risc_buffer(dev->pci, &buf->risc,
+					    dma->sglist, UNSET, 0,
+					    buf->bpl, 0, buf->vb.height);
+			break;
+		case V4L2_FIELD_INTERLACED:
+			/* All other formats are top field first */
+			line0_offset = 0;
+			line1_offset = buf->bpl;
+			dprintk(1, "top field first\n");
+
+			cx25821_risc_buffer(dev->pci, &buf->risc,
+					    dma->sglist, line0_offset,
+					    bpl_local, bpl_local, bpl_local,
+					    buf->vb.height >> 1);
+			break;
+		case V4L2_FIELD_SEQ_TB:
+			cx25821_risc_buffer(dev->pci, &buf->risc,
+					    dma->sglist,
+					    0, buf->bpl * (buf->vb.height >> 1),
+					    buf->bpl, 0, buf->vb.height >> 1);
+			break;
+		case V4L2_FIELD_SEQ_BT:
+			cx25821_risc_buffer(dev->pci, &buf->risc,
+					    dma->sglist,
+					    buf->bpl * (buf->vb.height >> 1), 0,
+					    buf->bpl, 0, buf->vb.height >> 1);
+			break;
+		default:
+			BUG();
+		}
+	}
+
+	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
+		buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
+		fh->fmt->name, (unsigned long)buf->risc.dma);
+
+	buf->vb.state = VIDEOBUF_PREPARED;
+
+	return 0;
+
+      fail:
+	cx25821_free_buffer(q, buf);
+	return rc;
+}
+
+void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+
+	cx25821_free_buffer(q, buf);
+}
+
+struct videobuf_queue *get_queue(struct cx25821_fh *fh)
+{
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return &fh->vidq;
+	default:
+		BUG();
+		return NULL;
+	}
+}
+
+int get_resource(struct cx25821_fh *fh, int resource)
+{
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		return resource;
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+int video_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	return videobuf_mmap_mapper(get_queue(fh), vma);
+}
+
+/* VIDEO IOCTLS                                                       */
+int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+
+	f->fmt.pix.width = fh->width;
+	f->fmt.pix.height = fh->height;
+	f->fmt.pix.field = fh->vidq.field;
+	f->fmt.pix.pixelformat = fh->fmt->fourcc;
+	f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
+	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
+	return 0;
+}
+
+int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
+{
+	struct cx25821_fmt *fmt;
+	enum v4l2_field field;
+	unsigned int maxw, maxh;
+
+	fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	if (NULL == fmt)
+		return -EINVAL;
+
+	field = f->fmt.pix.field;
+	maxw = 720;
+	maxh = 576;
+
+	if (V4L2_FIELD_ANY == field) {
+		field = (f->fmt.pix.height > maxh / 2)
+		    ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
+	}
+
+	switch (field) {
+	case V4L2_FIELD_TOP:
+	case V4L2_FIELD_BOTTOM:
+		maxh = maxh / 2;
+		break;
+	case V4L2_FIELD_INTERLACED:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	f->fmt.pix.field = field;
+	if (f->fmt.pix.height < 32)
+		f->fmt.pix.height = 32;
+	if (f->fmt.pix.height > maxh)
+		f->fmt.pix.height = maxh;
+	if (f->fmt.pix.width < 48)
+		f->fmt.pix.width = 48;
+	if (f->fmt.pix.width > maxw)
+		f->fmt.pix.width = maxw;
+	f->fmt.pix.width &= ~0x03;
+	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
+	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
+	return 0;
+}
+
+int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	strcpy(cap->driver, "cx25821");
+	strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
+	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
+	cap->version = CX25821_VERSION_CODE;
+	cap->capabilities =
+	    V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+	if (UNSET != dev->tuner_type)
+		cap->capabilities |= V4L2_CAP_TUNER;
+	return 0;
+}
+
+int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+			    struct v4l2_fmtdesc *f)
+{
+	if (unlikely(f->index >= ARRAY_SIZE(formats)))
+		return -EINVAL;
+
+	strlcpy(f->description, formats[f->index].name, sizeof(f->description));
+	f->pixelformat = formats[f->index].fourcc;
+
+	return 0;
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+	struct cx25821_fh *fh = priv;
+	struct videobuf_queue *q;
+	struct v4l2_requestbuffers req;
+	unsigned int i;
+	int err;
+
+	q = get_queue(fh);
+	memset(&req, 0, sizeof(req));
+	req.type = q->type;
+	req.count = 8;
+	req.memory = V4L2_MEMORY_MMAP;
+	err = videobuf_reqbufs(q, &req);
+	if (err < 0)
+		return err;
+
+	mbuf->frames = req.count;
+	mbuf->size = 0;
+	for (i = 0; i < mbuf->frames; i++) {
+		mbuf->offsets[i] = q->bufs[i]->boff;
+		mbuf->size += q->bufs[i]->bsize;
+	}
+	return 0;
+}
+#endif
+
+int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
+{
+	struct cx25821_fh *fh = priv;
+	return videobuf_reqbufs(get_queue(fh), p);
+}
+
+int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct cx25821_fh *fh = priv;
+	return videobuf_querybuf(get_queue(fh), p);
+}
+
+int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct cx25821_fh *fh = priv;
+	return videobuf_qbuf(get_queue(fh), p);
+}
+
+int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
+
+	*p = v4l2_prio_max(&dev->prio);
+
+	return 0;
+}
+
+int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
+{
+	struct cx25821_fh *fh = f;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
+
+	return v4l2_prio_change(&dev->prio, &fh->prio, prio);
+}
+
+#ifdef TUNER_FLAG
+int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	dprintk(1, "%s()\n", __func__);
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	if (dev->tvnorm == *tvnorms) {
+		return 0;
+	}
+
+	mutex_lock(&dev->lock);
+	cx25821_set_tvnorm(dev, *tvnorms);
+	mutex_unlock(&dev->lock);
+
+	medusa_set_videostandard(dev);
+
+	return 0;
+}
+#endif
+
+int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
+{
+	static const char *iname[] = {
+		[CX25821_VMUX_COMPOSITE] = "Composite",
+		[CX25821_VMUX_SVIDEO] = "S-Video",
+		[CX25821_VMUX_DEBUG] = "for debug only",
+	};
+	unsigned int n;
+	dprintk(1, "%s()\n", __func__);
+
+	n = i->index;
+	if (n > 2)
+		return -EINVAL;
+
+	if (0 == INPUT(n)->type)
+		return -EINVAL;
+
+	memset(i, 0, sizeof(*i));
+	i->index = n;
+	i->type = V4L2_INPUT_TYPE_CAMERA;
+	strcpy(i->name, iname[INPUT(n)->type]);
+
+	i->std = CX25821_NORMS;
+	return 0;
+}
+
+int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	dprintk(1, "%s()\n", __func__);
+	return cx25821_enum_input(dev, i);
+}
+
+int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	*i = dev->input;
+	dprintk(1, "%s() returns %d\n", __func__, *i);
+	return 0;
+}
+
+int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	dprintk(1, "%s(%d)\n", __func__, i);
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	if (i > 2) {
+		dprintk(1, "%s() -EINVAL\n", __func__);
+		return -EINVAL;
+	}
+
+	mutex_lock(&dev->lock);
+	cx25821_video_mux(dev, i);
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+#ifdef TUNER_FLAG
+int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	f->frequency = dev->freq;
+
+	cx25821_call_all(dev, tuner, g_frequency, f);
+
+	return 0;
+}
+
+int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
+{
+	mutex_lock(&dev->lock);
+	dev->freq = f->frequency;
+
+	cx25821_call_all(dev, tuner, s_frequency, f);
+
+	/* When changing channels it is required to reset TVAUDIO */
+	msleep(10);
+
+	mutex_unlock(&dev->lock);
+
+	return 0;
+}
+
+int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_freq(dev, f);
+}
+#endif
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+int vidioc_g_register(struct file *file, void *fh,
+		      struct v4l2_dbg_register *reg)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
+
+	if (!v4l2_chip_match_host(&reg->match))
+		return -EINVAL;
+
+	cx25821_call_all(dev, core, g_register, reg);
+
+	return 0;
+}
+
+int vidioc_s_register(struct file *file, void *fh,
+		      struct v4l2_dbg_register *reg)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
+
+	if (!v4l2_chip_match_host(&reg->match))
+		return -EINVAL;
+
+	cx25821_call_all(dev, core, s_register, reg);
+
+	return 0;
+}
+
+#endif
+
+#ifdef TUNER_FLAG
+int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	if (unlikely(UNSET == dev->tuner_type))
+		return -EINVAL;
+	if (0 != t->index)
+		return -EINVAL;
+
+	strcpy(t->name, "Television");
+	t->type = V4L2_TUNER_ANALOG_TV;
+	t->capability = V4L2_TUNER_CAP_NORM;
+	t->rangehigh = 0xffffffffUL;
+
+	t->signal = 0xffff;	/* LOCKED */
+	return 0;
+}
+
+int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	struct cx25821_fh *fh = priv;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(1, "%s()\n", __func__);
+	if (UNSET == dev->tuner_type)
+		return -EINVAL;
+	if (0 != t->index)
+		return -EINVAL;
+
+	return 0;
+}
+
+#endif
+// ******************************************************************************************
+static const struct v4l2_queryctrl no_ctl = {
+	.name = "42",
+	.flags = V4L2_CTRL_FLAG_DISABLED,
+};
+
+static struct v4l2_queryctrl cx25821_ctls[] = {
+	/* --- video --- */
+	{
+	 .id = V4L2_CID_BRIGHTNESS,
+	 .name = "Brightness",
+	 .minimum = 0,
+	 .maximum = 10000,
+	 .step = 1,
+	 .default_value = 6200,
+	 .type = V4L2_CTRL_TYPE_INTEGER,
+	 }, {
+	     .id = V4L2_CID_CONTRAST,
+	     .name = "Contrast",
+	     .minimum = 0,
+	     .maximum = 10000,
+	     .step = 1,
+	     .default_value = 5000,
+	     .type = V4L2_CTRL_TYPE_INTEGER,
+	     }, {
+		 .id = V4L2_CID_SATURATION,
+		 .name = "Saturation",
+		 .minimum = 0,
+		 .maximum = 10000,
+		 .step = 1,
+		 .default_value = 5000,
+		 .type = V4L2_CTRL_TYPE_INTEGER,
+		 }, {
+		     .id = V4L2_CID_HUE,
+		     .name = "Hue",
+		     .minimum = 0,
+		     .maximum = 10000,
+		     .step = 1,
+		     .default_value = 5000,
+		     .type = V4L2_CTRL_TYPE_INTEGER,
+		     }
+};
+static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
+
+static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
+{
+	int i;
+
+	if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
+		return -EINVAL;
+	for (i = 0; i < CX25821_CTLS; i++)
+		if (cx25821_ctls[i].id == qctrl->id)
+			break;
+	if (i == CX25821_CTLS) {
+		*qctrl = no_ctl;
+		return 0;
+	}
+	*qctrl = cx25821_ctls[i];
+	return 0;
+}
+
+int vidioc_queryctrl(struct file *file, void *priv,
+		     struct v4l2_queryctrl *qctrl)
+{
+	return cx25821_ctrl_query(qctrl);
+}
+
+/* ------------------------------------------------------------------ */
+/* VIDEO CTRL IOCTLS                                                  */
+
+static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
+{
+	unsigned int i;
+
+	for (i = 0; i < CX25821_CTLS; i++)
+		if (cx25821_ctls[i].id == id)
+			return cx25821_ctls + i;
+	return NULL;
+}
+
+int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	const struct v4l2_queryctrl *ctrl;
+
+	ctrl = ctrl_by_id(ctl->id);
+
+	if (NULL == ctrl)
+		return -EINVAL;
+	switch (ctl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctl->value = dev->ctl_bright;
+		break;
+	case V4L2_CID_HUE:
+		ctl->value = dev->ctl_hue;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctl->value = dev->ctl_contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		ctl->value = dev->ctl_saturation;
+		break;
+	}
+	return 0;
+}
+
+int cx25821_set_control(struct cx25821_dev *dev,
+			struct v4l2_control *ctl, int chan_num)
+{
+	int err;
+	const struct v4l2_queryctrl *ctrl;
+
+	err = -EINVAL;
+
+	ctrl = ctrl_by_id(ctl->id);
+
+	if (NULL == ctrl)
+		return err;
+
+	switch (ctrl->type) {
+	case V4L2_CTRL_TYPE_BOOLEAN:
+	case V4L2_CTRL_TYPE_MENU:
+	case V4L2_CTRL_TYPE_INTEGER:
+		if (ctl->value < ctrl->minimum)
+			ctl->value = ctrl->minimum;
+		if (ctl->value > ctrl->maximum)
+			ctl->value = ctrl->maximum;
+		break;
+	default:
+		/* nothing */ ;
+	};
+
+	switch (ctl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		dev->ctl_bright = ctl->value;
+		medusa_set_brightness(dev, ctl->value, chan_num);
+		break;
+	case V4L2_CID_HUE:
+		dev->ctl_hue = ctl->value;
+		medusa_set_hue(dev, ctl->value, chan_num);
+		break;
+	case V4L2_CID_CONTRAST:
+		dev->ctl_contrast = ctl->value;
+		medusa_set_contrast(dev, ctl->value, chan_num);
+		break;
+	case V4L2_CID_SATURATION:
+		dev->ctl_saturation = ctl->value;
+		medusa_set_saturation(dev, ctl->value, chan_num);
+		break;
+	}
+
+	err = 0;
+
+	return err;
+}
+
+static void init_controls(struct cx25821_dev *dev, int chan_num)
+{
+	struct v4l2_control ctrl;
+	int i;
+	for (i = 0; i < CX25821_CTLS; i++) {
+		ctrl.id = cx25821_ctls[i].id;
+		ctrl.value = cx25821_ctls[i].default_value;
+
+		cx25821_set_control(dev, &ctrl, chan_num);
+	}
+}
+
+int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	cropcap->bounds.top = cropcap->bounds.left = 0;
+	cropcap->bounds.width = 720;
+	cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
+	cropcap->pixelaspect.numerator =
+	    dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
+	cropcap->pixelaspect.denominator =
+	    dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
+	cropcap->defrect = cropcap->bounds;
+	return 0;
+}
+
+int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	struct cx25821_fh *fh = priv;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+	// vidioc_s_crop not supported
+	return -EINVAL;
+}
+
+int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
+{
+	// vidioc_g_crop not supported
+	return -EINVAL;
+}
+
+int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
+{
+	// medusa does not support video standard sensing of current input
+	*norm = CX25821_NORMS;
+
+	return 0;
+}
+
+int is_valid_width(u32 width, v4l2_std_id tvnorm)
+{
+	if (tvnorm == V4L2_STD_PAL_BG) {
+		if (width == 352 || width == 720)
+			return 1;
+		else
+			return 0;
+	}
+
+	if (tvnorm == V4L2_STD_NTSC_M) {
+		if (width == 320 || width == 352 || width == 720)
+			return 1;
+		else
+			return 0;
+	}
+	return 0;
+}
+
+int is_valid_height(u32 height, v4l2_std_id tvnorm)
+{
+	if (tvnorm == V4L2_STD_PAL_BG) {
+		if (height == 576 || height == 288)
+			return 1;
+		else
+			return 0;
+	}
+
+	if (tvnorm == V4L2_STD_NTSC_M) {
+		if (height == 480 || height == 240)
+			return 1;
+		else
+			return 0;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
new file mode 100644
index 0000000..4417ff5
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -0,0 +1,194 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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 CX25821_VIDEO_H_
+#define CX25821_VIDEO_H_
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <asm/div64.h>
+
+#include "cx25821.h"
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+/* Include V4L1 specific functions. Should be removed soon */
+#include <linux/videodev.h>
+#endif
+
+#define TUNER_FLAG
+
+#define VIDEO_DEBUG 0
+
+#define dprintk(level, fmt, arg...)\
+    do { if (VIDEO_DEBUG >= level)\
+	printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
+    } while (0)
+
+//For IOCTL to identify running upstream
+#define UPSTREAM_START_VIDEO        700
+#define UPSTREAM_STOP_VIDEO         701
+#define UPSTREAM_START_AUDIO        702
+#define UPSTREAM_STOP_AUDIO         703
+#define UPSTREAM_DUMP_REGISTERS     702
+#define SET_VIDEO_STD               800
+#define SET_PIXEL_FORMAT            1000
+#define ENABLE_CIF_RESOLUTION       1001
+
+#define REG_READ		    900
+#define REG_WRITE		    901
+#define MEDUSA_READ		    910
+#define MEDUSA_WRITE		911
+
+extern struct sram_channel *channel0;
+extern struct sram_channel *channel1;
+extern struct sram_channel *channel2;
+extern struct sram_channel *channel3;
+extern struct sram_channel *channel4;
+extern struct sram_channel *channel5;
+extern struct sram_channel *channel6;
+extern struct sram_channel *channel7;
+extern struct sram_channel *channel9;
+extern struct sram_channel *channel10;
+extern struct sram_channel *channel11;
+extern struct video_device cx25821_video_template0;
+extern struct video_device cx25821_video_template1;
+extern struct video_device cx25821_video_template2;
+extern struct video_device cx25821_video_template3;
+extern struct video_device cx25821_video_template4;
+extern struct video_device cx25821_video_template5;
+extern struct video_device cx25821_video_template6;
+extern struct video_device cx25821_video_template7;
+extern struct video_device cx25821_video_template9;
+extern struct video_device cx25821_video_template10;
+extern struct video_device cx25821_video_template11;
+extern struct video_device cx25821_videoioctl_template;
+//extern const u32 *ctrl_classes[];
+
+extern unsigned int vid_limit;
+
+#define FORMAT_FLAGS_PACKED       0x01
+extern struct cx25821_fmt formats[];
+extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
+extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
+
+extern void dump_video_queue(struct cx25821_dev *dev,
+			     struct cx25821_dmaqueue *q);
+extern void cx25821_video_wakeup(struct cx25821_dev *dev,
+				 struct cx25821_dmaqueue *q, u32 count);
+
+#ifdef TUNER_FLAG
+extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm);
+#endif
+
+extern int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
+		   unsigned int bit);
+extern int res_check(struct cx25821_fh *fh, unsigned int bit);
+extern int res_locked(struct cx25821_dev *dev, unsigned int bit);
+extern void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
+		     unsigned int bits);
+extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
+extern int cx25821_start_video_dma(struct cx25821_dev *dev,
+				   struct cx25821_dmaqueue *q,
+				   struct cx25821_buffer *buf,
+				   struct sram_channel *channel);
+
+extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width,
+			     unsigned int height, enum v4l2_field field);
+extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
+extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
+extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
+				  struct video_device *video_template);
+extern int get_format_size(void);
+
+extern int buffer_setup(struct videobuf_queue *q, unsigned int *count,
+			unsigned int *size);
+extern int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
+			  enum v4l2_field field);
+extern void buffer_release(struct videobuf_queue *q,
+			   struct videobuf_buffer *vb);
+extern struct videobuf_queue *get_queue(struct cx25821_fh *fh);
+extern int get_resource(struct cx25821_fh *fh, int resource);
+extern int video_mmap(struct file *file, struct vm_area_struct *vma);
+extern int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+				  struct v4l2_format *f);
+extern int vidioc_querycap(struct file *file, void *priv,
+			   struct v4l2_capability *cap);
+extern int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_fmtdesc *f);
+extern int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf);
+extern int vidioc_reqbufs(struct file *file, void *priv,
+			  struct v4l2_requestbuffers *p);
+extern int vidioc_querybuf(struct file *file, void *priv,
+			   struct v4l2_buffer *p);
+extern int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
+extern int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms);
+extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i);
+extern int vidioc_enum_input(struct file *file, void *priv,
+			     struct v4l2_input *i);
+extern int vidioc_g_input(struct file *file, void *priv, unsigned int *i);
+extern int vidioc_s_input(struct file *file, void *priv, unsigned int i);
+extern int vidioc_g_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl);
+extern int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f);
+extern int vidioc_g_frequency(struct file *file, void *priv,
+			      struct v4l2_frequency *f);
+extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f);
+extern int vidioc_s_frequency(struct file *file, void *priv,
+			      struct v4l2_frequency *f);
+extern int vidioc_g_register(struct file *file, void *fh,
+			     struct v4l2_dbg_register *reg);
+extern int vidioc_s_register(struct file *file, void *fh,
+			     struct v4l2_dbg_register *reg);
+extern int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
+extern int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
+
+extern int is_valid_width(u32 width, v4l2_std_id tvnorm);
+extern int is_valid_height(u32 height, v4l2_std_id tvnorm);
+
+extern int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p);
+extern int vidioc_s_priority(struct file *file, void *f,
+			     enum v4l2_priority prio);
+
+extern int vidioc_queryctrl(struct file *file, void *priv,
+			    struct v4l2_queryctrl *qctrl);
+extern int cx25821_set_control(struct cx25821_dev *dev,
+			       struct v4l2_control *ctrl, int chan_num);
+
+extern int vidioc_cropcap(struct file *file, void *fh,
+			  struct v4l2_cropcap *cropcap);
+extern int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop);
+extern int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop);
+
+extern int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm);
+#endif
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
new file mode 100644
index 0000000..950fac1
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video0.c
@@ -0,0 +1,451 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH00];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH00]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH00]
+		    && h->video_dev[SRAM_CH00]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH00;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO0))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO0)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH00]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel0->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO0)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO0);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO0)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO0);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = PIXEL_FRMT_422;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH00] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH00] = 0;
+	}
+	dev->cif_width[SRAM_CH00] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH00);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH00].count;
+
+	return ret_val;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH00];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 0 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH00);
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template0 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
new file mode 100644
index 0000000..a4dddc6
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video1.c
@@ -0,0 +1,451 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH01];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH01]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH01]
+		    && h->video_dev[SRAM_CH01]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH01;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO1))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO1)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH01]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel1->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO1)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO1);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO1)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO1);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = 0;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH01, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH01] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH01] = 0;
+	}
+	dev->cif_width[SRAM_CH01] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH01);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH01].count;
+
+	return ret_val;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH01];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 1 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH01);
+}
+
+//exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template1 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
new file mode 100644
index 0000000..8e04e25
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video2.c
@@ -0,0 +1,452 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH02];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH02]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH02]
+		    && h->video_dev[SRAM_CH02]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH02;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO2))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO2)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH02]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel2->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO2)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO2);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO2)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO2);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = 0;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH02, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH02] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH02] = 0;
+	}
+	dev->cif_width[SRAM_CH02] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH02);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH02].count;
+
+	return ret_val;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH02];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+
+	cx25821_call_all(dev, core, log_status);
+
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 2 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH02);
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template2 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
new file mode 100644
index 0000000..8801a8e
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video3.c
@@ -0,0 +1,451 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH03];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH03]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH03]
+		    && h->video_dev[SRAM_CH03]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH03;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO3))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO3)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH03]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel3->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO3)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO3);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO3)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO3);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = 0;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH03, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH03] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH03] = 0;
+	}
+	dev->cif_width[SRAM_CH03] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH03);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH03].count;
+
+	return ret_val;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH03];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 3 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH03);
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template3 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
new file mode 100644
index 0000000..ab0d747
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video4.c
@@ -0,0 +1,450 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH04];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH04]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH04]
+		    && h->video_dev[SRAM_CH04]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH04;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO4))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO4)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH04]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel4->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO4)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO4);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO4)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO4);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = 0;
+
+	// check priority
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH04, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH04] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH04] = 0;
+	}
+	dev->cif_width[SRAM_CH04] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH04);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH04].count;
+
+	return ret_val;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH04];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 4 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH04);
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template4 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
new file mode 100644
index 0000000..7ef0b97
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video5.c
@@ -0,0 +1,450 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH05];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH05]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH05]
+		    && h->video_dev[SRAM_CH05]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH05;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO5))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO5)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH05]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel5->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO5)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO5);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO5)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO5);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = 0;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH05, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH05] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH05] = 0;
+	}
+	dev->cif_width[SRAM_CH05] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH05);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH05].count;
+
+	return ret_val;
+}
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH05];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 5 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH05);
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template5 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
new file mode 100644
index 0000000..3c41b49
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video6.c
@@ -0,0 +1,450 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH06];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH06]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH06]
+		    && h->video_dev[SRAM_CH06]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH06;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO6))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO6)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH06]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel6->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO6)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO6);
+	}
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO6)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO6);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = 0;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH06, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH06] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH06] = 0;
+	}
+	dev->cif_width[SRAM_CH06] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH06);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH06].count;
+
+	return ret_val;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH06];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 6 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH06);
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template6 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
new file mode 100644
index 0000000..625c9b7
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video7.c
@@ -0,0 +1,449 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH07];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH07]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH07]
+		    && h->video_dev[SRAM_CH07]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = SRAM_CH07;
+	pix_format =
+	    (dev->pixel_formats[dev->channel_opened] ==
+	     PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO7))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO7)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+		if (buf->vb.state == VIDEOBUF_DONE) {
+			struct cx25821_dev *dev = fh->dev;
+
+			if (dev && dev->use_cif_resolution[SRAM_CH07]) {
+				u8 cam_id = *((char *)buf->vb.baddr + 3);
+				memcpy((char *)buf->vb.baddr,
+				       (char *)buf->vb.baddr + (fh->width * 2),
+				       (fh->width * 2));
+				*((char *)buf->vb.baddr + 3) = cam_id;
+			}
+		}
+
+		return POLLIN | POLLRDNORM;
+	}
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	cx_write(channel7->dma_ctl, 0);	/* FIFO and RISC disable */
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO7)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO7);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO7)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO7);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+	int pix_format = 0;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->vidq.field = f->fmt.pix.field;
+
+	// check if width and height is valid based on set standard
+	if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
+		fh->width = f->fmt.pix.width;
+	}
+
+	if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
+		fh->height = f->fmt.pix.height;
+	}
+
+	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+		pix_format = PIXEL_FRMT_411;
+	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+		pix_format = PIXEL_FRMT_422;
+	else
+		return -EINVAL;
+
+	cx25821_set_pixel_format(dev, SRAM_CH07, pix_format);
+
+	// check if cif resolution
+	if (fh->width == 320 || fh->width == 352) {
+		dev->use_cif_resolution[SRAM_CH07] = 1;
+	} else {
+		dev->use_cif_resolution[SRAM_CH07] = 0;
+	}
+	dev->cif_width[SRAM_CH07] = fh->width;
+	medusa_set_resolution(dev, fh->width, SRAM_CH07);
+
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	int ret_val = 0;
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+	p->sequence = dev->vidq[SRAM_CH07].count;
+
+	return ret_val;
+}
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH07];
+	u32 tmp = 0;
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+
+	tmp = cx_read(sram_ch->dma_ctl);
+	printk(KERN_INFO "Video input 7 is %s\n",
+	       (tmp & 0x11) ? "streaming" : "stopped");
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return cx25821_set_control(dev, ctl, SRAM_CH07);
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template7 = {
+	.name = "cx25821-video",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
new file mode 100644
index 0000000..2a312ce
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-videoioctl.c
@@ -0,0 +1,496 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[VIDEO_IOCTL_CH];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[VIDEO_IOCTL_CH]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+	u32 pix_format;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->ioctl_dev && h->ioctl_dev->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = VIDEO_IOCTL_CH;
+	pix_format = V4L2_PIX_FMT_YUYV;
+	fh->fmt = format_by_fourcc(pix_format);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO_IOCTL))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO_IOCTL);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO_IOCTL)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO_IOCTL);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->width = f->fmt.pix.width;
+	fh->height = f->fmt.pix.height;
+	fh->vidq.field = f->fmt.pix.field;
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct cx25821_fh *fh = priv;
+	return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+}
+
+static long video_ioctl_set(struct file *file, unsigned int cmd,
+			    unsigned long arg)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct downstream_user_struct *data_from_user;
+	int command;
+	int width = 720;
+	int selected_channel = 0, pix_format = 0, i = 0;
+	int cif_enable = 0, cif_width = 0;
+	u32 value = 0;
+
+	data_from_user = (struct downstream_user_struct *)arg;
+
+	if (!data_from_user) {
+		printk("cx25821 in %s(): User data is INVALID. Returning.\n",
+		       __func__);
+		return 0;
+	}
+
+	command = data_from_user->command;
+
+	if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
+	    && command != ENABLE_CIF_RESOLUTION && command != REG_READ
+	    && command != REG_WRITE && command != MEDUSA_READ
+	    && command != MEDUSA_WRITE) {
+		return 0;
+	}
+
+	switch (command) {
+	case SET_VIDEO_STD:
+		dev->tvnorm =
+		    !strcmp(data_from_user->vid_stdname,
+			    "PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
+		medusa_set_videostandard(dev);
+		break;
+
+	case SET_PIXEL_FORMAT:
+		selected_channel = data_from_user->decoder_select;
+		pix_format = data_from_user->pixel_format;
+
+		if (!(selected_channel <= 7 && selected_channel >= 0)) {
+			selected_channel -= 4;
+			selected_channel = selected_channel % 8;
+		}
+
+		if (selected_channel >= 0)
+			cx25821_set_pixel_format(dev, selected_channel,
+						 pix_format);
+
+		break;
+
+	case ENABLE_CIF_RESOLUTION:
+		selected_channel = data_from_user->decoder_select;
+		cif_enable = data_from_user->cif_resolution_enable;
+		cif_width = data_from_user->cif_width;
+
+		if (cif_enable) {
+			if (dev->tvnorm & V4L2_STD_PAL_BG
+			    || dev->tvnorm & V4L2_STD_PAL_DK)
+				width = 352;
+			else
+				width = (cif_width == 320
+					 || cif_width == 352) ? cif_width : 320;
+		}
+
+		if (!(selected_channel <= 7 && selected_channel >= 0)) {
+			selected_channel -= 4;
+			selected_channel = selected_channel % 8;
+		}
+
+		if (selected_channel <= 7 && selected_channel >= 0) {
+			dev->use_cif_resolution[selected_channel] = cif_enable;
+			dev->cif_width[selected_channel] = width;
+		} else {
+			for (i = 0; i < VID_CHANNEL_NUM; i++) {
+				dev->use_cif_resolution[i] = cif_enable;
+				dev->cif_width[i] = width;
+			}
+		}
+
+		medusa_set_resolution(dev, width, selected_channel);
+		break;
+	case REG_READ:
+		data_from_user->reg_data = cx_read(data_from_user->reg_address);
+		break;
+	case REG_WRITE:
+		cx_write(data_from_user->reg_address, data_from_user->reg_data);
+		break;
+	case MEDUSA_READ:
+		value =
+		    cx25821_i2c_read(&dev->i2c_bus[0],
+				     (u16) data_from_user->reg_address,
+				     &data_from_user->reg_data);
+		break;
+	case MEDUSA_WRITE:
+		cx25821_i2c_write(&dev->i2c_bus[0],
+				  (u16) data_from_user->reg_address,
+				  data_from_user->reg_data);
+		break;
+	}
+
+	return 0;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return 0;
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl_set,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_videoioctl_template = {
+	.name = "cx25821-videoioctl",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
new file mode 100644
index 0000000..77b63b0
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups10.c
@@ -0,0 +1,435 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH10];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH10]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH10]
+		    && h->video_dev[SRAM_CH10]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = 9;
+	fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO10))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO10)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	//cx_write(channel10->dma_ctl, 0);
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO10)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO10);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO10)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO10);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
+				   unsigned long arg)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+	int command = 0;
+	struct upstream_user_struct *data_from_user;
+
+	data_from_user = (struct upstream_user_struct *)arg;
+
+	if (!data_from_user) {
+		printk
+		    ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
+		     __func__);
+		return 0;
+	}
+
+	command = data_from_user->command;
+
+	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
+		return 0;
+	}
+
+	dev->input_filename_ch2 = data_from_user->input_filename;
+	dev->input_audiofilename = data_from_user->input_filename;
+	dev->vid_stdname_ch2 = data_from_user->vid_stdname;
+	dev->pixel_format_ch2 = data_from_user->pixel_format;
+	dev->channel_select_ch2 = data_from_user->channel_select;
+	dev->command_ch2 = data_from_user->command;
+
+	switch (command) {
+	case UPSTREAM_START_VIDEO:
+		cx25821_start_upstream_video_ch2(dev, data_from_user);
+		break;
+
+	case UPSTREAM_STOP_VIDEO:
+		cx25821_stop_upstream_video_ch2(dev);
+		break;
+	}
+
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->width = f->fmt.pix.width;
+	fh->height = f->fmt.pix.height;
+	fh->vidq.field = f->fmt.pix.field;
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct cx25821_fh *fh = priv;
+	return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return 0;
+}
+
+//exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl_upstream10,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template10 = {
+	.name = "cx25821-upstream10",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
new file mode 100644
index 0000000..75c8c1e
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups9.c
@@ -0,0 +1,433 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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.
+ */
+
+#include "cx25821-video.h"
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+	struct cx25821_buffer *buf =
+	    container_of(vb, struct cx25821_buffer, vb);
+	struct cx25821_buffer *prev;
+	struct cx25821_fh *fh = vq->priv_data;
+	struct cx25821_dev *dev = fh->dev;
+	struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH09];
+
+	/* add jump to stopper */
+	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+	buf->risc.jmp[2] = cpu_to_le32(0);	/* bits 63-32 */
+
+	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+	if (!list_empty(&q->queued)) {
+		list_add_tail(&buf->vb.queue, &q->queued);
+		buf->vb.state = VIDEOBUF_QUEUED;
+		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+			buf->vb.i);
+
+	} else if (list_empty(&q->active)) {
+		list_add_tail(&buf->vb.queue, &q->active);
+		cx25821_start_video_dma(dev, q, buf,
+					&dev->sram_channels[SRAM_CH09]);
+		buf->vb.state = VIDEOBUF_ACTIVE;
+		buf->count = q->count++;
+		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+		dprintk(2,
+			"[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
+			buf, buf->vb.i, buf->count, q->count);
+	} else {
+		prev =
+		    list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+		if (prev->vb.width == buf->vb.width
+		    && prev->vb.height == buf->vb.height
+		    && prev->fmt == buf->fmt) {
+			list_add_tail(&buf->vb.queue, &q->active);
+			buf->vb.state = VIDEOBUF_ACTIVE;
+			buf->count = q->count++;
+			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+			/* 64 bit bits 63-32 */
+			prev->risc.jmp[2] = cpu_to_le32(0);
+			dprintk(2,
+				"[%p/%d] buffer_queue - append to active, buf->count=%d\n",
+				buf, buf->vb.i, buf->count);
+
+		} else {
+			list_add_tail(&buf->vb.queue, &q->queued);
+			buf->vb.state = VIDEOBUF_QUEUED;
+			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+				buf->vb.i);
+		}
+	}
+
+	if (list_empty(&q->active)) {
+		dprintk(2, "active queue empty!\n");
+	}
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+	.buf_setup = buffer_setup,
+	.buf_prepare = buffer_prepare,
+	.buf_queue = buffer_queue,
+	.buf_release = buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+	int minor = video_devdata(file)->minor;
+	struct cx25821_dev *h, *dev = NULL;
+	struct cx25821_fh *fh;
+	struct list_head *list;
+	enum v4l2_buf_type type = 0;
+
+	lock_kernel();
+	list_for_each(list, &cx25821_devlist) {
+		h = list_entry(list, struct cx25821_dev, devlist);
+
+		if (h->video_dev[SRAM_CH09]
+		    && h->video_dev[SRAM_CH09]->minor == minor) {
+			dev = h;
+			type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		}
+	}
+
+	if (NULL == dev) {
+		unlock_kernel();
+		return -ENODEV;
+	}
+
+	printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
+
+	/* allocate + initialize per filehandle data */
+	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+	if (NULL == fh) {
+		unlock_kernel();
+		return -ENOMEM;
+	}
+
+	file->private_data = fh;
+	fh->dev = dev;
+	fh->type = type;
+	fh->width = 720;
+
+	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+		fh->height = 576;
+	else
+		fh->height = 480;
+
+	dev->channel_opened = 8;
+	fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
+
+	v4l2_prio_open(&dev->prio, &fh->prio);
+
+	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+			       &dev->pci->dev, &dev->slock,
+			       V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			       V4L2_FIELD_INTERLACED,
+			       sizeof(struct cx25821_buffer), fh);
+
+	dprintk(1, "post videobuf_queue_init()\n");
+	unlock_kernel();
+
+	return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+			  loff_t * ppos)
+{
+	struct cx25821_fh *fh = file->private_data;
+
+	switch (fh->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		if (res_locked(fh->dev, RESOURCE_VIDEO9))
+			return -EBUSY;
+
+		return videobuf_read_one(&fh->vidq, data, count, ppos,
+					 file->f_flags & O_NONBLOCK);
+
+	default:
+		BUG();
+		return 0;
+	}
+}
+
+static unsigned int video_poll(struct file *file,
+			       struct poll_table_struct *wait)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_buffer *buf;
+
+	if (res_check(fh, RESOURCE_VIDEO9)) {
+		/* streaming capture */
+		if (list_empty(&fh->vidq.stream))
+			return POLLERR;
+		buf = list_entry(fh->vidq.stream.next,
+				 struct cx25821_buffer, vb.stream);
+	} else {
+		/* read() capture */
+		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+		if (NULL == buf)
+			return POLLERR;
+	}
+
+	poll_wait(file, &buf->vb.done, wait);
+	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static int video_release(struct file *file)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+
+	//stop the risc engine and fifo
+	//cx_write(channel9->dma_ctl, 0);
+
+	/* stop video capture */
+	if (res_check(fh, RESOURCE_VIDEO9)) {
+		videobuf_queue_cancel(&fh->vidq);
+		res_free(dev, fh, RESOURCE_VIDEO9);
+	}
+
+	if (fh->vidq.read_buf) {
+		buffer_release(&fh->vidq, fh->vidq.read_buf);
+		kfree(fh->vidq.read_buf);
+	}
+
+	videobuf_mmap_free(&fh->vidq);
+
+	v4l2_prio_close(&dev->prio, &fh->prio);
+
+	file->private_data = NULL;
+	kfree(fh);
+
+	return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+
+	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(i != fh->type)) {
+		return -EINVAL;
+	}
+
+	if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO9)))) {
+		return -EBUSY;
+	}
+
+	return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = fh->dev;
+	int err, res;
+
+	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+	if (i != fh->type)
+		return -EINVAL;
+
+	res = get_resource(fh, RESOURCE_VIDEO9);
+	err = videobuf_streamoff(get_queue(fh));
+	if (err < 0)
+		return err;
+	res_free(dev, fh, res);
+	return 0;
+}
+
+static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
+				  unsigned long arg)
+{
+	struct cx25821_fh *fh = file->private_data;
+	struct cx25821_dev *dev = fh->dev;
+	int command = 0;
+	struct upstream_user_struct *data_from_user;
+
+	data_from_user = (struct upstream_user_struct *)arg;
+
+	if (!data_from_user) {
+		printk
+		    ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
+		     __func__);
+		return 0;
+	}
+
+	command = data_from_user->command;
+
+	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
+		return 0;
+	}
+
+	dev->input_filename = data_from_user->input_filename;
+	dev->input_audiofilename = data_from_user->input_filename;
+	dev->vid_stdname = data_from_user->vid_stdname;
+	dev->pixel_format = data_from_user->pixel_format;
+	dev->channel_select = data_from_user->channel_select;
+	dev->command = data_from_user->command;
+
+	switch (command) {
+	case UPSTREAM_START_VIDEO:
+		cx25821_start_upstream_video_ch1(dev, data_from_user);
+		break;
+
+	case UPSTREAM_STOP_VIDEO:
+		cx25821_stop_upstream_video_ch1(dev);
+		break;
+	}
+
+	return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+				struct v4l2_format *f)
+{
+	struct cx25821_fh *fh = priv;
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	int err;
+
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	dprintk(2, "%s()\n", __func__);
+	err = vidioc_try_fmt_vid_cap(file, priv, f);
+
+	if (0 != err)
+		return err;
+	fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+	fh->width = f->fmt.pix.width;
+	fh->height = f->fmt.pix.height;
+	fh->vidq.field = f->fmt.pix.field;
+	dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+		fh->height, fh->vidq.field);
+	cx25821_call_all(dev, video, s_fmt, f);
+	return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct cx25821_fh *fh = priv;
+	return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+}
+static int vidioc_log_status(struct file *file, void *priv)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	char name[32 + 2];
+
+	snprintf(name, sizeof(name), "%s/2", dev->name);
+	printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
+	       dev->name);
+	cx25821_call_all(dev, core, log_status);
+	printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
+	       dev->name);
+	return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+			 struct v4l2_control *ctl)
+{
+	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+	struct cx25821_fh *fh = priv;
+	int err;
+	if (fh) {
+		err = v4l2_prio_check(&dev->prio, &fh->prio);
+		if (0 != err)
+			return err;
+	}
+
+	return 0;
+}
+
+// exported stuff
+static const struct v4l2_file_operations video_fops = {
+	.owner = THIS_MODULE,
+	.open = video_open,
+	.release = video_release,
+	.read = video_read,
+	.poll = video_poll,
+	.mmap = video_mmap,
+	.ioctl = video_ioctl_upstream9,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+	.vidioc_querycap = vidioc_querycap,
+	.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+	.vidioc_reqbufs = vidioc_reqbufs,
+	.vidioc_querybuf = vidioc_querybuf,
+	.vidioc_qbuf = vidioc_qbuf,
+	.vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+	.vidioc_s_std = vidioc_s_std,
+	.vidioc_querystd = vidioc_querystd,
+#endif
+	.vidioc_cropcap = vidioc_cropcap,
+	.vidioc_s_crop = vidioc_s_crop,
+	.vidioc_g_crop = vidioc_g_crop,
+	.vidioc_enum_input = vidioc_enum_input,
+	.vidioc_g_input = vidioc_g_input,
+	.vidioc_s_input = vidioc_s_input,
+	.vidioc_g_ctrl = vidioc_g_ctrl,
+	.vidioc_s_ctrl = vidioc_s_ctrl,
+	.vidioc_queryctrl = vidioc_queryctrl,
+	.vidioc_streamon = vidioc_streamon,
+	.vidioc_streamoff = vidioc_streamoff,
+	.vidioc_log_status = vidioc_log_status,
+	.vidioc_g_priority = vidioc_g_priority,
+	.vidioc_s_priority = vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+	.vidiocgmbuf = vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+	.vidioc_g_tuner = vidioc_g_tuner,
+	.vidioc_s_tuner = vidioc_s_tuner,
+	.vidioc_g_frequency = vidioc_g_frequency,
+	.vidioc_s_frequency = vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	.vidioc_g_register = vidioc_g_register,
+	.vidioc_s_register = vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_video_template9 = {
+	.name = "cx25821-upstream9",
+	.fops = &video_fops,
+	.minor = -1,
+	.ioctl_ops = &video_ioctl_ops,
+	.tvnorms = CX25821_NORMS,
+	.current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
new file mode 100644
index 0000000..cf2286d
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821.h
@@ -0,0 +1,602 @@
+/*
+ *  Driver for the Conexant CX25821 PCIe bridge
+ *
+ *  Copyright (C) 2009 Conexant Systems Inc.
+ *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
+ *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ *  GNU 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 CX25821_H_
+#define CX25821_H_
+
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/kdev_t.h>
+#include <linux/smp_lock.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+#include <media/videobuf-dma-sg.h>
+#include <media/videobuf-dvb.h>
+
+#include "btcx-risc.h"
+#include "cx25821-reg.h"
+#include "cx25821-medusa-reg.h"
+#include "cx25821-sram.h"
+#include "cx25821-audio.h"
+#include "media/cx2341x.h"
+
+#include <linux/version.h>
+#include <linux/mutex.h>
+
+#define CX25821_VERSION_CODE KERNEL_VERSION(0, 0, 106)
+
+#define UNSET (-1U)
+#define NO_SYNC_LINE (-1U)
+
+#define CX25821_MAXBOARDS 2
+
+#define TRUE    1
+#define FALSE   0
+#define LINE_SIZE_D1    1440
+
+// Number of decoders and encoders
+#define MAX_DECODERS            8
+#define MAX_ENCODERS            2
+#define QUAD_DECODERS           4
+#define MAX_CAMERAS             16
+
+/* Max number of inputs by card */
+#define MAX_CX25821_INPUT 8
+#define INPUT(nr) (&cx25821_boards[dev->board].input[nr])
+#define RESOURCE_VIDEO0       1
+#define RESOURCE_VIDEO1       2
+#define RESOURCE_VIDEO2       4
+#define RESOURCE_VIDEO3       8
+#define RESOURCE_VIDEO4       16
+#define RESOURCE_VIDEO5       32
+#define RESOURCE_VIDEO6       64
+#define RESOURCE_VIDEO7       128
+#define RESOURCE_VIDEO8       256
+#define RESOURCE_VIDEO9       512
+#define RESOURCE_VIDEO10      1024
+#define RESOURCE_VIDEO11      2048
+#define RESOURCE_VIDEO_IOCTL  4096
+
+#define BUFFER_TIMEOUT     (HZ)	/* 0.5 seconds */
+
+#define UNKNOWN_BOARD       0
+#define CX25821_BOARD        1
+
+/* Currently supported by the driver */
+#define CX25821_NORMS (\
+    V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \
+    V4L2_STD_PAL_BG |  V4L2_STD_PAL_DK    |  V4L2_STD_PAL_I    | \
+    V4L2_STD_PAL_M  |  V4L2_STD_PAL_N     |  V4L2_STD_PAL_H    | \
+    V4L2_STD_PAL_Nc )
+
+#define CX25821_BOARD_CONEXANT_ATHENA10 1
+#define MAX_VID_CHANNEL_NUM     12
+#define VID_CHANNEL_NUM 8
+
+struct cx25821_fmt {
+	char *name;
+	u32 fourcc;		/* v4l2 format id */
+	int depth;
+	int flags;
+	u32 cxformat;
+};
+
+struct cx25821_ctrl {
+	struct v4l2_queryctrl v;
+	u32 off;
+	u32 reg;
+	u32 mask;
+	u32 shift;
+};
+
+struct cx25821_tvnorm {
+	char *name;
+	v4l2_std_id id;
+	u32 cxiformat;
+	u32 cxoformat;
+};
+
+struct cx25821_fh {
+	struct cx25821_dev *dev;
+	enum v4l2_buf_type type;
+	int radio;
+	u32 resources;
+
+	enum v4l2_priority prio;
+
+	/* video overlay */
+	struct v4l2_window win;
+	struct v4l2_clip *clips;
+	unsigned int nclips;
+
+	/* video capture */
+	struct cx25821_fmt *fmt;
+	unsigned int width, height;
+
+	/* vbi capture */
+	struct videobuf_queue vidq;
+	struct videobuf_queue vbiq;
+
+	/* H264 Encoder specifics ONLY */
+	struct videobuf_queue mpegq;
+	atomic_t v4l_reading;
+};
+
+enum cx25821_itype {
+	CX25821_VMUX_COMPOSITE = 1,
+	CX25821_VMUX_SVIDEO,
+	CX25821_VMUX_DEBUG,
+	CX25821_RADIO,
+};
+
+enum cx25821_src_sel_type {
+	CX25821_SRC_SEL_EXT_656_VIDEO = 0,
+	CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO
+};
+
+/* buffer for one video frame */
+struct cx25821_buffer {
+	/* common v4l buffer stuff -- must be first */
+	struct videobuf_buffer vb;
+
+	/* cx25821 specific */
+	unsigned int bpl;
+	struct btcx_riscmem risc;
+	struct cx25821_fmt *fmt;
+	u32 count;
+};
+
+struct cx25821_input {
+	enum cx25821_itype type;
+	unsigned int vmux;
+	u32 gpio0, gpio1, gpio2, gpio3;
+};
+
+typedef enum {
+	CX25821_UNDEFINED = 0,
+	CX25821_RAW,
+	CX25821_264
+} port_t;
+
+struct cx25821_board {
+	char *name;
+	port_t porta, portb, portc;
+	unsigned int tuner_type;
+	unsigned int radio_type;
+	unsigned char tuner_addr;
+	unsigned char radio_addr;
+
+	u32 clk_freq;
+	struct cx25821_input input[2];
+};
+
+struct cx25821_subid {
+	u16 subvendor;
+	u16 subdevice;
+	u32 card;
+};
+
+struct cx25821_i2c {
+	struct cx25821_dev *dev;
+
+	int nr;
+
+	/* i2c i/o */
+	struct i2c_adapter i2c_adap;
+	struct i2c_algo_bit_data i2c_algo;
+	struct i2c_client i2c_client;
+	u32 i2c_rc;
+
+	/* cx25821 registers used for raw addess */
+	u32 i2c_period;
+	u32 reg_ctrl;
+	u32 reg_stat;
+	u32 reg_addr;
+	u32 reg_rdata;
+	u32 reg_wdata;
+};
+
+struct cx25821_dmaqueue {
+	struct list_head active;
+	struct list_head queued;
+	struct timer_list timeout;
+	struct btcx_riscmem stopper;
+	u32 count;
+};
+
+struct cx25821_data {
+	struct cx25821_dev *dev;
+	struct sram_channel *channel;
+};
+
+struct cx25821_dev {
+	struct list_head devlist;
+	atomic_t refcount;
+	struct v4l2_device v4l2_dev;
+
+	struct v4l2_prio_state prio;
+
+	/* pci stuff */
+	struct pci_dev *pci;
+	unsigned char pci_rev, pci_lat;
+	int pci_bus, pci_slot;
+	u32 base_io_addr;
+	u32 __iomem *lmmio;
+	u8 __iomem *bmmio;
+	int pci_irqmask;
+	int hwrevision;
+
+	u32 clk_freq;
+
+	/* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
+	struct cx25821_i2c i2c_bus[3];
+
+	int nr;
+	struct mutex lock;
+
+	/* board details */
+	unsigned int board;
+	char name[32];
+
+	/* sram configuration */
+	struct sram_channel *sram_channels;
+
+	/* Analog video */
+	u32 resources;
+	unsigned int input;
+	u32 tvaudio;
+	v4l2_std_id tvnorm;
+	unsigned int tuner_type;
+	unsigned char tuner_addr;
+	unsigned int radio_type;
+	unsigned char radio_addr;
+	unsigned int has_radio;
+	unsigned int videc_type;
+	unsigned char videc_addr;
+	unsigned short _max_num_decoders;
+
+	int ctl_bright;
+	int ctl_contrast;
+	int ctl_hue;
+	int ctl_saturation;
+
+	struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
+
+	/* Analog Audio Upstream */
+	int _audio_is_running;
+	int _audiopixel_format;
+	int _is_first_audio_frame;
+	int _audiofile_status;
+	int _audio_lines_count;
+	int _audioframe_count;
+	int _audio_upstream_channel_select;
+	int _last_index_irq;	//The last interrupt index processed.
+
+	__le32 *_risc_audio_jmp_addr;
+	__le32 *_risc_virt_start_addr;
+	__le32 *_risc_virt_addr;
+	dma_addr_t _risc_phys_addr;
+	dma_addr_t _risc_phys_start_addr;
+
+	unsigned int _audiorisc_size;
+	unsigned int _audiodata_buf_size;
+	__le32 *_audiodata_buf_virt_addr;
+	dma_addr_t _audiodata_buf_phys_addr;
+	char *_audiofilename;
+
+	/* V4l */
+	u32 freq;
+	struct video_device *video_dev[MAX_VID_CHANNEL_NUM];
+	struct video_device *vbi_dev;
+	struct video_device *radio_dev;
+	struct video_device *ioctl_dev;
+
+	struct cx25821_dmaqueue vidq[MAX_VID_CHANNEL_NUM];
+	spinlock_t slock;
+
+	/* Video Upstream */
+	int _line_size;
+	int _prog_cnt;
+	int _pixel_format;
+	int _is_first_frame;
+	int _is_running;
+	int _file_status;
+	int _lines_count;
+	int _frame_count;
+	int _channel_upstream_select;
+	unsigned int _risc_size;
+
+	__le32 *_dma_virt_start_addr;
+	__le32 *_dma_virt_addr;
+	dma_addr_t _dma_phys_addr;
+	dma_addr_t _dma_phys_start_addr;
+
+	unsigned int _data_buf_size;
+	__le32 *_data_buf_virt_addr;
+	dma_addr_t _data_buf_phys_addr;
+	char *_filename;
+	char *_defaultname;
+
+	int _line_size_ch2;
+	int _prog_cnt_ch2;
+	int _pixel_format_ch2;
+	int _is_first_frame_ch2;
+	int _is_running_ch2;
+	int _file_status_ch2;
+	int _lines_count_ch2;
+	int _frame_count_ch2;
+	int _channel2_upstream_select;
+	unsigned int _risc_size_ch2;
+
+	__le32 *_dma_virt_start_addr_ch2;
+	__le32 *_dma_virt_addr_ch2;
+	dma_addr_t _dma_phys_addr_ch2;
+	dma_addr_t _dma_phys_start_addr_ch2;
+
+	unsigned int _data_buf_size_ch2;
+	__le32 *_data_buf_virt_addr_ch2;
+	dma_addr_t _data_buf_phys_addr_ch2;
+	char *_filename_ch2;
+	char *_defaultname_ch2;
+
+	/* MPEG Encoder ONLY settings */
+	u32 cx23417_mailbox;
+	struct cx2341x_mpeg_params mpeg_params;
+	struct video_device *v4l_device;
+	atomic_t v4l_reader_count;
+	struct cx25821_tvnorm encodernorm;
+
+	u32 upstream_riscbuf_size;
+	u32 upstream_databuf_size;
+	u32 upstream_riscbuf_size_ch2;
+	u32 upstream_databuf_size_ch2;
+	u32 audio_upstream_riscbuf_size;
+	u32 audio_upstream_databuf_size;
+	int _isNTSC;
+	int _frame_index;
+	int _audioframe_index;
+	struct workqueue_struct *_irq_queues;
+	struct work_struct _irq_work_entry;
+	struct workqueue_struct *_irq_queues_ch2;
+	struct work_struct _irq_work_entry_ch2;
+	struct workqueue_struct *_irq_audio_queues;
+	struct work_struct _audio_work_entry;
+	char *input_filename;
+	char *input_filename_ch2;
+	int _frame_index_ch2;
+	int _isNTSC_ch2;
+	char *vid_stdname_ch2;
+	int pixel_format_ch2;
+	int channel_select_ch2;
+	int command_ch2;
+	char *input_audiofilename;
+	char *vid_stdname;
+	int pixel_format;
+	int channel_select;
+	int command;
+	int pixel_formats[VID_CHANNEL_NUM];
+	int use_cif_resolution[VID_CHANNEL_NUM];
+	int cif_width[VID_CHANNEL_NUM];
+	int channel_opened;
+};
+
+struct upstream_user_struct {
+	char *input_filename;
+	char *vid_stdname;
+	int pixel_format;
+	int channel_select;
+	int command;
+};
+
+struct downstream_user_struct {
+	char *vid_stdname;
+	int pixel_format;
+	int cif_resolution_enable;
+	int cif_width;
+	int decoder_select;
+	int command;
+	int reg_address;
+	int reg_data;
+};
+
+extern struct upstream_user_struct *up_data;
+
+static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev);
+}
+
+#define cx25821_call_all(dev, o, f, args...) \
+    v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
+
+extern struct list_head cx25821_devlist;
+extern struct cx25821_board cx25821_boards[];
+extern struct cx25821_subid cx25821_subids[];
+
+#define SRAM_CH00  0		/* Video A */
+#define SRAM_CH01  1		/* Video B */
+#define SRAM_CH02  2		/* Video C */
+#define SRAM_CH03  3		/* Video D */
+#define SRAM_CH04  4		/* Video E */
+#define SRAM_CH05  5		/* Video F */
+#define SRAM_CH06  6		/* Video G */
+#define SRAM_CH07  7		/* Video H */
+
+#define SRAM_CH08  8		/* Audio A */
+#define SRAM_CH09  9		/* Video Upstream I */
+#define SRAM_CH10  10		/* Video Upstream J */
+#define SRAM_CH11  11		/* Audio Upstream AUD_CHANNEL_B */
+
+#define VID_UPSTREAM_SRAM_CHANNEL_I     SRAM_CH09
+#define VID_UPSTREAM_SRAM_CHANNEL_J     SRAM_CH10
+#define AUDIO_UPSTREAM_SRAM_CHANNEL_B   SRAM_CH11
+#define VIDEO_IOCTL_CH  11
+
+struct sram_channel {
+	char *name;
+	u32 i;
+	u32 cmds_start;
+	u32 ctrl_start;
+	u32 cdt;
+	u32 fifo_start;
+	u32 fifo_size;
+	u32 ptr1_reg;
+	u32 ptr2_reg;
+	u32 cnt1_reg;
+	u32 cnt2_reg;
+	u32 int_msk;
+	u32 int_stat;
+	u32 int_mstat;
+	u32 dma_ctl;
+	u32 gpcnt_ctl;
+	u32 gpcnt;
+	u32 aud_length;
+	u32 aud_cfg;
+	u32 fld_aud_fifo_en;
+	u32 fld_aud_risc_en;
+
+	//For Upstream Video
+	u32 vid_fmt_ctl;
+	u32 vid_active_ctl1;
+	u32 vid_active_ctl2;
+	u32 vid_cdt_size;
+
+	u32 vip_ctl;
+	u32 pix_frmt;
+	u32 jumponly;
+	u32 irq_bit;
+};
+extern struct sram_channel cx25821_sram_channels[];
+
+#define STATUS_SUCCESS         0
+#define STATUS_UNSUCCESSFUL    -1
+
+#define cx_read(reg)             readl(dev->lmmio + ((reg)>>2))
+#define cx_write(reg, value)     writel((value), dev->lmmio + ((reg)>>2))
+
+#define cx_andor(reg, mask, value) \
+  writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
+  ((value) & (mask)), dev->lmmio+((reg)>>2))
+
+#define cx_set(reg, bit)          cx_andor((reg), (bit), (bit))
+#define cx_clear(reg, bit)        cx_andor((reg), (bit), 0)
+
+#define Set_GPIO_Bit(Bit)                       (1 << Bit)
+#define Clear_GPIO_Bit(Bit)                     (~(1 << Bit))
+
+#define CX25821_ERR(fmt, args...)      printk(KERN_ERR  "cx25821(%d): " fmt, dev->board, ## args)
+#define CX25821_WARN(fmt, args...)     printk(KERN_WARNING "cx25821(%d): " fmt, dev->board , ## args)
+#define CX25821_INFO(fmt, args...)     printk(KERN_INFO "cx25821(%d): " fmt, dev->board , ## args)
+
+extern int cx25821_i2c_register(struct cx25821_i2c *bus);
+extern void cx25821_card_setup(struct cx25821_dev *dev);
+extern int cx25821_ir_init(struct cx25821_dev *dev);
+extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value);
+extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value);
+extern int cx25821_i2c_unregister(struct cx25821_i2c *bus);
+extern void cx25821_gpio_init(struct cx25821_dev *dev);
+extern void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
+					  int pin_number, int pin_logic_value);
+
+extern int medusa_video_init(struct cx25821_dev *dev);
+extern int medusa_set_videostandard(struct cx25821_dev *dev);
+extern void medusa_set_resolution(struct cx25821_dev *dev, int width,
+				  int decoder_select);
+extern int medusa_set_brightness(struct cx25821_dev *dev, int brightness,
+				 int decoder);
+extern int medusa_set_contrast(struct cx25821_dev *dev, int contrast,
+			       int decoder);
+extern int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder);
+extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation,
+				 int decoder);
+
+extern int cx25821_sram_channel_setup(struct cx25821_dev *dev,
+				      struct sram_channel *ch, unsigned int bpl,
+				      u32 risc);
+
+extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
+			       struct scatterlist *sglist,
+			       unsigned int top_offset,
+			       unsigned int bottom_offset,
+			       unsigned int bpl,
+			       unsigned int padding, unsigned int lines);
+extern int cx25821_risc_databuffer_audio(struct pci_dev *pci,
+					 struct btcx_riscmem *risc,
+					 struct scatterlist *sglist,
+					 unsigned int bpl,
+					 unsigned int lines, unsigned int lpi);
+extern void cx25821_free_buffer(struct videobuf_queue *q,
+				struct cx25821_buffer *buf);
+extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
+				u32 reg, u32 mask, u32 value);
+extern void cx25821_sram_channel_dump(struct cx25821_dev *dev,
+				      struct sram_channel *ch);
+extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
+					    struct sram_channel *ch);
+
+extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci);
+extern void cx25821_print_irqbits(char *name, char *tag, char **strings,
+				  int len, u32 bits, u32 mask);
+extern void cx25821_dev_unregister(struct cx25821_dev *dev);
+extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
+					    struct sram_channel *ch,
+					    unsigned int bpl, u32 risc);
+
+extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev,
+					int channel_select, int pixel_format);
+extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev,
+					int channel_select, int pixel_format);
+extern int cx25821_audio_upstream_init(struct cx25821_dev *dev,
+				       int channel_select);
+extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev);
+extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev);
+extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
+extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
+					     struct upstream_user_struct
+					     *up_data);
+extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
+					     struct upstream_user_struct
+					     *up_data);
+extern void cx25821_start_upstream_audio(struct cx25821_dev *dev,
+					 struct upstream_user_struct *up_data);
+extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev);
+extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev);
+extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);
+extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
+					       struct sram_channel *ch,
+					       unsigned int bpl, u32 risc);
+extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel,
+				     u32 format);
+extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev);
+extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
+					      struct pci_dev *pci,
+					      struct video_device *template,
+					      char *type);
+#endif
diff --git a/drivers/staging/dream/Kconfig b/drivers/staging/dream/Kconfig
new file mode 100644
index 0000000..52bd187
--- /dev/null
+++ b/drivers/staging/dream/Kconfig
@@ -0,0 +1,12 @@
+source "drivers/staging/dream/smd/Kconfig"
+
+source "drivers/staging/dream/camera/Kconfig"
+
+
+config INPUT_GPIO
+	tristate "GPIO driver support"
+	help
+	  Say Y here if you want to support gpio based keys, wheels etc...
+
+
+
diff --git a/drivers/staging/dream/Makefile b/drivers/staging/dream/Makefile
new file mode 100644
index 0000000..2b79151
--- /dev/null
+++ b/drivers/staging/dream/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_MSM_ADSP)		+= qdsp5/ smd/
+obj-$(CONFIG_MSM_CAMERA)	+= camera/
+obj-$(CONFIG_INPUT_GPIO)	+= gpio_axis.o gpio_event.o gpio_input.o gpio_matrix.o gpio_output.o
+
diff --git a/drivers/staging/dream/camera/Kconfig b/drivers/staging/dream/camera/Kconfig
new file mode 100644
index 0000000..0a3e903
--- /dev/null
+++ b/drivers/staging/dream/camera/Kconfig
@@ -0,0 +1,46 @@
+comment "Qualcomm MSM Camera And Video"
+
+menuconfig MSM_CAMERA
+	bool "Qualcomm MSM camera and video capture support"
+	depends on ARCH_MSM && VIDEO_V4L2_COMMON
+	help
+	  Say Y here to enable selecting the video adapters for
+	  Qualcomm msm camera and video encoding
+
+config MSM_CAMERA_DEBUG
+	bool "Qualcomm MSM camera debugging with printk"
+	depends on MSM_CAMERA
+	help
+	  Enable printk() debug for msm camera
+
+config MSM_CAMERA_FLASH
+	bool "Qualcomm MSM camera flash support"
+	depends on MSM_CAMERA
+	---help---
+	  Enable support for LED flash for msm camera
+
+
+comment "Camera Sensor Selection"
+config MT9T013
+	bool "Sensor mt9t013 (BAYER 3M)"
+	depends on MSM_CAMERA
+	---help---
+	  MICRON 3M Bayer Sensor with AutoFocus
+
+config MT9D112
+	bool "Sensor mt9d112 (YUV 2M)"
+	depends on MSM_CAMERA
+	---help---
+	  MICRON 2M YUV Sensor
+
+config MT9P012
+	bool "Sensor mt9p012 (BAYER 5M)"
+	depends on MSM_CAMERA
+	---help---
+	  MICRON 5M Bayer Sensor with Autofocus
+
+config S5K3E2FX
+	bool "Sensor s5k3e2fx (Samsung 5M)"
+	depends on MSM_CAMERA
+	---help---
+	  Samsung 5M with Autofocus
diff --git a/drivers/staging/dream/camera/Makefile b/drivers/staging/dream/camera/Makefile
new file mode 100644
index 0000000..4429ae5
--- /dev/null
+++ b/drivers/staging/dream/camera/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_MT9T013) += mt9t013.o mt9t013_reg.o
+obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
+obj-$(CONFIG_MT9P012) += mt9p012_fox.o mt9p012_reg.o
+obj-$(CONFIG_MSM_CAMERA) += msm_camera.o msm_v4l2.o
+obj-$(CONFIG_S5K3E2FX) += s5k3e2fx.o
+obj-$(CONFIG_ARCH_MSM) += msm_vfe7x.o msm_io7x.o
+obj-$(CONFIG_ARCH_QSD) += msm_vfe8x.o msm_vfe8x_proc.o msm_io8x.o
diff --git a/drivers/staging/dream/camera/msm_camera.c b/drivers/staging/dream/camera/msm_camera.c
new file mode 100644
index 0000000..8816599
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_camera.c
@@ -0,0 +1,2181 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+//FIXME: most allocations need not be GFP_ATOMIC
+/* FIXME: management of mutexes */
+/* FIXME: msm_pmem_region_lookup return values */
+/* FIXME: way too many copy to/from user */
+/* FIXME: does region->active mean free */
+/* FIXME: check limits on command lenghts passed from userspace */
+/* FIXME: __msm_release: which queues should we flush when opencnt != 0 */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <mach/board.h>
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/uaccess.h>
+#include <linux/android_pmem.h>
+#include <linux/poll.h>
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+
+#define MSM_MAX_CAMERA_SENSORS 5
+
+#define ERR_USER_COPY(to) pr_err("%s(%d): copy %s user\n", \
+				__func__, __LINE__, ((to) ? "to" : "from"))
+#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
+#define ERR_COPY_TO_USER() ERR_USER_COPY(1)
+
+static struct class *msm_class;
+static dev_t msm_devno;
+static LIST_HEAD(msm_sensors);
+
+#define __CONTAINS(r, v, l, field) ({				\
+	typeof(r) __r = r;					\
+	typeof(v) __v = v;					\
+	typeof(v) __e = __v + l;				\
+	int res = __v >= __r->field &&				\
+		__e <= __r->field + __r->len;			\
+	res;							\
+})
+
+#define CONTAINS(r1, r2, field) ({				\
+	typeof(r2) __r2 = r2;					\
+	__CONTAINS(r1, __r2->field, __r2->len, field);		\
+})
+
+#define IN_RANGE(r, v, field) ({				\
+	typeof(r) __r = r;					\
+	typeof(v) __vv = v;					\
+	int res = ((__vv >= __r->field) &&			\
+		(__vv < (__r->field + __r->len)));		\
+	res;							\
+})
+
+#define OVERLAPS(r1, r2, field) ({				\
+	typeof(r1) __r1 = r1;					\
+	typeof(r2) __r2 = r2;					\
+	typeof(__r2->field) __v = __r2->field;			\
+	typeof(__v) __e = __v + __r2->len - 1;			\
+	int res = (IN_RANGE(__r1, __v, field) ||		\
+		   IN_RANGE(__r1, __e, field));                 \
+	res;							\
+})
+
+#define MSM_DRAIN_QUEUE_NOSYNC(sync, name) do {			\
+	struct msm_queue_cmd *qcmd = NULL;			\
+	CDBG("%s: draining queue "#name"\n", __func__);		\
+	while (!list_empty(&(sync)->name)) {			\
+		qcmd = list_first_entry(&(sync)->name,		\
+			struct msm_queue_cmd, list);		\
+		list_del_init(&qcmd->list);			\
+		kfree(qcmd);					\
+	};							\
+} while(0)
+
+#define MSM_DRAIN_QUEUE(sync, name) do {			\
+	unsigned long flags;					\
+	spin_lock_irqsave(&(sync)->name##_lock, flags);		\
+	MSM_DRAIN_QUEUE_NOSYNC(sync, name);			\
+	spin_unlock_irqrestore(&(sync)->name##_lock, flags);	\
+} while(0)
+
+static int check_overlap(struct hlist_head *ptype,
+			unsigned long paddr,
+			unsigned long len)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region t = { .paddr = paddr, .len = len };
+	struct hlist_node *node;
+
+	hlist_for_each_entry(region, node, ptype, list) {
+		if (CONTAINS(region, &t, paddr) ||
+				CONTAINS(&t, region, paddr) ||
+				OVERLAPS(region, &t, paddr)) {
+			printk(KERN_ERR
+				" region (PHYS %p len %ld)"
+				" clashes with registered region"
+				" (paddr %p len %ld)\n",
+				(void *)t.paddr, t.len,
+				(void *)region->paddr, region->len);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int msm_pmem_table_add(struct hlist_head *ptype,
+	struct msm_pmem_info *info)
+{
+	struct file *file;
+	unsigned long paddr;
+	unsigned long vstart;
+	unsigned long len;
+	int rc;
+	struct msm_pmem_region *region;
+
+	rc = get_pmem_file(info->fd, &paddr, &vstart, &len, &file);
+	if (rc < 0) {
+		pr_err("msm_pmem_table_add: get_pmem_file fd %d error %d\n",
+			info->fd, rc);
+		return rc;
+	}
+
+	if (check_overlap(ptype, paddr, len) < 0)
+		return -EINVAL;
+
+	CDBG("%s: type = %d, paddr = 0x%lx, vaddr = 0x%lx\n",
+		__func__,
+		info->type, paddr, (unsigned long)info->vaddr);
+
+	region = kmalloc(sizeof(*region), GFP_KERNEL);
+	if (!region)
+		return -ENOMEM;
+
+	INIT_HLIST_NODE(&region->list);
+
+	region->type = info->type;
+	region->vaddr = info->vaddr;
+	region->paddr = paddr;
+	region->len = len;
+	region->file = file;
+	region->y_off = info->y_off;
+	region->cbcr_off = info->cbcr_off;
+	region->fd = info->fd;
+	region->active = info->active;
+
+	hlist_add_head(&(region->list), ptype);
+
+	return 0;
+}
+
+/* return of 0 means failure */
+static uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
+	int pmem_type, struct msm_pmem_region *reg, uint8_t maxcount)
+{
+	struct msm_pmem_region *region;
+	struct msm_pmem_region *regptr;
+	struct hlist_node *node, *n;
+
+	uint8_t rc = 0;
+
+	regptr = reg;
+
+	hlist_for_each_entry_safe(region, node, n, ptype, list) {
+		if (region->type == pmem_type && region->active) {
+			*regptr = *region;
+			rc += 1;
+			if (rc >= maxcount)
+				break;
+			regptr++;
+		}
+	}
+
+	return rc;
+}
+
+static unsigned long msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
+		unsigned long pyaddr,
+		unsigned long pcbcraddr,
+		uint32_t *yoff, uint32_t *cbcroff, int *fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	hlist_for_each_entry_safe(region, node, n, &sync->frame, list) {
+		if (pyaddr == (region->paddr + region->y_off) &&
+				pcbcraddr == (region->paddr +
+						region->cbcr_off) &&
+				region->active) {
+			/* offset since we could pass vaddr inside
+			 * a registerd pmem buffer
+			 */
+			*yoff = region->y_off;
+			*cbcroff = region->cbcr_off;
+			*fd = region->fd;
+			region->active = 0;
+			return (unsigned long)(region->vaddr);
+		}
+	}
+
+	return 0;
+}
+
+static unsigned long msm_pmem_stats_ptov_lookup(struct msm_sync *sync,
+		unsigned long addr, int *fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	hlist_for_each_entry_safe(region, node, n, &sync->stats, list) {
+		if (addr == region->paddr && region->active) {
+			/* offset since we could pass vaddr inside a
+			 * registered pmem buffer */
+			*fd = region->fd;
+			region->active = 0;
+			return (unsigned long)(region->vaddr);
+		}
+	}
+
+	return 0;
+}
+
+static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
+		unsigned long buffer,
+		uint32_t yoff, uint32_t cbcroff, int fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	hlist_for_each_entry_safe(region,
+		node, n, &sync->frame, list) {
+		if (((unsigned long)(region->vaddr) == buffer) &&
+				(region->y_off == yoff) &&
+				(region->cbcr_off == cbcroff) &&
+				(region->fd == fd) &&
+				(region->active == 0)) {
+
+			region->active = 1;
+			return region->paddr;
+		}
+	}
+
+	return 0;
+}
+
+static unsigned long msm_pmem_stats_vtop_lookup(
+		struct msm_sync *sync,
+		unsigned long buffer,
+		int fd)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	hlist_for_each_entry_safe(region, node, n, &sync->stats, list) {
+		if (((unsigned long)(region->vaddr) == buffer) &&
+				(region->fd == fd) && region->active == 0) {
+			region->active = 1;
+			return region->paddr;
+		}
+	}
+
+	return 0;
+}
+
+static int __msm_pmem_table_del(struct msm_sync *sync,
+		struct msm_pmem_info *pinfo)
+{
+	int rc = 0;
+	struct msm_pmem_region *region;
+	struct hlist_node *node, *n;
+
+	switch (pinfo->type) {
+	case MSM_PMEM_OUTPUT1:
+	case MSM_PMEM_OUTPUT2:
+	case MSM_PMEM_THUMBAIL:
+	case MSM_PMEM_MAINIMG:
+	case MSM_PMEM_RAW_MAINIMG:
+		hlist_for_each_entry_safe(region, node, n,
+			&sync->frame, list) {
+
+			if (pinfo->type == region->type &&
+					pinfo->vaddr == region->vaddr &&
+					pinfo->fd == region->fd) {
+				hlist_del(node);
+				put_pmem_file(region->file);
+				kfree(region);
+			}
+		}
+		break;
+
+	case MSM_PMEM_AEC_AWB:
+	case MSM_PMEM_AF:
+		hlist_for_each_entry_safe(region, node, n,
+			&sync->stats, list) {
+
+			if (pinfo->type == region->type &&
+					pinfo->vaddr == region->vaddr &&
+					pinfo->fd == region->fd) {
+				hlist_del(node);
+				put_pmem_file(region->file);
+				kfree(region);
+			}
+		}
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int msm_pmem_table_del(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_pmem_info info;
+
+	if (copy_from_user(&info, arg, sizeof(info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_pmem_table_del(sync, &info);
+}
+
+static int __msm_get_frame(struct msm_sync *sync,
+		struct msm_frame *frame)
+{
+	unsigned long flags;
+	int rc = 0;
+
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_vfe_phy_info *pphy;
+
+	spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
+	if (!list_empty(&sync->prev_frame_q)) {
+		qcmd = list_first_entry(&sync->prev_frame_q,
+			struct msm_queue_cmd, list);
+		list_del_init(&qcmd->list);
+	}
+	spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
+
+	if (!qcmd) {
+		pr_err("%s: no preview frame.\n", __func__);
+		return -EAGAIN;
+	}
+
+	pphy = (struct msm_vfe_phy_info *)(qcmd->command);
+
+	frame->buffer =
+		msm_pmem_frame_ptov_lookup(sync,
+			pphy->y_phy,
+			pphy->cbcr_phy, &(frame->y_off),
+			&(frame->cbcr_off), &(frame->fd));
+	if (!frame->buffer) {
+		pr_err("%s: cannot get frame, invalid lookup address "
+			"y=%x cbcr=%x offset=%d\n",
+			__FUNCTION__,
+			pphy->y_phy,
+			pphy->cbcr_phy,
+			frame->y_off);
+		rc = -EINVAL;
+	}
+
+	CDBG("__msm_get_frame: y=0x%x, cbcr=0x%x, qcmd=0x%x, virt_addr=0x%x\n",
+		pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
+
+	kfree(qcmd);
+	return rc;
+}
+
+static int msm_get_frame(struct msm_sync *sync, void __user *arg)
+{
+	int rc = 0;
+	struct msm_frame frame;
+
+	if (copy_from_user(&frame,
+				arg,
+				sizeof(struct msm_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	rc = __msm_get_frame(sync, &frame);
+	if (rc < 0)
+		return rc;
+
+	if (sync->croplen) {
+		if (frame.croplen > sync->croplen) {
+			pr_err("msm_get_frame: invalid frame croplen %d\n",
+				frame.croplen);
+			return -EINVAL;
+		}
+
+		if (copy_to_user((void *)frame.cropinfo,
+				sync->cropinfo,
+				sync->croplen)) {
+			ERR_COPY_TO_USER();
+			return -EFAULT;
+		}
+	}
+
+	if (copy_to_user((void *)arg,
+				&frame, sizeof(struct msm_frame))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+	}
+
+	CDBG("Got frame!!!\n");
+
+	return rc;
+}
+
+static int msm_enable_vfe(struct msm_sync *sync, void __user *arg)
+{
+	int rc = -EIO;
+	struct camera_enable_cmd cfg;
+
+	if (copy_from_user(&cfg,
+			arg,
+			sizeof(struct camera_enable_cmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	if (sync->vfefn.vfe_enable)
+		rc = sync->vfefn.vfe_enable(&cfg);
+
+	CDBG("msm_enable_vfe: returned rc = %d\n", rc);
+	return rc;
+}
+
+static int msm_disable_vfe(struct msm_sync *sync, void __user *arg)
+{
+	int rc = -EIO;
+	struct camera_enable_cmd cfg;
+
+	if (copy_from_user(&cfg,
+			arg,
+			sizeof(struct camera_enable_cmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	if (sync->vfefn.vfe_disable)
+		rc = sync->vfefn.vfe_disable(&cfg, NULL);
+
+	CDBG("msm_disable_vfe: returned rc = %d\n", rc);
+	return rc;
+}
+
+static struct msm_queue_cmd* __msm_control(struct msm_sync *sync,
+		struct msm_control_device_queue *queue,
+		struct msm_queue_cmd *qcmd,
+		int timeout)
+{
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&sync->msg_event_q_lock, flags);
+	list_add_tail(&qcmd->list, &sync->msg_event_q);
+	/* wake up config thread */
+	wake_up(&sync->msg_event_wait);
+	spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
+
+	if (!queue)
+		return NULL;
+
+	/* wait for config status */
+	rc = wait_event_interruptible_timeout(
+			queue->ctrl_status_wait,
+			!list_empty_careful(&queue->ctrl_status_q),
+			timeout);
+	if (list_empty_careful(&queue->ctrl_status_q)) {
+		if (!rc)
+			rc = -ETIMEDOUT;
+		if (rc < 0) {
+			pr_err("msm_control: wait_event error %d\n", rc);
+#if 0
+			/* This is a bit scary.  If we time out too early, we
+			 * will free qcmd at the end of this function, and the
+			 * dsp may do the same when it does respond, so we
+			 * remove the message from the source queue.
+			 */
+			pr_err("%s: error waiting for ctrl_status_q: %d\n",
+				__func__, rc);
+			spin_lock_irqsave(&sync->msg_event_q_lock, flags);
+			list_del_init(&qcmd->list);
+			spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
+#endif
+			return ERR_PTR(rc);
+		}
+	}
+
+	/* control command status is ready */
+	spin_lock_irqsave(&queue->ctrl_status_q_lock, flags);
+	BUG_ON(list_empty(&queue->ctrl_status_q));
+	qcmd = list_first_entry(&queue->ctrl_status_q,
+			struct msm_queue_cmd, list);
+	list_del_init(&qcmd->list);
+	spin_unlock_irqrestore(&queue->ctrl_status_q_lock, flags);
+
+	return qcmd;
+}
+
+static int msm_control(struct msm_control_device *ctrl_pmsm,
+			int block,
+			void __user *arg)
+{
+	int rc = 0;
+
+	struct msm_sync *sync = ctrl_pmsm->pmsm->sync;
+	struct msm_ctrl_cmd udata, *ctrlcmd;
+	struct msm_queue_cmd *qcmd = NULL, *qcmd_temp;
+
+	if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
+		ERR_COPY_FROM_USER();
+		rc = -EFAULT;
+		goto end;
+	}
+
+	qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
+				sizeof(struct msm_ctrl_cmd) + udata.length,
+				GFP_KERNEL);
+	if (!qcmd) {
+		pr_err("msm_control: cannot allocate buffer\n");
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	qcmd->type = MSM_CAM_Q_CTRL;
+	qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
+	*ctrlcmd = udata;
+	ctrlcmd->value = ctrlcmd + 1;
+
+	if (udata.length) {
+		if (copy_from_user(ctrlcmd->value,
+				udata.value, udata.length)) {
+			ERR_COPY_FROM_USER();
+			rc = -EFAULT;
+			goto end;
+		}
+	}
+
+	if (!block) {
+		/* qcmd will be set to NULL */
+		qcmd = __msm_control(sync, NULL, qcmd, 0);
+		goto end;
+	}
+
+	qcmd_temp = __msm_control(sync,
+				  &ctrl_pmsm->ctrl_q,
+				  qcmd, MAX_SCHEDULE_TIMEOUT);
+
+	if (IS_ERR(qcmd_temp)) {
+		rc = PTR_ERR(qcmd_temp);
+		goto end;
+	}
+	qcmd = qcmd_temp;
+
+	if (qcmd->command) {
+		void __user *to = udata.value;
+		udata = *(struct msm_ctrl_cmd *)qcmd->command;
+		if (udata.length > 0) {
+			if (copy_to_user(to,
+					 udata.value,
+					 udata.length)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto end;
+			}
+		}
+		udata.value = to;
+
+		if (copy_to_user((void *)arg, &udata,
+				sizeof(struct msm_ctrl_cmd))) {
+			ERR_COPY_TO_USER();
+			rc = -EFAULT;
+			goto end;
+		}
+	}
+
+end:
+	/* Note: if we get here as a result of an error, we will free the
+	 * qcmd that we kmalloc() in this function.  When we come here as
+	 * a result of a successful completion, we are freeing the qcmd that
+	 * we dequeued from queue->ctrl_status_q.
+	 */
+	if (qcmd)
+		kfree(qcmd);
+
+	CDBG("msm_control: end rc = %d\n", rc);
+	return rc;
+}
+
+static int msm_get_stats(struct msm_sync *sync, void __user *arg)
+{
+	unsigned long flags;
+	int timeout;
+	int rc = 0;
+
+	struct msm_stats_event_ctrl se;
+
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_ctrl_cmd  *ctrl = NULL;
+	struct msm_vfe_resp  *data = NULL;
+	struct msm_stats_buf stats;
+
+	if (copy_from_user(&se, arg,
+			sizeof(struct msm_stats_event_ctrl))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	timeout = (int)se.timeout_ms;
+
+	CDBG("msm_get_stats timeout %d\n", timeout);
+	rc = wait_event_interruptible_timeout(
+			sync->msg_event_wait,
+			!list_empty_careful(&sync->msg_event_q),
+			msecs_to_jiffies(timeout));
+	if (list_empty_careful(&sync->msg_event_q)) {
+		if (rc == 0)
+			rc = -ETIMEDOUT;
+		if (rc < 0) {
+			pr_err("msm_get_stats error %d\n", rc);
+			return rc;
+		}
+	}
+	CDBG("msm_get_stats returned from wait: %d\n", rc);
+
+	spin_lock_irqsave(&sync->msg_event_q_lock, flags);
+	BUG_ON(list_empty(&sync->msg_event_q));
+	qcmd = list_first_entry(&sync->msg_event_q,
+			struct msm_queue_cmd, list);
+	list_del_init(&qcmd->list);
+	spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
+
+	CDBG("=== received from DSP === %d\n", qcmd->type);
+
+	switch (qcmd->type) {
+	case MSM_CAM_Q_VFE_EVT:
+	case MSM_CAM_Q_VFE_MSG:
+		data = (struct msm_vfe_resp *)(qcmd->command);
+
+		/* adsp event and message */
+		se.resptype = MSM_CAM_RESP_STAT_EVT_MSG;
+
+		/* 0 - msg from aDSP, 1 - event from mARM */
+		se.stats_event.type   = data->evt_msg.type;
+		se.stats_event.msg_id = data->evt_msg.msg_id;
+		se.stats_event.len    = data->evt_msg.len;
+
+		CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
+		CDBG("length = %d\n", se.stats_event.len);
+		CDBG("msg_id = %d\n", se.stats_event.msg_id);
+
+		if ((data->type == VFE_MSG_STATS_AF) ||
+				(data->type == VFE_MSG_STATS_WE)) {
+
+			stats.buffer =
+			msm_pmem_stats_ptov_lookup(sync,
+					data->phy.sbuf_phy,
+					&(stats.fd));
+			if (!stats.buffer) {
+				pr_err("%s: msm_pmem_stats_ptov_lookup error\n",
+					__FUNCTION__);
+				rc = -EINVAL;
+				goto failure;
+			}
+
+			if (copy_to_user((void *)(se.stats_event.data),
+					&stats,
+					sizeof(struct msm_stats_buf))) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		} else if ((data->evt_msg.len > 0) &&
+				(data->type == VFE_MSG_GENERAL)) {
+			if (copy_to_user((void *)(se.stats_event.data),
+					data->evt_msg.data,
+					data->evt_msg.len)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+			}
+		} else if (data->type == VFE_MSG_OUTPUT1 ||
+			data->type == VFE_MSG_OUTPUT2) {
+			if (copy_to_user((void *)(se.stats_event.data),
+					data->extdata,
+					data->extlen)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+			}
+		} else if (data->type == VFE_MSG_SNAPSHOT && sync->pict_pp) {
+			struct msm_postproc buf;
+			struct msm_pmem_region region;
+			buf.fmnum = msm_pmem_region_lookup(&sync->frame,
+					MSM_PMEM_MAINIMG,
+					&region, 1);
+			if (buf.fmnum == 1) {
+				buf.fmain.buffer = (unsigned long)region.vaddr;
+				buf.fmain.y_off  = region.y_off;
+				buf.fmain.cbcr_off = region.cbcr_off;
+				buf.fmain.fd = region.fd;
+			} else {
+				buf.fmnum = msm_pmem_region_lookup(&sync->frame,
+						MSM_PMEM_RAW_MAINIMG,
+						&region, 1);
+				if (buf.fmnum == 1) {
+					buf.fmain.path = MSM_FRAME_PREV_2;
+					buf.fmain.buffer =
+						(unsigned long)region.vaddr;
+					buf.fmain.fd = region.fd;
+				}
+				else {
+					pr_err("%s: pmem lookup failed\n",
+						__func__);
+					rc = -EINVAL;
+				}
+			}
+
+			if (copy_to_user((void *)(se.stats_event.data), &buf,
+					sizeof(buf))) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+			CDBG("snapshot copy_to_user!\n");
+		}
+		break;
+
+	case MSM_CAM_Q_CTRL:
+		/* control command from control thread */
+		ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
+
+		CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
+		CDBG("length = %d\n", ctrl->length);
+
+		if (ctrl->length > 0) {
+			if (copy_to_user((void *)(se.ctrl_cmd.value),
+						ctrl->value,
+						ctrl->length)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		}
+
+		se.resptype = MSM_CAM_RESP_CTRL;
+
+		/* what to control */
+		se.ctrl_cmd.type = ctrl->type;
+		se.ctrl_cmd.length = ctrl->length;
+		se.ctrl_cmd.resp_fd = ctrl->resp_fd;
+		break;
+
+	case MSM_CAM_Q_V4L2_REQ:
+		/* control command from v4l2 client */
+		ctrl = (struct msm_ctrl_cmd *)(qcmd->command);
+
+		CDBG("msm_get_stats, qcmd->type = %d\n", qcmd->type);
+		CDBG("length = %d\n", ctrl->length);
+
+		if (ctrl->length > 0) {
+			if (copy_to_user((void *)(se.ctrl_cmd.value),
+					ctrl->value, ctrl->length)) {
+				ERR_COPY_TO_USER();
+				rc = -EFAULT;
+				goto failure;
+			}
+		}
+
+		/* 2 tells config thread this is v4l2 request */
+		se.resptype = MSM_CAM_RESP_V4L2;
+
+		/* what to control */
+		se.ctrl_cmd.type   = ctrl->type;
+		se.ctrl_cmd.length = ctrl->length;
+		break;
+
+	default:
+		rc = -EFAULT;
+		goto failure;
+	} /* switch qcmd->type */
+
+	if (copy_to_user((void *)arg, &se, sizeof(se))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+	}
+
+failure:
+	if (qcmd)
+		kfree(qcmd);
+
+	CDBG("msm_get_stats: %d\n", rc);
+	return rc;
+}
+
+static int msm_ctrl_cmd_done(struct msm_control_device *ctrl_pmsm,
+		void __user *arg)
+{
+	unsigned long flags;
+	int rc = 0;
+
+	struct msm_ctrl_cmd udata, *ctrlcmd;
+	struct msm_queue_cmd *qcmd = NULL;
+
+	if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
+		ERR_COPY_FROM_USER();
+		rc = -EFAULT;
+		goto end;
+	}
+
+	qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
+			sizeof(struct msm_ctrl_cmd) + udata.length,
+			GFP_KERNEL);
+	if (!qcmd) {
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
+	*ctrlcmd = udata;
+	if (udata.length > 0) {
+		ctrlcmd->value = ctrlcmd + 1;
+		if (copy_from_user(ctrlcmd->value,
+					(void *)udata.value,
+					udata.length)) {
+			ERR_COPY_FROM_USER();
+			rc = -EFAULT;
+			kfree(qcmd);
+			goto end;
+		}
+	}
+	else ctrlcmd->value = NULL;
+
+end:
+	CDBG("msm_ctrl_cmd_done: end rc = %d\n", rc);
+	if (rc == 0) {
+		/* wake up control thread */
+		spin_lock_irqsave(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags);
+		list_add_tail(&qcmd->list, &ctrl_pmsm->ctrl_q.ctrl_status_q);
+		wake_up(&ctrl_pmsm->ctrl_q.ctrl_status_wait);
+		spin_unlock_irqrestore(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock, flags);
+	}
+
+	return rc;
+}
+
+static int msm_config_vfe(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+	struct msm_pmem_region region[8];
+	struct axidata axi_data;
+	void *data = NULL;
+	int rc = -EIO;
+
+	memset(&axi_data, 0, sizeof(axi_data));
+
+	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	switch(cfgcmd.cmd_type) {
+	case CMD_STATS_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->stats,
+					MSM_PMEM_AEC_AWB, &region[0],
+					NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
+		if (!axi_data.bufnum1) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		data = &axi_data;
+		break;
+	case CMD_STATS_AF_ENABLE:
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->stats,
+					MSM_PMEM_AF, &region[0],
+					NUM_AF_STAT_OUTPUT_BUFFERS);
+		if (!axi_data.bufnum1) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+		data = &axi_data;
+		break;
+	case CMD_GENERAL:
+	case CMD_STATS_DISABLE:
+		break;
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__FUNCTION__, cfgcmd.cmd_type);
+		return -EINVAL;
+	}
+
+
+	if (sync->vfefn.vfe_config)
+		rc = sync->vfefn.vfe_config(&cfgcmd, data);
+
+	return rc;
+}
+
+static int msm_frame_axi_cfg(struct msm_sync *sync,
+		struct msm_vfe_cfg_cmd *cfgcmd)
+{
+	int rc = -EIO;
+	struct axidata axi_data;
+	void *data = &axi_data;
+	struct msm_pmem_region region[8];
+	int pmem_type;
+
+	memset(&axi_data, 0, sizeof(axi_data));
+
+	switch (cfgcmd->cmd_type) {
+	case CMD_AXI_CFG_OUT1:
+		pmem_type = MSM_PMEM_OUTPUT1;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->frame, pmem_type,
+				&region[0], 8);
+		if (!axi_data.bufnum1) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_AXI_CFG_OUT2:
+		pmem_type = MSM_PMEM_OUTPUT2;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->frame, pmem_type,
+				&region[0], 8);
+		if (!axi_data.bufnum2) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_AXI_CFG_SNAP_O1_AND_O2:
+		pmem_type = MSM_PMEM_THUMBAIL;
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->frame, pmem_type,
+				&region[0], 8);
+		if (!axi_data.bufnum1) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+
+		pmem_type = MSM_PMEM_MAINIMG;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->frame, pmem_type,
+				&region[axi_data.bufnum1], 8);
+		if (!axi_data.bufnum2) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_RAW_PICT_AXI_CFG:
+		pmem_type = MSM_PMEM_RAW_MAINIMG;
+		axi_data.bufnum2 =
+			msm_pmem_region_lookup(&sync->frame, pmem_type,
+				&region[0], 8);
+		if (!axi_data.bufnum2) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+		break;
+
+	case CMD_GENERAL:
+		data = NULL;
+		break;
+
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__FUNCTION__, cfgcmd->cmd_type);
+		return -EINVAL;
+	}
+
+	axi_data.region = &region[0];
+
+	/* send the AXI configuration command to driver */
+	if (sync->vfefn.vfe_config)
+		rc = sync->vfefn.vfe_config(cfgcmd, data);
+
+	return rc;
+}
+
+static int msm_get_sensor_info(struct msm_sync *sync, void __user *arg)
+{
+	int rc = 0;
+	struct msm_camsensor_info info;
+	struct msm_camera_sensor_info *sdata;
+
+	if (copy_from_user(&info,
+			arg,
+			sizeof(struct msm_camsensor_info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	sdata = sync->pdev->dev.platform_data;
+	CDBG("sensor_name %s\n", sdata->sensor_name);
+
+	memcpy(&info.name[0],
+		sdata->sensor_name,
+		MAX_SENSOR_NAME);
+	info.flash_enabled = sdata->flash_type != MSM_CAMERA_FLASH_NONE;
+
+	/* copy back to user space */
+	if (copy_to_user((void *)arg,
+			&info,
+			sizeof(struct msm_camsensor_info))) {
+		ERR_COPY_TO_USER();
+		rc = -EFAULT;
+	}
+
+	return rc;
+}
+
+static int __msm_put_frame_buf(struct msm_sync *sync,
+		struct msm_frame *pb)
+{
+	unsigned long pphy;
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	int rc = -EIO;
+
+	pphy = msm_pmem_frame_vtop_lookup(sync,
+		pb->buffer,
+		pb->y_off, pb->cbcr_off, pb->fd);
+
+	if (pphy != 0) {
+		CDBG("rel: vaddr = 0x%lx, paddr = 0x%lx\n",
+			pb->buffer, pphy);
+		cfgcmd.cmd_type = CMD_FRAME_BUF_RELEASE;
+		cfgcmd.value    = (void *)pb;
+		if (sync->vfefn.vfe_config)
+			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
+	} else {
+		pr_err("%s: msm_pmem_frame_vtop_lookup failed\n",
+			__FUNCTION__);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+static int msm_put_frame_buffer(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_frame buf_t;
+
+	if (copy_from_user(&buf_t,
+				arg,
+				sizeof(struct msm_frame))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_put_frame_buf(sync, &buf_t);
+}
+
+static int __msm_register_pmem(struct msm_sync *sync,
+		struct msm_pmem_info *pinfo)
+{
+	int rc = 0;
+
+	switch (pinfo->type) {
+	case MSM_PMEM_OUTPUT1:
+	case MSM_PMEM_OUTPUT2:
+	case MSM_PMEM_THUMBAIL:
+	case MSM_PMEM_MAINIMG:
+	case MSM_PMEM_RAW_MAINIMG:
+		rc = msm_pmem_table_add(&sync->frame, pinfo);
+		break;
+
+	case MSM_PMEM_AEC_AWB:
+	case MSM_PMEM_AF:
+		rc = msm_pmem_table_add(&sync->stats, pinfo);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int msm_register_pmem(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_pmem_info info;
+
+	if (copy_from_user(&info, arg, sizeof(info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	return __msm_register_pmem(sync, &info);
+}
+
+static int msm_stats_axi_cfg(struct msm_sync *sync,
+		struct msm_vfe_cfg_cmd *cfgcmd)
+{
+	int rc = -EIO;
+	struct axidata axi_data;
+	void *data = &axi_data;
+
+	struct msm_pmem_region region[3];
+	int pmem_type = MSM_PMEM_MAX;
+
+	memset(&axi_data, 0, sizeof(axi_data));
+
+	switch (cfgcmd->cmd_type) {
+	case CMD_STATS_AXI_CFG:
+		pmem_type = MSM_PMEM_AEC_AWB;
+		break;
+	case CMD_STATS_AF_AXI_CFG:
+		pmem_type = MSM_PMEM_AF;
+		break;
+	case CMD_GENERAL:
+		data = NULL;
+		break;
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__FUNCTION__, cfgcmd->cmd_type);
+		return -EINVAL;
+	}
+
+	if (cfgcmd->cmd_type != CMD_GENERAL) {
+		axi_data.bufnum1 =
+			msm_pmem_region_lookup(&sync->stats, pmem_type,
+				&region[0], NUM_WB_EXP_STAT_OUTPUT_BUFFERS);
+		if (!axi_data.bufnum1) {
+			pr_err("%s: pmem region lookup error\n", __FUNCTION__);
+			return -EINVAL;
+		}
+		axi_data.region = &region[0];
+	}
+
+	/* send the AEC/AWB STATS configuration command to driver */
+	if (sync->vfefn.vfe_config)
+		rc = sync->vfefn.vfe_config(cfgcmd, &axi_data);
+
+	return rc;
+}
+
+static int msm_put_stats_buffer(struct msm_sync *sync, void __user *arg)
+{
+	int rc = -EIO;
+
+	struct msm_stats_buf buf;
+	unsigned long pphy;
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	if (copy_from_user(&buf, arg,
+				sizeof(struct msm_stats_buf))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	CDBG("msm_put_stats_buffer\n");
+	pphy = msm_pmem_stats_vtop_lookup(sync, buf.buffer, buf.fd);
+
+	if (pphy != 0) {
+		if (buf.type == STAT_AEAW)
+			cfgcmd.cmd_type = CMD_STATS_BUF_RELEASE;
+		else if (buf.type == STAT_AF)
+			cfgcmd.cmd_type = CMD_STATS_AF_BUF_RELEASE;
+		else {
+			pr_err("%s: invalid buf type %d\n",
+				__FUNCTION__,
+				buf.type);
+			rc = -EINVAL;
+			goto put_done;
+		}
+
+		cfgcmd.value = (void *)&buf;
+
+		if (sync->vfefn.vfe_config) {
+			rc = sync->vfefn.vfe_config(&cfgcmd, &pphy);
+			if (rc < 0)
+				pr_err("msm_put_stats_buffer: "\
+					"vfe_config err %d\n", rc);
+		} else
+			pr_err("msm_put_stats_buffer: vfe_config is NULL\n");
+	} else {
+		pr_err("msm_put_stats_buffer: NULL physical address\n");
+		rc = -EINVAL;
+	}
+
+put_done:
+	return rc;
+}
+
+static int msm_axi_config(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_vfe_cfg_cmd cfgcmd;
+
+	if (copy_from_user(&cfgcmd, arg, sizeof(cfgcmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	switch (cfgcmd.cmd_type) {
+	case CMD_AXI_CFG_OUT1:
+	case CMD_AXI_CFG_OUT2:
+	case CMD_AXI_CFG_SNAP_O1_AND_O2:
+	case CMD_RAW_PICT_AXI_CFG:
+		return msm_frame_axi_cfg(sync, &cfgcmd);
+
+	case CMD_STATS_AXI_CFG:
+	case CMD_STATS_AF_AXI_CFG:
+		return msm_stats_axi_cfg(sync, &cfgcmd);
+
+	default:
+		pr_err("%s: unknown command type %d\n",
+			__FUNCTION__,
+			cfgcmd.cmd_type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int __msm_get_pic(struct msm_sync *sync, struct msm_ctrl_cmd *ctrl)
+{
+	unsigned long flags;
+	int rc = 0;
+	int tm;
+
+	struct msm_queue_cmd *qcmd = NULL;
+
+	tm = (int)ctrl->timeout_ms;
+
+	rc = wait_event_interruptible_timeout(
+			sync->pict_frame_wait,
+			!list_empty_careful(&sync->pict_frame_q),
+			msecs_to_jiffies(tm));
+	if (list_empty_careful(&sync->pict_frame_q)) {
+		if (rc == 0)
+			return -ETIMEDOUT;
+		if (rc < 0) {
+			pr_err("msm_camera_get_picture, rc = %d\n", rc);
+			return rc;
+		}
+	}
+
+	spin_lock_irqsave(&sync->pict_frame_q_lock, flags);
+	BUG_ON(list_empty(&sync->pict_frame_q));
+	qcmd = list_first_entry(&sync->pict_frame_q,
+			struct msm_queue_cmd, list);
+	list_del_init(&qcmd->list);
+	spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
+
+	if (qcmd->command != NULL) {
+		struct msm_ctrl_cmd *q =
+			(struct msm_ctrl_cmd *)qcmd->command;
+		ctrl->type = q->type;
+		ctrl->status = q->status;
+	} else {
+		ctrl->type = -1;
+		ctrl->status = -1;
+	}
+
+	kfree(qcmd);
+	return rc;
+}
+
+static int msm_get_pic(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_ctrl_cmd ctrlcmd_t;
+	int rc;
+
+	if (copy_from_user(&ctrlcmd_t,
+				arg,
+				sizeof(struct msm_ctrl_cmd))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	rc = __msm_get_pic(sync, &ctrlcmd_t);
+	if (rc < 0)
+		return rc;
+
+	if (sync->croplen) {
+		if (ctrlcmd_t.length < sync->croplen) {
+			pr_err("msm_get_pic: invalid len %d\n",
+				ctrlcmd_t.length);
+			return -EINVAL;
+		}
+		if (copy_to_user(ctrlcmd_t.value,
+				sync->cropinfo,
+				sync->croplen)) {
+			ERR_COPY_TO_USER();
+			return -EFAULT;
+		}
+	}
+
+	if (copy_to_user((void *)arg,
+		&ctrlcmd_t,
+		sizeof(struct msm_ctrl_cmd))) {
+		ERR_COPY_TO_USER();
+		return -EFAULT;
+	}
+	return 0;
+}
+
+static int msm_set_crop(struct msm_sync *sync, void __user *arg)
+{
+	struct crop_info crop;
+
+	if (copy_from_user(&crop,
+				arg,
+				sizeof(struct crop_info))) {
+		ERR_COPY_FROM_USER();
+		return -EFAULT;
+	}
+
+	if (!sync->croplen) {
+		sync->cropinfo = kmalloc(crop.len, GFP_KERNEL);
+		if (!sync->cropinfo)
+			return -ENOMEM;
+	} else if (sync->croplen < crop.len)
+		return -EINVAL;
+
+	if (copy_from_user(sync->cropinfo,
+				crop.info,
+				crop.len)) {
+		ERR_COPY_FROM_USER();
+		kfree(sync->cropinfo);
+		return -EFAULT;
+	}
+
+	sync->croplen = crop.len;
+
+	return 0;
+}
+
+static int msm_pict_pp_done(struct msm_sync *sync, void __user *arg)
+{
+	struct msm_ctrl_cmd udata;
+	struct msm_ctrl_cmd *ctrlcmd = NULL;
+	struct msm_queue_cmd *qcmd = NULL;
+	unsigned long flags;
+	int rc = 0;
+
+	if (!sync->pict_pp)
+		return -EINVAL;
+
+	if (copy_from_user(&udata, arg, sizeof(struct msm_ctrl_cmd))) {
+		ERR_COPY_FROM_USER();
+		rc = -EFAULT;
+		goto pp_fail;
+	}
+
+	qcmd = kmalloc(sizeof(struct msm_queue_cmd) +
+			sizeof(struct msm_ctrl_cmd),
+			GFP_KERNEL);
+	if (!qcmd) {
+		rc = -ENOMEM;
+		goto pp_fail;
+	}
+
+	qcmd->type = MSM_CAM_Q_VFE_MSG;
+	qcmd->command = ctrlcmd = (struct msm_ctrl_cmd *)(qcmd + 1);
+	memset(ctrlcmd, 0, sizeof(struct msm_ctrl_cmd));
+	ctrlcmd->type = udata.type;
+	ctrlcmd->status = udata.status;
+
+	spin_lock_irqsave(&sync->pict_frame_q_lock, flags);
+	list_add_tail(&qcmd->list, &sync->pict_frame_q);
+	spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
+	wake_up(&sync->pict_frame_wait);
+
+pp_fail:
+	return rc;
+}
+
+static long msm_ioctl_common(struct msm_device *pmsm,
+		unsigned int cmd,
+		void __user *argp)
+{
+	CDBG("msm_ioctl_common\n");
+	switch (cmd) {
+	case MSM_CAM_IOCTL_REGISTER_PMEM:
+		return msm_register_pmem(pmsm->sync, argp);
+	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
+		return msm_pmem_table_del(pmsm->sync, argp);
+	default:
+		return -EINVAL;
+	}
+}
+
+static long msm_ioctl_config(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct msm_device *pmsm = filep->private_data;
+
+	CDBG("msm_ioctl_config cmd = %d\n", _IOC_NR(cmd));
+
+	switch (cmd) {
+	case MSM_CAM_IOCTL_GET_SENSOR_INFO:
+		rc = msm_get_sensor_info(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_CONFIG_VFE:
+		/* Coming from config thread for update */
+		rc = msm_config_vfe(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_GET_STATS:
+		/* Coming from config thread wait
+		 * for vfe statistics and control requests */
+		rc = msm_get_stats(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_ENABLE_VFE:
+		/* This request comes from control thread:
+		 * enable either QCAMTASK or VFETASK */
+		rc = msm_enable_vfe(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_DISABLE_VFE:
+		/* This request comes from control thread:
+		 * disable either QCAMTASK or VFETASK */
+		rc = msm_disable_vfe(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_VFE_APPS_RESET:
+		msm_camio_vfe_blk_reset();
+		rc = 0;
+		break;
+
+	case MSM_CAM_IOCTL_RELEASE_STATS_BUFFER:
+		rc = msm_put_stats_buffer(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_AXI_CONFIG:
+		rc = msm_axi_config(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_SET_CROP:
+		rc = msm_set_crop(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_PICT_PP: {
+		uint8_t enable;
+		if (copy_from_user(&enable, argp, sizeof(enable))) {
+			ERR_COPY_FROM_USER();
+			rc = -EFAULT;
+		} else {
+			pmsm->sync->pict_pp = enable;
+			rc = 0;
+		}
+		break;
+	}
+
+	case MSM_CAM_IOCTL_PICT_PP_DONE:
+		rc = msm_pict_pp_done(pmsm->sync, argp);
+		break;
+
+	case MSM_CAM_IOCTL_SENSOR_IO_CFG:
+		rc = pmsm->sync->sctrl.s_config(argp);
+		break;
+
+	case MSM_CAM_IOCTL_FLASH_LED_CFG: {
+		uint32_t led_state;
+		if (copy_from_user(&led_state, argp, sizeof(led_state))) {
+			ERR_COPY_FROM_USER();
+			rc = -EFAULT;
+		} else
+			rc = msm_camera_flash_set_led_state(led_state);
+		break;
+	}
+
+	default:
+		rc = msm_ioctl_common(pmsm, cmd, argp);
+		break;
+	}
+
+	CDBG("msm_ioctl_config cmd = %d DONE\n", _IOC_NR(cmd));
+	return rc;
+}
+
+static int msm_unblock_poll_frame(struct msm_sync *);
+
+static long msm_ioctl_frame(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct msm_device *pmsm = filep->private_data;
+
+
+	switch (cmd) {
+	case MSM_CAM_IOCTL_GETFRAME:
+		/* Coming from frame thread to get frame
+		 * after SELECT is done */
+		rc = msm_get_frame(pmsm->sync, argp);
+		break;
+	case MSM_CAM_IOCTL_RELEASE_FRAME_BUFFER:
+		rc = msm_put_frame_buffer(pmsm->sync, argp);
+		break;
+	case MSM_CAM_IOCTL_UNBLOCK_POLL_FRAME:
+		rc = msm_unblock_poll_frame(pmsm->sync);
+		break;
+	default:
+		break;
+	}
+
+	return rc;
+}
+
+
+static long msm_ioctl_control(struct file *filep, unsigned int cmd,
+	unsigned long arg)
+{
+	int rc = -EINVAL;
+	void __user *argp = (void __user *)arg;
+	struct msm_control_device *ctrl_pmsm = filep->private_data;
+	struct msm_device *pmsm = ctrl_pmsm->pmsm;
+
+	switch (cmd) {
+	case MSM_CAM_IOCTL_CTRL_COMMAND:
+		/* Coming from control thread, may need to wait for
+		 * command status */
+		rc = msm_control(ctrl_pmsm, 1, argp);
+		break;
+	case MSM_CAM_IOCTL_CTRL_COMMAND_2:
+		/* Sends a message, returns immediately */
+		rc = msm_control(ctrl_pmsm, 0, argp);
+		break;
+	case MSM_CAM_IOCTL_CTRL_CMD_DONE:
+		/* Config thread calls the control thread to notify it
+		 * of the result of a MSM_CAM_IOCTL_CTRL_COMMAND.
+		 */
+		rc = msm_ctrl_cmd_done(ctrl_pmsm, argp);
+		break;
+	case MSM_CAM_IOCTL_GET_PICTURE:
+		rc = msm_get_pic(pmsm->sync, argp);
+		break;
+	default:
+		rc = msm_ioctl_common(pmsm, cmd, argp);
+		break;
+	}
+
+	return rc;
+}
+
+static int __msm_release(struct msm_sync *sync)
+{
+	struct msm_pmem_region *region;
+	struct hlist_node *hnode;
+	struct hlist_node *n;
+
+	mutex_lock(&sync->lock);
+	if (sync->opencnt)
+		sync->opencnt--;
+
+	if (!sync->opencnt) {
+		/* need to clean up system resource */
+		if (sync->vfefn.vfe_release)
+			sync->vfefn.vfe_release(sync->pdev);
+
+		if (sync->cropinfo) {
+			kfree(sync->cropinfo);
+			sync->cropinfo = NULL;
+			sync->croplen = 0;
+		}
+
+		hlist_for_each_entry_safe(region, hnode, n,
+				&sync->frame, list) {
+			hlist_del(hnode);
+			put_pmem_file(region->file);
+			kfree(region);
+		}
+
+		hlist_for_each_entry_safe(region, hnode, n,
+				&sync->stats, list) {
+			hlist_del(hnode);
+			put_pmem_file(region->file);
+			kfree(region);
+		}
+
+		MSM_DRAIN_QUEUE(sync, msg_event_q);
+		MSM_DRAIN_QUEUE(sync, prev_frame_q);
+		MSM_DRAIN_QUEUE(sync, pict_frame_q);
+
+		sync->sctrl.s_release();
+		wake_unlock(&sync->wake_lock);
+
+		sync->apps_id = NULL;
+		CDBG("msm_release completed!\n");
+	}
+	mutex_unlock(&sync->lock);
+
+	return 0;
+}
+
+static int msm_release_config(struct inode *node, struct file *filep)
+{
+	int rc;
+	struct msm_device *pmsm = filep->private_data;
+	printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
+	rc = __msm_release(pmsm->sync);
+	atomic_set(&pmsm->opened, 0);
+	return rc;
+}
+
+static int msm_release_control(struct inode *node, struct file *filep)
+{
+	int rc;
+	struct msm_control_device *ctrl_pmsm = filep->private_data;
+	struct msm_device *pmsm = ctrl_pmsm->pmsm;
+	printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
+	rc = __msm_release(pmsm->sync);
+	if (!rc) {
+		MSM_DRAIN_QUEUE(&ctrl_pmsm->ctrl_q, ctrl_status_q);
+		MSM_DRAIN_QUEUE(pmsm->sync, pict_frame_q);
+	}
+	kfree(ctrl_pmsm);
+	return rc;
+}
+
+static int msm_release_frame(struct inode *node, struct file *filep)
+{
+	int rc;
+	struct msm_device *pmsm = filep->private_data;
+	printk("msm_camera: RELEASE %s\n", filep->f_path.dentry->d_name.name);
+	rc = __msm_release(pmsm->sync);
+	if (!rc) {
+		MSM_DRAIN_QUEUE(pmsm->sync, prev_frame_q);
+		atomic_set(&pmsm->opened, 0);
+	}
+	return rc;
+}
+
+static int msm_unblock_poll_frame(struct msm_sync *sync)
+{
+	unsigned long flags;
+	CDBG("msm_unblock_poll_frame\n");
+	spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
+	sync->unblock_poll_frame = 1;
+	wake_up(&sync->prev_frame_wait);
+	spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
+	return 0;
+}
+
+static unsigned int __msm_poll_frame(struct msm_sync *sync,
+		struct file *filep,
+		struct poll_table_struct *pll_table)
+{
+	int rc = 0;
+	unsigned long flags;
+
+	poll_wait(filep, &sync->prev_frame_wait, pll_table);
+
+	spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
+	if (!list_empty_careful(&sync->prev_frame_q))
+		/* frame ready */
+		rc = POLLIN | POLLRDNORM;
+	if (sync->unblock_poll_frame) {
+		CDBG("%s: sync->unblock_poll_frame is true\n", __func__);
+		rc |= POLLPRI;
+		sync->unblock_poll_frame = 0;
+	}
+	spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
+
+	return rc;
+}
+
+static unsigned int msm_poll_frame(struct file *filep,
+	struct poll_table_struct *pll_table)
+{
+	struct msm_device *pmsm = filep->private_data;
+	return __msm_poll_frame(pmsm->sync, filep, pll_table);
+}
+
+/*
+ * This function executes in interrupt context.
+ */
+
+static void *msm_vfe_sync_alloc(int size,
+			void *syncdata __attribute__((unused)))
+{
+	struct msm_queue_cmd *qcmd =
+		kmalloc(sizeof(struct msm_queue_cmd) + size, GFP_ATOMIC);
+	return qcmd ? qcmd + 1 : NULL;
+}
+
+/*
+ * This function executes in interrupt context.
+ */
+
+static void msm_vfe_sync(struct msm_vfe_resp *vdata,
+		enum msm_queue qtype, void *syncdata)
+{
+	struct msm_queue_cmd *qcmd = NULL;
+	struct msm_queue_cmd *qcmd_frame = NULL;
+	struct msm_vfe_phy_info *fphy;
+
+	unsigned long flags;
+	struct msm_sync *sync = (struct msm_sync *)syncdata;
+	if (!sync) {
+		pr_err("msm_camera: no context in dsp callback.\n");
+		return;
+	}
+
+	qcmd = ((struct msm_queue_cmd *)vdata) - 1;
+	qcmd->type = qtype;
+
+	if (qtype == MSM_CAM_Q_VFE_MSG) {
+		switch(vdata->type) {
+		case VFE_MSG_OUTPUT1:
+		case VFE_MSG_OUTPUT2:
+			qcmd_frame =
+				kmalloc(sizeof(struct msm_queue_cmd) +
+					sizeof(struct msm_vfe_phy_info),
+					GFP_ATOMIC);
+			if (!qcmd_frame)
+				goto mem_fail;
+			fphy = (struct msm_vfe_phy_info *)(qcmd_frame + 1);
+			*fphy = vdata->phy;
+
+			qcmd_frame->type = MSM_CAM_Q_VFE_MSG;
+			qcmd_frame->command = fphy;
+
+			CDBG("qcmd_frame= 0x%x phy_y= 0x%x, phy_cbcr= 0x%x\n",
+				(int) qcmd_frame, fphy->y_phy, fphy->cbcr_phy);
+
+			spin_lock_irqsave(&sync->prev_frame_q_lock, flags);
+			list_add_tail(&qcmd_frame->list, &sync->prev_frame_q);
+			wake_up(&sync->prev_frame_wait);
+			spin_unlock_irqrestore(&sync->prev_frame_q_lock, flags);
+			CDBG("woke up frame thread\n");
+			break;
+		case VFE_MSG_SNAPSHOT:
+			if (sync->pict_pp)
+				break;
+
+			CDBG("snapshot pp = %d\n", sync->pict_pp);
+			qcmd_frame =
+				kmalloc(sizeof(struct msm_queue_cmd),
+					GFP_ATOMIC);
+			if (!qcmd_frame)
+				goto mem_fail;
+			qcmd_frame->type = MSM_CAM_Q_VFE_MSG;
+			qcmd_frame->command = NULL;
+				spin_lock_irqsave(&sync->pict_frame_q_lock,
+				flags);
+			list_add_tail(&qcmd_frame->list, &sync->pict_frame_q);
+			wake_up(&sync->pict_frame_wait);
+			spin_unlock_irqrestore(&sync->pict_frame_q_lock, flags);
+			CDBG("woke up picture thread\n");
+			break;
+		default:
+			CDBG("%s: qtype = %d not handled\n",
+				__func__, vdata->type);
+			break;
+		}
+	}
+
+	qcmd->command = (void *)vdata;
+	CDBG("vdata->type = %d\n", vdata->type);
+
+	spin_lock_irqsave(&sync->msg_event_q_lock, flags);
+	list_add_tail(&qcmd->list, &sync->msg_event_q);
+	wake_up(&sync->msg_event_wait);
+	spin_unlock_irqrestore(&sync->msg_event_q_lock, flags);
+	CDBG("woke up config thread\n");
+	return;
+
+mem_fail:
+	kfree(qcmd);
+}
+
+static struct msm_vfe_callback msm_vfe_s = {
+	.vfe_resp = msm_vfe_sync,
+	.vfe_alloc = msm_vfe_sync_alloc,
+};
+
+static int __msm_open(struct msm_sync *sync, const char *const apps_id)
+{
+	int rc = 0;
+
+	mutex_lock(&sync->lock);
+	if (sync->apps_id && strcmp(sync->apps_id, apps_id)) {
+		pr_err("msm_camera(%s): sensor %s is already opened for %s\n",
+			apps_id,
+			sync->sdata->sensor_name,
+			sync->apps_id);
+		rc = -EBUSY;
+		goto msm_open_done;
+	}
+
+	sync->apps_id = apps_id;
+
+	if (!sync->opencnt) {
+		wake_lock(&sync->wake_lock);
+
+		msm_camvfe_fn_init(&sync->vfefn, sync);
+		if (sync->vfefn.vfe_init) {
+			rc = sync->vfefn.vfe_init(&msm_vfe_s,
+				sync->pdev);
+			if (rc < 0) {
+				pr_err("vfe_init failed at %d\n", rc);
+				goto msm_open_done;
+			}
+			rc = sync->sctrl.s_init(sync->sdata);
+			if (rc < 0) {
+				pr_err("sensor init failed: %d\n", rc);
+				goto msm_open_done;
+			}
+		} else {
+			pr_err("no sensor init func\n");
+			rc = -ENODEV;
+			goto msm_open_done;
+		}
+
+		if (rc >= 0) {
+			INIT_HLIST_HEAD(&sync->frame);
+			INIT_HLIST_HEAD(&sync->stats);
+			sync->unblock_poll_frame = 0;
+		}
+	}
+	sync->opencnt++;
+
+msm_open_done:
+	mutex_unlock(&sync->lock);
+	return rc;
+}
+
+static int msm_open_common(struct inode *inode, struct file *filep,
+			   int once)
+{
+	int rc;
+	struct msm_device *pmsm =
+		container_of(inode->i_cdev, struct msm_device, cdev);
+
+	CDBG("msm_camera: open %s\n", filep->f_path.dentry->d_name.name);
+
+	if (atomic_cmpxchg(&pmsm->opened, 0, 1) && once) {
+		pr_err("msm_camera: %s is already opened.\n",
+			filep->f_path.dentry->d_name.name);
+		return -EBUSY;
+	}
+
+	rc = nonseekable_open(inode, filep);
+	if (rc < 0) {
+		pr_err("msm_open: nonseekable_open error %d\n", rc);
+		return rc;
+	}
+
+	rc = __msm_open(pmsm->sync, MSM_APPS_ID_PROP);
+	if (rc < 0)
+		return rc;
+
+	filep->private_data = pmsm;
+
+	CDBG("msm_open() open: rc = %d\n", rc);
+	return rc;
+}
+
+static int msm_open(struct inode *inode, struct file *filep)
+{
+	return msm_open_common(inode, filep, 1);
+}
+
+static int msm_open_control(struct inode *inode, struct file *filep)
+{
+	int rc;
+
+	struct msm_control_device *ctrl_pmsm =
+		kmalloc(sizeof(struct msm_control_device), GFP_KERNEL);
+	if (!ctrl_pmsm)
+		return -ENOMEM;
+
+	rc = msm_open_common(inode, filep, 0);
+	if (rc < 0)
+		return rc;
+
+	ctrl_pmsm->pmsm = filep->private_data;
+	filep->private_data = ctrl_pmsm;
+	spin_lock_init(&ctrl_pmsm->ctrl_q.ctrl_status_q_lock);
+	INIT_LIST_HEAD(&ctrl_pmsm->ctrl_q.ctrl_status_q);
+	init_waitqueue_head(&ctrl_pmsm->ctrl_q.ctrl_status_wait);
+
+	CDBG("msm_open() open: rc = %d\n", rc);
+	return rc;
+}
+
+static int __msm_v4l2_control(struct msm_sync *sync,
+		struct msm_ctrl_cmd *out)
+{
+	int rc = 0;
+
+	struct msm_queue_cmd *qcmd = NULL, *rcmd = NULL;
+	struct msm_ctrl_cmd *ctrl;
+	struct msm_control_device_queue FIXME;
+
+	/* wake up config thread, 4 is for V4L2 application */
+	qcmd = kmalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+	if (!qcmd) {
+		pr_err("msm_control: cannot allocate buffer\n");
+		rc = -ENOMEM;
+		goto end;
+	}
+	qcmd->type = MSM_CAM_Q_V4L2_REQ;
+	qcmd->command = out;
+
+	rcmd = __msm_control(sync, &FIXME, qcmd, out->timeout_ms);
+	if (IS_ERR(rcmd)) {
+		rc = PTR_ERR(rcmd);
+		goto end;
+	}
+
+	ctrl = (struct msm_ctrl_cmd *)(rcmd->command);
+	/* FIXME: we should just set out->length = ctrl->length; */
+	BUG_ON(out->length < ctrl->length);
+	memcpy(out->value, ctrl->value, ctrl->length);
+
+end:
+	if (rcmd) kfree(rcmd);
+	CDBG("__msm_v4l2_control: end rc = %d\n", rc);
+	return rc;
+}
+
+static const struct file_operations msm_fops_config = {
+	.owner = THIS_MODULE,
+	.open = msm_open,
+	.unlocked_ioctl = msm_ioctl_config,
+	.release = msm_release_config,
+};
+
+static const struct file_operations msm_fops_control = {
+	.owner = THIS_MODULE,
+	.open = msm_open_control,
+	.unlocked_ioctl = msm_ioctl_control,
+	.release = msm_release_control,
+};
+
+static const struct file_operations msm_fops_frame = {
+	.owner = THIS_MODULE,
+	.open = msm_open,
+	.unlocked_ioctl = msm_ioctl_frame,
+	.release = msm_release_frame,
+	.poll = msm_poll_frame,
+};
+
+static int msm_setup_cdev(struct msm_device *msm,
+			int node,
+			dev_t devno,
+			const char *suffix,
+			const struct file_operations *fops)
+{
+	int rc = -ENODEV;
+
+	struct device *device =
+		device_create(msm_class, NULL,
+			devno, NULL,
+			"%s%d", suffix, node);
+
+	if (IS_ERR(device)) {
+		rc = PTR_ERR(device);
+		pr_err("msm_camera: error creating device: %d\n", rc);
+		return rc;
+	}
+
+	cdev_init(&msm->cdev, fops);
+	msm->cdev.owner = THIS_MODULE;
+
+	rc = cdev_add(&msm->cdev, devno, 1);
+	if (rc < 0) {
+		pr_err("msm_camera: error adding cdev: %d\n", rc);
+		device_destroy(msm_class, devno);
+		return rc;
+	}
+
+	return rc;
+}
+
+static int msm_tear_down_cdev(struct msm_device *msm, dev_t devno)
+{
+	cdev_del(&msm->cdev);
+	device_destroy(msm_class, devno);
+	return 0;
+}
+
+int msm_v4l2_register(struct msm_v4l2_driver *drv)
+{
+	/* FIXME: support multiple sensors */
+	if (list_empty(&msm_sensors))
+		return -ENODEV;
+
+	drv->sync = list_first_entry(&msm_sensors, struct msm_sync, list);
+	drv->open      = __msm_open;
+	drv->release   = __msm_release;
+	drv->ctrl      = __msm_v4l2_control;
+	drv->reg_pmem  = __msm_register_pmem;
+	drv->get_frame = __msm_get_frame;
+	drv->put_frame = __msm_put_frame_buf;
+	drv->get_pict  = __msm_get_pic;
+	drv->drv_poll  = __msm_poll_frame;
+
+	return 0;
+}
+EXPORT_SYMBOL(msm_v4l2_register);
+
+int msm_v4l2_unregister(struct msm_v4l2_driver *drv)
+{
+	drv->sync = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(msm_v4l2_unregister);
+
+static int msm_sync_init(struct msm_sync *sync,
+		struct platform_device *pdev,
+		int (*sensor_probe)(const struct msm_camera_sensor_info *,
+				struct msm_sensor_ctrl *))
+{
+	int rc = 0;
+	struct msm_sensor_ctrl sctrl;
+	sync->sdata = pdev->dev.platform_data;
+
+	spin_lock_init(&sync->msg_event_q_lock);
+	INIT_LIST_HEAD(&sync->msg_event_q);
+	init_waitqueue_head(&sync->msg_event_wait);
+
+	spin_lock_init(&sync->prev_frame_q_lock);
+	INIT_LIST_HEAD(&sync->prev_frame_q);
+	init_waitqueue_head(&sync->prev_frame_wait);
+
+	spin_lock_init(&sync->pict_frame_q_lock);
+	INIT_LIST_HEAD(&sync->pict_frame_q);
+	init_waitqueue_head(&sync->pict_frame_wait);
+
+	wake_lock_init(&sync->wake_lock, WAKE_LOCK_IDLE, "msm_camera");
+
+	rc = msm_camio_probe_on(pdev);
+	if (rc < 0)
+		return rc;
+	rc = sensor_probe(sync->sdata, &sctrl);
+	if (rc >= 0) {
+		sync->pdev = pdev;
+		sync->sctrl = sctrl;
+	}
+	msm_camio_probe_off(pdev);
+	if (rc < 0) {
+		pr_err("msm_camera: failed to initialize %s\n",
+			sync->sdata->sensor_name);
+		wake_lock_destroy(&sync->wake_lock);
+		return rc;
+	}
+
+	sync->opencnt = 0;
+	mutex_init(&sync->lock);
+	CDBG("initialized %s\n", sync->sdata->sensor_name);
+	return rc;
+}
+
+static int msm_sync_destroy(struct msm_sync *sync)
+{
+	wake_lock_destroy(&sync->wake_lock);
+	return 0;
+}
+
+static int msm_device_init(struct msm_device *pmsm,
+		struct msm_sync *sync,
+		int node)
+{
+	int dev_num = 3 * node;
+	int rc = msm_setup_cdev(pmsm, node,
+		MKDEV(MAJOR(msm_devno), dev_num),
+		"control", &msm_fops_control);
+	if (rc < 0) {
+		pr_err("error creating control node: %d\n", rc);
+		return rc;
+	}
+
+	rc = msm_setup_cdev(pmsm + 1, node,
+		MKDEV(MAJOR(msm_devno), dev_num + 1),
+		"config", &msm_fops_config);
+	if (rc < 0) {
+		pr_err("error creating config node: %d\n", rc);
+		msm_tear_down_cdev(pmsm, MKDEV(MAJOR(msm_devno),
+				dev_num));
+		return rc;
+	}
+
+	rc = msm_setup_cdev(pmsm + 2, node,
+		MKDEV(MAJOR(msm_devno), dev_num + 2),
+		"frame", &msm_fops_frame);
+	if (rc < 0) {
+		pr_err("error creating frame node: %d\n", rc);
+		msm_tear_down_cdev(pmsm,
+			MKDEV(MAJOR(msm_devno), dev_num));
+		msm_tear_down_cdev(pmsm + 1,
+			MKDEV(MAJOR(msm_devno), dev_num + 1));
+		return rc;
+	}
+
+	atomic_set(&pmsm[0].opened, 0);
+	atomic_set(&pmsm[1].opened, 0);
+	atomic_set(&pmsm[2].opened, 0);
+
+	pmsm[0].sync = sync;
+	pmsm[1].sync = sync;
+	pmsm[2].sync = sync;
+
+	return rc;
+}
+
+int msm_camera_drv_start(struct platform_device *dev,
+		int (*sensor_probe)(const struct msm_camera_sensor_info *,
+			struct msm_sensor_ctrl *))
+{
+	struct msm_device *pmsm = NULL;
+	struct msm_sync *sync;
+	int rc = -ENODEV;
+	static int camera_node;
+
+	if (camera_node >= MSM_MAX_CAMERA_SENSORS) {
+		pr_err("msm_camera: too many camera sensors\n");
+		return rc;
+	}
+
+	if (!msm_class) {
+		/* There are three device nodes per sensor */
+		rc = alloc_chrdev_region(&msm_devno, 0,
+				3 * MSM_MAX_CAMERA_SENSORS,
+				"msm_camera");
+		if (rc < 0) {
+			pr_err("msm_camera: failed to allocate chrdev: %d\n",
+				rc);
+			return rc;
+		}
+
+		msm_class = class_create(THIS_MODULE, "msm_camera");
+		if (IS_ERR(msm_class)) {
+			rc = PTR_ERR(msm_class);
+			pr_err("msm_camera: create device class failed: %d\n",
+				rc);
+			return rc;
+		}
+	}
+
+	pmsm = kzalloc(sizeof(struct msm_device) * 3 +
+			sizeof(struct msm_sync), GFP_ATOMIC);
+	if (!pmsm)
+		return -ENOMEM;
+	sync = (struct msm_sync *)(pmsm + 3);
+
+	rc = msm_sync_init(sync, dev, sensor_probe);
+	if (rc < 0) {
+		kfree(pmsm);
+		return rc;
+	}
+
+	CDBG("setting camera node %d\n", camera_node);
+	rc = msm_device_init(pmsm, sync, camera_node);
+	if (rc < 0) {
+		msm_sync_destroy(sync);
+		kfree(pmsm);
+		return rc;
+	}
+
+	camera_node++;
+	list_add(&sync->list, &msm_sensors);
+	return rc;
+}
+EXPORT_SYMBOL(msm_camera_drv_start);
diff --git a/drivers/staging/dream/camera/msm_io7x.c b/drivers/staging/dream/camera/msm_io7x.c
new file mode 100644
index 0000000..55c020b
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_io7x.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2008-2009 QUALCOMM Incorporated
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+
+#define CAMIF_CFG_RMSK 0x1fffff
+#define CAM_SEL_BMSK 0x2
+#define CAM_PCLK_SRC_SEL_BMSK 0x60000
+#define CAM_PCLK_INVERT_BMSK 0x80000
+#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
+
+#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
+#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
+#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
+
+#define CAM_SEL_SHFT 0x1
+#define CAM_PCLK_SRC_SEL_SHFT 0x11
+#define CAM_PCLK_INVERT_SHFT 0x13
+#define CAM_PAD_REG_SW_RESET_SHFT 0x14
+
+#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
+#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
+#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
+#define APPS_RESET_OFFSET 0x00000210
+
+static struct clk *camio_vfe_mdc_clk;
+static struct clk *camio_mdc_clk;
+static struct clk *camio_vfe_clk;
+
+static struct msm_camera_io_ext camio_ext;
+static struct resource *appio, *mdcio;
+void __iomem *appbase, *mdcbase;
+
+static struct msm_camera_io_ext camio_ext;
+static struct resource *appio, *mdcio;
+void __iomem *appbase, *mdcbase;
+
+extern int clk_set_flags(struct clk *clk, unsigned long flags);
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = -1;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
+		break;
+
+	case CAMIO_MDC_CLK:
+		clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_enable(clk);
+		rc = 0;
+	}
+
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = -1;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		clk = camio_vfe_mdc_clk;
+		break;
+
+	case CAMIO_MDC_CLK:
+		clk = camio_mdc_clk;
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+		rc = 0;
+	}
+
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_vfe_clk;
+
+	if (clk != ERR_PTR(-ENOENT))
+		clk_set_rate(clk, rate);
+}
+
+int msm_camio_enable(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camio_ext = camdev->ioext;
+
+	appio = request_mem_region(camio_ext.appphy,
+		camio_ext.appsz, pdev->name);
+	if (!appio) {
+		rc = -EBUSY;
+		goto enable_fail;
+	}
+
+	appbase = ioremap(camio_ext.appphy,
+		camio_ext.appsz);
+	if (!appbase) {
+		rc = -ENOMEM;
+		goto apps_no_mem;
+	}
+
+	mdcio = request_mem_region(camio_ext.mdcphy,
+		camio_ext.mdcsz, pdev->name);
+	if (!mdcio) {
+		rc = -EBUSY;
+		goto mdc_busy;
+	}
+
+	mdcbase = ioremap(camio_ext.mdcphy,
+		camio_ext.mdcsz);
+	if (!mdcbase) {
+		rc = -ENOMEM;
+		goto mdc_no_mem;
+	}
+
+	camdev->camera_gpio_on();
+
+	msm_camio_clk_enable(CAMIO_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_MDC_CLK);
+	msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
+	return 0;
+
+mdc_no_mem:
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+mdc_busy:
+	iounmap(appbase);
+apps_no_mem:
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+enable_fail:
+	return rc;
+}
+
+void msm_camio_disable(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	iounmap(mdcbase);
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+	iounmap(appbase);
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+
+	camdev->camera_gpio_off();
+
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_MDC_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
+}
+
+void msm_camio_camif_pad_reg_reset(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	/* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+
+	mask = CAM_SEL_BMSK |
+		CAM_PCLK_SRC_SEL_BMSK |
+		CAM_PCLK_INVERT_BMSK;
+
+	value = 1 << CAM_SEL_SHFT |
+		3 << CAM_PCLK_SRC_SEL_SHFT |
+		0 << CAM_PCLK_INVERT_SHFT;
+
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
+	mdelay(10);
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	uint32_t val;
+
+	val = readl(appbase + 0x00000210);
+	val |= 0x1;
+	writel(val, appbase + 0x00000210);
+	mdelay(10);
+
+	val = readl(appbase + 0x00000210);
+	val &= ~0x1;
+	writel(val, appbase + 0x00000210);
+	mdelay(10);
+}
+
+void msm_camio_camif_pad_reg_reset_2(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+}
+
+void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
+{
+	struct clk *clk = NULL;
+
+	clk = camio_vfe_clk;
+
+	if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
+		switch (srctype) {
+		case MSM_CAMIO_CLK_SRC_INTERNAL:
+			clk_set_flags(clk, 0x00000100 << 1);
+			break;
+
+		case MSM_CAMIO_CLK_SRC_EXTERNAL:
+			clk_set_flags(clk, 0x00000100);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+int msm_camio_probe_on(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_on();
+	return msm_camio_clk_enable(CAMIO_VFE_CLK);
+}
+
+int msm_camio_probe_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_VFE_CLK);
+}
diff --git a/drivers/staging/dream/camera/msm_io8x.c b/drivers/staging/dream/camera/msm_io8x.c
new file mode 100644
index 0000000..895161a
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_io8x.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2008-2009 QUALCOMM Incorporated
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+
+#define CAMIF_CFG_RMSK 0x1fffff
+#define CAM_SEL_BMSK 0x2
+#define CAM_PCLK_SRC_SEL_BMSK 0x60000
+#define CAM_PCLK_INVERT_BMSK 0x80000
+#define CAM_PAD_REG_SW_RESET_BMSK 0x100000
+
+#define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
+#define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
+#define MDDI_CLK_CHICKEN_BIT_BMSK  0x80
+
+#define CAM_SEL_SHFT 0x1
+#define CAM_PCLK_SRC_SEL_SHFT 0x11
+#define CAM_PCLK_INVERT_SHFT 0x13
+#define CAM_PAD_REG_SW_RESET_SHFT 0x14
+
+#define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
+#define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
+#define MDDI_CLK_CHICKEN_BIT_SHFT  0x7
+#define APPS_RESET_OFFSET 0x00000210
+
+static struct clk *camio_vfe_mdc_clk;
+static struct clk *camio_mdc_clk;
+static struct clk *camio_vfe_clk;
+static struct clk *camio_vfe_axi_clk;
+static struct msm_camera_io_ext camio_ext;
+static struct resource *appio, *mdcio;
+void __iomem *appbase, *mdcbase;
+
+extern int clk_set_flags(struct clk *clk, unsigned long flags);
+
+int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		camio_vfe_mdc_clk =
+		clk = clk_get(NULL, "vfe_mdc_clk");
+		break;
+
+	case CAMIO_MDC_CLK:
+		camio_mdc_clk =
+		clk = clk_get(NULL, "mdc_clk");
+		break;
+
+	case CAMIO_VFE_CLK:
+		camio_vfe_clk =
+		clk = clk_get(NULL, "vfe_clk");
+		break;
+
+	case CAMIO_VFE_AXI_CLK:
+		camio_vfe_axi_clk =
+		clk = clk_get(NULL, "vfe_axi_clk");
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+	else
+		rc = -1;
+
+	return rc;
+}
+
+int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
+{
+	int rc = 0;
+	struct clk *clk = NULL;
+
+	switch (clktype) {
+	case CAMIO_VFE_MDC_CLK:
+		clk = camio_vfe_mdc_clk;
+		break;
+
+	case CAMIO_MDC_CLK:
+		clk = camio_mdc_clk;
+		break;
+
+	case CAMIO_VFE_CLK:
+		clk = camio_vfe_clk;
+		break;
+
+	case CAMIO_VFE_AXI_CLK:
+		clk = camio_vfe_axi_clk;
+		break;
+
+	default:
+		break;
+	}
+
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+	} else
+		rc = -1;
+
+	return rc;
+}
+
+void msm_camio_clk_rate_set(int rate)
+{
+	struct clk *clk = camio_vfe_mdc_clk;
+
+	/* TODO: check return */
+	clk_set_rate(clk, rate);
+}
+
+int msm_camio_enable(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camio_ext = camdev->ioext;
+
+	appio = request_mem_region(camio_ext.appphy,
+		camio_ext.appsz, pdev->name);
+	if (!appio) {
+		rc = -EBUSY;
+		goto enable_fail;
+	}
+
+	appbase = ioremap(camio_ext.appphy,
+		camio_ext.appsz);
+	if (!appbase) {
+		rc = -ENOMEM;
+		goto apps_no_mem;
+	}
+
+	mdcio = request_mem_region(camio_ext.mdcphy,
+		camio_ext.mdcsz, pdev->name);
+	if (!mdcio) {
+		rc = -EBUSY;
+		goto mdc_busy;
+	}
+
+	mdcbase = ioremap(camio_ext.mdcphy,
+		camio_ext.mdcsz);
+	if (!mdcbase) {
+		rc = -ENOMEM;
+		goto mdc_no_mem;
+	}
+
+	camdev->camera_gpio_on();
+
+	msm_camio_clk_enable(CAMIO_VFE_CLK);
+	msm_camio_clk_enable(CAMIO_MDC_CLK);
+	msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
+	msm_camio_clk_enable(CAMIO_VFE_AXI_CLK);
+	return 0;
+
+mdc_no_mem:
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+mdc_busy:
+	iounmap(appbase);
+apps_no_mem:
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+enable_fail:
+	return rc;
+}
+
+void msm_camio_disable(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	iounmap(mdcbase);
+	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
+	iounmap(appbase);
+	release_mem_region(camio_ext.appphy, camio_ext.appsz);
+
+	camdev->camera_gpio_off();
+
+	msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
+	msm_camio_clk_disable(CAMIO_MDC_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_CLK);
+	msm_camio_clk_disable(CAMIO_VFE_AXI_CLK);
+}
+
+void msm_camio_camif_pad_reg_reset(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	/* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+
+	mask = CAM_SEL_BMSK |
+		CAM_PCLK_SRC_SEL_BMSK |
+		CAM_PCLK_INVERT_BMSK |
+		EXT_CAM_HSYNC_POL_SEL_BMSK |
+		EXT_CAM_VSYNC_POL_SEL_BMSK |
+		MDDI_CLK_CHICKEN_BIT_BMSK;
+
+	value = 1 << CAM_SEL_SHFT |
+		3 << CAM_PCLK_SRC_SEL_SHFT |
+		0 << CAM_PCLK_INVERT_SHFT |
+		0 << EXT_CAM_HSYNC_POL_SEL_SHFT |
+		0 << EXT_CAM_VSYNC_POL_SEL_SHFT |
+		0 << MDDI_CLK_CHICKEN_BIT_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
+
+	mdelay(10);
+
+	/* todo: check return */
+	if (camio_vfe_clk)
+		clk_set_rate(camio_vfe_clk, 96000000);
+}
+
+void msm_camio_vfe_blk_reset(void)
+{
+	uint32_t val;
+
+	val = readl(appbase + 0x00000210);
+	val |= 0x1;
+	writel(val, appbase + 0x00000210);
+	mdelay(10);
+
+	val = readl(appbase + 0x00000210);
+	val &= ~0x1;
+	writel(val, appbase + 0x00000210);
+	mdelay(10);
+}
+
+void msm_camio_camif_pad_reg_reset_2(void)
+{
+	uint32_t reg;
+	uint32_t mask, value;
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+
+	reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
+	mask = CAM_PAD_REG_SW_RESET_BMSK;
+	value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
+	writel((reg & (~mask)) | (value & mask), mdcbase);
+	mdelay(10);
+}
+
+void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
+{
+	struct clk *clk = NULL;
+
+	clk = camio_vfe_clk;
+
+	if (clk != NULL) {
+		switch (srctype) {
+		case MSM_CAMIO_CLK_SRC_INTERNAL:
+			clk_set_flags(clk, 0x00000100 << 1);
+			break;
+
+		case MSM_CAMIO_CLK_SRC_EXTERNAL:
+			clk_set_flags(clk, 0x00000100);
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+void msm_camio_clk_axi_rate_set(int rate)
+{
+	struct clk *clk = camio_vfe_axi_clk;
+	/* todo: check return */
+	clk_set_rate(clk, rate);
+}
+
+int msm_camio_probe_on(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camdev->camera_gpio_on();
+	return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
+}
+
+int msm_camio_probe_off(struct platform_device *pdev)
+{
+	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
+
+	camdev->camera_gpio_off();
+	return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
+}
diff --git a/drivers/staging/dream/camera/msm_v4l2.c b/drivers/staging/dream/camera/msm_v4l2.c
new file mode 100644
index 0000000..6a7d46c
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_v4l2.c
@@ -0,0 +1,797 @@
+/*
+ *
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ *
+ */
+
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <linux/proc_fs.h>
+#include <media/v4l2-dev.h>
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+#include <media/v4l2-ioctl.h>
+/*#include <linux/platform_device.h>*/
+
+#define MSM_V4L2_START_SNAPSHOT _IOWR('V', BASE_VIDIOC_PRIVATE+1, \
+      struct v4l2_buffer)
+
+#define MSM_V4L2_GET_PICTURE    _IOWR('V', BASE_VIDIOC_PRIVATE+2, \
+      struct v4l2_buffer)
+
+#define MSM_V4L2_DEVICE_NAME       "msm_v4l2"
+
+#define MSM_V4L2_PROC_NAME         "msm_v4l2"
+
+#define MSM_V4L2_DEVNUM_MPEG2       0
+#define MSM_V4L2_DEVNUM_YUV         20
+
+/* HVGA-P (portrait) and HVGA-L (landscape) */
+#define MSM_V4L2_WIDTH              480
+#define MSM_V4L2_HEIGHT             320
+
+#if 1
+#define D(fmt, args...) printk(KERN_INFO "msm_v4l2: " fmt, ##args)
+#else
+#define D(fmt, args...) do {} while (0)
+#endif
+
+#define PREVIEW_FRAMES_NUM 4
+
+struct msm_v4l2_device {
+	struct list_head read_queue;
+	struct v4l2_format current_cap_format;
+	struct v4l2_format current_pix_format;
+	struct video_device *pvdev;
+	struct msm_v4l2_driver   *drv;
+	uint8_t opencnt;
+
+	spinlock_t read_queue_lock;
+};
+
+static struct msm_v4l2_device *g_pmsm_v4l2_dev;
+
+
+static DEFINE_MUTEX(msm_v4l2_opencnt_lock);
+
+static int msm_v4l2_open(struct file *f)
+{
+	int rc = 0;
+	D("%s\n", __func__);
+	mutex_lock(&msm_v4l2_opencnt_lock);
+	if (!g_pmsm_v4l2_dev->opencnt) {
+		rc = g_pmsm_v4l2_dev->drv->open(
+				g_pmsm_v4l2_dev->drv->sync,
+				MSM_APPS_ID_V4L2);
+	}
+	g_pmsm_v4l2_dev->opencnt++;
+	mutex_unlock(&msm_v4l2_opencnt_lock);
+	return rc;
+}
+
+static int msm_v4l2_release(struct file *f)
+{
+	int rc = 0;
+	D("%s\n", __func__);
+	mutex_lock(&msm_v4l2_opencnt_lock);
+	if (!g_pmsm_v4l2_dev->opencnt) {
+		g_pmsm_v4l2_dev->opencnt--;
+		if (!g_pmsm_v4l2_dev->opencnt) {
+			rc = g_pmsm_v4l2_dev->drv->release(
+					g_pmsm_v4l2_dev->drv->sync);
+		}
+	}
+	mutex_unlock(&msm_v4l2_opencnt_lock);
+	return rc;
+}
+
+static unsigned int msm_v4l2_poll(struct file *f, struct poll_table_struct *w)
+{
+	return g_pmsm_v4l2_dev->drv->drv_poll(g_pmsm_v4l2_dev->drv->sync, f, w);
+}
+
+static long msm_v4l2_ioctl(struct file *filep,
+			   unsigned int cmd, unsigned long arg)
+{
+	struct msm_ctrl_cmd *ctrlcmd;
+
+	D("msm_v4l2_ioctl, cmd = %d, %d\n", cmd, __LINE__);
+
+	switch (cmd) {
+	case MSM_V4L2_START_SNAPSHOT:
+
+		ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+		if (!ctrlcmd) {
+			CDBG("msm_v4l2_ioctl: cannot allocate buffer\n");
+			return -ENOMEM;
+		}
+
+		ctrlcmd->length     = 0;
+		ctrlcmd->value      = NULL;
+		ctrlcmd->timeout_ms = 10000;
+
+		D("msm_v4l2_ioctl,  MSM_V4L2_START_SNAPSHOT v4l2 ioctl %d\n",
+		cmd);
+		ctrlcmd->type = MSM_V4L2_SNAPSHOT;
+		return g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync,
+							ctrlcmd);
+
+	case MSM_V4L2_GET_PICTURE:
+		D("msm_v4l2_ioctl,  MSM_V4L2_GET_PICTURE v4l2 ioctl %d\n", cmd);
+		ctrlcmd = (struct msm_ctrl_cmd *)arg;
+		return g_pmsm_v4l2_dev->drv->get_pict(
+				g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
+
+	default:
+		D("msm_v4l2_ioctl, standard v4l2 ioctl %d\n", cmd);
+		return video_ioctl2(filep, cmd, arg);
+	}
+}
+
+static void msm_v4l2_release_dev(struct video_device *d)
+{
+	D("%s\n", __func__);
+}
+
+static int msm_v4l2_querycap(struct file *f,
+			     void *pctx, struct v4l2_capability *pcaps)
+{
+	D("%s\n", __func__);
+	strncpy(pcaps->driver, MSM_APPS_ID_V4L2, sizeof(pcaps->driver));
+	strncpy(pcaps->card,
+		MSM_V4L2_DEVICE_NAME, sizeof(pcaps->card));
+	pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	return 0;
+}
+
+static int msm_v4l2_s_std(struct file *f, void *pctx, v4l2_std_id *pnorm)
+{
+	D("%s\n", __func__);
+	return 0;
+}
+
+static int msm_v4l2_queryctrl(struct file *f,
+				void *pctx, struct v4l2_queryctrl *pqctrl)
+{
+  int rc = 0;
+  struct msm_ctrl_cmd *ctrlcmd;
+
+	D("%s\n", __func__);
+
+	ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+	if (!ctrlcmd) {
+		CDBG("msm_v4l2_queryctrl: cannot allocate buffer\n");
+		return -ENOMEM;
+	}
+
+	ctrlcmd->type       = MSM_V4L2_QUERY_CTRL;
+	ctrlcmd->length     = sizeof(struct v4l2_queryctrl);
+	ctrlcmd->value      = pqctrl;
+	ctrlcmd->timeout_ms = 10000;
+
+	rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
+	if (rc < 0)
+		return -1;
+
+	return ctrlcmd->status;
+}
+
+static int msm_v4l2_g_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd *ctrlcmd;
+
+	D("%s\n", __func__);
+
+	ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+	if (!ctrlcmd) {
+		CDBG("msm_v4l2_g_ctrl: cannot allocate buffer\n");
+		return -ENOMEM;
+	}
+
+	ctrlcmd->type       = MSM_V4L2_GET_CTRL;
+	ctrlcmd->length     = sizeof(struct v4l2_control);
+	ctrlcmd->value      = c;
+	ctrlcmd->timeout_ms = 10000;
+
+	rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
+	if (rc < 0)
+		return -1;
+
+	return ctrlcmd->status;
+}
+
+static int msm_v4l2_s_ctrl(struct file *f, void *pctx, struct v4l2_control *c)
+{
+	int rc = 0;
+	struct msm_ctrl_cmd *ctrlcmd;
+
+	ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+	if (!ctrlcmd) {
+		CDBG("msm_v4l2_s_ctrl: cannot allocate buffer\n");
+		return -ENOMEM;
+	}
+
+	ctrlcmd->type       = MSM_V4L2_SET_CTRL;
+	ctrlcmd->length     = sizeof(struct v4l2_control);
+	ctrlcmd->value      = c;
+	ctrlcmd->timeout_ms = 10000;
+
+	D("%s\n", __func__);
+
+	rc = g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
+	if (rc < 0)
+		return -1;
+
+	return ctrlcmd->status;
+}
+
+static int msm_v4l2_reqbufs(struct file *f,
+			    void *pctx, struct v4l2_requestbuffers *b)
+{
+	D("%s\n", __func__);
+	return 0;
+}
+
+static int msm_v4l2_querybuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
+{
+	struct msm_pmem_info pmem_buf;
+#if 0
+	__u32 width = 0;
+	__u32 height = 0;
+	__u32 y_size = 0;
+	__u32 y_pad = 0;
+
+	/* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.width; */
+	width = 640;
+	/* FIXME: g_pmsm_v4l2_dev->current_pix_format.fmt.pix.height; */
+	height = 480;
+
+	D("%s: width = %d, height = %d\n", __func__, width, height);
+
+	y_size = width * height;
+	y_pad = y_size % 4;
+#endif
+
+    __u32 y_pad = pb->bytesused % 4;
+
+	/* V4L2 videodev will do the copy_from_user. */
+
+	memset(&pmem_buf, 0, sizeof(struct msm_pmem_info));
+	pmem_buf.type = MSM_PMEM_OUTPUT2;
+	pmem_buf.vaddr = (void *)pb->m.userptr;
+	pmem_buf.y_off = 0;
+	pmem_buf.fd = (int)pb->reserved;
+	/* pmem_buf.cbcr_off = (y_size + y_pad); */
+    pmem_buf.cbcr_off = (pb->bytesused + y_pad);
+
+	g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync, &pmem_buf);
+
+	return 0;
+}
+
+static int msm_v4l2_qbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
+{
+    /*
+	__u32 y_size = 0;
+	__u32 y_pad = 0;
+	__u32 width = 0;
+	__u32 height = 0;
+    */
+
+	__u32 y_pad = 0;
+
+	struct msm_pmem_info meminfo;
+	struct msm_frame frame;
+	static int cnt;
+
+	if ((pb->flags >> 16) & 0x0001) {
+		/* this is for previwe */
+#if 0
+		width = 640;
+		height = 480;
+
+		/* V4L2 videodev will do the copy_from_user. */
+		D("%s: width = %d, height = %d\n", __func__, width, height);
+		y_size = width * height;
+		y_pad = y_size % 4;
+#endif
+
+		y_pad = pb->bytesused % 4;
+
+		if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
+			/* this qbuf is actually for releasing */
+
+			frame.buffer           = pb->m.userptr;
+			frame.y_off            = 0;
+			/* frame.cbcr_off = (y_size + y_pad); */
+			frame.cbcr_off         = (pb->bytesused + y_pad);
+			frame.fd               = pb->reserved;
+
+			D("V4L2_BUF_TYPE_PRIVATE: pb->bytesused = %d \n",
+			pb->bytesused);
+
+			g_pmsm_v4l2_dev->drv->put_frame(
+				g_pmsm_v4l2_dev->drv->sync,
+				&frame);
+
+			return 0;
+		}
+
+		D("V4L2_BUF_TYPE_VIDEO_CAPTURE: pb->bytesused = %d \n",
+		pb->bytesused);
+
+		meminfo.type             = MSM_PMEM_OUTPUT2;
+		meminfo.fd               = (int)pb->reserved;
+		meminfo.vaddr            = (void *)pb->m.userptr;
+		meminfo.y_off            = 0;
+		/* meminfo.cbcr_off = (y_size + y_pad); */
+		meminfo.cbcr_off         = (pb->bytesused + y_pad);
+		if (cnt == PREVIEW_FRAMES_NUM - 1)
+			meminfo.active = 0;
+		else
+			meminfo.active = 1;
+		cnt++;
+		g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
+				&meminfo);
+	} else if ((pb->flags) & 0x0001) {
+		/* this is for snapshot */
+
+	__u32 y_size = 0;
+
+	if ((pb->flags >> 8) & 0x01) {
+
+		y_size = pb->bytesused;
+
+		meminfo.type = MSM_PMEM_THUMBAIL;
+	} else if ((pb->flags >> 9) & 0x01) {
+
+		y_size = pb->bytesused;
+
+		meminfo.type = MSM_PMEM_MAINIMG;
+	}
+
+	y_pad = y_size % 4;
+
+	meminfo.fd         = (int)pb->reserved;
+	meminfo.vaddr      = (void *)pb->m.userptr;
+	meminfo.y_off      = 0;
+	/* meminfo.cbcr_off = (y_size + y_pad); */
+	meminfo.cbcr_off   = (y_size + y_pad);
+	meminfo.active 	   = 1;
+	g_pmsm_v4l2_dev->drv->reg_pmem(g_pmsm_v4l2_dev->drv->sync,
+					&meminfo);
+	}
+
+	return 0;
+}
+
+static int msm_v4l2_dqbuf(struct file *f, void *pctx, struct v4l2_buffer *pb)
+{
+	struct msm_frame frame;
+	D("%s\n", __func__);
+
+	/* V4L2 videodev will do the copy_to_user. */
+	if (pb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+
+		D("%s, %d\n", __func__, __LINE__);
+
+		g_pmsm_v4l2_dev->drv->get_frame(
+			g_pmsm_v4l2_dev->drv->sync,
+			&frame);
+
+		pb->type       = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		pb->m.userptr  = (unsigned long)frame.buffer;  /* FIXME */
+		pb->reserved   = (int)frame.fd;
+		/* pb->length     = (int)frame.cbcr_off; */
+
+		pb->bytesused  = frame.cbcr_off;
+
+	} else if (pb->type == V4L2_BUF_TYPE_PRIVATE) {
+		__u32 y_pad     = pb->bytesused % 4;
+
+		frame.buffer   = pb->m.userptr;
+		frame.y_off    = 0;
+		/* frame.cbcr_off = (y_size + y_pad); */
+		frame.cbcr_off = (pb->bytesused + y_pad);
+		frame.fd       = pb->reserved;
+
+		g_pmsm_v4l2_dev->drv->put_frame(
+			g_pmsm_v4l2_dev->drv->sync,
+			&frame);
+	}
+
+	return 0;
+}
+
+static int msm_v4l2_streamon(struct file *f, void *pctx, enum v4l2_buf_type i)
+{
+  struct msm_ctrl_cmd *ctrlcmd;
+
+	ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+	if (!ctrlcmd) {
+		CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
+		return -ENOMEM;
+	}
+
+	ctrlcmd->type       = MSM_V4L2_STREAM_ON;
+	ctrlcmd->timeout_ms = 10000;
+	ctrlcmd->length     = 0;
+	ctrlcmd->value      = NULL;
+
+	D("%s\n", __func__);
+
+	g_pmsm_v4l2_dev->drv->ctrl(
+		g_pmsm_v4l2_dev->drv->sync,
+		ctrlcmd);
+
+	D("%s after drv->ctrl \n", __func__);
+
+	return 0;
+}
+
+static int msm_v4l2_streamoff(struct file *f, void *pctx, enum v4l2_buf_type i)
+{
+  struct msm_ctrl_cmd *ctrlcmd;
+
+	ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+	if (!ctrlcmd) {
+		CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
+		return -ENOMEM;
+	}
+
+	ctrlcmd->type       = MSM_V4L2_STREAM_OFF;
+	ctrlcmd->timeout_ms = 10000;
+	ctrlcmd->length     = 0;
+	ctrlcmd->value      = NULL;
+
+
+	D("%s\n", __func__);
+
+	g_pmsm_v4l2_dev->drv->ctrl(
+		g_pmsm_v4l2_dev->drv->sync,
+		ctrlcmd);
+
+	return 0;
+}
+
+static int msm_v4l2_enum_fmt_overlay(struct file *f,
+				     void *pctx, struct v4l2_fmtdesc *pfmtdesc)
+{
+	D("%s\n", __func__);
+	return 0;
+}
+
+static int msm_v4l2_enum_fmt_cap(struct file *f,
+				 void *pctx, struct v4l2_fmtdesc *pfmtdesc)
+{
+	D("%s\n", __func__);
+
+	switch (pfmtdesc->index) {
+	case 0:
+		pfmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		pfmtdesc->flags = 0;
+		strncpy(pfmtdesc->description, "YUV 4:2:0",
+			sizeof(pfmtdesc->description));
+		pfmtdesc->pixelformat = V4L2_PIX_FMT_YVU420;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int msm_v4l2_g_fmt_cap(struct file *f,
+			      void *pctx, struct v4l2_format *pfmt)
+{
+	D("%s\n", __func__);
+	pfmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
+	pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
+	pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
+	pfmt->fmt.pix.field = V4L2_FIELD_ANY;
+	pfmt->fmt.pix.bytesperline = 0;
+	pfmt->fmt.pix.sizeimage = 0;
+	pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+	pfmt->fmt.pix.priv = 0;
+	return 0;
+}
+
+static int msm_v4l2_s_fmt_cap(struct file *f,
+			      void *pctx, struct v4l2_format *pfmt)
+{
+  struct msm_ctrl_cmd *ctrlcmd;
+
+	D("%s\n", __func__);
+
+	ctrlcmd = kmalloc(sizeof(struct msm_ctrl_cmd), GFP_ATOMIC);
+	if (!ctrlcmd) {
+		CDBG("msm_v4l2_s_fmt_cap: cannot allocate buffer\n");
+		return -ENOMEM;
+	}
+
+  ctrlcmd->type       = MSM_V4L2_VID_CAP_TYPE;
+  ctrlcmd->length     = sizeof(struct v4l2_format);
+  ctrlcmd->value      = pfmt;
+  ctrlcmd->timeout_ms = 10000;
+
+	if (pfmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		kfree(ctrlcmd);
+		return -1;
+	}
+
+#if 0
+	/* FIXEME */
+	if (pfmt->fmt.pix.pixelformat != V4L2_PIX_FMT_YVU420) {
+		kfree(ctrlcmd);
+		return -EINVAL;
+	}
+#endif
+
+	/* Ok, but check other params, too. */
+
+#if 0
+	memcpy(&g_pmsm_v4l2_dev->current_pix_format.fmt.pix, pfmt,
+	       sizeof(struct v4l2_format));
+#endif
+
+	g_pmsm_v4l2_dev->drv->ctrl(g_pmsm_v4l2_dev->drv->sync, ctrlcmd);
+
+	return 0;
+}
+
+static int msm_v4l2_g_fmt_overlay(struct file *f,
+				  void *pctx, struct v4l2_format *pfmt)
+{
+	D("%s\n", __func__);
+	pfmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
+	pfmt->fmt.pix.width = MSM_V4L2_WIDTH;
+	pfmt->fmt.pix.height = MSM_V4L2_HEIGHT;
+	pfmt->fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420;
+	pfmt->fmt.pix.field = V4L2_FIELD_ANY;
+	pfmt->fmt.pix.bytesperline = 0;
+	pfmt->fmt.pix.sizeimage = 0;
+	pfmt->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
+	pfmt->fmt.pix.priv = 0;
+	return 0;
+}
+
+static int msm_v4l2_s_fmt_overlay(struct file *f,
+				  void *pctx, struct v4l2_format *pfmt)
+{
+	D("%s\n", __func__);
+	return 0;
+}
+
+static int msm_v4l2_overlay(struct file *f, void *pctx, unsigned int i)
+{
+	D("%s\n", __func__);
+	return 0;
+}
+
+static int msm_v4l2_g_jpegcomp(struct file *f,
+			       void *pctx, struct v4l2_jpegcompression *pcomp)
+{
+	D("%s\n", __func__);
+	return 0;
+}
+
+static int msm_v4l2_s_jpegcomp(struct file *f,
+			       void *pctx, struct v4l2_jpegcompression *pcomp)
+{
+	D("%s\n", __func__);
+	return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+int msm_v4l2_read_proc(char *pbuf, char **start, off_t offset,
+		       int count, int *eof, void *data)
+{
+	int len = 0;
+	len += snprintf(pbuf, strlen("stats\n") + 1, "stats\n");
+
+	if (g_pmsm_v4l2_dev) {
+		len += snprintf(pbuf, strlen("mode: ") + 1, "mode: ");
+
+		if (g_pmsm_v4l2_dev->current_cap_format.type
+		    == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+			len += snprintf(pbuf, strlen("capture\n") + 1,
+					"capture\n");
+		else
+			len += snprintf(pbuf, strlen("unknown\n") + 1,
+					"unknown\n");
+
+		len += snprintf(pbuf, 21, "resolution: %dx%d\n",
+				g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
+				width,
+				g_pmsm_v4l2_dev->current_cap_format.fmt.pix.
+				height);
+
+		len += snprintf(pbuf,
+				strlen("pixel format: ") + 1, "pixel format: ");
+		if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.pixelformat
+		    == V4L2_PIX_FMT_YVU420)
+			len += snprintf(pbuf, strlen("yvu420\n") + 1,
+					"yvu420\n");
+		else
+			len += snprintf(pbuf, strlen("unknown\n") + 1,
+					"unknown\n");
+
+		len += snprintf(pbuf, strlen("colorspace: ") + 1,
+				"colorspace: ");
+		if (g_pmsm_v4l2_dev->current_cap_format.fmt.pix.colorspace
+		    == V4L2_COLORSPACE_JPEG)
+			len += snprintf(pbuf, strlen("jpeg\n") + 1, "jpeg\n");
+		else
+			len += snprintf(pbuf, strlen("unknown\n") + 1,
+					"unknown\n");
+	}
+
+	*eof = 1;
+	return len;
+}
+#endif
+
+static const struct v4l2_file_operations msm_v4l2_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_v4l2_open,
+	.poll = msm_v4l2_poll,
+	.release = msm_v4l2_release,
+	.ioctl = msm_v4l2_ioctl,
+};
+
+static void msm_v4l2_dev_init(struct msm_v4l2_device *pmsm_v4l2_dev)
+{
+	pmsm_v4l2_dev->read_queue_lock =
+	    __SPIN_LOCK_UNLOCKED(pmsm_v4l2_dev->read_queue_lock);
+	INIT_LIST_HEAD(&pmsm_v4l2_dev->read_queue);
+}
+
+static int msm_v4l2_try_fmt_cap(struct file *file,
+				 void *fh, struct v4l2_format *f)
+{
+	/* FIXME */
+	return 0;
+}
+
+static int mm_v4l2_try_fmt_type_private(struct file *file,
+					 void *fh, struct v4l2_format *f)
+{
+	/* FIXME */
+	return 0;
+}
+
+/*
+ * should the following structure be used instead of the code in the function?
+ * static const struct v4l2_ioctl_ops msm_v4l2_ioctl_ops = {
+ *     .vidioc_querycap = ....
+ * }
+ */
+static const struct v4l2_ioctl_ops msm_ioctl_ops = {
+	.vidioc_querycap = msm_v4l2_querycap,
+	.vidioc_s_std = msm_v4l2_s_std,
+
+	.vidioc_queryctrl = msm_v4l2_queryctrl,
+	.vidioc_g_ctrl = msm_v4l2_g_ctrl,
+	.vidioc_s_ctrl = msm_v4l2_s_ctrl,
+
+	.vidioc_reqbufs = msm_v4l2_reqbufs,
+	.vidioc_querybuf = msm_v4l2_querybuf,
+	.vidioc_qbuf = msm_v4l2_qbuf,
+	.vidioc_dqbuf = msm_v4l2_dqbuf,
+
+	.vidioc_streamon = msm_v4l2_streamon,
+	.vidioc_streamoff = msm_v4l2_streamoff,
+
+	.vidioc_enum_fmt_vid_overlay = msm_v4l2_enum_fmt_overlay,
+	.vidioc_enum_fmt_vid_cap = msm_v4l2_enum_fmt_cap,
+
+	.vidioc_try_fmt_vid_cap = msm_v4l2_try_fmt_cap,
+	.vidioc_try_fmt_type_private = mm_v4l2_try_fmt_type_private,
+
+	.vidioc_g_fmt_vid_cap = msm_v4l2_g_fmt_cap,
+	.vidioc_s_fmt_vid_cap = msm_v4l2_s_fmt_cap,
+	.vidioc_g_fmt_vid_overlay = msm_v4l2_g_fmt_overlay,
+	.vidioc_s_fmt_vid_overlay = msm_v4l2_s_fmt_overlay,
+	.vidioc_overlay = msm_v4l2_overlay,
+
+	.vidioc_g_jpegcomp = msm_v4l2_g_jpegcomp,
+	.vidioc_s_jpegcomp = msm_v4l2_s_jpegcomp,
+};
+
+static int msm_v4l2_video_dev_init(struct video_device *pvd)
+{
+	strncpy(pvd->name, MSM_APPS_ID_V4L2, sizeof(pvd->name));
+	pvd->vfl_type = 1;
+	pvd->fops = &msm_v4l2_fops;
+	pvd->release = msm_v4l2_release_dev;
+	pvd->minor = -1;
+	pvd->ioctl_ops = &msm_ioctl_ops;
+	return msm_v4l2_register(g_pmsm_v4l2_dev->drv);
+}
+
+static int __init msm_v4l2_init(void)
+{
+	int rc = -ENOMEM;
+	struct video_device *pvdev = NULL;
+	struct msm_v4l2_device *pmsm_v4l2_dev = NULL;
+	D("%s\n", __func__);
+
+	pvdev = video_device_alloc();
+	if (pvdev == NULL)
+		return rc;
+
+	pmsm_v4l2_dev =
+		kzalloc(sizeof(struct msm_v4l2_device), GFP_KERNEL);
+	if (pmsm_v4l2_dev == NULL) {
+		video_device_release(pvdev);
+		return rc;
+	}
+
+	msm_v4l2_dev_init(pmsm_v4l2_dev);
+
+	g_pmsm_v4l2_dev = pmsm_v4l2_dev;
+	g_pmsm_v4l2_dev->pvdev = pvdev;
+
+	g_pmsm_v4l2_dev->drv =
+		kzalloc(sizeof(struct msm_v4l2_driver), GFP_KERNEL);
+	if (!g_pmsm_v4l2_dev->drv) {
+		video_device_release(pvdev);
+		kfree(pmsm_v4l2_dev);
+		return rc;
+	}
+
+	rc = msm_v4l2_video_dev_init(pvdev);
+	if (rc < 0) {
+		video_device_release(pvdev);
+		kfree(g_pmsm_v4l2_dev->drv);
+		kfree(pmsm_v4l2_dev);
+		return rc;
+	}
+
+	if (video_register_device(pvdev, VFL_TYPE_GRABBER,
+	    MSM_V4L2_DEVNUM_YUV)) {
+		D("failed to register device\n");
+		video_device_release(pvdev);
+		kfree(g_pmsm_v4l2_dev);
+		g_pmsm_v4l2_dev = NULL;
+		return -ENOENT;
+	}
+#ifdef CONFIG_PROC_FS
+	create_proc_read_entry(MSM_V4L2_PROC_NAME,
+			       0, NULL, msm_v4l2_read_proc, NULL);
+#endif
+
+	return 0;
+}
+
+static void __exit msm_v4l2_exit(void)
+{
+	struct video_device *pvdev = g_pmsm_v4l2_dev->pvdev;
+	D("%s\n", __func__);
+#ifdef CONFIG_PROC_FS
+	remove_proc_entry(MSM_V4L2_PROC_NAME, NULL);
+#endif
+	video_unregister_device(pvdev);
+	video_device_release(pvdev);
+
+	msm_v4l2_unregister(g_pmsm_v4l2_dev->drv);
+
+	kfree(g_pmsm_v4l2_dev->drv);
+	g_pmsm_v4l2_dev->drv = NULL;
+
+	kfree(g_pmsm_v4l2_dev);
+	g_pmsm_v4l2_dev = NULL;
+}
+
+module_init(msm_v4l2_init);
+module_exit(msm_v4l2_exit);
+
+MODULE_DESCRIPTION("MSM V4L2 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/dream/camera/msm_vfe7x.c b/drivers/staging/dream/camera/msm_vfe7x.c
new file mode 100644
index 0000000..5de96c5
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_vfe7x.c
@@ -0,0 +1,701 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#include <linux/msm_adsp.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/android_pmem.h>
+#include <mach/msm_adsp.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include "msm_vfe7x.h"
+
+#define QDSP_CMDQUEUE QDSP_vfeCommandQueue
+
+#define VFE_RESET_CMD 0
+#define VFE_START_CMD 1
+#define VFE_STOP_CMD  2
+#define VFE_FRAME_ACK 20
+#define STATS_AF_ACK  21
+#define STATS_WE_ACK  22
+
+#define MSG_STOP_ACK  1
+#define MSG_SNAPSHOT  2
+#define MSG_OUTPUT1   6
+#define MSG_OUTPUT2   7
+#define MSG_STATS_AF  8
+#define MSG_STATS_WE  9
+
+static struct msm_adsp_module *qcam_mod;
+static struct msm_adsp_module *vfe_mod;
+static struct msm_vfe_callback *resp;
+static void *extdata;
+static uint32_t extlen;
+
+struct mutex vfe_lock;
+static void     *vfe_syncdata;
+static uint8_t vfestopped;
+
+static struct stop_event stopevent;
+
+static void vfe_7x_convert(struct msm_vfe_phy_info *pinfo,
+		enum vfe_resp_msg type,
+		void *data, void **ext, int32_t *elen)
+{
+	switch (type) {
+	case VFE_MSG_OUTPUT1:
+	case VFE_MSG_OUTPUT2: {
+		pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
+		pinfo->cbcr_phy =
+			((struct vfe_endframe *)data)->cbcr_address;
+
+		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
+				 pinfo->y_phy, pinfo->cbcr_phy);
+
+		((struct vfe_frame_extra *)extdata)->bl_evencol =
+		((struct vfe_endframe *)data)->blacklevelevencolumn;
+
+		((struct vfe_frame_extra *)extdata)->bl_oddcol =
+		((struct vfe_endframe *)data)->blackleveloddcolumn;
+
+		((struct vfe_frame_extra *)extdata)->g_def_p_cnt =
+		((struct vfe_endframe *)data)->greendefectpixelcount;
+
+		((struct vfe_frame_extra *)extdata)->r_b_def_p_cnt =
+		((struct vfe_endframe *)data)->redbluedefectpixelcount;
+
+		*ext  = extdata;
+		*elen = extlen;
+	}
+		break;
+
+	case VFE_MSG_STATS_AF:
+	case VFE_MSG_STATS_WE:
+		pinfo->sbuf_phy = *(uint32_t *)data;
+		break;
+
+	default:
+		break;
+	} /* switch */
+}
+
+static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
+		void (*getevent)(void *ptr, size_t len))
+{
+	uint32_t evt_buf[3];
+	struct msm_vfe_resp *rp;
+	void *data;
+
+	len = (id == (uint16_t)-1) ? 0 : len;
+	data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len, vfe_syncdata);
+
+	if (!data) {
+		pr_err("rp: cannot allocate buffer\n");
+		return;
+	}
+	rp = (struct msm_vfe_resp *)data;
+	rp->evt_msg.len = len;
+
+	if (id == ((uint16_t)-1)) {
+		/* event */
+		rp->type           = VFE_EVENT;
+		rp->evt_msg.type   = MSM_CAMERA_EVT;
+		getevent(evt_buf, sizeof(evt_buf));
+		rp->evt_msg.msg_id = evt_buf[0];
+		resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata);
+	} else {
+		/* messages */
+		rp->evt_msg.type   = MSM_CAMERA_MSG;
+		rp->evt_msg.msg_id = id;
+		rp->evt_msg.data = rp + 1;
+		getevent(rp->evt_msg.data, len);
+
+		switch (rp->evt_msg.msg_id) {
+		case MSG_SNAPSHOT:
+			rp->type = VFE_MSG_SNAPSHOT;
+			break;
+
+		case MSG_OUTPUT1:
+			rp->type = VFE_MSG_OUTPUT1;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT1,
+				rp->evt_msg.data, &(rp->extdata),
+				&(rp->extlen));
+			break;
+
+		case MSG_OUTPUT2:
+			rp->type = VFE_MSG_OUTPUT2;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT2,
+					rp->evt_msg.data, &(rp->extdata),
+					&(rp->extlen));
+			break;
+
+		case MSG_STATS_AF:
+			rp->type = VFE_MSG_STATS_AF;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
+					rp->evt_msg.data, NULL, NULL);
+			break;
+
+		case MSG_STATS_WE:
+			rp->type = VFE_MSG_STATS_WE;
+			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
+					rp->evt_msg.data, NULL, NULL);
+
+			CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
+			break;
+
+		case MSG_STOP_ACK:
+			rp->type = VFE_MSG_GENERAL;
+			stopevent.state = 1;
+			wake_up(&stopevent.wait);
+			break;
+
+
+		default:
+			rp->type = VFE_MSG_GENERAL;
+			break;
+		}
+		resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, vfe_syncdata);
+	}
+}
+
+static struct msm_adsp_ops vfe_7x_sync = {
+	.event = vfe_7x_ops,
+};
+
+static int vfe_7x_enable(struct camera_enable_cmd *enable)
+{
+	int rc = -EFAULT;
+
+	if (!strcmp(enable->name, "QCAMTASK"))
+		rc = msm_adsp_enable(qcam_mod);
+	else if (!strcmp(enable->name, "VFETASK"))
+		rc = msm_adsp_enable(vfe_mod);
+
+	return rc;
+}
+
+static int vfe_7x_disable(struct camera_enable_cmd *enable,
+		struct platform_device *dev __attribute__((unused)))
+{
+	int rc = -EFAULT;
+
+	if (!strcmp(enable->name, "QCAMTASK"))
+		rc = msm_adsp_disable(qcam_mod);
+	else if (!strcmp(enable->name, "VFETASK"))
+		rc = msm_adsp_disable(vfe_mod);
+
+	return rc;
+}
+
+static int vfe_7x_stop(void)
+{
+	int rc = 0;
+	uint32_t stopcmd = VFE_STOP_CMD;
+	rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+				&stopcmd, sizeof(uint32_t));
+	if (rc < 0) {
+		CDBG("%s:%d: failed rc = %d \n", __func__, __LINE__, rc);
+		return rc;
+	}
+
+	stopevent.state = 0;
+	rc = wait_event_timeout(stopevent.wait,
+		stopevent.state != 0,
+		msecs_to_jiffies(stopevent.timeout));
+
+	return rc;
+}
+
+static void vfe_7x_release(struct platform_device *pdev)
+{
+	mutex_lock(&vfe_lock);
+	vfe_syncdata = NULL;
+	mutex_unlock(&vfe_lock);
+
+	if (!vfestopped) {
+		CDBG("%s:%d:Calling vfe_7x_stop()\n", __func__, __LINE__);
+		vfe_7x_stop();
+	} else
+		vfestopped = 0;
+
+	msm_adsp_disable(qcam_mod);
+	msm_adsp_disable(vfe_mod);
+
+	msm_adsp_put(qcam_mod);
+	msm_adsp_put(vfe_mod);
+
+	msm_camio_disable(pdev);
+
+	kfree(extdata);
+	extlen = 0;
+}
+
+static int vfe_7x_init(struct msm_vfe_callback *presp,
+	struct platform_device *dev)
+{
+	int rc = 0;
+
+	init_waitqueue_head(&stopevent.wait);
+	stopevent.timeout = 200;
+	stopevent.state = 0;
+
+	if (presp && presp->vfe_resp)
+		resp = presp;
+	else
+		return -EFAULT;
+
+	/* Bring up all the required GPIOs and Clocks */
+	rc = msm_camio_enable(dev);
+	if (rc < 0)
+		return rc;
+
+	msm_camio_camif_pad_reg_reset();
+
+	extlen = sizeof(struct vfe_frame_extra);
+
+	extdata =
+		kmalloc(sizeof(extlen), GFP_ATOMIC);
+	if (!extdata) {
+		rc = -ENOMEM;
+		goto init_fail;
+	}
+
+	rc = msm_adsp_get("QCAMTASK", &qcam_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_qcam_fail;
+	}
+
+	rc = msm_adsp_get("VFETASK", &vfe_mod, &vfe_7x_sync, NULL);
+	if (rc) {
+		rc = -EBUSY;
+		goto get_vfe_fail;
+	}
+
+	return 0;
+
+get_vfe_fail:
+	msm_adsp_put(qcam_mod);
+get_qcam_fail:
+	kfree(extdata);
+init_fail:
+	extlen = 0;
+	return rc;
+}
+
+static int vfe_7x_config_axi(int mode,
+	struct axidata *ad, struct axiout *ao)
+{
+	struct msm_pmem_region *regptr;
+	unsigned long *bptr;
+	int    cnt;
+
+	int rc = 0;
+
+	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
+		regptr = ad->region;
+
+		CDBG("bufnum1 = %d\n", ad->bufnum1);
+		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
+			regptr->paddr, regptr->y_off, regptr->cbcr_off);
+
+		bptr = &ao->output1buffer1_y_phy;
+		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
+			*bptr = regptr->paddr + regptr->y_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->cbcr_off;
+
+			bptr++;
+			regptr++;
+		}
+
+		regptr--;
+		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
+			*bptr = regptr->paddr + regptr->y_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->cbcr_off;
+			bptr++;
+		}
+	} /* if OUTPUT1 or Both */
+
+	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
+		regptr = &(ad->region[ad->bufnum1]);
+
+		CDBG("bufnum2 = %d\n", ad->bufnum2);
+		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
+			regptr->paddr, regptr->y_off, regptr->cbcr_off);
+
+		bptr = &ao->output2buffer1_y_phy;
+		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
+			*bptr = regptr->paddr + regptr->y_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->cbcr_off;
+
+			bptr++;
+			regptr++;
+		}
+
+		regptr--;
+		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
+			*bptr = regptr->paddr + regptr->y_off;
+			bptr++;
+			*bptr = regptr->paddr + regptr->cbcr_off;
+			bptr++;
+		}
+	}
+
+	return rc;
+}
+
+static int vfe_7x_config(struct msm_vfe_cfg_cmd *cmd, void *data)
+{
+	struct msm_pmem_region *regptr;
+	unsigned char buf[256];
+
+	struct vfe_stats_ack sack;
+	struct axidata *axid;
+	uint32_t i;
+
+	struct vfe_stats_we_cfg *scfg = NULL;
+	struct vfe_stats_af_cfg *sfcfg = NULL;
+
+	struct axiout *axio = NULL;
+	void   *cmd_data = NULL;
+	void   *cmd_data_alloc = NULL;
+	long rc = 0;
+	struct msm_vfe_command_7k *vfecmd;
+
+	vfecmd =
+			kmalloc(sizeof(struct msm_vfe_command_7k),
+				GFP_ATOMIC);
+	if (!vfecmd) {
+		pr_err("vfecmd alloc failed!\n");
+		return -ENOMEM;
+	}
+
+	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+	    cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
+	    cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
+		if (copy_from_user(vfecmd,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_vfe_command_7k))) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+	}
+
+	switch (cmd->cmd_type) {
+	case CMD_STATS_ENABLE:
+	case CMD_STATS_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		scfg =
+			kmalloc(sizeof(struct vfe_stats_we_cfg),
+				GFP_ATOMIC);
+		if (!scfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(scfg,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
+			axid->bufnum1, scfg->wb_expstatsenable);
+
+		if (axid->bufnum1 > 0) {
+			regptr = axid->region;
+
+			for (i = 0; i < axid->bufnum1; i++) {
+
+				CDBG("STATS_ENABLE, phy = 0x%lx\n",
+					regptr->paddr);
+
+				scfg->wb_expstatoutputbuffer[i] =
+					(void *)regptr->paddr;
+				regptr++;
+			}
+
+			cmd_data = scfg;
+
+		} else {
+			rc = -EINVAL;
+			goto config_done;
+		}
+	}
+		break;
+
+	case CMD_STATS_AF_ENABLE:
+	case CMD_STATS_AF_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sfcfg =
+			kmalloc(sizeof(struct vfe_stats_af_cfg),
+				GFP_ATOMIC);
+
+		if (!sfcfg) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(sfcfg,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
+			axid->bufnum1, sfcfg->af_enable);
+
+		if (axid->bufnum1 > 0) {
+			regptr = axid->region;
+
+			for (i = 0; i < axid->bufnum1; i++) {
+
+				CDBG("STATS_ENABLE, phy = 0x%lx\n",
+					regptr->paddr);
+
+				sfcfg->af_outbuf[i] =
+					(void *)regptr->paddr;
+
+				regptr++;
+			}
+
+			cmd_data = sfcfg;
+
+		} else {
+			rc = -EINVAL;
+			goto config_done;
+		}
+	}
+		break;
+
+	case CMD_FRAME_BUF_RELEASE: {
+		struct msm_frame *b;
+		unsigned long p;
+		struct vfe_outputack fack;
+		if (!data)  {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		b = (struct msm_frame *)(cmd->value);
+		p = *(unsigned long *)data;
+
+		fack.header = VFE_FRAME_ACK;
+
+		fack.output2newybufferaddress =
+			(void *)(p + b->y_off);
+
+		fack.output2newcbcrbufferaddress =
+			(void *)(p + b->cbcr_off);
+
+		vfecmd->queue = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_outputack);
+		cmd_data = &fack;
+	}
+		break;
+
+	case CMD_SNAP_BUF_RELEASE:
+		break;
+
+	case CMD_STATS_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = STATS_WE_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		vfecmd->queue  = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_stats_ack);
+		cmd_data = &sack;
+	}
+		break;
+
+	case CMD_STATS_AF_BUF_RELEASE: {
+		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
+		if (!data) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		sack.header = STATS_AF_ACK;
+		sack.bufaddr = (void *)*(uint32_t *)data;
+
+		vfecmd->queue  = QDSP_CMDQUEUE;
+		vfecmd->length = sizeof(struct vfe_stats_ack);
+		cmd_data = &sack;
+	}
+		break;
+
+	case CMD_GENERAL:
+	case CMD_STATS_DISABLE: {
+		if (vfecmd->length > 256) {
+			cmd_data_alloc =
+			cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
+			if (!cmd_data) {
+				rc = -ENOMEM;
+				goto config_failure;
+			}
+		} else
+			cmd_data = buf;
+
+		if (copy_from_user(cmd_data,
+					(void __user *)(vfecmd->value),
+					vfecmd->length)) {
+
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		if (vfecmd->queue == QDSP_CMDQUEUE) {
+			switch (*(uint32_t *)cmd_data) {
+			case VFE_RESET_CMD:
+				msm_camio_vfe_blk_reset();
+				msm_camio_camif_pad_reg_reset_2();
+				vfestopped = 0;
+				break;
+
+			case VFE_START_CMD:
+				msm_camio_camif_pad_reg_reset_2();
+				vfestopped = 0;
+				break;
+
+			case VFE_STOP_CMD:
+				vfestopped = 1;
+				goto config_send;
+
+			default:
+				break;
+			}
+		} /* QDSP_CMDQUEUE */
+	}
+		break;
+
+	case CMD_AXI_CFG_OUT1: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(axio, (void *)(vfecmd->value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		vfe_7x_config_axi(OUTPUT_1, axid, axio);
+
+		cmd_data = axio;
+	}
+		break;
+
+	case CMD_AXI_CFG_OUT2:
+	case CMD_RAW_PICT_AXI_CFG: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd->value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		vfe_7x_config_axi(OUTPUT_2, axid, axio);
+		cmd_data = axio;
+	}
+		break;
+
+	case CMD_AXI_CFG_SNAP_O1_AND_O2: {
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			goto config_failure;
+		}
+
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd->value),
+					sizeof(struct axiout))) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+
+		vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
+
+		cmd_data = axio;
+	}
+		break;
+
+	default:
+		break;
+	} /* switch */
+
+	if (vfestopped)
+		goto config_done;
+
+config_send:
+	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
+	rc = msm_adsp_write(vfe_mod, vfecmd->queue,
+				cmd_data, vfecmd->length);
+
+config_done:
+	if (cmd_data_alloc != NULL)
+		kfree(cmd_data_alloc);
+
+config_failure:
+	kfree(scfg);
+	kfree(axio);
+	kfree(vfecmd);
+	return rc;
+}
+
+void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
+{
+	mutex_init(&vfe_lock);
+	fptr->vfe_init    = vfe_7x_init;
+	fptr->vfe_enable  = vfe_7x_enable;
+	fptr->vfe_config  = vfe_7x_config;
+	fptr->vfe_disable = vfe_7x_disable;
+	fptr->vfe_release = vfe_7x_release;
+	vfe_syncdata = data;
+}
diff --git a/drivers/staging/dream/camera/msm_vfe7x.h b/drivers/staging/dream/camera/msm_vfe7x.h
new file mode 100644
index 0000000..be3e9ad
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_vfe7x.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+#ifndef __MSM_VFE7X_H__
+#define __MSM_VFE7X_H__
+#include <media/msm_camera.h>
+#include <mach/camera.h>
+
+struct vfe_frame_extra {
+	uint32_t  bl_evencol;
+	uint32_t  bl_oddcol;
+	uint16_t  g_def_p_cnt;
+	uint16_t  r_b_def_p_cnt;
+};
+
+struct vfe_endframe {
+	uint32_t      y_address;
+	uint32_t      cbcr_address;
+
+	unsigned int  blacklevelevencolumn:23;
+	uint16_t      reserved1:9;
+	unsigned int  blackleveloddcolumn:23;
+	uint16_t      reserved2:9;
+
+	uint16_t      greendefectpixelcount:8;
+	uint16_t      reserved3:8;
+	uint16_t      redbluedefectpixelcount:8;
+	uint16_t      reserved4:8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_outputack {
+	uint32_t  header;
+	void      *output2newybufferaddress;
+	void      *output2newcbcrbufferaddress;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_stats_ack {
+	uint32_t header;
+	/* MUST BE 64 bit ALIGNED */
+	void     *bufaddr;
+} __attribute__((packed, aligned(4)));
+
+/* AXI Output Config Command sent to DSP */
+struct axiout {
+	uint32_t            cmdheader:32;
+	int 		    outputmode:3;
+	uint8_t             format:2;
+	uint32_t            /* reserved */ : 27;
+
+	/* AXI Output 1 Y Configuration, Part 1 */
+	uint32_t            out1yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 Y Configuration, Part 2 */
+	uint8_t             out1yburstlen:2;
+	uint32_t            out1ynumrows:12;
+	uint32_t            out1yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 1 */
+	uint32_t            out1cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out1cbcrimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 1 CbCr Configuration, Part 2 */
+	uint8_t             out1cbcrburstlen:2;
+	uint32_t            out1cbcrnumrows:12;
+	uint32_t            out1cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 1 */
+	uint32_t            out2yimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2yimagewidthin64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 Y Configuration, Part 2 */
+	uint8_t             out2yburstlen:2;
+	uint32_t            out2ynumrows:12;
+	uint32_t            out2yrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 1 */
+	uint32_t            out2cbcrimageheight:12;
+	uint32_t            /* reserved */ : 4;
+	uint32_t            out2cbcrimagewidtein64bitwords:10;
+	uint32_t            /* reserved */ : 6;
+
+	/* AXI Output 2 CbCr Configuration, Part 2 */
+	uint8_t             out2cbcrburstlen:2;
+	uint32_t            out2cbcrnumrows:12;
+	uint32_t            out2cbcrrowincin64bitincs:12;
+	uint32_t            /* reserved */ : 6;
+
+	/* Address configuration:
+	 * output1 phisycal address */
+	unsigned long   output1buffer1_y_phy;
+	unsigned long   output1buffer1_cbcr_phy;
+	unsigned long   output1buffer2_y_phy;
+	unsigned long   output1buffer2_cbcr_phy;
+	unsigned long   output1buffer3_y_phy;
+	unsigned long   output1buffer3_cbcr_phy;
+	unsigned long   output1buffer4_y_phy;
+	unsigned long   output1buffer4_cbcr_phy;
+	unsigned long   output1buffer5_y_phy;
+	unsigned long   output1buffer5_cbcr_phy;
+	unsigned long   output1buffer6_y_phy;
+	unsigned long   output1buffer6_cbcr_phy;
+	unsigned long   output1buffer7_y_phy;
+	unsigned long   output1buffer7_cbcr_phy;
+	unsigned long   output1buffer8_y_phy;
+	unsigned long   output1buffer8_cbcr_phy;
+
+	/* output2 phisycal address */
+	unsigned long   output2buffer1_y_phy;
+	unsigned long   output2buffer1_cbcr_phy;
+	unsigned long   output2buffer2_y_phy;
+	unsigned long   output2buffer2_cbcr_phy;
+	unsigned long   output2buffer3_y_phy;
+	unsigned long   output2buffer3_cbcr_phy;
+	unsigned long   output2buffer4_y_phy;
+	unsigned long   output2buffer4_cbcr_phy;
+	unsigned long   output2buffer5_y_phy;
+	unsigned long   output2buffer5_cbcr_phy;
+	unsigned long   output2buffer6_y_phy;
+	unsigned long   output2buffer6_cbcr_phy;
+	unsigned long   output2buffer7_y_phy;
+	unsigned long   output2buffer7_cbcr_phy;
+	unsigned long   output2buffer8_y_phy;
+	unsigned long   output2buffer8_cbcr_phy;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_stats_we_cfg {
+	uint32_t       header;
+
+	/* White Balance/Exposure Statistic Selection */
+	uint8_t        wb_expstatsenable:1;
+	uint8_t        wb_expstatbuspriorityselection:1;
+	unsigned int   wb_expstatbuspriorityvalue:4;
+	unsigned int   /* reserved */ : 26;
+
+	/* White Balance/Exposure Statistic Configuration, Part 1 */
+	uint8_t        exposurestatregions:1;
+	uint8_t        exposurestatsubregions:1;
+	unsigned int   /* reserved */ : 14;
+
+	unsigned int   whitebalanceminimumy:8;
+	unsigned int   whitebalancemaximumy:8;
+
+	/* White Balance/Exposure Statistic Configuration, Part 2 */
+	uint8_t wb_expstatslopeofneutralregionline[
+		NUM_WB_EXP_NEUTRAL_REGION_LINES];
+
+	/* White Balance/Exposure Statistic Configuration, Part 3 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline2:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralreginnline1:12;
+	unsigned int    /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Configuration, Part 4 */
+	unsigned int   wb_expstatcrinterceptofneutralregionline4:12;
+	unsigned int   /* reserved */ : 4;
+	unsigned int   wb_expstatcbinterceptofneutralregionline3:12;
+	unsigned int   /* reserved */ : 4;
+
+	/* White Balance/Exposure Statistic Output Buffer Header */
+	unsigned int   wb_expmetricheaderpattern:8;
+	unsigned int   /* reserved */ : 24;
+
+	/* White Balance/Exposure Statistic Output Buffers-MUST
+	* BE 64 bit ALIGNED */
+	void  *wb_expstatoutputbuffer[NUM_WB_EXP_STAT_OUTPUT_BUFFERS];
+} __attribute__((packed, aligned(4)));
+
+struct vfe_stats_af_cfg {
+	uint32_t header;
+
+	/* Autofocus Statistic Selection */
+	uint8_t       af_enable:1;
+	uint8_t       af_busprioritysel:1;
+	unsigned int  af_buspriorityval:4;
+	unsigned int  /* reserved */ : 26;
+
+	/* Autofocus Statistic Configuration, Part 1 */
+	unsigned int  af_singlewinvoffset:12;
+	unsigned int  /* reserved */ : 4;
+	unsigned int  af_singlewinhoffset:12;
+	unsigned int  /* reserved */ : 3;
+	uint8_t       af_winmode:1;
+
+	/* Autofocus Statistic Configuration, Part 2 */
+	unsigned int  af_singglewinvh:11;
+	unsigned int  /* reserved */ : 5;
+	unsigned int  af_singlewinhw:11;
+	unsigned int  /* reserved */ : 5;
+
+	/* Autofocus Statistic Configuration, Parts 3-6 */
+	uint8_t       af_multiwingrid[NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS];
+
+	/* Autofocus Statistic Configuration, Part 7 */
+	signed int    af_metrichpfcoefa00:5;
+	signed int    af_metrichpfcoefa04:5;
+	unsigned int  af_metricmaxval:11;
+	uint8_t       af_metricsel:1;
+	unsigned int  /* reserved */ : 10;
+
+	/* Autofocus Statistic Configuration, Part 8 */
+	signed int    af_metrichpfcoefa20:5;
+	signed int    af_metrichpfcoefa21:5;
+	signed int    af_metrichpfcoefa22:5;
+	signed int    af_metrichpfcoefa23:5;
+	signed int    af_metrichpfcoefa24:5;
+	unsigned int  /* reserved */ : 7;
+
+	/* Autofocus Statistic Output Buffer Header */
+	unsigned int  af_metrichp:8;
+	unsigned int  /* reserved */ : 24;
+
+	/* Autofocus Statistic Output Buffers - MUST BE 64 bit ALIGNED!!! */
+	void *af_outbuf[NUM_AF_STAT_OUTPUT_BUFFERS];
+} __attribute__((packed, aligned(4))); /* VFE_StatsAutofocusConfigCmdType */
+
+struct msm_camera_frame_msg {
+	unsigned long   output_y_address;
+	unsigned long   output_cbcr_address;
+
+	unsigned int    blacklevelevenColumn:23;
+	uint16_t        reserved1:9;
+	unsigned int    blackleveloddColumn:23;
+	uint16_t        reserved2:9;
+
+	uint16_t        greendefectpixelcount:8;
+	uint16_t        reserved3:8;
+	uint16_t        redbluedefectpixelcount:8;
+	uint16_t        reserved4:8;
+} __attribute__((packed, aligned(4)));
+
+/* New one for 7k */
+struct msm_vfe_command_7k {
+	uint16_t queue;
+	uint16_t length;
+	void     *value;
+};
+
+struct stop_event {
+  wait_queue_head_t wait;
+	int state;
+  int timeout;
+};
+
+
+#endif /* __MSM_VFE7X_H__ */
diff --git a/drivers/staging/dream/camera/msm_vfe8x.c b/drivers/staging/dream/camera/msm_vfe8x.c
new file mode 100644
index 0000000..03de6ec
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_vfe8x.c
@@ -0,0 +1,756 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <mach/irqs.h>
+#include "msm_vfe8x_proc.h"
+
+#define ON  1
+#define OFF 0
+
+struct mutex vfe_lock;
+static void     *vfe_syncdata;
+
+static int vfe_enable(struct camera_enable_cmd *enable)
+{
+	int rc = 0;
+	return rc;
+}
+
+static int vfe_disable(struct camera_enable_cmd *enable,
+	struct platform_device *dev)
+{
+	int rc = 0;
+
+	vfe_stop();
+
+	msm_camio_disable(dev);
+	return rc;
+}
+
+static void vfe_release(struct platform_device *dev)
+{
+	msm_camio_disable(dev);
+	vfe_cmd_release(dev);
+
+	mutex_lock(&vfe_lock);
+	vfe_syncdata = NULL;
+	mutex_unlock(&vfe_lock);
+}
+
+static void vfe_config_axi(int mode,
+	struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
+{
+	struct msm_pmem_region *regptr;
+	int i, j;
+	uint32_t *p1, *p2;
+
+	if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
+		regptr = ad->region;
+		for (i = 0;
+			i < ad->bufnum1; i++) {
+
+			p1 = &(ao->output1.outputY.outFragments[i][0]);
+			p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
+
+			for (j = 0;
+				j < ao->output1.fragmentCount; j++) {
+
+				*p1 = regptr->paddr + regptr->y_off;
+				p1++;
+
+				*p2 = regptr->paddr + regptr->cbcr_off;
+				p2++;
+			}
+			regptr++;
+		}
+	} /* if OUTPUT1 or Both */
+
+	if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
+
+		regptr = &(ad->region[ad->bufnum1]);
+		CDBG("bufnum2 = %d\n", ad->bufnum2);
+
+		for (i = 0;
+			i < ad->bufnum2; i++) {
+
+			p1 = &(ao->output2.outputY.outFragments[i][0]);
+			p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
+
+		CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
+			regptr->paddr, regptr->y_off, regptr->cbcr_off);
+
+			for (j = 0;
+				j < ao->output2.fragmentCount; j++) {
+
+				*p1 = regptr->paddr + regptr->y_off;
+				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
+				p1++;
+
+				*p2 = regptr->paddr + regptr->cbcr_off;
+				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
+				p2++;
+			}
+			regptr++;
+		}
+	}
+}
+
+static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
+{
+	int rc = 0;
+
+	CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
+
+	switch (cmd->id) {
+	case VFE_CMD_ID_RESET:
+		msm_camio_vfe_blk_reset();
+		msm_camio_camif_pad_reg_reset_2();
+		vfe_reset();
+		break;
+
+	case VFE_CMD_ID_START: {
+		struct vfe_cmd_start start;
+		if (copy_from_user(&start,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		/* msm_camio_camif_pad_reg_reset_2(); */
+		msm_camio_camif_pad_reg_reset();
+		vfe_start(&start);
+	}
+		break;
+
+	case VFE_CMD_ID_CAMIF_CONFIG: {
+		struct vfe_cmd_camif_config camif;
+		if (copy_from_user(&camif,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_camif_config(&camif);
+	}
+		break;
+
+	case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
+		struct vfe_cmd_black_level_config bl;
+		if (copy_from_user(&bl,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_black_level_config(&bl);
+	}
+		break;
+
+	case VFE_CMD_ID_ROLL_OFF_CONFIG: {
+		struct vfe_cmd_roll_off_config rolloff;
+		if (copy_from_user(&rolloff,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_roll_off_config(&rolloff);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
+		struct vfe_cmd_demux_channel_gain_config demuxc;
+		if (copy_from_user(&demuxc,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		/* demux is always enabled.  */
+		vfe_demux_channel_gain_config(&demuxc);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMOSAIC_CONFIG: {
+		struct vfe_cmd_demosaic_config demosaic;
+		if (copy_from_user(&demosaic,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_demosaic_config(&demosaic);
+	}
+		break;
+
+	case VFE_CMD_ID_FOV_CROP_CONFIG:
+	case VFE_CMD_ID_FOV_CROP_UPDATE: {
+		struct vfe_cmd_fov_crop_config fov;
+		if (copy_from_user(&fov,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_fov_crop_config(&fov);
+	}
+		break;
+
+	case VFE_CMD_ID_MAIN_SCALER_CONFIG:
+	case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
+		struct vfe_cmd_main_scaler_config mainds;
+		if (copy_from_user(&mainds,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_main_scaler_config(&mainds);
+	}
+		break;
+
+	case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
+	case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
+		struct vfe_cmd_white_balance_config wb;
+		if (copy_from_user(&wb,
+			(void __user *)	cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_white_balance_config(&wb);
+	}
+		break;
+
+	case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
+	case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
+		struct vfe_cmd_color_correction_config cc;
+		if (copy_from_user(&cc,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_color_correction_config(&cc);
+	}
+		break;
+
+	case VFE_CMD_ID_LA_CONFIG: {
+		struct vfe_cmd_la_config la;
+		if (copy_from_user(&la,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_la_config(&la);
+	}
+		break;
+
+	case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
+		struct vfe_cmd_rgb_gamma_config rgb;
+		if (copy_from_user(&rgb,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		rc = vfe_rgb_gamma_config(&rgb);
+	}
+		break;
+
+	case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
+	case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
+		struct vfe_cmd_chroma_enhan_config chrom;
+		if (copy_from_user(&chrom,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_chroma_enhan_config(&chrom);
+	}
+		break;
+
+	case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
+	case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
+		struct vfe_cmd_chroma_suppression_config chromsup;
+		if (copy_from_user(&chromsup,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_chroma_sup_config(&chromsup);
+	}
+		break;
+
+	case VFE_CMD_ID_ASF_CONFIG: {
+		struct vfe_cmd_asf_config asf;
+		if (copy_from_user(&asf,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_asf_config(&asf);
+	}
+		break;
+
+	case VFE_CMD_ID_SCALER2Y_CONFIG:
+	case VFE_CMD_ID_SCALER2Y_UPDATE: {
+		struct vfe_cmd_scaler2_config ds2y;
+		if (copy_from_user(&ds2y,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_scaler2y_config(&ds2y);
+	}
+		break;
+
+	case VFE_CMD_ID_SCALER2CbCr_CONFIG:
+	case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
+		struct vfe_cmd_scaler2_config ds2cbcr;
+		if (copy_from_user(&ds2cbcr,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_scaler2cbcr_config(&ds2cbcr);
+	}
+		break;
+
+	case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
+		struct vfe_cmd_chroma_subsample_config sub;
+		if (copy_from_user(&sub,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_chroma_subsample_config(&sub);
+	}
+		break;
+
+	case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
+		struct vfe_cmd_frame_skip_config fskip;
+		if (copy_from_user(&fskip,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_frame_skip_config(&fskip);
+	}
+		break;
+
+	case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
+		struct vfe_cmd_output_clamp_config clamp;
+		if (copy_from_user(&clamp,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_output_clamp_config(&clamp);
+	}
+		break;
+
+	/* module update commands */
+	case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
+		struct vfe_cmd_black_level_config blk;
+		if (copy_from_user(&blk,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_black_level_update(&blk);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
+		struct vfe_cmd_demux_channel_gain_config dmu;
+		if (copy_from_user(&dmu,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_demux_channel_gain_update(&dmu);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
+		struct vfe_cmd_demosaic_bpc_update demo_bpc;
+		if (copy_from_user(&demo_bpc,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_demosaic_bpc_update(&demo_bpc);
+	}
+		break;
+
+	case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
+		struct vfe_cmd_demosaic_abf_update demo_abf;
+		if (copy_from_user(&demo_abf,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_demosaic_abf_update(&demo_abf);
+	}
+		break;
+
+	case VFE_CMD_ID_LA_UPDATE: {
+		struct vfe_cmd_la_config la;
+		if (copy_from_user(&la,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_la_update(&la);
+	}
+		break;
+
+	case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
+		struct vfe_cmd_rgb_gamma_config rgb;
+		if (copy_from_user(&rgb,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		rc = vfe_rgb_gamma_update(&rgb);
+	}
+		break;
+
+	case VFE_CMD_ID_ASF_UPDATE: {
+		struct vfe_cmd_asf_update asf;
+		if (copy_from_user(&asf,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_asf_update(&asf);
+	}
+		break;
+
+	case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
+		struct vfe_cmd_frame_skip_update fskip;
+		if (copy_from_user(&fskip,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_frame_skip_update(&fskip);
+	}
+		break;
+
+	case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
+		struct vfe_cmds_camif_frame fup;
+		if (copy_from_user(&fup,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_camif_frame_update(&fup);
+	}
+		break;
+
+	/* stats update commands */
+	case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
+		struct vfe_cmd_stats_af_update afup;
+		if (copy_from_user(&afup,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_stats_update_af(&afup);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
+		struct vfe_cmd_stats_wb_exp_update wbexp;
+		if (copy_from_user(&wbexp,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_stats_update_wb_exp(&wbexp);
+	}
+		break;
+
+	/* control of start, stop, update, etc... */
+	case VFE_CMD_ID_STOP:
+		vfe_stop();
+		break;
+
+	case VFE_CMD_ID_GET_HW_VERSION:
+		break;
+
+	/* stats */
+	case VFE_CMD_ID_STATS_SETTING: {
+		struct vfe_cmd_stats_setting stats;
+		if (copy_from_user(&stats,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_stats_setting(&stats);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
+		struct vfe_cmd_stats_af_start af;
+		if (copy_from_user(&af,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_stats_start_af(&af);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
+		vfe_stats_af_stop();
+		break;
+
+	case VFE_CMD_ID_STATS_WB_EXP_START: {
+		struct vfe_cmd_stats_wb_exp_start awexp;
+		if (copy_from_user(&awexp,
+			(void __user *) cmd->value, cmd->length))
+			rc = -EFAULT;
+
+		vfe_stats_start_wb_exp(&awexp);
+	}
+		break;
+
+	case VFE_CMD_ID_STATS_WB_EXP_STOP:
+		vfe_stats_wb_exp_stop();
+		break;
+
+	case VFE_CMD_ID_ASYNC_TIMER_SETTING:
+		break;
+
+	case VFE_CMD_ID_UPDATE:
+		vfe_update();
+		break;
+
+	/* test gen */
+	case VFE_CMD_ID_TEST_GEN_START:
+		break;
+
+/*
+  acknowledge from upper layer
+	these are not in general command.
+
+	case VFE_CMD_ID_OUTPUT1_ACK:
+		break;
+	case VFE_CMD_ID_OUTPUT2_ACK:
+		break;
+	case VFE_CMD_ID_EPOCH1_ACK:
+		break;
+	case VFE_CMD_ID_EPOCH2_ACK:
+		break;
+	case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
+		break;
+	case VFE_CMD_ID_STATS_WB_EXP_ACK:
+		break;
+*/
+
+	default:
+		break;
+	} /* switch */
+
+	return rc;
+}
+
+static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
+{
+	struct msm_pmem_region *regptr;
+	struct msm_vfe_command_8k vfecmd;
+
+	uint32_t i;
+
+	void *cmd_data = NULL;
+	long rc = 0;
+
+	struct vfe_cmd_axi_output_config *axio = NULL;
+	struct vfe_cmd_stats_setting *scfg = NULL;
+
+	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
+	    cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
+
+		if (copy_from_user(&vfecmd,
+				(void __user *)(cmd->value),
+				sizeof(struct msm_vfe_command_8k)))
+			return -EFAULT;
+	}
+
+	CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
+
+	switch (cmd->cmd_type) {
+	case CMD_GENERAL:
+		rc = vfe_proc_general(&vfecmd);
+		break;
+
+	case CMD_STATS_ENABLE:
+	case CMD_STATS_AXI_CFG: {
+		struct axidata *axid;
+
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+
+		scfg =
+			kmalloc(sizeof(struct vfe_cmd_stats_setting),
+				GFP_ATOMIC);
+		if (!scfg)
+			return -ENOMEM;
+
+		if (copy_from_user(scfg,
+					(void __user *)(vfecmd.value),
+					vfecmd.length)) {
+
+			kfree(scfg);
+			return -EFAULT;
+		}
+
+		regptr = axid->region;
+		if (axid->bufnum1 > 0) {
+			for (i = 0; i < axid->bufnum1; i++) {
+				scfg->awbBuffer[i] =
+					(uint32_t)(regptr->paddr);
+				regptr++;
+			}
+		}
+
+		if (axid->bufnum2 > 0) {
+			for (i = 0; i < axid->bufnum2; i++) {
+				scfg->afBuffer[i] =
+					(uint32_t)(regptr->paddr);
+				regptr++;
+			}
+		}
+
+		vfe_stats_config(scfg);
+	}
+		break;
+
+	case CMD_STATS_AF_AXI_CFG: {
+	}
+		break;
+
+	case CMD_FRAME_BUF_RELEASE: {
+		/* preview buffer release */
+		struct msm_frame *b;
+		unsigned long p;
+		struct vfe_cmd_output_ack fack;
+
+		if (!data)
+			return -EFAULT;
+
+		b = (struct msm_frame *)(cmd->value);
+		p = *(unsigned long *)data;
+
+		b->path = MSM_FRAME_ENC;
+
+		fack.ybufaddr[0] =
+			(uint32_t)(p + b->y_off);
+
+		fack.chromabufaddr[0] =
+			(uint32_t)(p + b->cbcr_off);
+
+		if (b->path == MSM_FRAME_PREV_1)
+			vfe_output1_ack(&fack);
+
+		if (b->path == MSM_FRAME_ENC ||
+		    b->path == MSM_FRAME_PREV_2)
+			vfe_output2_ack(&fack);
+	}
+		break;
+
+	case CMD_SNAP_BUF_RELEASE: {
+	}
+		break;
+
+	case CMD_STATS_BUF_RELEASE: {
+		struct vfe_cmd_stats_wb_exp_ack sack;
+
+		if (!data)
+			return -EFAULT;
+
+		sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
+		vfe_stats_wb_exp_ack(&sack);
+	}
+		break;
+
+	case CMD_AXI_CFG_OUT1: {
+		struct axidata *axid;
+
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+
+		axio =
+			kmalloc(sizeof(struct vfe_cmd_axi_output_config),
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+			sizeof(struct vfe_cmd_axi_output_config))) {
+			kfree(axio);
+			return -EFAULT;
+		}
+
+		vfe_config_axi(OUTPUT_1, axid, axio);
+		vfe_axi_output_config(axio);
+	}
+		break;
+
+	case CMD_AXI_CFG_OUT2:
+	case CMD_RAW_PICT_AXI_CFG: {
+		struct axidata *axid;
+
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+
+		axio =
+			kmalloc(sizeof(struct vfe_cmd_axi_output_config),
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				sizeof(struct vfe_cmd_axi_output_config))) {
+			kfree(axio);
+			return -EFAULT;
+		}
+
+		vfe_config_axi(OUTPUT_2, axid, axio);
+
+		axio->outputDataSize = 0;
+		vfe_axi_output_config(axio);
+	}
+		break;
+
+	case CMD_AXI_CFG_SNAP_O1_AND_O2: {
+		struct axidata *axid;
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+
+		axio =
+			kmalloc(sizeof(struct vfe_cmd_axi_output_config),
+				GFP_ATOMIC);
+		if (!axio)
+			return -ENOMEM;
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+			sizeof(struct vfe_cmd_axi_output_config))) {
+			kfree(axio);
+			return -EFAULT;
+		}
+
+		vfe_config_axi(OUTPUT_1_AND_2,
+			axid, axio);
+		vfe_axi_output_config(axio);
+		cmd_data = axio;
+	}
+		break;
+
+	default:
+		break;
+	} /* switch */
+
+	kfree(scfg);
+
+	kfree(axio);
+
+/*
+	if (cmd->length > 256 &&
+			cmd_data &&
+			(cmd->cmd_type == CMD_GENERAL ||
+			 cmd->cmd_type == CMD_STATS_DISABLE)) {
+		kfree(cmd_data);
+	}
+*/
+	return rc;
+}
+
+static int vfe_init(struct msm_vfe_callback *presp,
+	struct platform_device *dev)
+{
+	int rc = 0;
+
+	rc = vfe_cmd_init(presp, dev, vfe_syncdata);
+	if (rc < 0)
+		return rc;
+
+	/* Bring up all the required GPIOs and Clocks */
+	return msm_camio_enable(dev);
+}
+
+void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
+{
+	mutex_init(&vfe_lock);
+	fptr->vfe_init    = vfe_init;
+	fptr->vfe_enable  = vfe_enable;
+	fptr->vfe_config  = vfe_config;
+	fptr->vfe_disable = vfe_disable;
+	fptr->vfe_release = vfe_release;
+	vfe_syncdata = data;
+}
diff --git a/drivers/staging/dream/camera/msm_vfe8x.h b/drivers/staging/dream/camera/msm_vfe8x.h
new file mode 100644
index 0000000..28a70a9
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_vfe8x.h
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+#ifndef __MSM_VFE8X_H__
+#define __MSM_VFE8X_H__
+
+#define TRUE  1
+#define FALSE 0
+#define boolean uint8_t
+
+enum  VFE_STATE {
+	VFE_STATE_IDLE,
+	VFE_STATE_ACTIVE
+};
+
+enum vfe_cmd_id {
+	/*
+	*Important! Command_ID are arranged in order.
+	*Don't change!*/
+	VFE_CMD_ID_START,
+	VFE_CMD_ID_RESET,
+
+	/* bus and camif config */
+	VFE_CMD_ID_AXI_INPUT_CONFIG,
+	VFE_CMD_ID_CAMIF_CONFIG,
+	VFE_CMD_ID_AXI_OUTPUT_CONFIG,
+
+	/* module config  */
+	VFE_CMD_ID_BLACK_LEVEL_CONFIG,
+	VFE_CMD_ID_ROLL_OFF_CONFIG,
+	VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG,
+	VFE_CMD_ID_DEMOSAIC_CONFIG,
+	VFE_CMD_ID_FOV_CROP_CONFIG,
+	VFE_CMD_ID_MAIN_SCALER_CONFIG,
+	VFE_CMD_ID_WHITE_BALANCE_CONFIG,
+	VFE_CMD_ID_COLOR_CORRECTION_CONFIG,
+	VFE_CMD_ID_LA_CONFIG,
+	VFE_CMD_ID_RGB_GAMMA_CONFIG,
+	VFE_CMD_ID_CHROMA_ENHAN_CONFIG,
+	VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG,
+	VFE_CMD_ID_ASF_CONFIG,
+	VFE_CMD_ID_SCALER2Y_CONFIG,
+	VFE_CMD_ID_SCALER2CbCr_CONFIG,
+	VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG,
+	VFE_CMD_ID_FRAME_SKIP_CONFIG,
+	VFE_CMD_ID_OUTPUT_CLAMP_CONFIG,
+
+	/* test gen */
+	VFE_CMD_ID_TEST_GEN_START,
+
+	VFE_CMD_ID_UPDATE,
+
+	/* ackownledge from upper layer */
+	VFE_CMD_ID_OUTPUT1_ACK,
+	VFE_CMD_ID_OUTPUT2_ACK,
+	VFE_CMD_ID_EPOCH1_ACK,
+	VFE_CMD_ID_EPOCH2_ACK,
+	VFE_CMD_ID_STATS_AUTOFOCUS_ACK,
+	VFE_CMD_ID_STATS_WB_EXP_ACK,
+
+	/* module update commands */
+	VFE_CMD_ID_BLACK_LEVEL_UPDATE,
+	VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE,
+	VFE_CMD_ID_DEMOSAIC_BPC_UPDATE,
+	VFE_CMD_ID_DEMOSAIC_ABF_UPDATE,
+	VFE_CMD_ID_FOV_CROP_UPDATE,
+	VFE_CMD_ID_WHITE_BALANCE_UPDATE,
+	VFE_CMD_ID_COLOR_CORRECTION_UPDATE,
+	VFE_CMD_ID_LA_UPDATE,
+	VFE_CMD_ID_RGB_GAMMA_UPDATE,
+	VFE_CMD_ID_CHROMA_ENHAN_UPDATE,
+	VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE,
+	VFE_CMD_ID_MAIN_SCALER_UPDATE,
+	VFE_CMD_ID_SCALER2CbCr_UPDATE,
+	VFE_CMD_ID_SCALER2Y_UPDATE,
+	VFE_CMD_ID_ASF_UPDATE,
+	VFE_CMD_ID_FRAME_SKIP_UPDATE,
+	VFE_CMD_ID_CAMIF_FRAME_UPDATE,
+
+	/* stats update commands */
+	VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE,
+	VFE_CMD_ID_STATS_WB_EXP_UPDATE,
+
+	/* control of start, stop, update, etc... */
+  VFE_CMD_ID_STOP,
+	VFE_CMD_ID_GET_HW_VERSION,
+
+	/* stats */
+	VFE_CMD_ID_STATS_SETTING,
+	VFE_CMD_ID_STATS_AUTOFOCUS_START,
+	VFE_CMD_ID_STATS_AUTOFOCUS_STOP,
+	VFE_CMD_ID_STATS_WB_EXP_START,
+	VFE_CMD_ID_STATS_WB_EXP_STOP,
+
+	VFE_CMD_ID_ASYNC_TIMER_SETTING,
+
+	/* max id  */
+	VFE_CMD_ID_MAX
+};
+
+struct vfe_cmd_hw_version {
+	uint32_t minorVersion;
+	uint32_t majorVersion;
+	uint32_t coreVersion;
+};
+
+enum VFE_CAMIF_SYNC_EDGE {
+	VFE_CAMIF_SYNC_EDGE_ActiveHigh,
+	VFE_CAMIF_SYNC_EDGE_ActiveLow
+};
+
+enum VFE_CAMIF_SYNC_MODE {
+	VFE_CAMIF_SYNC_MODE_APS,
+	VFE_CAMIF_SYNC_MODE_EFS,
+	VFE_CAMIF_SYNC_MODE_ELS,
+	VFE_CAMIF_SYNC_MODE_ILLEGAL
+};
+
+struct vfe_cmds_camif_efs {
+	uint8_t efsendofline;
+	uint8_t efsstartofline;
+	uint8_t efsendofframe;
+	uint8_t efsstartofframe;
+};
+
+struct vfe_cmds_camif_frame {
+	uint16_t pixelsPerLine;
+	uint16_t linesPerFrame;
+};
+
+struct vfe_cmds_camif_window {
+	uint16_t firstpixel;
+	uint16_t lastpixel;
+	uint16_t firstline;
+	uint16_t lastline;
+};
+
+enum CAMIF_SUBSAMPLE_FRAME_SKIP {
+	CAMIF_SUBSAMPLE_FRAME_SKIP_0,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_AllFrames,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_2Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_3Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_4Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_5Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_6Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_7Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_8Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_9Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_10Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_11Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_12Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_13Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_14Frame,
+	CAMIF_SUBSAMPLE_FRAME_SKIP_ONE_OUT_OF_EVERY_15Frame
+};
+
+struct vfe_cmds_camif_subsample {
+	uint16_t pixelskipmask;
+	uint16_t lineskipmask;
+	enum CAMIF_SUBSAMPLE_FRAME_SKIP frameskip;
+	uint8_t frameskipmode;
+	uint8_t pixelskipwrap;
+};
+
+struct vfe_cmds_camif_epoch {
+	uint8_t  enable;
+	uint16_t lineindex;
+};
+
+struct vfe_cmds_camif_cfg {
+	enum VFE_CAMIF_SYNC_EDGE  vSyncEdge;
+	enum VFE_CAMIF_SYNC_EDGE  hSyncEdge;
+	enum VFE_CAMIF_SYNC_MODE  syncMode;
+	uint8_t vfeSubSampleEnable;
+	uint8_t busSubSampleEnable;
+	uint8_t irqSubSampleEnable;
+	uint8_t binningEnable;
+	uint8_t misrEnable;
+};
+
+struct vfe_cmd_camif_config {
+	struct vfe_cmds_camif_cfg camifConfig;
+	struct vfe_cmds_camif_efs EFS;
+	struct vfe_cmds_camif_frame     frame;
+	struct vfe_cmds_camif_window    window;
+	struct vfe_cmds_camif_subsample subsample;
+	struct vfe_cmds_camif_epoch     epoch1;
+	struct vfe_cmds_camif_epoch     epoch2;
+};
+
+enum VFE_AXI_OUTPUT_MODE {
+	VFE_AXI_OUTPUT_MODE_Output1,
+	VFE_AXI_OUTPUT_MODE_Output2,
+	VFE_AXI_OUTPUT_MODE_Output1AndOutput2,
+	VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2,
+	VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1,
+	VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2,
+	VFE_AXI_LAST_OUTPUT_MODE_ENUM
+};
+
+enum VFE_RAW_WR_PATH_SEL {
+	VFE_RAW_OUTPUT_DISABLED,
+	VFE_RAW_OUTPUT_ENC_CBCR_PATH,
+	VFE_RAW_OUTPUT_VIEW_CBCR_PATH,
+	VFE_RAW_OUTPUT_PATH_INVALID
+};
+
+enum VFE_RAW_PIXEL_DATA_SIZE {
+	VFE_RAW_PIXEL_DATA_SIZE_8BIT,
+	VFE_RAW_PIXEL_DATA_SIZE_10BIT,
+	VFE_RAW_PIXEL_DATA_SIZE_12BIT,
+};
+
+#define VFE_AXI_OUTPUT_BURST_LENGTH     4
+#define VFE_MAX_NUM_FRAGMENTS_PER_FRAME 4
+#define VFE_AXI_OUTPUT_CFG_FRAME_COUNT  3
+
+struct vfe_cmds_axi_out_per_component {
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint16_t outRowCount;
+	uint16_t outRowIncrement;
+	uint32_t outFragments[VFE_AXI_OUTPUT_CFG_FRAME_COUNT]
+		[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+struct vfe_cmds_axi_per_output_path {
+	uint8_t fragmentCount;
+	struct vfe_cmds_axi_out_per_component outputY;
+	struct vfe_cmds_axi_out_per_component outputCbcr;
+};
+
+enum VFE_AXI_BURST_LENGTH {
+	VFE_AXI_BURST_LENGTH_IS_2  = 2,
+	VFE_AXI_BURST_LENGTH_IS_4  = 4,
+	VFE_AXI_BURST_LENGTH_IS_8  = 8,
+	VFE_AXI_BURST_LENGTH_IS_16 = 16
+};
+
+struct vfe_cmd_axi_output_config {
+	enum VFE_AXI_BURST_LENGTH burstLength;
+	enum VFE_AXI_OUTPUT_MODE outputMode;
+	enum VFE_RAW_PIXEL_DATA_SIZE outputDataSize;
+	struct vfe_cmds_axi_per_output_path output1;
+	struct vfe_cmds_axi_per_output_path output2;
+};
+
+struct vfe_cmd_fov_crop_config {
+	uint8_t enable;
+	uint16_t firstPixel;
+	uint16_t lastPixel;
+	uint16_t firstLine;
+	uint16_t lastLine;
+};
+
+struct vfe_cmds_main_scaler_stripe_init {
+	uint16_t MNCounterInit;
+	uint16_t phaseInit;
+};
+
+struct vfe_cmds_scaler_one_dimension {
+	uint8_t  enable;
+	uint16_t inputSize;
+	uint16_t outputSize;
+	uint32_t phaseMultiplicationFactor;
+	uint8_t  interpolationResolution;
+};
+
+struct vfe_cmd_main_scaler_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension    hconfig;
+	struct vfe_cmds_scaler_one_dimension    vconfig;
+	struct vfe_cmds_main_scaler_stripe_init MNInitH;
+	struct vfe_cmds_main_scaler_stripe_init MNInitV;
+};
+
+struct vfe_cmd_scaler2_config {
+	uint8_t enable;
+	struct vfe_cmds_scaler_one_dimension hconfig;
+	struct vfe_cmds_scaler_one_dimension vconfig;
+};
+
+struct vfe_cmd_frame_skip_config {
+	uint8_t output1Period;
+	uint32_t output1Pattern;
+	uint8_t output2Period;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_frame_skip_update {
+	uint32_t output1Pattern;
+	uint32_t output2Pattern;
+};
+
+struct vfe_cmd_output_clamp_config {
+	uint8_t minCh0;
+	uint8_t minCh1;
+	uint8_t minCh2;
+	uint8_t maxCh0;
+	uint8_t maxCh1;
+	uint8_t maxCh2;
+};
+
+struct vfe_cmd_chroma_subsample_config {
+	uint8_t enable;
+	uint8_t cropEnable;
+	uint8_t vsubSampleEnable;
+	uint8_t hsubSampleEnable;
+	uint8_t vCosited;
+	uint8_t hCosited;
+	uint8_t vCositedPhase;
+	uint8_t hCositedPhase;
+	uint16_t cropWidthFirstPixel;
+	uint16_t cropWidthLastPixel;
+	uint16_t cropHeightFirstLine;
+	uint16_t cropHeightLastLine;
+};
+
+enum VFE_START_INPUT_SOURCE {
+	VFE_START_INPUT_SOURCE_CAMIF,
+	VFE_START_INPUT_SOURCE_TESTGEN,
+	VFE_START_INPUT_SOURCE_AXI,
+	VFE_START_INPUT_SOURCE_INVALID
+};
+
+enum VFE_START_OPERATION_MODE {
+	VFE_START_OPERATION_MODE_CONTINUOUS,
+	VFE_START_OPERATION_MODE_SNAPSHOT
+};
+
+enum VFE_START_PIXEL_PATTERN {
+	VFE_BAYER_RGRGRG,
+	VFE_BAYER_GRGRGR,
+	VFE_BAYER_BGBGBG,
+	VFE_BAYER_GBGBGB,
+	VFE_YUV_YCbYCr,
+	VFE_YUV_YCrYCb,
+	VFE_YUV_CbYCrY,
+	VFE_YUV_CrYCbY
+};
+
+enum VFE_BUS_RD_INPUT_PIXEL_PATTERN {
+	VFE_BAYER_RAW,
+	VFE_YUV_INTERLEAVED,
+	VFE_YUV_PSEUDO_PLANAR_Y,
+	VFE_YUV_PSEUDO_PLANAR_CBCR
+};
+
+enum VFE_YUV_INPUT_COSITING_MODE {
+	VFE_YUV_COSITED,
+	VFE_YUV_INTERPOLATED
+};
+
+struct vfe_cmd_start {
+	enum VFE_START_INPUT_SOURCE inputSource;
+	enum VFE_START_OPERATION_MODE operationMode;
+	uint8_t     snapshotCount;
+	enum VFE_START_PIXEL_PATTERN pixel;
+	enum VFE_YUV_INPUT_COSITING_MODE yuvInputCositingMode;
+};
+
+struct vfe_cmd_output_ack {
+	uint32_t ybufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+	uint32_t chromabufaddr[VFE_MAX_NUM_FRAGMENTS_PER_FRAME];
+};
+
+#define VFE_STATS_BUFFER_COUNT 3
+
+struct vfe_cmd_stats_setting {
+	uint16_t frameHDimension;
+	uint16_t frameVDimension;
+	uint8_t  afBusPrioritySelection;
+	uint8_t  afBusPriority;
+	uint8_t  awbBusPrioritySelection;
+	uint8_t  awbBusPriority;
+	uint8_t  histBusPrioritySelection;
+	uint8_t  histBusPriority;
+	uint32_t afBuffer[VFE_STATS_BUFFER_COUNT];
+	uint32_t awbBuffer[VFE_STATS_BUFFER_COUNT];
+	uint32_t histBuffer[VFE_STATS_BUFFER_COUNT];
+};
+
+struct vfe_cmd_stats_af_start {
+	uint8_t  enable;
+	uint8_t  windowMode;
+	uint16_t windowHOffset;
+	uint16_t windowVOffset;
+	uint16_t windowWidth;
+	uint16_t windowHeight;
+	uint8_t  gridForMultiWindows[16];
+	uint8_t     metricSelection;
+	int16_t  metricMax;
+	int8_t   highPassCoef[7];
+	int8_t   bufferHeader;
+};
+
+struct vfe_cmd_stats_af_update {
+	uint8_t  windowMode;
+	uint16_t windowHOffset;
+	uint16_t windowVOffset;
+	uint16_t windowWidth;
+	uint16_t windowHeight;
+};
+
+struct vfe_cmd_stats_wb_exp_start {
+	uint8_t   enable;
+	uint8_t   wbExpRegions;
+	uint8_t   wbExpSubRegion;
+	uint8_t   awbYMin;
+	uint8_t   awbYMax;
+	int8_t    awbMCFG[4];
+	int16_t   awbCCFG[4];
+	int8_t    axwHeader;
+};
+
+struct vfe_cmd_stats_wb_exp_update {
+	uint8_t wbExpRegions;
+	uint8_t wbExpSubRegion;
+	int8_t  awbYMin;
+	int8_t  awbYMax;
+	int8_t  awbMCFG[4];
+	int16_t awbCCFG[4];
+};
+
+struct vfe_cmd_stats_af_ack {
+	uint32_t nextAFOutputBufferAddr;
+};
+
+struct vfe_cmd_stats_wb_exp_ack {
+	uint32_t  nextWbExpOutputBufferAddr;
+};
+
+struct vfe_cmd_black_level_config {
+	uint8_t  enable;
+	uint16_t evenEvenAdjustment;
+	uint16_t evenOddAdjustment;
+	uint16_t oddEvenAdjustment;
+	uint16_t oddOddAdjustment;
+};
+
+/* 13*1  */
+#define  VFE_ROLL_OFF_INIT_TABLE_SIZE  13
+/* 13*16 */
+#define  VFE_ROLL_OFF_DELTA_TABLE_SIZE 208
+
+struct vfe_cmd_roll_off_config {
+	uint8_t  enable;
+	uint16_t gridWidth;
+	uint16_t gridHeight;
+	uint16_t  yDelta;
+	uint8_t  gridXIndex;
+	uint8_t  gridYIndex;
+	uint16_t gridPixelXIndex;
+	uint16_t gridPixelYIndex;
+	uint16_t yDeltaAccum;
+	uint16_t initTableR[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	uint16_t initTableGr[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	uint16_t initTableB[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	uint16_t initTableGb[VFE_ROLL_OFF_INIT_TABLE_SIZE];
+	int16_t  deltaTableR[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+	int16_t  deltaTableGr[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+	int16_t  deltaTableB[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+	int16_t  deltaTableGb[VFE_ROLL_OFF_DELTA_TABLE_SIZE];
+};
+
+struct vfe_cmd_demux_channel_gain_config {
+	uint16_t ch0EvenGain;
+	uint16_t ch0OddGain;
+	uint16_t ch1Gain;
+	uint16_t ch2Gain;
+};
+
+struct vfe_cmds_demosaic_abf {
+	uint8_t   enable;
+	uint8_t   forceOn;
+	uint8_t   shift;
+	uint16_t  lpThreshold;
+	uint16_t  max;
+	uint16_t  min;
+	uint8_t   ratio;
+};
+
+struct vfe_cmds_demosaic_bpc {
+	uint8_t   enable;
+	uint16_t  fmaxThreshold;
+	uint16_t  fminThreshold;
+	uint16_t  redDiffThreshold;
+	uint16_t  blueDiffThreshold;
+	uint16_t  greenDiffThreshold;
+};
+
+struct vfe_cmd_demosaic_config {
+	uint8_t   enable;
+	uint8_t   slopeShift;
+	struct vfe_cmds_demosaic_abf abfConfig;
+	struct vfe_cmds_demosaic_bpc bpcConfig;
+};
+
+struct vfe_cmd_demosaic_bpc_update {
+	struct vfe_cmds_demosaic_bpc bpcUpdate;
+};
+
+struct vfe_cmd_demosaic_abf_update {
+	struct vfe_cmds_demosaic_abf abfUpdate;
+};
+
+struct vfe_cmd_white_balance_config {
+	uint8_t  enable;
+	uint16_t ch2Gain;
+	uint16_t ch1Gain;
+	uint16_t ch0Gain;
+};
+
+enum VFE_COLOR_CORRECTION_COEF_QFACTOR {
+	COEF_IS_Q7_SIGNED,
+	COEF_IS_Q8_SIGNED,
+	COEF_IS_Q9_SIGNED,
+	COEF_IS_Q10_SIGNED
+};
+
+struct vfe_cmd_color_correction_config {
+	uint8_t     enable;
+	enum VFE_COLOR_CORRECTION_COEF_QFACTOR coefQFactor;
+	int16_t  C0;
+	int16_t  C1;
+	int16_t  C2;
+	int16_t  C3;
+	int16_t  C4;
+	int16_t  C5;
+	int16_t  C6;
+	int16_t  C7;
+	int16_t  C8;
+	int16_t  K0;
+	int16_t  K1;
+	int16_t  K2;
+};
+
+#define VFE_LA_TABLE_LENGTH 256
+struct vfe_cmd_la_config {
+	uint8_t enable;
+	int16_t table[VFE_LA_TABLE_LENGTH];
+};
+
+#define VFE_GAMMA_TABLE_LENGTH 256
+enum VFE_RGB_GAMMA_TABLE_SELECT {
+	RGB_GAMMA_CH0_SELECTED,
+	RGB_GAMMA_CH1_SELECTED,
+	RGB_GAMMA_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_SELECTED,
+	RGB_GAMMA_CH0_CH2_SELECTED,
+	RGB_GAMMA_CH1_CH2_SELECTED,
+	RGB_GAMMA_CH0_CH1_CH2_SELECTED
+};
+
+struct vfe_cmd_rgb_gamma_config {
+	uint8_t enable;
+	enum VFE_RGB_GAMMA_TABLE_SELECT channelSelect;
+	int16_t table[VFE_GAMMA_TABLE_LENGTH];
+};
+
+struct vfe_cmd_chroma_enhan_config {
+	uint8_t  enable;
+	int16_t am;
+	int16_t ap;
+	int16_t bm;
+	int16_t bp;
+	int16_t cm;
+	int16_t cp;
+	int16_t dm;
+	int16_t dp;
+	int16_t kcr;
+	int16_t kcb;
+	int16_t RGBtoYConversionV0;
+	int16_t RGBtoYConversionV1;
+	int16_t RGBtoYConversionV2;
+	uint8_t RGBtoYConversionOffset;
+};
+
+struct vfe_cmd_chroma_suppression_config {
+	uint8_t enable;
+	uint8_t m1;
+	uint8_t m3;
+	uint8_t n1;
+	uint8_t n3;
+	uint8_t nn1;
+	uint8_t mm1;
+};
+
+struct vfe_cmd_asf_config {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t sharpThreshE2;
+	int8_t sharpThreshE3;
+	int8_t sharpThreshE4;
+	int8_t sharpThreshE5;
+	int8_t filter1Coefficients[9];
+	int8_t filter2Coefficients[9];
+	uint8_t  cropEnable;
+	uint16_t cropFirstPixel;
+	uint16_t cropLastPixel;
+	uint16_t cropFirstLine;
+	uint16_t cropLastLine;
+};
+
+struct vfe_cmd_asf_update {
+	uint8_t enable;
+	uint8_t smoothFilterEnabled;
+	uint8_t sharpMode;
+	uint8_t smoothCoefCenter;
+	uint8_t smoothCoefSurr;
+	uint8_t normalizeFactor;
+	uint8_t sharpK1;
+	uint8_t sharpK2;
+	uint8_t sharpThreshE1;
+	int8_t  sharpThreshE2;
+	int8_t  sharpThreshE3;
+	int8_t  sharpThreshE4;
+	int8_t  sharpThreshE5;
+	int8_t  filter1Coefficients[9];
+	int8_t  filter2Coefficients[9];
+	uint8_t cropEnable;
+};
+
+enum VFE_TEST_GEN_SYNC_EDGE {
+	VFE_TEST_GEN_SYNC_EDGE_ActiveHigh,
+	VFE_TEST_GEN_SYNC_EDGE_ActiveLow
+};
+
+struct vfe_cmd_test_gen_start {
+	uint8_t pixelDataSelect;
+	uint8_t systematicDataSelect;
+	enum VFE_TEST_GEN_SYNC_EDGE  hsyncEdge;
+	enum VFE_TEST_GEN_SYNC_EDGE  vsyncEdge;
+	uint16_t numFrame;
+	enum VFE_RAW_PIXEL_DATA_SIZE pixelDataSize;
+	uint16_t imageWidth;
+	uint16_t imageHeight;
+	uint32_t startOfFrameOffset;
+	uint32_t endOfFrameNOffset;
+	uint16_t startOfLineOffset;
+	uint16_t endOfLineNOffset;
+	uint16_t hbi;
+	uint8_t  vblEnable;
+	uint16_t vbl;
+	uint8_t  startOfFrameDummyLine;
+	uint8_t  endOfFrameDummyLine;
+	uint8_t  unicolorBarEnable;
+	uint8_t  colorBarsSplitEnable;
+	uint8_t  unicolorBarSelect;
+	enum VFE_START_PIXEL_PATTERN  colorBarsPixelPattern;
+	uint8_t  colorBarsRotatePeriod;
+	uint16_t testGenRandomSeed;
+};
+
+struct vfe_cmd_bus_pm_start {
+	uint8_t output2YWrPmEnable;
+	uint8_t output2CbcrWrPmEnable;
+	uint8_t output1YWrPmEnable;
+	uint8_t output1CbcrWrPmEnable;
+};
+
+struct vfe_cmd_camif_frame_update {
+	struct vfe_cmds_camif_frame camifFrame;
+};
+
+struct vfe_cmd_sync_timer_setting {
+	uint8_t  whichSyncTimer;
+	uint8_t  operation;
+	uint8_t  polarity;
+	uint16_t repeatCount;
+	uint16_t hsyncCount;
+	uint32_t pclkCount;
+	uint32_t outputDuration;
+};
+
+struct vfe_cmd_async_timer_setting {
+	uint8_t  whichAsyncTimer;
+	uint8_t  operation;
+	uint8_t  polarity;
+	uint16_t repeatCount;
+	uint16_t inactiveCount;
+	uint32_t activeCount;
+};
+
+struct  vfe_frame_skip_counts {
+	uint32_t  totalFrameCount;
+	uint32_t  output1Count;
+	uint32_t  output2Count;
+};
+
+enum VFE_AXI_RD_UNPACK_HBI_SEL {
+	VFE_AXI_RD_HBI_32_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_64_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_128_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_256_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_512_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_1024_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_2048_CLOCK_CYCLES,
+	VFE_AXI_RD_HBI_4096_CLOCK_CYCLES
+};
+
+struct vfe_cmd_axi_input_config {
+	uint32_t  fragAddr[4];
+	uint8_t   totalFragmentCount;
+	uint16_t  ySize;
+	uint16_t  xOffset;
+	uint16_t  xSize;
+	uint16_t  rowIncrement;
+	uint16_t  numOfRows;
+	enum VFE_AXI_BURST_LENGTH burstLength;
+	uint8_t   unpackPhase;
+	enum VFE_AXI_RD_UNPACK_HBI_SEL unpackHbi;
+	enum VFE_RAW_PIXEL_DATA_SIZE   pixelSize;
+	uint8_t   padRepeatCountLeft;
+	uint8_t   padRepeatCountRight;
+	uint8_t   padRepeatCountTop;
+	uint8_t   padRepeatCountBottom;
+	uint8_t   padLeftComponentSelectCycle0;
+	uint8_t   padLeftComponentSelectCycle1;
+	uint8_t   padLeftComponentSelectCycle2;
+	uint8_t   padLeftComponentSelectCycle3;
+	uint8_t   padLeftStopCycle0;
+	uint8_t   padLeftStopCycle1;
+	uint8_t   padLeftStopCycle2;
+	uint8_t   padLeftStopCycle3;
+	uint8_t   padRightComponentSelectCycle0;
+	uint8_t   padRightComponentSelectCycle1;
+	uint8_t   padRightComponentSelectCycle2;
+	uint8_t   padRightComponentSelectCycle3;
+	uint8_t   padRightStopCycle0;
+	uint8_t   padRightStopCycle1;
+	uint8_t   padRightStopCycle2;
+	uint8_t   padRightStopCycle3;
+	uint8_t   padTopLineCount;
+	uint8_t   padBottomLineCount;
+};
+
+struct vfe_interrupt_status {
+	uint8_t camifErrorIrq;
+	uint8_t camifSofIrq;
+	uint8_t camifEolIrq;
+	uint8_t camifEofIrq;
+	uint8_t camifEpoch1Irq;
+	uint8_t camifEpoch2Irq;
+	uint8_t camifOverflowIrq;
+	uint8_t ceIrq;
+	uint8_t regUpdateIrq;
+	uint8_t resetAckIrq;
+	uint8_t encYPingpongIrq;
+	uint8_t encCbcrPingpongIrq;
+	uint8_t viewYPingpongIrq;
+	uint8_t viewCbcrPingpongIrq;
+	uint8_t rdPingpongIrq;
+	uint8_t afPingpongIrq;
+	uint8_t awbPingpongIrq;
+	uint8_t histPingpongIrq;
+	uint8_t encIrq;
+	uint8_t viewIrq;
+	uint8_t busOverflowIrq;
+	uint8_t afOverflowIrq;
+	uint8_t awbOverflowIrq;
+	uint8_t syncTimer0Irq;
+	uint8_t syncTimer1Irq;
+	uint8_t syncTimer2Irq;
+	uint8_t asyncTimer0Irq;
+	uint8_t asyncTimer1Irq;
+	uint8_t asyncTimer2Irq;
+	uint8_t asyncTimer3Irq;
+	uint8_t axiErrorIrq;
+	uint8_t violationIrq;
+	uint8_t anyErrorIrqs;
+	uint8_t anyOutput1PathIrqs;
+	uint8_t anyOutput2PathIrqs;
+	uint8_t anyOutputPathIrqs;
+	uint8_t anyAsyncTimerIrqs;
+	uint8_t anySyncTimerIrqs;
+	uint8_t anyIrqForActiveStatesOnly;
+};
+
+enum VFE_MESSAGE_ID {
+	VFE_MSG_ID_RESET_ACK,
+	VFE_MSG_ID_START_ACK,
+	VFE_MSG_ID_STOP_ACK,
+	VFE_MSG_ID_UPDATE_ACK,
+	VFE_MSG_ID_OUTPUT1,
+	VFE_MSG_ID_OUTPUT2,
+	VFE_MSG_ID_SNAPSHOT_DONE,
+	VFE_MSG_ID_STATS_AUTOFOCUS,
+	VFE_MSG_ID_STATS_WB_EXP,
+	VFE_MSG_ID_EPOCH1,
+	VFE_MSG_ID_EPOCH2,
+	VFE_MSG_ID_SYNC_TIMER0_DONE,
+	VFE_MSG_ID_SYNC_TIMER1_DONE,
+	VFE_MSG_ID_SYNC_TIMER2_DONE,
+	VFE_MSG_ID_ASYNC_TIMER0_DONE,
+	VFE_MSG_ID_ASYNC_TIMER1_DONE,
+	VFE_MSG_ID_ASYNC_TIMER2_DONE,
+	VFE_MSG_ID_ASYNC_TIMER3_DONE,
+	VFE_MSG_ID_AF_OVERFLOW,
+	VFE_MSG_ID_AWB_OVERFLOW,
+	VFE_MSG_ID_AXI_ERROR,
+	VFE_MSG_ID_CAMIF_OVERFLOW,
+	VFE_MSG_ID_VIOLATION,
+	VFE_MSG_ID_CAMIF_ERROR,
+	VFE_MSG_ID_BUS_OVERFLOW,
+};
+
+struct vfe_msg_stats_autofocus {
+	uint32_t    afBuffer;
+	uint32_t    frameCounter;
+};
+
+struct vfe_msg_stats_wb_exp {
+	uint32_t awbBuffer;
+	uint32_t frameCounter;
+};
+
+struct vfe_frame_bpc_info {
+	uint32_t greenDefectPixelCount;
+	uint32_t redBlueDefectPixelCount;
+};
+
+struct vfe_frame_asf_info {
+	uint32_t  asfMaxEdge;
+	uint32_t  asfHbiCount;
+};
+
+struct vfe_msg_camif_status {
+	uint8_t  camifState;
+	uint32_t pixelCount;
+	uint32_t lineCount;
+};
+
+struct vfe_bus_pm_per_path {
+	uint32_t yWrPmStats0;
+	uint32_t yWrPmStats1;
+	uint32_t cbcrWrPmStats0;
+	uint32_t cbcrWrPmStats1;
+};
+
+struct vfe_bus_performance_monitor {
+	struct vfe_bus_pm_per_path encPathPmInfo;
+	struct vfe_bus_pm_per_path viewPathPmInfo;
+};
+
+struct vfe_irq_thread_msg {
+	uint32_t  vfeIrqStatus;
+	uint32_t  camifStatus;
+	uint32_t  demosaicStatus;
+	uint32_t  asfMaxEdge;
+	struct vfe_bus_performance_monitor pmInfo;
+};
+
+struct vfe_msg_output {
+	uint32_t  yBuffer;
+	uint32_t  cbcrBuffer;
+	struct vfe_frame_bpc_info bpcInfo;
+	struct vfe_frame_asf_info asfInfo;
+	uint32_t  frameCounter;
+	struct vfe_bus_pm_per_path pmData;
+};
+
+struct vfe_message {
+	enum VFE_MESSAGE_ID _d;
+	union {
+		struct vfe_msg_output              msgOutput1;
+		struct vfe_msg_output              msgOutput2;
+		struct vfe_msg_stats_autofocus     msgStatsAf;
+		struct vfe_msg_stats_wb_exp        msgStatsWbExp;
+		struct vfe_msg_camif_status        msgCamifError;
+		struct vfe_bus_performance_monitor msgBusOverflow;
+   } _u;
+};
+
+/* New one for 8k */
+struct msm_vfe_command_8k {
+	int32_t  id;
+	uint16_t length;
+	void     *value;
+};
+
+struct vfe_frame_extra {
+	struct vfe_frame_bpc_info bpcInfo;
+	struct vfe_frame_asf_info asfInfo;
+	uint32_t  frameCounter;
+	struct vfe_bus_pm_per_path pmData;
+};
+#endif /* __MSM_VFE8X_H__ */
diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.c b/drivers/staging/dream/camera/msm_vfe8x_proc.c
new file mode 100644
index 0000000..10aef0e
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_vfe8x_proc.c
@@ -0,0 +1,4003 @@
+/*
+* Copyright (C) 2008-2009 QUALCOMM Incorporated.
+*/
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include "msm_vfe8x_proc.h"
+#include <media/msm_camera.h>
+
+struct msm_vfe8x_ctrl {
+	/* bit 1:0 ENC_IRQ_MASK = 0x11:
+	 * generate IRQ when both y and cbcr frame is ready. */
+
+	/* bit 1:0 VIEW_IRQ_MASK= 0x11:
+	 * generate IRQ when both y and cbcr frame is ready. */
+	struct vfe_irq_composite_mask_config vfeIrqCompositeMaskLocal;
+	struct vfe_module_enable vfeModuleEnableLocal;
+	struct vfe_camif_cfg_data   vfeCamifConfigLocal;
+	struct vfe_interrupt_mask   vfeImaskLocal;
+	struct vfe_stats_cmd_data   vfeStatsCmdLocal;
+	struct vfe_bus_cfg_data     vfeBusConfigLocal;
+	struct vfe_cmd_bus_pm_start vfeBusPmConfigLocal;
+	struct vfe_bus_cmd_data     vfeBusCmdLocal;
+	enum vfe_interrupt_name     vfeInterruptNameLocal;
+	uint32_t vfeLaBankSel;
+	struct vfe_gamma_lut_sel  vfeGammaLutSel;
+
+	boolean vfeStartAckPendingFlag;
+	boolean vfeStopAckPending;
+	boolean vfeResetAckPending;
+	boolean vfeUpdateAckPending;
+
+	enum VFE_AXI_OUTPUT_MODE        axiOutputMode;
+	enum VFE_START_OPERATION_MODE   vfeOperationMode;
+
+	uint32_t            vfeSnapShotCount;
+	uint32_t            vfeRequestedSnapShotCount;
+	boolean             vfeStatsPingPongReloadFlag;
+	uint32_t            vfeFrameId;
+
+	struct vfe_cmd_frame_skip_config vfeFrameSkip;
+	uint32_t vfeFrameSkipPattern;
+	uint8_t  vfeFrameSkipCount;
+	uint8_t  vfeFrameSkipPeriod;
+
+	boolean  vfeTestGenStartFlag;
+	uint32_t vfeImaskPacked;
+	uint32_t vfeImaskCompositePacked;
+	enum VFE_RAW_PIXEL_DATA_SIZE       axiInputDataSize;
+	struct vfe_irq_thread_msg          vfeIrqThreadMsgLocal;
+
+	struct vfe_output_path_combo  viewPath;
+	struct vfe_output_path_combo  encPath;
+	struct vfe_frame_skip_counts vfeDroppedFrameCounts;
+	struct vfe_stats_control afStatsControl;
+	struct vfe_stats_control awbStatsControl;
+
+	enum VFE_STATE  vstate;
+
+	spinlock_t  ack_lock;
+	spinlock_t  state_lock;
+	spinlock_t  io_lock;
+
+	struct msm_vfe_callback *resp;
+	uint32_t extlen;
+	void *extdata;
+
+	spinlock_t  tasklet_lock;
+	struct list_head tasklet_q;
+
+	int vfeirq;
+	void __iomem *vfebase;
+
+	void *syncdata;
+};
+static struct msm_vfe8x_ctrl *ctrl;
+static irqreturn_t vfe_parse_irq(int irq_num, void *data);
+
+struct isr_queue_cmd {
+	struct list_head list;
+	struct vfe_interrupt_status        vfeInterruptStatus;
+	struct vfe_frame_asf_info          vfeAsfFrameInfo;
+	struct vfe_frame_bpc_info          vfeBpcFrameInfo;
+	struct vfe_msg_camif_status        vfeCamifStatusLocal;
+	struct vfe_bus_performance_monitor vfePmData;
+};
+
+static void vfe_prog_hw(uint8_t *hwreg,
+	uint32_t *inptr, uint32_t regcnt)
+{
+	/* unsigned long flags; */
+	uint32_t i;
+	uint32_t *p;
+
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->io_lock, flags); */
+
+	p = (uint32_t *)(hwreg);
+	for (i = 0; i < (regcnt >> 2); i++)
+		writel(*inptr++, p++);
+		/* *p++ = *inptr++; */
+
+	/* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
+}
+
+static void vfe_read_reg_values(uint8_t *hwreg,
+	uint32_t *dest, uint32_t count)
+{
+	/* unsigned long flags; */
+	uint32_t *temp;
+	uint32_t i;
+
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->io_lock, flags); */
+
+	temp = (uint32_t *)(hwreg);
+	for (i = 0; i < count; i++)
+		*dest++ = *temp++;
+
+	/* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
+}
+
+static struct vfe_irqenable vfe_read_irq_mask(void)
+{
+	/* unsigned long flags; */
+	uint32_t *temp;
+	struct vfe_irqenable rc;
+
+	memset(&rc, 0, sizeof(rc));
+
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->io_lock, flags); */
+	temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_MASK);
+
+	rc = *((struct vfe_irqenable *)temp);
+	/* spin_unlock_irqrestore(&ctrl->io_lock, flags); */
+
+	return rc;
+}
+
+static void
+vfe_set_bus_pipo_addr(struct vfe_output_path_combo *vpath,
+	struct vfe_output_path_combo *epath)
+{
+	vpath->yPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PING_ADDR);
+	vpath->yPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_Y_WR_PONG_ADDR);
+	vpath->cbcrPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PING_ADDR);
+	vpath->cbcrPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_VIEW_CBCR_WR_PONG_ADDR);
+
+	epath->yPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR);
+	epath->yPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PONG_ADDR);
+	epath->cbcrPath.hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PING_ADDR);
+	epath->cbcrPath.hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PONG_ADDR);
+}
+
+static void vfe_axi_output(struct vfe_cmd_axi_output_config *in,
+	struct vfe_output_path_combo *out1,
+	struct vfe_output_path_combo *out2, uint16_t out)
+{
+	struct vfe_axi_out_cfg cmd;
+
+	uint16_t temp;
+	uint32_t burstLength;
+
+	/* force it to burst length 4, hardware does not support it. */
+	burstLength = 1;
+
+	/* AXI Output 2 Y Configuration*/
+	/* VFE_BUS_ENC_Y_WR_PING_ADDR  */
+	cmd.out2YPingAddr = out2->yPath.addressBuffer[0];
+
+	/* VFE_BUS_ENC_Y_WR_PONG_ADDR  */
+	cmd.out2YPongAddr = out2->yPath.addressBuffer[1];
+
+	/* VFE_BUS_ENC_Y_WR_IMAGE_SIZE */
+	cmd.out2YImageHeight = in->output2.outputY.imageHeight;
+	/* convert the image width and row increment to be in
+	 * unit of 64bit (8 bytes) */
+	temp = (in->output2.outputY.imageWidth + (out - 1)) /
+		out;
+	cmd.out2YImageWidthin64bit = temp;
+
+	/* VFE_BUS_ENC_Y_WR_BUFFER_CFG */
+	cmd.out2YBurstLength = burstLength;
+	cmd.out2YNumRows = in->output2.outputY.outRowCount;
+	temp = (in->output2.outputY.outRowIncrement + (out - 1)) /
+		out;
+	cmd.out2YRowIncrementIn64bit = temp;
+
+	/* AXI Output 2 Cbcr Configuration*/
+	/* VFE_BUS_ENC_Cbcr_WR_PING_ADDR  */
+	cmd.out2CbcrPingAddr = out2->cbcrPath.addressBuffer[0];
+
+	/* VFE_BUS_ENC_Cbcr_WR_PONG_ADDR  */
+	cmd.out2CbcrPongAddr = out2->cbcrPath.addressBuffer[1];
+
+	/* VFE_BUS_ENC_Cbcr_WR_IMAGE_SIZE */
+	cmd.out2CbcrImageHeight = in->output2.outputCbcr.imageHeight;
+	temp = (in->output2.outputCbcr.imageWidth + (out - 1)) /
+		out;
+	cmd.out2CbcrImageWidthIn64bit = temp;
+
+	/* VFE_BUS_ENC_Cbcr_WR_BUFFER_CFG */
+	cmd.out2CbcrBurstLength = burstLength;
+	cmd.out2CbcrNumRows = in->output2.outputCbcr.outRowCount;
+	temp = (in->output2.outputCbcr.outRowIncrement + (out - 1)) /
+		out;
+	cmd.out2CbcrRowIncrementIn64bit = temp;
+
+	/* AXI Output 1 Y Configuration */
+	/* VFE_BUS_VIEW_Y_WR_PING_ADDR  */
+	cmd.out1YPingAddr = out1->yPath.addressBuffer[0];
+
+	/* VFE_BUS_VIEW_Y_WR_PONG_ADDR */
+	cmd.out1YPongAddr = out1->yPath.addressBuffer[1];
+
+	/* VFE_BUS_VIEW_Y_WR_IMAGE_SIZE */
+	cmd.out1YImageHeight = in->output1.outputY.imageHeight;
+	temp = (in->output1.outputY.imageWidth + (out - 1)) /
+		out;
+	cmd.out1YImageWidthin64bit = temp;
+
+	/* VFE_BUS_VIEW_Y_WR_BUFFER_CFG     */
+	cmd.out1YBurstLength = burstLength;
+	cmd.out1YNumRows = in->output1.outputY.outRowCount;
+
+	temp =
+		(in->output1.outputY.outRowIncrement +
+		 (out - 1)) / out;
+	cmd.out1YRowIncrementIn64bit = temp;
+
+	/* AXI Output 1 Cbcr Configuration*/
+	cmd.out1CbcrPingAddr = out1->cbcrPath.addressBuffer[0];
+
+	/* VFE_BUS_VIEW_Cbcr_WR_PONG_ADDR  */
+	cmd.out1CbcrPongAddr =
+		out1->cbcrPath.addressBuffer[1];
+
+	/* VFE_BUS_VIEW_Cbcr_WR_IMAGE_SIZE */
+	cmd.out1CbcrImageHeight = in->output1.outputCbcr.imageHeight;
+	temp = (in->output1.outputCbcr.imageWidth +
+		(out - 1)) / out;
+	cmd.out1CbcrImageWidthIn64bit = temp;
+
+	cmd.out1CbcrBurstLength = burstLength;
+	cmd.out1CbcrNumRows = in->output1.outputCbcr.outRowCount;
+	temp =
+		(in->output1.outputCbcr.outRowIncrement +
+		 (out - 1)) / out;
+
+	cmd.out1CbcrRowIncrementIn64bit = temp;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PING_ADDR,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+static void vfe_reg_bus_cfg(struct vfe_bus_cfg_data *in)
+{
+	struct vfe_axi_bus_cfg cmd;
+
+	cmd.stripeRdPathEn      = in->stripeRdPathEn;
+	cmd.encYWrPathEn        = in->encYWrPathEn;
+	cmd.encCbcrWrPathEn     = in->encCbcrWrPathEn;
+	cmd.viewYWrPathEn       = in->viewYWrPathEn;
+	cmd.viewCbcrWrPathEn    = in->viewCbcrWrPathEn;
+	cmd.rawPixelDataSize    = (uint32_t)in->rawPixelDataSize;
+	cmd.rawWritePathSelect  = (uint32_t)in->rawWritePathSelect;
+
+	/*  program vfe_bus_cfg */
+	writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CFG);
+}
+
+static void vfe_reg_camif_config(struct vfe_camif_cfg_data *in)
+{
+	struct VFE_CAMIFConfigType cfg;
+
+	memset(&cfg, 0, sizeof(cfg));
+
+	cfg.VSyncEdge          =
+		in->camifCfgFromCmd.vSyncEdge;
+
+	cfg.HSyncEdge          =
+		in->camifCfgFromCmd.hSyncEdge;
+
+	cfg.syncMode           =
+		in->camifCfgFromCmd.syncMode;
+
+	cfg.vfeSubsampleEnable =
+		in->camifCfgFromCmd.vfeSubSampleEnable;
+
+	cfg.busSubsampleEnable =
+		in->camifCfgFromCmd.busSubSampleEnable;
+
+	cfg.camif2vfeEnable    =
+		in->camif2OutputEnable;
+
+	cfg.camif2busEnable    =
+		in->camif2BusEnable;
+
+	cfg.irqSubsampleEnable =
+		in->camifCfgFromCmd.irqSubSampleEnable;
+
+	cfg.binningEnable      =
+		in->camifCfgFromCmd.binningEnable;
+
+	cfg.misrEnable         =
+		in->camifCfgFromCmd.misrEnable;
+
+	/*  program camif_config */
+	writel(*((uint32_t *)&cfg), ctrl->vfebase + CAMIF_CONFIG);
+}
+
+static void vfe_reg_bus_cmd(struct vfe_bus_cmd_data *in)
+{
+	struct vfe_buscmd cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.stripeReload        = in->stripeReload;
+	cmd.busPingpongReload   = in->busPingpongReload;
+	cmd.statsPingpongReload = in->statsPingpongReload;
+
+	writel(*((uint32_t *)&cmd), ctrl->vfebase + VFE_BUS_CMD);
+
+	CDBG("bus command = 0x%x\n", (*((uint32_t *)&cmd)));
+
+	/* this is needed, as the control bits are pulse based.
+	 * Don't want to reload bus pingpong again. */
+	in->busPingpongReload = 0;
+	in->statsPingpongReload = 0;
+	in->stripeReload = 0;
+}
+
+static void vfe_reg_module_cfg(struct vfe_module_enable *in)
+{
+	struct vfe_mod_enable ena;
+
+	memset(&ena, 0, sizeof(ena));
+
+	ena.blackLevelCorrectionEnable = in->blackLevelCorrectionEnable;
+	ena.lensRollOffEnable          = in->lensRollOffEnable;
+	ena.demuxEnable                = in->demuxEnable;
+	ena.chromaUpsampleEnable       = in->chromaUpsampleEnable;
+	ena.demosaicEnable             = in->demosaicEnable;
+	ena.statsEnable                = in->statsEnable;
+	ena.cropEnable                 = in->cropEnable;
+	ena.mainScalerEnable           = in->mainScalerEnable;
+	ena.whiteBalanceEnable         = in->whiteBalanceEnable;
+	ena.colorCorrectionEnable      = in->colorCorrectionEnable;
+	ena.yHistEnable                = in->yHistEnable;
+	ena.skinToneEnable             = in->skinToneEnable;
+	ena.lumaAdaptationEnable       = in->lumaAdaptationEnable;
+	ena.rgbLUTEnable               = in->rgbLUTEnable;
+	ena.chromaEnhanEnable          = in->chromaEnhanEnable;
+	ena.asfEnable                  = in->asfEnable;
+	ena.chromaSuppressionEnable    = in->chromaSuppressionEnable;
+	ena.chromaSubsampleEnable      = in->chromaSubsampleEnable;
+	ena.scaler2YEnable             = in->scaler2YEnable;
+	ena.scaler2CbcrEnable          = in->scaler2CbcrEnable;
+
+	writel(*((uint32_t *)&ena), ctrl->vfebase + VFE_MODULE_CFG);
+}
+
+static void vfe_program_dmi_cfg(enum VFE_DMI_RAM_SEL bankSel)
+{
+	/* set bit 8 for auto increment. */
+	uint32_t value = (uint32_t) ctrl->vfebase + VFE_DMI_CFG_DEFAULT;
+
+	value += (uint32_t)bankSel;
+	/* CDBG("dmi cfg input bank is  0x%x\n", bankSel); */
+
+	writel(value, ctrl->vfebase + VFE_DMI_CFG);
+	writel(0, ctrl->vfebase + VFE_DMI_ADDR);
+}
+
+static void vfe_write_lens_roll_off_table(
+	struct vfe_cmd_roll_off_config *in)
+{
+	uint16_t i;
+	uint32_t data;
+
+	uint16_t *initGr = in->initTableGr;
+	uint16_t *initGb = in->initTableGb;
+	uint16_t *initB =  in->initTableB;
+	uint16_t *initR =  in->initTableR;
+
+	int16_t *pDeltaGr = in->deltaTableGr;
+	int16_t *pDeltaGb = in->deltaTableGb;
+	int16_t *pDeltaB =  in->deltaTableB;
+	int16_t *pDeltaR =  in->deltaTableR;
+
+	vfe_program_dmi_cfg(ROLLOFF_RAM);
+
+	/* first pack and write init table */
+	for (i = 0; i < VFE_ROLL_OFF_INIT_TABLE_SIZE; i++) {
+		data = (((uint32_t)(*initR)) & 0x0000FFFF) |
+			(((uint32_t)(*initGr)) << 16);
+		initR++;
+		initGr++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+
+		data = (((uint32_t)(*initB)) & 0x0000FFFF) |
+			(((uint32_t)(*initGr))<<16);
+		initB++;
+		initGb++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+
+	/* there are gaps between the init table and delta table,
+	 * set the offset for delta table. */
+	writel(LENS_ROLL_OFF_DELTA_TABLE_OFFSET,
+		ctrl->vfebase + VFE_DMI_ADDR);
+
+	/* pack and write delta table */
+	for (i = 0; i < VFE_ROLL_OFF_DELTA_TABLE_SIZE; i++) {
+		data = (((int32_t)(*pDeltaR)) & 0x0000FFFF) |
+			(((int32_t)(*pDeltaGr))<<16);
+		pDeltaR++;
+		pDeltaGr++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+
+		data = (((int32_t)(*pDeltaB)) & 0x0000FFFF) |
+			(((int32_t)(*pDeltaGb))<<16);
+		pDeltaB++;
+		pDeltaGb++;
+
+		writel(data, ctrl->vfebase + VFE_DMI_DATA_LO);
+	}
+
+	/* After DMI transfer, to make it safe, need to set the
+	 * DMI_CFG to unselect any SRAM
+	 */
+	/* unselect the SRAM Bank. */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+}
+
+static void vfe_set_default_reg_values(void)
+{
+	writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_0);
+	writel(0x800080, ctrl->vfebase + VFE_DEMUX_GAIN_1);
+	writel(0xFFFFF, ctrl->vfebase + VFE_CGC_OVERRIDE);
+
+	/* default frame drop period and pattern */
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG);
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_CFG);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_ENC_CBCR_PATTERN);
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_CFG);
+	writel(0x1f, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_CFG);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN);
+	writel(0xFFFFFFFF, ctrl->vfebase + VFE_FRAMEDROP_VIEW_CBCR_PATTERN);
+	writel(0, ctrl->vfebase + VFE_CLAMP_MIN_CFG);
+	writel(0xFFFFFF, ctrl->vfebase + VFE_CLAMP_MAX_CFG);
+}
+
+static void vfe_config_demux(uint32_t period, uint32_t even, uint32_t odd)
+{
+	writel(period, ctrl->vfebase + VFE_DEMUX_CFG);
+	writel(even, ctrl->vfebase + VFE_DEMUX_EVEN_CFG);
+	writel(odd, ctrl->vfebase + VFE_DEMUX_ODD_CFG);
+}
+
+static void vfe_pm_stop(void)
+{
+	writel(VFE_PERFORMANCE_MONITOR_STOP, ctrl->vfebase + VFE_BUS_PM_CMD);
+}
+
+static void vfe_program_bus_rd_irq_en(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
+}
+
+static void vfe_camif_go(void)
+{
+	writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
+}
+
+static void vfe_camif_stop_immediately(void)
+{
+	writel(CAMIF_COMMAND_STOP_IMMEDIATELY, ctrl->vfebase + CAMIF_COMMAND);
+	writel(0, ctrl->vfebase + VFE_CGC_OVERRIDE);
+}
+
+static void vfe_program_reg_update_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_REG_UPDATE_CMD);
+}
+
+static void vfe_program_bus_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_BUS_CMD);
+}
+
+static void vfe_program_global_reset_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
+}
+
+static void vfe_program_axi_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_AXI_CMD);
+}
+
+static void vfe_program_irq_composite_mask(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
+}
+
+static inline void vfe_program_irq_mask(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_IRQ_MASK);
+}
+
+static void vfe_program_chroma_upsample_cfg(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
+}
+
+static uint32_t vfe_read_axi_status(void)
+{
+	return readl(ctrl->vfebase + VFE_AXI_STATUS);
+}
+
+static uint32_t vfe_read_pm_status_in_raw_capture(void)
+{
+	return readl(ctrl->vfebase + VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
+}
+
+static void
+vfe_set_stats_pingpong_address(struct vfe_stats_control *afControl,
+	struct vfe_stats_control *awbControl)
+{
+	afControl->hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	afControl->hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+
+	awbControl->hwRegPingAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	awbControl->hwRegPongAddress = (uint8_t *)
+		(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+}
+
+static uint32_t vfe_read_camif_status(void)
+{
+	return readl(ctrl->vfebase + CAMIF_STATUS);
+}
+
+static void vfe_program_lut_bank_sel(struct vfe_gamma_lut_sel *in)
+{
+	struct VFE_GammaLutSelect_ConfigCmdType cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.ch0BankSelect = in->ch0BankSelect;
+	cmd.ch1BankSelect = in->ch1BankSelect;
+	cmd.ch2BankSelect = in->ch2BankSelect;
+	CDBG("VFE gamma lut bank selection is 0x%x\n", *((uint32_t *)&cmd));
+	vfe_prog_hw(ctrl->vfebase + VFE_LUT_BANK_SEL,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+static void vfe_program_stats_cmd(struct vfe_stats_cmd_data *in)
+{
+	struct VFE_StatsCmdType stats;
+	memset(&stats, 0, sizeof(stats));
+
+	stats.autoFocusEnable        = in->autoFocusEnable;
+	stats.axwEnable              = in->axwEnable;
+	stats.histEnable             = in->histEnable;
+	stats.clearHistEnable        = in->clearHistEnable;
+	stats.histAutoClearEnable    = in->histAutoClearEnable;
+	stats.colorConversionEnable  = in->colorConversionEnable;
+
+	writel(*((uint32_t *)&stats), ctrl->vfebase + VFE_STATS_CMD);
+}
+
+static void vfe_pm_start(struct vfe_cmd_bus_pm_start *in)
+{
+	struct VFE_Bus_Pm_ConfigCmdType cmd;
+	memset(&cmd, 0, sizeof(struct VFE_Bus_Pm_ConfigCmdType));
+
+	cmd.output2YWrPmEnable     = in->output2YWrPmEnable;
+	cmd.output2CbcrWrPmEnable  = in->output2CbcrWrPmEnable;
+	cmd.output1YWrPmEnable     = in->output1YWrPmEnable;
+	cmd.output1CbcrWrPmEnable  = in->output1CbcrWrPmEnable;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_PM_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+static void vfe_8k_pm_start(struct vfe_cmd_bus_pm_start *in)
+{
+	in->output1CbcrWrPmEnable = ctrl->vfeBusConfigLocal.viewCbcrWrPathEn;
+	in->output1YWrPmEnable    = ctrl->vfeBusConfigLocal.viewYWrPathEn;
+	in->output2CbcrWrPmEnable = ctrl->vfeBusConfigLocal.encCbcrWrPathEn;
+	in->output2YWrPmEnable    = ctrl->vfeBusConfigLocal.encYWrPathEn;
+
+	if (in->output1CbcrWrPmEnable || in->output1YWrPmEnable)
+		ctrl->viewPath.pmEnabled = TRUE;
+
+	if (in->output2CbcrWrPmEnable || in->output2YWrPmEnable)
+		ctrl->encPath.pmEnabled = TRUE;
+
+	vfe_pm_start(in);
+
+	writel(VFE_PERFORMANCE_MONITOR_GO, ctrl->vfebase + VFE_BUS_PM_CMD);
+}
+
+static uint32_t vfe_irq_pack(struct vfe_interrupt_mask data)
+{
+	struct vfe_irqenable packedData;
+
+	memset(&packedData, 0, sizeof(packedData));
+
+	packedData.camifErrorIrq          = data.camifErrorIrq;
+	packedData.camifSofIrq            = data.camifSofIrq;
+	packedData.camifEolIrq            = data.camifEolIrq;
+	packedData.camifEofIrq            = data.camifEofIrq;
+	packedData.camifEpoch1Irq         = data.camifEpoch1Irq;
+	packedData.camifEpoch2Irq         = data.camifEpoch2Irq;
+	packedData.camifOverflowIrq       = data.camifOverflowIrq;
+	packedData.ceIrq                  = data.ceIrq;
+	packedData.regUpdateIrq           = data.regUpdateIrq;
+	packedData.resetAckIrq            = data.resetAckIrq;
+	packedData.encYPingpongIrq        = data.encYPingpongIrq;
+	packedData.encCbcrPingpongIrq     = data.encCbcrPingpongIrq;
+	packedData.viewYPingpongIrq       = data.viewYPingpongIrq;
+	packedData.viewCbcrPingpongIrq    = data.viewCbcrPingpongIrq;
+	packedData.rdPingpongIrq          = data.rdPingpongIrq;
+	packedData.afPingpongIrq          = data.afPingpongIrq;
+	packedData.awbPingpongIrq         = data.awbPingpongIrq;
+	packedData.histPingpongIrq        = data.histPingpongIrq;
+	packedData.encIrq                 = data.encIrq;
+	packedData.viewIrq                = data.viewIrq;
+	packedData.busOverflowIrq         = data.busOverflowIrq;
+	packedData.afOverflowIrq          = data.afOverflowIrq;
+	packedData.awbOverflowIrq         = data.awbOverflowIrq;
+	packedData.syncTimer0Irq          = data.syncTimer0Irq;
+	packedData.syncTimer1Irq          = data.syncTimer1Irq;
+	packedData.syncTimer2Irq          = data.syncTimer2Irq;
+	packedData.asyncTimer0Irq         = data.asyncTimer0Irq;
+	packedData.asyncTimer1Irq         = data.asyncTimer1Irq;
+	packedData.asyncTimer2Irq         = data.asyncTimer2Irq;
+	packedData.asyncTimer3Irq         = data.asyncTimer3Irq;
+	packedData.axiErrorIrq            = data.axiErrorIrq;
+	packedData.violationIrq           = data.violationIrq;
+
+	return *((uint32_t *)&packedData);
+}
+
+static uint32_t
+vfe_irq_composite_pack(struct vfe_irq_composite_mask_config data)
+{
+	struct VFE_Irq_Composite_MaskType packedData;
+
+	memset(&packedData, 0, sizeof(packedData));
+
+	packedData.encIrqComMaskBits   = data.encIrqComMask;
+	packedData.viewIrqComMaskBits  = data.viewIrqComMask;
+	packedData.ceDoneSelBits       = data.ceDoneSel;
+
+	return *((uint32_t *)&packedData);
+}
+
+static void vfe_addr_convert(struct msm_vfe_phy_info *pinfo,
+	enum vfe_resp_msg type, void *data, void **ext, int32_t *elen)
+{
+	switch (type) {
+	case VFE_MSG_OUTPUT1: {
+		pinfo->y_phy =
+			((struct vfe_message *)data)->_u.msgOutput1.yBuffer;
+		pinfo->cbcr_phy =
+			((struct vfe_message *)data)->_u.msgOutput1.cbcrBuffer;
+
+		((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo =
+		((struct vfe_message *)data)->_u.msgOutput1.bpcInfo;
+
+		((struct vfe_frame_extra *)ctrl->extdata)->asfInfo =
+		((struct vfe_message *)data)->_u.msgOutput1.asfInfo;
+
+		((struct vfe_frame_extra *)ctrl->extdata)->frameCounter =
+		((struct vfe_message *)data)->_u.msgOutput1.frameCounter;
+
+		((struct vfe_frame_extra *)ctrl->extdata)->pmData =
+		((struct vfe_message *)data)->_u.msgOutput1.pmData;
+
+		*ext  = ctrl->extdata;
+		*elen = ctrl->extlen;
+	}
+		break;
+
+	case VFE_MSG_OUTPUT2: {
+		pinfo->y_phy =
+			((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
+		pinfo->cbcr_phy =
+			((struct vfe_message *)data)->_u.msgOutput2.cbcrBuffer;
+
+		CDBG("vfe_addr_convert, pinfo->y_phy = 0x%x\n", pinfo->y_phy);
+		CDBG("vfe_addr_convert, pinfo->cbcr_phy = 0x%x\n",
+			pinfo->cbcr_phy);
+
+		((struct vfe_frame_extra *)ctrl->extdata)->bpcInfo =
+		((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
+
+		((struct vfe_frame_extra *)ctrl->extdata)->asfInfo =
+		((struct vfe_message *)data)->_u.msgOutput2.asfInfo;
+
+		((struct vfe_frame_extra *)ctrl->extdata)->frameCounter =
+		((struct vfe_message *)data)->_u.msgOutput2.frameCounter;
+
+		((struct vfe_frame_extra *)ctrl->extdata)->pmData =
+		((struct vfe_message *)data)->_u.msgOutput2.pmData;
+
+		*ext  = ctrl->extdata;
+		*elen = ctrl->extlen;
+	}
+		break;
+
+	case VFE_MSG_STATS_AF:
+		pinfo->sbuf_phy =
+		((struct vfe_message *)data)->_u.msgStatsAf.afBuffer;
+		break;
+
+	case VFE_MSG_STATS_WE:
+		pinfo->sbuf_phy =
+		((struct vfe_message *)data)->_u.msgStatsWbExp.awbBuffer;
+		break;
+
+	default:
+		break;
+	} /* switch */
+}
+
+static void
+vfe_proc_ops(enum VFE_MESSAGE_ID id, void *msg, size_t len)
+{
+	struct msm_vfe_resp *rp;
+
+	/* In 8k, OUTPUT1 & OUTPUT2 messages arrive before
+	 * SNAPSHOT_DONE. We don't send such messages to user */
+
+	CDBG("ctrl->vfeOperationMode = %d, msgId = %d\n",
+		ctrl->vfeOperationMode, id);
+
+	if ((ctrl->vfeOperationMode == VFE_START_OPERATION_MODE_SNAPSHOT) &&
+		(id == VFE_MSG_ID_OUTPUT1 || id == VFE_MSG_ID_OUTPUT2)) {
+		return;
+	}
+
+	rp = ctrl->resp->vfe_alloc(sizeof(struct msm_vfe_resp), ctrl->syncdata);
+	if (!rp) {
+		CDBG("rp: cannot allocate buffer\n");
+		return;
+	}
+
+	CDBG("vfe_proc_ops, msgId = %d\n", id);
+
+	rp->evt_msg.type   = MSM_CAMERA_MSG;
+	rp->evt_msg.msg_id = id;
+	rp->evt_msg.len    = len;
+	rp->evt_msg.data   = msg;
+
+	switch (rp->evt_msg.msg_id) {
+	case VFE_MSG_ID_SNAPSHOT_DONE:
+		rp->type = VFE_MSG_SNAPSHOT;
+		break;
+
+	case VFE_MSG_ID_OUTPUT1:
+		rp->type = VFE_MSG_OUTPUT1;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT1,
+			rp->evt_msg.data, &(rp->extdata),
+			&(rp->extlen));
+		break;
+
+	case VFE_MSG_ID_OUTPUT2:
+		rp->type = VFE_MSG_OUTPUT2;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_OUTPUT2,
+				rp->evt_msg.data, &(rp->extdata),
+				&(rp->extlen));
+		break;
+
+	case VFE_MSG_ID_STATS_AUTOFOCUS:
+		rp->type = VFE_MSG_STATS_AF;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_AF,
+				rp->evt_msg.data, NULL, NULL);
+		break;
+
+	case VFE_MSG_ID_STATS_WB_EXP:
+		rp->type = VFE_MSG_STATS_WE;
+		vfe_addr_convert(&(rp->phy), VFE_MSG_STATS_WE,
+				rp->evt_msg.data, NULL, NULL);
+		break;
+
+	default:
+		rp->type = VFE_MSG_GENERAL;
+		break;
+	}
+
+	ctrl->resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG, ctrl->syncdata);
+}
+
+static void vfe_send_msg_no_payload(enum VFE_MESSAGE_ID id)
+{
+	struct vfe_message *msg;
+
+	msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	msg->_d = id;
+	vfe_proc_ops(id, msg, 0);
+}
+
+static void vfe_send_bus_overflow_msg(void)
+{
+	struct vfe_message *msg;
+	msg =
+		kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	msg->_d = VFE_MSG_ID_BUS_OVERFLOW;
+#if 0
+	memcpy(&(msg->_u.msgBusOverflow),
+		&ctrl->vfePmData, sizeof(ctrl->vfePmData));
+#endif
+
+	vfe_proc_ops(VFE_MSG_ID_BUS_OVERFLOW,
+		msg, sizeof(struct vfe_message));
+}
+
+static void vfe_send_camif_error_msg(void)
+{
+#if 0
+	struct vfe_message *msg;
+	msg =
+		kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	msg->_d = VFE_MSG_ID_CAMIF_ERROR;
+	memcpy(&(msg->_u.msgCamifError),
+		&ctrl->vfeCamifStatusLocal, sizeof(ctrl->vfeCamifStatusLocal));
+
+	vfe_proc_ops(VFE_MSG_ID_CAMIF_ERROR,
+		msg, sizeof(struct vfe_message));
+#endif
+}
+
+static void vfe_process_error_irq(
+	struct vfe_interrupt_status *irqstatus)
+{
+	/* all possible error irq.  Note error irqs are not enabled, it is
+	 * checked only when other interrupts are present. */
+	if (irqstatus->afOverflowIrq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_AF_OVERFLOW);
+
+	if (irqstatus->awbOverflowIrq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_AWB_OVERFLOW);
+
+	if (irqstatus->axiErrorIrq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_AXI_ERROR);
+
+	if (irqstatus->busOverflowIrq)
+		vfe_send_bus_overflow_msg();
+
+	if (irqstatus->camifErrorIrq)
+		vfe_send_camif_error_msg();
+
+	if (irqstatus->camifOverflowIrq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_CAMIF_OVERFLOW);
+
+	if (irqstatus->violationIrq)
+		;
+}
+
+static void vfe_process_camif_sof_irq(void)
+{
+	/* increment the frame id number. */
+	ctrl->vfeFrameId++;
+
+	CDBG("camif_sof_irq, frameId = %d\n",
+		ctrl->vfeFrameId);
+
+	/* In snapshot mode, if frame skip is programmed,
+	* need to check it accordingly to stop camif at
+	* correct frame boundary. For the dropped frames,
+	* there won't be any output path irqs, but there is
+	* still SOF irq, which can help us determine when
+	* to stop the camif.
+	*/
+	if (ctrl->vfeOperationMode) {
+		if ((1 << ctrl->vfeFrameSkipCount) &
+				ctrl->vfeFrameSkipPattern) {
+
+			ctrl->vfeSnapShotCount--;
+			if (ctrl->vfeSnapShotCount == 0)
+				/* terminate vfe pipeline at frame boundary. */
+				writel(CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY,
+					ctrl->vfebase + CAMIF_COMMAND);
+		}
+
+		/* update frame skip counter for bit checking. */
+		ctrl->vfeFrameSkipCount++;
+		if (ctrl->vfeFrameSkipCount ==
+				(ctrl->vfeFrameSkipPeriod + 1))
+			ctrl->vfeFrameSkipCount = 0;
+	}
+}
+
+static int vfe_get_af_pingpong_status(void)
+{
+	uint32_t busPingPongStatus;
+	int rc = 0;
+
+	busPingPongStatus =
+		readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
+
+	if ((busPingPongStatus & VFE_AF_PINGPONG_STATUS_BIT) == 0)
+		return -EFAULT;
+
+	return rc;
+}
+
+static uint32_t vfe_read_af_buf_addr(boolean pipo)
+{
+	if (pipo == FALSE)
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	else
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+}
+
+static void
+vfe_update_af_buf_addr(boolean pipo, uint32_t addr)
+{
+	if (pipo == FALSE)
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	else
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+}
+
+static void
+vfe_send_af_stats_msg(uint32_t afBufAddress)
+{
+	/* unsigned long flags; */
+	struct vfe_message *msg;
+	msg =
+		kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	if (ctrl->vstate != VFE_STATE_ACTIVE) {
+		kfree(msg);
+		goto af_stats_done;
+	}
+
+	msg->_d = VFE_MSG_ID_STATS_AUTOFOCUS;
+	msg->_u.msgStatsAf.afBuffer = afBufAddress;
+	msg->_u.msgStatsAf.frameCounter = ctrl->vfeFrameId;
+
+	vfe_proc_ops(VFE_MSG_ID_STATS_AUTOFOCUS,
+		msg, sizeof(struct vfe_message));
+
+	ctrl->afStatsControl.ackPending = TRUE;
+
+af_stats_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_process_stats_af_irq(void)
+{
+	boolean bufferAvailable;
+
+	if (!(ctrl->afStatsControl.ackPending)) {
+
+		/* read hardware status. */
+		ctrl->afStatsControl.pingPongStatus =
+			vfe_get_af_pingpong_status();
+
+		bufferAvailable =
+			(ctrl->afStatsControl.pingPongStatus) ^ 1;
+
+		ctrl->afStatsControl.bufToRender =
+			vfe_read_af_buf_addr(bufferAvailable);
+
+		/* update the same buffer address (ping or pong) */
+		vfe_update_af_buf_addr(bufferAvailable,
+			ctrl->afStatsControl.nextFrameAddrBuf);
+
+		vfe_send_af_stats_msg(ctrl->afStatsControl.bufToRender);
+	} else
+		ctrl->afStatsControl.droppedStatsFrameCount++;
+}
+
+static boolean vfe_get_awb_pingpong_status(void)
+{
+	uint32_t busPingPongStatus;
+
+	busPingPongStatus =
+		readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
+
+	if ((busPingPongStatus & VFE_AWB_PINGPONG_STATUS_BIT) == 0)
+		return FALSE;
+
+	return TRUE;
+}
+
+static uint32_t
+vfe_read_awb_buf_addr(boolean pingpong)
+{
+	if (pingpong == FALSE)
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	else
+		return readl(ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+}
+
+static void vfe_update_awb_buf_addr(
+	boolean pingpong, uint32_t addr)
+{
+	if (pingpong == FALSE)
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	else
+		writel(addr, ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+}
+
+static void vfe_send_awb_stats_msg(uint32_t awbBufAddress)
+{
+	/* unsigned long flags; */
+	struct vfe_message   *msg;
+
+	msg =
+		kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	if (ctrl->vstate != VFE_STATE_ACTIVE) {
+		kfree(msg);
+		goto awb_stats_done;
+	}
+
+	msg->_d = VFE_MSG_ID_STATS_WB_EXP;
+	msg->_u.msgStatsWbExp.awbBuffer = awbBufAddress;
+	msg->_u.msgStatsWbExp.frameCounter = ctrl->vfeFrameId;
+
+	vfe_proc_ops(VFE_MSG_ID_STATS_WB_EXP,
+		msg, sizeof(struct vfe_message));
+
+	ctrl->awbStatsControl.ackPending = TRUE;
+
+awb_stats_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_process_stats_awb_irq(void)
+{
+	boolean bufferAvailable;
+
+	if (!(ctrl->awbStatsControl.ackPending)) {
+
+		ctrl->awbStatsControl.pingPongStatus =
+			vfe_get_awb_pingpong_status();
+
+		bufferAvailable = (ctrl->awbStatsControl.pingPongStatus) ^ 1;
+
+		ctrl->awbStatsControl.bufToRender =
+			vfe_read_awb_buf_addr(bufferAvailable);
+
+		vfe_update_awb_buf_addr(bufferAvailable,
+			ctrl->awbStatsControl.nextFrameAddrBuf);
+
+		vfe_send_awb_stats_msg(ctrl->awbStatsControl.bufToRender);
+
+	} else
+		ctrl->awbStatsControl.droppedStatsFrameCount++;
+}
+
+static void vfe_process_sync_timer_irq(
+	struct vfe_interrupt_status *irqstatus)
+{
+	if (irqstatus->syncTimer0Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER0_DONE);
+
+	if (irqstatus->syncTimer1Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER1_DONE);
+
+	if (irqstatus->syncTimer2Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_SYNC_TIMER2_DONE);
+}
+
+static void vfe_process_async_timer_irq(
+	struct vfe_interrupt_status *irqstatus)
+{
+
+	if (irqstatus->asyncTimer0Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE);
+
+	if (irqstatus->asyncTimer1Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER1_DONE);
+
+	if (irqstatus->asyncTimer2Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER2_DONE);
+
+	if (irqstatus->asyncTimer3Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER3_DONE);
+}
+
+static void vfe_send_violation_msg(void)
+{
+	vfe_send_msg_no_payload(VFE_MSG_ID_VIOLATION);
+}
+
+static void vfe_send_async_timer_msg(void)
+{
+	vfe_send_msg_no_payload(VFE_MSG_ID_ASYNC_TIMER0_DONE);
+}
+
+static void vfe_write_gamma_table(uint8_t channel,
+	boolean bank, int16_t *pTable)
+{
+	uint16_t i;
+
+	enum VFE_DMI_RAM_SEL dmiRamSel = NO_MEM_SELECTED;
+
+	switch (channel) {
+	case 0:
+		if (bank == 0)
+			dmiRamSel = RGBLUT_RAM_CH0_BANK0;
+		else
+			dmiRamSel = RGBLUT_RAM_CH0_BANK1;
+		break;
+
+	case 1:
+		if (bank == 0)
+			dmiRamSel = RGBLUT_RAM_CH1_BANK0;
+		else
+			dmiRamSel = RGBLUT_RAM_CH1_BANK1;
+		break;
+
+	case 2:
+		if (bank == 0)
+			dmiRamSel = RGBLUT_RAM_CH2_BANK0;
+		else
+			dmiRamSel = RGBLUT_RAM_CH2_BANK1;
+		break;
+
+	default:
+		break;
+	}
+
+	vfe_program_dmi_cfg(dmiRamSel);
+
+	for (i = 0; i < VFE_GAMMA_TABLE_LENGTH; i++) {
+		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
+		pTable++;
+	}
+
+	/* After DMI transfer, need to set the DMI_CFG to unselect any SRAM
+	unselect the SRAM Bank. */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+}
+
+static void vfe_prog_hw_testgen_cmd(uint32_t value)
+{
+	writel(value, ctrl->vfebase + VFE_HW_TESTGEN_CMD);
+}
+
+static inline void vfe_read_irq_status(struct vfe_irq_thread_msg *out)
+{
+	uint32_t *temp;
+
+	memset(out, 0, sizeof(struct vfe_irq_thread_msg));
+
+	temp = (uint32_t *)(ctrl->vfebase + VFE_IRQ_STATUS);
+	out->vfeIrqStatus = readl(temp);
+
+	temp = (uint32_t *)(ctrl->vfebase + CAMIF_STATUS);
+	out->camifStatus = readl(temp);
+	writel(0x7, ctrl->vfebase + CAMIF_COMMAND);
+	writel(0x3, ctrl->vfebase + CAMIF_COMMAND);
+	CDBG("camifStatus  = 0x%x\n", out->camifStatus);
+
+/*
+	temp = (uint32_t *)(ctrl->vfebase + VFE_DEMOSAIC_STATUS);
+	out->demosaicStatus = readl(temp);
+
+	temp = (uint32_t *)(ctrl->vfebase + VFE_ASF_MAX_EDGE);
+	out->asfMaxEdge = readl(temp);
+
+	temp = (uint32_t *)(ctrl->vfebase + VFE_BUS_ENC_Y_WR_PM_STATS_0);
+*/
+
+#if 0
+	out->pmInfo.encPathPmInfo.yWrPmStats0      = readl(temp++);
+	out->pmInfo.encPathPmInfo.yWrPmStats1      = readl(temp++);
+	out->pmInfo.encPathPmInfo.cbcrWrPmStats0   = readl(temp++);
+	out->pmInfo.encPathPmInfo.cbcrWrPmStats1   = readl(temp++);
+	out->pmInfo.viewPathPmInfo.yWrPmStats0     = readl(temp++);
+	out->pmInfo.viewPathPmInfo.yWrPmStats1     = readl(temp++);
+	out->pmInfo.viewPathPmInfo.cbcrWrPmStats0  = readl(temp++);
+	out->pmInfo.viewPathPmInfo.cbcrWrPmStats1  = readl(temp);
+#endif /* if 0 Jeff */
+}
+
+static struct vfe_interrupt_status
+vfe_parse_interrupt_status(uint32_t irqStatusIn)
+{
+	struct vfe_irqenable hwstat;
+	struct vfe_interrupt_status ret;
+	boolean temp;
+
+	memset(&hwstat, 0, sizeof(hwstat));
+	memset(&ret, 0, sizeof(ret));
+
+	hwstat = *((struct vfe_irqenable *)(&irqStatusIn));
+
+	ret.camifErrorIrq       = hwstat.camifErrorIrq;
+	ret.camifSofIrq         = hwstat.camifSofIrq;
+	ret.camifEolIrq         = hwstat.camifEolIrq;
+	ret.camifEofIrq         = hwstat.camifEofIrq;
+	ret.camifEpoch1Irq      = hwstat.camifEpoch1Irq;
+	ret.camifEpoch2Irq      = hwstat.camifEpoch2Irq;
+	ret.camifOverflowIrq    = hwstat.camifOverflowIrq;
+	ret.ceIrq               = hwstat.ceIrq;
+	ret.regUpdateIrq        = hwstat.regUpdateIrq;
+	ret.resetAckIrq         = hwstat.resetAckIrq;
+	ret.encYPingpongIrq     = hwstat.encYPingpongIrq;
+	ret.encCbcrPingpongIrq  = hwstat.encCbcrPingpongIrq;
+	ret.viewYPingpongIrq    = hwstat.viewYPingpongIrq;
+	ret.viewCbcrPingpongIrq = hwstat.viewCbcrPingpongIrq;
+	ret.rdPingpongIrq       = hwstat.rdPingpongIrq;
+	ret.afPingpongIrq       = hwstat.afPingpongIrq;
+	ret.awbPingpongIrq      = hwstat.awbPingpongIrq;
+	ret.histPingpongIrq     = hwstat.histPingpongIrq;
+	ret.encIrq              = hwstat.encIrq;
+	ret.viewIrq             = hwstat.viewIrq;
+	ret.busOverflowIrq      = hwstat.busOverflowIrq;
+	ret.afOverflowIrq       = hwstat.afOverflowIrq;
+	ret.awbOverflowIrq      = hwstat.awbOverflowIrq;
+	ret.syncTimer0Irq       = hwstat.syncTimer0Irq;
+	ret.syncTimer1Irq       = hwstat.syncTimer1Irq;
+	ret.syncTimer2Irq       = hwstat.syncTimer2Irq;
+	ret.asyncTimer0Irq      = hwstat.asyncTimer0Irq;
+	ret.asyncTimer1Irq      = hwstat.asyncTimer1Irq;
+	ret.asyncTimer2Irq      = hwstat.asyncTimer2Irq;
+	ret.asyncTimer3Irq      = hwstat.asyncTimer3Irq;
+	ret.axiErrorIrq         = hwstat.axiErrorIrq;
+	ret.violationIrq        = hwstat.violationIrq;
+
+	/* logic OR of any error bits
+	 * although each irq corresponds to a bit, the data type here is a
+	 * boolean already. hence use logic operation.
+	 */
+	temp =
+		ret.camifErrorIrq    ||
+		ret.camifOverflowIrq ||
+		ret.afOverflowIrq    ||
+		ret.awbPingpongIrq   ||
+		ret.busOverflowIrq   ||
+		ret.axiErrorIrq      ||
+		ret.violationIrq;
+
+	ret.anyErrorIrqs = temp;
+
+	/* logic OR of any output path bits*/
+	temp =
+		ret.encYPingpongIrq    ||
+		ret.encCbcrPingpongIrq ||
+		ret.encIrq;
+
+	ret.anyOutput2PathIrqs = temp;
+
+	temp =
+		ret.viewYPingpongIrq    ||
+		ret.viewCbcrPingpongIrq ||
+		ret.viewIrq;
+
+	ret.anyOutput1PathIrqs = temp;
+
+	ret.anyOutputPathIrqs =
+		ret.anyOutput1PathIrqs ||
+		ret.anyOutput2PathIrqs;
+
+	/* logic OR of any sync timer bits*/
+	temp =
+		ret.syncTimer0Irq ||
+		ret.syncTimer1Irq ||
+		ret.syncTimer2Irq;
+
+	ret.anySyncTimerIrqs = temp;
+
+	/* logic OR of any async timer bits*/
+	temp =
+		ret.asyncTimer0Irq ||
+		ret.asyncTimer1Irq ||
+		ret.asyncTimer2Irq ||
+		ret.asyncTimer3Irq;
+
+	ret.anyAsyncTimerIrqs = temp;
+
+	/* bool for all interrupts that are not allowed in idle state */
+	temp =
+		ret.anyErrorIrqs      ||
+		ret.anyOutputPathIrqs ||
+		ret.anySyncTimerIrqs  ||
+		ret.regUpdateIrq      ||
+		ret.awbPingpongIrq    ||
+		ret.afPingpongIrq     ||
+		ret.camifSofIrq       ||
+		ret.camifEpoch2Irq    ||
+		ret.camifEpoch1Irq;
+
+	ret.anyIrqForActiveStatesOnly =
+		temp;
+
+	return ret;
+}
+
+static struct vfe_frame_asf_info
+vfe_get_asf_frame_info(struct vfe_irq_thread_msg *in)
+{
+	struct vfe_asf_info     asfInfoTemp;
+	struct vfe_frame_asf_info rc;
+
+	memset(&rc, 0, sizeof(rc));
+	memset(&asfInfoTemp, 0, sizeof(asfInfoTemp));
+
+	asfInfoTemp =
+		*((struct vfe_asf_info *)(&(in->asfMaxEdge)));
+
+	rc.asfHbiCount = asfInfoTemp.HBICount;
+	rc.asfMaxEdge  = asfInfoTemp.maxEdge;
+
+	return rc;
+}
+
+static struct vfe_frame_bpc_info
+vfe_get_demosaic_frame_info(struct vfe_irq_thread_msg *in)
+{
+	struct vfe_bps_info     bpcInfoTemp;
+	struct vfe_frame_bpc_info rc;
+
+	memset(&rc, 0, sizeof(rc));
+	memset(&bpcInfoTemp, 0, sizeof(bpcInfoTemp));
+
+	bpcInfoTemp =
+		*((struct vfe_bps_info *)(&(in->demosaicStatus)));
+
+	rc.greenDefectPixelCount    =
+		bpcInfoTemp.greenBadPixelCount;
+
+	rc.redBlueDefectPixelCount  =
+		bpcInfoTemp.RedBlueBadPixelCount;
+
+	return rc;
+}
+
+static struct vfe_msg_camif_status
+vfe_get_camif_status(struct vfe_irq_thread_msg *in)
+{
+	struct vfe_camif_stats camifStatusTemp;
+	struct vfe_msg_camif_status rc;
+
+	memset(&rc, 0, sizeof(rc));
+	memset(&camifStatusTemp, 0, sizeof(camifStatusTemp));
+
+	camifStatusTemp =
+		*((struct vfe_camif_stats *)(&(in->camifStatus)));
+
+	rc.camifState = (boolean)camifStatusTemp.camifHalt;
+	rc.lineCount  = camifStatusTemp.lineCount;
+	rc.pixelCount = camifStatusTemp.pixelCount;
+
+	return rc;
+}
+
+static struct vfe_bus_performance_monitor
+vfe_get_performance_monitor_data(struct vfe_irq_thread_msg *in)
+{
+	struct vfe_bus_performance_monitor rc;
+	memset(&rc, 0, sizeof(rc));
+
+	rc.encPathPmInfo.yWrPmStats0     =
+		in->pmInfo.encPathPmInfo.yWrPmStats0;
+	rc.encPathPmInfo.yWrPmStats1     =
+		in->pmInfo.encPathPmInfo.yWrPmStats1;
+	rc.encPathPmInfo.cbcrWrPmStats0  =
+		in->pmInfo.encPathPmInfo.cbcrWrPmStats0;
+	rc.encPathPmInfo.cbcrWrPmStats1  =
+		in->pmInfo.encPathPmInfo.cbcrWrPmStats1;
+	rc.viewPathPmInfo.yWrPmStats0    =
+		in->pmInfo.viewPathPmInfo.yWrPmStats0;
+	rc.viewPathPmInfo.yWrPmStats1    =
+		in->pmInfo.viewPathPmInfo.yWrPmStats1;
+	rc.viewPathPmInfo.cbcrWrPmStats0 =
+		in->pmInfo.viewPathPmInfo.cbcrWrPmStats0;
+	rc.viewPathPmInfo.cbcrWrPmStats1 =
+		in->pmInfo.viewPathPmInfo.cbcrWrPmStats1;
+
+	return rc;
+}
+
+static void vfe_process_reg_update_irq(void)
+{
+	CDBG("vfe_process_reg_update_irq: ackPendingFlag is %d\n",
+	ctrl->vfeStartAckPendingFlag);
+	if (ctrl->vfeStartAckPendingFlag == TRUE) {
+		vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK);
+		ctrl->vfeStartAckPendingFlag = FALSE;
+	} else
+		vfe_send_msg_no_payload(VFE_MSG_ID_UPDATE_ACK);
+}
+
+static void vfe_process_reset_irq(void)
+{
+	/* unsigned long flags; */
+
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	ctrl->vstate = VFE_STATE_IDLE;
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+
+	if (ctrl->vfeStopAckPending == TRUE) {
+		ctrl->vfeStopAckPending = FALSE;
+		vfe_send_msg_no_payload(VFE_MSG_ID_STOP_ACK);
+	} else {
+		vfe_set_default_reg_values();
+		vfe_send_msg_no_payload(VFE_MSG_ID_RESET_ACK);
+	}
+}
+
+static void vfe_process_pingpong_irq(struct vfe_output_path *in,
+	uint8_t fragmentCount)
+{
+	uint16_t circularIndex;
+	uint32_t nextFragmentAddr;
+
+	/* get next fragment address from circular buffer */
+	circularIndex    = (in->fragIndex) % (2 * fragmentCount);
+	nextFragmentAddr = in->addressBuffer[circularIndex];
+
+	in->fragIndex = circularIndex + 1;
+
+	/* use next fragment to program hardware ping/pong address. */
+	if (in->hwCurrentFlag == ping) {
+		writel(nextFragmentAddr, in->hwRegPingAddress);
+		in->hwCurrentFlag = pong;
+
+	} else {
+		writel(nextFragmentAddr, in->hwRegPongAddress);
+		in->hwCurrentFlag = ping;
+	}
+}
+
+static void vfe_send_output2_msg(
+	struct vfe_msg_output *pPayload)
+{
+	/* unsigned long flags; */
+	struct vfe_message *msg;
+
+	msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	/* fill message with right content. */
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	if (ctrl->vstate != VFE_STATE_ACTIVE) {
+		kfree(msg);
+		goto output2_msg_done;
+	}
+
+	msg->_d = VFE_MSG_ID_OUTPUT2;
+
+	memcpy(&(msg->_u.msgOutput2),
+		(void *)pPayload, sizeof(struct vfe_msg_output));
+
+	vfe_proc_ops(VFE_MSG_ID_OUTPUT2,
+		msg, sizeof(struct vfe_message));
+
+	ctrl->encPath.ackPending = TRUE;
+
+	if (!(ctrl->vfeRequestedSnapShotCount <= 3) &&
+			(ctrl->vfeOperationMode ==
+			 VFE_START_OPERATION_MODE_SNAPSHOT))
+		ctrl->encPath.ackPending = TRUE;
+
+output2_msg_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_send_output1_msg(
+	struct vfe_msg_output *pPayload)
+{
+	/* unsigned long flags; */
+	struct vfe_message *msg;
+
+	msg = kzalloc(sizeof(struct vfe_message), GFP_ATOMIC);
+	if (!msg)
+		return;
+
+	/* @todo This is causing issues, need further investigate */
+	/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+	if (ctrl->vstate != VFE_STATE_ACTIVE) {
+		kfree(msg);
+		goto output1_msg_done;
+	}
+
+	msg->_d = VFE_MSG_ID_OUTPUT1;
+	memmove(&(msg->_u),
+		(void *)pPayload, sizeof(struct vfe_msg_output));
+
+	vfe_proc_ops(VFE_MSG_ID_OUTPUT1,
+		msg, sizeof(struct vfe_message));
+
+	ctrl->viewPath.ackPending = TRUE;
+
+	if (!(ctrl->vfeRequestedSnapShotCount <= 3) &&
+			(ctrl->vfeOperationMode ==
+			 VFE_START_OPERATION_MODE_SNAPSHOT))
+		ctrl->viewPath.ackPending = TRUE;
+
+output1_msg_done:
+	/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+	return;
+}
+
+static void vfe_send_output_msg(boolean whichOutputPath,
+	uint32_t yPathAddr, uint32_t cbcrPathAddr)
+{
+	struct vfe_msg_output msgPayload;
+
+	msgPayload.yBuffer = yPathAddr;
+	msgPayload.cbcrBuffer = cbcrPathAddr;
+
+	/* asf info is common for both output1 and output2 */
+#if 0
+	msgPayload.asfInfo.asfHbiCount = ctrl->vfeAsfFrameInfo.asfHbiCount;
+	msgPayload.asfInfo.asfMaxEdge = ctrl->vfeAsfFrameInfo.asfMaxEdge;
+
+	/* demosaic info is common for both output1 and output2 */
+	msgPayload.bpcInfo.greenDefectPixelCount =
+		ctrl->vfeBpcFrameInfo.greenDefectPixelCount;
+	msgPayload.bpcInfo.redBlueDefectPixelCount =
+		ctrl->vfeBpcFrameInfo.redBlueDefectPixelCount;
+#endif /* if 0 */
+
+	/* frame ID is common for both paths. */
+	msgPayload.frameCounter = ctrl->vfeFrameId;
+
+	if (whichOutputPath) {
+		/* msgPayload.pmData = ctrl->vfePmData.encPathPmInfo; */
+		vfe_send_output2_msg(&msgPayload);
+	} else {
+		/* msgPayload.pmData = ctrl->vfePmData.viewPathPmInfo; */
+		vfe_send_output1_msg(&msgPayload);
+	}
+}
+
+static void vfe_process_frame_done_irq_multi_frag(
+	struct vfe_output_path_combo *in)
+{
+	uint32_t yAddress, cbcrAddress;
+	uint16_t idx;
+	uint32_t *ptrY;
+	uint32_t *ptrCbcr;
+	const uint32_t *ptrSrc;
+	uint8_t i;
+
+	if (!in->ackPending) {
+
+		idx = (in->currentFrame) * (in->fragCount);
+
+		/* Send output message. */
+		yAddress = in->yPath.addressBuffer[idx];
+		cbcrAddress = in->cbcrPath.addressBuffer[idx];
+
+		/* copy next frame to current frame. */
+		ptrSrc  = in->nextFrameAddrBuf;
+		ptrY    = (uint32_t *)&(in->yPath.addressBuffer[idx]);
+		ptrCbcr = (uint32_t *)&(in->cbcrPath.addressBuffer[idx]);
+
+		/* Copy Y address */
+		for (i = 0; i < in->fragCount; i++)
+			*ptrY++ = *ptrSrc++;
+
+		/* Copy Cbcr address */
+		for (i = 0; i < in->fragCount; i++)
+			*ptrCbcr++ = *ptrSrc++;
+
+		vfe_send_output_msg(in->whichOutputPath, yAddress, cbcrAddress);
+
+	} else {
+		if (in->whichOutputPath == 0)
+			ctrl->vfeDroppedFrameCounts.output1Count++;
+
+		if (in->whichOutputPath == 1)
+			ctrl->vfeDroppedFrameCounts.output2Count++;
+	}
+
+	/* toggle current frame. */
+	in->currentFrame = in->currentFrame^1;
+
+	if (ctrl->vfeOperationMode)
+		in->snapshotPendingCount--;
+}
+
+static void vfe_process_frame_done_irq_no_frag_io(
+	struct vfe_output_path_combo *in, uint32_t *pNextAddr,
+	uint32_t *pdestRenderAddr)
+{
+	uint32_t busPingPongStatus;
+	uint32_t tempAddress;
+
+	/* 1. read hw status register. */
+	busPingPongStatus =
+		readl(ctrl->vfebase + VFE_BUS_PINGPONG_STATUS);
+
+	CDBG("hardware status is 0x%x\n", busPingPongStatus);
+
+	/* 2. determine ping or pong */
+	/* use cbcr status */
+	busPingPongStatus = busPingPongStatus & (1<<(in->cbcrStatusBit));
+
+	/* 3. read out address and update address */
+	if (busPingPongStatus == 0) {
+		/* hw is working on ping, render pong buffer */
+		/* a. read out pong address */
+		/* read out y address. */
+		tempAddress = readl(in->yPath.hwRegPongAddress);
+
+		CDBG("pong 1 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr++ = tempAddress;
+		/* read out cbcr address. */
+		tempAddress = readl(in->cbcrPath.hwRegPongAddress);
+
+		CDBG("pong 2 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr = tempAddress;
+
+		/* b. update pong address */
+		writel(*pNextAddr++, in->yPath.hwRegPongAddress);
+		writel(*pNextAddr, in->cbcrPath.hwRegPongAddress);
+	} else {
+		/* hw is working on pong, render ping buffer */
+
+		/* a. read out ping address */
+		tempAddress = readl(in->yPath.hwRegPingAddress);
+		CDBG("ping 1 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr++ = tempAddress;
+		tempAddress = readl(in->cbcrPath.hwRegPingAddress);
+
+		CDBG("ping 2 addr = 0x%x\n", tempAddress);
+		*pdestRenderAddr = tempAddress;
+
+		/* b. update ping address */
+		writel(*pNextAddr++, in->yPath.hwRegPingAddress);
+		CDBG("NextAddress = 0x%x\n", *pNextAddr);
+		writel(*pNextAddr, in->cbcrPath.hwRegPingAddress);
+	}
+}
+
+static void vfe_process_frame_done_irq_no_frag(
+	struct vfe_output_path_combo *in)
+{
+	uint32_t addressToRender[2];
+	static uint32_t fcnt;
+
+	if (fcnt++ < 3)
+		return;
+
+	if (!in->ackPending) {
+		vfe_process_frame_done_irq_no_frag_io(in,
+			in->nextFrameAddrBuf, addressToRender);
+
+		/* use addressToRender to send out message. */
+		vfe_send_output_msg(in->whichOutputPath,
+				addressToRender[0], addressToRender[1]);
+
+	} else {
+		/* ackPending is still there, accumulate dropped frame count.
+		 * These count can be read through ioctrl command. */
+		CDBG("waiting frame ACK\n");
+
+		if (in->whichOutputPath == 0)
+			ctrl->vfeDroppedFrameCounts.output1Count++;
+
+		if (in->whichOutputPath == 1)
+			ctrl->vfeDroppedFrameCounts.output2Count++;
+	}
+
+	/* in case of multishot when upper layer did not ack, there will still
+	 * be a snapshot done msg sent out, even though the number of frames
+	 * sent out may be less than the desired number of frames.  snapshot
+	 * done msg would be helpful to indicate that vfe pipeline has stop,
+	 * and in good known state.
+	 */
+	if (ctrl->vfeOperationMode)
+		in->snapshotPendingCount--;
+}
+
+static void vfe_process_output_path_irq(
+	struct vfe_interrupt_status *irqstatus)
+{
+	/* unsigned long flags; */
+
+	/* process the view path interrupts */
+	if (irqstatus->anyOutput1PathIrqs) {
+		if (ctrl->viewPath.multiFrag) {
+
+			if (irqstatus->viewCbcrPingpongIrq)
+				vfe_process_pingpong_irq(
+					&(ctrl->viewPath.cbcrPath),
+					ctrl->viewPath.fragCount);
+
+			if (irqstatus->viewYPingpongIrq)
+				vfe_process_pingpong_irq(
+					&(ctrl->viewPath.yPath),
+					ctrl->viewPath.fragCount);
+
+			if (irqstatus->viewIrq)
+				vfe_process_frame_done_irq_multi_frag(
+					&ctrl->viewPath);
+
+		} else {
+			/* typical case for no fragment,
+			 only frame done irq is enabled. */
+			if (irqstatus->viewIrq)
+				vfe_process_frame_done_irq_no_frag(
+					&ctrl->viewPath);
+		}
+	}
+
+	/* process the encoder path interrupts */
+	if (irqstatus->anyOutput2PathIrqs) {
+		if (ctrl->encPath.multiFrag) {
+			if (irqstatus->encCbcrPingpongIrq)
+				vfe_process_pingpong_irq(
+					&(ctrl->encPath.cbcrPath),
+					ctrl->encPath.fragCount);
+
+			if (irqstatus->encYPingpongIrq)
+				vfe_process_pingpong_irq(&(ctrl->encPath.yPath),
+				ctrl->encPath.fragCount);
+
+			if (irqstatus->encIrq)
+				vfe_process_frame_done_irq_multi_frag(
+					&ctrl->encPath);
+
+		} else {
+			if (irqstatus->encIrq)
+				vfe_process_frame_done_irq_no_frag(
+					&ctrl->encPath);
+		}
+	}
+
+	if (ctrl->vfeOperationMode) {
+		if ((ctrl->encPath.snapshotPendingCount == 0) &&
+				(ctrl->viewPath.snapshotPendingCount == 0)) {
+
+			/* @todo This is causing issues, further investigate */
+			/* spin_lock_irqsave(&ctrl->state_lock, flags); */
+			ctrl->vstate = VFE_STATE_IDLE;
+			/* spin_unlock_irqrestore(&ctrl->state_lock, flags); */
+
+			vfe_send_msg_no_payload(VFE_MSG_ID_SNAPSHOT_DONE);
+			vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
+			vfe_pm_stop();
+		}
+	}
+}
+
+static void vfe_do_tasklet(unsigned long data)
+{
+	unsigned long flags;
+
+	struct isr_queue_cmd *qcmd = NULL;
+
+	CDBG("=== vfe_do_tasklet start === \n");
+
+	spin_lock_irqsave(&ctrl->tasklet_lock, flags);
+	qcmd = list_first_entry(&ctrl->tasklet_q,
+			struct isr_queue_cmd, list);
+
+	if (!qcmd) {
+		spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
+		return;
+	}
+
+	list_del(&qcmd->list);
+	spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
+
+	if (qcmd->vfeInterruptStatus.regUpdateIrq) {
+		CDBG("irq	regUpdateIrq\n");
+		vfe_process_reg_update_irq();
+	}
+
+	if (qcmd->vfeInterruptStatus.resetAckIrq) {
+		CDBG("irq	resetAckIrq\n");
+		vfe_process_reset_irq();
+	}
+
+	spin_lock_irqsave(&ctrl->state_lock, flags);
+	if (ctrl->vstate != VFE_STATE_ACTIVE) {
+		spin_unlock_irqrestore(&ctrl->state_lock, flags);
+		return;
+	}
+	spin_unlock_irqrestore(&ctrl->state_lock, flags);
+
+#if 0
+	if (qcmd->vfeInterruptStatus.camifEpoch1Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH1);
+
+	if (qcmd->vfeInterruptStatus.camifEpoch2Irq)
+		vfe_send_msg_no_payload(VFE_MSG_ID_EPOCH2);
+#endif /* Jeff */
+
+	/* next, check output path related interrupts. */
+	if (qcmd->vfeInterruptStatus.anyOutputPathIrqs) {
+		CDBG("irq	anyOutputPathIrqs\n");
+		vfe_process_output_path_irq(&qcmd->vfeInterruptStatus);
+	}
+
+	if (qcmd->vfeInterruptStatus.afPingpongIrq)
+		vfe_process_stats_af_irq();
+
+	if (qcmd->vfeInterruptStatus.awbPingpongIrq)
+		vfe_process_stats_awb_irq();
+
+	/* any error irqs*/
+	if (qcmd->vfeInterruptStatus.anyErrorIrqs)
+		vfe_process_error_irq(&qcmd->vfeInterruptStatus);
+
+#if 0
+	if (qcmd->vfeInterruptStatus.anySyncTimerIrqs)
+		vfe_process_sync_timer_irq();
+
+	if (qcmd->vfeInterruptStatus.anyAsyncTimerIrqs)
+		vfe_process_async_timer_irq();
+#endif /* Jeff */
+
+	if (qcmd->vfeInterruptStatus.camifSofIrq) {
+		CDBG("irq	camifSofIrq\n");
+		vfe_process_camif_sof_irq();
+	}
+
+	kfree(qcmd);
+	CDBG("=== vfe_do_tasklet end === \n");
+}
+
+DECLARE_TASKLET(vfe_tasklet, vfe_do_tasklet, 0);
+
+static irqreturn_t vfe_parse_irq(int irq_num, void *data)
+{
+	unsigned long flags;
+	uint32_t irqStatusLocal;
+	struct vfe_irq_thread_msg irq;
+	struct isr_queue_cmd *qcmd;
+
+	CDBG("vfe_parse_irq\n");
+
+	vfe_read_irq_status(&irq);
+
+	if (irq.vfeIrqStatus == 0) {
+		CDBG("vfe_parse_irq: irq.vfeIrqStatus is 0\n");
+		return IRQ_HANDLED;
+	}
+
+	qcmd = kzalloc(sizeof(struct isr_queue_cmd),
+		GFP_ATOMIC);
+	if (!qcmd) {
+		CDBG("vfe_parse_irq: qcmd malloc failed!\n");
+		return IRQ_HANDLED;
+	}
+
+	spin_lock_irqsave(&ctrl->ack_lock, flags);
+
+	if (ctrl->vfeStopAckPending)
+		irqStatusLocal =
+			(VFE_IMASK_WHILE_STOPPING & irq.vfeIrqStatus);
+	else
+		irqStatusLocal =
+			((ctrl->vfeImaskPacked | VFE_IMASK_ERROR_ONLY) &
+				irq.vfeIrqStatus);
+
+	spin_unlock_irqrestore(&ctrl->ack_lock, flags);
+
+	/* first parse the interrupt status to local data structures. */
+	qcmd->vfeInterruptStatus = vfe_parse_interrupt_status(irqStatusLocal);
+	qcmd->vfeAsfFrameInfo = vfe_get_asf_frame_info(&irq);
+	qcmd->vfeBpcFrameInfo = vfe_get_demosaic_frame_info(&irq);
+	qcmd->vfeCamifStatusLocal = vfe_get_camif_status(&irq);
+	qcmd->vfePmData = vfe_get_performance_monitor_data(&irq);
+
+	spin_lock_irqsave(&ctrl->tasklet_lock, flags);
+	list_add_tail(&qcmd->list, &ctrl->tasklet_q);
+	spin_unlock_irqrestore(&ctrl->tasklet_lock, flags);
+	tasklet_schedule(&vfe_tasklet);
+
+	/* clear the pending interrupt of the same kind.*/
+	writel(irq.vfeIrqStatus, ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	return IRQ_HANDLED;
+}
+
+int vfe_cmd_init(struct msm_vfe_callback *presp,
+	struct platform_device *pdev, void *sdata)
+{
+	struct resource	*vfemem, *vfeirq, *vfeio;
+	int rc;
+
+	vfemem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!vfemem) {
+		CDBG("no mem resource?\n");
+		return -ENODEV;
+	}
+
+	vfeirq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!vfeirq) {
+		CDBG("no irq resource?\n");
+		return -ENODEV;
+	}
+
+	vfeio = request_mem_region(vfemem->start,
+		resource_size(vfemem), pdev->name);
+	if (!vfeio) {
+		CDBG("VFE region already claimed\n");
+		return -EBUSY;
+	}
+
+	ctrl =
+	kzalloc(sizeof(struct msm_vfe8x_ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		rc = -ENOMEM;
+		goto cmd_init_failed1;
+	}
+
+	ctrl->vfeirq  = vfeirq->start;
+
+	ctrl->vfebase =
+		ioremap(vfemem->start, (vfemem->end - vfemem->start) + 1);
+	if (!ctrl->vfebase) {
+		rc = -ENOMEM;
+		goto cmd_init_failed2;
+	}
+
+	rc = request_irq(ctrl->vfeirq, vfe_parse_irq,
+		IRQF_TRIGGER_RISING, "vfe", 0);
+	if (rc < 0)
+		goto cmd_init_failed2;
+
+	if (presp && presp->vfe_resp)
+		ctrl->resp = presp;
+	else {
+		rc = -EINVAL;
+		goto cmd_init_failed3;
+	}
+
+	ctrl->extdata =
+		kmalloc(sizeof(struct vfe_frame_extra), GFP_KERNEL);
+	if (!ctrl->extdata) {
+		rc = -ENOMEM;
+		goto cmd_init_failed3;
+	}
+
+	spin_lock_init(&ctrl->ack_lock);
+	spin_lock_init(&ctrl->state_lock);
+	spin_lock_init(&ctrl->io_lock);
+
+	ctrl->extlen = sizeof(struct vfe_frame_extra);
+
+	spin_lock_init(&ctrl->tasklet_lock);
+	INIT_LIST_HEAD(&ctrl->tasklet_q);
+
+	ctrl->syncdata = sdata;
+	return 0;
+
+cmd_init_failed3:
+	disable_irq(ctrl->vfeirq);
+	free_irq(ctrl->vfeirq, 0);
+	iounmap(ctrl->vfebase);
+cmd_init_failed2:
+	kfree(ctrl);
+cmd_init_failed1:
+	release_mem_region(vfemem->start, (vfemem->end - vfemem->start) + 1);
+	return rc;
+}
+
+void vfe_cmd_release(struct platform_device *dev)
+{
+	struct resource	*mem;
+
+	disable_irq(ctrl->vfeirq);
+	free_irq(ctrl->vfeirq, 0);
+
+	iounmap(ctrl->vfebase);
+	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	release_mem_region(mem->start, (mem->end - mem->start) + 1);
+
+	ctrl->extlen = 0;
+
+	kfree(ctrl->extdata);
+	kfree(ctrl);
+}
+
+void vfe_stats_af_stop(void)
+{
+	ctrl->vfeStatsCmdLocal.autoFocusEnable = FALSE;
+	ctrl->vfeImaskLocal.afPingpongIrq = FALSE;
+}
+
+void vfe_stop(void)
+{
+	boolean vfeAxiBusy;
+	uint32_t vfeAxiStauts;
+
+	/* for reset hw modules, and send msg when reset_irq comes.*/
+	ctrl->vfeStopAckPending = TRUE;
+
+	ctrl->vfeStatsPingPongReloadFlag = FALSE;
+	vfe_pm_stop();
+
+	/* disable all interrupts.  */
+	vfe_program_irq_mask(VFE_DISABLE_ALL_IRQS);
+
+	/* in either continuous or snapshot mode, stop command can be issued
+	 * at any time.
+	 */
+	vfe_camif_stop_immediately();
+	vfe_program_axi_cmd(AXI_HALT);
+	vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_STOP);
+
+	vfeAxiBusy = TRUE;
+
+	while (vfeAxiBusy) {
+		vfeAxiStauts = vfe_read_axi_status();
+		if ((vfeAxiStauts & AXI_STATUS_BUSY_MASK) != 0)
+			vfeAxiBusy = FALSE;
+	}
+
+	vfe_program_axi_cmd(AXI_HALT_CLEAR);
+
+	/* clear all pending interrupts */
+	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	/* enable reset_ack and async timer interrupt only while stopping
+	 * the pipeline.
+	 */
+	vfe_program_irq_mask(VFE_IMASK_WHILE_STOPPING);
+
+	vfe_program_global_reset_cmd(VFE_RESET_UPON_STOP_CMD);
+}
+
+void vfe_update(void)
+{
+	ctrl->vfeModuleEnableLocal.statsEnable =
+		ctrl->vfeStatsCmdLocal.autoFocusEnable |
+		ctrl->vfeStatsCmdLocal.axwEnable;
+
+	vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
+
+	vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
+
+	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
+	vfe_program_irq_mask(ctrl->vfeImaskPacked);
+
+	if ((ctrl->vfeModuleEnableLocal.statsEnable == TRUE) &&
+			(ctrl->vfeStatsPingPongReloadFlag == FALSE)) {
+		ctrl->vfeStatsPingPongReloadFlag = TRUE;
+
+		ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
+		vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
+	}
+
+	vfe_program_reg_update_cmd(VFE_REG_UPDATE_TRIGGER);
+}
+
+int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *in)
+{
+	int rc = 0;
+
+	ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
+
+	switch (in->channelSelect) {
+	case RGB_GAMMA_CH0_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		vfe_write_gamma_table(0,
+			ctrl->vfeGammaLutSel.ch0BankSelect, in->table);
+		break;
+
+	case RGB_GAMMA_CH1_SELECTED:
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		vfe_write_gamma_table(1,
+			ctrl->vfeGammaLutSel.ch1BankSelect, in->table);
+		break;
+
+	case RGB_GAMMA_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(2,
+			ctrl->vfeGammaLutSel.ch2BankSelect, in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
+			in->table);
+		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
+			in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
+			in->table);
+		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
+			in->table);
+		break;
+
+	case RGB_GAMMA_CH1_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
+			in->table);
+		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
+			in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
+		ctrl->vfeGammaLutSel.ch0BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch1BankSelect ^= 1;
+		ctrl->vfeGammaLutSel.ch2BankSelect ^= 1;
+		vfe_write_gamma_table(0, ctrl->vfeGammaLutSel.ch0BankSelect,
+			in->table);
+		vfe_write_gamma_table(1, ctrl->vfeGammaLutSel.ch1BankSelect,
+			in->table);
+		vfe_write_gamma_table(2, ctrl->vfeGammaLutSel.ch2BankSelect,
+			in->table);
+		break;
+
+	default:
+		return -EINVAL;
+	} /* switch */
+
+	/* update the gammaLutSel register. */
+	vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
+
+	return rc;
+}
+
+int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *in)
+{
+	int rc = 0;
+
+	ctrl->vfeModuleEnableLocal.rgbLUTEnable = in->enable;
+
+	switch (in->channelSelect) {
+	case RGB_GAMMA_CH0_SELECTED:
+vfe_write_gamma_table(0, 0, in->table);
+break;
+
+	case RGB_GAMMA_CH1_SELECTED:
+		vfe_write_gamma_table(1, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH2_SELECTED:
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_SELECTED:
+		vfe_write_gamma_table(0, 0, in->table);
+		vfe_write_gamma_table(1, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH2_SELECTED:
+		vfe_write_gamma_table(0, 0, in->table);
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH1_CH2_SELECTED:
+		vfe_write_gamma_table(1, 0, in->table);
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	case RGB_GAMMA_CH0_CH1_CH2_SELECTED:
+		vfe_write_gamma_table(0, 0, in->table);
+		vfe_write_gamma_table(1, 0, in->table);
+		vfe_write_gamma_table(2, 0, in->table);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	} /* switch */
+
+	return rc;
+}
+
+void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *in)
+{
+	ctrl->afStatsControl.nextFrameAddrBuf = in->nextAFOutputBufferAddr;
+	ctrl->afStatsControl.ackPending = FALSE;
+}
+
+void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *in)
+{
+	ctrl->awbStatsControl.nextFrameAddrBuf = in->nextWbExpOutputBufferAddr;
+	ctrl->awbStatsControl.ackPending = FALSE;
+}
+
+void vfe_output2_ack(struct vfe_cmd_output_ack *in)
+{
+	const uint32_t *psrc;
+	uint32_t *pdest;
+	uint8_t i;
+
+	pdest = ctrl->encPath.nextFrameAddrBuf;
+
+	CDBG("output2_ack: ack addr = 0x%x\n", in->ybufaddr[0]);
+
+	psrc = in->ybufaddr;
+	for (i = 0; i < ctrl->encPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	psrc = in->chromabufaddr;
+	for (i = 0; i < ctrl->encPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	ctrl->encPath.ackPending = FALSE;
+}
+
+void vfe_output1_ack(struct vfe_cmd_output_ack *in)
+{
+	const uint32_t *psrc;
+	uint32_t *pdest;
+	uint8_t i;
+
+	pdest = ctrl->viewPath.nextFrameAddrBuf;
+
+	psrc = in->ybufaddr;
+	for (i = 0; i < ctrl->viewPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	psrc = in->chromabufaddr;
+	for (i = 0; i < ctrl->viewPath.fragCount; i++)
+		*pdest++ = *psrc++;
+
+	ctrl->viewPath.ackPending = FALSE;
+}
+
+void vfe_start(struct vfe_cmd_start *in)
+{
+	unsigned long flags;
+	uint32_t  pmstatus = 0;
+	boolean rawmode;
+	uint32_t  demperiod = 0;
+	uint32_t  demeven = 0;
+	uint32_t  demodd = 0;
+
+	/* derived from other commands.  (camif config, axi output config,
+	 * etc)
+	*/
+	struct vfe_cfg hwcfg;
+	struct vfe_upsample_cfg chromupcfg;
+
+	CDBG("vfe_start operationMode = %d\n", in->operationMode);
+
+	memset(&hwcfg, 0, sizeof(hwcfg));
+	memset(&chromupcfg, 0, sizeof(chromupcfg));
+
+	switch (in->pixel) {
+	case VFE_BAYER_RGRGRG:
+		demperiod = 1;
+		demeven = 0xC9;
+		demodd = 0xAC;
+		break;
+
+	case VFE_BAYER_GRGRGR:
+		demperiod = 1;
+		demeven = 0x9C;
+		demodd = 0xCA;
+		break;
+
+	case VFE_BAYER_BGBGBG:
+		demperiod = 1;
+		demeven = 0xCA;
+		demodd = 0x9C;
+		break;
+
+	case VFE_BAYER_GBGBGB:
+		demperiod = 1;
+		demeven = 0xAC;
+		demodd = 0xC9;
+		break;
+
+	case VFE_YUV_YCbYCr:
+		demperiod = 3;
+		demeven = 0x9CAC;
+		demodd = 0x9CAC;
+		break;
+
+	case VFE_YUV_YCrYCb:
+		demperiod = 3;
+		demeven = 0xAC9C;
+		demodd = 0xAC9C;
+		break;
+
+	case VFE_YUV_CbYCrY:
+		demperiod = 3;
+		demeven = 0xC9CA;
+		demodd = 0xC9CA;
+		break;
+
+	case VFE_YUV_CrYCbY:
+		demperiod = 3;
+		demeven = 0xCAC9;
+		demodd = 0xCAC9;
+		break;
+
+	default:
+		return;
+	}
+
+	vfe_config_demux(demperiod, demeven, demodd);
+
+	vfe_program_lut_bank_sel(&ctrl->vfeGammaLutSel);
+
+	/* save variables to local. */
+	ctrl->vfeOperationMode = in->operationMode;
+	if (ctrl->vfeOperationMode ==
+			VFE_START_OPERATION_MODE_SNAPSHOT) {
+		/* in snapshot mode, initialize snapshot count*/
+		ctrl->vfeSnapShotCount = in->snapshotCount;
+
+		/* save the requested count, this is temporarily done, to
+		help with HJR / multishot. */
+		ctrl->vfeRequestedSnapShotCount = ctrl->vfeSnapShotCount;
+
+		CDBG("requested snapshot count = %d\n", ctrl->vfeSnapShotCount);
+
+		/* Assumption is to have the same pattern and period for both
+		paths, if both paths are used. */
+		if (ctrl->viewPath.pathEnabled) {
+			ctrl->viewPath.snapshotPendingCount =
+				in->snapshotCount;
+
+			ctrl->vfeFrameSkipPattern =
+				ctrl->vfeFrameSkip.output1Pattern;
+			ctrl->vfeFrameSkipPeriod =
+				ctrl->vfeFrameSkip.output1Period;
+		}
+
+		if (ctrl->encPath.pathEnabled) {
+			ctrl->encPath.snapshotPendingCount =
+				in->snapshotCount;
+
+			ctrl->vfeFrameSkipPattern =
+				ctrl->vfeFrameSkip.output2Pattern;
+			ctrl->vfeFrameSkipPeriod =
+				ctrl->vfeFrameSkip.output2Period;
+		}
+	}
+
+	/* enable color conversion for bayer sensor
+	if stats enabled, need to do color conversion. */
+	if (in->pixel <= VFE_BAYER_GBGBGB)
+		ctrl->vfeStatsCmdLocal.colorConversionEnable = TRUE;
+
+	vfe_program_stats_cmd(&ctrl->vfeStatsCmdLocal);
+
+	if (in->pixel >= VFE_YUV_YCbYCr)
+		ctrl->vfeModuleEnableLocal.chromaUpsampleEnable = TRUE;
+
+	ctrl->vfeModuleEnableLocal.demuxEnable = TRUE;
+
+	/* if any stats module is enabled, the main bit is enabled. */
+	ctrl->vfeModuleEnableLocal.statsEnable =
+		ctrl->vfeStatsCmdLocal.autoFocusEnable |
+		ctrl->vfeStatsCmdLocal.axwEnable;
+
+	vfe_reg_module_cfg(&ctrl->vfeModuleEnableLocal);
+
+	/* in case of offline processing, do not need to config camif. Having
+	 * bus output enabled in camif_config register might confuse the
+	 * hardware?
+	 */
+	if (in->inputSource != VFE_START_INPUT_SOURCE_AXI) {
+		vfe_reg_camif_config(&ctrl->vfeCamifConfigLocal);
+	} else {
+		/* offline processing, enable axi read */
+		ctrl->vfeBusConfigLocal.stripeRdPathEn = TRUE;
+		ctrl->vfeBusCmdLocal.stripeReload = TRUE;
+		ctrl->vfeBusConfigLocal.rawPixelDataSize =
+			ctrl->axiInputDataSize;
+	}
+
+	vfe_reg_bus_cfg(&ctrl->vfeBusConfigLocal);
+
+	/* directly from start command */
+	hwcfg.pixelPattern = in->pixel;
+	hwcfg.inputSource = in->inputSource;
+	writel(*(uint32_t *)&hwcfg, ctrl->vfebase + VFE_CFG);
+
+	/* regardless module enabled or not, it does not hurt
+	 * to program the cositing mode. */
+	chromupcfg.chromaCositingForYCbCrInputs =
+		in->yuvInputCositingMode;
+
+	writel(*(uint32_t *)&(chromupcfg),
+		ctrl->vfebase + VFE_CHROMA_UPSAMPLE_CFG);
+
+	/* MISR to monitor the axi read. */
+	writel(0xd8, ctrl->vfebase + VFE_BUS_MISR_MAST_CFG_0);
+
+	/* clear all pending interrupts. */
+	writel(VFE_CLEAR_ALL_IRQS, ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	/*  define how composite interrupt work.  */
+	ctrl->vfeImaskCompositePacked =
+		vfe_irq_composite_pack(ctrl->vfeIrqCompositeMaskLocal);
+
+	vfe_program_irq_composite_mask(ctrl->vfeImaskCompositePacked);
+
+	/*  enable all necessary interrupts.      */
+	ctrl->vfeImaskLocal.camifSofIrq  = TRUE;
+	ctrl->vfeImaskLocal.regUpdateIrq = TRUE;
+	ctrl->vfeImaskLocal.resetAckIrq  = TRUE;
+
+	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
+	vfe_program_irq_mask(ctrl->vfeImaskPacked);
+
+	/* enable bus performance monitor */
+	vfe_8k_pm_start(&ctrl->vfeBusPmConfigLocal);
+
+	/* trigger vfe reg update */
+	ctrl->vfeStartAckPendingFlag = TRUE;
+
+	/* write bus command to trigger reload of ping pong buffer. */
+	ctrl->vfeBusCmdLocal.busPingpongReload = TRUE;
+
+	if (ctrl->vfeModuleEnableLocal.statsEnable == TRUE) {
+		ctrl->vfeBusCmdLocal.statsPingpongReload = TRUE;
+		ctrl->vfeStatsPingPongReloadFlag = TRUE;
+	}
+
+	writel(VFE_REG_UPDATE_TRIGGER,
+		ctrl->vfebase + VFE_REG_UPDATE_CMD);
+
+	/* program later than the reg update. */
+	vfe_reg_bus_cmd(&ctrl->vfeBusCmdLocal);
+
+	if ((in->inputSource ==
+			 VFE_START_INPUT_SOURCE_CAMIF) ||
+			(in->inputSource ==
+			 VFE_START_INPUT_SOURCE_TESTGEN))
+		writel(CAMIF_COMMAND_START, ctrl->vfebase + CAMIF_COMMAND);
+
+	/* start test gen if it is enabled */
+	if (ctrl->vfeTestGenStartFlag == TRUE) {
+		ctrl->vfeTestGenStartFlag = FALSE;
+		vfe_prog_hw_testgen_cmd(VFE_TEST_GEN_GO);
+	}
+
+	CDBG("ctrl->axiOutputMode = %d\n", ctrl->axiOutputMode);
+	if (ctrl->axiOutputMode == VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2) {
+		/* raw dump mode */
+		rawmode = TRUE;
+
+		while (rawmode) {
+			pmstatus =
+				readl(ctrl->vfebase +
+					VFE_BUS_ENC_CBCR_WR_PM_STATS_1);
+
+			if ((pmstatus & VFE_PM_BUF_MAX_CNT_MASK) != 0)
+				rawmode = FALSE;
+		}
+
+		vfe_send_msg_no_payload(VFE_MSG_ID_START_ACK);
+		ctrl->vfeStartAckPendingFlag = FALSE;
+	}
+
+	spin_lock_irqsave(&ctrl->state_lock, flags);
+	ctrl->vstate = VFE_STATE_ACTIVE;
+	spin_unlock_irqrestore(&ctrl->state_lock, flags);
+}
+
+void vfe_la_update(struct vfe_cmd_la_config *in)
+{
+	int16_t *pTable;
+	enum VFE_DMI_RAM_SEL dmiRamSel;
+	int i;
+
+	pTable = in->table;
+	ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
+
+	/* toggle the bank to be used. */
+	ctrl->vfeLaBankSel ^= 1;
+
+	if (ctrl->vfeLaBankSel == 0)
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
+	else
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
+
+	/* configure the DMI_CFG to select right sram */
+	vfe_program_dmi_cfg(dmiRamSel);
+
+	for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
+		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
+		pTable++;
+	}
+
+	/* After DMI transfer, to make it safe, need to set
+	 * the DMI_CFG to unselect any SRAM */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+	writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
+}
+
+void vfe_la_config(struct vfe_cmd_la_config *in)
+{
+	uint16_t i;
+	int16_t  *pTable;
+	enum VFE_DMI_RAM_SEL dmiRamSel;
+
+	pTable = in->table;
+	ctrl->vfeModuleEnableLocal.lumaAdaptationEnable = in->enable;
+
+	if (ctrl->vfeLaBankSel == 0)
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK0;
+	else
+		dmiRamSel = LUMA_ADAPT_LUT_RAM_BANK1;
+
+	/* configure the DMI_CFG to select right sram */
+	vfe_program_dmi_cfg(dmiRamSel);
+
+	for (i = 0; i < VFE_LA_TABLE_LENGTH; i++) {
+		writel((uint32_t)(*pTable), ctrl->vfebase + VFE_DMI_DATA_LO);
+		pTable++;
+	}
+
+	/* After DMI transfer, to make it safe, need to set the
+	 * DMI_CFG to unselect any SRAM */
+	writel(VFE_DMI_CFG_DEFAULT, ctrl->vfebase + VFE_DMI_CFG);
+
+	/* can only be bank 0 or bank 1 for now. */
+	writel(ctrl->vfeLaBankSel, ctrl->vfebase + VFE_LA_CFG);
+	CDBG("VFE Luma adaptation bank selection is 0x%x\n",
+			 *(uint32_t *)&ctrl->vfeLaBankSel);
+}
+
+void vfe_test_gen_start(struct vfe_cmd_test_gen_start *in)
+{
+	struct VFE_TestGen_ConfigCmdType cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.numFrame              = in->numFrame;
+	cmd.pixelDataSelect       = in->pixelDataSelect;
+	cmd.systematicDataSelect  = in->systematicDataSelect;
+	cmd.pixelDataSize         = (uint32_t)in->pixelDataSize;
+	cmd.hsyncEdge             = (uint32_t)in->hsyncEdge;
+	cmd.vsyncEdge             = (uint32_t)in->vsyncEdge;
+	cmd.imageWidth            = in->imageWidth;
+	cmd.imageHeight           = in->imageHeight;
+	cmd.sofOffset             = in->startOfFrameOffset;
+	cmd.eofNOffset            = in->endOfFrameNOffset;
+	cmd.solOffset             = in->startOfLineOffset;
+	cmd.eolNOffset            = in->endOfLineNOffset;
+	cmd.hBlankInterval        = in->hbi;
+	cmd.vBlankInterval        = in->vbl;
+	cmd.vBlankIntervalEnable  = in->vblEnable;
+	cmd.sofDummy              = in->startOfFrameDummyLine;
+	cmd.eofDummy              = in->endOfFrameDummyLine;
+	cmd.unicolorBarSelect     = in->unicolorBarSelect;
+	cmd.unicolorBarEnable     = in->unicolorBarEnable;
+	cmd.splitEnable           = in->colorBarsSplitEnable;
+	cmd.pixelPattern          = (uint32_t)in->colorBarsPixelPattern;
+	cmd.rotatePeriod          = in->colorBarsRotatePeriod;
+	cmd.randomSeed            = in->testGenRandomSeed;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_HW_TESTGEN_CFG,
+		(uint32_t *) &cmd, sizeof(cmd));
+}
+
+void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *in)
+{
+	struct VFE_FRAME_SKIP_UpdateCmdType cmd;
+
+	cmd.yPattern    = in->output1Pattern;
+	cmd.cbcrPattern = in->output1Pattern;
+	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_VIEW_Y_PATTERN,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd.yPattern    = in->output2Pattern;
+	cmd.cbcrPattern = in->output2Pattern;
+	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_PATTERN,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *in)
+{
+	struct vfe_frame_skip_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeFrameSkip = *in;
+
+	cmd.output2YPeriod     = in->output2Period;
+	cmd.output2CbCrPeriod  = in->output2Period;
+	cmd.output2YPattern    = in->output2Pattern;
+	cmd.output2CbCrPattern = in->output2Pattern;
+	cmd.output1YPeriod     = in->output1Period;
+	cmd.output1CbCrPeriod  = in->output1Period;
+	cmd.output1YPattern    = in->output1Pattern;
+	cmd.output1CbCrPattern = in->output1Pattern;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_FRAMEDROP_ENC_Y_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *in)
+{
+	struct vfe_output_clamp_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.yChanMax  = in->maxCh0;
+	cmd.cbChanMax = in->maxCh1;
+	cmd.crChanMax = in->maxCh2;
+
+	cmd.yChanMin  = in->minCh0;
+	cmd.cbChanMin = in->minCh1;
+	cmd.crChanMin = in->minCh2;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CLAMP_MAX_CFG, (uint32_t *)&cmd,
+		sizeof(cmd));
+}
+
+void vfe_camif_frame_update(struct vfe_cmds_camif_frame *in)
+{
+	struct vfe_camifframe_update cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.pixelsPerLine = in->pixelsPerLine;
+	cmd.linesPerFrame = in->linesPerFrame;
+
+	vfe_prog_hw(ctrl->vfebase + CAMIF_FRAME_CONFIG, (uint32_t *)&cmd,
+		sizeof(cmd));
+}
+
+void vfe_color_correction_config(
+	struct vfe_cmd_color_correction_config *in)
+{
+	struct vfe_color_correction_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ctrl->vfeModuleEnableLocal.colorCorrectionEnable = in->enable;
+
+	cmd.c0 = in->C0;
+	cmd.c1 = in->C1;
+	cmd.c2 = in->C2;
+	cmd.c3 = in->C3;
+	cmd.c4 = in->C4;
+	cmd.c5 = in->C5;
+	cmd.c6 = in->C6;
+	cmd.c7 = in->C7;
+	cmd.c8 = in->C8;
+
+	cmd.k0 = in->K0;
+	cmd.k1 = in->K1;
+	cmd.k2 = in->K2;
+
+	cmd.coefQFactor = in->coefQFactor;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CORRECT_COEFF_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *in)
+{
+struct vfe_demosaic_cfg cmd;
+	struct vfe_demosaic_abf_cfg cmdabf;
+	uint32_t temp;
+
+	memset(&cmd, 0, sizeof(cmd));
+	temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
+
+	cmd = *((struct vfe_demosaic_cfg *)(&temp));
+	cmd.abfEnable       = in->abfUpdate.enable;
+	cmd.forceAbfOn      = in->abfUpdate.forceOn;
+	cmd.abfShift        = in->abfUpdate.shift;
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmdabf.lpThreshold  = in->abfUpdate.lpThreshold;
+	cmdabf.ratio        = in->abfUpdate.ratio;
+	cmdabf.minValue     = in->abfUpdate.min;
+	cmdabf.maxValue     = in->abfUpdate.max;
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
+		(uint32_t *)&cmdabf, sizeof(cmdabf));
+}
+
+void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *in)
+{
+	struct vfe_demosaic_cfg cmd;
+	struct vfe_demosaic_bpc_cfg cmdbpc;
+	uint32_t temp;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	temp = readl(ctrl->vfebase + VFE_DEMOSAIC_CFG);
+
+	cmd = *((struct vfe_demosaic_cfg *)(&temp));
+	cmd.badPixelCorrEnable = in->bpcUpdate.enable;
+	cmd.fminThreshold      = in->bpcUpdate.fminThreshold;
+	cmd.fmaxThreshold      = in->bpcUpdate.fmaxThreshold;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmdbpc.blueDiffThreshold  = in->bpcUpdate.blueDiffThreshold;
+	cmdbpc.redDiffThreshold   = in->bpcUpdate.redDiffThreshold;
+	cmdbpc.greenDiffThreshold = in->bpcUpdate.greenDiffThreshold;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
+		(uint32_t *)&cmdbpc, sizeof(cmdbpc));
+}
+
+void vfe_demosaic_config(struct vfe_cmd_demosaic_config *in)
+{
+	struct vfe_demosaic_cfg cmd;
+	struct vfe_demosaic_bpc_cfg cmd_bpc;
+	struct vfe_demosaic_abf_cfg cmd_abf;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd_bpc, 0, sizeof(cmd_bpc));
+	memset(&cmd_abf, 0, sizeof(cmd_abf));
+
+	ctrl->vfeModuleEnableLocal.demosaicEnable = in->enable;
+
+	cmd.abfEnable          = in->abfConfig.enable;
+	cmd.badPixelCorrEnable = in->bpcConfig.enable;
+	cmd.forceAbfOn         = in->abfConfig.forceOn;
+	cmd.abfShift           = in->abfConfig.shift;
+	cmd.fminThreshold      = in->bpcConfig.fminThreshold;
+	cmd.fmaxThreshold      = in->bpcConfig.fmaxThreshold;
+	cmd.slopeShift         = in->slopeShift;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd_abf.lpThreshold = in->abfConfig.lpThreshold;
+	cmd_abf.ratio       = in->abfConfig.ratio;
+	cmd_abf.minValue    = in->abfConfig.min;
+	cmd_abf.maxValue    = in->abfConfig.max;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_ABF_CFG_0,
+		(uint32_t *)&cmd_abf, sizeof(cmd_abf));
+
+	cmd_bpc.blueDiffThreshold   = in->bpcConfig.blueDiffThreshold;
+	cmd_bpc.redDiffThreshold    = in->bpcConfig.redDiffThreshold;
+	cmd_bpc.greenDiffThreshold  = in->bpcConfig.greenDiffThreshold;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMOSAIC_BPC_CFG_0,
+		(uint32_t *)&cmd_bpc, sizeof(cmd_bpc));
+}
+
+void vfe_demux_channel_gain_update(
+	struct vfe_cmd_demux_channel_gain_config *in)
+{
+	struct vfe_demux_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.ch0EvenGain  = in->ch0EvenGain;
+	cmd.ch0OddGain   = in->ch0OddGain;
+	cmd.ch1Gain      = in->ch1Gain;
+	cmd.ch2Gain      = in->ch2Gain;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_demux_channel_gain_config(
+	struct vfe_cmd_demux_channel_gain_config *in)
+{
+	struct vfe_demux_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.ch0EvenGain = in->ch0EvenGain;
+	cmd.ch0OddGain  = in->ch0OddGain;
+	cmd.ch1Gain     = in->ch1Gain;
+	cmd.ch2Gain     = in->ch2Gain;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_DEMUX_GAIN_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_black_level_update(struct vfe_cmd_black_level_config *in)
+{
+	struct vfe_blacklevel_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
+
+	cmd.evenEvenAdjustment = in->evenEvenAdjustment;
+	cmd.evenOddAdjustment  = in->evenOddAdjustment;
+	cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
+	cmd.oddOddAdjustment   = in->oddOddAdjustment;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_black_level_config(struct vfe_cmd_black_level_config *in)
+{
+	struct vfe_blacklevel_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.blackLevelCorrectionEnable = in->enable;
+
+	cmd.evenEvenAdjustment = in->evenEvenAdjustment;
+	cmd.evenOddAdjustment  = in->evenOddAdjustment;
+	cmd.oddEvenAdjustment  = in->oddEvenAdjustment;
+	cmd.oddOddAdjustment   = in->oddOddAdjustment;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BLACK_EVEN_EVEN_VALUE,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_asf_update(struct vfe_cmd_asf_update *in)
+{
+	struct vfe_asf_update cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
+
+	cmd.smoothEnable     = in->smoothFilterEnabled;
+	cmd.sharpMode        = in->sharpMode;
+	cmd.smoothCoeff1     = in->smoothCoefCenter;
+	cmd.smoothCoeff0     = in->smoothCoefSurr;
+	cmd.cropEnable       = in->cropEnable;
+	cmd.sharpThresholdE1 = in->sharpThreshE1;
+	cmd.sharpDegreeK1    = in->sharpK1;
+	cmd.sharpDegreeK2    = in->sharpK2;
+	cmd.normalizeFactor  = in->normalizeFactor;
+	cmd.sharpThresholdE2 = in->sharpThreshE2;
+	cmd.sharpThresholdE3 = in->sharpThreshE3;
+	cmd.sharpThresholdE4 = in->sharpThreshE4;
+	cmd.sharpThresholdE5 = in->sharpThreshE5;
+	cmd.F1Coeff0         = in->filter1Coefficients[0];
+	cmd.F1Coeff1         = in->filter1Coefficients[1];
+	cmd.F1Coeff2         = in->filter1Coefficients[2];
+	cmd.F1Coeff3         = in->filter1Coefficients[3];
+	cmd.F1Coeff4         = in->filter1Coefficients[4];
+	cmd.F1Coeff5         = in->filter1Coefficients[5];
+	cmd.F1Coeff6         = in->filter1Coefficients[6];
+	cmd.F1Coeff7         = in->filter1Coefficients[7];
+	cmd.F1Coeff8         = in->filter1Coefficients[8];
+	cmd.F2Coeff0         = in->filter2Coefficients[0];
+	cmd.F2Coeff1         = in->filter2Coefficients[1];
+	cmd.F2Coeff2         = in->filter2Coefficients[2];
+	cmd.F2Coeff3         = in->filter2Coefficients[3];
+	cmd.F2Coeff4         = in->filter2Coefficients[4];
+	cmd.F2Coeff5         = in->filter2Coefficients[5];
+	cmd.F2Coeff6         = in->filter2Coefficients[6];
+	cmd.F2Coeff7         = in->filter2Coefficients[7];
+	cmd.F2Coeff8         = in->filter2Coefficients[8];
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_asf_config(struct vfe_cmd_asf_config *in)
+{
+	struct vfe_asf_update     cmd;
+	struct vfe_asfcrop_cfg cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	ctrl->vfeModuleEnableLocal.asfEnable = in->enable;
+
+	cmd.smoothEnable       = in->smoothFilterEnabled;
+	cmd.sharpMode          = in->sharpMode;
+	cmd.smoothCoeff0       = in->smoothCoefCenter;
+	cmd.smoothCoeff1       = in->smoothCoefSurr;
+	cmd.cropEnable         = in->cropEnable;
+	cmd.sharpThresholdE1   = in->sharpThreshE1;
+	cmd.sharpDegreeK1      = in->sharpK1;
+	cmd.sharpDegreeK2      = in->sharpK2;
+	cmd.normalizeFactor    = in->normalizeFactor;
+	cmd.sharpThresholdE2   = in->sharpThreshE2;
+	cmd.sharpThresholdE3   = in->sharpThreshE3;
+	cmd.sharpThresholdE4   = in->sharpThreshE4;
+	cmd.sharpThresholdE5   = in->sharpThreshE5;
+	cmd.F1Coeff0           = in->filter1Coefficients[0];
+	cmd.F1Coeff1           = in->filter1Coefficients[1];
+	cmd.F1Coeff2           = in->filter1Coefficients[2];
+	cmd.F1Coeff3           = in->filter1Coefficients[3];
+	cmd.F1Coeff4           = in->filter1Coefficients[4];
+	cmd.F1Coeff5           = in->filter1Coefficients[5];
+	cmd.F1Coeff6           = in->filter1Coefficients[6];
+	cmd.F1Coeff7           = in->filter1Coefficients[7];
+	cmd.F1Coeff8           = in->filter1Coefficients[8];
+	cmd.F2Coeff0           = in->filter2Coefficients[0];
+	cmd.F2Coeff1           = in->filter2Coefficients[1];
+	cmd.F2Coeff2           = in->filter2Coefficients[2];
+	cmd.F2Coeff3           = in->filter2Coefficients[3];
+	cmd.F2Coeff4           = in->filter2Coefficients[4];
+	cmd.F2Coeff5           = in->filter2Coefficients[5];
+	cmd.F2Coeff6           = in->filter2Coefficients[6];
+	cmd.F2Coeff7           = in->filter2Coefficients[7];
+	cmd.F2Coeff8           = in->filter2Coefficients[8];
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.firstLine  = in->cropFirstLine;
+	cmd2.lastLine   = in->cropLastLine;
+	cmd2.firstPixel = in->cropFirstPixel;
+	cmd2.lastPixel  = in->cropLastPixel;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ASF_CROP_WIDTH_CFG,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_white_balance_config(struct vfe_cmd_white_balance_config *in)
+{
+	struct vfe_wb_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.whiteBalanceEnable =
+		in->enable;
+
+	cmd.ch0Gain = in->ch0Gain;
+	cmd.ch1Gain = in->ch1Gain;
+	cmd.ch2Gain = in->ch2Gain;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_WB_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *in)
+{
+	struct vfe_chroma_suppress_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.chromaSuppressionEnable = in->enable;
+
+	cmd.m1  = in->m1;
+	cmd.m3  = in->m3;
+	cmd.n1  = in->n1;
+	cmd.n3  = in->n3;
+	cmd.mm1 = in->mm1;
+	cmd.nn1 = in->nn1;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUPPRESS_CFG_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_roll_off_config(struct vfe_cmd_roll_off_config *in)
+{
+	struct vfe_rolloff_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.lensRollOffEnable = in->enable;
+
+	cmd.gridWidth   = in->gridWidth;
+	cmd.gridHeight  = in->gridHeight;
+	cmd.yDelta      = in->yDelta;
+	cmd.gridX       = in->gridXIndex;
+	cmd.gridY       = in->gridYIndex;
+	cmd.pixelX      = in->gridPixelXIndex;
+	cmd.pixelY      = in->gridPixelYIndex;
+	cmd.yDeltaAccum = in->yDeltaAccum;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_ROLLOFF_CFG_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	vfe_write_lens_roll_off_table(in);
+}
+
+void vfe_chroma_subsample_config(
+	struct vfe_cmd_chroma_subsample_config *in)
+{
+	struct vfe_chromasubsample_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.chromaSubsampleEnable = in->enable;
+
+	cmd.hCositedPhase       = in->hCositedPhase;
+	cmd.vCositedPhase       = in->vCositedPhase;
+	cmd.hCosited            = in->hCosited;
+	cmd.vCosited            = in->vCosited;
+	cmd.hsubSampleEnable    = in->hsubSampleEnable;
+	cmd.vsubSampleEnable    = in->vsubSampleEnable;
+	cmd.cropEnable          = in->cropEnable;
+	cmd.cropWidthLastPixel  = in->cropWidthLastPixel;
+	cmd.cropWidthFirstPixel = in->cropWidthFirstPixel;
+	cmd.cropHeightLastLine  = in->cropHeightLastLine;
+	cmd.cropHeightFirstLine = in->cropHeightFirstLine;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_SUBSAMPLE_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *in)
+{
+	struct vfe_chroma_enhance_cfg cmd;
+	struct vfe_color_convert_cfg cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	ctrl->vfeModuleEnableLocal.chromaEnhanEnable = in->enable;
+
+	cmd.ap             = in->ap;
+	cmd.am             = in->am;
+	cmd.bp             = in->bp;
+	cmd.bm             = in->bm;
+	cmd.cp             = in->cp;
+	cmd.cm             = in->cm;
+	cmd.dp             = in->dp;
+	cmd.dm             = in->dm;
+	cmd.kcb            = in->kcb;
+	cmd.kcr            = in->kcr;
+
+	cmd2.v0            = in->RGBtoYConversionV0;
+	cmd2.v1            = in->RGBtoYConversionV1;
+	cmd2.v2            = in->RGBtoYConversionV2;
+	cmd2.ConvertOffset = in->RGBtoYConversionOffset;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CHROMA_ENHAN_A,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	vfe_prog_hw(ctrl->vfebase + VFE_COLOR_CONVERT_COEFF_0,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *in)
+{
+	struct vfe_scaler2_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.scaler2CbcrEnable = in->enable;
+
+	cmd.hEnable              = in->hconfig.enable;
+	cmd.vEnable              = in->vconfig.enable;
+	cmd.inWidth              = in->hconfig.inputSize;
+	cmd.outWidth             = in->hconfig.outputSize;
+	cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
+	cmd.horizInterResolution = in->hconfig.interpolationResolution;
+	cmd.inHeight             = in->vconfig.inputSize;
+	cmd.outHeight            = in->vconfig.outputSize;
+	cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
+	cmd.vertInterResolution  = in->vconfig.interpolationResolution;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CBCR_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *in)
+{
+	struct vfe_scaler2_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.scaler2YEnable = in->enable;
+
+	cmd.hEnable               = in->hconfig.enable;
+	cmd.vEnable               = in->vconfig.enable;
+	cmd.inWidth               = in->hconfig.inputSize;
+	cmd.outWidth              = in->hconfig.outputSize;
+	cmd.horizPhaseMult        = in->hconfig.phaseMultiplicationFactor;
+	cmd.horizInterResolution  = in->hconfig.interpolationResolution;
+	cmd.inHeight              = in->vconfig.inputSize;
+	cmd.outHeight             = in->vconfig.outputSize;
+	cmd.vertPhaseMult         = in->vconfig.phaseMultiplicationFactor;
+	cmd.vertInterResolution   = in->vconfig.interpolationResolution;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_Y_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *in)
+{
+	struct vfe_main_scaler_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.mainScalerEnable = in->enable;
+
+	cmd.hEnable              = in->hconfig.enable;
+	cmd.vEnable              = in->vconfig.enable;
+	cmd.inWidth              = in->hconfig.inputSize;
+	cmd.outWidth             = in->hconfig.outputSize;
+	cmd.horizPhaseMult       = in->hconfig.phaseMultiplicationFactor;
+	cmd.horizInterResolution = in->hconfig.interpolationResolution;
+	cmd.horizMNInit          = in->MNInitH.MNCounterInit;
+	cmd.horizPhaseInit       = in->MNInitH.phaseInit;
+	cmd.inHeight             = in->vconfig.inputSize;
+	cmd.outHeight            = in->vconfig.outputSize;
+	cmd.vertPhaseMult        = in->vconfig.phaseMultiplicationFactor;
+	cmd.vertInterResolution  = in->vconfig.interpolationResolution;
+	cmd.vertMNInit           = in->MNInitV.MNCounterInit;
+	cmd.vertPhaseInit        = in->MNInitV.phaseInit;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_SCALE_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_stats_wb_exp_stop(void)
+{
+	ctrl->vfeStatsCmdLocal.axwEnable = FALSE;
+	ctrl->vfeImaskLocal.awbPingpongIrq = FALSE;
+}
+
+void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *in)
+{
+	struct vfe_statsawb_update   cmd;
+	struct vfe_statsawbae_update cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	cmd.m1  = in->awbMCFG[0];
+	cmd.m2  = in->awbMCFG[1];
+	cmd.m3  = in->awbMCFG[2];
+	cmd.m4  = in->awbMCFG[3];
+	cmd.c1  = in->awbCCFG[0];
+	cmd.c2  = in->awbCCFG[1];
+	cmd.c3  = in->awbCCFG[2];
+	cmd.c4  = in->awbCCFG[3];
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.aeRegionCfg    = in->wbExpRegions;
+	cmd2.aeSubregionCfg = in->wbExpSubRegion;
+	cmd2.awbYMin        = in->awbYMin;
+	cmd2.awbYMax        = in->awbYMax;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_stats_update_af(struct vfe_cmd_stats_af_update *in)
+{
+	struct vfe_statsaf_update cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	cmd.windowVOffset = in->windowVOffset;
+	cmd.windowHOffset = in->windowHOffset;
+	cmd.windowMode    = in->windowMode;
+	cmd.windowHeight  = in->windowHeight;
+	cmd.windowWidth   = in->windowWidth;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *in)
+{
+	struct vfe_statsawb_update   cmd;
+	struct vfe_statsawbae_update cmd2;
+	struct vfe_statsaxw_hdr_cfg  cmd3;
+
+	ctrl->vfeStatsCmdLocal.axwEnable   =  in->enable;
+	ctrl->vfeImaskLocal.awbPingpongIrq = TRUE;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+	memset(&cmd3, 0, sizeof(cmd3));
+
+	cmd.m1  = in->awbMCFG[0];
+	cmd.m2  = in->awbMCFG[1];
+	cmd.m3  = in->awbMCFG[2];
+	cmd.m4  = in->awbMCFG[3];
+	cmd.c1  = in->awbCCFG[0];
+	cmd.c2  = in->awbCCFG[1];
+	cmd.c3  = in->awbCCFG[2];
+	cmd.c4  = in->awbCCFG[3];
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWB_MCFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.aeRegionCfg     = in->wbExpRegions;
+	cmd2.aeSubregionCfg  = in->wbExpSubRegion;
+	cmd2.awbYMin         = in->awbYMin;
+	cmd2.awbYMax         = in->awbYMax;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AWBAE_CFG,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+
+	cmd3.axwHeader       = in->axwHeader;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AXW_HEADER,
+		(uint32_t *)&cmd3, sizeof(cmd3));
+}
+
+void vfe_stats_start_af(struct vfe_cmd_stats_af_start *in)
+{
+	struct vfe_statsaf_update cmd;
+	struct vfe_statsaf_cfg    cmd2;
+
+	memset(&cmd, 0, sizeof(cmd));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+ctrl->vfeStatsCmdLocal.autoFocusEnable = in->enable;
+ctrl->vfeImaskLocal.afPingpongIrq = TRUE;
+
+	cmd.windowVOffset = in->windowVOffset;
+	cmd.windowHOffset = in->windowHOffset;
+	cmd.windowMode    = in->windowMode;
+	cmd.windowHeight  = in->windowHeight;
+	cmd.windowWidth   = in->windowWidth;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	cmd2.a00       = in->highPassCoef[0];
+	cmd2.a04       = in->highPassCoef[1];
+	cmd2.a20       = in->highPassCoef[2];
+	cmd2.a21       = in->highPassCoef[3];
+	cmd2.a22       = in->highPassCoef[4];
+	cmd2.a23       = in->highPassCoef[5];
+	cmd2.a24       = in->highPassCoef[6];
+	cmd2.fvMax     = in->metricMax;
+	cmd2.fvMetric  = in->metricSelection;
+	cmd2.afHeader  = in->bufferHeader;
+	cmd2.entry00   = in->gridForMultiWindows[0];
+	cmd2.entry01   = in->gridForMultiWindows[1];
+	cmd2.entry02   = in->gridForMultiWindows[2];
+	cmd2.entry03   = in->gridForMultiWindows[3];
+	cmd2.entry10   = in->gridForMultiWindows[4];
+	cmd2.entry11   = in->gridForMultiWindows[5];
+	cmd2.entry12   = in->gridForMultiWindows[6];
+	cmd2.entry13   = in->gridForMultiWindows[7];
+	cmd2.entry20   = in->gridForMultiWindows[8];
+	cmd2.entry21   = in->gridForMultiWindows[9];
+	cmd2.entry22   = in->gridForMultiWindows[10];
+	cmd2.entry23   = in->gridForMultiWindows[11];
+	cmd2.entry30   = in->gridForMultiWindows[12];
+	cmd2.entry31   = in->gridForMultiWindows[13];
+	cmd2.entry32   = in->gridForMultiWindows[14];
+	cmd2.entry33   = in->gridForMultiWindows[15];
+
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_AF_GRID_0,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+}
+
+void vfe_stats_setting(struct vfe_cmd_stats_setting *in)
+{
+	struct vfe_statsframe cmd1;
+	struct vfe_busstats_wrprio cmd2;
+
+	memset(&cmd1, 0, sizeof(cmd1));
+	memset(&cmd2, 0, sizeof(cmd2));
+
+	ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
+	ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
+	ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
+
+	ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
+	ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
+	ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
+
+	cmd1.lastPixel = in->frameHDimension;
+	cmd1.lastLine  = in->frameVDimension;
+	vfe_prog_hw(ctrl->vfebase + VFE_STATS_FRAME_SIZE,
+		(uint32_t *)&cmd1, sizeof(cmd1));
+
+	cmd2.afBusPriority    = in->afBusPriority;
+	cmd2.awbBusPriority   = in->awbBusPriority;
+	cmd2.histBusPriority  = in->histBusPriority;
+	cmd2.afBusPriorityEn  = in->afBusPrioritySelection;
+	cmd2.awbBusPriorityEn = in->awbBusPrioritySelection;
+	cmd2.histBusPriorityEn = in->histBusPrioritySelection;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_STATS_WR_PRIORITY,
+		(uint32_t *)&cmd2, sizeof(cmd2));
+
+	/* Program the bus ping pong address for statistics modules. */
+	writel(in->afBuffer[0], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PING_ADDR);
+	writel(in->afBuffer[1], ctrl->vfebase + VFE_BUS_STATS_AF_WR_PONG_ADDR);
+	writel(in->awbBuffer[0],
+		ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PING_ADDR);
+	writel(in->awbBuffer[1],
+		ctrl->vfebase + VFE_BUS_STATS_AWB_WR_PONG_ADDR);
+	writel(in->histBuffer[0],
+		ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PING_ADDR);
+	writel(in->histBuffer[1],
+		ctrl->vfebase + VFE_BUS_STATS_HIST_WR_PONG_ADDR);
+}
+
+void vfe_axi_input_config(struct vfe_cmd_axi_input_config *in)
+{
+	struct VFE_AxiInputCmdType cmd;
+	uint32_t xSizeWord, axiRdUnpackPattern;
+	uint8_t  axiInputPpw;
+	uint32_t busPingpongRdIrqEnable;
+
+	ctrl->vfeImaskLocal.rdPingpongIrq = TRUE;
+
+	switch (in->pixelSize) {
+	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
+		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_10BIT;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
+		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_12BIT;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
+	default:
+		ctrl->axiInputDataSize = VFE_RAW_PIXEL_DATA_SIZE_8BIT;
+		break;
+	}
+
+	memset(&cmd, 0, sizeof(cmd));
+
+	switch (in->pixelSize) {
+	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
+		axiInputPpw = 6;
+		axiRdUnpackPattern = 0xD43210;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
+		axiInputPpw = 5;
+		axiRdUnpackPattern = 0xC3210;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
+	default:
+		axiInputPpw = 8;
+		axiRdUnpackPattern = 0xF6543210;
+		break;
+	}
+
+	xSizeWord =
+		((((in->xOffset % axiInputPpw) + in->xSize) +
+			(axiInputPpw-1)) / axiInputPpw) - 1;
+
+	cmd.stripeStartAddr0  = in->fragAddr[0];
+	cmd.stripeStartAddr1  = in->fragAddr[1];
+	cmd.stripeStartAddr2  = in->fragAddr[2];
+	cmd.stripeStartAddr3  = in->fragAddr[3];
+	cmd.ySize             = in->ySize;
+	cmd.yOffsetDelta      = 0;
+	cmd.xSizeWord         = xSizeWord;
+	cmd.burstLength       = 1;
+	cmd.NumOfRows         = in->numOfRows;
+	cmd.RowIncrement      =
+		(in->rowIncrement + (axiInputPpw-1))/axiInputPpw;
+	cmd.mainUnpackHeight  = in->ySize;
+	cmd.mainUnpackWidth   = in->xSize - 1;
+	cmd.mainUnpackHbiSel  = (uint32_t)in->unpackHbi;
+	cmd.mainUnpackPhase   = in->unpackPhase;
+	cmd.unpackPattern     = axiRdUnpackPattern;
+	cmd.padLeft           = in->padRepeatCountLeft;
+	cmd.padRight          = in->padRepeatCountRight;
+	cmd.padTop            = in->padRepeatCountTop;
+	cmd.padBottom         = in->padRepeatCountBottom;
+	cmd.leftUnpackPattern0   = in->padLeftComponentSelectCycle0;
+	cmd.leftUnpackPattern1   = in->padLeftComponentSelectCycle1;
+	cmd.leftUnpackPattern2   = in->padLeftComponentSelectCycle2;
+	cmd.leftUnpackPattern3   = in->padLeftComponentSelectCycle3;
+	cmd.leftUnpackStop0      = in->padLeftStopCycle0;
+	cmd.leftUnpackStop1      = in->padLeftStopCycle1;
+	cmd.leftUnpackStop2      = in->padLeftStopCycle2;
+	cmd.leftUnpackStop3      = in->padLeftStopCycle3;
+	cmd.rightUnpackPattern0  = in->padRightComponentSelectCycle0;
+	cmd.rightUnpackPattern1  = in->padRightComponentSelectCycle1;
+	cmd.rightUnpackPattern2  = in->padRightComponentSelectCycle2;
+	cmd.rightUnpackPattern3  = in->padRightComponentSelectCycle3;
+	cmd.rightUnpackStop0     = in->padRightStopCycle0;
+	cmd.rightUnpackStop1     = in->padRightStopCycle1;
+	cmd.rightUnpackStop2     = in->padRightStopCycle2;
+	cmd.rightUnpackStop3     = in->padRightStopCycle3;
+	cmd.topUnapckPattern     = in->padTopLineCount;
+	cmd.bottomUnapckPattern  = in->padBottomLineCount;
+
+	/*  program vfe_bus_cfg */
+	vfe_prog_hw(ctrl->vfebase + VFE_BUS_STRIPE_RD_ADDR_0,
+		(uint32_t *)&cmd, sizeof(cmd));
+
+	/* hacking code, put it to default value */
+	busPingpongRdIrqEnable = 0xf;
+
+	writel(busPingpongRdIrqEnable,
+		ctrl->vfebase + VFE_BUS_PINGPONG_IRQ_EN);
+}
+
+void vfe_stats_config(struct vfe_cmd_stats_setting *in)
+{
+	ctrl->afStatsControl.addressBuffer[0] = in->afBuffer[0];
+	ctrl->afStatsControl.addressBuffer[1] = in->afBuffer[1];
+	ctrl->afStatsControl.nextFrameAddrBuf = in->afBuffer[2];
+
+	ctrl->awbStatsControl.addressBuffer[0] = in->awbBuffer[0];
+	ctrl->awbStatsControl.addressBuffer[1] = in->awbBuffer[1];
+	ctrl->awbStatsControl.nextFrameAddrBuf = in->awbBuffer[2];
+
+	vfe_stats_setting(in);
+}
+
+void vfe_axi_output_config(
+	struct vfe_cmd_axi_output_config *in)
+{
+	/* local variable  */
+	uint32_t *pcircle;
+	uint32_t *pdest;
+	uint32_t *psrc;
+	uint8_t  i;
+	uint8_t  fcnt;
+	uint16_t axioutpw = 8;
+
+	/* parameters check, condition and usage mode check */
+	ctrl->encPath.fragCount = in->output2.fragmentCount;
+	if (ctrl->encPath.fragCount > 1)
+		ctrl->encPath.multiFrag = TRUE;
+
+	ctrl->viewPath.fragCount = in->output1.fragmentCount;
+	if (ctrl->viewPath.fragCount > 1)
+		ctrl->viewPath.multiFrag = TRUE;
+
+	/* VFE_BUS_CFG.  raw data size */
+	ctrl->vfeBusConfigLocal.rawPixelDataSize = in->outputDataSize;
+
+	switch (in->outputDataSize) {
+	case VFE_RAW_PIXEL_DATA_SIZE_8BIT:
+		axioutpw = 8;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_10BIT:
+		axioutpw = 6;
+		break;
+
+	case VFE_RAW_PIXEL_DATA_SIZE_12BIT:
+		axioutpw = 5;
+		break;
+	}
+
+	ctrl->axiOutputMode = in->outputMode;
+
+	CDBG("axiOutputMode = %d\n", ctrl->axiOutputMode);
+
+	switch (ctrl->axiOutputMode) {
+	case VFE_AXI_OUTPUT_MODE_Output1: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_DISABLED;
+
+		ctrl->encPath.pathEnabled                   = FALSE;
+		ctrl->vfeImaskLocal.encIrq                  = FALSE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = FALSE;
+		ctrl->viewPath.pathEnabled                    = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                   = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn    = TRUE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output1 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_Output2: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = FALSE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_DISABLED;
+
+		ctrl->encPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.encIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
+
+		ctrl->viewPath.pathEnabled                   = FALSE;
+		ctrl->vfeImaskLocal.viewIrq                  = FALSE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output2 */
+			break;
+
+	case VFE_AXI_OUTPUT_MODE_Output1AndOutput2: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable    = FALSE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect   =
+			VFE_RAW_OUTPUT_DISABLED;
+
+		ctrl->encPath.pathEnabled                    = TRUE;
+		ctrl->vfeImaskLocal.encIrq                   = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn         = TRUE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn      = TRUE;
+		ctrl->viewPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = TRUE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output1AndOutput2 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2: {
+		/* For raw snapshot, we need both ping and pong buffer
+		 * initialized to the same address. Otherwise, if we
+		 * leave the pong buffer to NULL, there will be axi_error.
+		 * Note that ideally we should deal with this at upper layer,
+		 * which is in msm_vfe8x.c */
+		if (!in->output2.outputCbcr.outFragments[1][0]) {
+			in->output2.outputCbcr.outFragments[1][0] =
+				in->output2.outputCbcr.outFragments[0][0];
+		}
+
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = FALSE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_ENC_CBCR_PATH;
+
+		ctrl->encPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.encIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_CBCR_ONLY;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
+
+		ctrl->viewPath.pathEnabled                   = FALSE;
+		ctrl->vfeImaskLocal.viewIrq                  = FALSE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = FALSE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_CAMIFToAXIViaOutput2 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_VIEW_CBCR_PATH;
+
+		ctrl->encPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.encIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn        = TRUE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn     = TRUE;
+
+		ctrl->viewPath.pathEnabled                   = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                  = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_CBCR_ONLY;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn        = FALSE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn     = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq   = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output2AndCAMIFToAXIViaOutput1 */
+		break;
+
+	case VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2: {
+		ctrl->vfeCamifConfigLocal.camif2BusEnable   = TRUE;
+		ctrl->vfeCamifConfigLocal.camif2OutputEnable = TRUE;
+		ctrl->vfeBusConfigLocal.rawWritePathSelect  =
+			VFE_RAW_OUTPUT_ENC_CBCR_PATH;
+
+		ctrl->encPath.pathEnabled                     = TRUE;
+		ctrl->vfeImaskLocal.encIrq                    = TRUE;
+		ctrl->vfeIrqCompositeMaskLocal.encIrqComMask  =
+			VFE_COMP_IRQ_CBCR_ONLY;
+
+		ctrl->vfeBusConfigLocal.encYWrPathEn          = FALSE;
+		ctrl->vfeBusConfigLocal.encCbcrWrPathEn       = TRUE;
+
+		ctrl->viewPath.pathEnabled                    = TRUE;
+		ctrl->vfeImaskLocal.viewIrq                   = TRUE;
+
+		ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+			VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+		ctrl->vfeBusConfigLocal.viewYWrPathEn         = TRUE;
+		ctrl->vfeBusConfigLocal.viewCbcrWrPathEn      = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encYWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encYPingpongIrq       = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.encCbcrWrPathEn &&
+				ctrl->encPath.multiFrag)
+			ctrl->vfeImaskLocal.encCbcrPingpongIrq    = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewYWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewYPingpongIrq      = TRUE;
+
+		if (ctrl->vfeBusConfigLocal.viewCbcrWrPathEn &&
+				ctrl->viewPath.multiFrag)
+			ctrl->vfeImaskLocal.viewCbcrPingpongIrq   = TRUE;
+	} /* VFE_AXI_OUTPUT_MODE_Output1AndCAMIFToAXIViaOutput2 */
+		break;
+
+	case VFE_AXI_LAST_OUTPUT_MODE_ENUM:
+		break;
+	} /* switch */
+
+	/* Save the addresses for each path. */
+	/* output2 path */
+	fcnt = ctrl->encPath.fragCount;
+
+	pcircle = ctrl->encPath.yPath.addressBuffer;
+	pdest = ctrl->encPath.nextFrameAddrBuf;
+
+	psrc = &(in->output2.outputY.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputY.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputY.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	pcircle = ctrl->encPath.cbcrPath.addressBuffer;
+
+	psrc = &(in->output2.outputCbcr.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputCbcr.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output2.outputCbcr.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	vfe_set_bus_pipo_addr(&ctrl->viewPath, &ctrl->encPath);
+
+	ctrl->encPath.ackPending = FALSE;
+	ctrl->encPath.currentFrame = ping;
+	ctrl->encPath.whichOutputPath = 1;
+	ctrl->encPath.yPath.fragIndex = 2;
+	ctrl->encPath.cbcrPath.fragIndex = 2;
+	ctrl->encPath.yPath.hwCurrentFlag = ping;
+	ctrl->encPath.cbcrPath.hwCurrentFlag = ping;
+
+	/* output1 path */
+	pcircle = ctrl->viewPath.yPath.addressBuffer;
+	pdest = ctrl->viewPath.nextFrameAddrBuf;
+	fcnt = ctrl->viewPath.fragCount;
+
+	psrc = &(in->output1.outputY.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputY.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputY.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	pcircle = ctrl->viewPath.cbcrPath.addressBuffer;
+
+	psrc = &(in->output1.outputCbcr.outFragments[0][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputCbcr.outFragments[1][0]);
+	for (i = 0; i < fcnt; i++)
+		*pcircle++ = *psrc++;
+
+	psrc = &(in->output1.outputCbcr.outFragments[2][0]);
+	for (i = 0; i < fcnt; i++)
+		*pdest++ = *psrc++;
+
+	ctrl->viewPath.ackPending = FALSE;
+	ctrl->viewPath.currentFrame = ping;
+	ctrl->viewPath.whichOutputPath = 0;
+	ctrl->viewPath.yPath.fragIndex = 2;
+	ctrl->viewPath.cbcrPath.fragIndex = 2;
+	ctrl->viewPath.yPath.hwCurrentFlag = ping;
+	ctrl->viewPath.cbcrPath.hwCurrentFlag = ping;
+
+	/* call to program the registers. */
+	vfe_axi_output(in, &ctrl->viewPath, &ctrl->encPath, axioutpw);
+}
+
+void vfe_camif_config(struct vfe_cmd_camif_config *in)
+{
+	struct vfe_camifcfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	CDBG("camif.frame pixelsPerLine = %d\n", in->frame.pixelsPerLine);
+	CDBG("camif.frame linesPerFrame = %d\n", in->frame.linesPerFrame);
+	CDBG("camif.window firstpixel = %d\n", in->window.firstpixel);
+	CDBG("camif.window lastpixel = %d\n",  in->window.lastpixel);
+	CDBG("camif.window firstline = %d\n",  in->window.firstline);
+	CDBG("camif.window lastline = %d\n",   in->window.lastline);
+
+	/* determine if epoch interrupt needs to be enabled.  */
+	if ((in->epoch1.enable == TRUE) &&
+			(in->epoch1.lineindex <=
+			 in->frame.linesPerFrame))
+		ctrl->vfeImaskLocal.camifEpoch1Irq = 1;
+
+	if ((in->epoch2.enable == TRUE) &&
+			(in->epoch2.lineindex <=
+			 in->frame.linesPerFrame)) {
+		ctrl->vfeImaskLocal.camifEpoch2Irq = 1;
+	}
+
+	/*  save the content to program CAMIF_CONFIG seperately. */
+	ctrl->vfeCamifConfigLocal.camifCfgFromCmd = in->camifConfig;
+
+	/* EFS_Config */
+	cmd.efsEndOfLine     = in->EFS.efsendofline;
+	cmd.efsStartOfLine   = in->EFS.efsstartofline;
+	cmd.efsEndOfFrame    = in->EFS.efsendofframe;
+	cmd.efsStartOfFrame  = in->EFS.efsstartofframe;
+
+	/* Frame Config */
+	cmd.frameConfigPixelsPerLine = in->frame.pixelsPerLine;
+	cmd.frameConfigLinesPerFrame = in->frame.linesPerFrame;
+
+	/* Window Width Config */
+	cmd.windowWidthCfgLastPixel  = in->window.lastpixel;
+	cmd.windowWidthCfgFirstPixel = in->window.firstpixel;
+
+	/* Window Height Config */
+	cmd.windowHeightCfglastLine   = in->window.lastline;
+	cmd.windowHeightCfgfirstLine  = in->window.firstline;
+
+	/* Subsample 1 Config */
+	cmd.subsample1CfgPixelSkip = in->subsample.pixelskipmask;
+	cmd.subsample1CfgLineSkip  = in->subsample.lineskipmask;
+
+	/* Subsample 2 Config */
+	cmd.subsample2CfgFrameSkip      = in->subsample.frameskip;
+	cmd.subsample2CfgFrameSkipMode  = in->subsample.frameskipmode;
+	cmd.subsample2CfgPixelSkipWrap  = in->subsample.pixelskipwrap;
+
+	/* Epoch Interrupt */
+	cmd.epoch1Line = in->epoch1.lineindex;
+	cmd.epoch2Line = in->epoch2.lineindex;
+
+	vfe_prog_hw(ctrl->vfebase + CAMIF_EFS_CONFIG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *in)
+{
+	struct vfe_fov_crop_cfg cmd;
+	memset(&cmd, 0, sizeof(cmd));
+
+	ctrl->vfeModuleEnableLocal.cropEnable = in->enable;
+
+	/* FOV Corp, Part 1 */
+	cmd.lastPixel  = in->lastPixel;
+	cmd.firstPixel = in->firstPixel;
+
+	/* FOV Corp, Part 2 */
+	cmd.lastLine   = in->lastLine;
+	cmd.firstLine  = in->firstLine;
+
+	vfe_prog_hw(ctrl->vfebase + VFE_CROP_WIDTH_CFG,
+		(uint32_t *)&cmd, sizeof(cmd));
+}
+
+void vfe_get_hw_version(struct vfe_cmd_hw_version *out)
+{
+	uint32_t vfeHwVersionPacked;
+	struct vfe_hw_ver ver;
+
+	vfeHwVersionPacked = readl(ctrl->vfebase + VFE_HW_VERSION);
+
+	ver = *((struct vfe_hw_ver *)&vfeHwVersionPacked);
+
+	out->coreVersion  = ver.coreVersion;
+	out->minorVersion = ver.minorVersion;
+	out->majorVersion = ver.majorVersion;
+}
+
+static void vfe_reset_internal_variables(void)
+{
+	unsigned long flags;
+
+	/* local variables to program the hardware. */
+	ctrl->vfeImaskPacked = 0;
+	ctrl->vfeImaskCompositePacked = 0;
+
+	/* FALSE = disable,  1 = enable. */
+	memset(&ctrl->vfeModuleEnableLocal, 0,
+		sizeof(ctrl->vfeModuleEnableLocal));
+
+	/* 0 = disable, 1 = enable */
+	memset(&ctrl->vfeCamifConfigLocal, 0,
+		sizeof(ctrl->vfeCamifConfigLocal));
+	/* 0 = disable, 1 = enable */
+	memset(&ctrl->vfeImaskLocal, 0, sizeof(ctrl->vfeImaskLocal));
+	memset(&ctrl->vfeStatsCmdLocal, 0, sizeof(ctrl->vfeStatsCmdLocal));
+	memset(&ctrl->vfeBusConfigLocal, 0, sizeof(ctrl->vfeBusConfigLocal));
+	memset(&ctrl->vfeBusPmConfigLocal, 0,
+		sizeof(ctrl->vfeBusPmConfigLocal));
+	memset(&ctrl->vfeBusCmdLocal, 0, sizeof(ctrl->vfeBusCmdLocal));
+	memset(&ctrl->vfeInterruptNameLocal, 0,
+		sizeof(ctrl->vfeInterruptNameLocal));
+	memset(&ctrl->vfeDroppedFrameCounts, 0,
+		sizeof(ctrl->vfeDroppedFrameCounts));
+	memset(&ctrl->vfeIrqThreadMsgLocal, 0,
+		sizeof(ctrl->vfeIrqThreadMsgLocal));
+
+	/* state control variables */
+	ctrl->vfeStartAckPendingFlag = FALSE;
+	ctrl->vfeStopAckPending = FALSE;
+	ctrl->vfeIrqCompositeMaskLocal.ceDoneSel = 0;
+	ctrl->vfeIrqCompositeMaskLocal.encIrqComMask =
+		VFE_COMP_IRQ_BOTH_Y_CBCR;
+	ctrl->vfeIrqCompositeMaskLocal.viewIrqComMask =
+		VFE_COMP_IRQ_BOTH_Y_CBCR;
+
+	spin_lock_irqsave(&ctrl->state_lock, flags);
+	ctrl->vstate = VFE_STATE_IDLE;
+	spin_unlock_irqrestore(&ctrl->state_lock, flags);
+
+	ctrl->axiOutputMode = VFE_AXI_LAST_OUTPUT_MODE_ENUM;
+	/* 0 for continuous mode, 1 for snapshot mode */
+	ctrl->vfeOperationMode = VFE_START_OPERATION_MODE_CONTINUOUS;
+	ctrl->vfeSnapShotCount = 0;
+	ctrl->vfeStatsPingPongReloadFlag = FALSE;
+	/* this is unsigned 32 bit integer. */
+	ctrl->vfeFrameId = 0;
+	ctrl->vfeFrameSkip.output1Pattern = 0xffffffff;
+	ctrl->vfeFrameSkip.output1Period  = 31;
+	ctrl->vfeFrameSkip.output2Pattern = 0xffffffff;
+	ctrl->vfeFrameSkip.output2Period  = 31;
+	ctrl->vfeFrameSkipPattern = 0xffffffff;
+	ctrl->vfeFrameSkipCount   = 0;
+	ctrl->vfeFrameSkipPeriod  = 31;
+
+	memset((void *)&ctrl->encPath, 0, sizeof(ctrl->encPath));
+	memset((void *)&ctrl->viewPath, 0, sizeof(ctrl->viewPath));
+
+	ctrl->encPath.whichOutputPath  = 1;
+	ctrl->encPath.cbcrStatusBit    = 5;
+	ctrl->viewPath.whichOutputPath = 0;
+	ctrl->viewPath.cbcrStatusBit   = 7;
+
+	ctrl->vfeTestGenStartFlag = FALSE;
+
+	/* default to bank 0. */
+	ctrl->vfeLaBankSel = 0;
+
+	/* default to bank 0 for all channels. */
+	memset(&ctrl->vfeGammaLutSel, 0, sizeof(ctrl->vfeGammaLutSel));
+
+	/* Stats control variables. */
+	memset(&ctrl->afStatsControl, 0, sizeof(ctrl->afStatsControl));
+	memset(&ctrl->awbStatsControl, 0, sizeof(ctrl->awbStatsControl));
+	vfe_set_stats_pingpong_address(&ctrl->afStatsControl,
+		&ctrl->awbStatsControl);
+}
+
+void vfe_reset(void)
+{
+	vfe_reset_internal_variables();
+
+	ctrl->vfeImaskLocal.resetAckIrq = TRUE;
+	ctrl->vfeImaskPacked = vfe_irq_pack(ctrl->vfeImaskLocal);
+
+	/* disable all interrupts. */
+	writel(VFE_DISABLE_ALL_IRQS,
+		ctrl->vfebase + VFE_IRQ_COMPOSITE_MASK);
+
+	/* clear all pending interrupts*/
+	writel(VFE_CLEAR_ALL_IRQS,
+		ctrl->vfebase + VFE_IRQ_CLEAR);
+
+	/* enable reset_ack interrupt.  */
+	writel(ctrl->vfeImaskPacked,
+		ctrl->vfebase + VFE_IRQ_MASK);
+
+	writel(VFE_RESET_UPON_RESET_CMD,
+		ctrl->vfebase + VFE_GLOBAL_RESET_CMD);
+}
diff --git a/drivers/staging/dream/camera/msm_vfe8x_proc.h b/drivers/staging/dream/camera/msm_vfe8x_proc.h
new file mode 100644
index 0000000..9182856
--- /dev/null
+++ b/drivers/staging/dream/camera/msm_vfe8x_proc.h
@@ -0,0 +1,1549 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#ifndef __MSM_VFE8X_REG_H__
+#define __MSM_VFE8X_REG_H__
+
+#include <mach/msm_iomap.h>
+#include <mach/camera.h>
+#include "msm_vfe8x.h"
+
+/* at start of camif,  bit 1:0 = 0x01:enable
+ * image data capture at frame boundary. */
+#define CAMIF_COMMAND_START  0x00000005
+
+/* bit 2= 0x1:clear the CAMIF_STATUS register
+ * value. */
+#define CAMIF_COMMAND_CLEAR  0x00000004
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x10:
+ * disable image data capture immediately. */
+#define CAMIF_COMMAND_STOP_IMMEDIATELY  0x00000002
+
+/* at stop of vfe pipeline, for now it is assumed
+ * that camif will stop at any time. Bit 1:0 = 0x00:
+ * disable image data capture at frame boundary */
+#define CAMIF_COMMAND_STOP_AT_FRAME_BOUNDARY  0x00000000
+
+/* to halt axi bridge */
+#define AXI_HALT  0x00000001
+
+/* clear the halt bit. */
+#define AXI_HALT_CLEAR  0x00000000
+
+/* reset the pipeline when stop command is issued.
+ * (without reset the register.) bit 26-31 = 0,
+ * domain reset, bit 0-9 = 1 for module reset, except
+ * register module. */
+#define VFE_RESET_UPON_STOP_CMD  0x000003ef
+
+/* reset the pipeline when reset command.
+ * bit 26-31 = 0, domain reset, bit 0-9 = 1 for module reset. */
+#define VFE_RESET_UPON_RESET_CMD  0x000003ff
+
+/* bit 5 is for axi status idle or busy.
+ * 1 =  halted,  0 = busy */
+#define AXI_STATUS_BUSY_MASK 0x00000020
+
+/* bit 0 & bit 1 = 1, both y and cbcr irqs need to be present
+ * for frame done interrupt */
+#define VFE_COMP_IRQ_BOTH_Y_CBCR 3
+
+/* bit 1 = 1, only cbcr irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_CBCR_ONLY 2
+
+/* bit 0 = 1, only y irq triggers frame done interrupt */
+#define VFE_COMP_IRQ_Y_ONLY 1
+
+/* bit 0 = 1, PM go;   bit1 = 1, PM stop */
+#define VFE_PERFORMANCE_MONITOR_GO   0x00000001
+#define VFE_PERFORMANCE_MONITOR_STOP 0x00000002
+
+/* bit 0 = 1, test gen go;   bit1 = 1, test gen stop */
+#define VFE_TEST_GEN_GO   0x00000001
+#define VFE_TEST_GEN_STOP 0x00000002
+
+/* the chroma is assumed to be interpolated between
+ * the luma samples.  JPEG 4:2:2 */
+#define VFE_CHROMA_UPSAMPLE_INTERPOLATED 0
+
+/* constants for irq registers */
+#define VFE_DISABLE_ALL_IRQS 0
+/* bit =1 is to clear the corresponding bit in VFE_IRQ_STATUS.  */
+#define VFE_CLEAR_ALL_IRQS   0xffffffff
+/* imask for while waiting for stop ack,  driver has already
+ * requested stop, waiting for reset irq,
+ * bit 29,28,27,26 for async timer, bit 9 for reset */
+#define VFE_IMASK_WHILE_STOPPING  0x3c000200
+
+/* when normal case, don't want to block error status.
+ * bit 0,6,20,21,22,30,31 */
+#define VFE_IMASK_ERROR_ONLY             0xC0700041
+#define VFE_REG_UPDATE_TRIGGER           1
+#define VFE_PM_BUF_MAX_CNT_MASK          0xFF
+#define VFE_DMI_CFG_DEFAULT              0x00000100
+#define LENS_ROLL_OFF_DELTA_TABLE_OFFSET 32
+#define VFE_AF_PINGPONG_STATUS_BIT       0x100
+#define VFE_AWB_PINGPONG_STATUS_BIT      0x200
+
+/* VFE I/O registers */
+enum {
+	VFE_HW_VERSION                    = 0x00000000,
+	VFE_GLOBAL_RESET_CMD              = 0x00000004,
+	VFE_MODULE_RESET                  = 0x00000008,
+	VFE_CGC_OVERRIDE                  = 0x0000000C,
+	VFE_MODULE_CFG                    = 0x00000010,
+	VFE_CFG                           = 0x00000014,
+	VFE_IRQ_MASK                      = 0x00000018,
+	VFE_IRQ_CLEAR                     = 0x0000001C,
+VFE_IRQ_STATUS                    = 0x00000020,
+VFE_IRQ_COMPOSITE_MASK            = 0x00000024,
+VFE_BUS_CMD                       = 0x00000028,
+VFE_BUS_CFG                       = 0x0000002C,
+VFE_BUS_ENC_Y_WR_PING_ADDR        = 0x00000030,
+VFE_BUS_ENC_Y_WR_PONG_ADDR        = 0x00000034,
+VFE_BUS_ENC_Y_WR_IMAGE_SIZE       = 0x00000038,
+VFE_BUS_ENC_Y_WR_BUFFER_CFG       = 0x0000003C,
+VFE_BUS_ENC_CBCR_WR_PING_ADDR     = 0x00000040,
+VFE_BUS_ENC_CBCR_WR_PONG_ADDR     = 0x00000044,
+VFE_BUS_ENC_CBCR_WR_IMAGE_SIZE    = 0x00000048,
+VFE_BUS_ENC_CBCR_WR_BUFFER_CFG    = 0x0000004C,
+VFE_BUS_VIEW_Y_WR_PING_ADDR       = 0x00000050,
+VFE_BUS_VIEW_Y_WR_PONG_ADDR       = 0x00000054,
+VFE_BUS_VIEW_Y_WR_IMAGE_SIZE      = 0x00000058,
+VFE_BUS_VIEW_Y_WR_BUFFER_CFG      = 0x0000005C,
+VFE_BUS_VIEW_CBCR_WR_PING_ADDR    = 0x00000060,
+VFE_BUS_VIEW_CBCR_WR_PONG_ADDR    = 0x00000064,
+VFE_BUS_VIEW_CBCR_WR_IMAGE_SIZE   = 0x00000068,
+VFE_BUS_VIEW_CBCR_WR_BUFFER_CFG   = 0x0000006C,
+VFE_BUS_STATS_AF_WR_PING_ADDR     = 0x00000070,
+VFE_BUS_STATS_AF_WR_PONG_ADDR     = 0x00000074,
+VFE_BUS_STATS_AWB_WR_PING_ADDR    = 0x00000078,
+VFE_BUS_STATS_AWB_WR_PONG_ADDR    = 0x0000007C,
+VFE_BUS_STATS_HIST_WR_PING_ADDR   = 0x00000080,
+VFE_BUS_STATS_HIST_WR_PONG_ADDR   = 0x00000084,
+VFE_BUS_STATS_WR_PRIORITY         = 0x00000088,
+VFE_BUS_STRIPE_RD_ADDR_0          = 0x0000008C,
+VFE_BUS_STRIPE_RD_ADDR_1          = 0x00000090,
+VFE_BUS_STRIPE_RD_ADDR_2          = 0x00000094,
+VFE_BUS_STRIPE_RD_ADDR_3          = 0x00000098,
+VFE_BUS_STRIPE_RD_VSIZE           = 0x0000009C,
+VFE_BUS_STRIPE_RD_HSIZE           = 0x000000A0,
+VFE_BUS_STRIPE_RD_BUFFER_CFG      = 0x000000A4,
+VFE_BUS_STRIPE_RD_UNPACK_CFG      = 0x000000A8,
+VFE_BUS_STRIPE_RD_UNPACK          = 0x000000AC,
+VFE_BUS_STRIPE_RD_PAD_SIZE        = 0x000000B0,
+VFE_BUS_STRIPE_RD_PAD_L_UNPACK    = 0x000000B4,
+VFE_BUS_STRIPE_RD_PAD_R_UNPACK    = 0x000000B8,
+VFE_BUS_STRIPE_RD_PAD_TB_UNPACK   = 0x000000BC,
+VFE_BUS_PINGPONG_IRQ_EN           = 0x000000C0,
+VFE_BUS_PINGPONG_STATUS           = 0x000000C4,
+VFE_BUS_PM_CMD                    = 0x000000C8,
+VFE_BUS_PM_CFG                    = 0x000000CC,
+VFE_BUS_ENC_Y_WR_PM_STATS_0       = 0x000000D0,
+VFE_BUS_ENC_Y_WR_PM_STATS_1       = 0x000000D4,
+VFE_BUS_ENC_CBCR_WR_PM_STATS_0    = 0x000000D8,
+VFE_BUS_ENC_CBCR_WR_PM_STATS_1    = 0x000000DC,
+VFE_BUS_VIEW_Y_WR_PM_STATS_0      = 0x000000E0,
+VFE_BUS_VIEW_Y_WR_PM_STATS_1      = 0x000000E4,
+VFE_BUS_VIEW_CBCR_WR_PM_STATS_0   = 0x000000E8,
+VFE_BUS_VIEW_CBCR_WR_PM_STATS_1   = 0x000000EC,
+VFE_BUS_MISR_CFG                  = 0x000000F4,
+VFE_BUS_MISR_MAST_CFG_0           = 0x000000F8,
+VFE_BUS_MISR_MAST_CFG_1           = 0x000000FC,
+VFE_BUS_MISR_RD_VAL               = 0x00000100,
+VFE_AXI_CMD                       = 0x00000104,
+VFE_AXI_CFG                       = 0x00000108,
+VFE_AXI_STATUS                    = 0x0000010C,
+CAMIF_COMMAND                     = 0x00000110,
+CAMIF_CONFIG                      = 0x00000114,
+CAMIF_EFS_CONFIG                  = 0x00000118,
+CAMIF_FRAME_CONFIG                = 0x0000011C,
+CAMIF_WINDOW_WIDTH_CONFIG         = 0x00000120,
+CAMIF_WINDOW_HEIGHT_CONFIG        = 0x00000124,
+CAMIF_SUBSAMPLE1_CONFIG           = 0x00000128,
+CAMIF_SUBSAMPLE2_CONFIG           = 0x0000012C,
+CAMIF_EPOCH_IRQ                   = 0x00000130,
+CAMIF_STATUS                      = 0x00000134,
+CAMIF_MISR                        = 0x00000138,
+VFE_SYNC_TIMER_CMD                = 0x0000013C,
+VFE_SYNC_TIMER0_LINE_START        = 0x00000140,
+VFE_SYNC_TIMER0_PIXEL_START       = 0x00000144,
+VFE_SYNC_TIMER0_PIXEL_DURATION    = 0x00000148,
+VFE_SYNC_TIMER1_LINE_START        = 0x0000014C,
+VFE_SYNC_TIMER1_PIXEL_START       = 0x00000150,
+VFE_SYNC_TIMER1_PIXEL_DURATION    = 0x00000154,
+VFE_SYNC_TIMER2_LINE_START        = 0x00000158,
+VFE_SYNC_TIMER2_PIXEL_START       = 0x0000015C,
+VFE_SYNC_TIMER2_PIXEL_DURATION    = 0x00000160,
+VFE_SYNC_TIMER_POLARITY           = 0x00000164,
+VFE_ASYNC_TIMER_CMD               = 0x00000168,
+VFE_ASYNC_TIMER0_CFG_0            = 0x0000016C,
+VFE_ASYNC_TIMER0_CFG_1            = 0x00000170,
+VFE_ASYNC_TIMER1_CFG_0            = 0x00000174,
+VFE_ASYNC_TIMER1_CFG_1            = 0x00000178,
+VFE_ASYNC_TIMER2_CFG_0            = 0x0000017C,
+VFE_ASYNC_TIMER2_CFG_1            = 0x00000180,
+VFE_ASYNC_TIMER3_CFG_0            = 0x00000184,
+VFE_ASYNC_TIMER3_CFG_1            = 0x00000188,
+VFE_TIMER_SEL                     = 0x0000018C,
+VFE_REG_UPDATE_CMD                = 0x00000190,
+VFE_BLACK_EVEN_EVEN_VALUE         = 0x00000194,
+VFE_BLACK_EVEN_ODD_VALUE          = 0x00000198,
+VFE_BLACK_ODD_EVEN_VALUE          = 0x0000019C,
+VFE_BLACK_ODD_ODD_VALUE           = 0x000001A0,
+VFE_ROLLOFF_CFG_0                 = 0x000001A4,
+VFE_ROLLOFF_CFG_1                 = 0x000001A8,
+VFE_ROLLOFF_CFG_2                 = 0x000001AC,
+VFE_DEMUX_CFG                     = 0x000001B0,
+VFE_DEMUX_GAIN_0                  = 0x000001B4,
+VFE_DEMUX_GAIN_1                  = 0x000001B8,
+VFE_DEMUX_EVEN_CFG                = 0x000001BC,
+VFE_DEMUX_ODD_CFG                 = 0x000001C0,
+VFE_DEMOSAIC_CFG                  = 0x000001C4,
+VFE_DEMOSAIC_ABF_CFG_0            = 0x000001C8,
+VFE_DEMOSAIC_ABF_CFG_1            = 0x000001CC,
+VFE_DEMOSAIC_BPC_CFG_0            = 0x000001D0,
+VFE_DEMOSAIC_BPC_CFG_1            = 0x000001D4,
+VFE_DEMOSAIC_STATUS               = 0x000001D8,
+VFE_CHROMA_UPSAMPLE_CFG           = 0x000001DC,
+VFE_CROP_WIDTH_CFG                = 0x000001E0,
+VFE_CROP_HEIGHT_CFG               = 0x000001E4,
+VFE_COLOR_CORRECT_COEFF_0         = 0x000001E8,
+VFE_COLOR_CORRECT_COEFF_1         = 0x000001EC,
+VFE_COLOR_CORRECT_COEFF_2         = 0x000001F0,
+VFE_COLOR_CORRECT_COEFF_3         = 0x000001F4,
+VFE_COLOR_CORRECT_COEFF_4         = 0x000001F8,
+VFE_COLOR_CORRECT_COEFF_5         = 0x000001FC,
+VFE_COLOR_CORRECT_COEFF_6         = 0x00000200,
+VFE_COLOR_CORRECT_COEFF_7         = 0x00000204,
+VFE_COLOR_CORRECT_COEFF_8         = 0x00000208,
+VFE_COLOR_CORRECT_OFFSET_0        = 0x0000020C,
+VFE_COLOR_CORRECT_OFFSET_1        = 0x00000210,
+VFE_COLOR_CORRECT_OFFSET_2        = 0x00000214,
+VFE_COLOR_CORRECT_COEFF_Q         = 0x00000218,
+VFE_LA_CFG                        = 0x0000021C,
+VFE_LUT_BANK_SEL                  = 0x00000220,
+VFE_CHROMA_ENHAN_A                = 0x00000224,
+VFE_CHROMA_ENHAN_B                = 0x00000228,
+VFE_CHROMA_ENHAN_C                = 0x0000022C,
+VFE_CHROMA_ENHAN_D                = 0x00000230,
+VFE_CHROMA_ENHAN_K                = 0x00000234,
+VFE_COLOR_CONVERT_COEFF_0         = 0x00000238,
+VFE_COLOR_CONVERT_COEFF_1         = 0x0000023C,
+VFE_COLOR_CONVERT_COEFF_2         = 0x00000240,
+VFE_COLOR_CONVERT_OFFSET          = 0x00000244,
+VFE_ASF_CFG                       = 0x00000248,
+VFE_ASF_SHARP_CFG_0               = 0x0000024C,
+VFE_ASF_SHARP_CFG_1               = 0x00000250,
+VFE_ASF_SHARP_COEFF_0             = 0x00000254,
+VFE_ASF_SHARP_COEFF_1             = 0x00000258,
+VFE_ASF_SHARP_COEFF_2             = 0x0000025C,
+VFE_ASF_SHARP_COEFF_3             = 0x00000260,
+VFE_ASF_MAX_EDGE                  = 0x00000264,
+VFE_ASF_CROP_WIDTH_CFG            = 0x00000268,
+VFE_ASF_CROP_HEIGHT_CFG           = 0x0000026C,
+VFE_SCALE_CFG                     = 0x00000270,
+VFE_SCALE_H_IMAGE_SIZE_CFG        = 0x00000274,
+VFE_SCALE_H_PHASE_CFG             = 0x00000278,
+VFE_SCALE_H_STRIPE_CFG            = 0x0000027C,
+VFE_SCALE_V_IMAGE_SIZE_CFG        = 0x00000280,
+VFE_SCALE_V_PHASE_CFG             = 0x00000284,
+VFE_SCALE_V_STRIPE_CFG            = 0x00000288,
+VFE_SCALE_Y_CFG                   = 0x0000028C,
+VFE_SCALE_Y_H_IMAGE_SIZE_CFG      = 0x00000290,
+VFE_SCALE_Y_H_PHASE_CFG           = 0x00000294,
+VFE_SCALE_Y_V_IMAGE_SIZE_CFG      = 0x00000298,
+VFE_SCALE_Y_V_PHASE_CFG           = 0x0000029C,
+VFE_SCALE_CBCR_CFG                = 0x000002A0,
+VFE_SCALE_CBCR_H_IMAGE_SIZE_CFG   = 0x000002A4,
+VFE_SCALE_CBCR_H_PHASE_CFG        = 0x000002A8,
+VFE_SCALE_CBCR_V_IMAGE_SIZE_CFG   = 0x000002AC,
+VFE_SCALE_CBCR_V_PHASE_CFG        = 0x000002B0,
+VFE_WB_CFG                        = 0x000002B4,
+VFE_CHROMA_SUPPRESS_CFG_0         = 0x000002B8,
+VFE_CHROMA_SUPPRESS_CFG_1         = 0x000002BC,
+VFE_CHROMA_SUBSAMPLE_CFG          = 0x000002C0,
+VFE_CHROMA_SUB_CROP_WIDTH_CFG     = 0x000002C4,
+VFE_CHROMA_SUB_CROP_HEIGHT_CFG    = 0x000002C8,
+VFE_FRAMEDROP_ENC_Y_CFG           = 0x000002CC,
+VFE_FRAMEDROP_ENC_CBCR_CFG        = 0x000002D0,
+VFE_FRAMEDROP_ENC_Y_PATTERN       = 0x000002D4,
+VFE_FRAMEDROP_ENC_CBCR_PATTERN    = 0x000002D8,
+VFE_FRAMEDROP_VIEW_Y_CFG          = 0x000002DC,
+VFE_FRAMEDROP_VIEW_CBCR_CFG       = 0x000002E0,
+VFE_FRAMEDROP_VIEW_Y_PATTERN      = 0x000002E4,
+VFE_FRAMEDROP_VIEW_CBCR_PATTERN   = 0x000002E8,
+VFE_CLAMP_MAX_CFG                 = 0x000002EC,
+VFE_CLAMP_MIN_CFG                 = 0x000002F0,
+VFE_STATS_CMD                     = 0x000002F4,
+VFE_STATS_AF_CFG                  = 0x000002F8,
+VFE_STATS_AF_DIM                  = 0x000002FC,
+VFE_STATS_AF_GRID_0               = 0x00000300,
+VFE_STATS_AF_GRID_1               = 0x00000304,
+VFE_STATS_AF_GRID_2               = 0x00000308,
+VFE_STATS_AF_GRID_3               = 0x0000030C,
+VFE_STATS_AF_HEADER               = 0x00000310,
+VFE_STATS_AF_COEF0                = 0x00000314,
+VFE_STATS_AF_COEF1                = 0x00000318,
+VFE_STATS_AWBAE_CFG               = 0x0000031C,
+VFE_STATS_AXW_HEADER              = 0x00000320,
+VFE_STATS_AWB_MCFG                = 0x00000324,
+VFE_STATS_AWB_CCFG1               = 0x00000328,
+VFE_STATS_AWB_CCFG2               = 0x0000032C,
+VFE_STATS_HIST_HEADER             = 0x00000330,
+VFE_STATS_HIST_INNER_OFFSET       = 0x00000334,
+VFE_STATS_HIST_INNER_DIM          = 0x00000338,
+VFE_STATS_FRAME_SIZE              = 0x0000033C,
+VFE_DMI_CFG                       = 0x00000340,
+VFE_DMI_ADDR                      = 0x00000344,
+VFE_DMI_DATA_HI                   = 0x00000348,
+VFE_DMI_DATA_LO                   = 0x0000034C,
+VFE_DMI_RAM_AUTO_LOAD_CMD         = 0x00000350,
+VFE_DMI_RAM_AUTO_LOAD_STATUS      = 0x00000354,
+VFE_DMI_RAM_AUTO_LOAD_CFG         = 0x00000358,
+VFE_DMI_RAM_AUTO_LOAD_SEED        = 0x0000035C,
+VFE_TESTBUS_SEL                   = 0x00000360,
+VFE_TESTGEN_CFG                   = 0x00000364,
+VFE_SW_TESTGEN_CMD                = 0x00000368,
+VFE_HW_TESTGEN_CMD                = 0x0000036C,
+VFE_HW_TESTGEN_CFG                = 0x00000370,
+VFE_HW_TESTGEN_IMAGE_CFG          = 0x00000374,
+VFE_HW_TESTGEN_SOF_OFFSET_CFG     = 0x00000378,
+VFE_HW_TESTGEN_EOF_NOFFSET_CFG    = 0x0000037C,
+VFE_HW_TESTGEN_SOL_OFFSET_CFG     = 0x00000380,
+VFE_HW_TESTGEN_EOL_NOFFSET_CFG    = 0x00000384,
+VFE_HW_TESTGEN_HBI_CFG            = 0x00000388,
+VFE_HW_TESTGEN_VBL_CFG            = 0x0000038C,
+VFE_HW_TESTGEN_SOF_DUMMY_LINE_CFG2 = 0x00000390,
+VFE_HW_TESTGEN_EOF_DUMMY_LINE_CFG2 = 0x00000394,
+VFE_HW_TESTGEN_COLOR_BARS_CFG     = 0x00000398,
+VFE_HW_TESTGEN_RANDOM_CFG         = 0x0000039C,
+VFE_SPARE                         = 0x000003A0,
+};
+
+#define ping 0x0
+#define pong 0x1
+
+struct vfe_bus_cfg_data {
+	boolean                  stripeRdPathEn;
+	boolean                  encYWrPathEn;
+	boolean                  encCbcrWrPathEn;
+	boolean                  viewYWrPathEn;
+	boolean                  viewCbcrWrPathEn;
+	enum VFE_RAW_PIXEL_DATA_SIZE rawPixelDataSize;
+	enum VFE_RAW_WR_PATH_SEL     rawWritePathSelect;
+};
+
+struct vfe_camif_cfg_data {
+	boolean camif2OutputEnable;
+	boolean camif2BusEnable;
+	struct vfe_cmds_camif_cfg camifCfgFromCmd;
+};
+
+struct vfe_irq_composite_mask_config {
+	uint8_t encIrqComMask;
+	uint8_t viewIrqComMask;
+	uint8_t ceDoneSel;
+};
+
+/* define a structure for each output path.*/
+struct vfe_output_path {
+	uint32_t addressBuffer[8];
+	uint16_t fragIndex;
+	boolean  hwCurrentFlag;
+	uint8_t  *hwRegPingAddress;
+	uint8_t  *hwRegPongAddress;
+};
+
+struct vfe_output_path_combo {
+	boolean           whichOutputPath;
+	boolean           pathEnabled;
+	boolean           multiFrag;
+	uint8_t           fragCount;
+	boolean           ackPending;
+	uint8_t           currentFrame;
+	uint32_t          nextFrameAddrBuf[8];
+	struct vfe_output_path   yPath;
+	struct vfe_output_path   cbcrPath;
+	uint8_t           snapshotPendingCount;
+	boolean           pmEnabled;
+	uint8_t           cbcrStatusBit;
+};
+
+struct vfe_stats_control {
+	boolean  ackPending;
+	uint32_t addressBuffer[2];
+	uint32_t nextFrameAddrBuf;
+	boolean  pingPongStatus;
+	uint8_t  *hwRegPingAddress;
+	uint8_t  *hwRegPongAddress;
+	uint32_t droppedStatsFrameCount;
+	uint32_t bufToRender;
+};
+
+struct vfe_gamma_lut_sel {
+	boolean  ch0BankSelect;
+	boolean  ch1BankSelect;
+	boolean  ch2BankSelect;
+};
+
+struct vfe_interrupt_mask {
+	boolean  camifErrorIrq;
+	boolean  camifSofIrq;
+	boolean  camifEolIrq;
+	boolean  camifEofIrq;
+	boolean  camifEpoch1Irq;
+	boolean  camifEpoch2Irq;
+	boolean  camifOverflowIrq;
+	boolean  ceIrq;
+	boolean  regUpdateIrq;
+	boolean  resetAckIrq;
+	boolean  encYPingpongIrq;
+	boolean  encCbcrPingpongIrq;
+	boolean  viewYPingpongIrq;
+	boolean  viewCbcrPingpongIrq;
+	boolean  rdPingpongIrq;
+	boolean  afPingpongIrq;
+	boolean  awbPingpongIrq;
+	boolean  histPingpongIrq;
+	boolean  encIrq;
+	boolean  viewIrq;
+	boolean  busOverflowIrq;
+	boolean  afOverflowIrq;
+	boolean  awbOverflowIrq;
+	boolean  syncTimer0Irq;
+	boolean  syncTimer1Irq;
+	boolean  syncTimer2Irq;
+	boolean  asyncTimer0Irq;
+	boolean  asyncTimer1Irq;
+	boolean  asyncTimer2Irq;
+	boolean  asyncTimer3Irq;
+	boolean  axiErrorIrq;
+	boolean  violationIrq;
+};
+
+enum vfe_interrupt_name {
+	CAMIF_ERROR_IRQ,
+	CAMIF_SOF_IRQ,
+	CAMIF_EOL_IRQ,
+	CAMIF_EOF_IRQ,
+	CAMIF_EPOCH1_IRQ,
+	CAMIF_EPOCH2_IRQ,
+	CAMIF_OVERFLOW_IRQ,
+	CE_IRQ,
+	REG_UPDATE_IRQ,
+	RESET_ACK_IRQ,
+	ENC_Y_PINGPONG_IRQ,
+	ENC_CBCR_PINGPONG_IRQ,
+	VIEW_Y_PINGPONG_IRQ,
+	VIEW_CBCR_PINGPONG_IRQ,
+	RD_PINGPONG_IRQ,
+	AF_PINGPONG_IRQ,
+	AWB_PINGPONG_IRQ,
+	HIST_PINGPONG_IRQ,
+	ENC_IRQ,
+	VIEW_IRQ,
+	BUS_OVERFLOW_IRQ,
+	AF_OVERFLOW_IRQ,
+	AWB_OVERFLOW_IRQ,
+	SYNC_TIMER0_IRQ,
+	SYNC_TIMER1_IRQ,
+	SYNC_TIMER2_IRQ,
+	ASYNC_TIMER0_IRQ,
+	ASYNC_TIMER1_IRQ,
+	ASYNC_TIMER2_IRQ,
+	ASYNC_TIMER3_IRQ,
+	AXI_ERROR_IRQ,
+	VIOLATION_IRQ
+};
+
+enum VFE_DMI_RAM_SEL {
+	NO_MEM_SELECTED          = 0,
+	ROLLOFF_RAM              = 0x1,
+	RGBLUT_RAM_CH0_BANK0     = 0x2,
+	RGBLUT_RAM_CH0_BANK1     = 0x3,
+	RGBLUT_RAM_CH1_BANK0     = 0x4,
+	RGBLUT_RAM_CH1_BANK1     = 0x5,
+	RGBLUT_RAM_CH2_BANK0     = 0x6,
+	RGBLUT_RAM_CH2_BANK1     = 0x7,
+	STATS_HIST_CB_EVEN_RAM   = 0x8,
+	STATS_HIST_CB_ODD_RAM    = 0x9,
+	STATS_HIST_CR_EVEN_RAM   = 0xa,
+	STATS_HIST_CR_ODD_RAM    = 0xb,
+	RGBLUT_CHX_BANK0         = 0xc,
+	RGBLUT_CHX_BANK1         = 0xd,
+	LUMA_ADAPT_LUT_RAM_BANK0 = 0xe,
+	LUMA_ADAPT_LUT_RAM_BANK1 = 0xf
+};
+
+struct vfe_module_enable {
+	boolean  blackLevelCorrectionEnable;
+	boolean  lensRollOffEnable;
+	boolean  demuxEnable;
+	boolean  chromaUpsampleEnable;
+	boolean  demosaicEnable;
+	boolean  statsEnable;
+	boolean  cropEnable;
+	boolean  mainScalerEnable;
+	boolean  whiteBalanceEnable;
+	boolean  colorCorrectionEnable;
+	boolean  yHistEnable;
+	boolean  skinToneEnable;
+	boolean  lumaAdaptationEnable;
+	boolean  rgbLUTEnable;
+	boolean  chromaEnhanEnable;
+	boolean  asfEnable;
+	boolean  chromaSuppressionEnable;
+	boolean  chromaSubsampleEnable;
+	boolean  scaler2YEnable;
+	boolean  scaler2CbcrEnable;
+};
+
+struct vfe_bus_cmd_data {
+	boolean  stripeReload;
+	boolean  busPingpongReload;
+	boolean  statsPingpongReload;
+};
+
+struct vfe_stats_cmd_data {
+	boolean  autoFocusEnable;
+	boolean  axwEnable;
+	boolean  histEnable;
+	boolean  clearHistEnable;
+	boolean  histAutoClearEnable;
+	boolean  colorConversionEnable;
+};
+
+struct vfe_hw_ver {
+	uint32_t minorVersion:8;
+	uint32_t majorVersion:8;
+	uint32_t coreVersion:4;
+	uint32_t /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_cfg {
+	uint32_t pixelPattern:3;
+	uint32_t /* reserved */ : 13;
+	uint32_t inputSource:2;
+	uint32_t /* reserved */ : 14;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_buscmd {
+	uint32_t  stripeReload:1;
+	uint32_t  /* reserved */ : 3;
+	uint32_t  busPingpongReload:1;
+	uint32_t  statsPingpongReload:1;
+	uint32_t  /* reserved */ : 26;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_Irq_Composite_MaskType {
+	uint32_t  encIrqComMaskBits:2;
+	uint32_t  viewIrqComMaskBits:2;
+	uint32_t  ceDoneSelBits:5;
+	uint32_t  /* reserved */ : 23;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_mod_enable {
+	uint32_t blackLevelCorrectionEnable:1;
+	uint32_t lensRollOffEnable:1;
+	uint32_t demuxEnable:1;
+	uint32_t chromaUpsampleEnable:1;
+	uint32_t demosaicEnable:1;
+	uint32_t statsEnable:1;
+	uint32_t cropEnable:1;
+	uint32_t mainScalerEnable:1;
+	uint32_t whiteBalanceEnable:1;
+	uint32_t colorCorrectionEnable:1;
+	uint32_t yHistEnable:1;
+	uint32_t skinToneEnable:1;
+	uint32_t lumaAdaptationEnable:1;
+	uint32_t rgbLUTEnable:1;
+	uint32_t chromaEnhanEnable:1;
+	uint32_t asfEnable:1;
+	uint32_t chromaSuppressionEnable:1;
+	uint32_t chromaSubsampleEnable:1;
+	uint32_t scaler2YEnable:1;
+	uint32_t scaler2CbcrEnable:1;
+	uint32_t /* reserved */ : 14;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_irqenable {
+	uint32_t camifErrorIrq:1;
+	uint32_t camifSofIrq:1;
+	uint32_t camifEolIrq:1;
+	uint32_t camifEofIrq:1;
+	uint32_t camifEpoch1Irq:1;
+	uint32_t camifEpoch2Irq:1;
+	uint32_t camifOverflowIrq:1;
+	uint32_t ceIrq:1;
+	uint32_t regUpdateIrq:1;
+	uint32_t resetAckIrq:1;
+	uint32_t encYPingpongIrq:1;
+	uint32_t encCbcrPingpongIrq:1;
+	uint32_t viewYPingpongIrq:1;
+	uint32_t viewCbcrPingpongIrq:1;
+	uint32_t rdPingpongIrq:1;
+	uint32_t afPingpongIrq:1;
+	uint32_t awbPingpongIrq:1;
+	uint32_t histPingpongIrq:1;
+	uint32_t encIrq:1;
+	uint32_t viewIrq:1;
+	uint32_t busOverflowIrq:1;
+	uint32_t afOverflowIrq:1;
+	uint32_t awbOverflowIrq:1;
+	uint32_t syncTimer0Irq:1;
+	uint32_t syncTimer1Irq:1;
+	uint32_t syncTimer2Irq:1;
+	uint32_t asyncTimer0Irq:1;
+	uint32_t asyncTimer1Irq:1;
+	uint32_t asyncTimer2Irq:1;
+	uint32_t asyncTimer3Irq:1;
+	uint32_t axiErrorIrq:1;
+	uint32_t violationIrq:1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_upsample_cfg {
+	uint32_t chromaCositingForYCbCrInputs:1;
+	uint32_t /* reserved */ : 31;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_CAMIFConfigType {
+	/* CAMIF Config */
+	uint32_t  /* reserved */ : 1;
+	uint32_t  VSyncEdge:1;
+	uint32_t  HSyncEdge:1;
+	uint32_t  syncMode:2;
+	uint32_t  vfeSubsampleEnable:1;
+	uint32_t  /* reserved */ : 1;
+	uint32_t  busSubsampleEnable:1;
+	uint32_t  camif2vfeEnable:1;
+	uint32_t  /* reserved */ : 1;
+	uint32_t  camif2busEnable:1;
+	uint32_t  irqSubsampleEnable:1;
+	uint32_t  binningEnable:1;
+	uint32_t  /* reserved */ : 18;
+	uint32_t  misrEnable:1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_camifcfg {
+	/* EFS_Config */
+	uint32_t efsEndOfLine:8;
+	uint32_t efsStartOfLine:8;
+	uint32_t efsEndOfFrame:8;
+	uint32_t efsStartOfFrame:8;
+	/* Frame Config */
+	uint32_t frameConfigPixelsPerLine:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t frameConfigLinesPerFrame:14;
+	uint32_t /* reserved */ : 2;
+	/* Window Width Config */
+	uint32_t windowWidthCfgLastPixel:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t windowWidthCfgFirstPixel:14;
+	uint32_t /* reserved */ : 2;
+	/* Window Height Config */
+	uint32_t windowHeightCfglastLine:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t windowHeightCfgfirstLine:14;
+	uint32_t /* reserved */ : 2;
+	/* Subsample 1 Config */
+	uint32_t subsample1CfgPixelSkip:16;
+	uint32_t subsample1CfgLineSkip:16;
+	/* Subsample 2 Config */
+	uint32_t subsample2CfgFrameSkip:4;
+	uint32_t subsample2CfgFrameSkipMode:1;
+	uint32_t subsample2CfgPixelSkipWrap:1;
+	uint32_t /* reserved */ : 26;
+	/* Epoch Interrupt */
+	uint32_t epoch1Line:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t epoch2Line:14;
+	uint32_t /* reserved */ : 2;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_camifframe_update {
+	uint32_t pixelsPerLine:14;
+	uint32_t /* reserved */ : 2;
+	uint32_t linesPerFrame:14;
+	uint32_t /* reserved */ : 2;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_axi_bus_cfg {
+	uint32_t  stripeRdPathEn:1;
+	uint32_t  /* reserved */ : 3;
+	uint32_t  encYWrPathEn:1;
+	uint32_t  encCbcrWrPathEn:1;
+	uint32_t  viewYWrPathEn:1;
+	uint32_t  viewCbcrWrPathEn:1;
+	uint32_t  rawPixelDataSize:2;
+	uint32_t  rawWritePathSelect:2;
+	uint32_t  /* reserved */ : 20;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_axi_out_cfg {
+	uint32_t  out2YPingAddr:32;
+	uint32_t  out2YPongAddr:32;
+	uint32_t  out2YImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out2YImageWidthin64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out2YBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out2YNumRows:12;
+	uint32_t  out2YRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out2CbcrPingAddr:32;
+	uint32_t  out2CbcrPongAddr:32;
+	uint32_t  out2CbcrImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out2CbcrImageWidthIn64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out2CbcrBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out2CbcrNumRows:12;
+	uint32_t  out2CbcrRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1YPingAddr:32;
+	uint32_t  out1YPongAddr:32;
+	uint32_t  out1YImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1YImageWidthin64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out1YBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out1YNumRows:12;
+	uint32_t  out1YRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1CbcrPingAddr:32;
+	uint32_t  out1CbcrPongAddr:32;
+	uint32_t  out1CbcrImageHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  out1CbcrImageWidthIn64bit:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  out1CbcrBurstLength:2;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  out1CbcrNumRows:12;
+	uint32_t  out1CbcrRowIncrementIn64bit:12;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_output_clamp_cfg {
+	/* Output Clamp Maximums */
+	uint32_t yChanMax:8;
+	uint32_t cbChanMax:8;
+	uint32_t crChanMax:8;
+	uint32_t /* reserved */ : 8;
+	/* Output Clamp Minimums */
+	uint32_t yChanMin:8;
+	uint32_t cbChanMin:8;
+	uint32_t crChanMin:8;
+	uint32_t /* reserved */ : 8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_fov_crop_cfg {
+	uint32_t lastPixel:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstPixel:12;
+	uint32_t /* reserved */ : 4;
+
+	/* FOV Corp, Part 2 */
+	uint32_t lastLine:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstLine:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_FRAME_SKIP_UpdateCmdType {
+	uint32_t  yPattern:32;
+	uint32_t  cbcrPattern:32;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_frame_skip_cfg {
+	/* Frame Drop Enc (output2) */
+	uint32_t output2YPeriod:5;
+	uint32_t /* reserved */	: 27;
+	uint32_t output2CbCrPeriod:5;
+	uint32_t /* reserved */ : 27;
+	uint32_t output2YPattern:32;
+	uint32_t output2CbCrPattern:32;
+	/* Frame Drop View (output1) */
+	uint32_t output1YPeriod:5;
+	uint32_t /* reserved */ : 27;
+	uint32_t output1CbCrPeriod:5;
+	uint32_t /* reserved */ : 27;
+	uint32_t output1YPattern:32;
+	uint32_t output1CbCrPattern:32;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_main_scaler_cfg {
+	/* Scaler Enable Config */
+	uint32_t hEnable:1;
+	uint32_t vEnable:1;
+	uint32_t /* reserved */ : 30;
+	/* Scale H Image Size Config */
+	uint32_t inWidth:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t outWidth:12;
+	uint32_t /* reserved */ : 4;
+	/* Scale H Phase Config */
+	uint32_t horizPhaseMult:18;
+	uint32_t /* reserved */ : 2;
+	uint32_t horizInterResolution:2;
+	uint32_t /* reserved */ : 10;
+	/* Scale H Stripe Config */
+	uint32_t horizMNInit:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t horizPhaseInit:15;
+	uint32_t /* reserved */ : 1;
+	/* Scale V Image Size Config */
+	uint32_t inHeight:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t outHeight:12;
+	uint32_t /* reserved */ : 4;
+	/* Scale V Phase Config */
+	uint32_t vertPhaseMult:18;
+	uint32_t /* reserved */ : 2;
+	uint32_t vertInterResolution:2;
+	uint32_t /* reserved */ : 10;
+	/* Scale V Stripe Config */
+	uint32_t vertMNInit:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t vertPhaseInit:15;
+	uint32_t /* reserved */ : 1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_scaler2_cfg {
+	/* Scaler   Enable Config */
+	uint32_t  hEnable:1;
+	uint32_t  vEnable:1;
+	uint32_t  /* reserved */ : 30;
+	/* Scaler   H Image Size Config */
+	uint32_t  inWidth:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  outWidth:12;
+	uint32_t  /* reserved */ : 4;
+	/* Scaler   H Phase Config */
+	uint32_t  horizPhaseMult:18;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  horizInterResolution:2;
+	uint32_t  /* reserved */ : 10;
+	/* Scaler   V Image Size Config */
+	uint32_t  inHeight:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  outHeight:12;
+	uint32_t  /* reserved */ : 4;
+	/* Scaler   V Phase Config */
+	uint32_t  vertPhaseMult:18;
+	uint32_t  /* reserved */ : 2;
+	uint32_t  vertInterResolution:2;
+	uint32_t  /* reserved */ : 10;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_rolloff_cfg {
+	/* Rolloff 0 Config */
+	uint32_t  gridWidth:9;
+	uint32_t  gridHeight:9;
+	uint32_t  yDelta:9;
+	uint32_t  /* reserved */ : 5;
+	/* Rolloff 1 Config*/
+	uint32_t  gridX:4;
+	uint32_t  gridY:4;
+	uint32_t  pixelX:9;
+	uint32_t  /* reserved */ : 3;
+	uint32_t  pixelY:9;
+	uint32_t  /* reserved */ : 3;
+	/* Rolloff 2 Config */
+	uint32_t  yDeltaAccum:12;
+	uint32_t  /* reserved */ : 20;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_asf_update {
+	/* ASF Config Command */
+	uint32_t smoothEnable:1;
+	uint32_t sharpMode:2;
+	uint32_t /* reserved */ : 1;
+	uint32_t smoothCoeff1:4;
+	uint32_t smoothCoeff0:8;
+	uint32_t pipeFlushCount:12;
+	uint32_t pipeFlushOvd:1;
+	uint32_t flushHaltOvd:1;
+	uint32_t cropEnable:1;
+	uint32_t /* reserved */ : 1;
+	/* Sharpening Config 0 */
+	uint32_t sharpThresholdE1:7;
+	uint32_t /* reserved */ : 1;
+	uint32_t sharpDegreeK1:5;
+	uint32_t /* reserved */ : 3;
+	uint32_t sharpDegreeK2:5;
+	uint32_t /* reserved */ : 3;
+	uint32_t normalizeFactor:7;
+	uint32_t /* reserved */ : 1;
+	/* Sharpening Config 1 */
+	uint32_t sharpThresholdE2:8;
+	uint32_t sharpThresholdE3:8;
+	uint32_t sharpThresholdE4:8;
+	uint32_t sharpThresholdE5:8;
+	/* Sharpening Coefficients 0 */
+	uint32_t F1Coeff0:6;
+	uint32_t F1Coeff1:6;
+	uint32_t F1Coeff2:6;
+	uint32_t F1Coeff3:6;
+	uint32_t F1Coeff4:6;
+	uint32_t /* reserved */ : 2;
+	/* Sharpening Coefficients 1 */
+	uint32_t F1Coeff5:6;
+	uint32_t F1Coeff6:6;
+	uint32_t F1Coeff7:6;
+	uint32_t F1Coeff8:7;
+	uint32_t /* reserved */ : 7;
+	/* Sharpening Coefficients 2 */
+	uint32_t F2Coeff0:6;
+	uint32_t F2Coeff1:6;
+	uint32_t F2Coeff2:6;
+	uint32_t F2Coeff3:6;
+	uint32_t F2Coeff4:6;
+	uint32_t /* reserved */ : 2;
+	/* Sharpening Coefficients 3 */
+	uint32_t F2Coeff5:6;
+	uint32_t F2Coeff6:6;
+	uint32_t F2Coeff7:6;
+	uint32_t F2Coeff8:7;
+	uint32_t /* reserved */ : 7;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_asfcrop_cfg {
+	/* ASF Crop Width Config */
+	uint32_t lastPixel:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstPixel:12;
+	uint32_t /* reserved */ : 4;
+	/* ASP Crop Height Config */
+	uint32_t lastLine:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t firstLine:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_chroma_suppress_cfg {
+	/* Chroma Suppress 0 Config */
+	uint32_t m1:8;
+	uint32_t m3:8;
+	uint32_t n1:3;
+	uint32_t /* reserved */ : 1;
+	uint32_t n3:3;
+	uint32_t /* reserved */ : 9;
+	/* Chroma Suppress 1 Config */
+	uint32_t mm1:8;
+	uint32_t nn1:3;
+	uint32_t /* reserved */ : 21;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_chromasubsample_cfg {
+	/* Chroma Subsample Selection */
+	uint32_t  hCositedPhase:1;
+	uint32_t  vCositedPhase:1;
+	uint32_t  hCosited:1;
+	uint32_t  vCosited:1;
+	uint32_t  hsubSampleEnable:1;
+	uint32_t  vsubSampleEnable:1;
+	uint32_t  cropEnable:1;
+	uint32_t  /* reserved */ : 25;
+	uint32_t  cropWidthLastPixel:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  cropWidthFirstPixel:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  cropHeightLastLine:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  cropHeightFirstLine:12;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_blacklevel_cfg {
+	/* Black Even-Even Value Config */
+	uint32_t    evenEvenAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+	/* Black Even-Odd Value Config */
+	uint32_t    evenOddAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+	/* Black Odd-Even Value Config */
+	uint32_t    oddEvenAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+	/* Black Odd-Odd Value Config */
+	uint32_t    oddOddAdjustment:9;
+	uint32_t   /* reserved */ : 23;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demux_cfg {
+	/* Demux Gain 0 Config */
+	uint32_t  ch0EvenGain:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  ch0OddGain:10;
+	uint32_t  /* reserved */ : 6;
+	/* Demux Gain 1 Config */
+	uint32_t  ch1Gain:10;
+	uint32_t  /* reserved */ : 6;
+	uint32_t  ch2Gain:10;
+	uint32_t  /* reserved */ : 6;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_bps_info {
+  uint32_t greenBadPixelCount:8;
+  uint32_t /* reserved */ : 8;
+  uint32_t RedBlueBadPixelCount:8;
+  uint32_t /* reserved */ : 8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demosaic_cfg {
+	/* Demosaic Config */
+	uint32_t abfEnable:1;
+	uint32_t badPixelCorrEnable:1;
+	uint32_t forceAbfOn:1;
+	uint32_t /* reserved */ : 1;
+	uint32_t abfShift:4;
+	uint32_t fminThreshold:7;
+	uint32_t /* reserved */ : 1;
+	uint32_t fmaxThreshold:7;
+	uint32_t /* reserved */ : 5;
+	uint32_t slopeShift:3;
+	uint32_t /* reserved */ : 1;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demosaic_bpc_cfg {
+	/* Demosaic BPC Config 0 */
+	uint32_t blueDiffThreshold:12;
+	uint32_t redDiffThreshold:12;
+	uint32_t /* reserved */ : 8;
+	/* Demosaic BPC Config 1 */
+	uint32_t greenDiffThreshold:12;
+	uint32_t /* reserved */ : 20;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_demosaic_abf_cfg {
+	/* Demosaic ABF Config 0 */
+	uint32_t lpThreshold:10;
+	uint32_t /* reserved */ : 22;
+	/* Demosaic ABF Config 1 */
+	uint32_t ratio:4;
+	uint32_t minValue:10;
+	uint32_t /* reserved */ : 2;
+	uint32_t maxValue:10;
+	uint32_t /* reserved */ : 6;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_color_correction_cfg {
+	/* Color Corr. Coefficient 0 Config */
+	uint32_t   c0:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 1 Config */
+	uint32_t   c1:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 2 Config */
+	uint32_t   c2:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 3 Config */
+	uint32_t   c3:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 4 Config */
+	uint32_t   c4:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 5 Config */
+	uint32_t   c5:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 6 Config */
+	uint32_t   c6:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 7 Config */
+	uint32_t   c7:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Coefficient 8 Config */
+	uint32_t   c8:12;
+	uint32_t   /* reserved */ : 20;
+	/* Color Corr. Offset 0 Config */
+	uint32_t   k0:11;
+	uint32_t   /* reserved */ : 21;
+	/* Color Corr. Offset 1 Config */
+	uint32_t   k1:11;
+	uint32_t   /* reserved */ : 21;
+	/* Color Corr. Offset 2 Config */
+	uint32_t   k2:11;
+	uint32_t   /* reserved */ : 21;
+	/* Color Corr. Coefficient Q Config */
+	uint32_t   coefQFactor:2;
+	uint32_t   /* reserved */ : 30;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_LumaAdaptation_ConfigCmdType {
+	/* LA Config */
+	uint32_t   lutBankSelect:1;
+	uint32_t   /* reserved */ : 31;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_wb_cfg {
+	/* WB Config */
+	uint32_t ch0Gain:9;
+	uint32_t ch1Gain:9;
+	uint32_t ch2Gain:9;
+	uint32_t /* reserved */ : 5;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_GammaLutSelect_ConfigCmdType {
+	/* LUT Bank Select Config */
+	uint32_t   ch0BankSelect:1;
+	uint32_t   ch1BankSelect:1;
+	uint32_t   ch2BankSelect:1;
+	uint32_t   /* reserved */ : 29;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_chroma_enhance_cfg {
+	/* Chroma Enhance A Config */
+	uint32_t ap:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t am:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance B Config */
+	uint32_t bp:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t bm:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance C Config */
+	uint32_t cp:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t cm:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance D Config */
+	uint32_t dp:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t dm:11;
+	uint32_t /* reserved */ : 5;
+	/* Chroma Enhance K Config */
+	uint32_t kcb:11;
+	uint32_t /* reserved */ : 5;
+	uint32_t kcr:11;
+	uint32_t /* reserved */ : 5;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_color_convert_cfg {
+	/* Conversion Coefficient 0 */
+	uint32_t v0:12;
+	uint32_t /* reserved */ : 20;
+	/* Conversion Coefficient 1 */
+	uint32_t v1:12;
+	uint32_t /* reserved */ : 20;
+	/* Conversion Coefficient 2 */
+	uint32_t v2:12;
+	uint32_t /* reserved */ : 20;
+	/* Conversion Offset */
+	uint32_t ConvertOffset:8;
+	uint32_t /* reserved */ : 24;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_SyncTimer_ConfigCmdType {
+	/* Timer Line Start Config */
+	uint32_t       timerLineStart:12;
+	uint32_t       /* reserved */ : 20;
+	/* Timer Pixel Start Config */
+	uint32_t       timerPixelStart:18;
+	uint32_t       /* reserved */ : 14;
+	/* Timer Pixel Duration Config */
+	uint32_t       timerPixelDuration:28;
+	uint32_t       /* reserved */ : 4;
+	/* Sync Timer Polarity Config */
+	uint32_t       timer0Polarity:1;
+	uint32_t       timer1Polarity:1;
+	uint32_t       timer2Polarity:1;
+	uint32_t       /* reserved */ : 29;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AsyncTimer_ConfigCmdType {
+	/* Async Timer Config 0 */
+	uint32_t     inactiveLength:20;
+	uint32_t     numRepetition:10;
+	uint32_t     /* reserved */ : 1;
+	uint32_t     polarity:1;
+	/* Async Timer Config 1 */
+	uint32_t     activeLength:20;
+	uint32_t     /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AWBAEStatistics_ConfigCmdType {
+	/* AWB autoexposure Config */
+	uint32_t    aeRegionConfig:1;
+	uint32_t    aeSubregionConfig:1;
+	uint32_t    /* reserved */ : 14;
+	uint32_t    awbYMin:8;
+	uint32_t    awbYMax:8;
+	/* AXW Header */
+	uint32_t    axwHeader:8;
+	uint32_t    /* reserved */ : 24;
+	/* AWB Mconfig */
+	uint32_t    m4:8;
+	uint32_t    m3:8;
+	uint32_t    m2:8;
+	uint32_t    m1:8;
+	/* AWB Cconfig */
+	uint32_t    c2:12;
+	uint32_t    /* reserved */ : 4;
+	uint32_t    c1:12;
+	uint32_t    /* reserved */ : 4;
+	/* AWB Cconfig 2 */
+	uint32_t    c4:12;
+	uint32_t    /* reserved */ : 4;
+	uint32_t    c3:12;
+	uint32_t    /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_TestGen_ConfigCmdType {
+	/* HW Test Gen Config */
+	uint32_t   numFrame:10;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   pixelDataSelect:1;
+	uint32_t   systematicDataSelect:1;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   pixelDataSize:2;
+	uint32_t   hsyncEdge:1;
+	uint32_t   vsyncEdge:1;
+	uint32_t   /* reserved */ : 12;
+	/* HW Test Gen Image Config */
+	uint32_t   imageWidth:14;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   imageHeight:14;
+	uint32_t   /* reserved */ : 2;
+	/* SOF Offset Config */
+	uint32_t   sofOffset:24;
+	uint32_t   /* reserved */ : 8;
+	/* EOF NOffset Config */
+	uint32_t   eofNOffset:24;
+	uint32_t   /* reserved */ : 8;
+	/* SOL Offset Config */
+	uint32_t   solOffset:9;
+	uint32_t   /* reserved */ : 23;
+	/* EOL NOffset Config */
+	uint32_t   eolNOffset:9;
+	uint32_t   /* reserved */ : 23;
+	/* HBI Config */
+	uint32_t   hBlankInterval:14;
+	uint32_t   /* reserved */ : 18;
+	/* VBL Config */
+	uint32_t   vBlankInterval:14;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   vBlankIntervalEnable:1;
+	uint32_t   /* reserved */ : 15;
+	/* SOF Dummy Line Config */
+	uint32_t   sofDummy:8;
+	uint32_t   /* reserved */ : 24;
+	/* EOF Dummy Line Config */
+	uint32_t   eofDummy:8;
+	uint32_t   /* reserved */ : 24;
+	/* Color Bars Config */
+	uint32_t   unicolorBarSelect:3;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   unicolorBarEnable:1;
+	uint32_t   splitEnable:1;
+	uint32_t   pixelPattern:2;
+	uint32_t   rotatePeriod:6;
+	uint32_t   /* reserved */ : 18;
+	/* Random Config */
+	uint32_t   randomSeed:16;
+	uint32_t   /* reserved */ : 16;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_Bus_Pm_ConfigCmdType {
+	/* VFE Bus Performance Monitor Config */
+	uint32_t  output2YWrPmEnable:1;
+	uint32_t  output2CbcrWrPmEnable:1;
+	uint32_t  output1YWrPmEnable:1;
+	uint32_t  output1CbcrWrPmEnable:1;
+	uint32_t  /* reserved */ : 28;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_asf_info {
+	/* asf max edge  */
+	uint32_t maxEdge:13;
+	uint32_t /* reserved */ : 3;
+	/* HBi count  */
+	uint32_t HBICount:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_camif_stats {
+  uint32_t  pixelCount:14;
+  uint32_t  /* reserved */ : 2;
+  uint32_t  lineCount:14;
+  uint32_t  /* reserved */ : 1;
+  uint32_t  camifHalt:1;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_StatsCmdType {
+	uint32_t  autoFocusEnable:1;
+	uint32_t  axwEnable:1;
+	uint32_t  histEnable:1;
+	uint32_t  clearHistEnable:1;
+	uint32_t  histAutoClearEnable:1;
+	uint32_t  colorConversionEnable:1;
+	uint32_t  /* reserved */ : 26;
+} __attribute__((packed, aligned(4)));
+
+
+struct vfe_statsframe {
+	uint32_t lastPixel:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t lastLine:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_busstats_wrprio {
+	uint32_t afBusPriority:4;
+	uint32_t awbBusPriority:4;
+	uint32_t histBusPriority:4;
+	uint32_t afBusPriorityEn:1;
+	uint32_t awbBusPriorityEn:1;
+	uint32_t histBusPriorityEn:1;
+	uint32_t /* reserved */ : 17;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsaf_update {
+	/* VFE_STATS_AF_CFG */
+	uint32_t windowVOffset:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t windowHOffset:12;
+	uint32_t /* reserved */ : 3;
+	uint32_t windowMode:1;
+
+	/* VFE_STATS_AF_DIM */
+	uint32_t windowHeight:12;
+	uint32_t /* reserved */ : 4;
+	uint32_t windowWidth:12;
+	uint32_t /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsaf_cfg {
+	/* VFE_STATS_AF_GRID_0 */
+	uint32_t  entry00:8;
+	uint32_t  entry01:8;
+	uint32_t  entry02:8;
+	uint32_t  entry03:8;
+
+	/* VFE_STATS_AF_GRID_1 */
+	uint32_t  entry10:8;
+	uint32_t  entry11:8;
+	uint32_t  entry12:8;
+	uint32_t  entry13:8;
+
+	/* VFE_STATS_AF_GRID_2 */
+	uint32_t  entry20:8;
+	uint32_t  entry21:8;
+	uint32_t  entry22:8;
+	uint32_t  entry23:8;
+
+	/* VFE_STATS_AF_GRID_3 */
+	uint32_t  entry30:8;
+	uint32_t  entry31:8;
+	uint32_t  entry32:8;
+	uint32_t  entry33:8;
+
+	/* VFE_STATS_AF_HEADER */
+	uint32_t  afHeader:8;
+	uint32_t  /* reserved */ : 24;
+	/*  VFE_STATS_AF_COEF0 */
+	uint32_t  a00:5;
+	uint32_t  a04:5;
+	uint32_t  fvMax:11;
+	uint32_t  fvMetric:1;
+	uint32_t  /* reserved */ : 10;
+
+	/* VFE_STATS_AF_COEF1 */
+	uint32_t  a20:5;
+	uint32_t  a21:5;
+	uint32_t  a22:5;
+	uint32_t  a23:5;
+	uint32_t  a24:5;
+	uint32_t  /* reserved */ : 7;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsawbae_update {
+	uint32_t  aeRegionCfg:1;
+	uint32_t  aeSubregionCfg:1;
+	uint32_t  /* reserved */ : 14;
+	uint32_t  awbYMin:8;
+	uint32_t  awbYMax:8;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsaxw_hdr_cfg {
+	/* Stats AXW Header Config */
+	uint32_t axwHeader:8;
+	uint32_t /* reserved */ : 24;
+} __attribute__((packed, aligned(4)));
+
+struct vfe_statsawb_update {
+	/* AWB MConfig */
+	uint32_t  m4:8;
+	uint32_t  m3:8;
+	uint32_t  m2:8;
+	uint32_t  m1:8;
+
+	/* AWB CConfig1 */
+	uint32_t  c2:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  c1:12;
+	uint32_t  /* reserved */ : 4;
+
+	/* AWB CConfig2 */
+	uint32_t  c4:12;
+	uint32_t  /* reserved */ : 4;
+	uint32_t  c3:12;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_SyncTimerCmdType {
+	uint32_t  hsyncCount:12;
+	uint32_t  /* reserved */ : 20;
+	uint32_t  pclkCount:18;
+	uint32_t  /* reserved */ : 14;
+	uint32_t  outputDuration:28;
+	uint32_t  /* reserved */ : 4;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AsyncTimerCmdType {
+	/*  config 0 */
+	uint32_t    inactiveCount:20;
+	uint32_t    repeatCount:10;
+	uint32_t    /* reserved */ : 1;
+	uint32_t    polarity:1;
+	/*  config 1 */
+	uint32_t    activeCount:20;
+	uint32_t    /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AxiInputCmdType {
+	uint32_t   stripeStartAddr0:32;
+	uint32_t   stripeStartAddr1:32;
+	uint32_t   stripeStartAddr2:32;
+	uint32_t   stripeStartAddr3:32;
+
+	uint32_t   ySize:12;
+	uint32_t   yOffsetDelta:12;
+	uint32_t   /* reserved */ : 8;
+
+	/* bus_stripe_rd_hSize */
+	uint32_t   /* reserved */ : 16;
+	uint32_t   xSizeWord:10;
+	uint32_t   /* reserved */ : 6;
+
+	/* bus_stripe_rd_buffer_cfg */
+	uint32_t   burstLength:2;
+	uint32_t   /* reserved */ : 2;
+	uint32_t   NumOfRows:12;
+	uint32_t   RowIncrement:12;
+	uint32_t   /* reserved */ : 4;
+
+	/* bus_stripe_rd_unpack_cfg */
+	uint32_t   mainUnpackHeight:12;
+	uint32_t   mainUnpackWidth:13;
+	uint32_t   mainUnpackHbiSel:3;
+	uint32_t   mainUnpackPhase:3;
+	uint32_t   /* reserved */ : 1;
+
+	/* bus_stripe_rd_unpack */
+	uint32_t   unpackPattern:32;
+
+	/* bus_stripe_rd_pad_size */
+	uint32_t   padLeft:7;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   padRight:7;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   padTop:7;
+	uint32_t   /* reserved */ : 1;
+	uint32_t   padBottom:7;
+	uint32_t   /* reserved */ : 1;
+
+	/* bus_stripe_rd_pad_L_unpack */
+	uint32_t   leftUnpackPattern0:4;
+	uint32_t   leftUnpackPattern1:4;
+	uint32_t   leftUnpackPattern2:4;
+	uint32_t   leftUnpackPattern3:4;
+	uint32_t   leftUnpackStop0:1;
+	uint32_t   leftUnpackStop1:1;
+	uint32_t   leftUnpackStop2:1;
+	uint32_t   leftUnpackStop3:1;
+	uint32_t   /* reserved */ : 12;
+
+	/* bus_stripe_rd_pad_R_unpack */
+	uint32_t   rightUnpackPattern0:4;
+	uint32_t   rightUnpackPattern1:4;
+	uint32_t   rightUnpackPattern2:4;
+	uint32_t   rightUnpackPattern3:4;
+	uint32_t   rightUnpackStop0:1;
+	uint32_t   rightUnpackStop1:1;
+	uint32_t   rightUnpackStop2:1;
+	uint32_t   rightUnpackStop3:1;
+	uint32_t   /* reserved */ : 12;
+
+	/* bus_stripe_rd_pad_tb_unpack */
+	uint32_t   topUnapckPattern:4;
+	uint32_t   /* reserved */ : 12;
+	uint32_t   bottomUnapckPattern:4;
+	uint32_t   /* reserved */ : 12;
+} __attribute__((packed, aligned(4)));
+
+struct VFE_AxiRdFragIrqEnable {
+	uint32_t stripeRdFragirq0Enable:1;
+	uint32_t stripeRdFragirq1Enable:1;
+	uint32_t stripeRdFragirq2Enable:1;
+	uint32_t stripeRdFragirq3Enable:1;
+	uint32_t   /* reserved */ : 28;
+} __attribute__((packed, aligned(4)));
+
+int vfe_cmd_init(struct msm_vfe_callback *, struct platform_device *, void *);
+void vfe_stats_af_stop(void);
+void vfe_stop(void);
+void vfe_update(void);
+int vfe_rgb_gamma_update(struct vfe_cmd_rgb_gamma_config *);
+int vfe_rgb_gamma_config(struct vfe_cmd_rgb_gamma_config *);
+void vfe_stats_wb_exp_ack(struct vfe_cmd_stats_wb_exp_ack *);
+void vfe_stats_af_ack(struct vfe_cmd_stats_af_ack *);
+void vfe_start(struct vfe_cmd_start *);
+void vfe_la_update(struct vfe_cmd_la_config *);
+void vfe_la_config(struct vfe_cmd_la_config *);
+void vfe_test_gen_start(struct vfe_cmd_test_gen_start *);
+void vfe_frame_skip_update(struct vfe_cmd_frame_skip_update *);
+void vfe_frame_skip_config(struct vfe_cmd_frame_skip_config *);
+void vfe_output_clamp_config(struct vfe_cmd_output_clamp_config *);
+void vfe_camif_frame_update(struct vfe_cmds_camif_frame *);
+void vfe_color_correction_config(struct vfe_cmd_color_correction_config *);
+void vfe_demosaic_abf_update(struct vfe_cmd_demosaic_abf_update *);
+void vfe_demosaic_bpc_update(struct vfe_cmd_demosaic_bpc_update *);
+void vfe_demosaic_config(struct vfe_cmd_demosaic_config *);
+void vfe_demux_channel_gain_update(struct vfe_cmd_demux_channel_gain_config *);
+void vfe_demux_channel_gain_config(struct vfe_cmd_demux_channel_gain_config *);
+void vfe_black_level_update(struct vfe_cmd_black_level_config *);
+void vfe_black_level_config(struct vfe_cmd_black_level_config *);
+void vfe_asf_update(struct vfe_cmd_asf_update *);
+void vfe_asf_config(struct vfe_cmd_asf_config *);
+void vfe_white_balance_config(struct vfe_cmd_white_balance_config *);
+void vfe_chroma_sup_config(struct vfe_cmd_chroma_suppression_config *);
+void vfe_roll_off_config(struct vfe_cmd_roll_off_config *);
+void vfe_chroma_subsample_config(struct vfe_cmd_chroma_subsample_config *);
+void vfe_chroma_enhan_config(struct vfe_cmd_chroma_enhan_config *);
+void vfe_scaler2cbcr_config(struct vfe_cmd_scaler2_config *);
+void vfe_scaler2y_config(struct vfe_cmd_scaler2_config *);
+void vfe_main_scaler_config(struct vfe_cmd_main_scaler_config *);
+void vfe_stats_wb_exp_stop(void);
+void vfe_stats_update_wb_exp(struct vfe_cmd_stats_wb_exp_update *);
+void vfe_stats_update_af(struct vfe_cmd_stats_af_update *);
+void vfe_stats_start_wb_exp(struct vfe_cmd_stats_wb_exp_start *);
+void vfe_stats_start_af(struct vfe_cmd_stats_af_start *);
+void vfe_stats_setting(struct vfe_cmd_stats_setting *);
+void vfe_axi_input_config(struct vfe_cmd_axi_input_config *);
+void vfe_stats_config(struct vfe_cmd_stats_setting *);
+void vfe_axi_output_config(struct vfe_cmd_axi_output_config *);
+void vfe_camif_config(struct vfe_cmd_camif_config *);
+void vfe_fov_crop_config(struct vfe_cmd_fov_crop_config *);
+void vfe_get_hw_version(struct vfe_cmd_hw_version *);
+void vfe_reset(void);
+void vfe_cmd_release(struct platform_device *);
+void vfe_output1_ack(struct vfe_cmd_output_ack *);
+void vfe_output2_ack(struct vfe_cmd_output_ack *);
+#endif /* __MSM_VFE8X_REG_H__ */
diff --git a/drivers/staging/dream/camera/mt9d112.c b/drivers/staging/dream/camera/mt9d112.c
new file mode 100644
index 0000000..4f938f9
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9d112.c
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include "mt9d112.h"
+
+/* Micron MT9D112 Registers and their values */
+/* Sensor Core Registers */
+#define  REG_MT9D112_MODEL_ID 0x3000
+#define  MT9D112_MODEL_ID     0x1580
+
+/*  SOC Registers Page 1  */
+#define  REG_MT9D112_SENSOR_RESET     0x301A
+#define  REG_MT9D112_STANDBY_CONTROL  0x3202
+#define  REG_MT9D112_MCU_BOOT         0x3386
+
+struct mt9d112_work {
+	struct work_struct work;
+};
+
+static struct  mt9d112_work *mt9d112_sensorw;
+static struct  i2c_client *mt9d112_client;
+
+struct mt9d112_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+};
+
+
+static struct mt9d112_ctrl *mt9d112_ctrl;
+
+static DECLARE_WAIT_QUEUE_HEAD(mt9d112_wait_queue);
+DECLARE_MUTEX(mt9d112_sem);
+
+
+/*=============================================================
+	EXTERNAL DECLARATIONS
+==============================================================*/
+extern struct mt9d112_reg mt9d112_regs;
+
+
+/*=============================================================*/
+
+static int mt9d112_reset(const struct msm_camera_sensor_info *dev)
+{
+	int rc = 0;
+
+	rc = gpio_request(dev->sensor_reset, "mt9d112");
+
+	if (!rc) {
+		rc = gpio_direction_output(dev->sensor_reset, 0);
+		mdelay(20);
+		rc = gpio_direction_output(dev->sensor_reset, 1);
+	}
+
+	gpio_free(dev->sensor_reset);
+	return rc;
+}
+
+static int32_t mt9d112_i2c_txdata(unsigned short saddr,
+	unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+			.addr = saddr,
+			.flags = 0,
+			.len = length,
+			.buf = txdata,
+		},
+	};
+
+	if (i2c_transfer(mt9d112_client->adapter, msg, 1) < 0) {
+		CDBG("mt9d112_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9d112_i2c_write(unsigned short saddr,
+	unsigned short waddr, unsigned short wdata, enum mt9d112_width width)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	switch (width) {
+	case WORD_LEN: {
+		buf[0] = (waddr & 0xFF00)>>8;
+		buf[1] = (waddr & 0x00FF);
+		buf[2] = (wdata & 0xFF00)>>8;
+		buf[3] = (wdata & 0x00FF);
+
+		rc = mt9d112_i2c_txdata(saddr, buf, 4);
+	}
+		break;
+
+	case BYTE_LEN: {
+		buf[0] = waddr;
+		buf[1] = wdata;
+		rc = mt9d112_i2c_txdata(saddr, buf, 2);
+	}
+		break;
+
+	default:
+		break;
+	}
+
+	if (rc < 0)
+		CDBG(
+		"i2c_write failed, addr = 0x%x, val = 0x%x!\n",
+		waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9d112_i2c_write_table(
+	struct mt9d112_i2c_reg_conf const *reg_conf_tbl,
+	int num_of_items_in_table)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num_of_items_in_table; i++) {
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			reg_conf_tbl->waddr, reg_conf_tbl->wdata,
+			reg_conf_tbl->width);
+		if (rc < 0)
+			break;
+		if (reg_conf_tbl->mdelay_time != 0)
+			mdelay(reg_conf_tbl->mdelay_time);
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int mt9d112_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+	{
+		.addr   = saddr,
+		.flags = 0,
+		.len   = 2,
+		.buf   = rxdata,
+	},
+	{
+		.addr   = saddr,
+		.flags = I2C_M_RD,
+		.len   = length,
+		.buf   = rxdata,
+	},
+	};
+
+	if (i2c_transfer(mt9d112_client->adapter, msgs, 2) < 0) {
+		CDBG("mt9d112_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9d112_i2c_read(unsigned short   saddr,
+	unsigned short raddr, unsigned short *rdata, enum mt9d112_width width)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	switch (width) {
+	case WORD_LEN: {
+		buf[0] = (raddr & 0xFF00)>>8;
+		buf[1] = (raddr & 0x00FF);
+
+		rc = mt9d112_i2c_rxdata(saddr, buf, 2);
+		if (rc < 0)
+			return rc;
+
+		*rdata = buf[0] << 8 | buf[1];
+	}
+		break;
+
+	default:
+		break;
+	}
+
+	if (rc < 0)
+		CDBG("mt9d112_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9d112_set_lens_roll_off(void)
+{
+	int32_t rc = 0;
+	rc = mt9d112_i2c_write_table(&mt9d112_regs.rftbl[0],
+								 mt9d112_regs.rftbl_size);
+	return rc;
+}
+
+static long mt9d112_reg_init(void)
+{
+	int32_t array_length;
+	int32_t i;
+	long rc;
+
+	/* PLL Setup Start */
+	rc = mt9d112_i2c_write_table(&mt9d112_regs.plltbl[0],
+					mt9d112_regs.plltbl_size);
+
+	if (rc < 0)
+		return rc;
+	/* PLL Setup End   */
+
+	array_length = mt9d112_regs.prev_snap_reg_settings_size;
+
+	/* Configure sensor for Preview mode and Snapshot mode */
+	for (i = 0; i < array_length; i++) {
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+		  mt9d112_regs.prev_snap_reg_settings[i].register_address,
+		  mt9d112_regs.prev_snap_reg_settings[i].register_value,
+		  WORD_LEN);
+
+		if (rc < 0)
+			return rc;
+	}
+
+	/* Configure for Noise Reduction, Saturation and Aperture Correction */
+	array_length = mt9d112_regs.noise_reduction_reg_settings_size;
+
+	for (i = 0; i < array_length; i++) {
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			mt9d112_regs.noise_reduction_reg_settings[i].register_address,
+			mt9d112_regs.noise_reduction_reg_settings[i].register_value,
+			WORD_LEN);
+
+		if (rc < 0)
+			return rc;
+	}
+
+	/* Set Color Kill Saturation point to optimum value */
+	rc =
+	mt9d112_i2c_write(mt9d112_client->addr,
+	0x35A4,
+	0x0593,
+	WORD_LEN);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d112_i2c_write_table(&mt9d112_regs.stbl[0],
+					mt9d112_regs.stbl_size);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d112_set_lens_roll_off();
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+static long mt9d112_set_sensor_mode(int mode)
+{
+	uint16_t clock;
+	long rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA20C, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0004, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA215, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0004, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA20B, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0000, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		clock = 0x0250;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x341C, clock, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA103, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0001, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		/* Switch to lower fps for Snapshot */
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x341C, 0x0120, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA120, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0002, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x338C, 0xA103, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9d112_i2c_write(mt9d112_client->addr,
+				0x3390, 0x0002, WORD_LEN);
+		if (rc < 0)
+			return rc;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static long mt9d112_set_effect(int mode, int effect)
+{
+	uint16_t reg_addr;
+	uint16_t reg_val;
+	long rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		/* Context A Special Effects */
+		reg_addr = 0x2799;
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		/* Context B Special Effects */
+		reg_addr = 0x279B;
+		break;
+
+	default:
+		reg_addr = 0x2799;
+		break;
+	}
+
+	switch (effect) {
+	case CAMERA_EFFECT_OFF: {
+		reg_val = 0x6440;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+			break;
+
+	case CAMERA_EFFECT_MONO: {
+		reg_val = 0x6441;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	case CAMERA_EFFECT_NEGATIVE: {
+		reg_val = 0x6443;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	case CAMERA_EFFECT_SOLARIZE: {
+		reg_val = 0x6445;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	case CAMERA_EFFECT_SEPIA: {
+		reg_val = 0x6442;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+	}
+		break;
+
+	case CAMERA_EFFECT_PASTEL:
+	case CAMERA_EFFECT_MOSAIC:
+	case CAMERA_EFFECT_RESIZE:
+		return -EINVAL;
+
+	default: {
+		reg_val = 0x6440;
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x338C, reg_addr, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9d112_i2c_write(mt9d112_client->addr,
+			0x3390, reg_val, WORD_LEN);
+		if (rc < 0)
+			return rc;
+
+		return -EINVAL;
+	}
+	}
+
+	/* Refresh Sequencer */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		0x338C, 0xA103, WORD_LEN);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		0x3390, 0x0005, WORD_LEN);
+
+	return rc;
+}
+
+static int mt9d112_sensor_init_probe(const struct msm_camera_sensor_info *data)
+{
+	uint16_t model_id = 0;
+	int rc = 0;
+
+	CDBG("init entry \n");
+	rc = mt9d112_reset(data);
+	if (rc < 0) {
+		CDBG("reset failed!\n");
+		goto init_probe_fail;
+	}
+
+	mdelay(5);
+
+	/* Micron suggested Power up block Start:
+	* Put MCU into Reset - Stop MCU */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_MCU_BOOT, 0x0501, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* Pull MCU from Reset - Start MCU */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_MCU_BOOT, 0x0500, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	mdelay(5);
+
+	/* Micron Suggested - Power up block */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_SENSOR_RESET, 0x0ACC, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		REG_MT9D112_STANDBY_CONTROL, 0x0008, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* FUSED_DEFECT_CORRECTION */
+	rc = mt9d112_i2c_write(mt9d112_client->addr,
+		0x33F4, 0x031D, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	mdelay(5);
+
+	/* Micron suggested Power up block End */
+	/* Read the Model ID of the sensor */
+	rc = mt9d112_i2c_read(mt9d112_client->addr,
+		REG_MT9D112_MODEL_ID, &model_id, WORD_LEN);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	CDBG("mt9d112 model_id = 0x%x\n", model_id);
+
+	/* Check if it matches it with the value in Datasheet */
+	if (model_id != MT9D112_MODEL_ID) {
+		rc = -EINVAL;
+		goto init_probe_fail;
+	}
+
+	rc = mt9d112_reg_init();
+	if (rc < 0)
+		goto init_probe_fail;
+
+	return rc;
+
+init_probe_fail:
+	return rc;
+}
+
+int mt9d112_sensor_init(const struct msm_camera_sensor_info *data)
+{
+	int rc = 0;
+
+	mt9d112_ctrl = kzalloc(sizeof(struct mt9d112_ctrl), GFP_KERNEL);
+	if (!mt9d112_ctrl) {
+		CDBG("mt9d112_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	if (data)
+		mt9d112_ctrl->sensordata = data;
+
+	/* Input MCLK = 24MHz */
+	msm_camio_clk_rate_set(24000000);
+	mdelay(5);
+
+	msm_camio_camif_pad_reg_reset();
+
+	rc = mt9d112_sensor_init_probe(data);
+	if (rc < 0) {
+		CDBG("mt9d112_sensor_init failed!\n");
+		goto init_fail;
+	}
+
+init_done:
+	return rc;
+
+init_fail:
+	kfree(mt9d112_ctrl);
+	return rc;
+}
+
+static int mt9d112_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9d112_wait_queue);
+	return 0;
+}
+
+int mt9d112_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cfg_data;
+	long   rc = 0;
+
+	if (copy_from_user(&cfg_data,
+			(void *)argp,
+			sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	/* down(&mt9d112_sem); */
+
+	CDBG("mt9d112_ioctl, cfgtype = %d, mode = %d\n",
+		cfg_data.cfgtype, cfg_data.mode);
+
+		switch (cfg_data.cfgtype) {
+		case CFG_SET_MODE:
+			rc = mt9d112_set_sensor_mode(
+						cfg_data.mode);
+			break;
+
+		case CFG_SET_EFFECT:
+			rc = mt9d112_set_effect(cfg_data.mode,
+						cfg_data.cfg.effect);
+			break;
+
+		case CFG_GET_AF_MAX_STEPS:
+		default:
+			rc = -EINVAL;
+			break;
+		}
+
+	/* up(&mt9d112_sem); */
+
+	return rc;
+}
+
+int mt9d112_sensor_release(void)
+{
+	int rc = 0;
+
+	/* down(&mt9d112_sem); */
+
+	kfree(mt9d112_ctrl);
+	/* up(&mt9d112_sem); */
+
+	return rc;
+}
+
+static int mt9d112_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		rc = -ENOTSUPP;
+		goto probe_failure;
+	}
+
+	mt9d112_sensorw =
+		kzalloc(sizeof(struct mt9d112_work), GFP_KERNEL);
+
+	if (!mt9d112_sensorw) {
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9d112_sensorw);
+	mt9d112_init_client(client);
+	mt9d112_client = client;
+
+	CDBG("mt9d112_probe succeeded!\n");
+
+	return 0;
+
+probe_failure:
+	kfree(mt9d112_sensorw);
+	mt9d112_sensorw = NULL;
+	CDBG("mt9d112_probe failed!\n");
+	return rc;
+}
+
+static const struct i2c_device_id mt9d112_i2c_id[] = {
+	{ "mt9d112", 0},
+	{ },
+};
+
+static struct i2c_driver mt9d112_i2c_driver = {
+	.id_table = mt9d112_i2c_id,
+	.probe  = mt9d112_i2c_probe,
+	.remove = __exit_p(mt9d112_i2c_remove),
+	.driver = {
+		.name = "mt9d112",
+	},
+};
+
+static int mt9d112_sensor_probe(const struct msm_camera_sensor_info *info,
+				struct msm_sensor_ctrl *s)
+{
+	int rc = i2c_add_driver(&mt9d112_i2c_driver);
+	if (rc < 0 || mt9d112_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	/* Input MCLK = 24MHz */
+	msm_camio_clk_rate_set(24000000);
+	mdelay(5);
+
+	rc = mt9d112_sensor_init_probe(info);
+	if (rc < 0)
+		goto probe_done;
+
+	s->s_init = mt9d112_sensor_init;
+	s->s_release = mt9d112_sensor_release;
+	s->s_config  = mt9d112_sensor_config;
+
+probe_done:
+	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
+	return rc;
+}
+
+static int __mt9d112_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9d112_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9d112_probe,
+	.driver = {
+		.name = "msm_camera_mt9d112",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9d112_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9d112_init);
diff --git a/drivers/staging/dream/camera/mt9d112.h b/drivers/staging/dream/camera/mt9d112.h
new file mode 100644
index 0000000..c678996
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9d112.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#ifndef MT9D112_H
+#define MT9D112_H
+
+#include <linux/types.h>
+#include <mach/camera.h>
+
+enum mt9d112_width {
+	WORD_LEN,
+	BYTE_LEN
+};
+
+struct mt9d112_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+	enum mt9d112_width width;
+	unsigned short mdelay_time;
+};
+
+struct mt9d112_reg {
+	const struct register_address_value_pair *prev_snap_reg_settings;
+	uint16_t prev_snap_reg_settings_size;
+	const struct register_address_value_pair *noise_reduction_reg_settings;
+	uint16_t noise_reduction_reg_settings_size;
+	const struct mt9d112_i2c_reg_conf *plltbl;
+	uint16_t plltbl_size;
+	const struct mt9d112_i2c_reg_conf *stbl;
+	uint16_t stbl_size;
+	const struct mt9d112_i2c_reg_conf *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* MT9D112_H */
diff --git a/drivers/staging/dream/camera/mt9d112_reg.c b/drivers/staging/dream/camera/mt9d112_reg.c
new file mode 100644
index 0000000..c52e96f
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9d112_reg.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#include "mt9d112.h"
+
+struct register_address_value_pair
+preview_snapshot_mode_reg_settings_array[] = {
+	{0x338C, 0x2703},
+	{0x3390, 800},    /* Output Width (P) = 640 */
+	{0x338C, 0x2705},
+	{0x3390, 600},    /* Output Height (P) = 480 */
+	{0x338C, 0x2707},
+	{0x3390, 0x0640}, /* Output Width (S) = 1600 */
+	{0x338C, 0x2709},
+	{0x3390, 0x04B0}, /* Output Height (S) = 1200 */
+	{0x338C, 0x270D},
+	{0x3390, 0x0000}, /* Row Start (P) = 0 */
+	{0x338C, 0x270F},
+	{0x3390, 0x0000}, /* Column Start (P) = 0 */
+	{0x338C, 0x2711},
+	{0x3390, 0x04BD}, /* Row End (P) = 1213 */
+	{0x338C, 0x2713},
+	{0x3390, 0x064D}, /* Column End (P) = 1613 */
+	{0x338C, 0x2715},
+	{0x3390, 0x0000}, /* Extra Delay (P) = 0 */
+	{0x338C, 0x2717},
+	{0x3390, 0x2111}, /* Row Speed (P) = 8465 */
+	{0x338C, 0x2719},
+	{0x3390, 0x046C}, /* Read Mode (P) = 1132 */
+	{0x338C, 0x271B},
+	{0x3390, 0x024F}, /* Sensor_Sample_Time_pck(P) = 591 */
+	{0x338C, 0x271D},
+	{0x3390, 0x0102}, /* Sensor_Fine_Correction(P) = 258 */
+	{0x338C, 0x271F},
+	{0x3390, 0x0279}, /* Sensor_Fine_IT_min(P) = 633 */
+	{0x338C, 0x2721},
+	{0x3390, 0x0155}, /* Sensor_Fine_IT_max_margin(P) = 341 */
+	{0x338C, 0x2723},
+	{0x3390, 659},    /* Frame Lines (P) = 679 */
+	{0x338C, 0x2725},
+	{0x3390, 0x0824}, /* Line Length (P) = 2084 */
+	{0x338C, 0x2727},
+	{0x3390, 0x2020},
+	{0x338C, 0x2729},
+	{0x3390, 0x2020},
+	{0x338C, 0x272B},
+	{0x3390, 0x1020},
+	{0x338C, 0x272D},
+	{0x3390, 0x2007},
+	{0x338C, 0x272F},
+	{0x3390, 0x0004}, /* Row Start(S) = 4 */
+	{0x338C, 0x2731},
+	{0x3390, 0x0004}, /* Column Start(S) = 4 */
+	{0x338C, 0x2733},
+	{0x3390, 0x04BB}, /* Row End(S) = 1211 */
+	{0x338C, 0x2735},
+	{0x3390, 0x064B}, /* Column End(S) = 1611 */
+	{0x338C, 0x2737},
+	{0x3390, 0x04CE}, /* Extra Delay(S) = 1230 */
+	{0x338C, 0x2739},
+	{0x3390, 0x2111}, /* Row Speed(S) = 8465 */
+	{0x338C, 0x273B},
+	{0x3390, 0x0024}, /* Read Mode(S) = 36 */
+	{0x338C, 0x273D},
+	{0x3390, 0x0120}, /* Sensor sample time pck(S) = 288 */
+	{0x338C, 0x2741},
+	{0x3390, 0x0169}, /* Sensor_Fine_IT_min(P) = 361 */
+	{0x338C, 0x2745},
+	{0x3390, 0x04FF}, /* Frame Lines(S) = 1279 */
+	{0x338C, 0x2747},
+	{0x3390, 0x0824}, /* Line Length(S) = 2084 */
+	{0x338C, 0x2751},
+	{0x3390, 0x0000}, /* Crop_X0(P) = 0 */
+	{0x338C, 0x2753},
+	{0x3390, 0x0320}, /* Crop_X1(P) = 800 */
+	{0x338C, 0x2755},
+	{0x3390, 0x0000}, /* Crop_Y0(P) = 0 */
+	{0x338C, 0x2757},
+	{0x3390, 0x0258}, /* Crop_Y1(P) = 600 */
+	{0x338C, 0x275F},
+	{0x3390, 0x0000}, /* Crop_X0(S) = 0 */
+	{0x338C, 0x2761},
+	{0x3390, 0x0640}, /* Crop_X1(S) = 1600 */
+	{0x338C, 0x2763},
+	{0x3390, 0x0000}, /* Crop_Y0(S) = 0 */
+	{0x338C, 0x2765},
+	{0x3390, 0x04B0}, /* Crop_Y1(S) = 1200 */
+	{0x338C, 0x222E},
+	{0x3390, 0x00A0}, /* R9 Step = 160 */
+	{0x338C, 0xA408},
+	{0x3390, 0x001F},
+	{0x338C, 0xA409},
+	{0x3390, 0x0021},
+	{0x338C, 0xA40A},
+	{0x3390, 0x0025},
+	{0x338C, 0xA40B},
+	{0x3390, 0x0027},
+	{0x338C, 0x2411},
+	{0x3390, 0x00A0},
+	{0x338C, 0x2413},
+	{0x3390, 0x00C0},
+	{0x338C, 0x2415},
+	{0x3390, 0x00A0},
+	{0x338C, 0x2417},
+	{0x3390, 0x00C0},
+	{0x338C, 0x2799},
+	{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(P) */
+	{0x338C, 0x279B},
+	{0x3390, 0x6408}, /* MODE_SPEC_EFFECTS(S) */
+};
+
+static struct register_address_value_pair
+noise_reduction_reg_settings_array[] = {
+	{0x338C, 0xA76D},
+	{0x3390, 0x0003},
+	{0x338C, 0xA76E},
+	{0x3390, 0x0003},
+	{0x338C, 0xA76F},
+	{0x3390, 0},
+	{0x338C, 0xA770},
+	{0x3390, 21},
+	{0x338C, 0xA771},
+	{0x3390, 37},
+	{0x338C, 0xA772},
+	{0x3390, 63},
+	{0x338C, 0xA773},
+	{0x3390, 100},
+	{0x338C, 0xA774},
+	{0x3390, 128},
+	{0x338C, 0xA775},
+	{0x3390, 151},
+	{0x338C, 0xA776},
+	{0x3390, 169},
+	{0x338C, 0xA777},
+	{0x3390, 186},
+	{0x338C, 0xA778},
+	{0x3390, 199},
+	{0x338C, 0xA779},
+	{0x3390, 210},
+	{0x338C, 0xA77A},
+	{0x3390, 220},
+	{0x338C, 0xA77B},
+	{0x3390, 228},
+	{0x338C, 0xA77C},
+	{0x3390, 234},
+	{0x338C, 0xA77D},
+	{0x3390, 240},
+	{0x338C, 0xA77E},
+	{0x3390, 244},
+	{0x338C, 0xA77F},
+	{0x3390, 248},
+	{0x338C, 0xA780},
+	{0x3390, 252},
+	{0x338C, 0xA781},
+	{0x3390, 255},
+	{0x338C, 0xA782},
+	{0x3390, 0},
+	{0x338C, 0xA783},
+	{0x3390, 21},
+	{0x338C, 0xA784},
+	{0x3390, 37},
+	{0x338C, 0xA785},
+	{0x3390, 63},
+	{0x338C, 0xA786},
+	{0x3390, 100},
+	{0x338C, 0xA787},
+	{0x3390, 128},
+	{0x338C, 0xA788},
+	{0x3390, 151},
+	{0x338C, 0xA789},
+	{0x3390, 169},
+	{0x338C, 0xA78A},
+	{0x3390, 186},
+	{0x338C, 0xA78B},
+	{0x3390, 199},
+	{0x338C, 0xA78C},
+	{0x3390, 210},
+	{0x338C, 0xA78D},
+	{0x3390, 220},
+	{0x338C, 0xA78E},
+	{0x3390, 228},
+	{0x338C, 0xA78F},
+	{0x3390, 234},
+	{0x338C, 0xA790},
+	{0x3390, 240},
+	{0x338C, 0xA791},
+	{0x3390, 244},
+	{0x338C, 0xA793},
+	{0x3390, 252},
+	{0x338C, 0xA794},
+	{0x3390, 255},
+	{0x338C, 0xA103},
+	{0x3390, 6},
+};
+
+static const struct mt9d112_i2c_reg_conf const lens_roll_off_tbl[] = {
+	{ 0x34CE, 0x81A0, WORD_LEN, 0 },
+	{ 0x34D0, 0x6331, WORD_LEN, 0 },
+	{ 0x34D2, 0x3394, WORD_LEN, 0 },
+	{ 0x34D4, 0x9966, WORD_LEN, 0 },
+	{ 0x34D6, 0x4B25, WORD_LEN, 0 },
+	{ 0x34D8, 0x2670, WORD_LEN, 0 },
+	{ 0x34DA, 0x724C, WORD_LEN, 0 },
+	{ 0x34DC, 0xFFFD, WORD_LEN, 0 },
+	{ 0x34DE, 0x00CA, WORD_LEN, 0 },
+	{ 0x34E6, 0x00AC, WORD_LEN, 0 },
+	{ 0x34EE, 0x0EE1, WORD_LEN, 0 },
+	{ 0x34F6, 0x0D87, WORD_LEN, 0 },
+	{ 0x3500, 0xE1F7, WORD_LEN, 0 },
+	{ 0x3508, 0x1CF4, WORD_LEN, 0 },
+	{ 0x3510, 0x1D28, WORD_LEN, 0 },
+	{ 0x3518, 0x1F26, WORD_LEN, 0 },
+	{ 0x3520, 0x2220, WORD_LEN, 0 },
+	{ 0x3528, 0x333D, WORD_LEN, 0 },
+	{ 0x3530, 0x15D9, WORD_LEN, 0 },
+	{ 0x3538, 0xCFB8, WORD_LEN, 0 },
+	{ 0x354C, 0x05FE, WORD_LEN, 0 },
+	{ 0x3544, 0x05F8, WORD_LEN, 0 },
+	{ 0x355C, 0x0596, WORD_LEN, 0 },
+	{ 0x3554, 0x0611, WORD_LEN, 0 },
+	{ 0x34E0, 0x00F2, WORD_LEN, 0 },
+	{ 0x34E8, 0x00A8, WORD_LEN, 0 },
+	{ 0x34F0, 0x0F7B, WORD_LEN, 0 },
+	{ 0x34F8, 0x0CD7, WORD_LEN, 0 },
+	{ 0x3502, 0xFEDB, WORD_LEN, 0 },
+	{ 0x350A, 0x13E4, WORD_LEN, 0 },
+	{ 0x3512, 0x1F2C, WORD_LEN, 0 },
+	{ 0x351A, 0x1D20, WORD_LEN, 0 },
+	{ 0x3522, 0x2422, WORD_LEN, 0 },
+	{ 0x352A, 0x2925, WORD_LEN, 0 },
+	{ 0x3532, 0x1D04, WORD_LEN, 0 },
+	{ 0x353A, 0xFBF2, WORD_LEN, 0 },
+	{ 0x354E, 0x0616, WORD_LEN, 0 },
+	{ 0x3546, 0x0597, WORD_LEN, 0 },
+	{ 0x355E, 0x05CD, WORD_LEN, 0 },
+	{ 0x3556, 0x0529, WORD_LEN, 0 },
+	{ 0x34E4, 0x00B2, WORD_LEN, 0 },
+	{ 0x34EC, 0x005E, WORD_LEN, 0 },
+	{ 0x34F4, 0x0F43, WORD_LEN, 0 },
+	{ 0x34FC, 0x0E2F, WORD_LEN, 0 },
+	{ 0x3506, 0xF9FC, WORD_LEN, 0 },
+	{ 0x350E, 0x0CE4, WORD_LEN, 0 },
+	{ 0x3516, 0x1E1E, WORD_LEN, 0 },
+	{ 0x351E, 0x1B19, WORD_LEN, 0 },
+	{ 0x3526, 0x151B, WORD_LEN, 0 },
+	{ 0x352E, 0x1416, WORD_LEN, 0 },
+	{ 0x3536, 0x10FC, WORD_LEN, 0 },
+	{ 0x353E, 0xC018, WORD_LEN, 0 },
+	{ 0x3552, 0x06B4, WORD_LEN, 0 },
+	{ 0x354A, 0x0506, WORD_LEN, 0 },
+	{ 0x3562, 0x06AB, WORD_LEN, 0 },
+	{ 0x355A, 0x063A, WORD_LEN, 0 },
+	{ 0x34E2, 0x00E5, WORD_LEN, 0 },
+	{ 0x34EA, 0x008B, WORD_LEN, 0 },
+	{ 0x34F2, 0x0E4C, WORD_LEN, 0 },
+	{ 0x34FA, 0x0CA3, WORD_LEN, 0 },
+	{ 0x3504, 0x0907, WORD_LEN, 0 },
+	{ 0x350C, 0x1DFD, WORD_LEN, 0 },
+	{ 0x3514, 0x1E24, WORD_LEN, 0 },
+	{ 0x351C, 0x2529, WORD_LEN, 0 },
+	{ 0x3524, 0x1D20, WORD_LEN, 0 },
+	{ 0x352C, 0x2332, WORD_LEN, 0 },
+	{ 0x3534, 0x10E9, WORD_LEN, 0 },
+	{ 0x353C, 0x0BCB, WORD_LEN, 0 },
+	{ 0x3550, 0x04EF, WORD_LEN, 0 },
+	{ 0x3548, 0x0609, WORD_LEN, 0 },
+	{ 0x3560, 0x0580, WORD_LEN, 0 },
+	{ 0x3558, 0x05DD, WORD_LEN, 0 },
+	{ 0x3540, 0x0000, WORD_LEN, 0 },
+	{ 0x3542, 0x0000, WORD_LEN, 0 }
+};
+
+static const struct mt9d112_i2c_reg_conf const pll_setup_tbl[] = {
+	{ 0x341E, 0x8F09, WORD_LEN, 0 },
+	{ 0x341C, 0x0250, WORD_LEN, 0 },
+	{ 0x341E, 0x8F09, WORD_LEN, 5 },
+	{ 0x341E, 0x8F08, WORD_LEN, 0 }
+};
+
+/* Refresh Sequencer */
+static const struct mt9d112_i2c_reg_conf const sequencer_tbl[] = {
+	{ 0x338C, 0x2799, WORD_LEN, 0},
+	{ 0x3390, 0x6440, WORD_LEN, 5},
+	{ 0x338C, 0x279B, WORD_LEN, 0},
+	{ 0x3390, 0x6440, WORD_LEN, 5},
+	{ 0x338C, 0xA103, WORD_LEN, 0},
+	{ 0x3390, 0x0005, WORD_LEN, 5},
+	{ 0x338C, 0xA103, WORD_LEN, 0},
+	{ 0x3390, 0x0006, WORD_LEN, 5}
+};
+
+struct mt9d112_reg mt9d112_regs = {
+	.prev_snap_reg_settings = &preview_snapshot_mode_reg_settings_array[0],
+	.prev_snap_reg_settings_size = ARRAY_SIZE(preview_snapshot_mode_reg_settings_array),
+	.noise_reduction_reg_settings = &noise_reduction_reg_settings_array[0],
+	.noise_reduction_reg_settings_size = ARRAY_SIZE(noise_reduction_reg_settings_array),
+	.plltbl = pll_setup_tbl,
+	.plltbl_size = ARRAY_SIZE(pll_setup_tbl),
+	.stbl = sequencer_tbl,
+	.stbl_size = ARRAY_SIZE(sequencer_tbl),
+	.rftbl = lens_roll_off_tbl,
+	.rftbl_size = ARRAY_SIZE(lens_roll_off_tbl)
+};
+
+
+
diff --git a/drivers/staging/dream/camera/mt9p012.h b/drivers/staging/dream/camera/mt9p012.h
new file mode 100644
index 0000000..678a002
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9p012.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+
+#ifndef MT9T012_H
+#define MT9T012_H
+
+#include <linux/types.h>
+
+struct reg_struct {
+	uint16_t vt_pix_clk_div;     /* 0x0300 */
+	uint16_t vt_sys_clk_div;     /* 0x0302 */
+	uint16_t pre_pll_clk_div;    /* 0x0304 */
+	uint16_t pll_multiplier;     /* 0x0306 */
+	uint16_t op_pix_clk_div;     /* 0x0308 */
+	uint16_t op_sys_clk_div;     /* 0x030A */
+	uint16_t scale_m;            /* 0x0404 */
+	uint16_t row_speed;          /* 0x3016 */
+	uint16_t x_addr_start;       /* 0x3004 */
+	uint16_t x_addr_end;         /* 0x3008 */
+	uint16_t y_addr_start;       /* 0x3002 */
+	uint16_t y_addr_end;         /* 0x3006 */
+	uint16_t read_mode;          /* 0x3040 */
+	uint16_t x_output_size ;     /* 0x034C */
+	uint16_t y_output_size;      /* 0x034E */
+	uint16_t line_length_pck;    /* 0x300C */
+	uint16_t frame_length_lines; /* 0x300A */
+	uint16_t coarse_int_time;    /* 0x3012 */
+	uint16_t fine_int_time;      /* 0x3014 */
+};
+
+
+struct mt9p012_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+
+struct mt9p012_reg {
+	struct reg_struct *reg_pat;
+	uint16_t reg_pat_size;
+	struct mt9p012_i2c_reg_conf *ttbl;
+	uint16_t ttbl_size;
+	struct mt9p012_i2c_reg_conf *lctbl;
+	uint16_t lctbl_size;
+	struct mt9p012_i2c_reg_conf *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* MT9T012_H */
diff --git a/drivers/staging/dream/camera/mt9p012_fox.c b/drivers/staging/dream/camera/mt9p012_fox.c
new file mode 100644
index 0000000..70119d5
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9p012_fox.c
@@ -0,0 +1,1305 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kernel.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "mt9p012.h"
+
+/*=============================================================
+    SENSOR REGISTER DEFINES
+==============================================================*/
+#define MT9P012_REG_MODEL_ID         0x0000
+#define MT9P012_MODEL_ID             0x2801
+#define REG_GROUPED_PARAMETER_HOLD   0x0104
+#define GROUPED_PARAMETER_HOLD       0x0100
+#define GROUPED_PARAMETER_UPDATE     0x0000
+#define REG_COARSE_INT_TIME          0x3012
+#define REG_VT_PIX_CLK_DIV           0x0300
+#define REG_VT_SYS_CLK_DIV           0x0302
+#define REG_PRE_PLL_CLK_DIV          0x0304
+#define REG_PLL_MULTIPLIER           0x0306
+#define REG_OP_PIX_CLK_DIV           0x0308
+#define REG_OP_SYS_CLK_DIV           0x030A
+#define REG_SCALE_M                  0x0404
+#define REG_FRAME_LENGTH_LINES       0x300A
+#define REG_LINE_LENGTH_PCK          0x300C
+#define REG_X_ADDR_START             0x3004
+#define REG_Y_ADDR_START             0x3002
+#define REG_X_ADDR_END               0x3008
+#define REG_Y_ADDR_END               0x3006
+#define REG_X_OUTPUT_SIZE            0x034C
+#define REG_Y_OUTPUT_SIZE            0x034E
+#define REG_FINE_INTEGRATION_TIME    0x3014
+#define REG_ROW_SPEED                0x3016
+#define MT9P012_REG_RESET_REGISTER   0x301A
+#define MT9P012_RESET_REGISTER_PWON  0x10CC
+#define MT9P012_RESET_REGISTER_PWOFF 0x10C8
+#define REG_READ_MODE                0x3040
+#define REG_GLOBAL_GAIN              0x305E
+#define REG_TEST_PATTERN_MODE        0x3070
+
+#define MT9P012_REV_7
+
+
+enum mt9p012_test_mode {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9p012_resolution {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum mt9p012_reg_update {
+	/* Sensor egisters that need to be updated during initialization */
+	REG_INIT,
+	/* Sensor egisters that needs periodic I2C writes */
+	UPDATE_PERIODIC,
+	/* All the sensor Registers will be updated */
+	UPDATE_ALL,
+	/* Not valid update */
+	UPDATE_INVALID
+};
+
+enum mt9p012_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+
+/* actuator's Slave Address */
+#define MT9P012_AF_I2C_ADDR   0x18
+
+/* AF Total steps parameters */
+#define MT9P012_STEPS_NEAR_TO_CLOSEST_INF  32
+#define MT9P012_TOTAL_STEPS_NEAR_TO_FAR    32
+
+#define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
+#define MT9P012_MU5M0_PREVIEW_DUMMY_LINES  0
+
+/* Time in milisecs for waiting for the sensor to reset.*/
+#define MT9P012_RESET_DELAY_MSECS   66
+
+/* for 20 fps preview */
+#define MT9P012_DEFAULT_CLOCK_RATE  24000000
+#define MT9P012_DEFAULT_MAX_FPS     26 /* ???? */
+
+struct mt9p012_work {
+	struct work_struct work;
+};
+static struct mt9p012_work *mt9p012_sensorw;
+static struct i2c_client *mt9p012_client;
+
+struct mt9p012_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider; /* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum mt9p012_resolution prev_res;
+	enum mt9p012_resolution pict_res;
+	enum mt9p012_resolution curr_res;
+	enum mt9p012_test_mode  set_test;
+};
+
+
+static struct mt9p012_ctrl *mt9p012_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue);
+DECLARE_MUTEX(mt9p012_sem);
+
+/*=============================================================
+	EXTERNAL DECLARATIONS
+==============================================================*/
+extern struct mt9p012_reg mt9p012_regs;	/* from mt9p012_reg.c */
+
+
+
+/*=============================================================*/
+
+static int mt9p012_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
+	int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr   = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr   = saddr,
+			.flags = I2C_M_RD,
+			.len   = length,
+			.buf   = rxdata,
+		},
+	};
+
+	if (i2c_transfer(mt9p012_client->adapter, msgs, 2) < 0) {
+		CDBG("mt9p012_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9p012_i2c_read_w(unsigned short saddr, unsigned short raddr,
+	unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00)>>8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = mt9p012_i2c_rxdata(saddr, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		CDBG("mt9p012_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_txdata(unsigned short saddr, unsigned char *txdata,
+	int length)
+{
+	struct i2c_msg msg[] = {
+		{
+		.addr  = saddr,
+		.flags = 0,
+		.len = length,
+		.buf = txdata,
+		},
+	};
+
+	if (i2c_transfer(mt9p012_client->adapter, msg, 1) < 0) {
+		CDBG("mt9p012_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9p012_i2c_write_b(unsigned short saddr, unsigned short baddr,
+	unsigned short bdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = baddr;
+	buf[1] = bdata;
+	rc = mt9p012_i2c_txdata(saddr, buf, 2);
+
+	if (rc < 0)
+		CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
+		saddr, baddr, bdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_write_w(unsigned short saddr, unsigned short waddr,
+	unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00)>>8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00)>>8;
+	buf[3] = (wdata & 0x00FF);
+
+	rc = mt9p012_i2c_txdata(saddr, buf, 4);
+
+	if (rc < 0)
+		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9p012_i2c_write_w_table(
+	struct mt9p012_i2c_reg_conf *reg_conf_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num; i++) {
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+			reg_conf_tbl->waddr, reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t mt9p012_test(enum mt9p012_test_mode mo)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	if (mo == TEST_OFF)
+		return 0;
+	else {
+		rc = mt9p012_i2c_write_w_table(mt9p012_regs.ttbl, mt9p012_regs.ttbl_size);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+				REG_TEST_PATTERN_MODE, (uint16_t)mo);
+		if (rc < 0)
+			return rc;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		REG_GROUPED_PARAMETER_HOLD,
+		GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9p012_lens_shading_enable(uint8_t is_enable)
+{
+	int32_t rc = 0;
+
+	CDBG("%s: entered. enable = %d\n", __func__, is_enable);
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x3780,
+		((uint16_t) is_enable) << 15);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE);
+
+	CDBG("%s: exiting. rc = %d\n", __func__, rc);
+	return rc;
+}
+
+static int32_t mt9p012_set_lc(void)
+{
+	int32_t rc;
+
+	rc = mt9p012_i2c_write_w_table(mt9p012_regs.lctbl, mt9p012_regs.lctbl_size);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9p012_i2c_write_w_table(mt9p012_regs.rftbl, mt9p012_regs.rftbl_size);
+
+	return rc;
+}
+
+static void mt9p012_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;   /*Q10 */
+	uint32_t pclk_mult; /*Q10 */
+
+	if (mt9p012_ctrl->prev_res == QTR_SIZE) {
+		divider = (uint32_t)
+		(((mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines *
+		mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck) * 0x00000400) /
+		(mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines *
+		mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck));
+
+		pclk_mult =
+		(uint32_t) ((mt9p012_regs.reg_pat[RES_CAPTURE].pll_multiplier *
+		0x00000400) / (mt9p012_regs.reg_pat[RES_PREVIEW].pll_multiplier));
+	} else {
+		/* full size resolution used for preview. */
+		divider   = 0x00000400;  /*1.0 */
+		pclk_mult = 0x00000400;  /*1.0 */
+	}
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps = (uint16_t) (fps * divider * pclk_mult / 0x00000400 /
+		0x00000400);
+}
+
+static uint16_t mt9p012_get_prev_lines_pf(void)
+{
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		return mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines;
+	else
+		return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_get_prev_pixels_pl(void)
+{
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		return mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck;
+	else
+		return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint16_t mt9p012_get_pict_lines_pf(void)
+{
+	return mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9p012_get_pict_pixels_pl(void)
+{
+	return mt9p012_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint32_t mt9p012_get_pict_max_exp_lc(void)
+{
+	uint16_t snapshot_lines_per_frame;
+
+	if (mt9p012_ctrl->pict_res == QTR_SIZE)
+		snapshot_lines_per_frame =
+		mt9p012_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
+	else
+		snapshot_lines_per_frame =
+		mt9p012_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
+
+	return snapshot_lines_per_frame * 24;
+}
+
+static int32_t mt9p012_set_fps(struct fps_cfg *fps)
+{
+	/* input is new fps in Q10 format */
+	int32_t rc = 0;
+
+	mt9p012_ctrl->fps_divider = fps->fps_div;
+	mt9p012_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	rc =
+		mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return -EBUSY;
+
+	rc =
+		mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_LINE_LENGTH_PCK,
+			(mt9p012_regs.reg_pat[RES_PREVIEW].line_length_pck *
+			fps->f_mult / 0x00000400));
+	if (rc < 0)
+		return rc;
+
+	rc =
+		mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+
+	return rc;
+}
+
+static int32_t mt9p012_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	uint16_t max_legal_gain = 0x01FF;
+	uint32_t line_length_ratio = 0x00000400;
+	enum mt9p012_setting setting;
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__);
+
+	if (mt9p012_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		mt9p012_ctrl->my_reg_gain = gain;
+		mt9p012_ctrl->my_reg_line_count = (uint16_t)line;
+	}
+
+	if (gain > max_legal_gain) {
+		CDBG("Max legal gain Line:%d \n", __LINE__);
+		gain = max_legal_gain;
+	}
+
+	/* Verify no overflow */
+	if (mt9p012_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
+		line = (uint32_t)(line * mt9p012_ctrl->fps_divider /
+			0x00000400);
+		setting = RES_PREVIEW;
+	} else {
+		line = (uint32_t)(line * mt9p012_ctrl->pict_fps_divider /
+			0x00000400);
+		setting = RES_CAPTURE;
+	}
+
+	/* Set digital gain to 1 */
+#ifdef MT9P012_REV_7
+	gain |= 0x1000;
+#else
+	gain |= 0x0200;
+#endif
+
+	if ((mt9p012_regs.reg_pat[setting].frame_length_lines - 1) < line) {
+		line_length_ratio = (uint32_t) (line * 0x00000400) /
+		(mt9p012_regs.reg_pat[setting].frame_length_lines - 1);
+	} else
+		line_length_ratio = 0x00000400;
+
+	rc =
+		mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	rc =
+		mt9p012_i2c_write_w(
+			mt9p012_client->addr,
+			REG_GLOBAL_GAIN, gain);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	rc =
+		mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_COARSE_INT_TIME,
+			line);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain, line);
+
+	rc =
+		mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+
+	return rc;
+}
+
+static int32_t mt9p012_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__);
+
+	rc =
+		mt9p012_write_exp_gain(gain, line);
+	if (rc < 0) {
+		CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
+			__LINE__);
+		return rc;
+	}
+
+	rc =
+	mt9p012_i2c_write_w(mt9p012_client->addr,
+		MT9P012_REG_RESET_REGISTER,
+		0x10CC | 0x0002);
+	if (rc < 0) {
+		CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__);
+		return rc;
+	}
+
+	mdelay(5);
+
+	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
+	return rc;
+}
+
+static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate,
+	enum mt9p012_setting rt)
+{
+	int32_t rc = 0;
+
+	switch (rupdate) {
+	case UPDATE_PERIODIC:
+	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+
+		struct mt9p012_i2c_reg_conf ppc_tbl[] = {
+		{REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD},
+		{REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed},
+		{REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start},
+		{REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end},
+		{REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start},
+		{REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end},
+		{REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode},
+		{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
+		{REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size},
+		{REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size},
+
+		{REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck},
+		{REG_FRAME_LENGTH_LINES,
+			(mt9p012_regs.reg_pat[rt].frame_length_lines *
+			mt9p012_ctrl->fps_divider / 0x00000400)},
+		{REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time},
+		{REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time},
+		{REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE},
+		};
+
+		rc = mt9p012_i2c_write_w_table(&ppc_tbl[0],
+			ARRAY_SIZE(ppc_tbl));
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_test(mt9p012_ctrl->set_test);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9p012_i2c_write_w(mt9p012_client->addr,
+			MT9P012_REG_RESET_REGISTER,
+			MT9P012_RESET_REGISTER_PWON | 0x0002);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5); /* 15? wait for sensor to transition*/
+
+		return rc;
+	}
+	break; /* UPDATE_PERIODIC */
+
+	case REG_INIT:
+	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+		struct mt9p012_i2c_reg_conf ipc_tbl1[] = {
+		{MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF},
+		{REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
+		{REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
+		{REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
+		{REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier},
+		{REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div},
+		{REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div},
+#ifdef MT9P012_REV_7
+		{0x30B0, 0x0001},
+		{0x308E, 0xE060},
+		{0x3092, 0x0A52},
+		{0x3094, 0x4656},
+		{0x3096, 0x5652},
+		{0x30CA, 0x8006},
+		{0x312A, 0xDD02},
+		{0x312C, 0x00E4},
+		{0x3170, 0x299A},
+#endif
+		/* optimized settings for noise */
+		{0x3088, 0x6FF6},
+		{0x3154, 0x0282},
+		{0x3156, 0x0381},
+		{0x3162, 0x04CE},
+		{0x0204, 0x0010},
+		{0x0206, 0x0010},
+		{0x0208, 0x0010},
+		{0x020A, 0x0010},
+		{0x020C, 0x0010},
+		{MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON},
+		};
+
+		struct mt9p012_i2c_reg_conf ipc_tbl2[] = {
+		{MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWOFF},
+		{REG_VT_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_pix_clk_div},
+		{REG_VT_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].vt_sys_clk_div},
+		{REG_PRE_PLL_CLK_DIV, mt9p012_regs.reg_pat[rt].pre_pll_clk_div},
+		{REG_PLL_MULTIPLIER, mt9p012_regs.reg_pat[rt].pll_multiplier},
+		{REG_OP_PIX_CLK_DIV, mt9p012_regs.reg_pat[rt].op_pix_clk_div},
+		{REG_OP_SYS_CLK_DIV, mt9p012_regs.reg_pat[rt].op_sys_clk_div},
+#ifdef MT9P012_REV_7
+		{0x30B0, 0x0001},
+		{0x308E, 0xE060},
+		{0x3092, 0x0A52},
+		{0x3094, 0x4656},
+		{0x3096, 0x5652},
+		{0x30CA, 0x8006},
+		{0x312A, 0xDD02},
+		{0x312C, 0x00E4},
+		{0x3170, 0x299A},
+#endif
+		/* optimized settings for noise */
+		{0x3088, 0x6FF6},
+		{0x3154, 0x0282},
+		{0x3156, 0x0381},
+		{0x3162, 0x04CE},
+		{0x0204, 0x0010},
+		{0x0206, 0x0010},
+		{0x0208, 0x0010},
+		{0x020A, 0x0010},
+		{0x020C, 0x0010},
+		{MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON},
+		};
+
+		struct mt9p012_i2c_reg_conf ipc_tbl3[] = {
+		{REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD},
+		/* Set preview or snapshot mode */
+		{REG_ROW_SPEED, mt9p012_regs.reg_pat[rt].row_speed},
+		{REG_X_ADDR_START, mt9p012_regs.reg_pat[rt].x_addr_start},
+		{REG_X_ADDR_END, mt9p012_regs.reg_pat[rt].x_addr_end},
+		{REG_Y_ADDR_START, mt9p012_regs.reg_pat[rt].y_addr_start},
+		{REG_Y_ADDR_END, mt9p012_regs.reg_pat[rt].y_addr_end},
+		{REG_READ_MODE, mt9p012_regs.reg_pat[rt].read_mode},
+		{REG_SCALE_M, mt9p012_regs.reg_pat[rt].scale_m},
+		{REG_X_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].x_output_size},
+		{REG_Y_OUTPUT_SIZE, mt9p012_regs.reg_pat[rt].y_output_size},
+		{REG_LINE_LENGTH_PCK, mt9p012_regs.reg_pat[rt].line_length_pck},
+		{REG_FRAME_LENGTH_LINES,
+			mt9p012_regs.reg_pat[rt].frame_length_lines},
+		{REG_COARSE_INT_TIME, mt9p012_regs.reg_pat[rt].coarse_int_time},
+		{REG_FINE_INTEGRATION_TIME, mt9p012_regs.reg_pat[rt].fine_int_time},
+		{REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE},
+		};
+
+		/* reset fps_divider */
+		mt9p012_ctrl->fps_divider = 1 * 0x0400;
+
+		rc = mt9p012_i2c_write_w_table(&ipc_tbl1[0],
+			ARRAY_SIZE(ipc_tbl1));
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_i2c_write_w_table(&ipc_tbl2[0],
+			ARRAY_SIZE(ipc_tbl2));
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc = mt9p012_i2c_write_w_table(&ipc_tbl3[0],
+			ARRAY_SIZE(ipc_tbl3));
+		if (rc < 0)
+			return rc;
+
+		/* load lens shading */
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_set_lc();
+		if (rc < 0)
+			return rc;
+
+		rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+			REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE);
+
+		if (rc < 0)
+			return rc;
+	}
+	break; /* case REG_INIT: */
+
+	default:
+		rc = -EINVAL;
+		break;
+	} /* switch (rupdate) */
+
+	return rc;
+}
+
+static int32_t mt9p012_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case QTR_SIZE:
+		rc = mt9p012_setting(UPDATE_PERIODIC, RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+
+		CDBG("mt9p012 sensor configuration done!\n");
+		break;
+
+	case FULL_SIZE:
+		rc =
+		mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+
+		break;
+
+	default:
+		return 0;
+	} /* switch */
+
+	mt9p012_ctrl->prev_res = res;
+	mt9p012_ctrl->curr_res = res;
+	mt9p012_ctrl->sensormode = mode;
+
+	rc =
+		mt9p012_write_exp_gain(mt9p012_ctrl->my_reg_gain,
+			mt9p012_ctrl->my_reg_line_count);
+
+	rc =
+		mt9p012_i2c_write_w(mt9p012_client->addr,
+			MT9P012_REG_RESET_REGISTER,
+			0x10cc|0x0002);
+
+	return rc;
+}
+
+static int32_t mt9p012_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
+
+	mt9p012_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9p012_ctrl->curr_res = mt9p012_ctrl->pict_res;
+
+	mt9p012_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t mt9p012_power_down(void)
+{
+	int32_t rc = 0;
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		MT9P012_REG_RESET_REGISTER,
+		MT9P012_RESET_REGISTER_PWOFF);
+
+	mdelay(5);
+	return rc;
+}
+
+static int32_t mt9p012_move_focus(int direction, int32_t num_steps)
+{
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_position;
+	uint8_t code_val_msb, code_val_lsb;
+
+	if (num_steps > MT9P012_TOTAL_STEPS_NEAR_TO_FAR)
+		num_steps = MT9P012_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (num_steps == 0) {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (direction == MOVE_NEAR)
+		step_direction = 16; /* 10bit */
+	else if (direction == MOVE_FAR)
+		step_direction = -16; /* 10 bit */
+	else {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	if (mt9p012_ctrl->curr_lens_pos < mt9p012_ctrl->init_curr_lens_pos)
+		mt9p012_ctrl->curr_lens_pos =
+			mt9p012_ctrl->init_curr_lens_pos;
+
+	actual_step = (int16_t)(step_direction * (int16_t)num_steps);
+	next_position = (int16_t)(mt9p012_ctrl->curr_lens_pos + actual_step);
+
+	if (next_position > 1023)
+		next_position = 1023;
+	else if (next_position < 0)
+		next_position = 0;
+
+	code_val_msb = next_position >> 4;
+	code_val_lsb = (next_position & 0x000F) << 4;
+	/* code_val_lsb |= mode_mask; */
+
+	/* Writing the digital code for current to the actuator */
+	if (mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
+		code_val_msb, code_val_lsb) < 0) {
+		CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__);
+		return -EBUSY;
+	}
+
+	/* Storing the current lens Position */
+	mt9p012_ctrl->curr_lens_pos = next_position;
+
+	return 0;
+}
+
+static int32_t mt9p012_set_default_focus(void)
+{
+	int32_t rc = 0;
+	uint8_t code_val_msb, code_val_lsb;
+
+	code_val_msb = 0x00;
+	code_val_lsb = 0x00;
+
+	/* Write the digital code for current to the actuator */
+	rc = mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR >> 1,
+		code_val_msb, code_val_lsb);
+
+	mt9p012_ctrl->curr_lens_pos = 0;
+	mt9p012_ctrl->init_curr_lens_pos = 0;
+
+	return rc;
+}
+
+static int mt9p012_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+	uint16_t chipid;
+
+	rc = gpio_request(data->sensor_reset, "mt9p012");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	mdelay(20);
+
+	/* RESET the sensor image part via I2C command */
+	CDBG("mt9p012_sensor_init(): reseting sensor.\n");
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		MT9P012_REG_RESET_REGISTER, 0x10CC|0x0001);
+	if (rc < 0) {
+		CDBG("sensor reset failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	mdelay(MT9P012_RESET_DELAY_MSECS);
+
+	/* 3. Read sensor Model ID: */
+	rc = mt9p012_i2c_read_w(mt9p012_client->addr,
+		MT9P012_REG_MODEL_ID, &chipid);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* 4. Compare sensor ID to MT9T012VC ID: */
+	if (chipid != MT9P012_MODEL_ID) {
+		CDBG("mt9p012 wrong model_id = 0x%x\n", chipid);
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x306E, 0x9000);
+	if (rc < 0) {
+		CDBG("REV_7 write failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* RESET_REGISTER, enable parallel interface and disable serialiser */
+	CDBG("mt9p012_sensor_init(): enabling parallel interface.\n");
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr, 0x301A, 0x10CC);
+	if (rc < 0) {
+		CDBG("enable parallel interface failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	/* To disable the 2 extra lines */
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		0x3064, 0x0805);
+
+	if (rc < 0) {
+		CDBG("disable the 2 extra lines failed. rc = %d\n", rc);
+		goto init_probe_fail;
+	}
+
+	mdelay(MT9P012_RESET_DELAY_MSECS);
+	goto init_probe_done;
+
+init_probe_fail:
+	mt9p012_probe_init_done(data);
+init_probe_done:
+	return rc;
+}
+
+static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+
+	mt9p012_ctrl = kzalloc(sizeof(struct mt9p012_ctrl), GFP_KERNEL);
+	if (!mt9p012_ctrl) {
+		CDBG("mt9p012_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	mt9p012_ctrl->fps_divider = 1 * 0x00000400;
+	mt9p012_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9p012_ctrl->set_test = TEST_OFF;
+	mt9p012_ctrl->prev_res = QTR_SIZE;
+	mt9p012_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9p012_ctrl->sensordata = data;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = mt9p012_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail1;
+
+	if (mt9p012_ctrl->prev_res == QTR_SIZE)
+		rc = mt9p012_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = mt9p012_setting(REG_INIT, RES_CAPTURE);
+
+	if (rc < 0) {
+		CDBG("mt9p012_setting failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* sensor : output enable */
+	CDBG("mt9p012_sensor_open_init(): enabling output.\n");
+	rc = mt9p012_i2c_write_w(mt9p012_client->addr,
+		MT9P012_REG_RESET_REGISTER, MT9P012_RESET_REGISTER_PWON);
+	if (rc < 0) {
+		CDBG("sensor output enable failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* TODO: enable AF actuator */
+#if 0
+	CDBG("enable AF actuator, gpio = %d\n",
+		mt9p012_ctrl->sensordata->vcm_pwd);
+	rc = gpio_request(mt9p012_ctrl->sensordata->vcm_pwd, "mt9p012");
+	if (!rc)
+		gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 1);
+	else {
+		CDBG("mt9p012_ctrl gpio request failed!\n");
+		goto init_fail1;
+	}
+	mdelay(20);
+
+	rc = mt9p012_set_default_focus();
+#endif
+	if (rc >= 0)
+		goto init_done;
+
+	/* TODO:
+	 * gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
+	 * gpio_free(mt9p012_ctrl->sensordata->vcm_pwd); */
+init_fail1:
+	mt9p012_probe_init_done(data);
+	kfree(mt9p012_ctrl);
+init_done:
+	return rc;
+}
+
+static int mt9p012_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9p012_wait_queue);
+	return 0;
+}
+
+static int32_t mt9p012_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = mt9p012_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = mt9p012_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = mt9p012_raw_snapshot_config(mode);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+int mt9p012_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	int rc = 0;
+
+	if (copy_from_user(&cdata,
+			(void *)argp,
+			sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	down(&mt9p012_sem);
+
+		CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		mt9p012_get_pict_fps(cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp, &cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = mt9p012_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = mt9p012_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = mt9p012_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl = mt9p012_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			mt9p012_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = mt9p012_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc = mt9p012_write_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
+		rc = mt9p012_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = mt9p012_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = mt9p012_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d cdata.cfg.focus.steps=%d\n",
+				cdata.cfg.focus.dir, cdata.cfg.focus.steps);
+		rc = mt9p012_move_focus(cdata.cfg.focus.dir,
+					cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = mt9p012_set_default_focus();
+		break;
+
+	case CFG_SET_LENS_SHADING:
+		CDBG("%s: CFG_SET_LENS_SHADING\n", __func__);
+		rc = mt9p012_lens_shading_enable(cdata.cfg.lens_shading);
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = MT9P012_STEPS_NEAR_TO_CLOSEST_INF;
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_EFFECT:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	up(&mt9p012_sem);
+	return rc;
+}
+
+int mt9p012_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	down(&mt9p012_sem);
+
+	mt9p012_power_down();
+
+	gpio_direction_output(mt9p012_ctrl->sensordata->sensor_reset,
+		0);
+	gpio_free(mt9p012_ctrl->sensordata->sensor_reset);
+
+	gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
+	gpio_free(mt9p012_ctrl->sensordata->vcm_pwd);
+
+	kfree(mt9p012_ctrl);
+	mt9p012_ctrl = NULL;
+
+	CDBG("mt9p012_release completed\n");
+
+	up(&mt9p012_sem);
+	return rc;
+}
+
+static int mt9p012_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("mt9p012_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	mt9p012_sensorw = kzalloc(sizeof(struct mt9p012_work), GFP_KERNEL);
+	if (!mt9p012_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9p012_sensorw);
+	mt9p012_init_client(client);
+	mt9p012_client = client;
+
+	mdelay(50);
+
+	CDBG("mt9p012_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("mt9p012_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static const struct i2c_device_id mt9p012_i2c_id[] = {
+	{ "mt9p012", 0},
+	{ }
+};
+
+static struct i2c_driver mt9p012_i2c_driver = {
+	.id_table = mt9p012_i2c_id,
+	.probe  = mt9p012_i2c_probe,
+	.remove = __exit_p(mt9p012_i2c_remove),
+	.driver = {
+		.name = "mt9p012",
+	},
+};
+
+static int mt9p012_sensor_probe(const struct msm_camera_sensor_info *info,
+				struct msm_sensor_ctrl *s)
+{
+	int rc = i2c_add_driver(&mt9p012_i2c_driver);
+	if (rc < 0 || mt9p012_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = mt9p012_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_done;
+
+	s->s_init = mt9p012_sensor_open_init;
+	s->s_release = mt9p012_sensor_release;
+	s->s_config  = mt9p012_sensor_config;
+	mt9p012_probe_init_done(info);
+
+probe_done:
+	CDBG("%s %s:%d\n", __FILE__, __func__, __LINE__);
+	return rc;
+}
+
+static int __mt9p012_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9p012_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9p012_probe,
+	.driver = {
+		.name = "msm_camera_mt9p012",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9p012_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9p012_init);
diff --git a/drivers/staging/dream/camera/mt9p012_reg.c b/drivers/staging/dream/camera/mt9p012_reg.c
new file mode 100644
index 0000000..e5223d6
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9p012_reg.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright (C) 2009 QUALCOMM Incorporated.
+ */
+
+#include "mt9p012.h"
+#include <linux/kernel.h>
+
+/*Micron settings from Applications for lower power consumption.*/
+struct reg_struct mt9p012_reg_pat[2] = {
+	{ /* Preview */
+		/* vt_pix_clk_div          REG=0x0300 */
+		6,  /* 5 */
+
+		/* vt_sys_clk_div          REG=0x0302 */
+		1,
+
+		/* pre_pll_clk_div         REG=0x0304 */
+		2,
+
+		/* pll_multiplier          REG=0x0306 */
+		60,
+
+		/* op_pix_clk_div          REG=0x0308 */
+		8,  /* 10 */
+
+		/* op_sys_clk_div          REG=0x030A */
+		1,
+
+		/* scale_m                 REG=0x0404 */
+		16,
+
+		/* row_speed               REG=0x3016 */
+		0x0111,
+
+		/* x_addr_start            REG=0x3004 */
+		8,
+
+		/* x_addr_end              REG=0x3008 */
+		2597,
+
+		/* y_addr_start            REG=0x3002 */
+		8,
+
+		/* y_addr_end              REG=0x3006 */
+		1949,
+
+		/* read_mode               REG=0x3040
+		 * Preview 2x2 skipping */
+		0x00C3,
+
+		/* x_output_size           REG=0x034C */
+		1296,
+
+		/* y_output_size           REG=0x034E */
+		972,
+
+		/* line_length_pck         REG=0x300C */
+		3784,
+
+		/* frame_length_lines      REG=0x300A */
+		1057,
+
+		/* coarse_integration_time REG=0x3012 */
+		16,
+
+		/* fine_integration_time   REG=0x3014 */
+		1764
+	},
+	{ /*Snapshot*/
+		/* vt_pix_clk_div          REG=0x0300 */
+		6,
+
+		/* vt_sys_clk_div          REG=0x0302 */
+		1,
+
+		/* pre_pll_clk_div         REG=0x0304 */
+		2,
+
+		/* pll_multiplier          REG=0x0306
+		 * 60 for 10fps snapshot */
+		60,
+
+		/* op_pix_clk_div          REG=0x0308 */
+		8,
+
+		/* op_sys_clk_div          REG=0x030A */
+		1,
+
+		/* scale_m                 REG=0x0404 */
+		16,
+
+		/* row_speed               REG=0x3016 */
+		0x0111,
+
+		/* x_addr_start            REG=0x3004 */
+		8,
+
+		/* x_addr_end              REG=0x3008 */
+		2615,
+
+		/* y_addr_start            REG=0x3002 */
+		8,
+
+		/* y_addr_end              REG=0x3006 */
+		1967,
+
+		/* read_mode               REG=0x3040 */
+		0x0041,
+
+		/* x_output_size           REG=0x034C */
+		2608,
+
+		/* y_output_size           REG=0x034E */
+		1960,
+
+		/* line_length_pck         REG=0x300C */
+		3911,
+
+		/* frame_length_lines      REG=0x300A //10 fps snapshot */
+		2045,
+
+		/* coarse_integration_time REG=0x3012 */
+		16,
+
+		/* fine_integration_time   REG=0x3014 */
+		882
+	}
+};
+
+
+struct mt9p012_i2c_reg_conf mt9p012_test_tbl[] = {
+	{0x3044, 0x0544 & 0xFBFF},
+	{0x30CA, 0x0004 | 0x0001},
+	{0x30D4, 0x9020 & 0x7FFF},
+	{0x31E0, 0x0003 & 0xFFFE},
+	{0x3180, 0x91FF & 0x7FFF},
+	{0x301A, (0x10CC | 0x8000) & 0xFFF7},
+	{0x301E, 0x0000},
+	{0x3780, 0x0000},
+};
+
+
+struct mt9p012_i2c_reg_conf mt9p012_lc_tbl[] = {
+	/* [Lens shading 85 Percent TL84] */
+	/* P_RD_P0Q0 */
+	{0x360A, 0x7FEF},
+	/* P_RD_P0Q1 */
+	{0x360C, 0x232C},
+	/* P_RD_P0Q2 */
+	{0x360E, 0x7050},
+	/* P_RD_P0Q3 */
+	{0x3610, 0xF3CC},
+	/* P_RD_P0Q4 */
+	{0x3612, 0x89D1},
+	/* P_RD_P1Q0 */
+	{0x364A, 0xBE0D},
+	/* P_RD_P1Q1 */
+	{0x364C, 0x9ACB},
+	/* P_RD_P1Q2 */
+	{0x364E, 0x2150},
+	/* P_RD_P1Q3 */
+	{0x3650, 0xB26B},
+	/* P_RD_P1Q4 */
+	{0x3652, 0x9511},
+	/* P_RD_P2Q0 */
+	{0x368A, 0x2151},
+	/* P_RD_P2Q1 */
+	{0x368C, 0x00AD},
+	/* P_RD_P2Q2 */
+	{0x368E, 0x8334},
+	/* P_RD_P2Q3 */
+	{0x3690, 0x478E},
+	/* P_RD_P2Q4 */
+	{0x3692, 0x0515},
+	/* P_RD_P3Q0 */
+	{0x36CA, 0x0710},
+	/* P_RD_P3Q1 */
+	{0x36CC, 0x452D},
+	/* P_RD_P3Q2 */
+	{0x36CE, 0xF352},
+	/* P_RD_P3Q3 */
+	{0x36D0, 0x190F},
+	/* P_RD_P3Q4 */
+	{0x36D2, 0x4413},
+	/* P_RD_P4Q0 */
+	{0x370A, 0xD112},
+	/* P_RD_P4Q1 */
+	{0x370C, 0xF50F},
+	/* P_RD_P4Q2 */
+	{0x370C, 0xF50F},
+	/* P_RD_P4Q3 */
+	{0x3710, 0xDC11},
+	/* P_RD_P4Q4 */
+	{0x3712, 0xD776},
+	/* P_GR_P0Q0 */
+	{0x3600, 0x1750},
+	/* P_GR_P0Q1 */
+	{0x3602, 0xF0AC},
+	/* P_GR_P0Q2 */
+	{0x3604, 0x4711},
+	/* P_GR_P0Q3 */
+	{0x3606, 0x07CE},
+	/* P_GR_P0Q4 */
+	{0x3608, 0x96B2},
+	/* P_GR_P1Q0 */
+	{0x3640, 0xA9AE},
+	/* P_GR_P1Q1 */
+	{0x3642, 0xF9AC},
+	/* P_GR_P1Q2 */
+	{0x3644, 0x39F1},
+	/* P_GR_P1Q3 */
+	{0x3646, 0x016F},
+	/* P_GR_P1Q4 */
+	{0x3648, 0x8AB2},
+	/* P_GR_P2Q0 */
+	{0x3680, 0x1752},
+	/* P_GR_P2Q1 */
+	{0x3682, 0x70F0},
+	/* P_GR_P2Q2 */
+	{0x3684, 0x83F5},
+	/* P_GR_P2Q3 */
+	{0x3686, 0x8392},
+	/* P_GR_P2Q4 */
+	{0x3688, 0x1FD6},
+	/* P_GR_P3Q0 */
+	{0x36C0, 0x1131},
+	/* P_GR_P3Q1 */
+	{0x36C2, 0x3DAF},
+	/* P_GR_P3Q2 */
+	{0x36C4, 0x89B4},
+	/* P_GR_P3Q3 */
+	{0x36C6, 0xA391},
+	/* P_GR_P3Q4 */
+	{0x36C8, 0x1334},
+	/* P_GR_P4Q0 */
+	{0x3700, 0xDC13},
+	/* P_GR_P4Q1 */
+	{0x3702, 0xD052},
+	/* P_GR_P4Q2 */
+	{0x3704, 0x5156},
+	/* P_GR_P4Q3 */
+	{0x3706, 0x1F13},
+	/* P_GR_P4Q4 */
+	{0x3708, 0x8C38},
+	/* P_BL_P0Q0 */
+	{0x3614, 0x0050},
+	/* P_BL_P0Q1 */
+	{0x3616, 0xBD4C},
+	/* P_BL_P0Q2 */
+	{0x3618, 0x41B0},
+	/* P_BL_P0Q3 */
+	{0x361A, 0x660D},
+	/* P_BL_P0Q4 */
+	{0x361C, 0xC590},
+	/* P_BL_P1Q0 */
+	{0x3654, 0x87EC},
+	/* P_BL_P1Q1 */
+	{0x3656, 0xE44C},
+	/* P_BL_P1Q2 */
+	{0x3658, 0x302E},
+	/* P_BL_P1Q3 */
+	{0x365A, 0x106E},
+	/* P_BL_P1Q4 */
+	{0x365C, 0xB58E},
+	/* P_BL_P2Q0 */
+	{0x3694, 0x0DD1},
+	/* P_BL_P2Q1 */
+	{0x3696, 0x2A50},
+	/* P_BL_P2Q2 */
+	{0x3698, 0xC793},
+	/* P_BL_P2Q3 */
+	{0x369A, 0xE8F1},
+	/* P_BL_P2Q4 */
+	{0x369C, 0x4174},
+	/* P_BL_P3Q0 */
+	{0x36D4, 0x01EF},
+	/* P_BL_P3Q1 */
+	{0x36D6, 0x06CF},
+	/* P_BL_P3Q2 */
+	{0x36D8, 0x8D91},
+	/* P_BL_P3Q3 */
+	{0x36DA, 0x91F0},
+	/* P_BL_P3Q4 */
+	{0x36DC, 0x52EF},
+	/* P_BL_P4Q0 */
+	{0x3714, 0xA6D2},
+	/* P_BL_P4Q1 */
+	{0x3716, 0xA312},
+	/* P_BL_P4Q2 */
+	{0x3718, 0x2695},
+	/* P_BL_P4Q3 */
+	{0x371A, 0x3953},
+	/* P_BL_P4Q4 */
+	{0x371C, 0x9356},
+	/* P_GB_P0Q0 */
+	{0x361E, 0x7EAF},
+	/* P_GB_P0Q1 */
+	{0x3620, 0x2A4C},
+	/* P_GB_P0Q2 */
+	{0x3622, 0x49F0},
+	{0x3624, 0xF1EC},
+	/* P_GB_P0Q4 */
+	{0x3626, 0xC670},
+	/* P_GB_P1Q0 */
+	{0x365E, 0x8E0C},
+	/* P_GB_P1Q1 */
+	{0x3660, 0xC2A9},
+	/* P_GB_P1Q2 */
+	{0x3662, 0x274F},
+	/* P_GB_P1Q3 */
+	{0x3664, 0xADAB},
+	/* P_GB_P1Q4 */
+	{0x3666, 0x8EF0},
+	/* P_GB_P2Q0 */
+	{0x369E, 0x09B1},
+	/* P_GB_P2Q1 */
+	{0x36A0, 0xAA2E},
+	/* P_GB_P2Q2 */
+	{0x36A2, 0xC3D3},
+	/* P_GB_P2Q3 */
+	{0x36A4, 0x7FAF},
+	/* P_GB_P2Q4 */
+	{0x36A6, 0x3F34},
+	/* P_GB_P3Q0 */
+	{0x36DE, 0x4C8F},
+	/* P_GB_P3Q1 */
+	{0x36E0, 0x886E},
+	/* P_GB_P3Q2 */
+	{0x36E2, 0xE831},
+	/* P_GB_P3Q3 */
+	{0x36E4, 0x1FD0},
+	/* P_GB_P3Q4 */
+	{0x36E6, 0x1192},
+	/* P_GB_P4Q0 */
+	{0x371E, 0xB952},
+	/* P_GB_P4Q1 */
+	{0x3720, 0x6DCF},
+	/* P_GB_P4Q2 */
+	{0x3722, 0x1B55},
+	/* P_GB_P4Q3 */
+	{0x3724, 0xA112},
+	/* P_GB_P4Q4 */
+	{0x3726, 0x82F6},
+	/* POLY_ORIGIN_C */
+	{0x3782, 0x0510},
+	/* POLY_ORIGIN_R  */
+	{0x3784, 0x0390},
+	/* POLY_SC_ENABLE */
+	{0x3780, 0x8000},
+};
+
+/* rolloff table for illuminant A */
+struct mt9p012_i2c_reg_conf mt9p012_rolloff_tbl[] = {
+	/* P_RD_P0Q0 */
+	{0x360A, 0x7FEF},
+	/* P_RD_P0Q1 */
+	{0x360C, 0x232C},
+	/* P_RD_P0Q2 */
+	{0x360E, 0x7050},
+	/* P_RD_P0Q3 */
+	{0x3610, 0xF3CC},
+	/* P_RD_P0Q4 */
+	{0x3612, 0x89D1},
+	/* P_RD_P1Q0 */
+	{0x364A, 0xBE0D},
+	/* P_RD_P1Q1 */
+	{0x364C, 0x9ACB},
+	/* P_RD_P1Q2 */
+	{0x364E, 0x2150},
+	/* P_RD_P1Q3 */
+	{0x3650, 0xB26B},
+	/* P_RD_P1Q4 */
+	{0x3652, 0x9511},
+	/* P_RD_P2Q0 */
+	{0x368A, 0x2151},
+	/* P_RD_P2Q1 */
+	{0x368C, 0x00AD},
+	/* P_RD_P2Q2 */
+	{0x368E, 0x8334},
+	/* P_RD_P2Q3 */
+	{0x3690, 0x478E},
+	/* P_RD_P2Q4 */
+	{0x3692, 0x0515},
+	/* P_RD_P3Q0 */
+	{0x36CA, 0x0710},
+	/* P_RD_P3Q1 */
+	{0x36CC, 0x452D},
+	/* P_RD_P3Q2 */
+	{0x36CE, 0xF352},
+	/* P_RD_P3Q3 */
+	{0x36D0, 0x190F},
+	/* P_RD_P3Q4 */
+	{0x36D2, 0x4413},
+	/* P_RD_P4Q0 */
+	{0x370A, 0xD112},
+	/* P_RD_P4Q1 */
+	{0x370C, 0xF50F},
+	/* P_RD_P4Q2 */
+	{0x370E, 0x6375},
+	/* P_RD_P4Q3 */
+	{0x3710, 0xDC11},
+	/* P_RD_P4Q4 */
+	{0x3712, 0xD776},
+	/* P_GR_P0Q0 */
+	{0x3600, 0x1750},
+	/* P_GR_P0Q1 */
+	{0x3602, 0xF0AC},
+	/* P_GR_P0Q2 */
+	{0x3604, 0x4711},
+	/* P_GR_P0Q3 */
+	{0x3606, 0x07CE},
+	/* P_GR_P0Q4 */
+	{0x3608, 0x96B2},
+	/* P_GR_P1Q0 */
+	{0x3640, 0xA9AE},
+	/* P_GR_P1Q1 */
+	{0x3642, 0xF9AC},
+	/* P_GR_P1Q2 */
+	{0x3644, 0x39F1},
+	/* P_GR_P1Q3 */
+	{0x3646, 0x016F},
+	/* P_GR_P1Q4 */
+	{0x3648, 0x8AB2},
+	/* P_GR_P2Q0 */
+	{0x3680, 0x1752},
+	/* P_GR_P2Q1 */
+	{0x3682, 0x70F0},
+	/* P_GR_P2Q2 */
+	{0x3684, 0x83F5},
+	/* P_GR_P2Q3 */
+	{0x3686, 0x8392},
+	/* P_GR_P2Q4 */
+	{0x3688, 0x1FD6},
+	/* P_GR_P3Q0 */
+	{0x36C0, 0x1131},
+	/* P_GR_P3Q1 */
+	{0x36C2, 0x3DAF},
+	/* P_GR_P3Q2 */
+	{0x36C4, 0x89B4},
+	/* P_GR_P3Q3 */
+	{0x36C6, 0xA391},
+	/* P_GR_P3Q4 */
+	{0x36C8, 0x1334},
+	/* P_GR_P4Q0 */
+	{0x3700, 0xDC13},
+	/* P_GR_P4Q1 */
+	{0x3702, 0xD052},
+	/* P_GR_P4Q2 */
+	{0x3704, 0x5156},
+	/* P_GR_P4Q3 */
+	{0x3706, 0x1F13},
+	/* P_GR_P4Q4 */
+	{0x3708, 0x8C38},
+	/* P_BL_P0Q0 */
+	{0x3614, 0x0050},
+	/* P_BL_P0Q1 */
+	{0x3616, 0xBD4C},
+	/* P_BL_P0Q2 */
+	{0x3618, 0x41B0},
+	/* P_BL_P0Q3 */
+	{0x361A, 0x660D},
+	/* P_BL_P0Q4 */
+	{0x361C, 0xC590},
+	/* P_BL_P1Q0 */
+	{0x3654, 0x87EC},
+	/* P_BL_P1Q1 */
+	{0x3656, 0xE44C},
+	/* P_BL_P1Q2 */
+	{0x3658, 0x302E},
+	/* P_BL_P1Q3 */
+	{0x365A, 0x106E},
+	/* P_BL_P1Q4 */
+	{0x365C, 0xB58E},
+	/* P_BL_P2Q0 */
+	{0x3694, 0x0DD1},
+	/* P_BL_P2Q1 */
+	{0x3696, 0x2A50},
+	/* P_BL_P2Q2 */
+	{0x3698, 0xC793},
+	/* P_BL_P2Q3 */
+	{0x369A, 0xE8F1},
+	/* P_BL_P2Q4 */
+	{0x369C, 0x4174},
+	/* P_BL_P3Q0 */
+	{0x36D4, 0x01EF},
+	/* P_BL_P3Q1 */
+	{0x36D6, 0x06CF},
+	/* P_BL_P3Q2 */
+	{0x36D8, 0x8D91},
+	/* P_BL_P3Q3 */
+	{0x36DA, 0x91F0},
+	/* P_BL_P3Q4 */
+	{0x36DC, 0x52EF},
+	/* P_BL_P4Q0 */
+	{0x3714, 0xA6D2},
+	/* P_BL_P4Q1 */
+	{0x3716, 0xA312},
+	/* P_BL_P4Q2 */
+	{0x3718, 0x2695},
+	/* P_BL_P4Q3 */
+	{0x371A, 0x3953},
+	/* P_BL_P4Q4 */
+	{0x371C, 0x9356},
+	/* P_GB_P0Q0 */
+	{0x361E, 0x7EAF},
+	/* P_GB_P0Q1 */
+	{0x3620, 0x2A4C},
+	/* P_GB_P0Q2 */
+	{0x3622, 0x49F0},
+	{0x3624, 0xF1EC},
+	/* P_GB_P0Q4 */
+	{0x3626, 0xC670},
+	/* P_GB_P1Q0 */
+	{0x365E, 0x8E0C},
+	/* P_GB_P1Q1 */
+	{0x3660, 0xC2A9},
+	/* P_GB_P1Q2 */
+	{0x3662, 0x274F},
+	/* P_GB_P1Q3 */
+	{0x3664, 0xADAB},
+	/* P_GB_P1Q4 */
+	{0x3666, 0x8EF0},
+	/* P_GB_P2Q0 */
+	{0x369E, 0x09B1},
+	/* P_GB_P2Q1 */
+	{0x36A0, 0xAA2E},
+	/* P_GB_P2Q2 */
+	{0x36A2, 0xC3D3},
+	/* P_GB_P2Q3 */
+	{0x36A4, 0x7FAF},
+	/* P_GB_P2Q4 */
+	{0x36A6, 0x3F34},
+	/* P_GB_P3Q0 */
+	{0x36DE, 0x4C8F},
+	/* P_GB_P3Q1 */
+	{0x36E0, 0x886E},
+	/* P_GB_P3Q2 */
+	{0x36E2, 0xE831},
+	/* P_GB_P3Q3 */
+	{0x36E4, 0x1FD0},
+	/* P_GB_P3Q4 */
+	{0x36E6, 0x1192},
+	/* P_GB_P4Q0 */
+	{0x371E, 0xB952},
+	/* P_GB_P4Q1 */
+	{0x3720, 0x6DCF},
+	/* P_GB_P4Q2 */
+	{0x3722, 0x1B55},
+	/* P_GB_P4Q3 */
+	{0x3724, 0xA112},
+	/* P_GB_P4Q4 */
+	{0x3726, 0x82F6},
+	/* POLY_ORIGIN_C */
+	{0x3782, 0x0510},
+	/* POLY_ORIGIN_R  */
+	{0x3784, 0x0390},
+	/* POLY_SC_ENABLE */
+	{0x3780, 0x8000},
+};
+
+
+struct mt9p012_reg mt9p012_regs = {
+	.reg_pat = &mt9p012_reg_pat[0],
+	.reg_pat_size = ARRAY_SIZE(mt9p012_reg_pat),
+	.ttbl = &mt9p012_test_tbl[0],
+	.ttbl_size = ARRAY_SIZE(mt9p012_test_tbl),
+	.lctbl = &mt9p012_lc_tbl[0],
+	.lctbl_size = ARRAY_SIZE(mt9p012_lc_tbl),
+	.rftbl = &mt9p012_rolloff_tbl[0],
+	.rftbl_size = ARRAY_SIZE(mt9p012_rolloff_tbl)
+};
+
+
diff --git a/drivers/staging/dream/camera/mt9t013.c b/drivers/staging/dream/camera/mt9t013.c
new file mode 100644
index 0000000..88229f2
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9t013.c
@@ -0,0 +1,1496 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/kernel.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include <asm/mach-types.h>
+#include "mt9t013.h"
+
+/*=============================================================
+	SENSOR REGISTER DEFINES
+==============================================================*/
+#define MT9T013_REG_MODEL_ID 		 0x0000
+#define MT9T013_MODEL_ID     		 0x2600
+#define REG_GROUPED_PARAMETER_HOLD   0x0104
+#define GROUPED_PARAMETER_HOLD       0x0100
+#define GROUPED_PARAMETER_UPDATE     0x0000
+#define REG_COARSE_INT_TIME          0x3012
+#define REG_VT_PIX_CLK_DIV           0x0300
+#define REG_VT_SYS_CLK_DIV           0x0302
+#define REG_PRE_PLL_CLK_DIV          0x0304
+#define REG_PLL_MULTIPLIER           0x0306
+#define REG_OP_PIX_CLK_DIV           0x0308
+#define REG_OP_SYS_CLK_DIV           0x030A
+#define REG_SCALE_M                  0x0404
+#define REG_FRAME_LENGTH_LINES       0x300A
+#define REG_LINE_LENGTH_PCK          0x300C
+#define REG_X_ADDR_START             0x3004
+#define REG_Y_ADDR_START             0x3002
+#define REG_X_ADDR_END               0x3008
+#define REG_Y_ADDR_END               0x3006
+#define REG_X_OUTPUT_SIZE            0x034C
+#define REG_Y_OUTPUT_SIZE            0x034E
+#define REG_FINE_INT_TIME            0x3014
+#define REG_ROW_SPEED                0x3016
+#define MT9T013_REG_RESET_REGISTER   0x301A
+#define MT9T013_RESET_REGISTER_PWON  0x10CC
+#define MT9T013_RESET_REGISTER_PWOFF 0x1008 /* 0x10C8 stop streaming*/
+#define REG_READ_MODE                0x3040
+#define REG_GLOBAL_GAIN              0x305E
+#define REG_TEST_PATTERN_MODE        0x3070
+
+
+enum mt9t013_test_mode {
+	TEST_OFF,
+	TEST_1,
+	TEST_2,
+	TEST_3
+};
+
+enum mt9t013_resolution {
+	QTR_SIZE,
+	FULL_SIZE,
+	INVALID_SIZE
+};
+
+enum mt9t013_reg_update {
+	REG_INIT, /* registers that need to be updated during initialization */
+	UPDATE_PERIODIC, /* registers that needs periodic I2C writes */
+	UPDATE_ALL, /* all registers will be updated */
+	UPDATE_INVALID
+};
+
+enum mt9t013_setting {
+	RES_PREVIEW,
+	RES_CAPTURE
+};
+
+/* actuator's Slave Address */
+#define MT9T013_AF_I2C_ADDR   0x18
+
+/*
+* AF Total steps parameters
+*/
+#define MT9T013_TOTAL_STEPS_NEAR_TO_FAR    30
+
+/*
+ * Time in milisecs for waiting for the sensor to reset.
+ */
+#define MT9T013_RESET_DELAY_MSECS   66
+
+/* for 30 fps preview */
+#define MT9T013_DEFAULT_CLOCK_RATE  24000000
+#define MT9T013_DEFAULT_MAX_FPS     26
+
+
+/* FIXME: Changes from here */
+struct mt9t013_work {
+	struct work_struct work;
+};
+
+static struct  mt9t013_work *mt9t013_sensorw;
+static struct  i2c_client *mt9t013_client;
+
+struct mt9t013_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider; 		/* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider; 	/* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum mt9t013_resolution prev_res;
+	enum mt9t013_resolution pict_res;
+	enum mt9t013_resolution curr_res;
+	enum mt9t013_test_mode  set_test;
+
+	unsigned short imgaddr;
+};
+
+
+static struct mt9t013_ctrl *mt9t013_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(mt9t013_wait_queue);
+DECLARE_MUTEX(mt9t013_sem);
+
+extern struct mt9t013_reg mt9t013_regs; /* from mt9t013_reg.c */
+
+static int mt9t013_i2c_rxdata(unsigned short saddr,
+	unsigned char *rxdata, int length)
+{
+	struct i2c_msg msgs[] = {
+	{
+		.addr   = saddr,
+		.flags = 0,
+		.len   = 2,
+		.buf   = rxdata,
+	},
+	{
+		.addr  = saddr,
+		.flags = I2C_M_RD,
+		.len   = length,
+		.buf   = rxdata,
+	},
+	};
+
+	if (i2c_transfer(mt9t013_client->adapter, msgs, 2) < 0) {
+		pr_err("mt9t013_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9t013_i2c_read_w(unsigned short saddr,
+	unsigned short raddr, unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00)>>8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = mt9t013_i2c_rxdata(saddr, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		pr_err("mt9t013_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int32_t mt9t013_i2c_txdata(unsigned short saddr,
+	unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+	{
+		.addr = saddr,
+		.flags = 0,
+		.len = length,
+		.buf = txdata,
+	},
+	};
+
+	if (i2c_transfer(mt9t013_client->adapter, msg, 1) < 0) {
+		pr_err("mt9t013_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t mt9t013_i2c_write_b(unsigned short saddr,
+	unsigned short waddr, unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[2];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = waddr;
+	buf[1] = wdata;
+	rc = mt9t013_i2c_txdata(saddr, buf, 2);
+
+	if (rc < 0)
+		pr_err("i2c_write failed, addr = 0x%x, val = 0x%x!\n",
+		waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9t013_i2c_write_w(unsigned short saddr,
+	unsigned short waddr, unsigned short wdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00)>>8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = (wdata & 0xFF00)>>8;
+	buf[3] = (wdata & 0x00FF);
+
+	rc = mt9t013_i2c_txdata(saddr, buf, 4);
+
+	if (rc < 0)
+		pr_err("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+		waddr, wdata);
+
+	return rc;
+}
+
+static int32_t mt9t013_i2c_write_w_table(
+	struct mt9t013_i2c_reg_conf *reg_conf_tbl, int num_of_items_in_table)
+{
+	int i;
+	int32_t rc = -EIO;
+
+	for (i = 0; i < num_of_items_in_table; i++) {
+		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			reg_conf_tbl->waddr, reg_conf_tbl->wdata);
+		if (rc < 0)
+			break;
+		reg_conf_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t mt9t013_test(enum mt9t013_test_mode mo)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	if (mo == TEST_OFF)
+		return 0;
+	else {
+		rc = mt9t013_i2c_write_w_table(mt9t013_regs.ttbl,
+				mt9t013_regs.ttbl_size);
+		if (rc < 0)
+			return rc;
+		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_TEST_PATTERN_MODE, (uint16_t)mo);
+		if (rc < 0)
+			return rc;
+	}
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_set_lc(void)
+{
+	int32_t rc;
+
+	rc = mt9t013_i2c_write_w_table(mt9t013_regs.lctbl, mt9t013_regs.lctbl_size);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_set_default_focus(uint8_t af_step)
+{
+	int32_t rc = 0;
+	uint8_t code_val_msb, code_val_lsb;
+	code_val_msb = 0x01;
+	code_val_lsb = af_step;
+
+	/* Write the digital code for current to the actuator */
+	rc = mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
+			code_val_msb, code_val_lsb);
+
+	mt9t013_ctrl->curr_lens_pos = 0;
+	mt9t013_ctrl->init_curr_lens_pos = 0;
+	return rc;
+}
+
+static void mt9t013_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;   /*Q10 */
+	uint32_t pclk_mult; /*Q10 */
+
+	if (mt9t013_ctrl->prev_res == QTR_SIZE) {
+		divider =
+			(uint32_t)(
+		((mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines *
+		mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck) *
+		0x00000400) /
+		(mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines *
+		mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck));
+
+		pclk_mult =
+		(uint32_t) ((mt9t013_regs.reg_pat[RES_CAPTURE].pll_multiplier *
+		0x00000400) /
+		(mt9t013_regs.reg_pat[RES_PREVIEW].pll_multiplier));
+
+	} else {
+		/* full size resolution used for preview. */
+		divider   = 0x00000400;  /*1.0 */
+		pclk_mult = 0x00000400;  /*1.0 */
+	}
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps =
+		(uint16_t) (fps * divider * pclk_mult /
+		0x00000400 / 0x00000400);
+}
+
+static uint16_t mt9t013_get_prev_lines_pf(void)
+{
+	if (mt9t013_ctrl->prev_res == QTR_SIZE)
+		return mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines;
+	else
+		return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9t013_get_prev_pixels_pl(void)
+{
+	if (mt9t013_ctrl->prev_res == QTR_SIZE)
+		return mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck;
+	else
+		return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint16_t mt9t013_get_pict_lines_pf(void)
+{
+	return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
+}
+
+static uint16_t mt9t013_get_pict_pixels_pl(void)
+{
+	return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
+}
+
+static uint32_t mt9t013_get_pict_max_exp_lc(void)
+{
+	uint16_t snapshot_lines_per_frame;
+
+	if (mt9t013_ctrl->pict_res == QTR_SIZE) {
+		snapshot_lines_per_frame =
+		mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
+	} else  {
+		snapshot_lines_per_frame =
+		mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
+	}
+
+	return snapshot_lines_per_frame * 24;
+}
+
+static int32_t mt9t013_set_fps(struct fps_cfg *fps)
+{
+	/* input is new fps in Q8 format */
+	int32_t rc = 0;
+
+	mt9t013_ctrl->fps_divider = fps->fps_div;
+	mt9t013_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return -EBUSY;
+
+	CDBG("mt9t013_set_fps: fps_div is %d, frame_rate is %d\n",
+			fps->fps_div,
+			(uint16_t) (mt9t013_regs.reg_pat[RES_PREVIEW].
+						frame_length_lines *
+					fps->fps_div/0x00000400));
+
+	CDBG("mt9t013_set_fps: fps_mult is %d, frame_rate is %d\n",
+			fps->f_mult,
+			(uint16_t)(mt9t013_regs.reg_pat[RES_PREVIEW].
+					line_length_pck *
+					fps->f_mult / 0x00000400));
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_LINE_LENGTH_PCK,
+			(uint16_t) (
+			mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck *
+			fps->f_mult / 0x00000400));
+	if (rc < 0)
+		return rc;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	const uint16_t max_legal_gain = 0x01FF;
+	uint32_t line_length_ratio = 0x00000400;
+	enum mt9t013_setting setting;
+	int32_t rc = 0;
+
+	if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+		mt9t013_ctrl->my_reg_gain = gain;
+		mt9t013_ctrl->my_reg_line_count = (uint16_t) line;
+	}
+
+	if (gain > max_legal_gain)
+		gain = max_legal_gain;
+
+	/* Verify no overflow */
+	if (mt9t013_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
+		line = (uint32_t) (line * mt9t013_ctrl->fps_divider /
+			0x00000400);
+
+		setting = RES_PREVIEW;
+
+	} else {
+		line = (uint32_t) (line * mt9t013_ctrl->pict_fps_divider /
+			0x00000400);
+
+		setting = RES_CAPTURE;
+	}
+
+	/*Set digital gain to 1 */
+	gain |= 0x0200;
+
+	if ((mt9t013_regs.reg_pat[setting].frame_length_lines - 1) < line) {
+
+		line_length_ratio =
+		(uint32_t) (line * 0x00000400) /
+		(mt9t013_regs.reg_pat[setting].frame_length_lines - 1);
+	} else
+		line_length_ratio = 0x00000400;
+
+	/* There used to be PARAMETER_HOLD register write before and
+	 * after REG_GLOBAL_GAIN & REG_COARSE_INIT_TIME. This causes
+	 * aec oscillation. Hence removed. */
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr, REG_GLOBAL_GAIN, gain);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_COARSE_INT_TIME,
+			(uint16_t)((uint32_t) line * 0x00000400 /
+			line_length_ratio));
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int32_t mt9t013_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_write_exp_gain(gain, line);
+	if (rc < 0)
+		return rc;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			MT9T013_REG_RESET_REGISTER,
+			0x10CC | 0x0002);
+
+	mdelay(5);
+
+	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
+	return rc;
+}
+
+static int32_t mt9t013_setting(enum mt9t013_reg_update rupdate,
+	enum mt9t013_setting rt)
+{
+	int32_t rc = 0;
+
+	switch (rupdate) {
+	case UPDATE_PERIODIC: {
+
+	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+#if 0
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				MT9T013_REG_RESET_REGISTER,
+				MT9T013_RESET_REGISTER_PWOFF);
+		if (rc < 0)
+			return rc;
+#endif
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PRE_PLL_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PLL_MULTIPLIER,
+				mt9t013_regs.reg_pat[rt].pll_multiplier);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_HOLD);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_ROW_SPEED,
+				mt9t013_regs.reg_pat[rt].row_speed);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_START,
+				mt9t013_regs.reg_pat[rt].x_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_END,
+				mt9t013_regs.reg_pat[rt].x_addr_end);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_START,
+				mt9t013_regs.reg_pat[rt].y_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_END,
+				mt9t013_regs.reg_pat[rt].y_addr_end);
+		if (rc < 0)
+			return rc;
+
+		if (machine_is_sapphire()) {
+			if (rt == 0)
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x046F);
+			else
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x0027);
+		} else
+			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					mt9t013_regs.reg_pat[rt].read_mode);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_SCALE_M,
+				mt9t013_regs.reg_pat[rt].scale_m);
+		if (rc < 0)
+			return rc;
+
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].x_output_size);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].y_output_size);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_LINE_LENGTH_PCK,
+				mt9t013_regs.reg_pat[rt].line_length_pck);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_FRAME_LENGTH_LINES,
+			(mt9t013_regs.reg_pat[rt].frame_length_lines *
+			mt9t013_ctrl->fps_divider / 0x00000400));
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_COARSE_INT_TIME,
+			mt9t013_regs.reg_pat[rt].coarse_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_FINE_INT_TIME,
+			mt9t013_regs.reg_pat[rt].fine_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_UPDATE);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9t013_test(mt9t013_ctrl->set_test);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+			MT9T013_REG_RESET_REGISTER,
+			MT9T013_RESET_REGISTER_PWON);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		return rc;
+	}
+	}
+		break;
+
+	/*CAMSENSOR_REG_UPDATE_PERIODIC */
+	case REG_INIT: {
+	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				MT9T013_REG_RESET_REGISTER,
+				MT9T013_RESET_REGISTER_PWOFF);
+		if (rc < 0)
+			/* MODE_SELECT, stop streaming */
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_VT_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PRE_PLL_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_PLL_MULTIPLIER,
+				mt9t013_regs.reg_pat[rt].pll_multiplier);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_PIX_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_OP_SYS_CLK_DIV,
+				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_HOLD);
+		if (rc < 0)
+			return rc;
+
+		/* additional power saving mode ok around 38.2MHz */
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3084, 0x2409);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3092, 0x0A49);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3094, 0x4949);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				0x3096, 0x4949);
+		if (rc < 0)
+			return rc;
+
+		/* Set preview or snapshot mode */
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_ROW_SPEED,
+				mt9t013_regs.reg_pat[rt].row_speed);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_START,
+				mt9t013_regs.reg_pat[rt].x_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_ADDR_END,
+				mt9t013_regs.reg_pat[rt].x_addr_end);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_START,
+				mt9t013_regs.reg_pat[rt].y_addr_start);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_ADDR_END,
+				mt9t013_regs.reg_pat[rt].y_addr_end);
+		if (rc < 0)
+			return rc;
+
+		if (machine_is_sapphire()) {
+			if (rt == 0)
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x046F);
+			else
+				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					0x0027);
+		} else
+			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+					REG_READ_MODE,
+					mt9t013_regs.reg_pat[rt].read_mode);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_SCALE_M,
+				mt9t013_regs.reg_pat[rt].scale_m);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_X_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].x_output_size);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_Y_OUTPUT_SIZE,
+				mt9t013_regs.reg_pat[rt].y_output_size);
+		if (rc < 0)
+			return 0;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_LINE_LENGTH_PCK,
+				mt9t013_regs.reg_pat[rt].line_length_pck);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_FRAME_LENGTH_LINES,
+				mt9t013_regs.reg_pat[rt].frame_length_lines);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_COARSE_INT_TIME,
+				mt9t013_regs.reg_pat[rt].coarse_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_FINE_INT_TIME,
+				mt9t013_regs.reg_pat[rt].fine_int_time);
+		if (rc < 0)
+			return rc;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_UPDATE);
+			if (rc < 0)
+				return rc;
+
+		/* load lens shading */
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_HOLD);
+		if (rc < 0)
+			return rc;
+
+		/* most likely needs to be written only once. */
+		rc = mt9t013_set_lc();
+		if (rc < 0)
+			return -EBUSY;
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_UPDATE);
+		if (rc < 0)
+			return rc;
+
+		rc = mt9t013_test(mt9t013_ctrl->set_test);
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc =
+			mt9t013_i2c_write_w(mt9t013_client->addr,
+				MT9T013_REG_RESET_REGISTER,
+				MT9T013_RESET_REGISTER_PWON);
+		if (rc < 0)
+			/* MODE_SELECT, stop streaming */
+			return rc;
+
+		CDBG("!!! mt9t013 !!! PowerOn is done!\n");
+		mdelay(5);
+		return rc;
+		}
+	} /* case CAMSENSOR_REG_INIT: */
+	break;
+
+	/*CAMSENSOR_REG_INIT */
+	default:
+		rc = -EINVAL;
+		break;
+	} /* switch (rupdate) */
+
+	return rc;
+}
+
+static int32_t mt9t013_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case QTR_SIZE:
+		rc = mt9t013_setting(UPDATE_PERIODIC, RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+		CDBG("sensor configuration done!\n");
+		break;
+
+	case FULL_SIZE:
+		rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+		break;
+
+	default:
+		return -EINVAL;
+	} /* switch */
+
+	mt9t013_ctrl->prev_res = res;
+	mt9t013_ctrl->curr_res = res;
+	mt9t013_ctrl->sensormode = mode;
+
+	return mt9t013_write_exp_gain(mt9t013_ctrl->my_reg_gain,
+			mt9t013_ctrl->my_reg_line_count);
+}
+
+static int32_t mt9t013_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
+	mt9t013_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t mt9t013_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
+	mt9t013_ctrl->sensormode = mode;
+	return rc;
+}
+
+static int32_t mt9t013_power_down(void)
+{
+	int32_t rc = 0;
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			MT9T013_REG_RESET_REGISTER,
+			MT9T013_RESET_REGISTER_PWOFF);
+	if (rc >= 0)
+		mdelay(5);
+	return rc;
+}
+
+static int32_t mt9t013_move_focus(int direction, int32_t num_steps)
+{
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_position;
+	int16_t break_steps[4];
+	uint8_t code_val_msb, code_val_lsb;
+	int16_t i;
+
+	if (num_steps > MT9T013_TOTAL_STEPS_NEAR_TO_FAR)
+		num_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
+	else if (num_steps == 0)
+		return -EINVAL;
+
+	if (direction == MOVE_NEAR)
+		step_direction = 4;
+	else if (direction == MOVE_FAR)
+		step_direction = -4;
+	else
+		return -EINVAL;
+
+	if (mt9t013_ctrl->curr_lens_pos < mt9t013_ctrl->init_curr_lens_pos)
+		mt9t013_ctrl->curr_lens_pos = mt9t013_ctrl->init_curr_lens_pos;
+
+	actual_step =
+		(int16_t) (step_direction *
+		(int16_t) num_steps);
+
+	for (i = 0; i < 4; i++)
+		break_steps[i] =
+			actual_step / 4 * (i + 1) - actual_step / 4 * i;
+
+	for (i = 0; i < 4; i++) {
+		next_position =
+		(int16_t)
+		(mt9t013_ctrl->curr_lens_pos + break_steps[i]);
+
+		if (next_position > 255)
+			next_position = 255;
+		else if (next_position < 0)
+			next_position = 0;
+
+		code_val_msb =
+		((next_position >> 4) << 2) |
+		((next_position << 4) >> 6);
+
+		code_val_lsb =
+		((next_position & 0x03) << 6);
+
+		/* Writing the digital code for current to the actuator */
+		if (mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
+				code_val_msb, code_val_lsb) < 0)
+			return -EBUSY;
+
+		/* Storing the current lens Position */
+		mt9t013_ctrl->curr_lens_pos = next_position;
+
+		if (i < 3)
+			mdelay(1);
+	} /* for */
+
+	return 0;
+}
+
+static int mt9t013_sensor_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int mt9t013_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int rc;
+	uint16_t chipid;
+
+	rc = gpio_request(data->sensor_reset, "mt9t013");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	mdelay(20);
+
+	/* RESET the sensor image part via I2C command */
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+		MT9T013_REG_RESET_REGISTER, 0x1009);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	/* 3. Read sensor Model ID: */
+	rc = mt9t013_i2c_read_w(mt9t013_client->addr,
+		MT9T013_REG_MODEL_ID, &chipid);
+
+	if (rc < 0)
+		goto init_probe_fail;
+
+	CDBG("mt9t013 model_id = 0x%x\n", chipid);
+
+	/* 4. Compare sensor ID to MT9T012VC ID: */
+	if (chipid != MT9T013_MODEL_ID) {
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+		0x3064, 0x0805);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	mdelay(MT9T013_RESET_DELAY_MSECS);
+
+	goto init_probe_done;
+
+	/* sensor: output enable */
+#if 0
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+		MT9T013_REG_RESET_REGISTER,
+		MT9T013_RESET_REGISTER_PWON);
+
+	/* if this fails, the sensor is not the MT9T013 */
+	rc = mt9t013_set_default_focus(0);
+#endif
+
+init_probe_fail:
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+init_probe_done:
+	return rc;
+}
+
+static int32_t mt9t013_poweron_af(void)
+{
+	int32_t rc = 0;
+
+	/* enable AF actuator */
+	CDBG("enable AF actuator, gpio = %d\n",
+			mt9t013_ctrl->sensordata->vcm_pwd);
+	rc = gpio_request(mt9t013_ctrl->sensordata->vcm_pwd, "mt9t013");
+	if (!rc) {
+		gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 0);
+		mdelay(20);
+		rc = mt9t013_set_default_focus(0);
+	} else
+		pr_err("%s, gpio_request failed (%d)!\n", __func__, rc);
+	return rc;
+}
+
+static void mt9t013_poweroff_af(void)
+{
+	gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 1);
+	gpio_free(mt9t013_ctrl->sensordata->vcm_pwd);
+}
+
+int mt9t013_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+
+	mt9t013_ctrl = kzalloc(sizeof(struct mt9t013_ctrl), GFP_KERNEL);
+	if (!mt9t013_ctrl) {
+		pr_err("mt9t013_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	mt9t013_ctrl->fps_divider = 1 * 0x00000400;
+	mt9t013_ctrl->pict_fps_divider = 1 * 0x00000400;
+	mt9t013_ctrl->set_test = TEST_OFF;
+	mt9t013_ctrl->prev_res = QTR_SIZE;
+	mt9t013_ctrl->pict_res = FULL_SIZE;
+
+	if (data)
+		mt9t013_ctrl->sensordata = data;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = mt9t013_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail;
+
+	if (mt9t013_ctrl->prev_res == QTR_SIZE)
+		rc = mt9t013_setting(REG_INIT, RES_PREVIEW);
+	else
+		rc = mt9t013_setting(REG_INIT, RES_CAPTURE);
+
+	if (rc >= 0)
+		rc = mt9t013_poweron_af();
+
+	if (rc < 0)
+		goto init_fail;
+	else
+		goto init_done;
+
+init_fail:
+	kfree(mt9t013_ctrl);
+init_done:
+	return rc;
+}
+
+static int mt9t013_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&mt9t013_wait_queue);
+	return 0;
+}
+
+
+static int32_t mt9t013_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
+			REG_GROUPED_PARAMETER_HOLD,
+			GROUPED_PARAMETER_HOLD);
+	if (rc < 0)
+		return rc;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = mt9t013_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = mt9t013_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = mt9t013_raw_snapshot_config(mode);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	/* FIXME: what should we do if rc < 0? */
+	if (rc >= 0)
+		return mt9t013_i2c_write_w(mt9t013_client->addr,
+				REG_GROUPED_PARAMETER_HOLD,
+				GROUPED_PARAMETER_UPDATE);
+	return rc;
+}
+
+int mt9t013_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+
+	if (copy_from_user(&cdata, (void *)argp,
+			sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	down(&mt9t013_sem);
+
+	CDBG("mt9t013_sensor_config: cfgtype = %d\n", cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		mt9t013_get_pict_fps(cdata.cfg.gfps.prevfps,
+				&(cdata.cfg.gfps.pictfps));
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = mt9t013_get_prev_lines_pf();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = mt9t013_get_prev_pixels_pl();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = mt9t013_get_pict_lines_pf();
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl =
+			mt9t013_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			mt9t013_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = mt9t013_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc = mt9t013_write_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		rc = mt9t013_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc = mt9t013_set_sensor_mode(cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = mt9t013_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc = mt9t013_move_focus(cdata.cfg.focus.dir,
+				cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc = mt9t013_set_default_focus(cdata.cfg.focus.steps);
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+		cdata.max_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_EFFECT:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	up(&mt9t013_sem);
+	return rc;
+}
+
+int mt9t013_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	down(&mt9t013_sem);
+
+	mt9t013_poweroff_af();
+	mt9t013_power_down();
+
+	gpio_direction_output(mt9t013_ctrl->sensordata->sensor_reset,
+			0);
+	gpio_free(mt9t013_ctrl->sensordata->sensor_reset);
+
+	kfree(mt9t013_ctrl);
+
+	up(&mt9t013_sem);
+	CDBG("mt9t013_release completed!\n");
+	return rc;
+}
+
+static int mt9t013_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		rc = -ENOTSUPP;
+		goto probe_failure;
+	}
+
+	mt9t013_sensorw =
+		kzalloc(sizeof(struct mt9t013_work), GFP_KERNEL);
+
+	if (!mt9t013_sensorw) {
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, mt9t013_sensorw);
+	mt9t013_init_client(client);
+	mt9t013_client = client;
+	mt9t013_client->addr = mt9t013_client->addr >> 1;
+	mdelay(50);
+
+	CDBG("i2c probe ok\n");
+	return 0;
+
+probe_failure:
+	kfree(mt9t013_sensorw);
+	mt9t013_sensorw = NULL;
+	pr_err("i2c probe failure %d\n", rc);
+	return rc;
+}
+
+static const struct i2c_device_id mt9t013_i2c_id[] = {
+	{ "mt9t013", 0},
+	{ }
+};
+
+static struct i2c_driver mt9t013_i2c_driver = {
+	.id_table = mt9t013_i2c_id,
+	.probe  = mt9t013_i2c_probe,
+	.remove = __exit_p(mt9t013_i2c_remove),
+	.driver = {
+		.name = "mt9t013",
+	},
+};
+
+static int mt9t013_sensor_probe(
+		const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	/* We expect this driver to match with the i2c device registered
+	 * in the board file immediately. */
+	int rc = i2c_add_driver(&mt9t013_i2c_driver);
+	if (rc < 0 || mt9t013_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_done;
+	}
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
+	mdelay(20);
+
+	rc = mt9t013_probe_init_sensor(info);
+	if (rc < 0) {
+		i2c_del_driver(&mt9t013_i2c_driver);
+		goto probe_done;
+	}
+
+	s->s_init = mt9t013_sensor_open_init;
+	s->s_release = mt9t013_sensor_release;
+	s->s_config  = mt9t013_sensor_config;
+	mt9t013_sensor_init_done(info);
+
+probe_done:
+	return rc;
+}
+
+static int __mt9t013_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, mt9t013_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __mt9t013_probe,
+	.driver = {
+		.name = "msm_camera_mt9t013",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init mt9t013_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(mt9t013_init);
diff --git a/drivers/staging/dream/camera/mt9t013.h b/drivers/staging/dream/camera/mt9t013.h
new file mode 100644
index 0000000..9bce203
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9t013.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#ifndef MT9T013_H
+#define MT9T013_H
+
+#include <linux/types.h>
+
+struct reg_struct {
+	uint16_t vt_pix_clk_div;        /*  0x0300 */
+	uint16_t vt_sys_clk_div;        /*  0x0302 */
+	uint16_t pre_pll_clk_div;       /*  0x0304 */
+	uint16_t pll_multiplier;        /*  0x0306 */
+	uint16_t op_pix_clk_div;        /*  0x0308 */
+	uint16_t op_sys_clk_div;        /*  0x030A */
+	uint16_t scale_m;               /*  0x0404 */
+	uint16_t row_speed;             /*  0x3016 */
+	uint16_t x_addr_start;          /*  0x3004 */
+	uint16_t x_addr_end;            /*  0x3008 */
+	uint16_t y_addr_start;        	/*  0x3002 */
+	uint16_t y_addr_end;            /*  0x3006 */
+	uint16_t read_mode;             /*  0x3040 */
+	uint16_t x_output_size;         /*  0x034C */
+	uint16_t y_output_size;         /*  0x034E */
+	uint16_t line_length_pck;       /*  0x300C */
+	uint16_t frame_length_lines;	/*  0x300A */
+	uint16_t coarse_int_time; 		/*  0x3012 */
+	uint16_t fine_int_time;   		/*  0x3014 */
+};
+
+struct mt9t013_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned short wdata;
+};
+
+struct mt9t013_reg {
+	struct reg_struct *reg_pat;
+	uint16_t reg_pat_size;
+	struct mt9t013_i2c_reg_conf *ttbl;
+	uint16_t ttbl_size;
+	struct mt9t013_i2c_reg_conf *lctbl;
+	uint16_t lctbl_size;
+	struct mt9t013_i2c_reg_conf *rftbl;
+	uint16_t rftbl_size;
+};
+
+#endif /* #define MT9T013_H */
diff --git a/drivers/staging/dream/camera/mt9t013_reg.c b/drivers/staging/dream/camera/mt9t013_reg.c
new file mode 100644
index 0000000..ba0a1d4
--- /dev/null
+++ b/drivers/staging/dream/camera/mt9t013_reg.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2009 QUALCOMM Incorporated.
+ */
+
+#include "mt9t013.h"
+#include <linux/kernel.h>
+
+struct reg_struct const mt9t013_reg_pat[2] = {
+	{ /* Preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
+	/* vt_pix_clk_div:REG=0x0300 update get_snapshot_fps
+	* if this change */
+	8,
+
+	/* vt_sys_clk_div: REG=0x0302  update get_snapshot_fps
+	* if this change */
+	1,
+
+	/* pre_pll_clk_div REG=0x0304  update get_snapshot_fps
+	* if this change */
+	2,
+
+	/* pll_multiplier  REG=0x0306 60 for 30fps preview, 40
+	 * for 20fps preview
+	 * 46 for 30fps preview, try 47/48 to increase further */
+	46,
+
+	/* op_pix_clk_div        REG=0x0308 */
+	8,
+
+	/* op_sys_clk_div        REG=0x030A */
+	1,
+
+	/* scale_m       REG=0x0404 */
+	16,
+
+	/* row_speed     REG=0x3016 */
+	0x0111,
+
+	/* x_addr_start  REG=0x3004 */
+	8,
+
+	/* x_addr_end    REG=0x3008 */
+	2053,
+
+	/* y_addr_start  REG=0x3002 */
+	8,
+
+	/* y_addr_end    REG=0x3006 */
+	1541,
+
+	/* read_mode     REG=0x3040 */
+	0x046C,
+
+	/* x_output_size REG=0x034C */
+	1024,
+
+	/* y_output_size REG=0x034E */
+	768,
+
+	/* line_length_pck    REG=0x300C */
+	2616,
+
+	/* frame_length_lines REG=0x300A */
+	916,
+
+	/* coarse_int_time REG=0x3012 */
+	16,
+
+	/* fine_int_time   REG=0x3014 */
+	1461
+	},
+	{ /*Snapshot */
+	/* vt_pix_clk_div  REG=0x0300 update get_snapshot_fps
+	* if this change */
+	8,
+
+	/* vt_sys_clk_div  REG=0x0302 update get_snapshot_fps
+	* if this change */
+	1,
+
+	/* pre_pll_clk_div REG=0x0304 update get_snapshot_fps
+	 * if this change */
+	2,
+
+	/* pll_multiplier REG=0x0306 50 for 15fps snapshot,
+	 * 40 for 10fps snapshot
+	 * 46 for 30fps snapshot, try 47/48 to increase further */
+	46,
+
+	/* op_pix_clk_div        REG=0x0308 */
+	8,
+
+	/* op_sys_clk_div        REG=0x030A */
+	1,
+
+	/* scale_m       REG=0x0404 */
+	16,
+
+	/* row_speed     REG=0x3016 */
+	0x0111,
+
+	/* x_addr_start  REG=0x3004 */
+	8,
+
+	/* x_addr_end    REG=0x3008 */
+	2071,
+
+	/* y_addr_start  REG=0x3002 */
+	8,
+
+	/* y_addr_end    REG=0x3006 */
+	1551,
+
+	/* read_mode     REG=0x3040 */
+	0x0024,
+
+	/* x_output_size REG=0x034C */
+	2064,
+
+	/* y_output_size REG=0x034E */
+	1544,
+
+	/* line_length_pck REG=0x300C */
+	2952,
+
+	/* frame_length_lines    REG=0x300A */
+	1629,
+
+	/* coarse_int_time REG=0x3012 */
+	16,
+
+	/* fine_int_time REG=0x3014   */
+	733
+	}
+};
+
+struct mt9t013_i2c_reg_conf mt9t013_test_tbl[] = {
+	{ 0x3044, 0x0544 & 0xFBFF },
+	{ 0x30CA, 0x0004 | 0x0001 },
+	{ 0x30D4, 0x9020 & 0x7FFF },
+	{ 0x31E0, 0x0003 & 0xFFFE },
+	{ 0x3180, 0x91FF & 0x7FFF },
+	{ 0x301A, (0x10CC | 0x8000) & 0xFFF7 },
+	{ 0x301E, 0x0000 },
+	{ 0x3780, 0x0000 },
+};
+
+/* [Lens shading 85 Percent TL84] */
+struct mt9t013_i2c_reg_conf mt9t013_lc_tbl[] = {
+	{ 0x360A, 0x0290 }, /* P_RD_P0Q0 */
+	{ 0x360C, 0xC92D }, /* P_RD_P0Q1 */
+	{ 0x360E, 0x0771 }, /* P_RD_P0Q2 */
+	{ 0x3610, 0xE38C }, /* P_RD_P0Q3 */
+	{ 0x3612, 0xD74F }, /* P_RD_P0Q4 */
+	{ 0x364A, 0x168C }, /* P_RD_P1Q0 */
+	{ 0x364C, 0xCACB }, /* P_RD_P1Q1 */
+	{ 0x364E, 0x8C4C }, /* P_RD_P1Q2 */
+	{ 0x3650, 0x0BEA }, /* P_RD_P1Q3 */
+	{ 0x3652, 0xDC0F }, /* P_RD_P1Q4 */
+	{ 0x368A, 0x70B0 }, /* P_RD_P2Q0 */
+	{ 0x368C, 0x200B }, /* P_RD_P2Q1 */
+	{ 0x368E, 0x30B2 }, /* P_RD_P2Q2 */
+	{ 0x3690, 0xD04F }, /* P_RD_P2Q3 */
+	{ 0x3692, 0xACF5 }, /* P_RD_P2Q4 */
+	{ 0x36CA, 0xF7C9 }, /* P_RD_P3Q0 */
+	{ 0x36CC, 0x2AED }, /* P_RD_P3Q1 */
+	{ 0x36CE, 0xA652 }, /* P_RD_P3Q2 */
+	{ 0x36D0, 0x8192 }, /* P_RD_P3Q3 */
+	{ 0x36D2, 0x3A15 }, /* P_RD_P3Q4 */
+	{ 0x370A, 0xDA30 }, /* P_RD_P4Q0 */
+	{ 0x370C, 0x2E2F }, /* P_RD_P4Q1 */
+	{ 0x370E, 0xBB56 }, /* P_RD_P4Q2 */
+	{ 0x3710, 0x8195 }, /* P_RD_P4Q3 */
+	{ 0x3712, 0x02F9 }, /* P_RD_P4Q4 */
+	{ 0x3600, 0x0230 }, /* P_GR_P0Q0 */
+	{ 0x3602, 0x58AD }, /* P_GR_P0Q1 */
+	{ 0x3604, 0x18D1 }, /* P_GR_P0Q2 */
+	{ 0x3606, 0x260D }, /* P_GR_P0Q3 */
+	{ 0x3608, 0xF530 }, /* P_GR_P0Q4 */
+	{ 0x3640, 0x17EB }, /* P_GR_P1Q0 */
+	{ 0x3642, 0x3CAB }, /* P_GR_P1Q1 */
+	{ 0x3644, 0x87CE }, /* P_GR_P1Q2 */
+	{ 0x3646, 0xC02E }, /* P_GR_P1Q3 */
+	{ 0x3648, 0xF48F }, /* P_GR_P1Q4 */
+	{ 0x3680, 0x5350 }, /* P_GR_P2Q0 */
+	{ 0x3682, 0x7EAF }, /* P_GR_P2Q1 */
+	{ 0x3684, 0x4312 }, /* P_GR_P2Q2 */
+	{ 0x3686, 0xC652 }, /* P_GR_P2Q3 */
+	{ 0x3688, 0xBC15 }, /* P_GR_P2Q4 */
+	{ 0x36C0, 0xB8AD }, /* P_GR_P3Q0 */
+	{ 0x36C2, 0xBDCD }, /* P_GR_P3Q1 */
+	{ 0x36C4, 0xE4B2 }, /* P_GR_P3Q2 */
+	{ 0x36C6, 0xB50F }, /* P_GR_P3Q3 */
+	{ 0x36C8, 0x5B95 }, /* P_GR_P3Q4 */
+	{ 0x3700, 0xFC90 }, /* P_GR_P4Q0 */
+	{ 0x3702, 0x8C51 }, /* P_GR_P4Q1 */
+	{ 0x3704, 0xCED6 }, /* P_GR_P4Q2 */
+	{ 0x3706, 0xB594 }, /* P_GR_P4Q3 */
+	{ 0x3708, 0x0A39 }, /* P_GR_P4Q4 */
+	{ 0x3614, 0x0230 }, /* P_BL_P0Q0 */
+	{ 0x3616, 0x160D }, /* P_BL_P0Q1 */
+	{ 0x3618, 0x08D1 }, /* P_BL_P0Q2 */
+	{ 0x361A, 0x98AB }, /* P_BL_P0Q3 */
+	{ 0x361C, 0xEA50 }, /* P_BL_P0Q4 */
+	{ 0x3654, 0xB4EA }, /* P_BL_P1Q0 */
+	{ 0x3656, 0xEA6C }, /* P_BL_P1Q1 */
+	{ 0x3658, 0xFE08 }, /* P_BL_P1Q2 */
+	{ 0x365A, 0x2C6E }, /* P_BL_P1Q3 */
+	{ 0x365C, 0xEB0E }, /* P_BL_P1Q4 */
+	{ 0x3694, 0x6DF0 }, /* P_BL_P2Q0 */
+	{ 0x3696, 0x3ACF }, /* P_BL_P2Q1 */
+	{ 0x3698, 0x3E0F }, /* P_BL_P2Q2 */
+	{ 0x369A, 0xB2B1 }, /* P_BL_P2Q3 */
+	{ 0x369C, 0xC374 }, /* P_BL_P2Q4 */
+	{ 0x36D4, 0xF2AA }, /* P_BL_P3Q0 */
+	{ 0x36D6, 0x8CCC }, /* P_BL_P3Q1 */
+	{ 0x36D8, 0xDEF2 }, /* P_BL_P3Q2 */
+	{ 0x36DA, 0xFA11 }, /* P_BL_P3Q3 */
+	{ 0x36DC, 0x42F5 }, /* P_BL_P3Q4 */
+	{ 0x3714, 0xF4F1 }, /* P_BL_P4Q0 */
+	{ 0x3716, 0xF6F0 }, /* P_BL_P4Q1 */
+	{ 0x3718, 0x8FD6 }, /* P_BL_P4Q2 */
+	{ 0x371A, 0xEA14 }, /* P_BL_P4Q3 */
+	{ 0x371C, 0x6338 }, /* P_BL_P4Q4 */
+	{ 0x361E, 0x0350 }, /* P_GB_P0Q0 */
+	{ 0x3620, 0x91AE }, /* P_GB_P0Q1 */
+	{ 0x3622, 0x0571 }, /* P_GB_P0Q2 */
+	{ 0x3624, 0x100D }, /* P_GB_P0Q3 */
+	{ 0x3626, 0xCA70 }, /* P_GB_P0Q4 */
+	{ 0x365E, 0xE6CB }, /* P_GB_P1Q0 */
+	{ 0x3660, 0x50ED }, /* P_GB_P1Q1 */
+	{ 0x3662, 0x3DAE }, /* P_GB_P1Q2 */
+	{ 0x3664, 0xAA4F }, /* P_GB_P1Q3 */
+	{ 0x3666, 0xDC50 }, /* P_GB_P1Q4 */
+	{ 0x369E, 0x5470 }, /* P_GB_P2Q0 */
+	{ 0x36A0, 0x1F6E }, /* P_GB_P2Q1 */
+	{ 0x36A2, 0x6671 }, /* P_GB_P2Q2 */
+	{ 0x36A4, 0xC010 }, /* P_GB_P2Q3 */
+	{ 0x36A6, 0x8DF5 }, /* P_GB_P2Q4 */
+	{ 0x36DE, 0x0B0C }, /* P_GB_P3Q0 */
+	{ 0x36E0, 0x84CE }, /* P_GB_P3Q1 */
+	{ 0x36E2, 0x8493 }, /* P_GB_P3Q2 */
+	{ 0x36E4, 0xA610 }, /* P_GB_P3Q3 */
+	{ 0x36E6, 0x50B5 }, /* P_GB_P3Q4 */
+	{ 0x371E, 0x9651 }, /* P_GB_P4Q0 */
+	{ 0x3720, 0x1EAB }, /* P_GB_P4Q1 */
+	{ 0x3722, 0xAF76 }, /* P_GB_P4Q2 */
+	{ 0x3724, 0xE4F4 }, /* P_GB_P4Q3 */
+	{ 0x3726, 0x79F8 }, /* P_GB_P4Q4 */
+	{ 0x3782, 0x0410 }, /* POLY_ORIGIN_C */
+	{ 0x3784, 0x0320 }, /* POLY_ORIGIN_R  */
+	{ 0x3780, 0x8000 } /* POLY_SC_ENABLE */
+};
+
+struct mt9t013_reg mt9t013_regs = {
+	.reg_pat = &mt9t013_reg_pat[0],
+	.reg_pat_size = ARRAY_SIZE(mt9t013_reg_pat),
+	.ttbl = &mt9t013_test_tbl[0],
+	.ttbl_size = ARRAY_SIZE(mt9t013_test_tbl),
+	.lctbl = &mt9t013_lc_tbl[0],
+	.lctbl_size = ARRAY_SIZE(mt9t013_lc_tbl),
+	.rftbl = &mt9t013_lc_tbl[0],	/* &mt9t013_rolloff_tbl[0], */
+	.rftbl_size = ARRAY_SIZE(mt9t013_lc_tbl)
+};
+
+
diff --git a/drivers/staging/dream/camera/s5k3e2fx.c b/drivers/staging/dream/camera/s5k3e2fx.c
new file mode 100644
index 0000000..edba198
--- /dev/null
+++ b/drivers/staging/dream/camera/s5k3e2fx.c
@@ -0,0 +1,1310 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <media/msm_camera.h>
+#include <mach/gpio.h>
+#include <mach/camera.h>
+#include "s5k3e2fx.h"
+
+#define S5K3E2FX_REG_MODEL_ID   0x0000
+#define S5K3E2FX_MODEL_ID   		0x3E2F
+
+/* PLL Registers */
+#define REG_PRE_PLL_CLK_DIV       		0x0305
+#define REG_PLL_MULTIPLIER_MSB    		0x0306
+#define REG_PLL_MULTIPLIER_LSB    		0x0307
+#define REG_VT_PIX_CLK_DIV        		0x0301
+#define REG_VT_SYS_CLK_DIV        		0x0303
+#define REG_OP_PIX_CLK_DIV        		0x0309
+#define REG_OP_SYS_CLK_DIV        		0x030B
+
+/* Data Format Registers */
+#define REG_CCP_DATA_FORMAT_MSB   		0x0112
+#define REG_CCP_DATA_FORMAT_LSB   		0x0113
+
+/* Output Size */
+#define REG_X_OUTPUT_SIZE_MSB     		0x034C
+#define REG_X_OUTPUT_SIZE_LSB     		0x034D
+#define REG_Y_OUTPUT_SIZE_MSB     		0x034E
+#define REG_Y_OUTPUT_SIZE_LSB     		0x034F
+
+/* Binning */
+#define REG_X_EVEN_INC            		0x0381
+#define REG_X_ODD_INC             		0x0383
+#define REG_Y_EVEN_INC            		0x0385
+#define REG_Y_ODD_INC             		0x0387
+/*Reserved register */
+#define REG_BINNING_ENABLE        		0x3014
+
+/* Frame Fotmat */
+#define REG_FRAME_LENGTH_LINES_MSB		0x0340
+#define REG_FRAME_LENGTH_LINES_LSB		0x0341
+#define REG_LINE_LENGTH_PCK_MSB   		0x0342
+#define REG_LINE_LENGTH_PCK_LSB   		0x0343
+
+/* MSR setting */
+/* Reserved registers */
+#define REG_SHADE_CLK_ENABLE      		0x30AC
+#define REG_SEL_CCP               		0x30C4
+#define REG_VPIX                  		0x3024
+#define REG_CLAMP_ON              		0x3015
+#define REG_OFFSET                		0x307E
+
+/* CDS timing settings */
+/* Reserved registers */
+#define REG_LD_START              		0x3000
+#define REG_LD_END                		0x3001
+#define REG_SL_START              		0x3002
+#define REG_SL_END                		0x3003
+#define REG_RX_START              		0x3004
+#define REG_S1_START              		0x3005
+#define REG_S1_END                		0x3006
+#define REG_S1S_START             		0x3007
+#define REG_S1S_END               		0x3008
+#define REG_S3_START              		0x3009
+#define REG_S3_END                		0x300A
+#define REG_CMP_EN_START          		0x300B
+#define REG_CLP_SL_START          		0x300C
+#define REG_CLP_SL_END            		0x300D
+#define REG_OFF_START             		0x300E
+#define REG_RMP_EN_START          		0x300F
+#define REG_TX_START              		0x3010
+#define REG_TX_END                		0x3011
+#define REG_STX_WIDTH             		0x3012
+#define REG_TYPE1_AF_ENABLE       		0x3130
+#define DRIVER_ENABLED            		0x0001
+#define AUTO_START_ENABLED        		0x0010
+#define REG_NEW_POSITION          		0x3131
+#define REG_3152_RESERVED         		0x3152
+#define REG_315A_RESERVED         		0x315A
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB 0x0204
+#define REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB 0x0205
+#define REG_FINE_INTEGRATION_TIME     		0x0200
+#define REG_COARSE_INTEGRATION_TIME   		0x0202
+#define REG_COARSE_INTEGRATION_TIME_LSB   0x0203
+
+/* Mode select register */
+#define S5K3E2FX_REG_MODE_SELECT  		0x0100
+#define S5K3E2FX_MODE_SELECT_STREAM 		0x01   /* start streaming */
+#define S5K3E2FX_MODE_SELECT_SW_STANDBY 0x00   /* software standby */
+#define S5K3E2FX_REG_SOFTWARE_RESET   0x0103
+#define S5K3E2FX_SOFTWARE_RESET     		0x01
+#define REG_TEST_PATTERN_MODE     		0x0601
+
+struct reg_struct {
+	uint8_t pre_pll_clk_div;               /* 0x0305 */
+	uint8_t pll_multiplier_msb;            /* 0x0306 */
+	uint8_t pll_multiplier_lsb;            /* 0x0307 */
+	uint8_t vt_pix_clk_div;                /* 0x0301 */
+	uint8_t vt_sys_clk_div;                /* 0x0303 */
+	uint8_t op_pix_clk_div;                /* 0x0309 */
+	uint8_t op_sys_clk_div;                /* 0x030B */
+	uint8_t ccp_data_format_msb;           /* 0x0112 */
+	uint8_t ccp_data_format_lsb;           /* 0x0113 */
+	uint8_t x_output_size_msb;             /* 0x034C */
+	uint8_t x_output_size_lsb;             /* 0x034D */
+	uint8_t y_output_size_msb;             /* 0x034E */
+	uint8_t y_output_size_lsb;             /* 0x034F */
+	uint8_t x_even_inc;                    /* 0x0381 */
+	uint8_t x_odd_inc;                     /* 0x0383 */
+	uint8_t y_even_inc;                    /* 0x0385 */
+	uint8_t y_odd_inc;                     /* 0x0387 */
+	uint8_t binning_enable;                /* 0x3014 */
+	uint8_t frame_length_lines_msb;        /* 0x0340 */
+	uint8_t frame_length_lines_lsb;        /* 0x0341 */
+	uint8_t line_length_pck_msb;           /* 0x0342 */
+	uint8_t line_length_pck_lsb;           /* 0x0343 */
+	uint8_t shade_clk_enable ;             /* 0x30AC */
+	uint8_t sel_ccp;                       /* 0x30C4 */
+	uint8_t vpix;                          /* 0x3024 */
+	uint8_t clamp_on;                      /* 0x3015 */
+	uint8_t offset;                        /* 0x307E */
+	uint8_t ld_start;                      /* 0x3000 */
+	uint8_t ld_end;                        /* 0x3001 */
+	uint8_t sl_start;                      /* 0x3002 */
+	uint8_t sl_end;                        /* 0x3003 */
+	uint8_t rx_start;                      /* 0x3004 */
+	uint8_t s1_start;                      /* 0x3005 */
+	uint8_t s1_end;                        /* 0x3006 */
+	uint8_t s1s_start;                     /* 0x3007 */
+	uint8_t s1s_end;                       /* 0x3008 */
+	uint8_t s3_start;                      /* 0x3009 */
+	uint8_t s3_end;                        /* 0x300A */
+	uint8_t cmp_en_start;                  /* 0x300B */
+	uint8_t clp_sl_start;                  /* 0x300C */
+	uint8_t clp_sl_end;                    /* 0x300D */
+	uint8_t off_start;                     /* 0x300E */
+	uint8_t rmp_en_start;                  /* 0x300F */
+	uint8_t tx_start;                      /* 0x3010 */
+	uint8_t tx_end;                        /* 0x3011 */
+	uint8_t stx_width;                     /* 0x3012 */
+	uint8_t reg_3152_reserved;             /* 0x3152 */
+	uint8_t reg_315A_reserved;             /* 0x315A */
+	uint8_t analogue_gain_code_global_msb; /* 0x0204 */
+	uint8_t analogue_gain_code_global_lsb; /* 0x0205 */
+	uint8_t fine_integration_time;         /* 0x0200 */
+	uint8_t coarse_integration_time;       /* 0x0202 */
+	uint32_t size_h;
+	uint32_t blk_l;
+	uint32_t size_w;
+	uint32_t blk_p;
+};
+
+struct reg_struct s5k3e2fx_reg_pat[2] = {
+	{ /* Preview */
+		0x06,  /* pre_pll_clk_div       REG=0x0305 */
+		0x00,  /* pll_multiplier_msb    REG=0x0306 */
+		0x88,  /* pll_multiplier_lsb    REG=0x0307 */
+		0x0a,  /* vt_pix_clk_div        REG=0x0301 */
+		0x01,  /* vt_sys_clk_div        REG=0x0303 */
+		0x0a,  /* op_pix_clk_div        REG=0x0309 */
+		0x01,  /* op_sys_clk_div        REG=0x030B */
+		0x0a,  /* ccp_data_format_msb   REG=0x0112 */
+		0x0a,  /* ccp_data_format_lsb   REG=0x0113 */
+		0x05,  /* x_output_size_msb     REG=0x034C */
+		0x10,  /* x_output_size_lsb     REG=0x034D */
+		0x03,  /* y_output_size_msb     REG=0x034E */
+		0xcc,  /* y_output_size_lsb     REG=0x034F */
+
+	/* enable binning for preview */
+		0x01,  /* x_even_inc             REG=0x0381 */
+		0x01,  /* x_odd_inc              REG=0x0383 */
+		0x01,  /* y_even_inc             REG=0x0385 */
+		0x03,  /* y_odd_inc              REG=0x0387 */
+		0x06,  /* binning_enable         REG=0x3014 */
+
+		0x03,  /* frame_length_lines_msb        REG=0x0340 */
+		0xde,  /* frame_length_lines_lsb        REG=0x0341 */
+		0x0a,  /* line_length_pck_msb           REG=0x0342 */
+		0xac,  /* line_length_pck_lsb           REG=0x0343 */
+		0x81,  /* shade_clk_enable              REG=0x30AC */
+		0x01,  /* sel_ccp                       REG=0x30C4 */
+		0x04,  /* vpix                          REG=0x3024 */
+		0x00,  /* clamp_on                      REG=0x3015 */
+		0x02,  /* offset                        REG=0x307E */
+		0x03,  /* ld_start                      REG=0x3000 */
+		0x9c,  /* ld_end                        REG=0x3001 */
+		0x02,  /* sl_start                      REG=0x3002 */
+		0x9e,  /* sl_end                        REG=0x3003 */
+		0x05,  /* rx_start                      REG=0x3004 */
+		0x0f,  /* s1_start                      REG=0x3005 */
+		0x24,  /* s1_end                        REG=0x3006 */
+		0x7c,  /* s1s_start                     REG=0x3007 */
+		0x9a,  /* s1s_end                       REG=0x3008 */
+		0x10,  /* s3_start                      REG=0x3009 */
+		0x14,  /* s3_end                        REG=0x300A */
+		0x10,  /* cmp_en_start                  REG=0x300B */
+		0x04,  /* clp_sl_start                  REG=0x300C */
+		0x26,  /* clp_sl_end                    REG=0x300D */
+		0x02,  /* off_start                     REG=0x300E */
+		0x0e,  /* rmp_en_start                  REG=0x300F */
+		0x30,  /* tx_start                      REG=0x3010 */
+		0x4e,  /* tx_end                        REG=0x3011 */
+		0x1E,  /* stx_width                     REG=0x3012 */
+		0x08,  /* reg_3152_reserved             REG=0x3152 */
+		0x10,  /* reg_315A_reserved             REG=0x315A */
+		0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
+		0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
+		0x02,  /* fine_integration_time         REG=0x0200 */
+		0x03,  /* coarse_integration_time       REG=0x0202 */
+		972,
+		18,
+		1296,
+		1436
+	},
+	{ /* Snapshot */
+		0x06,  /* pre_pll_clk_div               REG=0x0305 */
+		0x00,  /* pll_multiplier_msb            REG=0x0306 */
+		0x88,  /* pll_multiplier_lsb            REG=0x0307 */
+		0x0a,  /* vt_pix_clk_div                REG=0x0301 */
+		0x01,  /* vt_sys_clk_div                REG=0x0303 */
+		0x0a,  /* op_pix_clk_div                REG=0x0309 */
+		0x01,  /* op_sys_clk_div                REG=0x030B */
+		0x0a,  /* ccp_data_format_msb           REG=0x0112 */
+		0x0a,  /* ccp_data_format_lsb           REG=0x0113 */
+		0x0a,  /* x_output_size_msb             REG=0x034C */
+		0x30,  /* x_output_size_lsb             REG=0x034D */
+		0x07,  /* y_output_size_msb             REG=0x034E */
+		0xa8,  /* y_output_size_lsb             REG=0x034F */
+
+	/* disable binning for snapshot */
+		0x01,  /* x_even_inc                    REG=0x0381 */
+		0x01,  /* x_odd_inc                     REG=0x0383 */
+		0x01,  /* y_even_inc                    REG=0x0385 */
+		0x01,  /* y_odd_inc                     REG=0x0387 */
+		0x00,  /* binning_enable                REG=0x3014 */
+
+		0x07,  /* frame_length_lines_msb        REG=0x0340 */
+		0xb6,  /* frame_length_lines_lsb        REG=0x0341 */
+		0x0a,  /* line_length_pck_msb           REG=0x0342 */
+		0xac,  /* line_length_pck_lsb           REG=0x0343 */
+		0x81,  /* shade_clk_enable              REG=0x30AC */
+		0x01,  /* sel_ccp                       REG=0x30C4 */
+		0x04,  /* vpix                          REG=0x3024 */
+		0x00,  /* clamp_on                      REG=0x3015 */
+		0x02,  /* offset                        REG=0x307E */
+		0x03,  /* ld_start                      REG=0x3000 */
+		0x9c,  /* ld_end                        REG=0x3001 */
+		0x02,  /* sl_start                      REG=0x3002 */
+		0x9e,  /* sl_end                        REG=0x3003 */
+		0x05,  /* rx_start                      REG=0x3004 */
+		0x0f,  /* s1_start                      REG=0x3005 */
+		0x24,  /* s1_end                        REG=0x3006 */
+		0x7c,  /* s1s_start                     REG=0x3007 */
+		0x9a,  /* s1s_end                       REG=0x3008 */
+		0x10,  /* s3_start                      REG=0x3009 */
+		0x14,  /* s3_end                        REG=0x300A */
+		0x10,  /* cmp_en_start                  REG=0x300B */
+		0x04,  /* clp_sl_start                  REG=0x300C */
+		0x26,  /* clp_sl_end                    REG=0x300D */
+		0x02,  /* off_start                     REG=0x300E */
+		0x0e,  /* rmp_en_start                  REG=0x300F */
+		0x30,  /* tx_start                      REG=0x3010 */
+		0x4e,  /* tx_end                        REG=0x3011 */
+		0x1E,  /* stx_width                     REG=0x3012 */
+		0x08,  /* reg_3152_reserved             REG=0x3152 */
+		0x10,  /* reg_315A_reserved             REG=0x315A */
+		0x00,  /* analogue_gain_code_global_msb REG=0x0204 */
+		0x80,  /* analogue_gain_code_global_lsb REG=0x0205 */
+		0x02,  /* fine_integration_time         REG=0x0200 */
+		0x03,  /* coarse_integration_time       REG=0x0202 */
+		1960,
+		14,
+		2608,
+		124
+	}
+};
+
+struct s5k3e2fx_work {
+	struct work_struct work;
+};
+static struct s5k3e2fx_work *s5k3e2fx_sensorw;
+static struct i2c_client *s5k3e2fx_client;
+
+struct s5k3e2fx_ctrl {
+	const struct msm_camera_sensor_info *sensordata;
+
+	int sensormode;
+	uint32_t fps_divider; /* init to 1 * 0x00000400 */
+	uint32_t pict_fps_divider; /* init to 1 * 0x00000400 */
+
+	uint16_t curr_lens_pos;
+	uint16_t init_curr_lens_pos;
+	uint16_t my_reg_gain;
+	uint32_t my_reg_line_count;
+
+	enum msm_s_resolution prev_res;
+	enum msm_s_resolution pict_res;
+	enum msm_s_resolution curr_res;
+	enum msm_s_test_mode  set_test;
+};
+
+struct s5k3e2fx_i2c_reg_conf {
+	unsigned short waddr;
+	unsigned char  bdata;
+};
+
+static struct s5k3e2fx_ctrl *s5k3e2fx_ctrl;
+static DECLARE_WAIT_QUEUE_HEAD(s5k3e2fx_wait_queue);
+DECLARE_MUTEX(s5k3e2fx_sem);
+
+static int s5k3e2fx_i2c_rxdata(unsigned short saddr, unsigned char *rxdata,
+	int length)
+{
+	struct i2c_msg msgs[] = {
+		{
+			.addr   = saddr,
+			.flags = 0,
+			.len   = 2,
+			.buf   = rxdata,
+		},
+		{
+			.addr   = saddr,
+			.flags = I2C_M_RD,
+			.len   = length,
+			.buf   = rxdata,
+		},
+	};
+
+	if (i2c_transfer(s5k3e2fx_client->adapter, msgs, 2) < 0) {
+		CDBG("s5k3e2fx_i2c_rxdata failed!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t s5k3e2fx_i2c_txdata(unsigned short saddr,
+	unsigned char *txdata, int length)
+{
+	struct i2c_msg msg[] = {
+		{
+		.addr  = saddr,
+		.flags = 0,
+		.len = length,
+		.buf = txdata,
+		},
+	};
+
+	if (i2c_transfer(s5k3e2fx_client->adapter, msg, 1) < 0) {
+		CDBG("s5k3e2fx_i2c_txdata failed\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int32_t s5k3e2fx_i2c_write_b(unsigned short saddr, unsigned short waddr,
+	unsigned char bdata)
+{
+	int32_t rc = -EIO;
+	unsigned char buf[4];
+
+	memset(buf, 0, sizeof(buf));
+	buf[0] = (waddr & 0xFF00)>>8;
+	buf[1] = (waddr & 0x00FF);
+	buf[2] = bdata;
+
+	rc = s5k3e2fx_i2c_txdata(saddr, buf, 3);
+
+	if (rc < 0)
+		CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
+			waddr, bdata);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_i2c_write_table(
+	struct s5k3e2fx_i2c_reg_conf *reg_cfg_tbl, int num)
+{
+	int i;
+	int32_t rc = -EIO;
+	for (i = 0; i < num; i++) {
+		if (rc < 0)
+			break;
+		reg_cfg_tbl++;
+	}
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_i2c_read_w(unsigned short saddr, unsigned short raddr,
+	unsigned short *rdata)
+{
+	int32_t rc = 0;
+	unsigned char buf[4];
+
+	if (!rdata)
+		return -EIO;
+
+	memset(buf, 0, sizeof(buf));
+
+	buf[0] = (raddr & 0xFF00)>>8;
+	buf[1] = (raddr & 0x00FF);
+
+	rc = s5k3e2fx_i2c_rxdata(saddr, buf, 2);
+	if (rc < 0)
+		return rc;
+
+	*rdata = buf[0] << 8 | buf[1];
+
+	if (rc < 0)
+		CDBG("s5k3e2fx_i2c_read failed!\n");
+
+	return rc;
+}
+
+static int s5k3e2fx_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+	gpio_direction_output(data->sensor_reset, 0);
+	gpio_free(data->sensor_reset);
+	return 0;
+}
+
+static int s5k3e2fx_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+	uint16_t chipid = 0;
+
+	rc = gpio_request(data->sensor_reset, "s5k3e2fx");
+	if (!rc)
+		gpio_direction_output(data->sensor_reset, 1);
+	else
+		goto init_probe_done;
+
+	mdelay(20);
+
+	CDBG("s5k3e2fx_sensor_init(): reseting sensor.\n");
+
+	rc = s5k3e2fx_i2c_read_w(s5k3e2fx_client->addr,
+		S5K3E2FX_REG_MODEL_ID, &chipid);
+	if (rc < 0)
+		goto init_probe_fail;
+
+	if (chipid != S5K3E2FX_MODEL_ID) {
+		CDBG("S5K3E2FX wrong model_id = 0x%x\n", chipid);
+		rc = -ENODEV;
+		goto init_probe_fail;
+	}
+
+	goto init_probe_done;
+
+init_probe_fail:
+	s5k3e2fx_probe_init_done(data);
+init_probe_done:
+	return rc;
+}
+
+static int s5k3e2fx_init_client(struct i2c_client *client)
+{
+	/* Initialize the MSM_CAMI2C Chip */
+	init_waitqueue_head(&s5k3e2fx_wait_queue);
+	return 0;
+}
+
+static const struct i2c_device_id s5k3e2fx_i2c_id[] = {
+	{ "s5k3e2fx", 0},
+	{ }
+};
+
+static int s5k3e2fx_i2c_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	int rc = 0;
+	CDBG("s5k3e2fx_probe called!\n");
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		CDBG("i2c_check_functionality failed\n");
+		goto probe_failure;
+	}
+
+	s5k3e2fx_sensorw = kzalloc(sizeof(struct s5k3e2fx_work), GFP_KERNEL);
+	if (!s5k3e2fx_sensorw) {
+		CDBG("kzalloc failed.\n");
+		rc = -ENOMEM;
+		goto probe_failure;
+	}
+
+	i2c_set_clientdata(client, s5k3e2fx_sensorw);
+	s5k3e2fx_init_client(client);
+	s5k3e2fx_client = client;
+
+	mdelay(50);
+
+	CDBG("s5k3e2fx_probe successed! rc = %d\n", rc);
+	return 0;
+
+probe_failure:
+	CDBG("s5k3e2fx_probe failed! rc = %d\n", rc);
+	return rc;
+}
+
+static struct i2c_driver s5k3e2fx_i2c_driver = {
+	.id_table = s5k3e2fx_i2c_id,
+	.probe  = s5k3e2fx_i2c_probe,
+	.remove = __exit_p(s5k3e2fx_i2c_remove),
+	.driver = {
+		.name = "s5k3e2fx",
+	},
+};
+
+static int32_t s5k3e2fx_test(enum msm_s_test_mode mo)
+{
+	int32_t rc = 0;
+
+	if (mo == S_TEST_OFF)
+		rc = 0;
+	else
+		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			REG_TEST_PATTERN_MODE, (uint16_t)mo);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_setting(enum msm_s_reg_update rupdate,
+	enum msm_s_setting rt)
+{
+	int32_t rc = 0;
+	uint16_t num_lperf;
+
+	switch (rupdate) {
+	case S_UPDATE_PERIODIC:
+	if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
+
+		struct s5k3e2fx_i2c_reg_conf tbl_1[] = {
+		{REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
+		{REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
+		{REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb},
+		{REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb},
+		{REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb},
+		{REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb},
+		{REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
+		{REG_X_ODD_INC,  s5k3e2fx_reg_pat[rt].x_odd_inc},
+		{REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
+		{REG_Y_ODD_INC,  s5k3e2fx_reg_pat[rt].y_odd_inc},
+		{REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable},
+		};
+
+		struct s5k3e2fx_i2c_reg_conf tbl_2[] = {
+			{REG_FRAME_LENGTH_LINES_MSB, 0},
+			{REG_FRAME_LENGTH_LINES_LSB, 0},
+			{REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb},
+			{REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
+			{REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable},
+			{REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
+			{REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
+			{REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
+			{REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
+			{REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
+			{REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
+			{REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
+			{REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
+			{REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
+			{REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
+			{REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
+			{REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
+			{REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
+			{REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
+			{REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
+			{REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
+			{REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
+			{REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
+			{REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
+			{REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
+			{REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
+			{REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
+			{REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
+			{REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved},
+			{REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb},
+			{REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time},
+			{REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time},
+			{S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
+		};
+
+		rc = s5k3e2fx_i2c_write_table(&tbl_1[0],
+			ARRAY_SIZE(tbl_1));
+		if (rc < 0)
+			return rc;
+
+		num_lperf =
+			(uint16_t)((s5k3e2fx_reg_pat[rt].frame_length_lines_msb << 8) & 0xFF00) +
+				s5k3e2fx_reg_pat[rt].frame_length_lines_lsb;
+
+		num_lperf = num_lperf * s5k3e2fx_ctrl->fps_divider / 0x0400;
+
+		tbl_2[0] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_MSB, (num_lperf & 0xFF00) >> 8};
+		tbl_2[1] = (struct s5k3e2fx_i2c_reg_conf) {REG_FRAME_LENGTH_LINES_LSB, (num_lperf & 0x00FF)};
+
+		rc = s5k3e2fx_i2c_write_table(&tbl_2[0],
+			ARRAY_SIZE(tbl_2));
+		if (rc < 0)
+			return rc;
+
+		mdelay(5);
+
+		rc = s5k3e2fx_test(s5k3e2fx_ctrl->set_test);
+		if (rc < 0)
+			return rc;
+	}
+	break; /* UPDATE_PERIODIC */
+
+	case S_REG_INIT:
+	if (rt == S_RES_PREVIEW || rt == S_RES_CAPTURE) {
+
+		struct s5k3e2fx_i2c_reg_conf tbl_3[] = {
+			{S5K3E2FX_REG_SOFTWARE_RESET, S5K3E2FX_SOFTWARE_RESET},
+			{S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_SW_STANDBY},
+			/* PLL setting */
+			{REG_PRE_PLL_CLK_DIV, s5k3e2fx_reg_pat[rt].pre_pll_clk_div},
+			{REG_PLL_MULTIPLIER_MSB, s5k3e2fx_reg_pat[rt].pll_multiplier_msb},
+			{REG_PLL_MULTIPLIER_LSB, s5k3e2fx_reg_pat[rt].pll_multiplier_lsb},
+			{REG_VT_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_pix_clk_div},
+			{REG_VT_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].vt_sys_clk_div},
+			{REG_OP_PIX_CLK_DIV, s5k3e2fx_reg_pat[rt].op_pix_clk_div},
+			{REG_OP_SYS_CLK_DIV, s5k3e2fx_reg_pat[rt].op_sys_clk_div},
+			/*Data Format */
+			{REG_CCP_DATA_FORMAT_MSB, s5k3e2fx_reg_pat[rt].ccp_data_format_msb},
+			{REG_CCP_DATA_FORMAT_LSB, s5k3e2fx_reg_pat[rt].ccp_data_format_lsb},
+			/*Output Size */
+			{REG_X_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].x_output_size_msb},
+			{REG_X_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].x_output_size_lsb},
+			{REG_Y_OUTPUT_SIZE_MSB, s5k3e2fx_reg_pat[rt].y_output_size_msb},
+			{REG_Y_OUTPUT_SIZE_LSB, s5k3e2fx_reg_pat[rt].y_output_size_lsb},
+			/* Binning */
+			{REG_X_EVEN_INC, s5k3e2fx_reg_pat[rt].x_even_inc},
+			{REG_X_ODD_INC, s5k3e2fx_reg_pat[rt].x_odd_inc },
+			{REG_Y_EVEN_INC, s5k3e2fx_reg_pat[rt].y_even_inc},
+			{REG_Y_ODD_INC, s5k3e2fx_reg_pat[rt].y_odd_inc},
+			{REG_BINNING_ENABLE, s5k3e2fx_reg_pat[rt].binning_enable},
+			/* Frame format */
+			{REG_FRAME_LENGTH_LINES_MSB, s5k3e2fx_reg_pat[rt].frame_length_lines_msb},
+			{REG_FRAME_LENGTH_LINES_LSB, s5k3e2fx_reg_pat[rt].frame_length_lines_lsb},
+			{REG_LINE_LENGTH_PCK_MSB, s5k3e2fx_reg_pat[rt].line_length_pck_msb},
+			{REG_LINE_LENGTH_PCK_LSB, s5k3e2fx_reg_pat[rt].line_length_pck_lsb},
+			/* MSR setting */
+			{REG_SHADE_CLK_ENABLE, s5k3e2fx_reg_pat[rt].shade_clk_enable},
+			{REG_SEL_CCP, s5k3e2fx_reg_pat[rt].sel_ccp},
+			{REG_VPIX, s5k3e2fx_reg_pat[rt].vpix},
+			{REG_CLAMP_ON, s5k3e2fx_reg_pat[rt].clamp_on},
+			{REG_OFFSET, s5k3e2fx_reg_pat[rt].offset},
+			/* CDS timing setting */
+			{REG_LD_START, s5k3e2fx_reg_pat[rt].ld_start},
+			{REG_LD_END, s5k3e2fx_reg_pat[rt].ld_end},
+			{REG_SL_START, s5k3e2fx_reg_pat[rt].sl_start},
+			{REG_SL_END, s5k3e2fx_reg_pat[rt].sl_end},
+			{REG_RX_START, s5k3e2fx_reg_pat[rt].rx_start},
+			{REG_S1_START, s5k3e2fx_reg_pat[rt].s1_start},
+			{REG_S1_END, s5k3e2fx_reg_pat[rt].s1_end},
+			{REG_S1S_START, s5k3e2fx_reg_pat[rt].s1s_start},
+			{REG_S1S_END, s5k3e2fx_reg_pat[rt].s1s_end},
+			{REG_S3_START, s5k3e2fx_reg_pat[rt].s3_start},
+			{REG_S3_END, s5k3e2fx_reg_pat[rt].s3_end},
+			{REG_CMP_EN_START, s5k3e2fx_reg_pat[rt].cmp_en_start},
+			{REG_CLP_SL_START, s5k3e2fx_reg_pat[rt].clp_sl_start},
+			{REG_CLP_SL_END, s5k3e2fx_reg_pat[rt].clp_sl_end},
+			{REG_OFF_START, s5k3e2fx_reg_pat[rt].off_start},
+			{REG_RMP_EN_START, s5k3e2fx_reg_pat[rt].rmp_en_start},
+			{REG_TX_START, s5k3e2fx_reg_pat[rt].tx_start},
+			{REG_TX_END, s5k3e2fx_reg_pat[rt].tx_end},
+			{REG_STX_WIDTH, s5k3e2fx_reg_pat[rt].stx_width},
+			{REG_3152_RESERVED, s5k3e2fx_reg_pat[rt].reg_3152_reserved},
+			{REG_315A_RESERVED, s5k3e2fx_reg_pat[rt].reg_315A_reserved},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_msb},
+			{REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB, s5k3e2fx_reg_pat[rt].analogue_gain_code_global_lsb},
+			{REG_FINE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].fine_integration_time},
+			{REG_COARSE_INTEGRATION_TIME, s5k3e2fx_reg_pat[rt].coarse_integration_time},
+			{S5K3E2FX_REG_MODE_SELECT, S5K3E2FX_MODE_SELECT_STREAM},
+		};
+
+		/* reset fps_divider */
+		s5k3e2fx_ctrl->fps_divider = 1 * 0x0400;
+		rc = s5k3e2fx_i2c_write_table(&tbl_3[0],
+			ARRAY_SIZE(tbl_3));
+		if (rc < 0)
+			return rc;
+	}
+	break; /* case REG_INIT: */
+
+	default:
+		rc = -EINVAL;
+		break;
+	} /* switch (rupdate) */
+
+	return rc;
+}
+
+static int s5k3e2fx_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+	int32_t  rc;
+
+	s5k3e2fx_ctrl = kzalloc(sizeof(struct s5k3e2fx_ctrl), GFP_KERNEL);
+	if (!s5k3e2fx_ctrl) {
+		CDBG("s5k3e2fx_init failed!\n");
+		rc = -ENOMEM;
+		goto init_done;
+	}
+
+	s5k3e2fx_ctrl->fps_divider = 1 * 0x00000400;
+	s5k3e2fx_ctrl->pict_fps_divider = 1 * 0x00000400;
+	s5k3e2fx_ctrl->set_test = S_TEST_OFF;
+	s5k3e2fx_ctrl->prev_res = S_QTR_SIZE;
+	s5k3e2fx_ctrl->pict_res = S_FULL_SIZE;
+
+	if (data)
+		s5k3e2fx_ctrl->sensordata = data;
+
+	/* enable mclk first */
+	msm_camio_clk_rate_set(24000000);
+	mdelay(20);
+
+	msm_camio_camif_pad_reg_reset();
+	mdelay(20);
+
+	rc = s5k3e2fx_probe_init_sensor(data);
+	if (rc < 0)
+		goto init_fail1;
+
+	if (s5k3e2fx_ctrl->prev_res == S_QTR_SIZE)
+		rc = s5k3e2fx_setting(S_REG_INIT, S_RES_PREVIEW);
+	else
+		rc = s5k3e2fx_setting(S_REG_INIT, S_RES_CAPTURE);
+
+	if (rc < 0) {
+		CDBG("s5k3e2fx_setting failed. rc = %d\n", rc);
+		goto init_fail1;
+	}
+
+	/* initialize AF */
+	if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3146, 0x3A)) < 0)
+		goto init_fail1;
+
+	if ((rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3130, 0x03)) < 0)
+		goto init_fail1;
+
+	goto init_done;
+
+init_fail1:
+	s5k3e2fx_probe_init_done(data);
+	kfree(s5k3e2fx_ctrl);
+init_done:
+	return rc;
+}
+
+static int32_t s5k3e2fx_power_down(void)
+{
+	int32_t rc = 0;
+	return rc;
+}
+
+static int s5k3e2fx_sensor_release(void)
+{
+	int rc = -EBADF;
+
+	down(&s5k3e2fx_sem);
+
+	s5k3e2fx_power_down();
+
+	gpio_direction_output(s5k3e2fx_ctrl->sensordata->sensor_reset,
+		0);
+	gpio_free(s5k3e2fx_ctrl->sensordata->sensor_reset);
+
+	kfree(s5k3e2fx_ctrl);
+	s5k3e2fx_ctrl = NULL;
+
+	CDBG("s5k3e2fx_release completed\n");
+
+	up(&s5k3e2fx_sem);
+	return rc;
+}
+
+static void s5k3e2fx_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+	/* input fps is preview fps in Q8 format */
+	uint32_t divider;   /* Q10 */
+
+	divider = (uint32_t)
+		((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
+		 (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p)) * 0x00000400 /
+		((s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l) *
+		 (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p));
+
+	/* Verify PCLK settings and frame sizes. */
+	*pfps = (uint16_t)(fps * divider / 0x00000400);
+}
+
+static uint16_t s5k3e2fx_get_prev_lines_pf(void)
+{
+	return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l);
+}
+
+static uint16_t s5k3e2fx_get_prev_pixels_pl(void)
+{
+	return (s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_p);
+}
+
+static uint16_t s5k3e2fx_get_pict_lines_pf(void)
+{
+	return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l);
+}
+
+static uint16_t s5k3e2fx_get_pict_pixels_pl(void)
+{
+	return (s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+		s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p);
+}
+
+static uint32_t s5k3e2fx_get_pict_max_exp_lc(void)
+{
+	uint32_t snapshot_lines_per_frame;
+
+	if (s5k3e2fx_ctrl->pict_res == S_QTR_SIZE)
+		snapshot_lines_per_frame =
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+		s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l;
+	else
+		snapshot_lines_per_frame = 3961 * 3;
+
+	return snapshot_lines_per_frame;
+}
+
+static int32_t s5k3e2fx_set_fps(struct fps_cfg *fps)
+{
+	/* input is new fps in Q10 format */
+	int32_t rc = 0;
+
+	s5k3e2fx_ctrl->fps_divider = fps->fps_div;
+
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+		REG_FRAME_LENGTH_LINES_MSB,
+		(((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
+			s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00) >> 8);
+	if (rc < 0)
+		goto set_fps_done;
+
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+		REG_FRAME_LENGTH_LINES_LSB,
+		(((s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+			s5k3e2fx_reg_pat[S_RES_PREVIEW].blk_l) *
+			s5k3e2fx_ctrl->fps_divider / 0x400) & 0xFF00));
+
+set_fps_done:
+	return rc;
+}
+
+static int32_t s5k3e2fx_write_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	uint16_t max_legal_gain = 0x0200;
+	uint32_t ll_ratio; /* Q10 */
+	uint16_t ll_pck, fl_lines;
+	uint16_t offset = 4;
+	uint8_t  gain_msb, gain_lsb;
+	uint8_t  intg_t_msb, intg_t_lsb;
+	uint8_t  ll_pck_msb, ll_pck_lsb, tmp;
+
+	struct s5k3e2fx_i2c_reg_conf tbl[2];
+
+	CDBG("Line:%d s5k3e2fx_write_exp_gain \n", __LINE__);
+
+	if (s5k3e2fx_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+
+		s5k3e2fx_ctrl->my_reg_gain = gain;
+		s5k3e2fx_ctrl->my_reg_line_count = (uint16_t)line;
+
+		fl_lines = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_h +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
+
+		ll_pck = s5k3e2fx_reg_pat[S_RES_PREVIEW].size_w +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
+
+	} else {
+
+		fl_lines = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_h +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_l;
+
+		ll_pck = s5k3e2fx_reg_pat[S_RES_CAPTURE].size_w +
+			s5k3e2fx_reg_pat[S_RES_CAPTURE].blk_p;
+	}
+
+	if (gain > max_legal_gain)
+		gain = max_legal_gain;
+
+	/* in Q10 */
+	line = (line * s5k3e2fx_ctrl->fps_divider);
+
+	if (fl_lines < (line / 0x400))
+		ll_ratio = (line / (fl_lines - offset));
+	else
+		ll_ratio = 0x400;
+
+	/* update gain registers */
+	gain_msb = (gain & 0xFF00) >> 8;
+	gain_lsb = gain & 0x00FF;
+	tbl[0].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_MSB;
+	tbl[0].bdata = gain_msb;
+	tbl[1].waddr = REG_ANALOGUE_GAIN_CODE_GLOBAL_LSB;
+	tbl[1].bdata = gain_lsb;
+	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
+	if (rc < 0)
+		goto write_gain_done;
+
+	ll_pck = ll_pck * ll_ratio;
+	ll_pck_msb = ((ll_pck / 0x400) & 0xFF00) >> 8;
+	ll_pck_lsb = (ll_pck / 0x400) & 0x00FF;
+	tbl[0].waddr = REG_LINE_LENGTH_PCK_MSB;
+	tbl[0].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_msb;
+	tbl[1].waddr = REG_LINE_LENGTH_PCK_LSB;
+	tbl[1].bdata = s5k3e2fx_reg_pat[S_RES_PREVIEW].line_length_pck_lsb;
+	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
+	if (rc < 0)
+		goto write_gain_done;
+
+	tmp = (ll_pck * 0x400) / ll_ratio;
+	intg_t_msb = (tmp & 0xFF00) >> 8;
+	intg_t_lsb = (tmp & 0x00FF);
+	tbl[0].waddr = REG_COARSE_INTEGRATION_TIME;
+	tbl[0].bdata = intg_t_msb;
+	tbl[1].waddr = REG_COARSE_INTEGRATION_TIME_LSB;
+	tbl[1].bdata = intg_t_lsb;
+	rc = s5k3e2fx_i2c_write_table(&tbl[0], ARRAY_SIZE(tbl));
+
+write_gain_done:
+	return rc;
+}
+
+static int32_t s5k3e2fx_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+	int32_t rc = 0;
+
+	CDBG("Line:%d s5k3e2fx_set_pict_exp_gain \n", __LINE__);
+
+	rc =
+		s5k3e2fx_write_exp_gain(gain, line);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_video_config(int mode, int res)
+{
+	int32_t rc;
+
+	switch (res) {
+	case S_QTR_SIZE:
+		rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_PREVIEW);
+		if (rc < 0)
+			return rc;
+
+		CDBG("s5k3e2fx sensor configuration done!\n");
+		break;
+
+	case S_FULL_SIZE:
+		rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+		if (rc < 0)
+			return rc;
+
+		break;
+
+	default:
+		return 0;
+	} /* switch */
+
+	s5k3e2fx_ctrl->prev_res = res;
+	s5k3e2fx_ctrl->curr_res = res;
+	s5k3e2fx_ctrl->sensormode = mode;
+
+	rc =
+		s5k3e2fx_write_exp_gain(s5k3e2fx_ctrl->my_reg_gain,
+			s5k3e2fx_ctrl->my_reg_line_count);
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
+	s5k3e2fx_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_raw_snapshot_config(int mode)
+{
+	int32_t rc = 0;
+
+	rc = s5k3e2fx_setting(S_UPDATE_PERIODIC, S_RES_CAPTURE);
+	if (rc < 0)
+		return rc;
+
+	s5k3e2fx_ctrl->curr_res = s5k3e2fx_ctrl->pict_res;
+	s5k3e2fx_ctrl->sensormode = mode;
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_set_sensor_mode(int mode, int res)
+{
+	int32_t rc = 0;
+
+	switch (mode) {
+	case SENSOR_PREVIEW_MODE:
+		rc = s5k3e2fx_video_config(mode, res);
+		break;
+
+	case SENSOR_SNAPSHOT_MODE:
+		rc = s5k3e2fx_snapshot_config(mode);
+		break;
+
+	case SENSOR_RAW_SNAPSHOT_MODE:
+		rc = s5k3e2fx_raw_snapshot_config(mode);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_set_default_focus(void)
+{
+	int32_t rc = 0;
+
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3131, 0);
+	if (rc < 0)
+		return rc;
+
+	rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr,
+			0x3132, 0);
+	if (rc < 0)
+		return rc;
+
+	s5k3e2fx_ctrl->curr_lens_pos = 0;
+
+	return rc;
+}
+
+static int32_t s5k3e2fx_move_focus(int direction, int32_t num_steps)
+{
+	int32_t rc = 0;
+	int32_t i;
+	int16_t step_direction;
+	int16_t actual_step;
+	int16_t next_pos, pos_offset;
+	int16_t init_code = 50;
+	uint8_t next_pos_msb, next_pos_lsb;
+	int16_t s_move[5];
+	uint32_t gain; /* Q10 format */
+
+	if (direction == MOVE_NEAR)
+		step_direction = 20;
+	else if (direction == MOVE_FAR)
+		step_direction = -20;
+	else {
+		CDBG("s5k3e2fx_move_focus failed at line %d ...\n", __LINE__);
+		return -EINVAL;
+	}
+
+	actual_step = step_direction * (int16_t)num_steps;
+	pos_offset = init_code + s5k3e2fx_ctrl->curr_lens_pos;
+	gain = actual_step * 0x400 / 5;
+
+	for (i = 0; i <= 4; i++) {
+		if (actual_step >= 0)
+			s_move[i] = ((((i+1)*gain+0x200) - (i*gain+0x200))/0x400);
+		else
+			s_move[i] = ((((i+1)*gain-0x200) - (i*gain-0x200))/0x400);
+	}
+
+	/* Ring Damping Code */
+	for (i = 0; i <= 4; i++) {
+		next_pos = (int16_t)(pos_offset + s_move[i]);
+
+		if (next_pos > (738 + init_code))
+			next_pos = 738 + init_code;
+		else if (next_pos < 0)
+			next_pos = 0;
+
+		CDBG("next_position in damping mode = %d\n", next_pos);
+		/* Writing the Values to the actuator */
+		if (next_pos == init_code)
+			next_pos = 0x00;
+
+		next_pos_msb = next_pos >> 8;
+		next_pos_lsb = next_pos & 0x00FF;
+
+		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3131, next_pos_msb);
+		if (rc < 0)
+			break;
+
+		rc = s5k3e2fx_i2c_write_b(s5k3e2fx_client->addr, 0x3132, next_pos_lsb);
+		if (rc < 0)
+			break;
+
+		pos_offset = next_pos;
+		s5k3e2fx_ctrl->curr_lens_pos = pos_offset - init_code;
+		if (i < 4)
+			mdelay(3);
+	}
+
+	return rc;
+}
+
+static int s5k3e2fx_sensor_config(void __user *argp)
+{
+	struct sensor_cfg_data cdata;
+	long   rc = 0;
+
+	if (copy_from_user(&cdata,
+			(void *)argp,
+			sizeof(struct sensor_cfg_data)))
+		return -EFAULT;
+
+	down(&s5k3e2fx_sem);
+
+	CDBG("%s: cfgtype = %d\n", __func__, cdata.cfgtype);
+	switch (cdata.cfgtype) {
+	case CFG_GET_PICT_FPS:
+		s5k3e2fx_get_pict_fps(cdata.cfg.gfps.prevfps,
+			&(cdata.cfg.gfps.pictfps));
+
+		if (copy_to_user((void *)argp, &cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_L_PF:
+		cdata.cfg.prevl_pf = s5k3e2fx_get_prev_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PREV_P_PL:
+		cdata.cfg.prevp_pl = s5k3e2fx_get_prev_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_L_PF:
+		cdata.cfg.pictl_pf = s5k3e2fx_get_pict_lines_pf();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_P_PL:
+		cdata.cfg.pictp_pl = s5k3e2fx_get_pict_pixels_pl();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_GET_PICT_MAX_EXP_LC:
+		cdata.cfg.pict_max_exp_lc =
+			s5k3e2fx_get_pict_max_exp_lc();
+
+		if (copy_to_user((void *)argp,
+				&cdata,
+				sizeof(struct sensor_cfg_data)))
+			rc = -EFAULT;
+		break;
+
+	case CFG_SET_FPS:
+	case CFG_SET_PICT_FPS:
+		rc = s5k3e2fx_set_fps(&(cdata.cfg.fps));
+		break;
+
+	case CFG_SET_EXP_GAIN:
+		rc =
+			s5k3e2fx_write_exp_gain(cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_PICT_EXP_GAIN:
+		CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__);
+		rc =
+			s5k3e2fx_set_pict_exp_gain(
+				cdata.cfg.exp_gain.gain,
+				cdata.cfg.exp_gain.line);
+		break;
+
+	case CFG_SET_MODE:
+		rc =
+			s5k3e2fx_set_sensor_mode(
+			cdata.mode, cdata.rs);
+		break;
+
+	case CFG_PWR_DOWN:
+		rc = s5k3e2fx_power_down();
+		break;
+
+	case CFG_MOVE_FOCUS:
+		rc =
+			s5k3e2fx_move_focus(
+			cdata.cfg.focus.dir,
+			cdata.cfg.focus.steps);
+		break;
+
+	case CFG_SET_DEFAULT_FOCUS:
+		rc =
+			s5k3e2fx_set_default_focus();
+		break;
+
+	case CFG_GET_AF_MAX_STEPS:
+	case CFG_SET_EFFECT:
+	case CFG_SET_LENS_SHADING:
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	up(&s5k3e2fx_sem);
+	return rc;
+}
+
+static int s5k3e2fx_sensor_probe(const struct msm_camera_sensor_info *info,
+		struct msm_sensor_ctrl *s)
+{
+	int rc = 0;
+
+	rc = i2c_add_driver(&s5k3e2fx_i2c_driver);
+	if (rc < 0 || s5k3e2fx_client == NULL) {
+		rc = -ENOTSUPP;
+		goto probe_fail;
+	}
+
+	msm_camio_clk_rate_set(24000000);
+	mdelay(20);
+
+	rc = s5k3e2fx_probe_init_sensor(info);
+	if (rc < 0)
+		goto probe_fail;
+
+	s->s_init = s5k3e2fx_sensor_open_init;
+	s->s_release = s5k3e2fx_sensor_release;
+	s->s_config  = s5k3e2fx_sensor_config;
+	s5k3e2fx_probe_init_done(info);
+
+	return rc;
+
+probe_fail:
+	CDBG("SENSOR PROBE FAILS!\n");
+	return rc;
+}
+
+static int __s5k3e2fx_probe(struct platform_device *pdev)
+{
+	return msm_camera_drv_start(pdev, s5k3e2fx_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+	.probe = __s5k3e2fx_probe,
+	.driver = {
+		.name = "msm_camera_s5k3e2fx",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init s5k3e2fx_init(void)
+{
+	return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(s5k3e2fx_init);
+
diff --git a/drivers/staging/dream/camera/s5k3e2fx.h b/drivers/staging/dream/camera/s5k3e2fx.h
new file mode 100644
index 0000000..69bc750
--- /dev/null
+++ b/drivers/staging/dream/camera/s5k3e2fx.h
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2008-2009 QUALCOMM Incorporated.
+ */
+
+#ifndef CAMSENSOR_S5K3E2FX
+#define CAMSENSOR_S5K3E2FX
+
+#include <mach/board.h>
+#endif /* CAMSENSOR_S5K3E2FX */
diff --git a/drivers/staging/dream/gpio_axis.c b/drivers/staging/dream/gpio_axis.c
new file mode 100644
index 0000000..c801172
--- /dev/null
+++ b/drivers/staging/dream/gpio_axis.c
@@ -0,0 +1,180 @@
+/* drivers/input/misc/gpio_axis.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/interrupt.h>
+
+struct gpio_axis_state {
+	struct input_dev *input_dev;
+	struct gpio_event_axis_info *info;
+	uint32_t pos;
+};
+
+uint16_t gpio_axis_4bit_gray_map_table[] = {
+	[0x0] = 0x0, [0x1] = 0x1, /* 0000 0001 */
+	[0x3] = 0x2, [0x2] = 0x3, /* 0011 0010 */
+	[0x6] = 0x4, [0x7] = 0x5, /* 0110 0111 */
+	[0x5] = 0x6, [0x4] = 0x7, /* 0101 0100 */
+	[0xc] = 0x8, [0xd] = 0x9, /* 1100 1101 */
+	[0xf] = 0xa, [0xe] = 0xb, /* 1111 1110 */
+	[0xa] = 0xc, [0xb] = 0xd, /* 1010 1011 */
+	[0x9] = 0xe, [0x8] = 0xf, /* 1001 1000 */
+};
+uint16_t gpio_axis_4bit_gray_map(struct gpio_event_axis_info *info, uint16_t in)
+{
+	return gpio_axis_4bit_gray_map_table[in];
+}
+
+uint16_t gpio_axis_5bit_singletrack_map_table[] = {
+	[0x10] = 0x00, [0x14] = 0x01, [0x1c] = 0x02, /*     10000 10100 11100 */
+	[0x1e] = 0x03, [0x1a] = 0x04, [0x18] = 0x05, /*     11110 11010 11000 */
+	[0x08] = 0x06, [0x0a] = 0x07, [0x0e] = 0x08, /*    01000 01010 01110  */
+	[0x0f] = 0x09, [0x0d] = 0x0a, [0x0c] = 0x0b, /*    01111 01101 01100  */
+	[0x04] = 0x0c, [0x05] = 0x0d, [0x07] = 0x0e, /*   00100 00101 00111   */
+	[0x17] = 0x0f, [0x16] = 0x10, [0x06] = 0x11, /*   10111 10110 00110   */
+	[0x02] = 0x12, [0x12] = 0x13, [0x13] = 0x14, /*  00010 10010 10011    */
+	[0x1b] = 0x15, [0x0b] = 0x16, [0x03] = 0x17, /*  11011 01011 00011    */
+	[0x01] = 0x18, [0x09] = 0x19, [0x19] = 0x1a, /* 00001 01001 11001     */
+	[0x1d] = 0x1b, [0x15] = 0x1c, [0x11] = 0x1d, /* 11101 10101 10001     */
+};
+uint16_t gpio_axis_5bit_singletrack_map(
+	struct gpio_event_axis_info *info, uint16_t in)
+{
+	return gpio_axis_5bit_singletrack_map_table[in];
+}
+
+static void gpio_event_update_axis(struct gpio_axis_state *as, int report)
+{
+	struct gpio_event_axis_info *ai = as->info;
+	int i;
+	int change;
+	uint16_t state = 0;
+	uint16_t pos;
+	uint16_t old_pos = as->pos;
+	for (i = ai->count - 1; i >= 0; i--)
+		state = (state << 1) | gpio_get_value(ai->gpio[i]);
+	pos = ai->map(ai, state);
+	if (ai->flags & GPIOEAF_PRINT_RAW)
+		pr_info("axis %d-%d raw %x, pos %d -> %d\n",
+			ai->type, ai->code, state, old_pos, pos);
+	if (report && pos != old_pos) {
+		if (ai->type == EV_REL) {
+			change = (ai->decoded_size + pos - old_pos) %
+				  ai->decoded_size;
+			if (change > ai->decoded_size / 2)
+				change -= ai->decoded_size;
+			if (change == ai->decoded_size / 2) {
+				if (ai->flags & GPIOEAF_PRINT_EVENT)
+					pr_info("axis %d-%d unknown direction, "
+						"pos %d -> %d\n", ai->type,
+						ai->code, old_pos, pos);
+				change = 0; /* no closest direction */
+			}
+			if (ai->flags & GPIOEAF_PRINT_EVENT)
+				pr_info("axis %d-%d change %d\n",
+					ai->type, ai->code, change);
+			input_report_rel(as->input_dev, ai->code, change);
+		} else {
+			if (ai->flags & GPIOEAF_PRINT_EVENT)
+				pr_info("axis %d-%d now %d\n",
+					ai->type, ai->code, pos);
+			input_event(as->input_dev, ai->type, ai->code, pos);
+		}
+		input_sync(as->input_dev);
+	}
+	as->pos = pos;
+}
+
+static irqreturn_t gpio_axis_irq_handler(int irq, void *dev_id)
+{
+	struct gpio_axis_state *as = dev_id;
+	gpio_event_update_axis(as, 1);
+	return IRQ_HANDLED;
+}
+
+int gpio_event_axis_func(struct input_dev *input_dev,
+			 struct gpio_event_info *info, void **data, int func)
+{
+	int ret;
+	int i;
+	int irq;
+	struct gpio_event_axis_info *ai;
+	struct gpio_axis_state *as;
+
+	ai = container_of(info, struct gpio_event_axis_info, info);
+	if (func == GPIO_EVENT_FUNC_SUSPEND) {
+		for (i = 0; i < ai->count; i++)
+			disable_irq(gpio_to_irq(ai->gpio[i]));
+		return 0;
+	}
+	if (func == GPIO_EVENT_FUNC_RESUME) {
+		for (i = 0; i < ai->count; i++)
+			enable_irq(gpio_to_irq(ai->gpio[i]));
+		return 0;
+	}
+
+	if (func == GPIO_EVENT_FUNC_INIT) {
+		*data = as = kmalloc(sizeof(*as), GFP_KERNEL);
+		if (as == NULL) {
+			ret = -ENOMEM;
+			goto err_alloc_axis_state_failed;
+		}
+		as->input_dev = input_dev;
+		as->info = ai;
+
+		input_set_capability(input_dev, ai->type, ai->code);
+		if (ai->type == EV_ABS) {
+			input_set_abs_params(input_dev, ai->code, 0,
+					     ai->decoded_size - 1, 0, 0);
+		}
+		for (i = 0; i < ai->count; i++) {
+			ret = gpio_request(ai->gpio[i], "gpio_event_axis");
+			if (ret < 0)
+				goto err_request_gpio_failed;
+			ret = gpio_direction_input(ai->gpio[i]);
+			if (ret < 0)
+				goto err_gpio_direction_input_failed;
+			ret = irq = gpio_to_irq(ai->gpio[i]);
+			if (ret < 0)
+				goto err_get_irq_num_failed;
+			ret = request_irq(irq, gpio_axis_irq_handler,
+					  IRQF_TRIGGER_RISING |
+					  IRQF_TRIGGER_FALLING,
+					  "gpio_event_axis", as);
+			if (ret < 0)
+				goto err_request_irq_failed;
+		}
+		gpio_event_update_axis(as, 0);
+		return 0;
+	}
+
+	ret = 0;
+	as = *data;
+	for (i = ai->count - 1; i >= 0; i--) {
+		free_irq(gpio_to_irq(ai->gpio[i]), as);
+err_request_irq_failed:
+err_get_irq_num_failed:
+err_gpio_direction_input_failed:
+		gpio_free(ai->gpio[i]);
+err_request_gpio_failed:
+		;
+	}
+	kfree(as);
+	*data = NULL;
+err_alloc_axis_state_failed:
+	return ret;
+}
diff --git a/drivers/staging/dream/gpio_event.c b/drivers/staging/dream/gpio_event.c
new file mode 100644
index 0000000..8b64c1e
--- /dev/null
+++ b/drivers/staging/dream/gpio_event.c
@@ -0,0 +1,224 @@
+/* drivers/input/misc/gpio_event.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/earlysuspend.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/gpio_event.h>
+#include <linux/hrtimer.h>
+#include <linux/platform_device.h>
+
+struct gpio_event {
+	struct input_dev *input_dev;
+	const struct gpio_event_platform_data *info;
+	struct early_suspend early_suspend;
+	void *state[0];
+};
+
+static int gpio_input_event(
+	struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	int i;
+	int ret = 0;
+	int tmp_ret;
+	struct gpio_event_info **ii;
+	struct gpio_event *ip = input_get_drvdata(dev);
+
+	for (i = 0, ii = ip->info->info; i < ip->info->info_count; i++, ii++) {
+		if ((*ii)->event) {
+			tmp_ret = (*ii)->event(ip->input_dev, *ii,
+					&ip->state[i], type, code, value);
+			if (tmp_ret)
+				ret = tmp_ret;
+		}
+	}
+	return ret;
+}
+
+static int gpio_event_call_all_func(struct gpio_event *ip, int func)
+{
+	int i;
+	int ret;
+	struct gpio_event_info **ii;
+
+	if (func == GPIO_EVENT_FUNC_INIT || func == GPIO_EVENT_FUNC_RESUME) {
+		ii = ip->info->info;
+		for (i = 0; i < ip->info->info_count; i++, ii++) {
+			if ((*ii)->func == NULL) {
+				ret = -ENODEV;
+				pr_err("gpio_event_probe: Incomplete pdata, "
+					"no function\n");
+				goto err_no_func;
+			}
+			ret = (*ii)->func(ip->input_dev, *ii, &ip->state[i],
+					  func);
+			if (ret) {
+				pr_err("gpio_event_probe: function failed\n");
+				goto err_func_failed;
+			}
+		}
+		return 0;
+	}
+
+	ret = 0;
+	i = ip->info->info_count;
+	ii = ip->info->info + i;
+	while (i > 0) {
+		i--;
+		ii--;
+		(*ii)->func(ip->input_dev, *ii, &ip->state[i], func & ~1);
+err_func_failed:
+err_no_func:
+		;
+	}
+	return ret;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+void gpio_event_suspend(struct early_suspend *h)
+{
+	struct gpio_event *ip;
+	ip = container_of(h, struct gpio_event, early_suspend);
+	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
+	ip->info->power(ip->info, 0);
+}
+
+void gpio_event_resume(struct early_suspend *h)
+{
+	struct gpio_event *ip;
+	ip = container_of(h, struct gpio_event, early_suspend);
+	ip->info->power(ip->info, 1);
+	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
+}
+#endif
+
+static int __init gpio_event_probe(struct platform_device *pdev)
+{
+	int err;
+	struct gpio_event *ip;
+	struct input_dev *input_dev;
+	struct gpio_event_platform_data *event_info;
+
+	event_info = pdev->dev.platform_data;
+	if (event_info == NULL) {
+		pr_err("gpio_event_probe: No pdata\n");
+		return -ENODEV;
+	}
+	if (event_info->name == NULL ||
+	   event_info->info == NULL ||
+	   event_info->info_count == 0) {
+		pr_err("gpio_event_probe: Incomplete pdata\n");
+		return -ENODEV;
+	}
+	ip = kzalloc(sizeof(*ip) +
+		     sizeof(ip->state[0]) * event_info->info_count, GFP_KERNEL);
+	if (ip == NULL) {
+		err = -ENOMEM;
+		pr_err("gpio_event_probe: Failed to allocate private data\n");
+		goto err_kp_alloc_failed;
+	}
+	platform_set_drvdata(pdev, ip);
+
+	input_dev = input_allocate_device();
+	if (input_dev == NULL) {
+		err = -ENOMEM;
+		pr_err("gpio_event_probe: Failed to allocate input device\n");
+		goto err_input_dev_alloc_failed;
+	}
+	input_set_drvdata(input_dev, ip);
+	ip->input_dev = input_dev;
+	ip->info = event_info;
+	if (event_info->power) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+		ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+		ip->early_suspend.suspend = gpio_event_suspend;
+		ip->early_suspend.resume = gpio_event_resume;
+		register_early_suspend(&ip->early_suspend);
+#endif
+		ip->info->power(ip->info, 1);
+	}
+
+	input_dev->name = ip->info->name;
+	input_dev->event = gpio_input_event;
+
+	err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
+	if (err)
+		goto err_call_all_func_failed;
+
+	err = input_register_device(input_dev);
+	if (err) {
+		pr_err("gpio_event_probe: Unable to register %s input device\n",
+			input_dev->name);
+		goto err_input_register_device_failed;
+	}
+
+	return 0;
+
+err_input_register_device_failed:
+	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
+err_call_all_func_failed:
+	if (event_info->power) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+		unregister_early_suspend(&ip->early_suspend);
+#endif
+		ip->info->power(ip->info, 0);
+	}
+	input_free_device(input_dev);
+err_input_dev_alloc_failed:
+	kfree(ip);
+err_kp_alloc_failed:
+	return err;
+}
+
+static int gpio_event_remove(struct platform_device *pdev)
+{
+	struct gpio_event *ip = platform_get_drvdata(pdev);
+
+	gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
+	if (ip->info->power) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+		unregister_early_suspend(&ip->early_suspend);
+#endif
+		ip->info->power(ip->info, 0);
+	}
+	input_unregister_device(ip->input_dev);
+	kfree(ip);
+	return 0;
+}
+
+static struct platform_driver gpio_event_driver = {
+	.probe		= gpio_event_probe,
+	.remove		= gpio_event_remove,
+	.driver		= {
+		.name	= GPIO_EVENT_DEV_NAME,
+	},
+};
+
+static int __devinit gpio_event_init(void)
+{
+	return platform_driver_register(&gpio_event_driver);
+}
+
+static void __exit gpio_event_exit(void)
+{
+	platform_driver_unregister(&gpio_event_driver);
+}
+
+module_init(gpio_event_init);
+module_exit(gpio_event_exit);
+
+MODULE_DESCRIPTION("GPIO Event Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/staging/dream/gpio_input.c b/drivers/staging/dream/gpio_input.c
new file mode 100644
index 0000000..7e307f2
--- /dev/null
+++ b/drivers/staging/dream/gpio_input.c
@@ -0,0 +1,343 @@
+/* drivers/input/misc/gpio_input.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/hrtimer.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/wakelock.h>
+
+enum {
+	DEBOUNCE_UNSTABLE     = BIT(0),	/* Got irq, while debouncing */
+	DEBOUNCE_PRESSED      = BIT(1),
+	DEBOUNCE_NOTPRESSED   = BIT(2),
+	DEBOUNCE_WAIT_IRQ     = BIT(3),	/* Stable irq state */
+	DEBOUNCE_POLL         = BIT(4),	/* Stable polling state */
+
+	DEBOUNCE_UNKNOWN =
+		DEBOUNCE_PRESSED | DEBOUNCE_NOTPRESSED,
+};
+
+struct gpio_key_state {
+	struct gpio_input_state *ds;
+	uint8_t debounce;
+};
+
+struct gpio_input_state {
+	struct input_dev *input_dev;
+	const struct gpio_event_input_info *info;
+	struct hrtimer timer;
+	int use_irq;
+	int debounce_count;
+	spinlock_t irq_lock;
+	struct wake_lock wake_lock;
+	struct gpio_key_state key_state[0];
+};
+
+static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
+{
+	int i;
+	int pressed;
+	struct gpio_input_state *ds =
+		container_of(timer, struct gpio_input_state, timer);
+	unsigned gpio_flags = ds->info->flags;
+	unsigned npolarity;
+	int nkeys = ds->info->keymap_size;
+	const struct gpio_event_direct_entry *key_entry;
+	struct gpio_key_state *key_state;
+	unsigned long irqflags;
+	uint8_t debounce;
+
+#if 0
+	key_entry = kp->keys_info->keymap;
+	key_state = kp->key_state;
+	for (i = 0; i < nkeys; i++, key_entry++, key_state++)
+		pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
+			gpio_read_detect_status(key_entry->gpio));
+#endif
+	key_entry = ds->info->keymap;
+	key_state = ds->key_state;
+	spin_lock_irqsave(&ds->irq_lock, irqflags);
+	for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
+		debounce = key_state->debounce;
+		if (debounce & DEBOUNCE_WAIT_IRQ)
+			continue;
+		if (key_state->debounce & DEBOUNCE_UNSTABLE) {
+			debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
+			enable_irq(gpio_to_irq(key_entry->gpio));
+			pr_info("gpio_keys_scan_keys: key %x-%x, %d "
+				"(%d) continue debounce\n",
+				ds->info->type, key_entry->code,
+				i, key_entry->gpio);
+		}
+		npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
+		pressed = gpio_get_value(key_entry->gpio) ^ npolarity;
+		if (debounce & DEBOUNCE_POLL) {
+			if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
+				ds->debounce_count++;
+				key_state->debounce = DEBOUNCE_UNKNOWN;
+				if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
+					pr_info("gpio_keys_scan_keys: key %x-"
+						"%x, %d (%d) start debounce\n",
+						ds->info->type, key_entry->code,
+						i, key_entry->gpio);
+			}
+			continue;
+		}
+		if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
+			if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
+				pr_info("gpio_keys_scan_keys: key %x-%x, %d "
+					"(%d) debounce pressed 1\n",
+					ds->info->type, key_entry->code,
+					i, key_entry->gpio);
+			key_state->debounce = DEBOUNCE_PRESSED;
+			continue;
+		}
+		if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
+			if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
+				pr_info("gpio_keys_scan_keys: key %x-%x, %d "
+					"(%d) debounce pressed 0\n",
+					ds->info->type, key_entry->code,
+					i, key_entry->gpio);
+			key_state->debounce = DEBOUNCE_NOTPRESSED;
+			continue;
+		}
+		/* key is stable */
+		ds->debounce_count--;
+		if (ds->use_irq)
+			key_state->debounce |= DEBOUNCE_WAIT_IRQ;
+		else
+			key_state->debounce |= DEBOUNCE_POLL;
+		if (gpio_flags & GPIOEDF_PRINT_KEYS)
+			pr_info("gpio_keys_scan_keys: key %x-%x, %d (%d) "
+				"changed to %d\n", ds->info->type,
+				key_entry->code, i, key_entry->gpio, pressed);
+		input_event(ds->input_dev, ds->info->type,
+			    key_entry->code, pressed);
+	}
+
+#if 0
+	key_entry = kp->keys_info->keymap;
+	key_state = kp->key_state;
+	for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
+		pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
+			gpio_read_detect_status(key_entry->gpio));
+	}
+#endif
+
+	if (ds->debounce_count)
+		hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
+	else if (!ds->use_irq)
+		hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
+	else
+		wake_unlock(&ds->wake_lock);
+
+	spin_unlock_irqrestore(&ds->irq_lock, irqflags);
+
+	return HRTIMER_NORESTART;
+}
+
+static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id)
+{
+	struct gpio_key_state *ks = dev_id;
+	struct gpio_input_state *ds = ks->ds;
+	int keymap_index = ks - ds->key_state;
+	const struct gpio_event_direct_entry *key_entry;
+	unsigned long irqflags;
+	int pressed;
+
+	if (!ds->use_irq)
+		return IRQ_HANDLED;
+
+	key_entry = &ds->info->keymap[keymap_index];
+
+	if (ds->info->debounce_time.tv64) {
+		spin_lock_irqsave(&ds->irq_lock, irqflags);
+		if (ks->debounce & DEBOUNCE_WAIT_IRQ) {
+			ks->debounce = DEBOUNCE_UNKNOWN;
+			if (ds->debounce_count++ == 0) {
+				wake_lock(&ds->wake_lock);
+				hrtimer_start(
+					&ds->timer, ds->info->debounce_time,
+					HRTIMER_MODE_REL);
+			}
+			if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
+				pr_info("gpio_event_input_irq_handler: "
+					"key %x-%x, %d (%d) start debounce\n",
+					ds->info->type, key_entry->code,
+					keymap_index, key_entry->gpio);
+		} else {
+			disable_irq(irq);
+			ks->debounce = DEBOUNCE_UNSTABLE;
+		}
+		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
+	} else {
+		pressed = gpio_get_value(key_entry->gpio) ^
+			!(ds->info->flags & GPIOEDF_ACTIVE_HIGH);
+		if (ds->info->flags & GPIOEDF_PRINT_KEYS)
+			pr_info("gpio_event_input_irq_handler: key %x-%x, %d "
+				"(%d) changed to %d\n",
+				ds->info->type, key_entry->code, keymap_index,
+				key_entry->gpio, pressed);
+		input_event(ds->input_dev, ds->info->type,
+			    key_entry->code, pressed);
+	}
+	return IRQ_HANDLED;
+}
+
+static int gpio_event_input_request_irqs(struct gpio_input_state *ds)
+{
+	int i;
+	int err;
+	unsigned int irq;
+	unsigned long req_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
+
+	for (i = 0; i < ds->info->keymap_size; i++) {
+		err = irq = gpio_to_irq(ds->info->keymap[i].gpio);
+		if (err < 0)
+			goto err_gpio_get_irq_num_failed;
+		err = request_irq(irq, gpio_event_input_irq_handler,
+				  req_flags, "gpio_keys", &ds->key_state[i]);
+		if (err) {
+			pr_err("gpio_event_input_request_irqs: request_irq "
+				"failed for input %d, irq %d\n",
+				ds->info->keymap[i].gpio, irq);
+			goto err_request_irq_failed;
+		}
+		enable_irq_wake(irq);
+	}
+	return 0;
+
+	for (i = ds->info->keymap_size - 1; i >= 0; i--) {
+		free_irq(gpio_to_irq(ds->info->keymap[i].gpio),
+			 &ds->key_state[i]);
+err_request_irq_failed:
+err_gpio_get_irq_num_failed:
+		;
+	}
+	return err;
+}
+
+int gpio_event_input_func(struct input_dev *input_dev,
+			struct gpio_event_info *info, void **data, int func)
+{
+	int ret;
+	int i;
+	unsigned long irqflags;
+	struct gpio_event_input_info *di;
+	struct gpio_input_state *ds = *data;
+
+	di = container_of(info, struct gpio_event_input_info, info);
+
+	if (func == GPIO_EVENT_FUNC_SUSPEND) {
+		spin_lock_irqsave(&ds->irq_lock, irqflags);
+		if (ds->use_irq)
+			for (i = 0; i < di->keymap_size; i++)
+				disable_irq(gpio_to_irq(di->keymap[i].gpio));
+		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
+		hrtimer_cancel(&ds->timer);
+		return 0;
+	}
+	if (func == GPIO_EVENT_FUNC_RESUME) {
+		spin_lock_irqsave(&ds->irq_lock, irqflags);
+		if (ds->use_irq)
+			for (i = 0; i < di->keymap_size; i++)
+				enable_irq(gpio_to_irq(di->keymap[i].gpio));
+		hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
+		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
+		return 0;
+	}
+
+	if (func == GPIO_EVENT_FUNC_INIT) {
+		if (ktime_to_ns(di->poll_time) <= 0)
+			di->poll_time = ktime_set(0, 20 * NSEC_PER_MSEC);
+
+		*data = ds = kzalloc(sizeof(*ds) + sizeof(ds->key_state[0]) *
+					di->keymap_size, GFP_KERNEL);
+		if (ds == NULL) {
+			ret = -ENOMEM;
+			pr_err("gpio_event_input_func: "
+				"Failed to allocate private data\n");
+			goto err_ds_alloc_failed;
+		}
+		ds->debounce_count = di->keymap_size;
+		ds->input_dev = input_dev;
+		ds->info = di;
+		wake_lock_init(&ds->wake_lock, WAKE_LOCK_SUSPEND, "gpio_input");
+		spin_lock_init(&ds->irq_lock);
+
+		for (i = 0; i < di->keymap_size; i++) {
+			input_set_capability(input_dev, di->type,
+					     di->keymap[i].code);
+			ds->key_state[i].ds = ds;
+			ds->key_state[i].debounce = DEBOUNCE_UNKNOWN;
+		}
+
+		for (i = 0; i < di->keymap_size; i++) {
+			ret = gpio_request(di->keymap[i].gpio, "gpio_kp_in");
+			if (ret) {
+				pr_err("gpio_event_input_func: gpio_request "
+					"failed for %d\n", di->keymap[i].gpio);
+				goto err_gpio_request_failed;
+			}
+			ret = gpio_direction_input(di->keymap[i].gpio);
+			if (ret) {
+				pr_err("gpio_event_input_func: "
+					"gpio_direction_input failed for %d\n",
+					di->keymap[i].gpio);
+				goto err_gpio_configure_failed;
+			}
+		}
+
+		ret = gpio_event_input_request_irqs(ds);
+
+		spin_lock_irqsave(&ds->irq_lock, irqflags);
+		ds->use_irq = ret == 0;
+
+		pr_info("GPIO Input Driver: Start gpio inputs for %s in %s "
+			"mode\n",
+			input_dev->name, ret == 0 ? "interrupt" : "polling");
+
+		hrtimer_init(&ds->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		ds->timer.function = gpio_event_input_timer_func;
+		hrtimer_start(&ds->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
+		spin_unlock_irqrestore(&ds->irq_lock, irqflags);
+		return 0;
+	}
+
+	ret = 0;
+	spin_lock_irqsave(&ds->irq_lock, irqflags);
+	hrtimer_cancel(&ds->timer);
+	if (ds->use_irq) {
+		for (i = di->keymap_size - 1; i >= 0; i--) {
+			free_irq(gpio_to_irq(di->keymap[i].gpio),
+				 &ds->key_state[i]);
+		}
+	}
+	spin_unlock_irqrestore(&ds->irq_lock, irqflags);
+
+	for (i = di->keymap_size - 1; i >= 0; i--) {
+err_gpio_configure_failed:
+		gpio_free(di->keymap[i].gpio);
+err_gpio_request_failed:
+		;
+	}
+	wake_lock_destroy(&ds->wake_lock);
+	kfree(ds);
+err_ds_alloc_failed:
+	return ret;
+}
diff --git a/drivers/staging/dream/gpio_matrix.c b/drivers/staging/dream/gpio_matrix.c
new file mode 100644
index 0000000..c1f4765
--- /dev/null
+++ b/drivers/staging/dream/gpio_matrix.c
@@ -0,0 +1,406 @@
+/* drivers/input/misc/gpio_matrix.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/gpio.h>
+#include <linux/gpio_event.h>
+#include <linux/hrtimer.h>
+#include <linux/interrupt.h>
+#include <linux/wakelock.h>
+
+struct gpio_kp {
+	struct input_dev *input_dev;
+	struct gpio_event_matrix_info *keypad_info;
+	struct hrtimer timer;
+	struct wake_lock wake_lock;
+	int current_output;
+	unsigned int use_irq:1;
+	unsigned int key_state_changed:1;
+	unsigned int last_key_state_changed:1;
+	unsigned int some_keys_pressed:2;
+	unsigned long keys_pressed[0];
+};
+
+static void clear_phantom_key(struct gpio_kp *kp, int out, int in)
+{
+	struct gpio_event_matrix_info *mi = kp->keypad_info;
+	int key_index = out * mi->ninputs + in;
+	unsigned short keycode = mi->keymap[key_index];;
+
+	if (!test_bit(keycode, kp->input_dev->key)) {
+		if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
+			pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
+				"cleared\n", keycode, out, in,
+				mi->output_gpios[out], mi->input_gpios[in]);
+		__clear_bit(key_index, kp->keys_pressed);
+	} else {
+		if (mi->flags & GPIOKPF_PRINT_PHANTOM_KEYS)
+			pr_info("gpiomatrix: phantom key %x, %d-%d (%d-%d) "
+				"not cleared\n", keycode, out, in,
+				mi->output_gpios[out], mi->input_gpios[in]);
+	}
+}
+
+static int restore_keys_for_input(struct gpio_kp *kp, int out, int in)
+{
+	int rv = 0;
+	int key_index;
+
+	key_index = out * kp->keypad_info->ninputs + in;
+	while (out < kp->keypad_info->noutputs) {
+		if (test_bit(key_index, kp->keys_pressed)) {
+			rv = 1;
+			clear_phantom_key(kp, out, in);
+		}
+		key_index += kp->keypad_info->ninputs;
+		out++;
+	}
+	return rv;
+}
+
+static void remove_phantom_keys(struct gpio_kp *kp)
+{
+	int out, in, inp;
+	int key_index;
+
+	if (kp->some_keys_pressed < 3)
+		return;
+
+	for (out = 0; out < kp->keypad_info->noutputs; out++) {
+		inp = -1;
+		key_index = out * kp->keypad_info->ninputs;
+		for (in = 0; in < kp->keypad_info->ninputs; in++, key_index++) {
+			if (test_bit(key_index, kp->keys_pressed)) {
+				if (inp == -1) {
+					inp = in;
+					continue;
+				}
+				if (inp >= 0) {
+					if (!restore_keys_for_input(kp, out + 1,
+									inp))
+						break;
+					clear_phantom_key(kp, out, inp);
+					inp = -2;
+				}
+				restore_keys_for_input(kp, out, in);
+			}
+		}
+	}
+}
+
+static void report_key(struct gpio_kp *kp, int key_index, int out, int in)
+{
+	struct gpio_event_matrix_info *mi = kp->keypad_info;
+	int pressed = test_bit(key_index, kp->keys_pressed);
+	unsigned short keycode = mi->keymap[key_index];
+	if (pressed != test_bit(keycode, kp->input_dev->key)) {
+		if (keycode == KEY_RESERVED) {
+			if (mi->flags & GPIOKPF_PRINT_UNMAPPED_KEYS)
+				pr_info("gpiomatrix: unmapped key, %d-%d "
+					"(%d-%d) changed to %d\n",
+					out, in, mi->output_gpios[out],
+					mi->input_gpios[in], pressed);
+		} else {
+			if (mi->flags & GPIOKPF_PRINT_MAPPED_KEYS)
+				pr_info("gpiomatrix: key %x, %d-%d (%d-%d) "
+					"changed to %d\n", keycode,
+					out, in, mi->output_gpios[out],
+					mi->input_gpios[in], pressed);
+			input_report_key(kp->input_dev, keycode, pressed);
+		}
+	}
+}
+
+static enum hrtimer_restart gpio_keypad_timer_func(struct hrtimer *timer)
+{
+	int out, in;
+	int key_index;
+	int gpio;
+	struct gpio_kp *kp = container_of(timer, struct gpio_kp, timer);
+	struct gpio_event_matrix_info *mi = kp->keypad_info;
+	unsigned gpio_keypad_flags = mi->flags;
+	unsigned polarity = !!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH);
+
+	out = kp->current_output;
+	if (out == mi->noutputs) {
+		out = 0;
+		kp->last_key_state_changed = kp->key_state_changed;
+		kp->key_state_changed = 0;
+		kp->some_keys_pressed = 0;
+	} else {
+		key_index = out * mi->ninputs;
+		for (in = 0; in < mi->ninputs; in++, key_index++) {
+			gpio = mi->input_gpios[in];
+			if (gpio_get_value(gpio) ^ !polarity) {
+				if (kp->some_keys_pressed < 3)
+					kp->some_keys_pressed++;
+				kp->key_state_changed |= !__test_and_set_bit(
+						key_index, kp->keys_pressed);
+			} else
+				kp->key_state_changed |= __test_and_clear_bit(
+						key_index, kp->keys_pressed);
+		}
+		gpio = mi->output_gpios[out];
+		if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
+			gpio_set_value(gpio, !polarity);
+		else
+			gpio_direction_input(gpio);
+		out++;
+	}
+	kp->current_output = out;
+	if (out < mi->noutputs) {
+		gpio = mi->output_gpios[out];
+		if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
+			gpio_set_value(gpio, polarity);
+		else
+			gpio_direction_output(gpio, polarity);
+		hrtimer_start(timer, mi->settle_time, HRTIMER_MODE_REL);
+		return HRTIMER_NORESTART;
+	}
+	if (gpio_keypad_flags & GPIOKPF_DEBOUNCE) {
+		if (kp->key_state_changed) {
+			hrtimer_start(&kp->timer, mi->debounce_delay,
+				      HRTIMER_MODE_REL);
+			return HRTIMER_NORESTART;
+		}
+		kp->key_state_changed = kp->last_key_state_changed;
+	}
+	if (kp->key_state_changed) {
+		if (gpio_keypad_flags & GPIOKPF_REMOVE_SOME_PHANTOM_KEYS)
+			remove_phantom_keys(kp);
+		key_index = 0;
+		for (out = 0; out < mi->noutputs; out++)
+			for (in = 0; in < mi->ninputs; in++, key_index++)
+				report_key(kp, key_index, out, in);
+	}
+	if (!kp->use_irq || kp->some_keys_pressed) {
+		hrtimer_start(timer, mi->poll_time, HRTIMER_MODE_REL);
+		return HRTIMER_NORESTART;
+	}
+
+	/* No keys are pressed, reenable interrupt */
+	for (out = 0; out < mi->noutputs; out++) {
+		if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
+			gpio_set_value(mi->output_gpios[out], polarity);
+		else
+			gpio_direction_output(mi->output_gpios[out], polarity);
+	}
+	for (in = 0; in < mi->ninputs; in++)
+		enable_irq(gpio_to_irq(mi->input_gpios[in]));
+	wake_unlock(&kp->wake_lock);
+	return HRTIMER_NORESTART;
+}
+
+static irqreturn_t gpio_keypad_irq_handler(int irq_in, void *dev_id)
+{
+	int i;
+	struct gpio_kp *kp = dev_id;
+	struct gpio_event_matrix_info *mi = kp->keypad_info;
+	unsigned gpio_keypad_flags = mi->flags;
+
+	if (!kp->use_irq) /* ignore interrupt while registering the handler */
+		return IRQ_HANDLED;
+
+	for (i = 0; i < mi->ninputs; i++)
+		disable_irq(gpio_to_irq(mi->input_gpios[i]));
+	for (i = 0; i < mi->noutputs; i++) {
+		if (gpio_keypad_flags & GPIOKPF_DRIVE_INACTIVE)
+			gpio_set_value(mi->output_gpios[i],
+				!(gpio_keypad_flags & GPIOKPF_ACTIVE_HIGH));
+		else
+			gpio_direction_input(mi->output_gpios[i]);
+	}
+	wake_lock(&kp->wake_lock);
+	hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
+	return IRQ_HANDLED;
+}
+
+static int gpio_keypad_request_irqs(struct gpio_kp *kp)
+{
+	int i;
+	int err;
+	unsigned int irq;
+	unsigned long request_flags;
+	struct gpio_event_matrix_info *mi = kp->keypad_info;
+
+	switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
+	default:
+		request_flags = IRQF_TRIGGER_FALLING;
+		break;
+	case GPIOKPF_ACTIVE_HIGH:
+		request_flags = IRQF_TRIGGER_RISING;
+		break;
+	case GPIOKPF_LEVEL_TRIGGERED_IRQ:
+		request_flags = IRQF_TRIGGER_LOW;
+		break;
+	case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
+		request_flags = IRQF_TRIGGER_HIGH;
+		break;
+	}
+
+	for (i = 0; i < mi->ninputs; i++) {
+		err = irq = gpio_to_irq(mi->input_gpios[i]);
+		if (err < 0)
+			goto err_gpio_get_irq_num_failed;
+		err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
+				  "gpio_kp", kp);
+		if (err) {
+			pr_err("gpiomatrix: request_irq failed for input %d, "
+				"irq %d\n", mi->input_gpios[i], irq);
+			goto err_request_irq_failed;
+		}
+		err = set_irq_wake(irq, 1);
+		if (err) {
+			pr_err("gpiomatrix: set_irq_wake failed for input %d, "
+				"irq %d\n", mi->input_gpios[i], irq);
+		}
+		disable_irq(irq);
+	}
+	return 0;
+
+	for (i = mi->noutputs - 1; i >= 0; i--) {
+		free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
+err_request_irq_failed:
+err_gpio_get_irq_num_failed:
+		;
+	}
+	return err;
+}
+
+int gpio_event_matrix_func(struct input_dev *input_dev,
+	struct gpio_event_info *info, void **data, int func)
+{
+	int i;
+	int err;
+	int key_count;
+	struct gpio_kp *kp;
+	struct gpio_event_matrix_info *mi;
+
+	mi = container_of(info, struct gpio_event_matrix_info, info);
+	if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
+		/* TODO: disable scanning */
+		return 0;
+	}
+
+	if (func == GPIO_EVENT_FUNC_INIT) {
+		if (mi->keymap == NULL ||
+		   mi->input_gpios == NULL ||
+		   mi->output_gpios == NULL) {
+			err = -ENODEV;
+			pr_err("gpiomatrix: Incomplete pdata\n");
+			goto err_invalid_platform_data;
+		}
+		key_count = mi->ninputs * mi->noutputs;
+
+		*data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
+				     BITS_TO_LONGS(key_count), GFP_KERNEL);
+		if (kp == NULL) {
+			err = -ENOMEM;
+			pr_err("gpiomatrix: Failed to allocate private data\n");
+			goto err_kp_alloc_failed;
+		}
+		kp->input_dev = input_dev;
+		kp->keypad_info = mi;
+		set_bit(EV_KEY, input_dev->evbit);
+		for (i = 0; i < key_count; i++) {
+			if (mi->keymap[i])
+				set_bit(mi->keymap[i] & KEY_MAX,
+					input_dev->keybit);
+		}
+
+		for (i = 0; i < mi->noutputs; i++) {
+			if (gpio_cansleep(mi->output_gpios[i])) {
+				pr_err("gpiomatrix: unsupported output gpio %d,"
+					" can sleep\n", mi->output_gpios[i]);
+				err = -EINVAL;
+				goto err_request_output_gpio_failed;
+			}
+			err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
+			if (err) {
+				pr_err("gpiomatrix: gpio_request failed for "
+					"output %d\n", mi->output_gpios[i]);
+				goto err_request_output_gpio_failed;
+			}
+			if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
+				err = gpio_direction_output(mi->output_gpios[i],
+					!(mi->flags & GPIOKPF_ACTIVE_HIGH));
+			else
+				err = gpio_direction_input(mi->output_gpios[i]);
+			if (err) {
+				pr_err("gpiomatrix: gpio_configure failed for "
+					"output %d\n", mi->output_gpios[i]);
+				goto err_output_gpio_configure_failed;
+			}
+		}
+		for (i = 0; i < mi->ninputs; i++) {
+			err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
+			if (err) {
+				pr_err("gpiomatrix: gpio_request failed for "
+					"input %d\n", mi->input_gpios[i]);
+				goto err_request_input_gpio_failed;
+			}
+			err = gpio_direction_input(mi->input_gpios[i]);
+			if (err) {
+				pr_err("gpiomatrix: gpio_direction_input failed"
+					" for input %d\n", mi->input_gpios[i]);
+				goto err_gpio_direction_input_failed;
+			}
+		}
+		kp->current_output = mi->noutputs;
+		kp->key_state_changed = 1;
+
+		hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		kp->timer.function = gpio_keypad_timer_func;
+		wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp");
+		err = gpio_keypad_request_irqs(kp);
+		kp->use_irq = err == 0;
+
+		pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for %s "
+			"in %s mode\n", input_dev->name,
+			kp->use_irq ? "interrupt" : "polling");
+
+		if (kp->use_irq)
+			wake_lock(&kp->wake_lock);
+		hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
+
+		return 0;
+	}
+
+	err = 0;
+	kp = *data;
+
+	if (kp->use_irq)
+		for (i = mi->noutputs - 1; i >= 0; i--)
+			free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
+
+	hrtimer_cancel(&kp->timer);
+	wake_lock_destroy(&kp->wake_lock);
+	for (i = mi->noutputs - 1; i >= 0; i--) {
+err_gpio_direction_input_failed:
+		gpio_free(mi->input_gpios[i]);
+err_request_input_gpio_failed:
+		;
+	}
+	for (i = mi->noutputs - 1; i >= 0; i--) {
+err_output_gpio_configure_failed:
+		gpio_free(mi->output_gpios[i]);
+err_request_output_gpio_failed:
+		;
+	}
+	kfree(kp);
+err_kp_alloc_failed:
+err_invalid_platform_data:
+	return err;
+}
diff --git a/drivers/staging/dream/gpio_output.c b/drivers/staging/dream/gpio_output.c
new file mode 100644
index 0000000..6f8453c
--- /dev/null
+++ b/drivers/staging/dream/gpio_output.c
@@ -0,0 +1,84 @@
+/* drivers/input/misc/gpio_output.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/gpio.h>
+#include <linux/gpio_event.h>
+
+int gpio_event_output_event(
+	struct input_dev *input_dev, struct gpio_event_info *info, void **data,
+	unsigned int type, unsigned int code, int value)
+{
+	int i;
+	struct gpio_event_output_info *oi;
+	oi = container_of(info, struct gpio_event_output_info, info);
+	if (type != oi->type)
+		return 0;
+	if (!(oi->flags & GPIOEDF_ACTIVE_HIGH))
+		value = !value;
+	for (i = 0; i < oi->keymap_size; i++)
+		if (code == oi->keymap[i].code)
+			gpio_set_value(oi->keymap[i].gpio, value);
+	return 0;
+}
+
+int gpio_event_output_func(
+	struct input_dev *input_dev, struct gpio_event_info *info, void **data,
+	int func)
+{
+	int ret;
+	int i;
+	struct gpio_event_output_info *oi;
+	oi = container_of(info, struct gpio_event_output_info, info);
+
+	if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME)
+		return 0;
+
+	if (func == GPIO_EVENT_FUNC_INIT) {
+		int output_level = !(oi->flags & GPIOEDF_ACTIVE_HIGH);
+		for (i = 0; i < oi->keymap_size; i++)
+			input_set_capability(input_dev, oi->type,
+					     oi->keymap[i].code);
+
+		for (i = 0; i < oi->keymap_size; i++) {
+			ret = gpio_request(oi->keymap[i].gpio,
+					   "gpio_event_output");
+			if (ret) {
+				pr_err("gpio_event_output_func: gpio_request "
+					"failed for %d\n", oi->keymap[i].gpio);
+				goto err_gpio_request_failed;
+			}
+			ret = gpio_direction_output(oi->keymap[i].gpio,
+						    output_level);
+			if (ret) {
+				pr_err("gpio_event_output_func: "
+					"gpio_direction_output failed for %d\n",
+					oi->keymap[i].gpio);
+				goto err_gpio_direction_output_failed;
+			}
+		}
+		return 0;
+	}
+
+	ret = 0;
+	for (i = oi->keymap_size - 1; i >= 0; i--) {
+err_gpio_direction_output_failed:
+		gpio_free(oi->keymap[i].gpio);
+err_gpio_request_failed:
+		;
+	}
+	return ret;
+}
+
diff --git a/drivers/staging/dream/qdsp5/Makefile b/drivers/staging/dream/qdsp5/Makefile
new file mode 100644
index 0000000..991d4a7
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/Makefile
@@ -0,0 +1,17 @@
+obj-y += adsp.o
+ifeq ($(CONFIG_MSM_AMSS_VERSION_6350),y)
+obj-y += adsp_info.o
+obj-y += audio_evrc.o audio_qcelp.o audio_amrnb.o audio_aac.o
+else
+obj-y += adsp_6225.o
+endif
+
+obj-y += adsp_driver.o
+obj-y += adsp_video_verify_cmd.o
+obj-y += adsp_videoenc_verify_cmd.o
+obj-y += adsp_jpeg_verify_cmd.o adsp_jpeg_patch_event.o
+obj-y += adsp_vfe_verify_cmd.o adsp_vfe_patch_event.o
+obj-y += adsp_lpm_verify_cmd.o
+obj-y += audio_out.o audio_in.o audio_mp3.o audmgr.o audpp.o
+obj-y += snd.o
+
diff --git a/drivers/staging/dream/qdsp5/adsp.c b/drivers/staging/dream/qdsp5/adsp.c
new file mode 100644
index 0000000..d096456
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp.c
@@ -0,0 +1,1163 @@
+/* arch/arm/mach-msm/qdsp5/adsp.c
+ *
+ * Register/Interrupt access for userspace aDSP library.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Iliyan Malchev <ibm@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/* TODO:
+ * - move shareable rpc code outside of adsp.c
+ * - general solution for virt->phys patchup
+ * - queue IDs should be relative to modules
+ * - disallow access to non-associated queues
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/wakelock.h>
+
+static struct wake_lock adsp_wake_lock;
+static inline void prevent_suspend(void)
+{
+	wake_lock(&adsp_wake_lock);
+}
+static inline void allow_suspend(void)
+{
+	wake_unlock(&adsp_wake_lock);
+}
+
+#include <linux/io.h>
+#include <mach/msm_iomap.h>
+#include "adsp.h"
+
+#define INT_ADSP INT_ADSP_A9_A11
+
+static struct adsp_info adsp_info;
+static struct msm_rpc_endpoint *rpc_cb_server_client;
+static struct msm_adsp_module *adsp_modules;
+static int adsp_open_count;
+static DEFINE_MUTEX(adsp_open_lock);
+
+/* protect interactions with the ADSP command/message queue */
+static spinlock_t adsp_cmd_lock;
+
+static uint32_t current_image = -1;
+
+void adsp_set_image(struct adsp_info *info, uint32_t image)
+{
+	current_image = image;
+}
+
+/*
+ * Checks whether the module_id is available in the
+ * module_entries table.If module_id is available returns `0`.
+ * If module_id is not available returns `-ENXIO`.
+ */
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+static int32_t adsp_validate_module(uint32_t module_id)
+{
+	uint32_t	*ptr;
+	uint32_t	module_index;
+	uint32_t	num_mod_entries;
+
+	ptr = adsp_info.init_info_ptr->module_entries;
+	num_mod_entries = adsp_info.init_info_ptr->module_table_size;
+
+	for (module_index = 0; module_index < num_mod_entries; module_index++)
+		if (module_id == ptr[module_index])
+			return 0;
+
+	return -ENXIO;
+}
+#else
+static inline int32_t adsp_validate_module(uint32_t module_id) { return 0; }
+#endif
+
+uint32_t adsp_get_module(struct adsp_info *info, uint32_t task)
+{
+	BUG_ON(current_image == -1UL);
+	return info->task_to_module[current_image][task];
+}
+
+uint32_t adsp_get_queue_offset(struct adsp_info *info, uint32_t queue_id)
+{
+	BUG_ON(current_image == -1UL);
+	return info->queue_offset[current_image][queue_id];
+}
+
+static int rpc_adsp_rtos_app_to_modem(uint32_t cmd, uint32_t module,
+				      struct msm_adsp_module *adsp_module)
+{
+	int rc;
+	struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
+	struct rpc_reply_hdr *rpc_rsp;
+
+	msm_rpc_setup_req(&rpc_req.hdr,
+			  RPC_ADSP_RTOS_ATOM_PROG,
+			  msm_rpc_get_vers(adsp_module->rpc_client),
+			  RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
+
+	rpc_req.gotit = cpu_to_be32(1);
+	rpc_req.cmd = cpu_to_be32(cmd);
+	rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
+	rpc_req.module = cpu_to_be32(module);
+	rc = msm_rpc_write(adsp_module->rpc_client, &rpc_req, sizeof(rpc_req));
+	if (rc < 0) {
+		pr_err("adsp: could not send RPC request: %d\n", rc);
+		return rc;
+	}
+
+	rc = msm_rpc_read(adsp_module->rpc_client,
+			  (void **)&rpc_rsp, -1, (5*HZ));
+	if (rc < 0) {
+		pr_err("adsp: error receiving RPC reply: %d (%d)\n",
+		       rc, -ERESTARTSYS);
+		return rc;
+	}
+
+	if (be32_to_cpu(rpc_rsp->reply_stat) != RPCMSG_REPLYSTAT_ACCEPTED) {
+		pr_err("adsp: RPC call was denied!\n");
+		kfree(rpc_rsp);
+		return -EPERM;
+	}
+
+	if (be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat) !=
+	    RPC_ACCEPTSTAT_SUCCESS) {
+		pr_err("adsp error: RPC call was not successful (%d)\n",
+		       be32_to_cpu(rpc_rsp->data.acc_hdr.accept_stat));
+		kfree(rpc_rsp);
+		return -EINVAL;
+	}
+
+	kfree(rpc_rsp);
+	return 0;
+}
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+static int get_module_index(uint32_t id)
+{
+	int mod_idx;
+	for (mod_idx = 0; mod_idx < adsp_info.module_count; mod_idx++)
+		if (adsp_info.module[mod_idx].id == id)
+			return mod_idx;
+
+	return -ENXIO;
+}
+#endif
+
+static struct msm_adsp_module *find_adsp_module_by_id(
+	struct adsp_info *info, uint32_t id)
+{
+	if (id > info->max_module_id) {
+		return NULL;
+	} else {
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+		id = get_module_index(id);
+		if (id < 0)
+			return NULL;
+#endif
+		return info->id_to_module[id];
+	}
+}
+
+static struct msm_adsp_module *find_adsp_module_by_name(
+	struct adsp_info *info, const char *name)
+{
+	unsigned n;
+	for (n = 0; n < info->module_count; n++)
+		if (!strcmp(name, adsp_modules[n].name))
+			return adsp_modules + n;
+	return NULL;
+}
+
+static int adsp_rpc_init(struct msm_adsp_module *adsp_module)
+{
+	/* remove the original connect once compatible support is complete */
+	adsp_module->rpc_client = msm_rpc_connect(
+			RPC_ADSP_RTOS_ATOM_PROG,
+			RPC_ADSP_RTOS_ATOM_VERS,
+			MSM_RPC_UNINTERRUPTIBLE);
+
+	if (IS_ERR(adsp_module->rpc_client)) {
+		int rc = PTR_ERR(adsp_module->rpc_client);
+		adsp_module->rpc_client = 0;
+		pr_err("adsp: could not open rpc client: %d\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+/*
+ * Send RPC_ADSP_RTOS_CMD_GET_INIT_INFO cmd to ARM9 and get
+ * queue offsets and module entries (init info) as part of the event.
+ */
+static void  msm_get_init_info(void)
+{
+	int rc;
+	struct rpc_adsp_rtos_app_to_modem_args_t rpc_req;
+
+	adsp_info.init_info_rpc_client = msm_rpc_connect(
+			RPC_ADSP_RTOS_ATOM_PROG,
+			RPC_ADSP_RTOS_ATOM_VERS,
+			MSM_RPC_UNINTERRUPTIBLE);
+	if (IS_ERR(adsp_info.init_info_rpc_client)) {
+		rc = PTR_ERR(adsp_info.init_info_rpc_client);
+		adsp_info.init_info_rpc_client = 0;
+		pr_err("adsp: could not open rpc client: %d\n", rc);
+		return;
+	}
+
+	msm_rpc_setup_req(&rpc_req.hdr,
+			RPC_ADSP_RTOS_ATOM_PROG,
+			msm_rpc_get_vers(adsp_info.init_info_rpc_client),
+			RPC_ADSP_RTOS_APP_TO_MODEM_PROC);
+
+	rpc_req.gotit = cpu_to_be32(1);
+	rpc_req.cmd = cpu_to_be32(RPC_ADSP_RTOS_CMD_GET_INIT_INFO);
+	rpc_req.proc_id = cpu_to_be32(RPC_ADSP_RTOS_PROC_APPS);
+	rpc_req.module = 0;
+
+	rc = msm_rpc_write(adsp_info.init_info_rpc_client,
+				&rpc_req, sizeof(rpc_req));
+	if (rc < 0)
+		pr_err("adsp: could not send RPC request: %d\n", rc);
+}
+#endif
+
+int msm_adsp_get(const char *name, struct msm_adsp_module **out,
+		 struct msm_adsp_ops *ops, void *driver_data)
+{
+	struct msm_adsp_module *module;
+	int rc = 0;
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	static uint32_t init_info_cmd_sent;
+	if (!init_info_cmd_sent) {
+		msm_get_init_info();
+		init_waitqueue_head(&adsp_info.init_info_wait);
+		rc = wait_event_timeout(adsp_info.init_info_wait,
+			adsp_info.init_info_state == ADSP_STATE_INIT_INFO,
+			5 * HZ);
+		if (!rc) {
+			pr_info("adsp: INIT_INFO failed\n");
+			return -ETIMEDOUT;
+		}
+		init_info_cmd_sent++;
+	}
+#endif
+
+	module = find_adsp_module_by_name(&adsp_info, name);
+	if (!module)
+		return -ENODEV;
+
+	mutex_lock(&module->lock);
+	pr_info("adsp: opening module %s\n", module->name);
+	if (module->open_count++ == 0 && module->clk)
+		clk_enable(module->clk);
+
+	mutex_lock(&adsp_open_lock);
+	if (adsp_open_count++ == 0) {
+		enable_irq(INT_ADSP);
+		prevent_suspend();
+	}
+	mutex_unlock(&adsp_open_lock);
+
+	if (module->ops) {
+		rc = -EBUSY;
+		goto done;
+	}
+
+	rc = adsp_rpc_init(module);
+	if (rc)
+		goto done;
+
+	module->ops = ops;
+	module->driver_data = driver_data;
+	*out = module;
+	rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_REGISTER_APP,
+					module->id, module);
+	if (rc) {
+		module->ops = NULL;
+		module->driver_data = NULL;
+		*out = NULL;
+		pr_err("adsp: REGISTER_APP failed\n");
+		goto done;
+	}
+
+	pr_info("adsp: module %s has been registered\n", module->name);
+
+done:
+	mutex_lock(&adsp_open_lock);
+	if (rc && --adsp_open_count == 0) {
+		disable_irq(INT_ADSP);
+		allow_suspend();
+	}
+	if (rc && --module->open_count == 0 && module->clk)
+		clk_disable(module->clk);
+	mutex_unlock(&adsp_open_lock);
+	mutex_unlock(&module->lock);
+	return rc;
+}
+EXPORT_SYMBOL(msm_adsp_get);
+
+static int msm_adsp_disable_locked(struct msm_adsp_module *module);
+
+void msm_adsp_put(struct msm_adsp_module *module)
+{
+	unsigned long flags;
+
+	mutex_lock(&module->lock);
+	if (--module->open_count == 0 && module->clk)
+		clk_disable(module->clk);
+	if (module->ops) {
+		pr_info("adsp: closing module %s\n", module->name);
+
+		/* lock to ensure a dsp event cannot be delivered
+		 * during or after removal of the ops and driver_data
+		 */
+		spin_lock_irqsave(&adsp_cmd_lock, flags);
+		module->ops = NULL;
+		module->driver_data = NULL;
+		spin_unlock_irqrestore(&adsp_cmd_lock, flags);
+
+		if (module->state != ADSP_STATE_DISABLED) {
+			pr_info("adsp: disabling module %s\n", module->name);
+			msm_adsp_disable_locked(module);
+		}
+
+		msm_rpc_close(module->rpc_client);
+		module->rpc_client = 0;
+		if (--adsp_open_count == 0) {
+			disable_irq(INT_ADSP);
+			allow_suspend();
+			pr_info("adsp: disable interrupt\n");
+		}
+	} else {
+		pr_info("adsp: module %s is already closed\n", module->name);
+	}
+	mutex_unlock(&module->lock);
+}
+EXPORT_SYMBOL(msm_adsp_put);
+
+/* this should be common code with rpc_servers.c */
+static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client,
+					uint32_t xid, uint32_t accept_status)
+{
+	int rc = 0;
+	uint8_t reply_buf[sizeof(struct rpc_reply_hdr)];
+	struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf;
+
+	reply->xid = cpu_to_be32(xid);
+	reply->type = cpu_to_be32(1); /* reply */
+	reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
+
+	reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status);
+	reply->data.acc_hdr.verf_flavor = 0;
+	reply->data.acc_hdr.verf_length = 0;
+
+	rc = msm_rpc_write(rpc_cb_server_client, reply_buf, sizeof(reply_buf));
+	if (rc < 0)
+		pr_err("adsp: could not write RPC response: %d\n", rc);
+	return rc;
+}
+
+int __msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
+		   void *cmd_buf, size_t cmd_size)
+{
+	uint32_t ctrl_word;
+	uint32_t dsp_q_addr;
+	uint32_t dsp_addr;
+	uint32_t cmd_id = 0;
+	int cnt = 0;
+	int ret_status = 0;
+	unsigned long flags;
+	struct adsp_info *info = module->info;
+
+	spin_lock_irqsave(&adsp_cmd_lock, flags);
+
+	if (module->state != ADSP_STATE_ENABLED) {
+		spin_unlock_irqrestore(&adsp_cmd_lock, flags);
+		pr_err("adsp: module %s not enabled before write\n",
+		       module->name);
+		return -ENODEV;
+	}
+	if (adsp_validate_module(module->id)) {
+		spin_unlock_irqrestore(&adsp_cmd_lock, flags);
+		pr_info("adsp: module id validation failed %s  %d\n",
+			module->name, module->id);
+		return -ENXIO;
+	}
+	dsp_q_addr = adsp_get_queue_offset(info, dsp_queue_addr);
+	dsp_q_addr &= ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M;
+
+	/* Poll until the ADSP is ready to accept a command.
+	 * Wait for 100us, return error if it's not responding.
+	 * If this returns an error, we need to disable ALL modules and
+	 * then retry.
+	 */
+	while (((ctrl_word = readl(info->write_ctrl)) &
+		ADSP_RTOS_WRITE_CTRL_WORD_READY_M) !=
+		ADSP_RTOS_WRITE_CTRL_WORD_READY_V) {
+		if (cnt > 100) {
+			pr_err("adsp: timeout waiting for DSP write ready\n");
+			ret_status = -EIO;
+			goto fail;
+		}
+		pr_warning("adsp: waiting for DSP write ready\n");
+		udelay(1);
+		cnt++;
+	}
+
+	/* Set the mutex bits */
+	ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
+	ctrl_word |=  ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
+
+	/* Clear the command bits */
+	ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
+
+	/* Set the queue address bits */
+	ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
+	ctrl_word |= dsp_q_addr;
+
+	writel(ctrl_word, info->write_ctrl);
+
+	/* Generate an interrupt to the DSP.  This notifies the DSP that
+	 * we are about to send a command on this particular queue.  The
+	 * DSP will in response change its state.
+	 */
+	writel(1, info->send_irq);
+
+	/* Poll until the adsp responds to the interrupt; this does not
+	 * generate an interrupt from the adsp.  This should happen within
+	 * 5ms.
+	 */
+	cnt = 0;
+	while ((readl(info->write_ctrl) &
+		ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M) ==
+		ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V) {
+		if (cnt > 5000) {
+			pr_err("adsp: timeout waiting for adsp ack\n");
+			ret_status = -EIO;
+			goto fail;
+		}
+		udelay(1);
+		cnt++;
+	}
+
+	/* Read the ctrl word */
+	ctrl_word = readl(info->write_ctrl);
+
+	if ((ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M) !=
+			 ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V) {
+		ret_status = -EAGAIN;
+		goto fail;
+	}
+
+	/* Ctrl word status bits were 00, no error in the ctrl word */
+
+	/* Get the DSP buffer address */
+	dsp_addr = (ctrl_word & ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M) +
+		   (uint32_t)MSM_AD5_BASE;
+
+	if (dsp_addr < (uint32_t)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
+		uint16_t *buf_ptr = (uint16_t *) cmd_buf;
+		uint16_t *dsp_addr16 = (uint16_t *)dsp_addr;
+		cmd_size /= sizeof(uint16_t);
+
+		/* Save the command ID */
+		cmd_id = (uint32_t) buf_ptr[0];
+
+		/* Copy the command to DSP memory */
+		cmd_size++;
+		while (--cmd_size)
+			*dsp_addr16++ = *buf_ptr++;
+	} else {
+		uint32_t *buf_ptr = (uint32_t *) cmd_buf;
+		uint32_t *dsp_addr32 = (uint32_t *)dsp_addr;
+		cmd_size /= sizeof(uint32_t);
+
+		/* Save the command ID */
+		cmd_id = buf_ptr[0];
+
+		cmd_size++;
+		while (--cmd_size)
+			*dsp_addr32++ = *buf_ptr++;
+	}
+
+	/* Set the mutex bits */
+	ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M);
+	ctrl_word |=  ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V;
+
+	/* Set the command bits to write done */
+	ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_CMD_M);
+	ctrl_word |= ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V;
+
+	/* Set the queue address bits */
+	ctrl_word &= ~(ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M);
+	ctrl_word |= dsp_q_addr;
+
+	writel(ctrl_word, info->write_ctrl);
+
+	/* Generate an interrupt to the DSP.  It does not respond with
+	 * an interrupt, and we do not need to wait for it to
+	 * acknowledge, because it will hold the mutex lock until it's
+	 * ready to receive more commands again.
+	 */
+	writel(1, info->send_irq);
+
+	module->num_commands++;
+
+fail:
+	spin_unlock_irqrestore(&adsp_cmd_lock, flags);
+	return ret_status;
+}
+EXPORT_SYMBOL(msm_adsp_write);
+
+int msm_adsp_write(struct msm_adsp_module *module, unsigned dsp_queue_addr,
+		   void *cmd_buf, size_t cmd_size)
+{
+	int rc, retries = 0;
+	do {
+		rc = __msm_adsp_write(module, dsp_queue_addr, cmd_buf, cmd_size);
+		if (rc == -EAGAIN)
+			udelay(10);
+	} while(rc == -EAGAIN && retries++ < 100);
+	if (retries > 50)
+		pr_warning("adsp: %s command took %d attempts: rc %d\n",
+				module->name, retries, rc);
+	return rc;
+}
+
+#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
+static void *modem_event_addr;
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+static void read_modem_event(void *buf, size_t len)
+{
+	uint32_t *dptr = buf;
+	struct rpc_adsp_rtos_modem_to_app_args_t *sptr;
+	struct adsp_rtos_mp_mtoa_type *pkt_ptr;
+
+	sptr = modem_event_addr;
+	pkt_ptr = &sptr->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
+
+	dptr[0] = be32_to_cpu(sptr->mtoa_pkt.mp_mtoa_header.event);
+	dptr[1] = be32_to_cpu(pkt_ptr->module);
+	dptr[2] = be32_to_cpu(pkt_ptr->image);
+}
+#else
+static void read_modem_event(void *buf, size_t len)
+{
+	uint32_t *dptr = buf;
+	struct rpc_adsp_rtos_modem_to_app_args_t *sptr =
+		modem_event_addr;
+	dptr[0] = be32_to_cpu(sptr->event);
+	dptr[1] = be32_to_cpu(sptr->module);
+	dptr[2] = be32_to_cpu(sptr->image);
+}
+#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
+#endif /* CONFIG_MSM_ADSP_REPORT_EVENTS */
+
+static void handle_adsp_rtos_mtoa_app(struct rpc_request_hdr *req)
+{
+	struct rpc_adsp_rtos_modem_to_app_args_t *args =
+		(struct rpc_adsp_rtos_modem_to_app_args_t *)req;
+	uint32_t event;
+	uint32_t proc_id;
+	uint32_t module_id;
+	uint32_t image;
+	struct msm_adsp_module *module;
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	struct adsp_rtos_mp_mtoa_type *pkt_ptr =
+		&args->mtoa_pkt.adsp_rtos_mp_mtoa_data.mp_mtoa_packet;
+
+	event = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.event);
+	proc_id = be32_to_cpu(args->mtoa_pkt.mp_mtoa_header.proc_id);
+	module_id = be32_to_cpu(pkt_ptr->module);
+	image = be32_to_cpu(pkt_ptr->image);
+
+	if (be32_to_cpu(args->mtoa_pkt.desc_field) == RPC_ADSP_RTOS_INIT_INFO) {
+		struct queue_to_offset_type *qptr;
+		struct queue_to_offset_type *qtbl;
+		uint32_t *mptr;
+		uint32_t *mtbl;
+		uint32_t q_idx;
+		uint32_t num_entries;
+		uint32_t entries_per_image;
+		struct adsp_rtos_mp_mtoa_init_info_type *iptr;
+		struct adsp_rtos_mp_mtoa_init_info_type *sptr;
+		int32_t i_no, e_idx;
+
+		pr_info("adsp:INIT_INFO Event\n");
+		sptr = &args->mtoa_pkt.adsp_rtos_mp_mtoa_data.
+				mp_mtoa_init_packet;
+
+		iptr = adsp_info.init_info_ptr;
+		iptr->image_count = be32_to_cpu(sptr->image_count);
+		iptr->num_queue_offsets = be32_to_cpu(sptr->num_queue_offsets);
+		num_entries = iptr->num_queue_offsets;
+		qptr = &sptr->queue_offsets_tbl[0][0];
+		for (i_no = 0; i_no < iptr->image_count; i_no++) {
+			qtbl = &iptr->queue_offsets_tbl[i_no][0];
+			for (e_idx = 0; e_idx < num_entries; e_idx++) {
+				qtbl[e_idx].offset = be32_to_cpu(qptr->offset);
+				qtbl[e_idx].queue = be32_to_cpu(qptr->queue);
+				q_idx = be32_to_cpu(qptr->queue);
+				iptr->queue_offsets[i_no][q_idx] =
+						qtbl[e_idx].offset;
+				qptr++;
+			}
+		}
+
+		num_entries = be32_to_cpu(sptr->num_task_module_entries);
+		iptr->num_task_module_entries = num_entries;
+		entries_per_image = num_entries / iptr->image_count;
+		mptr = &sptr->task_to_module_tbl[0][0];
+		for (i_no = 0; i_no < iptr->image_count; i_no++) {
+			mtbl = &iptr->task_to_module_tbl[i_no][0];
+			for (e_idx = 0; e_idx < entries_per_image; e_idx++) {
+				mtbl[e_idx] = be32_to_cpu(*mptr);
+				mptr++;
+			}
+		}
+
+		iptr->module_table_size = be32_to_cpu(sptr->module_table_size);
+		mptr = &sptr->module_entries[0];
+		for (i_no = 0; i_no < iptr->module_table_size; i_no++)
+			iptr->module_entries[i_no] = be32_to_cpu(mptr[i_no]);
+		adsp_info.init_info_state = ADSP_STATE_INIT_INFO;
+		rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
+						RPC_ACCEPTSTAT_SUCCESS);
+		wake_up(&adsp_info.init_info_wait);
+
+		return;
+	}
+#else
+	event = be32_to_cpu(args->event);
+	proc_id = be32_to_cpu(args->proc_id);
+	module_id = be32_to_cpu(args->module);
+	image = be32_to_cpu(args->image);
+#endif
+
+	pr_info("adsp: rpc event=%d, proc_id=%d, module=%d, image=%d\n",
+		event, proc_id, module_id, image);
+
+	module = find_adsp_module_by_id(&adsp_info, module_id);
+	if (!module) {
+		pr_err("adsp: module %d is not supported!\n", module_id);
+		rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
+				RPC_ACCEPTSTAT_GARBAGE_ARGS);
+		return;
+	}
+
+	mutex_lock(&module->lock);
+	switch (event) {
+	case RPC_ADSP_RTOS_MOD_READY:
+		pr_info("adsp: module %s: READY\n", module->name);
+		module->state = ADSP_STATE_ENABLED;
+		wake_up(&module->state_wait);
+		adsp_set_image(module->info, image);
+		break;
+	case RPC_ADSP_RTOS_MOD_DISABLE:
+		pr_info("adsp: module %s: DISABLED\n", module->name);
+		module->state = ADSP_STATE_DISABLED;
+		wake_up(&module->state_wait);
+		break;
+	case RPC_ADSP_RTOS_SERVICE_RESET:
+		pr_info("adsp: module %s: SERVICE_RESET\n", module->name);
+		module->state = ADSP_STATE_DISABLED;
+		wake_up(&module->state_wait);
+		break;
+	case RPC_ADSP_RTOS_CMD_SUCCESS:
+		pr_info("adsp: module %s: CMD_SUCCESS\n", module->name);
+		break;
+	case RPC_ADSP_RTOS_CMD_FAIL:
+		pr_info("adsp: module %s: CMD_FAIL\n", module->name);
+		break;
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	case RPC_ADSP_RTOS_DISABLE_FAIL:
+		pr_info("adsp: module %s: DISABLE_FAIL\n", module->name);
+		break;
+#endif
+	default:
+		pr_info("adsp: unknown event %d\n", event);
+		rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
+					     RPC_ACCEPTSTAT_GARBAGE_ARGS);
+		mutex_unlock(&module->lock);
+		return;
+	}
+	rpc_send_accepted_void_reply(rpc_cb_server_client, req->xid,
+				     RPC_ACCEPTSTAT_SUCCESS);
+	mutex_unlock(&module->lock);
+#ifdef CONFIG_MSM_ADSP_REPORT_EVENTS
+	modem_event_addr = (uint32_t *)req;
+	module->ops->event(module->driver_data, EVENT_MSG_ID,
+				EVENT_LEN, read_modem_event);
+#endif
+}
+
+static int handle_adsp_rtos_mtoa(struct rpc_request_hdr *req)
+{
+	switch (req->procedure) {
+	case RPC_ADSP_RTOS_MTOA_NULL_PROC:
+		rpc_send_accepted_void_reply(rpc_cb_server_client,
+					     req->xid,
+					     RPC_ACCEPTSTAT_SUCCESS);
+		break;
+	case RPC_ADSP_RTOS_MODEM_TO_APP_PROC:
+		handle_adsp_rtos_mtoa_app(req);
+		break;
+	default:
+		pr_err("adsp: unknowned proc %d\n", req->procedure);
+		rpc_send_accepted_void_reply(
+			rpc_cb_server_client, req->xid,
+			RPC_ACCEPTSTAT_PROC_UNAVAIL);
+		break;
+	}
+	return 0;
+}
+
+/* this should be common code with rpc_servers.c */
+static int adsp_rpc_thread(void *data)
+{
+	void *buffer;
+	struct rpc_request_hdr *req;
+	int rc;
+
+	do {
+		rc = msm_rpc_read(rpc_cb_server_client, &buffer, -1, -1);
+		if (rc < 0) {
+			pr_err("adsp: could not read rpc: %d\n", rc);
+			break;
+		}
+		req = (struct rpc_request_hdr *)buffer;
+
+		req->type = be32_to_cpu(req->type);
+		req->xid = be32_to_cpu(req->xid);
+		req->rpc_vers = be32_to_cpu(req->rpc_vers);
+		req->prog = be32_to_cpu(req->prog);
+		req->vers = be32_to_cpu(req->vers);
+		req->procedure = be32_to_cpu(req->procedure);
+
+		if (req->type != 0)
+			goto bad_rpc;
+		if (req->rpc_vers != 2)
+			goto bad_rpc;
+		if (req->prog != RPC_ADSP_RTOS_MTOA_PROG)
+			goto bad_rpc;
+		if (req->vers != RPC_ADSP_RTOS_MTOA_VERS)
+			goto bad_rpc;
+
+		handle_adsp_rtos_mtoa(req);
+		kfree(buffer);
+		continue;
+
+bad_rpc:
+		pr_err("adsp: bogus rpc from modem\n");
+		kfree(buffer);
+	} while (1);
+
+	do_exit(0);
+}
+
+static size_t read_event_size;
+static void *read_event_addr;
+
+static void read_event_16(void *buf, size_t len)
+{
+	uint16_t *dst = buf;
+	uint16_t *src = read_event_addr;
+	len /= 2;
+	if (len > read_event_size)
+		len = read_event_size;
+	while (len--)
+		*dst++ = *src++;
+}
+
+static void read_event_32(void *buf, size_t len)
+{
+	uint32_t *dst = buf;
+	uint32_t *src = read_event_addr;
+	len /= 2;
+	if (len > read_event_size)
+		len = read_event_size;
+	while (len--)
+		*dst++ = *src++;
+}
+
+static int adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(
+	struct adsp_info *info, void *dsp_addr)
+{
+	struct msm_adsp_module *module;
+	unsigned rtos_task_id;
+	unsigned msg_id;
+	unsigned msg_length;
+	void (*func)(void *, size_t);
+
+	if (dsp_addr >= (void *)(MSM_AD5_BASE + QDSP_RAMC_OFFSET)) {
+		uint32_t *dsp_addr32 = dsp_addr;
+		uint32_t tmp = *dsp_addr32++;
+		rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
+		msg_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M);
+		read_event_size = tmp >> 16;
+		read_event_addr = dsp_addr32;
+		msg_length = read_event_size * sizeof(uint32_t);
+		func = read_event_32;
+	} else {
+		uint16_t *dsp_addr16 = dsp_addr;
+		uint16_t tmp = *dsp_addr16++;
+		rtos_task_id = (tmp & ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M) >> 8;
+		msg_id = tmp & ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M;
+		read_event_size = *dsp_addr16++;
+		read_event_addr = dsp_addr16;
+		msg_length = read_event_size * sizeof(uint16_t);
+		func = read_event_16;
+	}
+
+	if (rtos_task_id > info->max_task_id) {
+		pr_err("adsp: bogus task id %d\n", rtos_task_id);
+		return 0;
+	}
+	module = find_adsp_module_by_id(info,
+					adsp_get_module(info, rtos_task_id));
+
+	if (!module) {
+		pr_err("adsp: no module for task id %d\n", rtos_task_id);
+		return 0;
+	}
+
+	module->num_events++;
+
+	if (!module->ops) {
+		pr_err("adsp: module %s is not open\n", module->name);
+		return 0;
+	}
+
+	module->ops->event(module->driver_data, msg_id, msg_length, func);
+	return 0;
+}
+
+static int adsp_get_event(struct adsp_info *info)
+{
+	uint32_t ctrl_word;
+	uint32_t ready;
+	void *dsp_addr;
+	uint32_t cmd_type;
+	int cnt;
+	unsigned long flags;
+	int rc = 0;
+
+	spin_lock_irqsave(&adsp_cmd_lock, flags);
+
+	/* Whenever the DSP has a message, it updates this control word
+	 * and generates an interrupt.  When we receive the interrupt, we
+	 * read this register to find out what ADSP task the command is
+	 * comming from.
+	 *
+	 * The ADSP should *always* be ready on the first call, but the
+	 * irq handler calls us in a loop (to handle back-to-back command
+	 * processing), so we give the DSP some time to return to the
+	 * ready state.  The DSP will not issue another IRQ for events
+	 * pending between the first IRQ and the event queue being drained,
+	 * unfortunately.
+	 */
+
+	for (cnt = 0; cnt < 10; cnt++) {
+		ctrl_word = readl(info->read_ctrl);
+
+		if ((ctrl_word & ADSP_RTOS_READ_CTRL_WORD_FLAG_M) ==
+		    ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V)
+			goto ready;
+
+		udelay(10);
+	}
+	pr_warning("adsp: not ready after 100uS\n");
+	rc = -EBUSY;
+	goto done;
+
+ready:
+	/* Here we check to see if there are pending messages. If there are
+	 * none, we siply return -EAGAIN to indicate that there are no more
+	 * messages pending.
+	 */
+	ready = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_READY_M;
+	if ((ready != ADSP_RTOS_READ_CTRL_WORD_READY_V) &&
+	    (ready != ADSP_RTOS_READ_CTRL_WORD_CONT_V)) {
+		rc = -EAGAIN;
+		goto done;
+	}
+
+	/* DSP says that there are messages waiting for the host to read */
+
+	/* Get the Command Type */
+	cmd_type = ctrl_word & ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M;
+
+	/* Get the DSP buffer address */
+	dsp_addr = (void *)((ctrl_word &
+			     ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M) +
+			    (uint32_t)MSM_AD5_BASE);
+
+	/* We can only handle Task-to-Host messages */
+	if (cmd_type != ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V) {
+		pr_err("adsp: unknown dsp cmd_type %d\n", cmd_type);
+		rc = -EIO;
+		goto done;
+	}
+
+	adsp_rtos_read_ctrl_word_cmd_tast_to_h_v(info, dsp_addr);
+
+	ctrl_word = readl(info->read_ctrl);
+	ctrl_word &= ~ADSP_RTOS_READ_CTRL_WORD_READY_M;
+
+	/* Write ctrl word to the DSP */
+	writel(ctrl_word, info->read_ctrl);
+
+	/* Generate an interrupt to the DSP */
+	writel(1, info->send_irq);
+
+done:
+	spin_unlock_irqrestore(&adsp_cmd_lock, flags);
+	return rc;
+}
+
+static irqreturn_t adsp_irq_handler(int irq, void *data)
+{
+	struct adsp_info *info = &adsp_info;
+	int cnt = 0;
+	for (cnt = 0; cnt < 10; cnt++)
+		if (adsp_get_event(info) < 0)
+			break;
+	if (cnt > info->event_backlog_max)
+		info->event_backlog_max = cnt;
+	info->events_received += cnt;
+	if (cnt == 10)
+		pr_err("adsp: too many (%d) events for single irq!\n", cnt);
+	return IRQ_HANDLED;
+}
+
+int adsp_set_clkrate(struct msm_adsp_module *module, unsigned long clk_rate)
+{
+	if (module->clk && clk_rate)
+		return clk_set_rate(module->clk, clk_rate);
+
+	return -EINVAL;
+}
+
+int msm_adsp_enable(struct msm_adsp_module *module)
+{
+	int rc = 0;
+
+	pr_info("msm_adsp_enable() '%s'state[%d] id[%d]\n",
+		module->name, module->state, module->id);
+
+	mutex_lock(&module->lock);
+	switch (module->state) {
+	case ADSP_STATE_DISABLED:
+		rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_ENABLE,
+						module->id, module);
+		if (rc)
+			break;
+		module->state = ADSP_STATE_ENABLING;
+		mutex_unlock(&module->lock);
+		rc = wait_event_timeout(module->state_wait,
+					module->state != ADSP_STATE_ENABLING,
+					1 * HZ);
+		mutex_lock(&module->lock);
+		if (module->state == ADSP_STATE_ENABLED) {
+			rc = 0;
+		} else {
+			pr_err("adsp: module '%s' enable timed out\n",
+			       module->name);
+			rc = -ETIMEDOUT;
+		}
+		break;
+	case ADSP_STATE_ENABLING:
+		pr_warning("adsp: module '%s' enable in progress\n",
+			   module->name);
+		break;
+	case ADSP_STATE_ENABLED:
+		pr_warning("adsp: module '%s' already enabled\n",
+			   module->name);
+		break;
+	case ADSP_STATE_DISABLING:
+		pr_err("adsp: module '%s' disable in progress\n",
+		       module->name);
+		rc = -EBUSY;
+		break;
+	}
+	mutex_unlock(&module->lock);
+	return rc;
+}
+EXPORT_SYMBOL(msm_adsp_enable);
+
+static int msm_adsp_disable_locked(struct msm_adsp_module *module)
+{
+	int rc = 0;
+
+	switch (module->state) {
+	case ADSP_STATE_DISABLED:
+		pr_warning("adsp: module '%s' already disabled\n",
+			   module->name);
+		break;
+	case ADSP_STATE_ENABLING:
+	case ADSP_STATE_ENABLED:
+		rc = rpc_adsp_rtos_app_to_modem(RPC_ADSP_RTOS_CMD_DISABLE,
+						module->id, module);
+		module->state = ADSP_STATE_DISABLED;
+	}
+	return rc;
+}
+
+int msm_adsp_disable(struct msm_adsp_module *module)
+{
+	int rc;
+	pr_info("msm_adsp_disable() '%s'\n", module->name);
+	mutex_lock(&module->lock);
+	rc = msm_adsp_disable_locked(module);
+	mutex_unlock(&module->lock);
+	return rc;
+}
+EXPORT_SYMBOL(msm_adsp_disable);
+
+static int msm_adsp_probe(struct platform_device *pdev)
+{
+	unsigned count;
+	int rc, i;
+	int max_module_id;
+
+	pr_info("adsp: probe\n");
+
+	wake_lock_init(&adsp_wake_lock, WAKE_LOCK_SUSPEND, "adsp");
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	adsp_info.init_info_ptr = kzalloc(
+		(sizeof(struct adsp_rtos_mp_mtoa_init_info_type)), GFP_KERNEL);
+	if (!adsp_info.init_info_ptr)
+		return -ENOMEM;
+#endif
+
+	rc = adsp_init_info(&adsp_info);
+	if (rc)
+		return rc;
+	adsp_info.send_irq += (uint32_t) MSM_AD5_BASE;
+	adsp_info.read_ctrl += (uint32_t) MSM_AD5_BASE;
+	adsp_info.write_ctrl += (uint32_t) MSM_AD5_BASE;
+	count = adsp_info.module_count;
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	max_module_id = count;
+#else
+	max_module_id = adsp_info.max_module_id + 1;
+#endif
+
+	adsp_modules = kzalloc(
+		sizeof(struct msm_adsp_module) * count +
+		sizeof(void *) * max_module_id, GFP_KERNEL);
+	if (!adsp_modules)
+		return -ENOMEM;
+
+	adsp_info.id_to_module = (void *) (adsp_modules + count);
+
+	spin_lock_init(&adsp_cmd_lock);
+
+	rc = request_irq(INT_ADSP, adsp_irq_handler, IRQF_TRIGGER_RISING,
+			 "adsp", 0);
+	if (rc < 0)
+		goto fail_request_irq;
+	disable_irq(INT_ADSP);
+
+	rpc_cb_server_client = msm_rpc_open();
+	if (IS_ERR(rpc_cb_server_client)) {
+		rpc_cb_server_client = NULL;
+		rc = PTR_ERR(rpc_cb_server_client);
+		pr_err("adsp: could not create rpc server (%d)\n", rc);
+		goto fail_rpc_open;
+	}
+
+	rc = msm_rpc_register_server(rpc_cb_server_client,
+				     RPC_ADSP_RTOS_MTOA_PROG,
+				     RPC_ADSP_RTOS_MTOA_VERS);
+	if (rc) {
+		pr_err("adsp: could not register callback server (%d)\n", rc);
+		goto fail_rpc_register;
+	}
+
+	/* start the kernel thread to process the callbacks */
+	kthread_run(adsp_rpc_thread, NULL, "kadspd");
+
+	for (i = 0; i < count; i++) {
+		struct msm_adsp_module *mod = adsp_modules + i;
+		mutex_init(&mod->lock);
+		init_waitqueue_head(&mod->state_wait);
+		mod->info = &adsp_info;
+		mod->name = adsp_info.module[i].name;
+		mod->id = adsp_info.module[i].id;
+		if (adsp_info.module[i].clk_name)
+			mod->clk = clk_get(NULL, adsp_info.module[i].clk_name);
+		else
+			mod->clk = NULL;
+		if (mod->clk && adsp_info.module[i].clk_rate)
+			clk_set_rate(mod->clk, adsp_info.module[i].clk_rate);
+		mod->verify_cmd = adsp_info.module[i].verify_cmd;
+		mod->patch_event = adsp_info.module[i].patch_event;
+		INIT_HLIST_HEAD(&mod->pmem_regions);
+		mod->pdev.name = adsp_info.module[i].pdev_name;
+		mod->pdev.id = -1;
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+		adsp_info.id_to_module[i] = mod;
+#else
+		adsp_info.id_to_module[mod->id] = mod;
+#endif
+		platform_device_register(&mod->pdev);
+	}
+
+	msm_adsp_publish_cdevs(adsp_modules, count);
+
+	return 0;
+
+fail_rpc_register:
+	msm_rpc_close(rpc_cb_server_client);
+	rpc_cb_server_client = NULL;
+fail_rpc_open:
+	enable_irq(INT_ADSP);
+	free_irq(INT_ADSP, 0);
+fail_request_irq:
+	kfree(adsp_modules);
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	kfree(adsp_info.init_info_ptr);
+#endif
+	return rc;
+}
+
+static struct platform_driver msm_adsp_driver = {
+	.probe = msm_adsp_probe,
+	.driver = {
+		.name = MSM_ADSP_DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init adsp_init(void)
+{
+	return platform_driver_register(&msm_adsp_driver);
+}
+
+device_initcall(adsp_init);
diff --git a/drivers/staging/dream/qdsp5/adsp.h b/drivers/staging/dream/qdsp5/adsp.h
new file mode 100644
index 0000000..0e5c9ab
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp.h
@@ -0,0 +1,369 @@
+/* arch/arm/mach-msm/qdsp5/adsp.h
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Iliyan Malchev <ibm@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 _ARCH_ARM_MACH_MSM_ADSP_H
+#define _ARCH_ARM_MACH_MSM_ADSP_H
+
+#include <linux/types.h>
+#include <linux/msm_adsp.h>
+#include <mach/msm_rpcrouter.h>
+#include <mach/msm_adsp.h>
+
+int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
+		    unsigned long len);
+int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
+			   unsigned long *kvaddr, unsigned long len);
+int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr);
+
+int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
+			unsigned int queue_id, void *cmd_data,
+			size_t cmd_size);
+int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
+			 unsigned int queue_id, void *cmd_data,
+			 size_t cmd_size);
+int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
+			unsigned int queue_id, void *cmd_data,
+			size_t cmd_size);
+int adsp_video_verify_cmd(struct msm_adsp_module *module,
+			  unsigned int queue_id, void *cmd_data,
+			  size_t cmd_size);
+int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
+			  unsigned int queue_id, void *cmd_data,
+			  size_t cmd_size);
+
+
+struct adsp_event;
+
+int adsp_vfe_patch_event(struct msm_adsp_module *module,
+			struct adsp_event *event);
+
+int adsp_jpeg_patch_event(struct msm_adsp_module *module,
+			struct adsp_event *event);
+
+
+struct adsp_module_info {
+	const char *name;
+	const char *pdev_name;
+	uint32_t id;
+	const char *clk_name;
+	unsigned long clk_rate;
+	int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
+			   size_t);
+	int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
+};
+
+#define ADSP_EVENT_MAX_SIZE 496
+#define EVENT_LEN	12
+#define EVENT_MSG_ID	((uint16_t)~0)
+
+struct adsp_event {
+	struct list_head list;
+	uint32_t size; /* always in bytes */
+	uint16_t msg_id;
+	uint16_t type; /* 0 for msgs (from aDSP), -1 for events (from ARM9) */
+	int is16; /* always 0 (msg is 32-bit) when the event type is 1(ARM9) */
+	union {
+		uint16_t msg16[ADSP_EVENT_MAX_SIZE / 2];
+		uint32_t msg32[ADSP_EVENT_MAX_SIZE / 4];
+	} data;
+};
+
+struct adsp_info {
+	uint32_t send_irq;
+	uint32_t read_ctrl;
+	uint32_t write_ctrl;
+
+	uint32_t max_msg16_size;
+	uint32_t max_msg32_size;
+
+	uint32_t max_task_id;
+	uint32_t max_module_id;
+	uint32_t max_queue_id;
+	uint32_t max_image_id;
+
+	/* for each image id, a map of queue id to offset */
+	uint32_t **queue_offset;
+
+	/* for each image id, a map of task id to module id */
+	uint32_t **task_to_module;
+
+	/* for each module id, map of module id to module */
+	struct msm_adsp_module **id_to_module;
+
+	uint32_t module_count;
+	struct adsp_module_info *module;
+
+	/* stats */
+	uint32_t events_received;
+	uint32_t event_backlog_max;
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	/* rpc_client for init_info */
+	struct msm_rpc_endpoint *init_info_rpc_client;
+	struct adsp_rtos_mp_mtoa_init_info_type *init_info_ptr;
+	wait_queue_head_t init_info_wait;
+	unsigned init_info_state;
+#endif
+};
+
+#define RPC_ADSP_RTOS_ATOM_PROG 0x3000000a
+#define RPC_ADSP_RTOS_MTOA_PROG 0x3000000b
+#define RPC_ADSP_RTOS_ATOM_NULL_PROC 0
+#define RPC_ADSP_RTOS_MTOA_NULL_PROC 0
+#define RPC_ADSP_RTOS_APP_TO_MODEM_PROC 2
+#define RPC_ADSP_RTOS_MODEM_TO_APP_PROC 2
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(1,0)
+#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(2,1) /* must be actual vers */
+#define MSM_ADSP_DRIVER_NAME "rs3000000a:00010000"
+#elif (CONFIG_MSM_AMSS_VERSION == 6220) || (CONFIG_MSM_AMSS_VERSION == 6225)
+#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x71d1094b, 0)
+#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0xee3a9966, 0)
+#define MSM_ADSP_DRIVER_NAME "rs3000000a:71d1094b"
+#elif CONFIG_MSM_AMSS_VERSION == 6210
+#define RPC_ADSP_RTOS_ATOM_VERS MSM_RPC_VERS(0x20f17fd3, 0)
+#define RPC_ADSP_RTOS_MTOA_VERS MSM_RPC_VERS(0x75babbd6, 0)
+#define MSM_ADSP_DRIVER_NAME "rs3000000a:20f17fd3"
+#else
+#error "Unknown AMSS version"
+#endif
+
+enum rpc_adsp_rtos_proc_type {
+	RPC_ADSP_RTOS_PROC_NONE = 0,
+	RPC_ADSP_RTOS_PROC_MODEM = 1,
+	RPC_ADSP_RTOS_PROC_APPS = 2,
+};
+
+enum {
+	RPC_ADSP_RTOS_CMD_REGISTER_APP,
+	RPC_ADSP_RTOS_CMD_ENABLE,
+	RPC_ADSP_RTOS_CMD_DISABLE,
+	RPC_ADSP_RTOS_CMD_KERNEL_COMMAND,
+	RPC_ADSP_RTOS_CMD_16_COMMAND,
+	RPC_ADSP_RTOS_CMD_32_COMMAND,
+	RPC_ADSP_RTOS_CMD_DISABLE_EVENT_RSP,
+	RPC_ADSP_RTOS_CMD_REMOTE_EVENT,
+	RPC_ADSP_RTOS_CMD_SET_STATE,
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	RPC_ADSP_RTOS_CMD_REMOTE_INIT_INFO_EVENT,
+	RPC_ADSP_RTOS_CMD_GET_INIT_INFO,
+#endif
+};
+
+enum rpc_adsp_rtos_mod_status_type {
+	RPC_ADSP_RTOS_MOD_READY,
+	RPC_ADSP_RTOS_MOD_DISABLE,
+	RPC_ADSP_RTOS_SERVICE_RESET,
+	RPC_ADSP_RTOS_CMD_FAIL,
+	RPC_ADSP_RTOS_CMD_SUCCESS,
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	RPC_ADSP_RTOS_INIT_INFO,
+	RPC_ADSP_RTOS_DISABLE_FAIL,
+#endif
+};
+
+struct rpc_adsp_rtos_app_to_modem_args_t {
+	struct rpc_request_hdr hdr;
+	uint32_t gotit; /* if 1, the next elements are present */
+	uint32_t cmd; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
+	uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
+	uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
+};
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+enum qdsp_image_type {
+	QDSP_IMAGE_COMBO,
+	QDSP_IMAGE_GAUDIO,
+	QDSP_IMAGE_QTV_LP,
+	QDSP_IMAGE_MAX,
+	/* DO NOT USE: Force this enum to be a 32bit type to improve speed */
+	QDSP_IMAGE_32BIT_DUMMY = 0x10000
+};
+
+struct adsp_rtos_mp_mtoa_header_type {
+	enum rpc_adsp_rtos_mod_status_type  event;
+	enum rpc_adsp_rtos_proc_type        proc_id;
+};
+
+/* ADSP RTOS MP Communications - Modem to APP's  Event Info*/
+struct adsp_rtos_mp_mtoa_type {
+	uint32_t	module;
+	uint32_t	image;
+	uint32_t	apps_okts;
+};
+
+/* ADSP RTOS MP Communications - Modem to APP's Init Info  */
+#define IMG_MAX         8
+#define ENTRIES_MAX     64
+
+struct queue_to_offset_type {
+	uint32_t	queue;
+	uint32_t	offset;
+};
+
+struct adsp_rtos_mp_mtoa_init_info_type {
+	uint32_t	image_count;
+	uint32_t	num_queue_offsets;
+	struct queue_to_offset_type	queue_offsets_tbl[IMG_MAX][ENTRIES_MAX];
+	uint32_t	num_task_module_entries;
+	uint32_t	task_to_module_tbl[IMG_MAX][ENTRIES_MAX];
+
+	uint32_t	module_table_size;
+	uint32_t	module_entries[ENTRIES_MAX];
+	/*
+	 * queue_offsets[] is to store only queue_offsets
+	 */
+	uint32_t	queue_offsets[IMG_MAX][ENTRIES_MAX];
+};
+
+struct adsp_rtos_mp_mtoa_s_type {
+	struct adsp_rtos_mp_mtoa_header_type mp_mtoa_header;
+
+	uint32_t desc_field;
+	union {
+		struct adsp_rtos_mp_mtoa_init_info_type mp_mtoa_init_packet;
+		struct adsp_rtos_mp_mtoa_type mp_mtoa_packet;
+	} adsp_rtos_mp_mtoa_data;
+};
+
+struct rpc_adsp_rtos_modem_to_app_args_t {
+	struct rpc_request_hdr hdr;
+	uint32_t gotit; /* if 1, the next elements are present */
+	struct adsp_rtos_mp_mtoa_s_type mtoa_pkt;
+};
+#else
+struct rpc_adsp_rtos_modem_to_app_args_t {
+	struct rpc_request_hdr hdr;
+	uint32_t gotit; /* if 1, the next elements are present */
+	uint32_t event; /* e.g., RPC_ADSP_RTOS_CMD_REGISTER_APP */
+	uint32_t proc_id; /* e.g., RPC_ADSP_RTOS_PROC_APPS */
+	uint32_t module; /* e.g., QDSP_MODULE_AUDPPTASK */
+	uint32_t image; /* RPC_QDSP_IMAGE_GAUDIO */
+};
+#endif /* CONFIG_MSM_AMSS_VERSION >= 6350 */
+
+#define ADSP_STATE_DISABLED   0
+#define ADSP_STATE_ENABLING   1
+#define ADSP_STATE_ENABLED    2
+#define ADSP_STATE_DISABLING  3
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+#define ADSP_STATE_INIT_INFO  4
+#endif
+
+struct msm_adsp_module {
+	struct mutex lock;
+	const char *name;
+	unsigned id;
+	struct adsp_info *info;
+
+	struct msm_rpc_endpoint *rpc_client;
+	struct msm_adsp_ops *ops;
+	void *driver_data;
+
+	/* statistics */
+	unsigned num_commands;
+	unsigned num_events;
+
+	wait_queue_head_t state_wait;
+	unsigned state;
+
+	struct platform_device pdev;
+	struct clk *clk;
+	int open_count;
+
+	struct mutex pmem_regions_lock;
+	struct hlist_head pmem_regions;
+	int (*verify_cmd) (struct msm_adsp_module*, unsigned int, void *,
+			   size_t);
+	int (*patch_event) (struct msm_adsp_module*, struct adsp_event *);
+};
+
+extern void msm_adsp_publish_cdevs(struct msm_adsp_module *, unsigned);
+extern int adsp_init_info(struct adsp_info *info);
+
+/* Value to indicate that a queue is not defined for a particular image */
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+#define QDSP_RTOS_NO_QUEUE  0xfffffffe
+#else
+#define QDSP_RTOS_NO_QUEUE  0xffffffff
+#endif
+
+/*
+ * Constants used to communicate with the ADSP RTOS
+ */
+#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_M            0x80000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_NAVAIL_V     0x80000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_MUTEX_AVAIL_V      0x00000000U
+
+#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_M              0x70000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_REQ_V    0x00000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_WRITE_DONE_V   0x10000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_CMD_NO_CMD_V       0x70000000U
+
+#define ADSP_RTOS_WRITE_CTRL_WORD_STATUS_M           0x0E000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_NO_ERR_V           0x00000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_NO_FREE_BUF_V      0x02000000U
+
+#define ADSP_RTOS_WRITE_CTRL_WORD_KERNEL_FLG_M       0x01000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_MSG_WRITE_V   0x00000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_V         0x01000000U
+
+#define ADSP_RTOS_WRITE_CTRL_WORD_DSP_ADDR_M         0x00FFFFFFU
+#define ADSP_RTOS_WRITE_CTRL_WORD_HTOD_CMD_ID_M      0x00FFFFFFU
+
+/* Combination of MUTEX and CMD bits to check if the DSP is busy */
+#define ADSP_RTOS_WRITE_CTRL_WORD_READY_M            0xF0000000U
+#define ADSP_RTOS_WRITE_CTRL_WORD_READY_V            0x70000000U
+
+/* RTOS to Host processor command mask values */
+#define ADSP_RTOS_READ_CTRL_WORD_FLAG_M              0x80000000U
+#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_WAIT_V      0x00000000U
+#define ADSP_RTOS_READ_CTRL_WORD_FLAG_UP_CONT_V      0x80000000U
+
+#define ADSP_RTOS_READ_CTRL_WORD_CMD_M               0x60000000U
+#define ADSP_RTOS_READ_CTRL_WORD_READ_DONE_V         0x00000000U
+#define ADSP_RTOS_READ_CTRL_WORD_READ_REQ_V          0x20000000U
+#define ADSP_RTOS_READ_CTRL_WORD_NO_CMD_V            0x60000000U
+
+/* Combination of FLAG and COMMAND bits to check if MSG ready */
+#define ADSP_RTOS_READ_CTRL_WORD_READY_M             0xE0000000U
+#define ADSP_RTOS_READ_CTRL_WORD_READY_V             0xA0000000U
+#define ADSP_RTOS_READ_CTRL_WORD_CONT_V              0xC0000000U
+#define ADSP_RTOS_READ_CTRL_WORD_DONE_V              0xE0000000U
+
+#define ADSP_RTOS_READ_CTRL_WORD_STATUS_M            0x18000000U
+#define ADSP_RTOS_READ_CTRL_WORD_NO_ERR_V            0x00000000U
+
+#define ADSP_RTOS_READ_CTRL_WORD_IN_PROG_M           0x04000000U
+#define ADSP_RTOS_READ_CTRL_WORD_NO_READ_IN_PROG_V   0x00000000U
+#define ADSP_RTOS_READ_CTRL_WORD_READ_IN_PROG_V      0x04000000U
+
+#define ADSP_RTOS_READ_CTRL_WORD_CMD_TYPE_M          0x03000000U
+#define ADSP_RTOS_READ_CTRL_WORD_CMD_TASK_TO_H_V     0x00000000U
+#define ADSP_RTOS_READ_CTRL_WORD_CMD_KRNL_TO_H_V     0x01000000U
+#define ADSP_RTOS_READ_CTRL_WORD_CMD_H_TO_KRNL_CFM_V 0x02000000U
+
+#define ADSP_RTOS_READ_CTRL_WORD_DSP_ADDR_M          0x00FFFFFFU
+
+#define ADSP_RTOS_READ_CTRL_WORD_MSG_ID_M            0x000000FFU
+#define ADSP_RTOS_READ_CTRL_WORD_TASK_ID_M           0x0000FF00U
+
+/* Base address of DSP and DSP hardware registers */
+#define QDSP_RAMC_OFFSET  0x400000
+
+#endif /* _ARCH_ARM_MACH_MSM_ADSP_H */
diff --git a/drivers/staging/dream/qdsp5/adsp_6210.c b/drivers/staging/dream/qdsp5/adsp_6210.c
new file mode 100644
index 0000000..3cf4e99
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_6210.c
@@ -0,0 +1,283 @@
+/* arch/arm/mach-msm/qdsp5/adsp_6210.h
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 "adsp.h"
+
+/* Firmware modules */
+typedef enum {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_VIDEO_AAC_VOC,
+	QDSP_MODULE_PCM_DEC,
+	QDSP_MODULE_AUDIO_DEC_MP3,
+	QDSP_MODULE_AUDIO_DEC_AAC,
+	QDSP_MODULE_AUDIO_DEC_WMA,
+	QDSP_MODULE_HOSTPCM,
+	QDSP_MODULE_DTMF,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_SBC_ENC,
+	QDSP_MODULE_VOC,
+	QDSP_MODULE_VOC_PCM,
+	QDSP_MODULE_VOCENCTASK,
+	QDSP_MODULE_VOCDECTASK,
+	QDSP_MODULE_VOICEPROCTASK,
+	QDSP_MODULE_VIDEOENCTASK,
+	QDSP_MODULE_VFETASK,
+	QDSP_MODULE_WAV_ENC,
+	QDSP_MODULE_AACLC_ENC,
+	QDSP_MODULE_VIDEO_AMR,
+	QDSP_MODULE_VOC_AMR,
+	QDSP_MODULE_VOC_EVRC,
+	QDSP_MODULE_VOC_13K,
+	QDSP_MODULE_VOC_FGV,
+	QDSP_MODULE_DIAGTASK,
+	QDSP_MODULE_JPEGTASK,
+	QDSP_MODULE_LPMTASK,
+	QDSP_MODULE_QCAMTASK,
+	QDSP_MODULE_MODMATHTASK,
+	QDSP_MODULE_AUDPLAY2TASK,
+	QDSP_MODULE_AUDPLAY3TASK,
+	QDSP_MODULE_AUDPLAY4TASK,
+	QDSP_MODULE_GRAPHICSTASK,
+	QDSP_MODULE_MIDI,
+	QDSP_MODULE_GAUDIO,
+	QDSP_MODULE_VDEC_LP_MODE,
+	QDSP_MODULE_MAX,
+} qdsp_module_type;
+
+#define QDSP_RTOS_MAX_TASK_ID  19U
+
+/* Table of modules indexed by task ID for the GAUDIO image */
+static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_AUDPLAY2TASK,
+	QDSP_MODULE_AUDPLAY3TASK,
+	QDSP_MODULE_AUDPLAY4TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_GRAPHICSTASK,
+	QDSP_MODULE_MAX
+};
+
+/* Queue offset table indexed by queue ID for the GAUDIO image */
+static uint32_t qdsp_gaudio_queue_offset_table[] = {
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
+	0x3be,               /* QDSP_mpuAfeQueue                  */
+	0x3ee,               /* QDSP_mpuGraphicsCmdQueue          */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecPktQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
+	0x3c2,               /* QDSP_uPAudPPCmd1Queue             */
+	0x3c6,               /* QDSP_uPAudPPCmd2Queue             */
+	0x3ca,               /* QDSP_uPAudPPCmd3Queue             */
+	0x3da,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	0x3de,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	0x3e2,               /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	0x3e6,               /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	0x3ea,               /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x3ce,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x3d6,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x3d2,               /* QDSP_uPAudRecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
+	QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
+};
+
+/* Table of modules indexed by task ID for the COMBO image */
+static qdsp_module_type qdsp_combo_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_VOCDECTASK,
+	QDSP_MODULE_VOCENCTASK,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_VIDEOENCTASK,
+	QDSP_MODULE_VOICEPROCTASK,
+	QDSP_MODULE_VFETASK,
+	QDSP_MODULE_JPEGTASK,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_LPMTASK,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MODMATHTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX
+};
+
+/* Queue offset table indexed by queue ID for the COMBO image */
+static uint32_t qdsp_combo_queue_offset_table[] = {
+	0x585,               /* QDSP_lpmCommandQueue              */
+	0x52d,               /* QDSP_mpuAfeQueue                  */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
+	0x541,               /* QDSP_mpuModmathCmdQueue           */
+	0x555,               /* QDSP_mpuVDecCmdQueue              */
+	0x559,               /* QDSP_mpuVDecPktQueue              */
+	0x551,               /* QDSP_mpuVEncCmdQueue              */
+	0x535,               /* QDSP_rxMpuDecCmdQueue             */
+	0x539,               /* QDSP_rxMpuDecPktQueue             */
+	0x53d,               /* QDSP_txMpuEncQueue                */
+	0x55d,               /* QDSP_uPAudPPCmd1Queue             */
+	0x561,               /* QDSP_uPAudPPCmd2Queue             */
+	0x565,               /* QDSP_uPAudPPCmd3Queue             */
+	0x575,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	0x579,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x569,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x571,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x56d,               /* QDSP_uPAudRecCmdQueue             */
+	0x581,               /* QDSP_uPJpegActionCmdQueue         */
+	0x57d,               /* QDSP_uPJpegCfgCmdQueue            */
+	0x531,               /* QDSP_uPVocProcQueue               */
+	0x545,               /* QDSP_vfeCommandQueue              */
+	0x54d,               /* QDSP_vfeCommandScaleQueue         */
+	0x549                /* QDSP_vfeCommandTableQueue         */
+};
+
+/* Table of modules indexed by task ID for the QTV_LP image */
+static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX
+};
+
+/* Queue offset table indexed by queue ID for the QTV_LP image */
+static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
+	0x40c,               /* QDSP_mpuAfeQueue                  */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
+	0x410,               /* QDSP_mpuVDecCmdQueue              */
+	0x414,               /* QDSP_mpuVDecPktQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
+	0x41c,               /* QDSP_uPAudPPCmd1Queue             */
+	0x420,               /* QDSP_uPAudPPCmd2Queue             */
+	0x424,               /* QDSP_uPAudPPCmd3Queue             */
+	0x430,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x418,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x42c,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x428,               /* QDSP_uPAudRecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
+	QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
+};
+
+/* Tables to convert tasks to modules */
+static uint32_t *qdsp_task_to_module[] = {
+	qdsp_combo_task_to_module_table,
+	qdsp_gaudio_task_to_module_table,
+	qdsp_qtv_lp_task_to_module_table,
+};
+
+/* Tables to retrieve queue offsets */
+static uint32_t *qdsp_queue_offset_table[] = {
+	qdsp_combo_queue_offset_table,
+	qdsp_gaudio_queue_offset_table,
+	qdsp_qtv_lp_queue_offset_table,
+};
+
+#define QDSP_MODULE(n) \
+	{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
+
+static struct adsp_module_info module_info[] = {
+	QDSP_MODULE(AUDPPTASK),
+	QDSP_MODULE(AUDRECTASK),
+	QDSP_MODULE(AUDPREPROCTASK),
+	QDSP_MODULE(VFETASK),
+	QDSP_MODULE(QCAMTASK),
+	QDSP_MODULE(LPMTASK),
+	QDSP_MODULE(JPEGTASK),
+	QDSP_MODULE(VIDEOTASK),
+	QDSP_MODULE(VDEC_LP_MODE),
+};
+
+int adsp_init_info(struct adsp_info *info)
+{
+	info->send_irq =   0x00c00200;
+	info->read_ctrl =  0x00400038;
+	info->write_ctrl = 0x00400034;
+
+	info->max_msg16_size = 193;
+	info->max_msg32_size = 8;
+
+	info->max_task_id = 16;
+	info->max_module_id = QDSP_MODULE_MAX - 1;
+	info->max_queue_id = QDSP_QUEUE_MAX;
+	info->max_image_id = 2;
+	info->queue_offset = qdsp_queue_offset_table;
+	info->task_to_module = qdsp_task_to_module;
+
+	info->module_count = ARRAY_SIZE(module_info);
+	info->module = module_info;
+	return 0;
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_6220.c b/drivers/staging/dream/qdsp5/adsp_6220.c
new file mode 100644
index 0000000..02225cd
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_6220.c
@@ -0,0 +1,284 @@
+/* arch/arm/mach-msm/qdsp5/adsp_6220.h
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 "adsp.h"
+
+/* Firmware modules */
+typedef enum {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_VIDEO_AAC_VOC,
+	QDSP_MODULE_PCM_DEC,
+	QDSP_MODULE_AUDIO_DEC_MP3,
+	QDSP_MODULE_AUDIO_DEC_AAC,
+	QDSP_MODULE_AUDIO_DEC_WMA,
+	QDSP_MODULE_HOSTPCM,
+	QDSP_MODULE_DTMF,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_SBC_ENC,
+	QDSP_MODULE_VOC,
+	QDSP_MODULE_VOC_PCM,
+	QDSP_MODULE_VOCENCTASK,
+	QDSP_MODULE_VOCDECTASK,
+	QDSP_MODULE_VOICEPROCTASK,
+	QDSP_MODULE_VIDEOENCTASK,
+	QDSP_MODULE_VFETASK,
+	QDSP_MODULE_WAV_ENC,
+	QDSP_MODULE_AACLC_ENC,
+	QDSP_MODULE_VIDEO_AMR,
+	QDSP_MODULE_VOC_AMR,
+	QDSP_MODULE_VOC_EVRC,
+	QDSP_MODULE_VOC_13K,
+	QDSP_MODULE_VOC_FGV,
+	QDSP_MODULE_DIAGTASK,
+	QDSP_MODULE_JPEGTASK,
+	QDSP_MODULE_LPMTASK,
+	QDSP_MODULE_QCAMTASK,
+	QDSP_MODULE_MODMATHTASK,
+	QDSP_MODULE_AUDPLAY2TASK,
+	QDSP_MODULE_AUDPLAY3TASK,
+	QDSP_MODULE_AUDPLAY4TASK,
+	QDSP_MODULE_GRAPHICSTASK,
+	QDSP_MODULE_MIDI,
+	QDSP_MODULE_GAUDIO,
+	QDSP_MODULE_VDEC_LP_MODE,
+	QDSP_MODULE_MAX,
+} qdsp_module_type;
+
+#define QDSP_RTOS_MAX_TASK_ID  19U
+
+/* Table of modules indexed by task ID for the GAUDIO image */
+static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_AUDPLAY2TASK,
+	QDSP_MODULE_AUDPLAY3TASK,
+	QDSP_MODULE_AUDPLAY4TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_GRAPHICSTASK,
+	QDSP_MODULE_MAX
+};
+
+/* Queue offset table indexed by queue ID for the GAUDIO image */
+static uint32_t qdsp_gaudio_queue_offset_table[] = {
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
+	0x3f0,               /* QDSP_mpuAfeQueue                  */
+	0x420,               /* QDSP_mpuGraphicsCmdQueue          */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecPktQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
+	0x3f4,               /* QDSP_uPAudPPCmd1Queue             */
+	0x3f8,               /* QDSP_uPAudPPCmd2Queue             */
+	0x3fc,               /* QDSP_uPAudPPCmd3Queue             */
+	0x40c,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	0x410,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	0x414,               /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	0x418,               /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	0x41c,               /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x400,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x408,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x404,               /* QDSP_uPAudRecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
+	QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
+};
+
+/* Table of modules indexed by task ID for the COMBO image */
+static qdsp_module_type qdsp_combo_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_VOCDECTASK,
+	QDSP_MODULE_VOCENCTASK,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_VIDEOENCTASK,
+	QDSP_MODULE_VOICEPROCTASK,
+	QDSP_MODULE_VFETASK,
+	QDSP_MODULE_JPEGTASK,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_LPMTASK,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MODMATHTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX
+};
+
+/* Queue offset table indexed by queue ID for the COMBO image */
+static uint32_t qdsp_combo_queue_offset_table[] = {
+	0x6f2,               /* QDSP_lpmCommandQueue              */
+	0x69e,               /* QDSP_mpuAfeQueue                  */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
+	0x6b2,               /* QDSP_mpuModmathCmdQueue           */
+	0x6c6,               /* QDSP_mpuVDecCmdQueue              */
+	0x6ca,               /* QDSP_mpuVDecPktQueue              */
+	0x6c2,               /* QDSP_mpuVEncCmdQueue              */
+	0x6a6,               /* QDSP_rxMpuDecCmdQueue             */
+	0x6aa,               /* QDSP_rxMpuDecPktQueue             */
+	0x6ae,               /* QDSP_txMpuEncQueue                */
+	0x6ce,               /* QDSP_uPAudPPCmd1Queue             */
+	0x6d2,               /* QDSP_uPAudPPCmd2Queue             */
+	0x6d6,               /* QDSP_uPAudPPCmd3Queue             */
+	0x6e6,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x6da,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x6e2,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x6de,               /* QDSP_uPAudRecCmdQueue             */
+	0x6ee,               /* QDSP_uPJpegActionCmdQueue         */
+	0x6ea,               /* QDSP_uPJpegCfgCmdQueue            */
+	0x6a2,               /* QDSP_uPVocProcQueue               */
+	0x6b6,               /* QDSP_vfeCommandQueue              */
+	0x6be,               /* QDSP_vfeCommandScaleQueue         */
+	0x6ba                /* QDSP_vfeCommandTableQueue         */
+};
+
+/* Table of modules indexed by task ID for the QTV_LP image */
+static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX
+};
+
+/* Queue offset table indexed by queue ID for the QTV_LP image */
+static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
+	0x430,               /* QDSP_mpuAfeQueue                  */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
+	0x434,               /* QDSP_mpuVDecCmdQueue              */
+	0x438,               /* QDSP_mpuVDecPktQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
+	0x440,               /* QDSP_uPAudPPCmd1Queue             */
+	0x444,               /* QDSP_uPAudPPCmd2Queue             */
+	0x448,               /* QDSP_uPAudPPCmd3Queue             */
+	0x454,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x43c,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x450,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x44c,               /* QDSP_uPAudRecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
+	QDSP_RTOS_NO_QUEUE   /* QDSP_vfeCommandTableQueue         */
+};
+
+/* Tables to convert tasks to modules */
+static qdsp_module_type *qdsp_task_to_module[] = {
+	qdsp_combo_task_to_module_table,
+	qdsp_gaudio_task_to_module_table,
+	qdsp_qtv_lp_task_to_module_table,
+};
+
+/* Tables to retrieve queue offsets */
+static uint32_t *qdsp_queue_offset_table[] = {
+	qdsp_combo_queue_offset_table,
+	qdsp_gaudio_queue_offset_table,
+	qdsp_qtv_lp_queue_offset_table,
+};
+
+#define QDSP_MODULE(n) \
+	{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n }
+
+static struct adsp_module_info module_info[] = {
+	QDSP_MODULE(AUDPLAY0TASK),
+	QDSP_MODULE(AUDPPTASK),
+	QDSP_MODULE(AUDPREPROCTASK),
+	QDSP_MODULE(AUDRECTASK),
+	QDSP_MODULE(VFETASK),
+	QDSP_MODULE(QCAMTASK),
+	QDSP_MODULE(LPMTASK),
+	QDSP_MODULE(JPEGTASK),
+	QDSP_MODULE(VIDEOTASK),
+	QDSP_MODULE(VDEC_LP_MODE),
+};
+
+int adsp_init_info(struct adsp_info *info)
+{
+	info->send_irq =   0x00c00200;
+	info->read_ctrl =  0x00400038;
+	info->write_ctrl = 0x00400034;
+
+	info->max_msg16_size = 193;
+	info->max_msg32_size = 8;
+
+	info->max_task_id = 16;
+	info->max_module_id = QDSP_MODULE_MAX - 1;
+	info->max_queue_id = QDSP_QUEUE_MAX;
+	info->max_image_id = 2;
+	info->queue_offset = qdsp_queue_offset_table;
+	info->task_to_module = qdsp_task_to_module;
+
+	info->module_count = ARRAY_SIZE(module_info);
+	info->module = module_info;
+	return 0;
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_6225.c b/drivers/staging/dream/qdsp5/adsp_6225.c
new file mode 100644
index 0000000..5078afb
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_6225.c
@@ -0,0 +1,328 @@
+/* arch/arm/mach-msm/qdsp5/adsp_6225.h
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 "adsp.h"
+
+/* Firmware modules */
+typedef enum {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_VIDEO_AAC_VOC,
+	QDSP_MODULE_PCM_DEC,
+	QDSP_MODULE_AUDIO_DEC_MP3,
+	QDSP_MODULE_AUDIO_DEC_AAC,
+	QDSP_MODULE_AUDIO_DEC_WMA,
+	QDSP_MODULE_HOSTPCM,
+	QDSP_MODULE_DTMF,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_SBC_ENC,
+	QDSP_MODULE_VOC_UMTS,
+	QDSP_MODULE_VOC_CDMA,
+	QDSP_MODULE_VOC_PCM,
+	QDSP_MODULE_VOCENCTASK,
+	QDSP_MODULE_VOCDECTASK,
+	QDSP_MODULE_VOICEPROCTASK,
+	QDSP_MODULE_VIDEOENCTASK,
+	QDSP_MODULE_VFETASK,
+	QDSP_MODULE_WAV_ENC,
+	QDSP_MODULE_AACLC_ENC,
+	QDSP_MODULE_VIDEO_AMR,
+	QDSP_MODULE_VOC_AMR,
+	QDSP_MODULE_VOC_EVRC,
+	QDSP_MODULE_VOC_13K,
+	QDSP_MODULE_VOC_FGV,
+	QDSP_MODULE_DIAGTASK,
+	QDSP_MODULE_JPEGTASK,
+	QDSP_MODULE_LPMTASK,
+	QDSP_MODULE_QCAMTASK,
+	QDSP_MODULE_MODMATHTASK,
+	QDSP_MODULE_AUDPLAY2TASK,
+	QDSP_MODULE_AUDPLAY3TASK,
+	QDSP_MODULE_AUDPLAY4TASK,
+	QDSP_MODULE_GRAPHICSTASK,
+	QDSP_MODULE_MIDI,
+	QDSP_MODULE_GAUDIO,
+	QDSP_MODULE_VDEC_LP_MODE,
+	QDSP_MODULE_MAX,
+} qdsp_module_type;
+
+#define QDSP_RTOS_MAX_TASK_ID  30U
+
+/* Table of modules indexed by task ID for the GAUDIO image */
+static qdsp_module_type qdsp_gaudio_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_AUDPLAY2TASK,
+	QDSP_MODULE_AUDPLAY3TASK,
+	QDSP_MODULE_AUDPLAY4TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_GRAPHICSTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+};
+
+/* Queue offset table indexed by queue ID for the GAUDIO image */
+static uint32_t qdsp_gaudio_queue_offset_table[] = {
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
+	0x3f0,               /* QDSP_mpuAfeQueue                  */
+	0x420,               /* QDSP_mpuGraphicsCmdQueue          */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVDecPktQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
+	0x3f4,               /* QDSP_uPAudPPCmd1Queue             */
+	0x3f8,               /* QDSP_uPAudPPCmd2Queue             */
+	0x3fc,               /* QDSP_uPAudPPCmd3Queue             */
+	0x40c,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	0x410,               /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	0x414,               /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	0x418,               /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	0x41c,               /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x400,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x408,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x404,               /* QDSP_uPAudRecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandTableQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPDiagQueue                  */
+};
+
+/* Table of modules indexed by task ID for the COMBO image */
+static qdsp_module_type qdsp_combo_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_VOCDECTASK,
+	QDSP_MODULE_VOCENCTASK,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_VIDEOENCTASK,
+	QDSP_MODULE_VOICEPROCTASK,
+	QDSP_MODULE_VFETASK,
+	QDSP_MODULE_JPEGTASK,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_AUDPLAY1TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_LPMTASK,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MODMATHTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_DIAGTASK,
+	QDSP_MODULE_MAX,
+};
+
+/* Queue offset table indexed by queue ID for the COMBO image */
+static uint32_t qdsp_combo_queue_offset_table[] = {
+	0x714,               /* QDSP_lpmCommandQueue              */
+	0x6bc,               /* QDSP_mpuAfeQueue                  */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
+	0x6d0,               /* QDSP_mpuModmathCmdQueue           */
+	0x6e8,               /* QDSP_mpuVDecCmdQueue              */
+	0x6ec,               /* QDSP_mpuVDecPktQueue              */
+	0x6e4,               /* QDSP_mpuVEncCmdQueue              */
+	0x6c4,               /* QDSP_rxMpuDecCmdQueue             */
+	0x6c8,               /* QDSP_rxMpuDecPktQueue             */
+	0x6cc,               /* QDSP_txMpuEncQueue                */
+	0x6f0,               /* QDSP_uPAudPPCmd1Queue             */
+	0x6f4,               /* QDSP_uPAudPPCmd2Queue             */
+	0x6f8,               /* QDSP_uPAudPPCmd3Queue             */
+	0x708,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x6fc,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x704,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x700,               /* QDSP_uPAudRecCmdQueue             */
+	0x710,               /* QDSP_uPJpegActionCmdQueue         */
+	0x70c,               /* QDSP_uPJpegCfgCmdQueue            */
+	0x6c0,               /* QDSP_uPVocProcQueue               */
+	0x6d8,               /* QDSP_vfeCommandQueue              */
+	0x6e0,               /* QDSP_vfeCommandScaleQueue         */
+	0x6dc,               /* QDSP_vfeCommandTableQueue         */
+	0x6d4,               /* QDSP_uPDiagQueue                  */
+};
+
+/* Table of modules indexed by task ID for the QTV_LP image */
+static qdsp_module_type qdsp_qtv_lp_task_to_module_table[] = {
+	QDSP_MODULE_KERNEL,
+	QDSP_MODULE_AFETASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_VIDEOTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDPPTASK,
+	QDSP_MODULE_AUDPLAY0TASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_AUDRECTASK,
+	QDSP_MODULE_AUDPREPROCTASK,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+	QDSP_MODULE_MAX,
+};
+
+/* Queue offset table indexed by queue ID for the QTV_LP image */
+static uint32_t qdsp_qtv_lp_queue_offset_table[] = {
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_lpmCommandQueue              */
+	0x3fe,               /* QDSP_mpuAfeQueue                  */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuGraphicsCmdQueue          */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuModmathCmdQueue           */
+	0x402,               /* QDSP_mpuVDecCmdQueue              */
+	0x406,               /* QDSP_mpuVDecPktQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_mpuVEncCmdQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_rxMpuDecPktQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_txMpuEncQueue                */
+	0x40e,               /* QDSP_uPAudPPCmd1Queue             */
+	0x412,               /* QDSP_uPAudPPCmd2Queue             */
+	0x416,               /* QDSP_uPAudPPCmd3Queue             */
+	0x422,               /* QDSP_uPAudPlay0BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay1BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay2BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay3BitStreamCtrlQueue */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPAudPlay4BitStreamCtrlQueue */
+	0x40a,               /* QDSP_uPAudPreProcCmdQueue         */
+	0x41e,               /* QDSP_uPAudRecBitStreamQueue       */
+	0x41a,               /* QDSP_uPAudRecCmdQueue             */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegActionCmdQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPJpegCfgCmdQueue            */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPVocProcQueue               */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandQueue              */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandScaleQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_vfeCommandTableQueue         */
+	QDSP_RTOS_NO_QUEUE,  /* QDSP_uPDiagQueue                  */
+};
+
+/* Tables to convert tasks to modules */
+static qdsp_module_type *qdsp_task_to_module[] = {
+	qdsp_combo_task_to_module_table,
+	qdsp_gaudio_task_to_module_table,
+	qdsp_qtv_lp_task_to_module_table,
+};
+
+/* Tables to retrieve queue offsets */
+static uint32_t *qdsp_queue_offset_table[] = {
+	qdsp_combo_queue_offset_table,
+	qdsp_gaudio_queue_offset_table,
+	qdsp_qtv_lp_queue_offset_table,
+};
+
+#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
+	{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
+	  .clk_name = clkname, .clk_rate = clkrate, \
+	  .verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
+
+static struct adsp_module_info module_info[] = {
+	QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
+		adsp_vfe_patch_event),
+	QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
+	QDSP_MODULE(JPEGTASK, "vdc_clk", 0, adsp_jpeg_verify_cmd,
+		adsp_jpeg_patch_event),
+	QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
+		adsp_video_verify_cmd, NULL),
+	QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
+	QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
+		adsp_videoenc_verify_cmd, NULL),
+};
+
+int adsp_init_info(struct adsp_info *info)
+{
+	info->send_irq =   0x00c00200;
+	info->read_ctrl =  0x00400038;
+	info->write_ctrl = 0x00400034;
+
+	info->max_msg16_size = 193;
+	info->max_msg32_size = 8;
+
+	info->max_task_id = 16;
+	info->max_module_id = QDSP_MODULE_MAX - 1;
+	info->max_queue_id = QDSP_QUEUE_MAX;
+	info->max_image_id = 2;
+	info->queue_offset = qdsp_queue_offset_table;
+	info->task_to_module = qdsp_task_to_module;
+
+	info->module_count = ARRAY_SIZE(module_info);
+	info->module = module_info;
+	return 0;
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_driver.c b/drivers/staging/dream/qdsp5/adsp_driver.c
new file mode 100644
index 0000000..e55a0db
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_driver.c
@@ -0,0 +1,641 @@
+/* arch/arm/mach-msm/qdsp5/adsp_driver.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Iliyan Malchev <ibm@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/cdev.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+
+#include "adsp.h"
+
+#include <linux/msm_adsp.h>
+#include <linux/android_pmem.h>
+
+struct adsp_pmem_region {
+	struct hlist_node list;
+	void *vaddr;
+	unsigned long paddr;
+	unsigned long kvaddr;
+	unsigned long len;
+	struct file *file;
+};
+
+struct adsp_device {
+	struct msm_adsp_module *module;
+
+	spinlock_t event_queue_lock;
+	wait_queue_head_t event_wait;
+	struct list_head event_queue;
+	int abort;
+
+	const char *name;
+	struct device *device;
+	struct cdev cdev;
+};
+
+static struct adsp_device *inode_to_device(struct inode *inode);
+
+#define __CONTAINS(r, v, l) ({					\
+	typeof(r) __r = r;					\
+	typeof(v) __v = v;					\
+	typeof(v) __e = __v + l;				\
+	int res = __v >= __r->vaddr && 				\
+		__e <= __r->vaddr + __r->len;			\
+	res;							\
+})
+
+#define CONTAINS(r1, r2) ({					\
+	typeof(r2) __r2 = r2;					\
+	__CONTAINS(r1, __r2->vaddr, __r2->len);			\
+})
+
+#define IN_RANGE(r, v) ({					\
+	typeof(r) __r = r;					\
+	typeof(v) __vv = v;					\
+	int res = ((__vv >= __r->vaddr) &&			\
+		(__vv < (__r->vaddr + __r->len)));		\
+	res;							\
+})
+
+#define OVERLAPS(r1, r2) ({					\
+	typeof(r1) __r1 = r1;					\
+	typeof(r2) __r2 = r2;					\
+	typeof(__r2->vaddr) __v = __r2->vaddr;			\
+	typeof(__v) __e = __v + __r2->len - 1;			\
+	int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e));	\
+	res;							\
+})
+
+static int adsp_pmem_check(struct msm_adsp_module *module,
+		void *vaddr, unsigned long len)
+{
+	struct adsp_pmem_region *region_elt;
+	struct hlist_node *node;
+	struct adsp_pmem_region t = { .vaddr = vaddr, .len = len };
+
+	hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
+		if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
+		    OVERLAPS(region_elt, &t)) {
+			printk(KERN_ERR "adsp: module %s:"
+				" region (vaddr %p len %ld)"
+				" clashes with registered region"
+				" (vaddr %p paddr %p len %ld)\n",
+				module->name,
+				vaddr, len,
+				region_elt->vaddr,
+				(void *)region_elt->paddr,
+				region_elt->len);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int adsp_pmem_add(struct msm_adsp_module *module,
+			 struct adsp_pmem_info *info)
+{
+	unsigned long paddr, kvaddr, len;
+	struct file *file;
+	struct adsp_pmem_region *region;
+	int rc = -EINVAL;
+
+	mutex_lock(&module->pmem_regions_lock);
+	region = kmalloc(sizeof(*region), GFP_KERNEL);
+	if (!region) {
+		rc = -ENOMEM;
+		goto end;
+	}
+	INIT_HLIST_NODE(&region->list);
+	if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
+		kfree(region);
+		goto end;
+	}
+
+	rc = adsp_pmem_check(module, info->vaddr, len);
+	if (rc < 0) {
+		put_pmem_file(file);
+		kfree(region);
+		goto end;
+	}
+
+	region->vaddr = info->vaddr;
+	region->paddr = paddr;
+	region->kvaddr = kvaddr;
+	region->len = len;
+	region->file = file;
+
+	hlist_add_head(&region->list, &module->pmem_regions);
+end:
+	mutex_unlock(&module->pmem_regions_lock);
+	return rc;
+}
+
+static int adsp_pmem_lookup_vaddr(struct msm_adsp_module *module, void **addr,
+		     unsigned long len, struct adsp_pmem_region **region)
+{
+	struct hlist_node *node;
+	void *vaddr = *addr;
+	struct adsp_pmem_region *region_elt;
+
+	int match_count = 0;
+
+	*region = NULL;
+
+	/* returns physical address or zero */
+	hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
+		if (vaddr >= region_elt->vaddr &&
+		    vaddr < region_elt->vaddr + region_elt->len &&
+		    vaddr + len <= region_elt->vaddr + region_elt->len) {
+			/* offset since we could pass vaddr inside a registerd
+			 * pmem buffer
+			 */
+
+			match_count++;
+			if (!*region)
+				*region = region_elt;
+		}
+	}
+
+	if (match_count > 1) {
+		printk(KERN_ERR "adsp: module %s: "
+			"multiple hits for vaddr %p, len %ld\n",
+			module->name, vaddr, len);
+		hlist_for_each_entry(region_elt, node,
+				&module->pmem_regions, list) {
+			if (vaddr >= region_elt->vaddr &&
+			    vaddr < region_elt->vaddr + region_elt->len &&
+			    vaddr + len <= region_elt->vaddr + region_elt->len)
+				printk(KERN_ERR "\t%p, %ld --> %p\n",
+					region_elt->vaddr,
+					region_elt->len,
+					(void *)region_elt->paddr);
+		}
+	}
+
+	return *region ? 0 : -1;
+}
+
+int adsp_pmem_fixup_kvaddr(struct msm_adsp_module *module, void **addr,
+			   unsigned long *kvaddr, unsigned long len)
+{
+	struct adsp_pmem_region *region;
+	void *vaddr = *addr;
+	unsigned long *paddr = (unsigned long *)addr;
+	int ret;
+
+	ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
+	if (ret) {
+		printk(KERN_ERR "adsp: not patching %s (paddr & kvaddr),"
+			" lookup (%p, %ld) failed\n",
+			module->name, vaddr, len);
+		return ret;
+	}
+	*paddr = region->paddr + (vaddr - region->vaddr);
+	*kvaddr = region->kvaddr + (vaddr - region->vaddr);
+	return 0;
+}
+
+int adsp_pmem_fixup(struct msm_adsp_module *module, void **addr,
+		    unsigned long len)
+{
+	struct adsp_pmem_region *region;
+	void *vaddr = *addr;
+	unsigned long *paddr = (unsigned long *)addr;
+	int ret;
+
+	ret = adsp_pmem_lookup_vaddr(module, addr, len, &region);
+	if (ret) {
+		printk(KERN_ERR "adsp: not patching %s, lookup (%p, %ld) failed\n",
+			module->name, vaddr, len);
+		return ret;
+	}
+
+	*paddr = region->paddr + (vaddr - region->vaddr);
+	return 0;
+}
+
+static int adsp_verify_cmd(struct msm_adsp_module *module,
+			   unsigned int queue_id, void *cmd_data,
+			   size_t cmd_size)
+{
+	/* call the per module verifier */
+	if (module->verify_cmd)
+		return module->verify_cmd(module, queue_id, cmd_data,
+					     cmd_size);
+	else
+		printk(KERN_INFO "adsp: no packet verifying function "
+				 "for task %s\n", module->name);
+	return 0;
+}
+
+static long adsp_write_cmd(struct adsp_device *adev, void __user *arg)
+{
+	struct adsp_command_t cmd;
+	unsigned char buf[256];
+	void *cmd_data;
+	long rc;
+
+	if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
+		return -EFAULT;
+
+	if (cmd.len > 256) {
+		cmd_data = kmalloc(cmd.len, GFP_USER);
+		if (!cmd_data)
+			return -ENOMEM;
+	} else {
+		cmd_data = buf;
+	}
+
+	if (copy_from_user(cmd_data, (void __user *)(cmd.data), cmd.len)) {
+		rc = -EFAULT;
+		goto end;
+	}
+
+	mutex_lock(&adev->module->pmem_regions_lock);
+	if (adsp_verify_cmd(adev->module, cmd.queue, cmd_data, cmd.len)) {
+		printk(KERN_ERR "module %s: verify failed.\n",
+			adev->module->name);
+		rc = -EINVAL;
+		goto end;
+	}
+	rc = msm_adsp_write(adev->module, cmd.queue, cmd_data, cmd.len);
+end:
+	mutex_unlock(&adev->module->pmem_regions_lock);
+
+	if (cmd.len > 256)
+		kfree(cmd_data);
+
+	return rc;
+}
+
+static int adsp_events_pending(struct adsp_device *adev)
+{
+	unsigned long flags;
+	int yes;
+	spin_lock_irqsave(&adev->event_queue_lock, flags);
+	yes = !list_empty(&adev->event_queue);
+	spin_unlock_irqrestore(&adev->event_queue_lock, flags);
+	return yes || adev->abort;
+}
+
+static int adsp_pmem_lookup_paddr(struct msm_adsp_module *module, void **addr,
+		     struct adsp_pmem_region **region)
+{
+	struct hlist_node *node;
+	unsigned long paddr = (unsigned long)(*addr);
+	struct adsp_pmem_region *region_elt;
+
+	hlist_for_each_entry(region_elt, node, &module->pmem_regions, list) {
+		if (paddr >= region_elt->paddr &&
+		    paddr < region_elt->paddr + region_elt->len) {
+			*region = region_elt;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+int adsp_pmem_paddr_fixup(struct msm_adsp_module *module, void **addr)
+{
+	struct adsp_pmem_region *region;
+	unsigned long paddr = (unsigned long)(*addr);
+	unsigned long *vaddr = (unsigned long *)addr;
+	int ret;
+
+	ret = adsp_pmem_lookup_paddr(module, addr, &region);
+	if (ret) {
+		printk(KERN_ERR "adsp: not patching %s, paddr %p lookup failed\n",
+			module->name, vaddr);
+		return ret;
+	}
+
+	*vaddr = (unsigned long)region->vaddr + (paddr - region->paddr);
+	return 0;
+}
+
+static int adsp_patch_event(struct msm_adsp_module *module,
+				struct adsp_event *event)
+{
+	/* call the per-module msg verifier */
+	if (module->patch_event)
+		return module->patch_event(module, event);
+	return 0;
+}
+
+static long adsp_get_event(struct adsp_device *adev, void __user *arg)
+{
+	unsigned long flags;
+	struct adsp_event *data = NULL;
+	struct adsp_event_t evt;
+	int timeout;
+	long rc = 0;
+
+	if (copy_from_user(&evt, arg, sizeof(struct adsp_event_t)))
+		return -EFAULT;
+
+	timeout = (int)evt.timeout_ms;
+
+	if (timeout > 0) {
+		rc = wait_event_interruptible_timeout(
+			adev->event_wait, adsp_events_pending(adev),
+			msecs_to_jiffies(timeout));
+		if (rc == 0)
+			return -ETIMEDOUT;
+	} else {
+		rc = wait_event_interruptible(
+			adev->event_wait, adsp_events_pending(adev));
+	}
+	if (rc < 0)
+		return rc;
+
+	if (adev->abort)
+		return -ENODEV;
+
+	spin_lock_irqsave(&adev->event_queue_lock, flags);
+	if (!list_empty(&adev->event_queue)) {
+		data = list_first_entry(&adev->event_queue,
+					struct adsp_event, list);
+		list_del(&data->list);
+	}
+	spin_unlock_irqrestore(&adev->event_queue_lock, flags);
+
+	if (!data)
+		return -EAGAIN;
+
+	/* DSP messages are type 0; they may contain physical addresses */
+	if (data->type == 0)
+		adsp_patch_event(adev->module, data);
+
+	/* map adsp_event --> adsp_event_t */
+	if (evt.len < data->size) {
+		rc = -ETOOSMALL;
+		goto end;
+	}
+	if (data->msg_id != EVENT_MSG_ID) {
+		if (copy_to_user((void *)(evt.data), data->data.msg16,
+					data->size)) {
+			rc = -EFAULT;
+			goto end;
+	}
+	} else {
+		if (copy_to_user((void *)(evt.data), data->data.msg32,
+					data->size)) {
+			rc = -EFAULT;
+			goto end;
+		}
+	}
+
+	evt.type = data->type; /* 0 --> from aDSP, 1 --> from ARM9 */
+	evt.msg_id = data->msg_id;
+	evt.flags = data->is16;
+	evt.len = data->size;
+	if (copy_to_user(arg, &evt, sizeof(evt)))
+		rc = -EFAULT;
+end:
+	kfree(data);
+	return rc;
+}
+
+static long adsp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct adsp_device *adev = filp->private_data;
+
+	switch (cmd) {
+	case ADSP_IOCTL_ENABLE:
+		return msm_adsp_enable(adev->module);
+
+	case ADSP_IOCTL_DISABLE:
+		return msm_adsp_disable(adev->module);
+
+	case ADSP_IOCTL_DISABLE_EVENT_RSP:
+		return 0;
+
+	case ADSP_IOCTL_DISABLE_ACK:
+		pr_err("adsp: ADSP_IOCTL_DISABLE_ACK is not implemented.\n");
+		break;
+
+	case ADSP_IOCTL_WRITE_COMMAND:
+		return adsp_write_cmd(adev, (void __user *) arg);
+
+	case ADSP_IOCTL_GET_EVENT:
+		return adsp_get_event(adev, (void __user *) arg);
+
+	case ADSP_IOCTL_SET_CLKRATE: {
+#if CONFIG_MSM_AMSS_VERSION==6350
+		unsigned long clk_rate;
+		if (copy_from_user(&clk_rate, (void *) arg, sizeof(clk_rate)))
+			return -EFAULT;
+		return adsp_set_clkrate(adev->module, clk_rate);
+#endif
+	}
+
+	case ADSP_IOCTL_REGISTER_PMEM: {
+		struct adsp_pmem_info info;
+		if (copy_from_user(&info, (void *) arg, sizeof(info)))
+			return -EFAULT;
+		return adsp_pmem_add(adev->module, &info);
+	}
+
+	case ADSP_IOCTL_ABORT_EVENT_READ:
+		adev->abort = 1;
+		wake_up(&adev->event_wait);
+		break;
+
+	default:
+		break;
+	}
+	return -EINVAL;
+}
+
+static int adsp_release(struct inode *inode, struct file *filp)
+{
+	struct adsp_device *adev = filp->private_data;
+	struct msm_adsp_module *module = adev->module;
+	struct hlist_node *node, *tmp;
+	struct adsp_pmem_region *region;
+
+	pr_info("adsp_release() '%s'\n", adev->name);
+
+	/* clear module before putting it to avoid race with open() */
+	adev->module = NULL;
+
+	mutex_lock(&module->pmem_regions_lock);
+	hlist_for_each_safe(node, tmp, &module->pmem_regions) {
+		region = hlist_entry(node, struct adsp_pmem_region, list);
+		hlist_del(node);
+		put_pmem_file(region->file);
+		kfree(region);
+	}
+	mutex_unlock(&module->pmem_regions_lock);
+	BUG_ON(!hlist_empty(&module->pmem_regions));
+
+	msm_adsp_put(module);
+	return 0;
+}
+
+static void adsp_event(void *driver_data, unsigned id, size_t len,
+		       void (*getevent)(void *ptr, size_t len))
+{
+	struct adsp_device *adev = driver_data;
+	struct adsp_event *event;
+	unsigned long flags;
+
+	if (len > ADSP_EVENT_MAX_SIZE) {
+		pr_err("adsp_event: event too large (%d bytes)\n", len);
+		return;
+	}
+
+	event = kmalloc(sizeof(*event), GFP_ATOMIC);
+	if (!event) {
+		pr_err("adsp_event: cannot allocate buffer\n");
+		return;
+	}
+
+	if (id != EVENT_MSG_ID) {
+		event->type = 0;
+		event->is16 = 0;
+		event->msg_id = id;
+		event->size = len;
+
+		getevent(event->data.msg16, len);
+	} else {
+		event->type = 1;
+		event->is16 = 1;
+		event->msg_id = id;
+		event->size = len;
+		getevent(event->data.msg32, len);
+	}
+
+	spin_lock_irqsave(&adev->event_queue_lock, flags);
+	list_add_tail(&event->list, &adev->event_queue);
+	spin_unlock_irqrestore(&adev->event_queue_lock, flags);
+	wake_up(&adev->event_wait);
+}
+
+static struct msm_adsp_ops adsp_ops = {
+	.event = adsp_event,
+};
+
+static int adsp_open(struct inode *inode, struct file *filp)
+{
+	struct adsp_device *adev;
+	int rc;
+
+	rc = nonseekable_open(inode, filp);
+	if (rc < 0)
+		return rc;
+
+	adev = inode_to_device(inode);
+	if (!adev)
+		return -ENODEV;
+
+	pr_info("adsp_open() name = '%s'\n", adev->name);
+
+	rc = msm_adsp_get(adev->name, &adev->module, &adsp_ops, adev);
+	if (rc)
+		return rc;
+
+	pr_info("adsp_open() module '%s' adev %p\n", adev->name, adev);
+	filp->private_data = adev;
+	adev->abort = 0;
+	INIT_HLIST_HEAD(&adev->module->pmem_regions);
+	mutex_init(&adev->module->pmem_regions_lock);
+
+	return 0;
+}
+
+static unsigned adsp_device_count;
+static struct adsp_device *adsp_devices;
+
+static struct adsp_device *inode_to_device(struct inode *inode)
+{
+	unsigned n = MINOR(inode->i_rdev);
+	if (n < adsp_device_count) {
+		if (adsp_devices[n].device)
+			return adsp_devices + n;
+	}
+	return NULL;
+}
+
+static dev_t adsp_devno;
+static struct class *adsp_class;
+
+static struct file_operations adsp_fops = {
+	.owner = THIS_MODULE,
+	.open = adsp_open,
+	.unlocked_ioctl = adsp_ioctl,
+	.release = adsp_release,
+};
+
+static void adsp_create(struct adsp_device *adev, const char *name,
+			struct device *parent, dev_t devt)
+{
+	struct device *dev;
+	int rc;
+
+	dev = device_create(adsp_class, parent, devt, "%s", name);
+	if (IS_ERR(dev))
+		return;
+
+	init_waitqueue_head(&adev->event_wait);
+	INIT_LIST_HEAD(&adev->event_queue);
+	spin_lock_init(&adev->event_queue_lock);
+
+	cdev_init(&adev->cdev, &adsp_fops);
+	adev->cdev.owner = THIS_MODULE;
+
+	rc = cdev_add(&adev->cdev, devt, 1);
+	if (rc < 0) {
+		device_destroy(adsp_class, devt);
+	} else {
+		adev->device = dev;
+		adev->name = name;
+	}
+}
+
+void msm_adsp_publish_cdevs(struct msm_adsp_module *modules, unsigned n)
+{
+	int rc;
+
+	adsp_devices = kzalloc(sizeof(struct adsp_device) * n, GFP_KERNEL);
+	if (!adsp_devices)
+		return;
+
+	adsp_class = class_create(THIS_MODULE, "adsp");
+	if (IS_ERR(adsp_class))
+		goto fail_create_class;
+
+	rc = alloc_chrdev_region(&adsp_devno, 0, n, "adsp");
+	if (rc < 0)
+		goto fail_alloc_region;
+
+	adsp_device_count = n;
+	for (n = 0; n < adsp_device_count; n++) {
+		adsp_create(adsp_devices + n,
+			    modules[n].name, &modules[n].pdev.dev,
+			    MKDEV(MAJOR(adsp_devno), n));
+	}
+
+	return;
+
+fail_alloc_region:
+	class_unregister(adsp_class);
+fail_create_class:
+	kfree(adsp_devices);
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_info.c b/drivers/staging/dream/qdsp5/adsp_info.c
new file mode 100644
index 0000000..b9c77d2
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_info.c
@@ -0,0 +1,121 @@
+/* arch/arm/mach-msm/adsp_info.c
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated.
+ * Copyright (c) 2008 QUALCOMM USA, INC.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 "adsp.h"
+
+/* Firmware modules */
+#define QDSP_MODULE_KERNEL                  0x0106dd4e
+#define QDSP_MODULE_AFETASK                 0x0106dd6f
+#define QDSP_MODULE_AUDPLAY0TASK            0x0106dd70
+#define QDSP_MODULE_AUDPLAY1TASK            0x0106dd71
+#define QDSP_MODULE_AUDPPTASK               0x0106dd72
+#define QDSP_MODULE_VIDEOTASK               0x0106dd73
+#define QDSP_MODULE_VIDEO_AAC_VOC           0x0106dd74
+#define QDSP_MODULE_PCM_DEC                 0x0106dd75
+#define QDSP_MODULE_AUDIO_DEC_MP3           0x0106dd76
+#define QDSP_MODULE_AUDIO_DEC_AAC           0x0106dd77
+#define QDSP_MODULE_AUDIO_DEC_WMA           0x0106dd78
+#define QDSP_MODULE_HOSTPCM                 0x0106dd79
+#define QDSP_MODULE_DTMF                    0x0106dd7a
+#define QDSP_MODULE_AUDRECTASK              0x0106dd7b
+#define QDSP_MODULE_AUDPREPROCTASK          0x0106dd7c
+#define QDSP_MODULE_SBC_ENC                 0x0106dd7d
+#define QDSP_MODULE_VOC_UMTS                0x0106dd9a
+#define QDSP_MODULE_VOC_CDMA                0x0106dd98
+#define QDSP_MODULE_VOC_PCM                 0x0106dd7f
+#define QDSP_MODULE_VOCENCTASK              0x0106dd80
+#define QDSP_MODULE_VOCDECTASK              0x0106dd81
+#define QDSP_MODULE_VOICEPROCTASK           0x0106dd82
+#define QDSP_MODULE_VIDEOENCTASK            0x0106dd83
+#define QDSP_MODULE_VFETASK                 0x0106dd84
+#define QDSP_MODULE_WAV_ENC                 0x0106dd85
+#define QDSP_MODULE_AACLC_ENC               0x0106dd86
+#define QDSP_MODULE_VIDEO_AMR               0x0106dd87
+#define QDSP_MODULE_VOC_AMR                 0x0106dd88
+#define QDSP_MODULE_VOC_EVRC                0x0106dd89
+#define QDSP_MODULE_VOC_13K                 0x0106dd8a
+#define QDSP_MODULE_VOC_FGV                 0x0106dd8b
+#define QDSP_MODULE_DIAGTASK                0x0106dd8c
+#define QDSP_MODULE_JPEGTASK                0x0106dd8d
+#define QDSP_MODULE_LPMTASK                 0x0106dd8e
+#define QDSP_MODULE_QCAMTASK                0x0106dd8f
+#define QDSP_MODULE_MODMATHTASK             0x0106dd90
+#define QDSP_MODULE_AUDPLAY2TASK            0x0106dd91
+#define QDSP_MODULE_AUDPLAY3TASK            0x0106dd92
+#define QDSP_MODULE_AUDPLAY4TASK            0x0106dd93
+#define QDSP_MODULE_GRAPHICSTASK            0x0106dd94
+#define QDSP_MODULE_MIDI                    0x0106dd95
+#define QDSP_MODULE_GAUDIO                  0x0106dd96
+#define QDSP_MODULE_VDEC_LP_MODE            0x0106dd97
+#define QDSP_MODULE_MAX                     0x7fffffff
+
+   /* DO NOT USE: Force this enum to be a 32bit type to improve speed */
+#define QDSP_MODULE_32BIT_DUMMY 0x10000
+
+static uint32_t *qdsp_task_to_module[IMG_MAX];
+static uint32_t	*qdsp_queue_offset_table[IMG_MAX];
+
+#define QDSP_MODULE(n, clkname, clkrate, verify_cmd_func, patch_event_func) \
+	{ .name = #n, .pdev_name = "adsp_" #n, .id = QDSP_MODULE_##n, \
+	  .clk_name = clkname, .clk_rate = clkrate, \
+	  .verify_cmd = verify_cmd_func, .patch_event = patch_event_func }
+
+static struct adsp_module_info module_info[] = {
+	QDSP_MODULE(AUDPLAY0TASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(AUDPPTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(AUDRECTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(AUDPREPROCTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(VFETASK, "vfe_clk", 0, adsp_vfe_verify_cmd,
+		adsp_vfe_patch_event),
+	QDSP_MODULE(QCAMTASK, NULL, 0, NULL, NULL),
+	QDSP_MODULE(LPMTASK, NULL, 0, adsp_lpm_verify_cmd, NULL),
+	QDSP_MODULE(JPEGTASK, "vdc_clk", 96000000, adsp_jpeg_verify_cmd,
+		adsp_jpeg_patch_event),
+	QDSP_MODULE(VIDEOTASK, "vdc_clk", 96000000,
+		adsp_video_verify_cmd, NULL),
+	QDSP_MODULE(VDEC_LP_MODE, NULL, 0, NULL, NULL),
+	QDSP_MODULE(VIDEOENCTASK, "vdc_clk", 96000000,
+		adsp_videoenc_verify_cmd, NULL),
+};
+
+int adsp_init_info(struct adsp_info *info)
+{
+	uint32_t img_num;
+
+	info->send_irq =   0x00c00200;
+	info->read_ctrl =  0x00400038;
+	info->write_ctrl = 0x00400034;
+
+	info->max_msg16_size = 193;
+	info->max_msg32_size = 8;
+	for (img_num = 0; img_num < IMG_MAX; img_num++)
+		qdsp_queue_offset_table[img_num] =
+		&info->init_info_ptr->queue_offsets[img_num][0];
+
+	for (img_num = 0; img_num < IMG_MAX; img_num++)
+		qdsp_task_to_module[img_num] =
+		&info->init_info_ptr->task_to_module_tbl[img_num][0];
+	info->max_task_id = 30;
+	info->max_module_id = QDSP_MODULE_MAX - 1;
+	info->max_queue_id = QDSP_MAX_NUM_QUEUES;
+	info->max_image_id = 2;
+	info->queue_offset = qdsp_queue_offset_table;
+	info->task_to_module = qdsp_task_to_module;
+
+	info->module_count = ARRAY_SIZE(module_info);
+	info->module = module_info;
+	return 0;
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c b/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c
new file mode 100644
index 0000000..4f493ed
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_jpeg_patch_event.c
@@ -0,0 +1,31 @@
+/* arch/arm/mach-msm/qdsp5/adsp_jpeg_patch_event.c
+ *
+ * Verification code for aDSP JPEG events.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/qdsp5/qdsp5jpegmsg.h>
+#include "adsp.h"
+
+int adsp_jpeg_patch_event(struct msm_adsp_module *module,
+			struct adsp_event *event)
+{
+	if (event->msg_id == JPEG_MSG_ENC_OP_PRODUCED) {
+		jpeg_msg_enc_op_produced *op = (jpeg_msg_enc_op_produced *)event->data.msg16;
+		return adsp_pmem_paddr_fixup(module, (void **)&op->op_buf_addr);
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c
new file mode 100644
index 0000000..b33eba2
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_jpeg_verify_cmd.c
@@ -0,0 +1,182 @@
+/* arch/arm/mach-msm/qdsp5/adsp_jpeg_verify_cmd.c
+ *
+ * Verification code for aDSP JPEG packets from userspace.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/qdsp5/qdsp5jpegcmdi.h>
+#include "adsp.h"
+
+static uint32_t dec_fmt;
+
+static inline void get_sizes(jpeg_cmd_enc_cfg *cmd, uint32_t *luma_size,
+			     uint32_t *chroma_size)
+{
+	uint32_t fmt, luma_width, luma_height;
+
+	fmt = cmd->process_cfg & JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_M;
+	luma_width = (cmd->ip_size_cfg & JPEG_CMD_IP_SIZE_CFG_LUMA_WIDTH_M)
+		      >> 16;
+	luma_height = cmd->frag_cfg & JPEG_CMD_FRAG_SIZE_LUMA_HEIGHT_M;
+	*luma_size = luma_width * luma_height;
+	if (fmt == JPEG_CMD_ENC_PROCESS_CFG_IP_DATA_FORMAT_H2V2)
+		*chroma_size = *luma_size/2;
+	else
+		*chroma_size = *luma_size;
+}
+
+static inline int verify_jpeg_cmd_enc_cfg(struct msm_adsp_module *module,
+                             		  void *cmd_data, size_t cmd_size)
+{
+	jpeg_cmd_enc_cfg *cmd = (jpeg_cmd_enc_cfg *)cmd_data;
+	uint32_t luma_size, chroma_size;
+	int i, num_frags;
+
+	if (cmd_size != sizeof(jpeg_cmd_enc_cfg)) {
+		printk(KERN_ERR "adsp: module %s: JPEG ENC CFG invalid cmd_size %d\n",
+			module->name, cmd_size);
+		return -1;
+	}
+
+	get_sizes(cmd, &luma_size, &chroma_size);
+	num_frags = (cmd->process_cfg >> 10) & 0xf;
+	num_frags = ((num_frags == 1) ? num_frags : num_frags * 2);
+	for (i = 0; i < num_frags; i += 2) {
+		if (adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i]), luma_size) ||
+		    adsp_pmem_fixup(module, (void **)(&cmd->frag_cfg_part[i+1]), chroma_size))
+			return -1;
+	}
+
+	if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_0_cfg_part1,
+			    cmd->op_buf_0_cfg_part2) ||
+	    adsp_pmem_fixup(module, (void **)&cmd->op_buf_1_cfg_part1,
+			    cmd->op_buf_1_cfg_part2))
+		return -1;
+	return 0;
+}
+
+static inline int verify_jpeg_cmd_dec_cfg(struct msm_adsp_module *module,
+					  void *cmd_data, size_t cmd_size)
+{
+	jpeg_cmd_dec_cfg *cmd = (jpeg_cmd_dec_cfg *)cmd_data;
+	uint32_t div;
+
+	if (cmd_size != sizeof(jpeg_cmd_dec_cfg)) {
+		printk(KERN_ERR "adsp: module %s: JPEG DEC CFG invalid cmd_size %d\n",
+			module->name, cmd_size);
+		return -1;
+	}
+
+	if (adsp_pmem_fixup(module, (void **)&cmd->ip_stream_buf_cfg_part1,
+			    cmd->ip_stream_buf_cfg_part2) ||
+	    adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part1,
+			    cmd->op_stream_buf_0_cfg_part2) ||
+	    adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part1,
+			    cmd->op_stream_buf_1_cfg_part2))
+		return -1;
+	dec_fmt = cmd->op_data_format &
+		JPEG_CMD_DEC_OP_DATA_FORMAT_M;
+	div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ? 2 : 1;
+	if (adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_0_cfg_part3,
+			    cmd->op_stream_buf_0_cfg_part2 / div) ||
+	    adsp_pmem_fixup(module, (void **)&cmd->op_stream_buf_1_cfg_part3,
+			    cmd->op_stream_buf_1_cfg_part2 / div))
+		return -1;
+	return 0;
+}
+
+static int verify_jpeg_cfg_cmd(struct msm_adsp_module *module,
+			       void *cmd_data, size_t cmd_size)
+{
+	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
+	switch(cmd_id) {
+	case JPEG_CMD_ENC_CFG:
+		return verify_jpeg_cmd_enc_cfg(module, cmd_data, cmd_size);
+	case JPEG_CMD_DEC_CFG:
+		return verify_jpeg_cmd_dec_cfg(module, cmd_data, cmd_size);
+	default:
+		if (cmd_id > 1) {
+			printk(KERN_ERR "adsp: module %s: invalid JPEG CFG cmd_id %d\n", module->name, cmd_id);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int verify_jpeg_action_cmd(struct msm_adsp_module *module,
+				  void *cmd_data, size_t cmd_size)
+{
+	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
+	switch (cmd_id) {
+	case JPEG_CMD_ENC_OP_CONSUMED:
+	{
+		jpeg_cmd_enc_op_consumed *cmd =
+			(jpeg_cmd_enc_op_consumed *)cmd_data;
+
+		if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
+			printk(KERN_ERR "adsp: module %s: JPEG_CMD_ENC_OP_CONSUMED invalid size %d\n",
+				module->name, cmd_size);
+			return -1;
+		}
+
+		if (adsp_pmem_fixup(module, (void **)&cmd->op_buf_addr,
+				    cmd->op_buf_size))
+			return -1;
+	}
+	break;
+	case JPEG_CMD_DEC_OP_CONSUMED:
+	{
+		uint32_t div;
+		jpeg_cmd_dec_op_consumed *cmd =
+			(jpeg_cmd_dec_op_consumed *)cmd_data;
+
+		if (cmd_size != sizeof(jpeg_cmd_enc_op_consumed)) {
+			printk(KERN_ERR "adsp: module %s: JPEG_CMD_DEC_OP_CONSUMED invalid size %d\n",
+				module->name, cmd_size);
+			return -1;
+		}
+
+		div = (dec_fmt == JPEG_CMD_DEC_OP_DATA_FORMAT_H2V2) ?  2 : 1;
+		if (adsp_pmem_fixup(module, (void **)&cmd->luma_op_buf_addr,
+				    cmd->luma_op_buf_size) ||
+		    adsp_pmem_fixup(module, (void **)&cmd->chroma_op_buf_addr,
+				    cmd->luma_op_buf_size / div))
+			return -1;
+	}
+	break;
+	default:
+		if (cmd_id > 7) {
+			printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
+				module->name, cmd_id);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+int adsp_jpeg_verify_cmd(struct msm_adsp_module *module,
+			 unsigned int queue_id, void *cmd_data,
+			 size_t cmd_size)
+{
+	switch(queue_id) {
+	case QDSP_uPJpegCfgCmdQueue:
+		return verify_jpeg_cfg_cmd(module, cmd_data, cmd_size);
+	case QDSP_uPJpegActionCmdQueue:
+		return verify_jpeg_action_cmd(module, cmd_data, cmd_size);
+	default:
+		return -1;
+	}
+}
+
diff --git a/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c
new file mode 100644
index 0000000..1e23ef3
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_lpm_verify_cmd.c
@@ -0,0 +1,65 @@
+/* arch/arm/mach-msm/qdsp5/adsp_lpm_verify_cmd.c
+ *
+ * Verificion code for aDSP LPM packets from userspace.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/qdsp5/qdsp5lpmcmdi.h>
+#include "adsp.h"
+
+int adsp_lpm_verify_cmd(struct msm_adsp_module *module,
+			 unsigned int queue_id, void *cmd_data,
+			 size_t cmd_size)
+{
+	uint32_t cmd_id, col_height, input_row_incr, output_row_incr,
+		input_size, output_size;
+	uint32_t size_mask = 0x0fff;
+	lpm_cmd_start *cmd;
+
+	if (queue_id != QDSP_lpmCommandQueue) {
+		printk(KERN_ERR "adsp: module %s: wrong queue id %d\n",
+			module->name, queue_id);
+		return -1;
+	}
+
+	cmd = (lpm_cmd_start *)cmd_data;
+	cmd_id = cmd->cmd_id;
+
+	if (cmd_id == LPM_CMD_START) {
+		if (cmd_size != sizeof(lpm_cmd_start)) {
+			printk(KERN_ERR "adsp: module %s: wrong size %d, expect %d\n",
+				module->name, cmd_size, sizeof(lpm_cmd_start));
+			return -1;
+		}
+		col_height = cmd->ip_data_cfg_part1 & size_mask;
+		input_row_incr = cmd->ip_data_cfg_part2 & size_mask;
+		output_row_incr = cmd->op_data_cfg_part1 & size_mask;
+		input_size = col_height * input_row_incr;
+		output_size = col_height * output_row_incr;
+		if ((cmd->ip_data_cfg_part4 && adsp_pmem_fixup(module,
+				    (void **)(&cmd->ip_data_cfg_part4),
+				    input_size)) ||
+		   (cmd->op_data_cfg_part3 && adsp_pmem_fixup(module,
+				    (void **)(&cmd->op_data_cfg_part3),
+				    output_size)))
+			return -1;
+	} else if (cmd_id > 1) {
+		printk(KERN_ERR "adsp: module %s: invalid cmd_id %d\n",
+			module->name, cmd_id);
+		return -1;
+	}
+	return 0;
+}
+
diff --git a/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c b/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c
new file mode 100644
index 0000000..a56392b
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_vfe_patch_event.c
@@ -0,0 +1,54 @@
+/* arch/arm/mach-msm/qdsp5/adsp_vfe_patch_event.c
+ *
+ * Verification code for aDSP VFE packets from userspace.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/qdsp5/qdsp5vfemsg.h>
+#include "adsp.h"
+
+static int patch_op_event(struct msm_adsp_module *module,
+				struct adsp_event *event)
+{
+	vfe_msg_op1 *op = (vfe_msg_op1 *)event->data.msg16;
+	if (adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_y_addr) ||
+	    adsp_pmem_paddr_fixup(module, (void **)&op->op1_buf_cbcr_addr))
+		return -1;
+	return 0;
+}
+
+static int patch_af_wb_event(struct msm_adsp_module *module,
+				struct adsp_event *event)
+{
+	vfe_msg_stats_wb_exp *af = (vfe_msg_stats_wb_exp *)event->data.msg16;
+	return adsp_pmem_paddr_fixup(module, (void **)&af->wb_exp_stats_op_buf);
+}
+
+int adsp_vfe_patch_event(struct msm_adsp_module *module,
+			struct adsp_event *event)
+{
+	switch(event->msg_id) {
+	case VFE_MSG_OP1:
+	case VFE_MSG_OP2:
+		return patch_op_event(module, event);
+	case VFE_MSG_STATS_AF:
+	case VFE_MSG_STATS_WB_EXP:
+		return patch_af_wb_event(module, event);
+	default:
+		break;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c
new file mode 100644
index 0000000..927d50a
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_vfe_verify_cmd.c
@@ -0,0 +1,239 @@
+/* arch/arm/mach-msm/qdsp5/adsp_vfe_verify_cmd.c
+ *
+ * Verification code for aDSP VFE packets from userspace.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/qdsp5/qdsp5vfecmdi.h>
+#include "adsp.h"
+
+static uint32_t size1_y, size2_y, size1_cbcr, size2_cbcr;
+static uint32_t af_size = 4228;
+static uint32_t awb_size = 8196;
+
+static inline int verify_cmd_op_ack(struct msm_adsp_module *module,
+				    void *cmd_data, size_t cmd_size)
+{
+	vfe_cmd_op1_ack *cmd = (vfe_cmd_op1_ack *)cmd_data;
+	void **addr_y = (void **)&cmd->op1_buf_y_addr;
+	void **addr_cbcr = (void **)(&cmd->op1_buf_cbcr_addr);
+
+	if (cmd_size != sizeof(vfe_cmd_op1_ack))
+		return -1;
+	if ((*addr_y && adsp_pmem_fixup(module, addr_y, size1_y)) ||
+	    (*addr_cbcr && adsp_pmem_fixup(module, addr_cbcr, size1_cbcr)))
+		return -1;
+	return 0;
+}
+
+static inline int verify_cmd_stats_autofocus_cfg(struct msm_adsp_module *module,
+						 void *cmd_data, size_t cmd_size)
+{
+	int i;
+	vfe_cmd_stats_autofocus_cfg *cmd =
+		(vfe_cmd_stats_autofocus_cfg *)cmd_data;
+
+	if (cmd_size != sizeof(vfe_cmd_stats_autofocus_cfg))
+		return -1;
+
+	for (i = 0; i < 3; i++) {
+		void **addr = (void **)(&cmd->af_stats_op_buf[i]);
+		if (*addr && adsp_pmem_fixup(module, addr, af_size))
+			return -1;
+	}
+	return 0;
+}
+
+static inline int verify_cmd_stats_wb_exp_cfg(struct msm_adsp_module *module,
+					      void *cmd_data, size_t cmd_size)
+{
+	vfe_cmd_stats_wb_exp_cfg *cmd =
+		(vfe_cmd_stats_wb_exp_cfg *)cmd_data;
+	int i;
+
+	if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_cfg))
+		return -1;
+
+	for (i = 0; i < 3; i++) {
+		void **addr = (void **)(&cmd->wb_exp_stats_op_buf[i]);
+		if (*addr && adsp_pmem_fixup(module, addr, awb_size))
+			return -1;
+	}
+	return 0;
+}
+
+static inline int verify_cmd_stats_af_ack(struct msm_adsp_module *module,
+					  void *cmd_data, size_t cmd_size)
+{
+	vfe_cmd_stats_af_ack *cmd = (vfe_cmd_stats_af_ack *)cmd_data;
+	void **addr = (void **)&cmd->af_stats_op_buf;
+
+	if (cmd_size != sizeof(vfe_cmd_stats_af_ack))
+		return -1;
+
+	if (*addr && adsp_pmem_fixup(module, addr, af_size))
+		return -1;
+	return 0;
+}
+
+static inline int verify_cmd_stats_wb_exp_ack(struct msm_adsp_module *module,
+					      void *cmd_data, size_t cmd_size)
+{
+	vfe_cmd_stats_wb_exp_ack *cmd =
+		(vfe_cmd_stats_wb_exp_ack *)cmd_data;
+	void **addr = (void **)&cmd->wb_exp_stats_op_buf;
+
+	if (cmd_size != sizeof(vfe_cmd_stats_wb_exp_ack))
+		return -1;
+
+	if (*addr && adsp_pmem_fixup(module, addr, awb_size))
+		return -1;
+	return 0;
+}
+
+static int verify_vfe_command(struct msm_adsp_module *module,
+			      void *cmd_data, size_t cmd_size)
+{
+	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
+	switch (cmd_id) {
+	case VFE_CMD_OP1_ACK:
+		return verify_cmd_op_ack(module, cmd_data, cmd_size);
+	case VFE_CMD_OP2_ACK:
+		return verify_cmd_op_ack(module, cmd_data, cmd_size);
+	case VFE_CMD_STATS_AUTOFOCUS_CFG:
+		return verify_cmd_stats_autofocus_cfg(module, cmd_data,
+						      cmd_size);
+	case VFE_CMD_STATS_WB_EXP_CFG:
+		return verify_cmd_stats_wb_exp_cfg(module, cmd_data, cmd_size);
+	case VFE_CMD_STATS_AF_ACK:
+		return verify_cmd_stats_af_ack(module, cmd_data, cmd_size);
+	case VFE_CMD_STATS_WB_EXP_ACK:
+		return verify_cmd_stats_wb_exp_ack(module, cmd_data, cmd_size);
+	default:
+		if (cmd_id > 29) {
+			printk(KERN_ERR "adsp: module %s: invalid VFE command id %d\n", module->name, cmd_id);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static int verify_vfe_command_scale(struct msm_adsp_module *module,
+				    void *cmd_data, size_t cmd_size)
+{
+	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
+	// FIXME: check the size
+	if (cmd_id > 1) {
+		printk(KERN_ERR "adsp: module %s: invalid VFE SCALE command id %d\n", module->name, cmd_id);
+		return -1;
+	}
+	return 0;
+}
+
+
+static uint32_t get_size(uint32_t hw)
+{
+	uint32_t height, width;
+	uint32_t height_mask = 0x3ffc;
+	uint32_t width_mask = 0x3ffc000;
+
+	height = (hw & height_mask) >> 2;
+	width = (hw & width_mask) >> 14 ;
+	return height * width;
+}
+
+static int verify_vfe_command_table(struct msm_adsp_module *module,
+				    void *cmd_data, size_t cmd_size)
+{
+	uint32_t cmd_id = ((uint32_t *)cmd_data)[0];
+	int i;
+
+	switch (cmd_id) {
+	case VFE_CMD_AXI_IP_CFG:
+	{
+		vfe_cmd_axi_ip_cfg *cmd = (vfe_cmd_axi_ip_cfg *)cmd_data;
+		uint32_t size;
+		if (cmd_size != sizeof(vfe_cmd_axi_ip_cfg)) {
+			printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_IP_CFG) command size %d\n",
+				module->name, cmd_size);
+			return -1;
+		}
+		size = get_size(cmd->ip_cfg_part2);
+
+		for (i = 0; i < 8; i++) {
+			void **addr = (void **)
+				&cmd->ip_buf_addr[i];
+			if (*addr && adsp_pmem_fixup(module, addr, size))
+				return -1;
+		}
+	}
+	case VFE_CMD_AXI_OP_CFG:
+	{
+		vfe_cmd_axi_op_cfg *cmd = (vfe_cmd_axi_op_cfg *)cmd_data;
+		void **addr1_y, **addr2_y, **addr1_cbcr, **addr2_cbcr;
+
+		if (cmd_size != sizeof(vfe_cmd_axi_op_cfg)) {
+			printk(KERN_ERR "adsp: module %s: invalid VFE TABLE (VFE_CMD_AXI_OP_CFG) command size %d\n",
+				module->name, cmd_size);
+			return -1;
+		}
+		size1_y = get_size(cmd->op1_y_cfg_part2);
+		size1_cbcr = get_size(cmd->op1_cbcr_cfg_part2);
+		size2_y = get_size(cmd->op2_y_cfg_part2);
+		size2_cbcr = get_size(cmd->op2_cbcr_cfg_part2);
+		for (i = 0; i < 8; i++) {
+			addr1_y = (void **)(&cmd->op1_buf1_addr[2*i]);
+			addr1_cbcr = (void **)(&cmd->op1_buf1_addr[2*i+1]);
+			addr2_y = (void **)(&cmd->op2_buf1_addr[2*i]);
+			addr2_cbcr = (void **)(&cmd->op2_buf1_addr[2*i+1]);
+/*
+			printk("module %s: [%d] %p %p %p %p\n",
+				module->name, i,
+				*addr1_y, *addr1_cbcr, *addr2_y, *addr2_cbcr);
+*/
+			if ((*addr1_y && adsp_pmem_fixup(module, addr1_y, size1_y)) ||
+			    (*addr1_cbcr && adsp_pmem_fixup(module, addr1_cbcr, size1_cbcr)) ||
+			    (*addr2_y && adsp_pmem_fixup(module, addr2_y, size2_y)) ||
+			    (*addr2_cbcr && adsp_pmem_fixup(module, addr2_cbcr, size2_cbcr)))
+				return -1;
+		}
+	}
+	default:
+		if (cmd_id > 4) {
+			printk(KERN_ERR "adsp: module %s: invalid VFE TABLE command id %d\n",
+				module->name, cmd_id);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+int adsp_vfe_verify_cmd(struct msm_adsp_module *module,
+			unsigned int queue_id, void *cmd_data,
+			size_t cmd_size)
+{
+	switch (queue_id) {
+	case QDSP_vfeCommandQueue:
+		return verify_vfe_command(module, cmd_data, cmd_size);
+	case QDSP_vfeCommandScaleQueue:
+		return verify_vfe_command_scale(module, cmd_data, cmd_size);
+	case QDSP_vfeCommandTableQueue:
+		return verify_vfe_command_table(module, cmd_data, cmd_size);
+	default:
+		printk(KERN_ERR "adsp: module %s: unknown queue id %d\n",
+			module->name, queue_id);
+		return -1;
+	}
+}
diff --git a/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c
new file mode 100644
index 0000000..53aff77
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_video_verify_cmd.c
@@ -0,0 +1,163 @@
+/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
+ *
+ * Verificion code for aDSP VDEC packets from userspace.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/io.h>
+
+#define ADSP_DEBUG_MSGS 0
+#if ADSP_DEBUG_MSGS
+#define DLOG(fmt,args...) \
+	do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
+	     ##args); } \
+	while (0)
+#else
+#define DLOG(x...) do {} while (0)
+#endif
+
+
+#include <mach/qdsp5/qdsp5vdeccmdi.h>
+#include "adsp.h"
+
+static inline void *high_low_short_to_ptr(unsigned short high,
+					  unsigned short low)
+{
+	return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
+}
+
+static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
+					 unsigned short *low)
+{
+	*high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
+	*low = (unsigned short)((unsigned long)ptr & 0xffff);
+}
+
+static int pmem_fixup_high_low(unsigned short *high,
+				unsigned short *low,
+				unsigned short size_high,
+				unsigned short size_low,
+				struct msm_adsp_module *module,
+				unsigned long *addr, unsigned long *size)
+{
+	void *phys_addr;
+	unsigned long phys_size;
+	unsigned long kvaddr;
+
+	phys_addr = high_low_short_to_ptr(*high, *low);
+	phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
+	DLOG("virt %x %x\n", phys_addr, phys_size);
+	if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
+		DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
+			*high, *low, size_high, size_low, phys_addr, phys_size);
+		return -1;
+	}
+	ptr_to_high_low_short(phys_addr, high, low);
+	DLOG("phys %x %x\n", phys_addr, phys_size);
+	if (addr)
+		*addr = kvaddr;
+	if (size)
+		*size = phys_size;
+	return 0;
+}
+
+static int verify_vdec_pkt_cmd(struct msm_adsp_module *module,
+			       void *cmd_data, size_t cmd_size)
+{
+	unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
+	viddec_cmd_subframe_pkt *pkt;
+	unsigned long subframe_pkt_addr;
+	unsigned long subframe_pkt_size;
+	viddec_cmd_frame_header_packet *frame_header_pkt;
+	int i, num_addr, skip;
+	unsigned short *frame_buffer_high, *frame_buffer_low;
+	unsigned long frame_buffer_size;
+	unsigned short frame_buffer_size_high, frame_buffer_size_low;
+
+	DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
+	if (cmd_id != VIDDEC_CMD_SUBFRAME_PKT) {
+		printk(KERN_INFO "adsp_video: unknown video packet %u\n",
+			cmd_id);
+		return 0;
+	}
+	if (cmd_size < sizeof(viddec_cmd_subframe_pkt))
+		return -1;
+
+	pkt = (viddec_cmd_subframe_pkt *)cmd_data;
+
+	if (pmem_fixup_high_low(&(pkt->subframe_packet_high),
+				&(pkt->subframe_packet_low),
+				pkt->subframe_packet_size_high,
+				pkt->subframe_packet_size_low,
+				module,
+				&subframe_pkt_addr,
+				&subframe_pkt_size))
+		return -1;
+
+	/* deref those ptrs and check if they are a frame header packet */
+	frame_header_pkt = (viddec_cmd_frame_header_packet *)subframe_pkt_addr;
+
+	switch (frame_header_pkt->packet_id) {
+	case 0xB201: /* h.264 */
+		num_addr = skip = 8;
+		break;
+	case 0x4D01: /* mpeg-4 and h.263 */
+		num_addr = 3;
+		skip = 0;
+		break;
+	default:
+		return 0;
+	}
+
+	frame_buffer_high = &frame_header_pkt->frame_buffer_0_high;
+	frame_buffer_low = &frame_header_pkt->frame_buffer_0_low;
+	frame_buffer_size = (frame_header_pkt->x_dimension *
+			     frame_header_pkt->y_dimension * 3) / 2;
+	ptr_to_high_low_short((void *)frame_buffer_size,
+			      &frame_buffer_size_high,
+			      &frame_buffer_size_low);
+	for (i = 0; i < num_addr; i++) {
+		if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
+					frame_buffer_size_high,
+					frame_buffer_size_low,
+					module,
+					NULL, NULL))
+			return -1;
+		frame_buffer_high += 2;
+		frame_buffer_low += 2;
+	}
+	/* Patch the output buffer. */
+	frame_buffer_high += 2*skip;
+	frame_buffer_low += 2*skip;
+	if (pmem_fixup_high_low(frame_buffer_high, frame_buffer_low,
+				frame_buffer_size_high,
+				frame_buffer_size_low, module, NULL, NULL))
+		return -1;
+	return 0;
+}
+
+int adsp_video_verify_cmd(struct msm_adsp_module *module,
+			 unsigned int queue_id, void *cmd_data,
+			 size_t cmd_size)
+{
+	switch (queue_id) {
+	case QDSP_mpuVDecPktQueue:
+		DLOG("\n");
+		return verify_vdec_pkt_cmd(module, cmd_data, cmd_size);
+	default:
+		printk(KERN_INFO "unknown video queue %u\n", queue_id);
+		return 0;
+	}
+}
+
diff --git a/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c b/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
new file mode 100644
index 0000000..ee37449
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/adsp_videoenc_verify_cmd.c
@@ -0,0 +1,235 @@
+/* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
+ *
+ * Verificion code for aDSP VENC packets from userspace.
+ *
+ * Copyright (c) 2008 QUALCOMM Incorporated
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/io.h>
+
+#define ADSP_DEBUG_MSGS 0
+#if ADSP_DEBUG_MSGS
+#define DLOG(fmt,args...) \
+	do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
+	     ##args); } \
+	while (0)
+#else
+#define DLOG(x...) do {} while (0)
+#endif
+
+#include <mach/qdsp5/qdsp5venccmdi.h>
+#include "adsp.h"
+
+
+static unsigned short x_dimension, y_dimension;
+
+static inline void *high_low_short_to_ptr(unsigned short high,
+					  unsigned short low)
+{
+	return (void *)((((unsigned long)high) << 16) | ((unsigned long)low));
+}
+
+static inline void ptr_to_high_low_short(void *ptr, unsigned short *high,
+					 unsigned short *low)
+{
+	*high = (unsigned short)((((unsigned long)ptr) >> 16) & 0xffff);
+	*low = (unsigned short)((unsigned long)ptr & 0xffff);
+}
+
+static int pmem_fixup_high_low(unsigned short *high,
+				unsigned short *low,
+				unsigned short size_high,
+				unsigned short size_low,
+				struct msm_adsp_module *module,
+				unsigned long *addr, unsigned long *size)
+{
+	void *phys_addr;
+	unsigned long phys_size;
+	unsigned long kvaddr;
+
+	phys_addr = high_low_short_to_ptr(*high, *low);
+	phys_size = (unsigned long)high_low_short_to_ptr(size_high, size_low);
+	DLOG("virt %x %x\n", phys_addr, phys_size);
+	if (adsp_pmem_fixup_kvaddr(module, &phys_addr, &kvaddr, phys_size)) {
+		DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
+			*high, *low, size_high, size_low, phys_addr, phys_size);
+		return -1;
+	}
+	ptr_to_high_low_short(phys_addr, high, low);
+	DLOG("phys %x %x\n", phys_addr, phys_size);
+	if (addr)
+		*addr = kvaddr;
+	if (size)
+		*size = phys_size;
+	return 0;
+}
+
+static int verify_venc_cmd(struct msm_adsp_module *module,
+			       void *cmd_data, size_t cmd_size)
+{
+	unsigned short cmd_id = ((unsigned short *)cmd_data)[0];
+	unsigned long frame_buf_size, luma_buf_size, chroma_buf_size;
+	unsigned short frame_buf_size_high, frame_buf_size_low;
+	unsigned short luma_buf_size_high, luma_buf_size_low;
+	unsigned short chroma_buf_size_high, chroma_buf_size_low;
+	videnc_cmd_cfg *config_cmd;
+	videnc_cmd_frame_start *frame_cmd;
+	videnc_cmd_dis *dis_cmd;
+
+	DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size, cmd_id, cmd_data);
+	switch (cmd_id) {
+	case VIDENC_CMD_ACTIVE:
+		if (cmd_size < sizeof(videnc_cmd_active))
+			return -1;
+		break;
+	case VIDENC_CMD_IDLE:
+		if (cmd_size < sizeof(videnc_cmd_idle))
+			return -1;
+		x_dimension = y_dimension = 0;
+		break;
+	case VIDENC_CMD_STATUS_QUERY:
+		if (cmd_size < sizeof(videnc_cmd_status_query))
+			return -1;
+		break;
+	case VIDENC_CMD_RC_CFG:
+		if (cmd_size < sizeof(videnc_cmd_rc_cfg))
+			return -1;
+		break;
+	case VIDENC_CMD_INTRA_REFRESH:
+		if (cmd_size < sizeof(videnc_cmd_intra_refresh))
+			return -1;
+		break;
+	case VIDENC_CMD_DIGITAL_ZOOM:
+		if (cmd_size < sizeof(videnc_cmd_digital_zoom))
+			return -1;
+		break;
+	case VIDENC_CMD_DIS_CFG:
+		if (cmd_size < sizeof(videnc_cmd_dis_cfg))
+			return -1;
+		break;
+	case VIDENC_CMD_CFG:
+		if (cmd_size < sizeof(videnc_cmd_cfg))
+			return -1;
+		config_cmd = (videnc_cmd_cfg *)cmd_data;
+		x_dimension = ((config_cmd->venc_frame_dim) & 0xFF00)>>8;
+		x_dimension = x_dimension*16;
+		y_dimension = (config_cmd->venc_frame_dim) & 0xFF;
+		y_dimension = y_dimension * 16;
+		break;
+	case VIDENC_CMD_FRAME_START:
+		if (cmd_size < sizeof(videnc_cmd_frame_start))
+			return -1;
+		frame_cmd = (videnc_cmd_frame_start *)cmd_data;
+		luma_buf_size = x_dimension * y_dimension;
+		chroma_buf_size = luma_buf_size>>1;
+		frame_buf_size = luma_buf_size + chroma_buf_size;
+		ptr_to_high_low_short((void *)luma_buf_size,
+			      &luma_buf_size_high,
+			      &luma_buf_size_low);
+		ptr_to_high_low_short((void *)chroma_buf_size,
+			      &chroma_buf_size_high,
+			      &chroma_buf_size_low);
+		ptr_to_high_low_short((void *)frame_buf_size,
+			      &frame_buf_size_high,
+			      &frame_buf_size_low);
+		/* Address of raw Y data. */
+		if (pmem_fixup_high_low(&frame_cmd->input_luma_addr_high,
+					&frame_cmd->input_luma_addr_low,
+					luma_buf_size_high,
+					luma_buf_size_low,
+					module,
+					NULL, NULL))
+			return -1;
+		/* Address of raw CbCr data */
+		if (pmem_fixup_high_low(&frame_cmd->input_chroma_addr_high,
+					&frame_cmd->input_chroma_addr_low,
+					chroma_buf_size_high,
+					chroma_buf_size_low,
+					module,
+					NULL, NULL))
+			return -1;
+		/* Reference VOP */
+		if (pmem_fixup_high_low(&frame_cmd->ref_vop_buf_ptr_high,
+					&frame_cmd->ref_vop_buf_ptr_low,
+					frame_buf_size_high,
+					frame_buf_size_low,
+					module,
+					NULL, NULL))
+			return -1;
+		/* Encoded Packet Address */
+		if (pmem_fixup_high_low(&frame_cmd->enc_pkt_buf_ptr_high,
+					&frame_cmd->enc_pkt_buf_ptr_low,
+					frame_cmd->enc_pkt_buf_size_high,
+					frame_cmd->enc_pkt_buf_size_low,
+					module,
+					NULL, NULL))
+			return -1;
+		/* Unfiltered VOP Buffer Address */
+		if (pmem_fixup_high_low(
+				&frame_cmd->unfilt_recon_vop_buf_ptr_high,
+				&frame_cmd->unfilt_recon_vop_buf_ptr_low,
+				frame_buf_size_high,
+				frame_buf_size_low,
+				module,
+				NULL, NULL))
+			return -1;
+		/* Filtered VOP Buffer Address */
+		if (pmem_fixup_high_low(&frame_cmd->filt_recon_vop_buf_ptr_high,
+					&frame_cmd->filt_recon_vop_buf_ptr_low,
+					frame_buf_size_high,
+					frame_buf_size_low,
+					module,
+					NULL, NULL))
+			return -1;
+		break;
+	case VIDENC_CMD_DIS:
+		if (cmd_size < sizeof(videnc_cmd_dis))
+			return -1;
+		dis_cmd = (videnc_cmd_dis *)cmd_data;
+		luma_buf_size = x_dimension * y_dimension;
+		ptr_to_high_low_short((void *)luma_buf_size,
+			      &luma_buf_size_high,
+			      &luma_buf_size_low);
+		/* Prev VFE Luma Output Address */
+		if (pmem_fixup_high_low(&dis_cmd->vfe_out_prev_luma_addr_high,
+					&dis_cmd->vfe_out_prev_luma_addr_low,
+					luma_buf_size_high,
+					luma_buf_size_low,
+					module,
+					NULL, NULL))
+			return -1;
+		break;
+	default:
+		printk(KERN_INFO "adsp_video:unknown encoder video command %u\n",
+			cmd_id);
+		return 0;
+	}
+
+	return 0;
+}
+
+
+int adsp_videoenc_verify_cmd(struct msm_adsp_module *module,
+			 unsigned int queue_id, void *cmd_data,
+			 size_t cmd_size)
+{
+	switch (queue_id) {
+	case QDSP_mpuVEncCmdQueue:
+		DLOG("\n");
+		return verify_venc_cmd(module, cmd_data, cmd_size);
+	default:
+		printk(KERN_INFO "unknown video queue %u\n", queue_id);
+		return 0;
+	}
+}
+
diff --git a/drivers/staging/dream/qdsp5/audio_aac.c b/drivers/staging/dream/qdsp5/audio_aac.c
new file mode 100644
index 0000000..ad2390f
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audio_aac.c
@@ -0,0 +1,1052 @@
+/* arch/arm/mach-msm/qdsp5/audio_aac.c
+ *
+ * aac audio decoder device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 2008-2009 QUALCOMM USA, INC.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/delay.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include "audmgr.h"
+
+#include <mach/msm_adsp.h>
+#include <mach/msm_audio_aac.h>
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audplaycmdi.h>
+#include <mach/qdsp5/qdsp5audplaymsg.h>
+
+/* for queue ids - should be relative to module number*/
+#include "adsp.h"
+
+#ifdef DEBUG
+#define dprintk(format, arg...) \
+printk(KERN_DEBUG format, ## arg)
+#else
+#define dprintk(format, arg...) do {} while (0)
+#endif
+
+#define BUFSZ 32768
+#define DMASZ (BUFSZ * 2)
+
+#define AUDPLAY_INVALID_READ_PTR_OFFSET	0xFFFF
+#define AUDDEC_DEC_AAC 5
+
+#define PCM_BUFSZ_MIN 9600	/* Hold one stereo AAC frame */
+#define PCM_BUF_MAX_COUNT 5	/* DSP only accepts 5 buffers at most
+				   but support 2 buffers currently */
+#define ROUTING_MODE_FTRT 1
+#define ROUTING_MODE_RT 2
+/* Decoder status received from AUDPPTASK */
+#define  AUDPP_DEC_STATUS_SLEEP	0
+#define	 AUDPP_DEC_STATUS_INIT  1
+#define  AUDPP_DEC_STATUS_CFG   2
+#define  AUDPP_DEC_STATUS_PLAY  3
+
+struct buffer {
+	void *data;
+	unsigned size;
+	unsigned used;		/* Input usage actual DSP produced PCM size  */
+	unsigned addr;
+};
+
+struct audio {
+	struct buffer out[2];
+
+	spinlock_t dsp_lock;
+
+	uint8_t out_head;
+	uint8_t out_tail;
+	uint8_t out_needed;	/* number of buffers the dsp is waiting for */
+
+	atomic_t out_bytes;
+
+	struct mutex lock;
+	struct mutex write_lock;
+	wait_queue_head_t write_wait;
+
+	/* Host PCM section */
+	struct buffer in[PCM_BUF_MAX_COUNT];
+	struct mutex read_lock;
+	wait_queue_head_t read_wait;	/* Wait queue for read */
+	char *read_data;	/* pointer to reader buffer */
+	dma_addr_t read_phys;	/* physical address of reader buffer */
+	uint8_t read_next;	/* index to input buffers to be read next */
+	uint8_t fill_next;	/* index to buffer that DSP should be filling */
+	uint8_t pcm_buf_count;	/* number of pcm buffer allocated */
+	/* ---- End of Host PCM section */
+
+	struct msm_adsp_module *audplay;
+
+	/* configuration to use on next enable */
+	uint32_t out_sample_rate;
+	uint32_t out_channel_mode;
+	struct msm_audio_aac_config aac_config;
+	struct audmgr audmgr;
+
+	/* data allocated for various buffers */
+	char *data;
+	dma_addr_t phys;
+
+	int rflush; /* Read  flush */
+	int wflush; /* Write flush */
+	int opened;
+	int enabled;
+	int running;
+	int stopped;	/* set when stopped, cleared on flush */
+	int pcm_feedback;
+	int buf_refresh;
+
+	int reserved; /* A byte is being reserved */
+	char rsv_byte; /* Handle odd length user data */
+
+	unsigned volume;
+
+	uint16_t dec_id;
+	uint32_t read_ptr_offset;
+};
+
+static int auddec_dsp_config(struct audio *audio, int enable);
+static void audpp_cmd_cfg_adec_params(struct audio *audio);
+static void audpp_cmd_cfg_routing_mode(struct audio *audio);
+static void audplay_send_data(struct audio *audio, unsigned needed);
+static void audplay_config_hostpcm(struct audio *audio);
+static void audplay_buffer_refresh(struct audio *audio);
+static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+
+/* must be called with audio->lock held */
+static int audio_enable(struct audio *audio)
+{
+	struct audmgr_config cfg;
+	int rc;
+
+	dprintk("audio_enable()\n");
+
+	if (audio->enabled)
+		return 0;
+
+	audio->out_tail = 0;
+	audio->out_needed = 0;
+
+	cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
+	cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
+	cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
+	cfg.codec = RPC_AUD_DEF_CODEC_AAC;
+	cfg.snd_method = RPC_SND_METHOD_MIDI;
+
+	rc = audmgr_enable(&audio->audmgr, &cfg);
+	if (rc < 0)
+		return rc;
+
+	if (msm_adsp_enable(audio->audplay)) {
+		pr_err("audio: msm_adsp_enable(audplay) failed\n");
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+
+	if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
+		pr_err("audio: audpp_enable() failed\n");
+    msm_adsp_disable(audio->audplay);
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+	audio->enabled = 1;
+	return 0;
+}
+
+/* must be called with audio->lock held */
+static int audio_disable(struct audio *audio)
+{
+	dprintk("audio_disable()\n");
+	if (audio->enabled) {
+		audio->enabled = 0;
+		auddec_dsp_config(audio, 0);
+		wake_up(&audio->write_wait);
+		wake_up(&audio->read_wait);
+		msm_adsp_disable(audio->audplay);
+		audpp_disable(audio->dec_id, audio);
+		audmgr_disable(&audio->audmgr);
+		audio->out_needed = 0;
+	}
+	return 0;
+}
+
+/* ------------------- dsp --------------------- */
+static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
+{
+	uint8_t index;
+	unsigned long flags;
+
+	if (audio->rflush)
+		return;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	for (index = 0; index < payload[1]; index++) {
+		if (audio->in[audio->fill_next].addr ==
+		    payload[2 + index * 2]) {
+			dprintk("audio_update_pcm_buf_entry: in[%d] ready\n",
+				audio->fill_next);
+			audio->in[audio->fill_next].used =
+				payload[3 + index * 2];
+			if ((++audio->fill_next) == audio->pcm_buf_count)
+				audio->fill_next = 0;
+
+		} else {
+			pr_err
+			    ("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
+			     , audio->in[audio->fill_next].addr,
+			     payload[1 + index * 2]);
+			break;
+		}
+	}
+	if (audio->in[audio->fill_next].used == 0) {
+		audplay_buffer_refresh(audio);
+	} else {
+		dprintk("audio_update_pcm_buf_entry: read cannot keep up\n");
+		audio->buf_refresh = 1;
+	}
+	wake_up(&audio->read_wait);
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+
+}
+
+static void audplay_dsp_event(void *data, unsigned id, size_t len,
+			      void (*getevent) (void *ptr, size_t len))
+{
+	struct audio *audio = data;
+	uint32_t msg[28];
+	getevent(msg, sizeof(msg));
+
+	dprintk("audplay_dsp_event: msg_id=%x\n", id);
+
+	switch (id) {
+	case AUDPLAY_MSG_DEC_NEEDS_DATA:
+		audplay_send_data(audio, 1);
+		break;
+
+	case AUDPLAY_MSG_BUFFER_UPDATE:
+		audio_update_pcm_buf_entry(audio, msg);
+		break;
+
+	default:
+		pr_err("unexpected message from decoder \n");
+	}
+}
+
+static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
+{
+	struct audio *audio = private;
+
+	switch (id) {
+	case AUDPP_MSG_STATUS_MSG:{
+			unsigned status = msg[1];
+
+			switch (status) {
+			case AUDPP_DEC_STATUS_SLEEP:
+				dprintk("decoder status: sleep \n");
+				break;
+
+			case AUDPP_DEC_STATUS_INIT:
+				dprintk("decoder status: init \n");
+				audpp_cmd_cfg_routing_mode(audio);
+				break;
+
+			case AUDPP_DEC_STATUS_CFG:
+				dprintk("decoder status: cfg \n");
+				break;
+			case AUDPP_DEC_STATUS_PLAY:
+				dprintk("decoder status: play \n");
+				if (audio->pcm_feedback) {
+					audplay_config_hostpcm(audio);
+					audplay_buffer_refresh(audio);
+				}
+				break;
+			default:
+				pr_err("unknown decoder status \n");
+			}
+			break;
+		}
+	case AUDPP_MSG_CFG_MSG:
+		if (msg[0] == AUDPP_MSG_ENA_ENA) {
+			dprintk("audio_dsp_event: CFG_MSG ENABLE\n");
+			auddec_dsp_config(audio, 1);
+			audio->out_needed = 0;
+			audio->running = 1;
+			audpp_set_volume_and_pan(audio->dec_id, audio->volume,
+						 0);
+			audpp_avsync(audio->dec_id, 22050);
+		} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
+			dprintk("audio_dsp_event: CFG_MSG DISABLE\n");
+			audpp_avsync(audio->dec_id, 0);
+			audio->running = 0;
+		} else {
+			pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
+		}
+		break;
+	case AUDPP_MSG_ROUTING_ACK:
+		dprintk("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
+		audpp_cmd_cfg_adec_params(audio);
+		break;
+
+	case AUDPP_MSG_FLUSH_ACK:
+		dprintk("%s: FLUSH_ACK\n", __func__);
+		audio->wflush = 0;
+		audio->rflush = 0;
+		if (audio->pcm_feedback)
+			audplay_buffer_refresh(audio);
+		break;
+
+	default:
+		pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
+	}
+
+}
+
+struct msm_adsp_ops audplay_adsp_ops_aac = {
+	.event = audplay_dsp_event,
+};
+
+#define audplay_send_queue0(audio, cmd, len) \
+	msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
+		       cmd, len)
+
+static int auddec_dsp_config(struct audio *audio, int enable)
+{
+	audpp_cmd_cfg_dec_type cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
+	if (enable)
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
+		    AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AAC;
+	else
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
+
+	return audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_adec_params(struct audio *audio)
+{
+	audpp_cmd_cfg_adec_params_aac cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
+	cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN;
+	cmd.common.dec_id = audio->dec_id;
+	cmd.common.input_sampling_frequency = audio->out_sample_rate;
+	cmd.format = audio->aac_config.format;
+	cmd.audio_object = audio->aac_config.audio_object;
+	cmd.ep_config = audio->aac_config.ep_config;
+	cmd.aac_section_data_resilience_flag =
+		audio->aac_config.aac_section_data_resilience_flag;
+	cmd.aac_scalefactor_data_resilience_flag =
+		audio->aac_config.aac_scalefactor_data_resilience_flag;
+	cmd.aac_spectral_data_resilience_flag =
+		audio->aac_config.aac_spectral_data_resilience_flag;
+	cmd.sbr_on_flag = audio->aac_config.sbr_on_flag;
+	cmd.sbr_ps_on_flag = audio->aac_config.sbr_ps_on_flag;
+	cmd.channel_configuration = audio->aac_config.channel_configuration;
+
+	audpp_send_queue2(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_routing_mode(struct audio *audio)
+{
+	struct audpp_cmd_routing_mode cmd;
+	dprintk("audpp_cmd_cfg_routing_mode()\n");
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
+	cmd.object_number = audio->dec_id;
+	if (audio->pcm_feedback)
+		cmd.routing_mode = ROUTING_MODE_FTRT;
+	else
+		cmd.routing_mode = ROUTING_MODE_RT;
+
+	audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static int audplay_dsp_send_data_avail(struct audio *audio,
+				       unsigned idx, unsigned len)
+{
+	audplay_cmd_bitstream_data_avail cmd;
+
+	cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
+	cmd.decoder_id = audio->dec_id;
+	cmd.buf_ptr = audio->out[idx].addr;
+	cmd.buf_size = len / 2;
+	cmd.partition_number = 0;
+	return audplay_send_queue0(audio, &cmd, sizeof(cmd));
+}
+
+static void audplay_buffer_refresh(struct audio *audio)
+{
+	struct audplay_cmd_buffer_refresh refresh_cmd;
+
+	refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
+	refresh_cmd.num_buffers = 1;
+	refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
+	refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
+		(audio->in[audio->fill_next].size % 1024); /* AAC frame size */
+	refresh_cmd.buf_read_count = 0;
+	dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
+		refresh_cmd.buf0_address, refresh_cmd.buf0_length);
+	(void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
+}
+
+static void audplay_config_hostpcm(struct audio *audio)
+{
+	struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
+
+	dprintk("audplay_config_hostpcm()\n");
+	cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
+	cfg_cmd.max_buffers = audio->pcm_buf_count;
+	cfg_cmd.byte_swap = 0;
+	cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
+	cfg_cmd.feedback_frequency = 1;
+	cfg_cmd.partition_number = 0;
+	(void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
+
+}
+
+static void audplay_send_data(struct audio *audio, unsigned needed)
+{
+	struct buffer *frame;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	if (!audio->running)
+		goto done;
+
+	if (needed && !audio->wflush) {
+		/* We were called from the callback because the DSP
+		 * requested more data.  Note that the DSP does want
+		 * more data, and if a buffer was in-flight, mark it
+		 * as available (since the DSP must now be done with
+		 * it).
+		 */
+		audio->out_needed = 1;
+		frame = audio->out + audio->out_tail;
+		if (frame->used == 0xffffffff) {
+			dprintk("frame %d free\n", audio->out_tail);
+			frame->used = 0;
+			audio->out_tail ^= 1;
+			wake_up(&audio->write_wait);
+		}
+	}
+
+	if (audio->out_needed) {
+		/* If the DSP currently wants data and we have a
+		 * buffer available, we will send it and reset
+		 * the needed flag.  We'll mark the buffer as in-flight
+		 * so that it won't be recycled until the next buffer
+		 * is requested
+		 */
+
+		frame = audio->out + audio->out_tail;
+		if (frame->used) {
+			BUG_ON(frame->used == 0xffffffff);
+/*                      printk("frame %d busy\n", audio->out_tail); */
+			audplay_dsp_send_data_avail(audio, audio->out_tail,
+						    frame->used);
+			frame->used = 0xffffffff;
+			audio->out_needed = 0;
+		}
+	}
+ done:
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+}
+
+/* ------------------- device --------------------- */
+
+static void audio_flush(struct audio *audio)
+{
+	audio->out[0].used = 0;
+	audio->out[1].used = 0;
+	audio->out_head = 0;
+	audio->out_tail = 0;
+	audio->reserved = 0;
+	audio->out_needed = 0;
+	atomic_set(&audio->out_bytes, 0);
+}
+
+static void audio_flush_pcm_buf(struct audio *audio)
+{
+	uint8_t index;
+
+	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
+		audio->in[index].used = 0;
+	audio->buf_refresh = 0;
+	audio->read_next = 0;
+	audio->fill_next = 0;
+}
+
+static int audaac_validate_usr_config(struct msm_audio_aac_config *config)
+{
+	int ret_val = -1;
+
+	if (config->format != AUDIO_AAC_FORMAT_ADTS &&
+		config->format != AUDIO_AAC_FORMAT_RAW &&
+		config->format != AUDIO_AAC_FORMAT_PSUEDO_RAW &&
+		config->format != AUDIO_AAC_FORMAT_LOAS)
+		goto done;
+
+	if (config->audio_object != AUDIO_AAC_OBJECT_LC &&
+		config->audio_object != AUDIO_AAC_OBJECT_LTP &&
+		config->audio_object != AUDIO_AAC_OBJECT_ERLC)
+		goto done;
+
+	if (config->audio_object == AUDIO_AAC_OBJECT_ERLC) {
+		if (config->ep_config > 3)
+			goto done;
+		if (config->aac_scalefactor_data_resilience_flag !=
+			AUDIO_AAC_SCA_DATA_RES_OFF &&
+			config->aac_scalefactor_data_resilience_flag !=
+			AUDIO_AAC_SCA_DATA_RES_ON)
+			goto done;
+		if (config->aac_section_data_resilience_flag !=
+			AUDIO_AAC_SEC_DATA_RES_OFF &&
+			config->aac_section_data_resilience_flag !=
+			AUDIO_AAC_SEC_DATA_RES_ON)
+			goto done;
+		if (config->aac_spectral_data_resilience_flag !=
+			AUDIO_AAC_SPEC_DATA_RES_OFF &&
+			config->aac_spectral_data_resilience_flag !=
+			AUDIO_AAC_SPEC_DATA_RES_ON)
+			goto done;
+	} else {
+		config->aac_section_data_resilience_flag =
+			AUDIO_AAC_SEC_DATA_RES_OFF;
+		config->aac_scalefactor_data_resilience_flag =
+			AUDIO_AAC_SCA_DATA_RES_OFF;
+		config->aac_spectral_data_resilience_flag =
+			AUDIO_AAC_SPEC_DATA_RES_OFF;
+	}
+
+	if (config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_OFF &&
+		config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_ON)
+		goto done;
+
+	if (config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_OFF &&
+		config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_ON)
+		goto done;
+
+	if (config->dual_mono_mode > AUDIO_AAC_DUAL_MONO_PL_SR)
+		goto done;
+
+	if (config->channel_configuration > 2)
+		goto done;
+
+	ret_val = 0;
+ done:
+	return ret_val;
+}
+
+static void audio_ioport_reset(struct audio *audio)
+{
+	/* Make sure read/write thread are free from
+	 * sleep and knowing that system is not able
+	 * to process io request at the moment
+	 */
+	wake_up(&audio->write_wait);
+	mutex_lock(&audio->write_lock);
+	audio_flush(audio);
+	mutex_unlock(&audio->write_lock);
+	wake_up(&audio->read_wait);
+	mutex_lock(&audio->read_lock);
+	audio_flush_pcm_buf(audio);
+	mutex_unlock(&audio->read_lock);
+}
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct audio *audio = file->private_data;
+	int rc = 0;
+
+	dprintk("audio_ioctl() cmd = %d\n", cmd);
+
+	if (cmd == AUDIO_GET_STATS) {
+		struct msm_audio_stats stats;
+		stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
+		stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
+		if (copy_to_user((void *)arg, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == AUDIO_SET_VOLUME) {
+		unsigned long flags;
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		audio->volume = arg;
+		if (audio->running)
+			audpp_set_volume_and_pan(audio->dec_id, arg, 0);
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+		return 0;
+	}
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_START:
+		rc = audio_enable(audio);
+		break;
+	case AUDIO_STOP:
+		rc = audio_disable(audio);
+		audio->stopped = 1;
+		audio_ioport_reset(audio);
+		audio->stopped = 0;
+		break;
+	case AUDIO_FLUSH:
+		dprintk("%s: AUDIO_FLUSH\n", __func__);
+		audio->rflush = 1;
+		audio->wflush = 1;
+		audio_ioport_reset(audio);
+		if (audio->running)
+			audpp_flush(audio->dec_id);
+		else {
+			audio->rflush = 0;
+			audio->wflush = 0;
+		}
+		break;
+
+	case AUDIO_SET_CONFIG:{
+			struct msm_audio_config config;
+
+			if (copy_from_user
+			    (&config, (void *)arg, sizeof(config))) {
+				rc = -EFAULT;
+				break;
+			}
+
+			if (config.channel_count == 1) {
+				config.channel_count =
+				    AUDPP_CMD_PCM_INTF_MONO_V;
+			} else if (config.channel_count == 2) {
+				config.channel_count =
+				    AUDPP_CMD_PCM_INTF_STEREO_V;
+			} else {
+				rc = -EINVAL;
+				break;
+			}
+
+			audio->out_sample_rate = config.sample_rate;
+			audio->out_channel_mode = config.channel_count;
+			rc = 0;
+			break;
+		}
+	case AUDIO_GET_CONFIG:{
+			struct msm_audio_config config;
+			config.buffer_size = BUFSZ;
+			config.buffer_count = 2;
+			config.sample_rate = audio->out_sample_rate;
+			if (audio->out_channel_mode ==
+			    AUDPP_CMD_PCM_INTF_MONO_V) {
+				config.channel_count = 1;
+			} else {
+				config.channel_count = 2;
+			}
+			config.unused[0] = 0;
+			config.unused[1] = 0;
+			config.unused[2] = 0;
+			config.unused[3] = 0;
+			if (copy_to_user((void *)arg, &config,
+					 sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+
+			break;
+		}
+	case AUDIO_GET_AAC_CONFIG:{
+			if (copy_to_user((void *)arg, &audio->aac_config,
+				sizeof(audio->aac_config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+			break;
+		}
+	case AUDIO_SET_AAC_CONFIG:{
+			struct msm_audio_aac_config usr_config;
+
+			if (copy_from_user
+				(&usr_config, (void *)arg,
+					sizeof(usr_config))) {
+				rc = -EFAULT;
+				break;
+			}
+
+			if (audaac_validate_usr_config(&usr_config) == 0) {
+				audio->aac_config = usr_config;
+				rc = 0;
+			} else
+				rc = -EINVAL;
+
+			break;
+		}
+	case AUDIO_GET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+			config.pcm_feedback = 0;
+			config.buffer_count = PCM_BUF_MAX_COUNT;
+			config.buffer_size = PCM_BUFSZ_MIN;
+			if (copy_to_user((void *)arg, &config,
+					 sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+			break;
+		}
+	case AUDIO_SET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+			if (copy_from_user
+			    (&config, (void *)arg, sizeof(config))) {
+				rc = -EFAULT;
+				break;
+			}
+			if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
+			    (config.buffer_count == 1))
+				config.buffer_count = PCM_BUF_MAX_COUNT;
+
+			if (config.buffer_size < PCM_BUFSZ_MIN)
+				config.buffer_size = PCM_BUFSZ_MIN;
+
+			/* Check if pcm feedback is required */
+			if ((config.pcm_feedback) && (!audio->read_data)) {
+				dprintk("ioctl: allocate PCM buffer %d\n",
+					config.buffer_count *
+					config.buffer_size);
+				audio->read_data =
+				    dma_alloc_coherent(NULL,
+						       config.buffer_size *
+						       config.buffer_count,
+						       &audio->read_phys,
+						       GFP_KERNEL);
+				if (!audio->read_data) {
+					pr_err("audio_aac: buf alloc fail\n");
+					rc = -1;
+				} else {
+					uint8_t index;
+					uint32_t offset = 0;
+					audio->pcm_feedback = 1;
+					audio->buf_refresh = 0;
+					audio->pcm_buf_count =
+					    config.buffer_count;
+					audio->read_next = 0;
+					audio->fill_next = 0;
+
+					for (index = 0;
+					     index < config.buffer_count;
+					     index++) {
+						audio->in[index].data =
+						    audio->read_data + offset;
+						audio->in[index].addr =
+						    audio->read_phys + offset;
+						audio->in[index].size =
+						    config.buffer_size;
+						audio->in[index].used = 0;
+						offset += config.buffer_size;
+					}
+					rc = 0;
+				}
+			} else {
+				rc = 0;
+			}
+			break;
+		}
+	case AUDIO_PAUSE:
+		dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
+		rc = audpp_pause(audio->dec_id, (int) arg);
+		break;
+	default:
+		rc = -EINVAL;
+	}
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
+			  loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	int rc = 0;
+
+	if (!audio->pcm_feedback)
+		return 0; /* PCM feedback is not enabled. Nothing to read */
+
+	mutex_lock(&audio->read_lock);
+	dprintk("audio_read() %d \n", count);
+	while (count > 0) {
+		rc = wait_event_interruptible(audio->read_wait,
+					      (audio->in[audio->read_next].
+						used > 0) || (audio->stopped)
+						|| (audio->rflush));
+
+		if (rc < 0)
+			break;
+
+		if (audio->stopped || audio->rflush) {
+			rc = -EBUSY;
+			break;
+		}
+
+		if (count < audio->in[audio->read_next].used) {
+			/* Read must happen in frame boundary. Since driver
+			   does not know frame size, read count must be greater
+			   or equal to size of PCM samples */
+			dprintk("audio_read: no partial frame done reading\n");
+			break;
+		} else {
+			dprintk("audio_read: read from in[%d]\n",
+				audio->read_next);
+			if (copy_to_user
+			    (buf, audio->in[audio->read_next].data,
+			     audio->in[audio->read_next].used)) {
+				pr_err("audio_read: invalid addr %x \n",
+				       (unsigned int)buf);
+				rc = -EFAULT;
+				break;
+			}
+			count -= audio->in[audio->read_next].used;
+			buf += audio->in[audio->read_next].used;
+			audio->in[audio->read_next].used = 0;
+			if ((++audio->read_next) == audio->pcm_buf_count)
+				audio->read_next = 0;
+			if (audio->in[audio->read_next].used == 0)
+				break; /* No data ready at this moment
+					* Exit while loop to prevent
+					* output thread sleep too long
+					*/
+		}
+	}
+
+	/* don't feed output buffer to HW decoder during flushing
+	 * buffer refresh command will be sent once flush completes
+	 * send buf refresh command here can confuse HW decoder
+	 */
+	if (audio->buf_refresh && !audio->rflush) {
+		audio->buf_refresh = 0;
+		dprintk("audio_read: kick start pcm feedback again\n");
+		audplay_buffer_refresh(audio);
+	}
+
+	mutex_unlock(&audio->read_lock);
+
+	if (buf > start)
+		rc = buf - start;
+
+	dprintk("audio_read: read %d bytes\n", rc);
+	return rc;
+}
+
+static ssize_t audio_write(struct file *file, const char __user *buf,
+			   size_t count, loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	struct buffer *frame;
+	size_t xfer;
+	char *cpy_ptr;
+	int rc = 0;
+	unsigned dsize;
+
+	mutex_lock(&audio->write_lock);
+	while (count > 0) {
+		frame = audio->out + audio->out_head;
+		cpy_ptr = frame->data;
+		dsize = 0;
+		rc = wait_event_interruptible(audio->write_wait,
+					      (frame->used == 0)
+						|| (audio->stopped)
+						|| (audio->wflush));
+		if (rc < 0)
+			break;
+		if (audio->stopped || audio->wflush) {
+			rc = -EBUSY;
+			break;
+		}
+
+		if (audio->reserved) {
+			dprintk("%s: append reserved byte %x\n",
+				__func__, audio->rsv_byte);
+			*cpy_ptr = audio->rsv_byte;
+			xfer = (count > (frame->size - 1)) ?
+				frame->size - 1 : count;
+			cpy_ptr++;
+			dsize = 1;
+			audio->reserved = 0;
+		} else
+			xfer = (count > frame->size) ? frame->size : count;
+
+		if (copy_from_user(cpy_ptr, buf, xfer)) {
+			rc = -EFAULT;
+			break;
+		}
+
+		dsize += xfer;
+		if (dsize & 1) {
+			audio->rsv_byte = ((char *) frame->data)[dsize - 1];
+			dprintk("%s: odd length buf reserve last byte %x\n",
+				__func__, audio->rsv_byte);
+			audio->reserved = 1;
+			dsize--;
+		}
+		count -= xfer;
+		buf += xfer;
+
+		if (dsize > 0) {
+			audio->out_head ^= 1;
+			frame->used = dsize;
+			audplay_send_data(audio, 0);
+		}
+	}
+	mutex_unlock(&audio->write_lock);
+	if (buf > start)
+		return buf - start;
+	return rc;
+}
+
+static int audio_release(struct inode *inode, struct file *file)
+{
+	struct audio *audio = file->private_data;
+
+	dprintk("audio_release()\n");
+
+	mutex_lock(&audio->lock);
+	audio_disable(audio);
+	audio_flush(audio);
+	audio_flush_pcm_buf(audio);
+	msm_adsp_put(audio->audplay);
+	audio->audplay = NULL;
+	audio->opened = 0;
+	audio->reserved = 0;
+	dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
+	audio->data = NULL;
+	if (audio->read_data != NULL) {
+		dma_free_coherent(NULL,
+				  audio->in[0].size * audio->pcm_buf_count,
+				  audio->read_data, audio->read_phys);
+		audio->read_data = NULL;
+	}
+	audio->pcm_feedback = 0;
+	mutex_unlock(&audio->lock);
+	return 0;
+}
+
+static struct audio the_aac_audio;
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+	struct audio *audio = &the_aac_audio;
+	int rc;
+
+	mutex_lock(&audio->lock);
+
+	if (audio->opened) {
+		pr_err("audio: busy\n");
+		rc = -EBUSY;
+		goto done;
+	}
+
+	if (!audio->data) {
+		audio->data = dma_alloc_coherent(NULL, DMASZ,
+						 &audio->phys, GFP_KERNEL);
+		if (!audio->data) {
+			pr_err("audio: could not allocate DMA buffers\n");
+			rc = -ENOMEM;
+			goto done;
+		}
+	}
+
+	rc = audmgr_open(&audio->audmgr);
+	if (rc)
+		goto done;
+
+	rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
+			  &audplay_adsp_ops_aac, audio);
+	if (rc) {
+		pr_err("audio: failed to get audplay0 dsp module\n");
+		goto done;
+	}
+	audio->out_sample_rate = 44100;
+	audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
+	audio->aac_config.format = AUDIO_AAC_FORMAT_ADTS;
+	audio->aac_config.audio_object = AUDIO_AAC_OBJECT_LC;
+	audio->aac_config.ep_config = 0;
+	audio->aac_config.aac_section_data_resilience_flag =
+		AUDIO_AAC_SEC_DATA_RES_OFF;
+	audio->aac_config.aac_scalefactor_data_resilience_flag =
+		AUDIO_AAC_SCA_DATA_RES_OFF;
+	audio->aac_config.aac_spectral_data_resilience_flag =
+		AUDIO_AAC_SPEC_DATA_RES_OFF;
+	audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_ON;
+	audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_ON;
+	audio->aac_config.dual_mono_mode = AUDIO_AAC_DUAL_MONO_PL_SR;
+	audio->aac_config.channel_configuration = 2;
+	audio->dec_id = 0;
+
+	audio->out[0].data = audio->data + 0;
+	audio->out[0].addr = audio->phys + 0;
+	audio->out[0].size = BUFSZ;
+
+	audio->out[1].data = audio->data + BUFSZ;
+	audio->out[1].addr = audio->phys + BUFSZ;
+	audio->out[1].size = BUFSZ;
+
+	audio->volume = 0x2000;	/* Q13 1.0 */
+
+	audio_flush(audio);
+
+	file->private_data = audio;
+	audio->opened = 1;
+	rc = 0;
+done:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static struct file_operations audio_aac_fops = {
+	.owner = THIS_MODULE,
+	.open = audio_open,
+	.release = audio_release,
+	.read = audio_read,
+	.write = audio_write,
+	.unlocked_ioctl = audio_ioctl,
+};
+
+struct miscdevice audio_aac_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "msm_aac",
+	.fops = &audio_aac_fops,
+};
+
+static int __init audio_init(void)
+{
+	mutex_init(&the_aac_audio.lock);
+	mutex_init(&the_aac_audio.write_lock);
+	mutex_init(&the_aac_audio.read_lock);
+	spin_lock_init(&the_aac_audio.dsp_lock);
+	init_waitqueue_head(&the_aac_audio.write_wait);
+	init_waitqueue_head(&the_aac_audio.read_wait);
+	the_aac_audio.read_data = NULL;
+	return misc_register(&audio_aac_misc);
+}
+
+device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_amrnb.c b/drivers/staging/dream/qdsp5/audio_amrnb.c
new file mode 100644
index 0000000..cd818a5
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audio_amrnb.c
@@ -0,0 +1,873 @@
+/* linux/arch/arm/mach-msm/qdsp5/audio_amrnb.c
+ *
+ * amrnb audio decoder device
+ *
+ * Copyright (c) 2008 QUALCOMM USA, INC.
+ *
+ * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ *
+ * All source code in this file is licensed under the following license except
+ * where indicated.
+ *
+ * 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, you can find it at http://www.fsf.org
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/delay.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include <mach/msm_adsp.h>
+#include <linux/msm_audio.h>
+#include "audmgr.h"
+
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audplaycmdi.h>
+#include <mach/qdsp5/qdsp5audplaymsg.h>
+
+/* for queue ids - should be relative to module number*/
+#include "adsp.h"
+
+#define DEBUG
+#ifdef DEBUG
+#define dprintk(format, arg...) \
+printk(KERN_DEBUG format, ## arg)
+#else
+#define dprintk(format, arg...) do {} while (0)
+#endif
+
+#define BUFSZ 1024 /* Hold minimum 700ms voice data */
+#define DMASZ (BUFSZ * 2)
+
+#define AUDPLAY_INVALID_READ_PTR_OFFSET	0xFFFF
+#define AUDDEC_DEC_AMRNB 10
+
+#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
+#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */
+#define PCM_BUF_MAX_COUNT 5	/* DSP only accepts 5 buffers at most
+				   but support 2 buffers currently */
+#define ROUTING_MODE_FTRT 1
+#define ROUTING_MODE_RT 2
+/* Decoder status received from AUDPPTASK */
+#define  AUDPP_DEC_STATUS_SLEEP	0
+#define	 AUDPP_DEC_STATUS_INIT  1
+#define  AUDPP_DEC_STATUS_CFG   2
+#define  AUDPP_DEC_STATUS_PLAY  3
+
+struct buffer {
+	void *data;
+	unsigned size;
+	unsigned used;		/* Input usage actual DSP produced PCM size  */
+	unsigned addr;
+};
+
+struct audio {
+	struct buffer out[2];
+
+	spinlock_t dsp_lock;
+
+	uint8_t out_head;
+	uint8_t out_tail;
+	uint8_t out_needed;	/* number of buffers the dsp is waiting for */
+
+	atomic_t out_bytes;
+
+	struct mutex lock;
+	struct mutex write_lock;
+	wait_queue_head_t write_wait;
+
+	/* Host PCM section */
+	struct buffer in[PCM_BUF_MAX_COUNT];
+	struct mutex read_lock;
+	wait_queue_head_t read_wait;	/* Wait queue for read */
+	char *read_data;	/* pointer to reader buffer */
+	dma_addr_t read_phys;	/* physical address of reader buffer */
+	uint8_t read_next;	/* index to input buffers to be read next */
+	uint8_t fill_next;	/* index to buffer that DSP should be filling */
+	uint8_t pcm_buf_count;	/* number of pcm buffer allocated */
+	/* ---- End of Host PCM section */
+
+	struct msm_adsp_module *audplay;
+
+	struct audmgr audmgr;
+
+	/* data allocated for various buffers */
+	char *data;
+	dma_addr_t phys;
+
+	uint8_t opened:1;
+	uint8_t enabled:1;
+	uint8_t running:1;
+	uint8_t stopped:1;	/* set when stopped, cleared on flush */
+	uint8_t pcm_feedback:1;
+	uint8_t buf_refresh:1;
+
+	unsigned volume;
+
+	uint16_t dec_id;
+	uint32_t read_ptr_offset;
+};
+
+struct audpp_cmd_cfg_adec_params_amrnb {
+   audpp_cmd_cfg_adec_params_common     common;
+   unsigned short                       stereo_cfg;
+} __attribute__((packed)) ;
+
+static int auddec_dsp_config(struct audio *audio, int enable);
+static void audpp_cmd_cfg_adec_params(struct audio *audio);
+static void audpp_cmd_cfg_routing_mode(struct audio *audio);
+static void audamrnb_send_data(struct audio *audio, unsigned needed);
+static void audamrnb_config_hostpcm(struct audio *audio);
+static void audamrnb_buffer_refresh(struct audio *audio);
+static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg);
+
+/* must be called with audio->lock held */
+static int audamrnb_enable(struct audio *audio)
+{
+	struct audmgr_config cfg;
+	int rc;
+
+	dprintk("audamrnb_enable()\n");
+
+	if (audio->enabled)
+		return 0;
+
+	audio->out_tail = 0;
+	audio->out_needed = 0;
+
+	cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
+	cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
+	cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
+	cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB;
+	cfg.snd_method = RPC_SND_METHOD_MIDI;
+
+	rc = audmgr_enable(&audio->audmgr, &cfg);
+	if (rc < 0)
+		return rc;
+
+	if (msm_adsp_enable(audio->audplay)) {
+		pr_err("audio: msm_adsp_enable(audplay) failed\n");
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+
+	if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) {
+		pr_err("audio: audpp_enable() failed\n");
+		msm_adsp_disable(audio->audplay);
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+	audio->enabled = 1;
+	return 0;
+}
+
+/* must be called with audio->lock held */
+static int audamrnb_disable(struct audio *audio)
+{
+	dprintk("audamrnb_disable()\n");
+	if (audio->enabled) {
+		audio->enabled = 0;
+		auddec_dsp_config(audio, 0);
+		wake_up(&audio->write_wait);
+		wake_up(&audio->read_wait);
+		msm_adsp_disable(audio->audplay);
+		audpp_disable(audio->dec_id, audio);
+		audmgr_disable(&audio->audmgr);
+		audio->out_needed = 0;
+	}
+	return 0;
+}
+
+/* ------------------- dsp --------------------- */
+static void audamrnb_update_pcm_buf_entry(struct audio *audio,
+		uint32_t *payload)
+{
+	uint8_t index;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	for (index = 0; index < payload[1]; index++) {
+		if (audio->in[audio->fill_next].addr ==
+		    payload[2 + index * 2]) {
+			dprintk("audamrnb_update_pcm_buf_entry: in[%d] ready\n",
+				audio->fill_next);
+			audio->in[audio->fill_next].used =
+			    payload[3 + index * 2];
+			if ((++audio->fill_next) == audio->pcm_buf_count)
+				audio->fill_next = 0;
+
+		} else {
+			pr_err
+			  ("audamrnb_update_pcm_buf_entry: expected=%x ret=%x\n"
+			   , audio->in[audio->fill_next].addr,
+			   payload[1 + index * 2]);
+			break;
+		}
+	}
+	if (audio->in[audio->fill_next].used == 0) {
+		audamrnb_buffer_refresh(audio);
+	} else {
+		dprintk("audamrnb_update_pcm_buf_entry: read cannot keep up\n");
+		audio->buf_refresh = 1;
+	}
+
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+	wake_up(&audio->read_wait);
+}
+
+static void audplay_dsp_event(void *data, unsigned id, size_t len,
+			      void (*getevent) (void *ptr, size_t len))
+{
+	struct audio *audio = data;
+	uint32_t msg[28];
+	getevent(msg, sizeof(msg));
+
+	dprintk("audplay_dsp_event: msg_id=%x\n", id);
+
+	switch (id) {
+	case AUDPLAY_MSG_DEC_NEEDS_DATA:
+		audamrnb_send_data(audio, 1);
+		break;
+
+	case AUDPLAY_MSG_BUFFER_UPDATE:
+		audamrnb_update_pcm_buf_entry(audio, msg);
+		break;
+
+	default:
+		pr_err("unexpected message from decoder \n");
+	}
+}
+
+static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg)
+{
+	struct audio *audio = private;
+
+	switch (id) {
+	case AUDPP_MSG_STATUS_MSG:{
+			unsigned status = msg[1];
+
+			switch (status) {
+			case AUDPP_DEC_STATUS_SLEEP:
+				dprintk("decoder status: sleep \n");
+				break;
+
+			case AUDPP_DEC_STATUS_INIT:
+				dprintk("decoder status: init \n");
+				audpp_cmd_cfg_routing_mode(audio);
+				break;
+
+			case AUDPP_DEC_STATUS_CFG:
+				dprintk("decoder status: cfg \n");
+				break;
+			case AUDPP_DEC_STATUS_PLAY:
+				dprintk("decoder status: play \n");
+				if (audio->pcm_feedback) {
+					audamrnb_config_hostpcm(audio);
+					audamrnb_buffer_refresh(audio);
+				}
+				break;
+			default:
+				pr_err("unknown decoder status \n");
+				break;
+			}
+			break;
+		}
+	case AUDPP_MSG_CFG_MSG:
+		if (msg[0] == AUDPP_MSG_ENA_ENA) {
+			dprintk("audamrnb_dsp_event: CFG_MSG ENABLE\n");
+			auddec_dsp_config(audio, 1);
+			audio->out_needed = 0;
+			audio->running = 1;
+			audpp_set_volume_and_pan(audio->dec_id, audio->volume,
+						 0);
+			audpp_avsync(audio->dec_id, 22050);
+		} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
+			dprintk("audamrnb_dsp_event: CFG_MSG DISABLE\n");
+			audpp_avsync(audio->dec_id, 0);
+			audio->running = 0;
+		} else {
+			pr_err("audamrnb_dsp_event: CFG_MSG %d?\n", msg[0]);
+		}
+		break;
+	case AUDPP_MSG_ROUTING_ACK:
+		dprintk("audamrnb_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
+		audpp_cmd_cfg_adec_params(audio);
+		break;
+
+	default:
+		pr_err("audamrnb_dsp_event: UNKNOWN (%d)\n", id);
+	}
+
+}
+
+struct msm_adsp_ops audplay_adsp_ops_amrnb = {
+	.event = audplay_dsp_event,
+};
+
+#define audplay_send_queue0(audio, cmd, len) \
+	msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
+		       cmd, len)
+
+static int auddec_dsp_config(struct audio *audio, int enable)
+{
+	audpp_cmd_cfg_dec_type cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
+	if (enable)
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
+		    AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB;
+	else
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
+
+	return audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_adec_params(struct audio *audio)
+{
+	struct audpp_cmd_cfg_adec_params_amrnb cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
+	cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
+	cmd.common.dec_id = audio->dec_id;
+	cmd.common.input_sampling_frequency = 8000;
+	cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
+
+	audpp_send_queue2(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_routing_mode(struct audio *audio)
+{
+	struct audpp_cmd_routing_mode cmd;
+	dprintk("audpp_cmd_cfg_routing_mode()\n");
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
+	cmd.object_number = audio->dec_id;
+	if (audio->pcm_feedback)
+		cmd.routing_mode = ROUTING_MODE_FTRT;
+	else
+		cmd.routing_mode = ROUTING_MODE_RT;
+
+	audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static int audplay_dsp_send_data_avail(struct audio *audio,
+				       unsigned idx, unsigned len)
+{
+	audplay_cmd_bitstream_data_avail cmd;
+
+	cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
+	cmd.decoder_id = audio->dec_id;
+	cmd.buf_ptr = audio->out[idx].addr;
+	cmd.buf_size = len / 2;
+	cmd.partition_number = 0;
+	return audplay_send_queue0(audio, &cmd, sizeof(cmd));
+}
+
+static void audamrnb_buffer_refresh(struct audio *audio)
+{
+	struct audplay_cmd_buffer_refresh refresh_cmd;
+
+	refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
+	refresh_cmd.num_buffers = 1;
+	refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
+	refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
+	  (audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ);
+	refresh_cmd.buf_read_count = 0;
+	dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
+		refresh_cmd.buf0_address, refresh_cmd.buf0_length);
+	(void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
+}
+
+static void audamrnb_config_hostpcm(struct audio *audio)
+{
+	struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
+
+	dprintk("audamrnb_config_hostpcm()\n");
+	cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
+	cfg_cmd.max_buffers = audio->pcm_buf_count;
+	cfg_cmd.byte_swap = 0;
+	cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
+	cfg_cmd.feedback_frequency = 1;
+	cfg_cmd.partition_number = 0;
+	(void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
+
+}
+
+static void audamrnb_send_data(struct audio *audio, unsigned needed)
+{
+	struct buffer *frame;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	if (!audio->running)
+		goto done;
+
+	if (needed) {
+		/* We were called from the callback because the DSP
+		 * requested more data.  Note that the DSP does want
+		 * more data, and if a buffer was in-flight, mark it
+		 * as available (since the DSP must now be done with
+		 * it).
+		 */
+		audio->out_needed = 1;
+		frame = audio->out + audio->out_tail;
+		if (frame->used == 0xffffffff) {
+			frame->used = 0;
+			audio->out_tail ^= 1;
+			wake_up(&audio->write_wait);
+		}
+	}
+
+	if (audio->out_needed) {
+		/* If the DSP currently wants data and we have a
+		 * buffer available, we will send it and reset
+		 * the needed flag.  We'll mark the buffer as in-flight
+		 * so that it won't be recycled until the next buffer
+		 * is requested
+		 */
+
+		frame = audio->out + audio->out_tail;
+		if (frame->used) {
+			BUG_ON(frame->used == 0xffffffff);
+/*                      printk("frame %d busy\n", audio->out_tail); */
+			audplay_dsp_send_data_avail(audio, audio->out_tail,
+						    frame->used);
+			frame->used = 0xffffffff;
+			audio->out_needed = 0;
+		}
+	}
+ done:
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+}
+
+/* ------------------- device --------------------- */
+
+static void audamrnb_flush(struct audio *audio)
+{
+	audio->out[0].used = 0;
+	audio->out[1].used = 0;
+	audio->out_head = 0;
+	audio->out_tail = 0;
+	audio->stopped = 0;
+	atomic_set(&audio->out_bytes, 0);
+}
+
+static void audamrnb_flush_pcm_buf(struct audio *audio)
+{
+	uint8_t index;
+
+	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
+		audio->in[index].used = 0;
+
+	audio->read_next = 0;
+	audio->fill_next = 0;
+}
+
+static long audamrnb_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg)
+{
+	struct audio *audio = file->private_data;
+	int rc = 0;
+
+	dprintk("audamrnb_ioctl() cmd = %d\n", cmd);
+
+	if (cmd == AUDIO_GET_STATS) {
+		struct msm_audio_stats stats;
+		stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
+		stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
+		if (copy_to_user((void *)arg, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == AUDIO_SET_VOLUME) {
+		unsigned long flags;
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		audio->volume = arg;
+		if (audio->running)
+			audpp_set_volume_and_pan(audio->dec_id, arg, 0);
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+    return 0;
+	}
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_START:
+		rc = audamrnb_enable(audio);
+		break;
+	case AUDIO_STOP:
+		rc = audamrnb_disable(audio);
+		audio->stopped = 1;
+		break;
+	case AUDIO_FLUSH:
+		if (audio->stopped) {
+			/* Make sure we're stopped and we wake any threads
+			 * that might be blocked holding the write_lock.
+			 * While audio->stopped write threads will always
+			 * exit immediately.
+			 */
+			wake_up(&audio->write_wait);
+			mutex_lock(&audio->write_lock);
+			audamrnb_flush(audio);
+			mutex_unlock(&audio->write_lock);
+			wake_up(&audio->read_wait);
+			mutex_lock(&audio->read_lock);
+			audamrnb_flush_pcm_buf(audio);
+			mutex_unlock(&audio->read_lock);
+			break;
+		}
+
+  case AUDIO_SET_CONFIG:{
+      dprintk("AUDIO_SET_CONFIG not applicable \n");
+			break;
+		}
+	case AUDIO_GET_CONFIG:{
+			struct msm_audio_config config;
+			config.buffer_size = BUFSZ;
+			config.buffer_count = 2;
+			config.sample_rate = 8000;
+			config.channel_count = 1;
+			config.unused[0] = 0;
+			config.unused[1] = 0;
+			config.unused[2] = 0;
+			config.unused[3] = 0;
+			if (copy_to_user((void *)arg, &config,
+					 sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+
+			break;
+		}
+	case AUDIO_GET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+			config.pcm_feedback = 0;
+			config.buffer_count = PCM_BUF_MAX_COUNT;
+			config.buffer_size = PCM_BUFSZ_MIN;
+			if (copy_to_user((void *)arg, &config,
+					 sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+			break;
+		}
+	case AUDIO_SET_PCM_CONFIG:{
+		struct msm_audio_pcm_config config;
+		if (copy_from_user
+		    (&config, (void *)arg, sizeof(config))) {
+			rc = -EFAULT;
+			break;
+		}
+		if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
+		    (config.buffer_count == 1))
+			config.buffer_count = PCM_BUF_MAX_COUNT;
+
+		if (config.buffer_size < PCM_BUFSZ_MIN)
+			config.buffer_size = PCM_BUFSZ_MIN;
+
+			/* Check if pcm feedback is required */
+		if ((config.pcm_feedback) && (!audio->read_data)) {
+			dprintk("audamrnb_ioctl: allocate PCM buf %d\n",
+					config.buffer_count *
+					config.buffer_size);
+			audio->read_data =
+				dma_alloc_coherent(NULL,
+						       config.buffer_size *
+						       config.buffer_count,
+						       &audio->read_phys,
+						       GFP_KERNEL);
+			if (!audio->read_data) {
+				pr_err("audamrnb_ioctl: no mem for pcm buf\n");
+				rc = -1;
+			} else {
+				uint8_t index;
+				uint32_t offset = 0;
+				audio->pcm_feedback = 1;
+				audio->buf_refresh = 0;
+				audio->pcm_buf_count =
+					config.buffer_count;
+				audio->read_next = 0;
+				audio->fill_next = 0;
+
+				for (index = 0;
+				index < config.buffer_count; index++) {
+					audio->in[index].data =
+						audio->read_data + offset;
+					audio->in[index].addr =
+					    audio->read_phys + offset;
+					audio->in[index].size =
+					    config.buffer_size;
+					audio->in[index].used = 0;
+					offset += config.buffer_size;
+				}
+				rc = 0;
+			}
+		} else {
+			rc = 0;
+		}
+		break;
+	}
+	default:
+		rc = -EINVAL;
+	}
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count,
+			  loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	int rc = 0;
+
+	if (!audio->pcm_feedback)
+		return 0; /* PCM feedback is not enabled. Nothing to read */
+
+	mutex_lock(&audio->read_lock);
+	dprintk("audamrnb_read() %d \n", count);
+	while (count > 0) {
+		rc = wait_event_interruptible(audio->read_wait,
+					      (audio->in[audio->read_next].
+					       used > 0) || (audio->stopped));
+
+		if (rc < 0)
+			break;
+
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+
+		if (count < audio->in[audio->read_next].used) {
+			/* Read must happen in frame boundary. Since driver does
+			 * not know frame size, read count must be greater or
+			 * equal to size of PCM samples
+			 */
+			dprintk("audamrnb_read:read stop - partial frame\n");
+			break;
+		} else {
+			dprintk("audamrnb_read: read from in[%d]\n",
+				audio->read_next);
+			if (copy_to_user
+			    (buf, audio->in[audio->read_next].data,
+			     audio->in[audio->read_next].used)) {
+				pr_err("audamrnb_read: invalid addr %x \n",
+				       (unsigned int)buf);
+				rc = -EFAULT;
+				break;
+			}
+			count -= audio->in[audio->read_next].used;
+			buf += audio->in[audio->read_next].used;
+			audio->in[audio->read_next].used = 0;
+			if ((++audio->read_next) == audio->pcm_buf_count)
+				audio->read_next = 0;
+		}
+	}
+
+	if (audio->buf_refresh) {
+		audio->buf_refresh = 0;
+		dprintk("audamrnb_read: kick start pcm feedback again\n");
+		audamrnb_buffer_refresh(audio);
+	}
+
+	mutex_unlock(&audio->read_lock);
+
+	if (buf > start)
+		rc = buf - start;
+
+	dprintk("audamrnb_read: read %d bytes\n", rc);
+	return rc;
+}
+
+static ssize_t audamrnb_write(struct file *file, const char __user *buf,
+			   size_t count, loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	struct buffer *frame;
+	size_t xfer;
+	int rc = 0;
+
+	if (count & 1)
+		return -EINVAL;
+	dprintk("audamrnb_write() \n");
+	mutex_lock(&audio->write_lock);
+	while (count > 0) {
+		frame = audio->out + audio->out_head;
+		rc = wait_event_interruptible(audio->write_wait,
+					      (frame->used == 0)
+					      || (audio->stopped));
+		dprintk("audamrnb_write() buffer available\n");
+		if (rc < 0)
+			break;
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+		xfer = (count > frame->size) ? frame->size : count;
+		if (copy_from_user(frame->data, buf, xfer)) {
+			rc = -EFAULT;
+			break;
+		}
+
+		frame->used = xfer;
+		audio->out_head ^= 1;
+		count -= xfer;
+		buf += xfer;
+
+		audamrnb_send_data(audio, 0);
+
+	}
+	mutex_unlock(&audio->write_lock);
+	if (buf > start)
+		return buf - start;
+	return rc;
+}
+
+static int audamrnb_release(struct inode *inode, struct file *file)
+{
+	struct audio *audio = file->private_data;
+
+	dprintk("audamrnb_release()\n");
+
+	mutex_lock(&audio->lock);
+	audamrnb_disable(audio);
+	audamrnb_flush(audio);
+	audamrnb_flush_pcm_buf(audio);
+	msm_adsp_put(audio->audplay);
+	audio->audplay = NULL;
+	audio->opened = 0;
+	dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
+	audio->data = NULL;
+	if (audio->read_data != NULL) {
+		dma_free_coherent(NULL,
+				  audio->in[0].size * audio->pcm_buf_count,
+				  audio->read_data, audio->read_phys);
+		audio->read_data = NULL;
+	}
+	audio->pcm_feedback = 0;
+	mutex_unlock(&audio->lock);
+	return 0;
+}
+
+static struct audio the_amrnb_audio;
+
+static int audamrnb_open(struct inode *inode, struct file *file)
+{
+	struct audio *audio = &the_amrnb_audio;
+	int rc;
+
+	mutex_lock(&audio->lock);
+
+	if (audio->opened) {
+		pr_err("audio: busy\n");
+		rc = -EBUSY;
+		goto done;
+	}
+
+	if (!audio->data) {
+		audio->data = dma_alloc_coherent(NULL, DMASZ,
+						 &audio->phys, GFP_KERNEL);
+		if (!audio->data) {
+			pr_err("audio: could not allocate DMA buffers\n");
+			rc = -ENOMEM;
+			goto done;
+		}
+	}
+
+	rc = audmgr_open(&audio->audmgr);
+	if (rc)
+		goto done;
+
+	rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
+		&audplay_adsp_ops_amrnb, audio);
+	if (rc) {
+		pr_err("audio: failed to get audplay0 dsp module\n");
+		audmgr_disable(&audio->audmgr);
+		dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
+		audio->data = NULL;
+		goto done;
+	}
+
+	audio->dec_id = 0;
+
+	audio->out[0].data = audio->data + 0;
+	audio->out[0].addr = audio->phys + 0;
+	audio->out[0].size = BUFSZ;
+
+	audio->out[1].data = audio->data + BUFSZ;
+	audio->out[1].addr = audio->phys + BUFSZ;
+	audio->out[1].size = BUFSZ;
+
+	audio->volume = 0x2000;	/* Q13 1.0 */
+
+	audamrnb_flush(audio);
+
+	file->private_data = audio;
+	audio->opened = 1;
+	rc = 0;
+done:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static struct file_operations audio_amrnb_fops = {
+	.owner = THIS_MODULE,
+	.open = audamrnb_open,
+	.release = audamrnb_release,
+	.read = audamrnb_read,
+	.write = audamrnb_write,
+	.unlocked_ioctl = audamrnb_ioctl,
+};
+
+struct miscdevice audio_amrnb_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "msm_amrnb",
+	.fops = &audio_amrnb_fops,
+};
+
+static int __init audamrnb_init(void)
+{
+	mutex_init(&the_amrnb_audio.lock);
+	mutex_init(&the_amrnb_audio.write_lock);
+	mutex_init(&the_amrnb_audio.read_lock);
+	spin_lock_init(&the_amrnb_audio.dsp_lock);
+	init_waitqueue_head(&the_amrnb_audio.write_wait);
+	init_waitqueue_head(&the_amrnb_audio.read_wait);
+	the_amrnb_audio.read_data = NULL;
+	return misc_register(&audio_amrnb_misc);
+}
+
+static void __exit audamrnb_exit(void)
+{
+	misc_deregister(&audio_amrnb_misc);
+}
+
+module_init(audamrnb_init);
+module_exit(audamrnb_exit);
+
+MODULE_DESCRIPTION("MSM AMR-NB driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("QUALCOMM Inc");
diff --git a/drivers/staging/dream/qdsp5/audio_evrc.c b/drivers/staging/dream/qdsp5/audio_evrc.c
new file mode 100644
index 0000000..4b43e18
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audio_evrc.c
@@ -0,0 +1,845 @@
+/* arch/arm/mach-msm/audio_evrc.c
+ *
+ * Copyright (c) 2008 QUALCOMM USA, INC.
+ *
+ * This code also borrows from audio_aac.c, which is
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can find it at http://www.fsf.org.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include <mach/msm_adsp.h>
+#include <linux/msm_audio.h>
+#include "audmgr.h"
+
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audplaycmdi.h>
+#include <mach/qdsp5/qdsp5audplaymsg.h>
+
+#include "adsp.h"
+
+#ifdef DEBUG
+#define dprintk(format, arg...) \
+	printk(KERN_DEBUG format, ## arg)
+#else
+#define dprintk(format, arg...) do {} while (0)
+#endif
+
+/* Hold 30 packets of 24 bytes each*/
+#define BUFSZ 			720
+#define DMASZ 			(BUFSZ * 2)
+
+#define AUDDEC_DEC_EVRC 	12
+
+#define PCM_BUFSZ_MIN 		1600	/* 100ms worth of data */
+#define PCM_BUF_MAX_COUNT 	5
+/* DSP only accepts 5 buffers at most
+ * but support 2 buffers currently
+ */
+#define EVRC_DECODED_FRSZ 	320	/* EVRC 20ms 8KHz mono PCM size */
+
+#define ROUTING_MODE_FTRT 	1
+#define ROUTING_MODE_RT 	2
+/* Decoder status received from AUDPPTASK */
+#define  AUDPP_DEC_STATUS_SLEEP	0
+#define	 AUDPP_DEC_STATUS_INIT  1
+#define  AUDPP_DEC_STATUS_CFG   2
+#define  AUDPP_DEC_STATUS_PLAY  3
+
+struct buffer {
+	void *data;
+	unsigned size;
+	unsigned used;		/* Input usage actual DSP produced PCM size  */
+	unsigned addr;
+};
+
+struct audio {
+	struct buffer out[2];
+
+	spinlock_t dsp_lock;
+
+	uint8_t out_head;
+	uint8_t out_tail;
+	uint8_t out_needed;	/* number of buffers the dsp is waiting for */
+
+	atomic_t out_bytes;
+
+	struct mutex lock;
+	struct mutex write_lock;
+	wait_queue_head_t write_wait;
+
+	/* Host PCM section */
+	struct buffer in[PCM_BUF_MAX_COUNT];
+	struct mutex read_lock;
+	wait_queue_head_t read_wait;	/* Wait queue for read */
+	char *read_data;	/* pointer to reader buffer */
+	dma_addr_t read_phys;	/* physical address of reader buffer */
+	uint8_t read_next;	/* index to input buffers to be read next */
+	uint8_t fill_next;	/* index to buffer that DSP should be filling */
+	uint8_t pcm_buf_count;	/* number of pcm buffer allocated */
+	/* ---- End of Host PCM section */
+
+	struct msm_adsp_module *audplay;
+	struct audmgr audmgr;
+
+	/* data allocated for various buffers */
+	char *data;
+	dma_addr_t phys;
+
+	uint8_t opened:1;
+	uint8_t enabled:1;
+	uint8_t running:1;
+	uint8_t stopped:1;	/* set when stopped, cleared on flush */
+	uint8_t pcm_feedback:1;
+	uint8_t buf_refresh:1;
+
+	unsigned volume;
+	uint16_t dec_id;
+	uint32_t read_ptr_offset;
+};
+static struct audio the_evrc_audio;
+
+static int auddec_dsp_config(struct audio *audio, int enable);
+static void audpp_cmd_cfg_adec_params(struct audio *audio);
+static void audpp_cmd_cfg_routing_mode(struct audio *audio);
+static void audevrc_send_data(struct audio *audio, unsigned needed);
+static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg);
+static void audevrc_config_hostpcm(struct audio *audio);
+static void audevrc_buffer_refresh(struct audio *audio);
+
+/* must be called with audio->lock held */
+static int audevrc_enable(struct audio *audio)
+{
+	struct audmgr_config cfg;
+	int rc;
+
+	if (audio->enabled)
+		return 0;
+
+	audio->out_tail = 0;
+	audio->out_needed = 0;
+
+	cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
+	cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
+	cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
+	cfg.codec = RPC_AUD_DEF_CODEC_EVRC;
+	cfg.snd_method = RPC_SND_METHOD_MIDI;
+
+	rc = audmgr_enable(&audio->audmgr, &cfg);
+	if (rc < 0)
+		return rc;
+
+	if (msm_adsp_enable(audio->audplay)) {
+		pr_err("audio: msm_adsp_enable(audplay) failed\n");
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+
+	if (audpp_enable(audio->dec_id, audevrc_dsp_event, audio)) {
+		pr_err("audio: audpp_enable() failed\n");
+		msm_adsp_disable(audio->audplay);
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+	audio->enabled = 1;
+	return 0;
+}
+
+/* must be called with audio->lock held */
+static int audevrc_disable(struct audio *audio)
+{
+	if (audio->enabled) {
+		audio->enabled = 0;
+		auddec_dsp_config(audio, 0);
+		wake_up(&audio->write_wait);
+		wake_up(&audio->read_wait);
+		msm_adsp_disable(audio->audplay);
+		audpp_disable(audio->dec_id, audio);
+		audmgr_disable(&audio->audmgr);
+		audio->out_needed = 0;
+	}
+	return 0;
+}
+
+/* ------------------- dsp --------------------- */
+
+static void audevrc_update_pcm_buf_entry(struct audio *audio,
+					 uint32_t *payload)
+{
+	uint8_t index;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	for (index = 0; index < payload[1]; index++) {
+		if (audio->in[audio->fill_next].addr
+				== payload[2 + index * 2]) {
+			dprintk("audevrc_update_pcm_buf_entry: in[%d] ready\n",
+				audio->fill_next);
+			audio->in[audio->fill_next].used =
+				payload[3 + index * 2];
+			if ((++audio->fill_next) == audio->pcm_buf_count)
+				audio->fill_next = 0;
+
+		} else {
+			pr_err
+			("audevrc_update_pcm_buf_entry: expected=%x ret=%x\n",
+				audio->in[audio->fill_next].addr,
+				payload[1 + index * 2]);
+			break;
+		}
+	}
+	if (audio->in[audio->fill_next].used == 0) {
+		audevrc_buffer_refresh(audio);
+	} else {
+		dprintk("audevrc_update_pcm_buf_entry: read cannot keep up\n");
+		audio->buf_refresh = 1;
+	}
+
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+	wake_up(&audio->read_wait);
+}
+
+static void audplay_dsp_event(void *data, unsigned id, size_t len,
+			      void (*getevent) (void *ptr, size_t len))
+{
+	struct audio *audio = data;
+	uint32_t msg[28];
+	getevent(msg, sizeof(msg));
+
+	dprintk("audplay_dsp_event: msg_id=%x\n", id);
+	switch (id) {
+	case AUDPLAY_MSG_DEC_NEEDS_DATA:
+		audevrc_send_data(audio, 1);
+		break;
+	case AUDPLAY_MSG_BUFFER_UPDATE:
+		dprintk("audevrc_update_pcm_buf_entry:======> \n");
+		audevrc_update_pcm_buf_entry(audio, msg);
+		break;
+	default:
+		pr_err("unexpected message from decoder \n");
+	}
+}
+
+static void audevrc_dsp_event(void *private, unsigned id, uint16_t *msg)
+{
+	struct audio *audio = private;
+
+	switch (id) {
+	case AUDPP_MSG_STATUS_MSG:{
+			unsigned status = msg[1];
+
+			switch (status) {
+			case AUDPP_DEC_STATUS_SLEEP:
+				dprintk("decoder status: sleep \n");
+				break;
+
+			case AUDPP_DEC_STATUS_INIT:
+				dprintk("decoder status: init \n");
+				audpp_cmd_cfg_routing_mode(audio);
+				break;
+
+			case AUDPP_DEC_STATUS_CFG:
+				dprintk("decoder status: cfg \n");
+				break;
+			case AUDPP_DEC_STATUS_PLAY:
+				dprintk("decoder status: play \n");
+				if (audio->pcm_feedback) {
+					audevrc_config_hostpcm(audio);
+					audevrc_buffer_refresh(audio);
+				}
+				break;
+			default:
+				pr_err("unknown decoder status \n");
+			}
+			break;
+		}
+	case AUDPP_MSG_CFG_MSG:
+		if (msg[0] == AUDPP_MSG_ENA_ENA) {
+			dprintk("audevrc_dsp_event: CFG_MSG ENABLE\n");
+			auddec_dsp_config(audio, 1);
+			audio->out_needed = 0;
+			audio->running = 1;
+			audpp_set_volume_and_pan(audio->dec_id, audio->volume,
+						 0);
+			audpp_avsync(audio->dec_id, 22050);
+		} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
+			dprintk("audevrc_dsp_event: CFG_MSG DISABLE\n");
+			audpp_avsync(audio->dec_id, 0);
+			audio->running = 0;
+		} else {
+			pr_err("audevrc_dsp_event: CFG_MSG %d?\n", msg[0]);
+		}
+		break;
+	case AUDPP_MSG_ROUTING_ACK:
+		dprintk("audevrc_dsp_event: ROUTING_ACK\n");
+		audpp_cmd_cfg_adec_params(audio);
+		break;
+
+	default:
+		pr_err("audevrc_dsp_event: UNKNOWN (%d)\n", id);
+	}
+
+}
+
+struct msm_adsp_ops audplay_adsp_ops_evrc = {
+	.event = audplay_dsp_event,
+};
+
+#define audplay_send_queue0(audio, cmd, len) \
+	msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
+		       cmd, len)
+
+static int auddec_dsp_config(struct audio *audio, int enable)
+{
+	audpp_cmd_cfg_dec_type cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
+	if (enable)
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
+		    AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_EVRC;
+	else
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
+
+	return audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_adec_params(struct audio *audio)
+{
+	struct audpp_cmd_cfg_adec_params_evrc cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
+	cmd.common.length = sizeof(cmd);
+	cmd.common.dec_id = audio->dec_id;
+	cmd.common.input_sampling_frequency = 8000;
+	cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
+
+	audpp_send_queue2(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_routing_mode(struct audio *audio)
+{
+	struct audpp_cmd_routing_mode cmd;
+	dprintk("audpp_cmd_cfg_routing_mode()\n");
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
+	cmd.object_number = audio->dec_id;
+	if (audio->pcm_feedback)
+		cmd.routing_mode = ROUTING_MODE_FTRT;
+	else
+		cmd.routing_mode = ROUTING_MODE_RT;
+
+	audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static int audplay_dsp_send_data_avail(struct audio *audio,
+				       unsigned idx, unsigned len)
+{
+	audplay_cmd_bitstream_data_avail cmd;
+
+	cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
+	cmd.decoder_id = audio->dec_id;
+	cmd.buf_ptr = audio->out[idx].addr;
+	cmd.buf_size = len / 2;
+	cmd.partition_number = 0;
+	return audplay_send_queue0(audio, &cmd, sizeof(cmd));
+}
+
+static void audevrc_buffer_refresh(struct audio *audio)
+{
+	struct audplay_cmd_buffer_refresh refresh_cmd;
+
+	refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
+	refresh_cmd.num_buffers = 1;
+	refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
+	refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
+
+	refresh_cmd.buf_read_count = 0;
+	dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
+		refresh_cmd.buf0_address, refresh_cmd.buf0_length);
+	audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
+}
+
+static void audevrc_config_hostpcm(struct audio *audio)
+{
+	struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
+
+	dprintk("audevrc_config_hostpcm()\n");
+	cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
+	cfg_cmd.max_buffers = 1;
+	cfg_cmd.byte_swap = 0;
+	cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
+	cfg_cmd.feedback_frequency = 1;
+	cfg_cmd.partition_number = 0;
+	audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
+
+}
+
+static void audevrc_send_data(struct audio *audio, unsigned needed)
+{
+	struct buffer *frame;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	if (!audio->running)
+		goto done;
+
+	if (needed) {
+		/* We were called from the callback because the DSP
+		 * requested more data.  Note that the DSP does want
+		 * more data, and if a buffer was in-flight, mark it
+		 * as available (since the DSP must now be done with
+		 * it).
+		 */
+		audio->out_needed = 1;
+		frame = audio->out + audio->out_tail;
+		if (frame->used == 0xffffffff) {
+			dprintk("frame %d free\n", audio->out_tail);
+			frame->used = 0;
+			audio->out_tail ^= 1;
+			wake_up(&audio->write_wait);
+		}
+	}
+
+	if (audio->out_needed) {
+		/* If the DSP currently wants data and we have a
+		 * buffer available, we will send it and reset
+		 * the needed flag.  We'll mark the buffer as in-flight
+		 * so that it won't be recycled until the next buffer
+		 * is requested
+		 */
+
+		frame = audio->out + audio->out_tail;
+		if (frame->used) {
+			BUG_ON(frame->used == 0xffffffff);
+			dprintk("frame %d busy\n", audio->out_tail);
+			audplay_dsp_send_data_avail(audio, audio->out_tail,
+						    frame->used);
+			frame->used = 0xffffffff;
+			audio->out_needed = 0;
+		}
+	}
+done:
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+}
+
+/* ------------------- device --------------------- */
+
+static void audevrc_flush(struct audio *audio)
+{
+	audio->out[0].used = 0;
+	audio->out[1].used = 0;
+	audio->out_head = 0;
+	audio->out_tail = 0;
+	audio->stopped = 0;
+	atomic_set(&audio->out_bytes, 0);
+}
+
+static void audevrc_flush_pcm_buf(struct audio *audio)
+{
+	uint8_t index;
+
+	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
+		audio->in[index].used = 0;
+
+	audio->read_next = 0;
+	audio->fill_next = 0;
+}
+
+static long audevrc_ioctl(struct file *file, unsigned int cmd,
+			  unsigned long arg)
+{
+	struct audio *audio = file->private_data;
+	int rc = 0;
+
+	dprintk("audevrc_ioctl() cmd = %d\n", cmd);
+
+	if (cmd == AUDIO_GET_STATS) {
+		struct msm_audio_stats stats;
+		stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
+		stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
+		if (copy_to_user((void *)arg, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == AUDIO_SET_VOLUME) {
+		unsigned long flags;
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		audio->volume = arg;
+		if (audio->running)
+			audpp_set_volume_and_pan(audio->dec_id, arg, 0);
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+		return 0;
+	}
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_START:
+		rc = audevrc_enable(audio);
+		break;
+	case AUDIO_STOP:
+		rc = audevrc_disable(audio);
+		audio->stopped = 1;
+		break;
+	case AUDIO_SET_CONFIG:{
+			dprintk("AUDIO_SET_CONFIG not applicable \n");
+			break;
+		}
+	case AUDIO_GET_CONFIG:{
+			struct msm_audio_config config;
+			config.buffer_size = BUFSZ;
+			config.buffer_count = 2;
+			config.sample_rate = 8000;
+			config.channel_count = 1;
+			config.unused[0] = 0;
+			config.unused[1] = 0;
+			config.unused[2] = 0;
+			config.unused[3] = 0;
+			if (copy_to_user((void *)arg, &config, sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+			break;
+		}
+	case AUDIO_GET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+			config.pcm_feedback = 0;
+			config.buffer_count = PCM_BUF_MAX_COUNT;
+			config.buffer_size = PCM_BUFSZ_MIN;
+			if (copy_to_user((void *)arg, &config, sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+			break;
+		}
+	case AUDIO_SET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+			if (copy_from_user
+			    (&config, (void *)arg, sizeof(config))) {
+				rc = -EFAULT;
+				break;
+			}
+			if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
+			    (config.buffer_count == 1))
+				config.buffer_count = PCM_BUF_MAX_COUNT;
+
+			if (config.buffer_size < PCM_BUFSZ_MIN)
+				config.buffer_size = PCM_BUFSZ_MIN;
+
+			/* Check if pcm feedback is required */
+			if ((config.pcm_feedback) && (!audio->read_data)) {
+				dprintk("audevrc_ioctl: allocate PCM buf %d\n",
+					config.buffer_count *
+					config.buffer_size);
+				audio->read_data =
+				    dma_alloc_coherent(NULL,
+						       config.buffer_size *
+						       config.buffer_count,
+						       &audio->read_phys,
+						       GFP_KERNEL);
+				if (!audio->read_data) {
+					pr_err
+					("audevrc_ioctl: no mem for pcm buf\n");
+					rc = -1;
+				} else {
+					uint8_t index;
+					uint32_t offset = 0;
+					audio->pcm_feedback = 1;
+					audio->buf_refresh = 0;
+					audio->pcm_buf_count =
+					    config.buffer_count;
+					audio->read_next = 0;
+					audio->fill_next = 0;
+
+					for (index = 0;
+					     index < config.buffer_count;
+					     index++) {
+						audio->in[index].data =
+						    audio->read_data + offset;
+						audio->in[index].addr =
+						    audio->read_phys + offset;
+						audio->in[index].size =
+						    config.buffer_size;
+						audio->in[index].used = 0;
+						offset += config.buffer_size;
+					}
+					rc = 0;
+				}
+			} else {
+				rc = 0;
+			}
+			break;
+		}
+	case AUDIO_PAUSE:
+		dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
+		rc = audpp_pause(audio->dec_id, (int) arg);
+		break;
+	default:
+		rc = -EINVAL;
+	}
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static ssize_t audevrc_read(struct file *file, char __user *buf, size_t count,
+			    loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	int rc = 0;
+	if (!audio->pcm_feedback) {
+		return 0;
+		/* PCM feedback is not enabled. Nothing to read */
+	}
+	mutex_lock(&audio->read_lock);
+	dprintk("audevrc_read() \n");
+	while (count > 0) {
+		rc = wait_event_interruptible(audio->read_wait,
+					      (audio->in[audio->read_next].
+					       used > 0) || (audio->stopped));
+		dprintk("audevrc_read() wait terminated \n");
+		if (rc < 0)
+			break;
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+		if (count < audio->in[audio->read_next].used) {
+			/* Read must happen in frame boundary. Since driver does
+			 * not know frame size, read count must be greater or
+			 * equal to size of PCM samples
+			 */
+			dprintk("audevrc_read:read stop - partial frame\n");
+			break;
+		} else {
+			dprintk("audevrc_read: read from in[%d]\n",
+				audio->read_next);
+			if (copy_to_user
+			    (buf, audio->in[audio->read_next].data,
+			     audio->in[audio->read_next].used)) {
+				pr_err("audevrc_read: invalid addr %x \n",
+				       (unsigned int)buf);
+				rc = -EFAULT;
+				break;
+			}
+			count -= audio->in[audio->read_next].used;
+			buf += audio->in[audio->read_next].used;
+			audio->in[audio->read_next].used = 0;
+			if ((++audio->read_next) == audio->pcm_buf_count)
+				audio->read_next = 0;
+			if (audio->in[audio->read_next].used == 0)
+				break;	/* No data ready at this moment
+					 * Exit while loop to prevent
+					 * output thread sleep too long
+					 */
+
+		}
+	}
+	if (audio->buf_refresh) {
+		audio->buf_refresh = 0;
+		dprintk("audevrc_read: kick start pcm feedback again\n");
+		audevrc_buffer_refresh(audio);
+	}
+	mutex_unlock(&audio->read_lock);
+	if (buf > start)
+		rc = buf - start;
+	dprintk("audevrc_read: read %d bytes\n", rc);
+	return rc;
+}
+
+static ssize_t audevrc_write(struct file *file, const char __user *buf,
+			     size_t count, loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	struct buffer *frame;
+	size_t xfer;
+	int rc = 0;
+
+	if (count & 1)
+		return -EINVAL;
+	mutex_lock(&audio->write_lock);
+	dprintk("audevrc_write() \n");
+	while (count > 0) {
+		frame = audio->out + audio->out_head;
+		rc = wait_event_interruptible(audio->write_wait,
+					      (frame->used == 0)
+					      || (audio->stopped));
+		if (rc < 0)
+			break;
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+		xfer = (count > frame->size) ? frame->size : count;
+		if (copy_from_user(frame->data, buf, xfer)) {
+			rc = -EFAULT;
+			break;
+		}
+
+		frame->used = xfer;
+		audio->out_head ^= 1;
+		count -= xfer;
+		buf += xfer;
+
+		audevrc_send_data(audio, 0);
+
+	}
+	mutex_unlock(&audio->write_lock);
+	if (buf > start)
+		return buf - start;
+	return rc;
+}
+
+static int audevrc_release(struct inode *inode, struct file *file)
+{
+	struct audio *audio = file->private_data;
+
+	dprintk("audevrc_release()\n");
+
+	mutex_lock(&audio->lock);
+	audevrc_disable(audio);
+	audevrc_flush(audio);
+	audevrc_flush_pcm_buf(audio);
+	msm_adsp_put(audio->audplay);
+	audio->audplay = NULL;
+	audio->opened = 0;
+	dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
+	audio->data = NULL;
+	if (audio->read_data != NULL) {
+		dma_free_coherent(NULL,
+				  audio->in[0].size * audio->pcm_buf_count,
+				  audio->read_data, audio->read_phys);
+		audio->read_data = NULL;
+	}
+	audio->pcm_feedback = 0;
+	mutex_unlock(&audio->lock);
+	return 0;
+}
+
+static struct audio the_evrc_audio;
+
+static int audevrc_open(struct inode *inode, struct file *file)
+{
+	struct audio *audio = &the_evrc_audio;
+	int rc;
+
+	if (audio->opened) {
+		pr_err("audio: busy\n");
+		return -EBUSY;
+	}
+
+	/* Acquire Lock */
+	mutex_lock(&audio->lock);
+
+	if (!audio->data) {
+		audio->data = dma_alloc_coherent(NULL, DMASZ,
+						 &audio->phys, GFP_KERNEL);
+		if (!audio->data) {
+			pr_err("audio: could not allocate DMA buffers\n");
+			rc = -ENOMEM;
+			goto dma_fail;
+		}
+	}
+
+	rc = audmgr_open(&audio->audmgr);
+	if (rc)
+		goto audmgr_fail;
+
+	rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
+			  &audplay_adsp_ops_evrc, audio);
+	if (rc) {
+		pr_err("audio: failed to get audplay0 dsp module\n");
+		goto adsp_fail;
+	}
+
+	audio->dec_id = 0;
+
+	audio->out[0].data = audio->data + 0;
+	audio->out[0].addr = audio->phys + 0;
+	audio->out[0].size = BUFSZ;
+
+	audio->out[1].data = audio->data + BUFSZ;
+	audio->out[1].addr = audio->phys + BUFSZ;
+	audio->out[1].size = BUFSZ;
+
+	audio->volume = 0x3FFF;
+
+	audevrc_flush(audio);
+
+	audio->opened = 1;
+	file->private_data = audio;
+
+	mutex_unlock(&audio->lock);
+	return rc;
+
+adsp_fail:
+	audmgr_close(&audio->audmgr);
+audmgr_fail:
+	dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
+dma_fail:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static struct file_operations audio_evrc_fops = {
+	.owner = THIS_MODULE,
+	.open = audevrc_open,
+	.release = audevrc_release,
+	.read = audevrc_read,
+	.write = audevrc_write,
+	.unlocked_ioctl = audevrc_ioctl,
+};
+
+struct miscdevice audio_evrc_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "msm_evrc",
+	.fops = &audio_evrc_fops,
+};
+
+static int __init audevrc_init(void)
+{
+	mutex_init(&the_evrc_audio.lock);
+	mutex_init(&the_evrc_audio.write_lock);
+	mutex_init(&the_evrc_audio.read_lock);
+	spin_lock_init(&the_evrc_audio.dsp_lock);
+	init_waitqueue_head(&the_evrc_audio.write_wait);
+	init_waitqueue_head(&the_evrc_audio.read_wait);
+	the_evrc_audio.read_data = NULL;
+	return misc_register(&audio_evrc_misc);
+}
+
+static void __exit audevrc_exit(void)
+{
+	misc_deregister(&audio_evrc_misc);
+}
+
+module_init(audevrc_init);
+module_exit(audevrc_exit);
+
+MODULE_DESCRIPTION("MSM EVRC driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("QUALCOMM Inc");
diff --git a/drivers/staging/dream/qdsp5/audio_in.c b/drivers/staging/dream/qdsp5/audio_in.c
new file mode 100644
index 0000000..3d950a2
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audio_in.c
@@ -0,0 +1,967 @@
+/* arch/arm/mach-msm/qdsp5/audio_in.c
+ *
+ * pcm audio input device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/delay.h>
+
+#include <linux/msm_audio.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include <mach/msm_adsp.h>
+#include <mach/msm_rpcrouter.h>
+
+#include "audmgr.h"
+
+#include <mach/qdsp5/qdsp5audpreproccmdi.h>
+#include <mach/qdsp5/qdsp5audpreprocmsg.h>
+#include <mach/qdsp5/qdsp5audreccmdi.h>
+#include <mach/qdsp5/qdsp5audrecmsg.h>
+
+/* for queue ids - should be relative to module number*/
+#include "adsp.h"
+
+/* FRAME_NUM must be a power of two */
+#define FRAME_NUM		(8)
+#define FRAME_SIZE		(2052 * 2)
+#define MONO_DATA_SIZE		(2048)
+#define STEREO_DATA_SIZE	(MONO_DATA_SIZE * 2)
+#define DMASZ 			(FRAME_SIZE * FRAME_NUM)
+
+#define AGC_PARAM_SIZE		(20)
+#define NS_PARAM_SIZE		(6)
+#define IIR_PARAM_SIZE		(48)
+#define DEBUG			(0)
+
+#define AGC_ENABLE   0x0001
+#define NS_ENABLE    0x0002
+#define IIR_ENABLE   0x0004
+
+struct tx_agc_config {
+	uint16_t agc_params[AGC_PARAM_SIZE];
+};
+
+struct ns_config {
+	uint16_t ns_params[NS_PARAM_SIZE];
+};
+
+struct tx_iir_filter {
+	uint16_t num_bands;
+	uint16_t iir_params[IIR_PARAM_SIZE];
+};
+
+struct audpre_cmd_iir_config_type {
+	uint16_t cmd_id;
+	uint16_t active_flag;
+	uint16_t num_bands;
+	uint16_t iir_params[IIR_PARAM_SIZE];
+};
+
+struct buffer {
+	void *data;
+	uint32_t size;
+	uint32_t read;
+	uint32_t addr;
+};
+
+struct audio_in {
+	struct buffer in[FRAME_NUM];
+
+	spinlock_t dsp_lock;
+
+	atomic_t in_bytes;
+
+	struct mutex lock;
+	struct mutex read_lock;
+	wait_queue_head_t wait;
+
+	struct msm_adsp_module *audpre;
+	struct msm_adsp_module *audrec;
+
+	/* configuration to use on next enable */
+	uint32_t samp_rate;
+	uint32_t channel_mode;
+	uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */
+	uint32_t type; /* 0 for PCM ,1 for AAC */
+	uint32_t dsp_cnt;
+	uint32_t in_head; /* next buffer dsp will write */
+	uint32_t in_tail; /* next buffer read() will read */
+	uint32_t in_count; /* number of buffers available to read() */
+
+	unsigned short samp_rate_index;
+
+	struct audmgr audmgr;
+
+	/* data allocated for various buffers */
+	char *data;
+	dma_addr_t phys;
+
+	int opened;
+	int enabled;
+	int running;
+	int stopped; /* set when stopped, cleared on flush */
+
+	/* audpre settings */
+	int agc_enable;
+	struct tx_agc_config agc;
+
+	int ns_enable;
+	struct ns_config ns;
+
+	int iir_enable;
+	struct tx_iir_filter iir;
+};
+
+static int audio_in_dsp_enable(struct audio_in *audio, int enable);
+static int audio_in_encoder_config(struct audio_in *audio);
+static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt);
+static void audio_flush(struct audio_in *audio);
+static int audio_dsp_set_agc(struct audio_in *audio);
+static int audio_dsp_set_ns(struct audio_in *audio);
+static int audio_dsp_set_tx_iir(struct audio_in *audio);
+
+static unsigned convert_dsp_samp_index(unsigned index)
+{
+	switch (index) {
+	case 48000:	return AUDREC_CMD_SAMP_RATE_INDX_48000;
+	case 44100:	return AUDREC_CMD_SAMP_RATE_INDX_44100;
+	case 32000:	return AUDREC_CMD_SAMP_RATE_INDX_32000;
+	case 24000:	return AUDREC_CMD_SAMP_RATE_INDX_24000;
+	case 22050:	return AUDREC_CMD_SAMP_RATE_INDX_22050;
+	case 16000:	return AUDREC_CMD_SAMP_RATE_INDX_16000;
+	case 12000:	return AUDREC_CMD_SAMP_RATE_INDX_12000;
+	case 11025:	return AUDREC_CMD_SAMP_RATE_INDX_11025;
+	case 8000:	return AUDREC_CMD_SAMP_RATE_INDX_8000;
+	default: 	return AUDREC_CMD_SAMP_RATE_INDX_11025;
+	}
+}
+
+static unsigned convert_samp_rate(unsigned hz)
+{
+	switch (hz) {
+	case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000;
+	case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100;
+	case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000;
+	case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000;
+	case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050;
+	case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000;
+	case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000;
+	case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025;
+	case 8000:  return RPC_AUD_DEF_SAMPLE_RATE_8000;
+	default:    return RPC_AUD_DEF_SAMPLE_RATE_11025;
+	}
+}
+
+static unsigned convert_samp_index(unsigned index)
+{
+	switch (index) {
+	case RPC_AUD_DEF_SAMPLE_RATE_48000:	return 48000;
+	case RPC_AUD_DEF_SAMPLE_RATE_44100:	return 44100;
+	case RPC_AUD_DEF_SAMPLE_RATE_32000:	return 32000;
+	case RPC_AUD_DEF_SAMPLE_RATE_24000:	return 24000;
+	case RPC_AUD_DEF_SAMPLE_RATE_22050:	return 22050;
+	case RPC_AUD_DEF_SAMPLE_RATE_16000:	return 16000;
+	case RPC_AUD_DEF_SAMPLE_RATE_12000:	return 12000;
+	case RPC_AUD_DEF_SAMPLE_RATE_11025:	return 11025;
+	case RPC_AUD_DEF_SAMPLE_RATE_8000:	return 8000;
+	default: 				return 11025;
+	}
+}
+
+/* must be called with audio->lock held */
+static int audio_in_enable(struct audio_in *audio)
+{
+	struct audmgr_config cfg;
+	int rc;
+
+	if (audio->enabled)
+		return 0;
+
+	cfg.tx_rate = audio->samp_rate;
+	cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
+	cfg.def_method = RPC_AUD_DEF_METHOD_RECORD;
+	if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
+		cfg.codec = RPC_AUD_DEF_CODEC_PCM;
+	else
+		cfg.codec = RPC_AUD_DEF_CODEC_AAC;
+	cfg.snd_method = RPC_SND_METHOD_MIDI;
+
+	rc = audmgr_enable(&audio->audmgr, &cfg);
+	if (rc < 0)
+		return rc;
+
+	if (msm_adsp_enable(audio->audpre)) {
+		pr_err("audrec: msm_adsp_enable(audpre) failed\n");
+		return -ENODEV;
+	}
+	if (msm_adsp_enable(audio->audrec)) {
+		pr_err("audrec: msm_adsp_enable(audrec) failed\n");
+		return -ENODEV;
+	}
+
+	audio->enabled = 1;
+	audio_in_dsp_enable(audio, 1);
+
+	return 0;
+}
+
+/* must be called with audio->lock held */
+static int audio_in_disable(struct audio_in *audio)
+{
+	if (audio->enabled) {
+		audio->enabled = 0;
+
+		audio_in_dsp_enable(audio, 0);
+
+		wake_up(&audio->wait);
+
+		msm_adsp_disable(audio->audrec);
+		msm_adsp_disable(audio->audpre);
+		audmgr_disable(&audio->audmgr);
+	}
+	return 0;
+}
+
+/* ------------------- dsp --------------------- */
+static void audpre_dsp_event(void *data, unsigned id, size_t len,
+			    void (*getevent)(void *ptr, size_t len))
+{
+	uint16_t msg[2];
+	getevent(msg, sizeof(msg));
+
+	switch (id) {
+	case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
+		pr_info("audpre: type %d, status_flag %d\n", msg[0], msg[1]);
+		break;
+	case AUDPREPROC_MSG_ERROR_MSG_ID:
+		pr_info("audpre: err_index %d\n", msg[0]);
+		break;
+	default:
+		pr_err("audpre: unknown event %d\n", id);
+	}
+}
+
+struct audio_frame {
+	uint16_t count_low;
+	uint16_t count_high;
+	uint16_t bytes;
+	uint16_t unknown;
+	unsigned char samples[];
+} __attribute__((packed));
+
+static void audio_in_get_dsp_frames(struct audio_in *audio)
+{
+	struct audio_frame *frame;
+	uint32_t index;
+	unsigned long flags;
+
+	index = audio->in_head;
+
+	/* XXX check for bogus frame size? */
+
+	frame = (void *) (((char *)audio->in[index].data) - sizeof(*frame));
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	audio->in[index].size = frame->bytes;
+
+	audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
+
+	/* If overflow, move the tail index foward. */
+	if (audio->in_head == audio->in_tail)
+		audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
+	else
+		audio->in_count++;
+
+	audio_dsp_read_buffer(audio, audio->dsp_cnt++);
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+
+	wake_up(&audio->wait);
+}
+
+static void audrec_dsp_event(void *data, unsigned id, size_t len,
+			    void (*getevent)(void *ptr, size_t len))
+{
+	struct audio_in *audio = data;
+	uint16_t msg[3];
+	getevent(msg, sizeof(msg));
+
+	switch (id) {
+	case AUDREC_MSG_CMD_CFG_DONE_MSG:
+		if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE) {
+			if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_ENA) {
+				pr_info("audpre: CFG ENABLED\n");
+				audio_dsp_set_agc(audio);
+				audio_dsp_set_ns(audio);
+				audio_dsp_set_tx_iir(audio);
+				audio_in_encoder_config(audio);
+			} else {
+				pr_info("audrec: CFG SLEEP\n");
+				audio->running = 0;
+			}
+		} else {
+			pr_info("audrec: CMD_CFG_DONE %x\n", msg[0]);
+		}
+		break;
+	case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
+		pr_info("audrec: PARAM CFG DONE\n");
+		audio->running = 1;
+		break;
+	}
+	case AUDREC_MSG_FATAL_ERR_MSG:
+		pr_err("audrec: ERROR %x\n", msg[0]);
+		break;
+	case AUDREC_MSG_PACKET_READY_MSG:
+/* REC_DBG("type %x, count %d", msg[0], (msg[1] | (msg[2] << 16))); */
+		audio_in_get_dsp_frames(audio);
+		break;
+	default:
+		pr_err("audrec: unknown event %d\n", id);
+	}
+}
+
+struct msm_adsp_ops audpre_adsp_ops = {
+	.event = audpre_dsp_event,
+};
+
+struct msm_adsp_ops audrec_adsp_ops = {
+	.event = audrec_dsp_event,
+};
+
+
+#define audio_send_queue_pre(audio, cmd, len) \
+	msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len)
+#define audio_send_queue_recbs(audio, cmd, len) \
+	msm_adsp_write(audio->audrec, QDSP_uPAudRecBitStreamQueue, cmd, len)
+#define audio_send_queue_rec(audio, cmd, len) \
+	msm_adsp_write(audio->audrec, \
+	QDSP_uPAudRecCmdQueue, cmd, len)
+
+static int audio_dsp_set_agc(struct audio_in *audio)
+{
+	audpreproc_cmd_cfg_agc_params cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS;
+
+	if (audio->agc_enable) {
+		/* cmd.tx_agc_param_mask = 0xFE00 from sample code */
+		cmd.tx_agc_param_mask =
+		(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) |
+		(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) |
+		(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) |
+		(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) |
+		(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) |
+		(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) |
+		(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
+		cmd.tx_agc_enable_flag =
+			AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA;
+		memcpy(&cmd.static_gain, &audio->agc.agc_params[0],
+			sizeof(uint16_t) * 6);
+		/* cmd.param_mask = 0xFFF0 from sample code */
+		cmd.param_mask =
+			(1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) |
+			(1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK);
+		memcpy(&cmd.aig_attackk, &audio->agc.agc_params[6],
+			sizeof(uint16_t) * 14);
+
+	} else {
+		cmd.tx_agc_param_mask =
+			(1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG);
+		cmd.tx_agc_enable_flag =
+			AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS;
+	}
+#if DEBUG
+	pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
+	pr_info("tx_agc_param_mask = 0x%04x\n", cmd.tx_agc_param_mask);
+	pr_info("tx_agc_enable_flag = 0x%04x\n", cmd.tx_agc_enable_flag);
+	pr_info("static_gain = 0x%04x\n", cmd.static_gain);
+	pr_info("adaptive_gain_flag = 0x%04x\n", cmd.adaptive_gain_flag);
+	pr_info("expander_th = 0x%04x\n", cmd.expander_th);
+	pr_info("expander_slope = 0x%04x\n", cmd.expander_slope);
+	pr_info("compressor_th = 0x%04x\n", cmd.compressor_th);
+	pr_info("compressor_slope = 0x%04x\n", cmd.compressor_slope);
+	pr_info("param_mask = 0x%04x\n", cmd.param_mask);
+	pr_info("aig_attackk = 0x%04x\n", cmd.aig_attackk);
+	pr_info("aig_leak_down = 0x%04x\n", cmd.aig_leak_down);
+	pr_info("aig_leak_up = 0x%04x\n", cmd.aig_leak_up);
+	pr_info("aig_max = 0x%04x\n", cmd.aig_max);
+	pr_info("aig_min = 0x%04x\n", cmd.aig_min);
+	pr_info("aig_releasek = 0x%04x\n", cmd.aig_releasek);
+	pr_info("aig_leakrate_fast = 0x%04x\n", cmd.aig_leakrate_fast);
+	pr_info("aig_leakrate_slow = 0x%04x\n", cmd.aig_leakrate_slow);
+	pr_info("attackk_msw = 0x%04x\n", cmd.attackk_msw);
+	pr_info("attackk_lsw = 0x%04x\n", cmd.attackk_lsw);
+	pr_info("delay = 0x%04x\n", cmd.delay);
+	pr_info("releasek_msw = 0x%04x\n", cmd.releasek_msw);
+	pr_info("releasek_lsw = 0x%04x\n", cmd.releasek_lsw);
+	pr_info("rms_tav = 0x%04x\n", cmd.rms_tav);
+#endif
+	return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
+}
+
+static int audio_dsp_set_ns(struct audio_in *audio)
+{
+	audpreproc_cmd_cfg_ns_params cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS;
+
+	if (audio->ns_enable) {
+		/* cmd.ec_mode_new is fixed as 0x0064 when enable from sample code */
+		cmd.ec_mode_new =
+			AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA |
+			AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA |
+			AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA;
+		memcpy(&cmd.dens_gamma_n, &audio->ns.ns_params,
+			sizeof(audio->ns.ns_params));
+	} else {
+		cmd.ec_mode_new =
+			AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS |
+			AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS;
+	}
+#if DEBUG
+	pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
+	pr_info("ec_mode_new = 0x%04x\n", cmd.ec_mode_new);
+	pr_info("dens_gamma_n = 0x%04x\n", cmd.dens_gamma_n);
+	pr_info("dens_nfe_block_size = 0x%04x\n", cmd.dens_nfe_block_size);
+	pr_info("dens_limit_ns = 0x%04x\n", cmd.dens_limit_ns);
+	pr_info("dens_limit_ns_d = 0x%04x\n", cmd.dens_limit_ns_d);
+	pr_info("wb_gamma_e = 0x%04x\n", cmd.wb_gamma_e);
+	pr_info("wb_gamma_n = 0x%04x\n", cmd.wb_gamma_n);
+#endif
+	return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
+}
+
+static int audio_dsp_set_tx_iir(struct audio_in *audio)
+{
+	struct audpre_cmd_iir_config_type cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS;
+
+	if (audio->iir_enable) {
+		cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA;
+		cmd.num_bands = audio->iir.num_bands;
+		memcpy(&cmd.iir_params, &audio->iir.iir_params,
+			sizeof(audio->iir.iir_params));
+	} else {
+		cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS;
+	}
+#if DEBUG
+	pr_info("cmd_id = 0x%04x\n", cmd.cmd_id);
+	pr_info("active_flag = 0x%04x\n", cmd.active_flag);
+#endif
+	return audio_send_queue_pre(audio, &cmd, sizeof(cmd));
+}
+
+static int audio_in_dsp_enable(struct audio_in *audio, int enable)
+{
+	audrec_cmd_cfg cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDREC_CMD_CFG;
+	cmd.type_0 = enable ? AUDREC_CMD_TYPE_0_ENA : AUDREC_CMD_TYPE_0_DIS;
+	cmd.type_0 |= (AUDREC_CMD_TYPE_0_UPDATE | audio->type);
+	cmd.type_1 = 0;
+
+	return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
+}
+
+static int audio_in_encoder_config(struct audio_in *audio)
+{
+	audrec_cmd_arec0param_cfg cmd;
+	uint16_t *data = (void *) audio->data;
+	unsigned n;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDREC_CMD_AREC0PARAM_CFG;
+	cmd.ptr_to_extpkt_buffer_msw = audio->phys >> 16;
+	cmd.ptr_to_extpkt_buffer_lsw = audio->phys;
+	cmd.buf_len = FRAME_NUM; /* Both WAV and AAC use 8 frames */
+	cmd.samp_rate_index = audio->samp_rate_index;
+	cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */
+
+	/* FIXME have no idea why cmd.rec_quality is fixed
+	 * as 0x1C00 from sample code
+	 */
+	cmd.rec_quality = 0x1C00;
+
+	/* prepare buffer pointers:
+	 * Mono: 1024 samples + 4 halfword header
+	 * Stereo: 2048 samples + 4 halfword header
+	 * AAC
+	 * Mono/Stere: 768 + 4 halfword header
+	 */
+	for (n = 0; n < FRAME_NUM; n++) {
+		audio->in[n].data = data + 4;
+		if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
+			data += (4 + (audio->channel_mode ? 2048 : 1024));
+		else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
+			data += (4 + 768);
+	}
+
+	return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
+}
+
+static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt)
+{
+	audrec_cmd_packet_ext_ptr cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR;
+	/* Both WAV and AAC use AUDREC_CMD_TYPE_0 */
+	cmd.type = AUDREC_CMD_TYPE_0;
+	cmd.curr_rec_count_msw = read_cnt >> 16;
+	cmd.curr_rec_count_lsw = read_cnt;
+
+	return audio_send_queue_recbs(audio, &cmd, sizeof(cmd));
+}
+
+/* ------------------- device --------------------- */
+
+static void audio_enable_agc(struct audio_in *audio, int enable)
+{
+	if (audio->agc_enable != enable) {
+		audio->agc_enable = enable;
+		if (audio->running)
+			audio_dsp_set_agc(audio);
+	}
+}
+
+static void audio_enable_ns(struct audio_in *audio, int enable)
+{
+	if (audio->ns_enable != enable) {
+		audio->ns_enable = enable;
+		if (audio->running)
+			audio_dsp_set_ns(audio);
+	}
+}
+
+static void audio_enable_tx_iir(struct audio_in *audio, int enable)
+{
+	if (audio->iir_enable != enable) {
+		audio->iir_enable = enable;
+		if (audio->running)
+			audio_dsp_set_tx_iir(audio);
+	}
+}
+
+static void audio_flush(struct audio_in *audio)
+{
+	int i;
+
+	audio->dsp_cnt = 0;
+	audio->in_head = 0;
+	audio->in_tail = 0;
+	audio->in_count = 0;
+	for (i = 0; i < FRAME_NUM; i++) {
+		audio->in[i].size = 0;
+		audio->in[i].read = 0;
+	}
+}
+
+static long audio_in_ioctl(struct file *file,
+				unsigned int cmd, unsigned long arg)
+{
+	struct audio_in *audio = file->private_data;
+	int rc;
+
+	if (cmd == AUDIO_GET_STATS) {
+		struct msm_audio_stats stats;
+		stats.byte_count = atomic_read(&audio->in_bytes);
+		if (copy_to_user((void *) arg, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
+
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_START:
+		rc = audio_in_enable(audio);
+		break;
+	case AUDIO_STOP:
+		rc = audio_in_disable(audio);
+		audio->stopped = 1;
+		break;
+	case AUDIO_FLUSH:
+		if (audio->stopped) {
+			/* Make sure we're stopped and we wake any threads
+			 * that might be blocked holding the read_lock.
+			 * While audio->stopped read threads will always
+			 * exit immediately.
+			 */
+			wake_up(&audio->wait);
+			mutex_lock(&audio->read_lock);
+			audio_flush(audio);
+			mutex_unlock(&audio->read_lock);
+		}
+	case AUDIO_SET_CONFIG: {
+		struct msm_audio_config cfg;
+		if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
+			rc = -EFAULT;
+			break;
+		}
+		if (cfg.channel_count == 1) {
+			cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO;
+		} else if (cfg.channel_count == 2) {
+			cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO;
+		} else {
+			rc = -EINVAL;
+			break;
+		}
+
+		if (cfg.type == 0) {
+			cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV;
+		} else if (cfg.type == 1) {
+			cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC;
+		} else {
+			rc = -EINVAL;
+			break;
+		}
+		audio->samp_rate = convert_samp_rate(cfg.sample_rate);
+		audio->samp_rate_index =
+		  convert_dsp_samp_index(cfg.sample_rate);
+		audio->channel_mode = cfg.channel_count;
+		audio->buffer_size =
+				audio->channel_mode ? STEREO_DATA_SIZE
+							: MONO_DATA_SIZE;
+		audio->type = cfg.type;
+		rc = 0;
+		break;
+	}
+	case AUDIO_GET_CONFIG: {
+		struct msm_audio_config cfg;
+		cfg.buffer_size = audio->buffer_size;
+		cfg.buffer_count = FRAME_NUM;
+		cfg.sample_rate = convert_samp_index(audio->samp_rate);
+		if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO)
+			cfg.channel_count = 1;
+		else
+			cfg.channel_count = 2;
+		if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
+			cfg.type = 0;
+		else
+			cfg.type = 1;
+		cfg.unused[0] = 0;
+		cfg.unused[1] = 0;
+		cfg.unused[2] = 0;
+		if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
+			rc = -EFAULT;
+		else
+			rc = 0;
+		break;
+	}
+	default:
+		rc = -EINVAL;
+	}
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static ssize_t audio_in_read(struct file *file,
+				char __user *buf,
+				size_t count, loff_t *pos)
+{
+	struct audio_in *audio = file->private_data;
+	unsigned long flags;
+	const char __user *start = buf;
+	void *data;
+	uint32_t index;
+	uint32_t size;
+	int rc = 0;
+
+	mutex_lock(&audio->read_lock);
+	while (count > 0) {
+		rc = wait_event_interruptible(
+			audio->wait, (audio->in_count > 0) || audio->stopped);
+		if (rc < 0)
+			break;
+
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+
+		index = audio->in_tail;
+		data = (uint8_t *) audio->in[index].data;
+		size = audio->in[index].size;
+		if (count >= size) {
+			if (copy_to_user(buf, data, size)) {
+				rc = -EFAULT;
+				break;
+			}
+			spin_lock_irqsave(&audio->dsp_lock, flags);
+			if (index != audio->in_tail) {
+			/* overrun -- data is invalid and we need to retry */
+				spin_unlock_irqrestore(&audio->dsp_lock, flags);
+				continue;
+			}
+			audio->in[index].size = 0;
+			audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
+			audio->in_count--;
+			spin_unlock_irqrestore(&audio->dsp_lock, flags);
+			count -= size;
+			buf += size;
+			if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
+				break;
+		} else {
+			pr_err("audio_in: short read\n");
+			break;
+		}
+		if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
+			break; /* AAC only read one frame */
+	}
+	mutex_unlock(&audio->read_lock);
+
+	if (buf > start)
+		return buf - start;
+
+	return rc;
+}
+
+static ssize_t audio_in_write(struct file *file,
+				const char __user *buf,
+				size_t count, loff_t *pos)
+{
+	return -EINVAL;
+}
+
+static int audio_in_release(struct inode *inode, struct file *file)
+{
+	struct audio_in *audio = file->private_data;
+
+	mutex_lock(&audio->lock);
+	audio_in_disable(audio);
+	audio_flush(audio);
+	msm_adsp_put(audio->audrec);
+	msm_adsp_put(audio->audpre);
+	audio->audrec = NULL;
+	audio->audpre = NULL;
+	audio->opened = 0;
+	mutex_unlock(&audio->lock);
+	return 0;
+}
+
+static struct audio_in the_audio_in;
+
+static int audio_in_open(struct inode *inode, struct file *file)
+{
+	struct audio_in *audio = &the_audio_in;
+	int rc;
+
+	mutex_lock(&audio->lock);
+	if (audio->opened) {
+		rc = -EBUSY;
+		goto done;
+	}
+
+	/* Settings will be re-config at AUDIO_SET_CONFIG,
+	 * but at least we need to have initial config
+	 */
+	audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
+	audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
+	audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
+	audio->buffer_size = MONO_DATA_SIZE;
+	audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV;
+
+	rc = audmgr_open(&audio->audmgr);
+	if (rc)
+		goto done;
+	rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
+				&audpre_adsp_ops, audio);
+	if (rc)
+		goto done;
+	rc = msm_adsp_get("AUDRECTASK", &audio->audrec,
+			   &audrec_adsp_ops, audio);
+	if (rc)
+		goto done;
+
+	audio->dsp_cnt = 0;
+	audio->stopped = 0;
+
+	audio_flush(audio);
+
+	file->private_data = audio;
+	audio->opened = 1;
+	rc = 0;
+done:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct audio_in *audio = file->private_data;
+	int rc = 0, enable;
+	uint16_t enable_mask;
+#if DEBUG
+	int i;
+#endif
+
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_ENABLE_AUDPRE: {
+		if (copy_from_user(&enable_mask, (void *) arg,
+				sizeof(enable_mask)))
+			goto out_fault;
+
+		enable = (enable_mask & AGC_ENABLE) ? 1 : 0;
+		audio_enable_agc(audio, enable);
+		enable = (enable_mask & NS_ENABLE) ? 1 : 0;
+		audio_enable_ns(audio, enable);
+		enable = (enable_mask & IIR_ENABLE) ? 1 : 0;
+		audio_enable_tx_iir(audio, enable);
+		break;
+	}
+	case AUDIO_SET_AGC: {
+		if (copy_from_user(&audio->agc, (void *) arg,
+				sizeof(audio->agc)))
+			goto out_fault;
+#if DEBUG
+		pr_info("set agc\n");
+		for (i = 0; i < AGC_PARAM_SIZE; i++) \
+			pr_info("agc_params[%d] = 0x%04x\n", i,
+				audio->agc.agc_params[i]);
+#endif
+		break;
+	}
+	case AUDIO_SET_NS: {
+		if (copy_from_user(&audio->ns, (void *) arg,
+				sizeof(audio->ns)))
+			goto out_fault;
+#if DEBUG
+		pr_info("set ns\n");
+		for (i = 0; i < NS_PARAM_SIZE; i++) \
+			pr_info("ns_params[%d] = 0x%04x\n",
+				i, audio->ns.ns_params[i]);
+#endif
+		break;
+	}
+	case AUDIO_SET_TX_IIR: {
+		if (copy_from_user(&audio->iir, (void *) arg,
+				sizeof(audio->iir)))
+			goto out_fault;
+#if DEBUG
+		pr_info("set iir\n");
+		pr_info("iir.num_bands = 0x%04x\n", audio->iir.num_bands);
+		for (i = 0; i < IIR_PARAM_SIZE; i++) \
+			pr_info("iir_params[%d] = 0x%04x\n",
+				i, audio->iir.iir_params[i]);
+#endif
+		break;
+	}
+	default:
+		rc = -EINVAL;
+	}
+
+	goto out;
+
+out_fault:
+	rc = -EFAULT;
+out:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static int audpre_open(struct inode *inode, struct file *file)
+{
+	struct audio_in *audio = &the_audio_in;
+	file->private_data = audio;
+	return 0;
+}
+
+static struct file_operations audio_fops = {
+	.owner		= THIS_MODULE,
+	.open		= audio_in_open,
+	.release	= audio_in_release,
+	.read		= audio_in_read,
+	.write		= audio_in_write,
+	.unlocked_ioctl	= audio_in_ioctl,
+};
+
+static struct file_operations audpre_fops = {
+	.owner          = THIS_MODULE,
+	.open           = audpre_open,
+	.unlocked_ioctl = audpre_ioctl,
+};
+
+struct miscdevice audio_in_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_pcm_in",
+	.fops	= &audio_fops,
+};
+
+struct miscdevice audpre_misc = {
+	.minor  = MISC_DYNAMIC_MINOR,
+	.name   = "msm_audpre",
+	.fops   = &audpre_fops,
+};
+
+static int __init audio_in_init(void)
+{
+	int rc;
+	the_audio_in.data = dma_alloc_coherent(NULL, DMASZ,
+					       &the_audio_in.phys, GFP_KERNEL);
+	if (!the_audio_in.data) {
+		printk(KERN_ERR "%s: Unable to allocate DMA buffer\n",
+		       __func__);
+		return -ENOMEM;
+	}
+
+	mutex_init(&the_audio_in.lock);
+	mutex_init(&the_audio_in.read_lock);
+	spin_lock_init(&the_audio_in.dsp_lock);
+	init_waitqueue_head(&the_audio_in.wait);
+	rc = misc_register(&audio_in_misc);
+	if (!rc) {
+		rc = misc_register(&audpre_misc);
+		if (rc < 0)
+			misc_deregister(&audio_in_misc);
+	}
+	return rc;
+}
+
+device_initcall(audio_in_init);
diff --git a/drivers/staging/dream/qdsp5/audio_mp3.c b/drivers/staging/dream/qdsp5/audio_mp3.c
new file mode 100644
index 0000000..b95574f
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audio_mp3.c
@@ -0,0 +1,971 @@
+/* arch/arm/mach-msm/qdsp5/audio_mp3.c
+ *
+ * mp3 audio output device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/delay.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include <mach/msm_adsp.h>
+
+#include <linux/msm_audio.h>
+
+#include "audmgr.h"
+
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audplaycmdi.h>
+#include <mach/qdsp5/qdsp5audplaymsg.h>
+
+/* for queue ids - should be relative to module number*/
+#include "adsp.h"
+
+#ifdef DEBUG
+#define dprintk(format, arg...) \
+printk(KERN_DEBUG format, ## arg)
+#else
+#define dprintk(format, arg...) do {} while (0)
+#endif
+
+/* Size must be power of 2 */
+#define BUFSZ_MAX 32768
+#define BUFSZ_MIN 4096
+#define DMASZ_MAX (BUFSZ_MAX * 2)
+#define DMASZ_MIN (BUFSZ_MIN * 2)
+
+#define AUDPLAY_INVALID_READ_PTR_OFFSET	0xFFFF
+#define AUDDEC_DEC_MP3 2
+
+#define PCM_BUFSZ_MIN 4800	/* Hold one stereo MP3 frame */
+#define PCM_BUF_MAX_COUNT 5	/* DSP only accepts 5 buffers at most
+				   but support 2 buffers currently */
+#define ROUTING_MODE_FTRT 1
+#define ROUTING_MODE_RT 2
+/* Decoder status received from AUDPPTASK */
+#define  AUDPP_DEC_STATUS_SLEEP	0
+#define	 AUDPP_DEC_STATUS_INIT  1
+#define  AUDPP_DEC_STATUS_CFG   2
+#define  AUDPP_DEC_STATUS_PLAY  3
+
+struct buffer {
+	void *data;
+	unsigned size;
+	unsigned used;		/* Input usage actual DSP produced PCM size  */
+	unsigned addr;
+};
+
+struct audio {
+	struct buffer out[2];
+
+	spinlock_t dsp_lock;
+
+	uint8_t out_head;
+	uint8_t out_tail;
+	uint8_t out_needed; /* number of buffers the dsp is waiting for */
+	unsigned out_dma_sz;
+
+	atomic_t out_bytes;
+
+	struct mutex lock;
+	struct mutex write_lock;
+	wait_queue_head_t write_wait;
+
+	/* Host PCM section */
+	struct buffer in[PCM_BUF_MAX_COUNT];
+	struct mutex read_lock;
+	wait_queue_head_t read_wait;	/* Wait queue for read */
+	char *read_data;	/* pointer to reader buffer */
+	dma_addr_t read_phys;	/* physical address of reader buffer */
+	uint8_t read_next;	/* index to input buffers to be read next */
+	uint8_t fill_next;	/* index to buffer that DSP should be filling */
+	uint8_t pcm_buf_count;	/* number of pcm buffer allocated */
+	/* ---- End of Host PCM section */
+
+	struct msm_adsp_module *audplay;
+
+	/* configuration to use on next enable */
+	uint32_t out_sample_rate;
+	uint32_t out_channel_mode;
+
+	struct audmgr audmgr;
+
+	/* data allocated for various buffers */
+	char *data;
+	dma_addr_t phys;
+
+	int rflush; /* Read  flush */
+	int wflush; /* Write flush */
+	int opened;
+	int enabled;
+	int running;
+	int stopped; /* set when stopped, cleared on flush */
+	int pcm_feedback;
+	int buf_refresh;
+
+	int reserved; /* A byte is being reserved */
+	char rsv_byte; /* Handle odd length user data */
+
+	unsigned volume;
+
+	uint16_t dec_id;
+	uint32_t read_ptr_offset;
+};
+
+static int auddec_dsp_config(struct audio *audio, int enable);
+static void audpp_cmd_cfg_adec_params(struct audio *audio);
+static void audpp_cmd_cfg_routing_mode(struct audio *audio);
+static void audplay_send_data(struct audio *audio, unsigned needed);
+static void audplay_config_hostpcm(struct audio *audio);
+static void audplay_buffer_refresh(struct audio *audio);
+static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+
+/* must be called with audio->lock held */
+static int audio_enable(struct audio *audio)
+{
+	struct audmgr_config cfg;
+	int rc;
+
+	pr_info("audio_enable()\n");
+
+	if (audio->enabled)
+		return 0;
+
+	audio->out_tail = 0;
+	audio->out_needed = 0;
+
+	cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
+	cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
+	cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
+	cfg.codec = RPC_AUD_DEF_CODEC_MP3;
+	cfg.snd_method = RPC_SND_METHOD_MIDI;
+
+	rc = audmgr_enable(&audio->audmgr, &cfg);
+	if (rc < 0)
+		return rc;
+
+	if (msm_adsp_enable(audio->audplay)) {
+		pr_err("audio: msm_adsp_enable(audplay) failed\n");
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+
+	if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
+		pr_err("audio: audpp_enable() failed\n");
+		msm_adsp_disable(audio->audplay);
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+
+	audio->enabled = 1;
+	return 0;
+}
+
+/* must be called with audio->lock held */
+static int audio_disable(struct audio *audio)
+{
+	pr_info("audio_disable()\n");
+	if (audio->enabled) {
+		audio->enabled = 0;
+		auddec_dsp_config(audio, 0);
+		wake_up(&audio->write_wait);
+		wake_up(&audio->read_wait);
+		msm_adsp_disable(audio->audplay);
+		audpp_disable(audio->dec_id, audio);
+		audmgr_disable(&audio->audmgr);
+		audio->out_needed = 0;
+	}
+	return 0;
+}
+
+/* ------------------- dsp --------------------- */
+static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
+{
+	uint8_t index;
+	unsigned long flags;
+
+	if (audio->rflush) {
+		audio->buf_refresh = 1;
+		return;
+	}
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	for (index = 0; index < payload[1]; index++) {
+		if (audio->in[audio->fill_next].addr ==
+		    payload[2 + index * 2]) {
+			pr_info("audio_update_pcm_buf_entry: in[%d] ready\n",
+				audio->fill_next);
+			audio->in[audio->fill_next].used =
+			  payload[3 + index * 2];
+			if ((++audio->fill_next) == audio->pcm_buf_count)
+				audio->fill_next = 0;
+
+		} else {
+			pr_err
+			    ("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
+			     , audio->in[audio->fill_next].addr,
+			     payload[1 + index * 2]);
+			break;
+		}
+	}
+	if (audio->in[audio->fill_next].used == 0) {
+		audplay_buffer_refresh(audio);
+	} else {
+		pr_info("audio_update_pcm_buf_entry: read cannot keep up\n");
+		audio->buf_refresh = 1;
+	}
+	wake_up(&audio->read_wait);
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+
+}
+
+static void audplay_dsp_event(void *data, unsigned id, size_t len,
+			      void (*getevent) (void *ptr, size_t len))
+{
+	struct audio *audio = data;
+	uint32_t msg[28];
+	getevent(msg, sizeof(msg));
+
+	dprintk("audplay_dsp_event: msg_id=%x\n", id);
+
+	switch (id) {
+	case AUDPLAY_MSG_DEC_NEEDS_DATA:
+		audplay_send_data(audio, 1);
+		break;
+
+	case AUDPLAY_MSG_BUFFER_UPDATE:
+		audio_update_pcm_buf_entry(audio, msg);
+		break;
+
+	default:
+		pr_err("unexpected message from decoder \n");
+		break;
+	}
+}
+
+static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
+{
+	struct audio *audio = private;
+
+	switch (id) {
+	case AUDPP_MSG_STATUS_MSG:{
+			unsigned status = msg[1];
+
+			switch (status) {
+			case AUDPP_DEC_STATUS_SLEEP:
+				pr_info("decoder status: sleep \n");
+				break;
+
+			case AUDPP_DEC_STATUS_INIT:
+				pr_info("decoder status: init \n");
+				audpp_cmd_cfg_routing_mode(audio);
+				break;
+
+			case AUDPP_DEC_STATUS_CFG:
+				pr_info("decoder status: cfg \n");
+				break;
+			case AUDPP_DEC_STATUS_PLAY:
+				pr_info("decoder status: play \n");
+				if (audio->pcm_feedback) {
+					audplay_config_hostpcm(audio);
+					audplay_buffer_refresh(audio);
+				}
+				break;
+			default:
+				pr_err("unknown decoder status \n");
+				break;
+			}
+      break;
+		}
+	case AUDPP_MSG_CFG_MSG:
+		if (msg[0] == AUDPP_MSG_ENA_ENA) {
+			pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
+			auddec_dsp_config(audio, 1);
+			audio->out_needed = 0;
+			audio->running = 1;
+			audpp_set_volume_and_pan(audio->dec_id, audio->volume,
+						 0);
+			audpp_avsync(audio->dec_id, 22050);
+		} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
+			pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
+			audpp_avsync(audio->dec_id, 0);
+			audio->running = 0;
+		} else {
+			pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
+		}
+		break;
+	case AUDPP_MSG_ROUTING_ACK:
+		pr_info("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
+		audpp_cmd_cfg_adec_params(audio);
+		break;
+
+	case AUDPP_MSG_FLUSH_ACK:
+		dprintk("%s: FLUSH_ACK\n", __func__);
+		audio->wflush = 0;
+		audio->rflush = 0;
+		if (audio->pcm_feedback)
+			audplay_buffer_refresh(audio);
+		break;
+
+	default:
+		pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
+	}
+
+}
+
+
+struct msm_adsp_ops audplay_adsp_ops = {
+	.event = audplay_dsp_event,
+};
+
+
+#define audplay_send_queue0(audio, cmd, len) \
+	msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
+		       cmd, len)
+
+static int auddec_dsp_config(struct audio *audio, int enable)
+{
+	audpp_cmd_cfg_dec_type cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
+	if (enable)
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
+			       AUDPP_CMD_ENA_DEC_V |
+			       AUDDEC_DEC_MP3;
+	else
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
+			       AUDPP_CMD_DIS_DEC_V;
+
+	return audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_adec_params(struct audio *audio)
+{
+	audpp_cmd_cfg_adec_params_mp3 cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
+	cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN;
+	cmd.common.dec_id = audio->dec_id;
+	cmd.common.input_sampling_frequency = audio->out_sample_rate;
+
+	audpp_send_queue2(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_routing_mode(struct audio *audio)
+{
+	struct audpp_cmd_routing_mode cmd;
+	pr_info("audpp_cmd_cfg_routing_mode()\n");
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
+	cmd.object_number = audio->dec_id;
+	if (audio->pcm_feedback)
+		cmd.routing_mode = ROUTING_MODE_FTRT;
+	else
+		cmd.routing_mode = ROUTING_MODE_RT;
+
+	audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static int audplay_dsp_send_data_avail(struct audio *audio,
+					unsigned idx, unsigned len)
+{
+	audplay_cmd_bitstream_data_avail cmd;
+
+	cmd.cmd_id		= AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
+	cmd.decoder_id		= audio->dec_id;
+	cmd.buf_ptr		= audio->out[idx].addr;
+	cmd.buf_size		= len/2;
+	cmd.partition_number	= 0;
+	return audplay_send_queue0(audio, &cmd, sizeof(cmd));
+}
+
+static void audplay_buffer_refresh(struct audio *audio)
+{
+	struct audplay_cmd_buffer_refresh refresh_cmd;
+
+	refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
+	refresh_cmd.num_buffers = 1;
+	refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
+	refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
+	  (audio->in[audio->fill_next].size % 576);	/* Mp3 frame size */
+	refresh_cmd.buf_read_count = 0;
+	pr_info("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
+		refresh_cmd.buf0_address, refresh_cmd.buf0_length);
+	(void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
+}
+
+static void audplay_config_hostpcm(struct audio *audio)
+{
+	struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
+
+	pr_info("audplay_config_hostpcm()\n");
+	cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
+	cfg_cmd.max_buffers = 1;
+	cfg_cmd.byte_swap = 0;
+	cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
+	cfg_cmd.feedback_frequency = 1;
+	cfg_cmd.partition_number = 0;
+	(void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
+
+}
+
+static void audplay_send_data(struct audio *audio, unsigned needed)
+{
+	struct buffer *frame;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	if (!audio->running)
+		goto done;
+
+	if (audio->wflush) {
+		audio->out_needed = 1;
+		goto done;
+	}
+
+	if (needed && !audio->wflush) {
+		/* We were called from the callback because the DSP
+		 * requested more data.  Note that the DSP does want
+		 * more data, and if a buffer was in-flight, mark it
+		 * as available (since the DSP must now be done with
+		 * it).
+		 */
+		audio->out_needed = 1;
+		frame = audio->out + audio->out_tail;
+		if (frame->used == 0xffffffff) {
+		  dprintk("frame %d free\n", audio->out_tail);
+		  frame->used = 0;
+		  audio->out_tail ^= 1;
+		  wake_up(&audio->write_wait);
+		}
+	}
+
+	if (audio->out_needed) {
+		/* If the DSP currently wants data and we have a
+		 * buffer available, we will send it and reset
+		 * the needed flag.  We'll mark the buffer as in-flight
+		 * so that it won't be recycled until the next buffer
+		 * is requested
+		 */
+
+		frame = audio->out + audio->out_tail;
+		if (frame->used) {
+		  BUG_ON(frame->used == 0xffffffff);
+		  dprintk("frame %d busy\n", audio->out_tail);
+		  audplay_dsp_send_data_avail(audio, audio->out_tail,
+					      frame->used);
+		  frame->used = 0xffffffff;
+		  audio->out_needed = 0;
+		}
+	}
+done:
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+}
+
+/* ------------------- device --------------------- */
+
+static void audio_flush(struct audio *audio)
+{
+	audio->out[0].used = 0;
+	audio->out[1].used = 0;
+	audio->out_head = 0;
+	audio->out_tail = 0;
+	audio->reserved = 0;
+	atomic_set(&audio->out_bytes, 0);
+}
+
+static void audio_flush_pcm_buf(struct audio *audio)
+{
+	uint8_t index;
+
+	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
+		audio->in[index].used = 0;
+
+	audio->read_next = 0;
+	audio->fill_next = 0;
+}
+
+static void audio_ioport_reset(struct audio *audio)
+{
+	/* Make sure read/write thread are free from
+	 * sleep and knowing that system is not able
+	 * to process io request at the moment
+	 */
+	wake_up(&audio->write_wait);
+	mutex_lock(&audio->write_lock);
+	audio_flush(audio);
+	mutex_unlock(&audio->write_lock);
+	wake_up(&audio->read_wait);
+	mutex_lock(&audio->read_lock);
+	audio_flush_pcm_buf(audio);
+	mutex_unlock(&audio->read_lock);
+}
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct audio *audio = file->private_data;
+	int rc = 0;
+
+	pr_info("audio_ioctl() cmd = %d\n", cmd);
+
+	if (cmd == AUDIO_GET_STATS) {
+		struct msm_audio_stats stats;
+		stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
+		stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
+		if (copy_to_user((void *) arg, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == AUDIO_SET_VOLUME) {
+		unsigned long flags;
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		audio->volume = arg;
+		if (audio->running)
+			audpp_set_volume_and_pan(audio->dec_id, arg, 0);
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+		return 0;
+	}
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_START:
+		rc = audio_enable(audio);
+		break;
+	case AUDIO_STOP:
+		rc = audio_disable(audio);
+		audio->stopped = 1;
+		audio_ioport_reset(audio);
+		audio->stopped = 0;
+		break;
+	case AUDIO_FLUSH:
+		dprintk("%s: AUDIO_FLUSH\n", __func__);
+		audio->rflush = 1;
+		audio->wflush = 1;
+		audio_ioport_reset(audio);
+		audio->rflush = 0;
+		audio->wflush = 0;
+
+		if (audio->buf_refresh) {
+			audio->buf_refresh = 0;
+			audplay_buffer_refresh(audio);
+		}
+		break;
+
+	case AUDIO_SET_CONFIG: {
+		struct msm_audio_config config;
+		if (copy_from_user(&config, (void *) arg, sizeof(config))) {
+			rc = -EFAULT;
+			break;
+		}
+		if (config.channel_count == 1) {
+			config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
+		} else if (config.channel_count == 2) {
+			config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V;
+		} else {
+			rc = -EINVAL;
+			break;
+		}
+		audio->out_sample_rate = config.sample_rate;
+		audio->out_channel_mode = config.channel_count;
+		rc = 0;
+		break;
+	}
+	case AUDIO_GET_CONFIG: {
+		struct msm_audio_config config;
+		config.buffer_size = (audio->out_dma_sz >> 1);
+		config.buffer_count = 2;
+		config.sample_rate = audio->out_sample_rate;
+		if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
+			config.channel_count = 1;
+		} else {
+			config.channel_count = 2;
+		}
+		config.unused[0] = 0;
+		config.unused[1] = 0;
+		config.unused[2] = 0;
+		config.unused[3] = 0;
+		if (copy_to_user((void *) arg, &config, sizeof(config))) {
+			rc = -EFAULT;
+		} else {
+			rc = 0;
+		}
+		break;
+	}
+	case AUDIO_GET_PCM_CONFIG:{
+		struct msm_audio_pcm_config config;
+		config.pcm_feedback = 0;
+		config.buffer_count = PCM_BUF_MAX_COUNT;
+		config.buffer_size = PCM_BUFSZ_MIN;
+		if (copy_to_user((void *)arg, &config,
+			 sizeof(config)))
+			rc = -EFAULT;
+		else
+			rc = 0;
+		break;
+	}
+	case AUDIO_SET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+			if (copy_from_user
+			    (&config, (void *)arg, sizeof(config))) {
+				rc = -EFAULT;
+				break;
+			}
+			if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
+			    (config.buffer_count == 1))
+				config.buffer_count = PCM_BUF_MAX_COUNT;
+
+			if (config.buffer_size < PCM_BUFSZ_MIN)
+				config.buffer_size = PCM_BUFSZ_MIN;
+
+			/* Check if pcm feedback is required */
+			if ((config.pcm_feedback) && (!audio->read_data)) {
+				pr_info("ioctl: allocate PCM buffer %d\n",
+					config.buffer_count *
+					config.buffer_size);
+				audio->read_data =
+				    dma_alloc_coherent(NULL,
+						       config.buffer_size *
+						       config.buffer_count,
+						       &audio->read_phys,
+						       GFP_KERNEL);
+				if (!audio->read_data) {
+					pr_err("audio_mp3: malloc pcm \
+					buf failed\n");
+					rc = -1;
+				} else {
+					uint8_t index;
+					uint32_t offset = 0;
+					audio->pcm_feedback = 1;
+					audio->buf_refresh = 0;
+					audio->pcm_buf_count =
+					    config.buffer_count;
+					audio->read_next = 0;
+					audio->fill_next = 0;
+
+					for (index = 0;
+					     index < config.buffer_count;
+					     index++) {
+						audio->in[index].data =
+						    audio->read_data + offset;
+						audio->in[index].addr =
+						    audio->read_phys + offset;
+						audio->in[index].size =
+						    config.buffer_size;
+						audio->in[index].used = 0;
+						offset += config.buffer_size;
+					}
+					rc = 0;
+				}
+			} else {
+				rc = 0;
+			}
+			break;
+		}
+	case AUDIO_PAUSE:
+		dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
+		rc = audpp_pause(audio->dec_id, (int) arg);
+		break;
+	default:
+		rc = -EINVAL;
+	}
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
+			  loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	int rc = 0;
+
+	if (!audio->pcm_feedback)
+		return 0; /* PCM feedback disabled. Nothing to read */
+
+	mutex_lock(&audio->read_lock);
+	pr_info("audio_read() %d \n", count);
+	while (count > 0) {
+		rc = wait_event_interruptible(audio->read_wait,
+					      (audio->in[audio->read_next].
+					       used > 0) || (audio->stopped)
+						   || (audio->rflush));
+
+		if (rc < 0)
+			break;
+
+		if (audio->stopped || audio->rflush) {
+			rc = -EBUSY;
+			break;
+		}
+
+		if (count < audio->in[audio->read_next].used) {
+			/* Read must happen in frame boundary. Since
+			 * driver does not know frame size, read count
+			 * must be greater or equal
+			 * to size of PCM samples
+			 */
+			pr_info("audio_read: no partial frame done reading\n");
+			break;
+		} else {
+			pr_info("audio_read: read from in[%d]\n",
+				audio->read_next);
+			if (copy_to_user
+			    (buf, audio->in[audio->read_next].data,
+			     audio->in[audio->read_next].used)) {
+				pr_err("audio_read: invalid addr %x \n",
+				       (unsigned int)buf);
+				rc = -EFAULT;
+				break;
+			}
+			count -= audio->in[audio->read_next].used;
+			buf += audio->in[audio->read_next].used;
+			audio->in[audio->read_next].used = 0;
+			if ((++audio->read_next) == audio->pcm_buf_count)
+				audio->read_next = 0;
+			if (audio->in[audio->read_next].used == 0)
+				break; /* No data ready at this moment
+					* Exit while loop to prevent
+					* output thread sleep too long
+					*/
+		}
+	}
+
+	/* don't feed output buffer to HW decoder during flushing
+	 * buffer refresh command will be sent once flush completes
+	 * send buf refresh command here can confuse HW decoder
+	 */
+	if (audio->buf_refresh && !audio->rflush) {
+		audio->buf_refresh = 0;
+		pr_info("audio_read: kick start pcm feedback again\n");
+		audplay_buffer_refresh(audio);
+	}
+
+	mutex_unlock(&audio->read_lock);
+
+	if (buf > start)
+		rc = buf - start;
+
+	pr_info("audio_read: read %d bytes\n", rc);
+	return rc;
+}
+
+static ssize_t audio_write(struct file *file, const char __user *buf,
+			   size_t count, loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	struct buffer *frame;
+	size_t xfer;
+	char *cpy_ptr;
+	int rc = 0;
+	unsigned dsize;
+
+	mutex_lock(&audio->write_lock);
+	while (count > 0) {
+		frame = audio->out + audio->out_head;
+		cpy_ptr = frame->data;
+		dsize = 0;
+		rc = wait_event_interruptible(audio->write_wait,
+					      (frame->used == 0)
+					      || (audio->stopped)
+						  || (audio->wflush));
+		if (rc < 0)
+			break;
+		if (audio->stopped || audio->wflush) {
+			rc = -EBUSY;
+			break;
+		}
+
+		if (audio->reserved) {
+			dprintk("%s: append reserved byte %x\n",
+				__func__, audio->rsv_byte);
+			*cpy_ptr = audio->rsv_byte;
+			xfer = (count > (frame->size - 1)) ?
+				frame->size - 1 : count;
+			cpy_ptr++;
+			dsize = 1;
+			audio->reserved = 0;
+		} else
+			xfer = (count > frame->size) ? frame->size : count;
+
+		if (copy_from_user(cpy_ptr, buf, xfer)) {
+			rc = -EFAULT;
+			break;
+		}
+
+		dsize += xfer;
+		if (dsize & 1) {
+			audio->rsv_byte = ((char *) frame->data)[dsize - 1];
+			dprintk("%s: odd length buf reserve last byte %x\n",
+				__func__, audio->rsv_byte);
+			audio->reserved = 1;
+			dsize--;
+		}
+		count -= xfer;
+		buf += xfer;
+
+		if (dsize > 0) {
+			audio->out_head ^= 1;
+			frame->used = dsize;
+			audplay_send_data(audio, 0);
+		}
+	}
+	mutex_unlock(&audio->write_lock);
+	if (buf > start)
+		return buf - start;
+	return rc;
+}
+
+static int audio_release(struct inode *inode, struct file *file)
+{
+	struct audio *audio = file->private_data;
+
+	dprintk("audio_release()\n");
+
+	mutex_lock(&audio->lock);
+	audio_disable(audio);
+	audio_flush(audio);
+	audio_flush_pcm_buf(audio);
+	msm_adsp_put(audio->audplay);
+	audio->audplay = NULL;
+	audio->opened = 0;
+	audio->reserved = 0;
+	dma_free_coherent(NULL, audio->out_dma_sz, audio->data, audio->phys);
+	audio->data = NULL;
+	if (audio->read_data != NULL) {
+		dma_free_coherent(NULL,
+				  audio->in[0].size * audio->pcm_buf_count,
+				  audio->read_data, audio->read_phys);
+		audio->read_data = NULL;
+	}
+	audio->pcm_feedback = 0;
+	mutex_unlock(&audio->lock);
+	return 0;
+}
+
+static struct audio the_mp3_audio;
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+	struct audio *audio = &the_mp3_audio;
+	int rc;
+	unsigned pmem_sz;
+
+	mutex_lock(&audio->lock);
+
+	if (audio->opened) {
+		pr_err("audio: busy\n");
+		rc = -EBUSY;
+		goto done;
+	}
+
+	pmem_sz = DMASZ_MAX;
+
+	while (pmem_sz >= DMASZ_MIN) {
+		audio->data = dma_alloc_coherent(NULL, pmem_sz,
+						 &audio->phys, GFP_KERNEL);
+		if (audio->data)
+			break;
+		else if (pmem_sz == DMASZ_MIN) {
+			pr_err("audio: could not allocate DMA buffers\n");
+			rc = -ENOMEM;
+			goto done;
+		} else
+			pmem_sz >>= 1;
+	}
+
+	dprintk("%s: allocated %d bytes DMA buffer\n", __func__, pmem_sz);
+
+	rc = audmgr_open(&audio->audmgr);
+	if (rc) {
+		dma_free_coherent(NULL, pmem_sz,
+		audio->data, audio->phys);
+		goto done;
+	}
+
+	rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, &audplay_adsp_ops,
+			  audio);
+	if (rc) {
+		pr_err("audio: failed to get audplay0 dsp module\n");
+		dma_free_coherent(NULL, pmem_sz,
+		audio->data, audio->phys);
+		audmgr_close(&audio->audmgr);
+		goto done;
+	}
+
+	audio->out_dma_sz = pmem_sz;
+	pmem_sz >>= 1; /* Shift by 1 to get size of ping pong buffer */
+
+	audio->out_sample_rate = 44100;
+	audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
+	audio->dec_id = 0;
+
+	audio->out[0].data = audio->data + 0;
+	audio->out[0].addr = audio->phys + 0;
+	audio->out[0].size = pmem_sz;
+
+	audio->out[1].data = audio->data + pmem_sz;
+	audio->out[1].addr = audio->phys + pmem_sz;
+	audio->out[1].size = pmem_sz;
+
+	audio->volume = 0x2000;	/* equal to Q13 number 1.0 Unit Gain */
+
+	audio_flush(audio);
+
+	file->private_data = audio;
+	audio->opened = 1;
+	rc = 0;
+done:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static struct file_operations audio_mp3_fops = {
+	.owner		= THIS_MODULE,
+	.open		= audio_open,
+	.release	= audio_release,
+	.read		= audio_read,
+	.write		= audio_write,
+	.unlocked_ioctl	= audio_ioctl,
+};
+
+struct miscdevice audio_mp3_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_mp3",
+	.fops	= &audio_mp3_fops,
+};
+
+static int __init audio_init(void)
+{
+	mutex_init(&the_mp3_audio.lock);
+	mutex_init(&the_mp3_audio.write_lock);
+	mutex_init(&the_mp3_audio.read_lock);
+	spin_lock_init(&the_mp3_audio.dsp_lock);
+	init_waitqueue_head(&the_mp3_audio.write_wait);
+	init_waitqueue_head(&the_mp3_audio.read_wait);
+	the_mp3_audio.read_data = NULL;
+	return misc_register(&audio_mp3_misc);
+}
+
+device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_out.c b/drivers/staging/dream/qdsp5/audio_out.c
new file mode 100644
index 0000000..d1adcf6
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audio_out.c
@@ -0,0 +1,851 @@
+/* arch/arm/mach-msm/qdsp5/audio_out.c
+ *
+ * pcm audio output device
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/wakelock.h>
+
+#include <linux/msm_audio.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include <mach/msm_adsp.h>
+
+#include "audmgr.h"
+
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+
+#include <mach/htc_pwrsink.h>
+
+#include "evlog.h"
+
+#define LOG_AUDIO_EVENTS 1
+#define LOG_AUDIO_FAULTS 0
+
+enum {
+	EV_NULL,
+	EV_OPEN,
+	EV_WRITE,
+	EV_RETURN,
+	EV_IOCTL,
+	EV_WRITE_WAIT,
+	EV_WAIT_EVENT,
+	EV_FILL_BUFFER,
+	EV_SEND_BUFFER,
+	EV_DSP_EVENT,
+	EV_ENABLE,
+};
+
+#if (LOG_AUDIO_EVENTS != 1)
+static inline void LOG(unsigned id, unsigned arg) {}
+#else
+static const char *pcm_log_strings[] = {
+	"NULL",
+	"OPEN",
+	"WRITE",
+	"RETURN",
+	"IOCTL",
+	"WRITE_WAIT",
+	"WAIT_EVENT",
+	"FILL_BUFFER",
+	"SEND_BUFFER",
+	"DSP_EVENT",
+	"ENABLE",
+};
+
+DECLARE_LOG(pcm_log, 64, pcm_log_strings);
+
+static int __init _pcm_log_init(void)
+{
+	return ev_log_init(&pcm_log);
+}
+module_init(_pcm_log_init);
+
+#define LOG(id,arg) ev_log_write(&pcm_log, id, arg)
+#endif
+
+
+
+
+
+#define BUFSZ (960 * 5)
+#define DMASZ (BUFSZ * 2)
+
+#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
+#define AUDPP_CMD_EQ_FLAG_DIS	0x0000
+#define AUDPP_CMD_EQ_FLAG_ENA	-1
+#define AUDPP_CMD_IIR_FLAG_DIS	  0x0000
+#define AUDPP_CMD_IIR_FLAG_ENA	  -1
+
+#define AUDPP_CMD_IIR_TUNING_FILTER  1
+#define AUDPP_CMD_EQUALIZER	2
+#define AUDPP_CMD_ADRC	3
+
+#define ADRC_ENABLE  0x0001
+#define EQ_ENABLE    0x0002
+#define IIR_ENABLE   0x0004
+
+struct adrc_filter {
+	uint16_t compression_th;
+	uint16_t compression_slope;
+	uint16_t rms_time;
+	uint16_t attack_const_lsw;
+	uint16_t attack_const_msw;
+	uint16_t release_const_lsw;
+	uint16_t release_const_msw;
+	uint16_t adrc_system_delay;
+};
+
+struct eqalizer {
+	uint16_t num_bands;
+	uint16_t eq_params[132];
+};
+
+struct rx_iir_filter {
+	uint16_t num_bands;
+	uint16_t iir_params[48];
+};
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common common;
+	uint16_t eq_flag;
+	uint16_t num_bands;
+	uint16_t eq_params[132];
+} audpp_cmd_cfg_object_params_eq;
+
+typedef struct {
+	audpp_cmd_cfg_object_params_common common;
+	uint16_t active_flag;
+	uint16_t num_bands;
+	uint16_t iir_params[48];
+} audpp_cmd_cfg_object_params_rx_iir;
+
+struct buffer {
+	void *data;
+	unsigned size;
+	unsigned used;
+	unsigned addr;
+};
+
+struct audio {
+	struct buffer out[2];
+
+	spinlock_t dsp_lock;
+
+	uint8_t out_head;
+	uint8_t out_tail;
+	uint8_t out_needed; /* number of buffers the dsp is waiting for */
+
+	atomic_t out_bytes;
+
+	struct mutex lock;
+	struct mutex write_lock;
+	wait_queue_head_t wait;
+
+	/* configuration to use on next enable */
+	uint32_t out_sample_rate;
+	uint32_t out_channel_mode;
+	uint32_t out_weight;
+	uint32_t out_buffer_size;
+
+	struct audmgr audmgr;
+
+	/* data allocated for various buffers */
+	char *data;
+	dma_addr_t phys;
+
+	int opened;
+	int enabled;
+	int running;
+	int stopped; /* set when stopped, cleared on flush */
+	unsigned volume;
+
+	struct wake_lock wakelock;
+	struct wake_lock idlelock;
+
+	int adrc_enable;
+	struct adrc_filter adrc;
+
+	int eq_enable;
+	struct eqalizer eq;
+
+	int rx_iir_enable;
+	struct rx_iir_filter iir;
+};
+
+static void audio_prevent_sleep(struct audio *audio)
+{
+	printk(KERN_INFO "++++++++++++++++++++++++++++++\n");
+	wake_lock(&audio->wakelock);
+	wake_lock(&audio->idlelock);
+}
+
+static void audio_allow_sleep(struct audio *audio)
+{
+	wake_unlock(&audio->wakelock);
+	wake_unlock(&audio->idlelock);
+	printk(KERN_INFO "------------------------------\n");
+}
+
+static int audio_dsp_out_enable(struct audio *audio, int yes);
+static int audio_dsp_send_buffer(struct audio *audio, unsigned id, unsigned len);
+static int audio_dsp_set_adrc(struct audio *audio);
+static int audio_dsp_set_eq(struct audio *audio);
+static int audio_dsp_set_rx_iir(struct audio *audio);
+
+static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
+
+/* must be called with audio->lock held */
+static int audio_enable(struct audio *audio)
+{
+	struct audmgr_config cfg;
+	int rc;
+
+	pr_info("audio_enable()\n");
+
+	if (audio->enabled)
+		return 0;
+
+	/* refuse to start if we're not ready */
+	if (!audio->out[0].used || !audio->out[1].used)
+		return -EIO;
+
+	/* we start buffers 0 and 1, so buffer 0 will be the
+	 * next one the dsp will want
+	 */
+	audio->out_tail = 0;
+	audio->out_needed = 0;
+
+	cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
+	cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
+	cfg.def_method = RPC_AUD_DEF_METHOD_HOST_PCM;
+	cfg.codec = RPC_AUD_DEF_CODEC_PCM;
+	cfg.snd_method = RPC_SND_METHOD_MIDI;
+
+	audio_prevent_sleep(audio);
+	rc = audmgr_enable(&audio->audmgr, &cfg);
+	if (rc < 0) {
+		audio_allow_sleep(audio);
+		return rc;
+	}
+
+	if (audpp_enable(-1, audio_dsp_event, audio)) {
+		pr_err("audio: audpp_enable() failed\n");
+		audmgr_disable(&audio->audmgr);
+		audio_allow_sleep(audio);
+		return -ENODEV;
+	}
+
+	audio->enabled = 1;
+	htc_pwrsink_set(PWRSINK_AUDIO, 100);
+	return 0;
+}
+
+/* must be called with audio->lock held */
+static int audio_disable(struct audio *audio)
+{
+	pr_info("audio_disable()\n");
+	if (audio->enabled) {
+		audio->enabled = 0;
+		audio_dsp_out_enable(audio, 0);
+
+		audpp_disable(-1, audio);
+
+		wake_up(&audio->wait);
+		audmgr_disable(&audio->audmgr);
+		audio->out_needed = 0;
+		audio_allow_sleep(audio);
+	}
+	return 0;
+}
+
+/* ------------------- dsp --------------------- */
+static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
+{
+	struct audio *audio = private;
+	struct buffer *frame;
+	unsigned long flags;
+
+	LOG(EV_DSP_EVENT, id);
+	switch (id) {
+	case AUDPP_MSG_HOST_PCM_INTF_MSG: {
+		unsigned id = msg[2];
+		unsigned idx = msg[3] - 1;
+
+		/* pr_info("audio_dsp_event: HOST_PCM id %d idx %d\n", id, idx); */
+		if (id != AUDPP_MSG_HOSTPCM_ID_ARM_RX) {
+			pr_err("bogus id\n");
+			break;
+		}
+		if (idx > 1) {
+			pr_err("bogus buffer idx\n");
+			break;
+		}
+
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		if (audio->running) {
+			atomic_add(audio->out[idx].used, &audio->out_bytes);
+			audio->out[idx].used = 0;
+
+			frame = audio->out + audio->out_tail;
+			if (frame->used) {
+				audio_dsp_send_buffer(
+					audio, audio->out_tail, frame->used);
+				audio->out_tail ^= 1;
+			} else {
+				audio->out_needed++;
+			}
+			wake_up(&audio->wait);
+		}
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+		break;
+	}
+	case AUDPP_MSG_PCMDMAMISSED:
+		pr_info("audio_dsp_event: PCMDMAMISSED %d\n", msg[0]);
+		break;
+	case AUDPP_MSG_CFG_MSG:
+		if (msg[0] == AUDPP_MSG_ENA_ENA) {
+			LOG(EV_ENABLE, 1);
+			pr_info("audio_dsp_event: CFG_MSG ENABLE\n");
+			audio->out_needed = 0;
+			audio->running = 1;
+			audpp_set_volume_and_pan(5, audio->volume, 0);
+			audio_dsp_set_adrc(audio);
+			audio_dsp_set_eq(audio);
+			audio_dsp_set_rx_iir(audio);
+			audio_dsp_out_enable(audio, 1);
+		} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
+			LOG(EV_ENABLE, 0);
+			pr_info("audio_dsp_event: CFG_MSG DISABLE\n");
+			audio->running = 0;
+		} else {
+			pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
+		}
+		break;
+	default:
+		pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
+	}
+}
+
+static int audio_dsp_out_enable(struct audio *audio, int yes)
+{
+	audpp_cmd_pcm_intf cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id	= AUDPP_CMD_PCM_INTF_2;
+	cmd.object_num	= AUDPP_CMD_PCM_INTF_OBJECT_NUM;
+	cmd.config	= AUDPP_CMD_PCM_INTF_CONFIG_CMD_V;
+	cmd.intf_type	= AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
+
+	if (yes) {
+		cmd.write_buf1LSW	= audio->out[0].addr;
+		cmd.write_buf1MSW	= audio->out[0].addr >> 16;
+		cmd.write_buf1_len	= audio->out[0].size;
+		cmd.write_buf2LSW	= audio->out[1].addr;
+		cmd.write_buf2MSW	= audio->out[1].addr >> 16;
+		cmd.write_buf2_len	= audio->out[1].size;
+		cmd.arm_to_rx_flag	= AUDPP_CMD_PCM_INTF_ENA_V;
+		cmd.weight_decoder_to_rx = audio->out_weight;
+		cmd.weight_arm_to_rx	= 1;
+		cmd.partition_number_arm_to_dsp = 0;
+		cmd.sample_rate		= audio->out_sample_rate;
+		cmd.channel_mode	= audio->out_channel_mode;
+	}
+
+	return audpp_send_queue2(&cmd, sizeof(cmd));
+}
+
+static int audio_dsp_send_buffer(struct audio *audio, unsigned idx, unsigned len)
+{
+	audpp_cmd_pcm_intf_send_buffer cmd;
+
+	cmd.cmd_id		= AUDPP_CMD_PCM_INTF_2;
+	cmd.host_pcm_object	= AUDPP_CMD_PCM_INTF_OBJECT_NUM;
+	cmd.config		= AUDPP_CMD_PCM_INTF_BUFFER_CMD_V;
+	cmd.intf_type		= AUDPP_CMD_PCM_INTF_RX_ENA_ARMTODSP_V;
+	cmd.dsp_to_arm_buf_id	= 0;
+	cmd.arm_to_dsp_buf_id	= idx + 1;
+	cmd.arm_to_dsp_buf_len	= len;
+
+	LOG(EV_SEND_BUFFER, idx);
+	return audpp_send_queue2(&cmd, sizeof(cmd));
+}
+
+static int audio_dsp_set_adrc(struct audio *audio)
+{
+	audpp_cmd_cfg_object_params_adrc cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_CMD_ADRC;
+
+	if (audio->adrc_enable) {
+		cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_ENA;
+		cmd.compression_th = audio->adrc.compression_th;
+		cmd.compression_slope = audio->adrc.compression_slope;
+		cmd.rms_time = audio->adrc.rms_time;
+		cmd.attack_const_lsw = audio->adrc.attack_const_lsw;
+		cmd.attack_const_msw = audio->adrc.attack_const_msw;
+		cmd.release_const_lsw = audio->adrc.release_const_lsw;
+		cmd.release_const_msw = audio->adrc.release_const_msw;
+		cmd.adrc_system_delay = audio->adrc.adrc_system_delay;
+	} else {
+		cmd.adrc_flag = AUDPP_CMD_ADRC_FLAG_DIS;
+	}
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+
+static int audio_dsp_set_eq(struct audio *audio)
+{
+	audpp_cmd_cfg_object_params_eq cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_CMD_EQUALIZER;
+
+	if (audio->eq_enable) {
+		cmd.eq_flag = AUDPP_CMD_EQ_FLAG_ENA;
+		cmd.num_bands = audio->eq.num_bands;
+		memcpy(&cmd.eq_params, audio->eq.eq_params,
+		       sizeof(audio->eq.eq_params));
+	} else {
+		cmd.eq_flag = AUDPP_CMD_EQ_FLAG_DIS;
+	}
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+
+static int audio_dsp_set_rx_iir(struct audio *audio)
+{
+	audpp_cmd_cfg_object_params_rx_iir cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_CMD_IIR_TUNING_FILTER;
+
+	if (audio->rx_iir_enable) {
+		cmd.active_flag = AUDPP_CMD_IIR_FLAG_ENA;
+		cmd.num_bands = audio->iir.num_bands;
+		memcpy(&cmd.iir_params, audio->iir.iir_params,
+		       sizeof(audio->iir.iir_params));
+	} else {
+		cmd.active_flag = AUDPP_CMD_IIR_FLAG_DIS;
+	}
+
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+
+/* ------------------- device --------------------- */
+
+static int audio_enable_adrc(struct audio *audio, int enable)
+{
+	if (audio->adrc_enable != enable) {
+		audio->adrc_enable = enable;
+		if (audio->running)
+			audio_dsp_set_adrc(audio);
+	}
+	return 0;
+}
+
+static int audio_enable_eq(struct audio *audio, int enable)
+{
+	if (audio->eq_enable != enable) {
+		audio->eq_enable = enable;
+		if (audio->running)
+			audio_dsp_set_eq(audio);
+	}
+	return 0;
+}
+
+static int audio_enable_rx_iir(struct audio *audio, int enable)
+{
+	if (audio->rx_iir_enable != enable) {
+		audio->rx_iir_enable = enable;
+		if (audio->running)
+			audio_dsp_set_rx_iir(audio);
+	}
+	return 0;
+}
+
+static void audio_flush(struct audio *audio)
+{
+	audio->out[0].used = 0;
+	audio->out[1].used = 0;
+	audio->out_head = 0;
+	audio->out_tail = 0;
+	audio->stopped = 0;
+}
+
+static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct audio *audio = file->private_data;
+	int rc;
+
+	if (cmd == AUDIO_GET_STATS) {
+		struct msm_audio_stats stats;
+		stats.byte_count = atomic_read(&audio->out_bytes);
+		if (copy_to_user((void*) arg, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == AUDIO_SET_VOLUME) {
+		unsigned long flags;
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		audio->volume = arg;
+		if (audio->running)
+			audpp_set_volume_and_pan(6, arg, 0);
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+	}
+
+	LOG(EV_IOCTL, cmd);
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_START:
+		rc = audio_enable(audio);
+		break;
+	case AUDIO_STOP:
+		rc = audio_disable(audio);
+		audio->stopped = 1;
+		break;
+	case AUDIO_FLUSH:
+		if (audio->stopped) {
+			/* Make sure we're stopped and we wake any threads
+			 * that might be blocked holding the write_lock.
+			 * While audio->stopped write threads will always
+			 * exit immediately.
+			 */
+			wake_up(&audio->wait);
+			mutex_lock(&audio->write_lock);
+			audio_flush(audio);
+			mutex_unlock(&audio->write_lock);
+		}
+	case AUDIO_SET_CONFIG: {
+		struct msm_audio_config config;
+		if (copy_from_user(&config, (void*) arg, sizeof(config))) {
+			rc = -EFAULT;
+			break;
+		}
+		if (config.channel_count == 1) {
+			config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
+		} else if (config.channel_count == 2) {
+			config.channel_count= AUDPP_CMD_PCM_INTF_STEREO_V;
+		} else {
+			rc = -EINVAL;
+			break;
+		}
+		audio->out_sample_rate = config.sample_rate;
+		audio->out_channel_mode = config.channel_count;
+		rc = 0;
+		break;
+	}
+	case AUDIO_GET_CONFIG: {
+		struct msm_audio_config config;
+		config.buffer_size = BUFSZ;
+		config.buffer_count = 2;
+		config.sample_rate = audio->out_sample_rate;
+		if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V) {
+			config.channel_count = 1;
+		} else {
+			config.channel_count = 2;
+		}
+		config.unused[0] = 0;
+		config.unused[1] = 0;
+		config.unused[2] = 0;
+		config.unused[3] = 0;
+		if (copy_to_user((void*) arg, &config, sizeof(config))) {
+			rc = -EFAULT;
+		} else {
+			rc = 0;
+		}
+		break;
+	}
+	default:
+		rc = -EINVAL;
+	}
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static ssize_t audio_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
+{
+	return -EINVAL;
+}
+
+static inline int rt_policy(int policy)
+{
+	if (unlikely(policy == SCHED_FIFO) || unlikely(policy == SCHED_RR))
+		return 1;
+	return 0;
+}
+
+static inline int task_has_rt_policy(struct task_struct *p)
+{
+	return rt_policy(p->policy);
+}
+
+static ssize_t audio_write(struct file *file, const char __user *buf,
+			   size_t count, loff_t *pos)
+{
+	struct sched_param s = { .sched_priority = 1 };
+	struct audio *audio = file->private_data;
+	unsigned long flags;
+	const char __user *start = buf;
+	struct buffer *frame;
+	size_t xfer;
+	int old_prio = current->rt_priority;
+	int old_policy = current->policy;
+	int cap_nice = cap_raised(current_cap(), CAP_SYS_NICE);
+	int rc = 0;
+
+	LOG(EV_WRITE, count | (audio->running << 28) | (audio->stopped << 24));
+
+	/* just for this write, set us real-time */
+	if (!task_has_rt_policy(current)) {
+		struct cred *new = prepare_creds();
+		cap_raise(new->cap_effective, CAP_SYS_NICE);
+		commit_creds(new);
+		sched_setscheduler(current, SCHED_RR, &s);
+	}
+
+	mutex_lock(&audio->write_lock);
+	while (count > 0) {
+		frame = audio->out + audio->out_head;
+
+		LOG(EV_WAIT_EVENT, 0);
+		rc = wait_event_interruptible(audio->wait,
+					      (frame->used == 0) || (audio->stopped));
+		LOG(EV_WAIT_EVENT, 1);
+
+		if (rc < 0)
+			break;
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+		xfer = count > frame->size ? frame->size : count;
+		if (copy_from_user(frame->data, buf, xfer)) {
+			rc = -EFAULT;
+			break;
+		}
+		frame->used = xfer;
+		audio->out_head ^= 1;
+		count -= xfer;
+		buf += xfer;
+
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		LOG(EV_FILL_BUFFER, audio->out_head ^ 1);
+		frame = audio->out + audio->out_tail;
+		if (frame->used && audio->out_needed) {
+			audio_dsp_send_buffer(audio, audio->out_tail, frame->used);
+			audio->out_tail ^= 1;
+			audio->out_needed--;
+		}
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+	}
+
+	mutex_unlock(&audio->write_lock);
+
+	/* restore scheduling policy and priority */
+	if (!rt_policy(old_policy)) {
+		struct sched_param v = { .sched_priority = old_prio };
+		sched_setscheduler(current, old_policy, &v);
+		if (likely(!cap_nice)) {
+			struct cred *new = prepare_creds();
+			cap_lower(new->cap_effective, CAP_SYS_NICE);
+			commit_creds(new);
+			sched_setscheduler(current, SCHED_RR, &s);
+		}
+	}
+
+	LOG(EV_RETURN,(buf > start) ? (buf - start) : rc);
+	if (buf > start)
+		return buf - start;
+	return rc;
+}
+
+static int audio_release(struct inode *inode, struct file *file)
+{
+	struct audio *audio = file->private_data;
+
+	LOG(EV_OPEN, 0);
+	mutex_lock(&audio->lock);
+	audio_disable(audio);
+	audio_flush(audio);
+	audio->opened = 0;
+	mutex_unlock(&audio->lock);
+	htc_pwrsink_set(PWRSINK_AUDIO, 0);
+	return 0;
+}
+
+static struct audio the_audio;
+
+static int audio_open(struct inode *inode, struct file *file)
+{
+	struct audio *audio = &the_audio;
+	int rc;
+
+	mutex_lock(&audio->lock);
+
+	if (audio->opened) {
+		pr_err("audio: busy\n");
+		rc = -EBUSY;
+		goto done;
+	}
+
+	if (!audio->data) {
+		audio->data = dma_alloc_coherent(NULL, DMASZ,
+						 &audio->phys, GFP_KERNEL);
+		if (!audio->data) {
+			pr_err("audio: could not allocate DMA buffers\n");
+			rc = -ENOMEM;
+			goto done;
+		}
+	}
+
+	rc = audmgr_open(&audio->audmgr);
+	if (rc)
+		goto done;
+
+	audio->out_buffer_size = BUFSZ;
+	audio->out_sample_rate = 44100;
+	audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
+	audio->out_weight = 100;
+
+	audio->out[0].data = audio->data + 0;
+	audio->out[0].addr = audio->phys + 0;
+	audio->out[0].size = BUFSZ;
+
+	audio->out[1].data = audio->data + BUFSZ;
+	audio->out[1].addr = audio->phys + BUFSZ;
+	audio->out[1].size = BUFSZ;
+
+	audio->volume = 0x2000;
+
+	audio_flush(audio);
+
+	file->private_data = audio;
+	audio->opened = 1;
+	rc = 0;
+	LOG(EV_OPEN, 1);
+done:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static long audpp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct audio *audio = file->private_data;
+	int rc = 0, enable;
+	uint16_t enable_mask;
+
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_ENABLE_AUDPP:
+		if (copy_from_user(&enable_mask, (void *) arg, sizeof(enable_mask)))
+			goto out_fault;
+
+		enable = (enable_mask & ADRC_ENABLE)? 1 : 0;
+		audio_enable_adrc(audio, enable);
+		enable = (enable_mask & EQ_ENABLE)? 1 : 0;
+		audio_enable_eq(audio, enable);
+		enable = (enable_mask & IIR_ENABLE)? 1 : 0;
+		audio_enable_rx_iir(audio, enable);
+		break;
+
+	case AUDIO_SET_ADRC:
+		if (copy_from_user(&audio->adrc, (void*) arg, sizeof(audio->adrc)))
+			goto out_fault;
+		break;
+
+	case AUDIO_SET_EQ:
+		if (copy_from_user(&audio->eq, (void*) arg, sizeof(audio->eq)))
+			goto out_fault;
+		break;
+
+	case AUDIO_SET_RX_IIR:
+		if (copy_from_user(&audio->iir, (void*) arg, sizeof(audio->iir)))
+			goto out_fault;
+		break;
+
+	default:
+		rc = -EINVAL;
+	}
+
+	goto out;
+
+ out_fault:
+	rc = -EFAULT;
+ out:
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static int audpp_open(struct inode *inode, struct file *file)
+{
+	struct audio *audio = &the_audio;
+
+	file->private_data = audio;
+	return 0;
+}
+
+static struct file_operations audio_fops = {
+	.owner		= THIS_MODULE,
+	.open		= audio_open,
+	.release	= audio_release,
+	.read		= audio_read,
+	.write		= audio_write,
+	.unlocked_ioctl	= audio_ioctl,
+};
+
+static struct file_operations audpp_fops = {
+	.owner		= THIS_MODULE,
+	.open		= audpp_open,
+	.unlocked_ioctl	= audpp_ioctl,
+};
+
+struct miscdevice audio_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_pcm_out",
+	.fops	= &audio_fops,
+};
+
+struct miscdevice audpp_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_pcm_ctl",
+	.fops	= &audpp_fops,
+};
+
+static int __init audio_init(void)
+{
+	mutex_init(&the_audio.lock);
+	mutex_init(&the_audio.write_lock);
+	spin_lock_init(&the_audio.dsp_lock);
+	init_waitqueue_head(&the_audio.wait);
+	wake_lock_init(&the_audio.wakelock, WAKE_LOCK_SUSPEND, "audio_pcm");
+	wake_lock_init(&the_audio.idlelock, WAKE_LOCK_IDLE, "audio_pcm_idle");
+	return (misc_register(&audio_misc) || misc_register(&audpp_misc));
+}
+
+device_initcall(audio_init);
diff --git a/drivers/staging/dream/qdsp5/audio_qcelp.c b/drivers/staging/dream/qdsp5/audio_qcelp.c
new file mode 100644
index 0000000..f0f50e3
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audio_qcelp.c
@@ -0,0 +1,856 @@
+/* arch/arm/mach-msm/qdsp5/audio_qcelp.c
+ *
+ * qcelp 13k audio decoder device
+ *
+ * Copyright (c) 2008 QUALCOMM USA, INC.
+ *
+ * This code is based in part on audio_mp3.c, which is
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2008 HTC Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you can find it at http://www.fsf.org.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/ioctls.h>
+#include <mach/msm_adsp.h>
+#include <linux/msm_audio.h>
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+#include <mach/qdsp5/qdsp5audplaycmdi.h>
+#include <mach/qdsp5/qdsp5audplaymsg.h>
+
+#include "audmgr.h"
+/* for queue ids - should be relative to module number*/
+#include "adsp.h"
+
+#ifdef DEBUG
+#define dprintk(format, arg...) \
+printk(KERN_DEBUG format, ## arg)
+#else
+#define dprintk(format, arg...) do {} while (0)
+#endif
+
+#define BUFSZ 1080 /* QCELP 13K Hold 600ms packet data = 36 * 30 */
+#define BUF_COUNT 2
+#define DMASZ (BUFSZ * BUF_COUNT)
+
+#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */
+#define PCM_BUF_MAX_COUNT 5
+
+#define AUDDEC_DEC_QCELP 9
+
+#define	ROUTING_MODE_FTRT	1
+#define	ROUTING_MODE_RT		2
+/* Decoder status received from AUDPPTASK */
+#define	AUDPP_DEC_STATUS_SLEEP	0
+#define	AUDPP_DEC_STATUS_INIT	1
+#define	AUDPP_DEC_STATUS_CFG	2
+#define	AUDPP_DEC_STATUS_PLAY	3
+
+struct buffer {
+	void *data;
+	unsigned size;
+	unsigned used;		/* Input usage actual DSP produced PCM size  */
+	unsigned addr;
+};
+
+struct audio {
+	struct buffer out[BUF_COUNT];
+
+	spinlock_t dsp_lock;
+
+	uint8_t out_head;
+	uint8_t out_tail;
+	uint8_t out_needed;	/* number of buffers the dsp is waiting for */
+
+	struct mutex lock;
+	struct mutex write_lock;
+	wait_queue_head_t write_wait;
+
+	/* Host PCM section - START */
+	struct buffer in[PCM_BUF_MAX_COUNT];
+	struct mutex read_lock;
+	wait_queue_head_t read_wait;    /* Wait queue for read */
+	char *read_data;        /* pointer to reader buffer */
+	dma_addr_t read_phys;   /* physical address of reader buffer */
+	uint8_t read_next;      /* index to input buffers to be read next */
+	uint8_t fill_next;      /* index to buffer that DSP should be filling */
+	uint8_t pcm_buf_count;  /* number of pcm buffer allocated */
+	/* Host PCM section - END */
+
+	struct msm_adsp_module *audplay;
+
+	struct audmgr audmgr;
+
+	/* data allocated for various buffers */
+	char *data;
+	dma_addr_t phys;
+
+	uint8_t opened:1;
+	uint8_t enabled:1;
+	uint8_t running:1;
+	uint8_t stopped:1;	/* set when stopped, cleared on flush */
+	uint8_t pcm_feedback:1; /* set when non-tunnel mode */
+	uint8_t buf_refresh:1;
+
+	unsigned volume;
+
+	uint16_t dec_id;
+};
+
+static struct audio the_qcelp_audio;
+
+static int auddec_dsp_config(struct audio *audio, int enable);
+static void audpp_cmd_cfg_adec_params(struct audio *audio);
+static void audpp_cmd_cfg_routing_mode(struct audio *audio);
+static void audqcelp_send_data(struct audio *audio, unsigned needed);
+static void audqcelp_config_hostpcm(struct audio *audio);
+static void audqcelp_buffer_refresh(struct audio *audio);
+static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg);
+
+/* must be called with audio->lock held */
+static int audqcelp_enable(struct audio *audio)
+{
+	struct audmgr_config cfg;
+	int rc;
+
+	dprintk("audqcelp_enable()\n");
+
+	if (audio->enabled)
+		return 0;
+
+	audio->out_tail = 0;
+	audio->out_needed = 0;
+
+	cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
+	cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
+	cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
+	cfg.codec = RPC_AUD_DEF_CODEC_13K;
+	cfg.snd_method = RPC_SND_METHOD_MIDI;
+
+	rc = audmgr_enable(&audio->audmgr, &cfg);
+	if (rc < 0)
+		return rc;
+
+	if (msm_adsp_enable(audio->audplay)) {
+		pr_err("audio: msm_adsp_enable(audplay) failed\n");
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+
+	if (audpp_enable(audio->dec_id, audqcelp_dsp_event, audio)) {
+		pr_err("audio: audpp_enable() failed\n");
+		msm_adsp_disable(audio->audplay);
+		audmgr_disable(&audio->audmgr);
+		return -ENODEV;
+	}
+	audio->enabled = 1;
+	return 0;
+}
+
+/* must be called with audio->lock held */
+static int audqcelp_disable(struct audio *audio)
+{
+	dprintk("audqcelp_disable()\n");
+	if (audio->enabled) {
+		audio->enabled = 0;
+		auddec_dsp_config(audio, 0);
+		wake_up(&audio->write_wait);
+		wake_up(&audio->read_wait);
+		msm_adsp_disable(audio->audplay);
+		audpp_disable(audio->dec_id, audio);
+		audmgr_disable(&audio->audmgr);
+		audio->out_needed = 0;
+	}
+	return 0;
+}
+
+/* ------------------- dsp --------------------- */
+static void audqcelp_update_pcm_buf_entry(struct audio *audio,
+	uint32_t *payload)
+{
+	uint8_t index;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	for (index = 0; index < payload[1]; index++) {
+		if (audio->in[audio->fill_next].addr ==
+			payload[2 + index * 2]) {
+			dprintk("audqcelp_update_pcm_buf_entry: in[%d] ready\n",
+			audio->fill_next);
+			audio->in[audio->fill_next].used =
+			payload[3 + index * 2];
+			if ((++audio->fill_next) == audio->pcm_buf_count)
+				audio->fill_next = 0;
+		} else {
+			pr_err(
+			"audqcelp_update_pcm_buf_entry: expected=%x ret=%x\n",
+			audio->in[audio->fill_next].addr,
+			payload[1 + index * 2]);
+			break;
+		}
+	}
+	if (audio->in[audio->fill_next].used == 0) {
+		audqcelp_buffer_refresh(audio);
+	} else {
+		dprintk("audqcelp_update_pcm_buf_entry: read cannot keep up\n");
+		audio->buf_refresh = 1;
+	}
+
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+	wake_up(&audio->read_wait);
+}
+
+static void audplay_dsp_event(void *data, unsigned id, size_t len,
+			      void (*getevent) (void *ptr, size_t len))
+{
+	struct audio *audio = data;
+	uint32_t msg[28];
+	getevent(msg, sizeof(msg));
+
+	dprintk("audplay_dsp_event: msg_id=%x\n", id);
+
+	switch (id) {
+	case AUDPLAY_MSG_DEC_NEEDS_DATA:
+		audqcelp_send_data(audio, 1);
+		break;
+
+	case AUDPLAY_MSG_BUFFER_UPDATE:
+		audqcelp_update_pcm_buf_entry(audio, msg);
+		break;
+
+	default:
+		pr_err("unexpected message from decoder \n");
+	}
+}
+
+static void audqcelp_dsp_event(void *private, unsigned id, uint16_t *msg)
+{
+	struct audio *audio = private;
+
+	switch (id) {
+	case AUDPP_MSG_STATUS_MSG:{
+			unsigned status = msg[1];
+
+			switch (status) {
+			case AUDPP_DEC_STATUS_SLEEP:
+				dprintk("decoder status: sleep \n");
+				break;
+
+			case AUDPP_DEC_STATUS_INIT:
+				dprintk("decoder status: init \n");
+				audpp_cmd_cfg_routing_mode(audio);
+				break;
+
+			case AUDPP_DEC_STATUS_CFG:
+				dprintk("decoder status: cfg \n");
+				break;
+			case AUDPP_DEC_STATUS_PLAY:
+				dprintk("decoder status: play \n");
+				if (audio->pcm_feedback) {
+					audqcelp_config_hostpcm(audio);
+					audqcelp_buffer_refresh(audio);
+				}
+				break;
+			default:
+				pr_err("unknown decoder status \n");
+			}
+			break;
+		}
+	case AUDPP_MSG_CFG_MSG:
+		if (msg[0] == AUDPP_MSG_ENA_ENA) {
+			dprintk("audqcelp_dsp_event: CFG_MSG ENABLE\n");
+			auddec_dsp_config(audio, 1);
+			audio->out_needed = 0;
+			audio->running = 1;
+			audpp_set_volume_and_pan(audio->dec_id, audio->volume,
+						 0);
+			audpp_avsync(audio->dec_id, 22050);
+		} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
+			dprintk("audqcelp_dsp_event: CFG_MSG DISABLE\n");
+			audpp_avsync(audio->dec_id, 0);
+			audio->running = 0;
+		} else {
+			pr_err("audqcelp_dsp_event: CFG_MSG %d?\n", msg[0]);
+		}
+		break;
+	case AUDPP_MSG_ROUTING_ACK:
+		dprintk("audqcelp_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
+		audpp_cmd_cfg_adec_params(audio);
+		break;
+	default:
+		pr_err("audqcelp_dsp_event: UNKNOWN (%d)\n", id);
+	}
+
+}
+
+struct msm_adsp_ops audplay_adsp_ops_qcelp = {
+	.event = audplay_dsp_event,
+};
+
+#define audplay_send_queue0(audio, cmd, len) \
+	msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
+		       cmd, len)
+
+static int auddec_dsp_config(struct audio *audio, int enable)
+{
+	audpp_cmd_cfg_dec_type cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
+	if (enable)
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
+		    AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_QCELP;
+	else
+		cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
+
+	return audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_adec_params(struct audio *audio)
+{
+	struct audpp_cmd_cfg_adec_params_v13k cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
+	cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN;
+	cmd.common.dec_id = audio->dec_id;
+	cmd.common.input_sampling_frequency = 8000;
+	cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V;
+
+	audpp_send_queue2(&cmd, sizeof(cmd));
+}
+
+static void audpp_cmd_cfg_routing_mode(struct audio *audio)
+{
+	struct audpp_cmd_routing_mode cmd;
+	dprintk("audpp_cmd_cfg_routing_mode()\n");
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
+	cmd.object_number = audio->dec_id;
+	if (audio->pcm_feedback)
+		cmd.routing_mode = ROUTING_MODE_FTRT;
+	else
+		cmd.routing_mode = ROUTING_MODE_RT;
+	audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static int audplay_dsp_send_data_avail(struct audio *audio,
+				       unsigned idx, unsigned len)
+{
+	audplay_cmd_bitstream_data_avail cmd;
+
+	cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
+	cmd.decoder_id = audio->dec_id;
+	cmd.buf_ptr = audio->out[idx].addr;
+	cmd.buf_size = len / 2;
+	cmd.partition_number = 0;
+	return audplay_send_queue0(audio, &cmd, sizeof(cmd));
+}
+
+static void audqcelp_buffer_refresh(struct audio *audio)
+{
+	struct audplay_cmd_buffer_refresh refresh_cmd;
+
+	refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
+	refresh_cmd.num_buffers = 1;
+	refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
+	refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
+	refresh_cmd.buf_read_count = 0;
+	dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
+		refresh_cmd.buf0_address, refresh_cmd.buf0_length);
+
+	(void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
+}
+
+static void audqcelp_config_hostpcm(struct audio *audio)
+{
+	struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
+
+	dprintk("audqcelp_config_hostpcm()\n");
+	cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
+	cfg_cmd.max_buffers = audio->pcm_buf_count;
+	cfg_cmd.byte_swap = 0;
+	cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
+	cfg_cmd.feedback_frequency = 1;
+	cfg_cmd.partition_number = 0;
+
+	(void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
+}
+
+static void audqcelp_send_data(struct audio *audio, unsigned needed)
+{
+	struct buffer *frame;
+	unsigned long flags;
+
+	spin_lock_irqsave(&audio->dsp_lock, flags);
+	if (!audio->running)
+		goto done;
+
+	if (needed) {
+		/* We were called from the callback because the DSP
+		 * requested more data.  Note that the DSP does want
+		 * more data, and if a buffer was in-flight, mark it
+		 * as available (since the DSP must now be done with
+		 * it).
+		 */
+		audio->out_needed = 1;
+		frame = audio->out + audio->out_tail;
+		if (frame->used == 0xffffffff) {
+			dprintk("frame %d free\n", audio->out_tail);
+			frame->used = 0;
+			audio->out_tail ^= 1;
+			wake_up(&audio->write_wait);
+		}
+	}
+
+	if (audio->out_needed) {
+		/* If the DSP currently wants data and we have a
+		 * buffer available, we will send it and reset
+		 * the needed flag.  We'll mark the buffer as in-flight
+		 * so that it won't be recycled until the next buffer
+		 * is requested
+		 */
+
+		frame = audio->out + audio->out_tail;
+		if (frame->used) {
+			BUG_ON(frame->used == 0xffffffff);
+			dprintk("frame %d busy\n", audio->out_tail);
+			audplay_dsp_send_data_avail(audio, audio->out_tail,
+						    frame->used);
+			frame->used = 0xffffffff;
+			audio->out_needed = 0;
+		}
+	}
+ done:
+	spin_unlock_irqrestore(&audio->dsp_lock, flags);
+}
+
+/* ------------------- device --------------------- */
+
+static void audqcelp_flush(struct audio *audio)
+{
+	audio->out[0].used = 0;
+	audio->out[1].used = 0;
+	audio->out_head = 0;
+	audio->out_tail = 0;
+	audio->stopped = 0;
+}
+
+static void audqcelp_flush_pcm_buf(struct audio *audio)
+{
+	uint8_t index;
+
+	for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
+		audio->in[index].used = 0;
+
+	audio->read_next = 0;
+	audio->fill_next = 0;
+}
+
+static long audqcelp_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg)
+{
+	struct audio *audio = file->private_data;
+	int rc = 0;
+
+	dprintk("audqcelp_ioctl() cmd = %d\n", cmd);
+
+	if (cmd == AUDIO_GET_STATS) {
+		struct msm_audio_stats stats;
+		stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
+		stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
+		if (copy_to_user((void *)arg, &stats, sizeof(stats)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == AUDIO_SET_VOLUME) {
+		unsigned long flags;
+		spin_lock_irqsave(&audio->dsp_lock, flags);
+		audio->volume = arg;
+		if (audio->running)
+			audpp_set_volume_and_pan(audio->dec_id, arg, 0);
+		spin_unlock_irqrestore(&audio->dsp_lock, flags);
+		return 0;
+	}
+	mutex_lock(&audio->lock);
+	switch (cmd) {
+	case AUDIO_START:
+		rc = audqcelp_enable(audio);
+		break;
+	case AUDIO_STOP:
+		rc = audqcelp_disable(audio);
+		audio->stopped = 1;
+		break;
+	case AUDIO_FLUSH:
+		if (audio->stopped) {
+			/* Make sure we're stopped and we wake any threads
+			 * that might be blocked holding the write_lock.
+			 * While audio->stopped write threads will always
+			 * exit immediately.
+			 */
+			wake_up(&audio->write_wait);
+			mutex_lock(&audio->write_lock);
+			audqcelp_flush(audio);
+			mutex_unlock(&audio->write_lock);
+			wake_up(&audio->read_wait);
+			mutex_lock(&audio->read_lock);
+			audqcelp_flush_pcm_buf(audio);
+			mutex_unlock(&audio->read_lock);
+			break;
+		}
+		break;
+	case AUDIO_SET_CONFIG:
+		dprintk("AUDIO_SET_CONFIG not applicable \n");
+		break;
+	case AUDIO_GET_CONFIG:{
+			struct msm_audio_config config;
+			config.buffer_size = BUFSZ;
+			config.buffer_count = BUF_COUNT;
+			config.sample_rate = 8000;
+			config.channel_count = 1;
+			config.unused[0] = 0;
+			config.unused[1] = 0;
+			config.unused[2] = 0;
+			config.unused[3] = 0;
+			if (copy_to_user((void *)arg, &config,
+					 sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+
+			break;
+		}
+	case AUDIO_GET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+
+			config.pcm_feedback = 0;
+			config.buffer_count = PCM_BUF_MAX_COUNT;
+			config.buffer_size = PCM_BUFSZ_MIN;
+			if (copy_to_user((void *)arg, &config,
+				sizeof(config)))
+				rc = -EFAULT;
+			else
+				rc = 0;
+			break;
+		}
+	case AUDIO_SET_PCM_CONFIG:{
+			struct msm_audio_pcm_config config;
+
+			if (copy_from_user(&config, (void *)arg,
+				sizeof(config))) {
+				rc = -EFAULT;
+				break;
+			}
+			if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
+				(config.buffer_count == 1))
+				config.buffer_count = PCM_BUF_MAX_COUNT;
+
+			if (config.buffer_size < PCM_BUFSZ_MIN)
+				config.buffer_size = PCM_BUFSZ_MIN;
+
+			/* Check if pcm feedback is required */
+			if ((config.pcm_feedback) && (!audio->read_data)) {
+				dprintk(
+				"audqcelp_ioctl: allocate PCM buf %d\n",
+				config.buffer_count * config.buffer_size);
+				audio->read_data = dma_alloc_coherent(NULL,
+				config.buffer_size * config.buffer_count,
+				&audio->read_phys, GFP_KERNEL);
+				if (!audio->read_data) {
+					pr_err(
+					"audqcelp_ioctl: no mem for pcm buf\n"
+					);
+					rc = -ENOMEM;
+				} else {
+					uint8_t index;
+					uint32_t offset = 0;
+
+					audio->pcm_feedback = 1;
+					audio->buf_refresh = 0;
+					audio->pcm_buf_count =
+						config.buffer_count;
+					audio->read_next = 0;
+					audio->fill_next = 0;
+
+					for (index = 0;
+					index < config.buffer_count; index++) {
+						audio->in[index].data =
+						audio->read_data + offset;
+						audio->in[index].addr =
+						audio->read_phys + offset;
+						audio->in[index].size =
+						config.buffer_size;
+						audio->in[index].used = 0;
+						offset += config.buffer_size;
+					}
+					rc = 0;
+				}
+			} else {
+				rc = 0;
+			}
+			break;
+		}
+	case AUDIO_PAUSE:
+		dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
+		rc = audpp_pause(audio->dec_id, (int) arg);
+		break;
+	default:
+		rc = -EINVAL;
+	}
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static ssize_t audqcelp_read(struct file *file, char __user *buf, size_t count,
+			loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	int rc = 0;
+
+	if (!audio->pcm_feedback)
+		return 0; /* PCM feedback is not enabled. Nothing to read */
+
+	mutex_lock(&audio->read_lock);
+	dprintk("audqcelp_read() %d \n", count);
+	while (count > 0) {
+		rc = wait_event_interruptible(audio->read_wait,
+				(audio->in[audio->read_next].used > 0) ||
+				(audio->stopped));
+		if (rc < 0)
+			break;
+
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+
+		if (count < audio->in[audio->read_next].used) {
+			/* Read must happen in frame boundary. Since driver does
+			not know frame size, read count must be greater or equal
+			to size of PCM samples */
+			dprintk("audqcelp_read:read stop - partial frame\n");
+			break;
+		} else {
+			dprintk("audqcelp_read: read from in[%d]\n",
+				audio->read_next);
+			if (copy_to_user(buf,
+				audio->in[audio->read_next].data,
+				audio->in[audio->read_next].used)) {
+				pr_err("audqcelp_read: invalid addr %x \n",
+					(unsigned int)buf);
+				rc = -EFAULT;
+				break;
+			}
+			count -= audio->in[audio->read_next].used;
+			buf += audio->in[audio->read_next].used;
+			audio->in[audio->read_next].used = 0;
+			if ((++audio->read_next) == audio->pcm_buf_count)
+				audio->read_next = 0;
+		}
+	}
+
+	if (audio->buf_refresh) {
+		audio->buf_refresh = 0;
+		dprintk("audqcelp_read: kick start pcm feedback again\n");
+		audqcelp_buffer_refresh(audio);
+	}
+
+	mutex_unlock(&audio->read_lock);
+
+	if (buf > start)
+		rc = buf - start;
+
+	dprintk("audqcelp_read: read %d bytes\n", rc);
+	return rc;
+}
+
+static ssize_t audqcelp_write(struct file *file, const char __user *buf,
+			   size_t count, loff_t *pos)
+{
+	struct audio *audio = file->private_data;
+	const char __user *start = buf;
+	struct buffer *frame;
+	size_t xfer;
+	int rc = 0;
+
+	if (count & 1)
+		return -EINVAL;
+	dprintk("audqcelp_write() \n");
+	mutex_lock(&audio->write_lock);
+	while (count > 0) {
+		frame = audio->out + audio->out_head;
+		rc = wait_event_interruptible(audio->write_wait,
+					      (frame->used == 0)
+					      || (audio->stopped));
+		dprintk("audqcelp_write() buffer available\n");
+		if (rc < 0)
+			break;
+		if (audio->stopped) {
+			rc = -EBUSY;
+			break;
+		}
+		xfer = (count > frame->size) ? frame->size : count;
+		if (copy_from_user(frame->data, buf, xfer)) {
+			rc = -EFAULT;
+			break;
+		}
+
+		frame->used = xfer;
+		audio->out_head ^= 1;
+		count -= xfer;
+		buf += xfer;
+
+		audqcelp_send_data(audio, 0);
+
+	}
+	mutex_unlock(&audio->write_lock);
+	if (buf > start)
+		return buf - start;
+	return rc;
+}
+
+static int audqcelp_release(struct inode *inode, struct file *file)
+{
+	struct audio *audio = file->private_data;
+
+	dprintk("audqcelp_release()\n");
+
+	mutex_lock(&audio->lock);
+	audqcelp_disable(audio);
+	audqcelp_flush(audio);
+	audqcelp_flush_pcm_buf(audio);
+	msm_adsp_put(audio->audplay);
+	audio->audplay = NULL;
+	audio->opened = 0;
+	if (audio->data)
+		dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
+	audio->data = NULL;
+	if (audio->read_data) {
+		dma_free_coherent(NULL,
+				 audio->in[0].size * audio->pcm_buf_count,
+				 audio->read_data, audio->read_phys);
+		audio->read_data = NULL;
+	}
+	audio->pcm_feedback = 0;
+	mutex_unlock(&audio->lock);
+	return 0;
+}
+
+static int audqcelp_open(struct inode *inode, struct file *file)
+{
+	struct audio *audio = &the_qcelp_audio;
+	int rc;
+
+	mutex_lock(&audio->lock);
+
+	if (audio->opened) {
+		pr_err("audio: busy\n");
+		rc = -EBUSY;
+		goto done;
+	}
+
+	audio->data = dma_alloc_coherent(NULL, DMASZ,
+					 &audio->phys, GFP_KERNEL);
+	if (!audio->data) {
+		pr_err("audio: could not allocate DMA buffers\n");
+		rc = -ENOMEM;
+		goto done;
+	}
+
+	rc = audmgr_open(&audio->audmgr);
+	if (rc)
+		goto err;
+
+	rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
+		&audplay_adsp_ops_qcelp, audio);
+	if (rc) {
+		pr_err("audio: failed to get audplay0 dsp module\n");
+		audmgr_close(&audio->audmgr);
+		goto err;
+	}
+
+	audio->dec_id = 0;
+
+	audio->out[0].data = audio->data + 0;
+	audio->out[0].addr = audio->phys + 0;
+	audio->out[0].size = BUFSZ;
+
+	audio->out[1].data = audio->data + BUFSZ;
+	audio->out[1].addr = audio->phys + BUFSZ;
+	audio->out[1].size = BUFSZ;
+
+	audio->volume = 0x2000;	/* Q13 1.0 */
+
+	audqcelp_flush(audio);
+
+	file->private_data = audio;
+	audio->opened = 1;
+	rc = 0;
+done:
+	mutex_unlock(&audio->lock);
+	return rc;
+err:
+	dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
+	mutex_unlock(&audio->lock);
+	return rc;
+}
+
+static struct file_operations audio_qcelp_fops = {
+	.owner = THIS_MODULE,
+	.open = audqcelp_open,
+	.release = audqcelp_release,
+	.read = audqcelp_read,
+	.write = audqcelp_write,
+	.unlocked_ioctl = audqcelp_ioctl,
+};
+
+struct miscdevice audio_qcelp_misc = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "msm_qcelp",
+	.fops = &audio_qcelp_fops,
+};
+
+static int __init audqcelp_init(void)
+{
+	mutex_init(&the_qcelp_audio.lock);
+	mutex_init(&the_qcelp_audio.write_lock);
+	mutex_init(&the_qcelp_audio.read_lock);
+	spin_lock_init(&the_qcelp_audio.dsp_lock);
+	init_waitqueue_head(&the_qcelp_audio.write_wait);
+	init_waitqueue_head(&the_qcelp_audio.read_wait);
+	the_qcelp_audio.read_data = NULL;
+	return misc_register(&audio_qcelp_misc);
+}
+
+static void __exit audqcelp_exit(void)
+{
+	misc_deregister(&audio_qcelp_misc);
+}
+
+module_init(audqcelp_init);
+module_exit(audqcelp_exit);
+
+MODULE_DESCRIPTION("MSM QCELP 13K driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("QUALCOMM");
diff --git a/drivers/staging/dream/qdsp5/audmgr.c b/drivers/staging/dream/qdsp5/audmgr.c
new file mode 100644
index 0000000..1ad8b82
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audmgr.c
@@ -0,0 +1,313 @@
+/* arch/arm/mach-msm/qdsp5/audmgr.c
+ *
+ * interface to "audmgr" service on the baseband cpu
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/wait.h>
+
+#include <asm/atomic.h>
+#include <mach/msm_rpcrouter.h>
+
+#include "audmgr.h"
+
+#define STATE_CLOSED    0
+#define STATE_DISABLED  1
+#define STATE_ENABLING  2
+#define STATE_ENABLED   3
+#define STATE_DISABLING 4
+#define STATE_ERROR	5
+
+static void rpc_ack(struct msm_rpc_endpoint *ept, uint32_t xid)
+{
+	uint32_t rep[6];
+
+	rep[0] = cpu_to_be32(xid);
+	rep[1] = cpu_to_be32(1);
+	rep[2] = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
+	rep[3] = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS);
+	rep[4] = 0;
+	rep[5] = 0;
+
+	msm_rpc_write(ept, rep, sizeof(rep));
+}
+
+static void process_audmgr_callback(struct audmgr *am,
+				   struct rpc_audmgr_cb_func_ptr *args,
+				   int len)
+{
+	if (len < (sizeof(uint32_t) * 3))
+		return;
+	if (be32_to_cpu(args->set_to_one) != 1)
+		return;
+
+	switch (be32_to_cpu(args->status)) {
+	case RPC_AUDMGR_STATUS_READY:
+		if (len < sizeof(uint32_t) * 4)
+			break;
+		am->handle = be32_to_cpu(args->u.handle);
+		pr_info("audmgr: rpc READY handle=0x%08x\n", am->handle);
+		break;
+	case RPC_AUDMGR_STATUS_CODEC_CONFIG: {
+		uint32_t volume;
+		if (len < sizeof(uint32_t) * 4)
+			break;
+		volume = be32_to_cpu(args->u.volume);
+		pr_info("audmgr: rpc CODEC_CONFIG volume=0x%08x\n", volume);
+		am->state = STATE_ENABLED;
+		wake_up(&am->wait);
+		break;
+	}
+	case RPC_AUDMGR_STATUS_PENDING:
+		pr_err("audmgr: PENDING?\n");
+		break;
+	case RPC_AUDMGR_STATUS_SUSPEND:
+		pr_err("audmgr: SUSPEND?\n");
+		break;
+	case RPC_AUDMGR_STATUS_FAILURE:
+		pr_err("audmgr: FAILURE\n");
+		break;
+	case RPC_AUDMGR_STATUS_VOLUME_CHANGE:
+		pr_err("audmgr: VOLUME_CHANGE?\n");
+		break;
+	case RPC_AUDMGR_STATUS_DISABLED:
+		pr_err("audmgr: DISABLED\n");
+		am->state = STATE_DISABLED;
+		wake_up(&am->wait);
+		break;
+	case RPC_AUDMGR_STATUS_ERROR:
+		pr_err("audmgr: ERROR?\n");
+		am->state = STATE_ERROR;
+		wake_up(&am->wait);
+		break;
+	default:
+		break;
+	}
+}
+
+static void process_rpc_request(uint32_t proc, uint32_t xid,
+				void *data, int len, void *private)
+{
+	struct audmgr *am = private;
+	uint32_t *x = data;
+
+	if (0) {
+		int n = len / 4;
+		pr_info("rpc_call proc %d:", proc);
+		while (n--)
+			printk(" %08x", be32_to_cpu(*x++));
+		printk("\n");
+	}
+
+	if (proc == AUDMGR_CB_FUNC_PTR)
+		process_audmgr_callback(am, data, len);
+	else
+		pr_err("audmgr: unknown rpc proc %d\n", proc);
+	rpc_ack(am->ept, xid);
+}
+
+#define RPC_TYPE_REQUEST 0
+#define RPC_TYPE_REPLY 1
+
+#define RPC_VERSION 2
+
+#define RPC_COMMON_HDR_SZ  (sizeof(uint32_t) * 2)
+#define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr))
+#define RPC_REPLY_HDR_SZ   (sizeof(uint32_t) * 3)
+#define RPC_REPLY_SZ       (sizeof(uint32_t) * 6)
+
+static int audmgr_rpc_thread(void *data)
+{
+	struct audmgr *am = data;
+	struct rpc_request_hdr *hdr = NULL;
+	uint32_t type;
+	int len;
+
+	pr_info("audmgr_rpc_thread() start\n");
+
+	while (!kthread_should_stop()) {
+		if (hdr) {
+			kfree(hdr);
+			hdr = NULL;
+		}
+		len = msm_rpc_read(am->ept, (void **) &hdr, -1, -1);
+		if (len < 0) {
+			pr_err("audmgr: rpc read failed (%d)\n", len);
+			break;
+		}
+		if (len < RPC_COMMON_HDR_SZ)
+			continue;
+
+		type = be32_to_cpu(hdr->type);
+		if (type == RPC_TYPE_REPLY) {
+			struct rpc_reply_hdr *rep = (void *) hdr;
+			uint32_t status;
+			if (len < RPC_REPLY_HDR_SZ)
+				continue;
+			status = be32_to_cpu(rep->reply_stat);
+			if (status == RPCMSG_REPLYSTAT_ACCEPTED) {
+				status = be32_to_cpu(rep->data.acc_hdr.accept_stat);
+				pr_info("audmgr: rpc_reply status %d\n", status);
+			} else {
+				pr_info("audmgr: rpc_reply denied!\n");
+			}
+			/* process reply */
+			continue;
+		}
+
+		if (len < RPC_REQUEST_HDR_SZ)
+			continue;
+
+		process_rpc_request(be32_to_cpu(hdr->procedure),
+				    be32_to_cpu(hdr->xid),
+				    (void *) (hdr + 1),
+				    len - sizeof(*hdr),
+				    data);
+	}
+	pr_info("audmgr_rpc_thread() exit\n");
+	if (hdr) {
+		kfree(hdr);
+		hdr = NULL;
+	}
+	am->task = NULL;
+	wake_up(&am->wait);
+	return 0;
+}
+
+struct audmgr_enable_msg {
+	struct rpc_request_hdr hdr;
+	struct rpc_audmgr_enable_client_args args;
+};
+
+struct audmgr_disable_msg {
+	struct rpc_request_hdr hdr;
+	uint32_t handle;
+};
+
+int audmgr_open(struct audmgr *am)
+{
+	int rc;
+
+	if (am->state != STATE_CLOSED)
+		return 0;
+
+	am->ept = msm_rpc_connect(AUDMGR_PROG,
+				AUDMGR_VERS,
+				MSM_RPC_UNINTERRUPTIBLE);
+
+	init_waitqueue_head(&am->wait);
+
+	if (IS_ERR(am->ept)) {
+		rc = PTR_ERR(am->ept);
+		am->ept = NULL;
+		pr_err("audmgr: failed to connect to audmgr svc\n");
+		return rc;
+	}
+
+	am->task = kthread_run(audmgr_rpc_thread, am, "audmgr_rpc");
+	if (IS_ERR(am->task)) {
+		rc = PTR_ERR(am->task);
+		am->task = NULL;
+		msm_rpc_close(am->ept);
+		am->ept = NULL;
+		return rc;
+	}
+
+	am->state = STATE_DISABLED;
+	return 0;
+}
+EXPORT_SYMBOL(audmgr_open);
+
+int audmgr_close(struct audmgr *am)
+{
+	return -EBUSY;
+}
+EXPORT_SYMBOL(audmgr_close);
+
+int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg)
+{
+	struct audmgr_enable_msg msg;
+	int rc;
+
+	if (am->state == STATE_ENABLED)
+		return 0;
+
+	if (am->state == STATE_DISABLING)
+		pr_err("audmgr: state is DISABLING in enable?\n");
+	am->state = STATE_ENABLING;
+
+	msg.args.set_to_one = cpu_to_be32(1);
+	msg.args.tx_sample_rate = cpu_to_be32(cfg->tx_rate);
+	msg.args.rx_sample_rate = cpu_to_be32(cfg->rx_rate);
+	msg.args.def_method = cpu_to_be32(cfg->def_method);
+	msg.args.codec_type = cpu_to_be32(cfg->codec);
+	msg.args.snd_method = cpu_to_be32(cfg->snd_method);
+	msg.args.cb_func = cpu_to_be32(0x11111111);
+	msg.args.client_data = cpu_to_be32(0x11223344);
+
+	msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
+			  AUDMGR_ENABLE_CLIENT);
+
+	rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
+	if (rc < 0)
+		return rc;
+
+	rc = wait_event_timeout(am->wait, am->state != STATE_ENABLING, 15 * HZ);
+	if (rc == 0) {
+		pr_err("audmgr_enable: ARM9 did not reply to RPC am->state = %d\n", am->state);
+		BUG();
+	}
+	if (am->state == STATE_ENABLED)
+		return 0;
+
+	pr_err("audmgr: unexpected state %d while enabling?!\n", am->state);
+	return -ENODEV;
+}
+EXPORT_SYMBOL(audmgr_enable);
+
+int audmgr_disable(struct audmgr *am)
+{
+	struct audmgr_disable_msg msg;
+	int rc;
+
+	if (am->state == STATE_DISABLED)
+		return 0;
+
+	msm_rpc_setup_req(&msg.hdr, AUDMGR_PROG, msm_rpc_get_vers(am->ept),
+			  AUDMGR_DISABLE_CLIENT);
+	msg.handle = cpu_to_be32(am->handle);
+
+	am->state = STATE_DISABLING;
+
+	rc = msm_rpc_write(am->ept, &msg, sizeof(msg));
+	if (rc < 0)
+		return rc;
+
+	rc = wait_event_timeout(am->wait, am->state != STATE_DISABLING, 15 * HZ);
+	if (rc == 0) {
+		pr_err("audmgr_disable: ARM9 did not reply to RPC am->state = %d\n", am->state);
+		BUG();
+	}
+
+	if (am->state == STATE_DISABLED)
+		return 0;
+
+	pr_err("audmgr: unexpected state %d while disabling?!\n", am->state);
+	return -ENODEV;
+}
+EXPORT_SYMBOL(audmgr_disable);
diff --git a/drivers/staging/dream/qdsp5/audmgr.h b/drivers/staging/dream/qdsp5/audmgr.h
new file mode 100644
index 0000000..c07c36b
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audmgr.h
@@ -0,0 +1,215 @@
+/* arch/arm/mach-msm/qdsp5/audmgr.h
+ *
+ * Copyright 2008 (c) QUALCOMM Incorporated.
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 _ARCH_ARM_MACH_MSM_AUDMGR_H
+#define _ARCH_ARM_MACH_MSM_AUDMGR_H
+
+#if CONFIG_MSM_AMSS_VERSION==6350
+#include "audmgr_new.h"
+#else
+
+enum rpc_aud_def_sample_rate_type {
+	RPC_AUD_DEF_SAMPLE_RATE_NONE,
+	RPC_AUD_DEF_SAMPLE_RATE_8000,
+	RPC_AUD_DEF_SAMPLE_RATE_11025,
+	RPC_AUD_DEF_SAMPLE_RATE_12000,
+	RPC_AUD_DEF_SAMPLE_RATE_16000,
+	RPC_AUD_DEF_SAMPLE_RATE_22050,
+	RPC_AUD_DEF_SAMPLE_RATE_24000,
+	RPC_AUD_DEF_SAMPLE_RATE_32000,
+	RPC_AUD_DEF_SAMPLE_RATE_44100,
+	RPC_AUD_DEF_SAMPLE_RATE_48000,
+	RPC_AUD_DEF_SAMPLE_RATE_MAX,
+};
+
+enum rpc_aud_def_method_type {
+	RPC_AUD_DEF_METHOD_NONE,
+	RPC_AUD_DEF_METHOD_KEY_BEEP,
+	RPC_AUD_DEF_METHOD_PLAYBACK,
+	RPC_AUD_DEF_METHOD_VOICE,
+	RPC_AUD_DEF_METHOD_RECORD,
+	RPC_AUD_DEF_METHOD_HOST_PCM,
+	RPC_AUD_DEF_METHOD_MIDI_OUT,
+	RPC_AUD_DEF_METHOD_RECORD_SBC,
+	RPC_AUD_DEF_METHOD_DTMF_RINGER,
+	RPC_AUD_DEF_METHOD_MAX,
+};
+
+enum rpc_aud_def_codec_type {
+	RPC_AUD_DEF_CODEC_NONE,
+	RPC_AUD_DEF_CODEC_DTMF,
+	RPC_AUD_DEF_CODEC_MIDI,
+	RPC_AUD_DEF_CODEC_MP3,
+	RPC_AUD_DEF_CODEC_PCM,
+	RPC_AUD_DEF_CODEC_AAC,
+	RPC_AUD_DEF_CODEC_WMA,
+	RPC_AUD_DEF_CODEC_RA,
+	RPC_AUD_DEF_CODEC_ADPCM,
+	RPC_AUD_DEF_CODEC_GAUDIO,
+	RPC_AUD_DEF_CODEC_VOC_EVRC,
+	RPC_AUD_DEF_CODEC_VOC_13K,
+	RPC_AUD_DEF_CODEC_VOC_4GV_NB,
+	RPC_AUD_DEF_CODEC_VOC_AMR,
+	RPC_AUD_DEF_CODEC_VOC_EFR,
+	RPC_AUD_DEF_CODEC_VOC_FR,
+	RPC_AUD_DEF_CODEC_VOC_HR,
+	RPC_AUD_DEF_CODEC_VOC,
+	RPC_AUD_DEF_CODEC_SBC,
+	RPC_AUD_DEF_CODEC_VOC_PCM,
+	RPC_AUD_DEF_CODEC_AMR_WB,
+	RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
+	RPC_AUD_DEF_CODEC_MAX,
+};
+
+enum rpc_snd_method_type {
+	RPC_SND_METHOD_VOICE = 0,
+	RPC_SND_METHOD_KEY_BEEP,
+	RPC_SND_METHOD_MESSAGE,
+	RPC_SND_METHOD_RING,
+	RPC_SND_METHOD_MIDI,
+	RPC_SND_METHOD_AUX,
+	RPC_SND_METHOD_MAX,
+};
+
+enum rpc_voc_codec_type {
+	RPC_VOC_CODEC_DEFAULT,
+	RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
+	RPC_VOC_CODEC_ON_CHIP_1,
+	RPC_VOC_CODEC_STEREO_HEADSET,
+	RPC_VOC_CODEC_ON_CHIP_AUX,
+	RPC_VOC_CODEC_BT_OFF_BOARD,
+	RPC_VOC_CODEC_BT_A2DP,
+	RPC_VOC_CODEC_OFF_BOARD,
+	RPC_VOC_CODEC_SDAC,
+	RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
+	RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
+	RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
+	RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
+	RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
+	RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
+	RPC_VOC_CODEC_TTY_ON_CHIP_1,
+	RPC_VOC_CODEC_TTY_OFF_BOARD,
+	RPC_VOC_CODEC_TTY_VCO,
+	RPC_VOC_CODEC_TTY_HCO,
+	RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
+	RPC_VOC_CODEC_MAX,
+	RPC_VOC_CODEC_NONE,
+};
+
+enum rpc_audmgr_status_type {
+	RPC_AUDMGR_STATUS_READY,
+	RPC_AUDMGR_STATUS_CODEC_CONFIG,
+	RPC_AUDMGR_STATUS_PENDING,
+	RPC_AUDMGR_STATUS_SUSPEND,
+	RPC_AUDMGR_STATUS_FAILURE,
+	RPC_AUDMGR_STATUS_VOLUME_CHANGE,
+	RPC_AUDMGR_STATUS_DISABLED,
+	RPC_AUDMGR_STATUS_ERROR,
+};
+
+struct rpc_audmgr_enable_client_args {
+	uint32_t set_to_one;
+	uint32_t tx_sample_rate;
+	uint32_t rx_sample_rate;
+	uint32_t def_method;
+	uint32_t codec_type;
+	uint32_t snd_method;
+
+	uint32_t cb_func;
+	uint32_t client_data;
+};
+
+#define AUDMGR_ENABLE_CLIENT			2
+#define AUDMGR_DISABLE_CLIENT			3
+#define AUDMGR_SUSPEND_EVENT_RSP		4
+#define AUDMGR_REGISTER_OPERATION_LISTENER	5
+#define AUDMGR_UNREGISTER_OPERATION_LISTENER	6
+#define AUDMGR_REGISTER_CODEC_LISTENER		7
+#define AUDMGR_GET_RX_SAMPLE_RATE		8
+#define AUDMGR_GET_TX_SAMPLE_RATE		9
+#define AUDMGR_SET_DEVICE_MODE			10
+
+#if CONFIG_MSM_AMSS_VERSION < 6220
+#define AUDMGR_PROG_VERS "rs30000013:46255756"
+#define AUDMGR_PROG 0x30000013
+#define AUDMGR_VERS 0x46255756
+#else
+#define AUDMGR_PROG_VERS "rs30000013:e94e8f0c"
+#define AUDMGR_PROG 0x30000013
+#define AUDMGR_VERS 0xe94e8f0c
+#endif
+
+struct rpc_audmgr_cb_func_ptr {
+	uint32_t cb_id;
+	uint32_t set_to_one;
+	uint32_t status;
+	union {
+		uint32_t handle;
+		uint32_t volume;
+
+	} u;
+};
+
+#define AUDMGR_CB_FUNC_PTR			1
+#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR		2
+#define AUDMGR_CODEC_LSTR_FUNC_PTR		3
+
+#if CONFIG_MSM_AMSS_VERSION < 6220
+#define AUDMGR_CB_PROG 0x31000013
+#define AUDMGR_CB_VERS 0x5fa922a9
+#else
+#define AUDMGR_CB_PROG 0x31000013
+#define AUDMGR_CB_VERS 0x21570ba7
+#endif
+
+struct audmgr {
+	wait_queue_head_t wait;
+	uint32_t handle;
+	struct msm_rpc_endpoint *ept;
+	struct task_struct *task;
+	int state;
+};
+
+struct audmgr_config {
+	uint32_t tx_rate;
+	uint32_t rx_rate;
+	uint32_t def_method;
+	uint32_t codec;
+	uint32_t snd_method;
+};
+
+int audmgr_open(struct audmgr *am);
+int audmgr_close(struct audmgr *am);
+int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
+int audmgr_disable(struct audmgr *am);
+
+typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
+
+int audpp_enable(int id, audpp_event_func func, void *private);
+void audpp_disable(int id, void *private);
+
+int audpp_send_queue1(void *cmd, unsigned len);
+int audpp_send_queue2(void *cmd, unsigned len);
+int audpp_send_queue3(void *cmd, unsigned len);
+
+int audpp_pause(unsigned id, int pause);
+int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
+void audpp_avsync(int id, unsigned rate);
+unsigned audpp_avsync_sample_count(int id);
+unsigned audpp_avsync_byte_count(int id);
+
+#endif
+#endif
diff --git a/drivers/staging/dream/qdsp5/audmgr_new.h b/drivers/staging/dream/qdsp5/audmgr_new.h
new file mode 100644
index 0000000..49670fe
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audmgr_new.h
@@ -0,0 +1,213 @@
+/* arch/arm/mach-msm/qdsp5/audmgr.h
+ *
+ * Copyright 2008 (c) QUALCOMM Incorporated.
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H
+#define _ARCH_ARM_MACH_MSM_AUDMGR_NEW_H
+
+enum rpc_aud_def_sample_rate_type {
+	RPC_AUD_DEF_SAMPLE_RATE_NONE,
+	RPC_AUD_DEF_SAMPLE_RATE_8000,
+	RPC_AUD_DEF_SAMPLE_RATE_11025,
+	RPC_AUD_DEF_SAMPLE_RATE_12000,
+	RPC_AUD_DEF_SAMPLE_RATE_16000,
+	RPC_AUD_DEF_SAMPLE_RATE_22050,
+	RPC_AUD_DEF_SAMPLE_RATE_24000,
+	RPC_AUD_DEF_SAMPLE_RATE_32000,
+	RPC_AUD_DEF_SAMPLE_RATE_44100,
+	RPC_AUD_DEF_SAMPLE_RATE_48000,
+	RPC_AUD_DEF_SAMPLE_RATE_MAX,
+};
+
+enum rpc_aud_def_method_type {
+	RPC_AUD_DEF_METHOD_NONE,
+	RPC_AUD_DEF_METHOD_KEY_BEEP,
+	RPC_AUD_DEF_METHOD_PLAYBACK,
+	RPC_AUD_DEF_METHOD_VOICE,
+	RPC_AUD_DEF_METHOD_RECORD,
+	RPC_AUD_DEF_METHOD_HOST_PCM,
+	RPC_AUD_DEF_METHOD_MIDI_OUT,
+	RPC_AUD_DEF_METHOD_RECORD_SBC,
+	RPC_AUD_DEF_METHOD_DTMF_RINGER,
+	RPC_AUD_DEF_METHOD_MAX,
+};
+
+enum rpc_aud_def_codec_type {
+	RPC_AUD_DEF_CODEC_NONE,
+	RPC_AUD_DEF_CODEC_DTMF,
+	RPC_AUD_DEF_CODEC_MIDI,
+	RPC_AUD_DEF_CODEC_MP3,
+	RPC_AUD_DEF_CODEC_PCM,
+	RPC_AUD_DEF_CODEC_AAC,
+	RPC_AUD_DEF_CODEC_WMA,
+	RPC_AUD_DEF_CODEC_RA,
+	RPC_AUD_DEF_CODEC_ADPCM,
+	RPC_AUD_DEF_CODEC_GAUDIO,
+	RPC_AUD_DEF_CODEC_VOC_EVRC,
+	RPC_AUD_DEF_CODEC_VOC_13K,
+	RPC_AUD_DEF_CODEC_VOC_4GV_NB,
+	RPC_AUD_DEF_CODEC_VOC_AMR,
+	RPC_AUD_DEF_CODEC_VOC_EFR,
+	RPC_AUD_DEF_CODEC_VOC_FR,
+	RPC_AUD_DEF_CODEC_VOC_HR,
+	RPC_AUD_DEF_CODEC_VOC_CDMA,
+	RPC_AUD_DEF_CODEC_VOC_CDMA_WB,
+	RPC_AUD_DEF_CODEC_VOC_UMTS,
+	RPC_AUD_DEF_CODEC_VOC_UMTS_WB,
+	RPC_AUD_DEF_CODEC_SBC,
+	RPC_AUD_DEF_CODEC_VOC_PCM,
+	RPC_AUD_DEF_CODEC_AMR_WB,
+	RPC_AUD_DEF_CODEC_AMR_WB_PLUS,
+	RPC_AUD_DEF_CODEC_AAC_BSAC,
+	RPC_AUD_DEF_CODEC_MAX,
+	RPC_AUD_DEF_CODEC_AMR_NB,
+	RPC_AUD_DEF_CODEC_13K,
+	RPC_AUD_DEF_CODEC_EVRC,
+	RPC_AUD_DEF_CODEC_MAX_002,
+};
+
+enum rpc_snd_method_type {
+	RPC_SND_METHOD_VOICE = 0,
+	RPC_SND_METHOD_KEY_BEEP,
+	RPC_SND_METHOD_MESSAGE,
+	RPC_SND_METHOD_RING,
+	RPC_SND_METHOD_MIDI,
+	RPC_SND_METHOD_AUX,
+	RPC_SND_METHOD_MAX,
+};
+
+enum rpc_voc_codec_type {
+	RPC_VOC_CODEC_DEFAULT,
+	RPC_VOC_CODEC_ON_CHIP_0 = RPC_VOC_CODEC_DEFAULT,
+	RPC_VOC_CODEC_ON_CHIP_1,
+	RPC_VOC_CODEC_STEREO_HEADSET,
+	RPC_VOC_CODEC_ON_CHIP_AUX,
+	RPC_VOC_CODEC_BT_OFF_BOARD,
+	RPC_VOC_CODEC_BT_A2DP,
+	RPC_VOC_CODEC_OFF_BOARD,
+	RPC_VOC_CODEC_SDAC,
+	RPC_VOC_CODEC_RX_EXT_SDAC_TX_INTERNAL,
+	RPC_VOC_CODEC_IN_STEREO_SADC_OUT_MONO_HANDSET,
+	RPC_VOC_CODEC_IN_STEREO_SADC_OUT_STEREO_HEADSET,
+	RPC_VOC_CODEC_TX_INT_SADC_RX_EXT_AUXPCM,
+	RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_MONO_HANDSET,
+	RPC_VOC_CODEC_EXT_STEREO_SADC_OUT_STEREO_HEADSET,
+	RPC_VOC_CODEC_TTY_ON_CHIP_1,
+	RPC_VOC_CODEC_TTY_OFF_BOARD,
+	RPC_VOC_CODEC_TTY_VCO,
+	RPC_VOC_CODEC_TTY_HCO,
+	RPC_VOC_CODEC_ON_CHIP_0_DUAL_MIC,
+	RPC_VOC_CODEC_MAX,
+	RPC_VOC_CODEC_NONE,
+};
+
+enum rpc_audmgr_status_type {
+	RPC_AUDMGR_STATUS_READY,
+	RPC_AUDMGR_STATUS_CODEC_CONFIG,
+	RPC_AUDMGR_STATUS_PENDING,
+	RPC_AUDMGR_STATUS_SUSPEND,
+	RPC_AUDMGR_STATUS_FAILURE,
+	RPC_AUDMGR_STATUS_VOLUME_CHANGE,
+	RPC_AUDMGR_STATUS_DISABLED,
+	RPC_AUDMGR_STATUS_ERROR,
+};
+
+struct rpc_audmgr_enable_client_args {
+	uint32_t set_to_one;
+	uint32_t tx_sample_rate;
+	uint32_t rx_sample_rate;
+	uint32_t def_method;
+	uint32_t codec_type;
+	uint32_t snd_method;
+
+	uint32_t cb_func;
+	uint32_t client_data;
+};
+
+#define AUDMGR_ENABLE_CLIENT			2
+#define AUDMGR_DISABLE_CLIENT			3
+#define AUDMGR_SUSPEND_EVENT_RSP		4
+#define AUDMGR_REGISTER_OPERATION_LISTENER	5
+#define AUDMGR_UNREGISTER_OPERATION_LISTENER	6
+#define AUDMGR_REGISTER_CODEC_LISTENER		7
+#define AUDMGR_GET_RX_SAMPLE_RATE		8
+#define AUDMGR_GET_TX_SAMPLE_RATE		9
+#define AUDMGR_SET_DEVICE_MODE			10
+
+#define AUDMGR_PROG 0x30000013
+#define AUDMGR_VERS MSM_RPC_VERS(1,0)
+
+struct rpc_audmgr_cb_func_ptr {
+	uint32_t cb_id;
+	uint32_t status; /* Audmgr status */
+	uint32_t set_to_one;  /* Pointer status (1 = valid, 0  = invalid) */
+	uint32_t disc;
+	/* disc = AUDMGR_STATUS_READY => data=handle
+	   disc = AUDMGR_STATUS_CODEC_CONFIG => data = handle
+	   disc = AUDMGR_STATUS_DISABLED => data =status_disabled
+	   disc = AUDMGR_STATUS_VOLUME_CHANGE => data = volume-change */
+	union {
+		uint32_t handle;
+		uint32_t volume;
+		uint32_t status_disabled;
+		uint32_t volume_change;
+	} u;
+};
+
+#define AUDMGR_CB_FUNC_PTR			1
+#define AUDMGR_OPR_LSTNR_CB_FUNC_PTR		2
+#define AUDMGR_CODEC_LSTR_FUNC_PTR		3
+
+#define AUDMGR_CB_PROG 0x31000013
+#define AUDMGR_CB_VERS 0xf8e3e2d9
+
+struct audmgr {
+	wait_queue_head_t wait;
+	uint32_t handle;
+	struct msm_rpc_endpoint *ept;
+	struct task_struct *task;
+	int state;
+};
+
+struct audmgr_config {
+	uint32_t tx_rate;
+	uint32_t rx_rate;
+	uint32_t def_method;
+	uint32_t codec;
+	uint32_t snd_method;
+};
+
+int audmgr_open(struct audmgr *am);
+int audmgr_close(struct audmgr *am);
+int audmgr_enable(struct audmgr *am, struct audmgr_config *cfg);
+int audmgr_disable(struct audmgr *am);
+
+typedef void (*audpp_event_func)(void *private, unsigned id, uint16_t *msg);
+
+int audpp_enable(int id, audpp_event_func func, void *private);
+void audpp_disable(int id, void *private);
+
+int audpp_send_queue1(void *cmd, unsigned len);
+int audpp_send_queue2(void *cmd, unsigned len);
+int audpp_send_queue3(void *cmd, unsigned len);
+
+int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan);
+int audpp_pause(unsigned id, int pause);
+int audpp_flush(unsigned id);
+void audpp_avsync(int id, unsigned rate);
+unsigned audpp_avsync_sample_count(int id);
+unsigned audpp_avsync_byte_count(int id);
+
+#endif
diff --git a/drivers/staging/dream/qdsp5/audpp.c b/drivers/staging/dream/qdsp5/audpp.c
new file mode 100644
index 0000000..d06556e
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/audpp.c
@@ -0,0 +1,429 @@
+
+/* arch/arm/mach-msm/qdsp5/audpp.c
+ *
+ * common code to deal with the AUDPP dsp task (audio postproc)
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include <mach/msm_adsp.h>
+
+#include "audmgr.h"
+
+#include <mach/qdsp5/qdsp5audppcmdi.h>
+#include <mach/qdsp5/qdsp5audppmsg.h>
+
+/* for queue ids - should be relative to module number*/
+#include "adsp.h"
+
+#include "evlog.h"
+
+
+enum {
+	EV_NULL,
+	EV_ENABLE,
+	EV_DISABLE,
+	EV_EVENT,
+	EV_DATA,
+};
+
+static const char *dsp_log_strings[] = {
+	"NULL",
+	"ENABLE",
+	"DISABLE",
+	"EVENT",
+	"DATA",
+};
+
+DECLARE_LOG(dsp_log, 64, dsp_log_strings);
+
+static int __init _dsp_log_init(void)
+{
+	return ev_log_init(&dsp_log);
+}
+module_init(_dsp_log_init);
+#define LOG(id,arg) ev_log_write(&dsp_log, id, arg)
+
+static DEFINE_MUTEX(audpp_lock);
+
+#define CH_COUNT 5
+#define AUDPP_CLNT_MAX_COUNT 6
+#define AUDPP_AVSYNC_INFO_SIZE 7
+
+struct audpp_state {
+	struct msm_adsp_module *mod;
+	audpp_event_func func[AUDPP_CLNT_MAX_COUNT];
+	void *private[AUDPP_CLNT_MAX_COUNT];
+	struct mutex *lock;
+	unsigned open_count;
+	unsigned enabled;
+
+	/* which channels are actually enabled */
+	unsigned avsync_mask;
+
+	/* flags, 48 bits sample/bytes counter per channel */
+	uint16_t avsync[CH_COUNT * AUDPP_CLNT_MAX_COUNT + 1];
+};
+
+struct audpp_state the_audpp_state = {
+	.lock = &audpp_lock,
+};
+
+int audpp_send_queue1(void *cmd, unsigned len)
+{
+	return msm_adsp_write(the_audpp_state.mod,
+			      QDSP_uPAudPPCmd1Queue, cmd, len);
+}
+EXPORT_SYMBOL(audpp_send_queue1);
+
+int audpp_send_queue2(void *cmd, unsigned len)
+{
+	return msm_adsp_write(the_audpp_state.mod,
+			      QDSP_uPAudPPCmd2Queue, cmd, len);
+}
+EXPORT_SYMBOL(audpp_send_queue2);
+
+int audpp_send_queue3(void *cmd, unsigned len)
+{
+	return msm_adsp_write(the_audpp_state.mod,
+			      QDSP_uPAudPPCmd3Queue, cmd, len);
+}
+EXPORT_SYMBOL(audpp_send_queue3);
+
+static int audpp_dsp_config(int enable)
+{
+	audpp_cmd_cfg cmd;
+
+	cmd.cmd_id = AUDPP_CMD_CFG;
+	cmd.cfg = enable ? AUDPP_CMD_CFG_ENABLE : AUDPP_CMD_CFG_SLEEP;
+
+	return audpp_send_queue1(&cmd, sizeof(cmd));
+}
+
+static void audpp_broadcast(struct audpp_state *audpp, unsigned id,
+			    uint16_t *msg)
+{
+	unsigned n;
+	for (n = 0; n < AUDPP_CLNT_MAX_COUNT; n++) {
+		if (audpp->func[n])
+			audpp->func[n] (audpp->private[n], id, msg);
+	}
+}
+
+static void audpp_notify_clnt(struct audpp_state *audpp, unsigned clnt_id,
+			      unsigned id, uint16_t *msg)
+{
+	if (clnt_id < AUDPP_CLNT_MAX_COUNT && audpp->func[clnt_id])
+		audpp->func[clnt_id] (audpp->private[clnt_id], id, msg);
+}
+
+static void audpp_dsp_event(void *data, unsigned id, size_t len,
+			    void (*getevent)(void *ptr, size_t len))
+{
+	struct audpp_state *audpp = data;
+	uint16_t msg[8];
+
+	if (id == AUDPP_MSG_AVSYNC_MSG) {
+		getevent(audpp->avsync, sizeof(audpp->avsync));
+
+		/* mask off any channels we're not watching to avoid
+		 * cases where we might get one last update after
+		 * disabling avsync and end up in an odd state when
+		 * we next read...
+		 */
+		audpp->avsync[0] &= audpp->avsync_mask;
+		return;
+	}
+
+	getevent(msg, sizeof(msg));
+
+	LOG(EV_EVENT, (id << 16) | msg[0]);
+	LOG(EV_DATA, (msg[1] << 16) | msg[2]);
+
+	switch (id) {
+	case AUDPP_MSG_STATUS_MSG:{
+			unsigned cid = msg[0];
+			pr_info("audpp: status %d %d %d\n", cid, msg[1],
+				msg[2]);
+			if ((cid < 5) && audpp->func[cid])
+				audpp->func[cid] (audpp->private[cid], id, msg);
+			break;
+		}
+	case AUDPP_MSG_HOST_PCM_INTF_MSG:
+		if (audpp->func[5])
+			audpp->func[5] (audpp->private[5], id, msg);
+		break;
+	case AUDPP_MSG_PCMDMAMISSED:
+		pr_err("audpp: DMA missed obj=%x\n", msg[0]);
+		break;
+	case AUDPP_MSG_CFG_MSG:
+		if (msg[0] == AUDPP_MSG_ENA_ENA) {
+			pr_info("audpp: ENABLE\n");
+			audpp->enabled = 1;
+			audpp_broadcast(audpp, id, msg);
+		} else if (msg[0] == AUDPP_MSG_ENA_DIS) {
+			pr_info("audpp: DISABLE\n");
+			audpp->enabled = 0;
+			audpp_broadcast(audpp, id, msg);
+		} else {
+			pr_err("audpp: invalid config msg %d\n", msg[0]);
+		}
+		break;
+	case AUDPP_MSG_ROUTING_ACK:
+		audpp_broadcast(audpp, id, msg);
+		break;
+	case AUDPP_MSG_FLUSH_ACK:
+		audpp_notify_clnt(audpp, msg[0], id, msg);
+		break;
+	default:
+	  pr_info("audpp: unhandled msg id %x\n", id);
+	}
+}
+
+static struct msm_adsp_ops adsp_ops = {
+	.event = audpp_dsp_event,
+};
+
+static void audpp_fake_event(struct audpp_state *audpp, int id,
+			     unsigned event, unsigned arg)
+{
+	uint16_t msg[1];
+	msg[0] = arg;
+	audpp->func[id] (audpp->private[id], event, msg);
+}
+
+int audpp_enable(int id, audpp_event_func func, void *private)
+{
+	struct audpp_state *audpp = &the_audpp_state;
+	int res = 0;
+
+	if (id < -1 || id > 4)
+		return -EINVAL;
+
+	if (id == -1)
+		id = 5;
+
+	mutex_lock(audpp->lock);
+	if (audpp->func[id]) {
+		res = -EBUSY;
+		goto out;
+	}
+
+	audpp->func[id] = func;
+	audpp->private[id] = private;
+
+	LOG(EV_ENABLE, 1);
+	if (audpp->open_count++ == 0) {
+		pr_info("audpp: enable\n");
+		res = msm_adsp_get("AUDPPTASK", &audpp->mod, &adsp_ops, audpp);
+		if (res < 0) {
+			pr_err("audpp: cannot open AUDPPTASK\n");
+			audpp->open_count = 0;
+			audpp->func[id] = NULL;
+			audpp->private[id] = NULL;
+			goto out;
+		}
+		LOG(EV_ENABLE, 2);
+		msm_adsp_enable(audpp->mod);
+		audpp_dsp_config(1);
+	} else {
+		unsigned long flags;
+		local_irq_save(flags);
+		if (audpp->enabled)
+			audpp_fake_event(audpp, id,
+					 AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_ENA);
+		local_irq_restore(flags);
+	}
+
+	res = 0;
+out:
+	mutex_unlock(audpp->lock);
+	return res;
+}
+EXPORT_SYMBOL(audpp_enable);
+
+void audpp_disable(int id, void *private)
+{
+	struct audpp_state *audpp = &the_audpp_state;
+	unsigned long flags;
+
+	if (id < -1 || id > 4)
+		return;
+
+	if (id == -1)
+		id = 5;
+
+	mutex_lock(audpp->lock);
+	LOG(EV_DISABLE, 1);
+	if (!audpp->func[id])
+		goto out;
+	if (audpp->private[id] != private)
+		goto out;
+
+	local_irq_save(flags);
+	audpp_fake_event(audpp, id, AUDPP_MSG_CFG_MSG, AUDPP_MSG_ENA_DIS);
+	audpp->func[id] = NULL;
+	audpp->private[id] = NULL;
+	local_irq_restore(flags);
+
+	if (--audpp->open_count == 0) {
+		pr_info("audpp: disable\n");
+		LOG(EV_DISABLE, 2);
+		audpp_dsp_config(0);
+		msm_adsp_disable(audpp->mod);
+		msm_adsp_put(audpp->mod);
+		audpp->mod = NULL;
+	}
+out:
+	mutex_unlock(audpp->lock);
+}
+EXPORT_SYMBOL(audpp_disable);
+
+#define BAD_ID(id) ((id < 0) || (id >= CH_COUNT))
+
+void audpp_avsync(int id, unsigned rate)
+{
+	unsigned long flags;
+	audpp_cmd_avsync cmd;
+
+	if (BAD_ID(id))
+		return;
+
+	local_irq_save(flags);
+	if (rate)
+		the_audpp_state.avsync_mask |= (1 << id);
+	else
+		the_audpp_state.avsync_mask &= (~(1 << id));
+	the_audpp_state.avsync[0] &= the_audpp_state.avsync_mask;
+	local_irq_restore(flags);
+
+	cmd.cmd_id = AUDPP_CMD_AVSYNC;
+	cmd.object_number = id;
+	cmd.interrupt_interval_lsw = rate;
+	cmd.interrupt_interval_msw = rate >> 16;
+	audpp_send_queue1(&cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_avsync);
+
+unsigned audpp_avsync_sample_count(int id)
+{
+	uint16_t *avsync = the_audpp_state.avsync;
+	unsigned val;
+	unsigned long flags;
+	unsigned mask;
+
+	if (BAD_ID(id))
+		return 0;
+
+	mask = 1 << id;
+	id = id * AUDPP_AVSYNC_INFO_SIZE + 2;
+	local_irq_save(flags);
+	if (avsync[0] & mask)
+		val = (avsync[id] << 16) | avsync[id + 1];
+	else
+		val = 0;
+	local_irq_restore(flags);
+
+	return val;
+}
+EXPORT_SYMBOL(audpp_avsync_sample_count);
+
+unsigned audpp_avsync_byte_count(int id)
+{
+	uint16_t *avsync = the_audpp_state.avsync;
+	unsigned val;
+	unsigned long flags;
+	unsigned mask;
+
+	if (BAD_ID(id))
+		return 0;
+
+	mask = 1 << id;
+	id = id * AUDPP_AVSYNC_INFO_SIZE + 5;
+	local_irq_save(flags);
+	if (avsync[0] & mask)
+		val = (avsync[id] << 16) | avsync[id + 1];
+	else
+		val = 0;
+	local_irq_restore(flags);
+
+	return val;
+}
+EXPORT_SYMBOL(audpp_avsync_byte_count);
+
+#define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
+#define AUDPP_CMD_VOLUME_PAN 0
+
+int audpp_set_volume_and_pan(unsigned id, unsigned volume, int pan)
+{
+	/* cmd, obj_cfg[7], cmd_type, volume, pan */
+	uint16_t cmd[11];
+
+	if (id > 6)
+		return -EINVAL;
+
+	memset(cmd, 0, sizeof(cmd));
+	cmd[0] = AUDPP_CMD_CFG_OBJECT_PARAMS;
+	cmd[1 + id] = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd[8] = AUDPP_CMD_VOLUME_PAN;
+	cmd[9] = volume;
+	cmd[10] = pan;
+
+	return audpp_send_queue3(cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_set_volume_and_pan);
+
+int audpp_pause(unsigned id, int pause)
+{
+	/* pause 1 = pause 0 = resume */
+	u16 pause_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
+
+	if (id >= CH_COUNT)
+		return -EINVAL;
+
+	memset(pause_cmd, 0, sizeof(pause_cmd));
+
+	pause_cmd[0] = AUDPP_CMD_DEC_CTRL;
+	if (pause == 1)
+		pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_PAUSE_V;
+	else if (pause == 0)
+		pause_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_RESUME_V;
+	else
+		return -EINVAL;
+
+	return audpp_send_queue1(pause_cmd, sizeof(pause_cmd));
+}
+EXPORT_SYMBOL(audpp_pause);
+
+int audpp_flush(unsigned id)
+{
+	u16 flush_cmd[AUDPP_CMD_DEC_CTRL_LEN / sizeof(unsigned short)];
+
+	if (id >= CH_COUNT)
+		return -EINVAL;
+
+	memset(flush_cmd, 0, sizeof(flush_cmd));
+
+	flush_cmd[0] = AUDPP_CMD_DEC_CTRL;
+	flush_cmd[1 + id] = AUDPP_CMD_UPDATE_V | AUDPP_CMD_FLUSH_V;
+
+	return audpp_send_queue1(flush_cmd, sizeof(flush_cmd));
+}
+EXPORT_SYMBOL(audpp_flush);
diff --git a/drivers/staging/dream/qdsp5/evlog.h b/drivers/staging/dream/qdsp5/evlog.h
new file mode 100644
index 0000000..922ce67
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/evlog.h
@@ -0,0 +1,133 @@
+/* arch/arm/mach-msm/qdsp5/evlog.h
+ *
+ * simple event log debugging facility
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/hrtimer.h>
+#include <linux/debugfs.h>
+
+#define EV_LOG_ENTRY_NAME(n) n##_entry
+
+#define DECLARE_LOG(_name, _size, _str) \
+static struct ev_entry EV_LOG_ENTRY_NAME(_name)[_size]; \
+static struct ev_log _name = { \
+	.name = #_name, \
+	.strings = _str, \
+	.num_strings = ARRAY_SIZE(_str), \
+	.entry = EV_LOG_ENTRY_NAME(_name), \
+	.max = ARRAY_SIZE(EV_LOG_ENTRY_NAME(_name)), \
+}
+
+struct ev_entry {
+	ktime_t when;
+	uint32_t id;
+	uint32_t arg;
+};
+
+struct ev_log {
+	struct ev_entry *entry;
+	unsigned max;
+	unsigned next;
+	unsigned fault;
+	const char **strings;
+	unsigned num_strings;
+	const char *name;
+};
+
+static char ev_buf[4096];
+
+static ssize_t ev_log_read(struct file *file, char __user *buf,
+			   size_t count, loff_t *ppos)
+{
+	struct ev_log *log = file->private_data;
+	struct ev_entry *entry;
+	unsigned long flags;
+	int size = 0;
+	unsigned n, id, max;
+	ktime_t now, t;
+
+	max = log->max;
+	now = ktime_get();
+	local_irq_save(flags);
+	n = (log->next - 1) & (max - 1);
+	entry = log->entry;
+	while (n != log->next) {
+		t = ktime_sub(now, entry[n].when);
+		id = entry[n].id;
+		if (id) {
+			const char *str;
+			if (id < log->num_strings)
+				str = log->strings[id];
+			else
+				str = "UNKNOWN";
+			size += scnprintf(ev_buf + size, 4096 - size,
+					  "%8d.%03d %08x %s\n",
+					  t.tv.sec, t.tv.nsec / 1000000,
+					  entry[n].arg, str);
+		}
+		n = (n - 1) & (max - 1);
+	}
+	log->fault = 0;
+	local_irq_restore(flags);
+	return simple_read_from_buffer(buf, count, ppos, ev_buf, size);
+}
+
+static void ev_log_write(struct ev_log *log, unsigned id, unsigned arg)
+{
+	struct ev_entry *entry;
+	unsigned long flags;
+	local_irq_save(flags);
+
+	if (log->fault) {
+		if (log->fault == 1)
+			goto done;
+		log->fault--;
+	}
+
+	entry = log->entry + log->next;
+	entry->when = ktime_get();
+	entry->id = id;
+	entry->arg = arg;
+	log->next = (log->next + 1) & (log->max - 1);
+done:
+	local_irq_restore(flags);
+}
+
+static void ev_log_freeze(struct ev_log *log, unsigned count)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	log->fault = count;
+	local_irq_restore(flags);
+}
+
+static int ev_log_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static const struct file_operations ev_log_ops = {
+	.read = ev_log_read,
+	.open = ev_log_open,
+};
+
+static int ev_log_init(struct ev_log *log)
+{
+	debugfs_create_file(log->name, 0444, 0, log, &ev_log_ops);
+	return 0;
+}
+
diff --git a/drivers/staging/dream/qdsp5/snd.c b/drivers/staging/dream/qdsp5/snd.c
new file mode 100644
index 0000000..037d7ff
--- /dev/null
+++ b/drivers/staging/dream/qdsp5/snd.c
@@ -0,0 +1,279 @@
+/* arch/arm/mach-msm/qdsp5/snd.c
+ *
+ * interface to "snd" service on the baseband cpu
+ *
+ * Copyright (C) 2008 HTC Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/msm_audio.h>
+
+#include <asm/atomic.h>
+#include <asm/ioctls.h>
+#include <mach/board.h>
+#include <mach/msm_rpcrouter.h>
+
+struct snd_ctxt {
+	struct mutex lock;
+	int opened;
+	struct msm_rpc_endpoint *ept;
+	struct msm_snd_endpoints *snd_epts;
+};
+
+static struct snd_ctxt the_snd;
+
+#define RPC_SND_PROG    0x30000002
+#define RPC_SND_CB_PROG 0x31000002
+#if CONFIG_MSM_AMSS_VERSION == 6210
+#define RPC_SND_VERS	0x94756085 /* 2490720389 */
+#elif (CONFIG_MSM_AMSS_VERSION == 6220) || \
+      (CONFIG_MSM_AMSS_VERSION == 6225)
+#define RPC_SND_VERS	0xaa2b1a44 /* 2854951492 */
+#elif CONFIG_MSM_AMSS_VERSION == 6350
+#define RPC_SND_VERS 	MSM_RPC_VERS(1,0)
+#endif
+
+#define SND_SET_DEVICE_PROC 2
+#define SND_SET_VOLUME_PROC 3
+
+struct rpc_snd_set_device_args {
+	uint32_t device;
+	uint32_t ear_mute;
+	uint32_t mic_mute;
+
+	uint32_t cb_func;
+	uint32_t client_data;
+};
+
+struct rpc_snd_set_volume_args {
+	uint32_t device;
+	uint32_t method;
+	uint32_t volume;
+
+	uint32_t cb_func;
+	uint32_t client_data;
+};
+
+struct snd_set_device_msg {
+	struct rpc_request_hdr hdr;
+	struct rpc_snd_set_device_args args;
+};
+
+struct snd_set_volume_msg {
+	struct rpc_request_hdr hdr;
+	struct rpc_snd_set_volume_args args;
+};
+
+struct snd_endpoint *get_snd_endpoints(int *size);
+
+static inline int check_mute(int mute)
+{
+	return (mute == SND_MUTE_MUTED ||
+		mute == SND_MUTE_UNMUTED) ? 0 : -EINVAL;
+}
+
+static int get_endpoint(struct snd_ctxt *snd, unsigned long arg)
+{
+	int rc = 0, index;
+	struct msm_snd_endpoint ept;
+
+	if (copy_from_user(&ept, (void __user *)arg, sizeof(ept))) {
+		pr_err("snd_ioctl get endpoint: invalid read pointer.\n");
+		return -EFAULT;
+	}
+
+	index = ept.id;
+	if (index < 0 || index >= snd->snd_epts->num) {
+		pr_err("snd_ioctl get endpoint: invalid index!\n");
+		return -EINVAL;
+	}
+
+	ept.id = snd->snd_epts->endpoints[index].id;
+	strncpy(ept.name,
+		snd->snd_epts->endpoints[index].name,
+		sizeof(ept.name));
+
+	if (copy_to_user((void __user *)arg, &ept, sizeof(ept))) {
+		pr_err("snd_ioctl get endpoint: invalid write pointer.\n");
+		rc = -EFAULT;
+	}
+
+	return rc;
+}
+
+static long snd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct snd_set_device_msg dmsg;
+	struct snd_set_volume_msg vmsg;
+	struct msm_snd_device_config dev;
+	struct msm_snd_volume_config vol;
+	struct snd_ctxt *snd = file->private_data;
+	int rc = 0;
+
+	mutex_lock(&snd->lock);
+	switch (cmd) {
+	case SND_SET_DEVICE:
+		if (copy_from_user(&dev, (void __user *) arg, sizeof(dev))) {
+			pr_err("snd_ioctl set device: invalid pointer.\n");
+			rc = -EFAULT;
+			break;
+		}
+
+		dmsg.args.device = cpu_to_be32(dev.device);
+		dmsg.args.ear_mute = cpu_to_be32(dev.ear_mute);
+		dmsg.args.mic_mute = cpu_to_be32(dev.mic_mute);
+		if (check_mute(dev.ear_mute) < 0 ||
+				check_mute(dev.mic_mute) < 0) {
+			pr_err("snd_ioctl set device: invalid mute status.\n");
+			rc = -EINVAL;
+			break;
+		}
+		dmsg.args.cb_func = -1;
+		dmsg.args.client_data = 0;
+
+		pr_info("snd_set_device %d %d %d\n", dev.device,
+						 dev.ear_mute, dev.mic_mute);
+
+		rc = msm_rpc_call(snd->ept,
+			SND_SET_DEVICE_PROC,
+			&dmsg, sizeof(dmsg), 5 * HZ);
+		break;
+
+	case SND_SET_VOLUME:
+		if (copy_from_user(&vol, (void __user *) arg, sizeof(vol))) {
+			pr_err("snd_ioctl set volume: invalid pointer.\n");
+			rc = -EFAULT;
+			break;
+		}
+
+		vmsg.args.device = cpu_to_be32(vol.device);
+		vmsg.args.method = cpu_to_be32(vol.method);
+		if (vol.method != SND_METHOD_VOICE) {
+			pr_err("snd_ioctl set volume: invalid method.\n");
+			rc = -EINVAL;
+			break;
+		}
+
+		vmsg.args.volume = cpu_to_be32(vol.volume);
+		vmsg.args.cb_func = -1;
+		vmsg.args.client_data = 0;
+
+		pr_info("snd_set_volume %d %d %d\n", vol.device,
+						vol.method, vol.volume);
+
+		rc = msm_rpc_call(snd->ept,
+			SND_SET_VOLUME_PROC,
+			&vmsg, sizeof(vmsg), 5 * HZ);
+		break;
+
+	case SND_GET_NUM_ENDPOINTS:
+		if (copy_to_user((void __user *)arg,
+				&snd->snd_epts->num, sizeof(unsigned))) {
+			pr_err("snd_ioctl get endpoint: invalid pointer.\n");
+			rc = -EFAULT;
+		}
+		break;
+
+	case SND_GET_ENDPOINT:
+		rc = get_endpoint(snd, arg);
+		break;
+
+	default:
+		pr_err("snd_ioctl unknown command.\n");
+		rc = -EINVAL;
+		break;
+	}
+	mutex_unlock(&snd->lock);
+
+	return rc;
+}
+
+static int snd_release(struct inode *inode, struct file *file)
+{
+	struct snd_ctxt *snd = file->private_data;
+
+	mutex_lock(&snd->lock);
+	snd->opened = 0;
+	mutex_unlock(&snd->lock);
+	return 0;
+}
+
+static int snd_open(struct inode *inode, struct file *file)
+{
+	struct snd_ctxt *snd = &the_snd;
+	int rc = 0;
+
+	mutex_lock(&snd->lock);
+	if (snd->opened == 0) {
+		if (snd->ept == NULL) {
+			snd->ept = msm_rpc_connect(RPC_SND_PROG, RPC_SND_VERS,
+					MSM_RPC_UNINTERRUPTIBLE);
+			if (IS_ERR(snd->ept)) {
+				rc = PTR_ERR(snd->ept);
+				snd->ept = NULL;
+				pr_err("snd: failed to connect snd svc\n");
+				goto err;
+			}
+		}
+		file->private_data = snd;
+		snd->opened = 1;
+	} else {
+		pr_err("snd already opened.\n");
+		rc = -EBUSY;
+	}
+
+err:
+	mutex_unlock(&snd->lock);
+	return rc;
+}
+
+static struct file_operations snd_fops = {
+	.owner		= THIS_MODULE,
+	.open		= snd_open,
+	.release	= snd_release,
+	.unlocked_ioctl	= snd_ioctl,
+};
+
+struct miscdevice snd_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= "msm_snd",
+	.fops	= &snd_fops,
+};
+
+static int snd_probe(struct platform_device *pdev)
+{
+	struct snd_ctxt *snd = &the_snd;
+	mutex_init(&snd->lock);
+	snd->snd_epts = (struct msm_snd_endpoints *)pdev->dev.platform_data;
+	return misc_register(&snd_misc);
+}
+
+static struct platform_driver snd_plat_driver = {
+	.probe = snd_probe,
+	.driver = {
+		.name = "msm_snd",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init snd_init(void)
+{
+	return platform_driver_register(&snd_plat_driver);
+}
+
+module_init(snd_init);
diff --git a/drivers/staging/dream/smd/Kconfig b/drivers/staging/dream/smd/Kconfig
new file mode 100644
index 0000000..17b8bdc
--- /dev/null
+++ b/drivers/staging/dream/smd/Kconfig
@@ -0,0 +1,26 @@
+config MSM_SMD
+	depends on ARCH_MSM
+	default y
+	bool "MSM Shared Memory Driver (SMD)"
+	help
+	  Support for the shared memory interface between the apps
+	  processor and the baseband processor.  Provides access to
+	  the "shared heap", as well as virtual serial channels
+	  used to communicate with various services on the baseband
+	  processor.
+
+config MSM_ONCRPCROUTER
+	depends on MSM_SMD
+	default y
+	bool "MSM ONCRPC router support"
+	help
+	  Support for the MSM ONCRPC router for communication between
+	  the ARM9 and ARM11
+
+config MSM_RPCSERVERS
+	depends on MSM_ONCRPCROUTER
+	default y
+	bool "Kernel side RPC server bundle"
+	help
+	  none
+
diff --git a/drivers/staging/dream/smd/Makefile b/drivers/staging/dream/smd/Makefile
new file mode 100644
index 0000000..892c741
--- /dev/null
+++ b/drivers/staging/dream/smd/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_MSM_SMD) += smd.o smd_tty.o smd_qmi.o
+obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter.o
+obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_device.o
+obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_servers.o
+obj-$(CONFIG_MSM_RPCSERVERS) += rpc_server_dog_keepalive.o
+obj-$(CONFIG_MSM_RPCSERVERS) += rpc_server_time_remote.o
diff --git a/drivers/staging/dream/smd/rpc_server_dog_keepalive.c b/drivers/staging/dream/smd/rpc_server_dog_keepalive.c
new file mode 100644
index 0000000..b23fccf
--- /dev/null
+++ b/drivers/staging/dream/smd/rpc_server_dog_keepalive.c
@@ -0,0 +1,68 @@
+/* arch/arm/mach-msm/rpc_server_dog_keepalive.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Iliyan Malchev <ibm@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/msm_rpcrouter.h>
+
+/* dog_keepalive server definitions */
+
+#define DOG_KEEPALIVE_PROG 0x30000015
+#if CONFIG_MSM_AMSS_VERSION==6210
+#define DOG_KEEPALIVE_VERS 0
+#define RPC_DOG_KEEPALIVE_BEACON 1
+#elif (CONFIG_MSM_AMSS_VERSION==6220) || (CONFIG_MSM_AMSS_VERSION==6225)
+#define DOG_KEEPALIVE_VERS 0x731fa727
+#define RPC_DOG_KEEPALIVE_BEACON 2
+#elif CONFIG_MSM_AMSS_VERSION==6350
+#define DOG_KEEPALIVE_VERS 0x00010000
+#define RPC_DOG_KEEPALIVE_BEACON 2
+#else
+#error "Unsupported AMSS version"
+#endif
+#define RPC_DOG_KEEPALIVE_NULL 0
+
+
+/* TODO: Remove server registration with _VERS when modem is upated with _COMP*/
+
+static int handle_rpc_call(struct msm_rpc_server *server,
+			   struct rpc_request_hdr *req, unsigned len)
+{
+	switch (req->procedure) {
+	case RPC_DOG_KEEPALIVE_NULL:
+		return 0;
+	case RPC_DOG_KEEPALIVE_BEACON:
+		printk(KERN_INFO "DOG KEEPALIVE PING\n");
+		return 0;
+	default:
+		return -ENODEV;
+	}
+}
+
+static struct msm_rpc_server rpc_server = {
+	.prog = DOG_KEEPALIVE_PROG,
+	.vers = DOG_KEEPALIVE_VERS,
+	.rpc_call = handle_rpc_call,
+};
+
+static int __init rpc_server_init(void)
+{
+	/* Dual server registration to support backwards compatibility vers */
+	return msm_rpc_create_server(&rpc_server);
+}
+
+
+module_init(rpc_server_init);
diff --git a/drivers/staging/dream/smd/rpc_server_time_remote.c b/drivers/staging/dream/smd/rpc_server_time_remote.c
new file mode 100644
index 0000000..2f90fc8
--- /dev/null
+++ b/drivers/staging/dream/smd/rpc_server_time_remote.c
@@ -0,0 +1,77 @@
+/* arch/arm/mach-msm/rpc_server_time_remote.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Iliyan Malchev <ibm@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/msm_rpcrouter.h>
+
+/* time_remote_mtoa server definitions. */
+
+#define TIME_REMOTE_MTOA_PROG 0x3000005d
+#if CONFIG_MSM_AMSS_VERSION==6210
+#define TIME_REMOTE_MTOA_VERS 0
+#elif (CONFIG_MSM_AMSS_VERSION==6220) || (CONFIG_MSM_AMSS_VERSION==6225)
+#define TIME_REMOTE_MTOA_VERS 0x9202a8e4
+#elif CONFIG_MSM_AMSS_VERSION==6350
+#define TIME_REMOTE_MTOA_VERS 0x00010000
+#else
+#error "Unknown AMSS version"
+#endif
+#define RPC_TIME_REMOTE_MTOA_NULL   0
+#define RPC_TIME_TOD_SET_APPS_BASES 2
+
+struct rpc_time_tod_set_apps_bases_args {
+	uint32_t tick;
+	uint64_t stamp;
+};
+
+static int handle_rpc_call(struct msm_rpc_server *server,
+			   struct rpc_request_hdr *req, unsigned len)
+{
+	switch (req->procedure) {
+	case RPC_TIME_REMOTE_MTOA_NULL:
+		return 0;
+
+	case RPC_TIME_TOD_SET_APPS_BASES: {
+		struct rpc_time_tod_set_apps_bases_args *args;
+		args = (struct rpc_time_tod_set_apps_bases_args *)(req + 1);
+		args->tick = be32_to_cpu(args->tick);
+		args->stamp = be64_to_cpu(args->stamp);
+		printk(KERN_INFO "RPC_TIME_TOD_SET_APPS_BASES:\n"
+		       "\ttick = %d\n"
+		       "\tstamp = %lld\n",
+		       args->tick, args->stamp);
+		return 0;
+	}
+	default:
+		return -ENODEV;
+	}
+}
+
+static struct msm_rpc_server rpc_server = {
+	.prog = TIME_REMOTE_MTOA_PROG,
+	.vers = TIME_REMOTE_MTOA_VERS,
+	.rpc_call = handle_rpc_call,
+};
+
+static int __init rpc_server_init(void)
+{
+	/* Dual server registration to support backwards compatibility vers */
+	return msm_rpc_create_server(&rpc_server);
+}
+
+
+module_init(rpc_server_init);
diff --git a/drivers/staging/dream/smd/smd.c b/drivers/staging/dream/smd/smd.c
new file mode 100644
index 0000000..8f35be7
--- /dev/null
+++ b/drivers/staging/dream/smd/smd.c
@@ -0,0 +1,1330 @@
+/* arch/arm/mach-msm/smd.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/platform_device.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <mach/msm_smd.h>
+#include <mach/msm_iomap.h>
+#include <mach/system.h>
+
+#include "smd_private.h"
+#include "../../../../arch/arm/mach-msm/proc_comm.h"
+
+void (*msm_hw_reset_hook)(void);
+
+#define MODULE_NAME "msm_smd"
+
+enum {
+	MSM_SMD_DEBUG = 1U << 0,
+	MSM_SMSM_DEBUG = 1U << 0,
+};
+
+static int msm_smd_debug_mask;
+
+module_param_named(debug_mask, msm_smd_debug_mask,
+		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+void *smem_find(unsigned id, unsigned size);
+static void smd_diag(void);
+
+static unsigned last_heap_free = 0xffffffff;
+
+#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
+
+static inline void notify_other_smsm(void)
+{
+	writel(1, MSM_A2M_INT(5));
+}
+
+static inline void notify_other_smd(void)
+{
+	writel(1, MSM_A2M_INT(0));
+}
+
+static void smd_diag(void)
+{
+	char *x;
+
+	x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+	if (x != 0) {
+		x[SZ_DIAG_ERR_MSG - 1] = 0;
+		pr_info("smem: DIAG '%s'\n", x);
+	}
+}
+
+/* call when SMSM_RESET flag is set in the A9's smsm_state */
+static void handle_modem_crash(void)
+{
+	pr_err("ARM9 has CRASHED\n");
+	smd_diag();
+
+	/* hard reboot if possible */
+	if (msm_hw_reset_hook)
+		msm_hw_reset_hook();
+
+	/* in this case the modem or watchdog should reboot us */
+	for (;;)
+		;
+}
+
+extern int (*msm_check_for_modem_crash)(void);
+
+static int check_for_modem_crash(void)
+{
+	struct smsm_shared *smsm;
+
+	smsm = smem_find(ID_SHARED_STATE, 2 * sizeof(struct smsm_shared));
+
+	/* if the modem's not ready yet, we have to hope for the best */
+	if (!smsm)
+		return 0;
+
+	if (smsm[1].state & SMSM_RESET) {
+		handle_modem_crash();
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+#define SMD_SS_CLOSED            0x00000000
+#define SMD_SS_OPENING           0x00000001
+#define SMD_SS_OPENED            0x00000002
+#define SMD_SS_FLUSHING          0x00000003
+#define SMD_SS_CLOSING           0x00000004
+#define SMD_SS_RESET             0x00000005
+#define SMD_SS_RESET_OPENING     0x00000006
+
+#define SMD_BUF_SIZE 8192
+#define SMD_CHANNELS 64
+
+#define SMD_HEADER_SIZE 20
+
+
+/* the spinlock is used to synchronize between the
+** irq handler and code that mutates the channel
+** list or fiddles with channel state
+*/
+static DEFINE_SPINLOCK(smd_lock);
+static DEFINE_SPINLOCK(smem_lock);
+
+/* the mutex is used during open() and close()
+** operations to avoid races while creating or
+** destroying smd_channel structures
+*/
+static DEFINE_MUTEX(smd_creation_mutex);
+
+static int smd_initialized;
+
+struct smd_alloc_elm {
+	char name[20];
+	uint32_t cid;
+	uint32_t ctype;
+	uint32_t ref_count;
+};
+
+struct smd_half_channel {
+	unsigned state;
+	unsigned char fDSR;
+	unsigned char fCTS;
+	unsigned char fCD;
+	unsigned char fRI;
+	unsigned char fHEAD;
+	unsigned char fTAIL;
+	unsigned char fSTATE;
+	unsigned char fUNUSED;
+	unsigned tail;
+	unsigned head;
+	unsigned char data[SMD_BUF_SIZE];
+};
+
+struct smd_shared {
+	struct smd_half_channel ch0;
+	struct smd_half_channel ch1;
+};
+
+struct smd_channel {
+	volatile struct smd_half_channel *send;
+	volatile struct smd_half_channel *recv;
+	struct list_head ch_list;
+
+	unsigned current_packet;
+	unsigned n;
+	void *priv;
+	void (*notify)(void *priv, unsigned flags);
+
+	int (*read)(smd_channel_t *ch, void *data, int len);
+	int (*write)(smd_channel_t *ch, const void *data, int len);
+	int (*read_avail)(smd_channel_t *ch);
+	int (*write_avail)(smd_channel_t *ch);
+
+	void (*update_state)(smd_channel_t *ch);
+	unsigned last_state;
+
+	char name[32];
+	struct platform_device pdev;
+};
+
+static LIST_HEAD(smd_ch_closed_list);
+static LIST_HEAD(smd_ch_list);
+
+static unsigned char smd_ch_allocated[64];
+static struct work_struct probe_work;
+
+static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type);
+
+static void smd_channel_probe_worker(struct work_struct *work)
+{
+	struct smd_alloc_elm *shared;
+	unsigned n;
+
+	shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+
+	for (n = 0; n < 64; n++) {
+		if (smd_ch_allocated[n])
+			continue;
+		if (!shared[n].ref_count)
+			continue;
+		if (!shared[n].name[0])
+			continue;
+		smd_alloc_channel(shared[n].name,
+				  shared[n].cid,
+				  shared[n].ctype);
+		smd_ch_allocated[n] = 1;
+	}
+}
+
+static char *chstate(unsigned n)
+{
+	switch (n) {
+	case SMD_SS_CLOSED:
+		return "CLOSED";
+	case SMD_SS_OPENING:
+		return "OPENING";
+	case SMD_SS_OPENED:
+		return "OPENED";
+	case SMD_SS_FLUSHING:
+		return "FLUSHING";
+	case SMD_SS_CLOSING:
+		return "CLOSING";
+	case SMD_SS_RESET:
+		return "RESET";
+	case SMD_SS_RESET_OPENING:
+		return "ROPENING";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+/* how many bytes are available for reading */
+static int smd_stream_read_avail(struct smd_channel *ch)
+{
+	return (ch->recv->head - ch->recv->tail) & (SMD_BUF_SIZE - 1);
+}
+
+/* how many bytes we are free to write */
+static int smd_stream_write_avail(struct smd_channel *ch)
+{
+	return (SMD_BUF_SIZE - 1) -
+		((ch->send->head - ch->send->tail) & (SMD_BUF_SIZE - 1));
+}
+
+static int smd_packet_read_avail(struct smd_channel *ch)
+{
+	if (ch->current_packet) {
+		int n = smd_stream_read_avail(ch);
+		if (n > ch->current_packet)
+			n = ch->current_packet;
+		return n;
+	} else {
+		return 0;
+	}
+}
+
+static int smd_packet_write_avail(struct smd_channel *ch)
+{
+	int n = smd_stream_write_avail(ch);
+	return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
+}
+
+static int ch_is_open(struct smd_channel *ch)
+{
+	return (ch->recv->state == SMD_SS_OPENED) &&
+		(ch->send->state == SMD_SS_OPENED);
+}
+
+/* provide a pointer and length to readable data in the fifo */
+static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
+{
+	unsigned head = ch->recv->head;
+	unsigned tail = ch->recv->tail;
+	*ptr = (void *) (ch->recv->data + tail);
+
+	if (tail <= head)
+		return head - tail;
+	else
+		return SMD_BUF_SIZE - tail;
+}
+
+/* advance the fifo read pointer after data from ch_read_buffer is consumed */
+static void ch_read_done(struct smd_channel *ch, unsigned count)
+{
+	BUG_ON(count > smd_stream_read_avail(ch));
+	ch->recv->tail = (ch->recv->tail + count) & (SMD_BUF_SIZE - 1);
+	ch->recv->fTAIL = 1;
+}
+
+/* basic read interface to ch_read_{buffer,done} used
+** by smd_*_read() and update_packet_state()
+** will read-and-discard if the _data pointer is null
+*/
+static int ch_read(struct smd_channel *ch, void *_data, int len)
+{
+	void *ptr;
+	unsigned n;
+	unsigned char *data = _data;
+	int orig_len = len;
+
+	while (len > 0) {
+		n = ch_read_buffer(ch, &ptr);
+		if (n == 0)
+			break;
+
+		if (n > len)
+			n = len;
+		if (_data)
+			memcpy(data, ptr, n);
+
+		data += n;
+		len -= n;
+		ch_read_done(ch, n);
+	}
+
+	return orig_len - len;
+}
+
+static void update_stream_state(struct smd_channel *ch)
+{
+	/* streams have no special state requiring updating */
+}
+
+static void update_packet_state(struct smd_channel *ch)
+{
+	unsigned hdr[5];
+	int r;
+
+	/* can't do anything if we're in the middle of a packet */
+	if (ch->current_packet != 0)
+		return;
+
+	/* don't bother unless we can get the full header */
+	if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
+		return;
+
+	r = ch_read(ch, hdr, SMD_HEADER_SIZE);
+	BUG_ON(r != SMD_HEADER_SIZE);
+
+	ch->current_packet = hdr[0];
+}
+
+/* provide a pointer and length to next free space in the fifo */
+static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
+{
+	unsigned head = ch->send->head;
+	unsigned tail = ch->send->tail;
+	*ptr = (void *) (ch->send->data + head);
+
+	if (head < tail) {
+		return tail - head - 1;
+	} else {
+		if (tail == 0)
+			return SMD_BUF_SIZE - head - 1;
+		else
+			return SMD_BUF_SIZE - head;
+	}
+}
+
+/* advace the fifo write pointer after freespace
+ * from ch_write_buffer is filled
+ */
+static void ch_write_done(struct smd_channel *ch, unsigned count)
+{
+	BUG_ON(count > smd_stream_write_avail(ch));
+	ch->send->head = (ch->send->head + count) & (SMD_BUF_SIZE - 1);
+	ch->send->fHEAD = 1;
+}
+
+static void hc_set_state(volatile struct smd_half_channel *hc, unsigned n)
+{
+	if (n == SMD_SS_OPENED) {
+		hc->fDSR = 1;
+		hc->fCTS = 1;
+		hc->fCD = 1;
+	} else {
+		hc->fDSR = 0;
+		hc->fCTS = 0;
+		hc->fCD = 0;
+	}
+	hc->state = n;
+	hc->fSTATE = 1;
+	notify_other_smd();
+}
+
+static void do_smd_probe(void)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	if (shared->heap_info.free_offset != last_heap_free) {
+		last_heap_free = shared->heap_info.free_offset;
+		schedule_work(&probe_work);
+	}
+}
+
+static void smd_state_change(struct smd_channel *ch,
+			     unsigned last, unsigned next)
+{
+	ch->last_state = next;
+
+	pr_info("SMD: ch %d %s -> %s\n", ch->n,
+		chstate(last), chstate(next));
+
+	switch (next) {
+	case SMD_SS_OPENING:
+		ch->recv->tail = 0;
+	case SMD_SS_OPENED:
+		if (ch->send->state != SMD_SS_OPENED)
+			hc_set_state(ch->send, SMD_SS_OPENED);
+		ch->notify(ch->priv, SMD_EVENT_OPEN);
+		break;
+	case SMD_SS_FLUSHING:
+	case SMD_SS_RESET:
+		/* we should force them to close? */
+	default:
+		ch->notify(ch->priv, SMD_EVENT_CLOSE);
+	}
+}
+
+static irqreturn_t smd_irq_handler(int irq, void *data)
+{
+	unsigned long flags;
+	struct smd_channel *ch;
+	int do_notify = 0;
+	unsigned ch_flags;
+	unsigned tmp;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	list_for_each_entry(ch, &smd_ch_list, ch_list) {
+		ch_flags = 0;
+		if (ch_is_open(ch)) {
+			if (ch->recv->fHEAD) {
+				ch->recv->fHEAD = 0;
+				ch_flags |= 1;
+				do_notify |= 1;
+			}
+			if (ch->recv->fTAIL) {
+				ch->recv->fTAIL = 0;
+				ch_flags |= 2;
+				do_notify |= 1;
+			}
+			if (ch->recv->fSTATE) {
+				ch->recv->fSTATE = 0;
+				ch_flags |= 4;
+				do_notify |= 1;
+			}
+		}
+		tmp = ch->recv->state;
+		if (tmp != ch->last_state)
+			smd_state_change(ch, ch->last_state, tmp);
+		if (ch_flags) {
+			ch->update_state(ch);
+			ch->notify(ch->priv, SMD_EVENT_DATA);
+		}
+	}
+	if (do_notify)
+		notify_other_smd();
+	spin_unlock_irqrestore(&smd_lock, flags);
+	do_smd_probe();
+	return IRQ_HANDLED;
+}
+
+static void smd_fake_irq_handler(unsigned long arg)
+{
+	smd_irq_handler(0, NULL);
+}
+
+static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
+
+void smd_sleep_exit(void)
+{
+	unsigned long flags;
+	struct smd_channel *ch;
+	unsigned tmp;
+	int need_int = 0;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	list_for_each_entry(ch, &smd_ch_list, ch_list) {
+		if (ch_is_open(ch)) {
+			if (ch->recv->fHEAD) {
+				if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+					pr_info("smd_sleep_exit ch %d fHEAD "
+						"%x %x %x\n",
+						ch->n, ch->recv->fHEAD,
+						ch->recv->head, ch->recv->tail);
+				need_int = 1;
+				break;
+			}
+			if (ch->recv->fTAIL) {
+				if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+					pr_info("smd_sleep_exit ch %d fTAIL "
+						"%x %x %x\n",
+						ch->n, ch->recv->fTAIL,
+						ch->send->head, ch->send->tail);
+				need_int = 1;
+				break;
+			}
+			if (ch->recv->fSTATE) {
+				if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+					pr_info("smd_sleep_exit ch %d fSTATE %x"
+						"\n", ch->n, ch->recv->fSTATE);
+				need_int = 1;
+				break;
+			}
+			tmp = ch->recv->state;
+			if (tmp != ch->last_state) {
+				if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+					pr_info("smd_sleep_exit ch %d "
+						"state %x != %x\n",
+						ch->n, tmp, ch->last_state);
+				need_int = 1;
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&smd_lock, flags);
+	do_smd_probe();
+	if (need_int) {
+		if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+			pr_info("smd_sleep_exit need interrupt\n");
+		tasklet_schedule(&smd_fake_irq_tasklet);
+	}
+}
+
+
+void smd_kick(smd_channel_t *ch)
+{
+	unsigned long flags;
+	unsigned tmp;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	ch->update_state(ch);
+	tmp = ch->recv->state;
+	if (tmp != ch->last_state) {
+		ch->last_state = tmp;
+		if (tmp == SMD_SS_OPENED)
+			ch->notify(ch->priv, SMD_EVENT_OPEN);
+		else
+			ch->notify(ch->priv, SMD_EVENT_CLOSE);
+	}
+	ch->notify(ch->priv, SMD_EVENT_DATA);
+	notify_other_smd();
+	spin_unlock_irqrestore(&smd_lock, flags);
+}
+
+static int smd_is_packet(int chn)
+{
+	if ((chn > 4) || (chn == 1))
+		return 1;
+	else
+		return 0;
+}
+
+static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
+{
+	void *ptr;
+	const unsigned char *buf = _data;
+	unsigned xfer;
+	int orig_len = len;
+
+	if (len < 0)
+		return -EINVAL;
+
+	while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
+		if (!ch_is_open(ch))
+			break;
+		if (xfer > len)
+			xfer = len;
+		memcpy(ptr, buf, xfer);
+		ch_write_done(ch, xfer);
+		len -= xfer;
+		buf += xfer;
+		if (len == 0)
+			break;
+	}
+
+	notify_other_smd();
+
+	return orig_len - len;
+}
+
+static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
+{
+	unsigned hdr[5];
+
+	if (len < 0)
+		return -EINVAL;
+
+	if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
+		return -ENOMEM;
+
+	hdr[0] = len;
+	hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
+
+	smd_stream_write(ch, hdr, sizeof(hdr));
+	smd_stream_write(ch, _data, len);
+
+	return len;
+}
+
+static int smd_stream_read(smd_channel_t *ch, void *data, int len)
+{
+	int r;
+
+	if (len < 0)
+		return -EINVAL;
+
+	r = ch_read(ch, data, len);
+	if (r > 0)
+		notify_other_smd();
+
+	return r;
+}
+
+static int smd_packet_read(smd_channel_t *ch, void *data, int len)
+{
+	unsigned long flags;
+	int r;
+
+	if (len < 0)
+		return -EINVAL;
+
+	if (len > ch->current_packet)
+		len = ch->current_packet;
+
+	r = ch_read(ch, data, len);
+	if (r > 0)
+		notify_other_smd();
+
+	spin_lock_irqsave(&smd_lock, flags);
+	ch->current_packet -= r;
+	update_packet_state(ch);
+	spin_unlock_irqrestore(&smd_lock, flags);
+
+	return r;
+}
+
+static void smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
+{
+	struct smd_channel *ch;
+	struct smd_shared *shared;
+
+	shared = smem_alloc(ID_SMD_CHANNELS + cid, sizeof(*shared));
+	if (!shared) {
+		pr_err("smd_alloc_channel() cid %d does not exist\n", cid);
+		return;
+	}
+
+	ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
+	if (ch == 0) {
+		pr_err("smd_alloc_channel() out of memory\n");
+		return;
+	}
+
+	ch->send = &shared->ch0;
+	ch->recv = &shared->ch1;
+	ch->n = cid;
+
+	if (smd_is_packet(cid)) {
+		ch->read = smd_packet_read;
+		ch->write = smd_packet_write;
+		ch->read_avail = smd_packet_read_avail;
+		ch->write_avail = smd_packet_write_avail;
+		ch->update_state = update_packet_state;
+	} else {
+		ch->read = smd_stream_read;
+		ch->write = smd_stream_write;
+		ch->read_avail = smd_stream_read_avail;
+		ch->write_avail = smd_stream_write_avail;
+		ch->update_state = update_stream_state;
+	}
+
+	memcpy(ch->name, "SMD_", 4);
+	memcpy(ch->name + 4, name, 20);
+	ch->name[23] = 0;
+	ch->pdev.name = ch->name;
+	ch->pdev.id = -1;
+
+	pr_info("smd_alloc_channel() '%s' cid=%d, shared=%p\n",
+		ch->name, ch->n, shared);
+
+	mutex_lock(&smd_creation_mutex);
+	list_add(&ch->ch_list, &smd_ch_closed_list);
+	mutex_unlock(&smd_creation_mutex);
+
+	platform_device_register(&ch->pdev);
+}
+
+static void do_nothing_notify(void *priv, unsigned flags)
+{
+}
+
+struct smd_channel *smd_get_channel(const char *name)
+{
+	struct smd_channel *ch;
+
+	mutex_lock(&smd_creation_mutex);
+	list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
+		if (!strcmp(name, ch->name)) {
+			list_del(&ch->ch_list);
+			mutex_unlock(&smd_creation_mutex);
+			return ch;
+		}
+	}
+	mutex_unlock(&smd_creation_mutex);
+
+	return NULL;
+}
+
+int smd_open(const char *name, smd_channel_t **_ch,
+	     void *priv, void (*notify)(void *, unsigned))
+{
+	struct smd_channel *ch;
+	unsigned long flags;
+
+	if (smd_initialized == 0) {
+		pr_info("smd_open() before smd_init()\n");
+		return -ENODEV;
+	}
+
+	ch = smd_get_channel(name);
+	if (!ch)
+		return -ENODEV;
+
+	if (notify == 0)
+		notify = do_nothing_notify;
+
+	ch->notify = notify;
+	ch->current_packet = 0;
+	ch->last_state = SMD_SS_CLOSED;
+	ch->priv = priv;
+
+	*_ch = ch;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	list_add(&ch->ch_list, &smd_ch_list);
+
+	/* If the remote side is CLOSING, we need to get it to
+	 * move to OPENING (which we'll do by moving from CLOSED to
+	 * OPENING) and then get it to move from OPENING to
+	 * OPENED (by doing the same state change ourselves).
+	 *
+	 * Otherwise, it should be OPENING and we can move directly
+	 * to OPENED so that it will follow.
+	 */
+	if (ch->recv->state == SMD_SS_CLOSING) {
+		ch->send->head = 0;
+		hc_set_state(ch->send, SMD_SS_OPENING);
+	} else {
+		hc_set_state(ch->send, SMD_SS_OPENED);
+	}
+	spin_unlock_irqrestore(&smd_lock, flags);
+	smd_kick(ch);
+
+	return 0;
+}
+
+int smd_close(smd_channel_t *ch)
+{
+	unsigned long flags;
+
+	pr_info("smd_close(%p)\n", ch);
+
+	if (ch == 0)
+		return -1;
+
+	spin_lock_irqsave(&smd_lock, flags);
+	ch->notify = do_nothing_notify;
+	list_del(&ch->ch_list);
+	hc_set_state(ch->send, SMD_SS_CLOSED);
+	spin_unlock_irqrestore(&smd_lock, flags);
+
+	mutex_lock(&smd_creation_mutex);
+	list_add(&ch->ch_list, &smd_ch_closed_list);
+	mutex_unlock(&smd_creation_mutex);
+
+	return 0;
+}
+
+int smd_read(smd_channel_t *ch, void *data, int len)
+{
+	return ch->read(ch, data, len);
+}
+
+int smd_write(smd_channel_t *ch, const void *data, int len)
+{
+	return ch->write(ch, data, len);
+}
+
+int smd_read_avail(smd_channel_t *ch)
+{
+	return ch->read_avail(ch);
+}
+
+int smd_write_avail(smd_channel_t *ch)
+{
+	return ch->write_avail(ch);
+}
+
+int smd_wait_until_readable(smd_channel_t *ch, int bytes)
+{
+	return -1;
+}
+
+int smd_wait_until_writable(smd_channel_t *ch, int bytes)
+{
+	return -1;
+}
+
+int smd_cur_packet_size(smd_channel_t *ch)
+{
+	return ch->current_packet;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+void *smem_alloc(unsigned id, unsigned size)
+{
+	return smem_find(id, size);
+}
+
+static void *_smem_find(unsigned id, unsigned *size)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	struct smem_heap_entry *toc = shared->heap_toc;
+
+	if (id >= SMEM_NUM_ITEMS)
+		return 0;
+
+	if (toc[id].allocated) {
+		*size = toc[id].size;
+		return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset);
+	}
+
+	return 0;
+}
+
+void *smem_find(unsigned id, unsigned size_in)
+{
+	unsigned size;
+	void *ptr;
+
+	ptr = _smem_find(id, &size);
+	if (!ptr)
+		return 0;
+
+	size_in = ALIGN(size_in, 8);
+	if (size_in != size) {
+		pr_err("smem_find(%d, %d): wrong size %d\n",
+		       id, size_in, size);
+		return 0;
+	}
+
+	return ptr;
+}
+
+static irqreturn_t smsm_irq_handler(int irq, void *data)
+{
+	unsigned long flags;
+	struct smsm_shared *smsm;
+
+	spin_lock_irqsave(&smem_lock, flags);
+	smsm = smem_alloc(ID_SHARED_STATE,
+			  2 * sizeof(struct smsm_shared));
+
+	if (smsm == 0) {
+		pr_info("<SM NO STATE>\n");
+	} else {
+		unsigned apps = smsm[0].state;
+		unsigned modm = smsm[1].state;
+
+		if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+			pr_info("<SM %08x %08x>\n", apps, modm);
+		if (modm & SMSM_RESET) {
+			handle_modem_crash();
+		} else {
+			apps |= SMSM_INIT;
+			if (modm & SMSM_SMDINIT)
+				apps |= SMSM_SMDINIT;
+			if (modm & SMSM_RPCINIT)
+				apps |= SMSM_RPCINIT;
+		}
+
+		if (smsm[0].state != apps) {
+			if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+				pr_info("<SM %08x NOTIFY>\n", apps);
+			smsm[0].state = apps;
+			do_smd_probe();
+			notify_other_smsm();
+		}
+	}
+	spin_unlock_irqrestore(&smem_lock, flags);
+	return IRQ_HANDLED;
+}
+
+int smsm_change_state(uint32_t clear_mask, uint32_t set_mask)
+{
+	unsigned long flags;
+	struct smsm_shared *smsm;
+
+	spin_lock_irqsave(&smem_lock, flags);
+
+	smsm = smem_alloc(ID_SHARED_STATE,
+			  2 * sizeof(struct smsm_shared));
+
+	if (smsm) {
+		if (smsm[1].state & SMSM_RESET)
+			handle_modem_crash();
+		smsm[0].state = (smsm[0].state & ~clear_mask) | set_mask;
+		if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+			pr_info("smsm_change_state %x\n",
+			       smsm[0].state);
+		notify_other_smsm();
+	}
+
+	spin_unlock_irqrestore(&smem_lock, flags);
+
+	if (smsm == NULL) {
+		pr_err("smsm_change_state <SM NO STATE>\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+uint32_t smsm_get_state(void)
+{
+	unsigned long flags;
+	struct smsm_shared *smsm;
+	uint32_t rv;
+
+	spin_lock_irqsave(&smem_lock, flags);
+
+	smsm = smem_alloc(ID_SHARED_STATE,
+			  2 * sizeof(struct smsm_shared));
+
+	if (smsm)
+		rv = smsm[1].state;
+	else
+		rv = 0;
+
+	if (rv & SMSM_RESET)
+		handle_modem_crash();
+
+	spin_unlock_irqrestore(&smem_lock, flags);
+
+	if (smsm == NULL)
+		pr_err("smsm_get_state <SM NO STATE>\n");
+	return rv;
+}
+
+int smsm_set_sleep_duration(uint32_t delay)
+{
+	uint32_t *ptr;
+
+	ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+	if (ptr == NULL) {
+		pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
+		return -EIO;
+	}
+	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+		pr_info("smsm_set_sleep_duration %d -> %d\n",
+		       *ptr, delay);
+	*ptr = delay;
+	return 0;
+}
+
+int smsm_set_interrupt_info(struct smsm_interrupt_info *info)
+{
+	struct smsm_interrupt_info *ptr;
+
+	ptr = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*ptr));
+	if (ptr == NULL) {
+		pr_err("smsm_set_sleep_duration <SM NO INT_INFO>\n");
+		return -EIO;
+	}
+	if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+		pr_info("smsm_set_interrupt_info %x %x -> %x %x\n",
+		       ptr->aArm_en_mask, ptr->aArm_interrupts_pending,
+		       info->aArm_en_mask, info->aArm_interrupts_pending);
+	*ptr = *info;
+	return 0;
+}
+
+#define MAX_NUM_SLEEP_CLIENTS		64
+#define MAX_SLEEP_NAME_LEN		8
+
+#define NUM_GPIO_INT_REGISTERS		6
+#define GPIO_SMEM_NUM_GROUPS		2
+#define GPIO_SMEM_MAX_PC_INTERRUPTS	8
+
+struct tramp_gpio_save {
+	unsigned int enable;
+	unsigned int detect;
+	unsigned int polarity;
+};
+
+struct tramp_gpio_smem {
+	uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
+	uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
+	uint32_t enabled[NUM_GPIO_INT_REGISTERS];
+	uint32_t detection[NUM_GPIO_INT_REGISTERS];
+	uint32_t polarity[NUM_GPIO_INT_REGISTERS];
+};
+
+
+void smsm_print_sleep_info(void)
+{
+	unsigned long flags;
+	uint32_t *ptr;
+	struct tramp_gpio_smem *gpio;
+	struct smsm_interrupt_info *int_info;
+
+
+	spin_lock_irqsave(&smem_lock, flags);
+
+	ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+	if (ptr)
+		pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr);
+
+	ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr));
+	if (ptr)
+		pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr);
+
+	ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
+	if (ptr)
+		pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
+
+	int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info));
+	if (int_info)
+		pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
+			int_info->aArm_en_mask,
+			int_info->aArm_interrupts_pending,
+			int_info->aArm_wakeup_reason);
+
+	gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
+	if (gpio) {
+		int i;
+		for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
+			pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
+				i, gpio->enabled[i], gpio->detection[i],
+				gpio->polarity[i]);
+
+		for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
+			pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
+				i, gpio->num_fired[i], gpio->fired[i][0],
+				gpio->fired[i][1]);
+	}
+
+	spin_unlock_irqrestore(&smem_lock, flags);
+}
+
+int smd_core_init(void)
+{
+	int r;
+	pr_info("smd_core_init()\n");
+
+	r = request_irq(INT_A9_M2A_0, smd_irq_handler,
+			IRQF_TRIGGER_RISING, "smd_dev", 0);
+	if (r < 0)
+		return r;
+	r = enable_irq_wake(INT_A9_M2A_0);
+	if (r < 0)
+		pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
+
+	r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
+			IRQF_TRIGGER_RISING, "smsm_dev", 0);
+	if (r < 0) {
+		free_irq(INT_A9_M2A_0, 0);
+		return r;
+	}
+	r = enable_irq_wake(INT_A9_M2A_5);
+	if (r < 0)
+		pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
+
+	/* we may have missed a signal while booting -- fake
+	 * an interrupt to make sure we process any existing
+	 * state
+	 */
+	smsm_irq_handler(0, 0);
+
+	pr_info("smd_core_init() done\n");
+
+	return 0;
+}
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int dump_ch(char *buf, int max, int n,
+		  struct smd_half_channel *s,
+		  struct smd_half_channel *r)
+{
+	return scnprintf(
+		buf, max,
+		"ch%02d:"
+		" %8s(%04d/%04d) %c%c%c%c%c%c%c <->"
+		" %8s(%04d/%04d) %c%c%c%c%c%c%c\n", n,
+		chstate(s->state), s->tail, s->head,
+		s->fDSR ? 'D' : 'd',
+		s->fCTS ? 'C' : 'c',
+		s->fCD ? 'C' : 'c',
+		s->fRI ? 'I' : 'i',
+		s->fHEAD ? 'W' : 'w',
+		s->fTAIL ? 'R' : 'r',
+		s->fSTATE ? 'S' : 's',
+		chstate(r->state), r->tail, r->head,
+		r->fDSR ? 'D' : 'd',
+		r->fCTS ? 'R' : 'r',
+		r->fCD ? 'C' : 'c',
+		r->fRI ? 'I' : 'i',
+		r->fHEAD ? 'W' : 'w',
+		r->fTAIL ? 'R' : 'r',
+		r->fSTATE ? 'S' : 's'
+		);
+}
+
+static int debug_read_stat(char *buf, int max)
+{
+	struct smsm_shared *smsm;
+	char *msg;
+	int i = 0;
+
+	smsm = smem_find(ID_SHARED_STATE,
+			 2 * sizeof(struct smsm_shared));
+
+	msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+
+	if (smsm) {
+		if (smsm[1].state & SMSM_RESET)
+			i += scnprintf(buf + i, max - i,
+				       "smsm: ARM9 HAS CRASHED\n");
+		i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
+			       smsm[0].state, smsm[1].state);
+	} else {
+		i += scnprintf(buf + i, max - i, "smsm: cannot find\n");
+	}
+	if (msg) {
+		msg[SZ_DIAG_ERR_MSG - 1] = 0;
+		i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
+	}
+	return i;
+}
+
+static int debug_read_mem(char *buf, int max)
+{
+	unsigned n;
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	struct smem_heap_entry *toc = shared->heap_toc;
+	int i = 0;
+
+	i += scnprintf(buf + i, max - i,
+		       "heap: init=%d free=%d remain=%d\n",
+		       shared->heap_info.initialized,
+		       shared->heap_info.free_offset,
+		       shared->heap_info.heap_remaining);
+
+	for (n = 0; n < SMEM_NUM_ITEMS; n++) {
+		if (toc[n].allocated == 0)
+			continue;
+		i += scnprintf(buf + i, max - i,
+			       "%04d: offsed %08x size %08x\n",
+			       n, toc[n].offset, toc[n].size);
+	}
+	return i;
+}
+
+static int debug_read_ch(char *buf, int max)
+{
+	struct smd_shared *shared;
+	int n, i = 0;
+
+	for (n = 0; n < SMD_CHANNELS; n++) {
+		shared = smem_find(ID_SMD_CHANNELS + n,
+				   sizeof(struct smd_shared));
+		if (shared == 0)
+			continue;
+		i += dump_ch(buf + i, max - i, n, &shared->ch0, &shared->ch1);
+	}
+
+	return i;
+}
+
+static int debug_read_version(char *buf, int max)
+{
+	struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+	unsigned version = shared->version[VERSION_MODEM];
+	return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff);
+}
+
+static int debug_read_build_id(char *buf, int max)
+{
+	unsigned size;
+	void *data;
+
+	data = _smem_find(SMEM_HW_SW_BUILD_ID, &size);
+	if (!data)
+		return 0;
+
+	if (size >= max)
+		size = max;
+	memcpy(buf, data, size);
+
+	return size;
+}
+
+static int debug_read_alloc_tbl(char *buf, int max)
+{
+	struct smd_alloc_elm *shared;
+	int n, i = 0;
+
+	shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+
+	for (n = 0; n < 64; n++) {
+		if (shared[n].ref_count == 0)
+			continue;
+		i += scnprintf(buf + i, max - i,
+			       "%03d: %20s cid=%02d ctype=%d ref_count=%d\n",
+			       n, shared[n].name, shared[n].cid,
+			       shared[n].ctype, shared[n].ref_count);
+	}
+
+	return i;
+}
+
+static int debug_boom(char *buf, int max)
+{
+	unsigned ms = 5000;
+	msm_proc_comm(PCOM_RESET_MODEM, &ms, 0);
+	return 0;
+}
+
+#define DEBUG_BUFMAX 4096
+static char debug_buffer[DEBUG_BUFMAX];
+
+static ssize_t debug_read(struct file *file, char __user *buf,
+			  size_t count, loff_t *ppos)
+{
+	int (*fill)(char *buf, int max) = file->private_data;
+	int bsize = fill(debug_buffer, DEBUG_BUFMAX);
+	return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
+}
+
+static int debug_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static const struct file_operations debug_ops = {
+	.read = debug_read,
+	.open = debug_open,
+};
+
+static void debug_create(const char *name, mode_t mode,
+			 struct dentry *dent,
+			 int (*fill)(char *buf, int max))
+{
+	debugfs_create_file(name, mode, dent, fill, &debug_ops);
+}
+
+static void smd_debugfs_init(void)
+{
+	struct dentry *dent;
+
+	dent = debugfs_create_dir("smd", 0);
+	if (IS_ERR(dent))
+		return;
+
+	debug_create("ch", 0444, dent, debug_read_ch);
+	debug_create("stat", 0444, dent, debug_read_stat);
+	debug_create("mem", 0444, dent, debug_read_mem);
+	debug_create("version", 0444, dent, debug_read_version);
+	debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
+	debug_create("build", 0444, dent, debug_read_build_id);
+	debug_create("boom", 0444, dent, debug_boom);
+}
+#else
+static void smd_debugfs_init(void) {}
+#endif
+
+static int __init msm_smd_probe(struct platform_device *pdev)
+{
+	pr_info("smd_init()\n");
+
+	INIT_WORK(&probe_work, smd_channel_probe_worker);
+
+	if (smd_core_init()) {
+		pr_err("smd_core_init() failed\n");
+		return -1;
+	}
+
+	do_smd_probe();
+
+	msm_check_for_modem_crash = check_for_modem_crash;
+
+	smd_debugfs_init();
+	smd_initialized = 1;
+
+	return 0;
+}
+
+static struct platform_driver msm_smd_driver = {
+	.probe = msm_smd_probe,
+	.driver = {
+		.name = MODULE_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_smd_init(void)
+{
+	return platform_driver_register(&msm_smd_driver);
+}
+
+module_init(msm_smd_init);
+
+MODULE_DESCRIPTION("MSM Shared Memory Core");
+MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/dream/smd/smd_private.h b/drivers/staging/dream/smd/smd_private.h
new file mode 100644
index 0000000..c0eb3de
--- /dev/null
+++ b/drivers/staging/dream/smd/smd_private.h
@@ -0,0 +1,171 @@
+/* arch/arm/mach-msm/smd_private.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
+#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
+
+struct smem_heap_info
+{
+	unsigned initialized;
+	unsigned free_offset;
+	unsigned heap_remaining;
+	unsigned reserved;
+};
+
+struct smem_heap_entry
+{
+	unsigned allocated;
+	unsigned offset;
+	unsigned size;
+	unsigned reserved;
+};
+
+struct smem_proc_comm
+{
+	unsigned command;
+	unsigned status;
+	unsigned data1;
+	unsigned data2;
+};
+
+#define PC_APPS  0
+#define PC_MODEM 1
+
+#define VERSION_QDSP6     4
+#define VERSION_APPS_SBL  6
+#define VERSION_MODEM_SBL 7
+#define VERSION_APPS      8
+#define VERSION_MODEM     9
+
+struct smem_shared
+{
+	struct smem_proc_comm proc_comm[4];
+	unsigned version[32];
+	struct smem_heap_info heap_info;
+	struct smem_heap_entry heap_toc[128];
+};
+
+struct smsm_shared
+{
+	unsigned host;
+	unsigned state;
+};
+
+struct smsm_interrupt_info
+{
+	uint32_t aArm_en_mask;
+	uint32_t aArm_interrupts_pending;
+	uint32_t aArm_wakeup_reason;
+};
+
+#define SZ_DIAG_ERR_MSG 0xC8
+#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE
+#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID
+#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE
+#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL
+
+#define SMSM_INIT          0x000001
+#define SMSM_SMDINIT       0x000008
+#define SMSM_RPCINIT       0x000020
+#define SMSM_RESET         0x000040
+#define SMSM_RSA               0x0080
+#define SMSM_RUN           0x000100
+#define SMSM_PWRC              0x0200
+#define SMSM_TIMEWAIT          0x0400
+#define SMSM_TIMEINIT          0x0800
+#define SMSM_PWRC_EARLY_EXIT   0x1000
+#define SMSM_WFPI              0x2000
+#define SMSM_SLEEP             0x4000
+#define SMSM_SLEEPEXIT         0x8000
+#define SMSM_OEMSBL_RELEASE    0x10000
+#define SMSM_PWRC_SUSPEND      0x200000
+
+#define SMSM_WKUP_REASON_RPC	0x00000001
+#define SMSM_WKUP_REASON_INT	0x00000002
+#define SMSM_WKUP_REASON_GPIO	0x00000004
+#define SMSM_WKUP_REASON_TIMER	0x00000008
+#define SMSM_WKUP_REASON_ALARM	0x00000010
+#define SMSM_WKUP_REASON_RESET	0x00000020
+
+void *smem_alloc(unsigned id, unsigned size);
+int smsm_change_state(uint32_t clear_mask, uint32_t set_mask);
+uint32_t smsm_get_state(void);
+int smsm_set_sleep_duration(uint32_t delay);
+int smsm_set_interrupt_info(struct smsm_interrupt_info *info);
+void smsm_print_sleep_info(void);
+
+#define SMEM_NUM_SMD_CHANNELS        64
+
+typedef enum
+{
+	/* fixed items */
+	SMEM_PROC_COMM = 0,
+	SMEM_HEAP_INFO,
+	SMEM_ALLOCATION_TABLE,
+	SMEM_VERSION_INFO,
+	SMEM_HW_RESET_DETECT,
+	SMEM_AARM_WARM_BOOT,
+	SMEM_DIAG_ERR_MESSAGE,
+	SMEM_SPINLOCK_ARRAY,
+	SMEM_MEMORY_BARRIER_LOCATION,
+
+	/* dynamic items */
+	SMEM_AARM_PARTITION_TABLE,
+	SMEM_AARM_BAD_BLOCK_TABLE,
+	SMEM_RESERVE_BAD_BLOCKS,
+	SMEM_WM_UUID,
+	SMEM_CHANNEL_ALLOC_TBL,
+	SMEM_SMD_BASE_ID,
+	SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+	SMEM_SMEM_LOG_EVENTS,
+	SMEM_SMEM_STATIC_LOG_IDX,
+	SMEM_SMEM_STATIC_LOG_EVENTS,
+	SMEM_SMEM_SLOW_CLOCK_SYNC,
+	SMEM_SMEM_SLOW_CLOCK_VALUE,
+	SMEM_BIO_LED_BUF,
+	SMEM_SMSM_SHARED_STATE,
+	SMEM_SMSM_INT_INFO,
+	SMEM_SMSM_SLEEP_DELAY,
+	SMEM_SMSM_LIMIT_SLEEP,
+	SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
+	SMEM_KEYPAD_KEYS_PRESSED,
+	SMEM_KEYPAD_STATE_UPDATED,
+	SMEM_KEYPAD_STATE_IDX,
+	SMEM_GPIO_INT,
+	SMEM_MDDI_LCD_IDX,
+	SMEM_MDDI_HOST_DRIVER_STATE,
+	SMEM_MDDI_LCD_DISP_STATE,
+	SMEM_LCD_CUR_PANEL,
+	SMEM_MARM_BOOT_SEGMENT_INFO,
+	SMEM_AARM_BOOT_SEGMENT_INFO,
+	SMEM_SLEEP_STATIC,
+	SMEM_SCORPION_FREQUENCY,
+	SMEM_SMD_PROFILES,
+	SMEM_TSSC_BUSY,
+	SMEM_HS_SUSPEND_FILTER_INFO,
+	SMEM_BATT_INFO,
+	SMEM_APPS_BOOT_MODE,
+	SMEM_VERSION_FIRST,
+	SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
+	SMEM_OSS_RRCASN1_BUF1,
+	SMEM_OSS_RRCASN1_BUF2,
+	SMEM_ID_VENDOR0,
+	SMEM_ID_VENDOR1,
+	SMEM_ID_VENDOR2,
+	SMEM_HW_SW_BUILD_ID,
+	SMEM_NUM_ITEMS,
+} smem_mem_type;
+
+#endif
diff --git a/drivers/staging/dream/smd/smd_qmi.c b/drivers/staging/dream/smd/smd_qmi.c
new file mode 100644
index 0000000..d4e7d88
--- /dev/null
+++ b/drivers/staging/dream/smd/smd_qmi.c
@@ -0,0 +1,860 @@
+/* arch/arm/mach-msm/smd_qmi.c
+ *
+ * QMI Control Driver -- Manages network data connections.
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/miscdevice.h>
+#include <linux/workqueue.h>
+#include <linux/wakelock.h>
+
+#include <asm/uaccess.h>
+#include <mach/msm_smd.h>
+
+#define QMI_CTL 0x00
+#define QMI_WDS 0x01
+#define QMI_DMS 0x02
+#define QMI_NAS 0x03
+
+#define QMI_RESULT_SUCCESS 0x0000
+#define QMI_RESULT_FAILURE 0x0001
+
+struct qmi_msg {
+	unsigned char service;
+	unsigned char client_id;
+	unsigned short txn_id;
+	unsigned short type;
+	unsigned short size;
+	unsigned char *tlv;
+};
+
+#define qmi_ctl_client_id 0
+
+#define STATE_OFFLINE    0
+#define STATE_QUERYING   1
+#define STATE_ONLINE     2
+
+struct qmi_ctxt {
+	struct miscdevice misc;
+
+	struct mutex lock;
+
+	unsigned char ctl_txn_id;
+	unsigned char wds_client_id;
+	unsigned short wds_txn_id;
+
+	unsigned wds_busy;
+	unsigned wds_handle;
+	unsigned state_dirty;
+	unsigned state;
+
+	unsigned char addr[4];
+	unsigned char mask[4];
+	unsigned char gateway[4];
+	unsigned char dns1[4];
+	unsigned char dns2[4];
+
+	smd_channel_t *ch;
+	const char *ch_name;
+	struct wake_lock wake_lock;
+
+	struct work_struct open_work;
+	struct work_struct read_work;
+};
+
+static struct qmi_ctxt *qmi_minor_to_ctxt(unsigned n);
+
+static void qmi_read_work(struct work_struct *ws);
+static void qmi_open_work(struct work_struct *work);
+
+void qmi_ctxt_init(struct qmi_ctxt *ctxt, unsigned n)
+{
+	mutex_init(&ctxt->lock);
+	INIT_WORK(&ctxt->read_work, qmi_read_work);
+	INIT_WORK(&ctxt->open_work, qmi_open_work);
+	wake_lock_init(&ctxt->wake_lock, WAKE_LOCK_SUSPEND, ctxt->misc.name);
+	ctxt->ctl_txn_id = 1;
+	ctxt->wds_txn_id = 1;
+	ctxt->wds_busy = 1;
+	ctxt->state = STATE_OFFLINE;
+
+}
+
+static struct workqueue_struct *qmi_wq;
+
+static int verbose = 0;
+
+/* anyone waiting for a state change waits here */
+static DECLARE_WAIT_QUEUE_HEAD(qmi_wait_queue);
+
+
+static void qmi_dump_msg(struct qmi_msg *msg, const char *prefix)
+{
+	unsigned sz, n;
+	unsigned char *x;
+
+	if (!verbose)
+		return;
+
+	printk(KERN_INFO
+	       "qmi: %s: svc=%02x cid=%02x tid=%04x type=%04x size=%04x\n",
+	       prefix, msg->service, msg->client_id,
+	       msg->txn_id, msg->type, msg->size);
+
+	x = msg->tlv;
+	sz = msg->size;
+
+	while (sz >= 3) {
+		sz -= 3;
+
+		n = x[1] | (x[2] << 8);
+		if (n > sz)
+			break;
+
+		printk(KERN_INFO "qmi: %s: tlv: %02x %04x { ",
+		       prefix, x[0], n);
+		x += 3;
+		sz -= n;
+		while (n-- > 0)
+			printk("%02x ", *x++);
+		printk("}\n");
+	}
+}
+
+int qmi_add_tlv(struct qmi_msg *msg,
+		unsigned type, unsigned size, const void *data)
+{
+	unsigned char *x = msg->tlv + msg->size;
+
+	x[0] = type;
+	x[1] = size;
+	x[2] = size >> 8;
+
+	memcpy(x + 3, data, size);
+
+	msg->size += (size + 3);
+
+	return 0;
+}
+
+/* Extract a tagged item from a qmi message buffer,
+** taking care not to overrun the buffer.
+*/
+static int qmi_get_tlv(struct qmi_msg *msg,
+		       unsigned type, unsigned size, void *data)
+{
+	unsigned char *x = msg->tlv;
+	unsigned len = msg->size;
+	unsigned n;
+
+	while (len >= 3) {
+		len -= 3;
+
+		/* size of this item */
+		n = x[1] | (x[2] << 8);
+		if (n > len)
+			break;
+
+		if (x[0] == type) {
+			if (n != size)
+				return -1;
+			memcpy(data, x + 3, size);
+			return 0;
+		}
+
+		x += (n + 3);
+		len -= n;
+	}
+
+	return -1;
+}
+
+static unsigned qmi_get_status(struct qmi_msg *msg, unsigned *error)
+{
+	unsigned short status[2];
+	if (qmi_get_tlv(msg, 0x02, sizeof(status), status)) {
+		*error = 0;
+		return QMI_RESULT_FAILURE;
+	} else {
+		*error = status[1];
+		return status[0];
+	}
+}
+
+/* 0x01 <qmux-header> <payload> */
+#define QMUX_HEADER    13
+
+/* should be >= HEADER + FOOTER */
+#define QMUX_OVERHEAD  16
+
+static int qmi_send(struct qmi_ctxt *ctxt, struct qmi_msg *msg)
+{
+	unsigned char *data;
+	unsigned hlen;
+	unsigned len;
+	int r;
+
+	qmi_dump_msg(msg, "send");
+
+	if (msg->service == QMI_CTL) {
+		hlen = QMUX_HEADER - 1;
+	} else {
+		hlen = QMUX_HEADER;
+	}
+
+	/* QMUX length is total header + total payload - IFC selector */
+	len = hlen + msg->size - 1;
+	if (len > 0xffff)
+		return -1;
+
+	data = msg->tlv - hlen;
+
+	/* prepend encap and qmux header */
+	*data++ = 0x01; /* ifc selector */
+
+	/* qmux header */
+	*data++ = len;
+	*data++ = len >> 8;
+	*data++ = 0x00; /* flags: client */
+	*data++ = msg->service;
+	*data++ = msg->client_id;
+
+	/* qmi header */
+	*data++ = 0x00; /* flags: send */
+	*data++ = msg->txn_id;
+	if (msg->service != QMI_CTL)
+		*data++ = msg->txn_id >> 8;
+
+	*data++ = msg->type;
+	*data++ = msg->type >> 8;
+	*data++ = msg->size;
+	*data++ = msg->size >> 8;
+
+	/* len + 1 takes the interface selector into account */
+	r = smd_write(ctxt->ch, msg->tlv - hlen, len + 1);
+
+	if (r != len) {
+		return -1;
+	} else {
+		return 0;
+	}
+}
+
+static void qmi_process_ctl_msg(struct qmi_ctxt *ctxt, struct qmi_msg *msg)
+{
+	unsigned err;
+	if (msg->type == 0x0022) {
+		unsigned char n[2];
+		if (qmi_get_status(msg, &err))
+			return;
+		if (qmi_get_tlv(msg, 0x01, sizeof(n), n))
+			return;
+		if (n[0] == QMI_WDS) {
+			printk(KERN_INFO
+			       "qmi: ctl: wds use client_id 0x%02x\n", n[1]);
+			ctxt->wds_client_id = n[1];
+			ctxt->wds_busy = 0;
+		}
+	}
+}
+
+static int qmi_network_get_profile(struct qmi_ctxt *ctxt);
+
+static void swapaddr(unsigned char *src, unsigned char *dst)
+{
+	dst[0] = src[3];
+	dst[1] = src[2];
+	dst[2] = src[1];
+	dst[3] = src[0];
+}
+
+static unsigned char zero[4];
+static void qmi_read_runtime_profile(struct qmi_ctxt *ctxt, struct qmi_msg *msg)
+{
+	unsigned char tmp[4];
+	unsigned r;
+
+	r = qmi_get_tlv(msg, 0x1e, 4, tmp);
+	swapaddr(r ? zero : tmp, ctxt->addr);
+	r = qmi_get_tlv(msg, 0x21, 4, tmp);
+	swapaddr(r ? zero : tmp, ctxt->mask);
+	r = qmi_get_tlv(msg, 0x20, 4, tmp);
+	swapaddr(r ? zero : tmp, ctxt->gateway);
+	r = qmi_get_tlv(msg, 0x15, 4, tmp);
+	swapaddr(r ? zero : tmp, ctxt->dns1);
+	r = qmi_get_tlv(msg, 0x16, 4, tmp);
+	swapaddr(r ? zero : tmp, ctxt->dns2);
+}
+
+static void qmi_process_unicast_wds_msg(struct qmi_ctxt *ctxt,
+					struct qmi_msg *msg)
+{
+	unsigned err;
+	switch (msg->type) {
+	case 0x0021:
+		if (qmi_get_status(msg, &err)) {
+			printk(KERN_ERR
+			       "qmi: wds: network stop failed (%04x)\n", err);
+		} else {
+			printk(KERN_INFO
+			       "qmi: wds: network stopped\n");
+			ctxt->state = STATE_OFFLINE;
+			ctxt->state_dirty = 1;
+		}
+		break;
+	case 0x0020:
+		if (qmi_get_status(msg, &err)) {
+			printk(KERN_ERR
+			       "qmi: wds: network start failed (%04x)\n", err);
+		} else if (qmi_get_tlv(msg, 0x01, sizeof(ctxt->wds_handle), &ctxt->wds_handle)) {
+			printk(KERN_INFO
+			       "qmi: wds no handle?\n");
+		} else {
+			printk(KERN_INFO
+			       "qmi: wds: got handle 0x%08x\n",
+			       ctxt->wds_handle);
+		}
+		break;
+	case 0x002D:
+		printk("qmi: got network profile\n");
+		if (ctxt->state == STATE_QUERYING) {
+			qmi_read_runtime_profile(ctxt, msg);
+			ctxt->state = STATE_ONLINE;
+			ctxt->state_dirty = 1;
+		}
+		break;
+	default:
+		printk(KERN_ERR "qmi: unknown msg type 0x%04x\n", msg->type);
+	}
+	ctxt->wds_busy = 0;
+}
+
+static void qmi_process_broadcast_wds_msg(struct qmi_ctxt *ctxt,
+					  struct qmi_msg *msg)
+{
+	if (msg->type == 0x0022) {
+		unsigned char n[2];
+		if (qmi_get_tlv(msg, 0x01, sizeof(n), n))
+			return;
+		switch (n[0]) {
+		case 1:
+			printk(KERN_INFO "qmi: wds: DISCONNECTED\n");
+			ctxt->state = STATE_OFFLINE;
+			ctxt->state_dirty = 1;
+			break;
+		case 2:
+			printk(KERN_INFO "qmi: wds: CONNECTED\n");
+			ctxt->state = STATE_QUERYING;
+			ctxt->state_dirty = 1;
+			qmi_network_get_profile(ctxt);
+			break;
+		case 3:
+			printk(KERN_INFO "qmi: wds: SUSPENDED\n");
+			ctxt->state = STATE_OFFLINE;
+			ctxt->state_dirty = 1;
+		}
+	} else {
+		printk(KERN_ERR "qmi: unknown bcast msg type 0x%04x\n", msg->type);
+	}
+}
+
+static void qmi_process_wds_msg(struct qmi_ctxt *ctxt,
+				struct qmi_msg *msg)
+{
+	printk("wds: %04x @ %02x\n", msg->type, msg->client_id);
+	if (msg->client_id == ctxt->wds_client_id) {
+		qmi_process_unicast_wds_msg(ctxt, msg);
+	} else if (msg->client_id == 0xff) {
+		qmi_process_broadcast_wds_msg(ctxt, msg);
+	} else {
+		printk(KERN_ERR
+		       "qmi_process_wds_msg client id 0x%02x unknown\n",
+		       msg->client_id);
+	}
+}
+
+static void qmi_process_qmux(struct qmi_ctxt *ctxt,
+			     unsigned char *buf, unsigned sz)
+{
+	struct qmi_msg msg;
+
+	/* require a full header */
+	if (sz < 5)
+		return;
+
+	/* require a size that matches the buffer size */
+	if (sz != (buf[0] | (buf[1] << 8)))
+		return;
+
+	/* only messages from a service (bit7=1) are allowed */
+	if (buf[2] != 0x80)
+		return;
+
+	msg.service = buf[3];
+	msg.client_id = buf[4];
+
+	/* annoyingly, CTL messages have a shorter TID */
+	if (buf[3] == 0) {
+		if (sz < 7)
+			return;
+		msg.txn_id = buf[6];
+		buf += 7;
+		sz -= 7;
+	} else {
+		if (sz < 8)
+			return;
+		msg.txn_id = buf[6] | (buf[7] << 8);
+		buf += 8;
+		sz -= 8;
+	}
+
+	/* no type and size!? */
+	if (sz < 4)
+		return;
+	sz -= 4;
+
+	msg.type = buf[0] | (buf[1] << 8);
+	msg.size = buf[2] | (buf[3] << 8);
+	msg.tlv = buf + 4;
+
+	if (sz != msg.size)
+		return;
+
+	qmi_dump_msg(&msg, "recv");
+
+	mutex_lock(&ctxt->lock);
+	switch (msg.service) {
+	case QMI_CTL:
+		qmi_process_ctl_msg(ctxt, &msg);
+		break;
+	case QMI_WDS:
+		qmi_process_wds_msg(ctxt, &msg);
+		break;
+	default:
+		printk(KERN_ERR "qmi: msg from unknown svc 0x%02x\n",
+		       msg.service);
+		break;
+	}
+	mutex_unlock(&ctxt->lock);
+
+	wake_up(&qmi_wait_queue);
+}
+
+#define QMI_MAX_PACKET (256 + QMUX_OVERHEAD)
+
+static void qmi_read_work(struct work_struct *ws)
+{
+	struct qmi_ctxt *ctxt = container_of(ws, struct qmi_ctxt, read_work);
+	struct smd_channel *ch = ctxt->ch;
+	unsigned char buf[QMI_MAX_PACKET];
+	int sz;
+
+	for (;;) {
+		sz = smd_cur_packet_size(ch);
+		if (sz == 0)
+			break;
+		if (sz < smd_read_avail(ch))
+			break;
+		if (sz > QMI_MAX_PACKET) {
+			smd_read(ch, 0, sz);
+			continue;
+		}
+		if (smd_read(ch, buf, sz) != sz) {
+			printk(KERN_ERR "qmi: not enough data?!\n");
+			continue;
+		}
+
+		/* interface selector must be 1 */
+		if (buf[0] != 0x01)
+			continue;
+
+		qmi_process_qmux(ctxt, buf + 1, sz - 1);
+	}
+}
+
+static int qmi_request_wds_cid(struct qmi_ctxt *ctxt);
+
+static void qmi_open_work(struct work_struct *ws)
+{
+	struct qmi_ctxt *ctxt = container_of(ws, struct qmi_ctxt, open_work);
+	mutex_lock(&ctxt->lock);
+	qmi_request_wds_cid(ctxt);
+	mutex_unlock(&ctxt->lock);
+}
+
+static void qmi_notify(void *priv, unsigned event)
+{
+	struct qmi_ctxt *ctxt = priv;
+
+	switch (event) {
+	case SMD_EVENT_DATA: {
+		int sz;
+		sz = smd_cur_packet_size(ctxt->ch);
+		if ((sz > 0) && (sz <= smd_read_avail(ctxt->ch))) {
+			wake_lock_timeout(&ctxt->wake_lock, HZ / 2);
+			queue_work(qmi_wq, &ctxt->read_work);
+		}
+		break;
+	}
+	case SMD_EVENT_OPEN:
+		printk(KERN_INFO "qmi: smd opened\n");
+		queue_work(qmi_wq, &ctxt->open_work);
+		break;
+	case SMD_EVENT_CLOSE:
+		printk(KERN_INFO "qmi: smd closed\n");
+		break;
+	}
+}
+
+static int qmi_request_wds_cid(struct qmi_ctxt *ctxt)
+{
+	unsigned char data[64 + QMUX_OVERHEAD];
+	struct qmi_msg msg;
+	unsigned char n;
+
+	msg.service = QMI_CTL;
+	msg.client_id = qmi_ctl_client_id;
+	msg.txn_id = ctxt->ctl_txn_id;
+	msg.type = 0x0022;
+	msg.size = 0;
+	msg.tlv = data + QMUX_HEADER;
+
+	ctxt->ctl_txn_id += 2;
+
+	n = QMI_WDS;
+	qmi_add_tlv(&msg, 0x01, 0x01, &n);
+
+	return qmi_send(ctxt, &msg);
+}
+
+static int qmi_network_get_profile(struct qmi_ctxt *ctxt)
+{
+	unsigned char data[96 + QMUX_OVERHEAD];
+	struct qmi_msg msg;
+
+	msg.service = QMI_WDS;
+	msg.client_id = ctxt->wds_client_id;
+	msg.txn_id = ctxt->wds_txn_id;
+	msg.type = 0x002D;
+	msg.size = 0;
+	msg.tlv = data + QMUX_HEADER;
+
+	ctxt->wds_txn_id += 2;
+
+	return qmi_send(ctxt, &msg);
+}
+
+static int qmi_network_up(struct qmi_ctxt *ctxt, char *apn)
+{
+	unsigned char data[96 + QMUX_OVERHEAD];
+	struct qmi_msg msg;
+	char *auth_type;
+	char *user;
+	char *pass;
+
+	for (user = apn; *user; user++) {
+		if (*user == ' ') {
+			*user++ = 0;
+			break;
+		}
+	}
+	for (pass = user; *pass; pass++) {
+		if (*pass == ' ') {
+			*pass++ = 0;
+			break;
+		}
+	}
+
+	for (auth_type = pass; *auth_type; auth_type++) {
+		if (*auth_type == ' ') {
+			*auth_type++ = 0;
+			break;
+		}
+	}
+
+	msg.service = QMI_WDS;
+	msg.client_id = ctxt->wds_client_id;
+	msg.txn_id = ctxt->wds_txn_id;
+	msg.type = 0x0020;
+	msg.size = 0;
+	msg.tlv = data + QMUX_HEADER;
+
+	ctxt->wds_txn_id += 2;
+
+	qmi_add_tlv(&msg, 0x14, strlen(apn), apn);
+	if (*auth_type)
+		qmi_add_tlv(&msg, 0x16, strlen(auth_type), auth_type);
+	if (*user) {
+		if (!*auth_type) {
+			unsigned char x;
+			x = 3;
+			qmi_add_tlv(&msg, 0x16, 1, &x);
+		}
+		qmi_add_tlv(&msg, 0x17, strlen(user), user);
+		if (*pass)
+			qmi_add_tlv(&msg, 0x18, strlen(pass), pass);
+	}
+	return qmi_send(ctxt, &msg);
+}
+
+static int qmi_network_down(struct qmi_ctxt *ctxt)
+{
+	unsigned char data[16 + QMUX_OVERHEAD];
+	struct qmi_msg msg;
+
+	msg.service = QMI_WDS;
+	msg.client_id = ctxt->wds_client_id;
+	msg.txn_id = ctxt->wds_txn_id;
+	msg.type = 0x0021;
+	msg.size = 0;
+	msg.tlv = data + QMUX_HEADER;
+
+	ctxt->wds_txn_id += 2;
+
+	qmi_add_tlv(&msg, 0x01, sizeof(ctxt->wds_handle), &ctxt->wds_handle);
+
+	return qmi_send(ctxt, &msg);
+}
+
+static int qmi_print_state(struct qmi_ctxt *ctxt, char *buf, int max)
+{
+	int i;
+	char *statename;
+
+	if (ctxt->state == STATE_ONLINE) {
+		statename = "up";
+	} else if (ctxt->state == STATE_OFFLINE) {
+		statename = "down";
+	} else {
+		statename = "busy";
+	}
+
+	i = scnprintf(buf, max, "STATE=%s\n", statename);
+	i += scnprintf(buf + i, max - i, "CID=%d\n",ctxt->wds_client_id);
+
+	if (ctxt->state != STATE_ONLINE){
+		return i;
+	}
+
+	i += scnprintf(buf + i, max - i, "ADDR=%d.%d.%d.%d\n",
+		ctxt->addr[0], ctxt->addr[1], ctxt->addr[2], ctxt->addr[3]);
+	i += scnprintf(buf + i, max - i, "MASK=%d.%d.%d.%d\n",
+		ctxt->mask[0], ctxt->mask[1], ctxt->mask[2], ctxt->mask[3]);
+	i += scnprintf(buf + i, max - i, "GATEWAY=%d.%d.%d.%d\n",
+		ctxt->gateway[0], ctxt->gateway[1], ctxt->gateway[2],
+		ctxt->gateway[3]);
+	i += scnprintf(buf + i, max - i, "DNS1=%d.%d.%d.%d\n",
+		ctxt->dns1[0], ctxt->dns1[1], ctxt->dns1[2], ctxt->dns1[3]);
+	i += scnprintf(buf + i, max - i, "DNS2=%d.%d.%d.%d\n",
+		ctxt->dns2[0], ctxt->dns2[1], ctxt->dns2[2], ctxt->dns2[3]);
+
+	return i;
+}
+
+static ssize_t qmi_read(struct file *fp, char __user *buf,
+			size_t count, loff_t *pos)
+{
+	struct qmi_ctxt *ctxt = fp->private_data;
+	char msg[256];
+	int len;
+	int r;
+
+	mutex_lock(&ctxt->lock);
+	for (;;) {
+		if (ctxt->state_dirty) {
+			ctxt->state_dirty = 0;
+			len = qmi_print_state(ctxt, msg, 256);
+			break;
+		}
+		mutex_unlock(&ctxt->lock);
+		r = wait_event_interruptible(qmi_wait_queue, ctxt->state_dirty);
+		if (r < 0)
+			return r;
+		mutex_lock(&ctxt->lock);
+	}
+	mutex_unlock(&ctxt->lock);
+
+	if (len > count)
+		len = count;
+
+	if (copy_to_user(buf, msg, len))
+		return -EFAULT;
+
+	return len;
+}
+
+
+static ssize_t qmi_write(struct file *fp, const char __user *buf,
+			 size_t count, loff_t *pos)
+{
+	struct qmi_ctxt *ctxt = fp->private_data;
+	unsigned char cmd[64];
+	int len;
+	int r;
+
+	if (count < 1)
+		return 0;
+
+	len = count > 63 ? 63 : count;
+
+	if (copy_from_user(cmd, buf, len))
+		return -EFAULT;
+
+	cmd[len] = 0;
+
+	/* lazy */
+	if (cmd[len-1] == '\n') {
+		cmd[len-1] = 0;
+		len--;
+	}
+
+	if (!strncmp(cmd, "verbose", 7)) {
+		verbose = 1;
+	} else if (!strncmp(cmd, "terse", 5)) {
+		verbose = 0;
+	} else if (!strncmp(cmd, "poll", 4)) {
+		ctxt->state_dirty = 1;
+		wake_up(&qmi_wait_queue);
+	} else if (!strncmp(cmd, "down", 4)) {
+retry_down:
+		mutex_lock(&ctxt->lock);
+		if (ctxt->wds_busy) {
+			mutex_unlock(&ctxt->lock);
+			r = wait_event_interruptible(qmi_wait_queue, !ctxt->wds_busy);
+			if (r < 0)
+				return r;
+			goto retry_down;
+		}
+		ctxt->wds_busy = 1;
+		qmi_network_down(ctxt);
+		mutex_unlock(&ctxt->lock);
+	} else if (!strncmp(cmd, "up:", 3)) {
+retry_up:
+		mutex_lock(&ctxt->lock);
+		if (ctxt->wds_busy) {
+			mutex_unlock(&ctxt->lock);
+			r = wait_event_interruptible(qmi_wait_queue, !ctxt->wds_busy);
+			if (r < 0)
+				return r;
+			goto retry_up;
+		}
+		ctxt->wds_busy = 1;
+		qmi_network_up(ctxt, cmd+3);
+		mutex_unlock(&ctxt->lock);
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static int qmi_open(struct inode *ip, struct file *fp)
+{
+	struct qmi_ctxt *ctxt = qmi_minor_to_ctxt(MINOR(ip->i_rdev));
+	int r = 0;
+
+	if (!ctxt) {
+		printk(KERN_ERR "unknown qmi misc %d\n", MINOR(ip->i_rdev));
+		return -ENODEV;
+	}
+
+	fp->private_data = ctxt;
+
+	mutex_lock(&ctxt->lock);
+	if (ctxt->ch == 0)
+		r = smd_open(ctxt->ch_name, &ctxt->ch, ctxt, qmi_notify);
+	if (r == 0)
+		wake_up(&qmi_wait_queue);
+	mutex_unlock(&ctxt->lock);
+
+	return r;
+}
+
+static int qmi_release(struct inode *ip, struct file *fp)
+{
+	return 0;
+}
+
+static struct file_operations qmi_fops = {
+	.owner = THIS_MODULE,
+	.read = qmi_read,
+	.write = qmi_write,
+	.open = qmi_open,
+	.release = qmi_release,
+};
+
+static struct qmi_ctxt qmi_device0 = {
+	.ch_name = "SMD_DATA5_CNTL",
+	.misc = {
+		.minor = MISC_DYNAMIC_MINOR,
+		.name = "qmi0",
+		.fops = &qmi_fops,
+	}
+};
+static struct qmi_ctxt qmi_device1 = {
+	.ch_name = "SMD_DATA6_CNTL",
+	.misc = {
+		.minor = MISC_DYNAMIC_MINOR,
+		.name = "qmi1",
+		.fops = &qmi_fops,
+	}
+};
+static struct qmi_ctxt qmi_device2 = {
+	.ch_name = "SMD_DATA7_CNTL",
+	.misc = {
+		.minor = MISC_DYNAMIC_MINOR,
+		.name = "qmi2",
+		.fops = &qmi_fops,
+	}
+};
+
+static struct qmi_ctxt *qmi_minor_to_ctxt(unsigned n)
+{
+	if (n == qmi_device0.misc.minor)
+		return &qmi_device0;
+	if (n == qmi_device1.misc.minor)
+		return &qmi_device1;
+	if (n == qmi_device2.misc.minor)
+		return &qmi_device2;
+	return 0;
+}
+
+static int __init qmi_init(void)
+{
+	int ret;
+
+	qmi_wq = create_singlethread_workqueue("qmi");
+	if (qmi_wq == 0)
+		return -ENOMEM;
+
+	qmi_ctxt_init(&qmi_device0, 0);
+	qmi_ctxt_init(&qmi_device1, 1);
+	qmi_ctxt_init(&qmi_device2, 2);
+
+	ret = misc_register(&qmi_device0.misc);
+	if (ret == 0)
+		ret = misc_register(&qmi_device1.misc);
+	if (ret == 0)
+		ret = misc_register(&qmi_device2.misc);
+	return ret;
+}
+
+module_init(qmi_init);
diff --git a/drivers/staging/dream/smd/smd_rpcrouter.c b/drivers/staging/dream/smd/smd_rpcrouter.c
new file mode 100644
index 0000000..d4a4a88
--- /dev/null
+++ b/drivers/staging/dream/smd/smd_rpcrouter.c
@@ -0,0 +1,1274 @@
+/* arch/arm/mach-msm/smd_rpcrouter.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2009 QUALCOMM Incorporated.
+ * Author: San Mehat <san@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/* TODO: handle cases where smd_write() will tempfail due to full fifo */
+/* TODO: thread priority? schedule a work to bump it? */
+/* TODO: maybe make server_list_lock a mutex */
+/* TODO: pool fragments to avoid kmalloc/kfree churn */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/cdev.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/wakelock.h>
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+
+#include <asm/byteorder.h>
+
+#include <mach/msm_smd.h>
+#include "smd_rpcrouter.h"
+
+#define TRACE_R2R_MSG 0
+#define TRACE_R2R_RAW 0
+#define TRACE_RPC_MSG 0
+#define TRACE_NOTIFY_MSG 0
+
+#define MSM_RPCROUTER_DEBUG 0
+#define MSM_RPCROUTER_DEBUG_PKT 0
+#define MSM_RPCROUTER_R2R_DEBUG 0
+#define DUMP_ALL_RECEIVED_HEADERS 0
+
+#define DIAG(x...) printk("[RR] ERROR " x)
+
+#if MSM_RPCROUTER_DEBUG
+#define D(x...) printk(x)
+#else
+#define D(x...) do {} while (0)
+#endif
+
+#if TRACE_R2R_MSG
+#define RR(x...) printk("[RR] "x)
+#else
+#define RR(x...) do {} while (0)
+#endif
+
+#if TRACE_RPC_MSG
+#define IO(x...) printk("[RPC] "x)
+#else
+#define IO(x...) do {} while (0)
+#endif
+
+#if TRACE_NOTIFY_MSG
+#define NTFY(x...) printk(KERN_ERR "[NOTIFY] "x)
+#else
+#define NTFY(x...) do {} while (0)
+#endif
+
+static LIST_HEAD(local_endpoints);
+static LIST_HEAD(remote_endpoints);
+
+static LIST_HEAD(server_list);
+
+static smd_channel_t *smd_channel;
+static int initialized;
+static wait_queue_head_t newserver_wait;
+static wait_queue_head_t smd_wait;
+
+static DEFINE_SPINLOCK(local_endpoints_lock);
+static DEFINE_SPINLOCK(remote_endpoints_lock);
+static DEFINE_SPINLOCK(server_list_lock);
+static DEFINE_SPINLOCK(smd_lock);
+
+static struct workqueue_struct *rpcrouter_workqueue;
+static struct wake_lock rpcrouter_wake_lock;
+static int rpcrouter_need_len;
+
+static atomic_t next_xid = ATOMIC_INIT(1);
+static uint8_t next_pacmarkid;
+
+static void do_read_data(struct work_struct *work);
+static void do_create_pdevs(struct work_struct *work);
+static void do_create_rpcrouter_pdev(struct work_struct *work);
+
+static DECLARE_WORK(work_read_data, do_read_data);
+static DECLARE_WORK(work_create_pdevs, do_create_pdevs);
+static DECLARE_WORK(work_create_rpcrouter_pdev, do_create_rpcrouter_pdev);
+
+#define RR_STATE_IDLE    0
+#define RR_STATE_HEADER  1
+#define RR_STATE_BODY    2
+#define RR_STATE_ERROR   3
+
+struct rr_context {
+	struct rr_packet *pkt;
+	uint8_t *ptr;
+	uint32_t state; /* current assembly state */
+	uint32_t count; /* bytes needed in this state */
+};
+
+static struct rr_context the_rr_context;
+
+static struct platform_device rpcrouter_pdev = {
+	.name		= "oncrpc_router",
+	.id		= -1,
+};
+
+
+static int rpcrouter_send_control_msg(union rr_control_msg *msg)
+{
+	struct rr_header hdr;
+	unsigned long flags;
+	int need;
+
+	if (!(msg->cmd == RPCROUTER_CTRL_CMD_HELLO) && !initialized) {
+		printk(KERN_ERR "rpcrouter_send_control_msg(): Warning, "
+		       "router not initialized\n");
+		return -EINVAL;
+	}
+
+	hdr.version = RPCROUTER_VERSION;
+	hdr.type = msg->cmd;
+	hdr.src_pid = RPCROUTER_PID_LOCAL;
+	hdr.src_cid = RPCROUTER_ROUTER_ADDRESS;
+	hdr.confirm_rx = 0;
+	hdr.size = sizeof(*msg);
+	hdr.dst_pid = 0;
+	hdr.dst_cid = RPCROUTER_ROUTER_ADDRESS;
+
+	/* TODO: what if channel is full? */
+
+	need = sizeof(hdr) + hdr.size;
+	spin_lock_irqsave(&smd_lock, flags);
+	while (smd_write_avail(smd_channel) < need) {
+		spin_unlock_irqrestore(&smd_lock, flags);
+		msleep(250);
+		spin_lock_irqsave(&smd_lock, flags);
+	}
+	smd_write(smd_channel, &hdr, sizeof(hdr));
+	smd_write(smd_channel, msg, hdr.size);
+	spin_unlock_irqrestore(&smd_lock, flags);
+	return 0;
+}
+
+static struct rr_server *rpcrouter_create_server(uint32_t pid,
+							uint32_t cid,
+							uint32_t prog,
+							uint32_t ver)
+{
+	struct rr_server *server;
+	unsigned long flags;
+	int rc;
+
+	server = kmalloc(sizeof(struct rr_server), GFP_KERNEL);
+	if (!server)
+		return ERR_PTR(-ENOMEM);
+
+	memset(server, 0, sizeof(struct rr_server));
+	server->pid = pid;
+	server->cid = cid;
+	server->prog = prog;
+	server->vers = ver;
+
+	spin_lock_irqsave(&server_list_lock, flags);
+	list_add_tail(&server->list, &server_list);
+	spin_unlock_irqrestore(&server_list_lock, flags);
+
+	if (pid == RPCROUTER_PID_REMOTE) {
+		rc = msm_rpcrouter_create_server_cdev(server);
+		if (rc < 0)
+			goto out_fail;
+	}
+	return server;
+out_fail:
+	spin_lock_irqsave(&server_list_lock, flags);
+	list_del(&server->list);
+	spin_unlock_irqrestore(&server_list_lock, flags);
+	kfree(server);
+	return ERR_PTR(rc);
+}
+
+static void rpcrouter_destroy_server(struct rr_server *server)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&server_list_lock, flags);
+	list_del(&server->list);
+	spin_unlock_irqrestore(&server_list_lock, flags);
+	device_destroy(msm_rpcrouter_class, server->device_number);
+	kfree(server);
+}
+
+static struct rr_server *rpcrouter_lookup_server(uint32_t prog, uint32_t ver)
+{
+	struct rr_server *server;
+	unsigned long flags;
+
+	spin_lock_irqsave(&server_list_lock, flags);
+	list_for_each_entry(server, &server_list, list) {
+		if (server->prog == prog
+		 && server->vers == ver) {
+			spin_unlock_irqrestore(&server_list_lock, flags);
+			return server;
+		}
+	}
+	spin_unlock_irqrestore(&server_list_lock, flags);
+	return NULL;
+}
+
+static struct rr_server *rpcrouter_lookup_server_by_dev(dev_t dev)
+{
+	struct rr_server *server;
+	unsigned long flags;
+
+	spin_lock_irqsave(&server_list_lock, flags);
+	list_for_each_entry(server, &server_list, list) {
+		if (server->device_number == dev) {
+			spin_unlock_irqrestore(&server_list_lock, flags);
+			return server;
+		}
+	}
+	spin_unlock_irqrestore(&server_list_lock, flags);
+	return NULL;
+}
+
+struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev)
+{
+	struct msm_rpc_endpoint *ept;
+	unsigned long flags;
+
+	ept = kmalloc(sizeof(struct msm_rpc_endpoint), GFP_KERNEL);
+	if (!ept)
+		return NULL;
+	memset(ept, 0, sizeof(struct msm_rpc_endpoint));
+
+	/* mark no reply outstanding */
+	ept->reply_pid = 0xffffffff;
+
+	ept->cid = (uint32_t) ept;
+	ept->pid = RPCROUTER_PID_LOCAL;
+	ept->dev = dev;
+
+	if ((dev != msm_rpcrouter_devno) && (dev != MKDEV(0, 0))) {
+		struct rr_server *srv;
+		/*
+		 * This is a userspace client which opened
+		 * a program/ver devicenode. Bind the client
+		 * to that destination
+		 */
+		srv = rpcrouter_lookup_server_by_dev(dev);
+		/* TODO: bug? really? */
+		BUG_ON(!srv);
+
+		ept->dst_pid = srv->pid;
+		ept->dst_cid = srv->cid;
+		ept->dst_prog = cpu_to_be32(srv->prog);
+		ept->dst_vers = cpu_to_be32(srv->vers);
+
+		D("Creating local ept %p @ %08x:%08x\n", ept, srv->prog, srv->vers);
+	} else {
+		/* mark not connected */
+		ept->dst_pid = 0xffffffff;
+		D("Creating a master local ept %p\n", ept);
+	}
+
+	init_waitqueue_head(&ept->wait_q);
+	INIT_LIST_HEAD(&ept->read_q);
+	spin_lock_init(&ept->read_q_lock);
+	wake_lock_init(&ept->read_q_wake_lock, WAKE_LOCK_SUSPEND, "rpc_read");
+	INIT_LIST_HEAD(&ept->incomplete);
+
+	spin_lock_irqsave(&local_endpoints_lock, flags);
+	list_add_tail(&ept->list, &local_endpoints);
+	spin_unlock_irqrestore(&local_endpoints_lock, flags);
+	return ept;
+}
+
+int msm_rpcrouter_destroy_local_endpoint(struct msm_rpc_endpoint *ept)
+{
+	int rc;
+	union rr_control_msg msg;
+
+	msg.cmd = RPCROUTER_CTRL_CMD_REMOVE_CLIENT;
+	msg.cli.pid = ept->pid;
+	msg.cli.cid = ept->cid;
+
+	RR("x REMOVE_CLIENT id=%d:%08x\n", ept->pid, ept->cid);
+	rc = rpcrouter_send_control_msg(&msg);
+	if (rc < 0)
+		return rc;
+
+	wake_lock_destroy(&ept->read_q_wake_lock);
+	list_del(&ept->list);
+	kfree(ept);
+	return 0;
+}
+
+static int rpcrouter_create_remote_endpoint(uint32_t cid)
+{
+	struct rr_remote_endpoint *new_c;
+	unsigned long flags;
+
+	new_c = kmalloc(sizeof(struct rr_remote_endpoint), GFP_KERNEL);
+	if (!new_c)
+		return -ENOMEM;
+	memset(new_c, 0, sizeof(struct rr_remote_endpoint));
+
+	new_c->cid = cid;
+	new_c->pid = RPCROUTER_PID_REMOTE;
+	init_waitqueue_head(&new_c->quota_wait);
+	spin_lock_init(&new_c->quota_lock);
+
+	spin_lock_irqsave(&remote_endpoints_lock, flags);
+	list_add_tail(&new_c->list, &remote_endpoints);
+	spin_unlock_irqrestore(&remote_endpoints_lock, flags);
+	return 0;
+}
+
+static struct msm_rpc_endpoint *rpcrouter_lookup_local_endpoint(uint32_t cid)
+{
+	struct msm_rpc_endpoint *ept;
+	unsigned long flags;
+
+	spin_lock_irqsave(&local_endpoints_lock, flags);
+	list_for_each_entry(ept, &local_endpoints, list) {
+		if (ept->cid == cid) {
+			spin_unlock_irqrestore(&local_endpoints_lock, flags);
+			return ept;
+		}
+	}
+	spin_unlock_irqrestore(&local_endpoints_lock, flags);
+	return NULL;
+}
+
+static struct rr_remote_endpoint *rpcrouter_lookup_remote_endpoint(uint32_t cid)
+{
+	struct rr_remote_endpoint *ept;
+	unsigned long flags;
+
+	spin_lock_irqsave(&remote_endpoints_lock, flags);
+	list_for_each_entry(ept, &remote_endpoints, list) {
+		if (ept->cid == cid) {
+			spin_unlock_irqrestore(&remote_endpoints_lock, flags);
+			return ept;
+		}
+	}
+	spin_unlock_irqrestore(&remote_endpoints_lock, flags);
+	return NULL;
+}
+
+static int process_control_msg(union rr_control_msg *msg, int len)
+{
+	union rr_control_msg ctl;
+	struct rr_server *server;
+	struct rr_remote_endpoint *r_ept;
+	int rc = 0;
+	unsigned long flags;
+
+	if (len != sizeof(*msg)) {
+		printk(KERN_ERR "rpcrouter: r2r msg size %d != %d\n",
+		       len, sizeof(*msg));
+		return -EINVAL;
+	}
+
+	switch (msg->cmd) {
+	case RPCROUTER_CTRL_CMD_HELLO:
+		RR("o HELLO\n");
+
+		RR("x HELLO\n");
+		memset(&ctl, 0, sizeof(ctl));
+		ctl.cmd = RPCROUTER_CTRL_CMD_HELLO;
+		rpcrouter_send_control_msg(&ctl);
+
+		initialized = 1;
+
+		/* Send list of servers one at a time */
+		ctl.cmd = RPCROUTER_CTRL_CMD_NEW_SERVER;
+
+		/* TODO: long time to hold a spinlock... */
+		spin_lock_irqsave(&server_list_lock, flags);
+		list_for_each_entry(server, &server_list, list) {
+			ctl.srv.pid = server->pid;
+			ctl.srv.cid = server->cid;
+			ctl.srv.prog = server->prog;
+			ctl.srv.vers = server->vers;
+
+			RR("x NEW_SERVER id=%d:%08x prog=%08x:%08x\n",
+			   server->pid, server->cid,
+			   server->prog, server->vers);
+
+			rpcrouter_send_control_msg(&ctl);
+		}
+		spin_unlock_irqrestore(&server_list_lock, flags);
+
+		queue_work(rpcrouter_workqueue, &work_create_rpcrouter_pdev);
+		break;
+
+	case RPCROUTER_CTRL_CMD_RESUME_TX:
+		RR("o RESUME_TX id=%d:%08x\n", msg->cli.pid, msg->cli.cid);
+
+		r_ept = rpcrouter_lookup_remote_endpoint(msg->cli.cid);
+		if (!r_ept) {
+			printk(KERN_ERR
+			       "rpcrouter: Unable to resume client\n");
+			break;
+		}
+		spin_lock_irqsave(&r_ept->quota_lock, flags);
+		r_ept->tx_quota_cntr = 0;
+		spin_unlock_irqrestore(&r_ept->quota_lock, flags);
+		wake_up(&r_ept->quota_wait);
+		break;
+
+	case RPCROUTER_CTRL_CMD_NEW_SERVER:
+		RR("o NEW_SERVER id=%d:%08x prog=%08x:%08x\n",
+		   msg->srv.pid, msg->srv.cid, msg->srv.prog, msg->srv.vers);
+
+		server = rpcrouter_lookup_server(msg->srv.prog, msg->srv.vers);
+
+		if (!server) {
+			server = rpcrouter_create_server(
+				msg->srv.pid, msg->srv.cid,
+				msg->srv.prog, msg->srv.vers);
+			if (!server)
+				return -ENOMEM;
+			/*
+			 * XXX: Verify that its okay to add the
+			 * client to our remote client list
+			 * if we get a NEW_SERVER notification
+			 */
+			if (!rpcrouter_lookup_remote_endpoint(msg->srv.cid)) {
+				rc = rpcrouter_create_remote_endpoint(
+					msg->srv.cid);
+				if (rc < 0)
+					printk(KERN_ERR
+						"rpcrouter:Client create"
+						"error (%d)\n", rc);
+			}
+			schedule_work(&work_create_pdevs);
+			wake_up(&newserver_wait);
+		} else {
+			if ((server->pid == msg->srv.pid) &&
+			    (server->cid == msg->srv.cid)) {
+				printk(KERN_ERR "rpcrouter: Duplicate svr\n");
+			} else {
+				server->pid = msg->srv.pid;
+				server->cid = msg->srv.cid;
+			}
+		}
+		break;
+
+	case RPCROUTER_CTRL_CMD_REMOVE_SERVER:
+		RR("o REMOVE_SERVER prog=%08x:%d\n",
+		   msg->srv.prog, msg->srv.vers);
+		server = rpcrouter_lookup_server(msg->srv.prog, msg->srv.vers);
+		if (server)
+			rpcrouter_destroy_server(server);
+		break;
+
+	case RPCROUTER_CTRL_CMD_REMOVE_CLIENT:
+		RR("o REMOVE_CLIENT id=%d:%08x\n", msg->cli.pid, msg->cli.cid);
+		if (msg->cli.pid != RPCROUTER_PID_REMOTE) {
+			printk(KERN_ERR
+			       "rpcrouter: Denying remote removal of "
+			       "local client\n");
+			break;
+		}
+		r_ept = rpcrouter_lookup_remote_endpoint(msg->cli.cid);
+		if (r_ept) {
+			spin_lock_irqsave(&remote_endpoints_lock, flags);
+			list_del(&r_ept->list);
+			spin_unlock_irqrestore(&remote_endpoints_lock, flags);
+			kfree(r_ept);
+		}
+
+		/* Notify local clients of this event */
+		printk(KERN_ERR "rpcrouter: LOCAL NOTIFICATION NOT IMP\n");
+		rc = -ENOSYS;
+
+		break;
+	default:
+		RR("o UNKNOWN(%08x)\n", msg->cmd);
+		rc = -ENOSYS;
+	}
+
+	return rc;
+}
+
+static void do_create_rpcrouter_pdev(struct work_struct *work)
+{
+	platform_device_register(&rpcrouter_pdev);
+}
+
+static void do_create_pdevs(struct work_struct *work)
+{
+	unsigned long flags;
+	struct rr_server *server;
+
+	/* TODO: race if destroyed while being registered */
+	spin_lock_irqsave(&server_list_lock, flags);
+	list_for_each_entry(server, &server_list, list) {
+		if (server->pid == RPCROUTER_PID_REMOTE) {
+			if (server->pdev_name[0] == 0) {
+				spin_unlock_irqrestore(&server_list_lock,
+						       flags);
+				msm_rpcrouter_create_server_pdev(server);
+				schedule_work(&work_create_pdevs);
+				return;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&server_list_lock, flags);
+}
+
+static void rpcrouter_smdnotify(void *_dev, unsigned event)
+{
+	if (event != SMD_EVENT_DATA)
+		return;
+
+	if (smd_read_avail(smd_channel) >= rpcrouter_need_len)
+		wake_lock(&rpcrouter_wake_lock);
+	wake_up(&smd_wait);
+}
+
+static void *rr_malloc(unsigned sz)
+{
+	void *ptr = kmalloc(sz, GFP_KERNEL);
+	if (ptr)
+		return ptr;
+
+	printk(KERN_ERR "rpcrouter: kmalloc of %d failed, retrying...\n", sz);
+	do {
+		ptr = kmalloc(sz, GFP_KERNEL);
+	} while (!ptr);
+
+	return ptr;
+}
+
+/* TODO: deal with channel teardown / restore */
+static int rr_read(void *data, int len)
+{
+	int rc;
+	unsigned long flags;
+//	printk("rr_read() %d\n", len);
+	for(;;) {
+		spin_lock_irqsave(&smd_lock, flags);
+		if (smd_read_avail(smd_channel) >= len) {
+			rc = smd_read(smd_channel, data, len);
+			spin_unlock_irqrestore(&smd_lock, flags);
+			if (rc == len)
+				return 0;
+			else
+				return -EIO;
+		}
+		rpcrouter_need_len = len;
+		wake_unlock(&rpcrouter_wake_lock);
+		spin_unlock_irqrestore(&smd_lock, flags);
+
+//		printk("rr_read: waiting (%d)\n", len);
+		wait_event(smd_wait, smd_read_avail(smd_channel) >= len);
+	}
+	return 0;
+}
+
+static uint32_t r2r_buf[RPCROUTER_MSGSIZE_MAX];
+
+static void do_read_data(struct work_struct *work)
+{
+	struct rr_header hdr;
+	struct rr_packet *pkt;
+	struct rr_fragment *frag;
+	struct msm_rpc_endpoint *ept;
+	uint32_t pm, mid;
+	unsigned long flags;
+
+	if (rr_read(&hdr, sizeof(hdr)))
+		goto fail_io;
+
+#if TRACE_R2R_RAW
+	RR("- ver=%d type=%d src=%d:%08x crx=%d siz=%d dst=%d:%08x\n",
+	   hdr.version, hdr.type, hdr.src_pid, hdr.src_cid,
+	   hdr.confirm_rx, hdr.size, hdr.dst_pid, hdr.dst_cid);
+#endif
+
+	if (hdr.version != RPCROUTER_VERSION) {
+		DIAG("version %d != %d\n", hdr.version, RPCROUTER_VERSION);
+		goto fail_data;
+	}
+	if (hdr.size > RPCROUTER_MSGSIZE_MAX) {
+		DIAG("msg size %d > max %d\n", hdr.size, RPCROUTER_MSGSIZE_MAX);
+		goto fail_data;
+	}
+
+	if (hdr.dst_cid == RPCROUTER_ROUTER_ADDRESS) {
+		if (rr_read(r2r_buf, hdr.size))
+			goto fail_io;
+		process_control_msg((void*) r2r_buf, hdr.size);
+		goto done;
+	}
+
+	if (hdr.size < sizeof(pm)) {
+		DIAG("runt packet (no pacmark)\n");
+		goto fail_data;
+	}
+	if (rr_read(&pm, sizeof(pm)))
+		goto fail_io;
+
+	hdr.size -= sizeof(pm);
+
+	frag = rr_malloc(hdr.size + sizeof(*frag));
+	frag->next = NULL;
+	frag->length = hdr.size;
+	if (rr_read(frag->data, hdr.size))
+		goto fail_io;
+
+	ept = rpcrouter_lookup_local_endpoint(hdr.dst_cid);
+	if (!ept) {
+		DIAG("no local ept for cid %08x\n", hdr.dst_cid);
+		kfree(frag);
+		goto done;
+	}
+
+	/* See if there is already a partial packet that matches our mid
+	 * and if so, append this fragment to that packet.
+	 */
+	mid = PACMARK_MID(pm);
+	list_for_each_entry(pkt, &ept->incomplete, list) {
+		if (pkt->mid == mid) {
+			pkt->last->next = frag;
+			pkt->last = frag;
+			pkt->length += frag->length;
+			if (PACMARK_LAST(pm)) {
+				list_del(&pkt->list);
+				goto packet_complete;
+			}
+			goto done;
+		}
+	}
+	/* This mid is new -- create a packet for it, and put it on
+	 * the incomplete list if this fragment is not a last fragment,
+	 * otherwise put it on the read queue.
+	 */
+	pkt = rr_malloc(sizeof(struct rr_packet));
+	pkt->first = frag;
+	pkt->last = frag;
+	memcpy(&pkt->hdr, &hdr, sizeof(hdr));
+	pkt->mid = mid;
+	pkt->length = frag->length;
+	if (!PACMARK_LAST(pm)) {
+		list_add_tail(&pkt->list, &ept->incomplete);
+		goto done;
+	}
+
+packet_complete:
+	spin_lock_irqsave(&ept->read_q_lock, flags);
+	wake_lock(&ept->read_q_wake_lock);
+	list_add_tail(&pkt->list, &ept->read_q);
+	wake_up(&ept->wait_q);
+	spin_unlock_irqrestore(&ept->read_q_lock, flags);
+done:
+
+	if (hdr.confirm_rx) {
+		union rr_control_msg msg;
+
+		msg.cmd = RPCROUTER_CTRL_CMD_RESUME_TX;
+		msg.cli.pid = hdr.dst_pid;
+		msg.cli.cid = hdr.dst_cid;
+
+		RR("x RESUME_TX id=%d:%08x\n", msg.cli.pid, msg.cli.cid);
+		rpcrouter_send_control_msg(&msg);
+	}
+
+	queue_work(rpcrouter_workqueue, &work_read_data);
+	return;
+
+fail_io:
+fail_data:
+	printk(KERN_ERR "rpc_router has died\n");
+	wake_unlock(&rpcrouter_wake_lock);
+}
+
+void msm_rpc_setup_req(struct rpc_request_hdr *hdr, uint32_t prog,
+		       uint32_t vers, uint32_t proc)
+{
+	memset(hdr, 0, sizeof(struct rpc_request_hdr));
+	hdr->xid = cpu_to_be32(atomic_add_return(1, &next_xid));
+	hdr->rpc_vers = cpu_to_be32(2);
+	hdr->prog = cpu_to_be32(prog);
+	hdr->vers = cpu_to_be32(vers);
+	hdr->procedure = cpu_to_be32(proc);
+}
+
+struct msm_rpc_endpoint *msm_rpc_open(void)
+{
+	struct msm_rpc_endpoint *ept;
+
+	ept = msm_rpcrouter_create_local_endpoint(MKDEV(0, 0));
+	if (ept == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	return ept;
+}
+
+int msm_rpc_close(struct msm_rpc_endpoint *ept)
+{
+	return msm_rpcrouter_destroy_local_endpoint(ept);
+}
+EXPORT_SYMBOL(msm_rpc_close);
+
+int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count)
+{
+	struct rr_header hdr;
+	uint32_t pacmark;
+	struct rpc_request_hdr *rq = buffer;
+	struct rr_remote_endpoint *r_ept;
+	unsigned long flags;
+	int needed;
+	DEFINE_WAIT(__wait);
+
+	/* TODO: fragmentation for large outbound packets */
+	if (count > (RPCROUTER_MSGSIZE_MAX - sizeof(uint32_t)) || !count)
+		return -EINVAL;
+
+	/* snoop the RPC packet and enforce permissions */
+
+	/* has to have at least the xid and type fields */
+	if (count < (sizeof(uint32_t) * 2)) {
+		printk(KERN_ERR "rr_write: rejecting runt packet\n");
+		return -EINVAL;
+	}
+
+	if (rq->type == 0) {
+		/* RPC CALL */
+		if (count < (sizeof(uint32_t) * 6)) {
+			printk(KERN_ERR
+			       "rr_write: rejecting runt call packet\n");
+			return -EINVAL;
+		}
+		if (ept->dst_pid == 0xffffffff) {
+			printk(KERN_ERR "rr_write: not connected\n");
+			return -ENOTCONN;
+		}
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+		if ((ept->dst_prog != rq->prog) ||
+			!msm_rpc_is_compatible_version(
+					be32_to_cpu(ept->dst_vers),
+					be32_to_cpu(rq->vers))) {
+#else
+		if (ept->dst_prog != rq->prog || ept->dst_vers != rq->vers) {
+#endif
+			printk(KERN_ERR
+			       "rr_write: cannot write to %08x:%d "
+			       "(bound to %08x:%d)\n",
+			       be32_to_cpu(rq->prog), be32_to_cpu(rq->vers),
+			       be32_to_cpu(ept->dst_prog),
+			       be32_to_cpu(ept->dst_vers));
+			return -EINVAL;
+		}
+		hdr.dst_pid = ept->dst_pid;
+		hdr.dst_cid = ept->dst_cid;
+		IO("CALL on ept %p to %08x:%08x @ %d:%08x (%d bytes) (xid %x proc %x)\n",
+		   ept,
+		   be32_to_cpu(rq->prog), be32_to_cpu(rq->vers),
+		   ept->dst_pid, ept->dst_cid, count,
+		   be32_to_cpu(rq->xid), be32_to_cpu(rq->procedure));
+	} else {
+		/* RPC REPLY */
+		/* TODO: locking */
+		if (ept->reply_pid == 0xffffffff) {
+			printk(KERN_ERR
+			       "rr_write: rejecting unexpected reply\n");
+			return -EINVAL;
+		}
+		if (ept->reply_xid != rq->xid) {
+			printk(KERN_ERR
+			       "rr_write: rejecting packet w/ bad xid\n");
+			return -EINVAL;
+		}
+
+		hdr.dst_pid = ept->reply_pid;
+		hdr.dst_cid = ept->reply_cid;
+
+		/* consume this reply */
+		ept->reply_pid = 0xffffffff;
+
+		IO("REPLY on ept %p to xid=%d @ %d:%08x (%d bytes)\n",
+		   ept,
+		   be32_to_cpu(rq->xid), hdr.dst_pid, hdr.dst_cid, count);
+	}
+
+	r_ept = rpcrouter_lookup_remote_endpoint(hdr.dst_cid);
+
+	if (!r_ept) {
+		printk(KERN_ERR
+			"msm_rpc_write(): No route to ept "
+			"[PID %x CID %x]\n", hdr.dst_pid, hdr.dst_cid);
+		return -EHOSTUNREACH;
+	}
+
+	/* Create routing header */
+	hdr.type = RPCROUTER_CTRL_CMD_DATA;
+	hdr.version = RPCROUTER_VERSION;
+	hdr.src_pid = ept->pid;
+	hdr.src_cid = ept->cid;
+	hdr.confirm_rx = 0;
+	hdr.size = count + sizeof(uint32_t);
+
+	for (;;) {
+		prepare_to_wait(&r_ept->quota_wait, &__wait,
+				TASK_INTERRUPTIBLE);
+		spin_lock_irqsave(&r_ept->quota_lock, flags);
+		if (r_ept->tx_quota_cntr < RPCROUTER_DEFAULT_RX_QUOTA)
+			break;
+		if (signal_pending(current) &&
+		    (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE)))
+			break;
+		spin_unlock_irqrestore(&r_ept->quota_lock, flags);
+		schedule();
+	}
+	finish_wait(&r_ept->quota_wait, &__wait);
+
+	if (signal_pending(current) &&
+	    (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) {
+		spin_unlock_irqrestore(&r_ept->quota_lock, flags);
+		return -ERESTARTSYS;
+	}
+	r_ept->tx_quota_cntr++;
+	if (r_ept->tx_quota_cntr == RPCROUTER_DEFAULT_RX_QUOTA)
+		hdr.confirm_rx = 1;
+
+	/* bump pacmark while interrupts disabled to avoid race
+	 * probably should be atomic op instead
+	 */
+	pacmark = PACMARK(count, ++next_pacmarkid, 0, 1);
+
+	spin_unlock_irqrestore(&r_ept->quota_lock, flags);
+
+	spin_lock_irqsave(&smd_lock, flags);
+
+	needed = sizeof(hdr) + hdr.size;
+	while (smd_write_avail(smd_channel) < needed) {
+		spin_unlock_irqrestore(&smd_lock, flags);
+		msleep(250);
+		spin_lock_irqsave(&smd_lock, flags);
+	}
+
+	/* TODO: deal with full fifo */
+	smd_write(smd_channel, &hdr, sizeof(hdr));
+	smd_write(smd_channel, &pacmark, sizeof(pacmark));
+	smd_write(smd_channel, buffer, count);
+
+	spin_unlock_irqrestore(&smd_lock, flags);
+
+	return count;
+}
+EXPORT_SYMBOL(msm_rpc_write);
+
+/*
+ * NOTE: It is the responsibility of the caller to kfree buffer
+ */
+int msm_rpc_read(struct msm_rpc_endpoint *ept, void **buffer,
+		 unsigned user_len, long timeout)
+{
+	struct rr_fragment *frag, *next;
+	char *buf;
+	int rc;
+
+	rc = __msm_rpc_read(ept, &frag, user_len, timeout);
+	if (rc <= 0)
+		return rc;
+
+	/* single-fragment messages conveniently can be
+	 * returned as-is (the buffer is at the front)
+	 */
+	if (frag->next == 0) {
+		*buffer = (void*) frag;
+		return rc;
+	}
+
+	/* multi-fragment messages, we have to do it the
+	 * hard way, which is rather disgusting right now
+	 */
+	buf = rr_malloc(rc);
+	*buffer = buf;
+
+	while (frag != NULL) {
+		memcpy(buf, frag->data, frag->length);
+		next = frag->next;
+		buf += frag->length;
+		kfree(frag);
+		frag = next;
+	}
+
+	return rc;
+}
+
+int msm_rpc_call(struct msm_rpc_endpoint *ept, uint32_t proc,
+		 void *_request, int request_size,
+		 long timeout)
+{
+	return msm_rpc_call_reply(ept, proc,
+				  _request, request_size,
+				  NULL, 0, timeout);
+}
+EXPORT_SYMBOL(msm_rpc_call);
+
+int msm_rpc_call_reply(struct msm_rpc_endpoint *ept, uint32_t proc,
+		       void *_request, int request_size,
+		       void *_reply, int reply_size,
+		       long timeout)
+{
+	struct rpc_request_hdr *req = _request;
+	struct rpc_reply_hdr *reply;
+	int rc;
+
+	if (request_size < sizeof(*req))
+		return -ETOOSMALL;
+
+	if (ept->dst_pid == 0xffffffff)
+		return -ENOTCONN;
+
+	/* We can't use msm_rpc_setup_req() here, because dst_prog and
+	 * dst_vers here are already in BE.
+	 */
+	memset(req, 0, sizeof(*req));
+	req->xid = cpu_to_be32(atomic_add_return(1, &next_xid));
+	req->rpc_vers = cpu_to_be32(2);
+	req->prog = ept->dst_prog;
+	req->vers = ept->dst_vers;
+	req->procedure = cpu_to_be32(proc);
+
+	rc = msm_rpc_write(ept, req, request_size);
+	if (rc < 0)
+		return rc;
+
+	for (;;) {
+		rc = msm_rpc_read(ept, (void*) &reply, -1, timeout);
+		if (rc < 0)
+			return rc;
+		if (rc < (3 * sizeof(uint32_t))) {
+			rc = -EIO;
+			break;
+		}
+		/* we should not get CALL packets -- ignore them */
+		if (reply->type == 0) {
+			kfree(reply);
+			continue;
+		}
+		/* If an earlier call timed out, we could get the (no
+		 * longer wanted) reply for it.  Ignore replies that
+		 * we don't expect.
+		 */
+		if (reply->xid != req->xid) {
+			kfree(reply);
+			continue;
+		}
+		if (reply->reply_stat != 0) {
+			rc = -EPERM;
+			break;
+		}
+		if (reply->data.acc_hdr.accept_stat != 0) {
+			rc = -EINVAL;
+			break;
+		}
+		if (_reply == NULL) {
+			rc = 0;
+			break;
+		}
+		if (rc > reply_size) {
+			rc = -ENOMEM;
+		} else {
+			memcpy(_reply, reply, rc);
+		}
+		break;
+	}
+	kfree(reply);
+	return rc;
+}
+EXPORT_SYMBOL(msm_rpc_call_reply);
+
+
+static inline int ept_packet_available(struct msm_rpc_endpoint *ept)
+{
+	unsigned long flags;
+	int ret;
+	spin_lock_irqsave(&ept->read_q_lock, flags);
+	ret = !list_empty(&ept->read_q);
+	spin_unlock_irqrestore(&ept->read_q_lock, flags);
+	return ret;
+}
+
+int __msm_rpc_read(struct msm_rpc_endpoint *ept,
+		   struct rr_fragment **frag_ret,
+		   unsigned len, long timeout)
+{
+	struct rr_packet *pkt;
+	struct rpc_request_hdr *rq;
+	DEFINE_WAIT(__wait);
+	unsigned long flags;
+	int rc;
+
+	IO("READ on ept %p\n", ept);
+
+	if (ept->flags & MSM_RPC_UNINTERRUPTIBLE) {
+		if (timeout < 0) {
+			wait_event(ept->wait_q, ept_packet_available(ept));
+		} else {
+			rc = wait_event_timeout(
+				ept->wait_q, ept_packet_available(ept),
+				timeout);
+			if (rc == 0)
+				return -ETIMEDOUT;
+		}
+	} else {
+		if (timeout < 0) {
+			rc = wait_event_interruptible(
+				ept->wait_q, ept_packet_available(ept));
+			if (rc < 0)
+				return rc;
+		} else {
+			rc = wait_event_interruptible_timeout(
+				ept->wait_q, ept_packet_available(ept),
+				timeout);
+			if (rc == 0)
+				return -ETIMEDOUT;
+		}
+	}
+
+	spin_lock_irqsave(&ept->read_q_lock, flags);
+	if (list_empty(&ept->read_q)) {
+		spin_unlock_irqrestore(&ept->read_q_lock, flags);
+		return -EAGAIN;
+	}
+	pkt = list_first_entry(&ept->read_q, struct rr_packet, list);
+	if (pkt->length > len) {
+		spin_unlock_irqrestore(&ept->read_q_lock, flags);
+		return -ETOOSMALL;
+	}
+	list_del(&pkt->list);
+	if (list_empty(&ept->read_q))
+		wake_unlock(&ept->read_q_wake_lock);
+	spin_unlock_irqrestore(&ept->read_q_lock, flags);
+
+	rc = pkt->length;
+
+	*frag_ret = pkt->first;
+	rq = (void*) pkt->first->data;
+	if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 0)) {
+		IO("READ on ept %p is a CALL on %08x:%08x proc %d xid %d\n",
+			ept, be32_to_cpu(rq->prog), be32_to_cpu(rq->vers),
+			be32_to_cpu(rq->procedure),
+			be32_to_cpu(rq->xid));
+		/* RPC CALL */
+		if (ept->reply_pid != 0xffffffff) {
+			printk(KERN_WARNING
+			       "rr_read: lost previous reply xid...\n");
+		}
+		/* TODO: locking? */
+		ept->reply_pid = pkt->hdr.src_pid;
+		ept->reply_cid = pkt->hdr.src_cid;
+		ept->reply_xid = rq->xid;
+	}
+#if TRACE_RPC_MSG
+	else if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 1))
+		IO("READ on ept %p is a REPLY\n", ept);
+	else IO("READ on ept %p (%d bytes)\n", ept, rc);
+#endif
+
+	kfree(pkt);
+	return rc;
+}
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+int msm_rpc_is_compatible_version(uint32_t server_version,
+				  uint32_t client_version)
+{
+	if ((server_version & RPC_VERSION_MODE_MASK) !=
+	    (client_version & RPC_VERSION_MODE_MASK))
+		return 0;
+
+	if (server_version & RPC_VERSION_MODE_MASK)
+		return server_version == client_version;
+
+	return ((server_version & RPC_VERSION_MAJOR_MASK) ==
+		(client_version & RPC_VERSION_MAJOR_MASK)) &&
+		((server_version & RPC_VERSION_MINOR_MASK) >=
+		(client_version & RPC_VERSION_MINOR_MASK));
+}
+EXPORT_SYMBOL(msm_rpc_is_compatible_version);
+
+static int msm_rpc_get_compatible_server(uint32_t prog,
+					uint32_t ver,
+					uint32_t *found_vers)
+{
+	struct rr_server *server;
+	unsigned long     flags;
+	if (found_vers == NULL)
+		return 0;
+
+	spin_lock_irqsave(&server_list_lock, flags);
+	list_for_each_entry(server, &server_list, list) {
+		if ((server->prog == prog) &&
+		    msm_rpc_is_compatible_version(server->vers, ver)) {
+			*found_vers = server->vers;
+			spin_unlock_irqrestore(&server_list_lock, flags);
+			return 0;
+		}
+	}
+	spin_unlock_irqrestore(&server_list_lock, flags);
+	return -1;
+}
+#endif
+
+struct msm_rpc_endpoint *msm_rpc_connect(uint32_t prog, uint32_t vers, unsigned flags)
+{
+	struct msm_rpc_endpoint *ept;
+	struct rr_server *server;
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	if (!(vers & RPC_VERSION_MODE_MASK)) {
+		uint32_t found_vers;
+		if (msm_rpc_get_compatible_server(prog, vers, &found_vers) < 0)
+			return ERR_PTR(-EHOSTUNREACH);
+		if (found_vers != vers) {
+			D("RPC using new version %08x:{%08x --> %08x}\n",
+			 	prog, vers, found_vers);
+			vers = found_vers;
+		}
+	}
+#endif
+
+	server = rpcrouter_lookup_server(prog, vers);
+	if (!server)
+		return ERR_PTR(-EHOSTUNREACH);
+
+	ept = msm_rpc_open();
+	if (IS_ERR(ept))
+		return ept;
+
+	ept->flags = flags;
+	ept->dst_pid = server->pid;
+	ept->dst_cid = server->cid;
+	ept->dst_prog = cpu_to_be32(prog);
+	ept->dst_vers = cpu_to_be32(vers);
+
+	return ept;
+}
+EXPORT_SYMBOL(msm_rpc_connect);
+
+uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept)
+{
+	return be32_to_cpu(ept->dst_vers);
+}
+EXPORT_SYMBOL(msm_rpc_get_vers);
+
+/* TODO: permission check? */
+int msm_rpc_register_server(struct msm_rpc_endpoint *ept,
+			    uint32_t prog, uint32_t vers)
+{
+	int rc;
+	union rr_control_msg msg;
+	struct rr_server *server;
+
+	server = rpcrouter_create_server(ept->pid, ept->cid,
+					 prog, vers);
+	if (!server)
+		return -ENODEV;
+
+	msg.srv.cmd = RPCROUTER_CTRL_CMD_NEW_SERVER;
+	msg.srv.pid = ept->pid;
+	msg.srv.cid = ept->cid;
+	msg.srv.prog = prog;
+	msg.srv.vers = vers;
+
+	RR("x NEW_SERVER id=%d:%08x prog=%08x:%08x\n",
+	   ept->pid, ept->cid, prog, vers);
+
+	rc = rpcrouter_send_control_msg(&msg);
+	if (rc < 0)
+		return rc;
+
+	return 0;
+}
+
+/* TODO: permission check -- disallow unreg of somebody else's server */
+int msm_rpc_unregister_server(struct msm_rpc_endpoint *ept,
+			      uint32_t prog, uint32_t vers)
+{
+	struct rr_server *server;
+	server = rpcrouter_lookup_server(prog, vers);
+
+	if (!server)
+		return -ENOENT;
+	rpcrouter_destroy_server(server);
+	return 0;
+}
+
+static int msm_rpcrouter_probe(struct platform_device *pdev)
+{
+	int rc;
+
+	/* Initialize what we need to start processing */
+	INIT_LIST_HEAD(&local_endpoints);
+	INIT_LIST_HEAD(&remote_endpoints);
+
+	init_waitqueue_head(&newserver_wait);
+	init_waitqueue_head(&smd_wait);
+	wake_lock_init(&rpcrouter_wake_lock, WAKE_LOCK_SUSPEND, "SMD_RPCCALL");
+
+	rpcrouter_workqueue = create_singlethread_workqueue("rpcrouter");
+	if (!rpcrouter_workqueue)
+		return -ENOMEM;
+
+	rc = msm_rpcrouter_init_devices();
+	if (rc < 0)
+		goto fail_destroy_workqueue;
+
+	/* Open up SMD channel 2 */
+	initialized = 0;
+	rc = smd_open("SMD_RPCCALL", &smd_channel, NULL, rpcrouter_smdnotify);
+	if (rc < 0)
+		goto fail_remove_devices;
+
+	queue_work(rpcrouter_workqueue, &work_read_data);
+	return 0;
+
+ fail_remove_devices:
+	msm_rpcrouter_exit_devices();
+ fail_destroy_workqueue:
+	destroy_workqueue(rpcrouter_workqueue);
+	return rc;
+}
+
+static struct platform_driver msm_smd_channel2_driver = {
+	.probe		= msm_rpcrouter_probe,
+	.driver		= {
+			.name	= "SMD_RPCCALL",
+			.owner	= THIS_MODULE,
+	},
+};
+
+static int __init rpcrouter_init(void)
+{
+	return platform_driver_register(&msm_smd_channel2_driver);
+}
+
+module_init(rpcrouter_init);
+MODULE_DESCRIPTION("MSM RPC Router");
+MODULE_AUTHOR("San Mehat <san@android.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/dream/smd/smd_rpcrouter.h b/drivers/staging/dream/smd/smd_rpcrouter.h
new file mode 100644
index 0000000..a7416a2
--- /dev/null
+++ b/drivers/staging/dream/smd/smd_rpcrouter.h
@@ -0,0 +1,195 @@
+/** arch/arm/mach-msm/smd_rpcrouter.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2008 QUALCOMM Incorporated.
+ * Author: San Mehat <san@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H
+#define _ARCH_ARM_MACH_MSM_SMD_RPCROUTER_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/cdev.h>
+#include <linux/platform_device.h>
+#include <linux/wakelock.h>
+
+#include <mach/msm_smd.h>
+#include <mach/msm_rpcrouter.h>
+
+/* definitions for the R2R wire protcol */
+
+#define RPCROUTER_VERSION			1
+#define RPCROUTER_PROCESSORS_MAX		4
+#define RPCROUTER_MSGSIZE_MAX			512
+
+#define RPCROUTER_CLIENT_BCAST_ID		0xffffffff
+#define RPCROUTER_ROUTER_ADDRESS		0xfffffffe
+
+#define RPCROUTER_PID_LOCAL			1
+#define RPCROUTER_PID_REMOTE			0
+
+#define RPCROUTER_CTRL_CMD_DATA			1
+#define RPCROUTER_CTRL_CMD_HELLO		2
+#define RPCROUTER_CTRL_CMD_BYE			3
+#define RPCROUTER_CTRL_CMD_NEW_SERVER		4
+#define RPCROUTER_CTRL_CMD_REMOVE_SERVER	5
+#define RPCROUTER_CTRL_CMD_REMOVE_CLIENT	6
+#define RPCROUTER_CTRL_CMD_RESUME_TX		7
+#define RPCROUTER_CTRL_CMD_EXIT			8
+
+#define RPCROUTER_DEFAULT_RX_QUOTA	5
+
+union rr_control_msg {
+	uint32_t cmd;
+	struct {
+		uint32_t cmd;
+		uint32_t prog;
+		uint32_t vers;
+		uint32_t pid;
+		uint32_t cid;
+	} srv;
+	struct {
+		uint32_t cmd;
+		uint32_t pid;
+		uint32_t cid;
+	} cli;
+};
+
+struct rr_header {
+	uint32_t version;
+	uint32_t type;
+	uint32_t src_pid;
+	uint32_t src_cid;
+	uint32_t confirm_rx;
+	uint32_t size;
+	uint32_t dst_pid;
+	uint32_t dst_cid;
+};
+
+/* internals */
+
+#define RPCROUTER_MAX_REMOTE_SERVERS		100
+
+struct rr_fragment {
+	unsigned char data[RPCROUTER_MSGSIZE_MAX];
+	uint32_t length;
+	struct rr_fragment *next;
+};
+
+struct rr_packet {
+	struct list_head list;
+	struct rr_fragment *first;
+	struct rr_fragment *last;
+	struct rr_header hdr;
+	uint32_t mid;
+	uint32_t length;
+};
+
+#define PACMARK_LAST(n) ((n) & 0x80000000)
+#define PACMARK_MID(n)  (((n) >> 16) & 0xFF)
+#define PACMARK_LEN(n)  ((n) & 0xFFFF)
+
+static inline uint32_t PACMARK(uint32_t len, uint32_t mid, uint32_t first,
+			       uint32_t last)
+{
+	return (len & 0xFFFF) |
+	  ((mid & 0xFF) << 16) |
+	  ((!!first) << 30) |
+	  ((!!last) << 31);
+}
+
+struct rr_server {
+	struct list_head list;
+
+	uint32_t pid;
+	uint32_t cid;
+	uint32_t prog;
+	uint32_t vers;
+
+	dev_t device_number;
+	struct cdev cdev;
+	struct device *device;
+	struct rpcsvr_platform_device p_device;
+	char pdev_name[32];
+};
+
+struct rr_remote_endpoint {
+	uint32_t pid;
+	uint32_t cid;
+
+	int tx_quota_cntr;
+	spinlock_t quota_lock;
+	wait_queue_head_t quota_wait;
+
+	struct list_head list;
+};
+
+struct msm_rpc_endpoint {
+	struct list_head list;
+
+	/* incomplete packets waiting for assembly */
+	struct list_head incomplete;
+
+	/* complete packets waiting to be read */
+	struct list_head read_q;
+	spinlock_t read_q_lock;
+	struct wake_lock read_q_wake_lock;
+	wait_queue_head_t wait_q;
+	unsigned flags;
+
+	/* endpoint address */
+	uint32_t pid;
+	uint32_t cid;
+
+	/* bound remote address
+	 * if not connected (dst_pid == 0xffffffff) RPC_CALL writes fail
+	 * RPC_CALLs must be to the prog/vers below or they will fail
+	 */
+	uint32_t dst_pid;
+	uint32_t dst_cid;
+	uint32_t dst_prog; /* be32 */
+	uint32_t dst_vers; /* be32 */
+
+	/* reply remote address
+	 * if reply_pid == 0xffffffff, none available
+	 * RPC_REPLY writes may only go to the pid/cid/xid of the
+	 * last RPC_CALL we received.
+	 */
+	uint32_t reply_pid;
+	uint32_t reply_cid;
+	uint32_t reply_xid; /* be32 */
+	uint32_t next_pm;   /* Pacmark sequence */
+
+	/* device node if this endpoint is accessed via userspace */
+	dev_t dev;
+};
+
+/* shared between smd_rpcrouter*.c */
+
+int __msm_rpc_read(struct msm_rpc_endpoint *ept,
+		   struct rr_fragment **frag,
+		   unsigned len, long timeout);
+
+struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev);
+int msm_rpcrouter_destroy_local_endpoint(struct msm_rpc_endpoint *ept);
+
+int msm_rpcrouter_create_server_cdev(struct rr_server *server);
+int msm_rpcrouter_create_server_pdev(struct rr_server *server);
+
+int msm_rpcrouter_init_devices(void);
+void msm_rpcrouter_exit_devices(void);
+
+extern dev_t msm_rpcrouter_devno;
+extern struct class *msm_rpcrouter_class;
+#endif
diff --git a/drivers/staging/dream/smd/smd_rpcrouter_device.c b/drivers/staging/dream/smd/smd_rpcrouter_device.c
new file mode 100644
index 0000000..cd3910b
--- /dev/null
+++ b/drivers/staging/dream/smd/smd_rpcrouter_device.c
@@ -0,0 +1,376 @@
+/* arch/arm/mach-msm/smd_rpcrouter_device.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2009 QUALCOMM Incorporated.
+ * Author: San Mehat <san@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/string.h>
+#include <linux/errno.h>
+#include <linux/cdev.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/platform_device.h>
+#include <linux/msm_rpcrouter.h>
+
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+#include "smd_rpcrouter.h"
+
+#define SAFETY_MEM_SIZE 65536
+
+/* Next minor # available for a remote server */
+static int next_minor = 1;
+
+struct class *msm_rpcrouter_class;
+dev_t msm_rpcrouter_devno;
+
+static struct cdev rpcrouter_cdev;
+static struct device *rpcrouter_device;
+
+static int rpcrouter_open(struct inode *inode, struct file *filp)
+{
+	int rc;
+	struct msm_rpc_endpoint *ept;
+
+	rc = nonseekable_open(inode, filp);
+	if (rc < 0)
+		return rc;
+
+	ept = msm_rpcrouter_create_local_endpoint(inode->i_rdev);
+	if (!ept)
+		return -ENOMEM;
+
+	filp->private_data = ept;
+	return 0;
+}
+
+static int rpcrouter_release(struct inode *inode, struct file *filp)
+{
+	struct msm_rpc_endpoint *ept;
+	ept = (struct msm_rpc_endpoint *) filp->private_data;
+
+	return msm_rpcrouter_destroy_local_endpoint(ept);
+}
+
+static ssize_t rpcrouter_read(struct file *filp, char __user *buf,
+			      size_t count, loff_t *ppos)
+{
+	struct msm_rpc_endpoint *ept;
+	struct rr_fragment *frag, *next;
+	int rc;
+
+	ept = (struct msm_rpc_endpoint *) filp->private_data;
+
+	rc = __msm_rpc_read(ept, &frag, count, -1);
+	if (rc < 0)
+		return rc;
+
+	count = rc;
+
+	while (frag != NULL) {
+		if (copy_to_user(buf, frag->data, frag->length)) {
+			printk(KERN_ERR
+			       "rpcrouter: could not copy all read data to user!\n");
+			rc = -EFAULT;
+		}
+		buf += frag->length;
+		next = frag->next;
+		kfree(frag);
+		frag = next;
+	}
+
+	return rc;
+}
+
+static ssize_t rpcrouter_write(struct file *filp, const char __user *buf,
+				size_t count, loff_t *ppos)
+{
+	struct msm_rpc_endpoint	*ept;
+	int rc = 0;
+	void *k_buffer;
+
+	ept = (struct msm_rpc_endpoint *) filp->private_data;
+
+	/* A check for safety, this seems non-standard */
+	if (count > SAFETY_MEM_SIZE)
+		return -EINVAL;
+
+	k_buffer = kmalloc(count, GFP_KERNEL);
+	if (!k_buffer)
+		return -ENOMEM;
+
+	if (copy_from_user(k_buffer, buf, count)) {
+		rc = -EFAULT;
+		goto write_out_free;
+	}
+
+	rc = msm_rpc_write(ept, k_buffer, count);
+	if (rc < 0)
+		goto write_out_free;
+
+	rc = count;
+write_out_free:
+	kfree(k_buffer);
+	return rc;
+}
+
+static unsigned int rpcrouter_poll(struct file *filp,
+				   struct poll_table_struct *wait)
+{
+	struct msm_rpc_endpoint *ept;
+	unsigned mask = 0;
+	ept = (struct msm_rpc_endpoint *) filp->private_data;
+
+	/* If there's data already in the read queue, return POLLIN.
+	 * Else, wait for the requested amount of time, and check again.
+	 */
+
+	if (!list_empty(&ept->read_q))
+		mask |= POLLIN;
+
+	if (!mask) {
+		poll_wait(filp, &ept->wait_q, wait);
+		if (!list_empty(&ept->read_q))
+			mask |= POLLIN;
+	}
+
+	return mask;
+}
+
+static long rpcrouter_ioctl(struct file *filp, unsigned int cmd,
+			    unsigned long arg)
+{
+	struct msm_rpc_endpoint *ept;
+	struct rpcrouter_ioctl_server_args server_args;
+	int rc = 0;
+	uint32_t n;
+
+	ept = (struct msm_rpc_endpoint *) filp->private_data;
+	switch (cmd) {
+
+	case RPC_ROUTER_IOCTL_GET_VERSION:
+		n = RPC_ROUTER_VERSION_V1;
+		rc = put_user(n, (unsigned int *) arg);
+		break;
+
+	case RPC_ROUTER_IOCTL_GET_MTU:
+		/* the pacmark word reduces the actual payload
+		 * possible per message
+		 */
+		n = RPCROUTER_MSGSIZE_MAX - sizeof(uint32_t);
+		rc = put_user(n, (unsigned int *) arg);
+		break;
+
+	case RPC_ROUTER_IOCTL_REGISTER_SERVER:
+		rc = copy_from_user(&server_args, (void *) arg,
+				    sizeof(server_args));
+		if (rc < 0)
+			break;
+		msm_rpc_register_server(ept,
+					server_args.prog,
+					server_args.vers);
+		break;
+
+	case RPC_ROUTER_IOCTL_UNREGISTER_SERVER:
+		rc = copy_from_user(&server_args, (void *) arg,
+				    sizeof(server_args));
+		if (rc < 0)
+			break;
+
+		msm_rpc_unregister_server(ept,
+					  server_args.prog,
+					  server_args.vers);
+		break;
+
+	case RPC_ROUTER_IOCTL_GET_MINOR_VERSION:
+		n = MSM_RPC_GET_MINOR(msm_rpc_get_vers(ept));
+		rc = put_user(n, (unsigned int *)arg);
+		break;
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	return rc;
+}
+
+static struct file_operations rpcrouter_server_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = rpcrouter_open,
+	.release = rpcrouter_release,
+	.read	 = rpcrouter_read,
+	.write	 = rpcrouter_write,
+	.poll    = rpcrouter_poll,
+	.unlocked_ioctl	 = rpcrouter_ioctl,
+};
+
+static struct file_operations rpcrouter_router_fops = {
+	.owner	 = THIS_MODULE,
+	.open	 = rpcrouter_open,
+	.release = rpcrouter_release,
+	.read	 = rpcrouter_read,
+	.write	 = rpcrouter_write,
+	.poll    = rpcrouter_poll,
+	.unlocked_ioctl = rpcrouter_ioctl,
+};
+
+int msm_rpcrouter_create_server_cdev(struct rr_server *server)
+{
+	int rc;
+	uint32_t dev_vers;
+
+	if (next_minor == RPCROUTER_MAX_REMOTE_SERVERS) {
+		printk(KERN_ERR
+		       "rpcrouter: Minor numbers exhausted - Increase "
+		       "RPCROUTER_MAX_REMOTE_SERVERS\n");
+		return -ENOBUFS;
+	}
+
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+	/* Servers with bit 31 set are remote msm servers with hashkey version.
+	 * Servers with bit 31 not set are remote msm servers with
+	 * backwards compatible version type in which case the minor number
+	 * (lower 16 bits) is set to zero.
+	 *
+	 */
+	if ((server->vers & RPC_VERSION_MODE_MASK))
+		dev_vers = server->vers;
+	else
+		dev_vers = server->vers & RPC_VERSION_MAJOR_MASK;
+#else
+	dev_vers = server->vers;
+#endif
+
+	server->device_number =
+		MKDEV(MAJOR(msm_rpcrouter_devno), next_minor++);
+
+	server->device =
+		device_create(msm_rpcrouter_class, rpcrouter_device,
+			      server->device_number, NULL, "%.8x:%.8x",
+			      server->prog, dev_vers);
+	if (IS_ERR(server->device)) {
+		printk(KERN_ERR
+		       "rpcrouter: Unable to create device (%ld)\n",
+		       PTR_ERR(server->device));
+		return PTR_ERR(server->device);;
+	}
+
+	cdev_init(&server->cdev, &rpcrouter_server_fops);
+	server->cdev.owner = THIS_MODULE;
+
+	rc = cdev_add(&server->cdev, server->device_number, 1);
+	if (rc < 0) {
+		printk(KERN_ERR
+		       "rpcrouter: Unable to add chrdev (%d)\n", rc);
+		device_destroy(msm_rpcrouter_class, server->device_number);
+		return rc;
+	}
+	return 0;
+}
+
+/* for backward compatible version type (31st bit cleared)
+ * clearing minor number (lower 16 bits) in device name
+ * is neccessary for driver binding
+ */
+int msm_rpcrouter_create_server_pdev(struct rr_server *server)
+{
+	sprintf(server->pdev_name, "rs%.8x:%.8x",
+		server->prog,
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+		(server->vers & RPC_VERSION_MODE_MASK) ? server->vers :
+		(server->vers & RPC_VERSION_MAJOR_MASK));
+#else
+		server->vers);
+#endif
+
+	server->p_device.base.id = -1;
+	server->p_device.base.name = server->pdev_name;
+
+	server->p_device.prog = server->prog;
+	server->p_device.vers = server->vers;
+
+	platform_device_register(&server->p_device.base);
+	return 0;
+}
+
+int msm_rpcrouter_init_devices(void)
+{
+	int rc;
+	int major;
+
+	/* Create the device nodes */
+	msm_rpcrouter_class = class_create(THIS_MODULE, "oncrpc");
+	if (IS_ERR(msm_rpcrouter_class)) {
+		rc = -ENOMEM;
+		printk(KERN_ERR
+		       "rpcrouter: failed to create oncrpc class\n");
+		goto fail;
+	}
+
+	rc = alloc_chrdev_region(&msm_rpcrouter_devno, 0,
+				 RPCROUTER_MAX_REMOTE_SERVERS + 1,
+				 "oncrpc");
+	if (rc < 0) {
+		printk(KERN_ERR
+		       "rpcrouter: Failed to alloc chardev region (%d)\n", rc);
+		goto fail_destroy_class;
+	}
+
+	major = MAJOR(msm_rpcrouter_devno);
+	rpcrouter_device = device_create(msm_rpcrouter_class, NULL,
+					 msm_rpcrouter_devno, NULL, "%.8x:%d",
+					 0, 0);
+	if (IS_ERR(rpcrouter_device)) {
+		rc = -ENOMEM;
+		goto fail_unregister_cdev_region;
+	}
+
+	cdev_init(&rpcrouter_cdev, &rpcrouter_router_fops);
+	rpcrouter_cdev.owner = THIS_MODULE;
+
+	rc = cdev_add(&rpcrouter_cdev, msm_rpcrouter_devno, 1);
+	if (rc < 0)
+		goto fail_destroy_device;
+
+	return 0;
+
+fail_destroy_device:
+	device_destroy(msm_rpcrouter_class, msm_rpcrouter_devno);
+fail_unregister_cdev_region:
+	unregister_chrdev_region(msm_rpcrouter_devno,
+				 RPCROUTER_MAX_REMOTE_SERVERS + 1);
+fail_destroy_class:
+	class_destroy(msm_rpcrouter_class);
+fail:
+	return rc;
+}
+
+void msm_rpcrouter_exit_devices(void)
+{
+	cdev_del(&rpcrouter_cdev);
+	device_destroy(msm_rpcrouter_class, msm_rpcrouter_devno);
+	unregister_chrdev_region(msm_rpcrouter_devno,
+				 RPCROUTER_MAX_REMOTE_SERVERS + 1);
+	class_destroy(msm_rpcrouter_class);
+}
+
diff --git a/drivers/staging/dream/smd/smd_rpcrouter_servers.c b/drivers/staging/dream/smd/smd_rpcrouter_servers.c
new file mode 100644
index 0000000..2597bbb
--- /dev/null
+++ b/drivers/staging/dream/smd/smd_rpcrouter_servers.c
@@ -0,0 +1,229 @@
+/* arch/arm/mach-msm/rpc_servers.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Iliyan Malchev <ibm@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/string.h>
+#include <linux/errno.h>
+#include <linux/cdev.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/kthread.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/wakelock.h>
+
+#include <linux/msm_rpcrouter.h>
+#include <linux/uaccess.h>
+
+#include <mach/msm_rpcrouter.h>
+#include "smd_rpcrouter.h"
+
+static struct msm_rpc_endpoint *endpoint;
+
+#define FLAG_REGISTERED 0x0001
+
+static LIST_HEAD(rpc_server_list);
+static DEFINE_MUTEX(rpc_server_list_lock);
+static int rpc_servers_active;
+static struct wake_lock rpc_servers_wake_lock;
+
+static void rpc_server_register(struct msm_rpc_server *server)
+{
+	int rc;
+	rc = msm_rpc_register_server(endpoint, server->prog, server->vers);
+	if (rc < 0)
+		printk(KERN_ERR "[rpcserver] error registering %p @ %08x:%d\n",
+		       server, server->prog, server->vers);
+}
+
+static struct msm_rpc_server *rpc_server_find(uint32_t prog, uint32_t vers)
+{
+	struct msm_rpc_server *server;
+
+	mutex_lock(&rpc_server_list_lock);
+	list_for_each_entry(server, &rpc_server_list, list) {
+		if ((server->prog == prog) &&
+#if CONFIG_MSM_AMSS_VERSION >= 6350
+		    msm_rpc_is_compatible_version(server->vers, vers)) {
+#else
+		    server->vers == vers) {
+#endif
+			mutex_unlock(&rpc_server_list_lock);
+			return server;
+		}
+	}
+	mutex_unlock(&rpc_server_list_lock);
+	return NULL;
+}
+
+static void rpc_server_register_all(void)
+{
+	struct msm_rpc_server *server;
+
+	mutex_lock(&rpc_server_list_lock);
+	list_for_each_entry(server, &rpc_server_list, list) {
+		if (!(server->flags & FLAG_REGISTERED)) {
+			rpc_server_register(server);
+			server->flags |= FLAG_REGISTERED;
+		}
+	}
+	mutex_unlock(&rpc_server_list_lock);
+}
+
+int msm_rpc_create_server(struct msm_rpc_server *server)
+{
+	/* make sure we're in a sane state first */
+	server->flags = 0;
+	INIT_LIST_HEAD(&server->list);
+
+	mutex_lock(&rpc_server_list_lock);
+	list_add(&server->list, &rpc_server_list);
+	if (rpc_servers_active) {
+		rpc_server_register(server);
+		server->flags |= FLAG_REGISTERED;
+	}
+	mutex_unlock(&rpc_server_list_lock);
+
+	return 0;
+}
+
+static int rpc_send_accepted_void_reply(struct msm_rpc_endpoint *client,
+					uint32_t xid, uint32_t accept_status)
+{
+	int rc = 0;
+	uint8_t reply_buf[sizeof(struct rpc_reply_hdr)];
+	struct rpc_reply_hdr *reply = (struct rpc_reply_hdr *)reply_buf;
+
+	reply->xid = cpu_to_be32(xid);
+	reply->type = cpu_to_be32(1); /* reply */
+	reply->reply_stat = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED);
+
+	reply->data.acc_hdr.accept_stat = cpu_to_be32(accept_status);
+	reply->data.acc_hdr.verf_flavor = 0;
+	reply->data.acc_hdr.verf_length = 0;
+
+	rc = msm_rpc_write(client, reply_buf, sizeof(reply_buf));
+	if (rc < 0)
+		printk(KERN_ERR
+		       "%s: could not write response: %d\n",
+		       __FUNCTION__, rc);
+
+	return rc;
+}
+
+static int rpc_servers_thread(void *data)
+{
+	void *buffer;
+	struct rpc_request_hdr *req;
+	struct msm_rpc_server *server;
+	int rc;
+
+	for (;;) {
+		wake_unlock(&rpc_servers_wake_lock);
+		rc = wait_event_interruptible(endpoint->wait_q,
+						!list_empty(&endpoint->read_q));
+		wake_lock(&rpc_servers_wake_lock);
+		rc = msm_rpc_read(endpoint, &buffer, -1, -1);
+		if (rc < 0) {
+			printk(KERN_ERR "%s: could not read: %d\n",
+			       __FUNCTION__, rc);
+			break;
+		}
+		req = (struct rpc_request_hdr *)buffer;
+
+		req->type = be32_to_cpu(req->type);
+		req->xid = be32_to_cpu(req->xid);
+		req->rpc_vers = be32_to_cpu(req->rpc_vers);
+		req->prog = be32_to_cpu(req->prog);
+		req->vers = be32_to_cpu(req->vers);
+		req->procedure = be32_to_cpu(req->procedure);
+
+		server = rpc_server_find(req->prog, req->vers);
+
+		if (req->rpc_vers != 2)
+			continue;
+		if (req->type != 0)
+			continue;
+		if (!server) {
+			rpc_send_accepted_void_reply(
+				endpoint, req->xid,
+				RPC_ACCEPTSTAT_PROG_UNAVAIL);
+			continue;
+		}
+
+		rc = server->rpc_call(server, req, rc);
+
+		switch (rc) {
+		case 0:
+			rpc_send_accepted_void_reply(
+				endpoint, req->xid,
+				RPC_ACCEPTSTAT_SUCCESS);
+			break;
+		default:
+			rpc_send_accepted_void_reply(
+				endpoint, req->xid,
+				RPC_ACCEPTSTAT_PROG_UNAVAIL);
+			break;
+		}
+
+		kfree(buffer);
+	}
+
+	do_exit(0);
+}
+
+static int rpcservers_probe(struct platform_device *pdev)
+{
+	struct task_struct *server_thread;
+
+	endpoint = msm_rpc_open();
+	if (IS_ERR(endpoint))
+		return PTR_ERR(endpoint);
+
+	/* we're online -- register any servers installed beforehand */
+	rpc_servers_active = 1;
+	rpc_server_register_all();
+
+	/* start the kernel thread */
+	server_thread = kthread_run(rpc_servers_thread, NULL, "krpcserversd");
+	if (IS_ERR(server_thread))
+		return PTR_ERR(server_thread);
+
+	return 0;
+}
+
+static struct platform_driver rpcservers_driver = {
+	.probe	= rpcservers_probe,
+	.driver	= {
+		.name	= "oncrpc_router",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init rpc_servers_init(void)
+{
+	wake_lock_init(&rpc_servers_wake_lock, WAKE_LOCK_SUSPEND, "rpc_server");
+	return platform_driver_register(&rpcservers_driver);
+}
+
+module_init(rpc_servers_init);
+
+MODULE_DESCRIPTION("MSM RPC Servers");
+MODULE_AUTHOR("Iliyan Malchev <ibm@android.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/dream/smd/smd_tty.c b/drivers/staging/dream/smd/smd_tty.c
new file mode 100644
index 0000000..2edd9d1
--- /dev/null
+++ b/drivers/staging/dream/smd/smd_tty.c
@@ -0,0 +1,213 @@
+/* arch/arm/mach-msm/smd_tty.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/wakelock.h>
+
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+
+#include <mach/msm_smd.h>
+
+#define MAX_SMD_TTYS 32
+
+static DEFINE_MUTEX(smd_tty_lock);
+
+struct smd_tty_info {
+	smd_channel_t *ch;
+	struct tty_struct *tty;
+	struct wake_lock wake_lock;
+	int open_count;
+};
+
+static struct smd_tty_info smd_tty[MAX_SMD_TTYS];
+
+
+static void smd_tty_notify(void *priv, unsigned event)
+{
+	unsigned char *ptr;
+	int avail;
+	struct smd_tty_info *info = priv;
+	struct tty_struct *tty = info->tty;
+
+	if (!tty)
+		return;
+
+	if (event != SMD_EVENT_DATA)
+		return;
+
+	for (;;) {
+		if (test_bit(TTY_THROTTLED, &tty->flags)) break;
+		avail = smd_read_avail(info->ch);
+		if (avail == 0) break;
+
+		avail = tty_prepare_flip_string(tty, &ptr, avail);
+
+		if (smd_read(info->ch, ptr, avail) != avail) {
+			/* shouldn't be possible since we're in interrupt
+			** context here and nobody else could 'steal' our
+			** characters.
+			*/
+			printk(KERN_ERR "OOPS - smd_tty_buffer mismatch?!");
+		}
+
+		wake_lock_timeout(&info->wake_lock, HZ / 2);
+		tty_flip_buffer_push(tty);
+	}
+
+	/* XXX only when writable and necessary */
+	tty_wakeup(tty);
+}
+
+static int smd_tty_open(struct tty_struct *tty, struct file *f)
+{
+	int res = 0;
+	int n = tty->index;
+	struct smd_tty_info *info;
+	const char *name;
+
+	if (n == 0) {
+		name = "SMD_DS";
+	} else if (n == 27) {
+		name = "SMD_GPSNMEA";
+	} else {
+		return -ENODEV;
+	}
+
+	info = smd_tty + n;
+
+	mutex_lock(&smd_tty_lock);
+	wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, name);
+	tty->driver_data = info;
+
+	if (info->open_count++ == 0) {
+		info->tty = tty;
+		if (info->ch) {
+			smd_kick(info->ch);
+		} else {
+			res = smd_open(name, &info->ch, info, smd_tty_notify);
+		}
+	}
+	mutex_unlock(&smd_tty_lock);
+
+	return res;
+}
+
+static void smd_tty_close(struct tty_struct *tty, struct file *f)
+{
+	struct smd_tty_info *info = tty->driver_data;
+
+	if (info == 0)
+		return;
+
+	mutex_lock(&smd_tty_lock);
+	if (--info->open_count == 0) {
+		info->tty = 0;
+		tty->driver_data = 0;
+		wake_lock_destroy(&info->wake_lock);
+		if (info->ch) {
+			smd_close(info->ch);
+			info->ch = 0;
+		}
+	}
+	mutex_unlock(&smd_tty_lock);
+}
+
+static int smd_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
+{
+	struct smd_tty_info *info = tty->driver_data;
+	int avail;
+
+	/* if we're writing to a packet channel we will
+	** never be able to write more data than there
+	** is currently space for
+	*/
+	avail = smd_write_avail(info->ch);
+	if (len > avail)
+		len = avail;
+
+	return smd_write(info->ch, buf, len);
+}
+
+static int smd_tty_write_room(struct tty_struct *tty)
+{
+	struct smd_tty_info *info = tty->driver_data;
+	return smd_write_avail(info->ch);
+}
+
+static int smd_tty_chars_in_buffer(struct tty_struct *tty)
+{
+	struct smd_tty_info *info = tty->driver_data;
+	return smd_read_avail(info->ch);
+}
+
+static void smd_tty_unthrottle(struct tty_struct *tty)
+{
+	struct smd_tty_info *info = tty->driver_data;
+	smd_kick(info->ch);
+}
+
+static struct tty_operations smd_tty_ops = {
+	.open = smd_tty_open,
+	.close = smd_tty_close,
+	.write = smd_tty_write,
+	.write_room = smd_tty_write_room,
+	.chars_in_buffer = smd_tty_chars_in_buffer,
+	.unthrottle = smd_tty_unthrottle,
+};
+
+static struct tty_driver *smd_tty_driver;
+
+static int __init smd_tty_init(void)
+{
+	int ret;
+
+	smd_tty_driver = alloc_tty_driver(MAX_SMD_TTYS);
+	if (smd_tty_driver == 0)
+		return -ENOMEM;
+
+	smd_tty_driver->owner = THIS_MODULE;
+	smd_tty_driver->driver_name = "smd_tty_driver";
+	smd_tty_driver->name = "smd";
+	smd_tty_driver->major = 0;
+	smd_tty_driver->minor_start = 0;
+	smd_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+	smd_tty_driver->subtype = SERIAL_TYPE_NORMAL;
+	smd_tty_driver->init_termios = tty_std_termios;
+	smd_tty_driver->init_termios.c_iflag = 0;
+	smd_tty_driver->init_termios.c_oflag = 0;
+	smd_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD;
+	smd_tty_driver->init_termios.c_lflag = 0;
+	smd_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS |
+		TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
+	tty_set_operations(smd_tty_driver, &smd_tty_ops);
+
+	ret = tty_register_driver(smd_tty_driver);
+	if (ret) return ret;
+
+	/* this should be dynamic */
+	tty_register_device(smd_tty_driver, 0, 0);
+	tty_register_device(smd_tty_driver, 27, 0);
+
+	return 0;
+}
+
+module_init(smd_tty_init);
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.c b/drivers/staging/dream/synaptics_i2c_rmi.c
new file mode 100644
index 0000000..ae696d3
--- /dev/null
+++ b/drivers/staging/dream/synaptics_i2c_rmi.c
@@ -0,0 +1,658 @@
+/*
+ * Support for synaptics touchscreen.
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Arve HjÃ¸nnevÃ¥g <arve@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * http://www.synaptics.com/sites/default/files/511_000099_01F.pdf
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/hrtimer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include "synaptics_i2c_rmi.h"
+
+static struct workqueue_struct *synaptics_wq;
+
+struct synaptics_ts_data {
+	u16 addr;
+	struct i2c_client *client;
+	struct input_dev *input_dev;
+	int use_irq;
+	struct hrtimer timer;
+	struct work_struct  work;
+	u16 max[2];
+	int snap_state[2][2];
+	int snap_down_on[2];
+	int snap_down_off[2];
+	int snap_up_on[2];
+	int snap_up_off[2];
+	int snap_down[2];
+	int snap_up[2];
+	u32 flags;
+	int (*power)(int on);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct early_suspend early_suspend;
+#endif
+};
+
+static int i2c_set(struct synaptics_ts_data *ts, u8 reg, u8 val, char *msg)
+{
+	int ret = i2c_smbus_write_byte_data(ts->client, reg, val);
+	if (ret < 0)
+		pr_err("i2c_smbus_write_byte_data failed (%s)\n", msg);
+	return ret;
+}
+
+static int i2c_read(struct synaptics_ts_data *ts, u8 reg, char *msg)
+{
+	int ret = i2c_smbus_read_byte_data(ts->client, reg);
+	if (ret < 0)
+		pr_err("i2c_smbus_read_byte_data failed (%s)\n", msg);
+	return ret;
+}
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void synaptics_ts_early_suspend(struct early_suspend *h);
+static void synaptics_ts_late_resume(struct early_suspend *h);
+#endif
+
+static int synaptics_init_panel(struct synaptics_ts_data *ts)
+{
+	int ret;
+
+	ret = i2c_set(ts, 0xff, 0x10, "set page select");
+	if (ret == 0)
+		ret = i2c_set(ts, 0x41, 0x04, "set No Clip Z");
+
+	ret = i2c_set(ts, 0xff, 0x04, "fallback page select");
+	ret = i2c_set(ts, 0xf0, 0x81, "select 80 reports per second");
+	return ret;
+}
+
+static void decode_report(struct synaptics_ts_data *ts, u8 *buf)
+{
+/*
+ * This sensor sends two 6-byte absolute finger reports, an optional
+ * 2-byte relative report followed by a status byte. This function
+ * reads the two finger reports and transforms the coordinates
+ * according the platform data so they can be aligned with the lcd
+ * behind the touchscreen. Typically we flip the y-axis since the
+ * sensor uses the bottom left corner as the origin, but if the sensor
+ * is mounted upside down the platform data will request that the
+ * x-axis should be flipped instead. The snap to inactive edge border
+ * are used to allow tapping the edges of the screen on the G1. The
+ * active area of the touchscreen is smaller than the lcd. When the
+ * finger gets close the edge of the screen we snap it to the
+ * edge. This allows ui elements at the edge of the screen to be hit,
+ * and it prevents hitting ui elements that are not at the edge of the
+ * screen when the finger is touching the edge.
+ */
+	int pos[2][2];
+	int f, a;
+	int base = 2;
+	int z = buf[1];
+	int w = buf[0] >> 4;
+	int finger = buf[0] & 7;
+	int finger2_pressed;
+
+	for (f = 0; f < 2; f++) {
+		u32 flip_flag = SYNAPTICS_FLIP_X;
+		for (a = 0; a < 2; a++) {
+			int p = buf[base + 1];
+			p |= (u16)(buf[base] & 0x1f) << 8;
+			if (ts->flags & flip_flag)
+				p = ts->max[a] - p;
+			if (ts->flags & SYNAPTICS_SNAP_TO_INACTIVE_EDGE) {
+				if (ts->snap_state[f][a]) {
+					if (p <= ts->snap_down_off[a])
+						p = ts->snap_down[a];
+					else if (p >= ts->snap_up_off[a])
+						p = ts->snap_up[a];
+					else
+						ts->snap_state[f][a] = 0;
+				} else {
+					if (p <= ts->snap_down_on[a]) {
+						p = ts->snap_down[a];
+						ts->snap_state[f][a] = 1;
+					} else if (p >= ts->snap_up_on[a]) {
+						p = ts->snap_up[a];
+						ts->snap_state[f][a] = 1;
+					}
+				}
+			}
+			pos[f][a] = p;
+			base += 2;
+			flip_flag <<= 1;
+		}
+		base += 2;
+		if (ts->flags & SYNAPTICS_SWAP_XY)
+			swap(pos[f][0], pos[f][1]);
+	}
+	if (z) {
+		input_report_abs(ts->input_dev, ABS_X, pos[0][0]);
+		input_report_abs(ts->input_dev, ABS_Y, pos[0][1]);
+	}
+	input_report_abs(ts->input_dev, ABS_PRESSURE, z);
+	input_report_abs(ts->input_dev, ABS_TOOL_WIDTH, w);
+	input_report_key(ts->input_dev, BTN_TOUCH, finger);
+	finger2_pressed = finger > 1 && finger != 7;
+	input_report_key(ts->input_dev, BTN_2, finger2_pressed);
+	if (finger2_pressed) {
+		input_report_abs(ts->input_dev, ABS_HAT0X, pos[1][0]);
+		input_report_abs(ts->input_dev, ABS_HAT0Y, pos[1][1]);
+	}
+	input_sync(ts->input_dev);
+}
+
+static void synaptics_ts_work_func(struct work_struct *work)
+{
+	int i;
+	int ret;
+	int bad_data = 0;
+	struct i2c_msg msg[2];
+	u8 start_reg = 0;
+	u8 buf[15];
+	struct synaptics_ts_data *ts =
+		container_of(work, struct synaptics_ts_data, work);
+
+	msg[0].addr = ts->client->addr;
+	msg[0].flags = 0;
+	msg[0].len = 1;
+	msg[0].buf = &start_reg;
+	msg[1].addr = ts->client->addr;
+	msg[1].flags = I2C_M_RD;
+	msg[1].len = sizeof(buf);
+	msg[1].buf = buf;
+
+	for (i = 0; i < ((ts->use_irq && !bad_data) ? 1 : 10); i++) {
+		ret = i2c_transfer(ts->client->adapter, msg, 2);
+		if (ret < 0) {
+			pr_err("ts_work: i2c_transfer failed\n");
+			bad_data = 1;
+			continue;
+		}
+		if ((buf[14] & 0xc0) != 0x40) {
+			pr_warning("synaptics_ts_work_func:"
+			       " bad read %x %x %x %x %x %x %x %x %x"
+			       " %x %x %x %x %x %x, ret %d\n",
+			       buf[0], buf[1], buf[2], buf[3],
+			       buf[4], buf[5], buf[6], buf[7],
+			       buf[8], buf[9], buf[10], buf[11],
+			       buf[12], buf[13], buf[14], ret);
+			if (bad_data)
+				synaptics_init_panel(ts);
+			bad_data = 1;
+			continue;
+		}
+		bad_data = 0;
+		if ((buf[14] & 1) == 0)
+			break;
+
+		decode_report(ts, buf);
+	}
+	if (ts->use_irq)
+		enable_irq(ts->client->irq);
+}
+
+static enum hrtimer_restart synaptics_ts_timer_func(struct hrtimer *timer)
+{
+	struct synaptics_ts_data *ts =
+		container_of(timer, struct synaptics_ts_data, timer);
+
+	queue_work(synaptics_wq, &ts->work);
+
+	hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL);
+	return HRTIMER_NORESTART;
+}
+
+static irqreturn_t synaptics_ts_irq_handler(int irq, void *dev_id)
+{
+	struct synaptics_ts_data *ts = dev_id;
+
+	disable_irq_nosync(ts->client->irq);
+	queue_work(synaptics_wq, &ts->work);
+	return IRQ_HANDLED;
+}
+
+static int detect(struct synaptics_ts_data *ts, u32 *panel_version)
+{
+	int ret;
+	int retry = 10;
+
+	ret = i2c_set(ts, 0xf4, 0x01, "reset device");
+
+	while (retry-- > 0) {
+		ret = i2c_smbus_read_byte_data(ts->client, 0xe4);
+		if (ret >= 0)
+			break;
+		msleep(100);
+	}
+	if (ret < 0) {
+		pr_err("i2c_smbus_read_byte_data failed\n");
+		return ret;
+	}
+
+	*panel_version = ret << 8;
+	ret = i2c_read(ts, 0xe5, "product minor");
+	if (ret < 0)
+		return ret;
+	*panel_version |= ret;
+
+	ret = i2c_read(ts, 0xe3, "property");
+	if (ret < 0)
+		return ret;
+
+	pr_info("synaptics: version %x, product property %x\n",
+		*panel_version, ret);
+	return 0;
+}
+
+static void compute_areas(struct synaptics_ts_data *ts,
+			  struct synaptics_i2c_rmi_platform_data *pdata,
+			  u16 max_x, u16 max_y)
+{
+	int inactive_area_left;
+	int inactive_area_right;
+	int inactive_area_top;
+	int inactive_area_bottom;
+	int snap_left_on;
+	int snap_left_off;
+	int snap_right_on;
+	int snap_right_off;
+	int snap_top_on;
+	int snap_top_off;
+	int snap_bottom_on;
+	int snap_bottom_off;
+	int fuzz_x;
+	int fuzz_y;
+	int fuzz_p;
+	int fuzz_w;
+	int swapped = !!(ts->flags & SYNAPTICS_SWAP_XY);
+
+	inactive_area_left = pdata->inactive_left;
+	inactive_area_right = pdata->inactive_right;
+	inactive_area_top = pdata->inactive_top;
+	inactive_area_bottom = pdata->inactive_bottom;
+	snap_left_on = pdata->snap_left_on;
+	snap_left_off = pdata->snap_left_off;
+	snap_right_on = pdata->snap_right_on;
+	snap_right_off = pdata->snap_right_off;
+	snap_top_on = pdata->snap_top_on;
+	snap_top_off = pdata->snap_top_off;
+	snap_bottom_on = pdata->snap_bottom_on;
+	snap_bottom_off = pdata->snap_bottom_off;
+	fuzz_x = pdata->fuzz_x;
+	fuzz_y = pdata->fuzz_y;
+	fuzz_p = pdata->fuzz_p;
+	fuzz_w = pdata->fuzz_w;
+
+	inactive_area_left = inactive_area_left * max_x / 0x10000;
+	inactive_area_right = inactive_area_right * max_x / 0x10000;
+	inactive_area_top = inactive_area_top * max_y / 0x10000;
+	inactive_area_bottom = inactive_area_bottom * max_y / 0x10000;
+	snap_left_on = snap_left_on * max_x / 0x10000;
+	snap_left_off = snap_left_off * max_x / 0x10000;
+	snap_right_on = snap_right_on * max_x / 0x10000;
+	snap_right_off = snap_right_off * max_x / 0x10000;
+	snap_top_on = snap_top_on * max_y / 0x10000;
+	snap_top_off = snap_top_off * max_y / 0x10000;
+	snap_bottom_on = snap_bottom_on * max_y / 0x10000;
+	snap_bottom_off = snap_bottom_off * max_y / 0x10000;
+	fuzz_x = fuzz_x * max_x / 0x10000;
+	fuzz_y = fuzz_y * max_y / 0x10000;
+
+
+	ts->snap_down[swapped] = -inactive_area_left;
+	ts->snap_up[swapped] = max_x + inactive_area_right;
+	ts->snap_down[!swapped] = -inactive_area_top;
+	ts->snap_up[!swapped] = max_y + inactive_area_bottom;
+	ts->snap_down_on[swapped] = snap_left_on;
+	ts->snap_down_off[swapped] = snap_left_off;
+	ts->snap_up_on[swapped] = max_x - snap_right_on;
+	ts->snap_up_off[swapped] = max_x - snap_right_off;
+	ts->snap_down_on[!swapped] = snap_top_on;
+	ts->snap_down_off[!swapped] = snap_top_off;
+	ts->snap_up_on[!swapped] = max_y - snap_bottom_on;
+	ts->snap_up_off[!swapped] = max_y - snap_bottom_off;
+	pr_info("synaptics_ts_probe: max_x %d, max_y %d\n", max_x, max_y);
+	pr_info("synaptics_ts_probe: inactive_x %d %d, inactive_y %d %d\n",
+	       inactive_area_left, inactive_area_right,
+	       inactive_area_top, inactive_area_bottom);
+	pr_info("synaptics_ts_probe: snap_x %d-%d %d-%d, snap_y %d-%d %d-%d\n",
+	       snap_left_on, snap_left_off, snap_right_on, snap_right_off,
+	       snap_top_on, snap_top_off, snap_bottom_on, snap_bottom_off);
+
+	input_set_abs_params(ts->input_dev, ABS_X,
+			     -inactive_area_left, max_x + inactive_area_right,
+			     fuzz_x, 0);
+	input_set_abs_params(ts->input_dev, ABS_Y,
+			     -inactive_area_top, max_y + inactive_area_bottom,
+			     fuzz_y, 0);
+	input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 255, fuzz_p, 0);
+	input_set_abs_params(ts->input_dev, ABS_TOOL_WIDTH, 0, 15, fuzz_w, 0);
+	input_set_abs_params(ts->input_dev, ABS_HAT0X, -inactive_area_left,
+			     max_x + inactive_area_right, fuzz_x, 0);
+	input_set_abs_params(ts->input_dev, ABS_HAT0Y, -inactive_area_top,
+			     max_y + inactive_area_bottom, fuzz_y, 0);
+}
+
+static struct synaptics_i2c_rmi_platform_data fake_pdata;
+
+static int __devinit synaptics_ts_probe(
+	struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct synaptics_ts_data *ts;
+	u8 buf0[4];
+	u8 buf1[8];
+	struct i2c_msg msg[2];
+	int ret = 0;
+	struct synaptics_i2c_rmi_platform_data *pdata;
+	u32 panel_version = 0;
+	u16 max_x, max_y;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		pr_err("synaptics_ts_probe: need I2C_FUNC_I2C\n");
+		ret = -ENODEV;
+		goto err_check_functionality_failed;
+	}
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
+		pr_err("synaptics_ts_probe: need I2C_FUNC_SMBUS_WORD_DATA\n");
+		ret = -ENODEV;
+		goto err_check_functionality_failed;
+	}
+
+	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
+	if (ts == NULL) {
+		ret = -ENOMEM;
+		goto err_alloc_data_failed;
+	}
+	INIT_WORK(&ts->work, synaptics_ts_work_func);
+	ts->client = client;
+	i2c_set_clientdata(client, ts);
+	pdata = client->dev.platform_data;
+	if (pdata)
+		ts->power = pdata->power;
+	else
+		pdata = &fake_pdata;
+
+	if (ts->power) {
+		ret = ts->power(1);
+		if (ret < 0) {
+			pr_err("synaptics_ts_probe power on failed\n");
+			goto err_power_failed;
+		}
+	}
+
+	ret = detect(ts, &panel_version);
+	if (ret)
+		goto err_detect_failed;
+
+	while (pdata->version > panel_version)
+		pdata++;
+	ts->flags = pdata->flags;
+
+	ret = i2c_read(ts, 0xf0, "device control");
+	if (ret < 0)
+		goto err_detect_failed;
+	pr_info("synaptics: device control %x\n", ret);
+
+	ret = i2c_read(ts, 0xf1, "interrupt enable");
+	if (ret < 0)
+		goto err_detect_failed;
+	pr_info("synaptics_ts_probe: interrupt enable %x\n", ret);
+
+	ret = i2c_set(ts, 0xf1, 0, "disable interrupt");
+	if (ret < 0)
+		goto err_detect_failed;
+
+	msg[0].addr = ts->client->addr;
+	msg[0].flags = 0;
+	msg[0].len = 1;
+	msg[0].buf = buf0;
+	buf0[0] = 0xe0;
+	msg[1].addr = ts->client->addr;
+	msg[1].flags = I2C_M_RD;
+	msg[1].len = 8;
+	msg[1].buf = buf1;
+	ret = i2c_transfer(ts->client->adapter, msg, 2);
+	if (ret < 0) {
+		pr_err("i2c_transfer failed\n");
+		goto err_detect_failed;
+	}
+	pr_info("synaptics_ts_probe: 0xe0: %x %x %x %x %x %x %x %x\n",
+	       buf1[0], buf1[1], buf1[2], buf1[3],
+	       buf1[4], buf1[5], buf1[6], buf1[7]);
+
+	ret = i2c_set(ts, 0xff, 0x10, "page select = 0x10");
+	if (ret < 0)
+		goto err_detect_failed;
+
+	ret = i2c_smbus_read_word_data(ts->client, 0x04);
+	if (ret < 0) {
+		pr_err("i2c_smbus_read_word_data failed\n");
+		goto err_detect_failed;
+	}
+	ts->max[0] = max_x = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
+	ret = i2c_smbus_read_word_data(ts->client, 0x06);
+	if (ret < 0) {
+		pr_err("i2c_smbus_read_word_data failed\n");
+		goto err_detect_failed;
+	}
+	ts->max[1] = max_y = (ret >> 8 & 0xff) | ((ret & 0x1f) << 8);
+	if (ts->flags & SYNAPTICS_SWAP_XY)
+		swap(max_x, max_y);
+
+	/* will also switch back to page 0x04 */
+	ret = synaptics_init_panel(ts);
+	if (ret < 0) {
+		pr_err("synaptics_init_panel failed\n");
+		goto err_detect_failed;
+	}
+
+	ts->input_dev = input_allocate_device();
+	if (ts->input_dev == NULL) {
+		ret = -ENOMEM;
+		pr_err("synaptics: Failed to allocate input device\n");
+		goto err_input_dev_alloc_failed;
+	}
+	ts->input_dev->name = "synaptics-rmi-touchscreen";
+	ts->input_dev->phys = "msm/input0";
+	ts->input_dev->id.bustype = BUS_I2C;
+
+	__set_bit(EV_SYN, ts->input_dev->evbit);
+	__set_bit(EV_KEY, ts->input_dev->evbit);
+	__set_bit(BTN_TOUCH, ts->input_dev->keybit);
+	__set_bit(BTN_2, ts->input_dev->keybit);
+	__set_bit(EV_ABS, ts->input_dev->evbit);
+
+	compute_areas(ts, pdata, max_x, max_y);
+
+
+	ret = input_register_device(ts->input_dev);
+	if (ret) {
+		pr_err("synaptics: Unable to register %s input device\n",
+		       ts->input_dev->name);
+		goto err_input_register_device_failed;
+	}
+	if (client->irq) {
+		ret = request_irq(client->irq, synaptics_ts_irq_handler,
+				  0, client->name, ts);
+		if (ret == 0) {
+			ret = i2c_set(ts, 0xf1, 0x01, "enable abs int");
+			if (ret)
+				free_irq(client->irq, ts);
+		}
+		if (ret == 0)
+			ts->use_irq = 1;
+		else
+			dev_err(&client->dev, "request_irq failed\n");
+	}
+	if (!ts->use_irq) {
+		hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		ts->timer.function = synaptics_ts_timer_func;
+		hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+	}
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+	ts->early_suspend.suspend = synaptics_ts_early_suspend;
+	ts->early_suspend.resume = synaptics_ts_late_resume;
+	register_early_suspend(&ts->early_suspend);
+#endif
+
+	pr_info("synaptics: Start touchscreen %s in %s mode\n",
+		ts->input_dev->name, ts->use_irq ? "interrupt" : "polling");
+
+	return 0;
+
+err_input_register_device_failed:
+	input_free_device(ts->input_dev);
+
+err_input_dev_alloc_failed:
+err_detect_failed:
+err_power_failed:
+	kfree(ts);
+err_alloc_data_failed:
+err_check_functionality_failed:
+	return ret;
+}
+
+static int synaptics_ts_remove(struct i2c_client *client)
+{
+	struct synaptics_ts_data *ts = i2c_get_clientdata(client);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	unregister_early_suspend(&ts->early_suspend);
+#endif
+	if (ts->use_irq)
+		free_irq(client->irq, ts);
+	else
+		hrtimer_cancel(&ts->timer);
+	input_unregister_device(ts->input_dev);
+	kfree(ts);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int synaptics_ts_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	int ret;
+	struct synaptics_ts_data *ts = i2c_get_clientdata(client);
+
+	if (ts->use_irq)
+		disable_irq(client->irq);
+	else
+		hrtimer_cancel(&ts->timer);
+	ret = cancel_work_sync(&ts->work);
+	if (ret && ts->use_irq) /* if work was pending disable-count is now 2 */
+		enable_irq(client->irq);
+	i2c_set(ts, 0xf1, 0, "disable interrupt");
+	i2c_set(ts, 0xf0, 0x86, "deep sleep");
+
+	if (ts->power) {
+		ret = ts->power(0);
+		if (ret < 0)
+			pr_err("synaptics_ts_suspend power off failed\n");
+	}
+	return 0;
+}
+
+static int synaptics_ts_resume(struct i2c_client *client)
+{
+	int ret;
+	struct synaptics_ts_data *ts = i2c_get_clientdata(client);
+
+	if (ts->power) {
+		ret = ts->power(1);
+		if (ret < 0)
+			pr_err("synaptics_ts_resume power on failed\n");
+	}
+
+	synaptics_init_panel(ts);
+
+	if (ts->use_irq) {
+		enable_irq(client->irq);
+		i2c_set(ts, 0xf1, 0x01, "enable abs int");
+	} else
+		hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+
+	return 0;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void synaptics_ts_early_suspend(struct early_suspend *h)
+{
+	struct synaptics_ts_data *ts;
+	ts = container_of(h, struct synaptics_ts_data, early_suspend);
+	synaptics_ts_suspend(ts->client, PMSG_SUSPEND);
+}
+
+static void synaptics_ts_late_resume(struct early_suspend *h)
+{
+	struct synaptics_ts_data *ts;
+	ts = container_of(h, struct synaptics_ts_data, early_suspend);
+	synaptics_ts_resume(ts->client);
+}
+#endif
+#else
+#define synaptics_ts_suspend NULL
+#define synaptics_ts_resume NULL
+#endif
+
+
+
+static const struct i2c_device_id synaptics_ts_id[] = {
+	{ SYNAPTICS_I2C_RMI_NAME, 0 },
+	{ }
+};
+
+static struct i2c_driver synaptics_ts_driver = {
+	.probe		= synaptics_ts_probe,
+	.remove		= synaptics_ts_remove,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+	.suspend	= synaptics_ts_suspend,
+	.resume		= synaptics_ts_resume,
+#endif
+	.id_table	= synaptics_ts_id,
+	.driver = {
+		.name	= SYNAPTICS_I2C_RMI_NAME,
+	},
+};
+
+static int __devinit synaptics_ts_init(void)
+{
+	synaptics_wq = create_singlethread_workqueue("synaptics_wq");
+	if (!synaptics_wq)
+		return -ENOMEM;
+	return i2c_add_driver(&synaptics_ts_driver);
+}
+
+static void __exit synaptics_ts_exit(void)
+{
+	i2c_del_driver(&synaptics_ts_driver);
+	if (synaptics_wq)
+		destroy_workqueue(synaptics_wq);
+}
+
+module_init(synaptics_ts_init);
+module_exit(synaptics_ts_exit);
+
+MODULE_DESCRIPTION("Synaptics Touchscreen Driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arve HjÃ¸nnevÃ¥g <arve@android.com>");
diff --git a/drivers/staging/dream/synaptics_i2c_rmi.h b/drivers/staging/dream/synaptics_i2c_rmi.h
new file mode 100644
index 0000000..ca51b2f
--- /dev/null
+++ b/drivers/staging/dream/synaptics_i2c_rmi.h
@@ -0,0 +1,53 @@
+/*
+ * include/linux/synaptics_i2c_rmi.h - platform data structure for f75375s sensor
+ *
+ * Copyright (C) 2008 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_SYNAPTICS_I2C_RMI_H
+#define _LINUX_SYNAPTICS_I2C_RMI_H
+
+#define SYNAPTICS_I2C_RMI_NAME "synaptics-rmi-ts"
+
+enum {
+	SYNAPTICS_FLIP_X = 1UL << 0,
+	SYNAPTICS_FLIP_Y = 1UL << 1,
+	SYNAPTICS_SWAP_XY = 1UL << 2,
+	SYNAPTICS_SNAP_TO_INACTIVE_EDGE = 1UL << 3,
+};
+
+struct synaptics_i2c_rmi_platform_data {
+	uint32_t version;	/* Use this entry for panels with */
+				/* (major << 8 | minor) version or above. */
+				/* If non-zero another array entry follows */
+	int (*power)(int on);	/* Only valid in first array entry */
+	uint32_t flags;
+	uint32_t inactive_left; /* 0x10000 = screen width */
+	uint32_t inactive_right; /* 0x10000 = screen width */
+	uint32_t inactive_top; /* 0x10000 = screen height */
+	uint32_t inactive_bottom; /* 0x10000 = screen height */
+	uint32_t snap_left_on; /* 0x10000 = screen width */
+	uint32_t snap_left_off; /* 0x10000 = screen width */
+	uint32_t snap_right_on; /* 0x10000 = screen width */
+	uint32_t snap_right_off; /* 0x10000 = screen width */
+	uint32_t snap_top_on; /* 0x10000 = screen height */
+	uint32_t snap_top_off; /* 0x10000 = screen height */
+	uint32_t snap_bottom_on; /* 0x10000 = screen height */
+	uint32_t snap_bottom_off; /* 0x10000 = screen height */
+	uint32_t fuzz_x; /* 0x10000 = screen width */
+	uint32_t fuzz_y; /* 0x10000 = screen height */
+	int fuzz_p;
+	int fuzz_w;
+};
+
+#endif /* _LINUX_SYNAPTICS_I2C_RMI_H */
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
index fad25b7..ac85773 100644
--- a/drivers/staging/dst/dcore.c
+++ b/drivers/staging/dst/dcore.c
@@ -112,8 +112,9 @@ static int dst_request(struct request_queue *q, struct bio *bio)
 		 * 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.
+		 * for example, although later it was changed to
+		 * bio_rw_flagged(bio, BIO_RW_DISCARD) only, which does not
+		 * work in this case.
 		 */
 		//err = -EOPNOTSUPP;
 		err = 0;
@@ -846,10 +847,9 @@ static dst_command_func dst_commands[] = {
 /*
  * Configuration parser.
  */
-static void cn_dst_callback(void *data)
+static void cn_dst_callback(struct cn_msg *msg)
 {
 	struct dst_ctl *ctl;
-	struct cn_msg *msg = data;
 	int err;
 	struct dst_ctl_ack ack;
 	struct dst_node *n = NULL, *tmp;
diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c
index 80ae4eb..4fbd848 100644
--- a/drivers/staging/dst/export.c
+++ b/drivers/staging/dst/export.c
@@ -159,7 +159,7 @@ static struct dst_state *dst_accept_client(struct dst_state *st)
 		goto err_out_exit;
 
 	new = dst_state_alloc(st->node);
-	if (!new) {
+	if (IS_ERR(new)) {
 		err = -ENOMEM;
 		goto err_out_release;
 	}
diff --git a/drivers/staging/echo/TODO b/drivers/staging/echo/TODO
index f6d8580..72a311a 100644
--- a/drivers/staging/echo/TODO
+++ b/drivers/staging/echo/TODO
@@ -1,8 +1,5 @@
 TODO:
-	- checkpatch.pl cleanups
-	- handle bit_operations.h (merge in or make part of common code?)
-	- remove proc interface, only use echo.h interface (proc interface is
-	  racy and not correct.)
+	- send to lkml for review
 
 Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc: Steve
 Underwood <steveu@coppice.org> and David Rowe <david@rowetel.com>
diff --git a/drivers/staging/echo/bit_operations.h b/drivers/staging/echo/bit_operations.h
deleted file mode 100644
index 4c4ccbc..0000000
--- a/drivers/staging/echo/bit_operations.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * SpanDSP - a series of DSP components for telephony
- *
- * bit_operations.h - Various bit level operations, such as bit reversal
- *
- * Written by Steve Underwood <steveu@coppice.org>
- *
- * Copyright (C) 2006 Steve Underwood
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*! \file */
-
-#if !defined(_BIT_OPERATIONS_H_)
-#define _BIT_OPERATIONS_H_
-
-#if defined(__i386__)  ||  defined(__x86_64__)
-/*! \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)
-{
-	int res;
-
-	__asm__(" xorl %[res],%[res];\n"
-		" decl %[res];\n"
-		" bsrl %[bits],%[res]\n"
-		:[res] "=&r" (res)
-		:[bits] "rm"(bits)
-	);
-	return res;
-}
-
-/*! \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)
-{
-	int res;
-
-	__asm__(" xorl %[res],%[res];\n"
-		" decl %[res];\n"
-		" bsfl %[bits],%[res]\n"
-		:[res] "=&r" (res)
-		:[bits] "rm"(bits)
-	);
-	return res;
-}
-#else
-static inline int top_bit(unsigned int bits)
-{
-	int i;
-
-	if (bits == 0)
-		return -1;
-	i = 0;
-	if (bits & 0xFFFF0000) {
-		bits &= 0xFFFF0000;
-		i += 16;
-	}
-	if (bits & 0xFF00FF00) {
-		bits &= 0xFF00FF00;
-		i += 8;
-	}
-	if (bits & 0xF0F0F0F0) {
-		bits &= 0xF0F0F0F0;
-		i += 4;
-	}
-	if (bits & 0xCCCCCCCC) {
-		bits &= 0xCCCCCCCC;
-		i += 2;
-	}
-	if (bits & 0xAAAAAAAA) {
-		bits &= 0xAAAAAAAA;
-		i += 1;
-	}
-	return i;
-}
-
-static inline int bottom_bit(unsigned int bits)
-{
-	int i;
-
-	if (bits == 0)
-		return -1;
-	i = 32;
-	if (bits & 0x0000FFFF) {
-		bits &= 0x0000FFFF;
-		i -= 16;
-	}
-	if (bits & 0x00FF00FF) {
-		bits &= 0x00FF00FF;
-		i -= 8;
-	}
-	if (bits & 0x0F0F0F0F) {
-		bits &= 0x0F0F0F0F;
-		i -= 4;
-	}
-	if (bits & 0x33333333) {
-		bits &= 0x33333333;
-		i -= 2;
-	}
-	if (bits & 0x55555555) {
-		bits &= 0x55555555;
-		i -= 1;
-	}
-	return i;
-}
-#endif
-
-/*! \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)
-{
-#if defined(__i386__)  ||  defined(__x86_64__)
-	/* If multiply is fast */
-	return ((x * 0x0802U & 0x22110U) | (x * 0x8020U & 0x88440U)) *
-	    0x10101U >> 16;
-#else
-	/* If multiply is slow, but we have a barrel shifter */
-	x = (x >> 4) | (x << 4);
-	x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2);
-	return ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
-#endif
-}
-
-/*! \brief Bit reverse a 16 bit word.
-    \param data The word to be reversed.
-    \return The bit reversed version of data. */
-uint16_t bit_reverse16(uint16_t data);
-
-/*! \brief Bit reverse a 32 bit word.
-    \param data The word to be reversed.
-    \return The bit reversed version of data. */
-uint32_t bit_reverse32(uint32_t data);
-
-/*! \brief Bit reverse each of the four bytes in a 32 bit word.
-    \param data The word to be reversed.
-    \return The bit reversed version of data. */
-uint32_t bit_reverse_4bytes(uint32_t data);
-
-/*! \brief Find the number of set bits in a 32 bit word.
-    \param x The word to be searched.
-    \return The number of set bits. */
-int one_bits32(uint32_t x);
-
-/*! \brief Create a mask as wide as the number in a 32 bit word.
-    \param x The word to be searched.
-    \return The mask. */
-uint32_t make_mask32(uint32_t x);
-
-/*! \brief Create a mask as wide as the number in a 16 bit word.
-    \param x The word to be searched.
-    \return The mask. */
-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.
-    \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)
-{
-	return x & (-(int32_t) x);
-}
-
-/*! \brief Find the most significant one in a word, and return a word
-	    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)
-{
-#if defined(__i386__)  ||  defined(__x86_64__)
-	return 1 << top_bit(x);
-#else
-	x = make_mask32(x);
-	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)
-{
-	x = (x ^ (x >> 4)) & 0x0F;
-	return (0x6996 >> x) & 1;
-}
-
-/*! \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)
-{
-	x ^= (x >> 8);
-	x = (x ^ (x >> 4)) & 0x0F;
-	return (0x6996 >> x) & 1;
-}
-
-/*! \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)
-{
-	x ^= (x >> 16);
-	x ^= (x >> 8);
-	x = (x ^ (x >> 4)) & 0x0F;
-	return (0x6996 >> x) & 1;
-}
-
-#endif
-/*- End of file ------------------------------------------------------------*/
diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c
index 79d15c6..4cc4f2e 100644
--- a/drivers/staging/echo/echo.c
+++ b/drivers/staging/echo/echo.c
@@ -82,9 +82,9 @@
 
    [2] The classic, very useful paper that tells you how to
        actually build a real world echo canceller:
-         Messerschmitt, Hedberg, Cole, Haoui, Winship, "Digital Voice
-         Echo Canceller with a TMS320020,
-         http://www.rowetel.com/images/echo/spra129.pdf
+	 Messerschmitt, Hedberg, Cole, Haoui, Winship, "Digital Voice
+	 Echo Canceller with a TMS320020,
+	 http://www.rowetel.com/images/echo/spra129.pdf
 
    [3] I have written a series of blog posts on this work, here is
        Part 1: http://www.rowetel.com/blog/?p=18
@@ -92,7 +92,7 @@
    [4] The source code http://svn.rowetel.com/software/oslec/
 
    [5] A nice reference on LMS filters:
-         http://en.wikipedia.org/wiki/Least_mean_squares_filter
+	 http://en.wikipedia.org/wiki/Least_mean_squares_filter
 
    Credits:
 
@@ -102,21 +102,17 @@
    Mark, Pawel, and Pavel.
 */
 
-#include <linux/kernel.h>	/* We're doing kernel work */
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 
-#include "bit_operations.h"
 #include "echo.h"
 
-#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 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 */
 
-/*-----------------------------------------------------------------------*\
-				   FUNCTIONS
-\*-----------------------------------------------------------------------*/
 
 /* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
 
@@ -224,6 +220,14 @@ static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
 }
 #endif
 
+static inline int top_bit(unsigned int bits)
+{
+	if (bits == 0)
+		return -1;
+	else
+		return (int)fls((int32_t)bits)-1;
+}
+
 struct oslec_state *oslec_create(int len, int adaption_mode)
 {
 	struct oslec_state *ec;
@@ -328,7 +332,7 @@ void oslec_snapshot(struct oslec_state *ec)
 }
 EXPORT_SYMBOL_GPL(oslec_snapshot);
 
-/* Dual Path Echo Canceller ------------------------------------------------*/
+/* Dual Path Echo Canceller */
 
 int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 {
@@ -336,9 +340,11 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 	int clean_bg;
 	int tmp, tmp1;
 
-	/* Input scaling was found be required to prevent problems when tx
-	   starts clipping.  Another possible way to handle this would be the
-	   filter coefficent scaling. */
+	/*
+	 * Input scaling was found be required to prevent problems when tx
+	 * starts clipping.  Another possible way to handle this would be the
+	 * filter coefficent scaling.
+	 */
 
 	ec->tx = tx;
 	ec->rx = rx;
@@ -346,33 +352,40 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 	rx >>= 1;
 
 	/*
-	   Filter DC, 3dB point is 160Hz (I think), note 32 bit precision required
-	   otherwise values do not track down to 0. Zero at DC, Pole at (1-Beta)
-	   only real axis.  Some chip sets (like Si labs) don't need
-	   this, but something like a $10 X100P card does.  Any DC really slows
-	   down convergence.
-
-	   Note: removes some low frequency from the signal, this reduces
-	   the speech quality when listening to samples through headphones
-	   but may not be obvious through a telephone handset.
-
-	   Note that the 3dB frequency in radians is approx Beta, e.g. for
-	   Beta = 2^(-3) = 0.125, 3dB freq is 0.125 rads = 159Hz.
+	 * Filter DC, 3dB point is 160Hz (I think), note 32 bit precision
+	 * required otherwise values do not track down to 0. Zero at DC, Pole
+	 * at (1-Beta) on real axis.  Some chip sets (like Si labs) don't
+	 * need this, but something like a $10 X100P card does.  Any DC really
+	 * slows down convergence.
+	 *
+	 * Note: removes some low frequency from the signal, this reduces the
+	 * speech quality when listening to samples through headphones but may
+	 * not be obvious through a telephone handset.
+	 *
+	 * Note that the 3dB frequency in radians is approx Beta, e.g. for Beta
+	 * = 2^(-3) = 0.125, 3dB freq is 0.125 rads = 159Hz.
 	 */
 
 	if (ec->adaption_mode & ECHO_CAN_USE_RX_HPF) {
 		tmp = rx << 15;
-#if 1
-		/* Make sure the gain of the HPF is 1.0. This can still saturate a little under
-		   impulse conditions, and it might roll to 32768 and need clipping on sustained peak
-		   level signals. However, the scale of such clipping is small, and the error due to
-		   any saturation should not markedly affect the downstream processing. */
+
+		/*
+		 * Make sure the gain of the HPF is 1.0. This can still
+		 * saturate a little under impulse conditions, and it might
+		 * roll to 32768 and need clipping on sustained peak level
+		 * signals. However, the scale of such clipping is small, and
+		 * the error due to any saturation should not markedly affect
+		 * the downstream processing.
+		 */
 		tmp -= (tmp >> 4);
-#endif
+
 		ec->rx_1 += -(ec->rx_1 >> DC_LOG2BETA) + tmp - ec->rx_2;
 
-		/* hard limit filter to prevent clipping.  Note that at this stage
-		   rx should be limited to +/- 16383 due to right shift above */
+		/*
+		 * hard limit filter to prevent clipping.  Note that at this
+		 * stage rx should be limited to +/- 16383 due to right shift
+		 * above
+		 */
 		tmp1 = ec->rx_1 >> 15;
 		if (tmp1 > 16383)
 			tmp1 = 16383;
@@ -407,7 +420,7 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 	ec->Lrxacc += abs(rx) - ec->Lrx;
 	ec->Lrx = (ec->Lrxacc + (1 << 4)) >> 5;
 
-	/* Foreground filter --------------------------------------------------- */
+	/* Foreground filter */
 
 	ec->fir_state.coeffs = ec->fir_taps16[0];
 	echo_value = fir16(&ec->fir_state, tx);
@@ -415,14 +428,14 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 	ec->Lcleanacc += abs(ec->clean) - ec->Lclean;
 	ec->Lclean = (ec->Lcleanacc + (1 << 4)) >> 5;
 
-	/* Background filter --------------------------------------------------- */
+	/* Background filter */
 
 	echo_value = fir16(&ec->fir_state_bg, tx);
 	clean_bg = rx - echo_value;
 	ec->Lclean_bgacc += abs(clean_bg) - ec->Lclean_bg;
 	ec->Lclean_bg = (ec->Lclean_bgacc + (1 << 4)) >> 5;
 
-	/* Background Filter adaption ----------------------------------------- */
+	/* Background Filter adaption */
 
 	/* Almost always adap bg filter, just simple DT and energy
 	   detection to minimise adaption in cases of strong double talk.
@@ -447,14 +460,14 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 		   therefore the scaled version of (1) is:
 
 		   (2^30) * f  = (2^30) * Beta * clean_bg_rx/P
-		   factor  = (2^30) * Beta * clean_bg_rx/P         ----- (2)
+		   factor      = (2^30) * Beta * clean_bg_rx/P     ----- (2)
 
 		   We have chosen Beta = 0.25 by experiment, so:
 
-		   factor  = (2^30) * (2^-2) * clean_bg_rx/P
+		   factor      = (2^30) * (2^-2) * clean_bg_rx/P
 
-		   (30 - 2 - log2(P))
-		   factor  = clean_bg_rx 2                         ----- (3)
+						(30 - 2 - log2(P))
+		   factor      = clean_bg_rx 2                     ----- (3)
 
 		   To avoid a divide we approximate log2(P) as top_bit(P),
 		   which returns the position of the highest non-zero bit in
@@ -483,7 +496,7 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 	if (ec->nonupdate_dwell)
 		ec->nonupdate_dwell--;
 
-	/* Transfer logic ------------------------------------------------------ */
+	/* Transfer logic */
 
 	/* These conditions are from the dual path paper [1], I messed with
 	   them a bit to improve performance. */
@@ -495,7 +508,10 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 	    /* (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 */
+			/*
+			 * 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));
@@ -504,25 +520,34 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 	} else
 		ec->cond_met = 0;
 
-	/* Non-Linear Processing --------------------------------------------------- */
+	/* Non-Linear Processing */
 
 	ec->clean_nlp = ec->clean;
 	if (ec->adaption_mode & ECHO_CAN_USE_NLP) {
-		/* Non-linear processor - a fancy way to say "zap small signals, to avoid
-		   residual echo due to (uLaw/ALaw) non-linearity in the channel.". */
+		/*
+		 * Non-linear processor - a fancy way to say "zap small
+		 * signals, to avoid residual echo due to (uLaw/ALaw)
+		 * non-linearity in the channel.".
+		 */
 
 		if ((16 * ec->Lclean < ec->Ltx)) {
-			/* Our e/c has improved echo by at least 24 dB (each factor of 2 is 6dB,
-			   so 2*2*2*2=16 is the same as 6+6+6+6=24dB) */
+			/*
+			 * Our e/c has improved echo by at least 24 dB (each
+			 * factor of 2 is 6dB, so 2*2*2*2=16 is the same as
+			 * 6+6+6+6=24dB)
+			 */
 			if (ec->adaption_mode & ECHO_CAN_USE_CNG) {
 				ec->cng_level = ec->Lbgn;
 
-				/* Very elementary comfort noise generation.  Just random
-				   numbers rolled off very vaguely Hoth-like.  DR: This
-				   noise doesn't sound quite right to me - I suspect there
-				   are some overlfow issues in the filtering as it's too
-				   "crackly".  TODO: debug this, maybe just play noise at
-				   high level or look at spectrum.
+				/*
+				 * Very elementary comfort noise generation.
+				 * Just random numbers rolled off very vaguely
+				 * Hoth-like.  DR: This noise doesn't sound
+				 * quite right to me - I suspect there are some
+				 * overlfow issues in the filtering as it's too
+				 * "crackly".
+				 * TODO: debug this, maybe just play noise at
+				 * high level or look at spectrum.
 				 */
 
 				ec->cng_rndnum =
@@ -540,18 +565,22 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
 				if (ec->clean_nlp < -ec->Lbgn)
 					ec->clean_nlp = -ec->Lbgn;
 			} else {
-				/* just mute the residual, doesn't sound very good, used mainly
-				   in G168 tests */
+				/*
+				 * just mute the residual, doesn't sound very
+				 * good, used mainly in G168 tests
+				 */
 				ec->clean_nlp = 0;
 			}
 		} else {
-			/* Background noise estimator.  I tried a few algorithms
-			   here without much luck.  This very simple one seems to
-			   work best, we just average the level using a slow (1 sec
-			   time const) filter if the current level is less than a
-			   (experimentally derived) constant.  This means we dont
-			   include high level signals like near end speech.  When
-			   combined with CNG or especially CLIP seems to work OK.
+			/*
+			 * Background noise estimator.  I tried a few
+			 * algorithms here without much luck.  This very simple
+			 * one seems to work best, we just average the level
+			 * using a slow (1 sec time const) filter if the
+			 * current level is less than a (experimentally
+			 * derived) constant.  This means we dont include high
+			 * level signals like near end speech.  When combined
+			 * with CNG or especially CLIP seems to work OK.
 			 */
 			if (ec->Lclean < 40) {
 				ec->Lbgn_acc += abs(ec->clean) - ec->Lbgn;
@@ -587,12 +616,13 @@ EXPORT_SYMBOL_GPL(oslec_update);
    It can also help by removing and DC in the tx signal.  DC is bad
    for LMS algorithms.
 
-   This is one of the classic DC removal filters, adjusted to provide sufficient
-   bass rolloff to meet the above requirement to protect hybrids from things that
-   upset them. The difference between successive samples produces a lousy HPF, and
-   then a suitably placed pole flattens things out. The final result is a nicely
-   rolled off bass end. The filtering is implemented with extended fractional
-   precision, which noise shapes things, giving very clean DC removal.
+   This is one of the classic DC removal filters, adjusted to provide
+   sufficient bass rolloff to meet the above requirement to protect hybrids
+   from things that upset them. The difference between successive samples
+   produces a lousy HPF, and then a suitably placed pole flattens things out.
+   The final result is a nicely rolled off bass end. The filtering is
+   implemented with extended fractional precision, which noise shapes things,
+   giving very clean DC removal.
 */
 
 int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx)
@@ -601,13 +631,17 @@ int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx)
 
 	if (ec->adaption_mode & ECHO_CAN_USE_TX_HPF) {
 		tmp = tx << 15;
-#if 1
-		/* Make sure the gain of the HPF is 1.0. The first can still saturate a little under
-		   impulse conditions, and it might roll to 32768 and need clipping on sustained peak
-		   level signals. However, the scale of such clipping is small, and the error due to
-		   any saturation should not markedly affect the downstream processing. */
+
+		/*
+		 * Make sure the gain of the HPF is 1.0. The first can still
+		 * saturate a little under impulse conditions, and it might
+		 * roll to 32768 and need clipping on sustained peak level
+		 * signals. However, the scale of such clipping is small, and
+		 * the error due to any saturation should not markedly affect
+		 * the downstream processing.
+		 */
 		tmp -= (tmp >> 4);
-#endif
+
 		ec->tx_1 += -(ec->tx_1 >> DC_LOG2BETA) + tmp - ec->tx_2;
 		tmp1 = ec->tx_1 >> 15;
 		if (tmp1 > 32767)
diff --git a/drivers/staging/echo/echo.h b/drivers/staging/echo/echo.h
index c835e5c..754e66d 100644
--- a/drivers/staging/echo/echo.h
+++ b/drivers/staging/echo/echo.h
@@ -28,13 +28,17 @@
 #ifndef __ECHO_H
 #define __ECHO_H
 
-/*! \page echo_can_page Line echo cancellation for voice
+/*
+Line echo cancellation for voice
+
+What does it do?
 
-\section echo_can_page_sec_1 What does it do?
 This module aims to provide G.168-2002 compliant echo cancellation, to remove
 electrical echoes (e.g. from 2-4 wire hybrids) from voice calls.
 
-\section echo_can_page_sec_2 How does it work?
+
+How does it work?
+
 The heart of the echo cancellor is FIR filter. This is adapted to match the
 echo impulse response of the telephone line. It must be long enough to
 adequately cover the duration of that impulse response. The signal transmitted
@@ -108,7 +112,8 @@ major mis-convergence in the adaption process. An assessment algorithm is
 needed which produces a fairly accurate result from a very short burst of far
 end energy.
 
-\section echo_can_page_sec_3 How do I use it?
+How do I use it?
+
 The echo cancellor processes both the transmit and receive streams sample by
 sample. The processing function is not declared inline. Unfortunately,
 cancellation requires many operations per sample, so the call overhead is only
@@ -118,7 +123,7 @@ a minor burden.
 #include "fir.h"
 #include "oslec.h"
 
-/*!
+/*
     G.168 echo canceller descriptor. This defines the working state for a line
     echo canceller.
 */
diff --git a/drivers/staging/echo/fir.h b/drivers/staging/echo/fir.h
index ac6c553..7b9fabf 100644
--- a/drivers/staging/echo/fir.h
+++ b/drivers/staging/echo/fir.h
@@ -23,14 +23,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/*! \page fir_page FIR filtering
-\section fir_page_sec_1 What does it do?
-???.
-
-\section fir_page_sec_2 How does it work?
-???.
-*/
-
 #if !defined(_FIR_H_)
 #define _FIR_H_
 
@@ -62,14 +54,10 @@
    can.
 */
 
-#if defined(USE_MMX)  ||  defined(USE_SSE2)
-#include "mmx.h"
-#endif
-
-/*!
-    16 bit integer FIR descriptor. This defines the working state for a single
-    instance of an FIR filter using 16 bit integer coefficients.
-*/
+/*
+ * 16 bit integer FIR descriptor. This defines the working state for a single
+ * instance of an FIR filter using 16 bit integer coefficients.
+ */
 struct fir16_state_t {
 	int taps;
 	int curr_pos;
@@ -77,11 +65,11 @@ struct fir16_state_t {
 	int16_t *history;
 };
 
-/*!
-    32 bit integer FIR descriptor. This defines the working state for a single
-    instance of an FIR filter using 32 bit integer coefficients, and filtering
-    16 bit integer data.
-*/
+/*
+ * 32 bit integer FIR descriptor. This defines the working state for a single
+ * instance of an FIR filter using 32 bit integer coefficients, and filtering
+ * 16 bit integer data.
+ */
 struct fir32_state_t {
 	int taps;
 	int curr_pos;
@@ -89,10 +77,10 @@ struct fir32_state_t {
 	int16_t *history;
 };
 
-/*!
-    Floating point FIR descriptor. This defines the working state for a single
-    instance of an FIR filter using floating point coefficients and data.
-*/
+/*
+ * Floating point FIR descriptor. This defines the working state for a single
+ * instance of an FIR filter using floating point coefficients and data.
+ */
 struct fir_float_state_t {
 	int taps;
 	int curr_pos;
@@ -106,7 +94,7 @@ static inline const int16_t *fir16_create(struct fir16_state_t *fir,
 	fir->taps = taps;
 	fir->curr_pos = taps - 1;
 	fir->coeffs = coeffs;
-#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
+#if defined(__bfin__)
 	fir->history = kcalloc(2 * taps, sizeof(int16_t), GFP_KERNEL);
 #else
 	fir->history = kcalloc(taps, sizeof(int16_t), GFP_KERNEL);
@@ -116,7 +104,7 @@ static inline const int16_t *fir16_create(struct fir16_state_t *fir,
 
 static inline void fir16_flush(struct fir16_state_t *fir)
 {
-#if defined(USE_MMX)  ||  defined(USE_SSE2) || defined(__bfin__)
+#if defined(__bfin__)
 	memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
 #else
 	memset(fir->history, 0, fir->taps * sizeof(int16_t));
@@ -158,71 +146,7 @@ static inline int32_t dot_asm(short *x, short *y, int len)
 static inline int16_t fir16(struct fir16_state_t *fir, int16_t sample)
 {
 	int32_t y;
-#if defined(USE_MMX)
-	int i;
-	union mmx_t *mmx_coeffs;
-	union mmx_t *mmx_hist;
-
-	fir->history[fir->curr_pos] = sample;
-	fir->history[fir->curr_pos + fir->taps] = sample;
-
-	mmx_coeffs = (union mmx_t *)fir->coeffs;
-	mmx_hist = (union mmx_t *)&fir->history[fir->curr_pos];
-	i = fir->taps;
-	pxor_r2r(mm4, mm4);
-	/* 8 samples per iteration, so the filter must be a multiple of 8 long. */
-	while (i > 0) {
-		movq_m2r(mmx_coeffs[0], mm0);
-		movq_m2r(mmx_coeffs[1], mm2);
-		movq_m2r(mmx_hist[0], mm1);
-		movq_m2r(mmx_hist[1], mm3);
-		mmx_coeffs += 2;
-		mmx_hist += 2;
-		pmaddwd_r2r(mm1, mm0);
-		pmaddwd_r2r(mm3, mm2);
-		paddd_r2r(mm0, mm4);
-		paddd_r2r(mm2, mm4);
-		i -= 8;
-	}
-	movq_r2r(mm4, mm0);
-	psrlq_i2r(32, mm0);
-	paddd_r2r(mm0, mm4);
-	movd_r2m(mm4, y);
-	emms();
-#elif defined(USE_SSE2)
-	int i;
-	union xmm_t *xmm_coeffs;
-	union xmm_t *xmm_hist;
-
-	fir->history[fir->curr_pos] = sample;
-	fir->history[fir->curr_pos + fir->taps] = sample;
-
-	xmm_coeffs = (union xmm_t *)fir->coeffs;
-	xmm_hist = (union xmm_t *)&fir->history[fir->curr_pos];
-	i = fir->taps;
-	pxor_r2r(xmm4, xmm4);
-	/* 16 samples per iteration, so the filter must be a multiple of 16 long. */
-	while (i > 0) {
-		movdqu_m2r(xmm_coeffs[0], xmm0);
-		movdqu_m2r(xmm_coeffs[1], xmm2);
-		movdqu_m2r(xmm_hist[0], xmm1);
-		movdqu_m2r(xmm_hist[1], xmm3);
-		xmm_coeffs += 2;
-		xmm_hist += 2;
-		pmaddwd_r2r(xmm1, xmm0);
-		pmaddwd_r2r(xmm3, xmm2);
-		paddd_r2r(xmm0, xmm4);
-		paddd_r2r(xmm2, xmm4);
-		i -= 16;
-	}
-	movdqa_r2r(xmm4, xmm0);
-	psrldq_i2r(8, xmm0);
-	paddd_r2r(xmm0, xmm4);
-	movdqa_r2r(xmm4, xmm0);
-	psrldq_i2r(4, xmm0);
-	paddd_r2r(xmm0, xmm4);
-	movd_r2m(xmm4, y);
-#elif defined(__bfin__)
+#if defined(__bfin__)
 	fir->history[fir->curr_pos] = sample;
 	fir->history[fir->curr_pos + fir->taps] = sample;
 	y = dot_asm((int16_t *) fir->coeffs, &fir->history[fir->curr_pos],
@@ -290,4 +214,3 @@ static inline int16_t fir32(struct fir32_state_t *fir, int16_t sample)
 }
 
 #endif
-/*- End of file ------------------------------------------------------------*/
diff --git a/drivers/staging/echo/mmx.h b/drivers/staging/echo/mmx.h
deleted file mode 100644
index c1dcd72..0000000
--- a/drivers/staging/echo/mmx.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * mmx.h
- * Copyright (C) 1997-2001 H. Dietz and R. Fisher
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef AVCODEC_I386MMX_H
-#define AVCODEC_I386MMX_H
-
-/*
- * The type of an value that fits in an MMX register (note that long
- * long constant values MUST be suffixed by LL and unsigned long long
- * values by ULL, lest they be truncated by the compiler)
- */
-
-union mmx_t {
-	long long q;		/* Quadword (64-bit) value */
-	unsigned long long uq;	/* Unsigned Quadword */
-	int d[2];		/* 2 Doubleword (32-bit) values */
-	unsigned int ud[2];	/* 2 Unsigned Doubleword */
-	short w[4];		/* 4 Word (16-bit) values */
-	unsigned short uw[4];	/* 4 Unsigned Word */
-	char b[8];		/* 8 Byte (8-bit) values */
-	unsigned char ub[8];	/* 8 Unsigned Byte */
-	float s[2];		/* Single-precision (32-bit) value */
-};				/* On an 8-byte (64-bit) boundary */
-
-/* SSE registers */
-union xmm_t {
-	char b[16];
-};
-
-#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_r2m(op, reg, mem) \
-	__asm__ __volatile__ (#op " %%" #reg ", %0" \
-				: "=m" (mem) \
-				: /* nothing */)
-
-#define	mmx_r2r(op, regs, regd) \
-	__asm__ __volatile__ (#op " %" #regs ", %" #regd)
-
-#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	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	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	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	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	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	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	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	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	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	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	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	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)
-
-/* 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_fetch(mem, hint) \
-	__asm__ __volatile__ ("prefetch" #hint " %0" \
-				: /* nothing */ \
-				: "m" (mem))
-
-#define	maskmovq(regs, maskreg)	mmx_r2ri(maskmovq, regs, maskreg)
-
-#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	pextrw_r2r(mmreg, reg, imm)	mmx_r2ri(pextrw, mmreg, reg, 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	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	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	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	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	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	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	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	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/echo/oslec.h b/drivers/staging/echo/oslec.h
index bad8523..f417536 100644
--- a/drivers/staging/echo/oslec.h
+++ b/drivers/staging/echo/oslec.h
@@ -27,8 +27,6 @@
 #ifndef __OSLEC_H
 #define __OSLEC_H
 
-/* TODO: document interface */
-
 /* Mask bits for the adaption mode */
 #define ECHO_CAN_USE_ADAPTION	0x01
 #define ECHO_CAN_USE_NLP	0x02
@@ -38,49 +36,59 @@
 #define ECHO_CAN_USE_RX_HPF	0x20
 #define ECHO_CAN_DISABLE	0x40
 
-/*!
-    G.168 echo canceller descriptor. This defines the working state for a line
-    echo canceller.
-*/
+/**
+ * oslec_state: G.168 echo canceller descriptor.
+ *
+ * This defines the working state for a line echo canceller.
+ */
 struct oslec_state;
 
-/*! Create a voice echo canceller context.
-    \param len The length of the canceller, in samples.
-    \return The new canceller context, or NULL if the canceller could not be created.
-*/
+/**
+ * oslec_create - Create a voice echo canceller context.
+ * @len: The length of the canceller, in samples.
+ * @return: The new canceller context, or NULL if the canceller could not be
+ * created.
+ */
 struct oslec_state *oslec_create(int len, int adaption_mode);
 
-/*! Free a voice echo canceller context.
-    \param ec The echo canceller context.
-*/
+/**
+ * oslec_free - Free a voice echo canceller context.
+ * @ec: The echo canceller context.
+ */
 void oslec_free(struct oslec_state *ec);
 
-/*! Flush (reinitialise) a voice echo canceller context.
-    \param ec The echo canceller context.
-*/
+/**
+ * oslec_flush - Flush (reinitialise) a voice echo canceller context.
+ * @ec: The echo canceller context.
+ */
 void oslec_flush(struct oslec_state *ec);
 
-/*! Set the adaption mode of a voice echo canceller context.
-    \param ec The echo canceller context.
-    \param adapt The mode.
-*/
+/**
+ * oslec_adaption_mode - set the adaption mode of a voice echo canceller context.
+ * @ec The echo canceller context.
+ * @adaption_mode: The mode.
+ */
 void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode);
 
 void oslec_snapshot(struct oslec_state *ec);
 
-/*! Process a sample through a voice echo canceller.
-    \param ec The echo canceller context.
-    \param tx The transmitted audio sample.
-    \param rx The received audio sample.
-    \return The clean (echo cancelled) received sample.
-*/
+/**
+ * oslec_update: Process a sample through a voice echo canceller.
+ * @ec: The echo canceller context.
+ * @tx: The transmitted audio sample.
+ * @rx: The received audio sample.
+ *
+ * The return value is the clean (echo cancelled) received sample.
+ */
 int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx);
 
-/*! Process to high pass filter the tx signal.
-    \param ec The echo canceller context.
-    \param tx The transmitted auio sample.
-    \return The HP filtered transmit sample, send this to your D/A.
-*/
+/**
+ * oslec_hpf_tx: Process to high pass filter the tx signal.
+ * @ec: The echo canceller context.
+ * @tx: The transmitted auio sample.
+ *
+ * The return value is the HP filtered transmit sample, send this to your D/A.
+ */
 int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx);
 
 #endif /* __OSLEC_H */
diff --git a/drivers/staging/epl/Benchmark.h b/drivers/staging/epl/Benchmark.h
deleted file mode 100644
index 4cc01bd..0000000
--- a/drivers/staging/epl/Benchmark.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  header file for benchmarking
-
-  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: Benchmark.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    ...
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/08/16 d.k.:  start of implementation
-
-****************************************************************************/
-
-#ifndef _BENCHMARK_H_
-#define _BENCHMARK_H_
-
-#include "global.h"
-
-#include <linux/kernel.h>
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#include <asm/m5485gpio.h>
-
-#define BENCHMARK_SET(x)    MCF_GPIO_PODR_PCIBG |= (1 << (x))	// (x+1)
-#define BENCHMARK_RESET(x)  MCF_GPIO_PODR_PCIBG &= ~(1 << (x))	// (x+1)
-#define BENCHMARK_TOGGLE(x) MCF_GPIO_PODR_PCIBR ^= (1 << (x - 5))
-#else
-#undef BENCHMARK_MODULES
-#define BENCHMARK_MODULES           0x00000000
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef BENCHMARK_MODULES
-#define BENCHMARK_MODULES                   0x00000000
-#endif
-
-#define BENCHMARK_MOD_01                    0x00000001
-#define BENCHMARK_MOD_02                    0x00000002
-#define BENCHMARK_MOD_03                    0x00000004
-#define BENCHMARK_MOD_04                    0x00000008
-#define BENCHMARK_MOD_05                    0x00000010
-#define BENCHMARK_MOD_06                    0x00000020
-#define BENCHMARK_MOD_07                    0x00000040
-#define BENCHMARK_MOD_08                    0x00000080
-#define BENCHMARK_MOD_09                    0x00000100
-#define BENCHMARK_MOD_10                    0x00000200
-#define BENCHMARK_MOD_11                    0x00000400
-#define BENCHMARK_MOD_12                    0x00000800
-#define BENCHMARK_MOD_13                    0x00001000
-#define BENCHMARK_MOD_14                    0x00002000
-#define BENCHMARK_MOD_15                    0x00004000
-#define BENCHMARK_MOD_16                    0x00008000
-#define BENCHMARK_MOD_17                    0x00010000
-#define BENCHMARK_MOD_18                    0x00020000
-#define BENCHMARK_MOD_19                    0x00040000
-#define BENCHMARK_MOD_20                    0x00080000
-#define BENCHMARK_MOD_21                    0x00100000
-#define BENCHMARK_MOD_22                    0x00200000
-#define BENCHMARK_MOD_23                    0x00400000
-#define BENCHMARK_MOD_24                    0x00800000
-#define BENCHMARK_MOD_25                    0x01000000
-#define BENCHMARK_MOD_26                    0x02000000
-#define BENCHMARK_MOD_27                    0x04000000
-#define BENCHMARK_MOD_28                    0x08000000
-#define BENCHMARK_MOD_29                    0x10000000
-#define BENCHMARK_MOD_30                    0x20000000
-#define BENCHMARK_MOD_31                    0x40000000
-#define BENCHMARK_MOD_32                    0x80000000
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_01)
-#define BENCHMARK_MOD_01_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_01_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_01_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_01_SET(x)
-#define BENCHMARK_MOD_01_RESET(x)
-#define BENCHMARK_MOD_01_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_02)
-#define BENCHMARK_MOD_02_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_02_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_02_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_02_SET(x)
-#define BENCHMARK_MOD_02_RESET(x)
-#define BENCHMARK_MOD_02_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_03)
-#define BENCHMARK_MOD_03_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_03_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_03_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_03_SET(x)
-#define BENCHMARK_MOD_03_RESET(x)
-#define BENCHMARK_MOD_03_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_04)
-#define BENCHMARK_MOD_04_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_04_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_04_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_04_SET(x)
-#define BENCHMARK_MOD_04_RESET(x)
-#define BENCHMARK_MOD_04_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_05)
-#define BENCHMARK_MOD_05_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_05_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_05_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_05_SET(x)
-#define BENCHMARK_MOD_05_RESET(x)
-#define BENCHMARK_MOD_05_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_06)
-#define BENCHMARK_MOD_06_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_06_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_06_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_06_SET(x)
-#define BENCHMARK_MOD_06_RESET(x)
-#define BENCHMARK_MOD_06_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_07)
-#define BENCHMARK_MOD_07_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_07_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_07_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_07_SET(x)
-#define BENCHMARK_MOD_07_RESET(x)
-#define BENCHMARK_MOD_07_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_08)
-#define BENCHMARK_MOD_08_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_08_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_08_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_08_SET(x)
-#define BENCHMARK_MOD_08_RESET(x)
-#define BENCHMARK_MOD_08_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_09)
-#define BENCHMARK_MOD_09_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_09_RESET(x)       BENCHMARK_RESET(x)
-#define BENCHMARK_MOD_09_TOGGLE(x)      BENCHMARK_TOGGLE(x)
-#else
-#define BENCHMARK_MOD_09_SET(x)
-#define BENCHMARK_MOD_09_RESET(x)
-#define BENCHMARK_MOD_09_TOGGLE(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_10)
-#define BENCHMARK_MOD_10_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_10_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_10_SET(x)
-#define BENCHMARK_MOD_10_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_11)
-#define BENCHMARK_MOD_11_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_11_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_11_SET(x)
-#define BENCHMARK_MOD_11_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_12)
-#define BENCHMARK_MOD_12_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_12_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_12_SET(x)
-#define BENCHMARK_MOD_12_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_13)
-#define BENCHMARK_MOD_13_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_13_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_13_SET(x)
-#define BENCHMARK_MOD_13_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_14)
-#define BENCHMARK_MOD_14_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_14_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_14_SET(x)
-#define BENCHMARK_MOD_14_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_15)
-#define BENCHMARK_MOD_15_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_15_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_15_SET(x)
-#define BENCHMARK_MOD_15_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_16)
-#define BENCHMARK_MOD_16_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_16_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_16_SET(x)
-#define BENCHMARK_MOD_16_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_17)
-#define BENCHMARK_MOD_17_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_17_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_17_SET(x)
-#define BENCHMARK_MOD_17_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_18)
-#define BENCHMARK_MOD_18_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_18_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_18_SET(x)
-#define BENCHMARK_MOD_18_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_19)
-#define BENCHMARK_MOD_19_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_19_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_19_SET(x)
-#define BENCHMARK_MOD_19_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_20)
-#define BENCHMARK_MOD_20_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_20_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_20_SET(x)
-#define BENCHMARK_MOD_20_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_21)
-#define BENCHMARK_MOD_21_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_21_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_21_SET(x)
-#define BENCHMARK_MOD_21_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_22)
-#define BENCHMARK_MOD_22_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_22_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_22_SET(x)
-#define BENCHMARK_MOD_22_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_23)
-#define BENCHMARK_MOD_23_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_23_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_23_SET(x)
-#define BENCHMARK_MOD_23_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_24)
-#define BENCHMARK_MOD_24_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_24_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_24_SET(x)
-#define BENCHMARK_MOD_24_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_25)
-#define BENCHMARK_MOD_25_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_25_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_25_SET(x)
-#define BENCHMARK_MOD_25_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_26)
-#define BENCHMARK_MOD_26_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_26_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_26_SET(x)
-#define BENCHMARK_MOD_26_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_27)
-#define BENCHMARK_MOD_27_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_27_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_27_SET(x)
-#define BENCHMARK_MOD_27_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_28)
-#define BENCHMARK_MOD_28_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_28_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_28_SET(x)
-#define BENCHMARK_MOD_28_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_29)
-#define BENCHMARK_MOD_29_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_29_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_29_SET(x)
-#define BENCHMARK_MOD_29_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_30)
-#define BENCHMARK_MOD_30_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_30_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_30_SET(x)
-#define BENCHMARK_MOD_30_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_31)
-#define BENCHMARK_MOD_31_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_31_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_31_SET(x)
-#define BENCHMARK_MOD_31_RESET(x)
-#endif
-
-#if (BENCHMARK_MODULES & BENCHMARK_MOD_32)
-#define BENCHMARK_MOD_32_SET(x)         BENCHMARK_SET(x)
-#define BENCHMARK_MOD_32_RESET(x)       BENCHMARK_RESET(x)
-#else
-#define BENCHMARK_MOD_32_SET(x)
-#define BENCHMARK_MOD_32_RESET(x)
-#endif
-
-//---------------------------------------------------------------------------
-// modul global types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-#endif // _BENCHMARK_H_
diff --git a/drivers/staging/epl/Debug.h b/drivers/staging/epl/Debug.h
deleted file mode 100644
index 851a222..0000000
--- a/drivers/staging/epl/Debug.h
+++ /dev/null
@@ -1,694 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  Debug interface
-
-  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: Debug.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    ...
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-****************************************************************************/
-
-#ifndef _DEBUG_H_
-#define _DEBUG_H_
-
-#include "global.h"
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// global const defines
-//---------------------------------------------------------------------------
-
-// These definitions are important for level-debug traces.
-// A macro DEBUG_GLB_LVL() defines the current debug-level using following bis.
-// If the corresponding bit is set then trace message will be printed out
-// (only if NDEBUG is not defined). The upper debug-levels are reserved for
-// the debug-levels ALWAYS, ERROR and ASSERT.
-#define DEBUG_LVL_01                    0x00000001
-#define DEBUG_LVL_02                    0x00000002
-#define DEBUG_LVL_03                    0x00000004
-#define DEBUG_LVL_04                    0x00000008
-#define DEBUG_LVL_05                    0x00000010
-#define DEBUG_LVL_06                    0x00000020
-#define DEBUG_LVL_07                    0x00000040
-#define DEBUG_LVL_08                    0x00000080
-#define DEBUG_LVL_09                    0x00000100
-#define DEBUG_LVL_10                    0x00000200
-#define DEBUG_LVL_11                    0x00000400
-#define DEBUG_LVL_12                    0x00000800
-#define DEBUG_LVL_13                    0x00001000
-#define DEBUG_LVL_14                    0x00002000
-#define DEBUG_LVL_15                    0x00004000
-#define DEBUG_LVL_16                    0x00008000
-#define DEBUG_LVL_17                    0x00010000
-#define DEBUG_LVL_18                    0x00020000
-#define DEBUG_LVL_19                    0x00040000
-#define DEBUG_LVL_20                    0x00080000
-#define DEBUG_LVL_21                    0x00100000
-#define DEBUG_LVL_22                    0x00200000
-#define DEBUG_LVL_23                    0x00400000
-#define DEBUG_LVL_24                    0x00800000
-#define DEBUG_LVL_25                    0x01000000
-#define DEBUG_LVL_26                    0x02000000
-#define DEBUG_LVL_27                    0x04000000
-#define DEBUG_LVL_28                    0x08000000
-#define DEBUG_LVL_29                    0x10000000
-#define DEBUG_LVL_ASSERT                0x20000000
-#define DEBUG_LVL_ERROR                 0x40000000
-#define DEBUG_LVL_ALWAYS                0x80000000
-
-//---------------------------------------------------------------------------
-// global types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// global vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// global function prototypes
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// global macros
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// this macro defines a version string
-
-
-//---------------------------------------------------------------------------
-// this macro defines a build info string (e.g. for using in printf())
-#define DEBUG_MAKE_BUILD_INFO(prefix,product,prodid,descr,verstr,author) "\n" \
-    prefix "***************************************************\n" \
-    prefix "Project:   " product ", " prodid                  "\n" \
-    prefix "Descript.: " descr                                "\n" \
-    prefix "Author:    " author                               "\n" \
-    prefix "Date:      " __DATE__                             "\n" \
-    prefix "Version:   " verstr                               "\n" \
-    prefix "***************************************************\n\n"
-
-//---------------------------------------------------------------------------
-// The default debug-level is: ERROR and ALWAYS.
-// You can define an other debug-level in project settings.
-#ifndef DEF_DEBUG_LVL
-#define DEF_DEBUG_LVL                   (DEBUG_LVL_ALWAYS | DEBUG_LVL_ERROR)
-#endif
-#ifndef DEBUG_GLB_LVL
-#define DEBUG_GLB_LVL()                 (DEF_DEBUG_LVL)
-#endif
-
-//---------------------------------------------------------------------------
-    // At microcontrollers we do reduce the memory usage by deleting DEBUG_TRACE-lines
-    // (compiler does delete the lines).
-    //
-    // Here the parameter 'lvl' can only be used with one debug-level.
-    //
-    // Example: DEBUG_TRACE1(DEBUG_LVL_ERROR, "error code %d", dwRet);
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_ALWAYS)
-#define DEBUG_LVL_ALWAYS_TRACE0(str)                TRACE0(str)
-#define DEBUG_LVL_ALWAYS_TRACE1(str,p1)             TRACE1(str,p1)
-#define DEBUG_LVL_ALWAYS_TRACE2(str,p1,p2)          TRACE2(str,p1,p2)
-#define DEBUG_LVL_ALWAYS_TRACE3(str,p1,p2,p3)       TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_ALWAYS_TRACE4(str,p1,p2,p3,p4)    TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_ALWAYS_TRACE0(str)
-#define DEBUG_LVL_ALWAYS_TRACE1(str,p1)
-#define DEBUG_LVL_ALWAYS_TRACE2(str,p1,p2)
-#define DEBUG_LVL_ALWAYS_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_ALWAYS_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_ERROR)
-#define DEBUG_LVL_ERROR_TRACE0(str)                 TRACE0(str)
-#define DEBUG_LVL_ERROR_TRACE1(str,p1)              TRACE1(str,p1)
-#define DEBUG_LVL_ERROR_TRACE2(str,p1,p2)           TRACE2(str,p1,p2)
-#define DEBUG_LVL_ERROR_TRACE3(str,p1,p2,p3)        TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_ERROR_TRACE4(str,p1,p2,p3,p4)     TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_ERROR_TRACE0(str)
-#define DEBUG_LVL_ERROR_TRACE1(str,p1)
-#define DEBUG_LVL_ERROR_TRACE2(str,p1,p2)
-#define DEBUG_LVL_ERROR_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_ERROR_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)
-#define DEBUG_LVL_ASSERT_TRACE0(str)                TRACE0(str)
-#define DEBUG_LVL_ASSERT_TRACE1(str,p1)             TRACE1(str,p1)
-#define DEBUG_LVL_ASSERT_TRACE2(str,p1,p2)          TRACE2(str,p1,p2)
-#define DEBUG_LVL_ASSERT_TRACE3(str,p1,p2,p3)       TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_ASSERT_TRACE4(str,p1,p2,p3,p4)    TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_ASSERT_TRACE0(str)
-#define DEBUG_LVL_ASSERT_TRACE1(str,p1)
-#define DEBUG_LVL_ASSERT_TRACE2(str,p1,p2)
-#define DEBUG_LVL_ASSERT_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_ASSERT_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_29)
-#define DEBUG_LVL_29_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_29_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_29_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_29_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_29_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_29_TRACE0(str)
-#define DEBUG_LVL_29_TRACE1(str,p1)
-#define DEBUG_LVL_29_TRACE2(str,p1,p2)
-#define DEBUG_LVL_29_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_29_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_28)
-#define DEBUG_LVL_28_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_28_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_28_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_28_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_28_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_28_TRACE0(str)
-#define DEBUG_LVL_28_TRACE1(str,p1)
-#define DEBUG_LVL_28_TRACE2(str,p1,p2)
-#define DEBUG_LVL_28_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_28_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_27)
-#define DEBUG_LVL_27_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_27_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_27_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_27_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_27_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_27_TRACE0(str)
-#define DEBUG_LVL_27_TRACE1(str,p1)
-#define DEBUG_LVL_27_TRACE2(str,p1,p2)
-#define DEBUG_LVL_27_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_27_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_26)
-#define DEBUG_LVL_26_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_26_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_26_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_26_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_26_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_26_TRACE0(str)
-#define DEBUG_LVL_26_TRACE1(str,p1)
-#define DEBUG_LVL_26_TRACE2(str,p1,p2)
-#define DEBUG_LVL_26_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_26_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_25)
-#define DEBUG_LVL_25_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_25_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_25_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_25_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_25_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_25_TRACE0(str)
-#define DEBUG_LVL_25_TRACE1(str,p1)
-#define DEBUG_LVL_25_TRACE2(str,p1,p2)
-#define DEBUG_LVL_25_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_25_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_24)
-#define DEBUG_LVL_24_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_24_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_24_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_24_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_24_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_24_TRACE0(str)
-#define DEBUG_LVL_24_TRACE1(str,p1)
-#define DEBUG_LVL_24_TRACE2(str,p1,p2)
-#define DEBUG_LVL_24_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_24_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_23)
-#define DEBUG_LVL_23_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_23_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_23_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_23_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_23_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_23_TRACE0(str)
-#define DEBUG_LVL_23_TRACE1(str,p1)
-#define DEBUG_LVL_23_TRACE2(str,p1,p2)
-#define DEBUG_LVL_23_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_23_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_22)
-#define DEBUG_LVL_22_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_22_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_22_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_22_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_22_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_22_TRACE0(str)
-#define DEBUG_LVL_22_TRACE1(str,p1)
-#define DEBUG_LVL_22_TRACE2(str,p1,p2)
-#define DEBUG_LVL_22_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_22_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_21)
-#define DEBUG_LVL_21_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_21_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_21_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_21_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_21_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_21_TRACE0(str)
-#define DEBUG_LVL_21_TRACE1(str,p1)
-#define DEBUG_LVL_21_TRACE2(str,p1,p2)
-#define DEBUG_LVL_21_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_21_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_20)
-#define DEBUG_LVL_20_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_20_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_20_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_20_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_20_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_20_TRACE0(str)
-#define DEBUG_LVL_20_TRACE1(str,p1)
-#define DEBUG_LVL_20_TRACE2(str,p1,p2)
-#define DEBUG_LVL_20_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_20_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_19)
-#define DEBUG_LVL_19_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_19_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_19_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_19_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_19_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_19_TRACE0(str)
-#define DEBUG_LVL_19_TRACE1(str,p1)
-#define DEBUG_LVL_19_TRACE2(str,p1,p2)
-#define DEBUG_LVL_19_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_19_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_18)
-#define DEBUG_LVL_18_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_18_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_18_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_18_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_18_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_18_TRACE0(str)
-#define DEBUG_LVL_18_TRACE1(str,p1)
-#define DEBUG_LVL_18_TRACE2(str,p1,p2)
-#define DEBUG_LVL_18_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_18_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_17)
-#define DEBUG_LVL_17_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_17_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_17_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_17_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_17_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_17_TRACE0(str)
-#define DEBUG_LVL_17_TRACE1(str,p1)
-#define DEBUG_LVL_17_TRACE2(str,p1,p2)
-#define DEBUG_LVL_17_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_17_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_16)
-#define DEBUG_LVL_16_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_16_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_16_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_16_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_16_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_16_TRACE0(str)
-#define DEBUG_LVL_16_TRACE1(str,p1)
-#define DEBUG_LVL_16_TRACE2(str,p1,p2)
-#define DEBUG_LVL_16_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_16_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_15)
-#define DEBUG_LVL_15_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_15_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_15_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_15_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_15_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_15_TRACE0(str)
-#define DEBUG_LVL_15_TRACE1(str,p1)
-#define DEBUG_LVL_15_TRACE2(str,p1,p2)
-#define DEBUG_LVL_15_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_15_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_14)
-#define DEBUG_LVL_14_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_14_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_14_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_14_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_14_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_14_TRACE0(str)
-#define DEBUG_LVL_14_TRACE1(str,p1)
-#define DEBUG_LVL_14_TRACE2(str,p1,p2)
-#define DEBUG_LVL_14_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_14_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_13)
-#define DEBUG_LVL_13_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_13_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_13_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_13_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_13_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_13_TRACE0(str)
-#define DEBUG_LVL_13_TRACE1(str,p1)
-#define DEBUG_LVL_13_TRACE2(str,p1,p2)
-#define DEBUG_LVL_13_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_13_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_12)
-#define DEBUG_LVL_12_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_12_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_12_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_12_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_12_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_12_TRACE0(str)
-#define DEBUG_LVL_12_TRACE1(str,p1)
-#define DEBUG_LVL_12_TRACE2(str,p1,p2)
-#define DEBUG_LVL_12_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_12_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_11)
-#define DEBUG_LVL_11_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_11_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_11_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_11_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_11_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_11_TRACE0(str)
-#define DEBUG_LVL_11_TRACE1(str,p1)
-#define DEBUG_LVL_11_TRACE2(str,p1,p2)
-#define DEBUG_LVL_11_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_11_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_10)
-#define DEBUG_LVL_10_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_10_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_10_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_10_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_10_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_10_TRACE0(str)
-#define DEBUG_LVL_10_TRACE1(str,p1)
-#define DEBUG_LVL_10_TRACE2(str,p1,p2)
-#define DEBUG_LVL_10_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_10_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_09)
-#define DEBUG_LVL_09_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_09_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_09_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_09_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_09_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_09_TRACE0(str)
-#define DEBUG_LVL_09_TRACE1(str,p1)
-#define DEBUG_LVL_09_TRACE2(str,p1,p2)
-#define DEBUG_LVL_09_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_09_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_08)
-#define DEBUG_LVL_08_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_08_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_08_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_08_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_08_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_08_TRACE0(str)
-#define DEBUG_LVL_08_TRACE1(str,p1)
-#define DEBUG_LVL_08_TRACE2(str,p1,p2)
-#define DEBUG_LVL_08_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_08_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_07)
-#define DEBUG_LVL_07_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_07_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_07_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_07_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_07_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_07_TRACE0(str)
-#define DEBUG_LVL_07_TRACE1(str,p1)
-#define DEBUG_LVL_07_TRACE2(str,p1,p2)
-#define DEBUG_LVL_07_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_07_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_06)
-#define DEBUG_LVL_06_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_06_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_06_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_06_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_06_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_06_TRACE0(str)
-#define DEBUG_LVL_06_TRACE1(str,p1)
-#define DEBUG_LVL_06_TRACE2(str,p1,p2)
-#define DEBUG_LVL_06_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_06_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_05)
-#define DEBUG_LVL_05_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_05_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_05_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_05_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_05_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_05_TRACE0(str)
-#define DEBUG_LVL_05_TRACE1(str,p1)
-#define DEBUG_LVL_05_TRACE2(str,p1,p2)
-#define DEBUG_LVL_05_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_05_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_04)
-#define DEBUG_LVL_04_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_04_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_04_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_04_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_04_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_04_TRACE0(str)
-#define DEBUG_LVL_04_TRACE1(str,p1)
-#define DEBUG_LVL_04_TRACE2(str,p1,p2)
-#define DEBUG_LVL_04_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_04_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_03)
-#define DEBUG_LVL_03_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_03_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_03_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_03_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_03_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_03_TRACE0(str)
-#define DEBUG_LVL_03_TRACE1(str,p1)
-#define DEBUG_LVL_03_TRACE2(str,p1,p2)
-#define DEBUG_LVL_03_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_03_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_02)
-#define DEBUG_LVL_02_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_02_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_02_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_02_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_02_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_02_TRACE0(str)
-#define DEBUG_LVL_02_TRACE1(str,p1)
-#define DEBUG_LVL_02_TRACE2(str,p1,p2)
-#define DEBUG_LVL_02_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_02_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#if (DEBUG_GLB_LVL() & DEBUG_LVL_01)
-#define DEBUG_LVL_01_TRACE0(str)                    TRACE0(str)
-#define DEBUG_LVL_01_TRACE1(str,p1)                 TRACE1(str,p1)
-#define DEBUG_LVL_01_TRACE2(str,p1,p2)              TRACE2(str,p1,p2)
-#define DEBUG_LVL_01_TRACE3(str,p1,p2,p3)           TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_01_TRACE4(str,p1,p2,p3,p4)        TRACE4(str,p1,p2,p3,p4)
-#else
-#define DEBUG_LVL_01_TRACE0(str)
-#define DEBUG_LVL_01_TRACE1(str,p1)
-#define DEBUG_LVL_01_TRACE2(str,p1,p2)
-#define DEBUG_LVL_01_TRACE3(str,p1,p2,p3)
-#define DEBUG_LVL_01_TRACE4(str,p1,p2,p3,p4)
-#endif
-
-#define DEBUG_TRACE0(lvl,str)                           lvl##_TRACE0(str)
-#define DEBUG_TRACE1(lvl,str,p1)                        lvl##_TRACE1(str,p1)
-#define DEBUG_TRACE2(lvl,str,p1,p2)                     lvl##_TRACE2(str,p1,p2)
-#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)
-
-//---------------------------------------------------------------------------
-// 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))
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-	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, (u8 *)(ptr), (u16)(siz));
-#else
-
-#define DEBUG_DUMP_DATA(lvl,str,ptr,siz)
-
-#endif
-
-//---------------------------------------------------------------------------
-// The macro DEBUG_ASSERT() can be used to print out an error string if the
-// parametered expresion does not result TRUE.
-// NOTE: If DEBUG_KEEP_ASSERT is defined, then DEBUG_ASSERT-line will not be
-//       deleted from compiler (in release version too).
-#if !defined (NDEBUG) || defined (DEBUG_KEEP_ASSERT)
-
-	// For microcontrollers process will be stopped using endless loop.
-
-#define DEBUG_ASSERT0(expr,str)         if (!(expr )) { \
-                                                    DEBUG_LVL_ASSERT_TRACE3 ( \
-                                                        "Assertion failed: line %d file '%s'\n" \
-                                                        "    -> '%s'\n", __LINE__, __FILE__, str); \
-                                                    while (1); }
-
-#define DEBUG_ASSERT1(expr,str,p1)      if (!(expr )) { \
-                                                    DEBUG_LVL_ASSERT_TRACE4 ( \
-                                                        "Assertion failed: line %d file '%s'\n" \
-                                                        "    -> '%s'\n" \
-                                                        "    -> 0x%08lX\n", __LINE__, __FILE__, str, (u32) p1); \
-                                                    while (1); }
-
-
-#else
-
-#define DEBUG_ASSERT0(expr,str)
-#define DEBUG_ASSERT1(expr,str,p1)
-
-#endif
-
-//---------------------------------------------------------------------------
-// The macro DEBUG_ONLY() implements code, if NDEBUG is not defined.
-#if !defined (DEBUG_ONLY)
-#if !defined (NDEBUG)
-
-#define DEBUG_ONLY(expr)    expr
-
-#else
-
-#define DEBUG_ONLY(expr)
-
-#endif
-#endif
-
-#endif // _DEBUG_H_
diff --git a/drivers/staging/epl/Edrv8139.c b/drivers/staging/epl/Edrv8139.c
deleted file mode 100644
index 44e3f7b..0000000
--- a/drivers/staging/epl/Edrv8139.c
+++ /dev/null
@@ -1,1246 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  Ethernet driver for Realtek RTL8139 chips
-                except the RTL8139C+, because it has a different
-                Tx descriptor handling.
-
-  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: Edrv8139.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.10 $  $Date: 2008/11/21 09:00:38 $
-
-                $State: Exp $
-
-                Build Environment:
-                Dev C++ and GNU-Compiler for m68k
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2008/02/05 d.k.:   start of implementation
-
-****************************************************************************/
-
-#include "global.h"
-#include "EplInc.h"
-#include "edrv.h"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/major.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/atomic.h>
-#include <asm/irq.h>
-#include <linux/sched.h>
-#include <linux/delay.h>
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-// Buffer handling:
-// All buffers are created statically (i.e. at compile time resp. at
-// initialisation via kmalloc() ) and not dynamically on request (i.e. via
-// EdrvAllocTxMsgBuffer().
-// EdrvAllocTxMsgBuffer() searches for an unused buffer which is large enough.
-// EdrvInit() may allocate some buffers with sizes less than maximum frame
-// size (i.e. 1514 bytes), e.g. for SoC, SoA, StatusResponse, IdentResponse,
-// NMT requests / commands. The less the size of the buffer the less the
-// number of the buffer.
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef EDRV_MAX_TX_BUFFERS
-#define EDRV_MAX_TX_BUFFERS     20
-#endif
-
-#define EDRV_MAX_FRAME_SIZE     0x600
-
-#define EDRV_RX_BUFFER_SIZE     0x8610	// 32 kB + 16 Byte + 1,5 kB (WRAP is enabled)
-#define EDRV_RX_BUFFER_LENGTH   (EDRV_RX_BUFFER_SIZE & 0xF800)	// buffer size cut down to 2 kB alignment
-
-#define EDRV_TX_BUFFER_SIZE     (EDRV_MAX_TX_BUFFERS * EDRV_MAX_FRAME_SIZE)	// n * (MTU + 14 + 4)
-
-#define DRV_NAME                "epl"
-
-#define EDRV_REGW_INT_MASK      0x3C	// interrupt mask register
-#define EDRV_REGW_INT_STATUS    0x3E	// interrupt status register
-#define EDRV_REGW_INT_ROK       0x0001	// Receive OK interrupt
-#define EDRV_REGW_INT_RER       0x0002	// Receive error interrupt
-#define EDRV_REGW_INT_TOK       0x0004	// Transmit OK interrupt
-#define EDRV_REGW_INT_TER       0x0008	// Transmit error interrupt
-#define EDRV_REGW_INT_RXOVW     0x0010	// Rx buffer overflow interrupt
-#define EDRV_REGW_INT_PUN       0x0020	// Packet underrun/ link change interrupt
-#define EDRV_REGW_INT_FOVW      0x0040	// Rx FIFO overflow interrupt
-#define EDRV_REGW_INT_LENCHG    0x2000	// Cable length change interrupt
-#define EDRV_REGW_INT_TIMEOUT   0x4000	// Time out interrupt
-#define EDRV_REGW_INT_SERR      0x8000	// System error interrupt
-#define EDRV_REGW_INT_MASK_DEF  (EDRV_REGW_INT_ROK \
-                                 | EDRV_REGW_INT_RER \
-                                 | EDRV_REGW_INT_TOK \
-                                 | EDRV_REGW_INT_TER \
-                                 | EDRV_REGW_INT_RXOVW \
-                                 | EDRV_REGW_INT_FOVW \
-                                 | EDRV_REGW_INT_PUN \
-                                 | EDRV_REGW_INT_TIMEOUT \
-                                 | EDRV_REGW_INT_SERR)	// default interrupt mask
-
-#define EDRV_REGB_COMMAND       0x37	// command register
-#define EDRV_REGB_COMMAND_RST   0x10
-#define EDRV_REGB_COMMAND_RE    0x08
-#define EDRV_REGB_COMMAND_TE    0x04
-#define EDRV_REGB_COMMAND_BUFE  0x01
-
-#define EDRV_REGB_CMD9346       0x50	// 93C46 command register
-#define EDRV_REGB_CMD9346_LOCK  0x00	// lock configuration registers
-#define EDRV_REGB_CMD9346_UNLOCK 0xC0	// unlock configuration registers
-
-#define EDRV_REGDW_RCR          0x44	// Rx configuration register
-#define EDRV_REGDW_RCR_NO_FTH   0x0000E000	// no receive FIFO threshold
-#define EDRV_REGDW_RCR_RBLEN32K 0x00001000	// 32 kB receive buffer
-#define EDRV_REGDW_RCR_MXDMAUNL 0x00000700	// unlimited maximum DMA burst size
-#define EDRV_REGDW_RCR_NOWRAP   0x00000080	// do not wrap frame at end of buffer
-#define EDRV_REGDW_RCR_AER      0x00000020	// accept error frames (CRC, alignment, collided)
-#define EDRV_REGDW_RCR_AR       0x00000010	// accept runt
-#define EDRV_REGDW_RCR_AB       0x00000008	// accept broadcast frames
-#define EDRV_REGDW_RCR_AM       0x00000004	// accept multicast frames
-#define EDRV_REGDW_RCR_APM      0x00000002	// accept physical match frames
-#define EDRV_REGDW_RCR_AAP      0x00000001	// accept all frames
-#define EDRV_REGDW_RCR_DEF      (EDRV_REGDW_RCR_NO_FTH \
-                                 | EDRV_REGDW_RCR_RBLEN32K \
-                                 | EDRV_REGDW_RCR_MXDMAUNL \
-                                 | EDRV_REGDW_RCR_NOWRAP \
-                                 | EDRV_REGDW_RCR_AB \
-                                 | EDRV_REGDW_RCR_AM \
-                                 | EDRV_REGDW_RCR_APM)	// default value
-
-#define EDRV_REGDW_TCR          0x40	// Tx configuration register
-#define EDRV_REGDW_TCR_VER_MASK 0x7CC00000	// mask for hardware version
-#define EDRV_REGDW_TCR_VER_C    0x74000000	// RTL8139C
-#define EDRV_REGDW_TCR_VER_D    0x74400000	// RTL8139D
-#define EDRV_REGDW_TCR_IFG96    0x03000000	// default interframe gap (960 ns)
-#define EDRV_REGDW_TCR_CRC      0x00010000	// disable appending of CRC by the controller
-#define EDRV_REGDW_TCR_MXDMAUNL 0x00000700	// maximum DMA burst size of 2048 b
-#define EDRV_REGDW_TCR_TXRETRY  0x00000000	// 16 retries
-#define EDRV_REGDW_TCR_DEF      (EDRV_REGDW_TCR_IFG96 \
-                                 | EDRV_REGDW_TCR_MXDMAUNL \
-                                 | EDRV_REGDW_TCR_TXRETRY)
-
-#define EDRV_REGW_MULINT        0x5C	// multiple interrupt select register
-
-#define EDRV_REGDW_MPC          0x4C	// missed packet counter register
-
-#define EDRV_REGDW_TSAD0        0x20	// Transmit start address of descriptor 0
-#define EDRV_REGDW_TSAD1        0x24	// Transmit start address of descriptor 1
-#define EDRV_REGDW_TSAD2        0x28	// Transmit start address of descriptor 2
-#define EDRV_REGDW_TSAD3        0x2C	// Transmit start address of descriptor 3
-#define EDRV_REGDW_TSD0         0x10	// Transmit status of descriptor 0
-#define EDRV_REGDW_TSD_CRS      0x80000000	// Carrier sense lost
-#define EDRV_REGDW_TSD_TABT     0x40000000	// Transmit Abort
-#define EDRV_REGDW_TSD_OWC      0x20000000	// Out of window collision
-#define EDRV_REGDW_TSD_TXTH_DEF 0x00020000	// Transmit FIFO threshold of 64 bytes
-#define EDRV_REGDW_TSD_TOK      0x00008000	// Transmit OK
-#define EDRV_REGDW_TSD_TUN      0x00004000	// Transmit FIFO underrun
-#define EDRV_REGDW_TSD_OWN      0x00002000	// Owner
-
-#define EDRV_REGDW_RBSTART      0x30	// Receive buffer start address
-
-#define EDRV_REGW_CAPR          0x38	// Current address of packet read
-
-#define EDRV_REGDW_IDR0         0x00	// ID register 0
-#define EDRV_REGDW_IDR4         0x04	// ID register 4
-
-#define EDRV_REGDW_MAR0         0x08	// Multicast address register 0
-#define EDRV_REGDW_MAR4         0x0C	// Multicast address register 4
-
-// defines for the status word in the receive buffer
-#define EDRV_RXSTAT_MAR         0x8000	// Multicast address received
-#define EDRV_RXSTAT_PAM         0x4000	// Physical address matched
-#define EDRV_RXSTAT_BAR         0x2000	// Broadcast address received
-#define EDRV_RXSTAT_ISE         0x0020	// Invalid symbol error
-#define EDRV_RXSTAT_RUNT        0x0010	// Runt packet received
-#define EDRV_RXSTAT_LONG        0x0008	// Long packet
-#define EDRV_RXSTAT_CRC         0x0004	// CRC error
-#define EDRV_RXSTAT_FAE         0x0002	// Frame alignment error
-#define EDRV_RXSTAT_ROK         0x0001	// Receive OK
-
-#define EDRV_REGDW_WRITE(dwReg, dwVal)  writel(dwVal, EdrvInstance_l.m_pIoAddr + dwReg)
-#define EDRV_REGW_WRITE(dwReg, wVal)    writew(wVal, EdrvInstance_l.m_pIoAddr + dwReg)
-#define EDRV_REGB_WRITE(dwReg, bVal)    writeb(bVal, EdrvInstance_l.m_pIoAddr + dwReg)
-#define EDRV_REGDW_READ(dwReg)          readl(EdrvInstance_l.m_pIoAddr + dwReg)
-#define EDRV_REGW_READ(dwReg)           readw(EdrvInstance_l.m_pIoAddr + dwReg)
-#define EDRV_REGB_READ(dwReg)           readb(EdrvInstance_l.m_pIoAddr + dwReg)
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-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
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-
-#define EDRV_COUNT_SEND                 TGT_DBG_SIGNAL_TRACE_POINT(2)
-#define EDRV_COUNT_TIMEOUT              TGT_DBG_SIGNAL_TRACE_POINT(3)
-#define EDRV_COUNT_PCI_ERR              TGT_DBG_SIGNAL_TRACE_POINT(4)
-#define EDRV_COUNT_TX                   TGT_DBG_SIGNAL_TRACE_POINT(5)
-#define EDRV_COUNT_RX                   TGT_DBG_SIGNAL_TRACE_POINT(6)
-#define EDRV_COUNT_LATECOLLISION        TGT_DBG_SIGNAL_TRACE_POINT(10)
-#define EDRV_COUNT_TX_COL_RL            TGT_DBG_SIGNAL_TRACE_POINT(11)
-#define EDRV_COUNT_TX_FUN               TGT_DBG_SIGNAL_TRACE_POINT(12)
-#define EDRV_COUNT_TX_ERR               TGT_DBG_SIGNAL_TRACE_POINT(13)
-#define EDRV_COUNT_RX_CRC               TGT_DBG_SIGNAL_TRACE_POINT(14)
-#define EDRV_COUNT_RX_ERR               TGT_DBG_SIGNAL_TRACE_POINT(15)
-#define EDRV_COUNT_RX_FOVW              TGT_DBG_SIGNAL_TRACE_POINT(16)
-#define EDRV_COUNT_RX_PUN               TGT_DBG_SIGNAL_TRACE_POINT(17)
-#define EDRV_COUNT_RX_FAE               TGT_DBG_SIGNAL_TRACE_POINT(18)
-#define EDRV_COUNT_RX_OVW               TGT_DBG_SIGNAL_TRACE_POINT(19)
-
-#define EDRV_TRACE_CAPR(x)              TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x06000000)
-#define EDRV_TRACE_RX_CRC(x)            TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0E000000)
-#define EDRV_TRACE_RX_ERR(x)            TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x0F000000)
-#define EDRV_TRACE_RX_PUN(x)            TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF) | 0x11000000)
-#define EDRV_TRACE(x)                   TGT_DBG_POST_TRACE_VALUE(((x) & 0xFFFF0000) | 0x0000FEC0)
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-/*
-typedef struct
-{
-    BOOL            m_fUsed;
-    unsigned int    m_uiSize;
-    MCD_bufDescFec *m_pBufDescr;
-
-} tEdrvTxBufferIntern;
-*/
-
-// Private structure
-typedef struct {
-	struct pci_dev *m_pPciDev;	// pointer to PCI device structure
-	void *m_pIoAddr;	// pointer to register space of Ethernet controller
-	u8 *m_pbRxBuf;	// pointer to Rx buffer
-	dma_addr_t m_pRxBufDma;
-	u8 *m_pbTxBuf;	// pointer to Tx buffer
-	dma_addr_t m_pTxBufDma;
-	BOOL m_afTxBufUsed[EDRV_MAX_TX_BUFFERS];
-	unsigned int m_uiCurTxDesc;
-
-	tEdrvInitParam m_InitParam;
-	tEdrvTxBuffer *m_pLastTransmittedTxBuffer;
-
-} tEdrvInstance;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static int EdrvInitOne(struct pci_dev *pPciDev,
-		       const struct pci_device_id *pId);
-
-static void EdrvRemoveOne(struct pci_dev *pPciDev);
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-// buffers and buffer descriptors and pointers
-
-static struct pci_device_id aEdrvPciTbl[] = {
-	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0,}
-};
-
-MODULE_DEVICE_TABLE(pci, aEdrvPciTbl);
-
-static tEdrvInstance EdrvInstance_l;
-
-static struct pci_driver EdrvDriver = {
-	.name = DRV_NAME,
-	.id_table = aEdrvPciTbl,
-	.probe = EdrvInitOne,
-	.remove = EdrvRemoveOne,
-};
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <edrv>                                              */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static u8 EdrvCalcHash(u8 * pbMAC_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvInit
-//
-// Description: function for init of the Ethernet controller
-//
-// Parameters:  pEdrvInitParam_p    = pointer to struct including the init-parameters
-//
-// Returns:     Errorcode           = kEplSuccessful
-//                                  = kEplNoResource
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p)
-{
-	tEplKernel Ret;
-	int iResult;
-
-	Ret = kEplSuccessful;
-
-	// clear instance structure
-	EPL_MEMSET(&EdrvInstance_l, 0, sizeof(EdrvInstance_l));
-
-	// save the init data
-	EdrvInstance_l.m_InitParam = *pEdrvInitParam_p;
-
-	// register PCI driver
-	iResult = pci_register_driver(&EdrvDriver);
-	if (iResult != 0) {
-		printk("%s pci_register_driver failed with %d\n", __func__,
-		       iResult);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-	if (EdrvInstance_l.m_pPciDev == NULL) {
-		printk("%s m_pPciDev=NULL\n", __func__);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-	// read MAC address from controller
-	printk("%s local MAC = ", __func__);
-	for (iResult = 0; iResult < 6; iResult++) {
-		pEdrvInitParam_p->m_abMyMacAddr[iResult] =
-		    EDRV_REGB_READ((EDRV_REGDW_IDR0 + iResult));
-		printk("%02X ",
-		       (unsigned int)pEdrvInitParam_p->m_abMyMacAddr[iResult]);
-	}
-	printk("\n");
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvShutdown
-//
-// Description: Shutdown the Ethernet controller
-//
-// Parameters:  void
-//
-// Returns:     Errorcode   = kEplSuccessful
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvShutdown(void)
-{
-
-	// unregister PCI driver
-	printk("%s calling pci_unregister_driver()\n", __func__);
-	pci_unregister_driver(&EdrvDriver);
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvDefineRxMacAddrEntry
-//
-// Description: Set a multicast entry into the Ethernet controller
-//
-// Parameters:  pbMacAddr_p     = pointer to multicast entry to set
-//
-// Returns:     Errorcode       = kEplSuccessful
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	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",
-        (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);
-		dwData |= 1 << (bHash - 32);
-		EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData);
-	} else {
-		dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
-		dwData |= 1 << bHash;
-		EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData);
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvUndefineRxMacAddrEntry
-//
-// Description: Reset a multicast entry in the Ethernet controller
-//
-// Parameters:  pbMacAddr_p     = pointer to multicast entry to reset
-//
-// Returns:     Errorcode       = kEplSuccessful
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	u32 dwData;
-	u8 bHash;
-
-	bHash = EdrvCalcHash(pbMacAddr_p);
-
-	if (bHash > 31) {
-		dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
-		dwData &= ~(1 << (bHash - 32));
-		EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, dwData);
-	} else {
-		dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
-		dwData &= ~(1 << bHash);
-		EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, dwData);
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvAllocTxMsgBuffer
-//
-// Description: Register a Tx-Buffer
-//
-// Parameters:  pBuffer_p   = pointer to Buffer structure
-//
-// Returns:     Errorcode   = kEplSuccessful
-//                          = kEplEdrvNoFreeBufEntry
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	u32 i;
-
-	if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE) {
-		Ret = kEplEdrvNoFreeBufEntry;
-		goto Exit;
-	}
-	// search a free Tx buffer with appropriate size
-	for (i = 0; i < EDRV_MAX_TX_BUFFERS; i++) {
-		if (EdrvInstance_l.m_afTxBufUsed[i] == FALSE) {
-			// free channel found
-			EdrvInstance_l.m_afTxBufUsed[i] = TRUE;
-			pBuffer_p->m_uiBufferNumber = i;
-			pBuffer_p->m_pbBuffer =
-			    EdrvInstance_l.m_pbTxBuf +
-			    (i * EDRV_MAX_FRAME_SIZE);
-			pBuffer_p->m_uiMaxBufferLen = EDRV_MAX_FRAME_SIZE;
-			break;
-		}
-	}
-	if (i >= EDRV_MAX_TX_BUFFERS) {
-		Ret = kEplEdrvNoFreeBufEntry;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvReleaseTxMsgBuffer
-//
-// Description: Register a Tx-Buffer
-//
-// Parameters:  pBuffer_p   = pointer to Buffer structure
-//
-// Returns:     Errorcode   = kEplSuccessful
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p)
-{
-	unsigned int uiBufferNumber;
-
-	uiBufferNumber = pBuffer_p->m_uiBufferNumber;
-
-	if (uiBufferNumber < EDRV_MAX_TX_BUFFERS) {
-		EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] = FALSE;
-	}
-
-	return kEplSuccessful;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvSendTxMsg
-//
-// Description: immediately starts the transmission of the buffer
-//
-// Parameters:  pBuffer_p   = buffer descriptor to transmit
-//
-// Returns:     Errorcode   = kEplSuccessful
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiBufferNumber;
-	u32 dwTemp;
-
-	uiBufferNumber = pBuffer_p->m_uiBufferNumber;
-
-	if ((uiBufferNumber >= EDRV_MAX_TX_BUFFERS)
-	    || (EdrvInstance_l.m_afTxBufUsed[uiBufferNumber] == FALSE)) {
-		Ret = kEplEdrvBufNotExisting;
-		goto Exit;
-	}
-
-	if (EdrvInstance_l.m_pLastTransmittedTxBuffer != NULL) {	// transmission is already active
-		Ret = kEplInvalidOperation;
-		dwTemp =
-		    EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
-				     (EdrvInstance_l.m_uiCurTxDesc *
-				      sizeof(u32))));
-		printk("%s InvOp TSD%u = 0x%08X", __func__,
-		       EdrvInstance_l.m_uiCurTxDesc, dwTemp);
-		printk("  Cmd = 0x%02X\n",
-		       (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
-		goto Exit;
-	}
-	// save pointer to buffer structure for TxHandler
-	EdrvInstance_l.m_pLastTransmittedTxBuffer = pBuffer_p;
-
-	EDRV_COUNT_SEND;
-
-	// pad with zeros if necessary, because controller does not do it
-	if (pBuffer_p->m_uiTxMsgLen < MIN_ETH_SIZE) {
-		EPL_MEMSET(pBuffer_p->m_pbBuffer + pBuffer_p->m_uiTxMsgLen, 0,
-			   MIN_ETH_SIZE - pBuffer_p->m_uiTxMsgLen);
-		pBuffer_p->m_uiTxMsgLen = MIN_ETH_SIZE;
-	}
-	// set DMA address of buffer
-	EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 +
-			  (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(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(u32))),
-			 (EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
-	dwTemp =
-	    EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
-			     (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;
-}
-
-#if 0
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvTxMsgReady
-//
-// Description: starts copying the buffer to the ethernet controller's FIFO
-//
-// Parameters:  pbBuffer_p - bufferdescriptor to transmit
-//
-// Returns:     Errorcode - kEplSuccessful
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvTxMsgReady(tEdrvTxBuffer * pBuffer_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiBufferNumber;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvTxMsgStart
-//
-// Description: starts transmission of the ethernet controller's FIFO
-//
-// Parameters:  pbBuffer_p - bufferdescriptor to transmit
-//
-// Returns:     Errorcode - kEplSuccessful
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	return Ret;
-}
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvReinitRx
-//
-// Description: reinitialize the Rx process, because of error
-//
-// Parameters:  void
-//
-// Returns:     void
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static void EdrvReinitRx(void)
-{
-	u8 bCmd;
-
-	// simply switch off and on the receiver
-	// this will reset the CAPR register
-	bCmd = EDRV_REGB_READ(EDRV_REGB_COMMAND);
-	EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (bCmd & ~EDRV_REGB_COMMAND_RE));
-	EDRV_REGB_WRITE(EDRV_REGB_COMMAND, bCmd);
-
-	// set receive configuration register
-	EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF);
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:     EdrvInterruptHandler
-//
-// Description:  interrupt handler
-//
-// Parameters:   void
-//
-// Returns:      void
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if 0
-void EdrvInterruptHandler(void)
-{
-}
-#endif
-
-static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p)
-{
-//    EdrvInterruptHandler();
-	tEdrvRxBuffer RxBuffer;
-	tEdrvTxBuffer *pTxBuffer;
-	u16 wStatus;
-	u32 dwTxStatus;
-	u32 dwRxStatus;
-	u16 wCurRx;
-	u8 *pbRxBuf;
-	unsigned int uiLength;
-	int iHandled = IRQ_HANDLED;
-
-//    printk("¤");
-
-	// read the interrupt status
-	wStatus = EDRV_REGW_READ(EDRV_REGW_INT_STATUS);
-
-	// acknowledge the interrupts
-	EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS, wStatus);
-
-	if (wStatus == 0) {
-		iHandled = IRQ_NONE;
-		goto Exit;
-	}
-	// process tasks
-	if ((wStatus & (EDRV_REGW_INT_TER | EDRV_REGW_INT_TOK)) != 0) {	// transmit interrupt
-
-		if (EdrvInstance_l.m_pbTxBuf == NULL) {
-			printk("%s Tx buffers currently not allocated\n",
-			       __func__);
-			goto Exit;
-		}
-		// read transmit status
-		dwTxStatus =
-		    EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
-				     (EdrvInstance_l.m_uiCurTxDesc *
-				      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;
-			pTxBuffer = EdrvInstance_l.m_pLastTransmittedTxBuffer;
-			EdrvInstance_l.m_pLastTransmittedTxBuffer = NULL;
-
-			if ((dwTxStatus & EDRV_REGDW_TSD_TOK) != 0) {
-				EDRV_COUNT_TX;
-			} else if ((dwTxStatus & EDRV_REGDW_TSD_TUN) != 0) {
-				EDRV_COUNT_TX_FUN;
-			} else {	// assume EDRV_REGDW_TSD_TABT
-				EDRV_COUNT_TX_COL_RL;
-			}
-
-//            printk("T");
-			if (pTxBuffer != NULL) {
-				// call Tx handler of Data link layer
-				EdrvInstance_l.m_InitParam.
-				    m_pfnTxHandler(pTxBuffer);
-			}
-		} else {
-			EDRV_COUNT_TX_ERR;
-		}
-	}
-
-	if ((wStatus & (EDRV_REGW_INT_RER | EDRV_REGW_INT_FOVW | EDRV_REGW_INT_RXOVW | EDRV_REGW_INT_PUN)) != 0) {	// receive error interrupt
-
-		if ((wStatus & EDRV_REGW_INT_FOVW) != 0) {
-			EDRV_COUNT_RX_FOVW;
-		} else if ((wStatus & EDRV_REGW_INT_RXOVW) != 0) {
-			EDRV_COUNT_RX_OVW;
-		} else if ((wStatus & EDRV_REGW_INT_PUN) != 0) {	// Packet underrun
-			EDRV_TRACE_RX_PUN(wStatus);
-			EDRV_COUNT_RX_PUN;
-		} else {	/*if ((wStatus & EDRV_REGW_INT_RER) != 0) */
-
-			EDRV_TRACE_RX_ERR(wStatus);
-			EDRV_COUNT_RX_ERR;
-		}
-
-		// reinitialize Rx process
-		EdrvReinitRx();
-	}
-
-	if ((wStatus & EDRV_REGW_INT_ROK) != 0) {	// receive interrupt
-
-		if (EdrvInstance_l.m_pbRxBuf == NULL) {
-			printk("%s Rx buffers currently not allocated\n",
-			       __func__);
-			goto Exit;
-		}
-		// read current offset in receive buffer
-		wCurRx =
-		    (EDRV_REGW_READ(EDRV_REGW_CAPR) +
-		     0x10) % EDRV_RX_BUFFER_LENGTH;
-
-		while ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_BUFE) == 0) {	// frame available
-
-			// calculate pointer to current frame in receive buffer
-			pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx;
-
-			// read receive status u32
-			dwRxStatus = le32_to_cpu(*((u32 *) pbRxBuf));
-
-			// calculate length of received frame
-			uiLength = dwRxStatus >> 16;
-
-			if (uiLength == 0xFFF0) {	// frame is unfinished (maybe early Rx interrupt is active)
-				break;
-			}
-
-			if ((dwRxStatus & EDRV_RXSTAT_ROK) == 0) {	// error occured while receiving this frame
-				// ignore it
-				if ((dwRxStatus & EDRV_RXSTAT_FAE) != 0) {
-					EDRV_COUNT_RX_FAE;
-				} else if ((dwRxStatus & EDRV_RXSTAT_CRC) != 0) {
-					EDRV_TRACE_RX_CRC(dwRxStatus);
-					EDRV_COUNT_RX_CRC;
-				} else {
-					EDRV_TRACE_RX_ERR(dwRxStatus);
-					EDRV_COUNT_RX_ERR;
-				}
-
-				// reinitialize Rx process
-				EdrvReinitRx();
-
-				break;
-			} else {	// frame is OK
-				RxBuffer.m_BufferInFrame =
-				    kEdrvBufferLastInFrame;
-				RxBuffer.m_uiRxMsgLen = uiLength - ETH_CRC_SIZE;
-				RxBuffer.m_pbBuffer =
-				    pbRxBuf + sizeof(dwRxStatus);
-
-//                printk("R");
-				EDRV_COUNT_RX;
-
-				// call Rx handler of Data link layer
-				EdrvInstance_l.m_InitParam.
-				    m_pfnRxHandler(&RxBuffer);
-			}
-
-			// calulate new offset (u32 aligned)
-			wCurRx =
-			    (u16) ((wCurRx + uiLength + sizeof(dwRxStatus) +
-				     3) & ~0x3);
-			EDRV_TRACE_CAPR(wCurRx - 0x10);
-			EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10);
-
-			// reread current offset in receive buffer
-			wCurRx =
-			    (EDRV_REGW_READ(EDRV_REGW_CAPR) +
-			     0x10) % EDRV_RX_BUFFER_LENGTH;
-
-		}
-	}
-
-	if ((wStatus & EDRV_REGW_INT_SERR) != 0) {	// PCI error
-		EDRV_COUNT_PCI_ERR;
-	}
-
-	if ((wStatus & EDRV_REGW_INT_TIMEOUT) != 0) {	// Timeout
-		EDRV_COUNT_TIMEOUT;
-	}
-
-      Exit:
-	return iHandled;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvInitOne
-//
-// Description: initializes one PCI device
-//
-// Parameters:  pPciDev             = pointer to corresponding PCI device structure
-//              pId                 = PCI device ID
-//
-// Returns:     (int)               = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
-{
-	int iResult = 0;
-	u32 dwTemp;
-
-	if (EdrvInstance_l.m_pPciDev != NULL) {	// Edrv is already connected to a PCI device
-		printk("%s device %s discarded\n", __func__,
-		       pci_name(pPciDev));
-		iResult = -ENODEV;
-		goto Exit;
-	}
-
-	if (pPciDev->revision >= 0x20) {
-		printk
-		    ("%s device %s is an enhanced 8139C+ version, which is not supported\n",
-		     __func__, pci_name(pPciDev));
-		iResult = -ENODEV;
-		goto Exit;
-	}
-
-	EdrvInstance_l.m_pPciDev = pPciDev;
-
-	// enable device
-	printk("%s enable device\n", __func__);
-	iResult = pci_enable_device(pPciDev);
-	if (iResult != 0) {
-		goto Exit;
-	}
-
-	if ((pci_resource_flags(pPciDev, 1) & IORESOURCE_MEM) == 0) {
-		iResult = -ENODEV;
-		goto Exit;
-	}
-
-	printk("%s request regions\n", __func__);
-	iResult = pci_request_regions(pPciDev, DRV_NAME);
-	if (iResult != 0) {
-		goto Exit;
-	}
-
-	printk("%s ioremap\n", __func__);
-	EdrvInstance_l.m_pIoAddr =
-	    ioremap(pci_resource_start(pPciDev, 1),
-		    pci_resource_len(pPciDev, 1));
-	if (EdrvInstance_l.m_pIoAddr == NULL) {	// remap of controller's register space failed
-		iResult = -EIO;
-		goto Exit;
-	}
-	// enable PCI busmaster
-	printk("%s enable busmaster\n", __func__);
-	pci_set_master(pPciDev);
-
-	// reset controller
-	printk("%s reset controller\n", __func__);
-	EDRV_REGB_WRITE(EDRV_REGB_COMMAND, EDRV_REGB_COMMAND_RST);
-
-	// wait until reset has finished
-	for (iResult = 500; iResult > 0; iResult--) {
-		if ((EDRV_REGB_READ(EDRV_REGB_COMMAND) & EDRV_REGB_COMMAND_RST)
-		    == 0) {
-			break;
-		}
-
-		schedule_timeout(10);
-	}
-
-	// check hardware version, i.e. chip ID
-	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%08X\n", __func__,
-		       dwTemp);
-		iResult = -ENODEV;
-		goto Exit;
-	}
-	// disable interrupts
-	printk("%s disable interrupts\n", __func__);
-	EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0);
-	// acknowledge all pending interrupts
-	EDRV_REGW_WRITE(EDRV_REGW_INT_STATUS,
-			EDRV_REGW_READ(EDRV_REGW_INT_STATUS));
-
-	// install interrupt handler
-	printk("%s install interrupt handler\n", __func__);
-	iResult =
-	    request_irq(pPciDev->irq, TgtEthIsr, IRQF_SHARED,
-			DRV_NAME /*pPciDev->dev.name */ , pPciDev);
-	if (iResult != 0) {
-		goto Exit;
-	}
-
-/*
-    // unlock configuration registers
-    printk("%s unlock configuration registers\n", __func__);
-    EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_UNLOCK);
-
-    // check if user specified a MAC address
-    printk("%s check specified MAC address\n", __func__);
-    for (iResult = 0; iResult < 6; iResult++)
-    {
-        if (EdrvInstance_l.m_InitParam.m_abMyMacAddr[iResult] != 0)
-        {
-            printk("%s set local MAC address\n", __func__);
-            // write this MAC address to controller
-            EDRV_REGDW_WRITE(EDRV_REGDW_IDR0,
-                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(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
-            dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4);
-            break;
-        }
-    }
-    iResult = 0;
-
-    // lock configuration registers
-    EDRV_REGB_WRITE(EDRV_REGB_CMD9346, EDRV_REGB_CMD9346_LOCK);
-*/
-
-	// allocate buffers
-	printk("%s allocate buffers\n", __func__);
-	EdrvInstance_l.m_pbTxBuf =
-	    pci_alloc_consistent(pPciDev, EDRV_TX_BUFFER_SIZE,
-				 &EdrvInstance_l.m_pTxBufDma);
-	if (EdrvInstance_l.m_pbTxBuf == NULL) {
-		iResult = -ENOMEM;
-		goto Exit;
-	}
-
-	EdrvInstance_l.m_pbRxBuf =
-	    pci_alloc_consistent(pPciDev, EDRV_RX_BUFFER_SIZE,
-				 &EdrvInstance_l.m_pRxBufDma);
-	if (EdrvInstance_l.m_pbRxBuf == NULL) {
-		iResult = -ENOMEM;
-		goto Exit;
-	}
-	// reset pointers for Tx buffers
-	printk("%s reset pointers fo Tx buffers\n", __func__);
-	EDRV_REGDW_WRITE(EDRV_REGDW_TSAD0, 0);
-	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD0);
-	EDRV_REGDW_WRITE(EDRV_REGDW_TSAD1, 0);
-	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD1);
-	EDRV_REGDW_WRITE(EDRV_REGDW_TSAD2, 0);
-	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD2);
-	EDRV_REGDW_WRITE(EDRV_REGDW_TSAD3, 0);
-	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3);
-
-	printk("    Command = 0x%02X\n",
-	       (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
-
-	// set pointer for receive buffer in controller
-	printk("%s set pointer to Rx buffer\n", __func__);
-	EDRV_REGDW_WRITE(EDRV_REGDW_RBSTART, EdrvInstance_l.m_pRxBufDma);
-
-	// 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",
-	       (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
-
-	// clear missed packet counter to enable Rx/Tx process
-	EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0);
-
-	// set transmit configuration register
-	printk("%s set Tx conf register", __func__);
-	EDRV_REGDW_WRITE(EDRV_REGDW_TCR, EDRV_REGDW_TCR_DEF);
-	printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_TCR));
-
-	// set receive configuration register
-	printk("%s set Rx conf register", __func__);
-	EDRV_REGDW_WRITE(EDRV_REGDW_RCR, EDRV_REGDW_RCR_DEF);
-	printk(" = 0x%08X\n", EDRV_REGDW_READ(EDRV_REGDW_RCR));
-
-	// reset multicast MAC address filter
-	EDRV_REGDW_WRITE(EDRV_REGDW_MAR0, 0);
-	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR0);
-	EDRV_REGDW_WRITE(EDRV_REGDW_MAR4, 0);
-	dwTemp = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
-
-/*
-    // 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", (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
-*/
-	// disable early interrupts
-	EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0);
-
-	// enable interrupts
-	printk("%s enable interrupts\n", __func__);
-	EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, EDRV_REGW_INT_MASK_DEF);
-
-      Exit:
-	printk("%s finished with %d\n", __func__, iResult);
-	return iResult;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvRemoveOne
-//
-// Description: shuts down one PCI device
-//
-// Parameters:  pPciDev             = pointer to corresponding PCI device structure
-//
-// Returns:     (void)
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static void EdrvRemoveOne(struct pci_dev *pPciDev)
-{
-
-	if (EdrvInstance_l.m_pPciDev != pPciDev) {	// trying to remove unknown device
-		BUG_ON(EdrvInstance_l.m_pPciDev != pPciDev);
-		goto Exit;
-	}
-	// disable transmitter and receiver
-	EDRV_REGB_WRITE(EDRV_REGB_COMMAND, 0);
-
-	// disable interrupts
-	EDRV_REGW_WRITE(EDRV_REGW_INT_MASK, 0);
-
-	// remove interrupt handler
-	free_irq(pPciDev->irq, pPciDev);
-
-	// free buffers
-	if (EdrvInstance_l.m_pbTxBuf != NULL) {
-		pci_free_consistent(pPciDev, EDRV_TX_BUFFER_SIZE,
-				    EdrvInstance_l.m_pbTxBuf,
-				    EdrvInstance_l.m_pTxBufDma);
-		EdrvInstance_l.m_pbTxBuf = NULL;
-	}
-
-	if (EdrvInstance_l.m_pbRxBuf != NULL) {
-		pci_free_consistent(pPciDev, EDRV_RX_BUFFER_SIZE,
-				    EdrvInstance_l.m_pbRxBuf,
-				    EdrvInstance_l.m_pRxBufDma);
-		EdrvInstance_l.m_pbRxBuf = NULL;
-	}
-	// unmap controller's register space
-	if (EdrvInstance_l.m_pIoAddr != NULL) {
-		iounmap(EdrvInstance_l.m_pIoAddr);
-	}
-	// disable the PCI device
-	pci_disable_device(pPciDev);
-
-	// release memory regions
-	pci_release_regions(pPciDev);
-
-	EdrvInstance_l.m_pPciDev = NULL;
-
-      Exit:;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EdrvCalcHash
-//
-// Description: function calculates the entry for the hash-table from MAC
-//              address
-//
-// Parameters:  pbMAC_p - pointer to MAC address
-//
-// Returns:     hash value
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#define HASH_BITS              6	// used bits in hash
-#define CRC32_POLY    0x04C11DB6	//
-//#define CRC32_POLY    0xEDB88320  //
-// G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
-
-static u8 EdrvCalcHash(u8 * pbMAC_p)
-{
-	u32 dwByteCounter;
-	u32 dwBitCounter;
-	u32 dwData;
-	u32 dwCrc;
-	u32 dwCarry;
-	u8 *pbData;
-	u8 bHash;
-
-	pbData = pbMAC_p;
-
-	// calculate crc32 value of mac address
-	dwCrc = 0xFFFFFFFF;
-
-	for (dwByteCounter = 0; dwByteCounter < 6; dwByteCounter++) {
-		dwData = *pbData;
-		pbData++;
-		for (dwBitCounter = 0; dwBitCounter < 8;
-		     dwBitCounter++, dwData >>= 1) {
-			dwCarry = (((dwCrc >> 31) ^ dwData) & 1);
-			dwCrc = dwCrc << 1;
-			if (dwCarry != 0) {
-				dwCrc = (dwCrc ^ CRC32_POLY) | dwCarry;
-			}
-		}
-	}
-
-//    printk("MyCRC = 0x%08lX\n", dwCrc);
-	// only upper 6 bits (HASH_BITS) are used
-	// which point to specific bit in the hash registers
-	bHash = (u8) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
-
-	return bHash;
-}
diff --git a/drivers/staging/epl/EdrvFec.h b/drivers/staging/epl/EdrvFec.h
deleted file mode 100644
index 56728d1..0000000
--- a/drivers/staging/epl/EdrvFec.h
+++ /dev/null
@@ -1,114 +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: EdrvFec.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
-//---------------------------------------------------------------------------
-// do this in config header
-#define TARGET_HARDWARE TGTHW_SPLC_CF54
-
-// base addresses
-#if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282)
-
-#elif ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5485)
-
-#else
-
-#error 'ERROR: Target was never implemented!'
-
-#endif
-
-//---------------------------------------------------------------------------
-// types
-//---------------------------------------------------------------------------
-
-// Rx and Tx buffer descriptor format
-typedef struct {
-	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)
-
-#elif ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5485)
-
-#endif
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EDRV_FEC_H_
diff --git a/drivers/staging/epl/EdrvSim.h b/drivers/staging/epl/EdrvSim.h
deleted file mode 100644
index 191ec14..0000000
--- a/drivers/staging/epl/EdrvSim.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:  interface for ethernet driver simulation
-
-  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: EdrvSim.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:
-
-  2006/06/15 d.k.:   start of implementation
-
-****************************************************************************/
-
-#ifndef _EDRVSIM_H_
-#define _EDRVSIM_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-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
deleted file mode 100644
index 7f22b04..0000000
--- a/drivers/staging/epl/Epl.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for EPL API layer
-
-  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: Epl.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_API_H_
-#define _EPL_API_H_
-
-#include "EplInc.h"
-#include "EplSdo.h"
-#include "EplObd.h"
-#include "EplLed.h"
-#include "EplEvent.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef struct {
-	unsigned int m_uiNodeId;
-	tEplNmtState m_NmtState;
-	tEplNmtNodeEvent m_NodeEvent;
-	u16 m_wErrorCode;	// EPL error code if m_NodeEvent == kEplNmtNodeEventError
-	BOOL m_fMandatory;
-
-} tEplApiEventNode;
-
-typedef struct {
-	tEplNmtState m_NmtState;	// local NMT state
-	tEplNmtBootEvent m_BootEvent;
-	u16 m_wErrorCode;	// EPL error code if m_BootEvent == kEplNmtBootEventError
-
-} tEplApiEventBoot;
-
-typedef struct {
-	tEplLedType m_LedType;	// type of the LED (e.g. Status or Error)
-	BOOL m_fOn;		// state of the LED (e.g. on or off)
-
-} tEplApiEventLed;
-
-typedef enum {
-	kEplApiEventNmtStateChange = 0x10,	// m_NmtStateChange
-//    kEplApiEventRequestNmt     = 0x11,    // m_bNmtCmd
-	kEplApiEventCriticalError = 0x12,	// m_InternalError, Stack halted
-	kEplApiEventWarning = 0x13,	// m_InternalError, Stack running
-	kEplApiEventNode = 0x20,	// m_Node
-	kEplApiEventBoot = 0x21,	// m_Boot
-	kEplApiEventSdo = 0x62,	// m_Sdo
-	kEplApiEventObdAccess = 0x69,	// m_ObdCbParam
-	kEplApiEventLed = 0x70,	// m_Led
-
-} tEplApiEventType;
-
-typedef union {
-	tEplEventNmtStateChange m_NmtStateChange;
-	tEplEventError m_InternalError;
-	tEplSdoComFinished m_Sdo;
-	tEplObdCbParam m_ObdCbParam;
-	tEplApiEventNode m_Node;
-	tEplApiEventBoot m_Boot;
-	tEplApiEventLed m_Led;
-
-} tEplApiEventArg;
-
-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
-	u8 m_abMacAddress[6];	// local MAC address
-
-	// 0x1F82: NMT_FeatureFlags_U32
-	u32 m_dwFeatureFlags;
-	// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
-	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
-	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
-	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
-	unsigned int m_uiAsyncMtu;	// required to set up max frame size
-	// 0x1F98.9: Prescaler_U16
-	unsigned int m_uiPrescaler;	// required for sync
-	// $$$ Multiplexed Slot
-
-	// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
-	u32 m_dwLossOfFrameTolerance;
-
-	// 0x1F8A: NMT_MNCycleTiming_REC
-	// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
-	u32 m_dwWaitSocPreq;
-
-	// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
-	u32 m_dwAsyncSlotTimeout;
-
-	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)
-	char *m_pszSwVersion;	// NMT_ManufactSwVers_VS  (0x100A/0 local OD)
-
-	tEplApiCbEvent m_pfnCbEvent;
-	void *m_pEventUserArg;
-	tEplSyncCb m_pfnCbSync;
-
-} tEplApiInitParam;
-
-typedef struct {
-	void *m_pImage;
-	unsigned int m_uiSize;
-
-} tEplApiProcessImage;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p);
-
-tEplKernel EplApiShutdown(void);
-
-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 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 EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p);
-
-tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
-				 unsigned int uiSubindex_p,
-				 void *pDstData_p,
-				 unsigned int *puiSize_p);
-
-tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
-				  unsigned int uiSubindex_p,
-				  void *pSrcData_p,
-				  unsigned int uiSize_p);
-
-tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p);
-
-tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
-			    void *pVar_p,
-			    unsigned int *puiVarEntries_p,
-			    tEplObdSize *pEntrySize_p,
-			    unsigned int uiFirstSubindex_p);
-
-tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
-
-tEplKernel EplApiProcess(void);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
-				      tEplNmtNodeCommand NodeCommand_p);
-#endif
-
-tEplKernel EplApiGetIdentResponse(unsigned int uiNodeId_p,
-				  tEplIdentResponse **ppIdentResponse_p);
-
-// functions for process image will be implemented in separate file
-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
deleted file mode 100644
index 3b46ea1..0000000
--- a/drivers/staging/epl/EplAmi.h
+++ /dev/null
@@ -1,323 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  Definitions for Abstract Memory Interface
-
-  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: EplAmi.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.2 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                GCC
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-   06.03.2000  -rs
-               Implementation
-
-   16.09.2002  -as
-               To save code space the functions AmiSetByte and AmiGetByte
-               are replaced by macros. For targets which assign u8 by
-               an 16Bit type, the definition of macros must changed to
-               functions.
-
-   23.02.2005  r.d.:
-               Functions included for extended data types such as UNSIGNED24,
-               UNSIGNED40, ...
-
-   13.06.2006  d.k.:
-               Extended the interface for EPL with the different functions
-               for little endian and big endian
-
-****************************************************************************/
-
-#ifndef _EPLAMI_H_
-#define _EPLAMI_H_
-
-
-//---------------------------------------------------------------------------
-//  types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Prototypen
-//---------------------------------------------------------------------------
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//---------------------------------------------------------------------------
-//
-// write functions
-//
-// To save code space the function AmiSetByte is replaced by
-// an macro.
-// void  AmiSetByte  (void * pAddr_p, u8 bByteVal_p);
-
-#define AmiSetByteToBe(pAddr_p, bByteVal_p)  {*(u8 *)(pAddr_p) = (bByteVal_p);}
-#define AmiSetByteToLe(pAddr_p, bByteVal_p)  {*(u8 *)(pAddr_p) = (bByteVal_p);}
-
-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);
-
-//---------------------------------------------------------------------------
-//
-// read functions
-//
-// To save code space the function AmiGetByte is replaced by
-// an macro.
-// u8   AmiGetByte  (void * pAddr_p);
-
-#define AmiGetByteFromBe(pAddr_p)  (*(u8 *)(pAddr_p))
-#define AmiGetByteFromLe(pAddr_p)  (*(u8 *)(pAddr_p))
-
-u16 AmiGetWordFromBe(void *pAddr_p);
-u32 AmiGetDwordFromBe(void *pAddr_p);
-u16 AmiGetWordFromLe(void *pAddr_p);
-u32 AmiGetDwordFromLe(void *pAddr_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetDword24()
-//
-// Description: sets a 24 bit value to a buffer
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              dwDwordVal_p    = value to set
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-
-void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p);
-void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetDword24()
-//
-// Description: reads a 24 bit value from a buffer
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u32           = read value
-//
-//---------------------------------------------------------------------------
-
-u32 AmiGetDword24FromBe(void *pAddr_p);
-u32 AmiGetDword24FromLe(void *pAddr_p);
-
-//#ifdef USE_VAR64
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword40()
-//
-// Description: sets a 40 bit value to a buffer
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p);
-void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword40()
-//
-// Description: reads a 40 bit value from a buffer
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword40FromBe(void *pAddr_p);
-u64 AmiGetQword40FromLe(void *pAddr_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword48()
-//
-// Description: sets a 48 bit value to a buffer
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p);
-void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword48()
-//
-// Description: reads a 48 bit value from a buffer
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword48FromBe(void *pAddr_p);
-u64 AmiGetQword48FromLe(void *pAddr_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword56()
-//
-// Description: sets a 56 bit value to a buffer
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p);
-void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword56()
-//
-// Description: reads a 56 bit value from a buffer
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword56FromBe(void *pAddr_p);
-u64 AmiGetQword56FromLe(void *pAddr_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword64()
-//
-// Description: sets a 64 bit value to a buffer
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p);
-void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword64()
-//
-// Description: reads a 64 bit value from a buffer
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword64FromBe(void *pAddr_p);
-u64 AmiGetQword64FromLe(void *pAddr_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetTimeOfDay()
-//
-// Description: sets a TIME_OF_DAY (CANopen) value to a buffer
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetTimeOfDay()
-//
-// Description: reads a TIME_OF_DAY (CANopen) value from a buffer
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
-//
-// Return:      void
-//
-//---------------------------------------------------------------------------
-void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
-
-#ifdef __cplusplus
-}
-#endif
-#endif				// ifndef _EPLAMI_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/EplApiGeneric.c b/drivers/staging/epl/EplApiGeneric.c
deleted file mode 100644
index c441956..0000000
--- a/drivers/staging/epl/EplApiGeneric.c
+++ /dev/null
@@ -1,2054 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for generic EPL API 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: EplApiGeneric.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.21 $  $Date: 2008/11/21 09:00:38 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/09/05 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "Epl.h"
-#include "kernel/EplDllk.h"
-#include "kernel/EplErrorHandlerk.h"
-#include "kernel/EplEventk.h"
-#include "kernel/EplNmtk.h"
-#include "kernel/EplObdk.h"
-#include "kernel/EplTimerk.h"
-#include "kernel/EplDllkCal.h"
-#include "kernel/EplPdokCal.h"
-#include "user/EplDlluCal.h"
-#include "user/EplLedu.h"
-#include "user/EplNmtCnu.h"
-#include "user/EplNmtMnu.h"
-#include "user/EplSdoComu.h"
-#include "user/EplIdentu.h"
-#include "user/EplStatusu.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-#include "kernel/EplPdok.h"
-#endif
-
-#include "SharedBuff.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
-#error "EPL API layer needs EPL module OBDK!"
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          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  EplApi                                              */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	tEplApiInitParam m_InitParam;
-
-} tEplApiInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplApiInstance EplApiInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-// NMT state change event callback function
-static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
-
-// update DLL configuration from OD
-static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
-
-// update OD from init param
-static tEplKernel EplApiUpdateObd(void);
-
-// process events from user event queue
-static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-// callback function of SDO module
-static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p);
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-// callback functions of NmtMnu module
-static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
-				    tEplNmtNodeEvent NodeEvent_p,
-				    tEplNmtState NmtState_p,
-				    u16 wErrorCode_p, BOOL fMandatory_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 EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p);
-#endif
-
-// OD initialization function (implemented in Objdict.c)
-tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiInitialize()
-//
-// Description: add and initialize new instance of EPL stack.
-//              After return from this function the application must start
-//              the NMT state machine via
-//              EplApiExecNmtCommand(kEplNmtEventSwReset)
-//              and thereby the whole EPL stack :-)
-//
-// Parameters:  pInitParam_p            = initialisation parameters
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplObdInitParam ObdInitParam;
-	tEplDllkInitParam DllkInitParam;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-#endif
-
-	// reset instance structure
-	EPL_MEMSET(&EplApiInstance_g, 0, sizeof(EplApiInstance_g));
-
-	EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p,
-		   min(sizeof(tEplApiInitParam),
-		       pInitParam_p->m_uiSizeOfStruct));
-
-	// check event callback function pointer
-	if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL) {	// application must always have an event callback function
-		Ret = kEplApiInvalidParam;
-		goto Exit;
-	}
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	// init OD
-// FIXME
-//    Ret = EplObdInitRam(&ObdInitParam);
-//    if (Ret != kEplSuccessful)
-//    {
-//        goto Exit;
-//    }
-
-	// initialize EplObd module
-	Ret = EplObdInit(&ObdInitParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-#ifndef EPL_NO_FIFO
-	ShbError = ShbInit();
-	if (ShbError != kShbOk) {
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-#endif
-
-	// initialize EplEventk module
-	Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// initialize EplEventu module
-	Ret = EplEventuInit(EplApiProcessEvent);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// init EplTimerk module
-	Ret = EplTimerkInit();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// initialize EplNmtk module before DLL
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-	Ret = EplNmtkInit();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// initialize EplDllk module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-	EPL_MEMCPY(DllkInitParam.m_be_abSrcMac,
-		   EplApiInstance_g.m_InitParam.m_abMacAddress, 6);
-	Ret = EplDllkAddInstance(&DllkInitParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// initialize EplErrorHandlerk module
-	Ret = EplErrorHandlerkInit();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// initialize EplDllkCal module
-	Ret = EplDllkCalAddInstance();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// initialize EplDlluCal module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	Ret = EplDlluCalAddInstance();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// initialize EplPdok module
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-	Ret = EplPdokAddInstance();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret = EplPdokCalAddInstance();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// initialize EplNmtCnu module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-	Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// initialize EplNmtu module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-	Ret = EplNmtuInit();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// register NMT event callback function
-	Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	// initialize EplNmtMnu module
-	Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// initialize EplIdentu module
-	Ret = EplIdentuInit();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// initialize EplStatusu module
-	Ret = EplStatusuInit();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// initialize EplLedu module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-	Ret = EplLeduInit(EplApiCbLedStateChange);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// init SDO module
-#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
-     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
-	// init sdo command layer
-	Ret = EplSdoComInit();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// the application must start NMT state machine
-	// via EplApiExecNmtCommand(kEplNmtEventSwReset)
-	// and thereby the whole EPL stack
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiShutdown()
-//
-// Description: deletes an instance of EPL stack
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplApiShutdown(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// $$$ d.k.: check if NMT state is NMT_GS_OFF
-
-	// $$$ d.k.: maybe delete event queues at first, but this implies that
-	//           no other module must not use the event queues for communication
-	//           during shutdown.
-
-	// delete instance for all modules
-
-	// deinitialize EplSdoCom module
-#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
-     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
-	Ret = EplSdoComDelInstance();
-//    PRINTF1("EplSdoComDelInstance():  0x%X\n", Ret);
-#endif
-
-	// deinitialize EplLedu module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-	Ret = EplLeduDelInstance();
-//    PRINTF1("EplLeduDelInstance():    0x%X\n", Ret);
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	// deinitialize EplNmtMnu module
-	Ret = EplNmtMnuDelInstance();
-//    PRINTF1("EplNmtMnuDelInstance():  0x%X\n", Ret);
-
-	// deinitialize EplIdentu module
-	Ret = EplIdentuDelInstance();
-//    PRINTF1("EplIdentuDelInstance():  0x%X\n", Ret);
-
-	// deinitialize EplStatusu module
-	Ret = EplStatusuDelInstance();
-//    PRINTF1("EplStatusuDelInstance():  0x%X\n", Ret);
-#endif
-
-	// deinitialize EplNmtCnu module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-	Ret = EplNmtCnuDelInstance();
-//    PRINTF1("EplNmtCnuDelInstance():  0x%X\n", Ret);
-#endif
-
-	// deinitialize EplNmtu module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-	Ret = EplNmtuDelInstance();
-//    PRINTF1("EplNmtuDelInstance():    0x%X\n", Ret);
-#endif
-
-	// deinitialize EplDlluCal module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	Ret = EplDlluCalDelInstance();
-//    PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret);
-
-#endif
-
-	// deinitialize EplEventu module
-	Ret = EplEventuDelInstance();
-//    PRINTF1("EplEventuDelInstance():  0x%X\n", Ret);
-
-	// deinitialize EplNmtk module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-	Ret = EplNmtkDelInstance();
-//    PRINTF1("EplNmtkDelInstance():    0x%X\n", Ret);
-#endif
-
-	// deinitialize EplDllk module
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-	Ret = EplDllkDelInstance();
-//    PRINTF1("EplDllkDelInstance():    0x%X\n", Ret);
-
-	// deinitialize EplDllkCal module
-	Ret = EplDllkCalDelInstance();
-//    PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret);
-#endif
-
-	// deinitialize EplEventk module
-	Ret = EplEventkDelInstance();
-//    PRINTF1("EplEventkDelInstance():  0x%X\n", Ret);
-
-	// deinitialize EplTimerk module
-	Ret = EplTimerkDelInstance();
-//    PRINTF1("EplTimerkDelInstance():  0x%X\n", Ret);
-
-#ifndef EPL_NO_FIFO
-	ShbExit();
-#endif
-
-	return Ret;
-}
-
-//----------------------------------------------------------------------------
-// Function:    EplApiExecNmtCommand()
-//
-// Description: executes a NMT command, i.e. post the NMT command/event to the
-//              NMTk module. NMT commands which are not appropriate in the current
-//              NMT state are silently ignored. Please keep in mind that the
-//              NMT state may change until the NMT command is actually executed.
-//
-// Parameters:  NmtEvent_p              = NMT command/event
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//----------------------------------------------------------------------------
-
-tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-	Ret = EplNmtuNmtEvent(NmtEvent_p);
-#endif
-
-	return Ret;
-}
-
-//----------------------------------------------------------------------------
-// Function:    EplApiLinkObject()
-//
-// Description: Function maps array of application variables onto specified object in OD
-//
-// Parameters:  uiObjIndex_p            = Function maps variables for this object index
-//              pVar_p                  = Pointer to data memory area for the specified object
-//              puiVarEntries_p         = IN: pointer to number of entries to map
-//                                        OUT: pointer to number of actually used entries
-//              pEntrySize_p            = IN: pointer to size of one entry;
-//                                            if size is zero, the actual size will be read from OD
-//                                        OUT: pointer to entire size of all entries mapped
-//              uiFirstSubindex_p       = This is the first subindex to be mapped.
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//----------------------------------------------------------------------------
-
-tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
-			    void *pVar_p,
-			    unsigned int *puiVarEntries_p,
-			    tEplObdSize *pEntrySize_p,
-			    unsigned int uiFirstSubindex_p)
-{
-	u8 bVarEntries;
-	u8 bIndexEntries;
-	u8 *pbData;
-	unsigned int uiSubindex;
-	tEplVarParam VarParam;
-	tEplObdSize EntrySize;
-	tEplObdSize UsedSize;
-
-	tEplKernel RetCode = kEplSuccessful;
-
-	if ((pVar_p == NULL)
-	    || (puiVarEntries_p == NULL)
-	    || (*puiVarEntries_p == 0)
-	    || (pEntrySize_p == NULL)) {
-		RetCode = kEplApiInvalidParam;
-		goto Exit;
-	}
-
-	pbData = (u8 *)pVar_p;
-	bVarEntries = (u8) * puiVarEntries_p;
-	UsedSize = 0;
-
-	// init VarParam structure with default values
-	VarParam.m_uiIndex = uiObjIndex_p;
-	VarParam.m_ValidFlag = kVarValidAll;
-
-	if (uiFirstSubindex_p != 0) {	// check if object exists by reading subindex 0x00,
-		// because user wants to link a variable to a subindex unequal 0x00
-		// read number of entries
-		EntrySize = (tEplObdSize) sizeof(bIndexEntries);
-		RetCode = EplObdReadEntry(uiObjIndex_p,
-					  0x00,
-					  (void *)&bIndexEntries,
-					  &EntrySize);
-
-		if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
-			// Object doesn't exist or invalid entry number
-			RetCode = kEplObdIndexNotExist;
-			goto Exit;
-		}
-	} else {		// user wants to link a variable to subindex 0x00
-		// that's OK
-		bIndexEntries = 0;
-	}
-
-	// Correct number of entries if number read from OD is greater
-	// than the specified number.
-	// This is done, so that we do not set more entries than subindexes the
-	// object actually has.
-	if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
-	    (bVarEntries != 0x00)) {
-		bIndexEntries = (u8) (bVarEntries + uiFirstSubindex_p - 1);
-	}
-	// map entries
-	for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
-	     uiSubindex++) {
-		// if passed entry size is 0, then get size from OD
-		if (*pEntrySize_p == 0x00) {
-			// read entry size
-			EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex);
-
-			if (EntrySize == 0x00) {
-				// invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty)
-				RetCode = kEplObdSubindexNotExist;
-				break;
-			}
-		} else {	// use passed entry size
-			EntrySize = *pEntrySize_p;
-		}
-
-		VarParam.m_uiSubindex = uiSubindex;
-
-		// set pointer to user var
-		VarParam.m_Size = EntrySize;
-		VarParam.m_pData = pbData;
-
-		UsedSize += EntrySize;
-		pbData += EntrySize;
-
-		RetCode = EplObdDefineVar(&VarParam);
-		if (RetCode != kEplSuccessful) {
-			break;
-		}
-	}
-
-	// set number of mapped entries and entry size
-	*puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1);
-	*pEntrySize_p = UsedSize;
-
-      Exit:
-
-	return (RetCode);
-
-}
-
-// ----------------------------------------------------------------------------
-//
-// Function:    EplApiReadObject()
-//
-// Description: reads the specified entry from the OD of the specified node.
-//              If this node is a remote node, it performs a SDO transfer, which
-//              means this function returns kEplApiTaskDeferred and the application
-//              is informed via the event callback function when the task is completed.
-//
-// Parameters:  pSdoComConHdl_p         = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
-//              uiNodeId_p              = IN: node ID (0 = itself)
-//              uiIndex_p               = IN: index of object in OD
-//              uiSubindex_p            = IN: sub-index of object in OD
-//              pDstData_le_p           = OUT: pointer to data in little endian
-//              puiSize_p               = INOUT: pointer to size of data
-//              SdoType_p               = IN: type of SDO transfer
-//              pUserArg_p              = IN: user-definable argument pointer,
-//                                            which will be passed to the event callback function
-//
-// Return:      tEplKernel              = error code
-//
-// ----------------------------------------------------------------------------
-
-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;
-
-	if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL)
-	    || (*puiSize_p == 0)) {
-		Ret = kEplApiInvalidParam;
-		goto Exit;
-	}
-
-	if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) {	// local OD access can be performed
-		tEplObdSize ObdSize;
-
-		ObdSize = (tEplObdSize) * puiSize_p;
-		Ret =
-		    EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p,
-					&ObdSize);
-		*puiSize_p = (unsigned int)ObdSize;
-	} else {		// perform SDO transfer
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-		tEplSdoComTransParamByIndex TransParamByIndex;
-//    tEplSdoComConHdl            SdoComConHdl;
-
-		// check if application provides space for handle
-		if (pSdoComConHdl_p == NULL) {
-			Ret = kEplApiInvalidParam;
-			goto Exit;
-//            pSdoComConHdl_p = &SdoComConHdl;
-		}
-		// init command layer connection
-		Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p,	// target node id
-					 SdoType_p);	// SDO type
-		if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
-			goto Exit;
-		}
-		TransParamByIndex.m_pData = pDstData_le_p;
-		TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead;
-		TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
-		TransParamByIndex.m_uiDataSize = *puiSize_p;
-		TransParamByIndex.m_uiIndex = uiIndex_p;
-		TransParamByIndex.m_uiSubindex = uiSubindex_p;
-		TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
-		TransParamByIndex.m_pUserArg = pUserArg_p;
-
-		Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		Ret = kEplApiTaskDeferred;
-
-#else
-		Ret = kEplApiInvalidParam;
-#endif
-	}
-
-      Exit:
-	return Ret;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Function:    EplApiWriteObject()
-//
-// Description: writes the specified entry to the OD of the specified node.
-//              If this node is a remote node, it performs a SDO transfer, which
-//              means this function returns kEplApiTaskDeferred and the application
-//              is informed via the event callback function when the task is completed.
-//
-// Parameters:  pSdoComConHdl_p         = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
-//              uiNodeId_p              = IN: node ID (0 = itself)
-//              uiIndex_p               = IN: index of object in OD
-//              uiSubindex_p            = IN: sub-index of object in OD
-//              pSrcData_le_p           = IN: pointer to data in little endian
-//              uiSize_p                = IN: size of data in bytes
-//              SdoType_p               = IN: type of SDO transfer
-//              pUserArg_p              = IN: user-definable argument pointer,
-//                                            which will be passed to the event callback function
-//
-// Return:      tEplKernel              = error code
-//
-// ----------------------------------------------------------------------------
-
-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;
-
-	if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0)) {
-		Ret = kEplApiInvalidParam;
-		goto Exit;
-	}
-
-	if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) {	// local OD access can be performed
-
-		Ret =
-		    EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p,
-					   pSrcData_le_p, uiSize_p);
-	} else {		// perform SDO transfer
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-		tEplSdoComTransParamByIndex TransParamByIndex;
-//    tEplSdoComConHdl            SdoComConHdl;
-
-		// check if application provides space for handle
-		if (pSdoComConHdl_p == NULL) {
-			Ret = kEplApiInvalidParam;
-			goto Exit;
-//            pSdoComConHdl_p = &SdoComConHdl;
-		}
-		// d.k.: How to recycle command layer connection?
-		//       Try to redefine it, which will return kEplSdoComHandleExists
-		//       and the existing command layer handle.
-		//       If the returned handle is busy, EplSdoComInitTransferByIndex()
-		//       will return with error.
-		// $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and
-		//           Configuration Manager, are trying to communicate with the very same node.
-		//     possible solution: disallow communication by application if Configuration Manager is busy
-
-		// init command layer connection
-		Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p,	// target node id
-					 SdoType_p);	// SDO type
-		if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
-			goto Exit;
-		}
-		TransParamByIndex.m_pData = pSrcData_le_p;
-		TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite;
-		TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
-		TransParamByIndex.m_uiDataSize = uiSize_p;
-		TransParamByIndex.m_uiIndex = uiIndex_p;
-		TransParamByIndex.m_uiSubindex = uiSubindex_p;
-		TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
-		TransParamByIndex.m_pUserArg = pUserArg_p;
-
-		Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		Ret = kEplApiTaskDeferred;
-
-#else
-		Ret = kEplApiInvalidParam;
-#endif
-	}
-
-      Exit:
-	return Ret;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Function:    EplApiFreeSdoChannel()
-//
-// Description: frees the specified SDO channel.
-//              This function must be called after each call to EplApiReadObject()/EplApiWriteObject()
-//              which returns kEplApiTaskDeferred and the application
-//              is informed via the event callback function when the task is completed.
-//
-// Parameters:  SdoComConHdl_p          = IN: SDO connection handle
-//
-// Return:      tEplKernel              = error code
-//
-// ----------------------------------------------------------------------------
-
-tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-
-	// init command layer connection
-	Ret = EplSdoComUndefineCon(SdoComConHdl_p);
-
-#else
-	Ret = kEplApiInvalidParam;
-#endif
-
-	return Ret;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Function:    EplApiReadLocalObject()
-//
-// Description: reads the specified entry from the local OD.
-//
-// Parameters:  uiIndex_p               = IN: index of object in OD
-//              uiSubindex_p            = IN: sub-index of object in OD
-//              pDstData_p              = OUT: pointer to data in platform byte order
-//              puiSize_p               = INOUT: pointer to size of data
-//
-// Return:      tEplKernel              = error code
-//
-// ----------------------------------------------------------------------------
-
-tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
-				 unsigned int uiSubindex_p,
-				 void *pDstData_p, unsigned int *puiSize_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplObdSize ObdSize;
-
-	ObdSize = (tEplObdSize) * puiSize_p;
-	Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize);
-	*puiSize_p = (unsigned int)ObdSize;
-
-	return Ret;
-}
-
-// ----------------------------------------------------------------------------
-//
-// Function:    EplApiWriteLocalObject()
-//
-// Description: writes the specified entry to the local OD.
-//
-// Parameters:  uiIndex_p               = IN: index of object in OD
-//              uiSubindex_p            = IN: sub-index of object in OD
-//              pSrcData_p              = IN: pointer to data in platform byte order
-//              uiSize_p                = IN: size of data in bytes
-//
-// Return:      tEplKernel              = error code
-//
-// ----------------------------------------------------------------------------
-
-tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
-				  unsigned int uiSubindex_p,
-				  void *pSrcData_p,
-				  unsigned int uiSize_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	Ret =
-	    EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p,
-			     (tEplObdSize) uiSize_p);
-
-	return Ret;
-}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-// ----------------------------------------------------------------------------
-//
-// Function:    EplApiMnTriggerStateChange()
-//
-// Description: triggers the specified node command for the specified node.
-//
-// Parameters:  uiNodeId_p              = node ID for which the node command will be executed
-//              NodeCommand_p           = node command
-//
-// Return:      tEplKernel              = error code
-//
-// ----------------------------------------------------------------------------
-
-tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
-				      tEplNmtNodeCommand NodeCommand_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p);
-
-	return Ret;
-}
-
-#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiCbObdAccess
-//
-// Description: callback function for OD accesses
-//
-// Parameters:  pParam_p                = OBD parameter
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-#if (EPL_API_OBD_FORWARD_EVENT != FALSE)
-	tEplApiEventArg EventArg;
-
-	// call user callback
-	// must be disabled for EplApiLinuxKernel.c, because of reentrancy problem
-	// for local OD access. This is not so bad as user callback function in
-	// application does not use OD callbacks at the moment.
-	EventArg.m_ObdCbParam = *pParam_p;
-	Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess,
-							&EventArg,
-							EplApiInstance_g.
-							m_InitParam.
-							m_pEventUserArg);
-#endif
-
-	switch (pParam_p->m_uiIndex) {
-		//case 0x1006:    // NMT_CycleLen_U32 (valid on reset)
-	case 0x1C14:		// DLL_LossOfFrameTolerance_U32
-		//case 0x1F98:    // NMT_CycleTiming_REC (valid on reset)
-		{
-			if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
-				// update DLL configuration
-				Ret = EplApiUpdateDllConfig(FALSE);
-			}
-			break;
-		}
-
-	case 0x1020:		// CFM_VerifyConfiguration_REC.ConfId_U32 != 0
-		{
-			if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
-			    && (pParam_p->m_uiSubIndex == 3)
-			    && (*((u32 *) pParam_p->m_pArg) != 0)) {
-				u32 dwVerifyConfInvalid = 0;
-				// set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
-				Ret =
-				    EplObdWriteEntry(0x1020, 4,
-						     &dwVerifyConfInvalid, 4);
-				// ignore any error because this objekt is optional
-				Ret = kEplSuccessful;
-			}
-			break;
-		}
-
-	case 0x1F9E:		// NMT_ResetCmd_U8
-		{
-			if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
-				u8 bNmtCommand;
-
-				bNmtCommand = *((u8 *) pParam_p->m_pArg);
-				// check value range
-				switch ((tEplNmtCommand) bNmtCommand) {
-				case kEplNmtCmdResetNode:
-				case kEplNmtCmdResetCommunication:
-				case kEplNmtCmdResetConfiguration:
-				case kEplNmtCmdSwReset:
-				case kEplNmtCmdInvalidService:
-					// valid command identifier specified
-					break;
-
-				default:
-					pParam_p->m_dwAbortCode =
-					    EPL_SDOAC_VALUE_RANGE_EXCEEDED;
-					Ret = kEplObdAccessViolation;
-					break;
-				}
-			} else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
-				u8 bNmtCommand;
-
-				bNmtCommand = *((u8 *) pParam_p->m_pArg);
-				// check value range
-				switch ((tEplNmtCommand) bNmtCommand) {
-				case kEplNmtCmdResetNode:
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventResetNode);
-#endif
-					break;
-
-				case kEplNmtCmdResetCommunication:
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventResetCom);
-#endif
-					break;
-
-				case kEplNmtCmdResetConfiguration:
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventResetConfig);
-#endif
-					break;
-
-				case kEplNmtCmdSwReset:
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventSwReset);
-#endif
-					break;
-
-				case kEplNmtCmdInvalidService:
-					break;
-
-				default:
-					pParam_p->m_dwAbortCode =
-					    EPL_SDOAC_VALUE_RANGE_EXCEEDED;
-					Ret = kEplObdAccessViolation;
-					break;
-				}
-			}
-			break;
-		}
-
-	default:
-		break;
-	}
-
-//Exit:
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiProcessEvent
-//
-// Description: processes events from event queue and forwards these to
-//              the application's event callback function
-//
-// Parameters:  pEplEvent_p =   pointer to event
-//
-// Returns:     tEplKernel  = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p)
-{
-	tEplKernel Ret;
-	tEplEventError *pEventError;
-	tEplApiEventType EventType;
-
-	Ret = kEplSuccessful;
-
-	// process event
-	switch (pEplEvent_p->m_EventType) {
-		// error event
-	case kEplEventTypeError:
-		{
-			pEventError = (tEplEventError *) pEplEvent_p->m_pArg;
-			switch (pEventError->m_EventSource) {
-				// treat the errors from the following sources as critical
-			case kEplEventSourceEventk:
-			case kEplEventSourceEventu:
-			case kEplEventSourceDllk:
-				{
-					EventType = kEplApiEventCriticalError;
-					// halt the stack by entering NMT state Off
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventCriticalError);
-					break;
-				}
-
-				// the other errors are just warnings
-			default:
-				{
-					EventType = kEplApiEventWarning;
-					break;
-				}
-			}
-
-			// call user callback
-			Ret =
-			    EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType,
-								      (tEplApiEventArg
-								       *)
-								      pEventError,
-								      EplApiInstance_g.
-								      m_InitParam.
-								      m_pEventUserArg);
-			// discard error from callback function, because this could generate an endless loop
-			Ret = kEplSuccessful;
-			break;
-		}
-
-		// at present, there are no other events for this module
-	default:
-		break;
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiCbNmtStateChange
-//
-// Description: callback function for NMT state changes
-//
-// Parameters:  NmtStateChange_p        = NMT state change event
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	u8 bNmtState;
-	tEplApiEventArg EventArg;
-
-	// save NMT state in OD
-	bNmtState = (u8) NmtStateChange_p.m_NewNmtState;
-	Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// do work which must be done in that state
-	switch (NmtStateChange_p.m_NewNmtState) {
-		// EPL stack is not running
-	case kEplNmtGsOff:
-		break;
-
-		// first init of the hardware
-	case kEplNmtGsInitialising:
-#if 0
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-		// configure SDO via UDP (i.e. bind it to the EPL ethernet interface)
-		Ret =
-		    EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress,
-				     EPL_C_SDO_EPL_PORT);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-#endif
-#endif
-
-		break;
-
-		// init of the manufacturer-specific profile area and the
-		// standardised device profile area
-	case kEplNmtGsResetApplication:
-		{
-			// reset application part of OD
-			Ret = EplObdAccessOdPart(kEplObdPartApp,
-						 kEplObdDirLoad);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-
-			break;
-		}
-
-		// init of the communication profile area
-	case kEplNmtGsResetCommunication:
-		{
-			// reset communication part of OD
-			Ret = EplObdAccessOdPart(kEplObdPartGen,
-						 kEplObdDirLoad);
-
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-			// $$$ d.k.: update OD only if OD was not loaded from non-volatile memory
-			Ret = EplApiUpdateObd();
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-
-			break;
-		}
-
-		// build the configuration with infos from OD
-	case kEplNmtGsResetConfiguration:
-		{
-
-			Ret = EplApiUpdateDllConfig(TRUE);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-
-			break;
-		}
-
-		//-----------------------------------------------------------
-		// CN part of the state machine
-
-		// node liste for EPL-Frames and check timeout
-	case kEplNmtCsNotActive:
-		{
-			// indicate completion of reset in NMT_ResetCmd_U8
-			bNmtState = (u8) kEplNmtCmdInvalidService;
-			Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-
-			break;
-		}
-
-		// node process only async frames
-	case kEplNmtCsPreOperational1:
-		{
-			break;
-		}
-
-		// node process isochronus and asynchronus frames
-	case kEplNmtCsPreOperational2:
-		{
-			break;
-		}
-
-		// node should be configured und application is ready
-	case kEplNmtCsReadyToOperate:
-		{
-			break;
-		}
-
-		// normal work state
-	case kEplNmtCsOperational:
-		{
-			break;
-		}
-
-		// node stopped by MN
-		// -> only process asynchronus frames
-	case kEplNmtCsStopped:
-		{
-			break;
-		}
-
-		// no EPL cycle
-		// -> normal ethernet communication
-	case kEplNmtCsBasicEthernet:
-		{
-			break;
-		}
-
-		//-----------------------------------------------------------
-		// MN part of the state machine
-
-		// node listens for EPL-Frames and check timeout
-	case kEplNmtMsNotActive:
-		{
-			break;
-		}
-
-		// node processes only async frames
-	case kEplNmtMsPreOperational1:
-		{
-			break;
-		}
-
-		// node processes isochronous and asynchronous frames
-	case kEplNmtMsPreOperational2:
-		{
-			break;
-		}
-
-		// node should be configured und application is ready
-	case kEplNmtMsReadyToOperate:
-		{
-			break;
-		}
-
-		// normal work state
-	case kEplNmtMsOperational:
-		{
-			break;
-		}
-
-		// no EPL cycle
-		// -> normal ethernet communication
-	case kEplNmtMsBasicEthernet:
-		{
-			break;
-		}
-
-	default:
-		{
-			TRACE0
-			    ("EplApiCbNmtStateChange(): unhandled NMT state\n");
-		}
-	}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-	// forward event to Led module
-	Ret = EplLeduCbNmtStateChange(NmtStateChange_p);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	// forward event to NmtMn module
-	Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// call user callback
-	EventArg.m_NmtStateChange = NmtStateChange_p;
-	Ret =
-	    EplApiInstance_g.m_InitParam.
-	    m_pfnCbEvent(kEplApiEventNmtStateChange, &EventArg,
-			 EplApiInstance_g.m_InitParam.m_pEventUserArg);
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiUpdateDllConfig
-//
-// Description: update configuration of DLL
-//
-// Parameters:  fUpdateIdentity_p       = TRUE, if identity must be updated
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplDllConfigParam DllConfigParam;
-	tEplDllIdentParam DllIdentParam;
-	tEplObdSize ObdSize;
-	u16 wTemp;
-	u8 bTemp;
-
-	// configure Dll
-	EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
-	DllConfigParam.m_uiNodeId = EplObdGetNodeId();
-
-	// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
-	ObdSize = 4;
-	Ret =
-	    EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// 0x1F82: NMT_FeatureFlags_U32
-	ObdSize = 4;
-	Ret =
-	    EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags,
-			    &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// d.k. There is no dependance between FeatureFlags and async-only CN
-	DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly;
-
-	// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
-	ObdSize = 4;
-	Ret =
-	    EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance,
-			    &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// 0x1F98: NMT_CycleTiming_REC
-	// 0x1F98.1: IsochrTxMaxPayload_U16
-	ObdSize = 2;
-	Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	DllConfigParam.m_uiIsochrTxMaxPayload = wTemp;
-
-	// 0x1F98.2: IsochrRxMaxPayload_U16
-	ObdSize = 2;
-	Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	DllConfigParam.m_uiIsochrRxMaxPayload = wTemp;
-
-	// 0x1F98.3: PResMaxLatency_U32
-	ObdSize = 4;
-	Ret =
-	    EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency,
-			    &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// 0x1F98.4: PReqActPayloadLimit_U16
-	ObdSize = 2;
-	Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	DllConfigParam.m_uiPreqActPayloadLimit = wTemp;
-
-	// 0x1F98.5: PResActPayloadLimit_U16
-	ObdSize = 2;
-	Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	DllConfigParam.m_uiPresActPayloadLimit = wTemp;
-
-	// 0x1F98.6: ASndMaxLatency_U32
-	ObdSize = 4;
-	Ret =
-	    EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency,
-			    &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// 0x1F98.7: MultiplCycleCnt_U8
-	ObdSize = 1;
-	Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	DllConfigParam.m_uiMultiplCycleCnt = bTemp;
-
-	// 0x1F98.8: AsyncMTU_U16
-	ObdSize = 2;
-	Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	DllConfigParam.m_uiAsyncMtu = wTemp;
-
-	// $$$ Prescaler
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
-	ObdSize = 4;
-	Ret =
-	    EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq,
-			    &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional)
-	ObdSize = 4;
-	Ret =
-	    EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout,
-			    &ObdSize);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-#endif
-
-	DllConfigParam.m_uiSizeOfStruct = sizeof(DllConfigParam);
-	Ret = EplDllkConfig(&DllConfigParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	if (fUpdateIdentity_p != FALSE) {
-		// configure Identity
-		EPL_MEMSET(&DllIdentParam, 0, sizeof(DllIdentParam));
-		ObdSize = 4;
-		Ret =
-		    EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType,
-				    &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		ObdSize = 4;
-		Ret =
-		    EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId,
-				    &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		ObdSize = 4;
-		Ret =
-		    EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode,
-				    &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		ObdSize = 4;
-		Ret =
-		    EplObdReadEntry(0x1018, 3,
-				    &DllIdentParam.m_dwRevisionNumber,
-				    &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		ObdSize = 4;
-		Ret =
-		    EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber,
-				    &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		DllIdentParam.m_dwIpAddress =
-		    EplApiInstance_g.m_InitParam.m_dwIpAddress;
-		DllIdentParam.m_dwSubnetMask =
-		    EplApiInstance_g.m_InitParam.m_dwSubnetMask;
-		EPL_MEMCPY(DllIdentParam.m_sHostname,
-			   EplApiInstance_g.m_InitParam.m_sHostname,
-			   sizeof(DllIdentParam.m_sHostname));
-
-		ObdSize = 4;
-		Ret =
-		    EplObdReadEntry(0x1020, 1,
-				    &DllIdentParam.m_dwVerifyConfigurationDate,
-				    &ObdSize);
-		// ignore any error, because this object is optional
-
-		ObdSize = 4;
-		Ret =
-		    EplObdReadEntry(0x1020, 2,
-				    &DllIdentParam.m_dwVerifyConfigurationTime,
-				    &ObdSize);
-		// ignore any error, because this object is optional
-
-		// $$$ d.k.: fill rest of ident structure
-
-		DllIdentParam.m_uiSizeOfStruct = sizeof(DllIdentParam);
-		Ret = EplDllkSetIdentity(&DllIdentParam);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiUpdateObd
-//
-// Description: update OD from init param
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplApiUpdateObd(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-	u16 wTemp;
-	u8 bTemp;
-
-	// set node id in OD
-	Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId,	// node id
-			      kEplObdNodeIdHardware);	// set by hardware
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1006, 0,
-				     &EplApiInstance_g.m_InitParam.m_dwCycleLen,
-				     4);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1C14, 0,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwLossOfFrameTolerance, 4);
-		/*        if(Ret != kEplSuccessful)
-		   {
-		   goto Exit;
-		   } */
-	}
-	// d.k. There is no dependance between FeatureFlags and async-only CN.
-	if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1F82, 0,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwFeatureFlags, 4);
-		/*    if(Ret != kEplSuccessful)
-		   {
-		   goto Exit;
-		   } */
-	}
-
-	wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
-	Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-
-	wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
-	Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-
-	Ret =
-	    EplObdWriteEntry(0x1F98, 3,
-			     &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency,
-			     4);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-
-	if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
-	    EPL_C_DLL_ISOCHR_MAX_PAYL) {
-		wTemp =
-		    (u16) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
-		Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
-	    EPL_C_DLL_ISOCHR_MAX_PAYL) {
-		wTemp =
-		    (u16) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
-		Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-	}
-
-	Ret =
-	    EplObdWriteEntry(0x1F98, 6,
-			     &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency,
-			     4);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-
-	if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
-		bTemp = (u8) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
-		Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
-	    EPL_C_DLL_MAX_ASYNC_MTU) {
-		wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
-		Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
-/*    if(Ret != kEplSuccessful)
-    {
-        goto Exit;
-    }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
-		wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiPrescaler;
-		Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
-		// ignore return code
-		Ret = kEplSuccessful;
-	}
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1F8A, 1,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwWaitSocPreq, 4);
-		/*        if(Ret != kEplSuccessful)
-		   {
-		   goto Exit;
-		   } */
-	}
-
-	if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0)
-	    && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1)) {
-		Ret =
-		    EplObdWriteEntry(0x1F8A, 2,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwAsyncSlotTimeout, 4);
-		/*        if(Ret != kEplSuccessful)
-		   {
-		   goto Exit;
-		   } */
-	}
-#endif
-
-	// configure Identity
-	if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1000, 0,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwDeviceType, 4);
-/*        if(Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1018, 1,
-				     &EplApiInstance_g.m_InitParam.m_dwVendorId,
-				     4);
-/*        if(Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1018, 2,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwProductCode, 4);
-/*        if(Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1018, 3,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwRevisionNumber, 4);
-/*        if(Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1) {
-		Ret =
-		    EplObdWriteEntry(0x1018, 4,
-				     &EplApiInstance_g.m_InitParam.
-				     m_dwSerialNumber, 4);
-/*        if(Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL) {
-		// write Device Name (0x1008)
-		Ret =
-		    EplObdWriteEntry(0x1008, 0,
-				     (void *)EplApiInstance_g.
-				     m_InitParam.m_pszDevName,
-				     (tEplObdSize) strlen(EplApiInstance_g.
-							  m_InitParam.
-							  m_pszDevName));
-/*        if (Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL) {
-		// write Hardware version (0x1009)
-		Ret =
-		    EplObdWriteEntry(0x1009, 0,
-				     (void *)EplApiInstance_g.
-				     m_InitParam.m_pszHwVersion,
-				     (tEplObdSize) strlen(EplApiInstance_g.
-							  m_InitParam.
-							  m_pszHwVersion));
-/*        if (Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-	if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL) {
-		// write Software version (0x100A)
-		Ret =
-		    EplObdWriteEntry(0x100A, 0,
-				     (void *)EplApiInstance_g.
-				     m_InitParam.m_pszSwVersion,
-				     (tEplObdSize) strlen(EplApiInstance_g.
-							  m_InitParam.
-							  m_pszSwVersion));
-/*        if (Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiCbSdoCon
-//
-// Description: callback function for SDO transfers
-//
-// Parameters:  pSdoComFinished_p       = SDO parameter
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p)
-{
-	tEplKernel Ret;
-	tEplApiEventArg EventArg;
-
-	Ret = kEplSuccessful;
-
-	// call user callback
-	EventArg.m_Sdo = *pSdoComFinished_p;
-	Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo,
-							&EventArg,
-							EplApiInstance_g.
-							m_InitParam.
-							m_pEventUserArg);
-
-	return Ret;
-
-}
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiCbNodeEvent
-//
-// Description: callback function for node events
-//
-// Parameters:  uiNodeId_p              = node ID of the CN
-//              NodeEvent_p             = event from the specified CN
-//              NmtState_p              = current NMT state of the CN
-//              wErrorCode_p            = EPL error code if NodeEvent_p==kEplNmtNodeEventError
-//              fMandatory_p            = flag if CN is mandatory
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
-				    tEplNmtNodeEvent NodeEvent_p,
-				    tEplNmtState NmtState_p,
-				    u16 wErrorCode_p, BOOL fMandatory_p)
-{
-	tEplKernel Ret;
-	tEplApiEventArg EventArg;
-
-	Ret = kEplSuccessful;
-
-	// call user callback
-	EventArg.m_Node.m_uiNodeId = uiNodeId_p;
-	EventArg.m_Node.m_NodeEvent = NodeEvent_p;
-	EventArg.m_Node.m_NmtState = NmtState_p;
-	EventArg.m_Node.m_wErrorCode = wErrorCode_p;
-	EventArg.m_Node.m_fMandatory = fMandatory_p;
-
-	Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode,
-							&EventArg,
-							EplApiInstance_g.
-							m_InitParam.
-							m_pEventUserArg);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiCbBootEvent
-//
-// Description: callback function for boot events
-//
-// Parameters:  BootEvent_p             = event from the boot-up process
-//              NmtState_p              = current local NMT state
-//              wErrorCode_p            = EPL error code if BootEvent_p==kEplNmtBootEventError
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
-				    tEplNmtState NmtState_p,
-				    u16 wErrorCode_p)
-{
-	tEplKernel Ret;
-	tEplApiEventArg EventArg;
-
-	Ret = kEplSuccessful;
-
-	// call user callback
-	EventArg.m_Boot.m_BootEvent = BootEvent_p;
-	EventArg.m_Boot.m_NmtState = NmtState_p;
-	EventArg.m_Boot.m_wErrorCode = wErrorCode_p;
-
-	Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot,
-							&EventArg,
-							EplApiInstance_g.
-							m_InitParam.
-							m_pEventUserArg);
-
-	return Ret;
-
-}
-
-#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiCbLedStateChange
-//
-// Description: callback function for LED change events.
-//
-// Parameters:  LedType_p       = type of LED
-//              fOn_p           = state of LED
-//
-// Returns:     tEplKernel      = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p)
-{
-	tEplKernel Ret;
-	tEplApiEventArg EventArg;
-
-	Ret = kEplSuccessful;
-
-	// call user callback
-	EventArg.m_Led.m_LedType = LedType_p;
-	EventArg.m_Led.m_fOn = fOn_p;
-
-	Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed,
-							&EventArg,
-							EplApiInstance_g.
-							m_InitParam.
-							m_pEventUserArg);
-
-	return Ret;
-
-}
-
-#endif
-
-// EOF
diff --git a/drivers/staging/epl/EplApiLinux.h b/drivers/staging/epl/EplApiLinux.h
deleted file mode 100644
index 92cd125..0000000
--- a/drivers/staging/epl/EplApiLinux.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for EPL API layer for Linux (kernel and user space)
-
-  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: EplApiLinux.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/08/25 12:17:41 $
-
-                $State: Exp $
-
-                Build Environment:
-                KEIL uVision 2
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/10/11 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_API_LINUX_H_
-#define _EPL_API_LINUX_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define EPLLIN_DEV_NAME     "epl"	// used for "/dev" and "/proc" entry
-
-//---------------------------------------------------------------------------
-//  Commands for <ioctl>
-//---------------------------------------------------------------------------
-
-#define EPLLIN_CMD_INITIALIZE               0	// ulArg_p ~ tEplApiInitParam*
-#define EPLLIN_CMD_PI_IN                    1	// ulArg_p ~ tEplApiProcessImage*
-#define EPLLIN_CMD_PI_OUT                   2	// ulArg_p ~ tEplApiProcessImage*
-#define EPLLIN_CMD_WRITE_OBJECT             3	// ulArg_p ~ tEplLinSdoObject*
-#define EPLLIN_CMD_READ_OBJECT              4	// ulArg_p ~ tEplLinSdoObject*
-#define EPLLIN_CMD_WRITE_LOCAL_OBJECT       5	// ulArg_p ~ tEplLinLocalObject*
-#define EPLLIN_CMD_READ_LOCAL_OBJECT        6	// ulArg_p ~ tEplLinLocalObject*
-#define EPLLIN_CMD_FREE_SDO_CHANNEL         7	// ulArg_p ~ tEplSdoComConHdl
-#define EPLLIN_CMD_NMT_COMMAND              8	// ulArg_p ~ tEplNmtEvent
-#define EPLLIN_CMD_GET_EVENT                9	// ulArg_p ~ tEplLinEvent*
-#define EPLLIN_CMD_MN_TRIGGER_STATE_CHANGE 10	// ulArg_p ~ tEplLinNodeCmdObject*
-#define EPLLIN_CMD_PI_SETUP                11	// ulArg_p ~ 0
-#define EPLLIN_CMD_SHUTDOWN                12	// ulArg_p ~ 0
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef struct {
-	unsigned int m_uiEventArgSize;
-	tEplApiEventArg *m_pEventArg;
-	tEplApiEventType *m_pEventType;
-	tEplKernel m_RetCbEvent;
-
-} tEplLinEvent;
-
-typedef struct {
-	tEplSdoComConHdl m_SdoComConHdl;
-	BOOL m_fValidSdoComConHdl;
-	unsigned int m_uiNodeId;
-	unsigned int m_uiIndex;
-	unsigned int m_uiSubindex;
-	void *m_le_pData;
-	unsigned int m_uiSize;
-	tEplSdoType m_SdoType;
-	void *m_pUserArg;
-
-} tEplLinSdoObject;
-
-typedef struct {
-	unsigned int m_uiIndex;
-	unsigned int m_uiSubindex;
-	void *m_pData;
-	unsigned int m_uiSize;
-
-} tEplLinLocalObject;
-
-typedef struct {
-	unsigned int m_uiNodeId;
-	tEplNmtNodeCommand m_NodeCommand;
-
-} tEplLinNodeCmdObject;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_API_LINUX_H_
diff --git a/drivers/staging/epl/EplApiLinuxKernel.c b/drivers/staging/epl/EplApiLinuxKernel.c
deleted file mode 100644
index cb3e275..0000000
--- a/drivers/staging/epl/EplApiLinuxKernel.c
+++ /dev/null
@@ -1,1173 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  Linux kernel module as wrapper of EPL API layer,
-                i.e. counterpart to a Linux application
-
-  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: EplApiLinuxKernel.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.9 $  $Date: 2008/11/21 09:00:38 $
-
-                $State: Exp $
-
-                Build Environment:
-                GNU-Compiler for m68k
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/10/11 d.k.:  Initial Version
-  2008/04/10 m.u.:  Changed to new char driver init
-
-****************************************************************************/
-
-// kernel modul and driver
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/types.h>
-
-//#include <linux/module.h>
-//#include <linux/kernel.h>
-//#include <linux/init.h>
-//#include <linux/errno.h>
-
-// scheduling
-#include <linux/sched.h>
-
-// memory access
-#include <asm/uaccess.h>
-#include <linux/vmalloc.h>
-
-#include "Epl.h"
-#include "EplApiLinux.h"
-//#include "kernel/EplPdokCal.h"
-#include "proc_fs.h"
-
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-// Metainformation
-MODULE_LICENSE("Dual BSD/GPL");
-#ifdef MODULE_AUTHOR
-MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
-MODULE_DESCRIPTION("EPL API driver");
-#endif
-
-//---------------------------------------------------------------------------
-//  Configuration
-//---------------------------------------------------------------------------
-
-#define EPLLIN_DRV_NAME     "systec_epl"	// used for <register_chrdev>
-
-//---------------------------------------------------------------------------
-//  Constant definitions
-//---------------------------------------------------------------------------
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
-#else
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#endif
-
-#define EVENT_STATE_INIT        0
-#define EVENT_STATE_IOCTL       1	// ioctl entered and ready to receive EPL event
-#define EVENT_STATE_READY       2	// EPL event can be forwarded to user application
-#define EVENT_STATE_TERM        3	// terminate processing
-
-#define EPL_STATE_NOTOPEN       0
-#define EPL_STATE_NOTINIT       1
-#define EPL_STATE_RUNNING       2
-#define EPL_STATE_SHUTDOWN      3
-
-//---------------------------------------------------------------------------
-//  Global variables
-//---------------------------------------------------------------------------
-
-    // device number (major and minor)
-static dev_t nDevNum_g;
-static struct cdev *pEpl_cdev_g;
-
-static volatile unsigned int uiEplState_g = EPL_STATE_NOTOPEN;
-
-static struct semaphore SemaphoreCbEvent_g;	// semaphore for EplLinCbEvent
-static wait_queue_head_t WaitQueueCbEvent_g;	// wait queue EplLinCbEvent
-static wait_queue_head_t WaitQueueProcess_g;	// wait queue for EplApiProcess (user process)
-static wait_queue_head_t WaitQueueRelease_g;	// wait queue for EplLinRelease
-static atomic_t AtomicEventState_g = ATOMIC_INIT(EVENT_STATE_INIT);
-static tEplApiEventType EventType_g;	// event type (enum)
-static tEplApiEventArg *pEventArg_g;	// event argument (union)
-static tEplKernel RetCbEvent_g;	// return code from event callback function
-static wait_queue_head_t WaitQueueCbSync_g;	// wait queue EplLinCbSync
-static wait_queue_head_t WaitQueuePI_In_g;	// wait queue for EplApiProcessImageExchangeIn (user process)
-static atomic_t AtomicSyncState_g = ATOMIC_INIT(EVENT_STATE_INIT);
-
-//---------------------------------------------------------------------------
-//  Local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	void *m_pUserArg;
-	void *m_pData;
-
-} tEplLinSdoBufHeader;
-
-//---------------------------------------------------------------------------
-//  Local variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-tEplKernel EplLinCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-			 tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
-			 void *pUserArg_p);
-
-tEplKernel EplLinCbSync(void);
-
-static int __init EplLinInit(void);
-static void __exit EplLinExit(void);
-
-static int EplLinOpen(struct inode *pDeviceFile_p, struct file *pInstance_p);
-static int EplLinRelease(struct inode *pDeviceFile_p, struct file *pInstance_p);
-static ssize_t EplLinRead(struct file *pInstance_p, char *pDstBuff_p,
-			  size_t BuffSize_p, loff_t * pFileOffs_p);
-static ssize_t EplLinWrite(struct file *pInstance_p, const char *pSrcBuff_p,
-			   size_t BuffSize_p, loff_t * pFileOffs_p);
-static int EplLinIoctl(struct inode *pDeviceFile_p, struct file *pInstance_p,
-		       unsigned int uiIoctlCmd_p, unsigned long ulArg_p);
-
-//---------------------------------------------------------------------------
-//  Kernel Module specific Data Structures
-//---------------------------------------------------------------------------
-
-module_init(EplLinInit);
-module_exit(EplLinExit);
-
-static struct file_operations EplLinFileOps_g = {
-	.owner = THIS_MODULE,
-	.open = EplLinOpen,
-	.release = EplLinRelease,
-	.read = EplLinRead,
-	.write = EplLinWrite,
-	.ioctl = EplLinIoctl,
-
-};
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//  Initailize Driver
-//---------------------------------------------------------------------------
-//  -> insmod driver
-//---------------------------------------------------------------------------
-
-static int __init EplLinInit(void)
-{
-
-	tEplKernel EplRet;
-	int iErr;
-	int iRet;
-
-	TRACE0("EPL: + EplLinInit...\n");
-	TRACE2("EPL:   Driver build: %s / %s\n", __DATE__, __TIME__);
-
-	iRet = 0;
-
-	// initialize global variables
-	atomic_set(&AtomicEventState_g, EVENT_STATE_INIT);
-	sema_init(&SemaphoreCbEvent_g, 1);
-	init_waitqueue_head(&WaitQueueCbEvent_g);
-	init_waitqueue_head(&WaitQueueProcess_g);
-	init_waitqueue_head(&WaitQueueRelease_g);
-
-	// register character device handler
-	// only one Minor required
-	TRACE2("EPL:   Installing Driver '%s', Version %s...\n",
-	       EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION);
-	iRet = alloc_chrdev_region(&nDevNum_g, 0, 1, EPLLIN_DRV_NAME);
-	if (iRet == 0) {
-		TRACE2
-		    ("EPL:   Driver '%s' installed successful, assigned MajorNumber=%d\n",
-		     EPLLIN_DRV_NAME, MAJOR(nDevNum_g));
-	} else {
-		TRACE1
-		    ("EPL:   ERROR: Driver '%s' is unable to get a free MajorNumber!\n",
-		     EPLLIN_DRV_NAME);
-		iRet = -EIO;
-		goto Exit;
-	}
-
-	// register cdev structure
-	pEpl_cdev_g = cdev_alloc();
-	pEpl_cdev_g->ops = &EplLinFileOps_g;
-	pEpl_cdev_g->owner = THIS_MODULE;
-	iErr = cdev_add(pEpl_cdev_g, nDevNum_g, 1);
-	if (iErr) {
-		TRACE2("EPL:   ERROR %d: Driver '%s' could not be added!\n",
-		       iErr, EPLLIN_DRV_NAME);
-		iRet = -EIO;
-		goto Exit;
-	}
-
-	// create device node in PROCFS
-	EplRet = EplLinProcInit();
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-
-      Exit:
-
-	TRACE1("EPL: - EplLinInit (iRet=%d)\n", iRet);
-	return (iRet);
-
-}
-
-//---------------------------------------------------------------------------
-//  Remove Driver
-//---------------------------------------------------------------------------
-//  -> rmmod driver
-//---------------------------------------------------------------------------
-
-static void __exit EplLinExit(void)
-{
-
-	tEplKernel EplRet;
-
-	// delete instance for all modules
-//    EplRet = EplApiShutdown();
-//    printk("EplApiShutdown():  0x%X\n", EplRet);
-
-	// deinitialize proc fs
-	EplRet = EplLinProcFree();
-	printk("EplLinProcFree():        0x%X\n", EplRet);
-
-	TRACE0("EPL: + EplLinExit...\n");
-
-	// remove cdev structure
-	cdev_del(pEpl_cdev_g);
-
-	// unregister character device handler
-	unregister_chrdev_region(nDevNum_g, 1);
-
-	TRACE1("EPL:   Driver '%s' removed.\n", EPLLIN_DRV_NAME);
-
-	TRACE0("EPL: - EplLinExit\n");
-
-}
-
-//---------------------------------------------------------------------------
-//  Open Driver
-//---------------------------------------------------------------------------
-//  -> open("/dev/driver", O_RDWR)...
-//---------------------------------------------------------------------------
-
-static int EplLinOpen(struct inode *pDeviceFile_p,	// information about the device to open
-		      struct file *pInstance_p)	// information about driver instance
-{
-
-	int iRet;
-
-	TRACE0("EPL: + EplLinOpen...\n");
-
-	if (uiEplState_g != EPL_STATE_NOTOPEN) {	// stack already initialized
-		iRet = -EALREADY;
-	} else {
-		atomic_set(&AtomicEventState_g, EVENT_STATE_INIT);
-		sema_init(&SemaphoreCbEvent_g, 1);
-		init_waitqueue_head(&WaitQueueCbEvent_g);
-		init_waitqueue_head(&WaitQueueProcess_g);
-		init_waitqueue_head(&WaitQueueRelease_g);
-		atomic_set(&AtomicSyncState_g, EVENT_STATE_INIT);
-		init_waitqueue_head(&WaitQueueCbSync_g);
-		init_waitqueue_head(&WaitQueuePI_In_g);
-
-		uiEplState_g = EPL_STATE_NOTINIT;
-		iRet = 0;
-	}
-
-	TRACE1("EPL: - EplLinOpen (iRet=%d)\n", iRet);
-	return (iRet);
-
-}
-
-//---------------------------------------------------------------------------
-//  Close Driver
-//---------------------------------------------------------------------------
-//  -> close(device)...
-//---------------------------------------------------------------------------
-
-static int EplLinRelease(struct inode *pDeviceFile_p,	// information about the device to open
-			 struct file *pInstance_p)	// information about driver instance
-{
-
-	tEplKernel EplRet = kEplSuccessful;
-	int iRet;
-
-	TRACE0("EPL: + EplLinRelease...\n");
-
-	if (uiEplState_g != EPL_STATE_NOTINIT) {
-		// pass control to sync kernel thread, but signal termination
-		atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
-		wake_up_interruptible(&WaitQueueCbSync_g);
-		wake_up_interruptible(&WaitQueuePI_In_g);
-
-		// pass control to event queue kernel thread
-		atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
-		wake_up_interruptible(&WaitQueueCbEvent_g);
-
-		if (uiEplState_g == EPL_STATE_RUNNING) {	// post NmtEventSwitchOff
-			EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
-
-		}
-
-		if (EplRet == kEplSuccessful) {
-			TRACE0("EPL:   waiting for NMT_GS_OFF\n");
-			wait_event_interruptible(WaitQueueRelease_g,
-						 (uiEplState_g ==
-						  EPL_STATE_SHUTDOWN));
-		} else {	// post NmtEventSwitchOff failed
-			TRACE0("EPL:   event post failed\n");
-		}
-
-		// $$$ d.k.: What if waiting was interrupted by signal?
-
-		TRACE0("EPL:   call EplApiShutdown()\n");
-		// EPL stack can be safely shut down
-		// delete instance for all EPL modules
-		EplRet = EplApiShutdown();
-		printk("EplApiShutdown():  0x%X\n", EplRet);
-	}
-
-	uiEplState_g = EPL_STATE_NOTOPEN;
-	iRet = 0;
-
-	TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet);
-	return (iRet);
-
-}
-
-//---------------------------------------------------------------------------
-//  Read Data from Driver
-//---------------------------------------------------------------------------
-//  -> read(...)
-//---------------------------------------------------------------------------
-
-static ssize_t EplLinRead(struct file *pInstance_p,	// information about driver instance
-			  char *pDstBuff_p,	// address of buffer to fill with data
-			  size_t BuffSize_p,	// length of the buffer
-			  loff_t * pFileOffs_p)	// offset in the file
-{
-
-	int iRet;
-
-	TRACE0("EPL: + EplLinRead...\n");
-
-	TRACE0("EPL:   Sorry, this operation isn't supported.\n");
-	iRet = -EINVAL;
-
-	TRACE1("EPL: - EplLinRead (iRet=%d)\n", iRet);
-	return (iRet);
-
-}
-
-//---------------------------------------------------------------------------
-//  Write Data to Driver
-//---------------------------------------------------------------------------
-//  -> write(...)
-//---------------------------------------------------------------------------
-
-static ssize_t EplLinWrite(struct file *pInstance_p,	// information about driver instance
-			   const char *pSrcBuff_p,	// address of buffer to get data from
-			   size_t BuffSize_p,	// length of the buffer
-			   loff_t * pFileOffs_p)	// offset in the file
-{
-
-	int iRet;
-
-	TRACE0("EPL: + EplLinWrite...\n");
-
-	TRACE0("EPL:   Sorry, this operation isn't supported.\n");
-	iRet = -EINVAL;
-
-	TRACE1("EPL: - EplLinWrite (iRet=%d)\n", iRet);
-	return (iRet);
-
-}
-
-//---------------------------------------------------------------------------
-//  Generic Access to Driver
-//---------------------------------------------------------------------------
-//  -> ioctl(...)
-//---------------------------------------------------------------------------
-
-static int EplLinIoctl(struct inode *pDeviceFile_p,	// information about the device to open
-		       struct file *pInstance_p,	// information about driver instance
-		       unsigned int uiIoctlCmd_p,	// Ioctl command to execute
-		       unsigned long ulArg_p)	// Ioctl command specific argument/parameter
-{
-
-	tEplKernel EplRet;
-	int iErr;
-	int iRet;
-
-//    TRACE1("EPL: + EplLinIoctl (uiIoctlCmd_p=%d)...\n", uiIoctlCmd_p);
-
-	iRet = -EINVAL;
-
-	switch (uiIoctlCmd_p) {
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_INITIALIZE:
-		{
-			tEplApiInitParam EplApiInitParam;
-
-			iErr =
-			    copy_from_user(&EplApiInitParam,
-					   (const void *)ulArg_p,
-					   sizeof(EplApiInitParam));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			EplApiInitParam.m_pfnCbEvent = EplLinCbEvent;
-			EplApiInitParam.m_pfnCbSync = EplLinCbSync;
-
-			EplRet = EplApiInitialize(&EplApiInitParam);
-
-			uiEplState_g = EPL_STATE_RUNNING;
-
-			iRet = (int)EplRet;
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_SHUTDOWN:
-		{		// shutdown the threads
-
-			// pass control to sync kernel thread, but signal termination
-			atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
-			wake_up_interruptible(&WaitQueueCbSync_g);
-			wake_up_interruptible(&WaitQueuePI_In_g);
-
-			// pass control to event queue kernel thread
-			atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
-			wake_up_interruptible(&WaitQueueCbEvent_g);
-
-			if (uiEplState_g == EPL_STATE_RUNNING) {	// post NmtEventSwitchOff
-				EplRet =
-				    EplApiExecNmtCommand(kEplNmtEventSwitchOff);
-
-			}
-
-			iRet = 0;
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_READ_LOCAL_OBJECT:
-		{
-			tEplLinLocalObject LocalObject;
-			void *pData;
-
-			iErr =
-			    copy_from_user(&LocalObject, (const void *)ulArg_p,
-					   sizeof(LocalObject));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if ((LocalObject.m_pData == NULL)
-			    || (LocalObject.m_uiSize == 0)) {
-				iRet = (int)kEplApiInvalidParam;
-				goto Exit;
-			}
-
-			pData = vmalloc(LocalObject.m_uiSize);
-			if (pData == NULL) {	// no memory available
-				iRet = -ENOMEM;
-				goto Exit;
-			}
-
-			EplRet =
-			    EplApiReadLocalObject(LocalObject.m_uiIndex,
-						  LocalObject.m_uiSubindex,
-						  pData, &LocalObject.m_uiSize);
-
-			if (EplRet == kEplSuccessful) {
-				iErr =
-				    copy_to_user(LocalObject.m_pData, pData,
-						 LocalObject.m_uiSize);
-
-				vfree(pData);
-
-				if (iErr != 0) {
-					iRet = -EIO;
-					goto Exit;
-				}
-				// return actual size (LocalObject.m_uiSize)
-				iErr = put_user(LocalObject.m_uiSize,
-						(unsigned int *)(ulArg_p +
-								 (unsigned long)
-								 &LocalObject.
-								 m_uiSize -
-								 (unsigned long)
-								 &LocalObject));
-				if (iErr != 0) {
-					iRet = -EIO;
-					goto Exit;
-				}
-
-			} else {
-				vfree(pData);
-			}
-
-			iRet = (int)EplRet;
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_WRITE_LOCAL_OBJECT:
-		{
-			tEplLinLocalObject LocalObject;
-			void *pData;
-
-			iErr =
-			    copy_from_user(&LocalObject, (const void *)ulArg_p,
-					   sizeof(LocalObject));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if ((LocalObject.m_pData == NULL)
-			    || (LocalObject.m_uiSize == 0)) {
-				iRet = (int)kEplApiInvalidParam;
-				goto Exit;
-			}
-
-			pData = vmalloc(LocalObject.m_uiSize);
-			if (pData == NULL) {	// no memory available
-				iRet = -ENOMEM;
-				goto Exit;
-			}
-			iErr =
-			    copy_from_user(pData, LocalObject.m_pData,
-					   LocalObject.m_uiSize);
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			EplRet =
-			    EplApiWriteLocalObject(LocalObject.m_uiIndex,
-						   LocalObject.m_uiSubindex,
-						   pData, LocalObject.m_uiSize);
-
-			vfree(pData);
-
-			iRet = (int)EplRet;
-			break;
-		}
-
-	case EPLLIN_CMD_READ_OBJECT:
-		{
-			tEplLinSdoObject SdoObject;
-			void *pData;
-			tEplLinSdoBufHeader *pBufHeader;
-			tEplSdoComConHdl *pSdoComConHdl;
-
-			iErr =
-			    copy_from_user(&SdoObject, (const void *)ulArg_p,
-					   sizeof(SdoObject));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if ((SdoObject.m_le_pData == NULL)
-			    || (SdoObject.m_uiSize == 0)) {
-				iRet = (int)kEplApiInvalidParam;
-				goto Exit;
-			}
-
-			pBufHeader =
-			    (tEplLinSdoBufHeader *)
-			    vmalloc(sizeof(tEplLinSdoBufHeader) +
-				    SdoObject.m_uiSize);
-			if (pBufHeader == NULL) {	// no memory available
-				iRet = -ENOMEM;
-				goto Exit;
-			}
-			// initiate temporary buffer
-			pBufHeader->m_pUserArg = SdoObject.m_pUserArg;	// original user argument pointer
-			pBufHeader->m_pData = SdoObject.m_le_pData;	// original data pointer from app
-			pData = pBufHeader + sizeof(tEplLinSdoBufHeader);
-
-			if (SdoObject.m_fValidSdoComConHdl != FALSE) {
-				pSdoComConHdl = &SdoObject.m_SdoComConHdl;
-			} else {
-				pSdoComConHdl = NULL;
-			}
-
-			EplRet =
-			    EplApiReadObject(pSdoComConHdl,
-					     SdoObject.m_uiNodeId,
-					     SdoObject.m_uiIndex,
-					     SdoObject.m_uiSubindex, pData,
-					     &SdoObject.m_uiSize,
-					     SdoObject.m_SdoType, pBufHeader);
-
-			// return actual SDO handle (SdoObject.m_SdoComConHdl)
-			iErr = put_user(SdoObject.m_SdoComConHdl,
-					(unsigned int *)(ulArg_p +
-							 (unsigned long)
-							 &SdoObject.
-							 m_SdoComConHdl -
-							 (unsigned long)
-							 &SdoObject));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if (EplRet == kEplSuccessful) {
-				iErr =
-				    copy_to_user(SdoObject.m_le_pData, pData,
-						 SdoObject.m_uiSize);
-
-				vfree(pBufHeader);
-
-				if (iErr != 0) {
-					iRet = -EIO;
-					goto Exit;
-				}
-				// return actual size (SdoObject.m_uiSize)
-				iErr = put_user(SdoObject.m_uiSize,
-						(unsigned int *)(ulArg_p +
-								 (unsigned long)
-								 &SdoObject.
-								 m_uiSize -
-								 (unsigned long)
-								 &SdoObject));
-				if (iErr != 0) {
-					iRet = -EIO;
-					goto Exit;
-				}
-			} else if (EplRet != kEplApiTaskDeferred) {	// error ocurred
-				vfree(pBufHeader);
-				if (iErr != 0) {
-					iRet = -EIO;
-					goto Exit;
-				}
-			}
-
-			iRet = (int)EplRet;
-			break;
-		}
-
-	case EPLLIN_CMD_WRITE_OBJECT:
-		{
-			tEplLinSdoObject SdoObject;
-			void *pData;
-			tEplLinSdoBufHeader *pBufHeader;
-			tEplSdoComConHdl *pSdoComConHdl;
-
-			iErr =
-			    copy_from_user(&SdoObject, (const void *)ulArg_p,
-					   sizeof(SdoObject));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if ((SdoObject.m_le_pData == NULL)
-			    || (SdoObject.m_uiSize == 0)) {
-				iRet = (int)kEplApiInvalidParam;
-				goto Exit;
-			}
-
-			pBufHeader =
-			    (tEplLinSdoBufHeader *)
-			    vmalloc(sizeof(tEplLinSdoBufHeader) +
-				    SdoObject.m_uiSize);
-			if (pBufHeader == NULL) {	// no memory available
-				iRet = -ENOMEM;
-				goto Exit;
-			}
-			// initiate temporary buffer
-			pBufHeader->m_pUserArg = SdoObject.m_pUserArg;	// original user argument pointer
-			pBufHeader->m_pData = SdoObject.m_le_pData;	// original data pointer from app
-			pData = pBufHeader + sizeof(tEplLinSdoBufHeader);
-
-			iErr =
-			    copy_from_user(pData, SdoObject.m_le_pData,
-					   SdoObject.m_uiSize);
-
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if (SdoObject.m_fValidSdoComConHdl != FALSE) {
-				pSdoComConHdl = &SdoObject.m_SdoComConHdl;
-			} else {
-				pSdoComConHdl = NULL;
-			}
-
-			EplRet =
-			    EplApiWriteObject(pSdoComConHdl,
-					      SdoObject.m_uiNodeId,
-					      SdoObject.m_uiIndex,
-					      SdoObject.m_uiSubindex, pData,
-					      SdoObject.m_uiSize,
-					      SdoObject.m_SdoType, pBufHeader);
-
-			// return actual SDO handle (SdoObject.m_SdoComConHdl)
-			iErr = put_user(SdoObject.m_SdoComConHdl,
-					(unsigned int *)(ulArg_p +
-							 (unsigned long)
-							 &SdoObject.
-							 m_SdoComConHdl -
-							 (unsigned long)
-							 &SdoObject));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if (EplRet != kEplApiTaskDeferred) {	// succeeded or error ocurred, but task not deferred
-				vfree(pBufHeader);
-			}
-
-			iRet = (int)EplRet;
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_FREE_SDO_CHANNEL:
-		{
-			// forward SDO handle to EPL stack
-			EplRet =
-			    EplApiFreeSdoChannel((tEplSdoComConHdl) ulArg_p);
-
-			iRet = (int)EplRet;
-			break;
-		}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_MN_TRIGGER_STATE_CHANGE:
-		{
-			tEplLinNodeCmdObject NodeCmdObject;
-
-			iErr =
-			    copy_from_user(&NodeCmdObject,
-					   (const void *)ulArg_p,
-					   sizeof(NodeCmdObject));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			EplRet =
-			    EplApiMnTriggerStateChange(NodeCmdObject.m_uiNodeId,
-						       NodeCmdObject.
-						       m_NodeCommand);
-			iRet = (int)EplRet;
-			break;
-		}
-#endif
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_GET_EVENT:
-		{
-			tEplLinEvent Event;
-
-			// save event structure
-			iErr =
-			    copy_from_user(&Event, (const void *)ulArg_p,
-					   sizeof(Event));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-			// save return code from application's event callback function
-			RetCbEvent_g = Event.m_RetCbEvent;
-
-			if (RetCbEvent_g == kEplShutdown) {
-				// pass control to event queue kernel thread, but signal termination
-				atomic_set(&AtomicEventState_g,
-					   EVENT_STATE_TERM);
-				wake_up_interruptible(&WaitQueueCbEvent_g);
-				// exit with error -> EplApiProcess() will leave the infinite loop
-				iRet = 1;
-				goto Exit;
-			}
-			// pass control to event queue kernel thread
-			atomic_set(&AtomicEventState_g, EVENT_STATE_IOCTL);
-			wake_up_interruptible(&WaitQueueCbEvent_g);
-
-			// fall asleep itself in own wait queue
-			iErr = wait_event_interruptible(WaitQueueProcess_g,
-							(atomic_read
-							 (&AtomicEventState_g)
-							 == EVENT_STATE_READY)
-							||
-							(atomic_read
-							 (&AtomicEventState_g)
-							 == EVENT_STATE_TERM));
-			if (iErr != 0) {	// waiting was interrupted by signal
-				// pass control to event queue kernel thread, but signal termination
-				atomic_set(&AtomicEventState_g,
-					   EVENT_STATE_TERM);
-				wake_up_interruptible(&WaitQueueCbEvent_g);
-				// exit with this error -> EplApiProcess() will leave the infinite loop
-				iRet = iErr;
-				goto Exit;
-			} else if (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM) {	// termination in progress
-				// pass control to event queue kernel thread, but signal termination
-				wake_up_interruptible(&WaitQueueCbEvent_g);
-				// exit with this error -> EplApiProcess() will leave the infinite loop
-				iRet = 1;
-				goto Exit;
-			}
-			// copy event to user space
-			iErr =
-			    copy_to_user(Event.m_pEventType, &EventType_g,
-					 sizeof(EventType_g));
-			if (iErr != 0) {	// not all data could be copied
-				iRet = -EIO;
-				goto Exit;
-			}
-			// $$$ d.k. perform SDO event processing
-			if (EventType_g == kEplApiEventSdo) {
-				void *pData;
-				tEplLinSdoBufHeader *pBufHeader;
-
-				pBufHeader =
-				    (tEplLinSdoBufHeader *) pEventArg_g->m_Sdo.
-				    m_pUserArg;
-				pData =
-				    pBufHeader + sizeof(tEplLinSdoBufHeader);
-
-				if (pEventArg_g->m_Sdo.m_SdoAccessType ==
-				    kEplSdoAccessTypeRead) {
-					// copy read data to user space
-					iErr =
-					    copy_to_user(pBufHeader->m_pData,
-							 pData,
-							 pEventArg_g->m_Sdo.
-							 m_uiTransferredByte);
-					if (iErr != 0) {	// not all data could be copied
-						iRet = -EIO;
-						goto Exit;
-					}
-				}
-				pEventArg_g->m_Sdo.m_pUserArg =
-				    pBufHeader->m_pUserArg;
-				vfree(pBufHeader);
-			}
-
-			iErr =
-			    copy_to_user(Event.m_pEventArg, pEventArg_g,
-					 min(sizeof(tEplApiEventArg),
-					     Event.m_uiEventArgSize));
-			if (iErr != 0) {	// not all data could be copied
-				iRet = -EIO;
-				goto Exit;
-			}
-			// return to EplApiProcess(), which will call the application's event callback function
-			iRet = 0;
-
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_PI_SETUP:
-		{
-			EplRet = EplApiProcessImageSetup();
-			iRet = (int)EplRet;
-
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_PI_IN:
-		{
-			tEplApiProcessImage ProcessImageIn;
-
-			// save process image structure
-			iErr =
-			    copy_from_user(&ProcessImageIn,
-					   (const void *)ulArg_p,
-					   sizeof(ProcessImageIn));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-			// pass control to event queue kernel thread
-			atomic_set(&AtomicSyncState_g, EVENT_STATE_IOCTL);
-
-			// fall asleep itself in own wait queue
-			iErr = wait_event_interruptible(WaitQueuePI_In_g,
-							(atomic_read
-							 (&AtomicSyncState_g) ==
-							 EVENT_STATE_READY)
-							||
-							(atomic_read
-							 (&AtomicSyncState_g) ==
-							 EVENT_STATE_TERM));
-			if (iErr != 0) {	// waiting was interrupted by signal
-				// pass control to sync kernel thread, but signal termination
-				atomic_set(&AtomicSyncState_g,
-					   EVENT_STATE_TERM);
-				wake_up_interruptible(&WaitQueueCbSync_g);
-				// exit with this error -> application will leave the infinite loop
-				iRet = iErr;
-				goto Exit;
-			} else if (atomic_read(&AtomicSyncState_g) == EVENT_STATE_TERM) {	// termination in progress
-				// pass control to sync kernel thread, but signal termination
-				wake_up_interruptible(&WaitQueueCbSync_g);
-				// exit with this error -> application will leave the infinite loop
-				iRet = 1;
-				goto Exit;
-			}
-			// exchange process image
-			EplRet = EplApiProcessImageExchangeIn(&ProcessImageIn);
-
-			// return to EplApiProcessImageExchangeIn()
-			iRet = (int)EplRet;
-
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_PI_OUT:
-		{
-			tEplApiProcessImage ProcessImageOut;
-
-			// save process image structure
-			iErr =
-			    copy_from_user(&ProcessImageOut,
-					   (const void *)ulArg_p,
-					   sizeof(ProcessImageOut));
-			if (iErr != 0) {
-				iRet = -EIO;
-				goto Exit;
-			}
-
-			if (atomic_read(&AtomicSyncState_g) !=
-			    EVENT_STATE_READY) {
-				iRet = (int)kEplInvalidOperation;
-				goto Exit;
-			}
-			// exchange process image
-			EplRet =
-			    EplApiProcessImageExchangeOut(&ProcessImageOut);
-
-			// pass control to sync kernel thread
-			atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM);
-			wake_up_interruptible(&WaitQueueCbSync_g);
-
-			// return to EplApiProcessImageExchangeout()
-			iRet = (int)EplRet;
-
-			break;
-		}
-
-		// ----------------------------------------------------------
-	case EPLLIN_CMD_NMT_COMMAND:
-		{
-			// forward NMT command to EPL stack
-			EplRet = EplApiExecNmtCommand((tEplNmtEvent) ulArg_p);
-
-			iRet = (int)EplRet;
-
-			break;
-		}
-
-		// ----------------------------------------------------------
-	default:
-		{
-			break;
-		}
-	}
-
-      Exit:
-
-//    TRACE1("EPL: - EplLinIoctl (iRet=%d)\n", iRet);
-	return (iRet);
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-tEplKernel EplLinCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-			 tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
-			 void *pUserArg_p)
-{
-	tEplKernel EplRet = kEplSuccessful;
-	int iErr;
-
-	// block any further call to this function, i.e. enter critical section
-	iErr = down_interruptible(&SemaphoreCbEvent_g);
-	if (iErr != 0) {	// waiting was interrupted by signal
-		EplRet = kEplShutdown;
-		goto Exit;
-	}
-	// wait for EplApiProcess() to call ioctl
-	// normally it should be waiting already for us to pass a new event
-	iErr = wait_event_interruptible(WaitQueueCbEvent_g,
-					(atomic_read(&AtomicEventState_g) ==
-					 EVENT_STATE_IOCTL)
-					|| (atomic_read(&AtomicEventState_g) ==
-					    EVENT_STATE_TERM));
-	if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM)) {	// waiting was interrupted by signal
-		EplRet = kEplShutdown;
-		goto LeaveCriticalSection;
-	}
-	// save event information for ioctl
-	EventType_g = EventType_p;
-	pEventArg_g = pEventArg_p;
-
-	// pass control to application's event callback function, i.e. EplApiProcess()
-	atomic_set(&AtomicEventState_g, EVENT_STATE_READY);
-	wake_up_interruptible(&WaitQueueProcess_g);
-
-	// now, the application's event callback function processes the event
-
-	// wait for completion of application's event callback function, i.e. EplApiProcess() calls ioctl again
-	iErr = wait_event_interruptible(WaitQueueCbEvent_g,
-					(atomic_read(&AtomicEventState_g) ==
-					 EVENT_STATE_IOCTL)
-					|| (atomic_read(&AtomicEventState_g) ==
-					    EVENT_STATE_TERM));
-	if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_TERM)) {	// waiting was interrupted by signal
-		EplRet = kEplShutdown;
-		goto LeaveCriticalSection;
-	}
-	// read return code from application's event callback function
-	EplRet = RetCbEvent_g;
-
-      LeaveCriticalSection:
-	up(&SemaphoreCbEvent_g);
-
-      Exit:
-	// check if NMT_GS_OFF is reached
-	if (EventType_p == kEplApiEventNmtStateChange) {
-		if (pEventArg_p->m_NmtStateChange.m_NewNmtState == kEplNmtGsOff) {	// NMT state machine was shut down
-			TRACE0("EPL:   EplLinCbEvent(NMT_GS_OFF)\n");
-			uiEplState_g = EPL_STATE_SHUTDOWN;
-			atomic_set(&AtomicEventState_g, EVENT_STATE_TERM);
-			wake_up(&WaitQueueRelease_g);
-		} else {	// NMT state machine is running
-			uiEplState_g = EPL_STATE_RUNNING;
-		}
-	}
-
-	return EplRet;
-}
-
-tEplKernel EplLinCbSync(void)
-{
-	tEplKernel EplRet = kEplSuccessful;
-	int iErr;
-
-	// check if user process waits for sync
-	if (atomic_read(&AtomicSyncState_g) == EVENT_STATE_IOCTL) {
-		// pass control to application, i.e. EplApiProcessImageExchangeIn()
-		atomic_set(&AtomicSyncState_g, EVENT_STATE_READY);
-		wake_up_interruptible(&WaitQueuePI_In_g);
-
-		// now, the application processes the sync event
-
-		// wait for call of EplApiProcessImageExchangeOut()
-		iErr = wait_event_interruptible(WaitQueueCbSync_g,
-						(atomic_read(&AtomicSyncState_g)
-						 == EVENT_STATE_IOCTL)
-						||
-						(atomic_read(&AtomicSyncState_g)
-						 == EVENT_STATE_TERM));
-		if ((iErr != 0) || (atomic_read(&AtomicEventState_g) == EVENT_STATE_IOCTL)) {	// waiting was interrupted by signal or application called wrong function
-			EplRet = kEplShutdown;
-		}
-	} else {		// application is currently not waiting for sync
-		// continue without interruption
-		// TPDO are set valid by caller (i.e. EplEventkProcess())
-	}
-
-	TGT_DBG_SIGNAL_TRACE_POINT(1);
-
-	return EplRet;
-}
-
-// EOF
diff --git a/drivers/staging/epl/EplApiProcessImage.c b/drivers/staging/epl/EplApiProcessImage.c
deleted file mode 100644
index 7d55086..0000000
--- a/drivers/staging/epl/EplApiProcessImage.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for EPL API module (process image)
-
-  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: EplApiProcessImage.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.7 $  $Date: 2008/11/13 17:13:09 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/10/10 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "Epl.h"
-
-#include <linux/uaccess.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  EplApi                                              */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-#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
-	u8 m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
-#endif
-#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
-	u8 m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
-#endif
-
-} tEplApiProcessImageInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplApiProcessImageInstance EplApiProcessImageInstance_g;
-#endif
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplApiProcessImageSetup()
-//
-// Description: sets up static process image
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplApiProcessImageSetup(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
-	unsigned int uiVarEntries;
-	tEplObdSize ObdSize;
-#endif
-
-#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN;
-	ObdSize = 1;
-	Ret = EplApiLinkObject(0x2000,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageInput, &uiVarEntries, &ObdSize,
-			       1);
-
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN;
-	ObdSize = 1;
-	Ret = EplApiLinkObject(0x2001,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageInput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 2;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
-	Ret = EplApiLinkObject(0x2010,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageInput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 2;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
-	Ret = EplApiLinkObject(0x2011,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageInput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 4;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
-	Ret = EplApiLinkObject(0x2020,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageInput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 4;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_IN / ObdSize;
-	Ret = EplApiLinkObject(0x2021,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageInput, &uiVarEntries, &ObdSize,
-			       1);
-#endif
-
-#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT;
-	ObdSize = 1;
-	Ret = EplApiLinkObject(0x2030,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageOutput, &uiVarEntries, &ObdSize,
-			       1);
-
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT;
-	ObdSize = 1;
-	Ret = EplApiLinkObject(0x2031,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageOutput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 2;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
-	Ret = EplApiLinkObject(0x2040,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageOutput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 2;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
-	Ret = EplApiLinkObject(0x2041,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageOutput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 4;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
-	Ret = EplApiLinkObject(0x2050,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageOutput, &uiVarEntries, &ObdSize,
-			       1);
-
-	ObdSize = 4;
-	uiVarEntries = EPL_API_PROCESS_IMAGE_SIZE_OUT / ObdSize;
-	Ret = EplApiLinkObject(0x2051,
-			       EplApiProcessImageInstance_g.
-			       m_abProcessImageOutput, &uiVarEntries, &ObdSize,
-			       1);
-#endif
-
-	return Ret;
-}
-
-//----------------------------------------------------------------------------
-// Function:    EplApiProcessImageExchangeIn()
-//
-// Description: replaces passed input process image with the one of EPL stack
-//
-// Parameters:  pPI_p                   = input process image
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//----------------------------------------------------------------------------
-
-tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
-	copy_to_user(pPI_p->m_pImage,
-		     EplApiProcessImageInstance_g.m_abProcessImageInput,
-		     min(pPI_p->m_uiSize,
-			 sizeof(EplApiProcessImageInstance_g.
-				m_abProcessImageInput)));
-#endif
-
-	return Ret;
-}
-
-//----------------------------------------------------------------------------
-// Function:    EplApiProcessImageExchangeOut()
-//
-// Description: copies passed output process image to EPL stack.
-//
-// Parameters:  pPI_p                   = output process image
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//----------------------------------------------------------------------------
-
-tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
-	copy_from_user(EplApiProcessImageInstance_g.m_abProcessImageOutput,
-		       pPI_p->m_pImage,
-		       min(pPI_p->m_uiSize,
-			   sizeof(EplApiProcessImageInstance_g.
-				  m_abProcessImageOutput)));
-#endif
-
-	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/EplCfg.h b/drivers/staging/epl/EplCfg.h
deleted file mode 100644
index 38e958a..0000000
--- a/drivers/staging/epl/EplCfg.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  configuration file
-
-  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: EplCfg.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    ...
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/06    k.t.: Start of Implementation
-
-****************************************************************************/
-
-#ifndef _EPLCFG_H_
-#define _EPLCFG_H_
-
-// =========================================================================
-// generic defines which for whole EPL Stack
-// =========================================================================
-#define EPL_USE_DELETEINST_FUNC TRUE
-
-// needed to support datatypes over 32 bit by global.h
-#define USE_VAR64
-
-// EPL_MAX_INSTANCES specifies count of instances of all EPL modules.
-// If it is greater than 1 the first parameter of all
-// functions is the instance number.
-#define EPL_MAX_INSTANCES               1
-
-// This defines the target hardware. Here is encoded wich CPU and wich external
-// peripherals are connected. For possible values refere to target.h. If
-// necessary value is not available EPL stack has to
-// be adapted and tested.
-#define TARGET_HARDWARE                 TGTHW_PC_WRAPP
-
-// use no FIFOs, make direct calls
-//#define EPL_NO_FIFO
-
-// use no IPC between user- and kernelspace modules, make direct calls
-#define EPL_NO_USER_KERNEL
-
-#ifndef BENCHMARK_MODULES
-#define BENCHMARK_MODULES       0	//0xEE800042L
-#endif
-
-// Default defug level:
-// Only debug traces of these modules will be compiled which flags are set in define DEF_DEBUG_LVL.
-#ifndef DEF_DEBUG_LVL
-#define DEF_DEBUG_LVL           0xEC000000L
-#endif
-//   EPL_DBGLVL_OBD         =   0x00000004L
-// * EPL_DBGLVL_ASSERT      =   0x20000000L
-// * EPL_DBGLVL_ERROR       =   0x40000000L
-// * EPL_DBGLVL_ALWAYS      =   0x80000000L
-
-// EPL_MODULE_INTEGRATION defines all modules which are included in
-// EPL application. Please add or delete modules for your application.
-#define EPL_MODULE_INTEGRATION EPL_MODULE_OBDK \
-                               | EPL_MODULE_PDOK \
-                               | EPL_MODULE_NMT_MN \
-                               | EPL_MODULE_SDOS \
-                               | EPL_MODULE_SDOC \
-                               | EPL_MODULE_SDO_ASND \
-                               | EPL_MODULE_SDO_UDP \
-                               | EPL_MODULE_NMT_CN \
-                               | EPL_MODULE_NMTU \
-                               | EPL_MODULE_NMTK \
-                               | EPL_MODULE_DLLK \
-                               | EPL_MODULE_DLLU \
-                               | EPL_MODULE_VETH
-//                               | EPL_MODULE_OBDU
-
-// =========================================================================
-// EPL ethernet driver (Edrv) specific defines
-// =========================================================================
-
-// switch this define to TRUE if Edrv supports fast tx frames
-#define EDRV_FAST_TXFRAMES              FALSE
-//#define EDRV_FAST_TXFRAMES              TRUE
-
-// switch this define to TRUE if Edrv supports early receive interrupts
-#define EDRV_EARLY_RX_INT               FALSE
-//#define EDRV_EARLY_RX_INT               TRUE
-
-// enables setting of several port pins for benchmarking purposes
-#define EDRV_BENCHMARK                  FALSE
-//#define EDRV_BENCHMARK                  TRUE // MCF_GPIO_PODR_PCIBR
-
-// Call Tx handler (i.e. EplDllCbFrameTransmitted()) already if DMA has finished,
-// otherwise call the Tx handler if frame was actually transmitted over ethernet.
-#define EDRV_DMA_TX_HANDLER             FALSE
-//#define EDRV_DMA_TX_HANDLER             TRUE
-
-// number of used ethernet controller
-//#define EDRV_USED_ETH_CTRL              1
-
-// =========================================================================
-// Data Link Layer (DLL) specific defines
-// =========================================================================
-
-// switch this define to TRUE if Edrv supports fast tx frames
-// and DLL shall pass PRes as ready to Edrv after SoC
-#define EPL_DLL_PRES_READY_AFTER_SOC    FALSE
-//#define EPL_DLL_PRES_READY_AFTER_SOC    TRUE
-
-// switch this define to TRUE if Edrv supports fast tx frames
-// and DLL shall pass PRes as ready to Edrv after SoA
-#define EPL_DLL_PRES_READY_AFTER_SOA    FALSE
-//#define EPL_DLL_PRES_READY_AFTER_SOA    TRUE
-
-// =========================================================================
-// OBD specific defines
-// =========================================================================
-
-// switch this define to TRUE if Epl should compare object range
-// automaticly
-#define EPL_OBD_CHECK_OBJECT_RANGE          FALSE
-//#define EPL_OBD_CHECK_OBJECT_RANGE          TRUE
-
-// set this define to TRUE if there are strings or domains in OD, which
-// may be changed in object size and/or object data pointer by its object
-// callback function (called event kObdEvWrStringDomain)
-//#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM    FALSE
-#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM    TRUE
-
-#define EPL_OBD_USE_VARIABLE_SUBINDEX_TAB TRUE
-
-// =========================================================================
-// Timer module specific defines
-// =========================================================================
-
-// if TRUE it uses the Timer module implementation of EPL user also in EPL kernel
-#define EPL_TIMER_USE_USER              TRUE
-
-// if TRUE the high resolution timer module will be used
-#define EPL_TIMER_USE_HIGHRES              TRUE
-//#define EPL_TIMER_USE_HIGHRES              FALSE
-
-#endif //_EPLCFG_H_
diff --git a/drivers/staging/epl/EplDef.h b/drivers/staging/epl/EplDef.h
deleted file mode 100644
index 1dc8108..0000000
--- a/drivers/staging/epl/EplDef.h
+++ /dev/null
@@ -1,355 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for EPL default constants
-
-  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: EplDef.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.15 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_DEF_H_
-#define _EPL_DEF_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define EPL_C_ADR_BROADCAST         0xFF	// EPL broadcast address
-#define EPL_C_ADR_DIAG_DEF_NODE_ID  0xFD	// EPL default address of dignostic device
-#define EPL_C_ADR_DUMMY_NODE_ID     0xFC	// EPL dummy node address
-#define EPL_C_ADR_INVALID           0x00	// invalid EPL address
-#define EPL_C_ADR_MN_DEF_NODE_ID    0xF0	// EPL default address of MN
-#define EPL_C_ADR_RT1_DEF_NODE_ID   0xFE	// EPL default address of router type 1
-#define EPL_C_DLL_ASND_PRIO_NMTRQST 7	// increased ASnd request priority to be used by NMT Requests
-#define EPL_C_DLL_ASND_PRIO_STD     0	// standard ASnd request priority
-#define EPL_C_DLL_ETHERTYPE_EPL     0x88AB
-#define EPL_C_DLL_ISOCHR_MAX_PAYL   1490	// Byte: maximum size of PReq and PRes payload data, requires C_IP_MAX_MTU
-#define EPL_C_DLL_MAX_ASYNC_MTU     1500	// Byte: maximum asynchronous payload in bytes
-#define EPL_C_DLL_MAX_PAYL_OFFSET   1499	// Byte: maximum offset of Ethernet frame payload, requires C_IP_MAX_MTU
-#define EPL_C_DLL_MAX_RS            7
-#define EPL_C_DLL_MIN_ASYNC_MTU     282	// Byte: minimum asynchronous payload in bytes.
-#define EPL_C_DLL_MIN_PAYL_OFFSET   45	// Byte: minimum offset of Ethernet frame payload
-#define EPL_C_DLL_MULTICAST_ASND    0x01111E000004LL	// EPL ASnd multicast MAC address, canonical form
-#define EPL_C_DLL_MULTICAST_PRES    0x01111E000002LL	// EPL PRes multicast MAC address, canonical form
-#define EPL_C_DLL_MULTICAST_SOA     0x01111E000003LL	// EPL SoA multicast MAC address, canonical form
-#define EPL_C_DLL_MULTICAST_SOC     0x01111E000001LL	// EPL Soc multicast MAC address, canonical form
-#define EPL_C_DLL_PREOP1_START_CYCLES 10	// number of unassigning SoA frames at start of NMT_MS_PRE_OPERATIONAL_1
-#define EPL_C_DLL_T_BITTIME         10	// ns: Transmission time per bit on 100 Mbit/s network
-#define EPL_C_DLL_T_EPL_PDO_HEADER  10	// Byte: size of PReq and PRes EPL PDO message header
-#define EPL_C_DLL_T_ETH2_WRAPPER    18	// Byte: size of Ethernet type II wrapper consisting of header and checksum
-#define EPL_C_DLL_T_IFG             640	// ns: Ethernet Interframe Gap
-#define EPL_C_DLL_T_MIN_FRAME       5120	// ns: Size of minimum Ethernet frame (without preamble)
-#define EPL_C_DLL_T_PREAMBLE        960	// ns: Size of Ethernet frame preamble
-
-#define EPL_C_DLL_MINSIZE_SOC       36	// minimum size of SoC without padding and CRC
-#define EPL_C_DLL_MINSIZE_PREQ      60	// minimum size of PRec without CRC
-#define EPL_C_DLL_MINSIZE_PRES      60	// minimum size of PRes without CRC
-#define EPL_C_DLL_MINSIZE_SOA       24	// minimum size of SoA without padding and CRC
-#define EPL_C_DLL_MINSIZE_IDENTRES  176	// minimum size of IdentResponse without CRC
-#define EPL_C_DLL_MINSIZE_STATUSRES 72	// minimum size of StatusResponse without CRC
-#define EPL_C_DLL_MINSIZE_NMTCMD    20	// minimum size of NmtCommand without CommandData, padding and CRC
-#define EPL_C_DLL_MINSIZE_NMTCMDEXT 52	// minimum size of NmtCommand without padding and CRC
-#define EPL_C_DLL_MINSIZE_NMTREQ    20	// minimum size of NmtRequest without CommandData, padding and CRC
-#define EPL_C_DLL_MINSIZE_NMTREQEXT 52	// minimum size of NmtRequest without padding and CRC
-
-#define EPL_C_ERR_MONITOR_DELAY     10	// Error monitoring start delay (not used in DS 1.0.0)
-#define EPL_C_IP_ADR_INVALID        0x00000000L	// invalid IP address (0.0.0.0) used to indicate no change
-#define EPL_C_IP_INVALID_MTU        0	// Byte: invalid MTU size used to indicate no change
-#define EPL_C_IP_MAX_MTU            1518	// Byte: maximum size in bytes of the IP stack which must be processed.
-#define EPL_C_IP_MIN_MTU            300	// Byte: minimum size in bytes of the IP stack which must be processed.
-#define EPL_C_NMT_STATE_TOLERANCE   5	// Cycles: maximum reaction time to NMT state commands
-#define EPL_C_NMT_STATREQ_CYCLE     5	// sec: StatusRequest cycle time to be applied to AsyncOnly CNs
-#define EPL_C_SDO_EPL_PORT          3819
-
-#define EPL_C_DLL_MAX_ASND_SERVICE_IDS  5	// see tEplDllAsndServiceId in EplDll.h
-
-// Default configuration
-// ======================
-
-#ifndef EPL_D_PDO_Granularity_U8
-#define EPL_D_PDO_Granularity_U8    8	// minimum size of objects to be mapped in bits UNSIGNED8 O O 1 1
-#endif
-
-#ifndef EPL_NMT_MAX_NODE_ID
-#define EPL_NMT_MAX_NODE_ID         254	// maximum node-ID
-#endif
-
-#ifndef EPL_D_NMT_MaxCNNumber_U8
-#define EPL_D_NMT_MaxCNNumber_U8    239	// maximum number of supported regular CNs in the Node ID range 1 .. 239 UNSIGNED8 O O 239 239
-#endif
-
-// defines for EPL API layer static process image
-#ifndef EPL_API_PROCESS_IMAGE_SIZE_IN
-#define EPL_API_PROCESS_IMAGE_SIZE_IN   0
-#endif
-
-#ifndef EPL_API_PROCESS_IMAGE_SIZE_OUT
-#define EPL_API_PROCESS_IMAGE_SIZE_OUT  0
-#endif
-
-// configure whether OD access events shall be forwarded
-// to user callback function.
-// Because of reentrancy for local OD accesses, this has to be disabled
-// when application resides in other address space as the stack (e.g. if
-// EplApiLinuxUser.c and EplApiLinuxKernel.c are used)
-#ifndef EPL_API_OBD_FORWARD_EVENT
-#define EPL_API_OBD_FORWARD_EVENT       TRUE
-#endif
-
-#ifndef EPL_OBD_MAX_STRING_SIZE
-#define EPL_OBD_MAX_STRING_SIZE        32	// is used for objects 0x1008/0x1009/0x100A
-#endif
-
-#ifndef EPL_OBD_USE_STORE_RESTORE
-#define EPL_OBD_USE_STORE_RESTORE       FALSE
-#endif
-
-#ifndef EPL_OBD_CHECK_OBJECT_RANGE
-#define EPL_OBD_CHECK_OBJECT_RANGE      TRUE
-#endif
-
-#ifndef EPL_OBD_USE_STRING_DOMAIN_IN_RAM
-#define EPL_OBD_USE_STRING_DOMAIN_IN_RAM    TRUE
-#endif
-
-#ifndef EPL_OBD_USE_VARIABLE_SUBINDEX_TAB
-#define EPL_OBD_USE_VARIABLE_SUBINDEX_TAB   TRUE
-#endif
-
-#ifndef EPL_OBD_USE_KERNEL
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0)
-#define EPL_OBD_USE_KERNEL                  TRUE
-#else
-#define EPL_OBD_USE_KERNEL                  FALSE
-#endif
-#endif
-
-#ifndef EPL_OBD_INCLUDE_A000_TO_DEVICE_PART
-#define EPL_OBD_INCLUDE_A000_TO_DEVICE_PART FALSE
-#endif
-
-#ifndef EPL_VETH_NAME
-#define EPL_VETH_NAME       "epl"	// name of net device in Linux
-#endif
-
-/*
-#define EPL_D_CFG_ConfigManager_BOOL // Ability of a MN node to perform Configuration Manager functions BOOLEAN O - N -
-#define EPL_D_CFM_VerifyConf_BOOL   // Support of objects CFM_VerifyConfiguration_REC, CFM_ExpConfDateList_AU32, CFM_ExpConfTimeList_AU32 BOOLEAN O O N N
-#define EPL_D_CFM_VerifyConfId_BOOL // Support of objects CFM_VerifyConfiguration_REC.ConfId_U32 and CFM_ExpConfIdList_AU32 BOOLEAN O O N N
-#define EPL_D_DLL_CNFeatureIsochr_BOOL // CN’s ability to perform isochronous functions BOOLEAN - O - Y
-#define EPL_D_DLL_CNFeatureMultiplex_BOOL // node’s ability to perform control of multiplexed isochronous communication BOOLEAN - O - N
-#define EPL_D_DLL_FeatureCN_BOOL // node’s ability to perform CN functions BOOLEAN O O Y Y
-#define EPL_D_DLL_FeatureMN_BOOL // node’s ability to perform MN functions BOOLEAN M O - N
-#define EPL_D_DLL_MNFeatureMultiplex_BOOL // MN’s ability to perform control of multiplexed isochronous communication BOOLEAN O - Y -
-#define EPL_D_DLL_MNFeaturePResTx_BOOL // MN’s ability to transmit PRes BOOLEAN O - Y -
-#define EPL_D_NMT_ASndRxMaxPayload_U16 // size of ASnd frame receive buffer UNSIGNED16 M M - -
-#define EPL_D_NMT_ASndTxMaxPayload_U16 // size of ASnd frame transmit buffer UNSIGNED16 M M - -
-#define EPL_D_NMT_CNASnd2SoC_U32 // minimum delay between end of reception of ASnd and start of reception of SoC UNSIGNED32 - M - -
-#define EPL_D_NMT_CNASndMaxLatency_U32 // delay between end of SoA reception and start of ASnd transmission UNSIGNED32 - M - -
-#define EPL_D_NMT_CNPResMaxLatency_U32 // delay between end of PReq reception and start of PRes transmission UNSIGNED32 - M - -
-#define EPL_D_NMT_CNSoC2PReq_U32 // CN SoC handling maximum time, a subsequent PReq won’t be handled before SoC handling was finished UNSIGNED32 - M - -
-#define EPL_D_NMT_DeviceType_U32 // Device Type ID UNSIGNED32 M M - -
-#define EPL_D_NMT_EPLVers_U8 EPL // Version implemented by the device UNSIGNED8 M M - -
-#define EPL_D_NMT_ExtStateCmd_BOOL // abitilty to support Extended NMT State Commands BOOLEAN O O Y Y
-#define EPL_D_NMT_InfoSvc_BOOL // ability to support NMT Info Services BOOLEAN O - Y -
-#define EPL_D_NMT_InterfaceAddr_Xh_OSTR // Physical Address of Interface No. Xh OCTET_STRING M M - -
-#define EPL_D_NMT_InterfaceDescr_Xh_VSTR // Description text of Interface No. Xh VISIBLE_STRINGM M - -
-#define EPL_D_NMT_InterfaceMtu_Xh_U32 // MTU of Interface No. Xh UNSIGNED32 M M - -
-#define EPL_D_NMT_InterfaceType_Xh_U8 // Type of Interface No. Xh UNSIGNED8 M M - -
-#define EPL_D_NMT_IsochrRxMaxPayload_U16 // size of isochronous frame receive buffer UNSIGNED16 M M - -
-#define EPL_D_NMT_IsochrTxMaxPayload_U16 // size of isochronous frame transmit buffer UNSIGNED16 M M - -
-#define EPL_D_NMT_ManufactDevName_VS // Manufacturer Device Name VISIBLE_STRING O O - -
-#define EPL_D_NMT_ManufactHwVers_VS // Manufacturer HW version VISIBLE_STRING O O - -
-#define EPL_D_NMT_ManufactSwVers_VS // Manufacturer SW version VISIBLE_STRING O O - -
-#define EPL_D_NMT_MaxCNNodeID_U8 // maximum Node ID available for regular CNs the entry provides an upper limit to the NodeID available for cross traffic PDO reception from a regular CN UNSIGNED8 O O 239 239
-#define EPL_D_NMT_MaxCNNumber_U8 // maximum number of supported regular CNs in the Node ID range 1 .. 239 UNSIGNED8 O O 239 239
-#define EPL_D_NMT_MaxHeartbeats_U8 // number of guard channels UNSIGNED8 O O 254 254
-#define EPL_D_NMT_MNASnd2SoC_U32 // minimum delay between end of reception of ASnd and start of transmission of SoC UNSIGNED32 M - - -
-#define EPL_D_NMT_MNMultiplCycMax_U8 // maximum number of EPL cycles per multiplexed cycle UNSIGNED8 O - 0 -
-#define EPL_D_NMT_MNPRes2PReq_U32 // delay between end of PRes reception and start of PReq transmission UNSIGNED32 M - - -
-#define EPL_D_NMT_MNPRes2PRes_U32 // delay between end of reception of PRes from CNn and start of transmission of PRes by MN UNSIGNED32 M - - -
-#define EPL_D_NMT_MNPResRx2SoA_U32 // delay between end of reception of PRes from CNn and start of transmission of SoA by MN UNSIGNED32 M - - -
-#define EPL_D_NMT_MNPResTx2SoA_U32 // delay between end of PRes transmission by MN and start of transmission of SoA by MN UNSIGNED32 M - - -
-#define EPL_D_NMT_MNSoA2ASndTx_U32 // delay between end of transmission of SoA and start of transmission of ASnd by MN UNSIGNED32 M - - -
-#define EPL_D_NMT_MNSoC2PReq_U32 // MN minimum delay between end of SoC transmission and start of PReq transmission UNSIGNED32 M - - -
-#define EPL_D_NMT_NMTSvcViaUDPIP_BOOL // Ability of a node to perform NMT services via UDP/IP BOOLEAN O - Y -
-#define EPL_D_NMT_NodeIDByHW_BOOL // Ability of a node to support NodeID setup by HW BOOLEAN O O Y Y
-#define EPL_D_NMT_NodeIDBySW_BOOL // Ability of a node to support NodeID setup by SW BOOLEAN O O N N
-#define EPL_D_NMT_ProductCode_U32 // Identity Object Product Code UNSIGNED32 M M - -
-#define EPL_D_NMT_RevisionNo_U32 // Identity Object Revision Number UNSIGNED32 M M - -
-#define EPL_D_NMT_SerialNo_U32 // Identity Object Serial Number UNSIGNED32 M M - -
-#define EPL_D_NMT_SimpleBoot_BOOL // Ability of a MN node to perform Simple Boot Process, if not set Indivual Boot Process shall be proviced BOOLEAN M - - -
-#define EPL_D_NMT_VendorID_U32 // Identity Object Vendor ID UNSIGNED32 M M - -
-#define EPL_D_NWL_Forward_BOOL // Ability of node to forward datagrams BOOLEAN O O N N
-#define EPL_D_NWL_IPSupport_BOOL // Ability of the node cummunicate via IP BOOLEAN - - Y Y
-#define EPL_D_PDO_DynamicMapping_BOOL // Ability of a node to perform dynamic PDO mapping BOOLEAN O O Y Y
-#define EPL_D_PDO_MaxDescrMem_U32 // maximum cumulative memory consumption of TPDO and RPDO describing objects in byte UNSIGNED32 O O MAX_U32 MAX_U32
-#define EPL_D_PDO_RPDOChannels_U8 // number of supported RPDO channels UNSIGNED8 O O 256 256
-#define EPL_D_PDO_RPDOMaxMem_U32 // Maximum memory available for RPDO data per EPL cycle in byte UNSIGNED32 O O MAX_U32 MAX_U32
-#define EPL_D_PDO_RPDOObjects_U8 // Number of supported mapped objects per RPDO channel UNSIGNED8 O O 254 254
-#define EPL_D_PDO_TPDOChannels_U8 // number of supported TPDO channels UNSIGNED8 O - 256 -
-#define EPL_D_PDO_TPDOMaxMem_U32 // Maximum memory available for TPDO data per EPL cycle in byte UNSIGNED32 O O MAX_U32 MAX_U32
-#define EPL_D_PDO_TPDOObjects_U8 // Number of supported mapped objects per TPDO channel UNSIGNED8 O O 254 254
-#define EPL_D_SDO_ViaASnd_BOOL // Ability of a CN to perform SDO transfer by EPL ASnd BOOLEAN - M - -
-#define EPL_D_SDO_ViaPDO_BOOL // Ability of a node to perform SDO transfer by PDO BOOLEAN O O N N
-#define EPL_D_SDO_ViaUDPIP_BOOL // Ability of a CN to perform SDO transfer by UDP/IP BOOLEAN - M - -
-#define EPL_D_SYN_OptimizedSync_BOOL // Ability of node to perform optimized synchronisation BOOLEAN O O N N
-*/
-
-// Emergency error codes
-// ======================
-#define EPL_E_NO_ERROR                  0x0000
-// 0xFxxx manufacturer specific error codes
-#define EPL_E_NMT_NO_IDENT_RES          0xF001
-#define EPL_E_NMT_NO_STATUS_RES         0xF002
-
-// 0x816x HW errors
-#define EPL_E_DLL_BAD_PHYS_MODE         0x8161
-#define EPL_E_DLL_COLLISION             0x8162
-#define EPL_E_DLL_COLLISION_TH          0x8163
-#define EPL_E_DLL_CRC_TH                0x8164
-#define EPL_E_DLL_LOSS_OF_LINK          0x8165
-#define EPL_E_DLL_MAC_BUFFER            0x8166
-// 0x82xx Protocol errors
-#define EPL_E_DLL_ADDRESS_CONFLICT      0x8201
-#define EPL_E_DLL_MULTIPLE_MN           0x8202
-// 0x821x Frame size errors
-#define EPL_E_PDO_SHORT_RX              0x8210
-#define EPL_E_PDO_MAP_VERS              0x8211
-#define EPL_E_NMT_ASND_MTU_DIF          0x8212
-#define EPL_E_NMT_ASND_MTU_LIM          0x8213
-#define EPL_E_NMT_ASND_TX_LIM           0x8214
-// 0x823x Timing errors
-#define EPL_E_NMT_CYCLE_LEN             0x8231
-#define EPL_E_DLL_CYCLE_EXCEED          0x8232
-#define EPL_E_DLL_CYCLE_EXCEED_TH       0x8233
-#define EPL_E_NMT_IDLE_LIM              0x8234
-#define EPL_E_DLL_JITTER_TH             0x8235
-#define EPL_E_DLL_LATE_PRES_TH          0x8236
-#define EPL_E_NMT_PREQ_CN               0x8237
-#define EPL_E_NMT_PREQ_LIM              0x8238
-#define EPL_E_NMT_PRES_CN               0x8239
-#define EPL_E_NMT_PRES_RX_LIM           0x823A
-#define EPL_E_NMT_PRES_TX_LIM           0x823B
-// 0x824x Frame errors
-#define EPL_E_DLL_INVALID_FORMAT        0x8241
-#define EPL_E_DLL_LOSS_PREQ_TH          0x8242
-#define EPL_E_DLL_LOSS_PRES_TH          0x8243
-#define EPL_E_DLL_LOSS_SOA_TH           0x8244
-#define EPL_E_DLL_LOSS_SOC_TH           0x8245
-// 0x84xx BootUp Errors
-#define EPL_E_NMT_BA1                   0x8410	// other MN in MsNotActive active
-#define EPL_E_NMT_BA1_NO_MN_SUPPORT     0x8411	// MN is not supported
-#define EPL_E_NMT_BPO1                  0x8420	// mandatory CN was not found or failed in BootStep1
-#define EPL_E_NMT_BPO1_GET_IDENT        0x8421	// IdentRes was not received
-#define EPL_E_NMT_BPO1_DEVICE_TYPE      0x8422	// wrong device type
-#define EPL_E_NMT_BPO1_VENDOR_ID        0x8423	// wrong vendor ID
-#define EPL_E_NMT_BPO1_PRODUCT_CODE     0x8424	// wrong product code
-#define EPL_E_NMT_BPO1_REVISION_NO      0x8425	// wrong revision number
-#define EPL_E_NMT_BPO1_SERIAL_NO        0x8426	// wrong serial number
-#define EPL_E_NMT_BPO1_CF_VERIFY        0x8428	// verification of configuration failed
-#define EPL_E_NMT_BPO2                  0x8430	// mandatory CN failed in BootStep2
-#define EPL_E_NMT_BRO                   0x8440	// CheckCommunication failed for mandatory CN
-#define EPL_E_NMT_WRONG_STATE           0x8480	// mandatory CN has wrong NMT state
-
-// Defines for object 0x1F80 NMT_StartUp_U32
-// ==========================================
-#define EPL_NMTST_STARTALLNODES         0x00000002L	// Bit 1
-#define EPL_NMTST_NO_AUTOSTART          0x00000004L	// Bit 2
-#define EPL_NMTST_NO_STARTNODE          0x00000008L	// Bit 3
-#define EPL_NMTST_RESETALL_MAND_CN      0x00000010L	// Bit 4
-#define EPL_NMTST_STOPALL_MAND_CN       0x00000040L	// Bit 6
-#define EPL_NMTST_NO_AUTOPREOP2         0x00000080L	// Bit 7
-#define EPL_NMTST_NO_AUTOREADYTOOP      0x00000100L	// Bit 8
-#define EPL_NMTST_EXT_CNIDENTCHECK      0x00000200L	// Bit 9
-#define EPL_NMTST_SWVERSIONCHECK        0x00000400L	// Bit 10
-#define EPL_NMTST_CONFCHECK             0x00000800L	// Bit 11
-#define EPL_NMTST_NO_RETURN_PREOP1      0x00001000L	// Bit 12
-#define EPL_NMTST_BASICETHERNET         0x00002000L	// Bit 13
-
-// Defines for object 0x1F81 NMT_NodeAssignment_AU32
-// ==================================================
-#define EPL_NODEASSIGN_NODE_EXISTS      0x00000001L	// Bit 0
-#define EPL_NODEASSIGN_NODE_IS_CN       0x00000002L	// Bit 1
-#define EPL_NODEASSIGN_START_CN         0x00000004L	// Bit 2
-#define EPL_NODEASSIGN_MANDATORY_CN     0x00000008L	// Bit 3
-#define EPL_NODEASSIGN_KEEPALIVE        0x00000010L	//currently not used in EPL V2 standard
-#define EPL_NODEASSIGN_SWVERSIONCHECK   0x00000020L	// Bit 5
-#define EPL_NODEASSIGN_SWUPDATE         0x00000040L	// Bit 6
-#define EPL_NODEASSIGN_ASYNCONLY_NODE   0x00000100L	// Bit 8
-#define EPL_NODEASSIGN_MULTIPLEXED_CN   0x00000200L	// Bit 9
-#define EPL_NODEASSIGN_RT1              0x00000400L	// Bit 10
-#define EPL_NODEASSIGN_RT2              0x00000800L	// Bit 11
-#define EPL_NODEASSIGN_MN_PRES          0x00001000L	// Bit 12
-#define EPL_NODEASSIGN_VALID            0x80000000L	// Bit 31
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_DEF_H_
diff --git a/drivers/staging/epl/EplDll.h b/drivers/staging/epl/EplDll.h
deleted file mode 100644
index b960199..0000000
--- a/drivers/staging/epl/EplDll.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for DLL 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: EplDll.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/08 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_DLL_H_
-#define _EPL_DLL_H_
-
-#include "EplInc.h"
-#include "EplFrame.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef EPL_DLL_MAX_ASND_SERVICE_ID
-#define EPL_DLL_MAX_ASND_SERVICE_ID (EPL_C_DLL_MAX_ASND_SERVICE_IDS + 1)	// last is kEplDllAsndSdo == 5
-#endif
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef enum {
-	kEplDllAsndNotDefined = 0x00,
-	kEplDllAsndIdentResponse = 0x01,
-	kEplDllAsndStatusResponse = 0x02,
-	kEplDllAsndNmtRequest = 0x03,
-	kEplDllAsndNmtCommand = 0x04,
-	kEplDllAsndSdo = 0x05
-} tEplDllAsndServiceId;
-
-typedef enum {
-	kEplDllAsndFilterNone = 0x00,
-	kEplDllAsndFilterLocal = 0x01,	// receive only ASnd frames with local or broadcast node ID
-	kEplDllAsndFilterAny = 0x02,	// receive any ASnd frame
-} tEplDllAsndFilter;
-
-typedef enum {
-	kEplDllReqServiceNo = 0x00,
-	kEplDllReqServiceIdent = 0x01,
-	kEplDllReqServiceStatus = 0x02,
-	kEplDllReqServiceNmtRequest = 0x03,
-	kEplDllReqServiceUnspecified = 0xFF,
-
-} tEplDllReqServiceId;
-
-typedef enum {
-	kEplDllAsyncReqPrioNmt = 0x07,	// PRIO_NMT_REQUEST
-	kEplDllAsyncReqPrio6 = 0x06,
-	kEplDllAsyncReqPrio5 = 0x05,
-	kEplDllAsyncReqPrio4 = 0x04,
-	kEplDllAsyncReqPrioGeneric = 0x03,	// PRIO_GENERIC_REQUEST
-	kEplDllAsyncReqPrio2 = 0x02,	// till WSP 0.1.3: PRIO_ABOVE_GENERIC
-	kEplDllAsyncReqPrio1 = 0x01,	// till WSP 0.1.3: PRIO_BELOW_GENERIC
-	kEplDllAsyncReqPrio0 = 0x00,	// till WSP 0.1.3: PRIO_GENERIC_REQUEST
-
-} tEplDllAsyncReqPriority;
-
-typedef struct {
-	unsigned int m_uiFrameSize;
-	tEplFrame *m_pFrame;
-	tEplNetTime m_NetTime;
-
-} tEplFrameInfo;
-
-typedef struct {
-	unsigned int m_uiSizeOfStruct;
-	BOOL m_fAsyncOnly;	// do not need to register PRes-Frame
-	unsigned int m_uiNodeId;	// local node ID
-
-	// 0x1F82: NMT_FeatureFlags_U32
-	u32 m_dwFeatureFlags;
-	// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
-	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
-	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
-	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
-	unsigned int m_uiAsyncMtu;	// required to set up max frame size
-	// $$$ 0x1F98.9: Prescaler_U16
-	// $$$ Multiplexed Slot
-
-	// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
-	u32 m_dwLossOfFrameTolerance;
-
-	// 0x1F8A: NMT_MNCycleTiming_REC
-	// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
-	u32 m_dwWaitSocPreq;
-
-	// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
-	u32 m_dwAsyncSlotTimeout;
-
-} tEplDllConfigParam;
-
-typedef struct {
-	unsigned int m_uiSizeOfStruct;
-	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;
-	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;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_DLL_H_
diff --git a/drivers/staging/epl/EplDllCal.h b/drivers/staging/epl/EplDllCal.h
deleted file mode 100644
index 70b27b1..0000000
--- a/drivers/staging/epl/EplDllCal.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for DLL Communication Abstraction Layer 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: EplDllCal.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/20 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_DLLCAL_H_
-#define _EPL_DLLCAL_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-/*#ifndef EPL_DLLCAL_BUFFER_ID_RX
-#define EPL_DLLCAL_BUFFER_ID_RX    "EplSblDllCalRx"
-#endif
-
-#ifndef EPL_DLLCAL_BUFFER_SIZE_RX
-#define EPL_DLLCAL_BUFFER_SIZE_RX  32767
-#endif
-*/
-#ifndef EPL_DLLCAL_BUFFER_ID_TX_NMT
-#define EPL_DLLCAL_BUFFER_ID_TX_NMT     "EplSblDllCalTxNmt"
-#endif
-
-#ifndef EPL_DLLCAL_BUFFER_SIZE_TX_NMT
-#define EPL_DLLCAL_BUFFER_SIZE_TX_NMT   32767
-#endif
-
-#ifndef EPL_DLLCAL_BUFFER_ID_TX_GEN
-#define EPL_DLLCAL_BUFFER_ID_TX_GEN     "EplSblDllCalTxGen"
-#endif
-
-#ifndef EPL_DLLCAL_BUFFER_SIZE_TX_GEN
-#define EPL_DLLCAL_BUFFER_SIZE_TX_GEN   32767
-#endif
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef struct {
-	tEplDllAsndServiceId m_ServiceId;
-	tEplDllAsndFilter m_Filter;
-
-} tEplDllCalAsndServiceIdFilter;
-
-typedef struct {
-	tEplDllReqServiceId m_Service;
-	unsigned int m_uiNodeId;
-	u8 m_bSoaFlag1;
-
-} tEplDllCalIssueRequest;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_DLLKCAL_H_
diff --git a/drivers/staging/epl/EplDllk.c b/drivers/staging/epl/EplDllk.c
deleted file mode 100644
index 25d2c34..0000000
--- a/drivers/staging/epl/EplDllk.c
+++ /dev/null
@@ -1,4052 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for kernel DLL 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: EplDllk.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.21 $  $Date: 2008/11/13 17:13:09 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/12 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "kernel/EplDllk.h"
-#include "kernel/EplDllkCal.h"
-#include "kernel/EplEventk.h"
-#include "kernel/EplNmtk.h"
-#include "edrv.h"
-#include "Benchmark.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-#include "kernel/EplPdok.h"
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-#include "kernel/VirtualEthernet.h"
-#endif
-
-//#if EPL_TIMER_USE_HIGHRES != FALSE
-#include "kernel/EplTimerHighResk.h"
-//#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) == 0)
-#error "EPL module DLLK needs EPL module NMTK!"
-#endif
-
-#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) && (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
-#error "EPL module DLLK: select only one of EPL_DLL_PRES_READY_AFTER_SOA and EPL_DLL_PRES_READY_AFTER_SOC."
-#endif
-
-#if ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)) \
-    && (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
-#error "EPL module DLLK: currently, EPL_DLL_PRES_READY_AFTER_* is not supported if EPL_MODULE_NMT_MN is enabled."
-#endif
-
-#if (EDRV_FAST_TXFRAMES == FALSE) && \
-    ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE))
-#error "EPL module DLLK: EPL_DLL_PRES_READY_AFTER_* is enabled, but not EDRV_FAST_TXFRAMES."
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-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
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-#define EPL_DLLK_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
-    TGT_DBG_POST_TRACE_VALUE((kEplEventSinkDllk << 28) | (Event_p << 24) \
-                             | (uiNodeId_p << 16) | wErrorCode_p)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  EplDllk                                             */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// defines for indexes of tEplDllInstance.m_pTxFrameInfo
-#define EPL_DLLK_TXFRAME_IDENTRES   0	// IdentResponse on CN / MN
-#define EPL_DLLK_TXFRAME_STATUSRES  1	// StatusResponse on CN / MN
-#define EPL_DLLK_TXFRAME_NMTREQ     2	// NMT Request from FIFO on CN / MN
-#define EPL_DLLK_TXFRAME_NONEPL     3	// non-EPL frame from FIFO on CN / MN
-#define EPL_DLLK_TXFRAME_PRES       4	// PRes on CN / MN
-#define EPL_DLLK_TXFRAME_SOC        5	// SoC on MN
-#define EPL_DLLK_TXFRAME_SOA        6	// SoA on MN
-#define EPL_DLLK_TXFRAME_PREQ       7	// PReq on MN
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-#define EPL_DLLK_TXFRAME_COUNT      (7 + EPL_D_NMT_MaxCNNumber_U8 + 2)	// on MN: 7 + MaxPReq of regular CNs + 1 Diag + 1 Router
-#else
-#define EPL_DLLK_TXFRAME_COUNT      5	// on CN: 5
-#endif
-
-#define EPL_DLLK_BUFLEN_EMPTY       0	// buffer is empty
-#define EPL_DLLK_BUFLEN_FILLING     1	// just the buffer is being filled
-#define EPL_DLLK_BUFLEN_MIN         60	// minimum ethernet frame length
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef enum {
-	kEplDllGsInit = 0x00,	// MN/CN: initialisation (< PreOp2)
-	kEplDllCsWaitPreq = 0x01,	// CN: wait for PReq frame
-	kEplDllCsWaitSoc = 0x02,	// CN: wait for SoC frame
-	kEplDllCsWaitSoa = 0x03,	// CN: wait for SoA frame
-	kEplDllMsNonCyclic = 0x04,	// MN: reduced EPL cycle (PreOp1)
-	kEplDllMsWaitSocTrig = 0x05,	// MN: wait for SoC trigger (cycle timer)
-	kEplDllMsWaitPreqTrig = 0x06,	// MN: wait for (first) PReq trigger (WaitSoCPReq_U32)
-	kEplDllMsWaitPres = 0x07,	// MN: wait for PRes frame from CN
-	kEplDllMsWaitSoaTrig = 0x08,	// MN: wait for SoA trigger (PRes transmitted)
-	kEplDllMsWaitAsndTrig = 0x09,	// MN: wait for ASnd trigger (SoA transmitted)
-	kEplDllMsWaitAsnd = 0x0A,	// MN: wait for ASnd frame if SoA contained invitation
-
-} tEplDllState;
-
-typedef struct {
-	u8 m_be_abSrcMac[6];
-	tEdrvTxBuffer *m_pTxBuffer;	// Buffers for Tx-Frames
-	unsigned int m_uiMaxTxFrames;
-	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;
-	tEplDllkCbAsync m_pfnCbAsync;
-	tEplDllAsndFilter m_aAsndFilter[EPL_DLL_MAX_ASND_SERVICE_ID];
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	tEplDllkNodeInfo *m_pFirstNodeInfo;
-	tEplDllkNodeInfo *m_pCurNodeInfo;
-	tEplDllkNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID];
-	tEplDllReqServiceId m_LastReqServiceId;
-	unsigned int m_uiLastTargetNodeId;
-#endif
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-	tEplTimerHdl m_TimerHdlCycle;	// used for EPL cycle monitoring on CN and generation on MN
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	tEplTimerHdl m_TimerHdlResponse;	// used for CN response monitoring
-#endif				//(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-#endif
-
-	unsigned int m_uiCycleCount;	// cycle counter (needed for multiplexed cycle support)
-	unsigned long long m_ullFrameTimeout;	// frame timeout (cycle length + loss of frame tolerance)
-
-} tEplDllkInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-// if no dynamic memory allocation shall be used
-// define structures statically
-static tEplDllkInstance EplDllkInstance_g;
-
-static tEdrvTxBuffer aEplDllkTxBuffer_l[EPL_DLLK_TXFRAME_COUNT];
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-// change DLL state on event
-static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p,
-				     tEplNmtState NmtState_p);
-
-// called from EdrvInterruptHandler()
-static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p);
-
-// called from EdrvInterruptHandler()
-static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p);
-
-// check frame and set missing information
-static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
-				    unsigned int uiFrameSize_p);
-
-// called by high resolution timer module to monitor EPL cycle as CN
-#if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p);
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-// MN: returns internal node info structure
-static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p);
-
-// transmit SoA
-static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
-				   tEplDllState * pDllStateProposed_p,
-				   BOOL fEnableInvitation_p);
-
-static tEplKernel EplDllkMnSendSoc(void);
-
-static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
-				    tEplDllState * pDllStateProposed_p);
-
-static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
-					       ReqServiceId_p,
-					       unsigned int uiNodeId_p);
-
-static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p);
-
-static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p);
-
-#endif
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkAddInstance()
-//
-// Description: add and initialize new instance of EPL stack
-//
-// Parameters:  pInitParam_p            = initialisation parameters like MAC address
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiIndex;
-	tEdrvInitParam EdrvInitParam;
-
-	// reset instance structure
-	EPL_MEMSET(&EplDllkInstance_g, 0, sizeof(EplDllkInstance_g));
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-	Ret = EplTimerHighReskInit();
-	if (Ret != kEplSuccessful) {	// error occured while initializing high resolution timer module
-		goto Exit;
-	}
-#endif
-
-	// if dynamic memory allocation available
-	// allocate instance structure
-	// allocate TPDO and RPDO table with default size
-
-	// initialize and link pointers in instance structure to frame tables
-	EplDllkInstance_g.m_pTxBuffer = aEplDllkTxBuffer_l;
-	EplDllkInstance_g.m_uiMaxTxFrames =
-	    sizeof(aEplDllkTxBuffer_l) / sizeof(tEdrvTxBuffer);
-
-	// initialize state
-	EplDllkInstance_g.m_DllState = kEplDllGsInit;
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	// set up node info structure
-	for (uiIndex = 0; uiIndex < tabentries(EplDllkInstance_g.m_aNodeInfo);
-	     uiIndex++) {
-		EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
-		EplDllkInstance_g.m_aNodeInfo[uiIndex].m_wPresPayloadLimit =
-		    0xFFFF;
-	}
-#endif
-
-	// initialize Edrv
-	EPL_MEMCPY(EdrvInitParam.m_abMyMacAddr, pInitParam_p->m_be_abSrcMac, 6);
-	EdrvInitParam.m_pfnRxHandler = EplDllkCbFrameReceived;
-	EdrvInitParam.m_pfnTxHandler = EplDllkCbFrameTransmitted;
-	Ret = EdrvInit(&EdrvInitParam);
-	if (Ret != kEplSuccessful) {	// error occured while initializing ethernet driver
-		goto Exit;
-	}
-	// copy local MAC address from Ethernet driver back to local instance structure
-	// because Ethernet driver may have read it from controller EEPROM
-	EPL_MEMCPY(EplDllkInstance_g.m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr,
-		   6);
-	EPL_MEMCPY(pInitParam_p->m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, 6);
-
-	// initialize TxBuffer array
-	for (uiIndex = 0; uiIndex < EplDllkInstance_g.m_uiMaxTxFrames;
-	     uiIndex++) {
-		EplDllkInstance_g.m_pTxBuffer[uiIndex].m_pbBuffer = NULL;
-	}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-	Ret = VEthAddInstance(pInitParam_p);
-#endif
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkDelInstance()
-//
-// Description: deletes an instance of EPL stack
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkDelInstance(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// reset state
-	EplDllkInstance_g.m_DllState = kEplDllGsInit;
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-	Ret = EplTimerHighReskDelInstance();
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-	Ret = VEthDelInstance();
-#endif
-
-	Ret = EdrvShutdown();
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCreateTxFrame
-//
-// Description: creates the buffer for a Tx frame and registers it to the
-//              ethernet driver
-//
-// Parameters:  puiHandle_p             = OUT: handle to frame buffer
-//              ppFrame_p               = OUT: pointer to pointer of EPL frame
-//              puiFrameSize_p          = IN/OUT: pointer to size of frame
-//                                        returned size is always equal or larger than
-//                                        requested size, if that is not possible
-//                                        an error will be returned
-//              MsgType_p               = EPL message type
-//              ServiceId_p             = Service ID in case of ASnd frame, otherwise
-//                                        kEplDllAsndNotDefined
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
-				tEplFrame ** ppFrame_p,
-				unsigned int *puiFrameSize_p,
-				tEplMsgType MsgType_p,
-				tEplDllAsndServiceId ServiceId_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplFrame *pTxFrame;
-	unsigned int uiHandle = EplDllkInstance_g.m_uiMaxTxFrames;
-	tEdrvTxBuffer *pTxBuffer = NULL;
-
-	if (MsgType_p == kEplMsgTypeAsnd) {
-		// search for fixed Tx buffers
-		if (ServiceId_p == kEplDllAsndIdentResponse) {
-			uiHandle = EPL_DLLK_TXFRAME_IDENTRES;
-		} else if (ServiceId_p == kEplDllAsndStatusResponse) {
-			uiHandle = EPL_DLLK_TXFRAME_STATUSRES;
-		} else if ((ServiceId_p == kEplDllAsndNmtRequest)
-			   || (ServiceId_p == kEplDllAsndNmtCommand)) {
-			uiHandle = EPL_DLLK_TXFRAME_NMTREQ;
-		}
-
-		if (uiHandle >= EplDllkInstance_g.m_uiMaxTxFrames) {	// look for free entry
-			uiHandle = EPL_DLLK_TXFRAME_PREQ;
-			pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
-			for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames;
-			     uiHandle++, pTxBuffer++) {
-				if (pTxBuffer->m_pbBuffer == NULL) {	// free entry found
-					break;
-				}
-			}
-		}
-	} else if (MsgType_p == kEplMsgTypeNonEpl) {
-		uiHandle = EPL_DLLK_TXFRAME_NONEPL;
-	} else if (MsgType_p == kEplMsgTypePres) {
-		uiHandle = EPL_DLLK_TXFRAME_PRES;
-	} else if (MsgType_p == kEplMsgTypeSoc) {
-		uiHandle = EPL_DLLK_TXFRAME_SOC;
-	} else if (MsgType_p == kEplMsgTypeSoa) {
-		uiHandle = EPL_DLLK_TXFRAME_SOA;
-	} else {		// look for free entry
-		uiHandle = EPL_DLLK_TXFRAME_PREQ;
-		pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
-		for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames;
-		     uiHandle++, pTxBuffer++) {
-			if (pTxBuffer->m_pbBuffer == NULL) {	// free entry found
-				break;
-			}
-		}
-		if (pTxBuffer->m_pbBuffer != NULL) {
-			Ret = kEplEdrvNoFreeBufEntry;
-			goto Exit;
-		}
-	}
-
-	// test if requested entry is free
-	pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
-	if (pTxBuffer->m_pbBuffer != NULL) {	// entry is not free
-		Ret = kEplEdrvNoFreeBufEntry;
-		goto Exit;
-	}
-	// setup Tx buffer
-	pTxBuffer->m_EplMsgType = MsgType_p;
-	pTxBuffer->m_uiMaxBufferLen = *puiFrameSize_p;
-
-	Ret = EdrvAllocTxMsgBuffer(pTxBuffer);
-	if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-		goto Exit;
-	}
-	// because buffer size may be larger than requested
-	// memorize real length of frame
-	pTxBuffer->m_uiTxMsgLen = *puiFrameSize_p;
-
-	// fill whole frame with 0
-	EPL_MEMSET(pTxBuffer->m_pbBuffer, 0, pTxBuffer->m_uiMaxBufferLen);
-
-	pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
-
-	if (MsgType_p != kEplMsgTypeNonEpl) {	// fill out Frame only if it is an EPL frame
-		// ethertype
-		AmiSetWordToBe(&pTxFrame->m_be_wEtherType,
-			       EPL_C_DLL_ETHERTYPE_EPL);
-		// source node ID
-		AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId,
-			       (u8) EplDllkInstance_g.m_DllConfigParam.
-			       m_uiNodeId);
-		// source MAC address
-		EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0],
-			   &EplDllkInstance_g.m_be_abSrcMac[0], 6);
-		switch (MsgType_p) {
-		case kEplMsgTypeAsnd:
-			// destination MAC address
-			AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
-					  EPL_C_DLL_MULTICAST_ASND);
-			// destination node ID
-			switch (ServiceId_p) {
-			case kEplDllAsndIdentResponse:
-			case kEplDllAsndStatusResponse:
-				{	// IdentResponses and StatusResponses are Broadcast
-					AmiSetByteToLe(&pTxFrame->
-						       m_le_bDstNodeId,
-						       (u8)
-						       EPL_C_ADR_BROADCAST);
-					break;
-				}
-
-			default:
-				break;
-			}
-			// ASnd Service ID
-			AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_le_bServiceId,
-				       ServiceId_p);
-			break;
-
-		case kEplMsgTypeSoc:
-			// destination MAC address
-			AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
-					  EPL_C_DLL_MULTICAST_SOC);
-			// destination node ID
-			AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
-				       (u8) EPL_C_ADR_BROADCAST);
-			// reset Flags
-			//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:
-			// destination MAC address
-			AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
-					  EPL_C_DLL_MULTICAST_SOA);
-			// destination node ID
-			AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
-				       (u8) EPL_C_ADR_BROADCAST);
-			// reset Flags
-			//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,
-				       (u8) EPL_SPEC_VERSION);
-			break;
-
-		case kEplMsgTypePres:
-			// destination MAC address
-			AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
-					  EPL_C_DLL_MULTICAST_PRES);
-			// destination node ID
-			AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
-				       (u8) EPL_C_ADR_BROADCAST);
-			// reset Flags
-			//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, (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;
-
-		default:
-			break;
-		}
-		// EPL message type
-		AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (u8) MsgType_p);
-	}
-
-	*ppFrame_p = pTxFrame;
-	*puiFrameSize_p = pTxBuffer->m_uiMaxBufferLen;
-	*puiHandle_p = uiHandle;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkDeleteTxFrame
-//
-// Description: deletes the buffer for a Tx frame and frees it in the
-//              ethernet driver
-//
-// Parameters:  uiHandle_p              = IN: handle to frame buffer
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkDeleteTxFrame(unsigned int uiHandle_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEdrvTxBuffer *pTxBuffer = NULL;
-
-	if (uiHandle_p >= EplDllkInstance_g.m_uiMaxTxFrames) {	// handle is not valid
-		Ret = kEplDllIllegalHdl;
-		goto Exit;
-	}
-
-	pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle_p];
-
-	// mark buffer as free so that frame will not be send in future anymore
-	// $$$ d.k. What's up with running transmissions?
-	pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
-	pTxBuffer->m_pbBuffer = NULL;
-
-	// delete Tx buffer
-	Ret = EdrvReleaseTxMsgBuffer(pTxBuffer);
-	if (Ret != kEplSuccessful) {	// error occured while releasing Tx frame
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkProcess
-//
-// Description: process the passed event
-//
-// Parameters:  pEvent_p                = event to be processed
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplFrame *pTxFrame;
-	tEdrvTxBuffer *pTxBuffer;
-	unsigned int uiHandle;
-	unsigned int uiFrameSize;
-	u8 abMulticastMac[6];
-	tEplDllAsyncReqPriority AsyncReqPriority;
-	unsigned int uiFrameCount;
-	tEplNmtState NmtState;
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-	tEplFrameInfo FrameInfo;
-#endif
-
-	switch (pEvent_p->m_EventType) {
-	case kEplEventTypeDllkCreate:
-		{
-			// $$$ reset ethernet driver
-
-			NmtState = *((tEplNmtState *) pEvent_p->m_pArg);
-
-			// initialize flags for PRes and StatusRes
-			EplDllkInstance_g.m_bFlag1 = EPL_FRAME_FLAG1_EC;
-			EplDllkInstance_g.m_bMnFlag1 = 0;
-			EplDllkInstance_g.m_bFlag2 = 0;
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			// initialize linked node list
-			EplDllkInstance_g.m_pFirstNodeInfo = NULL;
-#endif
-
-			// register TxFrames in Edrv
-
-			// IdentResponse
-			uiFrameSize = EPL_C_DLL_MINSIZE_IDENTRES;
-			Ret =
-			    EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
-						 &uiFrameSize, kEplMsgTypeAsnd,
-						 kEplDllAsndIdentResponse);
-			if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-				goto Exit;
-			}
-			// EPL profile version
-			AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-				       m_IdentResponse.m_le_bEplProfileVersion,
-				       (u8) EPL_SPEC_VERSION);
-			// FeatureFlags
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwFeatureFlags,
-					EplDllkInstance_g.m_DllConfigParam.
-					m_dwFeatureFlags);
-			// MTU
-			AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-				       m_IdentResponse.m_le_wMtu,
-				       (u16) EplDllkInstance_g.
-				       m_DllConfigParam.m_uiAsyncMtu);
-			// PollInSize
-			AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-				       m_IdentResponse.m_le_wPollInSize,
-				       (u16) EplDllkInstance_g.
-				       m_DllConfigParam.
-				       m_uiPreqActPayloadLimit);
-			// PollOutSize
-			AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-				       m_IdentResponse.m_le_wPollOutSize,
-				       (u16) EplDllkInstance_g.
-				       m_DllConfigParam.
-				       m_uiPresActPayloadLimit);
-			// ResponseTime / PresMaxLatency
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwResponseTime,
-					EplDllkInstance_g.m_DllConfigParam.
-					m_dwPresMaxLatency);
-			// DeviceType
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwDeviceType,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwDeviceType);
-			// VendorId
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwVendorId,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwVendorId);
-			// ProductCode
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwProductCode,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwProductCode);
-			// RevisionNumber
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwRevisionNumber,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwRevisionNumber);
-			// SerialNumber
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwSerialNumber,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwSerialNumber);
-			// VendorSpecificExt1
-			AmiSetQword64ToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					  m_IdentResponse.
-					  m_le_qwVendorSpecificExt1,
-					  EplDllkInstance_g.m_DllIdentParam.
-					  m_qwVendorSpecificExt1);
-			// VerifyConfigurationDate
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.
-					m_le_dwVerifyConfigurationDate,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwVerifyConfigurationDate);
-			// VerifyConfigurationTime
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.
-					m_le_dwVerifyConfigurationTime,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwVerifyConfigurationTime);
-			// ApplicationSwDate
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.
-					m_le_dwApplicationSwDate,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwApplicationSwDate);
-			// ApplicationSwTime
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.
-					m_le_dwApplicationSwTime,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwApplicationSwTime);
-			// IPAddress
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwIpAddress,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwIpAddress);
-			// SubnetMask
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwSubnetMask,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwSubnetMask);
-			// DefaultGateway
-			AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
-					m_IdentResponse.m_le_dwDefaultGateway,
-					EplDllkInstance_g.m_DllIdentParam.
-					m_dwDefaultGateway);
-			// HostName
-			EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload.
-				   m_IdentResponse.m_le_sHostname[0],
-				   &EplDllkInstance_g.m_DllIdentParam.
-				   m_sHostname[0],
-				   sizeof(EplDllkInstance_g.m_DllIdentParam.
-					  m_sHostname));
-			// VendorSpecificExt2
-			EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload.
-				   m_IdentResponse.m_le_abVendorSpecificExt2[0],
-				   &EplDllkInstance_g.m_DllIdentParam.
-				   m_abVendorSpecificExt2[0],
-				   sizeof(EplDllkInstance_g.m_DllIdentParam.
-					  m_abVendorSpecificExt2));
-
-			// StatusResponse
-			uiFrameSize = EPL_C_DLL_MINSIZE_STATUSRES;
-			Ret =
-			    EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
-						 &uiFrameSize, kEplMsgTypeAsnd,
-						 kEplDllAsndStatusResponse);
-			if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-				goto Exit;
-			}
-			// PRes $$$ maybe move this to PDO module
-			if ((EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly ==
-			     FALSE)
-			    && (EplDllkInstance_g.m_DllConfigParam.m_uiPresActPayloadLimit >= 36)) {	// it is not configured as async-only CN,
-				// so take part in isochronous phase and register PRes frame
-				uiFrameSize =
-				    EplDllkInstance_g.m_DllConfigParam.
-				    m_uiPresActPayloadLimit + 24;
-				Ret =
-				    EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
-							 &uiFrameSize,
-							 kEplMsgTypePres,
-							 kEplDllAsndNotDefined);
-				if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-					goto Exit;
-				}
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-				// initially encode TPDO -> inform PDO module
-				FrameInfo.m_pFrame = pTxFrame;
-				FrameInfo.m_uiFrameSize = uiFrameSize;
-				Ret = EplPdokCbPdoTransmitted(&FrameInfo);
-#endif
-				// reset cycle counter
-				EplDllkInstance_g.m_uiCycleCount = 0;
-			} else {	// it is an async-only CN
-				// fool EplDllkChangeState() to think that PRes was not expected
-				EplDllkInstance_g.m_uiCycleCount = 1;
-			}
-
-			// NMT request
-			uiFrameSize = EPL_C_IP_MAX_MTU;
-			Ret =
-			    EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
-						 &uiFrameSize, kEplMsgTypeAsnd,
-						 kEplDllAsndNmtRequest);
-			if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-				goto Exit;
-			}
-			// mark Tx buffer as empty
-			EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen =
-			    EPL_DLLK_BUFLEN_EMPTY;
-
-			// non-EPL frame
-			uiFrameSize = EPL_C_IP_MAX_MTU;
-			Ret =
-			    EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
-						 &uiFrameSize,
-						 kEplMsgTypeNonEpl,
-						 kEplDllAsndNotDefined);
-			if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-				goto Exit;
-			}
-			// mark Tx buffer as empty
-			EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen =
-			    EPL_DLLK_BUFLEN_EMPTY;
-
-			// register multicast MACs in ethernet driver
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_SOC);
-			Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_SOA);
-			Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_PRES);
-			Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_ASND);
-			Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			if (NmtState >= kEplNmtMsNotActive) {	// local node is MN
-				unsigned int uiIndex;
-
-				// SoC
-				uiFrameSize = EPL_C_DLL_MINSIZE_SOC;
-				Ret =
-				    EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
-							 &uiFrameSize,
-							 kEplMsgTypeSoc,
-							 kEplDllAsndNotDefined);
-				if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-					goto Exit;
-				}
-				// SoA
-				uiFrameSize = EPL_C_DLL_MINSIZE_SOA;
-				Ret =
-				    EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
-							 &uiFrameSize,
-							 kEplMsgTypeSoa,
-							 kEplDllAsndNotDefined);
-				if (Ret != kEplSuccessful) {	// error occured while registering Tx frame
-					goto Exit;
-				}
-
-				for (uiIndex = 0;
-				     uiIndex <
-				     tabentries(EplDllkInstance_g.m_aNodeInfo);
-				     uiIndex++) {
-//                    EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
-					EplDllkInstance_g.m_aNodeInfo[uiIndex].
-					    m_wPresPayloadLimit =
-					    (u16) EplDllkInstance_g.
-					    m_DllConfigParam.
-					    m_uiIsochrRxMaxPayload;
-				}
-
-				// calculate cycle length
-				EplDllkInstance_g.m_ullFrameTimeout = 1000LL
-				    *
-				    ((unsigned long long)EplDllkInstance_g.
-				     m_DllConfigParam.m_dwCycleLen);
-			}
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-			Ret = EplDllkCalAsyncClearBuffer();
-
-			break;
-		}
-
-	case kEplEventTypeDllkDestroy:
-		{
-			// destroy all data structures
-
-			NmtState = *((tEplNmtState *) pEvent_p->m_pArg);
-
-			// delete Tx frames
-			Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_IDENTRES);
-			if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-				goto Exit;
-			}
-
-			Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_STATUSRES);
-			if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-				goto Exit;
-			}
-
-			Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_PRES);
-			if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-				goto Exit;
-			}
-
-			Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NMTREQ);
-			if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-				goto Exit;
-			}
-
-			Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NONEPL);
-			if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-				goto Exit;
-			}
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			if (NmtState >= kEplNmtMsNotActive) {	// local node was MN
-				unsigned int uiIndex;
-
-				Ret =
-				    EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOC);
-				if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-					goto Exit;
-				}
-
-				Ret =
-				    EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOA);
-				if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-					goto Exit;
-				}
-
-				for (uiIndex = 0;
-				     uiIndex <
-				     tabentries(EplDllkInstance_g.m_aNodeInfo);
-				     uiIndex++) {
-					if (EplDllkInstance_g.
-					    m_aNodeInfo[uiIndex].
-					    m_pPreqTxBuffer != NULL) {
-						uiHandle =
-						    EplDllkInstance_g.
-						    m_aNodeInfo[uiIndex].
-						    m_pPreqTxBuffer -
-						    EplDllkInstance_g.
-						    m_pTxBuffer;
-						EplDllkInstance_g.
-						    m_aNodeInfo[uiIndex].
-						    m_pPreqTxBuffer = NULL;
-						Ret =
-						    EplDllkDeleteTxFrame
-						    (uiHandle);
-						if (Ret != kEplSuccessful) {	// error occured while deregistering Tx frame
-							goto Exit;
-						}
-
-					}
-					EplDllkInstance_g.m_aNodeInfo[uiIndex].
-					    m_wPresPayloadLimit = 0xFFFF;
-				}
-			}
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-			// deregister multicast MACs in ethernet driver
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_SOC);
-			Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_SOA);
-			Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_PRES);
-			Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
-			AmiSetQword48ToBe(&abMulticastMac[0],
-					  EPL_C_DLL_MULTICAST_ASND);
-			Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
-
-			// delete timer
-#if EPL_TIMER_USE_HIGHRES != FALSE
-			Ret =
-			    EplTimerHighReskDeleteTimer(&EplDllkInstance_g.
-							m_TimerHdlCycle);
-#endif
-
-			break;
-		}
-
-	case kEplEventTypeDllkFillTx:
-		{
-			// fill TxBuffer of specified priority with new frame if empty
-
-			pTxFrame = NULL;
-			AsyncReqPriority =
-			    *((tEplDllAsyncReqPriority *) pEvent_p->m_pArg);
-			switch (AsyncReqPriority) {
-			case kEplDllAsyncReqPrioNmt:	// NMT request priority
-				{
-					pTxBuffer =
-					    &EplDllkInstance_g.
-					    m_pTxBuffer
-					    [EPL_DLLK_TXFRAME_NMTREQ];
-					if (pTxBuffer->m_pbBuffer != NULL) {	// NmtRequest does exist
-						// check if frame is empty and not being filled
-						if (pTxBuffer->m_uiTxMsgLen ==
-						    EPL_DLLK_BUFLEN_EMPTY) {
-							// mark Tx buffer as filling is in process
-							pTxBuffer->
-							    m_uiTxMsgLen =
-							    EPL_DLLK_BUFLEN_FILLING;
-							// set max buffer size as input parameter
-							uiFrameSize =
-							    pTxBuffer->
-							    m_uiMaxBufferLen;
-							// copy frame from shared loop buffer to Tx buffer
-							Ret =
-							    EplDllkCalAsyncGetTxFrame
-							    (pTxBuffer->
-							     m_pbBuffer,
-							     &uiFrameSize,
-							     AsyncReqPriority);
-							if (Ret ==
-							    kEplSuccessful) {
-								pTxFrame =
-								    (tEplFrame
-								     *)
-								    pTxBuffer->
-								    m_pbBuffer;
-								Ret =
-								    EplDllkCheckFrame
-								    (pTxFrame,
-								     uiFrameSize);
-
-								// set buffer valid
-								pTxBuffer->
-								    m_uiTxMsgLen
-								    =
-								    uiFrameSize;
-							} else if (Ret == kEplDllAsyncTxBufferEmpty) {	// empty Tx buffer is not a real problem
-								// so just ignore it
-								Ret =
-								    kEplSuccessful;
-								// mark Tx buffer as empty
-								pTxBuffer->
-								    m_uiTxMsgLen
-								    =
-								    EPL_DLLK_BUFLEN_EMPTY;
-							}
-						}
-					}
-					break;
-				}
-
-			default:	// generic priority
-				{
-					pTxBuffer =
-					    &EplDllkInstance_g.
-					    m_pTxBuffer
-					    [EPL_DLLK_TXFRAME_NONEPL];
-					if (pTxBuffer->m_pbBuffer != NULL) {	// non-EPL frame does exist
-						// check if frame is empty and not being filled
-						if (pTxBuffer->m_uiTxMsgLen ==
-						    EPL_DLLK_BUFLEN_EMPTY) {
-							// mark Tx buffer as filling is in process
-							pTxBuffer->
-							    m_uiTxMsgLen =
-							    EPL_DLLK_BUFLEN_FILLING;
-							// set max buffer size as input parameter
-							uiFrameSize =
-							    pTxBuffer->
-							    m_uiMaxBufferLen;
-							// copy frame from shared loop buffer to Tx buffer
-							Ret =
-							    EplDllkCalAsyncGetTxFrame
-							    (pTxBuffer->
-							     m_pbBuffer,
-							     &uiFrameSize,
-							     AsyncReqPriority);
-							if (Ret ==
-							    kEplSuccessful) {
-								pTxFrame =
-								    (tEplFrame
-								     *)
-								    pTxBuffer->
-								    m_pbBuffer;
-								Ret =
-								    EplDllkCheckFrame
-								    (pTxFrame,
-								     uiFrameSize);
-
-								// set buffer valid
-								pTxBuffer->
-								    m_uiTxMsgLen
-								    =
-								    uiFrameSize;
-							} else if (Ret == kEplDllAsyncTxBufferEmpty) {	// empty Tx buffer is not a real problem
-								// so just ignore it
-								Ret =
-								    kEplSuccessful;
-								// mark Tx buffer as empty
-								pTxBuffer->
-								    m_uiTxMsgLen
-								    =
-								    EPL_DLLK_BUFLEN_EMPTY;
-							}
-						}
-					}
-					break;
-				}
-			}
-
-			NmtState = EplNmtkGetNmtState();
-
-			if ((NmtState == kEplNmtCsBasicEthernet) || (NmtState == kEplNmtMsBasicEthernet)) {	// send frame immediately
-				if (pTxFrame != NULL) {	// frame is present
-					// padding is done by Edrv or ethernet controller
-					Ret = EdrvSendTxMsg(pTxBuffer);
-				} else {	// no frame moved to TxBuffer
-					// check if TxBuffers contain unsent frames
-					if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) {	// NMT request Tx buffer contains a frame
-						Ret =
-						    EdrvSendTxMsg
-						    (&EplDllkInstance_g.
-						     m_pTxBuffer
-						     [EPL_DLLK_TXFRAME_NMTREQ]);
-					} else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) {	// non-EPL Tx buffer contains a frame
-						Ret =
-						    EdrvSendTxMsg
-						    (&EplDllkInstance_g.
-						     m_pTxBuffer
-						     [EPL_DLLK_TXFRAME_NONEPL]);
-					}
-					if (Ret == kEplInvalidOperation) {	// ignore error if caused by already active transmission
-						Ret = kEplSuccessful;
-					}
-				}
-				// reset PRes flag 2
-				EplDllkInstance_g.m_bFlag2 = 0;
-			} else {
-				// update Flag 2 (PR, RS)
-				Ret =
-				    EplDllkCalAsyncGetTxCount(&AsyncReqPriority,
-							      &uiFrameCount);
-				if (AsyncReqPriority == kEplDllAsyncReqPrioNmt) {	// non-empty FIFO with hightest priority is for NMT requests
-					if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) {	// NMT request Tx buffer contains a frame
-						// add one more frame
-						uiFrameCount++;
-					}
-				} else {	// non-empty FIFO with highest priority is for generic frames
-					if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) {	// NMT request Tx buffer contains a frame
-						// use NMT request FIFO, because of higher priority
-						uiFrameCount = 1;
-						AsyncReqPriority =
-						    kEplDllAsyncReqPrioNmt;
-					} else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) {	// non-EPL Tx buffer contains a frame
-						// use NMT request FIFO, because of higher priority
-						// add one more frame
-						uiFrameCount++;
-					}
-				}
-
-				if (uiFrameCount > 7) {	// limit frame request to send counter to 7
-					uiFrameCount = 7;
-				}
-				if (uiFrameCount > 0) {
-					EplDllkInstance_g.m_bFlag2 =
-					    (u8) (((AsyncReqPriority <<
-						      EPL_FRAME_FLAG2_PR_SHIFT)
-						     & EPL_FRAME_FLAG2_PR)
-						    | (uiFrameCount &
-						       EPL_FRAME_FLAG2_RS));
-				} else {
-					EplDllkInstance_g.m_bFlag2 = 0;
-				}
-			}
-
-			break;
-		}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	case kEplEventTypeDllkStartReducedCycle:
-		{
-			// start the reduced cycle by programming the cycle timer
-			// it is issued by NMT MN module, when PreOp1 is entered
-
-			// clear the asynchronous queues
-			Ret = EplDllkCalAsyncClearQueues();
-
-			// reset cycle counter (everytime a SoA is triggerd in PreOp1 the counter is incremented
-			// and when it reaches EPL_C_DLL_PREOP1_START_CYCLES the SoA may contain invitations)
-			EplDllkInstance_g.m_uiCycleCount = 0;
-
-			// remove any CN from isochronous phase
-			while (EplDllkInstance_g.m_pFirstNodeInfo != NULL) {
-				EplDllkDeleteNode(EplDllkInstance_g.
-						  m_pFirstNodeInfo->m_uiNodeId);
-			}
-
-			// change state to NonCyclic,
-			// hence EplDllkChangeState() will not ignore the next call
-			EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic;
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-			if (EplDllkInstance_g.m_DllConfigParam.
-			    m_dwAsyncSlotTimeout != 0) {
-				Ret =
-				    EplTimerHighReskModifyTimerNs
-				    (&EplDllkInstance_g.m_TimerHdlCycle,
-				     EplDllkInstance_g.m_DllConfigParam.
-				     m_dwAsyncSlotTimeout,
-				     EplDllkCbMnTimerCycle, 0L, FALSE);
-			}
-#endif
-
-			break;
-		}
-#endif
-
-#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
-	case kEplEventTypeDllkPresReady:
-		{
-			// post PRes to transmit FIFO
-
-			NmtState = EplNmtkGetNmtState();
-
-			if (NmtState != kEplNmtCsBasicEthernet) {
-				// Does PRes exist?
-				if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].m_pbBuffer != NULL) {	// PRes does exist
-					pTxFrame =
-					    (tEplFrame *) EplDllkInstance_g.
-					    m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].
-					    m_pbBuffer;
-					// update frame (NMT state, RD, RS, PR, MS, EN flags)
-					if (NmtState < kEplNmtCsPreOperational2) {	// NMT state is not PreOp2, ReadyToOp or Op
-						// fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater
-						NmtState =
-						    kEplNmtCsPreOperational2;
-					}
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-						       m_le_bNmtStatus,
-						       (u8) NmtState);
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-						       m_le_bFlag2,
-						       EplDllkInstance_g.
-						       m_bFlag2);
-					if (NmtState != kEplNmtCsOperational) {	// mark PDO as invalid in NMT state Op
-						// $$$ reset only RD flag; set other flags appropriately
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Pres.
-							       m_le_bFlag1, 0);
-					}
-					// $$$ make function that updates Pres, StatusRes
-					// mark PRes frame as ready for transmission
-					Ret =
-					    EdrvTxMsgReady(&EplDllkInstance_g.
-							   m_pTxBuffer
-							   [EPL_DLLK_TXFRAME_PRES]);
-				}
-			}
-
-			break;
-		}
-#endif
-	default:
-		{
-			ASSERTMSG(FALSE,
-				  "EplDllkProcess(): unhandled event type!\n");
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkConfig
-//
-// Description: configure parameters of DLL
-//
-// Parameters:  pDllConfigParam_p       = configuration parameters
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-// d.k. check of NMT state disabled, because CycleLen is programmed at run time by MN without reset of CN
-/*tEplNmtState    NmtState;
-
-    NmtState = EplNmtkGetNmtState();
-
-    if (NmtState > kEplNmtGsResetConfiguration)
-    {   // only allowed in state DLL_GS_INIT
-        Ret = kEplInvalidOperation;
-        goto Exit;
-    }
-*/
-	EPL_MEMCPY(&EplDllkInstance_g.m_DllConfigParam, pDllConfigParam_p,
-		   (pDllConfigParam_p->m_uiSizeOfStruct <
-		    sizeof(tEplDllConfigParam) ? pDllConfigParam_p->
-		    m_uiSizeOfStruct : sizeof(tEplDllConfigParam)));
-
-	if ((EplDllkInstance_g.m_DllConfigParam.m_dwCycleLen != 0)
-	    && (EplDllkInstance_g.m_DllConfigParam.m_dwLossOfFrameTolerance != 0)) {	// monitor EPL cycle, calculate frame timeout
-		EplDllkInstance_g.m_ullFrameTimeout = (1000LL
-						       *
-						       ((unsigned long long)
-							EplDllkInstance_g.
-							m_DllConfigParam.
-							m_dwCycleLen))
-		    +
-		    ((unsigned long long)EplDllkInstance_g.m_DllConfigParam.
-		     m_dwLossOfFrameTolerance);
-	} else {
-		EplDllkInstance_g.m_ullFrameTimeout = 0LL;
-	}
-
-	if (EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly != FALSE) {	// it is configured as async-only CN
-		// disable multiplexed cycle, that m_uiCycleCount will not be incremented spuriously on SoC
-		EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt = 0;
-	}
-//Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkSetIdentity
-//
-// Description: configure identity of local node for IdentResponse
-//
-// Parameters:  pDllIdentParam_p        = identity
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	EPL_MEMCPY(&EplDllkInstance_g.m_DllIdentParam, pDllIdentParam_p,
-		   (pDllIdentParam_p->m_uiSizeOfStruct <
-		    sizeof(tEplDllIdentParam) ? pDllIdentParam_p->
-		    m_uiSizeOfStruct : sizeof(tEplDllIdentParam)));
-
-	// $$$ if IdentResponse frame exists update it
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkRegAsyncHandler
-//
-// Description: registers handler for non-EPL frames
-//
-// Parameters:  pfnDllkCbAsync_p        = pointer to callback function
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (EplDllkInstance_g.m_pfnCbAsync == NULL) {	// no handler registered yet
-		EplDllkInstance_g.m_pfnCbAsync = pfnDllkCbAsync_p;
-	} else {		// handler already registered
-		Ret = kEplDllCbAsyncRegistered;
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkDeregAsyncHandler
-//
-// Description: deregisters handler for non-EPL frames
-//
-// Parameters:  pfnDllkCbAsync_p        = pointer to callback function
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (EplDllkInstance_g.m_pfnCbAsync == pfnDllkCbAsync_p) {	// same handler is registered
-		// deregister it
-		EplDllkInstance_g.m_pfnCbAsync = NULL;
-	} else {		// wrong handler or no handler registered
-		Ret = kEplDllCbAsyncRegistered;
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkSetAsndServiceIdFilter()
-//
-// Description: sets the specified node ID filter for the specified
-//              AsndServiceId. It registers C_DLL_MULTICAST_ASND in ethernet
-//              driver if any AsndServiceId is open.
-//
-// Parameters:  ServiceId_p             = ASnd Service ID
-//              Filter_p                = node ID filter
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p,
-					 tEplDllAsndFilter Filter_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (ServiceId_p < tabentries(EplDllkInstance_g.m_aAsndFilter)) {
-		EplDllkInstance_g.m_aAsndFilter[ServiceId_p] = Filter_p;
-	}
-
-	return Ret;
-}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkSetFlag1OfNode()
-//
-// Description: sets Flag1 (for PReq and SoA) of the specified node ID.
-//
-// Parameters:  uiNodeId_p              = node ID
-//              bSoaFlag1_p             = flag1
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplDllkNodeInfo *pNodeInfo;
-
-	pNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
-	if (pNodeInfo == NULL) {	// no node info structure available
-		Ret = kEplDllNoNodeInfo;
-		goto Exit;
-	}
-	// store flag1 in internal node info structure
-	pNodeInfo->m_bSoaFlag1 = bSoaFlag1_p;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkGetFirstNodeInfo()
-//
-// Description: returns first info structure of first node in isochronous phase.
-//              It is only useful for ErrorHandlerk module.
-//
-// Parameters:  ppNodeInfo_p            = pointer to pointer of internal node info structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	*ppNodeInfo_p = EplDllkInstance_g.m_pFirstNodeInfo;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkAddNode()
-//
-// Description: adds the specified node to the isochronous phase.
-//
-// Parameters:  pNodeInfo_p             = pointer of node info structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplDllkNodeInfo *pIntNodeInfo;
-	tEplDllkNodeInfo **ppIntNodeInfo;
-	unsigned int uiHandle;
-	tEplFrame *pFrame;
-	unsigned int uiFrameSize;
-
-	pIntNodeInfo = EplDllkGetNodeInfo(pNodeInfo_p->m_uiNodeId);
-	if (pIntNodeInfo == NULL) {	// no node info structure available
-		Ret = kEplDllNoNodeInfo;
-		goto Exit;
-	}
-
-	EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkAddNode,
-				      pNodeInfo_p->m_uiNodeId, 0);
-
-	// copy node configuration
-	pIntNodeInfo->m_dwPresTimeout = pNodeInfo_p->m_dwPresTimeout;
-	pIntNodeInfo->m_wPresPayloadLimit = pNodeInfo_p->m_wPresPayloadLimit;
-
-	// $$$ d.k.: actually add node only if MN. On CN it is sufficient to update the node configuration
-	if (pNodeInfo_p->m_uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) {	// we shall send PRes ourself
-		// insert our node at the end of the list
-		ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
-		while ((*ppIntNodeInfo != NULL)
-		       && ((*ppIntNodeInfo)->m_pNextNodeInfo != NULL)) {
-			ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
-		}
-		if (*ppIntNodeInfo != NULL) {
-			if ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId) {	// node was already added to list
-				// $$$ d.k. maybe this should be an error
-				goto Exit;
-			} else {	// add our node at the end of the list
-				ppIntNodeInfo =
-				    &(*ppIntNodeInfo)->m_pNextNodeInfo;
-			}
-		}
-		// set "PReq"-TxBuffer to PRes-TxBuffer
-		pIntNodeInfo->m_pPreqTxBuffer =
-		    &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
-	} else {		// normal CN shall be added to isochronous phase
-		// insert node into list in ascending order
-		ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
-		while ((*ppIntNodeInfo != NULL)
-		       && ((*ppIntNodeInfo)->m_uiNodeId <
-			   pNodeInfo_p->m_uiNodeId)
-		       && ((*ppIntNodeInfo)->m_uiNodeId !=
-			   EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)) {
-			ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
-		}
-		if ((*ppIntNodeInfo != NULL) && ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId)) {	// node was already added to list
-			// $$$ d.k. maybe this should be an error
-			goto Exit;
-		}
-	}
-
-	// initialize elements of internal node info structure
-	pIntNodeInfo->m_bSoaFlag1 = 0;
-	pIntNodeInfo->m_fSoftDelete = FALSE;
-	pIntNodeInfo->m_NmtState = kEplNmtCsNotActive;
-	if (pIntNodeInfo->m_pPreqTxBuffer == NULL) {	// create TxBuffer entry
-		uiFrameSize = pNodeInfo_p->m_wPreqPayloadLimit + 24;
-		Ret =
-		    EplDllkCreateTxFrame(&uiHandle, &pFrame, &uiFrameSize,
-					 kEplMsgTypePreq,
-					 kEplDllAsndNotDefined);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		pIntNodeInfo->m_pPreqTxBuffer =
-		    &EplDllkInstance_g.m_pTxBuffer[uiHandle];
-		AmiSetByteToLe(&pFrame->m_le_bDstNodeId,
-			       (u8) pNodeInfo_p->m_uiNodeId);
-
-		// set up destination MAC address
-		EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr,
-			   6);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-		{
-			tEplFrameInfo FrameInfo;
-
-			// initially encode TPDO -> inform PDO module
-			FrameInfo.m_pFrame = pFrame;
-			FrameInfo.m_uiFrameSize = uiFrameSize;
-			Ret = EplPdokCbPdoTransmitted(&FrameInfo);
-		}
-#endif
-	}
-	pIntNodeInfo->m_ulDllErrorEvents = 0L;
-	// add node to list
-	pIntNodeInfo->m_pNextNodeInfo = *ppIntNodeInfo;
-	*ppIntNodeInfo = pIntNodeInfo;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkDeleteNode()
-//
-// Description: removes the specified node from the isochronous phase.
-//
-// Parameters:  uiNodeId_p              = node ID
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplDllkNodeInfo *pIntNodeInfo;
-	tEplDllkNodeInfo **ppIntNodeInfo;
-	unsigned int uiHandle;
-
-	pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
-	if (pIntNodeInfo == NULL) {	// no node info structure available
-		Ret = kEplDllNoNodeInfo;
-		goto Exit;
-	}
-
-	EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkDelNode, uiNodeId_p, 0);
-
-	// search node in whole list
-	ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
-	while ((*ppIntNodeInfo != NULL)
-	       && ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) {
-		ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
-	}
-	if ((*ppIntNodeInfo == NULL) || ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) {	// node was not found in list
-		// $$$ d.k. maybe this should be an error
-		goto Exit;
-	}
-	// remove node from list
-	*ppIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo;
-
-	if ((pIntNodeInfo->m_pPreqTxBuffer != NULL)
-	    && (pIntNodeInfo->m_pPreqTxBuffer != &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) {	// delete TxBuffer entry
-		uiHandle =
-		    pIntNodeInfo->m_pPreqTxBuffer -
-		    EplDllkInstance_g.m_pTxBuffer;
-		pIntNodeInfo->m_pPreqTxBuffer = NULL;
-		Ret = EplDllkDeleteTxFrame(uiHandle);
-/*        if (Ret != kEplSuccessful)
-        {
-            goto Exit;
-        }*/
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkSoftDeleteNode()
-//
-// Description: removes the specified node not immediately from the isochronous phase.
-//              Instead the will be removed after error (late/loss PRes) without
-//              charging the error.
-//
-// Parameters:  uiNodeId_p              = node ID
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplDllkNodeInfo *pIntNodeInfo;
-
-	pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
-	if (pIntNodeInfo == NULL) {	// no node info structure available
-		Ret = kEplDllNoNodeInfo;
-		goto Exit;
-	}
-
-	EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkSoftDelNode,
-				      uiNodeId_p, 0);
-
-	pIntNodeInfo->m_fSoftDelete = TRUE;
-
-      Exit:
-	return Ret;
-}
-
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkChangeState
-//
-// Description: change DLL state on event and diagnose some communication errors
-//
-// Parameters:  NmtEvent_p              = DLL event (wrapped in NMT event)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p,
-				     tEplNmtState NmtState_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-	tEplErrorHandlerkEvent DllEvent;
-
-	DllEvent.m_ulDllErrorEvents = 0;
-	DllEvent.m_uiNodeId = 0;
-	DllEvent.m_NmtState = NmtState_p;
-
-	switch (NmtState_p) {
-	case kEplNmtGsOff:
-	case kEplNmtGsInitialising:
-	case kEplNmtGsResetApplication:
-	case kEplNmtGsResetCommunication:
-	case kEplNmtGsResetConfiguration:
-	case kEplNmtCsBasicEthernet:
-		// enter DLL_GS_INIT
-		EplDllkInstance_g.m_DllState = kEplDllGsInit;
-		break;
-
-	case kEplNmtCsNotActive:
-	case kEplNmtCsPreOperational1:
-		// reduced EPL cycle is active
-		if (NmtEvent_p == kEplNmtEventDllCeSoc) {	// SoC received
-			// enter DLL_CS_WAIT_PREQ
-			EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
-		} else {
-			// enter DLL_GS_INIT
-			EplDllkInstance_g.m_DllState = kEplDllGsInit;
-		}
-		break;
-
-	case kEplNmtCsPreOperational2:
-	case kEplNmtCsReadyToOperate:
-	case kEplNmtCsOperational:
-		// full EPL cycle is active
-
-		switch (EplDllkInstance_g.m_DllState) {
-		case kEplDllCsWaitPreq:
-			switch (NmtEvent_p) {
-				// DLL_CT2
-			case kEplNmtEventDllCePreq:
-				// enter DLL_CS_WAIT_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_RECVD_PREQ;
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
-				break;
-
-				// DLL_CT8
-			case kEplNmtEventDllCeFrameTimeout:
-				if (NmtState_p == kEplNmtCsPreOperational2) {	// ignore frame timeout in PreOp2,
-					// because the previously configured cycle len
-					// may be wrong.
-					// 2008/10/15 d.k. If it would not be ignored,
-					// we would go cyclically to PreOp1 and on next
-					// SoC back to PreOp2.
-					break;
-				}
-				// report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA |
-				    EPL_DLL_ERR_CN_LOSS_SOC;
-
-				// enter DLL_CS_WAIT_SOC
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
-				break;
-
-			case kEplNmtEventDllCeSoa:
-				// check if multiplexed and PReq should have been received in this cycle
-				// and if >= NMT_CS_READY_TO_OPERATE
-				if ((EplDllkInstance_g.m_uiCycleCount == 0)
-				    && (NmtState_p >= kEplNmtCsReadyToOperate)) {	// report DLL_CEV_LOSS_OF_PREQ
-					DllEvent.m_ulDllErrorEvents |=
-					    EPL_DLL_ERR_CN_LOSS_PREQ;
-				}
-				// enter DLL_CS_WAIT_SOC
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
-				break;
-
-				// DLL_CT7
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeAsnd:
-				// report DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA;
-
-			case kEplNmtEventDllCePres:
-			default:
-				// remain in this state
-				break;
-			}
-			break;
-
-		case kEplDllCsWaitSoc:
-			switch (NmtEvent_p) {
-				// DLL_CT1
-			case kEplNmtEventDllCeSoc:
-				// start of cycle and isochronous phase
-				// enter DLL_CS_WAIT_PREQ
-				EplDllkInstance_g.m_DllState =
-				    kEplDllCsWaitPreq;
-				break;
-
-				// DLL_CT4
-//                        case kEplNmtEventDllCePres:
-			case kEplNmtEventDllCeFrameTimeout:
-				if (NmtState_p == kEplNmtCsPreOperational2) {	// ignore frame timeout in PreOp2,
-					// because the previously configured cycle len
-					// may be wrong.
-					// 2008/10/15 d.k. If it would not be ignored,
-					// we would go cyclically to PreOp1 and on next
-					// SoC back to PreOp2.
-					break;
-				}
-				// fall through
-
-			case kEplNmtEventDllCePreq:
-			case kEplNmtEventDllCeSoa:
-				// report DLL_CEV_LOSS_SOC
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOC;
-
-			case kEplNmtEventDllCeAsnd:
-			default:
-				// remain in this state
-				break;
-			}
-			break;
-
-		case kEplDllCsWaitSoa:
-			switch (NmtEvent_p) {
-			case kEplNmtEventDllCeFrameTimeout:
-				// DLL_CT3
-				if (NmtState_p == kEplNmtCsPreOperational2) {	// ignore frame timeout in PreOp2,
-					// because the previously configured cycle len
-					// may be wrong.
-					// 2008/10/15 d.k. If it would not be ignored,
-					// we would go cyclically to PreOp1 and on next
-					// SoC back to PreOp2.
-					break;
-				}
-				// fall through
-
-			case kEplNmtEventDllCePreq:
-				// report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA |
-				    EPL_DLL_ERR_CN_LOSS_SOC;
-
-			case kEplNmtEventDllCeSoa:
-				// enter DLL_CS_WAIT_SOC
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
-				break;
-
-				// DLL_CT9
-			case kEplNmtEventDllCeSoc:
-				// report DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA;
-
-				// enter DLL_CS_WAIT_PREQ
-				EplDllkInstance_g.m_DllState =
-				    kEplDllCsWaitPreq;
-				break;
-
-				// DLL_CT10
-			case kEplNmtEventDllCeAsnd:
-				// report DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA;
-
-			case kEplNmtEventDllCePres:
-			default:
-				// remain in this state
-				break;
-			}
-			break;
-
-		case kEplDllGsInit:
-			// enter DLL_CS_WAIT_PREQ
-			EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
-			break;
-
-		default:
-			break;
-		}
-		break;
-
-	case kEplNmtCsStopped:
-		// full EPL cycle is active, but without PReq/PRes
-
-		switch (EplDllkInstance_g.m_DllState) {
-		case kEplDllCsWaitPreq:
-			switch (NmtEvent_p) {
-				// DLL_CT2
-			case kEplNmtEventDllCePreq:
-				// enter DLL_CS_WAIT_SOA
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
-				break;
-
-				// DLL_CT8
-			case kEplNmtEventDllCeFrameTimeout:
-				// report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA |
-				    EPL_DLL_ERR_CN_LOSS_SOC;
-
-			case kEplNmtEventDllCeSoa:
-				// NMT_CS_STOPPED active
-				// it is Ok if no PReq was received
-
-				// enter DLL_CS_WAIT_SOC
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
-				break;
-
-				// DLL_CT7
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeAsnd:
-				// report DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA;
-
-			case kEplNmtEventDllCePres:
-			default:
-				// remain in this state
-				break;
-			}
-			break;
-
-		case kEplDllCsWaitSoc:
-			switch (NmtEvent_p) {
-				// DLL_CT1
-			case kEplNmtEventDllCeSoc:
-				// start of cycle and isochronous phase
-				// enter DLL_CS_WAIT_SOA
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
-				break;
-
-				// DLL_CT4
-//                        case kEplNmtEventDllCePres:
-			case kEplNmtEventDllCePreq:
-			case kEplNmtEventDllCeSoa:
-			case kEplNmtEventDllCeFrameTimeout:
-				// report DLL_CEV_LOSS_SOC
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOC;
-
-			case kEplNmtEventDllCeAsnd:
-			default:
-				// remain in this state
-				break;
-			}
-			break;
-
-		case kEplDllCsWaitSoa:
-			switch (NmtEvent_p) {
-				// DLL_CT3
-			case kEplNmtEventDllCeFrameTimeout:
-				// report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA |
-				    EPL_DLL_ERR_CN_LOSS_SOC;
-
-			case kEplNmtEventDllCeSoa:
-				// enter DLL_CS_WAIT_SOC
-				EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
-				break;
-
-				// DLL_CT9
-			case kEplNmtEventDllCeSoc:
-				// report DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA;
-				// remain in DLL_CS_WAIT_SOA
-				break;
-
-				// DLL_CT10
-			case kEplNmtEventDllCeAsnd:
-				// report DLL_CEV_LOSS_SOA
-				DllEvent.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOA;
-
-			case kEplNmtEventDllCePreq:
-				// NMT_CS_STOPPED active and we do not expect any PReq
-				// so just ignore it
-			case kEplNmtEventDllCePres:
-			default:
-				// remain in this state
-				break;
-			}
-			break;
-
-		case kEplDllGsInit:
-		default:
-			// enter DLL_CS_WAIT_PREQ
-			EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
-			break;
-		}
-		break;
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	case kEplNmtMsNotActive:
-	case kEplNmtMsBasicEthernet:
-		break;
-
-	case kEplNmtMsPreOperational1:
-		// reduced EPL cycle is active
-		if (EplDllkInstance_g.m_DllState != kEplDllMsNonCyclic) {	// stop cycle timer
-#if EPL_TIMER_USE_HIGHRES != FALSE
-			Ret =
-			    EplTimerHighReskDeleteTimer(&EplDllkInstance_g.
-							m_TimerHdlCycle);
-#endif
-			EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic;
-
-			// stop further processing,
-			// because it will be restarted by NMT MN module
-			break;
-		}
-
-		switch (NmtEvent_p) {
-		case kEplNmtEventDllMeSocTrig:
-		case kEplNmtEventDllCeAsnd:
-			{	// because of reduced EPL cycle SoA shall be triggered, not SoC
-				tEplDllState DummyDllState;
-
-				Ret =
-				    EplDllkAsyncFrameNotReceived
-				    (EplDllkInstance_g.m_LastReqServiceId,
-				     EplDllkInstance_g.m_uiLastTargetNodeId);
-
-				// go ahead and send SoA
-				Ret = EplDllkMnSendSoa(NmtState_p,
-						       &DummyDllState,
-						       (EplDllkInstance_g.
-							m_uiCycleCount >=
-							EPL_C_DLL_PREOP1_START_CYCLES));
-				// increment cycle counter to detect if EPL_C_DLL_PREOP1_START_CYCLES empty cycles are elapsed
-				EplDllkInstance_g.m_uiCycleCount++;
-
-				// reprogram timer
-#if EPL_TIMER_USE_HIGHRES != FALSE
-				if (EplDllkInstance_g.m_DllConfigParam.
-				    m_dwAsyncSlotTimeout != 0) {
-					Ret =
-					    EplTimerHighReskModifyTimerNs
-					    (&EplDllkInstance_g.m_TimerHdlCycle,
-					     EplDllkInstance_g.m_DllConfigParam.
-					     m_dwAsyncSlotTimeout,
-					     EplDllkCbMnTimerCycle, 0L, FALSE);
-				}
-#endif
-				break;
-			}
-
-		default:
-			break;
-		}
-		break;
-
-	case kEplNmtMsPreOperational2:
-	case kEplNmtMsReadyToOperate:
-	case kEplNmtMsOperational:
-		// full EPL cycle is active
-		switch (NmtEvent_p) {
-		case kEplNmtEventDllMeSocTrig:
-			{
-				// update cycle counter
-				if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) {	// multiplexed cycle active
-					EplDllkInstance_g.m_uiCycleCount =
-					    (EplDllkInstance_g.m_uiCycleCount +
-					     1) %
-					    EplDllkInstance_g.m_DllConfigParam.
-					    m_uiMultiplCycleCnt;
-					// $$$ check multiplexed cycle restart
-					//     -> toggle MC flag
-					//     -> change node linked list
-				} else {	// non-multiplexed cycle active
-					// start with first node in isochronous phase
-					EplDllkInstance_g.m_pCurNodeInfo = NULL;
-				}
-
-				switch (EplDllkInstance_g.m_DllState) {
-				case kEplDllMsNonCyclic:
-					{	// start continuous cycle timer
-#if EPL_TIMER_USE_HIGHRES != FALSE
-						Ret =
-						    EplTimerHighReskModifyTimerNs
-						    (&EplDllkInstance_g.
-						     m_TimerHdlCycle,
-						     EplDllkInstance_g.
-						     m_ullFrameTimeout,
-						     EplDllkCbMnTimerCycle, 0L,
-						     TRUE);
-#endif
-						// continue with sending SoC
-					}
-
-				case kEplDllMsWaitAsnd:
-				case kEplDllMsWaitSocTrig:
-					{	// if m_LastReqServiceId is still valid,
-						// SoA was not correctly answered
-						// and user part has to be informed
-						Ret =
-						    EplDllkAsyncFrameNotReceived
-						    (EplDllkInstance_g.
-						     m_LastReqServiceId,
-						     EplDllkInstance_g.
-						     m_uiLastTargetNodeId);
-
-						// send SoC
-						Ret = EplDllkMnSendSoc();
-
-						// new DLL state
-						EplDllkInstance_g.m_DllState =
-						    kEplDllMsWaitPreqTrig;
-
-						// start WaitSoCPReq Timer
-#if EPL_TIMER_USE_HIGHRES != FALSE
-						Ret =
-						    EplTimerHighReskModifyTimerNs
-						    (&EplDllkInstance_g.
-						     m_TimerHdlResponse,
-						     EplDllkInstance_g.
-						     m_DllConfigParam.
-						     m_dwWaitSocPreq,
-						     EplDllkCbMnTimerResponse,
-						     0L, FALSE);
-#endif
-						break;
-					}
-
-				default:
-					{	// wrong DLL state / cycle time exceeded
-						DllEvent.m_ulDllErrorEvents |=
-						    EPL_DLL_ERR_MN_CYCTIMEEXCEED;
-						EplDllkInstance_g.m_DllState =
-						    kEplDllMsWaitSocTrig;
-						break;
-					}
-				}
-
-				break;
-			}
-
-		case kEplNmtEventDllMePresTimeout:
-			{
-
-				switch (EplDllkInstance_g.m_DllState) {
-				case kEplDllMsWaitPres:
-					{	// PRes not received
-
-						if (EplDllkInstance_g.m_pCurNodeInfo->m_fSoftDelete == FALSE) {	// normal isochronous CN
-							DllEvent.
-							    m_ulDllErrorEvents
-							    |=
-							    EPL_DLL_ERR_MN_CN_LOSS_PRES;
-							DllEvent.m_uiNodeId =
-							    EplDllkInstance_g.
-							    m_pCurNodeInfo->
-							    m_uiNodeId;
-						} else {	// CN shall be deleted softly
-							Event.m_EventSink =
-							    kEplEventSinkDllkCal;
-							Event.m_EventType =
-							    kEplEventTypeDllkSoftDelNode;
-							// $$$ d.k. set Event.m_NetTime to current time
-							Event.m_uiSize =
-							    sizeof(unsigned
-								   int);
-							Event.m_pArg =
-							    &EplDllkInstance_g.
-							    m_pCurNodeInfo->
-							    m_uiNodeId;
-							Ret =
-							    EplEventkPost
-							    (&Event);
-						}
-
-						// continue with sending next PReq
-					}
-
-				case kEplDllMsWaitPreqTrig:
-					{
-						// send next PReq
-						Ret =
-						    EplDllkMnSendPreq
-						    (NmtState_p,
-						     &EplDllkInstance_g.
-						     m_DllState);
-
-						break;
-					}
-
-				default:
-					{	// wrong DLL state
-						break;
-					}
-				}
-
-				break;
-			}
-
-		case kEplNmtEventDllCePres:
-			{
-
-				switch (EplDllkInstance_g.m_DllState) {
-				case kEplDllMsWaitPres:
-					{	// PRes received
-						// send next PReq
-						Ret =
-						    EplDllkMnSendPreq
-						    (NmtState_p,
-						     &EplDllkInstance_g.
-						     m_DllState);
-
-						break;
-					}
-
-				default:
-					{	// wrong DLL state
-						break;
-					}
-				}
-
-				break;
-			}
-
-		case kEplNmtEventDllMeSoaTrig:
-			{
-
-				switch (EplDllkInstance_g.m_DllState) {
-				case kEplDllMsWaitSoaTrig:
-					{	// MN PRes sent
-						// send SoA
-						Ret =
-						    EplDllkMnSendSoa(NmtState_p,
-								     &EplDllkInstance_g.
-								     m_DllState,
-								     TRUE);
-
-						break;
-					}
-
-				default:
-					{	// wrong DLL state
-						break;
-					}
-				}
-
-				break;
-			}
-
-		case kEplNmtEventDllCeAsnd:
-			{	// ASnd has been received, but it may be not the requested one
-/*
-                    // report if SoA was correctly answered
-                    Ret = EplDllkAsyncFrameNotReceived(EplDllkInstance_g.m_LastReqServiceId,
-                                                       EplDllkInstance_g.m_uiLastTargetNodeId);
-*/
-				if (EplDllkInstance_g.m_DllState ==
-				    kEplDllMsWaitAsnd) {
-					EplDllkInstance_g.m_DllState =
-					    kEplDllMsWaitSocTrig;
-				}
-				break;
-			}
-
-		default:
-			break;
-		}
-		break;
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-	default:
-		break;
-	}
-
-	if (DllEvent.m_ulDllErrorEvents != 0) {	// error event set -> post it to error handler
-		Event.m_EventSink = kEplEventSinkErrk;
-		Event.m_EventType = kEplEventTypeDllError;
-		// $$$ d.k. set Event.m_NetTime to current time
-		Event.m_uiSize = sizeof(DllEvent);
-		Event.m_pArg = &DllEvent;
-		Ret = EplEventkPost(&Event);
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCbFrameReceived()
-//
-// Description: called from EdrvInterruptHandler()
-//
-// Parameters:  pRxBuffer_p             = receive buffer structure
-//
-// Returns:     (none)
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplNmtState NmtState;
-	tEplNmtEvent NmtEvent = kEplNmtEventNoEvent;
-	tEplEvent Event;
-	tEplFrame *pFrame;
-	tEplFrame *pTxFrame;
-	tEdrvTxBuffer *pTxBuffer = NULL;
-	tEplFrameInfo FrameInfo;
-	tEplMsgType MsgType;
-	tEplDllReqServiceId ReqServiceId;
-	unsigned int uiAsndServiceId;
-	unsigned int uiNodeId;
-	u8 bFlag1;
-
-	BENCHMARK_MOD_02_SET(3);
-	NmtState = EplNmtkGetNmtState();
-
-	if (NmtState <= kEplNmtGsResetConfiguration) {
-		goto Exit;
-	}
-
-	pFrame = (tEplFrame *) pRxBuffer_p->m_pbBuffer;
-
-#if EDRV_EARLY_RX_INT != FALSE
-	switch (pRxBuffer_p->m_BufferInFrame) {
-	case kEdrvBufferFirstInFrame:
-		{
-			MsgType =
-			    (tEplMsgType) AmiGetByteFromLe(&pFrame->
-							   m_le_bMessageType);
-			if (MsgType == kEplMsgTypePreq) {
-				if (EplDllkInstance_g.m_DllState == kEplDllCsWaitPreq) {	// PReq expected and actually received
-					// d.k.: The condition above is sufficent, because EPL cycle is active
-					//       and no non-EPL frame shall be received in isochronous phase.
-					// start transmission PRes
-					// $$$ What if Tx buffer is invalid?
-					pTxBuffer =
-					    &EplDllkInstance_g.
-					    m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
-#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
-					Ret = EdrvTxMsgStart(pTxBuffer);
-#else
-					pTxFrame =
-					    (tEplFrame *) pTxBuffer->m_pbBuffer;
-					// update frame (NMT state, RD, RS, PR, MS, EN flags)
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-						       m_le_bNmtStatus,
-						       (u8) NmtState);
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-						       m_le_bFlag2,
-						       EplDllkInstance_g.
-						       m_bFlag2);
-					if (NmtState != kEplNmtCsOperational) {	// mark PDO as invalid in NMT state Op
-						// $$$ reset only RD flag; set other flags appropriately
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Pres.
-							       m_le_bFlag1, 0);
-					}
-					// $$$ make function that updates Pres, StatusRes
-					// send PRes frame
-					Ret = EdrvSendTxMsg(pTxBuffer);
-#endif
-				}
-			}
-			goto Exit;
-		}
-
-	case kEdrvBufferMiddleInFrame:
-		{
-			goto Exit;
-		}
-
-	case kEdrvBufferLastInFrame:
-		{
-			break;
-		}
-	}
-#endif
-
-	FrameInfo.m_pFrame = pFrame;
-	FrameInfo.m_uiFrameSize = pRxBuffer_p->m_uiRxMsgLen;
-	FrameInfo.m_NetTime.m_dwNanoSec = pRxBuffer_p->m_NetTime.m_dwNanoSec;
-	FrameInfo.m_NetTime.m_dwSec = pRxBuffer_p->m_NetTime.m_dwSec;
-
-	if (AmiGetWordFromBe(&pFrame->m_be_wEtherType) != EPL_C_DLL_ETHERTYPE_EPL) {	// non-EPL frame
-		//TRACE2("EplDllkCbFrameReceived: pfnCbAsync=0x%p SrcMAC=0x%llx\n", EplDllkInstance_g.m_pfnCbAsync, AmiGetQword48FromBe(pFrame->m_be_abSrcMac));
-		if (EplDllkInstance_g.m_pfnCbAsync != NULL) {	// handler for async frames is registered
-			EplDllkInstance_g.m_pfnCbAsync(&FrameInfo);
-		}
-
-		goto Exit;
-	}
-
-	MsgType = (tEplMsgType) AmiGetByteFromLe(&pFrame->m_le_bMessageType);
-	switch (MsgType) {
-	case kEplMsgTypePreq:
-		{
-			// PReq frame
-			// d.k.: (we assume that this PReq frame is intended for us and don't check DstNodeId)
-			if (AmiGetByteFromLe(&pFrame->m_le_bDstNodeId) != EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) {	// this PReq is not intended for us
-				goto Exit;
-			}
-			NmtEvent = kEplNmtEventDllCePreq;
-
-			if (NmtState >= kEplNmtMsNotActive) {	// MN is active -> wrong msg type
-				break;
-			}
-#if EDRV_EARLY_RX_INT == FALSE
-			if (NmtState >= kEplNmtCsPreOperational2) {	// respond to and process PReq frames only in PreOp2, ReadyToOp and Op
-				// Does PRes exist?
-				pTxBuffer =
-				    &EplDllkInstance_g.
-				    m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
-				if (pTxBuffer->m_pbBuffer != NULL) {	// PRes does exist
-#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
-					EdrvTxMsgStart(pTxBuffer);
-#else
-					pTxFrame =
-					    (tEplFrame *) pTxBuffer->m_pbBuffer;
-					// update frame (NMT state, RD, RS, PR, MS, EN flags)
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-						       m_le_bNmtStatus,
-						       (u8) NmtState);
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-						       m_le_bFlag2,
-						       EplDllkInstance_g.
-						       m_bFlag2);
-					bFlag1 =
-					    AmiGetByteFromLe(&pFrame->m_Data.
-							     m_Preq.
-							     m_le_bFlag1);
-					// save EA flag
-					EplDllkInstance_g.m_bMnFlag1 =
-					    (EplDllkInstance_g.
-					     m_bMnFlag1 & ~EPL_FRAME_FLAG1_EA)
-					    | (bFlag1 & EPL_FRAME_FLAG1_EA);
-					// preserve MS flag
-					bFlag1 &= EPL_FRAME_FLAG1_MS;
-					// add EN flag from Error signaling module
-					bFlag1 |=
-					    EplDllkInstance_g.
-					    m_bFlag1 & EPL_FRAME_FLAG1_EN;
-					if (NmtState != kEplNmtCsOperational) {	// mark PDO as invalid in NMT state Op
-						// reset only RD flag
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Pres.
-							       m_le_bFlag1,
-							       bFlag1);
-					} else {	// leave RD flag untouched
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Pres.
-							       m_le_bFlag1,
-							       (AmiGetByteFromLe
-								(&pTxFrame->
-								 m_Data.m_Pres.
-								 m_le_bFlag1) &
-								EPL_FRAME_FLAG1_RD)
-							       | bFlag1);
-					}
-					// $$$ update EPL_DLL_PRES_READY_AFTER_* code
-					// send PRes frame
-					Ret = EdrvSendTxMsg(pTxBuffer);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-#endif
-				}
-#endif
-				// inform PDO module
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-				if (NmtState >= kEplNmtCsReadyToOperate) {	// inform PDO module only in ReadyToOp and Op
-					if (NmtState != kEplNmtCsOperational) {
-						// reset RD flag and all other flags, but that does not matter, because they were processed above
-						AmiSetByteToLe(&pFrame->m_Data.
-							       m_Preq.
-							       m_le_bFlag1, 0);
-					}
-					// compares real frame size and PDO size
-					if ((unsigned
-					     int)(AmiGetWordFromLe(&pFrame->
-								   m_Data.
-								   m_Preq.
-								   m_le_wSize) +
-						  24)
-					    > FrameInfo.m_uiFrameSize) {	// format error
-						tEplErrorHandlerkEvent DllEvent;
-
-						DllEvent.m_ulDllErrorEvents =
-						    EPL_DLL_ERR_INVALID_FORMAT;
-						DllEvent.m_uiNodeId =
-						    AmiGetByteFromLe(&pFrame->
-								     m_le_bSrcNodeId);
-						DllEvent.m_NmtState = NmtState;
-						Event.m_EventSink =
-						    kEplEventSinkErrk;
-						Event.m_EventType =
-						    kEplEventTypeDllError;
-						Event.m_NetTime =
-						    FrameInfo.m_NetTime;
-						Event.m_uiSize =
-						    sizeof(DllEvent);
-						Event.m_pArg = &DllEvent;
-						Ret = EplEventkPost(&Event);
-						break;
-					}
-					// forward PReq frame as RPDO to PDO module
-					Ret = EplPdokCbPdoReceived(&FrameInfo);
-
-				}
-#if (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
-				if (pTxBuffer->m_pbBuffer != NULL) {	// PRes does exist
-					// inform PDO module about PRes after PReq
-					FrameInfo.m_pFrame =
-					    (tEplFrame *) pTxBuffer->m_pbBuffer;
-					FrameInfo.m_uiFrameSize =
-					    pTxBuffer->m_uiMaxBufferLen;
-					Ret =
-					    EplPdokCbPdoTransmitted(&FrameInfo);
-				}
-#endif
-#endif
-
-#if EDRV_EARLY_RX_INT == FALSE
-				// $$$ inform emergency protocol handling (error signaling module) about flags
-			}
-#endif
-
-			// reset cycle counter
-			EplDllkInstance_g.m_uiCycleCount = 0;
-
-			break;
-		}
-
-	case kEplMsgTypePres:
-		{
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			tEplDllkNodeInfo *pIntNodeInfo;
-			tEplHeartbeatEvent HeartbeatEvent;
-#endif
-
-			// PRes frame
-			NmtEvent = kEplNmtEventDllCePres;
-
-			uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
-
-			if ((NmtState >= kEplNmtCsPreOperational2)
-			    && (NmtState <= kEplNmtCsOperational)) {	// process PRes frames only in PreOp2, ReadyToOp and Op of CN
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-				pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId);
-				if (pIntNodeInfo == NULL) {	// no node info structure available
-					Ret = kEplDllNoNodeInfo;
-					goto Exit;
-				}
-			} else if (EplDllkInstance_g.m_DllState == kEplDllMsWaitPres) {	// or process PRes frames in MsWaitPres
-
-				pIntNodeInfo = EplDllkInstance_g.m_pCurNodeInfo;
-				if ((pIntNodeInfo == NULL) || (pIntNodeInfo->m_uiNodeId != uiNodeId)) {	// ignore PRes, because it is from wrong CN
-					// $$$ maybe post event to NmtMn module
-					goto Exit;
-				}
-				// forward Flag2 to asynchronous scheduler
-				bFlag1 =
-				    AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.
-						     m_Payload.m_StatusResponse.
-						     m_le_bFlag2);
-				Ret =
-				    EplDllkCalAsyncSetPendingRequests(uiNodeId,
-								      ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS));
-
-#endif
-			} else {	// ignore PRes, because it was received in wrong NMT state
-				// but execute EplDllkChangeState() and post event to NMT module
-				break;
-			}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			{	// check NMT state of CN
-				HeartbeatEvent.m_wErrorCode = EPL_E_NO_ERROR;
-				HeartbeatEvent.m_NmtState =
-				    (tEplNmtState) (AmiGetByteFromLe
-						    (&pFrame->m_Data.m_Pres.
-						     m_le_bNmtStatus) |
-						    EPL_NMT_TYPE_CS);
-				if (pIntNodeInfo->m_NmtState != HeartbeatEvent.m_NmtState) {	// NMT state of CN has changed -> post event to NmtMnu module
-					if (pIntNodeInfo->m_fSoftDelete == FALSE) {	// normal isochronous CN
-						HeartbeatEvent.m_uiNodeId =
-						    uiNodeId;
-						Event.m_EventSink =
-						    kEplEventSinkNmtMnu;
-						Event.m_EventType =
-						    kEplEventTypeHeartbeat;
-						Event.m_uiSize =
-						    sizeof(HeartbeatEvent);
-						Event.m_pArg = &HeartbeatEvent;
-					} else {	// CN shall be deleted softly
-						Event.m_EventSink =
-						    kEplEventSinkDllkCal;
-						Event.m_EventType =
-						    kEplEventTypeDllkSoftDelNode;
-						Event.m_uiSize =
-						    sizeof(unsigned int);
-						Event.m_pArg =
-						    &pIntNodeInfo->m_uiNodeId;
-					}
-					Event.m_NetTime = FrameInfo.m_NetTime;
-					Ret = EplEventkPost(&Event);
-
-					// save current NMT state of CN in internal node structure
-					pIntNodeInfo->m_NmtState =
-					    HeartbeatEvent.m_NmtState;
-				}
-			}
-#endif
-
-			// inform PDO module
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-			if ((NmtState != kEplNmtCsPreOperational2)
-			    && (NmtState != kEplNmtMsPreOperational2)) {	// inform PDO module only in ReadyToOp and Op
-				// compare real frame size and PDO size?
-				if (((unsigned
-				      int)(AmiGetWordFromLe(&pFrame->m_Data.
-							    m_Pres.m_le_wSize) +
-					   24)
-				     > FrameInfo.m_uiFrameSize)
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-				    ||
-				    (AmiGetWordFromLe
-				     (&pFrame->m_Data.m_Pres.m_le_wSize) >
-				     pIntNodeInfo->m_wPresPayloadLimit)
-#endif
-				    ) {	// format error
-					tEplErrorHandlerkEvent DllEvent;
-
-					DllEvent.m_ulDllErrorEvents =
-					    EPL_DLL_ERR_INVALID_FORMAT;
-					DllEvent.m_uiNodeId = uiNodeId;
-					DllEvent.m_NmtState = NmtState;
-					Event.m_EventSink = kEplEventSinkErrk;
-					Event.m_EventType =
-					    kEplEventTypeDllError;
-					Event.m_NetTime = FrameInfo.m_NetTime;
-					Event.m_uiSize = sizeof(DllEvent);
-					Event.m_pArg = &DllEvent;
-					Ret = EplEventkPost(&Event);
-					break;
-				}
-				if ((NmtState != kEplNmtCsOperational)
-				    && (NmtState != kEplNmtMsOperational)) {
-					// reset RD flag and all other flags, but that does not matter, because they were processed above
-					AmiSetByteToLe(&pFrame->m_Data.m_Pres.
-						       m_le_bFlag1, 0);
-				}
-				Ret = EplPdokCbPdoReceived(&FrameInfo);
-			}
-#endif
-
-			break;
-		}
-
-	case kEplMsgTypeSoc:
-		{
-			// SoC frame
-			NmtEvent = kEplNmtEventDllCeSoc;
-
-			if (NmtState >= kEplNmtMsNotActive) {	// MN is active -> wrong msg type
-				break;
-			}
-#if EPL_DLL_PRES_READY_AFTER_SOC != FALSE
-			// post PRes to transmit FIFO of the ethernet controller, but don't start
-			// transmission over bus
-			pTxBuffer =
-			    &EplDllkInstance_g.
-			    m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
-			// Does PRes exist?
-			if (pTxBuffer->m_pbBuffer != NULL) {	// PRes does exist
-				pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
-				// update frame (NMT state, RD, RS, PR, MS, EN flags)
-				if (NmtState < kEplNmtCsPreOperational2) {	// NMT state is not PreOp2, ReadyToOp or Op
-					// fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater
-					NmtState = kEplNmtCsPreOperational2;
-				}
-				AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-					       m_le_bNmtStatus,
-					       (u8) NmtState);
-				AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-					       m_le_bFlag2,
-					       EplDllkInstance_g.m_bFlag2);
-				if (NmtState != kEplNmtCsOperational) {	// mark PDO as invalid in NMT state Op
-					// $$$ reset only RD flag; set other flags appropriately
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
-						       m_le_bFlag1, 0);
-				}
-				// $$$ make function that updates Pres, StatusRes
-				// mark PRes frame as ready for transmission
-				Ret = EdrvTxMsgReady(pTxBuffer);
-			}
-#endif
-
-			if (NmtState >= kEplNmtCsPreOperational2) {	// SoC frames only in PreOp2, ReadyToOp and Op
-				// trigger synchronous task
-				Event.m_EventSink = kEplEventSinkSync;
-				Event.m_EventType = kEplEventTypeSync;
-				Event.m_uiSize = 0;
-				Ret = EplEventkPost(&Event);
-
-				// update cycle counter
-				if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) {	// multiplexed cycle active
-					EplDllkInstance_g.m_uiCycleCount =
-					    (EplDllkInstance_g.m_uiCycleCount +
-					     1) %
-					    EplDllkInstance_g.m_DllConfigParam.
-					    m_uiMultiplCycleCnt;
-				}
-			}
-			// reprogram timer
-#if EPL_TIMER_USE_HIGHRES != FALSE
-			if (EplDllkInstance_g.m_ullFrameTimeout != 0) {
-				Ret =
-				    EplTimerHighReskModifyTimerNs
-				    (&EplDllkInstance_g.m_TimerHdlCycle,
-				     EplDllkInstance_g.m_ullFrameTimeout,
-				     EplDllkCbCnTimer, 0L, FALSE);
-			}
-#endif
-
-			break;
-		}
-
-	case kEplMsgTypeSoa:
-		{
-			// SoA frame
-			NmtEvent = kEplNmtEventDllCeSoa;
-
-			if (NmtState >= kEplNmtMsNotActive) {	// MN is active -> wrong msg type
-				break;
-			}
-
-			pTxFrame = NULL;
-
-			if ((NmtState & EPL_NMT_SUPERSTATE_MASK) != EPL_NMT_CS_EPLMODE) {	// do not respond, if NMT state is < PreOp1 (i.e. not EPL_MODE)
-				break;
-			}
-			// check TargetNodeId
-			uiNodeId =
-			    AmiGetByteFromLe(&pFrame->m_Data.m_Soa.
-					     m_le_bReqServiceTarget);
-			if (uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) {	// local node is the target of the current request
-
-				// check ServiceId
-				ReqServiceId =
-				    (tEplDllReqServiceId)
-				    AmiGetByteFromLe(&pFrame->m_Data.m_Soa.
-						     m_le_bReqServiceId);
-				if (ReqServiceId == kEplDllReqServiceStatus) {	// StatusRequest
-					if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) {	// StatusRes does exist
-
-						pTxFrame =
-						    (tEplFrame *)
-						    EplDllkInstance_g.
-						    m_pTxBuffer
-						    [EPL_DLLK_TXFRAME_STATUSRES].
-						    m_pbBuffer;
-						// update StatusRes frame (NMT state, EN, EC, RS, PR flags)
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Asnd.
-							       m_Payload.
-							       m_StatusResponse.
-							       m_le_bNmtStatus,
-							       (u8) NmtState);
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Asnd.
-							       m_Payload.
-							       m_StatusResponse.
-							       m_le_bFlag1,
-							       EplDllkInstance_g.
-							       m_bFlag1);
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Asnd.
-							       m_Payload.
-							       m_StatusResponse.
-							       m_le_bFlag2,
-							       EplDllkInstance_g.
-							       m_bFlag2);
-						// send StatusRes
-						Ret =
-						    EdrvSendTxMsg
-						    (&EplDllkInstance_g.
-						     m_pTxBuffer
-						     [EPL_DLLK_TXFRAME_STATUSRES]);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						TGT_DBG_SIGNAL_TRACE_POINT(8);
-
-						// update error signaling
-						bFlag1 =
-						    AmiGetByteFromLe(&pFrame->
-								     m_Data.
-								     m_Soa.
-								     m_le_bFlag1);
-						if (((bFlag1 ^ EplDllkInstance_g.m_bMnFlag1) & EPL_FRAME_FLAG1_ER) != 0) {	// exception reset flag was changed by MN
-							// assume same state for EC in next cycle (clear all other bits)
-							if ((bFlag1 &
-							     EPL_FRAME_FLAG1_ER)
-							    != 0) {
-								// set EC and reset rest
-								EplDllkInstance_g.
-								    m_bFlag1 =
-								    EPL_FRAME_FLAG1_EC;
-							} else {
-								// reset complete flag 1 (including EC and EN)
-								EplDllkInstance_g.
-								    m_bFlag1 =
-								    0;
-							}
-						}
-						// save flag 1 from MN for Status request response cycle
-						EplDllkInstance_g.m_bMnFlag1 =
-						    bFlag1;
-					}
-				} else if (ReqServiceId == kEplDllReqServiceIdent) {	// IdentRequest
-					if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) {	// IdentRes does exist
-						pTxFrame =
-						    (tEplFrame *)
-						    EplDllkInstance_g.
-						    m_pTxBuffer
-						    [EPL_DLLK_TXFRAME_IDENTRES].
-						    m_pbBuffer;
-						// update IdentRes frame (NMT state, RS, PR flags)
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Asnd.
-							       m_Payload.
-							       m_IdentResponse.
-							       m_le_bNmtStatus,
-							       (u8) NmtState);
-						AmiSetByteToLe(&pTxFrame->
-							       m_Data.m_Asnd.
-							       m_Payload.
-							       m_IdentResponse.
-							       m_le_bFlag2,
-							       EplDllkInstance_g.
-							       m_bFlag2);
-						// send IdentRes
-						Ret =
-						    EdrvSendTxMsg
-						    (&EplDllkInstance_g.
-						     m_pTxBuffer
-						     [EPL_DLLK_TXFRAME_IDENTRES]);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						TGT_DBG_SIGNAL_TRACE_POINT(7);
-					}
-				} else if (ReqServiceId == kEplDllReqServiceNmtRequest) {	// NmtRequest
-					if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) {	// NmtRequest does exist
-						// check if frame is not empty and not being filled
-						if (EplDllkInstance_g.
-						    m_pTxBuffer
-						    [EPL_DLLK_TXFRAME_NMTREQ].
-						    m_uiTxMsgLen >
-						    EPL_DLLK_BUFLEN_FILLING) {
-							/*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN)
-							   {   // pad frame
-							   EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN;
-							   } */
-							// memorize transmission
-							pTxFrame =
-							    (tEplFrame *) 1;
-							// send NmtRequest
-							Ret =
-							    EdrvSendTxMsg
-							    (&EplDllkInstance_g.
-							     m_pTxBuffer
-							     [EPL_DLLK_TXFRAME_NMTREQ]);
-							if (Ret !=
-							    kEplSuccessful) {
-								goto Exit;
-							}
-
-						}
-					}
-
-				} else if (ReqServiceId == kEplDllReqServiceUnspecified) {	// unspecified invite
-					if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) {	// non-EPL frame does exist
-						// check if frame is not empty and not being filled
-						if (EplDllkInstance_g.
-						    m_pTxBuffer
-						    [EPL_DLLK_TXFRAME_NONEPL].
-						    m_uiTxMsgLen >
-						    EPL_DLLK_BUFLEN_FILLING) {
-							/*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN)
-							   {   // pad frame
-							   EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN;
-							   } */
-							// memorize transmission
-							pTxFrame =
-							    (tEplFrame *) 1;
-							// send non-EPL frame
-							Ret =
-							    EdrvSendTxMsg
-							    (&EplDllkInstance_g.
-							     m_pTxBuffer
-							     [EPL_DLLK_TXFRAME_NONEPL]);
-							if (Ret !=
-							    kEplSuccessful) {
-								goto Exit;
-							}
-
-						}
-					}
-
-				} else if (ReqServiceId == kEplDllReqServiceNo) {	// no async service requested -> do nothing
-				}
-			}
-#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
-			if (pTxFrame == NULL) {	// signal process function readiness of PRes frame
-				Event.m_EventSink = kEplEventSinkDllk;
-				Event.m_EventType = kEplEventTypeDllkPresReady;
-				Event.m_uiSize = 0;
-				Event.m_pArg = NULL;
-				Ret = EplEventkPost(&Event);
-			}
-#endif
-
-			// inform PDO module
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-//            Ret = EplPdokCbSoa(&FrameInfo);
-#endif
-
-			// $$$ put SrcNodeId, NMT state and NetTime as HeartbeatEvent into eventqueue
-
-			// $$$ inform emergency protocol handling about flags
-			break;
-		}
-
-	case kEplMsgTypeAsnd:
-		{
-			// ASnd frame
-			NmtEvent = kEplNmtEventDllCeAsnd;
-
-			// ASnd service registered?
-			uiAsndServiceId =
-			    (unsigned int)AmiGetByteFromLe(&pFrame->m_Data.
-							   m_Asnd.
-							   m_le_bServiceId);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			if ((EplDllkInstance_g.m_DllState >= kEplDllMsNonCyclic)
-			    &&
-			    ((((tEplDllAsndServiceId) uiAsndServiceId) ==
-			      kEplDllAsndStatusResponse)
-			     || (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse))) {	// StatusRes or IdentRes received
-				uiNodeId =
-				    AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
-				if ((EplDllkInstance_g.m_LastReqServiceId ==
-				     ((tEplDllReqServiceId) uiAsndServiceId))
-				    && (uiNodeId == EplDllkInstance_g.m_uiLastTargetNodeId)) {	// mark request as responded
-					EplDllkInstance_g.m_LastReqServiceId =
-					    kEplDllReqServiceNo;
-				}
-				if (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse) {	// memorize MAC address of CN for PReq
-					tEplDllkNodeInfo *pIntNodeInfo;
-
-					pIntNodeInfo =
-					    EplDllkGetNodeInfo(uiNodeId);
-					if (pIntNodeInfo == NULL) {	// no node info structure available
-						Ret = kEplDllNoNodeInfo;
-					} else {
-						EPL_MEMCPY(pIntNodeInfo->
-							   m_be_abMacAddr,
-							   pFrame->
-							   m_be_abSrcMac, 6);
-					}
-				}
-				// forward Flag2 to asynchronous scheduler
-				bFlag1 =
-				    AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.
-						     m_Payload.m_StatusResponse.
-						     m_le_bFlag2);
-				Ret =
-				    EplDllkCalAsyncSetPendingRequests(uiNodeId,
-								      ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS));
-			}
-#endif
-
-			if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID) {	// ASnd service ID is valid
-				if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterAny) {	// ASnd service ID is registered
-					// forward frame via async receive FIFO to userspace
-					Ret =
-					    EplDllkCalAsyncFrameReceived
-					    (&FrameInfo);
-				} else if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterLocal) {	// ASnd service ID is registered, but only local node ID or broadcasts
-					// shall be forwarded
-					uiNodeId =
-					    AmiGetByteFromLe(&pFrame->
-							     m_le_bDstNodeId);
-					if ((uiNodeId ==
-					     EplDllkInstance_g.m_DllConfigParam.
-					     m_uiNodeId)
-					    || (uiNodeId == EPL_C_ADR_BROADCAST)) {	// ASnd frame is intended for us
-						// forward frame via async receive FIFO to userspace
-						Ret =
-						    EplDllkCalAsyncFrameReceived
-						    (&FrameInfo);
-					}
-				}
-			}
-			break;
-		}
-
-	default:
-		{
-			break;
-		}
-	}
-
-	if (NmtEvent != kEplNmtEventNoEvent) {	// event for DLL and NMT state machine generated
-		Ret = EplDllkChangeState(NmtEvent, NmtState);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		if ((NmtEvent != kEplNmtEventDllCeAsnd)
-		    && ((NmtState <= kEplNmtCsPreOperational1) || (NmtEvent != kEplNmtEventDllCePres))) {	// NMT state machine is not interested in ASnd frames and PRes frames when not CsNotActive or CsPreOp1
-			// inform NMT module
-			Event.m_EventSink = kEplEventSinkNmtk;
-			Event.m_EventType = kEplEventTypeNmtEvent;
-			Event.m_uiSize = sizeof(NmtEvent);
-			Event.m_pArg = &NmtEvent;
-			Ret = EplEventkPost(&Event);
-		}
-	}
-
-      Exit:
-	if (Ret != kEplSuccessful) {
-		u32 dwArg;
-
-		BENCHMARK_MOD_02_TOGGLE(9);
-
-		dwArg = EplDllkInstance_g.m_DllState | (NmtEvent << 8);
-
-		// Error event for API layer
-		Ret = EplEventkPostError(kEplEventSourceDllk,
-					 Ret, sizeof(dwArg), &dwArg);
-	}
-	BENCHMARK_MOD_02_RESET(3);
-	return;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCbFrameTransmitted()
-//
-// Description: called from EdrvInterruptHandler().
-//              It signals
-//
-// Parameters:  pRxBuffer_p             = receive buffer structure
-//
-// Returns:     (none)
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-	tEplDllAsyncReqPriority Priority;
-	tEplNmtState NmtState;
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
-    && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)
-	tEplFrameInfo FrameInfo;
-#endif
-
-	NmtState = EplNmtkGetNmtState();
-
-	if (NmtState <= kEplNmtGsResetConfiguration) {
-		goto Exit;
-	}
-
-	if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NMTREQ) {	// frame from NMT request FIFO sent
-		// mark Tx-buffer as empty
-		pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
-
-		// post event to DLL
-		Priority = kEplDllAsyncReqPrioNmt;
-		Event.m_EventSink = kEplEventSinkDllk;
-		Event.m_EventType = kEplEventTypeDllkFillTx;
-		EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
-		Event.m_pArg = &Priority;
-		Event.m_uiSize = sizeof(Priority);
-		Ret = EplEventkPost(&Event);
-	} else if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NONEPL) {	// frame from generic priority FIFO sent
-		// mark Tx-buffer as empty
-		pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
-
-		// post event to DLL
-		Priority = kEplDllAsyncReqPrioGeneric;
-		Event.m_EventSink = kEplEventSinkDllk;
-		Event.m_EventType = kEplEventTypeDllkFillTx;
-		EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
-		Event.m_pArg = &Priority;
-		Event.m_uiSize = sizeof(Priority);
-		Ret = EplEventkPost(&Event);
-	}
-#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
-    && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)) \
-    || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	else if ((pTxBuffer_p->m_EplMsgType == kEplMsgTypePreq)
-		 || (pTxBuffer_p->m_EplMsgType == kEplMsgTypePres)) {	// PRes resp. PReq frame sent
-
-#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
-            && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE))
-		{
-			// inform PDO module
-			FrameInfo.m_pFrame =
-			    (tEplFrame *) pTxBuffer_p->m_pbBuffer;
-			FrameInfo.m_uiFrameSize = pTxBuffer_p->m_uiMaxBufferLen;
-			Ret = EplPdokCbPdoTransmitted(&FrameInfo);
-		}
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-		{
-			// if own Pres on MN, trigger SoA
-			if ((NmtState >= kEplNmtMsPreOperational2)
-			    && (pTxBuffer_p ==
-				&EplDllkInstance_g.
-				m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) {
-				Ret =
-				    EplDllkChangeState(kEplNmtEventDllMeSoaTrig,
-						       NmtState);
-			}
-		}
-#endif
-
-#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
-		goto Exit;
-#endif
-	}
-#endif
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	else if (pTxBuffer_p->m_EplMsgType == kEplMsgTypeSoa) {	// SoA frame sent
-		tEplNmtEvent NmtEvent = kEplNmtEventDllMeSoaSent;
-
-		// check if we are invited
-		if (EplDllkInstance_g.m_uiLastTargetNodeId ==
-		    EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) {
-			tEplFrame *pTxFrame;
-
-			if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceStatus) {	// StatusRequest
-				if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) {	// StatusRes does exist
-
-					pTxFrame =
-					    (tEplFrame *) EplDllkInstance_g.
-					    m_pTxBuffer
-					    [EPL_DLLK_TXFRAME_STATUSRES].
-					    m_pbBuffer;
-					// update StatusRes frame (NMT state, EN, EC, RS, PR flags)
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
-						       m_Payload.
-						       m_StatusResponse.
-						       m_le_bNmtStatus,
-						       (u8) NmtState);
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
-						       m_Payload.
-						       m_StatusResponse.
-						       m_le_bFlag1,
-						       EplDllkInstance_g.
-						       m_bFlag1);
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
-						       m_Payload.
-						       m_StatusResponse.
-						       m_le_bFlag2,
-						       EplDllkInstance_g.
-						       m_bFlag2);
-					// send StatusRes
-					Ret =
-					    EdrvSendTxMsg(&EplDllkInstance_g.
-							  m_pTxBuffer
-							  [EPL_DLLK_TXFRAME_STATUSRES]);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-					TGT_DBG_SIGNAL_TRACE_POINT(8);
-
-				}
-			} else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceIdent) {	// IdentRequest
-				if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) {	// IdentRes does exist
-					pTxFrame =
-					    (tEplFrame *) EplDllkInstance_g.
-					    m_pTxBuffer
-					    [EPL_DLLK_TXFRAME_IDENTRES].
-					    m_pbBuffer;
-					// update IdentRes frame (NMT state, RS, PR flags)
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
-						       m_Payload.
-						       m_IdentResponse.
-						       m_le_bNmtStatus,
-						       (u8) NmtState);
-					AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
-						       m_Payload.
-						       m_IdentResponse.
-						       m_le_bFlag2,
-						       EplDllkInstance_g.
-						       m_bFlag2);
-					// send IdentRes
-					Ret =
-					    EdrvSendTxMsg(&EplDllkInstance_g.
-							  m_pTxBuffer
-							  [EPL_DLLK_TXFRAME_IDENTRES]);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-					TGT_DBG_SIGNAL_TRACE_POINT(7);
-				}
-			} else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceNmtRequest) {	// NmtRequest
-				if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) {	// NmtRequest does exist
-					// check if frame is not empty and not being filled
-					if (EplDllkInstance_g.
-					    m_pTxBuffer
-					    [EPL_DLLK_TXFRAME_NMTREQ].
-					    m_uiTxMsgLen >
-					    EPL_DLLK_BUFLEN_FILLING) {
-						// check if this frame is a NMT command,
-						// then forward this frame back to NmtMnu module,
-						// because it needs the time, when this frame is
-						// actually sent, to start the timer for monitoring
-						// the NMT state change.
-
-						pTxFrame =
-						    (tEplFrame *)
-						    EplDllkInstance_g.
-						    m_pTxBuffer
-						    [EPL_DLLK_TXFRAME_NMTREQ].
-						    m_pbBuffer;
-						if ((AmiGetByteFromLe
-						     (&pTxFrame->
-						      m_le_bMessageType)
-						     == (u8) kEplMsgTypeAsnd)
-						    &&
-						    (AmiGetByteFromLe
-						     (&pTxFrame->m_Data.m_Asnd.
-						      m_le_bServiceId)
-						     == (u8) kEplDllAsndNmtCommand)) {	// post event directly to NmtMnu module
-							Event.m_EventSink =
-							    kEplEventSinkNmtMnu;
-							Event.m_EventType =
-							    kEplEventTypeNmtMnuNmtCmdSent;
-							Event.m_uiSize =
-							    EplDllkInstance_g.
-							    m_pTxBuffer
-							    [EPL_DLLK_TXFRAME_NMTREQ].
-							    m_uiTxMsgLen;
-							Event.m_pArg = pTxFrame;
-							Ret =
-							    EplEventkPost
-							    (&Event);
-
-						}
-						// send NmtRequest
-						Ret =
-						    EdrvSendTxMsg
-						    (&EplDllkInstance_g.
-						     m_pTxBuffer
-						     [EPL_DLLK_TXFRAME_NMTREQ]);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-
-					}
-				}
-
-			} else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceUnspecified) {	// unspecified invite
-				if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) {	// non-EPL frame does exist
-					// check if frame is not empty and not being filled
-					if (EplDllkInstance_g.
-					    m_pTxBuffer
-					    [EPL_DLLK_TXFRAME_NONEPL].
-					    m_uiTxMsgLen >
-					    EPL_DLLK_BUFLEN_FILLING) {
-						// send non-EPL frame
-						Ret =
-						    EdrvSendTxMsg
-						    (&EplDllkInstance_g.
-						     m_pTxBuffer
-						     [EPL_DLLK_TXFRAME_NONEPL]);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-
-					}
-				}
-			}
-			// ASnd frame was sent, remove the request
-			EplDllkInstance_g.m_LastReqServiceId =
-			    kEplDllReqServiceNo;
-		}
-		// forward event to ErrorHandler and PDO module
-		Event.m_EventSink = kEplEventSinkNmtk;
-		Event.m_EventType = kEplEventTypeNmtEvent;
-		Event.m_uiSize = sizeof(NmtEvent);
-		Event.m_pArg = &NmtEvent;
-		Ret = EplEventkPost(&Event);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-#endif
-
-#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
-	else {			// d.k.: Why that else? on CN it is entered on IdentRes and StatusRes
-		goto Exit;
-	}
-
-	// signal process function readiness of PRes frame
-	Event.m_EventSink = kEplEventSinkDllk;
-	Event.m_EventType = kEplEventTypeDllkPresReady;
-	Event.m_uiSize = 0;
-	Event.m_pArg = NULL;
-	Ret = EplEventkPost(&Event);
-
-#endif
-
-      Exit:
-	if (Ret != kEplSuccessful) {
-		u32 dwArg;
-
-		BENCHMARK_MOD_02_TOGGLE(9);
-
-		dwArg =
-		    EplDllkInstance_g.m_DllState | (pTxBuffer_p->
-						    m_EplMsgType << 16);
-
-		// Error event for API layer
-		Ret = EplEventkPostError(kEplEventSourceDllk,
-					 Ret, sizeof(dwArg), &dwArg);
-	}
-
-	return;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCheckFrame()
-//
-// Description: check frame and set missing information
-//
-// Parameters:  pFrame_p                = ethernet frame
-//              uiFrameSize_p           = size of frame
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
-				    unsigned int uiFrameSize_p)
-{
-	tEplMsgType MsgType;
-	u16 wEtherType;
-
-	// check frame
-	if (pFrame_p != NULL) {
-		// check SrcMAC
-		if (AmiGetQword48FromBe(pFrame_p->m_be_abSrcMac) == 0) {
-			// source MAC address
-			EPL_MEMCPY(&pFrame_p->m_be_abSrcMac[0],
-				   &EplDllkInstance_g.m_be_abSrcMac[0], 6);
-		}
-		// check ethertype
-		wEtherType = AmiGetWordFromBe(&pFrame_p->m_be_wEtherType);
-		if (wEtherType == 0) {
-			// assume EPL frame
-			wEtherType = EPL_C_DLL_ETHERTYPE_EPL;
-			AmiSetWordToBe(&pFrame_p->m_be_wEtherType, wEtherType);
-		}
-
-		if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL) {
-			// source node ID
-			AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId,
-				       (u8) EplDllkInstance_g.
-				       m_DllConfigParam.m_uiNodeId);
-
-			// check message type
-			MsgType =
-			    AmiGetByteFromLe(&pFrame_p->m_le_bMessageType);
-			if (MsgType == 0) {
-				MsgType = kEplMsgTypeAsnd;
-				AmiSetByteToLe(&pFrame_p->m_le_bMessageType,
-					       (u8) MsgType);
-			}
-
-			if (MsgType == kEplMsgTypeAsnd) {
-				// destination MAC address
-				AmiSetQword48ToBe(&pFrame_p->m_be_abDstMac[0],
-						  EPL_C_DLL_MULTICAST_ASND);
-			}
-
-		}
-	}
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCbCnTimer()
-//
-// Description: called by timer module. It monitors the EPL cycle when it is a CN.
-//
-// Parameters:  pEventArg_p             = timer event argument
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplNmtState NmtState;
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-	if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) {	// zombie callback
-		// just exit
-		goto Exit;
-	}
-#endif
-
-	NmtState = EplNmtkGetNmtState();
-
-	if (NmtState <= kEplNmtGsResetConfiguration) {
-		goto Exit;
-	}
-
-	Ret = EplDllkChangeState(kEplNmtEventDllCeFrameTimeout, NmtState);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// 2008/10/15 d.k. reprogramming of timer not necessary,
-	// because it will be programmed, when SoC is received.
-/*
-    // reprogram timer
-#if EPL_TIMER_USE_HIGHRES != FALSE
-    if ((NmtState > kEplNmtCsPreOperational1)
-        && (EplDllkInstance_g.m_ullFrameTimeout != 0))
-    {
-        Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle, EplDllkInstance_g.m_ullFrameTimeout, EplDllkCbCnTimer, 0L, FALSE);
-    }
-#endif
-*/
-
-      Exit:
-	if (Ret != kEplSuccessful) {
-		u32 dwArg;
-
-		BENCHMARK_MOD_02_TOGGLE(9);
-
-		dwArg =
-		    EplDllkInstance_g.
-		    m_DllState | (kEplNmtEventDllCeFrameTimeout << 8);
-
-		// Error event for API layer
-		Ret = EplEventkPostError(kEplEventSourceDllk,
-					 Ret, sizeof(dwArg), &dwArg);
-	}
-
-	return Ret;
-}
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCbMnTimerCycle()
-//
-// Description: called by timer module. It triggers the SoC when it is a MN.
-//
-// Parameters:  pEventArg_p             = timer event argument
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplNmtState NmtState;
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-	if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) {	// zombie callback
-		// just exit
-		goto Exit;
-	}
-#endif
-
-	NmtState = EplNmtkGetNmtState();
-
-	if (NmtState <= kEplNmtGsResetConfiguration) {
-		goto Exit;
-	}
-
-	Ret = EplDllkChangeState(kEplNmtEventDllMeSocTrig, NmtState);
-
-      Exit:
-	if (Ret != kEplSuccessful) {
-		u32 dwArg;
-
-		BENCHMARK_MOD_02_TOGGLE(9);
-
-		dwArg =
-		    EplDllkInstance_g.
-		    m_DllState | (kEplNmtEventDllMeSocTrig << 8);
-
-		// Error event for API layer
-		Ret = EplEventkPostError(kEplEventSourceDllk,
-					 Ret, sizeof(dwArg), &dwArg);
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCbMnTimerResponse()
-//
-// Description: called by timer module. It monitors the PRes timeout.
-//
-// Parameters:  pEventArg_p             = timer event argument
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplNmtState NmtState;
-
-#if EPL_TIMER_USE_HIGHRES != FALSE
-	if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlResponse) {	// zombie callback
-		// just exit
-		goto Exit;
-	}
-#endif
-
-	NmtState = EplNmtkGetNmtState();
-
-	if (NmtState <= kEplNmtGsResetConfiguration) {
-		goto Exit;
-	}
-
-	Ret = EplDllkChangeState(kEplNmtEventDllMePresTimeout, NmtState);
-
-      Exit:
-	if (Ret != kEplSuccessful) {
-		u32 dwArg;
-
-		BENCHMARK_MOD_02_TOGGLE(9);
-
-		dwArg =
-		    EplDllkInstance_g.
-		    m_DllState | (kEplNmtEventDllMePresTimeout << 8);
-
-		// Error event for API layer
-		Ret = EplEventkPostError(kEplEventSourceDllk,
-					 Ret, sizeof(dwArg), &dwArg);
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkGetNodeInfo()
-//
-// Description: returns node info structure of the specified node.
-//
-// Parameters:  uiNodeId_p              = node ID
-//
-// Returns:     tEplDllkNodeInfo*       = pointer to internal node info structure
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p)
-{
-	// $$$ d.k.: use hash algorithm to retrieve the appropriate node info structure
-	//           if size of array is less than 254.
-	uiNodeId_p--;		// node ID starts at 1 but array at 0
-	if (uiNodeId_p >= tabentries(EplDllkInstance_g.m_aNodeInfo)) {
-		return NULL;
-	} else {
-		return &EplDllkInstance_g.m_aNodeInfo[uiNodeId_p];
-	}
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkMnSendSoa()
-//
-// Description: it updates and transmits the SoA.
-//
-// Parameters:  NmtState_p              = current NMT state
-//              pDllStateProposed_p     = proposed DLL state
-//              fEnableInvitation_p     = enable invitation for asynchronous phase
-//                                        it will be disabled for EPL_C_DLL_PREOP1_START_CYCLES SoAs
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
-				   tEplDllState * pDllStateProposed_p,
-				   BOOL fEnableInvitation_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEdrvTxBuffer *pTxBuffer = NULL;
-	tEplFrame *pTxFrame;
-	tEplDllkNodeInfo *pNodeInfo;
-
-	*pDllStateProposed_p = kEplDllMsNonCyclic;
-
-	pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOA];
-	if (pTxBuffer->m_pbBuffer != NULL) {	// SoA does exist
-		pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
-
-		if (fEnableInvitation_p != FALSE) {	// fetch target of asynchronous phase
-			if (EplDllkInstance_g.m_bFlag2 == 0) {	// own queues are empty
-				EplDllkInstance_g.m_LastReqServiceId =
-				    kEplDllReqServiceNo;
-			} else if (((tEplDllAsyncReqPriority) (EplDllkInstance_g.m_bFlag2 >> EPL_FRAME_FLAG2_PR_SHIFT)) == kEplDllAsyncReqPrioNmt) {	// frames in own NMT request queue available
-				EplDllkInstance_g.m_LastReqServiceId =
-				    kEplDllReqServiceNmtRequest;
-			} else {
-				EplDllkInstance_g.m_LastReqServiceId =
-				    kEplDllReqServiceUnspecified;
-			}
-			Ret =
-			    EplDllkCalAsyncGetSoaRequest(&EplDllkInstance_g.
-							 m_LastReqServiceId,
-							 &EplDllkInstance_g.
-							 m_uiLastTargetNodeId);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-			if (EplDllkInstance_g.m_LastReqServiceId != kEplDllReqServiceNo) {	// asynchronous phase will be assigned to one node
-				if (EplDllkInstance_g.m_uiLastTargetNodeId == EPL_C_ADR_INVALID) {	// exchange invalid node ID with local node ID
-					EplDllkInstance_g.m_uiLastTargetNodeId =
-					    EplDllkInstance_g.m_DllConfigParam.
-					    m_uiNodeId;
-					// d.k. DLL state WaitAsndTrig is not helpful;
-					//      so just step over to WaitSocTrig,
-					//      because own ASnd is sent automatically in CbFrameTransmitted() after SoA.
-					//*pDllStateProposed_p = kEplDllMsWaitAsndTrig;
-					*pDllStateProposed_p =
-					    kEplDllMsWaitSocTrig;
-				} else {	// assignment to CN
-					*pDllStateProposed_p =
-					    kEplDllMsWaitAsnd;
-				}
-
-				pNodeInfo =
-				    EplDllkGetNodeInfo(EplDllkInstance_g.
-						       m_uiLastTargetNodeId);
-				if (pNodeInfo == NULL) {	// no node info structure available
-					Ret = kEplDllNoNodeInfo;
-					goto Exit;
-				}
-				// update frame (EA, ER flags)
-				AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
-					       m_le_bFlag1,
-					       pNodeInfo->
-					       m_bSoaFlag1 & (EPL_FRAME_FLAG1_EA
-							      |
-							      EPL_FRAME_FLAG1_ER));
-			} else {	// no assignment of asynchronous phase
-				*pDllStateProposed_p = kEplDllMsWaitSocTrig;
-				EplDllkInstance_g.m_uiLastTargetNodeId =
-				    EPL_C_ADR_INVALID;
-			}
-
-			// update frame (target)
-			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
-				       m_le_bReqServiceId,
-				       (u8) EplDllkInstance_g.
-				       m_LastReqServiceId);
-			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
-				       m_le_bReqServiceTarget,
-				       (u8) EplDllkInstance_g.
-				       m_uiLastTargetNodeId);
-
-		} else {	// invite nobody
-			// update frame (target)
-			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
-				       m_le_bReqServiceId, (u8) 0);
-			AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
-				       m_le_bReqServiceTarget, (u8) 0);
-		}
-
-		// update frame (NMT state)
-		AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus,
-			       (u8) NmtState_p);
-
-		// send SoA frame
-		Ret = EdrvSendTxMsg(pTxBuffer);
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkMnSendSoc()
-//
-// Description: it updates and transmits the SoA.
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkMnSendSoc(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEdrvTxBuffer *pTxBuffer = NULL;
-	tEplFrame *pTxFrame;
-	tEplEvent Event;
-
-	pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOC];
-	if (pTxBuffer->m_pbBuffer != NULL) {	// SoC does exist
-		pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
-
-		// $$$ update NetTime
-
-		// send SoC frame
-		Ret = EdrvSendTxMsg(pTxBuffer);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		// trigger synchronous task
-		Event.m_EventSink = kEplEventSinkSync;
-		Event.m_EventType = kEplEventTypeSync;
-		Event.m_uiSize = 0;
-		Ret = EplEventkPost(&Event);
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkMnSendPreq()
-//
-// Description: it updates and transmits the PReq for the next isochronous CN
-//              or own PRes if enabled.
-//
-// Parameters:  NmtState_p              = current NMT state
-//              pDllStateProposed_p     = proposed DLL state
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
-				    tEplDllState * pDllStateProposed_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEdrvTxBuffer *pTxBuffer = NULL;
-	tEplFrame *pTxFrame;
-	u8 bFlag1 = 0;
-
-	if (EplDllkInstance_g.m_pCurNodeInfo == NULL) {	// start with first isochronous CN
-		EplDllkInstance_g.m_pCurNodeInfo =
-		    EplDllkInstance_g.m_pFirstNodeInfo;
-	} else {		// iterate to next isochronous CN
-		EplDllkInstance_g.m_pCurNodeInfo =
-		    EplDllkInstance_g.m_pCurNodeInfo->m_pNextNodeInfo;
-	}
-
-	if (EplDllkInstance_g.m_pCurNodeInfo == NULL) {	// last isochronous CN reached
-		Ret = EplDllkMnSendSoa(NmtState_p, pDllStateProposed_p, TRUE);
-		goto Exit;
-	} else {
-		pTxBuffer = EplDllkInstance_g.m_pCurNodeInfo->m_pPreqTxBuffer;
-		bFlag1 =
-		    EplDllkInstance_g.m_pCurNodeInfo->
-		    m_bSoaFlag1 & EPL_FRAME_FLAG1_EA;
-		*pDllStateProposed_p = kEplDllMsWaitPres;
-
-		// start PRes Timer
-		// $$$ d.k.: maybe move this call to CbFrameTransmitted(), because the time should run from there
-#if EPL_TIMER_USE_HIGHRES != FALSE
-		Ret =
-		    EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.
-						  m_TimerHdlResponse,
-						  EplDllkInstance_g.
-						  m_pCurNodeInfo->
-						  m_dwPresTimeout,
-						  EplDllkCbMnTimerResponse, 0L,
-						  FALSE);
-#endif
-	}
-
-	if (pTxBuffer == NULL) {	// PReq does not exist
-		Ret = kEplDllTxBufNotReady;
-		goto Exit;
-	}
-
-	pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
-
-	if (pTxFrame != NULL) {	// PReq does exist
-		if (NmtState_p == kEplNmtMsOperational) {	// leave RD flag untouched
-			bFlag1 |=
-			    AmiGetByteFromLe(&pTxFrame->m_Data.m_Preq.
-					     m_le_bFlag1) & EPL_FRAME_FLAG1_RD;
-		}
-
-		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,
-				       (u8) NmtState_p);
-			*pDllStateProposed_p = kEplDllMsWaitSoaTrig;
-		}
-		// $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary
-		// update frame (Flag1)
-		AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, bFlag1);
-
-		// calculate frame size from payload size
-		pTxBuffer->m_uiTxMsgLen =
-		    AmiGetWordFromLe(&pTxFrame->m_Data.m_Preq.m_le_wSize) + 24;
-
-		// send PReq frame
-		Ret = EdrvSendTxMsg(pTxBuffer);
-	} else {
-		Ret = kEplDllTxFrameInvalid;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkAsyncFrameNotReceived()
-//
-// Description: passes empty ASnd frame to receive FIFO.
-//              It will be called only for frames with registered AsndServiceIds
-//              (only kEplDllAsndFilterAny).
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
-					       ReqServiceId_p,
-					       unsigned int uiNodeId_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	u8 abBuffer[18];
-	tEplFrame *pFrame = (tEplFrame *) abBuffer;
-	tEplFrameInfo FrameInfo;
-
-	// check if previous SoA invitation was not answered
-	switch (ReqServiceId_p) {
-	case kEplDllReqServiceIdent:
-	case kEplDllReqServiceStatus:
-		// ASnd service registered?
-		if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny) {	// ASnd service ID is registered
-			AmiSetByteToLe(&pFrame->m_le_bSrcNodeId,
-				       (u8) uiNodeId_p);
-			// EPL MsgType ASnd
-			AmiSetByteToLe(&pFrame->m_le_bMessageType,
-				       (u8) kEplMsgTypeAsnd);
-			// ASnd Service ID
-			AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
-				       (u8) ReqServiceId_p);
-			// create frame info structure
-			FrameInfo.m_pFrame = pFrame;
-			FrameInfo.m_uiFrameSize = 18;	// empty non existing ASnd frame
-			// forward frame via async receive FIFO to userspace
-			Ret = EplDllkCalAsyncFrameReceived(&FrameInfo);
-		}
-		break;
-	default:
-		// no invitation issued or it was successfully answered or it is uninteresting
-		break;
-	}
-
-	return Ret;
-}
-
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-// EOF
diff --git a/drivers/staging/epl/EplDllkCal.c b/drivers/staging/epl/EplDllkCal.c
deleted file mode 100644
index 0e283d5..0000000
--- a/drivers/staging/epl/EplDllkCal.c
+++ /dev/null
@@ -1,1260 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for kernel DLL Communication Abstraction Layer 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: EplDllkCal.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.7 $  $Date: 2008/11/13 17:13:09 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/15 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "kernel/EplDllkCal.h"
-#include "kernel/EplDllk.h"
-#include "kernel/EplEventk.h"
-
-#include "EplDllCal.h"
-#ifndef EPL_NO_FIFO
-#include "SharedBuff.h"
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef min
-#define min(a,b)            (((a) < (b)) ? (a) : (b))
-#endif
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  EplDllkCal                                          */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define EPL_DLLKCAL_MAX_QUEUES  5	// CnGenReq, CnNmtReq, {MnGenReq, MnNmtReq}, MnIdentReq, MnStatusReq
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-#ifndef EPL_NO_FIFO
-//    tShbInstance    m_ShbInstanceRx;      // FIFO for Rx ASnd frames
-	tShbInstance m_ShbInstanceTxNmt;	// FIFO for Tx frames with NMT request priority
-	tShbInstance m_ShbInstanceTxGen;	// FIFO for Tx frames with generic priority
-#else
-	unsigned int m_uiFrameSizeNmt;
-	u8 m_abFrameNmt[1500];
-	unsigned int m_uiFrameSizeGen;
-	u8 m_abFrameGen[1500];
-#endif
-
-	tEplDllkCalStatistics m_Statistics;
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	// IdentRequest queue with CN node IDs
-	unsigned int m_auiQueueIdentReq[EPL_D_NMT_MaxCNNumber_U8 + 1];	// 1 entry is reserved to distinguish between full and empty
-	unsigned int m_uiWriteIdentReq;
-	unsigned int m_uiReadIdentReq;
-
-	// StatusRequest queue with CN node IDs
-	unsigned int m_auiQueueStatusReq[EPL_D_NMT_MaxCNNumber_U8 + 1];	// 1 entry is reserved to distinguish between full and empty
-	unsigned int m_uiWriteStatusReq;
-	unsigned int m_uiReadStatusReq;
-
-	unsigned int m_auiQueueCnRequests[254 * 2];
-	// first 254 entries represent the generic requests of the corresponding node
-	// second 254 entries represent the NMT requests of the corresponding node
-	unsigned int m_uiNextQueueCnRequest;
-	unsigned int m_uiNextRequestQueue;
-#endif
-
-} tEplDllkCalInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-// if no dynamic memory allocation shall be used
-// define structures statically
-static tEplDllkCalInstance EplDllkCalInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAddInstance()
-//
-// Description: add and initialize new instance of DLL CAL module
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAddInstance(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-	unsigned int fShbNewCreated;
-
-/*    ShbError = ShbCirAllocBuffer (EPL_DLLCAL_BUFFER_SIZE_RX, EPL_DLLCAL_BUFFER_ID_RX,
-        &EplDllkCalInstance_g.m_ShbInstanceRx, &fShbNewCreated);
-    // returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
-
-    if (ShbError != kShbOk)
-    {
-        Ret = kEplNoResource;
-    }
-*/
-	ShbError =
-	    ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_NMT,
-			      EPL_DLLCAL_BUFFER_ID_TX_NMT,
-			      &EplDllkCalInstance_g.m_ShbInstanceTxNmt,
-			      &fShbNewCreated);
-	// returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
-
-	if (ShbError != kShbOk) {
-		Ret = kEplNoResource;
-	}
-
-/*    ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxNmt, EplDllkCalTxNmtSignalHandler, kShbPriorityNormal);
-    // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
-
-    if (ShbError != kShbOk)
-    {
-        Ret = kEplNoResource;
-    }
-*/
-	ShbError =
-	    ShbCirAllocBuffer(EPL_DLLCAL_BUFFER_SIZE_TX_GEN,
-			      EPL_DLLCAL_BUFFER_ID_TX_GEN,
-			      &EplDllkCalInstance_g.m_ShbInstanceTxGen,
-			      &fShbNewCreated);
-	// returns kShbOk, kShbOpenMismatch, kShbOutOfMem or kShbInvalidArg
-
-	if (ShbError != kShbOk) {
-		Ret = kEplNoResource;
-	}
-
-/*    ShbError = ShbCirSetSignalHandlerNewData (EplDllkCalInstance_g.m_ShbInstanceTxGen, EplDllkCalTxGenSignalHandler, kShbPriorityNormal);
-    // returns kShbOk, kShbAlreadySignaling or kShbInvalidArg
-
-    if (ShbError != kShbOk)
-    {
-        Ret = kEplNoResource;
-    }
-*/
-#else
-	EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
-	EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalDelInstance()
-//
-// Description: deletes instance of DLL CAL module
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalDelInstance(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-
-/*    ShbError = ShbCirReleaseBuffer (EplDllkCalInstance_g.m_ShbInstanceRx);
-    if (ShbError != kShbOk)
-    {
-        Ret = kEplNoResource;
-    }
-    EplDllkCalInstance_g.m_ShbInstanceRx = NULL;
-*/
-	ShbError = ShbCirReleaseBuffer(EplDllkCalInstance_g.m_ShbInstanceTxNmt);
-	if (ShbError != kShbOk) {
-		Ret = kEplNoResource;
-	}
-	EplDllkCalInstance_g.m_ShbInstanceTxNmt = NULL;
-
-	ShbError = ShbCirReleaseBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen);
-	if (ShbError != kShbOk) {
-		Ret = kEplNoResource;
-	}
-	EplDllkCalInstance_g.m_ShbInstanceTxGen = NULL;
-
-#else
-	EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
-	EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalProcess
-//
-// Description: process the passed configuration
-//
-// Parameters:  pEvent_p                = event containing configuration options
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	switch (pEvent_p->m_EventType) {
-	case kEplEventTypeDllkServFilter:
-		{
-			tEplDllCalAsndServiceIdFilter *pServFilter;
-
-			pServFilter =
-			    (tEplDllCalAsndServiceIdFilter *) pEvent_p->m_pArg;
-			Ret =
-			    EplDllkSetAsndServiceIdFilter(pServFilter->
-							  m_ServiceId,
-							  pServFilter->
-							  m_Filter);
-			break;
-		}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	case kEplEventTypeDllkIssueReq:
-		{
-			tEplDllCalIssueRequest *pIssueReq;
-
-			pIssueReq = (tEplDllCalIssueRequest *) pEvent_p->m_pArg;
-			Ret =
-			    EplDllkCalIssueRequest(pIssueReq->m_Service,
-						   pIssueReq->m_uiNodeId,
-						   pIssueReq->m_bSoaFlag1);
-			break;
-		}
-
-	case kEplEventTypeDllkAddNode:
-		{
-			tEplDllNodeInfo *pNodeInfo;
-
-			pNodeInfo = (tEplDllNodeInfo *) pEvent_p->m_pArg;
-			Ret = EplDllkAddNode(pNodeInfo);
-			break;
-		}
-
-	case kEplEventTypeDllkDelNode:
-		{
-			unsigned int *puiNodeId;
-
-			puiNodeId = (unsigned int *)pEvent_p->m_pArg;
-			Ret = EplDllkDeleteNode(*puiNodeId);
-			break;
-		}
-
-	case kEplEventTypeDllkSoftDelNode:
-		{
-			unsigned int *puiNodeId;
-
-			puiNodeId = (unsigned int *)pEvent_p->m_pArg;
-			Ret = EplDllkSoftDeleteNode(*puiNodeId);
-			break;
-		}
-#endif
-
-	case kEplEventTypeDllkIdentity:
-		{
-			tEplDllIdentParam *pIdentParam;
-
-			pIdentParam = (tEplDllIdentParam *) pEvent_p->m_pArg;
-			if (pIdentParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) {
-				pIdentParam->m_uiSizeOfStruct =
-				    pEvent_p->m_uiSize;
-			}
-			Ret = EplDllkSetIdentity(pIdentParam);
-			break;
-		}
-
-	case kEplEventTypeDllkConfig:
-		{
-			tEplDllConfigParam *pConfigParam;
-
-			pConfigParam = (tEplDllConfigParam *) pEvent_p->m_pArg;
-			if (pConfigParam->m_uiSizeOfStruct > pEvent_p->m_uiSize) {
-				pConfigParam->m_uiSizeOfStruct =
-				    pEvent_p->m_uiSize;
-			}
-			Ret = EplDllkConfig(pConfigParam);
-			break;
-		}
-
-	default:
-		break;
-	}
-
-//Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncGetTxCount()
-//
-// Description: returns count of Tx frames of FIFO with highest priority
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p,
-				     unsigned int *puiCount_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-	unsigned long ulFrameCount;
-
-	// get frame count of Tx FIFO with NMT request priority
-	ShbError =
-	    ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
-				    &ulFrameCount);
-	// returns kShbOk, kShbInvalidArg
-
-	// error handling
-	if (ShbError != kShbOk) {
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-	if (ulFrameCount >
-	    EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt) {
-		EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt =
-		    ulFrameCount;
-	}
-
-	if (ulFrameCount != 0) {	// NMT requests are in queue
-		*pPriority_p = kEplDllAsyncReqPrioNmt;
-		*puiCount_p = (unsigned int)ulFrameCount;
-		goto Exit;
-	}
-	// get frame count of Tx FIFO with generic priority
-	ShbError =
-	    ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen,
-				    &ulFrameCount);
-	// returns kShbOk, kShbInvalidArg
-
-	// error handling
-	if (ShbError != kShbOk) {
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-	if (ulFrameCount >
-	    EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen) {
-		EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen =
-		    ulFrameCount;
-	}
-
-	*pPriority_p = kEplDllAsyncReqPrioGeneric;
-	*puiCount_p = (unsigned int)ulFrameCount;
-
-      Exit:
-#else
-	if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) {
-		*pPriority_p = kEplDllAsyncReqPrioNmt;
-		*puiCount_p = 1;
-	} else if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) {
-		*pPriority_p = kEplDllAsyncReqPrioGeneric;
-		*puiCount_p = 1;
-	} else {
-		*pPriority_p = kEplDllAsyncReqPrioGeneric;
-		*puiCount_p = 0;
-	}
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncGetTxFrame()
-//
-// Description: returns Tx frames from FIFO with specified priority
-//
-// Parameters:  pFrame_p                = IN: pointer to buffer
-//              puiFrameSize_p          = IN: max size of buffer
-//                                        OUT: actual size of frame
-//              Priority_p              = IN: priority
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
-				     unsigned int *puiFrameSize_p,
-				     tEplDllAsyncReqPriority Priority_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-	unsigned long ulFrameSize;
-
-	switch (Priority_p) {
-	case kEplDllAsyncReqPrioNmt:	// NMT request priority
-		ShbError =
-		    ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
-					(u8 *) pFrame_p, *puiFrameSize_p,
-					&ulFrameSize);
-		// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
-		break;
-
-	default:		// generic priority
-		ShbError =
-		    ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxGen,
-					(u8 *) pFrame_p, *puiFrameSize_p,
-					&ulFrameSize);
-		// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
-		break;
-
-	}
-
-	// error handling
-	if (ShbError != kShbOk) {
-		if (ShbError == kShbNoReadableData) {
-			Ret = kEplDllAsyncTxBufferEmpty;
-		} else {	// other error
-			Ret = kEplNoResource;
-		}
-		goto Exit;
-	}
-
-	*puiFrameSize_p = (unsigned int)ulFrameSize;
-
-      Exit:
-#else
-	switch (Priority_p) {
-	case kEplDllAsyncReqPrioNmt:	// NMT request priority
-		*puiFrameSize_p =
-		    min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeNmt);
-		EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameNmt,
-			   *puiFrameSize_p);
-		EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
-		break;
-
-	default:		// generic priority
-		*puiFrameSize_p =
-		    min(*puiFrameSize_p, EplDllkCalInstance_g.m_uiFrameSizeGen);
-		EPL_MEMCPY(pFrame_p, EplDllkCalInstance_g.m_abFrameGen,
-			   *puiFrameSize_p);
-		EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
-		break;
-	}
-
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncFrameReceived()
-//
-// Description: passes ASnd frame to receive FIFO.
-//              It will be called only for frames with registered AsndServiceIds.
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-
-	Event.m_EventSink = kEplEventSinkDlluCal;
-	Event.m_EventType = kEplEventTypeAsndRx;
-	Event.m_pArg = pFrameInfo_p->m_pFrame;
-	Event.m_uiSize = pFrameInfo_p->m_uiFrameSize;
-	// pass NetTime of frame to userspace
-	Event.m_NetTime = pFrameInfo_p->m_NetTime;
-
-	Ret = EplEventkPost(&Event);
-	if (Ret != kEplSuccessful) {
-		EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount++;
-	} else {
-		EplDllkCalInstance_g.m_Statistics.m_ulMaxRxFrameCount++;
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncSend()
-//
-// Description: puts the given frame into the transmit FIFO with the specified
-//              priority.
-//
-// Parameters:  pFrameInfo_p            = frame info structure
-//              Priority_p              = priority
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p,
-			       tEplDllAsyncReqPriority Priority_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-
-	switch (Priority_p) {
-	case kEplDllAsyncReqPrioNmt:	// NMT request priority
-		ShbError =
-		    ShbCirWriteDataBlock(EplDllkCalInstance_g.
-					 m_ShbInstanceTxNmt,
-					 pFrameInfo_p->m_pFrame,
-					 pFrameInfo_p->m_uiFrameSize);
-		// returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
-		break;
-
-	default:		// generic priority
-		ShbError =
-		    ShbCirWriteDataBlock(EplDllkCalInstance_g.
-					 m_ShbInstanceTxGen,
-					 pFrameInfo_p->m_pFrame,
-					 pFrameInfo_p->m_uiFrameSize);
-		// returns kShbOk, kShbExceedDataSizeLimit, kShbBufferFull, kShbInvalidArg
-		break;
-
-	}
-
-	// error handling
-	switch (ShbError) {
-	case kShbOk:
-		break;
-
-	case kShbExceedDataSizeLimit:
-		Ret = kEplDllAsyncTxBufferFull;
-		break;
-
-	case kShbBufferFull:
-		Ret = kEplDllAsyncTxBufferFull;
-		break;
-
-	case kShbInvalidArg:
-	default:
-		Ret = kEplNoResource;
-		break;
-	}
-
-#else
-
-	switch (Priority_p) {
-	case kEplDllAsyncReqPrioNmt:	// NMT request priority
-		if (EplDllkCalInstance_g.m_uiFrameSizeNmt == 0) {
-			EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameNmt,
-				   pFrameInfo_p->m_pFrame,
-				   pFrameInfo_p->m_uiFrameSize);
-			EplDllkCalInstance_g.m_uiFrameSizeNmt =
-			    pFrameInfo_p->m_uiFrameSize;
-		} else {
-			Ret = kEplDllAsyncTxBufferFull;
-			goto Exit;
-		}
-		break;
-
-	default:		// generic priority
-		if (EplDllkCalInstance_g.m_uiFrameSizeGen == 0) {
-			EPL_MEMCPY(EplDllkCalInstance_g.m_abFrameGen,
-				   pFrameInfo_p->m_pFrame,
-				   pFrameInfo_p->m_uiFrameSize);
-			EplDllkCalInstance_g.m_uiFrameSizeGen =
-			    pFrameInfo_p->m_uiFrameSize;
-		} else {
-			Ret = kEplDllAsyncTxBufferFull;
-			goto Exit;
-		}
-		break;
-	}
-
-#endif
-
-	// post event to DLL
-	Event.m_EventSink = kEplEventSinkDllk;
-	Event.m_EventType = kEplEventTypeDllkFillTx;
-	EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
-	Event.m_pArg = &Priority_p;
-	Event.m_uiSize = sizeof(Priority_p);
-	Ret = EplEventkPost(&Event);
-
-#ifdef EPL_NO_FIFO
-      Exit:
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncClearBuffer()
-//
-// Description: clears the transmit buffer
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAsyncClearBuffer(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-
-	ShbError =
-	    ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxNmt, 1000,
-			      NULL);
-	ShbError =
-	    ShbCirResetBuffer(EplDllkCalInstance_g.m_ShbInstanceTxGen, 1000,
-			      NULL);
-
-#else
-	EplDllkCalInstance_g.m_uiFrameSizeNmt = 0;
-	EplDllkCalInstance_g.m_uiFrameSizeGen = 0;
-#endif
-
-//    EPL_MEMSET(&EplDllkCalInstance_g.m_Statistics, 0, sizeof (tEplDllkCalStatistics));
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncClearQueues()
-//
-// Description: clears the transmit buffer
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-tEplKernel EplDllkCalAsyncClearQueues(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// clear MN asynchronous queues
-	EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
-	EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
-	EplDllkCalInstance_g.m_uiReadIdentReq = 0;
-	EplDllkCalInstance_g.m_uiWriteIdentReq = 0;
-	EplDllkCalInstance_g.m_uiReadStatusReq = 0;
-	EplDllkCalInstance_g.m_uiWriteStatusReq = 0;
-
-	return Ret;
-}
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalGetStatistics()
-//
-// Description: returns statistics of the asynchronous queues.
-//
-// Parameters:  ppStatistics            = statistics structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
-{
-	tEplKernel Ret = kEplSuccessful;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-
-	ShbError =
-	    ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
-				    &EplDllkCalInstance_g.m_Statistics.
-				    m_ulCurTxFrameCountNmt);
-	ShbError =
-	    ShbCirGetReadBlockCount(EplDllkCalInstance_g.m_ShbInstanceTxGen,
-				    &EplDllkCalInstance_g.m_Statistics.
-				    m_ulCurTxFrameCountGen);
-//    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceRx, &EplDllkCalInstance_g.m_Statistics.m_ulCurRxFrameCount);
-
-#else
-	if (EplDllkCalInstance_g.m_uiFrameSizeNmt > 0) {
-		EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 1;
-	} else {
-		EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountNmt = 0;
-	}
-	if (EplDllkCalInstance_g.m_uiFrameSizeGen > 0) {
-		EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 1;
-	} else {
-		EplDllkCalInstance_g.m_Statistics.m_ulCurTxFrameCountGen = 0;
-	}
-#endif
-
-	*ppStatistics = &EplDllkCalInstance_g.m_Statistics;
-	return Ret;
-}
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalIssueRequest()
-//
-// Description: issues a StatusRequest or a IdentRequest to the specified node.
-//
-// Parameters:  Service_p               = request service ID
-//              uiNodeId_p              = node ID
-//              bSoaFlag1_p             = flag1 for this node (transmit in SoA and PReq)
-//                                        If 0xFF this flag is ignored.
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, u8 bSoaFlag1_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (bSoaFlag1_p != 0xFF) {
-		Ret = EplDllkSetFlag1OfNode(uiNodeId_p, bSoaFlag1_p);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-	// add node to appropriate request queue
-	switch (Service_p) {
-	case kEplDllReqServiceIdent:
-		{
-			if (((EplDllkCalInstance_g.m_uiWriteIdentReq +
-			      1) %
-			     tabentries(EplDllkCalInstance_g.
-					m_auiQueueIdentReq))
-			    == EplDllkCalInstance_g.m_uiReadIdentReq) {	// queue is full
-				Ret = kEplDllAsyncTxBufferFull;
-				goto Exit;
-			}
-			EplDllkCalInstance_g.
-			    m_auiQueueIdentReq[EplDllkCalInstance_g.
-					       m_uiWriteIdentReq] = uiNodeId_p;
-			EplDllkCalInstance_g.m_uiWriteIdentReq =
-			    (EplDllkCalInstance_g.m_uiWriteIdentReq +
-			     1) %
-			    tabentries(EplDllkCalInstance_g.m_auiQueueIdentReq);
-			break;
-		}
-
-	case kEplDllReqServiceStatus:
-		{
-			if (((EplDllkCalInstance_g.m_uiWriteStatusReq +
-			      1) %
-			     tabentries(EplDllkCalInstance_g.
-					m_auiQueueStatusReq))
-			    == EplDllkCalInstance_g.m_uiReadStatusReq) {	// queue is full
-				Ret = kEplDllAsyncTxBufferFull;
-				goto Exit;
-			}
-			EplDllkCalInstance_g.
-			    m_auiQueueStatusReq[EplDllkCalInstance_g.
-						m_uiWriteStatusReq] =
-			    uiNodeId_p;
-			EplDllkCalInstance_g.m_uiWriteStatusReq =
-			    (EplDllkCalInstance_g.m_uiWriteStatusReq +
-			     1) %
-			    tabentries(EplDllkCalInstance_g.
-				       m_auiQueueStatusReq);
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplDllInvalidParam;
-			goto Exit;
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncGetSoaRequest()
-//
-// Description: returns next request for SoA. This function is called by DLLk module.
-//
-// Parameters:  pReqServiceId_p         = pointer to request service ID
-//                                        IN: available request for MN NMT or generic request queue (Flag2.PR)
-//                                            or kEplDllReqServiceNo if queues are empty
-//                                        OUT: next request
-//              puiNodeId_p             = OUT: pointer to node ID of next request
-//                                             = EPL_C_ADR_INVALID, if request is self addressed
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p,
-					unsigned int *puiNodeId_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiCount;
-
-//    *pReqServiceId_p = kEplDllReqServiceNo;
-
-	for (uiCount = EPL_DLLKCAL_MAX_QUEUES; uiCount > 0; uiCount--) {
-		switch (EplDllkCalInstance_g.m_uiNextRequestQueue) {
-		case 0:
-			{	// CnGenReq
-				for (;
-				     EplDllkCalInstance_g.
-				     m_uiNextQueueCnRequest <
-				     (tabentries
-				      (EplDllkCalInstance_g.
-				       m_auiQueueCnRequests) / 2);
-				     EplDllkCalInstance_g.
-				     m_uiNextQueueCnRequest++) {
-					if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) {	// non empty queue found
-						// remove one request from queue
-						EplDllkCalInstance_g.
-						    m_auiQueueCnRequests
-						    [EplDllkCalInstance_g.
-						     m_uiNextQueueCnRequest]--;
-						*puiNodeId_p =
-						    EplDllkCalInstance_g.
-						    m_uiNextQueueCnRequest + 1;
-						*pReqServiceId_p =
-						    kEplDllReqServiceUnspecified;
-						EplDllkCalInstance_g.
-						    m_uiNextQueueCnRequest++;
-						if (EplDllkCalInstance_g.m_uiNextQueueCnRequest >= (tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) {	// last node reached
-							// continue with CnNmtReq queue at next SoA
-							EplDllkCalInstance_g.
-							    m_uiNextRequestQueue
-							    = 1;
-						}
-						goto Exit;
-					}
-				}
-				// all CnGenReq queues are empty -> continue with CnNmtReq queue
-				EplDllkCalInstance_g.m_uiNextRequestQueue = 1;
-				break;
-			}
-
-		case 1:
-			{	// CnNmtReq
-				for (;
-				     EplDllkCalInstance_g.
-				     m_uiNextQueueCnRequest <
-				     tabentries(EplDllkCalInstance_g.
-						m_auiQueueCnRequests);
-				     EplDllkCalInstance_g.
-				     m_uiNextQueueCnRequest++) {
-					if (EplDllkCalInstance_g.m_auiQueueCnRequests[EplDllkCalInstance_g.m_uiNextQueueCnRequest] > 0) {	// non empty queue found
-						// remove one request from queue
-						EplDllkCalInstance_g.
-						    m_auiQueueCnRequests
-						    [EplDllkCalInstance_g.
-						     m_uiNextQueueCnRequest]--;
-						*puiNodeId_p =
-						    EplDllkCalInstance_g.
-						    m_uiNextQueueCnRequest + 1 -
-						    (tabentries
-						     (EplDllkCalInstance_g.
-						      m_auiQueueCnRequests) /
-						     2);
-						*pReqServiceId_p =
-						    kEplDllReqServiceNmtRequest;
-						EplDllkCalInstance_g.
-						    m_uiNextQueueCnRequest++;
-						if (EplDllkCalInstance_g.m_uiNextQueueCnRequest > tabentries(EplDllkCalInstance_g.m_auiQueueCnRequests)) {	// last node reached
-							// restart CnGenReq queue
-							EplDllkCalInstance_g.
-							    m_uiNextQueueCnRequest
-							    = 0;
-							// continue with MnGenReq queue at next SoA
-							EplDllkCalInstance_g.
-							    m_uiNextRequestQueue
-							    = 2;
-						}
-						goto Exit;
-					}
-				}
-				// restart CnGenReq queue
-				EplDllkCalInstance_g.m_uiNextQueueCnRequest = 0;
-				// all CnNmtReq queues are empty -> continue with MnGenReq queue
-				EplDllkCalInstance_g.m_uiNextRequestQueue = 2;
-				break;
-			}
-
-		case 2:
-			{	// MnNmtReq and MnGenReq
-				// next queue will be MnIdentReq queue
-				EplDllkCalInstance_g.m_uiNextRequestQueue = 3;
-				if (*pReqServiceId_p != kEplDllReqServiceNo) {
-					*puiNodeId_p = EPL_C_ADR_INVALID;	// DLLk must exchange this with the actual node ID
-					goto Exit;
-				}
-				break;
-			}
-
-		case 3:
-			{	// MnIdentReq
-				// next queue will be MnStatusReq queue
-				EplDllkCalInstance_g.m_uiNextRequestQueue = 4;
-				if (EplDllkCalInstance_g.m_uiReadIdentReq != EplDllkCalInstance_g.m_uiWriteIdentReq) {	// queue is not empty
-					*puiNodeId_p =
-					    EplDllkCalInstance_g.
-					    m_auiQueueIdentReq
-					    [EplDllkCalInstance_g.
-					     m_uiReadIdentReq];
-					EplDllkCalInstance_g.m_uiReadIdentReq =
-					    (EplDllkCalInstance_g.
-					     m_uiReadIdentReq +
-					     1) %
-					    tabentries(EplDllkCalInstance_g.
-						       m_auiQueueIdentReq);
-					*pReqServiceId_p =
-					    kEplDllReqServiceIdent;
-					goto Exit;
-				}
-				break;
-			}
-
-		case 4:
-			{	// MnStatusReq
-				// next queue will be CnGenReq queue
-				EplDllkCalInstance_g.m_uiNextRequestQueue = 0;
-				if (EplDllkCalInstance_g.m_uiReadStatusReq != EplDllkCalInstance_g.m_uiWriteStatusReq) {	// queue is not empty
-					*puiNodeId_p =
-					    EplDllkCalInstance_g.
-					    m_auiQueueStatusReq
-					    [EplDllkCalInstance_g.
-					     m_uiReadStatusReq];
-					EplDllkCalInstance_g.m_uiReadStatusReq =
-					    (EplDllkCalInstance_g.
-					     m_uiReadStatusReq +
-					     1) %
-					    tabentries(EplDllkCalInstance_g.
-						       m_auiQueueStatusReq);
-					*pReqServiceId_p =
-					    kEplDllReqServiceStatus;
-					goto Exit;
-				}
-				break;
-			}
-
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDllkCalAsyncSetPendingRequests()
-//
-// Description: sets the pending asynchronous frame requests of the specified node.
-//              This will add the node to the asynchronous request scheduler.
-//
-// Parameters:  uiNodeId_p              = node ID
-//              AsyncReqPrio_p          = asynchronous request priority
-//              uiCount_p               = count of asynchronous frames
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p,
-					     tEplDllAsyncReqPriority
-					     AsyncReqPrio_p,
-					     unsigned int uiCount_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// add node to appropriate request queue
-	switch (AsyncReqPrio_p) {
-	case kEplDllAsyncReqPrioNmt:
-		{
-			uiNodeId_p--;
-			if (uiNodeId_p >=
-			    (tabentries
-			     (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) {
-				Ret = kEplDllInvalidParam;
-				goto Exit;
-			}
-			uiNodeId_p +=
-			    tabentries(EplDllkCalInstance_g.
-				       m_auiQueueCnRequests) / 2;
-			EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] =
-			    uiCount_p;
-			break;
-		}
-
-	default:
-		{
-			uiNodeId_p--;
-			if (uiNodeId_p >=
-			    (tabentries
-			     (EplDllkCalInstance_g.m_auiQueueCnRequests) / 2)) {
-				Ret = kEplDllInvalidParam;
-				goto Exit;
-			}
-			EplDllkCalInstance_g.m_auiQueueCnRequests[uiNodeId_p] =
-			    uiCount_p;
-			break;
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//  Callback handler for new data signaling
-//---------------------------------------------------------------------------
-
-#ifndef EPL_NO_FIFO
-/*static void  EplDllkCalTxNmtSignalHandler (
-    tShbInstance pShbRxInstance_p,
-    unsigned long ulDataSize_p)
-{
-tEplKernel      Ret = kEplSuccessful;
-tEplEvent       Event;
-tEplDllAsyncReqPriority Priority;
-#ifndef EPL_NO_FIFO
-tShbError   ShbError;
-unsigned long   ulBlockCount;
-
-    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxNmt, &ulBlockCount);
-    if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt)
-    {
-        EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountNmt = ulBlockCount;
-    }
-
-#endif
-
-    // post event to DLL
-    Priority = kEplDllAsyncReqPrioNmt;
-    Event.m_EventSink = kEplEventSinkDllk;
-    Event.m_EventType = kEplEventTypeDllkFillTx;
-    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
-    Event.m_pArg = &Priority;
-    Event.m_uiSize = sizeof(Priority);
-    Ret = EplEventkPost(&Event);
-
-}
-
-static void  EplDllkCalTxGenSignalHandler (
-    tShbInstance pShbRxInstance_p,
-    unsigned long ulDataSize_p)
-{
-tEplKernel      Ret = kEplSuccessful;
-tEplEvent       Event;
-tEplDllAsyncReqPriority Priority;
-#ifndef EPL_NO_FIFO
-tShbError   ShbError;
-unsigned long   ulBlockCount;
-
-    ShbError = ShbCirGetReadBlockCount (EplDllkCalInstance_g.m_ShbInstanceTxGen, &ulBlockCount);
-    if (ulBlockCount > EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen)
-    {
-        EplDllkCalInstance_g.m_Statistics.m_ulMaxTxFrameCountGen = ulBlockCount;
-    }
-
-#endif
-
-    // post event to DLL
-    Priority = kEplDllAsyncReqPrioGeneric;
-    Event.m_EventSink = kEplEventSinkDllk;
-    Event.m_EventType = kEplEventTypeDllkFillTx;
-    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
-    Event.m_pArg = &Priority;
-    Event.m_uiSize = sizeof(Priority);
-    Ret = EplEventkPost(&Event);
-
-}
-*/
-#endif
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplDlluCal.c b/drivers/staging/epl/EplDlluCal.c
deleted file mode 100644
index f96fe84..0000000
--- a/drivers/staging/epl/EplDlluCal.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for DLL Communication Abstraction Layer module in EPL user part
-
-  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: EplDlluCal.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.7 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/20 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "user/EplDlluCal.h"
-#include "user/EplEventu.h"
-
-#include "EplDllCal.h"
-
-// include only if direct call between user- and kernelspace is enabled
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-#include "kernel/EplDllkCal.h"
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          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  EplDlluCal                                          */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	tEplDlluCbAsnd m_apfnDlluCbAsnd[EPL_DLL_MAX_ASND_SERVICE_ID];
-
-} tEplDlluCalInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-// if no dynamic memory allocation shall be used
-// define structures statically
-static tEplDlluCalInstance EplDlluCalInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId
-						   ServiceId_p,
-						   tEplDllAsndFilter Filter_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalAddInstance()
-//
-// Description: add and initialize new instance of DLL CAL module
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalAddInstance(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// reset instance structure
-	EPL_MEMSET(&EplDlluCalInstance_g, 0, sizeof(EplDlluCalInstance_g));
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalDelInstance()
-//
-// Description: deletes an instance of DLL CAL module
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalDelInstance(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// reset instance structure
-	EPL_MEMSET(&EplDlluCalInstance_g, 0, sizeof(EplDlluCalInstance_g));
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalProcess
-//
-// Description: process the passed asynch frame
-//
-// Parameters:  pEvent_p                = event containing frame to be processed
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalProcess(tEplEvent * pEvent_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplMsgType MsgType;
-	unsigned int uiAsndServiceId;
-	tEplFrameInfo FrameInfo;
-
-	if (pEvent_p->m_EventType == kEplEventTypeAsndRx) {
-		FrameInfo.m_pFrame = (tEplFrame *) pEvent_p->m_pArg;
-		FrameInfo.m_uiFrameSize = pEvent_p->m_uiSize;
-		// extract NetTime
-		FrameInfo.m_NetTime = pEvent_p->m_NetTime;
-
-		MsgType =
-		    (tEplMsgType) AmiGetByteFromLe(&FrameInfo.m_pFrame->
-						   m_le_bMessageType);
-		if (MsgType != kEplMsgTypeAsnd) {
-			Ret = kEplInvalidOperation;
-			goto Exit;
-		}
-
-		uiAsndServiceId =
-		    (unsigned int)AmiGetByteFromLe(&FrameInfo.m_pFrame->m_Data.
-						   m_Asnd.m_le_bServiceId);
-		if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID) {	// ASnd service ID is valid
-			if (EplDlluCalInstance_g.m_apfnDlluCbAsnd[uiAsndServiceId] != NULL) {	// handler was registered
-				Ret =
-				    EplDlluCalInstance_g.
-				    m_apfnDlluCbAsnd[uiAsndServiceId]
-				    (&FrameInfo);
-			}
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalRegAsndService()
-//
-// Description: registers the specified handler for the specified
-//              AsndServiceId with the specified node ID filter.
-//
-// Parameters:  ServiceId_p             = ASnd Service ID
-//              pfnDlluCbAsnd_p         = callback function
-//              Filter_p                = node ID filter
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalRegAsndService(tEplDllAsndServiceId ServiceId_p,
-				    tEplDlluCbAsnd pfnDlluCbAsnd_p,
-				    tEplDllAsndFilter Filter_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (ServiceId_p < tabentries(EplDlluCalInstance_g.m_apfnDlluCbAsnd)) {
-		// memorize function pointer
-		EplDlluCalInstance_g.m_apfnDlluCbAsnd[ServiceId_p] =
-		    pfnDlluCbAsnd_p;
-
-		if (pfnDlluCbAsnd_p == NULL) {	// close filter
-			Filter_p = kEplDllAsndFilterNone;
-		}
-		// set filter in DLL module in kernel part
-		Ret = EplDlluCalSetAsndServiceIdFilter(ServiceId_p, Filter_p);
-
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalAsyncSend()
-//
-// Description: sends the frame with the specified priority.
-//
-// Parameters:  pFrameInfo_p            = frame
-//                                        m_uiFrameSize does not include the
-//                                        ethernet header (14 bytes)
-//              Priority_p              = priority
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo_p,
-			       tEplDllAsyncReqPriority Priority_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-	pFrameInfo_p->m_uiFrameSize += 14;	// add size of ethernet header
-	Ret = EplDllkCalAsyncSend(pFrameInfo_p, Priority_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-}
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalIssueRequest()
-//
-// Description: issues a StatusRequest or a IdentRequest to the specified node.
-//
-// Parameters:  Service_p               = request service ID
-//              uiNodeId_p              = node ID
-//              bSoaFlag1_p             = flag1 for this node (transmit in SoA and PReq)
-//                                        If 0xFF this flag is ignored.
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, u8 bSoaFlag1_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// add node to appropriate request queue
-	switch (Service_p) {
-	case kEplDllReqServiceIdent:
-	case kEplDllReqServiceStatus:
-		{
-			tEplEvent Event;
-			tEplDllCalIssueRequest IssueReq;
-
-			Event.m_EventSink = kEplEventSinkDllkCal;
-			Event.m_EventType = kEplEventTypeDllkIssueReq;
-			IssueReq.m_Service = Service_p;
-			IssueReq.m_uiNodeId = uiNodeId_p;
-			IssueReq.m_bSoaFlag1 = bSoaFlag1_p;
-			Event.m_pArg = &IssueReq;
-			Event.m_uiSize = sizeof(IssueReq);
-
-			Ret = EplEventuPost(&Event);
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplDllInvalidParam;
-			goto Exit;
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalAddNode()
-//
-// Description: adds the specified node to the isochronous phase.
-//
-// Parameters:  pNodeInfo_p             = pointer of node info structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalAddNode(tEplDllNodeInfo * pNodeInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-
-	Event.m_EventSink = kEplEventSinkDllkCal;
-	Event.m_EventType = kEplEventTypeDllkAddNode;
-	Event.m_pArg = pNodeInfo_p;
-	Event.m_uiSize = sizeof(tEplDllNodeInfo);
-
-	Ret = EplEventuPost(&Event);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalDeleteNode()
-//
-// Description: removes the specified node from the isochronous phase.
-//
-// Parameters:  uiNodeId_p              = node ID
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-
-	Event.m_EventSink = kEplEventSinkDllkCal;
-	Event.m_EventType = kEplEventTypeDllkDelNode;
-	Event.m_pArg = &uiNodeId_p;
-	Event.m_uiSize = sizeof(uiNodeId_p);
-
-	Ret = EplEventuPost(&Event);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalSoftDeleteNode()
-//
-// Description: removes the specified node softly from the isochronous phase.
-//
-// Parameters:  uiNodeId_p              = node ID
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-
-	Event.m_EventSink = kEplEventSinkDllkCal;
-	Event.m_EventType = kEplEventTypeDllkSoftDelNode;
-	Event.m_pArg = &uiNodeId_p;
-	Event.m_uiSize = sizeof(uiNodeId_p);
-
-	Ret = EplEventuPost(&Event);
-
-	return Ret;
-}
-
-#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplDlluCalSetAsndServiceIdFilter()
-//
-// Description: forwards call to EplDllkSetAsndServiceIdFilter() in kernel part
-//
-// Parameters:  ServiceId_p             = ASnd Service ID
-//              Filter_p                = node ID filter
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId
-						   ServiceId_p,
-						   tEplDllAsndFilter Filter_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-	tEplDllCalAsndServiceIdFilter ServFilter;
-
-	Event.m_EventSink = kEplEventSinkDllkCal;
-	Event.m_EventType = kEplEventTypeDllkServFilter;
-	ServFilter.m_ServiceId = ServiceId_p;
-	ServFilter.m_Filter = Filter_p;
-	Event.m_pArg = &ServFilter;
-	Event.m_uiSize = sizeof(ServFilter);
-
-	Ret = EplEventuPost(&Event);
-
-	return Ret;
-}
-
-#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplErrDef.h b/drivers/staging/epl/EplErrDef.h
deleted file mode 100644
index 2aee12c..0000000
--- a/drivers/staging/epl/EplErrDef.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  definitions for all EPL-function return codes
-
-  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: EplErrDef.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.9 $  $Date: 2008/06/23 14:56:33 $
-
-                $State: Exp $
-
-                Build Environment:
-                    all
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2005/12/05 -as:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_ERRORDEF_H_
-#define _EPL_ERRORDEF_H_
-
-//---------------------------------------------------------------------------
-// return codes
-//---------------------------------------------------------------------------
-
-typedef enum {
-	// area for generic errors 0x0000 - 0x000F
-	kEplSuccessful = 0x0000,	// no error/successful run
-	kEplIllegalInstance = 0x0001,	// the called Instanz does not exist
-	kEplInvalidInstanceParam = 0x0002,	//
-	kEplNoFreeInstance = 0x0003,	// XxxAddInstance was called but no free instance is available
-	kEplWrongSignature = 0x0004,	// wrong signature while writing to object 0x1010 or 0x1011
-	kEplInvalidOperation = 0x0005,	// operation not allowed in this situation
-	kEplInvalidNodeId = 0x0007,	// invalid NodeId was specified
-	kEplNoResource = 0x0008,	// resource could not be created (Windows, PxROS, ...)
-	kEplShutdown = 0x0009,	// stack is shutting down
-	kEplReject = 0x000A,	// reject the subsequent command
-
-	// area for EDRV module 0x0010 - 0x001F
-//    kEplEdrvNoFrame             = 0x0010,       // no CAN message was received
-//    kEplEdrvMsgHigh             = 0x0011,       // CAN message with high priority was received
-//    kEplEdrvMsgLow              = 0x0012,       // CAN message with low priority was received
-	kEplEdrvInitError = 0x0013,	// initialisation error
-	kEplEdrvNoFreeBufEntry = 0x0014,	// no free entry in internal buffer table for Tx frames
-	kEplEdrvBufNotExisting = 0x0015,	// specified Tx buffer does not exist
-//    kEplEdrvNoFreeChannel       = 0x0014,       // CAN controller has not a free channel
-//    kEplEdrvTxBuffHighOverrun   = 0x0015,       // buffer for high priority CAN transmit messages has overrun
-//    kEplEdrvTxBuffLowOverrun    = 0x0016,       // buffer for low priority CAN transmit messages has overrun
-//    kEplEdrvIllegalBdi          = 0x0017,       // unsupported baudrate within baudrate table
-//    kEplEdrvBusy                = 0x0018,       // remote frame can not be updated because no bus contact or CAN
-	// transmission is activ
-//    kEplEdrvInvalidDriverType   = 0x0019,       // (PC: Windows or Linux) invalid driver type
-//    kEplEdrvDriverNotFound      = 0x001A,       // (PC: Windows or Linux) driver (DLL) could not be found
-//    kEplEdrvInvalidBaseAddress  = 0x001B,       // (PC: Windows or Linux) driver could not found the CAN controller
-//    kEplEdrvInvalidParam        = 0x001C,       // invalid param in function call
-
-	// area for COB module 0x0020 - 0x002F
-/*    kEplCobNoFreeEntry          = 0x0020,       // no free entry in RX- or TX-COB table
-    kEplCobAlreadyExist         = 0x0021,       // COB-ID already exists in RX- resp. TX-COB table
-    */
-	kEplDllIllegalHdl = 0x0022,	// illegal handle for a TxFrame was passed
-	kEplDllCbAsyncRegistered = 0x0023,	// handler for non-EPL frames was already registered before
-//    kEplDllAsyncRxBufferFull    = 0x0024,       // receive buffer for asynchronous frames is full
-	kEplDllAsyncTxBufferEmpty = 0x0025,	// transmit buffer for asynchronous frames is empty
-	kEplDllAsyncTxBufferFull = 0x0026,	// transmit buffer for asynchronous frames is full
-	kEplDllNoNodeInfo = 0x0027,	// MN: too less space in the internal node info structure
-	kEplDllInvalidParam = 0x0028,	// invalid parameters passed to function
-	kEplDllTxBufNotReady = 0x002E,	// TxBuffer (e.g. for PReq) is not ready yet
-	kEplDllTxFrameInvalid = 0x002F,	// TxFrame (e.g. for PReq) is invalid or does not exist
-/*    kEplCobIllegalCanId         = 0x0023,       // COB-ID is not allowed (like 0x000 is reserved for NMT, ...)
-    kEplCobInvalidCanId         = 0x0024,       // COB-ID is switched off
-    kEplCobCdrvStateSet         = 0x0025,       // at least one bit of CAN driver state is set
-    kEplCobNoFreeEntryHighBuf   = 0x0026,       // no free entry in high priotity RX- or TX-COB table
-    kEplCobOwnId                = 0x0027,       // COB-ID already exists in own module which calls CobDefine() or CobCheck()
-*/
-	// area for OBD module 0x0030 - 0x003F
-	kEplObdIllegalPart = 0x0030,	// unknown OD part
-	kEplObdIndexNotExist = 0x0031,	// object index does not exist in OD
-	kEplObdSubindexNotExist = 0x0032,	// subindex does not exist in object index
-	kEplObdReadViolation = 0x0033,	// read access to a write-only object
-	kEplObdWriteViolation = 0x0034,	// write access to a read-only object
-	kEplObdAccessViolation = 0x0035,	// access not allowed
-	kEplObdUnknownObjectType = 0x0036,	// object type not defined/known
-	kEplObdVarEntryNotExist = 0x0037,	// object does not contain VarEntry structure
-	kEplObdValueTooLow = 0x0038,	// value to write to an object is too low
-	kEplObdValueTooHigh = 0x0039,	// value to write to an object is too high
-	kEplObdValueLengthError = 0x003A,	// value to write is to long or to short
-//    kEplObdIllegalFloat         = 0x003B,       // illegal float variable
-//    kEplObdWrongOdBuilderKey    = 0x003F,       // OD was generated with demo version of tool ODBuilder
-
-	// area for NMT module 0x0040 - 0x004F
-	kEplNmtUnknownCommand = 0x0040,	// unknown NMT command
-	kEplNmtInvalidFramePointer = 0x0041,	// pointer to the frame is not valid
-	kEplNmtInvalidEvent = 0x0042,	// invalid event send to NMT-modul
-	kEplNmtInvalidState = 0x0043,	// unknown state in NMT-State-Maschine
-	kEplNmtInvalidParam = 0x0044,	// invalid parameters specified
-
-	// area for SDO/UDP module 0x0050 - 0x005F
-	kEplSdoUdpMissCb = 0x0050,	// missing callback-function pointer during inti of
-	// module
-	kEplSdoUdpNoSocket = 0x0051,	// error during init of socket
-	kEplSdoUdpSocketError = 0x0052,	// error during usage of socket
-	kEplSdoUdpThreadError = 0x0053,	// error during start of listen thread
-	kEplSdoUdpNoFreeHandle = 0x0054,	// no free connection handle for Udp
-	kEplSdoUdpSendError = 0x0055,	// Error during send of frame
-	kEplSdoUdpInvalidHdl = 0x0056,	// the connection handle is invalid
-
-	// area for SDO Sequence layer module 0x0060 - 0x006F
-	kEplSdoSeqMissCb = 0x0060,	// no callback-function assign
-	kEplSdoSeqNoFreeHandle = 0x0061,	// no free handle for connection
-	kEplSdoSeqInvalidHdl = 0x0062,	// invalid handle in SDO sequence layer
-	kEplSdoSeqUnsupportedProt = 0x0063,	// unsupported Protocol selected
-	kEplSdoSeqNoFreeHistory = 0x0064,	// no free entry in history
-	kEplSdoSeqFrameSizeError = 0x0065,	// the size of the frames is not correct
-	kEplSdoSeqRequestAckNeeded = 0x0066,	// indeicates that the history buffer is full
-	// and a ack request is needed
-	kEplSdoSeqInvalidFrame = 0x0067,	// frame not valid
-	kEplSdoSeqConnectionBusy = 0x0068,	// connection is busy -> retry later
-	kEplSdoSeqInvalidEvent = 0x0069,	// invalid event received
-
-	// area for SDO Command Layer Module 0x0070 - 0x007F
-	kEplSdoComUnsupportedProt = 0x0070,	// unsupported Protocol selected
-	kEplSdoComNoFreeHandle = 0x0071,	// no free handle for connection
-	kEplSdoComInvalidServiceType = 0x0072,	// invalid SDO service type specified
-	kEplSdoComInvalidHandle = 0x0073,	// handle invalid
-	kEplSdoComInvalidSendType = 0x0074,	// the stated to of frame to send is
-	// not possible
-	kEplSdoComNotResponsible = 0x0075,	// internal error: command layer handle is
-	// not responsible for this event from sequence layer
-	kEplSdoComHandleExists = 0x0076,	// handle to same node already exists
-	kEplSdoComHandleBusy = 0x0077,	// transfer via this handle is already running
-	kEplSdoComInvalidParam = 0x0078,	// invalid parameters passed to function
-
-	// area for EPL Event-Modul 0x0080 - 0x008F
-	kEplEventUnknownSink = 0x0080,	// unknown sink for event
-	kEplEventPostError = 0x0081,	// error during post of event
-
-	// area for EPL Timer Modul 0x0090 - 0x009F
-	kEplTimerInvalidHandle = 0x0090,	// invalid handle for timer
-	kEplTimerNoTimerCreated = 0x0091,	// no timer was created caused by
-	// an error
-
-	// area for EPL SDO/Asnd Module 0x00A0 - 0x0AF
-	kEplSdoAsndInvalidNodeId = 0x00A0,	//0 node id is invalid
-	kEplSdoAsndNoFreeHandle = 0x00A1,	// no free handle for connection
-	kEplSdoAsndInvalidHandle = 0x00A2,	// handle for connection is invalid
-
-	// area for PDO module 0x00B0 - 0x00BF
-	kEplPdoNotExist = 0x00B0,	// selected PDO does not exist
-	kEplPdoLengthExceeded = 0x00B1,	// length of PDO mapping exceedes 64 bis
-	kEplPdoGranularityMismatch = 0x00B2,	// configured PDO granularity is not equal to supported granularity
-	kEplPdoInitError = 0x00B3,	// error during initialisation of PDO module
-	kEplPdoErrorPdoEncode = 0x00B4,	// error during encoding a PDO
-	kEplPdoErrorPdoDecode = 0x00B5,	// error during decoding a PDO
-	kEplPdoErrorSend = 0x00B6,	// error during sending a PDO
-	kEplPdoErrorSyncWin = 0x00B7,	// the SYNC window runs out during sending SYNC-PDOs
-	kEplPdoErrorMapp = 0x00B8,	// invalid PDO mapping
-	kEplPdoVarNotFound = 0x00B9,	// variable was not found in function PdoSignalVar()
-	kEplPdoErrorEmcyPdoLen = 0x00BA,	// the length of a received PDO is unequal to the expected value
-	kEplPdoWriteConstObject = 0x00BB,	// constant object can not be written
-	// (only TxType, Inhibit-, Event Time for CANopen Kit)
-
-	// area for LSS slave module
-/*    kEplLsssResetNode           = 0x0080,       // NMT command "reset node" has to be processed after LSS configuration
-                                                // new of NodeId
-    kEplLsssInvalidNodeId       = 0x0081,       // no valid NodeId is configured -> wait until it is configured with
-                                                // LSS service before calling CcmConnectToNet()
-*/
-	// area for emergency consumer module 0x0090 - 0x009F
-/*    kEplEmccNoFreeProducerEntry = 0x0090,       // no free entry to add a Emergency Producer
-    kEplEmccNodeIdNotExist      = 0x0091,       // selected NodeId was never added
-    kEplEmccNodeIdInvalid       = 0x0092,       // selected NodeId is outside of range (0x01 until 0x7F)
-    kEplEmccNodeIdExist         = 0x0093,       // selected NodeId already exist
-*/
-	// area for dynamic OD 0x00A0 - 0x00AF
-/*    kEplDynNoMemory             = 0x00A0,       // no memory available
-    kEplDynInvalidConfig        = 0x00A1,       // invalid configuration in segment container
-*/
-	// area for hertbeat consumer module 0x00B0 - 0x00BF
-/*    kEplHbcEntryNotExist        = 0x00B0,       // Heartbeat Producer node not configured
-    kEplHbcEntryAlreadyExist    = 0x00B1,       // NodeId was already defined in heartbeat consumer table (object 0x1016)
-*/
-	// Configuration manager module 0x00C0 - 0x00CF
-	kEplCfgMaConfigError = 0x00C0,	// error in configuration manager
-	kEplCfgMaSdocTimeOutError = 0x00C1,	// error in configuration manager, Sdo timeout
-	kEplCfgMaInvalidDcf = 0x00C2,	// configration file not valid
-	kEplCfgMaUnsupportedDcf = 0x00C3,	// unsupported Dcf format
-	kEplCfgMaConfigWithErrors = 0x00C4,	// configuration finished with errors
-	kEplCfgMaNoFreeConfig = 0x00C5,	// no free configuration entry
-	kEplCfgMaNoConfigData = 0x00C6,	// no configuration data present
-	kEplCfgMaUnsuppDatatypeDcf = 0x00C7,	// unsupported datatype found in dcf
-	// -> this entry was not configured
-
-	// area for LSS master module 0x00D0 - 0x00DF
-/*    kEplLssmIllegalMode         = 0x00D0,       // illegal LSS mode (operation / configuration)
-    kEplLssmIllegalState        = 0x00D1,       // function was called in illegal state of LSS master
-    kEplLssmBusy                = 0x00D2,       // LSS process is busy with an previous service
-    kEplLssmIllegalCmd          = 0x00D3,       // illegal command code was set for function LssmInquireIdentity()
-    kEplLssmTimeout             = 0x00D4,       // LSS slave did not answer a LSS service
-    kEplLssmErrorInConfirm      = 0x00D5,       // LSS slave replied an error code for a LSS service
-*/
-	// area for CCM modules 0x00E0 - 0xEF
-/*    kEplCcmStoreUnvalidState    = 0x00E0,       // memory device not available due device state
-    kEplCcmStoreHwError         = 0x00E1,       // hw error due device access
-*/
-	// area for SRDO module 0x0100 - 0x011F
-/*    kEplSrdoNotExist            = 0x0100,       // selected SRDO does not exist
-    kEplSrdoGranularityMismatch = 0x0101,       // configured SRDO granularity is not equal to supported granularity
-    kEplSrdoCfgTimingError      = 0x0102,       // configuration is not ok (Timing)
-    kEplSrdoCfgIdError          = 0x0103,       // configuration is not ok (CobIds)
-    kEplSrdoCfgCrcError         = 0x0104,       // configuration is not ok (CRC)
-    kEplSrdoNmtError            = 0x0105,       // an action was tried in a wrong NMT state
-    kEplSrdoInvalidCfg          = 0x0106,       // an action was tried with an invald SRDO configuration
-    kEplSrdoInvalid             = 0x0107,       // an action was tried with an invald SRDO
-    kEplSrdoRxTxConflict        = 0x0108,       // an transmission was tried with an receive SRDO (or the other way)
-    kEplSrdoIllegalCanId        = 0x0109,       // the CanId is invalid
-    kEplSrdoCanIdAlreadyInUse   = 0x010A,       // the CanId is already in use
-    kEplSrdoNotInOrder          = 0x010B,       // the two messages of a SRDO are not in order
-    kEplSrdoSctTimeout          = 0x010C,       // timeout of SCT
-    kEplSrdoSrvtTimeout         = 0x010D,       // timeout of SRVT
-    kEplSrdoCanIdNotValid       = 0x010E,       // one of received CAN-IDs are not equal to configured one
-    kEplSrdoDlcNotValid         = 0x010F,       // one of received CAN-DLC are not equal to configured one
-    kEplSrdoErrorMapp           = 0x0110,       // wrong values in mapping found
-    kEplSrdoDataError           = 0x0111,       // data of CAN messages are not invers
-    kEplSrdoLengthExceeded      = 0x0112,       // length of SRDO mapping exceedes 64 bit per CAN-message
-    kEplSrdoNotHandledInApp     = 0x0113,       // the SRDO error was not handled in AppSrdoError()
-    kEplSrdoOverrun             = 0x0114        // a RxSRDO was received but the pevious one was not else processed
-*/
-
-	kEplApiTaskDeferred = 0x0140,	// EPL performs task in background and informs the application (or vice-versa), when it is finished
-	kEplApiInvalidParam = 0x0142,	// passed invalid parameters to a function (e.g. invalid node id)
-
-	// area untill 0x07FF is reserved
-	// area for user application from 0x0800 to 0x7FFF
-
-} tEplKernel;
-
-#endif
-//EOF
-
-// 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/EplErrorHandlerk.c b/drivers/staging/epl/EplErrorHandlerk.c
deleted file mode 100644
index 6baed04..0000000
--- a/drivers/staging/epl/EplErrorHandlerk.c
+++ /dev/null
@@ -1,810 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for error handler 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: EplErrorHandlerk.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.9 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/10/02 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#include "kernel/EplErrorHandlerk.h"
-#include "EplNmt.h"
-#include "kernel/EplEventk.h"
-#include "kernel/EplObdk.h"	// function prototyps of the EplOBD-Modul
-#include "kernel/EplDllk.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
-#error "EPL ErrorHandler module needs EPL module OBDK!"
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	u32 m_dwCumulativeCnt;	// subindex 1
-	u32 m_dwThresholdCnt;	// subindex 2
-	u32 m_dwThreshold;	// subindex 3
-
-} tEplErrorHandlerkErrorCounter;
-
-typedef struct {
-	tEplErrorHandlerkErrorCounter m_CnLossSoc;	// object 0x1C0B
-	tEplErrorHandlerkErrorCounter m_CnLossPreq;	// object 0x1C0D
-	tEplErrorHandlerkErrorCounter m_CnCrcErr;	// object 0x1C0F
-	unsigned long m_ulDllErrorEvents;
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	tEplErrorHandlerkErrorCounter m_MnCrcErr;	// object 0x1C00
-	tEplErrorHandlerkErrorCounter m_MnCycTimeExceed;	// object 0x1C02
-	u32 m_adwMnCnLossPresCumCnt[254];	// object 0x1C07
-	u32 m_adwMnCnLossPresThrCnt[254];	// object 0x1C08
-	u32 m_adwMnCnLossPresThreshold[254];	// object 0x1C09
-	BOOL m_afMnCnLossPresEvent[254];
-#endif
-
-} tEplErrorHandlerkInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static tEplErrorHandlerkInstance EplErrorHandlerkInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
-						   * pErrorCounter_p,
-						   unsigned int uiIndex_p);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
-					    unsigned int uiValueCount_p,
-					    unsigned int uiIndex_p);
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <Epl-Kernelspace-Error-Handler>                     */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplErrorHandlerkInit
-//
-// Description: function initialize the first instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplErrorHandlerkInit(void)
-{
-	tEplKernel Ret;
-
-	Ret = EplErrorHandlerkAddInstance();
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplErrorHandlerkAddInstance
-//
-// Description: function add one more instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplErrorHandlerkAddInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// reset only event variable,
-	// all other instance members are reset by OD or may keep their current value
-	// d.k.: this is necessary for the cumulative counters, which shall not be reset
-	EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0;
-
-	// link counters to OD
-	// $$$ d.k. if OD resides in userspace, fetch pointer to shared memory,
-	//          which shall have the same structure as the instance (needs to be declared globally).
-	//          Other idea: error counter shall belong to the process image
-	//          (reset of counters by SDO write are a little bit tricky).
-
-	Ret =
-	    EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
-					     m_CnLossSoc, 0x1C0B);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret =
-	    EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
-					     m_CnLossPreq, 0x1C0D);
-	// ignore return code, because object 0x1C0D is conditional
-
-	Ret =
-	    EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
-					     m_CnCrcErr, 0x1C0F);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	Ret =
-	    EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
-					     m_MnCrcErr, 0x1C00);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret =
-	    EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
-					     m_MnCycTimeExceed, 0x1C02);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret =
-	    EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g.
-				      m_adwMnCnLossPresCumCnt,
-				      tabentries(EplErrorHandlerkInstance_g.
-						 m_adwMnCnLossPresCumCnt),
-				      0x1C07);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret =
-	    EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g.
-				      m_adwMnCnLossPresThrCnt,
-				      tabentries(EplErrorHandlerkInstance_g.
-						 m_adwMnCnLossPresThrCnt),
-				      0x1C08);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret =
-	    EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g.
-				      m_adwMnCnLossPresThreshold,
-				      tabentries(EplErrorHandlerkInstance_g.
-						 m_adwMnCnLossPresThreshold),
-				      0x1C09);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplErrorHandlerkDelInstance
-//
-// Description: function delete instance an free the bufferstructure
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplErrorHandlerkDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplErrorHandlerkProcess
-//
-// Description: processes error events from DLL
-//
-//
-//
-// Parameters:  pEvent_p = pointer to event-structur from buffer
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-	unsigned long ulDllErrorEvents;
-	tEplEvent Event;
-	tEplNmtEvent NmtEvent;
-
-	Ret = kEplSuccessful;
-
-	// check m_EventType
-	switch (pEvent_p->m_EventType) {
-	case kEplEventTypeDllError:
-		{
-			tEplErrorHandlerkEvent *pErrHandlerEvent =
-			    (tEplErrorHandlerkEvent *) pEvent_p->m_pArg;
-
-			ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents;
-
-			// check the several error events
-			if ((EplErrorHandlerkInstance_g.m_CnLossSoc.
-			     m_dwThreshold > 0)
-			    && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0)) {	// loss of SoC event occured
-				// increment cumulative counter by 1
-				EplErrorHandlerkInstance_g.m_CnLossSoc.
-				    m_dwCumulativeCnt++;
-				// increment threshold counter by 8
-				EplErrorHandlerkInstance_g.m_CnLossSoc.
-				    m_dwThresholdCnt += 8;
-				if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold) {	// threshold is reached
-					// $$$ d.k.: generate error history entry E_DLL_LOSS_SOC_TH
-
-					// post event to NMT state machine
-					NmtEvent = kEplNmtEventNmtCycleError;
-					Event.m_EventSink = kEplEventSinkNmtk;
-					Event.m_EventType =
-					    kEplEventTypeNmtEvent;
-					Event.m_pArg = &NmtEvent;
-					Event.m_uiSize = sizeof(NmtEvent);
-					Ret = EplEventkPost(&Event);
-				}
-				EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_LOSS_SOC;
-			}
-
-			if ((EplErrorHandlerkInstance_g.m_CnLossPreq.
-			     m_dwThreshold > 0)
-			    && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0)) {	// loss of PReq event occured
-				// increment cumulative counter by 1
-				EplErrorHandlerkInstance_g.m_CnLossPreq.
-				    m_dwCumulativeCnt++;
-				// increment threshold counter by 8
-				EplErrorHandlerkInstance_g.m_CnLossPreq.
-				    m_dwThresholdCnt += 8;
-				if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold) {	// threshold is reached
-					// $$$ d.k.: generate error history entry E_DLL_LOSS_PREQ_TH
-
-					// post event to NMT state machine
-					NmtEvent = kEplNmtEventNmtCycleError;
-					Event.m_EventSink = kEplEventSinkNmtk;
-					Event.m_EventType =
-					    kEplEventTypeNmtEvent;
-					Event.m_pArg = &NmtEvent;
-					Event.m_uiSize = sizeof(NmtEvent);
-					Ret = EplEventkPost(&Event);
-				}
-			}
-
-			if ((EplErrorHandlerkInstance_g.m_CnLossPreq.
-			     m_dwThresholdCnt > 0)
-			    && ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0)) {	// PReq correctly received
-				// decrement threshold counter by 1
-				EplErrorHandlerkInstance_g.m_CnLossPreq.
-				    m_dwThresholdCnt--;
-			}
-
-			if ((EplErrorHandlerkInstance_g.m_CnCrcErr.
-			     m_dwThreshold > 0)
-			    && ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0)) {	// CRC error event occured
-				// increment cumulative counter by 1
-				EplErrorHandlerkInstance_g.m_CnCrcErr.
-				    m_dwCumulativeCnt++;
-				// increment threshold counter by 8
-				EplErrorHandlerkInstance_g.m_CnCrcErr.
-				    m_dwThresholdCnt += 8;
-				if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold) {	// threshold is reached
-					// $$$ d.k.: generate error history entry E_DLL_CRC_TH
-
-					// post event to NMT state machine
-					NmtEvent = kEplNmtEventNmtCycleError;
-					Event.m_EventSink = kEplEventSinkNmtk;
-					Event.m_EventType =
-					    kEplEventTypeNmtEvent;
-					Event.m_pArg = &NmtEvent;
-					Event.m_uiSize = sizeof(NmtEvent);
-					Ret = EplEventkPost(&Event);
-				}
-				EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_CN_CRC;
-			}
-
-			if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0) {	// invalid format error occured (only direct reaction)
-				// $$$ d.k.: generate error history entry E_DLL_INVALID_FORMAT
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-				if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive) {	// MN is active
-					if (pErrHandlerEvent->m_uiNodeId != 0) {
-						tEplHeartbeatEvent
-						    HeartbeatEvent;
-
-						// remove node from isochronous phase
-						Ret =
-						    EplDllkDeleteNode
-						    (pErrHandlerEvent->
-						     m_uiNodeId);
-
-						// inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
-						HeartbeatEvent.m_uiNodeId =
-						    pErrHandlerEvent->
-						    m_uiNodeId;
-						HeartbeatEvent.m_NmtState =
-						    kEplNmtCsNotActive;
-						HeartbeatEvent.m_wErrorCode =
-						    EPL_E_DLL_INVALID_FORMAT;
-						Event.m_EventSink =
-						    kEplEventSinkNmtMnu;
-						Event.m_EventType =
-						    kEplEventTypeHeartbeat;
-						Event.m_uiSize =
-						    sizeof(HeartbeatEvent);
-						Event.m_pArg = &HeartbeatEvent;
-						Ret = EplEventkPost(&Event);
-					}
-					// $$$ and else should lead to InternComError
-				} else
-#endif
-				{	// CN is active
-					// post event to NMT state machine
-					NmtEvent = kEplNmtEventInternComError;
-					Event.m_EventSink = kEplEventSinkNmtk;
-					Event.m_EventType =
-					    kEplEventTypeNmtEvent;
-					Event.m_pArg = &NmtEvent;
-					Event.m_uiSize = sizeof(NmtEvent);
-					Ret = EplEventkPost(&Event);
-				}
-			}
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			if ((EplErrorHandlerkInstance_g.m_MnCrcErr.
-			     m_dwThreshold > 0)
-			    && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0)) {	// CRC error event occured
-				// increment cumulative counter by 1
-				EplErrorHandlerkInstance_g.m_MnCrcErr.
-				    m_dwCumulativeCnt++;
-				// increment threshold counter by 8
-				EplErrorHandlerkInstance_g.m_MnCrcErr.
-				    m_dwThresholdCnt += 8;
-				if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold) {	// threshold is reached
-					// $$$ d.k.: generate error history entry E_DLL_CRC_TH
-
-					// post event to NMT state machine
-					NmtEvent = kEplNmtEventNmtCycleError;
-					Event.m_EventSink = kEplEventSinkNmtk;
-					Event.m_EventType =
-					    kEplEventTypeNmtEvent;
-					Event.m_pArg = &NmtEvent;
-					Event.m_uiSize = sizeof(NmtEvent);
-					Ret = EplEventkPost(&Event);
-				}
-				EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_MN_CRC;
-			}
-
-			if ((EplErrorHandlerkInstance_g.m_MnCycTimeExceed.
-			     m_dwThreshold > 0)
-			    && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0)) {	// cycle time exceeded event occured
-				// increment cumulative counter by 1
-				EplErrorHandlerkInstance_g.m_MnCycTimeExceed.
-				    m_dwCumulativeCnt++;
-				// increment threshold counter by 8
-				EplErrorHandlerkInstance_g.m_MnCycTimeExceed.
-				    m_dwThresholdCnt += 8;
-				if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold) {	// threshold is reached
-					// $$$ d.k.: generate error history entry E_DLL_CYCLE_EXCEED_TH
-
-					// post event to NMT state machine
-					NmtEvent = kEplNmtEventNmtCycleError;
-					Event.m_EventSink = kEplEventSinkNmtk;
-					Event.m_EventType =
-					    kEplEventTypeNmtEvent;
-					Event.m_pArg = &NmtEvent;
-					Event.m_uiSize = sizeof(NmtEvent);
-					Ret = EplEventkPost(&Event);
-				}
-				// $$$ d.k.: else generate error history entry E_DLL_CYCLE_EXCEED
-				EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
-				    EPL_DLL_ERR_MN_CYCTIMEEXCEED;
-			}
-
-			if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0) {	// CN loss PRes event occured
-				unsigned int uiNodeId;
-
-				uiNodeId = pErrHandlerEvent->m_uiNodeId - 1;
-				if ((uiNodeId <
-				     tabentries(EplErrorHandlerkInstance_g.
-						m_adwMnCnLossPresCumCnt))
-				    && (EplErrorHandlerkInstance_g.
-					m_adwMnCnLossPresThreshold[uiNodeId] >
-					0)) {
-					// increment cumulative counter by 1
-					EplErrorHandlerkInstance_g.
-					    m_adwMnCnLossPresCumCnt[uiNodeId]++;
-					// increment threshold counter by 8
-					EplErrorHandlerkInstance_g.
-					    m_adwMnCnLossPresThrCnt[uiNodeId] +=
-					    8;
-					if (EplErrorHandlerkInstance_g.
-					    m_adwMnCnLossPresThrCnt[uiNodeId]
-					    >= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId]) {	// threshold is reached
-						tEplHeartbeatEvent
-						    HeartbeatEvent;
-
-						// $$$ d.k.: generate error history entry E_DLL_LOSS_PRES_TH
-
-						// remove node from isochronous phase
-						Ret =
-						    EplDllkDeleteNode
-						    (pErrHandlerEvent->
-						     m_uiNodeId);
-
-						// inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
-						HeartbeatEvent.m_uiNodeId =
-						    pErrHandlerEvent->
-						    m_uiNodeId;
-						HeartbeatEvent.m_NmtState =
-						    kEplNmtCsNotActive;
-						HeartbeatEvent.m_wErrorCode =
-						    EPL_E_DLL_LOSS_PRES_TH;
-						Event.m_EventSink =
-						    kEplEventSinkNmtMnu;
-						Event.m_EventType =
-						    kEplEventTypeHeartbeat;
-						Event.m_uiSize =
-						    sizeof(HeartbeatEvent);
-						Event.m_pArg = &HeartbeatEvent;
-						Ret = EplEventkPost(&Event);
-					}
-					EplErrorHandlerkInstance_g.
-					    m_afMnCnLossPresEvent[uiNodeId] =
-					    TRUE;
-				}
-			}
-#endif
-
-			break;
-		}
-
-		// NMT event
-	case kEplEventTypeNmtEvent:
-		{
-			if ((*(tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllCeSoa) {	// SoA event of CN -> decrement threshold counters
-
-				if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) == 0) {	// decrement loss of SoC threshold counter, because it didn't occur last cycle
-					if (EplErrorHandlerkInstance_g.
-					    m_CnLossSoc.m_dwThresholdCnt > 0) {
-						EplErrorHandlerkInstance_g.
-						    m_CnLossSoc.
-						    m_dwThresholdCnt--;
-					}
-				}
-
-				if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) == 0) {	// decrement CRC threshold counter, because it didn't occur last cycle
-					if (EplErrorHandlerkInstance_g.
-					    m_CnCrcErr.m_dwThresholdCnt > 0) {
-						EplErrorHandlerkInstance_g.
-						    m_CnCrcErr.
-						    m_dwThresholdCnt--;
-					}
-				}
-			}
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			else if ((*(tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent) {	// SoA event of MN -> decrement threshold counters
-				tEplDllkNodeInfo *pIntNodeInfo;
-				unsigned int uiNodeId;
-
-				Ret = EplDllkGetFirstNodeInfo(&pIntNodeInfo);
-				if (Ret != kEplSuccessful) {
-					break;
-				}
-				// iterate through node info structure list
-				while (pIntNodeInfo != NULL) {
-					uiNodeId = pIntNodeInfo->m_uiNodeId - 1;
-					if (uiNodeId <
-					    tabentries
-					    (EplErrorHandlerkInstance_g.
-					     m_adwMnCnLossPresCumCnt)) {
-						if (EplErrorHandlerkInstance_g.
-						    m_afMnCnLossPresEvent
-						    [uiNodeId] == FALSE) {
-							if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] > 0) {
-								EplErrorHandlerkInstance_g.
-								    m_adwMnCnLossPresThrCnt
-								    [uiNodeId]--;
-							}
-						} else {
-							EplErrorHandlerkInstance_g.
-							    m_afMnCnLossPresEvent
-							    [uiNodeId] = FALSE;
-						}
-					}
-					pIntNodeInfo =
-					    pIntNodeInfo->m_pNextNodeInfo;
-				}
-
-				if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) == 0) {	// decrement CRC threshold counter, because it didn't occur last cycle
-					if (EplErrorHandlerkInstance_g.
-					    m_MnCrcErr.m_dwThresholdCnt > 0) {
-						EplErrorHandlerkInstance_g.
-						    m_MnCrcErr.
-						    m_dwThresholdCnt--;
-					}
-				}
-
-				if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) == 0) {	// decrement cycle exceed threshold counter, because it didn't occur last cycle
-					if (EplErrorHandlerkInstance_g.
-					    m_MnCycTimeExceed.m_dwThresholdCnt >
-					    0) {
-						EplErrorHandlerkInstance_g.
-						    m_MnCycTimeExceed.
-						    m_dwThresholdCnt--;
-					}
-				}
-			}
-#endif
-
-			// reset error events
-			EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0L;
-
-			break;
-		}
-
-		// unknown type
-	default:
-		{
-		}
-
-	}			// end of switch(pEvent_p->m_EventType)
-
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplErrorHandlerkLinkErrorCounter
-//
-// Description: link specified error counter structure to OD entry
-//
-// Parameters:  pErrorCounter_p         = pointer to error counter structure
-//              uiIndex_p               = OD index
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
-						   * pErrorCounter_p,
-						   unsigned int uiIndex_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplVarParam VarParam;
-
-	VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt;
-	VarParam.m_Size = sizeof(u32);
-	VarParam.m_uiIndex = uiIndex_p;
-	VarParam.m_uiSubindex = 0x01;
-	VarParam.m_ValidFlag = kVarValidAll;
-	Ret = EplObdDefineVar(&VarParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt;
-	VarParam.m_Size = sizeof(u32);
-	VarParam.m_uiIndex = uiIndex_p;
-	VarParam.m_uiSubindex = 0x02;
-	VarParam.m_ValidFlag = kVarValidAll;
-	Ret = EplObdDefineVar(&VarParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	VarParam.m_pData = &pErrorCounter_p->m_dwThreshold;
-	VarParam.m_Size = sizeof(u32);
-	VarParam.m_uiIndex = uiIndex_p;
-	VarParam.m_uiSubindex = 0x03;
-	VarParam.m_ValidFlag = kVarValidAll;
-	Ret = EplObdDefineVar(&VarParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplErrorHandlerkLinkErrorCounter
-//
-// Description: link specified error counter structure to OD entry
-//
-// Parameters:  pErrorCounter_p         = pointer to error counter structure
-//              uiIndex_p               = OD index
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
-					    unsigned int uiValueCount_p,
-					    unsigned int uiIndex_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplVarParam VarParam;
-	tEplObdSize EntrySize;
-	u8 bIndexEntries;
-
-	EntrySize = (tEplObdSize) sizeof(bIndexEntries);
-	Ret = EplObdReadEntry(uiIndex_p,
-			      0x00, (void *)&bIndexEntries, &EntrySize);
-
-	if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00)) {
-		// Object doesn't exist or invalid entry number
-		Ret = kEplObdIndexNotExist;
-		goto Exit;
-	}
-
-	if (bIndexEntries < uiValueCount_p) {
-		uiValueCount_p = bIndexEntries;
-	}
-
-	VarParam.m_Size = sizeof(u32);
-	VarParam.m_uiIndex = uiIndex_p;
-	VarParam.m_ValidFlag = kVarValidAll;
-
-	for (VarParam.m_uiSubindex = 0x01;
-	     VarParam.m_uiSubindex <= uiValueCount_p; VarParam.m_uiSubindex++) {
-		VarParam.m_pData = pdwValue_p;
-		Ret = EplObdDefineVar(&VarParam);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		pdwValue_p++;
-	}
-
-      Exit:
-	return Ret;
-}
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplEvent.h b/drivers/staging/epl/EplEvent.h
deleted file mode 100644
index 910bd69..0000000
--- a/drivers/staging/epl/EplEvent.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for event 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: EplEvent.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/12 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_EVENT_H_
-#define _EPL_EVENT_H_
-
-#include "EplInc.h"
-#include "EplNmt.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// name and size of event queues
-#define EPL_EVENT_NAME_SHB_KERNEL_TO_USER   "ShbKernelToUser"
-#ifndef EPL_EVENT_SIZE_SHB_KERNEL_TO_USER
-#define EPL_EVENT_SIZE_SHB_KERNEL_TO_USER   32768	// 32 kByte
-#endif
-
-#define EPL_EVENT_NAME_SHB_USER_TO_KERNEL   "ShbUserToKernel"
-#ifndef EPL_EVENT_SIZE_SHB_USER_TO_KERNEL
-#define EPL_EVENT_SIZE_SHB_USER_TO_KERNEL   32768	// 32 kByte
-#endif
-
-// max size of event argument
-#ifndef EPL_MAX_EVENT_ARG_SIZE
-#define EPL_MAX_EVENT_ARG_SIZE      256	// because of PDO
-#endif
-
-#define EPL_DLL_ERR_MN_CRC           0x00000001L	// object 0x1C00
-#define EPL_DLL_ERR_MN_COLLISION     0x00000002L	// object 0x1C01
-#define EPL_DLL_ERR_MN_CYCTIMEEXCEED 0x00000004L	// object 0x1C02
-#define EPL_DLL_ERR_MN_LOSS_LINK     0x00000008L	// object 0x1C03
-#define EPL_DLL_ERR_MN_CN_LATE_PRES  0x00000010L	// objects 0x1C04-0x1C06
-#define EPL_DLL_ERR_MN_CN_LOSS_PRES  0x00000080L	// objects 0x1C07-0x1C09
-#define EPL_DLL_ERR_CN_COLLISION     0x00000400L	// object 0x1C0A
-#define EPL_DLL_ERR_CN_LOSS_SOC      0x00000800L	// object 0x1C0B
-#define EPL_DLL_ERR_CN_LOSS_SOA      0x00001000L	// object 0x1C0C
-#define EPL_DLL_ERR_CN_LOSS_PREQ     0x00002000L	// object 0x1C0D
-#define EPL_DLL_ERR_CN_RECVD_PREQ    0x00004000L	// decrement object 0x1C0D/2
-#define EPL_DLL_ERR_CN_SOC_JITTER    0x00008000L	// object 0x1C0E
-#define EPL_DLL_ERR_CN_CRC           0x00010000L	// object 0x1C0F
-#define EPL_DLL_ERR_CN_LOSS_LINK     0x00020000L	// object 0x1C10
-#define EPL_DLL_ERR_MN_LOSS_STATRES  0x00040000L	// objects 0x1C15-0x1C17 (should be operated by NmtMnu module)
-#define EPL_DLL_ERR_BAD_PHYS_MODE    0x00080000L	// no object
-#define EPL_DLL_ERR_MAC_BUFFER       0x00100000L	// no object (NMT_GT6)
-#define EPL_DLL_ERR_INVALID_FORMAT   0x00200000L	// no object (NMT_GT6)
-#define EPL_DLL_ERR_ADDRESS_CONFLICT 0x00400000L	// no object (remove CN from configuration)
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-// EventType determines the argument of the event
-typedef enum {
-	kEplEventTypeNmtEvent = 0x01,	// NMT event
-	// arg is pointer to tEplNmtEvent
-	kEplEventTypePdoRx = 0x02,	// PDO frame received event (PRes/PReq)
-	// arg is pointer to tEplFrame
-	kEplEventTypePdoTx = 0x03,	// PDO frame transmitted event (PRes/PReq)
-	// arg is pointer to tEplFrameInfo
-	kEplEventTypePdoSoa = 0x04,	// SoA frame received event (isochronous phase completed)
-	// arg is pointer to nothing
-	kEplEventTypeSync = 0x05,	// Sync event (e.g. SoC or anticipated SoC)
-	// arg is pointer to nothing
-	kEplEventTypeTimer = 0x06,	// Timer event
-	// arg is pointer to tEplTimerEventArg
-	kEplEventTypeHeartbeat = 0x07,	// Heartbeat event
-	// arg is pointer to tEplHeartbeatEvent
-	kEplEventTypeDllkCreate = 0x08,	// DLL kernel create event
-	// arg is pointer to the new tEplNmtState
-	kEplEventTypeDllkDestroy = 0x09,	// DLL kernel destroy event
-	// arg is pointer to the old tEplNmtState
-	kEplEventTypeDllkFillTx = 0x0A,	// DLL kernel fill TxBuffer event
-	// arg is pointer to tEplDllAsyncReqPriority
-	kEplEventTypeDllkPresReady = 0x0B,	// DLL kernel PRes ready event
-	// arg is pointer to nothing
-	kEplEventTypeError = 0x0C,	// Error event for API layer
-	// arg is pointer to tEplEventError
-	kEplEventTypeNmtStateChange = 0x0D,	// indicate change of NMT-State
-	// arg is pointer to tEplEventNmtStateChange
-	kEplEventTypeDllError = 0x0E,	// DLL error event for Error handler
-	// arg is pointer to tEplErrorHandlerkEvent
-	kEplEventTypeAsndRx = 0x0F,	// received ASnd frame for DLL user module
-	// arg is pointer to tEplFrame
-	kEplEventTypeDllkServFilter = 0x10,	// configure ServiceIdFilter
-	// arg is pointer to tEplDllCalServiceIdFilter
-	kEplEventTypeDllkIdentity = 0x11,	// configure Identity
-	// arg is pointer to tEplDllIdentParam
-	kEplEventTypeDllkConfig = 0x12,	// configure ConfigParam
-	// arg is pointer to tEplDllConfigParam
-	kEplEventTypeDllkIssueReq = 0x13,	// issue Ident/Status request
-	// arg is pointer to tEplDllCalIssueRequest
-	kEplEventTypeDllkAddNode = 0x14,	// add node to isochronous phase
-	// arg is pointer to tEplDllNodeInfo
-	kEplEventTypeDllkDelNode = 0x15,	// remove node from isochronous phase
-	// arg is pointer to unsigned int
-	kEplEventTypeDllkSoftDelNode = 0x16,	// remove node softly from isochronous phase
-	// arg is pointer to unsigned int
-	kEplEventTypeDllkStartReducedCycle = 0x17,	// start reduced EPL cycle on MN
-	// arg is pointer to nothing
-	kEplEventTypeNmtMnuNmtCmdSent = 0x18,	// NMT command was actually sent
-	// arg is pointer to tEplFrame
-
-} tEplEventType;
-
-// EventSink determines the consumer of the event
-typedef enum {
-	kEplEventSinkSync = 0x00,	// Sync event for application or kernel EPL module
-	kEplEventSinkNmtk = 0x01,	// events for Nmtk module
-	kEplEventSinkDllk = 0x02,	// events for Dllk module
-	kEplEventSinkDlluCal = 0x03,	// events for DlluCal module
-	kEplEventSinkDllkCal = 0x04,	// events for DllkCal module
-	kEplEventSinkPdok = 0x05,	// events for Pdok module
-	kEplEventSinkNmtu = 0x06,	// events for Nmtu module
-	kEplEventSinkErrk = 0x07,	// events for Error handler module
-	kEplEventSinkErru = 0x08,	// events for Error signaling module
-	kEplEventSinkSdoAsySeq = 0x09,	// events for asyncronous SDO Sequence Layer module
-	kEplEventSinkNmtMnu = 0x0A,	// events for NmtMnu module
-	kEplEventSinkLedu = 0x0B,	// events for Ledu module
-	kEplEventSinkApi = 0x0F,	// events for API module
-
-} tEplEventSink;
-
-// EventSource determines the source of an errorevent
-typedef enum {
-	// kernelspace modules
-	kEplEventSourceDllk = 0x01,	// Dllk module
-	kEplEventSourceNmtk = 0x02,	// Nmtk module
-	kEplEventSourceObdk = 0x03,	// Obdk module
-	kEplEventSourcePdok = 0x04,	// Pdok module
-	kEplEventSourceTimerk = 0x05,	// Timerk module
-	kEplEventSourceEventk = 0x06,	// Eventk module
-	kEplEventSourceSyncCb = 0x07,	// sync-Cb
-	kEplEventSourceErrk = 0x08,	// Error handler module
-
-	// userspace modules
-	kEplEventSourceDllu = 0x10,	// Dllu module
-	kEplEventSourceNmtu = 0x11,	// Nmtu module
-	kEplEventSourceNmtCnu = 0x12,	// NmtCnu module
-	kEplEventSourceNmtMnu = 0x13,	// NmtMnu module
-	kEplEventSourceObdu = 0x14,	// Obdu module
-	kEplEventSourceSdoUdp = 0x15,	// Sdo/Udp module
-	kEplEventSourceSdoAsnd = 0x16,	// Sdo/Asnd module
-	kEplEventSourceSdoAsySeq = 0x17,	// Sdo asynchronus Sequence Layer module
-	kEplEventSourceSdoCom = 0x18,	// Sdo command layer module
-	kEplEventSourceTimeru = 0x19,	// Timeru module
-	kEplEventSourceCfgMau = 0x1A,	// CfgMau module
-	kEplEventSourceEventu = 0x1B,	// Eventu module
-	kEplEventSourceEplApi = 0x1C,	// Api module
-	kEplEventSourceLedu = 0x1D,	// Ledu module
-
-} tEplEventSource;
-
-// structure of EPL event (element order must not be changed!)
-typedef struct {
-	tEplEventType m_EventType /*:28 */ ;	// event type
-	tEplEventSink m_EventSink /*:4 */ ;	// event sink
-	tEplNetTime m_NetTime;	// timestamp
-	unsigned int m_uiSize;	// size of argument
-	void *m_pArg;		// argument of event
-
-} tEplEvent;
-
-// short structure of EPL event without argument and its size (element order must not be changed!)
-typedef struct {
-	tEplEventType m_EventType /*:28 */ ;	// event type
-	tEplEventSink m_EventSink /*:4 */ ;	// event sink
-	tEplNetTime m_NetTime;	// timestamp
-
-} tEplEventShort;
-
-typedef struct {
-	unsigned int m_uiIndex;
-	unsigned int m_uiSubIndex;
-
-} tEplEventObdError;
-
-// structure for kEplEventTypeError
-typedef struct {
-	tEplEventSource m_EventSource;	// module which posted this error event
-	tEplKernel m_EplError;	// EPL error which occured
-	union {
-		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
-
-	} m_Arg;
-
-} tEplEventError;
-
-// structure for kEplEventTypeDllError
-typedef struct {
-	unsigned long m_ulDllErrorEvents;	// EPL_DLL_ERR_*
-	unsigned int m_uiNodeId;
-	tEplNmtState m_NmtState;
-
-} tEplErrorHandlerkEvent;
-
-// callback function to get informed about sync event
-typedef tEplKernel(*tEplSyncCb) (void);
-
-// callback function for generic events
-typedef tEplKernel(*tEplProcessEventCb) (tEplEvent *pEplEvent_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_EVENT_H_
diff --git a/drivers/staging/epl/EplEventk.c b/drivers/staging/epl/EplEventk.c
deleted file mode 100644
index ef36815..0000000
--- a/drivers/staging/epl/EplEventk.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for Epl-Kernelspace-Event-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: EplEventk.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.9 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/20 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "kernel/EplEventk.h"
-#include "kernel/EplNmtk.h"
-#include "kernel/EplDllk.h"
-#include "kernel/EplDllkCal.h"
-#include "kernel/EplErrorHandlerk.h"
-#include "Benchmark.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-#include "kernel/EplPdok.h"
-#include "kernel/EplPdokCal.h"
-#endif
-
-#ifdef EPL_NO_FIFO
-#include "user/EplEventu.h"
-#else
-#include "SharedBuff.h"
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-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
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-#ifndef EPL_NO_FIFO
-	tShbInstance m_pShbKernelToUserInstance;
-	tShbInstance m_pShbUserToKernelInstance;
-#else
-
-#endif
-	tEplSyncCb m_pfnCbSync;
-	unsigned int m_uiUserToKernelFullCount;
-
-} tEplEventkInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-static tEplEventkInstance EplEventkInstance_g;
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-// callback function for incoming events
-#ifndef EPL_NO_FIFO
-static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
-				       unsigned long ulDataSize_p);
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <Epl-Kernelspace-Event>                             */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventkInit
-//
-// Description: function initializes the first instance
-//
-// Parameters:  pfnCbSync_p = callback-function for sync event
-//
-// Returns:     tEpKernel   = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplEventkInit(tEplSyncCb pfnCbSync_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplEventkAddInstance(pfnCbSync_p);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventkAddInstance
-//
-// Description: function adds one more instance
-//
-// Parameters:  pfnCbSync_p = callback-function for sync event
-//
-// Returns:     tEpKernel   = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
-{
-	tEplKernel Ret;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-	unsigned int fShbNewCreated;
-#endif
-
-	Ret = kEplSuccessful;
-
-	// init instance structure
-	EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
-
-	// save cb-function
-	EplEventkInstance_g.m_pfnCbSync = pfnCbSync_p;
-
-#ifndef EPL_NO_FIFO
-	// init shared loop buffer
-	// kernel -> user
-	ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_KERNEL_TO_USER,
-				     EPL_EVENT_NAME_SHB_KERNEL_TO_USER,
-				     &EplEventkInstance_g.
-				     m_pShbKernelToUserInstance,
-				     &fShbNewCreated);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventkAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-	// user -> kernel
-	ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
-				     EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
-				     &EplEventkInstance_g.
-				     m_pShbUserToKernelInstance,
-				     &fShbNewCreated);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventkAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-	// register eventhandler
-	ShbError =
-	    ShbCirSetSignalHandlerNewData(EplEventkInstance_g.
-					  m_pShbUserToKernelInstance,
-					  EplEventkRxSignalHandlerCb,
-					  kshbPriorityHigh);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventkAddInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-      Exit:
-#endif
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventkDelInstance
-//
-// Description: function deletes instance and frees the buffers
-//
-// Parameters:  void
-//
-// Returns:     tEpKernel   = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplEventkDelInstance(void)
-{
-	tEplKernel Ret;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-#endif
-
-	Ret = kEplSuccessful;
-
-#ifndef EPL_NO_FIFO
-	// set eventhandler to NULL
-	ShbError =
-	    ShbCirSetSignalHandlerNewData(EplEventkInstance_g.
-					  m_pShbUserToKernelInstance, NULL,
-					  kShbPriorityNormal);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventkDelInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-	}
-	// free buffer User -> Kernel
-	ShbError =
-	    ShbCirReleaseBuffer(EplEventkInstance_g.m_pShbUserToKernelInstance);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventkDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-	} else {
-		EplEventkInstance_g.m_pShbUserToKernelInstance = NULL;
-	}
-
-	// free buffer  Kernel -> User
-	ShbError =
-	    ShbCirReleaseBuffer(EplEventkInstance_g.m_pShbKernelToUserInstance);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventkDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-	} else {
-		EplEventkInstance_g.m_pShbKernelToUserInstance = NULL;
-	}
-#endif
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventkProcess
-//
-// Description: Kernelthread that dispatches events in kernel part
-//
-// Parameters:  pEvent_p    = pointer to event-structure from buffer
-//
-// Returns:     tEpKernel   = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplEventkProcess(tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-	tEplEventSource EventSource;
-
-	Ret = kEplSuccessful;
-
-	// error handling if event queue is full
-	if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0) {	// UserToKernel event queue has run out of space -> kEplNmtEventInternComError
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-		tEplEvent Event;
-		tEplNmtEvent NmtEvent;
-#endif
-#ifndef EPL_NO_FIFO
-		tShbError ShbError;
-#endif
-
-		// directly call NMTk process function, because event queue is full
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-		NmtEvent = kEplNmtEventInternComError;
-		Event.m_EventSink = kEplEventSinkNmtk;
-		Event.m_NetTime.m_dwNanoSec = 0;
-		Event.m_NetTime.m_dwSec = 0;
-		Event.m_EventType = kEplEventTypeNmtEvent;
-		Event.m_pArg = &NmtEvent;
-		Event.m_uiSize = sizeof(NmtEvent);
-		Ret = EplNmtkProcess(&Event);
-#endif
-
-		// NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION)
-		// now, it is safe to reset the counter and empty the event queue
-#ifndef EPL_NO_FIFO
-		ShbError =
-		    ShbCirResetBuffer(EplEventkInstance_g.
-				      m_pShbUserToKernelInstance, 1000, NULL);
-#endif
-
-		EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
-		TGT_DBG_SIGNAL_TRACE_POINT(22);
-
-		// also discard the current event (it doesn't matter if we lose another event)
-		goto Exit;
-	}
-	// check m_EventSink
-	switch (pEvent_p->m_EventSink) {
-	case kEplEventSinkSync:
-		{
-			if (EplEventkInstance_g.m_pfnCbSync != NULL) {
-				Ret = EplEventkInstance_g.m_pfnCbSync();
-				if (Ret == kEplSuccessful) {
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-					// mark TPDOs as valid
-					Ret = EplPdokCalSetTpdosValid(TRUE);
-#endif
-				} else if ((Ret != kEplReject)
-					   && (Ret != kEplShutdown)) {
-					EventSource = kEplEventSourceSyncCb;
-
-					// Error event for API layer
-					EplEventkPostError
-					    (kEplEventSourceEventk, Ret,
-					     sizeof(EventSource), &EventSource);
-				}
-			}
-			break;
-		}
-
-		// NMT-Kernel-Modul
-	case kEplEventSinkNmtk:
-		{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-			Ret = EplNmtkProcess(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceNmtk;
-
-				// Error event for API layer
-				EplEventkPostError(kEplEventSourceEventk,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-#endif
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-			if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent)
-			    &&
-			    ((*((tEplNmtEvent *) pEvent_p->m_pArg) ==
-			      kEplNmtEventDllCeSoa)
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			     || (*((tEplNmtEvent *) pEvent_p->m_pArg) ==
-				 kEplNmtEventDllMeSoaSent)
-#endif
-			    )) {	// forward SoA event to error handler
-				Ret = EplErrorHandlerkProcess(pEvent_p);
-				if ((Ret != kEplSuccessful)
-				    && (Ret != kEplShutdown)) {
-					EventSource = kEplEventSourceErrk;
-
-					// Error event for API layer
-					EplEventkPostError
-					    (kEplEventSourceEventk, Ret,
-					     sizeof(EventSource), &EventSource);
-				}
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-				// forward SoA event to PDO module
-				pEvent_p->m_EventType = kEplEventTypePdoSoa;
-				Ret = EplPdokProcess(pEvent_p);
-				if ((Ret != kEplSuccessful)
-				    && (Ret != kEplShutdown)) {
-					EventSource = kEplEventSourcePdok;
-
-					// Error event for API layer
-					EplEventkPostError
-					    (kEplEventSourceEventk, Ret,
-					     sizeof(EventSource), &EventSource);
-				}
-#endif
-
-			}
-			break;
-#endif
-		}
-
-		// events for Dllk module
-	case kEplEventSinkDllk:
-		{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-			Ret = EplDllkProcess(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceDllk;
-
-				// Error event for API layer
-				EplEventkPostError(kEplEventSourceEventk,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-#endif
-			break;
-		}
-
-		// events for DllkCal module
-	case kEplEventSinkDllkCal:
-		{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-			Ret = EplDllkCalProcess(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceDllk;
-
-				// Error event for API layer
-				EplEventkPostError(kEplEventSourceEventk,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-#endif
-			break;
-		}
-
-		//
-	case kEplEventSinkPdok:
-		{
-			// PDO-Module
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-			Ret = EplPdokProcess(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourcePdok;
-
-				// Error event for API layer
-				EplEventkPostError(kEplEventSourceEventk,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-#endif
-			break;
-		}
-
-		// events for Error handler module
-	case kEplEventSinkErrk:
-		{
-			// only call error handler if DLL is present
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-			Ret = EplErrorHandlerkProcess(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceErrk;
-
-				// Error event for API layer
-				EplEventkPostError(kEplEventSourceEventk,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-			break;
-#endif
-		}
-
-		// unknown sink
-	default:
-		{
-			Ret = kEplEventUnknownSink;
-		}
-
-	}			// end of switch(pEvent_p->m_EventSink)
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventkPost
-//
-// Description: post events from kernel part
-//
-// Parameters:  pEvent_p    = pointer to event-structure from buffer
-//
-// Returns:     tEpKernel   = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplEventkPost(tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-	tShbCirChunk ShbCirChunk;
-	unsigned long ulDataSize;
-	unsigned int fBufferCompleted;
-#endif
-
-	Ret = kEplSuccessful;
-
-	// the event must be posted by using the abBuffer
-	// it is neede because the Argument must by copied
-	// to the buffer too and not only the pointer
-
-#ifndef EPL_NO_FIFO
-	// 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
-	ulDataSize =
-	    sizeof(tEplEvent) +
-	    ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
-#endif
-
-	// decide in which buffer the event have to write
-	switch (pEvent_p->m_EventSink) {
-		// kernelspace modules
-	case kEplEventSinkSync:
-	case kEplEventSinkNmtk:
-	case kEplEventSinkDllk:
-	case kEplEventSinkDllkCal:
-	case kEplEventSinkPdok:
-	case kEplEventSinkErrk:
-		{
-#ifndef EPL_NO_FIFO
-			// post message
-			BENCHMARK_MOD_27_SET(2);
-			ShbError =
-			    ShbCirAllocDataBlock(EplEventkInstance_g.
-						 m_pShbUserToKernelInstance,
-						 &ShbCirChunk, ulDataSize);
-			switch (ShbError) {
-			case kShbOk:
-				break;
-
-			case kShbBufferFull:
-				{
-					EplEventkInstance_g.
-					    m_uiUserToKernelFullCount++;
-					Ret = kEplEventPostError;
-					goto Exit;
-				}
-
-			default:
-				{
-					EPL_DBGLVL_EVENTK_TRACE1
-					    ("EplEventkPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n",
-					     ShbError);
-					Ret = kEplEventPostError;
-					goto Exit;
-				}
-			}
-			ShbError =
-			    ShbCirWriteDataChunk(EplEventkInstance_g.
-						 m_pShbUserToKernelInstance,
-						 &ShbCirChunk, pEvent_p,
-						 sizeof(tEplEvent),
-						 &fBufferCompleted);
-			if (ShbError != kShbOk) {
-				EPL_DBGLVL_EVENTK_TRACE1
-				    ("EplEventkPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n",
-				     ShbError);
-				Ret = kEplEventPostError;
-				goto Exit;
-			}
-			if (fBufferCompleted == FALSE) {
-				ShbError =
-				    ShbCirWriteDataChunk(EplEventkInstance_g.
-							 m_pShbUserToKernelInstance,
-							 &ShbCirChunk,
-							 pEvent_p->m_pArg,
-							 (unsigned long)
-							 pEvent_p->m_uiSize,
-							 &fBufferCompleted);
-				if ((ShbError != kShbOk)
-				    || (fBufferCompleted == FALSE)) {
-					EPL_DBGLVL_EVENTK_TRACE1
-					    ("EplEventkPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n",
-					     ShbError);
-					Ret = kEplEventPostError;
-					goto Exit;
-				}
-			}
-			BENCHMARK_MOD_27_RESET(2);
-
-#else
-			Ret = EplEventkProcess(pEvent_p);
-#endif
-
-			break;
-		}
-
-		// userspace modules
-	case kEplEventSinkNmtu:
-	case kEplEventSinkNmtMnu:
-	case kEplEventSinkSdoAsySeq:
-	case kEplEventSinkApi:
-	case kEplEventSinkDlluCal:
-	case kEplEventSinkErru:
-		{
-#ifndef EPL_NO_FIFO
-			// post message
-//            BENCHMARK_MOD_27_SET(3);    // 74 µs until reset
-			ShbError =
-			    ShbCirAllocDataBlock(EplEventkInstance_g.
-						 m_pShbKernelToUserInstance,
-						 &ShbCirChunk, ulDataSize);
-			if (ShbError != kShbOk) {
-				EPL_DBGLVL_EVENTK_TRACE1
-				    ("EplEventkPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n",
-				     ShbError);
-				Ret = kEplEventPostError;
-				goto Exit;
-			}
-			ShbError =
-			    ShbCirWriteDataChunk(EplEventkInstance_g.
-						 m_pShbKernelToUserInstance,
-						 &ShbCirChunk, pEvent_p,
-						 sizeof(tEplEvent),
-						 &fBufferCompleted);
-			if (ShbError != kShbOk) {
-				EPL_DBGLVL_EVENTK_TRACE1
-				    ("EplEventkPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n",
-				     ShbError);
-				Ret = kEplEventPostError;
-				goto Exit;
-			}
-			if (fBufferCompleted == FALSE) {
-				ShbError =
-				    ShbCirWriteDataChunk(EplEventkInstance_g.
-							 m_pShbKernelToUserInstance,
-							 &ShbCirChunk,
-							 pEvent_p->m_pArg,
-							 (unsigned long)
-							 pEvent_p->m_uiSize,
-							 &fBufferCompleted);
-				if ((ShbError != kShbOk)
-				    || (fBufferCompleted == FALSE)) {
-					EPL_DBGLVL_EVENTK_TRACE1
-					    ("EplEventkPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n",
-					     ShbError);
-					Ret = kEplEventPostError;
-					goto Exit;
-				}
-			}
-//            BENCHMARK_MOD_27_RESET(3);  // 82 µs until ShbCirGetReadDataSize() in EplEventu
-
-#else
-			Ret = EplEventuProcess(pEvent_p);
-#endif
-
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplEventUnknownSink;
-		}
-
-	}			// end of switch(pEvent_p->m_EventSink)
-
-#ifndef EPL_NO_FIFO
-      Exit:
-#endif
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventkPostError
-//
-// Description: post error event from kernel part to API layer
-//
-// Parameters:  EventSource_p   = source-module of the error event
-//              EplError_p      = code of occured error
-//              ArgSize_p       = size of the argument
-//              pArg_p          = pointer to the argument
-//
-// Returns:     tEpKernel       = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
-			      tEplKernel EplError_p,
-			      unsigned int uiArgSize_p, void *pArg_p)
-{
-	tEplKernel Ret;
-	u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
-	tEplEventError *pEventError = (tEplEventError *) abBuffer;
-	tEplEvent EplEvent;
-
-	Ret = kEplSuccessful;
-
-	// create argument
-	pEventError->m_EventSource = EventSource_p;
-	pEventError->m_EplError = EplError_p;
-	EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
-
-	// create event
-	EplEvent.m_EventType = kEplEventTypeError;
-	EplEvent.m_EventSink = kEplEventSinkApi;
-	EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
-	EplEvent.m_uiSize =
-	    (sizeof(EventSource_p) + sizeof(EplError_p) + uiArgSize_p);
-	EplEvent.m_pArg = &abBuffer[0];
-
-	// post errorevent
-	Ret = EplEventkPost(&EplEvent);
-
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventkRxSignalHandlerCb()
-//
-// Description: Callback-function for events from user and kernel part
-//
-// Parameters:  pShbRxInstance_p    = Instance-pointer of buffer
-//              ulDataSize_p        = size of data
-//
-// Returns: void
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#ifndef EPL_NO_FIFO
-static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
-				       unsigned long ulDataSize_p)
-{
-	tEplEvent *pEplEvent;
-	tShbError ShbError;
-//unsigned long   ulBlockCount;
-//unsigned long   ulDataSize;
-	u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
-	// d.k.: abDataBuffer contains the complete tEplEvent structure
-	//       and behind this the argument
-
-	TGT_DBG_SIGNAL_TRACE_POINT(20);
-
-	BENCHMARK_MOD_27_RESET(0);
-	// copy data from event queue
-	ShbError = ShbCirReadDataBlock(pShbRxInstance_p,
-				       &abDataBuffer[0],
-				       sizeof(abDataBuffer), &ulDataSize_p);
-	if (ShbError != kShbOk) {
-		// error goto exit
-		goto Exit;
-	}
-	// resolve the pointer to the event structure
-	pEplEvent = (tEplEvent *) abDataBuffer;
-	// set Datasize
-	pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
-	if (pEplEvent->m_uiSize > 0) {
-		// set pointer to argument
-		pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
-	} else {
-		//set pointer to NULL
-		pEplEvent->m_pArg = NULL;
-	}
-
-	BENCHMARK_MOD_27_SET(0);
-	// call processfunction
-	EplEventkProcess(pEplEvent);
-
-      Exit:
-	return;
-}
-#endif
-
-// EOF
diff --git a/drivers/staging/epl/EplEventu.c b/drivers/staging/epl/EplEventu.c
deleted file mode 100644
index 3ae2841..0000000
--- a/drivers/staging/epl/EplEventu.c
+++ /dev/null
@@ -1,813 +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-Event-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: EplEventu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/20 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplEventu.h"
-#include "user/EplNmtu.h"
-#include "user/EplNmtMnu.h"
-#include "user/EplSdoAsySequ.h"
-#include "user/EplDlluCal.h"
-#include "user/EplLedu.h"
-#include "Benchmark.h"
-
-#ifdef EPL_NO_FIFO
-#include "kernel/EplEventk.h"
-#else
-#include "SharedBuff.h"
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-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
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-#ifndef EPL_NO_FIFO
-	tShbInstance m_pShbKernelToUserInstance;
-	tShbInstance m_pShbUserToKernelInstance;
-#endif
-	tEplProcessEventCb m_pfnApiProcessEventCb;
-
-} tEplEventuInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//#ifndef EPL_NO_FIFO
-static tEplEventuInstance EplEventuInstance_g;
-//#endif
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-#ifndef EPL_NO_FIFO
-// callback function for incomming events
-static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
-				       unsigned long ulDataSize_p);
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <Epl-User-Event>                                    */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventuInit
-//
-// Description: function initialize the first instance
-//
-//
-//
-// Parameters:  pfnApiProcessEventCb_p  = function pointer for API event callback
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplEventuAddInstance(pfnApiProcessEventCb_p);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventuAddInstance
-//
-// Description: function add one more instance
-//
-//
-//
-// Parameters:  pfnApiProcessEventCb_p  = function pointer for API event callback
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p)
-{
-	tEplKernel Ret;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-	unsigned int fShbNewCreated;
-#endif
-
-	Ret = kEplSuccessful;
-
-	// init instance variables
-	EplEventuInstance_g.m_pfnApiProcessEventCb = pfnApiProcessEventCb_p;
-
-#ifndef EPL_NO_FIFO
-	// init shared loop buffer
-	// kernel -> user
-	ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_KERNEL_TO_USER,
-				     EPL_EVENT_NAME_SHB_KERNEL_TO_USER,
-				     &EplEventuInstance_g.
-				     m_pShbKernelToUserInstance,
-				     &fShbNewCreated);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventuAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-	// user -> kernel
-	ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
-				     EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
-				     &EplEventuInstance_g.
-				     m_pShbUserToKernelInstance,
-				     &fShbNewCreated);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventuAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-	// register eventhandler
-	ShbError =
-	    ShbCirSetSignalHandlerNewData(EplEventuInstance_g.
-					  m_pShbKernelToUserInstance,
-					  EplEventuRxSignalHandlerCb,
-					  kShbPriorityNormal);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventuAddInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-      Exit:
-#endif
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventuDelInstance
-//
-// Description: function delete instance an free the bufferstructure
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplEventuDelInstance(void)
-{
-	tEplKernel Ret;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-#endif
-
-	Ret = kEplSuccessful;
-
-#ifndef EPL_NO_FIFO
-	// set eventhandler to NULL
-	ShbError =
-	    ShbCirSetSignalHandlerNewData(EplEventuInstance_g.
-					  m_pShbKernelToUserInstance, NULL,
-					  kShbPriorityNormal);
-	if (ShbError != kShbOk) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventuDelInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-	}
-	// free buffer User -> Kernel
-	ShbError =
-	    ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbUserToKernelInstance);
-	if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventuDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-	} else {
-		EplEventuInstance_g.m_pShbUserToKernelInstance = NULL;
-	}
-
-	// free buffer  Kernel -> User
-	ShbError =
-	    ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbKernelToUserInstance);
-	if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) {
-		EPL_DBGLVL_EVENTK_TRACE1
-		    ("EplEventuDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n",
-		     ShbError);
-		Ret = kEplNoResource;
-	} else {
-		EplEventuInstance_g.m_pShbKernelToUserInstance = NULL;
-	}
-
-#endif
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventuProcess
-//
-// Description: Kernelthread that dispatches events in kernelspace
-//
-//
-//
-// Parameters:  pEvent_p = pointer to event-structur from buffer
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplEventuProcess(tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-	tEplEventSource EventSource;
-
-	Ret = kEplSuccessful;
-
-	// check m_EventSink
-	switch (pEvent_p->m_EventSink) {
-		// NMT-User-Module
-	case kEplEventSinkNmtu:
-		{
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-			Ret = EplNmtuProcessEvent(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceNmtu;
-
-				// Error event for API layer
-				EplEventuPostError(kEplEventSourceEventu,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-#endif
-			break;
-		}
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-		// NMT-MN-User-Module
-	case kEplEventSinkNmtMnu:
-		{
-			Ret = EplNmtMnuProcessEvent(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceNmtMnu;
-
-				// Error event for API layer
-				EplEventuPostError(kEplEventSourceEventu,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-			break;
-		}
-#endif
-
-#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)   \
-     || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0))
-		// events for asynchronus SDO Sequence Layer
-	case kEplEventSinkSdoAsySeq:
-		{
-			Ret = EplSdoAsySeqProcessEvent(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceSdoAsySeq;
-
-				// Error event for API layer
-				EplEventuPostError(kEplEventSourceEventu,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-			break;
-		}
-#endif
-
-		// LED user part module
-	case kEplEventSinkLedu:
-		{
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-			Ret = EplLeduProcessEvent(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceLedu;
-
-				// Error event for API layer
-				EplEventuPostError(kEplEventSourceEventu,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-#endif
-			break;
-		}
-
-		// event for EPL api
-	case kEplEventSinkApi:
-		{
-			if (EplEventuInstance_g.m_pfnApiProcessEventCb != NULL) {
-				Ret =
-				    EplEventuInstance_g.
-				    m_pfnApiProcessEventCb(pEvent_p);
-				if ((Ret != kEplSuccessful)
-				    && (Ret != kEplShutdown)) {
-					EventSource = kEplEventSourceEplApi;
-
-					// Error event for API layer
-					EplEventuPostError
-					    (kEplEventSourceEventu, Ret,
-					     sizeof(EventSource), &EventSource);
-				}
-			}
-			break;
-
-		}
-
-	case kEplEventSinkDlluCal:
-		{
-			Ret = EplDlluCalProcess(pEvent_p);
-			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
-				EventSource = kEplEventSourceDllu;
-
-				// Error event for API layer
-				EplEventuPostError(kEplEventSourceEventu,
-						   Ret,
-						   sizeof(EventSource),
-						   &EventSource);
-			}
-			break;
-
-		}
-
-	case kEplEventSinkErru:
-		{
-			/*
-			   Ret = EplErruProcess(pEvent_p);
-			   if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
-			   {
-			   EventSource = kEplEventSourceErru;
-
-			   // Error event for API layer
-			   EplEventuPostError(kEplEventSourceEventu,
-			   Ret,
-			   sizeof(EventSource),
-			   &EventSource);
-			   }
-			 */
-			break;
-
-		}
-
-		// unknown sink
-	default:
-		{
-			Ret = kEplEventUnknownSink;
-		}
-
-	}			// end of switch(pEvent_p->m_EventSink)
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventuPost
-//
-// Description: post events from userspace
-//
-//
-//
-// Parameters:  pEvent_p = pointer to event-structur from buffer
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplEventuPost(tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-#ifndef EPL_NO_FIFO
-	tShbError ShbError;
-	tShbCirChunk ShbCirChunk;
-	unsigned long ulDataSize;
-	unsigned int fBufferCompleted;
-#endif
-
-	Ret = kEplSuccessful;
-
-#ifndef EPL_NO_FIFO
-	// 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
-	ulDataSize =
-	    sizeof(tEplEvent) +
-	    ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
-#endif
-
-	// decide in which buffer the event have to write
-	switch (pEvent_p->m_EventSink) {
-		// kernelspace modules
-	case kEplEventSinkSync:
-	case kEplEventSinkNmtk:
-	case kEplEventSinkDllk:
-	case kEplEventSinkDllkCal:
-	case kEplEventSinkPdok:
-	case kEplEventSinkErrk:
-		{
-#ifndef EPL_NO_FIFO
-			// post message
-			ShbError =
-			    ShbCirAllocDataBlock(EplEventuInstance_g.
-						 m_pShbUserToKernelInstance,
-						 &ShbCirChunk, ulDataSize);
-			if (ShbError != kShbOk) {
-				EPL_DBGLVL_EVENTK_TRACE1
-				    ("EplEventuPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n",
-				     ShbError);
-				Ret = kEplEventPostError;
-				goto Exit;
-			}
-			ShbError =
-			    ShbCirWriteDataChunk(EplEventuInstance_g.
-						 m_pShbUserToKernelInstance,
-						 &ShbCirChunk, pEvent_p,
-						 sizeof(tEplEvent),
-						 &fBufferCompleted);
-			if (ShbError != kShbOk) {
-				EPL_DBGLVL_EVENTK_TRACE1
-				    ("EplEventuPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n",
-				     ShbError);
-				Ret = kEplEventPostError;
-				goto Exit;
-			}
-			if (fBufferCompleted == FALSE) {
-				ShbError =
-				    ShbCirWriteDataChunk(EplEventuInstance_g.
-							 m_pShbUserToKernelInstance,
-							 &ShbCirChunk,
-							 pEvent_p->m_pArg,
-							 (unsigned long)
-							 pEvent_p->m_uiSize,
-							 &fBufferCompleted);
-				if ((ShbError != kShbOk)
-				    || (fBufferCompleted == FALSE)) {
-					EPL_DBGLVL_EVENTK_TRACE1
-					    ("EplEventuPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n",
-					     ShbError);
-					Ret = kEplEventPostError;
-					goto Exit;
-				}
-			}
-#else
-			Ret = EplEventkProcess(pEvent_p);
-#endif
-
-			break;
-		}
-
-		// userspace modules
-	case kEplEventSinkNmtMnu:
-	case kEplEventSinkNmtu:
-	case kEplEventSinkSdoAsySeq:
-	case kEplEventSinkApi:
-	case kEplEventSinkDlluCal:
-	case kEplEventSinkErru:
-	case kEplEventSinkLedu:
-		{
-#ifndef EPL_NO_FIFO
-			// post message
-			ShbError =
-			    ShbCirAllocDataBlock(EplEventuInstance_g.
-						 m_pShbKernelToUserInstance,
-						 &ShbCirChunk, ulDataSize);
-			if (ShbError != kShbOk) {
-				EPL_DBGLVL_EVENTK_TRACE1
-				    ("EplEventuPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n",
-				     ShbError);
-				Ret = kEplEventPostError;
-				goto Exit;
-			}
-			ShbError =
-			    ShbCirWriteDataChunk(EplEventuInstance_g.
-						 m_pShbKernelToUserInstance,
-						 &ShbCirChunk, pEvent_p,
-						 sizeof(tEplEvent),
-						 &fBufferCompleted);
-			if (ShbError != kShbOk) {
-				EPL_DBGLVL_EVENTK_TRACE1
-				    ("EplEventuPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n",
-				     ShbError);
-				Ret = kEplEventPostError;
-				goto Exit;
-			}
-			if (fBufferCompleted == FALSE) {
-				ShbError =
-				    ShbCirWriteDataChunk(EplEventuInstance_g.
-							 m_pShbKernelToUserInstance,
-							 &ShbCirChunk,
-							 pEvent_p->m_pArg,
-							 (unsigned long)
-							 pEvent_p->m_uiSize,
-							 &fBufferCompleted);
-				if ((ShbError != kShbOk)
-				    || (fBufferCompleted == FALSE)) {
-					EPL_DBGLVL_EVENTK_TRACE1
-					    ("EplEventuPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n",
-					     ShbError);
-					Ret = kEplEventPostError;
-					goto Exit;
-				}
-			}
-#else
-			Ret = EplEventuProcess(pEvent_p);
-#endif
-
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplEventUnknownSink;
-		}
-
-	}			// end of switch(pEvent_p->m_EventSink)
-
-#ifndef EPL_NO_FIFO
-      Exit:
-#endif
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventuPostError
-//
-// Description: post errorevent from userspace
-//
-//
-//
-// Parameters:  EventSource_p   = source-module of the errorevent
-//              EplError_p     = code of occured error
-//              uiArgSize_p     = size of the argument
-//              pArg_p          = pointer to the argument
-//
-//
-// Returns:      tEpKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
-			      tEplKernel EplError_p,
-			      unsigned int uiArgSize_p, void *pArg_p)
-{
-	tEplKernel Ret;
-	u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
-	tEplEventError *pEventError = (tEplEventError *) abBuffer;
-	tEplEvent EplEvent;
-
-	Ret = kEplSuccessful;
-
-	// create argument
-	pEventError->m_EventSource = EventSource_p;
-	pEventError->m_EplError = EplError_p;
-	EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
-
-	// create event
-	EplEvent.m_EventType = kEplEventTypeError;
-	EplEvent.m_EventSink = kEplEventSinkApi;
-	EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
-	EplEvent.m_uiSize =
-	    (sizeof(EventSource_p) + sizeof(EplError_p) + uiArgSize_p);
-	EplEvent.m_pArg = &abBuffer[0];
-
-	// post errorevent
-	Ret = EplEventuPost(&EplEvent);
-
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEventuRxSignalHandlerCb()
-//
-// Description: Callback-function for evets from kernelspace
-//
-//
-//
-// Parameters:  pShbRxInstance_p    = Instance-pointer for buffer
-//              ulDataSize_p        = size of data
-//
-//
-// Returns: void
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#ifndef EPL_NO_FIFO
-static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
-				       unsigned long ulDataSize_p)
-{
-	tEplEvent *pEplEvent;
-	tShbError ShbError;
-//unsigned long   ulBlockCount;
-//unsigned long   ulDataSize;
-	u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
-	// d.k.: abDataBuffer contains the complete tEplEvent structure
-	//       and behind this the argument
-
-	TGT_DBG_SIGNAL_TRACE_POINT(21);
-
-// d.k. not needed because it is already done in SharedBuff
-/*    do
-    {
-        BENCHMARK_MOD_28_SET(1);    // 4 µs until reset
-        // get messagesize
-        ShbError = ShbCirGetReadDataSize (pShbRxInstance_p, &ulDataSize);
-        if(ShbError != kShbOk)
-        {
-            // error goto exit
-            goto Exit;
-        }
-
-        BENCHMARK_MOD_28_RESET(1);  // 14 µs until set
-*/
-	// copy data from event queue
-	ShbError = ShbCirReadDataBlock(pShbRxInstance_p,
-				       &abDataBuffer[0],
-				       sizeof(abDataBuffer), &ulDataSize_p);
-	if (ShbError != kShbOk) {
-		// error goto exit
-		goto Exit;
-	}
-	// resolve the pointer to the event structure
-	pEplEvent = (tEplEvent *) abDataBuffer;
-	// set Datasize
-	pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
-	if (pEplEvent->m_uiSize > 0) {
-		// set pointer to argument
-		pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
-	} else {
-		//set pointer to NULL
-		pEplEvent->m_pArg = NULL;
-	}
-
-	BENCHMARK_MOD_28_SET(1);
-	// call processfunction
-	EplEventuProcess(pEplEvent);
-
-	BENCHMARK_MOD_28_RESET(1);
-	// read number of left messages to process
-// d.k. not needed because it is already done in SharedBuff
-/*        ShbError = ShbCirGetReadBlockCount (pShbRxInstance_p, &ulBlockCount);
-        if (ShbError != kShbOk)
-        {
-            // error goto exit
-            goto Exit;
-        }
-    } while (ulBlockCount > 0);
-*/
-      Exit:
-	return;
-}
-#endif
-
-// EOF
diff --git a/drivers/staging/epl/EplFrame.h b/drivers/staging/epl/EplFrame.h
deleted file mode 100644
index ba1ae9e..0000000
--- a/drivers/staging/epl/EplFrame.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for EPL frames
-
-  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: EplFrame.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/06/23 14:56:33 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_FRAME_H_
-#define _EPL_FRAME_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// defines for EplFrame.m_wFlag
-#define EPL_FRAME_FLAG1_RD          0x01	// ready                                    (PReq, PRes)
-#define EPL_FRAME_FLAG1_ER          0x02	// exception reset (error signalling)       (SoA)
-#define EPL_FRAME_FLAG1_EA          0x04	// exception acknowledge (error signalling) (PReq, SoA)
-#define EPL_FRAME_FLAG1_EC          0x08	// exception clear (error signalling)       (StatusRes)
-#define EPL_FRAME_FLAG1_EN          0x10	// exception new (error signalling)         (PRes, StatusRes)
-#define EPL_FRAME_FLAG1_MS          0x20	// multiplexed slot                         (PReq)
-#define EPL_FRAME_FLAG1_PS          0x40	// prescaled slot                           (SoC)
-#define EPL_FRAME_FLAG1_MC          0x80	// multiplexed cycle completed              (SoC)
-#define EPL_FRAME_FLAG2_RS          0x07	// number of pending requests to send       (PRes, StatusRes, IdentRes)
-#define EPL_FRAME_FLAG2_PR          0x38	// priority of requested asynch. frame      (PRes, StatusRes, IdentRes)
-#define EPL_FRAME_FLAG2_PR_SHIFT    3	// shift of priority of requested asynch. frame
-
-// error history/status entry types
-#define EPL_ERR_ENTRYTYPE_STATUS        0x8000
-#define EPL_ERR_ENTRYTYPE_HISTORY       0x0000
-#define EPL_ERR_ENTRYTYPE_EMCY          0x4000
-#define EPL_ERR_ENTRYTYPE_MODE_ACTIVE   0x1000
-#define EPL_ERR_ENTRYTYPE_MODE_CLEARED  0x2000
-#define EPL_ERR_ENTRYTYPE_MODE_OCCURRED 0x3000
-#define EPL_ERR_ENTRYTYPE_MODE_MASK     0x3000
-#define EPL_ERR_ENTRYTYPE_PROF_VENDOR   0x0001
-#define EPL_ERR_ENTRYTYPE_PROF_EPL      0x0002
-#define EPL_ERR_ENTRYTYPE_PROF_MASK     0x0FFF
-
-// defines for EPL version / PDO version
-#define EPL_VERSION_SUB             0x0F	// sub version
-#define EPL_VERSION_MAIN            0xF0	// main version
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-// $$$ d.k.: move this definition to global.h
-// byte-align structures
-#ifdef _MSC_VER
-#    pragma pack( push, packing )
-#    pragma pack( 1 )
-#    define PACK_STRUCT
-#elif defined( __GNUC__ )
-#    define PACK_STRUCT    __attribute__((packed))
-#else
-#    error you must byte-align these structures with the appropriate compiler directives
-#endif
-
-typedef struct {
-	// Offset 17
-	u8 m_le_bRes1;	// reserved
-	// Offset 18
-	u8 m_le_bFlag1;	// Flags: MC, PS
-	// Offset 19
-	u8 m_le_bFlag2;	// Flags: res
-	// Offset 20
-	tEplNetTime m_le_NetTime;	// supported if D_NMT_NetTimeIsRealTime_BOOL is set
-	// Offset 28
-	u64 m_le_RelativeTime;	// in us (supported if D_NMT_RelativeTime_BOOL is set)
-
-} PACK_STRUCT tEplSocFrame;
-
-typedef struct {
-	// Offset 17
-	u8 m_le_bRes1;	// reserved
-	// Offset 18
-	u8 m_le_bFlag1;	// Flags: MS, EA, RD
-	// Offset 19
-	u8 m_le_bFlag2;	// Flags: res
-	// Offset 20
-	u8 m_le_bPdoVersion;
-	// Offset 21
-	u8 m_le_bRes2;	// reserved
-	// Offset 22
-	u16 m_le_wSize;
-	// Offset 24
-	u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ];
-
-} PACK_STRUCT tEplPreqFrame;
-
-typedef struct {
-	// Offset 17
-	u8 m_le_bNmtStatus;	// NMT state
-	// Offset 18
-	u8 m_le_bFlag1;	// Flags: MS, EN, RD
-	// Offset 19
-	u8 m_le_bFlag2;	// Flags: PR, RS
-	// Offset 20
-	u8 m_le_bPdoVersion;
-	// Offset 21
-	u8 m_le_bRes2;	// reserved
-	// Offset 22
-	u16 m_le_wSize;
-	// Offset 24
-	u8 m_le_abPayload[256	/*D_NMT_IsochrRxMaxPayload_U16
-				   / D_NMT_IsochrTxMaxPayload_U16 */ ];
-
-} PACK_STRUCT tEplPresFrame;
-
-typedef struct {
-	// Offset 17
-	u8 m_le_bNmtStatus;	// NMT state
-	// Offset 18
-	u8 m_le_bFlag1;	// Flags: EA, ER
-	// Offset 19
-	u8 m_le_bFlag2;	// Flags: res
-	// Offset 20
-	u8 m_le_bReqServiceId;
-	// Offset 21
-	u8 m_le_bReqServiceTarget;
-	// Offset 22
-	u8 m_le_bEplVersion;
-
-} PACK_STRUCT tEplSoaFrame;
-
-typedef struct {
-	u16 m_wEntryType;
-	u16 m_wErrorCode;
-	tEplNetTime m_TimeStamp;
-	u8 m_abAddInfo[8];
-
-} PACK_STRUCT tEplErrHistoryEntry;
-
-typedef struct {
-	// Offset 18
-	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
-	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
-	u8 m_le_bNmtCommandId;
-	u8 m_le_bRes1;
-	u8 m_le_abNmtCommandData[32];
-
-} PACK_STRUCT tEplNmtCommandService;
-
-typedef struct {
-	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 {
-	u8 m_le_bRecSeqNumCon;
-	u8 m_le_bSendSeqNumCon;
-	u8 m_le_abReserved[2];
-	tEplAsySdoCom m_le_abSdoSeqPayload;
-
-} PACK_STRUCT tEplAsySdoSeq;
-
-typedef struct {
-	// Offset 18
-	u8 m_le_bNmtCommandId;
-	u8 m_le_bTargetNodeId;
-	u8 m_le_abNmtCommandData[32];
-
-} PACK_STRUCT tEplNmtRequestService;
-
-typedef union {
-	// Offset 18
-	tEplStatusResponse m_StatusResponse;
-	tEplIdentResponse m_IdentResponse;
-	tEplNmtCommandService m_NmtCommandService;
-	tEplNmtRequestService m_NmtRequestService;
-	tEplAsySdoSeq m_SdoSequenceFrame;
-	u8 m_le_abPayload[256	/*D_NMT_ASndTxMaxPayload_U16
-				   / D_NMT_ASndRxMaxPayload_U16 */ ];
-
-} tEplAsndPayload;
-
-typedef struct {
-	// Offset 17
-	u8 m_le_bServiceId;
-	// Offset 18
-	tEplAsndPayload m_Payload;
-
-} PACK_STRUCT tEplAsndFrame;
-
-typedef union {
-	// Offset 17
-	tEplSocFrame m_Soc;
-	tEplPreqFrame m_Preq;
-	tEplPresFrame m_Pres;
-	tEplSoaFrame m_Soa;
-	tEplAsndFrame m_Asnd;
-
-} tEplFrameData;
-
-typedef struct {
-	// Offset 0
-	u8 m_be_abDstMac[6];	// MAC address of the addressed nodes
-	// Offset 6
-	u8 m_be_abSrcMac[6];	// MAC address of the transmitting node
-	// Offset 12
-	u16 m_be_wEtherType;	// Ethernet message type (big endian)
-	// Offset 14
-	u8 m_le_bMessageType;	// EPL message type
-	// Offset 15
-	u8 m_le_bDstNodeId;	// EPL node ID of the addressed nodes
-	// Offset 16
-	u8 m_le_bSrcNodeId;	// EPL node ID of the transmitting node
-	// Offset 17
-	tEplFrameData m_Data;
-
-} PACK_STRUCT tEplFrame;
-
-// un-byte-align structures
-#ifdef _MSC_VER
-#    pragma pack( pop, packing )
-#endif
-
-typedef enum {
-	kEplMsgTypeNonEpl = 0x00,
-	kEplMsgTypeSoc = 0x01,
-	kEplMsgTypePreq = 0x03,
-	kEplMsgTypePres = 0x04,
-	kEplMsgTypeSoa = 0x05,
-	kEplMsgTypeAsnd = 0x06,
-
-} tEplMsgType;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_FRAME_H_
diff --git a/drivers/staging/epl/EplIdentu.c b/drivers/staging/epl/EplIdentu.c
deleted file mode 100644
index 93d5a40..0000000
--- a/drivers/staging/epl/EplIdentu.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for Identu-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: EplIdentu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/11/21 09:00:38 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/11/15 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplIdentu.h"
-#include "user/EplDlluCal.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  <xxxxx>                                             */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	tEplIdentResponse *m_apIdentResponse[254];	// the IdentResponse are managed dynamically
-	tEplIdentuCbResponse m_apfnCbResponse[254];
-
-} tEplIdentuInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplIdentuInstance EplIdentuInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuInit
-//
-// Description: init first instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplIdentuInit(void)
-{
-	tEplKernel Ret;
-
-	Ret = EplIdentuAddInstance();
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuAddInstance
-//
-// Description: init other instances of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplIdentuAddInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// reset instance structure
-	EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof(EplIdentuInstance_g));
-
-	// register IdentResponse callback function
-	Ret =
-	    EplDlluCalRegAsndService(kEplDllAsndIdentResponse,
-				     EplIdentuCbIdentResponse,
-				     kEplDllAsndFilterAny);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuDelInstance
-//
-// Description: delete instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplIdentuDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// deregister IdentResponse callback function
-	Ret =
-	    EplDlluCalRegAsndService(kEplDllAsndIdentResponse, NULL,
-				     kEplDllAsndFilterNone);
-
-	Ret = EplIdentuReset();
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuReset
-//
-// Description: resets this instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplIdentuReset(void)
-{
-	tEplKernel Ret;
-	int iIndex;
-
-	Ret = kEplSuccessful;
-
-	for (iIndex = 0;
-	     iIndex < tabentries(EplIdentuInstance_g.m_apIdentResponse);
-	     iIndex++) {
-		if (EplIdentuInstance_g.m_apIdentResponse[iIndex] != NULL) {	// free memory
-			EPL_FREE(EplIdentuInstance_g.m_apIdentResponse[iIndex]);
-		}
-	}
-
-	EPL_MEMSET(&EplIdentuInstance_g, 0, sizeof(EplIdentuInstance_g));
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuGetIdentResponse
-//
-// Description: returns the IdentResponse for the specified node.
-//
-// Parameters:  uiNodeId_p                  = IN: node ID
-//              ppIdentResponse_p           = OUT: pointer to pointer of IdentResponse
-//                                            equals NULL, if no IdentResponse available
-//
-// Return:      tEplKernel                  = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
-				     tEplIdentResponse **ppIdentResponse_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// decrement node ID, because array is zero based
-	uiNodeId_p--;
-	if (uiNodeId_p < tabentries(EplIdentuInstance_g.m_apIdentResponse)) {
-		*ppIdentResponse_p =
-		    EplIdentuInstance_g.m_apIdentResponse[uiNodeId_p];
-	} else {		// invalid node ID specified
-		*ppIdentResponse_p = NULL;
-		Ret = kEplInvalidNodeId;
-	}
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuRequestIdentResponse
-//
-// Description: returns the IdentResponse for the specified node.
-//
-// Parameters:  uiNodeId_p                  = IN: node ID
-//              pfnCbResponse_p             = IN: function pointer to callback function
-//                                            which will be called if IdentResponse is received
-//
-// Return:      tEplKernel                  = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
-					 tEplIdentuCbResponse pfnCbResponse_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// decrement node ID, because array is zero based
-	uiNodeId_p--;
-	if (uiNodeId_p < tabentries(EplIdentuInstance_g.m_apfnCbResponse)) {
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-		if (EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL) {	// request already issued (maybe by someone else)
-			Ret = kEplInvalidOperation;
-		} else {
-			EplIdentuInstance_g.m_apfnCbResponse[uiNodeId_p] =
-			    pfnCbResponse_p;
-			Ret =
-			    EplDlluCalIssueRequest(kEplDllReqServiceIdent,
-						   (uiNodeId_p + 1), 0xFF);
-		}
-#else
-		Ret = kEplInvalidOperation;
-#endif
-	} else {		// invalid node ID specified
-		Ret = kEplInvalidNodeId;
-	}
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuGetRunningRequests
-//
-// Description: returns a bit field with the running requests for node-ID 1-32
-//              just for debugging purposes
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-u32 EplIdentuGetRunningRequests(void)
-{
-	u32 dwReqs = 0;
-	unsigned int uiIndex;
-
-	for (uiIndex = 0; uiIndex < 32; uiIndex++) {
-		if (EplIdentuInstance_g.m_apfnCbResponse[uiIndex] != NULL) {
-			dwReqs |= (1 << uiIndex);
-		}
-	}
-
-	return dwReqs;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplIdentuCbIdentResponse
-//
-// Description: callback funktion for IdentResponse
-//
-//
-//
-// Parameters:  pFrameInfo_p            = Frame with the IdentResponse
-//
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiNodeId;
-	unsigned int uiIndex;
-	tEplIdentuCbResponse pfnCbResponse;
-
-	uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId);
-
-	uiIndex = uiNodeId - 1;
-
-	if (uiIndex < tabentries(EplIdentuInstance_g.m_apfnCbResponse)) {
-		// memorize pointer to callback function
-		pfnCbResponse = EplIdentuInstance_g.m_apfnCbResponse[uiIndex];
-		// reset callback function pointer so that caller may issue next request immediately
-		EplIdentuInstance_g.m_apfnCbResponse[uiIndex] = NULL;
-
-		if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_IDENTRES) {	// IdentResponse not received or it has invalid size
-			if (pfnCbResponse == NULL) {	// response was not requested
-				goto Exit;
-			}
-			Ret = pfnCbResponse(uiNodeId, NULL);
-		} else {	// IdentResponse received
-			if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) {	// memory for IdentResponse must be allocated
-				EplIdentuInstance_g.m_apIdentResponse[uiIndex] =
-				    EPL_MALLOC(sizeof(tEplIdentResponse));
-				if (EplIdentuInstance_g.m_apIdentResponse[uiIndex] == NULL) {	// malloc failed
-					if (pfnCbResponse == NULL) {	// response was not requested
-						goto Exit;
-					}
-					Ret =
-					    pfnCbResponse(uiNodeId,
-							  &pFrameInfo_p->
-							  m_pFrame->m_Data.
-							  m_Asnd.m_Payload.
-							  m_IdentResponse);
-					goto Exit;
-				}
-			}
-			// copy IdentResponse to instance structure
-			EPL_MEMCPY(EplIdentuInstance_g.
-				   m_apIdentResponse[uiIndex],
-				   &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.
-				   m_Payload.m_IdentResponse,
-				   sizeof(tEplIdentResponse));
-			if (pfnCbResponse == NULL) {	// response was not requested
-				goto Exit;
-			}
-			Ret =
-			    pfnCbResponse(uiNodeId,
-					  EplIdentuInstance_g.
-					  m_apIdentResponse[uiIndex]);
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-// EOF
diff --git a/drivers/staging/epl/EplInc.h b/drivers/staging/epl/EplInc.h
deleted file mode 100644
index f91797a..0000000
--- a/drivers/staging/epl/EplInc.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  basic include file for internal EPL stack modules
-
-  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: EplInc.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/11/17 16:40:39 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_INC_H_
-#define _EPL_INC_H_
-
-// ============================================================================
-// include files
-// ============================================================================
-#if defined(WIN32) || defined(_WIN32)
-
-#ifdef UNDER_RTSS
-	// RTX header
-#include <windows.h>
-#include <process.h>
-#include <rtapi.h>
-
-#elif __BORLANDC__
-	// borland C header
-#include <windows.h>
-#include <process.h>
-
-#elif WINCE
-#include <windows.h>
-
-#else
-	// MSVC needs to include windows.h at first
-	// the following defines ar necessary for function prototypes for waitable timers
-#define _WIN32_WINDOWS 0x0401
-#define _WIN32_WINNT   0x0400
-#include <windows.h>
-#include <process.h>
-#endif
-
-#endif
-
-// defines for module integration
-// possible other include file needed
-// These constants defines modules which can be included in the Epl application.
-// Use this constants for define EPL_MODULE_INTEGRATION in file EplCfg.h.
-#define EPL_MODULE_OBDK        0x00000001L	// OBD kernel part module
-#define EPL_MODULE_PDOK        0x00000002L	// PDO kernel part module
-#define EPL_MODULE_NMT_MN      0x00000004L	// NMT MN module
-#define EPL_MODULE_SDOS        0x00000008L	// SDO Server module
-#define EPL_MODULE_SDOC        0x00000010L	// SDO Client module
-#define EPL_MODULE_SDO_ASND    0x00000020L	// SDO over Asnd module
-#define EPL_MODULE_SDO_UDP     0x00000040L	// SDO over UDP module
-#define EPL_MODULE_SDO_PDO     0x00000080L	// SDO in PDO module
-#define EPL_MODULE_NMT_CN      0x00000100L	// NMT CN module
-#define EPL_MODULE_NMTU        0x00000200L	// NMT user part module
-#define EPL_MODULE_NMTK        0x00000400L	// NMT kernel part module
-#define EPL_MODULE_DLLK        0x00000800L	// DLL kernel part module
-#define EPL_MODULE_DLLU        0x00001000L	// DLL user part module
-#define EPL_MODULE_OBDU        0x00002000L	// OBD user part module
-#define EPL_MODULE_CFGMA       0x00004000L	// Configuartioan Manager module
-#define EPL_MODULE_VETH        0x00008000L	// virtual ethernet driver module
-#define EPL_MODULE_PDOU        0x00010000L	// PDO user part module
-#define EPL_MODULE_LEDU        0x00020000L	// LED user part module
-
-#include "EplCfg.h"		// EPL configuration file (configuration from application)
-
-#include "global.h"		// global definitions
-
-#include "EplDef.h"		// EPL configuration file (default configuration)
-#include "EplInstDef.h"		// defines macros for instance types and table
-#include "Debug.h"		// debug definitions
-
-#include "EplErrDef.h"		// EPL error codes for API funtions
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-// IEEE 1588 conformant net time structure
-typedef struct {
-	u32 m_dwSec;
-	u32 m_dwNanoSec;
-
-} tEplNetTime;
-
-#include "EplTarget.h"		// target specific functions and definitions
-
-#include "EplAmi.h"
-
-// -------------------------------------------------------------------------
-// macros
-// -------------------------------------------------------------------------
-
-#define EPL_SPEC_VERSION                    0x20	// ETHERNET Powerlink V. 2.0
-#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"
-
-// defines for EPL FeatureFlags
-#define EPL_FEATURE_ISOCHR          0x00000001
-#define EPL_FEATURE_SDO_UDP         0x00000002
-#define EPL_FEATURE_SDO_ASND        0x00000004
-#define EPL_FEATURE_SDO_PDO         0x00000008
-#define EPL_FEATURE_NMT_INFO        0x00000010
-#define EPL_FEATURE_NMT_EXT         0x00000020
-#define EPL_FEATURE_PDO_DYN         0x00000040
-#define EPL_FEATURE_NMT_UDP         0x00000080
-#define EPL_FEATURE_CFGMA           0x00000100
-#define EPL_FEATURE_DLL_MULTIPLEX   0x00000200
-#define EPL_FEATURE_NODEID_SW       0x00000400
-#define EPL_FEATURE_NMT_BASICETH    0x00000800
-#define EPL_FEATURE_RT1             0x00001000
-#define EPL_FEATURE_RT2             0x00002000
-
-// generate EPL NMT_FeatureFlags_U32
-#ifndef EPL_DEF_FEATURE_ISOCHR
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-#define EPL_DEF_FEATURE_ISOCHR          (EPL_FEATURE_ISOCHR)
-#else
-#define EPL_DEF_FEATURE_ISOCHR          0
-#endif
-#endif
-
-#ifndef EPL_DEF_FEATURE_SDO_ASND
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-#define EPL_DEF_FEATURE_SDO_ASND        (EPL_FEATURE_SDO_ASND)
-#else
-#define EPL_DEF_FEATURE_SDO_ASND        0
-#endif
-#endif
-
-#ifndef EPL_DEF_FEATURE_SDO_UDP
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-#define EPL_DEF_FEATURE_SDO_UDP         (EPL_FEATURE_SDO_UDP)
-#else
-#define EPL_DEF_FEATURE_SDO_UDP         0
-#endif
-#endif
-
-#ifndef EPL_DEF_FEATURE_SDO_PDO
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_PDO)) != 0)
-#define EPL_DEF_FEATURE_SDO_PDO         (EPL_FEATURE_SDO_PDO)
-#else
-#define EPL_DEF_FEATURE_SDO_PDO         0
-#endif
-#endif
-
-#ifndef EPL_DEF_FEATURE_PDO_DYN
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-#define EPL_DEF_FEATURE_PDO_DYN         (EPL_FEATURE_PDO_DYN)
-#else
-#define EPL_DEF_FEATURE_PDO_DYN         0
-#endif
-#endif
-
-#ifndef EPL_DEF_FEATURE_CFGMA
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
-#define EPL_DEF_FEATURE_CFGMA           (EPL_FEATURE_CFGMA)
-#else
-#define EPL_DEF_FEATURE_CFGMA           0
-#endif
-#endif
-
-#define EPL_DEF_FEATURE_FLAGS                   (EPL_DEF_FEATURE_ISOCHR \
-                                                | EPL_DEF_FEATURE_SDO_ASND \
-                                                | EPL_DEF_FEATURE_SDO_UDP \
-                                                | EPL_DEF_FEATURE_SDO_PDO \
-                                                | EPL_DEF_FEATURE_PDO_DYN \
-                                                | EPL_DEF_FEATURE_CFGMA)
-
-#ifndef tabentries
-#define tabentries(a)   (sizeof(a)/sizeof(*(a)))
-#endif
-
-// ============================================================================
-// common debug macros
-// ============================================================================
-// for using macro DEBUG_TRACEx()
-//
-// Example:
-//      DEBUG_TRACE1 (EPL_DBGLVL_OBD, "Value is %d\n" , wObjectIndex);
-//
-// This message only will be printed if:
-//      - NDEBUG is not defined     AND !!!
-//      - flag 0x00000004L is set in DEF_DEBUG_LVL (can be defined in copcfg.h)
-//
-// default level is defined in copdef.h
-
-// debug-level and TRACE-macros         // standard-level   // flags for DEF_DEBUG_LVL
-#define EPL_DBGLVL_EDRV                 DEBUG_LVL_01	// 0x00000001L
-#define EPL_DBGLVL_EDRV_TRACE0          DEBUG_LVL_01_TRACE0
-#define EPL_DBGLVL_EDRV_TRACE1          DEBUG_LVL_01_TRACE1
-#define EPL_DBGLVL_EDRV_TRACE2          DEBUG_LVL_01_TRACE2
-#define EPL_DBGLVL_EDRV_TRACE3          DEBUG_LVL_01_TRACE3
-#define EPL_DBGLVL_EDRV_TRACE4          DEBUG_LVL_01_TRACE4
-
-#define EPL_DBGLVL_DLL                  DEBUG_LVL_02	// 0x00000002L
-#define EPL_DBGLVL_DLL_TRACE0           DEBUG_LVL_02_TRACE0
-#define EPL_DBGLVL_DLL_TRACE1           DEBUG_LVL_02_TRACE1
-#define EPL_DBGLVL_DLL_TRACE2           DEBUG_LVL_02_TRACE2
-#define EPL_DBGLVL_DLL_TRACE3           DEBUG_LVL_02_TRACE3
-#define EPL_DBGLVL_DLL_TRACE4           DEBUG_LVL_02_TRACE4
-
-#define EPL_DBGLVL_OBD                  DEBUG_LVL_03	// 0x00000004L
-#define EPL_DBGLVL_OBD_TRACE0           DEBUG_LVL_03_TRACE0
-#define EPL_DBGLVL_OBD_TRACE1           DEBUG_LVL_03_TRACE1
-#define EPL_DBGLVL_OBD_TRACE2           DEBUG_LVL_03_TRACE2
-#define EPL_DBGLVL_OBD_TRACE3           DEBUG_LVL_03_TRACE3
-#define EPL_DBGLVL_OBD_TRACE4           DEBUG_LVL_03_TRACE4
-
-#define EPL_DBGLVL_NMTK                 DEBUG_LVL_04	// 0x00000008L
-#define EPL_DBGLVL_NMTK_TRACE0          DEBUG_LVL_04_TRACE0
-#define EPL_DBGLVL_NMTK_TRACE1          DEBUG_LVL_04_TRACE1
-#define EPL_DBGLVL_NMTK_TRACE2          DEBUG_LVL_04_TRACE2
-#define EPL_DBGLVL_NMTK_TRACE3          DEBUG_LVL_04_TRACE3
-#define EPL_DBGLVL_NMTK_TRACE4          DEBUG_LVL_04_TRACE4
-
-#define EPL_DBGLVL_NMTCN                DEBUG_LVL_05	// 0x00000010L
-#define EPL_DBGLVL_NMTCN_TRACE0         DEBUG_LVL_05_TRACE0
-#define EPL_DBGLVL_NMTCN_TRACE1         DEBUG_LVL_05_TRACE1
-#define EPL_DBGLVL_NMTCN_TRACE2         DEBUG_LVL_05_TRACE2
-#define EPL_DBGLVL_NMTCN_TRACE3         DEBUG_LVL_05_TRACE3
-#define EPL_DBGLVL_NMTCN_TRACE4         DEBUG_LVL_05_TRACE4
-
-#define EPL_DBGLVL_NMTU                 DEBUG_LVL_06	// 0x00000020L
-#define EPL_DBGLVL_NMTU_TRACE0          DEBUG_LVL_06_TRACE0
-#define EPL_DBGLVL_NMTU_TRACE1          DEBUG_LVL_06_TRACE1
-#define EPL_DBGLVL_NMTU_TRACE2          DEBUG_LVL_06_TRACE2
-#define EPL_DBGLVL_NMTU_TRACE3          DEBUG_LVL_06_TRACE3
-#define EPL_DBGLVL_NMTU_TRACE4          DEBUG_LVL_06_TRACE4
-
-#define EPL_DBGLVL_NMTMN                DEBUG_LVL_07	// 0x00000040L
-#define EPL_DBGLVL_NMTMN_TRACE0         DEBUG_LVL_07_TRACE0
-#define EPL_DBGLVL_NMTMN_TRACE1         DEBUG_LVL_07_TRACE1
-#define EPL_DBGLVL_NMTMN_TRACE2         DEBUG_LVL_07_TRACE2
-#define EPL_DBGLVL_NMTMN_TRACE3         DEBUG_LVL_07_TRACE3
-#define EPL_DBGLVL_NMTMN_TRACE4         DEBUG_LVL_07_TRACE4
-
-//...
-
-#define EPL_DBGLVL_SDO                  DEBUG_LVL_25	// 0x01000000
-#define EPL_DBGLVL_SDO_TRACE0           DEBUG_LVL_25_TRACE0
-#define EPL_DBGLVL_SDO_TRACE1           DEBUG_LVL_25_TRACE1
-#define EPL_DBGLVL_SDO_TRACE2           DEBUG_LVL_25_TRACE2
-#define EPL_DBGLVL_SDO_TRACE3           DEBUG_LVL_25_TRACE3
-#define EPL_DBGLVL_SDO_TRACE4           DEBUG_LVL_25_TRACE4
-
-#define EPL_DBGLVL_VETH                 DEBUG_LVL_26	// 0x02000000
-#define EPL_DBGLVL_VETH_TRACE0          DEBUG_LVL_26_TRACE0
-#define EPL_DBGLVL_VETH_TRACE1          DEBUG_LVL_26_TRACE1
-#define EPL_DBGLVL_VETH_TRACE2          DEBUG_LVL_26_TRACE2
-#define EPL_DBGLVL_VETH_TRACE3          DEBUG_LVL_26_TRACE3
-#define EPL_DBGLVL_VETH_TRACE4          DEBUG_LVL_26_TRACE4
-
-#define EPL_DBGLVL_EVENTK               DEBUG_LVL_27	// 0x04000000
-#define EPL_DBGLVL_EVENTK_TRACE0        DEBUG_LVL_27_TRACE0
-#define EPL_DBGLVL_EVENTK_TRACE1        DEBUG_LVL_27_TRACE1
-#define EPL_DBGLVL_EVENTK_TRACE2        DEBUG_LVL_27_TRACE2
-#define EPL_DBGLVL_EVENTK_TRACE3        DEBUG_LVL_27_TRACE3
-#define EPL_DBGLVL_EVENTK_TRACE4        DEBUG_LVL_27_TRACE4
-
-#define EPL_DBGLVL_EVENTU               DEBUG_LVL_28	// 0x08000000
-#define EPL_DBGLVL_EVENTU_TRACE0        DEBUG_LVL_28_TRACE0
-#define EPL_DBGLVL_EVENTU_TRACE1        DEBUG_LVL_28_TRACE1
-#define EPL_DBGLVL_EVENTU_TRACE2        DEBUG_LVL_28_TRACE2
-#define EPL_DBGLVL_EVENTU_TRACE3        DEBUG_LVL_28_TRACE3
-#define EPL_DBGLVL_EVENTU_TRACE4        DEBUG_LVL_28_TRACE4
-
-// SharedBuff
-#define EPL_DBGLVL_SHB                  DEBUG_LVL_29	// 0x10000000
-#define EPL_DBGLVL_SHB_TRACE0           DEBUG_LVL_29_TRACE0
-#define EPL_DBGLVL_SHB_TRACE1           DEBUG_LVL_29_TRACE1
-#define EPL_DBGLVL_SHB_TRACE2           DEBUG_LVL_29_TRACE2
-#define EPL_DBGLVL_SHB_TRACE3           DEBUG_LVL_29_TRACE3
-#define EPL_DBGLVL_SHB_TRACE4           DEBUG_LVL_29_TRACE4
-
-#define EPL_DBGLVL_ASSERT               DEBUG_LVL_ASSERT	// 0x20000000L
-#define EPL_DBGLVL_ASSERT_TRACE0        DEBUG_LVL_ASSERT_TRACE0
-#define EPL_DBGLVL_ASSERT_TRACE1        DEBUG_LVL_ASSERT_TRACE1
-#define EPL_DBGLVL_ASSERT_TRACE2        DEBUG_LVL_ASSERT_TRACE2
-#define EPL_DBGLVL_ASSERT_TRACE3        DEBUG_LVL_ASSERT_TRACE3
-#define EPL_DBGLVL_ASSERT_TRACE4        DEBUG_LVL_ASSERT_TRACE4
-
-#define EPL_DBGLVL_ERROR                DEBUG_LVL_ERROR	// 0x40000000L
-#define EPL_DBGLVL_ERROR_TRACE0         DEBUG_LVL_ERROR_TRACE0
-#define EPL_DBGLVL_ERROR_TRACE1         DEBUG_LVL_ERROR_TRACE1
-#define EPL_DBGLVL_ERROR_TRACE2         DEBUG_LVL_ERROR_TRACE2
-#define EPL_DBGLVL_ERROR_TRACE3         DEBUG_LVL_ERROR_TRACE3
-#define EPL_DBGLVL_ERROR_TRACE4         DEBUG_LVL_ERROR_TRACE4
-
-#define EPL_DBGLVL_ALWAYS               DEBUG_LVL_ALWAYS	// 0x80000000L
-#define EPL_DBGLVL_ALWAYS_TRACE0        DEBUG_LVL_ALWAYS_TRACE0
-#define EPL_DBGLVL_ALWAYS_TRACE1        DEBUG_LVL_ALWAYS_TRACE1
-#define EPL_DBGLVL_ALWAYS_TRACE2        DEBUG_LVL_ALWAYS_TRACE2
-#define EPL_DBGLVL_ALWAYS_TRACE3        DEBUG_LVL_ALWAYS_TRACE3
-#define EPL_DBGLVL_ALWAYS_TRACE4        DEBUG_LVL_ALWAYS_TRACE4
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_INC_H_
diff --git a/drivers/staging/epl/EplInstDef.h b/drivers/staging/epl/EplInstDef.h
deleted file mode 100644
index 29ab7fb..0000000
--- a/drivers/staging/epl/EplInstDef.h
+++ /dev/null
@@ -1,363 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  definitions for generating instances
-
-  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: EplInstDef.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    ...
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  r.d.: first implementation
-
-****************************************************************************/
-
-#ifndef _EPLINSTDEF_H_
-#define _EPLINSTDEF_H_
-
-#include <linux/kernel.h>
-
-// =========================================================================
-// types and macros for generating instances
-// =========================================================================
-
-typedef enum {
-	kStateUnused = 0,
-	kStateDeleted = 1,
-	kStateUsed = 0xFF
-} tInstState;
-
-//------------------------------------------------------------------------------------------
-
-typedef void *tEplPtrInstance;
-typedef u8 tEplInstanceHdl;
-
-// define const for illegale values
-#define CCM_ILLINSTANCE      NULL
-#define CCM_ILLINSTANCE_HDL  0xFF
-
-//------------------------------------------------------------------------------------------
-// if more than one instance then use this macros
-#if (EPL_MAX_INSTANCES > 1)
-
-    //--------------------------------------------------------------------------------------
-    // macro definition for instance table definition
-    //--------------------------------------------------------------------------------------
-
-    // memory attributes for instance table
-#define STATIC			// prevent warnings for variables with same name
-
-#define INSTANCE_TYPE_BEGIN     typedef struct {
-#define INSTANCE_TYPE_END       } tEplInstanceInfo;
-
-    //--------------------------------------------------------------------------------------
-    // macro definition for API interface
-    //--------------------------------------------------------------------------------------
-
-    // declaration:
-
-    // macros for declaration within function header or prototype of API functions
-#define CCM_DECL_INSTANCE_HDL                   tEplInstanceHdl InstanceHandle
-#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 *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 *pInstance;
-#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL         tEplInstanceHdl  *pInstanceHandle;
-
-    // reference:
-
-    // macros for reference of instance handle for function parameters
-#define CCM_INSTANCE_HDL                        InstanceHandle
-#define CCM_INSTANCE_HDL_                       InstanceHandle,
-
-    // macros for reference of instance parameter for function parameters
-#define CCM_INSTANCE_PARAM(par)                 par
-#define CCM_INSTANCE_PARAM_(par)                par,
-
-    // macros for reference of instance parameter for writing or reading values
-#define CCM_INST_ENTRY                          (*((tEplPtrInstance)pInstance))
-
-    // processing:
-
-    // macros for process instance handle
-#define CCM_CHECK_INSTANCE_HDL()                if (InstanceHandle >= EPL_MAX_INSTANCES) \
-                                                        {return (kEplIllegalInstance);}
-
-    // macros for process pointer to instance handle
-#define CCM_CHECK_PTR_INSTANCE_HDL()            if (pInstanceHandle == NULL) \
-                                                        {return (kEplInvalidInstanceParam);}
-
-    // This macro returned the handle and pointer to next free instance.
-#define CCM_GET_FREE_INSTANCE_AND_HDL()         pInstance = CcmGetFreeInstanceAndHandle (pInstanceHandle); \
-                                                    ASSERT (*pInstanceHandle != CCM_ILLINSTANCE_HDL);
-
-#define CCM_CHECK_INSTANCE_PTR()                if (pInstance == CCM_ILLINSTANCE) \
-                                                        {return (kEplNoFreeInstance);}
-
-#define CCM_GET_INSTANCE_PTR()                  pInstance = CcmGetInstancePtr (InstanceHandle);
-#define CCM_GET_FREE_INSTANCE_PTR()             pInstance = GetFreeInstance (); \
-                                                    ASSERT (pInstance != CCM_ILLINSTANCE);
-
-    //--------------------------------------------------------------------------------------
-    // macro definition for stack interface
-    //--------------------------------------------------------------------------------------
-
-    // macros for declaration within the function header, prototype or local var list
-    // Declaration of pointers within function paramater list must defined as void *
-    // pointer.
-#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
-    // These macros are used for parameter passing to called function.
-#define EPL_MCO_INSTANCE_PTR                        pInstance
-#define EPL_MCO_INSTANCE_PTR_                       pInstance,
-#define EPL_MCO_ADDR_INSTANCE_PTR_                  &pInstance,
-
-    // macro for access of struct members of one instance
-    // An access to a member of instance table must be casted by the local
-    // defined type of instance table.
-#define EPL_MCO_INST_ENTRY                          (*(tEplPtrInstance)pInstance)
-#define EPL_MCO_GLB_VAR(var)                        (((tEplPtrInstance)pInstance)->var)
-
-    // macros for process pointer to instance
-#define EPL_MCO_GET_INSTANCE_PTR()                  pInstance = (tEplPtrInstance) GetInstancePtr (InstanceHandle);
-#define EPL_MCO_GET_FREE_INSTANCE_PTR()             pInstance = (tEplPtrInstance) GetFreeInstance (); \
-                                                    ASSERT (pInstance != CCM_ILLINSTANCE);
-
-    // This macro should be used to check the passed pointer to an public function
-#define EPL_MCO_CHECK_INSTANCE_STATE()              ASSERT (pInstance != NULL); \
-                                                    ASSERT (((tEplPtrInstance)pInstance)->m_InstState == kStateUsed);
-
-    // macros for declaration of pointer to instance pointer
-#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.
-#define EPL_MCO_PTR_INSTANCE_PTR                    pInstancePtr
-#define EPL_MCO_PTR_INSTANCE_PTR_                   pInstancePtr,
-
-    // macros for process pointer to instance pointer
-#define EPL_MCO_CHECK_PTR_INSTANCE_PTR()            ASSERT (pInstancePtr != NULL);
-#define EPL_MCO_SET_PTR_INSTANCE_PTR()              (*pInstancePtr = pInstance);
-
-#define EPL_MCO_INSTANCE_PARAM(a)                   (a)
-#define EPL_MCO_INSTANCE_PARAM_(a)                  (a),
-#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))
-#define EPL_MCO_WRITE_INSTANCE_STATE(a)             EPL_MCO_GLB_VAR (m_InstState) = a;
-
-    // this macro deletes all instance entries as unused
-#define EPL_MCO_DELETE_INSTANCE_TABLE()                                    \
-    {                                                                      \
-        tEplInstanceInfo *   pInstance       = &aEplInstanceTable_g[0];    \
-        tFastByte            InstNumber      = 0;                          \
-        tFastByte            i               = EPL_MAX_INSTANCES;          \
-        do {                                                               \
-            pInstance->m_InstState = (u8) kStateUnused;                  \
-            pInstance->m_bInstIndex = (u8) InstNumber;                   \
-            pInstance++; InstNumber++; i--;                                \
-        } while (i != 0);                                                  \
-    }
-
-    // definition of functions which has to be defined in each module of CANopen stack
-#define EPL_MCO_DEFINE_INSTANCE_FCT() \
-        static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p);  \
-        static tEplPtrInstance GetFreeInstance (void);
-#define EPL_MCO_DECL_INSTANCE_FCT()                                            \
-        static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p) { \
-            return &aEplInstanceTable_g[InstHandle_p]; }                       \
-        static tEplPtrInstance GetFreeInstance (void) {                        \
-            tEplInstanceInfo *pInstance   = &aEplInstanceTable_g[0];           \
-            tFastByte         i           = EPL_MAX_INSTANCES;                 \
-            do { if (pInstance->m_InstState != kStateUsed) {                   \
-                    return (tEplPtrInstance) pInstance; }                      \
-                pInstance++; i--; }                                            \
-            while (i != 0);                                                    \
-            return CCM_ILLINSTANCE; }
-
-    // this macro defines the instance table. Each entry is reserved for an instance of CANopen.
-#define EPL_MCO_DECL_INSTANCE_VAR() \
-        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  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))
-
-#else // only one instance is used
-
-    // Memory attributes for instance table.
-#define STATIC      static	// prevent warnings for variables with same name
-
-#define INSTANCE_TYPE_BEGIN
-#define INSTANCE_TYPE_END
-
-// macros for declaration, initializing and member access for instance handle
-// This class of macros are used by API function to inform CCM-modul which
-// instance is to be used.
-
-    // macros for reference of instance handle
-    // These macros are used for parameter passing to CANopen API function.
-#define CCM_INSTANCE_HDL
-#define CCM_INSTANCE_HDL_
-
-#define CCM_DECL_INSTANCE_PTR_LOCAL
-
-    // macros for declaration within the function header or prototype
-#define CCM_DECL_INSTANCE_HDL                   void
-#define CCM_DECL_INSTANCE_HDL_
-
-    // macros for process instance handle
-#define CCM_CHECK_INSTANCE_HDL()
-
-    // macros for declaration of pointer to instance handle
-#define CCM_DECL_PTR_INSTANCE_HDL               void
-#define CCM_DECL_PTR_INSTANCE_HDL_
-
-    // macros for process pointer to instance handle
-#define CCM_CHECK_PTR_INSTANCE_HDL()
-
-    // This macro returned the handle and pointer to next free instance.
-#define CCM_GET_FREE_INSTANCE_AND_HDL()
-
-#define CCM_CHECK_INSTANCE_PTR()
-
-#define CCM_GET_INSTANCE_PTR()
-#define CCM_GET_FREE_INSTANCE_PTR()
-
-#define CCM_INSTANCE_PARAM(par)
-#define CCM_INSTANCE_PARAM_(par)
-
-#define CCM_INST_ENTRY                          aCcmInstanceTable_g[0]
-
-// macros for declaration, initializing and member access for instance pointer
-// This class of macros are used by CANopen internal function to point to one instance.
-
-    // macros for declaration within the function header, prototype or local var list
-#define EPL_MCO_DECL_INSTANCE_PTR                   void
-#define EPL_MCO_DECL_INSTANCE_PTR_
-#define EPL_MCO_DECL_INSTANCE_PTR_LOCAL
-
-    // macros for reference of pointer to instance
-    // These macros are used for parameter passing to called function.
-#define EPL_MCO_INSTANCE_PTR
-#define EPL_MCO_INSTANCE_PTR_
-#define EPL_MCO_ADDR_INSTANCE_PTR_
-
-    // macros for process pointer to instance
-#define EPL_MCO_GET_INSTANCE_PTR()
-#define EPL_MCO_GET_FREE_INSTANCE_PTR()
-
-    // This macro should be used to check the passed pointer to an public function
-#define EPL_MCO_CHECK_INSTANCE_STATE()
-
-    // macros for declaration of pointer to instance pointer
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR               void
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR_
-
-    // macros for reference of pointer to instance pointer
-    // These macros are used for parameter passing to called function.
-#define EPL_MCO_PTR_INSTANCE_PTR
-#define EPL_MCO_PTR_INSTANCE_PTR_
-
-    // macros for process pointer to instance pointer
-#define EPL_MCO_CHECK_PTR_INSTANCE_PTR()
-#define EPL_MCO_SET_PTR_INSTANCE_PTR()
-
-#define EPL_MCO_INSTANCE_PARAM(a)
-#define EPL_MCO_INSTANCE_PARAM_(a)
-#define EPL_MCO_INSTANCE_PARAM_IDX_()
-#define EPL_MCO_INSTANCE_PARAM_IDX()
-
-    // macro for access of struct members of one instance
-#define EPL_MCO_INST_ENTRY                          aEplInstanceTable_g[0]
-#define EPL_MCO_GLB_VAR(var)                        (var)
-#define EPL_MCO_WRITE_INSTANCE_STATE(a)
-
-    // this macro deletes all instance entries as unused
-#define EPL_MCO_DELETE_INSTANCE_TABLE()
-
-    // definition of functions which has to be defined in each module of CANopen stack
-#define EPL_MCO_DEFINE_INSTANCE_FCT()
-#define EPL_MCO_DECL_INSTANCE_FCT()
-
-    // this macro defines the instance table. Each entry is reserved for an instance of CANopen.
-#define EPL_MCO_DECL_INSTANCE_VAR()
-
-    // this macro defines member variables in instance table which are needed in
-    // all modules of CANopen stack
-#define EPL_MCO_DECL_INSTANCE_MEMBER()
-
-#endif
-
-#endif // _EPLINSTDEF_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/EplLed.h b/drivers/staging/epl/EplLed.h
deleted file mode 100644
index 6a29aed..0000000
--- a/drivers/staging/epl/EplLed.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for status and error LED
-
-  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: EplLed.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.1 $  $Date: 2008/11/17 16:40:39 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2008/11/17 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLLED_H_
-#define _EPLLED_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef enum {
-	kEplLedTypeStatus = 0x00,
-	kEplLedTypeError = 0x01,
-
-} tEplLedType;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLLED_H_
diff --git a/drivers/staging/epl/EplNmt.h b/drivers/staging/epl/EplNmt.h
deleted file mode 100644
index e351b55..0000000
--- a/drivers/staging/epl/EplNmt.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  global include file for EPL-NMT-Modules
-
-  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: EplNmt.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/11/17 16:40:39 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLNMT_H_
-#define _EPLNMT_H_
-
-#include "EplInc.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// define super-states and masks to identify a super-state
-#define EPL_NMT_GS_POWERED          0x0008	// super state
-#define EPL_NMT_GS_INITIALISATION   0x0009	// super state
-#define EPL_NMT_GS_COMMUNICATING    0x000C	// super state
-#define EPL_NMT_CS_EPLMODE          0x000D	// super state
-#define EPL_NMT_MS_EPLMODE          0x000D	// super state
-
-#define EPL_NMT_SUPERSTATE_MASK     0x000F	// mask to select state
-
-#define EPL_NMT_TYPE_UNDEFINED      0x0000	// type of NMT state is still undefined
-#define EPL_NMT_TYPE_CS             0x0100	// CS type of NMT state
-#define EPL_NMT_TYPE_MS             0x0200	// MS type of NMT state
-#define EPL_NMT_TYPE_MASK           0x0300	// mask to select type of NMT state (i.e. CS or MS)
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-// the lower Byte of the NMT-State is encoded
-// like the values in the EPL-Standard
-// the higher byte is used to encode MN
-// (Bit 1 of the higher byte = 1) or CN (Bit 0 of the
-// higher byte  = 1)
-// the super-states are not mentioned in this
-// enum because they are no real states
-// --> there are masks defined to indentify the
-// super-states
-
-typedef enum {
-	kEplNmtGsOff = 0x0000,
-	kEplNmtGsInitialising = 0x0019,
-	kEplNmtGsResetApplication = 0x0029,
-	kEplNmtGsResetCommunication = 0x0039,
-	kEplNmtGsResetConfiguration = 0x0079,
-	kEplNmtCsNotActive = 0x011C,
-	kEplNmtCsPreOperational1 = 0x011D,
-	kEplNmtCsStopped = 0x014D,
-	kEplNmtCsPreOperational2 = 0x015D,
-	kEplNmtCsReadyToOperate = 0x016D,
-	kEplNmtCsOperational = 0x01FD,
-	kEplNmtCsBasicEthernet = 0x011E,
-	kEplNmtMsNotActive = 0x021C,
-	kEplNmtMsPreOperational1 = 0x021D,
-	kEplNmtMsPreOperational2 = 0x025D,
-	kEplNmtMsReadyToOperate = 0x026D,
-	kEplNmtMsOperational = 0x02FD,
-	kEplNmtMsBasicEthernet = 0x021E
-} tEplNmtState;
-
-// NMT-events
-typedef enum {
-	// Events from DLL
-	// Events defined by EPL V2 specification
-	kEplNmtEventNoEvent = 0x00,
-//    kEplNmtEventDllMePres           =   0x01,
-	kEplNmtEventDllMePresTimeout = 0x02,
-//    kEplNmtEventDllMeAsnd           =   0x03,
-//    kEplNmtEventDllMeAsndTimeout    =   0x04,
-	kEplNmtEventDllMeSoaSent = 0x04,
-	kEplNmtEventDllMeSocTrig = 0x05,
-	kEplNmtEventDllMeSoaTrig = 0x06,
-	kEplNmtEventDllCeSoc = 0x07,
-	kEplNmtEventDllCePreq = 0x08,
-	kEplNmtEventDllCePres = 0x09,
-	kEplNmtEventDllCeSoa = 0x0A,
-	kEplNmtEventDllCeAsnd = 0x0B,
-	kEplNmtEventDllCeFrameTimeout = 0x0C,
-
-	// Events triggered by NMT-Commands
-	kEplNmtEventSwReset = 0x10,	// NMT_GT1, NMT_GT2, NMT_GT8
-	kEplNmtEventResetNode = 0x11,
-	kEplNmtEventResetCom = 0x12,
-	kEplNmtEventResetConfig = 0x13,
-	kEplNmtEventEnterPreOperational2 = 0x14,
-	kEplNmtEventEnableReadyToOperate = 0x15,
-	kEplNmtEventStartNode = 0x16,	// NMT_CT7
-	kEplNmtEventStopNode = 0x17,
-
-	// Events triggered by higher layer
-	kEplNmtEventEnterResetApp = 0x20,
-	kEplNmtEventEnterResetCom = 0x21,
-	kEplNmtEventInternComError = 0x22,	// NMT_GT6, internal communication error -> enter ResetCommunication
-	kEplNmtEventEnterResetConfig = 0x23,
-	kEplNmtEventEnterCsNotActive = 0x24,
-	kEplNmtEventEnterMsNotActive = 0x25,
-	kEplNmtEventTimerBasicEthernet = 0x26,	// NMT_CT3; timer triggered state change (NotActive -> BasicEth)
-	kEplNmtEventTimerMsPreOp1 = 0x27,	// enter PreOp1 on MN (NotActive -> MsPreOp1)
-	kEplNmtEventNmtCycleError = 0x28,	// NMT_CT11, NMT_MT6; error during cycle -> enter PreOp1
-	kEplNmtEventTimerMsPreOp2 = 0x29,	// enter PreOp2 on MN (MsPreOp1 -> MsPreOp2 if kEplNmtEventAllMandatoryCNIdent)
-	kEplNmtEventAllMandatoryCNIdent = 0x2A,	// enter PreOp2 on MN if kEplNmtEventTimerMsPreOp2
-	kEplNmtEventEnterReadyToOperate = 0x2B,	// application ready for the state ReadyToOp
-	kEplNmtEventEnterMsOperational = 0x2C,	// enter Operational on MN
-	kEplNmtEventSwitchOff = 0x2D,	// enter state Off
-	kEplNmtEventCriticalError = 0x2E,	// enter state Off because of critical error
-
-} tEplNmtEvent;
-
-// type for argument of event kEplEventTypeNmtStateChange
-typedef struct {
-	tEplNmtState m_NewNmtState;
-	tEplNmtEvent m_NmtEvent;
-
-} tEplEventNmtStateChange;
-
-// structure for kEplEventTypeHeartbeat
-typedef struct {
-	unsigned int m_uiNodeId;	// NodeId
-	tEplNmtState m_NmtState;	// NMT state (remember distinguish between MN / CN)
-	u16 m_wErrorCode;	// EPL error code in case of NMT state NotActive
-
-} tEplHeartbeatEvent;
-
-typedef enum {
-	kEplNmtNodeEventFound = 0x00,
-	kEplNmtNodeEventUpdateSw = 0x01,	// application shall update software on CN
-	kEplNmtNodeEventCheckConf = 0x02,	// application / Configuration Manager shall check and update configuration on CN
-	kEplNmtNodeEventUpdateConf = 0x03,	// application / Configuration Manager shall update configuration on CN (check was done by NmtMn module)
-	kEplNmtNodeEventVerifyConf = 0x04,	// application / Configuration Manager shall verify configuration of CN
-	kEplNmtNodeEventReadyToStart = 0x05,	// issued if EPL_NMTST_NO_STARTNODE set
-	// application must call EplNmtMnuSendNmtCommand(kEplNmtCmdStartNode) manually
-	kEplNmtNodeEventNmtState = 0x06,
-	kEplNmtNodeEventError = 0x07,	// NMT error of CN
-
-} tEplNmtNodeEvent;
-
-typedef enum {
-	kEplNmtNodeCommandBoot = 0x01,	// if EPL_NODEASSIGN_START_CN not set it must be issued after kEplNmtNodeEventFound
-	kEplNmtNodeCommandSwOk = 0x02,	// application updated software on CN successfully
-	kEplNmtNodeCommandSwUpdated = 0x03,	// application updated software on CN successfully
-	kEplNmtNodeCommandConfOk = 0x04,	// application / Configuration Manager has updated configuration on CN successfully
-	kEplNmtNodeCommandConfReset = 0x05,	// application / Configuration Manager has updated configuration on CN successfully
-	// and CN needs ResetConf so that the configuration gets actived
-	kEplNmtNodeCommandConfErr = 0x06,	// application / Configuration Manager failed on updating configuration on CN
-	kEplNmtNodeCommandStart = 0x07,	// if EPL_NMTST_NO_STARTNODE set it must be issued after kEplNmtNodeEventReadyToStart
-
-} tEplNmtNodeCommand;
-
-typedef enum {
-	kEplNmtBootEventBootStep1Finish = 0x00,	// PreOp2 is possible
-	kEplNmtBootEventBootStep2Finish = 0x01,	// ReadyToOp is possible
-	kEplNmtBootEventCheckComFinish = 0x02,	// Operational is possible
-	kEplNmtBootEventOperational = 0x03,	// all mandatory CNs are Operational
-	kEplNmtBootEventError = 0x04,	// boot process halted because of an error
-
-} tEplNmtBootEvent;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLNMT_H_
diff --git a/drivers/staging/epl/EplNmtCnu.c b/drivers/staging/epl/EplNmtCnu.c
deleted file mode 100644
index c27ca8f..0000000
--- a/drivers/staging/epl/EplNmtCnu.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for NMT-CN-Userspace-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: EplNmtCnu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "user/EplNmtCnu.h"
-#include "user/EplDlluCal.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	unsigned int m_uiNodeId;
-	tEplNmtuCheckEventCallback m_pfnCheckEventCb;
-
-} tEplNmtCnuInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static tEplNmtCnuInstance EplNmtCnuInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
-
-static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p);
-
-static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuInit
-//
-// Description: init the first instance of the module
-//
-//
-//
-// Parameters:      uiNodeId_p = NodeId of the local node
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplNmtCnuAddInstance(uiNodeId_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuAddInstance
-//
-// Description: init the add new instance of the module
-//
-//
-//
-// Parameters:      uiNodeId_p = NodeId of the local node
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// reset instance structure
-	EPL_MEMSET(&EplNmtCnuInstance_g, 0, sizeof(EplNmtCnuInstance_g));
-
-	// save nodeid
-	EplNmtCnuInstance_g.m_uiNodeId = uiNodeId_p;
-
-	// register callback-function for NMT-commands
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
-				       EplNmtCnuCommandCb,
-				       kEplDllAsndFilterLocal);
-#endif
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuDelInstance
-//
-// Description: delte instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtCnuDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	// deregister callback function from DLL
-	Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
-				       NULL, kEplDllAsndFilterNone);
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuSendNmtRequest
-//
-// Description: Send an NMT-Request to the MN
-//
-//
-//
-// Parameters:      uiNodeId_p = NodeId of the local node
-//                  NmtCommand_p = requested NMT-Command
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
-				   tEplNmtCommand NmtCommand_p)
-{
-	tEplKernel Ret;
-	tEplFrameInfo NmtRequestFrameInfo;
-	tEplFrame NmtRequestFrame;
-
-	Ret = kEplSuccessful;
-
-	// build frame
-	EPL_MEMSET(&NmtRequestFrame.m_be_abDstMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abDstMac));	// set by DLL
-	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, (u8) EPL_C_ADR_MN_DEF_NODE_ID);	// node id of the MN
-	AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType,
-		       (u8) kEplMsgTypeAsnd);
-	AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId,
-		       (u8) kEplDllAsndNmtRequest);
-	AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.
-		       m_NmtRequestService.m_le_bNmtCommandId,
-		       (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.
-			  m_NmtRequestService.m_le_abNmtCommandData));
-
-	// build info-structure
-	NmtRequestFrameInfo.m_NetTime.m_dwNanoSec = 0;
-	NmtRequestFrameInfo.m_NetTime.m_dwSec = 0;
-	NmtRequestFrameInfo.m_pFrame = &NmtRequestFrame;
-	NmtRequestFrameInfo.m_uiFrameSize = EPL_C_DLL_MINSIZE_NMTREQ;	// sizeof(NmtRequestFrame);
-
-	// send NMT-Request
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	Ret = EplDlluCalAsyncSend(&NmtRequestFrameInfo,	// pointer to frameinfo
-				  kEplDllAsyncReqPrioNmt);	// priority
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuRegisterStateChangeCb
-//
-// Description: register Callback-function go get informed about a
-//              NMT-Change-State-Event
-//
-//
-//
-// Parameters:  pfnEplNmtStateChangeCb_p = functionpointer
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// save callback-function in modul global var
-	EplNmtCnuInstance_g.m_pfnCheckEventCb = pfnEplNmtCheckEventCb_p;
-
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuCommandCb
-//
-// Description: callback funktion for NMT-Commands
-//
-//
-//
-// Parameters:      pFrameInfo_p = Frame with the NMT-Commando
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplNmtCommand NmtCommand;
-	BOOL fNodeIdInList;
-	tEplNmtEvent NmtEvent = kEplNmtEventNoEvent;
-
-	if (pFrameInfo_p == NULL) {
-		Ret = kEplNmtInvalidFramePointer;
-		goto Exit;
-	}
-
-	NmtCommand = EplNmtCnuGetNmtCommand(pFrameInfo_p);
-
-	// check NMT-Command
-	switch (NmtCommand) {
-
-		//------------------------------------------------------------------------
-		// plain NMT state commands
-	case kEplNmtCmdStartNode:
-		{		// send NMT-Event to state maschine kEplNmtEventStartNode
-			NmtEvent = kEplNmtEventStartNode;
-			break;
-		}
-
-	case kEplNmtCmdStopNode:
-		{		// send NMT-Event to state maschine kEplNmtEventStopNode
-			NmtEvent = kEplNmtEventStopNode;
-			break;
-		}
-
-	case kEplNmtCmdEnterPreOperational2:
-		{		// send NMT-Event to state maschine kEplNmtEventEnterPreOperational2
-			NmtEvent = kEplNmtEventEnterPreOperational2;
-			break;
-		}
-
-	case kEplNmtCmdEnableReadyToOperate:
-		{		// send NMT-Event to state maschine kEplNmtEventEnableReadyToOperate
-			NmtEvent = kEplNmtEventEnableReadyToOperate;
-			break;
-		}
-
-	case kEplNmtCmdResetNode:
-		{		// send NMT-Event to state maschine kEplNmtEventResetNode
-			NmtEvent = kEplNmtEventResetNode;
-			break;
-		}
-
-	case kEplNmtCmdResetCommunication:
-		{		// send NMT-Event to state maschine kEplNmtEventResetCom
-			NmtEvent = kEplNmtEventResetCom;
-			break;
-		}
-
-	case kEplNmtCmdResetConfiguration:
-		{		// send NMT-Event to state maschine kEplNmtEventResetConfig
-			NmtEvent = kEplNmtEventResetConfig;
-			break;
-		}
-
-	case kEplNmtCmdSwReset:
-		{		// send NMT-Event to state maschine kEplNmtEventSwReset
-			NmtEvent = kEplNmtEventSwReset;
-			break;
-		}
-
-		//------------------------------------------------------------------------
-		// extended NMT state commands
-
-	case kEplNmtCmdStartNodeEx:
-		{
-			// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&
-						(pFrameInfo_p->m_pFrame->m_Data.
-						 m_Asnd.m_Payload.
-						 m_NmtCommandService.
-						 m_le_abNmtCommandData[0]));
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventStartNode;
-			}
-			break;
-		}
-
-	case kEplNmtCmdStopNodeEx:
-		{		// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
-						m_Asnd.m_Payload.
-						m_NmtCommandService.
-						m_le_abNmtCommandData[0]);
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventStopNode;
-			}
-			break;
-		}
-
-	case kEplNmtCmdEnterPreOperational2Ex:
-		{		// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
-						m_Asnd.m_Payload.
-						m_NmtCommandService.
-						m_le_abNmtCommandData[0]);
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventEnterPreOperational2;
-			}
-			break;
-		}
-
-	case kEplNmtCmdEnableReadyToOperateEx:
-		{		// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
-						m_Asnd.m_Payload.
-						m_NmtCommandService.
-						m_le_abNmtCommandData[0]);
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventEnableReadyToOperate;
-			}
-			break;
-		}
-
-	case kEplNmtCmdResetNodeEx:
-		{		// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
-						m_Asnd.m_Payload.
-						m_NmtCommandService.
-						m_le_abNmtCommandData[0]);
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventResetNode;
-			}
-			break;
-		}
-
-	case kEplNmtCmdResetCommunicationEx:
-		{		// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
-						m_Asnd.m_Payload.
-						m_NmtCommandService.
-						m_le_abNmtCommandData[0]);
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventResetCom;
-			}
-			break;
-		}
-
-	case kEplNmtCmdResetConfigurationEx:
-		{		// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
-						m_Asnd.m_Payload.
-						m_NmtCommandService.
-						m_le_abNmtCommandData[0]);
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventResetConfig;
-			}
-			break;
-		}
-
-	case kEplNmtCmdSwResetEx:
-		{		// check if own nodeid is in EPL node list
-			fNodeIdInList =
-			    EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.
-						m_Asnd.m_Payload.
-						m_NmtCommandService.
-						m_le_abNmtCommandData[0]);
-			if (fNodeIdInList != FALSE) {	// own nodeid in list
-				// send event to process command
-				NmtEvent = kEplNmtEventSwReset;
-			}
-			break;
-		}
-
-		//------------------------------------------------------------------------
-		// NMT managing commands
-
-		// TODO: add functions to process managing command (optional)
-
-	case kEplNmtCmdNetHostNameSet:
-		{
-			break;
-		}
-
-	case kEplNmtCmdFlushArpEntry:
-		{
-			break;
-		}
-
-		//------------------------------------------------------------------------
-		// NMT info services
-
-		// TODO: forward event with infos to the application (optional)
-
-	case kEplNmtCmdPublishConfiguredCN:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishActiveCN:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishPreOperational1:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishPreOperational2:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishReadyToOperate:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishOperational:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishStopped:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishEmergencyNew:
-		{
-			break;
-		}
-
-	case kEplNmtCmdPublishTime:
-		{
-			break;
-		}
-
-		//-----------------------------------------------------------------------
-		// error from MN
-		// -> requested command not supported by MN
-	case kEplNmtCmdInvalidService:
-		{
-
-			// TODO: errorevent to application
-			break;
-		}
-
-		//------------------------------------------------------------------------
-		// default
-	default:
-		{
-			Ret = kEplNmtUnknownCommand;
-			goto Exit;
-		}
-
-	}			// end of switch(NmtCommand)
-
-	if (NmtEvent != kEplNmtEventNoEvent) {
-		if (EplNmtCnuInstance_g.m_pfnCheckEventCb != NULL) {
-			Ret = EplNmtCnuInstance_g.m_pfnCheckEventCb(NmtEvent);
-			if (Ret == kEplReject) {
-				Ret = kEplSuccessful;
-				goto Exit;
-			} else if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-		}
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-		Ret = EplNmtuNmtEvent(NmtEvent);
-#endif
-	}
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuGetNmtCommand()
-//
-// Description: returns the NMT-Command from the frame
-//
-//
-//
-// Parameters:      pFrameInfo_p = pointer to the Frame
-//                                 with the NMT-Command
-//
-//
-// Returns:         tEplNmtCommand = NMT-Command
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p)
-{
-	tEplNmtCommand NmtCommand;
-	tEplNmtCommandService *pNmtCommandService;
-
-	pNmtCommandService =
-	    &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.
-	    m_NmtCommandService;
-
-	NmtCommand =
-	    (tEplNmtCommand) AmiGetByteFromLe(&pNmtCommandService->
-					      m_le_bNmtCommandId);
-
-	return NmtCommand;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtCnuNodeIdList()
-//
-// Description: check if the own nodeid is set in EPL Node List
-//
-//
-//
-// Parameters:      pbNmtCommandDate_p = pointer to the data of the NMT Command
-//
-//
-// Returns:         BOOL = TRUE if nodeid is set in EPL Node List
-//                         FALSE if nodeid not set in EPL Node List
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p)
-{
-	BOOL fNodeIdInList;
-	unsigned int uiByteOffset;
-	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 = (u8) EplNmtCnuInstance_g.m_uiNodeId % 8;
-
-	bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
-	if ((bNodeListByte & bBitOffset) == 0) {
-		fNodeIdInList = FALSE;
-	} else {
-		fNodeIdInList = TRUE;
-	}
-
-	return fNodeIdInList;
-}
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplNmtMnu.c b/drivers/staging/epl/EplNmtMnu.c
deleted file mode 100644
index d19434f..0000000
--- a/drivers/staging/epl/EplNmtMnu.c
+++ /dev/null
@@ -1,2828 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for NMT-MN-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: EplNmtMnu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.18 $  $Date: 2008/11/19 09:52:24 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplNmtMnu.h"
-#include "user/EplTimeru.h"
-#include "user/EplIdentu.h"
-#include "user/EplStatusu.h"
-#include "user/EplObdu.h"
-#include "user/EplDlluCal.h"
-#include "Benchmark.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
-#error "EPL NmtMnu module needs EPL module OBDU or OBDK!"
-#endif
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-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
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-#define EPL_NMTMNU_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
-    TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtMnu << 28) | (Event_p << 24) \
-                             | (uiNodeId_p << 16) | wErrorCode_p)
-
-// defines for flags in node info structure
-#define EPL_NMTMNU_NODE_FLAG_ISOCHRON       0x0001	// CN is being accessed isochronously
-#define EPL_NMTMNU_NODE_FLAG_NOT_SCANNED    0x0002	// CN was not scanned once -> decrement SignalCounter and reset flag
-#define EPL_NMTMNU_NODE_FLAG_HALTED         0x0004	// boot process for this CN is halted
-#define EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED 0x0008	// NMT command was just issued, wrong NMT states will be tolerated
-#define EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ  0x0300	// counter for StatusRequest timer handle
-#define EPL_NMTMNU_NODE_FLAG_COUNT_LONGER   0x0C00	// counter for longer timeouts timer handle
-#define EPL_NMTMNU_NODE_FLAG_INC_STATREQ    0x0100	// increment for StatusRequest timer handle
-#define EPL_NMTMNU_NODE_FLAG_INC_LONGER     0x0400	// increment for longer timeouts timer handle
-		    // These counters will be incremented at every timer start
-		    // and copied to timerarg. When the timer event occures
-		    // both will be compared and if unequal the timer event
-		    // will be discarded, because it is an old one.
-
-// defines for timer arguments to draw a distinction between serveral events
-#define EPL_NMTMNU_TIMERARG_NODE_MASK   0x000000FFL	// mask that contains the node-ID
-#define EPL_NMTMNU_TIMERARG_IDENTREQ    0x00010000L	// timer event is for IdentRequest
-#define EPL_NMTMNU_TIMERARG_STATREQ     0x00020000L	// timer event is for StatusRequest
-#define EPL_NMTMNU_TIMERARG_LONGER      0x00040000L	// timer event is for longer timeouts
-#define EPL_NMTMNU_TIMERARG_STATE_MON   0x00080000L	// timer event for StatusRequest to monitor execution of NMT state changes
-#define EPL_NMTMNU_TIMERARG_COUNT_SR    0x00000300L	// counter for StatusRequest
-#define EPL_NMTMNU_TIMERARG_COUNT_LO    0x00000C00L	// counter for longer timeouts
-		    // The counters must have the same position as in the node flags above.
-
-#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
-    pNodeInfo_p->m_wFlags = \
-        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
-         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
-        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
-    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p | \
-        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
-    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
-
-#define EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
-    pNodeInfo_p->m_wFlags = \
-        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
-         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
-        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
-    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p | \
-        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
-    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
-
-#define EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
-    pNodeInfo_p->m_wFlags = \
-        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_LONGER) \
-         & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) \
-        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
-    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p | \
-        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
-    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
-
-#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
-    pNodeInfo_p->m_wFlags = \
-        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
-         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
-        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
-    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATE_MON | uiNodeId_p | \
-        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
-    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
-
-// defines for global flags
-#define EPL_NMTMNU_FLAG_HALTED          0x0001	// boot process is halted
-#define EPL_NMTMNU_FLAG_APP_INFORMED    0x0002	// application was informed about possible NMT state change
-
-// return pointer to node info structure for specified node ID
-// d.k. may be replaced by special (hash) function if node ID array is smaller than 254
-#define EPL_NMTMNU_GET_NODEINFO(uiNodeId_p) (&EplNmtMnuInstance_g.m_aNodeInfo[uiNodeId_p - 1])
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef enum {
-	kEplNmtMnuIntNodeEventNoIdentResponse = 0x00,
-	kEplNmtMnuIntNodeEventIdentResponse = 0x01,
-	kEplNmtMnuIntNodeEventBoot = 0x02,
-	kEplNmtMnuIntNodeEventExecReset = 0x03,
-	kEplNmtMnuIntNodeEventConfigured = 0x04,
-	kEplNmtMnuIntNodeEventNoStatusResponse = 0x05,
-	kEplNmtMnuIntNodeEventStatusResponse = 0x06,
-	kEplNmtMnuIntNodeEventHeartbeat = 0x07,
-	kEplNmtMnuIntNodeEventNmtCmdSent = 0x08,
-	kEplNmtMnuIntNodeEventTimerIdentReq = 0x09,
-	kEplNmtMnuIntNodeEventTimerStatReq = 0x0A,
-	kEplNmtMnuIntNodeEventTimerStateMon = 0x0B,
-	kEplNmtMnuIntNodeEventTimerLonger = 0x0C,
-	kEplNmtMnuIntNodeEventError = 0x0D,
-
-} tEplNmtMnuIntNodeEvent;
-
-typedef enum {
-	kEplNmtMnuNodeStateUnknown = 0x00,
-	kEplNmtMnuNodeStateIdentified = 0x01,
-	kEplNmtMnuNodeStateResetConf = 0x02,	// CN reset after configuration update
-	kEplNmtMnuNodeStateConfigured = 0x03,	// BootStep1 completed
-	kEplNmtMnuNodeStateReadyToOp = 0x04,	// BootStep2 completed
-	kEplNmtMnuNodeStateComChecked = 0x05,	// Communication checked successfully
-	kEplNmtMnuNodeStateOperational = 0x06,	// CN is in NMT state OPERATIONAL
-
-} tEplNmtMnuNodeState;
-
-typedef struct {
-	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)
-	u32 m_dwNodeCfg;	// subindex from 0x1F81
-	u16 m_wFlags;		// flags: CN is being accessed isochronously
-
-} tEplNmtMnuNodeInfo;
-
-typedef struct {
-	tEplNmtMnuNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID];
-	tEplTimerHdl m_TimerHdlNmtState;	// timeout for stay in NMT state
-	unsigned int m_uiMandatorySlaveCount;
-	unsigned int m_uiSignalSlaveCount;
-	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)
-	u16 m_wFlags;		// global flags
-	u32 m_dwNmtStartup;	// object 0x1F80 NMT_StartUp_U32
-	tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent;
-	tEplNmtMnuCbBootEvent m_pfnCbBootEvent;
-
-} tEplNmtMnuInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplNmtMnuInstance EplNmtMnuInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p);
-
-static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
-					   tEplIdentResponse *pIdentResponse_p);
-
-static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
-					    tEplStatusResponse *pStatusResponse_p);
-
-static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
-					 tEplNmtMnuNodeInfo * pNodeInfo_p,
-					 tEplNmtState NodeNmtState_p,
-					 u16 wErrorCode_p,
-					 tEplNmtState LocalNmtState_p);
-
-static tEplKernel EplNmtMnuStartBootStep1(void);
-
-static tEplKernel EplNmtMnuStartBootStep2(void);
-
-static tEplKernel EplNmtMnuStartCheckCom(void);
-
-static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
-					 tEplNmtMnuNodeInfo * pNodeInfo_p);
-
-static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
-					tEplNmtMnuNodeInfo * pNodeInfo_p);
-
-static tEplKernel EplNmtMnuStartNodes(void);
-
-static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
-						tEplNmtState NodeNmtState_p,
-						u16 wErrorCode_p,
-						tEplNmtMnuIntNodeEvent
-						NodeEvent_p);
-
-static tEplKernel EplNmtMnuReset(void);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuInit
-//
-// Description: init first instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
-			 tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplNmtMnuAddInstance(pfnCbNodeEvent_p, pfnCbBootEvent_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuAddInstance
-//
-// Description: init other instances of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
-				tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// reset instance structure
-	EPL_MEMSET(&EplNmtMnuInstance_g, 0, sizeof(EplNmtMnuInstance_g));
-
-	if ((pfnCbNodeEvent_p == NULL) || (pfnCbBootEvent_p == NULL)) {
-		Ret = kEplNmtInvalidParam;
-		goto Exit;
-	}
-	EplNmtMnuInstance_g.m_pfnCbNodeEvent = pfnCbNodeEvent_p;
-	EplNmtMnuInstance_g.m_pfnCbBootEvent = pfnCbBootEvent_p;
-
-	// initialize StatusRequest delay
-	EplNmtMnuInstance_g.m_ulStatusRequestDelay = 5000L;
-
-	// register NmtMnResponse callback function
-	Ret =
-	    EplDlluCalRegAsndService(kEplDllAsndNmtRequest,
-				     EplNmtMnuCbNmtRequest,
-				     kEplDllAsndFilterLocal);
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuDelInstance
-//
-// Description: delete instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// deregister NmtMnResponse callback function
-	Ret =
-	    EplDlluCalRegAsndService(kEplDllAsndNmtRequest, NULL,
-				     kEplDllAsndFilterNone);
-
-	Ret = EplNmtMnuReset();
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuSendNmtCommandEx
-//
-// Description: sends the specified NMT command to the specified node.
-//
-// Parameters:  uiNodeId_p              = node ID to which the NMT command will be sent
-//              NmtCommand_p            = NMT command
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
-				     tEplNmtCommand NmtCommand_p,
-				     void *pNmtCommandData_p,
-				     unsigned int uiDataSize_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplFrameInfo FrameInfo;
-	u8 abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
-	tEplFrame *pFrame = (tEplFrame *) abBuffer;
-	BOOL fSoftDeleteNode = FALSE;
-
-	if ((uiNodeId_p == 0) || (uiNodeId_p > EPL_C_ADR_BROADCAST)) {	// invalid node ID specified
-		Ret = kEplInvalidNodeId;
-		goto Exit;
-	}
-
-	if ((pNmtCommandData_p != NULL)
-	    && (uiDataSize_p >
-		(EPL_C_DLL_MINSIZE_NMTCMDEXT - EPL_C_DLL_MINSIZE_NMTCMD))) {
-		Ret = kEplNmtInvalidParam;
-		goto Exit;
-	}
-	// $$$ d.k. may be check in future versions if the caller wants to perform prohibited state transitions
-	//     the CN should not perform these transitions, but the expected NMT state will be changed and never fullfilled.
-
-	// build frame
-	EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer));
-	AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (u8) uiNodeId_p);
-	AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
-		       (u8) kEplDllAsndNmtCommand);
-	AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
-		       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,
-			   uiDataSize_p);
-	}
-	// build info structure
-	FrameInfo.m_NetTime.m_dwNanoSec = 0;
-	FrameInfo.m_NetTime.m_dwSec = 0;
-	FrameInfo.m_pFrame = pFrame;
-	FrameInfo.m_uiFrameSize = sizeof(abBuffer);
-
-	// send NMT-Request
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	Ret = EplDlluCalAsyncSend(&FrameInfo,	// pointer to frameinfo
-				  kEplDllAsyncReqPrioNmt);	// priority
-#endif
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	EPL_DBGLVL_NMTMN_TRACE2("NMTCmd(%02X->%02X)\n", NmtCommand_p,
-				uiNodeId_p);
-
-	switch (NmtCommand_p) {
-	case kEplNmtCmdStartNode:
-	case kEplNmtCmdEnterPreOperational2:
-	case kEplNmtCmdEnableReadyToOperate:
-		{
-			// nothing left to do,
-			// because any further processing is done
-			// when the NMT command is actually sent
-			goto Exit;
-		}
-
-	case kEplNmtCmdStopNode:
-		{
-			fSoftDeleteNode = TRUE;
-			break;
-		}
-
-	case kEplNmtCmdResetNode:
-	case kEplNmtCmdResetCommunication:
-	case kEplNmtCmdResetConfiguration:
-	case kEplNmtCmdSwReset:
-		{
-			break;
-		}
-
-	default:
-		goto Exit;
-	}
-
-	// remove CN from isochronous phase;
-	// This must be done here and not when NMT command is actually sent
-	// because it will be too late and may cause unwanted errors
-	if (uiNodeId_p != EPL_C_ADR_BROADCAST) {
-		if (fSoftDeleteNode == FALSE) {	// remove CN immediately from isochronous phase
-			Ret = EplDlluCalDeleteNode(uiNodeId_p);
-		} else {	// remove CN from isochronous phase softly
-			Ret = EplDlluCalSoftDeleteNode(uiNodeId_p);
-		}
-	} else {		// do it for all active CNs
-		for (uiNodeId_p = 1;
-		     uiNodeId_p <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
-		     uiNodeId_p++) {
-			if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId_p)->
-			     m_dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN |
-					    EPL_NODEASSIGN_NODE_EXISTS)) != 0) {
-				if (fSoftDeleteNode == FALSE) {	// remove CN immediately from isochronous phase
-					Ret = EplDlluCalDeleteNode(uiNodeId_p);
-				} else {	// remove CN from isochronous phase softly
-					Ret =
-					    EplDlluCalSoftDeleteNode
-					    (uiNodeId_p);
-				}
-			}
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuSendNmtCommand
-//
-// Description: sends the specified NMT command to the specified node.
-//
-// Parameters:  uiNodeId_p              = node ID to which the NMT command will be sent
-//              NmtCommand_p            = NMT command
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
-				   tEplNmtCommand NmtCommand_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	Ret = EplNmtMnuSendNmtCommandEx(uiNodeId_p, NmtCommand_p, NULL, 0);
-
-//Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuTriggerStateChange
-//
-// Description: triggers the specified node command for the specified node.
-//
-// Parameters:  uiNodeId_p              = node ID for which the node command will be executed
-//              NodeCommand_p           = node command
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
-				       tEplNmtNodeCommand NodeCommand_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplNmtMnuIntNodeEvent NodeEvent;
-	tEplObdSize ObdSize;
-	u8 bNmtState;
-	u16 wErrorCode = EPL_E_NO_ERROR;
-
-	if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST)) {
-		Ret = kEplInvalidNodeId;
-		goto Exit;
-	}
-
-	switch (NodeCommand_p) {
-	case kEplNmtNodeCommandBoot:
-		{
-			NodeEvent = kEplNmtMnuIntNodeEventBoot;
-			break;
-		}
-
-	case kEplNmtNodeCommandConfOk:
-		{
-			NodeEvent = kEplNmtMnuIntNodeEventConfigured;
-			break;
-		}
-
-	case kEplNmtNodeCommandConfErr:
-		{
-			NodeEvent = kEplNmtMnuIntNodeEventError;
-			wErrorCode = EPL_E_NMT_BPO1_CF_VERIFY;
-			break;
-		}
-
-	case kEplNmtNodeCommandConfReset:
-		{
-			NodeEvent = kEplNmtMnuIntNodeEventExecReset;
-			break;
-		}
-
-	default:
-		{		// invalid node command
-			goto Exit;
-		}
-	}
-
-	// fetch current NMT state
-	ObdSize = 1;
-	Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtState, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
-					    (tEplNmtState) (bNmtState |
-							    EPL_NMT_TYPE_CS),
-					    wErrorCode, NodeEvent);
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuCbNmtStateChange
-//
-// Description: callback function for NMT state changes
-//
-// Parameters:  NmtStateChange_p        = NMT state change event
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// do work which must be done in that state
-	switch (NmtStateChange_p.m_NewNmtState) {
-		// EPL stack is not running
-/*        case kEplNmtGsOff:
-            break;
-
-        // first init of the hardware
-        case kEplNmtGsInitialising:
-            break;
-
-        // init of the manufacturer-specific profile area and the
-        // standardised device profile area
-        case kEplNmtGsResetApplication:
-        {
-            break;
-        }
-
-        // init of the communication profile area
-        case kEplNmtGsResetCommunication:
-        {
-            break;
-        }
-*/
-		// build the configuration with infos from OD
-	case kEplNmtGsResetConfiguration:
-		{
-			u32 dwTimeout;
-			tEplObdSize ObdSize;
-
-			// read object 0x1F80 NMT_StartUp_U32
-			ObdSize = 4;
-			Ret =
-			    EplObduReadEntry(0x1F80, 0,
-					     &EplNmtMnuInstance_g.
-					     m_dwNmtStartup, &ObdSize);
-			if (Ret != kEplSuccessful) {
-				break;
-			}
-			// compute StatusReqDelay = object 0x1006 * EPL_C_NMT_STATREQ_CYCLE
-			ObdSize = sizeof(dwTimeout);
-			Ret = EplObduReadEntry(0x1006, 0, &dwTimeout, &ObdSize);
-			if (Ret != kEplSuccessful) {
-				break;
-			}
-			if (dwTimeout != 0L) {
-				EplNmtMnuInstance_g.m_ulStatusRequestDelay =
-				    dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
-				if (EplNmtMnuInstance_g.
-				    m_ulStatusRequestDelay == 0L) {
-					EplNmtMnuInstance_g.m_ulStatusRequestDelay = 1L;	// at least 1 ms
-				}
-				// $$$ fetch and use MultiplexedCycleCount from OD
-				EplNmtMnuInstance_g.m_ulTimeoutCheckCom =
-				    dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
-				if (EplNmtMnuInstance_g.m_ulTimeoutCheckCom ==
-				    0L) {
-					EplNmtMnuInstance_g.m_ulTimeoutCheckCom = 1L;	// at least 1 ms
-				}
-			}
-			// fetch ReadyToOp Timeout from OD
-			ObdSize = sizeof(dwTimeout);
-			Ret = EplObduReadEntry(0x1F89, 5, &dwTimeout, &ObdSize);
-			if (Ret != kEplSuccessful) {
-				break;
-			}
-			if (dwTimeout != 0L) {
-				// convert [us] to [ms]
-				dwTimeout /= 1000L;
-				if (dwTimeout == 0L) {
-					dwTimeout = 1L;	// at least 1 ms
-				}
-				EplNmtMnuInstance_g.m_ulTimeoutReadyToOp =
-				    dwTimeout;
-			} else {
-				EplNmtMnuInstance_g.m_ulTimeoutReadyToOp = 0L;
-			}
-			break;
-		}
-/*
-        //-----------------------------------------------------------
-        // CN part of the state machine
-
-        // node liste for EPL-Frames and check timeout
-        case kEplNmtCsNotActive:
-        {
-            break;
-        }
-
-        // node process only async frames
-        case kEplNmtCsPreOperational1:
-        {
-            break;
-        }
-
-        // node process isochronus and asynchronus frames
-        case kEplNmtCsPreOperational2:
-        {
-            break;
-        }
-
-        // node should be configured und application is ready
-        case kEplNmtCsReadyToOperate:
-        {
-            break;
-        }
-
-        // normal work state
-        case kEplNmtCsOperational:
-        {
-            break;
-        }
-
-        // node stopped by MN
-        // -> only process asynchronus frames
-        case kEplNmtCsStopped:
-        {
-            break;
-        }
-
-        // no EPL cycle
-        // -> normal ethernet communication
-        case kEplNmtCsBasicEthernet:
-        {
-            break;
-        }
-*/
-		//-----------------------------------------------------------
-		// MN part of the state machine
-
-		// node listens for EPL-Frames and check timeout
-	case kEplNmtMsNotActive:
-		{
-			break;
-		}
-
-		// node processes only async frames
-	case kEplNmtMsPreOperational1:
-		{
-			u32 dwTimeout;
-			tEplTimerArg TimerArg;
-			tEplObdSize ObdSize;
-			tEplEvent Event;
-
-			// clear global flags, e.g. reenable boot process
-			EplNmtMnuInstance_g.m_wFlags = 0;
-
-			// reset IdentResponses and running IdentRequests and StatusRequests
-			Ret = EplIdentuReset();
-			Ret = EplStatusuReset();
-
-			// reset timers
-			Ret = EplNmtMnuReset();
-
-			// 2008/11/18 d.k. reset internal node info is not necessary,
-			//                 because timer flags are important and other
-			//                 things are reset by EplNmtMnuStartBootStep1().
-/*
-            EPL_MEMSET(EplNmtMnuInstance_g.m_aNodeInfo,
-                       0,
-                       sizeof (EplNmtMnuInstance_g.m_aNodeInfo));
-*/
-
-			// inform DLL about NMT state change,
-			// so that it can clear the asynchonous queues and start the reduced cycle
-			Event.m_EventSink = kEplEventSinkDllk;
-			Event.m_EventType = kEplEventTypeDllkStartReducedCycle;
-			EPL_MEMSET(&Event.m_NetTime, 0x00,
-				   sizeof(Event.m_NetTime));
-			Event.m_pArg = NULL;
-			Event.m_uiSize = 0;
-			Ret = EplEventuPost(&Event);
-			if (Ret != kEplSuccessful) {
-				break;
-			}
-			// reset all nodes
-			// d.k.: skip this step if was just done before, e.g. because of a ResetNode command from a diagnostic node
-			if (NmtStateChange_p.m_NmtEvent ==
-			    kEplNmtEventTimerMsPreOp1) {
-				BENCHMARK_MOD_07_TOGGLE(9);
-
-				EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
-								EPL_C_ADR_BROADCAST,
-								kEplNmtCmdResetNode);
-
-				Ret =
-				    EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST,
-							    kEplNmtCmdResetNode);
-				if (Ret != kEplSuccessful) {
-					break;
-				}
-			}
-			// start network scan
-			Ret = EplNmtMnuStartBootStep1();
-
-			// start timer for 0x1F89/2 MNTimeoutPreOp1_U32
-			ObdSize = sizeof(dwTimeout);
-			Ret = EplObduReadEntry(0x1F89, 2, &dwTimeout, &ObdSize);
-			if (Ret != kEplSuccessful) {
-				break;
-			}
-			if (dwTimeout != 0L) {
-				dwTimeout /= 1000L;
-				if (dwTimeout == 0L) {
-					dwTimeout = 1L;	// at least 1 ms
-				}
-				TimerArg.m_EventSink = kEplEventSinkNmtMnu;
-				TimerArg.m_ulArg = 0;
-				Ret =
-				    EplTimeruModifyTimerMs(&EplNmtMnuInstance_g.
-							   m_TimerHdlNmtState,
-							   dwTimeout, TimerArg);
-			}
-			break;
-		}
-
-		// node processes isochronous and asynchronous frames
-	case kEplNmtMsPreOperational2:
-		{
-			// add identified CNs to isochronous phase
-			// send EnableReadyToOp to all identified CNs
-			Ret = EplNmtMnuStartBootStep2();
-
-			// wait for NMT state change of CNs
-			break;
-		}
-
-		// node should be configured und application is ready
-	case kEplNmtMsReadyToOperate:
-		{
-			// check if PRes of CNs are OK
-			// d.k. that means wait CycleLength * MultiplexCycleCount (i.e. start timer)
-			//      because Dllk checks PRes of CNs automatically in ReadyToOp
-			Ret = EplNmtMnuStartCheckCom();
-			break;
-		}
-
-		// normal work state
-	case kEplNmtMsOperational:
-		{
-			// send StartNode to CNs
-			// wait for NMT state change of CNs
-			Ret = EplNmtMnuStartNodes();
-			break;
-		}
-
-		// no EPL cycle
-		// -> normal ethernet communication
-	case kEplNmtMsBasicEthernet:
-		{
-			break;
-		}
-
-	default:
-		{
-//            TRACE0("EplNmtMnuCbNmtStateChange(): unhandled NMT state\n");
-		}
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuCbCheckEvent
-//
-// Description: callback funktion for NMT events before they are actually executed.
-//              The EPL API layer must forward NMT events from NmtCnu module.
-//              This module will reject some NMT commands while MN.
-//
-// Parameters:  NmtEvent_p              = outstanding NMT event for approval
-//
-// Returns:     tEplKernel              = error code
-//                      kEplReject      = reject the NMT event
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuProcessEvent
-//
-// Description: processes events from event queue
-//
-// Parameters:  pEvent_p        = pointer to event
-//
-// Returns:     tEplKernel      = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// process event
-	switch (pEvent_p->m_EventType) {
-		// timer event
-	case kEplEventTypeTimer:
-		{
-			tEplTimerEventArg *pTimerEventArg =
-			    (tEplTimerEventArg *) pEvent_p->m_pArg;
-			unsigned int uiNodeId;
-
-			uiNodeId =
-			    (unsigned int)(pTimerEventArg->
-					   m_ulArg &
-					   EPL_NMTMNU_TIMERARG_NODE_MASK);
-			if (uiNodeId != 0) {
-				tEplObdSize ObdSize;
-				u8 bNmtState;
-				tEplNmtMnuNodeInfo *pNodeInfo;
-
-				pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId);
-
-				ObdSize = 1;
-				Ret =
-				    EplObduReadEntry(0x1F8E, uiNodeId,
-						     &bNmtState, &ObdSize);
-				if (Ret != kEplSuccessful) {
-					break;
-				}
-
-				if ((pTimerEventArg->
-				     m_ulArg & EPL_NMTMNU_TIMERARG_IDENTREQ) !=
-				    0L) {
-					if ((pNodeInfo->
-					     m_wFlags &
-					     EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
-					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) {	// this is an old (already deleted or modified) timer
-						// but not the current timer
-						// so discard it
-						EPL_NMTMNU_DBG_POST_TRACE_VALUE
-						    (kEplNmtMnuIntNodeEventTimerIdentReq,
-						     uiNodeId,
-						     ((pNodeInfo->
-						       m_NodeState << 8)
-						      | 0xFF));
-
-						break;
-					}
-/*
-                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerIdentReq,
-                                                    uiNodeId,
-                                                    ((pNodeInfo->m_NodeState << 8)
-                                                     | 0x80
-                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
-                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
-*/
-					Ret =
-					    EplNmtMnuProcessInternalEvent
-					    (uiNodeId,
-					     (tEplNmtState) (bNmtState |
-							     EPL_NMT_TYPE_CS),
-					     EPL_E_NO_ERROR,
-					     kEplNmtMnuIntNodeEventTimerIdentReq);
-				}
-
-				else if ((pTimerEventArg->
-					  m_ulArg & EPL_NMTMNU_TIMERARG_STATREQ)
-					 != 0L) {
-					if ((pNodeInfo->
-					     m_wFlags &
-					     EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
-					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) {	// this is an old (already deleted or modified) timer
-						// but not the current timer
-						// so discard it
-						EPL_NMTMNU_DBG_POST_TRACE_VALUE
-						    (kEplNmtMnuIntNodeEventTimerStatReq,
-						     uiNodeId,
-						     ((pNodeInfo->
-						       m_NodeState << 8)
-						      | 0xFF));
-
-						break;
-					}
-/*
-                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
-                                                    uiNodeId,
-                                                    ((pNodeInfo->m_NodeState << 8)
-                                                     | 0x80
-                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
-                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
-*/
-					Ret =
-					    EplNmtMnuProcessInternalEvent
-					    (uiNodeId,
-					     (tEplNmtState) (bNmtState |
-							     EPL_NMT_TYPE_CS),
-					     EPL_E_NO_ERROR,
-					     kEplNmtMnuIntNodeEventTimerStatReq);
-				}
-
-				else if ((pTimerEventArg->
-					  m_ulArg &
-					  EPL_NMTMNU_TIMERARG_STATE_MON) !=
-					 0L) {
-					if ((pNodeInfo->
-					     m_wFlags &
-					     EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
-					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) {	// this is an old (already deleted or modified) timer
-						// but not the current timer
-						// so discard it
-						EPL_NMTMNU_DBG_POST_TRACE_VALUE
-						    (kEplNmtMnuIntNodeEventTimerStateMon,
-						     uiNodeId,
-						     ((pNodeInfo->
-						       m_NodeState << 8)
-						      | 0xFF));
-
-						break;
-					}
-/*
-                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
-                                                    uiNodeId,
-                                                    ((pNodeInfo->m_NodeState << 8)
-                                                     | 0x80
-                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
-                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
-*/
-					Ret =
-					    EplNmtMnuProcessInternalEvent
-					    (uiNodeId,
-					     (tEplNmtState) (bNmtState |
-							     EPL_NMT_TYPE_CS),
-					     EPL_E_NO_ERROR,
-					     kEplNmtMnuIntNodeEventTimerStateMon);
-				}
-
-				else if ((pTimerEventArg->
-					  m_ulArg & EPL_NMTMNU_TIMERARG_LONGER)
-					 != 0L) {
-					if ((pNodeInfo->
-					     m_wFlags &
-					     EPL_NMTMNU_NODE_FLAG_COUNT_LONGER)
-					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO)) {	// this is an old (already deleted or modified) timer
-						// but not the current timer
-						// so discard it
-						EPL_NMTMNU_DBG_POST_TRACE_VALUE
-						    (kEplNmtMnuIntNodeEventTimerLonger,
-						     uiNodeId,
-						     ((pNodeInfo->
-						       m_NodeState << 8)
-						      | 0xFF));
-
-						break;
-					}
-/*
-                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerLonger,
-                                                    uiNodeId,
-                                                    ((pNodeInfo->m_NodeState << 8)
-                                                     | 0x80
-                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) >> 6)
-                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO) >> 8)));
-*/
-					Ret =
-					    EplNmtMnuProcessInternalEvent
-					    (uiNodeId,
-					     (tEplNmtState) (bNmtState |
-							     EPL_NMT_TYPE_CS),
-					     EPL_E_NO_ERROR,
-					     kEplNmtMnuIntNodeEventTimerLonger);
-				}
-
-			} else {	// global timer event
-			}
-			break;
-		}
-
-	case kEplEventTypeHeartbeat:
-		{
-			tEplHeartbeatEvent *pHeartbeatEvent =
-			    (tEplHeartbeatEvent *) pEvent_p->m_pArg;
-
-			Ret =
-			    EplNmtMnuProcessInternalEvent(pHeartbeatEvent->
-							  m_uiNodeId,
-							  pHeartbeatEvent->
-							  m_NmtState,
-							  pHeartbeatEvent->
-							  m_wErrorCode,
-							  kEplNmtMnuIntNodeEventHeartbeat);
-			break;
-		}
-
-	case kEplEventTypeNmtMnuNmtCmdSent:
-		{
-			tEplFrame *pFrame = (tEplFrame *) pEvent_p->m_pArg;
-			unsigned int uiNodeId;
-			tEplNmtCommand NmtCommand;
-			u8 bNmtState;
-
-			uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
-			NmtCommand =
-			    (tEplNmtCommand) AmiGetByteFromLe(&pFrame->m_Data.
-							      m_Asnd.m_Payload.
-							      m_NmtCommandService.
-							      m_le_bNmtCommandId);
-
-			switch (NmtCommand) {
-			case kEplNmtCmdStartNode:
-				bNmtState =
-				    (u8) (kEplNmtCsOperational & 0xFF);
-				break;
-
-			case kEplNmtCmdStopNode:
-				bNmtState = (u8) (kEplNmtCsStopped & 0xFF);
-				break;
-
-			case kEplNmtCmdEnterPreOperational2:
-				bNmtState =
-				    (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 =
-				    (u8) (kEplNmtCsPreOperational2 & 0xFF);
-				break;
-
-			case kEplNmtCmdResetNode:
-			case kEplNmtCmdResetCommunication:
-			case kEplNmtCmdResetConfiguration:
-			case kEplNmtCmdSwReset:
-				bNmtState = (u8) (kEplNmtCsNotActive & 0xFF);
-				// EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown
-				// after next unresponded IdentRequest/StatusRequest
-				break;
-
-			default:
-				goto Exit;
-			}
-
-			// process as internal event which update expected NMT state in OD
-			if (uiNodeId != EPL_C_ADR_BROADCAST) {
-				Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
-								    (tEplNmtState)
-								    (bNmtState |
-								     EPL_NMT_TYPE_CS),
-								    0,
-								    kEplNmtMnuIntNodeEventNmtCmdSent);
-
-			} else {	// process internal event for all active nodes (except myself)
-
-				for (uiNodeId = 1;
-				     uiNodeId <=
-				     tabentries(EplNmtMnuInstance_g.
-						m_aNodeInfo); uiNodeId++) {
-					if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId)->
-					     m_dwNodeCfg &
-					     (EPL_NODEASSIGN_NODE_IS_CN |
-					      EPL_NODEASSIGN_NODE_EXISTS)) !=
-					    0) {
-						Ret =
-						    EplNmtMnuProcessInternalEvent
-						    (uiNodeId,
-						     (tEplNmtState) (bNmtState |
-								     EPL_NMT_TYPE_CS),
-						     0,
-						     kEplNmtMnuIntNodeEventNmtCmdSent);
-
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-					}
-				}
-			}
-
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplNmtInvalidEvent;
-		}
-
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuGetRunningTimerStatReq
-//
-// Description: returns a bit field with running StatReq timers
-//              just for debugging purposes
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int *puiMandatorySlaveCount_p,
-				      unsigned int *puiSignalSlaveCount_p,
-				      u16 *pwFlags_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if ((puiMandatorySlaveCount_p == NULL)
-	    || (puiSignalSlaveCount_p == NULL)
-	    || (pwFlags_p == NULL)) {
-		Ret = kEplNmtInvalidParam;
-		goto Exit;
-	}
-
-	*puiMandatorySlaveCount_p = EplNmtMnuInstance_g.m_uiMandatorySlaveCount;
-	*puiSignalSlaveCount_p = EplNmtMnuInstance_g.m_uiSignalSlaveCount;
-	*pwFlags_p = EplNmtMnuInstance_g.m_wFlags;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuGetRunningTimerStatReq
-//
-// Description: returns a bit field with running StatReq timers
-//              just for debugging purposes
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-/*
-u32 EplNmtMnuGetRunningTimerStatReq(void)
-{
-tEplKernel      Ret = kEplSuccessful;
-unsigned int    uiIndex;
-tEplNmtMnuNodeInfo* pNodeInfo;
-
-    pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
-    for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++)
-    {
-        if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateConfigured)
-        {
-            // reset flag "scanned once"
-            pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_SCANNED;
-
-            Ret = EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
-            if (Ret != kEplSuccessful)
-            {
-                goto Exit;
-            }
-            EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
-            // signal slave counter shall be decremented if StatusRequest was sent once to a CN
-            // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
-        }
-    }
-
-Exit:
-    return Ret;
-}
-*/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuCbNmtRequest
-//
-// Description: callback funktion for NmtRequest
-//
-// Parameters:  pFrameInfo_p            = Frame with the NmtRequest
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// $$$ perform NMTRequest
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuCbIdentResponse
-//
-// Description: callback funktion for IdentResponse
-//
-// Parameters:  uiNodeId_p              = node ID for which IdentReponse was received
-//              pIdentResponse_p        = pointer to IdentResponse
-//                                        is NULL if node did not answer
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
-					   tEplIdentResponse *pIdentResponse_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (pIdentResponse_p == NULL) {	// node did not answer
-		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_IDENT_RES,	// was EPL_E_NO_ERROR
-						    kEplNmtMnuIntNodeEventNoIdentResponse);
-	} else {		// node answered IdentRequest
-		tEplObdSize ObdSize;
-		u32 dwDevType;
-		u16 wErrorCode = EPL_E_NO_ERROR;
-		tEplNmtState NmtState =
-		    (tEplNmtState) (AmiGetByteFromLe
-				    (&pIdentResponse_p->
-				     m_le_bNmtStatus) | EPL_NMT_TYPE_CS);
-
-		// check IdentResponse $$$ move to ProcessIntern, because this function may be called also if CN
-
-		// check DeviceType (0x1F84)
-		ObdSize = 4;
-		Ret =
-		    EplObduReadEntry(0x1F84, uiNodeId_p, &dwDevType, &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		if (dwDevType != 0L) {	// actually compare it with DeviceType from IdentResponse
-			if (AmiGetDwordFromLe(&pIdentResponse_p->m_le_dwDeviceType) != dwDevType) {	// wrong DeviceType
-				NmtState = kEplNmtCsNotActive;
-				wErrorCode = EPL_E_NMT_BPO1_DEVICE_TYPE;
-			}
-		}
-
-		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
-						    NmtState,
-						    wErrorCode,
-						    kEplNmtMnuIntNodeEventIdentResponse);
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuCbStatusResponse
-//
-// Description: callback funktion for StatusResponse
-//
-// Parameters:  uiNodeId_p              = node ID for which IdentReponse was received
-//              pIdentResponse_p        = pointer to IdentResponse
-//                                        is NULL if node did not answer
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
-					    tEplStatusResponse *pStatusResponse_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (pStatusResponse_p == NULL) {	// node did not answer
-		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_STATUS_RES,	// was EPL_E_NO_ERROR
-						    kEplNmtMnuIntNodeEventNoStatusResponse);
-	} else {		// node answered StatusRequest
-		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
-						    (tEplNmtState)
-						    (AmiGetByteFromLe
-						     (&pStatusResponse_p->
-						      m_le_bNmtStatus) |
-						     EPL_NMT_TYPE_CS),
-						    EPL_E_NO_ERROR,
-						    kEplNmtMnuIntNodeEventStatusResponse);
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuStartBootStep1
-//
-// Description: starts BootStep1
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuStartBootStep1(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiSubIndex;
-	unsigned int uiLocalNodeId;
-	u32 dwNodeCfg;
-	tEplObdSize ObdSize;
-
-	// $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32
-
-	// start network scan
-	EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
-	EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
-	// check 0x1F81
-	uiLocalNodeId = EplObduGetNodeId();
-	for (uiSubIndex = 1; uiSubIndex <= 254; uiSubIndex++) {
-		ObdSize = 4;
-		Ret =
-		    EplObduReadEntry(0x1F81, uiSubIndex, &dwNodeCfg, &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		if (uiSubIndex != uiLocalNodeId) {
-			// reset flags "not scanned" and "isochronous"
-			EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags &=
-			    ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON |
-			      EPL_NMTMNU_NODE_FLAG_NOT_SCANNED);
-
-			if (uiSubIndex == EPL_C_ADR_DIAG_DEF_NODE_ID) {	// diagnostic node must be scanned by MN in any case
-				dwNodeCfg |=
-				    (EPL_NODEASSIGN_NODE_IS_CN |
-				     EPL_NODEASSIGN_NODE_EXISTS);
-				// and it must be isochronously accessed
-				dwNodeCfg &= ~EPL_NODEASSIGN_ASYNCONLY_NODE;
-			}
-			// save node config in local node info structure
-			EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_dwNodeCfg =
-			    dwNodeCfg;
-			EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_NodeState =
-			    kEplNmtMnuNodeStateUnknown;
-
-			if ((dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS)) != 0) {	// node is configured as CN
-				// identify the node
-				Ret =
-				    EplIdentuRequestIdentResponse(uiSubIndex,
-								  EplNmtMnuCbIdentResponse);
-				if (Ret != kEplSuccessful) {
-					goto Exit;
-				}
-				// set flag "not scanned"
-				EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags |=
-				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
-				// signal slave counter shall be decremented if IdentRequest was sent once to a CN
-
-				if ((dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
-					EplNmtMnuInstance_g.
-					    m_uiMandatorySlaveCount++;
-					// mandatory slave counter shall be decremented if mandatory CN was configured successfully
-				}
-			}
-		} else {	// subindex of MN
-			if ((dwNodeCfg & (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS)) != 0) {	// MN shall send PRes
-				tEplDllNodeInfo DllNodeInfo;
-
-				EPL_MEMSET(&DllNodeInfo, 0,
-					   sizeof(DllNodeInfo));
-				DllNodeInfo.m_uiNodeId = uiLocalNodeId;
-
-				Ret = EplDlluCalAddNode(&DllNodeInfo);
-			}
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuStartBootStep2
-//
-// Description: starts BootStep2.
-//              That means add nodes to isochronous phase and send
-//              NMT EnableReadyToOp.
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuStartBootStep2(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiIndex;
-	tEplNmtMnuNodeInfo *pNodeInfo;
-
-	if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) {	// boot process is not halted
-		// add nodes to isochronous phase and send NMT EnableReadyToOp
-		EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
-		EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
-		// reset flag that application was informed about possible state change
-		EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
-
-		pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
-		for (uiIndex = 1;
-		     uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
-		     uiIndex++, pNodeInfo++) {
-			if (pNodeInfo->m_NodeState ==
-			    kEplNmtMnuNodeStateConfigured) {
-				Ret =
-				    EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
-				if (Ret != kEplSuccessful) {
-					goto Exit;
-				}
-				// set flag "not scanned"
-				pNodeInfo->m_wFlags |=
-				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-
-				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
-				// signal slave counter shall be decremented if StatusRequest was sent once to a CN
-
-				if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
-					EplNmtMnuInstance_g.
-					    m_uiMandatorySlaveCount++;
-				}
-				// mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
-			}
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuNodeBootStep2
-//
-// Description: starts BootStep2 for the specified node.
-//              This means the CN is added to isochronous phase if not
-//              async-only and it gets the NMT command EnableReadyToOp.
-//              The CN must be in node state Configured, when it enters
-//              BootStep2. When BootStep2 finishes, the CN is in node state
-//              ReadyToOp.
-//              If TimeoutReadyToOp in object 0x1F89/5 is configured,
-//              TimerHdlLonger will be started with this timeout.
-//
-// Parameters:  uiNodeId_p              = node ID
-//              pNodeInfo_p             = pointer to internal node info structure
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
-					 tEplNmtMnuNodeInfo * pNodeInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplDllNodeInfo DllNodeInfo;
-	u32 dwNodeCfg;
-	tEplObdSize ObdSize;
-	tEplTimerArg TimerArg;
-
-	dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
-	if ((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0) {	// add node to isochronous phase
-		DllNodeInfo.m_uiNodeId = uiNodeId_p;
-		ObdSize = 4;
-		Ret =
-		    EplObduReadEntry(0x1F92, uiNodeId_p,
-				     &DllNodeInfo.m_dwPresTimeout, &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		ObdSize = 2;
-		Ret =
-		    EplObduReadEntry(0x1F8B, uiNodeId_p,
-				     &DllNodeInfo.m_wPreqPayloadLimit,
-				     &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		ObdSize = 2;
-		Ret =
-		    EplObduReadEntry(0x1F8D, uiNodeId_p,
-				     &DllNodeInfo.m_wPresPayloadLimit,
-				     &ObdSize);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		pNodeInfo_p->m_wFlags |= EPL_NMTMNU_NODE_FLAG_ISOCHRON;
-
-		Ret = EplDlluCalAddNode(&DllNodeInfo);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-	}
-
-	EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
-					uiNodeId_p,
-					kEplNmtCmdEnableReadyToOperate);
-
-	Ret =
-	    EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdEnableReadyToOperate);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	if (EplNmtMnuInstance_g.m_ulTimeoutReadyToOp != 0L) {	// start timer
-		// when the timer expires the CN must be ReadyToOp
-		EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p,
-						     TimerArg);
-//        TimerArg.m_EventSink = kEplEventSinkNmtMnu;
-//        TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
-		Ret =
-		    EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger,
-					   EplNmtMnuInstance_g.
-					   m_ulTimeoutReadyToOp, TimerArg);
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuStartCheckCom
-//
-// Description: starts CheckCommunication
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuStartCheckCom(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiIndex;
-	tEplNmtMnuNodeInfo *pNodeInfo;
-
-	if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) {	// boot process is not halted
-		// wait some time and check that no communication error occurs
-		EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
-		EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
-		// reset flag that application was informed about possible state change
-		EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
-
-		pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
-		for (uiIndex = 1;
-		     uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
-		     uiIndex++, pNodeInfo++) {
-			if (pNodeInfo->m_NodeState ==
-			    kEplNmtMnuNodeStateReadyToOp) {
-				Ret = EplNmtMnuNodeCheckCom(uiIndex, pNodeInfo);
-				if (Ret == kEplReject) {	// timer was started
-					// wait until it expires
-					if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
-						EplNmtMnuInstance_g.
-						    m_uiMandatorySlaveCount++;
-					}
-				} else if (Ret != kEplSuccessful) {
-					goto Exit;
-				}
-				// set flag "not scanned"
-				pNodeInfo->m_wFlags |=
-				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-
-				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
-				// signal slave counter shall be decremented if timeout elapsed and regardless of an error
-				// mandatory slave counter shall be decremented if timeout elapsed and no error occured
-			}
-		}
-	}
-
-	Ret = kEplSuccessful;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuNodeCheckCom
-//
-// Description: checks communication of the specified node.
-//              That means wait some time and if no error occured everything
-//              is OK.
-//
-// Parameters:  uiNodeId_p              = node ID
-//              pNodeInfo_p             = pointer to internal node info structure
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
-					tEplNmtMnuNodeInfo * pNodeInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	u32 dwNodeCfg;
-	tEplTimerArg TimerArg;
-
-	dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
-	if (((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0)
-	    && (EplNmtMnuInstance_g.m_ulTimeoutCheckCom != 0L)) {	// CN is not async-only and timeout for CheckCom was set
-
-		// check communication,
-		// that means wait some time and if no error occured everything is OK;
-
-		// start timer (when the timer expires the CN must be still ReadyToOp)
-		EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p,
-						     TimerArg);
-//        TimerArg.m_EventSink = kEplEventSinkNmtMnu;
-//        TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
-		Ret =
-		    EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger,
-					   EplNmtMnuInstance_g.
-					   m_ulTimeoutCheckCom, TimerArg);
-
-		// update mandatory slave counter, because timer was started
-		if (Ret == kEplSuccessful) {
-			Ret = kEplReject;
-		}
-	} else {		// timer was not started
-		// assume everything is OK
-		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateComChecked;
-	}
-
-//Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuStartNodes
-//
-// Description: really starts all nodes which are ReadyToOp and CheckCom did not fail
-//
-// Parameters:  (none)
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuStartNodes(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiIndex;
-	tEplNmtMnuNodeInfo *pNodeInfo;
-
-	if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) {	// boot process is not halted
-		// send NMT command Start Node
-		EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
-		EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
-		// reset flag that application was informed about possible state change
-		EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
-
-		pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
-		for (uiIndex = 1;
-		     uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
-		     uiIndex++, pNodeInfo++) {
-			if (pNodeInfo->m_NodeState ==
-			    kEplNmtMnuNodeStateComChecked) {
-				if ((EplNmtMnuInstance_g.
-				     m_dwNmtStartup & EPL_NMTST_STARTALLNODES)
-				    == 0) {
-					EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
-									uiIndex,
-									kEplNmtCmdStartNode);
-
-					Ret =
-					    EplNmtMnuSendNmtCommand(uiIndex,
-								    kEplNmtCmdStartNode);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-				}
-
-				if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
-					EplNmtMnuInstance_g.
-					    m_uiMandatorySlaveCount++;
-				}
-				// set flag "not scanned"
-				pNodeInfo->m_wFlags |=
-				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-
-				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
-				// signal slave counter shall be decremented if StatusRequest was sent once to a CN
-				// mandatory slave counter shall be decremented if mandatory CN is OPERATIONAL
-			}
-		}
-
-		// $$$ inform application if EPL_NMTST_NO_STARTNODE is set
-
-		if ((EplNmtMnuInstance_g.
-		     m_dwNmtStartup & EPL_NMTST_STARTALLNODES) != 0) {
-			EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, EPL_C_ADR_BROADCAST,
-							kEplNmtCmdStartNode);
-
-			Ret =
-			    EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST,
-						    kEplNmtCmdStartNode);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuProcessInternalEvent
-//
-// Description: processes internal node events
-//
-// Parameters:  uiNodeId_p              = node ID
-//              NodeNmtState_p          = NMT state of CN
-//              NodeEvent_p             = occured events
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
-						tEplNmtState NodeNmtState_p,
-						u16 wErrorCode_p,
-						tEplNmtMnuIntNodeEvent
-						NodeEvent_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplNmtState NmtState;
-	tEplNmtMnuNodeInfo *pNodeInfo;
-	tEplTimerArg TimerArg;
-
-	pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId_p);
-	NmtState = EplNmtuGetNmtState();
-	if (NmtState <= kEplNmtMsNotActive) {	// MN is not active
-		goto Exit;
-	}
-
-	switch (NodeEvent_p) {
-	case kEplNmtMnuIntNodeEventIdentResponse:
-		{
-			u8 bNmtState;
-
-			EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
-							uiNodeId_p,
-							pNodeInfo->m_NodeState);
-
-			if (pNodeInfo->m_NodeState !=
-			    kEplNmtMnuNodeStateResetConf) {
-				pNodeInfo->m_NodeState =
-				    kEplNmtMnuNodeStateIdentified;
-			}
-			// reset flags ISOCHRON and NMT_CMD_ISSUED
-			pNodeInfo->m_wFlags &= ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON
-						 |
-						 EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED);
-
-			if ((NmtState == kEplNmtMsPreOperational1)
-			    &&
-			    ((pNodeInfo->
-			      m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
-			     0)) {
-				// decrement only signal slave count
-				EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
-				pNodeInfo->m_wFlags &=
-				    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-			}
-			// update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2)
-			bNmtState = (u8) (kEplNmtCsPreOperational1 & 0xFF);
-			Ret =
-			    EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
-					      1);
-
-			// check NMT state of CN
-			Ret =
-			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
-						   NodeNmtState_p, wErrorCode_p,
-						   NmtState);
-			if (Ret != kEplSuccessful) {
-				if (Ret == kEplReject) {
-					Ret = kEplSuccessful;
-				}
-				break;
-			}
-			// request StatusResponse immediately,
-			// because we want a fast boot-up of CNs
-			Ret =
-			    EplStatusuRequestStatusResponse(uiNodeId_p,
-							    EplNmtMnuCbStatusResponse);
-			if (Ret != kEplSuccessful) {
-				EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
-								uiNodeId_p,
-								Ret);
-
-				if (Ret == kEplInvalidOperation) {	// the only situation when this should happen is, when
-					// StatusResponse was already requested from within
-					// the StatReq timer event.
-					// so ignore this error.
-					Ret = kEplSuccessful;
-				} else {
-					break;
-				}
-			}
-
-			if (pNodeInfo->m_NodeState !=
-			    kEplNmtMnuNodeStateResetConf) {
-				// inform application
-				Ret =
-				    EplNmtMnuInstance_g.
-				    m_pfnCbNodeEvent(uiNodeId_p,
-						     kEplNmtNodeEventFound,
-						     NodeNmtState_p,
-						     EPL_E_NO_ERROR,
-						     (pNodeInfo->
-						      m_dwNodeCfg &
-						      EPL_NODEASSIGN_MANDATORY_CN)
-						     != 0);
-				if (Ret == kEplReject) {	// interrupt boot process on user request
-					EPL_NMTMNU_DBG_POST_TRACE_VALUE
-					    (NodeEvent_p, uiNodeId_p,
-					     ((pNodeInfo->m_NodeState << 8)
-					      | Ret));
-
-					Ret = kEplSuccessful;
-					break;
-				} else if (Ret != kEplSuccessful) {
-					EPL_NMTMNU_DBG_POST_TRACE_VALUE
-					    (NodeEvent_p, uiNodeId_p,
-					     ((pNodeInfo->m_NodeState << 8)
-					      | Ret));
-
-					break;
-				}
-			}
-			// continue BootStep1
-		}
-
-	case kEplNmtMnuIntNodeEventBoot:
-		{
-
-			// $$$ check identification (vendor ID, product code, revision no, serial no)
-
-			if (pNodeInfo->m_NodeState ==
-			    kEplNmtMnuNodeStateIdentified) {
-				// $$$ check software
-
-				// check/start configuration
-				// inform application
-				Ret =
-				    EplNmtMnuInstance_g.
-				    m_pfnCbNodeEvent(uiNodeId_p,
-						     kEplNmtNodeEventCheckConf,
-						     NodeNmtState_p,
-						     EPL_E_NO_ERROR,
-						     (pNodeInfo->
-						      m_dwNodeCfg &
-						      EPL_NODEASSIGN_MANDATORY_CN)
-						     != 0);
-				if (Ret == kEplReject) {	// interrupt boot process on user request
-					EPL_NMTMNU_DBG_POST_TRACE_VALUE
-					    (kEplNmtMnuIntNodeEventBoot,
-					     uiNodeId_p,
-					     ((pNodeInfo->m_NodeState << 8)
-					      | Ret));
-
-					Ret = kEplSuccessful;
-					break;
-				} else if (Ret != kEplSuccessful) {
-					EPL_NMTMNU_DBG_POST_TRACE_VALUE
-					    (kEplNmtMnuIntNodeEventBoot,
-					     uiNodeId_p,
-					     ((pNodeInfo->m_NodeState << 8)
-					      | Ret));
-
-					break;
-				}
-			} else if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf) {	// wrong CN state
-				// ignore event
-				break;
-			}
-			// $$$ d.k.: currently we assume configuration is OK
-
-			// continue BootStep1
-		}
-
-	case kEplNmtMnuIntNodeEventConfigured:
-		{
-			if ((pNodeInfo->m_NodeState !=
-			     kEplNmtMnuNodeStateIdentified)
-			    && (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)) {	// wrong CN state
-				// ignore event
-				break;
-			}
-
-			pNodeInfo->m_NodeState = kEplNmtMnuNodeStateConfigured;
-
-			if (NmtState == kEplNmtMsPreOperational1) {
-				if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// decrement mandatory CN counter
-					EplNmtMnuInstance_g.
-					    m_uiMandatorySlaveCount--;
-				}
-			} else {
-				// put optional node to next step (BootStep2)
-				Ret =
-				    EplNmtMnuNodeBootStep2(uiNodeId_p,
-							   pNodeInfo);
-			}
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventNoIdentResponse:
-		{
-			if ((NmtState == kEplNmtMsPreOperational1)
-			    &&
-			    ((pNodeInfo->
-			      m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
-			     0)) {
-				// decrement only signal slave count
-				EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
-				pNodeInfo->m_wFlags &=
-				    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-			}
-
-			if (pNodeInfo->m_NodeState !=
-			    kEplNmtMnuNodeStateResetConf) {
-				pNodeInfo->m_NodeState =
-				    kEplNmtMnuNodeStateUnknown;
-			}
-			// $$$ d.k. check start time for 0x1F89/2 MNTimeoutPreOp1_U32
-			// $$$ d.k. check individual timeout 0x1F89/6 MNIdentificationTimeout_U32
-			// if mandatory node and timeout elapsed -> halt boot procedure
-			// trigger IdentRequest again (if >= PreOp2, after delay)
-			if (NmtState >= kEplNmtMsPreOperational2) {	// start timer
-				EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ
-				    (pNodeInfo, uiNodeId_p, TimerArg);
-//                TimerArg.m_EventSink = kEplEventSinkNmtMnu;
-//                TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p;
-/*
-                EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventNoIdentResponse,
-                                                uiNodeId_p,
-                                                ((pNodeInfo->m_NodeState << 8)
-                                                 | 0x80
-                                                 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
-                                                 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
-*/
-				Ret =
-				    EplTimeruModifyTimerMs(&pNodeInfo->
-							   m_TimerHdlStatReq,
-							   EplNmtMnuInstance_g.
-							   m_ulStatusRequestDelay,
-							   TimerArg);
-			} else {	// trigger IdentRequest immediately
-				Ret =
-				    EplIdentuRequestIdentResponse(uiNodeId_p,
-								  EplNmtMnuCbIdentResponse);
-			}
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventStatusResponse:
-		{
-			if ((NmtState >= kEplNmtMsPreOperational2)
-			    &&
-			    ((pNodeInfo->
-			      m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
-			     0)) {
-				// decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
-				EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
-				pNodeInfo->m_wFlags &=
-				    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-			}
-			// check NMT state of CN
-			Ret =
-			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
-						   NodeNmtState_p, wErrorCode_p,
-						   NmtState);
-			if (Ret != kEplSuccessful) {
-				if (Ret == kEplReject) {
-					Ret = kEplSuccessful;
-				}
-				break;
-			}
-
-			if (NmtState == kEplNmtMsPreOperational1) {
-				// request next StatusResponse immediately
-				Ret =
-				    EplStatusuRequestStatusResponse(uiNodeId_p,
-								    EplNmtMnuCbStatusResponse);
-				if (Ret != kEplSuccessful) {
-					EPL_NMTMNU_DBG_POST_TRACE_VALUE
-					    (NodeEvent_p, uiNodeId_p, Ret);
-				}
-
-			} else if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_ISOCHRON) == 0) {	// start timer
-				// not isochronously accessed CN (e.g. async-only or stopped CN)
-				EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo,
-								      uiNodeId_p,
-								      TimerArg);
-//                TimerArg.m_EventSink = kEplEventSinkNmtMnu;
-//                TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p;
-/*
-                EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventStatusResponse,
-                                                uiNodeId_p,
-                                                ((pNodeInfo->m_NodeState << 8)
-                                                 | 0x80
-                                                 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
-                                                 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
-*/
-				Ret =
-				    EplTimeruModifyTimerMs(&pNodeInfo->
-							   m_TimerHdlStatReq,
-							   EplNmtMnuInstance_g.
-							   m_ulStatusRequestDelay,
-							   TimerArg);
-			}
-
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventNoStatusResponse:
-		{
-			// function CheckNmtState sets node state to unknown if necessary
-/*
-            if ((NmtState >= kEplNmtMsPreOperational2)
-                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
-            {
-                // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
-                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
-                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-            }
-*/
-			// check NMT state of CN
-			Ret =
-			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
-						   NodeNmtState_p, wErrorCode_p,
-						   NmtState);
-			if (Ret != kEplSuccessful) {
-				if (Ret == kEplReject) {
-					Ret = kEplSuccessful;
-				}
-				break;
-			}
-
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventError:
-		{		// currently only issued on kEplNmtNodeCommandConfErr
-
-			if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) {	// wrong CN state
-				// ignore event
-				break;
-			}
-			// check NMT state of CN
-			Ret =
-			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
-						   kEplNmtCsNotActive,
-						   wErrorCode_p, NmtState);
-			if (Ret != kEplSuccessful) {
-				if (Ret == kEplReject) {
-					Ret = kEplSuccessful;
-				}
-				break;
-			}
-
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventExecReset:
-		{
-			if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) {	// wrong CN state
-				// ignore event
-				break;
-			}
-
-			pNodeInfo->m_NodeState = kEplNmtMnuNodeStateResetConf;
-
-			EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
-							uiNodeId_p,
-							(((NodeNmtState_p &
-							   0xFF) << 8)
-							 |
-							 kEplNmtCmdResetConfiguration));
-
-			// send NMT reset configuration to CN for activation of configuration
-			Ret =
-			    EplNmtMnuSendNmtCommand(uiNodeId_p,
-						    kEplNmtCmdResetConfiguration);
-
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventHeartbeat:
-		{
-/*
-            if ((NmtState >= kEplNmtMsPreOperational2)
-                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
-            {
-                // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
-                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
-                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-            }
-*/
-			// check NMT state of CN
-			Ret =
-			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
-						   NodeNmtState_p, wErrorCode_p,
-						   NmtState);
-			if (Ret != kEplSuccessful) {
-				if (Ret == kEplReject) {
-					Ret = kEplSuccessful;
-				}
-				break;
-			}
-
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventTimerIdentReq:
-		{
-			EPL_DBGLVL_NMTMN_TRACE1
-			    ("TimerStatReq->IdentReq(%02X)\n", uiNodeId_p);
-			// trigger IdentRequest again
-			Ret =
-			    EplIdentuRequestIdentResponse(uiNodeId_p,
-							  EplNmtMnuCbIdentResponse);
-			if (Ret != kEplSuccessful) {
-				EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
-								uiNodeId_p,
-								(((NodeNmtState_p & 0xFF) << 8)
-								 | Ret));
-				if (Ret == kEplInvalidOperation) {	// this can happen because of a bug in EplTimeruLinuxKernel.c
-					// so ignore this error.
-					Ret = kEplSuccessful;
-				}
-			}
-
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventTimerStateMon:
-		{
-			// reset NMT state change flag
-			// because from now on the CN must have the correct NMT state
-			pNodeInfo->m_wFlags &=
-			    ~EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;
-
-			// continue with normal StatReq processing
-		}
-
-	case kEplNmtMnuIntNodeEventTimerStatReq:
-		{
-			EPL_DBGLVL_NMTMN_TRACE1("TimerStatReq->StatReq(%02X)\n",
-						uiNodeId_p);
-			// request next StatusResponse
-			Ret =
-			    EplStatusuRequestStatusResponse(uiNodeId_p,
-							    EplNmtMnuCbStatusResponse);
-			if (Ret != kEplSuccessful) {
-				EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
-								uiNodeId_p,
-								(((NodeNmtState_p & 0xFF) << 8)
-								 | Ret));
-				if (Ret == kEplInvalidOperation) {	// the only situation when this should happen is, when
-					// StatusResponse was already requested while processing
-					// event IdentResponse.
-					// so ignore this error.
-					Ret = kEplSuccessful;
-				}
-			}
-
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventTimerLonger:
-		{
-			switch (pNodeInfo->m_NodeState) {
-			case kEplNmtMnuNodeStateConfigured:
-				{	// node should be ReadyToOp but it is not
-
-					// check NMT state which shall be intentionally wrong, so that ERROR_TREATMENT will be started
-					Ret =
-					    EplNmtMnuCheckNmtState(uiNodeId_p,
-								   pNodeInfo,
-								   kEplNmtCsNotActive,
-								   EPL_E_NMT_BPO2,
-								   NmtState);
-					if (Ret != kEplSuccessful) {
-						if (Ret == kEplReject) {
-							Ret = kEplSuccessful;
-						}
-						break;
-					}
-
-					break;
-				}
-
-			case kEplNmtMnuNodeStateReadyToOp:
-				{	// CheckCom finished successfully
-
-					pNodeInfo->m_NodeState =
-					    kEplNmtMnuNodeStateComChecked;
-
-					if ((pNodeInfo->
-					     m_wFlags &
-					     EPL_NMTMNU_NODE_FLAG_NOT_SCANNED)
-					    != 0) {
-						// decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
-						EplNmtMnuInstance_g.
-						    m_uiSignalSlaveCount--;
-						pNodeInfo->m_wFlags &=
-						    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-					}
-
-					if ((pNodeInfo->
-					     m_dwNodeCfg &
-					     EPL_NODEASSIGN_MANDATORY_CN) !=
-					    0) {
-						// decrement mandatory slave counter
-						EplNmtMnuInstance_g.
-						    m_uiMandatorySlaveCount--;
-					}
-					if (NmtState != kEplNmtMsReadyToOperate) {
-						EPL_NMTMNU_DBG_POST_TRACE_VALUE
-						    (NodeEvent_p, uiNodeId_p,
-						     (((NodeNmtState_p & 0xFF)
-						       << 8)
-						      | kEplNmtCmdStartNode));
-
-						// start optional CN
-						Ret =
-						    EplNmtMnuSendNmtCommand
-						    (uiNodeId_p,
-						     kEplNmtCmdStartNode);
-					}
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-			}
-			break;
-		}
-
-	case kEplNmtMnuIntNodeEventNmtCmdSent:
-		{
-			u8 bNmtState;
-
-			// update expected NMT state with the one that results
-			// from the sent NMT command
-			bNmtState = (u8) (NodeNmtState_p & 0xFF);
-
-			// write object 0x1F8F NMT_MNNodeExpState_AU8
-			Ret =
-			    EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
-					      1);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-
-			if (NodeNmtState_p == kEplNmtCsNotActive) {	// restart processing with IdentRequest
-				EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ
-				    (pNodeInfo, uiNodeId_p, TimerArg);
-			} else {	// monitor NMT state change with StatusRequest after
-				// the corresponding delay;
-				// until then wrong NMT states will be ignored
-				EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON
-				    (pNodeInfo, uiNodeId_p, TimerArg);
-
-				// set NMT state change flag
-				pNodeInfo->m_wFlags |=
-				    EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;
-			}
-
-			Ret =
-			    EplTimeruModifyTimerMs(&pNodeInfo->
-						   m_TimerHdlStatReq,
-						   EplNmtMnuInstance_g.
-						   m_ulStatusRequestDelay,
-						   TimerArg);
-
-			// finish processing, because NmtState_p is the expected and not the current state
-			goto Exit;
-		}
-
-	default:
-		{
-			break;
-		}
-	}
-
-	// check if network is ready to change local NMT state and this was not done before
-	if ((EplNmtMnuInstance_g.m_wFlags & (EPL_NMTMNU_FLAG_HALTED | EPL_NMTMNU_FLAG_APP_INFORMED)) == 0) {	// boot process is not halted
-		switch (NmtState) {
-		case kEplNmtMsPreOperational1:
-			{
-				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
-				     0)
-				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all optional CNs scanned once and all mandatory CNs configured successfully
-					EplNmtMnuInstance_g.m_wFlags |=
-					    EPL_NMTMNU_FLAG_APP_INFORMED;
-					// inform application
-					Ret =
-					    EplNmtMnuInstance_g.
-					    m_pfnCbBootEvent
-					    (kEplNmtBootEventBootStep1Finish,
-					     NmtState, EPL_E_NO_ERROR);
-					if (Ret != kEplSuccessful) {
-						if (Ret == kEplReject) {
-							// wait for application
-							Ret = kEplSuccessful;
-						}
-						break;
-					}
-					// enter PreOp2
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventAllMandatoryCNIdent);
-				}
-				break;
-			}
-
-		case kEplNmtMsPreOperational2:
-			{
-				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
-				     0)
-				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all optional CNs checked once for ReadyToOp and all mandatory CNs are ReadyToOp
-					EplNmtMnuInstance_g.m_wFlags |=
-					    EPL_NMTMNU_FLAG_APP_INFORMED;
-					// inform application
-					Ret =
-					    EplNmtMnuInstance_g.
-					    m_pfnCbBootEvent
-					    (kEplNmtBootEventBootStep2Finish,
-					     NmtState, EPL_E_NO_ERROR);
-					if (Ret != kEplSuccessful) {
-						if (Ret == kEplReject) {
-							// wait for application
-							Ret = kEplSuccessful;
-						}
-						break;
-					}
-					// enter ReadyToOp
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventEnterReadyToOperate);
-				}
-				break;
-			}
-
-		case kEplNmtMsReadyToOperate:
-			{
-				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
-				     0)
-				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all CNs checked for errorless communication
-					EplNmtMnuInstance_g.m_wFlags |=
-					    EPL_NMTMNU_FLAG_APP_INFORMED;
-					// inform application
-					Ret =
-					    EplNmtMnuInstance_g.
-					    m_pfnCbBootEvent
-					    (kEplNmtBootEventCheckComFinish,
-					     NmtState, EPL_E_NO_ERROR);
-					if (Ret != kEplSuccessful) {
-						if (Ret == kEplReject) {
-							// wait for application
-							Ret = kEplSuccessful;
-						}
-						break;
-					}
-					// enter Operational
-					Ret =
-					    EplNmtuNmtEvent
-					    (kEplNmtEventEnterMsOperational);
-				}
-				break;
-			}
-
-		case kEplNmtMsOperational:
-			{
-				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
-				     0)
-				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all optional CNs scanned once and all mandatory CNs are OPERATIONAL
-					EplNmtMnuInstance_g.m_wFlags |=
-					    EPL_NMTMNU_FLAG_APP_INFORMED;
-					// inform application
-					Ret =
-					    EplNmtMnuInstance_g.
-					    m_pfnCbBootEvent
-					    (kEplNmtBootEventOperational,
-					     NmtState, EPL_E_NO_ERROR);
-					if (Ret != kEplSuccessful) {
-						if (Ret == kEplReject) {
-							// ignore error code
-							Ret = kEplSuccessful;
-						}
-						break;
-					}
-				}
-				break;
-			}
-
-		default:
-			{
-				break;
-			}
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuCheckNmtState
-//
-// Description: checks the NMT state, i.e. evaluates it with object 0x1F8F
-//              NMT_MNNodeExpState_AU8 and updates object 0x1F8E
-//              NMT_MNNodeCurrState_AU8.
-//              It manipulates m_NodeState in internal node info structure.
-//
-// Parameters:  uiNodeId_p              = node ID
-//              NodeNmtState_p          = NMT state of CN
-//
-// Returns:     tEplKernel              = error code
-//                  kEplReject          = CN was in wrong state and has been reset
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
-					 tEplNmtMnuNodeInfo * pNodeInfo_p,
-					 tEplNmtState NodeNmtState_p,
-					 u16 wErrorCode_p,
-					 tEplNmtState LocalNmtState_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplObdSize ObdSize;
-	u8 bNmtState;
-	u8 bNmtStatePrev;
-	tEplNmtState ExpNmtState;
-
-	ObdSize = 1;
-	// read object 0x1F8F NMT_MNNodeExpState_AU8
-	Ret = EplObduReadEntry(0x1F8F, uiNodeId_p, &bNmtState, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// compute expected NMT state
-	ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS);
-	// 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;
-		goto Exit;
-	} else if ((ExpNmtState == kEplNmtCsPreOperational2)
-		   && (NodeNmtState_p == kEplNmtCsReadyToOperate)) {	// CN switched to ReadyToOp
-		// delete timer for timeout handling
-		Ret = EplTimeruDeleteTimer(&pNodeInfo_p->m_TimerHdlLonger);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateReadyToOp;
-
-		// update object 0x1F8F NMT_MNNodeExpState_AU8 to ReadyToOp
-		Ret = EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, 1);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN -> decrement counter
-			EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
-		}
-		if (LocalNmtState_p >= kEplNmtMsReadyToOperate) {	// start procedure CheckCommunication for this node
-			Ret = EplNmtMnuNodeCheckCom(uiNodeId_p, pNodeInfo_p);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-
-			if ((LocalNmtState_p == kEplNmtMsOperational)
-			    && (pNodeInfo_p->m_NodeState ==
-				kEplNmtMnuNodeStateComChecked)) {
-				EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, uiNodeId_p,
-								(((NodeNmtState_p & 0xFF) << 8)
-								 |
-								 kEplNmtCmdStartNode));
-
-				// immediately start optional CN, because communication is always OK (e.g. async-only CN)
-				Ret =
-				    EplNmtMnuSendNmtCommand(uiNodeId_p,
-							    kEplNmtCmdStartNode);
-				if (Ret != kEplSuccessful) {
-					goto Exit;
-				}
-			}
-		}
-
-	} else if ((ExpNmtState == kEplNmtCsReadyToOperate)
-		   && (NodeNmtState_p == kEplNmtCsOperational)) {	// CN switched to OPERATIONAL
-		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateOperational;
-
-		if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN -> decrement counter
-			EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
-		}
-
-	} else if ((ExpNmtState != NodeNmtState_p)
-		   && !((ExpNmtState == kEplNmtCsPreOperational1)
-			&& (NodeNmtState_p == kEplNmtCsPreOperational2))) {	// CN is not in expected NMT state (without the exceptions above)
-		u16 wbeErrorCode;
-
-		if ((pNodeInfo_p->
-		     m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0) {
-			// decrement only signal slave count if checked once
-			EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
-			pNodeInfo_p->m_wFlags &=
-			    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
-		}
-
-		if (pNodeInfo_p->m_NodeState == kEplNmtMnuNodeStateUnknown) {	// CN is already in state unknown, which means that it got
-			// NMT reset command earlier
-			goto Exit;
-		}
-		// -> CN is in wrong NMT state
-		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateUnknown;
-
-		if (wErrorCode_p == 0) {	// assume wrong NMT state error
-			if ((pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED) != 0) {	// NMT command has been just issued;
-				// ignore wrong NMT state until timer expires;
-				// other errors like LOSS_PRES_TH are still processed
-				goto Exit;
-			}
-
-			wErrorCode_p = EPL_E_NMT_WRONG_STATE;
-		}
-
-		BENCHMARK_MOD_07_TOGGLE(9);
-
-		// $$$ start ERROR_TREATMENT and inform application
-		Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
-							   kEplNmtNodeEventError,
-							   NodeNmtState_p,
-							   wErrorCode_p,
-							   (pNodeInfo_p->
-							    m_dwNodeCfg &
-							    EPL_NODEASSIGN_MANDATORY_CN)
-							   != 0);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-
-		EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
-						uiNodeId_p,
-						(((NodeNmtState_p & 0xFF) << 8)
-						 | kEplNmtCmdResetNode));
-
-		// reset CN
-		// store error code in NMT command data for diagnostic purpose
-		AmiSetWordToLe(&wbeErrorCode, wErrorCode_p);
-		Ret =
-		    EplNmtMnuSendNmtCommandEx(uiNodeId_p, kEplNmtCmdResetNode,
-					      &wbeErrorCode,
-					      sizeof(wbeErrorCode));
-		if (Ret == kEplSuccessful) {
-			Ret = kEplReject;
-		}
-
-		goto Exit;
-	}
-	// check if NMT_MNNodeCurrState_AU8 has to be changed
-	ObdSize = 1;
-	Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtStatePrev, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	if (bNmtState != bNmtStatePrev) {
-		// update object 0x1F8E NMT_MNNodeCurrState_AU8
-		Ret = EplObduWriteEntry(0x1F8E, uiNodeId_p, &bNmtState, 1);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
-							   kEplNmtNodeEventNmtState,
-							   NodeNmtState_p,
-							   wErrorCode_p,
-							   (pNodeInfo_p->
-							    m_dwNodeCfg &
-							    EPL_NODEASSIGN_MANDATORY_CN)
-							   != 0);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtMnuReset
-//
-// Description: reset internal structures, e.g. timers
-//
-// Parameters:  void
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplNmtMnuReset(void)
-{
-	tEplKernel Ret;
-	int iIndex;
-
-	Ret = EplTimeruDeleteTimer(&EplNmtMnuInstance_g.m_TimerHdlNmtState);
-
-	for (iIndex = 1; iIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
-	     iIndex++) {
-		// delete timer handles
-		Ret =
-		    EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->
-					 m_TimerHdlStatReq);
-		Ret =
-		    EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->
-					 m_TimerHdlLonger);
-	}
-
-	return Ret;
-}
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplNmtk.c b/drivers/staging/epl/EplNmtk.c
deleted file mode 100644
index 609d5c0..0000000
--- a/drivers/staging/epl/EplNmtk.c
+++ /dev/null
@@ -1,1840 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for NMT-Kernelspace-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: EplNmtk.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.12 $  $Date: 2008/11/13 17:13:09 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "kernel/EplNmtk.h"
-#include "kernel/EplTimerk.h"
-
-#include "kernel/EplDllk.h"	// for EplDllkProcess()
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-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
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-#define EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent_p, OldNmtState_p, NewNmtState_p) \
-    TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtk << 28) | (NmtEvent_p << 16) \
-                             | ((OldNmtState_p & 0xFF) << 8) \
-                             | (NewNmtState_p & 0xFF))
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-// struct for instance table
-INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
-
-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
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-// 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*
-EPL_MCO_DECL_INSTANCE_VAR()
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-EPL_MCO_DEFINE_INSTANCE_FCT()
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <NMT_Kernel-Module>                                 */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: This module realize the NMT-State-Machine of the EPL-Stack
-//
-//
-/***************************************************************************/
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-//---------------------------------------------------------------------------
-//
-// Function:        EplNmtkInit
-//
-// Description: initializes the first instance
-//
-//
-//
-// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer
-//              uiNodeId_p = Node Id of the lokal node
-//
-//
-// Returns:     tEplKernel  =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
-{
-	tEplKernel Ret;
-
-	Ret = EplNmtkAddInstance(EPL_MCO_PTR_INSTANCE_PTR);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplNmtkAddInstance
-//
-// Description: adds a new instance
-//
-//
-//
-// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer
-//
-//
-// Returns:     tEplKernel  =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
-{
-	EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
-//tEplEvent               Event;
-//tEplEventNmtStateChange NmtStateChange;
-
-	// check if pointer to instance pointer valid
-	// get free instance and set the globale instance pointer
-	// set also the instance addr to parameterlist
-	EPL_MCO_CHECK_PTR_INSTANCE_PTR();
-	EPL_MCO_GET_FREE_INSTANCE_PTR();
-	EPL_MCO_SET_PTR_INSTANCE_PTR();
-
-	// sign instance as used
-	EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed);
-
-	Ret = kEplSuccessful;
-
-	// initialize intern vaiables
-	// 2006/07/31 d.k.: set NMT-State to kEplNmtGsOff
-	EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
-	// set NMT-State to kEplNmtGsInitialising
-	//EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsInitialising;
-
-	// set flags to FALSE
-	EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
-	EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
-	EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) = FALSE;
-	EPL_MCO_GLB_VAR(m_fAllMandatoryCNIdent) = FALSE;
-	EPL_MCO_GLB_VAR(m_fFrozen) = FALSE;
-
-//    EPL_MCO_GLB_VAR(m_TimerHdl) = 0;
-
-	// inform higher layer about state change
-	// 2006/07/31 d.k.: The EPL API layer/application has to start NMT state
-	//                  machine via NmtEventSwReset after initialisation of
-	//                  all modules has been completed. DLL has to be initialised
-	//                  after NMTk because NMT state shall not be uninitialised
-	//                  at that time.
-/*    NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState);
-    NmtStateChange.m_NmtEvent = kEplNmtEventNoEvent;
-    Event.m_EventSink = kEplEventSinkNmtu;
-    Event.m_EventType = kEplEventTypeNmtStateChange;
-    EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
-    Event.m_pArg = &NmtStateChange;
-    Event.m_uiSize = sizeof(NmtStateChange);
-    Ret = EplEventkPost(&Event);
-*/
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplNmtkDelInstance
-//
-// Description: delete instance
-//
-//
-//
-// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR = Instance pointer
-//
-//
-// Returns:     tEplKernel  =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if (EPL_USE_DELETEINST_FUNC != FALSE)
-tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
-{
-	tEplKernel Ret = kEplSuccessful;
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	// set NMT-State to kEplNmtGsOff
-	EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsOff;
-
-	// sign instance as unused
-	EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused);
-
-	// delete timer
-//    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
-
-	return Ret;
-}
-#endif // (EPL_USE_DELETEINST_FUNC != FALSE)
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplNmtkProcess
-//
-// Description: main process function
-//              -> process NMT-State-Maschine und read NMT-Events from Queue
-//
-//
-//
-// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instance pointer
-//              pEvent_p    =   Epl-Event with NMT-event to process
-//
-//
-// Returns:     tEplKernel  =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-	tEplNmtState OldNmtState;
-	tEplNmtEvent NmtEvent;
-	tEplEvent Event;
-	tEplEventNmtStateChange NmtStateChange;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	Ret = kEplSuccessful;
-
-	switch (pEvent_p->m_EventType) {
-	case kEplEventTypeNmtEvent:
-		{
-			NmtEvent = *((tEplNmtEvent *) pEvent_p->m_pArg);
-			break;
-		}
-
-	case kEplEventTypeTimer:
-		{
-			NmtEvent =
-			    (tEplNmtEvent) ((tEplTimerEventArg *) pEvent_p->
-					    m_pArg)->m_ulArg;
-			break;
-		}
-	default:
-		{
-			Ret = kEplNmtInvalidEvent;
-			goto Exit;
-		}
-	}
-
-	// save NMT-State
-	// needed for later comparison to
-	// inform hgher layer about state change
-	OldNmtState = EPL_MCO_GLB_VAR(m_NmtState);
-
-	// NMT-State-Maschine
-	switch (EPL_MCO_GLB_VAR(m_NmtState)) {
-		//-----------------------------------------------------------
-		// general part of the statemaschine
-
-		// first init of the hardware
-	case kEplNmtGsOff:
-		{
-			// leave this state only if higher layer says so
-			if (NmtEvent == kEplNmtEventSwReset) {	// new state kEplNmtGsInitialising
-				EPL_MCO_GLB_VAR(m_NmtState) =
-				    kEplNmtGsInitialising;
-			}
-			break;
-		}
-
-		// first init of the hardware
-	case kEplNmtGsInitialising:
-		{
-			// leave this state only if higher layer says so
-
-			// check events
-			switch (NmtEvent) {
-				// 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// new state kEplNmtGsResetApplication
-			case kEplNmtEventEnterResetApp:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-			}
-			break;
-		}
-
-		// init of the manufacturer-specific profile area and the
-		// standardised device profile area
-	case kEplNmtGsResetApplication:
-		{
-			// check events
-			switch (NmtEvent) {
-				// 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// leave this state only if higher layer
-				// say so
-			case kEplNmtEventEnterResetCom:
-				{
-					// new state kEplNmtGsResetCommunication
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-			}
-			break;
-		}
-
-		// init of the communication profile area
-	case kEplNmtGsResetCommunication:
-		{
-			// check events
-			switch (NmtEvent) {
-				// 2006/07/31 d.k.: react also on NMT reset commands in ResetComm state
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// leave this state only if higher layer
-				// say so
-			case kEplNmtEventEnterResetConfig:
-				{
-					// new state kEplNmtGsResetCommunication
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-			}
-			break;
-		}
-
-		// build the configuration with infos from OD
-	case kEplNmtGsResetConfiguration:
-		{
-			// reset flags
-			EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
-			EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
-			EPL_MCO_GLB_VAR(m_fFrozen) = FALSE;
-
-			// check events
-			switch (NmtEvent) {
-				// 2006/07/31 d.k.: react also on NMT reset commands in ResetConf state
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-			case kEplNmtEventResetCom:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// leave this state only if higher layer says so
-			case kEplNmtEventEnterCsNotActive:
-				{	// Node should be CN
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsNotActive;
-					break;
-
-				}
-
-			case kEplNmtEventEnterMsNotActive:
-				{	// Node should be CN
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
-					// no MN functionality
-					// TODO: -create error E_NMT_BA1_NO_MN_SUPPORT
-					EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
-#else
-
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtMsNotActive;
-#endif
-					break;
-
-				}
-
-			default:
-				{
-					break;
-				}
-			}
-			break;
-		}
-
-		//-----------------------------------------------------------
-		// CN part of the statemaschine
-
-		// node liste for EPL-Frames and check timeout
-	case kEplNmtCsNotActive:
-		{
-
-			// check events
-			switch (NmtEvent) {
-				// 2006/07/31 d.k.: react also on NMT reset commands in NotActive state
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
-					break;
-				}
-
-				// NMT Command Reset Configuration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
-					break;
-				}
-
-				// see if SoA or SoC received
-				// k.t. 20.07.2006: only SoA forces change of state
-				// see EPL V2 DS 1.0.0 p.267
-				// case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeSoa:
-				{	// new state PRE_OPERATIONAL1
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational1;
-//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
-					break;
-				}
-				// timeout for SoA and Soc
-			case kEplNmtEventTimerBasicEthernet:
-				{
-					// new state BASIC_ETHERNET
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsBasicEthernet;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-			}	// end of switch(NmtEvent)
-
-			break;
-		}
-
-		// node processes only async frames
-	case kEplNmtCsPreOperational1:
-		{
-
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command Reset Configuration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// NMT Command StopNode
-			case kEplNmtEventStopNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsStopped;
-					break;
-				}
-
-				// check if SoC received
-			case kEplNmtEventDllCeSoc:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational2;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-
-			break;
-		}
-
-		// node processes isochronous and asynchronous frames
-	case kEplNmtCsPreOperational2:
-		{
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command Reset Configuration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// NMT Command StopNode
-			case kEplNmtEventStopNode:
-				{
-					// reset flags
-					EPL_MCO_GLB_VAR(m_fEnableReadyToOperate)
-					    = FALSE;
-					EPL_MCO_GLB_VAR(m_fAppReadyToOperate) =
-					    FALSE;
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsStopped;
-					break;
-				}
-
-				// error occured
-			case kEplNmtEventNmtCycleError:
-				{
-					// reset flags
-					EPL_MCO_GLB_VAR(m_fEnableReadyToOperate)
-					    = FALSE;
-					EPL_MCO_GLB_VAR(m_fAppReadyToOperate) =
-					    FALSE;
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational1;
-					break;
-				}
-
-				// check if application is ready to operate
-			case kEplNmtEventEnterReadyToOperate:
-				{
-					// check if command NMTEnableReadyToOperate from MN was received
-					if (EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) == TRUE) {	// reset flags
-						EPL_MCO_GLB_VAR
-						    (m_fEnableReadyToOperate) =
-						    FALSE;
-						EPL_MCO_GLB_VAR
-						    (m_fAppReadyToOperate) =
-						    FALSE;
-						// change state
-						EPL_MCO_GLB_VAR(m_NmtState) =
-						    kEplNmtCsReadyToOperate;
-					} else {	// set Flag
-						EPL_MCO_GLB_VAR
-						    (m_fAppReadyToOperate) =
-						    TRUE;
-					}
-					break;
-				}
-
-				// NMT Commando EnableReadyToOperate
-			case kEplNmtEventEnableReadyToOperate:
-				{
-					// check if application is ready
-					if (EPL_MCO_GLB_VAR(m_fAppReadyToOperate) == TRUE) {	// reset flags
-						EPL_MCO_GLB_VAR
-						    (m_fEnableReadyToOperate) =
-						    FALSE;
-						EPL_MCO_GLB_VAR
-						    (m_fAppReadyToOperate) =
-						    FALSE;
-						// change state
-						EPL_MCO_GLB_VAR(m_NmtState) =
-						    kEplNmtCsReadyToOperate;
-					} else {	// set Flag
-						EPL_MCO_GLB_VAR
-						    (m_fEnableReadyToOperate) =
-						    TRUE;
-					}
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-			break;
-		}
-
-		// node should be configured und application is ready
-	case kEplNmtCsReadyToOperate:
-		{
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// NMT Command StopNode
-			case kEplNmtEventStopNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsStopped;
-					break;
-				}
-
-				// error occured
-			case kEplNmtEventNmtCycleError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational1;
-					break;
-				}
-
-				// NMT Command StartNode
-			case kEplNmtEventStartNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsOperational;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-			break;
-		}
-
-		// normal work state
-	case kEplNmtCsOperational:
-		{
-
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// NMT Command StopNode
-			case kEplNmtEventStopNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsStopped;
-					break;
-				}
-
-				// NMT Command EnterPreOperational2
-			case kEplNmtEventEnterPreOperational2:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational2;
-					break;
-				}
-
-				// error occured
-			case kEplNmtEventNmtCycleError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational1;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-			break;
-		}
-
-		// node stopped by MN
-		// -> only process asynchronous frames
-	case kEplNmtCsStopped:
-		{
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// NMT Command EnterPreOperational2
-			case kEplNmtEventEnterPreOperational2:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational2;
-					break;
-				}
-
-				// error occured
-			case kEplNmtEventNmtCycleError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational1;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-			break;
-		}
-
-		// no epl cycle
-		// -> normal ethernet communication
-	case kEplNmtCsBasicEthernet:
-		{
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// error occured
-				// d.k.: how does this error occur? on CRC errors
-/*                case kEplNmtEventNmtCycleError:
-                {
-                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
-                    break;
-                }
-*/
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCePreq:
-			case kEplNmtEventDllCePres:
-			case kEplNmtEventDllCeSoa:
-				{	// Epl-Frame on net -> stop any communication
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtCsPreOperational1;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-
-			break;
-		}
-
-		//-----------------------------------------------------------
-		// MN part of the statemaschine
-
-		// MN listen to network
-		// -> if no EPL traffic go to next state
-	case kEplNmtMsNotActive:
-		{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
-			// no MN functionality
-			// TODO: -create error E_NMT_BA1_NO_MN_SUPPORT
-			EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
-#else
-
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// EPL frames received
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeSoa:
-				{	// other MN in network
-					// $$$ d.k.: generate error history entry
-					EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
-					break;
-				}
-
-				// timeout event
-			case kEplNmtEventTimerBasicEthernet:
-				{
-					if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) {	// new state BasicEthernet
-						EPL_MCO_GLB_VAR(m_NmtState) =
-						    kEplNmtMsBasicEthernet;
-					}
-					break;
-				}
-
-				// timeout event
-			case kEplNmtEventTimerMsPreOp1:
-				{
-					if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) {	// new state PreOp1
-						EPL_MCO_GLB_VAR(m_NmtState) =
-						    kEplNmtMsPreOperational1;
-						EPL_MCO_GLB_VAR
-						    (m_fTimerMsPreOp2) = FALSE;
-						EPL_MCO_GLB_VAR
-						    (m_fAllMandatoryCNIdent) =
-						    FALSE;
-
-					}
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-
-#endif // ((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
-
-			break;
-		}
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-		// MN process reduces epl cycle
-	case kEplNmtMsPreOperational1:
-		{
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// EPL frames received
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeSoa:
-				{	// other MN in network
-					// $$$ d.k.: generate error history entry
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// error occured
-				// d.k. MSPreOp1->CSPreOp1: nonsense -> keep state
-				/*
-				   case kEplNmtEventNmtCycleError:
-				   {
-				   EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
-				   break;
-				   }
-				 */
-
-			case kEplNmtEventAllMandatoryCNIdent:
-				{	// all mandatory CN identified
-					if (EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) !=
-					    FALSE) {
-						EPL_MCO_GLB_VAR(m_NmtState) =
-						    kEplNmtMsPreOperational2;
-					} else {
-						EPL_MCO_GLB_VAR
-						    (m_fAllMandatoryCNIdent) =
-						    TRUE;
-					}
-					break;
-				}
-
-			case kEplNmtEventTimerMsPreOp2:
-				{	// residence time for PreOp1 is elapsed
-					if (EPL_MCO_GLB_VAR
-					    (m_fAllMandatoryCNIdent) != FALSE) {
-						EPL_MCO_GLB_VAR(m_NmtState) =
-						    kEplNmtMsPreOperational2;
-					} else {
-						EPL_MCO_GLB_VAR
-						    (m_fTimerMsPreOp2) = TRUE;
-					}
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-			break;
-		}
-
-		// MN process full epl cycle
-	case kEplNmtMsPreOperational2:
-		{
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// EPL frames received
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeSoa:
-				{	// other MN in network
-					// $$$ d.k.: generate error history entry
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// error occured
-			case kEplNmtEventNmtCycleError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtMsPreOperational1;
-					break;
-				}
-
-			case kEplNmtEventEnterReadyToOperate:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtMsReadyToOperate;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-
-			break;
-		}
-
-		// all madatory nodes ready to operate
-		// -> MN process full epl cycle
-	case kEplNmtMsReadyToOperate:
-		{
-
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// EPL frames received
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeSoa:
-				{	// other MN in network
-					// $$$ d.k.: generate error history entry
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// error occured
-			case kEplNmtEventNmtCycleError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtMsPreOperational1;
-					break;
-				}
-
-			case kEplNmtEventEnterMsOperational:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtMsOperational;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-
-			break;
-		}
-
-		// normal eplcycle processing
-	case kEplNmtMsOperational:
-		{
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// EPL frames received
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeSoa:
-				{	// other MN in network
-					// $$$ d.k.: generate error history entry
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// error occured
-			case kEplNmtEventNmtCycleError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtMsPreOperational1;
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-			break;
-		}
-
-		//  normal ethernet traffic
-	case kEplNmtMsBasicEthernet:
-		{
-
-			// check events
-			switch (NmtEvent) {
-				// NMT Command SwitchOff
-			case kEplNmtEventCriticalError:
-			case kEplNmtEventSwitchOff:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsOff;
-					break;
-				}
-
-				// NMT Command SwReset
-			case kEplNmtEventSwReset:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsInitialising;
-					break;
-				}
-
-				// NMT Command ResetNode
-			case kEplNmtEventResetNode:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetApplication;
-					break;
-				}
-
-				// NMT Command ResetCommunication
-				// or internal Communication error
-			case kEplNmtEventResetCom:
-			case kEplNmtEventInternComError:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// NMT Command ResetConfiguration
-			case kEplNmtEventResetConfig:
-				{
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetConfiguration;
-					break;
-				}
-
-				// EPL frames received
-			case kEplNmtEventDllCeSoc:
-			case kEplNmtEventDllCeSoa:
-				{	// other MN in network
-					// $$$ d.k.: generate error history entry
-					EPL_MCO_GLB_VAR(m_NmtState) =
-					    kEplNmtGsResetCommunication;
-					break;
-				}
-
-				// error occured
-				// d.k. BE->PreOp1 on cycle error? No
-/*                case kEplNmtEventNmtCycleError:
-                {
-                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
-                    break;
-                }
-*/
-			default:
-				{
-					break;
-				}
-
-			}	// end of switch(NmtEvent)
-			break;
-		}
-#endif //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-	default:
-		{
-			//DEBUG_EPL_DBGLVL_NMTK_TRACE0(EPL_DBGLVL_NMT ,"Error in EplNmtProcess: Unknown NMT-State");
-			//EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
-			Ret = kEplNmtInvalidState;
-			goto Exit;
-		}
-
-	}			// end of switch(NmtEvent)
-
-	// inform higher layer about State-Change if needed
-	if (OldNmtState != EPL_MCO_GLB_VAR(m_NmtState)) {
-		EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent, OldNmtState,
-					      EPL_MCO_GLB_VAR(m_NmtState));
-
-		// d.k.: memorize NMT state before posting any events
-		NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState);
-
-		// inform DLL
-		if ((OldNmtState > kEplNmtGsResetConfiguration)
-		    && (EPL_MCO_GLB_VAR(m_NmtState) <=
-			kEplNmtGsResetConfiguration)) {
-			// send DLL DEINIT
-			Event.m_EventSink = kEplEventSinkDllk;
-			Event.m_EventType = kEplEventTypeDllkDestroy;
-			EPL_MEMSET(&Event.m_NetTime, 0x00,
-				   sizeof(Event.m_NetTime));
-			Event.m_pArg = &OldNmtState;
-			Event.m_uiSize = sizeof(OldNmtState);
-			// d.k.: directly call DLLk process function, because
-			//       1. execution of process function is still synchonized and serialized,
-			//       2. it is the same as without event queues (i.e. well tested),
-			//       3. DLLk will get those necessary events even if event queue is full,
-			//       4. event queue is very inefficient
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-			Ret = EplDllkProcess(&Event);
-#else
-			Ret = EplEventkPost(&Event);
-#endif
-		} else if ((OldNmtState <= kEplNmtGsResetConfiguration)
-			   && (EPL_MCO_GLB_VAR(m_NmtState) >
-			       kEplNmtGsResetConfiguration)) {
-			// send DLL INIT
-			Event.m_EventSink = kEplEventSinkDllk;
-			Event.m_EventType = kEplEventTypeDllkCreate;
-			EPL_MEMSET(&Event.m_NetTime, 0x00,
-				   sizeof(Event.m_NetTime));
-			Event.m_pArg = &NmtStateChange.m_NewNmtState;
-			Event.m_uiSize = sizeof(NmtStateChange.m_NewNmtState);
-			// d.k.: directly call DLLk process function, because
-			//       1. execution of process function is still synchonized and serialized,
-			//       2. it is the same as without event queues (i.e. well tested),
-			//       3. DLLk will get those necessary events even if event queue is full
-			//       4. event queue is very inefficient
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-			Ret = EplDllkProcess(&Event);
-#else
-			Ret = EplEventkPost(&Event);
-#endif
-		} else
-		    if ((EPL_MCO_GLB_VAR(m_NmtState) == kEplNmtCsBasicEthernet)
-			|| (EPL_MCO_GLB_VAR(m_NmtState) ==
-			    kEplNmtMsBasicEthernet)) {
-			tEplDllAsyncReqPriority AsyncReqPriority;
-
-			// send DLL Fill Async Tx Buffer, because state BasicEthernet was entered
-			Event.m_EventSink = kEplEventSinkDllk;
-			Event.m_EventType = kEplEventTypeDllkFillTx;
-			EPL_MEMSET(&Event.m_NetTime, 0x00,
-				   sizeof(Event.m_NetTime));
-			AsyncReqPriority = kEplDllAsyncReqPrioGeneric;
-			Event.m_pArg = &AsyncReqPriority;
-			Event.m_uiSize = sizeof(AsyncReqPriority);
-			// d.k.: directly call DLLk process function, because
-			//       1. execution of process function is still synchonized and serialized,
-			//       2. it is the same as without event queues (i.e. well tested),
-			//       3. DLLk will get those necessary events even if event queue is full
-			//       4. event queue is very inefficient
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-			Ret = EplDllkProcess(&Event);
-#else
-			Ret = EplEventkPost(&Event);
-#endif
-		}
-		// inform higher layer about state change
-		NmtStateChange.m_NmtEvent = NmtEvent;
-		Event.m_EventSink = kEplEventSinkNmtu;
-		Event.m_EventType = kEplEventTypeNmtStateChange;
-		EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
-		Event.m_pArg = &NmtStateChange;
-		Event.m_uiSize = sizeof(NmtStateChange);
-		Ret = EplEventkPost(&Event);
-		EPL_DBGLVL_NMTK_TRACE2
-		    ("EplNmtkProcess(NMT-Event = 0x%04X): New NMT-State = 0x%03X\n",
-		     NmtEvent, NmtStateChange.m_NewNmtState);
-
-	}
-
-      Exit:
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtkGetNmtState
-//
-// Description: return the actuell NMT-State and the bits
-//              to for MN- or CN-mode
-//
-//
-//
-// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instancepointer
-//
-//
-// Returns:     tEplNmtState = NMT-State
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
-{
-	tEplNmtState NmtState;
-
-	NmtState = EPL_MCO_GLB_VAR(m_NmtState);
-
-	return NmtState;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-EPL_MCO_DECL_INSTANCE_FCT()
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-// EOF
diff --git a/drivers/staging/epl/EplNmtkCal.c b/drivers/staging/epl/EplNmtkCal.c
deleted file mode 100644
index 4453c09..0000000
--- a/drivers/staging/epl/EplNmtkCal.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source 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.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/06/16 -k.t.:   start of the implementation
-
-****************************************************************************/
-
-// TODO: init function needed to prepare EplNmtkGetNmtState for
-//       io-controll-call from EplNmtuCal-Modul
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          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
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-// EOF
diff --git a/drivers/staging/epl/EplNmtu.c b/drivers/staging/epl/EplNmtu.c
deleted file mode 100644
index 9ac2e8e..0000000
--- a/drivers/staging/epl/EplNmtu.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for NMT-Userspace-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: EplNmtu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/11/10 17:17:42 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "user/EplNmtu.h"
-#include "user/EplObdu.h"
-#include "user/EplTimeru.h"
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-#include "kernel/EplNmtk.h"
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	tEplNmtuStateChangeCallback m_pfnNmtChangeCb;
-	tEplTimerHdl m_TimerHdl;
-
-} tEplNmtuInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static tEplNmtuInstance EplNmtuInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuInit
-//
-// Description: init first instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtuInit(void)
-{
-	tEplKernel Ret;
-
-	Ret = EplNmtuAddInstance();
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuAddInstance
-//
-// Description: init other instances of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtuAddInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuDelInstance
-//
-// Description: delete instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtuDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
-
-	// delete timer
-	Ret = EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuNmtEvent
-//
-// Description: sends the NMT-Event to the NMT-State-Maschine
-//
-//
-//
-// Parameters:  NmtEvent_p  = NMT-Event to send
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
-{
-	tEplKernel Ret;
-	tEplEvent Event;
-
-	Event.m_EventSink = kEplEventSinkNmtk;
-	Event.m_NetTime.m_dwNanoSec = 0;
-	Event.m_NetTime.m_dwSec = 0;
-	Event.m_EventType = kEplEventTypeNmtEvent;
-	Event.m_pArg = &NmtEvent_p;
-	Event.m_uiSize = sizeof(NmtEvent_p);
-
-	Ret = EplEventuPost(&Event);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuGetNmtState
-//
-// Description: returns the actuell NMT-State
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplNmtState  = NMT-State
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplNmtState EplNmtuGetNmtState(void)
-{
-	tEplNmtState NmtState;
-
-	// $$$ call function of communication abstraction layer
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-	NmtState = EplNmtkGetNmtState();
-#else
-	NmtState = 0;
-#endif
-
-	return NmtState;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuProcessEvent
-//
-// Description: processes events from event queue
-//
-//
-//
-// Parameters:  pEplEvent_p =   pointer to event
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// process event
-	switch (pEplEvent_p->m_EventType) {
-		// state change of NMT-Module
-	case kEplEventTypeNmtStateChange:
-		{
-			tEplEventNmtStateChange *pNmtStateChange;
-
-			// delete timer
-			Ret =
-			    EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
-
-			pNmtStateChange =
-			    (tEplEventNmtStateChange *) pEplEvent_p->m_pArg;
-
-			// call cb-functions to inform higher layer
-			if (EplNmtuInstance_g.m_pfnNmtChangeCb != NULL) {
-				Ret =
-				    EplNmtuInstance_g.
-				    m_pfnNmtChangeCb(*pNmtStateChange);
-			}
-
-			if (Ret == kEplSuccessful) {	// everything is OK, so switch to next state if necessary
-				switch (pNmtStateChange->m_NewNmtState) {
-					// EPL stack is not running
-				case kEplNmtGsOff:
-					break;
-
-					// first init of the hardware
-				case kEplNmtGsInitialising:
-					{
-						Ret =
-						    EplNmtuNmtEvent
-						    (kEplNmtEventEnterResetApp);
-						break;
-					}
-
-					// init of the manufacturer-specific profile area and the
-					// standardised device profile area
-				case kEplNmtGsResetApplication:
-					{
-						Ret =
-						    EplNmtuNmtEvent
-						    (kEplNmtEventEnterResetCom);
-						break;
-					}
-
-					// init of the communication profile area
-				case kEplNmtGsResetCommunication:
-					{
-						Ret =
-						    EplNmtuNmtEvent
-						    (kEplNmtEventEnterResetConfig);
-						break;
-					}
-
-					// build the configuration with infos from OD
-				case kEplNmtGsResetConfiguration:
-					{
-						unsigned int uiNodeId;
-
-						// get node ID from OD
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
-						uiNodeId =
-						    EplObduGetNodeId
-						    (EPL_MCO_PTR_INSTANCE_PTR);
-#else
-						uiNodeId = 0;
-#endif
-						//check node ID if not should be master or slave
-						if (uiNodeId == EPL_C_ADR_MN_DEF_NODE_ID) {	// node shall be MN
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-							Ret =
-							    EplNmtuNmtEvent
-							    (kEplNmtEventEnterMsNotActive);
-#else
-							TRACE0
-							    ("EplNmtuProcess(): no MN functionality implemented\n");
-#endif
-						} else {	// node shall be CN
-							Ret =
-							    EplNmtuNmtEvent
-							    (kEplNmtEventEnterCsNotActive);
-						}
-						break;
-					}
-
-					//-----------------------------------------------------------
-					// CN part of the state machine
-
-					// node listens for EPL-Frames and check timeout
-				case kEplNmtCsNotActive:
-					{
-						u32 dwBuffer;
-						tEplObdSize ObdSize;
-						tEplTimerArg TimerArg;
-
-						// create timer to switch automatically to BasicEthernet if no MN available in network
-
-						// read NMT_CNBasicEthernetTimerout_U32 from OD
-						ObdSize = sizeof(dwBuffer);
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
-						Ret =
-						    EplObduReadEntry
-						    (EPL_MCO_PTR_INSTANCE_PTR_
-						     0x1F99, 0x00, &dwBuffer,
-						     &ObdSize);
-#else
-						Ret = kEplObdIndexNotExist;
-#endif
-						if (Ret != kEplSuccessful) {
-							break;
-						}
-						if (dwBuffer != 0) {	// BasicEthernet is enabled
-							// convert us into ms
-							dwBuffer =
-							    dwBuffer / 1000;
-							if (dwBuffer == 0) {	// timer was below one ms
-								// set one ms
-								dwBuffer = 1;
-							}
-							TimerArg.m_EventSink =
-							    kEplEventSinkNmtk;
-							TimerArg.m_ulArg =
-							    (unsigned long)
-							    kEplNmtEventTimerBasicEthernet;
-							Ret =
-							    EplTimeruModifyTimerMs
-							    (&EplNmtuInstance_g.
-							     m_TimerHdl,
-							     (unsigned long)
-							     dwBuffer,
-							     TimerArg);
-							// potential error is forwarded to event queue which generates error event
-						}
-						break;
-					}
-
-					// node processes only async frames
-				case kEplNmtCsPreOperational1:
-					{
-						break;
-					}
-
-					// node processes isochronous and asynchronous frames
-				case kEplNmtCsPreOperational2:
-					{
-						Ret =
-						    EplNmtuNmtEvent
-						    (kEplNmtEventEnterReadyToOperate);
-						break;
-					}
-
-					// node should be configured und application is ready
-				case kEplNmtCsReadyToOperate:
-					{
-						break;
-					}
-
-					// normal work state
-				case kEplNmtCsOperational:
-					{
-						break;
-					}
-
-					// node stopped by MN
-					// -> only process asynchronous frames
-				case kEplNmtCsStopped:
-					{
-						break;
-					}
-
-					// no EPL cycle
-					// -> normal ethernet communication
-				case kEplNmtCsBasicEthernet:
-					{
-						break;
-					}
-
-					//-----------------------------------------------------------
-					// MN part of the state machine
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-					// node listens for EPL-Frames and check timeout
-				case kEplNmtMsNotActive:
-					{
-						u32 dwBuffer;
-						tEplObdSize ObdSize;
-						tEplTimerArg TimerArg;
-
-						// create timer to switch automatically to BasicEthernet/PreOp1 if no other MN active in network
-
-						// check NMT_StartUp_U32.Bit13
-						// read NMT_StartUp_U32 from OD
-						ObdSize = sizeof(dwBuffer);
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
-						Ret =
-						    EplObduReadEntry
-						    (EPL_MCO_PTR_INSTANCE_PTR_
-						     0x1F80, 0x00, &dwBuffer,
-						     &ObdSize);
-#else
-						Ret = kEplObdIndexNotExist;
-#endif
-						if (Ret != kEplSuccessful) {
-							break;
-						}
-
-						if ((dwBuffer & EPL_NMTST_BASICETHERNET) == 0) {	// NMT_StartUp_U32.Bit13 == 0
-							// new state PreOperational1
-							TimerArg.m_ulArg =
-							    (unsigned long)
-							    kEplNmtEventTimerMsPreOp1;
-						} else {	// NMT_StartUp_U32.Bit13 == 1
-							// new state BasicEthernet
-							TimerArg.m_ulArg =
-							    (unsigned long)
-							    kEplNmtEventTimerBasicEthernet;
-						}
-
-						// read NMT_BootTime_REC.MNWaitNotAct_U32 from OD
-						ObdSize = sizeof(dwBuffer);
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
-						Ret =
-						    EplObduReadEntry
-						    (EPL_MCO_PTR_INSTANCE_PTR_
-						     0x1F89, 0x01, &dwBuffer,
-						     &ObdSize);
-#else
-						Ret = kEplObdIndexNotExist;
-#endif
-						if (Ret != kEplSuccessful) {
-							break;
-						}
-						// convert us into ms
-						dwBuffer = dwBuffer / 1000;
-						if (dwBuffer == 0) {	// timer was below one ms
-							// set one ms
-							dwBuffer = 1;
-						}
-						TimerArg.m_EventSink =
-						    kEplEventSinkNmtk;
-						Ret =
-						    EplTimeruModifyTimerMs
-						    (&EplNmtuInstance_g.
-						     m_TimerHdl,
-						     (unsigned long)dwBuffer,
-						     TimerArg);
-						// potential error is forwarded to event queue which generates error event
-						break;
-					}
-
-					// node processes only async frames
-				case kEplNmtMsPreOperational1:
-					{
-						u32 dwBuffer = 0;
-						tEplObdSize ObdSize;
-						tEplTimerArg TimerArg;
-
-						// create timer to switch automatically to PreOp2 if MN identified all mandatory CNs
-
-						// read NMT_BootTime_REC.MNWaitPreOp1_U32 from OD
-						ObdSize = sizeof(dwBuffer);
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
-						Ret =
-						    EplObduReadEntry
-						    (EPL_MCO_PTR_INSTANCE_PTR_
-						     0x1F89, 0x03, &dwBuffer,
-						     &ObdSize);
-						if (Ret != kEplSuccessful) {
-							// ignore error, because this timeout is optional
-							dwBuffer = 0;
-						}
-#endif
-						if (dwBuffer == 0) {	// delay is deactivated
-							// immediately post timer event
-							Ret =
-							    EplNmtuNmtEvent
-							    (kEplNmtEventTimerMsPreOp2);
-							break;
-						}
-						// convert us into ms
-						dwBuffer = dwBuffer / 1000;
-						if (dwBuffer == 0) {	// timer was below one ms
-							// set one ms
-							dwBuffer = 1;
-						}
-						TimerArg.m_EventSink =
-						    kEplEventSinkNmtk;
-						TimerArg.m_ulArg =
-						    (unsigned long)
-						    kEplNmtEventTimerMsPreOp2;
-						Ret =
-						    EplTimeruModifyTimerMs
-						    (&EplNmtuInstance_g.
-						     m_TimerHdl,
-						     (unsigned long)dwBuffer,
-						     TimerArg);
-						// potential error is forwarded to event queue which generates error event
-						break;
-					}
-
-					// node processes isochronous and asynchronous frames
-				case kEplNmtMsPreOperational2:
-					{
-						break;
-					}
-
-					// node should be configured und application is ready
-				case kEplNmtMsReadyToOperate:
-					{
-						break;
-					}
-
-					// normal work state
-				case kEplNmtMsOperational:
-					{
-						break;
-					}
-
-					// no EPL cycle
-					// -> normal ethernet communication
-				case kEplNmtMsBasicEthernet:
-					{
-						break;
-					}
-#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-				default:
-					{
-						TRACE1
-						    ("EplNmtuProcess(): unhandled NMT state 0x%X\n",
-						     pNmtStateChange->
-						     m_NewNmtState);
-					}
-				}
-			} else if (Ret == kEplReject) {	// application wants to change NMT state itself
-				// it's OK
-				Ret = kEplSuccessful;
-			}
-
-			EPL_DBGLVL_NMTU_TRACE0
-			    ("EplNmtuProcessEvent(): NMT-State-Maschine announce change of NMT State\n");
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplNmtInvalidEvent;
-		}
-
-	}
-
-//Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtuRegisterStateChangeCb
-//
-// Description: register Callback-function go get informed about a
-//              NMT-Change-State-Event
-//
-//
-//
-// Parameters:  pfnEplNmtStateChangeCb_p = functionpointer
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// save callback-function in modul global var
-	EplNmtuInstance_g.m_pfnNmtChangeCb = pfnEplNmtStateChangeCb_p;
-
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplNmtuCal.c b/drivers/staging/epl/EplNmtuCal.c
deleted file mode 100644
index 92164c5..0000000
--- a/drivers/staging/epl/EplNmtuCal.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for communication abstraction layer of the
-                NMT-Userspace-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: EplNmtuCal.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                KEIL uVision 2
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/16 -k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplNmtuCal.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
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplNmtkCalGetNmtState
-//
-// Description: return current NMT-State
-//              -> encapsulate access to kernelspace
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplNmtState = current NMT-State
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplNmtState EplNmtkCalGetNmtState(void)
-{
-	tEplNmtState NmtState;
-	// for test direkt call for EplNmtkGetNmtState()
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-	NmtState = EplNmtkGetNmtState();
-#else
-	NmtState = 0;
-#endif
-	return NmtState;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-// EOF
diff --git a/drivers/staging/epl/EplObd.c b/drivers/staging/epl/EplObd.c
deleted file mode 100644
index 1e46323..0000000
--- a/drivers/staging/epl/EplObd.c
+++ /dev/null
@@ -1,3192 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for api function of EplOBD-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: EplObd.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.12 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                Microsoft VC7
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/02 k.t.:   start of the implementation, version 1.00
-		     ->based on CANopen OBD-Modul
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "kernel/EplObdk.h"	// function prototyps of the EplOBD-Modul
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// float definitions and macros
-#define _SHIFTED_EXPONENT_MASK_SP   0xff
-#define _BIAS_SP                    126
-#define T_SP                        23
-#define EXPONENT_DENORM_SP          (-_BIAS_SP)
-#define BASE_TO_THE_T_SP            ((float) 8388608.0)
-#define GET_EXPONENT_SP(x)          ((((x) >> T_SP) & _SHIFTED_EXPONENT_MASK_SP) - _BIAS_SP)
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-// struct for instance table
-INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
-
-STATIC tEplObdInitParam m_ObdInitParam;
-STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback;
-
-INSTANCE_TYPE_END
-// decomposition of float
-typedef union {
-	tEplObdReal32 m_flRealPart;
-	int m_nIntegerPart;
-
-} tEplObdRealParts;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-// 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 *
-
-EPL_MCO_DECL_INSTANCE_VAR()
-
-u8 abEplObdTrashObject_g[8];
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-EPL_MCO_DEFINE_INSTANCE_FCT()
-
-static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
-					   tEplObdCallback fpCallback_p,
-					   tEplObdCbParam *pCbParam_p);
-
-static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p);
-
-static tEplObdSize EplObdGetStrLen(void *pObjData_p,
-				   tEplObdSize ObjLen_p, tEplObdType ObjType_p);
-
-#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
-static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
-					 void *pData_p);
-#endif
-
-static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
-				    tEplObdVarEntry **ppVarEntry_p);
-
-static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
-				 unsigned int uiIndex_p,
-				 unsigned int uiSubindex_p,
-				 tEplObdEntryPtr * ppObdEntry_p,
-				 tEplObdSubEntryPtr * ppObdSubEntry_p);
-
-static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p);
-
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
-				       unsigned int uiIndex_p,
-				       tEplObdEntryPtr * ppObdEntry_p);
-
-static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,
-					  unsigned int uiSubIndex_p,
-					  tEplObdSubEntryPtr * ppObdSubEntry_p);
-
-static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
-					   tEplObdPart CurrentOdPart_p,
-					   tEplObdEntryPtr pObdEnty_p,
-					   tEplObdDir Direction_p);
-
-static void *EplObdGetObjectDefaultPtr(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 *pCbStoreParam_p);
-
-#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-
-static void EplObdCopyObjectData(void *pDstData_p,
-				 void *pSrcData_p,
-				 tEplObdSize ObjSize_p, tEplObdType ObjType_p);
-
-void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p);
-
-static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
-					  BOOL * pfEntryNumerical_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 EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
-				       tEplObdSubEntryPtr pSubEntry_p,
-				       tEplObdCbParam *pCbParam_p,
-				       void *pSrcData_p,
-				       void *pDstData_p,
-				       tEplObdSize ObdSize_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdInit()
-//
-// Description: initializes the first instance
-//
-// Parameters:  pInitParam_p    = init parameter
-//
-// Return:      tEplKernel      =   errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
-{
-
-	tEplKernel Ret;
-	EPL_MCO_DELETE_INSTANCE_TABLE();
-
-	if (pInitParam_p == NULL) {
-		Ret = kEplSuccessful;
-		goto Exit;
-	}
-
-	Ret = EplObdAddInstance(EPL_MCO_PTR_INSTANCE_PTR_ pInitParam_p);
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdAddInstance()
-//
-// Description: adds a new instance
-//
-// Parameters:  pInitParam_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
-{
-
-	EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
-
-	// check if pointer to instance pointer valid
-	// get free instance and set the globale instance pointer
-	// set also the instance addr to parameterlist
-	EPL_MCO_CHECK_PTR_INSTANCE_PTR();
-	EPL_MCO_GET_FREE_INSTANCE_PTR();
-	EPL_MCO_SET_PTR_INSTANCE_PTR();
-
-	// save init parameters
-	EPL_MEMCPY(&EPL_MCO_GLB_VAR(m_ObdInitParam), pInitParam_p,
-		   sizeof(tEplObdInitParam));
-
-	// clear callback function for command LOAD and STORE
-	EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = NULL;
-
-	// sign instance as used
-	EPL_MCO_WRITE_INSTANCE_STATE(kStateUsed);
-
-	// initialize object dictionary
-	// so all all VarEntries will be initialized to trash object and default values will be set to current data
-	Ret = EplObdAccessOdPart(EPL_MCO_INSTANCE_PTR_
-				 kEplObdPartAll, kEplObdDirInit);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdDeleteInstance()
-//
-// Description: delete instance
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if (EPL_USE_DELETEINST_FUNC != FALSE)
-tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
-{
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	// sign instance as unused
-	EPL_MCO_WRITE_INSTANCE_STATE(kStateUnused);
-
-	return kEplSuccessful;
-
-}
-#endif // (EPL_USE_DELETEINST_FUNC != FALSE)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdWriteEntry()
-//
-// Description: Function writes data to an OBD entry. Strings
-//              are stored with added '\0' character.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-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 CbParam;
-	void *pDstData;
-	tEplObdSize ObdSize;
-
-	Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
-				  uiIndex_p,
-				  uiSubIndex_p,
-				  pSrcData_p,
-				  &pDstData,
-				  Size_p,
-				  &pObdEntry, &pSubEntry, &CbParam, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
-				   pObdEntry,
-				   pSubEntry,
-				   &CbParam, pSrcData_p, pDstData, ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdReadEntry()
-//
-// Description: The function reads an object entry. The application
-//              can always read the data even if attrib kEplObdAccRead
-//              is not set. The attrib is only checked up for SDO transfer.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       = Index oof the OD entry to read
-//              uiSubIndex_p    = Subindex to read
-//              pDstData_p      = pointer to the buffer for data
-//              Offset_p        = offset in data for read access
-//              pSize_p         = IN: Size of the buffer
-//                                OUT: number of readed Bytes
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-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 CbParam;
-	void *pSrcData;
-	tEplObdSize ObdSize;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	ASSERT(pDstData_p != NULL);
-	ASSERT(pSize_p != NULL);
-
-	// get address of index and subindex entry
-	Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
-			     uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get pointer to object data
-	pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry);
-
-	// check source pointer
-	if (pSrcData == NULL) {
-		Ret = kEplObdReadViolation;
-		goto Exit;
-	}
-	//------------------------------------------------------------------------
-	// address of source data to structure of callback parameters
-	// so callback function can change this data before reading
-	CbParam.m_uiIndex = uiIndex_p;
-	CbParam.m_uiSubIndex = uiSubIndex_p;
-	CbParam.m_pArg = pSrcData;
-	CbParam.m_ObdEvent = kEplObdEvPreRead;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry->m_fpCallback, &CbParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get size of data and check if application has reserved enough memory
-	ObdSize = EplObdGetDataSizeIntern(pSubEntry);
-	// check if offset given and calc correct number of bytes to read
-	if (*pSize_p < ObdSize) {
-		Ret = kEplObdValueLengthError;
-		goto Exit;
-	}
-	// read value from object
-	EPL_MEMCPY(pDstData_p, pSrcData, ObdSize);
-	*pSize_p = ObdSize;
-
-	// write address of destination data to structure of callback parameters
-	// so callback function can change this data after reading
-	CbParam.m_pArg = pDstData_p;
-	CbParam.m_ObdEvent = kEplObdEvPostRead;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry->m_fpCallback, &CbParam);
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdAccessOdPart()
-//
-// Description: restores default values of one part of OD
-//
-// Parameters:  ObdPart_p
-//              Direction_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
-			      tEplObdDir Direction_p)
-{
-
-	tEplKernel Ret = kEplSuccessful;
-	BOOL fPartFount;
-	tEplObdEntryPtr pObdEntry;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	//  part always has to be unequal to NULL
-	pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pPart);
-	ASSERTMSG(pObdEntry != NULL,
-		  "EplObdAccessOdPart(): no  OD part is defined!\n");
-
-	// if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart
-	fPartFount = FALSE;
-
-	// access to  part
-	if ((ObdPart_p & kEplObdPartGen) != 0) {
-		fPartFount = TRUE;
-
-		Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
-					       kEplObdPartGen, pObdEntry,
-					       Direction_p);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-	// access to manufacturer part
-	pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pManufacturerPart);
-
-	if (((ObdPart_p & kEplObdPartMan) != 0) && (pObdEntry != NULL)) {
-		fPartFount = TRUE;
-
-		Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
-					       kEplObdPartMan, pObdEntry,
-					       Direction_p);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-	// access to device part
-	pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pDevicePart);
-
-	if (((ObdPart_p & kEplObdPartDev) != 0) && (pObdEntry != NULL)) {
-		fPartFount = TRUE;
-
-		Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
-					       kEplObdPartDev, pObdEntry,
-					       Direction_p);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-	{
-		// access to user part
-		pObdEntry = EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart);
-
-		if (((ObdPart_p & kEplObdPartUsr) != 0) && (pObdEntry != NULL)) {
-			fPartFount = TRUE;
-
-			Ret = EplObdAccessOdPartIntern(EPL_MCO_INSTANCE_PTR_
-						       kEplObdPartUsr,
-						       pObdEntry, Direction_p);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-		}
-	}
-#endif
-
-	// no access to an OD part was done? illegal OD part was specified!
-	if (fPartFount == FALSE) {
-		Ret = kEplObdIllegalPart;
-	}
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdDefineVar()
-//
-// Description: defines a variable in OD
-//
-// Parameters:  pEplVarParam_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p)
-{
-
-	tEplKernel Ret;
-	tEplObdVarEntry *pVarEntry;
-	tEplVarParamValid VarValid;
-	tEplObdSubEntryPtr pSubindexEntry;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	ASSERT(pVarParam_p != NULL);	// is not allowed to be NULL
-
-	// get address of subindex entry
-	Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
-			     pVarParam_p->m_uiIndex,
-			     pVarParam_p->m_uiSubindex, NULL, &pSubindexEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get var entry
-	Ret = EplObdGetVarEntry(pSubindexEntry, &pVarEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	VarValid = pVarParam_p->m_ValidFlag;
-
-	// copy only this values, which valid flag is set
-	if ((VarValid & kVarValidSize) != 0) {
-		if (pSubindexEntry->m_Type != kEplObdTypDomain) {
-			tEplObdSize DataSize;
-
-			// check passed size parameter
-			DataSize = EplObdGetObjectSize(pSubindexEntry);
-			if (DataSize != pVarParam_p->m_Size) {	// size of variable does not match
-				Ret = kEplObdValueLengthError;
-				goto Exit;
-			}
-		} else {	// size can be set only for objects of type DOMAIN
-			pVarEntry->m_Size = pVarParam_p->m_Size;
-		}
-	}
-
-	if ((VarValid & kVarValidData) != 0) {
-		pVarEntry->m_pData = pVarParam_p->m_pData;
-	}
-/*
-    #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
-    {
-        if ((VarValid & kVarValidCallback) != 0)
-        {
-           pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback;
-        }
-
-        if ((VarValid & kVarValidArg) != 0)
-        {
-           pVarEntry->m_pArg = pVarParam_p->m_pArg;
-        }
-    }
-    #endif
-*/
-	// Ret is already set to kEplSuccessful from ObdGetVarIntern()
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetObjectDataPtr()
-//
-// Description: It returnes the current data pointer. But if object is an
-//              constant object it returnes the default pointer.
-//
-// Parameters:  uiIndex_p    =   Index of the entry
-//              uiSubindex_p =   Subindex of the entry
-//
-// Return:      void *    = pointer to object data
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			     unsigned int uiSubIndex_p)
-{
-	tEplKernel Ret;
-	void *pData;
-	tEplObdEntryPtr pObdEntry;
-	tEplObdSubEntryPtr pObdSubEntry;
-
-	// get pointer to index structure
-	Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
-				   uiIndex_p, &pObdEntry);
-	if (Ret != kEplSuccessful) {
-		pData = NULL;
-		goto Exit;
-	}
-	// get pointer to subindex structure
-	Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
-	if (Ret != kEplSuccessful) {
-		pData = NULL;
-		goto Exit;
-	}
-	// get Datapointer
-	pData = EplObdGetObjectDataPtrIntern(pObdSubEntry);
-
-      Exit:
-	return pData;
-
-}
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdRegisterUserOd()
-//
-// Description: function registers the user OD
-//
-// Parameters:  pUserOd_p   =pointer to user ODd
-//
-// Return:     tEplKernel = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p)
-{
-
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	EPL_MCO_GLB_VAR(m_ObdInitParam.m_pUserPart) = pUserOd_p;
-
-	return kEplSuccessful;
-
-}
-
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdInitVarEntry()
-//
-// Description: function to initialize VarEntry dependened on object type
-//
-// Parameters:  pVarEntry_p = pointer to var entry structure
-//              Type_p      = object type
-//              ObdSize_p   = size of object data
-//
-// Returns:     none
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
-			tEplObdType Type_p, tEplObdSize ObdSize_p)
-{
-/*
-    #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
-    {
-        // reset pointer to VAR callback and argument
-        pVarEntry_p->m_fpCallback  = NULL;
-        pVarEntry_p->m_pArg = NULL;
-    }
-    #endif
-*/
-
-// 10-dec-2004 r.d.: this function will not be used for strings
-	if ((Type_p == kEplObdTypDomain))
-//         (bType_p == kEplObdTypVString) /* ||
-//         (bType_p == kEplObdTypOString) ||
-//         (bType_p == kEplObdTypUString)    */ )
-	{
-		// variables which are defined as DOMAIN or VSTRING should not point to
-		// trash object, because this trash object contains only 8 bytes. DOMAINS or
-		// STRINGS can be longer.
-		pVarEntry_p->m_pData = NULL;
-		pVarEntry_p->m_Size = 0;
-	} else {
-		// set address to variable data to trash object
-		// This prevents an access violation if user forgets to call EplObdDefineVar()
-		// for this variable but mappes it in a PDO.
-		pVarEntry_p->m_pData = &abEplObdTrashObject_g[0];
-		pVarEntry_p->m_Size = ObdSize_p;
-	}
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetDataSize()
-//
-// Description: function to initialize VarEntry dependened on object type
-//
-//              gets the data size of an object
-//              for string objects it returnes the string length
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
-//              uiIndex_p   =   Index
-//              uiSubIndex_p=   Subindex
-//
-// Return:      tEplObdSize
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			      unsigned int uiSubIndex_p)
-{
-	tEplKernel Ret;
-	tEplObdSize ObdSize;
-	tEplObdEntryPtr pObdEntry;
-	tEplObdSubEntryPtr pObdSubEntry;
-
-	// get pointer to index structure
-	Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
-				   uiIndex_p, &pObdEntry);
-	if (Ret != kEplSuccessful) {
-		ObdSize = 0;
-		goto Exit;
-	}
-	// get pointer to subindex structure
-	Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
-	if (Ret != kEplSuccessful) {
-		ObdSize = 0;
-		goto Exit;
-	}
-	// get size
-	ObdSize = EplObdGetDataSizeIntern(pObdSubEntry);
-      Exit:
-	return ObdSize;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetNodeId()
-//
-// Description: function returns nodeid from entry 0x1F93
-//
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR = Instancepointer
-//
-// Return:      unsigned int = Node Id
-//
-// State:
-//
-//---------------------------------------------------------------------------
-unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
-{
-	tEplKernel Ret;
-	tEplObdSize ObdSize;
-	u8 bNodeId;
-
-	bNodeId = 0;
-	ObdSize = sizeof(bNodeId);
-	Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
-			      EPL_OBD_NODE_ID_INDEX,
-			      EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		bNodeId = EPL_C_ADR_INVALID;
-		goto Exit;
-	}
-
-      Exit:
-	return (unsigned int)bNodeId;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdSetNodeId()
-//
-// Description: function sets nodeid in entry 0x1F93
-//
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
-//              uiNodeId_p  =   Node Id to set
-//              NodeIdType_p=   Type on which way the Node Id was set
-//
-// Return:      tEplKernel = Errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p,
-			   tEplObdNodeIdType NodeIdType_p)
-{
-	tEplKernel Ret;
-	tEplObdSize ObdSize;
-	u8 fHwBool;
-	u8 bNodeId;
-
-	// check Node Id
-	if (uiNodeId_p == EPL_C_ADR_INVALID) {
-		Ret = kEplInvalidNodeId;
-		goto Exit;
-	}
-	bNodeId = (u8) uiNodeId_p;
-	ObdSize = sizeof(u8);
-	// write NodeId to OD entry
-	Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
-			       EPL_OBD_NODE_ID_INDEX,
-			       EPL_OBD_NODE_ID_SUBINDEX, &bNodeId, ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX
-	switch (NodeIdType_p) {
-		// type unknown
-	case kEplObdNodeIdUnknown:
-		{
-			fHwBool = OBD_FALSE;
-			break;
-		}
-
-	case kEplObdNodeIdSoftware:
-		{
-			fHwBool = OBD_FALSE;
-			break;
-		}
-
-	case kEplObdNodeIdHardware:
-		{
-			fHwBool = OBD_TRUE;
-			break;
-		}
-
-	default:
-		{
-			fHwBool = OBD_FALSE;
-		}
-
-	}			// end of switch (NodeIdType_p)
-
-	// write flag
-	ObdSize = sizeof(fHwBool);
-	Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR
-			       EPL_OBD_NODE_ID_INDEX,
-			       EPL_OBD_NODE_ID_HWBOOL_SUBINDEX,
-			       &fHwBool, ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdIsNumerical()
-//
-// Description: function checks if a entry is numerical or not
-//
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
-//              uiIndex_p           = Index
-//              uiSubIndex_p        = Subindex
-//              pfEntryNumerical_p  = pointer to BOOL for returnvalue
-//                                  -> TRUE if entry a numerical value
-//                                  -> FALSE if entry not a numerical value
-//
-// Return:      tEplKernel = Errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			     unsigned int uiSubIndex_p,
-			     BOOL *pfEntryNumerical_p)
-{
-	tEplKernel Ret;
-	tEplObdEntryPtr pObdEntry;
-	tEplObdSubEntryPtr pObdSubEntry;
-
-	// get pointer to index structure
-	Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
-				   uiIndex_p, &pObdEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get pointer to subindex structure
-	Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p);
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdReadEntryToLe()
-//
-// Description: The function reads an object entry from the byteoder
-//              of the system to the little endian byteorder for numerical values.
-//              For other types a normal read will be processed. This is usefull for
-//              the PDO and SDO module. The application
-//              can always read the data even if attrib kEplObdAccRead
-//              is not set. The attrib is only checked up for SDO transfer.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       = Index of the OD entry to read
-//              uiSubIndex_p    = Subindex to read
-//              pDstData_p      = pointer to the buffer for data
-//              Offset_p        = offset in data for read access
-//              pSize_p         = IN: Size of the buffer
-//                                OUT: number of readed Bytes
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-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 CbParam;
-	void *pSrcData;
-	tEplObdSize ObdSize;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	ASSERT(pDstData_p != NULL);
-	ASSERT(pSize_p != NULL);
-
-	// get address of index and subindex entry
-	Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
-			     uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get pointer to object data
-	pSrcData = EplObdGetObjectDataPtrIntern(pSubEntry);
-
-	// check source pointer
-	if (pSrcData == NULL) {
-		Ret = kEplObdReadViolation;
-		goto Exit;
-	}
-	//------------------------------------------------------------------------
-	// address of source data to structure of callback parameters
-	// so callback function can change this data before reading
-	CbParam.m_uiIndex = uiIndex_p;
-	CbParam.m_uiSubIndex = uiSubIndex_p;
-	CbParam.m_pArg = pSrcData;
-	CbParam.m_ObdEvent = kEplObdEvPreRead;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry->m_fpCallback, &CbParam);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get size of data and check if application has reserved enough memory
-	ObdSize = EplObdGetDataSizeIntern(pSubEntry);
-	// check if offset given and calc correct number of bytes to read
-	if (*pSize_p < ObdSize) {
-		Ret = kEplObdValueLengthError;
-		goto Exit;
-	}
-	// check if numerical type
-	switch (pSubEntry->m_Type) {
-		//-----------------------------------------------
-		// types without ami
-	case kEplObdTypVString:
-	case kEplObdTypOString:
-	case kEplObdTypDomain:
-	default:
-		{
-			// read value from object
-			EPL_MEMCPY(pDstData_p, pSrcData, ObdSize);
-			break;
-		}
-
-		//-----------------------------------------------
-		// numerical type which needs ami-write
-		// 8 bit or smaller values
-	case kEplObdTypBool:
-	case kEplObdTypInt8:
-	case kEplObdTypUInt8:
-		{
-			AmiSetByteToLe(pDstData_p, *((u8 *) pSrcData));
-			break;
-		}
-
-		// 16 bit values
-	case kEplObdTypInt16:
-	case kEplObdTypUInt16:
-		{
-			AmiSetWordToLe(pDstData_p, *((u16 *) pSrcData));
-			break;
-		}
-
-		// 24 bit values
-	case kEplObdTypInt24:
-	case kEplObdTypUInt24:
-		{
-			AmiSetDword24ToLe(pDstData_p, *((u32 *) pSrcData));
-			break;
-		}
-
-		// 32 bit values
-	case kEplObdTypInt32:
-	case kEplObdTypUInt32:
-	case kEplObdTypReal32:
-		{
-			AmiSetDwordToLe(pDstData_p, *((u32 *) pSrcData));
-			break;
-		}
-
-		// 40 bit values
-	case kEplObdTypInt40:
-	case kEplObdTypUInt40:
-		{
-			AmiSetQword40ToLe(pDstData_p, *((u64 *) pSrcData));
-			break;
-		}
-
-		// 48 bit values
-	case kEplObdTypInt48:
-	case kEplObdTypUInt48:
-		{
-			AmiSetQword48ToLe(pDstData_p, *((u64 *) pSrcData));
-			break;
-		}
-
-		// 56 bit values
-	case kEplObdTypInt56:
-	case kEplObdTypUInt56:
-		{
-			AmiSetQword56ToLe(pDstData_p, *((u64 *) pSrcData));
-			break;
-		}
-
-		// 64 bit values
-	case kEplObdTypInt64:
-	case kEplObdTypUInt64:
-	case kEplObdTypReal64:
-		{
-			AmiSetQword64ToLe(pDstData_p, *((u64 *) pSrcData));
-			break;
-		}
-
-		// time of day
-	case kEplObdTypTimeOfDay:
-	case kEplObdTypTimeDiff:
-		{
-			AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay *) pSrcData));
-			break;
-		}
-
-	}			// end of switch(pSubEntry->m_Type)
-
-	*pSize_p = ObdSize;
-
-	// write address of destination data to structure of callback parameters
-	// so callback function can change this data after reading
-	CbParam.m_pArg = pDstData_p;
-	CbParam.m_ObdEvent = kEplObdEvPostRead;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry->m_fpCallback, &CbParam);
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdWriteEntryFromLe()
-//
-// Description: Function writes data to an OBD entry from a source with
-//              little endian byteorder to the od with system specuific
-//              byteorder. Not numerical values will only by copied. Strings
-//              are stored with added '\0' character.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-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 CbParam;
-	void *pDstData;
-	tEplObdSize ObdSize;
-	u64 qwBuffer;
-	void *pBuffer = &qwBuffer;
-
-	Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
-				  uiIndex_p,
-				  uiSubIndex_p,
-				  pSrcData_p,
-				  &pDstData,
-				  Size_p,
-				  &pObdEntry, &pSubEntry, &CbParam, &ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	// check if numerical type
-	switch (pSubEntry->m_Type) {
-		//-----------------------------------------------
-		// types without ami
-	default:
-		{		// do nothing, i.e. use the given source pointer
-			pBuffer = pSrcData_p;
-			break;
-		}
-
-		//-----------------------------------------------
-		// numerical type which needs ami-write
-		// 8 bit or smaller values
-	case kEplObdTypBool:
-	case kEplObdTypInt8:
-	case kEplObdTypUInt8:
-		{
-			*((u8 *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
-			break;
-		}
-
-		// 16 bit values
-	case kEplObdTypInt16:
-	case kEplObdTypUInt16:
-		{
-			*((u16 *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
-			break;
-		}
-
-		// 24 bit values
-	case kEplObdTypInt24:
-	case kEplObdTypUInt24:
-		{
-			*((u32 *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
-			break;
-		}
-
-		// 32 bit values
-	case kEplObdTypInt32:
-	case kEplObdTypUInt32:
-	case kEplObdTypReal32:
-		{
-			*((u32 *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
-			break;
-		}
-
-		// 40 bit values
-	case kEplObdTypInt40:
-	case kEplObdTypUInt40:
-		{
-			*((u64 *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
-			break;
-		}
-
-		// 48 bit values
-	case kEplObdTypInt48:
-	case kEplObdTypUInt48:
-		{
-			*((u64 *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
-			break;
-		}
-
-		// 56 bit values
-	case kEplObdTypInt56:
-	case kEplObdTypUInt56:
-		{
-			*((u64 *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
-			break;
-		}
-
-		// 64 bit values
-	case kEplObdTypInt64:
-	case kEplObdTypUInt64:
-	case kEplObdTypReal64:
-		{
-			*((u64 *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
-			break;
-		}
-
-		// time of day
-	case kEplObdTypTimeOfDay:
-	case kEplObdTypTimeDiff:
-		{
-			AmiGetTimeOfDay(pBuffer, ((tTimeOfDay *) pSrcData_p));
-			break;
-		}
-
-	}			// end of switch(pSubEntry->m_Type)
-
-	Ret = EplObdWriteEntryPost(EPL_MCO_INSTANCE_PTR_
-				   pObdEntry,
-				   pSubEntry,
-				   &CbParam, pBuffer, pDstData, ObdSize);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetAccessType()
-//
-// Description: Function returns accesstype of the entry
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pAccessTyp_p    =   pointer to buffer to store accesstype
-//
-// Return:      tEplKernel     =   errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			       unsigned int uiSubIndex_p,
-			       tEplObdAccess *pAccessTyp_p)
-{
-	tEplKernel Ret;
-	tEplObdEntryPtr pObdEntry;
-	tEplObdSubEntryPtr pObdSubEntry;
-
-	// get pointer to index structure
-	Ret = EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam),
-				   uiIndex_p, &pObdEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get pointer to subindex structure
-	Ret = EplObdGetSubindexIntern(pObdEntry, uiSubIndex_p, &pObdSubEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get accessType
-	*pAccessTyp_p = pObdSubEntry->m_Access;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdSearchVarEntry()
-//
-// Description: gets variable from OD
-//
-// Parameters:  uiIndex_p       =   index of the var entry to search
-//              uiSubindex_p    =   subindex of var entry to search
-//              ppVarEntry_p    =   pointer to the pointer to the varentry
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-				unsigned int uiSubindex_p,
-				tEplObdVarEntry **ppVarEntry_p)
-{
-
-	tEplKernel Ret;
-	tEplObdSubEntryPtr pSubindexEntry;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	// get address of subindex entry
-	Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
-			     uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry);
-	if (Ret == kEplSuccessful) {
-		// get var entry
-		Ret = EplObdGetVarEntry(pSubindexEntry, ppVarEntry_p);
-	}
-
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-EPL_MCO_DECL_INSTANCE_FCT()
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdCallObjectCallback()
-//
-// Description: calls callback function of an object or of a variable
-//
-// Parameters:  fpCallback_p
-//              pCbParam_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
-					   tEplObdCallback fpCallback_p,
-					   tEplObdCbParam *pCbParam_p)
-{
-
-	tEplKernel Ret;
-	tEplObdCallback fpCallback;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	ASSERT(pCbParam_p != NULL);
-
-	Ret = kEplSuccessful;
-
-	// check address of callback function before calling it
-	if (fpCallback_p != NULL) {
-		// KEIL C51 V6.01 has a bug.
-		// Therefore the parameter fpCallback_p has to be copied in local variable fpCallback.
-		fpCallback = fpCallback_p;
-
-		// call callback function for this object
-		Ret = fpCallback(EPL_MCO_INSTANCE_PARAM_IDX_()
-				 pCbParam_p);
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetDataSizeIntern()
-//
-// Description: gets the data size of an object
-//              for string objects it returnes the string length
-//
-// Parameters:  pSubIndexEntry_p
-//
-// Return:      tEplObdSize
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)
-{
-
-	tEplObdSize DataSize;
-	void *pData;
-
-	// If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
-	// then the current pointer is always NULL. The function
-	// returns the length of default string.
-	DataSize = EplObdGetObjectSize(pSubIndexEntry_p);
-
-	if (pSubIndexEntry_p->m_Type == kEplObdTypVString) {
-		// The pointer to current value can be received from EplObdGetObjectCurrentPtr()
-		pData = ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
-		if (pData != NULL) {
-			DataSize =
-			    EplObdGetStrLen((void *)pData, DataSize,
-					    pSubIndexEntry_p->m_Type);
-		}
-
-	}
-
-	return DataSize;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetStrLen()
-//
-// Description: The function calculates the length of string. The '\0'
-//              character is included!!
-//
-// Parameters:  pObjData_p          = pointer to string
-//              ObjLen_p            = max. length of objectr entry
-//              bObjType_p          = object type (VSTRING, ...)
-//
-// Returns:     string length + 1
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplObdSize EplObdGetStrLen(void *pObjData_p,
-				   tEplObdSize ObjLen_p, tEplObdType ObjType_p)
-{
-
-	tEplObdSize StrLen = 0;
-	u8 *pbString;
-
-	if (pObjData_p == NULL) {
-		goto Exit;
-	}
-	//----------------------------------------
-	// Visible String: data format byte
-	if (ObjType_p == kEplObdTypVString) {
-		pbString = pObjData_p;
-
-		for (StrLen = 0; StrLen < ObjLen_p; StrLen++) {
-			if (*pbString == '\0') {
-				StrLen++;
-				break;
-			}
-
-			pbString++;
-		}
-	}
-	//----------------------------------------
-	// other string types ...
-
-      Exit:
-	return (StrLen);
-
-}
-
-#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdCheckObjectRange()
-//
-// Description: function to check value range of object data
-//
-// NOTICE: The pointer of data (pData_p) must point out to an even address,
-//         if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is
-//         always realiced because pointer m_pDefault points always to an
-//         array of the SPECIFIED type.
-//
-// Parameters:  pSubindexEntry_p
-//              pData_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
-					 void *pData_p)
-{
-
-	tEplKernel Ret;
-	void *pRangeData;
-
-	ASSERTMSG(pSubindexEntry_p != NULL,
-		  "EplObdCheckObjectRange(): no address to subindex struct!\n");
-
-	Ret = kEplSuccessful;
-
-	// check if data range has to be checked
-	if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0) {
-		goto Exit;
-	}
-	// get address of default data
-	pRangeData = pSubindexEntry_p->m_pDefault;
-
-	// jump to called object type
-	switch ((tEplObdType) pSubindexEntry_p->m_Type) {
-		// -----------------------------------------------------------------
-		// ObdType kEplObdTypBool will not be checked because there are only
-		// two possible values 0 or 1.
-
-		// -----------------------------------------------------------------
-		// ObdTypes which has to be check up because numerical values
-	case kEplObdTypInt8:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdInteger8 *) pData_p) <
-		    *((tEplObdInteger8 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdInteger8 *) pData_p) >
-		    *((tEplObdInteger8 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-	case kEplObdTypUInt8:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdUnsigned8 *) pData_p) <
-		    *((tEplObdUnsigned8 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdUnsigned8 *) pData_p) >
-		    *((tEplObdUnsigned8 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-	case kEplObdTypInt16:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdInteger16 *) pData_p) <
-		    *((tEplObdInteger16 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdInteger16 *) pData_p) >
-		    *((tEplObdInteger16 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-	case kEplObdTypUInt16:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdUnsigned16 *) pData_p) <
-		    *((tEplObdUnsigned16 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdUnsigned16 *) pData_p) >
-		    *((tEplObdUnsigned16 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-	case kEplObdTypInt32:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdInteger32 *) pData_p) <
-		    *((tEplObdInteger32 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdInteger32 *) pData_p) >
-		    *((tEplObdInteger32 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-	case kEplObdTypUInt32:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdUnsigned32 *) pData_p) <
-		    *((tEplObdUnsigned32 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdUnsigned32 *) pData_p) >
-		    *((tEplObdUnsigned32 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-	case kEplObdTypReal32:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdReal32 *) pData_p) <
-		    *((tEplObdReal32 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdReal32 *) pData_p) >
-		    *((tEplObdReal32 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt40:
-	case kEplObdTypInt48:
-	case kEplObdTypInt56:
-	case kEplObdTypInt64:
-
-		// switch to lower limit
-		pRangeData = ((signed u64 *)pRangeData) + 1;
-
-		// check if value is to low
-		if (*((signed u64 *)pData_p) < *((signed u64 *)pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((signed u64 *)pRangeData) + 1;
-
-		// check if value is to high
-		if (*((signed u64 *)pData_p) > *((signed u64 *)pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypUInt40:
-	case kEplObdTypUInt48:
-	case kEplObdTypUInt56:
-	case kEplObdTypUInt64:
-
-		// switch to lower limit
-		pRangeData = ((unsigned u64 *)pRangeData) + 1;
-
-		// check if value is to low
-		if (*((unsigned u64 *)pData_p) <
-		    *((unsigned u64 *)pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((unsigned u64 *)pRangeData) + 1;
-
-		// check if value is to high
-		if (*((unsigned u64 *)pData_p) >
-		    *((unsigned u64 *)pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypReal64:
-
-		// switch to lower limit
-		pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
-
-		// check if value is to low
-		if (*((tEplObdReal64 *) pData_p) <
-		    *((tEplObdReal64 *) pRangeData)) {
-			Ret = kEplObdValueTooLow;
-			break;
-		}
-		// switch to higher limit
-		pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
-
-		// check if value is to high
-		if (*((tEplObdReal64 *) pData_p) >
-		    *((tEplObdReal64 *) pRangeData)) {
-			Ret = kEplObdValueTooHigh;
-		}
-
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypTimeOfDay:
-	case kEplObdTypTimeDiff:
-		break;
-
-		// -----------------------------------------------------------------
-		// ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because
-		// they have no numerical value.
-	default:
-
-		Ret = kEplObdUnknownObjectType;
-		break;
-	}
-
-      Exit:
-
-	return Ret;
-
-}
-#endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdWriteEntryPre()
-//
-// Description: Function prepares write of data to an OBD entry. Strings
-//              are stored with added '\0' character.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-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 *pDstData;
-	tEplObdSize ObdSize;
-	BOOL fEntryNumerical;
-
-#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
-	tEplObdVStringDomain MemVStringDomain;
-	void *pCurrData;
-#endif
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	ASSERT(pSrcData_p != NULL);	// should never be NULL
-
-	//------------------------------------------------------------------------
-	// get address of index and subindex entry
-	Ret = EplObdGetEntry(EPL_MCO_INSTANCE_PTR_
-			     uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// get pointer to object data
-	pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
-
-	Access = (tEplObdAccess) pSubEntry->m_Access;
-
-	// check access for write
-	// access violation if adress to current value is NULL
-	if (((Access & kEplObdAccConst) != 0) || (pDstData == NULL)) {
-		Ret = kEplObdAccessViolation;
-		goto Exit;
-	}
-	//------------------------------------------------------------------------
-	// get size of object
-	// -as ObdSize = ObdGetObjectSize (pSubEntry);
-
-	//------------------------------------------------------------------------
-	// To use the same callback function for ObdWriteEntry as well as for
-	// an SDO download call at first (kEplObdEvPre...) the callback function
-	// with the argument pointer to object size.
-	pCbParam_p->m_uiIndex = uiIndex_p;
-	pCbParam_p->m_uiSubIndex = uiSubIndex_p;
-
-	// Because object size and object pointer are
-	// adapted by user callback function, re-read
-	// this values.
-	ObdSize = EplObdGetObjectSize(pSubEntry);
-	pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
-
-	// 09-dec-2004 r.d.:
-	//      Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
-	//      for String or Domain which lets called module directly change
-	//      the data pointer or size. This prevents a recursive call to
-	//      the callback function if it calls EplObdGetEntry().
-#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
-	if ((pSubEntry->m_Type == kEplObdTypVString) ||
-	    (pSubEntry->m_Type == kEplObdTypDomain) ||
-	    (pSubEntry->m_Type == kEplObdTypOString)) {
-		if (pSubEntry->m_Type == kEplObdTypVString) {
-			// reserve one byte for 0-termination
-			// -as ObdSize -= 1;
-			Size_p += 1;
-		}
-		// fill out new arg-struct
-		MemVStringDomain.m_DownloadSize = Size_p;
-		MemVStringDomain.m_ObjSize = ObdSize;
-		MemVStringDomain.m_pData = pDstData;
-
-		pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain;
-		pCbParam_p->m_pArg = &MemVStringDomain;
-		//  call user callback
-		Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-					       pObdEntry->m_fpCallback,
-					       pCbParam_p);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		// write back new settings
-		pCurrData = pSubEntry->m_pCurrent;
-		if ((pSubEntry->m_Type == kEplObdTypVString)
-		    || (pSubEntry->m_Type == kEplObdTypOString)) {
-			((tEplObdVString *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
-			((tEplObdVString *)pCurrData)->m_pString = MemVStringDomain.m_pData;
-		} else		// if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
-		{
-			((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 *)MemVStringDomain.m_pData;
-	}
-#endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
-
-	// 07-dec-2004 r.d.: size from application is needed because callback function can change the object size
-	// -as 16.11.04 CbParam.m_pArg     = &ObdSize;
-	// 09-dec-2004 r.d.: CbParam.m_pArg     = &Size_p;
-	pCbParam_p->m_pArg = &ObdSize;
-	pCbParam_p->m_ObdEvent = kEplObdEvInitWrite;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry->m_fpCallback, pCbParam_p);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	if (Size_p > ObdSize) {
-		Ret = kEplObdValueLengthError;
-		goto Exit;
-	}
-
-	if (pSubEntry->m_Type == kEplObdTypVString) {
-		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;
-		} else if (Size_p >= ObdSize) {	// source string is not 0-terminated
-			// and destination buffer is too short
-			Ret = kEplObdValueLengthError;
-			goto Exit;
-		}
-	}
-
-	Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-	if ((fEntryNumerical != FALSE)
-	    && (Size_p != ObdSize)) {
-		// type is numerical, therefor size has to fit, but it does not.
-		Ret = kEplObdValueLengthError;
-		goto Exit;
-	}
-	// use given size, because non-numerical objects can be written with shorter values
-	ObdSize = Size_p;
-
-	// set output parameters
-	*pObdSize_p = ObdSize;
-	*ppObdEntry_p = pObdEntry;
-	*ppSubEntry_p = pSubEntry;
-	*ppDstData_p = pDstData;
-
-	// all checks are done
-	// the caller may now convert the numerial source value to platform byte order in a temporary buffer
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdWriteEntryPost()
-//
-// Description: Function finishes write of data to an OBD entry. Strings
-//              are stored with added '\0' character.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-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;
-
-	// caller converted the source value to platform byte order
-	// now the range of the value may be checked
-
-#if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
-	{
-		// check data range
-		Ret = EplObdCheckObjectRange(pSubEntry_p, pSrcData_p);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-	}
-#endif
-
-	// now call user callback function to check value
-	// write address of source data to structure of callback parameters
-	// so callback function can check this data
-	pCbParam_p->m_pArg = pSrcData_p;
-	pCbParam_p->m_ObdEvent = kEplObdEvPreWrite;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry_p->m_fpCallback, pCbParam_p);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	// copy object data to OBD
-	EPL_MEMCPY(pDstData_p, pSrcData_p, ObdSize_p);
-
-	// terminate string with 0
-	if (pSubEntry_p->m_Type == kEplObdTypVString) {
-		((char *)pDstData_p)[ObdSize_p] = '\0';
-	}
-	// write address of destination to structure of callback parameters
-	// so callback function can change data subsequently
-	pCbParam_p->m_pArg = pDstData_p;
-	pCbParam_p->m_ObdEvent = kEplObdEvPostWrite;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry_p->m_fpCallback, pCbParam_p);
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetObjectSize()
-//
-// Description: function to get size of object
-//              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.
-//              For strings the function returns the whole object size not the
-//              length of string.
-//
-// Parameters:  pSubIndexEntry_p
-//
-// Return:      tEplObdSize
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
-{
-
-	tEplObdSize DataSize = 0;
-	void *pData;
-
-	switch (pSubIndexEntry_p->m_Type) {
-		// -----------------------------------------------------------------
-	case kEplObdTypBool:
-
-		DataSize = 1;
-		break;
-
-		// -----------------------------------------------------------------
-		// ObdTypes which has to be check because numerical values
-	case kEplObdTypInt8:
-		DataSize = sizeof(tEplObdInteger8);
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypUInt8:
-		DataSize = sizeof(tEplObdUnsigned8);
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt16:
-		DataSize = sizeof(tEplObdInteger16);
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypUInt16:
-		DataSize = sizeof(tEplObdUnsigned16);
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt32:
-		DataSize = sizeof(tEplObdInteger32);
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypUInt32:
-		DataSize = sizeof(tEplObdUnsigned32);
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypReal32:
-		DataSize = sizeof(tEplObdReal32);
-		break;
-
-		// -----------------------------------------------------------------
-		// ObdTypes which has to be not checked because not NUM values
-	case kEplObdTypDomain:
-
-		pData = (void *)pSubIndexEntry_p->m_pCurrent;
-		if ((void *)pData != (void *)NULL) {
-			DataSize = ((tEplObdVarEntry *) pData)->m_Size;
-		}
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypVString:
-		//case kEplObdTypUString:
-
-		// If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
-		// then the current pointer is always NULL. The function
-		// returns the length of default string.
-		pData = (void *)pSubIndexEntry_p->m_pCurrent;
-		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 *) 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 *)pData != (const void *)NULL) {
-				// The max. size of strings defined by STRING-Macro is stored in
-				// tEplObdVString of default value.
-				DataSize = ((const tEplObdVString *)pData)->m_Size;
-			}
-		}
-
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypOString:
-
-		pData = (void *)pSubIndexEntry_p->m_pCurrent;
-		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 *) 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 *)pData != (const void *)NULL) {
-				// The max. size of strings defined by STRING-Macro is stored in
-				// tEplObdVString of default value.
-				DataSize = ((const tEplObdOString *)pData)->m_Size;
-			}
-		}
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt24:
-	case kEplObdTypUInt24:
-
-		DataSize = 3;
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt40:
-	case kEplObdTypUInt40:
-
-		DataSize = 5;
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt48:
-	case kEplObdTypUInt48:
-
-		DataSize = 6;
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt56:
-	case kEplObdTypUInt56:
-
-		DataSize = 7;
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypInt64:
-	case kEplObdTypUInt64:
-	case kEplObdTypReal64:
-
-		DataSize = 8;
-		break;
-
-		// -----------------------------------------------------------------
-	case kEplObdTypTimeOfDay:
-	case kEplObdTypTimeDiff:
-
-		DataSize = 6;
-		break;
-
-		// -----------------------------------------------------------------
-	default:
-		break;
-	}
-
-	return DataSize;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetObjectDefaultPtr()
-//
-// Description: function to get the default pointer (type specific)
-//
-// Parameters:  pSubIndexEntry_p    = pointer to subindex structure
-//
-// Returns:     (void *)   = pointer to default value
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
-{
-
-	void *pDefault;
-	tEplObdType Type;
-
-	ASSERTMSG(pSubIndexEntry_p != NULL,
-		  "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n");
-
-	// get address to default data from default pointer
-	pDefault = pSubIndexEntry_p->m_pDefault;
-	if (pDefault != NULL) {
-		// there are some special types, whose default pointer always is NULL or has to get from other structure
-		// get type from subindex structure
-		Type = pSubIndexEntry_p->m_Type;
-
-		// check if object type is a string value
-		if ((Type == kEplObdTypVString)	/* ||
-						   (Type == kEplObdTypUString) */ ) {
-
-			// EPL_OBD_SUBINDEX_RAM_VSTRING
-			//    tEplObdSize         m_Size;       --> size of default string
-			//    char *    m_pDefString; --> pointer to  default string
-			//    char *    m_pString;    --> pointer to string in RAM
-			//
-			pDefault =
-			    (void *)((tEplObdVString *) pDefault)->m_pString;
-		} else if (Type == kEplObdTypOString) {
-			pDefault =
-			    (void *)((tEplObdOString *) pDefault)->m_pString;
-		}
-	}
-
-	return pDefault;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetVarEntry()
-//
-// Description: gets a variable entry of an object
-//
-// Parameters:  pSubindexEntry_p
-//              ppVarEntry_p
-//
-// Return:      tCopKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
-				    tEplObdVarEntry **ppVarEntry_p)
-{
-
-	tEplKernel Ret = kEplObdVarEntryNotExist;
-
-	ASSERT(ppVarEntry_p != NULL);	// is not allowed to be NULL
-	ASSERT(pSubindexEntry_p != NULL);
-
-	// check VAR-Flag - only this object points to variables
-	if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) {
-		// check if object is an array
-		if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) {
-			*ppVarEntry_p = &((tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
-		} else {
-			*ppVarEntry_p = (tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent;
-		}
-
-		Ret = kEplSuccessful;
-	}
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetEntry()
-//
-// Description: gets a index entry from OD
-//
-// Parameters:  uiIndex_p       =   Index number
-//              uiSubindex_p    =   Subindex number
-//              ppObdEntry_p    =   pointer to the pointer to the entry
-//              ppObdSubEntry_p =   pointer to the pointer to the subentry
-//
-// Return:      tEplKernel
-
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
-				 unsigned int uiIndex_p,
-				 unsigned int uiSubindex_p,
-				 tEplObdEntryPtr * ppObdEntry_p,
-				 tEplObdSubEntryPtr * ppObdSubEntry_p)
-{
-
-	tEplObdEntryPtr pObdEntry;
-	tEplObdCbParam CbParam;
-	tEplKernel Ret;
-
-	// check for all API function if instance is valid
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	//------------------------------------------------------------------------
-	// get address of entry of index
-	Ret =
-	    EplObdGetIndexIntern(&EPL_MCO_GLB_VAR(m_ObdInitParam), uiIndex_p,
-				 &pObdEntry);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	//------------------------------------------------------------------------
-	// get address of entry of subindex
-	Ret = EplObdGetSubindexIntern(pObdEntry, uiSubindex_p, ppObdSubEntry_p);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-	//------------------------------------------------------------------------
-	// call callback function to inform user/stack that an object will be searched
-	// if the called module returnes an error then we abort the searching with kEplObdIndexNotExist
-	CbParam.m_uiIndex = uiIndex_p;
-	CbParam.m_uiSubIndex = uiSubindex_p;
-	CbParam.m_pArg = NULL;
-	CbParam.m_ObdEvent = kEplObdEvCheckExist;
-	Ret = EplObdCallObjectCallback(EPL_MCO_INSTANCE_PTR_
-				       pObdEntry->m_fpCallback, &CbParam);
-	if (Ret != kEplSuccessful) {
-		Ret = kEplObdIndexNotExist;
-		goto Exit;
-	}
-	//------------------------------------------------------------------------
-	// it is allowed to set ppObdEntry_p to NULL
-	// if so, no address will be written to calling function
-	if (ppObdEntry_p != NULL) {
-		*ppObdEntry_p = pObdEntry;
-	}
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetObjectCurrentPtr()
-//
-// Description: function to get Current pointer (type specific)
-//
-// Parameters:  pSubIndexEntry_p
-//
-// Return:      void *
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
-{
-
-	void *pData;
-	unsigned int uiArrayIndex;
-	tEplObdSize Size;
-
-	pData = pSubIndexEntry_p->m_pCurrent;
-
-	// check if constant object
-	if (pData != NULL) {
-		// check if object is an array
-		if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0) {
-			// calculate correct data pointer
-			uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1;
-			if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
-				Size = sizeof(tEplObdVarEntry);
-			} else {
-				Size = EplObdGetObjectSize(pSubIndexEntry_p);
-			}
-			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 *) 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 *)((tEplObdVString *)pData)->m_pString;
-		} else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) {
-			pData =
-			    (void *)((tEplObdOString *)pData)->m_pString;
-		}
-	}
-
-	return pData;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetIndexIntern()
-//
-// Description: gets a index entry from OD
-//
-// Parameters:  pInitParam_p
-//              uiIndex_p
-//              ppObdEntry_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
-				       unsigned int uiIndex_p,
-				       tEplObdEntryPtr * ppObdEntry_p)
-{
-
-	tEplObdEntryPtr pObdEntry;
-	tEplKernel Ret;
-	unsigned int uiIndex;
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-
-	unsigned int nLoop;
-
-	// if user OD is used then objekts also has to be searched in user OD
-	// there is less code need if we do this in a loop
-	nLoop = 2;
-
-#endif
-
-	ASSERTMSG(ppObdEntry_p != NULL,
-		  "EplObdGetIndexIntern(): pointer to index entry is NULL!\n");
-
-	Ret = kEplObdIndexNotExist;
-
-	// get start address of OD part
-	// start address depends on object index because
-	// object dictionary is divided in 3 parts
-	if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000)) {
-		pObdEntry = pInitParam_p->m_pPart;
-	} else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000)) {
-		pObdEntry = pInitParam_p->m_pManufacturerPart;
-	}
-	// index range 0xA000 to 0xFFFF is reserved for DSP-405
-	// DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3.
-	// Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE.
-	// But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000...
-	// should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE.
-
-#if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE)
-	else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF))
-#else
-	else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF))
-#endif
-	{
-		pObdEntry = pInitParam_p->m_pDevicePart;
-	}
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-
-	// if index does not match in static OD then index only has to be searched in user OD
-	else {
-		// begin from first entry of user OD part
-		pObdEntry = pInitParam_p->m_pUserPart;
-
-		// no user OD is available
-		if (pObdEntry == NULL) {
-			goto Exit;
-		}
-		// loop must only run once
-		nLoop = 1;
-	}
-
-	do {
-
-#else
-
-	// no user OD is available
-	// so other object can be found in OD
-	else {
-		Ret = kEplObdIllegalPart;
-		goto Exit;
-	}
-
-#endif
-
-	// note:
-	// The end of Index table is marked with m_uiIndex = 0xFFFF.
-	// If this function will be called with wIndex_p = 0xFFFF, entry
-	// should not be found. Therefor it is important to use
-	// while{} instead of do{}while !!!
-
-	// get first index of index table
-	uiIndex = pObdEntry->m_uiIndex;
-
-	// search Index in OD part
-	while (uiIndex != EPL_OBD_TABLE_INDEX_END) {
-		// go to the end of this function if index is found
-		if (uiIndex_p == uiIndex) {
-			// write address of OD entry to calling function
-			*ppObdEntry_p = pObdEntry;
-			Ret = kEplSuccessful;
-			goto Exit;
-		}
-		// objects are sorted in OD
-		// if the current index in OD is greater than the index which is to search then break loop
-		// in this case user OD has to be search too
-		if (uiIndex_p < uiIndex) {
-			break;
-		}
-		// next entry in index table
-		pObdEntry++;
-
-		// get next index of index table
-		uiIndex = pObdEntry->m_uiIndex;
-	}
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-
-	// begin from first entry of user OD part
-	pObdEntry = pInitParam_p->m_pUserPart;
-
-	// no user OD is available
-	if (pObdEntry == NULL) {
-		goto Exit;
-	}
-	// switch next loop for user OD
-	nLoop--;
-
-}
-
-while (nLoop > 0) ;
-
-#endif
-
-    // in this line Index was not found
-
-Exit:
-
-return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetSubindexIntern()
-//
-// Description: gets a subindex entry from a index entry
-//
-// Parameters:  pObdEntry_p
-//              bSubIndex_p
-//              ppObdSubEntry_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,
-					  unsigned int uiSubIndex_p,
-					  tEplObdSubEntryPtr * ppObdSubEntry_p)
-{
-
-	tEplObdSubEntryPtr pSubEntry;
-	unsigned int nSubIndexCount;
-	tEplKernel Ret;
-
-	ASSERTMSG(pObdEntry_p != NULL,
-		  "EplObdGetSubindexIntern(): pointer to index is NULL!\n");
-	ASSERTMSG(ppObdSubEntry_p != NULL,
-		  "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n");
-
-	Ret = kEplObdSubindexNotExist;
-
-	// get start address of subindex table and count of subindices
-	pSubEntry = pObdEntry_p->m_pSubIndex;
-	nSubIndexCount = pObdEntry_p->m_uiCount;
-	ASSERTMSG((pSubEntry != NULL) && (nSubIndexCount > 0), "ObdGetSubindexIntern(): invalid subindex table within index table!\n");	// should never be NULL
-
-	// search subindex in subindex table
-	while (nSubIndexCount > 0) {
-		// check if array is found
-		if ((pSubEntry->m_Access & kEplObdAccArray) != 0) {
-			// check if subindex is in range
-			if (uiSubIndex_p < pObdEntry_p->m_uiCount) {
-				// update subindex number (subindex entry of an array is always in RAM !!!)
-				pSubEntry->m_uiSubIndex = uiSubIndex_p;
-				*ppObdSubEntry_p = pSubEntry;
-				Ret = kEplSuccessful;
-				goto Exit;
-			}
-		}
-		// go to the end of this function if subindex is found
-		else if (uiSubIndex_p == pSubEntry->m_uiSubIndex) {
-			*ppObdSubEntry_p = pSubEntry;
-			Ret = kEplSuccessful;
-			goto Exit;
-		}
-		// objects are sorted in OD
-		// if the current subindex in OD is greater than the subindex which is to search then break loop
-		// in this case user OD has to be search too
-		if (uiSubIndex_p < pSubEntry->m_uiSubIndex) {
-			break;
-		}
-
-		pSubEntry++;
-		nSubIndexCount--;
-	}
-
-	// in this line SubIndex was not fount
-
-      Exit:
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdSetStoreLoadObjCallback()
-//
-// Description: function set address to callbackfunction for command Store and Load
-//
-// Parameters:  fpCallback_p
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p)
-{
-
-	EPL_MCO_CHECK_INSTANCE_STATE();
-
-	// set new address of callback function
-	EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) = fpCallback_p;
-
-	return kEplSuccessful;
-
-}
-#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdAccessOdPartIntern()
-//
-// Description: runs through OD and executes a job
-//
-// Parameters:  CurrentOdPart_p
-//              pObdEnty_p
-//              Direction_p     = what is to do (load values from flash or EEPROM, store, ...)
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
-					   tEplObdPart CurrentOdPart_p,
-					   tEplObdEntryPtr pObdEnty_p,
-					   tEplObdDir Direction_p)
-{
-
-	tEplObdSubEntryPtr pSubIndex;
-	unsigned int nSubIndexCount;
-	tEplObdAccess Access;
-	void *pDstData;
-	void *pDefault;
-	tEplObdSize ObjSize;
-	tEplKernel Ret;
-	tEplObdCbStoreParam CbStore;
-	tEplObdVarEntry *pVarEntry;
-
-	ASSERT(pObdEnty_p != NULL);
-
-	Ret = kEplSuccessful;
-
-	// prepare structure for STORE RESTORE callback function
-	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 = (u8) kEplObdCommOpenRead;
-
-		// call callback function for previous command
-		Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		// set command for index and subindex loop
-		CbStore.m_bCommand = (u8) kEplObdCommReadObj;
-	} else if (Direction_p == kEplObdDirStore) {
-		CbStore.m_bCommand = (u8) kEplObdCommOpenWrite;
-
-		// call callback function for previous command
-		Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
-		if (Ret != kEplSuccessful) {
-			goto Exit;
-		}
-		// set command for index and subindex loop
-		CbStore.m_bCommand = (u8) kEplObdCommWriteObj;
-	}
-#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-
-	// we should not restore the OD values here
-	// the next NMT command "Reset Node" or "Reset Communication" resets the OD data
-	if (Direction_p != kEplObdDirRestore) {
-		// walk through OD part till end is found
-		while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END) {
-			// get address to subindex table and count of subindices
-			pSubIndex = pObdEnty_p->m_pSubIndex;
-			nSubIndexCount = pObdEnty_p->m_uiCount;
-			ASSERT((pSubIndex != NULL) && (nSubIndexCount > 0));	// should never be NULL
-
-			// walk through subindex table till all subinices were restored
-			while (nSubIndexCount != 0) {
-				Access = (tEplObdAccess) pSubIndex->m_Access;
-
-				// get pointer to current and default data
-				pDefault = EplObdGetObjectDefaultPtr(pSubIndex);
-				pDstData = EplObdGetObjectCurrentPtr(pSubIndex);
-
-				// NOTE (for kEplObdTypVString):
-				//      The function returnes the max. number of bytes for a
-				//      current string.
-				//      r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit).
-				ObjSize = EplObdGetObjectSize(pSubIndex);
-
-				// switch direction of OD access
-				switch (Direction_p) {
-					// --------------------------------------------------------------------------
-					// VarEntry structures has to be initialized
-				case kEplObdDirInit:
-
-					// If VAR-Flag is set, m_pCurrent means not address of data
-					// but address of tEplObdVarEntry. Address of data has to be get from
-					// this structure.
-					if ((Access & kEplObdAccVar) != 0) {
-						EplObdGetVarEntry(pSubIndex,
-								  &pVarEntry);
-						EplObdInitVarEntry(pVarEntry,
-								   pSubIndex->
-								   m_Type,
-								   ObjSize);
-/*
-                            if ((Access & kEplObdAccArray) == 0)
-                            {
-                                EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize);
-                            }
-                            else
-                            {
-                                EplObdInitVarEntry ((tEplObdVarEntry *) (((u8 *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
-                                    pSubIndex->m_Type, ObjSize);
-                            }
-*/
-						// at this time no application variable is defined !!!
-						// therefore data can not be copied.
-						break;
-					} else if (pSubIndex->m_Type ==
-						   kEplObdTypVString) {
-						// If pointer m_pCurrent is not equal to NULL then the
-						// string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current
-						// pointer points to struct tEplObdVString located in MEM.
-						// The element size includes the max. number of
-						// bytes. The element m_pString includes the pointer
-						// to string in MEM. The memory location of default string
-						// must be copied to memory location of current string.
-
-						pDstData =
-						    pSubIndex->m_pCurrent;
-						if (pDstData != NULL) {
-							// 08-dec-2004: code optimization !!!
-							//              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 *)((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString;
-							ObjSize = ((tEplObdVStringDef *)pSubIndex->m_pDefault)->m_Size;
-
-							((tEplObdVString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
-							((tEplObdVString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
-						}
-
-					} else if (pSubIndex->m_Type ==
-						   kEplObdTypOString) {
-						pDstData =
-						    pSubIndex->m_pCurrent;
-						if (pDstData != NULL) {
-							// 08-dec-2004: code optimization !!!
-							//              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 *)((tEplObdOStringDef *) pSubIndex->m_pDefault)->m_pString;
-							ObjSize = ((tEplObdOStringDef *)pSubIndex->m_pDefault)->m_Size;
-
-							((tEplObdOString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
-							((tEplObdOString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
-						}
-
-					}
-
-					// no break !! because copy of data has to done too.
-
-					// --------------------------------------------------------------------------
-					// all objects has to be restored with default values
-				case kEplObdDirRestore:
-
-					// 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad
-					//                   is replaced to function ObdCopyObjectData() with a new parameter.
-
-					// restore object data for init phase
-					EplObdCopyObjectData(pDstData, pDefault,
-							     ObjSize,
-							     pSubIndex->m_Type);
-					break;
-
-					// --------------------------------------------------------------------------
-					// objects with attribute kEplObdAccStore has to be load from EEPROM or from a file
-				case kEplObdDirLoad:
-
-					// restore object data for init phase
-					EplObdCopyObjectData(pDstData, pDefault,
-							     ObjSize,
-							     pSubIndex->m_Type);
-
-					// no break !! because callback function has to be called too.
-
-					// --------------------------------------------------------------------------
-					// objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file
-				case kEplObdDirStore:
-
-					// when attribute kEplObdAccStore is set, then call callback function
-#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-					if ((Access & kEplObdAccStore) != 0) {
-						// fill out data pointer and size of data
-						CbStore.m_pData = pDstData;
-						CbStore.m_ObjSize = ObjSize;
-
-						// call callback function for read or write object
-						Ret =
-						    ObdCallStoreCallback
-						    (EPL_MCO_INSTANCE_PTR_ &
-						     CbStore);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-					}
-#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-					break;
-
-					// --------------------------------------------------------------------------
-					// if OD Builder key has to be checked no access to subindex and data should be made
-				case kEplObdDirOBKCheck:
-
-					// no break !! because we want to break the second loop too.
-
-					// --------------------------------------------------------------------------
-					// unknown Direction
-				default:
-
-					// so we can break the second loop earler
-					nSubIndexCount = 1;
-					break;
-				}
-
-				nSubIndexCount--;
-
-				// next subindex entry
-				if ((Access & kEplObdAccArray) == 0) {
-					pSubIndex++;
-					if ((nSubIndexCount > 0)
-					    &&
-					    ((pSubIndex->
-					      m_Access & kEplObdAccArray) !=
-					     0)) {
-						// next subindex points to an array
-						// reset subindex number
-						pSubIndex->m_uiSubIndex = 1;
-					}
-				} else {
-					if (nSubIndexCount > 0) {
-						// next subindex points to an array
-						// increment subindex number
-						pSubIndex->m_uiSubIndex++;
-					}
-				}
-			}
-
-			// next index entry
-			pObdEnty_p++;
-		}
-	}
-	// -----------------------------------------------------------------------------------------
-	// command of last action depends on direction to access
-	if (Direction_p == kEplObdDirOBKCheck) {
-
-		goto Exit;
-	}
-#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-	else {
-		if (Direction_p == kEplObdDirLoad) {
-			CbStore.m_bCommand = (u8) kEplObdCommCloseRead;
-		} else if (Direction_p == kEplObdDirStore) {
-			CbStore.m_bCommand = (u8) kEplObdCommCloseWrite;
-		} else if (Direction_p == kEplObdDirRestore) {
-			CbStore.m_bCommand = (u8) kEplObdCommClear;
-		} else {
-			goto Exit;
-		}
-
-		// call callback function for last command
-		Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
-	}
-#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-
-//    goto Exit;
-
-      Exit:
-
-	return Ret;
-
-}
-
-// ----------------------------------------------------------------------------
-// Function:    EplObdCopyObjectData()
-//
-// Description: checks pointers to object data and copy them from source to destination
-//
-// Parameters:  pDstData_p              = destination pointer
-//              pSrcData_p              = source pointer
-//              ObjSize_p               = size of object
-//              ObjType_p               =
-//
-// Returns:     tEplKernel              = error code
-// ----------------------------------------------------------------------------
-
-static void EplObdCopyObjectData(void *pDstData_p,
-				 void *pSrcData_p,
-				 tEplObdSize ObjSize_p, tEplObdType ObjType_p)
-{
-
-	tEplObdSize StrSize = 0;
-
-	// it is allowed to set default and current address to NULL (nothing to copy)
-	if (pDstData_p != NULL) {
-
-		if (ObjType_p == kEplObdTypVString) {
-			// The function calculates the really number of characters of string. The
-			// object entry size can be bigger as string size of default string.
-			// The '\0'-termination is included. A string with no characters has a
-			// size of 1.
-			StrSize =
-			    EplObdGetStrLen((void *)pSrcData_p, ObjSize_p,
-					    kEplObdTypVString);
-
-			// If the string length is greater than or equal to the entry size in OD then only copy
-			// entry size - 1 and always set the '\0'-termination.
-			if (StrSize >= ObjSize_p) {
-				StrSize = ObjSize_p - 1;
-			}
-		}
-
-		if (pSrcData_p != NULL) {
-			// copy data
-			EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p);
-
-			if (ObjType_p == kEplObdTypVString) {
-				((char *)pDstData_p)[StrSize] = '\0';
-			}
-		}
-	}
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdIsNumericalIntern()
-//
-// Description: function checks if a entry is numerical or not
-//
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
-//              uiIndex_p           = Index
-//              uiSubIndex_p        = Subindex
-//              pfEntryNumerical_p  = pointer to BOOL for returnvalue
-//                                  -> TRUE if entry a numerical value
-//                                  -> FALSE if entry not a numerical value
-//
-// Return:      tEplKernel = Errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
-					  BOOL * pfEntryNumerical_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// get Type
-	if ((pObdSubEntry_p->m_Type == kEplObdTypVString)
-	    || (pObdSubEntry_p->m_Type == kEplObdTypOString)
-	    || (pObdSubEntry_p->m_Type == kEplObdTypDomain)) {	// not numerical types
-		*pfEntryNumerical_p = FALSE;
-	} else {		// numerical types
-		*pfEntryNumerical_p = TRUE;
-	}
-
-	return Ret;
-
-}
-
-// -------------------------------------------------------------------------
-// function to classify object type (fixed/non fixed)
-// -------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------
-// Function:    EplObdCallStoreCallback()
-//
-// Description: checks address to callback function and calles it when unequal
-//              to NULL
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer)
-//              pCbStoreParam_p        = address to callback parameters
-//
-// Returns:     tEplKernel             = error code
-// ----------------------------------------------------------------------------
-#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
-					  tEplObdCbStoreParam *
-					  pCbStoreParam_p)
-{
-
-	tEplKernel Ret = kEplSuccessful;
-
-	ASSERT(pCbStoreParam_p != NULL);
-
-	// check if function pointer is NULL - if so, no callback should be called
-	if (EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback) != NULL) {
-		Ret =
-		    EPL_MCO_GLB_VAR(m_fpStoreLoadObjCallback)
-		    (EPL_MCO_INSTANCE_PARAM_IDX_()
-		     pCbStoreParam_p);
-	}
-
-	return Ret;
-
-}
-#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdGetObjectDataPtrIntern()
-//
-// Description: Function gets the data pointer of an object.
-//              It returnes the current data pointer. But if object is an
-//              constant object it returnes the default pointer.
-//
-// Parameters:  pSubindexEntry_p = pointer to subindex entry
-//
-// Return:      void *    = pointer to object data
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p)
-{
-
-	void *pData;
-	tEplObdAccess Access;
-
-	ASSERTMSG(pSubindexEntry_p != NULL,
-		  "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n");
-
-	// there are are some objects whose data pointer has to get from other structure
-	// get access type for this object
-	Access = pSubindexEntry_p->m_Access;
-
-	// If object has access type = const,
-	// for data only exists default values.
-	if ((Access & kEplObdAccConst) != 0) {
-		// The pointer to defualt value can be received from ObdGetObjectDefaultPtr()
-		pData = ((void *)EplObdGetObjectDefaultPtr(pSubindexEntry_p));
-	} else {
-		// The pointer to current value can be received from ObdGetObjectCurrentPtr()
-		pData = ((void *)EplObdGetObjectCurrentPtr(pSubindexEntry_p));
-	}
-
-	return pData;
-
-}
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-// EOF
diff --git a/drivers/staging/epl/EplObd.h b/drivers/staging/epl/EplObd.h
deleted file mode 100644
index 6bb5a27..0000000
--- a/drivers/staging/epl/EplObd.h
+++ /dev/null
@@ -1,456 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for api function of EplOBD-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: EplObd.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                Microsoft VC7
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/02 k.t.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPLOBD_H_
-#define _EPLOBD_H_
-
-#include "EplInc.h"
-
-// ============================================================================
-// defines
-// ============================================================================
-
-#define EPL_OBD_TABLE_INDEX_END     0xFFFF
-
-// for the usage of BOOLEAN in OD
-#define OBD_TRUE    0x01
-#define OBD_FALSE   0x00
-
-// default OD index for Node id
-#define EPL_OBD_NODE_ID_INDEX               0x1F93
-// default subindex for NodeId in OD
-#define EPL_OBD_NODE_ID_SUBINDEX            0x01
-// default subindex for NodeIDByHW_BOOL
-#define EPL_OBD_NODE_ID_HWBOOL_SUBINDEX     0x02
-
-// ============================================================================
-// enums
-// ============================================================================
-
-// directions for access to object dictionary
-typedef enum {
-	kEplObdDirInit = 0x00,	// initialising after power on
-	kEplObdDirStore = 0x01,	// store all object values to non volatile memory
-	kEplObdDirLoad = 0x02,	// load all object values from non volatile memory
-	kEplObdDirRestore = 0x03,	// deletes non volatile memory (restore)
-	kEplObdDirOBKCheck = 0xFF	// reserved
-} tEplObdDir;
-
-// commands for store
-typedef enum {
-	kEplObdCommNothing = 0x00,
-	kEplObdCommOpenWrite = 0x01,
-	kEplObdCommWriteObj = 0x02,
-	kEplObdCommCloseWrite = 0x03,
-	kEplObdCommOpenRead = 0x04,
-	kEplObdCommReadObj = 0x05,
-	kEplObdCommCloseRead = 0x06,
-	kEplObdCommClear = 0x07,
-	kEplObdCommUnknown = 0xFF
-} tEplObdCommand;
-
-//-----------------------------------------------------------------------------------------------------------
-// events of object callback function
-typedef enum {
-//                                                                                                      m_pArg points to
-//                                                                                                    ---------------------
-	kEplObdEvCheckExist = 0x06,	// checking if object does exist (reading and writing)    NULL
-	kEplObdEvPreRead = 0x00,	// before reading an object                               source data buffer in OD
-	kEplObdEvPostRead = 0x01,	// after reading an object                                destination data buffer from caller
-	kEplObdEvWrStringDomain = 0x07,	// event for changing string/domain data pointer or size  struct tEplObdVStringDomain in RAM
-	kEplObdEvInitWrite = 0x04,	// initializes writing an object (checking object size)   size of object in OD (tEplObdSize)
-	kEplObdEvPreWrite = 0x02,	// before writing an object                               source data buffer from caller
-	kEplObdEvPostWrite = 0x03,	// after writing an object                                destination data buffer in OD
-//    kEplObdEvAbortSdo              = 0x05     // after an abort of an SDO transfer
-
-} tEplObdEvent;
-
-// part of OD (bit oriented)
-typedef unsigned int tEplObdPart;
-
-#define kEplObdPartNo          0x00	// nothing
-#define kEplObdPartGen         0x01	//  part      (0x1000 - 0x1FFF)
-#define kEplObdPartMan         0x02	// manufacturer part (0x2000 - 0x5FFF)
-#define kEplObdPartDev         0x04	// device part       (0x6000 - 0x9FFF)
-#define kEplObdPartUsr         0x08	// dynamic part e.g. for ICE61131-3
-
-// combinations
-#define kEplObdPartApp         (              kEplObdPartMan | kEplObdPartDev | kEplObdPartUsr)	// manufacturer and device part (0x2000 - 0x9FFF) and user OD
-#define kEplObdPartAll         (kEplObdPartGen | kEplObdPartMan | kEplObdPartDev | kEplObdPartUsr)	// whole OD
-
-//-----------------------------------------------------------------------------------------------------------
-// access types for objects
-// must be a difine because bit-flags
-typedef unsigned int tEplObdAccess;
-
-#define kEplObdAccRead         0x01	// object can be read
-#define kEplObdAccWrite        0x02	// object can be written
-#define kEplObdAccConst        0x04	// object contains a constant value
-#define kEplObdAccPdo          0x08	// object can be mapped in a PDO
-#define kEplObdAccArray        0x10	// object contains an array of numerical values
-#define kEplObdAccRange        0x20	// object contains lower and upper limit
-#define kEplObdAccVar          0x40	// object data is placed in application
-#define kEplObdAccStore        0x80	// object data can be stored to non volatile memory
-
-// combinations (not all combinations are required)
-#define kEplObdAccR            (0            | 0          | 0            | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccW            (0            | 0          | 0            | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccRW           (0            | 0          | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccCR           (0            | 0          | 0            | 0          | kEplObdAccConst | 0            | kEplObdAccRead)
-#define kEplObdAccGR           (0            | 0          | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccGW           (0            | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccGRW          (0            | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccVR           (0            | kEplObdAccVar | 0            | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccVW           (0            | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccVRW          (0            | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccVPR          (0            | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccVPW          (0            | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccVPRW         (0            | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccVGR          (0            | kEplObdAccVar | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccVGW          (0            | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccVGRW         (0            | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccVGPR         (0            | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccVGPW         (0            | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccVGPRW        (0            | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccSR           (kEplObdAccStore | 0          | 0            | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccSW           (kEplObdAccStore | 0          | 0            | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccSRW          (kEplObdAccStore | 0          | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccSCR          (kEplObdAccStore | 0          | 0            | 0          | kEplObdAccConst | 0            | kEplObdAccRead)
-#define kEplObdAccSGR          (kEplObdAccStore | 0          | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccSGW          (kEplObdAccStore | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccSGRW         (kEplObdAccStore | 0          | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccSVR          (kEplObdAccStore | kEplObdAccVar | 0            | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccSVW          (kEplObdAccStore | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccSVRW         (kEplObdAccStore | kEplObdAccVar | 0            | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccSVPR         (kEplObdAccStore | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccSVPW         (kEplObdAccStore | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccSVPRW        (kEplObdAccStore | kEplObdAccVar | 0            | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccSVGR         (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0          | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccSVGW         (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccSVGRW        (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | 0          | 0            | kEplObdAccWrite | kEplObdAccRead)
-#define kEplObdAccSVGPR        (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | 0            | kEplObdAccRead)
-#define kEplObdAccSVGPW        (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | 0          )
-#define kEplObdAccSVGPRW       (kEplObdAccStore | kEplObdAccVar | kEplObdAccRange | kEplObdAccPdo | 0            | kEplObdAccWrite | kEplObdAccRead)
-
-typedef unsigned int tEplObdSize;	// For all objects as objects size are used an unsigned int.
-
-// -------------------------------------------------------------------------
-// types for data types defined in DS301
-// -------------------------------------------------------------------------
-
-// types of objects in object dictionary
-// DS-301 defines these types as u16
-typedef enum {
-// types which are always supported
-	kEplObdTypBool = 0x0001,
-
-	kEplObdTypInt8 = 0x0002,
-	kEplObdTypInt16 = 0x0003,
-	kEplObdTypInt32 = 0x0004,
-	kEplObdTypUInt8 = 0x0005,
-	kEplObdTypUInt16 = 0x0006,
-	kEplObdTypUInt32 = 0x0007,
-	kEplObdTypReal32 = 0x0008,
-	kEplObdTypVString = 0x0009,
-	kEplObdTypOString = 0x000A,
-	kEplObdTypDomain = 0x000F,
-
-	kEplObdTypInt24 = 0x0010,
-	kEplObdTypUInt24 = 0x0016,
-
-	kEplObdTypReal64 = 0x0011,
-	kEplObdTypInt40 = 0x0012,
-	kEplObdTypInt48 = 0x0013,
-	kEplObdTypInt56 = 0x0014,
-	kEplObdTypInt64 = 0x0015,
-	kEplObdTypUInt40 = 0x0018,
-	kEplObdTypUInt48 = 0x0019,
-	kEplObdTypUInt56 = 0x001A,
-	kEplObdTypUInt64 = 0x001B,
-	kEplObdTypTimeOfDay = 0x000C,
-	kEplObdTypTimeDiff = 0x000D
-} tEplObdType;
-// other types are not supported in this version
-
-// -------------------------------------------------------------------------
-// types for data types defined in DS301
-// -------------------------------------------------------------------------
-
-typedef unsigned char tEplObdBoolean;	// 0001
-typedef signed char tEplObdInteger8;	// 0002
-typedef signed short int tEplObdInteger16;	// 0003
-typedef signed long tEplObdInteger32;	// 0004
-typedef unsigned char tEplObdUnsigned8;	// 0005
-typedef unsigned short int tEplObdUnsigned16;	// 0006
-typedef unsigned long tEplObdUnsigned32;	// 0007
-typedef float tEplObdReal32;	// 0008
-typedef unsigned char tEplObdDomain;	// 000F
-typedef signed long tEplObdInteger24;	// 0010
-typedef unsigned long tEplObdUnsigned24;	// 0016
-
-typedef s64 tEplObdInteger40;	// 0012
-typedef s64 tEplObdInteger48;	// 0013
-typedef s64 tEplObdInteger56;	// 0014
-typedef s64 tEplObdInteger64;	// 0015
-
-typedef u64 tEplObdUnsigned40;	// 0018
-typedef u64 tEplObdUnsigned48;	// 0019
-typedef u64 tEplObdUnsigned56;	// 001A
-typedef u64 tEplObdUnsigned64;	// 001B
-
-typedef double tEplObdReal64;	// 0011
-
-typedef tTimeOfDay tEplObdTimeOfDay;	// 000C
-typedef tTimeOfDay tEplObdTimeDifference;	// 000D
-
-// -------------------------------------------------------------------------
-// structur for defining a variable
-// -------------------------------------------------------------------------
-// -------------------------------------------------------------------------
-typedef enum {
-	kVarValidSize = 0x01,
-	kVarValidData = 0x02,
-//    kVarValidCallback       = 0x04,
-//    kVarValidArg            = 0x08,
-
-	kVarValidAll = 0x03	// currently only size and data are implemented and used
-} tEplVarParamValid;
-
-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 *m_pData;
-//    tEplVarCallback     m_fpCallback;
-//    void *       m_pArg;
-
-} tEplVarParam;
-
-typedef struct {
-	void *m_pData;
-	tEplObdSize m_Size;
-/*
-    #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
-        tEplVarCallback    m_fpCallback;
-        void *   m_pArg;
-    #endif
-*/
-} tEplObdVarEntry;
-
-typedef struct {
-	tEplObdSize m_Size;
-	u8 *m_pString;
-
-} tEplObdOString;		// 000C
-
-typedef struct {
-	tEplObdSize m_Size;
-	char *m_pString;
-} tEplObdVString;		// 000D
-
-typedef struct {
-	tEplObdSize m_Size;
-	char *m_pDefString;	// $$$ d.k. it is unused, so we could delete it
-	char *m_pString;
-
-} tEplObdVStringDef;
-
-typedef struct {
-	tEplObdSize m_Size;
-	u8 *m_pDefString;	// $$$ d.k. it is unused, so we could delete it
-	u8 *m_pString;
-
-} tEplObdOStringDef;
-
-//r.d. parameter struct for changing object size and/or pointer to data of Strings or Domains
-typedef struct {
-	tEplObdSize m_DownloadSize;	// download size from SDO or APP
-	tEplObdSize m_ObjSize;	// current object size from OD - should be changed from callback function
-	void *m_pData;		// current object ptr  from OD - should be changed from callback function
-
-} tEplObdVStringDomain;		// 000D
-
-// ============================================================================
-// types
-// ============================================================================
-// -------------------------------------------------------------------------
-// subindexstruct
-// -------------------------------------------------------------------------
-
-// Change not the order for this struct!!!
-typedef struct {
-	unsigned int m_uiSubIndex;
-	tEplObdType m_Type;
-	tEplObdAccess m_Access;
-	void *m_pDefault;
-	void *m_pCurrent;	// points always to RAM
-
-} tEplObdSubEntry;
-
-// r.d.: has always to be  because new OBD-Macros for arrays
-typedef tEplObdSubEntry *tEplObdSubEntryPtr;
-
-// -------------------------------------------------------------------------
-// callback function for objdictionary modul
-// -------------------------------------------------------------------------
-
-// parameters for callback function
-typedef struct {
-	tEplObdEvent m_ObdEvent;
-	unsigned int m_uiIndex;
-	unsigned int m_uiSubIndex;
-	void *m_pArg;
-	u32 m_dwAbortCode;
-
-} tEplObdCbParam;
-
-// define type for callback function: pParam_p points to tEplObdCbParam
-typedef tEplKernel(*tEplObdCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbParam *pParam_p);
-
-// do not change the order for this struct!!!
-
-typedef struct {
-	unsigned int m_uiIndex;
-	tEplObdSubEntryPtr m_pSubIndex;
-	unsigned int m_uiCount;
-	tEplObdCallback m_fpCallback;	// function is called back if object access
-
-} tEplObdEntry;
-
-// allways  pointer
-typedef tEplObdEntry *tEplObdEntryPtr;
-
-// -------------------------------------------------------------------------
-// structur to initialize OBD module
-// -------------------------------------------------------------------------
-
-typedef struct {
-	tEplObdEntryPtr m_pPart;
-	tEplObdEntryPtr m_pManufacturerPart;
-	tEplObdEntryPtr m_pDevicePart;
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-
-	tEplObdEntryPtr m_pUserPart;
-
-#endif
-
-} tEplObdInitParam;
-
-// -------------------------------------------------------------------------
-// structur for parameters of STORE RESTORE command
-// -------------------------------------------------------------------------
-
-typedef struct {
-	tEplObdCommand m_bCommand;
-	tEplObdPart m_bCurrentOdPart;
-	void *m_pData;
-	tEplObdSize m_ObjSize;
-
-} tEplObdCbStoreParam;
-
-typedef tEplKernel(*tInitTabEntryCallback) (void *pTabEntry_p, unsigned int uiObjIndex_p);
-
-typedef tEplKernel(*tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbStoreParam *pCbStoreParam_p);
-
-// -------------------------------------------------------------------------
-// this stucture is used for parameters for function ObdInitModuleTab()
-// -------------------------------------------------------------------------
-typedef struct {
-	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 *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;
-
-//-------------------------------------------------------------------
-//  enum for function EplObdSetNodeId
-//-------------------------------------------------------------------
-typedef enum {
-	kEplObdNodeIdUnknown = 0x00,	// unknown how the node id was set
-	kEplObdNodeIdSoftware = 0x01,	// node id set by software
-	kEplObdNodeIdHardware = 0x02	// node id set by hardware
-} tEplObdNodeIdType;
-
-// ============================================================================
-// global variables
-// ============================================================================
-
-// ============================================================================
-// public functions
-// ============================================================================
-
-#endif // #ifndef _EPLOBD_H_
diff --git a/drivers/staging/epl/EplObdMacro.h b/drivers/staging/epl/EplObdMacro.h
deleted file mode 100644
index fc325bf..0000000
--- a/drivers/staging/epl/EplObdMacro.h
+++ /dev/null
@@ -1,354 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for macros of EplOBD-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: EplObdMacro.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/05 k.t.:   start of the implementation
-                    -> based on CANopen ObdMacro.h
-
-****************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#if defined (EPL_OBD_DEFINE_MACRO)
-
-    //-------------------------------------------------------------------------------------------
-#if defined (EPL_OBD_CREATE_ROM_DATA)
-
-//        #pragma message ("EPL_OBD_CREATE_ROM_DATA")
-
-#define EPL_OBD_BEGIN()                                                         static  u32  dwObd_OBK_g = 0x0000;
-#define EPL_OBD_END()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_PART_GENERIC()
-#define EPL_OBD_BEGIN_PART_MANUFACTURER()
-#define EPL_OBD_BEGIN_PART_DEVICE()
-#define EPL_OBD_END_PART()
-
-	//---------------------------------------------------------------------------------------
-#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  tEplObdUnsigned8    xDef##ind##_0x00_g = (cnt); \
-                                                                                        static  dtyp  xDef##ind##_0x01_g = (def);
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      static  tEplObdUnsigned8    xDef##ind##_0x00_g = (cnt); \
-                                                                                        static  dtyp  xDef##ind##_0x01_g = (def);
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   static  tEplObdUnsigned8    xDef##ind##_0x00_g = (cnt);
-
-	//---------------------------------------------------------------------------------------
-#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  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  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};
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
-
-//-------------------------------------------------------------------------------------------
-#elif defined (EPL_OBD_CREATE_RAM_DATA)
-
-//        #pragma message ("EPL_OBD_CREATE_RAM_DATA")
-
-#define EPL_OBD_BEGIN()
-#define EPL_OBD_END()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_PART_GENERIC()
-#define EPL_OBD_BEGIN_PART_MANUFACTURER()
-#define EPL_OBD_BEGIN_PART_DEVICE()
-#define EPL_OBD_END_PART()
-
-	//---------------------------------------------------------------------------------------
-#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         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         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)
-
-//        #pragma message ("EPL_OBD_CREATE_SUBINDEX_TAB")
-
-#define EPL_OBD_BEGIN()
-#define EPL_OBD_END()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_PART_GENERIC()
-#define EPL_OBD_BEGIN_PART_MANUFACTURER()
-#define EPL_OBD_BEGIN_PART_DEVICE()
-#define EPL_OBD_END_PART()
-
-	//---------------------------------------------------------------------------------------
-#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 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 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 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()};
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)                 {sub,typ,            (acc),                        &xDef##ind##_##sub##_g,   &xCur##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)     {sub,typ,            (acc)|kEplObdAccRange,           &xDef##ind##_##sub##_g[0],&xCur##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)              {sub,typ,            (acc),                        NULL,   &xCur##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)                 {sub,kEplObdTypVString,(acc)/*|kEplObdAccVar*/,         &xDef##ind##_##sub##_g,   &xCur##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)                     {sub,kEplObdTypOString,(acc)/*|kEplObdAccVar*/,         &xDef##ind##_##sub##_g,   &xCur##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)                           {sub,kEplObdTypDomain, (acc)|kEplObdAccVar,             NULL,                     &VarEntry##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)             {sub,typ,           (acc)|kEplObdAccVar,             &xDef##ind##_##sub##_g,   &VarEntry##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) {sub,typ,           (acc)|kEplObdAccVar|kEplObdAccRange,&xDef##ind##_##sub##_g[0],&VarEntry##ind##_##sub##_g},
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)          {sub,typ,           (acc)|kEplObdAccVar,             NULL,    &VarEntry##ind##_##sub##_g},
-
-    //-------------------------------------------------------------------------------------------
-#elif defined (EPL_OBD_CREATE_INDEX_TAB)
-
-//        #pragma message ("EPL_OBD_CREATE_INDEX_TAB")
-
-#define EPL_OBD_BEGIN()
-#define EPL_OBD_END()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_PART_GENERIC()                                                   static  tEplObdEntry  aObdTab_g[]      = {
-#define EPL_OBD_BEGIN_PART_MANUFACTURER()                                       static  tEplObdEntry  aObdTabManufacturer_g[] = {
-#define EPL_OBD_BEGIN_PART_DEVICE()                                             static  tEplObdEntry  aObdTabDevice_g[]       = {
-#define EPL_OBD_END_PART()                                                      {EPL_OBD_TABLE_INDEX_END,(tEplObdSubEntryPtr)&dwObd_OBK_g,0,NULL}};
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)                                   {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],cnt,(tEplObdCallback)call},
-#define EPL_OBD_END_INDEX(ind)
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)         {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call},
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)      {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call},
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)   {ind,(tEplObdSubEntryPtr)&aObdSubEntry##ind##Ram_g[0],(cnt)+1,(tEplObdCallback)call},
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
-
-	    //-------------------------------------------------------------------------------------------
-#elif defined (EPL_OBD_CREATE_INIT_FUNCTION)
-
-//        #pragma message ("EPL_OBD_CREATE_INIT_FUNCTION")
-
-#define EPL_OBD_BEGIN()
-#define EPL_OBD_END()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_PART_GENERIC()                                                   pInitParam->m_pPart      = (tEplObdEntryPtr) &aObdTab_g[0];
-#define EPL_OBD_BEGIN_PART_MANUFACTURER()                                       pInitParam->m_pManufacturerPart = (tEplObdEntryPtr) &aObdTabManufacturer_g[0];
-#define EPL_OBD_BEGIN_PART_DEVICE()                                             pInitParam->m_pDevicePart       = (tEplObdEntryPtr) &aObdTabDevice_g[0];
-#define EPL_OBD_END_PART()
-
-	//---------------------------------------------------------------------------------------
-#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)
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
-
-    //-------------------------------------------------------------------------------------------
-#elif defined (EPL_OBD_CREATE_INIT_SUBINDEX)
-
-//        #pragma message ("EPL_OBD_CREATE_INIT_SUBINDEX")
-
-#define EPL_OBD_BEGIN()
-#define EPL_OBD_END()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_PART_GENERIC()
-#define EPL_OBD_BEGIN_PART_MANUFACTURER()
-#define EPL_OBD_BEGIN_PART_DEVICE()
-#define EPL_OBD_END_PART()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)	//CCM_SUBINDEX_RAM_ONLY (EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g)));
-#define EPL_OBD_END_INDEX(ind)
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def)	//EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g));
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)	//EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g));
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)	//EPL_MEMCPY (&aObdSubEntry##ind##Ram_g[0],&aObdSubEntry##ind##Rom_g[0],sizeof(aObdSubEntry##ind##Ram_g));
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val)
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
-
-    //-------------------------------------------------------------------------------------------
-#else
-
-//        #pragma message ("ELSE OF DEFINE")
-
-#define EPL_OBD_BEGIN()
-#define EPL_OBD_END()
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_PART_GENERIC()
-#define EPL_OBD_BEGIN_PART_MANUFACTURER()
-#define EPL_OBD_BEGIN_PART_DEVICE()
-#define EPL_OBD_END_PART()
-
-	//---------------------------------------------------------------------------------------
-#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)
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def)
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name)
-
-	//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,sizes,val)
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size)
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high)
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name)
-
-#endif
-
-    //-------------------------------------------------------------------------------------------
-#elif defined (EPL_OBD_UNDEFINE_MACRO)
-
-//    #pragma message ("EPL_OBD_UNDEFINE_MACRO")
-
-#undef EPL_OBD_BEGIN
-#undef EPL_OBD_END
-
-    //---------------------------------------------------------------------------------------
-#undef EPL_OBD_BEGIN_PART_GENERIC
-#undef EPL_OBD_BEGIN_PART_MANUFACTURER
-#undef EPL_OBD_BEGIN_PART_DEVICE
-#undef EPL_OBD_END_PART
-
-    //---------------------------------------------------------------------------------------
-#undef EPL_OBD_BEGIN_INDEX_RAM
-#undef EPL_OBD_END_INDEX
-#undef EPL_OBD_RAM_INDEX_RAM_ARRAY
-#undef EPL_OBD_RAM_INDEX_RAM_VARARRAY
-#undef EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT
-
-    //---------------------------------------------------------------------------------------
-#undef EPL_OBD_SUBINDEX_RAM_VAR
-#undef EPL_OBD_SUBINDEX_RAM_VAR_RG
-#undef EPL_OBD_SUBINDEX_RAM_VSTRING
-#undef EPL_OBD_SUBINDEX_RAM_OSTRING
-#undef EPL_OBD_SUBINDEX_RAM_VAR_NOINIT
-#undef EPL_OBD_SUBINDEX_RAM_DOMAIN
-#undef EPL_OBD_SUBINDEX_RAM_USERDEF
-#undef EPL_OBD_SUBINDEX_RAM_USERDEF_RG
-#undef EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT
-
-#else
-
-#error "nothing defined"
-
-#endif
diff --git a/drivers/staging/epl/EplObdkCal.c b/drivers/staging/epl/EplObdkCal.c
deleted file mode 100644
index 02bd722..0000000
--- a/drivers/staging/epl/EplObdkCal.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source 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.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/06/19 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "EplInc.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
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-// EOF
diff --git a/drivers/staging/epl/EplObdu.c b/drivers/staging/epl/EplObdu.c
deleted file mode 100644
index 5f1d998..0000000
--- a/drivers/staging/epl/EplObdu.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for Epl-Obd-Userspace-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: EplObdu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/19 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "user/EplObdu.h"
-#include "user/EplObduCal.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          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
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduWriteEntry()
-//
-// Description: Function writes data to an OBD entry. Strings
-//              are stored with added '\0' character.
-//
-// Parameters:  uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduWriteEntry(unsigned int uiIndex_p,
-			     unsigned int uiSubIndex_p,
-			     void *pSrcData_p, tEplObdSize Size_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplObduCalWriteEntry(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduReadEntry()
-//
-// Description: The function reads an object entry. The application
-//              can always read the data even if attrib kEplObdAccRead
-//              is not set. The attrib is only checked up for SDO transfer.
-//
-// Parameters:  uiIndex_p       = Index oof the OD entry to read
-//              uiSubIndex_p    = Subindex to read
-//              pDstData_p      = pointer to the buffer for data
-//              Offset_p        = offset in data for read access
-//              pSize_p         = IN: Size of the buffer
-//                                OUT: number of readed Bytes
-//
-// Return:      tEplKernel      =   errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduReadEntry(unsigned int uiIndex_p,
-			    unsigned int uiSubIndex_p,
-			    void *pDstData_p,
-			    tEplObdSize *pSize_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplObduCalReadEntry(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdAccessOdPart()
-//
-// Description: restores default values of one part of OD
-//
-// Parameters:  ObdPart_p       = od-part to reset
-//              Direction_p     = directory flag for
-//
-// Return:      tEplKernel  = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplObduCalAccessOdPart(ObdPart_p, Direction_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduDefineVar()
-//
-// Description: defines a variable in OD
-//
-// Parameters:  pEplVarParam_p = varentry
-//
-// Return:      tEplKernel  =   errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplObduCalDefineVar(pVarParam_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduGetObjectDataPtr()
-//
-// Description: It returnes the current data pointer. But if object is an
-//              constant object it returnes the default pointer.
-//
-// Parameters:  uiIndex_p    =   Index of the entry
-//              uiSubindex_p =   Subindex of the entry
-//
-// Return:      void *    = pointer to object data
-//
-// State:
-//
-//---------------------------------------------------------------------------
-void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
-{
-	void *pData;
-
-	pData = EplObduCalGetObjectDataPtr(uiIndex_p, uiSubIndex_p);
-
-	return pData;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduRegisterUserOd()
-//
-// Description: function registers the user OD
-//
-// Parameters:  pUserOd_p   =pointer to user ODd
-//
-// Return:     tEplKernel = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplObduCalRegisterUserOd(pUserOd_p);
-
-	return Ret;
-
-}
-#endif
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduInitVarEntry()
-//
-// Description: function to initialize VarEntry dependened on object type
-//
-// Parameters:  pVarEntry_p = pointer to var entry structure
-//              bType_p     = object type
-//              ObdSize_p   = size of object data
-//
-// Returns:     none
-//
-// State:
-//
-//---------------------------------------------------------------------------
-void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p, tEplObdSize ObdSize_p)
-{
-	EplObduCalInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduGetDataSize()
-//
-// Description: function to initialize VarEntry dependened on object type
-//
-//              gets the data size of an object
-//              for string objects it returnes the string length
-//
-// Parameters:  uiIndex_p   =   Index
-//              uiSubIndex_p=   Subindex
-//
-// Return:      tEplObdSize
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
-{
-	tEplObdSize Size;
-
-	Size = EplObduCalGetDataSize(uiIndex_p, uiSubIndex_p);
-
-	return Size;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduGetNodeId()
-//
-// Description: function returns nodeid from entry 0x1F93
-//
-//
-// Parameters:
-//
-// Return:      unsigned int = Node Id
-//
-// State:
-//
-//---------------------------------------------------------------------------
-unsigned int EplObduGetNodeId(void)
-{
-	unsigned int uiNodeId;
-
-	uiNodeId = EplObduCalGetNodeId();
-
-	return uiNodeId;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduSetNodeId()
-//
-// Description: function sets nodeid in entry 0x1F93
-//
-//
-// Parameters:  uiNodeId_p  =   Node Id to set
-//              NodeIdType_p=   Type on which way the Node Id was set
-//
-// Return:      tEplKernel = Errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p, tEplObdNodeIdType NodeIdType_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplObduCalSetNodeId(uiNodeId_p, NodeIdType_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduGetAccessType()
-//
-// Description: Function returns accesstype of the entry
-//
-// Parameters:  uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pAccessTyp_p    =   pointer to buffer to store accesstyp
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduGetAccessType(unsigned int uiIndex_p,
-				unsigned int uiSubIndex_p,
-				tEplObdAccess *pAccessTyp_p)
-{
-	tEplObdAccess AccessType;
-
-	AccessType =
-	    EplObduCalGetAccessType(uiIndex_p, uiSubIndex_p, pAccessTyp_p);
-
-	return AccessType;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObdReaduEntryToLe()
-//
-// Description: The function reads an object entry from the byteoder
-//              of the system to the little endian byteorder for numeric values.
-//              For other types a normal read will be processed. This is usefull for
-//              the PDO and SDO module. The application
-//              can always read the data even if attrib kEplObdAccRead
-//              is not set. The attrib is only checked up for SDO transfer.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       = Index of the OD entry to read
-//              uiSubIndex_p    = Subindex to read
-//              pDstData_p      = pointer to the buffer for data
-//              Offset_p        = offset in data for read access
-//              pSize_p         = IN: Size of the buffer
-//                                OUT: number of readed Bytes
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p,
-				unsigned int uiSubIndex_p,
-				void *pDstData_p,
-				tEplObdSize *pSize_p)
-{
-	tEplKernel Ret;
-
-	Ret =
-	    EplObduCalReadEntryToLe(uiIndex_p, uiSubIndex_p, pDstData_p,
-				    pSize_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduWriteEntryFromLe()
-//
-// Description: Function writes data to an OBD entry from a source with
-//              little endian byteorder to the od with system specuific
-//              byteorder. Not numeric values will only by copied. Strings
-//              are stored with added '\0' character.
-//
-// Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
-//              uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p,
-				   unsigned int uiSubIndex_p,
-				   void *pSrcData_p,
-				   tEplObdSize Size_p)
-{
-	tEplKernel Ret;
-
-	Ret =
-	    EplObduCalWriteEntryFromLe(uiIndex_p, uiSubIndex_p, pSrcData_p,
-				       Size_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduSearchVarEntry()
-//
-// Description: gets variable from OD
-//
-// Parameters:  uiIndex_p       =   index of the var entry to search
-//              uiSubindex_p    =   subindex of var entry to search
-//              ppVarEntry_p    =   pointer to the pointer to the varentry
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-				 unsigned int uiSubindex_p,
-				 tEplObdVarEntry **ppVarEntry_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplObduCalSearchVarEntry(uiIndex_p, uiSubindex_p, ppVarEntry_p);
-
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplObduCal.c b/drivers/staging/epl/EplObduCal.c
deleted file mode 100644
index 55612cf..0000000
--- a/drivers/staging/epl/EplObduCal.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for communication abstraction layer
-                for the Epl-Obd-Userspace-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: EplObduCal.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/19 k.t.:   start of the implementation
-
-****************************************************************************/
-#include "EplInc.h"
-#include "user/EplObduCal.h"
-#include "kernel/EplObdk.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) && (EPL_OBD_USE_KERNEL != FALSE)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          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
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalWriteEntry()
-//
-// Description: Function encapsulate access of function EplObdWriteEntry
-//
-// Parameters:  uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
-				unsigned int uiSubIndex_p,
-				void *pSrcData_p, tEplObdSize Size_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdWriteEntry(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalReadEntry()
-//
-// Description: Function encapsulate access of function EplObdReadEntry
-//
-// Parameters:  uiIndex_p       = Index oof the OD entry to read
-//              uiSubIndex_p    = Subindex to read
-//              pDstData_p      = pointer to the buffer for data
-//              Offset_p        = offset in data for read access
-//              pSize_p         = IN: Size of the buffer
-//                                OUT: number of readed Bytes
-//
-// Return:      tEplKernel      =   errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
-			       unsigned int uiSubIndex_p,
-			       void *pDstData_p, tEplObdSize *pSize_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdReadEntry(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalAccessOdPart()
-//
-// Description: Function encapsulate access of function EplObdAccessOdPart
-//
-// Parameters:  ObdPart_p       = od-part to reset
-//              Direction_p     = directory flag for
-//
-// Return:      tEplKernel  = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdAccessOdPart(ObdPart_p, Direction_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalDefineVar()
-//
-// Description: Function encapsulate access of function EplObdDefineVar
-//
-// Parameters:  pEplVarParam_p = varentry
-//
-// Return:      tEplKernel  =   errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdDefineVar(pVarParam_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalGetObjectDataPtr()
-//
-// Description: Function encapsulate access of function EplObdGetObjectDataPtr
-//
-// Parameters:  uiIndex_p    =   Index of the entry
-//              uiSubindex_p =   Subindex of the entry
-//
-// Return:      void *    = pointer to object data
-//
-// State:
-//
-//---------------------------------------------------------------------------
-void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
-{
-	void *pData;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	pData = EplObdGetObjectDataPtr(uiIndex_p, uiSubIndex_p);
-#else
-	pData = NULL;
-#endif
-
-	return pData;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalRegisterUserOd()
-//
-// Description: Function encapsulate access of function EplObdRegisterUserOd
-//
-// Parameters:  pUserOd_p   = pointer to user OD
-//
-// Return:     tEplKernel = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdRegisterUserOd(pUserOd_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-
-}
-#endif
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalInitVarEntry()
-//
-// Description: Function encapsulate access of function EplObdInitVarEntry
-//
-// Parameters:  pVarEntry_p = pointer to var entry structure
-//              bType_p     = object type
-//              ObdSize_p   = size of object data
-//
-// Returns:     none
-//
-// State:
-//
-//---------------------------------------------------------------------------
-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);
-#endif
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalGetDataSize()
-//
-// Description: Function encapsulate access of function EplObdGetDataSize
-//
-//              gets the data size of an object
-//              for string objects it returnes the string length
-//
-// Parameters:  uiIndex_p   =   Index
-//              uiSubIndex_p=   Subindex
-//
-// Return:      tEplObdSize
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
-				  unsigned int uiSubIndex_p)
-{
-	tEplObdSize Size;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Size = EplObdGetDataSize(uiIndex_p, uiSubIndex_p);
-#else
-	Size = 0;
-#endif
-
-	return Size;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalGetNodeId()
-//
-// Description: Function encapsulate access of function EplObdGetNodeId
-//
-//
-// Parameters:
-//
-// Return:      unsigned int = Node Id
-//
-// State:
-//
-//---------------------------------------------------------------------------
-unsigned int EplObduCalGetNodeId(void)
-{
-	unsigned int uiNodeId;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	uiNodeId = EplObdGetNodeId();
-#else
-	uiNodeId = 0;
-#endif
-
-	return uiNodeId;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalSetNodeId()
-//
-// Description: Function encapsulate access of function EplObdSetNodeId
-//
-//
-// Parameters:  uiNodeId_p  =   Node Id to set
-//              NodeIdType_p=   Type on which way the Node Id was set
-//
-// Return:      tEplKernel = Errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
-			       tEplObdNodeIdType NodeIdType_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdSetNodeId(uiNodeId_p, NodeIdType_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalGetAccessType()
-//
-// Description: Function encapsulate access of function EplObdGetAccessType
-//
-// Parameters:  uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pAccessTyp_p    =   pointer to buffer to store accesstype
-//
-// Return:      tEplKernel      =   errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
-				   unsigned int uiSubIndex_p,
-				   tEplObdAccess *pAccessTyp_p)
-{
-	tEplObdAccess AccesType;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	AccesType = EplObdGetAccessType(uiIndex_p, uiSubIndex_p, pAccessTyp_p);
-#else
-	AccesType = 0;
-#endif
-
-	return AccesType;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalReadEntryToLe()
-//
-// Description: Function encapsulate access of function EplObdReadEntryToLe
-//
-// Parameters:  uiIndex_p       = Index of the OD entry to read
-//              uiSubIndex_p    = Subindex to read
-//              pDstData_p      = pointer to the buffer for data
-//              Offset_p        = offset in data for read access
-//              pSize_p         = IN: Size of the buffer
-//                                OUT: number of readed Bytes
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
-				   unsigned int uiSubIndex_p,
-				   void *pDstData_p,
-				   tEplObdSize *pSize_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdReadEntryToLe(uiIndex_p, uiSubIndex_p, pDstData_p, pSize_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalWriteEntryFromLe()
-//
-// Description: Function encapsulate access of function EplObdWriteEntryFromLe
-//
-// Parameters:  uiIndex_p       =   Index of the OD entry
-//              uiSubIndex_p    =   Subindex of the OD Entry
-//              pSrcData_p      =   Pointer to the data to write
-//              Size_p          =   Size of the data in Byte
-//
-// Return:      tEplKernel      =   Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
-				      unsigned int uiSubIndex_p,
-				      void *pSrcData_p, tEplObdSize Size_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret =
-	    EplObdWriteEntryFromLe(uiIndex_p, uiSubIndex_p, pSrcData_p, Size_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplObduCalSearchVarEntry()
-//
-// Description: gets variable from OD
-//
-// Parameters:  uiIndex_p       =   index of the var entry to search
-//              uiSubindex_p    =   subindex of var entry to search
-//              ppVarEntry_p    =   pointer to the pointer to the varentry
-//
-// Return:      tEplKernel
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-				    unsigned int uiSubindex_p,
-				    tEplObdVarEntry **ppVarEntry_p)
-{
-	tEplKernel Ret;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-	Ret = EplObdSearchVarEntry(uiIndex_p, uiSubindex_p, ppVarEntry_p);
-#else
-	Ret = kEplSuccessful;
-#endif
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplPdo.h b/drivers/staging/epl/EplPdo.h
deleted file mode 100644
index 0b3ad5b..0000000
--- a/drivers/staging/epl/EplPdo.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for PDO 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: EplPdo.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_PDO_H_
-#define _EPL_PDO_H_
-
-#include "EplInc.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// invalid PDO-NodeId
-#define EPL_PDO_INVALID_NODE_ID     0xFF
-// NodeId for PReq RPDO
-#define EPL_PDO_PREQ_NODE_ID        0x00
-// NodeId for PRes TPDO
-#define EPL_PDO_PRES_NODE_ID        0x00
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef struct {
-	void *m_pVar;
-	u16 m_wOffset;		// in Bits
-	u16 m_wSize;		// in Bits
-	BOOL m_fNumeric;	// numeric value -> use AMI functions
-
-} tEplPdoMapping;
-
-typedef struct {
-	unsigned int m_uiSizeOfStruct;
-	unsigned int m_uiPdoId;
-	unsigned int m_uiNodeId;
-	// 0xFF=invalid, RPDO: 0x00=PReq, localNodeId=PRes, remoteNodeId=PRes
-	//               TPDO: 0x00=PRes, MN: CnNodeId=PReq
-
-	BOOL m_fTxRx;
-	u8 m_bMappingVersion;
-	unsigned int m_uiMaxMappingEntries;	// maximum number of mapping entries, i.e. size of m_aPdoMapping
-	tEplPdoMapping m_aPdoMapping[1];
-
-} tEplPdoParam;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPL_PDO_H_
diff --git a/drivers/staging/epl/EplPdok.c b/drivers/staging/epl/EplPdok.c
deleted file mode 100644
index db9b3f0..0000000
--- a/drivers/staging/epl/EplPdok.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for kernel PDO 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: EplPdok.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "kernel/EplPdok.h"
-#include "kernel/EplPdokCal.h"
-#include "kernel/EplEventk.h"
-#include "kernel/EplObdk.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) == 0)
-
-#error 'ERROR: Missing DLLk-Modul!'
-
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
-
-#error 'ERROR: Missing OBDk-Modul!'
-
-#endif
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define EPL_PDOK_OBD_IDX_RX_COMM_PARAM  0x1400
-#define EPL_PDOK_OBD_IDX_RX_MAPP_PARAM  0x1600
-#define EPL_PDOK_OBD_IDX_TX_COMM_PARAM  0x1800
-#define EPL_PDOK_OBD_IDX_TX_MAPP_PARAM  0x1A00
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  EplPdok                                             */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokAddInstance()
-//
-// Description: add and initialize new instance of EPL stack
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokAddInstance(void)
-{
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokDelInstance()
-//
-// Description: deletes an instance of EPL stack
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokDelInstance(void)
-{
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokCbPdoReceived
-//
-// Description: This function is called by DLL if PRes or PReq frame was
-//              received. It posts the frame to the event queue.
-//              It is called in states NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL.
-//              The passed PDO needs not to be valid.
-//
-// Parameters:  pFrameInfo_p            = pointer to frame info structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-
-	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)
-	Event.m_uiSize = AmiGetWordFromLe(&pFrameInfo_p->m_pFrame->m_Data.m_Pres.m_le_wSize) + 24;	// pFrameInfo_p->m_uiFrameSize;
-	Event.m_pArg = pFrameInfo_p->m_pFrame;
-	Ret = EplEventkPost(&Event);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokCbPdoTransmitted
-//
-// Description: This function is called by DLL if PRes or PReq frame was
-//              sent. It posts the pointer to the frame to the event queue.
-//              It is called in NMT_CS_PRE_OPERATIONAL_2,
-//              NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL.
-//
-// Parameters:  pFrameInfo_p            = pointer to frame info structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-
-	Event.m_EventSink = kEplEventSinkPdok;
-	Event.m_EventType = kEplEventTypePdoTx;
-	Event.m_uiSize = sizeof(tEplFrameInfo);
-	Event.m_pArg = pFrameInfo_p;
-	Ret = EplEventkPost(&Event);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokCbSoa
-//
-// Description: This function is called by DLL if SoA frame was
-//              received resp. sent. It posts this event to the event queue.
-//
-// Parameters:  pFrameInfo_p            = pointer to frame info structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplEvent Event;
-
-	Event.m_EventSink = kEplEventSinkPdok;
-	Event.m_EventType = kEplEventTypePdoSoa;
-	Event.m_uiSize = 0;
-	Event.m_pArg = NULL;
-	Ret = EplEventkPost(&Event);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokProcess
-//
-// Description: This function processes all received and transmitted PDOs.
-//              This function must not be interrupted by any other task
-//              except ISRs (like the ethernet driver ISR, which may call
-//              EplPdokCbFrameReceived() or EplPdokCbFrameTransmitted()).
-//
-// Parameters:  pEvent_p                = pointer to event structure
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	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;
-	tEplFrameInfo *pFrameInfo;
-	unsigned int uiNodeId;
-	tEplMsgType MsgType;
-
-	// 0xFF=invalid, RPDO: 0x00=PReq, localNodeId=PRes, remoteNodeId=PRes
-	//               TPDO: 0x00=PRes, MN: CnNodeId=PReq
-
-	switch (pEvent_p->m_EventType) {
-	case kEplEventTypePdoRx:	// RPDO received
-		pFrame = (tEplFrame *) pEvent_p->m_pArg;
-
-		// check if received RPDO is valid
-		bFrameData =
-		    AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bFlag1);
-		if ((bFrameData & EPL_FRAME_FLAG1_RD) == 0) {	// RPDO invalid
-			goto Exit;
-		}
-		// retrieve EPL message type
-		MsgType = AmiGetByteFromLe(&pFrame->m_le_bMessageType);
-		if (MsgType == kEplMsgTypePreq) {	// RPDO is PReq frame
-			uiNodeId = EPL_PDO_PREQ_NODE_ID;	// 0x00
-		} else {	// RPDO is PRes frame
-			// retrieve node ID
-			uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
-		}
-
-		// search for appropriate valid RPDO in OD
-		wObdMappIndex = EPL_PDOK_OBD_IDX_RX_MAPP_PARAM;
-		for (wObdCommIndex = EPL_PDOK_OBD_IDX_RX_COMM_PARAM;
-		     wObdCommIndex < (EPL_PDOK_OBD_IDX_RX_COMM_PARAM + 0x00FF);
-		     wObdCommIndex++, wObdMappIndex++) {
-			ObdSize = 1;
-			// read node ID from OD
-			Ret =
-			    EplObdReadEntry(wObdCommIndex, 0x01, &bObdData,
-					    &ObdSize);
-			if ((Ret == kEplObdIndexNotExist)
-			    || (Ret == kEplObdSubindexNotExist)
-			    || (Ret == kEplObdIllegalPart)) {	// PDO does not exist; last PDO reached
-				Ret = kEplSuccessful;
-				goto Exit;
-			} else if (Ret != kEplSuccessful) {	// other fatal error occured
-				goto Exit;
-			}
-			// entry read successfully
-			if (bObdData != uiNodeId) {	// node ID does not equal - wrong PDO, try next PDO in OD
-				continue;
-			}
-			ObdSize = 1;
-			// read number of mapped objects from OD; this indicates if the PDO is valid
-			Ret =
-			    EplObdReadEntry(wObdMappIndex, 0x00, &bObjectCount,
-					    &ObdSize);
-			if ((Ret == kEplObdIndexNotExist)
-			    || (Ret == kEplObdSubindexNotExist)
-			    || (Ret == kEplObdIllegalPart)) {	// PDO does not exist; last PDO reached
-				Ret = kEplSuccessful;
-				goto Exit;
-			} else if (Ret != kEplSuccessful) {	// other fatal error occured
-				goto Exit;
-			}
-			// entry read successfully
-			if (bObjectCount == 0) {	// PDO in OD not valid, try next PDO in OD
-				continue;
-			}
-
-			ObdSize = 1;
-			// check PDO mapping version
-			Ret =
-			    EplObdReadEntry(wObdCommIndex, 0x02, &bObdData,
-					    &ObdSize);
-			if (Ret != kEplSuccessful) {	// other fatal error occured
-				goto Exit;
-			}
-			// entry read successfully
-			// retrieve PDO version from frame
-			bFrameData =
-			    AmiGetByteFromLe(&pFrame->m_Data.m_Pres.
-					     m_le_bPdoVersion);
-			if ((bObdData & EPL_VERSION_MAIN) != (bFrameData & EPL_VERSION_MAIN)) {	// PDO versions do not match
-				// $$$ raise PDO error
-				// termiate processing of this RPDO
-				goto Exit;
-			}
-			// valid RPDO found
-
-			// retrieve PDO size
-			wPdoSize =
-			    AmiGetWordFromLe(&pFrame->m_Data.m_Pres.m_le_wSize);
-
-			// process mapping
-			for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
-			     bMappSubindex++) {
-				ObdSize = 8;	// u64
-				// read object mapping from OD
-				Ret =
-				    EplObdReadEntry(wObdMappIndex,
-						    bMappSubindex,
-						    &qwObjectMapping, &ObdSize);
-				if (Ret != kEplSuccessful) {	// other fatal error occured
-					goto Exit;
-				}
-				// check if object mapping entry is valid, i.e. unequal zero, because "empty" entries are allowed
-				if (qwObjectMapping == 0) {	// invalid entry, continue with next entry
-					continue;
-				}
-				// decode object mapping
-				wObdCommIndex =
-				    (u16) (qwObjectMapping &
-					    0x000000000000FFFFLL);
-				bObdSubindex =
-				    (u8) ((qwObjectMapping &
-					     0x0000000000FF0000LL) >> 16);
-				wBitOffset =
-				    (u16) ((qwObjectMapping &
-					     0x0000FFFF00000000LL) >> 32);
-				wBitSize =
-				    (u16) ((qwObjectMapping &
-					     0xFFFF000000000000LL) >> 48);
-
-				// check if object exceeds PDO size
-				if (((wBitOffset + wBitSize) >> 3) > wPdoSize) {	// wrong object mapping; PDO size is too low
-					// $$$ raise PDO error
-					// terminate processing of this RPDO
-					goto Exit;
-				}
-				// copy object from RPDO to process/OD variable
-				ObdSize = wBitSize >> 3;
-				Ret =
-				    EplObdWriteEntryFromLe(wObdCommIndex,
-							   bObdSubindex,
-							   &pFrame->m_Data.
-							   m_Pres.
-							   m_le_abPayload[(wBitOffset >> 3)], ObdSize);
-				if (Ret != kEplSuccessful) {	// other fatal error occured
-					goto Exit;
-				}
-
-			}
-
-			// processing finished successfully
-			goto Exit;
-		}
-		break;
-
-	case kEplEventTypePdoTx:	// TPDO transmitted
-		pFrameInfo = (tEplFrameInfo *) pEvent_p->m_pArg;
-		pFrame = pFrameInfo->m_pFrame;
-
-		// set TPDO invalid, so that only fully processed TPDOs are sent as valid
-		bFrameData =
-		    AmiGetByteFromLe(&pFrame->m_Data.m_Pres.m_le_bFlag1);
-		AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bFlag1,
-			       (bFrameData & ~EPL_FRAME_FLAG1_RD));
-
-		// retrieve EPL message type
-		MsgType = AmiGetByteFromLe(&pFrame->m_le_bMessageType);
-		if (MsgType == kEplMsgTypePres) {	// TPDO is PRes frame
-			uiNodeId = EPL_PDO_PRES_NODE_ID;	// 0x00
-		} else {	// TPDO is PReq frame
-			// retrieve node ID
-			uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
-		}
-
-		// search for appropriate valid TPDO in OD
-		wObdMappIndex = EPL_PDOK_OBD_IDX_TX_MAPP_PARAM;
-		wObdCommIndex = EPL_PDOK_OBD_IDX_TX_COMM_PARAM;
-		for (wPdoId = 0;; wPdoId++, wObdCommIndex++, wObdMappIndex++) {
-			ObdSize = 1;
-			// read node ID from OD
-			Ret =
-			    EplObdReadEntry(wObdCommIndex, 0x01, &bObdData,
-					    &ObdSize);
-			if ((Ret == kEplObdIndexNotExist)
-			    || (Ret == kEplObdSubindexNotExist)
-			    || (Ret == kEplObdIllegalPart)) {	// PDO does not exist; last PDO reached
-				Ret = kEplSuccessful;
-				goto Exit;
-			} else if (Ret != kEplSuccessful) {	// other fatal error occured
-				goto Exit;
-			}
-			// entry read successfully
-			if (bObdData != uiNodeId) {	// node ID does not equal - wrong PDO, try next PDO in OD
-				continue;
-			}
-			ObdSize = 1;
-			// read number of mapped objects from OD; this indicates if the PDO is valid
-			Ret =
-			    EplObdReadEntry(wObdMappIndex, 0x00, &bObjectCount,
-					    &ObdSize);
-			if ((Ret == kEplObdIndexNotExist)
-			    || (Ret == kEplObdSubindexNotExist)
-			    || (Ret == kEplObdIllegalPart)) {	// PDO does not exist; last PDO reached
-				Ret = kEplSuccessful;
-				goto Exit;
-			} else if (Ret != kEplSuccessful) {	// other fatal error occured
-				goto Exit;
-			}
-			// entry read successfully
-			if (bObjectCount == 0) {	// PDO in OD not valid, try next PDO in OD
-				continue;
-			}
-			// valid TPDO found
-
-			ObdSize = 1;
-			// get PDO mapping version from OD
-			Ret =
-			    EplObdReadEntry(wObdCommIndex, 0x02, &bObdData,
-					    &ObdSize);
-			if (Ret != kEplSuccessful) {	// other fatal error occured
-				goto Exit;
-			}
-			// entry read successfully
-			// set PDO version in frame
-			AmiSetByteToLe(&pFrame->m_Data.m_Pres.m_le_bPdoVersion,
-				       bObdData);
-
-			// calculate PDO size
-			wPdoSize = 0;
-
-			// process mapping
-			for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
-			     bMappSubindex++) {
-				ObdSize = 8;	// u64
-				// read object mapping from OD
-				Ret =
-				    EplObdReadEntry(wObdMappIndex,
-						    bMappSubindex,
-						    &qwObjectMapping, &ObdSize);
-				if (Ret != kEplSuccessful) {	// other fatal error occured
-					goto Exit;
-				}
-				// check if object mapping entry is valid, i.e. unequal zero, because "empty" entries are allowed
-				if (qwObjectMapping == 0) {	// invalid entry, continue with next entry
-					continue;
-				}
-				// decode object mapping
-				wObdCommIndex =
-				    (u16) (qwObjectMapping &
-					    0x000000000000FFFFLL);
-				bObdSubindex =
-				    (u8) ((qwObjectMapping &
-					     0x0000000000FF0000LL) >> 16);
-				wBitOffset =
-				    (u16) ((qwObjectMapping &
-					     0x0000FFFF00000000LL) >> 32);
-				wBitSize =
-				    (u16) ((qwObjectMapping &
-					     0xFFFF000000000000LL) >> 48);
-
-				// calculate max PDO size
-				ObdSize = wBitSize >> 3;
-				wVarSize = (wBitOffset >> 3) + (u16) ObdSize;
-				if ((unsigned int)(wVarSize + 24) > pFrameInfo->m_uiFrameSize) {	// TPDO is too short
-					// $$$ raise PDO error, set Ret
-					goto Exit;
-				}
-				if (wVarSize > wPdoSize) {	// memorize new PDO size
-					wPdoSize = wVarSize;
-				}
-				// copy object from process/OD variable to TPDO
-				Ret =
-				    EplObdReadEntryToLe(wObdCommIndex,
-							bObdSubindex,
-							&pFrame->m_Data.m_Pres.
-							m_le_abPayload[(wBitOffset >> 3)], &ObdSize);
-				if (Ret != kEplSuccessful) {	// other fatal error occured
-					goto Exit;
-				}
-
-			}
-
-			// set PDO size in frame
-			AmiSetWordToLe(&pFrame->m_Data.m_Pres.m_le_wSize,
-				       wPdoSize);
-
-			Ret = EplPdokCalAreTpdosValid(&fValid);
-			if (fValid != FALSE) {
-				// set TPDO valid
-				bFrameData =
-				    AmiGetByteFromLe(&pFrame->m_Data.m_Pres.
-						     m_le_bFlag1);
-				AmiSetByteToLe(&pFrame->m_Data.m_Pres.
-					       m_le_bFlag1,
-					       (bFrameData |
-						EPL_FRAME_FLAG1_RD));
-			}
-			// processing finished successfully
-
-			goto Exit;
-		}
-		break;
-
-	case kEplEventTypePdoSoa:	// SoA received
-
-		// invalidate TPDOs
-		Ret = EplPdokCalSetTpdosValid(FALSE);
-		break;
-
-	default:
-		{
-			ASSERTMSG(FALSE,
-				  "EplPdokProcess(): unhandled event type!\n");
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplPdokCal.c b/drivers/staging/epl/EplPdokCal.c
deleted file mode 100644
index f44c475..0000000
--- a/drivers/staging/epl/EplPdokCal.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for kernel PDO Communication Abstraction Layer 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: EplPdokCal.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/27 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "kernel/EplPdokCal.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          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  EplPdokCal                                          */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	BOOL m_fTpdosValid;
-
-} tEplPdokCalInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplPdokCalInstance EplPdokCalInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokCalAddInstance()
-//
-// Description: add and initialize new instance of EPL stack
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokCalAddInstance(void)
-{
-
-	EPL_MEMSET(&EplPdokCalInstance_g, 0, sizeof(EplPdokCalInstance_g));
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokCalDelInstance()
-//
-// Description: deletes an instance of EPL stack
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokCalDelInstance(void)
-{
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokCalSetTpdosValid()
-//
-// Description: This function sets the validity flag for TPDOs to the
-//              specified value.
-//
-// Parameters:  fValid_p                = validity flag
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokCalSetTpdosValid(BOOL fValid_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	EplPdokCalInstance_g.m_fTpdosValid = fValid_p;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdokCalAreTpdosValid()
-//
-// Description: This function returns the validity flag for TPDOs.
-//
-// Parameters:  pfValid_p               = OUT: validity flag
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdokCalAreTpdosValid(BOOL * pfValid_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	*pfValid_p = EplPdokCalInstance_g.m_fTpdosValid;
-
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-#endif
-
-// EOF
diff --git a/drivers/staging/epl/EplPdou.c b/drivers/staging/epl/EplPdou.c
deleted file mode 100644
index d6d0624..0000000
--- a/drivers/staging/epl/EplPdou.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for user PDO module
-                Currently, this module just implements a OD callback function
-                to check if the PDO configuration is valid.
-
-  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: EplPdou.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#include "EplInc.h"
-//#include "user/EplPdouCal.h"
-#include "user/EplObdu.h"
-#include "user/EplPdou.h"
-#include "EplSdoAc.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
-#error "EPL PDOu module needs EPL module OBDU or OBDK!"
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define EPL_PDOU_OBD_IDX_RX_COMM_PARAM  0x1400
-#define EPL_PDOU_OBD_IDX_RX_MAPP_PARAM  0x1600
-#define EPL_PDOU_OBD_IDX_TX_COMM_PARAM  0x1800
-#define EPL_PDOU_OBD_IDX_TX_MAPP_PARAM  0x1A00
-#define EPL_PDOU_OBD_IDX_MAPP_PARAM     0x0200
-#define EPL_PDOU_OBD_IDX_MASK           0xFF00
-#define EPL_PDOU_PDO_ID_MASK            0x00FF
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  EplPdou                                             */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
-					  unsigned int uiIndex_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(u64 qwObjectMapping_p,
-					    tEplObdAccess AccessType_p,
-					    u32 * pdwAbortCode_p,
-					    unsigned int *puiPdoSize_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdouAddInstance()
-//
-// Description: add and initialize new instance of EPL stack
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdouAddInstance(void)
-{
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdouDelInstance()
-//
-// Description: deletes an instance of EPL stack
-//
-// Parameters:  none
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdouDelInstance(void)
-{
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdouCbObdAccess
-//
-// Description: callback function for OD accesses
-//
-// Parameters:  pParam_p                = OBD parameter
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiPdoId;
-	unsigned int uiIndexType;
-	tEplObdSize ObdSize;
-	u8 bObjectCount;
-	u64 qwObjectMapping;
-	tEplObdAccess AccessType;
-	u8 bMappSubindex;
-	unsigned int uiCurPdoSize;
-	u16 wMaxPdoSize;
-	unsigned int uiSubIndex;
-
-	// fetch PDO ID
-	uiPdoId = pParam_p->m_uiIndex & EPL_PDOU_PDO_ID_MASK;
-
-	// fetch object index type
-	uiIndexType = pParam_p->m_uiIndex & EPL_PDOU_OBD_IDX_MASK;
-
-	if (pParam_p->m_ObdEvent != kEplObdEvPreWrite) {	// read accesses, post write events etc. are OK
-		pParam_p->m_dwAbortCode = 0;
-		goto Exit;
-	}
-	// check index type
-	switch (uiIndexType) {
-	case EPL_PDOU_OBD_IDX_RX_COMM_PARAM:
-		// RPDO communication parameter accessed
-	case EPL_PDOU_OBD_IDX_TX_COMM_PARAM:
-		{		// TPDO communication parameter accessed
-			Ret = EplPdouCheckPdoValidity(pParam_p,
-						      (EPL_PDOU_OBD_IDX_MAPP_PARAM
-						       | pParam_p->m_uiIndex));
-			if (Ret != kEplSuccessful) {	// PDO is valid or does not exist
-				goto Exit;
-			}
-
-			goto Exit;
-		}
-
-	case EPL_PDOU_OBD_IDX_RX_MAPP_PARAM:
-		{		// RPDO mapping parameter accessed
-
-			AccessType = kEplObdAccWrite;
-			break;
-		}
-
-	case EPL_PDOU_OBD_IDX_TX_MAPP_PARAM:
-		{		// TPDO mapping parameter accessed
-
-			AccessType = kEplObdAccRead;
-			break;
-		}
-
-	default:
-		{		// this callback function is only for
-			// PDO mapping and communication parameters
-			pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
-			goto Exit;
-		}
-	}
-
-	// RPDO and TPDO mapping parameter accessed
-
-	if (pParam_p->m_uiSubIndex == 0) {	// object mapping count accessed
-
-		// PDO is enabled or disabled
-		bObjectCount = *((u8 *) pParam_p->m_pArg);
-
-		if (bObjectCount == 0) {	// PDO shall be disabled
-
-			// that is always possible
-			goto Exit;
-		}
-		// PDO shall be enabled
-		// it should have been disabled for this operation
-		Ret = EplPdouCheckPdoValidity(pParam_p, pParam_p->m_uiIndex);
-		if (Ret != kEplSuccessful) {	// PDO is valid or does not exist
-			goto Exit;
-		}
-
-		if (AccessType == kEplObdAccWrite) {
-			uiSubIndex = 0x04;	// PReqActPayloadLimit_U16
-		} else {
-			uiSubIndex = 0x05;	// PResActPayloadLimit_U16
-		}
-
-		// fetch maximum PDO size from Object 1F98h: NMT_CycleTiming_REC
-		ObdSize = sizeof(wMaxPdoSize);
-		Ret =
-		    EplObduReadEntry(0x1F98, uiSubIndex, &wMaxPdoSize,
-				     &ObdSize);
-		if (Ret != kEplSuccessful) {	// other fatal error occured
-			pParam_p->m_dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
-			goto Exit;
-		}
-		// check all objectmappings
-		for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
-		     bMappSubindex++) {
-			// read object mapping from OD
-			ObdSize = sizeof(qwObjectMapping);	// u64
-			Ret = EplObduReadEntry(pParam_p->m_uiIndex,
-					       bMappSubindex, &qwObjectMapping,
-					       &ObdSize);
-			if (Ret != kEplSuccessful) {	// other fatal error occured
-				pParam_p->m_dwAbortCode =
-				    EPL_SDOAC_GENERAL_ERROR;
-				goto Exit;
-			}
-			// check object mapping
-			Ret = EplPdouCheckObjectMapping(qwObjectMapping,
-							AccessType,
-							&pParam_p->
-							m_dwAbortCode,
-							&uiCurPdoSize);
-			if (Ret != kEplSuccessful) {	// illegal object mapping
-				goto Exit;
-			}
-
-			if (uiCurPdoSize > wMaxPdoSize) {	// mapping exceeds object size
-				pParam_p->m_dwAbortCode =
-				    EPL_SDOAC_GENERAL_ERROR;
-				Ret = kEplPdoVarNotFound;
-			}
-
-		}
-
-	} else {		// ObjectMapping
-		Ret = EplPdouCheckPdoValidity(pParam_p, pParam_p->m_uiIndex);
-		if (Ret != kEplSuccessful) {	// PDO is valid or does not exist
-			goto Exit;
-		}
-		// check existence of object and validity of object length
-
-		qwObjectMapping = *((u64 *) pParam_p->m_pArg);
-
-		Ret = EplPdouCheckObjectMapping(qwObjectMapping,
-						AccessType,
-						&pParam_p->m_dwAbortCode,
-						&uiCurPdoSize);
-
-	}
-
-      Exit:
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdouCheckPdoValidity
-//
-// Description: check if PDO is valid
-//
-// Parameters:  pParam_p                = OBD parameter
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
-					  unsigned int uiIndex_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplObdSize ObdSize;
-	u8 bObjectCount;
-
-	ObdSize = 1;
-	// read number of mapped objects from OD; this indicates if the PDO is valid
-	Ret = EplObduReadEntry(uiIndex_p, 0x00, &bObjectCount, &ObdSize);
-	if (Ret != kEplSuccessful) {	// other fatal error occured
-		pParam_p->m_dwAbortCode =
-		    EPL_SDOAC_GEN_INTERNAL_INCOMPATIBILITY;
-		goto Exit;
-	}
-	// entry read successfully
-	if (bObjectCount != 0) {	// PDO in OD is still valid
-		pParam_p->m_dwAbortCode = EPL_SDOAC_GEN_PARAM_INCOMPATIBILITY;
-		Ret = kEplPdoNotExist;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdouDecodeObjectMapping
-//
-// Description: decodes the given object mapping entry into index, subindex,
-//              bit offset and bit size.
-//
-// Parameters:  qwObjectMapping_p       = object mapping entry
-//              puiIndex_p              = [OUT] pointer to object index
-//              puiSubIndex_p           = [OUT] pointer to subindex
-//              puiBitOffset_p          = [OUT] pointer to bit offset
-//              puiBitSize_p            = [OUT] pointer to bit size
-//
-// Returns:     (void)
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p,
-				       unsigned int *puiIndex_p,
-				       unsigned int *puiSubIndex_p,
-				       unsigned int *puiBitOffset_p,
-				       unsigned int *puiBitSize_p)
-{
-	*puiIndex_p = (unsigned int)
-	    (qwObjectMapping_p & 0x000000000000FFFFLL);
-
-	*puiSubIndex_p = (unsigned int)
-	    ((qwObjectMapping_p & 0x0000000000FF0000LL) >> 16);
-
-	*puiBitOffset_p = (unsigned int)
-	    ((qwObjectMapping_p & 0x0000FFFF00000000LL) >> 32);
-
-	*puiBitSize_p = (unsigned int)
-	    ((qwObjectMapping_p & 0xFFFF000000000000LL) >> 48);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplPdouCheckObjectMapping
-//
-// Description: checks the given object mapping entry.
-//
-// Parameters:  qwObjectMapping_p       = object mapping entry
-//              AccessType_p            = access type to mapped object:
-//                                        write = RPDO and read = TPDO
-//              puiPdoSize_p            = [OUT] pointer to covered PDO size
-//                                        (offset + size) in byte;
-//                                        0 if mapping failed
-//              pdwAbortCode_p          = [OUT] pointer to SDO abort code;
-//                                        0 if mapping is possible
-//
-// Returns:     tEplKernel              = error code
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p,
-					    tEplObdAccess AccessType_p,
-					    u32 * pdwAbortCode_p,
-					    unsigned int *puiPdoSize_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplObdSize ObdSize;
-	unsigned int uiIndex;
-	unsigned int uiSubIndex;
-	unsigned int uiBitOffset;
-	unsigned int uiBitSize;
-	tEplObdAccess AccessType;
-	BOOL fNumerical;
-
-	if (qwObjectMapping_p == 0) {	// discard zero value
-		*puiPdoSize_p = 0;
-		goto Exit;
-	}
-	// decode object mapping
-	EplPdouDecodeObjectMapping(qwObjectMapping_p,
-				   &uiIndex,
-				   &uiSubIndex, &uiBitOffset, &uiBitSize);
-
-	if ((uiBitOffset & 0x7) != 0x0) {	// bit mapping is not supported
-		*pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
-		Ret = kEplPdoGranularityMismatch;
-		goto Exit;
-	}
-
-	if ((uiBitSize & 0x7) != 0x0) {	// bit mapping is not supported
-		*pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
-		Ret = kEplPdoGranularityMismatch;
-		goto Exit;
-	}
-	// check access type
-	Ret = EplObduGetAccessType(uiIndex, uiSubIndex, &AccessType);
-	if (Ret != kEplSuccessful) {	// entry doesn't exist
-		*pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_EXIST;
-		goto Exit;
-	}
-
-	if ((AccessType & kEplObdAccPdo) == 0) {	// object is not mappable
-		*pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_MAPPABLE;
-		Ret = kEplPdoVarNotFound;
-		goto Exit;
-	}
-
-	if ((AccessType & AccessType_p) == 0) {	// object is not writeable (RPDO) or readable (TPDO) respectively
-		*pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_MAPPABLE;
-		Ret = kEplPdoVarNotFound;
-		goto Exit;
-	}
-
-	ObdSize = EplObduGetDataSize(uiIndex, uiSubIndex);
-	if (ObdSize < (uiBitSize >> 3)) {	// object does not exist or has smaller size
-		*pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
-		Ret = kEplPdoVarNotFound;
-	}
-
-	Ret = EplObduIsNumerical(uiIndex, uiSubIndex, &fNumerical);
-	if (Ret != kEplSuccessful) {	// entry doesn't exist
-		*pdwAbortCode_p = EPL_SDOAC_OBJECT_NOT_EXIST;
-		goto Exit;
-	}
-
-	if ((fNumerical != FALSE)
-	    && ((uiBitSize >> 3) != ObdSize)) {
-		// object is numerical,
-		// therefor size has to fit, but it does not.
-		*pdwAbortCode_p = EPL_SDOAC_GENERAL_ERROR;
-		Ret = kEplPdoVarNotFound;
-		goto Exit;
-	}
-	// calucaled needed PDO size
-	*puiPdoSize_p = (uiBitOffset >> 3) + (uiBitSize >> 3);
-
-      Exit:
-	return Ret;
-}
-
-#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplSdo.h b/drivers/staging/epl/EplSdo.h
deleted file mode 100644
index 8002e0c..0000000
--- a/drivers/staging/epl/EplSdo.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for api function of the sdo 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: EplSdo.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
- 2006/06/26 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "EplFrame.h"
-#include "EplSdoAc.h"
-
-#ifndef _EPLSDO_H_
-#define _EPLSDO_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-// global defines
-#ifndef EPL_SDO_MAX_PAYLOAD
-#define EPL_SDO_MAX_PAYLOAD     256
-#endif
-
-// handle between Protocol Abstraction Layer and asynchronous SDO Sequence Layer
-#define EPL_SDO_UDP_HANDLE      0x8000
-#define EPL_SDO_ASND_HANDLE     0x4000
-#define EPL_SDO_ASY_HANDLE_MASK 0xC000
-#define EPL_SDO_ASY_INVALID_HDL 0x3FFF
-
-// handle between  SDO Sequence Layer and sdo command layer
-#define EPL_SDO_ASY_HANDLE      0x8000
-#define EPL_SDO_PDO_HANDLE      0x4000
-#define EPL_SDO_SEQ_HANDLE_MASK 0xC000
-#define EPL_SDO_SEQ_INVALID_HDL 0x3FFF
-
-#define EPL_ASND_HEADER_SIZE        4
-//#define EPL_SEQ_HEADER_SIZE         4
-#define EPL_ETHERNET_HEADER_SIZE    14
-
-#define EPL_SEQ_NUM_MASK            0xFC
-
-// size for send buffer and history
-#define EPL_MAX_SDO_FRAME_SIZE      EPL_C_IP_MIN_MTU
-// size for receive frame
-// -> needed because SND-Kit sends up to 1518 Byte
-//    without Sdo-Command: Maximum Segment Size
-#define EPL_MAX_SDO_REC_FRAME_SIZE  EPL_C_IP_MAX_MTU
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-// handle between Protocol Abstraction Layer and asynchronuus SDO Sequence Layer
-typedef unsigned int tEplSdoConHdl;
-
-// callback function pointer for Protocol Abstraction Layer to call
-// asynchronuus SDO Sequence Layer
-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(* tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
-					   tEplAsySdoCom *pAsySdoCom_p,
-					   unsigned int uiDataSize_p);
-
-// status of connection
-typedef enum {
-	kAsySdoConStateConnected = 0x00,
-	kAsySdoConStateInitError = 0x01,
-	kAsySdoConStateConClosed = 0x02,
-	kAsySdoConStateAckReceived = 0x03,
-	kAsySdoConStateFrameSended = 0x04,
-	kAsySdoConStateTimeout = 0x05
-} tEplAsySdoConState;
-
-// callback function pointer for asynchronuus SDO Sequence Layer to call
-// SDO Command layer for connection status
-typedef tEplKernel(* tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
-				       tEplAsySdoConState AsySdoConState_p);
-
-// handle between  SDO Command layer and application
-typedef unsigned int tEplSdoComConHdl;
-
-// status of connection
-typedef enum {
-	kEplSdoComTransferNotActive = 0x00,
-	kEplSdoComTransferRunning = 0x01,
-	kEplSdoComTransferTxAborted = 0x02,
-	kEplSdoComTransferRxAborted = 0x03,
-	kEplSdoComTransferFinished = 0x04,
-	kEplSdoComTransferLowerLayerAbort = 0x05
-} tEplSdoComConState;
-
-// SDO Services and Command-Ids from DS 1.0.0 p.152
-typedef enum {
-	kEplSdoServiceNIL = 0x00,
-	kEplSdoServiceWriteByIndex = 0x01,
-	kEplSdoServiceReadByIndex = 0x02
-	    //--------------------------------
-	    // the following services are optional and
-	    // not supported now
-/*
-    kEplSdoServiceWriteAllByIndex   = 0x03,
-    kEplSdoServiceReadAllByIndex    = 0x04,
-    kEplSdoServiceWriteByName       = 0x05,
-    kEplSdoServiceReadByName        = 0x06,
-
-    kEplSdoServiceFileWrite         = 0x20,
-    kEplSdoServiceFileRead          = 0x21,
-
-    kEplSdoServiceWriteMultiByIndex = 0x31,
-    kEplSdoServiceReadMultiByIndex  = 0x32,
-
-    kEplSdoServiceMaxSegSize        = 0x70
-
-    // 0x80 - 0xFF manufacturer specific
-
- */
-} tEplSdoServiceType;
-
-// describes if read or write access
-typedef enum {
-	kEplSdoAccessTypeRead = 0x00,
-	kEplSdoAccessTypeWrite = 0x01
-} tEplSdoAccessType;
-
-typedef enum {
-	kEplSdoTypeAuto = 0x00,
-	kEplSdoTypeUdp = 0x01,
-	kEplSdoTypeAsnd = 0x02,
-	kEplSdoTypePdo = 0x03
-} tEplSdoType;
-
-typedef enum {
-	kEplSdoTransAuto = 0x00,
-	kEplSdoTransExpedited = 0x01,
-	kEplSdoTransSegmented = 0x02
-} tEplSdoTransType;
-
-// structure to inform application about finish of SDO transfer
-typedef struct {
-	tEplSdoComConHdl m_SdoComConHdl;
-	tEplSdoComConState m_SdoComConState;
-	u32 m_dwAbortCode;
-	tEplSdoAccessType m_SdoAccessType;
-	unsigned int m_uiNodeId;	// NodeId of the target
-	unsigned int m_uiTargetIndex;	// index which was accessed
-	unsigned int m_uiTargetSubIndex;	// subindex which was accessed
-	unsigned int m_uiTransferredByte;	// number of bytes transferred
-	void *m_pUserArg;	// user definable argument pointer
-
-} tEplSdoComFinished;
-
-// callback function pointer to inform application about connection
-typedef tEplKernel(* tEplSdoFinishedCb) (tEplSdoComFinished *pSdoComFinished_p);
-
-// structure to init SDO transfer to Read or Write by Index
-typedef struct {
-	tEplSdoComConHdl m_SdoComConHdl;
-	unsigned int m_uiIndex;
-	unsigned int m_uiSubindex;
-	void *m_pData;
-	unsigned int m_uiDataSize;
-	unsigned int m_uiTimeout;	// not used in this version
-	tEplSdoAccessType m_SdoAccessType;
-	tEplSdoFinishedCb m_pfnSdoFinishedCb;
-	void *m_pUserArg;	// user definable argument pointer
-
-} tEplSdoComTransParamByIndex;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLSDO_H_
diff --git a/drivers/staging/epl/EplSdoAc.h b/drivers/staging/epl/EplSdoAc.h
deleted file mode 100644
index 400fb38..0000000
--- a/drivers/staging/epl/EplSdoAc.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  definitions for SDO Abort codes
-
-  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: EplSdoAc.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    ...
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/30 k.t.: first implementation
-
-****************************************************************************/
-
-#ifndef _EPLSDOAC_H_
-#define _EPLSDOAC_H_
-
-// =========================================================================
-// SDO abort codes
-// =========================================================================
-
-#define    EPL_SDOAC_TIME_OUT                            0x05040000L
-#define    EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER           0x05040001L
-#define    EPL_SDOAC_INVALID_BLOCK_SIZE                  0x05040002L
-#define    EPL_SDOAC_INVALID_SEQUENCE_NUMBER             0x05040003L
-#define    EPL_SDOAC_OUT_OF_MEMORY                       0x05040005L
-#define    EPL_SDOAC_UNSUPPORTED_ACCESS                  0x06010000L
-#define    EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ              0x06010001L
-#define    EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ              0x06010002L
-#define    EPL_SDOAC_OBJECT_NOT_EXIST                    0x06020000L
-#define    EPL_SDOAC_OBJECT_NOT_MAPPABLE                 0x06040041L
-#define    EPL_SDOAC_PDO_LENGTH_EXCEEDED                 0x06040042L
-#define    EPL_SDOAC_GEN_PARAM_INCOMPATIBILITY           0x06040043L
-#define    EPL_SDOAC_INVALID_HEARTBEAT_DEC               0x06040044L
-#define    EPL_SDOAC_GEN_INTERNAL_INCOMPATIBILITY        0x06040047L
-#define    EPL_SDOAC_ACCESS_FAILED_DUE_HW_ERROR          0x06060000L
-#define    EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH          0x06070010L
-#define    EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH           0x06070012L
-#define    EPL_SDOAC_DATA_TYPE_LENGTH_TOO_LOW            0x06070013L
-#define    EPL_SDOAC_SUB_INDEX_NOT_EXIST                 0x06090011L
-#define    EPL_SDOAC_VALUE_RANGE_EXCEEDED                0x06090030L
-#define    EPL_SDOAC_VALUE_RANGE_TOO_HIGH                0x06090031L
-#define    EPL_SDOAC_VALUE_RANGE_TOO_LOW                 0x06090032L
-#define    EPL_SDOAC_MAX_VALUE_LESS_MIN_VALUE            0x06090036L
-#define    EPL_SDOAC_GENERAL_ERROR                       0x08000000L
-#define    EPL_SDOAC_DATA_NOT_TRANSF_OR_STORED           0x08000020L
-#define    EPL_SDOAC_DATA_NOT_TRANSF_DUE_LOCAL_CONTROL   0x08000021L
-#define    EPL_SDOAC_DATA_NOT_TRANSF_DUE_DEVICE_STATE    0x08000022L
-#define    EPL_SDOAC_OBJECT_DICTIONARY_NOT_EXIST         0x08000023L
-#define    EPL_SDOAC_CONFIG_DATA_EMPTY                   0x08000024L
-
-#endif // _EPLSDOAC_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/EplSdoAsndu.c b/drivers/staging/epl/EplSdoAsndu.c
deleted file mode 100644
index aa8bdef..0000000
--- a/drivers/staging/epl/EplSdoAsndu.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for SDO/Asnd-Protocolabstractionlayer 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: EplSdoAsndu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.7 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/07/07 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplSdoAsndu.h"
-#include "user/EplDlluCal.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef EPL_SDO_MAX_CONNECTION_ASND
-#define EPL_SDO_MAX_CONNECTION_ASND 5
-#endif
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-// instance table
-typedef struct {
-	unsigned int m_auiSdoAsndConnection[EPL_SDO_MAX_CONNECTION_ASND];
-	tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
-
-} tEplSdoAsndInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static tEplSdoAsndInstance SdoAsndInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p);
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <EPL SDO-Asnd Protocolabstraction layer>            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: EPL SDO-Asnd Protocolabstraction layer
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsnduInit
-//
-// Description: init first instance of the module
-//
-//
-//
-// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
-//                                  callback-function
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplSdoAsnduAddInstance(fpReceiveCb_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsnduAddInstance
-//
-// Description: init additional instance of the module
-//
-//
-//
-// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
-//                                  callback-function
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// init control structure
-	EPL_MEMSET(&SdoAsndInstance_g, 0x00, sizeof(SdoAsndInstance_g));
-
-	// save pointer to callback-function
-	if (fpReceiveCb_p != NULL) {
-		SdoAsndInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
-	} else {
-		Ret = kEplSdoUdpMissCb;
-	}
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
-				       EplSdoAsnduCb, kEplDllAsndFilterLocal);
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsnduDelInstance
-//
-// Description: del instance of the module
-//              del socket and del Listen-Thread
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsnduDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	// deregister callback function from DLL
-	Ret = EplDlluCalRegAsndService(kEplDllAsndSdo,
-				       NULL, kEplDllAsndFilterNone);
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsnduInitCon
-//
-// Description: init a new connect
-//
-//
-//
-// Parameters:  pSdoConHandle_p = pointer for the new connection handle
-//              uiTargetNodeId_p = NodeId of the target node
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
-			      unsigned int uiTargetNodeId_p)
-{
-	tEplKernel Ret;
-	unsigned int uiCount;
-	unsigned int uiFreeCon;
-	unsigned int *puiConnection;
-
-	Ret = kEplSuccessful;
-
-	if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
-	    || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) {
-		Ret = kEplSdoAsndInvalidNodeId;
-		goto Exit;
-	}
-	// get free entry in control structure
-	uiCount = 0;
-	uiFreeCon = EPL_SDO_MAX_CONNECTION_ASND;
-	puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
-	while (uiCount < EPL_SDO_MAX_CONNECTION_ASND) {
-		if (*puiConnection == uiTargetNodeId_p) {	// existing connection to target node found
-			// save handle for higher layer
-			*pSdoConHandle_p = (uiCount | EPL_SDO_ASND_HANDLE);
-
-			goto Exit;
-		} else if (*puiConnection == 0) {	// free entry-> save target nodeId
-			uiFreeCon = uiCount;
-		}
-		uiCount++;
-		puiConnection++;
-	}
-
-	if (uiFreeCon == EPL_SDO_MAX_CONNECTION_ASND) {
-		// no free connection
-		Ret = kEplSdoAsndNoFreeHandle;
-	} else {
-		puiConnection =
-		    &SdoAsndInstance_g.m_auiSdoAsndConnection[uiFreeCon];
-		*puiConnection = uiTargetNodeId_p;
-		// save handle for higher layer
-		*pSdoConHandle_p = (uiFreeCon | EPL_SDO_ASND_HANDLE);
-
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsnduSendData
-//
-// Description: send data using exisiting connection
-//
-//
-//
-// Parameters:  SdoConHandle_p  = connection handle
-//              pSrcData_p      = pointer to data
-//              dwDataSize_p    = number of databyte
-//                                  -> without asnd-header!!!
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
-			       tEplFrame *pSrcData_p,
-			       u32 dwDataSize_p)
-{
-	tEplKernel Ret;
-	unsigned int uiArray;
-	tEplFrameInfo FrameInfo;
-
-	Ret = kEplSuccessful;
-
-	uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
-
-	if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) {
-		Ret = kEplSdoAsndInvalidHandle;
-		goto Exit;
-	}
-	// fillout Asnd header
-	// own node id not needed -> filled by DLL
-
-	// set message type
-	AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (u8) kEplMsgTypeAsnd);	// ASnd == 0x06
-	// target node id
-	AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId,
-		       (u8) SdoAsndInstance_g.
-		       m_auiSdoAsndConnection[uiArray]);
-	// set source-nodeid (filled by DLL 0)
-	AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
-
-	// calc size
-	dwDataSize_p += EPL_ASND_HEADER_SIZE;
-
-	// send function of DLL
-	FrameInfo.m_uiFrameSize = dwDataSize_p;
-	FrameInfo.m_pFrame = pSrcData_p;
-	EPL_MEMSET(&FrameInfo.m_NetTime, 0x00, sizeof(tEplNetTime));
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-	Ret = EplDlluCalAsyncSend(&FrameInfo, kEplDllAsyncReqPrioGeneric);
-#endif
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsnduDelCon
-//
-// Description: delete connection from intern structure
-//
-//
-//
-// Parameters:  SdoConHandle_p  = connection handle
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
-{
-	tEplKernel Ret;
-	unsigned int uiArray;
-
-	Ret = kEplSuccessful;
-
-	uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
-	// check parameter
-	if (uiArray > EPL_SDO_MAX_CONNECTION_ASND) {
-		Ret = kEplSdoAsndInvalidHandle;
-		goto Exit;
-	}
-	// set target nodeId to 0
-	SdoAsndInstance_g.m_auiSdoAsndConnection[uiArray] = 0;
-
-      Exit:
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsnduCb
-//
-// Description: callback function for SDO ASnd frames
-//
-//
-//
-// Parameters:      pFrameInfo_p = Frame with SDO payload
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiCount;
-	unsigned int *puiConnection;
-	unsigned int uiNodeId;
-	unsigned int uiFreeEntry = 0xFFFF;
-	tEplSdoConHdl SdoConHdl;
-	tEplFrame *pFrame;
-
-	pFrame = pFrameInfo_p->m_pFrame;
-
-	uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
-
-	// search corresponding entry in control structure
-	uiCount = 0;
-	puiConnection = &SdoAsndInstance_g.m_auiSdoAsndConnection[0];
-	while (uiCount < EPL_SDO_MAX_CONNECTION_ASND) {
-		if (uiNodeId == *puiConnection) {
-			break;
-		} else if ((*puiConnection == 0)
-			   && (uiFreeEntry == 0xFFFF)) {	// free entry
-			uiFreeEntry = uiCount;
-		}
-		uiCount++;
-		puiConnection++;
-	}
-
-	if (uiCount == EPL_SDO_MAX_CONNECTION_ASND) {
-		if (uiFreeEntry != 0xFFFF) {
-			puiConnection =
-			    &SdoAsndInstance_g.
-			    m_auiSdoAsndConnection[uiFreeEntry];
-			*puiConnection = uiNodeId;
-			uiCount = uiFreeEntry;
-		} else {
-			EPL_DBGLVL_SDO_TRACE0
-			    ("EplSdoAsnduCb(): no free handle\n");
-			goto Exit;
-		}
-	}
-//    if (uiNodeId == *puiConnection)
-	{			// entry found or created
-		SdoConHdl = (uiCount | EPL_SDO_ASND_HANDLE);
-
-		SdoAsndInstance_g.m_fpSdoAsySeqCb(SdoConHdl,
-						  &pFrame->m_Data.m_Asnd.
-						  m_Payload.m_SdoSequenceFrame,
-						  (pFrameInfo_p->m_uiFrameSize -
-						   18));
-	}
-
-      Exit:
-	return Ret;
-
-}
-
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-// EOF
diff --git a/drivers/staging/epl/EplSdoAsySequ.c b/drivers/staging/epl/EplSdoAsySequ.c
deleted file mode 100644
index 256d708..0000000
--- a/drivers/staging/epl/EplSdoAsySequ.c
+++ /dev/null
@@ -1,2522 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for asychronous SDO Sequence Layer 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: EplSdoAsySequ.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.10 $  $Date: 2008/11/13 17:13:09 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/26 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplSdoAsySequ.h"
-
-#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) == 0) &&\
-     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) == 0)   )
-
-#error 'ERROR: At least UDP or Asnd module needed!'
-
-#endif
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define EPL_SDO_HISTORY_SIZE        5
-
-#ifndef EPL_MAX_SDO_SEQ_CON
-#define EPL_MAX_SDO_SEQ_CON         10
-#endif
-
-#define EPL_SEQ_DEFAULT_TIMEOUT     5000	// in [ms] => 5 sec
-
-#define EPL_SEQ_RETRY_COUNT         5	// => max. Timeout 30 sec
-
-#define EPL_SEQ_NUM_THRESHOLD       100	// threshold which distinguishes between old and new sequence numbers
-
-// define frame with size of Asnd-Header-, SDO Sequenze Header size, SDO Command header
-// and Ethernet-Header size
-#define EPL_SEQ_FRAME_SIZE          24
-// size of the header of the asynchronus SDO Sequence layer
-#define EPL_SEQ_HEADER_SIZE         4
-
-// buffersize for one frame in history
-#define EPL_SEQ_HISTROY_FRAME_SIZE  EPL_MAX_SDO_FRAME_SIZE
-
-// mask to get scon and rcon
-#define EPL_ASY_SDO_CON_MASK        0x03
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-// events for processfunction
-typedef enum {
-	kAsySdoSeqEventNoEvent = 0x00,	// no Event
-	kAsySdoSeqEventInitCon = 0x01,	// init connection
-	kAsySdoSeqEventFrameRec = 0x02,	// frame received
-	kAsySdoSeqEventFrameSend = 0x03,	// frame to send
-	kAsySdoSeqEventTimeout = 0x04,	// Timeout for connection
-	kAsySdoSeqEventCloseCon = 0x05	// higher layer close connection
-} tEplAsySdoSeqEvent;
-
-// structure for History-Buffer
-typedef struct {
-	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];
-
-} tEplAsySdoConHistory;
-
-// state of the statemaschine
-typedef enum {
-	kEplAsySdoStateIdle = 0x00,
-	kEplAsySdoStateInit1 = 0x01,
-	kEplAsySdoStateInit2 = 0x02,
-	kEplAsySdoStateInit3 = 0x03,
-	kEplAsySdoStateConnected = 0x04,
-	kEplAsySdoStateWaitAck = 0x05
-} tEplAsySdoState;
-
-// connection control structure
-typedef struct {
-	tEplSdoConHdl m_ConHandle;
-	tEplAsySdoState m_SdoState;
-	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
-	unsigned int m_uiUseCount;	// one sequence layer connection may be used by
-	// multiple command layer connections
-
-} tEplAsySdoSeqCon;
-
-// instance structure
-typedef struct {
-	tEplAsySdoSeqCon m_AsySdoConnection[EPL_MAX_SDO_SEQ_CON];
-	tEplSdoComReceiveCb m_fpSdoComReceiveCb;
-	tEplSdoComConCb m_fpSdoComConCb;
-
-#if defined(WIN32) || defined(_WIN32)
-	LPCRITICAL_SECTION m_pCriticalSection;
-	CRITICAL_SECTION m_CriticalSection;
-
-	LPCRITICAL_SECTION m_pCriticalSectionReceive;
-	CRITICAL_SECTION m_CriticalSectionReceive;
-#endif
-
-} tEplAsySdoSequInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static tEplAsySdoSequInstance AsySdoSequInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p,
-				      unsigned int uiDataSize_p,
-				      tEplFrame * pData_p,
-				      tEplAsySdoSeq * pRecFrame_p,
-				      tEplAsySdoSeqEvent Event_p);
-
-static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					 unsigned int uiDataSize_p,
-					 tEplFrame * pData_p,
-					 BOOL fFrameInHistory);
-
-static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     unsigned int uiDataSize_p,
-					     tEplFrame * pEplFrame_p);
-
-tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
-			      tEplAsySdoSeq *pSdoSeqData_p,
-			      unsigned int uiDataSize_p);
-
-static tEplKernel EplSdoAsyInitHistory(void);
-
-static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     tEplFrame * pFrame_p,
-					     unsigned int uiSize_p);
-
-static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     u8 bRecSeqNumber_p);
-
-static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					   tEplFrame ** ppFrame_p,
-					   unsigned int *puiSize_p,
-					   BOOL fInitRead);
-
-static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon *
-						       pAsySdoSeqCon_p);
-
-static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-				       unsigned long ulTimeout);
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <EPL asychronus SDO Sequence layer>                 */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: this module contains the asynchronus SDO Sequence Layer for
-//              the EPL SDO service
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqInit
-//
-// Description: init first instance
-//
-//
-//
-// Parameters:  fpSdoComCb_p    = callback function to inform Command layer
-//                                about new frames
-//              fpSdoComConCb_p = callback function to inform command layer
-//                                about connection state
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
-			    tEplSdoComConCb fpSdoComConCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplSdoAsySeqAddInstance(fpSdoComCb_p, fpSdoComConCb_p);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqAddInstance
-//
-// Description: init following instances
-//
-//
-//
-// Parameters:  fpSdoComCb_p    = callback function to inform Command layer
-//                                about new frames
-//              fpSdoComConCb_p = callback function to inform command layer
-//                                about connection state
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
-				   tEplSdoComConCb fpSdoComConCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// check functionpointer
-	if (fpSdoComCb_p == NULL) {
-		Ret = kEplSdoSeqMissCb;
-		goto Exit;
-	} else {
-		AsySdoSequInstance_g.m_fpSdoComReceiveCb = fpSdoComCb_p;
-	}
-
-	// check functionpointer
-	if (fpSdoComConCb_p == NULL) {
-		Ret = kEplSdoSeqMissCb;
-		goto Exit;
-	} else {
-		AsySdoSequInstance_g.m_fpSdoComConCb = fpSdoComConCb_p;
-	}
-
-	// set controllstructure to 0
-	EPL_MEMSET(&AsySdoSequInstance_g.m_AsySdoConnection[0], 0x00,
-		   sizeof(AsySdoSequInstance_g.m_AsySdoConnection));
-
-	// init History
-	Ret = EplSdoAsyInitHistory();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#if defined(WIN32) || defined(_WIN32)
-	// create critical section for process function
-	AsySdoSequInstance_g.m_pCriticalSection =
-	    &AsySdoSequInstance_g.m_CriticalSection;
-	InitializeCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
-
-	// init critical section for receive cb function
-	AsySdoSequInstance_g.m_pCriticalSectionReceive =
-	    &AsySdoSequInstance_g.m_CriticalSectionReceive;
-	InitializeCriticalSection(AsySdoSequInstance_g.
-				  m_pCriticalSectionReceive);
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-	// init lower layer
-	Ret = EplSdoUdpuAddInstance(EplSdoAsyReceiveCb);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-	// init lower layer
-	Ret = EplSdoAsnduAddInstance(EplSdoAsyReceiveCb);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqDelInstance
-//
-// Description: delete instances
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsySeqDelInstance(void)
-{
-	tEplKernel Ret;
-	unsigned int uiCount;
-	tEplAsySdoSeqCon *pAsySdoSeqCon;
-
-	Ret = kEplSuccessful;
-
-	// delete timer of open connections
-	uiCount = 0;
-	pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0];
-	while (uiCount < EPL_MAX_SDO_SEQ_CON) {
-		if (pAsySdoSeqCon->m_ConHandle != 0) {
-			EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
-		}
-		uiCount++;
-		pAsySdoSeqCon++;
-	}
-
-#if defined(WIN32) || defined(_WIN32)
-	// delete critical section for process function
-	DeleteCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
-#endif
-
-	// set instance-table to 0
-	EPL_MEMSET(&AsySdoSequInstance_g, 0x00, sizeof(AsySdoSequInstance_g));
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-	// delete lower layer
-	Ret = EplSdoUdpuDelInstance();
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-	// delete lower layer
-	Ret = EplSdoAsnduDelInstance();
-#endif
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqInitCon
-//
-// Description: start initialization of a sequence layer connection.
-//              It tries to reuse an existing connection to the same node.
-//
-//
-// Parameters:  pSdoSeqConHdl_p = pointer to the variable for the connection handle
-//              uiNodeId_p      = Node Id of the target
-//              SdoType          = Type of the SDO connection
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
-			       unsigned int uiNodeId_p,
-			       tEplSdoType SdoType)
-{
-	tEplKernel Ret;
-	unsigned int uiCount;
-	unsigned int uiFreeCon;
-	tEplSdoConHdl ConHandle;
-	tEplAsySdoSeqCon *pAsySdoSeqCon;
-	Ret = kEplSuccessful;
-
-	// check SdoType
-	// call init function of the protcol abstraction layer
-	// which tries to find an existing connection to the same node
-	switch (SdoType) {
-		// SDO over UDP
-	case kEplSdoTypeUdp:
-		{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-			Ret = EplSdoUdpuInitCon(&ConHandle, uiNodeId_p);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-#else
-			Ret = kEplSdoSeqUnsupportedProt;
-#endif
-			break;
-		}
-
-		// SDO over Asnd
-	case kEplSdoTypeAsnd:
-		{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-			Ret = EplSdoAsnduInitCon(&ConHandle, uiNodeId_p);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-#else
-			Ret = kEplSdoSeqUnsupportedProt;
-#endif
-			break;
-		}
-
-		// unsupported protocols
-		// -> auto should be replaced by command layer
-	case kEplSdoTypeAuto:
-	case kEplSdoTypePdo:
-	default:
-		{
-			Ret = kEplSdoSeqUnsupportedProt;
-			goto Exit;
-		}
-
-	}			// end of switch(SdoType)
-
-	// find existing connection to the same node or find empty entry for connection
-	uiCount = 0;
-	uiFreeCon = EPL_MAX_SDO_SEQ_CON;
-	pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[0];
-
-	while (uiCount < EPL_MAX_SDO_SEQ_CON) {
-		if (pAsySdoSeqCon->m_ConHandle == ConHandle) {	// existing connection found
-			break;
-		}
-		if (pAsySdoSeqCon->m_ConHandle == 0) {
-			uiFreeCon = uiCount;
-		}
-		uiCount++;
-		pAsySdoSeqCon++;
-	}
-
-	if (uiCount == EPL_MAX_SDO_SEQ_CON) {
-		if (uiFreeCon == EPL_MAX_SDO_SEQ_CON) {	// no free entry found
-			switch (SdoType) {
-				// SDO over UDP
-			case kEplSdoTypeUdp:
-				{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-					Ret = EplSdoUdpuDelCon(ConHandle);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-#endif
-					break;
-				}
-
-				// SDO over Asnd
-			case kEplSdoTypeAsnd:
-				{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-					Ret = EplSdoAsnduDelCon(ConHandle);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-#endif
-					break;
-				}
-
-				// unsupported protocols
-				// -> auto should be replaced by command layer
-			case kEplSdoTypeAuto:
-			case kEplSdoTypePdo:
-			default:
-				{
-					Ret = kEplSdoSeqUnsupportedProt;
-					goto Exit;
-				}
-
-			}	// end of switch(SdoType)
-
-			Ret = kEplSdoSeqNoFreeHandle;
-			goto Exit;
-		} else {	// free entry found
-			pAsySdoSeqCon =
-			    &AsySdoSequInstance_g.m_AsySdoConnection[uiFreeCon];
-			pAsySdoSeqCon->m_ConHandle = ConHandle;
-			uiCount = uiFreeCon;
-		}
-	}
-	// set handle
-	*pSdoSeqConHdl_p = (uiCount | EPL_SDO_ASY_HANDLE);
-
-	// increment use counter
-	pAsySdoSeqCon->m_uiUseCount++;
-
-	// call intern process function
-	Ret = EplSdoAsySeqProcess(uiCount,
-				  0, NULL, NULL, kAsySdoSeqEventInitCon);
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqSendData
-//
-// Description: send sata unsing a established connection
-//
-//
-//
-// Parameters:  pSdoSeqConHdl_p = connection handle
-//              uiDataSize_p    = Size of Frame to send
-//                                  -> wihtout SDO sequence layer header, Asnd header
-//                                     and ethernetnet
-//                                  ==> SDO Sequence layer payload
-//              SdoType          = Type of the SDO connection
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				unsigned int uiDataSize_p,
-				tEplFrame *pabData_p)
-{
-	tEplKernel Ret;
-	unsigned int uiHandle;
-
-	uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK);
-
-	// check if connection ready
-	if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].m_SdoState ==
-	    kEplAsySdoStateIdle) {
-		// no connection with this handle
-		Ret = kEplSdoSeqInvalidHdl;
-		goto Exit;
-	} else if (AsySdoSequInstance_g.m_AsySdoConnection[uiHandle].
-		   m_SdoState != kEplAsySdoStateConnected) {
-		Ret = kEplSdoSeqConnectionBusy;
-		goto Exit;
-	}
-
-	Ret = EplSdoAsySeqProcess(uiHandle,
-				  uiDataSize_p,
-				  pabData_p, NULL, kAsySdoSeqEventFrameSend);
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqProcessEvent
-//
-// Description: function processes extern events
-//              -> later needed for timeout controll with timer-module
-//
-//
-//
-// Parameters:  pEvent_p = pointer to event
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p)
-{
-	tEplKernel Ret;
-	tEplTimerEventArg *pTimerEventArg;
-	tEplAsySdoSeqCon *pAsySdoSeqCon;
-	tEplTimerHdl EplTimerHdl;
-	unsigned int uiCount;
-
-	Ret = kEplSuccessful;
-	// check parameter
-	if (pEvent_p == NULL) {
-		Ret = kEplSdoSeqInvalidEvent;
-		goto Exit;
-	}
-
-	if (pEvent_p->m_EventType != kEplEventTypeTimer) {
-		Ret = kEplSdoSeqInvalidEvent;
-		goto Exit;
-	}
-	// get timerhdl
-	pTimerEventArg = (tEplTimerEventArg *) pEvent_p->m_pArg;
-	EplTimerHdl = pTimerEventArg->m_TimerHdl;
-
-	// get pointer to intern control structure of connection
-	if (pTimerEventArg->m_ulArg == 0) {
-		goto Exit;
-	}
-	pAsySdoSeqCon = (tEplAsySdoSeqCon *) pTimerEventArg->m_ulArg;
-
-	// check if time is current
-	if (EplTimerHdl != pAsySdoSeqCon->m_EplTimerHdl) {
-		// delete timer
-		EplTimeruDeleteTimer(&EplTimerHdl);
-		goto Exit;
-	}
-	// delete timer
-	EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
-
-	// get indexnumber of control structure
-	uiCount = 0;
-	while ((&AsySdoSequInstance_g.m_AsySdoConnection[uiCount]) !=
-	       pAsySdoSeqCon) {
-		uiCount++;
-		if (uiCount > EPL_MAX_SDO_SEQ_CON) {
-			goto Exit;
-		}
-	}
-
-	// process event and call processfunction if needed
-	Ret = EplSdoAsySeqProcess(uiCount,
-				  0, NULL, NULL, kAsySdoSeqEventTimeout);
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqDelCon
-//
-// Description: del and close one connection
-//
-//
-//
-// Parameters:  SdoSeqConHdl_p = handle of connection
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiHandle;
-	tEplAsySdoSeqCon *pAsySdoSeqCon;
-
-	uiHandle = (SdoSeqConHdl_p & ~EPL_SDO_SEQ_HANDLE_MASK);
-
-	// check if handle invalid
-	if (uiHandle >= EPL_MAX_SDO_SEQ_CON) {
-		Ret = kEplSdoSeqInvalidHdl;
-		goto Exit;
-	}
-	// get pointer to connection
-	pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle];
-
-	// decrement use counter
-	pAsySdoSeqCon->m_uiUseCount--;
-
-	if (pAsySdoSeqCon->m_uiUseCount == 0) {
-		// process close in processfunction
-		Ret = EplSdoAsySeqProcess(uiHandle,
-					  0,
-					  NULL, NULL, kAsySdoSeqEventCloseCon);
-
-		//check protocol
-		if ((pAsySdoSeqCon->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) ==
-		    EPL_SDO_UDP_HANDLE) {
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-			// call close function of lower layer
-			EplSdoUdpuDelCon(pAsySdoSeqCon->m_ConHandle);
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-		} else {
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-			// call close function of lower layer
-			EplSdoAsnduDelCon(pAsySdoSeqCon->m_ConHandle);
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-		}
-
-		// delete timer
-		EplTimeruDeleteTimer(&pAsySdoSeqCon->m_EplTimerHdl);
-
-		// clean controllstructure
-		EPL_MEMSET(pAsySdoSeqCon, 0x00, sizeof(tEplAsySdoSeqCon));
-		pAsySdoSeqCon->m_SdoConHistory.m_bFreeEntries =
-		    EPL_SDO_HISTORY_SIZE;
-	}
-
-      Exit:
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplEplSdoAsySeqProcess
-//
-// Description: intern function to process the asynchronus SDO Sequence Layer
-//              state maschine
-//
-//
-//
-// Parameters:  uiHandle_p      = index of the control structure of the connection
-//              uiDataSize_p    = size of data frame to process (can be 0)
-//                                  -> without size of sequence header and Asnd header!!!
-//
-//              pData_p         = pointer to frame to send (can be NULL)
-//              pRecFrame_p     = pointer to received frame (can be NULL)
-//              Event_p         = Event to process
-//
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p,
-				      unsigned int uiDataSize_p,
-				      tEplFrame * pData_p,
-				      tEplAsySdoSeq * pRecFrame_p,
-				      tEplAsySdoSeqEvent Event_p)
-{
-	tEplKernel Ret;
-	unsigned int uiFrameSize;
-	tEplFrame *pEplFrame;
-	tEplAsySdoSeqCon *pAsySdoSeqCon;
-	tEplSdoSeqConHdl SdoSeqConHdl;
-	unsigned int uiFreeEntries;
-
-#if defined(WIN32) || defined(_WIN32)
-	// enter  critical section for process function
-	EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
-#endif
-
-	Ret = kEplSuccessful;
-
-	// get handle for hinger layer
-	SdoSeqConHdl = uiHandle_p | EPL_SDO_ASY_HANDLE;
-
-	// check if handle invalid
-	if ((SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) ==
-	    EPL_SDO_SEQ_INVALID_HDL) {
-		Ret = kEplSdoSeqInvalidHdl;
-		goto Exit;
-	}
-	// get pointer to connection
-	pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiHandle_p];
-
-	// check size
-	if ((pData_p == NULL) && (pRecFrame_p == NULL) && (uiDataSize_p != 0)) {
-		Ret = kEplSdoSeqInvalidFrame;
-		goto Exit;
-	}
-	// check state
-	switch (pAsySdoSeqCon->m_SdoState) {
-		// idle state
-	case kEplAsySdoStateIdle:
-		{
-			// check event
-			switch (Event_p) {
-				// new connection
-				// -> send init frame and change to
-				// kEplAsySdoStateInit1
-			case kAsySdoSeqEventInitCon:
-				{
-					// set sending scon to 1
-					pAsySdoSeqCon->m_bRecSeqNum = 0x01;
-					// set set send rcon to 0
-					pAsySdoSeqCon->m_bSendSeqNum = 0x00;
-					Ret =
-					    EplSdoAsySeqSendIntern
-					    (pAsySdoSeqCon, 0, NULL, FALSE);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-					// change state
-					pAsySdoSeqCon->m_SdoState =
-					    kEplAsySdoStateInit1;
-
-					// set timer
-					Ret =
-					    EplSdoAsySeqSetTimer(pAsySdoSeqCon,
-								 EPL_SEQ_DEFAULT_TIMEOUT);
-
-					break;
-				}
-
-				// init con from extern
-				// check rcon and scon
-				// -> send answer
-			case kAsySdoSeqEventFrameRec:
-				{
-/*
-                    PRINTF3("%s scon=%u rcon=%u\n",
-                            __func__,
-                            pRecFrame_p->m_le_bSendSeqNumCon,
-                            pRecFrame_p->m_le_bRecSeqNumCon);
-*/
-					// check if scon == 1 and rcon == 0
-					if (((pRecFrame_p->
-					      m_le_bRecSeqNumCon &
-					      EPL_ASY_SDO_CON_MASK) == 0x00)
-					    &&
-					    ((pRecFrame_p->
-					      m_le_bSendSeqNumCon &
-					      EPL_ASY_SDO_CON_MASK) == 0x01)) {
-						// save sequence numbers
-						pAsySdoSeqCon->m_bRecSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bRecSeqNumCon);
-						pAsySdoSeqCon->m_bSendSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bSendSeqNumCon);
-						// create answer and send answer
-						// set rcon to 1 (in send direction own scon)
-						pAsySdoSeqCon->m_bRecSeqNum++;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						// change state to kEplAsySdoStateInit2
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateInit2;
-
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-					} else {	// error -> close
-						// delete timer
-						EplTimeruDeleteTimer
-						    (&pAsySdoSeqCon->
-						     m_EplTimerHdl);
-						if (((pRecFrame_p->
-						      m_le_bRecSeqNumCon &
-						      EPL_ASY_SDO_CON_MASK) !=
-						     0x00)
-						    || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {	// d.k. only answer with close message if the message sent was not a close message
-							// save sequence numbers
-							pAsySdoSeqCon->
-							    m_bRecSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bRecSeqNumCon);
-							pAsySdoSeqCon->
-							    m_bSendSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bSendSeqNumCon);
-							// set rcon and scon to 0
-							pAsySdoSeqCon->
-							    m_bSendSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							pAsySdoSeqCon->
-							    m_bRecSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							// send frame
-							EplSdoAsySeqSendIntern
-							    (pAsySdoSeqCon, 0,
-							     NULL, FALSE);
-						}
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateInitError);
-					}
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of switch(Event_p)
-			break;
-		}
-
-		// init connection step 1
-		// wait for frame with scon = 1
-		// and rcon = 1
-	case kEplAsySdoStateInit1:
-		{
-//            PRINTF0("EplSdoAsySequ: StateInit1\n");
-
-			// check event
-			switch (Event_p) {
-				// frame received
-			case kAsySdoSeqEventFrameRec:
-				{
-					// check scon == 1 and rcon == 1
-					if (((pRecFrame_p->
-					      m_le_bRecSeqNumCon &
-					      EPL_ASY_SDO_CON_MASK) == 0x01)
-					    && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x01)) {	// create answer own scon = 2
-						// save sequence numbers
-						pAsySdoSeqCon->m_bRecSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bRecSeqNumCon);
-						pAsySdoSeqCon->m_bSendSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bSendSeqNumCon);
-
-						pAsySdoSeqCon->m_bRecSeqNum++;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						// change state to kEplAsySdoStateInit3
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateInit3;
-
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-
-					}
-					// check if scon == 1 and rcon == 0, i.e. other side wants me to be server
-					else if (((pRecFrame_p->
-						   m_le_bRecSeqNumCon &
-						   EPL_ASY_SDO_CON_MASK) ==
-						  0x00)
-						 &&
-						 ((pRecFrame_p->
-						   m_le_bSendSeqNumCon &
-						   EPL_ASY_SDO_CON_MASK) ==
-						  0x01)) {
-						// save sequence numbers
-						pAsySdoSeqCon->m_bRecSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bRecSeqNumCon);
-						pAsySdoSeqCon->m_bSendSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bSendSeqNumCon);
-						// create answer and send answer
-						// set rcon to 1 (in send direction own scon)
-						pAsySdoSeqCon->m_bRecSeqNum++;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						// change state to kEplAsySdoStateInit2
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateInit2;
-
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-					} else {	// error -> Close
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateIdle;
-						// delete timer
-						EplTimeruDeleteTimer
-						    (&pAsySdoSeqCon->
-						     m_EplTimerHdl);
-						if (((pRecFrame_p->
-						      m_le_bRecSeqNumCon &
-						      EPL_ASY_SDO_CON_MASK) !=
-						     0x00)
-						    || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {	// d.k. only answer with close message if the message sent was not a close message
-							// save sequence numbers
-							pAsySdoSeqCon->
-							    m_bRecSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bRecSeqNumCon);
-							pAsySdoSeqCon->
-							    m_bSendSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bSendSeqNumCon);
-
-							// set rcon and scon to 0
-							pAsySdoSeqCon->
-							    m_bSendSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							pAsySdoSeqCon->
-							    m_bRecSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							// send frame
-							EplSdoAsySeqSendIntern
-							    (pAsySdoSeqCon, 0,
-							     NULL, FALSE);
-						}
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateInitError);
-					}
-					break;
-				}
-
-				// timeout
-			case kAsySdoSeqEventTimeout:
-				{	// error -> Close
-					pAsySdoSeqCon->m_SdoState =
-					    kEplAsySdoStateIdle;
-
-					// set rcon and scon to 0
-					pAsySdoSeqCon->m_bSendSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					pAsySdoSeqCon->m_bRecSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					// send frame
-					EplSdoAsySeqSendIntern(pAsySdoSeqCon,
-							       0, NULL, FALSE);
-					// call Command Layer Cb
-					AsySdoSequInstance_g.
-					    m_fpSdoComConCb(SdoSeqConHdl,
-							    kAsySdoConStateInitError);
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of switch(Event_p)
-			break;
-		}
-
-		// init connection step 2
-	case kEplAsySdoStateInit2:
-		{
-//            PRINTF0("EplSdoAsySequ: StateInit2\n");
-
-			// check event
-			switch (Event_p) {
-				// frame received
-			case kAsySdoSeqEventFrameRec:
-				{
-					// check scon == 2 and rcon == 1
-					if (((pRecFrame_p->
-					      m_le_bRecSeqNumCon &
-					      EPL_ASY_SDO_CON_MASK) == 0x01)
-					    && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) {	// create answer own rcon = 2
-						// save sequence numbers
-						pAsySdoSeqCon->m_bRecSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bRecSeqNumCon);
-						pAsySdoSeqCon->m_bSendSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bSendSeqNumCon);
-
-						pAsySdoSeqCon->m_bRecSeqNum++;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						// change state to kEplAsySdoStateConnected
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateConnected;
-
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateConnected);
-
-					}
-					// check scon == 1 and rcon == 1, i.e. other side wants me to initiate the connection
-					else if (((pRecFrame_p->
-						   m_le_bRecSeqNumCon &
-						   EPL_ASY_SDO_CON_MASK) ==
-						  0x01)
-						 &&
-						 ((pRecFrame_p->
-						   m_le_bSendSeqNumCon &
-						   EPL_ASY_SDO_CON_MASK) ==
-						  0x01)) {
-						// save sequence numbers
-						pAsySdoSeqCon->m_bRecSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bRecSeqNumCon);
-						pAsySdoSeqCon->m_bSendSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bSendSeqNumCon);
-						// create answer and send answer
-						// set rcon to 1 (in send direction own scon)
-						pAsySdoSeqCon->m_bRecSeqNum++;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-						// change state to kEplAsySdoStateInit3
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateInit3;
-
-					} else {	// error -> Close
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateIdle;
-						// delete timer
-						EplTimeruDeleteTimer
-						    (&pAsySdoSeqCon->
-						     m_EplTimerHdl);
-						if (((pRecFrame_p->
-						      m_le_bRecSeqNumCon &
-						      EPL_ASY_SDO_CON_MASK) !=
-						     0x00)
-						    || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {	// d.k. only answer with close message if the message sent was not a close message
-							// save sequence numbers
-							pAsySdoSeqCon->
-							    m_bRecSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bRecSeqNumCon);
-							pAsySdoSeqCon->
-							    m_bSendSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bSendSeqNumCon);
-							// set rcon and scon to 0
-							pAsySdoSeqCon->
-							    m_bSendSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							pAsySdoSeqCon->
-							    m_bRecSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							// send frame
-							EplSdoAsySeqSendIntern
-							    (pAsySdoSeqCon, 0,
-							     NULL, FALSE);
-						}
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateInitError);
-					}
-					break;
-				}
-
-				// timeout
-			case kAsySdoSeqEventTimeout:
-				{	// error -> Close
-					pAsySdoSeqCon->m_SdoState =
-					    kEplAsySdoStateIdle;
-					// set rcon and scon to 0
-					pAsySdoSeqCon->m_bSendSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					pAsySdoSeqCon->m_bRecSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					// send frame
-					EplSdoAsySeqSendIntern(pAsySdoSeqCon,
-							       0, NULL, FALSE);
-
-					// call Command Layer Cb
-					AsySdoSequInstance_g.
-					    m_fpSdoComConCb(SdoSeqConHdl,
-							    kAsySdoConStateInitError);
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of switch(Event_p)
-			break;
-		}
-
-		// init connection step 3
-	case kEplAsySdoStateInit3:
-		{
-			// check event
-			switch (Event_p) {
-				// frame received
-			case kAsySdoSeqEventFrameRec:
-				{
-					// check scon == 2 and rcon == 2
-					if (((pRecFrame_p->
-					      m_le_bRecSeqNumCon &
-					      EPL_ASY_SDO_CON_MASK) == 0x02)
-					    &&
-					    ((pRecFrame_p->
-					      m_le_bSendSeqNumCon &
-					      EPL_ASY_SDO_CON_MASK) == 0x02)) {
-						// save sequence numbers
-						pAsySdoSeqCon->m_bRecSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bRecSeqNumCon);
-						pAsySdoSeqCon->m_bSendSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bSendSeqNumCon);
-						// change state to kEplAsySdoStateConnected
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateConnected;
-
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateConnected);
-
-					}
-					// check scon == 2 and rcon == 1
-					else if (((pRecFrame_p->
-						   m_le_bRecSeqNumCon &
-						   EPL_ASY_SDO_CON_MASK) ==
-						  0x01)
-						 && ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 0x02)) {	// create answer own rcon = 2
-						// save sequence numbers
-						pAsySdoSeqCon->m_bRecSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bRecSeqNumCon);
-						pAsySdoSeqCon->m_bSendSeqNum =
-						    AmiGetByteFromLe
-						    (&pRecFrame_p->
-						     m_le_bSendSeqNumCon);
-
-						pAsySdoSeqCon->m_bRecSeqNum++;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						// change state to kEplAsySdoStateConnected
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateConnected;
-
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateConnected);
-
-					} else {	// error -> Close
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateIdle;
-						// delete timer
-						EplTimeruDeleteTimer
-						    (&pAsySdoSeqCon->
-						     m_EplTimerHdl);
-						if (((pRecFrame_p->
-						      m_le_bRecSeqNumCon &
-						      EPL_ASY_SDO_CON_MASK) !=
-						     0x00)
-						    || ((pRecFrame_p->m_le_bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) != 0x00)) {	// d.k. only answer with close message if the message sent was not a close message
-							// save sequence numbers
-							pAsySdoSeqCon->
-							    m_bRecSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bRecSeqNumCon);
-							pAsySdoSeqCon->
-							    m_bSendSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bSendSeqNumCon);
-							// set rcon and scon to 0
-							pAsySdoSeqCon->
-							    m_bSendSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							pAsySdoSeqCon->
-							    m_bRecSeqNum &=
-							    EPL_SEQ_NUM_MASK;
-							// send frame
-							EplSdoAsySeqSendIntern
-							    (pAsySdoSeqCon, 0,
-							     NULL, FALSE);
-						}
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateInitError);
-					}
-					break;
-				}
-
-				// timeout
-			case kAsySdoSeqEventTimeout:
-				{	// error -> Close
-					pAsySdoSeqCon->m_SdoState =
-					    kEplAsySdoStateIdle;
-					// set rcon and scon to 0
-					pAsySdoSeqCon->m_bSendSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					pAsySdoSeqCon->m_bRecSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					// send frame
-					EplSdoAsySeqSendIntern(pAsySdoSeqCon,
-							       0, NULL, FALSE);
-
-					// call Command Layer Cb
-					AsySdoSequInstance_g.
-					    m_fpSdoComConCb(SdoSeqConHdl,
-							    kAsySdoConStateInitError);
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of switch(Event_p)
-			break;
-		}
-
-		// connection established
-	case kEplAsySdoStateConnected:
-		{
-			// check event
-			switch (Event_p) {
-
-				// frame to send
-			case kAsySdoSeqEventFrameSend:
-				{
-					// set timer
-					Ret =
-					    EplSdoAsySeqSetTimer(pAsySdoSeqCon,
-								 EPL_SEQ_DEFAULT_TIMEOUT);
-					// check if data frame or ack
-					if (pData_p == NULL) {	// send ack
-						// inc scon
-						//pAsySdoSeqCon->m_bRecSeqNum += 4;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-					} else {	// send dataframe
-						// increment send sequence number
-						pAsySdoSeqCon->m_bRecSeqNum +=
-						    4;
-						Ret =
-						    EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon,
-						     uiDataSize_p, pData_p,
-						     TRUE);
-						if (Ret == kEplSdoSeqRequestAckNeeded) {	// request ack
-							// change state to wait ack
-							pAsySdoSeqCon->
-							    m_SdoState =
-							    kEplAsySdoStateWaitAck;
-							// set Ret to kEplSuccessful, because no error
-							// for higher layer
-							Ret = kEplSuccessful;
-
-						} else if (Ret !=
-							   kEplSuccessful) {
-							goto Exit;
-						} else {
-							// call Command Layer Cb
-							AsySdoSequInstance_g.
-							    m_fpSdoComConCb
-							    (SdoSeqConHdl,
-							     kAsySdoConStateFrameSended);
-						}
-					}
-					break;
-				}	// end of case kAsySdoSeqEventFrameSend
-
-				// frame received
-			case kAsySdoSeqEventFrameRec:
-				{
-					u8 bSendSeqNumCon =
-					    AmiGetByteFromLe(&pRecFrame_p->
-							     m_le_bSendSeqNumCon);
-
-					// set timer
-					Ret =
-					    EplSdoAsySeqSetTimer(pAsySdoSeqCon,
-								 EPL_SEQ_DEFAULT_TIMEOUT);
-					// check scon
-					switch (bSendSeqNumCon &
-						EPL_ASY_SDO_CON_MASK) {
-						// close from other node
-					case 0:
-					case 1:
-						{
-							// return to idle
-							pAsySdoSeqCon->
-							    m_SdoState =
-							    kEplAsySdoStateIdle;
-							// delete timer
-							EplTimeruDeleteTimer
-							    (&pAsySdoSeqCon->
-							     m_EplTimerHdl);
-							// call Command Layer Cb
-							AsySdoSequInstance_g.
-							    m_fpSdoComConCb
-							    (SdoSeqConHdl,
-							     kAsySdoConStateConClosed);
-
-							break;
-						}
-
-						// Request Ack or Error Ack
-						// possible contain data
-					case 3:
-						// normal frame
-					case 2:
-						{
-							if ((AmiGetByteFromLe
-							     (&pRecFrame_p->
-							      m_le_bRecSeqNumCon)
-							     &
-							     EPL_ASY_SDO_CON_MASK)
-							    == 3) {
-//                                PRINTF0("EplSdoAsySequ: error response received\n");
-
-								// error response (retransmission request)
-								// resend frames from history
-
-								// read frame from history
-								Ret =
-								    EplSdoAsyReadFromHistory
-								    (pAsySdoSeqCon,
-								     &pEplFrame,
-								     &uiFrameSize,
-								     TRUE);
-								if (Ret !=
-								    kEplSuccessful)
-								{
-									goto Exit;
-								}
-
-								while ((pEplFrame != NULL)
-								       &&
-								       (uiFrameSize
-									!= 0)) {
-									// send frame
-									Ret =
-									    EplSdoAsySeqSendLowerLayer
-									    (pAsySdoSeqCon,
-									     uiFrameSize,
-									     pEplFrame);
-									if (Ret
-									    !=
-									    kEplSuccessful)
-									{
-										goto Exit;
-									}
-									// read next frame from history
-									Ret =
-									    EplSdoAsyReadFromHistory
-									    (pAsySdoSeqCon,
-									     &pEplFrame,
-									     &uiFrameSize,
-									     FALSE);
-									if (Ret
-									    !=
-									    kEplSuccessful)
-									{
-										goto Exit;
-									}
-								}	// end of while((pabFrame != NULL)
-							}	// end of if (error response)
-
-							if (((pAsySdoSeqCon->m_bSendSeqNum + 4) & EPL_SEQ_NUM_MASK) == (bSendSeqNumCon & EPL_SEQ_NUM_MASK)) {	// next frame of sequence received
-								// save send sequence number (without ack request)
-								pAsySdoSeqCon->
-								    m_bSendSeqNum
-								    =
-								    bSendSeqNumCon
-								    & ~0x01;
-
-								// check if ack or data-frame
-								//ignore ack -> already processed
-								if (uiDataSize_p
-								    >
-								    EPL_SEQ_HEADER_SIZE)
-								{
-									AsySdoSequInstance_g.
-									    m_fpSdoComReceiveCb
-									    (SdoSeqConHdl,
-									     ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE));
-									// call Command Layer Cb
-									AsySdoSequInstance_g.
-									    m_fpSdoComConCb
-									    (SdoSeqConHdl,
-									     kAsySdoConStateFrameSended);
-
-								} else {
-									// call Command Layer Cb
-									AsySdoSequInstance_g.
-									    m_fpSdoComConCb
-									    (SdoSeqConHdl,
-									     kAsySdoConStateAckReceived);
-								}
-							} else if (((bSendSeqNumCon - pAsySdoSeqCon->m_bSendSeqNum - 4) & EPL_SEQ_NUM_MASK) < EPL_SEQ_NUM_THRESHOLD) {	// frame of sequence was lost,
-								// because difference of received and old value
-								// is less then halve of the values range.
-
-								// send error frame with own rcon = 3
-								pAsySdoSeqCon->
-								    m_bSendSeqNum
-								    |= 0x03;
-								Ret =
-								    EplSdoAsySeqSendIntern
-								    (pAsySdoSeqCon,
-								     0, NULL,
-								     FALSE);
-								// restore send sequence number
-								pAsySdoSeqCon->
-								    m_bSendSeqNum
-								    =
-								    (pAsySdoSeqCon->
-								     m_bSendSeqNum
-								     &
-								     EPL_SEQ_NUM_MASK)
-								    | 0x02;
-								if (Ret !=
-								    kEplSuccessful)
-								{
-									goto Exit;
-								}
-								// break here, because a requested acknowledge
-								// was sent implicitly above
-								break;
-							}
-							// else, ignore repeated frame
-
-							if ((bSendSeqNumCon & EPL_ASY_SDO_CON_MASK) == 3) {	// ack request received
-
-								// create ack with own scon = 2
-								Ret =
-								    EplSdoAsySeqSendIntern
-								    (pAsySdoSeqCon,
-								     0, NULL,
-								     FALSE);
-								if (Ret !=
-								    kEplSuccessful)
-								{
-									goto Exit;
-								}
-							}
-
-							break;
-						}
-
-					}	// switch(pAsySdoSeqCon->m_bSendSeqNum & EPL_ASY_SDO_CON_MASK)
-					break;
-				}	// end of case kAsySdoSeqEventFrameRec:
-
-				//close event from higher layer
-			case kAsySdoSeqEventCloseCon:
-				{
-					pAsySdoSeqCon->m_SdoState =
-					    kEplAsySdoStateIdle;
-					// set rcon and scon to 0
-					pAsySdoSeqCon->m_bSendSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					pAsySdoSeqCon->m_bRecSeqNum &=
-					    EPL_SEQ_NUM_MASK;
-					// send frame
-					EplSdoAsySeqSendIntern(pAsySdoSeqCon,
-							       0, NULL, FALSE);
-
-					// delete timer
-					EplTimeruDeleteTimer(&pAsySdoSeqCon->
-							     m_EplTimerHdl);
-					// call Command Layer Cb is not necessary, because the event came from there
-//                    AsySdoSequInstance_g.m_fpSdoComConCb(SdoSeqConHdl,
-//                                                            kAsySdoConStateInitError);
-					break;
-				}
-
-				// timeout
-			case kAsySdoSeqEventTimeout:
-				{
-
-					uiFreeEntries =
-					    EplSdoAsyGetFreeEntriesFromHistory
-					    (pAsySdoSeqCon);
-					if ((uiFreeEntries <
-					     EPL_SDO_HISTORY_SIZE)
-					    && (pAsySdoSeqCon->m_uiRetryCount < EPL_SEQ_RETRY_COUNT)) {	// unacknowlegded frames in history
-						// and retry counter not exceeded
-
-						// resend data with acknowledge request
-
-						// increment retry counter
-						pAsySdoSeqCon->m_uiRetryCount++;
-
-						// set timer
-						Ret =
-						    EplSdoAsySeqSetTimer
-						    (pAsySdoSeqCon,
-						     EPL_SEQ_DEFAULT_TIMEOUT);
-
-						// read first frame from history
-						Ret =
-						    EplSdoAsyReadFromHistory
-						    (pAsySdoSeqCon, &pEplFrame,
-						     &uiFrameSize, TRUE);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-
-						if ((pEplFrame != NULL)
-						    && (uiFrameSize != 0)) {
-
-							// set ack request in scon
-							AmiSetByteToLe
-							    (&pEplFrame->m_Data.
-							     m_Asnd.m_Payload.
-							     m_SdoSequenceFrame.
-							     m_le_bSendSeqNumCon,
-							     AmiGetByteFromLe
-							     (&pEplFrame->
-							      m_Data.m_Asnd.
-							      m_Payload.
-							      m_SdoSequenceFrame.
-							      m_le_bSendSeqNumCon)
-							     | 0x03);
-
-							// send frame
-							Ret =
-							    EplSdoAsySeqSendLowerLayer
-							    (pAsySdoSeqCon,
-							     uiFrameSize,
-							     pEplFrame);
-							if (Ret !=
-							    kEplSuccessful) {
-								goto Exit;
-							}
-
-						}
-					} else {
-						// timeout, because of no traffic -> Close
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateIdle;
-						// set rcon and scon to 0
-						pAsySdoSeqCon->m_bSendSeqNum &=
-						    EPL_SEQ_NUM_MASK;
-						pAsySdoSeqCon->m_bRecSeqNum &=
-						    EPL_SEQ_NUM_MASK;
-						// send frame
-						EplSdoAsySeqSendIntern
-						    (pAsySdoSeqCon, 0, NULL,
-						     FALSE);
-
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateTimeout);
-					}
-
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of switch(Event_p)
-			break;
-		}
-
-		// wait for Acknowledge (history buffer full)
-	case kEplAsySdoStateWaitAck:
-		{
-			PRINTF0("EplSdoAsySequ: StateWaitAck\n");
-
-			// set timer
-			Ret = EplSdoAsySeqSetTimer(pAsySdoSeqCon,
-						   EPL_SEQ_DEFAULT_TIMEOUT);
-
-			//TODO: retry of acknowledge
-			if (Event_p == kAsySdoSeqEventFrameRec) {
-				// check rcon
-				switch (pRecFrame_p->
-					m_le_bRecSeqNumCon &
-					EPL_ASY_SDO_CON_MASK) {
-					// close-frome other node
-				case 0:
-					{
-						// return to idle
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateIdle;
-						// delete timer
-						EplTimeruDeleteTimer
-						    (&pAsySdoSeqCon->
-						     m_EplTimerHdl);
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateConClosed);
-
-						break;
-					}
-
-					// normal frame
-				case 2:
-					{
-						// should be ack
-						// -> change to state kEplAsySdoStateConnected
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateConnected;
-						// call Command Layer Cb
-						AsySdoSequInstance_g.
-						    m_fpSdoComConCb
-						    (SdoSeqConHdl,
-						     kAsySdoConStateAckReceived);
-						// send data to higher layer if needed
-						if (uiDataSize_p >
-						    EPL_SEQ_HEADER_SIZE) {
-							AsySdoSequInstance_g.
-							    m_fpSdoComReceiveCb
-							    (SdoSeqConHdl,
-							     ((tEplAsySdoCom *)
-							      & pRecFrame_p->
-							      m_le_abSdoSeqPayload),
-							     (uiDataSize_p -
-							      EPL_SEQ_HEADER_SIZE));
-						}
-						break;
-					}
-
-					// Request Ack or Error Ack
-				case 3:
-					{
-						// -> change to state kEplAsySdoStateConnected
-						pAsySdoSeqCon->m_SdoState =
-						    kEplAsySdoStateConnected;
-
-						if (pRecFrame_p->m_le_bRecSeqNumCon == pAsySdoSeqCon->m_bRecSeqNum) {	// ack request
-							// -> send ack
-							// save sequence numbers
-							pAsySdoSeqCon->
-							    m_bRecSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bRecSeqNumCon);
-							pAsySdoSeqCon->
-							    m_bSendSeqNum =
-							    AmiGetByteFromLe
-							    (&pRecFrame_p->
-							     m_le_bSendSeqNumCon);
-
-							// create answer own rcon = 2
-							pAsySdoSeqCon->
-							    m_bRecSeqNum--;
-
-							// check if ack or data-frame
-							if (uiDataSize_p >
-							    EPL_SEQ_HEADER_SIZE)
-							{
-								AsySdoSequInstance_g.
-								    m_fpSdoComReceiveCb
-								    (SdoSeqConHdl,
-								     ((tEplAsySdoCom *) & pRecFrame_p->m_le_abSdoSeqPayload), (uiDataSize_p - EPL_SEQ_HEADER_SIZE));
-								// call Command Layer Cb
-								AsySdoSequInstance_g.
-								    m_fpSdoComConCb
-								    (SdoSeqConHdl,
-								     kAsySdoConStateFrameSended);
-
-							} else {
-								Ret =
-								    EplSdoAsySeqSendIntern
-								    (pAsySdoSeqCon,
-								     0, NULL,
-								     FALSE);
-								if (Ret !=
-								    kEplSuccessful)
-								{
-									goto Exit;
-								}
-							}
-
-						} else {
-							// error ack
-							// resend frames from history
-
-							// read frame from history
-							Ret =
-							    EplSdoAsyReadFromHistory
-							    (pAsySdoSeqCon,
-							     &pEplFrame,
-							     &uiFrameSize,
-							     TRUE);
-							while ((pEplFrame !=
-								NULL)
-							       && (uiFrameSize
-								   != 0)) {
-								// send frame
-								Ret =
-								    EplSdoAsySeqSendLowerLayer
-								    (pAsySdoSeqCon,
-								     uiFrameSize,
-								     pEplFrame);
-								if (Ret !=
-								    kEplSuccessful)
-								{
-									goto Exit;
-								}
-								// read next frame
-
-								// read frame from history
-								Ret =
-								    EplSdoAsyReadFromHistory
-								    (pAsySdoSeqCon,
-								     &pEplFrame,
-								     &uiFrameSize,
-								     FALSE);
-							}	// end of while((pabFrame != NULL)
-						}
-						break;
-					}
-				}	// end of switch(pRecFrame_p->m_le_bRecSeqNumCon & EPL_ASY_SDO_CON_MASK)
-
-			} else if (Event_p == kAsySdoSeqEventTimeout) {	// error -> Close
-				pAsySdoSeqCon->m_SdoState = kEplAsySdoStateIdle;
-				// set rcon and scon to 0
-				pAsySdoSeqCon->m_bSendSeqNum &=
-				    EPL_SEQ_NUM_MASK;
-				pAsySdoSeqCon->m_bRecSeqNum &= EPL_SEQ_NUM_MASK;
-				// send frame
-				EplSdoAsySeqSendIntern(pAsySdoSeqCon,
-						       0, NULL, FALSE);
-
-				// call Command Layer Cb
-				AsySdoSequInstance_g.
-				    m_fpSdoComConCb(SdoSeqConHdl,
-						    kAsySdoConStateTimeout);
-			}
-
-			break;
-		}
-
-		// unknown state
-	default:
-		{
-			EPL_DBGLVL_SDO_TRACE0
-			    ("Error: Unknown State in EplSdoAsySeqProcess\n");
-
-		}
-	}			// end of switch(pAsySdoSeqCon->m_SdoState)
-
-      Exit:
-
-#if defined(WIN32) || defined(_WIN32)
-	// leave critical section for process function
-	LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSection);
-#endif
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqSendIntern
-//
-// Description: intern function to create and send a frame
-//              -> if uiDataSize_p == 0 create a frame with infos from
-//                 pAsySdoSeqCon_p
-//
-//
-//
-// Parameters:  pAsySdoSeqCon_p = pointer to control structure of the connection
-//              uiDataSize_p    = size of data frame to process (can be 0)
-//                                  -> without size of sequence header and Asnd header!!!
-//              pData_p         = pointer to frame to process (can be NULL)
-//              fFrameInHistory = if TRUE frame is saved to history else not
-//
-//
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					 unsigned int uiDataSize_p,
-					 tEplFrame * pData_p,
-					 BOOL fFrameInHistory_p)
-{
-	tEplKernel Ret;
-	u8 abFrame[EPL_SEQ_FRAME_SIZE];
-	tEplFrame *pEplFrame;
-	unsigned int uiFreeEntries;
-
-	if (pData_p == NULL) {	// set pointer to own frame
-		EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
-		pEplFrame = (tEplFrame *) & abFrame[0];
-	} else {		// set pointer to frame from calling function
-		pEplFrame = pData_p;
-	}
-
-	if (fFrameInHistory_p != FALSE) {
-		// check if only one free entry in history buffer
-		uiFreeEntries =
-		    EplSdoAsyGetFreeEntriesFromHistory(pAsySdoSeqCon_p);
-		if (uiFreeEntries == 1) {	// request an acknowledge in dataframe
-			// own scon = 3
-			pAsySdoSeqCon_p->m_bRecSeqNum |= 0x03;
-		}
-	}
-	// fillin header informations
-	// set service id sdo
-	AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_le_bServiceId, 0x05);
-	AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
-		       m_le_abReserved, 0x00);
-	// set receive sequence number and rcon
-	AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
-		       m_le_bRecSeqNumCon, pAsySdoSeqCon_p->m_bSendSeqNum);
-	// set send sequence number and scon
-	AmiSetByteToLe(&pEplFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
-		       m_le_bSendSeqNumCon, pAsySdoSeqCon_p->m_bRecSeqNum);
-
-	// add size
-	uiDataSize_p += EPL_SEQ_HEADER_SIZE;
-
-	// forward frame to appropriate lower layer
-	Ret = EplSdoAsySeqSendLowerLayer(pAsySdoSeqCon_p, uiDataSize_p, pEplFrame);	// pointer to frame
-
-	// check if all allright
-	if ((Ret == kEplSuccessful)
-	    && (fFrameInHistory_p != FALSE)) {
-		// set own scon to 2 if needed
-		if ((pAsySdoSeqCon_p->m_bRecSeqNum & 0x03) == 0x03) {
-			pAsySdoSeqCon_p->m_bRecSeqNum--;
-		}
-		// save frame to history
-		Ret = EplSdoAsyAddFrameToHistory(pAsySdoSeqCon_p,
-						 pEplFrame, uiDataSize_p);
-		if (Ret == kEplSdoSeqNoFreeHistory) {	// request Ack needed
-			Ret = kEplSdoSeqRequestAckNeeded;
-		}
-
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoAsySeqSendLowerLayer
-//
-// Description: intern function to send a previously created frame to lower layer
-//
-// Parameters:  pAsySdoSeqCon_p = pointer to control structure of the connection
-//              uiDataSize_p    = size of data frame to process (can be 0)
-//                                  -> without size of Asnd header!!!
-//              pData_p         = pointer to frame to process (can be NULL)
-//
-// Returns:     tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     unsigned int uiDataSize_p,
-					     tEplFrame * pEplFrame_p)
-{
-	tEplKernel Ret;
-
-	// call send-function
-	// check handle for UDP or Asnd
-	if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_UDP_HANDLE) {	// send over UDP
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-		Ret = EplSdoUdpuSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p,	// pointer to frame
-					 uiDataSize_p);
-#else
-		Ret = kEplSdoSeqUnsupportedProt;
-#endif
-
-	} else if ((pAsySdoSeqCon_p->m_ConHandle & EPL_SDO_ASY_HANDLE_MASK) == EPL_SDO_ASND_HANDLE) {	// ASND
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-		Ret = EplSdoAsnduSendData(pAsySdoSeqCon_p->m_ConHandle, pEplFrame_p,	// pointer to frame
-					  uiDataSize_p);
-#else
-		Ret = kEplSdoSeqUnsupportedProt;
-#endif
-	} else {		// error
-		Ret = kEplSdoSeqInvalidHdl;
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoAsyReceiveCb
-//
-// Description:     callback-function for received frames from lower layer
-//
-//
-//
-// Parameters:      ConHdl_p        = handle of the connection
-//                  pSdoSeqData_p   = pointer to frame
-//                  uiDataSize_p    = size of frame
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
-			      tEplAsySdoSeq *pSdoSeqData_p,
-			      unsigned int uiDataSize_p)
-{
-	tEplKernel Ret;
-	unsigned int uiCount = 0;
-	unsigned int uiFreeEntry = EPL_MAX_SDO_SEQ_CON;
-	tEplAsySdoSeqCon *pAsySdoSeqCon;
-
-#if defined(WIN32) || defined(_WIN32)
-	// enter  critical section
-	EnterCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive);
-#endif
-
-	EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p,
-			      ((u8 *) pSdoSeqData_p)[0]);
-
-	// search controll structure for this connection
-	pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount];
-	while (uiCount < EPL_MAX_SDO_SEQ_CON) {
-		if (pAsySdoSeqCon->m_ConHandle == ConHdl_p) {
-			break;
-		} else if ((pAsySdoSeqCon->m_ConHandle == 0)
-			   && (uiFreeEntry == EPL_MAX_SDO_SEQ_CON)) {
-			// free entry
-			uiFreeEntry = uiCount;
-		}
-		uiCount++;
-		pAsySdoSeqCon++;
-	}
-
-	if (uiCount == EPL_MAX_SDO_SEQ_CON) {	// new connection
-		if (uiFreeEntry == EPL_MAX_SDO_SEQ_CON) {
-			Ret = kEplSdoSeqNoFreeHandle;
-			goto Exit;
-		} else {
-			pAsySdoSeqCon =
-			    &AsySdoSequInstance_g.
-			    m_AsySdoConnection[uiFreeEntry];
-			// save handle from lower layer
-			pAsySdoSeqCon->m_ConHandle = ConHdl_p;
-			// increment use counter
-			pAsySdoSeqCon->m_uiUseCount++;
-			uiCount = uiFreeEntry;
-		}
-	}
-	// call history ack function
-	Ret = EplSdoAsyAckFrameToHistory(pAsySdoSeqCon,
-					 (AmiGetByteFromLe
-					  (&pSdoSeqData_p->
-					   m_le_bRecSeqNumCon) &
-					  EPL_SEQ_NUM_MASK));
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#if defined(WIN32) || defined(_WIN32)
-	// leave critical section
-	LeaveCriticalSection(AsySdoSequInstance_g.m_pCriticalSectionReceive);
-#endif
-
-	// call process function with pointer of frame and event kAsySdoSeqEventFrameRec
-	Ret = EplSdoAsySeqProcess(uiCount,
-				  uiDataSize_p,
-				  NULL, pSdoSeqData_p, kAsySdoSeqEventFrameRec);
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoAsyInitHistory
-//
-// Description:     inti function for history buffer
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsyInitHistory(void)
-{
-	tEplKernel Ret;
-	unsigned int uiCount;
-
-	Ret = kEplSuccessful;
-	// init m_bFreeEntries in history-buffer
-	for (uiCount = 0; uiCount < EPL_MAX_SDO_SEQ_CON; uiCount++) {
-		AsySdoSequInstance_g.m_AsySdoConnection[uiCount].
-		    m_SdoConHistory.m_bFreeEntries = EPL_SDO_HISTORY_SIZE;
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoAsyAddFrameToHistory
-//
-// Description:     function to add a frame to the history buffer
-//
-//
-//
-// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
-//                  pFrame_p        = pointer to frame
-//                  uiSize_p        = size of the frame
-//                                     -> without size of the ethernet header
-//                                        and the asnd header
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     tEplFrame * pFrame_p,
-					     unsigned int uiSize_p)
-{
-	tEplKernel Ret;
-	tEplAsySdoConHistory *pHistory;
-
-	Ret = kEplSuccessful;
-
-	// add frame to history buffer
-
-	// check size
-	// $$$ d.k. EPL_SEQ_HISTORY_FRAME_SIZE includes the header size, but uiSize_p does not!!!
-	if (uiSize_p > EPL_SEQ_HISTROY_FRAME_SIZE) {
-		Ret = kEplSdoSeqFrameSizeError;
-		goto Exit;
-	}
-	// save pointer to history
-	pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
-
-	// check if a free entry is available
-	if (pHistory->m_bFreeEntries > 0) {	// write message in free entry
-		EPL_MEMCPY(&
-			   ((tEplFrame *) pHistory->
-			    m_aabHistoryFrame[pHistory->m_bWrite])->
-			   m_le_bMessageType, &pFrame_p->m_le_bMessageType,
-			   uiSize_p + EPL_ASND_HEADER_SIZE);
-		// store size
-		pHistory->m_auiFrameSize[pHistory->m_bWrite] = uiSize_p;
-
-		// decremend number of free bufferentries
-		pHistory->m_bFreeEntries--;
-
-		// increment writeindex
-		pHistory->m_bWrite++;
-
-		// check if write-index run over array-boarder
-		if (pHistory->m_bWrite == EPL_SDO_HISTORY_SIZE) {
-			pHistory->m_bWrite = 0;
-		}
-
-	} else {		// no free entry
-		Ret = kEplSdoSeqNoFreeHistory;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoAsyAckFrameToHistory
-//
-// Description:     function to delete acknowledged frames fron history buffer
-//
-//
-//
-// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
-//                  bRecSeqNumber_p = receive sequence number of the received frame
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					     u8 bRecSeqNumber_p)
-{
-	tEplKernel Ret;
-	tEplAsySdoConHistory *pHistory;
-	u8 bAckIndex;
-	u8 bCurrentSeqNum;
-
-	Ret = kEplSuccessful;
-
-	// get pointer to history buffer
-	pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
-
-	// release all acknowledged frames from history buffer
-
-	// check if there are entries in history
-	if (pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE) {
-		bAckIndex = pHistory->m_bAck;
-		do {
-			bCurrentSeqNum =
-			    (((tEplFrame *) pHistory->
-			      m_aabHistoryFrame[bAckIndex])->m_Data.m_Asnd.
-			     m_Payload.m_SdoSequenceFrame.
-			     m_le_bSendSeqNumCon & EPL_SEQ_NUM_MASK);
-			if (((bRecSeqNumber_p -
-			      bCurrentSeqNum) & EPL_SEQ_NUM_MASK)
-			    < EPL_SEQ_NUM_THRESHOLD) {
-				pHistory->m_auiFrameSize[bAckIndex] = 0;
-				bAckIndex++;
-				pHistory->m_bFreeEntries++;
-				if (bAckIndex == EPL_SDO_HISTORY_SIZE) {	// read index run over array-boarder
-					bAckIndex = 0;
-				}
-			} else {	// nothing to do anymore,
-				// because any further frame in history has larger sequence
-				// number than the acknowledge
-				goto Exit;
-			}
-		}
-		while ((((bRecSeqNumber_p - 1 -
-			  bCurrentSeqNum) & EPL_SEQ_NUM_MASK)
-			< EPL_SEQ_NUM_THRESHOLD)
-		       && (pHistory->m_bWrite != bAckIndex));
-
-		// store local read-index to global var
-		pHistory->m_bAck = bAckIndex;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoAsyReadFromHistory
-//
-// Description:     function to one frame from history
-//
-//
-//
-// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
-//                  ppFrame_p       = pointer to pointer to the buffer of the stored frame
-//                  puiSize_p       = OUT: size of the frame
-//                  fInitRead       = bool which indicate a start of retransmission
-//                                      -> return last not acknowledged message if TRUE
-//
-//
-// Returns:         tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-					   tEplFrame ** ppFrame_p,
-					   unsigned int *puiSize_p,
-					   BOOL fInitRead_p)
-{
-	tEplKernel Ret;
-	tEplAsySdoConHistory *pHistory;
-
-	Ret = kEplSuccessful;
-
-	// read one message from History
-
-	// get pointer to history buffer
-	pHistory = &pAsySdoSeqCon_p->m_SdoConHistory;
-
-	// check if init
-	if (fInitRead_p != FALSE) {	// initialize read index to the index which shall be acknowledged next
-		pHistory->m_bRead = pHistory->m_bAck;
-	}
-	// 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, (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 =
-		    (tEplFrame *) pHistory->m_aabHistoryFrame[pHistory->
-							      m_bRead];
-
-		// save size
-		*puiSize_p = pHistory->m_auiFrameSize[pHistory->m_bRead];
-
-		pHistory->m_bRead++;
-		if (pHistory->m_bRead == EPL_SDO_HISTORY_SIZE) {
-			pHistory->m_bRead = 0;
-		}
-
-	} else {
-//        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
-		*ppFrame_p = NULL;
-
-		*puiSize_p = 0;
-	}
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoAsyGetFreeEntriesFromHistory
-//
-// Description:     function returns the number of free histroy entries
-//
-//
-//
-// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
-//
-//
-// Returns:         unsigned int    = number of free entries
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static unsigned int EplSdoAsyGetFreeEntriesFromHistory(tEplAsySdoSeqCon *
-						       pAsySdoSeqCon_p)
-{
-	unsigned int uiFreeEntries;
-
-	uiFreeEntries =
-	    (unsigned int)pAsySdoSeqCon_p->m_SdoConHistory.m_bFreeEntries;
-
-	return uiFreeEntries;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoAsySeqSetTimer
-//
-// Description:     function sets or modify timer in timermosule
-//
-//
-//
-// Parameters:      pAsySdoSeqCon_p = pointer to control structure of this connection
-//                  ulTimeout       = timeout in ms
-//
-//
-// Returns:         unsigned int    = number of free entries
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
-				       unsigned long ulTimeout)
-{
-	tEplKernel Ret;
-	tEplTimerArg TimerArg;
-
-	TimerArg.m_EventSink = kEplEventSinkSdoAsySeq;
-	TimerArg.m_ulArg = (unsigned long)pAsySdoSeqCon_p;
-
-	if (pAsySdoSeqCon_p->m_EplTimerHdl == 0) {	// create new timer
-		Ret = EplTimeruSetTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl,
-					  ulTimeout, TimerArg);
-	} else {		// modify exisiting timer
-		Ret = EplTimeruModifyTimerMs(&pAsySdoSeqCon_p->m_EplTimerHdl,
-					     ulTimeout, TimerArg);
-
-	}
-
-	return Ret;
-}
-
-// EOF
diff --git a/drivers/staging/epl/EplSdoComu.c b/drivers/staging/epl/EplSdoComu.c
deleted file mode 100644
index bf35afa..0000000
--- a/drivers/staging/epl/EplSdoComu.c
+++ /dev/null
@@ -1,3345 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for SDO Command Layer 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: EplSdoComu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.14 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/26 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplSdoComu.h"
-
-#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) == 0) &&\
-     (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) == 0)   )
-
-#error 'ERROR: At least SDO Server or SDO Client should be activate!'
-
-#endif
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
-
-#error 'ERROR: SDO Server needs OBDu module!'
-
-#endif
-
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef EPL_MAX_SDO_COM_CON
-#define EPL_MAX_SDO_COM_CON         5
-#endif
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-// intern events
-typedef enum {
-	kEplSdoComConEventSendFirst = 0x00,	// first frame to send
-	kEplSdoComConEventRec = 0x01,	// frame received
-	kEplSdoComConEventConEstablished = 0x02,	// connection established
-	kEplSdoComConEventConClosed = 0x03,	// connection closed
-	kEplSdoComConEventAckReceived = 0x04,	// acknowledge received by lower layer
-	// -> continue sending
-	kEplSdoComConEventFrameSended = 0x05,	// lower has send a frame
-	kEplSdoComConEventInitError = 0x06,	// error duringinitialisiation
-	// of the connection
-	kEplSdoComConEventTimeout = 0x07	// timeout in lower layer
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-	    ,
-
-	kEplSdoComConEventInitCon = 0x08,	// init connection (only client)
-	kEplSdoComConEventAbort = 0x09	// abort sdo transfer (only client)
-#endif
-} tEplSdoComConEvent;
-
-typedef enum {
-	kEplSdoComSendTypeReq = 0x00,	// send a request
-	kEplSdoComSendTypeAckRes = 0x01,	// send a resonse without data
-	kEplSdoComSendTypeRes = 0x02,	// send response with data
-	kEplSdoComSendTypeAbort = 0x03	// send abort
-} tEplSdoComSendType;
-
-// state of the state maschine
-typedef enum {
-	// General State
-	kEplSdoComStateIdle = 0x00,	// idle state
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-	// Server States
-	kEplSdoComStateServerSegmTrans = 0x01,	// send following frames
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-	// Client States
-	kEplSdoComStateClientWaitInit = 0x10,	// wait for init connection
-	// on lower layer
-	kEplSdoComStateClientConnected = 0x11,	// connection established
-	kEplSdoComStateClientSegmTrans = 0x12	// send following frames
-#endif
-} tEplSdoComState;
-
-// control structure for transaction
-typedef struct {
-	tEplSdoSeqConHdl m_SdoSeqConHdl;	// if != 0 -> entry used
-	tEplSdoComState m_SdoComState;
-	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
-	u8 *m_pData;		// pointer to data
-	unsigned int m_uiTransSize;	// number of bytes
-	// to transfer
-	unsigned int m_uiTransferredByte;	// number of bytes
-	// already transferred
-	tEplSdoFinishedCb m_pfnTransferFinished;	// callback function of the
-	// application
-	// -> called in the end of
-	//    the SDO transfer
-	void *m_pUserArg;	// user definable argument pointer
-
-	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
-	unsigned int m_uiTargetSubIndex;	// subiondex to access
-
-	// for future use
-	unsigned int m_uiTimeout;	// timeout for this connection
-
-#endif
-
-} tEplSdoComCon;
-
-// instance table
-typedef struct {
-	tEplSdoComCon m_SdoComCon[EPL_MAX_SDO_COM_CON];
-
-#if defined(WIN32) || defined(_WIN32)
-	LPCRITICAL_SECTION m_pCriticalSection;
-	CRITICAL_SECTION m_CriticalSection;
-#endif
-
-} tEplSdoComInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-static tEplSdoComInstance SdoComInstance_g;
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-			      tEplAsySdoCom *pAsySdoCom_p,
-			      unsigned int uiDataSize_p);
-
-tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-			  tEplAsySdoConState AsySdoConState_p);
-
-static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
-					   tEplSdoComConEvent SdoComConEvent_p,
-					   tEplAsySdoCom * pAsySdoCom_p);
-
-static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
-					 tEplSdoComConEvent SdoComConEvent_p,
-					 tEplAsySdoCom * pAsySdoCom_p);
-
-static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
-					    tEplSdoComCon * pSdoComCon_p,
-					    tEplSdoComConState
-					    SdoComConState_p);
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
-						 tEplAsySdoCom * pAsySdoCom_p);
-
-static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
-						 unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p,
-						 tEplSdoComSendType SendType_p);
-
-static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
-						  tEplAsySdoCom * pAsySdoCom_p);
-#endif
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-
-static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p);
-
-static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
-					      tEplAsySdoCom * pAsySdoCom_p);
-
-static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
-					   u32 dwAbortCode_p);
-#endif
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <SDO Command Layer>                                 */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: SDO Command layer Modul
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComInit
-//
-// Description: Init first instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoComInit(void)
-{
-	tEplKernel Ret;
-
-	Ret = EplSdoComAddInstance();
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComAddInstance
-//
-// Description: Init additional instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoComAddInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// init controll structure
-	EPL_MEMSET(&SdoComInstance_g, 0x00, sizeof(SdoComInstance_g));
-
-	// init instance of lower layer
-	Ret = EplSdoAsySeqAddInstance(EplSdoComReceiveCb, EplSdoComConCb);
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-#if defined(WIN32) || defined(_WIN32)
-	// create critical section for process function
-	SdoComInstance_g.m_pCriticalSection =
-	    &SdoComInstance_g.m_CriticalSection;
-	InitializeCriticalSection(SdoComInstance_g.m_pCriticalSection);
-#endif
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComDelInstance
-//
-// Description: delete instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoComDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-#if defined(WIN32) || defined(_WIN32)
-	// delete critical section for process function
-	DeleteCriticalSection(SdoComInstance_g.m_pCriticalSection);
-#endif
-
-	Ret = EplSdoAsySeqDelInstance();
-	if (Ret != kEplSuccessful) {
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComDefineCon
-//
-// Description: function defines a SDO connection to another node
-//              -> init lower layer and returns a handle for the connection.
-//              Two client connections to the same node via the same protocol
-//              are not allowed. If this function detects such a situation
-//              it will return kEplSdoComHandleExists and the handle of
-//              the existing connection in pSdoComConHdl_p.
-//              Using of existing server connections is possible.
-//
-// Parameters:  pSdoComConHdl_p     = pointer to the buffer of the handle
-//              uiTargetNodeId_p    = NodeId of the targetnode
-//              ProtType_p          = type of protocol to use for connection
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
-			      unsigned int uiTargetNodeId_p,
-			      tEplSdoType ProtType_p)
-{
-	tEplKernel Ret;
-	unsigned int uiCount;
-	unsigned int uiFreeHdl;
-	tEplSdoComCon *pSdoComCon;
-
-	// check Parameter
-	ASSERT(pSdoComConHdl_p != NULL);
-
-	// check NodeId
-	if ((uiTargetNodeId_p == EPL_C_ADR_INVALID)
-	    || (uiTargetNodeId_p >= EPL_C_ADR_BROADCAST)) {
-		Ret = kEplInvalidNodeId;
-
-	}
-	// search free control structure
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
-	uiCount = 0;
-	uiFreeHdl = EPL_MAX_SDO_COM_CON;
-	while (uiCount < EPL_MAX_SDO_COM_CON) {
-		if (pSdoComCon->m_SdoSeqConHdl == 0) {	// free entry
-			uiFreeHdl = uiCount;
-		} else if ((pSdoComCon->m_uiNodeId == uiTargetNodeId_p)
-			   && (pSdoComCon->m_SdoProtType == ProtType_p)) {	// existing client connection with same node ID and same protocol type
-			*pSdoComConHdl_p = uiCount;
-			Ret = kEplSdoComHandleExists;
-			goto Exit;
-		}
-		uiCount++;
-		pSdoComCon++;
-	}
-
-	if (uiFreeHdl == EPL_MAX_SDO_COM_CON) {
-		Ret = kEplSdoComNoFreeHandle;
-		goto Exit;
-	}
-
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[uiFreeHdl];
-	// save handle for application
-	*pSdoComConHdl_p = uiFreeHdl;
-	// save parameters
-	pSdoComCon->m_SdoProtType = ProtType_p;
-	pSdoComCon->m_uiNodeId = uiTargetNodeId_p;
-
-	// set Transaction Id
-	pSdoComCon->m_bTransactionId = 0;
-
-	// check protocol
-	switch (ProtType_p) {
-		// udp
-	case kEplSdoTypeUdp:
-		{
-			// call connection int function of lower layer
-			Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
-						  pSdoComCon->m_uiNodeId,
-						  kEplSdoTypeUdp);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-			break;
-		}
-
-		// Asend
-	case kEplSdoTypeAsnd:
-		{
-			// call connection int function of lower layer
-			Ret = EplSdoAsySeqInitCon(&pSdoComCon->m_SdoSeqConHdl,
-						  pSdoComCon->m_uiNodeId,
-						  kEplSdoTypeAsnd);
-			if (Ret != kEplSuccessful) {
-				goto Exit;
-			}
-			break;
-		}
-
-		// Pdo -> not supported
-	case kEplSdoTypePdo:
-	default:
-		{
-			Ret = kEplSdoComUnsupportedProt;
-			goto Exit;
-		}
-	}			// end of switch(m_ProtType_p)
-
-	// call process function
-	Ret = EplSdoComProcessIntern(uiFreeHdl,
-				     kEplSdoComConEventInitCon, NULL);
-
-      Exit:
-	return Ret;
-}
-#endif
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComInitTransferByIndex
-//
-// Description: function init SDO Transfer for a defined connection
-//
-//
-//
-// Parameters:  SdoComTransParam_p    = Structure with parameters for connection
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p)
-{
-	tEplKernel Ret;
-	tEplSdoComCon *pSdoComCon;
-
-	// check parameter
-	if ((pSdoComTransParam_p->m_uiSubindex >= 0xFF)
-	    || (pSdoComTransParam_p->m_uiIndex == 0)
-	    || (pSdoComTransParam_p->m_uiIndex > 0xFFFF)
-	    || (pSdoComTransParam_p->m_pData == NULL)
-	    || (pSdoComTransParam_p->m_uiDataSize == 0)) {
-		Ret = kEplSdoComInvalidParam;
-		goto Exit;
-	}
-
-	if (pSdoComTransParam_p->m_SdoComConHdl >= EPL_MAX_SDO_COM_CON) {
-		Ret = kEplSdoComInvalidHandle;
-		goto Exit;
-	}
-	// get pointer to control structure of connection
-	pSdoComCon =
-	    &SdoComInstance_g.m_SdoComCon[pSdoComTransParam_p->m_SdoComConHdl];
-
-	// check if handle ok
-	if (pSdoComCon->m_SdoSeqConHdl == 0) {
-		Ret = kEplSdoComInvalidHandle;
-		goto Exit;
-	}
-	// check if command layer is idle
-	if ((pSdoComCon->m_uiTransferredByte + pSdoComCon->m_uiTransSize) > 0) {	// handle is not idle
-		Ret = kEplSdoComHandleBusy;
-		goto Exit;
-	}
-	// save parameter
-	// callback function for end of transfer
-	pSdoComCon->m_pfnTransferFinished =
-	    pSdoComTransParam_p->m_pfnSdoFinishedCb;
-	pSdoComCon->m_pUserArg = pSdoComTransParam_p->m_pUserArg;
-
-	// set type of SDO command
-	if (pSdoComTransParam_p->m_SdoAccessType == kEplSdoAccessTypeRead) {
-		pSdoComCon->m_SdoServiceType = kEplSdoServiceReadByIndex;
-	} else {
-		pSdoComCon->m_SdoServiceType = kEplSdoServiceWriteByIndex;
-
-	}
-	// save pointer to data
-	pSdoComCon->m_pData = pSdoComTransParam_p->m_pData;
-	// maximal bytes to transfer
-	pSdoComCon->m_uiTransSize = pSdoComTransParam_p->m_uiDataSize;
-	// bytes already transfered
-	pSdoComCon->m_uiTransferredByte = 0;
-
-	// reset parts of control structure
-	pSdoComCon->m_dwLastAbortCode = 0;
-	pSdoComCon->m_SdoTransType = kEplSdoTransAuto;
-	// save timeout
-	//pSdoComCon->m_uiTimeout = SdoComTransParam_p.m_uiTimeout;
-
-	// save index and subindex
-	pSdoComCon->m_uiTargetIndex = pSdoComTransParam_p->m_uiIndex;
-	pSdoComCon->m_uiTargetSubIndex = pSdoComTransParam_p->m_uiSubindex;
-
-	// call process function
-	Ret = EplSdoComProcessIntern(pSdoComTransParam_p->m_SdoComConHdl, kEplSdoComConEventSendFirst,	// event to start transfer
-				     NULL);
-
-      Exit:
-	return Ret;
-
-}
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComUndefineCon
-//
-// Description: function undefine a SDO connection
-//
-//
-//
-// Parameters:  SdoComConHdl_p    = handle for the connection
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
-{
-	tEplKernel Ret;
-	tEplSdoComCon *pSdoComCon;
-
-	Ret = kEplSuccessful;
-
-	if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
-		Ret = kEplSdoComInvalidHandle;
-		goto Exit;
-	}
-	// get pointer to control structure
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
-
-	// $$$ d.k. abort a running transfer before closing the sequence layer
-
-	if (((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) !=
-	     EPL_SDO_SEQ_INVALID_HDL)
-	    && (pSdoComCon->m_SdoSeqConHdl != 0)) {
-		// close connection in lower layer
-		switch (pSdoComCon->m_SdoProtType) {
-		case kEplSdoTypeAsnd:
-		case kEplSdoTypeUdp:
-			{
-				Ret =
-				    EplSdoAsySeqDelCon(pSdoComCon->
-						       m_SdoSeqConHdl);
-				break;
-			}
-
-		case kEplSdoTypePdo:
-		case kEplSdoTypeAuto:
-		default:
-			{
-				Ret = kEplSdoComUnsupportedProt;
-				goto Exit;
-			}
-
-		}		// end of switch(pSdoComCon->m_SdoProtType)
-	}
-
-	// clean controll structure
-	EPL_MEMSET(pSdoComCon, 0x00, sizeof(tEplSdoComCon));
-      Exit:
-	return Ret;
-}
-#endif
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComGetState
-//
-// Description: function returns the state fo the connection
-//
-//
-//
-// Parameters:  SdoComConHdl_p    = handle for the connection
-//              pSdoComFinished_p = pointer to structur for sdo state
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
-			     tEplSdoComFinished *pSdoComFinished_p)
-{
-	tEplKernel Ret;
-	tEplSdoComCon *pSdoComCon;
-
-	Ret = kEplSuccessful;
-
-	if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
-		Ret = kEplSdoComInvalidHandle;
-		goto Exit;
-	}
-	// get pointer to control structure
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
-
-	// check if handle ok
-	if (pSdoComCon->m_SdoSeqConHdl == 0) {
-		Ret = kEplSdoComInvalidHandle;
-		goto Exit;
-	}
-
-	pSdoComFinished_p->m_pUserArg = pSdoComCon->m_pUserArg;
-	pSdoComFinished_p->m_uiNodeId = pSdoComCon->m_uiNodeId;
-	pSdoComFinished_p->m_uiTargetIndex = pSdoComCon->m_uiTargetIndex;
-	pSdoComFinished_p->m_uiTargetSubIndex = pSdoComCon->m_uiTargetSubIndex;
-	pSdoComFinished_p->m_uiTransferredByte =
-	    pSdoComCon->m_uiTransferredByte;
-	pSdoComFinished_p->m_dwAbortCode = pSdoComCon->m_dwLastAbortCode;
-	pSdoComFinished_p->m_SdoComConHdl = SdoComConHdl_p;
-	if (pSdoComCon->m_SdoServiceType == kEplSdoServiceWriteByIndex) {
-		pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeWrite;
-	} else {
-		pSdoComFinished_p->m_SdoAccessType = kEplSdoAccessTypeRead;
-	}
-
-	if (pSdoComCon->m_dwLastAbortCode != 0) {	// sdo abort
-		pSdoComFinished_p->m_SdoComConState =
-		    kEplSdoComTransferRxAborted;
-
-		// delete abort code
-		pSdoComCon->m_dwLastAbortCode = 0;
-
-	} else if ((pSdoComCon->m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) == EPL_SDO_SEQ_INVALID_HDL) {	// check state
-		pSdoComFinished_p->m_SdoComConState =
-		    kEplSdoComTransferLowerLayerAbort;
-	} else if (pSdoComCon->m_SdoComState == kEplSdoComStateClientWaitInit) {
-		// finished
-		pSdoComFinished_p->m_SdoComConState =
-		    kEplSdoComTransferNotActive;
-	} else if (pSdoComCon->m_uiTransSize == 0) {	// finished
-		pSdoComFinished_p->m_SdoComConState =
-		    kEplSdoComTransferFinished;
-	}
-
-      Exit:
-	return Ret;
-
-}
-#endif
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComSdoAbort
-//
-// Description: function abort a sdo transfer
-//
-//
-//
-// Parameters:  SdoComConHdl_p    = handle for the connection
-//              dwAbortCode_p     = abort code
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
-			     u32 dwAbortCode_p)
-{
-	tEplKernel Ret;
-	tEplSdoComCon *pSdoComCon;
-
-	if (SdoComConHdl_p >= EPL_MAX_SDO_COM_CON) {
-		Ret = kEplSdoComInvalidHandle;
-		goto Exit;
-	}
-	// get pointer to control structure of connection
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComConHdl_p];
-
-	// check if handle ok
-	if (pSdoComCon->m_SdoSeqConHdl == 0) {
-		Ret = kEplSdoComInvalidHandle;
-		goto Exit;
-	}
-	// save pointer to abort code
-	pSdoComCon->m_pData = (u8 *) & dwAbortCode_p;
-
-	Ret = EplSdoComProcessIntern(SdoComConHdl_p,
-				     kEplSdoComConEventAbort,
-				     (tEplAsySdoCom *) NULL);
-
-      Exit:
-	return Ret;
-}
-#endif
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComReceiveCb
-//
-// Description:     callback function for SDO Sequence Layer
-//                  -> indicates new data
-//
-//
-//
-// Parameters:      SdoSeqConHdl_p = Handle for connection
-//                  pAsySdoCom_p   = pointer to data
-//                  uiDataSize_p   = size of data ($$$ not used yet, but it should)
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-			      tEplAsySdoCom *pAsySdoCom_p,
-			      unsigned int uiDataSize_p)
-{
-	tEplKernel Ret;
-
-	// search connection internally
-	Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
-				       kEplSdoComConEventRec, pAsySdoCom_p);
-
-	EPL_DBGLVL_SDO_TRACE3
-	    ("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n",
-	     SdoSeqConHdl_p, (u16) pAsySdoCom_p->m_le_abCommandData[0],
-	     uiDataSize_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComConCb
-//
-// Description:     callback function called by SDO Sequence Layer to inform
-//                  command layer about state change of connection
-//
-//
-//
-// Parameters:      SdoSeqConHdl_p      = Handle of the connection
-//                  AsySdoConState_p    = Event of the connection
-//
-//
-// Returns:         tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
-			  tEplAsySdoConState AsySdoConState_p)
-{
-	tEplKernel Ret;
-	tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
-
-	Ret = kEplSuccessful;
-
-	// check state
-	switch (AsySdoConState_p) {
-	case kAsySdoConStateConnected:
-		{
-			EPL_DBGLVL_SDO_TRACE0("Connection established\n");
-			SdoComConEvent = kEplSdoComConEventConEstablished;
-			// start transmission if needed
-			break;
-		}
-
-	case kAsySdoConStateInitError:
-		{
-			EPL_DBGLVL_SDO_TRACE0("Error during initialisation\n");
-			SdoComConEvent = kEplSdoComConEventInitError;
-			// inform app about error and close sequence layer handle
-			break;
-		}
-
-	case kAsySdoConStateConClosed:
-		{
-			EPL_DBGLVL_SDO_TRACE0("Connection closed\n");
-			SdoComConEvent = kEplSdoComConEventConClosed;
-			// close sequence layer handle
-			break;
-		}
-
-	case kAsySdoConStateAckReceived:
-		{
-			EPL_DBGLVL_SDO_TRACE0("Acknowlage received\n");
-			SdoComConEvent = kEplSdoComConEventAckReceived;
-			// continue transmission
-			break;
-		}
-
-	case kAsySdoConStateFrameSended:
-		{
-			EPL_DBGLVL_SDO_TRACE0("One Frame sent\n");
-			SdoComConEvent = kEplSdoComConEventFrameSended;
-			// to continue transmission
-			break;
-
-		}
-
-	case kAsySdoConStateTimeout:
-		{
-			EPL_DBGLVL_SDO_TRACE0("Timeout\n");
-			SdoComConEvent = kEplSdoComConEventTimeout;
-			// close sequence layer handle
-			break;
-
-		}
-	}			// end of switch(AsySdoConState_p)
-
-	Ret = EplSdoComSearchConIntern(SdoSeqConHdl_p,
-				       SdoComConEvent, (tEplAsySdoCom *) NULL);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComSearchConIntern
-//
-// Description:     search a Sdo Sequence Layer connection handle in the
-//                  control structure of the Command Layer
-//
-// Parameters:      SdoSeqConHdl_p     = Handle to search
-//                  SdoComConEvent_p = event to process
-//                  pAsySdoCom_p     = pointer to received frame
-//
-// Returns:         tEplKernel
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
-					   tEplSdoComConEvent SdoComConEvent_p,
-					   tEplAsySdoCom * pAsySdoCom_p)
-{
-	tEplKernel Ret;
-	tEplSdoComCon *pSdoComCon;
-	tEplSdoComConHdl HdlCount;
-	tEplSdoComConHdl HdlFree;
-
-	Ret = kEplSdoComNotResponsible;
-
-	// get pointer to first element of the array
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[0];
-	HdlCount = 0;
-	HdlFree = 0xFFFF;
-	while (HdlCount < EPL_MAX_SDO_COM_CON) {
-		if (pSdoComCon->m_SdoSeqConHdl == SdoSeqConHdl_p) {	// matching command layer handle found
-			Ret = EplSdoComProcessIntern(HdlCount,
-						     SdoComConEvent_p,
-						     pAsySdoCom_p);
-		} else if ((pSdoComCon->m_SdoSeqConHdl == 0)
-			   && (HdlFree == 0xFFFF)) {
-			HdlFree = HdlCount;
-		}
-
-		pSdoComCon++;
-		HdlCount++;
-	}
-
-	if (Ret == kEplSdoComNotResponsible) {	// no responsible command layer handle found
-		if (HdlFree == 0xFFFF) {	// no free handle
-			// delete connection immediately
-			// 2008/04/14 m.u./d.k. This connection actually does not exist.
-			//                      pSdoComCon is invalid.
-			// Ret = EplSdoAsySeqDelCon(pSdoComCon->m_SdoSeqConHdl);
-			Ret = kEplSdoComNoFreeHandle;
-		} else {	// create new handle
-			HdlCount = HdlFree;
-			pSdoComCon = &SdoComInstance_g.m_SdoComCon[HdlCount];
-			pSdoComCon->m_SdoSeqConHdl = SdoSeqConHdl_p;
-			Ret = EplSdoComProcessIntern(HdlCount,
-						     SdoComConEvent_p,
-						     pAsySdoCom_p);
-		}
-	}
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComProcessIntern
-//
-// Description:     search a Sdo Sequence Layer connection handle in the
-//                  control structer of the Command Layer
-//
-//
-//
-// Parameters:      SdoComCon_p     = index of control structure of connection
-//                  SdoComConEvent_p = event to process
-//                  pAsySdoCom_p     = pointer to received frame
-//
-// Returns:         tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
-					 tEplSdoComConEvent SdoComConEvent_p,
-					 tEplAsySdoCom * pAsySdoCom_p)
-{
-	tEplKernel Ret;
-	tEplSdoComCon *pSdoComCon;
-	u8 bFlag;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-	u32 dwAbortCode;
-	unsigned int uiSize;
-#endif
-
-#if defined(WIN32) || defined(_WIN32)
-	// enter  critical section for process function
-	EnterCriticalSection(SdoComInstance_g.m_pCriticalSection);
-	EPL_DBGLVL_SDO_TRACE0
-	    ("\n\tEnterCiticalSection EplSdoComProcessIntern\n\n");
-#endif
-
-	Ret = kEplSuccessful;
-
-	// get pointer to control structure
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
-
-	// process state maschine
-	switch (pSdoComCon->m_SdoComState) {
-		// idle state
-	case kEplSdoComStateIdle:
-		{
-			// check events
-			switch (SdoComConEvent_p) {
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-				// init con for client
-			case kEplSdoComConEventInitCon:
-				{
-
-					// call of the init function already
-					// processed in EplSdoComDefineCon()
-					// only change state to kEplSdoComStateClientWaitInit
-					pSdoComCon->m_SdoComState =
-					    kEplSdoComStateClientWaitInit;
-					break;
-				}
-#endif
-
-				// int con for server
-			case kEplSdoComConEventRec:
-				{
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-					// check if init of an transfer and no SDO abort
-					if ((pAsySdoCom_p->m_le_bFlags & 0x80) == 0) {	// SDO request
-						if ((pAsySdoCom_p->m_le_bFlags & 0x40) == 0) {	// no SDO abort
-							// save tansaction id
-							pSdoComCon->
-							    m_bTransactionId =
-							    AmiGetByteFromLe
-							    (&pAsySdoCom_p->
-							     m_le_bTransactionId);
-							// check command
-							switch (pAsySdoCom_p->
-								m_le_bCommandId)
-							{
-							case kEplSdoServiceNIL:
-								{	// simply acknowlegde NIL command on sequence layer
-
-									Ret =
-									    EplSdoAsySeqSendData
-									    (pSdoComCon->
-									     m_SdoSeqConHdl,
-									     0,
-									     (tEplFrame
-									      *)
-									     NULL);
-
-									break;
-								}
-
-							case kEplSdoServiceReadByIndex:
-								{	// read by index
-
-									// search entry an start transfer
-									EplSdoComServerInitReadByIndex
-									    (pSdoComCon,
-									     pAsySdoCom_p);
-									// check next state
-									if (pSdoComCon->m_uiTransSize == 0) {	// ready -> stay idle
-										pSdoComCon->
-										    m_SdoComState
-										    =
-										    kEplSdoComStateIdle;
-										// reset abort code
-										pSdoComCon->
-										    m_dwLastAbortCode
-										    =
-										    0;
-									} else {	// segmented transfer
-										pSdoComCon->
-										    m_SdoComState
-										    =
-										    kEplSdoComStateServerSegmTrans;
-									}
-
-									break;
-								}
-
-							case kEplSdoServiceWriteByIndex:
-								{
-
-									// search entry an start write
-									EplSdoComServerInitWriteByIndex
-									    (pSdoComCon,
-									     pAsySdoCom_p);
-									// check next state
-									if (pSdoComCon->m_uiTransSize == 0) {	// already -> stay idle
-										pSdoComCon->
-										    m_SdoComState
-										    =
-										    kEplSdoComStateIdle;
-										// reset abort code
-										pSdoComCon->
-										    m_dwLastAbortCode
-										    =
-										    0;
-									} else {	// segmented transfer
-										pSdoComCon->
-										    m_SdoComState
-										    =
-										    kEplSdoComStateServerSegmTrans;
-									}
-
-									break;
-								}
-
-							default:
-								{
-									//  unsupported command
-									//       -> abort senden
-									dwAbortCode
-									    =
-									    EPL_SDOAC_UNKNOWN_COMMAND_SPECIFIER;
-									// send abort
-									pSdoComCon->
-									    m_pData
-									    =
-									    (u8
-									     *)
-									    &
-									    dwAbortCode;
-									Ret =
-									    EplSdoComServerSendFrameIntern
-									    (pSdoComCon,
-									     0,
-									     0,
-									     kEplSdoComSendTypeAbort);
-
-								}
-
-							}	// end of switch(pAsySdoCom_p->m_le_bCommandId)
-						}
-					} else {	// this command layer handle is not responsible
-						// (wrong direction or wrong transaction ID)
-						Ret = kEplSdoComNotResponsible;
-						goto Exit;
-					}
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-
-					break;
-				}
-
-				// connection closed
-			case kEplSdoComConEventInitError:
-			case kEplSdoComConEventTimeout:
-			case kEplSdoComConEventConClosed:
-				{
-					Ret =
-					    EplSdoAsySeqDelCon(pSdoComCon->
-							       m_SdoSeqConHdl);
-					// clean control structure
-					EPL_MEMSET(pSdoComCon, 0x00,
-						   sizeof(tEplSdoComCon));
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-			}	// end of switch(SdoComConEvent_p)
-			break;
-		}
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-		//-------------------------------------------------------------------------
-		// SDO Server part
-		// segmented transfer
-	case kEplSdoComStateServerSegmTrans:
-		{
-			// check events
-			switch (SdoComConEvent_p) {
-				// send next frame
-			case kEplSdoComConEventAckReceived:
-			case kEplSdoComConEventFrameSended:
-				{
-					// check if it is a read
-					if (pSdoComCon->m_SdoServiceType ==
-					    kEplSdoServiceReadByIndex) {
-						// send next frame
-						EplSdoComServerSendFrameIntern
-						    (pSdoComCon, 0, 0,
-						     kEplSdoComSendTypeRes);
-						// if all send -> back to idle
-						if (pSdoComCon->m_uiTransSize == 0) {	// back to idle
-							pSdoComCon->
-							    m_SdoComState =
-							    kEplSdoComStateIdle;
-							// reset abort code
-							pSdoComCon->
-							    m_dwLastAbortCode =
-							    0;
-						}
-
-					}
-					break;
-				}
-
-				// process next frame
-			case kEplSdoComConEventRec:
-				{
-					// check if the frame is a SDO response and has the right transaction ID
-					bFlag =
-					    AmiGetByteFromLe(&pAsySdoCom_p->
-							     m_le_bFlags);
-					if (((bFlag & 0x80) != 0)
-					    &&
-					    (AmiGetByteFromLe
-					     (&pAsySdoCom_p->
-					      m_le_bTransactionId) ==
-					     pSdoComCon->m_bTransactionId)) {
-						// check if it is a abort
-						if ((bFlag & 0x40) != 0) {	// SDO abort
-							// clear control structure
-							pSdoComCon->
-							    m_uiTransSize = 0;
-							pSdoComCon->
-							    m_uiTransferredByte
-							    = 0;
-							// change state
-							pSdoComCon->
-							    m_SdoComState =
-							    kEplSdoComStateIdle;
-							// reset abort code
-							pSdoComCon->
-							    m_dwLastAbortCode =
-							    0;
-							// d.k.: do not execute anything further on this command
-							break;
-						}
-						// check if it is a write
-						if (pSdoComCon->
-						    m_SdoServiceType ==
-						    kEplSdoServiceWriteByIndex)
-						{
-							// write data to OD
-							uiSize =
-							    AmiGetWordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_wSegmentSize);
-							if (pSdoComCon->
-							    m_dwLastAbortCode ==
-							    0) {
-								EPL_MEMCPY
-								    (pSdoComCon->
-								     m_pData,
-								     &pAsySdoCom_p->
-								     m_le_abCommandData
-								     [0],
-								     uiSize);
-							}
-							// update counter
-							pSdoComCon->
-							    m_uiTransferredByte
-							    += uiSize;
-							pSdoComCon->
-							    m_uiTransSize -=
-							    uiSize;
-
-							// update pointer
-							if (pSdoComCon->
-							    m_dwLastAbortCode ==
-							    0) {
-								( /*(u8*) */
-								 pSdoComCon->
-								 m_pData) +=
-						      uiSize;
-							}
-							// check end of transfer
-							if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x30) {	// transfer ready
-								pSdoComCon->
-								    m_uiTransSize
-								    = 0;
-
-								if (pSdoComCon->
-								    m_dwLastAbortCode
-								    == 0) {
-									// send response
-									// send next frame
-									EplSdoComServerSendFrameIntern
-									    (pSdoComCon,
-									     0,
-									     0,
-									     kEplSdoComSendTypeRes);
-									// if all send -> back to idle
-									if (pSdoComCon->m_uiTransSize == 0) {	// back to idle
-										pSdoComCon->
-										    m_SdoComState
-										    =
-										    kEplSdoComStateIdle;
-										// reset abort code
-										pSdoComCon->
-										    m_dwLastAbortCode
-										    =
-										    0;
-									}
-								} else {	// send dabort code
-									// send abort
-									pSdoComCon->
-									    m_pData
-									    =
-									    (u8
-									     *)
-									    &
-									    pSdoComCon->
-									    m_dwLastAbortCode;
-									Ret =
-									    EplSdoComServerSendFrameIntern
-									    (pSdoComCon,
-									     0,
-									     0,
-									     kEplSdoComSendTypeAbort);
-
-									// reset abort code
-									pSdoComCon->
-									    m_dwLastAbortCode
-									    = 0;
-
-								}
-							} else {
-								// send acknowledge without any Command layer data
-								Ret =
-								    EplSdoAsySeqSendData
-								    (pSdoComCon->
-								     m_SdoSeqConHdl,
-								     0,
-								     (tEplFrame
-								      *) NULL);
-							}
-						}
-					} else {	// this command layer handle is not responsible
-						// (wrong direction or wrong transaction ID)
-						Ret = kEplSdoComNotResponsible;
-						goto Exit;
-					}
-					break;
-				}
-
-				// connection closed
-			case kEplSdoComConEventInitError:
-			case kEplSdoComConEventTimeout:
-			case kEplSdoComConEventConClosed:
-				{
-					Ret =
-					    EplSdoAsySeqDelCon(pSdoComCon->
-							       m_SdoSeqConHdl);
-					// clean control structure
-					EPL_MEMSET(pSdoComCon, 0x00,
-						   sizeof(tEplSdoComCon));
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-			}	// end of switch(SdoComConEvent_p)
-
-			break;
-		}
-#endif // endif of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-		//-------------------------------------------------------------------------
-		// SDO Client part
-		// wait for finish of establishing connection
-	case kEplSdoComStateClientWaitInit:
-		{
-
-			// if connection handle is invalid reinit connection
-			// d.k.: this will be done only on new events (i.e. InitTransfer)
-			if ((pSdoComCon->
-			     m_SdoSeqConHdl & ~EPL_SDO_SEQ_HANDLE_MASK) ==
-			    EPL_SDO_SEQ_INVALID_HDL) {
-				// check kind of connection to reinit
-				// check protocol
-				switch (pSdoComCon->m_SdoProtType) {
-					// udp
-				case kEplSdoTypeUdp:
-					{
-						// call connection int function of lower layer
-						Ret =
-						    EplSdoAsySeqInitCon
-						    (&pSdoComCon->
-						     m_SdoSeqConHdl,
-						     pSdoComCon->m_uiNodeId,
-						     kEplSdoTypeUdp);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						break;
-					}
-
-					// Asend -> not supported
-				case kEplSdoTypeAsnd:
-					{
-						// call connection int function of lower layer
-						Ret =
-						    EplSdoAsySeqInitCon
-						    (&pSdoComCon->
-						     m_SdoSeqConHdl,
-						     pSdoComCon->m_uiNodeId,
-						     kEplSdoTypeAsnd);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						break;
-					}
-
-					// Pdo -> not supported
-				case kEplSdoTypePdo:
-				default:
-					{
-						Ret = kEplSdoComUnsupportedProt;
-						goto Exit;
-					}
-				}	// end of switch(m_ProtType_p)
-				// d.k.: reset transaction ID, because new sequence layer connection was initialized
-				// $$$ d.k. is this really necessary?
-				//pSdoComCon->m_bTransactionId = 0;
-			}
-			// check events
-			switch (SdoComConEvent_p) {
-				// connection established
-			case kEplSdoComConEventConEstablished:
-				{
-					//send first frame if needed
-					if ((pSdoComCon->m_uiTransSize > 0)
-					    && (pSdoComCon->m_uiTargetIndex != 0)) {	// start SDO transfer
-						Ret =
-						    EplSdoComClientSend
-						    (pSdoComCon);
-						if (Ret != kEplSuccessful) {
-							goto Exit;
-						}
-						// check if segemted transfer
-						if (pSdoComCon->
-						    m_SdoTransType ==
-						    kEplSdoTransSegmented) {
-							pSdoComCon->
-							    m_SdoComState =
-							    kEplSdoComStateClientSegmTrans;
-							goto Exit;
-						}
-					}
-					// goto state kEplSdoComStateClientConnected
-					pSdoComCon->m_SdoComState =
-					    kEplSdoComStateClientConnected;
-					goto Exit;
-				}
-
-			case kEplSdoComConEventSendFirst:
-				{
-					// infos for transfer already saved by function EplSdoComInitTransferByIndex
-					break;
-				}
-
-			case kEplSdoComConEventConClosed:
-			case kEplSdoComConEventInitError:
-			case kEplSdoComConEventTimeout:
-				{
-					// close sequence layer handle
-					Ret =
-					    EplSdoAsySeqDelCon(pSdoComCon->
-							       m_SdoSeqConHdl);
-					pSdoComCon->m_SdoSeqConHdl |=
-					    EPL_SDO_SEQ_INVALID_HDL;
-					// call callback function
-					if (SdoComConEvent_p ==
-					    kEplSdoComConEventTimeout) {
-						pSdoComCon->m_dwLastAbortCode =
-						    EPL_SDOAC_TIME_OUT;
-					} else {
-						pSdoComCon->m_dwLastAbortCode =
-						    0;
-					}
-					Ret =
-					    EplSdoComTransferFinished
-					    (SdoComCon_p, pSdoComCon,
-					     kEplSdoComTransferLowerLayerAbort);
-					// d.k.: do not clean control structure
-					break;
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of  switch(SdoComConEvent_p)
-			break;
-		}
-
-		// connected
-	case kEplSdoComStateClientConnected:
-		{
-			// check events
-			switch (SdoComConEvent_p) {
-				// send a frame
-			case kEplSdoComConEventSendFirst:
-			case kEplSdoComConEventAckReceived:
-			case kEplSdoComConEventFrameSended:
-				{
-					Ret = EplSdoComClientSend(pSdoComCon);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-					// check if read transfer finished
-					if ((pSdoComCon->m_uiTransSize == 0)
-					    && (pSdoComCon->
-						m_uiTransferredByte != 0)
-					    && (pSdoComCon->m_SdoServiceType ==
-						kEplSdoServiceReadByIndex)) {
-						// inc transaction id
-						pSdoComCon->m_bTransactionId++;
-						// call callback of application
-						pSdoComCon->m_dwLastAbortCode =
-						    0;
-						Ret =
-						    EplSdoComTransferFinished
-						    (SdoComCon_p, pSdoComCon,
-						     kEplSdoComTransferFinished);
-
-						goto Exit;
-					}
-					// check if segemted transfer
-					if (pSdoComCon->m_SdoTransType ==
-					    kEplSdoTransSegmented) {
-						pSdoComCon->m_SdoComState =
-						    kEplSdoComStateClientSegmTrans;
-						goto Exit;
-					}
-					break;
-				}
-
-				// frame received
-			case kEplSdoComConEventRec:
-				{
-					// check if the frame is a SDO response and has the right transaction ID
-					bFlag =
-					    AmiGetByteFromLe(&pAsySdoCom_p->
-							     m_le_bFlags);
-					if (((bFlag & 0x80) != 0)
-					    &&
-					    (AmiGetByteFromLe
-					     (&pAsySdoCom_p->
-					      m_le_bTransactionId) ==
-					     pSdoComCon->m_bTransactionId)) {
-						// check if abort or not
-						if ((bFlag & 0x40) != 0) {
-							// send acknowledge without any Command layer data
-							Ret =
-							    EplSdoAsySeqSendData
-							    (pSdoComCon->
-							     m_SdoSeqConHdl, 0,
-							     (tEplFrame *)
-							     NULL);
-							// inc transaction id
-							pSdoComCon->
-							    m_bTransactionId++;
-							// save abort code
-							pSdoComCon->
-							    m_dwLastAbortCode =
-							    AmiGetDwordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_abCommandData
-							     [0]);
-							// call callback of application
-							Ret =
-							    EplSdoComTransferFinished
-							    (SdoComCon_p,
-							     pSdoComCon,
-							     kEplSdoComTransferRxAborted);
-
-							goto Exit;
-						} else {	// normal frame received
-							// check frame
-							Ret =
-							    EplSdoComClientProcessFrame
-							    (SdoComCon_p,
-							     pAsySdoCom_p);
-
-							// check if transfer ready
-							if (pSdoComCon->
-							    m_uiTransSize ==
-							    0) {
-								// send acknowledge without any Command layer data
-								Ret =
-								    EplSdoAsySeqSendData
-								    (pSdoComCon->
-								     m_SdoSeqConHdl,
-								     0,
-								     (tEplFrame
-								      *) NULL);
-								// inc transaction id
-								pSdoComCon->
-								    m_bTransactionId++;
-								// call callback of application
-								pSdoComCon->
-								    m_dwLastAbortCode
-								    = 0;
-								Ret =
-								    EplSdoComTransferFinished
-								    (SdoComCon_p,
-								     pSdoComCon,
-								     kEplSdoComTransferFinished);
-
-								goto Exit;
-							}
-
-						}
-					} else {	// this command layer handle is not responsible
-						// (wrong direction or wrong transaction ID)
-						Ret = kEplSdoComNotResponsible;
-						goto Exit;
-					}
-					break;
-				}
-
-				// connection closed event go back to kEplSdoComStateClientWaitInit
-			case kEplSdoComConEventConClosed:
-				{	// connection closed by communication partner
-					// close sequence layer handle
-					Ret =
-					    EplSdoAsySeqDelCon(pSdoComCon->
-							       m_SdoSeqConHdl);
-					// set handle to invalid and enter kEplSdoComStateClientWaitInit
-					pSdoComCon->m_SdoSeqConHdl |=
-					    EPL_SDO_SEQ_INVALID_HDL;
-					// change state
-					pSdoComCon->m_SdoComState =
-					    kEplSdoComStateClientWaitInit;
-
-					// call callback of application
-					pSdoComCon->m_dwLastAbortCode = 0;
-					Ret =
-					    EplSdoComTransferFinished
-					    (SdoComCon_p, pSdoComCon,
-					     kEplSdoComTransferLowerLayerAbort);
-
-					goto Exit;
-
-					break;
-				}
-
-				// abort to send from higher layer
-			case kEplSdoComConEventAbort:
-				{
-					EplSdoComClientSendAbort(pSdoComCon,
-								 *((u32 *)
-								   pSdoComCon->
-								   m_pData));
-
-					// inc transaction id
-					pSdoComCon->m_bTransactionId++;
-					// call callback of application
-					pSdoComCon->m_dwLastAbortCode =
-					    *((u32 *) pSdoComCon->m_pData);
-					Ret =
-					    EplSdoComTransferFinished
-					    (SdoComCon_p, pSdoComCon,
-					     kEplSdoComTransferTxAborted);
-
-					break;
-				}
-
-			case kEplSdoComConEventInitError:
-			case kEplSdoComConEventTimeout:
-				{
-					// close sequence layer handle
-					Ret =
-					    EplSdoAsySeqDelCon(pSdoComCon->
-							       m_SdoSeqConHdl);
-					pSdoComCon->m_SdoSeqConHdl |=
-					    EPL_SDO_SEQ_INVALID_HDL;
-					// change state
-					pSdoComCon->m_SdoComState =
-					    kEplSdoComStateClientWaitInit;
-					// call callback of application
-					pSdoComCon->m_dwLastAbortCode =
-					    EPL_SDOAC_TIME_OUT;
-					Ret =
-					    EplSdoComTransferFinished
-					    (SdoComCon_p, pSdoComCon,
-					     kEplSdoComTransferLowerLayerAbort);
-
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of switch(SdoComConEvent_p)
-
-			break;
-		}
-
-		// process segmented transfer
-	case kEplSdoComStateClientSegmTrans:
-		{
-			// check events
-			switch (SdoComConEvent_p) {
-				// sned a frame
-			case kEplSdoComConEventSendFirst:
-			case kEplSdoComConEventAckReceived:
-			case kEplSdoComConEventFrameSended:
-				{
-					Ret = EplSdoComClientSend(pSdoComCon);
-					if (Ret != kEplSuccessful) {
-						goto Exit;
-					}
-					// check if read transfer finished
-					if ((pSdoComCon->m_uiTransSize == 0)
-					    && (pSdoComCon->m_SdoServiceType ==
-						kEplSdoServiceReadByIndex)) {
-						// inc transaction id
-						pSdoComCon->m_bTransactionId++;
-						// change state
-						pSdoComCon->m_SdoComState =
-						    kEplSdoComStateClientConnected;
-						// call callback of application
-						pSdoComCon->m_dwLastAbortCode =
-						    0;
-						Ret =
-						    EplSdoComTransferFinished
-						    (SdoComCon_p, pSdoComCon,
-						     kEplSdoComTransferFinished);
-
-						goto Exit;
-					}
-
-					break;
-				}
-
-				// frame received
-			case kEplSdoComConEventRec:
-				{
-					// check if the frame is a response
-					bFlag =
-					    AmiGetByteFromLe(&pAsySdoCom_p->
-							     m_le_bFlags);
-					if (((bFlag & 0x80) != 0)
-					    &&
-					    (AmiGetByteFromLe
-					     (&pAsySdoCom_p->
-					      m_le_bTransactionId) ==
-					     pSdoComCon->m_bTransactionId)) {
-						// check if abort or not
-						if ((bFlag & 0x40) != 0) {
-							// send acknowledge without any Command layer data
-							Ret =
-							    EplSdoAsySeqSendData
-							    (pSdoComCon->
-							     m_SdoSeqConHdl, 0,
-							     (tEplFrame *)
-							     NULL);
-							// inc transaction id
-							pSdoComCon->
-							    m_bTransactionId++;
-							// change state
-							pSdoComCon->
-							    m_SdoComState =
-							    kEplSdoComStateClientConnected;
-							// save abort code
-							pSdoComCon->
-							    m_dwLastAbortCode =
-							    AmiGetDwordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_abCommandData
-							     [0]);
-							// call callback of application
-							Ret =
-							    EplSdoComTransferFinished
-							    (SdoComCon_p,
-							     pSdoComCon,
-							     kEplSdoComTransferRxAborted);
-
-							goto Exit;
-						} else {	// normal frame received
-							// check frame
-							Ret =
-							    EplSdoComClientProcessFrame
-							    (SdoComCon_p,
-							     pAsySdoCom_p);
-
-							// check if transfer ready
-							if (pSdoComCon->
-							    m_uiTransSize ==
-							    0) {
-								// send acknowledge without any Command layer data
-								Ret =
-								    EplSdoAsySeqSendData
-								    (pSdoComCon->
-								     m_SdoSeqConHdl,
-								     0,
-								     (tEplFrame
-								      *) NULL);
-								// inc transaction id
-								pSdoComCon->
-								    m_bTransactionId++;
-								// change state
-								pSdoComCon->
-								    m_SdoComState
-								    =
-								    kEplSdoComStateClientConnected;
-								// call callback of application
-								pSdoComCon->
-								    m_dwLastAbortCode
-								    = 0;
-								Ret =
-								    EplSdoComTransferFinished
-								    (SdoComCon_p,
-								     pSdoComCon,
-								     kEplSdoComTransferFinished);
-
-							}
-
-						}
-					}
-					break;
-				}
-
-				// connection closed event go back to kEplSdoComStateClientWaitInit
-			case kEplSdoComConEventConClosed:
-				{	// connection closed by communication partner
-					// close sequence layer handle
-					Ret =
-					    EplSdoAsySeqDelCon(pSdoComCon->
-							       m_SdoSeqConHdl);
-					// set handle to invalid and enter kEplSdoComStateClientWaitInit
-					pSdoComCon->m_SdoSeqConHdl |=
-					    EPL_SDO_SEQ_INVALID_HDL;
-					// change state
-					pSdoComCon->m_SdoComState =
-					    kEplSdoComStateClientWaitInit;
-					// inc transaction id
-					pSdoComCon->m_bTransactionId++;
-					// call callback of application
-					pSdoComCon->m_dwLastAbortCode = 0;
-					Ret =
-					    EplSdoComTransferFinished
-					    (SdoComCon_p, pSdoComCon,
-					     kEplSdoComTransferFinished);
-
-					break;
-				}
-
-				// abort to send from higher layer
-			case kEplSdoComConEventAbort:
-				{
-					EplSdoComClientSendAbort(pSdoComCon,
-								 *((u32 *)
-								   pSdoComCon->
-								   m_pData));
-
-					// inc transaction id
-					pSdoComCon->m_bTransactionId++;
-					// change state
-					pSdoComCon->m_SdoComState =
-					    kEplSdoComStateClientConnected;
-					// call callback of application
-					pSdoComCon->m_dwLastAbortCode =
-					    *((u32 *) pSdoComCon->m_pData);
-					Ret =
-					    EplSdoComTransferFinished
-					    (SdoComCon_p, pSdoComCon,
-					     kEplSdoComTransferTxAborted);
-
-					break;
-				}
-
-			case kEplSdoComConEventInitError:
-			case kEplSdoComConEventTimeout:
-				{
-					// close sequence layer handle
-					Ret =
-					    EplSdoAsySeqDelCon(pSdoComCon->
-							       m_SdoSeqConHdl);
-					pSdoComCon->m_SdoSeqConHdl |=
-					    EPL_SDO_SEQ_INVALID_HDL;
-					// change state
-					pSdoComCon->m_SdoComState =
-					    kEplSdoComStateClientWaitInit;
-					// call callback of application
-					pSdoComCon->m_dwLastAbortCode =
-					    EPL_SDOAC_TIME_OUT;
-					Ret =
-					    EplSdoComTransferFinished
-					    (SdoComCon_p, pSdoComCon,
-					     kEplSdoComTransferLowerLayerAbort);
-
-				}
-
-			default:
-				// d.k. do nothing
-				break;
-
-			}	// end of switch(SdoComConEvent_p)
-
-			break;
-		}
-#endif // endo of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-
-	}			// end of switch(pSdoComCon->m_SdoComState)
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-      Exit:
-#endif
-
-#if defined(WIN32) || defined(_WIN32)
-	// leave critical section for process function
-	EPL_DBGLVL_SDO_TRACE0
-	    ("\n\tLeaveCriticalSection EplSdoComProcessIntern\n\n");
-	LeaveCriticalSection(SdoComInstance_g.m_pCriticalSection);
-
-#endif
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComServerInitReadByIndex
-//
-// Description:    function start the processing of an read by index command
-//
-//
-//
-// Parameters:      pSdoComCon_p     = pointer to control structure of connection
-//                  pAsySdoCom_p     = pointer to received frame
-//
-// Returns:         tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
-						 tEplAsySdoCom * pAsySdoCom_p)
-{
-	tEplKernel Ret;
-	unsigned int uiIndex;
-	unsigned int uiSubindex;
-	tEplObdSize EntrySize;
-	tEplObdAccess AccessType;
-	u32 dwAbortCode;
-
-	dwAbortCode = 0;
-
-	// a init of a read could not be a segmented transfer
-	// -> no variable part of header
-
-	// get index and subindex
-	uiIndex = AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
-	uiSubindex = AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
-
-	// check accesstype of entry
-	// existens of entry
-//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-	Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
-/*#else
-    Ret = kEplObdSubindexNotExist;
-    AccessType = 0;
-#endif*/
-	if (Ret == kEplObdSubindexNotExist) {	// subentry doesn't exist
-		dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
-		// send abort
-		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
-		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-						     uiIndex,
-						     uiSubindex,
-						     kEplSdoComSendTypeAbort);
-		goto Exit;
-	} else if (Ret != kEplSuccessful) {	// entry doesn't exist
-		dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
-		// send abort
-		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
-		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-						     uiIndex,
-						     uiSubindex,
-						     kEplSdoComSendTypeAbort);
-		goto Exit;
-	}
-	// compare accesstype must be read or const
-	if (((AccessType & kEplObdAccRead) == 0)
-	    && ((AccessType & kEplObdAccConst) == 0)) {
-
-		if ((AccessType & kEplObdAccWrite) != 0) {
-			// entry read a write only object
-			dwAbortCode = EPL_SDOAC_READ_TO_WRITE_ONLY_OBJ;
-		} else {
-			dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
-		}
-		// send abort
-		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
-		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-						     uiIndex,
-						     uiSubindex,
-						     kEplSdoComSendTypeAbort);
-		goto Exit;
-	}
-	// save service
-	pSdoComCon_p->m_SdoServiceType = kEplSdoServiceReadByIndex;
-
-	// get size of object to see iof segmented or expedited transfer
-//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-	EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
-/*#else
-    EntrySize = 0;
-#endif*/
-	if (EntrySize > EPL_SDO_MAX_PAYLOAD) {	// segmented transfer
-		pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
-		// get pointer to object-entry data
-//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-		pSdoComCon_p->m_pData =
-		    EplObduGetObjectDataPtr(uiIndex, uiSubindex);
-//#endif
-	} else {		// expedited transfer
-		pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
-	}
-
-	pSdoComCon_p->m_uiTransSize = EntrySize;
-	pSdoComCon_p->m_uiTransferredByte = 0;
-
-	Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-					     uiIndex,
-					     uiSubindex, kEplSdoComSendTypeRes);
-	if (Ret != kEplSuccessful) {
-		// error -> abort
-		dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
-		// send abort
-		pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
-		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-						     uiIndex,
-						     uiSubindex,
-						     kEplSdoComSendTypeAbort);
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComServerSendFrameIntern();
-//
-// Description:    function creats and send a frame for server
-//
-//
-//
-// Parameters:      pSdoComCon_p     = pointer to control structure of connection
-//                  uiIndex_p        = index to send if expedited transfer else 0
-//                  uiSubIndex_p     = subindex to send if expedited transfer else 0
-//                  SendType_p       = to of frame to send
-//
-// Returns:         tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
-						 unsigned int uiIndex_p,
-						 unsigned int uiSubIndex_p,
-						 tEplSdoComSendType SendType_p)
-{
-	tEplKernel Ret;
-	u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
-	tEplFrame *pFrame;
-	tEplAsySdoCom *pCommandFrame;
-	unsigned int uiSizeOfFrame;
-	u8 bFlag;
-
-	Ret = kEplSuccessful;
-
-	pFrame = (tEplFrame *) & abFrame[0];
-
-	EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
-
-	// build generic part of frame
-	// get pointer to command layerpart of frame
-	pCommandFrame =
-	    &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
-	    m_le_abSdoSeqPayload;
-	AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
-		       pSdoComCon_p->m_SdoServiceType);
-	AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
-		       pSdoComCon_p->m_bTransactionId);
-
-	// set size to header size
-	uiSizeOfFrame = 8;
-
-	// check SendType
-	switch (SendType_p) {
-		// requestframe to send
-	case kEplSdoComSendTypeReq:
-		{
-			// nothing to do for server
-			//-> error
-			Ret = kEplSdoComInvalidSendType;
-			break;
-		}
-
-		// response without data to send
-	case kEplSdoComSendTypeAckRes:
-		{
-			// set response flag
-			AmiSetByteToLe(&pCommandFrame->m_le_bFlags, 0x80);
-
-			// send frame
-			Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
-						   uiSizeOfFrame, pFrame);
-
-			break;
-		}
-
-		// responsframe to send
-	case kEplSdoComSendTypeRes:
-		{
-			// set response flag
-			bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
-			bFlag |= 0x80;
-			AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
-
-			// check type of resonse
-			if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) {	// Expedited transfer
-				// copy data in frame
-//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-				Ret = EplObduReadEntryToLe(uiIndex_p,
-							   uiSubIndex_p,
-							   &pCommandFrame->
-							   m_le_abCommandData
-							   [0],
-							   (tEplObdSize *) &
-							   pSdoComCon_p->
-							   m_uiTransSize);
-				if (Ret != kEplSuccessful) {
-					goto Exit;
-				}
-//#endif
-
-				// set size of frame
-				AmiSetWordToLe(&pCommandFrame->
-					       m_le_wSegmentSize,
-					       (u16) pSdoComCon_p->
-					       m_uiTransSize);
-
-				// correct byte-counter
-				uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
-				pSdoComCon_p->m_uiTransferredByte +=
-				    pSdoComCon_p->m_uiTransSize;
-				pSdoComCon_p->m_uiTransSize = 0;
-
-				// send frame
-				uiSizeOfFrame += pSdoComCon_p->m_uiTransSize;
-				Ret =
-				    EplSdoAsySeqSendData(pSdoComCon_p->
-							 m_SdoSeqConHdl,
-							 uiSizeOfFrame, pFrame);
-			} else if (pSdoComCon_p->m_SdoTransType == kEplSdoTransSegmented) {	// segmented transfer
-				// distinguish between init, segment and complete
-				if (pSdoComCon_p->m_uiTransferredByte == 0) {	// init
-					// set init flag
-					bFlag =
-					    AmiGetByteFromLe(&pCommandFrame->
-							     m_le_bFlags);
-					bFlag |= 0x10;
-					AmiSetByteToLe(&pCommandFrame->
-						       m_le_bFlags, bFlag);
-					// init variable header
-					AmiSetDwordToLe(&pCommandFrame->
-							m_le_abCommandData[0],
-							pSdoComCon_p->
-							m_uiTransSize);
-					// copy data in frame
-					EPL_MEMCPY(&pCommandFrame->
-						   m_le_abCommandData[4],
-						   pSdoComCon_p->m_pData,
-						   (EPL_SDO_MAX_PAYLOAD - 4));
-
-					// correct byte-counter
-					pSdoComCon_p->m_uiTransSize -=
-					    (EPL_SDO_MAX_PAYLOAD - 4);
-					pSdoComCon_p->m_uiTransferredByte +=
-					    (EPL_SDO_MAX_PAYLOAD - 4);
-					// move data pointer
-					pSdoComCon_p->m_pData +=
-					    (EPL_SDO_MAX_PAYLOAD - 4);
-
-					// set segment size
-					AmiSetWordToLe(&pCommandFrame->
-						       m_le_wSegmentSize,
-						       (EPL_SDO_MAX_PAYLOAD -
-							4));
-
-					// send frame
-					uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
-					Ret =
-					    EplSdoAsySeqSendData(pSdoComCon_p->
-								 m_SdoSeqConHdl,
-								 uiSizeOfFrame,
-								 pFrame);
-
-				} else
-				    if ((pSdoComCon_p->m_uiTransferredByte > 0)
-					&& (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD)) {	// segment
-					// set segment flag
-					bFlag =
-					    AmiGetByteFromLe(&pCommandFrame->
-							     m_le_bFlags);
-					bFlag |= 0x20;
-					AmiSetByteToLe(&pCommandFrame->
-						       m_le_bFlags, bFlag);
-
-					// copy data in frame
-					EPL_MEMCPY(&pCommandFrame->
-						   m_le_abCommandData[0],
-						   pSdoComCon_p->m_pData,
-						   EPL_SDO_MAX_PAYLOAD);
-
-					// correct byte-counter
-					pSdoComCon_p->m_uiTransSize -=
-					    EPL_SDO_MAX_PAYLOAD;
-					pSdoComCon_p->m_uiTransferredByte +=
-					    EPL_SDO_MAX_PAYLOAD;
-					// move data pointer
-					pSdoComCon_p->m_pData +=
-					    EPL_SDO_MAX_PAYLOAD;
-
-					// set segment size
-					AmiSetWordToLe(&pCommandFrame->
-						       m_le_wSegmentSize,
-						       EPL_SDO_MAX_PAYLOAD);
-
-					// send frame
-					uiSizeOfFrame += EPL_SDO_MAX_PAYLOAD;
-					Ret =
-					    EplSdoAsySeqSendData(pSdoComCon_p->
-								 m_SdoSeqConHdl,
-								 uiSizeOfFrame,
-								 pFrame);
-				} else {
-					if ((pSdoComCon_p->m_uiTransSize == 0)
-					    && (pSdoComCon_p->
-						m_SdoServiceType !=
-						kEplSdoServiceWriteByIndex)) {
-						goto Exit;
-					}
-					// complete
-					// set segment complete flag
-					bFlag =
-					    AmiGetByteFromLe(&pCommandFrame->
-							     m_le_bFlags);
-					bFlag |= 0x30;
-					AmiSetByteToLe(&pCommandFrame->
-						       m_le_bFlags, bFlag);
-
-					// copy data in frame
-					EPL_MEMCPY(&pCommandFrame->
-						   m_le_abCommandData[0],
-						   pSdoComCon_p->m_pData,
-						   pSdoComCon_p->m_uiTransSize);
-
-					// correct byte-counter
-					pSdoComCon_p->m_uiTransferredByte +=
-					    pSdoComCon_p->m_uiTransSize;
-
-					// move data pointer
-					pSdoComCon_p->m_pData +=
-					    pSdoComCon_p->m_uiTransSize;
-
-					// set segment size
-					AmiSetWordToLe(&pCommandFrame->
-						       m_le_wSegmentSize,
-						       (u16) pSdoComCon_p->
-						       m_uiTransSize);
-
-					// send frame
-					uiSizeOfFrame +=
-					    pSdoComCon_p->m_uiTransSize;
-					pSdoComCon_p->m_uiTransSize = 0;
-					Ret =
-					    EplSdoAsySeqSendData(pSdoComCon_p->
-								 m_SdoSeqConHdl,
-								 uiSizeOfFrame,
-								 pFrame);
-				}
-
-			}
-			break;
-		}
-		// abort to send
-	case kEplSdoComSendTypeAbort:
-		{
-			// set response and abort flag
-			bFlag = AmiGetByteFromLe(&pCommandFrame->m_le_bFlags);
-			bFlag |= 0xC0;
-			AmiSetByteToLe(&pCommandFrame->m_le_bFlags, bFlag);
-
-			// copy abortcode to frame
-			AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],
-					*((u32 *) pSdoComCon_p->m_pData));
-
-			// set size of segment
-			AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,
-				       sizeof(u32));
-
-			// update counter
-			pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
-			pSdoComCon_p->m_uiTransSize = 0;
-
-			// calc framesize
-			uiSizeOfFrame += sizeof(u32);
-			Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
-						   uiSizeOfFrame, pFrame);
-			break;
-		}
-	}			// end of switch(SendType_p)
-
-      Exit:
-	return Ret;
-}
-#endif
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComServerInitWriteByIndex
-//
-// Description:    function start the processing of an write by index command
-//
-//
-//
-// Parameters:      pSdoComCon_p     = pointer to control structure of connection
-//                  pAsySdoCom_p     = pointer to received frame
-//
-// Returns:         tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
-static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
-						  tEplAsySdoCom * pAsySdoCom_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiIndex;
-	unsigned int uiSubindex;
-	unsigned int uiBytesToTransfer;
-	tEplObdSize EntrySize;
-	tEplObdAccess AccessType;
-	u32 dwAbortCode;
-	u8 *pbSrcData;
-
-	dwAbortCode = 0;
-
-	// a init of a write
-	// -> variable part of header possible
-
-	// check if expedited or segmented transfer
-	if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x10) {	// initiate segmented transfer
-		pSdoComCon_p->m_SdoTransType = kEplSdoTransSegmented;
-		// get index and subindex
-		uiIndex =
-		    AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[4]);
-		uiSubindex =
-		    AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[6]);
-		// get source-pointer for copy
-		pbSrcData = &pAsySdoCom_p->m_le_abCommandData[8];
-		// save size
-		pSdoComCon_p->m_uiTransSize =
-		    AmiGetDwordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
-
-	} else if ((pAsySdoCom_p->m_le_bFlags & 0x30) == 0x00) {	// expedited transfer
-		pSdoComCon_p->m_SdoTransType = kEplSdoTransExpedited;
-		// get index and subindex
-		uiIndex =
-		    AmiGetWordFromLe(&pAsySdoCom_p->m_le_abCommandData[0]);
-		uiSubindex =
-		    AmiGetByteFromLe(&pAsySdoCom_p->m_le_abCommandData[2]);
-		// get source-pointer for copy
-		pbSrcData = &pAsySdoCom_p->m_le_abCommandData[4];
-		// save size
-		pSdoComCon_p->m_uiTransSize =
-		    AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
-		// subtract header
-		pSdoComCon_p->m_uiTransSize -= 4;
-
-	} else {
-		// just ignore any other transfer type
-		goto Exit;
-	}
-
-	// check accesstype of entry
-	// existens of entry
-//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-	Ret = EplObduGetAccessType(uiIndex, uiSubindex, &AccessType);
-/*#else
-    Ret = kEplObdSubindexNotExist;
-    AccessType = 0;
-#endif*/
-	if (Ret == kEplObdSubindexNotExist) {	// subentry doesn't exist
-		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 = (u8*)pSdoComCon_p->m_dwLastAbortCode;
-		   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-		   uiIndex,
-		   uiSubindex,
-		   kEplSdoComSendTypeAbort); */
-		goto Abort;
-	} else if (Ret != kEplSuccessful) {	// entry doesn't exist
-		pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
-		// send abort
-		// d.k. This is wrong: k.t. not needed send abort on end of write
-		/*
-		   pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
-		   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-		   uiIndex,
-		   uiSubindex,
-		   kEplSdoComSendTypeAbort); */
-		goto Abort;
-	}
-	// compare accesstype must be read
-	if ((AccessType & kEplObdAccWrite) == 0) {
-
-		if ((AccessType & kEplObdAccRead) != 0) {
-			// entry write a read only object
-			pSdoComCon_p->m_dwLastAbortCode =
-			    EPL_SDOAC_WRITE_TO_READ_ONLY_OBJ;
-		} else {
-			pSdoComCon_p->m_dwLastAbortCode =
-			    EPL_SDOAC_UNSUPPORTED_ACCESS;
-		}
-		// send abort
-		// d.k. This is wrong: k.t. not needed send abort on end of write
-		/*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
-		   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-		   uiIndex,
-		   uiSubindex,
-		   kEplSdoComSendTypeAbort); */
-		goto Abort;
-	}
-	// save service
-	pSdoComCon_p->m_SdoServiceType = kEplSdoServiceWriteByIndex;
-
-	pSdoComCon_p->m_uiTransferredByte = 0;
-
-	// write data to OD
-	if (pSdoComCon_p->m_SdoTransType == kEplSdoTransExpedited) {	// expedited transfer
-		// size checking is done by EplObduWriteEntryFromLe()
-
-//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-		Ret = EplObduWriteEntryFromLe(uiIndex,
-					      uiSubindex,
-					      pbSrcData,
-					      pSdoComCon_p->m_uiTransSize);
-		switch (Ret) {
-		case kEplSuccessful:
-			{
-				break;
-			}
-
-		case kEplObdAccessViolation:
-			{
-				pSdoComCon_p->m_dwLastAbortCode =
-				    EPL_SDOAC_UNSUPPORTED_ACCESS;
-				// send abort
-				goto Abort;
-			}
-
-		case kEplObdValueLengthError:
-			{
-				pSdoComCon_p->m_dwLastAbortCode =
-				    EPL_SDOAC_DATA_TYPE_LENGTH_NOT_MATCH;
-				// send abort
-				goto Abort;
-			}
-
-		case kEplObdValueTooHigh:
-			{
-				pSdoComCon_p->m_dwLastAbortCode =
-				    EPL_SDOAC_VALUE_RANGE_TOO_HIGH;
-				// send abort
-				goto Abort;
-			}
-
-		case kEplObdValueTooLow:
-			{
-				pSdoComCon_p->m_dwLastAbortCode =
-				    EPL_SDOAC_VALUE_RANGE_TOO_LOW;
-				// send abort
-				goto Abort;
-			}
-
-		default:
-			{
-				pSdoComCon_p->m_dwLastAbortCode =
-				    EPL_SDOAC_GENERAL_ERROR;
-				// send abort
-				goto Abort;
-			}
-		}
-//#endif
-		// send command acknowledge
-		Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-						     0,
-						     0,
-						     kEplSdoComSendTypeAckRes);
-
-		pSdoComCon_p->m_uiTransSize = 0;
-		goto Exit;
-	} else {
-		// get size of the object to check if it fits
-		// because we directly write to the destination memory
-		// d.k. no one calls the user OD callback function
-
-		//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-		EntrySize = EplObduGetDataSize(uiIndex, uiSubindex);
-		/*#else
-		   EntrySize = 0;
-		   #endif */
-		if (EntrySize < pSdoComCon_p->m_uiTransSize) {	// parameter too big
-			pSdoComCon_p->m_dwLastAbortCode =
-			    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 = (u8*)&dwAbortCode;
-			   Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-			   uiIndex,
-			   uiSubindex,
-			   kEplSdoComSendTypeAbort); */
-			goto Abort;
-		}
-
-		uiBytesToTransfer =
-		    AmiGetWordFromLe(&pAsySdoCom_p->m_le_wSegmentSize);
-		// eleminate header (Command header (8) + variable part (4) + Command header (4))
-		uiBytesToTransfer -= 16;
-		// get pointer to object entry
-//#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-		pSdoComCon_p->m_pData = EplObduGetObjectDataPtr(uiIndex,
-								uiSubindex);
-//#endif
-		if (pSdoComCon_p->m_pData == NULL) {
-			pSdoComCon_p->m_dwLastAbortCode =
-			    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 = (u8*)&pSdoComCon_p->m_dwLastAbortCode;
-            Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
-                                        uiIndex,
-                                        uiSubindex,
-                                        kEplSdoComSendTypeAbort);*/
-			goto Abort;
-		}
-		// copy data
-		EPL_MEMCPY(pSdoComCon_p->m_pData, pbSrcData, uiBytesToTransfer);
-
-		// update internal counter
-		pSdoComCon_p->m_uiTransferredByte = uiBytesToTransfer;
-		pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
-
-		// update target pointer
-		( /*(u8*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
-
-		// send acknowledge without any Command layer data
-		Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
-					   0, (tEplFrame *) NULL);
-		goto Exit;
-	}
-
-      Abort:
-	if (pSdoComCon_p->m_dwLastAbortCode != 0) {
-		// send abort
-		pSdoComCon_p->m_pData =
-		    (u8 *) & pSdoComCon_p->m_dwLastAbortCode;
-		Ret =
-		    EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex,
-						   uiSubindex,
-						   kEplSdoComSendTypeAbort);
-
-		// reset abort code
-		pSdoComCon_p->m_dwLastAbortCode = 0;
-		pSdoComCon_p->m_uiTransSize = 0;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-}
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComClientSend
-//
-// Description:    function starts an sdo transfer an send all further frames
-//
-//
-//
-// Parameters:      pSdoComCon_p     = pointer to control structure of connection
-//
-// Returns:         tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
-{
-	tEplKernel Ret;
-	u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
-	tEplFrame *pFrame;
-	tEplAsySdoCom *pCommandFrame;
-	unsigned int uiSizeOfFrame;
-	u8 bFlags;
-	u8 *pbPayload;
-
-	Ret = kEplSuccessful;
-
-	pFrame = (tEplFrame *) & abFrame[0];
-
-	EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
-
-	// build generic part of frame
-	// get pointer to command layerpart of frame
-	pCommandFrame =
-	    &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
-	    m_le_abSdoSeqPayload;
-	AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
-		       pSdoComCon_p->m_SdoServiceType);
-	AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
-		       pSdoComCon_p->m_bTransactionId);
-
-	// set size constant part of header
-	uiSizeOfFrame = 8;
-
-	// check if first frame to send -> command header needed
-	if (pSdoComCon_p->m_uiTransSize > 0) {
-		if (pSdoComCon_p->m_uiTransferredByte == 0) {	// start SDO transfer
-			// check if segmented or expedited transfer
-			// only for write commands
-			switch (pSdoComCon_p->m_SdoServiceType) {
-			case kEplSdoServiceReadByIndex:
-				{	// first frame of read access always expedited
-					pSdoComCon_p->m_SdoTransType =
-					    kEplSdoTransExpedited;
-					pbPayload =
-					    &pCommandFrame->
-					    m_le_abCommandData[0];
-					// fill rest of header
-					AmiSetWordToLe(&pCommandFrame->
-						       m_le_wSegmentSize, 4);
-
-					// create command header
-					AmiSetWordToLe(pbPayload,
-						       (u16) pSdoComCon_p->
-						       m_uiTargetIndex);
-					pbPayload += 2;
-					AmiSetByteToLe(pbPayload,
-						       (u8) pSdoComCon_p->
-						       m_uiTargetSubIndex);
-					// calc size
-					uiSizeOfFrame += 4;
-
-					// set pSdoComCon_p->m_uiTransferredByte to one
-					pSdoComCon_p->m_uiTransferredByte = 1;
-					break;
-				}
-
-			case kEplSdoServiceWriteByIndex:
-				{
-					if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) {	// segmented transfer
-						// -> variable part of header needed
-						// save that transfer is segmented
-						pSdoComCon_p->m_SdoTransType =
-						    kEplSdoTransSegmented;
-						// fill variable part of header
-						AmiSetDwordToLe(&pCommandFrame->
-								m_le_abCommandData
-								[0],
-								pSdoComCon_p->
-								m_uiTransSize);
-						// set pointer to real payload
-						pbPayload =
-						    &pCommandFrame->
-						    m_le_abCommandData[4];
-						// fill rest of header
-						AmiSetWordToLe(&pCommandFrame->
-							       m_le_wSegmentSize,
-							       EPL_SDO_MAX_PAYLOAD);
-						bFlags = 0x10;
-						AmiSetByteToLe(&pCommandFrame->
-							       m_le_bFlags,
-							       bFlags);
-						// create command header
-						AmiSetWordToLe(pbPayload,
-							       (u16)
-							       pSdoComCon_p->
-							       m_uiTargetIndex);
-						pbPayload += 2;
-						AmiSetByteToLe(pbPayload,
-							       (u8)
-							       pSdoComCon_p->
-							       m_uiTargetSubIndex);
-						// on byte for reserved
-						pbPayload += 2;
-						// calc size
-						uiSizeOfFrame +=
-						    EPL_SDO_MAX_PAYLOAD;
-
-						// copy payload
-						EPL_MEMCPY(pbPayload,
-							   pSdoComCon_p->
-							   m_pData,
-							   (EPL_SDO_MAX_PAYLOAD
-							    - 8));
-						pSdoComCon_p->m_pData +=
-						    (EPL_SDO_MAX_PAYLOAD - 8);
-						// correct intern counter
-						pSdoComCon_p->m_uiTransSize -=
-						    (EPL_SDO_MAX_PAYLOAD - 8);
-						pSdoComCon_p->
-						    m_uiTransferredByte =
-						    (EPL_SDO_MAX_PAYLOAD - 8);
-
-					} else {	// expedited trandsfer
-						// save that transfer is expedited
-						pSdoComCon_p->m_SdoTransType =
-						    kEplSdoTransExpedited;
-						pbPayload =
-						    &pCommandFrame->
-						    m_le_abCommandData[0];
-
-						// create command header
-						AmiSetWordToLe(pbPayload,
-							       (u16)
-							       pSdoComCon_p->
-							       m_uiTargetIndex);
-						pbPayload += 2;
-						AmiSetByteToLe(pbPayload,
-							       (u8)
-							       pSdoComCon_p->
-							       m_uiTargetSubIndex);
-						// + 2 -> one byte for subindex and one byte reserved
-						pbPayload += 2;
-						// copy data
-						EPL_MEMCPY(pbPayload,
-							   pSdoComCon_p->
-							   m_pData,
-							   pSdoComCon_p->
-							   m_uiTransSize);
-						// calc size
-						uiSizeOfFrame +=
-						    (4 +
-						     pSdoComCon_p->
-						     m_uiTransSize);
-						// fill rest of header
-						AmiSetWordToLe(&pCommandFrame->
-							       m_le_wSegmentSize,
-							       (u16) (4 +
-								       pSdoComCon_p->
-								       m_uiTransSize));
-
-						pSdoComCon_p->
-						    m_uiTransferredByte =
-						    pSdoComCon_p->m_uiTransSize;
-						pSdoComCon_p->m_uiTransSize = 0;
-					}
-					break;
-				}
-
-			case kEplSdoServiceNIL:
-			default:
-				// invalid service requested
-				Ret = kEplSdoComInvalidServiceType;
-				goto Exit;
-			}	// end of switch(pSdoComCon_p->m_SdoServiceType)
-		} else		// (pSdoComCon_p->m_uiTransferredByte > 0)
-		{		// continue SDO transfer
-			switch (pSdoComCon_p->m_SdoServiceType) {
-				// for expedited read is nothing to do
-				// -> server sends data
-
-			case kEplSdoServiceWriteByIndex:
-				{	// send next frame
-					if (pSdoComCon_p->m_SdoTransType ==
-					    kEplSdoTransSegmented) {
-						if (pSdoComCon_p->m_uiTransSize > EPL_SDO_MAX_PAYLOAD) {	// next segment
-							pbPayload =
-							    &pCommandFrame->
-							    m_le_abCommandData
-							    [0];
-							// fill rest of header
-							AmiSetWordToLe
-							    (&pCommandFrame->
-							     m_le_wSegmentSize,
-							     EPL_SDO_MAX_PAYLOAD);
-							bFlags = 0x20;
-							AmiSetByteToLe
-							    (&pCommandFrame->
-							     m_le_bFlags,
-							     bFlags);
-							// copy data
-							EPL_MEMCPY(pbPayload,
-								   pSdoComCon_p->
-								   m_pData,
-								   EPL_SDO_MAX_PAYLOAD);
-							pSdoComCon_p->m_pData +=
-							    EPL_SDO_MAX_PAYLOAD;
-							// correct intern counter
-							pSdoComCon_p->
-							    m_uiTransSize -=
-							    EPL_SDO_MAX_PAYLOAD;
-							pSdoComCon_p->
-							    m_uiTransferredByte
-							    =
-							    EPL_SDO_MAX_PAYLOAD;
-							// calc size
-							uiSizeOfFrame +=
-							    EPL_SDO_MAX_PAYLOAD;
-
-						} else {	// end of transfer
-							pbPayload =
-							    &pCommandFrame->
-							    m_le_abCommandData
-							    [0];
-							// fill rest of header
-							AmiSetWordToLe
-							    (&pCommandFrame->
-							     m_le_wSegmentSize,
-							     (u16)
-							     pSdoComCon_p->
-							     m_uiTransSize);
-							bFlags = 0x30;
-							AmiSetByteToLe
-							    (&pCommandFrame->
-							     m_le_bFlags,
-							     bFlags);
-							// copy data
-							EPL_MEMCPY(pbPayload,
-								   pSdoComCon_p->
-								   m_pData,
-								   pSdoComCon_p->
-								   m_uiTransSize);
-							pSdoComCon_p->m_pData +=
-							    pSdoComCon_p->
-							    m_uiTransSize;
-							// calc size
-							uiSizeOfFrame +=
-							    pSdoComCon_p->
-							    m_uiTransSize;
-							// correct intern counter
-							pSdoComCon_p->
-							    m_uiTransSize = 0;
-							pSdoComCon_p->
-							    m_uiTransferredByte
-							    =
-							    pSdoComCon_p->
-							    m_uiTransSize;
-
-						}
-					} else {
-						goto Exit;
-					}
-					break;
-				}
-			default:
-				{
-					goto Exit;
-				}
-			}	// end of switch(pSdoComCon_p->m_SdoServiceType)
-		}
-	} else {
-		goto Exit;
-	}
-
-	// call send function of lower layer
-	switch (pSdoComCon_p->m_SdoProtType) {
-	case kEplSdoTypeAsnd:
-	case kEplSdoTypeUdp:
-		{
-			Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
-						   uiSizeOfFrame, pFrame);
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplSdoComUnsupportedProt;
-		}
-	}			// end of switch(pSdoComCon_p->m_SdoProtType)
-
-      Exit:
-	return Ret;
-
-}
-#endif
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoComClientProcessFrame
-//
-// Description:    function process a received frame
-//
-//
-//
-// Parameters:      SdoComCon_p      = connection handle
-//                  pAsySdoCom_p     = pointer to frame to process
-//
-// Returns:         tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
-					      tEplAsySdoCom * pAsySdoCom_p)
-{
-	tEplKernel Ret;
-	u8 bBuffer;
-	unsigned int uiBuffer;
-	unsigned int uiDataSize;
-	unsigned long ulBuffer;
-	tEplSdoComCon *pSdoComCon;
-
-	Ret = kEplSuccessful;
-
-	// get pointer to control structure
-	pSdoComCon = &SdoComInstance_g.m_SdoComCon[SdoComCon_p];
-
-	// check if transaction Id fit
-	bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bTransactionId);
-	if (pSdoComCon->m_bTransactionId != bBuffer) {
-		// incorrect transaction id
-
-		// if running transfer
-		if ((pSdoComCon->m_uiTransferredByte != 0)
-		    && (pSdoComCon->m_uiTransSize != 0)) {
-			pSdoComCon->m_dwLastAbortCode = EPL_SDOAC_GENERAL_ERROR;
-			// -> send abort
-			EplSdoComClientSendAbort(pSdoComCon,
-						 pSdoComCon->m_dwLastAbortCode);
-			// call callback of application
-			Ret =
-			    EplSdoComTransferFinished(SdoComCon_p, pSdoComCon,
-						      kEplSdoComTransferTxAborted);
-		}
-
-	} else {		// check if correct command
-		bBuffer = AmiGetByteFromLe(&pAsySdoCom_p->m_le_bCommandId);
-		if (pSdoComCon->m_SdoServiceType != bBuffer) {
-			// incorrect command
-			// if running transfer
-			if ((pSdoComCon->m_uiTransferredByte != 0)
-			    && (pSdoComCon->m_uiTransSize != 0)) {
-				pSdoComCon->m_dwLastAbortCode =
-				    EPL_SDOAC_GENERAL_ERROR;
-				// -> send abort
-				EplSdoComClientSendAbort(pSdoComCon,
-							 pSdoComCon->
-							 m_dwLastAbortCode);
-				// call callback of application
-				Ret =
-				    EplSdoComTransferFinished(SdoComCon_p,
-							      pSdoComCon,
-							      kEplSdoComTransferTxAborted);
-			}
-
-		} else {	// switch on command
-			switch (pSdoComCon->m_SdoServiceType) {
-			case kEplSdoServiceWriteByIndex:
-				{	// check if confirmation from server
-					// nothing more to do
-					break;
-				}
-
-			case kEplSdoServiceReadByIndex:
-				{	// check if it is an segmented or an expedited transfer
-					bBuffer =
-					    AmiGetByteFromLe(&pAsySdoCom_p->
-							     m_le_bFlags);
-					// mask uninteressting bits
-					bBuffer &= 0x30;
-					switch (bBuffer) {
-						// expedited transfer
-					case 0x00:
-						{
-							// check size of buffer
-							uiBuffer =
-							    AmiGetWordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_wSegmentSize);
-							if (uiBuffer > pSdoComCon->m_uiTransSize) {	// buffer provided by the application is to small
-								// copy only a part
-								uiDataSize =
-								    pSdoComCon->
-								    m_uiTransSize;
-							} else {	// buffer fits
-								uiDataSize =
-								    uiBuffer;
-							}
-
-							// copy data
-							EPL_MEMCPY(pSdoComCon->
-								   m_pData,
-								   &pAsySdoCom_p->
-								   m_le_abCommandData
-								   [0],
-								   uiDataSize);
-
-							// correct counter
-							pSdoComCon->
-							    m_uiTransSize = 0;
-							pSdoComCon->
-							    m_uiTransferredByte
-							    = uiDataSize;
-							break;
-						}
-
-						// start of a segmented transfer
-					case 0x10:
-						{	// get total size of transfer
-							ulBuffer =
-							    AmiGetDwordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_abCommandData
-							     [0]);
-							if (ulBuffer <= pSdoComCon->m_uiTransSize) {	// buffer fit
-								pSdoComCon->
-								    m_uiTransSize
-								    =
-								    (unsigned
-								     int)
-								    ulBuffer;
-							} else {	// buffer to small
-								// send abort
-								pSdoComCon->
-								    m_dwLastAbortCode
-								    =
-								    EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
-								// -> send abort
-								EplSdoComClientSendAbort
-								    (pSdoComCon,
-								     pSdoComCon->
-								     m_dwLastAbortCode);
-								// call callback of application
-								Ret =
-								    EplSdoComTransferFinished
-								    (SdoComCon_p,
-								     pSdoComCon,
-								     kEplSdoComTransferRxAborted);
-								goto Exit;
-							}
-
-							// get segment size
-							// check size of buffer
-							uiBuffer =
-							    AmiGetWordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_wSegmentSize);
-							// subtract size of vaiable header from datasize
-							uiBuffer -= 4;
-							// copy data
-							EPL_MEMCPY(pSdoComCon->
-								   m_pData,
-								   &pAsySdoCom_p->
-								   m_le_abCommandData
-								   [4],
-								   uiBuffer);
-
-							// correct counter an pointer
-							pSdoComCon->m_pData +=
-							    uiBuffer;
-							pSdoComCon->
-							    m_uiTransferredByte
-							    += uiBuffer;
-							pSdoComCon->
-							    m_uiTransSize -=
-							    uiBuffer;
-
-							break;
-						}
-
-						// segment
-					case 0x20:
-						{
-							// get segment size
-							// check size of buffer
-							uiBuffer =
-							    AmiGetWordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_wSegmentSize);
-							// check if data to copy fit to buffer
-							if (uiBuffer >= pSdoComCon->m_uiTransSize) {	// to much data
-								uiBuffer =
-								    (pSdoComCon->
-								     m_uiTransSize
-								     - 1);
-							}
-							// copy data
-							EPL_MEMCPY(pSdoComCon->
-								   m_pData,
-								   &pAsySdoCom_p->
-								   m_le_abCommandData
-								   [0],
-								   uiBuffer);
-
-							// correct counter an pointer
-							pSdoComCon->m_pData +=
-							    uiBuffer;
-							pSdoComCon->
-							    m_uiTransferredByte
-							    += uiBuffer;
-							pSdoComCon->
-							    m_uiTransSize -=
-							    uiBuffer;
-							break;
-						}
-
-						// last segment
-					case 0x30:
-						{
-							// get segment size
-							// check size of buffer
-							uiBuffer =
-							    AmiGetWordFromLe
-							    (&pAsySdoCom_p->
-							     m_le_wSegmentSize);
-							// check if data to copy fit to buffer
-							if (uiBuffer > pSdoComCon->m_uiTransSize) {	// to much data
-								uiBuffer =
-								    (pSdoComCon->
-								     m_uiTransSize
-								     - 1);
-							}
-							// copy data
-							EPL_MEMCPY(pSdoComCon->
-								   m_pData,
-								   &pAsySdoCom_p->
-								   m_le_abCommandData
-								   [0],
-								   uiBuffer);
-
-							// correct counter an pointer
-							pSdoComCon->m_pData +=
-							    uiBuffer;
-							pSdoComCon->
-							    m_uiTransferredByte
-							    += uiBuffer;
-							pSdoComCon->
-							    m_uiTransSize = 0;
-
-							break;
-						}
-					}	// end of switch(bBuffer & 0x30)
-
-					break;
-				}
-
-			case kEplSdoServiceNIL:
-			default:
-				// invalid service requested
-				// $$$ d.k. What should we do?
-				break;
-			}	// end of switch(pSdoComCon->m_SdoServiceType)
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComClientSendAbort
-//
-// Description: function send a abort message
-//
-//
-//
-// Parameters:  pSdoComCon_p     = pointer to control structure of connection
-//              dwAbortCode_p    = Sdo abort code
-//
-// Returns:     tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
-					   u32 dwAbortCode_p)
-{
-	tEplKernel Ret;
-	u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
-	tEplFrame *pFrame;
-	tEplAsySdoCom *pCommandFrame;
-	unsigned int uiSizeOfFrame;
-
-	Ret = kEplSuccessful;
-
-	pFrame = (tEplFrame *) & abFrame[0];
-
-	EPL_MEMSET(&abFrame[0], 0x00, sizeof(abFrame));
-
-	// build generic part of frame
-	// get pointer to command layerpart of frame
-	pCommandFrame =
-	    &pFrame->m_Data.m_Asnd.m_Payload.m_SdoSequenceFrame.
-	    m_le_abSdoSeqPayload;
-	AmiSetByteToLe(&pCommandFrame->m_le_bCommandId,
-		       pSdoComCon_p->m_SdoServiceType);
-	AmiSetByteToLe(&pCommandFrame->m_le_bTransactionId,
-		       pSdoComCon_p->m_bTransactionId);
-
-	uiSizeOfFrame = 8;
-
-	// set response and abort flag
-	pCommandFrame->m_le_bFlags |= 0x40;
-
-	// copy abortcode to frame
-	AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
-
-	// set size of segment
-	AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(u32));
-
-	// update counter
-	pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
-	pSdoComCon_p->m_uiTransSize = 0;
-
-	// calc framesize
-	uiSizeOfFrame += sizeof(u32);
-
-	// save abort code
-	pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
-
-	// call send function of lower layer
-	switch (pSdoComCon_p->m_SdoProtType) {
-	case kEplSdoTypeAsnd:
-	case kEplSdoTypeUdp:
-		{
-			Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
-						   uiSizeOfFrame, pFrame);
-			break;
-		}
-
-	default:
-		{
-			Ret = kEplSdoComUnsupportedProt;
-		}
-	}			// end of switch(pSdoComCon_p->m_SdoProtType)
-
-	return Ret;
-}
-#endif
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoComTransferFinished
-//
-// Description: calls callback function of application if available
-//              and clears entry in control structure
-//
-// Parameters:  pSdoComCon_p     = pointer to control structure of connection
-//              SdoComConState_p = state of SDO transfer
-//
-// Returns:     tEplKernel  =  errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplSdoComTransferFinished(tEplSdoComConHdl SdoComCon_p,
-					    tEplSdoComCon * pSdoComCon_p,
-					    tEplSdoComConState SdoComConState_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	if (pSdoComCon_p->m_pfnTransferFinished != NULL) {
-		tEplSdoFinishedCb pfnTransferFinished;
-		tEplSdoComFinished SdoComFinished;
-
-		SdoComFinished.m_pUserArg = pSdoComCon_p->m_pUserArg;
-		SdoComFinished.m_uiNodeId = pSdoComCon_p->m_uiNodeId;
-		SdoComFinished.m_uiTargetIndex = pSdoComCon_p->m_uiTargetIndex;
-		SdoComFinished.m_uiTargetSubIndex =
-		    pSdoComCon_p->m_uiTargetSubIndex;
-		SdoComFinished.m_uiTransferredByte =
-		    pSdoComCon_p->m_uiTransferredByte;
-		SdoComFinished.m_dwAbortCode = pSdoComCon_p->m_dwLastAbortCode;
-		SdoComFinished.m_SdoComConHdl = SdoComCon_p;
-		SdoComFinished.m_SdoComConState = SdoComConState_p;
-		if (pSdoComCon_p->m_SdoServiceType ==
-		    kEplSdoServiceWriteByIndex) {
-			SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeWrite;
-		} else {
-			SdoComFinished.m_SdoAccessType = kEplSdoAccessTypeRead;
-		}
-
-		// reset transfer state so this handle is not busy anymore
-		pSdoComCon_p->m_uiTransferredByte = 0;
-		pSdoComCon_p->m_uiTransSize = 0;
-
-		pfnTransferFinished = pSdoComCon_p->m_pfnTransferFinished;
-		// delete function pointer to inform application only once for each transfer
-		pSdoComCon_p->m_pfnTransferFinished = NULL;
-
-		// call application's callback function
-		pfnTransferFinished(&SdoComFinished);
-
-	}
-
-	return Ret;
-}
-
-// EOF
diff --git a/drivers/staging/epl/EplSdoUdpu.c b/drivers/staging/epl/EplSdoUdpu.c
deleted file mode 100644
index c8e950f..0000000
--- a/drivers/staging/epl/EplSdoUdpu.c
+++ /dev/null
@@ -1,650 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for SDO/UDP-Protocolabstractionlayer 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: EplSdoUdpu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/26 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplSdoUdpu.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-
-#include "SocketLinuxKernel.h"
-#include <linux/completion.h>
-#include <linux/sched.h>
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef EPL_SDO_MAX_CONNECTION_UDP
-#define EPL_SDO_MAX_CONNECTION_UDP  5
-#endif
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	unsigned long m_ulIpAddr;	// in network byte order
-	unsigned int m_uiPort;	// in network byte order
-
-} tEplSdoUdpCon;
-
-// instance table
-typedef struct {
-	tEplSdoUdpCon m_aSdoAbsUdpConnection[EPL_SDO_MAX_CONNECTION_UDP];
-	tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
-	SOCKET m_UdpSocket;
-
-	struct completion m_CompletionUdpThread;
-	int m_ThreadHandle;
-	int m_iTerminateThread;
-} tEplSdoUdpInstance;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static tEplSdoUdpInstance SdoUdpInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static int EplSdoUdpThread(void *pArg_p);
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <EPL-SDO-UDP-Layer>                                 */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: Protocolabstraction layer for UDP
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoUdpuInit
-//
-// Description: init first instance of the module
-//
-//
-//
-// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
-//                                  callback-function
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
-{
-	tEplKernel Ret;
-
-	Ret = EplSdoUdpuAddInstance(fpReceiveCb_p);
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoUdpuAddInstance
-//
-// Description: init additional instance of the module
-//              înit socket and start Listen-Thread
-//
-//
-//
-// Parameters:  pReceiveCb_p    =   functionpointer to Sdo-Sequence layer
-//                                  callback-function
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
-{
-	tEplKernel Ret;
-
-	// set instance variables to 0
-	EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
-
-	Ret = kEplSuccessful;
-
-	// save pointer to callback-function
-	if (fpReceiveCb_p != NULL) {
-		SdoUdpInstance_g.m_fpSdoAsySeqCb = fpReceiveCb_p;
-	} else {
-		Ret = kEplSdoUdpMissCb;
-		goto Exit;
-	}
-
-	init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
-	SdoUdpInstance_g.m_iTerminateThread = 0;
-	SdoUdpInstance_g.m_ThreadHandle = 0;
-	SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
-
-	Ret = EplSdoUdpuConfig(INADDR_ANY, 0);
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoUdpuDelInstance
-//
-// Description: del instance of the module
-//              del socket and del Listen-Thread
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoUdpuDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	if (SdoUdpInstance_g.m_ThreadHandle != 0) {	// listen thread was started
-		// close thread
-		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_ThreadHandle = 0;
-	}
-
-	if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
-		// close socket
-		closesocket(SdoUdpInstance_g.m_UdpSocket);
-		SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
-	}
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoUdpuConfig
-//
-// Description: reconfigurate socket with new IP-Address
-//              -> needed for NMT ResetConfiguration
-//
-// Parameters:  ulIpAddr_p      = IpAddress in platform byte order
-//              uiPort_p        = port number in platform byte order
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
-{
-	tEplKernel Ret;
-	struct sockaddr_in Addr;
-	int iError;
-
-	Ret = kEplSuccessful;
-
-	if (uiPort_p == 0) {	// set UDP port to default port number
-		uiPort_p = EPL_C_SDO_EPL_PORT;
-	} else if (uiPort_p > 65535) {
-		Ret = kEplSdoUdpSocketError;
-		goto Exit;
-	}
-
-	if (SdoUdpInstance_g.m_ThreadHandle != 0) {	// listen thread was started
-
-		// close old thread
-		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;
-		SdoUdpInstance_g.m_ThreadHandle = 0;
-	}
-
-	if (SdoUdpInstance_g.m_UdpSocket != INVALID_SOCKET) {
-		// close socket
-		iError = closesocket(SdoUdpInstance_g.m_UdpSocket);
-		SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
-		if (iError != 0) {
-			Ret = kEplSdoUdpSocketError;
-			goto Exit;
-		}
-	}
-	// create Socket
-	SdoUdpInstance_g.m_UdpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-	if (SdoUdpInstance_g.m_UdpSocket == INVALID_SOCKET) {
-		Ret = kEplSdoUdpNoSocket;
-		EPL_DBGLVL_SDO_TRACE0("EplSdoUdpuConfig: socket() failed\n");
-		goto Exit;
-	}
-	// bind socket
-	Addr.sin_family = AF_INET;
-	Addr.sin_port = htons((unsigned short)uiPort_p);
-	Addr.sin_addr.s_addr = htonl(ulIpAddr_p);
-	iError =
-	    bind(SdoUdpInstance_g.m_UdpSocket, (struct sockaddr *)&Addr,
-		 sizeof(Addr));
-	if (iError < 0) {
-		//iError = WSAGetLastError();
-		EPL_DBGLVL_SDO_TRACE1
-		    ("EplSdoUdpuConfig: bind() finished with %i\n", iError);
-		Ret = kEplSdoUdpNoSocket;
-		goto Exit;
-	}
-	// create Listen-Thread
-	SdoUdpInstance_g.m_ThreadHandle =
-		kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g,
-				CLONE_FS | CLONE_FILES);
-	if (SdoUdpInstance_g.m_ThreadHandle == 0) {
-		Ret = kEplSdoUdpThreadError;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoUdpuInitCon
-//
-// Description: init a new connect
-//
-//
-//
-// Parameters:  pSdoConHandle_p = pointer for the new connection handle
-//              uiTargetNodeId_p = NodeId of the target node
-//
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
-			     unsigned int uiTargetNodeId_p)
-{
-	tEplKernel Ret;
-	unsigned int uiCount;
-	unsigned int uiFreeCon;
-	tEplSdoUdpCon *pSdoUdpCon;
-
-	Ret = kEplSuccessful;
-
-	// get free entry in control structure
-	uiCount = 0;
-	uiFreeCon = EPL_SDO_MAX_CONNECTION_UDP;
-	pSdoUdpCon = &SdoUdpInstance_g.m_aSdoAbsUdpConnection[0];
-	while (uiCount < EPL_SDO_MAX_CONNECTION_UDP) {
-		if ((pSdoUdpCon->m_ulIpAddr & htonl(0xFF)) == htonl(uiTargetNodeId_p)) {	// existing connection to target node found
-			// set handle
-			*pSdoConHandle_p = (uiCount | EPL_SDO_UDP_HANDLE);
-
-			goto Exit;
-		} else if ((pSdoUdpCon->m_ulIpAddr == 0)
-			   && (pSdoUdpCon->m_uiPort == 0)) {
-			uiFreeCon = uiCount;
-		}
-		uiCount++;
-		pSdoUdpCon++;
-	}
-
-	if (uiFreeCon == EPL_SDO_MAX_CONNECTION_UDP) {
-		// error no free handle
-		Ret = kEplSdoUdpNoFreeHandle;
-	} else {
-		pSdoUdpCon =
-		    &SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiFreeCon];
-		// save infos for connection
-		pSdoUdpCon->m_uiPort = htons(EPL_C_SDO_EPL_PORT);
-		pSdoUdpCon->m_ulIpAddr = htonl(0xC0A86400 | uiTargetNodeId_p);	// 192.168.100.uiTargetNodeId_p
-
-		// set handle
-		*pSdoConHandle_p = (uiFreeCon | EPL_SDO_UDP_HANDLE);
-
-	}
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoUdpuSendData
-//
-// Description: send data using exisiting connection
-//
-//
-//
-// Parameters:  SdoConHandle_p  = connection handle
-//              pSrcData_p      = pointer to data
-//              dwDataSize_p    = number of databyte
-//                                  -> without asend-header!!!
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
-			      tEplFrame *pSrcData_p, u32 dwDataSize_p)
-{
-	tEplKernel Ret;
-	int iError;
-	unsigned int uiArray;
-	struct sockaddr_in Addr;
-
-	Ret = kEplSuccessful;
-
-	uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
-	if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
-		Ret = kEplSdoUdpInvalidHdl;
-		goto Exit;
-	}
-	//set message type
-	AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, 0x06);	// SDO
-	// target node id (for Udp = 0)
-	AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId, 0x00);
-	// set source-nodeid (for Udp = 0)
-	AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
-
-	// calc size
-	dwDataSize_p += EPL_ASND_HEADER_SIZE;
-
-	// call sendto
-	Addr.sin_family = AF_INET;
-	Addr.sin_port =
-	    (unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
-	    m_uiPort;
-	Addr.sin_addr.s_addr =
-	    SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
-
-	iError = sendto(SdoUdpInstance_g.m_UdpSocket,	// sockethandle
-			(const char *)&pSrcData_p->m_le_bMessageType,	// data to send
-			dwDataSize_p,	// number of bytes to send
-			0,	// flags
-			(struct sockaddr *)&Addr,	// target
-			sizeof(struct sockaddr_in));	// sizeof targetadress
-	if (iError < 0) {
-		EPL_DBGLVL_SDO_TRACE1
-		    ("EplSdoUdpuSendData: sendto() finished with %i\n", iError);
-		Ret = kEplSdoUdpSendError;
-		goto Exit;
-	}
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplSdoUdpuDelCon
-//
-// Description: delete connection from intern structure
-//
-//
-//
-// Parameters:  SdoConHandle_p  = connection handle
-//
-// Returns:     tEplKernel  = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
-{
-	tEplKernel Ret;
-	unsigned int uiArray;
-
-	uiArray = (SdoConHandle_p & ~EPL_SDO_ASY_HANDLE_MASK);
-
-	if (uiArray >= EPL_SDO_MAX_CONNECTION_UDP) {
-		Ret = kEplSdoUdpInvalidHdl;
-		goto Exit;
-	} else {
-		Ret = kEplSuccessful;
-	}
-
-	// delete connection
-	SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr = 0;
-	SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_uiPort = 0;
-
-      Exit:
-	return Ret;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:        EplSdoUdpThread
-//
-// Description:     thread check socket for new data
-//
-//
-//
-// Parameters:      lpParameter = pointer to parameter type tEplSdoUdpThreadPara
-//
-//
-// Returns:         u32   =   errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static int EplSdoUdpThread(void *pArg_p)
-{
-
-	tEplSdoUdpInstance *pInstance;
-	struct sockaddr_in RemoteAddr;
-	int iError;
-	int iCount;
-	int iFreeEntry;
-	u8 abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
-	unsigned int uiSize;
-	tEplSdoConHdl SdoConHdl;
-
-	pInstance = (tEplSdoUdpInstance *) pArg_p;
-	daemonize("EplSdoUdpThread");
-	allow_signal(SIGTERM);
-
-	for (; pInstance->m_iTerminateThread == 0;)
-
-	{
-		// wait for data
-		uiSize = sizeof(struct sockaddr);
-		iError = recvfrom(pInstance->m_UdpSocket,	// Socket
-				  (char *)&abBuffer[0],	// buffer for data
-				  sizeof(abBuffer),	// size of the buffer
-				  0,	// flags
-				  (struct sockaddr *)&RemoteAddr,
-				  (int *)&uiSize);
-		if (iError == -ERESTARTSYS) {
-			break;
-		}
-		if (iError > 0) {
-			// get handle for higher layer
-			iCount = 0;
-			iFreeEntry = 0xFFFF;
-			while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
-				// check if this connection is already known
-				if ((pInstance->m_aSdoAbsUdpConnection[iCount].
-				     m_ulIpAddr == RemoteAddr.sin_addr.s_addr)
-				    && (pInstance->
-					m_aSdoAbsUdpConnection[iCount].
-					m_uiPort == RemoteAddr.sin_port)) {
-					break;
-				}
-
-				if ((pInstance->m_aSdoAbsUdpConnection[iCount].
-				     m_ulIpAddr == 0)
-				    && (pInstance->
-					m_aSdoAbsUdpConnection[iCount].
-					m_uiPort == 0)
-				    && (iFreeEntry == 0xFFFF))
-				{
-					iFreeEntry = iCount;
-				}
-
-				iCount++;
-			}
-
-			if (iCount == EPL_SDO_MAX_CONNECTION_UDP) {
-				// connection unknown
-				// see if there is a free handle
-				if (iFreeEntry != 0xFFFF) {
-					// save adress infos
-					pInstance->
-					    m_aSdoAbsUdpConnection[iFreeEntry].
-					    m_ulIpAddr =
-					    RemoteAddr.sin_addr.s_addr;
-					pInstance->
-					    m_aSdoAbsUdpConnection[iFreeEntry].
-					    m_uiPort = RemoteAddr.sin_port;
-					// call callback
-					SdoConHdl = iFreeEntry;
-					SdoConHdl |= EPL_SDO_UDP_HANDLE;
-					// offset 4 -> start of SDO Sequence header
-					pInstance->m_fpSdoAsySeqCb(SdoConHdl,
-								   (tEplAsySdoSeq
-								    *) &
-								   abBuffer[4],
-								   (iError -
-								    4));
-				} else {
-					EPL_DBGLVL_SDO_TRACE0
-					    ("Error in EplSdoUdpThread() no free handle\n");
-				}
-
-			} else {
-				// known connection
-				// call callback with correct handle
-				SdoConHdl = iCount;
-				SdoConHdl |= EPL_SDO_UDP_HANDLE;
-				// offset 4 -> start of SDO Sequence header
-				pInstance->m_fpSdoAsySeqCb(SdoConHdl,
-							   (tEplAsySdoSeq *) &
-							   abBuffer[4],
-							   (iError - 4));
-			}
-		}		// end of  if(iError!=SOCKET_ERROR)
-	}			// end of for(;;)
-
-	complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
-	return 0;
-}
-
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-
-// EOF
diff --git a/drivers/staging/epl/EplStatusu.c b/drivers/staging/epl/EplStatusu.c
deleted file mode 100644
index b291399..0000000
--- a/drivers/staging/epl/EplStatusu.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for Statusu-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: EplStatusu.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/11/15 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplStatusu.h"
-#include "user/EplDlluCal.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  <xxxxx>                                             */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description:
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   D E F I N I T I O N S                          //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	tEplStatusuCbResponse m_apfnCbResponse[254];
-
-} tEplStatusuInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplStatusuInstance EplStatusuInstance_g;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplStatusuInit
-//
-// Description: init first instance of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplStatusuInit(void)
-{
-	tEplKernel Ret;
-
-	Ret = EplStatusuAddInstance();
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplStatusuAddInstance
-//
-// Description: init other instances of the module
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplStatusuAddInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// reset instance structure
-	EPL_MEMSET(&EplStatusuInstance_g, 0, sizeof(EplStatusuInstance_g));
-
-	// register StatusResponse callback function
-	Ret =
-	    EplDlluCalRegAsndService(kEplDllAsndStatusResponse,
-				     EplStatusuCbStatusResponse,
-				     kEplDllAsndFilterAny);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplStatusuDelInstance
-//
-// Description: delete instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplStatusuDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// deregister StatusResponse callback function
-	Ret =
-	    EplDlluCalRegAsndService(kEplDllAsndStatusResponse, NULL,
-				     kEplDllAsndFilterNone);
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplStatusuReset
-//
-// Description: resets this instance
-//
-// Parameters:
-//
-// Returns:     tEplKernel  = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplStatusuReset(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// reset instance structure
-	EPL_MEMSET(&EplStatusuInstance_g, 0, sizeof(EplStatusuInstance_g));
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplStatusuRequestStatusResponse
-//
-// Description: returns the StatusResponse for the specified node.
-//
-// Parameters:  uiNodeId_p                  = IN: node ID
-//              pfnCbResponse_p             = IN: function pointer to callback function
-//                                            which will be called if StatusResponse is received
-//
-// Return:      tEplKernel                  = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
-					   tEplStatusuCbResponse pfnCbResponse_p)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	// decrement node ID, because array is zero based
-	uiNodeId_p--;
-	if (uiNodeId_p < tabentries(EplStatusuInstance_g.m_apfnCbResponse)) {
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-		if (EplStatusuInstance_g.m_apfnCbResponse[uiNodeId_p] != NULL) {	// request already issued (maybe by someone else)
-			Ret = kEplInvalidOperation;
-		} else {
-			EplStatusuInstance_g.m_apfnCbResponse[uiNodeId_p] =
-			    pfnCbResponse_p;
-			Ret =
-			    EplDlluCalIssueRequest(kEplDllReqServiceStatus,
-						   (uiNodeId_p + 1), 0xFF);
-		}
-#else
-		Ret = kEplInvalidOperation;
-#endif
-	} else {		// invalid node ID specified
-		Ret = kEplInvalidNodeId;
-	}
-
-	return Ret;
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplStatusuCbStatusResponse
-//
-// Description: callback funktion for StatusResponse
-//
-//
-//
-// Parameters:  pFrameInfo_p            = Frame with the StatusResponse
-//
-//
-// Returns:     tEplKernel              = error code
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiNodeId;
-	unsigned int uiIndex;
-	tEplStatusuCbResponse pfnCbResponse;
-
-	uiNodeId = AmiGetByteFromLe(&pFrameInfo_p->m_pFrame->m_le_bSrcNodeId);
-
-	uiIndex = uiNodeId - 1;
-
-	if (uiIndex < tabentries(EplStatusuInstance_g.m_apfnCbResponse)) {
-		// memorize pointer to callback function
-		pfnCbResponse = EplStatusuInstance_g.m_apfnCbResponse[uiIndex];
-		if (pfnCbResponse == NULL) {	// response was not requested
-			goto Exit;
-		}
-		// reset callback function pointer so that caller may issue next request
-		EplStatusuInstance_g.m_apfnCbResponse[uiIndex] = NULL;
-
-		if (pFrameInfo_p->m_uiFrameSize < EPL_C_DLL_MINSIZE_STATUSRES) {	// StatusResponse not received or it has invalid size
-			Ret = pfnCbResponse(uiNodeId, NULL);
-		} else {	// StatusResponse received
-			Ret =
-			    pfnCbResponse(uiNodeId,
-					  &pFrameInfo_p->m_pFrame->m_Data.
-					  m_Asnd.m_Payload.m_StatusResponse);
-		}
-	}
-
-      Exit:
-	return Ret;
-}
-
-// EOF
diff --git a/drivers/staging/epl/EplTarget.h b/drivers/staging/epl/EplTarget.h
deleted file mode 100644
index e76d21f..0000000
--- a/drivers/staging/epl/EplTarget.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for target api function
-
-  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: EplTarget.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2005/12/05 -as:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPLTARGET_H_
-#define _EPLTARGET_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-// =========================================================================
-// macros for memory access (depends on target system)
-// =========================================================================
-
-// NOTE:
-// The following macros are used to combine standard library definitions. Some
-// applications needs to use one common library function (e.g. memcpy()). So
-// you can set (or change) it here.
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/major.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)             kmalloc((size_t)(siz), GFP_KERNEL)
-#define EPL_FREE(ptr)               kfree((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
-
-#define EPL_TGT_INTMASK_ETH     0x0001	// ethernet interrupt
-#define EPL_TGT_INTMASK_DMA     0x0002	// DMA interrupt
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-// currently no Timer functions are needed by EPL stack
-// so they are not implemented yet
-//void  TgtTimerInit(void);
-//u32 TgtGetTickCount(void);
-//void TgtGetNetTime(tEplNetTime * pNetTime_p);
-
-// functions for ethernet driver
-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
deleted file mode 100644
index d1a73ea..0000000
--- a/drivers/staging/epl/EplTimer.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for Epl Timer-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: EplTimer.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/07/06 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "EplEvent.h"
-
-#ifndef _EPLTIMER_H_
-#define _EPLTIMER_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-// type for timer handle
-typedef unsigned long tEplTimerHdl;
-
-typedef struct {
-	tEplEventSink m_EventSink;
-	unsigned long m_ulArg;	// d.k.: converted to unsigned long because
-	// it is never accessed as a pointer by the
-	// timer module and the data the
-	// pointer points to is not saved in any way.
-	// It is just a value. The user is responsible
-	// to store the data statically and convert
-	// the pointer between address spaces.
-
-} tEplTimerArg;
-
-typedef struct {
-	tEplTimerHdl m_TimerHdl;
-	unsigned long m_ulArg;	// d.k.: converted to unsigned long because
-	// it is never accessed as a pointer by the
-	// timer module and the data the
-	// pointer points to is not saved in any way.
-	// It is just a value.
-
-} tEplTimerEventArg;
-
-typedef tEplKernel(* tEplTimerkCallback) (tEplTimerEventArg *pEventArg_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLTIMER_H_
diff --git a/drivers/staging/epl/EplTimeruLinuxKernel.c b/drivers/staging/epl/EplTimeruLinuxKernel.c
deleted file mode 100644
index ff80fc8..0000000
--- a/drivers/staging/epl/EplTimeruLinuxKernel.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  source file for EPL User Timermodule for Linux 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: EplTimeruLinuxKernel.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                KEIL uVision 2
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/09/12 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#include "user/EplTimeru.h"
-#include <linux/timer.h>
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-typedef struct {
-	struct timer_list m_Timer;
-	tEplTimerArg TimerArgument;
-
-} tEplTimeruData;
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-static void EplTimeruCbMs(unsigned long ulParameter_p);
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          C L A S S  <Epl Userspace-Timermodule for Linux Kernel>              */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-//
-// Description: Epl Userspace-Timermodule for Linux Kernel
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruInit
-//
-// Description: function inits first instance
-//
-// Parameters:  void
-//
-// Returns:     tEplKernel  = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimeruInit(void)
-{
-	tEplKernel Ret;
-
-	Ret = EplTimeruAddInstance();
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruAddInstance
-//
-// Description: function inits additional instance
-//
-// Parameters:  void
-//
-// Returns:     tEplKernel  = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimeruAddInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruDelInstance
-//
-// Description: function deletes instance
-//              -> under Linux nothing to do
-//              -> no instance table needed
-//
-// Parameters:  void
-//
-// Returns:     tEplKernel  = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimeruDelInstance(void)
-{
-	tEplKernel Ret;
-
-	Ret = kEplSuccessful;
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruSetTimerMs
-//
-// Description: function creates a timer and returns the corresponding handle
-//
-// 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 EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
-			       unsigned long ulTime_p,
-			       tEplTimerArg Argument_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplTimeruData *pData;
-
-	// check pointer to handle
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-	pData = (tEplTimeruData *) EPL_MALLOC(sizeof(tEplTimeruData));
-	if (pData == NULL) {
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-	init_timer(&pData->m_Timer);
-	pData->m_Timer.function = EplTimeruCbMs;
-	pData->m_Timer.data = (unsigned long)pData;
-	pData->m_Timer.expires = jiffies + ulTime_p * HZ / 1000;
-
-	EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
-
-	add_timer(&pData->m_Timer);
-
-	*pTimerHdl_p = (tEplTimerHdl) pData;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruModifyTimerMs
-//
-// Description: function changes a timer and returns the corresponding handle
-//
-// 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 EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
-				  unsigned long ulTime_p,
-				  tEplTimerArg Argument_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplTimeruData *pData;
-
-	// check pointer to handle
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-	// check handle itself, i.e. was the handle initialized before
-	if (*pTimerHdl_p == 0) {
-		Ret = EplTimeruSetTimerMs(pTimerHdl_p, ulTime_p, Argument_p);
-		goto Exit;
-	}
-	pData = (tEplTimeruData *) * pTimerHdl_p;
-	if ((tEplTimeruData *) pData->m_Timer.data != pData) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-	mod_timer(&pData->m_Timer, (jiffies + ulTime_p * HZ / 1000));
-
-	// copy the TimerArg after the timer is restarted,
-	// so that a timer occured immediately before mod_timer
-	// won't use the new TimerArg and
-	// therefore the old timer cannot be distinguished from the new one.
-	// But if the new timer is too fast, it may get lost.
-	EPL_MEMCPY(&pData->TimerArgument, &Argument_p, sizeof(tEplTimerArg));
-
-	// check if timer is really running
-	if (timer_pending(&pData->m_Timer) == 0) {	// timer is not running
-		// retry starting it
-		add_timer(&pData->m_Timer);
-	}
-	// set handle to pointer of tEplTimeruData
-//    *pTimerHdl_p = (tEplTimerHdl) pData;
-
-      Exit:
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruDeleteTimer
-//
-// Description: function deletes a timer
-//
-// Parameters:  pTimerHdl_p = pointer to a buffer to fill in the handle
-//
-// Returns:     tEplKernel  = errorcode
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplTimeruData *pData;
-
-	// check pointer to handle
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-	// check handle itself, i.e. was the handle initialized before
-	if (*pTimerHdl_p == 0) {
-		Ret = kEplSuccessful;
-		goto Exit;
-	}
-	pData = (tEplTimeruData *) * pTimerHdl_p;
-	if ((tEplTimeruData *) pData->m_Timer.data != pData) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-/*    if (del_timer(&pData->m_Timer) == 1)
-    {
-        kfree(pData);
-    }
-*/
-	// try to delete the timer
-	del_timer(&pData->m_Timer);
-	// free memory in any case
-	kfree(pData);
-
-	// uninitialize handle
-	*pTimerHdl_p = 0;
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruIsTimerActive
-//
-// Description: checks if the timer referenced by the handle is currently
-//              active.
-//
-// Parameters:  TimerHdl_p  = handle of the timer to check
-//
-// Returns:     BOOL        = TRUE, if active;
-//                            FALSE, otherwise
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
-{
-	BOOL fActive = FALSE;
-	tEplTimeruData *pData;
-
-	// check handle itself, i.e. was the handle initialized before
-	if (TimerHdl_p == 0) {	// timer was not created yet, so it is not active
-		goto Exit;
-	}
-	pData = (tEplTimeruData *) TimerHdl_p;
-	if ((tEplTimeruData *) pData->m_Timer.data != pData) {	// invalid timer
-		goto Exit;
-	}
-	// check if timer is running
-	if (timer_pending(&pData->m_Timer) == 0) {	// timer is not running
-		goto Exit;
-	}
-
-	fActive = TRUE;
-
-      Exit:
-	return fActive;
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimeruCbMs
-//
-// Description: function to process timer
-//
-//
-//
-// Parameters:  lpParameter = pointer to structur of type tEplTimeruData
-//
-//
-// Returns:     (none)
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-static void EplTimeruCbMs(unsigned long ulParameter_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplTimeruData *pData;
-	tEplEvent EplEvent;
-	tEplTimerEventArg TimerEventArg;
-
-	pData = (tEplTimeruData *) ulParameter_p;
-
-	// call event function
-	TimerEventArg.m_TimerHdl = (tEplTimerHdl) pData;
-	TimerEventArg.m_ulArg = pData->TimerArgument.m_ulArg;
-
-	EplEvent.m_EventSink = pData->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);
-
-	// d.k. do not free memory, user has to call EplTimeruDeleteTimer()
-	//kfree(pData);
-
-}
-
-// EOF
diff --git a/drivers/staging/epl/EplVersion.h b/drivers/staging/epl/EplVersion.h
deleted file mode 100644
index 75570d5..0000000
--- a/drivers/staging/epl/EplVersion.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  This file defines the EPL version for the stack, as string
-                and for object 0x1018 within object 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: EplVersion.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    all
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-****************************************************************************/
-
-#ifndef _EPL_VERSION_H_
-#define _EPL_VERSION_H_
-
-// NOTE:
-// All version macros should contain the same version number. But do not use
-// defines instead of the numbers. Because the macro EPL_STRING_VERSION() can not
-// convert a define to a string.
-//
-// Format: maj.min.build
-//         maj            = major version
-//             min        = minor version (will be set to 0 if major version will be incremented)
-//                 build  = current build (will be set to 0 if minor version will be incremented)
-//
-#define DEFINED_STACK_VERSION       EPL_STACK_VERSION   (1, 3, 0)
-#define DEFINED_OBJ1018_VERSION     EPL_OBJ1018_VERSION (1, 3, 0)
-#define DEFINED_STRING_VERSION      EPL_STRING_VERSION  (1, 3, 0)
-
-// -----------------------------------------------------------------------------
-#define EPL_PRODUCT_NAME            "EPL V2"
-#define EPL_PRODUCT_VERSION         DEFINED_STRING_VERSION
-#define EPL_PRODUCT_MANUFACTURER    "SYS TEC electronic GmbH"
-
-#define EPL_PRODUCT_KEY         "SO-1083"
-#define EPL_PRODUCT_DESCRIPTION "openPOWERLINK Protocol Stack Source"
-
-#endif // _EPL_VERSION_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/Kconfig b/drivers/staging/epl/Kconfig
deleted file mode 100644
index 9f939d5..0000000
--- a/drivers/staging/epl/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config EPL
-	tristate "openPOWERLINK protocol stack"
-	depends on NET && HIGH_RES_TIMERS && X86
-	default N
-	---help---
-	  Enable support for the openPOWERLINK network protocol stack.
diff --git a/drivers/staging/epl/Makefile b/drivers/staging/epl/Makefile
deleted file mode 100644
index a2c8241..0000000
--- a/drivers/staging/epl/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-obj-$(CONFIG_EPL)	+= epl.o
-
-epl-objs := 	\
-	EplApiGeneric.o		\
-	EplApiLinuxKernel.o	\
-	EplApiProcessImage.o	\
-	EplDllk.o		\
-	EplDllkCal.o		\
-	EplDlluCal.o		\
-	EplErrorHandlerk.o	\
-	EplEventk.o		\
-	EplEventu.o		\
-	EplIdentu.o		\
-	EplNmtCnu.o		\
-	EplNmtk.o		\
-	EplNmtkCal.o		\
-	EplNmtMnu.o		\
-	EplNmtu.o		\
-	EplNmtuCal.o		\
-	EplObd.o		\
-	EplObdkCal.o		\
-	EplObdu.o		\
-	EplObduCal.o		\
-	EplPdok.o		\
-	EplPdokCal.o		\
-	EplPdou.o		\
-	EplSdoAsndu.o		\
-	EplSdoAsySequ.o		\
-	EplSdoComu.o		\
-	EplSdoUdpu.o		\
-	EplStatusu.o		\
-	EplTimeruLinuxKernel.o	\
-	amix86.o		\
-	SharedBuff.o		\
-	ShbIpc-LinuxKernel.o	\
-	TimerHighReskX86.o	\
-	VirtualEthernetLinux.o	\
-	SocketLinuxKernel.o	\
-	proc_fs.o		\
-	demo_main.o		\
-	Edrv8139.o		\
diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c
deleted file mode 100644
index 2b10c37..0000000
--- a/drivers/staging/epl/SharedBuff.c
+++ /dev/null
@@ -1,1762 +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 independend part for the
-                shared buffer
-
-  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)
-
-****************************************************************************/
-
-#if defined(WIN32) || defined(_WIN32)
-
-#ifdef UNDER_RTSS
-	// RTX header
-#include <windows.h>
-#include <process.h>
-#include <rtapi.h>
-
-#elif __BORLANDC__
-	// borland C header
-#include <windows.h>
-#include <process.h>
-
-#elif WINCE
-#include <windows.h>
-
-#else
-	// MSVC needs to include windows.h at first
-	// the following defines ar necessary for function prototypes for waitable timers
-#define _WIN32_WINDOWS 0x0401
-#define _WIN32_WINNT   0x0400
-#include <windows.h>
-#include <process.h>
-#endif
-
-#endif
-
-#include "global.h"
-#include "SharedBuff.h"
-#include "ShbIpc.h"
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-//  Configuration
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Constant definitions
-//---------------------------------------------------------------------------
-
-#define SBC_MAGIC_ID    0x53424323	// magic ID ("SBC#")
-#define SBL_MAGIC_ID    0x53424C23	// magic ID ("SBL#")
-
-//---------------------------------------------------------------------------
-//  Local types
-//---------------------------------------------------------------------------
-
-// structure to administrate circular shared buffer head
-typedef struct {
-	unsigned long m_ShbCirMagicID;	// magic ID ("SBC#")
-	unsigned long m_ulBufferTotalSize;	// over-all size of complete buffer
-	unsigned long m_ulBufferDataSize;	// size of complete data area
-	unsigned long m_ulWrIndex;	// current write index (set bevore write)
-	unsigned long m_ulRdIndex;	// current read index (set after read)
-	unsigned long m_ulNumOfWriteJobs;	// number of currently (parallel running) write operations
-	unsigned long m_ulDataInUse;	// currently used buffer size (incl. uncompleted write operations)
-	unsigned long m_ulDataApended;	// buffer size of complete new written but not yet readable data (in case of m_ulNumOfWriteJobs>1)
-	unsigned long m_ulBlocksApended;	// number of complete new written but not yet readable data blocks (in case of m_ulNumOfWriteJobs>1)
-	unsigned long m_ulDataReadable;	// buffer size with readable (complete written) data
-	unsigned long m_ulBlocksReadable;	// number of readable (complete written) data blocks
-	tShbCirSigHndlrNewData m_pfnSigHndlrNewData;	// application handler to signal new data
-	unsigned int m_fBufferLocked;	// TRUE if buffer is locked (because of pending reset request)
-	tShbCirSigHndlrReset m_pfnSigHndlrReset;	// application handler to signal buffer reset is done
-	unsigned char m_Data;	// start of data area (the real data size is unknown at this time)
-
-} tShbCirBuff;
-
-// structure to administrate linear shared buffer head
-typedef struct {
-	unsigned int m_ShbLinMagicID;	// magic ID ("SBL#")
-	unsigned long m_ulBufferTotalSize;	// over-all size of complete buffer
-	unsigned long m_ulBufferDataSize;	// size of complete data area
-	unsigned char m_Data;	// start of data area (the real data size is unknown at this time)
-
-} tShbLinBuff;
-
-// type to save size of a single data block inside the circular shared buffer
-typedef struct {
-	unsigned int m_uiFullBlockSize:28;	// a single block must not exceed a length of 256MByte :-)
-	unsigned int m_uiAlignFillBytes:4;
-
-} tShbCirBlockSize;
-
-#define SBC_BLOCK_ALIGNMENT                  4	// alignment must *not* be lower than sizeof(tShbCirBlockSize)!
-#define SBC_MAX_BLOCK_SIZE         ((1<<28)-1)	// = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
-
-#define SBL_BLOCK_ALIGNMENT                  4
-#define SBL_MAX_BLOCK_SIZE         ((1<<28)-1)	// = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
-
-//---------------------------------------------------------------------------
-//  Global variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Local variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Get pointer to Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-
-	pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance_p);
-	ASSERT(pShbCirBuff->m_ShbCirMagicID == SBC_MAGIC_ID);
-
-	return (pShbCirBuff);
-
-}
-
-//---------------------------------------------------------------------------
-//  Get pointer to Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
-{
-
-	tShbLinBuff *pShbLinBuff;
-
-	pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance_p);
-	ASSERT(pShbLinBuff->m_ShbLinMagicID == SBL_MAGIC_ID);
-
-	return (pShbLinBuff);
-
-}
-
-// not inlined internal functions
-int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p);
-void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
-			      unsigned int fTimeOut_p);
-
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-// not inlined external functions
-
-//---------------------------------------------------------------------------
-//  Initialize Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbInit(void)
-{
-
-	tShbError ShbError;
-
-	ShbError = ShbIpcInit();
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Deinitialize Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbExit(void)
-{
-
-	tShbError ShbError;
-
-	ShbError = ShbIpcExit();
-
-	return (ShbError);
-
-}
-
-//-------------------------------------------------------------------------//
-//                                                                         //
-//          C i r c u l a r   S h a r e d   B u f f e r                    //
-//                                                                         //
-//-------------------------------------------------------------------------//
-
-//---------------------------------------------------------------------------
-//  Allocate Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirAllocBuffer(unsigned long ulBufferSize_p,
-			    const char *pszBufferID_p,
-			    tShbInstance * ppShbInstance_p,
-			    unsigned int *pfShbNewCreated_p)
-{
-
-	tShbInstance pShbInstance;
-	tShbCirBuff *pShbCirBuff;
-	unsigned int fShbNewCreated;
-	unsigned long ulBufferDataSize;
-	unsigned long ulBufferTotalSize;
-	tShbError ShbError;
-
-	// check arguments
-	if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-
-	// calculate length of memory to allocate
-	ulBufferDataSize =
-	    (ulBufferSize_p +
-	     (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
-	ulBufferTotalSize = ulBufferDataSize + sizeof(tShbCirBuff);
-
-	// allocate a new or open an existing shared buffer
-	ShbError = ShbIpcAllocBuffer(ulBufferTotalSize, pszBufferID_p,
-				     &pShbInstance, &fShbNewCreated);
-	if (ShbError != kShbOk) {
-		goto Exit;
-	}
-
-	if (pShbInstance == NULL) {
-		ShbError = kShbOutOfMem;
-		goto Exit;
-	}
-
-	// get pointer to shared buffer
-	pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance);
-
-	// if the shared buffer was new created, than this process has
-	// to initialize it, otherwise the buffer is already in use
-	// and *must not* be reseted
-	if (fShbNewCreated) {
-#ifndef NDEBUG
-		{
-			memset(pShbCirBuff, 0xCC, ulBufferTotalSize);
-		}
-#endif
-
-		pShbCirBuff->m_ShbCirMagicID = SBC_MAGIC_ID;
-		pShbCirBuff->m_ulBufferTotalSize = ulBufferTotalSize;
-		pShbCirBuff->m_ulBufferDataSize = ulBufferDataSize;
-		pShbCirBuff->m_ulWrIndex = 0;
-		pShbCirBuff->m_ulRdIndex = 0;
-		pShbCirBuff->m_ulNumOfWriteJobs = 0;
-		pShbCirBuff->m_ulDataInUse = 0;
-		pShbCirBuff->m_ulDataApended = 0;
-		pShbCirBuff->m_ulBlocksApended = 0;
-		pShbCirBuff->m_ulDataReadable = 0;
-		pShbCirBuff->m_ulBlocksReadable = 0;
-		pShbCirBuff->m_pfnSigHndlrNewData = NULL;
-		pShbCirBuff->m_fBufferLocked = FALSE;
-		pShbCirBuff->m_pfnSigHndlrReset = NULL;
-	} else {
-		if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-			ShbError = kShbInvalidBufferType;
-			goto Exit;
-		}
-	}
-
-      Exit:
-
-	*ppShbInstance_p = pShbInstance;
-	*pfShbNewCreated_p = fShbNewCreated;
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Release Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
-	tShbError ShbError;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbOk;
-		goto Exit;
-	}
-
-	ShbError = ShbIpcReleaseBuffer(pShbInstance_p);
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Reset Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
-			    unsigned long ulTimeOut_p,
-			    tShbCirSigHndlrReset pfnSignalHandlerReset_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	unsigned long ulNumOfWriteJobs = 0;	// d.k. GCC complains about uninitialized variable otherwise
-	tShbError ShbError;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	// start reset job by setting request request in buffer header
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		if (!pShbCirBuff->m_fBufferLocked) {
-			ulNumOfWriteJobs = pShbCirBuff->m_ulNumOfWriteJobs;
-
-			pShbCirBuff->m_fBufferLocked = TRUE;
-			pShbCirBuff->m_pfnSigHndlrReset =
-			    pfnSignalHandlerReset_p;
-		} else {
-			ShbError = kShbAlreadyReseting;
-		}
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	if (ShbError != kShbOk) {
-		goto Exit;
-	}
-
-	// if there is currently no running write operation then reset buffer
-	// immediately, otherwise wait until the last write job is ready by
-	// starting a signal process
-	if (ulNumOfWriteJobs == 0) {
-		// there is currently no running write operation
-		// -> reset buffer immediately
-		ShbCirSignalHandlerReset(pShbInstance_p, FALSE);
-		ShbError = kShbOk;
-	} else {
-		// there is currently at least one running write operation
-		// -> starting signal process to wait until the last write job is ready
-		ShbError =
-		    ShbIpcStartSignalingJobReady(pShbInstance_p, ulTimeOut_p,
-						 ShbCirSignalHandlerReset);
-	}
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Write data block to Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
-			       const void *pSrcDataBlock_p,
-			       unsigned long ulDataBlockSize_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	tShbCirBlockSize ShbCirBlockSize;
-	unsigned int uiFullBlockSize;
-	unsigned int uiAlignFillBytes;
-	unsigned char *pShbCirDataPtr;
-	unsigned char *pScrDataPtr;
-	unsigned long ulDataSize;
-	unsigned long ulChunkSize;
-	unsigned long ulWrIndex = 0;	// d.k. GCC complains about uninitialized variable otherwise
-	unsigned int fSignalNewData;
-	unsigned int fSignalReset;
-	tShbError ShbError;
-	tShbError ShbError2;
-	int fRes;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) {
-		// nothing to do here
-		ShbError = kShbOk;
-		goto Exit;
-	}
-
-	if (ulDataBlockSize_p > SBC_MAX_BLOCK_SIZE) {
-		ShbError = kShbExceedDataSizeLimit;
-		goto Exit;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	pScrDataPtr = (unsigned char *)pSrcDataBlock_p;
-	fSignalNewData = FALSE;
-	fSignalReset = FALSE;
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	// calculate data block size in circular buffer
-	ulDataSize =
-	    (ulDataBlockSize_p +
-	     (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
-	uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize);	// data size + header
-	uiAlignFillBytes = ulDataSize - ulDataBlockSize_p;
-
-	ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize;
-	ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
-
-	// reserve the needed memory for the write operation to do now
-	// and make necessary adjustments in the circular buffer header
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		// check if there is sufficient memory available to store
-		// the new data
-		fRes =
-		    uiFullBlockSize <=
-		    (pShbCirBuff->m_ulBufferDataSize -
-		     pShbCirBuff->m_ulDataInUse);
-		if (fRes) {
-			// set write pointer for the write operation to do now
-			// to the current write pointer of the circular buffer
-			ulWrIndex = pShbCirBuff->m_ulWrIndex;
-
-			// reserve the needed memory for the write operation to do now
-			pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
-
-			// set new write pointer behind the reserved memory
-			// for the write operation to do now
-			pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
-			pShbCirBuff->m_ulWrIndex %=
-			    pShbCirBuff->m_ulBufferDataSize;
-
-			// increment number of currently (parallel running)
-			// write operations
-			pShbCirBuff->m_ulNumOfWriteJobs++;
-		}
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	if (!fRes) {
-		ShbError = kShbBufferFull;
-		goto Exit;
-	}
-
-	// copy the data to the circular buffer
-	// (the copy process itself will be done outside of any
-	// critical/locked section)
-	pShbCirDataPtr = &pShbCirBuff->m_Data;	// ptr to start of data area
-
-	// write real size of current block (incl. alignment fill bytes)
-	*(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
-	ulWrIndex += sizeof(tShbCirBlockSize);
-	ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
-	if (ulWrIndex + ulDataBlockSize_p <= pShbCirBuff->m_ulBufferDataSize) {
-		// linear write operation
-		memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr,
-		       ulDataBlockSize_p);
-	} else {
-		// wrap-around write operation
-		ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
-		memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulChunkSize);
-		memcpy(pShbCirDataPtr, pScrDataPtr + ulChunkSize,
-		       ulDataBlockSize_p - ulChunkSize);
-	}
-
-	// adjust header information for circular buffer with properties
-	// of the wiritten data block
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		pShbCirBuff->m_ulDataApended += uiFullBlockSize;
-		pShbCirBuff->m_ulBlocksApended++;
-
-		// decrement number of currently (parallel running) write operations
-		if (!--pShbCirBuff->m_ulNumOfWriteJobs) {
-			// if there is no other write process running then
-			// set new size of readable (complete written) data and
-			// adjust number of readable blocks
-			pShbCirBuff->m_ulDataReadable +=
-			    pShbCirBuff->m_ulDataApended;
-			pShbCirBuff->m_ulBlocksReadable +=
-			    pShbCirBuff->m_ulBlocksApended;
-
-			pShbCirBuff->m_ulDataApended = 0;
-			pShbCirBuff->m_ulBlocksApended = 0;
-
-			fSignalNewData = TRUE;
-			fSignalReset = pShbCirBuff->m_fBufferLocked;
-		}
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	// signal new data event to a potentially reading application
-	if (fSignalNewData) {
-		ShbError2 = ShbIpcSignalNewData(pShbInstance_p);
-		if (ShbError == kShbOk) {
-			ShbError = ShbError2;
-		}
-	}
-	// signal that the last write job has been finished to allow
-	// a waiting application to reset the buffer now
-	if (fSignalReset) {
-		ShbError2 = ShbIpcSignalJobReady(pShbInstance_p);
-		if (ShbError == kShbOk) {
-			ShbError = ShbError2;
-		}
-	}
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Allocate block within the Circular Shared Buffer for chunk writing
-//---------------------------------------------------------------------------
-
-tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
-			       tShbCirChunk * pShbCirChunk_p,
-			       unsigned long ulDataBufferSize_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	tShbCirBlockSize ShbCirBlockSize;
-	unsigned int uiFullBlockSize;
-	unsigned int uiAlignFillBytes;
-	unsigned char *pShbCirDataPtr;
-	unsigned long ulDataSize;
-	unsigned long ulWrIndex = 0;	// d.k. GCC complains about uninitialized variable otherwise
-	tShbError ShbError;
-	int fRes;
-
-	// check arguments
-	if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL)) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	if (ulDataBufferSize_p == 0) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	if (ulDataBufferSize_p > SBC_MAX_BLOCK_SIZE) {
-		ShbError = kShbExceedDataSizeLimit;
-		goto Exit;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	// calculate data block size in circular buffer
-	ulDataSize =
-	    (ulDataBufferSize_p +
-	     (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
-	uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize);	// data size + header
-	uiAlignFillBytes = ulDataSize - ulDataBufferSize_p;
-
-	ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize;
-	ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
-
-	// reserve the needed memory for the write operation to do now
-	// and make necessary adjustments in the circular buffer header
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		// check if there is sufficient memory available to store
-		// the new data
-		fRes =
-		    (uiFullBlockSize <=
-		     (pShbCirBuff->m_ulBufferDataSize -
-		      pShbCirBuff->m_ulDataInUse));
-		if (fRes) {
-			// set write pointer for the write operation to do now
-			// to the current write pointer of the circular buffer
-			ulWrIndex = pShbCirBuff->m_ulWrIndex;
-
-			// reserve the needed memory for the write operation to do now
-			pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
-
-			// set new write pointer behind the reserved memory
-			// for the write operation to do now
-			pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
-			pShbCirBuff->m_ulWrIndex %=
-			    pShbCirBuff->m_ulBufferDataSize;
-
-			// increment number of currently (parallel running)
-			// write operations
-			pShbCirBuff->m_ulNumOfWriteJobs++;
-		}
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	if (!fRes) {
-		ShbError = kShbBufferFull;
-		goto Exit;
-	}
-
-	// setup header information for allocated buffer
-	pShbCirDataPtr = &pShbCirBuff->m_Data;	// ptr to start of data area
-
-	// write real size of current block (incl. alignment fill bytes)
-	*(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
-	ulWrIndex += sizeof(tShbCirBlockSize);
-	ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
-	// setup chunk descriptor
-	pShbCirChunk_p->m_uiFullBlockSize = uiFullBlockSize;
-	pShbCirChunk_p->m_ulAvailableSize = ulDataBufferSize_p;
-	pShbCirChunk_p->m_ulWrIndex = ulWrIndex;
-	pShbCirChunk_p->m_fBufferCompleted = FALSE;
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Write data chunk into an allocated buffer of the Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
-			       tShbCirChunk *pShbCirChunk_p,
-			       const void *pSrcDataChunk_p,
-			       unsigned long ulDataChunkSize_p,
-			       unsigned int *pfBufferCompleted_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	unsigned char *pShbCirDataPtr;
-	unsigned char *pScrDataPtr;
-	unsigned long ulSubChunkSize;
-	unsigned long ulWrIndex;
-	unsigned int fBufferCompleted;
-	unsigned int fSignalNewData;
-	unsigned int fSignalReset;
-	tShbError ShbError;
-	tShbError ShbError2;
-
-	// check arguments
-	if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL)
-	    || (pfBufferCompleted_p == NULL)) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	if ((pSrcDataChunk_p == NULL) || (ulDataChunkSize_p == 0)) {
-		// nothing to do here
-		ShbError = kShbOk;
-		goto Exit;
-	}
-
-	if (pShbCirChunk_p->m_fBufferCompleted) {
-		ShbError = kShbBufferAlreadyCompleted;
-		goto Exit;
-	}
-
-	if (ulDataChunkSize_p > pShbCirChunk_p->m_ulAvailableSize) {
-		ShbError = kShbExceedDataSizeLimit;
-		goto Exit;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	pScrDataPtr = (unsigned char *)pSrcDataChunk_p;
-	fSignalNewData = FALSE;
-	fSignalReset = FALSE;
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	ulWrIndex = pShbCirChunk_p->m_ulWrIndex;
-
-	// copy the data to the circular buffer
-	// (the copy process itself will be done outside of any
-	// critical/locked section)
-	pShbCirDataPtr = &pShbCirBuff->m_Data;	// ptr to start of data area
-
-	if (ulWrIndex + ulDataChunkSize_p <= pShbCirBuff->m_ulBufferDataSize) {
-		// linear write operation
-		memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr,
-		       ulDataChunkSize_p);
-	} else {
-		// wrap-around write operation
-		ulSubChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
-		memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulSubChunkSize);
-		memcpy(pShbCirDataPtr, pScrDataPtr + ulSubChunkSize,
-		       ulDataChunkSize_p - ulSubChunkSize);
-	}
-
-	// adjust chunk descriptor
-	ulWrIndex += ulDataChunkSize_p;
-	ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
-	pShbCirChunk_p->m_ulAvailableSize -= ulDataChunkSize_p;
-	pShbCirChunk_p->m_ulWrIndex = ulWrIndex;
-
-	fBufferCompleted = (pShbCirChunk_p->m_ulAvailableSize == 0);
-	pShbCirChunk_p->m_fBufferCompleted = fBufferCompleted;
-
-	// if the complete allocated buffer is filled with data then
-	// adjust header information for circular buffer with properties
-	// of the wiritten data block
-	if (fBufferCompleted) {
-		ShbIpcEnterAtomicSection(pShbInstance_p);
-		{
-			pShbCirBuff->m_ulDataApended +=
-			    pShbCirChunk_p->m_uiFullBlockSize;
-			pShbCirBuff->m_ulBlocksApended++;
-
-			// decrement number of currently (parallel running) write operations
-			if (!--pShbCirBuff->m_ulNumOfWriteJobs) {
-				// if there is no other write process running then
-				// set new size of readable (complete written) data and
-				// adjust number of readable blocks
-				pShbCirBuff->m_ulDataReadable +=
-				    pShbCirBuff->m_ulDataApended;
-				pShbCirBuff->m_ulBlocksReadable +=
-				    pShbCirBuff->m_ulBlocksApended;
-
-				pShbCirBuff->m_ulDataApended = 0;
-				pShbCirBuff->m_ulBlocksApended = 0;
-
-				fSignalNewData = TRUE;
-				fSignalReset = pShbCirBuff->m_fBufferLocked;
-			}
-		}
-		ShbIpcLeaveAtomicSection(pShbInstance_p);
-	}
-
-	// signal new data event to a potentially reading application
-	if (fSignalNewData) {
-		ShbError2 = ShbIpcSignalNewData(pShbInstance_p);
-		if (ShbError == kShbOk) {
-			ShbError = ShbError2;
-		}
-	}
-	// signal that the last write job has been finished to allow
-	// a waiting application to reset the buffer now
-	if (fSignalReset) {
-		ShbError2 = ShbIpcSignalJobReady(pShbInstance_p);
-		if (ShbError == kShbOk) {
-			ShbError = ShbError2;
-		}
-	}
-
-	*pfBufferCompleted_p = fBufferCompleted;
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Read data block from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
-			      void *pDstDataBlock_p,
-			      unsigned long ulRdBuffSize_p,
-			      unsigned long *pulDataBlockSize_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	tShbCirBlockSize ShbCirBlockSize;
-	unsigned long ulDataReadable;
-	unsigned char *pShbCirDataPtr;
-	unsigned char *pDstDataPtr;
-	unsigned long ulDataSize = 0;	// d.k. GCC complains about uninitialized variable otherwise
-	unsigned long ulChunkSize;
-	unsigned long ulRdIndex;
-	tShbError ShbError;
-
-	// check arguments
-	if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-
-	if ((pDstDataBlock_p == NULL) || (ulRdBuffSize_p == 0)) {
-		// nothing to do here
-		ShbError = kShbOk;
-		goto Exit;
-	}
-
-	ShbError = kShbOk;
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	pDstDataPtr = (unsigned char *)pDstDataBlock_p;
-	ulDataSize = 0;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	// get total number of readable bytes for the whole circular buffer
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		ulDataReadable = pShbCirBuff->m_ulDataReadable;
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	// if there are readable data available, then there must be at least
-	// one complete readable data block
-	if (ulDataReadable > 0) {
-		// get pointer to start of data area and current read index
-		pShbCirDataPtr = &pShbCirBuff->m_Data;	// ptr to start of data area
-		ulRdIndex = pShbCirBuff->m_ulRdIndex;
-
-		// get real size of current block (incl. alignment fill bytes)
-		ShbCirBlockSize =
-		    *(tShbCirBlockSize *) (pShbCirDataPtr + ulRdIndex);
-		ulRdIndex += sizeof(tShbCirBlockSize);
-		ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
-
-		// get size of user data inside the current block
-		ulDataSize =
-		    ShbCirBlockSize.m_uiFullBlockSize -
-		    ShbCirBlockSize.m_uiAlignFillBytes;
-		ulDataSize -= sizeof(tShbCirBlockSize);
-	}
-
-	// ulDataSize = MIN(ulDataSize, ulRdBuffSize_p);
-	if (ulDataSize > ulRdBuffSize_p) {
-		ulDataSize = ulRdBuffSize_p;
-		ShbError = kShbDataTruncated;
-	}
-
-	if (ulDataSize == 0) {
-		// nothing to do here
-		ShbError = kShbNoReadableData;
-		goto Exit;
-	}
-
-	// copy the data from the circular buffer
-	// (the copy process itself will be done outside of any
-	// critical/locked section)
-	if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) {
-		// linear read operation
-		memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulDataSize);
-	} else {
-		// wrap-around read operation
-		ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
-		memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulChunkSize);
-		memcpy(pDstDataPtr + ulChunkSize, pShbCirDataPtr,
-		       ulDataSize - ulChunkSize);
-	}
-
-#ifndef NDEBUG
-	{
-		tShbCirBlockSize ClrShbCirBlockSize;
-
-		if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) {
-			// linear buffer
-			memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulDataSize);
-		} else {
-			// wrap-around read operation
-			ulChunkSize =
-			    pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
-			memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulChunkSize);
-			memset(pShbCirDataPtr, 0xDD, ulDataSize - ulChunkSize);
-		}
-
-		ClrShbCirBlockSize.m_uiFullBlockSize = /*(unsigned int) */ -1;	// -1 = xFFFFFFF
-		ClrShbCirBlockSize.m_uiAlignFillBytes = /*(unsigned int) */ -1;	// -1 = Fxxxxxxx
-		*(tShbCirBlockSize *) (pShbCirDataPtr +
-				       pShbCirBuff->m_ulRdIndex) =
-		    ClrShbCirBlockSize;
-	}
-#endif // #ifndef NDEBUG
-
-	// set new size of readable data, data in use, new read index
-	// and adjust number of readable blocks
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		pShbCirBuff->m_ulDataInUse -= ShbCirBlockSize.m_uiFullBlockSize;
-		pShbCirBuff->m_ulDataReadable -=
-		    ShbCirBlockSize.m_uiFullBlockSize;
-		pShbCirBuff->m_ulBlocksReadable--;
-
-		//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
-		if ((pShbCirBuff->m_ulDataInUse == 0)
-		    && (pShbCirBuff->m_ulDataReadable == 0)) {
-			ASSERT(pShbCirBuff->m_ulBlocksReadable == 0);
-
-			pShbCirBuff->m_ulWrIndex = 0;
-			pShbCirBuff->m_ulRdIndex = 0;
-		} else
-			//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
-		{
-			pShbCirBuff->m_ulRdIndex +=
-			    ShbCirBlockSize.m_uiFullBlockSize;
-			pShbCirBuff->m_ulRdIndex %=
-			    pShbCirBuff->m_ulBufferDataSize;
-		}
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-      Exit:
-
-	*pulDataBlockSize_p = ulDataSize;
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Get data size of next readable block from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
-				unsigned long *pulDataBlockSize_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	unsigned long ulDataReadable;
-	unsigned char *pShbCirDataPtr;
-	tShbCirBlockSize ShbCirBlockSize;
-	unsigned long ulDataSize;
-	tShbError ShbError;
-
-	// check arguments
-	if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	ulDataSize = 0;
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	// get total number of readable bytes for the whole circular buffer
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		ulDataReadable = pShbCirBuff->m_ulDataReadable;
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	// if there are readable data available, then there must be at least
-	// one complete readable data block
-	if (ulDataReadable > 0) {
-		pShbCirDataPtr =
-		    &pShbCirBuff->m_Data + pShbCirBuff->m_ulRdIndex;
-
-		// get real size of current block (incl. alignment fill bytes)
-		ShbCirBlockSize = *(tShbCirBlockSize *) pShbCirDataPtr;
-
-		// get size of user data inside the current block
-		ulDataSize =
-		    ShbCirBlockSize.m_uiFullBlockSize -
-		    ShbCirBlockSize.m_uiAlignFillBytes;
-		ulDataSize -= sizeof(tShbCirBlockSize);
-	}
-
-      Exit:
-
-	*pulDataBlockSize_p = ulDataSize;
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Get number of readable blocks from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
-				  unsigned long *pulDataBlockCount_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	unsigned long ulBlockCount;
-	tShbError ShbError;
-
-	// check arguments
-	if ((pShbInstance_p == NULL) || (pulDataBlockCount_p == NULL)) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	ulBlockCount = 0;
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		ulBlockCount = pShbCirBuff->m_ulBlocksReadable;
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	*pulDataBlockCount_p = ulBlockCount;
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Set application handler to signal new data for Circular Shared Buffer
-//  d.k.: new parameter priority as enum
-//---------------------------------------------------------------------------
-
-tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p,
-					tShbCirSigHndlrNewData pfnSignalHandlerNewData_p,
-					tShbPriority ShbPriority_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	tShbError ShbError;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	if (pfnSignalHandlerNewData_p != NULL) {
-		// set a new signal handler
-		if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) {
-			ShbError = kShbAlreadySignaling;
-			goto Exit;
-		}
-
-		pShbCirBuff->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
-		ShbError =
-		    ShbIpcStartSignalingNewData(pShbInstance_p,
-						ShbCirSignalHandlerNewData,
-						ShbPriority_p);
-	} else {
-		// remove existing signal handler
-		ShbError = ShbIpcStopSignalingNewData(pShbInstance_p);
-		if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) {
-			pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p, 0);
-		}
-		pShbCirBuff->m_pfnSigHndlrNewData = NULL;
-	}
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  DEBUG: Trace Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-#ifndef NDEBUG
-tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	char szMagigID[sizeof(SBC_MAGIC_ID) + 1];
-	tShbCirBlockSize ShbCirBlockSize;
-	unsigned long ulDataReadable;
-	unsigned char *pShbCirDataPtr;
-	unsigned long ulBlockIndex;
-	unsigned int nBlockCount;
-	unsigned long ulDataSize;
-	unsigned long ulChunkSize;
-	unsigned long ulRdIndex;
-	tShbError ShbError;
-
-	TRACE0("\n\n##### Circular Shared Buffer #####\n");
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		TRACE1("\nERROR: invalid buffer address (0x%08lX)\n",
-		       (unsigned long)pShbInstance_p);
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	*(unsigned long *)&szMagigID[0] = pShbCirBuff->m_ShbCirMagicID;
-	szMagigID[sizeof(SBC_MAGIC_ID)] = '\0';
-
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		TRACE1("\nBuffer Address:   0x%08lX\n",
-		       (unsigned long)pShbCirBuff);
-
-		TRACE0("\nHeader Info:");
-		TRACE2("\nMagigID:          '%s' (%08lX)", szMagigID,
-		       pShbCirBuff->m_ShbCirMagicID);
-		TRACE1("\nBufferTotalSize:  %4lu [Bytes]",
-		       pShbCirBuff->m_ulBufferTotalSize);
-		TRACE1("\nBufferDataSize:   %4lu [Bytes]",
-		       pShbCirBuff->m_ulBufferDataSize);
-		TRACE1("\nWrIndex:          %4lu", pShbCirBuff->m_ulWrIndex);
-		TRACE1("\nRdIndex:          %4lu", pShbCirBuff->m_ulRdIndex);
-		TRACE1("\nNumOfWriteJobs:   %4lu",
-		       pShbCirBuff->m_ulNumOfWriteJobs);
-		TRACE1("\nDataInUse:        %4lu [Bytes]",
-		       pShbCirBuff->m_ulDataInUse);
-		TRACE1("\nDataApended:      %4lu [Bytes]",
-		       pShbCirBuff->m_ulDataApended);
-		TRACE1("\nBlocksApended:    %4lu",
-		       pShbCirBuff->m_ulBlocksApended);
-		TRACE1("\nDataReadable:     %4lu [Bytes]",
-		       pShbCirBuff->m_ulDataReadable);
-		TRACE1("\nBlocksReadable:   %4lu",
-		       pShbCirBuff->m_ulBlocksReadable);
-		TRACE1("\nSigHndlrNewData:  %08lX",
-		       (unsigned long)pShbCirBuff->m_pfnSigHndlrNewData);
-		TRACE1("\nBufferLocked:     %d", pShbCirBuff->m_fBufferLocked);
-		TRACE1("\nSigHndlrReset:    %08lX",
-		       (unsigned long)pShbCirBuff->m_pfnSigHndlrReset);
-
-		ShbTraceDump(&pShbCirBuff->m_Data,
-			     pShbCirBuff->m_ulBufferDataSize, 0x00000000L,
-			     "\nData Area:");
-
-		ulDataReadable = pShbCirBuff->m_ulDataReadable;
-		nBlockCount = 1;
-		ulBlockIndex = pShbCirBuff->m_ulRdIndex;
-
-		while (ulDataReadable > 0) {
-			TRACE1("\n\n--- Block #%u ---", nBlockCount);
-
-			// get pointer to start of data area and current read index
-			pShbCirDataPtr = &pShbCirBuff->m_Data;	// ptr to start of data area
-			ulRdIndex = ulBlockIndex;
-
-			// get real size of current block (incl. alignment fill bytes)
-			ShbCirBlockSize =
-			    *(tShbCirBlockSize *) (pShbCirDataPtr + ulRdIndex);
-			ulRdIndex += sizeof(tShbCirBlockSize);
-			ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
-
-			// get size of user data inside the current block
-			ulDataSize =
-			    ShbCirBlockSize.m_uiFullBlockSize -
-			    ShbCirBlockSize.m_uiAlignFillBytes;
-			ulDataSize -= sizeof(tShbCirBlockSize);
-
-			TRACE1
-			    ("\nFull Data Size:       %4u [Bytes] (incl. header and alignment fill bytes)",
-			     ShbCirBlockSize.m_uiFullBlockSize);
-			TRACE1("\nUser Data Size:       %4lu [Bytes]",
-			       ulDataSize);
-			TRACE1("\nAlignment Fill Bytes: %4u [Bytes]",
-			       ShbCirBlockSize.m_uiAlignFillBytes);
-
-			if (ulRdIndex + ulDataSize <=
-			    pShbCirBuff->m_ulBufferDataSize) {
-				// linear data buffer
-				ShbTraceDump(pShbCirDataPtr + ulRdIndex,
-					     ulDataSize, 0x00000000L, NULL);
-			} else {
-				// wrap-around data buffer
-				ulChunkSize =
-				    pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
-				ShbTraceDump(pShbCirDataPtr + ulRdIndex,
-					     ulChunkSize, 0x00000000L, NULL);
-				ShbTraceDump(pShbCirDataPtr,
-					     ulDataSize - ulChunkSize,
-					     ulChunkSize, NULL);
-			}
-
-			nBlockCount++;
-
-			ulBlockIndex += ShbCirBlockSize.m_uiFullBlockSize;
-			ulBlockIndex %= pShbCirBuff->m_ulBufferDataSize;
-
-			ulDataReadable -= ShbCirBlockSize.m_uiFullBlockSize;
-		}
-
-		ASSERT(pShbCirBuff->m_ulBlocksReadable == nBlockCount - 1);
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-      Exit:
-
-	return (ShbError);
-
-}
-#endif
-
-//-------------------------------------------------------------------------//
-//                                                                         //
-//          L i n e a r   S h a r e d   B u f f e r                        //
-//                                                                         //
-//-------------------------------------------------------------------------//
-
-//---------------------------------------------------------------------------
-//  Allocate Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p,
-			    const char *pszBufferID_p,
-			    tShbInstance * ppShbInstance_p,
-			    unsigned int *pfShbNewCreated_p)
-{
-
-	tShbInstance pShbInstance;
-	tShbLinBuff *pShbLinBuff;
-	unsigned int fShbNewCreated;
-	unsigned long ulBufferDataSize;
-	unsigned long ulBufferTotalSize;
-	tShbError ShbError;
-
-	// check arguments
-	if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-
-	// calculate length of memory to allocate
-	ulBufferDataSize =
-	    (ulBufferSize_p +
-	     (SBL_BLOCK_ALIGNMENT - 1)) & ~(SBL_BLOCK_ALIGNMENT - 1);
-	ulBufferTotalSize = ulBufferDataSize + sizeof(tShbLinBuff);
-
-	// allocate a new or open an existing shared buffer
-	ShbError = ShbIpcAllocBuffer(ulBufferTotalSize, pszBufferID_p,
-				     &pShbInstance, &fShbNewCreated);
-	if (ShbError != kShbOk) {
-		goto Exit;
-	}
-
-	if (pShbInstance == NULL) {
-		ShbError = kShbOutOfMem;
-		goto Exit;
-	}
-
-	// get pointer to shared buffer
-	pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance);
-
-	// if the shared buffer was new created, than this process has
-	// to initialize it, otherwise the buffer is already in use
-	// and *must not* be reseted
-	if (fShbNewCreated) {
-#ifndef NDEBUG
-		{
-			memset(pShbLinBuff, 0xCC, ulBufferTotalSize);
-		}
-#endif
-
-		pShbLinBuff->m_ShbLinMagicID = SBL_MAGIC_ID;
-		pShbLinBuff->m_ulBufferTotalSize = ulBufferTotalSize;
-		pShbLinBuff->m_ulBufferDataSize = ulBufferDataSize;
-	} else {
-		if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
-			ShbError = kShbInvalidBufferType;
-			goto Exit;
-		}
-	}
-
-      Exit:
-
-	*ppShbInstance_p = pShbInstance;
-	*pfShbNewCreated_p = fShbNewCreated;
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Release Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
-	tShbError ShbError;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbOk;
-		goto Exit;
-	}
-
-	ShbError = ShbIpcReleaseBuffer(pShbInstance_p);
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Write data block to Linear Shared Buffer
-//---------------------------------------------------------------------------
-tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
-			       unsigned long ulDstBufferOffs_p,
-			       const void *pSrcDataBlock_p,
-			       unsigned long ulDataBlockSize_p)
-{
-
-	tShbLinBuff *pShbLinBuff;
-	unsigned char *pShbLinDataPtr;
-	unsigned char *pScrDataPtr;
-	unsigned long ulBufferDataSize;
-	tShbError ShbError;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) {
-		// nothing to do here
-		ShbError = kShbOk;
-		goto Exit;
-	}
-
-	if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) {
-		ShbError = kShbExceedDataSizeLimit;
-		goto Exit;
-	}
-
-	pShbLinBuff = ShbLinGetBuffer(pShbInstance_p);
-	pScrDataPtr = (unsigned char *)pSrcDataBlock_p;
-	ShbError = kShbOk;
-
-	if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	// check if offeset and size for the write operation matches with
-	// the size of the shared buffer
-	ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize;
-	if ((ulDstBufferOffs_p > ulBufferDataSize) ||
-	    (ulDataBlockSize_p > ulBufferDataSize) ||
-	    ((ulDstBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) {
-		ShbError = kShbDataOutsideBufferArea;
-		goto Exit;
-	}
-
-	// copy the data to the linear buffer
-	// (the copy process will be done inside of any critical/locked section)
-	pShbLinDataPtr = &pShbLinBuff->m_Data;	// ptr to start of data area
-	pShbLinDataPtr += ulDstBufferOffs_p;
-
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		memcpy(pShbLinDataPtr, pScrDataPtr, ulDataBlockSize_p);
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Read data block from Linear Shared Buffer
-//---------------------------------------------------------------------------
-tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
-			      void *pDstDataBlock_p,
-			      unsigned long ulSrcBufferOffs_p,
-			      unsigned long ulDataBlockSize_p)
-{
-
-	tShbLinBuff *pShbLinBuff;
-	unsigned char *pShbLinDataPtr;
-	unsigned char *pDstDataPtr;
-	unsigned long ulBufferDataSize;
-	tShbError ShbError;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	if ((pDstDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) {
-		// nothing to do here
-		ShbError = kShbOk;
-		goto Exit;
-	}
-
-	if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) {
-		ShbError = kShbExceedDataSizeLimit;
-		goto Exit;
-	}
-
-	pShbLinBuff = ShbLinGetBuffer(pShbInstance_p);
-	pDstDataPtr = (unsigned char *)pDstDataBlock_p;
-	ShbError = kShbOk;
-
-	if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	// check if offeset and size for the read operation matches with
-	// the size of the shared buffer
-	ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize;
-	if ((ulSrcBufferOffs_p > ulBufferDataSize) ||
-	    (ulDataBlockSize_p > ulBufferDataSize) ||
-	    ((ulSrcBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) {
-		ShbError = kShbDataOutsideBufferArea;
-		goto Exit;
-	}
-
-	// copy the data to the linear buffer
-	// (the copy process will be done inside of any critical/locked section)
-	pShbLinDataPtr = &pShbLinBuff->m_Data;	// ptr to start of data area
-	pShbLinDataPtr += ulSrcBufferOffs_p;
-
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		memcpy(pDstDataPtr, pShbLinDataPtr, ulDataBlockSize_p);
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-      Exit:
-
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  DEBUG: Trace Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-#ifndef NDEBUG
-tShbError ShbLinTraceBuffer(tShbInstance pShbInstance_p)
-{
-
-	tShbLinBuff *pShbLinBuff;
-	char szMagigID[sizeof(SBL_MAGIC_ID) + 1];
-	tShbError ShbError;
-
-	TRACE0("\n\n##### Linear Shared Buffer #####\n");
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		TRACE1("\nERROR: invalid buffer address (0x%08lX)\n",
-		       (unsigned long)pShbInstance_p);
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-
-	pShbLinBuff = ShbLinGetBuffer(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) {
-		ShbError = kShbInvalidBufferType;
-		goto Exit;
-	}
-
-	*(unsigned int *)&szMagigID[0] = pShbLinBuff->m_ShbLinMagicID;
-	szMagigID[sizeof(SBL_MAGIC_ID)] = '\0';
-
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		TRACE1("\nBuffer Address:   0x%08lX\n",
-		       (unsigned long)pShbLinBuff);
-
-		TRACE0("\nHeader Info:");
-		TRACE2("\nMagigID:          '%s' (%08X)", szMagigID,
-		       pShbLinBuff->m_ShbLinMagicID);
-		TRACE1("\nBufferTotalSize:  %4lu [Bytes]",
-		       pShbLinBuff->m_ulBufferTotalSize);
-		TRACE1("\nBufferDataSize:   %4lu [Bytes]",
-		       pShbLinBuff->m_ulBufferDataSize);
-
-		ShbTraceDump(&pShbLinBuff->m_Data,
-			     pShbLinBuff->m_ulBufferDataSize, 0x00000000L,
-			     "\nData Area:");
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-      Exit:
-
-	return (ShbError);
-
-}
-#endif
-
-//---------------------------------------------------------------------------
-//  Dump buffer contents
-//---------------------------------------------------------------------------
-
-#ifndef NDEBUG
-tShbError ShbTraceDump(const unsigned char *pabStartAddr_p,
-		       unsigned long ulDataSize_p,
-		       unsigned long ulAddrOffset_p, const char *pszInfoText_p)
-{
-
-	const unsigned char *pabBuffData;
-	unsigned long ulBuffSize;
-	unsigned char bData;
-	int nRow;
-	int nCol;
-
-	// get pointer to buffer and length of buffer
-	pabBuffData = pabStartAddr_p;
-	ulBuffSize = ulDataSize_p;
-
-	if (pszInfoText_p != NULL) {
-		TRACE1("%s", pszInfoText_p);
-	}
-	// dump buffer contents
-	for (nRow = 0;; nRow++) {
-		TRACE1("\n%08lX:   ",
-		       (unsigned long)(nRow * 0x10) + ulAddrOffset_p);
-
-		for (nCol = 0; nCol < 16; nCol++) {
-			if ((unsigned long)nCol < ulBuffSize) {
-				TRACE1("%02X ",
-				       (unsigned int)*(pabBuffData + nCol));
-			} else {
-				TRACE0("   ");
-			}
-		}
-
-		TRACE0(" ");
-
-		for (nCol = 0; nCol < 16; nCol++) {
-			bData = *pabBuffData++;
-			if ((unsigned long)nCol < ulBuffSize) {
-				if ((bData >= 0x20) && (bData < 0x7F)) {
-					TRACE1("%c", bData);
-				} else {
-					TRACE0(".");
-				}
-			} else {
-				TRACE0(" ");
-			}
-		}
-
-		if (ulBuffSize > 16) {
-			ulBuffSize -= 16;
-		} else {
-			break;
-		}
-	}
-
-	return (kShbOk);
-
-}
-#endif // #ifndef NDEBUG
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//  Handler to signal new data event for Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-	unsigned long ulDataSize;
-	unsigned long ulBlockCount;
-	tShbError ShbError;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		return FALSE;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	ShbError = kShbOk;
-
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		return FALSE;
-	}
-
-	// call application handler
-	if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) {
-/*        do
-        {*/
-		ShbError = ShbCirGetReadDataSize(pShbInstance_p, &ulDataSize);
-		if ((ulDataSize > 0) && (ShbError == kShbOk)) {
-			pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p,
-							  ulDataSize);
-		}
-
-		ShbError =
-		    ShbCirGetReadBlockCount(pShbInstance_p, &ulBlockCount);
-/*        }
-        while ((ulBlockCount > 0) && (ShbError == kShbOk));*/
-	}
-	// Return TRUE if there are pending blocks.
-	// In that case ShbIpc tries to call this function again immediately if there
-	// is no other filled shared buffer with higher priority.
-	return ((ulBlockCount > 0) && (ShbError == kShbOk));
-
-}
-
-//---------------------------------------------------------------------------
-//  Handler to reset Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
-			      unsigned int fTimeOut_p)
-{
-
-	tShbCirBuff *pShbCirBuff;
-
-	// check arguments
-	if (pShbInstance_p == NULL) {
-		return;
-	}
-
-	pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
-	if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
-		return;
-	}
-
-	// reset buffer header
-	if (!fTimeOut_p) {
-		ShbIpcEnterAtomicSection(pShbInstance_p);
-		{
-			pShbCirBuff->m_ulWrIndex = 0;
-			pShbCirBuff->m_ulRdIndex = 0;
-			pShbCirBuff->m_ulNumOfWriteJobs = 0;
-			pShbCirBuff->m_ulDataInUse = 0;
-			pShbCirBuff->m_ulDataApended = 0;
-			pShbCirBuff->m_ulBlocksApended = 0;
-			pShbCirBuff->m_ulDataReadable = 0;
-			pShbCirBuff->m_ulBlocksReadable = 0;
-		}
-		ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-#ifndef NDEBUG
-		{
-			memset(&pShbCirBuff->m_Data, 0xCC,
-			       pShbCirBuff->m_ulBufferDataSize);
-		}
-#endif
-	}
-
-	// call application handler
-	if (pShbCirBuff->m_pfnSigHndlrReset != NULL) {
-		pShbCirBuff->m_pfnSigHndlrReset(pShbInstance_p, fTimeOut_p);
-	}
-
-	// unlock buffer
-	ShbIpcEnterAtomicSection(pShbInstance_p);
-	{
-		pShbCirBuff->m_fBufferLocked = FALSE;
-		pShbCirBuff->m_pfnSigHndlrReset = NULL;
-	}
-	ShbIpcLeaveAtomicSection(pShbInstance_p);
-
-	return;
-
-}
-
-// EOF
diff --git a/drivers/staging/epl/SharedBuff.h b/drivers/staging/epl/SharedBuff.h
deleted file mode 100644
index 4edbd0b..0000000
--- a/drivers/staging/epl/SharedBuff.h
+++ /dev/null
@@ -1,187 +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:  Declaration of platform independend part for the
-                shared buffer
-
-  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)
-
-****************************************************************************/
-
-#ifndef _SHAREDBUFF_H_
-#define _SHAREDBUFF_H_
-
-//---------------------------------------------------------------------------
-//  Type definitions
-//---------------------------------------------------------------------------
-
-typedef enum {
-	kShbOk = 0,
-	kShbNoReadableData = 1,
-	kShbDataTruncated = 2,
-	kShbBufferFull = 3,
-	kShbDataOutsideBufferArea = 4,
-	kShbBufferAlreadyCompleted = 5,
-	kShbMemUsedByOtherProcs = 6,
-	kShbOpenMismatch = 7,
-	kShbInvalidBufferType = 8,
-	kShbInvalidArg = 9,
-	kShbBufferInvalid = 10,
-	kShbOutOfMem = 11,
-	kShbAlreadyReseting = 12,
-	kShbAlreadySignaling = 13,
-	kShbExceedDataSizeLimit = 14,
-
-} tShbError;
-
-// 2006/08/24 d.k.: Priority for threads (new data, job signaling)
-typedef enum {
-	kShbPriorityLow = 0,
-	kShbPriorityNormal = 1,
-	kshbPriorityHigh = 2
-} tShbPriority;
-
-typedef struct {
-	unsigned int m_uiFullBlockSize;	// real size of allocated block (incl. alignment fill bytes)
-	unsigned long m_ulAvailableSize;	// still available size for data
-	unsigned long m_ulWrIndex;	// current write index
-	unsigned int m_fBufferCompleted;	// TRUE if allocated block is complete filled with data
-
-} tShbCirChunk;
-
-typedef void *tShbInstance;
-
-typedef void (*tShbCirSigHndlrNewData) (tShbInstance pShbInstance_p,
-					unsigned long ulDataBlockSize_p);
-typedef void (*tShbCirSigHndlrReset) (tShbInstance pShbInstance_p,
-				      unsigned int fTimeOut_p);
-
-//---------------------------------------------------------------------------
-//  Prototypes
-//---------------------------------------------------------------------------
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-	tShbError ShbInit(void);
-	tShbError ShbExit(void);
-
-// Circular Shared Buffer
-	tShbError ShbCirAllocBuffer(unsigned long ulBufferSize_p,
-				    const char *pszBufferID_p,
-				    tShbInstance * ppShbInstance_p,
-				    unsigned int *pfShbNewCreated_p);
-	tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p);
-
-
-	tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
-				    unsigned long ulTimeOut_p,
-				    tShbCirSigHndlrReset
-				    pfnSignalHandlerReset_p);
-	tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
-				       const void *pSrcDataBlock_p,
-				       unsigned long ulDataBlockSize_p);
-	tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
-				       tShbCirChunk * pShbCirChunk_p,
-				       unsigned long ulDataBufferSize_p);
-	tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
-				       tShbCirChunk * pShbCirChunk_p,
-				       const void *pSrcDataChunk_p,
-				       unsigned long ulDataChunkSize_p,
-				       unsigned int *pfBufferCompleted_p);
-	tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
-				      void *pDstDataBlock_p,
-				      unsigned long ulRdBuffSize_p,
-				      unsigned long *pulDataBlockSize_p);
-	tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
-					unsigned long *pulDataBlockSize_p);
-	tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
-					  unsigned long *pulDataBlockCount_p);
-	tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p,
-						tShbCirSigHndlrNewData
-						pfnShbSignalHandlerNewData_p,
-						tShbPriority ShbPriority_p);
-
-
-// Linear Shared Buffer
-	tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p,
-				    const char *pszBufferID_p,
-				    tShbInstance * ppShbInstance_p,
-				    unsigned int *pfShbNewCreated_p);
-	tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p);
-
-
-	tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
-				       unsigned long ulDstBufferOffs_p,
-				       const void *pSrcDataBlock_p,
-				       unsigned long ulDataBlockSize_p);
-	tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
-				      void *pDstDataBlock_p,
-				      unsigned long ulSrcBufferOffs_p,
-				      unsigned long ulDataBlockSize_p);
-
-
-#ifndef NDEBUG
-	tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p);
-	tShbError ShbLinTraceBuffer(tShbInstance pShbInstance_p);
-	tShbError ShbTraceDump(const unsigned char *pabStartAddr_p,
-			       unsigned long ulDataSize_p,
-			       unsigned long ulAddrOffset_p,
-			       const char *pszInfoText_p);
-#else
-#define ShbCirTraceBuffer(p0)
-#define ShbLinTraceBuffer(p0)
-#define ShbTraceDump(p0, p1, p2, p3)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif				// #ifndef _SHAREDBUFF_H_
diff --git a/drivers/staging/epl/ShbIpc-LinuxKernel.c b/drivers/staging/epl/ShbIpc-LinuxKernel.c
deleted file mode 100644
index 12d1ecc..0000000
--- a/drivers/staging/epl/ShbIpc-LinuxKernel.c
+++ /dev/null
@@ -1,944 +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 Linux KernelSpace)
-
-  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/28 -rs:   V 1.00 (initial version)
-
-****************************************************************************/
-
-#include "global.h"
-#include "SharedBuff.h"
-#include "ShbIpc.h"
-#include "ShbLinuxKernel.h"
-#include "Debug.h"
-
-#include <linux/string.h>
-#include <linux/module.h>
-#include <asm/processor.h>
-//#include <linux/vmalloc.h>
-#include <linux/sched.h>
-#include <linux/param.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/completion.h>
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-//  Configuration
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Constant definitions
-//---------------------------------------------------------------------------
-
-#define MAX_LEN_BUFFER_ID       256
-
-#define TIMEOUT_ENTER_ATOMIC    1000	// (ms) for debgging: INFINITE
-#define TIMEOUT_TERM_THREAD     1000
-#define INFINITE                3600
-
-#define SBI_MAGIC_ID            0x5342492B	// magic ID ("SBI+")
-#define SBH_MAGIC_ID            0x5342482A	// magic ID ("SBH*")
-
-#define INVALID_ID              -1
-
-#define TABLE_SIZE              10
-
-//---------------------------------------------------------------------------
-//  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_ulShMemSize;
-	unsigned long m_ulRefCount;
-	int m_iBufferId;
-//    int                 m_iUserSpaceMem;           //0 for userspace mem   !=0 kernelspace mem
-	spinlock_t m_SpinlockBuffAccess;
-	BOOL m_fNewData;
-	BOOL m_fJobReady;
-	wait_queue_head_t m_WaitQueueNewData;
-	wait_queue_head_t m_WaitQueueJobReady;
-
-#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+")
-//    void*               m_pSharedMem;
-	int m_tThreadNewDataId;
-	long m_lThreadNewDataNice;	// nice value of the new data thread
-	int m_tThreadJobReadyId;
-	unsigned long m_ulFlagsBuffAccess;	// d.k. moved from tShbMemHeader, because each
-	// process needs to store the interrupt flags separately
-	tSigHndlrNewData m_pfnSigHndlrNewData;
-	unsigned long m_ulTimeOutJobReady;
-	tSigHndlrJobReady m_pfnSigHndlrJobReady;
-	tShbMemHeader *m_pShbMemHeader;
-	int m_iThreadTermFlag;
-	struct completion m_CompletionNewData;
-/*
-    struct semaphore    *m_pSemBuffAccess;
-    struct semaphore    *m_pSemNewData;
-    struct semaphore    *m_pSemStopSignalingNewData;
-    struct semaphore    *m_pSemJobReady;
-*/
-#ifndef NDEBUG
-	unsigned long m_ulThreadIDNewData;
-	unsigned long m_ulThreadIDJobReady;
-#endif
-} tShbMemInst;
-
-//---------------------------------------------------------------------------
-//  Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-//tShbMemInst*            ShbIpcGetShbMemInst         (tShbInstance pShbInstance_p);
-//tShbMemHeader*          ShbIpcGetShbMemHeader       (tShbMemInst* pShbMemInst_p);
-
-//---------------------------------------------------------------------------
-//  Get pointer to process local information structure
-//---------------------------------------------------------------------------
-
-static inline tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-
-	pShbMemInst = (tShbMemInst *) pShbInstance_p;
-
-	return (pShbMemInst);
-
-}
-
-//---------------------------------------------------------------------------
-//  Get pointer to shared memory header
-//---------------------------------------------------------------------------
-
-static inline tShbMemHeader *ShbIpcGetShbMemHeader(tShbMemInst * pShbMemInst_p)
-{
-
-	tShbMemHeader *pShbMemHeader;
-
-	pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
-
-	return (pShbMemHeader);
-
-}
-
-//  Get pointer to process local information structure
-//#define ShbIpcGetShbMemInst(pShbInstance_p) ((tShbMemInst*)pShbInstance_p)
-
-//  Get pointer to shared memory header
-//#define ShbIpcGetShbMemHeader(pShbMemInst_p) (pShbMemInst_p->m_pShbMemHeader)
-
-// not inlined internal functions
-int ShbIpcThreadSignalNewData(void *pvThreadParam_p);
-int ShbIpcThreadSignalJobReady(void *pvThreadParam_p);
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-struct sShbMemTable *psMemTableElementFirst_g;
-
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
-static int ShbIpcFindListElement(int iBufferId,
-				 struct sShbMemTable
-				 **ppsReturnMemTableElement);
-static void ShbIpcAppendListElement(struct sShbMemTable *sNewMemTableElement);
-static void ShbIpcDeleteListElement(int iBufferId);
-static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256]);
-static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
-				       unsigned long aulCrcTable[256]);
-
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-// not inlined external functions
-
-//---------------------------------------------------------------------------
-//  Initialize IPC for Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcInit(void)
-{
-	psMemTableElementFirst_g = NULL;
-	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)
-{
-	tShbError ShbError;
-	int iBufferId = 0;
-	unsigned long ulCrc32 = 0;
-	unsigned int uiFirstProcess = 0;
-	unsigned long ulShMemSize;
-	tShbMemHeader *pShbMemHeader;
-	tShbMemInst *pShbMemInst = NULL;
-	tShbInstance pShbInstance;
-	unsigned int fShMemNewCreated = FALSE;
-	void *pSharedMem = NULL;
-	unsigned long aulCrcTable[256];
-	struct sShbMemTable *psMemTableElement;
-
-	DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer \n");
-	ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader);
-
-	//create Buffer ID
-	ShbIpcCrc32GenTable(aulCrcTable);
-	ulCrc32 = ShbIpcCrc32GetCrc(pszBufferID_p, aulCrcTable);
-	iBufferId = ulCrc32;
-	DEBUG_LVL_29_TRACE2
-	    ("ShbIpcAllocBuffer BufferSize:%d sizeof(tShb..):%d\n",
-	     ulBufferSize_p, sizeof(tShbMemHeader));
-	DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferId:%d MemSize:%d\n",
-			    iBufferId, ulShMemSize);
-	//---------------------------------------------------------------
-	// (1) open an existing or create a new shared memory
-	//---------------------------------------------------------------
-	//test if buffer already exists
-	if (ShbIpcFindListElement(iBufferId, &psMemTableElement) == 0) {
-		//Buffer already exists
-		fShMemNewCreated = FALSE;
-		pSharedMem = psMemTableElement->m_pBuffer;
-		DEBUG_LVL_29_TRACE1
-		    ("ShbIpcAllocBuffer attach Buffer at:%p Id:%d\n",
-		     pSharedMem);
-		uiFirstProcess = 1;
-	} else {
-		//create new Buffer
-		fShMemNewCreated = TRUE;
-		uiFirstProcess = 0;
-		pSharedMem = kmalloc(ulShMemSize, GFP_KERNEL);
-		DEBUG_LVL_29_TRACE2
-		    ("ShbIpcAllocBuffer Create New Buffer at:%p Id:%d\n",
-		     pSharedMem, iBufferId);
-		if (pSharedMem == NULL) {
-			//unable to create mem
-			ShbError = kShbOutOfMem;
-			goto Exit;
-		}
-		DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer create semas\n");
-		// append Element to Mem Table
-		psMemTableElement =
-		    kmalloc(sizeof(struct sShbMemTable), GFP_KERNEL);
-		psMemTableElement->m_iBufferId = iBufferId;
-		psMemTableElement->m_pBuffer = pSharedMem;
-		psMemTableElement->m_psNextMemTableElement = NULL;
-		ShbIpcAppendListElement(psMemTableElement);
-	}
-
-	DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer update header\n");
-	//update header
-	pShbMemHeader = (tShbMemHeader *) pSharedMem;
-	DEBUG_LVL_29_TRACE1
-	    ("ShbIpcAllocBuffer 0 pShbMemHeader->m_ulShMemSize: %d\n",
-	     pShbMemHeader->m_ulShMemSize);
-	// allocate a memory block from process specific mempool to save
-	// process local information to administrate/manage the shared buffer
-	DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer alloc private mem\n");
-	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_pSharedMem                               = pSharedMem;
-	pShbMemInst->m_tThreadNewDataId = INVALID_ID;
-	pShbMemInst->m_tThreadJobReadyId = INVALID_ID;
-	pShbMemInst->m_pfnSigHndlrNewData = NULL;
-	pShbMemInst->m_ulTimeOutJobReady = 0;
-	pShbMemInst->m_pfnSigHndlrJobReady = NULL;
-	pShbMemInst->m_pShbMemHeader = pShbMemHeader;
-	pShbMemInst->m_iThreadTermFlag = 0;
-
-	// initialize completion etc.
-	init_completion(&pShbMemInst->m_CompletionNewData);
-
-	ShbError = kShbOk;
-	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_ulShMemSize = ulShMemSize;
-		pShbMemHeader->m_ulRefCount = 1;
-		pShbMemHeader->m_iBufferId = iBufferId;
-		// initialize spinlock
-		spin_lock_init(&pShbMemHeader->m_SpinlockBuffAccess);
-		// initialize wait queues
-		init_waitqueue_head(&pShbMemHeader->m_WaitQueueNewData);
-		init_waitqueue_head(&pShbMemHeader->m_WaitQueueJobReady);
-	} else {
-		// any other process has created the shared memory and this
-		// process only has to attach to it
-		// -> check and update existing header information inside the
-		//    shared memory region itself
-		if (pShbMemHeader->m_ulShMemSize != ulShMemSize) {
-			ShbError = kShbOpenMismatch;
-			goto Exit;
-		}
-		pShbMemHeader->m_ulRefCount++;
-	}
-
-      Exit:
-	pShbInstance = (tShbInstance *) pShbMemInst;
-	*pfShbNewCreated_p = fShMemNewCreated;
-	*ppShbInstance_p = pShbInstance;
-	return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-//  Release Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
-{
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	tShbError ShbError;
-	tShbError ShbError2;
-
-	DEBUG_LVL_26_TRACE1("ShbIpcReleaseBuffer(%p)\n", pShbInstance_p);
-	if (pShbInstance_p == NULL) {
-		return (kShbOk);
-	}
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-
-	// stop threads in any case, because they are bound to that specific instance
-	ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p);
-	// d.k.: Whats up with JobReady thread?
-	//       Just wake it up, but without setting the semaphore variable
-	wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
-
-	if (!--pShbMemHeader->m_ulRefCount) {
-		ShbError = kShbOk;
-		// delete mem table element
-		ShbIpcDeleteListElement(pShbMemHeader->m_iBufferId);
-		// delete shared mem
-		kfree(pShbMemInst->m_pShbMemHeader);
-	} else {
-		ShbError = kShbMemUsedByOtherProcs;
-	}
-	//delete privat mem
-	kfree(pShbMemInst);
-	return (ShbError);
-}
-
-//---------------------------------------------------------------------------
-//  Enter atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	tShbError ShbError = kShbOk;
-
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-	DEBUG_LVL_29_TRACE0("enter atomic\n");
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-
-	// lock interrupts
-	spin_lock_irqsave(&pShbMemHeader->m_SpinlockBuffAccess,
-			  pShbMemInst->m_ulFlagsBuffAccess);
-
-      Exit:
-	return ShbError;
-
-}
-
-//---------------------------------------------------------------------------
-//  Leave atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
-{
-
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	tShbError ShbError = kShbOk;
-
-	if (pShbInstance_p == NULL) {
-		ShbError = kShbInvalidArg;
-		goto Exit;
-	}
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-	// unlock interrupts
-	spin_unlock_irqrestore(&pShbMemHeader->m_SpinlockBuffAccess,
-			       pShbMemInst->m_ulFlagsBuffAccess);
-
-      Exit:
-	DEBUG_LVL_29_TRACE0("Leave Atomic \n");
-	return ShbError;
-
-}
-
-//---------------------------------------------------------------------------
-//  Start signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p,
-				      tSigHndlrNewData pfnSignalHandlerNewData_p,
-				      tShbPriority ShbPriority_p)
-{
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	tShbError ShbError;
-
-	DEBUG_LVL_29_TRACE0("------->ShbIpcStartSignalingNewData\n");
-	if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-	ShbError = kShbOk;
-
-	if ((pShbMemInst->m_tThreadNewDataId != INVALID_ID)
-	    || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) {
-		ShbError = kShbAlreadySignaling;
-		goto Exit;
-	}
-	DEBUG_LVL_26_TRACE2
-	    ("ShbIpcStartSignalingNewData(%p) m_pfnSigHndlrNewData = %p\n",
-	     pShbInstance_p, pfnSignalHandlerNewData_p);
-	pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
-	pShbMemHeader->m_fNewData = FALSE;
-	pShbMemInst->m_iThreadTermFlag = 0;
-
-	switch (ShbPriority_p) {
-	case kShbPriorityLow:
-		pShbMemInst->m_lThreadNewDataNice = -2;
-		break;
-
-	case kShbPriorityNormal:
-		pShbMemInst->m_lThreadNewDataNice = -9;
-		break;
-
-	case kshbPriorityHigh:
-		pShbMemInst->m_lThreadNewDataNice = -20;
-		break;
-
-	}
-
-	//create thread for signalling new data
-	pShbMemInst->m_tThreadNewDataId =
-		kernel_thread(ShbIpcThreadSignalNewData, pShbInstance_p,
-				CLONE_FS | CLONE_FILES);
-
-      Exit:
-	return ShbError;
-
-}
-
-//---------------------------------------------------------------------------
-//  Stop signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p)
-{
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	tShbError ShbError;
-
-	DEBUG_LVL_29_TRACE0("------->ShbIpcStopSignalingNewData\n");
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-	ShbError = kShbOk;
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-
-	DEBUG_LVL_26_TRACE2
-	    ("ShbIpcStopSignalingNewData(%p) pfnSignHndlrNewData=%p\n",
-	     pShbInstance_p, pShbMemInst->m_pfnSigHndlrNewData);
-	if (pShbMemInst->m_pfnSigHndlrNewData != NULL) {	// signal handler was set before
-		int iErr;
-		//set termination flag in mem header
-		pShbMemInst->m_iThreadTermFlag = 1;
-
-		// check if thread is still running at all by sending the null-signal to this thread
-		/* iErr = kill_proc(pShbMemInst->m_tThreadNewDataId, 0, 1); */
-		iErr = send_sig(0, pShbMemInst->m_tThreadNewDataId, 1);
-		if (iErr == 0) {
-			// wake up thread, because it is still running
-			wake_up_interruptible(&pShbMemHeader->
-					      m_WaitQueueNewData);
-
-			//wait for termination of thread
-			wait_for_completion(&pShbMemInst->m_CompletionNewData);
-		}
-
-		pShbMemInst->m_pfnSigHndlrNewData = NULL;
-		pShbMemInst->m_tThreadNewDataId = INVALID_ID;
-	}
-
-	return ShbError;
-
-}
-
-//---------------------------------------------------------------------------
-//  Signal new data (called from writing process)
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
-{
-	tShbMemHeader *pShbMemHeader;
-
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-	pShbMemHeader =
-	    ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
-	//set semaphore
-	pShbMemHeader->m_fNewData = TRUE;
-	DEBUG_LVL_29_TRACE0("ShbIpcSignalNewData set Sem -> New Data\n");
-
-	wake_up_interruptible(&pShbMemHeader->m_WaitQueueNewData);
-	return (kShbOk);
-}
-
-//---------------------------------------------------------------------------
-//  Start signaling for job ready (called from waiting process)
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
-				       unsigned long ulTimeOut_p,
-				       tSigHndlrJobReady pfnSignalHandlerJobReady_p)
-{
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	tShbError ShbError;
-
-	if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) {
-		return (kShbInvalidArg);
-	}
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-
-	ShbError = kShbOk;
-	if ((pShbMemInst->m_tThreadJobReadyId != INVALID_ID)
-	    || (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) {
-		ShbError = kShbAlreadySignaling;
-		goto Exit;
-	}
-	pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p;
-	pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
-	pShbMemHeader->m_fJobReady = FALSE;
-	//create thread for signalling new data
-	pShbMemInst->m_tThreadJobReadyId =
-		kernel_thread(ShbIpcThreadSignalJobReady, pShbInstance_p,
-				CLONE_FS | CLONE_FILES);
-      Exit:
-	return ShbError;
-}
-
-//---------------------------------------------------------------------------
-//  Signal job ready (called from executing process)
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
-{
-	tShbMemHeader *pShbMemHeader;
-
-	DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady\n");
-	if (pShbInstance_p == NULL) {
-		return (kShbInvalidArg);
-	}
-	pShbMemHeader =
-	    ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
-	//set semaphore
-	pShbMemHeader->m_fJobReady = TRUE;
-	DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady set Sem -> Job Ready \n");
-
-	wake_up_interruptible(&pShbMemHeader->m_WaitQueueJobReady);
-	return (kShbOk);
-}
-
-//---------------------------------------------------------------------------
-//  Get pointer to common used share memory area
-//---------------------------------------------------------------------------
-
-void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
-{
-
-	tShbMemHeader *pShbMemHeader;
-	void *pShbShMemPtr;
-
-	pShbMemHeader =
-	    ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
-	if (pShbMemHeader != NULL) {
-		pShbShMemPtr = (u8 *) pShbMemHeader + sizeof(tShbMemHeader);
-	} else {
-		pShbShMemPtr = NULL;
-	}
-
-	return (pShbShMemPtr);
-
-}
-
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//  Get pointer to process local information structure
-//---------------------------------------------------------------------------
-
-/*tShbMemInst*  ShbIpcGetShbMemInst (
-    tShbInstance pShbInstance_p)
-{
-
-tShbMemInst*  pShbMemInst;
-
-    pShbMemInst = (tShbMemInst*)pShbInstance_p;
-
-    return (pShbMemInst);
-
-}
-*/
-
-//---------------------------------------------------------------------------
-//  Get pointer to shared memory header
-//---------------------------------------------------------------------------
-
-/*tShbMemHeader*  ShbIpcGetShbMemHeader (
-    tShbMemInst* pShbMemInst_p)
-{
-
-tShbMemHeader*  pShbMemHeader;
-
-    pShbMemHeader = pShbMemInst_p->m_pShbMemHeader;
-
-    return (pShbMemHeader);
-
-}
-*/
-
-//---------------------------------------------------------------------------
-//  Allocate a memory block from process specific mempool
-//---------------------------------------------------------------------------
-
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p)
-{
-	tShbError ShbError;
-	void *pMem;
-
-	DEBUG_LVL_29_TRACE0("ShbIpcAllocPrivateMem \n");
-	//get private mem
-	pMem = kmalloc(ulMemSize_p, GFP_KERNEL);
-	if (pMem == NULL) {
-		//unable to create mem
-		ShbError = kShbOutOfMem;
-		goto Exit;
-	}
-      Exit:
-	return (pMem);
-
-}
-
-//---------------------------------------------------------------------------
-//  Thread for new data signaling
-//---------------------------------------------------------------------------
-
-int ShbIpcThreadSignalNewData(void *pvThreadParam_p)
-{
-	tShbInstance pShbInstance;
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	int iRetVal = -1;
-	int fCallAgain;
-
-	daemonize("ShbND%p", pvThreadParam_p);
-	allow_signal(SIGTERM);
-	pShbInstance = (tShbMemInst *) pvThreadParam_p;
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-
-	DEBUG_LVL_26_TRACE1("ShbIpcThreadSignalNewData(%p)\n", pvThreadParam_p);
-
-	set_user_nice(current, pShbMemInst->m_lThreadNewDataNice);
-
-//            DEBUG_LVL_29_TRACE1("ShbIpcThreadSignalNewData wait for New Data Sem %p\n",pShbMemInst->m_pSemNewData);
-	do {
-		iRetVal =
-		    wait_event_interruptible(pShbMemHeader->m_WaitQueueNewData,
-					     (pShbMemInst->m_iThreadTermFlag !=
-					      0)
-					     || (pShbMemHeader->m_fNewData !=
-						 FALSE));
-
-		if (iRetVal != 0) {	// signal pending
-			break;
-		}
-
-		if (pShbMemHeader->m_fNewData != FALSE) {
-			pShbMemHeader->m_fNewData = FALSE;
-			do {
-				fCallAgain =
-				    pShbMemInst->
-				    m_pfnSigHndlrNewData(pShbInstance);
-				// call scheduler, which will execute any task with higher priority
-				schedule();
-			} while (fCallAgain != FALSE);
-		}
-	} while (pShbMemInst->m_iThreadTermFlag == 0);
-	DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalNewData terminated \n");
-	//set thread completed
-	complete_and_exit(&pShbMemInst->m_CompletionNewData, 0);
-	return 0;
-}
-
-//---------------------------------------------------------------------------
-//  Thread for new data Job Ready signaling
-//---------------------------------------------------------------------------
-
-int ShbIpcThreadSignalJobReady(void *pvThreadParam_p)
-{
-	tShbInstance pShbInstance;
-	tShbMemInst *pShbMemInst;
-	tShbMemHeader *pShbMemHeader;
-	long lTimeOut;
-	int iRetVal = -1;
-
-	daemonize("ShbJR%p", pvThreadParam_p);
-	allow_signal(SIGTERM);
-	pShbInstance = (tShbMemInst *) pvThreadParam_p;
-	pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
-	pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
-
-	DEBUG_LVL_29_TRACE0
-	    ("ShbIpcThreadSignalJobReady wait for job ready Sem\n");
-	if (pShbMemInst->m_ulTimeOutJobReady != 0) {
-		lTimeOut = (long)pShbMemInst->m_ulTimeOutJobReady;
-		//wait for job ready semaphore
-		iRetVal =
-		    wait_event_interruptible_timeout(pShbMemHeader->
-						     m_WaitQueueJobReady,
-						     (pShbMemHeader->
-						      m_fJobReady != FALSE),
-						     lTimeOut);
-	} else {
-		//wait for job ready semaphore
-		iRetVal =
-		    wait_event_interruptible(pShbMemHeader->m_WaitQueueJobReady,
-					     (pShbMemHeader->m_fJobReady !=
-					      FALSE));
-	}
-
-	if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) {
-		//call Handler
-		pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance,
-						   !pShbMemHeader->m_fJobReady);
-	}
-
-	pShbMemInst->m_pfnSigHndlrJobReady = NULL;
-	return 0;
-}
-
-//Build the crc table
-static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256])
-{
-	unsigned long ulCrc, ulPoly;
-	int iIndexI, iIndexJ;
-
-	ulPoly = 0xEDB88320L;
-	for (iIndexI = 0; iIndexI < 256; iIndexI++) {
-		ulCrc = iIndexI;
-		for (iIndexJ = 8; iIndexJ > 0; iIndexJ--) {
-			if (ulCrc & 1) {
-				ulCrc = (ulCrc >> 1) ^ ulPoly;
-			} else {
-				ulCrc >>= 1;
-			}
-		}
-		aulCrcTable[iIndexI] = ulCrc;
-	}
-}
-
-//Calculate the crc value
-static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
-				       unsigned long aulCrcTable[256])
-{
-	unsigned long ulCrc;
-	int iIndex;
-
-	ulCrc = 0xFFFFFFFF;
-	for (iIndex = 0; iIndex < strlen(pcString); iIndex++) {
-		ulCrc =
-		    ((ulCrc >> 8) & 0x00FFFFFF) ^
-		    aulCrcTable[(ulCrc ^ pcString[iIndex]) & 0xFF];
-	}
-	return (ulCrc ^ 0xFFFFFFFF);
-
-}
-
-static void ShbIpcAppendListElement(struct sShbMemTable *psNewMemTableElement)
-{
-	struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
-	psNewMemTableElement->m_psNextMemTableElement = NULL;
-
-	if (psMemTableElementFirst_g != NULL) {	/* sind Elemente vorhanden */
-		while (psMemTableElement->m_psNextMemTableElement != NULL) {	/* suche das letzte Element */
-			psMemTableElement =
-			    psMemTableElement->m_psNextMemTableElement;
-		}
-		psMemTableElement->m_psNextMemTableElement = psNewMemTableElement;	/*  Haenge das Element hinten an */
-	} else {		/* wenn die liste leer ist, bin ich das erste Element */
-		psMemTableElementFirst_g = psNewMemTableElement;
-	}
-}
-
-static int ShbIpcFindListElement(int iBufferId,
-				 struct sShbMemTable **ppsReturnMemTableElement)
-{
-	struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
-	while (psMemTableElement != NULL) {
-		if (psMemTableElement->m_iBufferId == iBufferId) {
-//printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",psMemTableElement->m_pBuffer,psMemTableElement->m_iBufferId);
-			*ppsReturnMemTableElement = psMemTableElement;
-//printk("ShbIpcFindListElement Buffer at:%p Id:%d\n",(*ppsReturnMemTableElement)->m_pBuffer,(*ppsReturnMemTableElement)->m_iBufferId);
-			return 0;
-		}
-		psMemTableElement = psMemTableElement->m_psNextMemTableElement;
-	}
-	return -1;
-}
-
-static void ShbIpcDeleteListElement(int iBufferId)
-{
-	struct sShbMemTable *psMemTableElement = psMemTableElementFirst_g;
-	struct sShbMemTable *psMemTableElementOld = psMemTableElementFirst_g;
-	if (psMemTableElement != NULL) {
-		while ((psMemTableElement != NULL)
-		       && (psMemTableElement->m_iBufferId != iBufferId)) {
-			psMemTableElementOld = psMemTableElement;
-			psMemTableElement =
-			    psMemTableElement->m_psNextMemTableElement;
-		}
-		if (psMemTableElement != NULL) {
-			if (psMemTableElement != psMemTableElementFirst_g) {
-				psMemTableElementOld->m_psNextMemTableElement =
-				    psMemTableElement->m_psNextMemTableElement;
-				kfree(psMemTableElement);
-			} else {
-				kfree(psMemTableElement);
-				psMemTableElementFirst_g = NULL;
-			}
-
-		}
-	}
-
-}
-
diff --git a/drivers/staging/epl/ShbIpc.h b/drivers/staging/epl/ShbIpc.h
deleted file mode 100644
index 285f096..0000000
--- a/drivers/staging/epl/ShbIpc.h
+++ /dev/null
@@ -1,99 +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:  Declaration of platform specific part for the
-                shared buffer
-
-  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)
-
-****************************************************************************/
-
-#ifndef _SHBIPC_H_
-#define _SHBIPC_H_
-
-//---------------------------------------------------------------------------
-//  Type definitions
-//---------------------------------------------------------------------------
-
-typedef int (*tSigHndlrNewData) (tShbInstance pShbInstance_p);
-typedef void (*tSigHndlrJobReady) (tShbInstance pShbInstance_p,
-				   unsigned int fTimeOut_p);
-
-//---------------------------------------------------------------------------
-//  Prototypes
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcInit(void);
-tShbError ShbIpcExit(void);
-
-tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
-			    const char *pszBufferID_p,
-			    tShbInstance * ppShbInstance_p,
-			    unsigned int *pfShbNewCreated_p);
-tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p);
-
-tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p);
-tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p);
-
-tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p,
-				      tSigHndlrNewData
-				      pfnSignalHandlerNewData_p,
-				      tShbPriority ShbPriority_p);
-tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p);
-tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p);
-
-tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
-				       unsigned long ulTimeOut_p,
-				       tSigHndlrJobReady
-				       pfnSignalHandlerJobReady_p);
-tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p);
-
-void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p);
-
-#endif // #ifndef _SHBIPC_H_
diff --git a/drivers/staging/epl/ShbLinuxKernel.h b/drivers/staging/epl/ShbLinuxKernel.h
deleted file mode 100644
index 812702a..0000000
--- a/drivers/staging/epl/ShbLinuxKernel.h
+++ /dev/null
@@ -1,68 +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:  Declaration of platform specific part for the
-                shared buffer
-
-  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/07/20 -rs:   V 1.00 (initial version)
-
-****************************************************************************/
-
-#ifndef _SHBLINUXKERNEL_H_
-#define _SHBLINUXKERNEL_H_
-
-struct sShbMemTable {
-	int m_iBufferId;
-	void *m_pBuffer;
-	struct sShbMemTable *m_psNextMemTableElement;
-};
-
-extern struct sShbMemTable *psMemTableElementFirst_g;
-
-#endif // _SHBLINUXKERNEL_H_
diff --git a/drivers/staging/epl/SocketLinuxKernel.c b/drivers/staging/epl/SocketLinuxKernel.c
deleted file mode 100644
index 562bc4a..0000000
--- a/drivers/staging/epl/SocketLinuxKernel.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  Wrapper for BSD socket API for Linux kernel
-
-  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: SocketLinuxKernel.c,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:
-
-  2006/08/25 d.k.:   start of implementation
-
-****************************************************************************/
-
-#include <linux/net.h>
-#include <linux/in.h>
-#include "SocketLinuxKernel.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
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-//  Kernel Module specific Data Structures
-//---------------------------------------------------------------------------
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-SOCKET socket(int af, int type, int protocol)
-{
-	int rc;
-	SOCKET socket;
-
-	rc = sock_create_kern(af, type, protocol, &socket);
-	if (rc < 0) {
-		socket = NULL;
-		goto Exit;
-	}
-
-      Exit:
-	return socket;
-}
-
-int bind(SOCKET socket_p, const struct sockaddr *addr, int addrlen)
-{
-	int rc;
-
-	rc = socket_p->ops->bind(socket_p, (struct sockaddr *)addr, addrlen);
-
-	return rc;
-}
-
-int closesocket(SOCKET socket_p)
-{
-	sock_release(socket_p);
-
-	return 0;
-}
-
-int recvfrom(SOCKET socket_p, char *buf, int len, int flags,
-	     struct sockaddr *from, int *fromlen)
-{
-	int rc;
-	struct msghdr msg;
-	struct kvec iov;
-
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_name = from;	// will be struct sock_addr
-	msg.msg_namelen = *fromlen;
-	iov.iov_len = len;
-	iov.iov_base = buf;
-
-	rc = kernel_recvmsg(socket_p, &msg, &iov, 1, iov.iov_len, 0);
-
-	return rc;
-}
-
-int sendto(SOCKET socket_p, const char *buf, int len, int flags,
-	   const struct sockaddr *to, int tolen)
-{
-	int rc;
-	struct msghdr msg;
-	struct kvec iov;
-
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_name = (struct sockaddr *)to;	// will be struct sock_addr
-	msg.msg_namelen = tolen;
-	msg.msg_flags = 0;
-	iov.iov_len = len;
-	iov.iov_base = (char *)buf;
-
-	rc = kernel_sendmsg(socket_p, &msg, &iov, 1, len);
-
-	return rc;
-}
-
-// EOF
diff --git a/drivers/staging/epl/SocketLinuxKernel.h b/drivers/staging/epl/SocketLinuxKernel.h
deleted file mode 100644
index 6e1d619..0000000
--- a/drivers/staging/epl/SocketLinuxKernel.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for BSD socket API for Linux kernel
-
-  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: SocketLinuxKernel.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/08/25 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _SOCKETLINUXKERNEL_H_
-#define _SOCKETLINUXKERNEL_H_
-
-#include <linux/net.h>
-#include <linux/in.h>
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define INVALID_SOCKET  0
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef struct socket *SOCKET;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-int bind(SOCKET s, const struct sockaddr *addr, int addrlen);
-
-int closesocket(SOCKET s);
-
-int recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from,
-	     int *fromlen);
-
-int sendto(SOCKET s, const char *buf, int len, int flags,
-	   const struct sockaddr *to, int tolen);
-
-SOCKET socket(int af, int type, int protocol);
-
-#endif // #ifndef _SOCKETLINUXKERNEL_H_
diff --git a/drivers/staging/epl/TimerHighReskX86.c b/drivers/staging/epl/TimerHighReskX86.c
deleted file mode 100644
index d6897de..0000000
--- a/drivers/staging/epl/TimerHighReskX86.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  target specific implementation of
-                high resolution timer module for X86 under Linux
-                The Linux kernel has to be compiled with high resolution
-                timers enabled. This is done by configuring the kernel
-                with CONFIG_HIGH_RES_TIMERS enabled.
-
-  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: TimerHighReskX86.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/04/17 21:38:01 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GNU
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-****************************************************************************/
-
-#include "EplInc.h"
-#include "kernel/EplTimerHighResk.h"
-#include "Benchmark.h"
-
-//#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/hrtimer.h>
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#define TIMER_COUNT           2	/* max 15 timers selectable */
-#define TIMER_MIN_VAL_SINGLE  5000	/* min 5us */
-#define TIMER_MIN_VAL_CYCLE   100000	/* min 100us */
-
-#define PROVE_OVERRUN
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-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
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#define TGT_DBG_POST_TRACE_VALUE(v)
-#endif
-#define HRT_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
-    TGT_DBG_POST_TRACE_VALUE((0xE << 28) | (Event_p << 24) \
-                             | (uiNodeId_p << 16) | wErrorCode_p)
-
-#define TIMERHDL_MASK         0x0FFFFFFF
-#define TIMERHDL_SHIFT        28
-#define HDL_TO_IDX(Hdl)       ((Hdl >> TIMERHDL_SHIFT) - 1)
-#define HDL_INIT(Idx)         ((Idx + 1) << TIMERHDL_SHIFT)
-#define HDL_INC(Hdl)          (((Hdl + 1) & TIMERHDL_MASK) \
-                               | (Hdl & ~TIMERHDL_MASK))
-
-//---------------------------------------------------------------------------
-// modul global types
-//---------------------------------------------------------------------------
-
-typedef struct {
-	tEplTimerEventArg m_EventArg;
-	tEplTimerkCallback m_pfnCallback;
-	struct hrtimer m_Timer;
-	BOOL m_fContinuously;
-	unsigned long long m_ullPeriod;
-
-} tEplTimerHighReskTimerInfo;
-
-typedef struct {
-	tEplTimerHighReskTimerInfo m_aTimerInfo[TIMER_COUNT];
-
-} tEplTimerHighReskInstance;
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-static tEplTimerHighReskInstance EplTimerHighReskInstance_l;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimerHighReskInit()
-//
-// Description: initializes the high resolution timer module.
-//
-// Parameters:  void
-//
-// Return:      tEplKernel      = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskInit(void)
-{
-	tEplKernel Ret;
-
-	Ret = EplTimerHighReskAddInstance();
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimerHighReskAddInstance()
-//
-// Description: initializes the high resolution timer module.
-//
-// Parameters:  void
-//
-// Return:      tEplKernel      = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskAddInstance(void)
-{
-	tEplKernel Ret;
-	unsigned int uiIndex;
-
-	Ret = kEplSuccessful;
-
-	EPL_MEMSET(&EplTimerHighReskInstance_l, 0,
-		   sizeof(EplTimerHighReskInstance_l));
-
-	/*
-	 * Initialize hrtimer structures for all usable timers.
-	 */
-	for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++) {
-		tEplTimerHighReskTimerInfo *pTimerInfo;
-		struct hrtimer *pTimer;
-
-		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
-		pTimer = &pTimerInfo->m_Timer;
-		hrtimer_init(pTimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
-
-		pTimer->function = EplTimerHighReskCallback;
-	}
-
-	return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimerHighReskDelInstance()
-//
-// Description: shuts down the high resolution timer module.
-//
-// Parameters:  void
-//
-// Return:      tEplKernel      = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskDelInstance(void)
-{
-	tEplTimerHighReskTimerInfo *pTimerInfo;
-	tEplKernel Ret;
-	unsigned int uiIndex;
-
-	Ret = kEplSuccessful;
-
-	for (uiIndex = 0; uiIndex < TIMER_COUNT; uiIndex++) {
-		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
-		pTimerInfo->m_pfnCallback = NULL;
-		pTimerInfo->m_EventArg.m_TimerHdl = 0;
-		/*
-		 * In this case we can not just try to cancel the timer.
-		 * We actually have to wait until its callback function
-		 * has returned.
-		 */
-		hrtimer_cancel(&pTimerInfo->m_Timer);
-	}
-
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimerHighReskModifyTimerNs()
-//
-// Description: modifies the timeout of the timer with the specified handle.
-//              If the handle the pointer points to is zero, the timer must
-//              be created first.
-//              If it is not possible to stop the old timer,
-//              this function always assures that the old timer does not
-//              trigger the callback function with the same handle as the new
-//              timer. That means the callback function must check the passed
-//              handle with the one returned by this function. If these are
-//              unequal, the call can be discarded.
-//
-// Parameters:  pTimerHdl_p     = pointer to timer handle
-//              ullTimeNs_p     = relative timeout in [ns]
-//              pfnCallback_p   = callback function, which is called mutual
-//                                exclusive with the Edrv callback functions
-//                                (Rx and Tx).
-//              ulArgument_p    = user-specific argument
-//              fContinuously_p = if TRUE, callback function will be called
-//                                continuously;
-//                                otherwise, it is a oneshot timer.
-//
-// Return:      tEplKernel      = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-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;
-	tEplTimerHighReskTimerInfo *pTimerInfo;
-	ktime_t RelTime;
-
-	Ret = kEplSuccessful;
-
-	// check pointer to handle
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-	if (*pTimerHdl_p == 0) {	// no timer created yet
-
-		// search free timer info structure
-		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[0];
-		for (uiIndex = 0; uiIndex < TIMER_COUNT;
-		     uiIndex++, pTimerInfo++) {
-			if (pTimerInfo->m_EventArg.m_TimerHdl == 0) {	// free structure found
-				break;
-			}
-		}
-		if (uiIndex >= TIMER_COUNT) {	// no free structure found
-			Ret = kEplTimerNoTimerCreated;
-			goto Exit;
-		}
-
-		pTimerInfo->m_EventArg.m_TimerHdl = HDL_INIT(uiIndex);
-	} else {
-		uiIndex = HDL_TO_IDX(*pTimerHdl_p);
-		if (uiIndex >= TIMER_COUNT) {	// invalid handle
-			Ret = kEplTimerInvalidHandle;
-			goto Exit;
-		}
-
-		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
-	}
-
-	/*
-	 * increment timer handle
-	 * (if timer expires right after this statement, the user
-	 * would detect an unknown timer handle and discard it)
-	 */
-	pTimerInfo->m_EventArg.m_TimerHdl =
-	    HDL_INC(pTimerInfo->m_EventArg.m_TimerHdl);
-	*pTimerHdl_p = pTimerInfo->m_EventArg.m_TimerHdl;
-
-	// reject too small time values
-	if ((fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_CYCLE))
-	    || (!fContinuously_p && (ullTimeNs_p < TIMER_MIN_VAL_SINGLE))) {
-		Ret = kEplTimerNoTimerCreated;
-		goto Exit;
-	}
-
-	pTimerInfo->m_EventArg.m_ulArg = ulArgument_p;
-	pTimerInfo->m_pfnCallback = pfnCallback_p;
-	pTimerInfo->m_fContinuously = fContinuously_p;
-	pTimerInfo->m_ullPeriod = ullTimeNs_p;
-
-	/*
-	 * HRTIMER_MODE_REL does not influence general handling of this timer.
-	 * It only sets relative mode for this start operation.
-	 * -> Expire time is calculated by: Now + RelTime
-	 * hrtimer_start also skips pending timer events.
-	 * The state HRTIMER_STATE_CALLBACK is ignored.
-	 * We have to cope with that in our callback function.
-	 */
-	RelTime = ktime_add_ns(ktime_set(0, 0), ullTimeNs_p);
-	hrtimer_start(&pTimerInfo->m_Timer, RelTime, HRTIMER_MODE_REL);
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimerHighReskDeleteTimer()
-//
-// Description: deletes the timer with the specified handle. Afterward the
-//              handle is set to zero.
-//
-// Parameters:  pTimerHdl_p     = pointer to timer handle
-//
-// Return:      tEplKernel      = error code
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	unsigned int uiIndex;
-	tEplTimerHighReskTimerInfo *pTimerInfo;
-
-	// check pointer to handle
-	if (pTimerHdl_p == NULL) {
-		Ret = kEplTimerInvalidHandle;
-		goto Exit;
-	}
-
-	if (*pTimerHdl_p == 0) {	// no timer created yet
-		goto Exit;
-	} else {
-		uiIndex = HDL_TO_IDX(*pTimerHdl_p);
-		if (uiIndex >= TIMER_COUNT) {	// invalid handle
-			Ret = kEplTimerInvalidHandle;
-			goto Exit;
-		}
-		pTimerInfo = &EplTimerHighReskInstance_l.m_aTimerInfo[uiIndex];
-		if (pTimerInfo->m_EventArg.m_TimerHdl != *pTimerHdl_p) {	// invalid handle
-			goto Exit;
-		}
-	}
-
-	*pTimerHdl_p = 0;
-	pTimerInfo->m_EventArg.m_TimerHdl = 0;
-	pTimerInfo->m_pfnCallback = NULL;
-
-	/*
-	 * Three return cases of hrtimer_try_to_cancel have to be tracked:
-	 *  1 - timer has been removed
-	 *  0 - timer was not active
-	 *      We need not do anything. hrtimer timers just consist of
-	 *      a hrtimer struct, which we might enqueue in the hrtimers
-	 *      event list by calling hrtimer_start().
-	 *      If a timer is not enqueued, it is not present in hrtimers.
-	 * -1 - callback function is running
-	 *      In this case we have to ensure that the timer is not
-	 *      continuously restarted. This has been done by clearing
-	 *      its handle.
-	 */
-	hrtimer_try_to_cancel(&pTimerInfo->m_Timer);
-
-      Exit:
-	return Ret;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    EplTimerHighReskCallback()
-//
-// Description: Callback function commonly used for all timers.
-//
-// Parameters:  pTimer_p = pointer to hrtimer
-//
-// Return:
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p)
-{
-	unsigned int uiIndex;
-	tEplTimerHighReskTimerInfo *pTimerInfo;
-	tEplTimerHdl OrgTimerHdl;
-	enum hrtimer_restart Ret;
-
-	BENCHMARK_MOD_24_SET(4);
-
-	Ret = HRTIMER_NORESTART;
-	pTimerInfo =
-	    container_of(pTimer_p, tEplTimerHighReskTimerInfo, m_Timer);
-	uiIndex = HDL_TO_IDX(pTimerInfo->m_EventArg.m_TimerHdl);
-	if (uiIndex >= TIMER_COUNT) {	// invalid handle
-		goto Exit;
-	}
-
-	/*
-	 * We store the timer handle before calling the callback function
-	 * as the timer can be modified inside it.
-	 */
-	OrgTimerHdl = pTimerInfo->m_EventArg.m_TimerHdl;
-
-	if (pTimerInfo->m_pfnCallback != NULL) {
-		pTimerInfo->m_pfnCallback(&pTimerInfo->m_EventArg);
-	}
-
-	if (pTimerInfo->m_fContinuously) {
-		ktime_t Interval;
-#ifdef PROVE_OVERRUN
-		ktime_t Now;
-		unsigned long Overruns;
-#endif
-
-		if (OrgTimerHdl != pTimerInfo->m_EventArg.m_TimerHdl) {
-			/* modified timer has already been restarted */
-			goto Exit;
-		}
-#ifdef PROVE_OVERRUN
-		Now = ktime_get();
-		Interval =
-		    ktime_add_ns(ktime_set(0, 0), pTimerInfo->m_ullPeriod);
-		Overruns = hrtimer_forward(pTimer_p, Now, Interval);
-		if (Overruns > 1) {
-			printk
-			    ("EplTimerHighResk: Continuous timer (handle 0x%lX) had to skip %lu interval(s)!\n",
-			     pTimerInfo->m_EventArg.m_TimerHdl, Overruns - 1);
-		}
-#else
-		pTimer_p->expires = ktime_add_ns(pTimer_p->expires,
-						 pTimerInfo->m_ullPeriod);
-#endif
-
-		Ret = HRTIMER_RESTART;
-	}
-
-      Exit:
-	BENCHMARK_MOD_24_RESET(4);
-	return Ret;
-}
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c
deleted file mode 100644
index 077724a..0000000
--- a/drivers/staging/epl/VirtualEthernetLinux.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  Virtual Ethernet Driver for Linux
-
-  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: VirtualEthernetLinux.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/11/20 17:06:51 $
-
-                $State: Exp $
-
-                Build Environment:
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/12 -ar:   start of the implementation, version 1.00
-
-  2006/09/18 d.k.:  integration into EPL DLLk module
-
-  ToDo:
-
-  void netif_carrier_off(struct net_device *dev);
-  void netif_carrier_on(struct net_device *dev);
-
-****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/if_arp.h>
-#include <net/arp.h>
-
-#include <net/protocol.h>
-#include <net/pkt_sched.h>
-#include <linux/if_ether.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>	/* for struct sk_buff */
-
-#include "kernel/VirtualEthernet.h"
-#include "kernel/EplDllkCal.h"
-#include "kernel/EplDllk.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef EPL_VETH_TX_TIMEOUT
-//#define EPL_VETH_TX_TIMEOUT (2*HZ)
-#define EPL_VETH_TX_TIMEOUT 0	// d.k.: we use no timeout
-#endif
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static struct net_device *pVEthNetDevice_g = NULL;
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static int VEthOpen(struct net_device *pNetDevice_p);
-static int VEthClose(struct net_device *pNetDevice_p);
-static int VEthXmit(struct sk_buff *pSkb_p, struct net_device *pNetDevice_p);
-static struct net_device_stats *VEthGetStats(struct net_device *pNetDevice_p);
-static void VEthTimeout(struct net_device *pNetDevice_p);
-static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-static int VEthOpen(struct net_device *pNetDevice_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	//open the device
-//	struct net_device_stats* pStats = netdev_priv(pNetDevice_p);
-
-	//start the interface queue for the network subsystem
-	netif_start_queue(pNetDevice_p);
-
-	// register callback function in DLL
-	Ret = EplDllkRegAsyncHandler(VEthRecvFrame);
-
-	EPL_DBGLVL_VETH_TRACE1
-	    ("VEthOpen: EplDllkRegAsyncHandler returned 0x%02X\n", Ret);
-
-	return 0;
-}
-
-static int VEthClose(struct net_device *pNetDevice_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	EPL_DBGLVL_VETH_TRACE0("VEthClose\n");
-
-	Ret = EplDllkDeregAsyncHandler(VEthRecvFrame);
-
-	//stop the interface queue for the network subsystem
-	netif_stop_queue(pNetDevice_p);
-	return 0;
-}
-
-static int VEthXmit(struct sk_buff *pSkb_p, struct net_device *pNetDevice_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	tEplFrameInfo FrameInfo;
-
-	//transmit function
-	struct net_device_stats *pStats = netdev_priv(pNetDevice_p);
-
-	//save timestemp
-	pNetDevice_p->trans_start = jiffies;
-
-	FrameInfo.m_pFrame = (tEplFrame *) pSkb_p->data;
-	FrameInfo.m_uiFrameSize = pSkb_p->len;
-
-	//call send fkt on DLL
-	Ret = EplDllkCalAsyncSend(&FrameInfo, kEplDllAsyncReqPrioGeneric);
-	if (Ret != kEplSuccessful) {
-		EPL_DBGLVL_VETH_TRACE1
-		    ("VEthXmit: EplDllkCalAsyncSend returned 0x%02X\n", Ret);
-		netif_stop_queue(pNetDevice_p);
-		goto Exit;
-	} else {
-		EPL_DBGLVL_VETH_TRACE0("VEthXmit: frame passed to DLL\n");
-		dev_kfree_skb(pSkb_p);
-
-		//set stats for the device
-		pStats->tx_packets++;
-		pStats->tx_bytes += FrameInfo.m_uiFrameSize;
-	}
-
-      Exit:
-	return 0;
-
-}
-
-static struct net_device_stats *VEthGetStats(struct net_device *pNetDevice_p)
-{
-	EPL_DBGLVL_VETH_TRACE0("VEthGetStats\n");
-
-	return netdev_priv(pNetDevice_p);
-}
-
-static void VEthTimeout(struct net_device *pNetDevice_p)
-{
-	EPL_DBGLVL_VETH_TRACE0("VEthTimeout(\n");
-
-	// $$$ d.k.: move to extra function, which is called by DLL when new space is available in TxFifo
-	if (netif_queue_stopped(pNetDevice_p)) {
-		netif_wake_queue(pNetDevice_p);
-	}
-}
-
-static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-	struct net_device *pNetDevice = pVEthNetDevice_g;
-	struct net_device_stats *pStats = netdev_priv(pNetDevice);
-	struct sk_buff *pSkb;
-
-	EPL_DBGLVL_VETH_TRACE1("VEthRecvFrame: FrameSize=%u\n",
-			       pFrameInfo_p->m_uiFrameSize);
-
-	pSkb = dev_alloc_skb(pFrameInfo_p->m_uiFrameSize + 2);
-	if (pSkb == NULL) {
-		pStats->rx_dropped++;
-		goto Exit;
-	}
-	pSkb->dev = pNetDevice;
-
-	skb_reserve(pSkb, 2);
-
-	memcpy((void *)skb_put(pSkb, pFrameInfo_p->m_uiFrameSize),
-	       pFrameInfo_p->m_pFrame, pFrameInfo_p->m_uiFrameSize);
-
-	pSkb->protocol = eth_type_trans(pSkb, pNetDevice);
-	pSkb->ip_summed = CHECKSUM_UNNECESSARY;
-
-	// call netif_rx with skb
-	netif_rx(pSkb);
-
-	EPL_DBGLVL_VETH_TRACE1("VEthRecvFrame: SrcMAC=0x%llx\n",
-			       AmiGetQword48FromBe(pFrameInfo_p->m_pFrame->
-						   m_be_abSrcMac));
-
-	// update receive statistics
-	pStats->rx_packets++;
-	pStats->rx_bytes += pFrameInfo_p->m_uiFrameSize;
-
-      Exit:
-	return Ret;
-}
-
-static const struct net_device_ops epl_netdev_ops = {
-	.ndo_open		= VEthOpen,
-	.ndo_stop		= VEthClose,
-	.ndo_get_stats		= VEthGetStats,
-	.ndo_start_xmit		= VEthXmit,
-	.ndo_tx_timeout		= VEthTimeout,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	// allocate net device structure with priv pointing to stats structure
-	pVEthNetDevice_g =
-	    alloc_netdev(sizeof(struct net_device_stats), EPL_VETH_NAME,
-			 ether_setup);
-//    pVEthNetDevice_g = alloc_etherdev(sizeof (struct net_device_stats));
-
-	if (pVEthNetDevice_g == NULL) {
-		Ret = kEplNoResource;
-		goto Exit;
-	}
-
-	pVEthNetDevice_g->netdev_ops = &epl_netdev_ops;
-	pVEthNetDevice_g->watchdog_timeo = EPL_VETH_TX_TIMEOUT;
-	pVEthNetDevice_g->destructor = free_netdev;
-
-	// copy own MAC address to net device structure
-	memcpy(pVEthNetDevice_g->dev_addr, pInitParam_p->m_be_abSrcMac, 6);
-
-	//register VEth to the network subsystem
-	if (register_netdev(pVEthNetDevice_g)) {
-		EPL_DBGLVL_VETH_TRACE0
-		    ("VEthAddInstance: Could not register VEth...\n");
-	} else {
-		EPL_DBGLVL_VETH_TRACE0
-		    ("VEthAddInstance: Register VEth successfull...\n");
-	}
-
-      Exit:
-	return Ret;
-}
-
-tEplKernel VEthDelInstance(void)
-{
-	tEplKernel Ret = kEplSuccessful;
-
-	if (pVEthNetDevice_g != NULL) {
-		//unregister VEth from the network subsystem
-		unregister_netdev(pVEthNetDevice_g);
-		// destructor was set to free_netdev,
-		// so we do not need to call free_netdev here
-		pVEthNetDevice_g = NULL;
-	}
-
-	return Ret;
-}
-
-#endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
diff --git a/drivers/staging/epl/amix86.c b/drivers/staging/epl/amix86.c
deleted file mode 100644
index d40ad91..0000000
--- a/drivers/staging/epl/amix86.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  Abstract Memory Interface for x86 compatible
-
-  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: amix86.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    ...
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  r.s.: first implemetation
-
-  2006-06-13  d.k.: duplicate functions for little endian and big endian
-
-****************************************************************************/
-
-//#include "global.h"
-//#include "EplAmi.h"
-#include "EplInc.h"
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef struct {
-	u16 m_wWord;
-
-} twStruct;
-
-typedef struct {
-	u32 m_dwDword;
-
-} tdwStruct;
-
-typedef struct {
-	u64 m_qwQword;
-
-} tqwStruct;
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetXXXToBe()
-//
-// Description: writes the specified value to the absolute address in
-//              big endian
-//
-// Parameters:  pAddr_p                 = absolute address
-//              xXXXVal_p               = value
-//
-// Returns:     (none)
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-//------------< write u8 in big endian >--------------------------
-/*
-void AmiSetByteToBe (void *pAddr_p, u8 bByteVal_p)
-{
-
-	*(u8 *)pAddr_p = bByteVal_p;
-
-}
-*/
-
-//------------< write u16 in big endian >--------------------------
-
-void AmiSetWordToBe(void * pAddr_p, u16 wWordVal_p)
-{
-	twStruct *pwStruct;
-	twStruct wValue;
-
-	wValue.m_wWord = (u16) ((wWordVal_p & 0x00FF) << 8);	//LSB to MSB
-	wValue.m_wWord |= (u16) ((wWordVal_p & 0xFF00) >> 8);	//MSB to LSB
-
-	pwStruct = (twStruct *) pAddr_p;
-	pwStruct->m_wWord = wValue.m_wWord;
-
-}
-
-//------------< write u32 in big endian >-------------------------
-
-void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p)
-{
-	tdwStruct *pdwStruct;
-	tdwStruct dwValue;
-
-	dwValue.m_dwDword = ((dwDwordVal_p & 0x000000FF) << 24);	//LSB to MSB
-	dwValue.m_dwDword |= ((dwDwordVal_p & 0x0000FF00) << 8);
-	dwValue.m_dwDword |= ((dwDwordVal_p & 0x00FF0000) >> 8);
-	dwValue.m_dwDword |= ((dwDwordVal_p & 0xFF000000) >> 24);	//MSB to LSB
-
-	pdwStruct = (tdwStruct *) pAddr_p;
-	pdwStruct->m_dwDword = dwValue.m_dwDword;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetXXXToLe()
-//
-// Description: writes the specified value to the absolute address in
-//              little endian
-//
-// Parameters:  pAddr_p                 = absolute address
-//              xXXXVal_p               = value
-//
-// Returns:     (none)
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-//------------< write u8 in little endian >--------------------------
-/*
-void AmiSetByteToLe (void *pAddr_p, u8 bByteVal_p)
-{
-
-	*(u8 *)pAddr_p = bByteVal_p;
-
-}
-*/
-
-//------------< write u16 in little endian >--------------------------
-
-void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p)
-{
-	twStruct *pwStruct;
-
-	pwStruct = (twStruct *) pAddr_p;
-	pwStruct->m_wWord = wWordVal_p;
-
-}
-
-//------------< write u32 in little endian >-------------------------
-
-void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p)
-{
-	tdwStruct *pdwStruct;
-
-	pdwStruct = (tdwStruct *) pAddr_p;
-	pdwStruct->m_dwDword = dwDwordVal_p;
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetXXXFromBe()
-//
-// Description: reads the specified value from the absolute address in
-//              big endian
-//
-// Parameters:  pAddr_p                 = absolute address
-//
-// Returns:     XXX                     = value
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-//------------< read u8 in big endian >---------------------------
-/*
-u8 AmiGetByteFromBe (void *pAddr_p)
-{
-
-	return ( *(u8 *)pAddr_p );
-
-}
-*/
-
-//------------< read u16 in big endian >---------------------------
-
-u16 AmiGetWordFromBe(void *pAddr_p)
-{
-	twStruct *pwStruct;
-	twStruct wValue;
-
-	pwStruct = (twStruct *) pAddr_p;
-
-	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 u32 in big endian >--------------------------
-
-u32 AmiGetDwordFromBe(void *pAddr_p)
-{
-	tdwStruct *pdwStruct;
-	tdwStruct dwValue;
-
-	pdwStruct = (tdwStruct *) pAddr_p;
-
-	dwValue.m_dwDword = ((pdwStruct->m_dwDword & 0x000000FF) << 24);	//LSB to MSB
-	dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0x0000FF00) << 8);
-	dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0x00FF0000) >> 8);
-	dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0xFF000000) >> 24);	//MSB to LSB
-
-	return (dwValue.m_dwDword);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetXXXFromLe()
-//
-// Description: reads the specified value from the absolute address in
-//              little endian
-//
-// Parameters:  pAddr_p                 = absolute address
-//
-// Returns:     XXX                     = value
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-//------------< read u8 in little endian >---------------------------
-/*
-u8 AmiGetByteFromLe (void *pAddr_p)
-{
-
-	return ( *(u8 *)pAddr_p );
-
-}
-*/
-
-//------------< read u16 in little endian >---------------------------
-
-u16 AmiGetWordFromLe(void *pAddr_p)
-{
-	twStruct *pwStruct;
-
-	pwStruct = (twStruct *) pAddr_p;
-	return (pwStruct->m_wWord);
-}
-
-//------------< read u32 in little endian >--------------------------
-
-u32 AmiGetDwordFromLe(void *pAddr_p)
-{
-	tdwStruct *pdwStruct;
-
-	pdwStruct = (tdwStruct *) pAddr_p;
-	return (pdwStruct->m_dwDword);
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetDword24ToBe()
-//
-// Description: sets a 24 bit value to a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              dwDwordVal_p    = value to set
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p)
-{
-	((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[2];
-	((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
-	((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[0];
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetDword24ToLe()
-//
-// Description: sets a 24 bit value to a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              dwDwordVal_p    = value to set
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p)
-{
-	((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[0];
-	((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
-	((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[2];
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetDword24FromBe()
-//
-// Description: reads a 24 bit value from a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u32           = read value
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-u32 AmiGetDword24FromBe(void *pAddr_p)
-{
-	tdwStruct dwStruct;
-
-	dwStruct.m_dwDword = AmiGetDwordFromBe(pAddr_p);
-	dwStruct.m_dwDword >>= 8;
-
-	return (dwStruct.m_dwDword);
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetDword24FromLe()
-//
-// Description: reads a 24 bit value from a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u32           = read value
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-u32 AmiGetDword24FromLe(void *pAddr_p)
-{
-	tdwStruct dwStruct;
-
-	dwStruct.m_dwDword = AmiGetDwordFromLe(pAddr_p);
-	dwStruct.m_dwDword &= 0x00FFFFFF;
-
-	return (dwStruct.m_dwDword);
-}
-
-//#ifdef USE_VAR64
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword64ToBe()
-//
-// Description: sets a 64 bit value to a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p)
-{
-	((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];
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword64ToLe()
-//
-// Description: sets a 64 bit value to a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p)
-{
-	u64 *pqwDst;
-
-	pqwDst = (u64 *) pAddr_p;
-	*pqwDst = qwQwordVal_p;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword64FromBe()
-//
-// Description: reads a 64 bit value from a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-u64 AmiGetQword64FromBe(void *pAddr_p)
-{
-	tqwStruct qwStruct;
-
-	((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);
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword64FromLe()
-//
-// Description: reads a 64 bit value from a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-u64 AmiGetQword64FromLe(void *pAddr_p)
-{
-	tqwStruct *pqwStruct;
-	tqwStruct qwStruct;
-
-	pqwStruct = (tqwStruct *) pAddr_p;
-	qwStruct.m_qwQword = pqwStruct->m_qwQword;
-
-	return (qwStruct.m_qwQword);
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword40ToBe()
-//
-// Description: sets a 40 bit value to a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p)
-{
-
-	((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];
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword40ToLe()
-//
-// Description: sets a 40 bit value to a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p)
-{
-
-	((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
-	((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[4];
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword40FromBe()
-//
-// Description: reads a 40 bit value from a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword40FromBe(void *pAddr_p)
-{
-
-	tqwStruct qwStruct;
-
-	qwStruct.m_qwQword = AmiGetQword64FromBe(pAddr_p);
-	qwStruct.m_qwQword >>= 24;
-
-	return (qwStruct.m_qwQword);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword40FromLe()
-//
-// Description: reads a 40 bit value from a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword40FromLe(void *pAddr_p)
-{
-
-	tqwStruct qwStruct;
-
-	qwStruct.m_qwQword = AmiGetQword64FromLe(pAddr_p);
-	qwStruct.m_qwQword &= 0x000000FFFFFFFFFFLL;
-
-	return (qwStruct.m_qwQword);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword48ToBe()
-//
-// Description: sets a 48 bit value to a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p)
-{
-
-	((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];
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword48ToLe()
-//
-// Description: sets a 48 bit value to a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p)
-{
-
-	((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
-	((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword48FromBe()
-//
-// Description: reads a 48 bit value from a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword48FromBe(void *pAddr_p)
-{
-
-	tqwStruct qwStruct;
-
-	qwStruct.m_qwQword = AmiGetQword64FromBe(pAddr_p);
-	qwStruct.m_qwQword >>= 16;
-
-	return (qwStruct.m_qwQword);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword48FromLe()
-//
-// Description: reads a 48 bit value from a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword48FromLe(void *pAddr_p)
-{
-
-	tqwStruct qwStruct;
-
-	qwStruct.m_qwQword = AmiGetQword64FromLe(pAddr_p);
-	qwStruct.m_qwQword &= 0x0000FFFFFFFFFFFFLL;
-
-	return (qwStruct.m_qwQword);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword56ToBe()
-//
-// Description: sets a 56 bit value to a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p)
-{
-
-	((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];
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetQword56ToLe()
-//
-// Description: sets a 56 bit value to a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              qwQwordVal_p    = quadruple word value
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p)
-{
-
-	((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
-	((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
-	((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[6];
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword56FromBe()
-//
-// Description: reads a 56 bit value from a buffer in big endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword56FromBe(void *pAddr_p)
-{
-
-	tqwStruct qwStruct;
-
-	qwStruct.m_qwQword = AmiGetQword64FromBe(pAddr_p);
-	qwStruct.m_qwQword >>= 8;
-
-	return (qwStruct.m_qwQword);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetQword56FromLe()
-//
-// Description: reads a 56 bit value from a buffer in little endian
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//
-// Return:      u64
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-u64 AmiGetQword56FromLe(void *pAddr_p)
-{
-
-	tqwStruct qwStruct;
-
-	qwStruct.m_qwQword = AmiGetQword64FromLe(pAddr_p);
-	qwStruct.m_qwQword &= 0x00FFFFFFFFFFFFFFLL;
-
-	return (qwStruct.m_qwQword);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiSetTimeOfDay()
-//
-// Description: sets a TIME_OF_DAY (CANopen) value to a buffer
-//
-// Parameters:  pAddr_p         = pointer to destination buffer
-//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
-{
-
-	AmiSetDwordToLe(((u8 *) pAddr_p), pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
-	AmiSetWordToLe(((u8 *) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
-
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AmiGetTimeOfDay()
-//
-// Description: reads a TIME_OF_DAY (CANopen) value from a buffer
-//
-// Parameters:  pAddr_p         = pointer to source buffer
-//              pTimeOfDay_p    = pointer to struct TIME_OF_DAY
-//
-// Return:      void
-//
-// State:       not tested
-//
-//---------------------------------------------------------------------------
-
-void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
-{
-
-	pTimeOfDay_p->m_dwMs = AmiGetDwordFromLe(((u8 *) pAddr_p)) & 0x0FFFFFFF;
-	pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((u8 *) pAddr_p) + 4);
-
-}
-
-// EOF
-
-// 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/demo_main.c b/drivers/staging/epl/demo_main.c
deleted file mode 100644
index 7ad10fc..0000000
--- a/drivers/staging/epl/demo_main.c
+++ /dev/null
@@ -1,947 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  demoapplication for EPL MN (with SDO over UDP)
-                under Linux on X86 with RTL8139 Ethernet controller
-
-  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: demo_main.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.10 $  $Date: 2008/11/19 18:11:43 $
-
-                $State: Exp $
-
-                Build Environment:
-                GCC
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/09/01 d.k.:   start of implementation
-
-****************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/major.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/atomic.h>
-#include <linux/sched.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-
-#include "Epl.h"
-#include "proc_fs.h"
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-// Metainformation
-MODULE_LICENSE("Dual BSD/GPL");
-#ifdef MODULE_AUTHOR
-MODULE_AUTHOR("Daniel.Krueger@SYSTEC-electronic.com");
-MODULE_DESCRIPTION("EPL MN demo");
-#endif
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// TracePoint support for realtime-debugging
-#ifdef _DBG_TRACE_POINTS_
-void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
-#else
-#define TGT_DBG_SIGNAL_TRACE_POINT(p)
-#endif
-
-#define NODEID      0xF0	//=> MN
-#define CYCLE_LEN   5000	// [us]
-#define IP_ADDR     0xc0a86401	// 192.168.100.1
-#define SUBNET_MASK 0xFFFFFF00	// 255.255.255.0
-#define HOSTNAME    "SYS TEC electronic EPL Stack    "
-#define IF_ETH      EPL_VETH_NAME
-
-// LIGHT EFFECT
-#define DEFAULT_MAX_CYCLE_COUNT 20	// 6 is very fast
-#define APP_DEFAULT_MODE        0x01
-#define APP_LED_COUNT           5	// number of LEDs in one row
-#define APP_LED_MASK            ((1 << APP_LED_COUNT) - 1)
-#define APP_DOUBLE_LED_MASK     ((1 << (APP_LED_COUNT * 2)) - 1)
-#define APP_MODE_COUNT          5
-#define APP_MODE_MASK           ((1 << APP_MODE_COUNT) - 1)
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-static const u8 abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-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
-
-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
-
-//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 u32 dw_le_CycleLen_g;
-
-static uint uiNodeId_g = EPL_C_ADR_INVALID;
-module_param_named(nodeid, uiNodeId_g, uint, 0);
-
-static uint uiCycleLen_g = CYCLE_LEN;
-module_param_named(cyclelen, uiCycleLen_g, uint, 0);
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-// This function is the entry point for your object dictionary. It is defined
-// in OBJDICT.C by define EPL_OBD_INIT_RAM_NAME. Use this function name to define
-// 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 EplObdInitRam(tEplObdInitParam *pInitParam_p);
-
-tEplKernel AppCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-		      tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
-		      void *pUserArg_p);
-
-tEplKernel AppCbSync(void);
-
-
-//---------------------------------------------------------------------------
-//  Kernel Module specific Data Structures
-//---------------------------------------------------------------------------
-
-//module_init(EplLinInit);
-//module_exit(EplLinExit);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:
-//
-// Description:
-//
-//
-//
-// Parameters:
-//
-//
-// Returns:
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-#if 0
-static int __init EplLinInit(void)
-{
-	tEplKernel EplRet;
-	int iRet;
-	static tEplApiInitParam EplApiInitParam = { 0 };
-	char *sHostname = HOSTNAME;
-	char *argv[4], *envp[3];
-	char sBuffer[16];
-	unsigned int uiVarEntries;
-	tEplObdSize ObdSize;
-
-	atomic_set(&AtomicShutdown_g, TRUE);
-
-	// get node ID from insmod command line
-	EplApiInitParam.m_uiNodeId = uiNodeId_g;
-
-	if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) {	// invalid node ID set
-		// set default node ID
-		EplApiInitParam.m_uiNodeId = NODEID;
-	}
-
-	uiNodeId_g = EplApiInitParam.m_uiNodeId;
-
-	// calculate IP address
-	EplApiInitParam.m_dwIpAddress =
-	    (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId;
-
-	EplApiInitParam.m_fAsyncOnly = FALSE;
-
-	EplApiInitParam.m_uiSizeOfStruct = sizeof(EplApiInitParam);
-	EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr,
-		   sizeof(EplApiInitParam.m_abMacAddress));
-//	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
-	EplApiInitParam.m_uiIsochrRxMaxPayload = 100;	// const
-	EplApiInitParam.m_dwPresMaxLatency = 50000;	// const; only required for IdentRes
-	EplApiInitParam.m_uiPreqActPayloadLimit = 36;	// required for initialisation (+28 bytes)
-	EplApiInitParam.m_uiPresActPayloadLimit = 36;	// required for initialisation of Pres frame (+28 bytes)
-	EplApiInitParam.m_dwAsndMaxLatency = 150000;	// const; only required for IdentRes
-	EplApiInitParam.m_uiMultiplCycleCnt = 0;	// required for error detection
-	EplApiInitParam.m_uiAsyncMtu = 1500;	// required to set up max frame size
-	EplApiInitParam.m_uiPrescaler = 2;	// required for sync
-	EplApiInitParam.m_dwLossOfFrameTolerance = 500000;
-	EplApiInitParam.m_dwAsyncSlotTimeout = 3000000;
-	EplApiInitParam.m_dwWaitSocPreq = 150000;
-	EplApiInitParam.m_dwDeviceType = -1;	// NMT_DeviceType_U32
-	EplApiInitParam.m_dwVendorId = -1;	// NMT_IdentityObject_REC.VendorId_U32
-	EplApiInitParam.m_dwProductCode = -1;	// NMT_IdentityObject_REC.ProductCode_U32
-	EplApiInitParam.m_dwRevisionNumber = -1;	// NMT_IdentityObject_REC.RevisionNo_U32
-	EplApiInitParam.m_dwSerialNumber = -1;	// NMT_IdentityObject_REC.SerialNo_U32
-	EplApiInitParam.m_dwSubnetMask = SUBNET_MASK;
-	EplApiInitParam.m_dwDefaultGateway = 0;
-	EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname,
-		   sizeof(EplApiInitParam.m_sHostname));
-
-	// currently unset parameters left at default value 0
-	//EplApiInitParam.m_qwVendorSpecificExt1;
-	//EplApiInitParam.m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
-	//EplApiInitParam.m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
-	//EplApiInitParam.m_dwApplicationSwDate;       // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
-	//EplApiInitParam.m_dwApplicationSwTime;       // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
-	//EplApiInitParam.m_abVendorSpecificExt2[48];
-
-	// set callback functions
-	EplApiInitParam.m_pfnCbEvent = AppCbEvent;
-	EplApiInitParam.m_pfnCbSync = AppCbSync;
-
-	printk
-	    ("\n\n Hello, I'm a simple POWERLINK node running as %s!\n  (build: %s / %s)\n\n",
-	     (uiNodeId_g ==
-	      EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"),
-	     __DATE__, __TIME__);
-
-	// initialize the Linux a wait queue for shutdown of this module
-	init_waitqueue_head(&WaitQueueShutdown_g);
-
-	// initialize the procfs device
-	EplRet = EplLinProcInit();
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-	// initialize POWERLINK stack
-	EplRet = EplApiInitialize(&EplApiInitParam);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-	// link process variables used by CN to object dictionary
-	ObdSize = sizeof(bVarIn1_l);
-	uiVarEntries = 1;
-	EplRet =
-	    EplApiLinkObject(0x6000, &bVarIn1_l, &uiVarEntries, &ObdSize, 0x01);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-
-	ObdSize = sizeof(bVarOut1_l);
-	uiVarEntries = 1;
-	EplRet =
-	    EplApiLinkObject(0x6200, &bVarOut1_l, &uiVarEntries, &ObdSize,
-			     0x01);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-	// link process variables used by MN to object dictionary
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	ObdSize = sizeof(bLedsRow1_l);
-	uiVarEntries = 1;
-	EplRet =
-	    EplApiLinkObject(0x2000, &bLedsRow1_l, &uiVarEntries, &ObdSize,
-			     0x01);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-
-	ObdSize = sizeof(bLedsRow2_l);
-	uiVarEntries = 1;
-	EplRet =
-	    EplApiLinkObject(0x2000, &bLedsRow2_l, &uiVarEntries, &ObdSize,
-			     0x02);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-
-	ObdSize = sizeof(bSpeedSelect_l);
-	uiVarEntries = 1;
-	EplRet =
-	    EplApiLinkObject(0x2000, &bSpeedSelect_l, &uiVarEntries, &ObdSize,
-			     0x03);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-
-	ObdSize = sizeof(bSpeedSelectOld_l);
-	uiVarEntries = 1;
-	EplRet =
-	    EplApiLinkObject(0x2000, &bSpeedSelectOld_l, &uiVarEntries,
-			     &ObdSize, 0x04);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-
-	ObdSize = sizeof(abSelect_l[0]);
-	uiVarEntries = sizeof(abSelect_l);
-	EplRet =
-	    EplApiLinkObject(0x2200, &abSelect_l[0], &uiVarEntries, &ObdSize,
-			     0x01);
-	if (EplRet != kEplSuccessful) {
-		goto Exit;
-	}
-#endif
-
-	// link a DOMAIN to object 0x6100, but do not exit, if it is missing
-	ObdSize = sizeof(abDomain_l);
-	uiVarEntries = 1;
-	EplRet =
-	    EplApiLinkObject(0x6100, &abDomain_l, &uiVarEntries, &ObdSize,
-			     0x00);
-	if (EplRet != kEplSuccessful) {
-		printk("EplApiLinkObject(0x6100): returns 0x%X\n", EplRet);
-	}
-	// reset old process variables
-	bVarOut1Old_l = 0;
-	bSpeedSelectOld_l = 0;
-	dwMode_l = APP_DEFAULT_MODE;
-	iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
-
-	// configure IP address of virtual network interface
-	// for TCP/IP communication over the POWERLINK network
-	sprintf(sBuffer, "%u.%u.%u.%u",
-		(EplApiInitParam.m_dwIpAddress >> 24),
-		((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF),
-		((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF),
-		(EplApiInitParam.m_dwIpAddress & 0xFF));
-	/* set up a minimal environment */
-	iRet = 0;
-	envp[iRet++] = "HOME=/";
-	envp[iRet++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-	envp[iRet] = NULL;
-
-	/* set up the argument list */
-	iRet = 0;
-	argv[iRet++] = "/sbin/ifconfig";
-	argv[iRet++] = IF_ETH;
-	argv[iRet++] = sBuffer;
-	argv[iRet] = NULL;
-
-	/* call ifconfig to configure the virtual network interface */
-	iRet = call_usermodehelper(argv[0], argv, envp, 1);
-	printk("ifconfig %s %s returned %d\n", argv[1], argv[2], iRet);
-
-	// start the NMT state machine
-	EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset);
-	atomic_set(&AtomicShutdown_g, FALSE);
-
-      Exit:
-	printk("EplLinInit(): returns 0x%X\n", EplRet);
-	return EplRet;
-}
-
-static void __exit EplLinExit(void)
-{
-	tEplKernel EplRet;
-
-	// halt the NMT state machine
-	// so the processing of POWERLINK frames stops
-	EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff);
-
-	// wait until NMT state machine is shut down
-	wait_event_interruptible(WaitQueueShutdown_g,
-				 (atomic_read(&AtomicShutdown_g) == TRUE));
-/*    if ((iErr != 0) || (atomic_read(&AtomicShutdown_g) == EVENT_STATE_IOCTL))
-    {   // waiting was interrupted by signal or application called wrong function
-        EplRet = kEplShutdown;
-    }*/
-	// delete instance for all modules
-	EplRet = EplApiShutdown();
-	printk("EplApiShutdown():  0x%X\n", EplRet);
-
-	// deinitialize proc fs
-	EplRet = EplLinProcFree();
-	printk("EplLinProcFree():        0x%X\n", EplRet);
-
-}
-#endif
-//=========================================================================//
-//                                                                         //
-//          P R I V A T E   F U N C T I O N S                              //
-//                                                                         //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function:    AppCbEvent
-//
-// Description: event callback function called by EPL API layer within
-//              user part (low priority).
-//
-// Parameters:  EventType_p     = event type
-//              pEventArg_p     = pointer to union, which describes
-//                                the event in detail
-//              pUserArg_p      = user specific argument
-//
-// Returns:     tEplKernel      = error code,
-//                                kEplSuccessful = no error
-//                                kEplReject = reject further processing
-//                                otherwise = post error event to API layer
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel AppCbEvent(tEplApiEventType EventType_p,	// IN: event type (enum)
-		      tEplApiEventArg *pEventArg_p,	// IN: event argument (union)
-		      void *pUserArg_p)
-{
-	tEplKernel EplRet = kEplSuccessful;
-
-	// check if NMT_GS_OFF is reached
-	switch (EventType_p) {
-	case kEplApiEventNmtStateChange:
-		{
-			switch (pEventArg_p->m_NmtStateChange.m_NewNmtState) {
-			case kEplNmtGsOff:
-				{	// NMT state machine was shut down,
-					// because of user signal (CTRL-C) or critical EPL stack error
-					// -> also shut down EplApiProcess() and main()
-					EplRet = kEplShutdown;
-
-					printk
-					    ("AppCbEvent(kEplNmtGsOff) originating event = 0x%X\n",
-					     pEventArg_p->m_NmtStateChange.
-					     m_NmtEvent);
-
-					// wake up EplLinExit()
-					atomic_set(&AtomicShutdown_g, TRUE);
-					wake_up_interruptible
-					    (&WaitQueueShutdown_g);
-					break;
-				}
-
-			case kEplNmtGsResetCommunication:
-				{
-					u32 dwBuffer;
-
-					// configure OD for MN in state ResetComm after reseting the OD
-					// TODO: setup your own network configuration here
-					dwBuffer = (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS);	// 0x00000003L
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x01,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x02,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x03,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x04,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x05,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x06,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x07,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x08,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x20,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0xFE,
-								   &dwBuffer,
-								   4);
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0x6E,
-								   &dwBuffer,
-								   4);
-
-//                    dwBuffer |= EPL_NODEASSIGN_MANDATORY_CN;    // 0x0000000BL
-//                    EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwBuffer, 4);
-					dwBuffer = (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS);	// 0x00010001L
-					EplRet =
-					    EplApiWriteLocalObject(0x1F81, 0xF0,
-								   &dwBuffer,
-								   4);
-
-					// continue
-				}
-
-			case kEplNmtGsResetConfiguration:
-				{
-					unsigned int uiSize;
-
-					// fetch object 0x1006 NMT_CycleLen_U32 from local OD (in little endian byte order)
-					// for configuration of remote CN
-					uiSize = 4;
-					EplRet =
-					    EplApiReadObject(NULL, 0, 0x1006,
-							     0x00,
-							     &dw_le_CycleLen_g,
-							     &uiSize,
-							     kEplSdoTypeAsnd,
-							     NULL);
-					if (EplRet != kEplSuccessful) {	// local OD access failed
-						break;
-					}
-					// continue
-				}
-
-			case kEplNmtMsPreOperational1:
-				{
-					printk
-					    ("AppCbEvent(0x%X) originating event = 0x%X\n",
-					     pEventArg_p->m_NmtStateChange.
-					     m_NewNmtState,
-					     pEventArg_p->m_NmtStateChange.
-					     m_NmtEvent);
-
-					// continue
-				}
-
-			case kEplNmtGsInitialising:
-			case kEplNmtGsResetApplication:
-			case kEplNmtMsNotActive:
-			case kEplNmtCsNotActive:
-			case kEplNmtCsPreOperational1:
-				{
-					break;
-				}
-
-			case kEplNmtCsOperational:
-			case kEplNmtMsOperational:
-				{
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-			}
-
-/*
-            switch (pEventArg_p->m_NmtStateChange.m_NmtEvent)
-            {
-                case kEplNmtEventSwReset:
-                case kEplNmtEventResetNode:
-                case kEplNmtEventResetCom:
-                case kEplNmtEventResetConfig:
-                case kEplNmtEventInternComError:
-                case kEplNmtEventNmtCycleError:
-                {
-                    printk("AppCbEvent(0x%X) originating event = 0x%X\n",
-                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
-                           pEventArg_p->m_NmtStateChange.m_NmtEvent);
-                    break;
-                }
-
-                default:
-                {
-                    break;
-                }
-            }
-*/
-			break;
-		}
-
-	case kEplApiEventCriticalError:
-	case kEplApiEventWarning:
-		{		// error or warning occured within the stack or the application
-			// on error the API layer stops the NMT state machine
-
-			printk
-			    ("AppCbEvent(Err/Warn): Source=%02X EplError=0x%03X",
-			     pEventArg_p->m_InternalError.m_EventSource,
-			     pEventArg_p->m_InternalError.m_EplError);
-			// check additional argument
-			switch (pEventArg_p->m_InternalError.m_EventSource) {
-			case kEplEventSourceEventk:
-			case kEplEventSourceEventu:
-				{	// error occured within event processing
-					// either in kernel or in user part
-					printk(" OrgSource=%02X\n",
-					       pEventArg_p->m_InternalError.
-					       m_Arg.m_EventSource);
-					break;
-				}
-
-			case kEplEventSourceDllk:
-				{	// error occured within the data link layer (e.g. interrupt processing)
-					// the u32 argument contains the DLL state and the NMT event
-					printk(" val=%X\n",
-					       pEventArg_p->m_InternalError.
-					       m_Arg.m_dwArg);
-					break;
-				}
-
-			default:
-				{
-					printk("\n");
-					break;
-				}
-			}
-			break;
-		}
-
-	case kEplApiEventNode:
-		{
-//            printk("AppCbEvent(Node): Source=%02X EplError=0x%03X", pEventArg_p->m_InternalError.m_EventSource, pEventArg_p->m_InternalError.m_EplError);
-			// check additional argument
-			switch (pEventArg_p->m_Node.m_NodeEvent) {
-			case kEplNmtNodeEventCheckConf:
-				{
-					tEplSdoComConHdl SdoComConHdl;
-					// update object 0x1006 on CN
-					EplRet =
-					    EplApiWriteObject(&SdoComConHdl,
-							      pEventArg_p->
-							      m_Node.m_uiNodeId,
-							      0x1006, 0x00,
-							      &dw_le_CycleLen_g,
-							      4,
-							      kEplSdoTypeAsnd,
-							      NULL);
-					if (EplRet == kEplApiTaskDeferred) {	// SDO transfer started
-						EplRet = kEplReject;
-					} else if (EplRet == kEplSuccessful) {	// local OD access (should not occur)
-						printk
-						    ("AppCbEvent(Node) write to local OD\n");
-					} else {	// error occured
-						TGT_DBG_SIGNAL_TRACE_POINT(1);
-
-						EplRet =
-						    EplApiFreeSdoChannel
-						    (SdoComConHdl);
-						SdoComConHdl = 0;
-
-						EplRet =
-						    EplApiWriteObject
-						    (&SdoComConHdl,
-						     pEventArg_p->m_Node.
-						     m_uiNodeId, 0x1006, 0x00,
-						     &dw_le_CycleLen_g, 4,
-						     kEplSdoTypeAsnd, NULL);
-						if (EplRet == kEplApiTaskDeferred) {	// SDO transfer started
-							EplRet = kEplReject;
-						} else {
-							printk
-							    ("AppCbEvent(Node): EplApiWriteObject() returned 0x%02X\n",
-							     EplRet);
-						}
-					}
-
-					break;
-				}
-
-			default:
-				{
-					break;
-				}
-			}
-			break;
-		}
-
-	case kEplApiEventSdo:
-		{		// SDO transfer finished
-			EplRet =
-			    EplApiFreeSdoChannel(pEventArg_p->m_Sdo.
-						 m_SdoComConHdl);
-			if (EplRet != kEplSuccessful) {
-				break;
-			}
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-			if (pEventArg_p->m_Sdo.m_SdoComConState == kEplSdoComTransferFinished) {	// continue boot-up of CN with NMT command Reset Configuration
-				EplRet =
-				    EplApiMnTriggerStateChange(pEventArg_p->
-							       m_Sdo.m_uiNodeId,
-							       kEplNmtNodeCommandConfReset);
-			} else {	// indicate configuration error CN
-				EplRet =
-				    EplApiMnTriggerStateChange(pEventArg_p->
-							       m_Sdo.m_uiNodeId,
-							       kEplNmtNodeCommandConfErr);
-			}
-#endif
-
-			break;
-		}
-
-	default:
-		break;
-	}
-
-	return EplRet;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function:    AppCbSync
-//
-// Description: sync event callback function called by event module within
-//              kernel part (high priority).
-//              This function sets the outputs, reads the inputs and runs
-//              the control loop.
-//
-// Parameters:  void
-//
-// Returns:     tEplKernel      = error code,
-//                                kEplSuccessful = no error
-//                                otherwise = post error event to API layer
-//
-// State:
-//
-//---------------------------------------------------------------------------
-
-tEplKernel AppCbSync(void)
-{
-	tEplKernel EplRet = kEplSuccessful;
-
-	if (bVarOut1Old_l != bVarOut1_l) {	// output variable has changed
-		bVarOut1Old_l = bVarOut1_l;
-		// set LEDs
-
-//        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++;
-	}
-
-	if (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID) {	// we are the master and must run the control loop
-
-		// collect inputs from CNs and own input
-		bSpeedSelect_l = (bVarIn1_l | abSelect_l[0]) & 0x07;
-
-		bModeSelect_l = abSelect_l[1] | abSelect_l[2];
-
-		if ((bModeSelect_l & APP_MODE_MASK) != 0) {
-			dwMode_l = bModeSelect_l & APP_MODE_MASK;
-		}
-
-		iCurCycleCount_l--;
-
-		if (iCurCycleCount_l <= 0) {
-			if ((dwMode_l & 0x01) != 0) {	// fill-up
-				if (iToggle) {
-					if ((dwLeds_l & APP_DOUBLE_LED_MASK) ==
-					    0x00) {
-						dwLeds_l = 0x01;
-					} else {
-						dwLeds_l <<= 1;
-						dwLeds_l++;
-						if (dwLeds_l >=
-						    APP_DOUBLE_LED_MASK) {
-							iToggle = 0;
-						}
-					}
-				} else {
-					dwLeds_l <<= 1;
-					if ((dwLeds_l & APP_DOUBLE_LED_MASK) ==
-					    0x00) {
-						iToggle = 1;
-					}
-				}
-				bLedsRow1_l =
-				    (unsigned char)(dwLeds_l & APP_LED_MASK);
-				bLedsRow2_l =
-				    (unsigned char)((dwLeds_l >> APP_LED_COUNT)
-						    & APP_LED_MASK);
-			}
-
-			else if ((dwMode_l & 0x02) != 0) {	// running light forward
-				dwLeds_l <<= 1;
-				if ((dwLeds_l > APP_DOUBLE_LED_MASK)
-				    || (dwLeds_l == 0x00000000L)) {
-					dwLeds_l = 0x01;
-				}
-				bLedsRow1_l =
-				    (unsigned char)(dwLeds_l & APP_LED_MASK);
-				bLedsRow2_l =
-				    (unsigned char)((dwLeds_l >> APP_LED_COUNT)
-						    & APP_LED_MASK);
-			}
-
-			else if ((dwMode_l & 0x04) != 0) {	// running light backward
-				dwLeds_l >>= 1;
-				if ((dwLeds_l > APP_DOUBLE_LED_MASK)
-				    || (dwLeds_l == 0x00000000L)) {
-					dwLeds_l = 1 << (APP_LED_COUNT * 2);
-				}
-				bLedsRow1_l =
-				    (unsigned char)(dwLeds_l & APP_LED_MASK);
-				bLedsRow2_l =
-				    (unsigned char)((dwLeds_l >> APP_LED_COUNT)
-						    & APP_LED_MASK);
-			}
-
-			else if ((dwMode_l & 0x08) != 0) {	// Knightrider
-				if (bLedsRow1_l == 0x00) {
-					bLedsRow1_l = 0x01;
-					iToggle = 1;
-				} else if (iToggle) {
-					bLedsRow1_l <<= 1;
-					if (bLedsRow1_l >=
-					    (1 << (APP_LED_COUNT - 1))) {
-						iToggle = 0;
-					}
-				} else {
-					bLedsRow1_l >>= 1;
-					if (bLedsRow1_l <= 0x01) {
-						iToggle = 1;
-					}
-				}
-				bLedsRow2_l = bLedsRow1_l;
-			}
-
-			else if ((dwMode_l & 0x10) != 0) {	// Knightrider
-				if ((bLedsRow1_l == 0x00)
-				    || (bLedsRow2_l == 0x00)
-				    || ((bLedsRow2_l & ~APP_LED_MASK) != 0)) {
-					bLedsRow1_l = 0x01;
-					bLedsRow2_l =
-					    (1 << (APP_LED_COUNT - 1));
-					iToggle = 1;
-				} else if (iToggle) {
-					bLedsRow1_l <<= 1;
-					bLedsRow2_l >>= 1;
-					if (bLedsRow1_l >=
-					    (1 << (APP_LED_COUNT - 1))) {
-						iToggle = 0;
-					}
-				} else {
-					bLedsRow1_l >>= 1;
-					bLedsRow2_l <<= 1;
-					if (bLedsRow1_l <= 0x01) {
-						iToggle = 1;
-					}
-				}
-			}
-			// set own output
-			bVarOut1_l = bLedsRow1_l;
-//            bVarOut1_l = (bLedsRow1_l & 0x03) | (bLedsRow2_l << 2);
-
-			// restart cycle counter
-			iCurCycleCount_l = iMaxCycleCount_l;
-		}
-
-		if (bSpeedSelectOld_l == 0) {
-			if ((bSpeedSelect_l & 0x01) != 0) {
-				if (iMaxCycleCount_l < 200) {
-					iMaxCycleCount_l++;
-				}
-				bSpeedSelectOld_l = bSpeedSelect_l;
-			} else if ((bSpeedSelect_l & 0x02) != 0) {
-				if (iMaxCycleCount_l > 1) {
-					iMaxCycleCount_l--;
-				}
-				bSpeedSelectOld_l = bSpeedSelect_l;
-			} else if ((bSpeedSelect_l & 0x04) != 0) {
-				iMaxCycleCount_l = DEFAULT_MAX_CYCLE_COUNT;
-				bSpeedSelectOld_l = bSpeedSelect_l;
-			}
-		} else if (bSpeedSelect_l == 0) {
-			bSpeedSelectOld_l = 0;
-		}
-	}
-
-	TGT_DBG_SIGNAL_TRACE_POINT(1);
-
-	return EplRet;
-}
-
-// EOF
diff --git a/drivers/staging/epl/edrv.h b/drivers/staging/epl/edrv.h
deleted file mode 100644
index 62b4e77..0000000
--- a/drivers/staging/epl/edrv.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  interface for ethernetdriver
-
-  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: edrv.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $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 _EDRV_H_
-#define _EDRV_H_
-
-#include "EplInc.h"
-#include "EplFrame.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-// --------------------------------------------------------------------------
-#define MAX_ETH_DATA_SIZE       1500
-#define MIN_ETH_DATA_SIZE         46
-
-#define ETH_HDR_OFFSET 	 0	// Ethernet header at the top of the frame
-#define ETH_HDR_SIZE	14	// size of Ethernet header
-#define MIN_ETH_SIZE     (MIN_ETH_DATA_SIZE + ETH_HDR_SIZE)	// without CRC
-
-#define ETH_CRC_SIZE	 4	// size of Ethernet CRC, i.e. FCS
-
-//---------------------------------------------------------------------------
-// types
-//---------------------------------------------------------------------------
-
-// position of a buffer in an ethernet-frame
-typedef enum {
-	kEdrvBufferFirstInFrame = 0x01,	// first data buffer in an ethernet frame
-	kEdrvBufferMiddleInFrame = 0x02,	// a middle data buffer in an ethernet frame
-	kEdrvBufferLastInFrame = 0x04	// last data buffer in an ethernet frame
-} tEdrvBufferInFrame;
-
-// format of a tx-buffer
-typedef struct _tEdrvTxBuffer {
-	tEplMsgType m_EplMsgType;	// IN: type of EPL message, set by calling function
-	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
-	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
-} tEdrvTxBuffer;
-
-// format of a rx-buffer
-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)
-	u8 *m_pbBuffer;	// OUT: pointer to the buffer, set by ethernetdriver
-	tEplNetTime m_NetTime;	// OUT: Timestamp of end of receiption
-
-} tEdrvRxBuffer;
-
-//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 {
-	u8 m_abMyMacAddr[6];	// the own MAC address
-
-//    u8            m_bNoOfRxBuffDescr;     // number of entries in rx bufferdescriptor table
-//    tBufferDescr *  m_pRxBuffDescrTable;    // rx bufferdescriptor table
-//    u16            m_wRxBufferSize;        // size of the whole rx buffer
-
-	tEdrvRxHandler m_pfnRxHandler;
-	tEdrvTxHandler m_pfnTxHandler;
-
-} tEdrvInitParam;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p);
-
-tEplKernel EdrvShutdown(void);
-
-tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p);
-tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p);
-
-//tEplKernel EdrvDefineUnicastEntry     (u8 * pbUCEntry_p);
-//tEplKernel EdrvUndfineUnicastEntry    (u8 * pbUCEntry_p);
-
-tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
-tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
-
-//tEplKernel EdrvWriteMsg               (tBufferDescr * pbBuffer_p);
-tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p);
-tEplKernel EdrvTxMsgReady(tEdrvTxBuffer * pBuffer_p);
-tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p);
-
-//tEplKernel EdrvReadMsg                (void);
-
-// interrupt handler called by target specific interrupt handler
-void EdrvInterruptHandler(void);
-
-#endif // #ifndef _EDRV_H_
diff --git a/drivers/staging/epl/global.h b/drivers/staging/epl/global.h
deleted file mode 100644
index 8c52d97..0000000
--- a/drivers/staging/epl/global.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/****************************************************************************
-
-    global project definition file
-
-    12.06.1998   -rs
-    11.02.2002   r.d. Erweiterungen, Ergaenzungen
-    20.08.2002   SYS TEC electronic -as
-                 Definition Schluesselwort 'GENERIC'
-                 fuer das Erzeugen von Generic Pointer
-    28.08.2002   r.d. erweiterter SYS TEC Debug Code
-    16.09.2002   r.d. komplette Uebersetzung in Englisch
-    11.04.2003   f.j. Ergaenzung fuer Mitsubishi NC30 Compiler
-    17.06.2003   -rs  Definition von Basistypen in <#ifndef _WINDEF_> gesetzt
-    16.04.2004   r.d. Ergaenzung fuer Borland C++ Builder
-    30.08.2004   -rs  TRACE5 eingefügt
-    23.12.2005   d.k. Definitions for IAR compiler
-
-    $Id: global.h,v 1.6 2008/11/07 13:55:56 D.Krueger Exp $
-
-****************************************************************************/
-
-#ifndef _GLOBAL_H_
-#define _GLOBAL_H_
-
-
-#define TRACE  printk
-
-// --- logic types ---
-#ifndef BOOL
-#define BOOL unsigned char
-#endif
-
-// --- alias types ---
-#ifndef TRUE
-#define TRUE  0xFF
-#endif
-#ifndef FALSE
-#define FALSE 0x00
-#endif
-#ifndef _TIME_OF_DAY_DEFINED_
-typedef struct {
-	unsigned long int m_dwMs;
-	unsigned short int m_wDays;
-
-} tTimeOfDay;
-
-#define _TIME_OF_DAY_DEFINED_
-
-#endif
-
-//---------------------------------------------------------------------------
-//  Definition von TRACE
-//---------------------------------------------------------------------------
-
-#ifndef NDEBUG
-
-#ifndef TRACE0
-#define TRACE0(p0)                      TRACE(p0)
-#endif
-
-#ifndef TRACE1
-#define TRACE1(p0, p1)                  TRACE(p0, p1)
-#endif
-
-#ifndef TRACE2
-#define TRACE2(p0, p1, p2)              TRACE(p0, p1, p2)
-#endif
-
-#ifndef TRACE3
-#define TRACE3(p0, p1, p2, p3)          TRACE(p0, p1, p2, p3)
-#endif
-
-#ifndef TRACE4
-#define TRACE4(p0, p1, p2, p3, p4)      TRACE(p0, p1, p2, p3, p4)
-#endif
-
-#ifndef TRACE5
-#define TRACE5(p0, p1, p2, p3, p4, p5)  TRACE(p0, p1, p2, p3, p4, p5)
-#endif
-
-#ifndef TRACE6
-#define TRACE6(p0, p1, p2, p3, p4, p5, p6)  TRACE(p0, p1, p2, p3, p4, p5, p6)
-#endif
-
-#else
-
-#ifndef TRACE0
-#define TRACE0(p0)
-#endif
-
-#ifndef TRACE1
-#define TRACE1(p0, p1)
-#endif
-
-#ifndef TRACE2
-#define TRACE2(p0, p1, p2)
-#endif
-
-#ifndef TRACE3
-#define TRACE3(p0, p1, p2, p3)
-#endif
-
-#ifndef TRACE4
-#define TRACE4(p0, p1, p2, p3, p4)
-#endif
-
-#ifndef TRACE5
-#define TRACE5(p0, p1, p2, p3, p4, p5)
-#endif
-
-#ifndef TRACE6
-#define TRACE6(p0, p1, p2, p3, p4, p5, p6)
-#endif
-
-#endif
-
-//---------------------------------------------------------------------------
-//  definition of ASSERT
-//---------------------------------------------------------------------------
-
-#ifndef ASSERT
-#define ASSERT(p)
-#endif
-
-//---------------------------------------------------------------------------
-//  SYS TEC extensions
-//---------------------------------------------------------------------------
-
-// This macro doesn't print out C-file and line number of the failed assertion
-// but a string, which exactly names the mistake.
-#ifndef NDEBUG
-
-#define ASSERTMSG(expr,string)  if (!(expr)) {\
-                                        PRINTF0 ("Assertion failed: " string );\
-                                        while (1);}
-#else
-#define ASSERTMSG(expr,string)
-#endif
-
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _GLOBAL_H_
-
-// Please keep an empty line at the end of this file.
diff --git a/drivers/staging/epl/kernel/EplDllk.h b/drivers/staging/epl/kernel/EplDllk.h
deleted file mode 100644
index a97920a..0000000
--- a/drivers/staging/epl/kernel/EplDllk.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for kernelspace DLL 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: EplDllk.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/08 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_DLLK_H_
-#define _EPL_DLLK_H_
-
-#include "../EplDll.h"
-#include "../EplEvent.h"
-
-typedef tEplKernel(*tEplDllkCbAsync) (tEplFrameInfo * pFrameInfo_p);
-
-typedef struct {
-	u8 m_be_abSrcMac[6];
-
-} tEplDllkInitParam;
-
-// forward declaration
-struct _tEdrvTxBuffer;
-
-struct _tEplDllkNodeInfo {
-	struct _tEplDllkNodeInfo *m_pNextNodeInfo;
-	struct _tEdrvTxBuffer *m_pPreqTxBuffer;
-	unsigned int m_uiNodeId;
-	u32 m_dwPresTimeout;
-	unsigned long m_ulDllErrorEvents;
-	tEplNmtState m_NmtState;
-	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;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p);
-
-tEplKernel EplDllkDelInstance(void);
-
-// called before NMT_GS_COMMUNICATING will be entered to configure fixed parameters
-tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p);
-
-// set identity of local node (may be at any time, e.g. in case of hostname change)
-tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p);
-
-// process internal events and do work that cannot be done in interrupt-context
-tEplKernel EplDllkProcess(tEplEvent * pEvent_p);
-
-// registers handler for non-EPL frames
-tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p);
-
-// deregisters handler for non-EPL frames
-tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p);
-
-// register C_DLL_MULTICAST_ASND in ethernet driver if any AsndServiceId is registered
-tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p,
-					 tEplDllAsndFilter Filter_p);
-
-// creates the buffer for a Tx frame and registers it to the ethernet driver
-tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
-				tEplFrame ** ppFrame_p,
-				unsigned int *puiFrameSize_p,
-				tEplMsgType MsgType_p,
-				tEplDllAsndServiceId ServiceId_p);
-
-tEplKernel EplDllkDeleteTxFrame(unsigned int uiHandle_p);
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p);
-
-tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p);
-
-tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p);
-
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p);
-
-tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p);
-
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-#endif // #ifndef _EPL_DLLK_H_
diff --git a/drivers/staging/epl/kernel/EplDllkCal.h b/drivers/staging/epl/kernel/EplDllkCal.h
deleted file mode 100644
index ddec1d5..0000000
--- a/drivers/staging/epl/kernel/EplDllkCal.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for kernelspace DLL Communication Abstraction Layer 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: EplDllkCal.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/11/13 17:13:09 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/13 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_DLLKCAL_H_
-#define _EPL_DLLKCAL_H_
-
-#include "../EplDll.h"
-#include "../EplEvent.h"
-
-typedef struct {
-	unsigned long m_ulCurTxFrameCountGen;
-	unsigned long m_ulCurTxFrameCountNmt;
-	unsigned long m_ulCurRxFrameCount;
-	unsigned long m_ulMaxTxFrameCountGen;
-	unsigned long m_ulMaxTxFrameCountNmt;
-	unsigned long m_ulMaxRxFrameCount;
-
-} tEplDllkCalStatistics;
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-tEplKernel EplDllkCalAddInstance(void);
-
-tEplKernel EplDllkCalDelInstance(void);
-
-tEplKernel EplDllkCalAsyncGetTxCount(tEplDllAsyncReqPriority * pPriority_p,
-				     unsigned int *puiCount_p);
-tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
-				     unsigned int *puiFrameSize_p,
-				     tEplDllAsyncReqPriority Priority_p);
-// only frames with registered AsndServiceIds are passed to CAL
-tEplKernel EplDllkCalAsyncFrameReceived(tEplFrameInfo * pFrameInfo_p);
-
-tEplKernel EplDllkCalAsyncSend(tEplFrameInfo * pFrameInfo_p,
-			       tEplDllAsyncReqPriority Priority_p);
-
-tEplKernel EplDllkCalAsyncClearBuffer(void);
-
-tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics);
-
-tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-tEplKernel EplDllkCalAsyncClearQueues(void);
-
-tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, u8 bSoaFlag1_p);
-
-tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p,
-					unsigned int *puiNodeId_p);
-
-tEplKernel EplDllkCalAsyncSetPendingRequests(unsigned int uiNodeId_p,
-					     tEplDllAsyncReqPriority
-					     AsyncReqPrio_p,
-					     unsigned int uiCount_p);
-
-#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
-
-#endif // #ifndef _EPL_DLLKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplErrorHandlerk.h b/drivers/staging/epl/kernel/EplErrorHandlerk.h
deleted file mode 100644
index 185b597..0000000
--- a/drivers/staging/epl/kernel/EplErrorHandlerk.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for kernel error handler 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: EplErrorHandlerk.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/10/02 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_ERRORHANDLERK_H_
-#define _EPL_ERRORHANDLERK_H_
-
-#include "../EplEvent.h"
-
-// init function
-tEplKernel EplErrorHandlerkInit(void);
-
-// add instance
-tEplKernel EplErrorHandlerkAddInstance(void);
-
-// delete instance
-tEplKernel EplErrorHandlerkDelInstance(void);
-
-// processes error events
-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
deleted file mode 100644
index 0c2a60f..0000000
--- a/drivers/staging/epl/kernel/EplEventk.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for kernel event 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: EplEventk.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/12 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_EVENTK_H_
-#define _EPL_EVENTK_H_
-
-#include "../EplEvent.h"
-
-// init function
-tEplKernel EplEventkInit(tEplSyncCb fpSyncCb);
-
-// add instance
-tEplKernel EplEventkAddInstance(tEplSyncCb fpSyncCb);
-
-// delete instance
-tEplKernel EplEventkDelInstance(void);
-
-// Kernelthread that dispatches events in kernelspace
-tEplKernel EplEventkProcess(tEplEvent *pEvent_p);
-
-// post events from kernelspace
-tEplKernel EplEventkPost(tEplEvent *pEvent_p);
-
-// post errorevents from kernelspace
-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
deleted file mode 100644
index 5dc8a37..0000000
--- a/drivers/staging/epl/kernel/EplNmtk.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for NMT-Kernelspace-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: EplNmtk.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLNMTK_H_
-#define _EPLNMTK_H_
-
-#include "../EplNmt.h"
-#include "EplEventk.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-
-tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-
-tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-
-tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p);
-
-tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-
-#endif // #ifndef _EPLNMTK_H_
diff --git a/drivers/staging/epl/kernel/EplObdk.h b/drivers/staging/epl/kernel/EplObdk.h
deleted file mode 100644
index 78c4d96..0000000
--- a/drivers/staging/epl/kernel/EplObdk.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for Epl-Obd-Kernel-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: EplObdk.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.8 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/19 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLOBDK_H_
-#define _EPLOBDK_H_
-
-#include "../EplObd.h"
-
-extern u8 abEplObdTrashObject_g[8];
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
-// ---------------------------------------------------------------------
-tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			    unsigned int uiSubIndex_p,
-			    void *pSrcData_p, tEplObdSize Size_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			   unsigned int uiSubIndex_p,
-			   void *pDstData_p, tEplObdSize *pSize_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
-			      tEplObdDir Direction_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p);
-
-// ---------------------------------------------------------------------
-void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			     unsigned int uiSubIndex_p);
-// ---------------------------------------------------------------------
-tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p);
-
-// ---------------------------------------------------------------------
-void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
-			tEplObdType Type_p, tEplObdSize ObdSize_p);
-
-// ---------------------------------------------------------------------
-tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			      unsigned int uiSubIndex_p);
-
-// ---------------------------------------------------------------------
-unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiNodeId_p,
-			   tEplObdNodeIdType NodeIdType_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			     unsigned int uiSubIndex_p, BOOL *pfEntryNumerical);
-// ---------------------------------------------------------------------
-tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-				  unsigned int uiSubIndex_p,
-				  void *pSrcData_p,
-				  tEplObdSize Size_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			       unsigned int uiSubIndex_p,
-			       void *pDstData_p,
-			       tEplObdSize *pSize_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
-			       unsigned int uiSubIndex_p,
-			       tEplObdAccess *pAccessTyp_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)
-
-#endif // #ifndef _EPLOBDK_H_
diff --git a/drivers/staging/epl/kernel/EplPdok.h b/drivers/staging/epl/kernel/EplPdok.h
deleted file mode 100644
index 24bfc3f..0000000
--- a/drivers/staging/epl/kernel/EplPdok.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for kernel PDO 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: EplPdok.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/06/23 14:56:33 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_PDOK_H_
-#define _EPL_PDOK_H_
-
-#include "../EplPdo.h"
-#include "../EplEvent.h"
-#include "../EplDll.h"
-
-// process events from queue (PDOs/frames and SoA for synchronization)
-tEplKernel EplPdokProcess(tEplEvent * pEvent_p);
-
-// copies RPDO to event queue for processing
-// is called by DLL in NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL
-// PDO needs not to be valid
-tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p);
-
-// posts pointer and size of TPDO to event queue
-// is called by DLL in NMT_CS_PRE_OPERATIONAL_2,
-//     NMT_CS_READY_TO_OPERATE and NMT_CS_OPERATIONAL
-tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p);
-
-// posts SoA event to queue
-tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p);
-
-tEplKernel EplPdokAddInstance(void);
-
-tEplKernel EplPdokDelInstance(void);
-
-#endif // #ifndef _EPL_PDOK_H_
diff --git a/drivers/staging/epl/kernel/EplPdokCal.h b/drivers/staging/epl/kernel/EplPdokCal.h
deleted file mode 100644
index 8a31edf..0000000
--- a/drivers/staging/epl/kernel/EplPdokCal.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for kernel PDO Communication Abstraction Layer 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: EplPdokCal.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/26 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_PDOKCAL_H_
-#define _EPL_PDOKCAL_H_
-
-#include "../EplInc.h"
-
-tEplKernel EplPdokCalAddInstance(void);
-
-tEplKernel EplPdokCalDelInstance(void);
-
-// sets flag for validity of TPDOs in shared memory
-tEplKernel EplPdokCalSetTpdosValid(BOOL fValid_p);
-
-// gets flag for validity of TPDOs from shared memory
-tEplKernel EplPdokCalAreTpdosValid(BOOL * pfValid_p);
-
-#endif // #ifndef _EPL_PDOKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplTimerHighResk.h b/drivers/staging/epl/kernel/EplTimerHighResk.h
deleted file mode 100644
index a2124ee..0000000
--- a/drivers/staging/epl/kernel/EplTimerHighResk.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for EPL high resolution Timermodule
-
-  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: EplTimerHighResk.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/09/29 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLTIMERHIGHRESK_H_
-#define _EPLTIMERHIGHRESK_H_
-
-#include "../EplTimer.h"
-
-tEplKernel EplTimerHighReskInit(void);
-
-tEplKernel EplTimerHighReskAddInstance(void);
-
-tEplKernel EplTimerHighReskDelInstance(void);
-
-tEplKernel EplTimerHighReskSetTimerNs(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 EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p);
-
-#endif // #ifndef _EPLTIMERHIGHRESK_H_
diff --git a/drivers/staging/epl/kernel/EplTimerk.h b/drivers/staging/epl/kernel/EplTimerk.h
deleted file mode 100644
index 47c5f47..0000000
--- a/drivers/staging/epl/kernel/EplTimerk.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for EPL Kernel-Timermodule
-
-  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: EplTimerk.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/07/06 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLTIMERK_H_
-#define _EPLTIMERK_H_
-
-#include "../EplTimer.h"
-#include "../user/EplEventu.h"
-
-#if EPL_TIMER_USE_USER != FALSE
-#include "../user/EplTimeru.h"
-#endif
-
-
-#if EPL_TIMER_USE_USER != FALSE
-#define EplTimerkInit           EplTimeruInit
-#define EplTimerkAddInstance    EplTimeruAddInstance
-#define EplTimerkDelInstance    EplTimeruDelInstance
-#define EplTimerkSetTimerMs     EplTimeruSetTimerMs
-#define EplTimerkModifyTimerMs  EplTimeruModifyTimerMs
-#define EplTimerkDeleteTimer    EplTimeruDeleteTimer
-#endif
-
-#if EPL_TIMER_USE_USER == FALSE
-tEplKernel EplTimerkInit(void);
-
-tEplKernel EplTimerkAddInstance(void);
-
-tEplKernel EplTimerkDelInstance(void);
-
-tEplKernel EplTimerkSetTimerMs(tEplTimerHdl *pTimerHdl_p,
-			       unsigned long ulTime_p,
-			       tEplTimerArg Argument_p);
-
-tEplKernel EplTimerkModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
-				  unsigned long ulTime_p,
-				  tEplTimerArg Argument_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
deleted file mode 100644
index 4a42cce..0000000
--- a/drivers/staging/epl/kernel/VirtualEthernet.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for virtual ethernet driver 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: VirtualEthernet.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                KEIL uVision 2
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/09/19 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_VETH_H_
-#define _EPL_VETH_H_
-
-#include "EplDllk.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-
-tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p);
-
-tEplKernel VEthDelInstance(void);
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-
-#endif // #ifndef _EPL_VETH_H_
diff --git a/drivers/staging/epl/proc_fs.c b/drivers/staging/epl/proc_fs.c
deleted file mode 100644
index 9ccf079..0000000
--- a/drivers/staging/epl/proc_fs.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  proc fs entry with diagnostic information under Linux
-
-  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: proc_fs.c,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.13 $  $Date: 2008/11/07 13:55:56 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GNU
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/07/31 d.k.:   start of implementation
-
-****************************************************************************/
-
-#include "kernel/EplNmtk.h"
-#include "user/EplNmtu.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-#include "user/EplNmtMnu.h"
-#endif
-
-#include "kernel/EplDllkCal.h"
-
-//#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 <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/atomic.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-
-#ifdef CONFIG_COLDFIRE
-#include <asm/coldfire.h>
-#include "fec.h"
-#endif
-
-#include "proc_fs.h"
-
-/***************************************************************************/
-/*                                                                         */
-/*                                                                         */
-/*          G L O B A L   D E F I N I T I O N S                            */
-/*                                                                         */
-/*                                                                         */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-#ifndef EPL_PROC_DEV_NAME
-#define EPL_PROC_DEV_NAME    "epl"
-#endif
-
-#ifndef DBG_TRACE_POINTS
-#define DBG_TRACE_POINTS    23	// # of supported debug trace points
-#endif
-
-#ifndef DBG_TRACE_VALUES
-#define DBG_TRACE_VALUES    24	// # of supported debug trace values (size of circular buffer)
-#endif
-
-//---------------------------------------------------------------------------
-// modul global types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local vars
-//---------------------------------------------------------------------------
-
-#ifdef _DBG_TRACE_POINTS_
-atomic_t aatmDbgTracePoint_l[DBG_TRACE_POINTS];
-u32 adwDbgTraceValue_l[DBG_TRACE_VALUES];
-u32 dwDbgTraceValueOld_l;
-unsigned int uiDbgTraceValuePos_l;
-spinlock_t spinlockDbgTraceValue_l;
-unsigned long ulDbTraceValueFlags_l;
-#endif
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-static int EplLinProcRead(char *pcBuffer_p, char **ppcStart_p, off_t Offset_p,
-			  int nBufferSize_p, int *pEof_p, void *pData_p);
-static int EplLinProcWrite(struct file *file, const char __user * buffer,
-			   unsigned long count, void *data);
-
-void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
-void TgtDbgPostTraceValue(u32 dwTraceValue_p);
-
-extern u32 EplIdentuGetRunningRequests(void);
-
-//=========================================================================//
-//                                                                         //
-//          P U B L I C   F U N C T I O N S                                //
-//                                                                         //
-//=========================================================================//
-
-tEplKernel EplLinProcInit(void)
-{
-	struct proc_dir_entry *pProcDirEntry;
-	pProcDirEntry = create_proc_entry(EPL_PROC_DEV_NAME, S_IRUGO, NULL);
-	if (pProcDirEntry != NULL) {
-		pProcDirEntry->read_proc = EplLinProcRead;
-		pProcDirEntry->write_proc = EplLinProcWrite;
-		pProcDirEntry->data = NULL;	// device number or something else
-
-	} else {
-		return kEplNoResource;
-	}
-
-#ifdef _DBG_TRACE_POINTS_
-	// initialize spinlock and circular buffer position
-	spin_lock_init(&spinlockDbgTraceValue_l);
-	uiDbgTraceValuePos_l = 0;
-	dwDbgTraceValueOld_l = 0;
-#endif
-
-	return kEplSuccessful;
-}
-
-tEplKernel EplLinProcFree(void)
-{
-	remove_proc_entry(EPL_PROC_DEV_NAME, NULL);
-
-	return kEplSuccessful;
-}
-
-//---------------------------------------------------------------------------
-//  Target specific event signaling (FEC Tx-/Rx-Interrupt, used by Edrv)
-//---------------------------------------------------------------------------
-
-#ifdef _DBG_TRACE_POINTS_
-void TgtDbgSignalTracePoint(u8 bTracePointNumber_p)
-{
-
-	if (bTracePointNumber_p >=
-	    (sizeof(aatmDbgTracePoint_l) / sizeof(aatmDbgTracePoint_l[0]))) {
-		goto Exit;
-	}
-
-	atomic_inc(&aatmDbgTracePoint_l[bTracePointNumber_p]);
-
-      Exit:
-
-	return;
-
-}
-
-void TgtDbgPostTraceValue(u32 dwTraceValue_p)
-{
-
-	spin_lock_irqsave(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
-	if (dwDbgTraceValueOld_l != dwTraceValue_p) {
-		adwDbgTraceValue_l[uiDbgTraceValuePos_l] = dwTraceValue_p;
-		uiDbgTraceValuePos_l =
-		    (uiDbgTraceValuePos_l + 1) % DBG_TRACE_VALUES;
-		dwDbgTraceValueOld_l = dwTraceValue_p;
-	}
-	spin_unlock_irqrestore(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
-
-	return;
-
-}
-#endif
-
-//---------------------------------------------------------------------------
-//  Read function for PROC-FS read access
-//---------------------------------------------------------------------------
-
-static int EplLinProcRead(char *pcBuffer_p,
-			  char **ppcStart_p,
-			  off_t Offset_p,
-			  int nBufferSize_p, int *pEof_p, void *pData_p)
-{
-
-	int nSize;
-	int Eof;
-	tEplDllkCalStatistics *pDllkCalStats;
-
-	nSize = 0;
-	Eof = 0;
-
-	// count calls of this function
-#ifdef _DBG_TRACE_POINTS_
-	TgtDbgSignalTracePoint(0);
-#endif
-
-	//---------------------------------------------------------------
-	// generate static information
-	//---------------------------------------------------------------
-
-	// ---- Driver information ----
-	nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-			  "%s    %s    (c) 2006 %s\n",
-			  EPL_PRODUCT_NAME, EPL_PRODUCT_VERSION,
-			  EPL_PRODUCT_MANUFACTURER);
-
-	//---------------------------------------------------------------
-	// generate process information
-	//---------------------------------------------------------------
-
-	// ---- EPL state ----
-	nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-			  "NMT state:                  0x%04X\n",
-			  (u16) EplNmtkGetNmtState());
-
-	EplDllkCalGetStatistics(&pDllkCalStats);
-
-	nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-			  "CurAsyncTxGen=%lu CurAsyncTxNmt=%lu CurAsyncRx=%lu\nMaxAsyncTxGen=%lu MaxAsyncTxNmt=%lu MaxAsyncRx=%lu\n",
-			  pDllkCalStats->m_ulCurTxFrameCountGen,
-			  pDllkCalStats->m_ulCurTxFrameCountNmt,
-			  pDllkCalStats->m_ulCurRxFrameCount,
-			  pDllkCalStats->m_ulMaxTxFrameCountGen,
-			  pDllkCalStats->m_ulMaxTxFrameCountNmt,
-			  pDllkCalStats->m_ulMaxRxFrameCount);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-	// fetch running IdentRequests
-	nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-			  "running IdentRequests:      0x%08X\n",
-			  EplIdentuGetRunningRequests());
-
-	// fetch state of NmtMnu module
-	{
-		unsigned int uiMandatorySlaveCount;
-		unsigned int uiSignalSlaveCount;
-		u16 wFlags;
-
-		EplNmtMnuGetDiagnosticInfo(&uiMandatorySlaveCount,
-					   &uiSignalSlaveCount, &wFlags);
-
-		nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-				  "MN  MandSlaveCount: %u  SigSlaveCount: %u  Flags: 0x%X\n",
-				  uiMandatorySlaveCount, uiSignalSlaveCount,
-				  wFlags);
-
-	}
-#endif
-
-	// ---- FEC state ----
-#ifdef CONFIG_COLDFIRE
-	{
-		// Receive the base address
-		unsigned long base_addr;
-#if (EDRV_USED_ETH_CTRL == 0)
-		// Set the base address of FEC0
-		base_addr = FEC_BASE_ADDR_FEC0;
-#else
-		// Set the base address of FEC1
-		base_addr = FEC_BASE_ADDR_FEC1;
-#endif
-
-		nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-				  "FEC_ECR = 0x%08X FEC_EIR = 0x%08X FEC_EIMR = 0x%08X\nFEC_TCR = 0x%08X FECTFSR = 0x%08X FECRFSR = 0x%08X\n",
-				  FEC_ECR(base_addr), FEC_EIR(base_addr),
-				  FEC_EIMR(base_addr), FEC_TCR(base_addr),
-				  FEC_FECTFSR(base_addr),
-				  FEC_FECRFSR(base_addr));
-	}
-#endif
-
-	// ---- DBG: TracePoints ----
-#ifdef _DBG_TRACE_POINTS_
-	{
-		int nNum;
-
-		nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-				  "DbgTracePoints:\n");
-		for (nNum = 0;
-		     nNum < (sizeof(aatmDbgTracePoint_l) / sizeof(atomic_t));
-		     nNum++) {
-			nSize +=
-			    snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-				     " TracePoint[%2d]: %d\n", (int)nNum,
-				     atomic_read(&aatmDbgTracePoint_l[nNum]));
-		}
-
-		nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-				  "DbgTraceValues:\n");
-		for (nNum = 0; nNum < DBG_TRACE_VALUES; nNum++) {
-			if (nNum == uiDbgTraceValuePos_l) {	// next value will be stored at that position
-				nSize +=
-				    snprintf(pcBuffer_p + nSize,
-					     nBufferSize_p - nSize, "*%08lX",
-					     adwDbgTraceValue_l[nNum]);
-			} else {
-				nSize +=
-				    snprintf(pcBuffer_p + nSize,
-					     nBufferSize_p - nSize, " %08lX",
-					     adwDbgTraceValue_l[nNum]);
-			}
-			if ((nNum & 0x00000007) == 0x00000007) {	// 8 values printed -> end of line reached
-				nSize +=
-				    snprintf(pcBuffer_p + nSize,
-					     nBufferSize_p - nSize, "\n");
-			}
-		}
-		if ((nNum & 0x00000007) != 0x00000007) {	// number of values printed is not a multiple of 8 -> print new line
-			nSize +=
-			    snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
-				     "\n");
-		}
-	}
-#endif
-
-	Eof = 1;
-	goto Exit;
-
-      Exit:
-
-	*pEof_p = Eof;
-
-	return (nSize);
-
-}
-
-//---------------------------------------------------------------------------
-//  Write function for PROC-FS write access
-//---------------------------------------------------------------------------
-
-static int EplLinProcWrite(struct file *file, const char __user * buffer,
-			   unsigned long count, void *data)
-{
-	char abBuffer[count + 1];
-	int iErr;
-	int iVal = 0;
-	tEplNmtEvent NmtEvent;
-
-	if (count > 0) {
-		iErr = copy_from_user(abBuffer, buffer, count);
-		if (iErr != 0) {
-			return count;
-		}
-		abBuffer[count] = '\0';
-
-		iErr = sscanf(abBuffer, "%i", &iVal);
-	}
-	if ((iVal <= 0) || (iVal > 0x2F)) {
-		NmtEvent = kEplNmtEventSwReset;
-	} else {
-		NmtEvent = (tEplNmtEvent) iVal;
-	}
-	// execute specified NMT command on write access of /proc/epl
-	EplNmtuNmtEvent(NmtEvent);
-
-	return count;
-}
diff --git a/drivers/staging/epl/proc_fs.h b/drivers/staging/epl/proc_fs.h
deleted file mode 100644
index 0586f49..0000000
--- a/drivers/staging/epl/proc_fs.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:  interface for proc fs entry under Linux
-
-  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: proc_fs.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:33 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GNU
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/07/31 d.k.:   start of implementation
-
-****************************************************************************/
-
-#ifndef _EPLPROCFS_H_
-#define _EPLPROCFS_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-tEplKernel EplLinProcInit(void);
-tEplKernel EplLinProcFree(void);
-
-#endif // #ifndef _EPLPROCFS_H_
diff --git a/drivers/staging/epl/user/EplCfgMau.h b/drivers/staging/epl/user/EplCfgMau.h
deleted file mode 100644
index 4ac770f..0000000
--- a/drivers/staging/epl/user/EplCfgMau.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for Epl Configuration Manager 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: EplCfgMau.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.4 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                VC7
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/07/14 k.t.:   start of the implementation
-                     -> based on CANopen CfgMa-Modul (CANopen version 5.34)
-
-****************************************************************************/
-
-#ifndef _EPLCFGMA_H_
-#define _EPLCFGMA_H_
-
-#include "../EplInc.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
-
-#include "EplObdu.h"
-#include "EplSdoComu.h"
-
-//define max number of timeouts for configuration of 1 device
-#define EPL_CFGMA_MAX_TIMEOUT   3
-
-//callbackfunction, called if configuration is finished
-typedef void (* tfpEplCfgMaCb)(unsigned int uiNodeId_p,
-			       tEplKernel Errorstate_p);
-
-//State for configuartion manager Statemachine
-typedef enum {
-	// general states
-	kEplCfgMaIdle = 0x0000,	// Configurationsprocess
-	// is idle
-	kEplCfgMaWaitForSdocEvent = 0x0001,	// wait until the last
-	// SDOC is finisched
-	kEplCfgMaSkipMappingSub0 = 0x0002,	// write Sub0 of mapping
-	// parameter with 0
-
-	kEplCfgMaFinished = 0x0004	// configuartion is finished
-} tEplCfgState;
-
-typedef enum {
-	kEplCfgMaDcfTypSystecSeg = 0x00,
-	kEplCfgMaDcfTypConDcf = 0x01,
-	kEplCfgMaDcfTypDcf = 0x02,	// not supported
-	kEplCfgMaDcfTypXdc = 0x03	// not supported
-} tEplCfgMaDcfTyp;
-
-typedef enum {
-	kEplCfgMaCommon = 0,	// all other index
-	kEplCfgMaPdoComm = 1,	// communication index
-	kEplCfgMaPdoMapp = 2,	// mapping index
-	kEplCfgMaPdoCommAfterMapp = 3,	// write PDO Cob-Id after mapping subindex 0(set PDO valid)
-
-} tEplCfgMaIndexType;
-
-//bitcoded answer about the last sdo transfer saved in m_SdocState
-// also used to singal start of the State Maschine
-typedef enum {
-	kEplCfgMaSdocBusy = 0x00,	// SDOC activ
-	kEplCfgMaSdocReady = 0x01,	// SDOC finished
-	kEplCfgMaSdocTimeout = 0x02,	// SDOC Timeout
-	kEplCfgMaSdocAbortReceived = 0x04,	// SDOC Abort, see Abortcode
-	kEplCfgMaSdocStart = 0x08	// start State Mschine
-} tEplSdocState;
-
-//internal structure (instancetable for modul configuration manager)
-typedef struct {
-	tEplCfgState m_CfgState;	// state of the configuration state maschine
-	tEplSdoComConHdl m_SdoComConHdl;	// handle for sdo connection
-	u32 m_dwLastAbortCode;
-	unsigned int m_uiLastIndex;	// last index of configuration, to compair with actual index
-	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
-	u32 m_dwNumValueCopy;	// numeric values are copied in this variable
-	unsigned int m_uiPdoNodeId;	// buffer for PDO node id
-	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
-	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
-	u16 m_wTimeOutCnt;	// Timeout Counter, break configuration is
-	// m_wTimeOutCnt == CFGMA_MAX_TIMEOUT
-
-} tEplCfgMaNode;
-
-//---------------------------------------------------------------------------
-// Function:    EplCfgMaInit()
-//
-// Description: Function creates first instance of Configuration Manager
-//
-// Parameters:
-//
-// Returns:     tEplKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel EplCfgMaInit(void);
-
-//---------------------------------------------------------------------------
-// Function:    EplCfgMaAddInstance()
-//
-// Description: Function creates additional instance of Configuration Manager
-//
-// Parameters:
-//
-// Returns:     tEplKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel EplCfgMaAddInstance(void);
-
-//---------------------------------------------------------------------------
-// Function:    EplCfgMaDelInstance()
-//
-// Description: Function delete instance of Configuration Manager
-//
-// Parameters:
-//
-// Returns:     tEplKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel plCfgMaDelInstance(void);
-
-//---------------------------------------------------------------------------
-// Function:    EplCfgMaStartConfig()
-//
-// Description: Function starts the configuration process
-//              initialization the statemachine for CfgMa- process
-//
-// 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 u8 -> for future use
-//              DcfType_p               = type of the DCF
-//
-// Returns:     tCopKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel EplCfgMaStartConfig(unsigned int uiNodeId_p,
-			       u8 * pbConcise_p,
-			       tfpEplCfgMaCb fpCfgMaCb_p,
-			       tEplObdSize SizeOfConcise_p,
-			       tEplCfgMaDcfTyp DcfType_p);
-
-//---------------------------------------------------------------------------
-// Function:    CfgMaStartConfigurationNode()
-//
-// Description: Function started the configuration process
-//              with the DCF from according OD-entry Subindex == bNodeId_p
-//
-// Parameters:  uiNodeId_p              = NodeId of the node to configure
-//              fpCfgMaCb_p             = pointer to callback function (should not be NULL)
-//              DcfType_p               = type of the DCF
-//
-// Returns:     tCopKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
-				   tfpEplCfgMaCb fpCfgMaCb_p,
-				   tEplCfgMaDcfTyp DcfType_p);
-
-//---------------------------------------------------------------------------
-// Function:    EplCfgMaStartConfigNodeDcf()
-//
-// Description: Function starts the configuration process
-//              and links the configuration data to the OD
-//
-// 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 u8 -> for future use
-//              DcfType_p               = type of the DCF
-//
-// Returns:     tCopKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
-				      u8 * pbConcise_p,
-				      tfpEplCfgMaCb fpCfgMaCb_p,
-				      tEplObdSize SizeOfConcise_p,
-				      tEplCfgMaDcfTyp DcfType_p);
-
-//---------------------------------------------------------------------------
-// Function:    EplCfgMaLinkDcf()
-//
-// Description: Function links the configuration data to the OD
-//
-// Parameters:  uiNodeId_p              = NodeId of the node to configure
-//              pbConcise_p             = pointer to DCF
-//              SizeOfConcise_p        = size of DCF in u8 -> for future use
-//              DcfType_p               = type of the DCF
-//
-// Returns:     tCopKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel EplCfgMaLinkDcf(unsigned int uiNodeId_p,
-			   u8 * pbConcise_p,
-			   tEplObdSize SizeOfConcise_p,
-			   tEplCfgMaDcfTyp DcfType_p);
-
-//---------------------------------------------------------------------------
-// Function:    EplCfgMaCheckDcf()
-//
-// Description: Function check if there is allready a configuration file linked
-//              to the OD (type is given by DcfType_p)
-//
-// Parameters:  uiNodeId_p              = NodeId
-//              DcfType_p               = type of the DCF
-//
-// Returns:     tCopKernel              = error code
-//---------------------------------------------------------------------------
-tEplKernel EplCfgMaCheckDcf(unsigned int uiNodeId_p, tEplCfgMaDcfTyp DcfType_p);
-
-#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
-
-#endif // _EPLCFGMA_H_
-
-// EOF
diff --git a/drivers/staging/epl/user/EplDllu.h b/drivers/staging/epl/user/EplDllu.h
deleted file mode 100644
index 890f837..0000000
--- a/drivers/staging/epl/user/EplDllu.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for userspace DLL module for asynchronous communication
-
-  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: EplDllu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/20 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_DLLU_H_
-#define _EPL_DLLU_H_
-
-#include "../EplDll.h"
-
-typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-
-tEplKernel EplDlluAddInstance(void);
-
-tEplKernel EplDlluDelInstance(void);
-
-tEplKernel EplDlluRegAsndService(tEplDllAsndServiceId ServiceId_p,
-				 tEplDlluCbAsnd pfnDlluCbAsnd_p,
-				 tEplDllAsndFilter Filter_p);
-
-tEplKernel EplDlluAsyncSend(tEplFrameInfo * pFrameInfo_p,
-			    tEplDllAsyncReqPriority Priority_p);
-
-// processes asynch frames
-tEplKernel EplDlluProcess(tEplFrameInfo * pFrameInfo_p);
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
-
-#endif // #ifndef _EPL_DLLU_H_
diff --git a/drivers/staging/epl/user/EplDlluCal.h b/drivers/staging/epl/user/EplDlluCal.h
deleted file mode 100644
index bc9126b..0000000
--- a/drivers/staging/epl/user/EplDlluCal.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for DLL Communication Abstraction Layer module in EPL user part
-
-  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: EplDlluCal.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/20 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_DLLUCAL_H_
-#define _EPL_DLLUCAL_H_
-
-#include "../EplDll.h"
-#include "../EplEvent.h"
-
-
-typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-tEplKernel EplDlluCalAddInstance(void);
-
-tEplKernel EplDlluCalDelInstance(void);
-
-tEplKernel EplDlluCalRegAsndService(tEplDllAsndServiceId ServiceId_p,
-				    tEplDlluCbAsnd pfnDlluCbAsnd_p,
-				    tEplDllAsndFilter Filter_p);
-
-tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo,
-			       tEplDllAsyncReqPriority Priority_p);
-
-tEplKernel EplDlluCalProcess(tEplEvent * pEvent_p);
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-tEplKernel EplDlluCalAddNode(tEplDllNodeInfo * pNodeInfo_p);
-
-tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p);
-
-tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p);
-
-tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
-				  unsigned int uiNodeId_p, u8 bSoaFlag1_p);
-
-#endif
-
-#endif // #ifndef _EPL_DLLUCAL_H_
diff --git a/drivers/staging/epl/user/EplEventu.h b/drivers/staging/epl/user/EplEventu.h
deleted file mode 100644
index ab85205..0000000
--- a/drivers/staging/epl/user/EplEventu.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for kernel event 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: EplEventu.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/12 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_EVENTU_H_
-#define _EPL_EVENTU_H_
-
-#include "../EplEvent.h"
-
-// init function
-tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
-
-// add instance
-tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p);
-
-// delete instance
-tEplKernel EplEventuDelInstance(void);
-
-// Task that dispatches events in userspace
-tEplKernel EplEventuProcess(tEplEvent * pEvent_p);
-
-// post events from userspace
-tEplKernel EplEventuPost(tEplEvent * pEvent_p);
-
-// post errorevents from userspace
-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
deleted file mode 100644
index 057c902..0000000
--- a/drivers/staging/epl/user/EplIdentu.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for Identu-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: EplIdentu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/11/15 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLIDENTU_H_
-#define _EPLIDENTU_H_
-
-#include "../EplDll.h"
-
-typedef tEplKernel(* tEplIdentuCbResponse) (unsigned int uiNodeId_p,
-						   tEplIdentResponse *
-						   pIdentResponse_p);
-
-tEplKernel EplIdentuInit(void);
-
-tEplKernel EplIdentuAddInstance(void);
-
-tEplKernel EplIdentuDelInstance(void);
-
-tEplKernel EplIdentuReset(void);
-
-tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
-				     tEplIdentResponse **ppIdentResponse_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
deleted file mode 100644
index ca9eb43..0000000
--- a/drivers/staging/epl/user/EplLedu.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for status and error LED user part 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: EplLedu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.1 $  $Date: 2008/11/17 16:40:39 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2008/11/17 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLLEDU_H_
-#define _EPLLEDU_H_
-
-#include "../EplLed.h"
-#include "../EplNmt.h"
-#include "EplEventu.h"
-
-typedef tEplKernel(* tEplLeduStateChangeCallback) (tEplLedType LedType_p,
-							  BOOL fOn_p);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-
-tEplKernel EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
-
-tEplKernel EplLeduAddInstance(tEplLeduStateChangeCallback pfnCbStateChange_p);
-
-tEplKernel EplLeduDelInstance(void);
-
-tEplKernel EplLeduCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
-
-tEplKernel EplLeduProcessEvent(tEplEvent * pEplEvent_p);
-
-#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-
-#endif // #ifndef _EPLLEDU_H_
diff --git a/drivers/staging/epl/user/EplNmtCnu.h b/drivers/staging/epl/user/EplNmtCnu.h
deleted file mode 100644
index 7d23029..0000000
--- a/drivers/staging/epl/user/EplNmtCnu.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for NMT-CN-Userspace-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: EplNmtCnu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLNMTCNU_H_
-#define _EPLNMTCNU_H_
-
-#include "EplNmtu.h"
-#include "../EplDll.h"
-#include "../EplFrame.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-
-tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p);
-
-tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p);
-
-tEplKernel EplNmtCnuDelInstance(void);
-
-tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p, tEplNmtCommand NmtCommand_p);
-
-tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p);
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-
-#endif // #ifndef _EPLNMTCNU_H_
diff --git a/drivers/staging/epl/user/EplNmtMnu.h b/drivers/staging/epl/user/EplNmtMnu.h
deleted file mode 100644
index 5e5e0cd..0000000
--- a/drivers/staging/epl/user/EplNmtMnu.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for NMT-MN-Userspace-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: EplNmtMnu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLNMTMNU_H_
-#define _EPLNMTMNU_H_
-
-#include "EplNmtu.h"
-
-typedef tEplKernel(* tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p,
-					     tEplNmtNodeEvent NodeEvent_p,
-					     tEplNmtState NmtState_p,
-					     u16 wErrorCode_p,
-					     BOOL fMandatory_p);
-
-typedef tEplKernel(* tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p,
-					     tEplNmtState NmtState_p,
-					     u16 wErrorCode_p);
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-
-tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
-			 tEplNmtMnuCbBootEvent pfnCbBootEvent_p);
-
-tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
-				tEplNmtMnuCbBootEvent pfnCbBootEvent_p);
-
-tEplKernel EplNmtMnuDelInstance(void);
-
-tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p);
-
-tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
-				   tEplNmtCommand NmtCommand_p);
-
-tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
-				       tEplNmtNodeCommand NodeCommand_p);
-
-tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
-					    NmtStateChange_p);
-
-tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
-
-tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int
-					     *puiMandatorySlaveCount_p,
-					     unsigned int
-					     *puiSignalSlaveCount_p,
-					     u16 * pwFlags_p);
-
-#endif
-
-#endif // #ifndef _EPLNMTMNU_H_
diff --git a/drivers/staging/epl/user/EplNmtu.h b/drivers/staging/epl/user/EplNmtu.h
deleted file mode 100644
index c1fca80..0000000
--- a/drivers/staging/epl/user/EplNmtu.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for NMT-Userspace-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: EplNmtu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/09 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLNMTU_H_
-#define _EPLNMTU_H_
-
-#include "../EplNmt.h"
-#include "EplEventu.h"
-
-// nmt commands
-typedef enum {
-	// requestable ASnd ServiceIds    0x01..0x1F
-	kEplNmtCmdIdentResponse = 0x01,
-	kEplNmtCmdStatusResponse = 0x02,
-	// plain NMT state commands       0x20..0x3F
-	kEplNmtCmdStartNode = 0x21,
-	kEplNmtCmdStopNode = 0x22,
-	kEplNmtCmdEnterPreOperational2 = 0x23,
-	kEplNmtCmdEnableReadyToOperate = 0x24,
-	kEplNmtCmdResetNode = 0x28,
-	kEplNmtCmdResetCommunication = 0x29,
-	kEplNmtCmdResetConfiguration = 0x2A,
-	kEplNmtCmdSwReset = 0x2B,
-	// extended NMT state commands    0x40..0x5F
-	kEplNmtCmdStartNodeEx = 0x41,
-	kEplNmtCmdStopNodeEx = 0x42,
-	kEplNmtCmdEnterPreOperational2Ex = 0x43,
-	kEplNmtCmdEnableReadyToOperateEx = 0x44,
-	kEplNmtCmdResetNodeEx = 0x48,
-	kEplNmtCmdResetCommunicationEx = 0x49,
-	kEplNmtCmdResetConfigurationEx = 0x4A,
-	kEplNmtCmdSwResetEx = 0x4B,
-	// NMT managing commands          0x60..0x7F
-	kEplNmtCmdNetHostNameSet = 0x62,
-	kEplNmtCmdFlushArpEntry = 0x63,
-	// NMT info services              0x80..0xBF
-	kEplNmtCmdPublishConfiguredCN = 0x80,
-	kEplNmtCmdPublishActiveCN = 0x90,
-	kEplNmtCmdPublishPreOperational1 = 0x91,
-	kEplNmtCmdPublishPreOperational2 = 0x92,
-	kEplNmtCmdPublishReadyToOperate = 0x93,
-	kEplNmtCmdPublishOperational = 0x94,
-	kEplNmtCmdPublishStopped = 0x95,
-	kEplNmtCmdPublishEmergencyNew = 0xA0,
-	kEplNmtCmdPublishTime = 0xB0,
-
-	kEplNmtCmdInvalidService = 0xFF
-} tEplNmtCommand;
-
-typedef tEplKernel(* tEplNmtuStateChangeCallback) (tEplEventNmtStateChange NmtStateChange_p);
-
-typedef tEplKernel(* tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p);
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-
-tEplKernel EplNmtuInit(void);
-
-tEplKernel EplNmtuAddInstance(void);
-
-tEplKernel EplNmtuDelInstance(void);
-
-tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
-
-tEplNmtState EplNmtuGetNmtState(void);
-
-tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p);
-
-tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p);
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-
-#endif // #ifndef _EPLNMTU_H_
diff --git a/drivers/staging/epl/user/EplNmtuCal.h b/drivers/staging/epl/user/EplNmtuCal.h
deleted file mode 100644
index b985037..0000000
--- a/drivers/staging/epl/user/EplNmtuCal.h
+++ /dev/null
@@ -1,80 +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-Userspace-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: EplNmtuCal.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/16 -k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLNMTUCAL_H_
-#define _EPLNMTUCAL_H_
-
-#include "EplNmtu.h"
-#include "../kernel/EplNmtk.h"
-
-tEplNmtState EplNmtkCalGetNmtState(void);
-
-#endif // #ifndef _EPLNMTUCAL_H_
diff --git a/drivers/staging/epl/user/EplObdu.h b/drivers/staging/epl/user/EplObdu.h
deleted file mode 100644
index 0863712..0000000
--- a/drivers/staging/epl/user/EplObdu.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for Epl-Obd-Userspace-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: EplObdu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/19 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLOBDU_H_
-#define _EPLOBDU_H_
-
-#include "../EplObd.h"
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-
-#if EPL_OBD_USE_KERNEL != FALSE
-#error "EPL OBDu module enabled, but OBD_USE_KERNEL == TRUE"
-#endif
-
-tEplKernel EplObduWriteEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
-			     void *pSrcData_p, tEplObdSize Size_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObduReadEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
-			    void *pDstData_p, tEplObdSize *pSize_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p);
-
-// ---------------------------------------------------------------------
-void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p);
-
-// ---------------------------------------------------------------------
-tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p);
-
-// ---------------------------------------------------------------------
-void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p,
-			 tEplObdSize ObdSize_p);
-
-// ---------------------------------------------------------------------
-tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p,
-			       unsigned int uiSubIndex_p);
-
-// ---------------------------------------------------------------------
-unsigned int EplObduGetNodeId(void);
-
-// ---------------------------------------------------------------------
-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"
-
-#define EplObduWriteEntry       EplObdWriteEntry
-
-#define EplObduReadEntry        EplObdReadEntry
-
-#define EplObduAccessOdPart     EplObdAccessOdPart
-
-#define EplObduDefineVar        EplObdDefineVar
-
-#define EplObduGetObjectDataPtr EplObdGetObjectDataPtr
-
-#define EplObduRegisterUserOd   EplObdRegisterUserOd
-
-#define EplObduInitVarEntry     EplObdInitVarEntry
-
-#define EplObduGetDataSize      EplObdGetDataSize
-
-#define EplObduGetNodeId        EplObdGetNodeId
-
-#define EplObduSetNodeId        EplObdSetNodeId
-
-#define EplObduGetAccessType    EplObdGetAccessType
-
-#define EplObduReadEntryToLe    EplObdReadEntryToLe
-
-#define EplObduWriteEntryFromLe EplObdWriteEntryFromLe
-
-#define EplObduSearchVarEntry   EplObdSearchVarEntry
-
-#define EplObduIsNumerical      EplObdIsNumerical
-
-#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
-
-#endif // #ifndef _EPLOBDU_H_
diff --git a/drivers/staging/epl/user/EplObduCal.h b/drivers/staging/epl/user/EplObduCal.h
deleted file mode 100644
index 0727777..0000000
--- a/drivers/staging/epl/user/EplObduCal.h
+++ /dev/null
@@ -1,126 +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-Userspace-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: EplObduCal.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
-
-****************************************************************************/
-
-#ifndef _EPLOBDUCAL_H_
-#define _EPLOBDUCAL_H_
-
-#include "../EplObd.h"
-
-tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
-				unsigned int uiSubIndex_p,
-				void *pSrcData_p,
-				tEplObdSize Size_p);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
-			       unsigned int uiSubIndex_p,
-			       void *pDstData_p,
-			       tEplObdSize *pSize_p);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
-				  tEplObdDir Direction_p);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p);
-//---------------------------------------------------------------------------
-void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
-				 unsigned int uiSubIndex_p);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p);
-//---------------------------------------------------------------------------
-void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p,
-			    u8 bType_p, tEplObdSize ObdSize_p);
-//---------------------------------------------------------------------------
-tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
-				  unsigned int uiSubIndex_p);
-//---------------------------------------------------------------------------
-unsigned int EplObduCalGetNodeId(void);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
-			       tEplObdNodeIdType NodeIdType_p);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
-				   unsigned int uiSubIndex_p,
-				   tEplObdAccess *pAccessTyp_p);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
-				   unsigned int uiSubIndex_p,
-				   void *pDstData_p,
-				   tEplObdSize *pSize_p);
-//---------------------------------------------------------------------------
-tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
-				      unsigned int uiSubIndex_p,
-				      void *pSrcData_p,
-				      tEplObdSize Size_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
deleted file mode 100644
index b8c832b..0000000
--- a/drivers/staging/epl/user/EplPdou.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for userspace PDO 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: EplPdou.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/11/19 17:14:38 $
-
-                $State: Exp $
-
-                Build Environment:
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/05/22 d.k.:   start of the implementation, version 1.00
-
-****************************************************************************/
-
-#ifndef _EPL_PDOU_H_
-#define _EPL_PDOU_H_
-
-#include "../EplPdo.h"
-
-tEplKernel EplPdouAddInstance(void);
-
-tEplKernel EplPdouDelInstance(void);
-
-#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
-tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p);
-#else
-#define EplPdouCbObdAccess		NULL
-#endif
-
-// returns error if bPdoId_p is already valid
-/*
-tEplKernel EplPdouSetMapping(
-    u8 bPdoId_p, BOOL fTxRx_p, u8 bNodeId, u8 bMappingVersion,
-    tEplPdoMapping * pMapping_p, u8 bMaxEntries_p);
-
-tEplKernel EplPdouGetMapping(
-    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
deleted file mode 100644
index a62d4c9..0000000
--- a/drivers/staging/epl/user/EplSdoAsndu.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for SDO/Asnd-Protocolabstractionlayer 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: EplSdoAsndu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.6 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/07/07 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLSDOASNDU_H_
-#define _EPLSDOASNDU_H_
-
-#include "../EplSdo.h"
-#include "../EplDll.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-
-tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
-
-tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
-
-tEplKernel EplSdoAsnduDelInstance(void);
-
-tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
-			      unsigned int uiTargetNodeId_p);
-
-tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
-			       tEplFrame *pSrcData_p,
-			       u32 dwDataSize_p);
-
-tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
-
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-
-#endif // #ifndef _EPLSDOASNDU_H_
diff --git a/drivers/staging/epl/user/EplSdoAsySequ.h b/drivers/staging/epl/user/EplSdoAsySequ.h
deleted file mode 100644
index cc862de..0000000
--- a/drivers/staging/epl/user/EplSdoAsySequ.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for asychrionus SDO Sequence Layer 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: EplSdoAsySequ.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/26 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLSDOASYSEQU_H_
-#define _EPLSDOASYSEQU_H_
-
-#include "../EplSdo.h"
-#include "EplSdoUdpu.h"
-#include "EplSdoAsndu.h"
-#include "../EplEvent.h"
-#include "EplTimeru.h"
-
-tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
-			    tEplSdoComConCb fpSdoComConCb_p);
-
-tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
-				   tEplSdoComConCb fpSdoComConCb_p);
-
-tEplKernel EplSdoAsySeqDelInstance(void);
-
-tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
-			       unsigned int uiNodeId_p,
-			       tEplSdoType SdoType);
-
-tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
-				unsigned int uiDataSize_p,
-				tEplFrame *pData_p);
-
-tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_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
deleted file mode 100644
index 4eee6fa..0000000
--- a/drivers/staging/epl/user/EplSdoComu.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for SDO Command Layer 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: EplSdoComu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/26 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLSDOCOMU_H_
-#define _EPLSDOCOMU_H_
-
-#include "../EplSdo.h"
-#include "../EplObd.h"
-#include "../EplSdoAc.h"
-#include "EplObdu.h"
-#include "EplSdoAsySequ.h"
-
-tEplKernel EplSdoComInit(void);
-
-tEplKernel EplSdoComAddInstance(void);
-
-tEplKernel EplSdoComDelInstance(void);
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-
-tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
-			      unsigned int uiTargetNodeId_p,
-			      tEplSdoType ProtType_p);
-
-tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p);
-
-tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p);
-
-tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
-			     tEplSdoComFinished *pSdoComFinished_p);
-
-tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
-			     u32 dwAbortCode_p);
-
-#endif
-
-// for future extention
-/*
-tEplKernel EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
-
-tEplKernel EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
-
-tEplKernel EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
-
-*/
-
-#endif // #ifndef _EPLSDOCOMU_H_
diff --git a/drivers/staging/epl/user/EplSdoUdpu.h b/drivers/staging/epl/user/EplSdoUdpu.h
deleted file mode 100644
index 13e2a27..0000000
--- a/drivers/staging/epl/user/EplSdoUdpu.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for SDO/UDP-Protocollabstractionlayer 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: EplSdoUdpu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $Date: 2008/10/17 15:32:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/06/26 k.t.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLSDOUDPU_H_
-#define _EPLSDOUDPU_H_
-
-#include "../EplSdo.h"
-
-#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-
-tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
-
-tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
-
-tEplKernel EplSdoUdpuDelInstance(void);
-
-tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p,
-			    unsigned int uiPort_p);
-
-tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
-			     unsigned int uiTargetNodeId_p);
-
-tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
-			      tEplFrame *pSrcData_p, u32 dwDataSize_p);
-
-tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
-
-#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-
-#endif // #ifndef _EPLSDOUDPU_H_
diff --git a/drivers/staging/epl/user/EplStatusu.h b/drivers/staging/epl/user/EplStatusu.h
deleted file mode 100644
index 0fd3ebb..0000000
--- a/drivers/staging/epl/user/EplStatusu.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for Statusu-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: EplStatusu.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.3 $  $Date: 2008/04/17 21:36:32 $
-
-                $State: Exp $
-
-                Build Environment:
-                    GCC V3.4
-
-  -------------------------------------------------------------------------
-
-  Revision History:
-
-  2006/11/15 d.k.:   start of the implementation
-
-****************************************************************************/
-
-#ifndef _EPLSTATUSU_H_
-#define _EPLSTATUSU_H_
-
-#include "../EplDll.h"
-
-typedef tEplKernel(* tEplStatusuCbResponse) (unsigned int uiNodeId_p,
-					     tEplStatusResponse *pStatusResponse_p);
-
-tEplKernel EplStatusuInit(void);
-
-tEplKernel EplStatusuAddInstance(void);
-
-tEplKernel EplStatusuDelInstance(void);
-
-tEplKernel EplStatusuReset(void);
-
-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
deleted file mode 100644
index 5c44748..0000000
--- a/drivers/staging/epl/user/EplTimeru.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-
-  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
-      www.systec-electronic.com
-
-  Project:      openPOWERLINK
-
-  Description:  include file for Epl Userspace-Timermodule
-
-  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: EplTimeru.h,v $
-
-                $Author: D.Krueger $
-
-                $Revision: 1.5 $  $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
-
-****************************************************************************/
-
-#ifndef _EPLTIMERU_H_
-#define _EPLTIMERU_H_
-
-#include "../EplTimer.h"
-#include "EplEventu.h"
-
-tEplKernel EplTimeruInit(void);
-
-tEplKernel EplTimeruAddInstance(void);
-
-tEplKernel EplTimeruDelInstance(void);
-
-tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
-			       unsigned long ulTime_p,
-			       tEplTimerArg Argument_p);
-
-tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
-				  unsigned long ulTime_p,
-				  tEplTimerArg Argument_p);
-
-tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p);
-
-BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
-
-#endif // #ifndef _EPLTIMERU_H_
diff --git a/drivers/staging/et131x/Makefile b/drivers/staging/et131x/Makefile
index 3ad571d..95c645d 100644
--- a/drivers/staging/et131x/Makefile
+++ b/drivers/staging/et131x/Makefile
@@ -5,14 +5,11 @@
 obj-$(CONFIG_ET131X) += et131x.o
 
 et131x-objs :=	et1310_eeprom.o \
-		et1310_jagcore.o \
 		et1310_mac.o \
 		et1310_phy.o \
 		et1310_pm.o \
 		et1310_rx.o \
 		et1310_tx.o \
-		et131x_config.o \
-		et131x_debug.o \
 		et131x_initpci.o \
 		et131x_isr.o \
 		et131x_netdev.o
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
index 3c85999..6294d38 100644
--- a/drivers/staging/et131x/et1310_address_map.h
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -61,255 +61,110 @@
 
 /* START OF GLOBAL REGISTER ADDRESS MAP */
 
-typedef union _Q_ADDR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;	// bits 10-31
-		u32 addr:10;	// bits 0-9
-#else
-		u32 addr:10;	// bits 0-9
-		u32 unused:22;	// bits 10-31
-#endif
-	} bits;
-} Q_ADDR_t, *PQ_ADDR_t;
-
-/*
- * structure for tx queue start address reg in global address map
- * located at address 0x0000
- * Defined earlier (Q_ADDR_t)
- */
-
 /*
- * structure for tx queue end address reg in global address map
- * located at address 0x0004
- * Defined earlier (Q_ADDR_t)
- */
-
-/*
- * structure for rx queue start address reg in global address map
- * located at address 0x0008
- * Defined earlier (Q_ADDR_t)
- */
-
-/*
- * structure for rx queue end address reg in global address map
- * located at address 0x000C
- * Defined earlier (Q_ADDR_t)
+ * 10bit registers
+ *
+ * Tx queue start address reg in global address map at address 0x0000
+ * tx queue end address reg in global address map at address 0x0004
+ * rx queue start address reg in global address map at address 0x0008
+ * rx queue end address reg in global address map at address 0x000C
  */
 
 /*
  * structure for power management control status reg in global address map
  * located at address 0x0010
- */
-typedef union _PM_CSR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;		// bits 10-31
-		u32 pm_jagcore_rx_rdy:1;	// bit 9
-		u32 pm_jagcore_tx_rdy:1;	// bit 8
-		u32 pm_phy_lped_en:1;	// bit 7
-		u32 pm_phy_sw_coma:1;	// bit 6
-		u32 pm_rxclk_gate:1;	// bit 5
-		u32 pm_txclk_gate:1;	// bit 4
-		u32 pm_sysclk_gate:1;	// bit 3
-		u32 pm_jagcore_rx_en:1;	// bit 2
-		u32 pm_jagcore_tx_en:1;	// bit 1
-		u32 pm_gigephy_en:1;	// bit 0
-#else
-		u32 pm_gigephy_en:1;	// bit 0
-		u32 pm_jagcore_tx_en:1;	// bit 1
-		u32 pm_jagcore_rx_en:1;	// bit 2
-		u32 pm_sysclk_gate:1;	// bit 3
-		u32 pm_txclk_gate:1;	// bit 4
-		u32 pm_rxclk_gate:1;	// bit 5
-		u32 pm_phy_sw_coma:1;	// bit 6
-		u32 pm_phy_lped_en:1;	// bit 7
-		u32 pm_jagcore_tx_rdy:1;	// bit 8
-		u32 pm_jagcore_rx_rdy:1;	// bit 9
-		u32 unused:22;		// bits 10-31
-#endif
-	} bits;
-} PM_CSR_t, *PPM_CSR_t;
-
-/*
- * structure for interrupt status reg in global address map
- * located at address 0x0018
- */
-typedef union _INTERRUPT_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused5:11;			// bits 21-31
-		u32 slv_timeout:1;			// bit 20
-		u32 mac_stat_interrupt:1;		// bit 19
-		u32 rxmac_interrupt:1;		// bit 18
-		u32 txmac_interrupt:1;		// bit 17
-		u32 phy_interrupt:1;		// bit 16
-		u32 wake_on_lan:1;			// bit 15
-		u32 watchdog_interrupt:1;		// bit 14
-		u32 unused4:4;			// bits 10-13
-		u32 rxdma_err:1;			// bit 9
-		u32 rxdma_pkt_stat_ring_low:1;	// bit 8
-		u32 rxdma_fb_ring1_low:1;		// bit 7
-		u32 rxdma_fb_ring0_low:1;		// bit 6
-		u32 rxdma_xfr_done:1;		// bit 5
-		u32 txdma_err:1;			// bit 4
-		u32 txdma_isr:1;			// bit 3
-		u32 unused3:1;			// bit 2
-		u32 unused2:1;			// bit 1
-		u32 unused1:1;			// bit 0
-#else
-		u32 unused1:1;			// bit 0
-		u32 unused2:1;			// bit 1
-		u32 unused3:1;			// bit 2
-		u32 txdma_isr:1;			// bit 3
-		u32 txdma_err:1;			// bit 4
-		u32 rxdma_xfr_done:1;		// bit 5
-		u32 rxdma_fb_ring0_low:1;		// bit 6
-		u32 rxdma_fb_ring1_low:1;		// bit 7
-		u32 rxdma_pkt_stat_ring_low:1;	// bit 8
-		u32 rxdma_err:1;			// bit 9
-		u32 unused4:4;			// bits 10-13
-		u32 watchdog_interrupt:1;		// bit 14
-		u32 wake_on_lan:1;			// bit 15
-		u32 phy_interrupt:1;		// bit 16
-		u32 txmac_interrupt:1;		// bit 17
-		u32 rxmac_interrupt:1;		// bit 18
-		u32 mac_stat_interrupt:1;		// bit 19
-		u32 slv_timeout:1;			// bit 20
-		u32 unused5:11;			// bits 21-31
-#endif
-	} bits;
-} INTERRUPT_t, *PINTERRUPT_t;
-
-/*
- * structure for interrupt mask reg in global address map
- * located at address 0x001C
- * Defined earlier (INTERRUPT_t), but 'watchdog_interrupt' is not used.
+ *	jagcore_rx_rdy	bit 9
+ *	jagcore_tx_rdy	bit 8
+ *	phy_lped_en	bit 7
+ *	phy_sw_coma	bit 6
+ *	rxclk_gate	bit 5
+ *	txclk_gate	bit 4
+ *	sysclk_gate	bit 3
+ *	jagcore_rx_en	bit 2
+ *	jagcore_tx_en	bit 1
+ *	gigephy_en	bit 0
+ */
+
+#define ET_PM_PHY_SW_COMA		0x40
+#define ET_PMCSR_INIT			0x38
+
+/*
+ * Interrupt status reg at address 0x0018
+ */
+
+#define	ET_INTR_TXDMA_ISR	0x00000008
+#define ET_INTR_TXDMA_ERR	0x00000010
+#define ET_INTR_RXDMA_XFR_DONE	0x00000020
+#define ET_INTR_RXDMA_FB_R0_LOW	0x00000040
+#define ET_INTR_RXDMA_FB_R1_LOW	0x00000080
+#define ET_INTR_RXDMA_STAT_LOW	0x00000100
+#define ET_INTR_RXDMA_ERR	0x00000200
+#define ET_INTR_WATCHDOG	0x00004000
+#define ET_INTR_WOL		0x00008000
+#define ET_INTR_PHY		0x00010000
+#define ET_INTR_TXMAC		0x00020000
+#define ET_INTR_RXMAC		0x00040000
+#define ET_INTR_MAC_STAT	0x00080000
+#define ET_INTR_SLV_TIMEOUT	0x00100000
+
+/*
+ * Interrupt mask register at address 0x001C
+ * Interrupt alias clear mask reg at address 0x0020
+ * Interrupt status alias reg at address 0x0024
+ *
+ * Same masks as above
  */
 
 /*
- * structure for interrupt alias clear mask reg in global address map
- * located at address 0x0020
- * Defined earlier (INTERRUPT_t)
+ * Software reset reg at address 0x0028
+ * 0: 	txdma_sw_reset
+ * 1:	rxdma_sw_reset
+ * 2:	txmac_sw_reset
+ * 3:	rxmac_sw_reset
+ * 4:	mac_sw_reset
+ * 5:	mac_stat_sw_reset
+ * 6:	mmc_sw_reset
+ *31:	selfclr_disable
  */
 
 /*
- * structure for interrupt status alias reg in global address map
- * located at address 0x0024
- * Defined earlier (INTERRUPT_t)
+ * SLV Timer reg at address 0x002C (low 24 bits)
  */
 
 /*
- * structure for software reset reg in global address map
- * located at address 0x0028
+ * MSI Configuration reg at address 0x0030
  */
-typedef union _SW_RESET_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 selfclr_disable:1;	// bit 31
-		u32 unused:24;		// bits 7-30
-		u32 mmc_sw_reset:1;	// bit 6
-		u32 mac_stat_sw_reset:1;	// bit 5
-		u32 mac_sw_reset:1;	// bit 4
-		u32 rxmac_sw_reset:1;	// bit 3
-		u32 txmac_sw_reset:1;	// bit 2
-		u32 rxdma_sw_reset:1;	// bit 1
-		u32 txdma_sw_reset:1;	// bit 0
-#else
-		u32 txdma_sw_reset:1;	// bit 0
-		u32 rxdma_sw_reset:1;	// bit 1
-		u32 txmac_sw_reset:1;	// bit 2
-		u32 rxmac_sw_reset:1;	// bit 3
-		u32 mac_sw_reset:1;	// bit 4
-		u32 mac_stat_sw_reset:1;	// bit 5
-		u32 mmc_sw_reset:1;	// bit 6
-		u32 unused:24;		// bits 7-30
-		u32 selfclr_disable:1;	// bit 31
-#endif
-	} bits;
-} SW_RESET_t, *PSW_RESET_t;
 
-/*
- * structure for SLV Timer reg in global address map
- * located at address 0x002C
- */
-typedef union _SLV_TIMER_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:8;	// bits 24-31
-		u32 timer_ini:24;	// bits 0-23
-#else
-		u32 timer_ini:24;	// bits 0-23
-		u32 unused:8;	// bits 24-31
-#endif
-	} bits;
-} SLV_TIMER_t, *PSLV_TIMER_t;
+#define ET_MSI_VECTOR	0x0000001F
+#define ET_MSI_TC	0x00070000
 
 /*
- * structure for MSI Configuration reg in global address map
- * located at address 0x0030
+ * Loopback reg located at address 0x0034
  */
-typedef union _MSI_CONFIG_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused1:13;	// bits 19-31
-		u32 msi_tc:3;	// bits 16-18
-		u32 unused2:11;	// bits 5-15
-		u32 msi_vector:5;	// bits 0-4
-#else
-		u32 msi_vector:5;	// bits 0-4
-		u32 unused2:11;	// bits 5-15
-		u32 msi_tc:3;	// bits 16-18
-		u32 unused1:13;	// bits 19-31
-#endif
-	} bits;
-} MSI_CONFIG_t, *PMSI_CONFIG_t;
 
-/*
- * structure for Loopback reg in global address map
- * located at address 0x0034
- */
-typedef union _LOOPBACK_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:30;		// bits 2-31
-		u32 dma_loopback:1;	// bit 1
-		u32 mac_loopback:1;	// bit 0
-#else
-		u32 mac_loopback:1;	// bit 0
-		u32 dma_loopback:1;	// bit 1
-		u32 unused:30;		// bits 2-31
-#endif
-	} bits;
-} LOOPBACK_t, *PLOOPBACK_t;
+#define ET_LOOP_MAC	0x00000001
+#define ET_LOOP_DMA	0x00000002
 
 /*
  * GLOBAL Module of JAGCore Address Mapping
  * Located at address 0x0000
  */
-typedef struct _GLOBAL_t {			// Location:
-	Q_ADDR_t txq_start_addr;		//  0x0000
-	Q_ADDR_t txq_end_addr;			//  0x0004
-	Q_ADDR_t rxq_start_addr;		//  0x0008
-	Q_ADDR_t rxq_end_addr;			//  0x000C
-	PM_CSR_t pm_csr;			//  0x0010
-	u32 unused;				//  0x0014
-	INTERRUPT_t int_status;			//  0x0018
-	INTERRUPT_t int_mask;			//  0x001C
-	INTERRUPT_t int_alias_clr_en;		//  0x0020
-	INTERRUPT_t int_status_alias;		//  0x0024
-	SW_RESET_t sw_reset;			//  0x0028
-	SLV_TIMER_t slv_timer;			//  0x002C
-	MSI_CONFIG_t msi_config;		//  0x0030
-	LOOPBACK_t loopback;			//  0x0034
-	u32 watchdog_timer;			//  0x0038
+typedef struct _GLOBAL_t {			/* Location: */
+	u32 txq_start_addr;			/*  0x0000 */
+	u32 txq_end_addr;			/*  0x0004 */
+	u32 rxq_start_addr;			/*  0x0008 */
+	u32 rxq_end_addr;			/*  0x000C */
+	u32 pm_csr;				/*  0x0010 */
+	u32 unused;				/*  0x0014 */
+	u32 int_status;				/*  0x0018 */
+	u32 int_mask;				/*  0x001C */
+	u32 int_alias_clr_en;			/*  0x0020 */
+	u32 int_status_alias;			/*  0x0024 */
+	u32 sw_reset;				/*  0x0028 */
+	u32 slv_timer;				/*  0x002C */
+	u32 msi_config;				/*  0x0030 */
+	u32 loopback;			/*  0x0034 */
+	u32 watchdog_timer;			/*  0x0038 */
 } GLOBAL_t, *PGLOBAL_t;
 
 /* END OF GLOBAL REGISTER ADDRESS MAP */
@@ -318,31 +173,15 @@ typedef struct _GLOBAL_t {			// Location:
 /* START OF TXDMA REGISTER ADDRESS MAP */
 
 /*
- * structure for txdma control status reg in txdma address map
- * located at address 0x1000
+ * txdma control status reg at address 0x1000
  */
-typedef union _TXDMA_CSR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused2:19;		// bits 13-31
-		u32 traffic_class:4;	// bits 9-12
-		u32 sngl_epkt_mode:1;	// bit 8
-		u32 cache_thrshld:4;	// bits 4-7
-		u32 unused1:2;		// bits 2-3
-		u32 drop_TLP_disable:1;	// bit 1
-		u32 halt:1;		// bit 0
-#else
-		u32 halt:1;		// bit 0
-		u32 drop_TLP_disable:1;	// bit 1
-		u32 unused1:2;		// bits 2-3
-		u32 cache_thrshld:4;	// bits 4-7
-		u32 sngl_epkt_mode:1;	// bit 8
-		u32 traffic_class:4;	// bits 9-12
-		u32 unused2:19;		// bits 13-31
-#endif
-	} bits;
-} TXDMA_CSR_t, *PTXDMA_CSR_t;
+
+#define ET_TXDMA_CSR_HALT	0x00000001
+#define ET_TXDMA_DROP_TLP	0x00000002
+#define ET_TXDMA_CACHE_THRS	0x000000F0
+#define ET_TXDMA_CACHE_SHIFT	4
+#define ET_TXDMA_SNGL_EPKT	0x00000100
+#define ET_TXDMA_CLASS		0x00001E00
 
 /*
  * structure for txdma packet ring base address hi reg in txdma address map
@@ -364,162 +203,87 @@ typedef union _TXDMA_PR_NUM_DES_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;	// bits 10-31
-		u32 pr_ndes:10;	// bits 0-9
+		u32 unused:22;	/* bits 10-31 */
+		u32 pr_ndes:10;	/* bits 0-9 */
 #else
-		u32 pr_ndes:10;	// bits 0-9
-		u32 unused:22;	// bits 10-31
+		u32 pr_ndes:10;	/* bits 0-9 */
+		u32 unused:22;	/* bits 10-31 */
 #endif
 	} bits;
 } TXDMA_PR_NUM_DES_t, *PTXDMA_PR_NUM_DES_t;
 
 
-typedef union _DMA10W_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:21;	// bits 11-31
-		u32 wrap:1;	// bit 10
-		u32 val:10;	// bits 0-9
-#else
-		u32 val:10;	// bits 0-9
-		u32 wrap:1;	// bit 10
-		u32 unused:21;	// bits 11-31
-#endif
-	} bits;
-} DMA10W_t, *PDMA10W_t;
-
-/*
- * structure for txdma tx queue write address reg in txdma address map
- * located at address 0x1010
- * Defined earlier (DMA10W_t)
- */
-
-/*
- * structure for txdma tx queue write address external reg in txdma address map
- * located at address 0x1014
- * Defined earlier (DMA10W_t)
- */
+#define ET_DMA10_MASK		0x3FF	/* 10 bit mask for DMA10W types */
+#define ET_DMA10_WRAP		0x400
+#define ET_DMA4_MASK		0x00F	/* 4 bit mask for DMA4W types */
+#define ET_DMA4_WRAP		0x010
 
-/*
- * structure for txdma tx queue read address reg in txdma address map
- * located at address 0x1018
- * Defined earlier (DMA10W_t)
- */
-
-/*
- * structure for txdma status writeback address hi reg in txdma address map
- * located at address 0x101C
- * Defined earlier (u32)
- */
-
-/*
- * structure for txdma status writeback address lo reg in txdma address map
- * located at address 0x1020
- * Defined earlier (u32)
- */
+#define INDEX10(x)	((x) & ET_DMA10_MASK)
+#define INDEX4(x)	((x) & ET_DMA4_MASK)
 
-/*
- * structure for txdma service request reg in txdma address map
- * located at address 0x1024
- * Defined earlier (DMA10W_t)
- */
-
-/*
- * structure for txdma service complete reg in txdma address map
- * located at address 0x1028
- * Defined earlier (DMA10W_t)
- */
-
-typedef union _DMA4W_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused:27;	// bits 5-31
-		u32 wrap:1;	// bit 4
-		u32 val:4;		// bit 0-3
-#else
-		u32 val:4;		// bits 0-3
-		u32 wrap:1;	// bit 4
-		u32 unused:27;	// bits 5-31
-#endif
-	} bits;
-} DMA4W_t, *PDMA4W_t;
-
-/*
- * structure for txdma tx descriptor cache read index reg in txdma address map
- * located at address 0x102C
- * Defined earlier (DMA4W_t)
- */
-
-/*
- * structure for txdma tx descriptor cache write index reg in txdma address map
- * located at address 0x1030
- * Defined earlier (DMA4W_t)
- */
+extern inline void add_10bit(u32 *v, int n)
+{
+	*v = INDEX10(*v + n);
+}
 
 /*
- * structure for txdma error reg in txdma address map
- * located at address 0x1034
+ * 10bit DMA with wrap
+ * txdma tx queue write address reg in txdma address map at 0x1010
+ * txdma tx queue write address external reg in txdma address map at 0x1014
+ * txdma tx queue read address reg in txdma address map at 0x1018
+ *
+ * u32
+ * txdma status writeback address hi reg in txdma address map at0x101C
+ * txdma status writeback address lo reg in txdma address map at 0x1020
+ *
+ * 10bit DMA with wrap
+ * txdma service request reg in txdma address map at 0x1024
+ * structure for txdma service complete reg in txdma address map at 0x1028
+ *
+ * 4bit DMA with wrap
+ * txdma tx descriptor cache read index reg in txdma address map at 0x102C
+ * txdma tx descriptor cache write index reg in txdma address map at 0x1030
+ *
+ * txdma error reg in txdma address map at address 0x1034
+ * 0: PyldResend
+ * 1: PyldRewind
+ * 4: DescrResend
+ * 5: DescrRewind
+ * 8: WrbkResend
+ * 9: WrbkRewind
  */
-typedef union _TXDMA_ERROR_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 unused3:22;		// bits 10-31
-		u32 WrbkRewind:1;	// bit 9
-		u32 WrbkResend:1;	// bit 8
-		u32 unused2:2;		// bits 6-7
-		u32 DescrRewind:1;	// bit 5
-		u32 DescrResend:1;	// bit 4
-		u32 unused1:2;		// bits 2-3
-		u32 PyldRewind:1;	// bit 1
-		u32 PyldResend:1;	// bit 0
-#else
-		u32 PyldResend:1;	// bit 0
-		u32 PyldRewind:1;	// bit 1
-		u32 unused1:2;		// bits 2-3
-		u32 DescrResend:1;	// bit 4
-		u32 DescrRewind:1;	// bit 5
-		u32 unused2:2;		// bits 6-7
-		u32 WrbkResend:1;	// bit 8
-		u32 WrbkRewind:1;	// bit 9
-		u32 unused3:22;		// bits 10-31
-#endif
-	} bits;
-} TXDMA_ERROR_t, *PTXDMA_ERROR_t;
 
 /*
  * Tx DMA Module of JAGCore Address Mapping
  * Located at address 0x1000
  */
-typedef struct _TXDMA_t {		// Location:
-	TXDMA_CSR_t csr;		//  0x1000
-	u32 pr_base_hi;			//  0x1004
-	u32 pr_base_lo;			//  0x1008
-	TXDMA_PR_NUM_DES_t pr_num_des;	//  0x100C
-	DMA10W_t txq_wr_addr;		//  0x1010
-	DMA10W_t txq_wr_addr_ext;	//  0x1014
-	DMA10W_t txq_rd_addr;		//  0x1018
-	u32 dma_wb_base_hi;		//  0x101C
-	u32 dma_wb_base_lo;		//  0x1020
-	DMA10W_t service_request;	//  0x1024
-	DMA10W_t service_complete;	//  0x1028
-	DMA4W_t cache_rd_index;		//  0x102C
-	DMA4W_t cache_wr_index;		//  0x1030
-	TXDMA_ERROR_t TxDmaError;	//  0x1034
-	u32 DescAbortCount;		//  0x1038
-	u32 PayloadAbortCnt;		//  0x103c
-	u32 WriteBackAbortCnt;		//  0x1040
-	u32 DescTimeoutCnt;		//  0x1044
-	u32 PayloadTimeoutCnt;		//  0x1048
-	u32 WriteBackTimeoutCnt;	//  0x104c
-	u32 DescErrorCount;		//  0x1050
-	u32 PayloadErrorCnt;		//  0x1054
-	u32 WriteBackErrorCnt;		//  0x1058
-	u32 DroppedTLPCount;		//  0x105c
-	DMA10W_t NewServiceComplete;	//  0x1060
-	u32 EthernetPacketCount;	//  0x1064
+typedef struct _TXDMA_t {		/* Location: */
+	u32 csr;			/*  0x1000 */
+	u32 pr_base_hi;			/*  0x1004 */
+	u32 pr_base_lo;			/*  0x1008 */
+	TXDMA_PR_NUM_DES_t pr_num_des;	/*  0x100C */
+	u32 txq_wr_addr;		/*  0x1010 */
+	u32 txq_wr_addr_ext;		/*  0x1014 */
+	u32 txq_rd_addr;		/*  0x1018 */
+	u32 dma_wb_base_hi;		/*  0x101C */
+	u32 dma_wb_base_lo;		/*  0x1020 */
+	u32 service_request;		/*  0x1024 */
+	u32 service_complete;		/*  0x1028 */
+	u32 cache_rd_index;		/*  0x102C */
+	u32 cache_wr_index;		/*  0x1030 */
+	u32 TxDmaError;			/*  0x1034 */
+	u32 DescAbortCount;		/*  0x1038 */
+	u32 PayloadAbortCnt;		/*  0x103c */
+	u32 WriteBackAbortCnt;		/*  0x1040 */
+	u32 DescTimeoutCnt;		/*  0x1044 */
+	u32 PayloadTimeoutCnt;		/*  0x1048 */
+	u32 WriteBackTimeoutCnt;	/*  0x104c */
+	u32 DescErrorCount;		/*  0x1050 */
+	u32 PayloadErrorCnt;		/*  0x1054 */
+	u32 WriteBackErrorCnt;		/*  0x1058 */
+	u32 DroppedTLPCount;		/*  0x105c */
+	u32 NewServiceComplete;		/*  0x1060 */
+	u32 EthernetPacketCount;	/*  0x1064 */
 } TXDMA_t, *PTXDMA_t;
 
 /* END OF TXDMA REGISTER ADDRESS MAP */
@@ -535,37 +299,37 @@ typedef union _RXDMA_CSR_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused2:14;		// bits 18-31
-		u32 halt_status:1;	// bit 17
-		u32 pkt_done_flush:1;	// bit 16
-		u32 pkt_drop_disable:1;	// bit 15
-		u32 unused1:1;		// bit 14
-		u32 fbr1_enable:1;	// bit 13
-		u32 fbr1_size:2;	// bits 11-12
-		u32 fbr0_enable:1;	// bit 10
-		u32 fbr0_size:2;	// bits 8-9
-		u32 dma_big_endian:1;	// bit 7
-		u32 pkt_big_endian:1;	// bit 6
-		u32 psr_big_endian:1;	// bit 5
-		u32 fbr_big_endian:1;	// bit 4
-		u32 tc:3;		// bits 1-3
-		u32 halt:1;		// bit 0
-#else
-		u32 halt:1;		// bit 0
-		u32 tc:3;		// bits 1-3
-		u32 fbr_big_endian:1;	// bit 4
-		u32 psr_big_endian:1;	// bit 5
-		u32 pkt_big_endian:1;	// bit 6
-		u32 dma_big_endian:1;	// bit 7
-		u32 fbr0_size:2;	// bits 8-9
-		u32 fbr0_enable:1;	// bit 10
-		u32 fbr1_size:2;	// bits 11-12
-		u32 fbr1_enable:1;	// bit 13
-		u32 unused1:1;		// bit 14
-		u32 pkt_drop_disable:1;	// bit 15
-		u32 pkt_done_flush:1;	// bit 16
-		u32 halt_status:1;	// bit 17
-		u32 unused2:14;		// bits 18-31
+		u32 unused2:14;		/* bits 18-31 */
+		u32 halt_status:1;	/* bit 17 */
+		u32 pkt_done_flush:1;	/* bit 16 */
+		u32 pkt_drop_disable:1;	/* bit 15 */
+		u32 unused1:1;		/* bit 14 */
+		u32 fbr1_enable:1;	/* bit 13 */
+		u32 fbr1_size:2;	/* bits 11-12 */
+		u32 fbr0_enable:1;	/* bit 10 */
+		u32 fbr0_size:2;	/* bits 8-9 */
+		u32 dma_big_endian:1;	/* bit 7 */
+		u32 pkt_big_endian:1;	/* bit 6 */
+		u32 psr_big_endian:1;	/* bit 5 */
+		u32 fbr_big_endian:1;	/* bit 4 */
+		u32 tc:3;		/* bits 1-3 */
+		u32 halt:1;		/* bit 0 */
+#else
+		u32 halt:1;		/* bit 0 */
+		u32 tc:3;		/* bits 1-3 */
+		u32 fbr_big_endian:1;	/* bit 4 */
+		u32 psr_big_endian:1;	/* bit 5 */
+		u32 pkt_big_endian:1;	/* bit 6 */
+		u32 dma_big_endian:1;	/* bit 7 */
+		u32 fbr0_size:2;	/* bits 8-9 */
+		u32 fbr0_enable:1;	/* bit 10 */
+		u32 fbr1_size:2;	/* bits 11-12 */
+		u32 fbr1_enable:1;	/* bit 13 */
+		u32 unused1:1;		/* bit 14 */
+		u32 pkt_drop_disable:1;	/* bit 15 */
+		u32 pkt_done_flush:1;	/* bit 16 */
+		u32 halt_status:1;	/* bit 17 */
+		u32 unused2:14;		/* bits 18-31 */
 #endif
 	} bits;
 } RXDMA_CSR_t, *PRXDMA_CSR_t;
@@ -590,11 +354,11 @@ typedef union _RXDMA_NUM_PKT_DONE_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:24;	// bits 8-31
-		u32 num_done:8;	// bits 0-7
+		u32 unused:24;	/* bits 8-31 */
+		u32 num_done:8;	/* bits 0-7 */
 #else
-		u32 num_done:8;	// bits 0-7
-		u32 unused:24;	// bits 8-31
+		u32 num_done:8;	/* bits 0-7 */
+		u32 unused:24;	/* bits 8-31 */
 #endif
 	} bits;
 } RXDMA_NUM_PKT_DONE_t, *PRXDMA_NUM_PKT_DONE_t;
@@ -607,11 +371,11 @@ typedef union _RXDMA_MAX_PKT_TIME_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:14;		// bits 18-31
-		u32 time_done:18;	// bits 0-17
+		u32 unused:14;		/* bits 18-31 */
+		u32 time_done:18;	/* bits 0-17 */
 #else
-		u32 time_done:18;	// bits 0-17
-		u32 unused:14;		// bits 18-31
+		u32 time_done:18;	/* bits 0-17 */
+		u32 unused:14;		/* bits 18-31 */
 #endif
 	} bits;
 } RXDMA_MAX_PKT_TIME_t, *PRXDMA_MAX_PKT_TIME_t;
@@ -619,19 +383,19 @@ typedef union _RXDMA_MAX_PKT_TIME_t {
 /*
  * structure for rx queue read address reg in rxdma address map
  * located at address 0x2014
- * Defined earlier (DMA10W_t)
+ * Defined earlier (u32)
  */
 
 /*
  * structure for rx queue read address external reg in rxdma address map
  * located at address 0x2018
- * Defined earlier (DMA10W_t)
+ * Defined earlier (u32)
  */
 
 /*
  * structure for rx queue write address reg in rxdma address map
  * located at address 0x201C
- * Defined earlier (DMA10W_t)
+ * Defined earlier (u32)
  */
 
 /*
@@ -654,11 +418,11 @@ typedef union _RXDMA_PSR_NUM_DES_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;		// bits 12-31
-		u32 psr_ndes:12;	// bit 0-11
+		u32 unused:20;		/* bits 12-31 */
+		u32 psr_ndes:12;	/* bit 0-11 */
 #else
-		u32 psr_ndes:12;	// bit 0-11
-		u32 unused:20;		// bits 12-31
+		u32 psr_ndes:12;	/* bit 0-11 */
+		u32 unused:20;		/* bits 12-31 */
 #endif
 	} bits;
 } RXDMA_PSR_NUM_DES_t, *PRXDMA_PSR_NUM_DES_t;
@@ -671,13 +435,13 @@ typedef union _RXDMA_PSR_AVAIL_OFFSET_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:19;		// bits 13-31
-		u32 psr_avail_wrap:1;	// bit 12
-		u32 psr_avail:12;	// bit 0-11
+		u32 unused:19;		/* bits 13-31 */
+		u32 psr_avail_wrap:1;	/* bit 12 */
+		u32 psr_avail:12;	/* bit 0-11 */
 #else
-		u32 psr_avail:12;	// bit 0-11
-		u32 psr_avail_wrap:1;	// bit 12
-		u32 unused:19;		// bits 13-31
+		u32 psr_avail:12;	/* bit 0-11 */
+		u32 psr_avail_wrap:1;	/* bit 12 */
+		u32 unused:19;		/* bits 13-31 */
 #endif
 	} bits;
 } RXDMA_PSR_AVAIL_OFFSET_t, *PRXDMA_PSR_AVAIL_OFFSET_t;
@@ -690,13 +454,13 @@ typedef union _RXDMA_PSR_FULL_OFFSET_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:19;		// bits 13-31
-		u32 psr_full_wrap:1;	// bit 12
-		u32 psr_full:12;	// bit 0-11
+		u32 unused:19;		/* bits 13-31 */
+		u32 psr_full_wrap:1;	/* bit 12 */
+		u32 psr_full:12;	/* bit 0-11 */
 #else
-		u32 psr_full:12;	// bit 0-11
-		u32 psr_full_wrap:1;	// bit 12
-		u32 unused:19;		// bits 13-31
+		u32 psr_full:12;	/* bit 0-11 */
+		u32 psr_full_wrap:1;	/* bit 12 */
+		u32 unused:19;		/* bits 13-31 */
 #endif
 	} bits;
 } RXDMA_PSR_FULL_OFFSET_t, *PRXDMA_PSR_FULL_OFFSET_t;
@@ -709,11 +473,11 @@ typedef union _RXDMA_PSR_ACCESS_INDEX_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:27;	// bits 5-31
-		u32 psr_ai:5;	// bits 0-4
+		u32 unused:27;	/* bits 5-31 */
+		u32 psr_ai:5;	/* bits 0-4 */
 #else
-		u32 psr_ai:5;	// bits 0-4
-		u32 unused:27;	// bits 5-31
+		u32 psr_ai:5;	/* bits 0-4 */
+		u32 unused:27;	/* bits 5-31 */
 #endif
 	} bits;
 } RXDMA_PSR_ACCESS_INDEX_t, *PRXDMA_PSR_ACCESS_INDEX_t;
@@ -726,11 +490,11 @@ typedef union _RXDMA_PSR_MIN_DES_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;	// bits 12-31
-		u32 psr_min:12;	// bits 0-11
+		u32 unused:20;	/* bits 12-31 */
+		u32 psr_min:12;	/* bits 0-11 */
 #else
-		u32 psr_min:12;	// bits 0-11
-		u32 unused:20;	// bits 12-31
+		u32 psr_min:12;	/* bits 0-11 */
+		u32 unused:20;	/* bits 12-31 */
 #endif
 	} bits;
 } RXDMA_PSR_MIN_DES_t, *PRXDMA_PSR_MIN_DES_t;
@@ -755,11 +519,11 @@ typedef union _RXDMA_FBR_NUM_DES_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;		// bits 10-31
-		u32 fbr_ndesc:10;	// bits 0-9
+		u32 unused:22;		/* bits 10-31 */
+		u32 fbr_ndesc:10;	/* bits 0-9 */
 #else
-		u32 fbr_ndesc:10;	// bits 0-9
-		u32 unused:22;		// bits 10-31
+		u32 fbr_ndesc:10;	/* bits 0-9 */
+		u32 unused:22;		/* bits 10-31 */
 #endif
 	} bits;
 } RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t;
@@ -767,13 +531,13 @@ typedef union _RXDMA_FBR_NUM_DES_t {
 /*
  * structure for free buffer ring 0 available offset reg in rxdma address map
  * located at address 0x2048
- * Defined earlier (DMA10W_t)
+ * Defined earlier (u32)
  */
 
 /*
  * structure for free buffer ring 0 full offset reg in rxdma address map
  * located at address 0x204C
- * Defined earlier (DMA10W_t)
+ * Defined earlier (u32)
  */
 
 /*
@@ -784,11 +548,11 @@ typedef union _RXDMA_FBC_RD_INDEX_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:27;	// bits 5-31
-		u32 fbc_rdi:5;	// bit 0-4
+		u32 unused:27;	/* bits 5-31 */
+		u32 fbc_rdi:5;	/* bit 0-4 */
 #else
-		u32 fbc_rdi:5;	// bit 0-4
-		u32 unused:27;	// bits 5-31
+		u32 fbc_rdi:5;	/* bit 0-4 */
+		u32 unused:27;	/* bits 5-31 */
 #endif
 	} bits;
 } RXDMA_FBC_RD_INDEX_t, *PRXDMA_FBC_RD_INDEX_t;
@@ -801,11 +565,11 @@ typedef union _RXDMA_FBR_MIN_DES_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:22;	// bits 10-31
-		u32 fbr_min:10;	// bits 0-9
+		u32 unused:22;	/* bits 10-31 */
+		u32 fbr_min:10;	/* bits 0-9 */
 #else
-		u32 fbr_min:10;	// bits 0-9
-		u32 unused:22;	// bits 10-31
+		u32 fbr_min:10;	/* bits 0-9 */
+		u32 unused:22;	/* bits 10-31 */
 #endif
 	} bits;
 } RXDMA_FBR_MIN_DES_t, *PRXDMA_FBR_MIN_DES_t;
@@ -850,36 +614,36 @@ typedef union _RXDMA_FBR_MIN_DES_t {
  * Rx DMA Module of JAGCore Address Mapping
  * Located at address 0x2000
  */
-typedef struct _RXDMA_t {				// Location:
-	RXDMA_CSR_t csr;				//  0x2000
-	u32 dma_wb_base_lo;				//  0x2004
-	u32 dma_wb_base_hi;				//  0x2008
-	RXDMA_NUM_PKT_DONE_t num_pkt_done;		//  0x200C
-	RXDMA_MAX_PKT_TIME_t max_pkt_time;		//  0x2010
-	DMA10W_t rxq_rd_addr;				//  0x2014
-	DMA10W_t rxq_rd_addr_ext;			//  0x2018
-	DMA10W_t rxq_wr_addr;				//  0x201C
-	u32 psr_base_lo;				//  0x2020
-	u32 psr_base_hi;				//  0x2024
-	RXDMA_PSR_NUM_DES_t psr_num_des;		//  0x2028
-	RXDMA_PSR_AVAIL_OFFSET_t psr_avail_offset;	//  0x202C
-	RXDMA_PSR_FULL_OFFSET_t psr_full_offset;	//  0x2030
-	RXDMA_PSR_ACCESS_INDEX_t psr_access_index;	//  0x2034
-	RXDMA_PSR_MIN_DES_t psr_min_des;		//  0x2038
-	u32 fbr0_base_lo;				//  0x203C
-	u32 fbr0_base_hi;				//  0x2040
-	RXDMA_FBR_NUM_DES_t fbr0_num_des;		//  0x2044
-	DMA10W_t fbr0_avail_offset;			//  0x2048
-	DMA10W_t fbr0_full_offset;			//  0x204C
-	RXDMA_FBC_RD_INDEX_t fbr0_rd_index;		//  0x2050
-	RXDMA_FBR_MIN_DES_t fbr0_min_des;		//  0x2054
-	u32 fbr1_base_lo;				//  0x2058
-	u32 fbr1_base_hi;				//  0x205C
-	RXDMA_FBR_NUM_DES_t fbr1_num_des;		//  0x2060
-	DMA10W_t fbr1_avail_offset;			//  0x2064
-	DMA10W_t fbr1_full_offset;			//  0x2068
-	RXDMA_FBC_RD_INDEX_t fbr1_rd_index;		//  0x206C
-	RXDMA_FBR_MIN_DES_t fbr1_min_des;		//  0x2070
+typedef struct _RXDMA_t {				/* Location: */
+	RXDMA_CSR_t csr;				/*  0x2000 */
+	u32 dma_wb_base_lo;				/*  0x2004 */
+	u32 dma_wb_base_hi;				/*  0x2008 */
+	RXDMA_NUM_PKT_DONE_t num_pkt_done;		/*  0x200C */
+	RXDMA_MAX_PKT_TIME_t max_pkt_time;		/*  0x2010 */
+	u32 rxq_rd_addr;				/*  0x2014 */
+	u32 rxq_rd_addr_ext;			/*  0x2018 */
+	u32 rxq_wr_addr;				/*  0x201C */
+	u32 psr_base_lo;				/*  0x2020 */
+	u32 psr_base_hi;				/*  0x2024 */
+	RXDMA_PSR_NUM_DES_t psr_num_des;		/*  0x2028 */
+	RXDMA_PSR_AVAIL_OFFSET_t psr_avail_offset;	/*  0x202C */
+	RXDMA_PSR_FULL_OFFSET_t psr_full_offset;	/*  0x2030 */
+	RXDMA_PSR_ACCESS_INDEX_t psr_access_index;	/*  0x2034 */
+	RXDMA_PSR_MIN_DES_t psr_min_des;		/*  0x2038 */
+	u32 fbr0_base_lo;				/*  0x203C */
+	u32 fbr0_base_hi;				/*  0x2040 */
+	RXDMA_FBR_NUM_DES_t fbr0_num_des;		/*  0x2044 */
+	u32 fbr0_avail_offset;			/*  0x2048 */
+	u32 fbr0_full_offset;			/*  0x204C */
+	RXDMA_FBC_RD_INDEX_t fbr0_rd_index;		/*  0x2050 */
+	RXDMA_FBR_MIN_DES_t fbr0_min_des;		/*  0x2054 */
+	u32 fbr1_base_lo;				/*  0x2058 */
+	u32 fbr1_base_hi;				/*  0x205C */
+	RXDMA_FBR_NUM_DES_t fbr1_num_des;		/*  0x2060 */
+	u32 fbr1_avail_offset;			/*  0x2064 */
+	u32 fbr1_full_offset;			/*  0x2068 */
+	RXDMA_FBC_RD_INDEX_t fbr1_rd_index;		/*  0x206C */
+	RXDMA_FBR_MIN_DES_t fbr1_min_des;		/*  0x2070 */
 } RXDMA_t, *PRXDMA_t;
 
 /* END OF RXDMA REGISTER ADDRESS MAP */
@@ -895,25 +659,25 @@ typedef union _TXMAC_CTL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:24;		// bits 8-31
-		u32 cklseg_diable:1;	// bit 7
-		u32 ckbcnt_disable:1;	// bit 6
-		u32 cksegnum:1;		// bit 5
-		u32 async_disable:1;	// bit 4
-		u32 fc_disable:1;	// bit 3
-		u32 mcif_disable:1;	// bit 2
-		u32 mif_disable:1;	// bit 1
-		u32 txmac_en:1;		// bit 0
+		u32 unused:24;		/* bits 8-31 */
+		u32 cklseg_diable:1;	/* bit 7 */
+		u32 ckbcnt_disable:1;	/* bit 6 */
+		u32 cksegnum:1;		/* bit 5 */
+		u32 async_disable:1;	/* bit 4 */
+		u32 fc_disable:1;	/* bit 3 */
+		u32 mcif_disable:1;	/* bit 2 */
+		u32 mif_disable:1;	/* bit 1 */
+		u32 txmac_en:1;		/* bit 0 */
 #else
-		u32 txmac_en:1;		// bit 0
-		u32 mif_disable:1;	// bit 1 mac interface
-		u32 mcif_disable:1;	// bit 2 mem. contr. interface
-		u32 fc_disable:1;	// bit 3
-		u32 async_disable:1;	// bit 4
-		u32 cksegnum:1;		// bit 5
-		u32 ckbcnt_disable:1;	// bit 6
-		u32 cklseg_diable:1;	// bit 7
-		u32 unused:24;		// bits 8-31
+		u32 txmac_en:1;		/* bit 0 */
+		u32 mif_disable:1;	/* bit 1 mac interface */
+		u32 mcif_disable:1;	/* bit 2 mem. contr. interface */
+		u32 fc_disable:1;	/* bit 3 */
+		u32 async_disable:1;	/* bit 4 */
+		u32 cksegnum:1;		/* bit 5 */
+		u32 ckbcnt_disable:1;	/* bit 6 */
+		u32 cklseg_diable:1;	/* bit 7 */
+		u32 unused:24;		/* bits 8-31 */
 #endif
 	} bits;
 } TXMAC_CTL_t, *PTXMAC_CTL_t;
@@ -926,15 +690,15 @@ typedef union _TXMAC_SHADOW_PTR_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:5;	// bits 27-31
-		u32 txq_rd_ptr:11;	// bits 16-26
-		u32 reserved:5;		// bits 11-15
-		u32 txq_wr_ptr:11;	// bits 0-10
+		u32 reserved2:5;	/* bits 27-31 */
+		u32 txq_rd_ptr:11;	/* bits 16-26 */
+		u32 reserved:5;		/* bits 11-15 */
+		u32 txq_wr_ptr:11;	/* bits 0-10 */
 #else
-		u32 txq_wr_ptr:11;	// bits 0-10
-		u32 reserved:5;		// bits 11-15
-		u32 txq_rd_ptr:11;	// bits 16-26
-		u32 reserved2:5;	// bits 27-31
+		u32 txq_wr_ptr:11;	/* bits 0-10 */
+		u32 reserved:5;		/* bits 11-15 */
+		u32 txq_rd_ptr:11;	/* bits 16-26 */
+		u32 reserved2:5;	/* bits 27-31 */
 #endif
 	} bits;
 } TXMAC_SHADOW_PTR_t, *PTXMAC_SHADOW_PTR_t;
@@ -947,15 +711,15 @@ typedef union _TXMAC_ERR_CNT_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;		// bits 12-31
-		u32 reserved:4;		// bits 8-11
-		u32 txq_underrun:4;	// bits 4-7
-		u32 fifo_underrun:4;	// bits 0-3
+		u32 unused:20;		/* bits 12-31 */
+		u32 reserved:4;		/* bits 8-11 */
+		u32 txq_underrun:4;	/* bits 4-7 */
+		u32 fifo_underrun:4;	/* bits 0-3 */
 #else
-		u32 fifo_underrun:4;	// bits 0-3
-		u32 txq_underrun:4;	// bits 4-7
-		u32 reserved:4;		// bits 8-11
-		u32 unused:20;		// bits 12-31
+		u32 fifo_underrun:4;	/* bits 0-3 */
+		u32 txq_underrun:4;	/* bits 4-7 */
+		u32 reserved:4;		/* bits 8-11 */
+		u32 unused:20;		/* bits 12-31 */
 #endif
 	} bits;
 } TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t;
@@ -968,11 +732,11 @@ typedef union _TXMAC_MAX_FILL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:20;		// bits 12-31
-		u32 max_fill:12;	// bits 0-11
+		u32 unused:20;		/* bits 12-31 */
+		u32 max_fill:12;	/* bits 0-11 */
 #else
-		u32 max_fill:12;	// bits 0-11
-		u32 unused:20;		// bits 12-31
+		u32 max_fill:12;	/* bits 0-11 */
+		u32 unused:20;		/* bits 12-31 */
 #endif
 	} bits;
 } TXMAC_MAX_FILL_t, *PTXMAC_MAX_FILL_t;
@@ -985,11 +749,11 @@ typedef union _TXMAC_CF_PARAM_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 cfep:16;	// bits 16-31
-		u32 cfpt:16;	// bits 0-15
+		u32 cfep:16;	/* bits 16-31 */
+		u32 cfpt:16;	/* bits 0-15 */
 #else
-		u32 cfpt:16;	// bits 0-15
-		u32 cfep:16;	// bits 16-31
+		u32 cfpt:16;	/* bits 0-15 */
+		u32 cfep:16;	/* bits 16-31 */
 #endif
 	} bits;
 } TXMAC_CF_PARAM_t, *PTXMAC_CF_PARAM_t;
@@ -1002,17 +766,17 @@ typedef union _TXMAC_TXTEST_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused2:15;		// bits 17-31
-		u32 reserved1:1;	// bit 16
-		u32 txtest_en:1;	// bit 15
-		u32 unused1:4;		// bits 11-14
-		u32 txqtest_ptr:11;	// bits 0-11
+		u32 unused2:15;		/* bits 17-31 */
+		u32 reserved1:1;	/* bit 16 */
+		u32 txtest_en:1;	/* bit 15 */
+		u32 unused1:4;		/* bits 11-14 */
+		u32 txqtest_ptr:11;	/* bits 0-11 */
 #else
-		u32 txqtest_ptr:11;	// bits 0-10
-		u32 unused1:4;		// bits 11-14
-		u32 txtest_en:1;	// bit 15
-		u32 reserved1:1;	// bit 16
-		u32 unused2:15;		// bits 17-31
+		u32 txqtest_ptr:11;	/* bits 0-10 */
+		u32 unused1:4;		/* bits 11-14 */
+		u32 txtest_en:1;	/* bit 15 */
+		u32 reserved1:1;	/* bit 16 */
+		u32 unused2:15;		/* bits 17-31 */
 #endif
 	} bits;
 } TXMAC_TXTEST_t, *PTXMAC_TXTEST_t;
@@ -1025,25 +789,25 @@ typedef union _TXMAC_ERR_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused2:23;		// bits 9-31
-		u32 fifo_underrun:1;	// bit 8
-		u32 unused1:2;		// bits 6-7
-		u32 ctrl2_err:1;	// bit 5
-		u32 txq_underrun:1;	// bit 4
-		u32 bcnt_err:1;		// bit 3
-		u32 lseg_err:1;		// bit 2
-		u32 segnum_err:1;	// bit 1
-		u32 seg0_err:1;		// bit 0
+		u32 unused2:23;		/* bits 9-31 */
+		u32 fifo_underrun:1;	/* bit 8 */
+		u32 unused1:2;		/* bits 6-7 */
+		u32 ctrl2_err:1;	/* bit 5 */
+		u32 txq_underrun:1;	/* bit 4 */
+		u32 bcnt_err:1;		/* bit 3 */
+		u32 lseg_err:1;		/* bit 2 */
+		u32 segnum_err:1;	/* bit 1 */
+		u32 seg0_err:1;		/* bit 0 */
 #else
-		u32 seg0_err:1;		// bit 0
-		u32 segnum_err:1;	// bit 1
-		u32 lseg_err:1;		// bit 2
-		u32 bcnt_err:1;		// bit 3
-		u32 txq_underrun:1;	// bit 4
-		u32 ctrl2_err:1;	// bit 5
-		u32 unused1:2;		// bits 6-7
-		u32 fifo_underrun:1;	// bit 8
-		u32 unused2:23;		// bits 9-31
+		u32 seg0_err:1;		/* bit 0 */
+		u32 segnum_err:1;	/* bit 1 */
+		u32 lseg_err:1;		/* bit 2 */
+		u32 bcnt_err:1;		/* bit 3 */
+		u32 txq_underrun:1;	/* bit 4 */
+		u32 ctrl2_err:1;	/* bit 5 */
+		u32 unused1:2;		/* bits 6-7 */
+		u32 fifo_underrun:1;	/* bit 8 */
+		u32 unused2:23;		/* bits 9-31 */
 #endif
 	} bits;
 } TXMAC_ERR_t, *PTXMAC_ERR_t;
@@ -1056,25 +820,25 @@ typedef union _TXMAC_ERR_INT_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused2:23;		// bits 9-31
-		u32 fifo_underrun:1;	// bit 8
-		u32 unused1:2;		// bits 6-7
-		u32 ctrl2_err:1;	// bit 5
-		u32 txq_underrun:1;	// bit 4
-		u32 bcnt_err:1;		// bit 3
-		u32 lseg_err:1;		// bit 2
-		u32 segnum_err:1;	// bit 1
-		u32 seg0_err:1;		// bit 0
+		u32 unused2:23;		/* bits 9-31 */
+		u32 fifo_underrun:1;	/* bit 8 */
+		u32 unused1:2;		/* bits 6-7 */
+		u32 ctrl2_err:1;	/* bit 5 */
+		u32 txq_underrun:1;	/* bit 4 */
+		u32 bcnt_err:1;		/* bit 3 */
+		u32 lseg_err:1;		/* bit 2 */
+		u32 segnum_err:1;	/* bit 1 */
+		u32 seg0_err:1;		/* bit 0 */
 #else
-		u32 seg0_err:1;		// bit 0
-		u32 segnum_err:1;	// bit 1
-		u32 lseg_err:1;		// bit 2
-		u32 bcnt_err:1;		// bit 3
-		u32 txq_underrun:1;	// bit 4
-		u32 ctrl2_err:1;	// bit 5
-		u32 unused1:2;		// bits 6-7
-		u32 fifo_underrun:1;	// bit 8
-		u32 unused2:23;		// bits 9-31
+		u32 seg0_err:1;		/* bit 0 */
+		u32 segnum_err:1;	/* bit 1 */
+		u32 lseg_err:1;		/* bit 2 */
+		u32 bcnt_err:1;		/* bit 3 */
+		u32 txq_underrun:1;	/* bit 4 */
+		u32 ctrl2_err:1;	/* bit 5 */
+		u32 unused1:2;		/* bits 6-7 */
+		u32 fifo_underrun:1;	/* bit 8 */
+		u32 unused2:23;		/* bits 9-31 */
 #endif
 	} bits;
 } TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t;
@@ -1087,13 +851,13 @@ typedef union _TXMAC_CP_CTRL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:30;		// bits 2-31
-		u32 bp_req:1;		// bit 1
-		u32 bp_xonxoff:1;	// bit 0
+		u32 unused:30;		/* bits 2-31 */
+		u32 bp_req:1;		/* bit 1 */
+		u32 bp_xonxoff:1;	/* bit 0 */
 #else
-		u32 bp_xonxoff:1;	// bit 0
-		u32 bp_req:1;		// bit 1
-		u32 unused:30;		// bits 2-31
+		u32 bp_xonxoff:1;	/* bit 0 */
+		u32 bp_req:1;		/* bit 1 */
+		u32 unused:30;		/* bits 2-31 */
 #endif
 	} bits;
 } TXMAC_BP_CTRL_t, *PTXMAC_BP_CTRL_t;
@@ -1101,16 +865,16 @@ typedef union _TXMAC_CP_CTRL_t {
 /*
  * Tx MAC Module of JAGCore Address Mapping
  */
-typedef struct _TXMAC_t {		// Location:
-	TXMAC_CTL_t ctl;		//  0x3000
-	TXMAC_SHADOW_PTR_t shadow_ptr;	//  0x3004
-	TXMAC_ERR_CNT_t err_cnt;	//  0x3008
-	TXMAC_MAX_FILL_t max_fill;	//  0x300C
-	TXMAC_CF_PARAM_t cf_param;	//  0x3010
-	TXMAC_TXTEST_t tx_test;		//  0x3014
-	TXMAC_ERR_t err;		//  0x3018
-	TXMAC_ERR_INT_t err_int;	//  0x301C
-	TXMAC_BP_CTRL_t bp_ctrl;	//  0x3020
+typedef struct _TXMAC_t {		/* Location: */
+	TXMAC_CTL_t ctl;		/*  0x3000 */
+	TXMAC_SHADOW_PTR_t shadow_ptr;	/*  0x3004 */
+	TXMAC_ERR_CNT_t err_cnt;	/*  0x3008 */
+	TXMAC_MAX_FILL_t max_fill;	/*  0x300C */
+	TXMAC_CF_PARAM_t cf_param;	/*  0x3010 */
+	TXMAC_TXTEST_t tx_test;		/*  0x3014 */
+	TXMAC_ERR_t err;		/*  0x3018 */
+	TXMAC_ERR_INT_t err_int;	/*  0x301C */
+	TXMAC_BP_CTRL_t bp_ctrl;	/*  0x3020 */
 } TXMAC_t, *PTXMAC_t;
 
 /* END OF TXMAC REGISTER ADDRESS MAP */
@@ -1125,23 +889,23 @@ typedef union _RXMAC_CTRL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:25;		// bits 7-31
-		u32 rxmac_int_disable:1;	// bit 6
-		u32 async_disable:1;		// bit 5
-		u32 mif_disable:1;		// bit 4
-		u32 wol_disable:1;		// bit 3
-		u32 pkt_filter_disable:1;	// bit 2
-		u32 mcif_disable:1;		// bit 1
-		u32 rxmac_en:1;			// bit 0
+		u32 reserved:25;		/* bits 7-31 */
+		u32 rxmac_int_disable:1;	/* bit 6 */
+		u32 async_disable:1;		/* bit 5 */
+		u32 mif_disable:1;		/* bit 4 */
+		u32 wol_disable:1;		/* bit 3 */
+		u32 pkt_filter_disable:1;	/* bit 2 */
+		u32 mcif_disable:1;		/* bit 1 */
+		u32 rxmac_en:1;			/* bit 0 */
 #else
-		u32 rxmac_en:1;			// bit 0
-		u32 mcif_disable:1;		// bit 1
-		u32 pkt_filter_disable:1;	// bit 2
-		u32 wol_disable:1;		// bit 3
-		u32 mif_disable:1;		// bit 4
-		u32 async_disable:1;		// bit 5
-		u32 rxmac_int_disable:1;	// bit 6
-		u32 reserved:25;		// bits 7-31
+		u32 rxmac_en:1;			/* bit 0 */
+		u32 mcif_disable:1;		/* bit 1 */
+		u32 pkt_filter_disable:1;	/* bit 2 */
+		u32 wol_disable:1;		/* bit 3 */
+		u32 mif_disable:1;		/* bit 4 */
+		u32 async_disable:1;		/* bit 5 */
+		u32 rxmac_int_disable:1;	/* bit 6 */
+		u32 reserved:25;		/* bits 7-31 */
 #endif
 	} bits;
 } RXMAC_CTRL_t, *PRXMAC_CTRL_t;
@@ -1154,35 +918,35 @@ typedef union _RXMAC_WOL_CTL_CRC0_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 crc0:16;		// bits 16-31
-		u32 reserve:4;		// bits 12-15
-		u32 ignore_pp:1;	// bit 11
-		u32 ignore_mp:1;	// bit 10
-		u32 clr_intr:1;		// bit 9
-		u32 ignore_link_chg:1;	// bit 8
-		u32 ignore_uni:1;	// bit 7
-		u32 ignore_multi:1;	// bit 6
-		u32 ignore_broad:1;	// bit 5
-		u32 valid_crc4:1;	// bit 4
-		u32 valid_crc3:1;	// bit 3
-		u32 valid_crc2:1;	// bit 2
-		u32 valid_crc1:1;	// bit 1
-		u32 valid_crc0:1;	// bit 0
-#else
-		u32 valid_crc0:1;	// bit 0
-		u32 valid_crc1:1;	// bit 1
-		u32 valid_crc2:1;	// bit 2
-		u32 valid_crc3:1;	// bit 3
-		u32 valid_crc4:1;	// bit 4
-		u32 ignore_broad:1;	// bit 5
-		u32 ignore_multi:1;	// bit 6
-		u32 ignore_uni:1;	// bit 7
-		u32 ignore_link_chg:1;	// bit 8
-		u32 clr_intr:1;		// bit 9
-		u32 ignore_mp:1;	// bit 10
-		u32 ignore_pp:1;	// bit 11
-		u32 reserve:4;		// bits 12-15
-		u32 crc0:16;		// bits 16-31
+		u32 crc0:16;		/* bits 16-31 */
+		u32 reserve:4;		/* bits 12-15 */
+		u32 ignore_pp:1;	/* bit 11 */
+		u32 ignore_mp:1;	/* bit 10 */
+		u32 clr_intr:1;		/* bit 9 */
+		u32 ignore_link_chg:1;	/* bit 8 */
+		u32 ignore_uni:1;	/* bit 7 */
+		u32 ignore_multi:1;	/* bit 6 */
+		u32 ignore_broad:1;	/* bit 5 */
+		u32 valid_crc4:1;	/* bit 4 */
+		u32 valid_crc3:1;	/* bit 3 */
+		u32 valid_crc2:1;	/* bit 2 */
+		u32 valid_crc1:1;	/* bit 1 */
+		u32 valid_crc0:1;	/* bit 0 */
+#else
+		u32 valid_crc0:1;	/* bit 0 */
+		u32 valid_crc1:1;	/* bit 1 */
+		u32 valid_crc2:1;	/* bit 2 */
+		u32 valid_crc3:1;	/* bit 3 */
+		u32 valid_crc4:1;	/* bit 4 */
+		u32 ignore_broad:1;	/* bit 5 */
+		u32 ignore_multi:1;	/* bit 6 */
+		u32 ignore_uni:1;	/* bit 7 */
+		u32 ignore_link_chg:1;	/* bit 8 */
+		u32 clr_intr:1;		/* bit 9 */
+		u32 ignore_mp:1;	/* bit 10 */
+		u32 ignore_pp:1;	/* bit 11 */
+		u32 reserve:4;		/* bits 12-15 */
+		u32 crc0:16;		/* bits 16-31 */
 #endif
 	} bits;
 } RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t;
@@ -1195,11 +959,11 @@ typedef union _RXMAC_WOL_CRC12_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 crc2:16;	// bits 16-31
-		u32 crc1:16;	// bits 0-15
+		u32 crc2:16;	/* bits 16-31 */
+		u32 crc1:16;	/* bits 0-15 */
 #else
-		u32 crc1:16;	// bits 0-15
-		u32 crc2:16;	// bits 16-31
+		u32 crc1:16;	/* bits 0-15 */
+		u32 crc2:16;	/* bits 16-31 */
 #endif
 	} bits;
 } RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t;
@@ -1212,11 +976,11 @@ typedef union _RXMAC_WOL_CRC34_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 crc4:16;	// bits 16-31
-		u32 crc3:16;	// bits 0-15
+		u32 crc4:16;	/* bits 16-31 */
+		u32 crc3:16;	/* bits 0-15 */
 #else
-		u32 crc3:16;	// bits 0-15
-		u32 crc4:16;	// bits 16-31
+		u32 crc3:16;	/* bits 0-15 */
+		u32 crc4:16;	/* bits 16-31 */
 #endif
 	} bits;
 } RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t;
@@ -1229,15 +993,15 @@ typedef union _RXMAC_WOL_SA_LO_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 sa3:8;	// bits 24-31
-		u32 sa4:8;	// bits 16-23
-		u32 sa5:8;	// bits 8-15
-		u32 sa6:8;	// bits 0-7
+		u32 sa3:8;	/* bits 24-31 */
+		u32 sa4:8;	/* bits 16-23 */
+		u32 sa5:8;	/* bits 8-15 */
+		u32 sa6:8;	/* bits 0-7 */
 #else
-		u32 sa6:8;	// bits 0-7
-		u32 sa5:8;	// bits 8-15
-		u32 sa4:8;	// bits 16-23
-		u32 sa3:8;	// bits 24-31
+		u32 sa6:8;	/* bits 0-7 */
+		u32 sa5:8;	/* bits 8-15 */
+		u32 sa4:8;	/* bits 16-23 */
+		u32 sa3:8;	/* bits 24-31 */
 #endif
 	} bits;
 } RXMAC_WOL_SA_LO_t, *PRXMAC_WOL_SA_LO_t;
@@ -1250,13 +1014,13 @@ typedef union _RXMAC_WOL_SA_HI_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:16;	// bits 16-31
-		u32 sa1:8;		// bits 8-15
-		u32 sa2:8;		// bits 0-7
+		u32 reserved:16;	/* bits 16-31 */
+		u32 sa1:8;		/* bits 8-15 */
+		u32 sa2:8;		/* bits 0-7 */
 #else
-		u32 sa2:8;		// bits 0-7
-		u32 sa1:8;		// bits 8-15
-		u32 reserved:16;	// bits 16-31
+		u32 sa2:8;		/* bits 0-7 */
+		u32 sa1:8;		/* bits 8-15 */
+		u32 reserved:16;	/* bits 16-31 */
 #endif
 	} bits;
 } RXMAC_WOL_SA_HI_t, *PRXMAC_WOL_SA_HI_t;
@@ -1275,15 +1039,15 @@ typedef union _RXMAC_UNI_PF_ADDR1_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 addr1_3:8;	// bits 24-31
-		u32 addr1_4:8;	// bits 16-23
-		u32 addr1_5:8;	// bits 8-15
-		u32 addr1_6:8;	// bits 0-7
+		u32 addr1_3:8;	/* bits 24-31 */
+		u32 addr1_4:8;	/* bits 16-23 */
+		u32 addr1_5:8;	/* bits 8-15 */
+		u32 addr1_6:8;	/* bits 0-7 */
 #else
-		u32 addr1_6:8;	// bits 0-7
-		u32 addr1_5:8;	// bits 8-15
-		u32 addr1_4:8;	// bits 16-23
-		u32 addr1_3:8;	// bits 24-31
+		u32 addr1_6:8;	/* bits 0-7 */
+		u32 addr1_5:8;	/* bits 8-15 */
+		u32 addr1_4:8;	/* bits 16-23 */
+		u32 addr1_3:8;	/* bits 24-31 */
 #endif
 	} bits;
 } RXMAC_UNI_PF_ADDR1_t, *PRXMAC_UNI_PF_ADDR1_t;
@@ -1296,15 +1060,15 @@ typedef union _RXMAC_UNI_PF_ADDR2_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 addr2_3:8;	// bits 24-31
-		u32 addr2_4:8;	// bits 16-23
-		u32 addr2_5:8;	// bits 8-15
-		u32 addr2_6:8;	// bits 0-7
+		u32 addr2_3:8;	/* bits 24-31 */
+		u32 addr2_4:8;	/* bits 16-23 */
+		u32 addr2_5:8;	/* bits 8-15 */
+		u32 addr2_6:8;	/* bits 0-7 */
 #else
-		u32 addr2_6:8;	// bits 0-7
-		u32 addr2_5:8;	// bits 8-15
-		u32 addr2_4:8;	// bits 16-23
-		u32 addr2_3:8;	// bits 24-31
+		u32 addr2_6:8;	/* bits 0-7 */
+		u32 addr2_5:8;	/* bits 8-15 */
+		u32 addr2_4:8;	/* bits 16-23 */
+		u32 addr2_3:8;	/* bits 24-31 */
 #endif
 	} bits;
 } RXMAC_UNI_PF_ADDR2_t, *PRXMAC_UNI_PF_ADDR2_t;
@@ -1317,15 +1081,15 @@ typedef union _RXMAC_UNI_PF_ADDR3_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 addr2_1:8;	// bits 24-31
-		u32 addr2_2:8;	// bits 16-23
-		u32 addr1_1:8;	// bits 8-15
-		u32 addr1_2:8;	// bits 0-7
+		u32 addr2_1:8;	/* bits 24-31 */
+		u32 addr2_2:8;	/* bits 16-23 */
+		u32 addr1_1:8;	/* bits 8-15 */
+		u32 addr1_2:8;	/* bits 0-7 */
 #else
-		u32 addr1_2:8;	// bits 0-7
-		u32 addr1_1:8;	// bits 8-15
-		u32 addr2_2:8;	// bits 16-23
-		u32 addr2_1:8;	// bits 24-31
+		u32 addr1_2:8;	/* bits 0-7 */
+		u32 addr1_1:8;	/* bits 8-15 */
+		u32 addr2_2:8;	/* bits 16-23 */
+		u32 addr2_1:8;	/* bits 24-31 */
 #endif
 	} bits;
 } RXMAC_UNI_PF_ADDR3_t, *PRXMAC_UNI_PF_ADDR3_t;
@@ -1344,21 +1108,21 @@ typedef union _RXMAC_PF_CTRL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused2:9;		// bits 23-31
-		u32 min_pkt_size:7;	// bits 16-22
-		u32 unused1:12;		// bits 4-15
-		u32 filter_frag_en:1;	// bit 3
-		u32 filter_uni_en:1;	// bit 2
-		u32 filter_multi_en:1;	// bit 1
-		u32 filter_broad_en:1;	// bit 0
+		u32 unused2:9;		/* bits 23-31 */
+		u32 min_pkt_size:7;	/* bits 16-22 */
+		u32 unused1:12;		/* bits 4-15 */
+		u32 filter_frag_en:1;	/* bit 3 */
+		u32 filter_uni_en:1;	/* bit 2 */
+		u32 filter_multi_en:1;	/* bit 1 */
+		u32 filter_broad_en:1;	/* bit 0 */
 #else
-		u32 filter_broad_en:1;	// bit 0
-		u32 filter_multi_en:1;	// bit 1
-		u32 filter_uni_en:1;	// bit 2
-		u32 filter_frag_en:1;	// bit 3
-		u32 unused1:12;		// bits 4-15
-		u32 min_pkt_size:7;	// bits 16-22
-		u32 unused2:9;		// bits 23-31
+		u32 filter_broad_en:1;	/* bit 0 */
+		u32 filter_multi_en:1;	/* bit 1 */
+		u32 filter_uni_en:1;	/* bit 2 */
+		u32 filter_frag_en:1;	/* bit 3 */
+		u32 unused1:12;		/* bits 4-15 */
+		u32 min_pkt_size:7;	/* bits 16-22 */
+		u32 unused2:9;		/* bits 23-31 */
 #endif
 	} bits;
 } RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t;
@@ -1371,15 +1135,15 @@ typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:22;	// bits 10-31
-		u32 max_size:8;	// bits 2-9
-		u32 fc_en:1;	// bit 1
-		u32 seg_en:1;	// bit 0
+		u32 reserved:22;	/* bits 10-31 */
+		u32 max_size:8;	/* bits 2-9 */
+		u32 fc_en:1;	/* bit 1 */
+		u32 seg_en:1;	/* bit 0 */
 #else
-		u32 seg_en:1;	// bit 0
-		u32 fc_en:1;	// bit 1
-		u32 max_size:8;	// bits 2-9
-		u32 reserved:22;	// bits 10-31
+		u32 seg_en:1;	/* bit 0 */
+		u32 fc_en:1;	/* bit 1 */
+		u32 max_size:8;	/* bits 2-9 */
+		u32 reserved:22;	/* bits 10-31 */
 #endif
 	} bits;
 } RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t;
@@ -1392,15 +1156,15 @@ typedef union _RXMAC_MCIF_WATER_MARK_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:6;	// bits 26-31
-		u32 mark_hi:10;	// bits 16-25
-		u32 reserved1:6;	// bits 10-15
-		u32 mark_lo:10;	// bits 0-9
+		u32 reserved2:6;	/* bits 26-31 */
+		u32 mark_hi:10;	/* bits 16-25 */
+		u32 reserved1:6;	/* bits 10-15 */
+		u32 mark_lo:10;	/* bits 0-9 */
 #else
-		u32 mark_lo:10;	// bits 0-9
-		u32 reserved1:6;	// bits 10-15
-		u32 mark_hi:10;	// bits 16-25
-		u32 reserved2:6;	// bits 26-31
+		u32 mark_lo:10;	/* bits 0-9 */
+		u32 reserved1:6;	/* bits 10-15 */
+		u32 mark_hi:10;	/* bits 16-25 */
+		u32 reserved2:6;	/* bits 26-31 */
 #endif
 	} bits;
 } RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t;
@@ -1413,15 +1177,15 @@ typedef union _RXMAC_RXQ_DIAG_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:6;	// bits 26-31
-		u32 rd_ptr:10;	// bits 16-25
-		u32 reserved1:6;	// bits 10-15
-		u32 wr_ptr:10;	// bits 0-9
+		u32 reserved2:6;	/* bits 26-31 */
+		u32 rd_ptr:10;	/* bits 16-25 */
+		u32 reserved1:6;	/* bits 10-15 */
+		u32 wr_ptr:10;	/* bits 0-9 */
 #else
-		u32 wr_ptr:10;	// bits 0-9
-		u32 reserved1:6;	// bits 10-15
-		u32 rd_ptr:10;	// bits 16-25
-		u32 reserved2:6;	// bits 26-31
+		u32 wr_ptr:10;	/* bits 0-9 */
+		u32 reserved1:6;	/* bits 10-15 */
+		u32 rd_ptr:10;	/* bits 16-25 */
+		u32 reserved2:6;	/* bits 26-31 */
 #endif
 	} bits;
 } RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t;
@@ -1434,15 +1198,15 @@ typedef union _RXMAC_SPACE_AVAIL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:15;		// bits 17-31
-		u32 space_avail_en:1;	// bit 16
-		u32 reserved1:6;		// bits 10-15
-		u32 space_avail:10;	// bits 0-9
+		u32 reserved2:15;		/* bits 17-31 */
+		u32 space_avail_en:1;	/* bit 16 */
+		u32 reserved1:6;		/* bits 10-15 */
+		u32 space_avail:10;	/* bits 0-9 */
 #else
-		u32 space_avail:10;	// bits 0-9
-		u32 reserved1:6;		// bits 10-15
-		u32 space_avail_en:1;	// bit 16
-		u32 reserved2:15;		// bits 17-31
+		u32 space_avail:10;	/* bits 0-9 */
+		u32 reserved1:6;		/* bits 10-15 */
+		u32 space_avail_en:1;	/* bit 16 */
+		u32 reserved2:15;		/* bits 17-31 */
 #endif
 	} bits;
 } RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t;
@@ -1455,13 +1219,13 @@ typedef union _RXMAC_MIF_CTL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserve:14;		// bits 18-31
-		u32 drop_pkt_en:1;		// bit 17
-		u32 drop_pkt_mask:17;	// bits 0-16
+		u32 reserve:14;		/* bits 18-31 */
+		u32 drop_pkt_en:1;		/* bit 17 */
+		u32 drop_pkt_mask:17;	/* bits 0-16 */
 #else
-		u32 drop_pkt_mask:17;	// bits 0-16
-		u32 drop_pkt_en:1;		// bit 17
-		u32 reserve:14;		// bits 18-31
+		u32 drop_pkt_mask:17;	/* bits 0-16 */
+		u32 drop_pkt_en:1;		/* bit 17 */
+		u32 reserve:14;		/* bits 18-31 */
 #endif
 	} bits;
 } RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t;
@@ -1474,17 +1238,17 @@ typedef union _RXMAC_ERROR_REG_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserve:28;	// bits 4-31
-		u32 mif:1;		// bit 3
-		u32 async:1;	// bit 2
-		u32 pkt_filter:1;	// bit 1
-		u32 mcif:1;	// bit 0
+		u32 reserve:28;	/* bits 4-31 */
+		u32 mif:1;		/* bit 3 */
+		u32 async:1;	/* bit 2 */
+		u32 pkt_filter:1;	/* bit 1 */
+		u32 mcif:1;	/* bit 0 */
 #else
-		u32 mcif:1;	// bit 0
-		u32 pkt_filter:1;	// bit 1
-		u32 async:1;	// bit 2
-		u32 mif:1;		// bit 3
-		u32 reserve:28;	// bits 4-31
+		u32 mcif:1;	/* bit 0 */
+		u32 pkt_filter:1;	/* bit 1 */
+		u32 async:1;	/* bit 2 */
+		u32 mif:1;		/* bit 3 */
+		u32 reserve:28;	/* bits 4-31 */
 #endif
 	} bits;
 } RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t;
@@ -1492,48 +1256,48 @@ typedef union _RXMAC_ERROR_REG_t {
 /*
  * Rx MAC Module of JAGCore Address Mapping
  */
-typedef struct _RXMAC_t {				// Location:
-	RXMAC_CTRL_t ctrl;				//  0x4000
-	RXMAC_WOL_CTL_CRC0_t crc0;			//  0x4004
-	RXMAC_WOL_CRC12_t crc12;			//  0x4008
-	RXMAC_WOL_CRC34_t crc34;			//  0x400C
-	RXMAC_WOL_SA_LO_t sa_lo;			//  0x4010
-	RXMAC_WOL_SA_HI_t sa_hi;			//  0x4014
-	u32 mask0_word0;				//  0x4018
-	u32 mask0_word1;				//  0x401C
-	u32 mask0_word2;				//  0x4020
-	u32 mask0_word3;				//  0x4024
-	u32 mask1_word0;				//  0x4028
-	u32 mask1_word1;				//  0x402C
-	u32 mask1_word2;				//  0x4030
-	u32 mask1_word3;				//  0x4034
-	u32 mask2_word0;				//  0x4038
-	u32 mask2_word1;				//  0x403C
-	u32 mask2_word2;				//  0x4040
-	u32 mask2_word3;				//  0x4044
-	u32 mask3_word0;				//  0x4048
-	u32 mask3_word1;				//  0x404C
-	u32 mask3_word2;				//  0x4050
-	u32 mask3_word3;				//  0x4054
-	u32 mask4_word0;				//  0x4058
-	u32 mask4_word1;				//  0x405C
-	u32 mask4_word2;				//  0x4060
-	u32 mask4_word3;				//  0x4064
-	RXMAC_UNI_PF_ADDR1_t uni_pf_addr1;		//  0x4068
-	RXMAC_UNI_PF_ADDR2_t uni_pf_addr2;		//  0x406C
-	RXMAC_UNI_PF_ADDR3_t uni_pf_addr3;		//  0x4070
-	u32 multi_hash1;				//  0x4074
-	u32 multi_hash2;				//  0x4078
-	u32 multi_hash3;				//  0x407C
-	u32 multi_hash4;				//  0x4080
-	RXMAC_PF_CTRL_t pf_ctrl;			//  0x4084
-	RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;	//  0x4088
-	RXMAC_MCIF_WATER_MARK_t mcif_water_mark;	//  0x408C
-	RXMAC_RXQ_DIAG_t rxq_diag;			//  0x4090
-	RXMAC_SPACE_AVAIL_t space_avail;		//  0x4094
-
-	RXMAC_MIF_CTL_t mif_ctrl;			//  0x4098
-	RXMAC_ERROR_REG_t err_reg;			//  0x409C
+typedef struct _RXMAC_t {				/* Location: */
+	RXMAC_CTRL_t ctrl;				/*  0x4000 */
+	RXMAC_WOL_CTL_CRC0_t crc0;			/*  0x4004 */
+	RXMAC_WOL_CRC12_t crc12;			/*  0x4008 */
+	RXMAC_WOL_CRC34_t crc34;			/*  0x400C */
+	RXMAC_WOL_SA_LO_t sa_lo;			/*  0x4010 */
+	RXMAC_WOL_SA_HI_t sa_hi;			/*  0x4014 */
+	u32 mask0_word0;				/*  0x4018 */
+	u32 mask0_word1;				/*  0x401C */
+	u32 mask0_word2;				/*  0x4020 */
+	u32 mask0_word3;				/*  0x4024 */
+	u32 mask1_word0;				/*  0x4028 */
+	u32 mask1_word1;				/*  0x402C */
+	u32 mask1_word2;				/*  0x4030 */
+	u32 mask1_word3;				/*  0x4034 */
+	u32 mask2_word0;				/*  0x4038 */
+	u32 mask2_word1;				/*  0x403C */
+	u32 mask2_word2;				/*  0x4040 */
+	u32 mask2_word3;				/*  0x4044 */
+	u32 mask3_word0;				/*  0x4048 */
+	u32 mask3_word1;				/*  0x404C */
+	u32 mask3_word2;				/*  0x4050 */
+	u32 mask3_word3;				/*  0x4054 */
+	u32 mask4_word0;				/*  0x4058 */
+	u32 mask4_word1;				/*  0x405C */
+	u32 mask4_word2;				/*  0x4060 */
+	u32 mask4_word3;				/*  0x4064 */
+	RXMAC_UNI_PF_ADDR1_t uni_pf_addr1;		/*  0x4068 */
+	RXMAC_UNI_PF_ADDR2_t uni_pf_addr2;		/*  0x406C */
+	RXMAC_UNI_PF_ADDR3_t uni_pf_addr3;		/*  0x4070 */
+	u32 multi_hash1;				/*  0x4074 */
+	u32 multi_hash2;				/*  0x4078 */
+	u32 multi_hash3;				/*  0x407C */
+	u32 multi_hash4;				/*  0x4080 */
+	RXMAC_PF_CTRL_t pf_ctrl;			/*  0x4084 */
+	RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;	/*  0x4088 */
+	RXMAC_MCIF_WATER_MARK_t mcif_water_mark;	/*  0x408C */
+	RXMAC_RXQ_DIAG_t rxq_diag;			/*  0x4090 */
+	RXMAC_SPACE_AVAIL_t space_avail;		/*  0x4094 */
+
+	RXMAC_MIF_CTL_t mif_ctrl;			/*  0x4098 */
+	RXMAC_ERROR_REG_t err_reg;			/*  0x409C */
 } RXMAC_t, *PRXMAC_t;
 
 /* END OF TXMAC REGISTER ADDRESS MAP */
@@ -1549,39 +1313,39 @@ typedef union _MAC_CFG1_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 soft_reset:1;		// bit 31
-		u32 sim_reset:1;		// bit 30
-		u32 reserved3:10;		// bits 20-29
-		u32 reset_rx_mc:1;		// bit 19
-		u32 reset_tx_mc:1;		// bit 18
-		u32 reset_rx_fun:1;	// bit 17
-		u32 reset_tx_fun:1;	// bit 16
-		u32 reserved2:7;		// bits 9-15
-		u32 loop_back:1;		// bit 8
-		u32 reserved1:2;		// bits 6-7
-		u32 rx_flow:1;		// bit 5
-		u32 tx_flow:1;		// bit 4
-		u32 syncd_rx_en:1;		// bit 3
-		u32 rx_enable:1;		// bit 2
-		u32 syncd_tx_en:1;		// bit 1
-		u32 tx_enable:1;		// bit 0
-#else
-		u32 tx_enable:1;		// bit 0
-		u32 syncd_tx_en:1;		// bit 1
-		u32 rx_enable:1;		// bit 2
-		u32 syncd_rx_en:1;		// bit 3
-		u32 tx_flow:1;		// bit 4
-		u32 rx_flow:1;		// bit 5
-		u32 reserved1:2;		// bits 6-7
-		u32 loop_back:1;		// bit 8
-		u32 reserved2:7;		// bits 9-15
-		u32 reset_tx_fun:1;	// bit 16
-		u32 reset_rx_fun:1;	// bit 17
-		u32 reset_tx_mc:1;		// bit 18
-		u32 reset_rx_mc:1;		// bit 19
-		u32 reserved3:10;		// bits 20-29
-		u32 sim_reset:1;		// bit 30
-		u32 soft_reset:1;		// bit 31
+		u32 soft_reset:1;		/* bit 31 */
+		u32 sim_reset:1;		/* bit 30 */
+		u32 reserved3:10;		/* bits 20-29 */
+		u32 reset_rx_mc:1;		/* bit 19 */
+		u32 reset_tx_mc:1;		/* bit 18 */
+		u32 reset_rx_fun:1;	/* bit 17 */
+		u32 reset_tx_fun:1;	/* bit 16 */
+		u32 reserved2:7;		/* bits 9-15 */
+		u32 loop_back:1;		/* bit 8 */
+		u32 reserved1:2;		/* bits 6-7 */
+		u32 rx_flow:1;		/* bit 5 */
+		u32 tx_flow:1;		/* bit 4 */
+		u32 syncd_rx_en:1;		/* bit 3 */
+		u32 rx_enable:1;		/* bit 2 */
+		u32 syncd_tx_en:1;		/* bit 1 */
+		u32 tx_enable:1;		/* bit 0 */
+#else
+		u32 tx_enable:1;		/* bit 0 */
+		u32 syncd_tx_en:1;		/* bit 1 */
+		u32 rx_enable:1;		/* bit 2 */
+		u32 syncd_rx_en:1;		/* bit 3 */
+		u32 tx_flow:1;		/* bit 4 */
+		u32 rx_flow:1;		/* bit 5 */
+		u32 reserved1:2;		/* bits 6-7 */
+		u32 loop_back:1;		/* bit 8 */
+		u32 reserved2:7;		/* bits 9-15 */
+		u32 reset_tx_fun:1;	/* bit 16 */
+		u32 reset_rx_fun:1;	/* bit 17 */
+		u32 reset_tx_mc:1;		/* bit 18 */
+		u32 reset_rx_mc:1;		/* bit 19 */
+		u32 reserved3:10;		/* bits 20-29 */
+		u32 sim_reset:1;		/* bit 30 */
+		u32 soft_reset:1;		/* bit 31 */
 #endif
 	} bits;
 } MAC_CFG1_t, *PMAC_CFG1_t;
@@ -1594,29 +1358,29 @@ typedef union _MAC_CFG2_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved3:16;		// bits 16-31
-		u32 preamble_len:4;	// bits 12-15
-		u32 reserved2:2;		// bits 10-11
-		u32 if_mode:2;		// bits 8-9
-		u32 reserved1:2;		// bits 6-7
-		u32 huge_frame:1;		// bit 5
-		u32 len_check:1;		// bit 4
-		u32 undefined:1;		// bit 3
-		u32 pad_crc:1;		// bit 2
-		u32 crc_enable:1;		// bit 1
-		u32 full_duplex:1;		// bit 0
-#else
-		u32 full_duplex:1;		// bit 0
-		u32 crc_enable:1;		// bit 1
-		u32 pad_crc:1;		// bit 2
-		u32 undefined:1;		// bit 3
-		u32 len_check:1;		// bit 4
-		u32 huge_frame:1;		// bit 5
-		u32 reserved1:2;		// bits 6-7
-		u32 if_mode:2;		// bits 8-9
-		u32 reserved2:2;		// bits 10-11
-		u32 preamble_len:4;	// bits 12-15
-		u32 reserved3:16;		// bits 16-31
+		u32 reserved3:16;		/* bits 16-31 */
+		u32 preamble_len:4;	/* bits 12-15 */
+		u32 reserved2:2;		/* bits 10-11 */
+		u32 if_mode:2;		/* bits 8-9 */
+		u32 reserved1:2;		/* bits 6-7 */
+		u32 huge_frame:1;		/* bit 5 */
+		u32 len_check:1;		/* bit 4 */
+		u32 undefined:1;		/* bit 3 */
+		u32 pad_crc:1;		/* bit 2 */
+		u32 crc_enable:1;		/* bit 1 */
+		u32 full_duplex:1;		/* bit 0 */
+#else
+		u32 full_duplex:1;		/* bit 0 */
+		u32 crc_enable:1;		/* bit 1 */
+		u32 pad_crc:1;		/* bit 2 */
+		u32 undefined:1;		/* bit 3 */
+		u32 len_check:1;		/* bit 4 */
+		u32 huge_frame:1;		/* bit 5 */
+		u32 reserved1:2;		/* bits 6-7 */
+		u32 if_mode:2;		/* bits 8-9 */
+		u32 reserved2:2;		/* bits 10-11 */
+		u32 preamble_len:4;	/* bits 12-15 */
+		u32 reserved3:16;		/* bits 16-31 */
 #endif
 	} bits;
 } MAC_CFG2_t, *PMAC_CFG2_t;
@@ -1629,21 +1393,21 @@ typedef union _MAC_IPG_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:1;		// bit 31
-		u32 non_B2B_ipg_1:7;	// bits 24-30
-		u32 undefined2:1;		// bit 23
-		u32 non_B2B_ipg_2:7;	// bits 16-22
-		u32 min_ifg_enforce:8;	// bits 8-15
-		u32 undefined1:1;		// bit 7
-		u32 B2B_ipg:7;		// bits 0-6
+		u32 reserved:1;		/* bit 31 */
+		u32 non_B2B_ipg_1:7;	/* bits 24-30 */
+		u32 undefined2:1;		/* bit 23 */
+		u32 non_B2B_ipg_2:7;	/* bits 16-22 */
+		u32 min_ifg_enforce:8;	/* bits 8-15 */
+		u32 undefined1:1;		/* bit 7 */
+		u32 B2B_ipg:7;		/* bits 0-6 */
 #else
-		u32 B2B_ipg:7;		// bits 0-6
-		u32 undefined1:1;		// bit 7
-		u32 min_ifg_enforce:8;	// bits 8-15
-		u32 non_B2B_ipg_2:7;	// bits 16-22
-		u32 undefined2:1;		// bit 23
-		u32 non_B2B_ipg_1:7;	// bits 24-30
-		u32 reserved:1;		// bit 31
+		u32 B2B_ipg:7;		/* bits 0-6 */
+		u32 undefined1:1;		/* bit 7 */
+		u32 min_ifg_enforce:8;	/* bits 8-15 */
+		u32 non_B2B_ipg_2:7;	/* bits 16-22 */
+		u32 undefined2:1;		/* bit 23 */
+		u32 non_B2B_ipg_1:7;	/* bits 24-30 */
+		u32 reserved:1;		/* bit 31 */
 #endif
 	} bits;
 } MAC_IPG_t, *PMAC_IPG_t;
@@ -1656,25 +1420,25 @@ typedef union _MAC_HFDP_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:8;		// bits 24-31
-		u32 alt_beb_trunc:4;	// bits 23-20
-		u32 alt_beb_enable:1;	// bit 19
-		u32 bp_no_backoff:1;	// bit 18
-		u32 no_backoff:1;		// bit 17
-		u32 excess_defer:1;	// bit 16
-		u32 rexmit_max:4;		// bits 12-15
-		u32 reserved1:2;		// bits 10-11
-		u32 coll_window:10;	// bits 0-9
+		u32 reserved2:8;		/* bits 24-31 */
+		u32 alt_beb_trunc:4;	/* bits 23-20 */
+		u32 alt_beb_enable:1;	/* bit 19 */
+		u32 bp_no_backoff:1;	/* bit 18 */
+		u32 no_backoff:1;		/* bit 17 */
+		u32 excess_defer:1;	/* bit 16 */
+		u32 rexmit_max:4;		/* bits 12-15 */
+		u32 reserved1:2;		/* bits 10-11 */
+		u32 coll_window:10;	/* bits 0-9 */
 #else
-		u32 coll_window:10;	// bits 0-9
-		u32 reserved1:2;		// bits 10-11
-		u32 rexmit_max:4;		// bits 12-15
-		u32 excess_defer:1;	// bit 16
-		u32 no_backoff:1;		// bit 17
-		u32 bp_no_backoff:1;	// bit 18
-		u32 alt_beb_enable:1;	// bit 19
-		u32 alt_beb_trunc:4;	// bits 23-20
-		u32 reserved2:8;		// bits 24-31
+		u32 coll_window:10;	/* bits 0-9 */
+		u32 reserved1:2;		/* bits 10-11 */
+		u32 rexmit_max:4;		/* bits 12-15 */
+		u32 excess_defer:1;	/* bit 16 */
+		u32 no_backoff:1;		/* bit 17 */
+		u32 bp_no_backoff:1;	/* bit 18 */
+		u32 alt_beb_enable:1;	/* bit 19 */
+		u32 alt_beb_trunc:4;	/* bits 23-20 */
+		u32 reserved2:8;		/* bits 24-31 */
 #endif
 	} bits;
 } MAC_HFDP_t, *PMAC_HFDP_t;
@@ -1687,11 +1451,11 @@ typedef union _MAC_MAX_FM_LEN_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:16;	// bits 16-31
-		u32 max_len:16;	// bits 0-15
+		u32 reserved:16;	/* bits 16-31 */
+		u32 max_len:16;	/* bits 0-15 */
 #else
-		u32 max_len:16;	// bits 0-15
-		u32 reserved:16;	// bits 16-31
+		u32 max_len:16;	/* bits 0-15 */
+		u32 reserved:16;	/* bits 16-31 */
 #endif
 	} bits;
 } MAC_MAX_FM_LEN_t, *PMAC_MAX_FM_LEN_t;
@@ -1710,11 +1474,11 @@ typedef union _MAC_TEST_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:29;	// bits 3-31
-		u32 mac_test:3;	// bits 0-2
+		u32 unused:29;	/* bits 3-31 */
+		u32 mac_test:3;	/* bits 0-2 */
 #else
-		u32 mac_test:3;	// bits 0-2
-		u32 unused:29;	// bits 3-31
+		u32 mac_test:3;	/* bits 0-2 */
+		u32 unused:29;	/* bits 3-31 */
 #endif
 	} bits;
 } MAC_TEST_t, *PMAC_TEST_t;
@@ -1727,19 +1491,19 @@ typedef union _MII_MGMT_CFG_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reset_mii_mgmt:1;	// bit 31
-		u32 reserved:25;		// bits 6-30
-		u32 scan_auto_incremt:1;	// bit 5
-		u32 preamble_suppress:1;	// bit 4
-		u32 undefined:1;		// bit 3
-		u32 mgmt_clk_reset:3;	// bits 0-2
+		u32 reset_mii_mgmt:1;	/* bit 31 */
+		u32 reserved:25;		/* bits 6-30 */
+		u32 scan_auto_incremt:1;	/* bit 5 */
+		u32 preamble_suppress:1;	/* bit 4 */
+		u32 undefined:1;		/* bit 3 */
+		u32 mgmt_clk_reset:3;	/* bits 0-2 */
 #else
-		u32 mgmt_clk_reset:3;	// bits 0-2
-		u32 undefined:1;		// bit 3
-		u32 preamble_suppress:1;	// bit 4
-		u32 scan_auto_incremt:1;	// bit 5
-		u32 reserved:25;		// bits 6-30
-		u32 reset_mii_mgmt:1;	// bit 31
+		u32 mgmt_clk_reset:3;	/* bits 0-2 */
+		u32 undefined:1;		/* bit 3 */
+		u32 preamble_suppress:1;	/* bit 4 */
+		u32 scan_auto_incremt:1;	/* bit 5 */
+		u32 reserved:25;		/* bits 6-30 */
+		u32 reset_mii_mgmt:1;	/* bit 31 */
 #endif
 	} bits;
 } MII_MGMT_CFG_t, *PMII_MGMT_CFG_t;
@@ -1752,13 +1516,13 @@ typedef union _MII_MGMT_CMD_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:30;	// bits 2-31
-		u32 scan_cycle:1;	// bit 1
-		u32 read_cycle:1;	// bit 0
+		u32 reserved:30;	/* bits 2-31 */
+		u32 scan_cycle:1;	/* bit 1 */
+		u32 read_cycle:1;	/* bit 0 */
 #else
-		u32 read_cycle:1;	// bit 0
-		u32 scan_cycle:1;	// bit 1
-		u32 reserved:30;	// bits 2-31
+		u32 read_cycle:1;	/* bit 0 */
+		u32 scan_cycle:1;	/* bit 1 */
+		u32 reserved:30;	/* bits 2-31 */
 #endif
 	} bits;
 } MII_MGMT_CMD_t, *PMII_MGMT_CMD_t;
@@ -1771,15 +1535,15 @@ typedef union _MII_MGMT_ADDR_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved2:19;	// bit 13-31
-		u32 phy_addr:5;	// bits 8-12
-		u32 reserved1:3;	// bits 5-7
-		u32 reg_addr:5;	// bits 0-4
+		u32 reserved2:19;	/* bit 13-31 */
+		u32 phy_addr:5;	/* bits 8-12 */
+		u32 reserved1:3;	/* bits 5-7 */
+		u32 reg_addr:5;	/* bits 0-4 */
 #else
-		u32 reg_addr:5;	// bits 0-4
-		u32 reserved1:3;	// bits 5-7
-		u32 phy_addr:5;	// bits 8-12
-		u32 reserved2:19;	// bit 13-31
+		u32 reg_addr:5;	/* bits 0-4 */
+		u32 reserved1:3;	/* bits 5-7 */
+		u32 phy_addr:5;	/* bits 8-12 */
+		u32 reserved2:19;	/* bit 13-31 */
 #endif
 	} bits;
 } MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t;
@@ -1792,11 +1556,11 @@ typedef union _MII_MGMT_CTRL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:16;	// bits 16-31
-		u32 phy_ctrl:16;	// bits 0-15
+		u32 reserved:16;	/* bits 16-31 */
+		u32 phy_ctrl:16;	/* bits 0-15 */
 #else
-		u32 phy_ctrl:16;	// bits 0-15
-		u32 reserved:16;	// bits 16-31
+		u32 phy_ctrl:16;	/* bits 0-15 */
+		u32 reserved:16;	/* bits 16-31 */
 #endif
 	} bits;
 } MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t;
@@ -1809,11 +1573,11 @@ typedef union _MII_MGMT_STAT_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:16;	// bits 16-31
-		u32 phy_stat:16;	// bits 0-15
+		u32 reserved:16;	/* bits 16-31 */
+		u32 phy_stat:16;	/* bits 0-15 */
 #else
-		u32 phy_stat:16;	// bits 0-15
-		u32 reserved:16;	// bits 16-31
+		u32 phy_stat:16;	/* bits 0-15 */
+		u32 reserved:16;	/* bits 16-31 */
 #endif
 	} bits;
 } MII_MGMT_STAT_t, *PMII_MGMT_STAT_t;
@@ -1826,15 +1590,15 @@ typedef union _MII_MGMT_INDICATOR_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:29;	// bits 3-31
-		u32 not_valid:1;	// bit 2
-		u32 scanning:1;	// bit 1
-		u32 busy:1;	// bit 0
+		u32 reserved:29;	/* bits 3-31 */
+		u32 not_valid:1;	/* bit 2 */
+		u32 scanning:1;	/* bit 1 */
+		u32 busy:1;	/* bit 0 */
 #else
-		u32 busy:1;	// bit 0
-		u32 scanning:1;	// bit 1
-		u32 not_valid:1;	// bit 2
-		u32 reserved:29;	// bits 3-31
+		u32 busy:1;	/* bit 0 */
+		u32 scanning:1;	/* bit 1 */
+		u32 not_valid:1;	/* bit 2 */
+		u32 reserved:29;	/* bits 3-31 */
 #endif
 	} bits;
 } MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t;
@@ -1847,41 +1611,41 @@ typedef union _MAC_IF_CTRL_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reset_if_module:1;	// bit 31
-		u32 reserved4:3;		// bit 28-30
-		u32 tbi_mode:1;		// bit 27
-		u32 ghd_mode:1;		// bit 26
-		u32 lhd_mode:1;		// bit 25
-		u32 phy_mode:1;		// bit 24
-		u32 reset_per_mii:1;	// bit 23
-		u32 reserved3:6;		// bits 17-22
-		u32 speed:1;		// bit 16
-		u32 reset_pe100x:1;	// bit 15
-		u32 reserved2:4;		// bits 11-14
-		u32 force_quiet:1;		// bit 10
-		u32 no_cipher:1;		// bit 9
-		u32 disable_link_fail:1;	// bit 8
-		u32 reset_gpsi:1;		// bit 7
-		u32 reserved1:6;		// bits 1-6
-		u32 enab_jab_protect:1;	// bit 0
-#else
-		u32 enab_jab_protect:1;	// bit 0
-		u32 reserved1:6;		// bits 1-6
-		u32 reset_gpsi:1;		// bit 7
-		u32 disable_link_fail:1;	// bit 8
-		u32 no_cipher:1;		// bit 9
-		u32 force_quiet:1;		// bit 10
-		u32 reserved2:4;		// bits 11-14
-		u32 reset_pe100x:1;	// bit 15
-		u32 speed:1;		// bit 16
-		u32 reserved3:6;		// bits 17-22
-		u32 reset_per_mii:1;	// bit 23
-		u32 phy_mode:1;		// bit 24
-		u32 lhd_mode:1;		// bit 25
-		u32 ghd_mode:1;		// bit 26
-		u32 tbi_mode:1;		// bit 27
-		u32 reserved4:3;		// bit 28-30
-		u32 reset_if_module:1;	// bit 31
+		u32 reset_if_module:1;	/* bit 31 */
+		u32 reserved4:3;		/* bit 28-30 */
+		u32 tbi_mode:1;		/* bit 27 */
+		u32 ghd_mode:1;		/* bit 26 */
+		u32 lhd_mode:1;		/* bit 25 */
+		u32 phy_mode:1;		/* bit 24 */
+		u32 reset_per_mii:1;	/* bit 23 */
+		u32 reserved3:6;		/* bits 17-22 */
+		u32 speed:1;		/* bit 16 */
+		u32 reset_pe100x:1;	/* bit 15 */
+		u32 reserved2:4;		/* bits 11-14 */
+		u32 force_quiet:1;		/* bit 10 */
+		u32 no_cipher:1;		/* bit 9 */
+		u32 disable_link_fail:1;	/* bit 8 */
+		u32 reset_gpsi:1;		/* bit 7 */
+		u32 reserved1:6;		/* bits 1-6 */
+		u32 enab_jab_protect:1;	/* bit 0 */
+#else
+		u32 enab_jab_protect:1;	/* bit 0 */
+		u32 reserved1:6;		/* bits 1-6 */
+		u32 reset_gpsi:1;		/* bit 7 */
+		u32 disable_link_fail:1;	/* bit 8 */
+		u32 no_cipher:1;		/* bit 9 */
+		u32 force_quiet:1;		/* bit 10 */
+		u32 reserved2:4;		/* bits 11-14 */
+		u32 reset_pe100x:1;	/* bit 15 */
+		u32 speed:1;		/* bit 16 */
+		u32 reserved3:6;		/* bits 17-22 */
+		u32 reset_per_mii:1;	/* bit 23 */
+		u32 phy_mode:1;		/* bit 24 */
+		u32 lhd_mode:1;		/* bit 25 */
+		u32 ghd_mode:1;		/* bit 26 */
+		u32 tbi_mode:1;		/* bit 27 */
+		u32 reserved4:3;		/* bit 28-30 */
+		u32 reset_if_module:1;	/* bit 31 */
 #endif
 	} bits;
 } MAC_IF_CTRL_t, *PMAC_IF_CTRL_t;
@@ -1894,29 +1658,29 @@ typedef union _MAC_IF_STAT_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:22;		// bits 10-31
-		u32 excess_defer:1;	// bit 9
-		u32 clash:1;		// bit 8
-		u32 phy_jabber:1;		// bit 7
-		u32 phy_link_ok:1;		// bit 6
-		u32 phy_full_duplex:1;	// bit 5
-		u32 phy_speed:1;		// bit 4
-		u32 pe100x_link_fail:1;	// bit 3
-		u32 pe10t_loss_carrie:1;	// bit 2
-		u32 pe10t_sqe_error:1;	// bit 1
-		u32 pe10t_jabber:1;	// bit 0
-#else
-		u32 pe10t_jabber:1;	// bit 0
-		u32 pe10t_sqe_error:1;	// bit 1
-		u32 pe10t_loss_carrie:1;	// bit 2
-		u32 pe100x_link_fail:1;	// bit 3
-		u32 phy_speed:1;		// bit 4
-		u32 phy_full_duplex:1;	// bit 5
-		u32 phy_link_ok:1;		// bit 6
-		u32 phy_jabber:1;		// bit 7
-		u32 clash:1;		// bit 8
-		u32 excess_defer:1;	// bit 9
-		u32 reserved:22;		// bits 10-31
+		u32 reserved:22;		/* bits 10-31 */
+		u32 excess_defer:1;	/* bit 9 */
+		u32 clash:1;		/* bit 8 */
+		u32 phy_jabber:1;		/* bit 7 */
+		u32 phy_link_ok:1;		/* bit 6 */
+		u32 phy_full_duplex:1;	/* bit 5 */
+		u32 phy_speed:1;		/* bit 4 */
+		u32 pe100x_link_fail:1;	/* bit 3 */
+		u32 pe10t_loss_carrie:1;	/* bit 2 */
+		u32 pe10t_sqe_error:1;	/* bit 1 */
+		u32 pe10t_jabber:1;	/* bit 0 */
+#else
+		u32 pe10t_jabber:1;	/* bit 0 */
+		u32 pe10t_sqe_error:1;	/* bit 1 */
+		u32 pe10t_loss_carrie:1;	/* bit 2 */
+		u32 pe100x_link_fail:1;	/* bit 3 */
+		u32 phy_speed:1;		/* bit 4 */
+		u32 phy_full_duplex:1;	/* bit 5 */
+		u32 phy_link_ok:1;		/* bit 6 */
+		u32 phy_jabber:1;		/* bit 7 */
+		u32 clash:1;		/* bit 8 */
+		u32 excess_defer:1;	/* bit 9 */
+		u32 reserved:22;		/* bits 10-31 */
 #endif
 	} bits;
 } MAC_IF_STAT_t, *PMAC_IF_STAT_t;
@@ -1929,15 +1693,15 @@ typedef union _MAC_STATION_ADDR1_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 Octet6:8;	// bits 24-31
-		u32 Octet5:8;	// bits 16-23
-		u32 Octet4:8;	// bits 8-15
-		u32 Octet3:8;	// bits 0-7
+		u32 Octet6:8;	/* bits 24-31 */
+		u32 Octet5:8;	/* bits 16-23 */
+		u32 Octet4:8;	/* bits 8-15 */
+		u32 Octet3:8;	/* bits 0-7 */
 #else
-		u32 Octet3:8;	// bits 0-7
-		u32 Octet4:8;	// bits 8-15
-		u32 Octet5:8;	// bits 16-23
-		u32 Octet6:8;	// bits 24-31
+		u32 Octet3:8;	/* bits 0-7 */
+		u32 Octet4:8;	/* bits 8-15 */
+		u32 Octet5:8;	/* bits 16-23 */
+		u32 Octet6:8;	/* bits 24-31 */
 #endif
 	} bits;
 } MAC_STATION_ADDR1_t, *PMAC_STATION_ADDR1_t;
@@ -1950,13 +1714,13 @@ typedef union _MAC_STATION_ADDR2_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 Octet2:8;	// bits 24-31
-		u32 Octet1:8;	// bits 16-23
-		u32 reserved:16;	// bits 0-15
+		u32 Octet2:8;	/* bits 24-31 */
+		u32 Octet1:8;	/* bits 16-23 */
+		u32 reserved:16;	/* bits 0-15 */
 #else
-		u32 reserved:16;	// bit 0-15
-		u32 Octet1:8;	// bits 16-23
-		u32 Octet2:8;	// bits 24-31
+		u32 reserved:16;	/* bit 0-15 */
+		u32 Octet1:8;	/* bits 16-23 */
+		u32 Octet2:8;	/* bits 24-31 */
 #endif
 	} bits;
 } MAC_STATION_ADDR2_t, *PMAC_STATION_ADDR2_t;
@@ -1964,25 +1728,25 @@ typedef union _MAC_STATION_ADDR2_t {
 /*
  * MAC Module of JAGCore Address Mapping
  */
-typedef struct _MAC_t {					// Location:
-	MAC_CFG1_t cfg1;				//  0x5000
-	MAC_CFG2_t cfg2;				//  0x5004
-	MAC_IPG_t ipg;					//  0x5008
-	MAC_HFDP_t hfdp;				//  0x500C
-	MAC_MAX_FM_LEN_t max_fm_len;			//  0x5010
-	u32 rsv1;					//  0x5014
-	u32 rsv2;					//  0x5018
-	MAC_TEST_t mac_test;				//  0x501C
-	MII_MGMT_CFG_t mii_mgmt_cfg;			//  0x5020
-	MII_MGMT_CMD_t mii_mgmt_cmd;			//  0x5024
-	MII_MGMT_ADDR_t mii_mgmt_addr;			//  0x5028
-	MII_MGMT_CTRL_t mii_mgmt_ctrl;			//  0x502C
-	MII_MGMT_STAT_t mii_mgmt_stat;			//  0x5030
-	MII_MGMT_INDICATOR_t mii_mgmt_indicator;	//  0x5034
-	MAC_IF_CTRL_t if_ctrl;				//  0x5038
-	MAC_IF_STAT_t if_stat;				//  0x503C
-	MAC_STATION_ADDR1_t station_addr_1;		//  0x5040
-	MAC_STATION_ADDR2_t station_addr_2;		//  0x5044
+typedef struct _MAC_t {					/* Location: */
+	MAC_CFG1_t cfg1;				/*  0x5000 */
+	MAC_CFG2_t cfg2;				/*  0x5004 */
+	MAC_IPG_t ipg;					/*  0x5008 */
+	MAC_HFDP_t hfdp;				/*  0x500C */
+	MAC_MAX_FM_LEN_t max_fm_len;			/*  0x5010 */
+	u32 rsv1;					/*  0x5014 */
+	u32 rsv2;					/*  0x5018 */
+	MAC_TEST_t mac_test;				/*  0x501C */
+	MII_MGMT_CFG_t mii_mgmt_cfg;			/*  0x5020 */
+	MII_MGMT_CMD_t mii_mgmt_cmd;			/*  0x5024 */
+	MII_MGMT_ADDR_t mii_mgmt_addr;			/*  0x5028 */
+	MII_MGMT_CTRL_t mii_mgmt_ctrl;			/*  0x502C */
+	MII_MGMT_STAT_t mii_mgmt_stat;			/*  0x5030 */
+	MII_MGMT_INDICATOR_t mii_mgmt_indicator;	/*  0x5034 */
+	MAC_IF_CTRL_t if_ctrl;				/*  0x5038 */
+	MAC_IF_STAT_t if_stat;				/*  0x503C */
+	MAC_STATION_ADDR1_t station_addr_1;		/*  0x5040 */
+	MAC_STATION_ADDR2_t station_addr_2;		/*  0x5044 */
 } MAC_t, *PMAC_t;
 
 /* END OF MAC REGISTER ADDRESS MAP */
@@ -1997,57 +1761,57 @@ typedef union _MAC_STAT_REG_1_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 tr64:1;	// bit 31
-		u32 tr127:1;	// bit 30
-		u32 tr255:1;	// bit 29
-		u32 tr511:1;	// bit 28
-		u32 tr1k:1;	// bit 27
-		u32 trmax:1;	// bit 26
-		u32 trmgv:1;	// bit 25
-		u32 unused:8;	// bits 17-24
-		u32 rbyt:1;	// bit 16
-		u32 rpkt:1;	// bit 15
-		u32 rfcs:1;	// bit 14
-		u32 rmca:1;	// bit 13
-		u32 rbca:1;	// bit 12
-		u32 rxcf:1;	// bit 11
-		u32 rxpf:1;	// bit 10
-		u32 rxuo:1;	// bit 9
-		u32 raln:1;	// bit 8
-		u32 rflr:1;	// bit 7
-		u32 rcde:1;	// bit 6
-		u32 rcse:1;	// bit 5
-		u32 rund:1;	// bit 4
-		u32 rovr:1;	// bit 3
-		u32 rfrg:1;	// bit 2
-		u32 rjbr:1;	// bit 1
-		u32 rdrp:1;	// bit 0
-#else
-		u32 rdrp:1;	// bit 0
-		u32 rjbr:1;	// bit 1
-		u32 rfrg:1;	// bit 2
-		u32 rovr:1;	// bit 3
-		u32 rund:1;	// bit 4
-		u32 rcse:1;	// bit 5
-		u32 rcde:1;	// bit 6
-		u32 rflr:1;	// bit 7
-		u32 raln:1;	// bit 8
-		u32 rxuo:1;	// bit 9
-		u32 rxpf:1;	// bit 10
-		u32 rxcf:1;	// bit 11
-		u32 rbca:1;	// bit 12
-		u32 rmca:1;	// bit 13
-		u32 rfcs:1;	// bit 14
-		u32 rpkt:1;	// bit 15
-		u32 rbyt:1;	// bit 16
-		u32 unused:8;	// bits 17-24
-		u32 trmgv:1;	// bit 25
-		u32 trmax:1;	// bit 26
-		u32 tr1k:1;	// bit 27
-		u32 tr511:1;	// bit 28
-		u32 tr255:1;	// bit 29
-		u32 tr127:1;	// bit 30
-		u32 tr64:1;	// bit 31
+		u32 tr64:1;	/* bit 31 */
+		u32 tr127:1;	/* bit 30 */
+		u32 tr255:1;	/* bit 29 */
+		u32 tr511:1;	/* bit 28 */
+		u32 tr1k:1;	/* bit 27 */
+		u32 trmax:1;	/* bit 26 */
+		u32 trmgv:1;	/* bit 25 */
+		u32 unused:8;	/* bits 17-24 */
+		u32 rbyt:1;	/* bit 16 */
+		u32 rpkt:1;	/* bit 15 */
+		u32 rfcs:1;	/* bit 14 */
+		u32 rmca:1;	/* bit 13 */
+		u32 rbca:1;	/* bit 12 */
+		u32 rxcf:1;	/* bit 11 */
+		u32 rxpf:1;	/* bit 10 */
+		u32 rxuo:1;	/* bit 9 */
+		u32 raln:1;	/* bit 8 */
+		u32 rflr:1;	/* bit 7 */
+		u32 rcde:1;	/* bit 6 */
+		u32 rcse:1;	/* bit 5 */
+		u32 rund:1;	/* bit 4 */
+		u32 rovr:1;	/* bit 3 */
+		u32 rfrg:1;	/* bit 2 */
+		u32 rjbr:1;	/* bit 1 */
+		u32 rdrp:1;	/* bit 0 */
+#else
+		u32 rdrp:1;	/* bit 0 */
+		u32 rjbr:1;	/* bit 1 */
+		u32 rfrg:1;	/* bit 2 */
+		u32 rovr:1;	/* bit 3 */
+		u32 rund:1;	/* bit 4 */
+		u32 rcse:1;	/* bit 5 */
+		u32 rcde:1;	/* bit 6 */
+		u32 rflr:1;	/* bit 7 */
+		u32 raln:1;	/* bit 8 */
+		u32 rxuo:1;	/* bit 9 */
+		u32 rxpf:1;	/* bit 10 */
+		u32 rxcf:1;	/* bit 11 */
+		u32 rbca:1;	/* bit 12 */
+		u32 rmca:1;	/* bit 13 */
+		u32 rfcs:1;	/* bit 14 */
+		u32 rpkt:1;	/* bit 15 */
+		u32 rbyt:1;	/* bit 16 */
+		u32 unused:8;	/* bits 17-24 */
+		u32 trmgv:1;	/* bit 25 */
+		u32 trmax:1;	/* bit 26 */
+		u32 tr1k:1;	/* bit 27 */
+		u32 tr511:1;	/* bit 28 */
+		u32 tr255:1;	/* bit 29 */
+		u32 tr127:1;	/* bit 30 */
+		u32 tr64:1;	/* bit 31 */
 #endif
 	} bits;
 } MAC_STAT_REG_1_t, *PMAC_STAT_REG_1_t;
@@ -2060,49 +1824,49 @@ typedef union _MAC_STAT_REG_2_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:12;	// bit 20-31
-		u32 tjbr:1;	// bit 19
-		u32 tfcs:1;	// bit 18
-		u32 txcf:1;	// bit 17
-		u32 tovr:1;	// bit 16
-		u32 tund:1;	// bit 15
-		u32 tfrg:1;	// bit 14
-		u32 tbyt:1;	// bit 13
-		u32 tpkt:1;	// bit 12
-		u32 tmca:1;	// bit 11
-		u32 tbca:1;	// bit 10
-		u32 txpf:1;	// bit 9
-		u32 tdfr:1;	// bit 8
-		u32 tedf:1;	// bit 7
-		u32 tscl:1;	// bit 6
-		u32 tmcl:1;	// bit 5
-		u32 tlcl:1;	// bit 4
-		u32 txcl:1;	// bit 3
-		u32 tncl:1;	// bit 2
-		u32 tpfh:1;	// bit 1
-		u32 tdrp:1;	// bit 0
-#else
-		u32 tdrp:1;	// bit 0
-		u32 tpfh:1;	// bit 1
-		u32 tncl:1;	// bit 2
-		u32 txcl:1;	// bit 3
-		u32 tlcl:1;	// bit 4
-		u32 tmcl:1;	// bit 5
-		u32 tscl:1;	// bit 6
-		u32 tedf:1;	// bit 7
-		u32 tdfr:1;	// bit 8
-		u32 txpf:1;	// bit 9
-		u32 tbca:1;	// bit 10
-		u32 tmca:1;	// bit 11
-		u32 tpkt:1;	// bit 12
-		u32 tbyt:1;	// bit 13
-		u32 tfrg:1;	// bit 14
-		u32 tund:1;	// bit 15
-		u32 tovr:1;	// bit 16
-		u32 txcf:1;	// bit 17
-		u32 tfcs:1;	// bit 18
-		u32 tjbr:1;	// bit 19
-		u32 unused:12;	// bit 20-31
+		u32 unused:12;	/* bit 20-31 */
+		u32 tjbr:1;	/* bit 19 */
+		u32 tfcs:1;	/* bit 18 */
+		u32 txcf:1;	/* bit 17 */
+		u32 tovr:1;	/* bit 16 */
+		u32 tund:1;	/* bit 15 */
+		u32 tfrg:1;	/* bit 14 */
+		u32 tbyt:1;	/* bit 13 */
+		u32 tpkt:1;	/* bit 12 */
+		u32 tmca:1;	/* bit 11 */
+		u32 tbca:1;	/* bit 10 */
+		u32 txpf:1;	/* bit 9 */
+		u32 tdfr:1;	/* bit 8 */
+		u32 tedf:1;	/* bit 7 */
+		u32 tscl:1;	/* bit 6 */
+		u32 tmcl:1;	/* bit 5 */
+		u32 tlcl:1;	/* bit 4 */
+		u32 txcl:1;	/* bit 3 */
+		u32 tncl:1;	/* bit 2 */
+		u32 tpfh:1;	/* bit 1 */
+		u32 tdrp:1;	/* bit 0 */
+#else
+		u32 tdrp:1;	/* bit 0 */
+		u32 tpfh:1;	/* bit 1 */
+		u32 tncl:1;	/* bit 2 */
+		u32 txcl:1;	/* bit 3 */
+		u32 tlcl:1;	/* bit 4 */
+		u32 tmcl:1;	/* bit 5 */
+		u32 tscl:1;	/* bit 6 */
+		u32 tedf:1;	/* bit 7 */
+		u32 tdfr:1;	/* bit 8 */
+		u32 txpf:1;	/* bit 9 */
+		u32 tbca:1;	/* bit 10 */
+		u32 tmca:1;	/* bit 11 */
+		u32 tpkt:1;	/* bit 12 */
+		u32 tbyt:1;	/* bit 13 */
+		u32 tfrg:1;	/* bit 14 */
+		u32 tund:1;	/* bit 15 */
+		u32 tovr:1;	/* bit 16 */
+		u32 txcf:1;	/* bit 17 */
+		u32 tfcs:1;	/* bit 18 */
+		u32 tjbr:1;	/* bit 19 */
+		u32 unused:12;	/* bit 20-31 */
 #endif
 	} bits;
 } MAC_STAT_REG_2_t, *PMAC_STAT_REG_2_t;
@@ -2110,152 +1874,152 @@ typedef union _MAC_STAT_REG_2_t {
 /*
  * MAC STATS Module of JAGCore Address Mapping
  */
-typedef struct _MAC_STAT_t {		// Location:
-	u32 pad[32];		//  0x6000 - 607C
+typedef struct _MAC_STAT_t {		/* Location: */
+	u32 pad[32];		/*  0x6000 - 607C */
 
-	// Tx/Rx 0-64 Byte Frame Counter
-	u32 TR64;			//  0x6080
+	/* Tx/Rx 0-64 Byte Frame Counter */
+	u32 TR64;			/*  0x6080 */
 
-	// Tx/Rx 65-127 Byte Frame Counter
-	u32 TR127;			//  0x6084
+	/* Tx/Rx 65-127 Byte Frame Counter */
+	u32 TR127;			/*  0x6084 */
 
-	// Tx/Rx 128-255 Byte Frame Counter
-	u32 TR255;			//  0x6088
+	/* Tx/Rx 128-255 Byte Frame Counter */
+	u32 TR255;			/*  0x6088 */
 
-	// Tx/Rx 256-511 Byte Frame Counter
-	u32 TR511;			//  0x608C
+	/* Tx/Rx 256-511 Byte Frame Counter */
+	u32 TR511;			/*  0x608C */
 
-	// Tx/Rx 512-1023 Byte Frame Counter
-	u32 TR1K;			//  0x6090
+	/* Tx/Rx 512-1023 Byte Frame Counter */
+	u32 TR1K;			/*  0x6090 */
 
-	// Tx/Rx 1024-1518 Byte Frame Counter
-	u32 TRMax;			//  0x6094
+	/* Tx/Rx 1024-1518 Byte Frame Counter */
+	u32 TRMax;			/*  0x6094 */
 
-	// Tx/Rx 1519-1522 Byte Good VLAN Frame Count
-	u32 TRMgv;			//  0x6098
+	/* Tx/Rx 1519-1522 Byte Good VLAN Frame Count */
+	u32 TRMgv;			/*  0x6098 */
 
-	// Rx Byte Counter
-	u32 RByt;			//  0x609C
+	/* Rx Byte Counter */
+	u32 RByt;			/*  0x609C */
 
-	// Rx Packet Counter
-	u32 RPkt;			//  0x60A0
+	/* Rx Packet Counter */
+	u32 RPkt;			/*  0x60A0 */
 
-	// Rx FCS Error Counter
-	u32 RFcs;			//  0x60A4
+	/* Rx FCS Error Counter */
+	u32 RFcs;			/*  0x60A4 */
 
-	// Rx Multicast Packet Counter
-	u32 RMca;			//  0x60A8
+	/* Rx Multicast Packet Counter */
+	u32 RMca;			/*  0x60A8 */
 
-	// Rx Broadcast Packet Counter
-	u32 RBca;			//  0x60AC
+	/* Rx Broadcast Packet Counter */
+	u32 RBca;			/*  0x60AC */
 
-	// Rx Control Frame Packet Counter
-	u32 RxCf;			//  0x60B0
+	/* Rx Control Frame Packet Counter */
+	u32 RxCf;			/*  0x60B0 */
 
-	// Rx Pause Frame Packet Counter
-	u32 RxPf;			//  0x60B4
+	/* Rx Pause Frame Packet Counter */
+	u32 RxPf;			/*  0x60B4 */
 
-	// Rx Unknown OP Code Counter
-	u32 RxUo;			//  0x60B8
+	/* Rx Unknown OP Code Counter */
+	u32 RxUo;			/*  0x60B8 */
 
-	// Rx Alignment Error Counter
-	u32 RAln;			//  0x60BC
+	/* Rx Alignment Error Counter */
+	u32 RAln;			/*  0x60BC */
 
-	// Rx Frame Length Error Counter
-	u32 RFlr;			//  0x60C0
+	/* Rx Frame Length Error Counter */
+	u32 RFlr;			/*  0x60C0 */
 
-	// Rx Code Error Counter
-	u32 RCde;			//  0x60C4
+	/* Rx Code Error Counter */
+	u32 RCde;			/*  0x60C4 */
 
-	// Rx Carrier Sense Error Counter
-	u32 RCse;			//  0x60C8
+	/* Rx Carrier Sense Error Counter */
+	u32 RCse;			/*  0x60C8 */
 
-	// Rx Undersize Packet Counter
-	u32 RUnd;			//  0x60CC
+	/* Rx Undersize Packet Counter */
+	u32 RUnd;			/*  0x60CC */
 
-	// Rx Oversize Packet Counter
-	u32 ROvr;			//  0x60D0
+	/* Rx Oversize Packet Counter */
+	u32 ROvr;			/*  0x60D0 */
 
-	// Rx Fragment Counter
-	u32 RFrg;			//  0x60D4
+	/* Rx Fragment Counter */
+	u32 RFrg;			/*  0x60D4 */
 
-	// Rx Jabber Counter
-	u32 RJbr;			//  0x60D8
+	/* Rx Jabber Counter */
+	u32 RJbr;			/*  0x60D8 */
 
-	// Rx Drop
-	u32 RDrp;			//  0x60DC
+	/* Rx Drop */
+	u32 RDrp;			/*  0x60DC */
 
-	// Tx Byte Counter
-	u32 TByt;			//  0x60E0
+	/* Tx Byte Counter */
+	u32 TByt;			/*  0x60E0 */
 
-	// Tx Packet Counter
-	u32 TPkt;			//  0x60E4
+	/* Tx Packet Counter */
+	u32 TPkt;			/*  0x60E4 */
 
-	// Tx Multicast Packet Counter
-	u32 TMca;			//  0x60E8
+	/* Tx Multicast Packet Counter */
+	u32 TMca;			/*  0x60E8 */
 
-	// Tx Broadcast Packet Counter
-	u32 TBca;			//  0x60EC
+	/* Tx Broadcast Packet Counter */
+	u32 TBca;			/*  0x60EC */
 
-	// Tx Pause Control Frame Counter
-	u32 TxPf;			//  0x60F0
+	/* Tx Pause Control Frame Counter */
+	u32 TxPf;			/*  0x60F0 */
 
-	// Tx Deferral Packet Counter
-	u32 TDfr;			//  0x60F4
+	/* Tx Deferral Packet Counter */
+	u32 TDfr;			/*  0x60F4 */
 
-	// Tx Excessive Deferral Packet Counter
-	u32 TEdf;			//  0x60F8
+	/* Tx Excessive Deferral Packet Counter */
+	u32 TEdf;			/*  0x60F8 */
 
-	// Tx Single Collision Packet Counter
-	u32 TScl;			//  0x60FC
+	/* Tx Single Collision Packet Counter */
+	u32 TScl;			/*  0x60FC */
 
-	// Tx Multiple Collision Packet Counter
-	u32 TMcl;			//  0x6100
+	/* Tx Multiple Collision Packet Counter */
+	u32 TMcl;			/*  0x6100 */
 
-	// Tx Late Collision Packet Counter
-	u32 TLcl;			//  0x6104
+	/* Tx Late Collision Packet Counter */
+	u32 TLcl;			/*  0x6104 */
 
-	// Tx Excessive Collision Packet Counter
-	u32 TXcl;			//  0x6108
+	/* Tx Excessive Collision Packet Counter */
+	u32 TXcl;			/*  0x6108 */
 
-	// Tx Total Collision Packet Counter
-	u32 TNcl;			//  0x610C
+	/* Tx Total Collision Packet Counter */
+	u32 TNcl;			/*  0x610C */
 
-	// Tx Pause Frame Honored Counter
-	u32 TPfh;			//  0x6110
+	/* Tx Pause Frame Honored Counter */
+	u32 TPfh;			/*  0x6110 */
 
-	// Tx Drop Frame Counter
-	u32 TDrp;			//  0x6114
+	/* Tx Drop Frame Counter */
+	u32 TDrp;			/*  0x6114 */
 
-	// Tx Jabber Frame Counter
-	u32 TJbr;			//  0x6118
+	/* Tx Jabber Frame Counter */
+	u32 TJbr;			/*  0x6118 */
 
-	// Tx FCS Error Counter
-	u32 TFcs;			//  0x611C
+	/* Tx FCS Error Counter */
+	u32 TFcs;			/*  0x611C */
 
-	// Tx Control Frame Counter
-	u32 TxCf;			//  0x6120
+	/* Tx Control Frame Counter */
+	u32 TxCf;			/*  0x6120 */
 
-	// Tx Oversize Frame Counter
-	u32 TOvr;			//  0x6124
+	/* Tx Oversize Frame Counter */
+	u32 TOvr;			/*  0x6124 */
 
-	// Tx Undersize Frame Counter
-	u32 TUnd;			//  0x6128
+	/* Tx Undersize Frame Counter */
+	u32 TUnd;			/*  0x6128 */
 
-	// Tx Fragments Frame Counter
-	u32 TFrg;			//  0x612C
+	/* Tx Fragments Frame Counter */
+	u32 TFrg;			/*  0x612C */
 
-	// Carry Register One Register
-	MAC_STAT_REG_1_t Carry1;	//  0x6130
+	/* Carry Register One Register */
+	MAC_STAT_REG_1_t Carry1;	/*  0x6130 */
 
-	// Carry Register Two Register
-	MAC_STAT_REG_2_t Carry2;	//  0x6134
+	/* Carry Register Two Register */
+	MAC_STAT_REG_2_t Carry2;	/*  0x6134 */
 
-	// Carry Register One Mask Register
-	MAC_STAT_REG_1_t Carry1M;	//  0x6138
+	/* Carry Register One Mask Register */
+	MAC_STAT_REG_1_t Carry1M;	/*  0x6138 */
 
-	// Carry Register Two Mask Register
-	MAC_STAT_REG_2_t Carry2M;	//  0x613C
+	/* Carry Register Two Mask Register */
+	MAC_STAT_REG_2_t Carry2M;	/*  0x613C */
 } MAC_STAT_t, *PMAC_STAT_t;
 
 /* END OF MAC STAT REGISTER ADDRESS MAP */
@@ -2264,60 +2028,26 @@ typedef struct _MAC_STAT_t {		// Location:
 /* START OF MMC REGISTER ADDRESS MAP */
 
 /*
- * structure for Main Memory Controller Control reg in mmc address map.
+ * Main Memory Controller Control reg in mmc address map.
  * located at address 0x7000
  */
-typedef union _MMC_CTRL_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 reserved:25;		// bits 7-31
-		u32 force_ce:1;		// bit 6
-		u32 rxdma_disable:1;	// bit 5
-		u32 txdma_disable:1;	// bit 4
-		u32 txmac_disable:1;	// bit 3
-		u32 rxmac_disable:1;	// bit 2
-		u32 arb_disable:1;		// bit 1
-		u32 mmc_enable:1;		// bit 0
-#else
-		u32 mmc_enable:1;		// bit 0
-		u32 arb_disable:1;		// bit 1
-		u32 rxmac_disable:1;	// bit 2
-		u32 txmac_disable:1;	// bit 3
-		u32 txdma_disable:1;	// bit 4
-		u32 rxdma_disable:1;	// bit 5
-		u32 force_ce:1;		// bit 6
-		u32 reserved:25;		// bits 7-31
-#endif
-	} bits;
-} MMC_CTRL_t, *PMMC_CTRL_t;
+
+#define ET_MMC_ENABLE		1
+#define ET_MMC_ARB_DISABLE	2
+#define ET_MMC_RXMAC_DISABLE	4
+#define ET_MMC_TXMAC_DISABLE	8
+#define ET_MMC_TXDMA_DISABLE	16
+#define ET_MMC_RXDMA_DISABLE	32
+#define ET_MMC_FORCE_CE		64
 
 /*
- * structure for Main Memory Controller Host Memory Access Address reg in mmc
- * address map.  Located at address 0x7004
+ * Main Memory Controller Host Memory Access Address reg in mmc
+ * address map.  Located at address 0x7004. Top 16 bits hold the address bits
  */
-typedef union _MMC_SRAM_ACCESS_t {
-	u32 value;
-	struct {
-#ifdef _BIT_FIELDS_HTOL
-		u32 byte_enable:16;	// bits 16-31
-		u32 reserved2:2;		// bits 14-15
-		u32 req_addr:10;		// bits 4-13
-		u32 reserved1:1;		// bit 3
-		u32 is_ctrl_word:1;	// bit 2
-		u32 wr_access:1;		// bit 1
-		u32 req_access:1;		// bit 0
-#else
-		u32 req_access:1;		// bit 0
-		u32 wr_access:1;		// bit 1
-		u32 is_ctrl_word:1;	// bit 2
-		u32 reserved1:1;		// bit 3
-		u32 req_addr:10;		// bits 4-13
-		u32 reserved2:2;		// bits 14-15
-		u32 byte_enable:16;	// bits 16-31
-#endif
-	} bits;
-} MMC_SRAM_ACCESS_t, *PMMC_SRAM_ACCESS_t;
+
+#define ET_SRAM_REQ_ACCESS	1
+#define ET_SRAM_WR_ACCESS	2
+#define ET_SRAM_IS_CTRL		4
 
 /*
  * structure for Main Memory Controller Host Memory Access Data reg in mmc
@@ -2328,13 +2058,13 @@ typedef union _MMC_SRAM_ACCESS_t {
 /*
  * Memory Control Module of JAGCore Address Mapping
  */
-typedef struct _MMC_t {			// Location:
-	MMC_CTRL_t mmc_ctrl;		//  0x7000
-	MMC_SRAM_ACCESS_t sram_access;	//  0x7004
-	u32 sram_word1;		//  0x7008
-	u32 sram_word2;		//  0x700C
-	u32 sram_word3;		//  0x7010
-	u32 sram_word4;		//  0x7014
+typedef struct _MMC_t {			/* Location: */
+	u32 mmc_ctrl;		/*  0x7000 */
+	u32 sram_access;	/*  0x7004 */
+	u32 sram_word1;		/*  0x7008 */
+	u32 sram_word2;		/*  0x700C */
+	u32 sram_word3;		/*  0x7010 */
+	u32 sram_word4;		/*  0x7014 */
 } MMC_t, *PMMC_t;
 
 /* END OF MMC REGISTER ADDRESS MAP */
@@ -2361,30 +2091,30 @@ typedef struct _EXP_ROM_t {
  */
 typedef struct _ADDRESS_MAP_t {
 	GLOBAL_t global;
-	// unused section of global address map
+	/* unused section of global address map */
 	u8 unused_global[4096 - sizeof(GLOBAL_t)];
 	TXDMA_t txdma;
-	// unused section of txdma address map
+	/* unused section of txdma address map */
 	u8 unused_txdma[4096 - sizeof(TXDMA_t)];
 	RXDMA_t rxdma;
-	// unused section of rxdma address map
+	/* unused section of rxdma address map */
 	u8 unused_rxdma[4096 - sizeof(RXDMA_t)];
 	TXMAC_t txmac;
-	// unused section of txmac address map
+	/* unused section of txmac address map */
 	u8 unused_txmac[4096 - sizeof(TXMAC_t)];
 	RXMAC_t rxmac;
-	// unused section of rxmac address map
+	/* unused section of rxmac address map */
 	u8 unused_rxmac[4096 - sizeof(RXMAC_t)];
 	MAC_t mac;
-	// unused section of mac address map
+	/* unused section of mac address map */
 	u8 unused_mac[4096 - sizeof(MAC_t)];
 	MAC_STAT_t macStat;
-	// unused section of mac stat address map
+	/* unused section of mac stat address map */
 	u8 unused_mac_stat[4096 - sizeof(MAC_STAT_t)];
 	MMC_t mmc;
-	// unused section of mmc address map
+	/* unused section of mmc address map */
 	u8 unused_mmc[4096 - sizeof(MMC_t)];
-	// unused section of address map
+	/* unused section of address map */
 	u8 unused_[1015808];
 
 /* Take this out until it is not empty */
@@ -2392,8 +2122,8 @@ typedef struct _ADDRESS_MAP_t {
 	EXP_ROM_t exp_rom;
 #endif
 
-	u8 unused_exp_rom[4096];	// MGS-size TBD
-	u8 unused__[524288];	// unused section of address map
+	u8 unused_exp_rom[4096];	/* MGS-size TBD */
+	u8 unused__[524288];	/* unused section of address map */
 } ADDRESS_MAP_t, *PADDRESS_MAP_t;
 
 #endif /* _ET1310_ADDRESS_MAP_H_ */
diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c
index c2b194e..c853a2c 100644
--- a/drivers/staging/et131x/et1310_eeprom.c
+++ b/drivers/staging/et131x/et1310_eeprom.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -56,7 +56,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/pci.h>
@@ -74,9 +73,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -137,34 +136,30 @@
  * Define macros that allow individual register values to be extracted from a
  * DWORD1 register grouping
  */
-#define EXTRACT_DATA_REGISTER(x)    (uint8_t)(x & 0xFF)
-#define EXTRACT_STATUS_REGISTER(x)  (uint8_t)((x >> 16) & 0xFF)
-#define EXTRACT_CONTROL_REG(x)      (uint8_t)((x >> 8) & 0xFF)
+#define EXTRACT_DATA_REGISTER(x)    (u8)(x & 0xFF)
+#define EXTRACT_STATUS_REGISTER(x)  (u8)((x >> 16) & 0xFF)
+#define EXTRACT_CONTROL_REG(x)      (u8)((x >> 8) & 0xFF)
 
 /**
  * EepromWriteByte - Write a byte to the ET1310's EEPROM
- * @pAdapter: pointer to our private adapter structure
- * @unAddress: the address to write
- * @bData: the value to write
- * @unEepronId: the ID of the EEPROM
- * @unAddressingMode: how the EEPROM is to be accessed
+ * @etdev: pointer to our private adapter structure
+ * @addr: the address to write
+ * @data: the value to write
  *
  * Returns SUCCESS or FAILURE
  */
-int32_t EepromWriteByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
-			uint8_t bData, uint32_t unEepromId,
-			uint32_t unAddressingMode)
+int EepromWriteByte(struct et131x_adapter *etdev, u32 addr, u8 data)
 {
-        struct pci_dev *pdev = pAdapter->pdev;
-	int32_t nIndex;
-	int32_t nRetries;
-	int32_t nError = false;
-	int32_t nI2CWriteActive = 0;
-	int32_t nWriteSuccessful = 0;
-	uint8_t bControl;
-	uint8_t bStatus = 0;
-	uint32_t unDword1 = 0;
-	uint32_t unData = 0;
+	struct pci_dev *pdev = etdev->pdev;
+	int index;
+	int retries;
+	int err = 0;
+	int i2c_wack = 0;
+	int writeok = 0;
+	u8 control;
+	u8 status = 0;
+	u32 dword1 = 0;
+	u32 val = 0;
 
 	/*
 	 * The following excerpt is from "Serial EEPROM HW Design
@@ -215,93 +210,84 @@ int32_t EepromWriteByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
 	 */
 
 	/* Step 1: */
-	for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+	for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
 		/* Read registers grouped in DWORD1 */
 		if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
-					  &unDword1)) {
-			nError = 1;
+					  &dword1)) {
+			err = 1;
 			break;
 		}
 
-		bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+		status = EXTRACT_STATUS_REGISTER(dword1);
 
-		if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
-		    bStatus & LBCIF_STATUS_I2C_IDLE) {
-		    	/* bits 1:0 are equal to 1 */
+		if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
+			status & LBCIF_STATUS_I2C_IDLE)
+			/* bits 1:0 are equal to 1 */
 			break;
-		}
 	}
 
-	if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+	if (err || (index >= MAX_NUM_REGISTER_POLLS))
 		return FAILURE;
-	}
 
 	/* Step 2: */
-	bControl = 0;
-	bControl |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE;
-
-	if (unAddressingMode == DUAL_BYTE) {
-		bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR;
-	}
+	control = 0;
+	control |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE;
 
 	if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
-				  bControl)) {
+				  control)) {
 		return FAILURE;
 	}
 
-	nI2CWriteActive = 1;
+	i2c_wack = 1;
 
 	/* Prepare EEPROM address for Step 3 */
-	unAddress |= (unAddressingMode == DUAL_BYTE) ?
-	    (unEepromId << 16) : (unEepromId << 8);
 
-	for (nRetries = 0; nRetries < MAX_NUM_WRITE_RETRIES; nRetries++) {
+	for (retries = 0; retries < MAX_NUM_WRITE_RETRIES; retries++) {
 		/* Step 3:*/
 		if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET,
-					   unAddress)) {
+					   addr)) {
 			break;
 		}
 
 		/* Step 4: */
 		if (pci_write_config_byte(pdev, LBCIF_DATA_REGISTER_OFFSET,
-					  bData)) {
+					  data)) {
 			break;
 		}
 
 		/* Step 5: */
-		for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+		for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
 			/* Read registers grouped in DWORD1 */
 			if (pci_read_config_dword(pdev,
 						  LBCIF_DWORD1_GROUP_OFFSET,
-						  &unDword1)) {
-				nError = 1;
+						  &dword1)) {
+				err = 1;
 				break;
 			}
 
-			bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+			status = EXTRACT_STATUS_REGISTER(dword1);
 
-			if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
-			    bStatus & LBCIF_STATUS_I2C_IDLE) {
-			    	/* I2C write complete */
+			if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
+				status & LBCIF_STATUS_I2C_IDLE) {
+				/* I2C write complete */
 				break;
 			}
 		}
 
-		if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+		if (err || (index >= MAX_NUM_REGISTER_POLLS))
 			break;
-		}
 
 		/*
 		 * Step 6: Don't break here if we are revision 1, this is
 		 *	   so we do a blind write for load bug.
-	         */
-		if (bStatus & LBCIF_STATUS_GENERAL_ERROR
-		    && pAdapter->RevisionID == 0) {
+		 */
+		if (status & LBCIF_STATUS_GENERAL_ERROR
+		    && etdev->pdev->revision == 0) {
 			break;
 		}
 
 		/* Step 7 */
-		if (bStatus & LBCIF_STATUS_ACK_ERROR) {
+		if (status & LBCIF_STATUS_ACK_ERROR) {
 			/*
 			 * This could be due to an actual hardware failure
 			 * or the EEPROM may still be in its internal write
@@ -312,19 +298,19 @@ int32_t EepromWriteByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
 			continue;
 		}
 
-		nWriteSuccessful = 1;
+		writeok = 1;
 		break;
 	}
 
 	/* Step 8: */
 	udelay(10);
-	nIndex = 0;
-	while (nI2CWriteActive) {
-		bControl &= ~LBCIF_CONTROL_I2C_WRITE;
+	index = 0;
+	while (i2c_wack) {
+		control &= ~LBCIF_CONTROL_I2C_WRITE;
 
 		if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
-					  bControl)) {
-			nWriteSuccessful = 0;
+					  control)) {
+			writeok = 0;
 		}
 
 		/* Do read until internal ACK_ERROR goes away meaning write
@@ -333,45 +319,42 @@ int32_t EepromWriteByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
 		do {
 			pci_write_config_dword(pdev,
 					       LBCIF_ADDRESS_REGISTER_OFFSET,
-					       unAddress);
+					       addr);
 			do {
 				pci_read_config_dword(pdev,
-					LBCIF_DATA_REGISTER_OFFSET, &unData);
-			} while ((unData & 0x00010000) == 0);
-		} while (unData & 0x00040000);
+					LBCIF_DATA_REGISTER_OFFSET, &val);
+			} while ((val & 0x00010000) == 0);
+		} while (val & 0x00040000);
 
-		bControl = EXTRACT_CONTROL_REG(unData);
+		control = EXTRACT_CONTROL_REG(val);
 
-		if (bControl != 0xC0 || nIndex == 10000) {
+		if (control != 0xC0 || index == 10000)
 			break;
-		}
 
-		nIndex++;
+		index++;
 	}
 
-	return nWriteSuccessful ? SUCCESS : FAILURE;
+	return writeok ? SUCCESS : FAILURE;
 }
 
 /**
  * EepromReadByte - Read a byte from the ET1310's EEPROM
- * @pAdapter: pointer to our private adapter structure
- * @unAddress: the address from which to read
- * @pbData: a pointer to a byte in which to store the value of the read
- * @unEepronId: the ID of the EEPROM
- * @unAddressingMode: how the EEPROM is to be accessed
+ * @etdev: pointer to our private adapter structure
+ * @addr: the address from which to read
+ * @pdata: a pointer to a byte in which to store the value of the read
+ * @eeprom_id: the ID of the EEPROM
+ * @addrmode: how the EEPROM is to be accessed
  *
  * Returns SUCCESS or FAILURE
  */
-int32_t EepromReadByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
-		       uint8_t *pbData, uint32_t unEepromId,
-		       uint32_t unAddressingMode)
+int EepromReadByte(struct et131x_adapter *etdev, u32 addr, u8 *pdata)
 {
-        struct pci_dev *pdev = pAdapter->pdev;
-	int32_t nIndex;
-	int32_t nError = 0;
-	uint8_t bControl;
-	uint8_t bStatus = 0;
-	uint32_t unDword1 = 0;
+	struct pci_dev *pdev = etdev->pdev;
+	int index;
+	int err = 0;
+	u8 control;
+	u8 status = 0;
+	u32 dword1 = 0;
 
 	/*
 	 * The following excerpt is from "Serial EEPROM HW Design
@@ -408,73 +391,65 @@ int32_t EepromReadByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
 	 */
 
 	/* Step 1: */
-	for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+	for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
 		/* Read registers grouped in DWORD1 */
 		if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
-					  &unDword1)) {
-			nError = 1;
+					  &dword1)) {
+			err = 1;
 			break;
 		}
 
-		bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+		status = EXTRACT_STATUS_REGISTER(dword1);
 
-		if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
-		    bStatus & LBCIF_STATUS_I2C_IDLE) {
+		if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
+		    status & LBCIF_STATUS_I2C_IDLE) {
 			/* bits 1:0 are equal to 1 */
 			break;
 		}
 	}
 
-	if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+	if (err || (index >= MAX_NUM_REGISTER_POLLS))
 		return FAILURE;
-	}
 
 	/* Step 2: */
-	bControl = 0;
-	bControl |= LBCIF_CONTROL_LBCIF_ENABLE;
-
-	if (unAddressingMode == DUAL_BYTE) {
-		bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR;
-	}
+	control = 0;
+	control |= LBCIF_CONTROL_LBCIF_ENABLE;
 
 	if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
-				  bControl)) {
+				  control)) {
 		return FAILURE;
 	}
 
 	/* Step 3: */
-	unAddress |= (unAddressingMode == DUAL_BYTE) ?
-	    (unEepromId << 16) : (unEepromId << 8);
 
 	if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET,
-				   unAddress)) {
+				   addr)) {
 		return FAILURE;
 	}
 
 	/* Step 4: */
-	for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+	for (index = 0; index < MAX_NUM_REGISTER_POLLS; index++) {
 		/* Read registers grouped in DWORD1 */
 		if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
-					  &unDword1)) {
-			nError = 1;
+					  &dword1)) {
+			err = 1;
 			break;
 		}
 
-		bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+		status = EXTRACT_STATUS_REGISTER(dword1);
 
-		if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL
-		    && bStatus & LBCIF_STATUS_I2C_IDLE) {
+		if (status & LBCIF_STATUS_PHY_QUEUE_AVAIL
+		    && status & LBCIF_STATUS_I2C_IDLE) {
 			/* I2C read complete */
 			break;
 		}
 	}
 
-	if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+	if (err || (index >= MAX_NUM_REGISTER_POLLS))
 		return FAILURE;
-	}
 
 	/* Step 6: */
-	*pbData = EXTRACT_DATA_REGISTER(unDword1);
+	*pdata = EXTRACT_DATA_REGISTER(dword1);
 
-	return (bStatus & LBCIF_STATUS_ACK_ERROR) ? FAILURE : SUCCESS;
+	return (status & LBCIF_STATUS_ACK_ERROR) ? FAILURE : SUCCESS;
 }
diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h
index 9b6f8ad..d8ac9a0 100644
--- a/drivers/staging/et131x/et1310_eeprom.h
+++ b/drivers/staging/et131x/et1310_eeprom.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -66,24 +66,12 @@
 #define FAILURE		1
 #endif
 
-#ifndef READ
-#define READ		0
-#define WRITE		1
-#endif
-
-#ifndef SINGLE_BYTE
-#define SINGLE_BYTE	0
-#define DUAL_BYTE	1
-#endif
-
 /* Forward declaration of the private adapter structure */
 struct et131x_adapter;
 
 int32_t EepromWriteByte(struct et131x_adapter *adapter, u32 unAddress,
-			u8 bData, u32 unEepromId,
-			u32 unAddressingMode);
+			u8 bData);
 int32_t EepromReadByte(struct et131x_adapter *adapter, u32 unAddress,
-		       u8 *pbData, u32 unEepromId,
-		       u32 unAddressingMode);
+			u8 *pbData);
 
 #endif /* _ET1310_EEPROM_H_ */
diff --git a/drivers/staging/et131x/et1310_jagcore.c b/drivers/staging/et131x/et1310_jagcore.c
deleted file mode 100644
index 993b30e..0000000
--- a/drivers/staging/et131x/et1310_jagcore.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et1310_jagcore.c - All code pertaining to the ET1301/ET131x's JAGcore
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, are permitted provided that the following conditions are met:
- *
- * . Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following Disclaimer as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . 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.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS 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, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- */
-
-#include "et131x_version.h"
-#include "et131x_debug.h"
-#include "et131x_defs.h"
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ioport.h>
-
-#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-
-#include "et131x_adapter.h"
-#include "et131x_initpci.h"
-
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
-
-/**
- * ConfigGlobalRegs - Used to configure the global registers on the JAGCore
- * @pAdpater: pointer to our adapter structure
- */
-void ConfigGlobalRegs(struct et131x_adapter *pAdapter)
-{
-	struct _GLOBAL_t __iomem *pGbl = &pAdapter->CSRAddress->global;
-
-	DBG_ENTER(et131x_dbginfo);
-
-	if (pAdapter->RegistryPhyLoopbk == false) {
-		if (pAdapter->RegistryJumboPacket < 2048) {
-			/* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word
-			 * block of RAM that the driver can split between Tx
-			 * and Rx as it desires.  Our default is to split it
-			 * 50/50:
-			 */
-			writel(0, &pGbl->rxq_start_addr.value);
-			writel(pAdapter->RegistryRxMemEnd,
-			       &pGbl->rxq_end_addr.value);
-			writel(pAdapter->RegistryRxMemEnd + 1,
-			       &pGbl->txq_start_addr.value);
-			writel(INTERNAL_MEM_SIZE - 1,
-			       &pGbl->txq_end_addr.value);
-		} else if (pAdapter->RegistryJumboPacket < 8192) {
-			/* For jumbo packets > 2k but < 8k, split 50-50. */
-			writel(0, &pGbl->rxq_start_addr.value);
-			writel(INTERNAL_MEM_RX_OFFSET,
-			       &pGbl->rxq_end_addr.value);
-			writel(INTERNAL_MEM_RX_OFFSET + 1,
-			       &pGbl->txq_start_addr.value);
-			writel(INTERNAL_MEM_SIZE - 1,
-			       &pGbl->txq_end_addr.value);
-		} else {
-			/* 9216 is the only packet size greater than 8k that
-			 * is available. The Tx buffer has to be big enough
-			 * for one whole packet on the Tx side. We'll make
-			 * the Tx 9408, and give the rest to Rx
-			 */
-			writel(0x0000, &pGbl->rxq_start_addr.value);
-			writel(0x01b3, &pGbl->rxq_end_addr.value);
-			writel(0x01b4, &pGbl->txq_start_addr.value);
-			writel(INTERNAL_MEM_SIZE - 1,
-			       &pGbl->txq_end_addr.value);
-		}
-
-		/* Initialize the loopback register. Disable all loopbacks. */
-		writel(0, &pGbl->loopback.value);
-	} else {
-		/* For PHY Line loopback, the memory is configured as if Tx
-		 * and Rx both have all the memory.  This is because the
-		 * RxMAC will write data into the space, and the TxMAC will
-		 * read it out.
-		 */
-		writel(0, &pGbl->rxq_start_addr.value);
-		writel(INTERNAL_MEM_SIZE - 1, &pGbl->rxq_end_addr.value);
-		writel(0, &pGbl->txq_start_addr.value);
-		writel(INTERNAL_MEM_SIZE - 1, &pGbl->txq_end_addr.value);
-
-		/* Initialize the loopback register (MAC loopback). */
-		writel(1, &pGbl->loopback.value);
-	}
-
-	/* MSI Register */
-	writel(0, &pGbl->msi_config.value);
-
-	/* By default, disable the watchdog timer.  It will be enabled when
-	 * a packet is queued.
-	 */
-	writel(0, &pGbl->watchdog_timer);
-
-	DBG_LEAVE(et131x_dbginfo);
-}
-
-/**
- * ConfigMMCRegs - Used to configure the main memory registers in the JAGCore
- * @pAdapter: pointer to our adapter structure
- */
-void ConfigMMCRegs(struct et131x_adapter *pAdapter)
-{
-	MMC_CTRL_t mmc_ctrl = { 0 };
-
-	DBG_ENTER(et131x_dbginfo);
-
-	/* All we need to do is initialize the Memory Control Register */
-	mmc_ctrl.bits.force_ce = 0x0;
-	mmc_ctrl.bits.rxdma_disable = 0x0;
-	mmc_ctrl.bits.txdma_disable = 0x0;
-	mmc_ctrl.bits.txmac_disable = 0x0;
-	mmc_ctrl.bits.rxmac_disable = 0x0;
-	mmc_ctrl.bits.arb_disable = 0x0;
-	mmc_ctrl.bits.mmc_enable = 0x1;
-
-	writel(mmc_ctrl.value, &pAdapter->CSRAddress->mmc.mmc_ctrl.value);
-
-	DBG_LEAVE(et131x_dbginfo);
-}
-
-void et131x_enable_interrupts(struct et131x_adapter *adapter)
-{
-	uint32_t MaskValue;
-
-	/* Enable all global interrupts */
-	if ((adapter->FlowControl == TxOnly) || (adapter->FlowControl == Both)) {
-		MaskValue = INT_MASK_ENABLE;
-	} else {
-		MaskValue = INT_MASK_ENABLE_NO_FLOW;
-	}
-
-	if (adapter->DriverNoPhyAccess) {
-		MaskValue |= 0x10000;
-	}
-
-	adapter->CachedMaskValue.value = MaskValue;
-	writel(MaskValue, &adapter->CSRAddress->global.int_mask.value);
-}
-
-void et131x_disable_interrupts(struct et131x_adapter * adapter)
-{
-	/* Disable all global interrupts */
-	adapter->CachedMaskValue.value = INT_MASK_DISABLE;
-	writel(INT_MASK_DISABLE, &adapter->CSRAddress->global.int_mask.value);
-}
diff --git a/drivers/staging/et131x/et1310_jagcore.h b/drivers/staging/et131x/et1310_jagcore.h
index 9fc8293..0807a01 100644
--- a/drivers/staging/et131x/et1310_jagcore.h
+++ b/drivers/staging/et131x/et1310_jagcore.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -62,10 +62,8 @@
 #include "et1310_address_map.h"
 
 
-#define INTERNAL_MEM_SIZE       0x400	//1024 of internal memory
-#define INTERNAL_MEM_RX_OFFSET  0x1FF	//50%   Tx, 50%   Rx
-
-#define REGS_MAX_ARRAY          4096
+#define INTERNAL_MEM_SIZE       0x400	/* 1024 of internal memory */
+#define INTERNAL_MEM_RX_OFFSET  0x1FF	/* 50%   Tx, 50%   Rx */
 
 /*
  * For interrupts, normal running is:
@@ -78,29 +76,13 @@
  */
 #define INT_MASK_DISABLE            0xffffffff
 
-// NOTE: Masking out MAC_STAT Interrupt for now...
-//#define INT_MASK_ENABLE             0xfff6bf17
-//#define INT_MASK_ENABLE_NO_FLOW     0xfff6bfd7
+/* NOTE: Masking out MAC_STAT Interrupt for now...
+ * #define INT_MASK_ENABLE             0xfff6bf17
+ * #define INT_MASK_ENABLE_NO_FLOW     0xfff6bfd7
+ */
 #define INT_MASK_ENABLE             0xfffebf17
 #define INT_MASK_ENABLE_NO_FLOW     0xfffebfd7
 
-/* DATA STRUCTURES FOR DIRECT REGISTER ACCESS */
-
-typedef struct {
-	u8 bReadWrite;
-	u32 nRegCount;
-	u32 nData[REGS_MAX_ARRAY];
-	u32 nOffsets[REGS_MAX_ARRAY];
-} JAGCORE_ACCESS_REGS, *PJAGCORE_ACCESS_REGS;
-
-typedef struct {
-	u8 bReadWrite;
-	u32 nDataWidth;
-	u32 nRegCount;
-	u32 nOffsets[REGS_MAX_ARRAY];
-	u32 nData[REGS_MAX_ARRAY];
-} PCI_CFG_SPACE_REGS, *PPCI_CFG_SPACE_REGS;
-
 /* Forward declaration of the private adapter structure */
 struct et131x_adapter;
 
diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c
index 1924968..f81e1cb 100644
--- a/drivers/staging/et131x/et1310_mac.c
+++ b/drivers/staging/et131x/et1310_mac.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -56,7 +56,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/init.h>
@@ -73,9 +72,10 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -92,36 +92,29 @@
 #include "et131x_adapter.h"
 #include "et131x_initpci.h"
 
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
-
 /**
  * ConfigMacRegs1 - Initialize the first part of MAC regs
  * @pAdpater: pointer to our adapter structure
  */
-void ConfigMACRegs1(struct et131x_adapter *pAdapter)
+void ConfigMACRegs1(struct et131x_adapter *etdev)
 {
-	struct _MAC_t __iomem *pMac = &pAdapter->CSRAddress->mac;
+	struct _MAC_t __iomem *pMac = &etdev->regs->mac;
 	MAC_STATION_ADDR1_t station1;
 	MAC_STATION_ADDR2_t station2;
 	MAC_IPG_t ipg;
 	MAC_HFDP_t hfdp;
 	MII_MGMT_CFG_t mii_mgmt_cfg;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* First we need to reset everything.  Write to MAC configuration
 	 * register 1 to perform reset.
 	 */
 	writel(0xC00F0000, &pMac->cfg1.value);
 
 	/* Next lets configure the MAC Inter-packet gap register */
-	ipg.bits.non_B2B_ipg_1 = 0x38;		// 58d
-	ipg.bits.non_B2B_ipg_2 = 0x58;		// 88d
-	ipg.bits.min_ifg_enforce = 0x50;	// 80d
-	ipg.bits.B2B_ipg = 0x60;		// 96d
+	ipg.bits.non_B2B_ipg_1 = 0x38;		/* 58d */
+	ipg.bits.non_B2B_ipg_2 = 0x58;		/* 88d */
+	ipg.bits.min_ifg_enforce = 0x50;	/* 80d */
+	ipg.bits.B2B_ipg = 0x60;		/* 96d */
 	writel(ipg.value, &pMac->ipg.value);
 
 	/* Next lets configure the MAC Half Duplex register */
@@ -131,13 +124,13 @@ void ConfigMACRegs1(struct et131x_adapter *pAdapter)
 	hfdp.bits.no_backoff = 0x0;
 	hfdp.bits.excess_defer = 0x1;
 	hfdp.bits.rexmit_max = 0xF;
-	hfdp.bits.coll_window = 0x37;		// 55d
+	hfdp.bits.coll_window = 0x37;		/* 55d */
 	writel(hfdp.value, &pMac->hfdp.value);
 
 	/* Next lets configure the MAC Interface Control register */
 	writel(0, &pMac->if_ctrl.value);
 
-	/* Let's move on to setting up the mii managment configuration */
+	/* Let's move on to setting up the mii management configuration */
 	mii_mgmt_cfg.bits.reset_mii_mgmt = 0;
 	mii_mgmt_cfg.bits.scan_auto_incremt = 0;
 	mii_mgmt_cfg.bits.preamble_suppress = 0;
@@ -151,12 +144,12 @@ void ConfigMACRegs1(struct et131x_adapter *pAdapter)
 	 * station address is used for generating and checking pause control
 	 * packets.
 	 */
-	station2.bits.Octet1 = pAdapter->CurrentAddress[0];
-	station2.bits.Octet2 = pAdapter->CurrentAddress[1];
-	station1.bits.Octet3 = pAdapter->CurrentAddress[2];
-	station1.bits.Octet4 = pAdapter->CurrentAddress[3];
-	station1.bits.Octet5 = pAdapter->CurrentAddress[4];
-	station1.bits.Octet6 = pAdapter->CurrentAddress[5];
+	station2.bits.Octet1 = etdev->CurrentAddress[0];
+	station2.bits.Octet2 = etdev->CurrentAddress[1];
+	station1.bits.Octet3 = etdev->CurrentAddress[2];
+	station1.bits.Octet4 = etdev->CurrentAddress[3];
+	station1.bits.Octet5 = etdev->CurrentAddress[4];
+	station1.bits.Octet6 = etdev->CurrentAddress[5];
 	writel(station1.value, &pMac->station_addr_1.value);
 	writel(station2.value, &pMac->station_addr_2.value);
 
@@ -167,35 +160,31 @@ void ConfigMACRegs1(struct et131x_adapter *pAdapter)
 	 * Packets larger than (RegistryJumboPacket) that do not contain a
 	 * VLAN ID will be dropped by the Rx function.
 	 */
-	writel(pAdapter->RegistryJumboPacket + 4, &pMac->max_fm_len.value);
+	writel(etdev->RegistryJumboPacket + 4, &pMac->max_fm_len.value);
 
 	/* clear out MAC config reset */
 	writel(0, &pMac->cfg1.value);
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
  * ConfigMacRegs2 - Initialize the second part of MAC regs
  * @pAdpater: pointer to our adapter structure
  */
-void ConfigMACRegs2(struct et131x_adapter *pAdapter)
+void ConfigMACRegs2(struct et131x_adapter *etdev)
 {
 	int32_t delay = 0;
-	struct _MAC_t __iomem *pMac = &pAdapter->CSRAddress->mac;
+	struct _MAC_t __iomem *pMac = &etdev->regs->mac;
 	MAC_CFG1_t cfg1;
 	MAC_CFG2_t cfg2;
 	MAC_IF_CTRL_t ifctrl;
 	TXMAC_CTL_t ctl;
 
-	DBG_ENTER(et131x_dbginfo);
-
-	ctl.value = readl(&pAdapter->CSRAddress->txmac.ctl.value);
+	ctl.value = readl(&etdev->regs->txmac.ctl.value);
 	cfg1.value = readl(&pMac->cfg1.value);
 	cfg2.value = readl(&pMac->cfg2.value);
 	ifctrl.value = readl(&pMac->if_ctrl.value);
 
-	if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
+	if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) {
 		cfg2.bits.if_mode = 0x2;
 		ifctrl.bits.phy_mode = 0x0;
 	} else {
@@ -210,8 +199,8 @@ void ConfigMACRegs2(struct et131x_adapter *pAdapter)
 	/* Set up flow control */
 	cfg1.bits.tx_flow = 0x1;
 
-	if ((pAdapter->FlowControl == RxOnly) ||
-	    (pAdapter->FlowControl == Both)) {
+	if ((etdev->FlowControl == RxOnly) ||
+	    (etdev->FlowControl == Both)) {
 		cfg1.bits.rx_flow = 0x1;
 	} else {
 		cfg1.bits.rx_flow = 0x0;
@@ -232,7 +221,7 @@ void ConfigMACRegs2(struct et131x_adapter *pAdapter)
 	 */
 	cfg2.bits.len_check = 0x1;
 
-	if (pAdapter->RegistryPhyLoopbk == false) {
+	if (etdev->RegistryPhyLoopbk == false) {
 		cfg2.bits.pad_crc = 0x1;
 		cfg2.bits.crc_enable = 0x1;
 	} else {
@@ -241,8 +230,8 @@ void ConfigMACRegs2(struct et131x_adapter *pAdapter)
 	}
 
 	/* 1 - full duplex, 0 - half-duplex */
-	cfg2.bits.full_duplex = pAdapter->uiDuplexMode;
-	ifctrl.bits.ghd_mode = !pAdapter->uiDuplexMode;
+	cfg2.bits.full_duplex = etdev->duplex_mode;
+	ifctrl.bits.ghd_mode = !etdev->duplex_mode;
 
 	writel(ifctrl.value, &pMac->if_ctrl.value);
 	writel(cfg2.value, &pMac->cfg2.value);
@@ -251,48 +240,34 @@ void ConfigMACRegs2(struct et131x_adapter *pAdapter)
 		udelay(10);
 		delay++;
 		cfg1.value = readl(&pMac->cfg1.value);
-	} while ((!cfg1.bits.syncd_rx_en ||
-		  !cfg1.bits.syncd_tx_en) &&
-		 delay < 100);
+	} while ((!cfg1.bits.syncd_rx_en || !cfg1.bits.syncd_tx_en) &&
+								 delay < 100);
 
 	if (delay == 100) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Syncd bits did not respond correctly cfg1 word 0x%08x\n",
-			  cfg1.value);
+		dev_warn(&etdev->pdev->dev,
+		    "Syncd bits did not respond correctly cfg1 word 0x%08x\n",
+			cfg1.value);
 	}
 
-	DBG_TRACE(et131x_dbginfo,
-		  "Speed %d, Dup %d, CFG1 0x%08x, CFG2 0x%08x, if_ctrl 0x%08x\n",
-		  pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode,
-		  readl(&pMac->cfg1.value), readl(&pMac->cfg2.value),
-		  readl(&pMac->if_ctrl.value));
-
 	/* Enable TXMAC */
 	ctl.bits.txmac_en = 0x1;
 	ctl.bits.fc_disable = 0x1;
-	writel(ctl.value, &pAdapter->CSRAddress->txmac.ctl.value);
+	writel(ctl.value, &etdev->regs->txmac.ctl.value);
 
 	/* Ready to start the RXDMA/TXDMA engine */
-	if (!MP_TEST_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER)) {
-		et131x_rx_dma_enable(pAdapter);
-		et131x_tx_dma_enable(pAdapter);
-	} else {
-		DBG_WARNING(et131x_dbginfo,
-			    "Didn't enable Rx/Tx due to low-power mode\n");
+	if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) {
+		et131x_rx_dma_enable(etdev);
+		et131x_tx_dma_enable(etdev);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
-void ConfigRxMacRegs(struct et131x_adapter *pAdapter)
+void ConfigRxMacRegs(struct et131x_adapter *etdev)
 {
-	struct _RXMAC_t __iomem *pRxMac = &pAdapter->CSRAddress->rxmac;
+	struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac;
 	RXMAC_WOL_SA_LO_t sa_lo;
 	RXMAC_WOL_SA_HI_t sa_hi;
 	RXMAC_PF_CTRL_t pf_ctrl = { 0 };
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Disable the MAC while it is being configured (also disable WOL) */
 	writel(0x8, &pRxMac->ctrl.value);
 
@@ -331,22 +306,22 @@ void ConfigRxMacRegs(struct et131x_adapter *pAdapter)
 	writel(0, &pRxMac->mask4_word3);
 
 	/* Lets setup the WOL Source Address */
-	sa_lo.bits.sa3 = pAdapter->CurrentAddress[2];
-	sa_lo.bits.sa4 = pAdapter->CurrentAddress[3];
-	sa_lo.bits.sa5 = pAdapter->CurrentAddress[4];
-	sa_lo.bits.sa6 = pAdapter->CurrentAddress[5];
+	sa_lo.bits.sa3 = etdev->CurrentAddress[2];
+	sa_lo.bits.sa4 = etdev->CurrentAddress[3];
+	sa_lo.bits.sa5 = etdev->CurrentAddress[4];
+	sa_lo.bits.sa6 = etdev->CurrentAddress[5];
 	writel(sa_lo.value, &pRxMac->sa_lo.value);
 
-	sa_hi.bits.sa1 = pAdapter->CurrentAddress[0];
-	sa_hi.bits.sa2 = pAdapter->CurrentAddress[1];
+	sa_hi.bits.sa1 = etdev->CurrentAddress[0];
+	sa_hi.bits.sa2 = etdev->CurrentAddress[1];
 	writel(sa_hi.value, &pRxMac->sa_hi.value);
 
 	/* Disable all Packet Filtering */
 	writel(0, &pRxMac->pf_ctrl.value);
 
 	/* Let's initialize the Unicast Packet filtering address */
-	if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) {
-		SetupDeviceForUnicast(pAdapter);
+	if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) {
+		SetupDeviceForUnicast(etdev);
 		pf_ctrl.bits.filter_uni_en = 1;
 	} else {
 		writel(0, &pRxMac->uni_pf_addr1.value);
@@ -355,18 +330,18 @@ void ConfigRxMacRegs(struct et131x_adapter *pAdapter)
 	}
 
 	/* Let's initialize the Multicast hash */
-	if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
+	if (etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
 		pf_ctrl.bits.filter_multi_en = 0;
 	} else {
 		pf_ctrl.bits.filter_multi_en = 1;
-		SetupDeviceForMulticast(pAdapter);
+		SetupDeviceForMulticast(etdev);
 	}
 
 	/* Runt packet filtering.  Didn't work in version A silicon. */
 	pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4;
 	pf_ctrl.bits.filter_frag_en = 1;
 
-	if (pAdapter->RegistryJumboPacket > 8192) {
+	if (etdev->RegistryJumboPacket > 8192) {
 		RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;
 
 		/* In order to transmit jumbo packets greater than 8k, the
@@ -409,11 +384,10 @@ void ConfigRxMacRegs(struct et131x_adapter *pAdapter)
 	 * bit 16: Receive frame truncated.
 	 * bit 17: Drop packet enable
 	 */
-	if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS) {
+	if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS)
 		writel(0x30038, &pRxMac->mif_ctrl.value);
-	} else {
+	else
 		writel(0x30030, &pRxMac->mif_ctrl.value);
-	}
 
 	/* Finally we initialize RxMac to be enabled & WOL disabled.  Packet
 	 * filter is always enabled since it is where the runt packets are
@@ -423,38 +397,30 @@ void ConfigRxMacRegs(struct et131x_adapter *pAdapter)
 	 */
 	writel(pf_ctrl.value, &pRxMac->pf_ctrl.value);
 	writel(0x9, &pRxMac->ctrl.value);
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
-void ConfigTxMacRegs(struct et131x_adapter *pAdapter)
+void ConfigTxMacRegs(struct et131x_adapter *etdev)
 {
-	struct _TXMAC_t __iomem *pTxMac = &pAdapter->CSRAddress->txmac;
+	struct _TXMAC_t __iomem *pTxMac = &etdev->regs->txmac;
 	TXMAC_CF_PARAM_t Local;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* We need to update the Control Frame Parameters
 	 * cfpt - control frame pause timer set to 64 (0x40)
 	 * cfep - control frame extended pause timer set to 0x0
 	 */
-	if (pAdapter->FlowControl == None) {
+	if (etdev->FlowControl == None) {
 		writel(0, &pTxMac->cf_param.value);
 	} else {
 		Local.bits.cfpt = 0x40;
 		Local.bits.cfep = 0x0;
 		writel(Local.value, &pTxMac->cf_param.value);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
-void ConfigMacStatRegs(struct et131x_adapter *pAdapter)
+void ConfigMacStatRegs(struct et131x_adapter *etdev)
 {
 	struct _MAC_STAT_t __iomem *pDevMacStat =
-		&pAdapter->CSRAddress->macStat;
-
-	DBG_ENTER(et131x_dbginfo);
+		&etdev->regs->macStat;
 
 	/* Next we need to initialize all the MAC_STAT registers to zero on
 	 * the device.
@@ -536,56 +502,52 @@ void ConfigMacStatRegs(struct et131x_adapter *pAdapter)
 
 		writel(Carry2M.value, &pDevMacStat->Carry2M.value);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
-void ConfigFlowControl(struct et131x_adapter * pAdapter)
+void ConfigFlowControl(struct et131x_adapter *etdev)
 {
-	if (pAdapter->uiDuplexMode == 0) {
-		pAdapter->FlowControl = None;
+	if (etdev->duplex_mode == 0) {
+		etdev->FlowControl = None;
 	} else {
 		char RemotePause, RemoteAsyncPause;
 
-		ET1310_PhyAccessMiBit(pAdapter,
+		ET1310_PhyAccessMiBit(etdev,
 				      TRUEPHY_BIT_READ, 5, 10, &RemotePause);
-		ET1310_PhyAccessMiBit(pAdapter,
+		ET1310_PhyAccessMiBit(etdev,
 				      TRUEPHY_BIT_READ, 5, 11,
 				      &RemoteAsyncPause);
 
 		if ((RemotePause == TRUEPHY_BIT_SET) &&
 		    (RemoteAsyncPause == TRUEPHY_BIT_SET)) {
-			pAdapter->FlowControl = pAdapter->RegistryFlowControl;
+			etdev->FlowControl = etdev->RegistryFlowControl;
 		} else if ((RemotePause == TRUEPHY_BIT_SET) &&
 			   (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) {
-			if (pAdapter->RegistryFlowControl == Both) {
-				pAdapter->FlowControl = Both;
-			} else {
-				pAdapter->FlowControl = None;
-			}
+			if (etdev->RegistryFlowControl == Both)
+				etdev->FlowControl = Both;
+			else
+				etdev->FlowControl = None;
 		} else if ((RemotePause == TRUEPHY_BIT_CLEAR) &&
 			   (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) {
-			pAdapter->FlowControl = None;
+			etdev->FlowControl = None;
 		} else {/* if (RemotePause == TRUEPHY_CLEAR_BIT &&
 			       RemoteAsyncPause == TRUEPHY_SET_BIT) */
-			if (pAdapter->RegistryFlowControl == Both) {
-				pAdapter->FlowControl = RxOnly;
-			} else {
-				pAdapter->FlowControl = None;
-			}
+			if (etdev->RegistryFlowControl == Both)
+				etdev->FlowControl = RxOnly;
+			else
+				etdev->FlowControl = None;
 		}
 	}
 }
 
 /**
  * UpdateMacStatHostCounters - Update the local copy of the statistics
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  */
-void UpdateMacStatHostCounters(struct et131x_adapter *pAdapter)
+void UpdateMacStatHostCounters(struct et131x_adapter *etdev)
 {
-	struct _ce_stats_t *stats = &pAdapter->Stats;
+	struct _ce_stats_t *stats = &etdev->Stats;
 	struct _MAC_STAT_t __iomem *pDevMacStat =
-		&pAdapter->CSRAddress->macStat;
+		&etdev->regs->macStat;
 
 	stats->collisions += readl(&pDevMacStat->TNcl);
 	stats->first_collision += readl(&pDevMacStat->TScl);
@@ -607,27 +569,25 @@ void UpdateMacStatHostCounters(struct et131x_adapter *pAdapter)
 
 /**
  * HandleMacStatInterrupt
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  *
  * One of the MACSTAT counters has wrapped.  Update the local copy of
  * the statistics held in the adapter structure, checking the "wrap"
  * bit for each counter.
  */
-void HandleMacStatInterrupt(struct et131x_adapter *pAdapter)
+void HandleMacStatInterrupt(struct et131x_adapter *etdev)
 {
 	MAC_STAT_REG_1_t Carry1;
 	MAC_STAT_REG_2_t Carry2;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Read the interrupt bits from the register(s).  These are Clear On
 	 * Write.
 	 */
-	Carry1.value = readl(&pAdapter->CSRAddress->macStat.Carry1.value);
-	Carry2.value = readl(&pAdapter->CSRAddress->macStat.Carry2.value);
+	Carry1.value = readl(&etdev->regs->macStat.Carry1.value);
+	Carry2.value = readl(&etdev->regs->macStat.Carry2.value);
 
-	writel(Carry1.value, &pAdapter->CSRAddress->macStat.Carry1.value);
-	writel(Carry2.value, &pAdapter->CSRAddress->macStat.Carry2.value);
+	writel(Carry1.value, &etdev->regs->macStat.Carry1.value);
+	writel(Carry2.value, &etdev->regs->macStat.Carry2.value);
 
 	/* We need to do update the host copy of all the MAC_STAT counters.
 	 * For each counter, check it's overflow bit.  If the overflow bit is
@@ -635,88 +595,56 @@ void HandleMacStatInterrupt(struct et131x_adapter *pAdapter)
 	 * revolution of the counter.  This routine is called when the counter
 	 * block indicates that one of the counters has wrapped.
 	 */
-	if (Carry1.bits.rfcs) {
-		pAdapter->Stats.code_violations += COUNTER_WRAP_16_BIT;
-	}
-	if (Carry1.bits.raln) {
-		pAdapter->Stats.alignment_err += COUNTER_WRAP_12_BIT;
-	}
-	if (Carry1.bits.rflr) {
-		pAdapter->Stats.length_err += COUNTER_WRAP_16_BIT;
-	}
-	if (Carry1.bits.rfrg) {
-		pAdapter->Stats.other_errors += COUNTER_WRAP_16_BIT;
-	}
-	if (Carry1.bits.rcde) {
-		pAdapter->Stats.crc_err += COUNTER_WRAP_16_BIT;
-	}
-	if (Carry1.bits.rovr) {
-		pAdapter->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT;
-	}
-	if (Carry1.bits.rdrp) {
-		pAdapter->Stats.norcvbuf += COUNTER_WRAP_16_BIT;
-	}
-	if (Carry2.bits.tovr) {
-		pAdapter->Stats.max_pkt_error += COUNTER_WRAP_12_BIT;
-	}
-	if (Carry2.bits.tund) {
-		pAdapter->Stats.tx_uflo += COUNTER_WRAP_12_BIT;
-	}
-	if (Carry2.bits.tscl) {
-		pAdapter->Stats.first_collision += COUNTER_WRAP_12_BIT;
-	}
-	if (Carry2.bits.tdfr) {
-		pAdapter->Stats.tx_deferred += COUNTER_WRAP_12_BIT;
-	}
-	if (Carry2.bits.tmcl) {
-		pAdapter->Stats.excessive_collisions += COUNTER_WRAP_12_BIT;
-	}
-	if (Carry2.bits.tlcl) {
-		pAdapter->Stats.late_collisions += COUNTER_WRAP_12_BIT;
-	}
-	if (Carry2.bits.tncl) {
-		pAdapter->Stats.collisions += COUNTER_WRAP_12_BIT;
-	}
-
-	DBG_LEAVE(et131x_dbginfo);
+	if (Carry1.bits.rfcs)
+		etdev->Stats.code_violations += COUNTER_WRAP_16_BIT;
+	if (Carry1.bits.raln)
+		etdev->Stats.alignment_err += COUNTER_WRAP_12_BIT;
+	if (Carry1.bits.rflr)
+		etdev->Stats.length_err += COUNTER_WRAP_16_BIT;
+	if (Carry1.bits.rfrg)
+		etdev->Stats.other_errors += COUNTER_WRAP_16_BIT;
+	if (Carry1.bits.rcde)
+		etdev->Stats.crc_err += COUNTER_WRAP_16_BIT;
+	if (Carry1.bits.rovr)
+		etdev->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT;
+	if (Carry1.bits.rdrp)
+		etdev->Stats.norcvbuf += COUNTER_WRAP_16_BIT;
+	if (Carry2.bits.tovr)
+		etdev->Stats.max_pkt_error += COUNTER_WRAP_12_BIT;
+	if (Carry2.bits.tund)
+		etdev->Stats.tx_uflo += COUNTER_WRAP_12_BIT;
+	if (Carry2.bits.tscl)
+		etdev->Stats.first_collision += COUNTER_WRAP_12_BIT;
+	if (Carry2.bits.tdfr)
+		etdev->Stats.tx_deferred += COUNTER_WRAP_12_BIT;
+	if (Carry2.bits.tmcl)
+		etdev->Stats.excessive_collisions += COUNTER_WRAP_12_BIT;
+	if (Carry2.bits.tlcl)
+		etdev->Stats.late_collisions += COUNTER_WRAP_12_BIT;
+	if (Carry2.bits.tncl)
+		etdev->Stats.collisions += COUNTER_WRAP_12_BIT;
 }
 
-void SetupDeviceForMulticast(struct et131x_adapter *pAdapter)
+void SetupDeviceForMulticast(struct et131x_adapter *etdev)
 {
-	struct _RXMAC_t __iomem *rxmac = &pAdapter->CSRAddress->rxmac;
+	struct _RXMAC_t __iomem *rxmac = &etdev->regs->rxmac;
 	uint32_t nIndex;
 	uint32_t result;
 	uint32_t hash1 = 0;
 	uint32_t hash2 = 0;
 	uint32_t hash3 = 0;
 	uint32_t hash4 = 0;
-	PM_CSR_t pm_csr;
-
-	DBG_ENTER(et131x_dbginfo);
+	u32 pm_csr;
 
 	/* If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision
 	 * the multi-cast LIST.  If it is NOT specified, (and "ALL" is not
 	 * specified) then we should pass NO multi-cast addresses to the
 	 * driver.
 	 */
-	if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) {
-		DBG_VERBOSE(et131x_dbginfo,
-			    "MULTICAST flag is set, MCCount: %d\n",
-			    pAdapter->MCAddressCount);
-
+	if (etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) {
 		/* Loop through our multicast array and set up the device */
-		for (nIndex = 0; nIndex < pAdapter->MCAddressCount; nIndex++) {
-			DBG_VERBOSE(et131x_dbginfo,
-				    "MCList[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n",
-				    nIndex,
-				    pAdapter->MCList[nIndex][0],
-				    pAdapter->MCList[nIndex][1],
-				    pAdapter->MCList[nIndex][2],
-				    pAdapter->MCList[nIndex][3],
-				    pAdapter->MCList[nIndex][4],
-				    pAdapter->MCList[nIndex][5]);
-
-			result = ether_crc(6, pAdapter->MCList[nIndex]);
+		for (nIndex = 0; nIndex < etdev->MCAddressCount; nIndex++) {
+			result = ether_crc(6, etdev->MCList[nIndex]);
 
 			result = (result & 0x3F800000) >> 23;
 
@@ -736,26 +664,22 @@ void SetupDeviceForMulticast(struct et131x_adapter *pAdapter)
 	}
 
 	/* Write out the new hash to the device */
-	pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
-	if (pm_csr.bits.pm_phy_sw_coma == 0) {
+	pm_csr = readl(&etdev->regs->global.pm_csr);
+	if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) {
 		writel(hash1, &rxmac->multi_hash1);
 		writel(hash2, &rxmac->multi_hash2);
 		writel(hash3, &rxmac->multi_hash3);
 		writel(hash4, &rxmac->multi_hash4);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
-void SetupDeviceForUnicast(struct et131x_adapter *pAdapter)
+void SetupDeviceForUnicast(struct et131x_adapter *etdev)
 {
-	struct _RXMAC_t __iomem *rxmac = &pAdapter->CSRAddress->rxmac;
+	struct _RXMAC_t __iomem *rxmac = &etdev->regs->rxmac;
 	RXMAC_UNI_PF_ADDR1_t uni_pf1;
 	RXMAC_UNI_PF_ADDR2_t uni_pf2;
 	RXMAC_UNI_PF_ADDR3_t uni_pf3;
-	PM_CSR_t pm_csr;
-
-	DBG_ENTER(et131x_dbginfo);
+	u32 pm_csr;
 
 	/* Set up unicast packet filter reg 3 to be the first two octets of
 	 * the MAC address for both address
@@ -766,27 +690,25 @@ void SetupDeviceForUnicast(struct et131x_adapter *pAdapter)
 	 * Set up unicast packet filter reg 3 to be the octets 2 - 5 of the
 	 * MAC address for first address
 	 */
-	uni_pf3.bits.addr1_1 = pAdapter->CurrentAddress[0];
-	uni_pf3.bits.addr1_2 = pAdapter->CurrentAddress[1];
-	uni_pf3.bits.addr2_1 = pAdapter->CurrentAddress[0];
-	uni_pf3.bits.addr2_2 = pAdapter->CurrentAddress[1];
-
-	uni_pf2.bits.addr2_3 = pAdapter->CurrentAddress[2];
-	uni_pf2.bits.addr2_4 = pAdapter->CurrentAddress[3];
-	uni_pf2.bits.addr2_5 = pAdapter->CurrentAddress[4];
-	uni_pf2.bits.addr2_6 = pAdapter->CurrentAddress[5];
-
-	uni_pf1.bits.addr1_3 = pAdapter->CurrentAddress[2];
-	uni_pf1.bits.addr1_4 = pAdapter->CurrentAddress[3];
-	uni_pf1.bits.addr1_5 = pAdapter->CurrentAddress[4];
-	uni_pf1.bits.addr1_6 = pAdapter->CurrentAddress[5];
-
-	pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
-	if (pm_csr.bits.pm_phy_sw_coma == 0) {
+	uni_pf3.bits.addr1_1 = etdev->CurrentAddress[0];
+	uni_pf3.bits.addr1_2 = etdev->CurrentAddress[1];
+	uni_pf3.bits.addr2_1 = etdev->CurrentAddress[0];
+	uni_pf3.bits.addr2_2 = etdev->CurrentAddress[1];
+
+	uni_pf2.bits.addr2_3 = etdev->CurrentAddress[2];
+	uni_pf2.bits.addr2_4 = etdev->CurrentAddress[3];
+	uni_pf2.bits.addr2_5 = etdev->CurrentAddress[4];
+	uni_pf2.bits.addr2_6 = etdev->CurrentAddress[5];
+
+	uni_pf1.bits.addr1_3 = etdev->CurrentAddress[2];
+	uni_pf1.bits.addr1_4 = etdev->CurrentAddress[3];
+	uni_pf1.bits.addr1_5 = etdev->CurrentAddress[4];
+	uni_pf1.bits.addr1_6 = etdev->CurrentAddress[5];
+
+	pm_csr = readl(&etdev->regs->global.pm_csr);
+	if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) {
 		writel(uni_pf1.value, &rxmac->uni_pf_addr1.value);
 		writel(uni_pf2.value, &rxmac->uni_pf_addr2.value);
 		writel(uni_pf3.value, &rxmac->uni_pf_addr3.value);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
diff --git a/drivers/staging/et131x/et1310_mac.h b/drivers/staging/et131x/et1310_mac.h
index bd26cd3..2c38595 100644
--- a/drivers/staging/et131x/et1310_mac.h
+++ b/drivers/staging/et131x/et1310_mac.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -73,7 +73,7 @@
 #define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
 #define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
 
-#define UPDATE_COUNTER(HostCnt,DevCnt) \
+#define UPDATE_COUNTER(HostCnt, DevCnt) \
     HostCnt = HostCnt + DevCnt;
 
 /* Forward declaration of the private adapter structure */
diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c
index 9dd6dfd..dd199bd 100644
--- a/drivers/staging/et131x/et1310_phy.c
+++ b/drivers/staging/et131x/et1310_phy.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright * 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright * 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -56,7 +56,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/pci.h>
@@ -74,9 +73,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -98,11 +97,6 @@
 #include "et1310_rx.h"
 #include "et1310_mac.h"
 
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
-
 /* Prototypes for functions with local scope */
 static int et131x_xcvr_init(struct et131x_adapter *adapter);
 
@@ -118,7 +112,7 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter);
 int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr,
 	      uint8_t xcvrReg, uint16_t *value)
 {
-	struct _MAC_t __iomem *mac = &adapter->CSRAddress->mac;
+	struct _MAC_t __iomem *mac = &adapter->regs->mac;
 	int status = 0;
 	uint32_t delay;
 	MII_MGMT_ADDR_t miiAddr;
@@ -157,9 +151,9 @@ int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr,
 
 	/* If we hit the max delay, we could not read the register */
 	if (delay >= 50) {
-		DBG_WARNING(et131x_dbginfo,
+		dev_warn(&adapter->pdev->dev,
 			    "xcvrReg 0x%08x could not be read\n", xcvrReg);
-		DBG_WARNING(et131x_dbginfo, "status is  0x%08x\n",
+		dev_warn(&adapter->pdev->dev, "status is  0x%08x\n",
 			    miiIndicator.value);
 
 		status = -EIO;
@@ -179,10 +173,6 @@ int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr,
 	/* Stop the read operation */
 	writel(0, &mac->mii_mgmt_cmd.value);
 
-	DBG_VERBOSE(et131x_dbginfo, "  xcvr_addr = 0x%02x, "
-		    "xcvr_reg  = 0x%02x, "
-		    "value     = 0x%04x.\n", xcvrAddr, xcvrReg, *value);
-
 	/* set the registers we touched back to the state at which we entered
 	 * this function
 	 */
@@ -202,7 +192,7 @@ int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr,
  */
 int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
 {
-	struct _MAC_t __iomem *mac = &adapter->CSRAddress->mac;
+	struct _MAC_t __iomem *mac = &adapter->regs->mac;
 	int status = 0;
 	uint8_t xcvrAddr = adapter->Stats.xcvr_addr;
 	uint32_t delay;
@@ -242,11 +232,11 @@ int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
 	if (delay == 100) {
 		uint16_t TempValue;
 
-		DBG_WARNING(et131x_dbginfo,
-			    "xcvrReg 0x%08x could not be written", xcvrReg);
-		DBG_WARNING(et131x_dbginfo, "status is  0x%08x\n",
+		dev_warn(&adapter->pdev->dev,
+		    "xcvrReg 0x%08x could not be written", xcvrReg);
+		dev_warn(&adapter->pdev->dev, "status is  0x%08x\n",
 			    miiIndicator.value);
-		DBG_WARNING(et131x_dbginfo, "command is  0x%08x\n",
+		dev_warn(&adapter->pdev->dev, "command is  0x%08x\n",
 			    readl(&mac->mii_mgmt_cmd.value));
 
 		MiRead(adapter, xcvrReg, &TempValue);
@@ -258,15 +248,11 @@ int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
 	writel(0, &mac->mii_mgmt_cmd.value);
 
 	/* set the registers we touched back to the state at which we entered
-         * this function
-         */
+	 * this function
+	 */
 	writel(miiAddr.value, &mac->mii_mgmt_addr.value);
 	writel(miiCmd.value, &mac->mii_mgmt_cmd.value);
 
-	DBG_VERBOSE(et131x_dbginfo, " xcvr_addr = 0x%02x, "
-		    "xcvr_reg  = 0x%02x, "
-		    "value     = 0x%04x.\n", xcvrAddr, xcvrReg, value);
-
 	return status;
 }
 
@@ -284,8 +270,6 @@ int et131x_xcvr_find(struct et131x_adapter *adapter)
 	MI_IDR2_t idr2;
 	uint32_t xcvr_id;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* We need to get xcvr id and address we just get the first one */
 	for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) {
 		/* Read the ID from the PHY */
@@ -299,10 +283,6 @@ int et131x_xcvr_find(struct et131x_adapter *adapter)
 		xcvr_id = (uint32_t) ((idr1.value << 16) | idr2.value);
 
 		if ((idr1.value != 0) && (idr1.value != 0xffff)) {
-			DBG_TRACE(et131x_dbginfo,
-				  "Xcvr addr: 0x%02x\tXcvr_id: 0x%08x\n",
-				  xcvr_addr, xcvr_id);
-
 			adapter->Stats.xcvr_id = xcvr_id;
 			adapter->Stats.xcvr_addr = xcvr_addr;
 
@@ -310,8 +290,6 @@ int et131x_xcvr_find(struct et131x_adapter *adapter)
 			break;
 		}
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -327,13 +305,9 @@ int et131x_setphy_normal(struct et131x_adapter *adapter)
 {
 	int status;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Make sure the PHY is powered up */
 	ET1310_PhyPowerDown(adapter, 0);
 	status = et131x_xcvr_init(adapter);
-
-	DBG_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -350,8 +324,6 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter)
 	MI_ISR_t isr;
 	MI_LCR2_t lcr2;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Zero out the adapter structure variable representing BMSR */
 	adapter->Bmsr.value = 0;
 
@@ -412,8 +384,6 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter)
 
 		/* NOTE - Do we need this? */
 		ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL);
-
-		DBG_LEAVE(et131x_dbginfo);
 		return status;
 	} else {
 		ET1310_PhyAutoNeg(adapter, false);
@@ -449,79 +419,75 @@ static int et131x_xcvr_init(struct et131x_adapter *adapter)
 
 		switch (adapter->AiForceSpeed) {
 		case 10:
-			if (adapter->AiForceDpx == 1) {
+			if (adapter->AiForceDpx == 1)
 				TPAL_SetPhy10HalfDuplex(adapter);
-			} else if (adapter->AiForceDpx == 2) {
+			else if (adapter->AiForceDpx == 2)
 				TPAL_SetPhy10FullDuplex(adapter);
-			} else {
+			else
 				TPAL_SetPhy10Force(adapter);
-			}
 			break;
 		case 100:
-			if (adapter->AiForceDpx == 1) {
+			if (adapter->AiForceDpx == 1)
 				TPAL_SetPhy100HalfDuplex(adapter);
-			} else if (adapter->AiForceDpx == 2) {
+			else if (adapter->AiForceDpx == 2)
 				TPAL_SetPhy100FullDuplex(adapter);
-			} else {
+			else
 				TPAL_SetPhy100Force(adapter);
-			}
 			break;
 		case 1000:
 			TPAL_SetPhy1000FullDuplex(adapter);
 			break;
 		}
 
-		DBG_LEAVE(et131x_dbginfo);
 		return status;
 	}
 }
 
-void et131x_Mii_check(struct et131x_adapter *pAdapter,
+void et131x_Mii_check(struct et131x_adapter *etdev,
 		      MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints)
 {
-	uint8_t ucLinkStatus;
-	uint32_t uiAutoNegStatus;
-	uint32_t uiSpeed;
-	uint32_t uiDuplex;
-	uint32_t uiMdiMdix;
-	uint32_t uiMasterSlave;
-	uint32_t uiPolarity;
-	unsigned long lockflags;
-
-	DBG_ENTER(et131x_dbginfo);
+	uint8_t link_status;
+	uint32_t autoneg_status;
+	uint32_t speed;
+	uint32_t duplex;
+	uint32_t mdi_mdix;
+	uint32_t masterslave;
+	uint32_t polarity;
+	unsigned long flags;
 
 	if (bmsr_ints.bits.link_status) {
 		if (bmsr.bits.link_status) {
-			pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20;
+			etdev->PoMgmt.TransPhyComaModeOnBoot = 20;
 
 			/* Update our state variables and indicate the
 			 * connected state
 			 */
-			spin_lock_irqsave(&pAdapter->Lock, lockflags);
+			spin_lock_irqsave(&etdev->Lock, flags);
 
-			pAdapter->MediaState = NETIF_STATUS_MEDIA_CONNECT;
-			MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION);
+			etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT;
+			etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION;
 
-			spin_unlock_irqrestore(&pAdapter->Lock, lockflags);
+			spin_unlock_irqrestore(&etdev->Lock, flags);
 
 			/* Don't indicate state if we're in loopback mode */
-			if (pAdapter->RegistryPhyLoopbk == false) {
-				netif_carrier_on(pAdapter->netdev);
-			}
+			if (etdev->RegistryPhyLoopbk == false)
+				netif_carrier_on(etdev->netdev);
 		} else {
-			DBG_WARNING(et131x_dbginfo,
-				    "Link down cable problem\n");
+			dev_warn(&etdev->pdev->dev,
+			    "Link down - cable problem ?\n");
 
-			if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS) {
-				// NOTE - Is there a way to query this without TruePHY?
-				// && TRU_QueryCoreType(pAdapter->hTruePhy, 0) == EMI_TRUEPHY_A13O) {
+			if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) {
+				/* NOTE - Is there a way to query this without
+				 * TruePHY?
+				 * && TRU_QueryCoreType(etdev->hTruePhy, 0) == EMI_TRUEPHY_A13O) {
+				 */
 				uint16_t Register18;
 
-				MiRead(pAdapter, 0x12, &Register18);
-				MiWrite(pAdapter, 0x12, Register18 | 0x4);
-				MiWrite(pAdapter, 0x10, Register18 | 0x8402);
-				MiWrite(pAdapter, 0x11, Register18 | 511);
-				MiWrite(pAdapter, 0x12, Register18);
+				MiRead(etdev, 0x12, &Register18);
+				MiWrite(etdev, 0x12, Register18 | 0x4);
+				MiWrite(etdev, 0x10, Register18 | 0x8402);
+				MiWrite(etdev, 0x11, Register18 | 511);
+				MiWrite(etdev, 0x12, Register18);
 			}
 
 			/* For the first N seconds of life, we are in "link
@@ -530,35 +496,32 @@ void et131x_Mii_check(struct et131x_adapter *pAdapter,
 			 * Timer expires, we can report disconnected (handled
 			 * in the LinkDetectionDPC).
 			 */
-			if ((MP_IS_FLAG_CLEAR
-			     (pAdapter, fMP_ADAPTER_LINK_DETECTION))
-			    || (pAdapter->MediaState ==
-				NETIF_STATUS_MEDIA_DISCONNECT)) {
-				spin_lock_irqsave(&pAdapter->Lock, lockflags);
-				pAdapter->MediaState =
+			if (!(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) ||
+			  (etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) {
+				spin_lock_irqsave(&etdev->Lock, flags);
+				etdev->MediaState =
 				    NETIF_STATUS_MEDIA_DISCONNECT;
-				spin_unlock_irqrestore(&pAdapter->Lock,
-						       lockflags);
+				spin_unlock_irqrestore(&etdev->Lock,
+						       flags);
 
 				/* Only indicate state if we're in loopback
 				 * mode
 				 */
-				if (pAdapter->RegistryPhyLoopbk == false) {
-					netif_carrier_off(pAdapter->netdev);
-				}
+				if (etdev->RegistryPhyLoopbk == false)
+					netif_carrier_off(etdev->netdev);
 			}
 
-			pAdapter->uiLinkSpeed = 0;
-			pAdapter->uiDuplexMode = 0;
+			etdev->linkspeed = 0;
+			etdev->duplex_mode = 0;
 
 			/* Free the packets being actively sent & stopped */
-			et131x_free_busy_send_packets(pAdapter);
+			et131x_free_busy_send_packets(etdev);
 
 			/* Re-initialize the send structures */
-			et131x_init_send(pAdapter);
+			et131x_init_send(etdev);
 
 			/* Reset the RFD list and re-start RU */
-			et131x_reset_recv(pAdapter);
+			et131x_reset_recv(etdev);
 
 			/*
 			 * Bring the device back to the state it was during
@@ -566,296 +529,256 @@ void et131x_Mii_check(struct et131x_adapter *pAdapter,
 			 * way, when we get the auto-neg complete interrupt,
 			 * we can complete init by calling ConfigMacREGS2.
 			 */
-			et131x_soft_reset(pAdapter);
+			et131x_soft_reset(etdev);
 
 			/* Setup ET1310 as per the documentation */
-			et131x_adapter_setup(pAdapter);
+			et131x_adapter_setup(etdev);
 
 			/* Setup the PHY into coma mode until the cable is
 			 * plugged back in
 			 */
-			if (pAdapter->RegistryPhyComa == 1) {
-				EnablePhyComa(pAdapter);
-			}
+			if (etdev->RegistryPhyComa == 1)
+				EnablePhyComa(etdev);
 		}
 	}
 
 	if (bmsr_ints.bits.auto_neg_complete ||
-	    ((pAdapter->AiForceDpx == 3) && (bmsr_ints.bits.link_status))) {
-		if (bmsr.bits.auto_neg_complete || (pAdapter->AiForceDpx == 3)) {
-			ET1310_PhyLinkStatus(pAdapter,
-					     &ucLinkStatus, &uiAutoNegStatus,
-					     &uiSpeed, &uiDuplex, &uiMdiMdix,
-					     &uiMasterSlave, &uiPolarity);
-
-			pAdapter->uiLinkSpeed = uiSpeed;
-			pAdapter->uiDuplexMode = uiDuplex;
-
-			DBG_TRACE(et131x_dbginfo,
-				  "pAdapter->uiLinkSpeed 0x%04x, pAdapter->uiDuplex 0x%08x\n",
-				  pAdapter->uiLinkSpeed,
-				  pAdapter->uiDuplexMode);
-
-			pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20;
-
-			if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS) {
-				// NOTE - Is there a way to query this without TruePHY?
-				// && TRU_QueryCoreType(pAdapter->hTruePhy, 0) == EMI_TRUEPHY_A13O) {
+	    (etdev->AiForceDpx == 3 && bmsr_ints.bits.link_status)) {
+		if (bmsr.bits.auto_neg_complete || etdev->AiForceDpx == 3) {
+			ET1310_PhyLinkStatus(etdev,
+					     &link_status, &autoneg_status,
+					     &speed, &duplex, &mdi_mdix,
+					     &masterslave, &polarity);
+
+			etdev->linkspeed = speed;
+			etdev->duplex_mode = duplex;
+
+			etdev->PoMgmt.TransPhyComaModeOnBoot = 20;
+
+			if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) {
+				/*
+				 * NOTE - Is there a way to query this without
+				 * TruePHY?
+				 * && TRU_QueryCoreType(etdev->hTruePhy, 0)== EMI_TRUEPHY_A13O) {
+				 */
 				uint16_t Register18;
 
-				MiRead(pAdapter, 0x12, &Register18);
-				MiWrite(pAdapter, 0x12, Register18 | 0x4);
-				MiWrite(pAdapter, 0x10, Register18 | 0x8402);
-				MiWrite(pAdapter, 0x11, Register18 | 511);
-				MiWrite(pAdapter, 0x12, Register18);
+				MiRead(etdev, 0x12, &Register18);
+				MiWrite(etdev, 0x12, Register18 | 0x4);
+				MiWrite(etdev, 0x10, Register18 | 0x8402);
+				MiWrite(etdev, 0x11, Register18 | 511);
+				MiWrite(etdev, 0x12, Register18);
 			}
 
-			ConfigFlowControl(pAdapter);
+			ConfigFlowControl(etdev);
 
-			if ((pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) &&
-			    (pAdapter->RegistryJumboPacket > 2048))
-			{
-				ET1310_PhyAndOrReg(pAdapter, 0x16, 0xcfff,
-						   0x2000);
-			}
+			if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS &&
+					etdev->RegistryJumboPacket > 2048)
+				ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff,
+								   0x2000);
 
-			SetRxDmaTimer(pAdapter);
-			ConfigMACRegs2(pAdapter);
+			SetRxDmaTimer(etdev);
+			ConfigMACRegs2(etdev);
 		}
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
  * TPAL_SetPhy10HalfDuplex - Force the phy into 10 Base T Half Duplex mode.
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  *
  * Also sets the MAC so it is syncd up properly
  */
-void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *pAdapter)
+void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* First we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_HALF);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 /**
  * TPAL_SetPhy10FullDuplex - Force the phy into 10 Base T Full Duplex mode.
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  *
  * Also sets the MAC so it is syncd up properly
  */
-void TPAL_SetPhy10FullDuplex(struct et131x_adapter *pAdapter)
+void TPAL_SetPhy10FullDuplex(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* First we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 /**
  * TPAL_SetPhy10Force - Force Base-T FD mode WITHOUT using autonegotiation
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  */
-void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter)
+void TPAL_SetPhy10Force(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* Disable autoneg */
-	ET1310_PhyAutoNeg(pAdapter, false);
+	ET1310_PhyAutoNeg(etdev, false);
 
 	/* Disable all advertisement */
-	ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Force 10 Mbps */
-	ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_10MBPS);
+	ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS);
 
 	/* Force Full duplex */
-	ET1310_PhyDuplexMode(pAdapter, TRUEPHY_DUPLEX_FULL);
+	ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 /**
  * TPAL_SetPhy100HalfDuplex - Force 100 Base T Half Duplex mode.
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  *
  * Also sets the MAC so it is syncd up properly.
  */
-void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *pAdapter)
+void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* first we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_HALF);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_HALF);
 
 	/* Set speed */
-	ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_100MBPS);
+	ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 /**
  * TPAL_SetPhy100FullDuplex - Force 100 Base T Full Duplex mode.
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  *
  * Also sets the MAC so it is syncd up properly
  */
-void TPAL_SetPhy100FullDuplex(struct et131x_adapter *pAdapter)
+void TPAL_SetPhy100FullDuplex(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* First we need to turn off all other advertisement */
-	ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Set our advertise values accordingly */
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 /**
  * TPAL_SetPhy100Force - Force 100 BaseT FD mode WITHOUT using autonegotiation
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  */
-void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter)
+void TPAL_SetPhy100Force(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* Disable autoneg */
-	ET1310_PhyAutoNeg(pAdapter, false);
+	ET1310_PhyAutoNeg(etdev, false);
 
 	/* Disable all advertisement */
-	ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Force 100 Mbps */
-	ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_100MBPS);
+	ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS);
 
 	/* Force Full duplex */
-	ET1310_PhyDuplexMode(pAdapter, TRUEPHY_DUPLEX_FULL);
+	ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 /**
  * TPAL_SetPhy1000FullDuplex - Force 1000 Base T Full Duplex mode
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  *
  * Also sets the MAC so it is syncd up properly.
  */
-void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *pAdapter)
+void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* first we need to turn off all other advertisement */
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* set our advertise values accordingly */
-	ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+	ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
 
 	/* power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 /**
  * TPAL_SetPhyAutoNeg - Set phy to autonegotiation mode.
- * @pAdapter: pointer to the adapter structure
+ * @etdev: pointer to the adapter structure
  */
-void TPAL_SetPhyAutoNeg(struct et131x_adapter *pAdapter)
+void TPAL_SetPhyAutoNeg(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/* Turn on advertisement of all capabilities */
-	ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_BOTH);
+	ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH);
 
-	ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_BOTH);
+	ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_BOTH);
 
-	if (pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST) {
-		ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
-	} else {
-		ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
-	}
+	if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST)
+		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
+	else
+		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Make sure auto-neg is ON (it is disabled in FORCE modes) */
-	ET1310_PhyAutoNeg(pAdapter, true);
+	ET1310_PhyAutoNeg(etdev, true);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	DBG_LEAVE(et131x_dbginfo);
+	ET1310_PhyPowerDown(etdev, 0);
 }
 
 
@@ -906,371 +829,368 @@ static const uint16_t ConfigPhy[25][2] = {
 };
 
 /* condensed version of the phy initialization routine */
-void ET1310_PhyInit(struct et131x_adapter *pAdapter)
+void ET1310_PhyInit(struct et131x_adapter *etdev)
 {
-	uint16_t usData, usIndex;
+	uint16_t data, index;
 
-	if (pAdapter == NULL) {
+	if (etdev == NULL)
 		return;
-	}
 
-	// get the identity (again ?)
-	MiRead(pAdapter, PHY_ID_1, &usData);
-	MiRead(pAdapter, PHY_ID_2, &usData);
+	/* get the identity (again ?) */
+	MiRead(etdev, PHY_ID_1, &data);
+	MiRead(etdev, PHY_ID_2, &data);
 
-	// what does this do/achieve ?
-	MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData);	// should read 0002
-	MiWrite(pAdapter, PHY_MPHY_CONTROL_REG,	0x0006);
+	/* what does this do/achieve ? */
+	MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */
+	MiWrite(etdev, PHY_MPHY_CONTROL_REG,	0x0006);
 
-	// read modem register 0402, should I do something with the return data ?
-	MiWrite(pAdapter, PHY_INDEX_REG, 0x0402);
-	MiRead(pAdapter, PHY_DATA_REG, &usData);
+	/* read modem register 0402, should I do something with the return
+	   data ? */
+	MiWrite(etdev, PHY_INDEX_REG, 0x0402);
+	MiRead(etdev, PHY_DATA_REG, &data);
 
-	// what does this do/achieve ?
-	MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002);
+	/* what does this do/achieve ? */
+	MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002);
 
-	// get the identity (again ?)
-	MiRead(pAdapter, PHY_ID_1, &usData);
-	MiRead(pAdapter, PHY_ID_2, &usData);
+	/* get the identity (again ?) */
+	MiRead(etdev, PHY_ID_1, &data);
+	MiRead(etdev, PHY_ID_2, &data);
 
-	// what does this achieve ?
-	MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData);	// should read 0002
-	MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0006);
+	/* what does this achieve ? */
+	MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */
+	MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006);
 
-	// read modem register 0402, should I do something with the return data?
-	MiWrite(pAdapter, PHY_INDEX_REG, 0x0402);
-	MiRead(pAdapter, PHY_DATA_REG, &usData);
+	/* read modem register 0402, should I do something with
+	   the return data? */
+	MiWrite(etdev, PHY_INDEX_REG, 0x0402);
+	MiRead(etdev, PHY_DATA_REG, &data);
 
-	MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002);
+	MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002);
 
-	// what does this achieve (should return 0x1040)
-	MiRead(pAdapter, PHY_CONTROL, &usData);
-	MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData);	// should read 0002
-	MiWrite(pAdapter, PHY_CONTROL, 0x1840);
+	/* what does this achieve (should return 0x1040) */
+	MiRead(etdev, PHY_CONTROL, &data);
+	MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */
+	MiWrite(etdev, PHY_CONTROL, 0x1840);
 
-	MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0007);
+	MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0007);
 
-	// here the writing of the array starts....
-	usIndex = 0;
-	while (ConfigPhy[usIndex][0] != 0x0000) {
-		// write value
-		MiWrite(pAdapter, PHY_INDEX_REG, ConfigPhy[usIndex][0]);
-		MiWrite(pAdapter, PHY_DATA_REG, ConfigPhy[usIndex][1]);
+	/* here the writing of the array starts.... */
+	index = 0;
+	while (ConfigPhy[index][0] != 0x0000) {
+		/* write value */
+		MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]);
+		MiWrite(etdev, PHY_DATA_REG, ConfigPhy[index][1]);
 
-		// read it back
-		MiWrite(pAdapter, PHY_INDEX_REG, ConfigPhy[usIndex][0]);
-		MiRead(pAdapter, PHY_DATA_REG, &usData);
+		/* read it back */
+		MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]);
+		MiRead(etdev, PHY_DATA_REG, &data);
 
-		// do a check on the value read back ?
-		usIndex++;
+		/* do a check on the value read back ? */
+		index++;
 	}
-	// here the writing of the array ends...
+	/* here the writing of the array ends... */
 
-	MiRead(pAdapter, PHY_CONTROL, &usData);	// 0x1840
-	MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData);	// should read 0007
-	MiWrite(pAdapter, PHY_CONTROL, 0x1040);
-	MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002);
+	MiRead(etdev, PHY_CONTROL, &data);		/* 0x1840 */
+	MiRead(etdev, PHY_MPHY_CONTROL_REG, &data);/* should read 0007 */
+	MiWrite(etdev, PHY_CONTROL, 0x1040);
+	MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002);
 }
 
-void ET1310_PhyReset(struct et131x_adapter *pAdapter)
+void ET1310_PhyReset(struct et131x_adapter *etdev)
 {
-	MiWrite(pAdapter, PHY_CONTROL, 0x8000);
+	MiWrite(etdev, PHY_CONTROL, 0x8000);
 }
 
-void ET1310_PhyPowerDown(struct et131x_adapter *pAdapter, bool down)
+void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down)
 {
-	uint16_t usData;
+	uint16_t data;
 
-	MiRead(pAdapter, PHY_CONTROL, &usData);
+	MiRead(etdev, PHY_CONTROL, &data);
 
 	if (down == false) {
-		// Power UP
-		usData &= ~0x0800;
-		MiWrite(pAdapter, PHY_CONTROL, usData);
+		/* Power UP */
+		data &= ~0x0800;
+		MiWrite(etdev, PHY_CONTROL, data);
 	} else {
-		// Power DOWN
-		usData |= 0x0800;
-		MiWrite(pAdapter, PHY_CONTROL, usData);
+		/* Power DOWN */
+		data |= 0x0800;
+		MiWrite(etdev, PHY_CONTROL, data);
 	}
 }
 
-void ET1310_PhyAutoNeg(struct et131x_adapter *pAdapter, bool enable)
+void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable)
 {
-	uint16_t usData;
+	uint16_t data;
 
-	MiRead(pAdapter, PHY_CONTROL, &usData);
+	MiRead(etdev, PHY_CONTROL, &data);
 
 	if (enable == true) {
-		// Autonegotiation ON
-		usData |= 0x1000;
-		MiWrite(pAdapter, PHY_CONTROL, usData);
+		/* Autonegotiation ON */
+		data |= 0x1000;
+		MiWrite(etdev, PHY_CONTROL, data);
 	} else {
-		// Autonegotiation OFF
-		usData &= ~0x1000;
-		MiWrite(pAdapter, PHY_CONTROL, usData);
+		/* Autonegotiation OFF */
+		data &= ~0x1000;
+		MiWrite(etdev, PHY_CONTROL, data);
 	}
 }
 
-void ET1310_PhyDuplexMode(struct et131x_adapter *pAdapter, uint16_t duplex)
+void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, uint16_t duplex)
 {
-	uint16_t usData;
+	uint16_t data;
 
-	MiRead(pAdapter, PHY_CONTROL, &usData);
+	MiRead(etdev, PHY_CONTROL, &data);
 
 	if (duplex == TRUEPHY_DUPLEX_FULL) {
-		// Set Full Duplex
-		usData |= 0x100;
-		MiWrite(pAdapter, PHY_CONTROL, usData);
+		/* Set Full Duplex */
+		data |= 0x100;
+		MiWrite(etdev, PHY_CONTROL, data);
 	} else {
-		// Set Half Duplex
-		usData &= ~0x100;
-		MiWrite(pAdapter, PHY_CONTROL, usData);
+		/* Set Half Duplex */
+		data &= ~0x100;
+		MiWrite(etdev, PHY_CONTROL, data);
 	}
 }
 
-void ET1310_PhySpeedSelect(struct et131x_adapter *pAdapter, uint16_t speed)
+void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, uint16_t speed)
 {
-	uint16_t usData;
+	uint16_t data;
 
-	// Read the PHY control register
-	MiRead(pAdapter, PHY_CONTROL, &usData);
+	/* Read the PHY control register */
+	MiRead(etdev, PHY_CONTROL, &data);
 
-	// Clear all Speed settings (Bits 6, 13)
-	usData &= ~0x2040;
+	/* Clear all Speed settings (Bits 6, 13) */
+	data &= ~0x2040;
 
-	// Reset the speed bits based on user selection
+	/* Reset the speed bits based on user selection */
 	switch (speed) {
 	case TRUEPHY_SPEED_10MBPS:
-		// Bits already cleared above, do nothing
+		/* Bits already cleared above, do nothing */
 		break;
 
 	case TRUEPHY_SPEED_100MBPS:
-		// 100M == Set bit 13
-		usData |= 0x2000;
+		/* 100M == Set bit 13 */
+		data |= 0x2000;
 		break;
 
 	case TRUEPHY_SPEED_1000MBPS:
 	default:
-		usData |= 0x0040;
+		data |= 0x0040;
 		break;
 	}
 
-	// Write back the new speed
-	MiWrite(pAdapter, PHY_CONTROL, usData);
+	/* Write back the new speed */
+	MiWrite(etdev, PHY_CONTROL, data);
 }
 
-void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *pAdapter,
+void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev,
 				  uint16_t duplex)
 {
-	uint16_t usData;
+	uint16_t data;
 
-	// Read the PHY 1000 Base-T Control Register
-	MiRead(pAdapter, PHY_1000_CONTROL, &usData);
+	/* Read the PHY 1000 Base-T Control Register */
+	MiRead(etdev, PHY_1000_CONTROL, &data);
 
-	// Clear Bits 8,9
-	usData &= ~0x0300;
+	/* Clear Bits 8,9 */
+	data &= ~0x0300;
 
 	switch (duplex) {
 	case TRUEPHY_ADV_DUPLEX_NONE:
-		// Duplex already cleared, do nothing
+		/* Duplex already cleared, do nothing */
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_FULL:
-		// Set Bit 9
-		usData |= 0x0200;
+		/* Set Bit 9 */
+		data |= 0x0200;
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_HALF:
-		// Set Bit 8
-		usData |= 0x0100;
+		/* Set Bit 8 */
+		data |= 0x0100;
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_BOTH:
 	default:
-		usData |= 0x0300;
+		data |= 0x0300;
 		break;
 	}
 
-	// Write back advertisement
-	MiWrite(pAdapter, PHY_1000_CONTROL, usData);
+	/* Write back advertisement */
+	MiWrite(etdev, PHY_1000_CONTROL, data);
 }
 
-void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *pAdapter,
+void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev,
 				 uint16_t duplex)
 {
-	uint16_t usData;
+	uint16_t data;
 
-	// Read the Autonegotiation Register (10/100)
-	MiRead(pAdapter, PHY_AUTO_ADVERTISEMENT, &usData);
+	/* Read the Autonegotiation Register (10/100) */
+	MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data);
 
-	// Clear bits 7,8
-	usData &= ~0x0180;
+	/* Clear bits 7,8 */
+	data &= ~0x0180;
 
 	switch (duplex) {
 	case TRUEPHY_ADV_DUPLEX_NONE:
-		// Duplex already cleared, do nothing
+		/* Duplex already cleared, do nothing */
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_FULL:
-		// Set Bit 8
-		usData |= 0x0100;
+		/* Set Bit 8 */
+		data |= 0x0100;
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_HALF:
-		// Set Bit 7
-		usData |= 0x0080;
+		/* Set Bit 7 */
+		data |= 0x0080;
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_BOTH:
 	default:
-		// Set Bits 7,8
-		usData |= 0x0180;
+		/* Set Bits 7,8 */
+		data |= 0x0180;
 		break;
 	}
 
-	// Write back advertisement
-	MiWrite(pAdapter, PHY_AUTO_ADVERTISEMENT, usData);
+	/* Write back advertisement */
+	MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data);
 }
 
-void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *pAdapter,
+void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev,
 				uint16_t duplex)
 {
-	uint16_t usData;
+	uint16_t data;
 
-	// Read the Autonegotiation Register (10/100)
-	MiRead(pAdapter, PHY_AUTO_ADVERTISEMENT, &usData);
+	/* Read the Autonegotiation Register (10/100) */
+	MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data);
 
-	// Clear bits 5,6
-	usData &= ~0x0060;
+	/* Clear bits 5,6 */
+	data &= ~0x0060;
 
 	switch (duplex) {
 	case TRUEPHY_ADV_DUPLEX_NONE:
-		// Duplex already cleared, do nothing
+		/* Duplex already cleared, do nothing */
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_FULL:
-		// Set Bit 6
-		usData |= 0x0040;
+		/* Set Bit 6 */
+		data |= 0x0040;
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_HALF:
-		// Set Bit 5
-		usData |= 0x0020;
+		/* Set Bit 5 */
+		data |= 0x0020;
 		break;
 
 	case TRUEPHY_ADV_DUPLEX_BOTH:
 	default:
-		// Set Bits 5,6
-		usData |= 0x0060;
+		/* Set Bits 5,6 */
+		data |= 0x0060;
 		break;
 	}
 
-	// Write back advertisement
-	MiWrite(pAdapter, PHY_AUTO_ADVERTISEMENT, usData);
+	/* Write back advertisement */
+	MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data);
 }
 
-void ET1310_PhyLinkStatus(struct et131x_adapter *pAdapter,
-			  uint8_t *ucLinkStatus,
-			  uint32_t *uiAutoNeg,
-			  uint32_t *uiLinkSpeed,
-			  uint32_t *uiDuplexMode,
-			  uint32_t *uiMdiMdix,
-			  uint32_t *uiMasterSlave, uint32_t *uiPolarity)
+void ET1310_PhyLinkStatus(struct et131x_adapter *etdev,
+			  uint8_t *link_status,
+			  uint32_t *autoneg,
+			  uint32_t *linkspeed,
+			  uint32_t *duplex_mode,
+			  uint32_t *mdi_mdix,
+			  uint32_t *masterslave, uint32_t *polarity)
 {
-	uint16_t usMiStatus = 0;
-	uint16_t us1000BaseT = 0;
-	uint16_t usVmiPhyStatus = 0;
-	uint16_t usControl = 0;
-
-	MiRead(pAdapter, PHY_STATUS, &usMiStatus);
-	MiRead(pAdapter, PHY_1000_STATUS, &us1000BaseT);
-	MiRead(pAdapter, PHY_PHY_STATUS, &usVmiPhyStatus);
-	MiRead(pAdapter, PHY_CONTROL, &usControl);
-
-	if (ucLinkStatus) {
-		*ucLinkStatus =
-		    (unsigned char)((usVmiPhyStatus & 0x0040) ? 1 : 0);
+	uint16_t mistatus = 0;
+	uint16_t is1000BaseT = 0;
+	uint16_t vmi_phystatus = 0;
+	uint16_t control = 0;
+
+	MiRead(etdev, PHY_STATUS, &mistatus);
+	MiRead(etdev, PHY_1000_STATUS, &is1000BaseT);
+	MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus);
+	MiRead(etdev, PHY_CONTROL, &control);
+
+	if (link_status) {
+		*link_status =
+		    (unsigned char)((vmi_phystatus & 0x0040) ? 1 : 0);
 	}
 
-	if (uiAutoNeg) {
-		*uiAutoNeg =
-		    (usControl & 0x1000) ? ((usVmiPhyStatus & 0x0020) ?
+	if (autoneg) {
+		*autoneg =
+		    (control & 0x1000) ? ((vmi_phystatus & 0x0020) ?
 					    TRUEPHY_ANEG_COMPLETE :
 					    TRUEPHY_ANEG_NOT_COMPLETE) :
 		    TRUEPHY_ANEG_DISABLED;
 	}
 
-	if (uiLinkSpeed) {
-		*uiLinkSpeed = (usVmiPhyStatus & 0x0300) >> 8;
-	}
+	if (linkspeed)
+		*linkspeed = (vmi_phystatus & 0x0300) >> 8;
 
-	if (uiDuplexMode) {
-		*uiDuplexMode = (usVmiPhyStatus & 0x0080) >> 7;
-	}
+	if (duplex_mode)
+		*duplex_mode = (vmi_phystatus & 0x0080) >> 7;
 
-	if (uiMdiMdix) {
+	if (mdi_mdix)
 		/* NOTE: Need to complete this */
-		*uiMdiMdix = 0;
-	}
+		*mdi_mdix = 0;
 
-	if (uiMasterSlave) {
-		*uiMasterSlave =
-		    (us1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER :
+	if (masterslave) {
+		*masterslave =
+		    (is1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER :
 		    TRUEPHY_CFG_SLAVE;
 	}
 
-	if (uiPolarity) {
-		*uiPolarity =
-		    (usVmiPhyStatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED :
+	if (polarity) {
+		*polarity =
+		    (vmi_phystatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED :
 		    TRUEPHY_POLARITY_NORMAL;
 	}
 }
 
-void ET1310_PhyAndOrReg(struct et131x_adapter *pAdapter,
+void ET1310_PhyAndOrReg(struct et131x_adapter *etdev,
 			uint16_t regnum, uint16_t andMask, uint16_t orMask)
 {
 	uint16_t reg;
 
-	// Read the requested register
-	MiRead(pAdapter, regnum, &reg);
+	/* Read the requested register */
+	MiRead(etdev, regnum, &reg);
 
-	// Apply the AND mask
+	/* Apply the AND mask */
 	reg &= andMask;
 
-	// Apply the OR mask
+	/* Apply the OR mask */
 	reg |= orMask;
 
-	// Write the value back to the register
-	MiWrite(pAdapter, regnum, reg);
+	/* Write the value back to the register */
+	MiWrite(etdev, regnum, reg);
 }
 
-void ET1310_PhyAccessMiBit(struct et131x_adapter *pAdapter, uint16_t action,
+void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, uint16_t action,
 			   uint16_t regnum, uint16_t bitnum, uint8_t *value)
 {
 	uint16_t reg;
 	uint16_t mask = 0;
 
-	// Create a mask to isolate the requested bit
+	/* Create a mask to isolate the requested bit */
 	mask = 0x0001 << bitnum;
 
-	// Read the requested register
-	MiRead(pAdapter, regnum, &reg);
+	/* Read the requested register */
+	MiRead(etdev, regnum, &reg);
 
 	switch (action) {
 	case TRUEPHY_BIT_READ:
-		if (value != NULL) {
+		if (value != NULL)
 			*value = (reg & mask) >> bitnum;
-		}
 		break;
 
 	case TRUEPHY_BIT_SET:
 		reg |= mask;
-		MiWrite(pAdapter, regnum, reg);
+		MiWrite(etdev, regnum, reg);
 		break;
 
 	case TRUEPHY_BIT_CLEAR:
 		reg &= ~mask;
-		MiWrite(pAdapter, regnum, reg);
+		MiWrite(etdev, regnum, reg);
 		break;
 
 	default:
diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h
index d624cbb..080656c 100644
--- a/drivers/staging/et131x/et1310_phy.h
+++ b/drivers/staging/et131x/et1310_phy.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -63,9 +63,6 @@
 
 #define TRUEPHY_SUCCESS 0
 #define TRUEPHY_FAILURE 1
-typedef void *TRUEPHY_HANDLE;
-typedef void *TRUEPHY_PLATFORM_HANDLE;
-typedef void *TRUEPHY_OSAL_HANDLE;
 
 /* MI Register Addresses */
 #define MI_CONTROL_REG                      0
@@ -105,31 +102,31 @@ typedef void *TRUEPHY_OSAL_HANDLE;
 
 /* PHY Register Mapping(MI) Management Interface Regs */
 typedef struct _MI_REGS_t {
-	u8 bmcr;		// Basic mode control reg(Reg 0x00)
-	u8 bmsr;		// Basic mode status reg(Reg 0x01)
-	u8 idr1;		// Phy identifier reg 1(Reg 0x02)
-	u8 idr2;		// Phy identifier reg 2(Reg 0x03)
-	u8 anar;		// Auto-Negotiation advertisement(Reg 0x04)
-	u8 anlpar;		// Auto-Negotiation link Partner Ability(Reg 0x05)
-	u8 aner;		// Auto-Negotiation expansion reg(Reg 0x06)
-	u8 annptr;		// Auto-Negotiation next page transmit reg(Reg 0x07)
-	u8 lpnpr;		// link partner next page reg(Reg 0x08)
-	u8 gcr;		// Gigabit basic mode control reg(Reg 0x09)
-	u8 gsr;		// Gigabit basic mode status reg(Reg 0x0A)
-	u8 mi_res1[4];	// Future use by MI working group(Reg 0x0B - 0x0E)
-	u8 esr;		// Extended status reg(Reg 0x0F)
-	u8 mi_res2[3];	// Future use by MI working group(Reg 0x10 - 0x12)
-	u8 loop_ctl;	// Loopback Control Reg(Reg 0x13)
-	u8 mi_res3;	// Future use by MI working group(Reg 0x14)
-	u8 mcr;		// MI Control Reg(Reg 0x15)
-	u8 pcr;		// Configuration Reg(Reg 0x16)
-	u8 phy_ctl;	// PHY Control Reg(Reg 0x17)
-	u8 imr;		// Interrupt Mask Reg(Reg 0x18)
-	u8 isr;		// Interrupt Status Reg(Reg 0x19)
-	u8 psr;		// PHY Status Reg(Reg 0x1A)
-	u8 lcr1;		// LED Control 1 Reg(Reg 0x1B)
-	u8 lcr2;		// LED Control 2 Reg(Reg 0x1C)
-	u8 mi_res4[3];	// Future use by MI working group(Reg 0x1D - 0x1F)
+	u8 bmcr;	/* Basic mode control reg(Reg 0x00) */
+	u8 bmsr;	/* Basic mode status reg(Reg 0x01) */
+	u8 idr1;	/* Phy identifier reg 1(Reg 0x02) */
+	u8 idr2;	/* Phy identifier reg 2(Reg 0x03) */
+	u8 anar;	/* Auto-Negotiation advertisement(Reg 0x04) */
+	u8 anlpar;	/* Auto-Negotiation link Partner Ability(Reg 0x05) */
+	u8 aner;	/* Auto-Negotiation expansion reg(Reg 0x06) */
+	u8 annptr;	/* Auto-Negotiation next page transmit reg(Reg 0x07) */
+	u8 lpnpr;	/* link partner next page reg(Reg 0x08) */
+	u8 gcr;		/* Gigabit basic mode control reg(Reg 0x09) */
+	u8 gsr;		/* Gigabit basic mode status reg(Reg 0x0A) */
+	u8 mi_res1[4];	/* Future use by MI working group(Reg 0x0B - 0x0E) */
+	u8 esr;		/* Extended status reg(Reg 0x0F) */
+	u8 mi_res2[3];	/* Future use by MI working group(Reg 0x10 - 0x12) */
+	u8 loop_ctl;	/* Loopback Control Reg(Reg 0x13) */
+	u8 mi_res3;	/* Future use by MI working group(Reg 0x14) */
+	u8 mcr;		/* MI Control Reg(Reg 0x15) */
+	u8 pcr;		/* Configuration Reg(Reg 0x16) */
+	u8 phy_ctl;	/* PHY Control Reg(Reg 0x17) */
+	u8 imr;		/* Interrupt Mask Reg(Reg 0x18) */
+	u8 isr;		/* Interrupt Status Reg(Reg 0x19) */
+	u8 psr;		/* PHY Status Reg(Reg 0x1A) */
+	u8 lcr1;		/* LED Control 1 Reg(Reg 0x1B) */
+	u8 lcr2;		/* LED Control 2 Reg(Reg 0x1C) */
+	u8 mi_res4[3];	/* Future use by MI working group(Reg 0x1D - 0x1F) */
 } MI_REGS_t, *PMI_REGS_t;
 
 /* MI Register 0: Basic mode control register */
@@ -137,29 +134,29 @@ typedef union _MI_BMCR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 reset:1;		// bit 15
-		u16 loopback:1;		// bit 14
-		u16 speed_sel:1;		// bit 13
-		u16 enable_autoneg:1;	// bit 12
-		u16 power_down:1;		// bit 11
-		u16 isolate:1;		// bit 10
-		u16 restart_autoneg:1;	// bit 9
-		u16 duplex_mode:1;		// bit 8
-		u16 col_test:1;		// bit 7
-		u16 speed_1000_sel:1;	// bit 6
-		u16 res1:6;		// bits 0-5
+		u16 reset:1;		/* bit 15 */
+		u16 loopback:1;		/* bit 14 */
+		u16 speed_sel:1;		/* bit 13 */
+		u16 enable_autoneg:1;	/* bit 12 */
+		u16 power_down:1;		/* bit 11 */
+		u16 isolate:1;		/* bit 10 */
+		u16 restart_autoneg:1;	/* bit 9 */
+		u16 duplex_mode:1;		/* bit 8 */
+		u16 col_test:1;		/* bit 7 */
+		u16 speed_1000_sel:1;	/* bit 6 */
+		u16 res1:6;		/* bits 0-5 */
 #else
-		u16 res1:6;		// bits 0-5
-		u16 speed_1000_sel:1;	// bit 6
-		u16 col_test:1;		// bit 7
-		u16 duplex_mode:1;		// bit 8
-		u16 restart_autoneg:1;	// bit 9
-		u16 isolate:1;		// bit 10
-		u16 power_down:1;		// bit 11
-		u16 enable_autoneg:1;	// bit 12
-		u16 speed_sel:1;		// bit 13
-		u16 loopback:1;		// bit 14
-		u16 reset:1;		// bit 15
+		u16 res1:6;		/* bits 0-5 */
+		u16 speed_1000_sel:1;	/* bit 6 */
+		u16 col_test:1;		/* bit 7 */
+		u16 duplex_mode:1;		/* bit 8 */
+		u16 restart_autoneg:1;	/* bit 9 */
+		u16 isolate:1;		/* bit 10 */
+		u16 power_down:1;		/* bit 11 */
+		u16 enable_autoneg:1;	/* bit 12 */
+		u16 speed_sel:1;		/* bit 13 */
+		u16 loopback:1;		/* bit 14 */
+		u16 reset:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_BMCR_t, *PMI_BMCR_t;
@@ -169,39 +166,39 @@ typedef union _MI_BMSR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 link_100T4:1;		// bit 15
-		u16 link_100fdx:1;		// bit 14
-		u16 link_100hdx:1;		// bit 13
-		u16 link_10fdx:1;		// bit 12
-		u16 link_10hdx:1;		// bit 11
-		u16 link_100T2fdx:1;	// bit 10
-		u16 link_100T2hdx:1;	// bit 9
-		u16 extend_status:1;	// bit 8
-		u16 res1:1;		// bit 7
-		u16 preamble_supress:1;	// bit 6
-		u16 auto_neg_complete:1;	// bit 5
-		u16 remote_fault:1;	// bit 4
-		u16 auto_neg_able:1;	// bit 3
-		u16 link_status:1;		// bit 2
-		u16 jabber_detect:1;	// bit 1
-		u16 ext_cap:1;		// bit 0
+		u16 link_100T4:1;		/* bit 15 */
+		u16 link_100fdx:1;		/* bit 14 */
+		u16 link_100hdx:1;		/* bit 13 */
+		u16 link_10fdx:1;		/* bit 12 */
+		u16 link_10hdx:1;		/* bit 11 */
+		u16 link_100T2fdx:1;	/* bit 10 */
+		u16 link_100T2hdx:1;	/* bit 9 */
+		u16 extend_status:1;	/* bit 8 */
+		u16 res1:1;		/* bit 7 */
+		u16 preamble_supress:1;	/* bit 6 */
+		u16 auto_neg_complete:1;	/* bit 5 */
+		u16 remote_fault:1;	/* bit 4 */
+		u16 auto_neg_able:1;	/* bit 3 */
+		u16 link_status:1;		/* bit 2 */
+		u16 jabber_detect:1;	/* bit 1 */
+		u16 ext_cap:1;		/* bit 0 */
 #else
-		u16 ext_cap:1;		// bit 0
-		u16 jabber_detect:1;	// bit 1
-		u16 link_status:1;		// bit 2
-		u16 auto_neg_able:1;	// bit 3
-		u16 remote_fault:1;	// bit 4
-		u16 auto_neg_complete:1;	// bit 5
-		u16 preamble_supress:1;	// bit 6
-		u16 res1:1;		// bit 7
-		u16 extend_status:1;	// bit 8
-		u16 link_100T2hdx:1;	// bit 9
-		u16 link_100T2fdx:1;	// bit 10
-		u16 link_10hdx:1;		// bit 11
-		u16 link_10fdx:1;		// bit 12
-		u16 link_100hdx:1;		// bit 13
-		u16 link_100fdx:1;		// bit 14
-		u16 link_100T4:1;		// bit 15
+		u16 ext_cap:1;		/* bit 0 */
+		u16 jabber_detect:1;	/* bit 1 */
+		u16 link_status:1;		/* bit 2 */
+		u16 auto_neg_able:1;	/* bit 3 */
+		u16 remote_fault:1;	/* bit 4 */
+		u16 auto_neg_complete:1;	/* bit 5 */
+		u16 preamble_supress:1;	/* bit 6 */
+		u16 res1:1;		/* bit 7 */
+		u16 extend_status:1;	/* bit 8 */
+		u16 link_100T2hdx:1;	/* bit 9 */
+		u16 link_100T2fdx:1;	/* bit 10 */
+		u16 link_10hdx:1;		/* bit 11 */
+		u16 link_10fdx:1;		/* bit 12 */
+		u16 link_100hdx:1;		/* bit 13 */
+		u16 link_100fdx:1;		/* bit 14 */
+		u16 link_100T4:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_BMSR_t, *PMI_BMSR_t;
@@ -210,7 +207,7 @@ typedef union _MI_BMSR_t {
 typedef union _MI_IDR1_t {
 	u16 value;
 	struct {
-		u16 ieee_address:16;	// 0x0282 default(bits 0-15)
+		u16 ieee_address:16;	/* 0x0282 default(bits 0-15) */
 	} bits;
 } MI_IDR1_t, *PMI_IDR1_t;
 
@@ -219,13 +216,13 @@ typedef union _MI_IDR2_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 ieee_address:6;	// 111100 default(bits 10-15)
-		u16 model_no:6;		// 000001 default(bits 4-9)
-		u16 rev_no:4;		// 0010   default(bits 0-3)
+		u16 ieee_address:6;	/* 111100 default(bits 10-15) */
+		u16 model_no:6;		/* 000001 default(bits 4-9) */
+		u16 rev_no:4;		/* 0010   default(bits 0-3) */
 #else
-		u16 rev_no:4;		// 0010   default(bits 0-3)
-		u16 model_no:6;		// 000001 default(bits 4-9)
-		u16 ieee_address:6;	// 111100 default(bits 10-15)
+		u16 rev_no:4;		/* 0010   default(bits 0-3) */
+		u16 model_no:6;		/* 000001 default(bits 4-9) */
+		u16 ieee_address:6;	/* 111100 default(bits 10-15) */
 #endif
 	} bits;
 } MI_IDR2_t, *PMI_IDR2_t;
@@ -235,31 +232,31 @@ typedef union _MI_ANAR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 np_indication:1;	// bit 15
-		u16 res2:1;		// bit 14
-		u16 remote_fault:1;	// bit 13
-		u16 res1:1;		// bit 12
-		u16 cap_asmpause:1;	// bit 11
-		u16 cap_pause:1;		// bit 10
-		u16 cap_100T4:1;		// bit 9
-		u16 cap_100fdx:1;		// bit 8
-		u16 cap_100hdx:1;		// bit 7
-		u16 cap_10fdx:1;		// bit 6
-		u16 cap_10hdx:1;		// bit 5
-		u16 selector:5;		// bits 0-4
+		u16 np_indication:1;	/* bit 15 */
+		u16 res2:1;		/* bit 14 */
+		u16 remote_fault:1;	/* bit 13 */
+		u16 res1:1;		/* bit 12 */
+		u16 cap_asmpause:1;	/* bit 11 */
+		u16 cap_pause:1;		/* bit 10 */
+		u16 cap_100T4:1;		/* bit 9 */
+		u16 cap_100fdx:1;		/* bit 8 */
+		u16 cap_100hdx:1;		/* bit 7 */
+		u16 cap_10fdx:1;		/* bit 6 */
+		u16 cap_10hdx:1;		/* bit 5 */
+		u16 selector:5;		/* bits 0-4 */
 #else
-		u16 selector:5;		// bits 0-4
-		u16 cap_10hdx:1;		// bit 5
-		u16 cap_10fdx:1;		// bit 6
-		u16 cap_100hdx:1;		// bit 7
-		u16 cap_100fdx:1;		// bit 8
-		u16 cap_100T4:1;		// bit 9
-		u16 cap_pause:1;		// bit 10
-		u16 cap_asmpause:1;	// bit 11
-		u16 res1:1;		// bit 12
-		u16 remote_fault:1;	// bit 13
-		u16 res2:1;		// bit 14
-		u16 np_indication:1;	// bit 15
+		u16 selector:5;		/* bits 0-4 */
+		u16 cap_10hdx:1;		/* bit 5 */
+		u16 cap_10fdx:1;		/* bit 6 */
+		u16 cap_100hdx:1;		/* bit 7 */
+		u16 cap_100fdx:1;		/* bit 8 */
+		u16 cap_100T4:1;		/* bit 9 */
+		u16 cap_pause:1;		/* bit 10 */
+		u16 cap_asmpause:1;	/* bit 11 */
+		u16 res1:1;		/* bit 12 */
+		u16 remote_fault:1;	/* bit 13 */
+		u16 res2:1;		/* bit 14 */
+		u16 np_indication:1;	/* bit 15 */
 #endif
 	} bits;
 } MI_ANAR_t, *PMI_ANAR_t;
@@ -269,31 +266,31 @@ typedef struct _MI_ANLPAR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 np_indication:1;	// bit 15
-		u16 acknowledge:1;		// bit 14
-		u16 remote_fault:1;	// bit 13
-		u16 res1:1;		// bit 12
-		u16 cap_asmpause:1;	// bit 11
-		u16 cap_pause:1;		// bit 10
-		u16 cap_100T4:1;		// bit 9
-		u16 cap_100fdx:1;		// bit 8
-		u16 cap_100hdx:1;		// bit 7
-		u16 cap_10fdx:1;		// bit 6
-		u16 cap_10hdx:1;		// bit 5
-		u16 selector:5;		// bits 0-4
+		u16 np_indication:1;	/* bit 15 */
+		u16 acknowledge:1;		/* bit 14 */
+		u16 remote_fault:1;	/* bit 13 */
+		u16 res1:1;		/* bit 12 */
+		u16 cap_asmpause:1;	/* bit 11 */
+		u16 cap_pause:1;		/* bit 10 */
+		u16 cap_100T4:1;		/* bit 9 */
+		u16 cap_100fdx:1;		/* bit 8 */
+		u16 cap_100hdx:1;		/* bit 7 */
+		u16 cap_10fdx:1;		/* bit 6 */
+		u16 cap_10hdx:1;		/* bit 5 */
+		u16 selector:5;		/* bits 0-4 */
 #else
-		u16 selector:5;		// bits 0-4
-		u16 cap_10hdx:1;		// bit 5
-		u16 cap_10fdx:1;		// bit 6
-		u16 cap_100hdx:1;		// bit 7
-		u16 cap_100fdx:1;		// bit 8
-		u16 cap_100T4:1;		// bit 9
-		u16 cap_pause:1;		// bit 10
-		u16 cap_asmpause:1;	// bit 11
-		u16 res1:1;		// bit 12
-		u16 remote_fault:1;	// bit 13
-		u16 acknowledge:1;		// bit 14
-		u16 np_indication:1;	// bit 15
+		u16 selector:5;		/* bits 0-4 */
+		u16 cap_10hdx:1;		/* bit 5 */
+		u16 cap_10fdx:1;		/* bit 6 */
+		u16 cap_100hdx:1;		/* bit 7 */
+		u16 cap_100fdx:1;		/* bit 8 */
+		u16 cap_100T4:1;		/* bit 9 */
+		u16 cap_pause:1;		/* bit 10 */
+		u16 cap_asmpause:1;	/* bit 11 */
+		u16 res1:1;		/* bit 12 */
+		u16 remote_fault:1;	/* bit 13 */
+		u16 acknowledge:1;		/* bit 14 */
+		u16 np_indication:1;	/* bit 15 */
 #endif
 	} bits;
 } MI_ANLPAR_t, *PMI_ANLPAR_t;
@@ -303,19 +300,19 @@ typedef union _MI_ANER_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res:11;	// bits 5-15
-		u16 pdf:1;		// bit 4
-		u16 lp_np_able:1;	// bit 3
-		u16 np_able:1;	// bit 2
-		u16 page_rx:1;	// bit 1
-		u16 lp_an_able:1;	// bit 0
+		u16 res:11;	/* bits 5-15 */
+		u16 pdf:1;		/* bit 4 */
+		u16 lp_np_able:1;	/* bit 3 */
+		u16 np_able:1;	/* bit 2 */
+		u16 page_rx:1;	/* bit 1 */
+		u16 lp_an_able:1;	/* bit 0 */
 #else
-		u16 lp_an_able:1;	// bit 0
-		u16 page_rx:1;	// bit 1
-		u16 np_able:1;	// bit 2
-		u16 lp_np_able:1;	// bit 3
-		u16 pdf:1;		// bit 4
-		u16 res:11;	// bits 5-15
+		u16 lp_an_able:1;	/* bit 0 */
+		u16 page_rx:1;	/* bit 1 */
+		u16 np_able:1;	/* bit 2 */
+		u16 lp_np_able:1;	/* bit 3 */
+		u16 pdf:1;		/* bit 4 */
+		u16 res:11;	/* bits 5-15 */
 #endif
 	} bits;
 } MI_ANER_t, *PMI_ANER_t;
@@ -325,19 +322,19 @@ typedef union _MI_ANNPTR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 np:1;		// bit 15
-		u16 res1:1;	// bit 14
-		u16 msg_page:1;	// bit 13
-		u16 ack2:1;	// bit 12
-		u16 toggle:1;	// bit 11
-		u16 msg:11;	// bits 0-10
+		u16 np:1;		/* bit 15 */
+		u16 res1:1;	/* bit 14 */
+		u16 msg_page:1;	/* bit 13 */
+		u16 ack2:1;	/* bit 12 */
+		u16 toggle:1;	/* bit 11 */
+		u16 msg:11;	/* bits 0-10 */
 #else
-		u16 msg:11;	// bits 0-10
-		u16 toggle:1;	// bit 11
-		u16 ack2:1;	// bit 12
-		u16 msg_page:1;	// bit 13
-		u16 res1:1;	// bit 14
-		u16 np:1;		// bit 15
+		u16 msg:11;	/* bits 0-10 */
+		u16 toggle:1;	/* bit 11 */
+		u16 ack2:1;	/* bit 12 */
+		u16 msg_page:1;	/* bit 13 */
+		u16 res1:1;	/* bit 14 */
+		u16 np:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_ANNPTR_t, *PMI_ANNPTR_t;
@@ -347,19 +344,19 @@ typedef union _MI_LPNPR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 np:1;		// bit 15
-		u16 ack:1;		// bit 14
-		u16 msg_page:1;	// bit 13
-		u16 ack2:1;	// bit 12
-		u16 toggle:1;	// bit 11
-		u16 msg:11;	// bits 0-10
+		u16 np:1;		/* bit 15 */
+		u16 ack:1;		/* bit 14 */
+		u16 msg_page:1;	/* bit 13 */
+		u16 ack2:1;	/* bit 12 */
+		u16 toggle:1;	/* bit 11 */
+		u16 msg:11;	/* bits 0-10 */
 #else
-		u16 msg:11;	// bits 0-10
-		u16 toggle:1;	// bit 11
-		u16 ack2:1;	// bit 12
-		u16 msg_page:1;	// bit 13
-		u16 ack:1;		// bit 14
-		u16 np:1;		// bit 15
+		u16 msg:11;	/* bits 0-10 */
+		u16 toggle:1;	/* bit 11 */
+		u16 ack2:1;	/* bit 12 */
+		u16 msg_page:1;	/* bit 13 */
+		u16 ack:1;		/* bit 14 */
+		u16 np:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_LPNPR_t, *PMI_LPNPR_t;
@@ -369,21 +366,21 @@ typedef union _MI_GCR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 test_mode:3;		// bits 13-15
-		u16 ms_config_en:1;	// bit 12
-		u16 ms_value:1;		// bit 11
-		u16 port_type:1;		// bit 10
-		u16 link_1000fdx:1;	// bit 9
-		u16 link_1000hdx:1;	// bit 8
-		u16 res:8;			// bit 0-7
+		u16 test_mode:3;		/* bits 13-15 */
+		u16 ms_config_en:1;	/* bit 12 */
+		u16 ms_value:1;		/* bit 11 */
+		u16 port_type:1;		/* bit 10 */
+		u16 link_1000fdx:1;	/* bit 9 */
+		u16 link_1000hdx:1;	/* bit 8 */
+		u16 res:8;			/* bit 0-7 */
 #else
-		u16 res:8;			// bit 0-7
-		u16 link_1000hdx:1;	// bit 8
-		u16 link_1000fdx:1;	// bit 9
-		u16 port_type:1;		// bit 10
-		u16 ms_value:1;		// bit 11
-		u16 ms_config_en:1;	// bit 12
-		u16 test_mode:3;		// bits 13-15
+		u16 res:8;			/* bit 0-7 */
+		u16 link_1000hdx:1;	/* bit 8 */
+		u16 link_1000fdx:1;	/* bit 9 */
+		u16 port_type:1;		/* bit 10 */
+		u16 ms_value:1;		/* bit 11 */
+		u16 ms_config_en:1;	/* bit 12 */
+		u16 test_mode:3;		/* bits 13-15 */
 #endif
 	} bits;
 } MI_GCR_t, *PMI_GCR_t;
@@ -393,23 +390,23 @@ typedef union _MI_GSR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 ms_config_fault:1;	// bit 15
-		u16 ms_resolve:1;		// bit 14
-		u16 local_rx_status:1;	// bit 13
-		u16 remote_rx_status:1;	// bit 12
-		u16 link_1000fdx:1;	// bit 11
-		u16 link_1000hdx:1;	// bit 10
-		u16 res:2;			// bits 8-9
-		u16 idle_err_cnt:8;	// bits 0-7
+		u16 ms_config_fault:1;	/* bit 15 */
+		u16 ms_resolve:1;		/* bit 14 */
+		u16 local_rx_status:1;	/* bit 13 */
+		u16 remote_rx_status:1;	/* bit 12 */
+		u16 link_1000fdx:1;	/* bit 11 */
+		u16 link_1000hdx:1;	/* bit 10 */
+		u16 res:2;			/* bits 8-9 */
+		u16 idle_err_cnt:8;	/* bits 0-7 */
 #else
-		u16 idle_err_cnt:8;	// bits 0-7
-		u16 res:2;			// bits 8-9
-		u16 link_1000hdx:1;	// bit 10
-		u16 link_1000fdx:1;	// bit 11
-		u16 remote_rx_status:1;	// bit 12
-		u16 local_rx_status:1;	// bit 13
-		u16 ms_resolve:1;		// bit 14
-		u16 ms_config_fault:1;	// bit 15
+		u16 idle_err_cnt:8;	/* bits 0-7 */
+		u16 res:2;			/* bits 8-9 */
+		u16 link_1000hdx:1;	/* bit 10 */
+		u16 link_1000fdx:1;	/* bit 11 */
+		u16 remote_rx_status:1;	/* bit 12 */
+		u16 local_rx_status:1;	/* bit 13 */
+		u16 ms_resolve:1;		/* bit 14 */
+		u16 ms_config_fault:1;	/* bit 15 */
 #endif
 	} bits;
 } MI_GSR_t, *PMI_GSR_t;
@@ -419,39 +416,39 @@ typedef union _MI_RES_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res15:1;	// bit 15
-		u16 res14:1;	// bit 14
-		u16 res13:1;	// bit 13
-		u16 res12:1;	// bit 12
-		u16 res11:1;	// bit 11
-		u16 res10:1;	// bit 10
-		u16 res9:1;	// bit 9
-		u16 res8:1;	// bit 8
-		u16 res7:1;	// bit 7
-		u16 res6:1;	// bit 6
-		u16 res5:1;	// bit 5
-		u16 res4:1;	// bit 4
-		u16 res3:1;	// bit 3
-		u16 res2:1;	// bit 2
-		u16 res1:1;	// bit 1
-		u16 res0:1;	// bit 0
+		u16 res15:1;	/* bit 15 */
+		u16 res14:1;	/* bit 14 */
+		u16 res13:1;	/* bit 13 */
+		u16 res12:1;	/* bit 12 */
+		u16 res11:1;	/* bit 11 */
+		u16 res10:1;	/* bit 10 */
+		u16 res9:1;	/* bit 9 */
+		u16 res8:1;	/* bit 8 */
+		u16 res7:1;	/* bit 7 */
+		u16 res6:1;	/* bit 6 */
+		u16 res5:1;	/* bit 5 */
+		u16 res4:1;	/* bit 4 */
+		u16 res3:1;	/* bit 3 */
+		u16 res2:1;	/* bit 2 */
+		u16 res1:1;	/* bit 1 */
+		u16 res0:1;	/* bit 0 */
 #else
-		u16 res0:1;	// bit 0
-		u16 res1:1;	// bit 1
-		u16 res2:1;	// bit 2
-		u16 res3:1;	// bit 3
-		u16 res4:1;	// bit 4
-		u16 res5:1;	// bit 5
-		u16 res6:1;	// bit 6
-		u16 res7:1;	// bit 7
-		u16 res8:1;	// bit 8
-		u16 res9:1;	// bit 9
-		u16 res10:1;	// bit 10
-		u16 res11:1;	// bit 11
-		u16 res12:1;	// bit 12
-		u16 res13:1;	// bit 13
-		u16 res14:1;	// bit 14
-		u16 res15:1;	// bit 15
+		u16 res0:1;	/* bit 0 */
+		u16 res1:1;	/* bit 1 */
+		u16 res2:1;	/* bit 2 */
+		u16 res3:1;	/* bit 3 */
+		u16 res4:1;	/* bit 4 */
+		u16 res5:1;	/* bit 5 */
+		u16 res6:1;	/* bit 6 */
+		u16 res7:1;	/* bit 7 */
+		u16 res8:1;	/* bit 8 */
+		u16 res9:1;	/* bit 9 */
+		u16 res10:1;	/* bit 10 */
+		u16 res11:1;	/* bit 11 */
+		u16 res12:1;	/* bit 12 */
+		u16 res13:1;	/* bit 13 */
+		u16 res14:1;	/* bit 14 */
+		u16 res15:1;	/* bit 15 */
 #endif
 	} bits;
 } MI_RES_t, *PMI_RES_t;
@@ -461,17 +458,17 @@ typedef union _MI_ESR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 link_1000Xfdx:1;	// bit 15
-		u16 link_1000Xhdx:1;	// bit 14
-		u16 link_1000fdx:1;	// bit 13
-		u16 link_1000hdx:1;	// bit 12
-		u16 res:12;		// bit 0-11
+		u16 link_1000Xfdx:1;	/* bit 15 */
+		u16 link_1000Xhdx:1;	/* bit 14 */
+		u16 link_1000fdx:1;	/* bit 13 */
+		u16 link_1000hdx:1;	/* bit 12 */
+		u16 res:12;		/* bit 0-11 */
 #else
-		u16 res:12;		// bit 0-11
-		u16 link_1000hdx:1;	// bit 12
-		u16 link_1000fdx:1;	// bit 13
-		u16 link_1000Xhdx:1;	// bit 14
-		u16 link_1000Xfdx:1;	// bit 15
+		u16 res:12;		/* bit 0-11 */
+		u16 link_1000hdx:1;	/* bit 12 */
+		u16 link_1000fdx:1;	/* bit 13 */
+		u16 link_1000Xhdx:1;	/* bit 14 */
+		u16 link_1000Xfdx:1;	/* bit 15 */
 #endif
 	} bits;
 } MI_ESR_t, *PMI_ESR_t;
@@ -483,21 +480,21 @@ typedef union _MI_LCR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 mii_en:1;		// bit 15
-		u16 pcs_en:1;		// bit 14
-		u16 pmd_en:1;		// bit 13
-		u16 all_digital_en:1;	// bit 12
-		u16 replica_en:1;		// bit 11
-		u16 line_driver_en:1;	// bit 10
-		u16 res:10;		// bit 0-9
+		u16 mii_en:1;		/* bit 15 */
+		u16 pcs_en:1;		/* bit 14 */
+		u16 pmd_en:1;		/* bit 13 */
+		u16 all_digital_en:1;	/* bit 12 */
+		u16 replica_en:1;		/* bit 11 */
+		u16 line_driver_en:1;	/* bit 10 */
+		u16 res:10;		/* bit 0-9 */
 #else
-		u16 res:10;		// bit 0-9
-		u16 line_driver_en:1;	// bit 10
-		u16 replica_en:1;		// bit 11
-		u16 all_digital_en:1;	// bit 12
-		u16 pmd_en:1;		// bit 13
-		u16 pcs_en:1;		// bit 14
-		u16 mii_en:1;		// bit 15
+		u16 res:10;		/* bit 0-9 */
+		u16 line_driver_en:1;	/* bit 10 */
+		u16 replica_en:1;		/* bit 11 */
+		u16 all_digital_en:1;	/* bit 12 */
+		u16 pmd_en:1;		/* bit 13 */
+		u16 pcs_en:1;		/* bit 14 */
+		u16 mii_en:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_LCR_t, *PMI_LCR_t;
@@ -509,19 +506,19 @@ typedef union _MI_MICR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res1:5;		// bits 11-15
-		u16 mi_error_count:7;	// bits 4-10
-		u16 res2:1;		// bit 3
-		u16 ignore_10g_fr:1;	// bit 2
-		u16 res3:1;		// bit 1
-		u16 preamble_supress_en:1;	// bit 0
+		u16 res1:5;		/* bits 11-15 */
+		u16 mi_error_count:7;	/* bits 4-10 */
+		u16 res2:1;		/* bit 3 */
+		u16 ignore_10g_fr:1;	/* bit 2 */
+		u16 res3:1;		/* bit 1 */
+		u16 preamble_supress_en:1;	/* bit 0 */
 #else
-		u16 preamble_supress_en:1;	// bit 0
-		u16 res3:1;		// bit 1
-		u16 ignore_10g_fr:1;	// bit 2
-		u16 res2:1;		// bit 3
-		u16 mi_error_count:7;	// bits 4-10
-		u16 res1:5;		// bits 11-15
+		u16 preamble_supress_en:1;	/* bit 0 */
+		u16 res3:1;		/* bit 1 */
+		u16 ignore_10g_fr:1;	/* bit 2 */
+		u16 res2:1;		/* bit 3 */
+		u16 mi_error_count:7;	/* bits 4-10 */
+		u16 res1:5;		/* bits 11-15 */
 #endif
 	} bits;
 } MI_MICR_t, *PMI_MICR_t;
@@ -531,31 +528,31 @@ typedef union _MI_PHY_CONFIG_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 crs_tx_en:1;		// bit 15
-		u16 res1:1;		// bit 14
-		u16 tx_fifo_depth:2;	// bits 12-13
-		u16 speed_downshift:2;	// bits 10-11
-		u16 pbi_detect:1;		// bit 9
-		u16 tbi_rate:1;		// bit 8
-		u16 alternate_np:1;	// bit 7
-		u16 group_mdio_en:1;	// bit 6
-		u16 tx_clock_en:1;		// bit 5
-		u16 sys_clock_en:1;	// bit 4
-		u16 res2:1;		// bit 3
-		u16 mac_if_mode:3;		// bits 0-2
+		u16 crs_tx_en:1;		/* bit 15 */
+		u16 res1:1;		/* bit 14 */
+		u16 tx_fifo_depth:2;	/* bits 12-13 */
+		u16 speed_downshift:2;	/* bits 10-11 */
+		u16 pbi_detect:1;		/* bit 9 */
+		u16 tbi_rate:1;		/* bit 8 */
+		u16 alternate_np:1;	/* bit 7 */
+		u16 group_mdio_en:1;	/* bit 6 */
+		u16 tx_clock_en:1;		/* bit 5 */
+		u16 sys_clock_en:1;	/* bit 4 */
+		u16 res2:1;		/* bit 3 */
+		u16 mac_if_mode:3;		/* bits 0-2 */
 #else
-		u16 mac_if_mode:3;		// bits 0-2
-		u16 res2:1;		// bit 3
-		u16 sys_clock_en:1;	// bit 4
-		u16 tx_clock_en:1;		// bit 5
-		u16 group_mdio_en:1;	// bit 6
-		u16 alternate_np:1;	// bit 7
-		u16 tbi_rate:1;		// bit 8
-		u16 pbi_detect:1;		// bit 9
-		u16 speed_downshift:2;	// bits 10-11
-		u16 tx_fifo_depth:2;	// bits 12-13
-		u16 res1:1;		// bit 14
-		u16 crs_tx_en:1;		// bit 15
+		u16 mac_if_mode:3;		/* bits 0-2 */
+		u16 res2:1;		/* bit 3 */
+		u16 sys_clock_en:1;	/* bit 4 */
+		u16 tx_clock_en:1;		/* bit 5 */
+		u16 group_mdio_en:1;	/* bit 6 */
+		u16 alternate_np:1;	/* bit 7 */
+		u16 tbi_rate:1;		/* bit 8 */
+		u16 pbi_detect:1;		/* bit 9 */
+		u16 speed_downshift:2;	/* bits 10-11 */
+		u16 tx_fifo_depth:2;	/* bits 12-13 */
+		u16 res1:1;		/* bit 14 */
+		u16 crs_tx_en:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_PHY_CONFIG_t, *PMI_PHY_CONFIG_t;
@@ -565,29 +562,29 @@ typedef union _MI_PHY_CONTROL_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res1:1;		// bit 15
-		u16 tdr_en:1;		// bit 14
-		u16 res2:1;		// bit 13
-		u16 downshift_attempts:2;	// bits 11-12
-		u16 res3:5;		// bit 6-10
-		u16 jabber_10baseT:1;	// bit 5
-		u16 sqe_10baseT:1;		// bit 4
-		u16 tp_loopback_10baseT:1;	// bit 3
-		u16 preamble_gen_en:1;	// bit 2
-		u16 res4:1;		// bit 1
-		u16 force_int:1;		// bit 0
+		u16 res1:1;		/* bit 15 */
+		u16 tdr_en:1;		/* bit 14 */
+		u16 res2:1;		/* bit 13 */
+		u16 downshift_attempts:2;	/* bits 11-12 */
+		u16 res3:5;		/* bit 6-10 */
+		u16 jabber_10baseT:1;	/* bit 5 */
+		u16 sqe_10baseT:1;		/* bit 4 */
+		u16 tp_loopback_10baseT:1;	/* bit 3 */
+		u16 preamble_gen_en:1;	/* bit 2 */
+		u16 res4:1;		/* bit 1 */
+		u16 force_int:1;		/* bit 0 */
 #else
-		u16 force_int:1;		// bit 0
-		u16 res4:1;		// bit 1
-		u16 preamble_gen_en:1;	// bit 2
-		u16 tp_loopback_10baseT:1;	// bit 3
-		u16 sqe_10baseT:1;		// bit 4
-		u16 jabber_10baseT:1;	// bit 5
-		u16 res3:5;		// bit 6-10
-		u16 downshift_attempts:2;	// bits 11-12
-		u16 res2:1;		// bit 13
-		u16 tdr_en:1;		// bit 14
-		u16 res1:1;		// bit 15
+		u16 force_int:1;		/* bit 0 */
+		u16 res4:1;		/* bit 1 */
+		u16 preamble_gen_en:1;	/* bit 2 */
+		u16 tp_loopback_10baseT:1;	/* bit 3 */
+		u16 sqe_10baseT:1;		/* bit 4 */
+		u16 jabber_10baseT:1;	/* bit 5 */
+		u16 res3:5;		/* bit 6-10 */
+		u16 downshift_attempts:2;	/* bits 11-12 */
+		u16 res2:1;		/* bit 13 */
+		u16 tdr_en:1;		/* bit 14 */
+		u16 res1:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_PHY_CONTROL_t, *PMI_PHY_CONTROL_t;
@@ -597,29 +594,29 @@ typedef union _MI_IMR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res1:6;		// bits 10-15
-		u16 mdio_sync_lost:1;	// bit 9
-		u16 autoneg_status:1;	// bit 8
-		u16 hi_bit_err:1;		// bit 7
-		u16 np_rx:1;		// bit 6
-		u16 err_counter_full:1;	// bit 5
-		u16 fifo_over_underflow:1;	// bit 4
-		u16 rx_status:1;		// bit 3
-		u16 link_status:1;		// bit 2
-		u16 automatic_speed:1;	// bit 1
-		u16 int_en:1;		// bit 0
+		u16 res1:6;		/* bits 10-15 */
+		u16 mdio_sync_lost:1;	/* bit 9 */
+		u16 autoneg_status:1;	/* bit 8 */
+		u16 hi_bit_err:1;		/* bit 7 */
+		u16 np_rx:1;		/* bit 6 */
+		u16 err_counter_full:1;	/* bit 5 */
+		u16 fifo_over_underflow:1;	/* bit 4 */
+		u16 rx_status:1;		/* bit 3 */
+		u16 link_status:1;		/* bit 2 */
+		u16 automatic_speed:1;	/* bit 1 */
+		u16 int_en:1;		/* bit 0 */
 #else
-		u16 int_en:1;		// bit 0
-		u16 automatic_speed:1;	// bit 1
-		u16 link_status:1;		// bit 2
-		u16 rx_status:1;		// bit 3
-		u16 fifo_over_underflow:1;	// bit 4
-		u16 err_counter_full:1;	// bit 5
-		u16 np_rx:1;		// bit 6
-		u16 hi_bit_err:1;		// bit 7
-		u16 autoneg_status:1;	// bit 8
-		u16 mdio_sync_lost:1;	// bit 9
-		u16 res1:6;		// bits 10-15
+		u16 int_en:1;		/* bit 0 */
+		u16 automatic_speed:1;	/* bit 1 */
+		u16 link_status:1;		/* bit 2 */
+		u16 rx_status:1;		/* bit 3 */
+		u16 fifo_over_underflow:1;	/* bit 4 */
+		u16 err_counter_full:1;	/* bit 5 */
+		u16 np_rx:1;		/* bit 6 */
+		u16 hi_bit_err:1;		/* bit 7 */
+		u16 autoneg_status:1;	/* bit 8 */
+		u16 mdio_sync_lost:1;	/* bit 9 */
+		u16 res1:6;		/* bits 10-15 */
 #endif
 	} bits;
 } MI_IMR_t, *PMI_IMR_t;
@@ -629,29 +626,29 @@ typedef union _MI_ISR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res1:6;		// bits 10-15
-		u16 mdio_sync_lost:1;	// bit 9
-		u16 autoneg_status:1;	// bit 8
-		u16 hi_bit_err:1;		// bit 7
-		u16 np_rx:1;		// bit 6
-		u16 err_counter_full:1;	// bit 5
-		u16 fifo_over_underflow:1;	// bit 4
-		u16 rx_status:1;		// bit 3
-		u16 link_status:1;		// bit 2
-		u16 automatic_speed:1;	// bit 1
-		u16 int_en:1;		// bit 0
+		u16 res1:6;		/* bits 10-15 */
+		u16 mdio_sync_lost:1;	/* bit 9 */
+		u16 autoneg_status:1;	/* bit 8 */
+		u16 hi_bit_err:1;		/* bit 7 */
+		u16 np_rx:1;		/* bit 6 */
+		u16 err_counter_full:1;	/* bit 5 */
+		u16 fifo_over_underflow:1;	/* bit 4 */
+		u16 rx_status:1;		/* bit 3 */
+		u16 link_status:1;		/* bit 2 */
+		u16 automatic_speed:1;	/* bit 1 */
+		u16 int_en:1;		/* bit 0 */
 #else
-		u16 int_en:1;		// bit 0
-		u16 automatic_speed:1;	// bit 1
-		u16 link_status:1;		// bit 2
-		u16 rx_status:1;		// bit 3
-		u16 fifo_over_underflow:1;	// bit 4
-		u16 err_counter_full:1;	// bit 5
-		u16 np_rx:1;		// bit 6
-		u16 hi_bit_err:1;		// bit 7
-		u16 autoneg_status:1;	// bit 8
-		u16 mdio_sync_lost:1;	// bit 9
-		u16 res1:6;		// bits 10-15
+		u16 int_en:1;		/* bit 0 */
+		u16 automatic_speed:1;	/* bit 1 */
+		u16 link_status:1;		/* bit 2 */
+		u16 rx_status:1;		/* bit 3 */
+		u16 fifo_over_underflow:1;	/* bit 4 */
+		u16 err_counter_full:1;	/* bit 5 */
+		u16 np_rx:1;		/* bit 6 */
+		u16 hi_bit_err:1;		/* bit 7 */
+		u16 autoneg_status:1;	/* bit 8 */
+		u16 mdio_sync_lost:1;	/* bit 9 */
+		u16 res1:6;		/* bits 10-15 */
 #endif
 	} bits;
 } MI_ISR_t, *PMI_ISR_t;
@@ -661,35 +658,35 @@ typedef union _MI_PSR_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res1:1;		// bit 15
-		u16 autoneg_fault:2;	// bit 13-14
-		u16 autoneg_status:1;	// bit 12
-		u16 mdi_x_status:1;	// bit 11
-		u16 polarity_status:1;	// bit 10
-		u16 speed_status:2;	// bits 8-9
-		u16 duplex_status:1;	// bit 7
-		u16 link_status:1;		// bit 6
-		u16 tx_status:1;		// bit 5
-		u16 rx_status:1;		// bit 4
-		u16 collision_status:1;	// bit 3
-		u16 autoneg_en:1;		// bit 2
-		u16 pause_en:1;		// bit 1
-		u16 asymmetric_dir:1;	// bit 0
+		u16 res1:1;		/* bit 15 */
+		u16 autoneg_fault:2;	/* bit 13-14 */
+		u16 autoneg_status:1;	/* bit 12 */
+		u16 mdi_x_status:1;	/* bit 11 */
+		u16 polarity_status:1;	/* bit 10 */
+		u16 speed_status:2;	/* bits 8-9 */
+		u16 duplex_status:1;	/* bit 7 */
+		u16 link_status:1;		/* bit 6 */
+		u16 tx_status:1;		/* bit 5 */
+		u16 rx_status:1;		/* bit 4 */
+		u16 collision_status:1;	/* bit 3 */
+		u16 autoneg_en:1;		/* bit 2 */
+		u16 pause_en:1;		/* bit 1 */
+		u16 asymmetric_dir:1;	/* bit 0 */
 #else
-		u16 asymmetric_dir:1;	// bit 0
-		u16 pause_en:1;		// bit 1
-		u16 autoneg_en:1;		// bit 2
-		u16 collision_status:1;	// bit 3
-		u16 rx_status:1;		// bit 4
-		u16 tx_status:1;		// bit 5
-		u16 link_status:1;		// bit 6
-		u16 duplex_status:1;	// bit 7
-		u16 speed_status:2;	// bits 8-9
-		u16 polarity_status:1;	// bit 10
-		u16 mdi_x_status:1;	// bit 11
-		u16 autoneg_status:1;	// bit 12
-		u16 autoneg_fault:2;	// bit 13-14
-		u16 res1:1;		// bit 15
+		u16 asymmetric_dir:1;	/* bit 0 */
+		u16 pause_en:1;		/* bit 1 */
+		u16 autoneg_en:1;		/* bit 2 */
+		u16 collision_status:1;	/* bit 3 */
+		u16 rx_status:1;		/* bit 4 */
+		u16 tx_status:1;		/* bit 5 */
+		u16 link_status:1;		/* bit 6 */
+		u16 duplex_status:1;	/* bit 7 */
+		u16 speed_status:2;	/* bits 8-9 */
+		u16 polarity_status:1;	/* bit 10 */
+		u16 mdi_x_status:1;	/* bit 11 */
+		u16 autoneg_status:1;	/* bit 12 */
+		u16 autoneg_fault:2;	/* bit 13-14 */
+		u16 res1:1;		/* bit 15 */
 #endif
 	} bits;
 } MI_PSR_t, *PMI_PSR_t;
@@ -699,25 +696,25 @@ typedef union _MI_LCR1_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 res1:2;		// bits 14-15
-		u16 led_dup_indicate:2;	// bits 12-13
-		u16 led_10baseT:2;		// bits 10-11
-		u16 led_collision:2;	// bits 8-9
-		u16 res2:2;		// bits 6-7
-		u16 res3:2;		// bits 4-5
-		u16 pulse_dur:2;		// bits 2-3
-		u16 pulse_stretch1:1;	// bit 1
-		u16 pulse_stretch0:1;	// bit 0
+		u16 res1:2;		/* bits 14-15 */
+		u16 led_dup_indicate:2;	/* bits 12-13 */
+		u16 led_10baseT:2;		/* bits 10-11 */
+		u16 led_collision:2;	/* bits 8-9 */
+		u16 res2:2;		/* bits 6-7 */
+		u16 res3:2;		/* bits 4-5 */
+		u16 pulse_dur:2;		/* bits 2-3 */
+		u16 pulse_stretch1:1;	/* bit 1 */
+		u16 pulse_stretch0:1;	/* bit 0 */
 #else
-		u16 pulse_stretch0:1;	// bit 0
-		u16 pulse_stretch1:1;	// bit 1
-		u16 pulse_dur:2;		// bits 2-3
-		u16 res3:2;		// bits 4-5
-		u16 res2:2;		// bits 6-7
-		u16 led_collision:2;	// bits 8-9
-		u16 led_10baseT:2;		// bits 10-11
-		u16 led_dup_indicate:2;	// bits 12-13
-		u16 res1:2;		// bits 14-15
+		u16 pulse_stretch0:1;	/* bit 0 */
+		u16 pulse_stretch1:1;	/* bit 1 */
+		u16 pulse_dur:2;		/* bits 2-3 */
+		u16 res3:2;		/* bits 4-5 */
+		u16 res2:2;		/* bits 6-7 */
+		u16 led_collision:2;	/* bits 8-9 */
+		u16 led_10baseT:2;		/* bits 10-11 */
+		u16 led_dup_indicate:2;	/* bits 12-13 */
+		u16 res1:2;		/* bits 14-15 */
 #endif
 	} bits;
 } MI_LCR1_t, *PMI_LCR1_t;
@@ -727,43 +724,21 @@ typedef union _MI_LCR2_t {
 	u16 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u16 led_link:4;		// bits 12-15
-		u16 led_tx_rx:4;		// bits 8-11
-		u16 led_100BaseTX:4;	// bits 4-7
-		u16 led_1000BaseT:4;	// bits 0-3
+		u16 led_link:4;		/* bits 12-15 */
+		u16 led_tx_rx:4;		/* bits 8-11 */
+		u16 led_100BaseTX:4;	/* bits 4-7 */
+		u16 led_1000BaseT:4;	/* bits 0-3 */
 #else
-		u16 led_1000BaseT:4;	// bits 0-3
-		u16 led_100BaseTX:4;	// bits 4-7
-		u16 led_tx_rx:4;		// bits 8-11
-		u16 led_link:4;		// bits 12-15
+		u16 led_1000BaseT:4;	/* bits 0-3 */
+		u16 led_100BaseTX:4;	/* bits 4-7 */
+		u16 led_tx_rx:4;		/* bits 8-11 */
+		u16 led_link:4;		/* bits 12-15 */
 #endif
 	} bits;
 } MI_LCR2_t, *PMI_LCR2_t;
 
 /* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */
 
-/* TruePHY headers */
-typedef struct _TRUEPHY_ACCESS_MI_REGS_ {
-	TRUEPHY_HANDLE hTruePhy;
-	int32_t nPhyId;
-	u8 bReadWrite;
-	u8 *pbyRegs;
-	u8 *pwData;
-	int32_t nRegCount;
-} TRUEPHY_ACCESS_MI_REGS, *PTRUEPHY_ACCESS_MI_REGS;
-
-/* TruePHY headers */
-typedef struct _TAG_TPAL_ACCESS_MI_REGS_ {
-	u32 nPhyId;
-	u8 bReadWrite;
-	u32 nRegCount;
-	u16 Data[4096];
-	u8 Regs[4096];
-} TPAL_ACCESS_MI_REGS, *PTPAL_ACCESS_MI_REGS;
-
-
-typedef TRUEPHY_HANDLE TPAL_HANDLE;
-
 /* Forward declaration of the private adapter structure */
 struct et131x_adapter;
 
@@ -802,41 +777,41 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
 
 /* Defines for PHY access routines */
 
-// Define bit operation flags
+/* Define bit operation flags */
 #define TRUEPHY_BIT_CLEAR               0
 #define TRUEPHY_BIT_SET                 1
 #define TRUEPHY_BIT_READ                2
 
-// Define read/write operation flags
+/* Define read/write operation flags */
 #ifndef TRUEPHY_READ
 #define TRUEPHY_READ                    0
 #define TRUEPHY_WRITE                   1
 #define TRUEPHY_MASK                    2
 #endif
 
-// Define speeds
+/* Define speeds */
 #define TRUEPHY_SPEED_10MBPS            0
 #define TRUEPHY_SPEED_100MBPS           1
 #define TRUEPHY_SPEED_1000MBPS          2
 
-// Define duplex modes
+/* Define duplex modes */
 #define TRUEPHY_DUPLEX_HALF             0
 #define TRUEPHY_DUPLEX_FULL             1
 
-// Define master/slave configuration values
+/* Define master/slave configuration values */
 #define TRUEPHY_CFG_SLAVE               0
 #define TRUEPHY_CFG_MASTER              1
 
-// Define MDI/MDI-X settings
+/* Define MDI/MDI-X settings */
 #define TRUEPHY_MDI                     0
 #define TRUEPHY_MDIX                    1
 #define TRUEPHY_AUTO_MDI_MDIX           2
 
-// Define 10Base-T link polarities
+/* Define 10Base-T link polarities */
 #define TRUEPHY_POLARITY_NORMAL         0
 #define TRUEPHY_POLARITY_INVERTED       1
 
-// Define auto-negotiation results
+/* Define auto-negotiation results */
 #define TRUEPHY_ANEG_NOT_COMPLETE       0
 #define TRUEPHY_ANEG_COMPLETE           1
 #define TRUEPHY_ANEG_DISABLED           2
@@ -848,38 +823,38 @@ void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
 #define TRUEPHY_ADV_DUPLEX_BOTH     \
     (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF)
 
-#define PHY_CONTROL                0x00	//#define TRU_MI_CONTROL_REGISTER                 0
-#define PHY_STATUS                 0x01	//#define TRU_MI_STATUS_REGISTER                  1
-#define PHY_ID_1                   0x02	//#define TRU_MI_PHY_IDENTIFIER_1_REGISTER        2
-#define PHY_ID_2                   0x03	//#define TRU_MI_PHY_IDENTIFIER_2_REGISTER        3
-#define PHY_AUTO_ADVERTISEMENT     0x04	//#define TRU_MI_ADVERTISEMENT_REGISTER           4
-#define PHY_AUTO_LINK_PARTNER      0x05	//#define TRU_MI_LINK_PARTNER_ABILITY_REGISTER    5
-#define PHY_AUTO_EXPANSION         0x06	//#define TRU_MI_EXPANSION_REGISTER               6
-#define PHY_AUTO_NEXT_PAGE_TX      0x07	//#define TRU_MI_NEXT_PAGE_TRANSMIT_REGISTER      7
-#define PHY_LINK_PARTNER_NEXT_PAGE 0x08	//#define TRU_MI_LINK_PARTNER_NEXT_PAGE_REGISTER  8
-#define PHY_1000_CONTROL           0x09	//#define TRU_MI_1000BASET_CONTROL_REGISTER       9
-#define PHY_1000_STATUS            0x0A	//#define TRU_MI_1000BASET_STATUS_REGISTER        10
-
-#define PHY_EXTENDED_STATUS        0x0F	//#define TRU_MI_EXTENDED_STATUS_REGISTER         15
-
-// some defines for modem registers that seem to be 'reserved'
+#define PHY_CONTROL                0x00	/* #define TRU_MI_CONTROL_REGISTER                 0 */
+#define PHY_STATUS                 0x01	/* #define TRU_MI_STATUS_REGISTER                  1 */
+#define PHY_ID_1                   0x02	/* #define TRU_MI_PHY_IDENTIFIER_1_REGISTER        2 */
+#define PHY_ID_2                   0x03	/* #define TRU_MI_PHY_IDENTIFIER_2_REGISTER        3 */
+#define PHY_AUTO_ADVERTISEMENT     0x04	/* #define TRU_MI_ADVERTISEMENT_REGISTER           4 */
+#define PHY_AUTO_LINK_PARTNER      0x05	/* #define TRU_MI_LINK_PARTNER_ABILITY_REGISTER    5 */
+#define PHY_AUTO_EXPANSION         0x06	/* #define TRU_MI_EXPANSION_REGISTER               6 */
+#define PHY_AUTO_NEXT_PAGE_TX      0x07	/* #define TRU_MI_NEXT_PAGE_TRANSMIT_REGISTER      7 */
+#define PHY_LINK_PARTNER_NEXT_PAGE 0x08	/* #define TRU_MI_LINK_PARTNER_NEXT_PAGE_REGISTER  8 */
+#define PHY_1000_CONTROL           0x09	/* #define TRU_MI_1000BASET_CONTROL_REGISTER       9 */
+#define PHY_1000_STATUS            0x0A	/* #define TRU_MI_1000BASET_STATUS_REGISTER        10 */
+
+#define PHY_EXTENDED_STATUS        0x0F	/* #define TRU_MI_EXTENDED_STATUS_REGISTER         15 */
+
+/* some defines for modem registers that seem to be 'reserved' */
 #define PHY_INDEX_REG              0x10
 #define PHY_DATA_REG               0x11
 
-#define PHY_MPHY_CONTROL_REG       0x12	//#define TRU_VMI_MPHY_CONTROL_REGISTER           18
-
-#define PHY_LOOPBACK_CONTROL       0x13	//#define TRU_VMI_LOOPBACK_CONTROL_1_REGISTER     19
-					//#define TRU_VMI_LOOPBACK_CONTROL_2_REGISTER     20
-#define PHY_REGISTER_MGMT_CONTROL  0x15	//#define TRU_VMI_MI_SEQ_CONTROL_REGISTER         21
-#define PHY_CONFIG                 0x16	//#define TRU_VMI_CONFIGURATION_REGISTER          22
-#define PHY_PHY_CONTROL            0x17	//#define TRU_VMI_PHY_CONTROL_REGISTER            23
-#define PHY_INTERRUPT_MASK         0x18	//#define TRU_VMI_INTERRUPT_MASK_REGISTER         24
-#define PHY_INTERRUPT_STATUS       0x19	//#define TRU_VMI_INTERRUPT_STATUS_REGISTER       25
-#define PHY_PHY_STATUS             0x1A	//#define TRU_VMI_PHY_STATUS_REGISTER             26
-#define PHY_LED_1                  0x1B	//#define TRU_VMI_LED_CONTROL_1_REGISTER          27
-#define PHY_LED_2                  0x1C	//#define TRU_VMI_LED_CONTROL_2_REGISTER          28
-					//#define TRU_VMI_LINK_CONTROL_REGISTER           29
-					//#define TRU_VMI_TIMING_CONTROL_REGISTER
+#define PHY_MPHY_CONTROL_REG       0x12	/* #define TRU_VMI_MPHY_CONTROL_REGISTER           18 */
+
+#define PHY_LOOPBACK_CONTROL       0x13	/* #define TRU_VMI_LOOPBACK_CONTROL_1_REGISTER     19 */
+					/* #define TRU_VMI_LOOPBACK_CONTROL_2_REGISTER     20 */
+#define PHY_REGISTER_MGMT_CONTROL  0x15	/* #define TRU_VMI_MI_SEQ_CONTROL_REGISTER         21 */
+#define PHY_CONFIG                 0x16	/* #define TRU_VMI_CONFIGURATION_REGISTER          22 */
+#define PHY_PHY_CONTROL            0x17	/* #define TRU_VMI_PHY_CONTROL_REGISTER            23 */
+#define PHY_INTERRUPT_MASK         0x18	/* #define TRU_VMI_INTERRUPT_MASK_REGISTER         24 */
+#define PHY_INTERRUPT_STATUS       0x19	/* #define TRU_VMI_INTERRUPT_STATUS_REGISTER       25 */
+#define PHY_PHY_STATUS             0x1A	/* #define TRU_VMI_PHY_STATUS_REGISTER             26 */
+#define PHY_LED_1                  0x1B	/* #define TRU_VMI_LED_CONTROL_1_REGISTER          27 */
+#define PHY_LED_2                  0x1C	/* #define TRU_VMI_LED_CONTROL_2_REGISTER          28 */
+					/* #define TRU_VMI_LINK_CONTROL_REGISTER           29 */
+					/* #define TRU_VMI_TIMING_CONTROL_REGISTER */
 
 /* Prototypes for PHY access routines */
 void ET1310_PhyInit(struct et131x_adapter *adapter);
@@ -895,12 +870,12 @@ void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *adapter,
 void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *adapter,
 				u16 duplex);
 void ET1310_PhyLinkStatus(struct et131x_adapter *adapter,
-			  u8 *ucLinkStatus,
-			  u32 *uiAutoNeg,
-			  u32 *uiLinkSpeed,
-			  u32 *uiDuplexMode,
-			  u32 *uiMdiMdix,
-			  u32 *uiMasterSlave, u32 *uiPolarity);
+			  u8 *Link_status,
+			  u32 *autoneg,
+			  u32 *linkspeed,
+			  u32 *duplex_mode,
+			  u32 *mdi_mdix,
+			  u32 *masterslave, u32 *polarity);
 void ET1310_PhyAndOrReg(struct et131x_adapter *adapter,
 			u16 regnum, u16 andMask, u16 orMask);
 void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c
index 9539bc6..7d07723 100644
--- a/drivers/staging/et131x/et1310_pm.c
+++ b/drivers/staging/et131x/et1310_pm.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -56,7 +56,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/init.h>
@@ -73,9 +72,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -92,14 +91,9 @@
 #include "et131x_adapter.h"
 #include "et131x_initpci.h"
 
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
-
 /**
  * EnablePhyComa - called when network cable is unplugged
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  *
  * driver receive an phy status change interrupt while in D0 and check that
  * phy_status is down.
@@ -117,91 +111,75 @@ extern dbg_info_t *et131x_dbginfo;
  *       indicating linkup status, call the MPDisablePhyComa routine to
  *             restore JAGCore and gigE PHY
  */
-void EnablePhyComa(struct et131x_adapter *pAdapter)
+void EnablePhyComa(struct et131x_adapter *etdev)
 {
-	unsigned long lockflags;
-	PM_CSR_t GlobalPmCSR;
-	int32_t LoopCounter = 10;
-
-	DBG_ENTER(et131x_dbginfo);
+	unsigned long flags;
+	u32 GlobalPmCSR;
 
-	GlobalPmCSR.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+	GlobalPmCSR = readl(&etdev->regs->global.pm_csr);
 
 	/* Save the GbE PHY speed and duplex modes. Need to restore this
 	 * when cable is plugged back in
 	 */
-	pAdapter->PoMgmt.PowerDownSpeed = pAdapter->AiForceSpeed;
-	pAdapter->PoMgmt.PowerDownDuplex = pAdapter->AiForceDpx;
+	etdev->PoMgmt.PowerDownSpeed = etdev->AiForceSpeed;
+	etdev->PoMgmt.PowerDownDuplex = etdev->AiForceDpx;
 
 	/* Stop sending packets. */
-	spin_lock_irqsave(&pAdapter->SendHWLock, lockflags);
-	MP_SET_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER);
-	spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags);
+	spin_lock_irqsave(&etdev->SendHWLock, flags);
+	etdev->Flags |= fMP_ADAPTER_LOWER_POWER;
+	spin_unlock_irqrestore(&etdev->SendHWLock, flags);
 
 	/* Wait for outstanding Receive packets */
-	while ((MP_GET_RCV_REF(pAdapter) != 0) && (LoopCounter-- > 0)) {
-		mdelay(2);
-	}
 
 	/* Gate off JAGCore 3 clock domains */
-	GlobalPmCSR.bits.pm_sysclk_gate = 0;
-	GlobalPmCSR.bits.pm_txclk_gate = 0;
-	GlobalPmCSR.bits.pm_rxclk_gate = 0;
-	writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value);
+	GlobalPmCSR &= ~ET_PMCSR_INIT;
+	writel(GlobalPmCSR, &etdev->regs->global.pm_csr);
 
 	/* Program gigE PHY in to Coma mode */
-	GlobalPmCSR.bits.pm_phy_sw_coma = 1;
-	writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value);
-
-	DBG_LEAVE(et131x_dbginfo);
+	GlobalPmCSR |= ET_PM_PHY_SW_COMA;
+	writel(GlobalPmCSR, &etdev->regs->global.pm_csr);
 }
 
 /**
  * DisablePhyComa - Disable the Phy Coma Mode
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  */
-void DisablePhyComa(struct et131x_adapter *pAdapter)
+void DisablePhyComa(struct et131x_adapter *etdev)
 {
-	PM_CSR_t GlobalPmCSR;
+	u32 GlobalPmCSR;
 
-	DBG_ENTER(et131x_dbginfo);
-
-	GlobalPmCSR.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+	GlobalPmCSR = readl(&etdev->regs->global.pm_csr);
 
 	/* Disable phy_sw_coma register and re-enable JAGCore clocks */
-	GlobalPmCSR.bits.pm_sysclk_gate = 1;
-	GlobalPmCSR.bits.pm_txclk_gate = 1;
-	GlobalPmCSR.bits.pm_rxclk_gate = 1;
-	GlobalPmCSR.bits.pm_phy_sw_coma = 0;
-	writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value);
+	GlobalPmCSR |= ET_PMCSR_INIT;
+	GlobalPmCSR &= ~ET_PM_PHY_SW_COMA;
+	writel(GlobalPmCSR, &etdev->regs->global.pm_csr);
 
 	/* Restore the GbE PHY speed and duplex modes;
 	 * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY
 	 */
-	pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed;
-	pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex;
+	etdev->AiForceSpeed = etdev->PoMgmt.PowerDownSpeed;
+	etdev->AiForceDpx = etdev->PoMgmt.PowerDownDuplex;
 
 	/* Re-initialize the send structures */
-	et131x_init_send(pAdapter);
+	et131x_init_send(etdev);
 
 	/* Reset the RFD list and re-start RU  */
-	et131x_reset_recv(pAdapter);
+	et131x_reset_recv(etdev);
 
 	/* Bring the device back to the state it was during init prior to
-         * autonegotiation being complete.  This way, when we get the auto-neg
-         * complete interrupt, we can complete init by calling ConfigMacREGS2.
-         */
-	et131x_soft_reset(pAdapter);
+	 * autonegotiation being complete.  This way, when we get the auto-neg
+	 * complete interrupt, we can complete init by calling ConfigMacREGS2.
+	 */
+	et131x_soft_reset(etdev);
 
 	/* setup et1310 as per the documentation ?? */
-	et131x_adapter_setup(pAdapter);
+	et131x_adapter_setup(etdev);
 
 	/* Allow Tx to restart */
-	MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER);
+	etdev->Flags &= ~fMP_ADAPTER_LOWER_POWER;
 
 	/* Need to re-enable Rx. */
-	et131x_rx_dma_enable(pAdapter);
-
-	DBG_LEAVE(et131x_dbginfo);
+	et131x_rx_dma_enable(etdev);
 }
 
diff --git a/drivers/staging/et131x/et1310_pm.h b/drivers/staging/et131x/et1310_pm.h
index 6802338..295f3ab 100644
--- a/drivers/staging/et131x/et1310_pm.h
+++ b/drivers/staging/et131x/et1310_pm.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -61,64 +61,24 @@
 
 #include "et1310_address_map.h"
 
-#define MAX_WOL_PACKET_SIZE    0x80
-#define MAX_WOL_MASK_SIZE      ( MAX_WOL_PACKET_SIZE / 8 )
-#define NUM_WOL_PATTERNS       0x5
-#define CRC16_POLY             0x1021
-
-/* Definition of NDIS_DEVICE_POWER_STATE */
-typedef enum {
-	NdisDeviceStateUnspecified = 0,
-	NdisDeviceStateD0,
-	NdisDeviceStateD1,
-	NdisDeviceStateD2,
-	NdisDeviceStateD3
-} NDIS_DEVICE_POWER_STATE;
-
 typedef struct _MP_POWER_MGMT {
 	/* variable putting the phy into coma mode when boot up with no cable
 	 * plugged in after 5 seconds
 	 */
 	u8 TransPhyComaModeOnBoot;
 
-	/* Array holding the five CRC values that the device is currently
-	 * using for WOL.  This will be queried when a pattern is to be
-	 * removed.
-	 */
-	u32 localWolAndCrc0;
-	u16 WOLPatternList[NUM_WOL_PATTERNS];
-	u8 WOLMaskList[NUM_WOL_PATTERNS][MAX_WOL_MASK_SIZE];
-	u32 WOLMaskSize[NUM_WOL_PATTERNS];
-
-	/* IP address */
-	union {
-		u32 u32;
-		u8 u8[4];
-	} IPAddress;
-
-	/* Current Power state of the adapter. */
-	NDIS_DEVICE_POWER_STATE PowerState;
-	bool WOLState;
-	bool WOLEnabled;
-	bool Failed10Half;
-	bool bFailedStateTransition;
-
 	/* Next two used to save power information at power down. This
 	 * information will be used during power up to set up parts of Power
 	 * Management in JAGCore
 	 */
-	u32 tx_en;
-	u32 rx_en;
 	u16 PowerDownSpeed;
 	u8 PowerDownDuplex;
 } MP_POWER_MGMT, *PMP_POWER_MGMT;
 
 /* Forward declaration of the private adapter structure
- * ( IS THERE A WAY TO DO THIS WITH A TYPEDEF??? )
  */
 struct et131x_adapter;
 
-u16 CalculateCCITCRC16(u8 *Pattern, u8 *Mask, u32 MaskSize);
 void EnablePhyComa(struct et131x_adapter *adapter);
 void DisablePhyComa(struct et131x_adapter *adapter);
 
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index 8dc559a..8f2e91f 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -56,7 +56,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/pci.h>
@@ -74,9 +73,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -93,13 +92,8 @@
 
 #include "et1310_rx.h"
 
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
 
-
-void nic_return_rfd(struct et131x_adapter *pAdapter, PMP_RFD pMpRfd);
+void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd);
 
 /**
  * et131x_rx_dma_memory_alloc
@@ -117,10 +111,8 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 	uint32_t pktStatRingSize, FBRChunkSize;
 	RX_RING_t *rx_ring;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Setup some convenience pointers */
-	rx_ring = (RX_RING_t *) & adapter->RxRing;
+	rx_ring = (RX_RING_t *) &adapter->RxRing;
 
 	/* Alloc memory for the lookup table */
 #ifdef USE_FBR0
@@ -183,9 +175,8 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 						    bufsize,
 						    &rx_ring->pFbr1RingPa);
 	if (!rx_ring->pFbr1RingVa) {
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&adapter->pdev->dev,
 			  "Cannot alloc memory for Free Buffer Ring 1\n");
-		DBG_LEAVE(et131x_dbginfo);
 		return -ENOMEM;
 	}
 
@@ -213,9 +204,8 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 						    bufsize,
 						    &rx_ring->pFbr0RingPa);
 	if (!rx_ring->pFbr0RingVa) {
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&adapter->pdev->dev,
 			  "Cannot alloc memory for Free Buffer Ring 0\n");
-		DBG_LEAVE(et131x_dbginfo);
 		return -ENOMEM;
 	}
 
@@ -250,11 +240,10 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 		 * the size of FBR0.  By allocating N buffers at once, we
 		 * reduce this overhead.
 		 */
-		if (rx_ring->Fbr1BufferSize > 4096) {
+		if (rx_ring->Fbr1BufferSize > 4096)
 			Fbr1Align = 4096;
-		} else {
+		else
 			Fbr1Align = rx_ring->Fbr1BufferSize;
-		}
 
 		FBRChunkSize =
 		    (FBR_CHUNKS * rx_ring->Fbr1BufferSize) + Fbr1Align - 1;
@@ -263,8 +252,8 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 					 &rx_ring->Fbr1MemPa[OuterLoop]);
 
 		if (!rx_ring->Fbr1MemVa[OuterLoop]) {
-			DBG_ERROR(et131x_dbginfo, "Could not alloc memory\n");
-			DBG_LEAVE(et131x_dbginfo);
+		dev_err(&adapter->pdev->dev,
+				"Could not alloc memory\n");
 			return -ENOMEM;
 		}
 
@@ -314,8 +303,8 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 					 &rx_ring->Fbr0MemPa[OuterLoop]);
 
 		if (!rx_ring->Fbr0MemVa[OuterLoop]) {
-			DBG_ERROR(et131x_dbginfo, "Could not alloc memory\n");
-			DBG_LEAVE(et131x_dbginfo);
+			dev_err(&adapter->pdev->dev,
+				"Could not alloc memory\n");
 			return -ENOMEM;
 		}
 
@@ -357,9 +346,8 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 						  &rx_ring->pPSRingPa);
 
 	if (!rx_ring->pPSRingVa) {
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&adapter->pdev->dev,
 			  "Cannot alloc memory for Packet Status Ring\n");
-		DBG_LEAVE(et131x_dbginfo);
 		return -ENOMEM;
 	}
 
@@ -385,9 +373,8 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 						    sizeof(RX_STATUS_BLOCK_t) +
 						    0x7, &rx_ring->pRxStatusPa);
 	if (!rx_ring->pRxStatusVa) {
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&adapter->pdev->dev,
 			  "Cannot alloc memory for Status Block\n");
-		DBG_LEAVE(et131x_dbginfo);
 		return -ENOMEM;
 	}
 
@@ -416,15 +403,13 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
 						   SLAB_HWCACHE_ALIGN,
 						   NULL);
 
-	MP_SET_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE);
+	adapter->Flags |= fMP_ADAPTER_RECV_LOOKASIDE;
 
 	/* The RFDs are going to be put on lists later on, so initialize the
 	 * lists now.
 	 */
 	INIT_LIST_HEAD(&rx_ring->RecvList);
 	INIT_LIST_HEAD(&rx_ring->RecvPendingList);
-
-	DBG_LEAVE(et131x_dbginfo);
 	return 0;
 }
 
@@ -440,13 +425,11 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 	PMP_RFD pMpRfd;
 	RX_RING_t *rx_ring;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Setup some convenience pointers */
-	rx_ring = (RX_RING_t *) & adapter->RxRing;
+	rx_ring = (RX_RING_t *) &adapter->RxRing;
 
 	/* Free RFDs and associated packet descriptors */
-	DBG_ASSERT(rx_ring->nReadyRecv == rx_ring->NumRfd);
+	WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd);
 
 	while (!list_empty(&rx_ring->RecvList)) {
 		pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvList.next,
@@ -471,11 +454,10 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 			if (rx_ring->Fbr1MemVa[index]) {
 				uint32_t Fbr1Align;
 
-				if (rx_ring->Fbr1BufferSize > 4096) {
+				if (rx_ring->Fbr1BufferSize > 4096)
 					Fbr1Align = 4096;
-				} else {
+				else
 					Fbr1Align = rx_ring->Fbr1BufferSize;
-				}
 
 				bufsize =
 				    (rx_ring->Fbr1BufferSize * FBR_CHUNKS) +
@@ -491,8 +473,8 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 		}
 
 		/* Now the FIFO itself */
-		rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa -
-						rx_ring->Fbr1offset);
+		rx_ring->pFbr1RingVa = (void *)((uint8_t *)
+				rx_ring->pFbr1RingVa - rx_ring->Fbr1offset);
 
 		bufsize =
 		    (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff;
@@ -525,8 +507,8 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 		}
 
 		/* Now the FIFO itself */
-		rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa -
-						rx_ring->Fbr0offset);
+		rx_ring->pFbr0RingVa = (void *)((uint8_t *)
+				rx_ring->pFbr0RingVa - rx_ring->Fbr0offset);
 
 		bufsize =
 		    (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff;
@@ -556,12 +538,12 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 
 	/* Free area of memory for the writeback of status information */
 	if (rx_ring->pRxStatusVa) {
-		rx_ring->pRxStatusVa = (void *)((uint8_t *) rx_ring->pRxStatusVa -
-						rx_ring->RxStatusOffset);
+		rx_ring->pRxStatusVa = (void *)((uint8_t *)
+				rx_ring->pRxStatusVa - rx_ring->RxStatusOffset);
 
 		pci_free_consistent(adapter->pdev,
-				    sizeof(RX_STATUS_BLOCK_t) + 0x7,
-				    rx_ring->pRxStatusVa, rx_ring->pRxStatusPa);
+				sizeof(RX_STATUS_BLOCK_t) + 0x7,
+				rx_ring->pRxStatusVa, rx_ring->pRxStatusPa);
 
 		rx_ring->pRxStatusVa = NULL;
 	}
@@ -571,9 +553,9 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 	/* Free receive packet pool */
 
 	/* Destroy the lookaside (RFD) pool */
-	if (MP_TEST_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE)) {
+	if (adapter->Flags & fMP_ADAPTER_RECV_LOOKASIDE) {
 		kmem_cache_destroy(rx_ring->RecvLookaside);
-		MP_CLEAR_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE);
+		adapter->Flags &= ~fMP_ADAPTER_RECV_LOOKASIDE;
 	}
 
 	/* Free the FBR Lookup Table */
@@ -585,8 +567,6 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
 
 	/* Reset Counters */
 	rx_ring->nReadyRecv = 0;
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
@@ -603,10 +583,8 @@ int et131x_init_recv(struct et131x_adapter *adapter)
 	uint32_t TotalNumRfd = 0;
 	RX_RING_t *rx_ring = NULL;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Setup some convenience pointers */
-	rx_ring = (RX_RING_t *) & adapter->RxRing;
+	rx_ring = (RX_RING_t *) &adapter->RxRing;
 
 	/* Setup each RFD */
 	for (RfdCount = 0; RfdCount < rx_ring->NumRfd; RfdCount++) {
@@ -614,7 +592,7 @@ int et131x_init_recv(struct et131x_adapter *adapter)
 						     GFP_ATOMIC | GFP_DMA);
 
 		if (!pMpRfd) {
-			DBG_ERROR(et131x_dbginfo,
+			dev_err(&adapter->pdev->dev,
 				  "Couldn't alloc RFD out of kmem_cache\n");
 			status = -ENOMEM;
 			continue;
@@ -622,7 +600,7 @@ int et131x_init_recv(struct et131x_adapter *adapter)
 
 		status = et131x_rfd_resources_alloc(adapter, pMpRfd);
 		if (status != 0) {
-			DBG_ERROR(et131x_dbginfo,
+			dev_err(&adapter->pdev->dev,
 				  "Couldn't alloc packet for RFD\n");
 			kmem_cache_free(rx_ring->RecvLookaside, pMpRfd);
 			continue;
@@ -636,19 +614,16 @@ int et131x_init_recv(struct et131x_adapter *adapter)
 		TotalNumRfd++;
 	}
 
-	if (TotalNumRfd > NIC_MIN_NUM_RFD) {
+	if (TotalNumRfd > NIC_MIN_NUM_RFD)
 		status = 0;
-	}
 
 	rx_ring->NumRfd = TotalNumRfd;
 
 	if (status != 0) {
 		kmem_cache_free(rx_ring->RecvLookaside, pMpRfd);
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&adapter->pdev->dev,
 			  "Allocation problems in et131x_init_recv\n");
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -679,21 +654,19 @@ void et131x_rfd_resources_free(struct et131x_adapter *adapter, MP_RFD *pMpRfd)
 
 /**
  * ConfigRxDmaRegs - Start of Rx_DMA init sequence
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  */
-void ConfigRxDmaRegs(struct et131x_adapter *pAdapter)
+void ConfigRxDmaRegs(struct et131x_adapter *etdev)
 {
-	struct _RXDMA_t __iomem *pRxDma = &pAdapter->CSRAddress->rxdma;
-	struct _rx_ring_t *pRxLocal = &pAdapter->RxRing;
-	PFBR_DESC_t pFbrEntry;
-	uint32_t iEntry;
+	struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
+	struct _rx_ring_t *pRxLocal = &etdev->RxRing;
+	PFBR_DESC_t fbr_entry;
+	uint32_t entry;
 	RXDMA_PSR_NUM_DES_t psr_num_des;
-	unsigned long lockflags;
-
-	DBG_ENTER(et131x_dbginfo);
+	unsigned long flags;
 
 	/* Halt RXDMA to perform the reconfigure.  */
-	et131x_rx_dma_disable(pAdapter);
+	et131x_rx_dma_disable(etdev);
 
 	/* Load the completion writeback physical address
 	 *
@@ -703,8 +676,8 @@ void ConfigRxDmaRegs(struct et131x_adapter *pAdapter)
 	 * before storing the adjusted address.
 	 */
 	writel((uint32_t) (pRxLocal->RxStatusRealPA >> 32),
-	       &pRxDma->dma_wb_base_hi);
-	writel((uint32_t) pRxLocal->RxStatusRealPA, &pRxDma->dma_wb_base_lo);
+	       &rx_dma->dma_wb_base_hi);
+	writel((uint32_t) pRxLocal->RxStatusRealPA, &rx_dma->dma_wb_base_lo);
 
 	memset(pRxLocal->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t));
 
@@ -712,82 +685,66 @@ void ConfigRxDmaRegs(struct et131x_adapter *pAdapter)
 	 * 1310's registers
 	 */
 	writel((uint32_t) (pRxLocal->pPSRingRealPa >> 32),
-	       &pRxDma->psr_base_hi);
-	writel((uint32_t) pRxLocal->pPSRingRealPa, &pRxDma->psr_base_lo);
-	writel(pRxLocal->PsrNumEntries - 1, &pRxDma->psr_num_des.value);
-	writel(0, &pRxDma->psr_full_offset.value);
+	       &rx_dma->psr_base_hi);
+	writel((uint32_t) pRxLocal->pPSRingRealPa, &rx_dma->psr_base_lo);
+	writel(pRxLocal->PsrNumEntries - 1, &rx_dma->psr_num_des.value);
+	writel(0, &rx_dma->psr_full_offset.value);
 
-	psr_num_des.value = readl(&pRxDma->psr_num_des.value);
+	psr_num_des.value = readl(&rx_dma->psr_num_des.value);
 	writel((psr_num_des.bits.psr_ndes * LO_MARK_PERCENT_FOR_PSR) / 100,
-	       &pRxDma->psr_min_des.value);
+	       &rx_dma->psr_min_des.value);
 
-	spin_lock_irqsave(&pAdapter->RcvLock, lockflags);
+	spin_lock_irqsave(&etdev->RcvLock, flags);
 
 	/* These local variables track the PSR in the adapter structure */
 	pRxLocal->local_psr_full.bits.psr_full = 0;
 	pRxLocal->local_psr_full.bits.psr_full_wrap = 0;
 
 	/* Now's the best time to initialize FBR1 contents */
-	pFbrEntry = (PFBR_DESC_t) pRxLocal->pFbr1RingVa;
-	for (iEntry = 0; iEntry < pRxLocal->Fbr1NumEntries; iEntry++) {
-		pFbrEntry->addr_hi = pRxLocal->Fbr[1]->PAHigh[iEntry];
-		pFbrEntry->addr_lo = pRxLocal->Fbr[1]->PALow[iEntry];
-		pFbrEntry->word2.bits.bi = iEntry;
-		pFbrEntry++;
+	fbr_entry = (PFBR_DESC_t) pRxLocal->pFbr1RingVa;
+	for (entry = 0; entry < pRxLocal->Fbr1NumEntries; entry++) {
+		fbr_entry->addr_hi = pRxLocal->Fbr[1]->PAHigh[entry];
+		fbr_entry->addr_lo = pRxLocal->Fbr[1]->PALow[entry];
+		fbr_entry->word2.bits.bi = entry;
+		fbr_entry++;
 	}
 
 	/* Set the address and parameters of Free buffer ring 1 (and 0 if
 	 * required) into the 1310's registers
 	 */
-	writel((uint32_t) (pRxLocal->Fbr1Realpa >> 32), &pRxDma->fbr1_base_hi);
-	writel((uint32_t) pRxLocal->Fbr1Realpa, &pRxDma->fbr1_base_lo);
-	writel(pRxLocal->Fbr1NumEntries - 1, &pRxDma->fbr1_num_des.value);
-
-	{
-		DMA10W_t fbr1_full = { 0 };
-
-		fbr1_full.bits.val = 0;
-		fbr1_full.bits.wrap = 1;
-		writel(fbr1_full.value, &pRxDma->fbr1_full_offset.value);
-	}
+	writel((uint32_t) (pRxLocal->Fbr1Realpa >> 32), &rx_dma->fbr1_base_hi);
+	writel((uint32_t) pRxLocal->Fbr1Realpa, &rx_dma->fbr1_base_lo);
+	writel(pRxLocal->Fbr1NumEntries - 1, &rx_dma->fbr1_num_des.value);
+	writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset);
 
 	/* This variable tracks the free buffer ring 1 full position, so it
 	 * has to match the above.
 	 */
-	pRxLocal->local_Fbr1_full.bits.val = 0;
-	pRxLocal->local_Fbr1_full.bits.wrap = 1;
+	pRxLocal->local_Fbr1_full = ET_DMA10_WRAP;
 	writel(((pRxLocal->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
-	       &pRxDma->fbr1_min_des.value);
+	       &rx_dma->fbr1_min_des.value);
 
 #ifdef USE_FBR0
 	/* Now's the best time to initialize FBR0 contents */
-	pFbrEntry = (PFBR_DESC_t) pRxLocal->pFbr0RingVa;
-	for (iEntry = 0; iEntry < pRxLocal->Fbr0NumEntries; iEntry++) {
-		pFbrEntry->addr_hi = pRxLocal->Fbr[0]->PAHigh[iEntry];
-		pFbrEntry->addr_lo = pRxLocal->Fbr[0]->PALow[iEntry];
-		pFbrEntry->word2.bits.bi = iEntry;
-		pFbrEntry++;
+	fbr_entry = (PFBR_DESC_t) pRxLocal->pFbr0RingVa;
+	for (entry = 0; entry < pRxLocal->Fbr0NumEntries; entry++) {
+		fbr_entry->addr_hi = pRxLocal->Fbr[0]->PAHigh[entry];
+		fbr_entry->addr_lo = pRxLocal->Fbr[0]->PALow[entry];
+		fbr_entry->word2.bits.bi = entry;
+		fbr_entry++;
 	}
 
-	writel((uint32_t) (pRxLocal->Fbr0Realpa >> 32), &pRxDma->fbr0_base_hi);
-	writel((uint32_t) pRxLocal->Fbr0Realpa, &pRxDma->fbr0_base_lo);
-	writel(pRxLocal->Fbr0NumEntries - 1, &pRxDma->fbr0_num_des.value);
-
-	{
-		DMA10W_t fbr0_full = { 0 };
-
-		fbr0_full.bits.val = 0;
-		fbr0_full.bits.wrap = 1;
-		writel(fbr0_full.value, &pRxDma->fbr0_full_offset.value);
-	}
+	writel((uint32_t) (pRxLocal->Fbr0Realpa >> 32), &rx_dma->fbr0_base_hi);
+	writel((uint32_t) pRxLocal->Fbr0Realpa, &rx_dma->fbr0_base_lo);
+	writel(pRxLocal->Fbr0NumEntries - 1, &rx_dma->fbr0_num_des.value);
+	writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset);
 
 	/* This variable tracks the free buffer ring 0 full position, so it
 	 * has to match the above.
 	 */
-	pRxLocal->local_Fbr0_full.bits.val = 0;
-	pRxLocal->local_Fbr0_full.bits.wrap = 1;
+	pRxLocal->local_Fbr0_full = ET_DMA10_WRAP;
 	writel(((pRxLocal->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
-	       &pRxDma->fbr0_min_des.value);
+	       &rx_dma->fbr0_min_des.value);
 #endif
 
 	/* Program the number of packets we will receive before generating an
@@ -795,115 +752,102 @@ void ConfigRxDmaRegs(struct et131x_adapter *pAdapter)
 	 * For version B silicon, this value gets updated once autoneg is
 	 *complete.
 	 */
-	writel(pAdapter->RegistryRxNumBuffers, &pRxDma->num_pkt_done.value);
+	writel(PARM_RX_NUM_BUFS_DEF, &rx_dma->num_pkt_done.value);
 
 	/* The "time_done" is not working correctly to coalesce interrupts
 	 * after a given time period, but rather is giving us an interrupt
 	 * regardless of whether we have received packets.
 	 * This value gets updated once autoneg is complete.
 	 */
-	writel(pAdapter->RegistryRxTimeInterval, &pRxDma->max_pkt_time.value);
-
-	spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+	writel(PARM_RX_TIME_INT_DEF, &rx_dma->max_pkt_time.value);
 
-	DBG_LEAVE(et131x_dbginfo);
+	spin_unlock_irqrestore(&etdev->RcvLock, flags);
 }
 
 /**
  * SetRxDmaTimer - Set the heartbeat timer according to line rate.
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  */
-void SetRxDmaTimer(struct et131x_adapter *pAdapter)
+void SetRxDmaTimer(struct et131x_adapter *etdev)
 {
 	/* For version B silicon, we do not use the RxDMA timer for 10 and 100
 	 * Mbits/s line rates. We do not enable and RxDMA interrupt coalescing.
 	 */
-	if ((pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS) ||
-	    (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS)) {
-		writel(0, &pAdapter->CSRAddress->rxdma.max_pkt_time.value);
-		writel(1, &pAdapter->CSRAddress->rxdma.num_pkt_done.value);
+	if ((etdev->linkspeed == TRUEPHY_SPEED_100MBPS) ||
+	    (etdev->linkspeed == TRUEPHY_SPEED_10MBPS)) {
+		writel(0, &etdev->regs->rxdma.max_pkt_time.value);
+		writel(1, &etdev->regs->rxdma.num_pkt_done.value);
 	}
 }
 
 /**
  * et131x_rx_dma_disable - Stop of Rx_DMA on the ET1310
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  */
-void et131x_rx_dma_disable(struct et131x_adapter *pAdapter)
+void et131x_rx_dma_disable(struct et131x_adapter *etdev)
 {
 	RXDMA_CSR_t csr;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Setup the receive dma configuration register */
-	writel(0x00002001, &pAdapter->CSRAddress->rxdma.csr.value);
-	csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
+	writel(0x00002001, &etdev->regs->rxdma.csr.value);
+	csr.value = readl(&etdev->regs->rxdma.csr.value);
 	if (csr.bits.halt_status != 1) {
 		udelay(5);
-		csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
-		if (csr.bits.halt_status != 1) {
-			DBG_ERROR(et131x_dbginfo,
-				  "RX Dma failed to enter halt state. CSR 0x%08x\n",
-				  csr.value);
-		}
+		csr.value = readl(&etdev->regs->rxdma.csr.value);
+		if (csr.bits.halt_status != 1)
+			dev_err(&etdev->pdev->dev,
+				"RX Dma failed to enter halt state. CSR 0x%08x\n",
+				csr.value);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
  * et131x_rx_dma_enable - re-start of Rx_DMA on the ET1310.
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  */
-void et131x_rx_dma_enable(struct et131x_adapter *pAdapter)
+void et131x_rx_dma_enable(struct et131x_adapter *etdev)
 {
-	DBG_RX_ENTER(et131x_dbginfo);
-
-	if (pAdapter->RegistryPhyLoopbk) {
-	/* RxDMA is disabled for loopback operation. */
-		writel(0x1, &pAdapter->CSRAddress->rxdma.csr.value);
-	} else {
+	if (etdev->RegistryPhyLoopbk)
+		/* RxDMA is disabled for loopback operation. */
+		writel(0x1, &etdev->regs->rxdma.csr.value);
+	else {
 	/* Setup the receive dma configuration register for normal operation */
 		RXDMA_CSR_t csr = { 0 };
 
 		csr.bits.fbr1_enable = 1;
-		if (pAdapter->RxRing.Fbr1BufferSize == 4096) {
+		if (etdev->RxRing.Fbr1BufferSize == 4096)
 			csr.bits.fbr1_size = 1;
-		} else if (pAdapter->RxRing.Fbr1BufferSize == 8192) {
+		else if (etdev->RxRing.Fbr1BufferSize == 8192)
 			csr.bits.fbr1_size = 2;
-		} else if (pAdapter->RxRing.Fbr1BufferSize == 16384) {
+		else if (etdev->RxRing.Fbr1BufferSize == 16384)
 			csr.bits.fbr1_size = 3;
-		}
 #ifdef USE_FBR0
 		csr.bits.fbr0_enable = 1;
-		if (pAdapter->RxRing.Fbr0BufferSize == 256) {
+		if (etdev->RxRing.Fbr0BufferSize == 256)
 			csr.bits.fbr0_size = 1;
-		} else if (pAdapter->RxRing.Fbr0BufferSize == 512) {
+		else if (etdev->RxRing.Fbr0BufferSize == 512)
 			csr.bits.fbr0_size = 2;
-		} else if (pAdapter->RxRing.Fbr0BufferSize == 1024) {
+		else if (etdev->RxRing.Fbr0BufferSize == 1024)
 			csr.bits.fbr0_size = 3;
-		}
 #endif
-		writel(csr.value, &pAdapter->CSRAddress->rxdma.csr.value);
+		writel(csr.value, &etdev->regs->rxdma.csr.value);
 
-		csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
+		csr.value = readl(&etdev->regs->rxdma.csr.value);
 		if (csr.bits.halt_status != 0) {
 			udelay(5);
-			csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
+			csr.value = readl(&etdev->regs->rxdma.csr.value);
 			if (csr.bits.halt_status != 0) {
-				DBG_ERROR(et131x_dbginfo,
-					  "RX Dma failed to exit halt state.  CSR 0x%08x\n",
-					  csr.value);
+				dev_err(&etdev->pdev->dev,
+					"RX Dma failed to exit halt state.  CSR 0x%08x\n",
+					csr.value);
 			}
 		}
 	}
-
-	DBG_RX_LEAVE(et131x_dbginfo);
 }
 
 /**
  * nic_rx_pkts - Checks the hardware for available packets
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  *
  * Returns pMpRfd, a pointer to our MPRFD.
  *
@@ -912,24 +856,21 @@ void et131x_rx_dma_enable(struct et131x_adapter *pAdapter)
  * the packet to it, puts the RFD in the RecvPendList, and also returns
  * the pointer to the RFD.
  */
-PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
+PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
 {
-	struct _rx_ring_t *pRxLocal = &pAdapter->RxRing;
+	struct _rx_ring_t *pRxLocal = &etdev->RxRing;
 	PRX_STATUS_BLOCK_t pRxStatusBlock;
 	PPKT_STAT_DESC_t pPSREntry;
 	PMP_RFD pMpRfd;
 	uint32_t nIndex;
 	uint8_t *pBufVa;
-	unsigned long lockflags;
+	unsigned long flags;
 	struct list_head *element;
 	uint8_t ringIndex;
 	uint16_t bufferIndex;
 	uint32_t localLen;
 	PKT_STAT_DESC_WORD0_t Word0;
 
-
-	DBG_RX_ENTER(et131x_dbginfo);
-
 	/* RX Status block is written by the DMA engine prior to every
 	 * interrupt. It contains the next to be used entry in the Packet
 	 * Status Ring, and also the two Free Buffer rings.
@@ -938,11 +879,9 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 
 	if (pRxStatusBlock->Word1.bits.PSRoffset ==
 			pRxLocal->local_psr_full.bits.psr_full &&
-	    pRxStatusBlock->Word1.bits.PSRwrap ==
-	    		pRxLocal->local_psr_full.bits.psr_full_wrap) {
+			pRxStatusBlock->Word1.bits.PSRwrap ==
+			pRxLocal->local_psr_full.bits.psr_full_wrap) {
 		/* Looks like this ring is not updated yet */
-		DBG_RX(et131x_dbginfo, "(0)\n");
-		DBG_RX_LEAVE(et131x_dbginfo);
 		return NULL;
 	}
 
@@ -959,23 +898,6 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 	bufferIndex = (uint16_t) pPSREntry->word1.bits.bi;
 	Word0 = pPSREntry->word0;
 
-	DBG_RX(et131x_dbginfo, "RX PACKET STATUS\n");
-	DBG_RX(et131x_dbginfo, "\tlength      : %d\n", localLen);
-	DBG_RX(et131x_dbginfo, "\tringIndex   : %d\n", ringIndex);
-	DBG_RX(et131x_dbginfo, "\tbufferIndex : %d\n", bufferIndex);
-	DBG_RX(et131x_dbginfo, "\tword0       : 0x%08x\n", Word0.value);
-
-#if 0
-	/* Check the Status Word that the MAC has appended to the PSR
-	 * entry in case the MAC has detected errors.
-	 */
-	if (Word0.value & ALCATEL_BAD_STATUS) {
-		DBG_ERROR(et131x_dbginfo,
-			  "NICRxPkts >> Alcatel Status Word error."
-			  "Value 0x%08x\n", pPSREntry->word0.value);
-	}
-#endif
-
 	/* Indicate that we have used this PSR entry. */
 	if (++pRxLocal->local_psr_full.bits.psr_full >
 	    pRxLocal->PsrNumEntries - 1) {
@@ -984,62 +906,53 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 	}
 
 	writel(pRxLocal->local_psr_full.value,
-	       &pAdapter->CSRAddress->rxdma.psr_full_offset.value);
+	       &etdev->regs->rxdma.psr_full_offset.value);
 
 #ifndef USE_FBR0
 	if (ringIndex != 1) {
-		DBG_ERROR(et131x_dbginfo,
-			  "NICRxPkts PSR Entry %d indicates "
-			  "Buffer Ring 0 in use\n",
-			  pRxLocal->local_psr_full.bits.psr_full);
-		DBG_RX_LEAVE(et131x_dbginfo);
 		return NULL;
 	}
 #endif
 
 #ifdef USE_FBR0
 	if (ringIndex > 1 ||
-	    (ringIndex == 0 &&
-	     bufferIndex > pRxLocal->Fbr0NumEntries - 1) ||
-	    (ringIndex == 1 &&
-	     bufferIndex > pRxLocal->Fbr1NumEntries - 1))
+		(ringIndex == 0 &&
+		bufferIndex > pRxLocal->Fbr0NumEntries - 1) ||
+		(ringIndex == 1 &&
+		bufferIndex > pRxLocal->Fbr1NumEntries - 1))
 #else
 	if (ringIndex != 1 ||
-	    bufferIndex > pRxLocal->Fbr1NumEntries - 1)
+		bufferIndex > pRxLocal->Fbr1NumEntries - 1)
 #endif
 	{
 		/* Illegal buffer or ring index cannot be used by S/W*/
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&etdev->pdev->dev,
 			  "NICRxPkts PSR Entry %d indicates "
 			  "length of %d and/or bad bi(%d)\n",
 			  pRxLocal->local_psr_full.bits.psr_full,
 			  localLen, bufferIndex);
-		DBG_RX_LEAVE(et131x_dbginfo);
 		return NULL;
 	}
 
 	/* Get and fill the RFD. */
-	spin_lock_irqsave(&pAdapter->RcvLock, lockflags);
+	spin_lock_irqsave(&etdev->RcvLock, flags);
 
 	pMpRfd = NULL;
 	element = pRxLocal->RecvList.next;
 	pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
 
 	if (pMpRfd == NULL) {
-		DBG_RX(et131x_dbginfo,
-		       "NULL RFD returned from RecvList via list_entry()\n");
-		DBG_RX_LEAVE(et131x_dbginfo);
-		spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+		spin_unlock_irqrestore(&etdev->RcvLock, flags);
 		return NULL;
 	}
 
 	list_del(&pMpRfd->list_node);
 	pRxLocal->nReadyRecv--;
 
-	spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+	spin_unlock_irqrestore(&etdev->RcvLock, flags);
 
-	pMpRfd->iBufferIndex = bufferIndex;
-	pMpRfd->iRingIndex = ringIndex;
+	pMpRfd->bufferindex = bufferIndex;
+	pMpRfd->ringindex = ringIndex;
 
 	/* In V1 silicon, there is a bug which screws up filtering of
 	 * runt packets.  Therefore runt packet filtering is disabled
@@ -1047,34 +960,21 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 	 * also counted here.
 	 */
 	if (localLen < (NIC_MIN_PACKET_SIZE + 4)) {
-		pAdapter->Stats.other_errors++;
+		etdev->Stats.other_errors++;
 		localLen = 0;
 	}
 
 	if (localLen) {
-		if (pAdapter->ReplicaPhyLoopbk == 1) {
+		if (etdev->ReplicaPhyLoopbk == 1) {
 			pBufVa = pRxLocal->Fbr[ringIndex]->Va[bufferIndex];
 
-			if (memcmp(&pBufVa[6], &pAdapter->CurrentAddress[0],
+			if (memcmp(&pBufVa[6], &etdev->CurrentAddress[0],
 				   ETH_ALEN) == 0) {
 				if (memcmp(&pBufVa[42], "Replica packet",
 					   ETH_HLEN)) {
-					pAdapter->ReplicaPhyLoopbkPF = 1;
+					etdev->ReplicaPhyLoopbkPF = 1;
 				}
 			}
-			DBG_WARNING(et131x_dbginfo,
-				    "pBufVa:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
-				    pBufVa[6], pBufVa[7], pBufVa[8],
-				    pBufVa[9], pBufVa[10], pBufVa[11]);
-
-			DBG_WARNING(et131x_dbginfo,
-				    "CurrentAddr:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
-				    pAdapter->CurrentAddress[0],
-				    pAdapter->CurrentAddress[1],
-				    pAdapter->CurrentAddress[2],
-				    pAdapter->CurrentAddress[3],
-				    pAdapter->CurrentAddress[4],
-				    pAdapter->CurrentAddress[5]);
 		}
 
 		/* Determine if this is a multicast packet coming in */
@@ -1087,9 +987,9 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 			 * filters. Generally filter is 0x2b when in
 			 * promiscuous mode.
 			 */
-			if ((pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
-			    && !(pAdapter->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
-			    && !(pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
+			if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
+			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
+			    && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
 				pBufVa = pRxLocal->Fbr[ringIndex]->
 						Va[bufferIndex];
 
@@ -1098,20 +998,20 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 				 * matches one in our list.
 				 */
 				for (nIndex = 0;
-				     nIndex < pAdapter->MCAddressCount;
+				     nIndex < etdev->MCAddressCount;
 				     nIndex++) {
 					if (pBufVa[0] ==
-					    pAdapter->MCList[nIndex][0]
+					    etdev->MCList[nIndex][0]
 					    && pBufVa[1] ==
-					    pAdapter->MCList[nIndex][1]
+					    etdev->MCList[nIndex][1]
 					    && pBufVa[2] ==
-					    pAdapter->MCList[nIndex][2]
+					    etdev->MCList[nIndex][2]
 					    && pBufVa[3] ==
-					    pAdapter->MCList[nIndex][3]
+					    etdev->MCList[nIndex][3]
 					    && pBufVa[4] ==
-					    pAdapter->MCList[nIndex][4]
+					    etdev->MCList[nIndex][4]
 					    && pBufVa[5] ==
-					    pAdapter->MCList[nIndex][5]) {
+					    etdev->MCList[nIndex][5]) {
 						break;
 					}
 				}
@@ -1124,48 +1024,44 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 				 * so we free our RFD when we return
 				 * from this function.
 				 */
-				if (nIndex == pAdapter->MCAddressCount) {
+				if (nIndex == etdev->MCAddressCount)
 					localLen = 0;
-				}
 			}
 
-			if (localLen > 0) {
-				pAdapter->Stats.multircv++;
-			}
-		} else if (Word0.value & ALCATEL_BROADCAST_PKT) {
-			pAdapter->Stats.brdcstrcv++;
-		} else {
+			if (localLen > 0)
+				etdev->Stats.multircv++;
+		} else if (Word0.value & ALCATEL_BROADCAST_PKT)
+			etdev->Stats.brdcstrcv++;
+		else
 			/* Not sure what this counter measures in
 			 * promiscuous mode. Perhaps we should check
 			 * the MAC address to see if it is directed
 			 * to us in promiscuous mode.
 			 */
-			pAdapter->Stats.unircv++;
-		}
+			etdev->Stats.unircv++;
 	}
 
 	if (localLen > 0) {
 		struct sk_buff *skb = NULL;
 
-		//pMpRfd->PacketSize = localLen - 4;
+		/* pMpRfd->PacketSize = localLen - 4; */
 		pMpRfd->PacketSize = localLen;
 
 		skb = dev_alloc_skb(pMpRfd->PacketSize + 2);
 		if (!skb) {
-			DBG_ERROR(et131x_dbginfo,
+			dev_err(&etdev->pdev->dev,
 				  "Couldn't alloc an SKB for Rx\n");
-			DBG_RX_LEAVE(et131x_dbginfo);
 			return NULL;
 		}
 
-		pAdapter->net_stats.rx_bytes += pMpRfd->PacketSize;
+		etdev->net_stats.rx_bytes += pMpRfd->PacketSize;
 
 		memcpy(skb_put(skb, pMpRfd->PacketSize),
 		       pRxLocal->Fbr[ringIndex]->Va[bufferIndex],
 		       pMpRfd->PacketSize);
 
-		skb->dev = pAdapter->netdev;
-		skb->protocol = eth_type_trans(skb, pAdapter->netdev);
+		skb->dev = etdev->netdev;
+		skb->protocol = eth_type_trans(skb, etdev->netdev);
 		skb->ip_summed = CHECKSUM_NONE;
 
 		netif_rx(skb);
@@ -1173,49 +1069,42 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
 		pMpRfd->PacketSize = 0;
 	}
 
-	nic_return_rfd(pAdapter, pMpRfd);
-
-	DBG_RX(et131x_dbginfo, "(1)\n");
-	DBG_RX_LEAVE(et131x_dbginfo);
+	nic_return_rfd(etdev, pMpRfd);
 	return pMpRfd;
 }
 
 /**
  * et131x_reset_recv - Reset the receive list
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  *
  * Assumption, Rcv spinlock has been acquired.
  */
-void et131x_reset_recv(struct et131x_adapter *pAdapter)
+void et131x_reset_recv(struct et131x_adapter *etdev)
 {
 	PMP_RFD pMpRfd;
 	struct list_head *element;
 
-	DBG_ENTER(et131x_dbginfo);
-
-	DBG_ASSERT(!list_empty(&pAdapter->RxRing.RecvList));
+	WARN_ON(list_empty(&etdev->RxRing.RecvList));
 
 	/* Take all the RFD's from the pending list, and stick them on the
 	 * RecvList.
 	 */
-	while (!list_empty(&pAdapter->RxRing.RecvPendingList)) {
-		element = pAdapter->RxRing.RecvPendingList.next;
+	while (!list_empty(&etdev->RxRing.RecvPendingList)) {
+		element = etdev->RxRing.RecvPendingList.next;
 
 		pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
 
-		list_move_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
+		list_move_tail(&pMpRfd->list_node, &etdev->RxRing.RecvList);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
  * et131x_handle_recv_interrupt - Interrupt handler for receive processing
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  *
  * Assumption, Rcv spinlock has been acquired.
  */
-void et131x_handle_recv_interrupt(struct et131x_adapter *pAdapter)
+void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
 {
 	PMP_RFD pMpRfd = NULL;
 	struct sk_buff *PacketArray[NUM_PACKETS_HANDLED];
@@ -1225,43 +1114,37 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *pAdapter)
 	uint32_t PacketFreeCount = 0;
 	bool TempUnfinishedRec = false;
 
-	DBG_RX_ENTER(et131x_dbginfo);
-
 	PacketsToHandle = NUM_PACKETS_HANDLED;
 
 	/* Process up to available RFD's */
 	while (PacketArrayCount < PacketsToHandle) {
-		if (list_empty(&pAdapter->RxRing.RecvList)) {
-			DBG_ASSERT(pAdapter->RxRing.nReadyRecv == 0);
-			DBG_ERROR(et131x_dbginfo, "NO RFD's !!!!!!!!!!!!!\n");
+		if (list_empty(&etdev->RxRing.RecvList)) {
+			WARN_ON(etdev->RxRing.nReadyRecv != 0);
 			TempUnfinishedRec = true;
 			break;
 		}
 
-		pMpRfd = nic_rx_pkts(pAdapter);
+		pMpRfd = nic_rx_pkts(etdev);
 
-		if (pMpRfd == NULL) {
+		if (pMpRfd == NULL)
 			break;
-		}
 
 		/* Do not receive any packets until a filter has been set.
-		 * Do not receive any packets until we are at D0.
 		 * Do not receive any packets until we have link.
 		 * If length is zero, return the RFD in order to advance the
 		 * Free buffer ring.
 		 */
-		if ((!pAdapter->PacketFilter) ||
-		    (pAdapter->PoMgmt.PowerState != NdisDeviceStateD0) ||
-		    (!MP_LINK_DETECTED(pAdapter)) ||
-		    (pMpRfd->PacketSize == 0)) {
+		if (!etdev->PacketFilter ||
+		    !(etdev->Flags & fMP_ADAPTER_LINK_DETECTION) ||
+		    pMpRfd->PacketSize == 0) {
 			continue;
 		}
 
 		/* Increment the number of packets we received */
-		pAdapter->Stats.ipackets++;
+		etdev->Stats.ipackets++;
 
 		/* Set the status on the packet, either resources or success */
-		if (pAdapter->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK) {
+		if (etdev->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK) {
 			/* Put this RFD on the pending list
 			 *
 			 * NOTE: nic_rx_pkts() above is already returning the
@@ -1270,18 +1153,12 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *pAdapter)
 			 * Besides, we don't really need (at this point) the
 			 * pending list anyway.
 			 */
-			//spin_lock_irqsave( &pAdapter->RcvPendLock, lockflags );
-			//list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvPendingList );
-			//spin_unlock_irqrestore( &pAdapter->RcvPendLock, lockflags );
-
-			/* Update the number of outstanding Recvs */
-			//MP_INC_RCV_REF( pAdapter );
 		} else {
 			RFDFreeArray[PacketFreeCount] = pMpRfd;
 			PacketFreeCount++;
 
-			DBG_WARNING(et131x_dbginfo,
-				    "RFD's are running out !!!!!!!!!!!!!\n");
+			dev_warn(&etdev->pdev->dev,
+				    "RFD's are running out\n");
 		}
 
 		PacketArray[PacketArrayCount] = pMpRfd->Packet;
@@ -1289,102 +1166,97 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *pAdapter)
 	}
 
 	if ((PacketArrayCount == NUM_PACKETS_HANDLED) || TempUnfinishedRec) {
-		pAdapter->RxRing.UnfinishedReceives = true;
-		writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO,
-		       &pAdapter->CSRAddress->global.watchdog_timer);
+		etdev->RxRing.UnfinishedReceives = true;
+		writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
+		       &etdev->regs->global.watchdog_timer);
 	} else {
 		/* Watchdog timer will disable itself if appropriate. */
-		pAdapter->RxRing.UnfinishedReceives = false;
+		etdev->RxRing.UnfinishedReceives = false;
 	}
+}
 
-	DBG_RX_LEAVE(et131x_dbginfo);
+static inline u32 bump_fbr(u32 *fbr, u32 limit)
+{
+	u32 v = *fbr;
+	add_10bit(&v, 1);
+	if (v > limit)
+		v = (*fbr & ~ET_DMA10_MASK) ^ ET_DMA10_WRAP;
+	*fbr = v;
+	return v;
 }
 
 /**
  * NICReturnRFD - Recycle a RFD and put it back onto the receive list
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  * @pMpRfd: pointer to the RFD
  */
-void nic_return_rfd(struct et131x_adapter *pAdapter, PMP_RFD pMpRfd)
+void nic_return_rfd(struct et131x_adapter *etdev, PMP_RFD pMpRfd)
 {
-	struct _rx_ring_t *pRxLocal = &pAdapter->RxRing;
-	struct _RXDMA_t __iomem *pRxDma = &pAdapter->CSRAddress->rxdma;
-	uint16_t bi = pMpRfd->iBufferIndex;
-	uint8_t ri = pMpRfd->iRingIndex;
-	unsigned long lockflags;
-
-	DBG_RX_ENTER(et131x_dbginfo);
+	struct _rx_ring_t *rx_local = &etdev->RxRing;
+	struct _RXDMA_t __iomem *rx_dma = &etdev->regs->rxdma;
+	uint16_t bi = pMpRfd->bufferindex;
+	uint8_t ri = pMpRfd->ringindex;
+	unsigned long flags;
 
 	/* We don't use any of the OOB data besides status. Otherwise, we
 	 * need to clean up OOB data
 	 */
 	if (
 #ifdef USE_FBR0
-	    (ri == 0 && bi < pRxLocal->Fbr0NumEntries) ||
+	    (ri == 0 && bi < rx_local->Fbr0NumEntries) ||
 #endif
-	    (ri == 1 && bi < pRxLocal->Fbr1NumEntries)) {
-		spin_lock_irqsave(&pAdapter->FbrLock, lockflags);
+	    (ri == 1 && bi < rx_local->Fbr1NumEntries)) {
+		spin_lock_irqsave(&etdev->FbrLock, flags);
 
 		if (ri == 1) {
 			PFBR_DESC_t pNextDesc =
-			    (PFBR_DESC_t) (pRxLocal->pFbr1RingVa) +
-			    pRxLocal->local_Fbr1_full.bits.val;
+			    (PFBR_DESC_t) (rx_local->pFbr1RingVa) +
+			    INDEX10(rx_local->local_Fbr1_full);
 
 			/* Handle the Free Buffer Ring advancement here. Write
 			 * the PA / Buffer Index for the returned buffer into
 			 * the oldest (next to be freed)FBR entry
 			 */
-			pNextDesc->addr_hi = pRxLocal->Fbr[1]->PAHigh[bi];
-			pNextDesc->addr_lo = pRxLocal->Fbr[1]->PALow[bi];
+			pNextDesc->addr_hi = rx_local->Fbr[1]->PAHigh[bi];
+			pNextDesc->addr_lo = rx_local->Fbr[1]->PALow[bi];
 			pNextDesc->word2.value = bi;
 
-			if (++pRxLocal->local_Fbr1_full.bits.val >
-			    (pRxLocal->Fbr1NumEntries - 1)) {
-				pRxLocal->local_Fbr1_full.bits.val = 0;
-				pRxLocal->local_Fbr1_full.bits.wrap ^= 1;
-			}
-
-			writel(pRxLocal->local_Fbr1_full.value,
-			       &pRxDma->fbr1_full_offset.value);
+			writel(bump_fbr(&rx_local->local_Fbr1_full,
+				rx_local->Fbr1NumEntries - 1),
+				&rx_dma->fbr1_full_offset);
 		}
 #ifdef USE_FBR0
 		else {
 			PFBR_DESC_t pNextDesc =
-			    (PFBR_DESC_t) pRxLocal->pFbr0RingVa +
-			    pRxLocal->local_Fbr0_full.bits.val;
+			    (PFBR_DESC_t) rx_local->pFbr0RingVa +
+			    INDEX10(rx_local->local_Fbr0_full);
 
 			/* Handle the Free Buffer Ring advancement here. Write
 			 * the PA / Buffer Index for the returned buffer into
 			 * the oldest (next to be freed) FBR entry
 			 */
-			pNextDesc->addr_hi = pRxLocal->Fbr[0]->PAHigh[bi];
-			pNextDesc->addr_lo = pRxLocal->Fbr[0]->PALow[bi];
+			pNextDesc->addr_hi = rx_local->Fbr[0]->PAHigh[bi];
+			pNextDesc->addr_lo = rx_local->Fbr[0]->PALow[bi];
 			pNextDesc->word2.value = bi;
 
-			if (++pRxLocal->local_Fbr0_full.bits.val >
-			    (pRxLocal->Fbr0NumEntries - 1)) {
-				pRxLocal->local_Fbr0_full.bits.val = 0;
-				pRxLocal->local_Fbr0_full.bits.wrap ^= 1;
-			}
-
-			writel(pRxLocal->local_Fbr0_full.value,
-			       &pRxDma->fbr0_full_offset.value);
+			writel(bump_fbr(&rx_local->local_Fbr0_full,
+					rx_local->Fbr0NumEntries - 1),
+			       &rx_dma->fbr0_full_offset);
 		}
 #endif
-		spin_unlock_irqrestore(&pAdapter->FbrLock, lockflags);
+		spin_unlock_irqrestore(&etdev->FbrLock, flags);
 	} else {
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&etdev->pdev->dev,
 			  "NICReturnRFD illegal Buffer Index returned\n");
 	}
 
 	/* The processing on this RFD is done, so put it back on the tail of
 	 * our list
 	 */
-	spin_lock_irqsave(&pAdapter->RcvLock, lockflags);
-	list_add_tail(&pMpRfd->list_node, &pRxLocal->RecvList);
-	pRxLocal->nReadyRecv++;
-	spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+	spin_lock_irqsave(&etdev->RcvLock, flags);
+	list_add_tail(&pMpRfd->list_node, &rx_local->RecvList);
+	rx_local->nReadyRecv++;
+	spin_unlock_irqrestore(&etdev->RcvLock, flags);
 
-	DBG_ASSERT(pRxLocal->nReadyRecv <= pRxLocal->NumRfd);
-	DBG_RX_LEAVE(et131x_dbginfo);
+	WARN_ON(rx_local->nReadyRecv > rx_local->NumRfd);
 }
diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h
index ea66dbc..72a5229 100644
--- a/drivers/staging/et131x/et1310_rx.h
+++ b/drivers/staging/et131x/et1310_rx.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -64,10 +64,10 @@
 #define USE_FBR0 true
 
 #ifdef USE_FBR0
-//#define FBR0_BUFFER_SIZE 256
+/* #define FBR0_BUFFER_SIZE 256 */
 #endif
 
-//#define FBR1_BUFFER_SIZE 2048
+/* #define FBR1_BUFFER_SIZE 2048 */
 
 #define FBR_CHUNKS 32
 
@@ -95,11 +95,11 @@ typedef union _FBR_WORD2_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 reserved:22;	// bits 10-31
-		u32 bi:10;		// bits 0-9(Buffer Index)
+		u32 reserved:22;	/* bits 10-31 */
+		u32 bi:10;		/* bits 0-9(Buffer Index) */
 #else
-		u32 bi:10;		// bits 0-9(Buffer Index)
-		u32 reserved:22;	// bit 10-31
+		u32 bi:10;		/* bits 0-9(Buffer Index) */
+		u32 reserved:22;	/* bit 10-31 */
 #endif
 	} bits;
 } FBR_WORD2_t, *PFBR_WORD2_t;
@@ -115,70 +115,70 @@ typedef union _PKT_STAT_DESC_WORD0_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		// top 16 bits are from the Alcatel Status Word as enumerated in
-		// PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2)
+		/* top 16 bits are from the Alcatel Status Word as enumerated in */
+		/* PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) */
 #if 0
-		u32 asw_trunc:1;		// bit 31(Rx frame truncated)
+		u32 asw_trunc:1;		/* bit 31(Rx frame truncated) */
 #endif
-		u32 asw_long_evt:1;	// bit 31(Rx long event)
-		u32 asw_VLAN_tag:1;	// bit 30(VLAN tag detected)
-		u32 asw_unsupported_op:1;	// bit 29(unsupported OP code)
-		u32 asw_pause_frame:1;	// bit 28(is a pause frame)
-		u32 asw_control_frame:1;	// bit 27(is a control frame)
-		u32 asw_dribble_nibble:1;	// bit 26(spurious bits after EOP)
-		u32 asw_broadcast:1;	// bit 25(has a broadcast address)
-		u32 asw_multicast:1;	// bit 24(has a multicast address)
-		u32 asw_OK:1;		// bit 23(valid CRC + no code error)
-		u32 asw_too_long:1;	// bit 22(frame length > 1518 bytes)
-		u32 asw_len_chk_err:1;	// bit 21(frame length field incorrect)
-		u32 asw_CRC_err:1;		// bit 20(CRC error)
-		u32 asw_code_err:1;	// bit 19(one or more nibbles signalled as errors)
-		u32 asw_false_carrier_event:1;	// bit 18(bad carrier since last good packet)
-		u32 asw_RX_DV_event:1;	// bit 17(short receive event detected)
-		u32 asw_prev_pkt_dropped:1;// bit 16(e.g. IFG too small on previous)
-		u32 unused:5;		// bits 11-15
-		u32 vp:1;			// bit 10(VLAN Packet)
-		u32 jp:1;			// bit 9(Jumbo Packet)
-		u32 ft:1;			// bit 8(Frame Truncated)
-		u32 drop:1;		// bit 7(Drop packet)
-		u32 rxmac_error:1;		// bit 6(RXMAC Error Indicator)
-		u32 wol:1;			// bit 5(WOL Event)
-		u32 tcpp:1;		// bit 4(TCP checksum pass)
-		u32 tcpa:1;		// bit 3(TCP checksum assist)
-		u32 ipp:1;			// bit 2(IP checksum pass)
-		u32 ipa:1;			// bit 1(IP checksum assist)
-		u32 hp:1;			// bit 0(hash pass)
+		u32 asw_long_evt:1;	/* bit 31(Rx long event) */
+		u32 asw_VLAN_tag:1;	/* bit 30(VLAN tag detected) */
+		u32 asw_unsupported_op:1;	/* bit 29(unsupported OP code) */
+		u32 asw_pause_frame:1;	/* bit 28(is a pause frame) */
+		u32 asw_control_frame:1;	/* bit 27(is a control frame) */
+		u32 asw_dribble_nibble:1;	/* bit 26(spurious bits after EOP) */
+		u32 asw_broadcast:1;	/* bit 25(has a broadcast address) */
+		u32 asw_multicast:1;	/* bit 24(has a multicast address) */
+		u32 asw_OK:1;		/* bit 23(valid CRC + no code error) */
+		u32 asw_too_long:1;	/* bit 22(frame length > 1518 bytes) */
+		u32 asw_len_chk_err:1;	/* bit 21(frame length field incorrect) */
+		u32 asw_CRC_err:1;		/* bit 20(CRC error) */
+		u32 asw_code_err:1;	/* bit 19(one or more nibbles signalled as errors) */
+		u32 asw_false_carrier_event:1;	/* bit 18(bad carrier since last good packet) */
+		u32 asw_RX_DV_event:1;	/* bit 17(short receive event detected) */
+		u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
+		u32 unused:5;		/* bits 11-15 */
+		u32 vp:1;			/* bit 10(VLAN Packet) */
+		u32 jp:1;			/* bit 9(Jumbo Packet) */
+		u32 ft:1;			/* bit 8(Frame Truncated) */
+		u32 drop:1;		/* bit 7(Drop packet) */
+		u32 rxmac_error:1;		/* bit 6(RXMAC Error Indicator) */
+		u32 wol:1;			/* bit 5(WOL Event) */
+		u32 tcpp:1;		/* bit 4(TCP checksum pass) */
+		u32 tcpa:1;		/* bit 3(TCP checksum assist) */
+		u32 ipp:1;			/* bit 2(IP checksum pass) */
+		u32 ipa:1;			/* bit 1(IP checksum assist) */
+		u32 hp:1;			/* bit 0(hash pass) */
 #else
-		u32 hp:1;			// bit 0(hash pass)
-		u32 ipa:1;			// bit 1(IP checksum assist)
-		u32 ipp:1;			// bit 2(IP checksum pass)
-		u32 tcpa:1;		// bit 3(TCP checksum assist)
-		u32 tcpp:1;		// bit 4(TCP checksum pass)
-		u32 wol:1;			// bit 5(WOL Event)
-		u32 rxmac_error:1;		// bit 6(RXMAC Error Indicator)
-		u32 drop:1;		// bit 7(Drop packet)
-		u32 ft:1;			// bit 8(Frame Truncated)
-		u32 jp:1;			// bit 9(Jumbo Packet)
-		u32 vp:1;			// bit 10(VLAN Packet)
-		u32 unused:5;		// bits 11-15
-		u32 asw_prev_pkt_dropped:1;// bit 16(e.g. IFG too small on previous)
-		u32 asw_RX_DV_event:1;	// bit 17(short receive event detected)
-		u32 asw_false_carrier_event:1;	// bit 18(bad carrier since last good packet)
-		u32 asw_code_err:1;	// bit 19(one or more nibbles signalled as errors)
-		u32 asw_CRC_err:1;		// bit 20(CRC error)
-		u32 asw_len_chk_err:1;	// bit 21(frame length field incorrect)
-		u32 asw_too_long:1;	// bit 22(frame length > 1518 bytes)
-		u32 asw_OK:1;		// bit 23(valid CRC + no code error)
-		u32 asw_multicast:1;	// bit 24(has a multicast address)
-		u32 asw_broadcast:1;	// bit 25(has a broadcast address)
-		u32 asw_dribble_nibble:1;	// bit 26(spurious bits after EOP)
-		u32 asw_control_frame:1;	// bit 27(is a control frame)
-		u32 asw_pause_frame:1;	// bit 28(is a pause frame)
-		u32 asw_unsupported_op:1;	// bit 29(unsupported OP code)
-		u32 asw_VLAN_tag:1;	// bit 30(VLAN tag detected)
-		u32 asw_long_evt:1;	// bit 31(Rx long event)
+		u32 hp:1;			/* bit 0(hash pass) */
+		u32 ipa:1;			/* bit 1(IP checksum assist) */
+		u32 ipp:1;			/* bit 2(IP checksum pass) */
+		u32 tcpa:1;		/* bit 3(TCP checksum assist) */
+		u32 tcpp:1;		/* bit 4(TCP checksum pass) */
+		u32 wol:1;			/* bit 5(WOL Event) */
+		u32 rxmac_error:1;		/* bit 6(RXMAC Error Indicator) */
+		u32 drop:1;		/* bit 7(Drop packet) */
+		u32 ft:1;			/* bit 8(Frame Truncated) */
+		u32 jp:1;			/* bit 9(Jumbo Packet) */
+		u32 vp:1;			/* bit 10(VLAN Packet) */
+		u32 unused:5;		/* bits 11-15 */
+		u32 asw_prev_pkt_dropped:1;/* bit 16(e.g. IFG too small on previous) */
+		u32 asw_RX_DV_event:1;	/* bit 17(short receive event detected) */
+		u32 asw_false_carrier_event:1;	/* bit 18(bad carrier since last good packet) */
+		u32 asw_code_err:1;	/* bit 19(one or more nibbles signalled as errors) */
+		u32 asw_CRC_err:1;		/* bit 20(CRC error) */
+		u32 asw_len_chk_err:1;	/* bit 21(frame length field incorrect) */
+		u32 asw_too_long:1;	/* bit 22(frame length > 1518 bytes) */
+		u32 asw_OK:1;		/* bit 23(valid CRC + no code error) */
+		u32 asw_multicast:1;	/* bit 24(has a multicast address) */
+		u32 asw_broadcast:1;	/* bit 25(has a broadcast address) */
+		u32 asw_dribble_nibble:1;	/* bit 26(spurious bits after EOP) */
+		u32 asw_control_frame:1;	/* bit 27(is a control frame) */
+		u32 asw_pause_frame:1;	/* bit 28(is a pause frame) */
+		u32 asw_unsupported_op:1;	/* bit 29(unsupported OP code) */
+		u32 asw_VLAN_tag:1;	/* bit 30(VLAN tag detected) */
+		u32 asw_long_evt:1;	/* bit 31(Rx long event) */
 #if 0
-		u32 asw_trunc:1;		// bit 31(Rx frame truncated)
+		u32 asw_trunc:1;		/* bit 31(Rx frame truncated) */
 #endif
 #endif
 	} bits;
@@ -188,15 +188,15 @@ typedef union _PKT_STAT_DESC_WORD1_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:4;	// bits 28-31
-		u32 ri:2;		// bits 26-27(Ring Index)
-		u32 bi:10;		// bits 16-25(Buffer Index)
-		u32 length:16;	// bit 0-15(length in bytes)
+		u32 unused:4;	/* bits 28-31 */
+		u32 ri:2;		/* bits 26-27(Ring Index) */
+		u32 bi:10;		/* bits 16-25(Buffer Index) */
+		u32 length:16;	/* bit 0-15(length in bytes) */
 #else
-		u32 length:16;	// bit 0-15(length in bytes)
-		u32 bi:10;		// bits 16-25(Buffer Index)
-		u32 ri:2;		// bits 26-27(Ring Index)
-		u32 unused:4;	// bits 28-31
+		u32 length:16;	/* bit 0-15(length in bytes) */
+		u32 bi:10;		/* bits 16-25(Buffer Index) */
+		u32 ri:2;		/* bits 26-27(Ring Index) */
+		u32 unused:4;	/* bits 28-31 */
 #endif
 	} bits;
 } PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t;
@@ -217,19 +217,19 @@ typedef union _rxstat_word0_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 FBR1unused:5;	// bits 27-31
-		u32 FBR1wrap:1;	// bit 26
-		u32 FBR1offset:10;	// bits 16-25
-		u32 FBR0unused:5;	// bits 11-15
-		u32 FBR0wrap:1;	// bit 10
-		u32 FBR0offset:10;	// bits 0-9
+		u32 FBR1unused:5;	/* bits 27-31 */
+		u32 FBR1wrap:1;	/* bit 26 */
+		u32 FBR1offset:10;	/* bits 16-25 */
+		u32 FBR0unused:5;	/* bits 11-15 */
+		u32 FBR0wrap:1;	/* bit 10 */
+		u32 FBR0offset:10;	/* bits 0-9 */
 #else
-		u32 FBR0offset:10;	// bits 0-9
-		u32 FBR0wrap:1;	// bit 10
-		u32 FBR0unused:5;	// bits 11-15
-		u32 FBR1offset:10;	// bits 16-25
-		u32 FBR1wrap:1;	// bit 26
-		u32 FBR1unused:5;	// bits 27-31
+		u32 FBR0offset:10;	/* bits 0-9 */
+		u32 FBR0wrap:1;	/* bit 10 */
+		u32 FBR0unused:5;	/* bits 11-15 */
+		u32 FBR1offset:10;	/* bits 16-25 */
+		u32 FBR1wrap:1;	/* bit 26 */
+		u32 FBR1unused:5;	/* bits 27-31 */
 #endif
 	} bits;
 } RXSTAT_WORD0_t, *PRXSTAT_WORD0_t;
@@ -243,15 +243,15 @@ typedef union _rxstat_word1_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 PSRunused:3;	// bits 29-31
-		u32 PSRwrap:1;	// bit 28
-		u32 PSRoffset:12;	// bits 16-27
-		u32 reserved:16;	// bits 0-15
+		u32 PSRunused:3;	/* bits 29-31 */
+		u32 PSRwrap:1;	/* bit 28 */
+		u32 PSRoffset:12;	/* bits 16-27 */
+		u32 reserved:16;	/* bits 0-15 */
 #else
-		u32 reserved:16;	// bits 0-15
-		u32 PSRoffset:12;	// bits 16-27
-		u32 PSRwrap:1;	// bit 28
-		u32 PSRunused:3;	// bits 29-31
+		u32 reserved:16;	/* bits 0-15 */
+		u32 PSRoffset:12;	/* bits 16-27 */
+		u32 PSRwrap:1;	/* bit 28 */
+		u32 PSRunused:3;	/* bits 29-31 */
 #endif
 	} bits;
 } RXSTAT_WORD1_t, *PRXSTAT_WORD1_t;
@@ -302,7 +302,7 @@ typedef struct _rx_ring_t {
 	dma_addr_t Fbr0MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
 	uint64_t Fbr0Realpa;
 	uint64_t Fbr0offset;
-	DMA10W_t local_Fbr0_full;
+	u32 local_Fbr0_full;
 	u32 Fbr0NumEntries;
 	u32 Fbr0BufferSize;
 #endif
@@ -313,7 +313,7 @@ typedef struct _rx_ring_t {
 	uint64_t Fbr1Realpa;
 	uint64_t Fbr1offset;
 	FBRLOOKUPTABLE *Fbr[2];
-	DMA10W_t local_Fbr1_full;
+	u32 local_Fbr1_full;
 	u32 Fbr1NumEntries;
 	u32 Fbr1BufferSize;
 
diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c
index 30eaac4..94f7752 100644
--- a/drivers/staging/et131x/et1310_tx.c
+++ b/drivers/staging/et131x/et1310_tx.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -56,7 +56,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/pci.h>
@@ -74,9 +73,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -94,18 +93,14 @@
 
 #include "et1310_tx.h"
 
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
 
-static void et131x_update_tcb_list(struct et131x_adapter *pAdapter);
-static void et131x_check_send_wait_list(struct et131x_adapter *pAdapter);
-static inline void et131x_free_send_packet(struct et131x_adapter *pAdapter,
+static void et131x_update_tcb_list(struct et131x_adapter *etdev);
+static void et131x_check_send_wait_list(struct et131x_adapter *etdev);
+static inline void et131x_free_send_packet(struct et131x_adapter *etdev,
 					   PMP_TCB pMpTcb);
 static int et131x_send_packet(struct sk_buff *skb,
-			      struct et131x_adapter *pAdapter);
-static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb);
+			      struct et131x_adapter *etdev);
+static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb);
 
 /**
  * et131x_tx_dma_memory_alloc
@@ -124,14 +119,11 @@ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
 	int desc_size = 0;
 	TX_RING_t *tx_ring = &adapter->TxRing;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Allocate memory for the TCB's (Transmit Control Block) */
-	adapter->TxRing.MpTcbMem = (MP_TCB *) kcalloc(NUM_TCB, sizeof(MP_TCB),
+	adapter->TxRing.MpTcbMem = (MP_TCB *)kcalloc(NUM_TCB, sizeof(MP_TCB),
 						      GFP_ATOMIC | GFP_DMA);
 	if (!adapter->TxRing.MpTcbMem) {
-		DBG_ERROR(et131x_dbginfo, "Cannot alloc memory for TCBs\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&adapter->pdev->dev, "Cannot alloc memory for TCBs\n");
 		return -ENOMEM;
 	}
 
@@ -143,8 +135,7 @@ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
 	    (PTX_DESC_ENTRY_t) pci_alloc_consistent(adapter->pdev, desc_size,
 						    &tx_ring->pTxDescRingPa);
 	if (!adapter->TxRing.pTxDescRingVa) {
-		DBG_ERROR(et131x_dbginfo, "Cannot alloc memory for Tx Ring\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&adapter->pdev->dev, "Cannot alloc memory for Tx Ring\n");
 		return -ENOMEM;
 	}
 
@@ -169,9 +160,8 @@ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
 						    sizeof(TX_STATUS_BLOCK_t),
 						    &tx_ring->pTxStatusPa);
 	if (!adapter->TxRing.pTxStatusPa) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Cannot alloc memory for Tx status block\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&adapter->pdev->dev,
+				  "Cannot alloc memory for Tx status block\n");
 		return -ENOMEM;
 	}
 
@@ -180,13 +170,11 @@ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
 						      NIC_MIN_PACKET_SIZE,
 						      &tx_ring->pTxDummyBlkPa);
 	if (!adapter->TxRing.pTxDummyBlkPa) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Cannot alloc memory for Tx dummy buffer\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&adapter->pdev->dev,
+			"Cannot alloc memory for Tx dummy buffer\n");
 		return -ENOMEM;
 	}
 
-	DBG_LEAVE(et131x_dbginfo);
 	return 0;
 }
 
@@ -200,8 +188,6 @@ void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
 {
 	int desc_size = 0;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	if (adapter->TxRing.pTxDescRingVa) {
 		/* Free memory relating to Tx rings here */
 		adapter->TxRing.pTxDescRingVa -= adapter->TxRing.TxDescOffset;
@@ -238,32 +224,25 @@ void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
 	}
 
 	/* Free the memory for MP_TCB structures */
-	if (adapter->TxRing.MpTcbMem) {
-		kfree(adapter->TxRing.MpTcbMem);
-		adapter->TxRing.MpTcbMem = NULL;
-	}
-
-	DBG_LEAVE(et131x_dbginfo);
+	kfree(adapter->TxRing.MpTcbMem);
 }
 
 /**
  * ConfigTxDmaRegs - Set up the tx dma section of the JAGCore.
- * @adapter: pointer to our private adapter structure
+ * @etdev: pointer to our private adapter structure
  */
-void ConfigTxDmaRegs(struct et131x_adapter *pAdapter)
+void ConfigTxDmaRegs(struct et131x_adapter *etdev)
 {
-	struct _TXDMA_t __iomem *pTxDma = &pAdapter->CSRAddress->txdma;
-
-	DBG_ENTER(et131x_dbginfo);
+	struct _TXDMA_t __iomem *txdma = &etdev->regs->txdma;
 
 	/* Load the hardware with the start of the transmit descriptor ring. */
-	writel((uint32_t) (pAdapter->TxRing.pTxDescRingAdjustedPa >> 32),
-	       &pTxDma->pr_base_hi);
-	writel((uint32_t) pAdapter->TxRing.pTxDescRingAdjustedPa,
-	       &pTxDma->pr_base_lo);
+	writel((uint32_t) (etdev->TxRing.pTxDescRingAdjustedPa >> 32),
+	       &txdma->pr_base_hi);
+	writel((uint32_t) etdev->TxRing.pTxDescRingAdjustedPa,
+	       &txdma->pr_base_lo);
 
 	/* Initialise the transmit DMA engine */
-	writel(NUM_DESC_PER_RING_TX - 1, &pTxDma->pr_num_des.value);
+	writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des.value);
 
 	/* Load the completion writeback physical address
 	 *
@@ -272,57 +251,44 @@ void ConfigTxDmaRegs(struct et131x_adapter *pAdapter)
 	 * are ever returned, make sure the high part is retrieved here before
 	 * storing the adjusted address.
 	 */
-	writel(0, &pTxDma->dma_wb_base_hi);
-	writel(pAdapter->TxRing.pTxStatusPa, &pTxDma->dma_wb_base_lo);
-
-	memset(pAdapter->TxRing.pTxStatusVa, 0, sizeof(TX_STATUS_BLOCK_t));
+	writel(0, &txdma->dma_wb_base_hi);
+	writel(etdev->TxRing.pTxStatusPa, &txdma->dma_wb_base_lo);
 
-	writel(0, &pTxDma->service_request.value);
-	pAdapter->TxRing.txDmaReadyToSend.value = 0;
+	memset(etdev->TxRing.pTxStatusVa, 0, sizeof(TX_STATUS_BLOCK_t));
 
-	DBG_LEAVE(et131x_dbginfo);
+	writel(0, &txdma->service_request);
+	etdev->TxRing.txDmaReadyToSend = 0;
 }
 
 /**
  * et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  */
-void et131x_tx_dma_disable(struct et131x_adapter *pAdapter)
+void et131x_tx_dma_disable(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Setup the tramsmit dma configuration register */
-	writel(0x101, &pAdapter->CSRAddress->txdma.csr.value);
-
-	DBG_LEAVE(et131x_dbginfo);
+	writel(ET_TXDMA_CSR_HALT|ET_TXDMA_SNGL_EPKT,
+					&etdev->regs->txdma.csr);
 }
 
 /**
  * et131x_tx_dma_enable - re-start of Tx_DMA on the ET1310.
- * @pAdapter: pointer to our adapter structure
+ * @etdev: pointer to our adapter structure
  *
  * Mainly used after a return to the D0 (full-power) state from a lower state.
  */
-void et131x_tx_dma_enable(struct et131x_adapter *pAdapter)
+void et131x_tx_dma_enable(struct et131x_adapter *etdev)
 {
-	DBG_ENTER(et131x_dbginfo);
-
-	if (pAdapter->RegistryPhyLoopbk) {
-	/* TxDMA is disabled for loopback operation. */
-		writel(0x101, &pAdapter->CSRAddress->txdma.csr.value);
-	} else {
-		TXDMA_CSR_t csr = { 0 };
-
+	u32 csr = ET_TXDMA_SNGL_EPKT;
+	if (etdev->RegistryPhyLoopbk)
+		/* TxDMA is disabled for loopback operation. */
+		csr |= ET_TXDMA_CSR_HALT;
+	else
 		/* Setup the transmit dma configuration register for normal
 		 * operation
 		 */
-		csr.bits.sngl_epkt_mode = 1;
-		csr.bits.halt = 0;
-		csr.bits.cache_thrshld = pAdapter->RegistryDMACache;
-		writel(csr.value, &pAdapter->CSRAddress->txdma.csr.value);
-	}
-
-	DBG_LEAVE(et131x_dbginfo);
+		csr |= PARM_DMA_CACHE_DEF << ET_TXDMA_CACHE_SHIFT;
+	writel(csr, &etdev->regs->txdma.csr);
 }
 
 /**
@@ -335,8 +301,6 @@ void et131x_init_send(struct et131x_adapter *adapter)
 	uint32_t TcbCount;
 	TX_RING_t *tx_ring;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Setup some convenience pointers */
 	tx_ring = &adapter->TxRing;
 	pMpTcb = adapter->TxRing.MpTcbMem;
@@ -366,8 +330,6 @@ void et131x_init_send(struct et131x_adapter *adapter)
 	tx_ring->CurrSendTail = (PMP_TCB) NULL;
 
 	INIT_LIST_HEAD(&adapter->TxRing.SendWaitQueue);
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
@@ -380,11 +342,9 @@ void et131x_init_send(struct et131x_adapter *adapter)
 int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
 {
 	int status = 0;
-	struct et131x_adapter *pAdapter = NULL;
-
-	DBG_TX_ENTER(et131x_dbginfo);
+	struct et131x_adapter *etdev = NULL;
 
-	pAdapter = netdev_priv(netdev);
+	etdev = netdev_priv(netdev);
 
 	/* Send these packets
 	 *
@@ -393,30 +353,29 @@ int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
 	 */
 
 	/* Queue is not empty or TCB is not available */
-	if (!list_empty(&pAdapter->TxRing.SendWaitQueue) ||
-	    MP_TCB_RESOURCES_NOT_AVAILABLE(pAdapter)) {
+	if (!list_empty(&etdev->TxRing.SendWaitQueue) ||
+	    MP_TCB_RESOURCES_NOT_AVAILABLE(etdev)) {
 		/* NOTE: If there's an error on send, no need to queue the
 		 * packet under Linux; if we just send an error up to the
 		 * netif layer, it will resend the skb to us.
 		 */
-		DBG_VERBOSE(et131x_dbginfo, "TCB Resources Not Available\n");
 		status = -ENOMEM;
 	} else {
 		/* We need to see if the link is up; if it's not, make the
 		 * netif layer think we're good and drop the packet
 		 */
-		//if( MP_SHOULD_FAIL_SEND( pAdapter ) || pAdapter->DriverNoPhyAccess )
-		if (MP_SHOULD_FAIL_SEND(pAdapter) || pAdapter->DriverNoPhyAccess
+		/*
+		 * if( MP_SHOULD_FAIL_SEND( etdev ) ||
+		 *  etdev->DriverNoPhyAccess )
+		 */
+		if (MP_SHOULD_FAIL_SEND(etdev) || etdev->DriverNoPhyAccess
 		    || !netif_carrier_ok(netdev)) {
-			DBG_VERBOSE(et131x_dbginfo,
-				    "Can't Tx, Link is DOWN; drop the packet\n");
-
 			dev_kfree_skb_any(skb);
 			skb = NULL;
 
-			pAdapter->net_stats.tx_dropped++;
+			etdev->net_stats.tx_dropped++;
 		} else {
-			status = et131x_send_packet(skb, pAdapter);
+			status = et131x_send_packet(skb, etdev);
 
 			if (status == -ENOMEM) {
 
@@ -425,147 +384,113 @@ int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
 				 * send an error up to the netif layer, it
 				 * will resend the skb to us.
 				 */
-				DBG_WARNING(et131x_dbginfo,
-					    "Resources problem, Queue tx packet\n");
 			} else if (status != 0) {
 				/* On any other error, make netif think we're
 				 * OK and drop the packet
 				 */
-				DBG_WARNING(et131x_dbginfo,
-					    "General error, drop packet\n");
-
 				dev_kfree_skb_any(skb);
 				skb = NULL;
-
-				pAdapter->net_stats.tx_dropped++;
+				etdev->net_stats.tx_dropped++;
 			}
 		}
 	}
-
-	DBG_TX_LEAVE(et131x_dbginfo);
 	return status;
 }
 
 /**
  * et131x_send_packet - Do the work to send a packet
  * @skb: the packet(s) to send
- * @pAdapter: a pointer to the device's private adapter structure
+ * @etdev: a pointer to the device's private adapter structure
  *
  * Return 0 in almost all cases; non-zero value in extreme hard failure only.
  *
  * Assumption: Send spinlock has been acquired
  */
 static int et131x_send_packet(struct sk_buff *skb,
-			      struct et131x_adapter *pAdapter)
+			      struct et131x_adapter *etdev)
 {
 	int status = 0;
 	PMP_TCB pMpTcb = NULL;
-	uint16_t *pShBufVa;
-	unsigned long lockflags;
-
-	DBG_TX_ENTER(et131x_dbginfo);
-
-	/* Is our buffer scattered, or continuous? */
-	if (skb_shinfo(skb)->nr_frags == 0) {
-		DBG_TX(et131x_dbginfo, "Scattered buffer: NO\n");
-	} else {
-		DBG_TX(et131x_dbginfo, "Scattered buffer: YES, Num Frags: %d\n",
-		       skb_shinfo(skb)->nr_frags);
-	}
+	uint16_t *shbufva;
+	unsigned long flags;
 
 	/* All packets must have at least a MAC address and a protocol type */
 	if (skb->len < ETH_HLEN) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Packet size < ETH_HLEN (14 bytes)\n");
-		DBG_LEAVE(et131x_dbginfo);
 		return -EIO;
 	}
 
 	/* Get a TCB for this packet */
-	spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags);
+	spin_lock_irqsave(&etdev->TCBReadyQLock, flags);
 
-	pMpTcb = pAdapter->TxRing.TCBReadyQueueHead;
+	pMpTcb = etdev->TxRing.TCBReadyQueueHead;
 
 	if (pMpTcb == NULL) {
-		spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
-
-		DBG_WARNING(et131x_dbginfo, "Can't obtain a TCB\n");
-		DBG_TX_LEAVE(et131x_dbginfo);
+		spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
 		return -ENOMEM;
 	}
 
-	pAdapter->TxRing.TCBReadyQueueHead = pMpTcb->Next;
+	etdev->TxRing.TCBReadyQueueHead = pMpTcb->Next;
 
-	if (pAdapter->TxRing.TCBReadyQueueHead == NULL) {
-		pAdapter->TxRing.TCBReadyQueueTail = NULL;
-	}
+	if (etdev->TxRing.TCBReadyQueueHead == NULL)
+		etdev->TxRing.TCBReadyQueueTail = NULL;
 
-	spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
+	spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
 
 	pMpTcb->PacketLength = skb->len;
 	pMpTcb->Packet = skb;
 
 	if ((skb->data != NULL) && ((skb->len - skb->data_len) >= 6)) {
-		pShBufVa = (uint16_t *) skb->data;
+		shbufva = (uint16_t *) skb->data;
 
-		if ((pShBufVa[0] == 0xffff) &&
-		    (pShBufVa[1] == 0xffff) && (pShBufVa[2] == 0xffff)) {
-			MP_SET_FLAG(pMpTcb, fMP_DEST_BROAD);
-		} else if ((pShBufVa[0] & 0x3) == 0x0001) {
-			MP_SET_FLAG(pMpTcb, fMP_DEST_MULTI);
+		if ((shbufva[0] == 0xffff) &&
+		    (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff)) {
+			pMpTcb->Flags |= fMP_DEST_BROAD;
+		} else if ((shbufva[0] & 0x3) == 0x0001) {
+			pMpTcb->Flags |=  fMP_DEST_MULTI;
 		}
 	}
 
 	pMpTcb->Next = NULL;
 
 	/* Call the NIC specific send handler. */
-	if (status == 0) {
-		status = nic_send_packet(pAdapter, pMpTcb);
-	}
+	if (status == 0)
+		status = nic_send_packet(etdev, pMpTcb);
 
 	if (status != 0) {
-		spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags);
+		spin_lock_irqsave(&etdev->TCBReadyQLock, flags);
 
-		if (pAdapter->TxRing.TCBReadyQueueTail) {
-			pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb;
+		if (etdev->TxRing.TCBReadyQueueTail) {
+			etdev->TxRing.TCBReadyQueueTail->Next = pMpTcb;
 		} else {
 			/* Apparently ready Q is empty. */
-			pAdapter->TxRing.TCBReadyQueueHead = pMpTcb;
+			etdev->TxRing.TCBReadyQueueHead = pMpTcb;
 		}
 
-		pAdapter->TxRing.TCBReadyQueueTail = pMpTcb;
-
-		spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
-
-		DBG_TX_LEAVE(et131x_dbginfo);
+		etdev->TxRing.TCBReadyQueueTail = pMpTcb;
+		spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
 		return status;
 	}
-
-	DBG_ASSERT(pAdapter->TxRing.nBusySend <= NUM_TCB);
-
-	DBG_TX_LEAVE(et131x_dbginfo);
+	WARN_ON(etdev->TxRing.nBusySend > NUM_TCB);
 	return 0;
 }
 
 /**
  * nic_send_packet - NIC specific send handler for version B silicon.
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  * @pMpTcb: pointer to MP_TCB
  *
  * Returns 0 or errno.
  */
-static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
+static int nic_send_packet(struct et131x_adapter *etdev, PMP_TCB pMpTcb)
 {
 	uint32_t loopIndex;
 	TX_DESC_ENTRY_t CurDesc[24];
 	uint32_t FragmentNumber = 0;
-	uint32_t iThisCopy, iRemainder;
+	uint32_t thiscopy, remainder;
 	struct sk_buff *pPacket = pMpTcb->Packet;
 	uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1;
 	struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0];
-	unsigned long lockflags1, lockflags2;
-
-	DBG_TX_ENTER(et131x_dbginfo);
+	unsigned long flags;
 
 	/* Part of the optimizations of this send routine restrict us to
 	 * sending 24 fragments at a pass.  In practice we should never see
@@ -576,7 +501,6 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 	 * although it is less efficient.
 	 */
 	if (FragListCount > 23) {
-		DBG_TX_LEAVE(et131x_dbginfo);
 		return -EIO;
 	}
 
@@ -597,16 +521,7 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 			 * doesn't seem to like large fragments.
 			 */
 			if ((pPacket->len - pPacket->data_len) <= 1514) {
-				DBG_TX(et131x_dbginfo,
-				       "Got packet of length %d, "
-				       "filling desc entry %d, "
-				       "TCB: 0x%p\n",
-				       (pPacket->len - pPacket->data_len),
-				       pAdapter->TxRing.txDmaReadyToSend.bits.
-				       val, pMpTcb);
-
 				CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
-
 				CurDesc[FragmentNumber].word2.bits.
 				    length_in_bytes =
 				    pPacket->len - pPacket->data_len;
@@ -620,22 +535,13 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 				 * subsystem)
 				 */
 				CurDesc[FragmentNumber++].DataBufferPtrLow =
-				    pci_map_single(pAdapter->pdev,
+				    pci_map_single(etdev->pdev,
 						   pPacket->data,
 						   pPacket->len -
 						   pPacket->data_len,
 						   PCI_DMA_TODEVICE);
 			} else {
-				DBG_TX(et131x_dbginfo,
-				       "Got packet of length %d, "
-				       "filling desc entry %d, "
-				       "TCB: 0x%p\n",
-				       (pPacket->len - pPacket->data_len),
-				       pAdapter->TxRing.txDmaReadyToSend.bits.
-				       val, pMpTcb);
-
 				CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
-
 				CurDesc[FragmentNumber].word2.bits.
 				    length_in_bytes =
 				    ((pPacket->len - pPacket->data_len) / 2);
@@ -649,7 +555,7 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 				 * subsystem)
 				 */
 				CurDesc[FragmentNumber++].DataBufferPtrLow =
-				    pci_map_single(pAdapter->pdev,
+				    pci_map_single(etdev->pdev,
 						   pPacket->data,
 						   ((pPacket->len -
 						     pPacket->data_len) / 2),
@@ -669,7 +575,7 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 				 * subsystem)
 				 */
 				CurDesc[FragmentNumber++].DataBufferPtrLow =
-				    pci_map_single(pAdapter->pdev,
+				    pci_map_single(etdev->pdev,
 						   pPacket->data +
 						   ((pPacket->len -
 						     pPacket->data_len) / 2),
@@ -678,16 +584,7 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 						   PCI_DMA_TODEVICE);
 			}
 		} else {
-			DBG_TX(et131x_dbginfo,
-			       "Got packet of length %d,"
-			       "filling desc entry %d\n"
-			       "TCB: 0x%p\n",
-			       pFragList[loopIndex].size,
-			       pAdapter->TxRing.txDmaReadyToSend.bits.val,
-			       pMpTcb);
-
 			CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
-
 			CurDesc[FragmentNumber].word2.bits.length_in_bytes =
 			    pFragList[loopIndex - 1].size;
 
@@ -698,7 +595,7 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 			 * addressable (as defined by the pci/dma subsystem)
 			 */
 			CurDesc[FragmentNumber++].DataBufferPtrLow =
-			    pci_map_page(pAdapter->pdev,
+			    pci_map_page(etdev->pdev,
 					 pFragList[loopIndex - 1].page,
 					 pFragList[loopIndex - 1].page_offset,
 					 pFragList[loopIndex - 1].size,
@@ -706,16 +603,14 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 		}
 	}
 
-	if (FragmentNumber == 0) {
-		DBG_WARNING(et131x_dbginfo, "No. frags is 0\n");
+	if (FragmentNumber == 0)
 		return -EIO;
-	}
 
-	if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
-		if (++pAdapter->TxRing.TxPacketsSinceLastinterrupt ==
-		    pAdapter->RegistryTxNumBuffers) {
+	if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) {
+		if (++etdev->TxRing.TxPacketsSinceLastinterrupt ==
+		    PARM_TX_NUM_BUFS_DEF) {
 			CurDesc[FragmentNumber - 1].word3.value = 0x5;
-			pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0;
+			etdev->TxRing.TxPacketsSinceLastinterrupt = 0;
 		} else {
 			CurDesc[FragmentNumber - 1].word3.value = 0x1;
 		}
@@ -725,529 +620,101 @@ static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
 
 	CurDesc[0].word3.bits.f = 1;
 
-	pMpTcb->WrIndexStart = pAdapter->TxRing.txDmaReadyToSend;
+	pMpTcb->WrIndexStart = etdev->TxRing.txDmaReadyToSend;
 	pMpTcb->PacketStaleCount = 0;
 
-	spin_lock_irqsave(&pAdapter->SendHWLock, lockflags1);
+	spin_lock_irqsave(&etdev->SendHWLock, flags);
 
-	iThisCopy =
-	    NUM_DESC_PER_RING_TX - pAdapter->TxRing.txDmaReadyToSend.bits.val;
+	thiscopy = NUM_DESC_PER_RING_TX -
+				INDEX10(etdev->TxRing.txDmaReadyToSend);
 
-	if (iThisCopy >= FragmentNumber) {
-		iRemainder = 0;
-		iThisCopy = FragmentNumber;
+	if (thiscopy >= FragmentNumber) {
+		remainder = 0;
+		thiscopy = FragmentNumber;
 	} else {
-		iRemainder = FragmentNumber - iThisCopy;
+		remainder = FragmentNumber - thiscopy;
 	}
 
-	memcpy(pAdapter->TxRing.pTxDescRingVa +
-	       pAdapter->TxRing.txDmaReadyToSend.bits.val, CurDesc,
-	       sizeof(TX_DESC_ENTRY_t) * iThisCopy);
+	memcpy(etdev->TxRing.pTxDescRingVa +
+	       INDEX10(etdev->TxRing.txDmaReadyToSend), CurDesc,
+	       sizeof(TX_DESC_ENTRY_t) * thiscopy);
 
-	pAdapter->TxRing.txDmaReadyToSend.bits.val += iThisCopy;
+	add_10bit(&etdev->TxRing.txDmaReadyToSend, thiscopy);
 
-	if ((pAdapter->TxRing.txDmaReadyToSend.bits.val == 0) ||
-	    (pAdapter->TxRing.txDmaReadyToSend.bits.val ==
-	     NUM_DESC_PER_RING_TX)) {
-		if (pAdapter->TxRing.txDmaReadyToSend.bits.wrap) {
-			pAdapter->TxRing.txDmaReadyToSend.value = 0;
-		} else {
-			pAdapter->TxRing.txDmaReadyToSend.value = 0x400;
-		}
+	if (INDEX10(etdev->TxRing.txDmaReadyToSend)== 0 ||
+	    INDEX10(etdev->TxRing.txDmaReadyToSend) == NUM_DESC_PER_RING_TX) {
+	     	etdev->TxRing.txDmaReadyToSend &= ~ET_DMA10_MASK;
+	     	etdev->TxRing.txDmaReadyToSend ^= ET_DMA10_WRAP;
 	}
 
-	if (iRemainder) {
-		memcpy(pAdapter->TxRing.pTxDescRingVa,
-		       CurDesc + iThisCopy,
-		       sizeof(TX_DESC_ENTRY_t) * iRemainder);
+	if (remainder) {
+		memcpy(etdev->TxRing.pTxDescRingVa,
+		       CurDesc + thiscopy,
+		       sizeof(TX_DESC_ENTRY_t) * remainder);
 
-		pAdapter->TxRing.txDmaReadyToSend.bits.val += iRemainder;
+		add_10bit(&etdev->TxRing.txDmaReadyToSend, remainder);
 	}
 
-	if (pAdapter->TxRing.txDmaReadyToSend.bits.val == 0) {
-		if (pAdapter->TxRing.txDmaReadyToSend.value) {
-			pMpTcb->WrIndex.value = NUM_DESC_PER_RING_TX - 1;
-		} else {
-			pMpTcb->WrIndex.value =
-			    0x400 | (NUM_DESC_PER_RING_TX - 1);
-		}
-	} else {
-		pMpTcb->WrIndex.value =
-		    pAdapter->TxRing.txDmaReadyToSend.value - 1;
-	}
+	if (INDEX10(etdev->TxRing.txDmaReadyToSend) == 0) {
+		if (etdev->TxRing.txDmaReadyToSend)
+			pMpTcb->WrIndex = NUM_DESC_PER_RING_TX - 1;
+		else
+			pMpTcb->WrIndex= ET_DMA10_WRAP | (NUM_DESC_PER_RING_TX - 1);
+	} else
+		pMpTcb->WrIndex = etdev->TxRing.txDmaReadyToSend - 1;
 
-	spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags2);
+	spin_lock(&etdev->TCBSendQLock);
 
-	if (pAdapter->TxRing.CurrSendTail) {
-		pAdapter->TxRing.CurrSendTail->Next = pMpTcb;
-	} else {
-		pAdapter->TxRing.CurrSendHead = pMpTcb;
-	}
+	if (etdev->TxRing.CurrSendTail)
+		etdev->TxRing.CurrSendTail->Next = pMpTcb;
+	else
+		etdev->TxRing.CurrSendHead = pMpTcb;
 
-	pAdapter->TxRing.CurrSendTail = pMpTcb;
+	etdev->TxRing.CurrSendTail = pMpTcb;
 
-	DBG_ASSERT(pMpTcb->Next == NULL);
+	WARN_ON(pMpTcb->Next != NULL);
 
-	pAdapter->TxRing.nBusySend++;
+	etdev->TxRing.nBusySend++;
 
-	spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags2);
+	spin_unlock(&etdev->TCBSendQLock);
 
 	/* Write the new write pointer back to the device. */
-	writel(pAdapter->TxRing.txDmaReadyToSend.value,
-	       &pAdapter->CSRAddress->txdma.service_request.value);
+	writel(etdev->TxRing.txDmaReadyToSend,
+	       &etdev->regs->txdma.service_request);
 
 	/* For Gig only, we use Tx Interrupt coalescing.  Enable the software
 	 * timer to wake us up if this packet isn't followed by N more.
 	 */
-	if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
-		writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO,
-		       &pAdapter->CSRAddress->global.watchdog_timer);
+	if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) {
+		writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO,
+		       &etdev->regs->global.watchdog_timer);
 	}
+	spin_unlock_irqrestore(&etdev->SendHWLock, flags);
 
-	spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1);
-
-	DBG_TX_LEAVE(et131x_dbginfo);
 	return 0;
 }
 
-/*
- * NOTE: For now, keep this older version of NICSendPacket around for
- * reference, even though it's not used
- */
-#if 0
-
-/**
- * NICSendPacket - NIC specific send handler.
- * @pAdapter: pointer to our adapter
- * @pMpTcb: pointer to MP_TCB
- *
- * Returns 0 on succes, errno on failure.
- *
- * This version of the send routine is designed for version A silicon.
- * Assumption - Send spinlock has been acquired.
- */
-static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
-{
-	uint32_t loopIndex, fragIndex, loopEnd;
-	uint32_t iSplitFirstElement = 0;
-	uint32_t SegmentSize = 0;
-	TX_DESC_ENTRY_t CurDesc;
-	TX_DESC_ENTRY_t *CurDescPostCopy = NULL;
-	uint32_t SlotsAvailable;
-	DMA10W_t ServiceComplete;
-	unsigned int lockflags1, lockflags2;
-	struct sk_buff *pPacket = pMpTcb->Packet;
-	uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1;
-	struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0];
-
-	DBG_TX_ENTER(et131x_dbginfo);
-
-	ServiceComplete.value =
-		readl(&pAdapter->CSRAddress->txdma.NewServiceComplete.value);
-
-	/*
-	 * Attempt to fix TWO hardware bugs:
-	 * 1)  NEVER write an odd number of descriptors.
-	 * 2)  If packet length is less than NIC_MIN_PACKET_SIZE, then pad the
-	 *     packet to NIC_MIN_PACKET_SIZE bytes by adding a new last
-	 *     descriptor IN HALF DUPLEX MODE ONLY
-	 * NOTE that (2) interacts with (1).  If the packet is less than
-	 * NIC_MIN_PACKET_SIZE bytes then we will append a descriptor.
-	 * Therefore if it is even now, it will eventually end up odd, and
-	 * so will need adjusting.
-	 *
-	 * VLAN tags get involved since VLAN tags add another one or two
-	 * segments.
-	 */
-	DBG_TX(et131x_dbginfo,
-	       "pMpTcb->PacketLength: %d\n", pMpTcb->PacketLength);
-
-	if ((pAdapter->uiDuplexMode == 0)
-	    && (pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE)) {
-		DBG_TX(et131x_dbginfo,
-		       "HALF DUPLEX mode AND len < MIN_PKT_SIZE\n");
-		if ((FragListCount & 0x1) == 0) {
-			DBG_TX(et131x_dbginfo,
-			       "Even number of descs, split 1st elem\n");
-			iSplitFirstElement = 1;
-			//SegmentSize = pFragList[0].size / 2;
-			SegmentSize = (pPacket->len - pPacket->data_len) / 2;
-		}
-	} else if (FragListCount & 0x1) {
-		DBG_TX(et131x_dbginfo, "Odd number of descs, split 1st elem\n");
-
-		iSplitFirstElement = 1;
-		//SegmentSize = pFragList[0].size / 2;
-		SegmentSize = (pPacket->len - pPacket->data_len) / 2;
-	}
-
-	spin_lock_irqsave(&pAdapter->SendHWLock, lockflags1);
-
-	if (pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ==
-	    ServiceComplete.bits.serv_cpl_wrap) {
-		/* The ring hasn't wrapped.  Slots available should be
-		 * (RING_SIZE) -  the difference between the two pointers.
-		 */
-		SlotsAvailable = NUM_DESC_PER_RING_TX -
-		    (pAdapter->TxRing.txDmaReadyToSend.bits.serv_req -
-		     ServiceComplete.bits.serv_cpl);
-	} else {
-		/* The ring has wrapped.  Slots available should be the
-		 * difference between the two pointers.
-		 */
-		SlotsAvailable = ServiceComplete.bits.serv_cpl -
-		    pAdapter->TxRing.txDmaReadyToSend.bits.serv_req;
-	}
-
-	if ((FragListCount + iSplitFirstElement) > SlotsAvailable) {
-		DBG_WARNING(et131x_dbginfo,
-			    "Not Enough Space in Tx Desc Ring\n");
-		spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1);
-		return -ENOMEM;
-	}
-
-	loopEnd = (FragListCount) + iSplitFirstElement;
-	fragIndex = 0;
-
-	DBG_TX(et131x_dbginfo,
-	       "TCB           : 0x%p\n"
-	       "Packet (SKB)  : 0x%p\t Packet->len: %d\t Packet->data_len: %d\n"
-	       "FragListCount : %d\t iSplitFirstElement: %d\t loopEnd:%d\n",
-	       pMpTcb,
-	       pPacket, pPacket->len, pPacket->data_len,
-	       FragListCount, iSplitFirstElement, loopEnd);
-
-	for (loopIndex = 0; loopIndex < loopEnd; loopIndex++) {
-		if (loopIndex > iSplitFirstElement) {
-			fragIndex++;
-		}
-
-		DBG_TX(et131x_dbginfo,
-		       "In loop, loopIndex: %d\t fragIndex: %d\n", loopIndex,
-		       fragIndex);
-
-		/* If there is something in this element, let's get a
-		 * descriptor from the ring and get the necessary data
-		 */
-		DBG_TX(et131x_dbginfo,
-		       "Packet Length %d,"
-		       "filling desc entry %d\n",
-		       pPacket->len,
-		       pAdapter->TxRing.txDmaReadyToSend.bits.serv_req);
-
-		// NOTE - Should we do a paranoia check here to make sure the fragment
-		// actually has a length? It's HIGHLY unlikely the fragment would
-		// contain no data...
-		if (1) {
-			// NOTE - Currently always getting 32-bit addrs, and dma_addr_t is
-			//        only 32-bit, so leave "high" ptr value out for now
-			CurDesc.DataBufferPtrHigh = 0;
-
-			CurDesc.word2.value = 0;
-			CurDesc.word3.value = 0;
-
-			if (fragIndex == 0) {
-				if (iSplitFirstElement) {
-					DBG_TX(et131x_dbginfo,
-					       "Split first element: YES\n");
-
-					if (loopIndex == 0) {
-						DBG_TX(et131x_dbginfo,
-						       "Got fragment of length %d, fragIndex: %d\n",
-						       pPacket->len -
-						       pPacket->data_len,
-						       fragIndex);
-						DBG_TX(et131x_dbginfo,
-						       "SegmentSize: %d\n",
-						       SegmentSize);
-
-						CurDesc.word2.bits.
-						    length_in_bytes =
-						    SegmentSize;
-						CurDesc.DataBufferPtrLow =
-						    pci_map_single(pAdapter->
-								   pdev,
-								   pPacket->
-								   data,
-								   SegmentSize,
-								   PCI_DMA_TODEVICE);
-						DBG_TX(et131x_dbginfo,
-						       "pci_map_single() returns: 0x%08x\n",
-						       CurDesc.
-						       DataBufferPtrLow);
-					} else {
-						DBG_TX(et131x_dbginfo,
-						       "Got fragment of length %d, fragIndex: %d\n",
-						       pPacket->len -
-						       pPacket->data_len,
-						       fragIndex);
-						DBG_TX(et131x_dbginfo,
-						       "Leftover Size: %d\n",
-						       (pPacket->len -
-							pPacket->data_len -
-							SegmentSize));
-
-						CurDesc.word2.bits.
-						    length_in_bytes =
-						    ((pPacket->len -
-						      pPacket->data_len) -
-						     SegmentSize);
-						CurDesc.DataBufferPtrLow =
-						    pci_map_single(pAdapter->
-								   pdev,
-								   (pPacket->
-								    data +
-								    SegmentSize),
-								   (pPacket->
-								    len -
-								    pPacket->
-								    data_len -
-								    SegmentSize),
-								   PCI_DMA_TODEVICE);
-						DBG_TX(et131x_dbginfo,
-						       "pci_map_single() returns: 0x%08x\n",
-						       CurDesc.
-						       DataBufferPtrLow);
-					}
-				} else {
-					DBG_TX(et131x_dbginfo,
-					       "Split first element: NO\n");
-
-					CurDesc.word2.bits.length_in_bytes =
-					    pPacket->len - pPacket->data_len;
-
-					CurDesc.DataBufferPtrLow =
-					    pci_map_single(pAdapter->pdev,
-							   pPacket->data,
-							   (pPacket->len -
-							    pPacket->data_len),
-							   PCI_DMA_TODEVICE);
-					DBG_TX(et131x_dbginfo,
-					       "pci_map_single() returns: 0x%08x\n",
-					       CurDesc.DataBufferPtrLow);
-				}
-			} else {
-
-				CurDesc.word2.bits.length_in_bytes =
-				    pFragList[fragIndex - 1].size;
-				CurDesc.DataBufferPtrLow =
-				    pci_map_page(pAdapter->pdev,
-						 pFragList[fragIndex - 1].page,
-						 pFragList[fragIndex -
-							   1].page_offset,
-						 pFragList[fragIndex - 1].size,
-						 PCI_DMA_TODEVICE);
-				DBG_TX(et131x_dbginfo,
-				       "pci_map_page() returns: 0x%08x\n",
-				       CurDesc.DataBufferPtrLow);
-			}
-
-			if (loopIndex == 0) {
-				/* This is the first descriptor of the packet
-				 *
-				 * Set the "f" bit to indicate this is the
-				 * first descriptor in the packet.
-				 */
-				DBG_TX(et131x_dbginfo,
-				       "This is our FIRST descriptor\n");
-				CurDesc.word3.bits.f = 1;
-
-				pMpTcb->WrIndexStart =
-				    pAdapter->TxRing.txDmaReadyToSend;
-			}
-
-			if ((loopIndex == (loopEnd - 1)) &&
-			    (pAdapter->uiDuplexMode ||
-			     (pMpTcb->PacketLength >= NIC_MIN_PACKET_SIZE))) {
-				/* This is the Last descriptor of the packet */
-				DBG_TX(et131x_dbginfo,
-				       "THIS is our LAST descriptor\n");
-
-				if (pAdapter->uiLinkSpeed ==
-				    TRUEPHY_SPEED_1000MBPS) {
-					if (++pAdapter->TxRing.
-					    TxPacketsSinceLastinterrupt >=
-					    pAdapter->RegistryTxNumBuffers) {
-						CurDesc.word3.value = 0x5;
-						pAdapter->TxRing.
-						    TxPacketsSinceLastinterrupt
-						    = 0;
-					} else {
-						CurDesc.word3.value = 0x1;
-					}
-				} else {
-					CurDesc.word3.value = 0x5;
-				}
-
-				/* Following index will be used during freeing
-				 * of packet
-				 */
-				pMpTcb->WrIndex =
-				    pAdapter->TxRing.txDmaReadyToSend;
-				pMpTcb->PacketStaleCount = 0;
-			}
-
-			/* Copy the descriptor (filled above) into the
-			 * descriptor ring at the next free entry.  Advance
-			 * the "next free entry" variable
-			 */
-			memcpy(pAdapter->TxRing.pTxDescRingVa +
-			       pAdapter->TxRing.txDmaReadyToSend.bits.serv_req,
-			       &CurDesc, sizeof(TX_DESC_ENTRY_t));
-
-			CurDescPostCopy =
-			    pAdapter->TxRing.pTxDescRingVa +
-			    pAdapter->TxRing.txDmaReadyToSend.bits.serv_req;
-
-			DBG_TX(et131x_dbginfo,
-			       "CURRENT DESCRIPTOR\n"
-			       "\tAddress           : 0x%p\n"
-			       "\tDataBufferPtrHigh : 0x%08x\n"
-			       "\tDataBufferPtrLow  : 0x%08x\n"
-			       "\tword2             : 0x%08x\n"
-			       "\tword3             : 0x%08x\n",
-			       CurDescPostCopy,
-			       CurDescPostCopy->DataBufferPtrHigh,
-			       CurDescPostCopy->DataBufferPtrLow,
-			       CurDescPostCopy->word2.value,
-			       CurDescPostCopy->word3.value);
-
-			if (++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >=
-			    NUM_DESC_PER_RING_TX) {
-				if (pAdapter->TxRing.txDmaReadyToSend.bits.
-				    serv_req_wrap) {
-					pAdapter->TxRing.txDmaReadyToSend.
-					    value = 0;
-				} else {
-					pAdapter->TxRing.txDmaReadyToSend.
-					    value = 0x400;
-				}
-			}
-		}
-	}
-
-	if (pAdapter->uiDuplexMode == 0 &&
-	    pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE) {
-		// NOTE - Same 32/64-bit issue as above...
-		CurDesc.DataBufferPtrHigh = 0x0;
-		CurDesc.DataBufferPtrLow = pAdapter->TxRing.pTxDummyBlkPa;
-		CurDesc.word2.value = 0;
-
-		if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
-			if (++pAdapter->TxRing.TxPacketsSinceLastinterrupt >=
-			    pAdapter->RegistryTxNumBuffers) {
-				CurDesc.word3.value = 0x5;
-				pAdapter->TxRing.TxPacketsSinceLastinterrupt =
-				    0;
-			} else {
-				CurDesc.word3.value = 0x1;
-			}
-		} else {
-			CurDesc.word3.value = 0x5;
-		}
-
-		CurDesc.word2.bits.length_in_bytes =
-		    NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength;
-
-		pMpTcb->WrIndex = pAdapter->TxRing.txDmaReadyToSend;
-
-		memcpy(pAdapter->TxRing.pTxDescRingVa +
-		       pAdapter->TxRing.txDmaReadyToSend.bits.serv_req,
-		       &CurDesc, sizeof(TX_DESC_ENTRY_t));
-
-		CurDescPostCopy =
-		    pAdapter->TxRing.pTxDescRingVa +
-		    pAdapter->TxRing.txDmaReadyToSend.bits.serv_req;
-
-		DBG_TX(et131x_dbginfo,
-		       "CURRENT DESCRIPTOR\n"
-		       "\tAddress           : 0x%p\n"
-		       "\tDataBufferPtrHigh : 0x%08x\n"
-		       "\tDataBufferPtrLow  : 0x%08x\n"
-		       "\tword2             : 0x%08x\n"
-		       "\tword3             : 0x%08x\n",
-		       CurDescPostCopy,
-		       CurDescPostCopy->DataBufferPtrHigh,
-		       CurDescPostCopy->DataBufferPtrLow,
-		       CurDescPostCopy->word2.value,
-		       CurDescPostCopy->word3.value);
-
-		if (++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >=
-		    NUM_DESC_PER_RING_TX) {
-			if (pAdapter->TxRing.txDmaReadyToSend.bits.
-			    serv_req_wrap) {
-				pAdapter->TxRing.txDmaReadyToSend.value = 0;
-			} else {
-				pAdapter->TxRing.txDmaReadyToSend.value = 0x400;
-			}
-		}
-
-		DBG_TX(et131x_dbginfo, "Padding descriptor %d by %d bytes\n",
-		       //pAdapter->TxRing.txDmaReadyToSend.value,
-		       pAdapter->TxRing.txDmaReadyToSend.bits.serv_req,
-		       NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength);
-	}
-
-	spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags2);
-
-	if (pAdapter->TxRing.CurrSendTail) {
-		pAdapter->TxRing.CurrSendTail->Next = pMpTcb;
-	} else {
-		pAdapter->TxRing.CurrSendHead = pMpTcb;
-	}
-
-	pAdapter->TxRing.CurrSendTail = pMpTcb;
-
-	DBG_ASSERT(pMpTcb->Next == NULL);
-
-	pAdapter->TxRing.nBusySend++;
-
-	spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags2);
-
-	/* Write the new write pointer back to the device. */
-	writel(pAdapter->TxRing.txDmaReadyToSend.value,
-	       &pAdapter->CSRAddress->txdma.service_request.value);
-
-#ifdef CONFIG_ET131X_DEBUG
-	DumpDeviceBlock(DBG_TX_ON, pAdapter, 1);
-#endif
-
-	/* For Gig only, we use Tx Interrupt coalescing.  Enable the software
-	 * timer to wake us up if this packet isn't followed by N more.
-	 */
-	if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
-		writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO,
-		       &pAdapter->CSRAddress->global.watchdog_timer);
-	}
-
-	spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1);
-
-	DBG_TX_LEAVE(et131x_dbginfo);
-	return 0;
-}
-
-#endif
 
 /**
  * et131x_free_send_packet - Recycle a MP_TCB, complete the packet if necessary
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  * @pMpTcb: pointer to MP_TCB
  *
  * Assumption - Send spinlock has been acquired
  */
-__inline void et131x_free_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
+inline void et131x_free_send_packet(struct et131x_adapter *etdev,
+							PMP_TCB pMpTcb)
 {
-	unsigned long lockflags;
+	unsigned long flags;
 	TX_DESC_ENTRY_t *desc = NULL;
-	struct net_device_stats *stats = &pAdapter->net_stats;
+	struct net_device_stats *stats = &etdev->net_stats;
 
-	if (MP_TEST_FLAG(pMpTcb, fMP_DEST_BROAD)) {
-		atomic_inc(&pAdapter->Stats.brdcstxmt);
-	} else if (MP_TEST_FLAG(pMpTcb, fMP_DEST_MULTI)) {
-		atomic_inc(&pAdapter->Stats.multixmt);
-	} else {
-		atomic_inc(&pAdapter->Stats.unixmt);
-	}
+	if (pMpTcb->Flags & fMP_DEST_BROAD)
+		atomic_inc(&etdev->Stats.brdcstxmt);
+	else if (pMpTcb->Flags & fMP_DEST_MULTI)
+		atomic_inc(&etdev->Stats.multixmt);
+	else
+		atomic_inc(&etdev->Stats.unixmt);
 
 	if (pMpTcb->Packet) {
 		stats->tx_bytes += pMpTcb->Packet->len;
@@ -1256,60 +723,23 @@ __inline void et131x_free_send_packet(struct et131x_adapter *pAdapter, PMP_TCB p
 		 * corresponding to this packet and umap the fragments
 		 * they point to
 		 */
-		DBG_TX(et131x_dbginfo,
-		       "Unmap descriptors Here\n"
-		       "TCB                  : 0x%p\n"
-		       "TCB Next             : 0x%p\n"
-		       "TCB PacketLength     : %d\n"
-		       "TCB WrIndex.value    : 0x%08x\n"
-		       "TCB WrIndex.bits.val : %d\n"
-		       "TCB WrIndex.value    : 0x%08x\n"
-		       "TCB WrIndex.bits.val : %d\n",
-		       pMpTcb,
-		       pMpTcb->Next,
-		       pMpTcb->PacketLength,
-		       pMpTcb->WrIndexStart.value,
-		       pMpTcb->WrIndexStart.bits.val,
-		       pMpTcb->WrIndex.value,
-		       pMpTcb->WrIndex.bits.val);
-
 		do {
 			desc =
-			    (TX_DESC_ENTRY_t *) (pAdapter->TxRing.
-						 pTxDescRingVa +
-						 pMpTcb->WrIndexStart.bits.val);
-
-			DBG_TX(et131x_dbginfo,
-			       "CURRENT DESCRIPTOR\n"
-			       "\tAddress           : 0x%p\n"
-			       "\tDataBufferPtrHigh : 0x%08x\n"
-			       "\tDataBufferPtrLow  : 0x%08x\n"
-			       "\tword2             : 0x%08x\n"
-			       "\tword3             : 0x%08x\n",
-			       desc,
-			       desc->DataBufferPtrHigh,
-			       desc->DataBufferPtrLow,
-			       desc->word2.value,
-			       desc->word3.value);
-
-			pci_unmap_single(pAdapter->pdev,
+			    (TX_DESC_ENTRY_t *) (etdev->TxRing.pTxDescRingVa +
+			    	INDEX10(pMpTcb->WrIndexStart));
+
+			pci_unmap_single(etdev->pdev,
 					 desc->DataBufferPtrLow,
 					 desc->word2.value, PCI_DMA_TODEVICE);
 
-			if (++pMpTcb->WrIndexStart.bits.val >=
+			add_10bit(&pMpTcb->WrIndexStart, 1);
+			if (INDEX10(pMpTcb->WrIndexStart) >=
 			    NUM_DESC_PER_RING_TX) {
-				if (pMpTcb->WrIndexStart.bits.wrap) {
-					pMpTcb->WrIndexStart.value = 0;
-				} else {
-					pMpTcb->WrIndexStart.value = 0x400;
-				}
+			    	pMpTcb->WrIndexStart &= ~ET_DMA10_MASK;
+			    	pMpTcb->WrIndexStart ^= ET_DMA10_WRAP;
 			}
-		}
-		while (desc != (pAdapter->TxRing.pTxDescRingVa +
-				pMpTcb->WrIndex.bits.val));
-
-		DBG_TX(et131x_dbginfo,
-		       "Free Packet (SKB)   : 0x%p\n", pMpTcb->Packet);
+		} while (desc != (etdev->TxRing.pTxDescRingVa +
+				INDEX10(pMpTcb->WrIndex)));
 
 		dev_kfree_skb_any(pMpTcb->Packet);
 	}
@@ -1317,206 +747,183 @@ __inline void et131x_free_send_packet(struct et131x_adapter *pAdapter, PMP_TCB p
 	memset(pMpTcb, 0, sizeof(MP_TCB));
 
 	/* Add the TCB to the Ready Q */
-	spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags);
+	spin_lock_irqsave(&etdev->TCBReadyQLock, flags);
 
-	pAdapter->Stats.opackets++;
+	etdev->Stats.opackets++;
 
-	if (pAdapter->TxRing.TCBReadyQueueTail) {
-		pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb;
+	if (etdev->TxRing.TCBReadyQueueTail) {
+		etdev->TxRing.TCBReadyQueueTail->Next = pMpTcb;
 	} else {
 		/* Apparently ready Q is empty. */
-		pAdapter->TxRing.TCBReadyQueueHead = pMpTcb;
+		etdev->TxRing.TCBReadyQueueHead = pMpTcb;
 	}
 
-	pAdapter->TxRing.TCBReadyQueueTail = pMpTcb;
+	etdev->TxRing.TCBReadyQueueTail = pMpTcb;
 
-	spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
-
-	DBG_ASSERT(pAdapter->TxRing.nBusySend >= 0);
+	spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags);
+	WARN_ON(etdev->TxRing.nBusySend < 0);
 }
 
 /**
  * et131x_free_busy_send_packets - Free and complete the stopped active sends
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  *
  * Assumption - Send spinlock has been acquired
  */
-void et131x_free_busy_send_packets(struct et131x_adapter *pAdapter)
+void et131x_free_busy_send_packets(struct et131x_adapter *etdev)
 {
 	PMP_TCB pMpTcb;
-	struct list_head *pEntry;
-	unsigned long lockflags;
+	struct list_head *entry;
+	unsigned long flags;
 	uint32_t FreeCounter = 0;
 
-	DBG_ENTER(et131x_dbginfo);
-
-	while (!list_empty(&pAdapter->TxRing.SendWaitQueue)) {
-		spin_lock_irqsave(&pAdapter->SendWaitLock, lockflags);
+	while (!list_empty(&etdev->TxRing.SendWaitQueue)) {
+		spin_lock_irqsave(&etdev->SendWaitLock, flags);
 
-		pAdapter->TxRing.nWaitSend--;
-		spin_unlock_irqrestore(&pAdapter->SendWaitLock, lockflags);
+		etdev->TxRing.nWaitSend--;
+		spin_unlock_irqrestore(&etdev->SendWaitLock, flags);
 
-		pEntry = pAdapter->TxRing.SendWaitQueue.next;
+		entry = etdev->TxRing.SendWaitQueue.next;
 	}
 
-	pAdapter->TxRing.nWaitSend = 0;
+	etdev->TxRing.nWaitSend = 0;
 
 	/* Any packets being sent? Check the first TCB on the send list */
-	spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+	spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
-	pMpTcb = pAdapter->TxRing.CurrSendHead;
+	pMpTcb = etdev->TxRing.CurrSendHead;
 
 	while ((pMpTcb != NULL) && (FreeCounter < NUM_TCB)) {
 		PMP_TCB pNext = pMpTcb->Next;
 
-		pAdapter->TxRing.CurrSendHead = pNext;
+		etdev->TxRing.CurrSendHead = pNext;
 
-		if (pNext == NULL) {
-			pAdapter->TxRing.CurrSendTail = NULL;
-		}
+		if (pNext == NULL)
+			etdev->TxRing.CurrSendTail = NULL;
 
-		pAdapter->TxRing.nBusySend--;
+		etdev->TxRing.nBusySend--;
 
-		spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
-
-		DBG_VERBOSE(et131x_dbginfo, "pMpTcb = 0x%p\n", pMpTcb);
+		spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
 
 		FreeCounter++;
-		MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb);
+		et131x_free_send_packet(etdev, pMpTcb);
 
-		spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+		spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
-		pMpTcb = pAdapter->TxRing.CurrSendHead;
+		pMpTcb = etdev->TxRing.CurrSendHead;
 	}
 
-	if (FreeCounter == NUM_TCB) {
-		DBG_ERROR(et131x_dbginfo,
-			  "MpFreeBusySendPackets exitted loop for a bad reason\n");
-		BUG();
-	}
+	WARN_ON(FreeCounter == NUM_TCB);
 
-	spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+	spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
 
-	pAdapter->TxRing.nBusySend = 0;
-
-	DBG_LEAVE(et131x_dbginfo);
+	etdev->TxRing.nBusySend = 0;
 }
 
 /**
  * et131x_handle_send_interrupt - Interrupt handler for sending processing
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  *
  * Re-claim the send resources, complete sends and get more to send from
  * the send wait queue.
  *
  * Assumption - Send spinlock has been acquired
  */
-void et131x_handle_send_interrupt(struct et131x_adapter *pAdapter)
+void et131x_handle_send_interrupt(struct et131x_adapter *etdev)
 {
-	DBG_TX_ENTER(et131x_dbginfo);
-
 	/* Mark as completed any packets which have been sent by the device. */
-	et131x_update_tcb_list(pAdapter);
+	et131x_update_tcb_list(etdev);
 
 	/* If we queued any transmits because we didn't have any TCBs earlier,
 	 * dequeue and send those packets now, as long as we have free TCBs.
 	 */
-	et131x_check_send_wait_list(pAdapter);
-
-	DBG_TX_LEAVE(et131x_dbginfo);
+	et131x_check_send_wait_list(etdev);
 }
 
 /**
  * et131x_update_tcb_list - Helper routine for Send Interrupt handler
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  *
  * Re-claims the send resources and completes sends.  Can also be called as
  * part of the NIC send routine when the "ServiceComplete" indication has
  * wrapped.
  */
-static void et131x_update_tcb_list(struct et131x_adapter *pAdapter)
+static void et131x_update_tcb_list(struct et131x_adapter *etdev)
 {
-	unsigned long lockflags;
-	DMA10W_t ServiceComplete;
+	unsigned long flags;
+	u32 ServiceComplete;
 	PMP_TCB pMpTcb;
+	u32 index;
 
-	ServiceComplete.value =
-	    readl(&pAdapter->CSRAddress->txdma.NewServiceComplete.value);
+	ServiceComplete = readl(&etdev->regs->txdma.NewServiceComplete);
+	index = INDEX10(ServiceComplete);
 
 	/* Has the ring wrapped?  Process any descriptors that do not have
 	 * the same "wrap" indicator as the current completion indicator
 	 */
-	spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+	spin_lock_irqsave(&etdev->TCBSendQLock, flags);
+
+	pMpTcb = etdev->TxRing.CurrSendHead;
 
-	pMpTcb = pAdapter->TxRing.CurrSendHead;
 	while (pMpTcb &&
-	       ServiceComplete.bits.wrap != pMpTcb->WrIndex.bits.wrap  &&
-	       ServiceComplete.bits.val < pMpTcb->WrIndex.bits.val) {
-		pAdapter->TxRing.nBusySend--;
-		pAdapter->TxRing.CurrSendHead = pMpTcb->Next;
-		if (pMpTcb->Next == NULL) {
-			pAdapter->TxRing.CurrSendTail = NULL;
-		}
+	       ((ServiceComplete ^ pMpTcb->WrIndex) & ET_DMA10_WRAP) &&
+	       index < INDEX10(pMpTcb->WrIndex)) {
+		etdev->TxRing.nBusySend--;
+		etdev->TxRing.CurrSendHead = pMpTcb->Next;
+		if (pMpTcb->Next == NULL)
+			etdev->TxRing.CurrSendTail = NULL;
 
-		spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
-		MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb);
-		spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+		spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
+		et131x_free_send_packet(etdev, pMpTcb);
+		spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
 		/* Goto the next packet */
-		pMpTcb = pAdapter->TxRing.CurrSendHead;
+		pMpTcb = etdev->TxRing.CurrSendHead;
 	}
 	while (pMpTcb &&
-	       ServiceComplete.bits.wrap == pMpTcb->WrIndex.bits.wrap &&
-	       ServiceComplete.bits.val > pMpTcb->WrIndex.bits.val) {
-		pAdapter->TxRing.nBusySend--;
-		pAdapter->TxRing.CurrSendHead = pMpTcb->Next;
-		if (pMpTcb->Next == NULL) {
-			pAdapter->TxRing.CurrSendTail = NULL;
-		}
+	       !((ServiceComplete ^ pMpTcb->WrIndex) & ET_DMA10_WRAP)
+	       && index > (pMpTcb->WrIndex & ET_DMA10_MASK)) {
+		etdev->TxRing.nBusySend--;
+		etdev->TxRing.CurrSendHead = pMpTcb->Next;
+		if (pMpTcb->Next == NULL)
+			etdev->TxRing.CurrSendTail = NULL;
 
-		spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
-		MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb);
-		spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+		spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
+		et131x_free_send_packet(etdev, pMpTcb);
+		spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
 		/* Goto the next packet */
-		pMpTcb = pAdapter->TxRing.CurrSendHead;
+		pMpTcb = etdev->TxRing.CurrSendHead;
 	}
 
 	/* Wake up the queue when we hit a low-water mark */
-	if (pAdapter->TxRing.nBusySend <= (NUM_TCB / 3)) {
-		netif_wake_queue(pAdapter->netdev);
-	}
+	if (etdev->TxRing.nBusySend <= (NUM_TCB / 3))
+		netif_wake_queue(etdev->netdev);
 
-	spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+	spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
 }
 
 /**
  * et131x_check_send_wait_list - Helper routine for the interrupt handler
- * @pAdapter: pointer to our adapter
+ * @etdev: pointer to our adapter
  *
  * Takes packets from the send wait queue and posts them to the device (if
  * room available).
  */
-static void et131x_check_send_wait_list(struct et131x_adapter *pAdapter)
+static void et131x_check_send_wait_list(struct et131x_adapter *etdev)
 {
-	unsigned long lockflags;
-
-	spin_lock_irqsave(&pAdapter->SendWaitLock, lockflags);
-
-	while (!list_empty(&pAdapter->TxRing.SendWaitQueue) &&
-	       MP_TCB_RESOURCES_AVAILABLE(pAdapter)) {
-		struct list_head *pEntry;
+	unsigned long flags;
 
-		DBG_VERBOSE(et131x_dbginfo, "Tx packets on the wait queue\n");
+	spin_lock_irqsave(&etdev->SendWaitLock, flags);
 
-		pEntry = pAdapter->TxRing.SendWaitQueue.next;
+	while (!list_empty(&etdev->TxRing.SendWaitQueue) &&
+				MP_TCB_RESOURCES_AVAILABLE(etdev)) {
+		struct list_head *entry;
 
-		pAdapter->TxRing.nWaitSend--;
+		entry = etdev->TxRing.SendWaitQueue.next;
 
-		DBG_WARNING(et131x_dbginfo,
-			    "MpHandleSendInterrupt - sent a queued pkt. Waiting %d\n",
-			    pAdapter->TxRing.nWaitSend);
+		etdev->TxRing.nWaitSend--;
 	}
 
-	spin_unlock_irqrestore(&pAdapter->SendWaitLock, lockflags);
+	spin_unlock_irqrestore(&etdev->SendWaitLock, flags);
 }
diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h
index 2819c78..ad03721 100644
--- a/drivers/staging/et131x/et1310_tx.h
+++ b/drivers/staging/et131x/et1310_tx.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -70,15 +70,15 @@ typedef union _txdesc_word2_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 vlan_prio:3;		// bits 29-31(VLAN priority)
-		u32 vlan_cfi:1;		// bit 28(cfi)
-		u32 vlan_tag:12;		// bits 16-27(VLAN tag)
-		u32 length_in_bytes:16;	// bits  0-15(packet length)
+		u32 vlan_prio:3;		/* bits 29-31(VLAN priority) */
+		u32 vlan_cfi:1;		/* bit 28(cfi) */
+		u32 vlan_tag:12;		/* bits 16-27(VLAN tag) */
+		u32 length_in_bytes:16;	/* bits  0-15(packet length) */
 #else
-		u32 length_in_bytes:16;	// bits  0-15(packet length)
-		u32 vlan_tag:12;		// bits 16-27(VLAN tag)
-		u32 vlan_cfi:1;		// bit 28(cfi)
-		u32 vlan_prio:3;		// bits 29-31(VLAN priority)
+		u32 length_in_bytes:16;	/* bits  0-15(packet length) */
+		u32 vlan_tag:12;		/* bits 16-27(VLAN tag) */
+		u32 vlan_cfi:1;		/* bit 28(cfi) */
+		u32 vlan_prio:3;		/* bits 29-31(VLAN priority) */
 #endif	/* _BIT_FIELDS_HTOL */
 	} bits;
 } TXDESC_WORD2_t, *PTXDESC_WORD2_t;
@@ -91,39 +91,39 @@ typedef union _txdesc_word3_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:17;	// bits 15-31
-		u32 udpa:1;	// bit 14(UDP checksum assist)
-		u32 tcpa:1;	// bit 13(TCP checksum assist)
-		u32 ipa:1;		// bit 12(IP checksum assist)
-		u32 vlan:1;	// bit 11(append VLAN tag)
-		u32 hp:1;		// bit 10(Packet is a Huge packet)
-		u32 pp:1;		// bit  9(pad packet)
-		u32 mac:1;		// bit  8(MAC override)
-		u32 crc:1;		// bit  7(append CRC)
-		u32 e:1;		// bit  6(Tx frame has error)
-		u32 pf:1;		// bit  5(send pause frame)
-		u32 bp:1;		// bit  4(Issue half-duplex backpressure (XON/XOFF)
-		u32 cw:1;		// bit  3(Control word - no packet data)
-		u32 ir:1;		// bit  2(interrupt the processor when this pkt sent)
-		u32 f:1;		// bit  1(first packet in the sequence)
-		u32 l:1;		// bit  0(last packet in the sequence)
+		u32 unused:17;	/* bits 15-31 */
+		u32 udpa:1;	/* bit 14(UDP checksum assist) */
+		u32 tcpa:1;	/* bit 13(TCP checksum assist) */
+		u32 ipa:1;		/* bit 12(IP checksum assist) */
+		u32 vlan:1;	/* bit 11(append VLAN tag) */
+		u32 hp:1;		/* bit 10(Packet is a Huge packet) */
+		u32 pp:1;		/* bit  9(pad packet) */
+		u32 mac:1;		/* bit  8(MAC override) */
+		u32 crc:1;		/* bit  7(append CRC) */
+		u32 e:1;		/* bit  6(Tx frame has error) */
+		u32 pf:1;		/* bit  5(send pause frame) */
+		u32 bp:1;		/* bit  4(Issue half-duplex backpressure (XON/XOFF) */
+		u32 cw:1;		/* bit  3(Control word - no packet data) */
+		u32 ir:1;		/* bit  2(interrupt the processor when this pkt sent) */
+		u32 f:1;		/* bit  1(first packet in the sequence) */
+		u32 l:1;		/* bit  0(last packet in the sequence) */
 #else
-		u32 l:1;		// bit  0(last packet in the sequence)
-		u32 f:1;		// bit  1(first packet in the sequence)
-		u32 ir:1;		// bit  2(interrupt the processor when this pkt sent)
-		u32 cw:1;		// bit  3(Control word - no packet data)
-		u32 bp:1;		// bit  4(Issue half-duplex backpressure (XON/XOFF)
-		u32 pf:1;		// bit  5(send pause frame)
-		u32 e:1;		// bit  6(Tx frame has error)
-		u32 crc:1;		// bit  7(append CRC)
-		u32 mac:1;		// bit  8(MAC override)
-		u32 pp:1;		// bit  9(pad packet)
-		u32 hp:1;		// bit 10(Packet is a Huge packet)
-		u32 vlan:1;	// bit 11(append VLAN tag)
-		u32 ipa:1;		// bit 12(IP checksum assist)
-		u32 tcpa:1;	// bit 13(TCP checksum assist)
-		u32 udpa:1;	// bit 14(UDP checksum assist)
-		u32 unused:17;	// bits 15-31
+		u32 l:1;		/* bit  0(last packet in the sequence) */
+		u32 f:1;		/* bit  1(first packet in the sequence) */
+		u32 ir:1;		/* bit  2(interrupt the processor when this pkt sent) */
+		u32 cw:1;		/* bit  3(Control word - no packet data) */
+		u32 bp:1;		/* bit  4(Issue half-duplex backpressure (XON/XOFF) */
+		u32 pf:1;		/* bit  5(send pause frame) */
+		u32 e:1;		/* bit  6(Tx frame has error) */
+		u32 crc:1;		/* bit  7(append CRC) */
+		u32 mac:1;		/* bit  8(MAC override) */
+		u32 pp:1;		/* bit  9(pad packet) */
+		u32 hp:1;		/* bit 10(Packet is a Huge packet) */
+		u32 vlan:1;	/* bit 11(append VLAN tag) */
+		u32 ipa:1;		/* bit 12(IP checksum assist) */
+		u32 tcpa:1;	/* bit 13(TCP checksum assist) */
+		u32 udpa:1;	/* bit 14(UDP checksum assist) */
+		u32 unused:17;	/* bits 15-31 */
 #endif	/* _BIT_FIELDS_HTOL */
 	} bits;
 } TXDESC_WORD3_t, *PTXDESC_WORD3_t;
@@ -132,8 +132,8 @@ typedef union _txdesc_word3_t {
 typedef struct _tx_desc_entry_t {
 	u32 DataBufferPtrHigh;
 	u32 DataBufferPtrLow;
-	TXDESC_WORD2_t word2;	// control words how to xmit the
-	TXDESC_WORD3_t word3;	// data (detailed above)
+	TXDESC_WORD2_t word2;	/* control words how to xmit the */
+	TXDESC_WORD3_t word3;	/* data (detailed above) */
 } TX_DESC_ENTRY_t, *PTX_DESC_ENTRY_t;
 
 
@@ -147,13 +147,13 @@ typedef union _tx_status_block_t {
 	u32 value;
 	struct {
 #ifdef _BIT_FIELDS_HTOL
-		u32 unused:21;		// bits 11-31
-		u32 serv_cpl_wrap:1;	// bit 10
-		u32 serv_cpl:10;		// bits 0-9
+		u32 unused:21;		/* bits 11-31 */
+		u32 serv_cpl_wrap:1;	/* bit 10 */
+		u32 serv_cpl:10;		/* bits 0-9 */
 #else
-		u32 serv_cpl:10;		// bits 0-9
-		u32 serv_cpl_wrap:1;	// bit 10
-		u32 unused:21;		// bits 11-31
+		u32 serv_cpl:10;		/* bits 0-9 */
+		u32 serv_cpl_wrap:1;	/* bit 10 */
+		u32 unused:21;		/* bits 11-31 */
 #endif
 	} bits;
 } TX_STATUS_BLOCK_t, *PTX_STATUS_BLOCK_t;
@@ -166,8 +166,8 @@ typedef struct _MP_TCB {
 	u32 PacketStaleCount;
 	struct sk_buff *Packet;
 	u32 PacketLength;
-	DMA10W_t WrIndex;
-	DMA10W_t WrIndexStart;
+	u32 WrIndex;
+	u32 WrIndexStart;
 } MP_TCB, *PMP_TCB;
 
 /* Structure to hold the skb's in a list */
@@ -206,7 +206,7 @@ typedef struct _tx_ring_t {
 	uint64_t TxDescOffset;
 
 	/* ReadyToSend indicates where we last wrote to in the descriptor ring. */
-	DMA10W_t txDmaReadyToSend;
+	u32 txDmaReadyToSend;
 
 	/* The location of the write-back status block */
 	PTX_STATUS_BLOCK_t pTxStatusVa;
diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h
index 36e61a4..1dfe06f 100644
--- a/drivers/staging/et131x/et131x_adapter.h
+++ b/drivers/staging/et131x/et131x_adapter.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -67,7 +67,7 @@
  * Do not change these values: if changed, then change also in respective
  * TXdma and Rxdma engines
  */
-#define NUM_DESC_PER_RING_TX         512	// TX Do not change these values
+#define NUM_DESC_PER_RING_TX         512	/* TX Do not change these values */
 #define NUM_TCB                      64
 
 /*
@@ -100,28 +100,11 @@
 #define LO_MARK_PERCENT_FOR_PSR     15
 #define LO_MARK_PERCENT_FOR_RX      15
 
-/* Macros for flag and ref count operations        */
-#define MP_SET_FLAG(_M, _F)         ((_M)->Flags |= (_F))
-#define MP_CLEAR_FLAG(_M, _F)       ((_M)->Flags &= ~(_F))
-#define MP_CLEAR_FLAGS(_M)          ((_M)->Flags = 0)
-#define MP_TEST_FLAG(_M, _F)        (((_M)->Flags & (_F)) != 0)
-#define MP_TEST_FLAGS(_M, _F)       (((_M)->Flags & (_F)) == (_F))
-#define MP_IS_FLAG_CLEAR(_M, _F)    (((_M)->Flags & (_F)) == 0)
-
-#define MP_INC_RCV_REF(_A)          atomic_inc(&(_A)->RcvRefCount)
-#define MP_DEC_RCV_REF(_A)          atomic_dec(&(_A)->RcvRefCount)
-#define MP_GET_RCV_REF(_A)          atomic_read(&(_A)->RcvRefCount)
-
 /* Macros specific to the private adapter structure */
 #define MP_TCB_RESOURCES_AVAILABLE(_M) ((_M)->TxRing.nBusySend < NUM_TCB)
 #define MP_TCB_RESOURCES_NOT_AVAILABLE(_M) ((_M)->TxRing.nBusySend >= NUM_TCB)
 
 #define MP_SHOULD_FAIL_SEND(_M)   ((_M)->Flags & fMP_ADAPTER_FAIL_SEND_MASK)
-#define MP_IS_NOT_READY(_M)       ((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK)
-#define MP_IS_READY(_M)           !((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK)
-
-#define MP_HAS_CABLE(_M)           !((_M)->Flags & fMP_ADAPTER_NO_CABLE)
-#define MP_LINK_DETECTED(_M)       !((_M)->Flags & fMP_ADAPTER_LINK_DETECTION)
 
 /* Counters for error rate monitoring */
 typedef struct _MP_ERR_COUNTERS {
@@ -136,9 +119,9 @@ typedef struct _MP_ERR_COUNTERS {
 typedef struct _MP_RFD {
 	struct list_head list_node;
 	struct sk_buff *Packet;
-	u32 PacketSize;	// total size of receive frame
-	u16 iBufferIndex;
-	u8 iRingIndex;
+	u32 PacketSize;	/* total size of receive frame */
+	u16 bufferindex;
+	u8 ringindex;
 } MP_RFD, *PMP_RFD;
 
 /* Enum for Flow Control */
@@ -152,8 +135,8 @@ typedef enum _eflow_control_t {
 /* Struct to define some device statistics */
 typedef struct _ce_stats_t {
 	/* Link Input/Output stats */
-	uint64_t ipackets;	// # of in packets
-	uint64_t opackets;	// # of out packets
+	uint64_t ipackets;	/* # of in packets */
+	uint64_t opackets;	/* # of out packets */
 
 	/* MIB II variables
 	 *
@@ -161,21 +144,21 @@ typedef struct _ce_stats_t {
 	 * MUST have 32, then we'll need another way to perform atomic
 	 * operations
 	 */
-	u32 unircv;	// # multicast packets received
-	atomic_t unixmt;	// # multicast packets for Tx
-	u32 multircv;	// # multicast packets received
-	atomic_t multixmt;	// # multicast packets for Tx
-	u32 brdcstrcv;	// # broadcast packets received
-	atomic_t brdcstxmt;	// # broadcast packets for Tx
-	u32 norcvbuf;	// # Rx packets discarded
-	u32 noxmtbuf;	// # Tx packets discarded
+	u32 unircv;	/* # multicast packets received */
+	atomic_t unixmt;	/* # multicast packets for Tx */
+	u32 multircv;	/* # multicast packets received */
+	atomic_t multixmt;	/* # multicast packets for Tx */
+	u32 brdcstrcv;	/* # broadcast packets received */
+	atomic_t brdcstxmt;	/* # broadcast packets for Tx */
+	u32 norcvbuf;	/* # Rx packets discarded */
+	u32 noxmtbuf;	/* # Tx packets discarded */
 
 	/* Transciever state informations. */
 	u8 xcvr_addr;
 	u32 xcvr_id;
 
 	/* Tx Statistics. */
-	u32 tx_uflo;		// Tx Underruns
+	u32 tx_uflo;		/* Tx Underruns */
 
 	u32 collisions;
 	u32 excessive_collisions;
@@ -185,7 +168,7 @@ typedef struct _ce_stats_t {
 	u32 tx_deferred;
 
 	/* Rx Statistics. */
-	u32 rx_ov_flow;	// Rx Over Flow
+	u32 rx_ov_flow;	/* Rx Over Flow */
 
 	u32 length_err;
 	u32 alignment_err;
@@ -193,15 +176,8 @@ typedef struct _ce_stats_t {
 	u32 code_violations;
 	u32 other_errors;
 
-#ifdef CONFIG_ET131X_DEBUG
-	u32 UnhandledInterruptsPerSec;
-	u32 RxDmaInterruptsPerSec;
-	u32 TxDmaInterruptsPerSec;
-	u32 WatchDogInterruptsPerSec;
-#endif	/* CONFIG_ET131X_DEBUG */
-
 	u32 SynchrounousIterations;
-	INTERRUPT_t InterruptStatus;
+	u32 InterruptStatus;
 } CE_STATS_t, *PCE_STATS_t;
 
 /* The private adapter structure */
@@ -218,8 +194,7 @@ struct et131x_adapter {
 	/* Configuration  */
 	u8 PermanentAddress[ETH_ALEN];
 	u8 CurrentAddress[ETH_ALEN];
-	bool bOverrideAddress;
-	bool bEepromPresent;
+	bool has_eeprom;
 	u8 eepromData[2];
 
 	/* Spinlocks */
@@ -238,11 +213,8 @@ struct et131x_adapter {
 
 	/* Packet Filter and look ahead size */
 	u32 PacketFilter;
-	u32 ulLookAhead;
-	u32 uiLinkSpeed;
-	u32 uiDuplexMode;
-	u32 uiAutoNegStatus;
-	u8 ucLinkStatus;
+	u32 linkspeed;
+	u32 duplex_mode;
 
 	/* multicast list */
 	u32 MCAddressCount;
@@ -252,50 +224,24 @@ struct et131x_adapter {
 	TXMAC_TXTEST_t TxMacTest;
 
 	/* Pointer to the device's PCI register space */
-	ADDRESS_MAP_t __iomem *CSRAddress;
-
-	/* PCI config space info, for debug purposes only. */
-	u8 RevisionID;
-	u16 VendorID;
-	u16 DeviceID;
-	u16 SubVendorID;
-	u16 SubSystemID;
-	u32 CacheFillSize;
-	u16 PciXDevCtl;
-	u8 pci_lat_timer;
-	u8 pci_hdr_type;
-	u8 pci_bist;
-	u32 pci_cfg_state[64 / sizeof(u32)];
+	ADDRESS_MAP_t __iomem *regs;
 
 	/* Registry parameters */
-	u8 SpeedDuplex;		// speed/duplex
-	eFLOW_CONTROL_t RegistryFlowControl;	// for 802.3x flow control
-	u8 RegistryWOLMatch;	// Enable WOL pattern-matching
-	u8 RegistryWOLLink;	// Link state change is independant
-	u8 RegistryPhyComa;	// Phy Coma mode enable/disable
-
-	u32 RegistryRxMemEnd;	// Size of internal rx memory
-	u8 RegistryMACStat;	// If set, read MACSTAT, else don't
-	u32 RegistryVlanTag;	// 802.1q Vlan TAG
-	u32 RegistryJumboPacket;	// Max supported ethernet packet size
+	u8 SpeedDuplex;		/* speed/duplex */
+	eFLOW_CONTROL_t RegistryFlowControl;	/* for 802.3x flow control */
+	u8 RegistryPhyComa;	/* Phy Coma mode enable/disable */
 
-	u32 RegistryTxNumBuffers;
-	u32 RegistryTxTimeInterval;
-
-	u32 RegistryRxNumBuffers;
-	u32 RegistryRxTimeInterval;
+	u32 RegistryRxMemEnd;	/* Size of internal rx memory */
+	u32 RegistryJumboPacket;	/* Max supported ethernet packet size */
 
 	/* Validation helpers */
-	u8 RegistryPMWOL;
 	u8 RegistryNMIDisable;
-	u32 RegistryDMACache;
-	u32 RegistrySCGain;
-	u8 RegistryPhyLoopbk;	// Enable Phy loopback
+	u8 RegistryPhyLoopbk;	/* Enable Phy loopback */
 
 	/* Derived from the registry: */
-	u8 AiForceDpx;		// duplex setting
-	u16 AiForceSpeed;		// 'Speed', user over-ride of line speed
-	eFLOW_CONTROL_t FlowControl;	// flow control validated by the far-end
+	u8 AiForceDpx;		/* duplex setting */
+	u16 AiForceSpeed;		/* 'Speed', user over-ride of line speed */
+	eFLOW_CONTROL_t FlowControl;	/* flow control validated by the far-end */
 	enum {
 		NETIF_STATUS_INVALID = 0,
 		NETIF_STATUS_MEDIA_CONNECT,
@@ -305,15 +251,9 @@ struct et131x_adapter {
 	u8 DriverNoPhyAccess;
 
 	/* Minimize init-time */
-	bool bQueryPending;
-	bool bSetPending;
-	bool bResetPending;
 	struct timer_list ErrorTimer;
-	bool bLinkTimerActive;
 	MP_POWER_MGMT PoMgmt;
-	INTERRUPT_t CachedMaskValue;
-
-	atomic_t RcvRefCount;	// Num packets not yet returned
+	u32 CachedMaskValue;
 
 	/* Xcvr status at last poll */
 	MI_BMSR_t Bmsr;
@@ -324,13 +264,9 @@ struct et131x_adapter {
 	/* Rx Memory Variables */
 	RX_RING_t RxRing;
 
-	/* ET1310 register Access */
-	JAGCORE_ACCESS_REGS JagCoreRegs;
-	PCI_CFG_SPACE_REGS PciCfgRegs;
-
 	/* Loopback specifics */
-	u8 ReplicaPhyLoopbk;	// Replica Enable
-	u8 ReplicaPhyLoopbkPF;	// Replica Enable Pass/Fail
+	u8 ReplicaPhyLoopbk;	/* Replica Enable */
+	u8 ReplicaPhyLoopbkPF;	/* Replica Enable Pass/Fail */
 
 	/* Stats */
 	CE_STATS_t Stats;
@@ -339,9 +275,4 @@ struct et131x_adapter {
 	struct net_device_stats net_stats_prev;
 };
 
-#define MPSendPacketsHandler  MPSendPackets
-#define MP_FREE_SEND_PACKET_FUN(Adapter, pMpTcb) \
-	et131x_free_send_packet(Adapter, pMpTcb)
-#define MpSendPacketFun(Adapter, Packet) MpSendPacket(Adapter, Packet)
-
 #endif /* __ET131X_ADAPTER_H__ */
diff --git a/drivers/staging/et131x/et131x_config.c b/drivers/staging/et131x/et131x_config.c
deleted file mode 100644
index 0adbaa6..0000000
--- a/drivers/staging/et131x/et131x_config.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_config.c - Handles parsing of configuration data during
- *                   initialization.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, are permitted provided that the following conditions are met:
- *
- * . Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following Disclaimer as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . 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.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS 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, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- */
-
-#include "et131x_version.h"
-#include "et131x_debug.h"
-#include "et131x_defs.h"
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ioport.h>
-
-#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-
-#include "et131x_adapter.h"
-#include "et131x_initpci.h"
-#include "et131x_config.h"
-
-#include "et1310_tx.h"
-
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
-
-/* Defines for Parameter Default/Min/Max vaules */
-#define PARM_SPEED_DUPLEX_DEF   0
-#define PARM_SPEED_DUPLEX_MIN   0
-#define PARM_SPEED_DUPLEX_MAX   5
-
-#define PARM_VLAN_TAG_DEF       0
-#define PARM_VLAN_TAG_MIN       0
-#define PARM_VLAN_TAG_MAX       4095
-
-#define PARM_FLOW_CTL_DEF       0
-#define PARM_FLOW_CTL_MIN       0
-#define PARM_FLOW_CTL_MAX       3
-
-#define PARM_WOL_LINK_DEF       3
-#define PARM_WOL_LINK_MIN       0
-#define PARM_WOL_LINK_MAX       3
-
-#define PARM_WOL_MATCH_DEF      7
-#define PARM_WOL_MATCH_MIN      0
-#define PARM_WOL_MATCH_MAX      7
-
-#define PARM_JUMBO_PKT_DEF      1514
-#define PARM_JUMBO_PKT_MIN      1514
-#define PARM_JUMBO_PKT_MAX      9216
-
-#define PARM_PHY_COMA_DEF       0
-#define PARM_PHY_COMA_MIN       0
-#define PARM_PHY_COMA_MAX       1
-
-#define PARM_RX_NUM_BUFS_DEF    4
-#define PARM_RX_NUM_BUFS_MIN    1
-#define PARM_RX_NUM_BUFS_MAX    64
-
-#define PARM_RX_TIME_INT_DEF    10
-#define PARM_RX_TIME_INT_MIN    2
-#define PARM_RX_TIME_INT_MAX    320
-
-#define PARM_TX_NUM_BUFS_DEF    4
-#define PARM_TX_NUM_BUFS_MIN    1
-#define PARM_TX_NUM_BUFS_MAX    40
-
-#define PARM_TX_TIME_INT_DEF    40
-#define PARM_TX_TIME_INT_MIN    1
-#define PARM_TX_TIME_INT_MAX    140
-
-#define PARM_RX_MEM_END_DEF     0x2bc
-#define PARM_RX_MEM_END_MIN     0
-#define PARM_RX_MEM_END_MAX     0x3ff
-
-#define PARM_MAC_STAT_DEF       1
-#define PARM_MAC_STAT_MIN       0
-#define PARM_MAC_STAT_MAX       1
-
-#define PARM_SC_GAIN_DEF        7
-#define PARM_SC_GAIN_MIN        0
-#define PARM_SC_GAIN_MAX        7
-
-#define PARM_PM_WOL_DEF         0
-#define PARM_PM_WOL_MIN         0
-#define PARM_PM_WOL_MAX         1
-
-#define PARM_NMI_DISABLE_DEF    0
-#define PARM_NMI_DISABLE_MIN    0
-#define PARM_NMI_DISABLE_MAX    2
-
-#define PARM_DMA_CACHE_DEF      0
-#define PARM_DMA_CACHE_MIN      0
-#define PARM_DMA_CACHE_MAX      15
-
-#define PARM_PHY_LOOPBK_DEF     0
-#define PARM_PHY_LOOPBK_MIN     0
-#define PARM_PHY_LOOPBK_MAX     1
-
-#define PARM_MAC_ADDRESS_DEF    { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 }
-
-/* Module parameter for disabling NMI
- * et131x_speed_set :
- * Set Link speed and dublex manually (0-5)  [0]
- *  1 : 10Mb   Half-Duplex
- *  2 : 10Mb   Full-Duplex
- *  3 : 100Mb  Half-Duplex
- *  4 : 100Mb  Full-Duplex
- *  5 : 1000Mb Full-Duplex
- *  0 : Auto Speed Auto Dublex // default
- */
-static u32 et131x_nmi_disable = PARM_NMI_DISABLE_DEF;
-module_param(et131x_nmi_disable, uint, 0);
-MODULE_PARM_DESC(et131x_nmi_disable, "Disable NMI (0-2) [0]");
-
-/* Module parameter for manual speed setting
- * et131x_nmi_disable :
- * Disable NMI (0-2) [0]
- *  0 :
- *  1 :
- *  2 :
- */
-static u32 et131x_speed_set = PARM_SPEED_DUPLEX_DEF;
-module_param(et131x_speed_set, uint, 0);
-MODULE_PARM_DESC(et131x_speed_set,
-		 "Set Link speed and dublex manually (0-5)  [0] \n  1 : 10Mb   Half-Duplex \n  2 : 10Mb   Full-Duplex \n  3 : 100Mb  Half-Duplex \n  4 : 100Mb  Full-Duplex \n  5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex");
-
-/**
- * et131x_config_parse
- * @pAdapter: pointer to the private adapter struct
- *
- * Parses a configuration from some location (module parameters, for example)
- * into the private adapter struct
- */
-void et131x_config_parse(struct et131x_adapter *pAdapter)
-{
-	uint8_t macAddrDef[] = PARM_MAC_ADDRESS_DEF;
-
-	DBG_ENTER(et131x_dbginfo);
-
-	/*
-	 * The NDIS driver uses the registry to store persistent per-device
-	 * configuration, and reads this configuration into the appropriate
-	 * elements of the private adapter structure on initialization.
-	 * Because Linux has no analog to the registry, use this function to
-	 * initialize the private adapter structure with a default
-	 * configuration.
-	 *
-	 * One other possibility is to use a series of module parameters which
-	 * can be passed in by the caller when the module is initialized.
-	 * However, this implementation does not allow for seperate
-	 * configurations in the event multiple devices are present, and hence
-	 * will not suffice.
-	 *
-	 * If another method is derived which addresses this problem, this is
-	 * where it should be implemented.
-	 */
-
-	 /* Set the private adapter struct with default values for the
-	  * corresponding parameters
-	  */
-	if (et131x_speed_set != PARM_SPEED_DUPLEX_DEF) {
-		DBG_VERBOSE(et131x_dbginfo, "Speed set manually to : %d \n",
-			    et131x_speed_set);
-		pAdapter->SpeedDuplex = et131x_speed_set;
-	} else {
-		pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF;
-	}
-
-	//  pAdapter->SpeedDuplex            = PARM_SPEED_DUPLEX_DEF;
-
-	pAdapter->RegistryVlanTag = PARM_VLAN_TAG_DEF;
-	pAdapter->RegistryFlowControl = PARM_FLOW_CTL_DEF;
-	pAdapter->RegistryWOLLink = PARM_WOL_LINK_DEF;
-	pAdapter->RegistryWOLMatch = PARM_WOL_MATCH_DEF;
-	pAdapter->RegistryJumboPacket = PARM_JUMBO_PKT_DEF;
-	pAdapter->RegistryPhyComa = PARM_PHY_COMA_DEF;
-	pAdapter->RegistryRxNumBuffers = PARM_RX_NUM_BUFS_DEF;
-	pAdapter->RegistryRxTimeInterval = PARM_RX_TIME_INT_DEF;
-	pAdapter->RegistryTxNumBuffers = PARM_TX_NUM_BUFS_DEF;
-	pAdapter->RegistryTxTimeInterval = PARM_TX_TIME_INT_DEF;
-	pAdapter->RegistryRxMemEnd = PARM_RX_MEM_END_DEF;
-	pAdapter->RegistryMACStat = PARM_MAC_STAT_DEF;
-	pAdapter->RegistrySCGain = PARM_SC_GAIN_DEF;
-	pAdapter->RegistryPMWOL = PARM_PM_WOL_DEF;
-
-	if (et131x_nmi_disable != PARM_NMI_DISABLE_DEF) {
-		pAdapter->RegistryNMIDisable = et131x_nmi_disable;
-	} else {
-		pAdapter->RegistryNMIDisable = PARM_NMI_DISABLE_DEF;
-	}
-
-	pAdapter->RegistryDMACache = PARM_DMA_CACHE_DEF;
-	pAdapter->RegistryPhyLoopbk = PARM_PHY_LOOPBK_DEF;
-
-	/* Set the MAC address to a default */
-	memcpy(pAdapter->CurrentAddress, macAddrDef, ETH_ALEN);
-	pAdapter->bOverrideAddress = false;
-
-	DBG_TRACE(et131x_dbginfo,
-		  "Default MAC Address  : %02x:%02x:%02x:%02x:%02x:%02x\n",
-		  pAdapter->CurrentAddress[0], pAdapter->CurrentAddress[1],
-		  pAdapter->CurrentAddress[2], pAdapter->CurrentAddress[3],
-		  pAdapter->CurrentAddress[4], pAdapter->CurrentAddress[5]);
-
-	/* Decode SpeedDuplex
-	 *
-	 * Set up as if we are auto negotiating always and then change if we
-	 * go into force mode
-	 */
-	pAdapter->AiForceSpeed = 0;	// Auto speed
-	pAdapter->AiForceDpx = 0;	// Auto FDX
-
-	/* If we are the 10/100 device, and gigabit is somehow requested then
-	 * knock it down to 100 full.
-	 */
-	if ((pAdapter->DeviceID == ET131X_PCI_DEVICE_ID_FAST) &&
-	    (pAdapter->SpeedDuplex == 5)) {
-		pAdapter->SpeedDuplex = 4;
-	}
-
-	switch (pAdapter->SpeedDuplex) {
-	case 1:		// 10Mb   Half-Duplex
-		pAdapter->AiForceSpeed = 10;
-		pAdapter->AiForceDpx = 1;
-		break;
-
-	case 2:		// 10Mb   Full-Duplex
-		pAdapter->AiForceSpeed = 10;
-		pAdapter->AiForceDpx = 2;
-		break;
-
-	case 3:		// 100Mb  Half-Duplex
-		pAdapter->AiForceSpeed = 100;
-		pAdapter->AiForceDpx = 1;
-		break;
-
-	case 4:		// 100Mb  Full-Duplex
-		pAdapter->AiForceSpeed = 100;
-		pAdapter->AiForceDpx = 2;
-		break;
-
-	case 5:		// 1000Mb Full-Duplex
-		pAdapter->AiForceSpeed = 1000;
-		pAdapter->AiForceDpx = 2;
-		break;
-	}
-
-	DBG_LEAVE(et131x_dbginfo);
-}
diff --git a/drivers/staging/et131x/et131x_debug.c b/drivers/staging/et131x/et131x_debug.c
deleted file mode 100644
index d1dd46e..0000000
--- a/drivers/staging/et131x/et131x_debug.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_debug.c - Routines used for debugging.
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, are permitted provided that the following conditions are met:
- *
- * . Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following Disclaimer as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . 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.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS 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, INCLUDING, BUT NOT LIMITED TO, 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.
- *
- */
-
-#ifdef CONFIG_ET131X_DEBUG
-
-#include "et131x_version.h"
-#include "et131x_debug.h"
-#include "et131x_defs.h"
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/in.h>
-#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ioport.h>
-#include <linux/random.h>
-
-#include "et1310_phy.h"
-#include "et1310_pm.h"
-#include "et1310_jagcore.h"
-
-#include "et131x_adapter.h"
-#include "et131x_netdev.h"
-#include "et131x_config.h"
-#include "et131x_isr.h"
-
-#include "et1310_address_map.h"
-#include "et1310_tx.h"
-#include "et1310_rx.h"
-#include "et1310_mac.h"
-
-/* Data for debugging facilities */
-extern dbg_info_t *et131x_dbginfo;
-
-/**
- * DumpTxQueueContents - Dump out the tx queue and the shadow pointers
- * @pAdapter: pointer to our adapter structure
- */
-void DumpTxQueueContents(int dbgLvl, struct et131x_adapter *pAdapter)
-{
-	MMC_t __iomem *mmc = &pAdapter->CSRAddress->mmc;
-	uint32_t TxQueueAddr;
-
-	if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) {
-		for (TxQueueAddr = 0x200; TxQueueAddr < 0x3ff; TxQueueAddr++) {
-			MMC_SRAM_ACCESS_t sram_access;
-
-			sram_access.value = readl(&mmc->sram_access.value);
-			sram_access.bits.req_addr = TxQueueAddr;
-			sram_access.bits.req_access = 1;
-			writel(sram_access.value, &mmc->sram_access.value);
-
-			DBG_PRINT("Addr 0x%x, Access 0x%08x\t"
-				  "Value 1 0x%08x, Value 2 0x%08x, "
-				  "Value 3 0x%08x, Value 4 0x%08x, \n",
-				  TxQueueAddr,
-				  readl(&mmc->sram_access.value),
-				  readl(&mmc->sram_word1),
-				  readl(&mmc->sram_word2),
-				  readl(&mmc->sram_word3),
-				  readl(&mmc->sram_word4));
-		}
-
-		DBG_PRINT("Shadow Pointers 0x%08x\n",
-			  readl(&pAdapter->CSRAddress->txmac.shadow_ptr.value));
-	}
-}
-
-/**
- * DumpDeviceBlock
- * @pAdapter: pointer to our adapter
- *
- * Dumps the first 64 regs of each block of the et-1310 (each block is
- * mapped to a new page, each page is 4096 bytes).
- */
-#define NUM_BLOCKS 8
-void DumpDeviceBlock(int dbgLvl, struct et131x_adapter *pAdapter,
-		     uint32_t Block)
-{
-	uint32_t Address1, Address2;
-	uint32_t __iomem *BigDevicePointer =
-		(uint32_t __iomem *) pAdapter->CSRAddress;
-	const char *BlockNames[NUM_BLOCKS] = {
-		"Global", "Tx DMA", "Rx DMA", "Tx MAC",
-		"Rx MAC", "MAC", "MAC Stat", "MMC"
-	};
-
-	/* Output the debug counters to the debug terminal */
-	if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) {
-		DBG_PRINT("%s block\n", BlockNames[Block]);
-		BigDevicePointer += Block * 1024;
-		for (Address1 = 0; Address1 < 8; Address1++) {
-			for (Address2 = 0; Address2 < 8; Address2++) {
-				if (Block == 0 &&
-				    (Address1 * 8 + Address2) == 6) {
-					DBG_PRINT("  ISR    , ");
-				} else {
-					DBG_PRINT("0x%08x, ",
-						  readl(BigDevicePointer++));
-				}
-			}
-			DBG_PRINT("\n");
-		}
-		DBG_PRINT("\n");
-	}
-}
-
-/**
- * DumpDeviceReg
- * @pAdapter: pointer to our adapter
- *
- * Dumps the first 64 regs of each block of the et-1310 (each block is
- * mapped to a new page, each page is 4096 bytes).
- */
-void DumpDeviceReg(int dbgLvl, struct et131x_adapter *pAdapter)
-{
-	uint32_t Address1, Address2;
-	uint32_t Block;
-	uint32_t __iomem *BigDevicePointer =
-		(uint32_t __iomem *) pAdapter->CSRAddress;
-	uint32_t __iomem *Pointer;
-	const char *BlockNames[NUM_BLOCKS] = {
-		"Global", "Tx DMA", "Rx DMA", "Tx MAC",
-		"Rx MAC", "MAC", "MAC Stat", "MMC"
-	};
-
-	/* Output the debug counters to the debug terminal */
-	if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) {
-		for (Block = 0; Block < NUM_BLOCKS; Block++) {
-			DBG_PRINT("%s block\n", BlockNames[Block]);
-			Pointer = BigDevicePointer + (Block * 1024);
-
-			for (Address1 = 0; Address1 < 8; Address1++) {
-				for (Address2 = 0; Address2 < 8; Address2++) {
-					DBG_PRINT("0x%08x, ",
-						  readl(Pointer++));
-				}
-				DBG_PRINT("\n");
-			}
-			DBG_PRINT("\n");
-		}
-	}
-}
-
-#endif // CONFIG_ET131X_DEBUG
diff --git a/drivers/staging/et131x/et131x_debug.h b/drivers/staging/et131x/et131x_debug.h
deleted file mode 100644
index 994108e..0000000
--- a/drivers/staging/et131x/et131x_debug.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Agere Systems Inc.
- * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *   http://www.agere.com
- *
- *------------------------------------------------------------------------------
- *
- * et131x_debug.h - Defines, structs, enums, prototypes, etc. used for
- *                  outputting debug messages to the system logging facility
- *                  (ksyslogd)
- *
- *------------------------------------------------------------------------------
- *
- * SOFTWARE LICENSE
- *
- * This software is provided subject to the following terms and conditions,
- * which you should read carefully before using the software.  Using this
- * software indicates your acceptance of these terms and conditions.  If you do
- * not agree with these terms and conditions, do not use the software.
- *
- * Copyright © 2005 Agere Systems Inc.
- * All rights reserved.
- *
- * Redistribution and use in source or binary forms, with or without
- * modifications, are permitted provided that the following conditions are met:
- *
- * . Redistributions of source code must retain the above copyright notice, this
- *    list of conditions and the following Disclaimer as comments in the code as
- *    well as in the documentation and/or other materials provided with the
- *    distribution.
- *
- * . 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.
- *
- * . Neither the name of Agere Systems Inc. nor the names of the contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * Disclaimer
- *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
- * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
- * RISK. IN NO EVENT SHALL AGERE SYSTEMS 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, INCLUDING, BUT NOT LIMITED TO, 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.
- *
- */
-
-#ifndef __ET131X_DBG_H__
-#define __ET131X_DBG_H__
-
-/* Define Masks for debugging types/levels */
-#define DBG_ERROR_ON        0x00000001L
-#define DBG_WARNING_ON      0x00000002L
-#define DBG_NOTICE_ON       0x00000004L
-#define DBG_TRACE_ON        0x00000008L
-#define DBG_VERBOSE_ON      0x00000010L
-#define DBG_PARAM_ON        0x00000020L
-#define DBG_BREAK_ON        0x00000040L
-#define DBG_RX_ON           0x00000100L
-#define DBG_TX_ON           0x00000200L
-
-#ifdef CONFIG_ET131X_DEBUG
-
-/*
- * Set the level of debugging if not done with a preprocessor define. See
- * et131x_main.c, function et131x_init_module() for how the debug level
- * translates into the types of messages displayed.
- */
-#ifndef DBG_LVL
-#define DBG_LVL	3
-#endif /* DBG_LVL */
-
-#define DBG_DEFAULTS		(DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON)
-
-#define DBG_FLAGS(A)		((A)->dbgFlags)
-#define DBG_NAME(A)		((A)->dbgName)
-#define DBG_LEVEL(A)		((A)->dbgLevel)
-
-#ifndef DBG_PRINT
-#define DBG_PRINT(S...)		printk(KERN_DEBUG S)
-#endif /* DBG_PRINT */
-
-#ifndef DBG_PRINTC
-#define DBG_PRINTC(S...)	printk(S)
-#endif /* DBG_PRINTC */
-
-#ifndef DBG_TRAP
-#define DBG_TRAP		{}	/* BUG() */
-#endif /* DBG_TRAP */
-
-#define _ENTER_STR	">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
-#define _LEAVE_STR	"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
-
-#define _DBG_ENTER(A)	printk(KERN_DEBUG "%s:%.*s:%s\n", DBG_NAME(A),	\
-				++DBG_LEVEL(A), _ENTER_STR, __func__)
-#define _DBG_LEAVE(A)	printk(KERN_DEBUG "%s:%.*s:%s\n", DBG_NAME(A),	\
-				DBG_LEVEL(A)--, _LEAVE_STR, __func__)
-
-#define DBG_ENTER(A)							\
-	do {								\
-		if (DBG_FLAGS(A) & DBG_TRACE_ON)			\
-			_DBG_ENTER(A);					\
-	} while (0)
-
-#define DBG_LEAVE(A)							\
-	do {								\
-		if (DBG_FLAGS(A) & DBG_TRACE_ON)			\
-			_DBG_LEAVE(A);					\
-	} while (0)
-
-#define DBG_PARAM(A, N, F, S...)					\
-	do {								\
-		if (DBG_FLAGS(A) & DBG_PARAM_ON)			\
-			DBG_PRINT("  %s -- "F" ", N, S);		\
-	} while (0)
-
-#define DBG_ERROR(A, S...)						 \
-	do {								 \
-		if (DBG_FLAGS(A) & DBG_ERROR_ON) {			 \
-			DBG_PRINT("%s:ERROR:%s ", DBG_NAME(A), __func__);\
-			DBG_PRINTC(S);					 \
-			DBG_TRAP;					 \
-		}							 \
-	} while (0)
-
-#define DBG_WARNING(A, S...)						    \
-	do {								    \
-		if (DBG_FLAGS(A) & DBG_WARNING_ON) {			    \
-			DBG_PRINT("%s:WARNING:%s ", DBG_NAME(A), __func__); \
-			DBG_PRINTC(S);					    \
-		}							    \
-	} while (0)
-
-#define DBG_NOTICE(A, S...)						   \
-	do {								   \
-		if (DBG_FLAGS(A) & DBG_NOTICE_ON) {			   \
-			DBG_PRINT("%s:NOTICE:%s ", DBG_NAME(A), __func__); \
-			DBG_PRINTC(S);					   \
-		}							   \
-	} while (0)
-
-#define DBG_TRACE(A, S...)						  \
-	do {								  \
-		if (DBG_FLAGS(A) & DBG_TRACE_ON) {			  \
-			DBG_PRINT("%s:TRACE:%s ", DBG_NAME(A), __func__); \
-			DBG_PRINTC(S);					  \
-		}							  \
-	} while (0)
-
-#define DBG_VERBOSE(A, S...)						    \
-	do {								    \
-		if (DBG_FLAGS(A) & DBG_VERBOSE_ON) {			    \
-			DBG_PRINT("%s:VERBOSE:%s ", DBG_NAME(A), __func__); \
-			DBG_PRINTC(S);					    \
-		}							    \
-	} while (0)
-
-#define DBG_RX(A, S...)				\
-	do {					\
-		if (DBG_FLAGS(A) & DBG_RX_ON)	\
-			DBG_PRINT(S);		\
-	} while (0)
-
-#define DBG_RX_ENTER(A)				\
-	do {					\
-		if (DBG_FLAGS(A) & DBG_RX_ON)	\
-			_DBG_ENTER(A);		\
-	} while (0)
-
-#define DBG_RX_LEAVE(A)				\
-	do {					\
-		if (DBG_FLAGS(A) & DBG_RX_ON)	\
-			_DBG_LEAVE(A);		\
-	} while (0)
-
-#define DBG_TX(A, S...)				\
-	do {					\
-		if (DBG_FLAGS(A) & DBG_TX_ON)	\
-			DBG_PRINT(S);		\
-	} while (0)
-
-#define DBG_TX_ENTER(A)				\
-	do {					\
-		if (DBG_FLAGS(A) & DBG_TX_ON)	\
-			_DBG_ENTER(A);		\
-	} while (0)
-
-#define DBG_TX_LEAVE(A)				\
-	do {					\
-		if (DBG_FLAGS(A) & DBG_TX_ON)	\
-			_DBG_LEAVE(A);		\
-	} while (0)
-
-#define DBG_ASSERT(C)						\
-	do {							\
-		if (!(C)) {					\
-			DBG_PRINT("ASSERT(%s) -- %s#%d (%s) ",  \
-			     #C, __FILE__, __LINE__, __func__); \
-			DBG_TRAP;				\
-		}						\
-	} while (0)
-
-#define STATIC
-
-typedef struct {
-	char *dbgName;
-	int dbgLevel;
-	unsigned long dbgFlags;
-} dbg_info_t;
-
-#else /* CONFIG_ET131X_DEBUG */
-
-#define DBG_DEFN
-#define DBG_TRAP
-#define DBG_PRINT(S...)
-#define DBG_ENTER(A)
-#define DBG_LEAVE(A)
-#define DBG_PARAM(A,N,F,S...)
-#define DBG_ERROR(A,S...)
-#define DBG_WARNING(A,S...)
-#define DBG_NOTICE(A,S...)
-#define DBG_TRACE(A,S...)
-#define DBG_VERBOSE(A,S...)
-#define DBG_RX(A,S...)
-#define DBG_RX_ENTER(A)
-#define DBG_RX_LEAVE(A)
-#define DBG_TX(A,S...)
-#define DBG_TX_ENTER(A)
-#define DBG_TX_LEAVE(A)
-#define DBG_ASSERT(C)
-#define STATIC static
-
-#endif /* CONFIG_ET131X_DEBUG */
-
-/* Forward declaration of the private adapter structure */
-struct et131x_adapter;
-
-void DumpTxQueueContents(int dbgLvl, struct et131x_adapter *adapter);
-void DumpDeviceBlock(int dbgLvl, struct et131x_adapter *adapter,
-		     unsigned int Block);
-void DumpDeviceReg(int dbgLvl, struct et131x_adapter *adapter);
-
-#endif /* __ET131X_DBG_H__ */
diff --git a/drivers/staging/et131x/et131x_defs.h b/drivers/staging/et131x/et131x_defs.h
index 886cb78..f98dca5 100644
--- a/drivers/staging/et131x/et131x_defs.h
+++ b/drivers/staging/et131x/et131x_defs.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -61,7 +61,6 @@
 
 /* Packet and header sizes */
 #define NIC_MIN_PACKET_SIZE	60
-#define NIC_HEADER_SIZE		ETH_HLEN	/* 14 */
 
 /* Multicast list size */
 #define NIC_MAX_MCAST_LIST	128
@@ -102,27 +101,28 @@
 #define fMP_ADAPTER_NOT_READY_MASK	0x3ff00000
 
 /* Some offsets in PCI config space that are actually used. */
-#define ET1310_PCI_PM_CAPABILITY	0x40
-#define ET1310_PCI_PM_CSR		0x44
 #define ET1310_PCI_MAX_PYLD		0x4C
-#define ET1310_PCI_DEV_CTRL		0x50
-#define ET1310_PCI_DEV_STAT		0x52
 #define ET1310_NMI_DISABLE		0x61
 #define ET1310_PCI_MAC_ADDRESS		0xA4
 #define ET1310_PCI_EEPROM_STATUS	0xB2
-#define ET1310_PCI_PHY_INDEX_REG	0xB4
 #define ET1310_PCI_ACK_NACK		0xC0
 #define ET1310_PCI_REPLAY		0xC2
 #define ET1310_PCI_L0L1LATENCY		0xCF
-#define ET1310_PCI_SEL_PHY_CTRL		0xE4
-#define ET1310_PCI_ADVANCED_ERR		0x100
 
 /* PCI Vendor/Product IDs */
-#define ET131X_PCI_VENDOR_ID		0x11C1	// Agere Systems
-#define ET131X_PCI_DEVICE_ID_GIG	0xED00	// ET1310 1000 Base-T
-#define ET131X_PCI_DEVICE_ID_FAST	0xED01	// ET1310 100  Base-T
+#define ET131X_PCI_VENDOR_ID		0x11C1	/* Agere Systems */
+#define ET131X_PCI_DEVICE_ID_GIG	0xED00	/* ET1310 1000 Base-T 8 */
+#define ET131X_PCI_DEVICE_ID_FAST	0xED01	/* ET1310 100  Base-T */
 
 /* Define order of magnitude converter */
 #define NANO_IN_A_MICRO	1000
 
+#define PARM_RX_NUM_BUFS_DEF    4
+#define PARM_RX_TIME_INT_DEF    10
+#define PARM_RX_MEM_END_DEF     0x2bc
+#define PARM_TX_TIME_INT_DEF    40
+#define PARM_TX_NUM_BUFS_DEF    4
+#define PARM_DMA_CACHE_DEF      0
+
+
 #endif /* __ET131X_DEFS_H__ */
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
index a18c499..9db2056 100644
--- a/drivers/staging/et131x/et131x_initpci.c
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -21,7 +21,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -42,7 +42,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -58,7 +58,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/pci.h>
@@ -76,9 +75,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -103,130 +102,34 @@
 #include "et1310_eeprom.h"
 
 
-int __devinit et131x_pci_setup(struct pci_dev *pdev,
-			       const struct pci_device_id *ent);
-void __devexit et131x_pci_remove(struct pci_dev *pdev);
-
-
-/* Modinfo parameters (filled out using defines from et131x_version.h) */
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_INFO);
-MODULE_LICENSE(DRIVER_LICENSE);
-
-/* Module Parameters and related data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-static u32 et131x_debug_level = DBG_LVL;
-static u32 et131x_debug_flags = DBG_DEFAULTS;
-
-/*
-et131x_debug_level :
- Level of debugging desired (0-7)
-   7 : DBG_RX_ON | DBG_TX_ON
-   6 : DBG_PARAM_ON
-   5 : DBG_VERBOSE_ON
-   4 : DBG_TRACE_ON
-   3 : DBG_NOTICE_ON
-   2 : no debug info
-   1 : no debug info
-   0 : no debug info
-*/
-
-module_param(et131x_debug_level, uint, 0);
-module_param(et131x_debug_flags, uint, 0);
-
-MODULE_PARM_DESC(et131x_debug_level, "Level of debugging desired (0-7)");
-
-static dbg_info_t et131x_info = { DRIVER_NAME_EXT, 0, 0 };
-dbg_info_t *et131x_dbginfo = &et131x_info;
-#endif /* CONFIG_ET131X_DEBUG */
-
-static struct pci_device_id et131x_pci_table[] __devinitdata = {
-	{ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID,
-	 PCI_ANY_ID, 0, 0, 0UL},
-	{ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID,
-	 PCI_ANY_ID, 0, 0, 0UL},
-	{0,}
-};
-
-MODULE_DEVICE_TABLE(pci, et131x_pci_table);
-
-static struct pci_driver et131x_driver = {
-      .name	= DRIVER_NAME,
-      .id_table	= et131x_pci_table,
-      .probe	= et131x_pci_setup,
-      .remove	= __devexit_p(et131x_pci_remove),
-      .suspend	= NULL,		//et131x_pci_suspend,
-      .resume	= NULL,		//et131x_pci_resume,
-};
-
-
-/**
- * et131x_init_module - The "main" entry point called on driver initialization
- *
- * Returns 0 on success, errno on failure (as defined in errno.h)
- */
-int et131x_init_module(void)
-{
-	int result;
-
-#ifdef CONFIG_ET131X_DEBUG
-	/* Set the level of debug messages displayed using the module
-	 * parameter
-	 */
-	et131x_dbginfo->dbgFlags = et131x_debug_flags;
-
-	switch (et131x_debug_level) {
-	case 7:
-		et131x_dbginfo->dbgFlags |= (DBG_RX_ON | DBG_TX_ON);
-
-	case 6:
-		et131x_dbginfo->dbgFlags |= DBG_PARAM_ON;
-
-	case 5:
-		et131x_dbginfo->dbgFlags |= DBG_VERBOSE_ON;
-
-	case 4:
-		et131x_dbginfo->dbgFlags |= DBG_TRACE_ON;
-
-	case 3:
-		et131x_dbginfo->dbgFlags |= DBG_NOTICE_ON;
-
-	case 2:
-	case 1:
-	case 0:
-	default:
-		break;
-	}
-#endif /* CONFIG_ET131X_DEBUG */
-
-	DBG_ENTER(et131x_dbginfo);
-	DBG_PRINT("%s\n", DRIVER_INFO);
-
-	result = pci_register_driver(&et131x_driver);
+/* Defines for Parameter Default/Min/Max vaules */
+#define PARM_SPEED_DUPLEX_MIN   0
+#define PARM_SPEED_DUPLEX_MAX   5
 
-	DBG_LEAVE(et131x_dbginfo);
-	return result;
-}
-
-/**
- * et131x_cleanup_module - The entry point called on driver cleanup
+/* Module parameter for disabling NMI
+ * et131x_nmi_disable :
+ * Disable NMI (0-2) [0]
+ *  0 :
+ *  1 :
+ *  2 :
  */
-void et131x_cleanup_module(void)
-{
-	DBG_ENTER(et131x_dbginfo);
-
-	pci_unregister_driver(&et131x_driver);
-
-	DBG_LEAVE(et131x_dbginfo);
-}
-
-/*
- * These macros map the driver-specific init_module() and cleanup_module()
- * routines so they can be called by the kernel.
+static u32 et131x_nmi_disable;	/* 0-2 */
+module_param(et131x_nmi_disable, uint, 0);
+MODULE_PARM_DESC(et131x_nmi_disable, "Disable NMI (0-2) [0]");
+
+/* Module parameter for manual speed setting
+ * Set Link speed and dublex manually (0-5)  [0]
+ *  1 : 10Mb   Half-Duplex
+ *  2 : 10Mb   Full-Duplex
+ *  3 : 100Mb  Half-Duplex
+ *  4 : 100Mb  Full-Duplex
+ *  5 : 1000Mb Full-Duplex
+ *  0 : Auto Speed Auto Duplex // default
  */
-module_init(et131x_init_module);
-module_exit(et131x_cleanup_module);
-
+static u32 et131x_speed_set;
+module_param(et131x_speed_set, uint, 0);
+MODULE_PARM_DESC(et131x_speed_set,
+		"Set Link speed and dublex manually (0-5)  [0] \n  1 : 10Mb   Half-Duplex \n  2 : 10Mb   Full-Duplex \n  3 : 100Mb  Half-Duplex \n  4 : 100Mb  Full-Duplex \n  5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex");
 
 /**
  * et131x_find_adapter - Find the adapter and get all the assigned resources
@@ -240,8 +143,7 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 	uint8_t eepromStat;
 	uint8_t maxPayload = 0;
 	uint8_t read_size_reg;
-
-	DBG_ENTER(et131x_dbginfo);
+	u8 rev;
 
 	/* Allow disabling of Non-Maskable Interrupts in I/O space, to
 	 * support validation.
@@ -252,9 +154,8 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 		RegisterVal = inb(ET1310_NMI_DISABLE);
 		RegisterVal &= 0xf3;
 
-		if (adapter->RegistryNMIDisable == 2) {
+		if (adapter->RegistryNMIDisable == 2)
 			RegisterVal |= 0xc;
-		}
 
 		outb(ET1310_NMI_DISABLE, RegisterVal);
 	}
@@ -266,7 +167,7 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 				      &eepromStat);
 
 	/* THIS IS A WORKAROUND:
- 	 * I need to call this function twice to get my card in a
+	 * I need to call this function twice to get my card in a
 	 * LG M1 Express Dual running. I tried also a msleep before this
 	 * function, because I thougth there could be some time condidions
 	 * but it didn't work. Call the whole function twice also work.
@@ -274,9 +175,8 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 	result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS,
 				      &eepromStat);
 	if (result != PCIBIOS_SUCCESSFUL) {
-		DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for "
+		dev_err(&pdev->dev, "Could not read PCI config space for "
 			  "EEPROM Status\n");
-		DBG_LEAVE(et131x_dbginfo);
 		return -EIO;
 	}
 
@@ -284,30 +184,26 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 	 * present, we need to fail.
 	 */
 	if (eepromStat & 0x4C) {
-		result = pci_read_config_byte(pdev, PCI_REVISION_ID,
-					      &adapter->RevisionID);
+		result = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
 		if (result != PCIBIOS_SUCCESSFUL) {
-			DBG_ERROR(et131x_dbginfo,
+			dev_err(&pdev->dev,
 				  "Could not read PCI config space for "
 				  "Revision ID\n");
-			DBG_LEAVE(et131x_dbginfo);
 			return -EIO;
-		} else if (adapter->RevisionID == 0x01) {
+		} else if (rev == 0x01) {
 			int32_t nLoop;
-			uint8_t ucTemp[4] = { 0xFE, 0x13, 0x10, 0xFF };
+			uint8_t temp[4] = { 0xFE, 0x13, 0x10, 0xFF };
 
 			/* Re-write the first 4 bytes if we have an eeprom
 			 * present and the revision id is 1, this fixes the
 			 * corruption seen with 1310 B Silicon
 			 */
 			for (nLoop = 0; nLoop < 3; nLoop++) {
-				EepromWriteByte(adapter, nLoop, ucTemp[nLoop],
-						0, SINGLE_BYTE);
+				EepromWriteByte(adapter, nLoop, temp[nLoop]);
 			}
 		}
 
-		DBG_ERROR(et131x_dbginfo,
-			  "Fatal EEPROM Status Error - 0x%04x\n", eepromStat);
+		dev_err(&pdev->dev, "Fatal EEPROM Status Error - 0x%04x\n", eepromStat);
 
 		/* This error could mean that there was an error reading the
 		 * eeprom or that the eeprom doesn't exist.  We will treat
@@ -315,39 +211,33 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 		 * information that normally would come from the eeprom, like
 		 * MAC Address
 		 */
-		adapter->bEepromPresent = false;
-
-		DBG_LEAVE(et131x_dbginfo);
+		adapter->has_eeprom = 0;
 		return -EIO;
-	} else {
-		DBG_TRACE(et131x_dbginfo, "EEPROM Status Code - 0x%04x\n",
-			  eepromStat);
-		adapter->bEepromPresent = true;
-	}
+	} else
+		adapter->has_eeprom = 1;
 
 	/* Read the EEPROM for information regarding LED behavior. Refer to
 	 * ET1310_phy.c, et131x_xcvr_init(), for its use.
 	 */
-	EepromReadByte(adapter, 0x70, &adapter->eepromData[0], 0, SINGLE_BYTE);
-	EepromReadByte(adapter, 0x71, &adapter->eepromData[1], 0, SINGLE_BYTE);
+	EepromReadByte(adapter, 0x70, &adapter->eepromData[0]);
+	EepromReadByte(adapter, 0x71, &adapter->eepromData[1]);
 
-	if (adapter->eepromData[0] != 0xcd) {
-		adapter->eepromData[1] = 0x00;	// Disable all optional features
-	}
+	if (adapter->eepromData[0] != 0xcd)
+		/* Disable all optional features */
+		adapter->eepromData[1] = 0x00;
 
 	/* Let's set up the PORT LOGIC Register.  First we need to know what
 	 * the max_payload_size is
 	 */
 	result = pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &maxPayload);
 	if (result != PCIBIOS_SUCCESSFUL) {
-		DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for "
-			  "Max Payload Size\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&pdev->dev,
+		    "Could not read PCI config space for Max Payload Size\n");
 		return -EIO;
 	}
 
 	/* Program the Ack/Nak latency and replay timers */
-	maxPayload &= 0x07;	// Only the lower 3 bits are valid
+	maxPayload &= 0x07;	/* Only the lower 3 bits are valid */
 
 	if (maxPayload < 2) {
 		const uint16_t AckNak[2] = { 0x76, 0xD0 };
@@ -356,20 +246,16 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 		result = pci_write_config_word(pdev, ET1310_PCI_ACK_NACK,
 					       AckNak[maxPayload]);
 		if (result != PCIBIOS_SUCCESSFUL) {
-			DBG_ERROR(et131x_dbginfo,
-				  "Could not write PCI config space "
-				  "for ACK/NAK\n");
-			DBG_LEAVE(et131x_dbginfo);
+			dev_err(&pdev->dev,
+			  "Could not write PCI config space for ACK/NAK\n");
 			return -EIO;
 		}
 
 		result = pci_write_config_word(pdev, ET1310_PCI_REPLAY,
 					       Replay[maxPayload]);
 		if (result != PCIBIOS_SUCCESSFUL) {
-			DBG_ERROR(et131x_dbginfo,
-				  "Could not write PCI config space "
-				  "for Replay Timer\n");
-			DBG_LEAVE(et131x_dbginfo);
+			dev_err(&pdev->dev,
+			  "Could not write PCI config space for Replay Timer\n");
 			return -EIO;
 		}
 	}
@@ -379,19 +265,16 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 	 */
 	result = pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11);
 	if (result != PCIBIOS_SUCCESSFUL) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Could not write PCI config space for "
-			  "Latency Timers\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&pdev->dev,
+		  "Could not write PCI config space for Latency Timers\n");
 		return -EIO;
 	}
 
 	/* Change the max read size to 2k */
 	result = pci_read_config_byte(pdev, 0x51, &read_size_reg);
 	if (result != PCIBIOS_SUCCESSFUL) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Could not read PCI config space for Max read size\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&pdev->dev,
+			"Could not read PCI config space for Max read size\n");
 		return -EIO;
 	}
 
@@ -400,26 +283,15 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 
 	result = pci_write_config_byte(pdev, 0x51, read_size_reg);
 	if (result != PCIBIOS_SUCCESSFUL) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Could not write PCI config space for Max read size\n");
-		DBG_LEAVE(et131x_dbginfo);
-		return -EIO;
-	}
-
-	/* PCI Express Configuration registers 0x48-0x5B (Device Control) */
-	result = pci_read_config_word(pdev, ET1310_PCI_DEV_CTRL,
-				      &adapter->PciXDevCtl);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Could not read PCI config space for PCI Express Dev Ctl\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&pdev->dev,
+		      "Could not write PCI config space for Max read size\n");
 		return -EIO;
 	}
 
 	/* Get MAC address from config space if an eeprom exists, otherwise
 	 * the MAC address there will not be valid
 	 */
-	if (adapter->bEepromPresent) {
+	if (adapter->has_eeprom) {
 		int i;
 
 		for (i = 0; i < ETH_ALEN; i++) {
@@ -427,15 +299,11 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
 					pdev, ET1310_PCI_MAC_ADDRESS + i,
 					adapter->PermanentAddress + i);
 			if (result != PCIBIOS_SUCCESSFUL) {
-				DBG_ERROR(et131x_dbginfo,
-					  "Could not read PCI config space for MAC address\n");
-				DBG_LEAVE(et131x_dbginfo);
+				dev_err(&pdev->dev, ";Could not read PCI config space for MAC address\n");
 				return -EIO;
 			}
 		}
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 	return 0;
 }
 
@@ -448,42 +316,39 @@ int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
  */
 void et131x_error_timer_handler(unsigned long data)
 {
-	struct et131x_adapter *pAdapter = (struct et131x_adapter *) data;
-	PM_CSR_t pm_csr;
+	struct et131x_adapter *etdev = (struct et131x_adapter *) data;
+	u32 pm_csr;
 
-	pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+	pm_csr = readl(&etdev->regs->global.pm_csr);
 
-	if (pm_csr.bits.pm_phy_sw_coma == 0) {
-		if (pAdapter->RegistryMACStat) {
-			UpdateMacStatHostCounters(pAdapter);
-		}
-	} else {
-		DBG_VERBOSE(et131x_dbginfo,
-			    "No interrupts, in PHY coma, pm_csr = 0x%x\n",
-			    pm_csr.value);
-	}
+	if ((pm_csr & ET_PM_PHY_SW_COMA) == 0)
+		UpdateMacStatHostCounters(etdev);
+	else
+		dev_err(&etdev->pdev->dev,
+		    "No interrupts, in PHY coma, pm_csr = 0x%x\n", pm_csr);
 
-	if (!pAdapter->Bmsr.bits.link_status &&
-	    pAdapter->RegistryPhyComa &&
-	    pAdapter->PoMgmt.TransPhyComaModeOnBoot < 11) {
-		pAdapter->PoMgmt.TransPhyComaModeOnBoot++;
+	if (!etdev->Bmsr.bits.link_status &&
+	    etdev->RegistryPhyComa &&
+	    etdev->PoMgmt.TransPhyComaModeOnBoot < 11) {
+		etdev->PoMgmt.TransPhyComaModeOnBoot++;
 	}
 
-	if (pAdapter->PoMgmt.TransPhyComaModeOnBoot == 10) {
-		if (!pAdapter->Bmsr.bits.link_status
-		    && pAdapter->RegistryPhyComa) {
-			if (pm_csr.bits.pm_phy_sw_coma == 0) {
-				// NOTE - This was originally a 'sync with interrupt'. How
-				//        to do that under Linux?
-				et131x_enable_interrupts(pAdapter);
-				EnablePhyComa(pAdapter);
+	if (etdev->PoMgmt.TransPhyComaModeOnBoot == 10) {
+		if (!etdev->Bmsr.bits.link_status
+		    && etdev->RegistryPhyComa) {
+			if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) {
+				/* NOTE - This was originally a 'sync with
+				 *  interrupt'. How to do that under Linux?
+				 */
+				et131x_enable_interrupts(etdev);
+				EnablePhyComa(etdev);
 			}
 		}
 	}
 
 	/* This is a periodic timer, so reschedule */
-	mod_timer(&pAdapter->ErrorTimer, jiffies +
-		  TX_ERROR_PERIOD * HZ / 1000);
+	mod_timer(&etdev->ErrorTimer, jiffies +
+					  TX_ERROR_PERIOD * HZ / 1000);
 }
 
 /**
@@ -493,85 +358,143 @@ void et131x_error_timer_handler(unsigned long data)
  */
 void et131x_link_detection_handler(unsigned long data)
 {
-	struct et131x_adapter *pAdapter = (struct et131x_adapter *) data;
-	unsigned long lockflags;
+	struct et131x_adapter *etdev = (struct et131x_adapter *) data;
+	unsigned long flags;
 
-	/* Let everyone know that we have run */
-	pAdapter->bLinkTimerActive = false;
+	if (etdev->MediaState == 0) {
+		spin_lock_irqsave(&etdev->Lock, flags);
 
-	if (pAdapter->MediaState == 0) {
-		spin_lock_irqsave(&pAdapter->Lock, lockflags);
+		etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT;
+		etdev->Flags &= ~fMP_ADAPTER_LINK_DETECTION;
 
-		pAdapter->MediaState = NETIF_STATUS_MEDIA_DISCONNECT;
-		MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION);
+		spin_unlock_irqrestore(&etdev->Lock, flags);
 
-		spin_unlock_irqrestore(&pAdapter->Lock, lockflags);
+		netif_carrier_off(etdev->netdev);
+	}
+}
 
-		netif_carrier_off(pAdapter->netdev);
+/**
+ * et131x_configure_global_regs	-	configure JAGCore global regs
+ * @etdev: pointer to our adapter structure
+ *
+ * Used to configure the global registers on the JAGCore
+ */
+void ConfigGlobalRegs(struct et131x_adapter *etdev)
+{
+	struct _GLOBAL_t __iomem *regs = &etdev->regs->global;
+
+	if (etdev->RegistryPhyLoopbk == false) {
+		if (etdev->RegistryJumboPacket < 2048) {
+			/* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word
+			 * block of RAM that the driver can split between Tx
+			 * and Rx as it desires.  Our default is to split it
+			 * 50/50:
+			 */
+			writel(0, &regs->rxq_start_addr);
+			writel(PARM_RX_MEM_END_DEF, &regs->rxq_end_addr);
+			writel(PARM_RX_MEM_END_DEF + 1, &regs->txq_start_addr);
+			writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
+		} else if (etdev->RegistryJumboPacket < 8192) {
+			/* For jumbo packets > 2k but < 8k, split 50-50. */
+			writel(0, &regs->rxq_start_addr);
+			writel(INTERNAL_MEM_RX_OFFSET, &regs->rxq_end_addr);
+			writel(INTERNAL_MEM_RX_OFFSET + 1, &regs->txq_start_addr);
+			writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
+		} else {
+			/* 9216 is the only packet size greater than 8k that
+			 * is available. The Tx buffer has to be big enough
+			 * for one whole packet on the Tx side. We'll make
+			 * the Tx 9408, and give the rest to Rx
+			 */
+			writel(0x0000, &regs->rxq_start_addr);
+			writel(0x01b3, &regs->rxq_end_addr);
+			writel(0x01b4, &regs->txq_start_addr);
+			writel(INTERNAL_MEM_SIZE - 1,&regs->txq_end_addr);
+		}
+
+		/* Initialize the loopback register. Disable all loopbacks. */
+		writel(0, &regs->loopback);
+	} else {
+		/* For PHY Line loopback, the memory is configured as if Tx
+		 * and Rx both have all the memory.  This is because the
+		 * RxMAC will write data into the space, and the TxMAC will
+		 * read it out.
+		 */
+		writel(0, &regs->rxq_start_addr);
+		writel(INTERNAL_MEM_SIZE - 1, &regs->rxq_end_addr);
+		writel(0, &regs->txq_start_addr);
+		writel(INTERNAL_MEM_SIZE - 1, &regs->txq_end_addr);
 
-		pAdapter->bSetPending = false;
+		/* Initialize the loopback register (MAC loopback). */
+		writel(ET_LOOP_MAC, &regs->loopback);
 	}
+
+	/* MSI Register */
+	writel(0, &regs->msi_config);
+
+	/* By default, disable the watchdog timer.  It will be enabled when
+	 * a packet is queued.
+	 */
+	writel(0, &regs->watchdog_timer);
 }
 
+
 /**
  * et131x_adapter_setup - Set the adapter up as per cassini+ documentation
  * @adapter: pointer to our private adapter structure
  *
  * Returns 0 on success, errno on failure (as defined in errno.h)
  */
-int et131x_adapter_setup(struct et131x_adapter *pAdapter)
+int et131x_adapter_setup(struct et131x_adapter *etdev)
 {
 	int status = 0;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Configure the JAGCore */
-	ConfigGlobalRegs(pAdapter);
+	ConfigGlobalRegs(etdev);
 
-	ConfigMACRegs1(pAdapter);
-	ConfigMMCRegs(pAdapter);
+	ConfigMACRegs1(etdev);
 
-	ConfigRxMacRegs(pAdapter);
-	ConfigTxMacRegs(pAdapter);
+	/* Configure the MMC registers */
+	/* All we need to do is initialize the Memory Control Register */
+	writel(ET_MMC_ENABLE, &etdev->regs->mmc.mmc_ctrl);
 
-	ConfigRxDmaRegs(pAdapter);
-	ConfigTxDmaRegs(pAdapter);
+	ConfigRxMacRegs(etdev);
+	ConfigTxMacRegs(etdev);
 
-	ConfigMacStatRegs(pAdapter);
+	ConfigRxDmaRegs(etdev);
+	ConfigTxDmaRegs(etdev);
+
+	ConfigMacStatRegs(etdev);
 
 	/* Move the following code to Timer function?? */
-	status = et131x_xcvr_find(pAdapter);
+	status = et131x_xcvr_find(etdev);
 
-	if (status != 0) {
-		DBG_WARNING(et131x_dbginfo, "Could not find the xcvr\n");
-	}
+	if (status != 0)
+		dev_warn(&etdev->pdev->dev, "Could not find the xcvr\n");
 
 	/* Prepare the TRUEPHY library. */
-	ET1310_PhyInit(pAdapter);
+	ET1310_PhyInit(etdev);
 
 	/* Reset the phy now so changes take place */
-	ET1310_PhyReset(pAdapter);
+	ET1310_PhyReset(etdev);
 
 	/* Power down PHY */
-	ET1310_PhyPowerDown(pAdapter, 1);
+	ET1310_PhyPowerDown(etdev, 1);
 
 	/*
 	 * We need to turn off 1000 base half dulplex, the mac does not
 	 * support it. For the 10/100 part, turn off all gig advertisement
 	 */
-	if (pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST) {
-		ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
-	} else {
-		ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
-	}
+	if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST)
+		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL);
+	else
+		ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE);
 
 	/* Power up PHY */
-	ET1310_PhyPowerDown(pAdapter, 0);
-
-	et131x_setphy_normal(pAdapter);
+	ET1310_PhyPowerDown(etdev, 0);
 
-	DBG_LEAVE(et131x_dbginfo);
-	return status;
+	et131x_setphy_normal(etdev);
+;	return status;
 }
 
 /**
@@ -580,44 +503,37 @@ int et131x_adapter_setup(struct et131x_adapter *pAdapter)
  */
 void et131x_setup_hardware_properties(struct et131x_adapter *adapter)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* If have our default mac from registry and no mac address from
 	 * EEPROM then we need to generate the last octet and set it on the
 	 * device
 	 */
-	if (!adapter->bOverrideAddress) {
-		if (adapter->PermanentAddress[0] == 0x00 &&
-		    adapter->PermanentAddress[1] == 0x00 &&
-		    adapter->PermanentAddress[2] == 0x00 &&
-		    adapter->PermanentAddress[3] == 0x00 &&
-		    adapter->PermanentAddress[4] == 0x00 &&
-		    adapter->PermanentAddress[5] == 0x00) {
-			/*
-			 * We need to randomly generate the last octet so we
-			 * decrease our chances of setting the mac address to
-			 * same as another one of our cards in the system
-			 */
-			get_random_bytes(&adapter->CurrentAddress[5], 1);
-
-			/*
-			 * We have the default value in the register we are
-			 * working with so we need to copy the current
-			 * address into the permanent address
-			 */
-			memcpy(adapter->PermanentAddress,
-			       adapter->CurrentAddress, ETH_ALEN);
-		} else {
-			/* We do not have an override address, so set the
-			 * current address to the permanent address and add
-			 * it to the device
-			 */
-			memcpy(adapter->CurrentAddress,
-			       adapter->PermanentAddress, ETH_ALEN);
-		}
+	if (adapter->PermanentAddress[0] == 0x00 &&
+	    adapter->PermanentAddress[1] == 0x00 &&
+	    adapter->PermanentAddress[2] == 0x00 &&
+	    adapter->PermanentAddress[3] == 0x00 &&
+	    adapter->PermanentAddress[4] == 0x00 &&
+	    adapter->PermanentAddress[5] == 0x00) {
+		/*
+		 * We need to randomly generate the last octet so we
+		 * decrease our chances of setting the mac address to
+		 * same as another one of our cards in the system
+		 */
+		get_random_bytes(&adapter->CurrentAddress[5], 1);
+		/*
+		 * We have the default value in the register we are
+		 * working with so we need to copy the current
+		 * address into the permanent address
+		 */
+		memcpy(adapter->PermanentAddress,
+			adapter->CurrentAddress, ETH_ALEN);
+	} else {
+		/* We do not have an override address, so set the
+		 * current address to the permanent address and add
+		 * it to the device
+		 */
+		memcpy(adapter->CurrentAddress,
+		       adapter->PermanentAddress, ETH_ALEN);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
@@ -626,17 +542,13 @@ void et131x_setup_hardware_properties(struct et131x_adapter *adapter)
  */
 void et131x_soft_reset(struct et131x_adapter *adapter)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Disable MAC Core */
-	writel(0xc00f0000, &adapter->CSRAddress->mac.cfg1.value);
+	writel(0xc00f0000, &adapter->regs->mac.cfg1.value);
 
 	/* Set everything to a reset value */
-	writel(0x7F, &adapter->CSRAddress->global.sw_reset.value);
-	writel(0x000f0000, &adapter->CSRAddress->mac.cfg1.value);
-	writel(0x00000000, &adapter->CSRAddress->mac.cfg1.value);
-
-	DBG_LEAVE(et131x_dbginfo);
+	writel(0x7F, &adapter->regs->global.sw_reset);
+	writel(0x000f0000, &adapter->regs->mac.cfg1.value);
+	writel(0x00000000, &adapter->regs->mac.cfg1.value);
 }
 
 /**
@@ -652,8 +564,6 @@ void et131x_align_allocated_memory(struct et131x_adapter *adapter,
 {
 	uint64_t new_addr;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	*offset = 0;
 
 	new_addr = *phys_addr & ~mask;
@@ -666,8 +576,6 @@ void et131x_align_allocated_memory(struct et131x_adapter *adapter,
 		/* Return new physical address */
 		*phys_addr = new_addr;
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
 /**
@@ -682,13 +590,11 @@ int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
 {
 	int status = 0;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	do {
 		/* Allocate memory for the Tx Ring */
 		status = et131x_tx_dma_memory_alloc(adapter);
 		if (status != 0) {
-			DBG_ERROR(et131x_dbginfo,
+			dev_err(&adapter->pdev->dev,
 				  "et131x_tx_dma_memory_alloc FAILED\n");
 			break;
 		}
@@ -696,7 +602,7 @@ int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
 		/* Receive buffer memory allocation */
 		status = et131x_rx_dma_memory_alloc(adapter);
 		if (status != 0) {
-			DBG_ERROR(et131x_dbginfo,
+			dev_err(&adapter->pdev->dev,
 				  "et131x_rx_dma_memory_alloc FAILED\n");
 			et131x_tx_dma_memory_free(adapter);
 			break;
@@ -705,14 +611,13 @@ int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
 		/* Init receive data structures */
 		status = et131x_init_recv(adapter);
 		if (status != 0) {
-			DBG_ERROR(et131x_dbginfo, "et131x_init_recv FAILED\n");
+			dev_err(&adapter->pdev->dev,
+				"et131x_init_recv FAILED\n");
 			et131x_tx_dma_memory_free(adapter);
 			et131x_rx_dma_memory_free(adapter);
 			break;
 		}
 	} while (0);
-
-	DBG_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -722,15 +627,56 @@ int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
  */
 void et131x_adapter_memory_free(struct et131x_adapter *adapter)
 {
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Free DMA memory */
 	et131x_tx_dma_memory_free(adapter);
 	et131x_rx_dma_memory_free(adapter);
+}
+
+/**
+ * et131x_config_parse
+ * @etdev: pointer to the private adapter struct
+ *
+ * Parses a configuration from some location (module parameters, for example)
+ * into the private adapter struct. This really has no sensible analogy in
+ * Linux as sysfs parameters are dynamic. Several things that were hee could
+ * go into sysfs, but other stuff like speed handling is part of the mii
+ * interfaces/ethtool.
+ */
+void et131x_config_parse(struct et131x_adapter *etdev)
+{
+	static const u8 default_mac[] = { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 };
+	static const u8 duplex[] = { 0, 1, 2, 1, 2, 2 };
+	static const u16 speed[] = { 0, 10, 10, 100, 100, 1000 };
+
+	if (et131x_speed_set)
+		dev_info(&etdev->pdev->dev,
+			"Speed set manually to : %d \n", et131x_speed_set);
+
+	etdev->SpeedDuplex = et131x_speed_set;
+	etdev->RegistryJumboPacket = 1514;	/* 1514-9216 */
 
-	DBG_LEAVE(et131x_dbginfo);
+	etdev->RegistryNMIDisable = et131x_nmi_disable;
+
+	/* Set the MAC address to a default */
+	memcpy(etdev->CurrentAddress, default_mac, ETH_ALEN);
+
+	/* Decode SpeedDuplex
+	 *
+	 * Set up as if we are auto negotiating always and then change if we
+	 * go into force mode
+	 *
+	 * If we are the 10/100 device, and gigabit is somehow requested then
+	 * knock it down to 100 full.
+	 */
+	if (etdev->pdev->device == ET131X_PCI_DEVICE_ID_FAST &&
+	    etdev->SpeedDuplex == 5)
+		etdev->SpeedDuplex = 4;
+
+	etdev->AiForceSpeed = speed[etdev->SpeedDuplex];
+	etdev->AiForceDpx = duplex[etdev->SpeedDuplex];	/* Auto FDX */
 }
 
+
 /**
  * et131x_pci_remove
  * @pdev: a pointer to the device's pci_dev structure
@@ -739,13 +685,12 @@ void et131x_adapter_memory_free(struct et131x_adapter *adapter)
  * PCI subsystem detects that a PCI device which matches the information
  * contained in the pci_device_id table has been removed.
  */
+
 void __devexit et131x_pci_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev;
 	struct et131x_adapter *adapter;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Retrieve the net_device pointer from the pci_dev struct, as well
 	 * as the private adapter struct
 	 */
@@ -755,14 +700,14 @@ void __devexit et131x_pci_remove(struct pci_dev *pdev)
 	/* Perform device cleanup */
 	unregister_netdev(netdev);
 	et131x_adapter_memory_free(adapter);
-	iounmap(adapter->CSRAddress);
+	iounmap(adapter->regs);
+	pci_dev_put(adapter->pdev);
 	free_netdev(netdev);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
-
-	DBG_LEAVE(et131x_dbginfo);
 }
 
+
 /**
  * et131x_pci_setup - Perform device initialization
  * @pdev: a pointer to the device's pci_dev structure
@@ -775,6 +720,7 @@ void __devexit et131x_pci_remove(struct pci_dev *pdev)
  * contained in the pci_device_id table. This routine is the equivalent to
  * a device insertion routine.
  */
+
 int __devinit et131x_pci_setup(struct pci_dev *pdev,
 			       const struct pci_device_id *ent)
 {
@@ -784,18 +730,17 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	struct net_device *netdev = NULL;
 	struct et131x_adapter *adapter = NULL;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Enable the device via the PCI subsystem */
 	result = pci_enable_device(pdev);
 	if (result != 0) {
-		DBG_ERROR(et131x_dbginfo, "pci_enable_device() failed\n");
+		dev_err(&adapter->pdev->dev,
+			"pci_enable_device() failed\n");
 		goto out;
 	}
 
 	/* Perform some basic PCI checks */
 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&adapter->pdev->dev,
 			  "Can't find PCI device's base address\n");
 		result = -ENODEV;
 		goto out;
@@ -803,12 +748,12 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 
 	result = pci_request_regions(pdev, DRIVER_NAME);
 	if (result != 0) {
-		DBG_ERROR(et131x_dbginfo, "Can't get PCI resources\n");
+		dev_err(&adapter->pdev->dev,
+			"Can't get PCI resources\n");
 		goto err_disable;
 	}
 
 	/* Enable PCI bus mastering */
-	DBG_TRACE(et131x_dbginfo, "Setting PCI Bus Mastering...\n");
 	pci_set_master(pdev);
 
 	/* Query PCI for Power Mgmt Capabilities
@@ -818,7 +763,7 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	 */
 	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (pm_cap == 0) {
-		DBG_ERROR(et131x_dbginfo,
+		dev_err(&adapter->pdev->dev,
 			  "Cannot find Power Management capabilities\n");
 		result = -EIO;
 		goto err_release_res;
@@ -826,44 +771,40 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 
 	/* Check the DMA addressing support of this device */
 	if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
-		DBG_TRACE(et131x_dbginfo, "64-bit DMA addressing supported\n");
 		pci_using_dac = true;
 
 		result =
 		    pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
 		if (result != 0) {
-			DBG_ERROR(et131x_dbginfo,
+			dev_err(&pdev->dev,
 				  "Unable to obtain 64 bit DMA for consistent allocations\n");
 			goto err_release_res;
 		}
 	} else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) {
-		DBG_TRACE(et131x_dbginfo,
-			  "64-bit DMA addressing NOT supported\n");
-		DBG_TRACE(et131x_dbginfo,
-			  "32-bit DMA addressing will be used\n");
 		pci_using_dac = false;
 	} else {
-		DBG_ERROR(et131x_dbginfo, "No usable DMA addressing method\n");
+		dev_err(&adapter->pdev->dev,
+			"No usable DMA addressing method\n");
 		result = -EIO;
 		goto err_release_res;
 	}
 
 	/* Allocate netdev and private adapter structs */
-	DBG_TRACE(et131x_dbginfo,
-		  "Allocate netdev and private adapter structs...\n");
 	netdev = et131x_device_alloc();
 	if (netdev == NULL) {
-		DBG_ERROR(et131x_dbginfo, "Couldn't alloc netdev struct\n");
+		dev_err(&adapter->pdev->dev,
+			"Couldn't alloc netdev struct\n");
 		result = -ENOMEM;
 		goto err_release_res;
 	}
 
 	/* Setup the fundamental net_device and private adapter structure elements  */
-	DBG_TRACE(et131x_dbginfo, "Setting fundamental net_device info...\n");
 	SET_NETDEV_DEV(netdev, &pdev->dev);
+	/*
 	if (pci_using_dac) {
-		//netdev->features |= NETIF_F_HIGHDMA;
+		netdev->features |= NETIF_F_HIGHDMA;
 	}
+	*/
 
 	/*
 	 * NOTE - Turn this on when we're ready to deal with SG-DMA
@@ -884,24 +825,20 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	 * receiving a scattered buffer from the network stack, so leave it
 	 * off until checksums are calculated in HW.
 	 */
-	//netdev->features |= NETIF_F_SG;
-	//netdev->features |= NETIF_F_NO_CSUM;
-	//netdev->features |= NETIF_F_LLTX;
+	/* netdev->features |= NETIF_F_SG; */
+	/* netdev->features |= NETIF_F_NO_CSUM; */
+	/* netdev->features |= NETIF_F_LLTX; */
 
 	/* Allocate private adapter struct and copy in relevant information */
 	adapter = netdev_priv(netdev);
-	adapter->pdev = pdev;
+	adapter->pdev = pci_dev_get(pdev);
 	adapter->netdev = netdev;
-	adapter->VendorID = pdev->vendor;
-	adapter->DeviceID = pdev->device;
 
 	/* Do the same for the netdev struct */
 	netdev->irq = pdev->irq;
 	netdev->base_addr = pdev->resource[0].start;
 
 	/* Initialize spinlocks here */
-	DBG_TRACE(et131x_dbginfo, "Initialize spinlocks...\n");
-
 	spin_lock_init(&adapter->Lock);
 	spin_lock_init(&adapter->TCBSendQLock);
 	spin_lock_init(&adapter->TCBReadyQLock);
@@ -921,17 +858,15 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	 *       lump it's init with the device specific init below into a
 	 *       single init function?
 	 */
-	//while (et131x_find_adapter(adapter, pdev) != 0);
+	/* while (et131x_find_adapter(adapter, pdev) != 0); */
 	et131x_find_adapter(adapter, pdev);
 
 	/* Map the bus-relative registers to system virtual memory */
-	DBG_TRACE(et131x_dbginfo,
-		  "Mapping bus-relative registers to virtual memory...\n");
 
-	adapter->CSRAddress = ioremap_nocache(pci_resource_start(pdev, 0),
+	adapter->regs = ioremap_nocache(pci_resource_start(pdev, 0),
 					      pci_resource_len(pdev, 0));
-	if (adapter->CSRAddress == NULL) {
-		DBG_ERROR(et131x_dbginfo, "Cannot map device registers\n");
+	if (adapter->regs == NULL) {
+		dev_err(&pdev->dev, "Cannot map device registers\n");
 		result = -ENOMEM;
 		goto err_free_dev;
 	}
@@ -939,38 +874,24 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	/* Perform device-specific initialization here (See code below) */
 
 	/* If Phy COMA mode was enabled when we went down, disable it here. */
-	{
-		PM_CSR_t GlobalPmCSR = { 0 };
-
-		GlobalPmCSR.bits.pm_sysclk_gate = 1;
-		GlobalPmCSR.bits.pm_txclk_gate = 1;
-		GlobalPmCSR.bits.pm_rxclk_gate = 1;
-		writel(GlobalPmCSR.value,
-		       &adapter->CSRAddress->global.pm_csr.value);
-	}
+	writel(ET_PMCSR_INIT,  &adapter->regs->global.pm_csr);
 
 	/* Issue a global reset to the et1310 */
-	DBG_TRACE(et131x_dbginfo, "Issuing soft reset...\n");
 	et131x_soft_reset(adapter);
 
 	/* Disable all interrupts (paranoid) */
-	DBG_TRACE(et131x_dbginfo, "Disable device interrupts...\n");
 	et131x_disable_interrupts(adapter);
 
 	/* Allocate DMA memory */
 	result = et131x_adapter_memory_alloc(adapter);
 	if (result != 0) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Could not alloc adapater memory (DMA)\n");
+		dev_err(&pdev->dev, "Could not alloc adapater memory (DMA)\n");
 		goto err_iounmap;
 	}
 
 	/* Init send data structures */
-	DBG_TRACE(et131x_dbginfo, "Init send data structures...\n");
 	et131x_init_send(adapter);
 
-	adapter->PoMgmt.PowerState = NdisDeviceStateD0;
-
 	/* Register the interrupt
 	 *
 	 * NOTE - This is being done in the open routine, where most other
@@ -983,13 +904,11 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	INIT_WORK(&adapter->task, et131x_isr_handler);
 
 	/* Determine MAC Address, and copy into the net_device struct */
-	DBG_TRACE(et131x_dbginfo, "Retrieve MAC address...\n");
 	et131x_setup_hardware_properties(adapter);
 
 	memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN);
 
 	/* Setup et1310 as per the documentation */
-	DBG_TRACE(et131x_dbginfo, "Setup the adapter...\n");
 	et131x_adapter_setup(adapter);
 
 	/* Create a timer to count errors received by the NIC */
@@ -1002,7 +921,8 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	/* Initialize link state */
 	et131x_link_detection_handler((unsigned long)adapter);
 
-	/* Intialize variable for counting how long we do not have link status */
+	/* Intialize variable for counting how long we do not have
+							link status */
 	adapter->PoMgmt.TransPhyComaModeOnBoot = 0;
 
 	/* We can enable interrupts now
@@ -1013,9 +933,9 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	 */
 
 	/* Register the net_device struct with the Linux network layer */
-	DBG_TRACE(et131x_dbginfo, "Registering net_device...\n");
-	if ((result = register_netdev(netdev)) != 0) {
-		DBG_ERROR(et131x_dbginfo, "register_netdev() failed\n");
+	result = register_netdev(netdev);
+	if (result != 0) {
+		dev_err(&pdev->dev, "register_netdev() failed\n");
 		goto err_mem_free;
 	}
 
@@ -1028,14 +948,14 @@ int __devinit et131x_pci_setup(struct pci_dev *pdev,
 	pci_save_state(adapter->pdev);
 
 out:
-	DBG_LEAVE(et131x_dbginfo);
 	return result;
 
 err_mem_free:
 	et131x_adapter_memory_free(adapter);
 err_iounmap:
-	iounmap(adapter->CSRAddress);
+	iounmap(adapter->regs);
 err_free_dev:
+	pci_dev_put(pdev);
 	free_netdev(netdev);
 err_release_res:
 	pci_release_regions(pdev);
@@ -1043,3 +963,55 @@ err_disable:
 	pci_disable_device(pdev);
 	goto out;
 }
+
+static struct pci_device_id et131x_pci_table[] __devinitdata = {
+	{ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID,
+	 PCI_ANY_ID, 0, 0, 0UL},
+	{ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID,
+	 PCI_ANY_ID, 0, 0, 0UL},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, et131x_pci_table);
+
+static struct pci_driver et131x_driver = {
+      .name	= DRIVER_NAME,
+      .id_table	= et131x_pci_table,
+      .probe	= et131x_pci_setup,
+      .remove	= __devexit_p(et131x_pci_remove),
+      .suspend	= NULL,		/* et131x_pci_suspend */
+      .resume	= NULL,		/* et131x_pci_resume */
+};
+
+
+/**
+ * et131x_init_module - The "main" entry point called on driver initialization
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+static int et131x_init_module(void)
+{
+	if (et131x_speed_set < PARM_SPEED_DUPLEX_MIN ||
+	    et131x_speed_set > PARM_SPEED_DUPLEX_MAX) {
+		printk(KERN_WARNING "et131x: invalid speed setting ignored.\n");
+	    	et131x_speed_set = 0;
+	}
+	return pci_register_driver(&et131x_driver);
+}
+
+/**
+ * et131x_cleanup_module - The entry point called on driver cleanup
+ */
+static void et131x_cleanup_module(void)
+{
+	pci_unregister_driver(&et131x_driver);
+}
+
+module_init(et131x_init_module);
+module_exit(et131x_cleanup_module);
+
+
+/* Modinfo parameters (filled out using defines from et131x_version.h) */
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_INFO);
+MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h
index bbacb62..8131d6a 100644
--- a/drivers/staging/et131x/et131x_initpci.h
+++ b/drivers/staging/et131x/et131x_initpci.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c
index 00afad1..f80189d 100644
--- a/drivers/staging/et131x/et131x_isr.c
+++ b/drivers/staging/et131x/et131x_isr.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -57,7 +57,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/init.h>
@@ -74,9 +73,10 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -91,10 +91,45 @@
 
 #include "et131x_adapter.h"
 
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
+/**
+ *	et131x_enable_interrupts	-	enable interrupt
+ *	@adapter: et131x device
+ *
+ *	Enable the appropriate interrupts on the ET131x according to our
+ *	configuration
+ */
+
+void et131x_enable_interrupts(struct et131x_adapter *adapter)
+{
+	u32 mask;
+
+	/* Enable all global interrupts */
+	if (adapter->FlowControl == TxOnly || adapter->FlowControl == Both)
+		mask = INT_MASK_ENABLE;
+	else
+		mask = INT_MASK_ENABLE_NO_FLOW;
+
+	if (adapter->DriverNoPhyAccess)
+		mask |= ET_INTR_PHY;
+
+	adapter->CachedMaskValue = mask;
+	writel(mask, &adapter->regs->global.int_mask);
+}
+
+/**
+ *	et131x_disable_interrupts	-	interrupt disable
+ *	@adapter: et131x device
+ *
+ *	Block all interrupts from the et131x device at the device itself
+ */
+
+void et131x_disable_interrupts(struct et131x_adapter *adapter)
+{
+	/* Disable all global interrupts */
+	adapter->CachedMaskValue = INT_MASK_DISABLE;
+	writel(INT_MASK_DISABLE, &adapter->regs->global.int_mask);
+}
+
 
 /**
  * et131x_isr - The Interrupt Service Routine for the driver.
@@ -103,16 +138,15 @@ extern dbg_info_t *et131x_dbginfo;
  *
  * Returns a value indicating if the interrupt was handled.
  */
+
 irqreturn_t et131x_isr(int irq, void *dev_id)
 {
 	bool handled = true;
 	struct net_device *netdev = (struct net_device *)dev_id;
 	struct et131x_adapter *adapter = NULL;
-	INTERRUPT_t status;
+	u32 status;
 
-	if (netdev == NULL || !netif_device_present(netdev)) {
-		DBG_WARNING(et131x_dbginfo,
-			    "No net_device struct or device not present\n");
+	if (!netif_device_present(netdev)) {
 		handled = false;
 		goto out;
 	}
@@ -129,59 +163,40 @@ irqreturn_t et131x_isr(int irq, void *dev_id)
 	/* Get a copy of the value in the interrupt status register
 	 * so we can process the interrupting section
 	 */
-	status.value = readl(&adapter->CSRAddress->global.int_status.value);
+	status = readl(&adapter->regs->global.int_status);
 
 	if (adapter->FlowControl == TxOnly ||
 	    adapter->FlowControl == Both) {
-		status.value &= ~INT_MASK_ENABLE;
+		status &= ~INT_MASK_ENABLE;
 	} else {
-		status.value &= ~INT_MASK_ENABLE_NO_FLOW;
+		status &= ~INT_MASK_ENABLE_NO_FLOW;
 	}
 
 	/* Make sure this is our interrupt */
-	if (!status.value) {
-#ifdef CONFIG_ET131X_DEBUG
-		adapter->Stats.UnhandledInterruptsPerSec++;
-#endif
+	if (!status) {
 		handled = false;
-		DBG_VERBOSE(et131x_dbginfo, "NOT OUR INTERRUPT\n");
 		et131x_enable_interrupts(adapter);
 		goto out;
 	}
 
 	/* This is our interrupt, so process accordingly */
-#ifdef CONFIG_ET131X_DEBUG
-	if (status.bits.rxdma_xfr_done) {
-		adapter->Stats.RxDmaInterruptsPerSec++;
-	}
 
-	if (status.bits.txdma_isr) {
-		adapter->Stats.TxDmaInterruptsPerSec++;
-	}
-#endif
-
-	if (status.bits.watchdog_interrupt) {
+	if (status & ET_INTR_WATCHDOG) {
 		PMP_TCB pMpTcb = adapter->TxRing.CurrSendHead;
 
-		if (pMpTcb) {
-			if (++pMpTcb->PacketStaleCount > 1) {
-				status.bits.txdma_isr = 1;
-			}
-		}
+		if (pMpTcb)
+			if (++pMpTcb->PacketStaleCount > 1)
+				status |= ET_INTR_TXDMA_ISR;
 
-		if (adapter->RxRing.UnfinishedReceives) {
-			status.bits.rxdma_xfr_done = 1;
-		} else if (pMpTcb == NULL) {
-			writel(0, &adapter->CSRAddress->global.watchdog_timer);
-		}
+		if (adapter->RxRing.UnfinishedReceives)
+			status |= ET_INTR_RXDMA_XFR_DONE;
+		else if (pMpTcb == NULL)
+			writel(0, &adapter->regs->global.watchdog_timer);
 
-		status.bits.watchdog_interrupt = 0;
-#ifdef CONFIG_ET131X_DEBUG
-		adapter->Stats.WatchDogInterruptsPerSec++;
-#endif
+		status &= ~ET_INTR_WATCHDOG;
 	}
 
-	if (status.value == 0) {
+	if (status == 0) {
 		/* This interrupt has in some way been "handled" by
 		 * the ISR. Either it was a spurious Rx interrupt, or
 		 * it was a Tx interrupt that has been filtered by
@@ -202,7 +217,6 @@ irqreturn_t et131x_isr(int irq, void *dev_id)
 	 * execution
 	 */
 	schedule_work(&adapter->task);
-
 out:
 	return IRQ_RETVAL(handled);
 }
@@ -216,10 +230,10 @@ out:
  */
 void et131x_isr_handler(struct work_struct *work)
 {
-	struct et131x_adapter *pAdapter =
+	struct et131x_adapter *etdev =
 		container_of(work, struct et131x_adapter, task);
-	INTERRUPT_t GlobStatus = pAdapter->Stats.InterruptStatus;
-	ADDRESS_MAP_t __iomem *iomem = pAdapter->CSRAddress;
+	u32 status = etdev->Stats.InterruptStatus;
+	ADDRESS_MAP_t __iomem *iomem = etdev->regs;
 
 	/*
 	 * These first two are by far the most common.  Once handled, we clear
@@ -227,35 +241,32 @@ void et131x_isr_handler(struct work_struct *work)
 	 * exit.
 	 */
 	/* Handle all the completed Transmit interrupts */
-	if (GlobStatus.bits.txdma_isr) {
-		DBG_TX(et131x_dbginfo, "TXDMA_ISR interrupt\n");
-		et131x_handle_send_interrupt(pAdapter);
+	if (status & ET_INTR_TXDMA_ISR) {
+		et131x_handle_send_interrupt(etdev);
 	}
 
 	/* Handle all the completed Receives interrupts */
-	if (GlobStatus.bits.rxdma_xfr_done) {
-		DBG_RX(et131x_dbginfo, "RXDMA_XFR_DONE interrupt\n");
-		et131x_handle_recv_interrupt(pAdapter);
+	if (status & ET_INTR_RXDMA_XFR_DONE) {
+		et131x_handle_recv_interrupt(etdev);
 	}
 
-	GlobStatus.value &= 0xffffffd7;
+	status &= 0xffffffd7;
 
-	if (GlobStatus.value) {
+	if (status) {
 		/* Handle the TXDMA Error interrupt */
-		if (GlobStatus.bits.txdma_err) {
-			TXDMA_ERROR_t TxDmaErr;
+		if (status & ET_INTR_TXDMA_ERR) {
+			u32 txdma_err;
 
 			/* Following read also clears the register (COR) */
-			TxDmaErr.value = readl(&iomem->txdma.TxDmaError.value);
+			txdma_err = readl(&iomem->txdma.TxDmaError);
 
-			DBG_WARNING(et131x_dbginfo,
+			dev_warn(&etdev->pdev->dev,
 				    "TXDMA_ERR interrupt, error = %d\n",
-				    TxDmaErr.value);
+				    txdma_err);
 		}
 
 		/* Handle Free Buffer Ring 0 and 1 Low interrupt */
-		if (GlobStatus.bits.rxdma_fb_ring0_low ||
-		    GlobStatus.bits.rxdma_fb_ring1_low) {
+		if (status & (ET_INTR_RXDMA_FB_R0_LOW | ET_INTR_RXDMA_FB_R1_LOW)) {
 			/*
 			 * This indicates the number of unused buffers in
 			 * RXDMA free buffer ring 0 is <= the limit you
@@ -270,22 +281,19 @@ void et131x_isr_handler(struct work_struct *work)
 			 * ET1310 for re-use. This interrupt is one method of
 			 * returning resources.
 			 */
-			DBG_WARNING(et131x_dbginfo,
-				    "RXDMA_FB_RING0_LOW or "
-				    "RXDMA_FB_RING1_LOW interrupt\n");
 
 			/* If the user has flow control on, then we will
 			 * send a pause packet, otherwise just exit
 			 */
-			if (pAdapter->FlowControl == TxOnly ||
-			    pAdapter->FlowControl == Both) {
-				PM_CSR_t pm_csr;
+			if (etdev->FlowControl == TxOnly ||
+			    etdev->FlowControl == Both) {
+				u32 pm_csr;
 
 				/* Tell the device to send a pause packet via
 				 * the back pressure register
 				 */
-				pm_csr.value = readl(&iomem->global.pm_csr.value);
-				if (pm_csr.bits.pm_phy_sw_coma == 0) {
+				pm_csr = readl(&iomem->global.pm_csr);
+				if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) {
 					TXMAC_BP_CTRL_t bp_ctrl = { 0 };
 
 					bp_ctrl.bits.bp_req = 1;
@@ -297,9 +305,7 @@ void et131x_isr_handler(struct work_struct *work)
 		}
 
 		/* Handle Packet Status Ring Low Interrupt */
-		if (GlobStatus.bits.rxdma_pkt_stat_ring_low) {
-			DBG_WARNING(et131x_dbginfo,
-				    "RXDMA_PKT_STAT_RING_LOW interrupt\n");
+		if (status & ET_INTR_RXDMA_STAT_LOW) {
 
 			/*
 			 * Same idea as with the two Free Buffer Rings.
@@ -313,7 +319,7 @@ void et131x_isr_handler(struct work_struct *work)
 		}
 
 		/* Handle RXDMA Error Interrupt */
-		if (GlobStatus.bits.rxdma_err) {
+		if (status & ET_INTR_RXDMA_ERR) {
 			/*
 			 * The rxdma_error interrupt is sent when a time-out
 			 * on a request issued by the JAGCore has occurred or
@@ -332,17 +338,17 @@ void et131x_isr_handler(struct work_struct *work)
 			 * something bad has occurred. A reset might be the
 			 * thing to do.
 			 */
-			// TRAP();
+			/* TRAP();*/
 
-			pAdapter->TxMacTest.value =
+			etdev->TxMacTest.value =
 				readl(&iomem->txmac.tx_test.value);
-			DBG_WARNING(et131x_dbginfo,
+			dev_warn(&etdev->pdev->dev,
 				    "RxDMA_ERR interrupt, error %x\n",
-				    pAdapter->TxMacTest.value);
+				    etdev->TxMacTest.value);
 		}
 
 		/* Handle the Wake on LAN Event */
-		if (GlobStatus.bits.wake_on_lan) {
+		if (status & ET_INTR_WOL) {
 			/*
 			 * This is a secondary interrupt for wake on LAN.
 			 * The driver should never see this, if it does,
@@ -350,61 +356,51 @@ void et131x_isr_handler(struct work_struct *work)
 			 * message when we are in DBG mode, otherwise we
 			 * will ignore it.
 			 */
-			DBG_ERROR(et131x_dbginfo, "WAKE_ON_LAN interrupt\n");
+			dev_err(&etdev->pdev->dev, "WAKE_ON_LAN interrupt\n");
 		}
 
 		/* Handle the PHY interrupt */
-		if (GlobStatus.bits.phy_interrupt) {
-			PM_CSR_t pm_csr;
+		if (status & ET_INTR_PHY) {
+			u32 pm_csr;
 			MI_BMSR_t BmsrInts, BmsrData;
 			MI_ISR_t myIsr;
 
-			DBG_VERBOSE(et131x_dbginfo, "PHY interrupt\n");
-
 			/* If we are in coma mode when we get this interrupt,
 			 * we need to disable it.
 			 */
-			pm_csr.value = readl(&iomem->global.pm_csr.value);
-			if (pm_csr.bits.pm_phy_sw_coma == 1) {
+			pm_csr = readl(&iomem->global.pm_csr);
+			if (pm_csr & ET_PM_PHY_SW_COMA) {
 				/*
 				 * Check to see if we are in coma mode and if
 				 * so, disable it because we will not be able
 				 * to read PHY values until we are out.
 				 */
-				DBG_VERBOSE(et131x_dbginfo,
-					    "Device is in COMA mode, "
-					    "need to wake up\n");
-				DisablePhyComa(pAdapter);
+				DisablePhyComa(etdev);
 			}
 
 			/* Read the PHY ISR to clear the reason for the
 			 * interrupt.
 			 */
-			MiRead(pAdapter, (uint8_t) offsetof(MI_REGS_t, isr),
+			MiRead(etdev, (uint8_t) offsetof(MI_REGS_t, isr),
 			       &myIsr.value);
 
-			if (!pAdapter->ReplicaPhyLoopbk) {
-				MiRead(pAdapter,
+			if (!etdev->ReplicaPhyLoopbk) {
+				MiRead(etdev,
 				       (uint8_t) offsetof(MI_REGS_t, bmsr),
 				       &BmsrData.value);
 
 				BmsrInts.value =
-				    pAdapter->Bmsr.value ^ BmsrData.value;
-				pAdapter->Bmsr.value = BmsrData.value;
-
-				DBG_VERBOSE(et131x_dbginfo,
-					    "Bmsr.value = 0x%04x,"
-					    "Bmsr_ints.value = 0x%04x\n",
-					    BmsrData.value, BmsrInts.value);
+				    etdev->Bmsr.value ^ BmsrData.value;
+				etdev->Bmsr.value = BmsrData.value;
 
 				/* Do all the cable in / cable out stuff */
-				et131x_Mii_check(pAdapter, BmsrData, BmsrInts);
+				et131x_Mii_check(etdev, BmsrData, BmsrInts);
 			}
 		}
 
 		/* Let's move on to the TxMac */
-		if (GlobStatus.bits.txmac_interrupt) {
-			pAdapter->TxRing.TxMacErr.value =
+		if (status & ET_INTR_TXMAC) {
+			etdev->TxRing.TxMacErr.value =
 				readl(&iomem->txmac.err.value);
 
 			/*
@@ -417,32 +413,32 @@ void et131x_isr_handler(struct work_struct *work)
 			 * a nutshell, the whole Tx path will have to be reset
 			 * and re-configured afterwards.
 			 */
-			DBG_WARNING(et131x_dbginfo,
+			dev_warn(&etdev->pdev->dev,
 				    "TXMAC interrupt, error 0x%08x\n",
-				    pAdapter->TxRing.TxMacErr.value);
+				    etdev->TxRing.TxMacErr.value);
 
 			/* If we are debugging, we want to see this error,
 			 * otherwise we just want the device to be reset and
 			 * continue
 			 */
-			//DBG_TRAP();
 		}
 
 		/* Handle RXMAC Interrupt */
-		if (GlobStatus.bits.rxmac_interrupt) {
+		if (status & ET_INTR_RXMAC) {
 			/*
 			 * These interrupts are catastrophic to the device,
 			 * what we need to do is disable the interrupts and
 			 * set the flag to cause us to reset so we can solve
 			 * this issue.
 			 */
-			// MP_SET_FLAG( pAdapter, fMP_ADAPTER_HARDWARE_ERROR );
+			/* MP_SET_FLAG( etdev,
+						fMP_ADAPTER_HARDWARE_ERROR); */
 
-			DBG_WARNING(et131x_dbginfo,
-				    "RXMAC interrupt, error 0x%08x.  Requesting reset\n",
+			dev_warn(&etdev->pdev->dev,
+			  "RXMAC interrupt, error 0x%08x.  Requesting reset\n",
 				    readl(&iomem->rxmac.err_reg.value));
 
-			DBG_WARNING(et131x_dbginfo,
+			dev_warn(&etdev->pdev->dev,
 				    "Enable 0x%08x, Diag 0x%08x\n",
 				    readl(&iomem->rxmac.ctrl.value),
 				    readl(&iomem->rxmac.rxq_diag.value));
@@ -452,23 +448,21 @@ void et131x_isr_handler(struct work_struct *work)
 			 * otherwise we just want the device to be reset and
 			 * continue
 			 */
-			// TRAP();
 		}
 
 		/* Handle MAC_STAT Interrupt */
-		if (GlobStatus.bits.mac_stat_interrupt) {
+		if (status & ET_INTR_MAC_STAT) {
 			/*
 			 * This means at least one of the un-masked counters
 			 * in the MAC_STAT block has rolled over.  Use this
 			 * to maintain the top, software managed bits of the
 			 * counter(s).
 			 */
-			DBG_VERBOSE(et131x_dbginfo, "MAC_STAT interrupt\n");
-			HandleMacStatInterrupt(pAdapter);
+			HandleMacStatInterrupt(etdev);
 		}
 
 		/* Handle SLV Timeout Interrupt */
-		if (GlobStatus.bits.slv_timeout) {
+		if (status & ET_INTR_SLV_TIMEOUT) {
 			/*
 			 * This means a timeout has occured on a read or
 			 * write request to one of the JAGCore registers. The
@@ -478,11 +472,7 @@ void et131x_isr_handler(struct work_struct *work)
 			 * addressed module is in a power-down state and
 			 * can't respond.
 			 */
-			DBG_VERBOSE(et131x_dbginfo, "SLV_TIMEOUT interrupt\n");
 		}
 	}
-
-	if (pAdapter->PoMgmt.PowerState == NdisDeviceStateD0) {
-		et131x_enable_interrupts(pAdapter);
-	}
+	et131x_enable_interrupts(etdev);
 }
diff --git a/drivers/staging/et131x/et131x_isr.h b/drivers/staging/et131x/et131x_isr.h
index 76a51d5..906d577 100644
--- a/drivers/staging/et131x/et131x_isr.h
+++ b/drivers/staging/et131x/et131x_isr.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c
index 59e99cc..8c7612f 100644
--- a/drivers/staging/et131x/et131x_netdev.c
+++ b/drivers/staging/et131x/et131x_netdev.c
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
@@ -56,7 +56,6 @@
  */
 
 #include "et131x_version.h"
-#include "et131x_debug.h"
 #include "et131x_defs.h"
 
 #include <linux/init.h>
@@ -73,9 +72,10 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
 #include <asm/system.h>
-#include <asm/bitops.h>
 
 #include <linux/mii.h>
 #include <linux/netdevice.h>
@@ -94,11 +94,6 @@
 #include "et131x_isr.h"
 #include "et131x_initpci.h"
 
-/* Data for debugging facilities */
-#ifdef CONFIG_ET131X_DEBUG
-extern dbg_info_t *et131x_dbginfo;
-#endif /* CONFIG_ET131X_DEBUG */
-
 struct net_device_stats *et131x_stats(struct net_device *netdev);
 int et131x_open(struct net_device *netdev);
 int et131x_close(struct net_device *netdev);
@@ -138,33 +133,27 @@ struct net_device *et131x_device_alloc(void)
 {
 	struct net_device *netdev;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Alloc net_device and adapter structs */
 	netdev = alloc_etherdev(sizeof(struct et131x_adapter));
 
 	if (netdev == NULL) {
-		DBG_ERROR(et131x_dbginfo,
-			  "Alloc of net_device struct failed\n");
-		DBG_LEAVE(et131x_dbginfo);
+		printk(KERN_ERR "et131x: Alloc of net_device struct failed\n");
 		return NULL;
 	}
 
 	/* Setup the function registration table (and other data) for a
 	 * net_device
 	 */
-	//netdev->init               = &et131x_init;
-	//netdev->set_config = &et131x_config;
+	/* netdev->init               = &et131x_init; */
+	/* netdev->set_config = &et131x_config; */
 	netdev->watchdog_timeo = ET131X_TX_TIMEOUT;
 	netdev->netdev_ops = &et131x_netdev_ops;
 
-	//netdev->ethtool_ops        = &et131x_ethtool_ops;
-
-	// Poll?
-	//netdev->poll               = &et131x_poll;
-	//netdev->poll_controller    = &et131x_poll_controller;
+	/* netdev->ethtool_ops        = &et131x_ethtool_ops; */
 
-	DBG_LEAVE(et131x_dbginfo);
+	/* Poll? */
+	/* netdev->poll               = &et131x_poll; */
+	/* netdev->poll_controller    = &et131x_poll_controller; */
 	return netdev;
 }
 
@@ -180,8 +169,6 @@ struct net_device_stats *et131x_stats(struct net_device *netdev)
 	struct net_device_stats *stats = &adapter->net_stats;
 	CE_STATS_t *devstat = &adapter->Stats;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	stats->rx_packets = devstat->ipackets;
 	stats->tx_packets = devstat->opackets;
 	stats->rx_errors = devstat->length_err + devstat->alignment_err +
@@ -194,25 +181,25 @@ struct net_device_stats *et131x_stats(struct net_device *netdev)
 	stats->rx_over_errors = devstat->rx_ov_flow;
 	stats->rx_crc_errors = devstat->crc_err;
 
-	// NOTE: These stats don't have corresponding values in CE_STATS, so we're
-	//       going to have to update these directly from within the TX/RX code
-	//stats->rx_bytes            = 20; //devstat->;
-	//stats->tx_bytes            = 20; //devstat->;
-	//stats->rx_dropped          = devstat->;
-	//stats->tx_dropped          = devstat->;
-
-	// NOTE: Not used, can't find analogous statistics
-	//stats->rx_frame_errors     = devstat->;
-	//stats->rx_fifo_errors      = devstat->;
-	//stats->rx_missed_errors    = devstat->;
-
-	//stats->tx_aborted_errors   = devstat->;
-	//stats->tx_carrier_errors   = devstat->;
-	//stats->tx_fifo_errors      = devstat->;
-	//stats->tx_heartbeat_errors = devstat->;
-	//stats->tx_window_errors    = devstat->;
-
-	DBG_LEAVE(et131x_dbginfo);
+	/* NOTE: These stats don't have corresponding values in CE_STATS,
+	 * so we're going to have to update these directly from within the
+	 * TX/RX code
+	 */
+	/* stats->rx_bytes            = 20; devstat->; */
+	/* stats->tx_bytes            = 20;  devstat->; */
+	/* stats->rx_dropped          = devstat->; */
+	/* stats->tx_dropped          = devstat->; */
+
+	/*  NOTE: Not used, can't find analogous statistics */
+	/* stats->rx_frame_errors     = devstat->; */
+	/* stats->rx_fifo_errors      = devstat->; */
+	/* stats->rx_missed_errors    = devstat->; */
+
+	/* stats->tx_aborted_errors   = devstat->; */
+	/* stats->tx_carrier_errors   = devstat->; */
+	/* stats->tx_fifo_errors      = devstat->; */
+	/* stats->tx_heartbeat_errors = devstat->; */
+	/* stats->tx_window_errors    = devstat->; */
 	return stats;
 }
 
@@ -227,20 +214,15 @@ int et131x_open(struct net_device *netdev)
 	int result = 0;
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Start the timer to track NIC errors */
 	add_timer(&adapter->ErrorTimer);
 
-	/* Register our ISR */
-	DBG_TRACE(et131x_dbginfo, "Registering ISR...\n");
-
-	result =
-	    request_irq(netdev->irq, et131x_isr, IRQF_SHARED, netdev->name,
-			netdev);
+	/* Register our IRQ */
+	result = request_irq(netdev->irq, et131x_isr, IRQF_SHARED,
+					netdev->name, netdev);
 	if (result) {
-		DBG_ERROR(et131x_dbginfo, "Could not register ISR\n");
-		DBG_LEAVE(et131x_dbginfo);
+		dev_err(&adapter->pdev->dev, "c ould not register IRQ %d\n",
+			netdev->irq);
 		return result;
 	}
 
@@ -251,12 +233,10 @@ int et131x_open(struct net_device *netdev)
 	/* Enable device interrupts */
 	et131x_enable_interrupts(adapter);
 
-	MP_SET_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE);
+	adapter->Flags |= fMP_ADAPTER_INTERRUPT_IN_USE;
 
 	/* We're ready to move some data, so start the queue */
 	netif_start_queue(netdev);
-
-	DBG_LEAVE(et131x_dbginfo);
 	return result;
 }
 
@@ -270,8 +250,6 @@ int et131x_close(struct net_device *netdev)
 {
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* First thing is to stop the queue */
 	netif_stop_queue(netdev);
 
@@ -283,15 +261,11 @@ int et131x_close(struct net_device *netdev)
 	et131x_disable_interrupts(adapter);
 
 	/* Deregistering ISR */
-	MP_CLEAR_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE);
-
-	DBG_TRACE(et131x_dbginfo, "Deregistering ISR...\n");
+	adapter->Flags &= ~fMP_ADAPTER_INTERRUPT_IN_USE;
 	free_irq(netdev->irq, netdev);
 
 	/* Stop the error timer */
 	del_timer_sync(&adapter->ErrorTimer);
-
-	DBG_LEAVE(et131x_dbginfo);
 	return 0;
 }
 
@@ -306,42 +280,33 @@ int et131x_close(struct net_device *netdev)
 int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd)
 {
 	int status = 0;
-	struct et131x_adapter *pAdapter = netdev_priv(netdev);
+	struct et131x_adapter *etdev = netdev_priv(netdev);
 	struct mii_ioctl_data *data = if_mii(reqbuf);
 
-	DBG_ENTER(et131x_dbginfo);
-
 	switch (cmd) {
 	case SIOCGMIIPHY:
-		DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIPHY\n");
-		data->phy_id = pAdapter->Stats.xcvr_addr;
+		data->phy_id = etdev->Stats.xcvr_addr;
 		break;
 
 	case SIOCGMIIREG:
-		DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIREG\n");
-		if (!capable(CAP_NET_ADMIN)) {
+		if (!capable(CAP_NET_ADMIN))
 			status = -EPERM;
-		} else {
-			status = MiRead(pAdapter,
+		else
+			status = MiRead(etdev,
 					data->reg_num, &data->val_out);
-		}
 		break;
 
 	case SIOCSMIIREG:
-		DBG_VERBOSE(et131x_dbginfo, "SIOCSMIIREG\n");
-		if (!capable(CAP_NET_ADMIN)) {
+		if (!capable(CAP_NET_ADMIN))
 			status = -EPERM;
-		} else {
-			status = MiWrite(pAdapter, data->reg_num,
+		else
+			status = MiWrite(etdev, data->reg_num,
 					 data->val_in);
-		}
 		break;
 
 	default:
 		status = -EOPNOTSUPP;
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -357,8 +322,6 @@ int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd)
 {
 	int status = 0;
 
-	DBG_ENTER(et131x_dbginfo);
-
 	switch (cmd) {
 	case SIOCGMIIPHY:
 	case SIOCGMIIREG:
@@ -367,12 +330,8 @@ int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd)
 		break;
 
 	default:
-		DBG_WARNING(et131x_dbginfo, "Unhandled IOCTL Code: 0x%04x\n",
-			    cmd);
 		status = -EOPNOTSUPP;
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -389,10 +348,8 @@ int et131x_set_packet_filter(struct et131x_adapter *adapter)
 	RXMAC_CTRL_t ctrl;
 	RXMAC_PF_CTRL_t pf_ctrl;
 
-	DBG_ENTER(et131x_dbginfo);
-
-	ctrl.value = readl(&adapter->CSRAddress->rxmac.ctrl.value);
-	pf_ctrl.value = readl(&adapter->CSRAddress->rxmac.pf_ctrl.value);
+	ctrl.value = readl(&adapter->regs->rxmac.ctrl.value);
+	pf_ctrl.value = readl(&adapter->regs->rxmac.pf_ctrl.value);
 
 	/* Default to disabled packet filtering.  Enable it in the individual
 	 * case statements that require the device to filter something
@@ -413,11 +370,8 @@ int et131x_set_packet_filter(struct et131x_adapter *adapter)
 		 * multicast entries or (3) we receive none.
 		 */
 		if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
-			DBG_VERBOSE(et131x_dbginfo,
-				    "Multicast filtering OFF (Rx ALL MULTICAST)\n");
 			pf_ctrl.bits.filter_multi_en = 0;
 		} else {
-			DBG_VERBOSE(et131x_dbginfo, "Multicast filtering ON\n");
 			SetupDeviceForMulticast(adapter);
 			pf_ctrl.bits.filter_multi_en = 1;
 			ctrl.bits.pkt_filter_disable = 0;
@@ -425,7 +379,6 @@ int et131x_set_packet_filter(struct et131x_adapter *adapter)
 
 		/* Set us up with Unicast packet filtering */
 		if (filter & ET131X_PACKET_TYPE_DIRECTED) {
-			DBG_VERBOSE(et131x_dbginfo, "Unicast Filtering ON\n");
 			SetupDeviceForUnicast(adapter);
 			pf_ctrl.bits.filter_uni_en = 1;
 			ctrl.bits.pkt_filter_disable = 0;
@@ -433,12 +386,9 @@ int et131x_set_packet_filter(struct et131x_adapter *adapter)
 
 		/* Set us up with Broadcast packet filtering */
 		if (filter & ET131X_PACKET_TYPE_BROADCAST) {
-			DBG_VERBOSE(et131x_dbginfo, "Broadcast Filtering ON\n");
 			pf_ctrl.bits.filter_broad_en = 1;
 			ctrl.bits.pkt_filter_disable = 0;
 		} else {
-			DBG_VERBOSE(et131x_dbginfo,
-				    "Broadcast Filtering OFF\n");
 			pf_ctrl.bits.filter_broad_en = 0;
 		}
 
@@ -447,11 +397,9 @@ int et131x_set_packet_filter(struct et131x_adapter *adapter)
 		 * in the control reg.
 		 */
 		writel(pf_ctrl.value,
-		       &adapter->CSRAddress->rxmac.pf_ctrl.value);
-		writel(ctrl.value, &adapter->CSRAddress->rxmac.ctrl.value);
+		       &adapter->regs->rxmac.pf_ctrl.value);
+		writel(ctrl.value, &adapter->regs->rxmac.ctrl.value);
 	}
-
-	DBG_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -464,12 +412,10 @@ void et131x_multicast(struct net_device *netdev)
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 	uint32_t PacketFilter = 0;
 	uint32_t count;
-	unsigned long lockflags;
+	unsigned long flags;
 	struct dev_mc_list *mclist = netdev->mc_list;
 
-	DBG_ENTER(et131x_dbginfo);
-
-	spin_lock_irqsave(&adapter->Lock, lockflags);
+	spin_lock_irqsave(&adapter->Lock, flags);
 
 	/* Before we modify the platform-independent filter flags, store them
 	 * locally. This allows us to determine if anything's changed and if
@@ -487,37 +433,25 @@ void et131x_multicast(struct net_device *netdev)
 	/* Check the net_device flags and set the device independent flags
 	 * accordingly
 	 */
-	DBG_VERBOSE(et131x_dbginfo,
-		    "MULTICAST ADDR COUNT: %d\n", netdev->mc_count);
 
 	if (netdev->flags & IFF_PROMISC) {
-		DBG_VERBOSE(et131x_dbginfo, "Request: PROMISCUOUS MODE ON\n");
 		adapter->PacketFilter |= ET131X_PACKET_TYPE_PROMISCUOUS;
 	} else {
-		DBG_VERBOSE(et131x_dbginfo, "Request: PROMISCUOUS MODE OFF\n");
 		adapter->PacketFilter &= ~ET131X_PACKET_TYPE_PROMISCUOUS;
 	}
 
 	if (netdev->flags & IFF_ALLMULTI) {
-		DBG_VERBOSE(et131x_dbginfo, "Request: ACCEPT ALL MULTICAST\n");
 		adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST;
 	}
 
 	if (netdev->mc_count > NIC_MAX_MCAST_LIST) {
-		DBG_WARNING(et131x_dbginfo,
-			    "ACCEPT ALL MULTICAST for now, as there's more Multicast "
-			    "addresses than the HW supports\n");
-
 		adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST;
 	}
 
 	if (netdev->mc_count < 1) {
-		DBG_VERBOSE(et131x_dbginfo, "Request: REJECT ALL MULTICAST\n");
 		adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST;
 		adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST;
 	} else {
-		DBG_VERBOSE(et131x_dbginfo,
-			    "Request: SET MULTICAST FILTER(S)\n");
 		adapter->PacketFilter |= ET131X_PACKET_TYPE_MULTICAST;
 	}
 
@@ -525,14 +459,8 @@ void et131x_multicast(struct net_device *netdev)
 	adapter->MCAddressCount = netdev->mc_count;
 
 	if (netdev->mc_count) {
-		if (mclist->dmi_addrlen != ETH_ALEN) {
-			DBG_WARNING(et131x_dbginfo,
-				    "Multicast addrs are not ETH_ALEN in size\n");
-		} else {
-			count = netdev->mc_count - 1;
-			memcpy(adapter->MCList[count], mclist->dmi_addr,
-			       ETH_ALEN);
-		}
+		count = netdev->mc_count - 1;
+		memcpy(adapter->MCList[count], mclist->dmi_addr, ETH_ALEN);
 	}
 
 	/* Are the new flags different from the previous ones? If not, then no
@@ -543,17 +471,9 @@ void et131x_multicast(struct net_device *netdev)
 	 */
 	if (PacketFilter != adapter->PacketFilter) {
 		/* Call the device's filter function */
-		DBG_VERBOSE(et131x_dbginfo, "UPDATE REQUIRED, FLAGS changed\n");
-
 		et131x_set_packet_filter(adapter);
-	} else {
-		DBG_VERBOSE(et131x_dbginfo,
-			    "NO UPDATE REQUIRED, FLAGS didn't change\n");
 	}
-
-	spin_unlock_irqrestore(&adapter->Lock, lockflags);
-
-	DBG_LEAVE(et131x_dbginfo);
+	spin_unlock_irqrestore(&adapter->Lock, flags);
 }
 
 /**
@@ -567,8 +487,6 @@ int et131x_tx(struct sk_buff *skb, struct net_device *netdev)
 {
 	int status = 0;
 
-	DBG_TX_ENTER(et131x_dbginfo);
-
 	/* Save the timestamp for the TX timeout watchdog */
 	netdev->trans_start = jiffies;
 
@@ -578,22 +496,15 @@ int et131x_tx(struct sk_buff *skb, struct net_device *netdev)
 	/* Check status and manage the netif queue if necessary */
 	if (status != 0) {
 		if (status == -ENOMEM) {
-			DBG_VERBOSE(et131x_dbginfo,
-				    "OUT OF TCBs; STOP NETIF QUEUE\n");
-
 			/* Put the queue to sleep until resources are
 			 * available
 			 */
 			netif_stop_queue(netdev);
 			status = NETDEV_TX_BUSY;
 		} else {
-			DBG_WARNING(et131x_dbginfo,
-				    "Misc error; drop packet\n");
 			status = NETDEV_TX_OK;
 		}
 	}
-
-	DBG_TX_LEAVE(et131x_dbginfo);
 	return status;
 }
 
@@ -607,80 +518,52 @@ int et131x_tx(struct sk_buff *skb, struct net_device *netdev)
  */
 void et131x_tx_timeout(struct net_device *netdev)
 {
-	struct et131x_adapter *pAdapter = netdev_priv(netdev);
+	struct et131x_adapter *etdev = netdev_priv(netdev);
 	PMP_TCB pMpTcb;
-	unsigned long lockflags;
-
-	DBG_WARNING(et131x_dbginfo, "TX TIMEOUT\n");
+	unsigned long flags;
 
 	/* Just skip this part if the adapter is doing link detection */
-	if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION)) {
-		DBG_ERROR(et131x_dbginfo, "Still doing link detection\n");
+	if (etdev->Flags & fMP_ADAPTER_LINK_DETECTION)
 		return;
-	}
 
 	/* Any nonrecoverable hardware error?
 	 * Checks adapter->flags for any failure in phy reading
 	 */
-	if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_NON_RECOVER_ERROR)) {
-		DBG_WARNING(et131x_dbginfo, "Non recoverable error - remove\n");
+	if (etdev->Flags & fMP_ADAPTER_NON_RECOVER_ERROR)
 		return;
-	}
 
 	/* Hardware failure? */
-	if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_HARDWARE_ERROR)) {
-		DBG_WARNING(et131x_dbginfo, "hardware error - reset\n");
+	if (etdev->Flags & fMP_ADAPTER_HARDWARE_ERROR) {
+		dev_err(&etdev->pdev->dev, "hardware error - reset\n");
 		return;
 	}
 
 	/* Is send stuck? */
-	spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+	spin_lock_irqsave(&etdev->TCBSendQLock, flags);
 
-	pMpTcb = pAdapter->TxRing.CurrSendHead;
+	pMpTcb = etdev->TxRing.CurrSendHead;
 
 	if (pMpTcb != NULL) {
 		pMpTcb->Count++;
 
 		if (pMpTcb->Count > NIC_SEND_HANG_THRESHOLD) {
-#ifdef CONFIG_ET131X_DEBUG
-			TX_STATUS_BLOCK_t txDmaComplete =
-			    *(pAdapter->TxRing.pTxStatusVa);
-			PTX_DESC_ENTRY_t pDesc =
-			    pAdapter->TxRing.pTxDescRingVa +
-			    pMpTcb->WrIndex.bits.val;
-#endif
 			TX_DESC_ENTRY_t StuckDescriptors[10];
 
-			if (pMpTcb->WrIndex.bits.val > 7) {
+			if (INDEX10(pMpTcb->WrIndex) > 7) {
 				memcpy(StuckDescriptors,
-				       pAdapter->TxRing.pTxDescRingVa +
-				       pMpTcb->WrIndex.bits.val - 6,
+				       etdev->TxRing.pTxDescRingVa +
+				       INDEX10(pMpTcb->WrIndex) - 6,
 				       sizeof(TX_DESC_ENTRY_t) * 10);
 			}
 
-			spin_unlock_irqrestore(&pAdapter->TCBSendQLock,
-					       lockflags);
-
-			DBG_WARNING(et131x_dbginfo,
-				    "Send stuck - reset.  pMpTcb->WrIndex %x, Flags 0x%08x\n",
-				    pMpTcb->WrIndex.bits.val,
-				    pMpTcb->Flags);
-
-			DBG_WARNING(et131x_dbginfo,
-				    "pDesc 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
-				    pDesc->DataBufferPtrHigh,
-				    pDesc->DataBufferPtrLow, pDesc->word2.value,
-				    pDesc->word3.value);
-
-			DBG_WARNING(et131x_dbginfo,
-				    "WbStatus 0x%08x\n", txDmaComplete.value);
-
-#ifdef CONFIG_ET131X_DEBUG
-			DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 0);
-			DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 1);
-			DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 3);
-			DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 5);
-#endif
+			spin_unlock_irqrestore(&etdev->TCBSendQLock,
+					       flags);
+
+			dev_warn(&etdev->pdev->dev,
+				"Send stuck - reset.  pMpTcb->WrIndex %x, Flags 0x%08x\n",
+				pMpTcb->WrIndex,
+				pMpTcb->Flags);
+
 			et131x_close(netdev);
 			et131x_open(netdev);
 
@@ -688,7 +571,7 @@ void et131x_tx_timeout(struct net_device *netdev)
 		}
 	}
 
-	spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+	spin_unlock_irqrestore(&etdev->TCBSendQLock, flags);
 }
 
 /**
@@ -703,13 +586,9 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu)
 	int result = 0;
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 
-	DBG_ENTER(et131x_dbginfo);
-
 	/* Make sure the requested MTU is valid */
-	if (new_mtu == 0 || new_mtu > 9216) {
-		DBG_LEAVE(et131x_dbginfo);
+	if (new_mtu < 64 || new_mtu > 9216)
 		return -EINVAL;
-	}
 
 	/* Stop the netif queue */
 	netif_stop_queue(netdev);
@@ -736,8 +615,8 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu)
 	/* Alloc and init Rx DMA memory */
 	result = et131x_adapter_memory_alloc(adapter);
 	if (result != 0) {
-		DBG_WARNING(et131x_dbginfo,
-			    "Change MTU failed; couldn't re-alloc DMA memory\n");
+		dev_warn(&adapter->pdev->dev,
+			"Change MTU failed; couldn't re-alloc DMA memory\n");
 		return result;
 	}
 
@@ -750,9 +629,8 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu)
 	et131x_adapter_setup(adapter);
 
 	/* Enable interrupts */
-	if (MP_TEST_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE)) {
+	if (adapter->Flags & fMP_ADAPTER_INTERRUPT_IN_USE)
 		et131x_enable_interrupts(adapter);
-	}
 
 	/* Restart the Tx and Rx DMA engines */
 	et131x_rx_dma_enable(adapter);
@@ -760,8 +638,6 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu)
 
 	/* Restart the netif queue */
 	netif_wake_queue(netdev);
-
-	DBG_LEAVE(et131x_dbginfo);
 	return result;
 }
 
@@ -780,20 +656,14 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
 	struct et131x_adapter *adapter = netdev_priv(netdev);
 	struct sockaddr *address = new_mac;
 
-	DBG_ENTER(et131x_dbginfo);
-	// begin blux
-	// DBG_VERBOSE( et131x_dbginfo, "Function not implemented!!\n" );
+	/* begin blux */
 
-	if (adapter == NULL) {
-		DBG_LEAVE(et131x_dbginfo);
+	if (adapter == NULL)
 		return -ENODEV;
-	}
 
 	/* Make sure the requested MAC is valid */
-	if (!is_valid_ether_addr(address->sa_data)) {
-		DBG_LEAVE(et131x_dbginfo);
+	if (!is_valid_ether_addr(address->sa_data))
 		return -EINVAL;
-	}
 
 	/* Stop the netif queue */
 	netif_stop_queue(netdev);
@@ -808,46 +678,47 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
 	et131x_handle_recv_interrupt(adapter);
 
 	/* Set the new MAC */
-	// netdev->set_mac_address  = &new_mac;
-	// netdev->mtu = new_mtu;
+	/* netdev->set_mac_address  = &new_mac; */
+	/* netdev->mtu = new_mtu; */
 
 	memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len);
 
-	printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n",
-	       netdev->name, netdev->dev_addr[0], netdev->dev_addr[1],
-	       netdev->dev_addr[2], netdev->dev_addr[3], netdev->dev_addr[4],
-	       netdev->dev_addr[5]);
+	printk(KERN_INFO
+		"%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n",
+			netdev->name,
+			netdev->dev_addr[0], netdev->dev_addr[1],
+			netdev->dev_addr[2], netdev->dev_addr[3],
+			netdev->dev_addr[4], netdev->dev_addr[5]);
 
 	/* Free Rx DMA memory */
 	et131x_adapter_memory_free(adapter);
 
 	/* Set the config parameter for Jumbo Packet support */
-	// adapter->RegistryJumboPacket = new_mtu + 14;
-	// blux: not needet here, w'll change the MAC
+	/* adapter->RegistryJumboPacket = new_mtu + 14; */
+	/* blux: not needet here, we'll change the MAC */
 
 	et131x_soft_reset(adapter);
 
 	/* Alloc and init Rx DMA memory */
 	result = et131x_adapter_memory_alloc(adapter);
 	if (result != 0) {
-		DBG_WARNING(et131x_dbginfo,
-			    "Change MAC failed; couldn't re-alloc DMA memory\n");
+		dev_err(&adapter->pdev->dev,
+			"Change MAC failed; couldn't re-alloc DMA memory\n");
 		return result;
 	}
 
 	et131x_init_send(adapter);
 
 	et131x_setup_hardware_properties(adapter);
-	// memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN );
-	// blux: no, do not override our nice address
+	/* memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); */
+	/* blux: no, do not override our nice address */
 
 	/* Init the device with the new settings */
 	et131x_adapter_setup(adapter);
 
 	/* Enable interrupts */
-	if (MP_TEST_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE)) {
+	if (adapter->Flags & fMP_ADAPTER_INTERRUPT_IN_USE)
 		et131x_enable_interrupts(adapter);
-	}
 
 	/* Restart the Tx and Rx DMA engines */
 	et131x_rx_dma_enable(adapter);
@@ -855,7 +726,5 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
 
 	/* Restart the netif queue */
 	netif_wake_queue(netdev);
-
-	DBG_LEAVE(et131x_dbginfo);
 	return result;
 }
diff --git a/drivers/staging/et131x/et131x_netdev.h b/drivers/staging/et131x/et131x_netdev.h
index b8acd14..1eb4a92 100644
--- a/drivers/staging/et131x/et131x_netdev.h
+++ b/drivers/staging/et131x/et131x_netdev.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -20,7 +20,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -41,7 +41,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
diff --git a/drivers/staging/et131x/et131x_version.h b/drivers/staging/et131x/et131x_version.h
index 2ea645e..568f6c8 100644
--- a/drivers/staging/et131x/et131x_version.h
+++ b/drivers/staging/et131x/et131x_version.h
@@ -2,7 +2,7 @@
  * Agere Systems Inc.
  * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *   http://www.agere.com
  *
@@ -19,7 +19,7 @@
  * software indicates your acceptance of these terms and conditions.  If you do
  * not agree with these terms and conditions, do not use the software.
  *
- * Copyright © 2005 Agere Systems Inc.
+ * Copyright Â© 2005 Agere Systems Inc.
  * All rights reserved.
  *
  * Redistribution and use in source or binary forms, with or without
@@ -40,7 +40,7 @@
  *
  * Disclaimer
  *
- * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index ca6ade6..e47f683 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -1,5 +1,5 @@
 config VIDEO_GO7007
-	tristate "Go 7007 support"
+	tristate "WIS GO7007 MPEG encoder support"
 	depends on VIDEO_DEV && PCI && I2C && INPUT
 	depends on SND
 	select VIDEOBUF_DMA_SG
@@ -10,17 +10,19 @@ config VIDEO_GO7007
 	select CRC32
 	default N
 	---help---
-	  This is a video4linux driver for some weird device...
+	  This is a video4linux driver for the WIS GO7007 MPEG
+	  encoder chip.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called go7007
 
 config VIDEO_GO7007_USB
-	tristate "Go 7007 USB support"
+	tristate "WIS GO7007 USB support"
 	depends on VIDEO_GO7007 && USB
 	default N
 	---help---
-	  This is a video4linux driver for some weird device...
+	  This is a video4linux driver for the WIS GO7007 MPEG
+	  encoder chip over USB.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called go7007-usb
@@ -30,8 +32,78 @@ config VIDEO_GO7007_USB_S2250_BOARD
 	depends on VIDEO_GO7007_USB && DVB_USB
 	default N
 	---help---
-	  This is a video4linux driver for the Sensoray 2250/2251 device
+	  This is a video4linux driver for the Sensoray 2250/2251 device.
 
 	  To compile this driver as a module, choose M here: the
-	  module will be called s2250-board
+	  module will be called s2250
+
+config VIDEO_GO7007_OV7640
+	tristate "OV7640 subdev support"
+	depends on VIDEO_GO7007
+	default N
+	---help---
+	  This is a video4linux driver for the OV7640 sub-device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wis-ov7640
+
+config VIDEO_GO7007_SAA7113
+	tristate "SAA7113 subdev support"
+	depends on VIDEO_GO7007
+	default N
+	---help---
+	  This is a video4linux driver for the SAA7113 sub-device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wis-saa7113
+
+config VIDEO_GO7007_SAA7115
+	tristate "SAA7115 subdev support"
+	depends on VIDEO_GO7007
+	default N
+	---help---
+	  This is a video4linux driver for the SAA7115 sub-device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wis-saa7115
+
+config VIDEO_GO7007_TW9903
+	tristate "TW9903 subdev support"
+	depends on VIDEO_GO7007
+	default N
+	---help---
+	  This is a video4linux driver for the TW9903 sub-device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wis-tw9903
+
+config VIDEO_GO7007_UDA1342
+	tristate "UDA1342 subdev support"
+	depends on VIDEO_GO7007
+	default N
+	---help---
+	  This is a video4linux driver for the UDA1342 sub-device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wis-uda1342
+
+config VIDEO_GO7007_SONY_TUNER
+	tristate "Sony tuner subdev support"
+	depends on VIDEO_GO7007
+	default N
+	---help---
+	  This is a video4linux driver for the Sony Tuner sub-device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wis-sony-tuner
+
+config VIDEO_GO7007_TW2804
+	tristate "TW2804 subdev support"
+	depends on VIDEO_GO7007
+	default N
+	---help---
+	  This is a video4linux driver for the TW2804 sub-device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called wis-tw2804
 
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
index e514b4a..d14ea84 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/go7007/Makefile
@@ -6,22 +6,34 @@
 obj-$(CONFIG_VIDEO_GO7007) += go7007.o
 obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
 obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o
+obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
+obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
+obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
+obj-$(CONFIG_VIDEO_GO7007_TW9903) += wis-tw9903.o
+obj-$(CONFIG_VIDEO_GO7007_UDA1342) += wis-uda1342.o
+obj-$(CONFIG_VIDEO_GO7007_SONY_TUNER) += wis-sony-tuner.o
+obj-$(CONFIG_VIDEO_GO7007_TW2804) += wis-tw2804.o
 
 go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
-		snd-go7007.o wis-saa7113.o
+		snd-go7007.o
 
 s2250-objs += s2250-board.o s2250-loader.o
 
-# Uncompile when the saa7134 patches get into upstream
+# Uncomment when the saa7134 patches get into upstream
 #ifneq ($(CONFIG_VIDEO_SAA7134),)
 #obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
-#EXTRA_CFLAGS += -Idrivers/media/video/saa7134
+#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
 #endif
 
+# S2250 needs cypress ezusb loader from dvb-usb
 ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),)
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb
 endif
 
-EXTRA_CFLAGS += -Idrivers/staging/saa7134
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+
+# Ubuntu 8.04 has CONFIG_SND undefined, so include lum sound/config.h too
+ifeq ($(CONFIG_SND),)
+EXTRA_CFLAGS += -include sound/config.h
+endif
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index 77b1e76..472f4bb 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -27,7 +27,7 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/firmware.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <asm/system.h>
 #include <linux/videodev2.h>
@@ -49,7 +49,7 @@ int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
 	go->hpi_ops->read_interrupt(go);
 	if (wait_event_timeout(go->interrupt_waitq,
 				go->interrupt_available, 5*HZ) < 0) {
-		printk(KERN_ERR "go7007: timeout waiting for read interrupt\n");
+		v4l2_err(go->video_dev, "timeout waiting for read interrupt\n");
 		return -1;
 	}
 	if (!go->interrupt_available)
@@ -97,13 +97,12 @@ static int go7007_load_encoder(struct go7007 *go)
 	u16 intr_val, intr_data;
 
 	if (request_firmware(&fw_entry, fw_name, go->dev)) {
-		printk(KERN_ERR
-			"go7007: unable to load firmware from file \"%s\"\n",
-			fw_name);
+		v4l2_err(go, "unable to load firmware from file "
+			"\"%s\"\n", fw_name);
 		return -1;
 	}
 	if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
-		printk(KERN_ERR "go7007: file \"%s\" does not appear to be "
+		v4l2_err(go, "file \"%s\" does not appear to be "
 				"go7007 firmware\n", fw_name);
 		release_firmware(fw_entry);
 		return -1;
@@ -111,7 +110,7 @@ static int go7007_load_encoder(struct go7007 *go)
 	fw_len = fw_entry->size - 16;
 	bounce = kmalloc(fw_len, GFP_KERNEL);
 	if (bounce == NULL) {
-		printk(KERN_ERR "go7007: unable to allocate %d bytes for "
+		v4l2_err(go, "unable to allocate %d bytes for "
 				"firmware transfer\n", fw_len);
 		release_firmware(fw_entry);
 		return -1;
@@ -122,7 +121,7 @@ static int go7007_load_encoder(struct go7007 *go)
 			go7007_send_firmware(go, bounce, fw_len) < 0 ||
 			go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
 			(intr_val & ~0x1) != 0x5a5a) {
-		printk(KERN_ERR "go7007: error transferring firmware\n");
+		v4l2_err(go, "error transferring firmware\n");
 		rv = -1;
 	}
 	kfree(bounce);
@@ -140,9 +139,9 @@ int go7007_boot_encoder(struct go7007 *go, int init_i2c)
 {
 	int ret;
 
-	down(&go->hw_lock);
+	mutex_lock(&go->hw_lock);
 	ret = go7007_load_encoder(go);
-	up(&go->hw_lock);
+	mutex_unlock(&go->hw_lock);
 	if (ret < 0)
 		return -1;
 	if (!init_i2c)
@@ -257,9 +256,9 @@ int go7007_register_encoder(struct go7007 *go)
 
 	printk(KERN_INFO "go7007: registering new %s\n", go->name);
 
-	down(&go->hw_lock);
+	mutex_lock(&go->hw_lock);
 	ret = go7007_init_encoder(go);
-	up(&go->hw_lock);
+	mutex_unlock(&go->hw_lock);
 	if (ret < 0)
 		return -1;
 
@@ -316,7 +315,7 @@ int go7007_start_encoder(struct go7007 *go)
 
 	if (go7007_send_firmware(go, fw, fw_len) < 0 ||
 			go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
-		printk(KERN_ERR "go7007: error transferring firmware\n");
+		v4l2_err(go->video_dev, "error transferring firmware\n");
 		rv = -1;
 		goto start_error;
 	}
@@ -325,7 +324,7 @@ int go7007_start_encoder(struct go7007 *go)
 	go->parse_length = 0;
 	go->seen_frame = 0;
 	if (go7007_stream_start(go) < 0) {
-		printk(KERN_ERR "go7007: error starting stream transfer\n");
+		v4l2_err(go->video_dev, "error starting stream transfer\n");
 		rv = -1;
 		goto start_error;
 	}
@@ -421,7 +420,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
 	for (i = 0; i < length; ++i) {
 		if (go->active_buf != NULL &&
 			    go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
-			printk(KERN_DEBUG "go7007: dropping oversized frame\n");
+			v4l2_info(go->video_dev, "dropping oversized frame\n");
 			go->active_buf->offset -= go->active_buf->bytesused;
 			go->active_buf->bytesused = 0;
 			go->active_buf->modet_active = 0;
@@ -604,7 +603,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 	go->tuner_type = -1;
 	go->channel_number = 0;
 	go->name[0] = 0;
-	init_MUTEX(&go->hw_lock);
+	mutex_init(&go->hw_lock);
 	init_waitqueue_head(&go->frame_waitq);
 	spin_lock_init(&go->spinlock);
 	go->video_dev = NULL;
@@ -669,8 +668,8 @@ void go7007_remove(struct go7007 *go)
 		if (i2c_del_adapter(&go->i2c_adapter) == 0)
 			go->i2c_adapter_online = 0;
 		else
-			printk(KERN_ERR
-				"go7007: error removing I2C adapter!\n");
+			v4l2_err(go->video_dev,
+				"error removing I2C adapter!\n");
 	}
 
 	if (go->audio_enabled)
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
index 871ed43..a8bb264 100644
--- a/drivers/staging/go7007/go7007-fw.c
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -1034,7 +1034,8 @@ static int brctrl_to_package(struct go7007 *go,
 		0xBF1B,		framelen[7],
 		0,		0,
 
-#if 0 /* Remove once we don't care about matching */
+#if 0
+		/* Remove once we don't care about matching */
 		0x200e,		0x0000,
 		0xBF56,		4,
 		0xBF57,		0,
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
index c82867f..b8cfa1a 100644
--- a/drivers/staging/go7007/go7007-i2c.c
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -24,7 +24,7 @@
 #include <linux/time.h>
 #include <linux/device.h>
 #include <linux/i2c.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <asm/system.h>
 
@@ -48,7 +48,7 @@
 
 /* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
  * on the Adlink PCI-MPG24, so access is shared between all of them. */
-static DECLARE_MUTEX(adlink_mpg24_i2c_lock);
+static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
 
 static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
 		u16 command, int flags, u8 *data)
@@ -69,11 +69,11 @@ static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
 			*data, command, addr);
 #endif
 
-	down(&go->hw_lock);
+	mutex_lock(&go->hw_lock);
 
 	if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
 		/* Bridge the I2C port on this GO7007 to the shared bus */
-		down(&adlink_mpg24_i2c_lock);
+		mutex_lock(&adlink_mpg24_i2c_lock);
 		go7007_write_addr(go, 0x3c82, 0x0020);
 	}
 
@@ -134,9 +134,9 @@ i2c_done:
 	if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
 		/* Isolate the I2C port on this GO7007 from the shared bus */
 		go7007_write_addr(go, 0x3c82, 0x0000);
-		up(&adlink_mpg24_i2c_lock);
+		mutex_unlock(&adlink_mpg24_i2c_lock);
 	}
-	up(&go->hw_lock);
+	mutex_unlock(&go->hw_lock);
 	return ret;
 }
 
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
index 178d181..ce9307e 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -132,7 +132,7 @@ struct go7007_buffer {
 
 struct go7007_file {
 	struct go7007 *go;
-	struct semaphore lock;
+	struct mutex lock;
 	int buf_count;
 	struct go7007_buffer *bufs;
 };
@@ -170,7 +170,7 @@ struct go7007 {
 	int ref_count;
 	enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
 	spinlock_t spinlock;
-	struct semaphore hw_lock;
+	struct mutex hw_lock;
 	int streaming;
 	int in_use;
 	int audio_enabled;
@@ -240,7 +240,7 @@ struct go7007 {
 	unsigned short interrupt_data;
 };
 
-/* All of these must be called with the hpi_lock semaphore held! */
+/* All of these must be called with the hpi_lock mutex held! */
 #define go7007_interface_reset(go) \
 			((go)->hpi_ops->interface_reset(go))
 #define	go7007_write_interrupt(go, x, y) \
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index aa4a9e0..ecaa3c9 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -33,7 +33,8 @@
 
 static unsigned int assume_endura;
 module_param(assume_endura, int, 0644);
-MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura");
+MODULE_PARM_DESC(assume_endura, "when probing fails, "
+				"hardware is a Pelco Endura");
 
 /* #define GO7007_USB_DEBUG */
 /* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
@@ -44,12 +45,12 @@ MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura"
 
 /*
  * Pipes on EZ-USB interface:
- * 	0 snd - Control
- * 	0 rcv - Control
- * 	2 snd - Download firmware (control)
- * 	4 rcv - Read Interrupt (interrupt)
- * 	6 rcv - Read Video (bulk)
- * 	8 rcv - Read Audio (bulk)
+ *	0 snd - Control
+ *	0 rcv - Control
+ *	2 snd - Download firmware (control)
+ *	4 rcv - Read Interrupt (interrupt)
+ *	6 rcv - Read Video (bulk)
+ *	8 rcv - Read Audio (bulk)
  */
 
 #define GO7007_USB_EZUSB		(1<<0)
@@ -62,7 +63,7 @@ struct go7007_usb_board {
 
 struct go7007_usb {
 	struct go7007_usb_board *board;
-	struct semaphore i2c_lock;
+	struct mutex i2c_lock;
 	struct usb_device *usbdev;
 	struct urb *video_urbs[8];
 	struct urb *audio_urbs[8];
@@ -97,7 +98,7 @@ static struct go7007_usb_board board_matrix_ii = {
 			},
 		},
 		.num_inputs	 = 2,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.video_input	= 0,
 				.name		= "Composite",
@@ -134,7 +135,7 @@ static struct go7007_usb_board board_matrix_reload = {
 			},
 		},
 		.num_inputs	 = 2,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.video_input	= 0,
 				.name		= "Composite",
@@ -172,7 +173,7 @@ static struct go7007_usb_board board_star_trek = {
 			},
 		},
 		.num_inputs	 = 2,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.video_input	= 1,
 			/*	.audio_input	= AUDIO_EXTERN, */
@@ -228,7 +229,7 @@ static struct go7007_usb_board board_px_tv402u = {
 			},
 		},
 		.num_inputs	 = 3,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.video_input	= 1,
 				.audio_input	= TVAUDIO_INPUT_EXTERN,
@@ -276,7 +277,7 @@ static struct go7007_usb_board board_xmen = {
 			},
 		},
 		.num_inputs	  = 1,
-		.inputs 	  = {
+		.inputs		  = {
 			{
 				.name		= "Camera",
 			},
@@ -309,7 +310,7 @@ static struct go7007_usb_board board_matrix_revolution = {
 			},
 		},
 		.num_inputs	 = 2,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.video_input	= 2,
 				.name		= "Composite",
@@ -341,7 +342,7 @@ static struct go7007_usb_board board_lifeview_lr192 = {
 					GO7007_SENSOR_SCALING,
 		.num_i2c_devs	 = 0,
 		.num_inputs	 = 1,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.video_input	= 0,
 				.name		= "Composite",
@@ -367,7 +368,7 @@ static struct go7007_usb_board board_endura = {
 		.sensor_h_offset = 8,
 		.num_i2c_devs	 = 0,
 		.num_inputs	 = 1,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.name		= "Camera",
 			},
@@ -399,7 +400,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
 			},
 		},
 		.num_inputs	 = 1,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.name		= "Composite",
 			},
@@ -430,7 +431,7 @@ static struct go7007_usb_board board_sensoray_2250 = {
 			},
 		},
 		.num_inputs	 = 2,
-		.inputs 	 = {
+		.inputs		 = {
 			{
 				.video_input	= 0,
 				.name		= "Composite",
@@ -734,14 +735,15 @@ static int go7007_usb_read_interrupt(struct go7007 *go)
 static void go7007_usb_read_video_pipe_complete(struct urb *urb)
 {
 	struct go7007 *go = (struct go7007 *)urb->context;
-	int r, status = urb-> status;
+	int r, status = urb->status;
 
 	if (!go->streaming) {
 		wake_up_interruptible(&go->frame_waitq);
 		return;
 	}
 	if (status) {
-		printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", status);
+		printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
+			status);
 		return;
 	}
 	if (urb->actual_length != urb->transfer_buffer_length) {
@@ -762,7 +764,8 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
 	if (!go->streaming)
 		return;
 	if (status) {
-		printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", status);
+		printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
+			status);
 		return;
 	}
 	if (urb->actual_length != urb->transfer_buffer_length) {
@@ -877,7 +880,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
 	if (go->status == STATUS_SHUTDOWN)
 		return -1;
 
-	down(&usb->i2c_lock);
+	mutex_lock(&usb->i2c_lock);
 
 	for (i = 0; i < num; ++i) {
 		/* The hardware command is "write some bytes then read some
@@ -935,7 +938,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
 	ret = 0;
 
 i2c_done:
-	up(&usb->i2c_lock);
+	mutex_unlock(&usb->i2c_lock);
 	return ret;
 }
 
@@ -1017,7 +1020,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		break;
 	case GO7007_BOARDID_SENSORAY_2250:
 		printk(KERN_INFO "Sensoray 2250 found\n");
-		name = "Sensoray 2250/2251\n";
+		name = "Sensoray 2250/2251";
 		board = &board_sensoray_2250;
 		break;
 	default:
@@ -1065,7 +1068,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 	if (board->flags & GO7007_USB_EZUSB_I2C) {
 		memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
 				sizeof(go7007_usb_adap_templ));
-		init_MUTEX(&usb->i2c_lock);
+		mutex_init(&usb->i2c_lock);
 		go->i2c_adapter.dev.parent = go->dev;
 		i2c_set_adapdata(&go->i2c_adapter, go);
 		if (i2c_add_adapter(&go->i2c_adapter) < 0) {
@@ -1096,7 +1099,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 				usb->board = board = &board_endura;
 				go->board_info = &board->main_info;
 				strncpy(go->name, "Pelco Endura",
-						sizeof(go->name));
+					sizeof(go->name));
 			} else {
 				u16 channel;
 
@@ -1154,8 +1157,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
 		 * to the EZ-USB GPIO output pins */
 		if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
 					NULL, 0, 0) < 0) {
-			printk(KERN_ERR
-				"go7007-usb: GPIO write failed!\n");
+			printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
 			goto initfail;
 		}
 	}
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 06cacd3..4bd353a 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -30,7 +30,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <linux/i2c.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <asm/system.h>
 
@@ -75,7 +75,7 @@ static int go7007_streamoff(struct go7007 *go)
 	int retval = -EINVAL;
 	unsigned long flags;
 
-	down(&go->hw_lock);
+	mutex_lock(&go->hw_lock);
 	if (go->streaming) {
 		go->streaming = 0;
 		go7007_stream_stop(go);
@@ -85,7 +85,7 @@ static int go7007_streamoff(struct go7007 *go)
 		go7007_reset_encoder(go);
 		retval = 0;
 	}
-	up(&go->hw_lock);
+	mutex_unlock(&go->hw_lock);
 	return 0;
 }
 
@@ -101,7 +101,7 @@ static int go7007_open(struct file *file)
 		return -ENOMEM;
 	++go->ref_count;
 	gofh->go = go;
-	init_MUTEX(&gofh->lock);
+	mutex_init(&gofh->lock);
 	gofh->buf_count = 0;
 	file->private_data = gofh;
 	return 0;
@@ -383,13 +383,10 @@ static int clip_to_modet_map(struct go7007 *go, int region,
 	}
 	return 0;
 }
+#endif
 
-static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
+static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl)
 {
-	static const u32 user_ctrls[] = {
-		V4L2_CID_USER_CLASS,
-		0
-	};
 	static const u32 mpeg_ctrls[] = {
 		V4L2_CID_MPEG_CLASS,
 		V4L2_CID_MPEG_STREAM_TYPE,
@@ -401,26 +398,15 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
 		0
 	};
 	static const u32 *ctrl_classes[] = {
-		user_ctrls,
 		mpeg_ctrls,
 		NULL
 	};
 
-	/* The ctrl may already contain the queried i2c controls,
-	 * query the mpeg controls if the existing ctrl id is
-	 * greater than the next mpeg ctrl id.
-	 */
-	id = v4l2_ctrl_next(ctrl_classes, id);
-	if (id >= ctrl->id && ctrl->name[0])
-		return 0;
-
-	memset(ctrl, 0, sizeof(*ctrl));
-	ctrl->id = id;
+	ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
 
 	switch (ctrl->id) {
-	case V4L2_CID_USER_CLASS:
 	case V4L2_CID_MPEG_CLASS:
-		return v4l2_ctrl_query_fill_std(ctrl);
+		return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
 	case V4L2_CID_MPEG_STREAM_TYPE:
 		return v4l2_ctrl_query_fill(ctrl,
 				V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
@@ -437,20 +423,21 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
 				V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
 				V4L2_MPEG_VIDEO_ASPECT_1x1);
 	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
 	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
-		return v4l2_ctrl_query_fill_std(ctrl);
+		return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
 	case V4L2_CID_MPEG_VIDEO_BITRATE:
 		return v4l2_ctrl_query_fill(ctrl,
 				64000,
 				10000000, 1,
-				9800000);
+				1500000);
 	default:
-		break;
+		return -EINVAL;
 	}
-	return -EINVAL;
+	return 0;
 }
 
-static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
+static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 {
 	/* pretty sure we can't change any of these while streaming */
 	if (go->streaming)
@@ -528,6 +515,8 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
 		}
 		break;
 	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		if (ctrl->value < 0 || ctrl->value > 34)
+			return -EINVAL;
 		go->gop_size = ctrl->value;
 		break;
 	case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
@@ -547,7 +536,7 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
 	return 0;
 }
 
-static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go)
+static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
 {
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_STREAM_TYPE:
@@ -600,13 +589,11 @@ static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go)
 	}
 	return 0;
 }
-#endif
 
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *cap)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	strlcpy(cap->driver, "go7007", sizeof(cap->driver));
 	strlcpy(cap->card, go->name, sizeof(cap->card));
@@ -653,8 +640,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 					struct v4l2_format *fmt)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	fmt->fmt.pix.width = go->width;
@@ -672,8 +658,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 			struct v4l2_format *fmt)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	return set_capture_size(go, fmt, 1);
 }
@@ -681,8 +666,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 			struct v4l2_format *fmt)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (go->streaming)
 		return -EBUSY;
@@ -705,14 +689,14 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 			req->memory != V4L2_MEMORY_MMAP)
 		return -EINVAL;
 
-	down(&gofh->lock);
+	mutex_lock(&gofh->lock);
 	for (i = 0; i < gofh->buf_count; ++i)
 		if (gofh->bufs[i].mapped > 0)
 			goto unlock_and_return;
 
-	down(&go->hw_lock);
+	mutex_lock(&go->hw_lock);
 	if (go->in_use > 0 && gofh->buf_count == 0) {
-		up(&go->hw_lock);
+		mutex_unlock(&go->hw_lock);
 		goto unlock_and_return;
 	}
 
@@ -731,7 +715,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 				     GFP_KERNEL);
 
 		if (!gofh->bufs) {
-			up(&go->hw_lock);
+			mutex_unlock(&go->hw_lock);
 			goto unlock_and_return;
 		}
 
@@ -750,8 +734,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	}
 
 	gofh->buf_count = count;
-	up(&go->hw_lock);
-	up(&gofh->lock);
+	mutex_unlock(&go->hw_lock);
+	mutex_unlock(&gofh->lock);
 
 	memset(req, 0, sizeof(*req));
 
@@ -762,7 +746,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
 	return 0;
 
 unlock_and_return:
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
@@ -778,7 +762,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
 
 	index = buf->index;
 
-	down(&gofh->lock);
+	mutex_lock(&gofh->lock);
 	if (index >= gofh->buf_count)
 		goto unlock_and_return;
 
@@ -802,12 +786,12 @@ static int vidioc_querybuf(struct file *file, void *priv,
 	buf->memory = V4L2_MEMORY_MMAP;
 	buf->m.offset = index * GO7007_BUF_SIZE;
 	buf->length = GO7007_BUF_SIZE;
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 
 	return 0;
 
 unlock_and_return:
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
@@ -824,7 +808,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 			buf->memory != V4L2_MEMORY_MMAP)
 		return retval;
 
-	down(&gofh->lock);
+	mutex_lock(&gofh->lock);
 	if (buf->index < 0 || buf->index >= gofh->buf_count)
 		goto unlock_and_return;
 
@@ -865,12 +849,12 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 	spin_lock_irqsave(&go->spinlock, flags);
 	list_add_tail(&gobuf->stream, &go->stream);
 	spin_unlock_irqrestore(&go->spinlock, flags);
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 
 	return 0;
 
 unlock_and_return:
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
@@ -890,7 +874,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 	if (buf->memory != V4L2_MEMORY_MMAP)
 		return retval;
 
-	down(&gofh->lock);
+	mutex_lock(&gofh->lock);
 	if (list_empty(&go->stream))
 		goto unlock_and_return;
 	gobuf = list_entry(go->stream.next,
@@ -934,11 +918,11 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 	buf->length = GO7007_BUF_SIZE;
 	buf->reserved = gobuf->modet_active;
 
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 	return 0;
 
 unlock_and_return:
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 	return retval;
 }
 
@@ -952,8 +936,8 @@ static int vidioc_streamon(struct file *file, void *priv,
 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	down(&gofh->lock);
-	down(&go->hw_lock);
+	mutex_lock(&gofh->lock);
+	mutex_lock(&go->hw_lock);
 
 	if (!go->streaming) {
 		go->streaming = 1;
@@ -964,8 +948,8 @@ static int vidioc_streamon(struct file *file, void *priv,
 		else
 			retval = 0;
 	}
-	up(&go->hw_lock);
-	up(&gofh->lock);
+	mutex_unlock(&go->hw_lock);
+	mutex_unlock(&gofh->lock);
 
 	return retval;
 }
@@ -978,9 +962,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
 
 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
-	down(&gofh->lock);
+	mutex_lock(&gofh->lock);
 	go7007_streamoff(go);
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 
 	return 0;
 }
@@ -988,22 +972,20 @@ static int vidioc_streamoff(struct file *file, void *priv,
 static int vidioc_queryctrl(struct file *file, void *priv,
 			   struct v4l2_queryctrl *query)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (!go->i2c_adapter_online)
 		return -EIO;
 
 	i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
 
-	return (!query->name[0]) ? -EINVAL : 0;
+	return (!query->name[0]) ? mpeg_queryctrl(query) : 0;
 }
 
 static int vidioc_g_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 	struct v4l2_queryctrl query;
 
 	if (!go->i2c_adapter_online)
@@ -1013,7 +995,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
 	query.id = ctrl->id;
 	i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
 	if (query.name[0] == 0)
-		return -EINVAL;
+		return mpeg_g_ctrl(ctrl, go);
 	i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
 
 	return 0;
@@ -1022,8 +1004,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
 static int vidioc_s_ctrl(struct file *file, void *priv,
 				struct v4l2_control *ctrl)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 	struct v4l2_queryctrl query;
 
 	if (!go->i2c_adapter_online)
@@ -1033,7 +1014,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 	query.id = ctrl->id;
 	i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
 	if (query.name[0] == 0)
-		return -EINVAL;
+		return mpeg_s_ctrl(ctrl, go);
 	i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
 
 	return 0;
@@ -1042,8 +1023,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
 static int vidioc_g_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 	struct v4l2_fract timeperframe = {
 		.numerator = 1001 *  go->fps_scale,
 		.denominator = go->sensor_framerate,
@@ -1061,8 +1041,7 @@ static int vidioc_g_parm(struct file *filp, void *priv,
 static int vidioc_s_parm(struct file *filp, void *priv,
 		struct v4l2_streamparm *parm)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 	unsigned int n, d;
 
 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1094,8 +1073,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
 static int vidioc_enum_framesizes(struct file *filp, void *priv,
 				  struct v4l2_frmsizeenum *fsize)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	/* Return -EINVAL, if it is a TV board */
 	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1115,8 +1093,7 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
 static int vidioc_enum_frameintervals(struct file *filp, void *priv,
 				      struct v4l2_frmivalenum *fival)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	/* Return -EINVAL, if it is a TV board */
 	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1133,10 +1110,27 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
 	return 0;
 }
 
+static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
+{
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
+
+	switch (go->standard) {
+	case GO7007_STD_NTSC:
+		*std = V4L2_STD_NTSC;
+		break;
+	case GO7007_STD_PAL:
+		*std = V4L2_STD_PAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (go->streaming)
 		return -EBUSY;
@@ -1178,30 +1172,27 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
 	return 0;
 }
 
-#if 0
-	case VIDIOC_QUERYSTD:
-	{
-		v4l2_std_id *std = arg;
+static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
+{
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
-		if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
-				go->input == go->board_info->num_inputs - 1) {
-			if (!go->i2c_adapter_online)
-				return -EIO;
-			i2c_clients_command(&go->i2c_adapter,
-						VIDIOC_QUERYSTD, arg);
-		} else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
-			*std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
-		else
-			*std = 0;
-		return 0;
-	}
-#endif
+	if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
+			go->input == go->board_info->num_inputs - 1) {
+		if (!go->i2c_adapter_online)
+			return -EIO;
+		i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std);
+	} else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
+		*std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
+	else
+		*std = 0;
+
+	return 0;
+}
 
 static int vidioc_enum_input(struct file *file, void *priv,
 				struct v4l2_input *inp)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (inp->index >= go->board_info->num_inputs)
 		return -EINVAL;
@@ -1230,8 +1221,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
 
 static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	*input = go->input;
 
@@ -1240,8 +1230,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
 
 static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (input >= go->board_info->num_inputs)
 		return -EINVAL;
@@ -1262,8 +1251,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
 static int vidioc_g_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
 		return -EINVAL;
@@ -1281,8 +1269,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
 static int vidioc_s_tuner(struct file *file, void *priv,
 				struct v4l2_tuner *t)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
 		return -EINVAL;
@@ -1308,8 +1295,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
 static int vidioc_g_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
 		return -EINVAL;
@@ -1324,8 +1310,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
 static int vidioc_s_frequency(struct file *file, void *priv,
 				struct v4l2_frequency *f)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
 		return -EINVAL;
@@ -1340,8 +1325,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
 static int vidioc_cropcap(struct file *file, void *priv,
 					struct v4l2_cropcap *cropcap)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1385,8 +1369,7 @@ static int vidioc_cropcap(struct file *file, void *priv,
 
 static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
 {
-	struct go7007_file *gofh = priv;
-	struct go7007 *go = gofh->go;
+	struct go7007 *go = ((struct go7007_file *) priv)->go;
 
 	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1734,18 +1717,18 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
 		return -EINVAL; /* only support VM_SHARED mapping */
 	if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
 		return -EINVAL; /* must map exactly one full buffer */
-	down(&gofh->lock);
+	mutex_lock(&gofh->lock);
 	index = vma->vm_pgoff / GO7007_BUF_PAGES;
 	if (index >= gofh->buf_count) {
-		up(&gofh->lock);
+		mutex_unlock(&gofh->lock);
 		return -EINVAL; /* trying to map beyond requested buffers */
 	}
 	if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
-		up(&gofh->lock);
+		mutex_unlock(&gofh->lock);
 		return -EINVAL; /* offset is not aligned on buffer boundary */
 	}
 	if (gofh->bufs[index].mapped > 0) {
-		up(&gofh->lock);
+		mutex_unlock(&gofh->lock);
 		return -EBUSY;
 	}
 	gofh->bufs[index].mapped = 1;
@@ -1754,7 +1737,7 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
 	vma->vm_flags |= VM_DONTEXPAND;
 	vma->vm_flags &= ~VM_IO;
 	vma->vm_private_data = &gofh->bufs[index];
-	up(&gofh->lock);
+	mutex_unlock(&gofh->lock);
 	return 0;
 }
 
@@ -1801,7 +1784,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
 	.vidioc_querybuf          = vidioc_querybuf,
 	.vidioc_qbuf              = vidioc_qbuf,
 	.vidioc_dqbuf             = vidioc_dqbuf,
+	.vidioc_g_std             = vidioc_g_std,
 	.vidioc_s_std             = vidioc_s_std,
+	.vidioc_querystd          = vidioc_querystd,
 	.vidioc_enum_input        = vidioc_enum_input,
 	.vidioc_g_input           = vidioc_g_input,
 	.vidioc_s_input           = vidioc_s_input,
@@ -1862,7 +1847,7 @@ void go7007_v4l2_remove(struct go7007 *go)
 {
 	unsigned long flags;
 
-	down(&go->hw_lock);
+	mutex_lock(&go->hw_lock);
 	if (go->streaming) {
 		go->streaming = 0;
 		go7007_stream_stop(go);
@@ -1870,7 +1855,7 @@ void go7007_v4l2_remove(struct go7007 *go)
 		abort_queued(go);
 		spin_unlock_irqrestore(&go->spinlock, flags);
 	}
-	up(&go->hw_lock);
+	mutex_unlock(&go->hw_lock);
 	if (go->video_dev)
 		video_unregister_device(go->video_dev);
 }
diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/go7007/go7007.txt
index 1c2907c..06a76da 100644
--- a/drivers/staging/go7007/go7007.txt
+++ b/drivers/staging/go7007/go7007.txt
@@ -2,7 +2,7 @@ This is a driver for the WIS GO7007SB multi-format video encoder.
 
 Pete Eberlein <pete@sensoray.com>
 
-The driver was originally released under the GPL and is currently hosted at:
+The driver was orignally released under the GPL and is currently hosted at:
 http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
 The go7007 firmware can be acquired from the package on the site above.
 
@@ -24,10 +24,10 @@ These should be used instead of the non-standard GO7007 ioctls described
 below.
 
 
-The README files from the original package appears below:
+The README files from the orignal package appear below:
 
 ---------------------------------------------------------------------------
-                     WIS GO7007SB Public Linux Driver
+		     WIS GO7007SB Public Linux Driver
 ---------------------------------------------------------------------------
 
 
@@ -78,23 +78,23 @@ All vendor-built kernels should already be configured properly.  However,
 for custom-built kernels, the following options need to be enabled in the
 kernel as built-in or modules:
 
-        CONFIG_HOTPLUG           - Support for hot-pluggable devices
-        CONFIG_MODULES           - Enable loadable module support
-        CONFIG_KMOD              - Automatic kernel module loading
-        CONFIG_FW_LOADER         - Hotplug firmware loading support
-        CONFIG_I2C               - I2C support
-        CONFIG_VIDEO_DEV         - Video For Linux
-        CONFIG_SOUND             - Sound card support
-        CONFIG_SND               - Advanced Linux Sound Architecture
-        CONFIG_USB               - Support for Host-side USB
-        CONFIG_USB_DEVICEFS      - USB device filesystem
-        CONFIG_USB_EHCI_HCD      - EHCI HCD (USB 2.0) support
+	CONFIG_HOTPLUG           - Support for hot-pluggable devices
+	CONFIG_MODULES           - Enable loadable module support
+	CONFIG_KMOD              - Automatic kernel module loading
+	CONFIG_FW_LOADER         - Hotplug firmware loading support
+	CONFIG_I2C               - I2C support
+	CONFIG_VIDEO_DEV         - Video For Linux
+	CONFIG_SOUND             - Sound card support
+	CONFIG_SND               - Advanced Linux Sound Architecture
+	CONFIG_USB               - Support for Host-side USB
+	CONFIG_USB_DEVICEFS      - USB device filesystem
+	CONFIG_USB_EHCI_HCD      - EHCI HCD (USB 2.0) support
 
 Additionally, to use the example application, the following options need to
 be enabled in the ALSA section:
 
-        CONFIG_SND_MIXER_OSS     - OSS Mixer API
-        CONFIG_SND_PCM_OSS       - OSS PCM (digital audio) API
+	CONFIG_SND_MIXER_OSS     - OSS Mixer API
+	CONFIG_SND_PCM_OSS       - OSS PCM (digital audio) API
 
 The hotplug scripts, along with the fxload utility, must also be installed.
 These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
@@ -107,7 +107,7 @@ fxload and for loading firmware into the driver using the firmware agent.
 
 Most users should be able to compile the driver by simply running:
 
-        $ make
+	$ make
 
 in the top-level directory of the driver kit.  First the kernel modules
 will be built, followed by the example applications.
@@ -117,12 +117,12 @@ currently-running kernel, or if the module should be built for a kernel
 other than the currently-running kernel, an additional parameter will need
 to be passed to make to specify the appropriate kernel source directory:
 
-        $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
+	$ make KERNELSRC=/usr/src/linux-2.6.10-custom3
 
 Once the compile completes, the driver and firmware files should be
 installed by running:
 
-        $ make install
+	$ make install
 
 The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
 and the firmware files will be placed in the appropriate hotplug firmware
@@ -200,7 +200,7 @@ stereo audio broadcasts on the A2 carrier.
 To verify that the configuration has been placed in the correct location,
 execute:
 
-        $ modprobe -c | grep wis-sony-tuner
+	$ modprobe -c | grep wis-sony-tuner
 
 If the configuration line appears, then modprobe will pass the parameters
 correctly the next time the wis-sony-tuner module is loaded into the
@@ -223,7 +223,7 @@ This application will auto-detect the V4L2 and ALSA/OSS device names of the
 hardware and will record video and audio to an AVI file for a specified
 number of seconds.  For example:
 
-        $ apps/gorecord -duration 60 capture.avi
+	$ apps/gorecord -duration 60 capture.avi
 
 If this application does not successfully record an AVI file, the error
 messages produced by gorecord and recorded in the system log (usually in
@@ -286,35 +286,35 @@ features of the GO7007SB encoder, which are described below:
 
     Fields in struct go7007_comp_params:
 
-        __u32                        The maximum number of frames in each
-          gop_size                   Group Of Pictures; i.e. the maximum
-                                     number of frames minus one between
-                                     each key frame.
+	__u32                        The maximum number of frames in each
+	  gop_size                   Group Of Pictures; i.e. the maximum
+				     number of frames minus one between
+				     each key frame.
 
-        __u32                        The maximum number of sequential
-          max_b_frames               bidirectionally-predicted frames.
-                                     (B-frames are not yet supported.)
+	__u32                        The maximum number of sequential
+	  max_b_frames               bidirectionally-predicted frames.
+				     (B-frames are not yet supported.)
 
-        enum go7007_aspect_ratio     The aspect ratio to be encoded in the
-          aspect_ratio               meta-data of the compressed format.
+	enum go7007_aspect_ratio     The aspect ratio to be encoded in the
+	  aspect_ratio               meta-data of the compressed format.
 
-                                     Choices are:
-                                        GO7007_ASPECT_RATIO_1_1
-                                        GO7007_ASPECT_RATIO_4_3_NTSC
-                                        GO7007_ASPECT_RATIO_4_3_PAL
-                                        GO7007_ASPECT_RATIO_16_9_NTSC
-                                        GO7007_ASPECT_RATIO_16_9_PAL
+				     Choices are:
+					GO7007_ASPECT_RATIO_1_1
+					GO7007_ASPECT_RATIO_4_3_NTSC
+					GO7007_ASPECT_RATIO_4_3_PAL
+					GO7007_ASPECT_RATIO_16_9_NTSC
+					GO7007_ASPECT_RATIO_16_9_PAL
 
-        __u32                        Bit-wise OR of control flags (below)
-          flags
+	__u32                        Bit-wise OR of control flags (below)
+	  flags
 
     Flags in struct go7007_comp_params:
 
-        GO7007_COMP_CLOSED_GOP       Only produce self-contained GOPs, used
-                                     to produce streams appropriate for
-                                     random seeking.
+	GO7007_COMP_CLOSED_GOP       Only produce self-contained GOPs, used
+				     to produce streams appropriate for
+				     random seeking.
 
-        GO7007_COMP_OMIT_SEQ_HEADER  Omit the stream sequence header.
+	GO7007_COMP_OMIT_SEQ_HEADER  Omit the stream sequence header.
 
 
   GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
@@ -337,56 +337,56 @@ features of the GO7007SB encoder, which are described below:
 
     Fields in struct go7007_mpeg_params:
 
-        enum go7007_mpeg_video_standard
-          mpeg_video_standard        The MPEG video standard in which to
-                                     compress the video.
-
-                                     Choices are:
-                                        GO7007_MPEG_VIDEO_MPEG1
-                                        GO7007_MPEG_VIDEO_MPEG2
-                                        GO7007_MPEG_VIDEO_MPEG4
-
-        __u32                        Bit-wise OR of control flags (below)
-          flags
-
-        __u32                        The profile and level indication to be
-          pali                       stored in the sequence header.  This
-                                     is only used as an indicator to the
-                                     decoder, and does not affect the MPEG
-                                     features used in the video stream.
-                                     Not valid for MPEG1.
-
-                                     Choices for MPEG2 are:
-                                        GO7007_MPEG2_PROFILE_MAIN_MAIN
-
-                                     Choices for MPEG4 are:
-                                        GO7007_MPEG4_PROFILE_S_L0
-                                        GO7007_MPEG4_PROFILE_S_L1
-                                        GO7007_MPEG4_PROFILE_S_L2
-                                        GO7007_MPEG4_PROFILE_S_L3
-                                        GO7007_MPEG4_PROFILE_ARTS_L1
-                                        GO7007_MPEG4_PROFILE_ARTS_L2
-                                        GO7007_MPEG4_PROFILE_ARTS_L3
-                                        GO7007_MPEG4_PROFILE_ARTS_L4
-                                        GO7007_MPEG4_PROFILE_AS_L0
-                                        GO7007_MPEG4_PROFILE_AS_L1
-                                        GO7007_MPEG4_PROFILE_AS_L2
-                                        GO7007_MPEG4_PROFILE_AS_L3
-                                        GO7007_MPEG4_PROFILE_AS_L4
-                                        GO7007_MPEG4_PROFILE_AS_L5
+	enum go7007_mpeg_video_standard
+	  mpeg_video_standard        The MPEG video standard in which to
+				     compress the video.
+
+				     Choices are:
+					GO7007_MPEG_VIDEO_MPEG1
+					GO7007_MPEG_VIDEO_MPEG2
+					GO7007_MPEG_VIDEO_MPEG4
+
+	__u32                        Bit-wise OR of control flags (below)
+	  flags
+
+	__u32                        The profile and level indication to be
+	  pali                       stored in the sequence header.  This
+				     is only used as an indicator to the
+				     decoder, and does not affect the MPEG
+				     features used in the video stream.
+				     Not valid for MPEG1.
+
+				     Choices for MPEG2 are:
+					GO7007_MPEG2_PROFILE_MAIN_MAIN
+
+				     Choices for MPEG4 are:
+					GO7007_MPEG4_PROFILE_S_L0
+					GO7007_MPEG4_PROFILE_S_L1
+					GO7007_MPEG4_PROFILE_S_L2
+					GO7007_MPEG4_PROFILE_S_L3
+					GO7007_MPEG4_PROFILE_ARTS_L1
+					GO7007_MPEG4_PROFILE_ARTS_L2
+					GO7007_MPEG4_PROFILE_ARTS_L3
+					GO7007_MPEG4_PROFILE_ARTS_L4
+					GO7007_MPEG4_PROFILE_AS_L0
+					GO7007_MPEG4_PROFILE_AS_L1
+					GO7007_MPEG4_PROFILE_AS_L2
+					GO7007_MPEG4_PROFILE_AS_L3
+					GO7007_MPEG4_PROFILE_AS_L4
+					GO7007_MPEG4_PROFILE_AS_L5
 
     Flags in struct go7007_mpeg_params:
 
-        GO7007_MPEG_FORCE_DVD_MODE   Force all compression parameters and
-                                     bitrate control settings to comply
-                                     with DVD MPEG2 stream requirements.
-                                     This overrides most compression and
-                                     bitrate settings!
+	GO7007_MPEG_FORCE_DVD_MODE   Force all compression parameters and
+				     bitrate control settings to comply
+				     with DVD MPEG2 stream requirements.
+				     This overrides most compression and
+				     bitrate settings!
 
-        GO7007_MPEG_OMIT_GOP_HEADER  Omit the GOP header.
+	GO7007_MPEG_OMIT_GOP_HEADER  Omit the GOP header.
 
-        GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
-                                     the start of each GOP.
+	GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
+				     the start of each GOP.
 
 
   GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
@@ -404,7 +404,7 @@ features of the GO7007SB encoder, which are described below:
 
 
 ----------------------------------------------------------------------------
-                   Installing the WIS PCI Voyager Driver
+		   Installing the WIS PCI Voyager Driver
 ---------------------------------------------------------------------------
 
 The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index 1706fbf..8c85a9c 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -21,12 +21,10 @@
 #include <linux/i2c.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-common.h>
+#include "s2250-loader.h"
 #include "go7007-priv.h"
 #include "wis-i2c.h"
 
-extern int s2250loader_init(void);
-extern void s2250loader_cleanup(void);
-
 #define TLV320_ADDRESS      0x34
 #define VPX322_ADDR_ANALOGCONTROL1	0x02
 #define VPX322_ADDR_BRIGHTNESS0		0x0127
@@ -34,7 +32,7 @@ extern void s2250loader_cleanup(void);
 #define VPX322_ADDR_CONTRAST0		0x0128
 #define VPX322_ADDR_CONTRAST1		0x0132
 #define VPX322_ADDR_HUE			0x00dc
-#define VPX322_ADDR_SAT	 	        0x0030
+#define VPX322_ADDR_SAT			0x0030
 
 struct go7007_usb_board {
 	unsigned int flags;
@@ -43,7 +41,7 @@ struct go7007_usb_board {
 
 struct go7007_usb {
 	struct go7007_usb_board *board;
-	struct semaphore i2c_lock;
+	struct mutex i2c_lock;
 	struct usb_device *usbdev;
 	struct urb *video_urbs[8];
 	struct urb *audio_urbs[8];
@@ -114,7 +112,7 @@ static u16 vid_regs_fp_pal[] =
 };
 
 struct s2250 {
-	int std;
+	v4l2_std_id std;
 	int input;
 	int brightness;
 	int contrast;
@@ -165,7 +163,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
 		return -ENOMEM;
 
 	usb = go->hpi_context;
-	if (down_interruptible(&usb->i2c_lock) != 0) {
+	if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 		printk(KERN_INFO "i2c lock failed\n");
 		kfree(buf);
 		return -EINTR;
@@ -175,7 +173,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
 				       buf,
 				       16, 1);
 
-	up(&usb->i2c_lock);
+	mutex_unlock(&usb->i2c_lock);
 	kfree(buf);
 	return rc;
 }
@@ -203,19 +201,23 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
 	memset(buf, 0xcd, 6);
 
 	usb = go->hpi_context;
-	if (down_interruptible(&usb->i2c_lock) != 0) {
+	if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
 		printk(KERN_INFO "i2c lock failed\n");
+		kfree(buf);
 		return -EINTR;
 	}
-	if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0)
+	if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) {
+		kfree(buf);
 		return -EFAULT;
+	}
 
-	up(&usb->i2c_lock);
+	mutex_unlock(&usb->i2c_lock);
 	if (buf[0] == 0) {
 		unsigned int subaddr, val_read;
 
 		subaddr = (buf[4] << 8) + buf[5];
 		val_read = (buf[2] << 8) + buf[3];
+		kfree(buf);
 		if (val_read != val) {
 			printk(KERN_INFO "invalid fp write %x %x\n",
 			       val_read, val);
@@ -226,8 +228,10 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
 			       subaddr, addr);
 			return -EFAULT;
 		}
-	} else
+	} else {
+		kfree(buf);
 		return -EFAULT;
+	}
 
 	/* save last 12b value */
 	if (addr == 0x12b)
@@ -236,6 +240,45 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
 	return 0;
 }
 
+static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
+{
+	struct go7007 *go = i2c_get_adapdata(client->adapter);
+	struct go7007_usb *usb;
+	u8 *buf;
+
+	if (go == NULL)
+		return -ENODEV;
+
+	if (go->status == STATUS_SHUTDOWN)
+		return -EBUSY;
+
+	buf = kzalloc(16, GFP_KERNEL);
+
+	if (buf == NULL)
+		return -ENOMEM;
+
+
+
+	memset(buf, 0xcd, 6);
+	usb = go->hpi_context;
+	if (down_interruptible(&usb->i2c_lock) != 0) {
+		printk(KERN_INFO "i2c lock failed\n");
+		kfree(buf);
+		return -EINTR;
+	}
+	if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) {
+		kfree(buf);
+		return -EFAULT;
+	}
+	up(&usb->i2c_lock);
+
+	*val = (buf[0] << 8) | buf[1];
+	kfree(buf);
+
+	return 0;
+}
+
+
 static int write_regs(struct i2c_client *client, u8 *regs)
 {
 	int i;
@@ -350,14 +393,42 @@ static int s2250_command(struct i2c_client *client,
 	{
 		struct v4l2_control *ctrl = arg;
 		int value1;
+		u16 oldvalue;
 
 		switch (ctrl->id) {
 		case V4L2_CID_BRIGHTNESS:
-			printk(KERN_INFO "s2250: future setting\n");
-			return -EINVAL;
+			if (ctrl->value > 100)
+				dec->brightness = 100;
+			else if (ctrl->value < 0)
+				dec->brightness = 0;
+			else
+				dec->brightness = ctrl->value;
+			value1 = (dec->brightness - 50) * 255 / 100;
+			read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
+			write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
+				     value1 | (oldvalue & ~0xff));
+			read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
+			write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
+				     value1 | (oldvalue & ~0xff));
+			write_reg_fp(client, 0x140, 0x60);
+			break;
 		case V4L2_CID_CONTRAST:
-			printk(KERN_INFO "s2250: future setting\n");
-			return -EINVAL;
+			if (ctrl->value > 100)
+				dec->contrast = 100;
+			else if (ctrl->value < 0)
+				dec->contrast = 0;
+			else
+				dec->contrast = ctrl->value;
+			value1 = dec->contrast * 0x40 / 100;
+			if (value1 > 0x3f)
+				value1 = 0x3f; /* max */
+			read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
+			write_reg_fp(client, VPX322_ADDR_CONTRAST0,
+				     value1 | (oldvalue & ~0x3f));
+			read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
+			write_reg_fp(client, VPX322_ADDR_CONTRAST1,
+				     value1 | (oldvalue & ~0x3f));
+			write_reg_fp(client, 0x140, 0x60);
 			break;
 		case V4L2_CID_SATURATION:
 			if (ctrl->value > 127)
@@ -541,7 +612,7 @@ static int s2250_probe(struct i2c_client *client,
 	dec->audio_input = 0;
 	write_reg(client, 0x08, 0x02); /* Line In */
 
-	if (down_interruptible(&usb->i2c_lock) == 0) {
+	if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
 		data = kzalloc(16, GFP_KERNEL);
 		if (data != NULL) {
 			int rc;
@@ -560,7 +631,7 @@ static int s2250_probe(struct i2c_client *client,
 			}
 			kfree(data);
 		}
-		up(&usb->i2c_lock);
+		mutex_unlock(&usb->i2c_lock);
 	}
 
 	printk("s2250: initialized successfully\n");
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index bb22347..d7bf829 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -35,7 +35,7 @@ typedef struct device_extension_s {
 #define MAX_DEVICES 256
 
 static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
-static DECLARE_MUTEX(s2250_dev_table_mutex);
+static DEFINE_MUTEX(s2250_dev_table_mutex);
 
 #define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
 static void s2250loader_delete(struct kref *kref)
@@ -67,7 +67,7 @@ static int s2250loader_probe(struct usb_interface *interface,
 		printk(KERN_ERR "can't handle multiple config\n");
 		return -1;
 	}
-	down(&s2250_dev_table_mutex);
+	mutex_lock(&s2250_dev_table_mutex);
 
 	for (minor = 0; minor < MAX_DEVICES; minor++) {
 		if (s2250_dev_table[minor] == NULL)
@@ -96,7 +96,7 @@ static int s2250loader_probe(struct usb_interface *interface,
 
 	kref_init(&(s->kref));
 
-	up(&s2250_dev_table_mutex);
+	mutex_unlock(&s2250_dev_table_mutex);
 
 	if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
 		printk(KERN_ERR
@@ -128,7 +128,7 @@ static int s2250loader_probe(struct usb_interface *interface,
 	return 0;
 
 failed:
-	up(&s2250_dev_table_mutex);
+	mutex_unlock(&s2250_dev_table_mutex);
 failed2:
 	if (s)
 		kref_put(&(s->kref), s2250loader_delete);
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
index cd19be6..03c4dfc 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -26,7 +26,7 @@
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/i2c.h>
-#include <linux/semaphore.h>
+#include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <asm/system.h>
 #include <sound/core.h>
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 6c3427b..506dca6 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -111,7 +111,8 @@ static int wis_tw9903_command(struct i2c_client *client,
 		i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
 		break;
 	}
-#if 0   /* The scaler on this thing seems to be horribly broken */
+#if 0
+	/* The scaler on this thing seems to be horribly broken */
 	case DECODER_SET_RESOLUTION:
 	{
 		struct video_decoder_resolution *res = arg;
diff --git a/drivers/staging/heci/Kconfig b/drivers/staging/heci/Kconfig
deleted file mode 100644
index c7206f8..0000000
--- a/drivers/staging/heci/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config HECI
-	tristate "Intel Management Engine Interface (MEI) Support"
-	depends on PCI
-	---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
deleted file mode 100644
index 0524856..0000000
--- a/drivers/staging/heci/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index f86715d..0000000
--- a/drivers/staging/heci/TODO
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index 48f120d..0000000
--- a/drivers/staging/heci/heci.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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/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
deleted file mode 100644
index ff30386..0000000
--- a/drivers/staging/heci/heci_data_structures.h
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * 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/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
deleted file mode 100644
index 31fd891..0000000
--- a/drivers/staging/heci/heci_init.c
+++ /dev/null
@@ -1,1083 +0,0 @@
-/*
- * 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_csr_clear_his(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;
-
-	heci_set_csr_register(dev);
-
-	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;
-
-	spin_lock_bh(&dev->device_lock);
-	if (file_ext->state != HECI_FILE_DISCONNECTING) {
-		spin_unlock_bh(&dev->device_lock);
-		return 0;
-	}
-	spin_unlock_bh(&dev->device_lock);
-
-	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)) {
-			mdelay(10); /* Wait for hardware disconnection ready */
-			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);
-
-	spin_lock_bh(&dev->device_lock);
-	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");
-	}
-
-	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
deleted file mode 100644
index 03e1df1..0000000
--- a/drivers/staging/heci/heci_interface.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * 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,
- * and ignore the H_IS bit for it is write-one-to-zero.
- *
- * @dev: device object for our driver
- */
-void heci_set_csr_register(struct iamt_heci_device *dev)
-{
-	if ((dev->host_hw_state & H_IS) == H_IS)
-		dev->host_hw_state &= ~H_IS;
-	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);
-}
-
-/**
- * heci_csr_clear_his - clear H_IS bit in H_CSR
- *
- * @dev: device object for our driver
- */
-void heci_csr_clear_his(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);
-}
-
-/**
- * _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;
-	heci_set_csr_register(dev);
-	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
deleted file mode 100644
index 34db7e5..0000000
--- a/drivers/staging/heci/heci_interface.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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/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_csr_clear_his(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
deleted file mode 100644
index ddf4822..0000000
--- a/drivers/staging/heci/heci_main.c
+++ /dev/null
@@ -1,1576 +0,0 @@
-/*
- * 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);
-	spin_lock_bh(&dev->device_lock);
-	file_ext->state = HECI_FILE_INITIALIZING;
-	spin_unlock_bh(&dev->device_lock);
-	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);
-		spin_lock_bh(&dev->device_lock);
-		if (file_ext->state == HECI_FILE_CONNECTED) {
-			file_ext->state = HECI_FILE_DISCONNECTING;
-			spin_unlock_bh(&dev->device_lock);
-			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;
-	}
-
-	err = heci_start_read(dev, if_num, file_ext);
-	spin_lock_bh(&file_ext->read_io_lock);
-	if (err != 0 && err != -EBUSY) {
-		DBG("heci start read failure with status = %d\n", err);
-		spin_unlock_bh(&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_bh(&file_ext->read_io_lock);
-			goto out;
-		}
-		spin_unlock_bh(&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;
-		}
-
-		spin_lock_bh(&dev->device_lock);
-		if (HECI_FILE_INITIALIZING == file_ext->state ||
-		    HECI_FILE_DISCONNECTED == file_ext->state ||
-		    HECI_FILE_DISCONNECTING == file_ext->state) {
-			spin_unlock_bh(&dev->device_lock);
-			rets = -EBUSY;
-			goto out;
-		}
-		spin_unlock_bh(&dev->device_lock);
-		spin_lock_bh(&file_ext->read_io_lock);
-	}
-
-	priv_cb = file_ext->read_cb;
-
-	if (!priv_cb) {
-		spin_unlock_bh(&file_ext->read_io_lock);
-		return -ENODEV;
-	}
-	if (file_ext->reading_state != HECI_READ_COMPLETE) {
-		spin_unlock_bh(&file_ext->read_io_lock);
-		return 0;
-	}
-	spin_unlock_bh(&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_bh(&file_ext->read_io_lock);
-	file_ext->reading_state = HECI_IDLE;
-	file_ext->read_cb = NULL;
-	file_ext->read_pending = 0;
-	spin_unlock_bh(&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_bh(&file_ext->read_io_lock);
-			file_ext->reading_state = HECI_IDLE;
-			file_ext->read_cb = NULL;
-			file_ext->read_pending = 0;
-			spin_unlock_bh(&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],
-				 priv_write_cb->request_buffer.data, 4) == 0) ||
-	     (memcmp(heci_wd_state_independence_msg[1],
-				 priv_write_cb->request_buffer.data, 4) == 0) ||
-	     (memcmp(heci_wd_state_independence_msg[2],
-				 priv_write_cb->request_buffer.data, 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);
-	spin_lock_bh(&dev->device_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);
-		spin_unlock_bh(&dev->device_lock);
-		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;
-		spin_unlock_bh(&dev->device_lock);
-		goto unlock;
-	}
-	if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
-		rets = -EINVAL;
-		spin_unlock_bh(&dev->device_lock);
-		goto unlock;
-	}
-	priv_write_cb->file_private = file_ext;
-
-	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
deleted file mode 100644
index 3007aa6..0000000
--- a/drivers/staging/heci/heci_version.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 2a3a01a..0000000
--- a/drivers/staging/heci/interrupt.c
+++ /dev/null
@@ -1,1555 +0,0 @@
-/*
- * 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);
-
-	/* clear H_IS bit in H_CSR */
-	heci_csr_clear_his(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)
-		DBG("heci_bh_handler was already on the workqueue.\n");
-	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);
-
-		/* clear H_IS bit in H_CSR */
-		heci_csr_clear_his(dev);
-
-		PREPARE_WORK(&dev->work, heci_bh_handler);
-		DBG("schedule work the heci_bh_handler.\n");
-		rets = schedule_work(&dev->work);
-		if (!rets)
-			DBG("heci_bh_handler was already queued.\n");
-	} 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_bh(&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_bh(&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_bh(&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_bh(&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_WRITE) &&
-					(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
deleted file mode 100644
index 1a6faf8..0000000
--- a/drivers/staging/heci/io_heci.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
- * 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((void __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, (void __user *)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((void __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_unlock_bh(&dev->device_lock);
-
-	spin_lock(&file_ext->file_lock);
-	spin_lock_bh(&dev->device_lock);
-	if (file_ext->state != HECI_FILE_CONNECTING) {
-		rets = -ENODEV;
-		spin_unlock_bh(&dev->device_lock);
-		spin_unlock(&file_ext->file_lock);
-		goto end;
-	}
-	/* 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);
-			spin_unlock(&file_ext->file_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);
-	spin_unlock(&file_ext->file_lock);
-	err = wait_event_timeout(dev->wait_recvd_msg,
-			(HECI_FILE_CONNECTED == file_ext->state
-			 || HECI_FILE_DISCONNECTED == file_ext->state),
-			timeout * HZ);
-
-	spin_lock_bh(&dev->device_lock);
-	if (HECI_FILE_CONNECTED == file_ext->state) {
-		spin_unlock_bh(&dev->device_lock);
-		DBG("successfully connected to FW client.\n");
-		rets = file_ext->status;
-		/* now copy the data to user space */
-		if (copy_to_user((void __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);
-		spin_unlock_bh(&dev->device_lock);
-		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,
-				(void __user *)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, (void __user *)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;
-	}
-
-	spin_lock_bh(&dev->device_lock);
-	if (file_ext->state != HECI_FILE_CONNECTED) {
-		spin_unlock_bh(&dev->device_lock);
-		return -ENODEV;
-	}
-
-	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");
-	spin_lock_bh(&file_ext->read_io_lock);
-	if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) {
-		DBG("read is pending.\n");
-		spin_unlock_bh(&file_ext->read_io_lock);
-		return -EBUSY;
-	}
-	spin_unlock_bh(&file_ext->read_io_lock);
-
-	priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
-	if (!priv_cb)
-		return -ENOMEM;
-
-	spin_lock_bh(&file_ext->read_io_lock);
-	DBG("allocation call back success\n"
-	    "host client = %d, ME client = %d\n",
-	    file_ext->host_client_id, file_ext->me_client_id);
-	spin_unlock_bh(&file_ext->read_io_lock);
-
-	spin_lock_bh(&dev->device_lock);
-	spin_lock_bh(&file_ext->read_io_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);
-	spin_unlock_bh(&file_ext->read_io_lock);
-	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;
-	spin_lock_bh(&dev->device_lock);
-	spin_lock_bh(&file_ext->read_io_lock);
-	file_ext->read_cb = priv_cb;
-	if (dev->host_buffer_is_empty) {
-		dev->host_buffer_is_empty = 0;
-		if (!heci_send_flow_control(dev, file_ext)) {
-			rets = -ENODEV;
-			spin_unlock_bh(&file_ext->read_io_lock);
-			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(&file_ext->read_io_lock);
-	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/hv/BlkVsc.c b/drivers/staging/hv/BlkVsc.c
new file mode 100644
index 0000000..51aa861
--- /dev/null
+++ b/drivers/staging/hv/BlkVsc.c
@@ -0,0 +1,111 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include "osd.h"
+#include "StorVsc.c"
+
+static const char *gBlkDriverName = "blkvsc";
+
+/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
+static const struct hv_guid gBlkVscDeviceType = {
+	.data = {
+		0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
+		0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
+	}
+};
+
+static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
+{
+	struct storvsc_device_info *deviceInfo;
+	int ret = 0;
+
+	DPRINT_ENTER(BLKVSC);
+
+	deviceInfo = (struct storvsc_device_info *)AdditionalInfo;
+
+	ret = StorVscOnDeviceAdd(Device, AdditionalInfo);
+	if (ret != 0) {
+		DPRINT_EXIT(BLKVSC);
+		return ret;
+	}
+
+	/*
+	 * We need to use the device instance guid to set the path and target
+	 * id. For IDE devices, the device instance id is formatted as
+	 * <bus id> * - <device id> - 8899 - 000000000000.
+	 */
+	deviceInfo->PathId = Device->deviceInstance.data[3] << 24 |
+			     Device->deviceInstance.data[2] << 16 |
+			     Device->deviceInstance.data[1] << 8  |
+			     Device->deviceInstance.data[0];
+
+	deviceInfo->TargetId = Device->deviceInstance.data[5] << 8 |
+			       Device->deviceInstance.data[4];
+
+	DPRINT_EXIT(BLKVSC);
+
+	return ret;
+}
+
+int BlkVscInitialize(struct hv_driver *Driver)
+{
+	struct storvsc_driver_object *storDriver;
+	int ret = 0;
+
+	DPRINT_ENTER(BLKVSC);
+
+	storDriver = (struct storvsc_driver_object *)Driver;
+
+	/* Make sure we are at least 2 pages since 1 page is used for control */
+	ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1));
+
+	Driver->name = gBlkDriverName;
+	memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(struct hv_guid));
+
+	storDriver->RequestExtSize = sizeof(struct storvsc_request_extension);
+
+	/*
+	 * Divide the ring buffer data size (which is 1 page less than the ring
+	 * buffer size since that page is reserved for the ring buffer indices)
+	 * by the max request size (which is
+	 * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64)
+	 */
+	storDriver->MaxOutstandingRequestsPerChannel =
+		((storDriver->RingBufferSize - PAGE_SIZE) /
+		  ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET +
+			   sizeof(struct vstor_packet) + sizeof(u64),
+			   sizeof(u64)));
+
+	DPRINT_INFO(BLKVSC, "max io outstd %u",
+		    storDriver->MaxOutstandingRequestsPerChannel);
+
+	/* Setup the dispatch table */
+	storDriver->Base.OnDeviceAdd = BlkVscOnDeviceAdd;
+	storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove;
+	storDriver->Base.OnCleanup = StorVscOnCleanup;
+	storDriver->OnIORequest	= StorVscOnIORequest;
+
+	DPRINT_EXIT(BLKVSC);
+
+	return ret;
+}
diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/Channel.c
new file mode 100644
index 0000000..d649ee1
--- /dev/null
+++ b/drivers/staging/hv/Channel.c
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include "osd.h"
+#include "logging.h"
+#include "VmbusPrivate.h"
+
+/* Internal routines */
+static int VmbusChannelCreateGpadlHeader(
+	void *Kbuffer,	/* must be phys and virt contiguous */
+	u32 Size,	/* page-size multiple */
+	struct vmbus_channel_msginfo **msgInfo,
+	u32 *MessageCount);
+static void DumpVmbusChannel(struct vmbus_channel *channel);
+static void VmbusChannelSetEvent(struct vmbus_channel *channel);
+
+
+#if 0
+static void DumpMonitorPage(struct hv_monitor_page *MonitorPage)
+{
+	int i = 0;
+	int j = 0;
+
+	DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d",
+		   MonitorPage, MonitorPage->TriggerState);
+
+	for (i = 0; i < 4; i++)
+		DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i,
+			   MonitorPage->TriggerGroup[i].AsUINT64);
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 32; j++) {
+			DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j,
+				   MonitorPage->Latency[i][j]);
+		}
+	}
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < 32; j++) {
+			DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j,
+			       MonitorPage->Parameter[i][j].ConnectionId.Asu32);
+			DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j,
+				MonitorPage->Parameter[i][j].FlagNumber);
+		}
+	}
+}
+#endif
+
+/**
+ * VmbusChannelSetEvent - Trigger an event notification on the specified channel.
+ */
+static void VmbusChannelSetEvent(struct vmbus_channel *Channel)
+{
+	struct hv_monitor_page *monitorPage;
+
+	DPRINT_ENTER(VMBUS);
+
+	if (Channel->OfferMsg.MonitorAllocated) {
+		/* Each u32 represents 32 channels */
+		set_bit(Channel->OfferMsg.ChildRelId & 31,
+			(unsigned long *) gVmbusConnection.SendInterruptPage +
+			(Channel->OfferMsg.ChildRelId >> 5));
+
+		monitorPage = gVmbusConnection.MonitorPages;
+		monitorPage++; /* Get the child to parent monitor page */
+
+		set_bit(Channel->MonitorBit,
+			(unsigned long *)&monitorPage->TriggerGroup
+					[Channel->MonitorGroup].Pending);
+
+	} else {
+		VmbusSetEvent(Channel->OfferMsg.ChildRelId);
+	}
+
+	DPRINT_EXIT(VMBUS);
+}
+
+#if 0
+static void VmbusChannelClearEvent(struct vmbus_channel *channel)
+{
+	struct hv_monitor_page *monitorPage;
+
+	DPRINT_ENTER(VMBUS);
+
+	if (Channel->OfferMsg.MonitorAllocated) {
+		/* Each u32 represents 32 channels */
+		clear_bit(Channel->OfferMsg.ChildRelId & 31,
+			  (unsigned long *)gVmbusConnection.SendInterruptPage +
+			  (Channel->OfferMsg.ChildRelId >> 5));
+
+		monitorPage =
+			(struct hv_monitor_page *)gVmbusConnection.MonitorPages;
+		monitorPage++; /* Get the child to parent monitor page */
+
+		clear_bit(Channel->MonitorBit,
+			  (unsigned long *)&monitorPage->TriggerGroup
+					[Channel->MonitorGroup].Pending);
+	}
+
+	DPRINT_EXIT(VMBUS);
+}
+
+#endif
+/**
+ * VmbusChannelGetDebugInfo -Retrieve various channel debug info
+ */
+void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel,
+			      struct vmbus_channel_debug_info *DebugInfo)
+{
+	struct hv_monitor_page *monitorPage;
+	u8 monitorGroup = (u8)Channel->OfferMsg.MonitorId / 32;
+	u8 monitorOffset = (u8)Channel->OfferMsg.MonitorId % 32;
+	/* u32 monitorBit	= 1 << monitorOffset; */
+
+	DebugInfo->RelId = Channel->OfferMsg.ChildRelId;
+	DebugInfo->State = Channel->State;
+	memcpy(&DebugInfo->InterfaceType,
+	       &Channel->OfferMsg.Offer.InterfaceType, sizeof(struct hv_guid));
+	memcpy(&DebugInfo->InterfaceInstance,
+	       &Channel->OfferMsg.Offer.InterfaceInstance,
+	       sizeof(struct hv_guid));
+
+	monitorPage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages;
+
+	DebugInfo->MonitorId = Channel->OfferMsg.MonitorId;
+
+	DebugInfo->ServerMonitorPending =
+			monitorPage->TriggerGroup[monitorGroup].Pending;
+	DebugInfo->ServerMonitorLatency =
+			monitorPage->Latency[monitorGroup][monitorOffset];
+	DebugInfo->ServerMonitorConnectionId =
+			monitorPage->Parameter[monitorGroup]
+					      [monitorOffset].ConnectionId.u.Id;
+
+	monitorPage++;
+
+	DebugInfo->ClientMonitorPending =
+			monitorPage->TriggerGroup[monitorGroup].Pending;
+	DebugInfo->ClientMonitorLatency =
+			monitorPage->Latency[monitorGroup][monitorOffset];
+	DebugInfo->ClientMonitorConnectionId =
+			monitorPage->Parameter[monitorGroup]
+					      [monitorOffset].ConnectionId.u.Id;
+
+	RingBufferGetDebugInfo(&Channel->Inbound, &DebugInfo->Inbound);
+	RingBufferGetDebugInfo(&Channel->Outbound, &DebugInfo->Outbound);
+}
+
+/**
+ * VmbusChannelOpen - Open the specified channel.
+ */
+int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize,
+		     u32 RecvRingBufferSize, void *UserData, u32 UserDataLen,
+		     void (*OnChannelCallback)(void *context), void *Context)
+{
+	struct vmbus_channel_open_channel *openMsg;
+	struct vmbus_channel_msginfo *openInfo;
+	void *in, *out;
+	unsigned long flags;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Aligned to page size */
+	ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1)));
+	ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1)));
+
+	NewChannel->OnChannelCallback = OnChannelCallback;
+	NewChannel->ChannelCallbackContext = Context;
+
+	/* Allocate the ring buffer */
+	out = osd_PageAlloc((SendRingBufferSize + RecvRingBufferSize)
+			     >> PAGE_SHIFT);
+	ASSERT(out);
+	ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0);
+
+	in = (void *)((unsigned long)out + SendRingBufferSize);
+
+	NewChannel->RingBufferPages = out;
+	NewChannel->RingBufferPageCount = (SendRingBufferSize +
+					   RecvRingBufferSize) >> PAGE_SHIFT;
+
+	RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize);
+
+	RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize);
+
+	/* Establish the gpadl for the ring buffer */
+	DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...",
+		   NewChannel);
+
+	NewChannel->RingBufferGpadlHandle = 0;
+
+	ret = VmbusChannelEstablishGpadl(NewChannel,
+					 NewChannel->Outbound.RingBuffer,
+					 SendRingBufferSize +
+					 RecvRingBufferSize,
+					 &NewChannel->RingBufferGpadlHandle);
+
+	DPRINT_DBG(VMBUS, "channel %p <relid %d gpadl 0x%x send ring %p "
+		   "size %d recv ring %p size %d, downstreamoffset %d>",
+		   NewChannel, NewChannel->OfferMsg.ChildRelId,
+		   NewChannel->RingBufferGpadlHandle,
+		   NewChannel->Outbound.RingBuffer,
+		   NewChannel->Outbound.RingSize,
+		   NewChannel->Inbound.RingBuffer,
+		   NewChannel->Inbound.RingSize,
+		   SendRingBufferSize);
+
+	/* Create and init the channel open message */
+	openInfo = kmalloc(sizeof(*openInfo) +
+			   sizeof(struct vmbus_channel_open_channel),
+			   GFP_KERNEL);
+	ASSERT(openInfo != NULL);
+
+	openInfo->WaitEvent = osd_WaitEventCreate();
+
+	openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg;
+	openMsg->Header.MessageType = ChannelMessageOpenChannel;
+	openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; /* FIXME */
+	openMsg->ChildRelId = NewChannel->OfferMsg.ChildRelId;
+	openMsg->RingBufferGpadlHandle = NewChannel->RingBufferGpadlHandle;
+	ASSERT(openMsg->RingBufferGpadlHandle);
+	openMsg->DownstreamRingBufferPageOffset = SendRingBufferSize >>
+						  PAGE_SHIFT;
+	openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */
+
+	ASSERT(UserDataLen <= MAX_USER_DEFINED_BYTES);
+	if (UserDataLen)
+		memcpy(openMsg->UserData, UserData, UserDataLen);
+
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+	list_add_tail(&openInfo->MsgListEntry,
+		      &gVmbusConnection.ChannelMsgList);
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	DPRINT_DBG(VMBUS, "Sending channel open msg...");
+
+	ret = VmbusPostMessage(openMsg,
+			       sizeof(struct vmbus_channel_open_channel));
+	if (ret != 0) {
+		DPRINT_ERR(VMBUS, "unable to open channel - %d", ret);
+		goto Cleanup;
+	}
+
+	/* FIXME: Need to time-out here */
+	osd_WaitEventWait(openInfo->WaitEvent);
+
+	if (openInfo->Response.OpenResult.Status == 0)
+		DPRINT_INFO(VMBUS, "channel <%p> open success!!", NewChannel);
+	else
+		DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!",
+			    NewChannel, openInfo->Response.OpenResult.Status);
+
+Cleanup:
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+	list_del(&openInfo->MsgListEntry);
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	kfree(openInfo->WaitEvent);
+	kfree(openInfo);
+
+	DPRINT_EXIT(VMBUS);
+
+	return 0;
+}
+
+/**
+ * DumpGpadlBody - Dump the gpadl body message to the console for debugging purposes.
+ */
+static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len)
+{
+	int i;
+	int pfnCount;
+
+	pfnCount = (Len - sizeof(struct vmbus_channel_gpadl_body)) /
+		   sizeof(u64);
+	DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", Len, pfnCount);
+
+	for (i = 0; i < pfnCount; i++)
+		DPRINT_DBG(VMBUS, "gpadl body  - %d) pfn %llu",
+			   i, Gpadl->Pfn[i]);
+}
+
+/**
+ * DumpGpadlHeader - Dump the gpadl header message to the console for debugging purposes.
+ */
+static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl)
+{
+	int i, j;
+	int pageCount;
+
+	DPRINT_DBG(VMBUS,
+		   "gpadl header - relid %d, range count %d, range buflen %d",
+		   Gpadl->ChildRelId, Gpadl->RangeCount, Gpadl->RangeBufLen);
+	for (i = 0; i < Gpadl->RangeCount; i++) {
+		pageCount = Gpadl->Range[i].ByteCount >> PAGE_SHIFT;
+		pageCount = (pageCount > 26) ? 26 : pageCount;
+
+		DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
+			   "page count %d", i, Gpadl->Range[i].ByteCount,
+			   Gpadl->Range[i].ByteOffset, pageCount);
+
+		for (j = 0; j < pageCount; j++)
+			DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
+				   Gpadl->Range[i].PfnArray[j]);
+	}
+}
+
+/**
+ * VmbusChannelCreateGpadlHeader - Creates a gpadl for the specified buffer
+ */
+static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size,
+					 struct vmbus_channel_msginfo **MsgInfo,
+					 u32 *MessageCount)
+{
+	int i;
+	int pageCount;
+	unsigned long long pfn;
+	struct vmbus_channel_gpadl_header *gpaHeader;
+	struct vmbus_channel_gpadl_body *gpadlBody;
+	struct vmbus_channel_msginfo *msgHeader;
+	struct vmbus_channel_msginfo *msgBody;
+	u32 msgSize;
+
+	int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize;
+
+	/* ASSERT((kbuffer & (PAGE_SIZE-1)) == 0); */
+	ASSERT((Size & (PAGE_SIZE-1)) == 0);
+
+	pageCount = Size >> PAGE_SHIFT;
+	pfn = virt_to_phys(Kbuffer) >> PAGE_SHIFT;
+
+	/* do we need a gpadl body msg */
+	pfnSize = MAX_SIZE_CHANNEL_MESSAGE -
+		  sizeof(struct vmbus_channel_gpadl_header) -
+		  sizeof(struct gpa_range);
+	pfnCount = pfnSize / sizeof(u64);
+
+	if (pageCount > pfnCount) {
+		/* we need a gpadl body */
+		/* fill in the header */
+		msgSize = sizeof(struct vmbus_channel_msginfo) +
+			  sizeof(struct vmbus_channel_gpadl_header) +
+			  sizeof(struct gpa_range) + pfnCount * sizeof(u64);
+		msgHeader =  kzalloc(msgSize, GFP_KERNEL);
+
+		INIT_LIST_HEAD(&msgHeader->SubMsgList);
+		msgHeader->MessageSize = msgSize;
+
+		gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg;
+		gpaHeader->RangeCount = 1;
+		gpaHeader->RangeBufLen = sizeof(struct gpa_range) +
+					 pageCount * sizeof(u64);
+		gpaHeader->Range[0].ByteOffset = 0;
+		gpaHeader->Range[0].ByteCount = Size;
+		for (i = 0; i < pfnCount; i++)
+			gpaHeader->Range[0].PfnArray[i] = pfn+i;
+		*MsgInfo = msgHeader;
+		*MessageCount = 1;
+
+		pfnSum = pfnCount;
+		pfnLeft = pageCount - pfnCount;
+
+		/* how many pfns can we fit */
+		pfnSize = MAX_SIZE_CHANNEL_MESSAGE -
+			  sizeof(struct vmbus_channel_gpadl_body);
+		pfnCount = pfnSize / sizeof(u64);
+
+		/* fill in the body */
+		while (pfnLeft) {
+			if (pfnLeft > pfnCount)
+				pfnCurr = pfnCount;
+			else
+				pfnCurr = pfnLeft;
+
+			msgSize = sizeof(struct vmbus_channel_msginfo) +
+				  sizeof(struct vmbus_channel_gpadl_body) +
+				  pfnCurr * sizeof(u64);
+			msgBody = kzalloc(msgSize, GFP_KERNEL);
+			ASSERT(msgBody);
+			msgBody->MessageSize = msgSize;
+			(*MessageCount)++;
+			gpadlBody =
+				(struct vmbus_channel_gpadl_body *)msgBody->Msg;
+
+			/*
+			 * FIXME:
+			 * Gpadl is u32 and we are using a pointer which could
+			 * be 64-bit
+			 */
+			/* gpadlBody->Gpadl = kbuffer; */
+			for (i = 0; i < pfnCurr; i++)
+				gpadlBody->Pfn[i] = pfn + pfnSum + i;
+
+			/* add to msg header */
+			list_add_tail(&msgBody->MsgListEntry,
+				      &msgHeader->SubMsgList);
+			pfnSum += pfnCurr;
+			pfnLeft -= pfnCurr;
+		}
+	} else {
+		/* everything fits in a header */
+		msgSize = sizeof(struct vmbus_channel_msginfo) +
+			  sizeof(struct vmbus_channel_gpadl_header) +
+			  sizeof(struct gpa_range) + pageCount * sizeof(u64);
+		msgHeader = kzalloc(msgSize, GFP_KERNEL);
+		msgHeader->MessageSize = msgSize;
+
+		gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg;
+		gpaHeader->RangeCount = 1;
+		gpaHeader->RangeBufLen = sizeof(struct gpa_range) +
+					 pageCount * sizeof(u64);
+		gpaHeader->Range[0].ByteOffset = 0;
+		gpaHeader->Range[0].ByteCount = Size;
+		for (i = 0; i < pageCount; i++)
+			gpaHeader->Range[0].PfnArray[i] = pfn+i;
+
+		*MsgInfo = msgHeader;
+		*MessageCount = 1;
+	}
+
+	return 0;
+}
+
+/**
+ * VmbusChannelEstablishGpadl - Estabish a GPADL for the specified buffer
+ *
+ * @Channel: a channel
+ * @Kbuffer: from kmalloc
+ * @Size: page-size multiple
+ * @GpadlHandle: some funky thing
+ */
+int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer,
+			       u32 Size, u32 *GpadlHandle)
+{
+	struct vmbus_channel_gpadl_header *gpadlMsg;
+	struct vmbus_channel_gpadl_body *gpadlBody;
+	/* struct vmbus_channel_gpadl_created *gpadlCreated; */
+	struct vmbus_channel_msginfo *msgInfo;
+	struct vmbus_channel_msginfo *subMsgInfo;
+	u32 msgCount;
+	struct list_head *curr;
+	u32 nextGpadlHandle;
+	unsigned long flags;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+
+	nextGpadlHandle = atomic_read(&gVmbusConnection.NextGpadlHandle);
+	atomic_inc(&gVmbusConnection.NextGpadlHandle);
+
+	VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount);
+	ASSERT(msgInfo != NULL);
+	ASSERT(msgCount > 0);
+
+	msgInfo->WaitEvent = osd_WaitEventCreate();
+	gpadlMsg = (struct vmbus_channel_gpadl_header *)msgInfo->Msg;
+	gpadlMsg->Header.MessageType = ChannelMessageGpadlHeader;
+	gpadlMsg->ChildRelId = Channel->OfferMsg.ChildRelId;
+	gpadlMsg->Gpadl = nextGpadlHandle;
+
+	DumpGpadlHeader(gpadlMsg);
+
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+	list_add_tail(&msgInfo->MsgListEntry,
+		      &gVmbusConnection.ChannelMsgList);
+
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+	DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d",
+		   Kbuffer, Size, msgCount);
+
+	DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd",
+		   msgInfo->MessageSize - sizeof(*msgInfo));
+
+	ret = VmbusPostMessage(gpadlMsg, msgInfo->MessageSize -
+			       sizeof(*msgInfo));
+	if (ret != 0) {
+		DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret);
+		goto Cleanup;
+	}
+
+	if (msgCount > 1) {
+		list_for_each(curr, &msgInfo->SubMsgList) {
+
+			/* FIXME: should this use list_entry() instead ? */
+			subMsgInfo = (struct vmbus_channel_msginfo *)curr;
+			gpadlBody =
+			     (struct vmbus_channel_gpadl_body *)subMsgInfo->Msg;
+
+			gpadlBody->Header.MessageType = ChannelMessageGpadlBody;
+			gpadlBody->Gpadl = nextGpadlHandle;
+
+			DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd",
+				   subMsgInfo->MessageSize -
+				   sizeof(*subMsgInfo));
+
+			DumpGpadlBody(gpadlBody, subMsgInfo->MessageSize -
+				      sizeof(*subMsgInfo));
+			ret = VmbusPostMessage(gpadlBody,
+					       subMsgInfo->MessageSize -
+					       sizeof(*subMsgInfo));
+			ASSERT(ret == 0);
+		}
+	}
+	osd_WaitEventWait(msgInfo->WaitEvent);
+
+	/* At this point, we received the gpadl created msg */
+	DPRINT_DBG(VMBUS, "Received GPADL created "
+		   "(relid %d, status %d handle %x)",
+		   Channel->OfferMsg.ChildRelId,
+		   msgInfo->Response.GpadlCreated.CreationStatus,
+		   gpadlMsg->Gpadl);
+
+	*GpadlHandle = gpadlMsg->Gpadl;
+
+Cleanup:
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+	list_del(&msgInfo->MsgListEntry);
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	kfree(msgInfo->WaitEvent);
+	kfree(msgInfo);
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusChannelTeardownGpadl -Teardown the specified GPADL handle
+ */
+int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle)
+{
+	struct vmbus_channel_gpadl_teardown *msg;
+	struct vmbus_channel_msginfo *info;
+	unsigned long flags;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+
+	ASSERT(GpadlHandle != 0);
+
+	info = kmalloc(sizeof(*info) +
+		       sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
+	ASSERT(info != NULL);
+
+	info->WaitEvent = osd_WaitEventCreate();
+
+	msg = (struct vmbus_channel_gpadl_teardown *)info->Msg;
+
+	msg->Header.MessageType = ChannelMessageGpadlTeardown;
+	msg->ChildRelId = Channel->OfferMsg.ChildRelId;
+	msg->Gpadl = GpadlHandle;
+
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+	list_add_tail(&info->MsgListEntry,
+		      &gVmbusConnection.ChannelMsgList);
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	ret = VmbusPostMessage(msg,
+			       sizeof(struct vmbus_channel_gpadl_teardown));
+	if (ret != 0) {
+		/* TODO: */
+		/* something... */
+	}
+
+	osd_WaitEventWait(info->WaitEvent);
+
+	/* Received a torndown response */
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+	list_del(&info->MsgListEntry);
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	kfree(info->WaitEvent);
+	kfree(info);
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusChannelClose - Close the specified channel
+ */
+void VmbusChannelClose(struct vmbus_channel *Channel)
+{
+	struct vmbus_channel_close_channel *msg;
+	struct vmbus_channel_msginfo *info;
+	unsigned long flags;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Stop callback and cancel the timer asap */
+	Channel->OnChannelCallback = NULL;
+	del_timer(&Channel->poll_timer);
+
+	/* Send a closing message */
+	info = kmalloc(sizeof(*info) +
+		       sizeof(struct vmbus_channel_close_channel), GFP_KERNEL);
+	ASSERT(info != NULL);
+
+	/* info->waitEvent = osd_WaitEventCreate(); */
+
+	msg = (struct vmbus_channel_close_channel *)info->Msg;
+	msg->Header.MessageType = ChannelMessageCloseChannel;
+	msg->ChildRelId = Channel->OfferMsg.ChildRelId;
+
+	ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_close_channel));
+	if (ret != 0) {
+		/* TODO: */
+		/* something... */
+	}
+
+	/* Tear down the gpadl for the channel's ring buffer */
+	if (Channel->RingBufferGpadlHandle)
+		VmbusChannelTeardownGpadl(Channel,
+					  Channel->RingBufferGpadlHandle);
+
+	/* TODO: Send a msg to release the childRelId */
+
+	/* Cleanup the ring buffers for this channel */
+	RingBufferCleanup(&Channel->Outbound);
+	RingBufferCleanup(&Channel->Inbound);
+
+	osd_PageFree(Channel->RingBufferPages, Channel->RingBufferPageCount);
+
+	kfree(info);
+
+	/*
+	 * If we are closing the channel during an error path in
+	 * opening the channel, don't free the channel since the
+	 * caller will free the channel
+	 */
+
+	if (Channel->State == CHANNEL_OPEN_STATE) {
+		spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
+		list_del(&Channel->ListEntry);
+		spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
+
+		FreeVmbusChannel(Channel);
+	}
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelSendPacket - Send the specified buffer on the given channel
+ */
+int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer,
+			   u32 BufferLen, u64 RequestId,
+			   enum vmbus_packet_type Type, u32 Flags)
+{
+	struct vmpacket_descriptor desc;
+	u32 packetLen = sizeof(struct vmpacket_descriptor) + BufferLen;
+	u32 packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
+	struct scatterlist bufferList[3];
+	u64 alignedData = 0;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+	DPRINT_DBG(VMBUS, "channel %p buffer %p len %d",
+		   Channel, Buffer, BufferLen);
+
+	DumpVmbusChannel(Channel);
+
+	ASSERT((packetLenAligned - packetLen) < sizeof(u64));
+
+	/* Setup the descriptor */
+	desc.Type = Type; /* VmbusPacketTypeDataInBand; */
+	desc.Flags = Flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
+	/* in 8-bytes granularity */
+	desc.DataOffset8 = sizeof(struct vmpacket_descriptor) >> 3;
+	desc.Length8 = (u16)(packetLenAligned >> 3);
+	desc.TransactionId = RequestId;
+
+	sg_init_table(bufferList, 3);
+	sg_set_buf(&bufferList[0], &desc, sizeof(struct vmpacket_descriptor));
+	sg_set_buf(&bufferList[1], Buffer, BufferLen);
+	sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen);
+
+	ret = RingBufferWrite(&Channel->Outbound, bufferList, 3);
+
+	/* TODO: We should determine if this is optional */
+	if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
+		VmbusChannelSetEvent(Channel);
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer packets using a GPADL Direct packet type.
+ */
+int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel,
+				     struct hv_page_buffer PageBuffers[],
+				     u32 PageCount, void *Buffer, u32 BufferLen,
+				     u64 RequestId)
+{
+	int ret;
+	int i;
+	struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER desc;
+	u32 descSize;
+	u32 packetLen;
+	u32 packetLenAligned;
+	struct scatterlist bufferList[3];
+	u64 alignedData = 0;
+
+	DPRINT_ENTER(VMBUS);
+
+	ASSERT(PageCount <= MAX_PAGE_BUFFER_COUNT);
+
+	DumpVmbusChannel(Channel);
+
+	/*
+	 * Adjust the size down since VMBUS_CHANNEL_PACKET_PAGE_BUFFER is the
+	 * largest size we support
+	 */
+	descSize = sizeof(struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER) -
+			  ((MAX_PAGE_BUFFER_COUNT - PageCount) *
+			  sizeof(struct hv_page_buffer));
+	packetLen = descSize + BufferLen;
+	packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
+
+	ASSERT((packetLenAligned - packetLen) < sizeof(u64));
+
+	/* Setup the descriptor */
+	desc.Type = VmbusPacketTypeDataUsingGpaDirect;
+	desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
+	desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
+	desc.Length8 = (u16)(packetLenAligned >> 3);
+	desc.TransactionId = RequestId;
+	desc.RangeCount = PageCount;
+
+	for (i = 0; i < PageCount; i++) {
+		desc.Range[i].Length = PageBuffers[i].Length;
+		desc.Range[i].Offset = PageBuffers[i].Offset;
+		desc.Range[i].Pfn	 = PageBuffers[i].Pfn;
+	}
+
+	sg_init_table(bufferList, 3);
+	sg_set_buf(&bufferList[0], &desc, descSize);
+	sg_set_buf(&bufferList[1], Buffer, BufferLen);
+	sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen);
+
+	ret = RingBufferWrite(&Channel->Outbound, bufferList, 3);
+
+	/* TODO: We should determine if this is optional */
+	if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
+		VmbusChannelSetEvent(Channel);
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet using a GPADL Direct packet type.
+ */
+int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel,
+				struct hv_multipage_buffer *MultiPageBuffer,
+				void *Buffer, u32 BufferLen, u64 RequestId)
+{
+	int ret;
+	struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER desc;
+	u32 descSize;
+	u32 packetLen;
+	u32 packetLenAligned;
+	struct scatterlist bufferList[3];
+	u64 alignedData = 0;
+	u32 PfnCount = NUM_PAGES_SPANNED(MultiPageBuffer->Offset,
+					 MultiPageBuffer->Length);
+
+	DPRINT_ENTER(VMBUS);
+
+	DumpVmbusChannel(Channel);
+
+	DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u",
+		   MultiPageBuffer->Offset, MultiPageBuffer->Length, PfnCount);
+
+	ASSERT(PfnCount > 0);
+	ASSERT(PfnCount <= MAX_MULTIPAGE_BUFFER_COUNT);
+
+	/*
+	 * Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is
+	 * the largest size we support
+	 */
+	descSize = sizeof(struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER) -
+			  ((MAX_MULTIPAGE_BUFFER_COUNT - PfnCount) *
+			  sizeof(u64));
+	packetLen = descSize + BufferLen;
+	packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
+
+	ASSERT((packetLenAligned - packetLen) < sizeof(u64));
+
+	/* Setup the descriptor */
+	desc.Type = VmbusPacketTypeDataUsingGpaDirect;
+	desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
+	desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
+	desc.Length8 = (u16)(packetLenAligned >> 3);
+	desc.TransactionId = RequestId;
+	desc.RangeCount = 1;
+
+	desc.Range.Length = MultiPageBuffer->Length;
+	desc.Range.Offset = MultiPageBuffer->Offset;
+
+	memcpy(desc.Range.PfnArray, MultiPageBuffer->PfnArray,
+	       PfnCount * sizeof(u64));
+
+	sg_init_table(bufferList, 3);
+	sg_set_buf(&bufferList[0], &desc, descSize);
+	sg_set_buf(&bufferList[1], Buffer, BufferLen);
+	sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen);
+
+	ret = RingBufferWrite(&Channel->Outbound, bufferList, 3);
+
+	/* TODO: We should determine if this is optional */
+	if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
+		VmbusChannelSetEvent(Channel);
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusChannelRecvPacket - Retrieve the user packet on the specified channel
+ */
+/* TODO: Do we ever receive a gpa direct packet other than the ones we send ? */
+int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer,
+			   u32 BufferLen, u32 *BufferActualLen, u64 *RequestId)
+{
+	struct vmpacket_descriptor desc;
+	u32 packetLen;
+	u32 userLen;
+	int ret;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	*BufferActualLen = 0;
+	*RequestId = 0;
+
+	spin_lock_irqsave(&Channel->inbound_lock, flags);
+
+	ret = RingBufferPeek(&Channel->Inbound, &desc,
+			     sizeof(struct vmpacket_descriptor));
+	if (ret != 0) {
+		spin_unlock_irqrestore(&Channel->inbound_lock, flags);
+
+		/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
+		DPRINT_EXIT(VMBUS);
+		return 0;
+	}
+
+	/* VmbusChannelClearEvent(Channel); */
+
+	packetLen = desc.Length8 << 3;
+	userLen = packetLen - (desc.DataOffset8 << 3);
+	/* ASSERT(userLen > 0); */
+
+	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
+		   "flag %d tid %llx pktlen %d datalen %d> ",
+		   Channel, Channel->OfferMsg.ChildRelId, desc.Type,
+		   desc.Flags, desc.TransactionId, packetLen, userLen);
+
+	*BufferActualLen = userLen;
+
+	if (userLen > BufferLen) {
+		spin_unlock_irqrestore(&Channel->inbound_lock, flags);
+
+		DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d",
+			   BufferLen, userLen);
+		DPRINT_EXIT(VMBUS);
+
+		return -1;
+	}
+
+	*RequestId = desc.TransactionId;
+
+	/* Copy over the packet to the user buffer */
+	ret = RingBufferRead(&Channel->Inbound, Buffer, userLen,
+			     (desc.DataOffset8 << 3));
+
+	spin_unlock_irqrestore(&Channel->inbound_lock, flags);
+
+	DPRINT_EXIT(VMBUS);
+
+	return 0;
+}
+
+/**
+ * VmbusChannelRecvPacketRaw - Retrieve the raw packet on the specified channel
+ */
+int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer,
+			      u32 BufferLen, u32 *BufferActualLen,
+			      u64 *RequestId)
+{
+	struct vmpacket_descriptor desc;
+	u32 packetLen;
+	u32 userLen;
+	int ret;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	*BufferActualLen = 0;
+	*RequestId = 0;
+
+	spin_lock_irqsave(&Channel->inbound_lock, flags);
+
+	ret = RingBufferPeek(&Channel->Inbound, &desc,
+			     sizeof(struct vmpacket_descriptor));
+	if (ret != 0) {
+		spin_unlock_irqrestore(&Channel->inbound_lock, flags);
+
+		/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
+		DPRINT_EXIT(VMBUS);
+		return 0;
+	}
+
+	/* VmbusChannelClearEvent(Channel); */
+
+	packetLen = desc.Length8 << 3;
+	userLen = packetLen - (desc.DataOffset8 << 3);
+
+	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
+		   "flag %d tid %llx pktlen %d datalen %d> ",
+		   Channel, Channel->OfferMsg.ChildRelId, desc.Type,
+		   desc.Flags, desc.TransactionId, packetLen, userLen);
+
+	*BufferActualLen = packetLen;
+
+	if (packetLen > BufferLen) {
+		spin_unlock_irqrestore(&Channel->inbound_lock, flags);
+
+		DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but "
+			   "got space for only %d bytes", packetLen, BufferLen);
+		DPRINT_EXIT(VMBUS);
+		return -2;
+	}
+
+	*RequestId = desc.TransactionId;
+
+	/* Copy over the entire packet to the user buffer */
+	ret = RingBufferRead(&Channel->Inbound, Buffer, packetLen, 0);
+
+	spin_unlock_irqrestore(&Channel->inbound_lock, flags);
+
+	DPRINT_EXIT(VMBUS);
+
+	return 0;
+}
+
+/**
+ * VmbusChannelOnChannelEvent - Channel event callback
+ */
+void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel)
+{
+	DumpVmbusChannel(Channel);
+	ASSERT(Channel->OnChannelCallback);
+#ifdef ENABLE_POLLING
+	del_timer(&Channel->poll_timer);
+	Channel->OnChannelCallback(Channel->ChannelCallbackContext);
+	channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
+	add_timer(&channel->poll_timer);
+#else
+	Channel->OnChannelCallback(Channel->ChannelCallbackContext);
+#endif
+}
+
+/**
+ * VmbusChannelOnTimer - Timer event callback
+ */
+void VmbusChannelOnTimer(unsigned long data)
+{
+	struct vmbus_channel *channel = (struct vmbus_channel *)data;
+
+	if (channel->OnChannelCallback) {
+		channel->OnChannelCallback(channel->ChannelCallbackContext);
+#ifdef ENABLE_POLLING
+		channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
+		add_timer(&channel->poll_timer);
+#endif
+	}
+}
+
+/**
+ * DumpVmbusChannel - Dump vmbus channel info to the console
+ */
+static void DumpVmbusChannel(struct vmbus_channel *Channel)
+{
+	DPRINT_DBG(VMBUS, "Channel (%d)", Channel->OfferMsg.ChildRelId);
+	DumpRingInfo(&Channel->Outbound, "Outbound ");
+	DumpRingInfo(&Channel->Inbound, "Inbound ");
+}
diff --git a/drivers/staging/hv/Channel.h b/drivers/staging/hv/Channel.h
new file mode 100644
index 0000000..6b283ed
--- /dev/null
+++ b/drivers/staging/hv/Channel.h
@@ -0,0 +1,112 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#include "ChannelMgmt.h"
+
+/* The format must be the same as struct vmdata_gpa_direct */
+struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER {
+	u16 Type;
+	u16 DataOffset8;
+	u16 Length8;
+	u16 Flags;
+	u64 TransactionId;
+	u32 Reserved;
+	u32 RangeCount;
+	struct hv_page_buffer Range[MAX_PAGE_BUFFER_COUNT];
+} __attribute__((packed));
+
+/* The format must be the same as struct vmdata_gpa_direct */
+struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER {
+	u16 Type;
+	u16 DataOffset8;
+	u16 Length8;
+	u16 Flags;
+	u64 TransactionId;
+	u32 Reserved;
+	u32 RangeCount;		/* Always 1 in this case */
+	struct hv_multipage_buffer Range;
+} __attribute__((packed));
+
+
+extern int VmbusChannelOpen(struct vmbus_channel *channel,
+			    u32 SendRingBufferSize,
+			    u32 RecvRingBufferSize,
+			    void *UserData,
+			    u32 UserDataLen,
+			    void(*OnChannelCallback)(void *context),
+			    void *Context);
+
+extern void VmbusChannelClose(struct vmbus_channel *channel);
+
+extern int VmbusChannelSendPacket(struct vmbus_channel *channel,
+				  const void *Buffer,
+				  u32 BufferLen,
+				  u64 RequestId,
+				  enum vmbus_packet_type Type,
+				  u32 Flags);
+
+extern int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *channel,
+					    struct hv_page_buffer PageBuffers[],
+					    u32 PageCount,
+					    void *Buffer,
+					    u32 BufferLen,
+					    u64 RequestId);
+
+extern int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *channel,
+					struct hv_multipage_buffer *mpb,
+					void *Buffer,
+					u32 BufferLen,
+					u64 RequestId);
+
+extern int VmbusChannelEstablishGpadl(struct vmbus_channel *channel,
+				      void *Kbuffer,
+				      u32 Size,
+				      u32 *GpadlHandle);
+
+extern int VmbusChannelTeardownGpadl(struct vmbus_channel *channel,
+				     u32 GpadlHandle);
+
+extern int VmbusChannelRecvPacket(struct vmbus_channel *channel,
+				  void *Buffer,
+				  u32 BufferLen,
+				  u32 *BufferActualLen,
+				  u64 *RequestId);
+
+extern int VmbusChannelRecvPacketRaw(struct vmbus_channel *channel,
+				     void *Buffer,
+				     u32 BufferLen,
+				     u32 *BufferActualLen,
+				     u64 *RequestId);
+
+extern void VmbusChannelOnChannelEvent(struct vmbus_channel *channel);
+
+extern void VmbusChannelGetDebugInfo(struct vmbus_channel *channel,
+				     struct vmbus_channel_debug_info *debug);
+
+extern void VmbusChannelOnTimer(unsigned long data);
+
+#endif /* _CHANNEL_H_ */
diff --git a/drivers/staging/hv/ChannelInterface.c b/drivers/staging/hv/ChannelInterface.c
new file mode 100644
index 0000000..019b064
--- /dev/null
+++ b/drivers/staging/hv/ChannelInterface.c
@@ -0,0 +1,152 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include "osd.h"
+#include "VmbusPrivate.h"
+
+static int IVmbusChannelOpen(struct hv_device *device, u32 SendBufferSize,
+			     u32 RecvRingBufferSize, void *UserData,
+			     u32 UserDataLen,
+			     void (*ChannelCallback)(void *context),
+			     void *Context)
+{
+	return VmbusChannelOpen(device->context, SendBufferSize,
+				RecvRingBufferSize, UserData, UserDataLen,
+				ChannelCallback, Context);
+}
+
+static void IVmbusChannelClose(struct hv_device *device)
+{
+	VmbusChannelClose(device->context);
+}
+
+static int IVmbusChannelSendPacket(struct hv_device *device, const void *Buffer,
+				   u32 BufferLen, u64 RequestId, u32 Type,
+				   u32 Flags)
+{
+	return VmbusChannelSendPacket(device->context, Buffer, BufferLen,
+				      RequestId, Type, Flags);
+}
+
+static int IVmbusChannelSendPacketPageBuffer(struct hv_device *device,
+				struct hv_page_buffer PageBuffers[],
+				u32 PageCount, void *Buffer,
+				u32 BufferLen, u64 RequestId)
+{
+	return VmbusChannelSendPacketPageBuffer(device->context, PageBuffers,
+						PageCount, Buffer, BufferLen,
+						RequestId);
+}
+
+static int IVmbusChannelSendPacketMultiPageBuffer(struct hv_device *device,
+				struct hv_multipage_buffer *MultiPageBuffer,
+				void *Buffer, u32 BufferLen, u64 RequestId)
+{
+	return VmbusChannelSendPacketMultiPageBuffer(device->context,
+						     MultiPageBuffer, Buffer,
+						     BufferLen, RequestId);
+}
+
+static int IVmbusChannelRecvPacket(struct hv_device *device, void *Buffer,
+				   u32 BufferLen, u32 *BufferActualLen,
+				   u64 *RequestId)
+{
+	return VmbusChannelRecvPacket(device->context, Buffer, BufferLen,
+				      BufferActualLen, RequestId);
+}
+
+static int IVmbusChannelRecvPacketRaw(struct hv_device *device, void *Buffer,
+				      u32 BufferLen, u32 *BufferActualLen,
+				      u64 *RequestId)
+{
+	return VmbusChannelRecvPacketRaw(device->context, Buffer, BufferLen,
+					 BufferActualLen, RequestId);
+}
+
+static int IVmbusChannelEstablishGpadl(struct hv_device *device, void *Buffer,
+				       u32 BufferLen, u32 *GpadlHandle)
+{
+	return VmbusChannelEstablishGpadl(device->context, Buffer, BufferLen,
+					  GpadlHandle);
+}
+
+static int IVmbusChannelTeardownGpadl(struct hv_device *device, u32 GpadlHandle)
+{
+	return VmbusChannelTeardownGpadl(device->context, GpadlHandle);
+
+}
+
+void GetChannelInterface(struct vmbus_channel_interface *iface)
+{
+	iface->Open = IVmbusChannelOpen;
+	iface->Close	= IVmbusChannelClose;
+	iface->SendPacket = IVmbusChannelSendPacket;
+	iface->SendPacketPageBuffer = IVmbusChannelSendPacketPageBuffer;
+	iface->SendPacketMultiPageBuffer =
+					IVmbusChannelSendPacketMultiPageBuffer;
+	iface->RecvPacket = IVmbusChannelRecvPacket;
+	iface->RecvPacketRaw	= IVmbusChannelRecvPacketRaw;
+	iface->EstablishGpadl = IVmbusChannelEstablishGpadl;
+	iface->TeardownGpadl = IVmbusChannelTeardownGpadl;
+	iface->GetInfo = GetChannelInfo;
+}
+
+void GetChannelInfo(struct hv_device *device, struct hv_device_info *info)
+{
+	struct vmbus_channel_debug_info debugInfo;
+
+	if (!device->context)
+		return;
+
+	VmbusChannelGetDebugInfo(device->context, &debugInfo);
+
+	info->ChannelId = debugInfo.RelId;
+	info->ChannelState = debugInfo.State;
+	memcpy(&info->ChannelType, &debugInfo.InterfaceType,
+	       sizeof(struct hv_guid));
+	memcpy(&info->ChannelInstance, &debugInfo.InterfaceInstance,
+	       sizeof(struct hv_guid));
+
+	info->MonitorId = debugInfo.MonitorId;
+
+	info->ServerMonitorPending = debugInfo.ServerMonitorPending;
+	info->ServerMonitorLatency = debugInfo.ServerMonitorLatency;
+	info->ServerMonitorConnectionId = debugInfo.ServerMonitorConnectionId;
+
+	info->ClientMonitorPending = debugInfo.ClientMonitorPending;
+	info->ClientMonitorLatency = debugInfo.ClientMonitorLatency;
+	info->ClientMonitorConnectionId = debugInfo.ClientMonitorConnectionId;
+
+	info->Inbound.InterruptMask = debugInfo.Inbound.CurrentInterruptMask;
+	info->Inbound.ReadIndex = debugInfo.Inbound.CurrentReadIndex;
+	info->Inbound.WriteIndex = debugInfo.Inbound.CurrentWriteIndex;
+	info->Inbound.BytesAvailToRead = debugInfo.Inbound.BytesAvailToRead;
+	info->Inbound.BytesAvailToWrite = debugInfo.Inbound.BytesAvailToWrite;
+
+	info->Outbound.InterruptMask = debugInfo.Outbound.CurrentInterruptMask;
+	info->Outbound.ReadIndex = debugInfo.Outbound.CurrentReadIndex;
+	info->Outbound.WriteIndex = debugInfo.Outbound.CurrentWriteIndex;
+	info->Outbound.BytesAvailToRead = debugInfo.Outbound.BytesAvailToRead;
+	info->Outbound.BytesAvailToWrite = debugInfo.Outbound.BytesAvailToWrite;
+}
diff --git a/drivers/staging/hv/ChannelInterface.h b/drivers/staging/hv/ChannelInterface.h
new file mode 100644
index 0000000..27b7a25
--- /dev/null
+++ b/drivers/staging/hv/ChannelInterface.h
@@ -0,0 +1,35 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _CHANNEL_INTERFACE_H_
+#define _CHANNEL_INTERFACE_H_
+
+#include "VmbusApi.h"
+
+void GetChannelInterface(struct vmbus_channel_interface *ChannelInterface);
+
+void GetChannelInfo(struct hv_device *Device,
+		    struct hv_device_info *DeviceInfo);
+
+#endif /* _CHANNEL_INTERFACE_H_ */
diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/ChannelMgmt.c
new file mode 100644
index 0000000..3db62ca
--- /dev/null
+++ b/drivers/staging/hv/ChannelMgmt.c
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include "osd.h"
+#include "logging.h"
+#include "VmbusPrivate.h"
+
+struct vmbus_channel_message_table_entry {
+	enum vmbus_channel_message_type messageType;
+	void (*messageHandler)(struct vmbus_channel_message_header *msg);
+};
+
+#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 4
+static const struct hv_guid
+		gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
+	/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
+	/* Storage - SCSI */
+	{
+		.data  = {
+			0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
+			0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
+		}
+	},
+
+	/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
+	/* Network */
+	{
+		.data = {
+			0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
+			0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
+		}
+	},
+
+	/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
+	/* Input */
+	{
+		.data = {
+			0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
+			0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
+		}
+	},
+
+	/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
+	/* IDE */
+	{
+		.data = {
+			0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
+			0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
+		}
+	},
+};
+
+/**
+ * AllocVmbusChannel - Allocate and initialize a vmbus channel object
+ */
+struct vmbus_channel *AllocVmbusChannel(void)
+{
+	struct vmbus_channel *channel;
+
+	channel = kzalloc(sizeof(*channel), GFP_ATOMIC);
+	if (!channel)
+		return NULL;
+
+	spin_lock_init(&channel->inbound_lock);
+
+	init_timer(&channel->poll_timer);
+	channel->poll_timer.data = (unsigned long)channel;
+	channel->poll_timer.function = VmbusChannelOnTimer;
+
+	channel->ControlWQ = create_workqueue("hv_vmbus_ctl");
+	if (!channel->ControlWQ) {
+		kfree(channel);
+		return NULL;
+	}
+
+	return channel;
+}
+
+/**
+ * ReleaseVmbusChannel - Release the vmbus channel object itself
+ */
+static inline void ReleaseVmbusChannel(void *context)
+{
+	struct vmbus_channel *channel = context;
+
+	DPRINT_ENTER(VMBUS);
+
+	DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
+	destroy_workqueue(channel->ControlWQ);
+	DPRINT_DBG(VMBUS, "channel released (%p)", channel);
+
+	kfree(channel);
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * FreeVmbusChannel - Release the resources used by the vmbus channel object
+ */
+void FreeVmbusChannel(struct vmbus_channel *Channel)
+{
+	del_timer(&Channel->poll_timer);
+
+	/*
+	 * We have to release the channel's workqueue/thread in the vmbus's
+	 * workqueue/thread context
+	 * ie we can't destroy ourselves.
+	 */
+	osd_schedule_callback(gVmbusConnection.WorkQueue, ReleaseVmbusChannel,
+			      Channel);
+}
+
+/**
+ * VmbusChannelProcessOffer - Process the offer by creating a channel/device associated with this offer
+ */
+static void VmbusChannelProcessOffer(void *context)
+{
+	struct vmbus_channel *newChannel = context;
+	struct vmbus_channel *channel;
+	bool fNew = true;
+	int ret;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Make sure this is a new offer */
+	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
+
+	list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) {
+		if (!memcmp(&channel->OfferMsg.Offer.InterfaceType,
+			    &newChannel->OfferMsg.Offer.InterfaceType,
+			    sizeof(struct hv_guid)) &&
+		    !memcmp(&channel->OfferMsg.Offer.InterfaceInstance,
+			    &newChannel->OfferMsg.Offer.InterfaceInstance,
+			    sizeof(struct hv_guid))) {
+			fNew = false;
+			break;
+		}
+	}
+
+	if (fNew)
+		list_add_tail(&newChannel->ListEntry,
+			      &gVmbusConnection.ChannelList);
+
+	spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
+
+	if (!fNew) {
+		DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)",
+			   newChannel->OfferMsg.ChildRelId);
+		FreeVmbusChannel(newChannel);
+		DPRINT_EXIT(VMBUS);
+		return;
+	}
+
+	/*
+	 * Start the process of binding this offer to the driver
+	 * We need to set the DeviceObject field before calling
+	 * VmbusChildDeviceAdd()
+	 */
+	newChannel->DeviceObject = VmbusChildDeviceCreate(
+		&newChannel->OfferMsg.Offer.InterfaceType,
+		&newChannel->OfferMsg.Offer.InterfaceInstance,
+		newChannel);
+
+	DPRINT_DBG(VMBUS, "child device object allocated - %p",
+		   newChannel->DeviceObject);
+
+	/*
+	 * Add the new device to the bus. This will kick off device-driver
+	 * binding which eventually invokes the device driver's AddDevice()
+	 * method.
+	 */
+	ret = VmbusChildDeviceAdd(newChannel->DeviceObject);
+	if (ret != 0) {
+		DPRINT_ERR(VMBUS,
+			   "unable to add child device object (relid %d)",
+			   newChannel->OfferMsg.ChildRelId);
+
+		spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
+		list_del(&newChannel->ListEntry);
+		spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
+
+		FreeVmbusChannel(newChannel);
+	} else {
+		/*
+		 * This state is used to indicate a successful open
+		 * so that when we do close the channel normally, we
+		 * can cleanup properly
+		 */
+		newChannel->State = CHANNEL_OPEN_STATE;
+	}
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelProcessRescindOffer - Rescind the offer by initiating a device removal
+ */
+static void VmbusChannelProcessRescindOffer(void *context)
+{
+	struct vmbus_channel *channel = context;
+
+	DPRINT_ENTER(VMBUS);
+	VmbusChildDeviceRemove(channel->DeviceObject);
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelOnOffer - Handler for channel offers from vmbus in parent partition.
+ *
+ * We ignore all offers except network and storage offers. For each network and
+ * storage offers, we create a channel object and queue a work item to the
+ * channel object to process the offer synchronously
+ */
+static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
+{
+	struct vmbus_channel_offer_channel *offer;
+	struct vmbus_channel *newChannel;
+	struct hv_guid *guidType;
+	struct hv_guid *guidInstance;
+	int i;
+	int fSupported = 0;
+
+	DPRINT_ENTER(VMBUS);
+
+	offer = (struct vmbus_channel_offer_channel *)hdr;
+	for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
+		if (memcmp(&offer->Offer.InterfaceType,
+		    &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) {
+			fSupported = 1;
+			break;
+		}
+	}
+
+	if (!fSupported) {
+		DPRINT_DBG(VMBUS, "Ignoring channel offer notification for "
+			   "child relid %d", offer->ChildRelId);
+		DPRINT_EXIT(VMBUS);
+		return;
+	}
+
+	guidType = &offer->Offer.InterfaceType;
+	guidInstance = &offer->Offer.InterfaceInstance;
+
+	DPRINT_INFO(VMBUS, "Channel offer notification - "
+		    "child relid %d monitor id %d allocated %d, "
+		    "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		    "%02x%02x%02x%02x%02x%02x%02x%02x} "
+		    "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		    "%02x%02x%02x%02x%02x%02x%02x%02x}",
+		    offer->ChildRelId, offer->MonitorId,
+		    offer->MonitorAllocated,
+		    guidType->data[3], guidType->data[2],
+		    guidType->data[1], guidType->data[0],
+		    guidType->data[5], guidType->data[4],
+		    guidType->data[7], guidType->data[6],
+		    guidType->data[8], guidType->data[9],
+		    guidType->data[10], guidType->data[11],
+		    guidType->data[12], guidType->data[13],
+		    guidType->data[14], guidType->data[15],
+		    guidInstance->data[3], guidInstance->data[2],
+		    guidInstance->data[1], guidInstance->data[0],
+		    guidInstance->data[5], guidInstance->data[4],
+		    guidInstance->data[7], guidInstance->data[6],
+		    guidInstance->data[8], guidInstance->data[9],
+		    guidInstance->data[10], guidInstance->data[11],
+		    guidInstance->data[12], guidInstance->data[13],
+		    guidInstance->data[14], guidInstance->data[15]);
+
+	/* Allocate the channel object and save this offer. */
+	newChannel = AllocVmbusChannel();
+	if (!newChannel) {
+		DPRINT_ERR(VMBUS, "unable to allocate channel object");
+		return;
+	}
+
+	DPRINT_DBG(VMBUS, "channel object allocated - %p", newChannel);
+
+	memcpy(&newChannel->OfferMsg, offer,
+	       sizeof(struct vmbus_channel_offer_channel));
+	newChannel->MonitorGroup = (u8)offer->MonitorId / 32;
+	newChannel->MonitorBit = (u8)offer->MonitorId % 32;
+
+	/* TODO: Make sure the offer comes from our parent partition */
+	osd_schedule_callback(newChannel->ControlWQ, VmbusChannelProcessOffer,
+			      newChannel);
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelOnOfferRescind - Rescind offer handler.
+ *
+ * We queue a work item to process this offer synchronously
+ */
+static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
+{
+	struct vmbus_channel_rescind_offer *rescind;
+	struct vmbus_channel *channel;
+
+	DPRINT_ENTER(VMBUS);
+
+	rescind = (struct vmbus_channel_rescind_offer *)hdr;
+	channel = GetChannelFromRelId(rescind->ChildRelId);
+	if (channel == NULL) {
+		DPRINT_DBG(VMBUS, "channel not found for relId %d",
+			   rescind->ChildRelId);
+		return;
+	}
+
+	osd_schedule_callback(channel->ControlWQ,
+			      VmbusChannelProcessRescindOffer,
+			      channel);
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelOnOffersDelivered - This is invoked when all offers have been delivered.
+ *
+ * Nothing to do here.
+ */
+static void VmbusChannelOnOffersDelivered(
+			struct vmbus_channel_message_header *hdr)
+{
+	DPRINT_ENTER(VMBUS);
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelOnOpenResult - Open result handler.
+ *
+ * This is invoked when we received a response to our channel open request.
+ * Find the matching request, copy the response and signal the requesting
+ * thread.
+ */
+static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr)
+{
+	struct vmbus_channel_open_result *result;
+	struct list_head *curr;
+	struct vmbus_channel_msginfo *msgInfo;
+	struct vmbus_channel_message_header *requestHeader;
+	struct vmbus_channel_open_channel *openMsg;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	result = (struct vmbus_channel_open_result *)hdr;
+	DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status);
+
+	/*
+	 * Find the open msg, copy the result and signal/unblock the wait event
+	 */
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+
+	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
+/* FIXME: this should probably use list_entry() instead */
+		msgInfo = (struct vmbus_channel_msginfo *)curr;
+		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;
+
+		if (requestHeader->MessageType == ChannelMessageOpenChannel) {
+			openMsg = (struct vmbus_channel_open_channel *)msgInfo->Msg;
+			if (openMsg->ChildRelId == result->ChildRelId &&
+			    openMsg->OpenId == result->OpenId) {
+				memcpy(&msgInfo->Response.OpenResult,
+				       result,
+				       sizeof(struct vmbus_channel_open_result));
+				osd_WaitEventSet(msgInfo->WaitEvent);
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelOnGpadlCreated - GPADL created handler.
+ *
+ * This is invoked when we received a response to our gpadl create request.
+ * Find the matching request, copy the response and signal the requesting
+ * thread.
+ */
+static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr)
+{
+	struct vmbus_channel_gpadl_created *gpadlCreated;
+	struct list_head *curr;
+	struct vmbus_channel_msginfo *msgInfo;
+	struct vmbus_channel_message_header *requestHeader;
+	struct vmbus_channel_gpadl_header *gpadlHeader;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	gpadlCreated = (struct vmbus_channel_gpadl_created *)hdr;
+	DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d",
+		   gpadlCreated->CreationStatus);
+
+	/*
+	 * Find the establish msg, copy the result and signal/unblock the wait
+	 * event
+	 */
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+
+	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
+/* FIXME: this should probably use list_entry() instead */
+		msgInfo = (struct vmbus_channel_msginfo *)curr;
+		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;
+
+		if (requestHeader->MessageType == ChannelMessageGpadlHeader) {
+			gpadlHeader = (struct vmbus_channel_gpadl_header *)requestHeader;
+
+			if ((gpadlCreated->ChildRelId ==
+			     gpadlHeader->ChildRelId) &&
+			    (gpadlCreated->Gpadl == gpadlHeader->Gpadl)) {
+				memcpy(&msgInfo->Response.GpadlCreated,
+				       gpadlCreated,
+				       sizeof(struct vmbus_channel_gpadl_created));
+				osd_WaitEventSet(msgInfo->WaitEvent);
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelOnGpadlTorndown - GPADL torndown handler.
+ *
+ * This is invoked when we received a response to our gpadl teardown request.
+ * Find the matching request, copy the response and signal the requesting
+ * thread.
+ */
+static void VmbusChannelOnGpadlTorndown(
+			struct vmbus_channel_message_header *hdr)
+{
+	struct vmbus_channel_gpadl_torndown *gpadlTorndown;
+	struct list_head *curr;
+	struct vmbus_channel_msginfo *msgInfo;
+	struct vmbus_channel_message_header *requestHeader;
+	struct vmbus_channel_gpadl_teardown *gpadlTeardown;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	gpadlTorndown = (struct vmbus_channel_gpadl_torndown *)hdr;
+
+	/*
+	 * Find the open msg, copy the result and signal/unblock the wait event
+	 */
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+
+	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
+/* FIXME: this should probably use list_entry() instead */
+		msgInfo = (struct vmbus_channel_msginfo *)curr;
+		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;
+
+		if (requestHeader->MessageType == ChannelMessageGpadlTeardown) {
+			gpadlTeardown = (struct vmbus_channel_gpadl_teardown *)requestHeader;
+
+			if (gpadlTorndown->Gpadl == gpadlTeardown->Gpadl) {
+				memcpy(&msgInfo->Response.GpadlTorndown,
+				       gpadlTorndown,
+				       sizeof(struct vmbus_channel_gpadl_torndown));
+				osd_WaitEventSet(msgInfo->WaitEvent);
+				break;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelOnVersionResponse - Version response handler
+ *
+ * This is invoked when we received a response to our initiate contact request.
+ * Find the matching request, copy the response and signal the requesting
+ * thread.
+ */
+static void VmbusChannelOnVersionResponse(
+		struct vmbus_channel_message_header *hdr)
+{
+	struct list_head *curr;
+	struct vmbus_channel_msginfo *msgInfo;
+	struct vmbus_channel_message_header *requestHeader;
+	struct vmbus_channel_initiate_contact *initiate;
+	struct vmbus_channel_version_response *versionResponse;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	versionResponse = (struct vmbus_channel_version_response *)hdr;
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+
+	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
+/* FIXME: this should probably use list_entry() instead */
+		msgInfo = (struct vmbus_channel_msginfo *)curr;
+		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;
+
+		if (requestHeader->MessageType ==
+		    ChannelMessageInitiateContact) {
+			initiate = (struct vmbus_channel_initiate_contact *)requestHeader;
+			memcpy(&msgInfo->Response.VersionResponse,
+			      versionResponse,
+			      sizeof(struct vmbus_channel_version_response));
+			osd_WaitEventSet(msgInfo->WaitEvent);
+		}
+	}
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	DPRINT_EXIT(VMBUS);
+}
+
+/* Channel message dispatch table */
+static struct vmbus_channel_message_table_entry
+	gChannelMessageTable[ChannelMessageCount] = {
+	{ChannelMessageInvalid,			NULL},
+	{ChannelMessageOfferChannel,		VmbusChannelOnOffer},
+	{ChannelMessageRescindChannelOffer,	VmbusChannelOnOfferRescind},
+	{ChannelMessageRequestOffers,		NULL},
+	{ChannelMessageAllOffersDelivered,	VmbusChannelOnOffersDelivered},
+	{ChannelMessageOpenChannel,		NULL},
+	{ChannelMessageOpenChannelResult,	VmbusChannelOnOpenResult},
+	{ChannelMessageCloseChannel,		NULL},
+	{ChannelMessageGpadlHeader,		NULL},
+	{ChannelMessageGpadlBody,		NULL},
+	{ChannelMessageGpadlCreated,		VmbusChannelOnGpadlCreated},
+	{ChannelMessageGpadlTeardown,		NULL},
+	{ChannelMessageGpadlTorndown,		VmbusChannelOnGpadlTorndown},
+	{ChannelMessageRelIdReleased,		NULL},
+	{ChannelMessageInitiateContact,		NULL},
+	{ChannelMessageVersionResponse,		VmbusChannelOnVersionResponse},
+	{ChannelMessageUnload,			NULL},
+};
+
+/**
+ * VmbusOnChannelMessage - Handler for channel protocol messages.
+ *
+ * This is invoked in the vmbus worker thread context.
+ */
+void VmbusOnChannelMessage(void *Context)
+{
+	struct hv_message *msg = Context;
+	struct vmbus_channel_message_header *hdr;
+	int size;
+
+	DPRINT_ENTER(VMBUS);
+
+	hdr = (struct vmbus_channel_message_header *)msg->u.Payload;
+	size = msg->Header.PayloadSize;
+
+	DPRINT_DBG(VMBUS, "message type %d size %d", hdr->MessageType, size);
+
+	if (hdr->MessageType >= ChannelMessageCount) {
+		DPRINT_ERR(VMBUS,
+			   "Received invalid channel message type %d size %d",
+			   hdr->MessageType, size);
+		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
+				     (unsigned char *)msg->u.Payload, size);
+		kfree(msg);
+		return;
+	}
+
+	if (gChannelMessageTable[hdr->MessageType].messageHandler)
+		gChannelMessageTable[hdr->MessageType].messageHandler(hdr);
+	else
+		DPRINT_ERR(VMBUS, "Unhandled channel message type %d",
+			   hdr->MessageType);
+
+	/* Free the msg that was allocated in VmbusOnMsgDPC() */
+	kfree(msg);
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusChannelRequestOffers - Send a request to get all our pending offers.
+ */
+int VmbusChannelRequestOffers(void)
+{
+	struct vmbus_channel_message_header *msg;
+	struct vmbus_channel_msginfo *msgInfo;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+
+	msgInfo = kmalloc(sizeof(*msgInfo) +
+			  sizeof(struct vmbus_channel_message_header),
+			  GFP_KERNEL);
+	ASSERT(msgInfo != NULL);
+
+	msgInfo->WaitEvent = osd_WaitEventCreate();
+	msg = (struct vmbus_channel_message_header *)msgInfo->Msg;
+
+	msg->MessageType = ChannelMessageRequestOffers;
+
+	/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
+	INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList,
+			 &msgInfo->msgListEntry);
+	SpinlockRelease(gVmbusConnection.channelMsgLock);*/
+
+	ret = VmbusPostMessage(msg,
+			       sizeof(struct vmbus_channel_message_header));
+	if (ret != 0) {
+		DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret);
+
+		/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
+		REMOVE_ENTRY_LIST(&msgInfo->msgListEntry);
+		SpinlockRelease(gVmbusConnection.channelMsgLock);*/
+
+		goto Cleanup;
+	}
+	/* osd_WaitEventWait(msgInfo->waitEvent); */
+
+	/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
+	REMOVE_ENTRY_LIST(&msgInfo->msgListEntry);
+	SpinlockRelease(gVmbusConnection.channelMsgLock);*/
+
+
+Cleanup:
+	if (msgInfo) {
+		kfree(msgInfo->WaitEvent);
+		kfree(msgInfo);
+	}
+
+	DPRINT_EXIT(VMBUS);
+	return ret;
+}
+
+/**
+ * VmbusChannelReleaseUnattachedChannels - Release channels that are unattached/unconnected ie (no drivers associated)
+ */
+void VmbusChannelReleaseUnattachedChannels(void)
+{
+	struct vmbus_channel *channel, *pos;
+	struct vmbus_channel *start = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
+
+	list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList,
+				 ListEntry) {
+		if (channel == start)
+			break;
+
+		if (!channel->DeviceObject->Driver) {
+			list_del(&channel->ListEntry);
+			DPRINT_INFO(VMBUS,
+				    "Releasing unattached device object %p",
+				    channel->DeviceObject);
+
+			VmbusChildDeviceRemove(channel->DeviceObject);
+			FreeVmbusChannel(channel);
+		} else {
+			if (!start)
+				start = channel;
+		}
+	}
+
+	spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
+}
+
+/* eof */
diff --git a/drivers/staging/hv/ChannelMgmt.h b/drivers/staging/hv/ChannelMgmt.h
new file mode 100644
index 0000000..a839d8f
--- /dev/null
+++ b/drivers/staging/hv/ChannelMgmt.h
@@ -0,0 +1,319 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _CHANNEL_MGMT_H_
+#define _CHANNEL_MGMT_H_
+
+#include <linux/list.h>
+#include "RingBuffer.h"
+#include "VmbusChannelInterface.h"
+#include "VmbusPacketFormat.h"
+
+/* Version 1 messages */
+enum vmbus_channel_message_type {
+	ChannelMessageInvalid			=  0,
+	ChannelMessageOfferChannel		=  1,
+	ChannelMessageRescindChannelOffer	=  2,
+	ChannelMessageRequestOffers		=  3,
+	ChannelMessageAllOffersDelivered	=  4,
+	ChannelMessageOpenChannel		=  5,
+	ChannelMessageOpenChannelResult		=  6,
+	ChannelMessageCloseChannel		=  7,
+	ChannelMessageGpadlHeader		=  8,
+	ChannelMessageGpadlBody			=  9,
+	ChannelMessageGpadlCreated		= 10,
+	ChannelMessageGpadlTeardown		= 11,
+	ChannelMessageGpadlTorndown		= 12,
+	ChannelMessageRelIdReleased		= 13,
+	ChannelMessageInitiateContact		= 14,
+	ChannelMessageVersionResponse		= 15,
+	ChannelMessageUnload			= 16,
+#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
+	ChannelMessageViewRangeAdd		= 17,
+	ChannelMessageViewRangeRemove		= 18,
+#endif
+	ChannelMessageCount
+} __attribute__((packed));
+
+struct vmbus_channel_message_header {
+	enum vmbus_channel_message_type MessageType;
+	u32 Padding;
+} __attribute__((packed));
+
+/* Query VMBus Version parameters */
+struct vmbus_channel_query_vmbus_version {
+	struct vmbus_channel_message_header Header;
+	u32 Version;
+} __attribute__((packed));
+
+/* VMBus Version Supported parameters */
+struct vmbus_channel_version_supported {
+	struct vmbus_channel_message_header Header;
+	bool VersionSupported;
+} __attribute__((packed));
+
+/* Offer Channel parameters */
+struct vmbus_channel_offer_channel {
+	struct vmbus_channel_message_header Header;
+	struct vmbus_channel_offer Offer;
+	u32 ChildRelId;
+	u8 MonitorId;
+	bool MonitorAllocated;
+} __attribute__((packed));
+
+/* Rescind Offer parameters */
+struct vmbus_channel_rescind_offer {
+	struct vmbus_channel_message_header Header;
+	u32 ChildRelId;
+} __attribute__((packed));
+
+/*
+ * Request Offer -- no parameters, SynIC message contains the partition ID
+ * Set Snoop -- no parameters, SynIC message contains the partition ID
+ * Clear Snoop -- no parameters, SynIC message contains the partition ID
+ * All Offers Delivered -- no parameters, SynIC message contains the partition
+ *		           ID
+ * Flush Client -- no parameters, SynIC message contains the partition ID
+ */
+
+/* Open Channel parameters */
+struct vmbus_channel_open_channel {
+	struct vmbus_channel_message_header Header;
+
+	/* Identifies the specific VMBus channel that is being opened. */
+	u32 ChildRelId;
+
+	/* ID making a particular open request at a channel offer unique. */
+	u32 OpenId;
+
+	/* GPADL for the channel's ring buffer. */
+	u32 RingBufferGpadlHandle;
+
+	/* GPADL for the channel's server context save area. */
+	u32 ServerContextAreaGpadlHandle;
+
+	/*
+	* The upstream ring buffer begins at offset zero in the memory
+	* described by RingBufferGpadlHandle. The downstream ring buffer
+	* follows it at this offset (in pages).
+	*/
+	u32 DownstreamRingBufferPageOffset;
+
+	/* User-specific data to be passed along to the server endpoint. */
+	unsigned char UserData[MAX_USER_DEFINED_BYTES];
+} __attribute__((packed));
+
+/* Open Channel Result parameters */
+struct vmbus_channel_open_result {
+	struct vmbus_channel_message_header Header;
+	u32 ChildRelId;
+	u32 OpenId;
+	u32 Status;
+} __attribute__((packed));
+
+/* Close channel parameters; */
+struct vmbus_channel_close_channel {
+	struct vmbus_channel_message_header Header;
+	u32 ChildRelId;
+} __attribute__((packed));
+
+/* Channel Message GPADL */
+#define GPADL_TYPE_RING_BUFFER		1
+#define GPADL_TYPE_SERVER_SAVE_AREA	2
+#define GPADL_TYPE_TRANSACTION		8
+
+/*
+ * The number of PFNs in a GPADL message is defined by the number of
+ * pages that would be spanned by ByteCount and ByteOffset.  If the
+ * implied number of PFNs won't fit in this packet, there will be a
+ * follow-up packet that contains more.
+ */
+struct vmbus_channel_gpadl_header {
+	struct vmbus_channel_message_header Header;
+	u32 ChildRelId;
+	u32 Gpadl;
+	u16 RangeBufLen;
+	u16 RangeCount;
+	struct gpa_range Range[0];
+} __attribute__((packed));
+
+/* This is the followup packet that contains more PFNs. */
+struct vmbus_channel_gpadl_body {
+	struct vmbus_channel_message_header Header;
+	u32 MessageNumber;
+	u32 Gpadl;
+	u64 Pfn[0];
+} __attribute__((packed));
+
+struct vmbus_channel_gpadl_created {
+	struct vmbus_channel_message_header Header;
+	u32 ChildRelId;
+	u32 Gpadl;
+	u32 CreationStatus;
+} __attribute__((packed));
+
+struct vmbus_channel_gpadl_teardown {
+	struct vmbus_channel_message_header Header;
+	u32 ChildRelId;
+	u32 Gpadl;
+} __attribute__((packed));
+
+struct vmbus_channel_gpadl_torndown {
+	struct vmbus_channel_message_header Header;
+	u32 Gpadl;
+} __attribute__((packed));
+
+#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
+struct vmbus_channel_view_range_add {
+	struct vmbus_channel_message_header Header;
+	PHYSICAL_ADDRESS ViewRangeBase;
+	u64 ViewRangeLength;
+	u32 ChildRelId;
+} __attribute__((packed));
+
+struct vmbus_channel_view_range_remove {
+	struct vmbus_channel_message_header Header;
+	PHYSICAL_ADDRESS ViewRangeBase;
+	u32 ChildRelId;
+} __attribute__((packed));
+#endif
+
+struct vmbus_channel_relid_released {
+	struct vmbus_channel_message_header Header;
+	u32 ChildRelId;
+} __attribute__((packed));
+
+struct vmbus_channel_initiate_contact {
+	struct vmbus_channel_message_header Header;
+	u32 VMBusVersionRequested;
+	u32 Padding2;
+	u64 InterruptPage;
+	u64 MonitorPage1;
+	u64 MonitorPage2;
+} __attribute__((packed));
+
+struct vmbus_channel_version_response {
+	struct vmbus_channel_message_header Header;
+	bool VersionSupported;
+} __attribute__((packed));
+
+enum vmbus_channel_state {
+	CHANNEL_OFFER_STATE,
+	CHANNEL_OPENING_STATE,
+	CHANNEL_OPEN_STATE,
+};
+
+struct vmbus_channel {
+	struct list_head ListEntry;
+
+	struct hv_device *DeviceObject;
+
+	struct timer_list poll_timer; /* SA-111 workaround */
+
+	enum vmbus_channel_state State;
+
+	struct vmbus_channel_offer_channel OfferMsg;
+	/*
+	 * These are based on the OfferMsg.MonitorId.
+	 * Save it here for easy access.
+	 */
+	u8 MonitorGroup;
+	u8 MonitorBit;
+
+	u32 RingBufferGpadlHandle;
+
+	/* Allocated memory for ring buffer */
+	void *RingBufferPages;
+	u32 RingBufferPageCount;
+	RING_BUFFER_INFO Outbound;	/* send to parent */
+	RING_BUFFER_INFO Inbound;	/* receive from parent */
+	spinlock_t inbound_lock;
+	struct workqueue_struct *ControlWQ;
+
+	/* Channel callback are invoked in this workqueue context */
+	/* HANDLE dataWorkQueue; */
+
+	void (*OnChannelCallback)(void *context);
+	void *ChannelCallbackContext;
+};
+
+struct vmbus_channel_debug_info {
+	u32 RelId;
+	enum vmbus_channel_state State;
+	struct hv_guid InterfaceType;
+	struct hv_guid InterfaceInstance;
+	u32 MonitorId;
+	u32 ServerMonitorPending;
+	u32 ServerMonitorLatency;
+	u32 ServerMonitorConnectionId;
+	u32 ClientMonitorPending;
+	u32 ClientMonitorLatency;
+	u32 ClientMonitorConnectionId;
+
+	RING_BUFFER_DEBUG_INFO Inbound;
+	RING_BUFFER_DEBUG_INFO Outbound;
+};
+
+/*
+ * Represents each channel msg on the vmbus connection This is a
+ * variable-size data structure depending on the msg type itself
+ */
+struct vmbus_channel_msginfo {
+	/* Bookkeeping stuff */
+	struct list_head MsgListEntry;
+
+	/* So far, this is only used to handle gpadl body message */
+	struct list_head SubMsgList;
+
+	/* Synchronize the request/response if needed */
+	struct osd_waitevent *WaitEvent;
+
+	union {
+		struct vmbus_channel_version_supported VersionSupported;
+		struct vmbus_channel_open_result OpenResult;
+		struct vmbus_channel_gpadl_torndown GpadlTorndown;
+		struct vmbus_channel_gpadl_created GpadlCreated;
+		struct vmbus_channel_version_response VersionResponse;
+	} Response;
+
+	u32 MessageSize;
+	/*
+	 * The channel message that goes out on the "wire".
+	 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
+	 */
+	unsigned char Msg[0];
+};
+
+
+struct vmbus_channel *AllocVmbusChannel(void);
+
+void FreeVmbusChannel(struct vmbus_channel *Channel);
+
+void VmbusOnChannelMessage(void *Context);
+
+int VmbusChannelRequestOffers(void);
+
+void VmbusChannelReleaseUnattachedChannels(void);
+
+#endif /* _CHANNEL_MGMT_H_ */
diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/Connection.c
new file mode 100644
index 0000000..43c2e68
--- /dev/null
+++ b/drivers/staging/hv/Connection.c
@@ -0,0 +1,341 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include "osd.h"
+#include "logging.h"
+#include "VmbusPrivate.h"
+
+
+struct VMBUS_CONNECTION gVmbusConnection = {
+	.ConnectState		= Disconnected,
+	.NextGpadlHandle	= ATOMIC_INIT(0xE1E10),
+};
+
+/**
+ * VmbusConnect - Sends a connect request on the partition service connection
+ */
+int VmbusConnect(void)
+{
+	int ret = 0;
+	struct vmbus_channel_msginfo *msgInfo = NULL;
+	struct vmbus_channel_initiate_contact *msg;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Make sure we are not connecting or connected */
+	if (gVmbusConnection.ConnectState != Disconnected)
+		return -1;
+
+	/* Initialize the vmbus connection */
+	gVmbusConnection.ConnectState = Connecting;
+	gVmbusConnection.WorkQueue = create_workqueue("hv_vmbus_con");
+	if (!gVmbusConnection.WorkQueue) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	INIT_LIST_HEAD(&gVmbusConnection.ChannelMsgList);
+	spin_lock_init(&gVmbusConnection.channelmsg_lock);
+
+	INIT_LIST_HEAD(&gVmbusConnection.ChannelList);
+	spin_lock_init(&gVmbusConnection.channel_lock);
+
+	/*
+	 * Setup the vmbus event connection for channel interrupt
+	 * abstraction stuff
+	 */
+	gVmbusConnection.InterruptPage = osd_PageAlloc(1);
+	if (gVmbusConnection.InterruptPage == NULL) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	gVmbusConnection.RecvInterruptPage = gVmbusConnection.InterruptPage;
+	gVmbusConnection.SendInterruptPage =
+		(void *)((unsigned long)gVmbusConnection.InterruptPage +
+			(PAGE_SIZE >> 1));
+
+	/*
+	 * Setup the monitor notification facility. The 1st page for
+	 * parent->child and the 2nd page for child->parent
+	 */
+	gVmbusConnection.MonitorPages = osd_PageAlloc(2);
+	if (gVmbusConnection.MonitorPages == NULL) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	msgInfo = kzalloc(sizeof(*msgInfo) +
+			  sizeof(struct vmbus_channel_initiate_contact),
+			  GFP_KERNEL);
+	if (msgInfo == NULL) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	msgInfo->WaitEvent = osd_WaitEventCreate();
+	msg = (struct vmbus_channel_initiate_contact *)msgInfo->Msg;
+
+	msg->Header.MessageType = ChannelMessageInitiateContact;
+	msg->VMBusVersionRequested = VMBUS_REVISION_NUMBER;
+	msg->InterruptPage = virt_to_phys(gVmbusConnection.InterruptPage);
+	msg->MonitorPage1 = virt_to_phys(gVmbusConnection.MonitorPages);
+	msg->MonitorPage2 = virt_to_phys(
+			(void *)((unsigned long)gVmbusConnection.MonitorPages +
+				 PAGE_SIZE));
+
+	/*
+	 * Add to list before we send the request since we may
+	 * receive the response before returning from this routine
+	 */
+	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
+	list_add_tail(&msgInfo->MsgListEntry,
+		      &gVmbusConnection.ChannelMsgList);
+
+	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
+
+	DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, "
+		   "monitor1 pfn %llx,, monitor2 pfn %llx",
+		   msg->InterruptPage, msg->MonitorPage1, msg->MonitorPage2);
+
+	DPRINT_DBG(VMBUS, "Sending channel initiate msg...");
+	ret = VmbusPostMessage(msg,
+			       sizeof(struct vmbus_channel_initiate_contact));
+	if (ret != 0) {
+		list_del(&msgInfo->MsgListEntry);
+		goto Cleanup;
+	}
+
+	/* Wait for the connection response */
+	osd_WaitEventWait(msgInfo->WaitEvent);
+
+	list_del(&msgInfo->MsgListEntry);
+
+	/* Check if successful */
+	if (msgInfo->Response.VersionResponse.VersionSupported) {
+		DPRINT_INFO(VMBUS, "Vmbus connected!!");
+		gVmbusConnection.ConnectState = Connected;
+
+	} else {
+		DPRINT_ERR(VMBUS, "Vmbus connection failed!!..."
+			   "current version (%d) not supported",
+			   VMBUS_REVISION_NUMBER);
+		ret = -1;
+		goto Cleanup;
+	}
+
+	kfree(msgInfo->WaitEvent);
+	kfree(msgInfo);
+	DPRINT_EXIT(VMBUS);
+
+	return 0;
+
+Cleanup:
+	gVmbusConnection.ConnectState = Disconnected;
+
+	if (gVmbusConnection.WorkQueue)
+		destroy_workqueue(gVmbusConnection.WorkQueue);
+
+	if (gVmbusConnection.InterruptPage) {
+		osd_PageFree(gVmbusConnection.InterruptPage, 1);
+		gVmbusConnection.InterruptPage = NULL;
+	}
+
+	if (gVmbusConnection.MonitorPages) {
+		osd_PageFree(gVmbusConnection.MonitorPages, 2);
+		gVmbusConnection.MonitorPages = NULL;
+	}
+
+	if (msgInfo) {
+		kfree(msgInfo->WaitEvent);
+		kfree(msgInfo);
+	}
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusDisconnect - Sends a disconnect request on the partition service connection
+ */
+int VmbusDisconnect(void)
+{
+	int ret = 0;
+	struct vmbus_channel_message_header *msg;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Make sure we are connected */
+	if (gVmbusConnection.ConnectState != Connected)
+		return -1;
+
+	msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL);
+
+	msg->MessageType = ChannelMessageUnload;
+
+	ret = VmbusPostMessage(msg,
+			       sizeof(struct vmbus_channel_message_header));
+	if (ret != 0)
+		goto Cleanup;
+
+	osd_PageFree(gVmbusConnection.InterruptPage, 1);
+
+	/* TODO: iterate thru the msg list and free up */
+	destroy_workqueue(gVmbusConnection.WorkQueue);
+
+	gVmbusConnection.ConnectState = Disconnected;
+
+	DPRINT_INFO(VMBUS, "Vmbus disconnected!!");
+
+Cleanup:
+	kfree(msg);
+	DPRINT_EXIT(VMBUS);
+	return ret;
+}
+
+/**
+ * GetChannelFromRelId - Get the channel object given its child relative id (ie channel id)
+ */
+struct vmbus_channel *GetChannelFromRelId(u32 relId)
+{
+	struct vmbus_channel *channel;
+	struct vmbus_channel *foundChannel  = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
+	list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) {
+		if (channel->OfferMsg.ChildRelId == relId) {
+			foundChannel = channel;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
+
+	return foundChannel;
+}
+
+/**
+ * VmbusProcessChannelEvent - Process a channel event notification
+ */
+static void VmbusProcessChannelEvent(void *context)
+{
+	struct vmbus_channel *channel;
+	u32 relId = (u32)(unsigned long)context;
+
+	ASSERT(relId > 0);
+
+	/*
+	 * Find the channel based on this relid and invokes the
+	 * channel callback to process the event
+	 */
+	channel = GetChannelFromRelId(relId);
+
+	if (channel) {
+		VmbusChannelOnChannelEvent(channel);
+		/*
+		 * WorkQueueQueueWorkItem(channel->dataWorkQueue,
+		 * 			  VmbusChannelOnChannelEvent,
+		 * 			  (void*)channel);
+		 */
+	} else {
+		DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId);
+	}
+}
+
+/**
+ * VmbusOnEvents - Handler for events
+ */
+void VmbusOnEvents(void)
+{
+	int dword;
+	int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
+	int bit;
+	int relid;
+	u32 *recvInterruptPage = gVmbusConnection.RecvInterruptPage;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Check events */
+	if (recvInterruptPage) {
+		for (dword = 0; dword < maxdword; dword++) {
+			if (recvInterruptPage[dword]) {
+				for (bit = 0; bit < 32; bit++) {
+					if (test_and_clear_bit(bit, (unsigned long *)&recvInterruptPage[dword])) {
+						relid = (dword << 5) + bit;
+						DPRINT_DBG(VMBUS, "event detected for relid - %d", relid);
+
+						if (relid == 0) {
+							/* special case - vmbus channel protocol msg */
+							DPRINT_DBG(VMBUS, "invalid relid - %d", relid);
+							continue;
+						} else {
+							/* QueueWorkItem(VmbusProcessEvent, (void*)relid); */
+							/* ret = WorkQueueQueueWorkItem(gVmbusConnection.workQueue, VmbusProcessChannelEvent, (void*)relid); */
+							VmbusProcessChannelEvent((void *)(unsigned long)relid);
+						}
+					}
+				}
+			}
+		 }
+	}
+	DPRINT_EXIT(VMBUS);
+
+	return;
+}
+
+/**
+ * VmbusPostMessage - Send a msg on the vmbus's message connection
+ */
+int VmbusPostMessage(void *buffer, size_t bufferLen)
+{
+	union hv_connection_id connId;
+
+	connId.Asu32 = 0;
+	connId.u.Id = VMBUS_MESSAGE_CONNECTION_ID;
+	return HvPostMessage(connId, 1, buffer, bufferLen);
+}
+
+/**
+ * VmbusSetEvent - Send an event notification to the parent
+ */
+int VmbusSetEvent(u32 childRelId)
+{
+	int ret = 0;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Each u32 represents 32 channels */
+	set_bit(childRelId & 31,
+		(unsigned long *)gVmbusConnection.SendInterruptPage +
+		(childRelId >> 5));
+
+	ret = HvSignalEvent();
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/Hv.c
new file mode 100644
index 0000000..c5b6613
--- /dev/null
+++ b/drivers/staging/hv/Hv.c
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include "osd.h"
+#include "logging.h"
+#include "VmbusPrivate.h"
+
+/* The one and only */
+struct hv_context gHvContext = {
+	.SynICInitialized	= false,
+	.HypercallPage		= NULL,
+	.SignalEventParam	= NULL,
+	.SignalEventBuffer	= NULL,
+};
+
+/**
+ * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor
+ */
+static int HvQueryHypervisorPresence(void)
+{
+	unsigned int eax;
+	unsigned int ebx;
+	unsigned int ecx;
+	unsigned int edx;
+	unsigned int op;
+
+	eax = 0;
+	ebx = 0;
+	ecx = 0;
+	edx = 0;
+	op = HvCpuIdFunctionVersionAndFeatures;
+	cpuid(op, &eax, &ebx, &ecx, &edx);
+
+	return ecx & HV_PRESENT_BIT;
+}
+
+/**
+ * HvQueryHypervisorInfo - Get version info of the windows hypervisor
+ */
+static int HvQueryHypervisorInfo(void)
+{
+	unsigned int eax;
+	unsigned int ebx;
+	unsigned int ecx;
+	unsigned int edx;
+	unsigned int maxLeaf;
+	unsigned int op;
+
+	/*
+	* Its assumed that this is called after confirming that Viridian
+	* is present. Query id and revision.
+	*/
+	eax = 0;
+	ebx = 0;
+	ecx = 0;
+	edx = 0;
+	op = HvCpuIdFunctionHvVendorAndMaxFunction;
+	cpuid(op, &eax, &ebx, &ecx, &edx);
+
+	DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c",
+		    (ebx & 0xFF),
+		    ((ebx >> 8) & 0xFF),
+		    ((ebx >> 16) & 0xFF),
+		    ((ebx >> 24) & 0xFF),
+		    (ecx & 0xFF),
+		    ((ecx >> 8) & 0xFF),
+		    ((ecx >> 16) & 0xFF),
+		    ((ecx >> 24) & 0xFF),
+		    (edx & 0xFF),
+		    ((edx >> 8) & 0xFF),
+		    ((edx >> 16) & 0xFF),
+		    ((edx >> 24) & 0xFF));
+
+	maxLeaf = eax;
+	eax = 0;
+	ebx = 0;
+	ecx = 0;
+	edx = 0;
+	op = HvCpuIdFunctionHvInterface;
+	cpuid(op, &eax, &ebx, &ecx, &edx);
+
+	DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c",
+		    (eax & 0xFF),
+		    ((eax >> 8) & 0xFF),
+		    ((eax >> 16) & 0xFF),
+		    ((eax >> 24) & 0xFF));
+
+	if (maxLeaf >= HvCpuIdFunctionMsHvVersion) {
+		eax = 0;
+		ebx = 0;
+		ecx = 0;
+		edx = 0;
+		op = HvCpuIdFunctionMsHvVersion;
+		cpuid(op, &eax, &ebx, &ecx, &edx);
+		DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\
+			    eax,
+			    ebx >> 16,
+			    ebx & 0xFFFF,
+			    ecx,
+			    edx >> 24,
+			    edx & 0xFFFFFF);
+	}
+	return maxLeaf;
+}
+
+/**
+ * HvDoHypercall - Invoke the specified hypercall
+ */
+static u64 HvDoHypercall(u64 Control, void *Input, void *Output)
+{
+#ifdef CONFIG_X86_64
+	u64 hvStatus = 0;
+	u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
+	u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
+	volatile void *hypercallPage = gHvContext.HypercallPage;
+
+	DPRINT_DBG(VMBUS, "Hypercall <control %llx input phys %llx virt %p "
+		   "output phys %llx virt %p hypercall %p>",
+		   Control, inputAddress, Input,
+		   outputAddress, Output, hypercallPage);
+
+	__asm__ __volatile__("mov %0, %%r8" : : "r" (outputAddress) : "r8");
+	__asm__ __volatile__("call *%3" : "=a" (hvStatus) :
+			     "c" (Control), "d" (inputAddress),
+			     "m" (hypercallPage));
+
+	DPRINT_DBG(VMBUS, "Hypercall <return %llx>",  hvStatus);
+
+	return hvStatus;
+
+#else
+
+	u32 controlHi = Control >> 32;
+	u32 controlLo = Control & 0xFFFFFFFF;
+	u32 hvStatusHi = 1;
+	u32 hvStatusLo = 1;
+	u64 inputAddress = (Input) ? virt_to_phys(Input) : 0;
+	u32 inputAddressHi = inputAddress >> 32;
+	u32 inputAddressLo = inputAddress & 0xFFFFFFFF;
+	u64 outputAddress = (Output) ? virt_to_phys(Output) : 0;
+	u32 outputAddressHi = outputAddress >> 32;
+	u32 outputAddressLo = outputAddress & 0xFFFFFFFF;
+	volatile void *hypercallPage = gHvContext.HypercallPage;
+
+	DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
+		   Control, Input, Output);
+
+	__asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi),
+			      "=a"(hvStatusLo) : "d" (controlHi),
+			      "a" (controlLo), "b" (inputAddressHi),
+			      "c" (inputAddressLo), "D"(outputAddressHi),
+			      "S"(outputAddressLo), "m" (hypercallPage));
+
+	DPRINT_DBG(VMBUS, "Hypercall <return %llx>",
+		   hvStatusLo | ((u64)hvStatusHi << 32));
+
+	return hvStatusLo | ((u64)hvStatusHi << 32);
+#endif /* !x86_64 */
+}
+
+/**
+ * HvInit - Main initialization routine.
+ *
+ * This routine must be called before any other routines in here are called
+ */
+int HvInit(void)
+{
+	int ret = 0;
+	int maxLeaf;
+	union hv_x64_msr_hypercall_contents hypercallMsr;
+	void *virtAddr = NULL;
+
+	DPRINT_ENTER(VMBUS);
+
+	memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS);
+	memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS);
+
+	if (!HvQueryHypervisorPresence()) {
+		DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!");
+		goto Cleanup;
+	}
+
+	DPRINT_INFO(VMBUS,
+		    "Windows hypervisor detected! Retrieving more info...");
+
+	maxLeaf = HvQueryHypervisorInfo();
+	/* HvQueryHypervisorFeatures(maxLeaf); */
+
+	/*
+	 * Determine if we are running on xenlinux (ie x2v shim) or native
+	 * linux
+	 */
+	rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId);
+	if (gHvContext.GuestId == 0) {
+		/* Write our OS info */
+		wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
+		gHvContext.GuestId = HV_LINUX_GUEST_ID;
+	}
+
+	/* See if the hypercall page is already set */
+	rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
+		/* Allocate the hypercall page memory */
+		/* virtAddr = osd_PageAlloc(1); */
+		virtAddr = osd_VirtualAllocExec(PAGE_SIZE);
+
+		if (!virtAddr) {
+			DPRINT_ERR(VMBUS,
+				   "unable to allocate hypercall page!!");
+			goto Cleanup;
+		}
+
+		hypercallMsr.Enable = 1;
+		/* hypercallMsr.GuestPhysicalAddress =
+		 * 		virt_to_phys(virtAddr) >> PAGE_SHIFT; */
+		hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr);
+		wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+
+		/* Confirm that hypercall page did get setup. */
+		hypercallMsr.AsUINT64 = 0;
+		rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+		if (!hypercallMsr.Enable) {
+			DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
+			goto Cleanup;
+		}
+
+		gHvContext.HypercallPage = virtAddr;
+	} else {
+		DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
+				gHvContext.GuestId);
+		goto Cleanup;
+	}
+
+	DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
+		    gHvContext.HypercallPage,
+		    (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
+
+	/* Setup the global signal event param for the signal event hypercall */
+	gHvContext.SignalEventBuffer =
+			kmalloc(sizeof(struct hv_input_signal_event_buffer),
+				GFP_KERNEL);
+	if (!gHvContext.SignalEventBuffer)
+		goto Cleanup;
+
+	gHvContext.SignalEventParam =
+		(struct hv_input_signal_event *)
+			(ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer,
+				  HV_HYPERCALL_PARAM_ALIGN));
+	gHvContext.SignalEventParam->ConnectionId.Asu32 = 0;
+	gHvContext.SignalEventParam->ConnectionId.u.Id =
+						VMBUS_EVENT_CONNECTION_ID;
+	gHvContext.SignalEventParam->FlagNumber = 0;
+	gHvContext.SignalEventParam->RsvdZ = 0;
+
+	/* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+
+Cleanup:
+	if (virtAddr) {
+		if (hypercallMsr.Enable) {
+			hypercallMsr.AsUINT64 = 0;
+			wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+		}
+
+		vfree(virtAddr);
+	}
+	ret = -1;
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * HvCleanup - Cleanup routine.
+ *
+ * This routine is called normally during driver unloading or exiting.
+ */
+void HvCleanup(void)
+{
+	union hv_x64_msr_hypercall_contents hypercallMsr;
+
+	DPRINT_ENTER(VMBUS);
+
+	if (gHvContext.SignalEventBuffer) {
+		gHvContext.SignalEventBuffer = NULL;
+		gHvContext.SignalEventParam = NULL;
+		kfree(gHvContext.SignalEventBuffer);
+	}
+
+	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
+		if (gHvContext.HypercallPage) {
+			hypercallMsr.AsUINT64 = 0;
+			wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
+			vfree(gHvContext.HypercallPage);
+			gHvContext.HypercallPage = NULL;
+		}
+	}
+
+	DPRINT_EXIT(VMBUS);
+
+}
+
+/**
+ * HvPostMessage - Post a message using the hypervisor message IPC.
+ *
+ * This involves a hypercall.
+ */
+u16 HvPostMessage(union hv_connection_id connectionId,
+		  enum hv_message_type messageType,
+		  void *payload, size_t payloadSize)
+{
+	struct alignedInput {
+		u64 alignment8;
+		struct hv_input_post_message msg;
+	};
+
+	struct hv_input_post_message *alignedMsg;
+	u16 status;
+	unsigned long addr;
+
+	if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
+		return -1;
+
+	addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC);
+	if (!addr)
+		return -1;
+
+	alignedMsg = (struct hv_input_post_message *)
+			(ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN));
+
+	alignedMsg->ConnectionId = connectionId;
+	alignedMsg->MessageType = messageType;
+	alignedMsg->PayloadSize = payloadSize;
+	memcpy((void *)alignedMsg->Payload, payload, payloadSize);
+
+	status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF;
+
+	kfree((void *)addr);
+
+	return status;
+}
+
+
+/**
+ * HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC.
+ *
+ * This involves a hypercall.
+ */
+u16 HvSignalEvent(void)
+{
+	u16 status;
+
+	status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam,
+			       NULL) & 0xFFFF;
+	return status;
+}
+
+/**
+ * HvSynicInit - Initialize the Synthethic Interrupt Controller.
+ *
+ * If it is already initialized by another entity (ie x2v shim), we need to
+ * retrieve the initialized message and event pages.  Otherwise, we create and
+ * initialize the message and event pages.
+ */
+int HvSynicInit(u32 irqVector)
+{
+	u64 version;
+	union hv_synic_simp simp;
+	union hv_synic_siefp siefp;
+	union hv_synic_sint sharedSint;
+	union hv_synic_scontrol sctrl;
+	u64 guestID;
+	int ret = 0;
+
+	DPRINT_ENTER(VMBUS);
+
+	if (!gHvContext.HypercallPage) {
+		DPRINT_EXIT(VMBUS);
+		return ret;
+	}
+
+	/* Check the version */
+	rdmsrl(HV_X64_MSR_SVERSION, version);
+
+	DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
+
+	/* TODO: Handle SMP */
+	if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID) {
+		DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since "
+				"it is already set.");
+
+		rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+		rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+
+		DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx",
+			   simp.AsUINT64, siefp.AsUINT64);
+
+		/*
+		 * Determine if we are running on xenlinux (ie x2v shim) or
+		 * native linux
+		 */
+		rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
+		if (guestID == HV_LINUX_GUEST_ID) {
+			gHvContext.synICMessagePage[0] =
+				phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
+			gHvContext.synICEventPage[0] =
+				phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
+		} else {
+			DPRINT_ERR(VMBUS, "unknown guest id!!");
+			goto Cleanup;
+		}
+		DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
+			   gHvContext.synICMessagePage[0],
+			   gHvContext.synICEventPage[0]);
+	} else {
+		gHvContext.synICMessagePage[0] = osd_PageAlloc(1);
+		if (gHvContext.synICMessagePage[0] == NULL) {
+			DPRINT_ERR(VMBUS,
+				   "unable to allocate SYNIC message page!!");
+			goto Cleanup;
+		}
+
+		gHvContext.synICEventPage[0] = osd_PageAlloc(1);
+		if (gHvContext.synICEventPage[0] == NULL) {
+			DPRINT_ERR(VMBUS,
+				   "unable to allocate SYNIC event page!!");
+			goto Cleanup;
+		}
+
+		/* Setup the Synic's message page */
+		rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+		simp.SimpEnabled = 1;
+		simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[0])
+					>> PAGE_SHIFT;
+
+		DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx",
+				simp.AsUINT64);
+
+		wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+
+		/* Setup the Synic's event page */
+		rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+		siefp.SiefpEnabled = 1;
+		siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[0])
+					>> PAGE_SHIFT;
+
+		DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx",
+				siefp.AsUINT64);
+
+		wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+	}
+
+	/* Setup the interception SINT. */
+	/* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
+	/*	  interceptionSint.AsUINT64); */
+
+	/* Setup the shared SINT. */
+	rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+
+	sharedSint.AsUINT64 = 0;
+	sharedSint.Vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
+	sharedSint.Masked = false;
+	sharedSint.AutoEoi = true;
+
+	DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx",
+		   sharedSint.AsUINT64);
+
+	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+
+	/* Enable the global synic bit */
+	rdmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
+	sctrl.Enable = 1;
+
+	wrmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
+
+	gHvContext.SynICInitialized = true;
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+
+Cleanup:
+	ret = -1;
+
+	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
+		if (gHvContext.synICEventPage[0])
+			osd_PageFree(gHvContext.synICEventPage[0], 1);
+
+		if (gHvContext.synICMessagePage[0])
+			osd_PageFree(gHvContext.synICMessagePage[0], 1);
+	}
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * HvSynicCleanup - Cleanup routine for HvSynicInit().
+ */
+void HvSynicCleanup(void)
+{
+	union hv_synic_sint sharedSint;
+	union hv_synic_simp simp;
+	union hv_synic_siefp siefp;
+
+	DPRINT_ENTER(VMBUS);
+
+	if (!gHvContext.SynICInitialized) {
+		DPRINT_EXIT(VMBUS);
+		return;
+	}
+
+	rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+
+	sharedSint.Masked = 1;
+
+	/* Disable the interrupt */
+	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
+
+	/*
+	 * Disable and free the resources only if we are running as
+	 * native linux since in xenlinux, we are sharing the
+	 * resources with the x2v shim
+	 */
+	if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
+		rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+		simp.SimpEnabled = 0;
+		simp.BaseSimpGpa = 0;
+
+		wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
+
+		rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+		siefp.SiefpEnabled = 0;
+		siefp.BaseSiefpGpa = 0;
+
+		wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
+
+		osd_PageFree(gHvContext.synICMessagePage[0], 1);
+		osd_PageFree(gHvContext.synICEventPage[0], 1);
+	}
+
+	DPRINT_EXIT(VMBUS);
+}
diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/Hv.h
new file mode 100644
index 0000000..5379e4b
--- /dev/null
+++ b/drivers/staging/hv/Hv.h
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef __HV_H__
+#define __HV_H__
+
+#include "hv_api.h"
+
+enum {
+	VMBUS_MESSAGE_CONNECTION_ID	= 1,
+	VMBUS_MESSAGE_PORT_ID		= 1,
+	VMBUS_EVENT_CONNECTION_ID	= 2,
+	VMBUS_EVENT_PORT_ID		= 2,
+	VMBUS_MONITOR_CONNECTION_ID	= 3,
+	VMBUS_MONITOR_PORT_ID		= 3,
+	VMBUS_MESSAGE_SINT		= 2,
+};
+
+/* #defines */
+
+#define HV_PRESENT_BIT			0x80000000
+
+#define HV_XENLINUX_GUEST_ID_LO		0x00000000
+#define HV_XENLINUX_GUEST_ID_HI		0x0B00B135
+#define HV_XENLINUX_GUEST_ID		(((u64)HV_XENLINUX_GUEST_ID_HI << 32) \
+					  | HV_XENLINUX_GUEST_ID_LO)
+
+#define HV_LINUX_GUEST_ID_LO		0x00000000
+#define HV_LINUX_GUEST_ID_HI		0xB16B00B5
+#define HV_LINUX_GUEST_ID		(((u64)HV_LINUX_GUEST_ID_HI << 32) | \
+					   HV_LINUX_GUEST_ID_LO)
+
+#define HV_CPU_POWER_MANAGEMENT		(1 << 0)
+#define HV_RECOMMENDATIONS_MAX		4
+
+#define HV_X64_MAX			5
+#define HV_CAPS_MAX			8
+
+
+#define HV_HYPERCALL_PARAM_ALIGN	sizeof(u64)
+
+
+/* Service definitions */
+
+#define HV_SERVICE_PARENT_PORT				(0)
+#define HV_SERVICE_PARENT_CONNECTION			(0)
+
+#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS		(0)
+#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER	(1)
+#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE	(2)
+#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED	(3)
+
+#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID		(1)
+#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID		(2)
+#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID	(3)
+#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID	(4)
+#define HV_SERVICE_MAX_MESSAGE_ID				(4)
+
+#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
+#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
+
+/* #define VMBUS_REVISION_NUMBER	6 */
+
+/* Our local vmbus's port and connection id. Anything >0 is fine */
+/* #define VMBUS_PORT_ID		11 */
+
+/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
+static const struct hv_guid VMBUS_SERVICE_ID = {
+	.data = {
+		0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
+		0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
+	},
+};
+
+#define MAX_NUM_CPUS	1
+
+
+struct hv_input_signal_event_buffer {
+	u64 Align8;
+	struct hv_input_signal_event Event;
+};
+
+struct hv_context {
+	/* XenLinux or native Linux. If XenLinux, the hypercall and synic pages
+	 * has already been initialized */
+	u64 GuestId;
+
+	void *HypercallPage;
+
+	bool SynICInitialized;
+
+	/*
+	 * This is used as an input param to HvCallSignalEvent hypercall. The
+	 * input param is immutable in our usage and must be dynamic mem (vs
+	 * stack or global). */
+	struct hv_input_signal_event_buffer *SignalEventBuffer;
+	/* 8-bytes aligned of the buffer above */
+	struct hv_input_signal_event *SignalEventParam;
+
+	void *synICMessagePage[MAX_NUM_CPUS];
+	void *synICEventPage[MAX_NUM_CPUS];
+};
+
+extern struct hv_context gHvContext;
+
+
+/* Hv Interface */
+
+extern int HvInit(void);
+
+extern void HvCleanup(void);
+
+extern u16 HvPostMessage(union hv_connection_id connectionId,
+			 enum hv_message_type messageType,
+			 void *payload, size_t payloadSize);
+
+extern u16 HvSignalEvent(void);
+
+extern int HvSynicInit(u32 irqVector);
+
+extern void HvSynicCleanup(void);
+
+#endif /* __HV_H__ */
diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig
new file mode 100644
index 0000000..4044702
--- /dev/null
+++ b/drivers/staging/hv/Kconfig
@@ -0,0 +1,32 @@
+config HYPERV
+	tristate "Microsoft Hyper-V client drivers"
+	depends on X86 && m
+	default n
+	help
+	  Select this option to run Linux as a Hyper-V client operating
+	  system.
+
+if HYPERV
+
+config HYPERV_STORAGE
+	tristate "Microsoft Hyper-V virtual storage driver"
+	depends on SCSI
+	default HYPERV
+	help
+	 Select this option to enable the Hyper-V virtual storage driver.
+
+config HYPERV_BLOCK
+	tristate "Microsoft Hyper-V virtual block driver"
+	depends on BLOCK && SCSI
+	default HYPERV
+	help
+	  Select this option to enable the Hyper-V virtual block driver.
+
+config HYPERV_NET
+	tristate "Microsoft Hyper-V virtual network driver"
+	depends on NET
+	default HYPERV
+	help
+	  Select this option to enable the Hyper-V virtual network driver.
+
+endif
diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile
new file mode 100644
index 0000000..27ebae8
--- /dev/null
+++ b/drivers/staging/hv/Makefile
@@ -0,0 +1,11 @@
+obj-$(CONFIG_HYPERV)		+= hv_vmbus.o
+obj-$(CONFIG_HYPERV_STORAGE)	+= hv_storvsc.o
+obj-$(CONFIG_HYPERV_BLOCK)	+= hv_blkvsc.o
+obj-$(CONFIG_HYPERV_NET)	+= hv_netvsc.o
+
+hv_vmbus-objs := vmbus_drv.o osd.o \
+		 Vmbus.o Hv.o Connection.o Channel.o \
+		 ChannelMgmt.o ChannelInterface.o RingBuffer.o
+hv_storvsc-objs := storvsc_drv.o StorVsc.o
+hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o
+hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o
diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/NetVsc.c
new file mode 100644
index 0000000..1610b84
--- /dev/null
+++ b/drivers/staging/hv/NetVsc.c
@@ -0,0 +1,1379 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include "osd.h"
+#include "logging.h"
+#include "NetVsc.h"
+#include "RndisFilter.h"
+
+
+/* Globals */
+static const char *gDriverName = "netvsc";
+
+/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
+static const struct hv_guid gNetVscDeviceType = {
+	.data = {
+		0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
+		0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
+	}
+};
+
+static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo);
+
+static int NetVscOnDeviceRemove(struct hv_device *Device);
+
+static void NetVscOnCleanup(struct hv_driver *Driver);
+
+static void NetVscOnChannelCallback(void *context);
+
+static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device);
+
+static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device);
+
+static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice);
+
+static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice);
+
+static int NetVscConnectToVsp(struct hv_device *Device);
+
+static void NetVscOnSendCompletion(struct hv_device *Device,
+				   struct vmpacket_descriptor *Packet);
+
+static int NetVscOnSend(struct hv_device *Device,
+			struct hv_netvsc_packet *Packet);
+
+static void NetVscOnReceive(struct hv_device *Device,
+			    struct vmpacket_descriptor *Packet);
+
+static void NetVscOnReceiveCompletion(void *Context);
+
+static void NetVscSendReceiveCompletion(struct hv_device *Device,
+					u64 TransactionId);
+
+
+static struct netvsc_device *AllocNetDevice(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice;
+
+	netDevice = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL);
+	if (!netDevice)
+		return NULL;
+
+	/* Set to 2 to allow both inbound and outbound traffic */
+	atomic_cmpxchg(&netDevice->RefCount, 0, 2);
+
+	netDevice->Device = Device;
+	Device->Extension = netDevice;
+
+	return netDevice;
+}
+
+static void FreeNetDevice(struct netvsc_device *Device)
+{
+	ASSERT(atomic_read(&Device->RefCount) == 0);
+	Device->Device->Extension = NULL;
+	kfree(Device);
+}
+
+
+/* Get the net device object iff exists and its refcount > 1 */
+static struct netvsc_device *GetOutboundNetDevice(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice;
+
+	netDevice = Device->Extension;
+	if (netDevice && atomic_read(&netDevice->RefCount) > 1)
+		atomic_inc(&netDevice->RefCount);
+	else
+		netDevice = NULL;
+
+	return netDevice;
+}
+
+/* Get the net device object iff exists and its refcount > 0 */
+static struct netvsc_device *GetInboundNetDevice(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice;
+
+	netDevice = Device->Extension;
+	if (netDevice && atomic_read(&netDevice->RefCount))
+		atomic_inc(&netDevice->RefCount);
+	else
+		netDevice = NULL;
+
+	return netDevice;
+}
+
+static void PutNetDevice(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice;
+
+	netDevice = Device->Extension;
+	ASSERT(netDevice);
+
+	atomic_dec(&netDevice->RefCount);
+}
+
+static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice;
+
+	netDevice = Device->Extension;
+	if (netDevice == NULL)
+		return NULL;
+
+	/* Busy wait until the ref drop to 2, then set it to 1 */
+	while (atomic_cmpxchg(&netDevice->RefCount, 2, 1) != 2)
+		udelay(100);
+
+	return netDevice;
+}
+
+static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice;
+
+	netDevice = Device->Extension;
+	if (netDevice == NULL)
+		return NULL;
+
+	/* Busy wait until the ref drop to 1, then set it to 0 */
+	while (atomic_cmpxchg(&netDevice->RefCount, 1, 0) != 1)
+		udelay(100);
+
+	Device->Extension = NULL;
+	return netDevice;
+}
+
+/**
+ * NetVscInitialize - Main entry point
+ */
+int NetVscInitialize(struct hv_driver *drv)
+{
+	struct netvsc_driver *driver = (struct netvsc_driver *)drv;
+
+	DPRINT_ENTER(NETVSC);
+
+	DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, "
+		   "sizeof(struct nvsp_message)=%zd, "
+		   "sizeof(struct vmtransfer_page_packet_header)=%zd",
+		   sizeof(struct hv_netvsc_packet),
+		   sizeof(struct nvsp_message),
+		   sizeof(struct vmtransfer_page_packet_header));
+
+	/* Make sure we are at least 2 pages since 1 page is used for control */
+	ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1));
+
+	drv->name = gDriverName;
+	memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid));
+
+	/* Make sure it is set by the caller */
+	ASSERT(driver->OnReceiveCallback);
+	ASSERT(driver->OnLinkStatusChanged);
+
+	/* Setup the dispatch table */
+	driver->Base.OnDeviceAdd	= NetVscOnDeviceAdd;
+	driver->Base.OnDeviceRemove	= NetVscOnDeviceRemove;
+	driver->Base.OnCleanup		= NetVscOnCleanup;
+
+	driver->OnSend			= NetVscOnSend;
+
+	RndisFilterInit(driver);
+
+	DPRINT_EXIT(NETVSC);
+
+	return 0;
+}
+
+static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device)
+{
+	int ret = 0;
+	struct netvsc_device *netDevice;
+	struct nvsp_message *initPacket;
+
+	DPRINT_ENTER(NETVSC);
+
+	netDevice = GetOutboundNetDevice(Device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "unable to get net device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(NETVSC);
+		return -1;
+	}
+	ASSERT(netDevice->ReceiveBufferSize > 0);
+	/* page-size grandularity */
+	ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0);
+
+	netDevice->ReceiveBuffer =
+		osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT);
+	if (!netDevice->ReceiveBuffer) {
+		DPRINT_ERR(NETVSC,
+			   "unable to allocate receive buffer of size %d",
+			   netDevice->ReceiveBufferSize);
+		ret = -1;
+		goto Cleanup;
+	}
+	/* page-aligned buffer */
+	ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) ==
+		0);
+
+	DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL...");
+
+	/*
+	 * Establish the gpadl handle for this buffer on this
+	 * channel.  Note: This call uses the vmbus connection rather
+	 * than the channel to establish the gpadl handle.
+	 */
+	ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device,
+					netDevice->ReceiveBuffer,
+					netDevice->ReceiveBufferSize,
+					&netDevice->ReceiveBufferGpadlHandle);
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC,
+			   "unable to establish receive buffer's gpadl");
+		goto Cleanup;
+	}
+
+	/* osd_WaitEventWait(ext->ChannelInitEvent); */
+
+	/* Notify the NetVsp of the gpadl handle */
+	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer...");
+
+	initPacket = &netDevice->ChannelInitPacket;
+
+	memset(initPacket, 0, sizeof(struct nvsp_message));
+
+	initPacket->Header.MessageType = NvspMessage1TypeSendReceiveBuffer;
+	initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->ReceiveBufferGpadlHandle;
+	initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID;
+
+	/* Send the gpadl notification request */
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				initPacket,
+				sizeof(struct nvsp_message),
+				(unsigned long)initPacket,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC,
+			   "unable to send receive buffer's gpadl to netvsp");
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(netDevice->ChannelInitEvent);
+
+	/* Check the response */
+	if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) {
+		DPRINT_ERR(NETVSC, "Unable to complete receive buffer "
+			   "initialzation with NetVsp - status %d",
+			   initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status);
+		ret = -1;
+		goto Cleanup;
+	}
+
+	/* Parse the response */
+	ASSERT(netDevice->ReceiveSectionCount == 0);
+	ASSERT(netDevice->ReceiveSections == NULL);
+
+	netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections;
+
+	netDevice->ReceiveSections = kmalloc(netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL);
+	if (netDevice->ReceiveSections == NULL) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	memcpy(netDevice->ReceiveSections,
+		initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Sections,
+		netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section));
+
+	DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, "
+		    "endoffset %d, suballoc size %d, num suballocs %d)",
+		    netDevice->ReceiveSectionCount,
+		    netDevice->ReceiveSections[0].Offset,
+		    netDevice->ReceiveSections[0].EndOffset,
+		    netDevice->ReceiveSections[0].SubAllocationSize,
+		    netDevice->ReceiveSections[0].NumSubAllocations);
+
+	/*
+	 * For 1st release, there should only be 1 section that represents the
+	 * entire receive buffer
+	 */
+	if (netDevice->ReceiveSectionCount != 1 ||
+	    netDevice->ReceiveSections->Offset != 0) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	goto Exit;
+
+Cleanup:
+	NetVscDestroyReceiveBuffer(netDevice);
+
+Exit:
+	PutNetDevice(Device);
+	DPRINT_EXIT(NETVSC);
+	return ret;
+}
+
+static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device)
+{
+	int ret = 0;
+	struct netvsc_device *netDevice;
+	struct nvsp_message *initPacket;
+
+	DPRINT_ENTER(NETVSC);
+
+	netDevice = GetOutboundNetDevice(Device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "unable to get net device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(NETVSC);
+		return -1;
+	}
+	ASSERT(netDevice->SendBufferSize > 0);
+	/* page-size grandularity */
+	ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0);
+
+	netDevice->SendBuffer =
+		osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT);
+	if (!netDevice->SendBuffer) {
+		DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d",
+			   netDevice->SendBufferSize);
+		ret = -1;
+		goto Cleanup;
+	}
+	/* page-aligned buffer */
+	ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0);
+
+	DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL...");
+
+	/*
+	 * Establish the gpadl handle for this buffer on this
+	 * channel.  Note: This call uses the vmbus connection rather
+	 * than the channel to establish the gpadl handle.
+	 */
+	ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device,
+					netDevice->SendBuffer,
+					netDevice->SendBufferSize,
+					&netDevice->SendBufferGpadlHandle);
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl");
+		goto Cleanup;
+	}
+
+	/* osd_WaitEventWait(ext->ChannelInitEvent); */
+
+	/* Notify the NetVsp of the gpadl handle */
+	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer...");
+
+	initPacket = &netDevice->ChannelInitPacket;
+
+	memset(initPacket, 0, sizeof(struct nvsp_message));
+
+	initPacket->Header.MessageType = NvspMessage1TypeSendSendBuffer;
+	initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->SendBufferGpadlHandle;
+	initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_SEND_BUFFER_ID;
+
+	/* Send the gpadl notification request */
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				initPacket, sizeof(struct nvsp_message),
+				(unsigned long)initPacket,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC,
+			   "unable to send receive buffer's gpadl to netvsp");
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(netDevice->ChannelInitEvent);
+
+	/* Check the response */
+	if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) {
+		DPRINT_ERR(NETVSC, "Unable to complete send buffer "
+			   "initialzation with NetVsp - status %d",
+			   initPacket->Messages.Version1Messages.SendSendBufferComplete.Status);
+		ret = -1;
+		goto Cleanup;
+	}
+
+	netDevice->SendSectionSize = initPacket->Messages.Version1Messages.SendSendBufferComplete.SectionSize;
+
+	goto Exit;
+
+Cleanup:
+	NetVscDestroySendBuffer(netDevice);
+
+Exit:
+	PutNetDevice(Device);
+	DPRINT_EXIT(NETVSC);
+	return ret;
+}
+
+static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice)
+{
+	struct nvsp_message *revokePacket;
+	int ret = 0;
+
+	DPRINT_ENTER(NETVSC);
+
+	/*
+	 * If we got a section count, it means we received a
+	 * SendReceiveBufferComplete msg (ie sent
+	 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
+	 * to send a revoke msg here
+	 */
+	if (NetDevice->ReceiveSectionCount) {
+		DPRINT_INFO(NETVSC,
+			    "Sending NvspMessage1TypeRevokeReceiveBuffer...");
+
+		/* Send the revoke receive buffer */
+		revokePacket = &NetDevice->RevokePacket;
+		memset(revokePacket, 0, sizeof(struct nvsp_message));
+
+		revokePacket->Header.MessageType = NvspMessage1TypeRevokeReceiveBuffer;
+		revokePacket->Messages.Version1Messages.RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID;
+
+		ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket(
+						NetDevice->Device,
+						revokePacket,
+						sizeof(struct nvsp_message),
+						(unsigned long)revokePacket,
+						VmbusPacketTypeDataInBand, 0);
+		/*
+		 * If we failed here, we might as well return and
+		 * have a leak rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			DPRINT_ERR(NETVSC, "unable to send revoke receive "
+				   "buffer to netvsp");
+			DPRINT_EXIT(NETVSC);
+			return -1;
+		}
+	}
+
+	/* Teardown the gpadl on the vsp end */
+	if (NetDevice->ReceiveBufferGpadlHandle) {
+		DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL...");
+
+		ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(
+					NetDevice->Device,
+					NetDevice->ReceiveBufferGpadlHandle);
+
+		/* If we failed here, we might as well return and have a leak rather than continue and a bugchk */
+		if (ret != 0) {
+			DPRINT_ERR(NETVSC,
+				   "unable to teardown receive buffer's gpadl");
+			DPRINT_EXIT(NETVSC);
+			return -1;
+		}
+		NetDevice->ReceiveBufferGpadlHandle = 0;
+	}
+
+	if (NetDevice->ReceiveBuffer) {
+		DPRINT_INFO(NETVSC, "Freeing up receive buffer...");
+
+		/* Free up the receive buffer */
+		osd_PageFree(NetDevice->ReceiveBuffer,
+			     NetDevice->ReceiveBufferSize >> PAGE_SHIFT);
+		NetDevice->ReceiveBuffer = NULL;
+	}
+
+	if (NetDevice->ReceiveSections) {
+		NetDevice->ReceiveSectionCount = 0;
+		kfree(NetDevice->ReceiveSections);
+		NetDevice->ReceiveSections = NULL;
+	}
+
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice)
+{
+	struct nvsp_message *revokePacket;
+	int ret = 0;
+
+	DPRINT_ENTER(NETVSC);
+
+	/*
+	 * If we got a section count, it means we received a
+	 *  SendReceiveBufferComplete msg (ie sent
+	 *  NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
+	 *  to send a revoke msg here
+	 */
+	if (NetDevice->SendSectionSize) {
+		DPRINT_INFO(NETVSC,
+			    "Sending NvspMessage1TypeRevokeSendBuffer...");
+
+		/* Send the revoke send buffer */
+		revokePacket = &NetDevice->RevokePacket;
+		memset(revokePacket, 0, sizeof(struct nvsp_message));
+
+		revokePacket->Header.MessageType = NvspMessage1TypeRevokeSendBuffer;
+		revokePacket->Messages.Version1Messages.RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID;
+
+		ret = NetDevice->Device->Driver->VmbusChannelInterface.SendPacket(NetDevice->Device,
+					revokePacket,
+					sizeof(struct nvsp_message),
+					(unsigned long)revokePacket,
+					VmbusPacketTypeDataInBand, 0);
+		/*
+		 * If we failed here, we might as well return and have a leak
+		 * rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			DPRINT_ERR(NETVSC, "unable to send revoke send buffer "
+				   "to netvsp");
+			DPRINT_EXIT(NETVSC);
+			return -1;
+		}
+	}
+
+	/* Teardown the gpadl on the vsp end */
+	if (NetDevice->SendBufferGpadlHandle) {
+		DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL...");
+
+		ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(NetDevice->Device, NetDevice->SendBufferGpadlHandle);
+
+		/*
+		 * If we failed here, we might as well return and have a leak
+		 * rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			DPRINT_ERR(NETVSC, "unable to teardown send buffer's "
+				   "gpadl");
+			DPRINT_EXIT(NETVSC);
+			return -1;
+		}
+		NetDevice->SendBufferGpadlHandle = 0;
+	}
+
+	if (NetDevice->SendBuffer) {
+		DPRINT_INFO(NETVSC, "Freeing up send buffer...");
+
+		/* Free up the receive buffer */
+		osd_PageFree(NetDevice->SendBuffer,
+			     NetDevice->SendBufferSize >> PAGE_SHIFT);
+		NetDevice->SendBuffer = NULL;
+	}
+
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+
+static int NetVscConnectToVsp(struct hv_device *Device)
+{
+	int ret;
+	struct netvsc_device *netDevice;
+	struct nvsp_message *initPacket;
+	int ndisVersion;
+
+	DPRINT_ENTER(NETVSC);
+
+	netDevice = GetOutboundNetDevice(Device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "unable to get net device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(NETVSC);
+		return -1;
+	}
+
+	initPacket = &netDevice->ChannelInitPacket;
+
+	memset(initPacket, 0, sizeof(struct nvsp_message));
+	initPacket->Header.MessageType = NvspMessageTypeInit;
+	initPacket->Messages.InitMessages.Init.MinProtocolVersion = NVSP_MIN_PROTOCOL_VERSION;
+	initPacket->Messages.InitMessages.Init.MaxProtocolVersion = NVSP_MAX_PROTOCOL_VERSION;
+
+	DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit...");
+
+	/* Send the init request */
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				initPacket,
+				sizeof(struct nvsp_message),
+				(unsigned long)initPacket,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit");
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(netDevice->ChannelInitEvent);
+
+	/* Now, check the response */
+	/* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */
+	DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)",
+		initPacket->Messages.InitMessages.InitComplete.Status,
+		initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength);
+
+	if (initPacket->Messages.InitMessages.InitComplete.Status !=
+	    NvspStatusSuccess) {
+		DPRINT_ERR(NETVSC,
+			"unable to initialize with netvsp (status 0x%x)",
+			initPacket->Messages.InitMessages.InitComplete.Status);
+		ret = -1;
+		goto Cleanup;
+	}
+
+	if (initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) {
+		DPRINT_ERR(NETVSC, "unable to initialize with netvsp "
+			   "(version expected 1 got %d)",
+			   initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion);
+		ret = -1;
+		goto Cleanup;
+	}
+	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion...");
+
+	/* Send the ndis version */
+	memset(initPacket, 0, sizeof(struct nvsp_message));
+
+	ndisVersion = 0x00050000;
+
+	initPacket->Header.MessageType = NvspMessage1TypeSendNdisVersion;
+	initPacket->Messages.Version1Messages.SendNdisVersion.NdisMajorVersion =
+				(ndisVersion & 0xFFFF0000) >> 16;
+	initPacket->Messages.Version1Messages.SendNdisVersion.NdisMinorVersion =
+				ndisVersion & 0xFFFF;
+
+	/* Send the init request */
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+					initPacket,
+					sizeof(struct nvsp_message),
+					(unsigned long)initPacket,
+					VmbusPacketTypeDataInBand, 0);
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC,
+			   "unable to send NvspMessage1TypeSendNdisVersion");
+		ret = -1;
+		goto Cleanup;
+	}
+	/*
+	 * BUGBUG - We have to wait for the above msg since the
+	 * netvsp uses KMCL which acknowledges packet (completion
+	 * packet) since our Vmbus always set the
+	 * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag
+	 */
+	 /* osd_WaitEventWait(NetVscChannel->ChannelInitEvent); */
+
+	/* Post the big receive buffer to NetVSP */
+	ret = NetVscInitializeReceiveBufferWithNetVsp(Device);
+	if (ret == 0)
+		ret = NetVscInitializeSendBufferWithNetVsp(Device);
+
+Cleanup:
+	PutNetDevice(Device);
+	DPRINT_EXIT(NETVSC);
+	return ret;
+}
+
+static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice)
+{
+	DPRINT_ENTER(NETVSC);
+
+	NetVscDestroyReceiveBuffer(NetDevice);
+	NetVscDestroySendBuffer(NetDevice);
+
+	DPRINT_EXIT(NETVSC);
+}
+
+/**
+ * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added
+ */
+static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
+{
+	int ret = 0;
+	int i;
+	struct netvsc_device *netDevice;
+	struct hv_netvsc_packet *packet, *pos;
+	struct netvsc_driver *netDriver =
+				(struct netvsc_driver *)Device->Driver;
+
+	DPRINT_ENTER(NETVSC);
+
+	netDevice = AllocNetDevice(Device);
+	if (!netDevice) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice);
+
+	/* Initialize the NetVSC channel extension */
+	netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE;
+	spin_lock_init(&netDevice->receive_packet_list_lock);
+
+	netDevice->SendBufferSize = NETVSC_SEND_BUFFER_SIZE;
+
+	INIT_LIST_HEAD(&netDevice->ReceivePacketList);
+
+	for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
+		packet = kzalloc(sizeof(struct hv_netvsc_packet) +
+				 (NETVSC_RECEIVE_SG_COUNT *
+				  sizeof(struct hv_page_buffer)), GFP_KERNEL);
+		if (!packet) {
+			DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts "
+				   "for receive pool (wanted %d got %d)",
+				   NETVSC_RECEIVE_PACKETLIST_COUNT, i);
+			break;
+		}
+		list_add_tail(&packet->ListEntry,
+			      &netDevice->ReceivePacketList);
+	}
+	netDevice->ChannelInitEvent = osd_WaitEventCreate();
+
+	/* Open the channel */
+	ret = Device->Driver->VmbusChannelInterface.Open(Device,
+						netDriver->RingBufferSize,
+						netDriver->RingBufferSize,
+						NULL, 0,
+						NetVscOnChannelCallback,
+						Device);
+
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC, "unable to open channel: %d", ret);
+		ret = -1;
+		goto Cleanup;
+	}
+
+	/* Channel is opened */
+	DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***");
+
+	/* Connect with the NetVsp */
+	ret = NetVscConnectToVsp(Device);
+	if (ret != 0) {
+		DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret);
+		ret = -1;
+		goto Close;
+	}
+
+	DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***",
+		    ret);
+
+	DPRINT_EXIT(NETVSC);
+	return ret;
+
+Close:
+	/* Now, we can close the channel safely */
+	Device->Driver->VmbusChannelInterface.Close(Device);
+
+Cleanup:
+
+	if (netDevice) {
+		kfree(netDevice->ChannelInitEvent);
+
+		list_for_each_entry_safe(packet, pos,
+					 &netDevice->ReceivePacketList,
+					 ListEntry) {
+			list_del(&packet->ListEntry);
+			kfree(packet);
+		}
+
+		ReleaseOutboundNetDevice(Device);
+		ReleaseInboundNetDevice(Device);
+
+		FreeNetDevice(netDevice);
+	}
+
+	DPRINT_EXIT(NETVSC);
+	return ret;
+}
+
+/**
+ * NetVscOnDeviceRemove - Callback when the root bus device is removed
+ */
+static int NetVscOnDeviceRemove(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice;
+	struct hv_netvsc_packet *netvscPacket, *pos;
+
+	DPRINT_ENTER(NETVSC);
+
+	DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...",
+		    Device->Extension);
+
+	/* Stop outbound traffic ie sends and receives completions */
+	netDevice = ReleaseOutboundNetDevice(Device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "No net device present!!");
+		return -1;
+	}
+
+	/* Wait for all send completions */
+	while (atomic_read(&netDevice->NumOutstandingSends)) {
+		DPRINT_INFO(NETVSC, "waiting for %d requests to complete...",
+			    atomic_read(&netDevice->NumOutstandingSends));
+		udelay(100);
+	}
+
+	DPRINT_INFO(NETVSC, "Disconnecting from netvsp...");
+
+	NetVscDisconnectFromVsp(netDevice);
+
+	DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...",
+		    Device->Extension);
+
+	/* Stop inbound traffic ie receives and sends completions */
+	netDevice = ReleaseInboundNetDevice(Device);
+
+	/* At this point, no one should be accessing netDevice except in here */
+	DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice);
+
+	/* Now, we can close the channel safely */
+	Device->Driver->VmbusChannelInterface.Close(Device);
+
+	/* Release all resources */
+	list_for_each_entry_safe(netvscPacket, pos,
+				 &netDevice->ReceivePacketList, ListEntry) {
+		list_del(&netvscPacket->ListEntry);
+		kfree(netvscPacket);
+	}
+
+	kfree(netDevice->ChannelInitEvent);
+	FreeNetDevice(netDevice);
+
+	DPRINT_EXIT(NETVSC);
+	return 0;
+}
+
+/**
+ * NetVscOnCleanup - Perform any cleanup when the driver is removed
+ */
+static void NetVscOnCleanup(struct hv_driver *drv)
+{
+	DPRINT_ENTER(NETVSC);
+	DPRINT_EXIT(NETVSC);
+}
+
+static void NetVscOnSendCompletion(struct hv_device *Device,
+				   struct vmpacket_descriptor *Packet)
+{
+	struct netvsc_device *netDevice;
+	struct nvsp_message *nvspPacket;
+	struct hv_netvsc_packet *nvscPacket;
+
+	DPRINT_ENTER(NETVSC);
+
+	netDevice = GetInboundNetDevice(Device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "unable to get net device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(NETVSC);
+		return;
+	}
+
+	nvspPacket = (struct nvsp_message *)((unsigned long)Packet + (Packet->DataOffset8 << 3));
+
+	DPRINT_DBG(NETVSC, "send completion packet - type %d",
+		   nvspPacket->Header.MessageType);
+
+	if ((nvspPacket->Header.MessageType == NvspMessageTypeInitComplete) ||
+	    (nvspPacket->Header.MessageType ==
+	     NvspMessage1TypeSendReceiveBufferComplete) ||
+	    (nvspPacket->Header.MessageType ==
+	     NvspMessage1TypeSendSendBufferComplete)) {
+		/* Copy the response back */
+		memcpy(&netDevice->ChannelInitPacket, nvspPacket,
+		       sizeof(struct nvsp_message));
+		osd_WaitEventSet(netDevice->ChannelInitEvent);
+	} else if (nvspPacket->Header.MessageType ==
+		   NvspMessage1TypeSendRNDISPacketComplete) {
+		/* Get the send context */
+		nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId;
+		ASSERT(nvscPacket);
+
+		/* Notify the layer above us */
+		nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext);
+
+		atomic_dec(&netDevice->NumOutstandingSends);
+	} else {
+		DPRINT_ERR(NETVSC, "Unknown send completion packet type - "
+			   "%d received!!", nvspPacket->Header.MessageType);
+	}
+
+	PutNetDevice(Device);
+	DPRINT_EXIT(NETVSC);
+}
+
+static int NetVscOnSend(struct hv_device *Device,
+			struct hv_netvsc_packet *Packet)
+{
+	struct netvsc_device *netDevice;
+	int ret = 0;
+
+	struct nvsp_message sendMessage;
+
+	DPRINT_ENTER(NETVSC);
+
+	netDevice = GetOutboundNetDevice(Device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
+			   "ignoring outbound packets", netDevice);
+		DPRINT_EXIT(NETVSC);
+		return -2;
+	}
+
+	sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket;
+	if (Packet->IsDataPacket) {
+		/* 0 is RMC_DATA; */
+		sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0;
+	} else {
+		/* 1 is RMC_CONTROL; */
+		sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1;
+	}
+
+	/* Not using send buffer section */
+	sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF;
+	sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0;
+
+	if (Packet->PageBufferCount) {
+		ret = Device->Driver->VmbusChannelInterface.SendPacketPageBuffer(
+					Device, Packet->PageBuffers,
+					Packet->PageBufferCount,
+					&sendMessage,
+					sizeof(struct nvsp_message),
+					(unsigned long)Packet);
+	} else {
+		ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				&sendMessage,
+				sizeof(struct nvsp_message),
+				(unsigned long)Packet,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	}
+
+	if (ret != 0)
+		DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d",
+			   Packet, ret);
+
+	atomic_inc(&netDevice->NumOutstandingSends);
+	PutNetDevice(Device);
+
+	DPRINT_EXIT(NETVSC);
+	return ret;
+}
+
+static void NetVscOnReceive(struct hv_device *Device,
+			    struct vmpacket_descriptor *Packet)
+{
+	struct netvsc_device *netDevice;
+	struct vmtransfer_page_packet_header *vmxferpagePacket;
+	struct nvsp_message *nvspPacket;
+	struct hv_netvsc_packet *netvscPacket = NULL;
+	unsigned long start;
+	unsigned long end, endVirtual;
+	/* struct netvsc_driver *netvscDriver; */
+	struct xferpage_packet *xferpagePacket = NULL;
+	int i, j;
+	int count = 0, bytesRemain = 0;
+	unsigned long flags;
+	LIST_HEAD(listHead);
+
+	DPRINT_ENTER(NETVSC);
+
+	netDevice = GetInboundNetDevice(Device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "unable to get net device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(NETVSC);
+		return;
+	}
+
+	/*
+	 * All inbound packets other than send completion should be xfer page
+	 * packet
+	 */
+	if (Packet->Type != VmbusPacketTypeDataUsingTransferPages) {
+		DPRINT_ERR(NETVSC, "Unknown packet type received - %d",
+			   Packet->Type);
+		PutNetDevice(Device);
+		return;
+	}
+
+	nvspPacket = (struct nvsp_message *)((unsigned long)Packet +
+			(Packet->DataOffset8 << 3));
+
+	/* Make sure this is a valid nvsp packet */
+	if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket) {
+		DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d",
+			   nvspPacket->Header.MessageType);
+		PutNetDevice(Device);
+		return;
+	}
+
+	DPRINT_DBG(NETVSC, "NVSP packet received - type %d",
+		   nvspPacket->Header.MessageType);
+
+	vmxferpagePacket = (struct vmtransfer_page_packet_header *)Packet;
+
+	if (vmxferpagePacket->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) {
+		DPRINT_ERR(NETVSC, "Invalid xfer page set id - "
+			   "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
+			   vmxferpagePacket->TransferPageSetId);
+		PutNetDevice(Device);
+		return;
+	}
+
+	DPRINT_DBG(NETVSC, "xfer page - range count %d",
+		   vmxferpagePacket->RangeCount);
+
+	/*
+	 * Grab free packets (range count + 1) to represent this xfer
+	 * page packet. +1 to represent the xfer page packet itself.
+	 * We grab it here so that we know exactly how many we can
+	 * fulfil
+	 */
+	spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
+	while (!list_empty(&netDevice->ReceivePacketList)) {
+		list_move_tail(&netDevice->ReceivePacketList, &listHead);
+		if (++count == vmxferpagePacket->RangeCount + 1)
+			break;
+	}
+	spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
+
+	/*
+	 * We need at least 2 netvsc pkts (1 to represent the xfer
+	 * page and at least 1 for the range) i.e. we can handled
+	 * some of the xfer page packet ranges...
+	 */
+	if (count < 2) {
+		DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. "
+			   "Dropping this xfer page packet completely!",
+			   count, vmxferpagePacket->RangeCount + 1);
+
+		/* Return it to the freelist */
+		spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
+		for (i = count; i != 0; i--) {
+			list_move_tail(&listHead,
+				       &netDevice->ReceivePacketList);
+		}
+		spin_unlock_irqrestore(&netDevice->receive_packet_list_lock,
+				       flags);
+
+		NetVscSendReceiveCompletion(Device,
+					    vmxferpagePacket->d.TransactionId);
+
+		PutNetDevice(Device);
+		return;
+	}
+
+	/* Remove the 1st packet to represent the xfer page packet itself */
+	xferpagePacket = list_entry(&listHead, struct xferpage_packet,
+				    ListEntry);
+	list_del(&xferpagePacket->ListEntry);
+
+	/* This is how much we can satisfy */
+	xferpagePacket->Count = count - 1;
+	ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <=
+		vmxferpagePacket->RangeCount);
+
+	if (xferpagePacket->Count != vmxferpagePacket->RangeCount) {
+		DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer "
+			    "page...got %d", vmxferpagePacket->RangeCount,
+			    xferpagePacket->Count);
+	}
+
+	/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
+	for (i = 0; i < (count - 1); i++) {
+		netvscPacket = list_entry(&listHead, struct hv_netvsc_packet,
+					  ListEntry);
+		list_del(&netvscPacket->ListEntry);
+
+		/* Initialize the netvsc packet */
+		netvscPacket->XferPagePacket = xferpagePacket;
+		netvscPacket->Completion.Recv.OnReceiveCompletion =
+					NetVscOnReceiveCompletion;
+		netvscPacket->Completion.Recv.ReceiveCompletionContext =
+					netvscPacket;
+		netvscPacket->Device = Device;
+		/* Save this so that we can send it back */
+		netvscPacket->Completion.Recv.ReceiveCompletionTid =
+					vmxferpagePacket->d.TransactionId;
+
+		netvscPacket->TotalDataBufferLength =
+					vmxferpagePacket->Ranges[i].ByteCount;
+		netvscPacket->PageBufferCount = 1;
+
+		ASSERT(vmxferpagePacket->Ranges[i].ByteOffset +
+			vmxferpagePacket->Ranges[i].ByteCount <
+			netDevice->ReceiveBufferSize);
+
+		netvscPacket->PageBuffers[0].Length =
+					vmxferpagePacket->Ranges[i].ByteCount;
+
+		start = virt_to_phys((void *)((unsigned long)netDevice->ReceiveBuffer + vmxferpagePacket->Ranges[i].ByteOffset));
+
+		netvscPacket->PageBuffers[0].Pfn = start >> PAGE_SHIFT;
+		endVirtual = (unsigned long)netDevice->ReceiveBuffer
+		    + vmxferpagePacket->Ranges[i].ByteOffset
+		    + vmxferpagePacket->Ranges[i].ByteCount - 1;
+		end = virt_to_phys((void *)endVirtual);
+
+		/* Calculate the page relative offset */
+		netvscPacket->PageBuffers[0].Offset =
+			vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE - 1);
+		if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) {
+			/* Handle frame across multiple pages: */
+			netvscPacket->PageBuffers[0].Length =
+				(netvscPacket->PageBuffers[0].Pfn << PAGE_SHIFT)
+				+ PAGE_SIZE - start;
+			bytesRemain = netvscPacket->TotalDataBufferLength -
+					netvscPacket->PageBuffers[0].Length;
+			for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) {
+				netvscPacket->PageBuffers[j].Offset = 0;
+				if (bytesRemain <= PAGE_SIZE) {
+					netvscPacket->PageBuffers[j].Length = bytesRemain;
+					bytesRemain = 0;
+				} else {
+					netvscPacket->PageBuffers[j].Length = PAGE_SIZE;
+					bytesRemain -= PAGE_SIZE;
+				}
+				netvscPacket->PageBuffers[j].Pfn =
+				    virt_to_phys((void *)(endVirtual - bytesRemain)) >> PAGE_SHIFT;
+				netvscPacket->PageBufferCount++;
+				if (bytesRemain == 0)
+					break;
+			}
+			ASSERT(bytesRemain == 0);
+		}
+		DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => "
+			   "(pfn %llx, offset %u, len %u)", i,
+			   vmxferpagePacket->Ranges[i].ByteOffset,
+			   vmxferpagePacket->Ranges[i].ByteCount,
+			   netvscPacket->PageBuffers[0].Pfn,
+			   netvscPacket->PageBuffers[0].Offset,
+			   netvscPacket->PageBuffers[0].Length);
+
+		/* Pass it to the upper layer */
+		((struct netvsc_driver *)Device->Driver)->OnReceiveCallback(Device, netvscPacket);
+
+		NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext);
+	}
+
+	ASSERT(list_empty(&listHead));
+
+	PutNetDevice(Device);
+	DPRINT_EXIT(NETVSC);
+}
+
+static void NetVscSendReceiveCompletion(struct hv_device *Device,
+					u64 TransactionId)
+{
+	struct nvsp_message recvcompMessage;
+	int retries = 0;
+	int ret;
+
+	DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx",
+		   TransactionId);
+
+	recvcompMessage.Header.MessageType =
+				NvspMessage1TypeSendRNDISPacketComplete;
+
+	/* FIXME: Pass in the status */
+	recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess;
+
+retry_send_cmplt:
+	/* Send the completion */
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+					&recvcompMessage,
+					sizeof(struct nvsp_message),
+					TransactionId,
+					VmbusPacketTypeCompletion, 0);
+	if (ret == 0) {
+		/* success */
+		/* no-op */
+	} else if (ret == -1) {
+		/* no more room...wait a bit and attempt to retry 3 times */
+		retries++;
+		DPRINT_ERR(NETVSC, "unable to send receive completion pkt "
+			   "(tid %llx)...retrying %d", TransactionId, retries);
+
+		if (retries < 4) {
+			udelay(100);
+			goto retry_send_cmplt;
+		} else {
+			DPRINT_ERR(NETVSC, "unable to send receive completion "
+				  "pkt (tid %llx)...give up retrying",
+				  TransactionId);
+		}
+	} else {
+		DPRINT_ERR(NETVSC, "unable to send receive completion pkt - "
+			   "%llx", TransactionId);
+	}
+}
+
+/* Send a receive completion packet to RNDIS device (ie NetVsp) */
+static void NetVscOnReceiveCompletion(void *Context)
+{
+	struct hv_netvsc_packet *packet = Context;
+	struct hv_device *device = (struct hv_device *)packet->Device;
+	struct netvsc_device *netDevice;
+	u64 transactionId = 0;
+	bool fSendReceiveComp = false;
+	unsigned long flags;
+
+	DPRINT_ENTER(NETVSC);
+
+	ASSERT(packet->XferPagePacket);
+
+	/*
+	 * Even though it seems logical to do a GetOutboundNetDevice() here to
+	 * send out receive completion, we are using GetInboundNetDevice()
+	 * since we may have disable outbound traffic already.
+	 */
+	netDevice = GetInboundNetDevice(device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "unable to get net device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(NETVSC);
+		return;
+	}
+
+	/* Overloading use of the lock. */
+	spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
+
+	ASSERT(packet->XferPagePacket->Count > 0);
+	packet->XferPagePacket->Count--;
+
+	/*
+	 * Last one in the line that represent 1 xfer page packet.
+	 * Return the xfer page packet itself to the freelist
+	 */
+	if (packet->XferPagePacket->Count == 0) {
+		fSendReceiveComp = true;
+		transactionId = packet->Completion.Recv.ReceiveCompletionTid;
+		list_add_tail(&packet->XferPagePacket->ListEntry,
+			      &netDevice->ReceivePacketList);
+
+	}
+
+	/* Put the packet back */
+	list_add_tail(&packet->ListEntry, &netDevice->ReceivePacketList);
+	spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
+
+	/* Send a receive completion for the xfer page packet */
+	if (fSendReceiveComp)
+		NetVscSendReceiveCompletion(device, transactionId);
+
+	PutNetDevice(device);
+	DPRINT_EXIT(NETVSC);
+}
+
+void NetVscOnChannelCallback(void *Context)
+{
+	const int netPacketSize = 2048;
+	int ret;
+	struct hv_device *device = Context;
+	struct netvsc_device *netDevice;
+	u32 bytesRecvd;
+	u64 requestId;
+	unsigned char packet[netPacketSize];
+	struct vmpacket_descriptor *desc;
+	unsigned char *buffer = packet;
+	int bufferlen = netPacketSize;
+
+
+	DPRINT_ENTER(NETVSC);
+
+	ASSERT(device);
+
+	netDevice = GetInboundNetDevice(device);
+	if (!netDevice) {
+		DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
+			   "ignoring inbound packets", netDevice);
+		DPRINT_EXIT(NETVSC);
+		return;
+	}
+
+	do {
+		ret = device->Driver->VmbusChannelInterface.RecvPacketRaw(
+						device, buffer, bufferlen,
+						&bytesRecvd, &requestId);
+		if (ret == 0) {
+			if (bytesRecvd > 0) {
+				DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx",
+					   bytesRecvd, requestId);
+
+				desc = (struct vmpacket_descriptor *)buffer;
+				switch (desc->Type) {
+				case VmbusPacketTypeCompletion:
+					NetVscOnSendCompletion(device, desc);
+					break;
+
+				case VmbusPacketTypeDataUsingTransferPages:
+					NetVscOnReceive(device, desc);
+					break;
+
+				default:
+					DPRINT_ERR(NETVSC,
+						   "unhandled packet type %d, "
+						   "tid %llx len %d\n",
+						   desc->Type, requestId,
+						   bytesRecvd);
+					break;
+				}
+
+				/* reset */
+				if (bufferlen > netPacketSize) {
+					kfree(buffer);
+					buffer = packet;
+					bufferlen = netPacketSize;
+				}
+			} else {
+				/* reset */
+				if (bufferlen > netPacketSize) {
+					kfree(buffer);
+					buffer = packet;
+					bufferlen = netPacketSize;
+				}
+
+				break;
+			}
+		} else if (ret == -2) {
+			/* Handle large packet */
+			buffer = kmalloc(bytesRecvd, GFP_ATOMIC);
+			if (buffer == NULL) {
+				/* Try again next time around */
+				DPRINT_ERR(NETVSC,
+					   "unable to allocate buffer of size "
+					   "(%d)!!", bytesRecvd);
+				break;
+			}
+
+			bufferlen = bytesRecvd;
+		} else {
+			ASSERT(0);
+		}
+	} while (1);
+
+	PutNetDevice(device);
+	DPRINT_EXIT(NETVSC);
+	return;
+}
diff --git a/drivers/staging/hv/NetVsc.h b/drivers/staging/hv/NetVsc.h
new file mode 100644
index 0000000..3e7112f
--- /dev/null
+++ b/drivers/staging/hv/NetVsc.h
@@ -0,0 +1,329 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _NETVSC_H_
+#define _NETVSC_H_
+
+#include <linux/list.h>
+#include "VmbusPacketFormat.h"
+#include "VmbusChannelInterface.h"
+#include "NetVscApi.h"
+
+
+#define NVSP_INVALID_PROTOCOL_VERSION	((u32)0xFFFFFFFF)
+
+#define NVSP_PROTOCOL_VERSION_1		2
+#define NVSP_MIN_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
+#define NVSP_MAX_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
+
+enum {
+	NvspMessageTypeNone = 0,
+
+	/* Init Messages */
+	NvspMessageTypeInit			= 1,
+	NvspMessageTypeInitComplete		= 2,
+
+	NvspVersionMessageStart			= 100,
+
+	/* Version 1 Messages */
+	NvspMessage1TypeSendNdisVersion		= NvspVersionMessageStart,
+
+	NvspMessage1TypeSendReceiveBuffer,
+	NvspMessage1TypeSendReceiveBufferComplete,
+	NvspMessage1TypeRevokeReceiveBuffer,
+
+	NvspMessage1TypeSendSendBuffer,
+	NvspMessage1TypeSendSendBufferComplete,
+	NvspMessage1TypeRevokeSendBuffer,
+
+	NvspMessage1TypeSendRNDISPacket,
+	NvspMessage1TypeSendRNDISPacketComplete,
+
+	/*
+	 * This should be set to the number of messages for the version with
+	 * the maximum number of messages.
+	 */
+	NvspNumMessagePerVersion		= 9,
+};
+
+enum {
+	NvspStatusNone = 0,
+	NvspStatusSuccess,
+	NvspStatusFailure,
+	NvspStatusProtocolVersionRangeTooNew,
+	NvspStatusProtocolVersionRangeTooOld,
+	NvspStatusInvalidRndisPacket,
+	NvspStatusBusy,
+	NvspStatusMax,
+};
+
+struct nvsp_message_header {
+	u32 MessageType;
+};
+
+/* Init Messages */
+
+/*
+ * This message is used by the VSC to initialize the channel after the channels
+ * has been opened. This message should never include anything other then
+ * versioning (i.e. this message will be the same for ever).
+ */
+struct nvsp_message_init {
+	u32 MinProtocolVersion;
+	u32 MaxProtocolVersion;
+} __attribute__((packed));
+
+/*
+ * This message is used by the VSP to complete the initialization of the
+ * channel. This message should never include anything other then versioning
+ * (i.e. this message will be the same for ever).
+ */
+struct nvsp_message_init_complete {
+	u32 NegotiatedProtocolVersion;
+	u32 MaximumMdlChainLength;
+	u32 Status;
+} __attribute__((packed));
+
+union nvsp_message_init_uber {
+	struct nvsp_message_init Init;
+	struct nvsp_message_init_complete InitComplete;
+} __attribute__((packed));
+
+/* Version 1 Messages */
+
+/*
+ * This message is used by the VSC to send the NDIS version to the VSP. The VSP
+ * can use this information when handling OIDs sent by the VSC.
+ */
+struct nvsp_1_message_send_ndis_version {
+	u32 NdisMajorVersion;
+	u32 NdisMinorVersion;
+} __attribute__((packed));
+
+/*
+ * This message is used by the VSC to send a receive buffer to the VSP. The VSP
+ * can then use the receive buffer to send data to the VSC.
+ */
+struct nvsp_1_message_send_receive_buffer {
+	u32 GpadlHandle;
+	u16 Id;
+} __attribute__((packed));
+
+struct nvsp_1_receive_buffer_section {
+	u32 Offset;
+	u32 SubAllocationSize;
+	u32 NumSubAllocations;
+	u32 EndOffset;
+} __attribute__((packed));
+
+/*
+ * This message is used by the VSP to acknowledge a receive buffer send by the
+ * VSC. This message must be sent by the VSP before the VSP uses the receive
+ * buffer.
+ */
+struct nvsp_1_message_send_receive_buffer_complete {
+	u32 Status;
+	u32 NumSections;
+
+	/*
+	 * The receive buffer is split into two parts, a large suballocation
+	 * section and a small suballocation section. These sections are then
+	 * suballocated by a certain size.
+	 */
+
+	/*
+	 * For example, the following break up of the receive buffer has 6
+	 * large suballocations and 10 small suballocations.
+	 */
+
+	/*
+	 * |            Large Section          |  |   Small Section   |
+	 * ------------------------------------------------------------
+	 * |     |     |     |     |     |     |  | | | | | | | | | | |
+	 * |                                      |
+	 *  LargeOffset                            SmallOffset
+	 */
+
+	struct nvsp_1_receive_buffer_section Sections[1];
+} __attribute__((packed));
+
+/*
+ * This message is sent by the VSC to revoke the receive buffer.  After the VSP
+ * completes this transaction, the vsp should never use the receive buffer
+ * again.
+ */
+struct nvsp_1_message_revoke_receive_buffer {
+	u16 Id;
+};
+
+/*
+ * This message is used by the VSC to send a send buffer to the VSP. The VSC
+ * can then use the send buffer to send data to the VSP.
+ */
+struct nvsp_1_message_send_send_buffer {
+	u32 GpadlHandle;
+	u16 Id;
+} __attribute__((packed));
+
+/*
+ * This message is used by the VSP to acknowledge a send buffer sent by the
+ * VSC. This message must be sent by the VSP before the VSP uses the sent
+ * buffer.
+ */
+struct nvsp_1_message_send_send_buffer_complete {
+	u32 Status;
+
+	/*
+	 * The VSC gets to choose the size of the send buffer and the VSP gets
+	 * to choose the sections size of the buffer.  This was done to enable
+	 * dynamic reconfigurations when the cost of GPA-direct buffers
+	 * decreases.
+	 */
+	u32 SectionSize;
+} __attribute__((packed));
+
+/*
+ * This message is sent by the VSC to revoke the send buffer.  After the VSP
+ * completes this transaction, the vsp should never use the send buffer again.
+ */
+struct nvsp_1_message_revoke_send_buffer {
+	u16 Id;
+};
+
+/*
+ * This message is used by both the VSP and the VSC to send a RNDIS message to
+ * the opposite channel endpoint.
+ */
+struct nvsp_1_message_send_rndis_packet {
+	/*
+	 * This field is specified by RNIDS. They assume there's two different
+	 * channels of communication. However, the Network VSP only has one.
+	 * Therefore, the channel travels with the RNDIS packet.
+	 */
+	u32 ChannelType;
+
+	/*
+	 * This field is used to send part or all of the data through a send
+	 * buffer. This values specifies an index into the send buffer. If the
+	 * index is 0xFFFFFFFF, then the send buffer is not being used and all
+	 * of the data was sent through other VMBus mechanisms.
+	 */
+	u32 SendBufferSectionIndex;
+	u32 SendBufferSectionSize;
+} __attribute__((packed));
+
+/*
+ * This message is used by both the VSP and the VSC to complete a RNDIS message
+ * to the opposite channel endpoint. At this point, the initiator of this
+ * message cannot use any resources associated with the original RNDIS packet.
+ */
+struct nvsp_1_message_send_rndis_packet_complete {
+	u32 Status;
+};
+
+union nvsp_1_message_uber {
+	struct nvsp_1_message_send_ndis_version SendNdisVersion;
+
+	struct nvsp_1_message_send_receive_buffer SendReceiveBuffer;
+	struct nvsp_1_message_send_receive_buffer_complete
+						SendReceiveBufferComplete;
+	struct nvsp_1_message_revoke_receive_buffer RevokeReceiveBuffer;
+
+	struct nvsp_1_message_send_send_buffer SendSendBuffer;
+	struct nvsp_1_message_send_send_buffer_complete SendSendBufferComplete;
+	struct nvsp_1_message_revoke_send_buffer RevokeSendBuffer;
+
+	struct nvsp_1_message_send_rndis_packet SendRNDISPacket;
+	struct nvsp_1_message_send_rndis_packet_complete
+						SendRNDISPacketComplete;
+} __attribute__((packed));
+
+union nvsp_all_messages {
+	union nvsp_message_init_uber InitMessages;
+	union nvsp_1_message_uber Version1Messages;
+} __attribute__((packed));
+
+/* ALL Messages */
+struct nvsp_message {
+	struct nvsp_message_header Header;
+	union nvsp_all_messages Messages;
+} __attribute__((packed));
+
+
+
+
+/* #define NVSC_MIN_PROTOCOL_VERSION		1 */
+/* #define NVSC_MAX_PROTOCOL_VERSION		1 */
+
+#define NETVSC_SEND_BUFFER_SIZE			(64*1024)	/* 64K */
+#define NETVSC_SEND_BUFFER_ID			0xface
+
+
+#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024)	/* 1MB */
+
+#define NETVSC_RECEIVE_BUFFER_ID		0xcafe
+
+#define NETVSC_RECEIVE_SG_COUNT			1
+
+/* Preallocated receive packets */
+#define NETVSC_RECEIVE_PACKETLIST_COUNT		256
+
+
+/* Per netvsc channel-specific */
+struct netvsc_device {
+	struct hv_device *Device;
+
+	atomic_t RefCount;
+	atomic_t NumOutstandingSends;
+	/*
+	 * List of free preallocated hv_netvsc_packet to represent receive
+	 * packet
+	 */
+	struct list_head ReceivePacketList;
+	spinlock_t receive_packet_list_lock;
+
+	/* Send buffer allocated by us but manages by NetVSP */
+	void *SendBuffer;
+	u32 SendBufferSize;
+	u32 SendBufferGpadlHandle;
+	u32 SendSectionSize;
+
+	/* Receive buffer allocated by us but manages by NetVSP */
+	void *ReceiveBuffer;
+	u32 ReceiveBufferSize;
+	u32 ReceiveBufferGpadlHandle;
+	u32 ReceiveSectionCount;
+	struct nvsp_1_receive_buffer_section *ReceiveSections;
+
+	/* Used for NetVSP initialization protocol */
+	struct osd_waitevent *ChannelInitEvent;
+	struct nvsp_message ChannelInitPacket;
+
+	struct nvsp_message RevokePacket;
+	/* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
+
+	/* Holds rndis device info */
+	void *Extension;
+};
+
+#endif /* _NETVSC_H_ */
diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/NetVscApi.h
new file mode 100644
index 0000000..1ce2b74
--- /dev/null
+++ b/drivers/staging/hv/NetVscApi.h
@@ -0,0 +1,123 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _NETVSC_API_H_
+#define _NETVSC_API_H_
+
+#include "VmbusApi.h"
+
+/* Defines */
+#define NETVSC_DEVICE_RING_BUFFER_SIZE	(64*PAGE_SIZE)
+#define HW_MACADDR_LEN			6
+
+/* Fwd declaration */
+struct hv_netvsc_packet;
+
+/* Represent the xfer page packet which contains 1 or more netvsc packet */
+struct xferpage_packet {
+	struct list_head ListEntry;
+
+	/* # of netvsc packets this xfer packet contains */
+	u32 Count;
+};
+
+/* The number of pages which are enough to cover jumbo frame buffer. */
+#define NETVSC_PACKET_MAXPAGE		4
+
+/*
+ * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
+ * within the RNDIS
+ */
+struct hv_netvsc_packet {
+	/* Bookkeeping stuff */
+	struct list_head ListEntry;
+
+	struct hv_device *Device;
+	bool IsDataPacket;
+
+	/*
+	 * Valid only for receives when we break a xfer page packet
+	 * into multiple netvsc packets
+	 */
+	struct xferpage_packet *XferPagePacket;
+
+	union {
+		struct{
+			u64 ReceiveCompletionTid;
+			void *ReceiveCompletionContext;
+			void (*OnReceiveCompletion)(void *context);
+		} Recv;
+		struct{
+			u64 SendCompletionTid;
+			void *SendCompletionContext;
+			void (*OnSendCompletion)(void *context);
+		} Send;
+	} Completion;
+
+	/* This points to the memory after PageBuffers */
+	void *Extension;
+
+	u32 TotalDataBufferLength;
+	/* Points to the send/receive buffer where the ethernet frame is */
+	u32 PageBufferCount;
+	struct hv_page_buffer PageBuffers[NETVSC_PACKET_MAXPAGE];
+};
+
+/* Represents the net vsc driver */
+struct netvsc_driver {
+	/* Must be the first field */
+	/* Which is a bug FIXME! */
+	struct hv_driver Base;
+
+	u32 RingBufferSize;
+	u32 RequestExtSize;
+
+	/* Additional num  of page buffers to allocate */
+	u32 AdditionalRequestPageBufferCount;
+
+	/*
+	 * This is set by the caller to allow us to callback when we
+	 * receive a packet from the "wire"
+	 */
+	int (*OnReceiveCallback)(struct hv_device *dev,
+				 struct hv_netvsc_packet *packet);
+	void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status);
+
+	/* Specific to this driver */
+	int (*OnOpen)(struct hv_device *dev);
+	int (*OnClose)(struct hv_device *dev);
+	int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet);
+
+	void *Context;
+};
+
+struct netvsc_device_info {
+    unsigned char MacAddr[6];
+    bool LinkState;	/* 0 - link up, 1 - link down */
+};
+
+/* Interface */
+int NetVscInitialize(struct hv_driver *drv);
+
+#endif /* _NETVSC_API_H_ */
diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/RingBuffer.c
new file mode 100644
index 0000000..f69ae33
--- /dev/null
+++ b/drivers/staging/hv/RingBuffer.c
@@ -0,0 +1,606 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include "osd.h"
+#include "logging.h"
+#include "RingBuffer.h"
+
+
+/* #defines */
+
+
+/* Amount of space to write to */
+#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r))?((z) - ((w) - (r))):((r) - (w))
+
+
+/*++
+
+Name:
+	GetRingBufferAvailBytes()
+
+Description:
+	Get number of bytes available to read and to write to
+	for the specified ring buffer
+
+--*/
+static inline void
+GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write)
+{
+	u32 read_loc,write_loc;
+
+	/* Capture the read/write indices before they changed */
+	read_loc = rbi->RingBuffer->ReadIndex;
+	write_loc = rbi->RingBuffer->WriteIndex;
+
+	*write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->RingDataSize);
+	*read = rbi->RingDataSize - *write;
+}
+
+/*++
+
+Name:
+	GetNextWriteLocation()
+
+Description:
+	Get the next write location for the specified ring buffer
+
+--*/
+static inline u32
+GetNextWriteLocation(RING_BUFFER_INFO* RingInfo)
+{
+	u32 next = RingInfo->RingBuffer->WriteIndex;
+
+	ASSERT(next < RingInfo->RingDataSize);
+
+	return next;
+}
+
+/*++
+
+Name:
+	SetNextWriteLocation()
+
+Description:
+	Set the next write location for the specified ring buffer
+
+--*/
+static inline void
+SetNextWriteLocation(RING_BUFFER_INFO* RingInfo, u32 NextWriteLocation)
+{
+	RingInfo->RingBuffer->WriteIndex = NextWriteLocation;
+}
+
+/*++
+
+Name:
+	GetNextReadLocation()
+
+Description:
+	Get the next read location for the specified ring buffer
+
+--*/
+static inline u32
+GetNextReadLocation(RING_BUFFER_INFO* RingInfo)
+{
+	u32 next = RingInfo->RingBuffer->ReadIndex;
+
+	ASSERT(next < RingInfo->RingDataSize);
+
+	return next;
+}
+
+/*++
+
+Name:
+	GetNextReadLocationWithOffset()
+
+Description:
+	Get the next read location + offset for the specified ring buffer.
+	This allows the caller to skip
+
+--*/
+static inline u32
+GetNextReadLocationWithOffset(RING_BUFFER_INFO* RingInfo, u32 Offset)
+{
+	u32 next = RingInfo->RingBuffer->ReadIndex;
+
+	ASSERT(next < RingInfo->RingDataSize);
+	next += Offset;
+	next %= RingInfo->RingDataSize;
+
+	return next;
+}
+
+/*++
+
+Name:
+	SetNextReadLocation()
+
+Description:
+	Set the next read location for the specified ring buffer
+
+--*/
+static inline void
+SetNextReadLocation(RING_BUFFER_INFO* RingInfo, u32 NextReadLocation)
+{
+	RingInfo->RingBuffer->ReadIndex = NextReadLocation;
+}
+
+
+/*++
+
+Name:
+	GetRingBuffer()
+
+Description:
+	Get the start of the ring buffer
+
+--*/
+static inline void *
+GetRingBuffer(RING_BUFFER_INFO* RingInfo)
+{
+	return (void *)RingInfo->RingBuffer->Buffer;
+}
+
+
+/*++
+
+Name:
+	GetRingBufferSize()
+
+Description:
+	Get the size of the ring buffer
+
+--*/
+static inline u32
+GetRingBufferSize(RING_BUFFER_INFO* RingInfo)
+{
+	return RingInfo->RingDataSize;
+}
+
+/*++
+
+Name:
+	GetRingBufferIndices()
+
+Description:
+	Get the read and write indices as u64 of the specified ring buffer
+
+--*/
+static inline u64
+GetRingBufferIndices(RING_BUFFER_INFO* RingInfo)
+{
+	return ((u64)RingInfo->RingBuffer->WriteIndex << 32) || RingInfo->RingBuffer->ReadIndex;
+}
+
+
+/*++
+
+Name:
+	DumpRingInfo()
+
+Description:
+	Dump out to console the ring buffer info
+
+--*/
+void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix)
+{
+	u32 bytesAvailToWrite;
+	u32 bytesAvailToRead;
+
+	GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+
+	DPRINT(VMBUS, DEBUG_RING_LVL, "%s <<ringinfo %p buffer %p avail write %u avail read %u read idx %u write idx %u>>",
+		Prefix,
+		RingInfo,
+		RingInfo->RingBuffer->Buffer,
+		bytesAvailToWrite,
+		bytesAvailToRead,
+		RingInfo->RingBuffer->ReadIndex,
+		RingInfo->RingBuffer->WriteIndex);
+}
+
+
+/* Internal routines */
+
+static u32
+CopyToRingBuffer(
+	RING_BUFFER_INFO	*RingInfo,
+	u32				StartWriteOffset,
+	void *				Src,
+	u32				SrcLen);
+
+static u32
+CopyFromRingBuffer(
+	RING_BUFFER_INFO	*RingInfo,
+	void *				Dest,
+	u32				DestLen,
+	u32				StartReadOffset);
+
+
+
+/*++
+
+Name:
+	RingBufferGetDebugInfo()
+
+Description:
+	Get various debug metrics for the specified ring buffer
+
+--*/
+void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo,
+			    RING_BUFFER_DEBUG_INFO *DebugInfo)
+{
+	u32 bytesAvailToWrite;
+	u32 bytesAvailToRead;
+
+	if (RingInfo->RingBuffer)
+	{
+		GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+
+		DebugInfo->BytesAvailToRead = bytesAvailToRead;
+		DebugInfo->BytesAvailToWrite = bytesAvailToWrite;
+		DebugInfo->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex;
+		DebugInfo->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex;
+
+		DebugInfo->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask;
+	}
+}
+
+
+/*++
+
+Name:
+	GetRingBufferInterruptMask()
+
+Description:
+	Get the interrupt mask for the specified ring buffer
+
+--*/
+u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *rbi)
+{
+	return rbi->RingBuffer->InterruptMask;
+}
+
+/*++
+
+Name:
+	RingBufferInit()
+
+Description:
+	Initialize the ring buffer
+
+--*/
+int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen)
+{
+	ASSERT(sizeof(RING_BUFFER) == PAGE_SIZE);
+
+	memset(RingInfo, 0, sizeof(RING_BUFFER_INFO));
+
+	RingInfo->RingBuffer = (RING_BUFFER*)Buffer;
+	RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0;
+
+	RingInfo->RingSize = BufferLen;
+	RingInfo->RingDataSize = BufferLen - sizeof(RING_BUFFER);
+
+	spin_lock_init(&RingInfo->ring_lock);
+
+	return 0;
+}
+
+/*++
+
+Name:
+	RingBufferCleanup()
+
+Description:
+	Cleanup the ring buffer
+
+--*/
+void RingBufferCleanup(RING_BUFFER_INFO* RingInfo)
+{
+}
+
+/*++
+
+Name:
+	RingBufferWrite()
+
+Description:
+	Write to the ring buffer
+
+--*/
+int RingBufferWrite(RING_BUFFER_INFO *OutRingInfo,
+		    struct scatterlist *sglist, u32 sgcount)
+{
+	int i=0;
+	u32 byteAvailToWrite;
+	u32 byteAvailToRead;
+	u32 totalBytesToWrite=0;
+
+	struct scatterlist *sg;
+	volatile u32 nextWriteLocation;
+	u64 prevIndices=0;
+	unsigned long flags;
+
+	DPRINT_ENTER(VMBUS);
+
+	for_each_sg(sglist, sg, sgcount, i)
+	{
+		totalBytesToWrite += sg->length;
+	}
+
+	totalBytesToWrite += sizeof(u64);
+
+	spin_lock_irqsave(&OutRingInfo->ring_lock, flags);
+
+	GetRingBufferAvailBytes(OutRingInfo, &byteAvailToRead, &byteAvailToWrite);
+
+	DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite);
+
+	/* DumpRingInfo(OutRingInfo, "BEFORE "); */
+
+	/* If there is only room for the packet, assume it is full. Otherwise, the next time around, we think the ring buffer */
+	/* is empty since the read index == write index */
+	if (byteAvailToWrite <= totalBytesToWrite)
+	{
+		DPRINT_DBG(VMBUS, "No more space left on outbound ring buffer (needed %u, avail %u)", totalBytesToWrite, byteAvailToWrite);
+
+		spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
+
+		DPRINT_EXIT(VMBUS);
+
+		return -1;
+	}
+
+	/* Write to the ring buffer */
+	nextWriteLocation = GetNextWriteLocation(OutRingInfo);
+
+	for_each_sg(sglist, sg, sgcount, i)
+	{
+		nextWriteLocation = CopyToRingBuffer(OutRingInfo,
+						     nextWriteLocation,
+						     sg_virt(sg),
+						     sg->length);
+	}
+
+	/* Set previous packet start */
+	prevIndices = GetRingBufferIndices(OutRingInfo);
+
+	nextWriteLocation = CopyToRingBuffer(OutRingInfo,
+					     nextWriteLocation,
+					     &prevIndices,
+					     sizeof(u64));
+
+	/* Make sure we flush all writes before updating the writeIndex */
+	mb();
+
+	/* Now, update the write location */
+	SetNextWriteLocation(OutRingInfo, nextWriteLocation);
+
+	/* DumpRingInfo(OutRingInfo, "AFTER "); */
+
+	spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
+
+	DPRINT_EXIT(VMBUS);
+
+	return 0;
+}
+
+
+/*++
+
+Name:
+	RingBufferPeek()
+
+Description:
+	Read without advancing the read index
+
+--*/
+int RingBufferPeek(RING_BUFFER_INFO *InRingInfo, void *Buffer, u32 BufferLen)
+{
+	u32 bytesAvailToWrite;
+	u32 bytesAvailToRead;
+	u32 nextReadLocation=0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&InRingInfo->ring_lock, flags);
+
+	GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+
+	/* Make sure there is something to read */
+	if (bytesAvailToRead < BufferLen )
+	{
+		/* DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); */
+
+		spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+
+		return -1;
+	}
+
+	/* Convert to byte offset */
+	nextReadLocation = GetNextReadLocation(InRingInfo);
+
+	nextReadLocation = CopyFromRingBuffer(InRingInfo,
+											Buffer,
+											BufferLen,
+											nextReadLocation);
+
+	spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+
+	return 0;
+}
+
+
+/*++
+
+Name:
+	RingBufferRead()
+
+Description:
+	Read and advance the read index
+
+--*/
+int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer,
+		   u32 BufferLen, u32 Offset)
+{
+	u32 bytesAvailToWrite;
+	u32 bytesAvailToRead;
+	u32 nextReadLocation=0;
+	u64 prevIndices=0;
+	unsigned long flags;
+
+	ASSERT(BufferLen > 0);
+
+	spin_lock_irqsave(&InRingInfo->ring_lock, flags);
+
+	GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite);
+
+	DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen);
+
+	/* DumpRingInfo(InRingInfo, "BEFORE "); */
+
+	/* Make sure there is something to read */
+	if (bytesAvailToRead < BufferLen )
+	{
+		DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen);
+
+		spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+
+		return -1;
+	}
+
+	nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset);
+
+	nextReadLocation = CopyFromRingBuffer(InRingInfo,
+											Buffer,
+											BufferLen,
+											nextReadLocation);
+
+	nextReadLocation = CopyFromRingBuffer(InRingInfo,
+											&prevIndices,
+											sizeof(u64),
+											nextReadLocation);
+
+	/* Make sure all reads are done before we update the read index since */
+	/* the writer may start writing to the read area once the read index is updated */
+	mb();
+
+	/* Update the read index */
+	SetNextReadLocation(InRingInfo, nextReadLocation);
+
+	/* DumpRingInfo(InRingInfo, "AFTER "); */
+
+	spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
+
+	return 0;
+}
+
+
+/*++
+
+Name:
+	CopyToRingBuffer()
+
+Description:
+	Helper routine to copy from source to ring buffer.
+	Assume there is enough room. Handles wrap-around in dest case only!!
+
+--*/
+static u32
+CopyToRingBuffer(
+	RING_BUFFER_INFO	*RingInfo,
+	u32				StartWriteOffset,
+	void *				Src,
+	u32				SrcLen)
+{
+	void * ringBuffer=GetRingBuffer(RingInfo);
+	u32 ringBufferSize=GetRingBufferSize(RingInfo);
+	u32 fragLen;
+
+	if (SrcLen > ringBufferSize - StartWriteOffset) /* wrap-around detected! */
+	{
+		DPRINT_DBG(VMBUS, "wrap-around detected!");
+
+		fragLen = ringBufferSize - StartWriteOffset;
+		memcpy(ringBuffer + StartWriteOffset, Src, fragLen);
+		memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen);
+	}
+	else
+	{
+		memcpy(ringBuffer + StartWriteOffset, Src, SrcLen);
+	}
+
+	StartWriteOffset += SrcLen;
+	StartWriteOffset %= ringBufferSize;
+
+	return StartWriteOffset;
+}
+
+
+/*++
+
+Name:
+	CopyFromRingBuffer()
+
+Description:
+	Helper routine to copy to source from ring buffer.
+	Assume there is enough room. Handles wrap-around in src case only!!
+
+--*/
+static u32
+CopyFromRingBuffer(
+	RING_BUFFER_INFO	*RingInfo,
+	void *				Dest,
+	u32				DestLen,
+	u32				StartReadOffset)
+{
+	void * ringBuffer=GetRingBuffer(RingInfo);
+	u32 ringBufferSize=GetRingBufferSize(RingInfo);
+
+	u32 fragLen;
+
+	if (DestLen > ringBufferSize - StartReadOffset) /* wrap-around detected at the src */
+	{
+		DPRINT_DBG(VMBUS, "src wrap-around detected!");
+
+		fragLen = ringBufferSize - StartReadOffset;
+
+		memcpy(Dest, ringBuffer + StartReadOffset, fragLen);
+		memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen);
+	}
+	else
+	{
+		memcpy(Dest, ringBuffer + StartReadOffset, DestLen);
+	}
+
+	StartReadOffset += DestLen;
+	StartReadOffset %= ringBufferSize;
+
+	return StartReadOffset;
+}
+
+
+/* eof */
diff --git a/drivers/staging/hv/RingBuffer.h b/drivers/staging/hv/RingBuffer.h
new file mode 100644
index 0000000..6202157
--- /dev/null
+++ b/drivers/staging/hv/RingBuffer.h
@@ -0,0 +1,101 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _RING_BUFFER_H_
+#define _RING_BUFFER_H_
+
+#include <linux/scatterlist.h>
+
+typedef struct _RING_BUFFER {
+	/* Offset in bytes from the start of ring data below */
+	volatile u32 WriteIndex;
+
+	/* Offset in bytes from the start of ring data below */
+	volatile u32 ReadIndex;
+
+	volatile u32 InterruptMask;
+
+	/* Pad it to PAGE_SIZE so that data starts on page boundary */
+	u8	Reserved[4084];
+
+	/* NOTE:
+	 * The InterruptMask field is used only for channels but since our
+	 * vmbus connection also uses this data structure and its data starts
+	 * here, we commented out this field.
+	 */
+	/* volatile u32 InterruptMask; */
+
+	/*
+	 * Ring data starts here + RingDataStartOffset
+	 * !!! DO NOT place any fields below this !!!
+	 */
+	u8 Buffer[0];
+} __attribute__((packed)) RING_BUFFER;
+
+typedef struct _RING_BUFFER_INFO {
+	RING_BUFFER *RingBuffer;
+	u32 RingSize;			/* Include the shared header */
+	spinlock_t ring_lock;
+
+	u32 RingDataSize;		/* < ringSize */
+	u32 RingDataStartOffset;
+
+} RING_BUFFER_INFO;
+
+typedef struct _RING_BUFFER_DEBUG_INFO {
+	u32 CurrentInterruptMask;
+	u32 CurrentReadIndex;
+	u32 CurrentWriteIndex;
+	u32 BytesAvailToRead;
+	u32 BytesAvailToWrite;
+} RING_BUFFER_DEBUG_INFO;
+
+
+
+/* Interface */
+
+
+int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen);
+
+void RingBufferCleanup(RING_BUFFER_INFO *RingInfo);
+
+int RingBufferWrite(RING_BUFFER_INFO *RingInfo,
+		    struct scatterlist *sglist,
+		    u32 sgcount);
+
+int RingBufferPeek(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen);
+
+int RingBufferRead(RING_BUFFER_INFO *RingInfo,
+		   void *Buffer,
+		   u32 BufferLen,
+		   u32 Offset);
+
+u32 GetRingBufferInterruptMask(RING_BUFFER_INFO *RingInfo);
+
+void DumpRingInfo(RING_BUFFER_INFO *RingInfo, char *Prefix);
+
+void RingBufferGetDebugInfo(RING_BUFFER_INFO *RingInfo,
+			    RING_BUFFER_DEBUG_INFO *DebugInfo);
+
+#endif /* _RING_BUFFER_H_ */
diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/RndisFilter.c
new file mode 100644
index 0000000..26d7997
--- /dev/null
+++ b/drivers/staging/hv/RndisFilter.c
@@ -0,0 +1,1000 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/kernel.h>
+#include <linux/highmem.h>
+#include <linux/io.h>
+#include "osd.h"
+#include "logging.h"
+#include "NetVscApi.h"
+#include "RndisFilter.h"
+
+/* Data types */
+struct rndis_filter_driver_object {
+	/* The original driver */
+	struct netvsc_driver InnerDriver;
+};
+
+enum rndis_device_state {
+	RNDIS_DEV_UNINITIALIZED = 0,
+	RNDIS_DEV_INITIALIZING,
+	RNDIS_DEV_INITIALIZED,
+	RNDIS_DEV_DATAINITIALIZED,
+};
+
+struct rndis_device {
+	struct netvsc_device *NetDevice;
+
+	enum rndis_device_state State;
+	u32 LinkStatus;
+	atomic_t NewRequestId;
+
+	spinlock_t request_lock;
+	struct list_head RequestList;
+
+	unsigned char HwMacAddr[HW_MACADDR_LEN];
+};
+
+struct rndis_request {
+	struct list_head ListEntry;
+	struct osd_waitevent *WaitEvent;
+
+	/*
+	 * FIXME: We assumed a fixed size response here. If we do ever need to
+	 * handle a bigger response, we can either define a max response
+	 * message or add a response buffer variable above this field
+	 */
+	struct rndis_message ResponseMessage;
+
+	/* Simplify allocation by having a netvsc packet inline */
+	struct hv_netvsc_packet	Packet;
+	struct hv_page_buffer Buffer;
+	/* FIXME: We assumed a fixed size request here. */
+	struct rndis_message RequestMessage;
+};
+
+
+struct rndis_filter_packet {
+	void *CompletionContext;
+	void (*OnCompletion)(void *context);
+	struct rndis_message Message;
+};
+
+
+static int RndisFilterOnDeviceAdd(struct hv_device *Device,
+				  void *AdditionalInfo);
+
+static int RndisFilterOnDeviceRemove(struct hv_device *Device);
+
+static void RndisFilterOnCleanup(struct hv_driver *Driver);
+
+static int RndisFilterOnOpen(struct hv_device *Device);
+
+static int RndisFilterOnClose(struct hv_device *Device);
+
+static int RndisFilterOnSend(struct hv_device *Device,
+			     struct hv_netvsc_packet *Packet);
+
+static void RndisFilterOnSendCompletion(void *Context);
+
+static void RndisFilterOnSendRequestCompletion(void *Context);
+
+
+/* The one and only */
+static struct rndis_filter_driver_object gRndisFilter;
+
+static struct rndis_device *GetRndisDevice(void)
+{
+	struct rndis_device *device;
+
+	device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
+	if (!device)
+		return NULL;
+
+	spin_lock_init(&device->request_lock);
+
+	INIT_LIST_HEAD(&device->RequestList);
+
+	device->State = RNDIS_DEV_UNINITIALIZED;
+
+	return device;
+}
+
+static struct rndis_request *GetRndisRequest(struct rndis_device *Device,
+					     u32 MessageType,
+					     u32 MessageLength)
+{
+	struct rndis_request *request;
+	struct rndis_message *rndisMessage;
+	struct rndis_set_request *set;
+	unsigned long flags;
+
+	request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
+	if (!request)
+		return NULL;
+
+	request->WaitEvent = osd_WaitEventCreate();
+	if (!request->WaitEvent) {
+		kfree(request);
+		return NULL;
+	}
+
+	rndisMessage = &request->RequestMessage;
+	rndisMessage->NdisMessageType = MessageType;
+	rndisMessage->MessageLength = MessageLength;
+
+	/*
+	 * Set the request id. This field is always after the rndis header for
+	 * request/response packet types so we just used the SetRequest as a
+	 * template
+	 */
+	set = &rndisMessage->Message.SetRequest;
+	set->RequestId = atomic_inc_return(&Device->NewRequestId);
+
+	/* Add to the request list */
+	spin_lock_irqsave(&Device->request_lock, flags);
+	list_add_tail(&request->ListEntry, &Device->RequestList);
+	spin_unlock_irqrestore(&Device->request_lock, flags);
+
+	return request;
+}
+
+static void PutRndisRequest(struct rndis_device *Device,
+			    struct rndis_request *Request)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&Device->request_lock, flags);
+	list_del(&Request->ListEntry);
+	spin_unlock_irqrestore(&Device->request_lock, flags);
+
+	kfree(Request->WaitEvent);
+	kfree(Request);
+}
+
+static void DumpRndisMessage(struct rndis_message *RndisMessage)
+{
+	switch (RndisMessage->NdisMessageType) {
+	case REMOTE_NDIS_PACKET_MSG:
+		DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, "
+			   "data offset %u data len %u, # oob %u, "
+			   "oob offset %u, oob len %u, pkt offset %u, "
+			   "pkt len %u",
+			   RndisMessage->MessageLength,
+			   RndisMessage->Message.Packet.DataOffset,
+			   RndisMessage->Message.Packet.DataLength,
+			   RndisMessage->Message.Packet.NumOOBDataElements,
+			   RndisMessage->Message.Packet.OOBDataOffset,
+			   RndisMessage->Message.Packet.OOBDataLength,
+			   RndisMessage->Message.Packet.PerPacketInfoOffset,
+			   RndisMessage->Message.Packet.PerPacketInfoLength);
+		break;
+
+	case REMOTE_NDIS_INITIALIZE_CMPLT:
+		DPRINT_DBG(NETVSC, "REMOTE_NDIS_INITIALIZE_CMPLT "
+			"(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
+			"device flags %d, max xfer size 0x%x, max pkts %u, "
+			"pkt aligned %u)",
+			RndisMessage->MessageLength,
+			RndisMessage->Message.InitializeComplete.RequestId,
+			RndisMessage->Message.InitializeComplete.Status,
+			RndisMessage->Message.InitializeComplete.MajorVersion,
+			RndisMessage->Message.InitializeComplete.MinorVersion,
+			RndisMessage->Message.InitializeComplete.DeviceFlags,
+			RndisMessage->Message.InitializeComplete.MaxTransferSize,
+			RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage,
+			RndisMessage->Message.InitializeComplete.PacketAlignmentFactor);
+		break;
+
+	case REMOTE_NDIS_QUERY_CMPLT:
+		DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT "
+			"(len %u, id 0x%x, status 0x%x, buf len %u, "
+			"buf offset %u)",
+			RndisMessage->MessageLength,
+			RndisMessage->Message.QueryComplete.RequestId,
+			RndisMessage->Message.QueryComplete.Status,
+			RndisMessage->Message.QueryComplete.InformationBufferLength,
+			RndisMessage->Message.QueryComplete.InformationBufferOffset);
+		break;
+
+	case REMOTE_NDIS_SET_CMPLT:
+		DPRINT_DBG(NETVSC,
+			"REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)",
+			RndisMessage->MessageLength,
+			RndisMessage->Message.SetComplete.RequestId,
+			RndisMessage->Message.SetComplete.Status);
+		break;
+
+	case REMOTE_NDIS_INDICATE_STATUS_MSG:
+		DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG "
+			"(len %u, status 0x%x, buf len %u, buf offset %u)",
+			RndisMessage->MessageLength,
+			RndisMessage->Message.IndicateStatus.Status,
+			RndisMessage->Message.IndicateStatus.StatusBufferLength,
+			RndisMessage->Message.IndicateStatus.StatusBufferOffset);
+		break;
+
+	default:
+		DPRINT_DBG(NETVSC, "0x%x (len %u)",
+			RndisMessage->NdisMessageType,
+			RndisMessage->MessageLength);
+		break;
+	}
+}
+
+static int RndisFilterSendRequest(struct rndis_device *Device,
+				  struct rndis_request *Request)
+{
+	int ret;
+	struct hv_netvsc_packet *packet;
+
+	DPRINT_ENTER(NETVSC);
+
+	/* Setup the packet to send it */
+	packet = &Request->Packet;
+
+	packet->IsDataPacket = false;
+	packet->TotalDataBufferLength = Request->RequestMessage.MessageLength;
+	packet->PageBufferCount = 1;
+
+	packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >>
+					PAGE_SHIFT;
+	packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength;
+	packet->PageBuffers[0].Offset =
+		(unsigned long)&Request->RequestMessage & (PAGE_SIZE - 1);
+
+	packet->Completion.Send.SendCompletionContext = Request;/* packet; */
+	packet->Completion.Send.OnSendCompletion =
+		RndisFilterOnSendRequestCompletion;
+	packet->Completion.Send.SendCompletionTid = (unsigned long)Device;
+
+	ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet);
+	DPRINT_EXIT(NETVSC);
+	return ret;
+}
+
+static void RndisFilterReceiveResponse(struct rndis_device *Device,
+				       struct rndis_message *Response)
+{
+	struct rndis_request *request = NULL;
+	bool found = false;
+	unsigned long flags;
+
+	DPRINT_ENTER(NETVSC);
+
+	spin_lock_irqsave(&Device->request_lock, flags);
+	list_for_each_entry(request, &Device->RequestList, ListEntry) {
+		/*
+		 * All request/response message contains RequestId as the 1st
+		 * field
+		 */
+		if (request->RequestMessage.Message.InitializeRequest.RequestId
+		    == Response->Message.InitializeComplete.RequestId) {
+			DPRINT_DBG(NETVSC, "found rndis request for "
+				"this response (id 0x%x req type 0x%x res "
+				"type 0x%x)",
+				request->RequestMessage.Message.InitializeRequest.RequestId,
+				request->RequestMessage.NdisMessageType,
+				Response->NdisMessageType);
+
+			found = true;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&Device->request_lock, flags);
+
+	if (found) {
+		if (Response->MessageLength <= sizeof(struct rndis_message)) {
+			memcpy(&request->ResponseMessage, Response,
+			       Response->MessageLength);
+		} else {
+			DPRINT_ERR(NETVSC, "rndis response buffer overflow "
+				  "detected (size %u max %zu)",
+				  Response->MessageLength,
+				  sizeof(struct rndis_filter_packet));
+
+			if (Response->NdisMessageType ==
+			    REMOTE_NDIS_RESET_CMPLT) {
+				/* does not have a request id field */
+				request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW;
+			} else {
+				request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW;
+			}
+		}
+
+		osd_WaitEventSet(request->WaitEvent);
+	} else {
+		DPRINT_ERR(NETVSC, "no rndis request found for this response "
+			   "(id 0x%x res type 0x%x)",
+			   Response->Message.InitializeComplete.RequestId,
+			   Response->NdisMessageType);
+	}
+
+	DPRINT_EXIT(NETVSC);
+}
+
+static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device,
+					     struct rndis_message *Response)
+{
+	struct rndis_indicate_status *indicate =
+			&Response->Message.IndicateStatus;
+
+	if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) {
+		gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1);
+	} else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) {
+		gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0);
+	} else {
+		/*
+		 * TODO:
+		 */
+	}
+}
+
+static void RndisFilterReceiveData(struct rndis_device *Device,
+				   struct rndis_message *Message,
+				   struct hv_netvsc_packet *Packet)
+{
+	struct rndis_packet *rndisPacket;
+	u32 dataOffset;
+
+	DPRINT_ENTER(NETVSC);
+
+	/* empty ethernet frame ?? */
+	ASSERT(Packet->PageBuffers[0].Length >
+		RNDIS_MESSAGE_SIZE(struct rndis_packet));
+
+	rndisPacket = &Message->Message.Packet;
+
+	/*
+	 * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
+	 * netvsc packet (ie TotalDataBufferLength != MessageLength)
+	 */
+
+	/* Remove the rndis header and pass it back up the stack */
+	dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset;
+
+	Packet->TotalDataBufferLength -= dataOffset;
+	Packet->PageBuffers[0].Offset += dataOffset;
+	Packet->PageBuffers[0].Length -= dataOffset;
+
+	Packet->IsDataPacket = true;
+
+	gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device,
+						   Packet);
+
+	DPRINT_EXIT(NETVSC);
+}
+
+static int RndisFilterOnReceive(struct hv_device *Device,
+				struct hv_netvsc_packet	*Packet)
+{
+	struct netvsc_device *netDevice = Device->Extension;
+	struct rndis_device *rndisDevice;
+	struct rndis_message rndisMessage;
+	struct rndis_message *rndisHeader;
+
+	DPRINT_ENTER(NETVSC);
+
+	ASSERT(netDevice);
+	/* Make sure the rndis device state is initialized */
+	if (!netDevice->Extension) {
+		DPRINT_ERR(NETVSC, "got rndis message but no rndis device..."
+			  "dropping this message!");
+		DPRINT_EXIT(NETVSC);
+		return -1;
+	}
+
+	rndisDevice = (struct rndis_device *)netDevice->Extension;
+	if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) {
+		DPRINT_ERR(NETVSC, "got rndis message but rndis device "
+			   "uninitialized...dropping this message!");
+		DPRINT_EXIT(NETVSC);
+		return -1;
+	}
+
+	rndisHeader = (struct rndis_message *)kmap_atomic(
+			pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0);
+
+	rndisHeader = (void *)((unsigned long)rndisHeader +
+			Packet->PageBuffers[0].Offset);
+
+	/* Make sure we got a valid rndis message */
+	/*
+	 * FIXME: There seems to be a bug in set completion msg where its
+	 * MessageLength is 16 bytes but the ByteCount field in the xfer page
+	 * range shows 52 bytes
+	 * */
+#if 0
+	if (Packet->TotalDataBufferLength != rndisHeader->MessageLength) {
+		kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset,
+			      KM_IRQ0);
+
+		DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u "
+			   "bytes got %u)...dropping this message!",
+			   rndisHeader->MessageLength,
+			   Packet->TotalDataBufferLength);
+		DPRINT_EXIT(NETVSC);
+		return -1;
+	}
+#endif
+
+	if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) &&
+	    (rndisHeader->MessageLength > sizeof(struct rndis_message))) {
+		DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow "
+			   "detected (got %u, max %zu)...marking it an error!",
+			   rndisHeader->MessageLength,
+			   sizeof(struct rndis_message));
+	}
+
+	memcpy(&rndisMessage, rndisHeader,
+		(rndisHeader->MessageLength > sizeof(struct rndis_message)) ?
+			sizeof(struct rndis_message) :
+			rndisHeader->MessageLength);
+
+	kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0);
+
+	DumpRndisMessage(&rndisMessage);
+
+	switch (rndisMessage.NdisMessageType) {
+	case REMOTE_NDIS_PACKET_MSG:
+		/* data msg */
+		RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet);
+		break;
+
+	case REMOTE_NDIS_INITIALIZE_CMPLT:
+	case REMOTE_NDIS_QUERY_CMPLT:
+	case REMOTE_NDIS_SET_CMPLT:
+	/* case REMOTE_NDIS_RESET_CMPLT: */
+	/* case REMOTE_NDIS_KEEPALIVE_CMPLT: */
+		/* completion msgs */
+		RndisFilterReceiveResponse(rndisDevice, &rndisMessage);
+		break;
+
+	case REMOTE_NDIS_INDICATE_STATUS_MSG:
+		/* notification msgs */
+		RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage);
+		break;
+	default:
+		DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)",
+			   rndisMessage.NdisMessageType,
+			   rndisMessage.MessageLength);
+		break;
+	}
+
+	DPRINT_EXIT(NETVSC);
+	return 0;
+}
+
+static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid,
+				  void *Result, u32 *ResultSize)
+{
+	struct rndis_request *request;
+	u32 inresultSize = *ResultSize;
+	struct rndis_query_request *query;
+	struct rndis_query_complete *queryComplete;
+	int ret = 0;
+
+	DPRINT_ENTER(NETVSC);
+
+	ASSERT(Result);
+
+	*ResultSize = 0;
+	request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG,
+			RNDIS_MESSAGE_SIZE(struct rndis_query_request));
+	if (!request) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	/* Setup the rndis query */
+	query = &request->RequestMessage.Message.QueryRequest;
+	query->Oid = Oid;
+	query->InformationBufferOffset = sizeof(struct rndis_query_request);
+	query->InformationBufferLength = 0;
+	query->DeviceVcHandle = 0;
+
+	ret = RndisFilterSendRequest(Device, request);
+	if (ret != 0)
+		goto Cleanup;
+
+	osd_WaitEventWait(request->WaitEvent);
+
+	/* Copy the response back */
+	queryComplete = &request->ResponseMessage.Message.QueryComplete;
+
+	if (queryComplete->InformationBufferLength > inresultSize) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	memcpy(Result,
+	       (void *)((unsigned long)queryComplete +
+			 queryComplete->InformationBufferOffset),
+	       queryComplete->InformationBufferLength);
+
+	*ResultSize = queryComplete->InformationBufferLength;
+
+Cleanup:
+	if (request)
+		PutRndisRequest(Device, request);
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static int RndisFilterQueryDeviceMac(struct rndis_device *Device)
+{
+	u32 size = HW_MACADDR_LEN;
+
+	return RndisFilterQueryDevice(Device,
+				      RNDIS_OID_802_3_PERMANENT_ADDRESS,
+				      Device->HwMacAddr, &size);
+}
+
+static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device)
+{
+	u32 size = sizeof(u32);
+
+	return RndisFilterQueryDevice(Device,
+				      RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
+				      &Device->LinkStatus, &size);
+}
+
+static int RndisFilterSetPacketFilter(struct rndis_device *Device,
+				      u32 NewFilter)
+{
+	struct rndis_request *request;
+	struct rndis_set_request *set;
+	struct rndis_set_complete *setComplete;
+	u32 status;
+	int ret;
+
+	DPRINT_ENTER(NETVSC);
+
+	ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <=
+		sizeof(struct rndis_message));
+
+	request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG,
+			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
+			sizeof(u32));
+	if (!request) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	/* Setup the rndis set */
+	set = &request->RequestMessage.Message.SetRequest;
+	set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
+	set->InformationBufferLength = sizeof(u32);
+	set->InformationBufferOffset = sizeof(struct rndis_set_request);
+
+	memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
+	       &NewFilter, sizeof(u32));
+
+	ret = RndisFilterSendRequest(Device, request);
+	if (ret != 0)
+		goto Cleanup;
+
+	ret = osd_WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/);
+	if (!ret) {
+		ret = -1;
+		DPRINT_ERR(NETVSC, "timeout before we got a set response...");
+		/*
+		 * We cant deallocate the request since we may still receive a
+		 * send completion for it.
+		 */
+		goto Exit;
+	} else {
+		if (ret > 0)
+			ret = 0;
+		setComplete = &request->ResponseMessage.Message.SetComplete;
+		status = setComplete->Status;
+	}
+
+Cleanup:
+	if (request)
+		PutRndisRequest(Device, request);
+Exit:
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+int RndisFilterInit(struct netvsc_driver *Driver)
+{
+	DPRINT_ENTER(NETVSC);
+
+	DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd",
+		   sizeof(struct rndis_filter_packet));
+
+	Driver->RequestExtSize = sizeof(struct rndis_filter_packet);
+	Driver->AdditionalRequestPageBufferCount = 1; /* For rndis header */
+
+	/* Driver->Context = rndisDriver; */
+
+	memset(&gRndisFilter, 0, sizeof(struct rndis_filter_driver_object));
+
+	/*rndisDriver->Driver = Driver;
+
+	ASSERT(Driver->OnLinkStatusChanged);
+	rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/
+
+	/* Save the original dispatch handlers before we override it */
+	gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd;
+	gRndisFilter.InnerDriver.Base.OnDeviceRemove =
+					Driver->Base.OnDeviceRemove;
+	gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup;
+
+	ASSERT(Driver->OnSend);
+	ASSERT(Driver->OnReceiveCallback);
+	gRndisFilter.InnerDriver.OnSend = Driver->OnSend;
+	gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback;
+	gRndisFilter.InnerDriver.OnLinkStatusChanged =
+					Driver->OnLinkStatusChanged;
+
+	/* Override */
+	Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd;
+	Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
+	Driver->Base.OnCleanup = RndisFilterOnCleanup;
+	Driver->OnSend = RndisFilterOnSend;
+	Driver->OnOpen = RndisFilterOnOpen;
+	Driver->OnClose = RndisFilterOnClose;
+	/* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */
+	Driver->OnReceiveCallback = RndisFilterOnReceive;
+
+	DPRINT_EXIT(NETVSC);
+
+	return 0;
+}
+
+static int RndisFilterInitDevice(struct rndis_device *Device)
+{
+	struct rndis_request *request;
+	struct rndis_initialize_request *init;
+	struct rndis_initialize_complete *initComplete;
+	u32 status;
+	int ret;
+
+	DPRINT_ENTER(NETVSC);
+
+	request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG,
+			RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
+	if (!request) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	/* Setup the rndis set */
+	init = &request->RequestMessage.Message.InitializeRequest;
+	init->MajorVersion = RNDIS_MAJOR_VERSION;
+	init->MinorVersion = RNDIS_MINOR_VERSION;
+	/* FIXME: Use 1536 - rounded ethernet frame size */
+	init->MaxTransferSize = 2048;
+
+	Device->State = RNDIS_DEV_INITIALIZING;
+
+	ret = RndisFilterSendRequest(Device, request);
+	if (ret != 0) {
+		Device->State = RNDIS_DEV_UNINITIALIZED;
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(request->WaitEvent);
+
+	initComplete = &request->ResponseMessage.Message.InitializeComplete;
+	status = initComplete->Status;
+	if (status == RNDIS_STATUS_SUCCESS) {
+		Device->State = RNDIS_DEV_INITIALIZED;
+		ret = 0;
+	} else {
+		Device->State = RNDIS_DEV_UNINITIALIZED;
+		ret = -1;
+	}
+
+Cleanup:
+	if (request)
+		PutRndisRequest(Device, request);
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static void RndisFilterHaltDevice(struct rndis_device *Device)
+{
+	struct rndis_request *request;
+	struct rndis_halt_request *halt;
+
+	DPRINT_ENTER(NETVSC);
+
+	/* Attempt to do a rndis device halt */
+	request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG,
+				RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
+	if (!request)
+		goto Cleanup;
+
+	/* Setup the rndis set */
+	halt = &request->RequestMessage.Message.HaltRequest;
+	halt->RequestId = atomic_inc_return(&Device->NewRequestId);
+
+	/* Ignore return since this msg is optional. */
+	RndisFilterSendRequest(Device, request);
+
+	Device->State = RNDIS_DEV_UNINITIALIZED;
+
+Cleanup:
+	if (request)
+		PutRndisRequest(Device, request);
+	DPRINT_EXIT(NETVSC);
+	return;
+}
+
+static int RndisFilterOpenDevice(struct rndis_device *Device)
+{
+	int ret;
+
+	DPRINT_ENTER(NETVSC);
+
+	if (Device->State != RNDIS_DEV_INITIALIZED)
+		return 0;
+
+	ret = RndisFilterSetPacketFilter(Device,
+					 NDIS_PACKET_TYPE_BROADCAST |
+					 NDIS_PACKET_TYPE_DIRECTED);
+	if (ret == 0)
+		Device->State = RNDIS_DEV_DATAINITIALIZED;
+
+	DPRINT_EXIT(NETVSC);
+	return ret;
+}
+
+static int RndisFilterCloseDevice(struct rndis_device *Device)
+{
+	int ret;
+
+	DPRINT_ENTER(NETVSC);
+
+	if (Device->State != RNDIS_DEV_DATAINITIALIZED)
+		return 0;
+
+	ret = RndisFilterSetPacketFilter(Device, 0);
+	if (ret == 0)
+		Device->State = RNDIS_DEV_INITIALIZED;
+
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static int RndisFilterOnDeviceAdd(struct hv_device *Device,
+				  void *AdditionalInfo)
+{
+	int ret;
+	struct netvsc_device *netDevice;
+	struct rndis_device *rndisDevice;
+	struct netvsc_device_info *deviceInfo = AdditionalInfo;
+
+	DPRINT_ENTER(NETVSC);
+
+	rndisDevice = GetRndisDevice();
+	if (!rndisDevice) {
+		DPRINT_EXIT(NETVSC);
+		return -1;
+	}
+
+	DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
+
+	/*
+	 * Let the inner driver handle this first to create the netvsc channel
+	 * NOTE! Once the channel is created, we may get a receive callback
+	 * (RndisFilterOnReceive()) before this call is completed
+	 */
+	ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
+	if (ret != 0) {
+		kfree(rndisDevice);
+		DPRINT_EXIT(NETVSC);
+		return ret;
+	}
+
+
+	/* Initialize the rndis device */
+	netDevice = Device->Extension;
+	ASSERT(netDevice);
+	ASSERT(netDevice->Device);
+
+	netDevice->Extension = rndisDevice;
+	rndisDevice->NetDevice = netDevice;
+
+	/* Send the rndis initialization message */
+	ret = RndisFilterInitDevice(rndisDevice);
+	if (ret != 0) {
+		/*
+		 * TODO: If rndis init failed, we will need to shut down the
+		 * channel
+		 */
+	}
+
+	/* Get the mac address */
+	ret = RndisFilterQueryDeviceMac(rndisDevice);
+	if (ret != 0) {
+		/*
+		 * TODO: shutdown rndis device and the channel
+		 */
+	}
+
+	DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x",
+		    rndisDevice,
+		    rndisDevice->HwMacAddr[0],
+		    rndisDevice->HwMacAddr[1],
+		    rndisDevice->HwMacAddr[2],
+		    rndisDevice->HwMacAddr[3],
+		    rndisDevice->HwMacAddr[4],
+		    rndisDevice->HwMacAddr[5]);
+
+	memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, HW_MACADDR_LEN);
+
+	RndisFilterQueryDeviceLinkStatus(rndisDevice);
+
+	deviceInfo->LinkState = rndisDevice->LinkStatus;
+	DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice,
+		    ((deviceInfo->LinkState) ? ("down") : ("up")));
+
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static int RndisFilterOnDeviceRemove(struct hv_device *Device)
+{
+	struct netvsc_device *netDevice = Device->Extension;
+	struct rndis_device *rndisDevice = netDevice->Extension;
+
+	DPRINT_ENTER(NETVSC);
+
+	/* Halt and release the rndis device */
+	RndisFilterHaltDevice(rndisDevice);
+
+	kfree(rndisDevice);
+	netDevice->Extension = NULL;
+
+	/* Pass control to inner driver to remove the device */
+	gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device);
+
+	DPRINT_EXIT(NETVSC);
+
+	return 0;
+}
+
+static void RndisFilterOnCleanup(struct hv_driver *Driver)
+{
+	DPRINT_ENTER(NETVSC);
+
+	DPRINT_EXIT(NETVSC);
+}
+
+static int RndisFilterOnOpen(struct hv_device *Device)
+{
+	int ret;
+	struct netvsc_device *netDevice = Device->Extension;
+
+	DPRINT_ENTER(NETVSC);
+
+	ASSERT(netDevice);
+	ret = RndisFilterOpenDevice(netDevice->Extension);
+
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static int RndisFilterOnClose(struct hv_device *Device)
+{
+	int ret;
+	struct netvsc_device *netDevice = Device->Extension;
+
+	DPRINT_ENTER(NETVSC);
+
+	ASSERT(netDevice);
+	ret = RndisFilterCloseDevice(netDevice->Extension);
+
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static int RndisFilterOnSend(struct hv_device *Device,
+			     struct hv_netvsc_packet *Packet)
+{
+	int ret;
+	struct rndis_filter_packet *filterPacket;
+	struct rndis_message *rndisMessage;
+	struct rndis_packet *rndisPacket;
+	u32 rndisMessageSize;
+
+	DPRINT_ENTER(NETVSC);
+
+	/* Add the rndis header */
+	filterPacket = (struct rndis_filter_packet *)Packet->Extension;
+	ASSERT(filterPacket);
+
+	memset(filterPacket, 0, sizeof(struct rndis_filter_packet));
+
+	rndisMessage = &filterPacket->Message;
+	rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet);
+
+	rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG;
+	rndisMessage->MessageLength = Packet->TotalDataBufferLength +
+				      rndisMessageSize;
+
+	rndisPacket = &rndisMessage->Message.Packet;
+	rndisPacket->DataOffset = sizeof(struct rndis_packet);
+	rndisPacket->DataLength = Packet->TotalDataBufferLength;
+
+	Packet->IsDataPacket = true;
+	Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT;
+	Packet->PageBuffers[0].Offset =
+			(unsigned long)rndisMessage & (PAGE_SIZE-1);
+	Packet->PageBuffers[0].Length = rndisMessageSize;
+
+	/* Save the packet send completion and context */
+	filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion;
+	filterPacket->CompletionContext =
+				Packet->Completion.Send.SendCompletionContext;
+
+	/* Use ours */
+	Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion;
+	Packet->Completion.Send.SendCompletionContext = filterPacket;
+
+	ret = gRndisFilter.InnerDriver.OnSend(Device, Packet);
+	if (ret != 0) {
+		/*
+		 * Reset the completion to originals to allow retries from
+		 * above
+		 */
+		Packet->Completion.Send.OnSendCompletion =
+				filterPacket->OnCompletion;
+		Packet->Completion.Send.SendCompletionContext =
+				filterPacket->CompletionContext;
+	}
+
+	DPRINT_EXIT(NETVSC);
+
+	return ret;
+}
+
+static void RndisFilterOnSendCompletion(void *Context)
+{
+	struct rndis_filter_packet *filterPacket = Context;
+
+	DPRINT_ENTER(NETVSC);
+
+	/* Pass it back to the original handler */
+	filterPacket->OnCompletion(filterPacket->CompletionContext);
+
+	DPRINT_EXIT(NETVSC);
+}
+
+
+static void RndisFilterOnSendRequestCompletion(void *Context)
+{
+	DPRINT_ENTER(NETVSC);
+
+	/* Noop */
+	DPRINT_EXIT(NETVSC);
+}
diff --git a/drivers/staging/hv/RndisFilter.h b/drivers/staging/hv/RndisFilter.h
new file mode 100644
index 0000000..fa7dd79
--- /dev/null
+++ b/drivers/staging/hv/RndisFilter.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _RNDISFILTER_H_
+#define _RNDISFILTER_H_
+
+#define __struct_bcount(x)
+
+#include "NetVsc.h"
+
+#include "rndis.h"
+
+#define RNDIS_HEADER_SIZE	(sizeof(struct rndis_message) - \
+				 sizeof(union rndis_message_container))
+
+#define NDIS_PACKET_TYPE_DIRECTED	0x00000001
+#define NDIS_PACKET_TYPE_MULTICAST	0x00000002
+#define NDIS_PACKET_TYPE_ALL_MULTICAST	0x00000004
+#define NDIS_PACKET_TYPE_BROADCAST	0x00000008
+#define NDIS_PACKET_TYPE_SOURCE_ROUTING	0x00000010
+#define NDIS_PACKET_TYPE_PROMISCUOUS	0x00000020
+#define NDIS_PACKET_TYPE_SMT		0x00000040
+#define NDIS_PACKET_TYPE_ALL_LOCAL	0x00000080
+#define NDIS_PACKET_TYPE_GROUP		0x00000100
+#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL	0x00000200
+#define NDIS_PACKET_TYPE_FUNCTIONAL	0x00000400
+#define NDIS_PACKET_TYPE_MAC_FRAME	0x00000800
+
+
+/* Interface */
+
+extern int RndisFilterInit(struct netvsc_driver *driver);
+
+#endif /* _RNDISFILTER_H_ */
diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/StorVsc.c
new file mode 100644
index 0000000..14015c9
--- /dev/null
+++ b/drivers/staging/hv/StorVsc.c
@@ -0,0 +1,850 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include "osd.h"
+#include "logging.h"
+#include "StorVscApi.h"
+#include "VmbusPacketFormat.h"
+#include "vstorage.h"
+
+
+struct storvsc_request_extension {
+	/* LIST_ENTRY ListEntry; */
+
+	struct hv_storvsc_request *Request;
+	struct hv_device *Device;
+
+	/* Synchronize the request/response if needed */
+	struct osd_waitevent *WaitEvent;
+
+	struct vstor_packet VStorPacket;
+};
+
+/* A storvsc device is a device object that contains a vmbus channel */
+struct storvsc_device {
+	struct hv_device *Device;
+
+	/* 0 indicates the device is being destroyed */
+	atomic_t RefCount;
+
+	atomic_t NumOutstandingRequests;
+
+	/*
+	 * Each unique Port/Path/Target represents 1 channel ie scsi
+	 * controller. In reality, the pathid, targetid is always 0
+	 * and the port is set by us
+	 */
+	unsigned int PortNumber;
+	unsigned char PathId;
+	unsigned char TargetId;
+
+	/* LIST_ENTRY OutstandingRequestList; */
+	/* HANDLE OutstandingRequestLock; */
+
+	/* Used for vsc/vsp channel reset process */
+	struct storvsc_request_extension InitRequest;
+	struct storvsc_request_extension ResetRequest;
+};
+
+
+static const char *gDriverName = "storvsc";
+
+/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
+static const struct hv_guid gStorVscDeviceType = {
+	.data = {
+		0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
+		0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
+	}
+};
+
+
+static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+
+	storDevice = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
+	if (!storDevice)
+		return NULL;
+
+	/* Set to 2 to allow both inbound and outbound traffics */
+	/* (ie GetStorDevice() and MustGetStorDevice()) to proceed. */
+	atomic_cmpxchg(&storDevice->RefCount, 0, 2);
+
+	storDevice->Device = Device;
+	Device->Extension = storDevice;
+
+	return storDevice;
+}
+
+static inline void FreeStorDevice(struct storvsc_device *Device)
+{
+	ASSERT(atomic_read(&Device->RefCount) == 0);
+	kfree(Device);
+}
+
+/* Get the stordevice object iff exists and its refcount > 1 */
+static inline struct storvsc_device *GetStorDevice(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+
+	storDevice = (struct storvsc_device *)Device->Extension;
+	if (storDevice && atomic_read(&storDevice->RefCount) > 1)
+		atomic_inc(&storDevice->RefCount);
+	else
+		storDevice = NULL;
+
+	return storDevice;
+}
+
+/* Get the stordevice object iff exists and its refcount > 0 */
+static inline struct storvsc_device *MustGetStorDevice(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+
+	storDevice = (struct storvsc_device *)Device->Extension;
+	if (storDevice && atomic_read(&storDevice->RefCount))
+		atomic_inc(&storDevice->RefCount);
+	else
+		storDevice = NULL;
+
+	return storDevice;
+}
+
+static inline void PutStorDevice(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+
+	storDevice = (struct storvsc_device *)Device->Extension;
+	ASSERT(storDevice);
+
+	atomic_dec(&storDevice->RefCount);
+	ASSERT(atomic_read(&storDevice->RefCount));
+}
+
+/* Drop ref count to 1 to effectively disable GetStorDevice() */
+static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+
+	storDevice = (struct storvsc_device *)Device->Extension;
+	ASSERT(storDevice);
+
+	/* Busy wait until the ref drop to 2, then set it to 1 */
+	while (atomic_cmpxchg(&storDevice->RefCount, 2, 1) != 2)
+		udelay(100);
+
+	return storDevice;
+}
+
+/* Drop ref count to 0. No one can use StorDevice object. */
+static inline struct storvsc_device *FinalReleaseStorDevice(
+			struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+
+	storDevice = (struct storvsc_device *)Device->Extension;
+	ASSERT(storDevice);
+
+	/* Busy wait until the ref drop to 1, then set it to 0 */
+	while (atomic_cmpxchg(&storDevice->RefCount, 1, 0) != 1)
+		udelay(100);
+
+	Device->Extension = NULL;
+	return storDevice;
+}
+
+static int StorVscChannelInit(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+	struct storvsc_request_extension *request;
+	struct vstor_packet *vstorPacket;
+	int ret;
+
+	storDevice = GetStorDevice(Device);
+	if (!storDevice) {
+		DPRINT_ERR(STORVSC, "unable to get stor device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(STORVSC);
+		return -1;
+	}
+
+	request = &storDevice->InitRequest;
+	vstorPacket = &request->VStorPacket;
+
+	/*
+	 * Now, initiate the vsc/vsp initialization protocol on the open
+	 * channel
+	 */
+	memset(request, sizeof(struct storvsc_request_extension), 0);
+	request->WaitEvent = osd_WaitEventCreate();
+
+	vstorPacket->Operation = VStorOperationBeginInitialization;
+	vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
+
+	/*SpinlockAcquire(gDriverExt.packetListLock);
+	INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry);
+	SpinlockRelease(gDriverExt.packetListLock);*/
+
+	DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION...");
+
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				vstorPacket,
+				sizeof(struct vstor_packet),
+				(unsigned long)request,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC,
+			   "unable to send BEGIN_INITIALIZATION_OPERATION");
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(request->WaitEvent);
+
+	if (vstorPacket->Operation != VStorOperationCompleteIo ||
+	    vstorPacket->Status != 0) {
+		DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed "
+			   "(op %d status 0x%x)",
+			   vstorPacket->Operation, vstorPacket->Status);
+		goto Cleanup;
+	}
+
+	DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
+
+	/* reuse the packet for version range supported */
+	memset(vstorPacket, sizeof(struct vstor_packet), 0);
+	vstorPacket->Operation = VStorOperationQueryProtocolVersion;
+	vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
+
+	vstorPacket->Version.MajorMinor = VMSTOR_PROTOCOL_VERSION_CURRENT;
+	FILL_VMSTOR_REVISION(vstorPacket->Version.Revision);
+
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				vstorPacket,
+				sizeof(struct vstor_packet),
+				(unsigned long)request,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC,
+			   "unable to send BEGIN_INITIALIZATION_OPERATION");
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(request->WaitEvent);
+
+	/* TODO: Check returned version */
+	if (vstorPacket->Operation != VStorOperationCompleteIo ||
+	    vstorPacket->Status != 0) {
+		DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed "
+			   "(op %d status 0x%x)",
+			   vstorPacket->Operation, vstorPacket->Status);
+		goto Cleanup;
+	}
+
+	/* Query channel properties */
+	DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
+
+	memset(vstorPacket, sizeof(struct vstor_packet), 0);
+	vstorPacket->Operation = VStorOperationQueryProperties;
+	vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
+	vstorPacket->StorageChannelProperties.PortNumber =
+					storDevice->PortNumber;
+
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				vstorPacket,
+				sizeof(struct vstor_packet),
+				(unsigned long)request,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC,
+			   "unable to send QUERY_PROPERTIES_OPERATION");
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(request->WaitEvent);
+
+	/* TODO: Check returned version */
+	if (vstorPacket->Operation != VStorOperationCompleteIo ||
+	    vstorPacket->Status != 0) {
+		DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed "
+			   "(op %d status 0x%x)",
+			   vstorPacket->Operation, vstorPacket->Status);
+		goto Cleanup;
+	}
+
+	storDevice->PathId = vstorPacket->StorageChannelProperties.PathId;
+	storDevice->TargetId = vstorPacket->StorageChannelProperties.TargetId;
+
+	DPRINT_DBG(STORVSC, "channel flag 0x%x, max xfer len 0x%x",
+		   vstorPacket->StorageChannelProperties.Flags,
+		   vstorPacket->StorageChannelProperties.MaxTransferBytes);
+
+	DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION...");
+
+	memset(vstorPacket, sizeof(struct vstor_packet), 0);
+	vstorPacket->Operation = VStorOperationEndInitialization;
+	vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
+
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				vstorPacket,
+				sizeof(struct vstor_packet),
+				(unsigned long)request,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC,
+			   "unable to send END_INITIALIZATION_OPERATION");
+		goto Cleanup;
+	}
+
+	osd_WaitEventWait(request->WaitEvent);
+
+	if (vstorPacket->Operation != VStorOperationCompleteIo ||
+	    vstorPacket->Status != 0) {
+		DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed "
+			   "(op %d status 0x%x)",
+			   vstorPacket->Operation, vstorPacket->Status);
+		goto Cleanup;
+	}
+
+	DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****");
+
+Cleanup:
+	kfree(request->WaitEvent);
+	request->WaitEvent = NULL;
+
+	PutStorDevice(Device);
+
+	DPRINT_EXIT(STORVSC);
+	return ret;
+}
+
+static void StorVscOnIOCompletion(struct hv_device *Device,
+				  struct vstor_packet *VStorPacket,
+				  struct storvsc_request_extension *RequestExt)
+{
+	struct hv_storvsc_request *request;
+	struct storvsc_device *storDevice;
+
+	DPRINT_ENTER(STORVSC);
+
+	storDevice = MustGetStorDevice(Device);
+	if (!storDevice) {
+		DPRINT_ERR(STORVSC, "unable to get stor device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(STORVSC);
+		return;
+	}
+
+	DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p "
+		   "completed bytes xfer %u", RequestExt,
+		   VStorPacket->VmSrb.DataTransferLength);
+
+	ASSERT(RequestExt != NULL);
+	ASSERT(RequestExt->Request != NULL);
+
+	request = RequestExt->Request;
+
+	ASSERT(request->OnIOCompletion != NULL);
+
+	/* Copy over the status...etc */
+	request->Status = VStorPacket->VmSrb.ScsiStatus;
+
+	if (request->Status != 0 || VStorPacket->VmSrb.SrbStatus != 1) {
+		DPRINT_WARN(STORVSC,
+			    "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
+			    request->Cdb[0], VStorPacket->VmSrb.ScsiStatus,
+			    VStorPacket->VmSrb.SrbStatus);
+	}
+
+	if ((request->Status & 0xFF) == 0x02) {
+		/* CHECK_CONDITION */
+		if (VStorPacket->VmSrb.SrbStatus & 0x80) {
+			/* autosense data available */
+			DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data "
+				    "valid - len %d\n", RequestExt,
+				    VStorPacket->VmSrb.SenseInfoLength);
+
+			ASSERT(VStorPacket->VmSrb.SenseInfoLength <=
+				request->SenseBufferSize);
+			memcpy(request->SenseBuffer,
+			       VStorPacket->VmSrb.SenseData,
+			       VStorPacket->VmSrb.SenseInfoLength);
+
+			request->SenseBufferSize =
+					VStorPacket->VmSrb.SenseInfoLength;
+		}
+	}
+
+	/* TODO: */
+	request->BytesXfer = VStorPacket->VmSrb.DataTransferLength;
+
+	request->OnIOCompletion(request);
+
+	atomic_dec(&storDevice->NumOutstandingRequests);
+
+	PutStorDevice(Device);
+
+	DPRINT_EXIT(STORVSC);
+}
+
+static void StorVscOnReceive(struct hv_device *Device,
+			     struct vstor_packet *VStorPacket,
+			     struct storvsc_request_extension *RequestExt)
+{
+	switch (VStorPacket->Operation) {
+	case VStorOperationCompleteIo:
+		DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION");
+		StorVscOnIOCompletion(Device, VStorPacket, RequestExt);
+		break;
+	case VStorOperationRemoveDevice:
+		DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION");
+		/* TODO: */
+		break;
+
+	default:
+		DPRINT_INFO(STORVSC, "Unknown operation received - %d",
+			    VStorPacket->Operation);
+		break;
+	}
+}
+
+static void StorVscOnChannelCallback(void *context)
+{
+	struct hv_device *device = (struct hv_device *)context;
+	struct storvsc_device *storDevice;
+	u32 bytesRecvd;
+	u64 requestId;
+	unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)];
+	struct storvsc_request_extension *request;
+	int ret;
+
+	DPRINT_ENTER(STORVSC);
+
+	ASSERT(device);
+
+	storDevice = MustGetStorDevice(device);
+	if (!storDevice) {
+		DPRINT_ERR(STORVSC, "unable to get stor device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(STORVSC);
+		return;
+	}
+
+	do {
+		ret = device->Driver->VmbusChannelInterface.RecvPacket(device,
+				packet,
+				ALIGN_UP(sizeof(struct vstor_packet), 8),
+				&bytesRecvd, &requestId);
+		if (ret == 0 && bytesRecvd > 0) {
+			DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx",
+				   bytesRecvd, requestId);
+
+			/* ASSERT(bytesRecvd == sizeof(struct vstor_packet)); */
+
+			request = (struct storvsc_request_extension *)
+					(unsigned long)requestId;
+			ASSERT(request);
+
+			/* if (vstorPacket.Flags & SYNTHETIC_FLAG) */
+			if ((request == &storDevice->InitRequest) ||
+			    (request == &storDevice->ResetRequest)) {
+				/* DPRINT_INFO(STORVSC,
+				 *             "reset completion - operation "
+				 *             "%u status %u",
+				 *             vstorPacket.Operation,
+				 *             vstorPacket.Status); */
+
+				memcpy(&request->VStorPacket, packet,
+				       sizeof(struct vstor_packet));
+
+				osd_WaitEventSet(request->WaitEvent);
+			} else {
+				StorVscOnReceive(device,
+						(struct vstor_packet *)packet,
+						request);
+			}
+		} else {
+			/* DPRINT_DBG(STORVSC, "nothing else to read..."); */
+			break;
+		}
+	} while (1);
+
+	PutStorDevice(device);
+
+	DPRINT_EXIT(STORVSC);
+	return;
+}
+
+static int StorVscConnectToVsp(struct hv_device *Device)
+{
+	struct vmstorage_channel_properties props;
+	struct storvsc_driver_object *storDriver;
+	int ret;
+
+	storDriver = (struct storvsc_driver_object *)Device->Driver;
+	memset(&props, sizeof(struct vmstorage_channel_properties), 0);
+
+	/* Open the channel */
+	ret = Device->Driver->VmbusChannelInterface.Open(Device,
+			storDriver->RingBufferSize,
+			storDriver->RingBufferSize,
+			(void *)&props,
+			sizeof(struct vmstorage_channel_properties),
+			StorVscOnChannelCallback,
+			Device);
+
+	DPRINT_DBG(STORVSC, "storage props: path id %d, tgt id %d, max xfer %d",
+		   props.PathId, props.TargetId, props.MaxTransferBytes);
+
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC, "unable to open channel: %d", ret);
+		return -1;
+	}
+
+	ret = StorVscChannelInit(Device);
+
+	return ret;
+}
+
+/**
+ * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added
+ */
+static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
+{
+	struct storvsc_device *storDevice;
+	/* struct vmstorage_channel_properties *props; */
+	struct storvsc_device_info *deviceInfo;
+	int ret = 0;
+
+	DPRINT_ENTER(STORVSC);
+
+	deviceInfo = (struct storvsc_device_info *)AdditionalInfo;
+	storDevice = AllocStorDevice(Device);
+	if (!storDevice) {
+		ret = -1;
+		goto Cleanup;
+	}
+
+	/* Save the channel properties to our storvsc channel */
+	/* props = (struct vmstorage_channel_properties *)
+	 * 		channel->offerMsg.Offer.u.Standard.UserDefined; */
+
+	/* FIXME: */
+	/*
+	 * If we support more than 1 scsi channel, we need to set the
+	 * port number here to the scsi channel but how do we get the
+	 * scsi channel prior to the bus scan
+	 */
+
+	/* storChannel->PortNumber = 0;
+	storChannel->PathId = props->PathId;
+	storChannel->TargetId = props->TargetId; */
+
+	storDevice->PortNumber = deviceInfo->PortNumber;
+	/* Send it back up */
+	ret = StorVscConnectToVsp(Device);
+
+	/* deviceInfo->PortNumber = storDevice->PortNumber; */
+	deviceInfo->PathId = storDevice->PathId;
+	deviceInfo->TargetId = storDevice->TargetId;
+
+	DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n",
+		   storDevice->PortNumber, storDevice->PathId,
+		   storDevice->TargetId);
+
+Cleanup:
+	DPRINT_EXIT(STORVSC);
+
+	return ret;
+}
+
+/**
+ * StorVscOnDeviceRemove - Callback when the our device is being removed
+ */
+static int StorVscOnDeviceRemove(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+
+	DPRINT_ENTER(STORVSC);
+
+	DPRINT_INFO(STORVSC, "disabling storage device (%p)...",
+		    Device->Extension);
+
+	storDevice = ReleaseStorDevice(Device);
+
+	/*
+	 * At this point, all outbound traffic should be disable. We
+	 * only allow inbound traffic (responses) to proceed so that
+	 * outstanding requests can be completed.
+	 */
+	while (atomic_read(&storDevice->NumOutstandingRequests)) {
+		DPRINT_INFO(STORVSC, "waiting for %d requests to complete...",
+			    atomic_read(&storDevice->NumOutstandingRequests));
+		udelay(100);
+	}
+
+	DPRINT_INFO(STORVSC, "removing storage device (%p)...",
+		    Device->Extension);
+
+	storDevice = FinalReleaseStorDevice(Device);
+
+	DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", storDevice);
+
+	/* Close the channel */
+	Device->Driver->VmbusChannelInterface.Close(Device);
+
+	FreeStorDevice(storDevice);
+
+	DPRINT_EXIT(STORVSC);
+	return 0;
+}
+
+static int StorVscOnHostReset(struct hv_device *Device)
+{
+	struct storvsc_device *storDevice;
+	struct storvsc_request_extension *request;
+	struct vstor_packet *vstorPacket;
+	int ret;
+
+	DPRINT_ENTER(STORVSC);
+
+	DPRINT_INFO(STORVSC, "resetting host adapter...");
+
+	storDevice = GetStorDevice(Device);
+	if (!storDevice) {
+		DPRINT_ERR(STORVSC, "unable to get stor device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(STORVSC);
+		return -1;
+	}
+
+	request = &storDevice->ResetRequest;
+	vstorPacket = &request->VStorPacket;
+
+	request->WaitEvent = osd_WaitEventCreate();
+
+	vstorPacket->Operation = VStorOperationResetBus;
+	vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
+	vstorPacket->VmSrb.PathId = storDevice->PathId;
+
+	ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				vstorPacket,
+				sizeof(struct vstor_packet),
+				(unsigned long)&storDevice->ResetRequest,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d",
+			   vstorPacket, ret);
+		goto Cleanup;
+	}
+
+	/* FIXME: Add a timeout */
+	osd_WaitEventWait(request->WaitEvent);
+
+	kfree(request->WaitEvent);
+	DPRINT_INFO(STORVSC, "host adapter reset completed");
+
+	/*
+	 * At this point, all outstanding requests in the adapter
+	 * should have been flushed out and return to us
+	 */
+
+Cleanup:
+	PutStorDevice(Device);
+	DPRINT_EXIT(STORVSC);
+	return ret;
+}
+
+/**
+ * StorVscOnIORequest - Callback to initiate an I/O request
+ */
+static int StorVscOnIORequest(struct hv_device *Device,
+			      struct hv_storvsc_request *Request)
+{
+	struct storvsc_device *storDevice;
+	struct storvsc_request_extension *requestExtension;
+	struct vstor_packet *vstorPacket;
+	int ret = 0;
+
+	DPRINT_ENTER(STORVSC);
+
+	requestExtension =
+		(struct storvsc_request_extension *)Request->Extension;
+	vstorPacket = &requestExtension->VStorPacket;
+	storDevice = GetStorDevice(Device);
+
+	DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, "
+		   "Extension %p", Device, storDevice, Request,
+		   requestExtension);
+
+	DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d",
+		   Request, Request->DataBuffer.Length, Request->Bus,
+		   Request->TargetId, Request->LunId, Request->CdbLen);
+
+	if (!storDevice) {
+		DPRINT_ERR(STORVSC, "unable to get stor device..."
+			   "device being destroyed?");
+		DPRINT_EXIT(STORVSC);
+		return -2;
+	}
+
+	/* print_hex_dump_bytes("", DUMP_PREFIX_NONE, Request->Cdb,
+	 * 			Request->CdbLen); */
+
+	requestExtension->Request = Request;
+	requestExtension->Device  = Device;
+
+	memset(vstorPacket, 0 , sizeof(struct vstor_packet));
+
+	vstorPacket->Flags |= REQUEST_COMPLETION_FLAG;
+
+	vstorPacket->VmSrb.Length = sizeof(struct vmscsi_request);
+
+	vstorPacket->VmSrb.PortNumber = Request->Host;
+	vstorPacket->VmSrb.PathId = Request->Bus;
+	vstorPacket->VmSrb.TargetId = Request->TargetId;
+	vstorPacket->VmSrb.Lun = Request->LunId;
+
+	vstorPacket->VmSrb.SenseInfoLength = SENSE_BUFFER_SIZE;
+
+	/* Copy over the scsi command descriptor block */
+	vstorPacket->VmSrb.CdbLength = Request->CdbLen;
+	memcpy(&vstorPacket->VmSrb.Cdb, Request->Cdb, Request->CdbLen);
+
+	vstorPacket->VmSrb.DataIn = Request->Type;
+	vstorPacket->VmSrb.DataTransferLength = Request->DataBuffer.Length;
+
+	vstorPacket->Operation = VStorOperationExecuteSRB;
+
+	DPRINT_DBG(STORVSC, "srb - len %d port %d, path %d, target %d, "
+		   "lun %d senselen %d cdblen %d",
+		   vstorPacket->VmSrb.Length,
+		   vstorPacket->VmSrb.PortNumber,
+		   vstorPacket->VmSrb.PathId,
+		   vstorPacket->VmSrb.TargetId,
+		   vstorPacket->VmSrb.Lun,
+		   vstorPacket->VmSrb.SenseInfoLength,
+		   vstorPacket->VmSrb.CdbLength);
+
+	if (requestExtension->Request->DataBuffer.Length) {
+		ret = Device->Driver->VmbusChannelInterface.
+			SendPacketMultiPageBuffer(Device,
+				&requestExtension->Request->DataBuffer,
+				vstorPacket,
+				sizeof(struct vstor_packet),
+				(unsigned long)requestExtension);
+	} else {
+		ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
+				vstorPacket,
+				sizeof(struct vstor_packet),
+				(unsigned long)requestExtension,
+				VmbusPacketTypeDataInBand,
+				VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	}
+
+	if (ret != 0) {
+		DPRINT_DBG(STORVSC, "Unable to send packet %p ret %d",
+			   vstorPacket, ret);
+	}
+
+	atomic_inc(&storDevice->NumOutstandingRequests);
+
+	PutStorDevice(Device);
+
+	DPRINT_EXIT(STORVSC);
+	return ret;
+}
+
+/**
+ * StorVscOnCleanup - Perform any cleanup when the driver is removed
+ */
+static void StorVscOnCleanup(struct hv_driver *Driver)
+{
+	DPRINT_ENTER(STORVSC);
+	DPRINT_EXIT(STORVSC);
+}
+
+/**
+ * StorVscInitialize - Main entry point
+ */
+int StorVscInitialize(struct hv_driver *Driver)
+{
+	struct storvsc_driver_object *storDriver;
+
+	DPRINT_ENTER(STORVSC);
+
+	storDriver = (struct storvsc_driver_object *)Driver;
+
+	DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd "
+		   "sizeof(struct storvsc_request_extension)=%zd "
+		   "sizeof(struct vstor_packet)=%zd, "
+		   "sizeof(struct vmscsi_request)=%zd",
+		   sizeof(struct hv_storvsc_request),
+		   sizeof(struct storvsc_request_extension),
+		   sizeof(struct vstor_packet),
+		   sizeof(struct vmscsi_request));
+
+	/* Make sure we are at least 2 pages since 1 page is used for control */
+	ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1));
+
+	Driver->name = gDriverName;
+	memcpy(&Driver->deviceType, &gStorVscDeviceType,
+	       sizeof(struct hv_guid));
+
+	storDriver->RequestExtSize = sizeof(struct storvsc_request_extension);
+
+	/*
+	 * Divide the ring buffer data size (which is 1 page less
+	 * than the ring buffer size since that page is reserved for
+	 * the ring buffer indices) by the max request size (which is
+	 * VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + struct vstor_packet + u64)
+	 */
+	storDriver->MaxOutstandingRequestsPerChannel =
+		((storDriver->RingBufferSize - PAGE_SIZE) /
+		  ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET +
+			   sizeof(struct vstor_packet) + sizeof(u64),
+			   sizeof(u64)));
+
+	DPRINT_INFO(STORVSC, "max io %u, currently %u\n",
+		    storDriver->MaxOutstandingRequestsPerChannel,
+		    STORVSC_MAX_IO_REQUESTS);
+
+	/* Setup the dispatch table */
+	storDriver->Base.OnDeviceAdd	= StorVscOnDeviceAdd;
+	storDriver->Base.OnDeviceRemove	= StorVscOnDeviceRemove;
+	storDriver->Base.OnCleanup	= StorVscOnCleanup;
+
+	storDriver->OnIORequest		= StorVscOnIORequest;
+	storDriver->OnHostReset		= StorVscOnHostReset;
+
+	DPRINT_EXIT(STORVSC);
+
+	return 0;
+}
diff --git a/drivers/staging/hv/StorVscApi.h b/drivers/staging/hv/StorVscApi.h
new file mode 100644
index 0000000..69c1406
--- /dev/null
+++ b/drivers/staging/hv/StorVscApi.h
@@ -0,0 +1,113 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _STORVSC_API_H_
+#define _STORVSC_API_H_
+
+#include "VmbusApi.h"
+
+/* Defines */
+#define STORVSC_RING_BUFFER_SIZE			(10*PAGE_SIZE)
+#define BLKVSC_RING_BUFFER_SIZE				(20*PAGE_SIZE)
+
+#define STORVSC_MAX_IO_REQUESTS				64
+
+/*
+ * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
+ * reality, the path/target is not used (ie always set to 0) so our
+ * scsi host adapter essentially has 1 bus with 1 target that contains
+ * up to 256 luns.
+ */
+#define STORVSC_MAX_LUNS_PER_TARGET			64
+#define STORVSC_MAX_TARGETS				1
+#define STORVSC_MAX_CHANNELS				1
+
+struct hv_storvsc_request;
+
+/* Matches Windows-end */
+enum storvsc_request_type{
+	WRITE_TYPE,
+	READ_TYPE,
+	UNKNOWN_TYPE,
+};
+
+struct hv_storvsc_request {
+	enum storvsc_request_type Type;
+	u32 Host;
+	u32 Bus;
+	u32 TargetId;
+	u32 LunId;
+	u8 *Cdb;
+	u32 CdbLen;
+	u32 Status;
+	u32 BytesXfer;
+
+	unsigned char *SenseBuffer;
+	u32 SenseBufferSize;
+
+	void *Context;
+
+	void (*OnIOCompletion)(struct hv_storvsc_request *Request);
+
+	/* This points to the memory after DataBuffer */
+	void *Extension;
+
+	struct hv_multipage_buffer DataBuffer;
+};
+
+/* Represents the block vsc driver */
+struct storvsc_driver_object {
+	/* Must be the first field */
+	/* Which is a bug FIXME! */
+	struct hv_driver Base;
+
+	/* Set by caller (in bytes) */
+	u32 RingBufferSize;
+
+	/* Allocate this much private extension for each I/O request */
+	u32 RequestExtSize;
+
+	/* Maximum # of requests in flight per channel/device */
+	u32 MaxOutstandingRequestsPerChannel;
+
+	/* Set by the caller to allow us to re-enumerate the bus on the host */
+	void (*OnHostRescan)(struct hv_device *Device);
+
+	/* Specific to this driver */
+	int (*OnIORequest)(struct hv_device *Device,
+			   struct hv_storvsc_request *Request);
+	int (*OnHostReset)(struct hv_device *Device);
+};
+
+struct storvsc_device_info {
+	unsigned int PortNumber;
+	unsigned char PathId;
+	unsigned char TargetId;
+};
+
+/* Interface */
+int StorVscInitialize(struct hv_driver *driver);
+int BlkVscInitialize(struct hv_driver *driver);
+
+#endif /* _STORVSC_API_H_ */
diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO
new file mode 100644
index 0000000..4d390b2
--- /dev/null
+++ b/drivers/staging/hv/TODO
@@ -0,0 +1,13 @@
+TODO:
+	- fix remaining checkpatch warnings and errors
+	- remove RingBuffer.c to us in-kernel ringbuffer functions instead.
+	- audit the vmbus to verify it is working properly with the
+	  driver model
+	- see if the vmbus can be merged with the other virtual busses
+	  in the kernel
+	- audit the network driver
+	- audit the block driver
+	- audit the scsi driver
+
+Please send patches for this code to Greg Kroah-Hartman <gregkh@suse.de>,
+Hank Janssen <hjanssen@microsoft.com>, and Haiyang Zhang <haiyangz@microsoft.com>.
diff --git a/drivers/staging/hv/VersionInfo.h b/drivers/staging/hv/VersionInfo.h
new file mode 100644
index 0000000..9c3641d
--- /dev/null
+++ b/drivers/staging/hv/VersionInfo.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+#ifndef __HV_VERSION_INFO
+#define __HV_VERSION_INFO
+
+static const char VersionDate[] = __DATE__;
+static const char VersionTime[] = __TIME__;
+static const char VersionDesc[] = "Version 2.0";
+
+#endif
diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/Vmbus.c
new file mode 100644
index 0000000..a4dd06f
--- /dev/null
+++ b/drivers/staging/hv/Vmbus.c
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include "osd.h"
+#include "logging.h"
+#include "VersionInfo.h"
+#include "VmbusPrivate.h"
+
+static const char *gDriverName = "vmbus";
+
+/*
+ * Windows vmbus does not defined this.
+ * We defined this to be consistent with other devices
+ */
+/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */
+static const struct hv_guid gVmbusDeviceType = {
+	.data = {
+		0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d,
+		0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85
+	}
+};
+
+/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */
+static const struct hv_guid gVmbusDeviceId = {
+	.data = {
+		0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40,
+		0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5
+	}
+};
+
+static struct hv_driver *gDriver; /* vmbus driver object */
+static struct hv_device *gDevice; /* vmbus root device */
+
+/**
+ * VmbusGetChannelOffers - Retrieve the channel offers from the parent partition
+ */
+static void VmbusGetChannelOffers(void)
+{
+	DPRINT_ENTER(VMBUS);
+	VmbusChannelRequestOffers();
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusGetChannelInterface - Get the channel interface
+ */
+static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface)
+{
+	GetChannelInterface(Interface);
+}
+
+/**
+ * VmbusGetChannelInfo - Get the device info for the specified device object
+ */
+static void VmbusGetChannelInfo(struct hv_device *DeviceObject,
+				struct hv_device_info *DeviceInfo)
+{
+	GetChannelInfo(DeviceObject, DeviceInfo);
+}
+
+/**
+ * VmbusCreateChildDevice - Creates the child device on the bus that represents the channel offer
+ */
+struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType,
+					 struct hv_guid *DeviceInstance,
+					 void *Context)
+{
+	struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver;
+
+	return vmbusDriver->OnChildDeviceCreate(DeviceType, DeviceInstance,
+						Context);
+}
+
+/**
+ * VmbusChildDeviceAdd - Registers the child device with the vmbus
+ */
+int VmbusChildDeviceAdd(struct hv_device *ChildDevice)
+{
+	struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver;
+
+	return vmbusDriver->OnChildDeviceAdd(gDevice, ChildDevice);
+}
+
+/**
+ * VmbusChildDeviceRemove Unregisters the child device from the vmbus
+ */
+void VmbusChildDeviceRemove(struct hv_device *ChildDevice)
+{
+	struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver;
+
+	vmbusDriver->OnChildDeviceRemove(ChildDevice);
+}
+
+/**
+ * VmbusOnDeviceAdd - Callback when the root bus device is added
+ */
+static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo)
+{
+	u32 *irqvector = AdditionalInfo;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+
+	gDevice = dev;
+
+	memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid));
+	memcpy(&gDevice->deviceInstance, &gVmbusDeviceId,
+	       sizeof(struct hv_guid));
+
+	/* strcpy(dev->name, "vmbus"); */
+	/* SynIC setup... */
+	ret = HvSynicInit(*irqvector);
+
+	/* Connect to VMBus in the root partition */
+	ret = VmbusConnect();
+
+	/* VmbusSendEvent(device->localPortId+1); */
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusOnDeviceRemove - Callback when the root bus device is removed
+ */
+static int VmbusOnDeviceRemove(struct hv_device *dev)
+{
+	int ret = 0;
+
+	DPRINT_ENTER(VMBUS);
+	VmbusChannelReleaseUnattachedChannels();
+	VmbusDisconnect();
+	HvSynicCleanup();
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
+
+/**
+ * VmbusOnCleanup - Perform any cleanup when the driver is removed
+ */
+static void VmbusOnCleanup(struct hv_driver *drv)
+{
+	/* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */
+
+	DPRINT_ENTER(VMBUS);
+	HvCleanup();
+	DPRINT_EXIT(VMBUS);
+}
+
+/**
+ * VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior
+ */
+static void VmbusOnMsgDPC(struct hv_driver *drv)
+{
+	void *page_addr = gHvContext.synICMessagePage[0];
+	struct hv_message *msg = (struct hv_message *)page_addr +
+				  VMBUS_MESSAGE_SINT;
+	struct hv_message *copied;
+
+	while (1) {
+		if (msg->Header.MessageType == HvMessageTypeNone) {
+			/* no msg */
+			break;
+		} else {
+			copied = kmalloc(sizeof(*copied), GFP_ATOMIC);
+			if (copied == NULL)
+				continue;
+
+			memcpy(copied, msg, sizeof(*copied));
+			osd_schedule_callback(gVmbusConnection.WorkQueue,
+					      VmbusOnChannelMessage,
+					      (void *)copied);
+		}
+
+		msg->Header.MessageType = HvMessageTypeNone;
+
+		/*
+		 * Make sure the write to MessageType (ie set to
+		 * HvMessageTypeNone) happens before we read the
+		 * MessagePending and EOMing. Otherwise, the EOMing
+		 * will not deliver any more messages since there is
+		 * no empty slot
+		 */
+		mb();
+
+		if (msg->Header.MessageFlags.MessagePending) {
+			/*
+			 * This will cause message queue rescan to
+			 * possibly deliver another msg from the
+			 * hypervisor
+			 */
+			wrmsrl(HV_X64_MSR_EOM, 0);
+		}
+	}
+}
+
+/**
+ * VmbusOnEventDPC - DPC routine to handle events from the hypervisior
+ */
+static void VmbusOnEventDPC(struct hv_driver *drv)
+{
+	/* TODO: Process any events */
+	VmbusOnEvents();
+}
+
+/**
+ * VmbusOnISR - ISR routine
+ */
+static int VmbusOnISR(struct hv_driver *drv)
+{
+	int ret = 0;
+	void *page_addr;
+	struct hv_message *msg;
+	union hv_synic_event_flags *event;
+
+	page_addr = gHvContext.synICMessagePage[0];
+	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
+
+	DPRINT_ENTER(VMBUS);
+
+	/* Check if there are actual msgs to be process */
+	if (msg->Header.MessageType != HvMessageTypeNone) {
+		DPRINT_DBG(VMBUS, "received msg type %d size %d",
+				msg->Header.MessageType,
+				msg->Header.PayloadSize);
+		ret |= 0x1;
+	}
+
+	/* TODO: Check if there are events to be process */
+	page_addr = gHvContext.synICEventPage[0];
+	event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
+
+	/* Since we are a child, we only need to check bit 0 */
+	if (test_and_clear_bit(0, (unsigned long *) &event->Flags32[0])) {
+		DPRINT_DBG(VMBUS, "received event %d", event->Flags32[0]);
+		ret |= 0x2;
+	}
+
+	DPRINT_EXIT(VMBUS);
+	return ret;
+}
+
+/**
+ * VmbusInitialize - Main entry point
+ */
+int VmbusInitialize(struct hv_driver *drv)
+{
+	struct vmbus_driver *driver = (struct vmbus_driver *)drv;
+	int ret;
+
+	DPRINT_ENTER(VMBUS);
+
+	DPRINT_INFO(VMBUS, "+++++++ Build Date=%s %s +++++++",
+			VersionDate, VersionTime);
+	DPRINT_INFO(VMBUS, "+++++++ Build Description=%s +++++++",
+			VersionDesc);
+	DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++",
+			VMBUS_REVISION_NUMBER);
+	DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++",
+			VMBUS_MESSAGE_SINT);
+	DPRINT_DBG(VMBUS, "sizeof(VMBUS_CHANNEL_PACKET_PAGE_BUFFER)=%zd, "
+			"sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd",
+			sizeof(struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER),
+			sizeof(struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER));
+
+	drv->name = gDriverName;
+	memcpy(&drv->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid));
+
+	/* Setup dispatch table */
+	driver->Base.OnDeviceAdd	= VmbusOnDeviceAdd;
+	driver->Base.OnDeviceRemove	= VmbusOnDeviceRemove;
+	driver->Base.OnCleanup		= VmbusOnCleanup;
+	driver->OnIsr			= VmbusOnISR;
+	driver->OnMsgDpc		= VmbusOnMsgDPC;
+	driver->OnEventDpc		= VmbusOnEventDPC;
+	driver->GetChannelOffers	= VmbusGetChannelOffers;
+	driver->GetChannelInterface	= VmbusGetChannelInterface;
+	driver->GetChannelInfo		= VmbusGetChannelInfo;
+
+	/* Hypervisor initialization...setup hypercall page..etc */
+	ret = HvInit();
+	if (ret != 0)
+		DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x",
+				ret);
+	gDriver = drv;
+
+	DPRINT_EXIT(VMBUS);
+
+	return ret;
+}
diff --git a/drivers/staging/hv/VmbusApi.h b/drivers/staging/hv/VmbusApi.h
new file mode 100644
index 0000000..d089bb1
--- /dev/null
+++ b/drivers/staging/hv/VmbusApi.h
@@ -0,0 +1,175 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _VMBUS_API_H_
+#define _VMBUS_API_H_
+
+#define MAX_PAGE_BUFFER_COUNT				16
+#define MAX_MULTIPAGE_BUFFER_COUNT			32 /* 128K */
+
+#pragma pack(push, 1)
+
+/* Single-page buffer */
+struct hv_page_buffer {
+	u32 Length;
+	u32 Offset;
+	u64 Pfn;
+};
+
+/* Multiple-page buffer */
+struct hv_multipage_buffer {
+	/* Length and Offset determines the # of pfns in the array */
+	u32 Length;
+	u32 Offset;
+	u64 PfnArray[MAX_MULTIPAGE_BUFFER_COUNT];
+};
+
+/* 0x18 includes the proprietary packet header */
+#define MAX_PAGE_BUFFER_PACKET		(0x18 +			\
+					(sizeof(struct hv_page_buffer) * \
+					 MAX_PAGE_BUFFER_COUNT))
+#define MAX_MULTIPAGE_BUFFER_PACKET	(0x18 +			\
+					 sizeof(struct hv_multipage_buffer))
+
+
+#pragma pack(pop)
+
+struct hv_driver;
+struct hv_device;
+
+struct hv_dev_port_info {
+	u32 InterruptMask;
+	u32 ReadIndex;
+	u32 WriteIndex;
+	u32 BytesAvailToRead;
+	u32 BytesAvailToWrite;
+};
+
+struct hv_device_info {
+	u32 ChannelId;
+	u32 ChannelState;
+	struct hv_guid ChannelType;
+	struct hv_guid ChannelInstance;
+
+	u32 MonitorId;
+	u32 ServerMonitorPending;
+	u32 ServerMonitorLatency;
+	u32 ServerMonitorConnectionId;
+	u32 ClientMonitorPending;
+	u32 ClientMonitorLatency;
+	u32 ClientMonitorConnectionId;
+
+	struct hv_dev_port_info Inbound;
+	struct hv_dev_port_info Outbound;
+};
+
+struct vmbus_channel_interface {
+	int (*Open)(struct hv_device *Device, u32 SendBufferSize,
+		    u32 RecvRingBufferSize, void *UserData, u32 UserDataLen,
+		    void (*ChannelCallback)(void *context),
+		    void *Context);
+	void (*Close)(struct hv_device *device);
+	int (*SendPacket)(struct hv_device *Device, const void *Buffer,
+			  u32 BufferLen, u64 RequestId, u32 Type, u32 Flags);
+	int (*SendPacketPageBuffer)(struct hv_device *dev,
+				    struct hv_page_buffer PageBuffers[],
+				    u32 PageCount, void *Buffer, u32 BufferLen,
+				    u64 RequestId);
+	int (*SendPacketMultiPageBuffer)(struct hv_device *device,
+					 struct hv_multipage_buffer *mpb,
+					 void *Buffer,
+					 u32 BufferLen,
+					 u64 RequestId);
+	int (*RecvPacket)(struct hv_device *dev, void *buf, u32 buflen,
+			  u32 *BufferActualLen, u64 *RequestId);
+	int (*RecvPacketRaw)(struct hv_device *dev, void *buf, u32 buflen,
+			     u32 *BufferActualLen, u64 *RequestId);
+	int (*EstablishGpadl)(struct hv_device *dev, void *buf, u32 buflen,
+			      u32 *GpadlHandle);
+	int (*TeardownGpadl)(struct hv_device *device, u32 GpadlHandle);
+	void (*GetInfo)(struct hv_device *dev, struct hv_device_info *devinfo);
+};
+
+/* Base driver object */
+struct hv_driver {
+	const char *name;
+
+	/* the device type supported by this driver */
+	struct hv_guid deviceType;
+
+	int (*OnDeviceAdd)(struct hv_device *device, void *data);
+	int (*OnDeviceRemove)(struct hv_device *device);
+	void (*OnCleanup)(struct hv_driver *driver);
+
+	struct vmbus_channel_interface VmbusChannelInterface;
+};
+
+/* Base device object */
+struct hv_device {
+	/* the driver for this device */
+	struct hv_driver *Driver;
+
+	char name[64];
+
+	/* the device type id of this device */
+	struct hv_guid deviceType;
+
+	/* the device instance id of this device */
+	struct hv_guid deviceInstance;
+
+	void *context;
+
+	/* Device extension; */
+	void *Extension;
+};
+
+/* Vmbus driver object */
+struct vmbus_driver {
+	/* !! Must be the 1st field !! */
+	/* FIXME if ^, then someone is doing somthing stupid */
+	struct hv_driver Base;
+
+	/* Set by the caller */
+	struct hv_device * (*OnChildDeviceCreate)(struct hv_guid *DeviceType,
+						struct hv_guid *DeviceInstance,
+						void *Context);
+	void (*OnChildDeviceDestroy)(struct hv_device *device);
+	int (*OnChildDeviceAdd)(struct hv_device *RootDevice,
+				struct hv_device *ChildDevice);
+	void (*OnChildDeviceRemove)(struct hv_device *device);
+
+	/* Set by the callee */
+	int (*OnIsr)(struct hv_driver *driver);
+	void (*OnMsgDpc)(struct hv_driver *driver);
+	void (*OnEventDpc)(struct hv_driver *driver);
+	void (*GetChannelOffers)(void);
+
+	void (*GetChannelInterface)(struct vmbus_channel_interface *i);
+	void (*GetChannelInfo)(struct hv_device *dev,
+			       struct hv_device_info *devinfo);
+};
+
+int VmbusInitialize(struct hv_driver *drv);
+
+#endif /* _VMBUS_API_H_ */
diff --git a/drivers/staging/hv/VmbusChannelInterface.h b/drivers/staging/hv/VmbusChannelInterface.h
new file mode 100644
index 0000000..2674282
--- /dev/null
+++ b/drivers/staging/hv/VmbusChannelInterface.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+#ifndef __VMBUSCHANNELINTERFACE_H
+#define __VMBUSCHANNELINTERFACE_H
+
+/*
+ * A revision number of vmbus that is used for ensuring both ends on a
+ * partition are using compatible versions.
+ */
+#define VMBUS_REVISION_NUMBER		13
+
+/* Make maximum size of pipe payload of 16K */
+#define MAX_PIPE_DATA_PAYLOAD		(sizeof(u8) * 16384)
+
+/* Define PipeMode values. */
+#define VMBUS_PIPE_TYPE_BYTE		0x00000000
+#define VMBUS_PIPE_TYPE_MESSAGE		0x00000004
+
+/* The size of the user defined data buffer for non-pipe offers. */
+#define MAX_USER_DEFINED_BYTES		120
+
+/* The size of the user defined data buffer for pipe offers. */
+#define MAX_PIPE_USER_DEFINED_BYTES	116
+
+/*
+ * At the center of the Channel Management library is the Channel Offer. This
+ * struct contains the fundamental information about an offer.
+ */
+struct vmbus_channel_offer {
+	struct hv_guid InterfaceType;
+	struct hv_guid InterfaceInstance;
+	u64 InterruptLatencyIn100nsUnits;
+	u32 InterfaceRevision;
+	u32 ServerContextAreaSize;	/* in bytes */
+	u16 ChannelFlags;
+	u16 MmioMegabytes;		/* in bytes * 1024 * 1024 */
+
+	union {
+		/* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */
+		struct {
+			unsigned char UserDefined[MAX_USER_DEFINED_BYTES];
+		} Standard;
+
+		/*
+		 * Pipes:
+		 * The following sructure is an integrated pipe protocol, which
+		 * is implemented on top of standard user-defined data. Pipe
+		 * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own
+		 * use.
+		 */
+		struct {
+			u32  PipeMode;
+			unsigned char UserDefined[MAX_PIPE_USER_DEFINED_BYTES];
+		} Pipe;
+	} u;
+	u32 Padding;
+} __attribute__((packed));
+
+/* Server Flags */
+#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE	1
+#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES	2
+#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS		4
+#define VMBUS_CHANNEL_NAMED_PIPE_MODE			0x10
+#define VMBUS_CHANNEL_LOOPBACK_OFFER			0x100
+#define VMBUS_CHANNEL_PARENT_OFFER			0x200
+#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION	0x400
+
+#endif
diff --git a/drivers/staging/hv/VmbusPacketFormat.h b/drivers/staging/hv/VmbusPacketFormat.h
new file mode 100644
index 0000000..79120bc
--- /dev/null
+++ b/drivers/staging/hv/VmbusPacketFormat.h
@@ -0,0 +1,160 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+#ifndef _VMBUSPACKETFORMAT_H_
+
+struct vmpacket_descriptor {
+	u16 Type;
+	u16 DataOffset8;
+	u16 Length8;
+	u16 Flags;
+	u64 TransactionId;
+} __attribute__((packed));
+
+struct vmpacket_header {
+	u32 PreviousPacketStartOffset;
+	struct vmpacket_descriptor Descriptor;
+} __attribute__((packed));
+
+struct vmtransfer_page_range {
+	u32 ByteCount;
+	u32 ByteOffset;
+} __attribute__((packed));
+
+struct vmtransfer_page_packet_header {
+	struct vmpacket_descriptor d;
+	u16 TransferPageSetId;
+	bool SenderOwnsSet;
+	u8 Reserved;
+	u32 RangeCount;
+	struct vmtransfer_page_range Ranges[1];
+} __attribute__((packed));
+
+struct vmgpadl_packet_header {
+	struct vmpacket_descriptor d;
+	u32 Gpadl;
+	u32 Reserved;
+} __attribute__((packed));
+
+struct vmadd_remove_transfer_page_set {
+	struct vmpacket_descriptor d;
+	u32 Gpadl;
+	u16 TransferPageSetId;
+	u16 Reserved;
+} __attribute__((packed));
+
+/*
+ * This structure defines a range in guest physical space that can be made to
+ * look virtually contiguous.
+ */
+struct gpa_range {
+	u32 ByteCount;
+	u32 ByteOffset;
+	u64 PfnArray[0];
+};
+
+/*
+ * This is the format for an Establish Gpadl packet, which contains a handle by
+ * which this GPADL will be known and a set of GPA ranges associated with it.
+ * This can be converted to a MDL by the guest OS.  If there are multiple GPA
+ * ranges, then the resulting MDL will be "chained," representing multiple VA
+ * ranges.
+ */
+struct vmestablish_gpadl {
+	struct vmpacket_descriptor d;
+	u32 Gpadl;
+	u32 RangeCount;
+	struct gpa_range Range[1];
+} __attribute__((packed));
+
+/*
+ * This is the format for a Teardown Gpadl packet, which indicates that the
+ * GPADL handle in the Establish Gpadl packet will never be referenced again.
+ */
+struct vmteardown_gpadl {
+	struct vmpacket_descriptor d;
+	u32 Gpadl;
+	u32 Reserved;	/* for alignment to a 8-byte boundary */
+} __attribute__((packed));
+
+/*
+ * This is the format for a GPA-Direct packet, which contains a set of GPA
+ * ranges, in addition to commands and/or data.
+ */
+struct vmdata_gpa_direct {
+	struct vmpacket_descriptor d;
+	u32 Reserved;
+	u32 RangeCount;
+	struct gpa_range Range[1];
+} __attribute__((packed));
+
+/* This is the format for a Additional Data Packet. */
+struct vmadditional_data {
+	struct vmpacket_descriptor d;
+	u64 TotalBytes;
+	u32 ByteOffset;
+	u32 ByteCount;
+	unsigned char Data[1];
+} __attribute__((packed));
+
+union vmpacket_largest_possible_header {
+	struct vmpacket_descriptor SimpleHeader;
+	struct vmtransfer_page_packet_header TransferPageHeader;
+	struct vmgpadl_packet_header GpadlHeader;
+	struct vmadd_remove_transfer_page_set AddRemoveTransferPageHeader;
+	struct vmestablish_gpadl EstablishGpadlHeader;
+	struct vmteardown_gpadl TeardownGpadlHeader;
+	struct vmdata_gpa_direct DataGpaDirectHeader;
+};
+
+#define VMPACKET_DATA_START_ADDRESS(__packet)	\
+	(void *)(((unsigned char *)__packet) +	\
+	 ((struct vmpacket_descriptor)__packet)->DataOffset8 * 8)
+
+#define VMPACKET_DATA_LENGTH(__packet)		\
+	((((struct vmpacket_descriptor)__packet)->Length8 -	\
+	  ((struct vmpacket_descriptor)__packet)->DataOffset8) * 8)
+
+#define VMPACKET_TRANSFER_MODE(__packet)	\
+	(((struct IMPACT)__packet)->Type)
+
+enum vmbus_packet_type {
+	VmbusPacketTypeInvalid				= 0x0,
+	VmbusPacketTypeSynch				= 0x1,
+	VmbusPacketTypeAddTransferPageSet		= 0x2,
+	VmbusPacketTypeRemoveTransferPageSet		= 0x3,
+	VmbusPacketTypeEstablishGpadl			= 0x4,
+	VmbusPacketTypeTearDownGpadl			= 0x5,
+	VmbusPacketTypeDataInBand			= 0x6,
+	VmbusPacketTypeDataUsingTransferPages		= 0x7,
+	VmbusPacketTypeDataUsingGpadl			= 0x8,
+	VmbusPacketTypeDataUsingGpaDirect		= 0x9,
+	VmbusPacketTypeCancelRequest			= 0xa,
+	VmbusPacketTypeCompletion			= 0xb,
+	VmbusPacketTypeDataUsingAdditionalPackets	= 0xc,
+	VmbusPacketTypeAdditionalData			= 0xd
+};
+
+#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED	1
+
+#endif
diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/VmbusPrivate.h
new file mode 100644
index 0000000..05ad2c9
--- /dev/null
+++ b/drivers/staging/hv/VmbusPrivate.h
@@ -0,0 +1,134 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _VMBUS_PRIVATE_H_
+#define _VMBUS_PRIVATE_H_
+
+#include "Hv.h"
+#include "VmbusApi.h"
+#include "Channel.h"
+#include "ChannelMgmt.h"
+#include "ChannelInterface.h"
+#include "RingBuffer.h"
+#include <linux/list.h>
+
+
+/*
+ * Maximum channels is determined by the size of the interrupt page
+ * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
+ * and the other is receive endpoint interrupt
+ */
+#define MAX_NUM_CHANNELS	((PAGE_SIZE >> 1) << 3)	/* 16348 channels */
+
+/* The value here must be in multiple of 32 */
+/* TODO: Need to make this configurable */
+#define MAX_NUM_CHANNELS_SUPPORTED	256
+
+
+enum VMBUS_CONNECT_STATE {
+	Disconnected,
+	Connecting,
+	Connected,
+	Disconnecting
+};
+
+#define MAX_SIZE_CHANNEL_MESSAGE	HV_MESSAGE_PAYLOAD_BYTE_COUNT
+
+struct VMBUS_CONNECTION {
+	enum VMBUS_CONNECT_STATE ConnectState;
+
+	atomic_t NextGpadlHandle;
+
+	/*
+	 * Represents channel interrupts. Each bit position represents a
+	 * channel.  When a channel sends an interrupt via VMBUS, it finds its
+	 * bit in the sendInterruptPage, set it and calls Hv to generate a port
+	 * event. The other end receives the port event and parse the
+	 * recvInterruptPage to see which bit is set
+	 */
+	void *InterruptPage;
+	void *SendInterruptPage;
+	void *RecvInterruptPage;
+
+	/*
+	 * 2 pages - 1st page for parent->child notification and 2nd
+	 * is child->parent notification
+	 */
+	void *MonitorPages;
+	struct list_head ChannelMsgList;
+	spinlock_t channelmsg_lock;
+
+	/* List of channels */
+	struct list_head ChannelList;
+	spinlock_t channel_lock;
+
+	struct workqueue_struct *WorkQueue;
+};
+
+
+struct VMBUS_MSGINFO {
+	/* Bookkeeping stuff */
+	struct list_head MsgListEntry;
+
+	/* Synchronize the request/response if needed */
+	struct osd_waitevent *WaitEvent;
+
+	/* The message itself */
+	unsigned char Msg[0];
+};
+
+
+extern struct VMBUS_CONNECTION gVmbusConnection;
+
+/* General vmbus interface */
+
+struct hv_device *VmbusChildDeviceCreate(struct hv_guid *deviceType,
+					 struct hv_guid *deviceInstance,
+					 void *context);
+
+int VmbusChildDeviceAdd(struct hv_device *Device);
+
+void VmbusChildDeviceRemove(struct hv_device *Device);
+
+/* static void */
+/* VmbusChildDeviceDestroy( */
+/* struct hv_device *); */
+
+struct vmbus_channel *GetChannelFromRelId(u32 relId);
+
+
+/* Connection interface */
+
+int VmbusConnect(void);
+
+int VmbusDisconnect(void);
+
+int VmbusPostMessage(void *buffer, size_t bufSize);
+
+int VmbusSetEvent(u32 childRelId);
+
+void VmbusOnEvents(void);
+
+
+#endif /* _VMBUS_PRIVATE_H_ */
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
new file mode 100644
index 0000000..99c4926
--- /dev/null
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -0,0 +1,1511 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/blkdev.h>
+#include <linux/major.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_dbg.h>
+#include "osd.h"
+#include "logging.h"
+#include "vmbus.h"
+#include "StorVscApi.h"
+
+
+#define BLKVSC_MINORS	64
+
+enum blkvsc_device_type {
+	UNKNOWN_DEV_TYPE,
+	HARDDISK_TYPE,
+	DVD_TYPE,
+};
+
+/*
+ * This request ties the struct request and struct
+ * blkvsc_request/hv_storvsc_request together A struct request may be
+ * represented by 1 or more struct blkvsc_request
+ */
+struct blkvsc_request_group {
+	int outstanding;
+	int status;
+	struct list_head blkvsc_req_list;	/* list of blkvsc_requests */
+};
+
+struct blkvsc_request {
+	/* blkvsc_request_group.blkvsc_req_list */
+	struct list_head req_entry;
+
+	/* block_device_context.pending_list */
+	struct list_head pend_entry;
+
+	/* This may be null if we generate a request internally */
+	struct request *req;
+
+	struct block_device_context *dev;
+
+	/* The group this request is part of. Maybe null */
+	struct blkvsc_request_group *group;
+
+	wait_queue_head_t wevent;
+	int cond;
+
+	int write;
+	sector_t sector_start;
+	unsigned long sector_count;
+
+	unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
+	unsigned char cmd_len;
+	unsigned char cmnd[MAX_COMMAND_SIZE];
+
+	struct hv_storvsc_request request;
+	/*
+	 * !!!DO NOT ADD ANYTHING BELOW HERE!!! Otherwise, memory can overlap,
+	 * because - The extension buffer falls right here and is pointed to by
+	 * request.Extension;
+	 * Which sounds like a horrible idea, who designed this?
+	 */
+};
+
+/* Per device structure */
+struct block_device_context {
+	/* point back to our device context */
+	struct device_context *device_ctx;
+	struct kmem_cache *request_pool;
+	spinlock_t lock;
+	struct gendisk *gd;
+	enum blkvsc_device_type	device_type;
+	struct list_head pending_list;
+
+	unsigned char device_id[64];
+	unsigned int device_id_len;
+	int num_outstanding_reqs;
+	int shutting_down;
+	int media_not_present;
+	unsigned int sector_size;
+	sector_t capacity;
+	unsigned int port;
+	unsigned char path;
+	unsigned char target;
+	int users;
+};
+
+/* Per driver */
+struct blkvsc_driver_context {
+	/* !! These must be the first 2 fields !! */
+	/* FIXME this is a bug! */
+	struct driver_context drv_ctx;
+	struct storvsc_driver_object drv_obj;
+};
+
+/* Static decl */
+static int blkvsc_probe(struct device *dev);
+static int blkvsc_remove(struct device *device);
+static void blkvsc_shutdown(struct device *device);
+
+static int blkvsc_open(struct block_device *bdev,  fmode_t mode);
+static int blkvsc_release(struct gendisk *disk, fmode_t mode);
+static int blkvsc_media_changed(struct gendisk *gd);
+static int blkvsc_revalidate_disk(struct gendisk *gd);
+static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg);
+static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
+			unsigned cmd, unsigned long argument);
+static void blkvsc_request(struct request_queue *queue);
+static void blkvsc_request_completion(struct hv_storvsc_request *request);
+static int blkvsc_do_request(struct block_device_context *blkdev,
+			     struct request *req);
+static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
+		void (*request_completion)(struct hv_storvsc_request *));
+static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req);
+static void blkvsc_cmd_completion(struct hv_storvsc_request *request);
+static int blkvsc_do_inquiry(struct block_device_context *blkdev);
+static int blkvsc_do_read_capacity(struct block_device_context *blkdev);
+static int blkvsc_do_read_capacity16(struct block_device_context *blkdev);
+static int blkvsc_do_flush(struct block_device_context *blkdev);
+static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev);
+static int blkvsc_do_pending_reqs(struct block_device_context *blkdev);
+
+
+static int blkvsc_ringbuffer_size = BLKVSC_RING_BUFFER_SIZE;
+
+/* The one and only one */
+static struct blkvsc_driver_context g_blkvsc_drv;
+
+static struct block_device_operations block_ops = {
+	.owner = THIS_MODULE,
+	.open = blkvsc_open,
+	.release = blkvsc_release,
+	.media_changed = blkvsc_media_changed,
+	.revalidate_disk = blkvsc_revalidate_disk,
+	.getgeo = blkvsc_getgeo,
+	.ioctl  = blkvsc_ioctl,
+};
+
+/**
+ * blkvsc_drv_init -  BlkVsc driver initialization.
+ */
+static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
+{
+	struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv.drv_obj;
+	struct driver_context *drv_ctx = &g_blkvsc_drv.drv_ctx;
+	int ret;
+
+	DPRINT_ENTER(BLKVSC_DRV);
+
+	vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface);
+
+	storvsc_drv_obj->RingBufferSize = blkvsc_ringbuffer_size;
+
+	/* Callback to client driver to complete the initialization */
+	drv_init(&storvsc_drv_obj->Base);
+
+	drv_ctx->driver.name = storvsc_drv_obj->Base.name;
+	memcpy(&drv_ctx->class_id, &storvsc_drv_obj->Base.deviceType,
+	       sizeof(struct hv_guid));
+
+	drv_ctx->probe = blkvsc_probe;
+	drv_ctx->remove = blkvsc_remove;
+	drv_ctx->shutdown = blkvsc_shutdown;
+
+	/* The driver belongs to vmbus */
+	ret = vmbus_child_driver_register(drv_ctx);
+
+	DPRINT_EXIT(BLKVSC_DRV);
+
+	return ret;
+}
+
+static int blkvsc_drv_exit_cb(struct device *dev, void *data)
+{
+	struct device **curr = (struct device **)data;
+	*curr = dev;
+	return 1; /* stop iterating */
+}
+
+static void blkvsc_drv_exit(void)
+{
+	struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv.drv_obj;
+	struct driver_context *drv_ctx = &g_blkvsc_drv.drv_ctx;
+	struct device *current_dev;
+	int ret;
+
+	DPRINT_ENTER(BLKVSC_DRV);
+
+	while (1) {
+		current_dev = NULL;
+
+		/* Get the device */
+		ret = driver_for_each_device(&drv_ctx->driver, NULL,
+					     (void *) &current_dev,
+					     blkvsc_drv_exit_cb);
+
+		if (ret)
+			DPRINT_WARN(BLKVSC_DRV,
+				    "driver_for_each_device returned %d", ret);
+
+
+		if (current_dev == NULL)
+			break;
+
+		/* Initiate removal from the top-down */
+		device_unregister(current_dev);
+	}
+
+	if (storvsc_drv_obj->Base.OnCleanup)
+		storvsc_drv_obj->Base.OnCleanup(&storvsc_drv_obj->Base);
+
+	vmbus_child_driver_unregister(drv_ctx);
+
+	DPRINT_EXIT(BLKVSC_DRV);
+
+	return;
+}
+
+/**
+ * blkvsc_probe - Add a new device for this driver
+ */
+static int blkvsc_probe(struct device *device)
+{
+	struct driver_context *driver_ctx =
+				driver_to_driver_context(device->driver);
+	struct blkvsc_driver_context *blkvsc_drv_ctx =
+				(struct blkvsc_driver_context *)driver_ctx;
+	struct storvsc_driver_object *storvsc_drv_obj =
+				&blkvsc_drv_ctx->drv_obj;
+	struct device_context *device_ctx = device_to_device_context(device);
+	struct hv_device *device_obj = &device_ctx->device_obj;
+
+	struct block_device_context *blkdev = NULL;
+	struct storvsc_device_info device_info;
+	int major = 0;
+	int devnum = 0;
+	int ret = 0;
+	static int ide0_registered;
+	static int ide1_registered;
+
+	DPRINT_ENTER(BLKVSC_DRV);
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_probe - enter");
+
+	if (!storvsc_drv_obj->Base.OnDeviceAdd) {
+		DPRINT_ERR(BLKVSC_DRV, "OnDeviceAdd() not set");
+		ret = -1;
+		goto Cleanup;
+	}
+
+	blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL);
+	if (!blkdev) {
+		ret = -ENOMEM;
+		goto Cleanup;
+	}
+
+	INIT_LIST_HEAD(&blkdev->pending_list);
+
+	/* Initialize what we can here */
+	spin_lock_init(&blkdev->lock);
+
+	ASSERT(sizeof(struct blkvsc_request_group) <=
+		sizeof(struct blkvsc_request));
+
+	blkdev->request_pool = kmem_cache_create(dev_name(&device_ctx->device),
+					sizeof(struct blkvsc_request) +
+					storvsc_drv_obj->RequestExtSize, 0,
+					SLAB_HWCACHE_ALIGN, NULL);
+	if (!blkdev->request_pool) {
+		ret = -ENOMEM;
+		goto Cleanup;
+	}
+
+
+	/* Call to the vsc driver to add the device */
+	ret = storvsc_drv_obj->Base.OnDeviceAdd(device_obj, &device_info);
+	if (ret != 0) {
+		DPRINT_ERR(BLKVSC_DRV, "unable to add blkvsc device");
+		goto Cleanup;
+	}
+
+	blkdev->device_ctx = device_ctx;
+	/* this identified the device 0 or 1 */
+	blkdev->target = device_info.TargetId;
+	/* this identified the ide ctrl 0 or 1 */
+	blkdev->path = device_info.PathId;
+
+	dev_set_drvdata(device, blkdev);
+
+	/* Calculate the major and device num */
+	if (blkdev->path == 0) {
+		major = IDE0_MAJOR;
+		devnum = blkdev->path + blkdev->target;		/* 0 or 1 */
+
+		if (!ide0_registered) {
+			ret = register_blkdev(major, "ide");
+			if (ret != 0) {
+				DPRINT_ERR(BLKVSC_DRV,
+					   "register_blkdev() failed! ret %d",
+					   ret);
+				goto Remove;
+			}
+
+			ide0_registered = 1;
+		}
+	} else if (blkdev->path == 1) {
+		major = IDE1_MAJOR;
+		devnum = blkdev->path + blkdev->target + 1; /* 2 or 3 */
+
+		if (!ide1_registered) {
+			ret = register_blkdev(major, "ide");
+			if (ret != 0) {
+				DPRINT_ERR(BLKVSC_DRV,
+					   "register_blkdev() failed! ret %d",
+					   ret);
+				goto Remove;
+			}
+
+			ide1_registered = 1;
+		}
+	} else {
+		DPRINT_ERR(BLKVSC_DRV, "invalid pathid");
+		ret = -1;
+		goto Cleanup;
+	}
+
+	DPRINT_INFO(BLKVSC_DRV, "blkvsc registered for major %d!!", major);
+
+	blkdev->gd = alloc_disk(BLKVSC_MINORS);
+	if (!blkdev->gd) {
+		DPRINT_ERR(BLKVSC_DRV, "register_blkdev() failed! ret %d", ret);
+		ret = -1;
+		goto Cleanup;
+	}
+
+	blkdev->gd->queue = blk_init_queue(blkvsc_request, &blkdev->lock);
+
+	blk_queue_max_segment_size(blkdev->gd->queue, PAGE_SIZE);
+	blk_queue_max_phys_segments(blkdev->gd->queue,
+				    MAX_MULTIPAGE_BUFFER_COUNT);
+	blk_queue_max_hw_segments(blkdev->gd->queue,
+				  MAX_MULTIPAGE_BUFFER_COUNT);
+	blk_queue_segment_boundary(blkdev->gd->queue, PAGE_SIZE-1);
+	blk_queue_bounce_limit(blkdev->gd->queue, BLK_BOUNCE_ANY);
+	blk_queue_dma_alignment(blkdev->gd->queue, 511);
+
+	blkdev->gd->major = major;
+	if (devnum == 1 || devnum == 3)
+		blkdev->gd->first_minor = BLKVSC_MINORS;
+	else
+		blkdev->gd->first_minor = 0;
+	blkdev->gd->fops = &block_ops;
+	blkdev->gd->private_data = blkdev;
+	sprintf(blkdev->gd->disk_name, "hd%c", 'a' + devnum);
+
+	blkvsc_do_inquiry(blkdev);
+	if (blkdev->device_type == DVD_TYPE) {
+		set_disk_ro(blkdev->gd, 1);
+		blkdev->gd->flags |= GENHD_FL_REMOVABLE;
+		blkvsc_do_read_capacity(blkdev);
+	} else {
+		blkvsc_do_read_capacity16(blkdev);
+	}
+
+	set_capacity(blkdev->gd, blkdev->capacity * (blkdev->sector_size/512));
+	blk_queue_logical_block_size(blkdev->gd->queue, blkdev->sector_size);
+	/* go! */
+	add_disk(blkdev->gd);
+
+	DPRINT_INFO(BLKVSC_DRV, "%s added!! capacity %lu sector_size %d",
+		    blkdev->gd->disk_name, (unsigned long)blkdev->capacity,
+		    blkdev->sector_size);
+
+	return ret;
+
+Remove:
+	storvsc_drv_obj->Base.OnDeviceRemove(device_obj);
+
+Cleanup:
+	if (blkdev) {
+		if (blkdev->request_pool) {
+			kmem_cache_destroy(blkdev->request_pool);
+			blkdev->request_pool = NULL;
+		}
+		kfree(blkdev);
+		blkdev = NULL;
+	}
+
+	DPRINT_EXIT(BLKVSC_DRV);
+
+	return ret;
+}
+
+static void blkvsc_shutdown(struct device *device)
+{
+	struct block_device_context *blkdev = dev_get_drvdata(device);
+	unsigned long flags;
+
+	if (!blkdev)
+		return;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_shutdown - users %d disk %s\n",
+		   blkdev->users, blkdev->gd->disk_name);
+
+	spin_lock_irqsave(&blkdev->lock, flags);
+
+	blkdev->shutting_down = 1;
+
+	blk_stop_queue(blkdev->gd->queue);
+
+	spin_unlock_irqrestore(&blkdev->lock, flags);
+
+	while (blkdev->num_outstanding_reqs) {
+		DPRINT_INFO(STORVSC, "waiting for %d requests to complete...",
+			    blkdev->num_outstanding_reqs);
+		udelay(100);
+	}
+
+	blkvsc_do_flush(blkdev);
+
+	spin_lock_irqsave(&blkdev->lock, flags);
+
+	blkvsc_cancel_pending_reqs(blkdev);
+
+	spin_unlock_irqrestore(&blkdev->lock, flags);
+}
+
+static int blkvsc_do_flush(struct block_device_context *blkdev)
+{
+	struct blkvsc_request *blkvsc_req;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_flush()\n");
+
+	if (blkdev->device_type != HARDDISK_TYPE)
+		return 0;
+
+	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
+	if (!blkvsc_req)
+		return -ENOMEM;
+
+	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
+	init_waitqueue_head(&blkvsc_req->wevent);
+	blkvsc_req->dev = blkdev;
+	blkvsc_req->req = NULL;
+	blkvsc_req->write = 0;
+
+	blkvsc_req->request.DataBuffer.PfnArray[0] = 0;
+	blkvsc_req->request.DataBuffer.Offset = 0;
+	blkvsc_req->request.DataBuffer.Length = 0;
+
+	blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE;
+	blkvsc_req->cmd_len = 10;
+
+	/*
+	 * Set this here since the completion routine may be invoked and
+	 * completed before we return
+	 */
+	blkvsc_req->cond = 0;
+	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
+
+	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
+
+	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+
+	return 0;
+}
+
+/* Do a scsi INQUIRY cmd here to get the device type (ie disk or dvd) */
+static int blkvsc_do_inquiry(struct block_device_context *blkdev)
+{
+	struct blkvsc_request *blkvsc_req;
+	struct page *page_buf;
+	unsigned char *buf;
+	unsigned char device_type;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_inquiry()\n");
+
+	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
+	if (!blkvsc_req)
+		return -ENOMEM;
+
+	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
+	page_buf = alloc_page(GFP_KERNEL);
+	if (!page_buf) {
+		kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+		return -ENOMEM;
+	}
+
+	init_waitqueue_head(&blkvsc_req->wevent);
+	blkvsc_req->dev = blkdev;
+	blkvsc_req->req = NULL;
+	blkvsc_req->write = 0;
+
+	blkvsc_req->request.DataBuffer.PfnArray[0] = page_to_pfn(page_buf);
+	blkvsc_req->request.DataBuffer.Offset = 0;
+	blkvsc_req->request.DataBuffer.Length = 64;
+
+	blkvsc_req->cmnd[0] = INQUIRY;
+	blkvsc_req->cmnd[1] = 0x1;		/* Get product data */
+	blkvsc_req->cmnd[2] = 0x83;		/* mode page 83 */
+	blkvsc_req->cmnd[4] = 64;
+	blkvsc_req->cmd_len = 6;
+
+	/*
+	 * Set this here since the completion routine may be invoked and
+	 * completed before we return
+	 */
+	blkvsc_req->cond = 0;
+
+	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
+
+	DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n",
+		   blkvsc_req, blkvsc_req->cond);
+
+	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
+
+	buf = kmap(page_buf);
+
+	/* print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, 64); */
+	/* be to le */
+	device_type = buf[0] & 0x1F;
+
+	if (device_type == 0x0) {
+		blkdev->device_type = HARDDISK_TYPE;
+	} else if (device_type == 0x5) {
+		blkdev->device_type = DVD_TYPE;
+	} else {
+		/* TODO: this is currently unsupported device type */
+		blkdev->device_type = UNKNOWN_DEV_TYPE;
+	}
+
+	DPRINT_DBG(BLKVSC_DRV, "device type %d \n", device_type);
+
+	blkdev->device_id_len = buf[7];
+	if (blkdev->device_id_len > 64)
+		blkdev->device_id_len = 64;
+
+	memcpy(blkdev->device_id, &buf[8], blkdev->device_id_len);
+	/* printk_hex_dump_bytes("", DUMP_PREFIX_NONE, blkdev->device_id,
+	 * blkdev->device_id_len); */
+
+	kunmap(page_buf);
+
+	__free_page(page_buf);
+
+	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+
+	return 0;
+}
+
+/* Do a scsi READ_CAPACITY cmd here to get the size of the disk */
+static int blkvsc_do_read_capacity(struct block_device_context *blkdev)
+{
+	struct blkvsc_request *blkvsc_req;
+	struct page *page_buf;
+	unsigned char *buf;
+	struct scsi_sense_hdr sense_hdr;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_read_capacity()\n");
+
+	blkdev->sector_size = 0;
+	blkdev->capacity = 0;
+	blkdev->media_not_present = 0; /* assume a disk is present */
+
+	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
+	if (!blkvsc_req)
+		return -ENOMEM;
+
+	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
+	page_buf = alloc_page(GFP_KERNEL);
+	if (!page_buf) {
+		kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+		return -ENOMEM;
+	}
+
+	init_waitqueue_head(&blkvsc_req->wevent);
+	blkvsc_req->dev = blkdev;
+	blkvsc_req->req = NULL;
+	blkvsc_req->write = 0;
+
+	blkvsc_req->request.DataBuffer.PfnArray[0] = page_to_pfn(page_buf);
+	blkvsc_req->request.DataBuffer.Offset = 0;
+	blkvsc_req->request.DataBuffer.Length = 8;
+
+	blkvsc_req->cmnd[0] = READ_CAPACITY;
+	blkvsc_req->cmd_len = 16;
+
+	/*
+	 * Set this here since the completion routine may be invoked
+	 * and completed before we return
+	 */
+	blkvsc_req->cond = 0;
+
+	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
+
+	DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n",
+		   blkvsc_req, blkvsc_req->cond);
+
+	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
+
+	/* check error */
+	if (blkvsc_req->request.Status) {
+		scsi_normalize_sense(blkvsc_req->sense_buffer,
+				     SCSI_SENSE_BUFFERSIZE, &sense_hdr);
+
+		if (sense_hdr.asc == 0x3A) {
+			/* Medium not present */
+			blkdev->media_not_present = 1;
+		}
+		return 0;
+	}
+	buf = kmap(page_buf);
+
+	/* be to le */
+	blkdev->capacity = ((buf[0] << 24) | (buf[1] << 16) |
+			    (buf[2] << 8) | buf[3]) + 1;
+	blkdev->sector_size = (buf[4] << 24) | (buf[5] << 16) |
+			      (buf[6] << 8) | buf[7];
+
+	kunmap(page_buf);
+
+	__free_page(page_buf);
+
+	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+
+	return 0;
+}
+
+static int blkvsc_do_read_capacity16(struct block_device_context *blkdev)
+{
+	struct blkvsc_request *blkvsc_req;
+	struct page *page_buf;
+	unsigned char *buf;
+	struct scsi_sense_hdr sense_hdr;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_read_capacity16()\n");
+
+	blkdev->sector_size = 0;
+	blkdev->capacity = 0;
+	blkdev->media_not_present = 0; /* assume a disk is present */
+
+	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
+	if (!blkvsc_req)
+		return -ENOMEM;
+
+	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
+	page_buf = alloc_page(GFP_KERNEL);
+	if (!page_buf) {
+		kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+		return -ENOMEM;
+	}
+
+	init_waitqueue_head(&blkvsc_req->wevent);
+	blkvsc_req->dev = blkdev;
+	blkvsc_req->req = NULL;
+	blkvsc_req->write = 0;
+
+	blkvsc_req->request.DataBuffer.PfnArray[0] = page_to_pfn(page_buf);
+	blkvsc_req->request.DataBuffer.Offset = 0;
+	blkvsc_req->request.DataBuffer.Length = 12;
+
+	blkvsc_req->cmnd[0] = 0x9E; /* READ_CAPACITY16; */
+	blkvsc_req->cmd_len = 16;
+
+	/*
+	 * Set this here since the completion routine may be invoked
+	 * and completed before we return
+	 */
+	blkvsc_req->cond = 0;
+
+	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
+
+	DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n",
+		   blkvsc_req, blkvsc_req->cond);
+
+	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
+
+	/* check error */
+	if (blkvsc_req->request.Status) {
+		scsi_normalize_sense(blkvsc_req->sense_buffer,
+				     SCSI_SENSE_BUFFERSIZE, &sense_hdr);
+		if (sense_hdr.asc == 0x3A) {
+			/* Medium not present */
+			blkdev->media_not_present = 1;
+		}
+		return 0;
+	}
+	buf = kmap(page_buf);
+
+	/* be to le */
+	blkdev->capacity = be64_to_cpu(*(unsigned long long *) &buf[0]) + 1;
+	blkdev->sector_size = be32_to_cpu(*(unsigned int *)&buf[8]);
+
+#if 0
+	blkdev->capacity = ((buf[0] << 24) | (buf[1] << 16) |
+			    (buf[2] << 8) | buf[3]) + 1;
+	blkdev->sector_size = (buf[4] << 24) | (buf[5] << 16) |
+			      (buf[6] << 8) | buf[7];
+#endif
+
+	kunmap(page_buf);
+
+	__free_page(page_buf);
+
+	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+
+	return 0;
+}
+
+/**
+ * blkvsc_remove() - Callback when our device is removed
+ */
+static int blkvsc_remove(struct device *device)
+{
+	struct driver_context *driver_ctx =
+				driver_to_driver_context(device->driver);
+	struct blkvsc_driver_context *blkvsc_drv_ctx =
+				(struct blkvsc_driver_context *)driver_ctx;
+	struct storvsc_driver_object *storvsc_drv_obj =
+				&blkvsc_drv_ctx->drv_obj;
+	struct device_context *device_ctx = device_to_device_context(device);
+	struct hv_device *device_obj = &device_ctx->device_obj;
+	struct block_device_context *blkdev = dev_get_drvdata(device);
+	unsigned long flags;
+	int ret;
+
+	DPRINT_ENTER(BLKVSC_DRV);
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_remove()\n");
+
+	if (!storvsc_drv_obj->Base.OnDeviceRemove) {
+		DPRINT_EXIT(BLKVSC_DRV);
+		return -1;
+	}
+
+	/*
+	 * Call to the vsc driver to let it know that the device is being
+	 * removed
+	 */
+	ret = storvsc_drv_obj->Base.OnDeviceRemove(device_obj);
+	if (ret != 0) {
+		/* TODO: */
+		DPRINT_ERR(BLKVSC_DRV,
+			   "unable to remove blkvsc device (ret %d)", ret);
+	}
+
+	/* Get to a known state */
+	spin_lock_irqsave(&blkdev->lock, flags);
+
+	blkdev->shutting_down = 1;
+
+	blk_stop_queue(blkdev->gd->queue);
+
+	spin_unlock_irqrestore(&blkdev->lock, flags);
+
+	while (blkdev->num_outstanding_reqs) {
+		DPRINT_INFO(STORVSC, "waiting for %d requests to complete...",
+			    blkdev->num_outstanding_reqs);
+		udelay(100);
+	}
+
+	blkvsc_do_flush(blkdev);
+
+	spin_lock_irqsave(&blkdev->lock, flags);
+
+	blkvsc_cancel_pending_reqs(blkdev);
+
+	spin_unlock_irqrestore(&blkdev->lock, flags);
+
+	blk_cleanup_queue(blkdev->gd->queue);
+
+	del_gendisk(blkdev->gd);
+
+	kmem_cache_destroy(blkdev->request_pool);
+
+	kfree(blkdev);
+
+	DPRINT_EXIT(BLKVSC_DRV);
+
+	return ret;
+}
+
+static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req)
+{
+	ASSERT(blkvsc_req->req);
+	ASSERT(blkvsc_req->sector_count <= (MAX_MULTIPAGE_BUFFER_COUNT*8));
+
+	blkvsc_req->cmd_len = 16;
+
+	if (blkvsc_req->sector_start > 0xffffffff) {
+		if (rq_data_dir(blkvsc_req->req)) {
+			blkvsc_req->write = 1;
+			blkvsc_req->cmnd[0] = WRITE_16;
+		} else {
+			blkvsc_req->write = 0;
+			blkvsc_req->cmnd[0] = READ_16;
+		}
+
+		blkvsc_req->cmnd[1] |= blk_fua_rq(blkvsc_req->req) ? 0x8 : 0;
+
+		*(unsigned long long *)&blkvsc_req->cmnd[2] =
+				cpu_to_be64(blkvsc_req->sector_start);
+		*(unsigned int *)&blkvsc_req->cmnd[10] =
+				cpu_to_be32(blkvsc_req->sector_count);
+	} else if ((blkvsc_req->sector_count > 0xff) ||
+		   (blkvsc_req->sector_start > 0x1fffff)) {
+		if (rq_data_dir(blkvsc_req->req)) {
+			blkvsc_req->write = 1;
+			blkvsc_req->cmnd[0] = WRITE_10;
+		} else {
+			blkvsc_req->write = 0;
+			blkvsc_req->cmnd[0] = READ_10;
+		}
+
+		blkvsc_req->cmnd[1] |= blk_fua_rq(blkvsc_req->req) ? 0x8 : 0;
+
+		*(unsigned int *)&blkvsc_req->cmnd[2] =
+				cpu_to_be32(blkvsc_req->sector_start);
+		*(unsigned short *)&blkvsc_req->cmnd[7] =
+				cpu_to_be16(blkvsc_req->sector_count);
+	} else {
+		if (rq_data_dir(blkvsc_req->req)) {
+			blkvsc_req->write = 1;
+			blkvsc_req->cmnd[0] = WRITE_6;
+		} else {
+			blkvsc_req->write = 0;
+			blkvsc_req->cmnd[0] = READ_6;
+		}
+
+		*(unsigned int *)&blkvsc_req->cmnd[1] =
+				cpu_to_be32(blkvsc_req->sector_start) >> 8;
+		blkvsc_req->cmnd[1] &= 0x1f;
+		blkvsc_req->cmnd[4] = (unsigned char)blkvsc_req->sector_count;
+	}
+}
+
+static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
+			void (*request_completion)(struct hv_storvsc_request *))
+{
+	struct block_device_context *blkdev = blkvsc_req->dev;
+	struct device_context *device_ctx = blkdev->device_ctx;
+	struct driver_context *driver_ctx =
+			driver_to_driver_context(device_ctx->device.driver);
+	struct blkvsc_driver_context *blkvsc_drv_ctx =
+			(struct blkvsc_driver_context *)driver_ctx;
+	struct storvsc_driver_object *storvsc_drv_obj =
+			&blkvsc_drv_ctx->drv_obj;
+	struct hv_storvsc_request *storvsc_req;
+	int ret;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - "
+		   "req %p type %s start_sector %lu count %ld offset %d "
+		   "len %d\n", blkvsc_req,
+		   (blkvsc_req->write) ? "WRITE" : "READ",
+		   (unsigned long) blkvsc_req->sector_start,
+		   blkvsc_req->sector_count,
+		   blkvsc_req->request.DataBuffer.Offset,
+		   blkvsc_req->request.DataBuffer.Length);
+#if 0
+	for (i = 0; i < (blkvsc_req->request.DataBuffer.Length >> 12); i++) {
+		DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - "
+			   "req %p pfn[%d] %llx\n",
+			   blkvsc_req, i,
+			   blkvsc_req->request.DataBuffer.PfnArray[i]);
+	}
+#endif
+
+	storvsc_req = &blkvsc_req->request;
+	storvsc_req->Extension = (void *)((unsigned long)blkvsc_req +
+					  sizeof(struct blkvsc_request));
+
+	storvsc_req->Type = blkvsc_req->write ? WRITE_TYPE : READ_TYPE;
+
+	storvsc_req->OnIOCompletion = request_completion;
+	storvsc_req->Context = blkvsc_req;
+
+	storvsc_req->Host = blkdev->port;
+	storvsc_req->Bus = blkdev->path;
+	storvsc_req->TargetId = blkdev->target;
+	storvsc_req->LunId = 0;	 /* this is not really used at all */
+
+	storvsc_req->CdbLen = blkvsc_req->cmd_len;
+	storvsc_req->Cdb = blkvsc_req->cmnd;
+
+	storvsc_req->SenseBuffer = blkvsc_req->sense_buffer;
+	storvsc_req->SenseBufferSize = SCSI_SENSE_BUFFERSIZE;
+
+	ret = storvsc_drv_obj->OnIORequest(&blkdev->device_ctx->device_obj,
+					   &blkvsc_req->request);
+	if (ret == 0)
+		blkdev->num_outstanding_reqs++;
+
+	return ret;
+}
+
+/*
+ * We break the request into 1 or more blkvsc_requests and submit
+ * them.  If we cant submit them all, we put them on the
+ * pending_list. The blkvsc_request() will work on the pending_list.
+ */
+static int blkvsc_do_request(struct block_device_context *blkdev,
+			     struct request *req)
+{
+	struct bio *bio = NULL;
+	struct bio_vec *bvec = NULL;
+	struct bio_vec *prev_bvec = NULL;
+	struct blkvsc_request *blkvsc_req = NULL;
+	struct blkvsc_request *tmp;
+	int databuf_idx = 0;
+	int seg_idx = 0;
+	sector_t start_sector;
+	unsigned long num_sectors = 0;
+	int ret = 0;
+	int pending = 0;
+	struct blkvsc_request_group *group = NULL;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p sect %lu \n", blkdev, req,
+		  (unsigned long)blk_rq_pos(req));
+
+	/* Create a group to tie req to list of blkvsc_reqs */
+	group = kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC);
+	if (!group)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&group->blkvsc_req_list);
+	group->outstanding = group->status = 0;
+
+	start_sector = blk_rq_pos(req);
+
+	/* foreach bio in the request */
+	if (req->bio) {
+		for (bio = req->bio; bio; bio = bio->bi_next) {
+			/*
+			 * Map this bio into an existing or new storvsc request
+			 */
+			bio_for_each_segment(bvec, bio, seg_idx) {
+				DPRINT_DBG(BLKVSC_DRV, "bio_for_each_segment() "
+					   "- req %p bio %p bvec %p seg_idx %d "
+					   "databuf_idx %d\n", req, bio, bvec,
+					   seg_idx, databuf_idx);
+
+				/* Get a new storvsc request */
+				/* 1st-time */
+				if ((!blkvsc_req) ||
+				    (databuf_idx >= MAX_MULTIPAGE_BUFFER_COUNT)
+				    /* hole at the begin of page */
+				    || (bvec->bv_offset != 0) ||
+				    /* hold at the end of page */
+				    (prev_bvec &&
+				     (prev_bvec->bv_len != PAGE_SIZE))) {
+					/* submit the prev one */
+					if (blkvsc_req) {
+						blkvsc_req->sector_start = start_sector;
+						sector_div(blkvsc_req->sector_start, (blkdev->sector_size >> 9));
+
+						blkvsc_req->sector_count = num_sectors / (blkdev->sector_size >> 9);
+						blkvsc_init_rw(blkvsc_req);
+					}
+
+					/*
+					 * Create new blkvsc_req to represent
+					 * the current bvec
+					 */
+					blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC);
+					if (!blkvsc_req) {
+						/* free up everything */
+						list_for_each_entry_safe(
+							blkvsc_req, tmp,
+							&group->blkvsc_req_list,
+							req_entry) {
+							list_del(&blkvsc_req->req_entry);
+							kmem_cache_free(blkdev->request_pool, blkvsc_req);
+						}
+
+						kmem_cache_free(blkdev->request_pool, group);
+						return -ENOMEM;
+					}
+
+					memset(blkvsc_req, 0,
+					       sizeof(struct blkvsc_request));
+
+					blkvsc_req->dev = blkdev;
+					blkvsc_req->req = req;
+					blkvsc_req->request.DataBuffer.Offset = bvec->bv_offset;
+					blkvsc_req->request.DataBuffer.Length = 0;
+
+					/* Add to the group */
+					blkvsc_req->group = group;
+					blkvsc_req->group->outstanding++;
+					list_add_tail(&blkvsc_req->req_entry,
+						&blkvsc_req->group->blkvsc_req_list);
+
+					start_sector += num_sectors;
+					num_sectors = 0;
+					databuf_idx = 0;
+				}
+
+				/* Add the curr bvec/segment to the curr blkvsc_req */
+				blkvsc_req->request.DataBuffer.PfnArray[databuf_idx] = page_to_pfn(bvec->bv_page);
+				blkvsc_req->request.DataBuffer.Length += bvec->bv_len;
+
+				prev_bvec = bvec;
+
+				databuf_idx++;
+				num_sectors += bvec->bv_len >> 9;
+
+			} /* bio_for_each_segment */
+
+		} /* rq_for_each_bio */
+	}
+
+	/* Handle the last one */
+	if (blkvsc_req) {
+		DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p group %p count %d\n",
+			   blkdev, req, blkvsc_req->group,
+			   blkvsc_req->group->outstanding);
+
+		blkvsc_req->sector_start = start_sector;
+		sector_div(blkvsc_req->sector_start,
+			   (blkdev->sector_size >> 9));
+
+		blkvsc_req->sector_count = num_sectors /
+					   (blkdev->sector_size >> 9);
+
+		blkvsc_init_rw(blkvsc_req);
+	}
+
+	list_for_each_entry(blkvsc_req, &group->blkvsc_req_list, req_entry) {
+		if (pending) {
+			DPRINT_DBG(BLKVSC_DRV, "adding blkvsc_req to "
+				   "pending_list - blkvsc_req %p start_sect %lu"
+				   " sect_count %ld (%lu %ld)\n", blkvsc_req,
+				   (unsigned long)blkvsc_req->sector_start,
+				   blkvsc_req->sector_count,
+				   (unsigned long)start_sector,
+				   (unsigned long)num_sectors);
+
+			list_add_tail(&blkvsc_req->pend_entry,
+				      &blkdev->pending_list);
+		} else {
+			ret = blkvsc_submit_request(blkvsc_req,
+						    blkvsc_request_completion);
+			if (ret == -1) {
+				pending = 1;
+				list_add_tail(&blkvsc_req->pend_entry,
+					      &blkdev->pending_list);
+			}
+
+			DPRINT_DBG(BLKVSC_DRV, "submitted blkvsc_req %p "
+				   "start_sect %lu sect_count %ld (%lu %ld) "
+				   "ret %d\n", blkvsc_req,
+				   (unsigned long)blkvsc_req->sector_start,
+				   blkvsc_req->sector_count,
+				   (unsigned long)start_sector,
+				   num_sectors, ret);
+		}
+	}
+
+	return pending;
+}
+
+static void blkvsc_cmd_completion(struct hv_storvsc_request *request)
+{
+	struct blkvsc_request *blkvsc_req =
+			(struct blkvsc_request *)request->Context;
+	struct block_device_context *blkdev =
+			(struct block_device_context *)blkvsc_req->dev;
+	struct scsi_sense_hdr sense_hdr;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_cmd_completion() - req %p\n",
+		   blkvsc_req);
+
+	blkdev->num_outstanding_reqs--;
+
+	if (blkvsc_req->request.Status)
+		if (scsi_normalize_sense(blkvsc_req->sense_buffer,
+					 SCSI_SENSE_BUFFERSIZE, &sense_hdr))
+			scsi_print_sense_hdr("blkvsc", &sense_hdr);
+
+	blkvsc_req->cond = 1;
+	wake_up_interruptible(&blkvsc_req->wevent);
+}
+
+static void blkvsc_request_completion(struct hv_storvsc_request *request)
+{
+	struct blkvsc_request *blkvsc_req =
+			(struct blkvsc_request *)request->Context;
+	struct block_device_context *blkdev =
+			(struct block_device_context *)blkvsc_req->dev;
+	unsigned long flags;
+	struct blkvsc_request *comp_req, *tmp;
+
+	ASSERT(blkvsc_req->group);
+
+	DPRINT_DBG(BLKVSC_DRV, "blkdev %p blkvsc_req %p group %p type %s "
+		   "sect_start %lu sect_count %ld len %d group outstd %d "
+		   "total outstd %d\n",
+		   blkdev, blkvsc_req, blkvsc_req->group,
+		   (blkvsc_req->write) ? "WRITE" : "READ",
+		   (unsigned long)blkvsc_req->sector_start,
+		   blkvsc_req->sector_count,
+		   blkvsc_req->request.DataBuffer.Length,
+		   blkvsc_req->group->outstanding,
+		   blkdev->num_outstanding_reqs);
+
+	spin_lock_irqsave(&blkdev->lock, flags);
+
+	blkdev->num_outstanding_reqs--;
+	blkvsc_req->group->outstanding--;
+
+	/*
+	 * Only start processing when all the blkvsc_reqs are
+	 * completed. This guarantees no out-of-order blkvsc_req
+	 * completion when calling end_that_request_first()
+	 */
+	if (blkvsc_req->group->outstanding == 0) {
+		list_for_each_entry_safe(comp_req, tmp,
+					 &blkvsc_req->group->blkvsc_req_list,
+					 req_entry) {
+			DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p "
+				   "sect_start %lu sect_count %ld \n",
+				   comp_req,
+				   (unsigned long)comp_req->sector_start,
+				   comp_req->sector_count);
+
+			list_del(&comp_req->req_entry);
+
+			if (!__blk_end_request(comp_req->req,
+				(!comp_req->request.Status ? 0 : -EIO),
+				comp_req->sector_count * blkdev->sector_size)) {
+				/*
+				 * All the sectors have been xferred ie the
+				 * request is done
+				 */
+				DPRINT_DBG(BLKVSC_DRV, "req %p COMPLETED\n",
+					   comp_req->req);
+				kmem_cache_free(blkdev->request_pool,
+						comp_req->group);
+			}
+
+			kmem_cache_free(blkdev->request_pool, comp_req);
+		}
+
+		if (!blkdev->shutting_down) {
+			blkvsc_do_pending_reqs(blkdev);
+			blk_start_queue(blkdev->gd->queue);
+			blkvsc_request(blkdev->gd->queue);
+		}
+	}
+
+	spin_unlock_irqrestore(&blkdev->lock, flags);
+}
+
+static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev)
+{
+	struct blkvsc_request *pend_req, *tmp;
+	struct blkvsc_request *comp_req, *tmp2;
+
+	int ret = 0;
+
+	DPRINT_DBG(BLKVSC_DRV, "blkvsc_cancel_pending_reqs()");
+
+	/* Flush the pending list first */
+	list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
+				 pend_entry) {
+		/*
+		 * The pend_req could be part of a partially completed
+		 * request. If so, complete those req first until we
+		 * hit the pend_req
+		 */
+		list_for_each_entry_safe(comp_req, tmp2,
+					 &pend_req->group->blkvsc_req_list,
+					 req_entry) {
+			DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p "
+				   "sect_start %lu sect_count %ld \n",
+				   comp_req,
+				   (unsigned long) comp_req->sector_start,
+				   comp_req->sector_count);
+
+			if (comp_req == pend_req)
+				break;
+
+			list_del(&comp_req->req_entry);
+
+			if (comp_req->req) {
+				ret = __blk_end_request(comp_req->req,
+					(!comp_req->request.Status ? 0 : -EIO),
+					comp_req->sector_count *
+					blkdev->sector_size);
+				ASSERT(ret != 0);
+			}
+
+			kmem_cache_free(blkdev->request_pool, comp_req);
+		}
+
+		DPRINT_DBG(BLKVSC_DRV, "cancelling pending request - %p\n",
+			   pend_req);
+
+		list_del(&pend_req->pend_entry);
+
+		list_del(&pend_req->req_entry);
+
+		if (comp_req->req) {
+			if (!__blk_end_request(pend_req->req, -EIO,
+					       pend_req->sector_count *
+					       blkdev->sector_size)) {
+				/*
+				 * All the sectors have been xferred ie the
+				 * request is done
+				 */
+				DPRINT_DBG(BLKVSC_DRV,
+					   "blkvsc_cancel_pending_reqs() - "
+					   "req %p COMPLETED\n", pend_req->req);
+				kmem_cache_free(blkdev->request_pool,
+						pend_req->group);
+			}
+		}
+
+		kmem_cache_free(blkdev->request_pool, pend_req);
+	}
+
+	return ret;
+}
+
+static int blkvsc_do_pending_reqs(struct block_device_context *blkdev)
+{
+	struct blkvsc_request *pend_req, *tmp;
+	int ret = 0;
+
+	/* Flush the pending list first */
+	list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
+				 pend_entry) {
+		DPRINT_DBG(BLKVSC_DRV, "working off pending_list - %p\n",
+			   pend_req);
+
+		ret = blkvsc_submit_request(pend_req,
+					    blkvsc_request_completion);
+		if (ret != 0)
+			break;
+		else
+			list_del(&pend_req->pend_entry);
+	}
+
+	return ret;
+}
+
+static void blkvsc_request(struct request_queue *queue)
+{
+	struct block_device_context *blkdev = NULL;
+	struct request *req;
+	int ret = 0;
+
+	DPRINT_DBG(BLKVSC_DRV, "- enter \n");
+	while ((req = blk_peek_request(queue)) != NULL) {
+		DPRINT_DBG(BLKVSC_DRV, "- req %p\n", req);
+
+		blkdev = req->rq_disk->private_data;
+		if (blkdev->shutting_down || !blk_fs_request(req) ||
+		    blkdev->media_not_present) {
+			__blk_end_request_cur(req, 0);
+			continue;
+		}
+
+		ret = blkvsc_do_pending_reqs(blkdev);
+
+		if (ret != 0) {
+			DPRINT_DBG(BLKVSC_DRV,
+				   "- stop queue - pending_list not empty\n");
+			blk_stop_queue(queue);
+			break;
+		}
+
+		blk_start_request(req);
+
+		ret = blkvsc_do_request(blkdev, req);
+		if (ret > 0) {
+			DPRINT_DBG(BLKVSC_DRV, "- stop queue - no room\n");
+			blk_stop_queue(queue);
+			break;
+		} else if (ret < 0) {
+			DPRINT_DBG(BLKVSC_DRV, "- stop queue - no mem\n");
+			blk_requeue_request(queue, req);
+			blk_stop_queue(queue);
+			break;
+		}
+	}
+}
+
+static int blkvsc_open(struct block_device *bdev, fmode_t mode)
+{
+	struct block_device_context *blkdev = bdev->bd_disk->private_data;
+
+	DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users,
+		   blkdev->gd->disk_name);
+
+	spin_lock(&blkdev->lock);
+
+	if (!blkdev->users && blkdev->device_type == DVD_TYPE) {
+		spin_unlock(&blkdev->lock);
+		check_disk_change(bdev);
+		spin_lock(&blkdev->lock);
+	}
+
+	blkdev->users++;
+
+	spin_unlock(&blkdev->lock);
+	return 0;
+}
+
+static int blkvsc_release(struct gendisk *disk, fmode_t mode)
+{
+	struct block_device_context *blkdev = disk->private_data;
+
+	DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users,
+		   blkdev->gd->disk_name);
+
+	spin_lock(&blkdev->lock);
+	if (blkdev->users == 1) {
+		spin_unlock(&blkdev->lock);
+		blkvsc_do_flush(blkdev);
+		spin_lock(&blkdev->lock);
+	}
+
+	blkdev->users--;
+
+	spin_unlock(&blkdev->lock);
+	return 0;
+}
+
+static int blkvsc_media_changed(struct gendisk *gd)
+{
+	DPRINT_DBG(BLKVSC_DRV, "- enter\n");
+	return 1;
+}
+
+static int blkvsc_revalidate_disk(struct gendisk *gd)
+{
+	struct block_device_context *blkdev = gd->private_data;
+
+	DPRINT_DBG(BLKVSC_DRV, "- enter\n");
+
+	if (blkdev->device_type == DVD_TYPE) {
+		blkvsc_do_read_capacity(blkdev);
+		set_capacity(blkdev->gd, blkdev->capacity *
+			    (blkdev->sector_size/512));
+		blk_queue_logical_block_size(gd->queue, blkdev->sector_size);
+	}
+	return 0;
+}
+
+static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg)
+{
+	sector_t total_sectors = get_capacity(bd->bd_disk);
+	sector_t cylinder_times_heads = 0;
+	sector_t temp = 0;
+
+	int sectors_per_track = 0;
+	int heads = 0;
+	int cylinders = 0;
+	int rem = 0;
+
+	if (total_sectors > (65535 * 16 * 255))
+		total_sectors = (65535 * 16 * 255);
+
+	if (total_sectors >= (65535 * 16 * 63)) {
+		sectors_per_track = 255;
+		heads = 16;
+
+		cylinder_times_heads = total_sectors;
+		/* sector_div stores the quotient in cylinder_times_heads */
+		rem = sector_div(cylinder_times_heads, sectors_per_track);
+	} else {
+		sectors_per_track = 17;
+
+		cylinder_times_heads = total_sectors;
+		/* sector_div stores the quotient in cylinder_times_heads */
+		rem = sector_div(cylinder_times_heads, sectors_per_track);
+
+		temp = cylinder_times_heads + 1023;
+		/* sector_div stores the quotient in temp */
+		rem = sector_div(temp, 1024);
+
+		heads = temp;
+
+		if (heads < 4)
+			heads = 4;
+
+
+		if (cylinder_times_heads >= (heads * 1024) || (heads > 16)) {
+			sectors_per_track = 31;
+			heads = 16;
+
+			cylinder_times_heads = total_sectors;
+			/*
+			 * sector_div stores the quotient in
+			 * cylinder_times_heads
+			 */
+			rem = sector_div(cylinder_times_heads,
+					 sectors_per_track);
+		}
+
+		if (cylinder_times_heads >= (heads * 1024)) {
+			sectors_per_track = 63;
+			heads = 16;
+
+			cylinder_times_heads = total_sectors;
+			/*
+			 * sector_div stores the quotient in
+			 * cylinder_times_heads
+			 */
+			rem = sector_div(cylinder_times_heads,
+					 sectors_per_track);
+		}
+	}
+
+	temp = cylinder_times_heads;
+	/* sector_div stores the quotient in temp */
+	rem = sector_div(temp, heads);
+	cylinders = temp;
+
+	hg->heads = heads;
+	hg->sectors = sectors_per_track;
+	hg->cylinders = cylinders;
+
+	DPRINT_INFO(BLKVSC_DRV, "CHS (%d, %d, %d)", cylinders, heads,
+		    sectors_per_track);
+
+    return 0;
+}
+
+static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
+			unsigned cmd, unsigned long argument)
+{
+/*	struct block_device_context *blkdev = bd->bd_disk->private_data; */
+	int ret;
+
+	switch (cmd) {
+	/*
+	 * TODO: I think there is certain format for HDIO_GET_IDENTITY rather
+	 * than just a GUID. Commented it out for now.
+	 */
+#if 0
+	case HDIO_GET_IDENTITY:
+		DPRINT_INFO(BLKVSC_DRV, "HDIO_GET_IDENTITY\n");
+		if (copy_to_user((void __user *)arg, blkdev->device_id,
+				 blkdev->device_id_len))
+			ret = -EFAULT;
+		break;
+#endif
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int __init blkvsc_init(void)
+{
+	int ret;
+
+	ASSERT(sizeof(sector_t) == 8); /* Make sure CONFIG_LBD is set */
+
+	DPRINT_ENTER(BLKVSC_DRV);
+
+	DPRINT_INFO(BLKVSC_DRV, "Blkvsc initializing....");
+
+	ret = blkvsc_drv_init(BlkVscInitialize);
+
+	DPRINT_EXIT(BLKVSC_DRV);
+
+	return ret;
+}
+
+static void __exit blkvsc_exit(void)
+{
+	DPRINT_ENTER(BLKVSC_DRV);
+	blkvsc_drv_exit();
+	DPRINT_ENTER(BLKVSC_DRV);
+}
+
+MODULE_LICENSE("GPL");
+module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
+module_init(blkvsc_init);
+module_exit(blkvsc_exit);
diff --git a/drivers/staging/hv/hv_api.h b/drivers/staging/hv/hv_api.h
new file mode 100644
index 0000000..251e2d1
--- /dev/null
+++ b/drivers/staging/hv/hv_api.h
@@ -0,0 +1,905 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+#ifndef __HV_API_H
+#define __HV_API_H
+
+
+/* Status codes for hypervisor operations. */
+
+/*
+ * HV_STATUS_SUCCESS
+ * The specified hypercall succeeded
+ */
+#define HV_STATUS_SUCCESS				((u16)0x0000)
+
+/*
+ * HV_STATUS_INVALID_HYPERCALL_CODE
+ * The hypervisor does not support the operation because the specified
+ * hypercall code is not supported.
+ */
+#define HV_STATUS_INVALID_HYPERCALL_CODE		((u16)0x0002)
+
+/*
+ * HV_STATUS_INVALID_HYPERCALL_INPUT
+ * The hypervisor does not support the operation because the encoding for the
+ * hypercall input register is not supported.
+ */
+#define HV_STATUS_INVALID_HYPERCALL_INPUT		((u16)0x0003)
+
+/*
+ * HV_STATUS_INVALID_ALIGNMENT
+ * The hypervisor could not perform the operation beacuse a parameter has an
+ * invalid alignment.
+ */
+#define HV_STATUS_INVALID_ALIGNMENT			((u16)0x0004)
+
+/*
+ * HV_STATUS_INVALID_PARAMETER
+ * The hypervisor could not perform the operation beacuse an invalid parameter
+ * was specified.
+ */
+#define HV_STATUS_INVALID_PARAMETER			((u16)0x0005)
+
+/*
+ * HV_STATUS_ACCESS_DENIED
+ * Access to the specified object was denied.
+ */
+#define HV_STATUS_ACCESS_DENIED				((u16)0x0006)
+
+/*
+ * HV_STATUS_INVALID_PARTITION_STATE
+ * The hypervisor could not perform the operation because the partition is
+ * entering or in an invalid state.
+ */
+#define HV_STATUS_INVALID_PARTITION_STATE		((u16)0x0007)
+
+/*
+ * HV_STATUS_OPERATION_DENIED
+ * The operation is not allowed in the current state.
+ */
+#define HV_STATUS_OPERATION_DENIED			((u16)0x0008)
+
+/*
+ * HV_STATUS_UNKNOWN_PROPERTY
+ * The hypervisor does not recognize the specified partition property.
+ */
+#define HV_STATUS_UNKNOWN_PROPERTY			((u16)0x0009)
+
+/*
+ * HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE
+ * The specified value of a partition property is out of range or violates an
+ * invariant.
+ */
+#define HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE		((u16)0x000A)
+
+/*
+ * HV_STATUS_INSUFFICIENT_MEMORY
+ * There is not enough memory in the hypervisor pool to complete the operation.
+ */
+#define HV_STATUS_INSUFFICIENT_MEMORY			((u16)0x000B)
+
+/*
+ * HV_STATUS_PARTITION_TOO_DEEP
+ * The maximum partition depth has been exceeded for the partition hierarchy.
+ */
+#define HV_STATUS_PARTITION_TOO_DEEP			((u16)0x000C)
+
+/*
+ * HV_STATUS_INVALID_PARTITION_ID
+ * A partition with the specified partition Id does not exist.
+ */
+#define HV_STATUS_INVALID_PARTITION_ID			((u16)0x000D)
+
+/*
+ * HV_STATUS_INVALID_VP_INDEX
+ * The hypervisor could not perform the operation because the specified VP
+ * index is invalid.
+ */
+#define HV_STATUS_INVALID_VP_INDEX			((u16)0x000E)
+
+/*
+ * HV_STATUS_NOT_FOUND
+ * The iteration is complete; no addition items in the iteration could be
+ * found.
+ */
+#define HV_STATUS_NOT_FOUND				((u16)0x0010)
+
+/*
+ * HV_STATUS_INVALID_PORT_ID
+ * The hypervisor could not perform the operation because the specified port
+ * identifier is invalid.
+ */
+#define HV_STATUS_INVALID_PORT_ID			((u16)0x0011)
+
+/*
+ * HV_STATUS_INVALID_CONNECTION_ID
+ * The hypervisor could not perform the operation because the specified
+ * connection identifier is invalid.
+ */
+#define HV_STATUS_INVALID_CONNECTION_ID			((u16)0x0012)
+
+/*
+ * HV_STATUS_INSUFFICIENT_BUFFERS
+ * You did not supply enough message buffers to send a message.
+ */
+#define HV_STATUS_INSUFFICIENT_BUFFERS			((u16)0x0013)
+
+/*
+ * HV_STATUS_NOT_ACKNOWLEDGED
+ * The previous virtual interrupt has not been acknowledged.
+ */
+#define HV_STATUS_NOT_ACKNOWLEDGED			((u16)0x0014)
+
+/*
+ * HV_STATUS_INVALID_VP_STATE
+ * A virtual processor is not in the correct state for the performance of the
+ * indicated operation.
+ */
+#define HV_STATUS_INVALID_VP_STATE			((u16)0x0015)
+
+/*
+ * HV_STATUS_ACKNOWLEDGED
+ * The previous virtual interrupt has already been acknowledged.
+ */
+#define HV_STATUS_ACKNOWLEDGED				((u16)0x0016)
+
+/*
+ * HV_STATUS_INVALID_SAVE_RESTORE_STATE
+ * The indicated partition is not in a valid state for saving or restoring.
+ */
+#define HV_STATUS_INVALID_SAVE_RESTORE_STATE		((u16)0x0017)
+
+/*
+ * HV_STATUS_INVALID_SYNIC_STATE
+ * The hypervisor could not complete the operation because a required feature
+ * of the synthetic interrupt controller (SynIC) was disabled.
+ */
+#define HV_STATUS_INVALID_SYNIC_STATE			((u16)0x0018)
+
+/*
+ * HV_STATUS_OBJECT_IN_USE
+ * The hypervisor could not perform the operation because the object or value
+ * was either already in use or being used for a purpose that would not permit
+ * completing the operation.
+ */
+#define HV_STATUS_OBJECT_IN_USE				((u16)0x0019)
+
+/*
+ * HV_STATUS_INVALID_PROXIMITY_DOMAIN_INFO
+ * The proximity domain information is invalid.
+ */
+#define HV_STATUS_INVALID_PROXIMITY_DOMAIN_INFO		((u16)0x001A)
+
+/*
+ * HV_STATUS_NO_DATA
+ * An attempt to retrieve debugging data failed because none was available.
+ */
+#define HV_STATUS_NO_DATA				((u16)0x001B)
+
+/*
+ * HV_STATUS_INACTIVE
+ * The physical connection being used for debuggging has not recorded any
+ * receive activity since the last operation.
+ */
+#define HV_STATUS_INACTIVE				((u16)0x001C)
+
+/*
+ * HV_STATUS_NO_RESOURCES
+ * There are not enough resources to complete the operation.
+ */
+#define HV_STATUS_NO_RESOURCES				((u16)0x001D)
+
+/*
+ * HV_STATUS_FEATURE_UNAVAILABLE
+ * A hypervisor feature is not available to the user.
+ */
+#define HV_STATUS_FEATURE_UNAVAILABLE			((u16)0x001E)
+
+/*
+ * HV_STATUS_UNSUCCESSFUL
+ * {Operation Failed} The requested operation was unsuccessful.
+ */
+#define HV_STATUS_UNSUCCESSFUL				((u16)0x1001)
+
+/*
+ * HV_STATUS_INSUFFICIENT_BUFFER
+ * The specified buffer was too small to contain all of the requested data.
+ */
+#define HV_STATUS_INSUFFICIENT_BUFFER			((u16)0x1002)
+
+/*
+ * HV_STATUS_GPA_NOT_PRESENT
+ * The guest physical address is not currently associated with a system
+ * physical address.
+ */
+#define HV_STATUS_GPA_NOT_PRESENT			((u16)0x1003)
+
+/*
+ * HV_STATUS_GUEST_PAGE_FAULT
+ * The operation would have resulted in a page fault in the guest.
+ */
+#define HV_STATUS_GUEST_PAGE_FAULT			((u16)0x1004)
+
+/*
+ * HV_STATUS_RUNDOWN_DISABLED
+ * The operation cannot proceed as the rundown object was marked disabled.
+ */
+#define HV_STATUS_RUNDOWN_DISABLED			((u16)0x1005)
+
+/*
+ * HV_STATUS_KEY_ALREADY_EXISTS
+ * The entry cannot be added as another entry with the same key already exists.
+ */
+#define HV_STATUS_KEY_ALREADY_EXISTS			((u16)0x1006)
+
+/*
+ * HV_STATUS_GPA_INTERCEPT
+ * The operation resulted an intercept on a region of guest physical memory.
+ */
+#define HV_STATUS_GPA_INTERCEPT				((u16)0x1007)
+
+/*
+ * HV_STATUS_GUEST_GENERAL_PROTECTION_FAULT
+ * The operation would have resulted in a general protection fault in the
+ * guest.
+ */
+#define HV_STATUS_GUEST_GENERAL_PROTECTION_FAULT	((u16)0x1008)
+
+/*
+ * HV_STATUS_GUEST_STACK_FAULT
+ * The operation would have resulted in a stack fault in the guest.
+ */
+#define HV_STATUS_GUEST_STACK_FAULT			((u16)0x1009)
+
+/*
+ * HV_STATUS_GUEST_INVALID_OPCODE_FAULT
+ * The operation would have resulted in an invalid opcode fault in the guest.
+ */
+#define HV_STATUS_GUEST_INVALID_OPCODE_FAULT		((u16)0x100A)
+
+/*
+ * HV_STATUS_FINALIZE_INCOMPLETE
+ * The partition is not completely finalized.
+ */
+#define HV_STATUS_FINALIZE_INCOMPLETE			((u16)0x100B)
+
+/*
+ * HV_STATUS_GUEST_MACHINE_CHECK_ABORT
+ * The operation would have resulted in an machine check abort in the guest.
+ */
+#define HV_STATUS_GUEST_MACHINE_CHECK_ABORT		((u16)0x100C)
+
+/*
+ * HV_STATUS_ILLEGAL_OVERLAY_ACCESS
+ * An illegal access was attempted to an overlay page.
+ */
+#define HV_STATUS_ILLEGAL_OVERLAY_ACCESS		((u16)0x100D)
+
+/*
+ * HV_STATUS_INSUFFICIENT_SYSTEM_VA
+ * There is not enough system VA space available to satisfy the request,
+ */
+#define HV_STATUS_INSUFFICIENT_SYSTEM_VA		((u16)0x100E)
+
+/*
+ * HV_STATUS_VIRTUAL_ADDRESS_NOT_MAPPED
+ * The passed virtual address was not mapped in the hypervisor address space.
+ */
+#define HV_STATUS_VIRTUAL_ADDRESS_NOT_MAPPED		((u16)0x100F)
+
+/*
+ * HV_STATUS_NOT_IMPLEMENTED
+ * The requested operation is not implemented in this version of the
+ * hypervisor.
+ */
+#define HV_STATUS_NOT_IMPLEMENTED			((u16)0x1010)
+
+/*
+ * HV_STATUS_VMX_INSTRUCTION_FAILED
+ * The requested VMX instruction failed to complete succesfully.
+ */
+#define HV_STATUS_VMX_INSTRUCTION_FAILED		((u16)0x1011)
+
+/*
+ * HV_STATUS_VMX_INSTRUCTION_FAILED_WITH_STATUS
+ * The requested VMX instruction failed to complete succesfully indicating
+ * status.
+ */
+#define HV_STATUS_VMX_INSTRUCTION_FAILED_WITH_STATUS	((u16)0x1012)
+
+/*
+ * HV_STATUS_MSR_ACCESS_FAILED
+ * The requested access to the model specific register failed.
+ */
+#define HV_STATUS_MSR_ACCESS_FAILED		((u16)0x1013)
+
+/*
+ * HV_STATUS_CR_ACCESS_FAILED
+ * The requested access to the control register failed.
+ */
+#define HV_STATUS_CR_ACCESS_FAILED		((u16)0x1014)
+
+/*
+ * HV_STATUS_TIMEOUT
+ * The specified timeout expired before the operation completed.
+ */
+#define HV_STATUS_TIMEOUT			((u16)0x1016)
+
+/*
+ * HV_STATUS_MSR_INTERCEPT
+ * The requested access to the model specific register generated an intercept.
+ */
+#define HV_STATUS_MSR_INTERCEPT			((u16)0x1017)
+
+/*
+ * HV_STATUS_CPUID_INTERCEPT
+ * The CPUID instruction generated an intercept.
+ */
+#define HV_STATUS_CPUID_INTERCEPT		((u16)0x1018)
+
+/*
+ * HV_STATUS_REPEAT_INSTRUCTION
+ * The current instruction should be repeated and the instruction pointer not
+ * advanced.
+ */
+#define HV_STATUS_REPEAT_INSTRUCTION		((u16)0x1019)
+
+/*
+ * HV_STATUS_PAGE_PROTECTION_VIOLATION
+ * The current instruction should be repeated and the instruction pointer not
+ * advanced.
+ */
+#define HV_STATUS_PAGE_PROTECTION_VIOLATION	((u16)0x101A)
+
+/*
+ * HV_STATUS_PAGE_TABLE_INVALID
+ * The current instruction should be repeated and the instruction pointer not
+ * advanced.
+ */
+#define HV_STATUS_PAGE_TABLE_INVALID		((u16)0x101B)
+
+/*
+ * HV_STATUS_PAGE_NOT_PRESENT
+ * The current instruction should be repeated and the instruction pointer not
+ * advanced.
+ */
+#define HV_STATUS_PAGE_NOT_PRESENT		((u16)0x101C)
+
+/*
+ * HV_STATUS_IO_INTERCEPT
+ * The requested access to the I/O port generated an intercept.
+ */
+#define HV_STATUS_IO_INTERCEPT				((u16)0x101D)
+
+/*
+ * HV_STATUS_NOTHING_TO_DO
+ * There is nothing to do.
+ */
+#define HV_STATUS_NOTHING_TO_DO				((u16)0x101E)
+
+/*
+ * HV_STATUS_THREAD_TERMINATING
+ * The requested thread is terminating.
+ */
+#define HV_STATUS_THREAD_TERMINATING			((u16)0x101F)
+
+/*
+ * HV_STATUS_SECTION_ALREADY_CONSTRUCTED
+ * The specified section was already constructed.
+ */
+#define HV_STATUS_SECTION_ALREADY_CONSTRUCTED		((u16)0x1020)
+
+/* HV_STATUS_SECTION_NOT_ALREADY_CONSTRUCTED
+ * The specified section was not already constructed.
+ */
+#define HV_STATUS_SECTION_NOT_ALREADY_CONSTRUCTED	((u16)0x1021)
+
+/*
+ * HV_STATUS_PAGE_ALREADY_COMMITTED
+ * The specified virtual address was already backed by physical memory.
+ */
+#define HV_STATUS_PAGE_ALREADY_COMMITTED		((u16)0x1022)
+
+/*
+ * HV_STATUS_PAGE_NOT_ALREADY_COMMITTED
+ * The specified virtual address was not already backed by physical memory.
+ */
+#define HV_STATUS_PAGE_NOT_ALREADY_COMMITTED		((u16)0x1023)
+
+/*
+ * HV_STATUS_COMMITTED_PAGES_REMAIN
+ * Committed pages remain in the section.
+ */
+#define HV_STATUS_COMMITTED_PAGES_REMAIN		((u16)0x1024)
+
+/*
+ * HV_STATUS_NO_REMAINING_COMMITTED_PAGES
+ * No additional committed pages beyond the specified page exist in the
+ * section.
+ */
+#define HV_STATUS_NO_REMAINING_COMMITTED_PAGES		((u16)0x1025)
+
+/*
+ * HV_STATUS_INSUFFICIENT_COMPARTMENT_VA
+ * The VA space of the compartment is exhausted.
+ */
+#define HV_STATUS_INSUFFICIENT_COMPARTMENT_VA		((u16)0x1026)
+
+/*
+ * HV_STATUS_DEREF_SPA_LIST_FULL
+ * The SPA dereference list is full, and there are additional entries to be
+ * added to it.
+ */
+#define HV_STATUS_DEREF_SPA_LIST_FULL			((u16)0x1027)
+
+/*
+ * HV_STATUS_GPA_OUT_OF_RANGE
+ * The supplied GPA is out of range.
+ */
+#define HV_STATUS_GPA_OUT_OF_RANGE			((u16)0x1027)
+
+/*
+ * HV_STATUS_NONVOLATILE_XMM_STALE
+ * The XMM register that was being accessed is stale.
+ */
+#define HV_STATUS_NONVOLATILE_XMM_STALE			((u16)0x1028)
+
+/* HV_STATUS_UNSUPPORTED_PROCESSOR
+ * The hypervisor does not support the processors in this system.
+ */
+#define HV_STATUS_UNSUPPORTED_PROCESSOR			((u16)0x1029)
+
+/*
+ * HV_STATUS_INSUFFICIENT_CROM_SPACE
+ * Insufficient space existed for copying over the CROM contents.
+ */
+#define HV_STATUS_INSUFFICIENT_CROM_SPACE		((u16)0x2000)
+
+/*
+ * HV_STATUS_BAD_CROM_FORMAT
+ * The contents of the CROM failed validation attempts.
+ */
+#define HV_STATUS_BAD_CROM_FORMAT			((u16)0x2001)
+
+/*
+ * HV_STATUS_UNSUPPORTED_CROM_FORMAT
+ * The contents of the CROM contain contents the parser doesn't support.
+ */
+#define HV_STATUS_UNSUPPORTED_CROM_FORMAT		((u16)0x2002)
+
+/*
+ * HV_STATUS_UNSUPPORTED_CONTROLLER
+ * The register format of the OHCI controller specified for debugging is not
+ * supported.
+ */
+#define HV_STATUS_UNSUPPORTED_CONTROLLER		((u16)0x2003)
+
+/*
+ * HV_STATUS_CROM_TOO_LARGE
+ * The CROM contents were to large to copy over.
+ */
+#define HV_STATUS_CROM_TOO_LARGE			((u16)0x2004)
+
+/*
+ * HV_STATUS_CONTROLLER_IN_USE
+ * The OHCI controller specified for debugging cannot be used as it is already
+ * in use.
+ */
+#define HV_STATUS_CONTROLLER_IN_USE			((u16)0x2005)
+
+
+/*
+ * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+ * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
+ */
+enum hv_cpuid_function {
+	HvCpuIdFunctionVersionAndFeatures		= 0x00000001,
+	HvCpuIdFunctionHvVendorAndMaxFunction		= 0x40000000,
+	HvCpuIdFunctionHvInterface			= 0x40000001,
+
+	/*
+	 * The remaining functions depend on the value of
+	 * HvCpuIdFunctionInterface
+	 */
+	HvCpuIdFunctionMsHvVersion			= 0x40000002,
+	HvCpuIdFunctionMsHvFeatures			= 0x40000003,
+	HvCpuIdFunctionMsHvEnlightenmentInformation	= 0x40000004,
+	HvCpuIdFunctionMsHvImplementationLimits		= 0x40000005,
+};
+
+/* Define the virtual APIC registers */
+#define HV_X64_MSR_EOI			(0x40000070)
+#define HV_X64_MSR_ICR			(0x40000071)
+#define HV_X64_MSR_TPR			(0x40000072)
+#define HV_X64_MSR_APIC_ASSIST_PAGE	(0x40000073)
+
+/* Define version of the synthetic interrupt controller. */
+#define HV_SYNIC_VERSION		(1)
+
+/* Define synthetic interrupt controller model specific registers. */
+#define HV_X64_MSR_SCONTROL		(0x40000080)
+#define HV_X64_MSR_SVERSION		(0x40000081)
+#define HV_X64_MSR_SIEFP		(0x40000082)
+#define HV_X64_MSR_SIMP			(0x40000083)
+#define HV_X64_MSR_EOM			(0x40000084)
+#define HV_X64_MSR_SINT0		(0x40000090)
+#define HV_X64_MSR_SINT1		(0x40000091)
+#define HV_X64_MSR_SINT2		(0x40000092)
+#define HV_X64_MSR_SINT3		(0x40000093)
+#define HV_X64_MSR_SINT4		(0x40000094)
+#define HV_X64_MSR_SINT5		(0x40000095)
+#define HV_X64_MSR_SINT6		(0x40000096)
+#define HV_X64_MSR_SINT7		(0x40000097)
+#define HV_X64_MSR_SINT8		(0x40000098)
+#define HV_X64_MSR_SINT9		(0x40000099)
+#define HV_X64_MSR_SINT10		(0x4000009A)
+#define HV_X64_MSR_SINT11		(0x4000009B)
+#define HV_X64_MSR_SINT12		(0x4000009C)
+#define HV_X64_MSR_SINT13		(0x4000009D)
+#define HV_X64_MSR_SINT14		(0x4000009E)
+#define HV_X64_MSR_SINT15		(0x4000009F)
+
+/* Define the expected SynIC version. */
+#define HV_SYNIC_VERSION_1		(0x1)
+
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE			(256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
+#define HV_ANY_VP			(0xFFFFFFFF)
+
+/* Define synthetic interrupt controller flag constants. */
+#define HV_EVENT_FLAGS_COUNT		(256 * 8)
+#define HV_EVENT_FLAGS_BYTE_COUNT	(256)
+#define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
+
+/* Define hypervisor message types. */
+enum hv_message_type {
+	HvMessageTypeNone			= 0x00000000,
+
+	/* Memory access messages. */
+	HvMessageTypeUnmappedGpa		= 0x80000000,
+	HvMessageTypeGpaIntercept		= 0x80000001,
+
+	/* Timer notification messages. */
+	HvMessageTimerExpired			= 0x80000010,
+
+	/* Error messages. */
+	HvMessageTypeInvalidVpRegisterValue	= 0x80000020,
+	HvMessageTypeUnrecoverableException	= 0x80000021,
+	HvMessageTypeUnsupportedFeature		= 0x80000022,
+
+	/* Trace buffer complete messages. */
+	HvMessageTypeEventLogBufferComplete	= 0x80000040,
+
+	/* Platform-specific processor intercept messages. */
+	HvMessageTypeX64IoPortIntercept		= 0x80010000,
+	HvMessageTypeX64MsrIntercept		= 0x80010001,
+	HvMessageTypeX64CpuidIntercept		= 0x80010002,
+	HvMessageTypeX64ExceptionIntercept	= 0x80010003,
+	HvMessageTypeX64ApicEoi			= 0x80010004,
+	HvMessageTypeX64LegacyFpError		= 0x80010005
+};
+
+/* Define the number of synthetic interrupt sources. */
+#define HV_SYNIC_SINT_COUNT		(16)
+#define HV_SYNIC_STIMER_COUNT		(4)
+
+/* Define invalid partition identifier. */
+#define HV_PARTITION_ID_INVALID		((u64)0x0)
+
+/* Define connection identifier type. */
+union hv_connection_id {
+	u32 Asu32;
+	struct {
+		u32 Id:24;
+		u32 Reserved:8;
+	} u;
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+	u32 Asu32;
+	struct {
+		u32 Id:24;
+		u32 Reserved:8;
+	} u ;
+};
+
+/* Define port type. */
+enum hv_port_type {
+	HvPortTypeMessage	= 1,
+	HvPortTypeEvent		= 2,
+	HvPortTypeMonitor	= 3
+};
+
+/* Define port information structure. */
+struct hv_port_info {
+	enum hv_port_type PortType;
+	u32 Padding;
+	union {
+		struct {
+			u32 TargetSint;
+			u32 TargetVp;
+			u64 RsvdZ;
+		} MessagePortInfo;
+		struct {
+			u32 TargetSint;
+			u32 TargetVp;
+			u16 BaseFlagNumber;
+			u16 FlagCount;
+			u32 RsvdZ;
+		} EventPortInfo;
+		struct {
+			u64 MonitorAddress;
+			u64 RsvdZ;
+		} MonitorPortInfo;
+	};
+};
+
+struct hv_connection_info {
+	enum hv_port_type PortType;
+	u32 Padding;
+	union {
+		struct {
+			u64 RsvdZ;
+		} MessageConnectionInfo;
+		struct {
+			u64 RsvdZ;
+		} EventConnectionInfo;
+		struct {
+			u64 MonitorAddress;
+		} MonitorConnectionInfo;
+	};
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+	u8 Asu8;
+	struct {
+		u8 MessagePending:1;
+		u8 Reserved:7;
+	};
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+	enum hv_message_type MessageType;
+	u8 PayloadSize;
+	union hv_message_flags MessageFlags;
+	u8 Reserved[2];
+	union {
+		u64 Sender;
+		union hv_port_id Port;
+	};
+};
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+	u32 TimerIndex;
+	u32 Reserved;
+	u64 ExpirationTime;	/* When the timer expired */
+	u64 DeliveryTime;	/* When the message was delivered */
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+	struct hv_message_header Header;
+	union {
+		u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+	} u ;
+};
+
+/* Define the number of message buffers associated with each port. */
+#define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+	struct hv_message SintMessage[HV_SYNIC_SINT_COUNT];
+};
+
+/* Define the synthetic interrupt controller event flags format. */
+union hv_synic_event_flags {
+	u8 Flags8[HV_EVENT_FLAGS_BYTE_COUNT];
+	u32 Flags32[HV_EVENT_FLAGS_DWORD_COUNT];
+};
+
+/* Define the synthetic interrupt flags page layout. */
+struct hv_synic_event_flags_page {
+	union hv_synic_event_flags SintEventFlags[HV_SYNIC_SINT_COUNT];
+};
+
+/* Define SynIC control register. */
+union hv_synic_scontrol {
+	u64 AsUINT64;
+	struct {
+		u64 Enable:1;
+		u64 Reserved:63;
+	};
+};
+
+/* Define synthetic interrupt source. */
+union hv_synic_sint {
+	u64 AsUINT64;
+	struct {
+		u64 Vector:8;
+		u64 Reserved1:8;
+		u64 Masked:1;
+		u64 AutoEoi:1;
+		u64 Reserved2:46;
+	};
+};
+
+/* Define the format of the SIMP register */
+union hv_synic_simp {
+	u64 AsUINT64;
+	struct {
+		u64 SimpEnabled:1;
+		u64 Preserved:11;
+		u64 BaseSimpGpa:52;
+	};
+};
+
+/* Define the format of the SIEFP register */
+union hv_synic_siefp {
+	u64 AsUINT64;
+	struct {
+		u64 SiefpEnabled:1;
+		u64 Preserved:11;
+		u64 BaseSiefpGpa:52;
+	};
+};
+
+/* Definitions for the monitored notification facility */
+union hv_monitor_trigger_group {
+	u64 AsUINT64;
+	struct {
+		u32 Pending;
+		u32 Armed;
+	};
+};
+
+struct hv_monitor_parameter {
+	union hv_connection_id ConnectionId;
+	u16 FlagNumber;
+	u16 RsvdZ;
+};
+
+union hv_monitor_trigger_state {
+	u32 Asu32;
+
+	struct {
+		u32 GroupEnable:4;
+		u32 RsvdZ:28;
+	};
+};
+
+/* struct hv_monitor_page Layout */
+/* ------------------------------------------------------ */
+/* | 0   | TriggerState (4 bytes) | Rsvd1 (4 bytes)     | */
+/* | 8   | TriggerGroup[0]                              | */
+/* | 10  | TriggerGroup[1]                              | */
+/* | 18  | TriggerGroup[2]                              | */
+/* | 20  | TriggerGroup[3]                              | */
+/* | 28  | Rsvd2[0]                                     | */
+/* | 30  | Rsvd2[1]                                     | */
+/* | 38  | Rsvd2[2]                                     | */
+/* | 40  | NextCheckTime[0][0]    | NextCheckTime[0][1] | */
+/* | ...                                                | */
+/* | 240 | Latency[0][0..3]                             | */
+/* | 340 | Rsvz3[0]                                     | */
+/* | 440 | Parameter[0][0]                              | */
+/* | 448 | Parameter[0][1]                              | */
+/* | ...                                                | */
+/* | 840 | Rsvd4[0]                                     | */
+/* ------------------------------------------------------ */
+struct hv_monitor_page {
+	union hv_monitor_trigger_state TriggerState;
+	u32 RsvdZ1;
+
+	union hv_monitor_trigger_group TriggerGroup[4];
+	u64 RsvdZ2[3];
+
+	s32 NextCheckTime[4][32];
+
+	u16 Latency[4][32];
+	u64 RsvdZ3[32];
+
+	struct hv_monitor_parameter Parameter[4][32];
+
+	u8 RsvdZ4[1984];
+};
+
+/* Declare the various hypercall operations. */
+enum hv_call_code {
+	HvCallPostMessage	= 0x005c,
+	HvCallSignalEvent	= 0x005d,
+};
+
+/* Definition of the HvPostMessage hypercall input structure. */
+struct hv_input_post_message {
+	union hv_connection_id ConnectionId;
+	u32 Reserved;
+	enum hv_message_type MessageType;
+	u32 PayloadSize;
+	u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+};
+
+/* Definition of the HvSignalEvent hypercall input structure. */
+struct hv_input_signal_event {
+	union hv_connection_id ConnectionId;
+	u16 FlagNumber;
+	u16 RsvdZ;
+};
+
+/*
+ * Versioning definitions used for guests reporting themselves to the
+ * hypervisor, and visa versa.
+ */
+
+/* Version info reported by guest OS's */
+enum hv_guest_os_vendor {
+	HvGuestOsVendorMicrosoft	= 0x0001
+};
+
+enum hv_guest_os_microsoft_ids {
+	HvGuestOsMicrosoftUndefined	= 0x00,
+	HvGuestOsMicrosoftMSDOS		= 0x01,
+	HvGuestOsMicrosoftWindows3x	= 0x02,
+	HvGuestOsMicrosoftWindows9x	= 0x03,
+	HvGuestOsMicrosoftWindowsNT	= 0x04,
+	HvGuestOsMicrosoftWindowsCE	= 0x05
+};
+
+/*
+ * Declare the MSR used to identify the guest OS.
+ */
+#define HV_X64_MSR_GUEST_OS_ID	0x40000000
+
+union hv_x64_msr_guest_os_id_contents {
+	u64 AsUINT64;
+	struct {
+		u64 BuildNumber:16;
+		u64 ServiceVersion:8; /* Service Pack, etc. */
+		u64 MinorVersion:8;
+		u64 MajorVersion:8;
+		u64 OsId:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
+		u64 VendorId:16; /* enum hv_guest_os_vendor */
+	};
+};
+
+/*
+ * Declare the MSR used to setup pages used to communicate with the hypervisor.
+ */
+#define HV_X64_MSR_HYPERCALL	0x40000001
+
+union hv_x64_msr_hypercall_contents {
+	u64 AsUINT64;
+	struct {
+		u64 Enable:1;
+		u64 Reserved:11;
+		u64 GuestPhysicalAddress:52;
+	};
+};
+
+#endif
diff --git a/drivers/staging/hv/logging.h b/drivers/staging/hv/logging.h
new file mode 100644
index 0000000..9e55617
--- /dev/null
+++ b/drivers/staging/hv/logging.h
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _LOGGING_H_
+#define _LOGGING_H_
+
+/* #include <linux/init.h> */
+/* #include <linux/module.h> */
+
+
+#define VMBUS				0x0001
+#define STORVSC				0x0002
+#define NETVSC				0x0004
+#define INPUTVSC			0x0008
+#define BLKVSC				0x0010
+#define VMBUS_DRV			0x0100
+#define STORVSC_DRV			0x0200
+#define NETVSC_DRV			0x0400
+#define INPUTVSC_DRV		0x0800
+#define BLKVSC_DRV			0x1000
+
+#define ALL_MODULES			(VMBUS		|\
+							STORVSC		|\
+							NETVSC		|\
+							INPUTVSC	|\
+							BLKVSC		|\
+							VMBUS_DRV	|\
+							STORVSC_DRV	|\
+							NETVSC_DRV	|\
+							INPUTVSC_DRV|\
+							BLKVSC_DRV)
+
+/* Logging Level */
+#define ERROR_LVL				3
+#define WARNING_LVL				4
+#define INFO_LVL				6
+#define DEBUG_LVL				7
+#define DEBUG_LVL_ENTEREXIT			8
+#define DEBUG_RING_LVL				9
+
+extern unsigned int vmbus_loglevel;
+
+#define ASSERT(expr)	\
+	if (!(expr)) {	\
+		printk(KERN_CRIT "Assertion failed! %s,%s,%s,line=%d\n", \
+		       #expr, __FILE__, __func__, __LINE__);	\
+		__asm__ __volatile__("int3");	\
+	}
+
+#define DPRINT(mod, lvl, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&	\
+	    (lvl <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
+	} while (0)
+
+#define DPRINT_DBG(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (DEBUG_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
+	} while (0)
+
+#define DPRINT_INFO(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (INFO_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_INFO #mod": " fmt "\n", ## args);\
+	} while (0)
+
+#define DPRINT_WARN(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (WARNING_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_WARNING #mod": WARNING! " fmt "\n", ## args);\
+	} while (0)
+
+#define DPRINT_ERR(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (ERROR_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_ERR #mod": %s() ERROR!! " fmt "\n",	\
+		       __func__, ## args);\
+	} while (0)
+
+#ifdef DEBUG
+#define DPRINT_ENTER(mod) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) && \
+	    (DEBUG_LVL_ENTEREXIT <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_DEBUG "["#mod"]: %s() enter\n", __func__);\
+	} while (0)
+
+#define DPRINT_EXIT(mod) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) && \
+	    (DEBUG_LVL_ENTEREXIT <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_DEBUG "["#mod"]: %s() exit\n", __func__);\
+	} while (0)
+#else
+#define DPRINT_ENTER(mod)
+#define DPRINT_EXIT(mod)
+#endif
+
+#endif /* _LOGGING_H_ */
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
new file mode 100644
index 0000000..3192d50
--- /dev/null
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <net/arp.h>
+#include <net/route.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+#include "osd.h"
+#include "logging.h"
+#include "vmbus.h"
+#include "NetVscApi.h"
+
+MODULE_LICENSE("GPL");
+
+struct net_device_context {
+	/* point back to our device context */
+	struct device_context *device_ctx;
+	struct net_device_stats stats;
+};
+
+struct netvsc_driver_context {
+	/* !! These must be the first 2 fields !! */
+	/* Which is a bug FIXME! */
+	struct driver_context drv_ctx;
+	struct netvsc_driver drv_obj;
+};
+
+static int netvsc_ringbuffer_size = NETVSC_DEVICE_RING_BUFFER_SIZE;
+
+/* The one and only one */
+static struct netvsc_driver_context g_netvsc_drv;
+
+static struct net_device_stats *netvsc_get_stats(struct net_device *net)
+{
+	struct net_device_context *net_device_ctx = netdev_priv(net);
+
+	return &net_device_ctx->stats;
+}
+
+static void netvsc_set_multicast_list(struct net_device *net)
+{
+}
+
+static int netvsc_open(struct net_device *net)
+{
+	struct net_device_context *net_device_ctx = netdev_priv(net);
+	struct driver_context *driver_ctx =
+	    driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
+	struct netvsc_driver_context *net_drv_ctx =
+		(struct netvsc_driver_context *)driver_ctx;
+	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
+	struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
+	int ret = 0;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	if (netif_carrier_ok(net)) {
+		memset(&net_device_ctx->stats, 0,
+		       sizeof(struct net_device_stats));
+
+		/* Open up the device */
+		ret = net_drv_obj->OnOpen(device_obj);
+		if (ret != 0) {
+			DPRINT_ERR(NETVSC_DRV,
+				   "unable to open device (ret %d).", ret);
+			return ret;
+		}
+
+		netif_start_queue(net);
+	} else {
+		DPRINT_ERR(NETVSC_DRV, "unable to open device...link is down.");
+	}
+
+	DPRINT_EXIT(NETVSC_DRV);
+	return ret;
+}
+
+static int netvsc_close(struct net_device *net)
+{
+	struct net_device_context *net_device_ctx = netdev_priv(net);
+	struct driver_context *driver_ctx =
+	    driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
+	struct netvsc_driver_context *net_drv_ctx =
+		(struct netvsc_driver_context *)driver_ctx;
+	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
+	struct hv_device *device_obj = &net_device_ctx->device_ctx->device_obj;
+	int ret;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	netif_stop_queue(net);
+
+	ret = net_drv_obj->OnClose(device_obj);
+	if (ret != 0)
+		DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret);
+
+	DPRINT_EXIT(NETVSC_DRV);
+
+	return ret;
+}
+
+static void netvsc_xmit_completion(void *context)
+{
+	struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
+	struct sk_buff *skb = (struct sk_buff *)
+		(unsigned long)packet->Completion.Send.SendCompletionTid;
+	struct net_device *net;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	kfree(packet);
+
+	if (skb) {
+		net = skb->dev;
+		dev_kfree_skb_any(skb);
+
+		if (netif_queue_stopped(net)) {
+			DPRINT_INFO(NETVSC_DRV, "net device (%p) waking up...",
+				    net);
+
+			netif_wake_queue(net);
+		}
+	}
+
+	DPRINT_EXIT(NETVSC_DRV);
+}
+
+static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
+{
+	struct net_device_context *net_device_ctx = netdev_priv(net);
+	struct driver_context *driver_ctx =
+	    driver_to_driver_context(net_device_ctx->device_ctx->device.driver);
+	struct netvsc_driver_context *net_drv_ctx =
+		(struct netvsc_driver_context *)driver_ctx;
+	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
+	struct hv_netvsc_packet *packet;
+	int i;
+	int ret;
+	int num_frags;
+	int retries = 0;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	/* Support only 1 chain of frags */
+	ASSERT(skb_shinfo(skb)->frag_list == NULL);
+	ASSERT(skb->dev == net);
+
+	DPRINT_DBG(NETVSC_DRV, "xmit packet - len %d data_len %d",
+		   skb->len, skb->data_len);
+
+	/* Add 1 for skb->data and any additional ones requested */
+	num_frags = skb_shinfo(skb)->nr_frags + 1 +
+		    net_drv_obj->AdditionalRequestPageBufferCount;
+
+	/* Allocate a netvsc packet based on # of frags. */
+	packet = kzalloc(sizeof(struct hv_netvsc_packet) +
+			 (num_frags * sizeof(struct hv_page_buffer)) +
+			 net_drv_obj->RequestExtSize, GFP_ATOMIC);
+	if (!packet) {
+		DPRINT_ERR(NETVSC_DRV, "unable to allocate hv_netvsc_packet");
+		return -1;
+	}
+
+	packet->Extension = (void *)(unsigned long)packet +
+				sizeof(struct hv_netvsc_packet) +
+				    (num_frags * sizeof(struct hv_page_buffer));
+
+	/* Setup the rndis header */
+	packet->PageBufferCount = num_frags;
+
+	/* TODO: Flush all write buffers/ memory fence ??? */
+	/* wmb(); */
+
+	/* Initialize it from the skb */
+	ASSERT(skb->data);
+	packet->TotalDataBufferLength	= skb->len;
+
+	/*
+	 * Start filling in the page buffers starting at
+	 * AdditionalRequestPageBufferCount offset
+	 */
+	packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT;
+	packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Offset = (unsigned long)skb->data & (PAGE_SIZE - 1);
+	packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Length = skb->len - skb->data_len;
+
+	ASSERT((skb->len - skb->data_len) <= PAGE_SIZE);
+
+	for (i = net_drv_obj->AdditionalRequestPageBufferCount + 1;
+	     i < num_frags; i++) {
+		packet->PageBuffers[i].Pfn =
+			page_to_pfn(skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].page);
+		packet->PageBuffers[i].Offset =
+			skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].page_offset;
+		packet->PageBuffers[i].Length =
+			skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].size;
+	}
+
+	/* Set the completion routine */
+	packet->Completion.Send.OnSendCompletion = netvsc_xmit_completion;
+	packet->Completion.Send.SendCompletionContext = packet;
+	packet->Completion.Send.SendCompletionTid = (unsigned long)skb;
+
+retry_send:
+	ret = net_drv_obj->OnSend(&net_device_ctx->device_ctx->device_obj,
+				  packet);
+
+	if (ret == 0) {
+		ret = NETDEV_TX_OK;
+		net_device_ctx->stats.tx_bytes += skb->len;
+		net_device_ctx->stats.tx_packets++;
+	} else {
+		retries++;
+		if (retries < 4) {
+			DPRINT_ERR(NETVSC_DRV, "unable to send..."
+					"retrying %d...", retries);
+			udelay(100);
+			goto retry_send;
+		}
+
+		/* no more room or we are shutting down */
+		DPRINT_ERR(NETVSC_DRV, "unable to send (%d)..."
+			   "marking net device (%p) busy", ret, net);
+		DPRINT_INFO(NETVSC_DRV, "net device (%p) stopping", net);
+
+		ret = NETDEV_TX_BUSY;
+		net_device_ctx->stats.tx_dropped++;
+
+		netif_stop_queue(net);
+
+		/*
+		 * Null it since the caller will free it instead of the
+		 * completion routine
+		 */
+		packet->Completion.Send.SendCompletionTid = 0;
+
+		/*
+		 * Release the resources since we will not get any send
+		 * completion
+		 */
+		netvsc_xmit_completion((void *)packet);
+	}
+
+	DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu",
+		   net_device_ctx->stats.tx_packets,
+		   net_device_ctx->stats.tx_bytes);
+
+	DPRINT_EXIT(NETVSC_DRV);
+	return ret;
+}
+
+/**
+ * netvsc_linkstatus_callback - Link up/down notification
+ */
+static void netvsc_linkstatus_callback(struct hv_device *device_obj,
+				       unsigned int status)
+{
+	struct device_context *device_ctx = to_device_context(device_obj);
+	struct net_device *net = dev_get_drvdata(&device_ctx->device);
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	if (!net) {
+		DPRINT_ERR(NETVSC_DRV, "got link status but net device "
+				"not initialized yet");
+		return;
+	}
+
+	if (status == 1) {
+		netif_carrier_on(net);
+		netif_wake_queue(net);
+	} else {
+		netif_carrier_off(net);
+		netif_stop_queue(net);
+	}
+	DPRINT_EXIT(NETVSC_DRV);
+}
+
+/**
+ * netvsc_recv_callback -  Callback when we receive a packet from the "wire" on the specified device.
+ */
+static int netvsc_recv_callback(struct hv_device *device_obj,
+				struct hv_netvsc_packet *packet)
+{
+	struct device_context *device_ctx = to_device_context(device_obj);
+	struct net_device *net = dev_get_drvdata(&device_ctx->device);
+	struct net_device_context *net_device_ctx;
+	struct sk_buff *skb;
+	void *data;
+	int ret;
+	int i;
+	unsigned long flags;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	if (!net) {
+		DPRINT_ERR(NETVSC_DRV, "got receive callback but net device "
+				"not initialized yet");
+		return 0;
+	}
+
+	net_device_ctx = netdev_priv(net);
+
+	/* Allocate a skb - TODO preallocate this */
+	/* Pad 2-bytes to align IP header to 16 bytes */
+	skb = dev_alloc_skb(packet->TotalDataBufferLength + 2);
+	ASSERT(skb);
+	skb_reserve(skb, 2);
+	skb->dev = net;
+
+	/* for kmap_atomic */
+	local_irq_save(flags);
+
+	/*
+	 * Copy to skb. This copy is needed here since the memory pointed by
+	 * hv_netvsc_packet cannot be deallocated
+	 */
+	for (i = 0; i < packet->PageBufferCount; i++) {
+		data = kmap_atomic(pfn_to_page(packet->PageBuffers[i].Pfn),
+					       KM_IRQ1);
+		data = (void *)(unsigned long)data +
+				packet->PageBuffers[i].Offset;
+
+		memcpy(skb_put(skb, packet->PageBuffers[i].Length), data,
+		       packet->PageBuffers[i].Length);
+
+		kunmap_atomic((void *)((unsigned long)data -
+				       packet->PageBuffers[i].Offset), KM_IRQ1);
+	}
+
+	local_irq_restore(flags);
+
+	skb->protocol = eth_type_trans(skb, net);
+
+	skb->ip_summed = CHECKSUM_NONE;
+
+	/*
+	 * Pass the skb back up. Network stack will deallocate the skb when it
+	 * is done
+	 */
+	ret = netif_rx(skb);
+
+	switch (ret) {
+	case NET_RX_DROP:
+		net_device_ctx->stats.rx_dropped++;
+		break;
+	default:
+		net_device_ctx->stats.rx_packets++;
+		net_device_ctx->stats.rx_bytes += skb->len;
+		break;
+
+	}
+	DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu",
+		   net_device_ctx->stats.rx_packets,
+		   net_device_ctx->stats.rx_bytes);
+
+	DPRINT_EXIT(NETVSC_DRV);
+
+	return 0;
+}
+
+static const struct net_device_ops device_ops = {
+	.ndo_open =			netvsc_open,
+	.ndo_stop =			netvsc_close,
+	.ndo_start_xmit =		netvsc_start_xmit,
+	.ndo_get_stats =		netvsc_get_stats,
+	.ndo_set_multicast_list =	netvsc_set_multicast_list,
+};
+
+static int netvsc_probe(struct device *device)
+{
+	struct driver_context *driver_ctx =
+		driver_to_driver_context(device->driver);
+	struct netvsc_driver_context *net_drv_ctx =
+		(struct netvsc_driver_context *)driver_ctx;
+	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
+	struct device_context *device_ctx = device_to_device_context(device);
+	struct hv_device *device_obj = &device_ctx->device_obj;
+	struct net_device *net = NULL;
+	struct net_device_context *net_device_ctx;
+	struct netvsc_device_info device_info;
+	int ret;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	if (!net_drv_obj->Base.OnDeviceAdd)
+		return -1;
+
+	net = alloc_netdev(sizeof(struct net_device_context), "seth%d",
+			   ether_setup);
+	if (!net)
+		return -1;
+
+	/* Set initial state */
+	netif_carrier_off(net);
+	netif_stop_queue(net);
+
+	net_device_ctx = netdev_priv(net);
+	net_device_ctx->device_ctx = device_ctx;
+	dev_set_drvdata(device, net);
+
+	/* Notify the netvsc driver of the new device */
+	ret = net_drv_obj->Base.OnDeviceAdd(device_obj, &device_info);
+	if (ret != 0) {
+		free_netdev(net);
+		dev_set_drvdata(device, NULL);
+
+		DPRINT_ERR(NETVSC_DRV, "unable to add netvsc device (ret %d)",
+			   ret);
+		return ret;
+	}
+
+	/*
+	 * If carrier is still off ie we did not get a link status callback,
+	 * update it if necessary
+	 */
+	/*
+	 * FIXME: We should use a atomic or test/set instead to avoid getting
+	 * out of sync with the device's link status
+	 */
+	if (!netif_carrier_ok(net))
+		if (!device_info.LinkState)
+			netif_carrier_on(net);
+
+	memcpy(net->dev_addr, device_info.MacAddr, ETH_ALEN);
+
+	net->netdev_ops = &device_ops;
+
+	SET_NETDEV_DEV(net, device);
+
+	ret = register_netdev(net);
+	if (ret != 0) {
+		/* Remove the device and release the resource */
+		net_drv_obj->Base.OnDeviceRemove(device_obj);
+		free_netdev(net);
+	}
+
+	DPRINT_EXIT(NETVSC_DRV);
+	return ret;
+}
+
+static int netvsc_remove(struct device *device)
+{
+	struct driver_context *driver_ctx =
+		driver_to_driver_context(device->driver);
+	struct netvsc_driver_context *net_drv_ctx =
+		(struct netvsc_driver_context *)driver_ctx;
+	struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj;
+	struct device_context *device_ctx = device_to_device_context(device);
+	struct net_device *net = dev_get_drvdata(&device_ctx->device);
+	struct hv_device *device_obj = &device_ctx->device_obj;
+	int ret;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	if (net == NULL) {
+		DPRINT_INFO(NETVSC, "no net device to remove");
+		DPRINT_EXIT(NETVSC_DRV);
+		return 0;
+	}
+
+	if (!net_drv_obj->Base.OnDeviceRemove) {
+		DPRINT_EXIT(NETVSC_DRV);
+		return -1;
+	}
+
+	/* Stop outbound asap */
+	netif_stop_queue(net);
+	/* netif_carrier_off(net); */
+
+	unregister_netdev(net);
+
+	/*
+	 * Call to the vsc driver to let it know that the device is being
+	 * removed
+	 */
+	ret = net_drv_obj->Base.OnDeviceRemove(device_obj);
+	if (ret != 0) {
+		/* TODO: */
+		DPRINT_ERR(NETVSC, "unable to remove vsc device (ret %d)", ret);
+	}
+
+	free_netdev(net);
+	DPRINT_EXIT(NETVSC_DRV);
+	return ret;
+}
+
+static int netvsc_drv_exit_cb(struct device *dev, void *data)
+{
+	struct device **curr = (struct device **)data;
+
+	*curr = dev;
+	/* stop iterating */
+	return 1;
+}
+
+static void netvsc_drv_exit(void)
+{
+	struct netvsc_driver *netvsc_drv_obj = &g_netvsc_drv.drv_obj;
+	struct driver_context *drv_ctx = &g_netvsc_drv.drv_ctx;
+	struct device *current_dev;
+	int ret;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	while (1) {
+		current_dev = NULL;
+
+		/* Get the device */
+		ret = driver_for_each_device(&drv_ctx->driver, NULL,
+					     &current_dev, netvsc_drv_exit_cb);
+		if (ret)
+			DPRINT_WARN(NETVSC_DRV,
+				    "driver_for_each_device returned %d", ret);
+
+		if (current_dev == NULL)
+			break;
+
+		/* Initiate removal from the top-down */
+		DPRINT_INFO(NETVSC_DRV, "unregistering device (%p)...",
+			    current_dev);
+
+		device_unregister(current_dev);
+	}
+
+	if (netvsc_drv_obj->Base.OnCleanup)
+		netvsc_drv_obj->Base.OnCleanup(&netvsc_drv_obj->Base);
+
+	vmbus_child_driver_unregister(drv_ctx);
+
+	DPRINT_EXIT(NETVSC_DRV);
+
+	return;
+}
+
+static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
+{
+	struct netvsc_driver *net_drv_obj = &g_netvsc_drv.drv_obj;
+	struct driver_context *drv_ctx = &g_netvsc_drv.drv_ctx;
+	int ret;
+
+	DPRINT_ENTER(NETVSC_DRV);
+
+	vmbus_get_interface(&net_drv_obj->Base.VmbusChannelInterface);
+
+	net_drv_obj->RingBufferSize = netvsc_ringbuffer_size;
+	net_drv_obj->OnReceiveCallback = netvsc_recv_callback;
+	net_drv_obj->OnLinkStatusChanged = netvsc_linkstatus_callback;
+
+	/* Callback to client driver to complete the initialization */
+	drv_init(&net_drv_obj->Base);
+
+	drv_ctx->driver.name = net_drv_obj->Base.name;
+	memcpy(&drv_ctx->class_id, &net_drv_obj->Base.deviceType,
+	       sizeof(struct hv_guid));
+
+	drv_ctx->probe = netvsc_probe;
+	drv_ctx->remove = netvsc_remove;
+
+	/* The driver belongs to vmbus */
+	ret = vmbus_child_driver_register(drv_ctx);
+
+	DPRINT_EXIT(NETVSC_DRV);
+
+	return ret;
+}
+
+static int __init netvsc_init(void)
+{
+	int ret;
+
+	DPRINT_ENTER(NETVSC_DRV);
+	DPRINT_INFO(NETVSC_DRV, "Netvsc initializing....");
+
+	ret = netvsc_drv_init(NetVscInitialize);
+
+	DPRINT_EXIT(NETVSC_DRV);
+
+	return ret;
+}
+
+static void __exit netvsc_exit(void)
+{
+	DPRINT_ENTER(NETVSC_DRV);
+	netvsc_drv_exit();
+	DPRINT_EXIT(NETVSC_DRV);
+}
+
+module_param(netvsc_ringbuffer_size, int, S_IRUGO);
+
+module_init(netvsc_init);
+module_exit(netvsc_exit);
diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c
new file mode 100644
index 0000000..8fe543b
--- /dev/null
+++ b/drivers/staging/hv/osd.c
@@ -0,0 +1,156 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/vmalloc.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include "osd.h"
+
+struct osd_callback_struct {
+	struct work_struct work;
+	void (*callback)(void *);
+	void *data;
+};
+
+void *osd_VirtualAllocExec(unsigned int size)
+{
+#ifdef __x86_64__
+	return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL_EXEC);
+#else
+	return __vmalloc(size, GFP_KERNEL,
+			 __pgprot(__PAGE_KERNEL & (~_PAGE_NX)));
+#endif
+}
+
+void *osd_PageAlloc(unsigned int count)
+{
+	void *p;
+
+	p = (void *)__get_free_pages(GFP_KERNEL, get_order(count * PAGE_SIZE));
+	if (p)
+		memset(p, 0, count * PAGE_SIZE);
+	return p;
+
+	/* struct page* page = alloc_page(GFP_KERNEL|__GFP_ZERO); */
+	/* void *p; */
+
+	/* BUGBUG: We need to use kmap in case we are in HIMEM region */
+	/* p = page_address(page); */
+	/* if (p) memset(p, 0, PAGE_SIZE); */
+	/* return p; */
+}
+EXPORT_SYMBOL_GPL(osd_PageAlloc);
+
+void osd_PageFree(void *page, unsigned int count)
+{
+	free_pages((unsigned long)page, get_order(count * PAGE_SIZE));
+	/*struct page* p = virt_to_page(page);
+	__free_page(p);*/
+}
+EXPORT_SYMBOL_GPL(osd_PageFree);
+
+struct osd_waitevent *osd_WaitEventCreate(void)
+{
+	struct osd_waitevent *wait = kmalloc(sizeof(struct osd_waitevent),
+					     GFP_KERNEL);
+	if (!wait)
+		return NULL;
+
+	wait->condition = 0;
+	init_waitqueue_head(&wait->event);
+	return wait;
+}
+EXPORT_SYMBOL_GPL(osd_WaitEventCreate);
+
+void osd_WaitEventSet(struct osd_waitevent *waitEvent)
+{
+	waitEvent->condition = 1;
+	wake_up_interruptible(&waitEvent->event);
+}
+EXPORT_SYMBOL_GPL(osd_WaitEventSet);
+
+int osd_WaitEventWait(struct osd_waitevent *waitEvent)
+{
+	int ret = 0;
+
+	ret = wait_event_interruptible(waitEvent->event,
+				       waitEvent->condition);
+	waitEvent->condition = 0;
+	return ret;
+}
+EXPORT_SYMBOL_GPL(osd_WaitEventWait);
+
+int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent, u32 TimeoutInMs)
+{
+	int ret = 0;
+
+	ret = wait_event_interruptible_timeout(waitEvent->event,
+					       waitEvent->condition,
+					       msecs_to_jiffies(TimeoutInMs));
+	waitEvent->condition = 0;
+	return ret;
+}
+EXPORT_SYMBOL_GPL(osd_WaitEventWaitEx);
+
+static void osd_callback_work(struct work_struct *work)
+{
+	struct osd_callback_struct *cb = container_of(work,
+						struct osd_callback_struct,
+						work);
+	(cb->callback)(cb->data);
+	kfree(cb);
+}
+
+int osd_schedule_callback(struct workqueue_struct *wq,
+			  void (*func)(void *),
+			  void *data)
+{
+	struct osd_callback_struct *cb;
+
+	cb = kmalloc(sizeof(*cb), GFP_KERNEL);
+	if (!cb) {
+		printk(KERN_ERR "unable to allocate memory in osd_schedule_callback\n");
+		return -1;
+	}
+
+	cb->callback = func;
+	cb->data = data;
+	INIT_WORK(&cb->work, osd_callback_work);
+	return queue_work(wq, &cb->work);
+}
+
diff --git a/drivers/staging/hv/osd.h b/drivers/staging/hv/osd.h
new file mode 100644
index 0000000..9504604
--- /dev/null
+++ b/drivers/staging/hv/osd.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _OSD_H_
+#define _OSD_H_
+
+
+/* Defines */
+#define ALIGN_UP(value, align)	(((value) & (align-1)) ?		\
+				 (((value) + (align-1)) & ~(align-1)) :	\
+				 (value))
+#define ALIGN_DOWN(value, align)	((value) & ~(align-1))
+#define NUM_PAGES_SPANNED(addr, len)	((ALIGN_UP(addr+len, PAGE_SIZE) - \
+					 ALIGN_DOWN(addr, PAGE_SIZE)) >>  \
+					 PAGE_SHIFT)
+
+#define LOWORD(dw)	((unsigned short)(dw))
+#define HIWORD(dw)	((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF))
+
+struct hv_guid {
+	unsigned char data[16];
+};
+
+struct osd_waitevent {
+	int condition;
+	wait_queue_head_t event;
+};
+
+/* Osd routines */
+
+extern void *osd_VirtualAllocExec(unsigned int size);
+
+extern void *osd_PageAlloc(unsigned int count);
+extern void osd_PageFree(void *page, unsigned int count);
+
+extern struct osd_waitevent *osd_WaitEventCreate(void);
+extern void osd_WaitEventSet(struct osd_waitevent *waitEvent);
+extern int osd_WaitEventWait(struct osd_waitevent *waitEvent);
+
+/* If >0, waitEvent got signaled. If ==0, timeout. If < 0, error */
+extern int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent,
+			       u32 TimeoutInMs);
+
+int osd_schedule_callback(struct workqueue_struct *wq,
+			  void (*func)(void *),
+			  void *data);
+
+#endif /* _OSD_H_ */
diff --git a/drivers/staging/hv/rndis.h b/drivers/staging/hv/rndis.h
new file mode 100644
index 0000000..7c73277
--- /dev/null
+++ b/drivers/staging/hv/rndis.h
@@ -0,0 +1,652 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+#ifndef _RNDIS_H_
+#define _RNDIS_H_
+
+/*  Status codes */
+
+
+#ifndef STATUS_SUCCESS
+#define STATUS_SUCCESS				(0x00000000L)
+#endif
+
+#ifndef STATUS_UNSUCCESSFUL
+#define STATUS_UNSUCCESSFUL			(0xC0000001L)
+#endif
+
+#ifndef STATUS_PENDING
+#define STATUS_PENDING				(0x00000103L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_RESOURCES
+#define STATUS_INSUFFICIENT_RESOURCES		(0xC000009AL)
+#endif
+
+#ifndef STATUS_BUFFER_OVERFLOW
+#define STATUS_BUFFER_OVERFLOW			(0x80000005L)
+#endif
+
+#ifndef STATUS_NOT_SUPPORTED
+#define STATUS_NOT_SUPPORTED			(0xC00000BBL)
+#endif
+
+#define RNDIS_STATUS_SUCCESS			(STATUS_SUCCESS)
+#define RNDIS_STATUS_PENDING			(STATUS_PENDING)
+#define RNDIS_STATUS_NOT_RECOGNIZED		(0x00010001L)
+#define RNDIS_STATUS_NOT_COPIED			(0x00010002L)
+#define RNDIS_STATUS_NOT_ACCEPTED		(0x00010003L)
+#define RNDIS_STATUS_CALL_ACTIVE		(0x00010007L)
+
+#define RNDIS_STATUS_ONLINE			(0x40010003L)
+#define RNDIS_STATUS_RESET_START		(0x40010004L)
+#define RNDIS_STATUS_RESET_END			(0x40010005L)
+#define RNDIS_STATUS_RING_STATUS		(0x40010006L)
+#define RNDIS_STATUS_CLOSED			(0x40010007L)
+#define RNDIS_STATUS_WAN_LINE_UP		(0x40010008L)
+#define RNDIS_STATUS_WAN_LINE_DOWN		(0x40010009L)
+#define RNDIS_STATUS_WAN_FRAGMENT		(0x4001000AL)
+#define RNDIS_STATUS_MEDIA_CONNECT		(0x4001000BL)
+#define RNDIS_STATUS_MEDIA_DISCONNECT		(0x4001000CL)
+#define RNDIS_STATUS_HARDWARE_LINE_UP		(0x4001000DL)
+#define RNDIS_STATUS_HARDWARE_LINE_DOWN		(0x4001000EL)
+#define RNDIS_STATUS_INTERFACE_UP		(0x4001000FL)
+#define RNDIS_STATUS_INTERFACE_DOWN		(0x40010010L)
+#define RNDIS_STATUS_MEDIA_BUSY			(0x40010011L)
+#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION	(0x40010012L)
+#define RNDIS_STATUS_WW_INDICATION		RDIA_SPECIFIC_INDICATION
+#define RNDIS_STATUS_LINK_SPEED_CHANGE		(0x40010013L)
+
+#define RNDIS_STATUS_NOT_RESETTABLE		(0x80010001L)
+#define RNDIS_STATUS_SOFT_ERRORS		(0x80010003L)
+#define RNDIS_STATUS_HARD_ERRORS		(0x80010004L)
+#define RNDIS_STATUS_BUFFER_OVERFLOW		(STATUS_BUFFER_OVERFLOW)
+
+#define RNDIS_STATUS_FAILURE			(STATUS_UNSUCCESSFUL)
+#define RNDIS_STATUS_RESOURCES			(STATUS_INSUFFICIENT_RESOURCES)
+#define RNDIS_STATUS_CLOSING			(0xC0010002L)
+#define RNDIS_STATUS_BAD_VERSION		(0xC0010004L)
+#define RNDIS_STATUS_BAD_CHARACTERISTICS	(0xC0010005L)
+#define RNDIS_STATUS_ADAPTER_NOT_FOUND		(0xC0010006L)
+#define RNDIS_STATUS_OPEN_FAILED		(0xC0010007L)
+#define RNDIS_STATUS_DEVICE_FAILED		(0xC0010008L)
+#define RNDIS_STATUS_MULTICAST_FULL		(0xC0010009L)
+#define RNDIS_STATUS_MULTICAST_EXISTS		(0xC001000AL)
+#define RNDIS_STATUS_MULTICAST_NOT_FOUND	(0xC001000BL)
+#define RNDIS_STATUS_REQUEST_ABORTED		(0xC001000CL)
+#define RNDIS_STATUS_RESET_IN_PROGRESS		(0xC001000DL)
+#define RNDIS_STATUS_CLOSING_INDICATING		(0xC001000EL)
+#define RNDIS_STATUS_NOT_SUPPORTED		(STATUS_NOT_SUPPORTED)
+#define RNDIS_STATUS_INVALID_PACKET		(0xC001000FL)
+#define RNDIS_STATUS_OPEN_LIST_FULL		(0xC0010010L)
+#define RNDIS_STATUS_ADAPTER_NOT_READY		(0xC0010011L)
+#define RNDIS_STATUS_ADAPTER_NOT_OPEN		(0xC0010012L)
+#define RNDIS_STATUS_NOT_INDICATING		(0xC0010013L)
+#define RNDIS_STATUS_INVALID_LENGTH		(0xC0010014L)
+#define RNDIS_STATUS_INVALID_DATA		(0xC0010015L)
+#define RNDIS_STATUS_BUFFER_TOO_SHORT		(0xC0010016L)
+#define RNDIS_STATUS_INVALID_OID		(0xC0010017L)
+#define RNDIS_STATUS_ADAPTER_REMOVED		(0xC0010018L)
+#define RNDIS_STATUS_UNSUPPORTED_MEDIA		(0xC0010019L)
+#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE	(0xC001001AL)
+#define RNDIS_STATUS_FILE_NOT_FOUND		(0xC001001BL)
+#define RNDIS_STATUS_ERROR_READING_FILE		(0xC001001CL)
+#define RNDIS_STATUS_ALREADY_MAPPED		(0xC001001DL)
+#define RNDIS_STATUS_RESOURCE_CONFLICT		(0xC001001EL)
+#define RNDIS_STATUS_NO_CABLE			(0xC001001FL)
+
+#define RNDIS_STATUS_INVALID_SAP		(0xC0010020L)
+#define RNDIS_STATUS_SAP_IN_USE			(0xC0010021L)
+#define RNDIS_STATUS_INVALID_ADDRESS		(0xC0010022L)
+#define RNDIS_STATUS_VC_NOT_ACTIVATED		(0xC0010023L)
+#define RNDIS_STATUS_DEST_OUT_OF_ORDER		(0xC0010024L)
+#define RNDIS_STATUS_VC_NOT_AVAILABLE		(0xC0010025L)
+#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE	(0xC0010026L)
+#define RNDIS_STATUS_INCOMPATABLE_QOS		(0xC0010027L)
+#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED	(0xC0010028L)
+#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION	(0xC0010029L)
+
+#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR	(0xC0011000L)
+
+/* Object Identifiers used by NdisRequest Query/Set Information */
+/* General Objects */
+#define RNDIS_OID_GEN_SUPPORTED_LIST		0x00010101
+#define RNDIS_OID_GEN_HARDWARE_STATUS		0x00010102
+#define RNDIS_OID_GEN_MEDIA_SUPPORTED		0x00010103
+#define RNDIS_OID_GEN_MEDIA_IN_USE		0x00010104
+#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD		0x00010105
+#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE	0x00010106
+#define RNDIS_OID_GEN_LINK_SPEED		0x00010107
+#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE	0x00010108
+#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE	0x00010109
+#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE	0x0001010A
+#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE	0x0001010B
+#define RNDIS_OID_GEN_VENDOR_ID			0x0001010C
+#define RNDIS_OID_GEN_VENDOR_DESCRIPTION	0x0001010D
+#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER	0x0001010E
+#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD		0x0001010F
+#define RNDIS_OID_GEN_DRIVER_VERSION		0x00010110
+#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE	0x00010111
+#define RNDIS_OID_GEN_PROTOCOL_OPTIONS		0x00010112
+#define RNDIS_OID_GEN_MAC_OPTIONS		0x00010113
+#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS	0x00010114
+#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS	0x00010115
+#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION	0x00010116
+#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES	0x00010118
+#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET	0x00010119
+#define RNDIS_OID_GEN_MACHINE_NAME		0x0001021A
+#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER	0x0001021B
+
+#define RNDIS_OID_GEN_XMIT_OK			0x00020101
+#define RNDIS_OID_GEN_RCV_OK			0x00020102
+#define RNDIS_OID_GEN_XMIT_ERROR		0x00020103
+#define RNDIS_OID_GEN_RCV_ERROR			0x00020104
+#define RNDIS_OID_GEN_RCV_NO_BUFFER		0x00020105
+
+#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT	0x00020201
+#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT	0x00020202
+#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT	0x00020203
+#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT	0x00020204
+#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT	0x00020205
+#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT	0x00020206
+#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV	0x00020207
+#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV	0x00020208
+#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV	0x00020209
+#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV	0x0002020A
+#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV	0x0002020B
+#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV	0x0002020C
+
+#define RNDIS_OID_GEN_RCV_CRC_ERROR		0x0002020D
+#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH	0x0002020E
+
+#define RNDIS_OID_GEN_GET_TIME_CAPS		0x0002020F
+#define RNDIS_OID_GEN_GET_NETCARD_TIME		0x00020210
+
+/* These are connection-oriented general OIDs. */
+/* These replace the above OIDs for connection-oriented media. */
+#define RNDIS_OID_GEN_CO_SUPPORTED_LIST		0x00010101
+#define RNDIS_OID_GEN_CO_HARDWARE_STATUS	0x00010102
+#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED	0x00010103
+#define RNDIS_OID_GEN_CO_MEDIA_IN_USE		0x00010104
+#define RNDIS_OID_GEN_CO_LINK_SPEED		0x00010105
+#define RNDIS_OID_GEN_CO_VENDOR_ID		0x00010106
+#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION	0x00010107
+#define RNDIS_OID_GEN_CO_DRIVER_VERSION		0x00010108
+#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS	0x00010109
+#define RNDIS_OID_GEN_CO_MAC_OPTIONS		0x0001010A
+#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS	0x0001010B
+#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION	0x0001010C
+#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED	0x0001010D
+
+#define RNDIS_OID_GEN_CO_GET_TIME_CAPS		0x00010201
+#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME	0x00010202
+
+/* These are connection-oriented statistics OIDs. */
+#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK		0x00020101
+#define RNDIS_OID_GEN_CO_RCV_PDUS_OK		0x00020102
+#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR	0x00020103
+#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR		0x00020104
+#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER	0x00020105
+
+
+#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR		0x00020201
+#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH	0x00020202
+#define RNDIS_OID_GEN_CO_BYTES_XMIT		0x00020203
+#define RNDIS_OID_GEN_CO_BYTES_RCV		0x00020204
+#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING	0x00020205
+#define RNDIS_OID_GEN_CO_NETCARD_LOAD		0x00020206
+
+/* These are objects for Connection-oriented media call-managers. */
+#define RNDIS_OID_CO_ADD_PVC			0xFF000001
+#define RNDIS_OID_CO_DELETE_PVC			0xFF000002
+#define RNDIS_OID_CO_GET_CALL_INFORMATION	0xFF000003
+#define RNDIS_OID_CO_ADD_ADDRESS		0xFF000004
+#define RNDIS_OID_CO_DELETE_ADDRESS		0xFF000005
+#define RNDIS_OID_CO_GET_ADDRESSES		0xFF000006
+#define RNDIS_OID_CO_ADDRESS_CHANGE		0xFF000007
+#define RNDIS_OID_CO_SIGNALING_ENABLED		0xFF000008
+#define RNDIS_OID_CO_SIGNALING_DISABLED		0xFF000009
+
+/* 802.3 Objects (Ethernet) */
+#define RNDIS_OID_802_3_PERMANENT_ADDRESS	0x01010101
+#define RNDIS_OID_802_3_CURRENT_ADDRESS		0x01010102
+#define RNDIS_OID_802_3_MULTICAST_LIST		0x01010103
+#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE	0x01010104
+#define RNDIS_OID_802_3_MAC_OPTIONS		0x01010105
+
+#define NDIS_802_3_MAC_OPTION_PRIORITY		0x00000001
+
+#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT	0x01020101
+#define RNDIS_OID_802_3_XMIT_ONE_COLLISION	0x01020102
+#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS	0x01020103
+
+#define RNDIS_OID_802_3_XMIT_DEFERRED		0x01020201
+#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS	0x01020202
+#define RNDIS_OID_802_3_RCV_OVERRUN		0x01020203
+#define RNDIS_OID_802_3_XMIT_UNDERRUN		0x01020204
+#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE	0x01020205
+#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST	0x01020206
+#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS	0x01020207
+
+/* Remote NDIS message types */
+#define REMOTE_NDIS_PACKET_MSG			0x00000001
+#define REMOTE_NDIS_INITIALIZE_MSG		0x00000002
+#define REMOTE_NDIS_HALT_MSG			0x00000003
+#define REMOTE_NDIS_QUERY_MSG			0x00000004
+#define REMOTE_NDIS_SET_MSG			0x00000005
+#define REMOTE_NDIS_RESET_MSG			0x00000006
+#define REMOTE_NDIS_INDICATE_STATUS_MSG		0x00000007
+#define REMOTE_NDIS_KEEPALIVE_MSG		0x00000008
+
+#define REMOTE_CONDIS_MP_CREATE_VC_MSG		0x00008001
+#define REMOTE_CONDIS_MP_DELETE_VC_MSG		0x00008002
+#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG	0x00008005
+#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG	0x00008006
+#define REMOTE_CONDIS_INDICATE_STATUS_MSG	0x00008007
+
+/* Remote NDIS message completion types */
+#define REMOTE_NDIS_INITIALIZE_CMPLT		0x80000002
+#define REMOTE_NDIS_QUERY_CMPLT			0x80000004
+#define REMOTE_NDIS_SET_CMPLT			0x80000005
+#define REMOTE_NDIS_RESET_CMPLT			0x80000006
+#define REMOTE_NDIS_KEEPALIVE_CMPLT		0x80000008
+
+#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT	0x80008001
+#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT	0x80008002
+#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT	0x80008005
+#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT	0x80008006
+
+/*
+ * Reserved message type for private communication between lower-layer host
+ * driver and remote device, if necessary.
+ */
+#define REMOTE_NDIS_BUS_MSG			0xff000001
+
+/*  Defines for DeviceFlags in struct rndis_initialize_complete */
+#define RNDIS_DF_CONNECTIONLESS			0x00000001
+#define RNDIS_DF_CONNECTION_ORIENTED		0x00000002
+#define RNDIS_DF_RAW_DATA			0x00000004
+
+/*  Remote NDIS medium types. */
+#define RNdisMedium802_3			0x00000000
+#define RNdisMedium802_5			0x00000001
+#define RNdisMediumFddi				0x00000002
+#define RNdisMediumWan				0x00000003
+#define RNdisMediumLocalTalk			0x00000004
+#define RNdisMediumArcnetRaw			0x00000006
+#define RNdisMediumArcnet878_2			0x00000007
+#define RNdisMediumAtm				0x00000008
+#define RNdisMediumWirelessWan			0x00000009
+#define RNdisMediumIrda				0x0000000a
+#define RNdisMediumCoWan			0x0000000b
+/* Not a real medium, defined as an upper-bound */
+#define RNdisMediumMax				0x0000000d
+
+
+/* Remote NDIS medium connection states. */
+#define RNdisMediaStateConnected		0x00000000
+#define RNdisMediaStateDisconnected		0x00000001
+
+/*  Remote NDIS version numbers */
+#define RNDIS_MAJOR_VERSION			0x00000001
+#define RNDIS_MINOR_VERSION			0x00000000
+
+
+/* NdisInitialize message */
+struct rndis_initialize_request {
+	u32 RequestId;
+	u32 MajorVersion;
+	u32 MinorVersion;
+	u32 MaxTransferSize;
+};
+
+/* Response to NdisInitialize */
+struct rndis_initialize_complete {
+	u32 RequestId;
+	u32 Status;
+	u32 MajorVersion;
+	u32 MinorVersion;
+	u32 DeviceFlags;
+	u32 Medium;
+	u32 MaxPacketsPerMessage;
+	u32 MaxTransferSize;
+	u32 PacketAlignmentFactor;
+	u32 AFListOffset;
+	u32 AFListSize;
+};
+
+/* Call manager devices only: Information about an address family */
+/* supported by the device is appended to the response to NdisInitialize. */
+struct rndis_co_address_family {
+	u32 AddressFamily;
+	u32 MajorVersion;
+	u32 MinorVersion;
+};
+
+/* NdisHalt message */
+struct rndis_halt_request {
+	u32 RequestId;
+};
+
+/* NdisQueryRequest message */
+struct rndis_query_request {
+	u32 RequestId;
+	u32 Oid;
+	u32 InformationBufferLength;
+	u32 InformationBufferOffset;
+	u32 DeviceVcHandle;
+};
+
+/* Response to NdisQueryRequest */
+struct rndis_query_complete {
+	u32 RequestId;
+	u32 Status;
+	u32 InformationBufferLength;
+	u32 InformationBufferOffset;
+};
+
+/* NdisSetRequest message */
+struct rndis_set_request {
+	u32 RequestId;
+	u32 Oid;
+	u32 InformationBufferLength;
+	u32 InformationBufferOffset;
+	u32 DeviceVcHandle;
+};
+
+/* Response to NdisSetRequest */
+struct rndis_set_complete {
+	u32 RequestId;
+	u32 Status;
+};
+
+/* NdisReset message */
+struct rndis_reset_request {
+	u32 Reserved;
+};
+
+/* Response to NdisReset */
+struct rndis_reset_complete {
+	u32 Status;
+	u32 AddressingReset;
+};
+
+/* NdisMIndicateStatus message */
+struct rndis_indicate_status {
+	u32 Status;
+	u32 StatusBufferLength;
+	u32 StatusBufferOffset;
+};
+
+/* Diagnostic information passed as the status buffer in */
+/* struct rndis_indicate_status messages signifying error conditions. */
+struct rndis_diagnostic_info {
+	u32 DiagStatus;
+	u32 ErrorOffset;
+};
+
+/* NdisKeepAlive message */
+struct rndis_keepalive_request {
+	u32 RequestId;
+};
+
+/* Response to NdisKeepAlive */
+struct rndis_keepalive_complete {
+	u32 RequestId;
+	u32 Status;
+};
+
+/*
+ * Data message. All Offset fields contain byte offsets from the beginning of
+ * struct rndis_packet. All Length fields are in bytes.  VcHandle is set
+ * to 0 for connectionless data, otherwise it contains the VC handle.
+ */
+struct rndis_packet {
+	u32 DataOffset;
+	u32 DataLength;
+	u32 OOBDataOffset;
+	u32 OOBDataLength;
+	u32 NumOOBDataElements;
+	u32 PerPacketInfoOffset;
+	u32 PerPacketInfoLength;
+	u32 VcHandle;
+	u32 Reserved;
+};
+
+/* Optional Out of Band data associated with a Data message. */
+struct rndis_oobd {
+	u32 Size;
+	u32 Type;
+	u32 ClassInformationOffset;
+};
+
+/* Packet extension field contents associated with a Data message. */
+struct rndis_per_packet_info {
+	u32 Size;
+	u32 Type;
+	u32 PerPacketInformationOffset;
+};
+
+/* Format of Information buffer passed in a SetRequest for the OID */
+/* OID_GEN_RNDIS_CONFIG_PARAMETER. */
+struct rndis_config_parameter_info {
+	u32 ParameterNameOffset;
+	u32 ParameterNameLength;
+	u32 ParameterType;
+	u32 ParameterValueOffset;
+	u32 ParameterValueLength;
+};
+
+/* Values for ParameterType in struct rndis_config_parameter_info */
+#define RNDIS_CONFIG_PARAM_TYPE_INTEGER     0
+#define RNDIS_CONFIG_PARAM_TYPE_STRING      2
+
+/* CONDIS Miniport messages for connection oriented devices */
+/* that do not implement a call manager. */
+
+/* CoNdisMiniportCreateVc message */
+struct rcondis_mp_create_vc {
+	u32 RequestId;
+	u32 NdisVcHandle;
+};
+
+/* Response to CoNdisMiniportCreateVc */
+struct rcondis_mp_create_vc_complete {
+	u32 RequestId;
+	u32 DeviceVcHandle;
+	u32 Status;
+};
+
+/* CoNdisMiniportDeleteVc message */
+struct rcondis_mp_delete_vc {
+	u32 RequestId;
+	u32 DeviceVcHandle;
+};
+
+/* Response to CoNdisMiniportDeleteVc */
+struct rcondis_mp_delete_vc_complete {
+	u32 RequestId;
+	u32 Status;
+};
+
+/* CoNdisMiniportQueryRequest message */
+struct rcondis_mp_query_request {
+	u32 RequestId;
+	u32 RequestType;
+	u32 Oid;
+	u32 DeviceVcHandle;
+	u32 InformationBufferLength;
+	u32 InformationBufferOffset;
+};
+
+/* CoNdisMiniportSetRequest message */
+struct rcondis_mp_set_request {
+	u32 RequestId;
+	u32 RequestType;
+	u32 Oid;
+	u32 DeviceVcHandle;
+	u32 InformationBufferLength;
+	u32 InformationBufferOffset;
+};
+
+/* CoNdisIndicateStatus message */
+struct rcondis_indicate_status {
+	u32 NdisVcHandle;
+	u32 Status;
+	u32 StatusBufferLength;
+	u32 StatusBufferOffset;
+};
+
+/* CONDIS Call/VC parameters */
+struct rcondis_specific_parameters {
+	u32 ParameterType;
+	u32 ParameterLength;
+	u32 ParameterOffset;
+};
+
+struct rcondis_media_parameters {
+	u32 Flags;
+	u32 Reserved1;
+	u32 Reserved2;
+	struct rcondis_specific_parameters MediaSpecific;
+};
+
+struct rndis_flowspec {
+	u32 TokenRate;
+	u32 TokenBucketSize;
+	u32 PeakBandwidth;
+	u32 Latency;
+	u32 DelayVariation;
+	u32 ServiceType;
+	u32 MaxSduSize;
+	u32 MinimumPolicedSize;
+};
+
+struct rcondis_call_manager_parameters {
+	struct rndis_flowspec Transmit;
+	struct rndis_flowspec Receive;
+	struct rcondis_specific_parameters CallMgrSpecific;
+};
+
+/* CoNdisMiniportActivateVc message */
+struct rcondis_mp_activate_vc_request {
+	u32 RequestId;
+	u32 Flags;
+	u32 DeviceVcHandle;
+	u32 MediaParamsOffset;
+	u32 MediaParamsLength;
+	u32 CallMgrParamsOffset;
+	u32 CallMgrParamsLength;
+};
+
+/* Response to CoNdisMiniportActivateVc */
+struct rcondis_mp_activate_vc_complete {
+	u32 RequestId;
+	u32 Status;
+};
+
+/* CoNdisMiniportDeactivateVc message */
+struct rcondis_mp_deactivate_vc_request {
+	u32 RequestId;
+	u32 Flags;
+	u32 DeviceVcHandle;
+};
+
+/* Response to CoNdisMiniportDeactivateVc */
+struct rcondis_mp_deactivate_vc_complete {
+	u32 RequestId;
+	u32 Status;
+};
+
+
+/* union with all of the RNDIS messages */
+union rndis_message_container {
+	struct rndis_packet Packet;
+	struct rndis_initialize_request InitializeRequest;
+	struct rndis_halt_request HaltRequest;
+	struct rndis_query_request QueryRequest;
+	struct rndis_set_request SetRequest;
+	struct rndis_reset_request ResetRequest;
+	struct rndis_keepalive_request KeepaliveRequest;
+	struct rndis_indicate_status IndicateStatus;
+	struct rndis_initialize_complete InitializeComplete;
+	struct rndis_query_complete QueryComplete;
+	struct rndis_set_complete SetComplete;
+	struct rndis_reset_complete ResetComplete;
+	struct rndis_keepalive_complete KeepaliveComplete;
+	struct rcondis_mp_create_vc CoMiniportCreateVc;
+	struct rcondis_mp_delete_vc CoMiniportDeleteVc;
+	struct rcondis_indicate_status CoIndicateStatus;
+	struct rcondis_mp_activate_vc_request CoMiniportActivateVc;
+	struct rcondis_mp_deactivate_vc_request CoMiniportDeactivateVc;
+	struct rcondis_mp_create_vc_complete CoMiniportCreateVcComplete;
+	struct rcondis_mp_delete_vc_complete CoMiniportDeleteVcComplete;
+	struct rcondis_mp_activate_vc_complete CoMiniportActivateVcComplete;
+	struct rcondis_mp_deactivate_vc_complete CoMiniportDeactivateVcComplete;
+};
+
+/* Remote NDIS message format */
+struct rndis_message {
+	u32 NdisMessageType;
+
+	/* Total length of this message, from the beginning */
+	/* of the sruct rndis_message, in bytes. */
+	u32 MessageLength;
+
+	/* Actual message */
+	union rndis_message_container Message;
+};
+
+/* Handy macros */
+
+/* get the size of an RNDIS message. Pass in the message type, */
+/* struct rndis_set_request, struct rndis_packet for example */
+#define RNDIS_MESSAGE_SIZE(Message)				\
+	(sizeof(Message) + (sizeof(struct rndis_message) - 	\
+	 sizeof(union rndis_message_container)))
+
+/* get pointer to info buffer with message pointer */
+#define MESSAGE_TO_INFO_BUFFER(Message)				\
+	(((unsigned char *)(Message)) + Message->InformationBufferOffset)
+
+/* get pointer to status buffer with message pointer */
+#define MESSAGE_TO_STATUS_BUFFER(Message)			\
+	(((unsigned char *)(Message)) + Message->StatusBufferOffset)
+
+/* get pointer to OOBD buffer with message pointer */
+#define MESSAGE_TO_OOBD_BUFFER(Message)				\
+	(((unsigned char *)(Message)) + Message->OOBDataOffset)
+
+/* get pointer to data buffer with message pointer */
+#define MESSAGE_TO_DATA_BUFFER(Message)				\
+	(((unsigned char *)(Message)) + Message->PerPacketInfoOffset)
+
+/* get pointer to contained message from NDIS_MESSAGE pointer */
+#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(RndisMessage)		\
+	((void *) &RndisMessage->Message)
+
+/* get pointer to contained message from NDIS_MESSAGE pointer */
+#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(RndisMessage)	\
+	((void *) RndisMessage)
+
+#endif /* _RNDIS_H_ */
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
new file mode 100644
index 0000000..d49dc21
--- /dev/null
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -0,0 +1,1208 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_devinfo.h>
+#include <scsi/scsi_dbg.h>
+#include "osd.h"
+#include "logging.h"
+#include "vmbus.h"
+#include "StorVscApi.h"
+
+
+struct host_device_context {
+	/* must be 1st field
+	 * FIXME this is a bug */
+	struct work_struct host_rescan_work;
+
+	/* point back to our device context */
+	struct device_context *device_ctx;
+	struct kmem_cache *request_pool;
+	unsigned int port;
+	unsigned char path;
+	unsigned char target;
+};
+
+struct storvsc_cmd_request {
+	struct list_head entry;
+	struct scsi_cmnd *cmd;
+
+	unsigned int bounce_sgl_count;
+	struct scatterlist *bounce_sgl;
+
+	struct hv_storvsc_request request;
+	/* !!!DO NOT ADD ANYTHING BELOW HERE!!! */
+	/* The extension buffer falls right here and is pointed to by
+	 * request.Extension;
+	 * Which sounds like a very bad design... */
+};
+
+struct storvsc_driver_context {
+	/* !! These must be the first 2 fields !! */
+	/* FIXME this is a bug... */
+	struct driver_context drv_ctx;
+	struct storvsc_driver_object drv_obj;
+};
+
+/* Static decl */
+static int storvsc_probe(struct device *dev);
+static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
+				void (*done)(struct scsi_cmnd *));
+static int storvsc_device_alloc(struct scsi_device *);
+static int storvsc_device_configure(struct scsi_device *);
+static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd);
+static void storvsc_host_rescan_callback(struct work_struct *work);
+static void storvsc_host_rescan(struct hv_device *device_obj);
+static int storvsc_remove(struct device *dev);
+
+static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
+						unsigned int sg_count,
+						unsigned int len);
+static void destroy_bounce_buffer(struct scatterlist *sgl,
+				  unsigned int sg_count);
+static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count);
+static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
+					    struct scatterlist *bounce_sgl,
+					    unsigned int orig_sgl_count);
+static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
+					  struct scatterlist *bounce_sgl,
+					  unsigned int orig_sgl_count);
+
+static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
+			       unsigned int *lun_count);
+static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev,
+			   sector_t capacity, int *info);
+
+
+static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
+
+/* The one and only one */
+static struct storvsc_driver_context g_storvsc_drv;
+
+/* Scsi driver */
+static struct scsi_host_template scsi_driver = {
+	.module	=		THIS_MODULE,
+	.name =			"storvsc_host_t",
+	.bios_param =		storvsc_get_chs,
+	.queuecommand =		storvsc_queuecommand,
+	.eh_host_reset_handler =	storvsc_host_reset_handler,
+	.slave_alloc =		storvsc_device_alloc,
+	.slave_configure =	storvsc_device_configure,
+	.cmd_per_lun =		1,
+	/* 64 max_queue * 1 target */
+	.can_queue = 		STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
+	.this_id =		-1,
+	/* no use setting to 0 since ll_blk_rw reset it to 1 */
+	/* currently 32 */
+	.sg_tablesize =		MAX_MULTIPAGE_BUFFER_COUNT,
+	/*
+	 * ENABLE_CLUSTERING allows mutiple physically contig bio_vecs to merge
+	 * into 1 sg element. If set, we must limit the max_segment_size to
+	 * PAGE_SIZE, otherwise we may get 1 sg element that represents
+	 * multiple
+	 */
+	/* physically contig pfns (ie sg[x].length > PAGE_SIZE). */
+	.use_clustering =	ENABLE_CLUSTERING,
+	/* Make sure we dont get a sg segment crosses a page boundary */
+	.dma_boundary =		PAGE_SIZE-1,
+};
+
+
+/**
+ * storvsc_drv_init - StorVsc driver initialization.
+ */
+static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
+{
+	int ret;
+	struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj;
+	struct driver_context *drv_ctx = &g_storvsc_drv.drv_ctx;
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	vmbus_get_interface(&storvsc_drv_obj->Base.VmbusChannelInterface);
+
+	storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size;
+	storvsc_drv_obj->OnHostRescan = storvsc_host_rescan;
+
+	/* Callback to client driver to complete the initialization */
+	drv_init(&storvsc_drv_obj->Base);
+
+	DPRINT_INFO(STORVSC_DRV,
+		    "request extension size %u, max outstanding reqs %u",
+		    storvsc_drv_obj->RequestExtSize,
+		    storvsc_drv_obj->MaxOutstandingRequestsPerChannel);
+
+	if (storvsc_drv_obj->MaxOutstandingRequestsPerChannel <
+	    STORVSC_MAX_IO_REQUESTS) {
+		DPRINT_ERR(STORVSC_DRV,
+			   "The number of outstanding io requests (%d) "
+			   "is larger than that supported (%d) internally.",
+			   STORVSC_MAX_IO_REQUESTS,
+			   storvsc_drv_obj->MaxOutstandingRequestsPerChannel);
+		return -1;
+	}
+
+	drv_ctx->driver.name = storvsc_drv_obj->Base.name;
+	memcpy(&drv_ctx->class_id, &storvsc_drv_obj->Base.deviceType,
+	       sizeof(struct hv_guid));
+
+	drv_ctx->probe = storvsc_probe;
+	drv_ctx->remove = storvsc_remove;
+
+	/* The driver belongs to vmbus */
+	ret = vmbus_child_driver_register(drv_ctx);
+
+	DPRINT_EXIT(STORVSC_DRV);
+
+	return ret;
+}
+
+static int storvsc_drv_exit_cb(struct device *dev, void *data)
+{
+	struct device **curr = (struct device **)data;
+	*curr = dev;
+	return 1; /* stop iterating */
+}
+
+static void storvsc_drv_exit(void)
+{
+	struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj;
+	struct driver_context *drv_ctx = &g_storvsc_drv.drv_ctx;
+	struct device *current_dev = NULL;
+	int ret;
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	while (1) {
+		current_dev = NULL;
+
+		/* Get the device */
+		ret = driver_for_each_device(&drv_ctx->driver, NULL,
+					     (void *) &current_dev,
+					     storvsc_drv_exit_cb);
+
+		if (ret)
+			DPRINT_WARN(STORVSC_DRV,
+				    "driver_for_each_device returned %d", ret);
+
+		if (current_dev == NULL)
+			break;
+
+		/* Initiate removal from the top-down */
+		device_unregister(current_dev);
+	}
+
+	if (storvsc_drv_obj->Base.OnCleanup)
+		storvsc_drv_obj->Base.OnCleanup(&storvsc_drv_obj->Base);
+
+	vmbus_child_driver_unregister(drv_ctx);
+
+	DPRINT_EXIT(STORVSC_DRV);
+
+	return;
+}
+
+/**
+ * storvsc_probe - Add a new device for this driver
+ */
+static int storvsc_probe(struct device *device)
+{
+	int ret;
+	struct driver_context *driver_ctx =
+				driver_to_driver_context(device->driver);
+	struct storvsc_driver_context *storvsc_drv_ctx =
+				(struct storvsc_driver_context *)driver_ctx;
+	struct storvsc_driver_object *storvsc_drv_obj =
+				&storvsc_drv_ctx->drv_obj;
+	struct device_context *device_ctx = device_to_device_context(device);
+	struct hv_device *device_obj = &device_ctx->device_obj;
+	struct Scsi_Host *host;
+	struct host_device_context *host_device_ctx;
+	struct storvsc_device_info device_info;
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	if (!storvsc_drv_obj->Base.OnDeviceAdd)
+		return -1;
+
+	host = scsi_host_alloc(&scsi_driver,
+			       sizeof(struct host_device_context));
+	if (!host) {
+		DPRINT_ERR(STORVSC_DRV, "unable to allocate scsi host object");
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(device, host);
+
+	host_device_ctx = (struct host_device_context *)host->hostdata;
+	memset(host_device_ctx, 0, sizeof(struct host_device_context));
+
+	host_device_ctx->port = host->host_no;
+	host_device_ctx->device_ctx = device_ctx;
+
+	INIT_WORK(&host_device_ctx->host_rescan_work,
+		  storvsc_host_rescan_callback);
+
+	host_device_ctx->request_pool =
+				kmem_cache_create(dev_name(&device_ctx->device),
+					sizeof(struct storvsc_cmd_request) +
+					storvsc_drv_obj->RequestExtSize, 0,
+					SLAB_HWCACHE_ALIGN, NULL);
+
+	if (!host_device_ctx->request_pool) {
+		scsi_host_put(host);
+		DPRINT_EXIT(STORVSC_DRV);
+
+		return -ENOMEM;
+	}
+
+	device_info.PortNumber = host->host_no;
+	/* Call to the vsc driver to add the device */
+	ret = storvsc_drv_obj->Base.OnDeviceAdd(device_obj,
+						(void *)&device_info);
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC_DRV, "unable to add scsi vsc device");
+		kmem_cache_destroy(host_device_ctx->request_pool);
+		scsi_host_put(host);
+		DPRINT_EXIT(STORVSC_DRV);
+
+		return -1;
+	}
+
+	/* host_device_ctx->port = device_info.PortNumber; */
+	host_device_ctx->path = device_info.PathId;
+	host_device_ctx->target = device_info.TargetId;
+
+	/* max # of devices per target */
+	host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
+	/* max # of targets per channel */
+	host->max_id = STORVSC_MAX_TARGETS;
+	/* max # of channels */
+	host->max_channel = STORVSC_MAX_CHANNELS - 1;
+
+	/* Register the HBA and start the scsi bus scan */
+	ret = scsi_add_host(host, device);
+	if (ret != 0) {
+		DPRINT_ERR(STORVSC_DRV, "unable to add scsi host device");
+
+		storvsc_drv_obj->Base.OnDeviceRemove(device_obj);
+
+		kmem_cache_destroy(host_device_ctx->request_pool);
+		scsi_host_put(host);
+		DPRINT_EXIT(STORVSC_DRV);
+
+		return -1;
+	}
+
+	scsi_scan_host(host);
+
+	DPRINT_EXIT(STORVSC_DRV);
+
+	return ret;
+}
+
+/**
+ * storvsc_remove - Callback when our device is removed
+ */
+static int storvsc_remove(struct device *device)
+{
+	int ret;
+	struct driver_context *driver_ctx =
+			driver_to_driver_context(device->driver);
+	struct storvsc_driver_context *storvsc_drv_ctx =
+			(struct storvsc_driver_context *)driver_ctx;
+	struct storvsc_driver_object *storvsc_drv_obj =
+			&storvsc_drv_ctx->drv_obj;
+	struct device_context *device_ctx = device_to_device_context(device);
+	struct hv_device *device_obj = &device_ctx->device_obj;
+	struct Scsi_Host *host = dev_get_drvdata(device);
+	struct host_device_context *host_device_ctx =
+			(struct host_device_context *)host->hostdata;
+
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	if (!storvsc_drv_obj->Base.OnDeviceRemove) {
+		DPRINT_EXIT(STORVSC_DRV);
+		return -1;
+	}
+
+	/*
+	 * Call to the vsc driver to let it know that the device is being
+	 * removed
+	 */
+	ret = storvsc_drv_obj->Base.OnDeviceRemove(device_obj);
+	if (ret != 0) {
+		/* TODO: */
+		DPRINT_ERR(STORVSC, "unable to remove vsc device (ret %d)",
+			   ret);
+	}
+
+	if (host_device_ctx->request_pool) {
+		kmem_cache_destroy(host_device_ctx->request_pool);
+		host_device_ctx->request_pool = NULL;
+	}
+
+	DPRINT_INFO(STORVSC, "removing host adapter (%p)...", host);
+	scsi_remove_host(host);
+
+	DPRINT_INFO(STORVSC, "releasing host adapter (%p)...", host);
+	scsi_host_put(host);
+
+	DPRINT_EXIT(STORVSC_DRV);
+
+	return ret;
+}
+
+/**
+ * storvsc_commmand_completion - Command completion processing
+ */
+static void storvsc_commmand_completion(struct hv_storvsc_request *request)
+{
+	struct storvsc_cmd_request *cmd_request =
+		(struct storvsc_cmd_request *)request->Context;
+	struct scsi_cmnd *scmnd = cmd_request->cmd;
+	struct host_device_context *host_device_ctx =
+		(struct host_device_context *)scmnd->device->host->hostdata;
+	void (*scsi_done_fn)(struct scsi_cmnd *);
+	struct scsi_sense_hdr sense_hdr;
+
+	ASSERT(request == &cmd_request->request);
+	ASSERT((unsigned long)scmnd->host_scribble ==
+		(unsigned long)cmd_request);
+	ASSERT(scmnd);
+	ASSERT(scmnd->scsi_done);
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	if (cmd_request->bounce_sgl_count) {
+		/* using bounce buffer */
+		/* printk("copy_from_bounce_buffer\n"); */
+
+		/* FIXME: We can optimize on writes by just skipping this */
+		copy_from_bounce_buffer(scsi_sglist(scmnd),
+					cmd_request->bounce_sgl,
+					scsi_sg_count(scmnd));
+		destroy_bounce_buffer(cmd_request->bounce_sgl,
+				      cmd_request->bounce_sgl_count);
+	}
+
+	scmnd->result = request->Status;
+
+	if (scmnd->result) {
+		if (scsi_normalize_sense(scmnd->sense_buffer,
+					 request->SenseBufferSize, &sense_hdr))
+			scsi_print_sense_hdr("storvsc", &sense_hdr);
+	}
+
+	ASSERT(request->BytesXfer <= request->DataBuffer.Length);
+	scsi_set_resid(scmnd, request->DataBuffer.Length - request->BytesXfer);
+
+	scsi_done_fn = scmnd->scsi_done;
+
+	scmnd->host_scribble = NULL;
+	scmnd->scsi_done = NULL;
+
+	/* !!DO NOT MODIFY the scmnd after this call */
+	scsi_done_fn(scmnd);
+
+	kmem_cache_free(host_device_ctx->request_pool, cmd_request);
+
+	DPRINT_EXIT(STORVSC_DRV);
+}
+
+static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
+{
+	int i;
+
+	/* No need to check */
+	if (sg_count < 2)
+		return -1;
+
+	/* We have at least 2 sg entries */
+	for (i = 0; i < sg_count; i++) {
+		if (i == 0) {
+			/* make sure 1st one does not have hole */
+			if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
+				return i;
+		} else if (i == sg_count - 1) {
+			/* make sure last one does not have hole */
+			if (sgl[i].offset != 0)
+				return i;
+		} else {
+			/* make sure no hole in the middle */
+			if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
+				return i;
+		}
+	}
+	return -1;
+}
+
+static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
+						unsigned int sg_count,
+						unsigned int len)
+{
+	int i;
+	int num_pages;
+	struct scatterlist *bounce_sgl;
+	struct page *page_buf;
+
+	num_pages = ALIGN_UP(len, PAGE_SIZE) >> PAGE_SHIFT;
+
+	bounce_sgl = kcalloc(num_pages, sizeof(struct scatterlist), GFP_ATOMIC);
+	if (!bounce_sgl)
+		return NULL;
+
+	for (i = 0; i < num_pages; i++) {
+		page_buf = alloc_page(GFP_ATOMIC);
+		if (!page_buf)
+			goto cleanup;
+		sg_set_page(&bounce_sgl[i], page_buf, 0, 0);
+	}
+
+	return bounce_sgl;
+
+cleanup:
+	destroy_bounce_buffer(bounce_sgl, num_pages);
+	return NULL;
+}
+
+static void destroy_bounce_buffer(struct scatterlist *sgl,
+				  unsigned int sg_count)
+{
+	int i;
+	struct page *page_buf;
+
+	for (i = 0; i < sg_count; i++) {
+		page_buf = sg_page((&sgl[i]));
+		if (page_buf != NULL)
+			__free_page(page_buf);
+	}
+
+	kfree(sgl);
+}
+
+/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
+static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
+					  struct scatterlist *bounce_sgl,
+					  unsigned int orig_sgl_count)
+{
+	int i;
+	int j = 0;
+	unsigned long src, dest;
+	unsigned int srclen, destlen, copylen;
+	unsigned int total_copied = 0;
+	unsigned long bounce_addr = 0;
+	unsigned long src_addr = 0;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	for (i = 0; i < orig_sgl_count; i++) {
+		src_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
+				KM_IRQ0) + orig_sgl[i].offset;
+		src = src_addr;
+		srclen = orig_sgl[i].length;
+
+		ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE);
+
+		if (j == 0)
+			bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+
+		while (srclen) {
+			/* assume bounce offset always == 0 */
+			dest = bounce_addr + bounce_sgl[j].length;
+			destlen = PAGE_SIZE - bounce_sgl[j].length;
+
+			copylen = min(srclen, destlen);
+			memcpy((void *)dest, (void *)src, copylen);
+
+			total_copied += copylen;
+			bounce_sgl[j].length += copylen;
+			srclen -= copylen;
+			src += copylen;
+
+			if (bounce_sgl[j].length == PAGE_SIZE) {
+				/* full..move to next entry */
+				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
+				j++;
+
+				/* if we need to use another bounce buffer */
+				if (srclen || i != orig_sgl_count - 1)
+					bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+			} else if (srclen == 0 && i == orig_sgl_count - 1) {
+				/* unmap the last bounce that is < PAGE_SIZE */
+				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
+			}
+		}
+
+		kunmap_atomic((void *)(src_addr - orig_sgl[i].offset), KM_IRQ0);
+	}
+
+	local_irq_restore(flags);
+
+	return total_copied;
+}
+
+/* Assume the original sgl has enough room */
+static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
+					    struct scatterlist *bounce_sgl,
+					    unsigned int orig_sgl_count)
+{
+	int i;
+	int j = 0;
+	unsigned long src, dest;
+	unsigned int srclen, destlen, copylen;
+	unsigned int total_copied = 0;
+	unsigned long bounce_addr = 0;
+	unsigned long dest_addr = 0;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	for (i = 0; i < orig_sgl_count; i++) {
+		dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
+					KM_IRQ0) + orig_sgl[i].offset;
+		dest = dest_addr;
+		destlen = orig_sgl[i].length;
+		ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE);
+
+		if (j == 0)
+			bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+
+		while (destlen) {
+			src = bounce_addr + bounce_sgl[j].offset;
+			srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+
+			copylen = min(srclen, destlen);
+			memcpy((void *)dest, (void *)src, copylen);
+
+			total_copied += copylen;
+			bounce_sgl[j].offset += copylen;
+			destlen -= copylen;
+			dest += copylen;
+
+			if (bounce_sgl[j].offset == bounce_sgl[j].length) {
+				/* full */
+				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
+				j++;
+
+				/* if we need to use another bounce buffer */
+				if (destlen || i != orig_sgl_count - 1)
+					bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+			} else if (destlen == 0 && i == orig_sgl_count - 1) {
+				/* unmap the last bounce that is < PAGE_SIZE */
+				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
+			}
+		}
+
+		kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset),
+			      KM_IRQ0);
+	}
+
+	local_irq_restore(flags);
+
+	return total_copied;
+}
+
+/**
+ * storvsc_queuecommand - Initiate command processing
+ */
+static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
+				void (*done)(struct scsi_cmnd *))
+{
+	int ret;
+	struct host_device_context *host_device_ctx =
+		(struct host_device_context *)scmnd->device->host->hostdata;
+	struct device_context *device_ctx = host_device_ctx->device_ctx;
+	struct driver_context *driver_ctx =
+		driver_to_driver_context(device_ctx->device.driver);
+	struct storvsc_driver_context *storvsc_drv_ctx =
+		(struct storvsc_driver_context *)driver_ctx;
+	struct storvsc_driver_object *storvsc_drv_obj =
+		&storvsc_drv_ctx->drv_obj;
+	struct hv_storvsc_request *request;
+	struct storvsc_cmd_request *cmd_request;
+	unsigned int request_size = 0;
+	int i;
+	struct scatterlist *sgl;
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d "
+		   "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction,
+		   scsi_sg_count(scmnd), scsi_sglist(scmnd),
+		   scsi_bufflen(scmnd), scmnd->device->queue_depth,
+		   scmnd->device->tagged_supported);
+
+	/* If retrying, no need to prep the cmd */
+	if (scmnd->host_scribble) {
+		ASSERT(scmnd->scsi_done != NULL);
+
+		cmd_request =
+			(struct storvsc_cmd_request *)scmnd->host_scribble;
+		DPRINT_INFO(STORVSC_DRV, "retrying scmnd %p cmd_request %p",
+			    scmnd, cmd_request);
+
+		goto retry_request;
+	}
+
+	ASSERT(scmnd->scsi_done == NULL);
+	ASSERT(scmnd->host_scribble == NULL);
+
+	scmnd->scsi_done = done;
+
+	request_size = sizeof(struct storvsc_cmd_request);
+
+	cmd_request = kmem_cache_alloc(host_device_ctx->request_pool,
+				       GFP_ATOMIC);
+	if (!cmd_request) {
+		DPRINT_ERR(STORVSC_DRV, "scmnd (%p) - unable to allocate "
+			   "storvsc_cmd_request...marking queue busy", scmnd);
+		scmnd->scsi_done = NULL;
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+	}
+
+	/* Setup the cmd request */
+	cmd_request->bounce_sgl_count = 0;
+	cmd_request->bounce_sgl = NULL;
+	cmd_request->cmd = scmnd;
+
+	scmnd->host_scribble = (unsigned char *)cmd_request;
+
+	request = &cmd_request->request;
+
+	request->Extension =
+		(void *)((unsigned long)cmd_request + request_size);
+	DPRINT_DBG(STORVSC_DRV, "req %p size %d ext %d", request, request_size,
+		   storvsc_drv_obj->RequestExtSize);
+
+	/* Build the SRB */
+	switch (scmnd->sc_data_direction) {
+	case DMA_TO_DEVICE:
+		request->Type = WRITE_TYPE;
+		break;
+	case DMA_FROM_DEVICE:
+		request->Type = READ_TYPE;
+		break;
+	default:
+		request->Type = UNKNOWN_TYPE;
+		break;
+	}
+
+	request->OnIOCompletion = storvsc_commmand_completion;
+	request->Context = cmd_request;/* scmnd; */
+
+	/* request->PortId = scmnd->device->channel; */
+	request->Host = host_device_ctx->port;
+	request->Bus = scmnd->device->channel;
+	request->TargetId = scmnd->device->id;
+	request->LunId = scmnd->device->lun;
+
+	ASSERT(scmnd->cmd_len <= 16);
+	request->CdbLen = scmnd->cmd_len;
+	request->Cdb = scmnd->cmnd;
+
+	request->SenseBuffer = scmnd->sense_buffer;
+	request->SenseBufferSize = SCSI_SENSE_BUFFERSIZE;
+
+
+	request->DataBuffer.Length = scsi_bufflen(scmnd);
+	if (scsi_sg_count(scmnd)) {
+		sgl = (struct scatterlist *)scsi_sglist(scmnd);
+
+		/* check if we need to bounce the sgl */
+		if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
+			DPRINT_INFO(STORVSC_DRV,
+				    "need to bounce buffer for this scmnd %p",
+				    scmnd);
+			cmd_request->bounce_sgl =
+				create_bounce_buffer(sgl, scsi_sg_count(scmnd),
+						     scsi_bufflen(scmnd));
+			if (!cmd_request->bounce_sgl) {
+				DPRINT_ERR(STORVSC_DRV,
+					   "unable to create bounce buffer for "
+					   "this scmnd %p", scmnd);
+
+				scmnd->scsi_done = NULL;
+				scmnd->host_scribble = NULL;
+				kmem_cache_free(host_device_ctx->request_pool,
+						cmd_request);
+
+				return SCSI_MLQUEUE_HOST_BUSY;
+			}
+
+			cmd_request->bounce_sgl_count =
+				ALIGN_UP(scsi_bufflen(scmnd), PAGE_SIZE) >>
+					PAGE_SHIFT;
+
+			/*
+			 * FIXME: We can optimize on reads by just skipping
+			 * this
+			 */
+			copy_to_bounce_buffer(sgl, cmd_request->bounce_sgl,
+					      scsi_sg_count(scmnd));
+
+			sgl = cmd_request->bounce_sgl;
+		}
+
+		request->DataBuffer.Offset = sgl[0].offset;
+
+		for (i = 0; i < scsi_sg_count(scmnd); i++) {
+			DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d \n",
+				   i, sgl[i].length, sgl[i].offset);
+			request->DataBuffer.PfnArray[i] =
+					page_to_pfn(sg_page((&sgl[i])));
+		}
+	} else if (scsi_sglist(scmnd)) {
+		ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE);
+		request->DataBuffer.Offset =
+			virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
+		request->DataBuffer.PfnArray[0] =
+			virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
+	} else {
+		ASSERT(scsi_bufflen(scmnd) == 0);
+	}
+
+retry_request:
+	/* Invokes the vsc to start an IO */
+	ret = storvsc_drv_obj->OnIORequest(&device_ctx->device_obj,
+					   &cmd_request->request);
+	if (ret == -1) {
+		/* no more space */
+		DPRINT_ERR(STORVSC_DRV,
+			   "scmnd (%p) - queue FULL...marking queue busy",
+			   scmnd);
+
+		if (cmd_request->bounce_sgl_count) {
+			/*
+			 * FIXME: We can optimize on writes by just skipping
+			 * this
+			 */
+			copy_from_bounce_buffer(scsi_sglist(scmnd),
+						cmd_request->bounce_sgl,
+						scsi_sg_count(scmnd));
+			destroy_bounce_buffer(cmd_request->bounce_sgl,
+					      cmd_request->bounce_sgl_count);
+		}
+
+		kmem_cache_free(host_device_ctx->request_pool, cmd_request);
+
+		scmnd->scsi_done = NULL;
+		scmnd->host_scribble = NULL;
+
+		ret = SCSI_MLQUEUE_DEVICE_BUSY;
+	}
+
+	DPRINT_EXIT(STORVSC_DRV);
+
+	return ret;
+}
+
+static int storvsc_merge_bvec(struct request_queue *q,
+			      struct bvec_merge_data *bmd, struct bio_vec *bvec)
+{
+	/* checking done by caller. */
+	return bvec->bv_len;
+}
+
+/**
+ * storvsc_device_configure - Configure the specified scsi device
+ */
+static int storvsc_device_alloc(struct scsi_device *sdevice)
+{
+	DPRINT_DBG(STORVSC_DRV, "sdev (%p) - setting device flag to %d",
+		   sdevice, BLIST_SPARSELUN);
+	/*
+	 * This enables luns to be located sparsely. Otherwise, we may not
+	 * discovered them.
+	 */
+	sdevice->sdev_bflags |= BLIST_SPARSELUN | BLIST_LARGELUN;
+	return 0;
+}
+
+static int storvsc_device_configure(struct scsi_device *sdevice)
+{
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - curr queue depth %d", sdevice,
+		    sdevice->queue_depth);
+
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - setting queue depth to %d",
+		    sdevice, STORVSC_MAX_IO_REQUESTS);
+	scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG,
+				STORVSC_MAX_IO_REQUESTS);
+
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - setting max segment size to %ld",
+		    sdevice, PAGE_SIZE);
+	blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
+
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - adding merge bio vec routine",
+		    sdevice);
+	blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec);
+
+	blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
+	/* sdevice->timeout = (2000 * HZ);//(75 * HZ); */
+
+	return 0;
+}
+
+/**
+ * storvsc_host_reset_handler - Reset the scsi HBA
+ */
+static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
+{
+	int ret;
+	struct host_device_context *host_device_ctx =
+		(struct host_device_context *)scmnd->device->host->hostdata;
+	struct device_context *device_ctx = host_device_ctx->device_ctx;
+	struct driver_context *driver_ctx =
+			driver_to_driver_context(device_ctx->device.driver);
+	struct storvsc_driver_context *storvsc_drv_ctx =
+			(struct storvsc_driver_context *)driver_ctx;
+
+	struct storvsc_driver_object *storvsc_drv_obj =
+			&storvsc_drv_ctx->drv_obj;
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host resetting...",
+		    scmnd->device, &device_ctx->device_obj);
+
+	/* Invokes the vsc to reset the host/bus */
+	ASSERT(storvsc_drv_obj->OnHostReset);
+	ret = storvsc_drv_obj->OnHostReset(&device_ctx->device_obj);
+	if (ret != 0) {
+		DPRINT_EXIT(STORVSC_DRV);
+		return ret;
+	}
+
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host reseted",
+		    scmnd->device, &device_ctx->device_obj);
+
+	DPRINT_EXIT(STORVSC_DRV);
+
+	return ret;
+}
+
+/**
+ * storvsc_host_rescan - Rescan the scsi HBA
+ */
+static void storvsc_host_rescan_callback(struct work_struct *work)
+{
+	struct hv_device *device_obj =
+	    &((struct host_device_context *)work)->device_ctx->device_obj;
+	struct device_context *device_ctx = to_device_context(device_obj);
+	struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
+	struct scsi_device *sdev;
+	struct host_device_context *host_device_ctx;
+	struct scsi_device **sdevs_remove_list;
+	unsigned int sdevs_count = 0;
+	unsigned int found;
+	unsigned int i;
+	unsigned int lun_count = 0;
+	unsigned int *lun_list;
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	host_device_ctx = (struct host_device_context *)host->hostdata;
+	lun_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET, sizeof(unsigned int),
+			   GFP_ATOMIC);
+	if (!lun_list) {
+		DPRINT_ERR(STORVSC_DRV, "unable to allocate lun list");
+		return;
+	}
+
+	sdevs_remove_list = kcalloc(STORVSC_MAX_LUNS_PER_TARGET,
+				    sizeof(void *), GFP_ATOMIC);
+	if (!sdevs_remove_list) {
+		kfree(lun_list);
+		DPRINT_ERR(STORVSC_DRV, "unable to allocate lun remove list");
+		return;
+	}
+
+	DPRINT_INFO(STORVSC_DRV, "rescanning host for new scsi devices...");
+
+	/* Rescan for new device */
+	scsi_scan_target(&host->shost_gendev, host_device_ctx->path,
+			 host_device_ctx->target, SCAN_WILD_CARD, 1);
+
+	DPRINT_INFO(STORVSC_DRV, "rescanning host for removed scsi device...");
+
+	/* Use the 1st device to send the report luns cmd */
+	shost_for_each_device(sdev, host) {
+		lun_count = STORVSC_MAX_LUNS_PER_TARGET;
+		storvsc_report_luns(sdev, lun_list, &lun_count);
+
+		DPRINT_INFO(STORVSC_DRV,
+			    "report luns on scsi device (%p) found %u luns ",
+			    sdev, lun_count);
+		DPRINT_INFO(STORVSC_DRV,
+			    "existing luns on scsi device (%p) host (%d)",
+			    sdev, host->host_no);
+
+		scsi_device_put(sdev);
+		break;
+	}
+
+	for (i = 0; i < lun_count; i++)
+		DPRINT_INFO(STORVSC_DRV, "%d) lun %u", i, lun_list[i]);
+
+	/* Rescan for devices that may have been removed.
+	 * We do not have to worry that new devices may have been added since
+	 * this callback is serialized by the workqueue ie add/remove are done
+	 * here.
+	 */
+	shost_for_each_device(sdev, host) {
+		/* See if this device is still here */
+		found = 0;
+		for (i = 0; i < lun_count; i++) {
+			if (sdev->lun == lun_list[i]) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found) {
+			DPRINT_INFO(STORVSC_DRV, "lun (%u) does not exists",
+				    sdev->lun);
+			sdevs_remove_list[sdevs_count++] = sdev;
+		}
+	}
+
+	/* Now remove the devices */
+	for (i = 0; i < sdevs_count; i++) {
+		DPRINT_INFO(STORVSC_DRV,
+			    "removing scsi device (%p) lun (%u)...",
+			    sdevs_remove_list[i], sdevs_remove_list[i]->lun);
+
+		/* make sure it is not removed from underneath us */
+		if (!scsi_device_get(sdevs_remove_list[i])) {
+			scsi_remove_device(sdevs_remove_list[i]);
+			scsi_device_put(sdevs_remove_list[i]);
+		}
+	}
+
+	DPRINT_INFO(STORVSC_DRV, "rescan completed on dev obj (%p) "
+		    "target (%u) bus (%u)", device_obj,
+		    host_device_ctx->target, host_device_ctx->path);
+
+	kfree(lun_list);
+	kfree(sdevs_remove_list);
+
+	DPRINT_EXIT(STORVSC_DRV);
+}
+
+static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[],
+			       unsigned int *lun_count)
+{
+	int i, j;
+	unsigned int lun = 0;
+	unsigned int num_luns;
+	int result;
+	unsigned char *data;
+	struct scsi_sense_hdr sshdr;
+	unsigned char cmd[16] = {0};
+	/* Add 1 to cover the report_lun header */
+	unsigned int report_len = 8 * (STORVSC_MAX_LUNS_PER_TARGET+1);
+	unsigned long long *report_luns;
+	const unsigned int in_lun_count = *lun_count;
+
+	*lun_count = 0;
+
+	report_luns = kzalloc(report_len, GFP_ATOMIC);
+	if (!report_luns)
+		return -ENOMEM;
+
+	cmd[0] = REPORT_LUNS;
+
+	/* cmd length */
+	*(unsigned int *)&cmd[6] = cpu_to_be32(report_len);
+
+	result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE,
+				  (unsigned char *)report_luns, report_len,
+				  &sshdr, 30 * HZ, 3, NULL);
+	if (result != 0) {
+		kfree(report_luns);
+		return -EBUSY;
+	}
+
+	/* get the length from the first four bytes */
+	report_len = be32_to_cpu(*(unsigned int *)&report_luns[0]);
+
+	num_luns = (report_len / sizeof(unsigned long long));
+	if (num_luns > in_lun_count) {
+		kfree(report_luns);
+		return -EINVAL;
+	}
+
+	*lun_count = num_luns;
+
+	DPRINT_DBG(STORVSC_DRV,
+		   "report luns on scsi device (%p) found %u luns ",
+		   sdev, num_luns);
+
+	/* lun id starts at 1 */
+	for (i = 1; i < num_luns + 1; i++) {
+		lun = 0;
+		data = (unsigned char *)&report_luns[i];
+		for (j = 0; j < sizeof(lun); j += 2) {
+			lun = lun | (((data[j] << 8) | data[j + 1]) <<
+				(j * 8));
+		}
+
+		luns[i-1] = lun;
+	}
+
+	kfree(report_luns);
+	return 0;
+}
+
+static void storvsc_host_rescan(struct hv_device *device_obj)
+{
+	struct device_context *device_ctx = to_device_context(device_obj);
+	struct Scsi_Host *host = dev_get_drvdata(&device_ctx->device);
+	struct host_device_context *host_device_ctx;
+
+	DPRINT_ENTER(STORVSC_DRV);
+
+	host_device_ctx = (struct host_device_context *)host->hostdata;
+
+	DPRINT_INFO(STORVSC_DRV, "initiating rescan on dev obj (%p) "
+		    "target (%u) bus (%u)...", device_obj,
+		    host_device_ctx->target, host_device_ctx->path);
+
+	/*
+	 * We need to queue this since the scanning may block and the caller
+	 * may be in an intr context
+	 */
+	/* scsi_queue_work(host, &host_device_ctx->host_rescan_work); */
+	schedule_work(&host_device_ctx->host_rescan_work);
+	DPRINT_EXIT(STORVSC_DRV);
+}
+
+static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
+			   sector_t capacity, int *info)
+{
+	sector_t total_sectors = capacity;
+	sector_t cylinder_times_heads = 0;
+	sector_t temp = 0;
+
+	int sectors_per_track = 0;
+	int heads = 0;
+	int cylinders = 0;
+	int rem = 0;
+
+	if (total_sectors > (65535 * 16 * 255))
+		total_sectors = (65535 * 16 * 255);
+
+	if (total_sectors >= (65535 * 16 * 63)) {
+		sectors_per_track = 255;
+		heads = 16;
+
+		cylinder_times_heads = total_sectors;
+		/* sector_div stores the quotient in cylinder_times_heads */
+		rem = sector_div(cylinder_times_heads, sectors_per_track);
+	} else {
+		sectors_per_track = 17;
+
+		cylinder_times_heads = total_sectors;
+		/* sector_div stores the quotient in cylinder_times_heads */
+		rem = sector_div(cylinder_times_heads, sectors_per_track);
+
+		temp = cylinder_times_heads + 1023;
+		/* sector_div stores the quotient in temp */
+		rem = sector_div(temp, 1024);
+
+		heads = temp;
+
+		if (heads < 4)
+			heads = 4;
+
+		if (cylinder_times_heads >= (heads * 1024) || (heads > 16)) {
+			sectors_per_track = 31;
+			heads = 16;
+
+			cylinder_times_heads = total_sectors;
+			/*
+			 * sector_div stores the quotient in
+			 * cylinder_times_heads
+			 */
+			rem = sector_div(cylinder_times_heads,
+					 sectors_per_track);
+		}
+
+		if (cylinder_times_heads >= (heads * 1024)) {
+			sectors_per_track = 63;
+			heads = 16;
+
+			cylinder_times_heads = total_sectors;
+			/*
+			 * sector_div stores the quotient in
+			 * cylinder_times_heads
+			 */
+			rem = sector_div(cylinder_times_heads,
+					 sectors_per_track);
+		}
+	}
+
+	temp = cylinder_times_heads;
+	/* sector_div stores the quotient in temp */
+	rem = sector_div(temp, heads);
+	cylinders = temp;
+
+	info[0] = heads;
+	info[1] = sectors_per_track;
+	info[2] = cylinders;
+
+	DPRINT_INFO(STORVSC_DRV, "CHS (%d, %d, %d)", cylinders, heads,
+		    sectors_per_track);
+
+    return 0;
+}
+
+static int __init storvsc_init(void)
+{
+	int ret;
+
+	DPRINT_ENTER(STORVSC_DRV);
+	DPRINT_INFO(STORVSC_DRV, "Storvsc initializing....");
+	ret = storvsc_drv_init(StorVscInitialize);
+	DPRINT_EXIT(STORVSC_DRV);
+	return ret;
+}
+
+static void __exit storvsc_exit(void)
+{
+	DPRINT_ENTER(STORVSC_DRV);
+	storvsc_drv_exit();
+	DPRINT_ENTER(STORVSC_DRV);
+}
+
+MODULE_LICENSE("GPL");
+module_param(storvsc_ringbuffer_size, int, S_IRUGO);
+module_init(storvsc_init);
+module_exit(storvsc_exit);
diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h
new file mode 100644
index 0000000..ae0a896
--- /dev/null
+++ b/drivers/staging/hv/vmbus.h
@@ -0,0 +1,77 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+
+#ifndef _VMBUS_H_
+#define _VMBUS_H_
+
+#include <linux/device.h>
+#include "VmbusApi.h"
+
+struct driver_context {
+	struct hv_guid class_id;
+
+	struct device_driver driver;
+
+	/*
+	 * Use these methods instead of the struct device_driver so 2.6 kernel
+	 * stops complaining
+	 * TODO - fix this!
+	 */
+	int (*probe)(struct device *);
+	int (*remove)(struct device *);
+	void (*shutdown)(struct device *);
+};
+
+struct device_context {
+	struct work_struct probe_failed_work_item;
+	struct hv_guid class_id;
+	struct hv_guid device_id;
+	int probe_error;
+	struct device device;
+	struct hv_device device_obj;
+};
+
+static inline struct device_context *to_device_context(struct hv_device *d)
+{
+	return container_of(d, struct device_context, device_obj);
+}
+
+static inline struct device_context *device_to_device_context(struct device *d)
+{
+	return container_of(d, struct device_context, device);
+}
+
+static inline struct driver_context *driver_to_driver_context(struct device_driver *d)
+{
+	return container_of(d, struct driver_context, driver);
+}
+
+
+/* Vmbus interface */
+
+int vmbus_child_driver_register(struct driver_context *driver_ctx);
+void vmbus_child_driver_unregister(struct driver_context *driver_ctx);
+void vmbus_get_interface(struct vmbus_channel_interface *interface);
+
+#endif /* _VMBUS_H_ */
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
new file mode 100644
index 0000000..582318f
--- /dev/null
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -0,0 +1,999 @@
+/*
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include "osd.h"
+#include "logging.h"
+#include "vmbus.h"
+
+
+/* FIXME! We need to do this dynamically for PIC and APIC system */
+#define VMBUS_IRQ		0x5
+#define VMBUS_IRQ_VECTOR	IRQ5_VECTOR
+
+/* Main vmbus driver data structure */
+struct vmbus_driver_context {
+	/* !! These must be the first 2 fields !! */
+	/* FIXME, this is a bug */
+	/* The driver field is not used in here. Instead, the bus field is */
+	/* used to represent the driver */
+	struct driver_context drv_ctx;
+	struct vmbus_driver drv_obj;
+
+	struct bus_type bus;
+	struct tasklet_struct msg_dpc;
+	struct tasklet_struct event_dpc;
+
+	/* The bus root device */
+	struct device_context device_ctx;
+};
+
+static int vmbus_match(struct device *device, struct device_driver *driver);
+static int vmbus_probe(struct device *device);
+static int vmbus_remove(struct device *device);
+static void vmbus_shutdown(struct device *device);
+static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env);
+static void vmbus_msg_dpc(unsigned long data);
+static void vmbus_event_dpc(unsigned long data);
+
+static irqreturn_t vmbus_isr(int irq, void *dev_id);
+
+static void vmbus_device_release(struct device *device);
+static void vmbus_bus_release(struct device *device);
+
+static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
+						   struct hv_guid *instance,
+						   void *context);
+static void vmbus_child_device_destroy(struct hv_device *device_obj);
+static int vmbus_child_device_register(struct hv_device *root_device_obj,
+				       struct hv_device *child_device_obj);
+static void vmbus_child_device_unregister(struct hv_device *child_device_obj);
+static void vmbus_child_device_get_info(struct hv_device *device_obj,
+					struct hv_device_info *device_info);
+static ssize_t vmbus_show_device_attr(struct device *dev,
+				      struct device_attribute *dev_attr,
+				      char *buf);
+
+
+unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
+EXPORT_SYMBOL(vmbus_loglevel);
+	/* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
+	/* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
+
+static int vmbus_irq = VMBUS_IRQ;
+
+/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
+static struct device_attribute vmbus_device_attrs[] = {
+	__ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(class_id, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(device_id, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(monitor_id, S_IRUGO, vmbus_show_device_attr, NULL),
+
+	__ATTR(server_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(server_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(server_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
+
+	__ATTR(client_monitor_pending, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(client_monitor_latency, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(client_monitor_conn_id, S_IRUGO, vmbus_show_device_attr, NULL),
+
+	__ATTR(out_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(out_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(out_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(out_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(out_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
+
+	__ATTR(in_intr_mask, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(in_read_index, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(in_write_index, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(in_read_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR(in_write_bytes_avail, S_IRUGO, vmbus_show_device_attr, NULL),
+	__ATTR_NULL
+};
+
+/* The one and only one */
+static struct vmbus_driver_context g_vmbus_drv = {
+	.bus.name =		"vmbus",
+	.bus.match =		vmbus_match,
+	.bus.shutdown =		vmbus_shutdown,
+	.bus.remove =		vmbus_remove,
+	.bus.probe =		vmbus_probe,
+	.bus.uevent =		vmbus_uevent,
+	.bus.dev_attrs =	vmbus_device_attrs,
+};
+
+/**
+ * vmbus_show_device_attr - Show the device attribute in sysfs.
+ *
+ * This is invoked when user does a
+ * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
+ */
+static ssize_t vmbus_show_device_attr(struct device *dev,
+				      struct device_attribute *dev_attr,
+				      char *buf)
+{
+	struct device_context *device_ctx = device_to_device_context(dev);
+	struct hv_device_info device_info;
+
+	memset(&device_info, 0, sizeof(struct hv_device_info));
+
+	vmbus_child_device_get_info(&device_ctx->device_obj, &device_info);
+
+	if (!strcmp(dev_attr->attr.name, "class_id")) {
+		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
+			       device_info.ChannelType.data[3],
+			       device_info.ChannelType.data[2],
+			       device_info.ChannelType.data[1],
+			       device_info.ChannelType.data[0],
+			       device_info.ChannelType.data[5],
+			       device_info.ChannelType.data[4],
+			       device_info.ChannelType.data[7],
+			       device_info.ChannelType.data[6],
+			       device_info.ChannelType.data[8],
+			       device_info.ChannelType.data[9],
+			       device_info.ChannelType.data[10],
+			       device_info.ChannelType.data[11],
+			       device_info.ChannelType.data[12],
+			       device_info.ChannelType.data[13],
+			       device_info.ChannelType.data[14],
+			       device_info.ChannelType.data[15]);
+	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
+		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
+			       device_info.ChannelInstance.data[3],
+			       device_info.ChannelInstance.data[2],
+			       device_info.ChannelInstance.data[1],
+			       device_info.ChannelInstance.data[0],
+			       device_info.ChannelInstance.data[5],
+			       device_info.ChannelInstance.data[4],
+			       device_info.ChannelInstance.data[7],
+			       device_info.ChannelInstance.data[6],
+			       device_info.ChannelInstance.data[8],
+			       device_info.ChannelInstance.data[9],
+			       device_info.ChannelInstance.data[10],
+			       device_info.ChannelInstance.data[11],
+			       device_info.ChannelInstance.data[12],
+			       device_info.ChannelInstance.data[13],
+			       device_info.ChannelInstance.data[14],
+			       device_info.ChannelInstance.data[15]);
+	} else if (!strcmp(dev_attr->attr.name, "state")) {
+		return sprintf(buf, "%d\n", device_info.ChannelState);
+	} else if (!strcmp(dev_attr->attr.name, "id")) {
+		return sprintf(buf, "%d\n", device_info.ChannelId);
+	} else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
+		return sprintf(buf, "%d\n", device_info.Outbound.InterruptMask);
+	} else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
+		return sprintf(buf, "%d\n", device_info.Outbound.ReadIndex);
+	} else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
+		return sprintf(buf, "%d\n", device_info.Outbound.WriteIndex);
+	} else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.Outbound.BytesAvailToRead);
+	} else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.Outbound.BytesAvailToWrite);
+	} else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
+		return sprintf(buf, "%d\n", device_info.Inbound.InterruptMask);
+	} else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
+		return sprintf(buf, "%d\n", device_info.Inbound.ReadIndex);
+	} else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
+		return sprintf(buf, "%d\n", device_info.Inbound.WriteIndex);
+	} else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.Inbound.BytesAvailToRead);
+	} else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.Inbound.BytesAvailToWrite);
+	} else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
+		return sprintf(buf, "%d\n", device_info.MonitorId);
+	} else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
+		return sprintf(buf, "%d\n", device_info.ServerMonitorPending);
+	} else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
+		return sprintf(buf, "%d\n", device_info.ServerMonitorLatency);
+	} else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
+		return sprintf(buf, "%d\n",
+			       device_info.ServerMonitorConnectionId);
+	} else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
+		return sprintf(buf, "%d\n", device_info.ClientMonitorPending);
+	} else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
+		return sprintf(buf, "%d\n", device_info.ClientMonitorLatency);
+	} else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
+		return sprintf(buf, "%d\n",
+			       device_info.ClientMonitorConnectionId);
+	} else {
+		return 0;
+	}
+}
+
+/**
+ * vmbus_bus_init -Main vmbus driver initialization routine.
+ *
+ * Here, we
+ * 	- initialize the vmbus driver context
+ * 	- setup various driver entry points
+ * 	- invoke the vmbus hv main init routine
+ * 	- get the irq resource
+ * 	- invoke the vmbus to add the vmbus root device
+ * 	- setup the vmbus root device
+ * 	- retrieve the channel offers
+ */
+static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
+{
+	struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
+	struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
+	struct device_context *dev_ctx = &g_vmbus_drv.device_ctx;
+	int ret;
+	unsigned int vector;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/*
+	 * Set this up to allow lower layer to callback to add/remove child
+	 * devices on the bus
+	 */
+	vmbus_drv_obj->OnChildDeviceCreate = vmbus_child_device_create;
+	vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy;
+	vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register;
+	vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister;
+
+	/* Call to bus driver to initialize */
+	ret = drv_init(&vmbus_drv_obj->Base);
+	if (ret != 0) {
+		DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret);
+		goto cleanup;
+	}
+
+	/* Sanity checks */
+	if (!vmbus_drv_obj->Base.OnDeviceAdd) {
+		DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set");
+		ret = -1;
+		goto cleanup;
+	}
+
+	vmbus_drv_ctx->bus.name = vmbus_drv_obj->Base.name;
+
+	/* Initialize the bus context */
+	tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc,
+		     (unsigned long)vmbus_drv_obj);
+	tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc,
+		     (unsigned long)vmbus_drv_obj);
+
+	/* Now, register the bus driver with LDM */
+	ret = bus_register(&vmbus_drv_ctx->bus);
+	if (ret) {
+		ret = -1;
+		goto cleanup;
+	}
+
+	/* Get the interrupt resource */
+	ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
+			  vmbus_drv_obj->Base.name, NULL);
+
+	if (ret != 0) {
+		DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d",
+			   vmbus_irq);
+
+		bus_unregister(&vmbus_drv_ctx->bus);
+
+		ret = -1;
+		goto cleanup;
+	}
+	vector = VMBUS_IRQ_VECTOR;
+
+	DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
+
+	/* Call to bus driver to add the root device */
+	memset(dev_ctx, 0, sizeof(struct device_context));
+
+	ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
+	if (ret != 0) {
+		DPRINT_ERR(VMBUS_DRV,
+			   "ERROR - Unable to add vmbus root device");
+
+		free_irq(vmbus_irq, NULL);
+
+		bus_unregister(&vmbus_drv_ctx->bus);
+
+		ret = -1;
+		goto cleanup;
+	}
+	/* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */
+	dev_set_name(&dev_ctx->device, "vmbus_0_0");
+	memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType,
+		sizeof(struct hv_guid));
+	memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance,
+		sizeof(struct hv_guid));
+
+	/* No need to bind a driver to the root device. */
+	dev_ctx->device.parent = NULL;
+	/* NULL; vmbus_remove() does not get invoked */
+	dev_ctx->device.bus = &vmbus_drv_ctx->bus;
+
+	/* Setup the device dispatch table */
+	dev_ctx->device.release = vmbus_bus_release;
+
+	/* Setup the bus as root device */
+	ret = device_register(&dev_ctx->device);
+	if (ret) {
+		DPRINT_ERR(VMBUS_DRV,
+			   "ERROR - Unable to register vmbus root device");
+
+		free_irq(vmbus_irq, NULL);
+		bus_unregister(&vmbus_drv_ctx->bus);
+
+		ret = -1;
+		goto cleanup;
+	}
+
+
+	vmbus_drv_obj->GetChannelOffers();
+
+cleanup:
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return ret;
+}
+
+/**
+ * vmbus_bus_exit - Terminate the vmbus driver.
+ *
+ * This routine is opposite of vmbus_bus_init()
+ */
+static void vmbus_bus_exit(void)
+{
+	struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
+	struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv;
+
+	struct device_context *dev_ctx = &g_vmbus_drv.device_ctx;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/* Remove the root device */
+	if (vmbus_drv_obj->Base.OnDeviceRemove)
+		vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj);
+
+	if (vmbus_drv_obj->Base.OnCleanup)
+		vmbus_drv_obj->Base.OnCleanup(&vmbus_drv_obj->Base);
+
+	/* Unregister the root bus device */
+	device_unregister(&dev_ctx->device);
+
+	bus_unregister(&vmbus_drv_ctx->bus);
+
+	free_irq(vmbus_irq, NULL);
+
+	tasklet_kill(&vmbus_drv_ctx->msg_dpc);
+	tasklet_kill(&vmbus_drv_ctx->event_dpc);
+
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return;
+}
+
+/**
+ * vmbus_child_driver_register - Register a vmbus's child driver
+ */
+int vmbus_child_driver_register(struct driver_context *driver_ctx)
+{
+	struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
+	int ret;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s",
+		    driver_ctx, driver_ctx->driver.name);
+
+	/* The child driver on this vmbus */
+	driver_ctx->driver.bus = &g_vmbus_drv.bus;
+
+	ret = driver_register(&driver_ctx->driver);
+
+	vmbus_drv_obj->GetChannelOffers();
+
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return ret;
+}
+EXPORT_SYMBOL(vmbus_child_driver_register);
+
+/**
+ * vmbus_child_driver_unregister Unregister a vmbus's child driver
+ */
+void vmbus_child_driver_unregister(struct driver_context *driver_ctx)
+{
+	DPRINT_ENTER(VMBUS_DRV);
+
+	DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s",
+		    driver_ctx, driver_ctx->driver.name);
+
+	driver_unregister(&driver_ctx->driver);
+
+	driver_ctx->driver.bus = NULL;
+
+	DPRINT_EXIT(VMBUS_DRV);
+}
+EXPORT_SYMBOL(vmbus_child_driver_unregister);
+
+/**
+ * vmbus_get_interface - Get the vmbus channel interface.
+ *
+ * This is invoked by child/client driver that sits above vmbus
+ */
+void vmbus_get_interface(struct vmbus_channel_interface *interface)
+{
+	struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
+
+	vmbus_drv_obj->GetChannelInterface(interface);
+}
+EXPORT_SYMBOL(vmbus_get_interface);
+
+/**
+ * vmbus_child_device_get_info - Get the vmbus child device info.
+ *
+ * This is invoked to display various device attributes in sysfs.
+ */
+static void vmbus_child_device_get_info(struct hv_device *device_obj,
+					struct hv_device_info *device_info)
+{
+	struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj;
+
+	vmbus_drv_obj->GetChannelInfo(device_obj, device_info);
+}
+
+/**
+ * vmbus_child_device_create - Creates and registers a new child device on the vmbus.
+ */
+static struct hv_device *vmbus_child_device_create(struct hv_guid *type,
+						   struct hv_guid *instance,
+						   void *context)
+{
+	struct device_context *child_device_ctx;
+	struct hv_device *child_device_obj;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/* Allocate the new child device */
+	child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL);
+	if (!child_device_ctx) {
+		DPRINT_ERR(VMBUS_DRV,
+			"unable to allocate device_context for child device");
+		DPRINT_EXIT(VMBUS_DRV);
+
+		return NULL;
+	}
+
+	DPRINT_DBG(VMBUS_DRV, "child device (%p) allocated - "
+		"type {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		"%02x%02x%02x%02x%02x%02x%02x%02x},"
+		"id {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		"%02x%02x%02x%02x%02x%02x%02x%02x}",
+		&child_device_ctx->device,
+		type->data[3], type->data[2], type->data[1], type->data[0],
+		type->data[5], type->data[4], type->data[7], type->data[6],
+		type->data[8], type->data[9], type->data[10], type->data[11],
+		type->data[12], type->data[13], type->data[14], type->data[15],
+		instance->data[3], instance->data[2],
+		instance->data[1], instance->data[0],
+		instance->data[5], instance->data[4],
+		instance->data[7], instance->data[6],
+		instance->data[8], instance->data[9],
+		instance->data[10], instance->data[11],
+		instance->data[12], instance->data[13],
+		instance->data[14], instance->data[15]);
+
+	child_device_obj = &child_device_ctx->device_obj;
+	child_device_obj->context = context;
+	memcpy(&child_device_obj->deviceType, &type, sizeof(struct hv_guid));
+	memcpy(&child_device_obj->deviceInstance, &instance,
+	       sizeof(struct hv_guid));
+
+	memcpy(&child_device_ctx->class_id, &type, sizeof(struct hv_guid));
+	memcpy(&child_device_ctx->device_id, &instance, sizeof(struct hv_guid));
+
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return child_device_obj;
+}
+
+/**
+ * vmbus_child_device_register - Register the child device on the specified bus
+ */
+static int vmbus_child_device_register(struct hv_device *root_device_obj,
+				       struct hv_device *child_device_obj)
+{
+	int ret = 0;
+	struct device_context *root_device_ctx =
+				to_device_context(root_device_obj);
+	struct device_context *child_device_ctx =
+				to_device_context(child_device_obj);
+	static atomic_t device_num = ATOMIC_INIT(0);
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	DPRINT_DBG(VMBUS_DRV, "child device (%p) registering",
+		   child_device_ctx);
+
+	/* Make sure we are not registered already */
+	if (strlen(dev_name(&child_device_ctx->device)) != 0) {
+		DPRINT_ERR(VMBUS_DRV,
+			   "child device (%p) already registered - busid %s",
+			   child_device_ctx,
+			   dev_name(&child_device_ctx->device));
+
+		ret = -1;
+		goto Cleanup;
+	}
+
+	/* Set the device bus id. Otherwise, device_register()will fail. */
+	dev_set_name(&child_device_ctx->device, "vmbus_0_%d",
+		     atomic_inc_return(&device_num));
+
+	/* The new device belongs to this bus */
+	child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */
+	child_device_ctx->device.parent = &root_device_ctx->device;
+	child_device_ctx->device.release = vmbus_device_release;
+
+	/*
+	 * Register with the LDM. This will kick off the driver/device
+	 * binding...which will eventually call vmbus_match() and vmbus_probe()
+	 */
+	ret = device_register(&child_device_ctx->device);
+
+	/* vmbus_probe() error does not get propergate to device_register(). */
+	ret = child_device_ctx->probe_error;
+
+	if (ret)
+		DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)",
+			   &child_device_ctx->device);
+	else
+		DPRINT_INFO(VMBUS_DRV, "child device (%p) registered",
+			    &child_device_ctx->device);
+
+Cleanup:
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return ret;
+}
+
+/**
+ * vmbus_child_device_unregister - Remove the specified child device from the vmbus.
+ */
+static void vmbus_child_device_unregister(struct hv_device *device_obj)
+{
+	struct device_context *device_ctx = to_device_context(device_obj);
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)",
+		    &device_ctx->device);
+
+	/*
+	 * Kick off the process of unregistering the device.
+	 * This will call vmbus_remove() and eventually vmbus_device_release()
+	 */
+	device_unregister(&device_ctx->device);
+
+	DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered",
+		    &device_ctx->device);
+
+	DPRINT_EXIT(VMBUS_DRV);
+}
+
+/**
+ * vmbus_child_device_destroy - Destroy the specified child device on the vmbus.
+ */
+static void vmbus_child_device_destroy(struct hv_device *device_obj)
+{
+	DPRINT_ENTER(VMBUS_DRV);
+
+	DPRINT_EXIT(VMBUS_DRV);
+}
+
+/**
+ * vmbus_uevent - add uevent for our device
+ *
+ * This routine is invoked when a device is added or removed on the vmbus to
+ * generate a uevent to udev in the userspace. The udev will then look at its
+ * rule and the uevent generated here to load the appropriate driver
+ */
+static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
+{
+	struct device_context *device_ctx = device_to_device_context(device);
+	int i = 0;
+	int len = 0;
+	int ret;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={"
+		    "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+		    "%02x%02x%02x%02x%02x%02x%02x%02x}",
+		    device_ctx->class_id.data[3], device_ctx->class_id.data[2],
+		    device_ctx->class_id.data[1], device_ctx->class_id.data[0],
+		    device_ctx->class_id.data[5], device_ctx->class_id.data[4],
+		    device_ctx->class_id.data[7], device_ctx->class_id.data[6],
+		    device_ctx->class_id.data[8], device_ctx->class_id.data[9],
+		    device_ctx->class_id.data[10],
+		    device_ctx->class_id.data[11],
+		    device_ctx->class_id.data[12],
+		    device_ctx->class_id.data[13],
+		    device_ctx->class_id.data[14],
+		    device_ctx->class_id.data[15]);
+
+	env->envp_idx = i;
+	env->buflen = len;
+	ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
+			     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			     "%02x%02x%02x%02x%02x%02x%02x%02x}",
+			     device_ctx->class_id.data[3],
+			     device_ctx->class_id.data[2],
+			     device_ctx->class_id.data[1],
+			     device_ctx->class_id.data[0],
+			     device_ctx->class_id.data[5],
+			     device_ctx->class_id.data[4],
+			     device_ctx->class_id.data[7],
+			     device_ctx->class_id.data[6],
+			     device_ctx->class_id.data[8],
+			     device_ctx->class_id.data[9],
+			     device_ctx->class_id.data[10],
+			     device_ctx->class_id.data[11],
+			     device_ctx->class_id.data[12],
+			     device_ctx->class_id.data[13],
+			     device_ctx->class_id.data[14],
+			     device_ctx->class_id.data[15]);
+
+	if (ret)
+		return ret;
+
+	ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
+			     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			     "%02x%02x%02x%02x%02x%02x%02x%02x}",
+			     device_ctx->device_id.data[3],
+			     device_ctx->device_id.data[2],
+			     device_ctx->device_id.data[1],
+			     device_ctx->device_id.data[0],
+			     device_ctx->device_id.data[5],
+			     device_ctx->device_id.data[4],
+			     device_ctx->device_id.data[7],
+			     device_ctx->device_id.data[6],
+			     device_ctx->device_id.data[8],
+			     device_ctx->device_id.data[9],
+			     device_ctx->device_id.data[10],
+			     device_ctx->device_id.data[11],
+			     device_ctx->device_id.data[12],
+			     device_ctx->device_id.data[13],
+			     device_ctx->device_id.data[14],
+			     device_ctx->device_id.data[15]);
+	if (ret)
+		return ret;
+
+	env->envp[env->envp_idx] = NULL;
+
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return 0;
+}
+
+/**
+ * vmbus_match - Attempt to match the specified device to the specified driver
+ */
+static int vmbus_match(struct device *device, struct device_driver *driver)
+{
+	int match = 0;
+	struct driver_context *driver_ctx = driver_to_driver_context(driver);
+	struct device_context *device_ctx = device_to_device_context(device);
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/* We found our driver ? */
+	if (memcmp(&device_ctx->class_id, &driver_ctx->class_id,
+		   sizeof(struct hv_guid)) == 0) {
+		/*
+		 * !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast
+		 * it here to access the struct hv_driver field
+		 */
+		struct vmbus_driver_context *vmbus_drv_ctx =
+			(struct vmbus_driver_context *)driver_ctx;
+
+		device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj.Base;
+		DPRINT_INFO(VMBUS_DRV,
+			    "device object (%p) set to driver object (%p)",
+			    &device_ctx->device_obj,
+			    device_ctx->device_obj.Driver);
+
+		match = 1;
+	}
+
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return match;
+}
+
+/**
+ * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe()
+ *
+ * We need a callback because we cannot invoked device_unregister() inside
+ * vmbus_probe() since vmbus_probe() may be invoked inside device_register()
+ * i.e. we cannot call device_unregister() inside device_register()
+ */
+static void vmbus_probe_failed_cb(struct work_struct *context)
+{
+	struct device_context *device_ctx = (struct device_context *)context;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/*
+	 * Kick off the process of unregistering the device.
+	 * This will call vmbus_remove() and eventually vmbus_device_release()
+	 */
+	device_unregister(&device_ctx->device);
+
+	/* put_device(&device_ctx->device); */
+	DPRINT_EXIT(VMBUS_DRV);
+}
+
+/**
+ * vmbus_probe - Add the new vmbus's child device
+ */
+static int vmbus_probe(struct device *child_device)
+{
+	int ret = 0;
+	struct driver_context *driver_ctx =
+			driver_to_driver_context(child_device->driver);
+	struct device_context *device_ctx =
+			device_to_device_context(child_device);
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/* Let the specific open-source driver handles the probe if it can */
+	if (driver_ctx->probe) {
+		ret = device_ctx->probe_error = driver_ctx->probe(child_device);
+		if (ret != 0) {
+			DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s "
+				   "(%p) on driver %s (%d)...",
+				   dev_name(child_device), child_device,
+				   child_device->driver->name, ret);
+
+			INIT_WORK(&device_ctx->probe_failed_work_item,
+				  vmbus_probe_failed_cb);
+			schedule_work(&device_ctx->probe_failed_work_item);
+		}
+	} else {
+		DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s",
+			   child_device->driver->name);
+		ret = -1;
+	}
+
+	DPRINT_EXIT(VMBUS_DRV);
+	return ret;
+}
+
+/**
+ * vmbus_remove - Remove a vmbus device
+ */
+static int vmbus_remove(struct device *child_device)
+{
+	int ret;
+	struct driver_context *driver_ctx;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/* Special case root bus device */
+	if (child_device->parent == NULL) {
+		/*
+		 * No-op since it is statically defined and handle in
+		 * vmbus_bus_exit()
+		 */
+		DPRINT_EXIT(VMBUS_DRV);
+		return 0;
+	}
+
+	if (child_device->driver) {
+		driver_ctx = driver_to_driver_context(child_device->driver);
+
+		/*
+		 * Let the specific open-source driver handles the removal if
+		 * it can
+		 */
+		if (driver_ctx->remove) {
+			ret = driver_ctx->remove(child_device);
+		} else {
+			DPRINT_ERR(VMBUS_DRV,
+				   "remove() method not set for driver - %s",
+				   child_device->driver->name);
+			ret = -1;
+		}
+	}
+
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return 0;
+}
+
+/**
+ * vmbus_shutdown - Shutdown a vmbus device
+ */
+static void vmbus_shutdown(struct device *child_device)
+{
+	struct driver_context *driver_ctx;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/* Special case root bus device */
+	if (child_device->parent == NULL) {
+		/*
+		 * No-op since it is statically defined and handle in
+		 * vmbus_bus_exit()
+		 */
+		DPRINT_EXIT(VMBUS_DRV);
+		return;
+	}
+
+	/* The device may not be attached yet */
+	if (!child_device->driver) {
+		DPRINT_EXIT(VMBUS_DRV);
+		return;
+	}
+
+	driver_ctx = driver_to_driver_context(child_device->driver);
+
+	/* Let the specific open-source driver handles the removal if it can */
+	if (driver_ctx->shutdown)
+		driver_ctx->shutdown(child_device);
+
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return;
+}
+
+/**
+ * vmbus_bus_release - Final callback release of the vmbus root device
+ */
+static void vmbus_bus_release(struct device *device)
+{
+	DPRINT_ENTER(VMBUS_DRV);
+	/* FIXME */
+	/* Empty release functions are a bug, or a major sign
+	 * of a problem design, this MUST BE FIXED! */
+	dev_err(device, "%s needs to be fixed!\n", __func__);
+	WARN_ON(1);
+	DPRINT_EXIT(VMBUS_DRV);
+}
+
+/**
+ * vmbus_device_release - Final callback release of the vmbus child device
+ */
+static void vmbus_device_release(struct device *device)
+{
+	struct device_context *device_ctx = device_to_device_context(device);
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	/* vmbus_child_device_destroy(&device_ctx->device_obj); */
+	kfree(device_ctx);
+
+	/* !!DO NOT REFERENCE device_ctx anymore at this point!! */
+	DPRINT_EXIT(VMBUS_DRV);
+
+	return;
+}
+
+/**
+ * vmbus_msg_dpc - Tasklet routine to handle hypervisor messages
+ */
+static void vmbus_msg_dpc(unsigned long data)
+{
+	struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	ASSERT(vmbus_drv_obj->OnMsgDpc != NULL);
+
+	/* Call to bus driver to handle interrupt */
+	vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base);
+
+	DPRINT_EXIT(VMBUS_DRV);
+}
+
+/**
+ * vmbus_msg_dpc - Tasklet routine to handle hypervisor events
+ */
+static void vmbus_event_dpc(unsigned long data)
+{
+	struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	ASSERT(vmbus_drv_obj->OnEventDpc != NULL);
+
+	/* Call to bus driver to handle interrupt */
+	vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base);
+
+	DPRINT_EXIT(VMBUS_DRV);
+}
+
+static irqreturn_t vmbus_isr(int irq, void *dev_id)
+{
+	struct vmbus_driver *vmbus_driver_obj = &g_vmbus_drv.drv_obj;
+	int ret;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	ASSERT(vmbus_driver_obj->OnIsr != NULL);
+
+	/* Call to bus driver to handle interrupt */
+	ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base);
+
+	/* Schedules a dpc if necessary */
+	if (ret > 0) {
+		if (test_bit(0, (unsigned long *)&ret))
+			tasklet_schedule(&g_vmbus_drv.msg_dpc);
+
+		if (test_bit(1, (unsigned long *)&ret))
+			tasklet_schedule(&g_vmbus_drv.event_dpc);
+
+		DPRINT_EXIT(VMBUS_DRV);
+		return IRQ_HANDLED;
+	} else {
+		DPRINT_EXIT(VMBUS_DRV);
+		return IRQ_NONE;
+	}
+}
+
+static int __init vmbus_init(void)
+{
+	int ret = 0;
+
+	DPRINT_ENTER(VMBUS_DRV);
+
+	DPRINT_INFO(VMBUS_DRV,
+		"Vmbus initializing.... current log level 0x%x (%x,%x)",
+		vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
+	/* Todo: it is used for loglevel, to be ported to new kernel. */
+
+	ret = vmbus_bus_init(VmbusInitialize);
+
+	DPRINT_EXIT(VMBUS_DRV);
+	return ret;
+}
+
+static void __exit vmbus_exit(void)
+{
+	DPRINT_ENTER(VMBUS_DRV);
+
+	vmbus_bus_exit();
+	/* Todo: it is used for loglevel, to be ported to new kernel. */
+	DPRINT_EXIT(VMBUS_DRV);
+	return;
+}
+
+MODULE_LICENSE("GPL");
+module_param(vmbus_irq, int, S_IRUGO);
+module_param(vmbus_loglevel, int, S_IRUGO);
+
+module_init(vmbus_init);
+module_exit(vmbus_exit);
diff --git a/drivers/staging/hv/vstorage.h b/drivers/staging/hv/vstorage.h
new file mode 100644
index 0000000..6d160a5
--- /dev/null
+++ b/drivers/staging/hv/vstorage.h
@@ -0,0 +1,192 @@
+/*
+ *
+ * Copyright (c) 2009, Microsoft Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *
+ */
+
+/* vstorage.w revision number.  This is used in the case of a version match, */
+/* to alert the user that structure sizes may be mismatched even though the */
+/* protocol versions match. */
+
+#define REVISION_STRING(REVISION_) #REVISION_
+#define FILL_VMSTOR_REVISION(RESULT_LVALUE_)				\
+{									\
+	char *revisionString = REVISION_STRING($Revision: 6 $) + 11;	\
+	RESULT_LVALUE_ = 0;						\
+	while (*revisionString >= '0' && *revisionString <= '9') {	\
+		RESULT_LVALUE_ *= 10;					\
+		RESULT_LVALUE_ += *revisionString - '0';		\
+		revisionString++;					\
+	}								\
+}
+
+/* Major/minor macros.  Minor version is in LSB, meaning that earlier flat */
+/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
+#define VMSTOR_PROTOCOL_MAJOR(VERSION_)		(((VERSION_) >> 8) & 0xff)
+#define VMSTOR_PROTOCOL_MINOR(VERSION_)		(((VERSION_))      & 0xff)
+#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
+						 (((MINOR_) & 0xff)))
+#define VMSTOR_INVALID_PROTOCOL_VERSION		(-1)
+
+/* Version history: */
+/* V1 Beta                    0.1 */
+/* V1 RC < 2008/1/31          1.0 */
+/* V1 RC > 2008/1/31          2.0 */
+#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
+
+
+
+
+/*  This will get replaced with the max transfer length that is possible on */
+/*  the host adapter. */
+/*  The max transfer length will be published when we offer a vmbus channel. */
+#define MAX_TRANSFER_LENGTH	0x40000
+#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) +	\
+			sizeof(struct vstor_packet) +		\
+			sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
+
+
+/*  Packet structure describing virtual storage requests. */
+enum vstor_packet_operation {
+	VStorOperationCompleteIo            = 1,
+	VStorOperationRemoveDevice          = 2,
+	VStorOperationExecuteSRB            = 3,
+	VStorOperationResetLun              = 4,
+	VStorOperationResetAdapter          = 5,
+	VStorOperationResetBus              = 6,
+	VStorOperationBeginInitialization   = 7,
+	VStorOperationEndInitialization     = 8,
+	VStorOperationQueryProtocolVersion  = 9,
+	VStorOperationQueryProperties       = 10,
+	VStorOperationMaximum               = 10
+};
+
+/*
+ * Platform neutral description of a scsi request -
+ * this remains the same across the write regardless of 32/64 bit
+ * note: it's patterned off the SCSI_PASS_THROUGH structure
+ */
+#define CDB16GENERIC_LENGTH			0x10
+
+#ifndef SENSE_BUFFER_SIZE
+#define SENSE_BUFFER_SIZE			0x12
+#endif
+
+#define MAX_DATA_BUFFER_LENGTH_WITH_PADDING	0x14
+
+struct vmscsi_request {
+	unsigned short Length;
+	unsigned char SrbStatus;
+	unsigned char ScsiStatus;
+
+	unsigned char PortNumber;
+	unsigned char PathId;
+	unsigned char TargetId;
+	unsigned char Lun;
+
+	unsigned char CdbLength;
+	unsigned char SenseInfoLength;
+	unsigned char DataIn;
+	unsigned char Reserved;
+
+	unsigned int DataTransferLength;
+
+	union {
+	unsigned char Cdb[CDB16GENERIC_LENGTH];
+
+	unsigned char SenseData[SENSE_BUFFER_SIZE];
+
+	unsigned char ReservedArray[MAX_DATA_BUFFER_LENGTH_WITH_PADDING];
+	};
+} __attribute((packed));
+
+
+/*
+ * This structure is sent during the intialization phase to get the different
+ * properties of the channel.
+ */
+struct vmstorage_channel_properties {
+	unsigned short ProtocolVersion;
+	unsigned char  PathId;
+	unsigned char  TargetId;
+
+	/* Note: port number is only really known on the client side */
+	unsigned int  PortNumber;
+	unsigned int  Flags;
+	unsigned int  MaxTransferBytes;
+
+	/*  This id is unique for each channel and will correspond with */
+	/*  vendor specific data in the inquirydata */
+	unsigned long long UniqueId;
+} __attribute__((packed));
+
+/*  This structure is sent during the storage protocol negotiations. */
+struct vmstorage_protocol_version {
+	/* Major (MSW) and minor (LSW) version numbers. */
+	unsigned short MajorMinor;
+
+	/*
+	 * Revision number is auto-incremented whenever this file is changed
+	 * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
+	 * definitely indicate incompatibility--but it does indicate mismatched
+	 * builds.
+	 */
+	unsigned short Revision;
+} __attribute__((packed));
+
+/* Channel Property Flags */
+#define STORAGE_CHANNEL_REMOVABLE_FLAG		0x1
+#define STORAGE_CHANNEL_EMULATED_IDE_FLAG	0x2
+
+struct vstor_packet {
+	/* Requested operation type */
+	enum vstor_packet_operation Operation;
+
+	/*  Flags - see below for values */
+	unsigned int     Flags;
+
+	/* Status of the request returned from the server side. */
+	unsigned int     Status;
+
+	/* Data payload area */
+	union {
+		/*
+		 * Structure used to forward SCSI commands from the
+		 * client to the server.
+		 */
+		struct vmscsi_request VmSrb;
+
+		/* Structure used to query channel properties. */
+		struct vmstorage_channel_properties StorageChannelProperties;
+
+		/* Used during version negotiations. */
+		struct vmstorage_protocol_version Version;
+	};
+} __attribute__((packed));
+
+/* Packet flags */
+/*
+ * This flag indicates that the server should send back a completion for this
+ * packet.
+ */
+#define REQUEST_COMPLETION_FLAG	0x1
+
+/*  This is the set of flags that the vsc can set in any packets it sends */
+#define VSC_LEGAL_FLAGS		(REQUEST_COMPLETION_FLAG)
diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt
new file mode 100644
index 0000000..6916cd3
--- /dev/null
+++ b/drivers/staging/iio/Documentation/device.txt
@@ -0,0 +1,49 @@
+IIO Device drivers
+
+This is not intended to provide a comprehensive guide to writing an
+IIO device driver.  For further information see the drivers within the
+subsystem.
+
+The crucial structure for device drivers in iio is iio_dev.
+
+First allocate one using:
+
+struct iio_dev *indio_dev = iio_allocate_device();
+
+The fill in the following.
+
+indio_dev->dev.parent
+  the struct device associated with the underlying hardware.
+
+indio_dev->num_interrupt_lines
+   number of event triggering hardware lines the device has.
+
+indio_dev->event_attrs
+   attributes used to enable / disable hardware events - note the
+   attributes are embedded in iio_event_attr structures with an
+   associated iio_event_handler which may or may note be shared.
+   If num_interrupt_lines = 0, then no need to fill this in.
+
+indio_dev->attrs
+   general attributes such as polled access to device channels.
+
+indio_dev->dev_data
+   private device specific data.
+
+indio_dev->driver_module
+   typically set to THIS_MODULE. Used to specify ownership of some
+   iio created resources.
+
+indio_dev->modes
+   whether direct access and / or ring buffer access is supported.
+
+Once these are set up, a call to iio_device_register(indio_dev),
+will register the device with the iio core.
+
+Worth noting here is that, if a ring buffer is to be used, it can be
+allocated prior to registering the device with the iio-core, but must
+be registered afterwards (otherwise the whole parentage of devices
+gets confused)
+
+On remove iio_device_unregister(indio_dev) will remove the device from
+the core, and iio_free_device will clean up.
diff --git a/drivers/staging/iio/Documentation/iio_utils.h b/drivers/staging/iio/Documentation/iio_utils.h
new file mode 100644
index 0000000..74d3124
--- /dev/null
+++ b/drivers/staging/iio/Documentation/iio_utils.h
@@ -0,0 +1,159 @@
+/* IIO - useful set of util functionality
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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.
+ */
+
+#define IIO_EVENT_CODE_RING_50_FULL 200
+#define IIO_EVENT_CODE_RING_75_FULL 201
+#define IIO_EVENT_CODE_RING_100_FULL 202
+
+struct iio_event_data {
+	int id;
+	__s64 timestamp;
+};
+
+
+inline char *find_ring_subelement(const char *directory, const char *subelement)
+{
+	DIR *dp;
+	const struct dirent *ent;
+	int pos;
+	char temp[100];
+	char *returnstring;
+	dp = opendir(directory);
+	if (dp == NULL) {
+		printf("could not directory: %s\n", directory);
+		return NULL;
+	}
+	while (ent = readdir(dp), ent != NULL) {
+		if (strcmp(ent->d_name, ".") != 0 &&
+		    strcmp(ent->d_name, "..") != 0)  {
+			if (strncmp(ent->d_name, subelement, strlen(subelement)) == 0) {
+				int length = sprintf(temp, "%s%s%s", directory, ent->d_name, "/");
+				returnstring = malloc(length+1);
+				strncpy(returnstring, temp, length+1);
+				return returnstring;
+
+			}
+		}
+	}
+	return 0;
+}
+
+
+char *find_type_by_name(const char *name, const char *type)
+{
+	const char *iio_dir = "/sys/class/iio/";
+	const struct dirent *ent;
+	int cnt, pos, pos2;
+
+	FILE *nameFile;
+	DIR *dp;
+	char thisname[100];
+	char temp[100];
+
+	char *returnstring = NULL;
+	struct stat Stat;
+	pos = sprintf(temp, "%s", iio_dir);
+	dp = opendir(iio_dir);
+	if (dp == NULL) {
+		printf("No industrialio devices available");
+		return NULL;
+	}
+	while (ent = readdir(dp), ent != NULL) {
+		cnt++;
+		/*reject . and .. */
+		if (strcmp(ent->d_name, ".") != 0 &&
+		    strcmp(ent->d_name, "..") != 0)  {
+			/*make sure it isn't a trigger!*/
+			if (strncmp(ent->d_name, type, strlen(type)) == 0) {
+				/* build full path to new file */
+				pos2 = pos + sprintf(temp + pos, "%s/", ent->d_name);
+				sprintf(temp + pos2, "name");
+				printf("search location %s\n", temp);
+				nameFile = fopen(temp, "r");
+				if (!nameFile) {
+					sprintf(temp + pos2, "modalias", ent->d_name);
+					nameFile = fopen(temp, "r");
+					if (!nameFile) {
+						printf("Failed to find a name for device\n");
+						return NULL;
+					}
+				}
+				fscanf(nameFile, "%s", thisname);
+				if (strcmp(name, thisname) == 0) {
+					returnstring = malloc(strlen(temp) + 1);
+					sprintf(temp + pos2, "");
+					strcpy(returnstring, temp);
+					return returnstring;
+				}
+				fclose(nameFile);
+
+			}
+		}
+	}
+}
+
+int write_sysfs_int(char *filename, char *basedir, int val)
+{
+	int ret;
+	FILE  *sysfsfp;
+	char temp[100];
+	sprintf(temp, "%s%s", basedir, filename);
+	sysfsfp = fopen(temp, "w");
+	if (sysfsfp == NULL)
+		return -1;
+	fprintf(sysfsfp, "%d", val);
+	fclose(sysfsfp);
+	return 0;
+}
+
+/**
+ * write_sysfs_string_and_verify() - string write, readback and verify
+ * @filename: name of file to write to
+ * @basedir: the sysfs directory in which the file is to be found
+ * @val: the string to write
+ **/
+int write_sysfs_string_and_verify(char *filename, char *basedir, char *val)
+{
+	int ret;
+	FILE  *sysfsfp;
+	char temp[100];
+	sprintf(temp, "%s%s", basedir, filename);
+	sysfsfp = fopen(temp, "w");
+	if (sysfsfp == NULL)
+		return -1;
+	fprintf(sysfsfp, "%s", val);
+	fclose(sysfsfp);
+
+	sysfsfp = fopen(temp, "r");
+	if (sysfsfp == NULL)
+		return -1;
+	fscanf(sysfsfp, "%s", temp);
+	if (strcmp(temp, val) != 0) {
+		printf("Possible failure in string write %s to %s%s \n",
+		       val,
+		       basedir,
+		       filename);
+		return -1;
+	}
+	return 0;
+}
+
+int read_sysfs_posint(char *filename, char *basedir)
+{
+	int ret;
+	FILE  *sysfsfp;
+	char temp[100];
+	sprintf(temp, "%s%s", basedir, filename);
+	sysfsfp = fopen(temp, "r");
+	if (sysfsfp == NULL)
+		return -1;
+	fscanf(sysfsfp, "%d\n", &ret);
+	fclose(sysfsfp);
+	return ret;
+}
diff --git a/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c
new file mode 100644
index 0000000..2b5cfc5
--- /dev/null
+++ b/drivers/staging/iio/Documentation/lis3l02dqbuffersimple.c
@@ -0,0 +1,171 @@
+/* Industrialio test ring buffer with a lis3l02dq acceleromter
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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.
+ *
+ * Assumes suitable udev rules are used to create the dev nodes as named here.
+ */
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+
+#include <linux/types.h>
+#include <dirent.h>
+#include "iio_util.h"
+
+static const char *ring_access = "/dev/iio/lis3l02dq_ring_access";
+static const char *ring_event = "/dev/iio/lis3l02dq_ring_event";
+static const char *device_name = "lis3l02dq";
+static const char *trigger_name = "lis3l02dq-dev0";
+static int NumVals = 3;
+static int scan_ts = 1;
+static int RingLength = 128;
+
+/*
+ * Could get this from ring bps, but only after starting the ring
+ * which is a bit late for it to be useful
+ */
+int size_from_scanmode(int numVals, int timestamp)
+{
+	if (numVals && timestamp)
+		return 16;
+	else if (timestamp)
+		return 8;
+	else
+		return numVals*2;
+}
+
+int main(int argc, char **argv)
+{
+	int i, j, k, toread;
+	FILE *fp_ev;
+	int fp;
+	char *data;
+	size_t read_size;
+	struct iio_event_data dat;
+
+	char	*BaseDirectoryName,
+		*TriggerDirectoryName,
+		*RingBufferDirectoryName;
+
+	BaseDirectoryName = find_type_by_name(device_name, "device");
+	if (BaseDirectoryName == NULL) {
+		printf("Failed to find the %s \n", device_name);
+		return -1;
+	}
+	TriggerDirectoryName = find_type_by_name(trigger_name, "trigger");
+	if (TriggerDirectoryName == NULL) {
+		printf("Failed to find the %s\n", trigger_name);
+		return -1;
+	}
+	RingBufferDirectoryName = find_ring_subelement(BaseDirectoryName,
+						       "ring_buffer");
+	if (RingBufferDirectoryName == NULL) {
+		printf("Failed to find ring buffer\n");
+		return -1;
+	}
+
+	if (write_sysfs_string_and_verify("trigger/current_trigger",
+					  BaseDirectoryName,
+					  (char *)trigger_name) < 0) {
+		printf("Failed to write current_trigger file \n");
+		return -1;
+	}
+
+	/* Setup ring buffer parameters */
+	if (write_sysfs_int("length", RingBufferDirectoryName,
+			    RingLength) < 0) {
+		printf("Failed to open the ring buffer length file \n");
+		return -1;
+	}
+
+	/* Enable the ring buffer */
+	if (write_sysfs_int("ring_enable", RingBufferDirectoryName, 1) < 0) {
+		printf("Failed to open the ring buffer control file \n");
+		return -1;
+	};
+
+	data = malloc(size_from_scanmode(NumVals, scan_ts)*RingLength);
+	if (!data) {
+		printf("Could not allocate space for usespace data store\n");
+		return -1;
+	}
+
+	/* Attempt to open non blocking the access dev */
+	fp = open(ring_access, O_RDONLY | O_NONBLOCK);
+	if (fp == -1) { /*If it isn't there make the node */
+		printf("Failed to open %s\n", ring_access);
+		return -1;
+	}
+	/* Attempt to open the event access dev (blocking this time) */
+	fp_ev = fopen(ring_event, "rb");
+	if (fp_ev == NULL) {
+		printf("Failed to open %s\n", ring_event);
+		return -1;
+	}
+
+	/* Wait for events 10 times */
+	for (j = 0; j < 10; j++) {
+		read_size = fread(&dat, 1, sizeof(struct iio_event_data),
+				  fp_ev);
+		switch (dat.id) {
+		case IIO_EVENT_CODE_RING_100_FULL:
+			toread = RingLength;
+			break;
+		case IIO_EVENT_CODE_RING_75_FULL:
+			toread = RingLength*3/4;
+			break;
+		case IIO_EVENT_CODE_RING_50_FULL:
+			toread = RingLength/2;
+			break;
+		default:
+			printf("Unexpecteded event code\n");
+			continue;
+		}
+		read_size = read(fp,
+				 data,
+				 toread*size_from_scanmode(NumVals, scan_ts));
+		if (read_size == -EAGAIN) {
+			printf("nothing available \n");
+			continue;
+		}
+
+		for (i = 0;
+		     i < read_size/size_from_scanmode(NumVals, scan_ts);
+		     i++) {
+			for (k = 0; k < NumVals; k++) {
+				__s16 val = *(__s16 *)(&data[i*size_from_scanmode(NumVals, scan_ts)
+							     + (k)*2]);
+				printf("%05d ", val);
+			}
+			printf(" %lld\n",
+			       *(__s64 *)(&data[(i+1)*size_from_scanmode(NumVals, scan_ts)
+						- sizeof(__s64)]));
+		}
+	}
+
+	/* Stop the ring buffer */
+	if (write_sysfs_int("ring_enable", RingBufferDirectoryName, 0) < 0) {
+		printf("Failed to open the ring buffer control file \n");
+		return -1;
+	};
+
+	/* Disconnect from the trigger - writing something that doesn't exist.*/
+	write_sysfs_string_and_verify("trigger/current_trigger",
+				      BaseDirectoryName, "NULL");
+	free(BaseDirectoryName);
+	free(TriggerDirectoryName);
+	free(RingBufferDirectoryName);
+	free(data);
+
+	return 0;
+}
diff --git a/drivers/staging/iio/Documentation/overview.txt b/drivers/staging/iio/Documentation/overview.txt
new file mode 100644
index 0000000..64584ad
--- /dev/null
+++ b/drivers/staging/iio/Documentation/overview.txt
@@ -0,0 +1,62 @@
+Overview of IIO
+
+The Industrial I/O subsytem is intended to provide support for devices
+that in some sense are analog to digital convertors (ADCs). As many
+actual devices combine some ADCs with digital to analog convertors
+(DACs) the intention is to add that functionality at a future date
+(hence the name).
+
+The aim is to fill the gap between the somewhat similar hwmon and
+input subsystems.  Hwmon is very much directed at low sample rate
+sensors used in applications such as fan speed control and temperature
+measurement.  Input is, as it's name suggests focused on input
+devices. In some cases there is considerable overlap between these and
+IIO.
+
+A typical device falling into this category would be connected via SPI
+or I2C.
+
+Functionality of IIO
+
+* Basic device registration and handling. This is very similar to
+hwmon with simple polled access to device channels via sysfs.
+
+* Event chrdevs.  These are similar to input in that they provide a
+route to user space for hardware triggered events. Such events include
+threshold detectors, free-fall detectors and more complex action
+detection.  They events themselves are currently very simple with
+merely an event code and a timestamp.  Any data associated with the
+event must be accessed via polling. Note a given device may have one
+or more event channel.  These events are turned on or off (if possible)
+via sysfs interfaces.
+
+* Hardware ring buffer support.  Some recent sensors have included
+fifo / ring buffers on the sensor chip.  These greatly reduce the load
+on the host CPU by buffering relatively large numbers of data samples
+based on an internal sampling clock. Examples include VTI SCA3000
+series and Analog Device ADXL345 accelerometers.  Each ring buffer
+typically has an event chrdev (similar to the more general ones above)
+to pass on events such as buffer 50% full and an access chrdev via
+which the raw data it self may be read back.
+
+* Trigger and software ring buffer support. In many data analysis
+applications it it useful to be able to capture data based on some
+external signal (trigger).  These triggers might be a data ready
+signal, a gpio line connected to some external system or an on
+processor periodic interrupt.  A single trigger many initialize data
+capture or reading from a number of sensors.  These triggers are
+used in iio to fill software ring buffers acting in a very similar
+fashion to the hardware buffers described above.
+
+Other documentation:
+
+userspace.txt - overview of ring buffer reading from userspace
+
+device.txt - elemennts of a typical device driver.
+
+trigger.txt - elements of a typical trigger driver.
+
+ring.txt - additional elements required for ring buffer support
+
+
+
diff --git a/drivers/staging/iio/Documentation/ring.txt b/drivers/staging/iio/Documentation/ring.txt
new file mode 100644
index 0000000..d2ca683
--- /dev/null
+++ b/drivers/staging/iio/Documentation/ring.txt
@@ -0,0 +1,61 @@
+Ring buffer support within IIO
+
+This document is intended as a general overview of the functionality
+a ring buffer may supply and how it is specified within IIO.  For more
+specific information on a given ring buffer implementation, see the
+comments in the source code.  Note that the intention is to allow
+some drivers to specify ring buffers choice at probe or runtime, but
+for now the selection is hard coded within a given driver.
+
+A given ring buffer implementation typically embedded a struct
+iio_ring_buffer and it is a pointer to this that is provided to the
+IIO core. Access to the embedding structure is typically done via
+container_of functions.
+
+struct iio_ring_buffer contains 4 function pointers
+(preenable, postenable, predisable, postdisable).
+These are used to perform implementation specific steps on either side
+of the core changing it's current mode to indicate that the ring buffer
+is enabled or disabled (along with enabling triggering etc as appropriate).
+
+Also in struct iio_ring_buffer is a struct iio_ring_access_funcs.
+The function pointers within here are used to allow the core to handle
+as much ring buffer functionality as possible. Note almost all of these
+are optional.
+
+mark_in_use, unmark_in_use
+  Basically indicate that not changes should be made to the ring
+  buffer state that will effect the form of the data being captures
+  (e.g. scan elements or length)
+
+store_to
+  If possible, push data to ring buffer.
+
+read_last
+  If possible get the most recent entry from the buffer (without removal).
+  This provides polling like functionality whilst the ring buffering is in
+  use without a separate read from the device.
+
+rip_lots
+  The primary ring buffer reading function. Note that it may well not return
+  as much data as requested.  The deadoffset is used to indicate that some
+  initial data in the data array is not guaranteed to be valid.
+
+mark_param_changed
+  Used to indicate that something has changed. Used in conjunction with
+request_update
+  If parameters have changed that require reinitialization or configuration of
+  the ring buffer this will trigger it.
+
+get_bpd, set_bpd
+  Get/set the number of bytes for a given reading (single element, not sample set)
+  The value of bps (bytes per set) is created from a combination of this and the
+  enabled scan elements.
+
+get_length / set_length
+  Get/set the number of sample sets that may be held by the buffer.
+
+is_enabled
+  Query if ring buffer is in use
+enable
+  Start the ring buffer.
diff --git a/drivers/staging/iio/Documentation/trigger.txt b/drivers/staging/iio/Documentation/trigger.txt
new file mode 100644
index 0000000..650157f
--- /dev/null
+++ b/drivers/staging/iio/Documentation/trigger.txt
@@ -0,0 +1,38 @@
+IIO trigger drivers.
+
+Many triggers are provided by hardware that will also be registered as
+an IIO device.  Whilst this can create device specific complexities
+such triggers are registered with the core in the same way as
+stand-alone triggers.
+
+struct iio_trig *trig = iio_allocate_trigger();
+
+allocates a trigger structure.  The key elements to then fill in within
+a driver are:
+
+trig->control_attrs
+	Any sysfs attributes needed to control parameters of the trigger
+
+trig->private_data
+	Device specific private data.
+
+trig->owner
+	Typically set to THIS_MODULE. Used to ensure correct
+	ownership of core allocated resources.
+
+trig->name
+	A unique name for the trigger.
+
+When these have been set call:
+
+iio_trigger_register(trig);
+
+to register the trigger with the core, making it available to trigger
+consumers.
+
+
+Trigger Consumers
+
+Currently triggers are only used for the filling of software ring
+buffers and as such any device supporting INDIO_RING_TRIGGERED has the
+consumer interface automatically created.
diff --git a/drivers/staging/iio/Documentation/userspace.txt b/drivers/staging/iio/Documentation/userspace.txt
new file mode 100644
index 0000000..661015a
--- /dev/null
+++ b/drivers/staging/iio/Documentation/userspace.txt
@@ -0,0 +1,60 @@
+Userspace access to IIO
+
+Example, ST Microelectronics LIS3L02DQ accelerometer.
+
+Typical sysfs entries (pruned for clarity)
+
+/sys/class/iio
+  device0 - iio_dev related elements
+    name - driver specific identifier (here lis3l02dq)
+    accel_x - polled (or from ring) raw readout of acceleration
+    accel_x_gain - hardware gain (calibration)
+    accel_x_offset - hardware offset (calibration)
+    available_sampling_frequency
+
+    available_sampling_frequency - what options are there
+    sampling_frequency - control of internal sampling frequency
+    scan_elements - controls which channels will be stored in the ring buffer
+      scan_en_accel_x
+      scan_en_accel_y
+      scan_en_timestamp
+    device - link to underlying hardware device
+    uevent - udev related element
+
+    thresh - unified threshold used for detection on all axis
+    event_line0_sources - which events are enabled
+      accel_x_high - enable x axis high threshold event
+      accel_x_low - enable x axis low threshold event
+
+    event_line0 - event interface
+      dev - major:minor for the chrdev (note major allocation dynamic)
+    trigger - consumer attachement
+      current_trigger - name based association with a trigger
+    ring_buffer0 - ring buffer interface
+      bps - byptes per sample (read only), dependant on scan element selection
+      length - (rw) specificy length fo software ring buffer (typically ro in hw case)
+      ring_enable - turn the ring on. If its the first to be enabled attached to this
+                    trigger will also enable the trigger.
+      ring_access0
+        dev - major:minor for ring buffer access chrdev
+      ring_event_line0
+        dev - major:minor for ring buffer event chrdev
+
+  trigger0 - data ready trigger elements
+    name - unqiue name of trigger
+
+Udev will create the following entries under /dev by default:
+
+ring_access0 - ring access chrdev
+ring_event0 - ring event chrdev
+event_line0 - general event chrdev.
+
+For the example code we assume the following rules have been used to ensure
+unique and consistent naming of these for the lis3l02dq in question:
+
+KERNEL="ring_event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ring_event"
+KERNEL="event_line*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_event"
+KERNEL="ring_access*", ID="spi1.0", DRIVER="lis3l02dq", NAME="iio/lis3l02dq_ring_access"
+
+The files, lis3l02dqbuffersimple.c and iio_util.h in this directory provide an example
+of how to use the ring buffer and event interfaces.
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
new file mode 100644
index 0000000..beb99a5
--- /dev/null
+++ b/drivers/staging/iio/Kconfig
@@ -0,0 +1,47 @@
+#
+# Industrial I/O subsytem configuration
+#
+
+menuconfig IIO
+	tristate "Industrial I/O support"
+	---help---
+	  The industrial I/O subsystem provides a unified framework for
+	  drivers for many different types of embedded sensors using a
+	  number of different physical interfaces (i2c, spi etc). See
+	  Documentation/industrialio for more information.
+if IIO
+
+config IIO_RING_BUFFER
+	bool "Enable ring buffer support within IIO"
+	help
+	  Provide core support for various ring buffer based data
+	  acquisition methods.
+
+if IIO_RING_BUFFER
+
+config IIO_SW_RING
+	tristate "Industrial I/O lock free software ring"
+	help
+	example software ring buffer implementation.  The design aim
+	of this particular realization was to minize write locking
+	with the intention that some devices would be able to write
+	in interrupt context.
+
+endif # IIO_RINGBUFFER
+
+config IIO_TRIGGER
+	boolean "Enable triggered sampling support"
+	help
+	  Provides IIO core support for triggers.  Currently these
+	  are used to initialize capture of samples to push into
+	  ring buffers.  The triggers are effectively a 'capture
+	  data now' interrupt.
+
+
+source "drivers/staging/iio/accel/Kconfig"
+source "drivers/staging/iio/adc/Kconfig"
+source "drivers/staging/iio/light/Kconfig"
+
+source "drivers/staging/iio/trigger/Kconfig"
+
+endif # IIO
diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile
new file mode 100644
index 0000000..7ec0218
--- /dev/null
+++ b/drivers/staging/iio/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the industrial I/O core.
+#
+
+obj-$(CONFIG_IIO) += industrialio.o
+industrialio-y := industrialio-core.o
+industrialio-$(CONFIG_IIO_RING_BUFFER) += industrialio-ring.o
+industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o
+
+obj-$(CONFIG_IIO_SW_RING) += ring_sw.o
+
+obj-y += accel/
+obj-y += adc/
+obj-y += light/
+
+obj-y += trigger/
\ No newline at end of file
diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO
new file mode 100644
index 0000000..15da0c2
--- /dev/null
+++ b/drivers/staging/iio/TODO
@@ -0,0 +1,69 @@
+2009 8/18
+
+Core:
+1) Get reviews
+2) Additional testing
+3) Ensure all desirable features present by adding more devices.
+   Major changes not expected except in response to comments
+
+Max1363 core:
+1) Possibly add sysfs exports of constant useful to userspace.
+Would be nice
+2) Support hardware generated interrupts
+3) Expand device set. Lots of other maxim adc's have very
+   similar interfaces.
+
+TSL2561
+Would be nice
+1) Open question of userspace vs kernel space balance when
+converting to useful light measurements from device ones.
+2) Add sysfs elements necessary to allow device agnostic
+unit conversion.
+
+LIS3L02DQ core
+
+LIS3L02DQ ring
+
+KXSD9
+Currently minimal driver, would be nice to add:
+1) Support for all chip generated interrupts (events),
+basically get support up to level of lis3l02dq driver.
+
+Ring buffer core
+
+SCA3000
+Would be nice
+1) Testing on devices other than sca3000-e05
+
+Trigger core support
+1) Discussion of approach. Is it general enough?
+
+Ring Buffer:
+1) Discussion of approach.
+There are probably better ways of doing this. The
+intention is to allow for more than one software ring
+buffer implementation as different users will have
+different requirements.  This one suits mid range
+frequencies (100Hz - 4kHz).
+2) Lots of testing
+
+Periodic Timer trigger
+1) Move to a more general hardware periodic timer request
+subsystem. Current approach is abusing purpose of RTC.
+Initial discussions have taken place, but no actual code
+is in place as yet. This topic will be reopened on lkml
+shortly. I don't really envision this patch being merged
+in anything like its current form.
+
+GPIO trigger
+1) Add control over the type of interrupt etc.  This will
+necessitate a header that is also visible from arch board
+files. (avoided at the moment to keep the driver set
+contained in staging).
+
+Documentation
+1) Lots of cleanup and expansion.
+2) Some device require indvidual docs.
+
+Contact: Jonathan Cameron <jic23@cam.ac.uk>.
+Mailing list: LKML.
diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig
new file mode 100644
index 0000000..fef3da4
--- /dev/null
+++ b/drivers/staging/iio/accel/Kconfig
@@ -0,0 +1,27 @@
+#
+# Accelerometer drivers
+#
+comment "Accelerometers"
+
+config KXSD9
+	tristate "Kionix KXSD9 Accelerometer Driver"
+	depends on SPI
+	help
+	  Say yes here to build support for the Kionix KXSD9 accelerometer.
+	  Currently this only supports the device via an SPI interface.
+
+config LIS3L02DQ
+	tristate "ST Microelectronics LIS3L02DQ Accelerometer Driver"
+	depends on SPI
+	help
+	  Say yes here to build SPI support for the ST microelectronics
+	  accelerometer. The driver supplies direct access via sysfs files
+	  and an event interface via a character device.
+
+config SCA3000
+       depends on IIO_RING_BUFFER
+       depends on SPI
+       tristate "VTI SCA3000 series accelerometers"
+       help
+         Say yes here to build support for the VTI SCA3000 series of SPI
+	 accelerometers. These devices use a hardware ring buffer.
\ No newline at end of file
diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile
new file mode 100644
index 0000000..d5335f9
--- /dev/null
+++ b/drivers/staging/iio/accel/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for industrial I/O accelerometer drivers
+#
+obj-$(CONFIG_KXSD9)	+= kxsd9.o
+
+lis3l02dq-y		:= lis3l02dq_core.o
+lis3l02dq-$(CONFIG_IIO_RING_BUFFER) += lis3l02dq_ring.o
+obj-$(CONFIG_LIS3L02DQ)	+= lis3l02dq.o
+
+sca3000-y		:= sca3000_core.o sca3000_ring.o
+obj-$(CONFIG_SCA3000)	+= sca3000.o
\ No newline at end of file
diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h
new file mode 100644
index 0000000..811fa05
--- /dev/null
+++ b/drivers/staging/iio/accel/accel.h
@@ -0,0 +1,167 @@
+
+#include "../sysfs.h"
+
+/* Accelerometer types of attribute */
+
+#define IIO_DEV_ATTR_ACCEL_X_OFFSET(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(accel_x_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_OFFSET(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(accel_y_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_OFFSET(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(accel_z_offset, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_X_GAIN(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_x_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y_GAIN(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_y_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z_GAIN(_mode, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(accel_z_gain, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_X(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_x, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Y(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_y, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_Z(_show, _addr)			\
+	IIO_DEVICE_ATTR(accel_z, S_IRUGO, _show, NULL, _addr)
+
+/* Thresholds are somewhat chip dependent - may need quite a few defs here */
+/* For unified thesholds (shared across all directions */
+
+/**
+ * IIO_DEV_ATTR_ACCEL_THRESH: unified threshold
+ * @_mode: read/write
+ * @_show: read detector threshold value
+ * @_store: write detector theshold value
+ * @_addr: driver specific data, typically a register address
+ *
+ * This one is for cases where as single threshold covers all directions
+ **/
+#define IIO_DEV_ATTR_ACCEL_THRESH(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(thresh, _mode, _show, _store, _addr)
+
+/**
+ * IIO_DEV_ATTR_ACCEL_THRESH_X: independant direction threshold, x axis
+ * @_mode: readable / writable
+ * @_show: read x axis detector theshold value
+ * @_store: write x axis detector threshold value
+ * @_addr: device driver dependant, typically a register address
+ **/
+#define IIO_DEV_ATTR_ACCEL_THRESH_X(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(thresh_accel_x, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_THRESH_Y(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(thresh_accel_y, _mode, _show, _store, _addr)
+
+#define IIO_DEV_ATTR_ACCEL_THRESH_Z(_mode, _show, _store, _addr)	\
+	IIO_DEVICE_ATTR(thresh_accel_z, _mode, _show, _store, _addr)
+
+
+/**
+ * IIO_EVENT_ATTR_ACCEL_X_HIGH: threshold event, x acceleration
+ * @_show: read x acceleration high threshold
+ * @_store: write x acceleration high threshold
+ * @_mask: device dependant, typically a bit mask
+ * @_handler: the iio_handler associated with this attribute
+ **/
+#define IIO_EVENT_ATTR_ACCEL_X_HIGH(_show, _store, _mask, _handler)	\
+	IIO_EVENT_ATTR(accel_x_high, _show, _store, _mask, _handler)
+
+/**
+ * IIO_EVENT_ATTR_ACCEL_X_HIGH_SH: threshold event, x accel high, shared handler
+ * @_evlist: event list used to share the handler
+ * @_show: attribute read
+ * @_store: attribute write
+ * @_mask: driver specific data, typically a bit mask
+ **/
+#define IIO_EVENT_ATTR_ACCEL_X_HIGH_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(accel_x_high, _evlist, _show, _store, _mask)
+
+/**
+ * IIO_EVENT_CODE_ACCEL_X_HIGH - event code for x axis high accel threshold
+ **/
+#define IIO_EVENT_CODE_ACCEL_X_HIGH IIO_EVENT_CODE_ACCEL_BASE
+
+#define IIO_EVENT_ATTR_ACCEL_Y_HIGH(_show, _store, _mask, _handler)	\
+	IIO_EVENT_ATTR(accel_y_high, _show, _store, _mask, _handler)
+
+#define IIO_EVENT_ATTR_ACCEL_Y_HIGH_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(accel_y_high, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Y_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 1)
+
+#define IIO_EVENT_ATTR_ACCEL_Z_HIGH(_show, _store, _mask, _handler)	\
+	IIO_EVENT_ATTR(accel_z_high, _show, _store, _mask, _handler)
+
+#define IIO_EVENT_ATTR_ACCEL_Z_HIGH_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(accel_z_high, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Z_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 2)
+
+#define IIO_EVENT_ATTR_ACCEL_X_LOW(_show, _store, _mask, _handler)	\
+	IIO_EVENT_ATTR(accel_x_low, _show, _store, _mask, _handler)
+
+#define IIO_EVENT_ATTR_ACCEL_X_LOW_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(accel_x_low, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_X_LOW (IIO_EVENT_CODE_ACCEL_BASE + 3)
+
+#define IIO_EVENT_ATTR_ACCEL_Y_LOW(_show, _store, _mask, _handler) \
+	IIO_EVENT_ATTR(accel_y_low, _show, _store, _mask, _handler)
+
+#define IIO_EVENT_ATTR_ACCEL_Y_LOW_SH(_evlist, _show, _store, _mask)\
+	IIO_EVENT_ATTR_SH(accel_y_low, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Y_LOW (IIO_EVENT_CODE_ACCEL_BASE + 4)
+
+#define IIO_EVENT_ATTR_ACCEL_Z_LOW(_show, _store, _mask, _handler)	\
+	IIO_EVENT_ATTR(accel_z_low, _show, _store, _mask, _handler)
+
+#define IIO_EVENT_ATTR_ACCEL_Z_LOW_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(accel_z_low, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Z_LOW (IIO_EVENT_CODE_ACCEL_BASE + 5)
+
+#define IIO_EVENT_ATTR_FREE_FALL_DETECT(_show, _store, _mask, _handler)	\
+	IIO_EVENT_ATTR(free_fall, _show, _store, _mask, _handler)
+
+#define IIO_EVENT_ATTR_FREE_FALL_DETECT_SH(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(free_fall, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_FREE_FALL (IIO_EVENT_CODE_ACCEL_BASE + 6)
+
+
+#define IIO_EVENT_ATTR_ACCEL_X_ROC_HIGH_SH(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(accel_x_roc_high, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_X_ROC_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 10)
+
+#define IIO_EVENT_ATTR_ACCEL_X_ROC_LOW_SH(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(accel_x_roc_low, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_X_ROC_LOW (IIO_EVENT_CODE_ACCEL_BASE + 11)
+
+#define IIO_EVENT_ATTR_ACCEL_Y_ROC_HIGH_SH(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(accel_y_roc_high, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Y_ROC_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 12)
+
+#define IIO_EVENT_ATTR_ACCEL_Y_ROC_LOW_SH(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(accel_y_roc_low, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Y_ROC_LOW (IIO_EVENT_CODE_ACCEL_BASE + 13)
+
+#define IIO_EVENT_ATTR_ACCEL_Z_ROC_HIGH_SH(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(accel_z_roc_high, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Z_ROC_HIGH (IIO_EVENT_CODE_ACCEL_BASE + 14)
+
+#define IIO_EVENT_ATTR_ACCEL_Z_ROC_LOW_SH(_evlist, _show, _store, _mask) \
+	IIO_EVENT_ATTR_SH(accel_z_roc_low, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_ACCEL_Z_ROC_LOW (IIO_EVENT_CODE_ACCEL_BASE + 15)
diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c
new file mode 100644
index 0000000..33d16b6
--- /dev/null
+++ b/drivers/staging/iio/accel/kxsd9.c
@@ -0,0 +1,395 @@
+/*
+ * kxsd9.c	simple support for the Kionix KXSD9 3D
+ *		accelerometer.
+ *
+ * Copyright (c) 2008-2009 Jonathan Cameron <jic23@cam.ac.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
+ * published by the Free Software Foundation.
+ *
+ * The i2c interface is very similar, so shouldn't be a problem once
+ * I have a suitable wire made up.
+ *
+ * TODO:	Support the motion detector
+ *		Uses register address incrementing so could have a
+ *		heavily optimized ring buffer access function.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../adc/adc.h"
+#include "accel.h"
+
+#define KXSD9_REG_X		0x00
+#define KXSD9_REG_Y		0x02
+#define KXSD9_REG_Z		0x04
+#define KXSD9_REG_AUX		0x06
+#define KXSD9_REG_RESET		0x0a
+#define KXSD9_REG_CTRL_C	0x0c
+
+#define KXSD9_FS_8		0x00
+#define KXSD9_FS_6		0x01
+#define KXSD9_FS_4		0x02
+#define KXSD9_FS_2		0x03
+#define KXSD9_FS_MASK		0x03
+
+#define KXSD9_REG_CTRL_B	0x0d
+#define KXSD9_REG_CTRL_A	0x0e
+
+#define KXSD9_READ(a) (0x80 | (a))
+#define KXSD9_WRITE(a) (a)
+
+#define IIO_DEV_ATTR_ACCEL_SET_RANGE(_mode, _show, _store)	\
+	IIO_DEVICE_ATTR(accel_range, _mode, _show, _store, 0)
+
+#define KXSD9_STATE_RX_SIZE 2
+#define KXSD9_STATE_TX_SIZE 4
+/**
+ * struct kxsd9_state - device related storage
+ * @buf_lock:	protect the rx and tx buffers.
+ * @indio_dev:	associated industrial IO device
+ * @us:		spi device
+ * @rx:		single rx buffer storage
+ * @tx:		single tx buffer storage
+ **/
+struct kxsd9_state {
+	struct mutex buf_lock;
+	struct iio_dev *indio_dev;
+	struct spi_device *us;
+	u8 *rx;
+	u8 *tx;
+};
+
+/* This may want to move to mili g to allow for non integer ranges */
+static ssize_t kxsd9_read_accel_range(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	int ret;
+	ssize_t len = 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct kxsd9_state *st = indio_dev->dev_data;
+	struct spi_transfer xfer = {
+		.bits_per_word = 8,
+		.len = 2,
+		.cs_change = 1,
+		.tx_buf = st->tx,
+		.rx_buf = st->rx,
+	};
+	struct spi_message msg;
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C);
+	st->tx[1] = 0;
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		goto error_ret;
+
+	switch (st->rx[1] & KXSD9_FS_MASK) {
+	case KXSD9_FS_8:
+		len += sprintf(buf, "8\n");
+		break;
+	case KXSD9_FS_6:
+		len += sprintf(buf, "6\n");
+		break;
+	case KXSD9_FS_4:
+		len += sprintf(buf, "4\n");
+		break;
+	case KXSD9_FS_2:
+		len += sprintf(buf, "2\n");
+		break;
+	}
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+
+	return ret ? ret : len;
+}
+static ssize_t kxsd9_write_accel_range(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	long readin;
+	struct spi_message msg;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct kxsd9_state *st = indio_dev->dev_data;
+	u8 val;
+	struct spi_transfer xfers[] = {
+		{
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+		}, {
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.tx_buf = st->tx,
+		},
+	};
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+	switch (readin) {
+	case 8:
+		val = KXSD9_FS_8;
+		break;
+	case 6:
+		val = KXSD9_FS_6;
+		break;
+	case 4:
+		val = KXSD9_FS_4;
+		break;
+	case 2:
+		val = KXSD9_FS_2;
+		break;
+	default:
+		return -EINVAL;
+	}
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C);
+	st->tx[1] = 0;
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		goto error_ret;
+	st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
+	st->tx[1] = (st->rx[1] & ~KXSD9_FS_MASK) | val;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret ? ret : len;
+}
+static ssize_t kxsd9_read_accel(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct spi_message msg;
+	int ret;
+	ssize_t len = 0;
+	u16 val;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct kxsd9_state *st = indio_dev->dev_data;
+	struct spi_transfer xfers[] = {
+		{
+			.bits_per_word = 8,
+			.len = 1,
+			.cs_change = 0,
+			.delay_usecs = 200,
+			.tx_buf = st->tx,
+		}, {
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.rx_buf = st->rx,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = KXSD9_READ(this_attr->address);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		goto error_ret;
+	val = (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0);
+	len = sprintf(buf, "%d\n", val);
+error_ret:
+	mutex_unlock(&st->buf_lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEV_ATTR_ACCEL_X(kxsd9_read_accel, KXSD9_REG_X);
+static IIO_DEV_ATTR_ACCEL_Y(kxsd9_read_accel, KXSD9_REG_Y);
+static IIO_DEV_ATTR_ACCEL_Z(kxsd9_read_accel, KXSD9_REG_Z);
+static IIO_DEV_ATTR_ADC(0, kxsd9_read_accel, KXSD9_REG_AUX);
+static IIO_DEV_ATTR_ACCEL_SET_RANGE(S_IRUGO | S_IWUSR,
+				    kxsd9_read_accel_range,
+				    kxsd9_write_accel_range);
+
+static struct attribute *kxsd9_attributes[] = {
+	&iio_dev_attr_accel_x.dev_attr.attr,
+	&iio_dev_attr_accel_y.dev_attr.attr,
+	&iio_dev_attr_accel_z.dev_attr.attr,
+	&iio_dev_attr_adc_0.dev_attr.attr,
+	&iio_dev_attr_accel_range.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group kxsd9_attribute_group = {
+	.attrs = kxsd9_attributes,
+};
+
+static int __devinit kxsd9_power_up(struct spi_device *spi)
+{
+	int ret;
+	struct spi_transfer xfers[2] = {
+		{
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		},
+	};
+	struct spi_message msg;
+	u8 *tx2;
+	u8 *tx = kmalloc(2, GFP_KERNEL);
+
+	if (tx == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	tx2 = kmalloc(2, GFP_KERNEL);
+	if (tx2 == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+	tx[0] = 0x0d;
+	tx[1] = 0x40;
+
+	tx2[0] = 0x0c;
+	tx2[1] = 0x9b;
+
+	xfers[0].tx_buf = tx;
+	xfers[1].tx_buf = tx2;
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(spi, &msg);
+
+	kfree(tx2);
+error_free_tx:
+	kfree(tx);
+error_ret:
+	return ret;
+
+};
+
+static int __devinit kxsd9_probe(struct spi_device *spi)
+{
+
+	struct kxsd9_state *st;
+	int ret = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	st->rx = kmalloc(sizeof(*st->rx)*KXSD9_STATE_RX_SIZE,
+			 GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kmalloc(sizeof(*st->tx)*KXSD9_STATE_TX_SIZE,
+			 GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+	st->indio_dev->dev.parent = &spi->dev;
+	/* for now */
+	st->indio_dev->num_interrupt_lines = 0;
+	st->indio_dev->event_attrs = NULL;
+
+	st->indio_dev->attrs = &kxsd9_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	spi->mode = SPI_MODE_0;
+	spi_setup(spi);
+	kxsd9_power_up(spi);
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit kxsd9_remove(struct spi_device *spi)
+{
+	struct kxsd9_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver kxsd9_driver = {
+	.driver = {
+		.name = "kxsd9",
+		.owner = THIS_MODULE,
+	},
+	.probe = kxsd9_probe,
+	.remove = __devexit_p(kxsd9_remove),
+};
+
+static __init int kxsd9_spi_init(void)
+{
+	return spi_register_driver(&kxsd9_driver);
+}
+module_init(kxsd9_spi_init);
+
+static __exit void kxsd9_spi_exit(void)
+{
+	spi_unregister_driver(&kxsd9_driver);
+}
+module_exit(kxsd9_spi_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("Kionix KXSD9 SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h
new file mode 100644
index 0000000..91a5375
--- /dev/null
+++ b/drivers/staging/iio/accel/lis3l02dq.h
@@ -0,0 +1,232 @@
+/*
+ * LISL02DQ.h -- support STMicroelectronics LISD02DQ
+ *               3d 2g Linear Accelerometers via SPI
+ *
+ * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ * Loosely based upon tle62x0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef SPI_LIS3L02DQ_H_
+#define SPI_LIS3L02DQ_H_
+#define LIS3L02DQ_READ_REG(a) ((a) | 0x80)
+#define LIS3L02DQ_WRITE_REG(a) a
+
+/* Calibration parameters */
+#define LIS3L02DQ_REG_OFFSET_X_ADDR		0x16
+#define LIS3L02DQ_REG_OFFSET_Y_ADDR		0x17
+#define LIS3L02DQ_REG_OFFSET_Z_ADDR		0x18
+
+#define LIS3L02DQ_REG_GAIN_X_ADDR		0x19
+#define LIS3L02DQ_REG_GAIN_Y_ADDR		0x1A
+#define LIS3L02DQ_REG_GAIN_Z_ADDR		0x1B
+
+/* Control Register (1 of 2) */
+#define LIS3L02DQ_REG_CTRL_1_ADDR		0x20
+/* Power ctrl - either bit set corresponds to on*/
+#define LIS3L02DQ_REG_CTRL_1_PD_ON	0xC0
+
+/* Decimation Factor  */
+#define LIS3L02DQ_DEC_MASK			0x30
+#define LIS3L02DQ_REG_CTRL_1_DF_128		0x00
+#define LIS3L02DQ_REG_CTRL_1_DF_64		0x10
+#define LIS3L02DQ_REG_CTRL_1_DF_32		0x20
+#define LIS3L02DQ_REG_CTRL_1_DF_8		(0x10 | 0x20)
+
+/* Self Test Enable */
+#define LIS3L02DQ_REG_CTRL_1_SELF_TEST_ON	0x08
+
+/* Axes enable ctrls */
+#define LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE	0x04
+#define LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE	0x02
+#define LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE	0x01
+
+/* Control Register (2 of 2) */
+#define LIS3L02DQ_REG_CTRL_2_ADDR		0x21
+
+/* Block Data Update only after MSB and LSB read */
+#define LIS3L02DQ_REG_CTRL_2_BLOCK_UPDATE	0x40
+
+/* Set to big endian output */
+#define LIS3L02DQ_REG_CTRL_2_BIG_ENDIAN		0x20
+
+/* Reboot memory content */
+#define LIS3L02DQ_REG_CTRL_2_REBOOT_MEMORY	0x10
+
+/* Interupt Enable - applies data ready to the RDY pad */
+#define LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT	0x08
+
+/* Enable Data Ready Generation - relationship with previous unclear in docs */
+#define LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION 0x04
+
+/* SPI 3 wire mode */
+#define LIS3L02DQ_REG_CTRL_2_THREE_WIRE_SPI_MODE	0x02
+
+/* Data alignment, default is 12 bit right justified
+ * - option for 16 bit left justified */
+#define LIS3L02DQ_REG_CTRL_2_DATA_ALIGNMENT_16_BIT_LEFT_JUSTIFIED	0x01
+
+/* Interupt related stuff */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_ADDR			0x23
+
+/* Switch from or combination fo conditions to and */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_BOOLEAN_AND		0x80
+
+/* Latch interupt request,
+ * if on ack must be given by reading the ack register */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC		0x40
+
+/* Z Interupt on High (above threshold)*/
+#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH	0x20
+/* Z Interupt on Low */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW	0x10
+/* Y Interupt on High */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH	0x08
+/* Y Interupt on Low */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW	0x04
+/* X Interupt on High */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH	0x02
+/* X Interupt on Low */
+#define LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW 0x01
+
+/* Register that gives description of what caused interupt
+ * - latched if set in CFG_ADDRES */
+#define LIS3L02DQ_REG_WAKE_UP_SRC_ADDR			0x24
+/* top bit ignored */
+/* Interupt Active */
+#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_ACTIVATED	0x40
+/* Interupts that have been triggered */
+#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH	0x20
+#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW	0x10
+#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH	0x08
+#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW	0x04
+#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH	0x02
+#define LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW	0x01
+
+#define LIS3L02DQ_REG_WAKE_UP_ACK_ADDR			0x25
+
+/* Status register */
+#define LIS3L02DQ_REG_STATUS_ADDR			0x27
+/* XYZ axis data overrun - first is all overrun? */
+#define LIS3L02DQ_REG_STATUS_XYZ_OVERRUN		0x80
+#define LIS3L02DQ_REG_STATUS_Z_OVERRUN			0x40
+#define LIS3L02DQ_REG_STATUS_Y_OVERRUN			0x20
+#define LIS3L02DQ_REG_STATUS_X_OVERRUN			0x10
+/* XYZ new data available - first is all 3 available? */
+#define LIS3L02DQ_REG_STATUS_XYZ_NEW_DATA 0x08
+#define LIS3L02DQ_REG_STATUS_Z_NEW_DATA			0x04
+#define LIS3L02DQ_REG_STATUS_Y_NEW_DATA			0x02
+#define LIS3L02DQ_REG_STATUS_X_NEW_DATA			0x01
+
+/* The accelerometer readings - low and high bytes.
+Form of high byte dependant on justification set in ctrl reg */
+#define LIS3L02DQ_REG_OUT_X_L_ADDR			0x28
+#define LIS3L02DQ_REG_OUT_X_H_ADDR			0x29
+#define LIS3L02DQ_REG_OUT_Y_L_ADDR			0x2A
+#define LIS3L02DQ_REG_OUT_Y_H_ADDR			0x2B
+#define LIS3L02DQ_REG_OUT_Z_L_ADDR			0x2C
+#define LIS3L02DQ_REG_OUT_Z_H_ADDR			0x2D
+
+/* Threshold values for all axes and both above and below thresholds
+ * - i.e. there is only one value */
+#define LIS3L02DQ_REG_THS_L_ADDR			0x2E
+#define LIS3L02DQ_REG_THS_H_ADDR			0x2F
+
+#define LIS3L02DQ_DEFAULT_CTRL1 (LIS3L02DQ_REG_CTRL_1_PD_ON	      \
+				 | LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE \
+				 | LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE \
+				 | LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE \
+				 | LIS3L02DQ_REG_CTRL_1_DF_128)
+
+#define LIS3L02DQ_DEFAULT_CTRL2	0
+
+#define LIS3L02DQ_MAX_TX 12
+#define LIS3L02DQ_MAX_RX 12
+/**
+ * struct lis3l02dq_state - device instance specific data
+ * @us:			actual spi_device
+ * @work_trigger_to_ring: bh for triggered event handling
+ * @work_cont_thresh: CLEAN
+ * @inter:		used to check if new interrupt has been triggered
+ * @last_timestamp:	passing timestamp from th to bh of interrupt handler
+ * @indio_dev:		industrial I/O device structure
+ * @trig:		data ready trigger registered with iio
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct lis3l02dq_state {
+	struct spi_device		*us;
+	struct work_struct		work_trigger_to_ring;
+	struct iio_work_cont		work_cont_thresh;
+	bool				inter;
+	s64				last_timestamp;
+	struct iio_dev			*indio_dev;
+	struct iio_trigger		*trig;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+int lis3l02dq_spi_read_reg_8(struct device *dev,
+			     u8 reg_address,
+			     u8 *val);
+
+int lis3l02dq_spi_write_reg_8(struct device *dev,
+			      u8 reg_address,
+			      u8 *val);
+#define LIS3L02DQ_SCAN_ACC_X 0
+#define LIS3L02DQ_SCAN_ACC_Y 1
+#define LIS3L02DQ_SCAN_ACC_Z 2
+
+
+#ifdef CONFIG_IIO_RING_BUFFER
+/* At the moment triggers are only used for ring buffer
+ * filling. This may change!
+ */
+void lis3l02dq_remove_trigger(struct iio_dev *indio_dev);
+int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
+
+ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf);
+
+
+int lis3l02dq_configure_ring(struct iio_dev *indio_dev);
+void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev);
+
+int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring);
+void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring);
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev) {};
+static inline int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
+{
+	return 0;
+};
+
+static inline ssize_t
+lis3l02dq_read_accel_from_ring(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	return 0;
+};
+
+static int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
+{
+	return 0;
+};
+static inline void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
+{};
+static inline int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+};
+static inline void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring) {};
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* SPI_LIS3L02DQ_H_ */
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
new file mode 100644
index 0000000..f008837
--- /dev/null
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -0,0 +1,926 @@
+/*
+ * lis3l02dq.c	support STMicroelectronics LISD02DQ
+ *		3d 2g Linear Accelerometers via SPI
+ *
+ * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.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
+ * published by the Free Software Foundation.
+ *
+ * Settings:
+ * 16 bit left justified mode used.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "accel.h"
+
+#include "lis3l02dq.h"
+
+/* At the moment the spi framework doesn't allow global setting of cs_change.
+ * It's in the likely to be added comment at the top of spi.h.
+ * This means that use cannot be made of spi_write etc.
+ */
+
+/**
+ * lis3l02dq_spi_read_reg_8() - read single byte from a single register
+ * @dev: device asosciated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the register to be read
+ * @val: pass back the resulting value
+ **/
+int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfer = {
+		.tx_buf = st->tx,
+		.rx_buf = st->rx,
+		.bits_per_word = 8,
+		.len = 2,
+		.cs_change = 1,
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = LIS3L02DQ_READ_REG(reg_address);
+	st->tx[1] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret = spi_sync(st->us, &msg);
+	*val = st->rx[1];
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * lis3l02dq_spi_write_reg_8() - write single byte to a register
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the register to be writen
+ * @val: the value to write
+ **/
+int lis3l02dq_spi_write_reg_8(struct device *dev,
+			      u8 reg_address,
+			      u8 *val)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfer = {
+		.tx_buf = st->tx,
+		.bits_per_word = 8,
+		.len = 2,
+		.cs_change = 1,
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
+	st->tx[1] = *val;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+	ret =  spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * lisl302dq_spi_write_reg_s16() - write 2 bytes to a pair of registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: value to be written
+ **/
+static int lis3l02dq_spi_write_reg_s16(struct device *dev,
+				       u8 lower_reg_address,
+				       s16 value)
+{
+	int ret;
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+	struct spi_transfer xfers[] = { {
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.tx_buf = st->tx + 2,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = LIS3L02DQ_WRITE_REG(lower_reg_address);
+	st->tx[1] = value & 0xFF;
+	st->tx[2] = LIS3L02DQ_WRITE_REG(lower_reg_address + 1);
+	st->tx[3] = (value >> 8) & 0xFF;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+
+	return ret;
+}
+
+/**
+ * lisl302dq_spi_read_reg_s16() - write 2 bytes to a pair of registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @reg_address: the address of the lower of the two registers. Second register
+ *               is assumed to have address one greater.
+ * @val: somewhere to pass back the value read
+ **/
+static int lis3l02dq_spi_read_reg_s16(struct device *dev,
+				      u8 lower_reg_address,
+				      s16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = { {
+			.tx_buf = st->tx,
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+		}, {
+			.tx_buf = st->tx + 2,
+			.rx_buf = st->rx + 2,
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = LIS3L02DQ_READ_REG(lower_reg_address);
+	st->tx[1] = 0;
+	st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address+1);
+	st->tx[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem when reading 16 bit register");
+		goto error_ret;
+	}
+	*val = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+/**
+ * lis3l02dq_read_signed() - attribute function used for 8 bit signed values
+ * @dev: the child device associated with the iio_dev or iio_trigger
+ * @attr: the attribute being processed
+ * @buf: buffer into which put the output string
+ **/
+static ssize_t lis3l02dq_read_signed(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
+{
+	int ret;
+	s8 val;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = lis3l02dq_spi_read_reg_8(dev, this_attr->address, (u8 *)&val);
+
+	return ret ? ret : sprintf(buf, "%d\n", val);
+}
+
+static ssize_t lis3l02dq_read_unsigned(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	int ret;
+	u8 val;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = lis3l02dq_spi_read_reg_8(dev, this_attr->address, &val);
+
+	return ret ? ret : sprintf(buf, "%d\n", val);
+}
+
+static ssize_t lis3l02dq_write_signed(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	long valin;
+	s8 val;
+	int ret;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = strict_strtol(buf, 10, &valin);
+	if (ret)
+		goto error_ret;
+	val = valin;
+	ret = lis3l02dq_spi_write_reg_8(dev, this_attr->address, (u8 *)&val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t lis3l02dq_write_unsigned(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf,
+					size_t len)
+{
+	int ret;
+	ulong valin;
+	u8 val;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = strict_strtoul(buf, 10, &valin);
+	if (ret)
+		goto err_ret;
+	val = valin;
+	ret = lis3l02dq_spi_write_reg_8(dev, this_attr->address, &val);
+
+err_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t lis3l02dq_read_16bit_signed(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	int ret;
+	s16 val = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = lis3l02dq_spi_read_reg_s16(dev, this_attr->address, &val);
+
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t lis3l02dq_read_accel(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	ssize_t ret;
+
+	/* Take the iio_dev status lock */
+	mutex_lock(&indio_dev->mlock);
+	if (indio_dev->currentmode == INDIO_RING_TRIGGERED)
+		ret = lis3l02dq_read_accel_from_ring(dev, attr, buf);
+	else
+		ret =  lis3l02dq_read_16bit_signed(dev, attr, buf);
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret;
+}
+
+static ssize_t lis3l02dq_write_16bit_signed(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf,
+					    size_t len)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = lis3l02dq_spi_write_reg_s16(dev, this_attr->address, val);
+
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t lis3l02dq_read_frequency(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	int ret, len = 0;
+	s8 t;
+	ret = lis3l02dq_spi_read_reg_8(dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       (u8 *)&t);
+	if (ret)
+		return ret;
+	t &= LIS3L02DQ_DEC_MASK;
+	switch (t) {
+	case LIS3L02DQ_REG_CTRL_1_DF_128:
+		len = sprintf(buf, "280\n");
+		break;
+	case LIS3L02DQ_REG_CTRL_1_DF_64:
+		len = sprintf(buf, "560\n");
+		break;
+	case LIS3L02DQ_REG_CTRL_1_DF_32:
+		len = sprintf(buf, "1120\n");
+		break;
+	case LIS3L02DQ_REG_CTRL_1_DF_8:
+		len = sprintf(buf, "4480\n");
+		break;
+	}
+	return len;
+}
+
+static ssize_t lis3l02dq_write_frequency(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf,
+					 size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	long val;
+	int ret;
+	u8 t;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&indio_dev->mlock);
+	ret = lis3l02dq_spi_read_reg_8(dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       &t);
+	if (ret)
+		goto error_ret_mutex;
+	/* Wipe the bits clean */
+	t &= ~LIS3L02DQ_DEC_MASK;
+	switch (val) {
+	case 280:
+		t |= LIS3L02DQ_REG_CTRL_1_DF_128;
+		break;
+	case 560:
+		t |= LIS3L02DQ_REG_CTRL_1_DF_64;
+		break;
+	case 1120:
+		t |= LIS3L02DQ_REG_CTRL_1_DF_32;
+		break;
+	case 4480:
+		t |= LIS3L02DQ_REG_CTRL_1_DF_8;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error_ret_mutex;
+	};
+
+	ret = lis3l02dq_spi_write_reg_8(dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					&t);
+
+error_ret_mutex:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
+static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
+{
+	int ret;
+	u8 val, valtest;
+
+	st->us->mode = SPI_MODE_3;
+
+	spi_setup(st->us);
+
+	val = LIS3L02DQ_DEFAULT_CTRL1;
+	/* Write suitable defaults to ctrl1 */
+	ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					&val);
+	if (ret) {
+		dev_err(&st->us->dev, "problem with setup control register 1");
+		goto err_ret;
+	}
+	/* Repeat as sometimes doesn't work first time?*/
+	ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					&val);
+	if (ret) {
+		dev_err(&st->us->dev, "problem with setup control register 1");
+		goto err_ret;
+	}
+
+	/* Read back to check this has worked acts as loose test of correct
+	 * chip */
+	ret = lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       &valtest);
+	if (ret || (valtest != val)) {
+		dev_err(&st->indio_dev->dev, "device not playing ball");
+		ret = -EINVAL;
+		goto err_ret;
+	}
+
+	val = LIS3L02DQ_DEFAULT_CTRL2;
+	ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+					LIS3L02DQ_REG_CTRL_2_ADDR,
+					&val);
+	if (ret) {
+		dev_err(&st->us->dev, "problem with setup control register 2");
+		goto err_ret;
+	}
+
+	val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
+	ret = lis3l02dq_spi_write_reg_8(&st->indio_dev->dev,
+					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+					&val);
+	if (ret)
+		dev_err(&st->us->dev, "problem with interrupt cfg register");
+err_ret:
+
+	return ret;
+}
+
+static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
+				   lis3l02dq_read_signed,
+				   lis3l02dq_write_signed,
+				   LIS3L02DQ_REG_OFFSET_X_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
+				   lis3l02dq_read_signed,
+				   lis3l02dq_write_signed,
+				   LIS3L02DQ_REG_OFFSET_Y_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
+				   lis3l02dq_read_signed,
+				   lis3l02dq_write_signed,
+				   LIS3L02DQ_REG_OFFSET_Z_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_X_GAIN(S_IWUSR | S_IRUGO,
+				 lis3l02dq_read_unsigned,
+				 lis3l02dq_write_unsigned,
+				 LIS3L02DQ_REG_GAIN_X_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_Y_GAIN(S_IWUSR | S_IRUGO,
+				 lis3l02dq_read_unsigned,
+				 lis3l02dq_write_unsigned,
+				 LIS3L02DQ_REG_GAIN_Y_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_Z_GAIN(S_IWUSR | S_IRUGO,
+				 lis3l02dq_read_unsigned,
+				 lis3l02dq_write_unsigned,
+				 LIS3L02DQ_REG_GAIN_Z_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_THRESH(S_IWUSR | S_IRUGO,
+				 lis3l02dq_read_16bit_signed,
+				 lis3l02dq_write_16bit_signed,
+				 LIS3L02DQ_REG_THS_L_ADDR);
+
+/* RFC The reading method for these will change depending on whether
+ * ring buffer capture is in use. Is it worth making these take two
+ * functions and let the core handle which to call, or leave as in this
+ * driver where it is the drivers problem to manage this?
+ */
+
+static IIO_DEV_ATTR_ACCEL_X(lis3l02dq_read_accel,
+			    LIS3L02DQ_REG_OUT_X_L_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_Y(lis3l02dq_read_accel,
+			    LIS3L02DQ_REG_OUT_Y_L_ADDR);
+
+static IIO_DEV_ATTR_ACCEL_Z(lis3l02dq_read_accel,
+			    LIS3L02DQ_REG_OUT_Z_L_ADDR);
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+			      lis3l02dq_read_frequency,
+			      lis3l02dq_write_frequency);
+
+static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("280 560 1120 4480");
+
+static ssize_t lis3l02dq_read_interrupt_config(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf)
+{
+	int ret;
+	s8 val;
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+
+	ret = lis3l02dq_spi_read_reg_8(dev,
+				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+				       (u8 *)&val);
+
+	return ret ? ret : sprintf(buf, "%d\n",
+				   (val & this_attr->mask) ? 1 : 0);;
+}
+
+static ssize_t lis3l02dq_write_interrupt_config(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len)
+{
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	int ret, currentlyset, changed = 0;
+	u8 valold, controlold;
+	bool val;
+
+	val = !(buf[0] == '0');
+
+	mutex_lock(&indio_dev->mlock);
+	/* read current value */
+	ret = lis3l02dq_spi_read_reg_8(dev,
+				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+				       &valold);
+	if (ret)
+		goto error_mutex_unlock;
+
+	/* read current control */
+	ret = lis3l02dq_spi_read_reg_8(dev,
+				       LIS3L02DQ_REG_CTRL_2_ADDR,
+				       &controlold);
+	if (ret)
+		goto error_mutex_unlock;
+	currentlyset = !!(valold & this_attr->mask);
+	if (val == false && currentlyset) {
+		valold &= ~this_attr->mask;
+		changed = 1;
+		iio_remove_event_from_list(this_attr->listel,
+						 &indio_dev->interrupts[0]
+						 ->ev_list);
+	} else if (val == true && !currentlyset) {
+		changed = 1;
+		valold |= this_attr->mask;
+		iio_add_event_to_list(this_attr->listel,
+					    &indio_dev->interrupts[0]->ev_list);
+	}
+
+	if (changed) {
+		ret = lis3l02dq_spi_write_reg_8(dev,
+						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+						&valold);
+		if (ret)
+			goto error_mutex_unlock;
+		/* This always enables the interrupt, even if we've remove the
+		 * last thing using it. For this device we can use the reference
+		 * count on the handler to tell us if anyone wants the interrupt
+		 */
+		controlold = this_attr->listel->refcount ?
+			(controlold | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
+			(controlold & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
+		ret = lis3l02dq_spi_write_reg_8(dev,
+						LIS3L02DQ_REG_CTRL_2_ADDR,
+						&controlold);
+		if (ret)
+			goto error_mutex_unlock;
+	}
+error_mutex_unlock:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
+
+static int lis3l02dq_thresh_handler_th(struct iio_dev *dev_info,
+				       int index,
+				       s64 timestamp,
+				       int no_test)
+{
+	struct lis3l02dq_state *st = dev_info->dev_data;
+
+	/* Stash the timestamp somewhere convenient for the bh */
+	st->last_timestamp = timestamp;
+	schedule_work(&st->work_cont_thresh.ws);
+
+	return 0;
+}
+
+
+/* Unforunately it appears the interrupt won't clear unless you read from the
+ * src register.
+ */
+static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
+{
+	struct iio_work_cont *wc
+		= container_of(work_s, struct iio_work_cont, ws_nocheck);
+	struct lis3l02dq_state *st = wc->st;
+	u8 t;
+
+	lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
+				 &t);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_Z_HIGH,
+			       st->last_timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_Z_LOW,
+			       st->last_timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_Y_HIGH,
+			       st->last_timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_Y_LOW,
+			       st->last_timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_X_HIGH,
+			       st->last_timestamp);
+
+	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_X_LOW,
+			       st->last_timestamp);
+	/* reenable the irq */
+	enable_irq(st->us->irq);
+	/* Ack and allow for new interrupts */
+	lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+				 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
+				 &t);
+
+	return;
+}
+
+/* A shared handler for a number of threshold types */
+IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th);
+
+IIO_EVENT_ATTR_ACCEL_X_HIGH_SH(iio_event_threshold,
+			       lis3l02dq_read_interrupt_config,
+			       lis3l02dq_write_interrupt_config,
+			       LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH);
+
+IIO_EVENT_ATTR_ACCEL_Y_HIGH_SH(iio_event_threshold,
+			       lis3l02dq_read_interrupt_config,
+			       lis3l02dq_write_interrupt_config,
+			       LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH);
+
+IIO_EVENT_ATTR_ACCEL_Z_HIGH_SH(iio_event_threshold,
+			       lis3l02dq_read_interrupt_config,
+			       lis3l02dq_write_interrupt_config,
+			       LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH);
+
+IIO_EVENT_ATTR_ACCEL_X_LOW_SH(iio_event_threshold,
+			      lis3l02dq_read_interrupt_config,
+			      lis3l02dq_write_interrupt_config,
+			      LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW);
+
+IIO_EVENT_ATTR_ACCEL_Y_LOW_SH(iio_event_threshold,
+			      lis3l02dq_read_interrupt_config,
+			      lis3l02dq_write_interrupt_config,
+			      LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW);
+
+IIO_EVENT_ATTR_ACCEL_Z_LOW_SH(iio_event_threshold,
+			      lis3l02dq_read_interrupt_config,
+			      lis3l02dq_write_interrupt_config,
+			      LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW);
+
+static struct attribute *lis3l02dq_event_attributes[] = {
+	&iio_event_attr_accel_x_high.dev_attr.attr,
+	&iio_event_attr_accel_y_high.dev_attr.attr,
+	&iio_event_attr_accel_z_high.dev_attr.attr,
+	&iio_event_attr_accel_x_low.dev_attr.attr,
+	&iio_event_attr_accel_y_low.dev_attr.attr,
+	&iio_event_attr_accel_z_low.dev_attr.attr,
+	NULL
+};
+
+static struct attribute_group lis3l02dq_event_attribute_group = {
+	.attrs = lis3l02dq_event_attributes,
+};
+
+static IIO_CONST_ATTR(name, "lis3l02dq");
+
+static struct attribute *lis3l02dq_attributes[] = {
+	&iio_dev_attr_accel_x_offset.dev_attr.attr,
+	&iio_dev_attr_accel_y_offset.dev_attr.attr,
+	&iio_dev_attr_accel_z_offset.dev_attr.attr,
+	&iio_dev_attr_accel_x_gain.dev_attr.attr,
+	&iio_dev_attr_accel_y_gain.dev_attr.attr,
+	&iio_dev_attr_accel_z_gain.dev_attr.attr,
+	&iio_dev_attr_thresh.dev_attr.attr,
+	&iio_dev_attr_accel_x.dev_attr.attr,
+	&iio_dev_attr_accel_y.dev_attr.attr,
+	&iio_dev_attr_accel_z.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_available_sampling_frequency.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group lis3l02dq_attribute_group = {
+	.attrs = lis3l02dq_attributes,
+};
+
+static int __devinit lis3l02dq_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct lis3l02dq_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* this is only used tor removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*LIS3L02DQ_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*LIS3L02DQ_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &lis3l02dq_event_attribute_group;
+	st->indio_dev->attrs = &lis3l02dq_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = lis3l02dq_configure_ring(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_unreg_ring_funcs;
+	regdone = 1;
+
+	ret = lis3l02dq_initialize_ring(st->indio_dev->ring);
+	if (ret) {
+		printk(KERN_ERR "failed to initialize the ring\n");
+		goto error_unreg_ring_funcs;
+	}
+
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+		/* This is a little unusual, in that the device seems
+		   to need a full read of the interrupt source reg before
+		   the interrupt will reset.
+		   Hence the two handlers are the same */
+		iio_init_work_cont(&st->work_cont_thresh,
+				   lis3l02dq_thresh_handler_bh_no_check,
+				   lis3l02dq_thresh_handler_bh_no_check,
+				   LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
+				   0,
+				   st);
+		st->inter = 0;
+		ret = iio_register_interrupt_line(spi->irq,
+						  st->indio_dev,
+						  0,
+						  IRQF_TRIGGER_RISING,
+						  "lis3l02dq");
+		if (ret)
+			goto error_uninitialize_ring;
+
+		ret = lis3l02dq_probe_trigger(st->indio_dev);
+		if (ret)
+			goto error_unregister_line;
+	}
+
+	/* Get the device into a sane initial state */
+	ret = lis3l02dq_initial_setup(st);
+	if (ret)
+		goto error_remove_trigger;
+	return 0;
+
+error_remove_trigger:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		lis3l02dq_remove_trigger(st->indio_dev);
+error_unregister_line:
+	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_uninitialize_ring:
+	lis3l02dq_uninitialize_ring(st->indio_dev->ring);
+error_unreg_ring_funcs:
+	lis3l02dq_unconfigure_ring(st->indio_dev);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+/* Power down the device */
+static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
+{
+	int ret;
+	struct lis3l02dq_state *st = indio_dev->dev_data;
+	u8 val = 0;
+
+	mutex_lock(&indio_dev->mlock);
+	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					&val);
+	if (ret) {
+		dev_err(&st->us->dev, "problem with turning device off: ctrl1");
+		goto err_ret;
+	}
+
+	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+					LIS3L02DQ_REG_CTRL_2_ADDR,
+					&val);
+	if (ret)
+		dev_err(&st->us->dev, "problem with turning device off: ctrl2");
+err_ret:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
+}
+
+/* fixme, confirm ordering in this function */
+static int lis3l02dq_remove(struct spi_device *spi)
+{
+	int ret;
+	struct lis3l02dq_state *st = spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+
+	ret = lis3l02dq_stop_device(indio_dev);
+	if (ret)
+		goto err_ret;
+
+	flush_scheduled_work();
+
+	lis3l02dq_remove_trigger(indio_dev);
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+
+	lis3l02dq_uninitialize_ring(indio_dev->ring);
+	lis3l02dq_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+
+err_ret:
+	return ret;
+}
+
+static struct spi_driver lis3l02dq_driver = {
+	.driver = {
+		.name = "lis3l02dq",
+		.owner = THIS_MODULE,
+	},
+	.probe = lis3l02dq_probe,
+	.remove = __devexit_p(lis3l02dq_remove),
+};
+
+static __init int lis3l02dq_init(void)
+{
+	return spi_register_driver(&lis3l02dq_driver);
+}
+module_init(lis3l02dq_init);
+
+static __exit void lis3l02dq_exit(void)
+{
+	spi_unregister_driver(&lis3l02dq_driver);
+}
+module_exit(lis3l02dq_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c
new file mode 100644
index 0000000..a6b7c72
--- /dev/null
+++ b/drivers/staging/iio/accel/lis3l02dq_ring.c
@@ -0,0 +1,600 @@
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_sw.h"
+#include "accel.h"
+#include "../trigger.h"
+#include "lis3l02dq.h"
+
+/**
+ * combine_8_to_16() utility function to munge to u8s into u16
+ **/
+static inline u16 combine_8_to_16(u8 lower, u8 upper)
+{
+	u16 _lower = lower;
+	u16 _upper = upper;
+	return _lower | (_upper << 8);
+}
+
+/**
+ * lis3l02dq_scan_el_set_state() set whether a scan contains a given channel
+ * @scan_el:	associtate iio scan element attribute
+ * @indio_dev:	the device structure
+ * @bool:	desired state
+ *
+ * mlock already held when this is called.
+ **/
+static int lis3l02dq_scan_el_set_state(struct iio_scan_el *scan_el,
+				       struct iio_dev *indio_dev,
+				       bool state)
+{
+	u8 t, mask;
+	int ret;
+
+	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       &t);
+	if (ret)
+		goto error_ret;
+	switch (scan_el->label) {
+	case LIS3L02DQ_REG_OUT_X_L_ADDR:
+		mask = LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
+		break;
+	case LIS3L02DQ_REG_OUT_Y_L_ADDR:
+		mask = LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
+		break;
+	case LIS3L02DQ_REG_OUT_Z_L_ADDR:
+		mask = LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error_ret;
+	}
+
+	if (!(mask & t) == state) {
+		if (state)
+			t |= mask;
+		else
+			t &= ~mask;
+		ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+						LIS3L02DQ_REG_CTRL_1_ADDR,
+						&t);
+	}
+error_ret:
+	return ret;
+
+}
+static IIO_SCAN_EL_C(accel_x, LIS3L02DQ_SCAN_ACC_X, IIO_SIGNED(16),
+		     LIS3L02DQ_REG_OUT_X_L_ADDR,
+		     &lis3l02dq_scan_el_set_state);
+static IIO_SCAN_EL_C(accel_y, LIS3L02DQ_SCAN_ACC_Y, IIO_SIGNED(16),
+		     LIS3L02DQ_REG_OUT_Y_L_ADDR,
+		     &lis3l02dq_scan_el_set_state);
+static IIO_SCAN_EL_C(accel_z, LIS3L02DQ_SCAN_ACC_Z, IIO_SIGNED(16),
+		     LIS3L02DQ_REG_OUT_Z_L_ADDR,
+		     &lis3l02dq_scan_el_set_state);
+static IIO_SCAN_EL_TIMESTAMP;
+
+static struct attribute *lis3l02dq_scan_el_attrs[] = {
+	&iio_scan_el_accel_x.dev_attr.attr,
+	&iio_scan_el_accel_y.dev_attr.attr,
+	&iio_scan_el_accel_z.dev_attr.attr,
+	&iio_scan_el_timestamp.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group lis3l02dq_scan_el_group = {
+	.attrs = lis3l02dq_scan_el_attrs,
+	.name = "scan_elements",
+};
+
+/**
+ * lis3l02dq_poll_func_th() top half interrupt handler called by trigger
+ * @private_data:	iio_dev
+ **/
+static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev)
+{
+  struct lis3l02dq_state *st = iio_dev_get_devdata(indio_dev);
+	st->last_timestamp = indio_dev->trig->timestamp;
+	schedule_work(&st->work_trigger_to_ring);
+	/* Indicate that this interrupt is being handled */
+
+	/* Technically this is trigger related, but without this
+	 * handler running there is currently now way for the interrupt
+	 * to clear.
+	 */
+	st->inter = 1;
+}
+
+/**
+ * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
+ **/
+static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *dev_info,
+				       int index,
+				       s64 timestamp,
+				       int no_test)
+{
+	struct lis3l02dq_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_trigger *trig = st->trig;
+
+	trig->timestamp = timestamp;
+	iio_trigger_poll(trig);
+
+	return IRQ_HANDLED;
+}
+
+/* This is an event as it is a response to a physical interrupt */
+IIO_EVENT_SH(data_rdy_trig, &lis3l02dq_data_rdy_trig_poll);
+
+/**
+ * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
+ **/
+ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct iio_scan_el *el = NULL;
+	int ret, len = 0, i = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	s16 *data;
+
+	while (dev_info->scan_el_attrs->attrs[i]) {
+		el = to_iio_scan_el((struct device_attribute *)
+				    (dev_info->scan_el_attrs->attrs[i]));
+		/* label is in fact the address */
+		if (el->label == this_attr->address)
+			break;
+		i++;
+	}
+	if (!dev_info->scan_el_attrs->attrs[i]) {
+		ret = -EINVAL;
+		goto error_ret;
+	}
+	/* If this element is in the scan mask */
+	ret = iio_scan_mask_query(dev_info, el->number);
+	if (ret < 0)
+		goto error_ret;
+	if (ret) {
+		data = kmalloc(dev_info->ring->access.get_bpd(dev_info->ring),
+			       GFP_KERNEL);
+		if (data == NULL)
+			return -ENOMEM;
+		ret = dev_info->ring->access.read_last(dev_info->ring,
+						      (u8 *)data);
+		if (ret)
+			goto error_free_data;
+	} else {
+		ret = -EINVAL;
+		goto error_ret;
+	}
+	len = iio_scan_mask_count_to_right(dev_info, el->number);
+	if (len < 0) {
+		ret = len;
+		goto error_free_data;
+	}
+	len = sprintf(buf, "ring %d\n", data[len]);
+error_free_data:
+	kfree(data);
+error_ret:
+	return ret ? ret : len;
+
+}
+
+static const u8 read_all_tx_array[] =
+{
+	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_L_ADDR), 0,
+	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_X_H_ADDR), 0,
+	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_L_ADDR), 0,
+	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Y_H_ADDR), 0,
+	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_L_ADDR), 0,
+	LIS3L02DQ_READ_REG(LIS3L02DQ_REG_OUT_Z_H_ADDR), 0,
+};
+
+/**
+ * lis3l02dq_read_all() Reads all channels currently selected
+ * @st:		device specific state
+ * @rx_array:	(dma capable) recieve array, must be at least
+ *		4*number of channels
+ **/
+int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
+{
+	struct spi_transfer *xfers;
+	struct spi_message msg;
+	int ret, i, j = 0;
+
+	xfers = kzalloc((st->indio_dev->scan_count) * 2
+			* sizeof(*xfers), GFP_KERNEL);
+	if (!xfers)
+		return -ENOMEM;
+
+	mutex_lock(&st->buf_lock);
+
+	for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
+		if (st->indio_dev->scan_mask & (1 << i)) {
+			/* lower byte */
+			xfers[j].tx_buf = st->tx + 2*j;
+			st->tx[2*j] = read_all_tx_array[i*4];
+			st->tx[2*j + 1] = 0;
+			if (rx_array)
+				xfers[j].rx_buf = rx_array + j*2;
+			xfers[j].bits_per_word = 8;
+			xfers[j].len = 2;
+			xfers[j].cs_change = 1;
+			j++;
+
+			/* upper byte */
+			xfers[j].tx_buf = st->tx + 2*j;
+			st->tx[2*j] = read_all_tx_array[i*4 + 2];
+			st->tx[2*j + 1] = 0;
+			if (rx_array)
+				xfers[j].rx_buf = rx_array + j*2;
+			xfers[j].bits_per_word = 8;
+			xfers[j].len = 2;
+			xfers[j].cs_change = 1;
+			j++;
+		}
+	}
+	/* After these are transmitted, the rx_buff should have
+	 * values in alternate bytes
+	 */
+	spi_message_init(&msg);
+	for (j = 0; j < st->indio_dev->scan_count * 2; j++)
+		spi_message_add_tail(&xfers[j], &msg);
+
+	ret = spi_sync(st->us, &msg);
+	mutex_unlock(&st->buf_lock);
+	kfree(xfers);
+
+	return ret;
+}
+
+
+/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
+ * specific to be rolled into the core.
+ */
+static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s)
+{
+	struct lis3l02dq_state *st
+		= container_of(work_s, struct lis3l02dq_state,
+			       work_trigger_to_ring);
+
+	u8 *rx_array;
+	int i = 0;
+	u16 *data;
+	size_t datasize = st->indio_dev
+		->ring->access.get_bpd(st->indio_dev->ring);
+
+	data = kmalloc(datasize , GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(&st->us->dev, "memory alloc failed in ring bh");
+		return;
+	}
+	/* Due to interleaved nature of transmission this buffer must be
+	 * twice the number of bytes, or 4 times the number of channels
+	 */
+	rx_array = kmalloc(4 * (st->indio_dev->scan_count), GFP_KERNEL);
+	if (rx_array == NULL) {
+		dev_err(&st->us->dev, "memory alloc failed in ring bh");
+		kfree(data);
+		return;
+	}
+
+	/* whilst trigger specific, if this read does nto occur the data
+	   ready interrupt will not be cleared.  Need to add a mechanism
+	   to provide a dummy read function if this is not triggering on
+	   the data ready function but something else is.
+	*/
+	st->inter = 0;
+
+	if (st->indio_dev->scan_count)
+		if (lis3l02dq_read_all(st, rx_array) >= 0)
+			for (; i < st->indio_dev->scan_count; i++)
+				data[i] = combine_8_to_16(rx_array[i*4+1],
+							  rx_array[i*4+3]);
+	/* Guaranteed to be aligned with 8 byte boundary */
+	if (st->indio_dev->scan_timestamp)
+		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+
+	st->indio_dev->ring->access.store_to(st->indio_dev->ring,
+					    (u8 *)data,
+					    st->last_timestamp);
+
+	iio_trigger_notify_done(st->indio_dev->trig);
+	kfree(rx_array);
+	kfree(data);
+
+	return;
+}
+/* in these circumstances is it better to go with unaligned packing and
+ * deal with the cost?*/
+static int lis3l02dq_data_rdy_ring_preenable(struct iio_dev *indio_dev)
+{
+	size_t size;
+	/* Check if there are any scan elements enabled, if not fail*/
+	if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
+		return -EINVAL;
+
+	if (indio_dev->ring->access.set_bpd) {
+		if (indio_dev->scan_timestamp)
+			if (indio_dev->scan_count) /* Timestamp and data */
+				size = 2*sizeof(s64);
+			else /* Timestamp only  */
+				size = sizeof(s64);
+		else /* Data only */
+			size = indio_dev->scan_count*sizeof(s16);
+		indio_dev->ring->access.set_bpd(indio_dev->ring, size);
+	}
+
+	return 0;
+}
+
+static int lis3l02dq_data_rdy_ring_postenable(struct iio_dev *indio_dev)
+{
+	return indio_dev->trig
+		? iio_trigger_attach_poll_func(indio_dev->trig,
+					       indio_dev->pollfunc)
+		: 0;
+}
+
+static int lis3l02dq_data_rdy_ring_predisable(struct iio_dev *indio_dev)
+{
+	return indio_dev->trig
+		? iio_trigger_dettach_poll_func(indio_dev->trig,
+						indio_dev->pollfunc)
+		: 0;
+}
+
+
+/* Caller responsible for locking as necessary. */
+static int __lis3l02dq_write_data_ready_config(struct device *dev,
+					       struct
+					       iio_event_handler_list *list,
+					       bool state)
+{
+	int ret;
+	u8 valold;
+	bool currentlyset;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
+/* Get the current event mask register */
+	ret = lis3l02dq_spi_read_reg_8(dev,
+				       LIS3L02DQ_REG_CTRL_2_ADDR,
+				       &valold);
+	if (ret)
+		goto error_ret;
+/* Find out if data ready is already on */
+	currentlyset
+		= valold & LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
+
+/* Disable requested */
+	if (!state && currentlyset) {
+
+		valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
+		/* The double write is to overcome a hardware bug?*/
+		ret = lis3l02dq_spi_write_reg_8(dev,
+						LIS3L02DQ_REG_CTRL_2_ADDR,
+						&valold);
+		if (ret)
+			goto error_ret;
+		ret = lis3l02dq_spi_write_reg_8(dev,
+						LIS3L02DQ_REG_CTRL_2_ADDR,
+						&valold);
+		if (ret)
+			goto error_ret;
+
+		iio_remove_event_from_list(list,
+					   &indio_dev->interrupts[0]
+					   ->ev_list);
+
+/* Enable requested */
+	} else if (state && !currentlyset) {
+		/* if not set, enable requested */
+		valold |= LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
+		iio_add_event_to_list(list, &indio_dev->interrupts[0]->ev_list);
+		ret = lis3l02dq_spi_write_reg_8(dev,
+						LIS3L02DQ_REG_CTRL_2_ADDR,
+						&valold);
+		if (ret)
+			goto error_ret;
+	}
+
+	return 0;
+error_ret:
+	return ret;
+}
+
+/**
+ * lis3l02dq_data_rdy_trigger_set_state() set datardy interrupt state
+ *
+ * If disabling the interrupt also does a final read to ensure it is clear.
+ * This is only important in some cases where the scan enable elements are
+ * switched before the ring is reenabled.
+ **/
+static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
+						bool state)
+{
+	struct lis3l02dq_state *st = trig->private_data;
+	int ret = 0;
+	u8 t;
+	__lis3l02dq_write_data_ready_config(&st->indio_dev->dev,
+					    &iio_event_data_rdy_trig,
+					    state);
+	if (state == false) {
+		/* possible quirk with handler currently worked around
+		   by ensuring the work queue is empty */
+		flush_scheduled_work();
+		/* Clear any outstanding ready events */
+		ret = lis3l02dq_read_all(st, NULL);
+	}
+	lis3l02dq_spi_read_reg_8(&st->indio_dev->dev,
+				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
+				 &t);
+	return ret;
+}
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+static struct attribute *lis3l02dq_trigger_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group lis3l02dq_trigger_attr_group = {
+	.attrs = lis3l02dq_trigger_attrs,
+};
+
+/**
+ * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger
+ * @trig:	the datardy trigger
+ *
+ * As the trigger may occur on any data element being updated it is
+ * really rather likely to occur during the read from the previous
+ * trigger event.  The only way to discover if this has occured on
+ * boards not supporting level interrupts is to take a look at the line.
+ * If it is indicating another interrupt and we don't seem to have a
+ * handler looking at it, then we need to notify the core that we need
+ * to tell the triggering core to try reading all these again.
+ **/
+static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
+{
+	struct lis3l02dq_state *st = trig->private_data;
+	enable_irq(st->us->irq);
+	/* If gpio still high (or high again) */
+	if (gpio_get_value(irq_to_gpio(st->us->irq)))
+		if (st->inter == 0) {
+			/* already interrupt handler dealing with it */
+			disable_irq_nosync(st->us->irq);
+			if (st->inter == 1) {
+				/* interrupt handler snuck in between test
+				 * and disable */
+				enable_irq(st->us->irq);
+				return 0;
+			}
+			return -EAGAIN;
+		}
+	/* irq reenabled so success! */
+	return 0;
+}
+
+int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
+{
+	int ret;
+	struct lis3l02dq_state *state = indio_dev->dev_data;
+
+	state->trig = iio_allocate_trigger();
+	state->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+	if (!state->trig->name) {
+		ret = -ENOMEM;
+		goto error_free_trig;
+	}
+	snprintf((char *)state->trig->name,
+		 IIO_TRIGGER_NAME_LENGTH,
+		 "lis3l02dq-dev%d", indio_dev->id);
+	state->trig->dev.parent = &state->us->dev;
+	state->trig->owner = THIS_MODULE;
+	state->trig->private_data = state;
+	state->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
+	state->trig->try_reenable = &lis3l02dq_trig_try_reen;
+	state->trig->control_attrs = &lis3l02dq_trigger_attr_group;
+	ret = iio_trigger_register(state->trig);
+	if (ret)
+		goto error_free_trig_name;
+
+	return 0;
+
+error_free_trig_name:
+	kfree(state->trig->name);
+error_free_trig:
+	iio_free_trigger(state->trig);
+
+	return ret;
+}
+
+void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
+{
+	struct lis3l02dq_state *state = indio_dev->dev_data;
+
+	iio_trigger_unregister(state->trig);
+	kfree(state->trig->name);
+	iio_free_trigger(state->trig);
+}
+
+void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
+{
+	kfree(indio_dev->pollfunc);
+	iio_sw_rb_free(indio_dev->ring);
+}
+
+int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
+{
+	int ret = 0;
+	struct lis3l02dq_state *st = indio_dev->dev_data;
+	struct iio_ring_buffer *ring;
+	INIT_WORK(&st->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
+	/* Set default scan mode */
+
+	iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
+	iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
+	iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
+	indio_dev->scan_timestamp = true;
+
+	indio_dev->scan_el_attrs = &lis3l02dq_scan_el_group;
+
+	ring = iio_sw_rb_allocate(indio_dev);
+	if (!ring) {
+		ret = -ENOMEM;
+		return ret;
+	}
+	indio_dev->ring = ring;
+	/* Effectively select the ring buffer implementation */
+	iio_ring_sw_register_funcs(&ring->access);
+	ring->preenable = &lis3l02dq_data_rdy_ring_preenable;
+	ring->postenable = &lis3l02dq_data_rdy_ring_postenable;
+	ring->predisable = &lis3l02dq_data_rdy_ring_predisable;
+	ring->owner = THIS_MODULE;
+
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
+		goto error_iio_sw_rb_free;;
+	}
+	indio_dev->pollfunc->poll_func_main = &lis3l02dq_poll_func_th;
+	indio_dev->pollfunc->private_data = indio_dev;
+	indio_dev->modes |= INDIO_RING_TRIGGERED;
+	return 0;
+
+error_iio_sw_rb_free:
+	iio_sw_rb_free(indio_dev->ring);
+	return ret;
+}
+
+int lis3l02dq_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return iio_ring_buffer_register(ring);
+}
+
+void lis3l02dq_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+	iio_ring_buffer_unregister(ring);
+}
+
+
+int lis3l02dq_set_ring_length(struct iio_dev *indio_dev, int length)
+{
+	/* Set sensible defaults for the ring buffer */
+	if (indio_dev->ring->access.set_length)
+		return indio_dev->ring->access.set_length(indio_dev->ring, 500);
+	return 0;
+}
+
+
diff --git a/drivers/staging/iio/accel/sca3000.h b/drivers/staging/iio/accel/sca3000.h
new file mode 100644
index 0000000..29e11da
--- /dev/null
+++ b/drivers/staging/iio/accel/sca3000.h
@@ -0,0 +1,298 @@
+/*
+ * sca3000.c -- support VTI sca3000 series accelerometers
+ *              via SPI
+ *
+ * Copyright (c) 2007 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ * Partly based upon tle62x0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Initial mode is direct measurement.
+ *
+ * Untested things
+ *
+ * Temperature reading (the e05 I'm testing with doesn't have a sensor)
+ *
+ * Free fall detection mode - supported but untested as I'm not droping my
+ * dubious wire rig far enough to test it.
+ *
+ * Unsupported as yet
+ *
+ * Time stamping of data from ring. Various ideas on how to do this but none
+ * are remotely simple. Suggestions welcome.
+ *
+ * Individual enabling disabling of channels going into ring buffer
+ *
+ * Overflow handling (this is signaled for all but 8 bit ring buffer mode.)
+ *
+ * Motion detector using AND combinations of signals.
+ *
+ * Note: Be very careful about not touching an register bytes marked
+ * as reserved on the data sheet. They really mean it as changing convents of
+ * some will cause the device to lock up.
+ *
+ * Known issues - on rare occasions the interrupts lock up. Not sure why as yet.
+ * Can probably alleviate this by reading the interrupt register on start, but
+ * that is really just brushing the problem under the carpet.
+ */
+#define SCA3000_WRITE_REG(a) (((a) << 2) | 0x02)
+#define SCA3000_READ_REG(a) ((a) << 2)
+
+#define SCA3000_REG_ADDR_REVID			0x00
+#define SCA3000_REVID_MAJOR_MASK		0xf0
+#define SCA3000_REVID_MINOR_MASK		0x0f
+
+#define SCA3000_REG_ADDR_STATUS			0x02
+#define SCA3000_LOCKED				0x20
+#define SCA3000_EEPROM_CS_ERROR			0x02
+#define SCA3000_SPI_FRAME_ERROR			0x01
+
+/* All reads done using register decrement so no need to directly access LSBs */
+#define SCA3000_REG_ADDR_X_MSB			0x05
+#define SCA3000_REG_ADDR_Y_MSB			0x07
+#define SCA3000_REG_ADDR_Z_MSB			0x09
+
+#define SCA3000_REG_ADDR_RING_OUT		0x0f
+
+/* Temp read untested - the e05 doesn't have the sensor */
+#define SCA3000_REG_ADDR_TEMP_MSB		0x13
+
+#define SCA3000_REG_ADDR_MODE			0x14
+#define SCA3000_MODE_PROT_MASK			0x28
+
+#define SCA3000_RING_BUF_ENABLE			0x80
+#define SCA3000_RING_BUF_8BIT			0x40
+/* Free fall detection triggers an interrupt if the acceleration
+ * is below a threshold for equivalent of 25cm drop
+ */
+#define SCA3000_FREE_FALL_DETECT		0x10
+#define SCA3000_MEAS_MODE_NORMAL		0x00
+#define SCA3000_MEAS_MODE_OP_1			0x01
+#define SCA3000_MEAS_MODE_OP_2			0x02
+
+/* In motion detection mode the accelerations are band pass filtered
+ * (aprox 1 - 25Hz) and then a programmable theshold used to trigger
+ * and interrupt.
+ */
+#define SCA3000_MEAS_MODE_MOT_DET		0x03
+
+#define SCA3000_REG_ADDR_BUF_COUNT		0x15
+
+#define SCA3000_REG_ADDR_INT_STATUS		0x16
+
+#define SCA3000_INT_STATUS_THREE_QUARTERS	0x80
+#define SCA3000_INT_STATUS_HALF			0x40
+
+#define SCA3000_INT_STATUS_FREE_FALL		0x08
+#define SCA3000_INT_STATUS_Y_TRIGGER		0x04
+#define SCA3000_INT_STATUS_X_TRIGGER		0x02
+#define SCA3000_INT_STATUS_Z_TRIGGER		0x01
+
+/* Used to allow accesss to multiplexed registers */
+#define SCA3000_REG_ADDR_CTRL_SEL		0x18
+/* Only available for SCA3000-D03 and SCA3000-D01 */
+#define SCA3000_REG_CTRL_SEL_I2C_DISABLE	0x01
+#define SCA3000_REG_CTRL_SEL_MD_CTRL		0x02
+#define SCA3000_REG_CTRL_SEL_MD_Y_TH		0x03
+#define SCA3000_REG_CTRL_SEL_MD_X_TH		0x04
+#define SCA3000_REG_CTRL_SEL_MD_Z_TH		0x05
+/* BE VERY CAREFUL WITH THIS, IF 3 BITS ARE NOT SET the device
+   will not function */
+#define SCA3000_REG_CTRL_SEL_OUT_CTRL		0x0B
+#define SCA3000_OUT_CTRL_PROT_MASK		0xE0
+#define SCA3000_OUT_CTRL_BUF_X_EN		0x10
+#define SCA3000_OUT_CTRL_BUF_Y_EN		0x08
+#define SCA3000_OUT_CTRL_BUF_Z_EN		0x04
+#define SCA3000_OUT_CTRL_BUF_DIV_4		0x02
+#define SCA3000_OUT_CTRL_BUF_DIV_2		0x01
+
+/* Control which motion detector interrupts are on.
+ * For now only OR combinations are supported.x
+ */
+#define SCA3000_MD_CTRL_PROT_MASK		0xC0
+#define SCA3000_MD_CTRL_OR_Y			0x01
+#define SCA3000_MD_CTRL_OR_X			0x02
+#define SCA3000_MD_CTRL_OR_Z			0x04
+/* Currently unsupported */
+#define SCA3000_MD_CTRL_AND_Y			0x08
+#define SCA3000_MD_CTRL_AND_X			0x10
+#define SAC3000_MD_CTRL_AND_Z			0x20
+
+/* Some control registers of complex access methods requiring this register to
+ * be used to remove a lock.
+ */
+#define SCA3000_REG_ADDR_UNLOCK			0x1e
+
+#define SCA3000_REG_ADDR_INT_MASK		0x21
+#define SCA3000_INT_MASK_PROT_MASK		0x1C
+
+#define SCA3000_INT_MASK_RING_THREE_QUARTER	0x80
+#define SCA3000_INT_MASK_RING_HALF		0x40
+
+#define SCA3000_INT_MASK_ALL_INTS		0x02
+#define SCA3000_INT_MASK_ACTIVE_HIGH		0x01
+#define SCA3000_INT_MASK_ACTIVE_LOW		0x00
+
+/* Values of mulipexed registers (write to ctrl_data after select) */
+#define SCA3000_REG_ADDR_CTRL_DATA		0x22
+
+/* Measurment modes available on some sca3000 series chips. Code assumes others
+ * may become available in the future.
+ *
+ * Bypass - Bypass the low-pass filter in the signal channel so as to increase
+ *          signal bandwidth.
+ *
+ * Narrow - Narrow low-pass filtering of the signal channel and half output
+ *          data rate by decimation.
+ *
+ * Wide - Widen low-pass filtering of signal channel to increase bandwidth
+ */
+#define SCA3000_OP_MODE_BYPASS			0x01
+#define SCA3000_OP_MODE_NARROW			0x02
+#define SCA3000_OP_MODE_WIDE			0x04
+#define SCA3000_MAX_TX 6
+#define SCA3000_MAX_RX 2
+
+/**
+ * struct sca3000_state - device instance state information
+ * @us: 	 		the associated spi device
+ * @info: 	  		chip variant information
+ * @indio_dev: 	 		device information used by the IIO core
+ * @interrupt_handler_ws: 	event interrupt handler for all events
+ * @last_timestamp: 		the timestamp of the last event
+ * @mo_det_use_count: 		reference counter for the motion detection unit
+ * @lock: 		 	lock used to protect elements of sca3000_state
+ * 	 			and the underlying device state.
+ * @bpse: 		 	number of bits per scan element
+ * @tx: 		 	dma-able transmit buffer
+ * @rx: 		 	dma-able receive buffer
+ **/
+struct sca3000_state {
+	struct spi_device		*us;
+	const struct sca3000_chip_info	*info;
+	struct iio_dev			*indio_dev;
+	struct work_struct		interrupt_handler_ws;
+	s64				last_timestamp;
+	int				mo_det_use_count;
+	struct mutex			lock;
+	int				bpse;
+	u8				*tx;
+	/* not used during a ring buffer read */
+	u8				*rx;
+};
+
+/**
+ * struct sca3000_chip_info - model dependant parameters
+ * @name: 			model identification
+ * @temp_output:		some devices have temperature sensors.
+ * @measurement_mode_freq:	normal mode sampling frequency
+ * @option_mode_1:		first optional mode. Not all models have one
+ * @option_mode_1_freq:		option mode 1 sampling frequency
+ * @option_mode_2:		second optional mode. Not all chips have one
+ * @option_mode_2_freq:		option mode 2 sampling frequency
+ *
+ * This structure is used to hold information about the functionality of a given
+ * sca3000 variant.
+ **/
+struct sca3000_chip_info {
+	const char		*name;
+	bool			temp_output;
+	int			measurement_mode_freq;
+	int			option_mode_1;
+	int			option_mode_1_freq;
+	int			option_mode_2;
+	int			option_mode_2_freq;
+};
+
+/**
+ * sca3000_read_data() read a series of values from the device
+ * @dev:		device
+ * @reg_address_high:	start address (decremented read)
+ * @rx:			pointer where recieved data is placed. Callee
+ *			responsible for freeing this.
+ * @len:		number of bytes to read
+ *
+ * The main lock must be held.
+ **/
+int sca3000_read_data(struct sca3000_state *st,
+		      u8 reg_address_high,
+		      u8 **rx_p,
+		      int len);
+
+/**
+ * sca3000_write_reg() write a single register
+ * @address:	address of register on chip
+ * @val:	value to be written to register
+ *
+ * The main lock must be held.
+ **/
+int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val);
+
+/* Conversion function for use with the ring buffer when in 11bit mode */
+static inline int sca3000_11bit_convert(uint8_t msb, uint8_t lsb)
+{
+	int16_t val;
+
+	val = ((lsb >> 3) & 0x1C) | (msb << 5);
+	val |= (val & (1 << 12)) ? 0xE000 : 0;
+
+	return val;
+};
+
+static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb)
+{
+	s16 val;
+
+	val = ((lsb >> 3) & 0x1F) | (msb << 5);
+	/* sign fill */
+	val |= (val & (1 << 12)) ? 0xE000 : 0;
+
+	return val;
+};
+
+
+#ifdef CONFIG_IIO_RING_BUFFER
+/**
+ * sca3000_register_ring_funcs() setup the ring state change functions
+ **/
+void sca3000_register_ring_funcs(struct iio_dev *indio_dev);
+
+/**
+ * sca3000_configure_ring() - allocate and configure ring buffer
+ * @indio_dev: iio-core device whose ring is to be configured
+ *
+ * The hardware ring buffer needs far fewer ring buffer functions than
+ * a software one as a lot of things are handled automatically.
+ * This function also tells the iio core that our device supports a
+ * hardware ring buffer mode.
+ **/
+int sca3000_configure_ring(struct iio_dev *indio_dev);
+
+/**
+ * sca3000_unconfigure_ring() - deallocate the ring buffer
+ * @indio_dev: iio-core device whose ring we are freeing
+ **/
+void sca3000_unconfigure_ring(struct iio_dev *indio_dev);
+
+/**
+ * sca3000_ring_int_process() handles ring related event pushing and escalation
+ * @val:	the event code
+ **/
+void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring);
+
+#else
+static inline void sca3000_register_ring_funcs(struct iio_dev *indio_dev) {};
+
+static inline
+int sca3000_register_ring_access_and_init(struct iio_dev *indio_dev)
+{
+	return 0;
+};
+
+static inline void sca3000_ring_int_process(u8 val, void *ring) {};
+
+#endif
+
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
new file mode 100644
index 0000000..e27e3b7
--- /dev/null
+++ b/drivers/staging/iio/accel/sca3000_core.c
@@ -0,0 +1,1509 @@
+/*
+ * sca3000_core.c -- support VTI sca3000 series accelerometers via SPI
+ *
+ * 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.
+ *
+ * Copyright (c) 2009 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ * See industrialio/accels/sca3000.h for comments.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_generic.h"
+
+#include "accel.h"
+#include "sca3000.h"
+
+enum sca3000_variant {
+	d01,
+	d03,
+	e02,
+	e04,
+	e05,
+	l01,
+};
+
+/* Note where option modes are not defined, the chip simply does not
+ * support any.
+ * Other chips in the sca3000 series use i2c and are not included here.
+ *
+ * Some of these devices are only listed in the family data sheet and
+ * do not actually appear to be available.
+ */
+static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
+	{
+		.name = "sca3000-d01",
+		.temp_output = true,
+		.measurement_mode_freq = 250,
+		.option_mode_1 = SCA3000_OP_MODE_BYPASS,
+		.option_mode_1_freq = 250,
+	}, {
+		/* No data sheet available - may be the same as the 3100-d03?*/
+		.name = "sca3000-d03",
+		.temp_output = true,
+	}, {
+		.name = "sca3000-e02",
+		.measurement_mode_freq = 125,
+		.option_mode_1 = SCA3000_OP_MODE_NARROW,
+		.option_mode_1_freq = 63,
+	}, {
+		.name = "sca3000-e04",
+		.measurement_mode_freq = 100,
+		.option_mode_1 = SCA3000_OP_MODE_NARROW,
+		.option_mode_1_freq = 50,
+		.option_mode_2 = SCA3000_OP_MODE_WIDE,
+		.option_mode_2_freq = 400,
+	}, {
+		.name = "sca3000-e05",
+		.measurement_mode_freq = 200,
+		.option_mode_1 = SCA3000_OP_MODE_NARROW,
+		.option_mode_1_freq = 50,
+		.option_mode_2 = SCA3000_OP_MODE_WIDE,
+		.option_mode_2_freq = 400,
+	}, {
+		/* No data sheet available.
+		 * Frequencies are unknown.
+		 */
+		.name = "sca3000-l01",
+		.temp_output = true,
+		.option_mode_1 = SCA3000_OP_MODE_BYPASS,
+	},
+};
+
+
+int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
+{
+	struct spi_transfer xfer = {
+		.bits_per_word = 8,
+		.len = 2,
+		.cs_change = 1,
+		.tx_buf = st->tx,
+	};
+	struct spi_message msg;
+
+	st->tx[0] = SCA3000_WRITE_REG(address);
+	st->tx[1] = val;
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	return spi_sync(st->us, &msg);
+}
+
+int sca3000_read_data(struct sca3000_state *st,
+		      uint8_t reg_address_high,
+		      u8 **rx_p,
+		      int len)
+{
+	int ret;
+	struct spi_message msg;
+	struct spi_transfer xfer = {
+		.bits_per_word = 8,
+		.len = len + 1,
+		.cs_change = 1,
+		.tx_buf = st->tx,
+	};
+
+	*rx_p = kmalloc(len + 1, GFP_KERNEL);
+	if (*rx_p == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	xfer.rx_buf = *rx_p;
+	st->tx[0] = SCA3000_READ_REG(reg_address_high);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	ret = spi_sync(st->us, &msg);
+
+	if (ret) {
+		dev_err(get_device(&st->us->dev), "problem reading register");
+		goto error_free_rx;
+	}
+
+	return 0;
+error_free_rx:
+	kfree(*rx_p);
+error_ret:
+	return ret;
+
+}
+/**
+ * sca3000_reg_lock_on() test if the ctrl register lock is on
+ *
+ * Lock must be held.
+ **/
+static int sca3000_reg_lock_on(struct sca3000_state *st)
+{
+	u8 *rx;
+	int ret;
+
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1);
+
+	if (ret < 0)
+		return ret;
+	ret = !(rx[1] & SCA3000_LOCKED);
+	kfree(rx);
+
+	return ret;
+}
+
+/**
+ * __sca3000_unlock_reg_lock() unlock the control registers
+ *
+ * Note the device does not appear to support doing this in a single transfer.
+ * This should only ever be used as part of ctrl reg read.
+ * Lock must be held before calling this
+ **/
+static int __sca3000_unlock_reg_lock(struct sca3000_state *st)
+{
+	struct spi_message msg;
+	struct spi_transfer xfer[3] = {
+		{
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.tx_buf = st->tx,
+		}, {
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.tx_buf = st->tx + 2,
+		}, {
+			.bits_per_word = 8,
+			.len = 2,
+			.cs_change = 1,
+			.tx_buf = st->tx + 4,
+		},
+	};
+	st->tx[0] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
+	st->tx[1] = 0x00;
+	st->tx[2] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
+	st->tx[3] = 0x50;
+	st->tx[4] = SCA3000_WRITE_REG(SCA3000_REG_ADDR_UNLOCK);
+	st->tx[5] = 0xA0;
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer[0], &msg);
+	spi_message_add_tail(&xfer[1], &msg);
+	spi_message_add_tail(&xfer[2], &msg);
+
+	return spi_sync(st->us, &msg);
+}
+
+/**
+ * sca3000_write_ctrl_reg() write to a lock protect ctrl register
+ * @sel: selects which registers we wish to write to
+ * @val: the value to be written
+ *
+ * Certain control registers are protected against overwriting by the lock
+ * register and use a shared write address. This function allows writing of
+ * these registers.
+ * Lock must be held.
+ **/
+static int sca3000_write_ctrl_reg(struct sca3000_state *st,
+				  uint8_t sel,
+				  uint8_t val)
+{
+
+	int ret;
+
+	ret = sca3000_reg_lock_on(st);
+	if (ret < 0)
+		goto error_ret;
+	if (ret) {
+		ret = __sca3000_unlock_reg_lock(st);
+		if (ret)
+			goto error_ret;
+	}
+
+	/* Set the control select register */
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, sel);
+	if (ret)
+		goto error_ret;
+
+	/* Write the actual value into the register */
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_DATA, val);
+
+error_ret:
+	return ret;
+}
+
+/* Crucial that lock is called before calling this */
+/**
+ * sca3000_read_ctrl_reg() read from lock protected control register.
+ *
+ * Lock must be held.
+ **/
+static int sca3000_read_ctrl_reg(struct sca3000_state *st,
+				 u8 ctrl_reg,
+				 u8 **rx_p)
+{
+	int ret;
+
+	ret = sca3000_reg_lock_on(st);
+	if (ret < 0)
+		goto error_ret;
+	if (ret) {
+		ret = __sca3000_unlock_reg_lock(st);
+		if (ret)
+			goto error_ret;
+	}
+	/* Set the control select register */
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, ctrl_reg);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_CTRL_DATA, rx_p, 1);
+
+error_ret:
+	return ret;
+}
+
+#ifdef SCA3000_DEBUG
+/**
+ * sca3000_check_status() check the status register
+ *
+ * Only used for debugging purposes
+ **/
+static int sca3000_check_status(struct device *dev)
+{
+	u8 *rx;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1);
+	if (ret < 0)
+		goto error_ret;
+	if (rx[1] & SCA3000_EEPROM_CS_ERROR)
+		dev_err(dev, "eeprom error \n");
+	if (rx[1] & SCA3000_SPI_FRAME_ERROR)
+		dev_err(dev, "Previous SPI Frame was corrupt\n");
+	kfree(rx);
+
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret;
+}
+#endif /* SCA3000_DEBUG */
+
+/**
+ * sca3000_read_13bit_signed() sysfs interface to read 13 bit signed registers
+ *
+ * These are described as signed 12 bit on the data sheet, which appears
+ * to be a conventional 2's complement 13 bit.
+ **/
+static ssize_t sca3000_read_13bit_signed(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	int len = 0, ret;
+	int val;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	u8 *rx;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, this_attr->address, &rx, 2);
+	if (ret < 0)
+		goto error_ret;
+	val = sca3000_13bit_convert(rx[1], rx[2]);
+	len += sprintf(buf + len, "%d\n", val);
+	kfree(rx);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+
+static ssize_t sca3000_show_name(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct sca3000_state *st = dev_info->dev_data;
+	return sprintf(buf, "%s\n", st->info->name);
+}
+/**
+ * sca3000_show_reg() - sysfs interface to read the chip revision number
+ **/
+static ssize_t sca3000_show_rev(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	int len = 0, ret;
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct sca3000_state *st = dev_info->dev_data;
+
+	u8 *rx;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_REVID, &rx, 1);
+	if (ret < 0)
+		goto error_ret;
+	len += sprintf(buf + len,
+		       "major=%d, minor=%d\n",
+		       rx[1] & SCA3000_REVID_MAJOR_MASK,
+		       rx[1] & SCA3000_REVID_MINOR_MASK);
+	kfree(rx);
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+/**
+ * sca3000_show_available_measurement_modes() display available modes
+ *
+ * This is all read from chip specific data in the driver. Not all
+ * of the sca3000 series support modes other than normal.
+ **/
+static ssize_t
+sca3000_show_available_measurement_modes(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct sca3000_state *st = dev_info->dev_data;
+	int len = 0;
+
+	len += sprintf(buf + len, "0 - normal mode");
+	switch (st->info->option_mode_1) {
+	case SCA3000_OP_MODE_NARROW:
+		len += sprintf(buf + len, ", 1 - narrow mode");
+		break;
+	case SCA3000_OP_MODE_BYPASS:
+		len += sprintf(buf + len, ", 1 - bypass mode");
+		break;
+	};
+	switch (st->info->option_mode_2) {
+	case SCA3000_OP_MODE_WIDE:
+		len += sprintf(buf + len, ", 2 - wide mode");
+		break;
+	}
+	/* always supported */
+	len += sprintf(buf + len, " 3 - motion detection \n");
+
+	return len;
+}
+
+/**
+ * sca3000_show_measurmenet_mode() sysfs read of current mode
+ **/
+static ssize_t
+sca3000_show_measurement_mode(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct sca3000_state *st = dev_info->dev_data;
+	int len = 0, ret;
+	u8 *rx;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto error_ret;
+	/* mask bottom 2 bits - only ones that are relevant */
+	rx[1] &= 0x03;
+	switch (rx[1]) {
+	case SCA3000_MEAS_MODE_NORMAL:
+		len += sprintf(buf + len, "0 - normal mode\n");
+		break;
+	case SCA3000_MEAS_MODE_MOT_DET:
+		len += sprintf(buf + len, "3 - motion detection\n");
+		break;
+	case SCA3000_MEAS_MODE_OP_1:
+		switch (st->info->option_mode_1) {
+		case SCA3000_OP_MODE_NARROW:
+			len += sprintf(buf + len, "1 - narrow mode\n");
+			break;
+		case SCA3000_OP_MODE_BYPASS:
+			len += sprintf(buf + len, "1 - bypass mode\n");
+			break;
+		};
+		break;
+	case SCA3000_MEAS_MODE_OP_2:
+		switch (st->info->option_mode_2) {
+		case SCA3000_OP_MODE_WIDE:
+			len += sprintf(buf + len, "2 - wide mode\n");
+			break;
+		}
+		break;
+	};
+
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+/**
+ * sca3000_store_measurement_mode() set the current mode
+ **/
+static ssize_t
+sca3000_store_measurement_mode(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf,
+			       size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct sca3000_state *st = dev_info->dev_data;
+	int ret;
+	u8 *rx;
+	int mask = 0x03;
+	long val;
+
+	mutex_lock(&st->lock);
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto error_ret;
+	rx[1] &= ~mask;
+	rx[1] |= (val & mask);
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, rx[1]);
+	if (ret)
+		goto error_free_rx;
+	mutex_unlock(&st->lock);
+
+	return len;
+
+error_free_rx:
+	kfree(rx);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+
+
+/* Not even vaguely standard attributes so defined here rather than
+ * in the relevant IIO core headers
+ */
+static IIO_DEVICE_ATTR(available_measurement_modes, S_IRUGO,
+		       sca3000_show_available_measurement_modes,
+		       NULL, 0);
+
+static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR,
+		       sca3000_show_measurement_mode,
+		       sca3000_store_measurement_mode,
+		       0);
+
+/* More standard attributes */
+
+static IIO_DEV_ATTR_NAME(sca3000_show_name);
+static IIO_DEV_ATTR_REV(sca3000_show_rev);
+
+static IIO_DEV_ATTR_ACCEL_X(sca3000_read_13bit_signed,
+			    SCA3000_REG_ADDR_X_MSB);
+static IIO_DEV_ATTR_ACCEL_Y(sca3000_read_13bit_signed,
+			    SCA3000_REG_ADDR_Y_MSB);
+static IIO_DEV_ATTR_ACCEL_Z(sca3000_read_13bit_signed,
+			    SCA3000_REG_ADDR_Z_MSB);
+
+
+/**
+ * sca3000_read_av_freq() sysfs function to get available frequencies
+ *
+ * The later modes are only relevant to the ring buffer - and depend on current
+ * mode. Note that data sheet gives rather wide tolerances for these so integer
+ * division will give good enough answer and not all chips have them specified
+ * at all.
+ **/
+static ssize_t sca3000_read_av_freq(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	int len = 0, ret;
+	u8 *rx;
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	mutex_unlock(&st->lock);
+	if (ret)
+		goto error_ret;
+	rx[1] &= 0x03;
+	switch (rx[1]) {
+	case SCA3000_MEAS_MODE_NORMAL:
+		len += sprintf(buf + len, "%d %d %d\n",
+			       st->info->measurement_mode_freq,
+			       st->info->measurement_mode_freq/2,
+			       st->info->measurement_mode_freq/4);
+		break;
+	case SCA3000_MEAS_MODE_OP_1:
+		len += sprintf(buf + len, "%d %d %d\n",
+			       st->info->option_mode_1_freq,
+			       st->info->option_mode_1_freq/2,
+			       st->info->option_mode_1_freq/4);
+		break;
+	case SCA3000_MEAS_MODE_OP_2:
+		len += sprintf(buf + len, "%d %d %d\n",
+			       st->info->option_mode_2_freq,
+			       st->info->option_mode_2_freq/2,
+			       st->info->option_mode_2_freq/4);
+		break;
+	};
+	kfree(rx);
+	return len;
+error_ret:
+	return ret;
+}
+/**
+ * __sca3000_get_base_frequency() obtain mode specific base frequency
+ *
+ * lock must be held
+ **/
+static inline int __sca3000_get_base_freq(struct sca3000_state *st,
+					  const struct sca3000_chip_info *info,
+					  int *base_freq)
+{
+	int ret;
+	u8 *rx;
+
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto error_ret;
+	switch (0x03 & rx[1]) {
+	case SCA3000_MEAS_MODE_NORMAL:
+		*base_freq = info->measurement_mode_freq;
+		break;
+	case SCA3000_MEAS_MODE_OP_1:
+		*base_freq = info->option_mode_1_freq;
+		break;
+	case SCA3000_MEAS_MODE_OP_2:
+		*base_freq = info->option_mode_2_freq;
+		break;
+	};
+	kfree(rx);
+error_ret:
+	return ret;
+}
+
+/**
+ * sca3000_read_frequency() sysfs interface to get the current frequency
+ **/
+static ssize_t sca3000_read_frequency(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	int ret, len = 0, base_freq = 0;
+	u8 *rx;
+	mutex_lock(&st->lock);
+	ret = __sca3000_get_base_freq(st, st->info, &base_freq);
+	if (ret)
+		goto error_ret_mut;
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx);
+	mutex_unlock(&st->lock);
+	if (ret)
+		goto error_ret;
+	if (base_freq > 0)
+		switch (rx[1]&0x03) {
+		case 0x00:
+		case 0x03:
+			len = sprintf(buf, "%d\n", base_freq);
+			break;
+		case 0x01:
+			len = sprintf(buf, "%d\n", base_freq/2);
+			break;
+		case 0x02:
+			len = sprintf(buf, "%d\n", base_freq/4);
+			break;
+	};
+			kfree(rx);
+	return len;
+error_ret_mut:
+	mutex_unlock(&st->lock);
+error_ret:
+	return ret;
+}
+
+/**
+ * sca3000_set_frequency() sysfs interface to set the current frequency
+ **/
+static ssize_t sca3000_set_frequency(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	int ret, base_freq = 0;
+	u8 *rx;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&st->lock);
+	/* What mode are we in? */
+	ret = __sca3000_get_base_freq(st, st->info, &base_freq);
+	if (ret)
+		goto error_free_lock;
+
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx);
+	if (ret)
+		goto error_free_lock;
+	/* clear the bits */
+	rx[1] &= ~0x03;
+
+	if (val == base_freq/2) {
+		rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_2;
+	} else if (val == base_freq/4) {
+		rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_4;
+	} else if (val != base_freq) {
+		ret = -EINVAL;
+		goto error_free_lock;
+	}
+	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, rx[1]);
+error_free_lock:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+/* Should only really be registered if ring buffer support is compiled in.
+ * Does no harm however and doing it right would add a fair bit of complexity
+ */
+static IIO_DEV_ATTR_AVAIL_SAMP_FREQ(sca3000_read_av_freq);
+
+static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
+			      sca3000_read_frequency,
+			      sca3000_set_frequency);
+
+
+/**
+ * sca3000_read_temp() sysfs interface to get the temperature when available
+ *
+* The alignment of data in here is downright odd. See data sheet.
+* Converting this into a meaningful value is left to inline functions in
+* userspace part of header.
+**/
+static ssize_t sca3000_read_temp(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	int len = 0, ret;
+	int val;
+	u8 *rx;
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_TEMP_MSB, &rx, 2);
+	if (ret < 0)
+		goto error_ret;
+	val = ((rx[1]&0x3F) << 3) | ((rx[2] & 0xE0) >> 5);
+	len += sprintf(buf + len, "%d\n", val);
+	kfree(rx);
+
+	return len;
+
+error_ret:
+	return ret;
+}
+static IIO_DEV_ATTR_TEMP(sca3000_read_temp);
+
+/**
+ * sca3000_show_thresh() sysfs query of a theshold
+ **/
+static ssize_t sca3000_show_thresh(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int len = 0, ret;
+	u8 *rx;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_ctrl_reg(st,
+				    this_attr->address,
+				    &rx);
+	mutex_unlock(&st->lock);
+	if (ret)
+		return ret;
+	len += sprintf(buf + len, "%d\n", rx[1]);
+	kfree(rx);
+
+	return len;
+}
+
+/**
+ * sca3000_write_thresh() sysfs control of threshold
+ **/
+static ssize_t sca3000_write_thresh(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf,
+				    size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+	mutex_lock(&st->lock);
+	ret = sca3000_write_ctrl_reg(st, this_attr->address, val);
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEV_ATTR_ACCEL_THRESH_X(S_IRUGO | S_IWUSR,
+				   sca3000_show_thresh,
+				   sca3000_write_thresh,
+				   SCA3000_REG_CTRL_SEL_MD_X_TH);
+static IIO_DEV_ATTR_ACCEL_THRESH_Y(S_IRUGO | S_IWUSR,
+				   sca3000_show_thresh,
+				   sca3000_write_thresh,
+				   SCA3000_REG_CTRL_SEL_MD_Y_TH);
+static IIO_DEV_ATTR_ACCEL_THRESH_Z(S_IRUGO | S_IWUSR,
+				   sca3000_show_thresh,
+				   sca3000_write_thresh,
+				   SCA3000_REG_CTRL_SEL_MD_Z_TH);
+
+static struct attribute *sca3000_attributes[] = {
+	&iio_dev_attr_name.dev_attr.attr,
+	&iio_dev_attr_revision.dev_attr.attr,
+	&iio_dev_attr_accel_x.dev_attr.attr,
+	&iio_dev_attr_accel_y.dev_attr.attr,
+	&iio_dev_attr_accel_z.dev_attr.attr,
+	&iio_dev_attr_thresh_accel_x.dev_attr.attr,
+	&iio_dev_attr_thresh_accel_y.dev_attr.attr,
+	&iio_dev_attr_thresh_accel_z.dev_attr.attr,
+	&iio_dev_attr_available_measurement_modes.dev_attr.attr,
+	&iio_dev_attr_measurement_mode.dev_attr.attr,
+	&iio_dev_attr_available_sampling_frequency.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute *sca3000_attributes_with_temp[] = {
+	&iio_dev_attr_name.dev_attr.attr,
+	&iio_dev_attr_revision.dev_attr.attr,
+	&iio_dev_attr_accel_x.dev_attr.attr,
+	&iio_dev_attr_accel_y.dev_attr.attr,
+	&iio_dev_attr_accel_z.dev_attr.attr,
+	&iio_dev_attr_thresh_accel_x.dev_attr.attr,
+	&iio_dev_attr_thresh_accel_y.dev_attr.attr,
+	&iio_dev_attr_thresh_accel_z.dev_attr.attr,
+	&iio_dev_attr_available_measurement_modes.dev_attr.attr,
+	&iio_dev_attr_measurement_mode.dev_attr.attr,
+	&iio_dev_attr_available_sampling_frequency.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	/* Only present if temp sensor is */
+	&iio_dev_attr_temp.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group sca3000_attribute_group = {
+	.attrs = sca3000_attributes,
+};
+
+static const struct attribute_group sca3000_attribute_group_with_temp = {
+	.attrs = sca3000_attributes_with_temp,
+};
+
+/* RING RELATED interrupt handler */
+/* depending on event, push to the ring buffer event chrdev or the event one */
+
+/**
+ * sca3000_interrupt_handler_bh() - handling ring and non ring events
+ *
+ * This function is complicated by the fact that the devices can signify ring
+ * and non ring events via the same interrupt line and they can only
+ * be distinguished via a read of the relevant status register.
+ **/
+static void sca3000_interrupt_handler_bh(struct work_struct *work_s)
+{
+	struct sca3000_state *st
+		= container_of(work_s, struct sca3000_state,
+			       interrupt_handler_ws);
+	u8 *rx;
+	int ret;
+
+	/* Could lead if badly timed to an extra read of status reg,
+	 * but ensures no interrupt is missed.
+	 */
+	enable_irq(st->us->irq);
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS,
+				&rx, 1);
+	mutex_unlock(&st->lock);
+	if (ret)
+		goto done;
+
+	sca3000_ring_int_process(rx[1], st->indio_dev->ring);
+
+	if (rx[1] & SCA3000_INT_STATUS_FREE_FALL)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_FREE_FALL,
+			       st->last_timestamp);
+
+	if (rx[1] & SCA3000_INT_STATUS_Y_TRIGGER)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_Y_HIGH,
+			       st->last_timestamp);
+
+	if (rx[1] & SCA3000_INT_STATUS_X_TRIGGER)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_X_HIGH,
+			       st->last_timestamp);
+
+	if (rx[1] & SCA3000_INT_STATUS_Z_TRIGGER)
+		iio_push_event(st->indio_dev, 0,
+			       IIO_EVENT_CODE_ACCEL_Z_HIGH,
+			       st->last_timestamp);
+
+done:
+	kfree(rx);
+	return;
+}
+
+/**
+ * sca3000_handler_th() handles all interrupt events from device
+ *
+ * These devices deploy unified interrupt status registers meaning
+ * all interrupts must be handled together
+ **/
+static int sca3000_handler_th(struct iio_dev *dev_info,
+			      int index,
+			      s64 timestamp,
+			      int no_test)
+{
+	struct sca3000_state *st = dev_info->dev_data;
+
+	st->last_timestamp = timestamp;
+	schedule_work(&st->interrupt_handler_ws);
+
+	return 0;
+}
+
+/**
+ * sca3000_query_mo_det() is motion detection enabled for this axis
+ *
+ * First queries if motion detection is enabled and then if this axis is
+ * on.
+ **/
+static ssize_t sca3000_query_mo_det(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	int ret, len = 0;
+	u8 *rx;
+	u8 protect_mask = 0x03;
+
+	/* read current value of mode register */
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto error_ret;
+
+	if ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET)
+		len += sprintf(buf + len, "0\n");
+	else {
+		kfree(rx);
+		ret = sca3000_read_ctrl_reg(st,
+					    SCA3000_REG_CTRL_SEL_MD_CTRL,
+					    &rx);
+		if (ret)
+			goto error_ret;
+		/* only supporting logical or's for now */
+		len += sprintf(buf + len, "%d\n",
+			       (rx[1] & this_attr->mask) ? 1 : 0);
+	}
+	kfree(rx);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+/**
+ * sca3000_query_free_fall_mode() is free fall mode enabled
+ **/
+static ssize_t sca3000_query_free_fall_mode(struct device *dev,
+					    struct device_attribute *attr,
+					    char *buf)
+{
+	int ret, len;
+	u8 *rx;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	mutex_unlock(&st->lock);
+	if (ret)
+		return ret;
+	len = sprintf(buf, "%d\n",
+		      !!(rx[1] & SCA3000_FREE_FALL_DETECT));
+	kfree(rx);
+
+	return len;
+}
+/**
+ * sca3000_query_ring_int() is the hardware ring status interrupt enabled
+ **/
+static ssize_t sca3000_query_ring_int(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	int ret, len;
+	u8 *rx;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
+	mutex_unlock(&st->lock);
+	if (ret)
+		return ret;
+	len = sprintf(buf, "%d\n", (rx[1] & this_attr->mask) ? 1 : 0);
+	kfree(rx);
+
+	return len;
+}
+/**
+ * sca3000_set_ring_int() set state of ring status interrupt
+ **/
+static ssize_t sca3000_set_ring_int(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+
+	long val;
+	int ret;
+	u8 *rx;
+
+	mutex_lock(&st->lock);
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
+	if (ret)
+		goto error_ret;
+	if (val)
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_INT_MASK,
+					rx[1] | this_attr->mask);
+	else
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_INT_MASK,
+					rx[1] & ~this_attr->mask);
+	kfree(rx);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+/**
+ * sca3000_set_free_fall_mode() simple on off control for free fall int
+ *
+ * In these chips the free fall detector should send an interrupt if
+ * the device falls more than 25cm.  This has not been tested due
+ * to fragile wiring.
+ **/
+
+static ssize_t sca3000_set_free_fall_mode(struct device *dev,
+					  struct device_attribute *attr,
+					  const char *buf,
+					  size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	long val;
+	int ret;
+	u8 *rx;
+	u8 protect_mask = SCA3000_FREE_FALL_DETECT;
+
+	mutex_lock(&st->lock);
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+
+	/* read current value of mode register */
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto error_ret;
+
+	/*if off and should be on*/
+	if (val && !(rx[1] & protect_mask))
+		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+					(rx[1] | SCA3000_FREE_FALL_DETECT));
+	/* if on and should be off */
+	else if (!val && (rx[1]&protect_mask))
+		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+					(rx[1] & ~protect_mask));
+
+	kfree(rx);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+/**
+ * sca3000_set_mo_det() simple on off control for motion detector
+ *
+ * This is a per axis control, but enabling any will result in the
+ * motion detector unit being enabled.
+ * N.B. enabling motion detector stops normal data acquisition.
+ * There is a complexity in knowing which mode to return to when
+ * this mode is disabled.  Currently normal mode is assumed.
+ **/
+static ssize_t sca3000_set_mo_det(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct sca3000_state *st = indio_dev->dev_data;
+	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	long val;
+	int ret;
+	u8 *rx;
+	u8 protect_mask = 0x03;
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&st->lock);
+	/* First read the motion detector config to find out if
+	 * this axis is on*/
+	ret = sca3000_read_ctrl_reg(st,
+				    SCA3000_REG_CTRL_SEL_MD_CTRL,
+				    &rx);
+	if (ret)
+		goto exit_point;
+	/* Off and should be on */
+	if (val && !(rx[1] & this_attr->mask)) {
+		ret = sca3000_write_ctrl_reg(st,
+					     SCA3000_REG_CTRL_SEL_MD_CTRL,
+					     rx[1] | this_attr->mask);
+		if (ret)
+			goto exit_point_free_rx;
+		st->mo_det_use_count++;
+	} else if (!val && (rx[1]&this_attr->mask)) {
+		ret = sca3000_write_ctrl_reg(st,
+					     SCA3000_REG_CTRL_SEL_MD_CTRL,
+					     rx[1] & ~(this_attr->mask));
+		if (ret)
+			goto exit_point_free_rx;
+		st->mo_det_use_count--;
+	} else /* relies on clean state for device on boot */
+		goto exit_point_free_rx;
+	kfree(rx);
+	/* read current value of mode register */
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto exit_point;
+	/*if off and should be on*/
+	if ((st->mo_det_use_count)
+	    && ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
+		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+					(rx[1] & ~protect_mask)
+					| SCA3000_MEAS_MODE_MOT_DET);
+	/* if on and should be off */
+	else if (!(st->mo_det_use_count)
+		 && ((rx[1]&protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
+		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+					(rx[1] & ~protect_mask));
+exit_point_free_rx:
+	kfree(rx);
+exit_point:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+/* Shared event handler for all events as single event status register */
+IIO_EVENT_SH(all, &sca3000_handler_th);
+
+/* Free fall detector related event attribute */
+IIO_EVENT_ATTR_FREE_FALL_DETECT_SH(iio_event_all,
+				   sca3000_query_free_fall_mode,
+				   sca3000_set_free_fall_mode,
+				   0)
+
+/* Motion detector related event attributes */
+IIO_EVENT_ATTR_ACCEL_X_HIGH_SH(iio_event_all,
+			       sca3000_query_mo_det,
+			       sca3000_set_mo_det,
+			       SCA3000_MD_CTRL_OR_X);
+
+IIO_EVENT_ATTR_ACCEL_Y_HIGH_SH(iio_event_all,
+			       sca3000_query_mo_det,
+			       sca3000_set_mo_det,
+			       SCA3000_MD_CTRL_OR_Y);
+
+IIO_EVENT_ATTR_ACCEL_Z_HIGH_SH(iio_event_all,
+			       sca3000_query_mo_det,
+			       sca3000_set_mo_det,
+			       SCA3000_MD_CTRL_OR_Z);
+
+/* Hardware ring buffer related event attributes */
+IIO_EVENT_ATTR_RING_50_FULL_SH(iio_event_all,
+			       sca3000_query_ring_int,
+			       sca3000_set_ring_int,
+			       SCA3000_INT_MASK_RING_HALF);
+
+IIO_EVENT_ATTR_RING_75_FULL_SH(iio_event_all,
+			       sca3000_query_ring_int,
+			       sca3000_set_ring_int,
+			       SCA3000_INT_MASK_RING_THREE_QUARTER);
+
+static struct attribute *sca3000_event_attributes[] = {
+	&iio_event_attr_free_fall.dev_attr.attr,
+	&iio_event_attr_accel_x_high.dev_attr.attr,
+	&iio_event_attr_accel_y_high.dev_attr.attr,
+	&iio_event_attr_accel_z_high.dev_attr.attr,
+	&iio_event_attr_ring_50_full.dev_attr.attr,
+	&iio_event_attr_ring_75_full.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group sca3000_event_attribute_group = {
+	.attrs = sca3000_event_attributes,
+};
+
+/**
+ * sca3000_clean_setup() get the device into a predictable state
+ *
+ * Devices use flash memory to store many of the register values
+ * and hence can come up in somewhat unpredictable states.
+ * Hence reset everything on driver load.
+  **/
+static int sca3000_clean_setup(struct sca3000_state *st)
+{
+	int ret;
+	u8 *rx;
+
+	mutex_lock(&st->lock);
+	/* Ensure all interrupts have been acknowledged */
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS, &rx, 1);
+	if (ret)
+		goto error_ret;
+	kfree(rx);
+
+	/* Turn off all motion detection channels */
+	ret = sca3000_read_ctrl_reg(st,
+				    SCA3000_REG_CTRL_SEL_MD_CTRL,
+				    &rx);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_write_ctrl_reg(st,
+				     SCA3000_REG_CTRL_SEL_MD_CTRL,
+				     rx[1] & SCA3000_MD_CTRL_PROT_MASK);
+	kfree(rx);
+	if (ret)
+		goto error_ret;
+
+	/* Disable ring buffer */
+	sca3000_read_ctrl_reg(st,
+			      SCA3000_REG_CTRL_SEL_OUT_CTRL,
+			      &rx);
+	/* Frequency of ring buffer sampling deliberately restricted to make
+	 * debugging easier - add control of this later */
+	ret = sca3000_write_ctrl_reg(st,
+				     SCA3000_REG_CTRL_SEL_OUT_CTRL,
+				     (rx[1] & SCA3000_OUT_CTRL_PROT_MASK)
+				     | SCA3000_OUT_CTRL_BUF_X_EN
+				     | SCA3000_OUT_CTRL_BUF_Y_EN
+				     | SCA3000_OUT_CTRL_BUF_Z_EN
+				     | SCA3000_OUT_CTRL_BUF_DIV_4);
+	kfree(rx);
+
+	if (ret)
+		goto error_ret;
+	/* Enable interrupts, relevant to mode and set up as active low */
+	ret = sca3000_read_data(st,
+			  SCA3000_REG_ADDR_INT_MASK,
+			  &rx, 1);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_write_reg(st,
+				SCA3000_REG_ADDR_INT_MASK,
+				(rx[1] & SCA3000_INT_MASK_PROT_MASK)
+				| SCA3000_INT_MASK_ACTIVE_LOW);
+	kfree(rx);
+	if (ret)
+		goto error_ret;
+	/* Select normal measurement mode, free fall off, ring off */
+	/* Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5
+	 * as that occurs in one of the example on the datasheet */
+	ret = sca3000_read_data(st,
+			  SCA3000_REG_ADDR_MODE,
+			  &rx, 1);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_write_reg(st,
+				SCA3000_REG_ADDR_MODE,
+				(rx[1] & SCA3000_MODE_PROT_MASK));
+	kfree(rx);
+	st->bpse = 11;
+
+error_ret:
+	mutex_unlock(&st->lock);
+	return ret;
+}
+
+static int __devinit __sca3000_probe(struct spi_device *spi,
+				     enum sca3000_variant variant)
+{
+	int ret, regdone = 0;
+	struct sca3000_state *st;
+
+	st = kzalloc(sizeof(struct sca3000_state), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	spi_set_drvdata(spi, st);
+
+	st->tx = kmalloc(sizeof(*st->tx)*6, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_clear_st;
+	}
+	st->rx = kmalloc(sizeof(*st->rx)*3, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+	st->us = spi;
+	mutex_init(&st->lock);
+	st->info = &sca3000_spi_chip_info_tbl[variant];
+
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->num_interrupt_lines = 1;
+	st->indio_dev->event_attrs = &sca3000_event_attribute_group;
+	if (st->info->temp_output)
+		st->indio_dev->attrs = &sca3000_attribute_group_with_temp;
+	else
+		st->indio_dev->attrs = &sca3000_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	sca3000_configure_ring(st->indio_dev);
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret < 0)
+		goto error_free_dev;
+	regdone = 1;
+	ret = iio_ring_buffer_register(st->indio_dev->ring);
+	if (ret < 0)
+		goto error_unregister_dev;
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
+		INIT_WORK(&st->interrupt_handler_ws,
+			  sca3000_interrupt_handler_bh);
+		ret = iio_register_interrupt_line(spi->irq,
+						  st->indio_dev,
+						  0,
+						  IRQF_TRIGGER_FALLING,
+						  "sca3000");
+		if (ret)
+			goto error_unregister_ring;
+		/* RFC
+		 * Probably a common situation.  All interrupts need an ack
+		 * and there is only one handler so the complicated list system
+		 * is overkill.  At very least a simpler registration method
+		 * might be worthwhile.
+		 */
+		iio_add_event_to_list(iio_event_attr_accel_z_high.listel,
+					    &st->indio_dev
+					    ->interrupts[0]->ev_list);
+	}
+	sca3000_register_ring_funcs(st->indio_dev);
+	ret = sca3000_clean_setup(st);
+	if (ret)
+		goto error_unregister_interrupt_line;
+	return 0;
+
+error_unregister_interrupt_line:
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(st->indio_dev, 0);
+error_unregister_ring:
+	iio_ring_buffer_unregister(st->indio_dev->ring);
+error_unregister_dev:
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_rx:
+	kfree(st->rx);
+error_free_tx:
+	kfree(st->tx);
+error_clear_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int sca3000_stop_all_interrupts(struct sca3000_state *st)
+{
+	int ret;
+	u8 *rx;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_INT_MASK,
+				(rx[1] & ~(SCA3000_INT_MASK_RING_THREE_QUARTER
+					   | SCA3000_INT_MASK_RING_HALF
+					   | SCA3000_INT_MASK_ALL_INTS)));
+error_ret:
+	kfree(rx);
+	return ret;
+
+}
+
+static int sca3000_remove(struct spi_device *spi)
+{
+	struct sca3000_state *st =  spi_get_drvdata(spi);
+	struct iio_dev *indio_dev = st->indio_dev;
+	int ret;
+	/* Must ensure no interrupts can be generated after this!*/
+	ret = sca3000_stop_all_interrupts(st);
+	if (ret)
+		return ret;
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		iio_unregister_interrupt_line(indio_dev, 0);
+	iio_ring_buffer_unregister(indio_dev->ring);
+	sca3000_unconfigure_ring(indio_dev);
+	iio_device_unregister(indio_dev);
+
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+/* These macros save on an awful lot of repeated code */
+#define SCA3000_VARIANT_PROBE(_name)				\
+	static int __devinit					\
+	sca3000_##_name##_probe(struct spi_device *spi)		\
+	{							\
+		return __sca3000_probe(spi, _name);		\
+	}
+
+#define SCA3000_VARIANT_SPI_DRIVER(_name)			\
+	struct spi_driver sca3000_##_name##_driver = {		\
+		.driver = {					\
+			.name = "sca3000_" #_name,		\
+			.owner = THIS_MODULE,			\
+		},						\
+		.probe = sca3000_##_name##_probe,		\
+		.remove = __devexit_p(sca3000_remove),		\
+	}
+
+SCA3000_VARIANT_PROBE(d01);
+static SCA3000_VARIANT_SPI_DRIVER(d01);
+
+SCA3000_VARIANT_PROBE(d03);
+static SCA3000_VARIANT_SPI_DRIVER(d03);
+
+SCA3000_VARIANT_PROBE(e02);
+static SCA3000_VARIANT_SPI_DRIVER(e02);
+
+SCA3000_VARIANT_PROBE(e04);
+static SCA3000_VARIANT_SPI_DRIVER(e04);
+
+SCA3000_VARIANT_PROBE(e05);
+static SCA3000_VARIANT_SPI_DRIVER(e05);
+
+SCA3000_VARIANT_PROBE(l01);
+static SCA3000_VARIANT_SPI_DRIVER(l01);
+
+static __init int sca3000_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&sca3000_d01_driver);
+	if (ret)
+		goto error_ret;
+	ret = spi_register_driver(&sca3000_d03_driver);
+	if (ret)
+		goto error_unreg_d01;
+	ret = spi_register_driver(&sca3000_e02_driver);
+	if (ret)
+		goto error_unreg_d03;
+	ret = spi_register_driver(&sca3000_e04_driver);
+	if (ret)
+		goto error_unreg_e02;
+	ret = spi_register_driver(&sca3000_e05_driver);
+	if (ret)
+		goto error_unreg_e04;
+	ret = spi_register_driver(&sca3000_l01_driver);
+	if (ret)
+		goto error_unreg_e05;
+
+	return 0;
+
+error_unreg_e05:
+	spi_unregister_driver(&sca3000_e05_driver);
+error_unreg_e04:
+	spi_unregister_driver(&sca3000_e04_driver);
+error_unreg_e02:
+	spi_unregister_driver(&sca3000_e02_driver);
+error_unreg_d03:
+	spi_unregister_driver(&sca3000_d03_driver);
+error_unreg_d01:
+	spi_unregister_driver(&sca3000_d01_driver);
+error_ret:
+
+	return ret;
+}
+
+static __exit void sca3000_exit(void)
+{
+	spi_unregister_driver(&sca3000_l01_driver);
+	spi_unregister_driver(&sca3000_e05_driver);
+	spi_unregister_driver(&sca3000_e04_driver);
+	spi_unregister_driver(&sca3000_e02_driver);
+	spi_unregister_driver(&sca3000_d03_driver);
+	spi_unregister_driver(&sca3000_d01_driver);
+}
+
+module_init(sca3000_init);
+module_exit(sca3000_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("VTI SCA3000 Series Accelerometers SPI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c
new file mode 100644
index 0000000..d5ea237
--- /dev/null
+++ b/drivers/staging/iio/accel/sca3000_ring.c
@@ -0,0 +1,331 @@
+/*
+ * sca3000_ring.c -- support VTI sca3000 series accelerometers via SPI
+ *
+ * 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.
+ *
+ * Copyright (c) 2009 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_generic.h"
+#include "../ring_hw.h"
+#include "accel.h"
+#include "sca3000.h"
+
+/* RFC / future work
+ *
+ * The internal ring buffer doesn't actually change what it holds depending
+ * on which signals are enabled etc, merely whether you can read them.
+ * As such the scan mode selection is somewhat different than for a software
+ * ring buffer and changing it actually covers any data already in the buffer.
+ * Currently scan elements aren't configured so it doesn't matter.
+ */
+
+/**
+ * sca3000_rip_hw_rb() - main ring access function, pulls data from ring
+ * @r:			the ring
+ * @count:		number of samples to try and pull
+ * @data:		output the actual samples pulled from the hw ring
+ * @dead_offset:	cheating a bit here: Set to 1 so as to allow for the
+ *			leading byte used in bus comms.
+ *
+ * Currently does not provide timestamps.  As the hardware doesn't add them they
+ * can only be inferred aproximately from ring buffer events such as 50% full
+ * and knowledge of when buffer was last emptied.  This is left to userspace.
+ **/
+static int sca3000_rip_hw_rb(struct iio_ring_buffer *r,
+			     size_t count, u8 **data, int *dead_offset)
+{
+	struct iio_hw_ring_buffer *hw_ring = iio_to_hw_ring_buf(r);
+	struct iio_dev *indio_dev = hw_ring->private;
+	struct sca3000_state *st = indio_dev->dev_data;
+	u8 *rx;
+	int ret, num_available, num_read = 0;
+	int bytes_per_sample = 1;
+
+	if (st->bpse == 11)
+		bytes_per_sample = 2;
+
+	mutex_lock(&st->lock);
+	/* Check how much data is available:
+	 * RFC: Implement an ioctl to not bother checking whether there
+	 * is enough data in the ring?  Afterall, if we are responding
+	 * to an interrupt we have a minimum content guaranteed so it
+	 * seems slight silly to waste time checking it is there.
+	 */
+	ret = sca3000_read_data(st,
+				SCA3000_REG_ADDR_BUF_COUNT,
+				&rx, 1);
+	if (ret)
+		goto error_ret;
+	else
+		num_available = rx[1];
+	/* num_available is the total number of samples available
+	 * i.e. number of time points * number of channels.
+	 */
+	kfree(rx);
+	if (count > num_available * bytes_per_sample)
+		num_read = num_available*bytes_per_sample;
+	else
+		num_read = count - (count % (bytes_per_sample));
+
+	/* Avoid the read request byte */
+	*dead_offset = 1;
+	ret = sca3000_read_data(st,
+				SCA3000_REG_ADDR_RING_OUT,
+				data, num_read);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : num_read;
+}
+
+/* This is only valid with all 3 elements enabled */
+static int sca3000_ring_get_length(struct iio_ring_buffer *r)
+{
+	return 64;
+}
+
+/* only valid if resolution is kept at 11bits */
+static int sca3000_ring_get_bpd(struct iio_ring_buffer *r)
+{
+	return 6;
+}
+static void sca3000_ring_release(struct device *dev)
+{
+	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
+	kfree(iio_to_hw_ring_buf(r));
+}
+
+static IIO_RING_ENABLE_ATTR;
+static IIO_RING_BPS_ATTR;
+static IIO_RING_LENGTH_ATTR;
+
+/**
+ * sca3000_show_ring_bpse() -sysfs function to query bits per sample from ring
+ * @dev: ring buffer device
+ * @attr: this device attribute
+ * @buf: buffer to write to
+ **/
+static ssize_t sca3000_show_ring_bpse(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	int len = 0, ret;
+	u8 *rx;
+	struct iio_ring_buffer *r = dev_get_drvdata(dev);
+	struct sca3000_state *st = r->indio_dev->dev_data;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto error_ret;
+	len = sprintf(buf, "%d\n", (rx[1] & SCA3000_RING_BUF_8BIT) ? 8 : 11);
+	kfree(rx);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+/**
+ * sca3000_store_ring_bpse() - bits per scan element
+ * @dev: ring buffer device
+ * @attr: attribute called from
+ * @buf: input from userspace
+ * @len: length of input
+ **/
+static ssize_t sca3000_store_ring_bpse(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	struct iio_ring_buffer *r = dev_get_drvdata(dev);
+	struct sca3000_state *st = r->indio_dev->dev_data;
+	int ret;
+	u8 *rx;
+	long val;
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	mutex_lock(&st->lock);
+
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (!ret)
+		switch (val) {
+		case 8:
+			ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+						rx[1] | SCA3000_RING_BUF_8BIT);
+			st->bpse = 8;
+			break;
+		case 11:
+			ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+						rx[1] & ~SCA3000_RING_BUF_8BIT);
+			st->bpse = 11;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_CONST_ATTR(bpse_available, "8 11");
+
+static IIO_DEV_ATTR_BPSE(S_IRUGO | S_IWUSR,
+			      sca3000_show_ring_bpse,
+			      sca3000_store_ring_bpse);
+
+/*
+ * Ring buffer attributes
+ * This device is a bit unusual in that the sampling frequency and bpse
+ * only apply to the ring buffer.  At all times full rate and accuracy
+ * is available via direct reading from registers.
+ */
+static struct attribute *iio_ring_attributes[] = {
+	&dev_attr_length.attr,
+	&dev_attr_bps.attr,
+	&dev_attr_ring_enable.attr,
+	&iio_dev_attr_bpse.dev_attr.attr,
+	&iio_const_attr_bpse_available.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group sca3000_ring_attr = {
+	.attrs = iio_ring_attributes,
+};
+
+static const struct attribute_group *sca3000_ring_attr_groups[] = {
+	&sca3000_ring_attr,
+	NULL
+};
+
+static struct device_type sca3000_ring_type = {
+	.release = sca3000_ring_release,
+	.groups = sca3000_ring_attr_groups,
+};
+
+static struct iio_ring_buffer *sca3000_rb_allocate(struct iio_dev *indio_dev)
+{
+	struct iio_ring_buffer *buf;
+	struct iio_hw_ring_buffer *ring;
+
+	ring = kzalloc(sizeof *ring, GFP_KERNEL);
+	if (!ring)
+		return 0;
+	ring->private = indio_dev;
+	buf = &ring->buf;
+	iio_ring_buffer_init(buf, indio_dev);
+	buf->dev.type = &sca3000_ring_type;
+	device_initialize(&buf->dev);
+	buf->dev.parent = &indio_dev->dev;
+	dev_set_drvdata(&buf->dev, (void *)buf);
+
+	return buf;
+}
+
+static inline void sca3000_rb_free(struct iio_ring_buffer *r)
+{
+	if (r)
+		iio_put_ring_buffer(r);
+}
+
+int sca3000_configure_ring(struct iio_dev *indio_dev)
+{
+	indio_dev->ring = sca3000_rb_allocate(indio_dev);
+	if (indio_dev->ring == NULL)
+		return -ENOMEM;
+	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
+
+	indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
+	indio_dev->ring->access.get_length = &sca3000_ring_get_length;
+	indio_dev->ring->access.get_bpd = &sca3000_ring_get_bpd;
+
+	return 0;
+}
+
+void sca3000_unconfigure_ring(struct iio_dev *indio_dev)
+{
+	sca3000_rb_free(indio_dev->ring);
+}
+
+static inline
+int __sca3000_hw_ring_state_set(struct iio_dev *indio_dev, bool state)
+{
+	struct sca3000_state *st = indio_dev->dev_data;
+	int ret;
+	u8 *rx;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	if (ret)
+		goto error_ret;
+	if (state) {
+		printk(KERN_INFO "supposedly enabling ring buffer\n");
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_MODE,
+					(rx[1] | SCA3000_RING_BUF_ENABLE));
+	} else
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_MODE,
+					(rx[1] & ~SCA3000_RING_BUF_ENABLE));
+	kfree(rx);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret;
+}
+/**
+ * sca3000_hw_ring_preenable() hw ring buffer preenable function
+ *
+ * Very simple enable function as the chip will allows normal reads
+ * during ring buffer operation so as long as it is indeed running
+ * before we notify the core, the precise ordering does not matter.
+ **/
+static int sca3000_hw_ring_preenable(struct iio_dev *indio_dev)
+{
+	return __sca3000_hw_ring_state_set(indio_dev, 1);
+}
+
+static int sca3000_hw_ring_postdisable(struct iio_dev *indio_dev)
+{
+	return __sca3000_hw_ring_state_set(indio_dev, 0);
+}
+
+void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
+{
+	indio_dev->ring->preenable = &sca3000_hw_ring_preenable;
+	indio_dev->ring->postdisable = &sca3000_hw_ring_postdisable;
+}
+
+/**
+ * sca3000_ring_int_process() ring specific interrupt handling.
+ *
+ * This is only split from the main interrupt handler so as to
+ * reduce the amount of code if the ring buffer is not enabled.
+ **/
+void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring)
+{
+	if (val & SCA3000_INT_STATUS_THREE_QUARTERS)
+		iio_push_or_escallate_ring_event(ring,
+						 IIO_EVENT_CODE_RING_75_FULL,
+						 0);
+	else if (val & SCA3000_INT_STATUS_HALF)
+		iio_push_ring_event(ring,
+				    IIO_EVENT_CODE_RING_50_FULL, 0);
+}
diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig
new file mode 100644
index 0000000..b8c2858
--- /dev/null
+++ b/drivers/staging/iio/adc/Kconfig
@@ -0,0 +1,13 @@
+#
+# ADC drivers
+#
+comment "Analog to digital convertors"
+
+config MAX1363
+	tristate "MAXIM max1363 ADC driver"
+	depends on I2C
+	help
+	  Say yes here to build support for many MAXIM i2c analog to digital
+	  convertors (ADC). (max1361, max1362, max1363, max1364, max1136,
+	  max1136, max1137, max1138, max1139, max1236, max1237, max11238,
+	  max1239) Provides direct access via sysfs.
diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile
new file mode 100644
index 0000000..0c2b6f3
--- /dev/null
+++ b/drivers/staging/iio/adc/Makefile
@@ -0,0 +1,8 @@
+
+# Makefile for industrial I/O ADC drivers
+#
+
+max1363-y := max1363_core.o
+max1363-$(CONFIG_IIO_RING_BUFFER) += max1363_ring.o
+
+obj-$(CONFIG_MAX1363) += max1363.o
diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h
new file mode 100644
index 0000000..d925b2c
--- /dev/null
+++ b/drivers/staging/iio/adc/adc.h
@@ -0,0 +1,13 @@
+/*
+ * adc.h - sysfs attributes associated with ADCs
+ *
+ * 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.
+ *
+ * Copyright (c) 2008 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ */
+
+#define IIO_DEV_ATTR_ADC(_num, _show, _addr)			\
+  IIO_DEVICE_ATTR(adc_##_num, S_IRUGO, _show, NULL, _addr)
diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h
new file mode 100644
index 0000000..8aca81f
--- /dev/null
+++ b/drivers/staging/iio/adc/max1363.h
@@ -0,0 +1,269 @@
+#ifndef _MAX1363_H_
+#define  _MAX1363_H_
+
+#define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
+
+/* There is a fair bit more defined here than currently
+ * used, but the intention is to support everything these
+ * chips do in the long run */
+
+/* see data sheets */
+/* max1363 and max1236, max1237, max1238, max1239 */
+#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD	0x00
+#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF	0x20
+#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT	0x40
+#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT	0x60
+#define MAX1363_SETUP_POWER_UP_INT_REF		0x10
+#define MAX1363_SETUP_POWER_DOWN_INT_REF	0x00
+
+/* think about includeing max11600 etc - more settings */
+#define MAX1363_SETUP_EXT_CLOCK			0x08
+#define MAX1363_SETUP_INT_CLOCK			0x00
+#define MAX1363_SETUP_UNIPOLAR			0x00
+#define MAX1363_SETUP_BIPOLAR			0x04
+#define MAX1363_SETUP_RESET			0x00
+#define MAX1363_SETUP_NORESET			0x02
+/* max1363 only - though don't care on others.
+ * For now monitor modes are not implemented as the relevant
+ * line is not connected on my test board.
+ * The definitions are here as I intend to add this soon.
+ */
+#define MAX1363_SETUP_MONITOR_SETUP		0x01
+
+/* Specific to the max1363 */
+#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
+#define MAX1363_MON_CONV_RATE_133ksps		0
+#define MAX1363_MON_CONV_RATE_66_5ksps		0x02
+#define MAX1363_MON_CONV_RATE_33_3ksps		0x04
+#define MAX1363_MON_CONV_RATE_16_6ksps		0x06
+#define MAX1363_MON_CONV_RATE_8_3ksps		0x08
+#define MAX1363_MON_CONV_RATE_4_2ksps		0x0A
+#define MAX1363_MON_CONV_RATE_2_0ksps		0x0C
+#define MAX1363_MON_CONV_RATE_1_0ksps		0x0E
+#define MAX1363_MON_INT_ENABLE			0x01
+
+/* defined for readability reasons */
+/* All chips */
+#define MAX1363_CONFIG_BYTE(a) ((a))
+
+#define MAX1363_CONFIG_SE			0x01
+#define MAX1363_CONFIG_DE			0x00
+#define MAX1363_CONFIG_SCAN_TO_CS		0x00
+#define MAX1363_CONFIG_SCAN_SINGLE_8		0x20
+#define MAX1363_CONFIG_SCAN_MONITOR_MODE	0x40
+#define MAX1363_CONFIG_SCAN_SINGLE_1		0x60
+/* max123{6-9} only */
+#define MAX1236_SCAN_MID_TO_CHANNEL		0x40
+
+/* max1363 only - merely part of channel selects or don't care for others*/
+#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
+
+#define MAX1363_CHANNEL_SEL(a) ((a) << 1)
+
+/* max1363 strictly 0x06 - but doesn't matter */
+#define MAX1363_CHANNEL_SEL_MASK		0x1E
+#define MAX1363_SCAN_MASK			0x60
+#define MAX1363_SE_DE_MASK			0x01
+
+/**
+ * struct max1363_mode - scan mode information
+ * @name:	Name used to identify the scan mode.
+ * @conf:	The corresponding value of the configuration register
+ * @numvals:	The number of values returned by a single scan
+ */
+struct max1363_mode {
+	const char	*name;
+	int8_t		conf;
+	int		numvals;
+};
+
+#define MAX1363_MODE_SINGLE(_num) {					\
+		.name = #_num,						\
+			.conf = MAX1363_CHANNEL_SEL(_num)		\
+			| MAX1363_CONFIG_SCAN_SINGLE_1			\
+			| MAX1363_CONFIG_SE,				\
+			.numvals = 1,					\
+			}
+
+#define MAX1363_MODE_SINGLE_TIMES_8(_num) {				\
+		.name = #_num"x8",					\
+			.conf = MAX1363_CHANNEL_SEL(_num)		\
+			| MAX1363_CONFIG_SCAN_SINGLE_8			\
+			| MAX1363_CONFIG_SE,				\
+			.numvals = 8,					\
+			}
+
+#define MAX1363_MODE_SCAN_TO_CHANNEL(_num) {				\
+		.name = "0..."#_num,					\
+			.conf = MAX1363_CHANNEL_SEL(_num)		\
+			| MAX1363_CONFIG_SCAN_TO_CS			\
+			| MAX1363_CONFIG_SE,				\
+			.numvals = _num + 1,				\
+			}
+
+
+/* note not available for max1363 hence naming */
+#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num) {			\
+		.name = #_mid"..."#_num,				\
+			.conf = MAX1363_CHANNEL_SEL(_num)		\
+			| MAX1236_SCAN_MID_TO_CHANNEL			\
+			| MAX1363_CONFIG_SE,				\
+			.numvals = _num - _mid + 1			\
+}
+
+#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm) {			\
+		.name = #_nump"-"#_numm,				\
+			.conf = MAX1363_CHANNEL_SEL(_nump)		\
+			| MAX1363_CONFIG_SCAN_SINGLE_1			\
+			| MAX1363_CONFIG_DE,				\
+			.numvals = 1,					\
+			}
+
+#define MAX1363_MODE_DIFF_SINGLE_TIMES_8(_nump, _numm) {		\
+		.name = #_nump"-"#_numm,				\
+			.conf = MAX1363_CHANNEL_SEL(_nump)		\
+			| MAX1363_CONFIG_SCAN_SINGLE_8			\
+			| MAX1363_CONFIG_DE,				\
+			.numvals = 1,					\
+			}
+
+/* Can't think how to automate naming so specify for now */
+#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(_name, _num, _numvals) { \
+		.name = #_name,						\
+			.conf = MAX1363_CHANNEL_SEL(_num)		\
+			| MAX1363_CONFIG_SCAN_TO_CS			\
+			| MAX1363_CONFIG_DE,				\
+			.numvals = _numvals,				\
+			}
+
+/* note only available for max1363 hence naming */
+#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(_name, _num, _numvals) { \
+    .name = #_name,							\
+			.conf = MAX1363_CHANNEL_SEL(_num)		\
+			| MAX1236_SCAN_MID_TO_CHANNEL			\
+			| MAX1363_CONFIG_SE,				\
+			.numvals = _numvals,				\
+}
+
+/* Not currently handled */
+#define MAX1363_MODE_MONITOR {					\
+		.name = "monitor",				\
+			.conf = MAX1363_CHANNEL_SEL(3)		\
+			| MAX1363_CONFIG_SCAN_MONITOR_MODE	\
+			| MAX1363_CONFIG_SE,			\
+			.numvals = 10,				\
+		}
+
+/* This may seem an overly long winded way to do this, but at least it makes
+ * clear what all the various options actually do. Alternative suggestions
+ * that don't require user to have intimate knowledge of the chip welcomed.
+ */
+
+/* This must be maintained along side the max1363_mode_table in max1363_core */
+enum max1363_modes {
+	/* Single read of a single channel */
+	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
+	/* Eight reads of a single channel */
+	se0, se1, se2, se3, se4, se5, se6, se7, se8, se9, se10, se11,
+	/* Scan to channel */
+	s0to1, s0to2, s0to3, s0to4, s0to5, s0to6,
+	s0to7, s0to8, s0to9, s0to10, s0to11,
+	/* Differential single read */
+	d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
+	d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
+	/* Differential single read 8 times */
+	de0m1, de2m3, de4m5, de6m7, de8m9, de10m11,
+	de1m0, de3m2, de5m4, de7m6, de9m8, de11m10,
+	/* Differential scan to channel */
+	d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11,
+	d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10,
+	/* Scan mid to channel max123{6-9} only */
+	s2to3, s6to7, s6to8, s6to9, s6to10, s6to11,
+	/* Differential scan mid to channel */
+	s6m7to8m9, s6m7to10m11, s7m6to9m8, s7m6to11m10,
+};
+
+/**
+ * struct max1363_chip_info - chip specifc information
+ * @name:		indentification string for chip
+ * @num_inputs:		number of physical inputs on chip
+ * @int_vref_mv:	the internal reference voltage
+ * @monitor_mode:	whether the chip supports monitor interrupts
+ * @mode_list:		array of available scan modes
+ * @num_modes:		the number of scan modes available
+ * @default_mode:	the scan mode in which the chip starts up
+ */
+struct max1363_chip_info {
+	const char			*name;
+	u8				num_inputs;
+	u16				int_vref_mv;
+	bool				monitor_mode;
+	const enum max1363_modes	*mode_list;
+	int				num_modes;
+	enum max1363_modes		default_mode;
+};
+
+
+/**
+ * struct max1363_state - driver instance specific data
+ * @indio_dev:		the industrial I/O device
+ * @client:		i2c_client
+ * @setupbyte:		cache of current device setup byte
+ * @configbyte:		cache of current device config byte
+ * @chip_info:		chip model specific constants, available modes etc
+ * @current_mode:	the scan mode of this chip
+ * @poll_work:		bottom half of polling interrupt handler
+ * @protect_ring:	used to ensure only one polling bh running at a time
+ * @reg:		supply regulator
+ */
+struct max1363_state {
+	struct iio_dev			*indio_dev;
+	struct i2c_client		*client;
+	char				setupbyte;
+	char				configbyte;
+	const struct max1363_chip_info	*chip_info;
+	const struct max1363_mode	*current_mode;
+	struct work_struct		poll_work;
+	atomic_t			protect_ring;
+	struct iio_trigger		*trig;
+	struct regulator		*reg;
+};
+#ifdef CONFIG_IIO_RING_BUFFER
+
+ssize_t max1363_scan_from_ring(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf);
+int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
+void max1363_ring_cleanup(struct iio_dev *indio_dev);
+
+int max1363_initialize_ring(struct iio_ring_buffer *ring);
+void max1363_uninitialize_ring(struct iio_ring_buffer *ring);
+
+#else /* CONFIG_IIO_RING_BUFFER */
+
+static inline void max1363_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+};
+
+static inline int max1363_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return 0;
+};
+
+
+static inline ssize_t max1363_scan_from_ring(struct device *dev,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	return 0;
+};
+
+static inline int
+max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
+{
+	return 0;
+};
+
+static inline void max1363_ring_cleanup(struct iio_dev *indio_dev) {};
+#endif /* CONFIG_IIO_RING_BUFFER */
+#endif /* _MAX1363_H_ */
diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c
new file mode 100644
index 0000000..9703881
--- /dev/null
+++ b/drivers/staging/iio/adc/max1363_core.c
@@ -0,0 +1,623 @@
+ /*
+ * linux/drivers/industrialio/adc/max1363.c
+ * Copyright (C) 2008 Jonathan Cameron
+ *
+ * based on linux/drivers/i2c/chips/max123x
+ * Copyright (C) 2002-2004 Stefan Eletzhofer
+ *
+ * based on linux/drivers/acron/char/pcf8583.c
+ * Copyright (C) 2000 Russell King
+ *
+ * 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.
+ *
+ * max1363.c
+ *
+ * Partial support for max1363 and similar chips.
+ *
+ * Not currently implemented.
+ *
+ * - Monitor interrrupt generation.
+ * - Control of internal reference.
+ * - Sysfs scan interface currently assumes unipolar mode.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+#include <linux/regulator/consumer.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+
+#include "max1363.h"
+
+/* Available scan modes.
+ * Awkwardly the associated enum is in the header so it is available to
+ * the ring buffer code.
+ */
+static const struct  max1363_mode max1363_mode_table[] = {
+	MAX1363_MODE_SINGLE(0),
+	MAX1363_MODE_SINGLE(1),
+	MAX1363_MODE_SINGLE(2),
+	MAX1363_MODE_SINGLE(3),
+	MAX1363_MODE_SINGLE(4),
+	MAX1363_MODE_SINGLE(5),
+	MAX1363_MODE_SINGLE(6),
+	MAX1363_MODE_SINGLE(7),
+	MAX1363_MODE_SINGLE(8),
+	MAX1363_MODE_SINGLE(9),
+	MAX1363_MODE_SINGLE(10),
+	MAX1363_MODE_SINGLE(11),
+
+	MAX1363_MODE_SINGLE_TIMES_8(0),
+	MAX1363_MODE_SINGLE_TIMES_8(1),
+	MAX1363_MODE_SINGLE_TIMES_8(2),
+	MAX1363_MODE_SINGLE_TIMES_8(3),
+	MAX1363_MODE_SINGLE_TIMES_8(4),
+	MAX1363_MODE_SINGLE_TIMES_8(5),
+	MAX1363_MODE_SINGLE_TIMES_8(6),
+	MAX1363_MODE_SINGLE_TIMES_8(7),
+	MAX1363_MODE_SINGLE_TIMES_8(8),
+	MAX1363_MODE_SINGLE_TIMES_8(9),
+	MAX1363_MODE_SINGLE_TIMES_8(10),
+	MAX1363_MODE_SINGLE_TIMES_8(11),
+
+	MAX1363_MODE_SCAN_TO_CHANNEL(1),
+	MAX1363_MODE_SCAN_TO_CHANNEL(2),
+	MAX1363_MODE_SCAN_TO_CHANNEL(3),
+	MAX1363_MODE_SCAN_TO_CHANNEL(4),
+	MAX1363_MODE_SCAN_TO_CHANNEL(5),
+	MAX1363_MODE_SCAN_TO_CHANNEL(6),
+	MAX1363_MODE_SCAN_TO_CHANNEL(7),
+	MAX1363_MODE_SCAN_TO_CHANNEL(8),
+	MAX1363_MODE_SCAN_TO_CHANNEL(9),
+	MAX1363_MODE_SCAN_TO_CHANNEL(10),
+	MAX1363_MODE_SCAN_TO_CHANNEL(11),
+
+	MAX1363_MODE_DIFF_SINGLE(0, 1),
+	MAX1363_MODE_DIFF_SINGLE(2, 3),
+	MAX1363_MODE_DIFF_SINGLE(4, 5),
+	MAX1363_MODE_DIFF_SINGLE(6, 7),
+	MAX1363_MODE_DIFF_SINGLE(8, 9),
+	MAX1363_MODE_DIFF_SINGLE(10, 11),
+	MAX1363_MODE_DIFF_SINGLE(1, 0),
+	MAX1363_MODE_DIFF_SINGLE(3, 2),
+	MAX1363_MODE_DIFF_SINGLE(5, 4),
+	MAX1363_MODE_DIFF_SINGLE(7, 6),
+	MAX1363_MODE_DIFF_SINGLE(9, 8),
+	MAX1363_MODE_DIFF_SINGLE(11, 10),
+
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(0, 1),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(2, 3),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(4, 5),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(6, 7),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(8, 9),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(10, 11),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(1, 0),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(3, 2),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(5, 4),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(7, 6),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(9, 8),
+	MAX1363_MODE_DIFF_SINGLE_TIMES_8(11, 10),
+
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...2-3, 2, 2),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...4-5, 4, 3),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...6-7, 6, 4),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...8-9, 8, 5),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(0-1...10-11, 10, 6),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...3-2, 3, 2),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...5-4, 5, 3),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...7-6, 7, 4),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...9-8, 9, 5),
+	MAX1363_MODE_DIFF_SCAN_TO_CHANNEL_NAMED(1-0...11-10, 11, 6),
+
+	MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3),
+	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7),
+	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8),
+	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9),
+	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10),
+	MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11),
+
+	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(6-7...8-9, 8, 2),
+	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(6-7...10-11, 10, 3),
+	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(7-6...9-8, 9, 2),
+	MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL_NAMED(7-6...11-10, 11, 3),
+};
+
+/* Applies to max1363 */
+static const enum max1363_modes max1363_mode_list[] = {
+	_s0, _s1, _s2, _s3,
+	se0, se1, se2, se3,
+	s0to1, s0to2, s0to3,
+	d0m1, d2m3, d1m0, d3m2,
+	de0m1, de2m3, de1m0, de3m2,
+	d0m1to2m3, d1m0to3m2,
+};
+
+/* Appies to max1236, max1237 */
+static const enum max1363_modes max1236_mode_list[] = {
+	_s0, _s1, _s2, _s3,
+	se0, se1, se2, se3,
+	s0to1, s0to2, s0to3,
+	d0m1, d2m3, d1m0, d3m2,
+	de0m1, de2m3, de1m0, de3m2,
+	d0m1to2m3, d1m0to3m2,
+	s2to3,
+};
+
+/* Applies to max1238, max1239 */
+static const enum max1363_modes max1238_mode_list[] = {
+	_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
+	se0, se1, se2, se3, se4, se5, se6, se7, se8, se9, se10, se11,
+	s0to1, s0to2, s0to3, s0to4, s0to5, s0to6,
+	s0to7, s0to8, s0to9, s0to10, s0to11,
+	d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
+	d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
+	de0m1, de2m3, de4m5, de6m7, de8m9, de10m11,
+	de1m0, de3m2, de5m4, de7m6, de9m8, de11m10,
+	d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11,
+	d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10,
+	s6to7, s6to8, s6to9, s6to10, s6to11,
+	s6m7to8m9, s6m7to10m11, s7m6to9m8, s7m6to11m10,
+};
+
+
+enum { max1361,
+       max1362,
+       max1363,
+       max1364,
+       max1136,
+       max1137,
+       max1138,
+       max1139,
+       max1236,
+       max1237,
+       max1238,
+       max1239,
+};
+
+/* max1363 and max1368 tested - rest from data sheet */
+static const struct max1363_chip_info max1363_chip_info_tbl[] = {
+	{
+		.name = "max1361",
+		.num_inputs = 4,
+		.monitor_mode = 1,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1362",
+		.num_inputs = 4,
+		.monitor_mode = 1,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1363",
+		.num_inputs = 4,
+		.monitor_mode = 1,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1364",
+		.num_inputs = 4,
+		.monitor_mode = 1,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1136",
+		.num_inputs = 4,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1137",
+		.num_inputs = 4,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1138",
+		.num_inputs = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+	}, {
+		.name = "max1139",
+		.num_inputs = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+	}, {
+		.name = "max1236",
+		.num_inputs = 4,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1237",
+		.num_inputs = 4,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+	}, {
+		.name = "max1238",
+		.num_inputs = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+	}, {
+		.name = "max1239",
+		.num_inputs = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+	},
+};
+
+static int max1363_write_basic_config(struct i2c_client *client,
+				      unsigned char d1,
+				      unsigned char d2)
+{
+	int ret;
+	u8 *tx_buf = kmalloc(2 , GFP_KERNEL);
+	if (!tx_buf)
+		return -ENOMEM;
+	tx_buf[0] = d1;
+	tx_buf[1] = d2;
+
+	ret = i2c_master_send(client, tx_buf, 2);
+	kfree(tx_buf);
+	return (ret > 0) ? 0 : ret;
+}
+
+static int max1363_set_scan_mode(struct max1363_state *st)
+{
+	st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK
+			    | MAX1363_SCAN_MASK
+			    | MAX1363_SE_DE_MASK);
+	st->configbyte |= st->current_mode->conf;
+
+	return max1363_write_basic_config(st->client,
+					  st->setupbyte,
+					  st->configbyte);
+}
+
+static int max1363_initial_setup(struct max1363_state *st)
+{
+	st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD
+		| MAX1363_SETUP_POWER_UP_INT_REF
+		| MAX1363_SETUP_INT_CLOCK
+		| MAX1363_SETUP_UNIPOLAR
+		| MAX1363_SETUP_NORESET;
+
+	/* Set scan mode writes the config anyway so wait until then*/
+	st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte);
+	st->current_mode = &max1363_mode_table[st->chip_info->default_mode];
+	st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte);
+
+	return max1363_set_scan_mode(st);
+}
+
+static ssize_t max1363_show_av_scan_modes(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct max1363_state *st = dev_info->dev_data;
+	int i, len = 0;
+
+	for (i = 0; i < st->chip_info->num_modes; i++)
+		len += sprintf(buf + len, "%s ",
+			       max1363_mode_table[st->chip_info
+						  ->mode_list[i]].name);
+	len += sprintf(buf + len, "\n");
+
+	return len;
+}
+
+
+/* The dev here is the sysfs related one, not the underlying i2c one */
+static ssize_t max1363_scan_direct(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct max1363_state *st = dev_info->dev_data;
+	int len = 0, ret, i;
+	struct i2c_client *client = st->client;
+	char *rxbuf;
+
+	if (st->current_mode->numvals == 0)
+		return 0;
+	rxbuf = kmalloc(st->current_mode->numvals*2, GFP_KERNEL);
+	if (rxbuf == NULL)
+		return -ENOMEM;
+
+	/* Interpretation depends on whether these are signed or not!*/
+	/* Assume not for now */
+	ret = i2c_master_recv(client, rxbuf, st->current_mode->numvals*2);
+
+	if (ret < 0)
+		return ret;
+	for (i = 0; i < st->current_mode->numvals; i++)
+		len += sprintf(buf+len, "%d ",
+			       ((int)(rxbuf[i*2+0]&0x0F) << 8)
+			       + ((int)(rxbuf[i*2+1])));
+	kfree(rxbuf);
+	len += sprintf(buf + len, "\n");
+
+	return len;
+}
+
+static ssize_t max1363_scan(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	int ret;
+
+	mutex_lock(&dev_info->mlock);
+	if (dev_info->currentmode == INDIO_RING_TRIGGERED)
+		ret = max1363_scan_from_ring(dev, attr, buf);
+	else
+		ret = max1363_scan_direct(dev, attr, buf);
+	mutex_unlock(&dev_info->mlock);
+
+	return ret;
+}
+
+/* Cannot query the device, so use local copy of state */
+static ssize_t max1363_show_scan_mode(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct max1363_state *st = dev_info->dev_data;
+
+	return sprintf(buf, "%s\n", st->current_mode->name);
+}
+
+static const struct max1363_mode
+*__max1363_find_mode_in_ci(const struct max1363_chip_info *info,
+				  const char *buf)
+{
+	int i;
+	for (i = 0; i <  info->num_modes; i++)
+		if (strcmp(max1363_mode_table[info->mode_list[i]].name, buf)
+		    == 0)
+			return &max1363_mode_table[info->mode_list[i]];
+	return NULL;
+}
+
+static ssize_t max1363_store_scan_mode(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf,
+				       size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct max1363_state *st = dev_info->dev_data;
+	const struct max1363_mode *new_mode;
+	int ret;
+
+	mutex_lock(&dev_info->mlock);
+	new_mode = NULL;
+	/* Avoid state changes if a ring buffer is enabled */
+	if (!iio_ring_enabled(dev_info)) {
+		new_mode
+			= __max1363_find_mode_in_ci(st->chip_info, buf);
+		if (!new_mode) {
+			ret = -EINVAL;
+			goto error_ret;
+		}
+		st->current_mode = new_mode;
+		ret =  max1363_set_scan_mode(st);
+		if (ret)
+			goto error_ret;
+	} else {
+		ret = -EBUSY;
+		goto error_ret;
+	}
+	mutex_unlock(&dev_info->mlock);
+
+	return len;
+
+error_ret:
+	mutex_unlock(&dev_info->mlock);
+
+	return ret;
+}
+
+IIO_DEV_ATTR_AVAIL_SCAN_MODES(max1363_show_av_scan_modes);
+IIO_DEV_ATTR_SCAN_MODE(S_IRUGO | S_IWUSR,
+		       max1363_show_scan_mode,
+		       max1363_store_scan_mode);
+
+IIO_DEV_ATTR_SCAN(max1363_scan);
+
+static ssize_t max1363_show_name(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct max1363_state *st = dev_info->dev_data;
+	return sprintf(buf, "%s\n", st->chip_info->name);
+}
+
+IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0);
+
+/*name export */
+
+static struct attribute *max1363_attributes[] = {
+	&iio_dev_attr_available_scan_modes.dev_attr.attr,
+	&iio_dev_attr_scan_mode.dev_attr.attr,
+	&iio_dev_attr_scan.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group max1363_attribute_group = {
+	.attrs = max1363_attributes,
+};
+
+static int __devinit max1363_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	int ret, i, regdone = 0;
+	struct max1363_state *st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, st);
+
+	atomic_set(&st->protect_ring, 0);
+
+	/* Find the chip model specific data */
+	for (i = 0; i < ARRAY_SIZE(max1363_chip_info_tbl); i++)
+		if (!strcmp(max1363_chip_info_tbl[i].name, id->name)) {
+			st->chip_info = &max1363_chip_info_tbl[i];
+			break;
+		};
+	/* Unsupported chip */
+	if (!st->chip_info) {
+		dev_err(&client->dev, "%s is not supported\n", id->name);
+		ret = -ENODEV;
+		goto error_free_st;
+	}
+	st->reg = regulator_get(&client->dev, "vcc");
+	if (!IS_ERR(st->reg)) {
+		ret = regulator_enable(st->reg);
+		if (ret)
+			goto error_put_reg;
+	}
+	st->client = client;
+
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_disable_reg;
+	}
+
+	/* Estabilish that the iio_dev is a child of the i2c device */
+	st->indio_dev->dev.parent = &client->dev;
+	st->indio_dev->attrs = &max1363_attribute_group;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = max1363_initial_setup(st);
+	if (ret)
+		goto error_free_device;
+
+	ret = max1363_register_ring_funcs_and_init(st->indio_dev);
+	if (ret)
+		goto error_free_device;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_cleanup_ring;
+	regdone = 1;
+	ret = max1363_initialize_ring(st->indio_dev->ring);
+	if (ret)
+		goto error_cleanup_ring;
+	return 0;
+error_cleanup_ring:
+	max1363_ring_cleanup(st->indio_dev);
+error_free_device:
+	if (!regdone)
+		iio_free_device(st->indio_dev);
+	else
+		iio_device_unregister(st->indio_dev);
+error_disable_reg:
+	if (!IS_ERR(st->reg))
+		regulator_disable(st->reg);
+error_put_reg:
+	if (!IS_ERR(st->reg))
+		regulator_put(st->reg);
+error_free_st:
+	kfree(st);
+
+error_ret:
+	return ret;
+}
+
+static int max1363_remove(struct i2c_client *client)
+{
+	struct max1363_state *st = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = st->indio_dev;
+	max1363_uninitialize_ring(indio_dev->ring);
+	max1363_ring_cleanup(indio_dev);
+	iio_device_unregister(indio_dev);
+	if (!IS_ERR(st->reg)) {
+		regulator_disable(st->reg);
+		regulator_put(st->reg);
+	}
+	kfree(st);
+
+	return 0;
+}
+
+static const struct i2c_device_id max1363_id[] = {
+	{ "max1361", max1361 },
+	{ "max1362", max1362 },
+	{ "max1363", max1363 },
+	{ "max1364", max1364 },
+	{ "max1136", max1136 },
+	{ "max1137", max1137 },
+	{ "max1138", max1138 },
+	{ "max1139", max1139 },
+	{ "max1236", max1236 },
+	{ "max1237", max1237 },
+	{ "max1238", max1238 },
+	{ "max1239", max1239 },
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, max1363_id);
+
+static struct i2c_driver max1363_driver = {
+	.driver = {
+		.name = "max1363",
+	},
+	.probe = max1363_probe,
+	.remove = max1363_remove,
+	.id_table = max1363_id,
+};
+
+static __init int max1363_init(void)
+{
+	return i2c_add_driver(&max1363_driver);
+}
+
+static __exit void max1363_exit(void)
+{
+	i2c_del_driver(&max1363_driver);
+}
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("Maxim 1363 ADC");
+MODULE_LICENSE("GPL v2");
+
+module_init(max1363_init);
+module_exit(max1363_exit);
diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c
new file mode 100644
index 0000000..a953eac
--- /dev/null
+++ b/drivers/staging/iio/adc/max1363_ring.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2008 Jonathan Cameron
+ *
+ * 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.
+ *
+ * max1363_ring.c
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+#include <linux/i2c.h>
+
+#include "../iio.h"
+#include "../ring_generic.h"
+#include "../ring_sw.h"
+#include "../trigger.h"
+#include "../sysfs.h"
+
+#include "max1363.h"
+
+ssize_t max1363_scan_from_ring(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct max1363_state *info = dev_info->dev_data;
+	int i, ret, len = 0;
+	char *ring_data;
+
+	ring_data = kmalloc(info->current_mode->numvals*2, GFP_KERNEL);
+	if (ring_data == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	ret = dev_info->ring->access.read_last(dev_info->ring, ring_data);
+	if (ret)
+		goto error_free_ring_data;
+	len += sprintf(buf+len, "ring ");
+	for (i = 0; i < info->current_mode->numvals; i++)
+		len += sprintf(buf + len, "%d ",
+			       ((int)(ring_data[i*2 + 0] & 0x0F) << 8)
+			       + ((int)(ring_data[i*2 + 1])));
+	len += sprintf(buf + len, "\n");
+	kfree(ring_data);
+
+	return len;
+
+error_free_ring_data:
+	kfree(ring_data);
+error_ret:
+	return ret;
+}
+
+/**
+ * max1363_ring_preenable() setup the parameters of the ring before enabling
+ *
+ * The complex nature of the setting of the nuber of bytes per datum is due
+ * to this driver currently ensuring that the timestamp is stored at an 8
+ * byte boundary.
+ **/
+static int max1363_ring_preenable(struct iio_dev *indio_dev)
+{
+	struct max1363_state *st = indio_dev->dev_data;
+	size_t d_size;
+
+	if (indio_dev->ring->access.set_bpd) {
+		d_size = st->current_mode->numvals*2 + sizeof(s64);
+		if (d_size % 8)
+			d_size += 8 - (d_size % 8);
+		indio_dev->ring->access.set_bpd(indio_dev->ring, d_size);
+	}
+
+	return 0;
+}
+
+/**
+ * max1363_ring_postenable() typical ring post enable
+ *
+ * Only not moved into the core for the hardware ring buffer cases
+ * that are more sophisticated.
+ **/
+static int max1363_ring_postenable(struct iio_dev *indio_dev)
+{
+	if (indio_dev->trig == NULL)
+		return 0;
+	return iio_trigger_attach_poll_func(indio_dev->trig,
+					    indio_dev->pollfunc);
+}
+
+/**
+ * max1363_ring_predisable() runs just prior to ring buffer being disabled
+ *
+ * Typical predisable function which ensures that no trigger events can
+ * occur before we disable the ring buffer (and hence would have no idea
+ * what to do with them)
+ **/
+static int max1363_ring_predisable(struct iio_dev *indio_dev)
+{
+	if (indio_dev->trig)
+		return iio_trigger_dettach_poll_func(indio_dev->trig,
+						     indio_dev->pollfunc);
+	else
+		return 0;
+}
+
+/**
+ * max1363_poll_func_th() th of trigger launched polling to ring buffer
+ *
+ * As sampling only occurs on i2c comms occuring, leave timestamping until
+ * then.  Some triggers will generate their own time stamp.  Currently
+ * there is no way of notifying them when no one cares.
+ **/
+void max1363_poll_func_th(struct iio_dev *indio_dev)
+{
+	struct max1363_state *st = indio_dev->dev_data;
+
+	schedule_work(&st->poll_work);
+
+	return;
+}
+/**
+ * max1363_poll_bh_to_ring() bh of trigger launched polling to ring buffer
+ * @work_s:	the work struct through which this was scheduled
+ *
+ * Currently there is no option in this driver to disable the saving of
+ * timestamps within the ring.
+ * I think the one copy of this at a time was to avoid problems if the
+ * trigger was set far too high and the reads then locked up the computer.
+ **/
+static void max1363_poll_bh_to_ring(struct work_struct *work_s)
+{
+	struct max1363_state *st = container_of(work_s, struct max1363_state,
+						  poll_work);
+	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(indio_dev->ring);
+	s64 time_ns;
+	__u8 *rxbuf;
+	int b_sent;
+	size_t d_size;
+
+	/* Ensure the timestamp is 8 byte aligned */
+	d_size = st->current_mode->numvals*2 + sizeof(s64);
+	if (d_size % sizeof(s64))
+		d_size += sizeof(s64) - (d_size % sizeof(s64));
+
+	/* Ensure only one copy of this function running at a time */
+	if (atomic_inc_return(&st->protect_ring) > 1)
+		return;
+
+	/* Monitor mode prevents reading. Whilst not currently implemented
+	 * might as well have this test in here in the meantime as it does
+	 * no harm.
+	 */
+	if (st->current_mode->numvals == 0)
+		return;
+
+	rxbuf = kmalloc(d_size,	GFP_KERNEL);
+	if (rxbuf == NULL)
+		return;
+
+	b_sent = i2c_master_recv(st->client,
+				 rxbuf,
+				 st->current_mode->numvals*2);
+	if (b_sent < 0)
+		goto done;
+
+	time_ns = iio_get_time_ns();
+
+	memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
+
+	indio_dev->ring->access.store_to(&ring->buf, rxbuf, time_ns);
+done:
+	kfree(rxbuf);
+	atomic_dec(&st->protect_ring);
+}
+
+
+int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
+{
+	struct max1363_state *st = indio_dev->dev_data;
+	int ret = 0;
+
+	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
+	if (!indio_dev->ring) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	/* Effectively select the ring buffer implementation */
+	iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
+	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
+		goto error_deallocate_sw_rb;
+	}
+	/* Configure the polling function called on trigger interrupts */
+	indio_dev->pollfunc->poll_func_main = &max1363_poll_func_th;
+	indio_dev->pollfunc->private_data = indio_dev;
+
+	/* Ring buffer functions - here trigger setup related */
+	indio_dev->ring->postenable = &max1363_ring_postenable;
+	indio_dev->ring->preenable = &max1363_ring_preenable;
+	indio_dev->ring->predisable = &max1363_ring_predisable;
+	INIT_WORK(&st->poll_work, &max1363_poll_bh_to_ring);
+
+	/* Flag that polled ring buffering is possible */
+	indio_dev->modes |= INDIO_RING_TRIGGERED;
+	return 0;
+error_deallocate_sw_rb:
+	iio_sw_rb_free(indio_dev->ring);
+error_ret:
+	return ret;
+}
+
+void max1363_ring_cleanup(struct iio_dev *indio_dev)
+{
+	/* ensure that the trigger has been detached */
+	if (indio_dev->trig) {
+		iio_put_trigger(indio_dev->trig);
+		iio_trigger_dettach_poll_func(indio_dev->trig,
+					      indio_dev->pollfunc);
+	}
+	kfree(indio_dev->pollfunc);
+	iio_sw_rb_free(indio_dev->ring);
+}
+
+void max1363_uninitialize_ring(struct iio_ring_buffer *ring)
+{
+	iio_ring_buffer_unregister(ring);
+};
+
+int max1363_initialize_ring(struct iio_ring_buffer *ring)
+{
+	return iio_ring_buffer_register(ring);
+};
diff --git a/drivers/staging/iio/chrdev.h b/drivers/staging/iio/chrdev.h
new file mode 100644
index 0000000..8bc64bf
--- /dev/null
+++ b/drivers/staging/iio/chrdev.h
@@ -0,0 +1,118 @@
+/* The industrial I/O core - character device related
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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 _IIO_CHRDEV_H_
+#define _IIO_CHRDEV_H_
+struct iio_dev;
+
+/**
+ * struct iio_handler - Structure used to specify file operations
+ *			for a particular chrdev
+ * @chrdev:	character device structure
+ * @id:		the location in the handler table - used for deallocation.
+ * @flags:	file operations related flags including busy flag.
+ * @private:	handler specific data used by the fileops registered with
+ *		the chrdev.
+ */
+struct iio_handler {
+	struct cdev	chrdev;
+	int		id;
+	unsigned long	flags;
+	void		*private;
+};
+
+#define iio_cdev_to_handler(cd)				\
+	container_of(cd, struct iio_handler, chrdev)
+
+/**
+ * struct iio_event_data - The actual event being pushed to userspace
+ * @id:		event identifier
+ * @timestamp:	best estimate of time of event occurance (often from
+ *		the interrupt handler)
+ */
+struct iio_event_data {
+	int	id;
+	s64	timestamp;
+};
+
+/**
+ * struct iio_detected_event_list - list element for events that have occured
+ * @list:		linked list header
+ * @ev:			the event itself
+ * @shared_pointer:	used when the event is shared - i.e. can be escallated
+ *			on demand (eg ring buffer 50%->100% full)
+ */
+struct iio_detected_event_list {
+	struct list_head		list;
+	struct iio_event_data		ev;
+	struct iio_shared_ev_pointer	*shared_pointer;
+};
+/**
+ * struct iio_shared_ev_pointer - allows shared events to identify if currently
+ *				in the detected event list
+ * @ev_p:	pointer to detected event list element (null if not in list)
+ * @lock:	protect this element to prevent simultaneous edit and remove
+ */
+struct iio_shared_ev_pointer {
+	struct iio_detected_event_list	*ev_p;
+	spinlock_t			lock;
+};
+
+/**
+ * struct iio_event_interface - chrdev interface for an event line
+ * @dev:		device assocated with event interface
+ * @handler:		fileoperations and related control for the chrdev
+ * @wait:		wait queue to allow blocking reads of events
+ * @event_list_lock:	mutex to protect the list of detected events
+ * @det_events:		list of detected events
+ * @max_events:		maximum number of events before new ones are dropped
+ * @current_events:	number of events in detected list
+ * @id:			indentifier to allow the event interface to know which
+ *			physical line it corresponds to
+ * @owner:		ensure the driver module owns the file, not iio
+ * @private:		driver specific data
+ * @_name:		used internally to store the sysfs name for minor id
+ *			attribute
+ */
+struct iio_event_interface {
+	struct device				dev;
+	struct iio_handler			handler;
+	wait_queue_head_t			wait;
+	struct mutex				event_list_lock;
+	struct iio_detected_event_list		det_events;
+	int					max_events;
+	int					current_events;
+	int					id;
+	struct iio_chrdev_minor_attr		attr;
+	struct module				*owner;
+	void					*private;
+	char					_name[20];
+	char					_attrname[20];
+};
+
+/**
+ * struct iio_event_handler_list - element in list of handlers for events
+ * @list:		list header
+ * @refcount:		as the handler may be shared between multiple device
+ *			side events, reference counting ensures clean removal
+ * @exist_lock:		prevents race conditions related to refcount useage.
+ * @handler:		event handler function - called on event if this
+ *			event_handler is enabled.
+ *
+ * Each device has one list of these per interrupt line
+ **/
+struct iio_event_handler_list {
+	struct list_head	list;
+	int			refcount;
+	struct mutex		exist_lock;
+	int (*handler)(struct iio_dev *dev_info, int index, s64 timestamp,
+		       int no_test);
+};
+
+#endif
diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h
new file mode 100644
index 0000000..25ccb80
--- /dev/null
+++ b/drivers/staging/iio/iio.h
@@ -0,0 +1,411 @@
+/* The industrial I/O core
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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 _INDUSTRIAL_IO_H_
+#define _INDUSTRIAL_IO_H_
+
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include "sysfs.h"
+#include "chrdev.h"
+
+/* IIO TODO LIST */
+/* Static device specific elements (conversion factors etc)
+ * should be exported via sysfs
+ *
+ * Provide means of adjusting timer accuracy.
+ * Currently assumes nano seconds.
+ */
+
+/* Event interface flags */
+#define IIO_BUSY_BIT_POS 1
+
+struct iio_dev;
+
+/**
+ * iio_get_time_ns() - utility function to get a time stamp for events etc
+ **/
+static inline s64 iio_get_time_ns(void)
+{
+	struct timespec ts;
+	/*
+	 * calls getnstimeofday.
+	 * If hrtimers then up to ns accurate, if not microsecond.
+	 */
+	ktime_get_real_ts(&ts);
+
+	return timespec_to_ns(&ts);
+}
+
+/**
+ * iio_add_event_to_list() - Wraps adding to event lists
+ * @el:		the list element of the event to be handled.
+ * @head:	the list associated with the event handler being used.
+ *
+ * Does reference counting to allow shared handlers.
+ **/
+void iio_add_event_to_list(struct iio_event_handler_list *el,
+			   struct list_head *head);
+
+/**
+ * iio_remove_event_from_list() - Wraps removing from event list
+ * @el:		element to be removed
+ * @head:	associate list head for the interrupt handler.
+ *
+ * Does reference counting to allow shared handlers.
+ **/
+void iio_remove_event_from_list(struct iio_event_handler_list *el,
+				struct list_head *head);
+
+/* Device operating modes */
+#define INDIO_DIRECT_MODE		0x01
+#define INDIO_RING_TRIGGERED		0x02
+#define INDIO_RING_HARDWARE_BUFFER	0x08
+
+#define INDIO_ALL_RING_MODES (INDIO_RING_TRIGGERED | INDIO_RING_HARDWARE_BUFFER)
+
+/* Vast majority of this is set by the industrialio subsystem on a
+ * call to iio_device_register. */
+
+/**
+ * struct iio_dev - industrial I/O device
+ * @id:			[INTERN] used to identify device internally
+ * @dev_data:		[DRIVER] device specific data
+ * @modes:		[DRIVER] operating modes supported by device
+ * @currentmode:	[DRIVER] current operating mode
+ * @dev:		[DRIVER] device structure, should be assigned a parent
+ *			and owner
+ * @attrs:		[DRIVER] general purpose device attributes
+ * @driver_module:	[DRIVER] module structure used to ensure correct
+ *			ownership of chrdevs etc
+ * @num_interrupt_lines:[DRIVER] number of physical interrupt lines from device
+ * @interrupts:		[INTERN] interrupt line specific event lists etc
+ * @event_attrs:	[DRIVER] event control attributes
+ * @event_conf_attrs:	[DRIVER] event configuration attributes
+ * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
+ * @ring:		[DRIVER] any ring buffer present
+ * @mlock:		[INTERN] lock used to prevent simultaneous device state
+ *			changes
+ * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
+ *			control method is used
+ * @scan_count:	[INTERN] the number of elements in the current scan mode
+ * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
+ * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
+ * @trig:		[INTERN] current device trigger (ring buffer modes)
+ * @pollfunc:		[DRIVER] function run on trigger being recieved
+ **/
+struct iio_dev {
+	int				id;
+	void				*dev_data;
+	int				modes;
+	int				currentmode;
+	struct device			dev;
+	const struct attribute_group	*attrs;
+	struct module			*driver_module;
+
+	int				num_interrupt_lines;
+	struct iio_interrupt		**interrupts;
+	struct attribute_group		*event_attrs;
+	struct attribute_group		*event_conf_attrs;
+
+	struct iio_event_interface	*event_interfaces;
+
+	struct iio_ring_buffer		*ring;
+	struct mutex			mlock;
+
+	struct attribute_group		*scan_el_attrs;
+	int				scan_count;
+
+	u16				scan_mask;
+	bool				scan_timestamp;
+	struct iio_trigger		*trig;
+	struct iio_poll_func		*pollfunc;
+};
+
+/*
+ * These are mainly provided to allow for a change of implementation if a device
+ * has a large number of scan elements
+ */
+#define IIO_MAX_SCAN_LENGTH 15
+
+static inline int iio_scan_mask_query(struct iio_dev *dev_info, int bit)
+{
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	else
+		return !!(dev_info->scan_mask & (1 << bit));
+};
+
+static inline int iio_scan_mask_set(struct iio_dev *dev_info, int bit)
+{
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	dev_info->scan_mask |= (1 << bit);
+	dev_info->scan_count++;
+	return 0;
+};
+
+static inline int iio_scan_mask_clear(struct iio_dev *dev_info, int bit)
+{
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	dev_info->scan_mask &= ~(1 << bit);
+	dev_info->scan_count--;
+	return 0;
+};
+
+/**
+ * iio_scan_mask_count_to_right() - how many scan elements occur before here
+ * @dev_info: the iio_device whose scan mode we are querying
+ * @bit: which number scan element is this
+ **/
+static inline int iio_scan_mask_count_to_right(struct iio_dev *dev_info,
+int bit)
+{
+	int count = 0;
+	int mask = (1 << bit);
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	while (mask) {
+		mask >>= 1;
+		if (mask & dev_info->scan_mask)
+			count++;
+	}
+
+	return count;
+}
+
+/**
+ * iio_device_register() - register a device with the IIO subsystem
+ * @dev_info:		Device structure filled by the device driver
+ **/
+int iio_device_register(struct iio_dev *dev_info);
+
+/**
+ * iio_device_unregister() - unregister a device from the IIO subsystem
+ * @dev_info:		Device structure representing the device.
+ **/
+void iio_device_unregister(struct iio_dev *dev_info);
+
+/**
+ * struct iio_interrupt - wrapper used to allow easy handling of multiple
+ *			physical interrupt lines
+ * @dev_info:		the iio device for which the is an interrupt line
+ * @line_number:	associated line number
+ * @id:			idr allocated unique id number
+ * @irq:		associate interrupt number
+ * @ev_list:		event handler list for associated events
+ * @ev_list_lock:	ensure only one access to list at a time
+ **/
+struct iio_interrupt {
+	struct iio_dev			*dev_info;
+	int				line_number;
+	int				id;
+	int				irq;
+	struct list_head		ev_list;
+	spinlock_t			ev_list_lock;
+};
+
+#define to_iio_interrupt(i) container_of(i, struct iio_interrupt, ev_list)
+
+/**
+ * iio_register_interrupt_line() - Tell IIO about interrupt lines
+ *
+ * @irq:		Typically provided via platform data
+ * @dev_info:		IIO device info structure for device
+ * @line_number:	Which interrupt line of the device is this?
+ * @type:		Interrupt type (e.g. edge triggered etc)
+ * @name:		Identifying name.
+ **/
+int iio_register_interrupt_line(unsigned int			irq,
+				struct iio_dev			*dev_info,
+				int				line_number,
+				unsigned long			type,
+				const char			*name);
+
+void iio_unregister_interrupt_line(struct iio_dev *dev_info,
+				   int line_number);
+
+
+
+/**
+ * iio_push_event() - try to add event to the list for userspace reading
+ * @dev_info:		IIO device structure
+ * @ev_line:		Which event line (hardware interrupt)
+ * @ev_code:		What event
+ * @timestamp:		When the event occured
+ **/
+int iio_push_event(struct iio_dev *dev_info,
+		  int ev_line,
+		  int ev_code,
+		  s64 timestamp);
+
+/**
+ * struct iio_work_cont - container for when singleton handler case matters
+ * @ws:			[DEVICE]work_struct when not only possible event
+ * @ws_nocheck:		[DEVICE]work_struct when only possible event
+ * @address:		[DEVICE]associated register address
+ * @mask:		[DEVICE]associated mask for identifying event source
+ * @st:			[DEVICE]device specific state information
+ **/
+struct iio_work_cont {
+	struct work_struct	ws;
+	struct work_struct	ws_nocheck;
+	int			address;
+	int			mask;
+	void			*st;
+};
+
+#define to_iio_work_cont_check(_ws)			\
+	container_of(_ws, struct iio_work_cont, ws)
+
+#define to_iio_work_cont_no_check(_ws)				\
+	container_of(_ws, struct iio_work_cont, ws_nocheck)
+
+/**
+ * iio_init_work_cont() - intiialize the elements of a work container
+ * @cont: the work container
+ * @_checkfunc: function called when there are multiple possible int sources
+ * @_nocheckfunc: function for when there is only one int source
+ * @_add: driver dependant, typically a register address
+ * @_mask: driver dependant, typically a bit mask for a register
+ * @_st: driver dependant, typically pointer to a device state structure
+ **/
+static inline void
+iio_init_work_cont(struct iio_work_cont *cont,
+		   void (*_checkfunc)(struct work_struct *),
+		   void (*_nocheckfunc)(struct work_struct *),
+		   int _add, int _mask, void *_st)
+{
+	INIT_WORK(&(cont)->ws, _checkfunc);
+	INIT_WORK(&(cont)->ws_nocheck, _nocheckfunc);
+	cont->address = _add;
+	cont->mask = _mask;
+	cont->st = _st;
+}
+/**
+ * __iio_push_event() tries to add an event to the list associated with a chrdev
+ * @ev_int:		the event interface to which we are pushing the event
+ * @ev_code:		the outgoing event code
+ * @timestamp:		timestamp of the event
+ * @shared_pointer_p:	the shared event pointer
+ **/
+int __iio_push_event(struct iio_event_interface *ev_int,
+		    int ev_code,
+		    s64 timestamp,
+		    struct iio_shared_ev_pointer*
+		    shared_pointer_p);
+/**
+ * __iio_change_event() change an event code in case of event escallation
+ * @ev:			the evnet to be changed
+ * @ev_code:		new event code
+ * @timestamp:		new timestamp
+ **/
+void __iio_change_event(struct iio_detected_event_list *ev,
+			int ev_code,
+			s64 timestamp);
+
+/**
+ * iio_setup_ev_int() Configure an event interface (chrdev)
+ * @name:		name used for resulting sysfs directory etc.
+ * @ev_int:		interface we are configuring
+ * @owner:		module that is responsible for registering this ev_int
+ * @dev:		device whose ev_int this is
+ **/
+int iio_setup_ev_int(struct iio_event_interface *ev_int,
+		     const char *name,
+		     struct module *owner,
+		     struct device *dev);
+
+void iio_free_ev_int(struct iio_event_interface *ev_int);
+
+/**
+ * iio_allocate_chrdev() - Allocate a chrdev
+ * @handler:	struct that contains relevant file handling for chrdev
+ * @dev_info:	iio_dev for which chrdev is being created
+ **/
+int iio_allocate_chrdev(struct iio_handler *handler, struct iio_dev *dev_info);
+void iio_deallocate_chrdev(struct iio_handler *handler);
+
+/* Used to distinguish between bipolar and unipolar scan elemenents.
+ * Whilst this may seem obvious, we may well want to change the representation
+ * in the future!*/
+#define IIO_SIGNED(a) -(a)
+#define IIO_UNSIGNED(a) (a)
+
+extern dev_t iio_devt;
+extern struct class iio_class;
+
+/**
+ * iio_put_device() - reference counted deallocated of struct device
+ * @dev: the iio_device containing the device
+ **/
+static inline void iio_put_device(struct iio_dev *dev)
+{
+	if (dev)
+		put_device(&dev->dev);
+};
+
+/**
+ * to_iio_dev() - get iio_dev for which we have have the struct device
+ * @d: the struct device
+ **/
+static inline struct iio_dev *to_iio_dev(struct device *d)
+{
+	return container_of(d, struct iio_dev, dev);
+};
+
+/**
+ * iio_dev_get_devdata() - helper function gets device specific data
+ * @d: the iio_dev associated with the device
+ **/
+static inline void *iio_dev_get_devdata(struct iio_dev *d)
+{
+	return d->dev_data;
+}
+
+/**
+ * iio_allocate_device() - allocate an iio_dev from a driver
+ **/
+struct iio_dev *iio_allocate_device(void);
+
+/**
+ * iio_free_device() - free an iio_dev from a driver
+ **/
+void iio_free_device(struct iio_dev *dev);
+
+/**
+ * iio_put() - internal module reference count reduce
+ **/
+void iio_put(void);
+
+/**
+ * iio_get() - internal module reference count increase
+ **/
+void iio_get(void);
+
+/* Ring buffer related */
+int iio_device_get_chrdev_minor(void);
+void iio_device_free_chrdev_minor(int val);
+
+/**
+ * iio_ring_enabled() helper function to test if any form of ring enabled
+ **/
+static inline bool iio_ring_enabled(struct iio_dev *dev_info)
+{
+	return dev_info->currentmode
+		& (INDIO_RING_TRIGGERED
+		   | INDIO_RING_HARDWARE_BUFFER);
+};
+
+struct idr;
+
+int iio_get_new_idr_val(struct idr *this_idr);
+void iio_free_idr_val(struct idr *this_idr, int id);
+#endif /* _INDUSTRIAL_IO_H_ */
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
new file mode 100644
index 0000000..1fa18f2
--- /dev/null
+++ b/drivers/staging/iio/industrialio-core.c
@@ -0,0 +1,851 @@
+/* The industrial I/O core
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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.
+ *
+ * Based on elements of hwmon and input subsystems.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/idr.h>
+#include <linux/kdev_t.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/poll.h>
+#include <linux/cdev.h>
+#include "iio.h"
+#include "trigger_consumer.h"
+
+#define IIO_ID_PREFIX "device"
+#define IIO_ID_FORMAT IIO_ID_PREFIX "%d"
+
+/* IDR to assign each registered device a unique id*/
+static DEFINE_IDR(iio_idr);
+
+/* IDR for general event identifiers */
+static DEFINE_IDR(iio_event_idr);
+/* IDR to allocate character device minor numbers */
+static DEFINE_IDR(iio_chrdev_idr);
+/* Lock used to protect both of the above */
+static DEFINE_SPINLOCK(iio_idr_lock);
+
+dev_t iio_devt;
+EXPORT_SYMBOL(iio_devt);
+
+#define IIO_DEV_MAX 256
+static char *iio_devnode(struct device *dev, mode_t *mode)
+{
+	return kasprintf(GFP_KERNEL, "iio/%s", dev_name(dev));
+}
+
+struct class iio_class = {
+	.name = "iio",
+	.devnode = iio_devnode,
+};
+EXPORT_SYMBOL(iio_class);
+
+void __iio_change_event(struct iio_detected_event_list *ev,
+			int ev_code,
+			s64 timestamp)
+{
+	ev->ev.id = ev_code;
+	ev->ev.timestamp = timestamp;
+}
+EXPORT_SYMBOL(__iio_change_event);
+
+/* Used both in the interrupt line put events and the ring buffer ones */
+
+/* Note that in it's current form someone has to be listening before events
+ * are queued. Hence a client MUST open the chrdev before the ring buffer is
+ * switched on.
+ */
+ int __iio_push_event(struct iio_event_interface *ev_int,
+		     int ev_code,
+		     s64 timestamp,
+		     struct iio_shared_ev_pointer *
+		     shared_pointer_p)
+{
+	struct iio_detected_event_list *ev;
+	int ret = 0;
+
+	/* Does anyone care? */
+	mutex_lock(&ev_int->event_list_lock);
+	if (test_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags)) {
+		if (ev_int->current_events == ev_int->max_events)
+			return 0;
+		ev = kmalloc(sizeof(*ev), GFP_KERNEL);
+		if (ev == NULL) {
+			ret = -ENOMEM;
+			goto error_ret;
+		}
+		ev->ev.id = ev_code;
+		ev->ev.timestamp = timestamp;
+		ev->shared_pointer = shared_pointer_p;
+		if (ev->shared_pointer)
+			shared_pointer_p->ev_p = ev;
+
+		list_add_tail(&ev->list, &ev_int->det_events.list);
+		ev_int->current_events++;
+		mutex_unlock(&ev_int->event_list_lock);
+		wake_up_interruptible(&ev_int->wait);
+	} else
+		mutex_unlock(&ev_int->event_list_lock);
+
+error_ret:
+	return ret;
+}
+EXPORT_SYMBOL(__iio_push_event);
+
+int iio_push_event(struct iio_dev *dev_info,
+		   int ev_line,
+		   int ev_code,
+		   s64 timestamp)
+{
+	return __iio_push_event(&dev_info->event_interfaces[ev_line],
+				ev_code, timestamp, NULL);
+}
+EXPORT_SYMBOL(iio_push_event);
+
+/* Generic interrupt line interrupt handler */
+irqreturn_t iio_interrupt_handler(int irq, void *_int_info)
+{
+	struct iio_interrupt *int_info = _int_info;
+	struct iio_dev *dev_info = int_info->dev_info;
+	struct iio_event_handler_list *p;
+	s64 time_ns;
+	unsigned long flags;
+
+	spin_lock_irqsave(&int_info->ev_list_lock, flags);
+	if (list_empty(&int_info->ev_list)) {
+		spin_unlock_irqrestore(&int_info->ev_list_lock, flags);
+		return IRQ_NONE;
+	}
+
+	time_ns = iio_get_time_ns();
+	/* detect single element list*/
+	if (list_is_singular(&int_info->ev_list)) {
+		disable_irq_nosync(irq);
+		p = list_first_entry(&int_info->ev_list,
+				     struct iio_event_handler_list,
+				     list);
+		/* single event handler - maybe shared */
+		p->handler(dev_info, 1, time_ns, !(p->refcount > 1));
+	} else
+		list_for_each_entry(p, &int_info->ev_list, list) {
+			disable_irq_nosync(irq);
+			p->handler(dev_info, 1, time_ns, 0);
+		}
+	spin_unlock_irqrestore(&int_info->ev_list_lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static struct iio_interrupt *iio_allocate_interrupt(void)
+{
+	struct iio_interrupt *i = kmalloc(sizeof *i, GFP_KERNEL);
+	if (i) {
+		spin_lock_init(&i->ev_list_lock);
+		INIT_LIST_HEAD(&i->ev_list);
+	}
+	return i;
+}
+
+/* Confirming the validity of supplied irq is left to drivers.*/
+int iio_register_interrupt_line(unsigned int irq,
+				struct iio_dev *dev_info,
+				int line_number,
+				unsigned long type,
+				const char *name)
+{
+	int ret;
+
+	dev_info->interrupts[line_number] = iio_allocate_interrupt();
+	if (dev_info->interrupts[line_number] == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	dev_info->interrupts[line_number]->line_number = line_number;
+	dev_info->interrupts[line_number]->irq = irq;
+	dev_info->interrupts[line_number]->dev_info = dev_info;
+
+	/* Possibly only request on demand?
+	 * Can see this may complicate the handling of interrupts.
+	 * However, with this approach we might end up handling lots of
+	 * events no-one cares about.*/
+	ret = request_irq(irq,
+			  &iio_interrupt_handler,
+			  type,
+			  name,
+			  dev_info->interrupts[line_number]);
+
+error_ret:
+	return ret;
+}
+EXPORT_SYMBOL(iio_register_interrupt_line);
+
+/* This turns up an awful lot */
+ssize_t iio_read_const_attr(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	return sprintf(buf, "%s\n", to_iio_const_attr(attr)->string);
+}
+EXPORT_SYMBOL(iio_read_const_attr);
+
+/* Before this runs the interrupt generator must have been disabled */
+void iio_unregister_interrupt_line(struct iio_dev *dev_info, int line_number)
+{
+	/* make sure the interrupt handlers are all done */
+	flush_scheduled_work();
+	free_irq(dev_info->interrupts[line_number]->irq,
+		 dev_info->interrupts[line_number]);
+	kfree(dev_info->interrupts[line_number]);
+}
+EXPORT_SYMBOL(iio_unregister_interrupt_line);
+
+/* Reference counted add and remove */
+void iio_add_event_to_list(struct iio_event_handler_list *el,
+			  struct list_head *head)
+{
+	unsigned long flags;
+	struct iio_interrupt *inter = to_iio_interrupt(head);
+
+	/* take mutex to protect this element */
+	mutex_lock(&el->exist_lock);
+	if (el->refcount == 0) {
+		/* Take the event list spin lock */
+		spin_lock_irqsave(&inter->ev_list_lock, flags);
+		list_add(&el->list, head);
+		spin_unlock_irqrestore(&inter->ev_list_lock, flags);
+	}
+	el->refcount++;
+	mutex_unlock(&el->exist_lock);
+}
+EXPORT_SYMBOL(iio_add_event_to_list);
+
+void iio_remove_event_from_list(struct iio_event_handler_list *el,
+			       struct list_head *head)
+{
+	unsigned long flags;
+	struct iio_interrupt *inter = to_iio_interrupt(head);
+
+	mutex_lock(&el->exist_lock);
+	el->refcount--;
+	if (el->refcount == 0) {
+		/* Take the event list spin lock */
+		spin_lock_irqsave(&inter->ev_list_lock, flags);
+		list_del_init(&el->list);
+		spin_unlock_irqrestore(&inter->ev_list_lock, flags);
+	}
+	mutex_unlock(&el->exist_lock);
+}
+EXPORT_SYMBOL(iio_remove_event_from_list);
+
+ssize_t iio_event_chrdev_read(struct file *filep,
+			      char *buf,
+			      size_t count,
+			      loff_t *f_ps)
+{
+	struct iio_event_interface *ev_int = filep->private_data;
+	struct iio_detected_event_list *el;
+	int ret;
+	size_t len;
+
+	mutex_lock(&ev_int->event_list_lock);
+	if (list_empty(&ev_int->det_events.list)) {
+		if (filep->f_flags & O_NONBLOCK) {
+			ret = -EAGAIN;
+			goto error_mutex_unlock;
+		}
+		mutex_unlock(&ev_int->event_list_lock);
+		/* Blocking on device; waiting for something to be there */
+		ret = wait_event_interruptible(ev_int->wait,
+					       !list_empty(&ev_int
+							   ->det_events.list));
+		if (ret)
+			goto error_ret;
+		/* Single access device so noone else can get the data */
+		mutex_lock(&ev_int->event_list_lock);
+	}
+
+	el = list_first_entry(&ev_int->det_events.list,
+			      struct iio_detected_event_list,
+			      list);
+	len = sizeof el->ev;
+	if (copy_to_user(buf, &(el->ev), len)) {
+		ret = -EFAULT;
+		goto error_mutex_unlock;
+	}
+	list_del(&el->list);
+	ev_int->current_events--;
+	mutex_unlock(&ev_int->event_list_lock);
+	/*
+	 * Possible concurency issue if an update of this event is on its way
+	 * through. May lead to new even being removed whilst the reported event
+	 * was the unescalated event. In typical use case this is not a problem
+	 * as userspace will say read half the buffer due to a 50% full event
+	 * which would make the correct 100% full incorrect anyway.
+	 */
+	spin_lock(&el->shared_pointer->lock);
+	if (el->shared_pointer)
+		(el->shared_pointer->ev_p) = NULL;
+	spin_unlock(&el->shared_pointer->lock);
+
+	kfree(el);
+
+	return len;
+
+error_mutex_unlock:
+	mutex_unlock(&ev_int->event_list_lock);
+error_ret:
+
+	return ret;
+}
+
+int iio_event_chrdev_release(struct inode *inode, struct file *filep)
+{
+	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
+	struct iio_event_interface *ev_int = hand->private;
+	struct iio_detected_event_list *el, *t;
+
+	mutex_lock(&ev_int->event_list_lock);
+	clear_bit(IIO_BUSY_BIT_POS, &ev_int->handler.flags);
+	/*
+	 * In order to maintain a clean state for reopening,
+	 * clear out any awaiting events. The mask will prevent
+	 * any new __iio_push_event calls running.
+	 */
+	list_for_each_entry_safe(el, t, &ev_int->det_events.list, list) {
+		list_del(&el->list);
+		kfree(el);
+	}
+	mutex_unlock(&ev_int->event_list_lock);
+
+	return 0;
+}
+
+int iio_event_chrdev_open(struct inode *inode, struct file *filep)
+{
+	struct iio_handler *hand = iio_cdev_to_handler(inode->i_cdev);
+	struct iio_event_interface *ev_int = hand->private;
+
+	mutex_lock(&ev_int->event_list_lock);
+	if (test_and_set_bit(IIO_BUSY_BIT_POS, &hand->flags)) {
+		fops_put(filep->f_op);
+		mutex_unlock(&ev_int->event_list_lock);
+		return -EBUSY;
+	}
+	filep->private_data = hand->private;
+	mutex_unlock(&ev_int->event_list_lock);
+
+	return 0;
+}
+
+static const struct file_operations iio_event_chrdev_fileops = {
+	.read =  iio_event_chrdev_read,
+	.release = iio_event_chrdev_release,
+	.open = iio_event_chrdev_open,
+	.owner = THIS_MODULE,
+};
+
+static void iio_event_dev_release(struct device *dev)
+{
+	struct iio_event_interface *ev_int
+		= container_of(dev, struct iio_event_interface, dev);
+	cdev_del(&ev_int->handler.chrdev);
+	iio_device_free_chrdev_minor(MINOR(dev->devt));
+};
+
+static struct device_type iio_event_type = {
+	.release = iio_event_dev_release,
+};
+
+int iio_device_get_chrdev_minor(void)
+{
+	int ret, val;
+
+idr_again:
+	if (unlikely(idr_pre_get(&iio_chrdev_idr, GFP_KERNEL) == 0))
+		return -ENOMEM;
+	spin_lock(&iio_idr_lock);
+	ret = idr_get_new(&iio_chrdev_idr, NULL, &val);
+	spin_unlock(&iio_idr_lock);
+	if (unlikely(ret == -EAGAIN))
+		goto idr_again;
+	else if (unlikely(ret))
+		return ret;
+	if (val > IIO_DEV_MAX)
+		return -ENOMEM;
+	return val;
+}
+
+void iio_device_free_chrdev_minor(int val)
+{
+	spin_lock(&iio_idr_lock);
+	idr_remove(&iio_chrdev_idr, val);
+	spin_unlock(&iio_idr_lock);
+}
+
+int iio_setup_ev_int(struct iio_event_interface *ev_int,
+		     const char *name,
+		     struct module *owner,
+		     struct device *dev)
+{
+	int ret, minor;
+
+	ev_int->dev.class = &iio_class;
+	ev_int->dev.parent = dev;
+	ev_int->dev.type = &iio_event_type;
+	device_initialize(&ev_int->dev);
+
+	minor = iio_device_get_chrdev_minor();
+	if (minor < 0) {
+		ret = minor;
+		goto error_device_put;
+	}
+	ev_int->dev.devt = MKDEV(MAJOR(iio_devt), minor);
+	dev_set_name(&ev_int->dev, "%s", name);
+
+	ret = device_add(&ev_int->dev);
+	if (ret)
+		goto error_free_minor;
+
+	cdev_init(&ev_int->handler.chrdev, &iio_event_chrdev_fileops);
+	ev_int->handler.chrdev.owner = owner;
+
+	mutex_init(&ev_int->event_list_lock);
+	/* discussion point - make this variable? */
+	ev_int->max_events = 10;
+	ev_int->current_events = 0;
+	INIT_LIST_HEAD(&ev_int->det_events.list);
+	init_waitqueue_head(&ev_int->wait);
+	ev_int->handler.private = ev_int;
+	ev_int->handler.flags = 0;
+
+	ret = cdev_add(&ev_int->handler.chrdev, ev_int->dev.devt, 1);
+	if (ret)
+		goto error_unreg_device;
+
+	return 0;
+
+error_unreg_device:
+	device_unregister(&ev_int->dev);
+error_free_minor:
+	iio_device_free_chrdev_minor(minor);
+error_device_put:
+	put_device(&ev_int->dev);
+
+	return ret;
+}
+
+void iio_free_ev_int(struct iio_event_interface *ev_int)
+{
+	device_unregister(&ev_int->dev);
+	put_device(&ev_int->dev);
+}
+
+static int __init iio_dev_init(void)
+{
+	int err;
+
+	err = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio");
+	if (err < 0)
+		printk(KERN_ERR "%s: failed to allocate char dev region\n",
+		       __FILE__);
+
+	return err;
+}
+
+static void __exit iio_dev_exit(void)
+{
+	if (iio_devt)
+		unregister_chrdev_region(iio_devt, IIO_DEV_MAX);
+}
+
+static int __init iio_init(void)
+{
+	int ret;
+
+	/* Create sysfs class */
+	ret  = class_register(&iio_class);
+	if (ret < 0) {
+		printk(KERN_ERR
+		       "%s could not create sysfs class\n",
+			__FILE__);
+		goto error_nothing;
+	}
+
+	ret = iio_dev_init();
+	if (ret < 0)
+		goto error_unregister_class;
+
+	return 0;
+
+error_unregister_class:
+	class_unregister(&iio_class);
+error_nothing:
+	return ret;
+}
+
+static void __exit iio_exit(void)
+{
+	iio_dev_exit();
+	class_unregister(&iio_class);
+}
+
+static int iio_device_register_sysfs(struct iio_dev *dev_info)
+{
+	int ret = 0;
+
+	ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->attrs);
+	if (ret) {
+		dev_err(dev_info->dev.parent,
+			"Failed to register sysfs hooks\n");
+		goto error_ret;
+	}
+
+	if (dev_info->scan_el_attrs) {
+		ret = sysfs_create_group(&dev_info->dev.kobj,
+					 dev_info->scan_el_attrs);
+		if (ret)
+			dev_err(&dev_info->dev,
+				"Failed to add sysfs scan els\n");
+	}
+
+error_ret:
+	return ret;
+}
+
+static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
+{
+	if (dev_info->scan_el_attrs)
+		sysfs_remove_group(&dev_info->dev.kobj,
+				   dev_info->scan_el_attrs);
+
+	sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
+}
+
+int iio_get_new_idr_val(struct idr *this_idr)
+{
+	int ret;
+	int val;
+
+idr_again:
+	if (unlikely(idr_pre_get(this_idr, GFP_KERNEL) == 0))
+		return -ENOMEM;
+
+	spin_lock(&iio_idr_lock);
+	ret = idr_get_new(this_idr, NULL, &val);
+	spin_unlock(&iio_idr_lock);
+	if (unlikely(ret == -EAGAIN))
+		goto idr_again;
+	else if (unlikely(ret))
+		return ret;
+
+	return val;
+}
+EXPORT_SYMBOL(iio_get_new_idr_val);
+
+void iio_free_idr_val(struct idr *this_idr, int id)
+{
+	spin_lock(&iio_idr_lock);
+	idr_remove(this_idr, id);
+	spin_unlock(&iio_idr_lock);
+}
+EXPORT_SYMBOL(iio_free_idr_val);
+
+static int iio_device_register_id(struct iio_dev *dev_info,
+				  struct idr *this_idr)
+{
+
+	dev_info->id = iio_get_new_idr_val(&iio_idr);
+	if (dev_info->id < 0)
+		return dev_info->id;
+	return 0;
+}
+
+static void iio_device_unregister_id(struct iio_dev *dev_info)
+{
+	iio_free_idr_val(&iio_idr, dev_info->id);
+}
+
+static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
+{
+	int ret;
+	/*p for adding, q for removing */
+	struct attribute **attrp, **attrq;
+
+	if (dev_info->event_conf_attrs && dev_info->event_conf_attrs[i].attrs) {
+		attrp = dev_info->event_conf_attrs[i].attrs;
+		while (*attrp) {
+			ret =  sysfs_add_file_to_group(&dev_info->dev.kobj,
+						       *attrp,
+						       dev_info
+						       ->event_attrs[i].name);
+			if (ret)
+				goto error_ret;
+			attrp++;
+		}
+	}
+	return 0;
+
+error_ret:
+	attrq = dev_info->event_conf_attrs[i].attrs;
+	while (attrq != attrp) {
+			sysfs_remove_file_from_group(&dev_info->dev.kobj,
+					     *attrq,
+					     dev_info->event_attrs[i].name);
+		attrq++;
+	}
+
+	return ret;
+}
+
+static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info,
+						  int i)
+{
+	struct attribute **attrq;
+
+	if (dev_info->event_conf_attrs
+		&& dev_info->event_conf_attrs[i].attrs) {
+		attrq = dev_info->event_conf_attrs[i].attrs;
+		while (*attrq) {
+			sysfs_remove_file_from_group(&dev_info->dev.kobj,
+						     *attrq,
+						     dev_info
+						     ->event_attrs[i].name);
+			attrq++;
+		}
+	}
+
+	return 0;
+}
+
+static int iio_device_register_eventset(struct iio_dev *dev_info)
+{
+	int ret = 0, i, j;
+
+	if (dev_info->num_interrupt_lines == 0)
+		return 0;
+
+	dev_info->event_interfaces =
+		kzalloc(sizeof(struct iio_event_interface)
+			*dev_info->num_interrupt_lines,
+			GFP_KERNEL);
+	if (dev_info->event_interfaces == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	dev_info->interrupts = kzalloc(sizeof(struct iio_interrupt *)
+				       *dev_info->num_interrupt_lines,
+				       GFP_KERNEL);
+	if (dev_info->interrupts == NULL) {
+		ret = -ENOMEM;
+		goto error_free_event_interfaces;
+	}
+
+	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+		dev_info->event_interfaces[i].owner = dev_info->driver_module;
+		ret = iio_get_new_idr_val(&iio_event_idr);
+		if (ret)
+			goto error_free_setup_ev_ints;
+		else
+			dev_info->event_interfaces[i].id = ret;
+
+		snprintf(dev_info->event_interfaces[i]._name, 20,
+			 "event_line%d",
+			dev_info->event_interfaces[i].id);
+
+		ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
+				       (const char *)(dev_info
+						      ->event_interfaces[i]
+						      ._name),
+				       dev_info->driver_module,
+				       &dev_info->dev);
+		if (ret) {
+			dev_err(&dev_info->dev,
+				"Could not get chrdev interface\n");
+			iio_free_idr_val(&iio_event_idr,
+					 dev_info->event_interfaces[i].id);
+			goto error_free_setup_ev_ints;
+		}
+	}
+
+	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+		snprintf(dev_info->event_interfaces[i]._attrname, 20,
+			"event_line%d_sources", i);
+		dev_info->event_attrs[i].name
+			= (const char *)
+			(dev_info->event_interfaces[i]._attrname);
+		ret = sysfs_create_group(&dev_info->dev.kobj,
+					 &dev_info->event_attrs[i]);
+		if (ret) {
+			dev_err(&dev_info->dev,
+				"Failed to register sysfs for event attrs");
+			goto error_remove_sysfs_interfaces;
+		}
+	}
+
+	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+		ret = __iio_add_event_config_attrs(dev_info, i);
+		if (ret)
+			goto error_unregister_config_attrs;
+	}
+
+	return 0;
+
+error_unregister_config_attrs:
+	for (j = 0; j < i; j++)
+		__iio_remove_event_config_attrs(dev_info, i);
+	i = dev_info->num_interrupt_lines - 1;
+error_remove_sysfs_interfaces:
+	for (j = 0; j < i; j++)
+		sysfs_remove_group(&dev_info->dev.kobj,
+				   &dev_info->event_attrs[j]);
+	i = dev_info->num_interrupt_lines - 1;
+error_free_setup_ev_ints:
+	for (j = 0; j < i; j++) {
+		iio_free_idr_val(&iio_event_idr,
+				 dev_info->event_interfaces[i].id);
+		iio_free_ev_int(&dev_info->event_interfaces[j]);
+	}
+	kfree(dev_info->interrupts);
+error_free_event_interfaces:
+	kfree(dev_info->event_interfaces);
+error_ret:
+
+	return ret;
+}
+
+static void iio_device_unregister_eventset(struct iio_dev *dev_info)
+{
+	int i;
+
+	if (dev_info->num_interrupt_lines == 0)
+		return;
+	for (i = 0; i < dev_info->num_interrupt_lines; i++)
+		sysfs_remove_group(&dev_info->dev.kobj,
+				   &dev_info->event_attrs[i]);
+
+	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+		iio_free_idr_val(&iio_event_idr,
+				 dev_info->event_interfaces[i].id);
+		iio_free_ev_int(&dev_info->event_interfaces[i]);
+	}
+	kfree(dev_info->interrupts);
+	kfree(dev_info->event_interfaces);
+}
+
+static void iio_dev_release(struct device *device)
+{
+	struct iio_dev *dev = to_iio_dev(device);
+
+	iio_put();
+	kfree(dev);
+}
+
+static struct device_type iio_dev_type = {
+	.name = "iio_device",
+	.release = iio_dev_release,
+};
+
+struct iio_dev *iio_allocate_device(void)
+{
+	struct iio_dev *dev = kzalloc(sizeof *dev, GFP_KERNEL);
+
+	if (dev) {
+		dev->dev.type = &iio_dev_type;
+		dev->dev.class = &iio_class;
+		device_initialize(&dev->dev);
+		dev_set_drvdata(&dev->dev, (void *)dev);
+		mutex_init(&dev->mlock);
+		iio_get();
+	}
+
+	return dev;
+}
+EXPORT_SYMBOL(iio_allocate_device);
+
+void iio_free_device(struct iio_dev *dev)
+{
+	if (dev)
+		iio_put_device(dev);
+}
+EXPORT_SYMBOL(iio_free_device);
+
+int iio_device_register(struct iio_dev *dev_info)
+{
+	int ret;
+
+	ret = iio_device_register_id(dev_info, &iio_idr);
+	if (ret) {
+		dev_err(&dev_info->dev, "Failed to get id\n");
+		goto error_ret;
+	}
+	dev_set_name(&dev_info->dev, "device%d", dev_info->id);
+
+	ret = device_add(&dev_info->dev);
+	if (ret)
+		goto error_free_idr;
+	ret = iio_device_register_sysfs(dev_info);
+	if (ret) {
+		dev_err(dev_info->dev.parent,
+			"Failed to register sysfs interfaces\n");
+		goto error_del_device;
+	}
+	ret = iio_device_register_eventset(dev_info);
+	if (ret) {
+		dev_err(dev_info->dev.parent,
+			"Failed to register event set \n");
+		goto error_free_sysfs;
+	}
+	if (dev_info->modes & INDIO_RING_TRIGGERED)
+		iio_device_register_trigger_consumer(dev_info);
+
+	return 0;
+
+error_free_sysfs:
+	iio_device_unregister_sysfs(dev_info);
+error_del_device:
+	device_del(&dev_info->dev);
+error_free_idr:
+	iio_device_unregister_id(dev_info);
+error_ret:
+	return ret;
+}
+EXPORT_SYMBOL(iio_device_register);
+
+void iio_device_unregister(struct iio_dev *dev_info)
+{
+	if (dev_info->modes & INDIO_RING_TRIGGERED)
+		iio_device_unregister_trigger_consumer(dev_info);
+	iio_device_unregister_eventset(dev_info);
+	iio_device_unregister_sysfs(dev_info);
+	iio_device_unregister_id(dev_info);
+	device_unregister(&dev_info->dev);
+}
+EXPORT_SYMBOL(iio_device_unregister);
+
+void iio_put(void)
+{
+	module_put(THIS_MODULE);
+}
+
+void iio_get(void)
+{
+	__module_get(THIS_MODULE);
+}
+
+subsys_initcall(iio_init);
+module_exit(iio_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("Industrial I/O core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c
new file mode 100644
index 0000000..ebe5ccc
--- /dev/null
+++ b/drivers/staging/iio/industrialio-ring.c
@@ -0,0 +1,568 @@
+/* The industrial I/O core
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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.
+ *
+ * Handling of ring allocation / resizing.
+ *
+ *
+ * Things to look at here.
+ * - Better memory allocation techniques?
+ * - Alternative access techniques?
+ */
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/module.h>
+#include <linux/cdev.h>
+#include <linux/idr.h>
+
+#include "iio.h"
+#include "ring_generic.h"
+
+/* IDR for ring buffer identifier */
+static DEFINE_IDR(iio_ring_idr);
+/* IDR for ring event identifier */
+static DEFINE_IDR(iio_ring_event_idr);
+/* IDR for ring access identifier */
+static DEFINE_IDR(iio_ring_access_idr);
+
+int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
+		       int event_code,
+		       s64 timestamp)
+{
+	return __iio_push_event(&ring_buf->ev_int,
+			       event_code,
+			       timestamp,
+			       &ring_buf->shared_ev_pointer);
+}
+EXPORT_SYMBOL(iio_push_ring_event);
+
+int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
+				    int event_code,
+				    s64 timestamp)
+{
+	if (ring_buf->shared_ev_pointer.ev_p)
+		__iio_change_event(ring_buf->shared_ev_pointer.ev_p,
+				   event_code,
+				   timestamp);
+	else
+		return iio_push_ring_event(ring_buf,
+					  event_code,
+					  timestamp);
+	return 0;
+}
+EXPORT_SYMBOL(iio_push_or_escallate_ring_event);
+
+/**
+ * iio_ring_open() chrdev file open for ring buffer access
+ *
+ * This function relies on all ring buffer implementations having an
+ * iio_ring_buffer as their first element.
+ **/
+int iio_ring_open(struct inode *inode, struct file *filp)
+{
+	struct iio_handler *hand
+		= container_of(inode->i_cdev, struct iio_handler, chrdev);
+	struct iio_ring_buffer *rb = hand->private;
+
+	filp->private_data = hand->private;
+	if (rb->access.mark_in_use)
+		rb->access.mark_in_use(rb);
+
+	return 0;
+}
+
+/**
+ * iio_ring_release() -chrdev file close ring buffer access
+ *
+ * This function relies on all ring buffer implementations having an
+ * iio_ring_buffer as their first element.
+ **/
+int iio_ring_release(struct inode *inode, struct file *filp)
+{
+	struct cdev *cd = inode->i_cdev;
+	struct iio_handler *hand = iio_cdev_to_handler(cd);
+	struct iio_ring_buffer *rb = hand->private;
+
+	clear_bit(IIO_BUSY_BIT_POS, &rb->access_handler.flags);
+	if (rb->access.unmark_in_use)
+		rb->access.unmark_in_use(rb);
+
+	return 0;
+}
+
+/**
+ * iio_ring_rip_outer() chrdev read for ring buffer access
+ *
+ * This function relies on all ring buffer implementations having an
+ * iio_ring _bufer as their first element.
+ **/
+ssize_t iio_ring_rip_outer(struct file *filp,
+			   char *buf,
+			   size_t count,
+			   loff_t *f_ps)
+{
+	struct iio_ring_buffer *rb = filp->private_data;
+	int ret, dead_offset, copied;
+	u8 *data;
+	/* rip lots must exist. */
+	if (!rb->access.rip_lots)
+		return -EINVAL;
+	copied = rb->access.rip_lots(rb, count, &data, &dead_offset);
+
+	if (copied < 0) {
+		ret = copied;
+		goto error_ret;
+	}
+	if (copy_to_user(buf, data + dead_offset, copied))  {
+		ret =  -EFAULT;
+		goto error_free_data_cpy;
+	}
+	/* In clever ring buffer designs this may not need to be freed.
+	 * When such a design exists I'll add this to ring access funcs.
+	 */
+	kfree(data);
+
+	return copied;
+
+error_free_data_cpy:
+	kfree(data);
+error_ret:
+	return ret;
+}
+
+static const struct file_operations iio_ring_fileops = {
+	.read = iio_ring_rip_outer,
+	.release = iio_ring_release,
+	.open = iio_ring_open,
+	.owner = THIS_MODULE,
+};
+
+/**
+ * __iio_request_ring_buffer_event_chrdev() allocate ring event chrdev
+ * @buf:	ring buffer whose event chrdev we are allocating
+ * @owner:	the module who owns the ring buffer (for ref counting)
+ * @dev:	device with which the chrdev is associated
+ **/
+static inline int
+__iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf,
+				       int id,
+				       struct module *owner,
+				       struct device *dev)
+{
+	int ret;
+	ret = iio_get_new_idr_val(&iio_ring_event_idr);
+	if (ret < 0)
+		goto error_ret;
+	else
+		buf->ev_int.id = ret;
+
+	snprintf(buf->ev_int._name, 20,
+		 "ring_event_line%d",
+		 buf->ev_int.id);
+	ret = iio_setup_ev_int(&(buf->ev_int),
+			       buf->ev_int._name,
+			       owner,
+			       dev);
+	if (ret)
+		goto error_free_id;
+	return 0;
+
+error_free_id:
+	iio_free_idr_val(&iio_ring_event_idr, buf->ev_int.id);
+error_ret:
+	return ret;
+}
+
+static inline void
+__iio_free_ring_buffer_event_chrdev(struct iio_ring_buffer *buf)
+{
+	iio_free_ev_int(&(buf->ev_int));
+	iio_free_idr_val(&iio_ring_event_idr, buf->ev_int.id);
+}
+
+static void iio_ring_access_release(struct device *dev)
+{
+	struct iio_ring_buffer *buf
+		= access_dev_to_iio_ring_buffer(dev);
+	cdev_del(&buf->access_handler.chrdev);
+	iio_device_free_chrdev_minor(MINOR(dev->devt));
+}
+
+static struct device_type iio_ring_access_type = {
+	.release = iio_ring_access_release,
+};
+
+static inline int
+__iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf,
+					int id,
+					struct module *owner)
+{
+	int ret, minor;
+
+	buf->access_handler.flags = 0;
+
+	buf->access_dev.parent = &buf->dev;
+	buf->access_dev.class = &iio_class;
+	buf->access_dev.type = &iio_ring_access_type;
+	device_initialize(&buf->access_dev);
+
+	minor = iio_device_get_chrdev_minor();
+	if (minor < 0) {
+		ret = minor;
+		goto error_device_put;
+	}
+	buf->access_dev.devt = MKDEV(MAJOR(iio_devt), minor);
+
+	ret = iio_get_new_idr_val(&iio_ring_access_idr);
+	if (ret < 0)
+		goto error_device_put;
+	else
+		buf->access_id = ret;
+	dev_set_name(&buf->access_dev, "ring_access%d", buf->access_id);
+	ret = device_add(&buf->access_dev);
+	if (ret < 0) {
+		printk(KERN_ERR "failed to add the ring access dev\n");
+		goto error_free_idr;
+	}
+
+	cdev_init(&buf->access_handler.chrdev, &iio_ring_fileops);
+	buf->access_handler.chrdev.owner = owner;
+
+	ret = cdev_add(&buf->access_handler.chrdev, buf->access_dev.devt, 1);
+	if (ret) {
+		printk(KERN_ERR "failed to allocate ring access chrdev\n");
+		goto error_device_unregister;
+	}
+	return 0;
+error_device_unregister:
+	device_unregister(&buf->access_dev);
+error_free_idr:
+	iio_free_idr_val(&iio_ring_access_idr, buf->access_id);
+error_device_put:
+	put_device(&buf->access_dev);
+
+	return ret;
+}
+
+static void __iio_free_ring_buffer_access_chrdev(struct iio_ring_buffer *buf)
+{
+	iio_free_idr_val(&iio_ring_access_idr, buf->access_id);
+	device_unregister(&buf->access_dev);
+}
+
+void iio_ring_buffer_init(struct iio_ring_buffer *ring,
+			  struct iio_dev *dev_info)
+{
+	if (ring->access.mark_param_change)
+		ring->access.mark_param_change(ring);
+	ring->indio_dev = dev_info;
+	ring->ev_int.private = ring;
+	ring->access_handler.private = ring;
+}
+EXPORT_SYMBOL(iio_ring_buffer_init);
+
+int iio_ring_buffer_register(struct iio_ring_buffer *ring)
+{
+	int ret;
+	ret = iio_get_new_idr_val(&iio_ring_idr);
+	if (ret < 0)
+		goto error_ret;
+	else
+		ring->id = ret;
+
+	dev_set_name(&ring->dev, "ring_buffer%d", ring->id);
+	ret = device_add(&ring->dev);
+	if (ret)
+		goto error_free_id;
+
+	ret = __iio_request_ring_buffer_event_chrdev(ring,
+						     0,
+						     ring->owner,
+						     &ring->dev);
+	if (ret)
+		goto error_remove_device;
+
+	ret = __iio_request_ring_buffer_access_chrdev(ring,
+						      0,
+						      ring->owner);
+
+	if (ret)
+		goto error_free_ring_buffer_event_chrdev;
+
+	return ret;
+error_free_ring_buffer_event_chrdev:
+	__iio_free_ring_buffer_event_chrdev(ring);
+error_remove_device:
+	device_del(&ring->dev);
+error_free_id:
+	iio_free_idr_val(&iio_ring_idr, ring->id);
+error_ret:
+	return ret;
+}
+EXPORT_SYMBOL(iio_ring_buffer_register);
+
+void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
+{
+	__iio_free_ring_buffer_access_chrdev(ring);
+	__iio_free_ring_buffer_event_chrdev(ring);
+	device_del(&ring->dev);
+	iio_free_idr_val(&iio_ring_idr, ring->id);
+}
+EXPORT_SYMBOL(iio_ring_buffer_unregister);
+
+ssize_t iio_read_ring_length(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	int len = 0;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+
+	if (ring->access.get_length)
+		len = sprintf(buf, "%d\n",
+			      ring->access.get_length(ring));
+
+	return len;
+}
+EXPORT_SYMBOL(iio_read_ring_length);
+
+ ssize_t iio_write_ring_length(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf,
+			       size_t len)
+{
+	int ret;
+	ulong val;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	if (ring->access.get_length)
+		if (val == ring->access.get_length(ring))
+			return len;
+
+	if (ring->access.set_length) {
+		ring->access.set_length(ring, val);
+		if (ring->access.mark_param_change)
+			ring->access.mark_param_change(ring);
+	}
+
+	return len;
+}
+EXPORT_SYMBOL(iio_write_ring_length);
+
+ssize_t iio_read_ring_bps(struct device *dev,
+			  struct device_attribute *attr,
+			  char *buf)
+{
+	int len = 0;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+
+	if (ring->access.get_bpd)
+		len = sprintf(buf, "%d\n",
+			      ring->access.get_bpd(ring));
+
+	return len;
+}
+EXPORT_SYMBOL(iio_read_ring_bps);
+
+ssize_t iio_store_ring_enable(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t len)
+{
+	int ret;
+	bool requested_state, current_state;
+	int previous_mode;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *dev_info = ring->indio_dev;
+
+	mutex_lock(&dev_info->mlock);
+	previous_mode = dev_info->currentmode;
+	requested_state = !(buf[0] == '0');
+	current_state = !!(previous_mode & INDIO_ALL_RING_MODES);
+	if (current_state == requested_state) {
+		printk(KERN_INFO "iio-ring, current state requested again\n");
+		goto done;
+	}
+	if (requested_state) {
+		if (ring->preenable) {
+			ret = ring->preenable(dev_info);
+			if (ret) {
+				printk(KERN_ERR
+				       "Buffer not started:"
+				       "ring preenable failed\n");
+				goto error_ret;
+			}
+		}
+		if (ring->access.request_update) {
+			ret = ring->access.request_update(ring);
+			if (ret) {
+				printk(KERN_INFO
+				       "Buffer not started:"
+				       "ring parameter update failed\n");
+				goto error_ret;
+			}
+		}
+		if (ring->access.mark_in_use)
+			ring->access.mark_in_use(ring);
+		/* Definitely possible for devices to support both of these.*/
+		if (dev_info->modes & INDIO_RING_TRIGGERED) {
+			if (!dev_info->trig) {
+				printk(KERN_INFO
+				       "Buffer not started: no trigger\n");
+				ret = -EINVAL;
+				if (ring->access.unmark_in_use)
+					ring->access.unmark_in_use(ring);
+				goto error_ret;
+			}
+			dev_info->currentmode = INDIO_RING_TRIGGERED;
+		} else if (dev_info->modes & INDIO_RING_HARDWARE_BUFFER)
+			dev_info->currentmode = INDIO_RING_HARDWARE_BUFFER;
+		else { /* should never be reached */
+			ret = -EINVAL;
+			goto error_ret;
+		}
+
+		if (ring->postenable) {
+
+			ret = ring->postenable(dev_info);
+			if (ret) {
+				printk(KERN_INFO
+				       "Buffer not started:"
+				       "postenable failed\n");
+				if (ring->access.unmark_in_use)
+					ring->access.unmark_in_use(ring);
+				dev_info->currentmode = previous_mode;
+				if (ring->postdisable)
+					ring->postdisable(dev_info);
+				goto error_ret;
+			}
+		}
+	} else {
+		if (ring->predisable) {
+			ret = ring->predisable(dev_info);
+			if (ret)
+				goto error_ret;
+		}
+		if (ring->access.unmark_in_use)
+			ring->access.unmark_in_use(ring);
+		dev_info->currentmode = INDIO_DIRECT_MODE;
+		if (ring->postdisable) {
+			ret = ring->postdisable(dev_info);
+			if (ret)
+				goto error_ret;
+		}
+	}
+done:
+	mutex_unlock(&dev_info->mlock);
+	return len;
+
+error_ret:
+	mutex_unlock(&dev_info->mlock);
+	return ret;
+}
+EXPORT_SYMBOL(iio_store_ring_enable);
+ssize_t iio_show_ring_enable(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", !!(ring->indio_dev->currentmode
+				       & INDIO_ALL_RING_MODES));
+}
+EXPORT_SYMBOL(iio_show_ring_enable);
+
+ssize_t iio_scan_el_show(struct device *dev,
+			 struct device_attribute *attr,
+			 char *buf)
+{
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_scan_el *this_el = to_iio_scan_el(attr);
+
+	ret = iio_scan_mask_query(indio_dev, this_el->number);
+	if (ret < 0)
+		return ret;
+	return sprintf(buf, "%d\n", ret);
+}
+EXPORT_SYMBOL(iio_scan_el_show);
+
+ssize_t iio_scan_el_store(struct device *dev,
+			  struct device_attribute *attr,
+			  const char *buf,
+			  size_t len)
+{
+	int ret = 0;
+	bool state;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_scan_el *this_el = to_iio_scan_el(attr);
+
+	state = !(buf[0] == '0');
+	mutex_lock(&indio_dev->mlock);
+	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
+		ret = -EBUSY;
+		goto error_ret;
+	}
+	ret = iio_scan_mask_query(indio_dev, this_el->number);
+	if (ret < 0)
+		goto error_ret;
+	if (!state && ret) {
+		ret = iio_scan_mask_clear(indio_dev, this_el->number);
+		if (ret)
+			goto error_ret;
+		indio_dev->scan_count--;
+	} else if (state && !ret) {
+		ret = iio_scan_mask_set(indio_dev, this_el->number);
+		if (ret)
+			goto error_ret;
+		indio_dev->scan_count++;
+	}
+	if (this_el->set_state)
+		ret = this_el->set_state(this_el, indio_dev, state);
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+
+}
+EXPORT_SYMBOL(iio_scan_el_store);
+
+ssize_t iio_scan_el_ts_show(struct device *dev,
+			    struct device_attribute *attr,
+			    char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", indio_dev->scan_timestamp);
+}
+EXPORT_SYMBOL(iio_scan_el_ts_show);
+
+ssize_t iio_scan_el_ts_store(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf,
+			     size_t len)
+{
+	int ret = 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	bool state;
+	state = !(buf[0] == '0');
+	mutex_lock(&indio_dev->mlock);
+	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
+		ret = -EBUSY;
+		goto error_ret;
+	}
+	indio_dev->scan_timestamp = state;
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+EXPORT_SYMBOL(iio_scan_el_ts_store);
+
diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c
new file mode 100644
index 0000000..693ebc4
--- /dev/null
+++ b/drivers/staging/iio/industrialio-trigger.c
@@ -0,0 +1,399 @@
+/* The industrial I/O core, trigger handling functions
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/idr.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+
+#include "iio.h"
+#include "trigger.h"
+
+/* RFC - Question of approach
+ * Make the common case (single sensor single trigger)
+ * simple by starting trigger capture from when first sensors
+ * is added.
+ *
+ * Complex simultaneous start requires use of 'hold' functionality
+ * of the trigger. (not implemented)
+ *
+ * Any other suggestions?
+ */
+
+
+static DEFINE_IDR(iio_trigger_idr);
+static DEFINE_SPINLOCK(iio_trigger_idr_lock);
+
+/* Single list of all available triggers */
+static LIST_HEAD(iio_trigger_list);
+static DEFINE_MUTEX(iio_trigger_list_lock);
+
+/**
+ * iio_trigger_register_sysfs() - create a device for this trigger
+ * @trig_info:	the trigger
+ *
+ * Also adds any control attribute registered by the trigger driver
+ **/
+static int iio_trigger_register_sysfs(struct iio_trigger *trig_info)
+{
+	int ret = 0;
+
+	if (trig_info->control_attrs)
+		ret = sysfs_create_group(&trig_info->dev.kobj,
+					 trig_info->control_attrs);
+
+	return ret;
+}
+
+static void iio_trigger_unregister_sysfs(struct iio_trigger *trig_info)
+{
+	if (trig_info->control_attrs)
+		sysfs_remove_group(&trig_info->dev.kobj,
+				   trig_info->control_attrs);
+}
+
+
+/**
+ * iio_trigger_register_id() - get a unique id for this trigger
+ * @trig_info:	the trigger
+ **/
+static int iio_trigger_register_id(struct iio_trigger *trig_info)
+{
+	int ret = 0;
+
+idr_again:
+	if (unlikely(idr_pre_get(&iio_trigger_idr, GFP_KERNEL) == 0))
+		return -ENOMEM;
+
+	spin_lock(&iio_trigger_idr_lock);
+	ret = idr_get_new(&iio_trigger_idr, NULL, &trig_info->id);
+	spin_unlock(&iio_trigger_idr_lock);
+	if (unlikely(ret == -EAGAIN))
+		goto idr_again;
+	else if (likely(!ret))
+		trig_info->id = trig_info->id & MAX_ID_MASK;
+
+	return ret;
+}
+
+/**
+ * iio_trigger_unregister_id() - free up unique id for use by another trigger
+ * @trig_info: the trigger
+ **/
+static void iio_trigger_unregister_id(struct iio_trigger *trig_info)
+{
+		spin_lock(&iio_trigger_idr_lock);
+		idr_remove(&iio_trigger_idr, trig_info->id);
+		spin_unlock(&iio_trigger_idr_lock);
+}
+
+int iio_trigger_register(struct iio_trigger *trig_info)
+{
+	int ret;
+
+	ret = iio_trigger_register_id(trig_info);
+	if (ret)
+		goto error_ret;
+	/* Set the name used for the sysfs directory etc */
+	dev_set_name(&trig_info->dev, "trigger%ld",
+		     (unsigned long) trig_info->id);
+
+	ret = device_add(&trig_info->dev);
+	if (ret)
+		goto error_unregister_id;
+
+	ret = iio_trigger_register_sysfs(trig_info);
+	if (ret)
+		goto error_device_del;
+
+	/* Add to list of available triggers held by the IIO core */
+	mutex_lock(&iio_trigger_list_lock);
+	list_add_tail(&trig_info->list, &iio_trigger_list);
+	mutex_unlock(&iio_trigger_list_lock);
+
+	return 0;
+
+error_device_del:
+	device_del(&trig_info->dev);
+error_unregister_id:
+	iio_trigger_unregister_id(trig_info);
+error_ret:
+	return ret;
+}
+EXPORT_SYMBOL(iio_trigger_register);
+
+void iio_trigger_unregister(struct iio_trigger *trig_info)
+{
+	struct iio_trigger *cursor;
+
+	mutex_lock(&iio_trigger_list_lock);
+	list_for_each_entry(cursor, &iio_trigger_list, list)
+		if (cursor == trig_info) {
+			list_del(&cursor->list);
+			break;
+		}
+	mutex_unlock(&iio_trigger_list_lock);
+
+	iio_trigger_unregister_sysfs(trig_info);
+	iio_trigger_unregister_id(trig_info);
+	/* Possible issue in here */
+	device_unregister(&trig_info->dev);
+}
+EXPORT_SYMBOL(iio_trigger_unregister);
+
+struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len)
+{
+	struct iio_trigger *trig;
+	bool found = false;
+
+	mutex_lock(&iio_trigger_list_lock);
+	list_for_each_entry(trig, &iio_trigger_list, list) {
+		if (strncmp(trig->name, name, len) == 0) {
+			found = true;
+			break;
+		}
+	}
+	mutex_unlock(&iio_trigger_list_lock);
+
+	return found ? trig : NULL;
+};
+EXPORT_SYMBOL(iio_trigger_find_by_name);
+
+void iio_trigger_poll(struct iio_trigger *trig)
+{
+	struct iio_poll_func *pf_cursor;
+
+	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
+		if (pf_cursor->poll_func_immediate) {
+			pf_cursor->poll_func_immediate(pf_cursor->private_data);
+			trig->use_count++;
+		}
+	}
+	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
+		if (pf_cursor->poll_func_main) {
+			pf_cursor->poll_func_main(pf_cursor->private_data);
+			trig->use_count++;
+		}
+	}
+}
+EXPORT_SYMBOL(iio_trigger_poll);
+
+void iio_trigger_notify_done(struct iio_trigger *trig)
+{
+	trig->use_count--;
+	if (trig->use_count == 0 && trig->try_reenable)
+		if (trig->try_reenable(trig)) {
+			/* Missed and interrupt so launch new poll now */
+			trig->timestamp = 0;
+			iio_trigger_poll(trig);
+		}
+}
+EXPORT_SYMBOL(iio_trigger_notify_done);
+
+/**
+ * iio_trigger_read_name() - retrieve useful identifying name
+ **/
+ssize_t iio_trigger_read_name(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	struct iio_trigger *trig = dev_get_drvdata(dev);
+	return sprintf(buf, "%s\n", trig->name);
+}
+EXPORT_SYMBOL(iio_trigger_read_name);
+
+/* Trigger Consumer related functions */
+
+/* Complexity in here.  With certain triggers (datardy) an acknowledgement
+ * may be needed if the pollfuncs do not include the data read for the
+ * triggering device.
+ * This is not currently handled.  Alternative of not enabling trigger unless
+ * the relevant function is in there may be the best option.
+ */
+/* Worth protecting against double additions?*/
+int iio_trigger_attach_poll_func(struct iio_trigger *trig,
+				 struct iio_poll_func *pf)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
+	list_add_tail(&pf->list, &trig->pollfunc_list);
+	spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
+
+	if (trig->set_trigger_state)
+		ret = trig->set_trigger_state(trig, true);
+	if (ret) {
+		printk(KERN_ERR "set trigger state failed\n");
+		list_del(&pf->list);
+	}
+	return ret;
+}
+EXPORT_SYMBOL(iio_trigger_attach_poll_func);
+
+int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
+				  struct iio_poll_func *pf)
+{
+	struct iio_poll_func *pf_cursor;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
+	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list)
+		if (pf_cursor == pf) {
+			ret = 0;
+			break;
+		}
+	if (!ret) {
+		if (list_is_singular(&trig->pollfunc_list)
+		    && trig->set_trigger_state) {
+			spin_unlock_irqrestore(&trig->pollfunc_list_lock,
+					       flags);
+			/* May sleep hence cannot hold the spin lock */
+			ret = trig->set_trigger_state(trig, false);
+			if (ret)
+				goto error_ret;
+			spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
+		}
+		/*
+		 * Now we can delete safe in the knowledge that, if this is
+		 * the last pollfunc then we have disabled the trigger anyway
+		 * and so nothing should be able to call the pollfunc.
+		 */
+		list_del(&pf_cursor->list);
+	}
+	spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
+
+error_ret:
+	return ret;
+}
+EXPORT_SYMBOL(iio_trigger_dettach_poll_func);
+
+/**
+ * iio_trigger_read_currrent() trigger consumer sysfs query which trigger
+ *
+ * For trigger consumers the current_trigger interface allows the trigger
+ * used by the device to be queried.
+ **/
+static ssize_t iio_trigger_read_current(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	int len = 0;
+	if (dev_info->trig)
+		len = snprintf(buf,
+			       IIO_TRIGGER_NAME_LENGTH,
+			       "%s\n",
+			       dev_info->trig->name);
+	return len;
+}
+
+/**
+ * iio_trigger_write_current() trigger consumer sysfs set current trigger
+ *
+ * For trigger consumers the current_trigger interface allows the trigger
+ * used for this device to be specified at run time based on the triggers
+ * name.
+ **/
+static ssize_t iio_trigger_write_current(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf,
+					 size_t len)
+{
+	struct iio_dev *dev_info = dev_get_drvdata(dev);
+	struct iio_trigger *oldtrig = dev_info->trig;
+	mutex_lock(&dev_info->mlock);
+	if (dev_info->currentmode == INDIO_RING_TRIGGERED) {
+		mutex_unlock(&dev_info->mlock);
+		return -EBUSY;
+	}
+	mutex_unlock(&dev_info->mlock);
+
+	len = len < IIO_TRIGGER_NAME_LENGTH ? len : IIO_TRIGGER_NAME_LENGTH;
+
+	dev_info->trig = iio_trigger_find_by_name(buf, len);
+	if (oldtrig && dev_info->trig != oldtrig)
+		iio_put_trigger(oldtrig);
+	if (dev_info->trig)
+		iio_get_trigger(dev_info->trig);
+
+	return len;
+}
+
+DEVICE_ATTR(current_trigger, S_IRUGO | S_IWUSR,
+	    iio_trigger_read_current,
+	    iio_trigger_write_current);
+
+static struct attribute *iio_trigger_consumer_attrs[] = {
+	&dev_attr_current_trigger.attr,
+	NULL,
+};
+
+static const struct attribute_group iio_trigger_consumer_attr_group = {
+	.name = "trigger",
+	.attrs = iio_trigger_consumer_attrs,
+};
+
+static void iio_trig_release(struct device *device)
+{
+	struct iio_trigger *trig = to_iio_trigger(device);
+	kfree(trig);
+	iio_put();
+}
+
+static struct device_type iio_trig_type = {
+	.release = iio_trig_release,
+};
+
+struct iio_trigger *iio_allocate_trigger(void)
+{
+	struct iio_trigger *trig;
+	trig = kzalloc(sizeof *trig, GFP_KERNEL);
+	if (trig) {
+		trig->dev.type = &iio_trig_type;
+		trig->dev.class = &iio_class;
+		device_initialize(&trig->dev);
+		dev_set_drvdata(&trig->dev, (void *)trig);
+		spin_lock_init(&trig->pollfunc_list_lock);
+		INIT_LIST_HEAD(&trig->list);
+		INIT_LIST_HEAD(&trig->pollfunc_list);
+		iio_get();
+	}
+	return trig;
+}
+EXPORT_SYMBOL(iio_allocate_trigger);
+
+void iio_free_trigger(struct iio_trigger *trig)
+{
+	if (trig)
+		put_device(&trig->dev);
+}
+EXPORT_SYMBOL(iio_free_trigger);
+
+int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
+{
+	int ret;
+	ret = sysfs_create_group(&dev_info->dev.kobj,
+				 &iio_trigger_consumer_attr_group);
+	return ret;
+}
+EXPORT_SYMBOL(iio_device_register_trigger_consumer);
+
+int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
+{
+	sysfs_remove_group(&dev_info->dev.kobj,
+			   &iio_trigger_consumer_attr_group);
+	return 0;
+}
+EXPORT_SYMBOL(iio_device_unregister_trigger_consumer);
+
diff --git a/drivers/staging/iio/light/Kconfig b/drivers/staging/iio/light/Kconfig
new file mode 100644
index 0000000..12af0c4
--- /dev/null
+++ b/drivers/staging/iio/light/Kconfig
@@ -0,0 +1,13 @@
+#
+# Light sensors
+#
+comment "Light sensors"
+
+config TSL2561
+       tristate "TAOS TSL2561 light-to-digital convertor"
+       depends on I2C
+       help
+	Say yes bere to build support for the TAOS light to digital
+	convertor.  This chip has two light sensors. One is broadband
+	including infrared whilst the other measures only infrared.
+	Provides direct access via sysfs.
diff --git a/drivers/staging/iio/light/Makefile b/drivers/staging/iio/light/Makefile
new file mode 100644
index 0000000..ccff151
--- /dev/null
+++ b/drivers/staging/iio/light/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for industrial I/O Light sensors
+#
+
+obj-$(CONFIG_TSL2561)   += tsl2561.o
diff --git a/drivers/staging/iio/light/light.h b/drivers/staging/iio/light/light.h
new file mode 100644
index 0000000..f00f827
--- /dev/null
+++ b/drivers/staging/iio/light/light.h
@@ -0,0 +1,12 @@
+#include "../sysfs.h"
+
+/* Light to digital sensor attributes */
+
+#define IIO_DEV_ATTR_LIGHT_INFRARED(_num, _show, _addr)			\
+	IIO_DEVICE_ATTR(light_infrared##_num, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_LIGHT_BROAD(_num, _show, _addr)			\
+	IIO_DEVICE_ATTR(light_broadspectrum##_num, S_IRUGO, _show, NULL, _addr)
+
+#define IIO_DEV_ATTR_LIGHT_VISIBLE(_num, _show, _addr)			\
+	IIO_DEVICE_ATTR(light_visible##_num, S_IRUGO, _show, NULL, _addr)
diff --git a/drivers/staging/iio/light/tsl2561.c b/drivers/staging/iio/light/tsl2561.c
new file mode 100644
index 0000000..ea8a5ef
--- /dev/null
+++ b/drivers/staging/iio/light/tsl2561.c
@@ -0,0 +1,276 @@
+/*
+ *  tsl2561.c - Linux kernel modules for light to digital convertor
+ *
+ *  Copyright (C) 2008-2009 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU 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.
+ *
+ *  Some portions based upon the tsl2550 driver.
+ *
+ *  This driver could probably be adapted easily to talk to the tsl2560 (smbus)
+ *
+ *  Needs some work to support the events this can generate.
+ *  Todo: Implement interrupt handling.  Currently a hardware bug means
+ *  this isn't available on my test board.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include "../iio.h"
+#include "../sysfs.h"
+#include "light.h"
+
+#define TSL2561_CONTROL_REGISTER 0x00
+#define TSL2561_TIMING_REGISTER 0x01
+#define TSL2561_THRESHLOW_LOW_REGISTER 0x02
+#define TSL2561_THRESHLOW_HIGH_REGISTER 0x03
+#define TSL2561_THRESHHIGH_LOW_REGISTER 0x04
+#define TSL2561_THRESHHIGH_HIGH_REGISTER 0x05
+#define TSL2561_INT_CONTROL_REGISTER 0x06
+
+#define TSL2561_INT_REG_INT_OFF 0x00
+#define TSL2561_INT_REG_INT_LEVEL 0x08
+#define TSL2561_INT_REG_INT_SMBUS 0x10
+#define TSL2561_INT_REG_INT_TEST 0x18
+
+#define TSL2561_ID_REGISTER 0x0A
+
+#define TSL2561_DATA_0_LOW 0x0C
+#define TSL2561_DATA_1_LOW 0x0E
+
+/* Control Register Values */
+#define TSL2561_CONT_REG_PWR_ON 0x03
+#define TSL2561_CONT_REG_PWR_OFF 0x00
+
+/**
+ * struct tsl2561_state - device specific state
+ * @indio_dev:		the industrialio I/O info structure
+ * @client:		i2c client
+ * @command_buf:	single command buffer used for all operations
+ * @command_buf_lock:	ensure unique access to command_buf
+ */
+struct tsl2561_state {
+	struct iio_dev		*indio_dev;
+	struct i2c_client	*client;
+	struct tsl2561_command	*command_buf;
+	struct mutex		command_buf_lock;
+};
+
+/**
+ * struct tsl2561_command - command byte for smbus
+ * @address:	register address
+ * @block:	is this a block r/w
+ * @word:	is this a word r/w
+ * @clear:	set to 1 to clear pending interrupt
+ * @cmd:	select the command register - always 1.
+ */
+struct tsl2561_command {
+	unsigned int address:4;
+	unsigned int block:1;
+	unsigned int word:1;
+	unsigned int clear:1;
+	unsigned int cmd:1;
+};
+
+static inline void tsl2561_init_command_buf(struct tsl2561_command *buf)
+{
+	buf->address = 0;
+	buf->block = 0;
+	buf->word = 0;
+	buf->clear = 0;
+	buf->cmd = 1;
+}
+
+static ssize_t tsl2561_read_val(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	int ret = 0, data;
+	ssize_t len = 0;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2561_state *st = indio_dev->dev_data;
+
+	mutex_lock(&st->command_buf_lock);
+	st->command_buf->cmd = 1;
+	st->command_buf->word = 1;
+	st->command_buf->address = this_attr->address;
+
+	data = i2c_smbus_read_word_data(st->client, *(char *)(st->command_buf));
+	if (data < 0) {
+		ret = data;
+		goto error_ret;
+	}
+	len = sprintf(buf, "%u\n", data);
+
+error_ret:
+	mutex_unlock(&st->command_buf_lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEV_ATTR_LIGHT_INFRARED(0, tsl2561_read_val, TSL2561_DATA_0_LOW);
+static IIO_DEV_ATTR_LIGHT_BROAD(0, tsl2561_read_val, TSL2561_DATA_1_LOW);
+
+static struct attribute *tsl2561_attributes[] = {
+	&iio_dev_attr_light_infrared0.dev_attr.attr,
+	&iio_dev_attr_light_broadspectrum0.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group tsl2561_attribute_group = {
+	.attrs = tsl2561_attributes,
+};
+
+static int tsl2561_initialize(struct tsl2561_state *st)
+{
+	int err;
+
+	mutex_lock(&st->command_buf_lock);
+	st->command_buf->word = 0;
+	st->command_buf->block = 0;
+	st->command_buf->address = TSL2561_CONTROL_REGISTER;
+	err = i2c_smbus_write_byte_data(st->client, *(char *)(st->command_buf),
+					TSL2561_CONT_REG_PWR_ON);
+	if (err)
+		goto error_ret;
+
+	st->command_buf->address = TSL2561_INT_CONTROL_REGISTER;
+	err = i2c_smbus_write_byte_data(st->client, *(char *)(st->command_buf),
+					TSL2561_INT_REG_INT_TEST);
+
+error_ret:
+	mutex_unlock(&st->command_buf_lock);
+
+	return err;
+}
+
+static int tsl2561_powerdown(struct i2c_client *client)
+{
+	int err;
+	struct tsl2561_command Command = {
+		.cmd =  1,
+		.clear = 0,
+		.word = 0,
+		.block = 0,
+		.address = TSL2561_CONTROL_REGISTER,
+	};
+
+	err = i2c_smbus_write_byte_data(client, *(char *)(&Command),
+					TSL2561_CONT_REG_PWR_OFF);
+	return (err < 0) ? err : 0;
+}
+static int __devinit tsl2561_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	int ret = 0, regdone = 0;
+	struct tsl2561_state *st = kzalloc(sizeof(*st), GFP_KERNEL);
+
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	i2c_set_clientdata(client, st);
+	st->client = client;
+	mutex_init(&st->command_buf_lock);
+
+	st->command_buf = kmalloc(sizeof(*st->command_buf), GFP_KERNEL);
+	if (st->command_buf == NULL) {
+		ret = -ENOMEM;
+		goto error_free_state;
+	}
+	tsl2561_init_command_buf(st->command_buf);
+
+	st->indio_dev = iio_allocate_device();
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_command_buf;
+	}
+	st->indio_dev->attrs = &tsl2561_attribute_group;
+	st->indio_dev->dev.parent = &client->dev;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->driver_module = THIS_MODULE;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_free_iiodev;
+	regdone = 1;
+	/* Intialize the chip */
+	ret = tsl2561_initialize(st);
+	if (ret)
+		goto error_unregister_iiodev;
+
+	return 0;
+error_unregister_iiodev:
+error_free_iiodev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_command_buf:
+	kfree(st->command_buf);
+error_free_state:
+	kfree(st);
+error_ret:
+	return ret;
+
+}
+
+static int __devexit tsl2561_remove(struct i2c_client *client)
+{
+	struct tsl2561_state *st =  i2c_get_clientdata(client);
+
+	iio_device_unregister(st->indio_dev);
+	kfree(st);
+
+	return tsl2561_powerdown(client);
+}
+
+static unsigned short normal_i2c[] = { 0x29, 0x39, 0x49, I2C_CLIENT_END };
+
+I2C_CLIENT_INSMOD;
+
+static const struct i2c_device_id tsl2561_id[] = {
+	{ "tsl2561", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tsl2561_id);
+
+
+static struct i2c_driver tsl2561_driver = {
+	.driver = {
+		.name = "tsl2561",
+	},
+	.probe = tsl2561_probe,
+	.remove = __devexit_p(tsl2561_remove),
+	.id_table  = tsl2561_id,
+};
+
+static __init int tsl2561_init(void)
+{
+	return i2c_add_driver(&tsl2561_driver);
+}
+module_init(tsl2561_init);
+
+static __exit void tsl2561_exit(void)
+{
+	i2c_del_driver(&tsl2561_driver);
+}
+module_exit(tsl2561_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("TSL2561 light sensor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/ring_generic.h b/drivers/staging/iio/ring_generic.h
new file mode 100644
index 0000000..d926189
--- /dev/null
+++ b/drivers/staging/iio/ring_generic.h
@@ -0,0 +1,283 @@
+/* The industrial I/O core - generic ring buffer interfaces.
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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 _IIO_RING_GENERIC_H_
+#define _IIO_RING_GENERIC_H_
+#include "iio.h"
+
+struct iio_handler;
+struct iio_ring_buffer;
+struct iio_dev;
+
+/**
+ * iio_push_ring_event() - ring buffer specific push to event chrdev
+ * @ring_buf:		ring buffer that is the event source
+ * @event_code:		event indentification code
+ * @timestamp:		time of event
+ **/
+int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
+			int event_code,
+			s64 timestamp);
+/**
+ * iio_push_or_escallate_ring_event() -	escallate or add as appropriate
+ *
+ * Typical usecase is to escallate a 50% ring full to 75% full if noone has yet
+ * read the first event. Clearly the 50% full is no longer of interest in
+ * typical use case.
+ **/
+int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
+				     int event_code,
+				     s64 timestamp);
+
+/**
+ * struct iio_ring_access_funcs - access functions for ring buffers.
+ * @create:		perform allocation
+ * @init:		get ring buffer ready for use
+ * @_exit:		reverse steps in init
+ * @_free:		deallocate ring buffer
+ * @mark_in_use:	reference counting, typically to prevent module removal
+ * @unmark_in_use:	reduce reference count when no longer using ring buffer
+ * @store_to:		actually store stuff to the ring buffer
+ * @read_last:		get the last element stored
+ * @rip_lots:		try to get a specified number of elements (must exist)
+ * @mark_param_change:	notify ring that some relevant parameter has changed
+ *			Often this means the underlying storage may need to
+ *			change.
+ * @request_update:	if a parameter change has been marked, update underlying
+ *			storage.
+ * @get_bpd:		get current bytes per datum
+ * @set_bpd:		set number of bytes per datum
+ * @get_length:		get number of datums in ring
+ * @set_length:		set number of datums in ring
+ * @is_enabled:		query if ring is currently being used
+ * @enable:		enable the ring
+ *
+ * The purpose of this structure is to make the ring buffer element
+ * modular as event for a given driver, different usecases may require
+ * different ring designs (space efficiency vs speed for example.
+ *
+ * It is worth noting that a given ring implementation may only support a small
+ * proportion of these functions.  The core code 'should' cope fine with any of
+ * them not existing.
+ **/
+struct iio_ring_access_funcs {
+	void (*mark_in_use)(struct iio_ring_buffer *ring);
+	void (*unmark_in_use)(struct iio_ring_buffer *ring);
+
+	int (*store_to)(struct iio_ring_buffer *ring, u8 *data, s64 timestamp);
+	int (*read_last)(struct iio_ring_buffer *ring, u8 *data);
+	int (*rip_lots)(struct iio_ring_buffer *ring,
+			size_t count,
+			u8 **data,
+			int *dead_offset);
+
+	int (*mark_param_change)(struct iio_ring_buffer *ring);
+	int (*request_update)(struct iio_ring_buffer *ring);
+
+	int (*get_bpd)(struct iio_ring_buffer *ring);
+	int (*set_bpd)(struct iio_ring_buffer *ring, size_t bpd);
+	int (*get_length)(struct iio_ring_buffer *ring);
+	int (*set_length)(struct iio_ring_buffer *ring, int length);
+
+	int (*is_enabled)(struct iio_ring_buffer *ring);
+	int (*enable)(struct iio_ring_buffer *ring);
+};
+
+/**
+ * struct iio_ring_buffer - general ring buffer structure
+ * @length:		[DEVICE]number of datums in ring
+ * @bpd:		[DEVICE]size of individual datum including timestamp
+ * @loopcount:		[INTERN]number of times the ring has looped
+ * @access_minor_name:	[INTERN]store of name of the access chrdev minor number
+ *			sysfs attribute
+ * @access_handler:	[INTERN]chrdev access handling
+ * @event_minor_name:	[INTERN]store of name of the event chrdev minor number
+ *			sysfs attribute
+ * @ev_int:		[INTERN]chrdev interface for the event chrdev
+ * @shared_ev_pointer:	[INTERN]the shared event pointer to allow escalation of
+ *			events
+ * @ring_access:	[DRIVER]ring access functions associated with the
+ *			implementation.
+ * @ring_prenable:	[DRIVER] function to run prior to marking ring enabled
+ * @ring_postenable:	[DRIVER] function to run after marking ring enabled
+ * @ring_predisable:	[DRIVER] function to run prior to marking ring disabled
+ * @ring_postdisable:	[DRIVER] function to run after marking ring disabled
+  **/
+struct iio_ring_buffer {
+	struct device dev;
+	struct device access_dev;
+	struct iio_dev *indio_dev;
+	struct module *owner;
+	int				id;
+	int				access_id;
+	int				length;
+	int				bpd;
+	int				loopcount;
+	struct iio_handler		access_handler;
+	struct iio_event_interface	ev_int;
+	struct iio_shared_ev_pointer	shared_ev_pointer;
+	struct iio_ring_access_funcs	access;
+	int				(*preenable)(struct iio_dev *);
+	int				(*postenable)(struct iio_dev *);
+	int				(*predisable)(struct iio_dev *);
+	int				(*postdisable)(struct iio_dev *);
+
+};
+void iio_ring_buffer_init(struct iio_ring_buffer *ring,
+			  struct iio_dev *dev_info);
+
+/**
+ * __iio_init_ring_buffer() - initialize common elements of ring buffers.
+ **/
+static inline void __iio_init_ring_buffer(struct iio_ring_buffer *ring,
+				 int bytes_per_datum, int length)
+{
+	ring->bpd = bytes_per_datum;
+	ring->length = length;
+	ring->loopcount = 0;
+	ring->shared_ev_pointer.ev_p = 0;
+	ring->shared_ev_pointer.lock =
+		__SPIN_LOCK_UNLOCKED(ring->shared_ev_pointer->loc);
+}
+
+/**
+ * struct iio_scan_el - an individual element of a scan
+ * @dev_attr:		control attribute (if directly controllable)
+ * @number:		unique identifier of element (used for bit mask)
+ * @bit_count:		number of bits in scan element
+ * @label:		useful data for the scan el (often reg address)
+ * @set_state:		for some devices datardy signals are generated
+ *			for any enabled lines.  This allows unwanted lines
+ *			to be disabled and hence not get in the way.
+ **/
+struct iio_scan_el {
+	struct device_attribute		dev_attr;
+	unsigned int			number;
+	int				bit_count;
+	unsigned int			label;
+
+	int (*set_state)(struct iio_scan_el *scanel,
+			 struct iio_dev *dev_info,
+			 bool state);
+};
+
+#define to_iio_scan_el(_dev_attr)				\
+	container_of(_dev_attr, struct iio_scan_el, dev_attr);
+
+/**
+ * iio_scan_el_store() - sysfs scan element selection interface.
+ *
+ * A generic function used to enable various scan elements.  In some
+ * devices explicit read commands for each channel mean this is merely
+ * a software switch.  In others this must actively disable the channel.
+ * Complexities occur when this interacts with data ready type triggers
+ * which may not reset unless every channel that is enabled is explicitly
+ * read.
+ **/
+ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr,
+			  const char *buf, size_t len);
+/**
+ * iio_scal_el_show() -	sysfs interface to query whether a scan element is
+ *			is enabled or not.
+ **/
+ssize_t iio_scan_el_show(struct device *dev, struct device_attribute *attr,
+			 char *buf);
+/**
+ * IIO_SCAN_EL: - declare and initialize a scan element without control func
+ * @_name:	identifying name. Resulting struct is iio_scan_el_##_name,
+ *		sysfs element, scan_en_##_name.
+ * @_number:	unique id number for the scan element.
+ * @_bits:	number of bits in the scan element result (used in mixed bit
+ *		length devices).
+ * @_label:	indentification variable used by drivers.  Often a reg address.
+ **/
+#define IIO_SCAN_EL(_name, _number, _bits, _label)			\
+	struct iio_scan_el iio_scan_el_##_name = {			\
+		.dev_attr = __ATTR(scan_en_##_name,			\
+				   S_IRUGO | S_IWUSR,			\
+				   iio_scan_el_show,			\
+				   iio_scan_el_store),			\
+		.mask = (1 << _number),					\
+		.bit_count = _bits,					\
+		.label = _label,					\
+	}
+
+ssize_t iio_scan_el_ts_store(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t len);
+
+ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
+			    char *buf);
+/**
+ * IIO_SCAN_EL_C: - declare and initialize a scan element with a control func
+ *
+ * @_controlfunc: function used to notify hardware of whether state changes
+ **/
+#define IIO_SCAN_EL_C(_name, _number, _bits, _label, _controlfunc)	\
+	struct iio_scan_el iio_scan_el_##_name = {			\
+		.dev_attr = __ATTR(scan_en_##_name,			\
+				   S_IRUGO | S_IWUSR,			\
+				   iio_scan_el_show,			\
+				   iio_scan_el_store),			\
+		.number =  _number,					\
+		.bit_count = _bits,					\
+		.label = _label,					\
+		.set_state = _controlfunc,				\
+	}
+/**
+ * IIO_SCAN_EL_TIMESTAMP: - declare a special scan element for timestamps
+ *
+ * Odd one out. Handled slightly differently from other scan elements.
+ **/
+#define IIO_SCAN_EL_TIMESTAMP					\
+	struct iio_scan_el iio_scan_el_timestamp = {		\
+		.dev_attr = __ATTR(scan_en_timestamp,		\
+				   S_IRUGO | S_IWUSR,		\
+				   iio_scan_el_ts_show,		\
+				   iio_scan_el_ts_store),	\
+	}
+
+static inline void iio_put_ring_buffer(struct iio_ring_buffer *ring)
+{
+	put_device(&ring->dev);
+};
+
+#define to_iio_ring_buffer(d)			\
+	container_of(d, struct iio_ring_buffer, dev)
+#define access_dev_to_iio_ring_buffer(d)			\
+	container_of(d, struct iio_ring_buffer, access_dev)
+int iio_ring_buffer_register(struct iio_ring_buffer *ring);
+void iio_ring_buffer_unregister(struct iio_ring_buffer *ring);
+
+ssize_t iio_read_ring_length(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf);
+ssize_t iio_write_ring_length(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t len);
+ssize_t iio_read_ring_bps(struct device *dev,
+			  struct device_attribute *attr,
+			  char *buf);
+ssize_t iio_store_ring_enable(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t len);
+ssize_t iio_show_ring_enable(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf);
+#define IIO_RING_LENGTH_ATTR DEVICE_ATTR(length, S_IRUGO | S_IWUSR,	\
+					 iio_read_ring_length,		\
+					 iio_write_ring_length)
+#define IIO_RING_BPS_ATTR DEVICE_ATTR(bps, S_IRUGO | S_IWUSR,	\
+				      iio_read_ring_bps, NULL)
+#define IIO_RING_ENABLE_ATTR DEVICE_ATTR(ring_enable, S_IRUGO | S_IWUSR, \
+					 iio_show_ring_enable,		\
+					 iio_store_ring_enable)
+
+#endif /* _IIO_RING_GENERIC_H_ */
diff --git a/drivers/staging/iio/ring_hw.h b/drivers/staging/iio/ring_hw.h
new file mode 100644
index 0000000..bb8cfd2
--- /dev/null
+++ b/drivers/staging/iio/ring_hw.h
@@ -0,0 +1,22 @@
+/*
+ * ring_hw.h - common functionality for iio hardware ring buffers
+ *
+ * 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.
+ *
+ * Copyright (c) 2009 Jonathan Cameron <jic23@cam.ac.uk>
+ *
+ */
+
+/**
+ * struct iio_hw_ring_buffer- hardware ring buffer
+ * @buf:	generic ring buffer elements
+ * @private:	device specific data
+ */
+struct iio_hw_ring_buffer {
+	struct iio_ring_buffer buf;
+	void *private;
+};
+
+#define iio_to_hw_ring_buf(r) container_of(r, struct iio_hw_ring_buffer, buf)
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c
new file mode 100644
index 0000000..359ff92
--- /dev/null
+++ b/drivers/staging/iio/ring_sw.c
@@ -0,0 +1,433 @@
+/* The industrial I/O simple minimally locked ring buffer.
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include "ring_sw.h"
+
+static inline int __iio_init_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
+					    int bytes_per_datum, int length)
+{
+	if ((length == 0) || (bytes_per_datum == 0))
+		return -EINVAL;
+
+	__iio_init_ring_buffer(&ring->buf, bytes_per_datum, length);
+	ring->use_lock = __SPIN_LOCK_UNLOCKED((ring)->use_lock);
+	ring->data = kmalloc(length*ring->buf.bpd, GFP_KERNEL);
+	ring->read_p = 0;
+	ring->write_p = 0;
+	ring->last_written_p = 0;
+	ring->half_p = 0;
+	return ring->data ? 0 : -ENOMEM;
+}
+
+static inline void __iio_free_sw_ring_buffer(struct iio_sw_ring_buffer *ring)
+{
+	kfree(ring->data);
+}
+
+void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r)
+{
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+	spin_lock(&ring->use_lock);
+	ring->use_count++;
+	spin_unlock(&ring->use_lock);
+}
+EXPORT_SYMBOL(iio_mark_sw_rb_in_use);
+
+void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r)
+{
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+	spin_lock(&ring->use_lock);
+	ring->use_count--;
+	spin_unlock(&ring->use_lock);
+}
+EXPORT_SYMBOL(iio_unmark_sw_rb_in_use);
+
+
+/* Ring buffer related functionality */
+/* Store to ring is typically called in the bh of a data ready interrupt handler
+ * in the device driver */
+/* Lock always held if their is a chance this may be called */
+/* Only one of these per ring may run concurrently - enforced by drivers */
+int iio_store_to_sw_ring(struct iio_sw_ring_buffer *ring,
+			 unsigned char *data,
+			 s64 timestamp)
+{
+	int ret = 0;
+	int code;
+	unsigned char *temp_ptr, *change_test_ptr;
+
+	/* initial store */
+	if (unlikely(ring->write_p == 0)) {
+		ring->write_p = ring->data;
+		/* Doesn't actually matter if this is out of the set
+		 * as long as the read pointer is valid before this
+		 * passes it - guaranteed as set later in this function.
+		 */
+		ring->half_p = ring->data - ring->buf.length*ring->buf.bpd/2;
+	}
+	/* Copy data to where ever the current write pointer says */
+	memcpy(ring->write_p, data, ring->buf.bpd);
+	barrier();
+	/* Update the pointer used to get most recent value.
+	 * Always valid as either points to latest or second latest value.
+	 * Before this runs it is null and read attempts fail with -EAGAIN.
+	 */
+	ring->last_written_p = ring->write_p;
+	barrier();
+	/* temp_ptr used to ensure we never have an invalid pointer
+	 * it may be slightly lagging, but never invalid
+	 */
+	temp_ptr = ring->write_p + ring->buf.bpd;
+	/* End of ring, back to the beginning */
+	if (temp_ptr == ring->data + ring->buf.length*ring->buf.bpd)
+		temp_ptr = ring->data;
+	/* Update the write pointer
+	 * always valid as long as this is the only function able to write.
+	 * Care needed with smp systems to ensure more than one ring fill
+	 * is never scheduled.
+	 */
+	ring->write_p = temp_ptr;
+
+	if (ring->read_p == 0)
+		ring->read_p = ring->data;
+	/* Buffer full - move the read pointer and create / escalate
+	 * ring event */
+	/* Tricky case - if the read pointer moves before we adjust it.
+	 * Handle by not pushing if it has moved - may result in occasional
+	 * unnecessary buffer full events when it wasn't quite true.
+	 */
+	else if (ring->write_p == ring->read_p) {
+		change_test_ptr = ring->read_p;
+		temp_ptr = change_test_ptr + ring->buf.bpd;
+		if (temp_ptr
+		    == ring->data + ring->buf.length*ring->buf.bpd) {
+			temp_ptr = ring->data;
+		}
+		/* We are moving pointer on one because the ring is full.  Any
+		 * change to the read pointer will be this or greater.
+		 */
+		if (change_test_ptr == ring->read_p)
+			ring->read_p = temp_ptr;
+
+		spin_lock(&ring->buf.shared_ev_pointer.lock);
+
+		ret = iio_push_or_escallate_ring_event(&ring->buf,
+						       IIO_EVENT_CODE_RING_100_FULL,
+						       timestamp);
+		spin_unlock(&ring->buf.shared_ev_pointer.lock);
+		if (ret)
+			goto error_ret;
+	}
+	/* investigate if our event barrier has been passed */
+	/* There are definite 'issues' with this and chances of
+	 * simultaneous read */
+	/* Also need to use loop count to ensure this only happens once */
+	ring->half_p += ring->buf.bpd;
+	if (ring->half_p == ring->data + ring->buf.length*ring->buf.bpd)
+		ring->half_p = ring->data;
+	if (ring->half_p == ring->read_p) {
+		spin_lock(&ring->buf.shared_ev_pointer.lock);
+		code = IIO_EVENT_CODE_RING_50_FULL;
+		ret = __iio_push_event(&ring->buf.ev_int,
+				       code,
+				       timestamp,
+				       &ring->buf.shared_ev_pointer);
+		spin_unlock(&ring->buf.shared_ev_pointer.lock);
+	}
+error_ret:
+	return ret;
+}
+
+int iio_rip_sw_rb(struct iio_ring_buffer *r,
+		  size_t count, u8 **data, int *dead_offset)
+{
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+
+	u8 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p;
+	int ret, max_copied;
+	int bytes_to_rip;
+
+	/* A userspace program has probably made an error if it tries to
+	 *  read something that is not a whole number of bpds.
+	 * Return an error.
+	 */
+	if (count % ring->buf.bpd) {
+		ret = -EINVAL;
+		printk(KERN_INFO "Ring buffer read request not whole number of"
+		       "samples: Request bytes %zd, Current bpd %d\n",
+		       count, ring->buf.bpd);
+		goto error_ret;
+	}
+	/* Limit size to whole of ring buffer */
+	bytes_to_rip = min((size_t)(ring->buf.bpd*ring->buf.length), count);
+
+	*data = kmalloc(bytes_to_rip, GFP_KERNEL);
+	if (*data == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	/* build local copy */
+	initial_read_p = ring->read_p;
+	if (unlikely(initial_read_p == 0)) { /* No data here as yet */
+		ret = 0;
+		goto error_free_data_cpy;
+	}
+
+	initial_write_p = ring->write_p;
+
+	/* Need a consistent pair */
+	while ((initial_read_p != ring->read_p)
+	       || (initial_write_p != ring->write_p)) {
+		initial_read_p = ring->read_p;
+		initial_write_p = ring->write_p;
+	}
+	if (initial_write_p == initial_read_p) {
+		/* No new data available.*/
+		ret = 0;
+		goto error_free_data_cpy;
+	}
+
+	if (initial_write_p >= initial_read_p + bytes_to_rip) {
+		/* write_p is greater than necessary, all is easy */
+		max_copied = bytes_to_rip;
+		memcpy(*data, initial_read_p, max_copied);
+		end_read_p = initial_read_p + max_copied;
+	} else if (initial_write_p > initial_read_p) {
+		/*not enough data to cpy */
+		max_copied = initial_write_p - initial_read_p;
+		memcpy(*data, initial_read_p, max_copied);
+		end_read_p = initial_write_p;
+	} else {
+		/* going through 'end' of ring buffer */
+		max_copied = ring->data
+			+ ring->buf.length*ring->buf.bpd - initial_read_p;
+		memcpy(*data, initial_read_p, max_copied);
+		/* possible we are done if we align precisely with end */
+		if (max_copied == bytes_to_rip)
+			end_read_p = ring->data;
+		else if (initial_write_p
+			 > ring->data + bytes_to_rip - max_copied) {
+			/* enough data to finish */
+			memcpy(*data + max_copied, ring->data,
+			       bytes_to_rip - max_copied);
+			max_copied = bytes_to_rip;
+			end_read_p = ring->data + (bytes_to_rip - max_copied);
+		} else {  /* not enough data */
+			memcpy(*data + max_copied, ring->data,
+			       initial_write_p - ring->data);
+			max_copied += initial_write_p - ring->data;
+			end_read_p = initial_write_p;
+		}
+	}
+	/* Now to verify which section was cleanly copied - i.e. how far
+	 * read pointer has been pushed */
+	current_read_p = ring->read_p;
+
+	if (initial_read_p <= current_read_p)
+		*dead_offset = current_read_p - initial_read_p;
+	else
+		*dead_offset = ring->buf.length*ring->buf.bpd
+			- (initial_read_p - current_read_p);
+
+	/* possible issue if the initial write has been lapped or indeed
+	 * the point we were reading to has been passed */
+	/* No valid data read.
+	 * In this case the read pointer is already correct having been
+	 * pushed further than we would look. */
+	if (max_copied - *dead_offset < 0) {
+		ret = 0;
+		goto error_free_data_cpy;
+	}
+
+	/* setup the next read position */
+	/* Beware, this may fail due to concurrency fun and games.
+	 *  Possible that sufficient fill commands have run to push the read
+	 * pointer past where we would be after the rip. If this occurs, leave
+	 * it be.
+	 */
+	/* Tricky - deal with loops */
+
+	while (ring->read_p != end_read_p)
+		ring->read_p = end_read_p;
+
+	return max_copied - *dead_offset;
+
+error_free_data_cpy:
+	kfree(*data);
+error_ret:
+	return ret;
+}
+EXPORT_SYMBOL(iio_rip_sw_rb);
+
+int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp)
+{
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+	return iio_store_to_sw_ring(ring, data, timestamp);
+}
+EXPORT_SYMBOL(iio_store_to_sw_rb);
+
+int iio_read_last_from_sw_ring(struct iio_sw_ring_buffer *ring,
+			       unsigned char *data)
+{
+	unsigned char *last_written_p_copy;
+
+	iio_mark_sw_rb_in_use(&ring->buf);
+again:
+	barrier();
+	last_written_p_copy = ring->last_written_p;
+	barrier(); /*unnessecary? */
+	/* Check there is anything here */
+	if (last_written_p_copy == 0)
+		return -EAGAIN;
+	memcpy(data, last_written_p_copy, ring->buf.bpd);
+
+	if (unlikely(ring->last_written_p >= last_written_p_copy))
+		goto again;
+
+	iio_unmark_sw_rb_in_use(&ring->buf);
+	return 0;
+}
+
+int iio_read_last_from_sw_rb(struct iio_ring_buffer *r,
+			     unsigned char *data)
+{
+	return iio_read_last_from_sw_ring(iio_to_sw_ring(r), data);
+}
+EXPORT_SYMBOL(iio_read_last_from_sw_rb);
+
+int iio_request_update_sw_rb(struct iio_ring_buffer *r)
+{
+	int ret = 0;
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+
+	spin_lock(&ring->use_lock);
+	if (!ring->update_needed)
+		goto error_ret;
+	if (ring->use_count) {
+		ret = -EAGAIN;
+		goto error_ret;
+	}
+	__iio_free_sw_ring_buffer(ring);
+	ret = __iio_init_sw_ring_buffer(ring, ring->buf.bpd, ring->buf.length);
+error_ret:
+	spin_unlock(&ring->use_lock);
+	return ret;
+}
+EXPORT_SYMBOL(iio_request_update_sw_rb);
+
+int iio_get_bpd_sw_rb(struct iio_ring_buffer *r)
+{
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+	return ring->buf.bpd;
+}
+EXPORT_SYMBOL(iio_get_bpd_sw_rb);
+
+int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd)
+{
+	if (r->bpd != bpd) {
+		r->bpd = bpd;
+		if (r->access.mark_param_change)
+			r->access.mark_param_change(r);
+	}
+	return 0;
+}
+EXPORT_SYMBOL(iio_set_bpd_sw_rb);
+
+int iio_get_length_sw_rb(struct iio_ring_buffer *r)
+{
+	return r->length;
+}
+EXPORT_SYMBOL(iio_get_length_sw_rb);
+
+int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length)
+{
+	if (r->length != length) {
+		r->length = length;
+		if (r->access.mark_param_change)
+			r->access.mark_param_change(r);
+	}
+	return 0;
+}
+EXPORT_SYMBOL(iio_set_length_sw_rb);
+
+int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r)
+{
+	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
+	ring->update_needed = true;
+	return 0;
+}
+EXPORT_SYMBOL(iio_mark_update_needed_sw_rb);
+
+static void iio_sw_rb_release(struct device *dev)
+{
+	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
+	kfree(iio_to_sw_ring(r));
+}
+
+static IIO_RING_ENABLE_ATTR;
+static IIO_RING_BPS_ATTR;
+static IIO_RING_LENGTH_ATTR;
+
+/* Standard set of ring buffer attributes */
+static struct attribute *iio_ring_attributes[] = {
+	&dev_attr_length.attr,
+	&dev_attr_bps.attr,
+	&dev_attr_ring_enable.attr,
+	NULL,
+};
+
+static struct attribute_group iio_ring_attribute_group = {
+	.attrs = iio_ring_attributes,
+};
+
+static const struct attribute_group *iio_ring_attribute_groups[] = {
+	&iio_ring_attribute_group,
+	NULL
+};
+
+static struct device_type iio_sw_ring_type = {
+	.release = iio_sw_rb_release,
+	.groups = iio_ring_attribute_groups,
+};
+
+struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev)
+{
+	struct iio_ring_buffer *buf;
+	struct iio_sw_ring_buffer *ring;
+
+	ring = kzalloc(sizeof *ring, GFP_KERNEL);
+	if (!ring)
+		return 0;
+	buf = &ring->buf;
+
+	iio_ring_buffer_init(buf, indio_dev);
+	buf->dev.type = &iio_sw_ring_type;
+	device_initialize(&buf->dev);
+	buf->dev.parent = &indio_dev->dev;
+	buf->dev.class = &iio_class;
+	dev_set_drvdata(&buf->dev, (void *)buf);
+
+	return buf;
+}
+EXPORT_SYMBOL(iio_sw_rb_allocate);
+
+void iio_sw_rb_free(struct iio_ring_buffer *r)
+{
+	if (r)
+		iio_put_ring_buffer(r);
+}
+EXPORT_SYMBOL(iio_sw_rb_free);
+MODULE_DESCRIPTION("Industrialio I/O software ring buffer");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/iio/ring_sw.h b/drivers/staging/iio/ring_sw.h
new file mode 100644
index 0000000..ae70ee0
--- /dev/null
+++ b/drivers/staging/iio/ring_sw.h
@@ -0,0 +1,189 @@
+/* The industrial I/O simple minimally locked ring buffer.
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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 code is deliberately kept separate from the main industrialio I/O core
+ * as it is intended that in the future a number of different software ring
+ * buffer implementations will exist with different characteristics to suit
+ * different applications.
+ *
+ * This particular one was designed for a data capture application where it was
+ * particularly important that no userspace reads would interrupt the capture
+ * process. To this end the ring is not locked during a read.
+ *
+ * Comments on this buffer design welcomed. It's far from efficient and some of
+ * my understanding of the effects of scheduling on this are somewhat limited.
+ * Frankly, to my mind, this is the current weak point in the industrial I/O
+ * patch set.
+ */
+
+#ifndef _IIO_RING_SW_H_
+#define _IIO_RING_SW_H_
+/* NEEDS COMMENTS */
+/* The intention is that this should be a separate module from the iio core.
+ * This is a bit like supporting algorithms dependent on what the device
+ * driver requests - some may support multiple options */
+
+
+#include <linux/autoconf.h>
+#include "iio.h"
+#include "ring_generic.h"
+
+#if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE
+
+/**
+ * iio_create_sw_rb() software ring buffer allocation
+ * @r:		pointer to ring buffer pointer
+ **/
+int iio_create_sw_rb(struct iio_ring_buffer **r);
+
+/**
+ * iio_init_sw_rb() initialize the software ring buffer
+ * @r:		pointer to a software ring buffer created by an
+ *		iio_create_sw_rb call.
+ **/
+int iio_init_sw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev);
+/**
+ * iio_exit_sw_rb() reverse what was done in iio_init_sw_rb
+ **/
+void iio_exit_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_free_sw_rb() free memory occupied by the core ring buffer struct
+ **/
+void iio_free_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_mark_sw_rb_in_use() reference counting to prevent incorrect chances
+ **/
+void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r);
+
+/**
+ *  iio_unmark_sw_rb_in_use() notify the ring buffer that we don't care anymore
+ **/
+void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r);
+
+/**
+ * iio_read_last_from_sw_rb() attempt to read the last stored datum from the rb
+ **/
+int iio_read_last_from_sw_rb(struct iio_ring_buffer *r, u8 *data);
+
+/**
+ * iio_store_to_sw_rb() store a new datum to the ring buffer
+ * @rb:	pointer to ring buffer instance
+ * @data:	the datum to be stored including timestamp if relevant.
+ * @timestamp:	timestamp which will be attached to buffer events if relevant.
+ **/
+int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
+
+/**
+ * iio_rip_sw_rb() attempt to read data from the ring buffer
+ * @r:			ring buffer instance
+ * @count:		number of datum's to try and read
+ * @data:		where the data will be stored.
+ * @dead_offset:	how much of the stored data was possibly invalidated by
+ *			the end of the copy.
+ **/
+int iio_rip_sw_rb(struct iio_ring_buffer *r,
+		  size_t count,
+		  u8 **data,
+		  int *dead_offset);
+
+/**
+ * iio_request_update_sw_rb() update params if update needed
+ **/
+int iio_request_update_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_mark_update_needed_sw_rb() tell the ring buffer it needs a param update
+ **/
+int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
+
+
+/**
+ * iio_get_bpd_sw_rb() get the datum size in bytes
+ **/
+int iio_get_bpd_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_set_bpd_sw_rb() set the datum size in bytes
+ **/
+int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd);
+
+/**
+ * iio_get_length_sw_rb() get how many datums the rb may contain
+ **/
+int iio_get_length_sw_rb(struct iio_ring_buffer *r);
+
+/**
+ * iio_set_length_sw_rb() set how many datums the rb may contain
+ **/
+int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length);
+
+/**
+ * iio_ring_sw_register_funcs() helper function to set up rb access
+ **/
+static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
+{
+	ra->mark_in_use = &iio_mark_sw_rb_in_use;
+	ra->unmark_in_use = &iio_unmark_sw_rb_in_use;
+
+	ra->store_to = &iio_store_to_sw_rb;
+	ra->read_last = &iio_read_last_from_sw_rb;
+	ra->rip_lots = &iio_rip_sw_rb;
+
+	ra->mark_param_change = &iio_mark_update_needed_sw_rb;
+	ra->request_update = &iio_request_update_sw_rb;
+
+	ra->get_bpd = &iio_get_bpd_sw_rb;
+	ra->set_bpd = &iio_set_bpd_sw_rb;
+
+	ra->get_length = &iio_get_length_sw_rb;
+	ra->set_length = &iio_set_length_sw_rb;
+};
+
+/**
+ * struct iio_sw_ring_buffer - software ring buffer
+ * @buf:		generic ring buffer elements
+ * @data:		the ring buffer memory
+ * @read_p:		read pointer (oldest available)
+ * @write_p:		write pointer
+ * @last_written_p:	read pointer (newest available)
+ * @half_p:		half buffer length behind write_p (event generation)
+ * @use_count:		reference count to prevent resizing when in use
+ * @update_needed:	flag to indicated change in size requested
+ * @use_lock:		lock to prevent change in size when in use
+ *
+ * Note that the first element of all ring buffers must be a
+ * struct iio_ring_buffer.
+**/
+
+struct iio_sw_ring_buffer {
+	struct iio_ring_buffer  buf;
+	unsigned char		*data;
+	unsigned char		*read_p;
+	unsigned char		*write_p;
+	unsigned char		*last_written_p;
+	/* used to act as a point at which to signal an event */
+	unsigned char		*half_p;
+	int			use_count;
+	int			update_needed;
+	spinlock_t		use_lock;
+};
+
+#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
+
+struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
+void iio_sw_rb_free(struct iio_ring_buffer *ring);
+
+
+
+#else /* CONFIG_IIO_RING_BUFFER*/
+static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
+{};
+#endif /* !CONFIG_IIO_RING_BUFFER */
+#endif /* _IIO_RING_SW_H_ */
diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h
new file mode 100644
index 0000000..bfe4055
--- /dev/null
+++ b/drivers/staging/iio/sysfs.h
@@ -0,0 +1,293 @@
+/* The industrial I/O core
+ *
+ *Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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.
+ *
+ * General attributes
+ */
+
+#ifndef _INDUSTRIAL_IO_SYSFS_H_
+#define _INDUSTRIAL_IO_SYSFS_H_
+
+#include "iio.h"
+
+/**
+ * struct iio_event_attribute - event control attribute
+ * @dev_attr:	underlying device attribute
+ * @mask:	mask for the event when detecting
+ * @listel:	list header to allow addition to list of event handlers
+*/
+struct iio_event_attr {
+	struct device_attribute dev_attr;
+	int mask;
+	struct iio_event_handler_list *listel;
+};
+
+#define to_iio_event_attr(_dev_attr) \
+	container_of(_dev_attr, struct iio_event_attr, dev_attr)
+
+/**
+ * struct iio_chrdev_minor_attr - simple attribute to allow reading of chrdev
+ *				minor number
+ * @dev_attr:	underlying device attribute
+ * @minor:	the minor number
+ */
+struct iio_chrdev_minor_attr {
+	struct device_attribute dev_attr;
+	int minor;
+};
+
+void
+__init_iio_chrdev_minor_attr(struct iio_chrdev_minor_attr *minor_attr,
+			   const char *name,
+			   struct module *owner,
+			   int id);
+
+
+#define to_iio_chrdev_minor_attr(_dev_attr) \
+	container_of(_dev_attr, struct iio_chrdev_minor_attr, dev_attr);
+
+/**
+ * struct iio_dev_attr - iio specific device attribute
+ * @dev_attr:	underlying device attribute
+ * @address:	associated register address
+ */
+struct iio_dev_attr {
+	struct device_attribute dev_attr;
+	int address;
+	int val2;
+};
+
+#define to_iio_dev_attr(_dev_attr)				\
+	container_of(_dev_attr, struct iio_dev_attr, dev_attr)
+
+ssize_t iio_read_const_attr(struct device *dev,
+			    struct device_attribute *attr,
+			    char *len);
+
+/**
+ * struct iio_const_attr - constant device specific attribute
+ *                         often used for things like available modes
+ */
+struct iio_const_attr {
+	const char *string;
+	struct device_attribute dev_attr;
+};
+
+#define to_iio_const_attr(_dev_attr) \
+	container_of(_dev_attr, struct iio_const_attr, dev_attr)
+
+/* Some attributes will be hard coded (device dependant) and not require an
+   address, in these cases pass a negative */
+#define IIO_ATTR(_name, _mode, _show, _store, _addr)		\
+	{ .dev_attr = __ATTR(_name, _mode, _show, _store),	\
+	  .address = _addr }
+
+#define IIO_ATTR_2(_name, _mode, _show, _store, _addr, _val2)	\
+	{ .dev_attr = __ATTR(_name, _mode, _show, _store),	\
+			.address = _addr,			\
+			.val2 = _val2 }
+
+#define IIO_DEVICE_ATTR(_name, _mode, _show, _store, _addr)	\
+	struct iio_dev_attr iio_dev_attr_##_name		\
+	= IIO_ATTR(_name, _mode, _show, _store, _addr)
+
+
+#define IIO_DEVICE_ATTR_2(_name, _mode, _show, _store, _addr, _val2)	\
+	struct iio_dev_attr iio_dev_attr_##_name			\
+	= IIO_ATTR_2(_name, _mode, _show, _store, _addr, _val2)
+
+#define IIO_CONST_ATTR(_name, _string)					\
+	struct iio_const_attr iio_const_attr_##_name			\
+	= { .string = _string,						\
+	    .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)}
+
+/* Generic attributes of onetype or another */
+
+/**
+ * IIO_DEV_ATTR_REG: revision number for the device
+ *
+ * Very much device dependent.
+ **/
+#define IIO_DEV_ATTR_REV(_show)			\
+	IIO_DEVICE_ATTR(revision, S_IRUGO, _show, NULL, 0)
+/**
+ * IIO_DEV_ATTR_NAME: chip type dependant identifier
+ **/
+#define IIO_DEV_ATTR_NAME(_show)				\
+	IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
+
+/**
+ * IIO_DEV_ATTR_SAMP_FREQ: sets any internal clock frequency
+ **/
+#define IIO_DEV_ATTR_SAMP_FREQ(_mode, _show, _store)			\
+	IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0)
+
+/**
+ * IIO_DEV_ATTR_AVAIL_SAMP_FREQ: list available sampling frequencies.
+ *
+ * May be mode dependant on some devices
+ **/
+#define IIO_DEV_ATTR_AVAIL_SAMP_FREQ(_show)				\
+	IIO_DEVICE_ATTR(available_sampling_frequency, S_IRUGO, _show, NULL, 0)
+
+/**
+ * IIO_DEV_ATTR_CONST_AVAIL_SAMP_FREQ: list available sampling frequencies.
+ *
+ * Constant version
+ **/
+#define IIO_CONST_ATTR_AVAIL_SAMP_FREQ(_string)	\
+	IIO_CONST_ATTR(available_sampling_frequency, _string)
+/**
+ * IIO_DEV_ATTR_SCAN_MODE: select a scan mode
+ *
+ * This is used when only certain combinations of inputs may be read in one
+ * scan.
+ **/
+#define IIO_DEV_ATTR_SCAN_MODE(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(scan_mode, _mode, _show, _store, 0)
+/**
+ * IIO_DEV_ATTR_AVAIL_SCAN_MODES: list available scan modes
+ **/
+#define IIO_DEV_ATTR_AVAIL_SCAN_MODES(_show)				\
+	IIO_DEVICE_ATTR(available_scan_modes, S_IRUGO, _show, NULL, 0)
+
+/**
+ * IIO_DEV_ATTR_SCAN: result of scan of multiple channels
+ **/
+#define IIO_DEV_ATTR_SCAN(_show)		\
+	IIO_DEVICE_ATTR(scan, S_IRUGO, _show, NULL, 0);
+
+/**
+ * IIO_DEV_ATTR_INPUT: direct read of a single input channel
+ **/
+#define IIO_DEV_ATTR_INPUT(_number, _show)				\
+	IIO_DEVICE_ATTR(in##_number, S_IRUGO, _show, NULL, _number)
+
+
+/**
+ * IIO_DEV_ATTR_SW_RING_ENABLE: enable software ring buffer
+ *
+ * Success may be dependant on attachment of trigger previously
+ **/
+#define IIO_DEV_ATTR_SW_RING_ENABLE(_show, _store)			\
+	IIO_DEVICE_ATTR(sw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0)
+
+/**
+ * IIO_DEV_ATTR_HW_RING_ENABLE: enable hardware ring buffer
+ *
+ * This is a different attribute from the software one as one can invision
+ * schemes where a combination of the two may be used.
+ **/
+#define IIO_DEV_ATTR_HW_RING_ENABLE(_show, _store)			\
+	IIO_DEVICE_ATTR(hw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0)
+
+/**
+ * IIO_DEV_ATTR_BPSE: set number of bits per scan element
+ **/
+#define IIO_DEV_ATTR_BPSE(_mode, _show, _store)		\
+	IIO_DEVICE_ATTR(bpse, _mode, _show, _store, 0)
+
+/**
+ * IIO_DEV_ATTR_BPSE_AVAILABLE: no of bits per scan element supported
+ **/
+#define IIO_DEV_ATTR_BPSE_AVAILABLE(_show)				\
+	IIO_DEVICE_ATTR(bpse_available, S_IRUGO, _show, NULL, 0)
+
+/**
+ * IIO_DEV_ATTR_TEMP: many sensors have auxiliary temperature sensors
+ **/
+#define IIO_DEV_ATTR_TEMP(_show)			\
+	IIO_DEVICE_ATTR(temp, S_IRUGO, _show, NULL, 0)
+/**
+ * IIO_EVENT_SH: generic shared event handler
+ *
+ * This is used in cases where more than one event may result from a single
+ * handler.  Often the case that some alarm register must be read and multiple
+ * alarms may have been triggered.
+ **/
+#define IIO_EVENT_SH(_name, _handler)					\
+	static struct iio_event_handler_list				\
+	iio_event_##_name = {						\
+		.handler = _handler,					\
+		.refcount = 0,						\
+		.exist_lock = __MUTEX_INITIALIZER(iio_event_##_name	\
+						  .exist_lock),		\
+		.list = {						\
+			.next = &iio_event_##_name.list,		\
+			.prev = &iio_event_##_name.list,		\
+		},							\
+	};
+/**
+ * IIO_EVENT_ATTR_SH: generic shared event attribute
+ *
+ * An attribute with an associated IIO_EVENT_SH
+ **/
+#define IIO_EVENT_ATTR_SH(_name, _ev_list, _show, _store, _mask)	\
+	static struct iio_event_attr					\
+	iio_event_attr_##_name						\
+	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
+			       _show, _store),				\
+	    .mask = _mask,						\
+	    .listel = &_ev_list };
+
+/**
+ * IIO_EVENT_ATTR: non shared event attribute
+ **/
+#define IIO_EVENT_ATTR(_name, _show, _store, _mask, _handler)		\
+	static struct iio_event_handler_list				\
+	iio_event_##_name = {						\
+		.handler = _handler,					\
+	};								\
+	static struct							\
+	iio_event_attr							\
+	iio_event_attr_##_name						\
+	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
+			       _show, _store),				\
+	    .mask = _mask,						\
+	    .listel = &iio_event_##_name };				\
+
+/**
+ * IIO_EVENT_ATTR_DATA_RDY: event driven by data ready signal
+ *
+ * Not typically implemented in devices where full triggering support
+ * has been implemented
+ **/
+#define IIO_EVENT_ATTR_DATA_RDY(_show, _store, _mask, _handler) \
+	IIO_EVENT_ATTR(data_rdy, _show, _store, _mask, _handler)
+
+#define IIO_EVENT_CODE_DATA_RDY		100
+#define IIO_EVENT_CODE_RING_BASE	200
+#define IIO_EVENT_CODE_ACCEL_BASE	300
+#define IIO_EVENT_CODE_GYRO_BASE	400
+#define IIO_EVENT_CODE_ADC_BASE		500
+#define IIO_EVENT_CODE_MISC_BASE	600
+
+#define IIO_EVENT_CODE_DEVICE_SPECIFIC	1000
+
+/**
+ * IIO_EVENT_ATTR_RING_50_FULL: ring buffer event to indicate 50% full
+ **/
+#define IIO_EVENT_ATTR_RING_50_FULL(_show, _store, _mask, _handler)	\
+	IIO_EVENT_ATTR(ring_50_full, _show, _store, _mask, _handler)
+
+/**
+ * IIO_EVENT_ATTR_RING_50_FULL_SH: shared ring event to indicate 50% full
+ **/
+#define IIO_EVENT_ATTR_RING_50_FULL_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(ring_50_full, _evlist, _show, _store, _mask)
+
+/**
+ * IIO_EVENT_ATTR_RING_75_FULL_SH: shared ring event to indicate 75% full
+ **/
+#define IIO_EVENT_ATTR_RING_75_FULL_SH(_evlist, _show, _store, _mask)	\
+	IIO_EVENT_ATTR_SH(ring_75_full, _evlist, _show, _store, _mask)
+
+#define IIO_EVENT_CODE_RING_50_FULL	IIO_EVENT_CODE_RING_BASE
+#define IIO_EVENT_CODE_RING_75_FULL	(IIO_EVENT_CODE_RING_BASE + 1)
+#define IIO_EVENT_CODE_RING_100_FULL	(IIO_EVENT_CODE_RING_BASE + 2)
+
+#endif /* _INDUSTRIAL_IO_SYSFS_H_ */
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h
new file mode 100644
index 0000000..8284098
--- /dev/null
+++ b/drivers/staging/iio/trigger.h
@@ -0,0 +1,151 @@
+/* The industrial I/O core, trigger handling functions
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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 _IIO_TRIGGER_H_
+#define _IIO_TRIGGER_H_
+#define IIO_TRIGGER_NAME_LENGTH 20
+#define IIO_TRIGGER_ID_PREFIX "iio:trigger"
+#define IIO_TRIGGER_ID_FORMAT IIO_TRIGGER_ID_PREFIX "%d"
+
+
+/**
+ * struct iio_trigger - industrial I/O trigger device
+ *
+ * @id:			[INTERN] unique id number
+ * @name:		[DRIVER] unique name
+ * @dev:		[DRIVER] associated device (if relevant)
+ * @sysfs_dev:		[INTERN] sysfs relevant device
+ * @private_data:	[DRIVER] device specific data
+ * @list:		[INTERN] used in maintenance of global trigger list
+ * @alloc_list:		[DRIVER] used for driver specific trigger list
+ * @poll_func_list_lock:[INTERN] protection of the polling function list
+ * @pollfunc_list:	[INTERN] list of functions to run on trigger.
+ * @control_attrs:	[DRIVER] sysfs attributes relevant to trigger type
+ * @set_trigger_state:	[DRIVER] switch on/off the trigger on demand
+ * @timestamp:		[INTERN] timestamp usesd by some trigs (e.g. datardy)
+ * @owner:		[DRIVER] used to monitor usage count of the trigger.
+ **/
+struct iio_trigger {
+	int				id;
+	const char			*name;
+	struct device			dev;
+
+	void				*private_data;
+	struct list_head		list;
+	struct list_head		alloc_list;
+	spinlock_t			pollfunc_list_lock;
+	struct list_head		pollfunc_list;
+	const struct attribute_group	*control_attrs;
+	s64				timestamp;
+	struct module			*owner;
+	int use_count;
+
+	int (*set_trigger_state)(struct iio_trigger *trig, bool state);
+	int (*try_reenable)(struct iio_trigger *trig);
+};
+
+static inline struct iio_trigger *to_iio_trigger(struct device *d)
+{
+	return container_of(d, struct iio_trigger, dev);
+};
+
+static inline void iio_put_trigger(struct iio_trigger *trig)
+{
+	put_device(&trig->dev);
+	module_put(trig->owner);
+};
+
+static inline void iio_get_trigger(struct iio_trigger *trig)
+{
+	__module_get(trig->owner);
+	get_device(&trig->dev);
+};
+
+/**
+ * iio_trigger_read_name() - sysfs access function to get the trigger name
+ **/
+ssize_t iio_trigger_read_name(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf);
+
+#define IIO_TRIGGER_NAME_ATTR DEVICE_ATTR(name, S_IRUGO,		\
+					  iio_trigger_read_name,	\
+					  NULL);
+
+/**
+ * iio_trigger_find_by_name() - search global trigger list
+ **/
+struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len);
+
+/**
+ * iio_trigger_register() - register a trigger with the IIO core
+ * @trig_info:	trigger to be registered
+ **/
+int iio_trigger_register(struct iio_trigger *trig_info);
+
+/**
+ * iio_trigger_unregister() - unregister a trigger from the core
+ **/
+void iio_trigger_unregister(struct iio_trigger *trig_info);
+
+/**
+ * iio_trigger_attach_poll_func() - add a function pair to be run on trigger
+ * @trig:	trigger to which the function pair are being added
+ * @pf:	poll function pair
+ **/
+int iio_trigger_attach_poll_func(struct iio_trigger *trig,
+				 struct iio_poll_func *pf);
+
+/**
+ * iio_trigger_dettach_poll_func() -	remove function pair from those to be
+ *					run on trigger.
+ * @trig:	trigger from which the function is being removed.
+ * @pf:		poll function pair
+ **/
+int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
+				  struct iio_poll_func *pf);
+
+/**
+ * iio_trigger_poll() - called on a trigger occuring
+ * Typically called in relevant hardware interrupt handler.
+ **/
+void iio_trigger_poll(struct iio_trigger *);
+void iio_trigger_notify_done(struct iio_trigger *);
+
+/**
+ * struct iio_poll_func - poll function pair
+ *
+ * @list:			associate this with a triggers pollfunc_list
+ * @private_data:		data specific to device (passed into poll func)
+ * @poll_func_immediate:	function in here is run first. They should be
+ *				extremely lightweight.  Typically used for latch
+ *				control on sensor supporting it.
+ * @poll_func_main:		function in here is run after all immediates.
+ *				Reading from sensor etc typically involves
+ *				scheduling
+ *				from here.
+ *
+ * The two stage approach used here only important when multiple sensors are
+ * being triggered by a single trigger. This really comes into it's own with
+ * simultaneous sampling devices where a simple latch command can be used to
+ * make the device store the values on all inputs.
+ **/
+struct iio_poll_func {
+	struct				list_head list;
+	void				*private_data;
+	void (*poll_func_immediate)(struct iio_dev *indio_dev);
+	void (*poll_func_main)(struct iio_dev  *private_data);
+
+};
+
+struct iio_trigger *iio_allocate_trigger(void);
+
+void iio_free_trigger(struct iio_trigger *trig);
+
+
+#endif /* _IIO_TRIGGER_H_ */
diff --git a/drivers/staging/iio/trigger/Kconfig b/drivers/staging/iio/trigger/Kconfig
new file mode 100644
index 0000000..fdd9301
--- /dev/null
+++ b/drivers/staging/iio/trigger/Kconfig
@@ -0,0 +1,21 @@
+#
+# Industrial I/O standalone triggers
+#
+comment "Triggers - standalone"
+
+if IIO_TRIGGER
+
+config IIO_PERIODIC_RTC_TRIGGER
+	tristate "Periodic RTC triggers"
+	depends on RTC_CLASS
+	help
+	    Provides support for using periodic capable real time
+	    clocks as IIO triggers.
+
+config IIO_GPIO_TRIGGER
+	tristate "GPIO trigger"
+	depends on GENERIC_GPIO
+	help
+	    Provides support for using GPIO pins as IIO triggers.
+
+endif # IIO_TRIGGER
diff --git a/drivers/staging/iio/trigger/Makefile b/drivers/staging/iio/trigger/Makefile
new file mode 100644
index 0000000..e5f96d2
--- /dev/null
+++ b/drivers/staging/iio/trigger/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for triggers not associated with iio-devices
+#
+obj-$(CONFIG_IIO_PERIODIC_RTC_TRIGGER) += iio-trig-periodic-rtc.o
+obj-$(CONFIG_IIO_GPIO_TRIGGER) += iio-trig-gpio.o
\ No newline at end of file
diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c
new file mode 100644
index 0000000..539e416
--- /dev/null
+++ b/drivers/staging/iio/trigger/iio-trig-gpio.c
@@ -0,0 +1,202 @@
+/*
+ * Industrial I/O - gpio based trigger support
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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.
+ *
+ * Currently this is more of a functioning proof of concept that a fully
+ * fledged trigger driver.
+ *
+ * TODO:
+ *
+ * Add board config elements to allow specification of startup settings.
+ * Add configuration settings (irq type etc)
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include "../iio.h"
+#include "../trigger.h"
+
+LIST_HEAD(iio_gpio_trigger_list);
+DEFINE_MUTEX(iio_gpio_trigger_list_lock);
+
+struct iio_gpio_trigger_info {
+	struct mutex in_use;
+	int gpio;
+};
+/*
+ * Need to reference count these triggers and only enable gpio interrupts
+ * as appropriate.
+ */
+
+/* So what functionality do we want in here?... */
+/* set high / low as interrupt type? */
+
+static irqreturn_t iio_gpio_trigger_poll(int irq, void *private)
+{
+	iio_trigger_poll(private);
+	return IRQ_HANDLED;
+}
+
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+static struct attribute *iio_gpio_trigger_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+
+static const struct attribute_group iio_gpio_trigger_attr_group = {
+	.attrs = iio_gpio_trigger_attrs,
+};
+
+static int iio_gpio_trigger_probe(struct platform_device *dev)
+{
+	int *pdata = dev->dev.platform_data;
+	struct iio_gpio_trigger_info *trig_info;
+	struct iio_trigger *trig, *trig2;
+	int i, irq, ret = 0;
+	if (!pdata) {
+		printk(KERN_ERR "No IIO gpio trigger platform data found\n");
+		goto error_ret;
+	}
+	for (i = 0;; i++) {
+		if (!gpio_is_valid(pdata[i]))
+			break;
+		trig = iio_allocate_trigger();
+		if (!trig) {
+			ret = -ENOMEM;
+			goto error_free_completed_registrations;
+		}
+
+		trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
+		if (!trig_info) {
+			ret = -ENOMEM;
+			goto error_put_trigger;
+		}
+		trig->control_attrs = &iio_gpio_trigger_attr_group;
+		trig->private_data = trig_info;
+		trig_info->gpio = pdata[i];
+		trig->owner = THIS_MODULE;
+		trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+		if (!trig->name) {
+			ret = -ENOMEM;
+			goto error_free_trig_info;
+		}
+		snprintf((char *)trig->name,
+			 IIO_TRIGGER_NAME_LENGTH,
+			 "gpiotrig%d",
+			 pdata[i]);
+		ret = gpio_request(trig_info->gpio, trig->name);
+		if (ret)
+			goto error_free_name;
+
+		ret = gpio_direction_input(trig_info->gpio);
+		if (ret)
+			goto error_release_gpio;
+
+		irq = gpio_to_irq(trig_info->gpio);
+		if (irq < 0) {
+			ret = irq;
+			goto error_release_gpio;
+		}
+
+		ret = request_irq(irq, iio_gpio_trigger_poll,
+				  IRQF_TRIGGER_RISING,
+				  trig->name,
+				  trig);
+		if (ret)
+			goto error_release_gpio;
+
+		ret = iio_trigger_register(trig);
+		if (ret)
+			goto error_release_irq;
+
+		list_add_tail(&trig->alloc_list, &iio_gpio_trigger_list);
+
+	}
+	return 0;
+
+/* First clean up the partly allocated trigger */
+error_release_irq:
+	free_irq(irq, trig);
+error_release_gpio:
+	gpio_free(trig_info->gpio);
+error_free_name:
+	kfree(trig->name);
+error_free_trig_info:
+	kfree(trig_info);
+error_put_trigger:
+	iio_put_trigger(trig);
+error_free_completed_registrations:
+	/* The rest should have been added to the iio_gpio_trigger_list */
+	list_for_each_entry_safe(trig,
+				 trig2,
+				 &iio_gpio_trigger_list,
+				 alloc_list) {
+		trig_info = trig->private_data;
+		free_irq(gpio_to_irq(trig_info->gpio), trig);
+		gpio_free(trig_info->gpio);
+		kfree(trig->name);
+		kfree(trig_info);
+		iio_trigger_unregister(trig);
+	}
+
+error_ret:
+	return ret;
+}
+
+static int iio_gpio_trigger_remove(struct platform_device *dev)
+{
+	struct iio_trigger *trig, *trig2;
+	struct iio_gpio_trigger_info *trig_info;
+
+	mutex_lock(&iio_gpio_trigger_list_lock);
+	list_for_each_entry_safe(trig,
+				 trig2,
+				 &iio_gpio_trigger_list,
+				 alloc_list) {
+		trig_info = trig->private_data;
+		iio_trigger_unregister(trig);
+		free_irq(gpio_to_irq(trig_info->gpio), trig);
+		gpio_free(trig_info->gpio);
+		kfree(trig->name);
+		kfree(trig_info);
+		iio_put_trigger(trig);
+	}
+	mutex_unlock(&iio_gpio_trigger_list_lock);
+
+	return 0;
+}
+
+static struct platform_driver iio_gpio_trigger_driver = {
+	.probe = iio_gpio_trigger_probe,
+	.remove = iio_gpio_trigger_remove,
+	.driver = {
+		.name = "iio_gpio_trigger",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init iio_gpio_trig_init(void)
+{
+	return platform_driver_register(&iio_gpio_trigger_driver);
+}
+module_init(iio_gpio_trig_init);
+
+static void __exit iio_gpio_trig_exit(void)
+{
+	platform_driver_unregister(&iio_gpio_trigger_driver);
+}
+module_exit(iio_gpio_trig_exit);
+
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("Example gpio trigger for the iio subsystem");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
new file mode 100644
index 0000000..e310dc0
--- /dev/null
+++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
@@ -0,0 +1,228 @@
+/* The industrial I/O periodic RTC trigger driver
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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 is a heavily rewritten version of the periodic timer system in
+ * earlier version of industrialio.  It supplies the same functionality
+ * but via a trigger rather than a specific periodic timer system.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include "../iio.h"
+#include "../trigger.h"
+
+LIST_HEAD(iio_prtc_trigger_list);
+DEFINE_MUTEX(iio_prtc_trigger_list_lock);
+
+struct iio_prtc_trigger_info {
+	struct rtc_device *rtc;
+	int frequency;
+	char *name;
+	struct rtc_task task;
+};
+
+static int iio_trig_periodic_rtc_set_state(struct iio_trigger *trig, bool state)
+{
+	struct iio_prtc_trigger_info *trig_info = trig->private_data;
+	if (trig_info->frequency == 0)
+		return -EINVAL;
+	printk(KERN_INFO "trigger frequency is %d\n", trig_info->frequency);
+	return rtc_irq_set_state(trig_info->rtc, &trig_info->task, state);
+}
+
+static ssize_t iio_trig_periodic_read_freq(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct iio_trigger *trig = dev_get_drvdata(dev);
+	struct iio_prtc_trigger_info *trig_info = trig->private_data;
+	return sprintf(buf, "%u\n", trig_info->frequency);
+}
+
+static ssize_t iio_trig_periodic_write_freq(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf,
+					    size_t len)
+{
+	struct iio_trigger *trig = dev_get_drvdata(dev);
+	struct iio_prtc_trigger_info *trig_info = trig->private_data;
+	unsigned long val;
+	int ret;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+
+	ret = rtc_irq_set_freq(trig_info->rtc, &trig_info->task, val);
+	if (ret)
+		goto error_ret;
+
+	trig_info->frequency = val;
+
+	return len;
+
+error_ret:
+	return ret;
+}
+
+static ssize_t iio_trig_periodic_read_name(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct iio_trigger *trig = dev_get_drvdata(dev);
+	struct iio_prtc_trigger_info *trig_info = trig->private_data;
+	return sprintf(buf, "%s\n", trig_info->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO,
+	    iio_trig_periodic_read_name,
+	    NULL);
+static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR,
+	    iio_trig_periodic_read_freq,
+	    iio_trig_periodic_write_freq);
+
+static struct attribute *iio_trig_prtc_attrs[] = {
+	&dev_attr_frequency.attr,
+	&dev_attr_name.attr,
+	NULL,
+};
+static const struct attribute_group iio_trig_prtc_attr_group = {
+	.attrs = iio_trig_prtc_attrs,
+};
+
+static void iio_prtc_trigger_poll(void *private_data)
+{
+	iio_trigger_poll(private_data);
+}
+
+static int iio_trig_periodic_rtc_probe(struct platform_device *dev)
+{
+	char **pdata = dev->dev.platform_data;
+	struct iio_prtc_trigger_info *trig_info;
+	struct iio_trigger *trig, *trig2;
+
+	int i, ret;
+
+	for (i = 0;; i++) {
+		if (pdata[i] == NULL)
+			break;
+		trig = iio_allocate_trigger();
+		if (!trig) {
+			ret = -ENOMEM;
+			goto error_free_completed_registrations;
+		}
+		list_add(&trig->alloc_list, &iio_prtc_trigger_list);
+
+		trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL);
+		if (!trig_info) {
+			ret = -ENOMEM;
+			goto error_put_trigger_and_remove_from_list;
+		}
+		trig->private_data = trig_info;
+		trig->owner = THIS_MODULE;
+		trig->set_trigger_state = &iio_trig_periodic_rtc_set_state;
+		trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
+		if (trig->name == NULL) {
+			ret = -ENOMEM;
+			goto error_free_trig_info;
+		}
+		snprintf((char *)trig->name,
+			 IIO_TRIGGER_NAME_LENGTH,
+			 "periodic%s",
+			 pdata[i]);
+		trig_info->name = (char *)trig->name;
+		/* RTC access */
+		trig_info->rtc
+			= rtc_class_open(pdata[i]);
+		if (trig_info->rtc == NULL) {
+			ret = -EINVAL;
+			goto error_free_name;
+		}
+		trig_info->task.func = iio_prtc_trigger_poll;
+		trig_info->task.private_data = trig;
+		ret = rtc_irq_register(trig_info->rtc, &trig_info->task);
+		if (ret)
+			goto error_close_rtc;
+		trig->control_attrs = &iio_trig_prtc_attr_group;
+		ret = iio_trigger_register(trig);
+		if (ret)
+			goto error_unregister_rtc_irq;
+	}
+	return 0;
+error_unregister_rtc_irq:
+	rtc_irq_unregister(trig_info->rtc, &trig_info->task);
+error_close_rtc:
+	rtc_class_close(trig_info->rtc);
+error_free_name:
+	kfree(trig->name);
+error_free_trig_info:
+	kfree(trig_info);
+error_put_trigger_and_remove_from_list:
+	list_del(&trig->alloc_list);
+	iio_put_trigger(trig);
+error_free_completed_registrations:
+	list_for_each_entry_safe(trig,
+				 trig2,
+				 &iio_prtc_trigger_list,
+				 alloc_list) {
+		trig_info = trig->private_data;
+		rtc_irq_unregister(trig_info->rtc, &trig_info->task);
+		rtc_class_close(trig_info->rtc);
+		kfree(trig->name);
+		kfree(trig_info);
+		iio_trigger_unregister(trig);
+	}
+	return ret;
+}
+
+static int iio_trig_periodic_rtc_remove(struct platform_device *dev)
+{
+	struct iio_trigger *trig, *trig2;
+	struct iio_prtc_trigger_info *trig_info;
+	mutex_lock(&iio_prtc_trigger_list_lock);
+	list_for_each_entry_safe(trig,
+				 trig2,
+				 &iio_prtc_trigger_list,
+				 alloc_list) {
+		trig_info = trig->private_data;
+		rtc_irq_unregister(trig_info->rtc, &trig_info->task);
+		rtc_class_close(trig_info->rtc);
+		kfree(trig->name);
+		kfree(trig_info);
+		iio_trigger_unregister(trig);
+	}
+	mutex_unlock(&iio_prtc_trigger_list_lock);
+	return 0;
+}
+
+static struct platform_driver iio_trig_periodic_rtc_driver = {
+	.probe = iio_trig_periodic_rtc_probe,
+	.remove = iio_trig_periodic_rtc_remove,
+	.driver = {
+		.name = "iio_prtc_trigger",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init iio_trig_periodic_rtc_init(void)
+{
+	return platform_driver_register(&iio_trig_periodic_rtc_driver);
+}
+
+static void __exit iio_trig_periodic_rtc_exit(void)
+{
+	return platform_driver_unregister(&iio_trig_periodic_rtc_driver);
+}
+
+module_init(iio_trig_periodic_rtc_init);
+module_exit(iio_trig_periodic_rtc_exit);
+MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
+MODULE_DESCRIPTION("Periodic realtime clock  trigger for the iio subsystem");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h
new file mode 100644
index 0000000..4c7f527
--- /dev/null
+++ b/drivers/staging/iio/trigger_consumer.h
@@ -0,0 +1,45 @@
+
+/* The industrial I/O core, trigger consumer handling functions
+ *
+ * Copyright (c) 2008 Jonathan Cameron
+ *
+ * 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.
+ */
+
+#ifdef CONFIG_IIO_TRIGGER
+/**
+ * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers.
+ * @dev_info: iio_dev associated with the device that will consume the trigger
+ **/
+int iio_device_register_trigger_consumer(struct iio_dev *dev_info);
+/**
+ * iio_device_unregister_trigger_consumer() - reverse the registration process.
+ * @dev_info: iio_dev associated with the device that consumed the trigger
+ **/
+int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info);
+
+#else
+
+/**
+ * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers.
+ * @dev_info: iio_dev associated with the device that will consume the trigger
+ **/
+int iio_device_register_trigger_consumer(struct iio_dev *dev_info)
+{
+	return 0;
+};
+/**
+ * iio_device_unregister_trigger_consumer() - reverse the registration process
+ * @dev_info: iio_dev associated with the device that consumed the trigger
+ **/
+int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info)
+{
+	return 0;
+};
+
+#endif /* CONFIG_TRIGGER_CONSUMER */
+
+
+
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
index 8393e25..ea2060b 100644
--- a/drivers/staging/line6/capture.c
+++ b/drivers/staging/line6/capture.c
@@ -26,7 +26,7 @@
 */
 static int submit_audio_in_urb(struct snd_pcm_substream *substream)
 {
-	int index;
+	unsigned int index;
 	unsigned long flags;
 	struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
 	int i, urb_size;
@@ -35,7 +35,7 @@ static int submit_audio_in_urb(struct snd_pcm_substream *substream)
 	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) {
+	if (index >= LINE6_ISO_BUFFERS) {
 		spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
 		dev_err(s2m(substream), "no free URB found\n");
 		return -EINVAL;
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
index 85a20d0..f188ece 100644
--- a/drivers/staging/line6/driver.c
+++ b/drivers/staging/line6/driver.c
@@ -682,7 +682,7 @@ static int line6_probe(struct usb_interface *interface, const struct usb_device_
 		return -ENODEV;
 
 	/* check vendor and product id */
-	for (devtype = sizeof(line6_id_table) / sizeof(line6_id_table[0]) - 1; devtype--;)
+	for (devtype = ARRAY_SIZE(line6_id_table) - 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;
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
index fa5caa2..4c5b9d5 100644
--- a/drivers/staging/line6/pod.c
+++ b/drivers/staging/line6/pod.c
@@ -123,7 +123,7 @@ static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
 {
 	int i;
 
-	for (i = POD_CONTROL_SIZE; i--;)
+	for (i = 0; i < POD_CONTROL_SIZE; i++)
 		set_bit(i, pod->param_dirty);
 }
 
@@ -579,8 +579,8 @@ static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
 
 	if (count != sizeof(pod->prog_data)) {
 		dev_err(pod->line6.ifcdev,
-						"data block must be exactly %d bytes\n",
-						(int)sizeof(pod->prog_data));
+			"data block must be exactly %d bytes\n",
+			sizeof(pod->prog_data));
 		return -EINVAL;
 	}
 
@@ -692,7 +692,7 @@ static ssize_t pod_set_dump_buf(struct device *dev,
 	if (count != sizeof(pod->prog_data)) {
 		dev_err(pod->line6.ifcdev,
 						"data block must be exactly %d bytes\n",
-						(int)sizeof(pod->prog_data));
+						sizeof(pod->prog_data));
 		return -EINVAL;
 	}
 
diff --git a/drivers/staging/me4000/Kconfig b/drivers/staging/me4000/Kconfig
deleted file mode 100644
index 5e6c9de..0000000
--- a/drivers/staging/me4000/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config ME4000
-	tristate "Meilhaus ME-4000 support"
-	default n
-	depends on PCI
-	help
-	  This driver supports the Meilhaus ME-4000 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me4000.
diff --git a/drivers/staging/me4000/Makefile b/drivers/staging/me4000/Makefile
deleted file mode 100644
index 74487cd..0000000
--- a/drivers/staging/me4000/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_ME4000)		+= me4000.o
diff --git a/drivers/staging/me4000/README b/drivers/staging/me4000/README
deleted file mode 100644
index bbb8386..0000000
--- a/drivers/staging/me4000/README
+++ /dev/null
@@ -1,13 +0,0 @@
-
-TODO:
-	- checkpatch.pl cleanups
-	- sparse cleanups
-	- possible /proc interaction cleanups
-	- more info needed for Kconfig entry
-	- real device id?
-	- module parameter cleanup
-
-Please send patches to Greg Kroah-Hartman <gregkh@suse.de>
-and Cc: Wolfgang Beiter <w.beiter@aon.at> and
-Guenter Gebhardt <g.gebhardt@meilhaus.de>
-
diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c
deleted file mode 100644
index 01017b7..0000000
--- a/drivers/staging/me4000/me4000.c
+++ /dev/null
@@ -1,6109 +0,0 @@
-/* Device driver for Meilhaus ME-4000 board family.
- * ================================================
- *
- *  Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- *  This file is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Author:	Guenter Gebhardt	<g.gebhardt@meilhaus.de>
- */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/unistd.h>
-#include <linux/list.h>
-#include <linux/proc_fs.h>
-#include <linux/types.h>
-#include <linux/poll.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <asm/pgtable.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <asm/system.h>
-
-/* Include-File for the Meilhaus ME-4000 I/O board */
-#include "me4000.h"
-#include "me4000_firmware.h"
-#include "me4610_firmware.h"
-
-/* Administrative stuff for modinfo */
-MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
-MODULE_DESCRIPTION
-    ("Device Driver Module for Meilhaus ME-4000 boards version 1.0.5");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-4000 Multi I/O boards");
-MODULE_LICENSE("GPL");
-
-/* Board specific data are kept in a global list */
-static LIST_HEAD(me4000_board_info_list);
-
-/* Major Device Numbers. 0 means to get it automatically from the System */
-static int me4000_ao_major_driver_no;
-static int me4000_ai_major_driver_no;
-static int me4000_dio_major_driver_no;
-static int me4000_cnt_major_driver_no;
-static int me4000_ext_int_major_driver_no;
-
-/* Let the user specify a custom major driver number */
-module_param(me4000_ao_major_driver_no, int, 0);
-MODULE_PARM_DESC(me4000_ao_major_driver_no,
-		 "Major driver number for analog output (default 0)");
-
-module_param(me4000_ai_major_driver_no, int, 0);
-MODULE_PARM_DESC(me4000_ai_major_driver_no,
-		 "Major driver number for analog input (default 0)");
-
-module_param(me4000_dio_major_driver_no, int, 0);
-MODULE_PARM_DESC(me4000_dio_major_driver_no,
-		 "Major driver number digital I/O (default 0)");
-
-module_param(me4000_cnt_major_driver_no, int, 0);
-MODULE_PARM_DESC(me4000_cnt_major_driver_no,
-		 "Major driver number for counter (default 0)");
-
-module_param(me4000_ext_int_major_driver_no, int, 0);
-MODULE_PARM_DESC(me4000_ext_int_major_driver_no,
-		 "Major driver number for external interrupt (default 0)");
-
-/*-----------------------------------------------------------------------------
-  Board detection and initialization
-  ---------------------------------------------------------------------------*/
-static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id);
-static int me4000_xilinx_download(struct me4000_info *);
-static int me4000_reset_board(struct me4000_info *);
-
-static void clear_board_info_list(void);
-static void release_ao_contexts(struct me4000_info *board_info);
-/*-----------------------------------------------------------------------------
-  Stuff used by all device parts
-  ---------------------------------------------------------------------------*/
-static int me4000_open(struct inode *, struct file *);
-static int me4000_release(struct inode *, struct file *);
-
-static int me4000_get_user_info(struct me4000_user_info *,
-				struct me4000_info *board_info);
-static int me4000_read_procmem(char *, char **, off_t, int, int *, void *);
-
-/*-----------------------------------------------------------------------------
-  Analog output stuff
-  ---------------------------------------------------------------------------*/
-static ssize_t me4000_ao_write_sing(struct file *, const char *, size_t,
-				    loff_t *);
-static ssize_t me4000_ao_write_wrap(struct file *, const char *, size_t,
-				    loff_t *);
-static ssize_t me4000_ao_write_cont(struct file *, const char *, size_t,
-				    loff_t *);
-
-static int me4000_ao_ioctl_sing(struct inode *, struct file *, unsigned int,
-				unsigned long);
-static int me4000_ao_ioctl_wrap(struct inode *, struct file *, unsigned int,
-				unsigned long);
-static int me4000_ao_ioctl_cont(struct inode *, struct file *, unsigned int,
-				unsigned long);
-
-static unsigned int me4000_ao_poll_cont(struct file *, poll_table *);
-static int me4000_ao_fsync_cont(struct file *, struct dentry *, int);
-
-static int me4000_ao_start(unsigned long *, struct me4000_ao_context *);
-static int me4000_ao_stop(struct me4000_ao_context *);
-static int me4000_ao_immediate_stop(struct me4000_ao_context *);
-static int me4000_ao_timer_set_divisor(u32 *, struct me4000_ao_context *);
-static int me4000_ao_preload(struct me4000_ao_context *);
-static int me4000_ao_preload_update(struct me4000_ao_context *);
-static int me4000_ao_ex_trig_set_edge(int *, struct me4000_ao_context *);
-static int me4000_ao_ex_trig_enable(struct me4000_ao_context *);
-static int me4000_ao_ex_trig_disable(struct me4000_ao_context *);
-static int me4000_ao_prepare(struct me4000_ao_context *ao_info);
-static int me4000_ao_reset(struct me4000_ao_context *ao_info);
-static int me4000_ao_enable_do(struct me4000_ao_context *);
-static int me4000_ao_disable_do(struct me4000_ao_context *);
-static int me4000_ao_fsm_state(int *, struct me4000_ao_context *);
-
-static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context);
-static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context);
-static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context);
-static int me4000_ao_simultaneous_update(
-					struct me4000_ao_channel_list *channels,
-					struct me4000_ao_context *ao_context);
-
-static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context);
-static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context);
-static int me4000_ao_synchronous_disable(struct me4000_ao_context *ao_context);
-
-static int me4000_ao_ex_trig_timeout(unsigned long *arg,
-				     struct me4000_ao_context *ao_context);
-static int me4000_ao_get_free_buffer(unsigned long *arg,
-				     struct me4000_ao_context *ao_context);
-
-/*-----------------------------------------------------------------------------
-  Analog input stuff
-  ---------------------------------------------------------------------------*/
-static int me4000_ai_single(struct me4000_ai_single *,
-				struct me4000_ai_context *);
-static int me4000_ai_ioctl_sing(struct inode *, struct file *, unsigned int,
-				unsigned long);
-
-static ssize_t me4000_ai_read(struct file *, char *, size_t, loff_t *);
-static int me4000_ai_ioctl_sw(struct inode *, struct file *, unsigned int,
-			      unsigned long);
-static unsigned int me4000_ai_poll(struct file *, poll_table *);
-static int me4000_ai_fasync(int fd, struct file *file_p, int mode);
-
-static int me4000_ai_ioctl_ext(struct inode *, struct file *, unsigned int,
-			       unsigned long);
-
-static int me4000_ai_prepare(struct me4000_ai_context *ai_context);
-static int me4000_ai_reset(struct me4000_ai_context *ai_context);
-static int me4000_ai_config(struct me4000_ai_config *,
-				struct me4000_ai_context *);
-static int me4000_ai_start(struct me4000_ai_context *);
-static int me4000_ai_start_ex(unsigned long *, struct me4000_ai_context *);
-static int me4000_ai_stop(struct me4000_ai_context *);
-static int me4000_ai_immediate_stop(struct me4000_ai_context *);
-static int me4000_ai_ex_trig_enable(struct me4000_ai_context *);
-static int me4000_ai_ex_trig_disable(struct me4000_ai_context *);
-static int me4000_ai_ex_trig_setup(struct me4000_ai_trigger *,
-				   struct me4000_ai_context *);
-static int me4000_ai_sc_setup(struct me4000_ai_sc *arg,
-			      struct me4000_ai_context *ai_context);
-static int me4000_ai_offset_enable(struct me4000_ai_context *ai_context);
-static int me4000_ai_offset_disable(struct me4000_ai_context *ai_context);
-static int me4000_ai_fullscale_enable(struct me4000_ai_context *ai_context);
-static int me4000_ai_fullscale_disable(struct me4000_ai_context *ai_context);
-static int me4000_ai_fsm_state(int *arg, struct me4000_ai_context *ai_context);
-static int me4000_ai_get_count_buffer(unsigned long *arg,
-				      struct me4000_ai_context *ai_context);
-
-/*-----------------------------------------------------------------------------
-  EEPROM stuff
-  ---------------------------------------------------------------------------*/
-static int me4000_eeprom_read(struct me4000_eeprom *arg,
-			      struct me4000_ai_context *ai_context);
-static int me4000_eeprom_write(struct me4000_eeprom *arg,
-			       struct me4000_ai_context *ai_context);
-
-/*-----------------------------------------------------------------------------
-  Digital I/O stuff
-  ---------------------------------------------------------------------------*/
-static int me4000_dio_ioctl(struct inode *, struct file *, unsigned int,
-			    unsigned long);
-static int me4000_dio_config(struct me4000_dio_config *,
-				struct me4000_dio_context *);
-static int me4000_dio_get_byte(struct me4000_dio_byte *,
-				struct me4000_dio_context *);
-static int me4000_dio_set_byte(struct me4000_dio_byte *,
-				struct me4000_dio_context *);
-static int me4000_dio_reset(struct me4000_dio_context *);
-
-/*-----------------------------------------------------------------------------
-  Counter stuff
-  ---------------------------------------------------------------------------*/
-static int me4000_cnt_ioctl(struct inode *, struct file *, unsigned int,
-			    unsigned long);
-static int me4000_cnt_config(struct me4000_cnt_config *,
-				struct me4000_cnt_context *);
-static int me4000_cnt_read(struct me4000_cnt *, struct me4000_cnt_context *);
-static int me4000_cnt_write(struct me4000_cnt *, struct me4000_cnt_context *);
-static int me4000_cnt_reset(struct me4000_cnt_context *);
-
-/*-----------------------------------------------------------------------------
-  External interrupt routines
-  ---------------------------------------------------------------------------*/
-static int me4000_ext_int_ioctl(struct inode *, struct file *, unsigned int,
-				unsigned long);
-static int me4000_ext_int_enable(struct me4000_ext_int_context *);
-static int me4000_ext_int_disable(struct me4000_ext_int_context *);
-static int me4000_ext_int_count(unsigned long *arg,
-				struct me4000_ext_int_context *ext_int_context);
-static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode);
-
-/*-----------------------------------------------------------------------------
-  The interrupt service routines
-  ---------------------------------------------------------------------------*/
-static irqreturn_t me4000_ao_isr(int, void *);
-static irqreturn_t me4000_ai_isr(int, void *);
-static irqreturn_t me4000_ext_int_isr(int, void *);
-
-/*-----------------------------------------------------------------------------
-  Inline functions
-  ---------------------------------------------------------------------------*/
-
-static inline int me4000_buf_count(struct me4000_circ_buf buf, int size)
-{
-	return (buf.head - buf.tail) & (size - 1);
-}
-
-static inline int me4000_buf_space(struct me4000_circ_buf buf, int size)
-{
-	return (buf.tail - (buf.head + 1)) & (size - 1);
-}
-
-static inline int me4000_values_to_end(struct me4000_circ_buf buf, int size)
-{
-	int end;
-	int n;
-	end = size - buf.tail;
-	n = (buf.head + end) & (size - 1);
-	return (n < end) ? n : end;
-}
-
-static inline int me4000_space_to_end(struct me4000_circ_buf buf, int size)
-{
-	int end;
-	int n;
-
-	end = size - 1 - buf.head;
-	n = (end + buf.tail) & (size - 1);
-	return (n <= end) ? n : (end + 1);
-}
-
-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 inline void me4000_outl(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(unsigned long port)
-{
-	unsigned long value;
-	value = inl(port);
-	PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
-	return value;
-}
-
-static inline unsigned char me4000_inb(unsigned long port)
-{
-	unsigned char value;
-	value = inb(port);
-	PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
-	return value;
-}
-
-static struct pci_driver me4000_driver = {
-	.name = ME4000_NAME,
-	.id_table = me4000_pci_table,
-	.probe = me4000_probe
-};
-
-static const struct file_operations me4000_ao_fops_sing = {
-      .owner = THIS_MODULE,
-      .write = me4000_ao_write_sing,
-      .ioctl = me4000_ao_ioctl_sing,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_ao_fops_wrap = {
-      .owner = THIS_MODULE,
-      .write = me4000_ao_write_wrap,
-      .ioctl = me4000_ao_ioctl_wrap,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_ao_fops_cont = {
-      .owner = THIS_MODULE,
-      .write = me4000_ao_write_cont,
-      .poll = me4000_ao_poll_cont,
-      .ioctl = me4000_ao_ioctl_cont,
-      .open = me4000_open,
-      .release = me4000_release,
-      .fsync = me4000_ao_fsync_cont,
-};
-
-static const struct file_operations me4000_ai_fops_sing = {
-      .owner = THIS_MODULE,
-      .ioctl = me4000_ai_ioctl_sing,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_ai_fops_cont_sw = {
-      .owner = THIS_MODULE,
-      .read = me4000_ai_read,
-      .poll = me4000_ai_poll,
-      .ioctl = me4000_ai_ioctl_sw,
-      .open = me4000_open,
-      .release = me4000_release,
-      .fasync = me4000_ai_fasync,
-};
-
-static const struct file_operations me4000_ai_fops_cont_et = {
-      .owner = THIS_MODULE,
-      .read = me4000_ai_read,
-      .poll = me4000_ai_poll,
-      .ioctl = me4000_ai_ioctl_ext,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_ai_fops_cont_et_value = {
-      .owner = THIS_MODULE,
-      .read = me4000_ai_read,
-      .poll = me4000_ai_poll,
-      .ioctl = me4000_ai_ioctl_ext,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_ai_fops_cont_et_chanlist = {
-      .owner = THIS_MODULE,
-      .read = me4000_ai_read,
-      .poll = me4000_ai_poll,
-      .ioctl = me4000_ai_ioctl_ext,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_dio_fops = {
-      .owner = THIS_MODULE,
-      .ioctl = me4000_dio_ioctl,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_cnt_fops = {
-      .owner = THIS_MODULE,
-      .ioctl = me4000_cnt_ioctl,
-      .open = me4000_open,
-      .release = me4000_release,
-};
-
-static const struct file_operations me4000_ext_int_fops = {
-      .owner = THIS_MODULE,
-      .ioctl = me4000_ext_int_ioctl,
-      .open = me4000_open,
-      .release = me4000_release,
-      .fasync = me4000_ext_int_fasync,
-};
-
-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 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)
-{
-	int result;
-
-	CALL_PDEBUG("init_module() is executed\n");
-
-	/* Register driver capabilities */
-	result = pci_register_driver(&me4000_driver);
-	PDEBUG("init_module():%d devices detected\n", result);
-	if (result < 0) {
-		printk(KERN_ERR "ME4000:init_module():Can't register driver\n");
-		goto INIT_ERROR_1;
-	}
-
-	/* Allocate major number for analog output */
-	result =
-	    register_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME,
-			    &me4000_ao_fops_sing);
-	if (result < 0) {
-		printk(KERN_ERR "ME4000:init_module():Can't get AO major no\n");
-		goto INIT_ERROR_2;
-	} else {
-		me4000_ao_major_driver_no = result;
-	}
-	PDEBUG("init_module():Major driver number for AO = %ld\n",
-	       me4000_ao_major_driver_no);
-
-	/* Allocate major number for analog input  */
-	result =
-	    register_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME,
-			    &me4000_ai_fops_sing);
-	if (result < 0) {
-		printk(KERN_ERR "ME4000:init_module():Can't get AI major no\n");
-		goto INIT_ERROR_3;
-	} else {
-		me4000_ai_major_driver_no = result;
-	}
-	PDEBUG("init_module():Major driver number for AI = %ld\n",
-	       me4000_ai_major_driver_no);
-
-	/* Allocate major number for digital I/O */
-	result =
-	    register_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME,
-			    &me4000_dio_fops);
-	if (result < 0) {
-		printk(KERN_ERR
-		       "ME4000:init_module():Can't get DIO major no\n");
-		goto INIT_ERROR_4;
-	} else {
-		me4000_dio_major_driver_no = result;
-	}
-	PDEBUG("init_module():Major driver number for DIO = %ld\n",
-	       me4000_dio_major_driver_no);
-
-	/* Allocate major number for counter */
-	result =
-	    register_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME,
-			    &me4000_cnt_fops);
-	if (result < 0) {
-		printk(KERN_ERR
-		       "ME4000:init_module():Can't get CNT major no\n");
-		goto INIT_ERROR_5;
-	} else {
-		me4000_cnt_major_driver_no = result;
-	}
-	PDEBUG("init_module():Major driver number for CNT = %ld\n",
-	       me4000_cnt_major_driver_no);
-
-	/* Allocate major number for external interrupt */
-	result =
-	    register_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME,
-			    &me4000_ext_int_fops);
-	if (result < 0) {
-		printk(KERN_ERR
-		       "ME4000:init_module():Can't get major no for external interrupt\n");
-		goto INIT_ERROR_6;
-	} else {
-		me4000_ext_int_major_driver_no = result;
-	}
-	PDEBUG
-	    ("init_module():Major driver number for external interrupt = %ld\n",
-	     me4000_ext_int_major_driver_no);
-
-	/* Create the /proc/me4000 entry */
-	if (!create_proc_read_entry
-	    ("me4000", 0, NULL, me4000_read_procmem, NULL)) {
-		result = -ENODEV;
-		printk(KERN_ERR
-		       "ME4000:init_module():Can't create proc entry\n");
-		goto INIT_ERROR_7;
-	}
-
-	return 0;
-
-INIT_ERROR_7:
-	unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME);
-
-INIT_ERROR_6:
-	unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME);
-
-INIT_ERROR_5:
-	unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME);
-
-INIT_ERROR_4:
-	unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME);
-
-INIT_ERROR_3:
-	unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME);
-
-INIT_ERROR_2:
-	pci_unregister_driver(&me4000_driver);
-	clear_board_info_list();
-
-INIT_ERROR_1:
-	return result;
-}
-
-module_init(me4000_init_module);
-
-static void clear_board_info_list(void)
-{
-	struct me4000_info *board_info, *board_info_safe;
-	struct me4000_ao_context *ao_context, *ao_context_safe;
-
-	/* Clear context lists */
-	list_for_each_entry(board_info, &me4000_board_info_list, list) {
-		/* Clear analog output context list */
-		list_for_each_entry_safe(ao_context, ao_context_safe,
-				&board_info->ao_context_list, list) {
-			me4000_ao_reset(ao_context);
-			free_irq(ao_context->irq, ao_context);
-			kfree(ao_context->circ_buf.buf);
-			list_del(&ao_context->list);
-			kfree(ao_context);
-		}
-
-		/* Clear analog input context */
-		kfree(board_info->ai_context->circ_buf.buf);
-		kfree(board_info->ai_context);
-
-		/* Clear digital I/O context */
-		kfree(board_info->dio_context);
-
-		/* Clear counter context */
-		kfree(board_info->cnt_context);
-
-		/* Clear external interrupt context */
-		kfree(board_info->ext_int_context);
-	}
-
-	/* Clear the board info list */
-	list_for_each_entry_safe(board_info, board_info_safe,
-			&me4000_board_info_list, list) {
-		pci_release_regions(board_info->pci_dev_p);
-		list_del(&board_info->list);
-		kfree(board_info);
-	}
-}
-
-static int get_registers(struct pci_dev *dev, struct me4000_info *board_info)
-{
-
-	/*--------------------------- plx regbase ---------------------------------*/
-
-	board_info->plx_regbase = pci_resource_start(dev, 1);
-	if (board_info->plx_regbase == 0) {
-		printk(KERN_ERR
-		       "ME4000:get_registers():PCI base address 1 is not available\n");
-		return -ENODEV;
-	}
-	board_info->plx_regbase_size = pci_resource_len(dev, 1);
-
-	PDEBUG
-	    ("get_registers():PLX configuration registers at address 0x%4lX [0x%4lX]\n",
-	     board_info->plx_regbase, board_info->plx_regbase_size);
-
-	/*--------------------------- me4000 regbase ------------------------------*/
-
-	board_info->me4000_regbase = pci_resource_start(dev, 2);
-	if (board_info->me4000_regbase == 0) {
-		printk(KERN_ERR
-		       "ME4000:get_registers():PCI base address 2 is not available\n");
-		return -ENODEV;
-	}
-	board_info->me4000_regbase_size = pci_resource_len(dev, 2);
-
-	PDEBUG("get_registers():ME4000 registers at address 0x%4lX [0x%4lX]\n",
-	       board_info->me4000_regbase, board_info->me4000_regbase_size);
-
-	/*--------------------------- timer regbase ------------------------------*/
-
-	board_info->timer_regbase = pci_resource_start(dev, 3);
-	if (board_info->timer_regbase == 0) {
-		printk(KERN_ERR
-		       "ME4000:get_registers():PCI base address 3 is not available\n");
-		return -ENODEV;
-	}
-	board_info->timer_regbase_size = pci_resource_len(dev, 3);
-
-	PDEBUG("get_registers():Timer registers at address 0x%4lX [0x%4lX]\n",
-	       board_info->timer_regbase, board_info->timer_regbase_size);
-
-	/*--------------------------- program regbase ------------------------------*/
-
-	board_info->program_regbase = pci_resource_start(dev, 5);
-	if (board_info->program_regbase == 0) {
-		printk(KERN_ERR
-		       "get_registers():ME4000:PCI base address 5 is not available\n");
-		return -ENODEV;
-	}
-	board_info->program_regbase_size = pci_resource_len(dev, 5);
-
-	PDEBUG("get_registers():Program registers at address 0x%4lX [0x%4lX]\n",
-	       board_info->program_regbase, board_info->program_regbase_size);
-
-	return 0;
-}
-
-static int init_board_info(struct pci_dev *pci_dev_p,
-			   struct me4000_info *board_info)
-{
-	int i;
-	int result;
-	struct list_head *board_p;
-	board_info->pci_dev_p = pci_dev_p;
-
-	for (i = 0; i < ARRAY_SIZE(me4000_boards); i++) {
-		if (me4000_boards[i].device_id == pci_dev_p->device) {
-			board_info->board_p = &me4000_boards[i];
-			break;
-		}
-	}
-	if (i == ARRAY_SIZE(me4000_boards)) {
-		printk(KERN_ERR
-		       "ME4000:init_board_info():Device ID not valid\n");
-		return -ENODEV;
-	}
-
-	/* Get the index of the board in the global list */
-	i = 0;
-	list_for_each(board_p, &me4000_board_info_list) {
-		if (board_p == &board_info->list) {
-			board_info->board_count = i;
-			break;
-		}
-		i++;
-	}
-	if (board_p == &me4000_board_info_list) {
-		printk(KERN_ERR
-		       "ME4000:init_board_info():Cannot get index of board\n");
-		return -ENODEV;
-	}
-
-	/* Init list head for analog output contexts */
-	INIT_LIST_HEAD(&board_info->ao_context_list);
-
-	/* Init spin locks */
-	spin_lock_init(&board_info->preload_lock);
-	spin_lock_init(&board_info->ai_ctrl_lock);
-
-	/* Get the serial number */
-	result = pci_read_config_dword(pci_dev_p, 0x2C, &board_info->serial_no);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		printk(KERN_WARNING
-		       "ME4000:init_board_info: Can't get serial_no\n");
-		return result;
-	}
-	PDEBUG("init_board_info():serial_no = 0x%x\n", board_info->serial_no);
-
-	/* Get the hardware revision */
-	result =
-	    pci_read_config_byte(pci_dev_p, 0x08, &board_info->hw_revision);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		printk(KERN_WARNING
-		       "ME4000:init_board_info():Can't get hw_revision\n");
-		return result;
-	}
-	PDEBUG("init_board_info():hw_revision = 0x%x\n",
-	       board_info->hw_revision);
-
-	/* Get the vendor id */
-	board_info->vendor_id = pci_dev_p->vendor;
-	PDEBUG("init_board_info():vendor_id = 0x%x\n", board_info->vendor_id);
-
-	/* Get the device id */
-	board_info->device_id = pci_dev_p->device;
-	PDEBUG("init_board_info():device_id = 0x%x\n", board_info->device_id);
-
-	/* Get the pci device number */
-	board_info->pci_dev_no = PCI_FUNC(pci_dev_p->devfn);
-	PDEBUG("init_board_info():pci_func_no = 0x%x\n",
-	       board_info->pci_func_no);
-
-	/* Get the pci slot number */
-	board_info->pci_dev_no = PCI_SLOT(pci_dev_p->devfn);
-	PDEBUG("init_board_info():pci_dev_no = 0x%x\n", board_info->pci_dev_no);
-
-	/* Get the pci bus number */
-	board_info->pci_bus_no = pci_dev_p->bus->number;
-	PDEBUG("init_board_info():pci_bus_no = 0x%x\n", board_info->pci_bus_no);
-
-	/* Get the irq assigned to the board */
-	board_info->irq = pci_dev_p->irq;
-	PDEBUG("init_board_info():irq = %d\n", board_info->irq);
-
-	return 0;
-}
-
-static int alloc_ao_contexts(struct me4000_info *info)
-{
-	int i;
-	int err;
-	struct me4000_ao_context *ao_context;
-
-	for (i = 0; i < info->board_p->ao.count; i++) {
-		ao_context = kzalloc(sizeof(struct me4000_ao_context),
-								GFP_KERNEL);
-		if (!ao_context) {
-			printk(KERN_ERR
-			       "alloc_ao_contexts():Can't get memory for ao context\n");
-			release_ao_contexts(info);
-			return -ENOMEM;
-		}
-
-		spin_lock_init(&ao_context->use_lock);
-		spin_lock_init(&ao_context->int_lock);
-		ao_context->irq = info->irq;
-		init_waitqueue_head(&ao_context->wait_queue);
-		ao_context->board_info = info;
-
-		if (info->board_p->ao.fifo_count) {
-			/* Allocate circular buffer */
-			ao_context->circ_buf.buf =
-			    kzalloc(ME4000_AO_BUFFER_SIZE, GFP_KERNEL);
-			if (!ao_context->circ_buf.buf) {
-				printk(KERN_ERR
-				       "alloc_ao_contexts():Can't get circular buffer\n");
-				release_ao_contexts(info);
-				return -ENOMEM;
-			}
-
-			/* Clear the circular buffer */
-			ao_context->circ_buf.head = 0;
-			ao_context->circ_buf.tail = 0;
-		}
-
-		switch (i) {
-		case 0:
-			ao_context->ctrl_reg =
-			    info->me4000_regbase + ME4000_AO_00_CTRL_REG;
-			ao_context->status_reg =
-			    info->me4000_regbase + ME4000_AO_00_STATUS_REG;
-			ao_context->fifo_reg =
-			    info->me4000_regbase + ME4000_AO_00_FIFO_REG;
-			ao_context->single_reg =
-			    info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
-			ao_context->timer_reg =
-			    info->me4000_regbase + ME4000_AO_00_TIMER_REG;
-			ao_context->irq_status_reg =
-			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-			ao_context->preload_reg =
-			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-			break;
-		case 1:
-			ao_context->ctrl_reg =
-			    info->me4000_regbase + ME4000_AO_01_CTRL_REG;
-			ao_context->status_reg =
-			    info->me4000_regbase + ME4000_AO_01_STATUS_REG;
-			ao_context->fifo_reg =
-			    info->me4000_regbase + ME4000_AO_01_FIFO_REG;
-			ao_context->single_reg =
-			    info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
-			ao_context->timer_reg =
-			    info->me4000_regbase + ME4000_AO_01_TIMER_REG;
-			ao_context->irq_status_reg =
-			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-			ao_context->preload_reg =
-			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-			break;
-		case 2:
-			ao_context->ctrl_reg =
-			    info->me4000_regbase + ME4000_AO_02_CTRL_REG;
-			ao_context->status_reg =
-			    info->me4000_regbase + ME4000_AO_02_STATUS_REG;
-			ao_context->fifo_reg =
-			    info->me4000_regbase + ME4000_AO_02_FIFO_REG;
-			ao_context->single_reg =
-			    info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
-			ao_context->timer_reg =
-			    info->me4000_regbase + ME4000_AO_02_TIMER_REG;
-			ao_context->irq_status_reg =
-			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-			ao_context->preload_reg =
-			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-			break;
-		case 3:
-			ao_context->ctrl_reg =
-			    info->me4000_regbase + ME4000_AO_03_CTRL_REG;
-			ao_context->status_reg =
-			    info->me4000_regbase + ME4000_AO_03_STATUS_REG;
-			ao_context->fifo_reg =
-			    info->me4000_regbase + ME4000_AO_03_FIFO_REG;
-			ao_context->single_reg =
-			    info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
-			ao_context->timer_reg =
-			    info->me4000_regbase + ME4000_AO_03_TIMER_REG;
-			ao_context->irq_status_reg =
-			    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-			ao_context->preload_reg =
-			    info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
-			break;
-		default:
-			break;
-		}
-
-		if (info->board_p->ao.fifo_count) {
-			/* Request the interrupt line */
-			err =
-			    request_irq(ao_context->irq, me4000_ao_isr,
-					IRQF_DISABLED | IRQF_SHARED,
-					ME4000_NAME, ao_context);
-			if (err) {
-				printk(KERN_ERR
-				       "%s:Can't get interrupt line", __func__);
-				kfree(ao_context->circ_buf.buf);
-				kfree(ao_context);
-				release_ao_contexts(info);
-				return -ENODEV;
-			}
-		}
-
-		list_add_tail(&ao_context->list, &info->ao_context_list);
-		ao_context->index = i;
-	}
-
-	return 0;
-}
-
-static void release_ao_contexts(struct me4000_info *board_info)
-{
-	struct me4000_ao_context *ao_context, *ao_context_safe;
-
-	/* Clear analog output context list */
-	list_for_each_entry_safe(ao_context, ao_context_safe,
-			&board_info->ao_context_list, list) {
-		free_irq(ao_context->irq, ao_context);
-		kfree(ao_context->circ_buf.buf);
-		list_del(&ao_context->list);
-		kfree(ao_context);
-	}
-}
-
-static int alloc_ai_context(struct me4000_info *info)
-{
-	struct me4000_ai_context *ai_context;
-
-	if (info->board_p->ai.count) {
-		ai_context = kzalloc(sizeof(struct me4000_ai_context),
-								GFP_KERNEL);
-		if (!ai_context) {
-			printk(KERN_ERR
-			       "ME4000:alloc_ai_context():Can't get memory for ai context\n");
-			return -ENOMEM;
-		}
-
-		info->ai_context = ai_context;
-
-		spin_lock_init(&ai_context->use_lock);
-		spin_lock_init(&ai_context->int_lock);
-		ai_context->number = 0;
-		ai_context->irq = info->irq;
-		init_waitqueue_head(&ai_context->wait_queue);
-		ai_context->board_info = info;
-
-		ai_context->ctrl_reg =
-		    info->me4000_regbase + ME4000_AI_CTRL_REG;
-		ai_context->status_reg =
-		    info->me4000_regbase + ME4000_AI_STATUS_REG;
-		ai_context->channel_list_reg =
-		    info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
-		ai_context->data_reg =
-		    info->me4000_regbase + ME4000_AI_DATA_REG;
-		ai_context->chan_timer_reg =
-		    info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
-		ai_context->chan_pre_timer_reg =
-		    info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
-		ai_context->scan_timer_low_reg =
-		    info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
-		ai_context->scan_timer_high_reg =
-		    info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
-		ai_context->scan_pre_timer_low_reg =
-		    info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
-		ai_context->scan_pre_timer_high_reg =
-		    info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
-		ai_context->start_reg =
-		    info->me4000_regbase + ME4000_AI_START_REG;
-		ai_context->irq_status_reg =
-		    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-		ai_context->sample_counter_reg =
-		    info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
-	}
-
-	return 0;
-}
-
-static int alloc_dio_context(struct me4000_info *info)
-{
-	struct me4000_dio_context *dio_context;
-
-	if (info->board_p->dio.count) {
-		dio_context = kzalloc(sizeof(struct me4000_dio_context),
-								GFP_KERNEL);
-		if (!dio_context) {
-			printk(KERN_ERR
-			       "ME4000:alloc_dio_context():Can't get memory for dio context\n");
-			return -ENOMEM;
-		}
-
-		info->dio_context = dio_context;
-
-		spin_lock_init(&dio_context->use_lock);
-		dio_context->board_info = info;
-
-		dio_context->dio_count = info->board_p->dio.count;
-
-		dio_context->dir_reg =
-		    info->me4000_regbase + ME4000_DIO_DIR_REG;
-		dio_context->ctrl_reg =
-		    info->me4000_regbase + ME4000_DIO_CTRL_REG;
-		dio_context->port_0_reg =
-		    info->me4000_regbase + ME4000_DIO_PORT_0_REG;
-		dio_context->port_1_reg =
-		    info->me4000_regbase + ME4000_DIO_PORT_1_REG;
-		dio_context->port_2_reg =
-		    info->me4000_regbase + ME4000_DIO_PORT_2_REG;
-		dio_context->port_3_reg =
-		    info->me4000_regbase + ME4000_DIO_PORT_3_REG;
-	}
-
-	return 0;
-}
-
-static int alloc_cnt_context(struct me4000_info *info)
-{
-	struct me4000_cnt_context *cnt_context;
-
-	if (info->board_p->cnt.count) {
-		cnt_context = kzalloc(sizeof(struct me4000_cnt_context),
-								GFP_KERNEL);
-		if (!cnt_context) {
-			printk(KERN_ERR
-			       "ME4000:alloc_cnt_context():Can't get memory for cnt context\n");
-			return -ENOMEM;
-		}
-
-		info->cnt_context = cnt_context;
-
-		spin_lock_init(&cnt_context->use_lock);
-		cnt_context->board_info = info;
-
-		cnt_context->ctrl_reg =
-		    info->timer_regbase + ME4000_CNT_CTRL_REG;
-		cnt_context->counter_0_reg =
-		    info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
-		cnt_context->counter_1_reg =
-		    info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
-		cnt_context->counter_2_reg =
-		    info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
-	}
-
-	return 0;
-}
-
-static int alloc_ext_int_context(struct me4000_info *info)
-{
-	struct me4000_ext_int_context *ext_int_context;
-
-	if (info->board_p->cnt.count) {
-		ext_int_context =
-		    kzalloc(sizeof(struct me4000_ext_int_context), GFP_KERNEL);
-		if (!ext_int_context) {
-			printk(KERN_ERR
-			       "ME4000:alloc_ext_int_context():Can't get memory for cnt context\n");
-			return -ENOMEM;
-		}
-
-		info->ext_int_context = ext_int_context;
-
-		spin_lock_init(&ext_int_context->use_lock);
-		ext_int_context->board_info = info;
-
-		ext_int_context->fasync_ptr = NULL;
-		ext_int_context->irq = info->irq;
-
-		ext_int_context->ctrl_reg =
-		    info->me4000_regbase + ME4000_AI_CTRL_REG;
-		ext_int_context->irq_status_reg =
-		    info->me4000_regbase + ME4000_IRQ_STATUS_REG;
-	}
-
-	return 0;
-}
-
-static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int result = 0;
-	struct me4000_info *board_info;
-
-	CALL_PDEBUG("me4000_probe() is executed\n");
-
-	/* Allocate structure for board context */
-	board_info = kzalloc(sizeof(struct me4000_info), GFP_KERNEL);
-	if (!board_info) {
-		printk(KERN_ERR
-		       "ME4000:Can't get memory for board info structure\n");
-		result = -ENOMEM;
-		goto PROBE_ERROR_1;
-	}
-
-	/* Add to global linked list */
-	list_add_tail(&board_info->list, &me4000_board_info_list);
-
-	/* Get the PCI base registers */
-	result = get_registers(dev, board_info);
-	if (result) {
-		printk(KERN_ERR "%s:Cannot get registers\n", __func__);
-		goto PROBE_ERROR_2;
-	}
-
-	/* Enable the device */
-	result = pci_enable_device(dev);
-	if (result < 0) {
-		printk(KERN_ERR "%s:Cannot enable PCI device\n", __func__);
-		goto PROBE_ERROR_2;
-	}
-
-	/* Request the PCI register regions */
-	result = pci_request_regions(dev, ME4000_NAME);
-	if (result < 0) {
-		printk(KERN_ERR "%s:Cannot request I/O regions\n", __func__);
-		goto PROBE_ERROR_2;
-	}
-
-	/* Initialize board info */
-	result = init_board_info(dev, board_info);
-	if (result) {
-		printk(KERN_ERR "%s:Cannot init baord info\n", __func__);
-		goto PROBE_ERROR_3;
-	}
-
-	/* Download the xilinx firmware */
-	result = me4000_xilinx_download(board_info);
-	if (result) {
-		printk(KERN_ERR "%s:Can't download firmware\n", __func__);
-		goto PROBE_ERROR_3;
-	}
-
-	/* Make a hardware reset */
-	result = me4000_reset_board(board_info);
-	if (result) {
-		printk(KERN_ERR "%s :Can't reset board\n", __func__);
-		goto PROBE_ERROR_3;
-	}
-
-	/* Allocate analog output context structures */
-	result = alloc_ao_contexts(board_info);
-	if (result) {
-		printk(KERN_ERR "%s:Cannot allocate ao contexts\n", __func__);
-		goto PROBE_ERROR_3;
-	}
-
-	/* Allocate analog input context */
-	result = alloc_ai_context(board_info);
-	if (result) {
-		printk(KERN_ERR "%s:Cannot allocate ai context\n", __func__);
-		goto PROBE_ERROR_4;
-	}
-
-	/* Allocate digital I/O context */
-	result = alloc_dio_context(board_info);
-	if (result) {
-		printk(KERN_ERR "%s:Cannot allocate dio context\n", __func__);
-		goto PROBE_ERROR_5;
-	}
-
-	/* Allocate counter context */
-	result = alloc_cnt_context(board_info);
-	if (result) {
-		printk(KERN_ERR "%s:Cannot allocate cnt context\n", __func__);
-		goto PROBE_ERROR_6;
-	}
-
-	/* Allocate external interrupt context */
-	result = alloc_ext_int_context(board_info);
-	if (result) {
-		printk(KERN_ERR
-		       "%s:Cannot allocate ext_int context\n", __func__);
-		goto PROBE_ERROR_7;
-	}
-
-	return 0;
-
-PROBE_ERROR_7:
-	kfree(board_info->cnt_context);
-
-PROBE_ERROR_6:
-	kfree(board_info->dio_context);
-
-PROBE_ERROR_5:
-	kfree(board_info->ai_context);
-
-PROBE_ERROR_4:
-	release_ao_contexts(board_info);
-
-PROBE_ERROR_3:
-	pci_release_regions(dev);
-
-PROBE_ERROR_2:
-	list_del(&board_info->list);
-	kfree(board_info);
-
-PROBE_ERROR_1:
-	return result;
-}
-
-static int me4000_xilinx_download(struct me4000_info *info)
-{
-	int size = 0;
-	u32 value = 0;
-	int idx = 0;
-	unsigned char *firm;
-	wait_queue_head_t queue;
-
-	CALL_PDEBUG("me4000_xilinx_download() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	firm = (info->device_id == 0x4610) ? xilinx_firm_4610 : xilinx_firm;
-
-	/*
-	 * Set PLX local interrupt 2 polarity to high.
-	 * Interrupt is thrown by init pin of xilinx.
-	 */
-	outl(0x10, info->plx_regbase + PLX_INTCSR);
-
-	/* Set /CS and /WRITE of the Xilinx */
-	value = inl(info->plx_regbase + PLX_ICR);
-	value |= 0x100;
-	outl(value, info->plx_regbase + PLX_ICR);
-
-	/* Init Xilinx with CS1 */
-	inb(info->program_regbase + 0xC8);
-
-	/* Wait until /INIT pin is set */
-	udelay(20);
-	if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
-		printk(KERN_ERR "%s:Can't init Xilinx\n", __func__);
-		return -EIO;
-	}
-
-	/* Reset /CS and /WRITE of the Xilinx */
-	value = inl(info->plx_regbase + PLX_ICR);
-	value &= ~0x100;
-	outl(value, info->plx_regbase + PLX_ICR);
-
-	/* Download Xilinx firmware */
-	size = (firm[0] << 24) + (firm[1] << 16) + (firm[2] << 8) + firm[3];
-	udelay(10);
-
-	for (idx = 0; idx < size; idx++) {
-		outb(firm[16 + idx], info->program_regbase);
-
-		udelay(10);
-
-		/* Check if BUSY flag is low */
-		if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
-			printk(KERN_ERR
-			       "%s:Xilinx is still busy (idx = %d)\n", __func__,
-			       idx);
-			return -EIO;
-		}
-	}
-
-	PDEBUG("me4000_xilinx_download():%d bytes written\n", idx);
-
-	/* If done flag is high download was successful */
-	if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
-		PDEBUG("me4000_xilinx_download():Done flag is set\n");
-		PDEBUG("me4000_xilinx_download():Download was successful\n");
-	} else {
-		printk(KERN_ERR
-		       "ME4000:%s:DONE flag is not set\n", __func__);
-		printk(KERN_ERR
-		       "ME4000:%s:Download not succesful\n", __func__);
-		return -EIO;
-	}
-
-	/* Set /CS and /WRITE */
-	value = inl(info->plx_regbase + PLX_ICR);
-	value |= 0x100;
-	outl(value, info->plx_regbase + PLX_ICR);
-
-	return 0;
-}
-
-static int me4000_reset_board(struct me4000_info *info)
-{
-	unsigned long icr;
-
-	CALL_PDEBUG("me4000_reset_board() is executed\n");
-
-	/* Make a hardware reset */
-	icr = me4000_inl(info->plx_regbase + PLX_ICR);
-	icr |= 0x40000000;
-	me4000_outl(icr, info->plx_regbase + PLX_ICR);
-	icr &= ~0x40000000;
-	me4000_outl(icr, info->plx_regbase + PLX_ICR);
-
-	/* Set both stop bits in the analog input control register */
-	me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
-		    info->me4000_regbase + ME4000_AI_CTRL_REG);
-
-	/* Set both stop bits in the analog output control register */
-	me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		    info->me4000_regbase + ME4000_AO_00_CTRL_REG);
-	me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		    info->me4000_regbase + ME4000_AO_01_CTRL_REG);
-	me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		    info->me4000_regbase + ME4000_AO_02_CTRL_REG);
-	me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
-		    info->me4000_regbase + ME4000_AO_03_CTRL_REG);
-
-	/* 0x8000 to the DACs means an output voltage of 0V */
-	me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
-	me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
-	me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
-	me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
-
-	/* Enable interrupts on the PLX */
-	me4000_outl(0x43, info->plx_regbase + PLX_INTCSR);
-
-	/* Set the adustment register for AO demux */
-	me4000_outl(ME4000_AO_DEMUX_ADJUST_VALUE,
-		    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))
-		me4000_outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
-
-	return 0;
-}
-
-static int me4000_open(struct inode *inode_p, struct file *file_p)
-{
-	int board, dev, mode;
-	int err = 0;
-	int i;
-	struct list_head *ptr;
-	struct me4000_info *board_info = NULL;
-	struct me4000_ao_context *ao_context = NULL;
-	struct me4000_ai_context *ai_context = NULL;
-	struct me4000_dio_context *dio_context = NULL;
-	struct me4000_cnt_context *cnt_context = NULL;
-	struct me4000_ext_int_context *ext_int_context = NULL;
-
-	CALL_PDEBUG("me4000_open() is executed\n");
-
-	/* Analog output */
-	if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) {
-		board = AO_BOARD(inode_p->i_rdev);
-		dev = AO_PORT(inode_p->i_rdev);
-		mode = AO_MODE(inode_p->i_rdev);
-
-		PDEBUG("me4000_open():board = %d ao = %d mode = %d\n", board,
-		       dev, mode);
-
-		/* Search for the board context */
-		i = 0;
-		list_for_each(ptr, &me4000_board_info_list) {
-			if (i == board)
-				break;
-			i++;
-		}
-		board_info = list_entry(ptr, struct me4000_info, list);
-
-		if (ptr == &me4000_board_info_list) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Board %d not in device list\n",
-			       board);
-			return -ENODEV;
-		}
-
-		/* Search for the dac context */
-		i = 0;
-		list_for_each(ptr, &board_info->ao_context_list) {
-			if (i == dev)
-				break;
-			i++;
-		}
-		ao_context = list_entry(ptr, struct me4000_ao_context, list);
-
-		if (ptr == &board_info->ao_context_list) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Device %d not in device list\n",
-			       dev);
-			return -ENODEV;
-		}
-
-		/* Check if mode is valid */
-		if (mode > 2) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Mode is not valid\n");
-			return -ENODEV;
-		}
-
-		/* Check if mode is valid for this AO */
-		if ((mode != ME4000_AO_CONV_MODE_SINGLE)
-		    && (dev >= board_info->board_p->ao.fifo_count)) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():AO %d only in single mode available\n",
-			       dev);
-			return -ENODEV;
-		}
-
-		/* Check if already opened */
-		spin_lock(&ao_context->use_lock);
-		if (ao_context->dac_in_use) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():AO %d already in use\n",
-			       dev);
-			spin_unlock(&ao_context->use_lock);
-			return -EBUSY;
-		}
-		ao_context->dac_in_use = 1;
-		spin_unlock(&ao_context->use_lock);
-
-		ao_context->mode = mode;
-
-		/* Hold the context in private data */
-		file_p->private_data = ao_context;
-
-		/* Set file operations pointer */
-		file_p->f_op = me4000_ao_fops_array[mode];
-
-		err = me4000_ao_prepare(ao_context);
-		if (err) {
-			ao_context->dac_in_use = 0;
-			return 1;
-		}
-	}
-	/* Analog input */
-	else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) {
-		board = AI_BOARD(inode_p->i_rdev);
-		mode = AI_MODE(inode_p->i_rdev);
-
-		PDEBUG("me4000_open():ai board = %d mode = %d\n", board, mode);
-
-		/* Search for the board context */
-		i = 0;
-		list_for_each(ptr, &me4000_board_info_list) {
-			if (i == board)
-				break;
-			i++;
-		}
-		board_info = list_entry(ptr, struct me4000_info, list);
-
-		if (ptr == &me4000_board_info_list) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Board %d not in device list\n",
-			       board);
-			return -ENODEV;
-		}
-
-		ai_context = board_info->ai_context;
-
-		/* Check if mode is valid */
-		if (mode > 5) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Mode is not valid\n");
-			return -EINVAL;
-		}
-
-		/* Check if already opened */
-		spin_lock(&ai_context->use_lock);
-		if (ai_context->in_use) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():AI already in use\n");
-			spin_unlock(&ai_context->use_lock);
-			return -EBUSY;
-		}
-		ai_context->in_use = 1;
-		spin_unlock(&ai_context->use_lock);
-
-		ai_context->mode = mode;
-
-		/* Hold the context in private data */
-		file_p->private_data = ai_context;
-
-		/* Set file operations pointer */
-		file_p->f_op = me4000_ai_fops_array[mode];
-
-		/* Prepare analog input */
-		me4000_ai_prepare(ai_context);
-	}
-	/* Digital I/O */
-	else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) {
-		board = DIO_BOARD(inode_p->i_rdev);
-		dev = 0;
-		mode = 0;
-
-		PDEBUG("me4000_open():board = %d\n", board);
-
-		/* Search for the board context */
-		list_for_each_entry(board_info, &me4000_board_info_list, list) {
-			if (board_info->board_count == board)
-				break;
-		}
-
-		if (&board_info->list == &me4000_board_info_list) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Board %d not in device list\n",
-			       board);
-			return -ENODEV;
-		}
-
-		/* Search for the dio context */
-		dio_context = board_info->dio_context;
-
-		/* Check if already opened */
-		spin_lock(&dio_context->use_lock);
-		if (dio_context->in_use) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():DIO already in use\n");
-			spin_unlock(&dio_context->use_lock);
-			return -EBUSY;
-		}
-		dio_context->in_use = 1;
-		spin_unlock(&dio_context->use_lock);
-
-		/* Hold the context in private data */
-		file_p->private_data = dio_context;
-
-		/* Set file operations pointer to single functions */
-		file_p->f_op = &me4000_dio_fops;
-
-		/* me4000_dio_reset(dio_context); */
-	}
-	/* Counters */
-	else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
-		board = CNT_BOARD(inode_p->i_rdev);
-		dev = 0;
-		mode = 0;
-
-		PDEBUG("me4000_open():board = %d\n", board);
-
-		/* Search for the board context */
-		list_for_each_entry(board_info, &me4000_board_info_list, list) {
-			if (board_info->board_count == board)
-				break;
-		}
-
-		if (&board_info->list == &me4000_board_info_list) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Board %d not in device list\n",
-			       board);
-			return -ENODEV;
-		}
-
-		/* Get the cnt context */
-		cnt_context = board_info->cnt_context;
-
-		/* Check if already opened */
-		spin_lock(&cnt_context->use_lock);
-		if (cnt_context->in_use) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():CNT already in use\n");
-			spin_unlock(&cnt_context->use_lock);
-			return -EBUSY;
-		}
-		cnt_context->in_use = 1;
-		spin_unlock(&cnt_context->use_lock);
-
-		/* Hold the context in private data */
-		file_p->private_data = cnt_context;
-
-		/* Set file operations pointer to single functions */
-		file_p->f_op = &me4000_cnt_fops;
-	}
-	/* External Interrupt */
-	else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) {
-		board = EXT_INT_BOARD(inode_p->i_rdev);
-		dev = 0;
-		mode = 0;
-
-		PDEBUG("me4000_open():board = %d\n", board);
-
-		/* Search for the board context */
-		list_for_each_entry(board_info, &me4000_board_info_list, list) {
-			if (board_info->board_count == board)
-				break;
-		}
-
-		if (&board_info->list == &me4000_board_info_list) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Board %d not in device list\n",
-			       board);
-			return -ENODEV;
-		}
-
-		/* Get the external interrupt context */
-		ext_int_context = board_info->ext_int_context;
-
-		/* Check if already opened */
-		spin_lock(&cnt_context->use_lock);
-		if (ext_int_context->in_use) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():External interrupt already in use\n");
-			spin_unlock(&ext_int_context->use_lock);
-			return -EBUSY;
-		}
-		ext_int_context->in_use = 1;
-		spin_unlock(&ext_int_context->use_lock);
-
-		/* Hold the context in private data */
-		file_p->private_data = ext_int_context;
-
-		/* Set file operations pointer to single functions */
-		file_p->f_op = &me4000_ext_int_fops;
-
-		/* Request the interrupt line */
-		err =
-		    request_irq(ext_int_context->irq, me4000_ext_int_isr,
-				IRQF_DISABLED | IRQF_SHARED, ME4000_NAME,
-				ext_int_context);
-		if (err) {
-			printk(KERN_ERR
-			       "ME4000:me4000_open():Can't get interrupt line");
-			ext_int_context->in_use = 0;
-			return -ENODEV;
-		}
-
-		/* Reset the counter */
-		me4000_ext_int_disable(ext_int_context);
-	} else {
-		printk(KERN_ERR "ME4000:me4000_open():Major number unknown\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int me4000_release(struct inode *inode_p, struct file *file_p)
-{
-	struct me4000_ao_context *ao_context;
-	struct me4000_ai_context *ai_context;
-	struct me4000_dio_context *dio_context;
-	struct me4000_cnt_context *cnt_context;
-	struct me4000_ext_int_context *ext_int_context;
-
-	CALL_PDEBUG("me4000_release() is executed\n");
-
-	if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) {
-		ao_context = file_p->private_data;
-
-		/* Mark DAC as unused */
-		ao_context->dac_in_use = 0;
-	} else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) {
-		ai_context = file_p->private_data;
-
-		/* Reset the analog input */
-		me4000_ai_reset(ai_context);
-
-		/* Free the interrupt and the circular buffer */
-		if (ai_context->mode) {
-			free_irq(ai_context->irq, ai_context);
-			kfree(ai_context->circ_buf.buf);
-			ai_context->circ_buf.buf = NULL;
-			ai_context->circ_buf.head = 0;
-			ai_context->circ_buf.tail = 0;
-		}
-
-		/* Mark AI as unused */
-		ai_context->in_use = 0;
-	} else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) {
-		dio_context = file_p->private_data;
-
-		/* Mark digital I/O as unused */
-		dio_context->in_use = 0;
-	} else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
-		cnt_context = file_p->private_data;
-
-		/* Mark counters as unused */
-		cnt_context->in_use = 0;
-	} else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) {
-		ext_int_context = file_p->private_data;
-
-		/* Disable the externel interrupt */
-		me4000_ext_int_disable(ext_int_context);
-
-		free_irq(ext_int_context->irq, ext_int_context);
-
-		/* Mark as unused */
-		ext_int_context->in_use = 0;
-	} else {
-		printk(KERN_ERR
-		       "ME4000:me4000_release():Major number unknown\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*------------------------------- Analog output stuff --------------------------------------*/
-
-static int me4000_ao_prepare(struct me4000_ao_context *ao_context)
-{
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_prepare() is executed\n");
-
-	if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) {
-		/* Only do anything if not already in the correct mode */
-		unsigned long mode = me4000_inl(ao_context->ctrl_reg);
-		if ((mode & ME4000_AO_CONV_MODE_CONTINUOUS)
-		    && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) {
-			return 0;
-		}
-
-		/* Stop any conversion */
-		me4000_ao_immediate_stop(ao_context);
-
-		/* Set the control register to default state  */
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS |
-			    ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-			    ME4000_AO_CTRL_BIT_STOP |
-			    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-			    ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-		/* Set to fastest sample rate */
-		me4000_outl(65, ao_context->timer_reg);
-	} else if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) {
-		/* Only do anything if not already in the correct mode */
-		unsigned long mode = me4000_inl(ao_context->ctrl_reg);
-		if ((mode & ME4000_AO_CONV_MODE_WRAPAROUND)
-		    && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) {
-			return 0;
-		}
-
-		/* Stop any conversion */
-		me4000_ao_immediate_stop(ao_context);
-
-		/* Set the control register to default state  */
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND |
-			    ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-			    ME4000_AO_CTRL_BIT_STOP |
-			    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-			    ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-		/* Set to fastest sample rate */
-		me4000_outl(65, ao_context->timer_reg);
-	} else if (ao_context->mode == ME4000_AO_CONV_MODE_SINGLE) {
-		/* Only do anything if not already in the correct mode */
-		unsigned long mode = me4000_inl(ao_context->ctrl_reg);
-		if (!
-		    (mode &
-		     (ME4000_AO_CONV_MODE_WRAPAROUND |
-		      ME4000_AO_CONV_MODE_CONTINUOUS))) {
-			return 0;
-		}
-
-		/* Stop any conversion */
-		me4000_ao_immediate_stop(ao_context);
-
-		/* Clear the control register */
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		me4000_outl(0x0, ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-		/* Set voltage to 0V */
-		me4000_outl(0x8000, ao_context->single_reg);
-	} else {
-		printk(KERN_ERR
-		       "ME4000:me4000_ao_prepare():Invalid mode specified\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int me4000_ao_reset(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	wait_queue_head_t queue;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_reset() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) {
-		/*
-		 * First stop conversion of the DAC before reconfigure.
-		 * This is essantial, cause of the state machine.
-		 * If not stopped before configuring mode, it could
-		 * walk in a undefined state.
-		 */
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
-		me4000_outl(tmp, ao_context->ctrl_reg);
-
-		wait_event_timeout(queue,
-			(inl(ao_context->status_reg) &
-				ME4000_AO_STATUS_BIT_FSM) == 0,
-			1);
-
-		/* Set to transparent mode */
-		me4000_ao_simultaneous_disable(ao_context);
-
-		/* Set to single mode in order to set default voltage */
-		me4000_outl(0x0, ao_context->ctrl_reg);
-
-		/* Set voltage to 0V */
-		me4000_outl(0x8000, ao_context->single_reg);
-
-		/* Set to fastest sample rate */
-		me4000_outl(65, ao_context->timer_reg);
-
-		/* Set the original mode and enable FIFO */
-		me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND |
-			    ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-			    ME4000_AO_CTRL_BIT_STOP |
-			    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-			    ao_context->ctrl_reg);
-	} else if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) {
-		/*
-		 * First stop conversion of the DAC before reconfigure.
-		 * This is essantial, cause of the state machine.
-		 * If not stopped before configuring mode, it could
-		 * walk in a undefined state.
-		 */
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		tmp |= ME4000_AO_CTRL_BIT_STOP;
-		me4000_outl(tmp, ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-		wait_event_timeout(queue,
-			(inl(ao_context->status_reg) &
-				ME4000_AO_STATUS_BIT_FSM) == 0,
-			1);
-
-		/* Clear the circular buffer */
-		ao_context->circ_buf.head = 0;
-		ao_context->circ_buf.tail = 0;
-
-		/* Set to transparent mode */
-		me4000_ao_simultaneous_disable(ao_context);
-
-		/* Set to single mode in order to set default voltage */
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		me4000_outl(0x0, ao_context->ctrl_reg);
-
-		/* Set voltage to 0V */
-		me4000_outl(0x8000, ao_context->single_reg);
-
-		/* Set to fastest sample rate */
-		me4000_outl(65, ao_context->timer_reg);
-
-		/* Set the original mode and enable FIFO */
-		me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS |
-			    ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-			    ME4000_AO_CTRL_BIT_STOP |
-			    ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
-			    ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-	} else {
-		/* Set to transparent mode */
-		me4000_ao_simultaneous_disable(ao_context);
-
-		/* Set voltage to 0V */
-		me4000_outl(0x8000, ao_context->single_reg);
-	}
-
-	return 0;
-}
-
-static ssize_t me4000_ao_write_sing(struct file *filep, const char *buff,
-				    size_t cnt, loff_t *offp)
-{
-	struct me4000_ao_context *ao_context = filep->private_data;
-	u32 value;
-	const u16 *buffer = (const u16 *)buff;
-
-	CALL_PDEBUG("me4000_ao_write_sing() is executed\n");
-
-	if (cnt != 2) {
-		printk(KERN_ERR
-		       "%s:Write count is not 2\n", __func__);
-		return -EINVAL;
-	}
-
-	if (get_user(value, buffer)) {
-		printk(KERN_ERR
-		       "%s:Cannot copy data from user\n", __func__);
-		return -EFAULT;
-	}
-
-	me4000_outl(value, ao_context->single_reg);
-
-	return 2;
-}
-
-static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff,
-				    size_t cnt, loff_t *offp)
-{
-	struct me4000_ao_context *ao_context = filep->private_data;
-	size_t i;
-	u32 value;
-	u32 tmp;
-	const u16 *buffer = (const u16 *)buff;
-	size_t count = cnt / 2;
-
-	CALL_PDEBUG("me4000_ao_write_wrap() is executed\n");
-
-	/* Check if a conversion is already running */
-	if (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "%s:There is already a conversion running\n", __func__);
-		return -EBUSY;
-	}
-
-	if (count > ME4000_AO_FIFO_COUNT) {
-		printk(KERN_ERR
-		       "%s:Can't load more than %d values\n", __func__,
-		       ME4000_AO_FIFO_COUNT);
-		return -ENOSPC;
-	}
-
-	/* Reset the FIFO */
-	tmp = inl(ao_context->ctrl_reg);
-	tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_FIFO;
-	outl(tmp, ao_context->ctrl_reg);
-	tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO;
-	outl(tmp, ao_context->ctrl_reg);
-
-	for (i = 0; i < count; i++) {
-		if (get_user(value, buffer + i)) {
-			printk(KERN_ERR
-			       "%s:Cannot copy data from user\n", __func__);
-			return -EFAULT;
-		}
-		if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG)
-		    || ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG))
-			value = value << 16;
-		outl(value, ao_context->fifo_reg);
-	}
-	CALL_PDEBUG("me4000_ao_write_wrap() is leaved with %d\n", i * 2);
-
-	return i * 2;
-}
-
-static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
-				    size_t cnt, loff_t *offp)
-{
-	struct me4000_ao_context *ao_context = filep->private_data;
-	const u16 *buffer = (const u16 *)buff;
-	size_t count = cnt / 2;
-	unsigned long flags;
-	u32 tmp;
-	int c = 0;
-	int k = 0;
-	int ret = 0;
-	u16 svalue;
-	u32 lvalue;
-	int i;
-	wait_queue_head_t queue;
-
-	CALL_PDEBUG("me4000_ao_write_cont() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	/* Check count */
-	if (count <= 0) {
-		PDEBUG("me4000_ao_write_cont():Count is 0\n");
-		return 0;
-	}
-
-	if (filep->f_flags & O_APPEND) {
-		PDEBUG("me4000_ao_write_cont():Append data to data stream\n");
-		while (count > 0) {
-			if (filep->f_flags & O_NONBLOCK) {
-				if (ao_context->pipe_flag) {
-					printk(KERN_ERR
-					       "ME4000:me4000_ao_write_cont():Broken pipe in nonblocking write\n");
-					return -EPIPE;
-				}
-				c = me4000_space_to_end(ao_context->circ_buf,
-							ME4000_AO_BUFFER_COUNT);
-				if (!c) {
-					PDEBUG
-					    ("me4000_ao_write_cont():Returning from nonblocking write\n");
-					break;
-				}
-			} else {
-				wait_event_interruptible(ao_context->wait_queue,
-							 (c =
-							  me4000_space_to_end
-							  (ao_context->circ_buf,
-							   ME4000_AO_BUFFER_COUNT)));
-				if (ao_context->pipe_flag) {
-					printk(KERN_ERR
-					       "me4000_ao_write_cont():Broken pipe in blocking write\n");
-					return -EPIPE;
-				}
-				if (signal_pending(current)) {
-					printk(KERN_ERR
-					       "me4000_ao_write_cont():Wait for free buffer interrupted from signal\n");
-					return -EINTR;
-				}
-			}
-
-			PDEBUG("me4000_ao_write_cont():Space to end = %d\n", c);
-
-			/* Only able to write size of free buffer or size of count */
-			if (count < c)
-				c = count;
-
-			k = 2 * c;
-			k -= copy_from_user(ao_context->circ_buf.buf +
-					    ao_context->circ_buf.head, buffer,
-					    k);
-			c = k / 2;
-			PDEBUG
-			    ("me4000_ao_write_cont():Copy %d values from user space\n",
-			     c);
-
-			if (!c)
-				return -EFAULT;
-
-			ao_context->circ_buf.head =
-			    (ao_context->circ_buf.head +
-			     c) & (ME4000_AO_BUFFER_COUNT - 1);
-			buffer += c;
-			count -= c;
-			ret += c;
-
-			/* Values are now available so enable interrupts */
-			spin_lock_irqsave(&ao_context->int_lock, flags);
-			if (me4000_buf_count
-			    (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
-				tmp = me4000_inl(ao_context->ctrl_reg);
-				tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ;
-				me4000_outl(tmp, ao_context->ctrl_reg);
-			}
-			spin_unlock_irqrestore(&ao_context->int_lock, flags);
-		}
-
-		/* Wait until the state machine is stopped if O_SYNC is set */
-		if (filep->f_flags & O_SYNC) {
-			while (inl(ao_context->status_reg) &
-			       ME4000_AO_STATUS_BIT_FSM) {
-				interruptible_sleep_on_timeout(&queue, 1);
-				if (ao_context->pipe_flag) {
-					PDEBUG
-					    ("me4000_ao_write_cont():Broken pipe detected after sync\n");
-					return -EPIPE;
-				}
-				if (signal_pending(current)) {
-					printk(KERN_ERR
-					       "me4000_ao_write_cont():Wait on state machine after sync interrupted\n");
-					return -EINTR;
-				}
-			}
-		}
-	} else {
-		PDEBUG("me4000_ao_write_cont():Preload DAC FIFO\n");
-		if ((me4000_inl(ao_context->status_reg) &
-		     ME4000_AO_STATUS_BIT_FSM)) {
-			printk(KERN_ERR
-			       "me4000_ao_write_cont():Can't Preload DAC FIFO while conversion is running\n");
-			return -EBUSY;
-		}
-
-		/* Clear the FIFO */
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		tmp &=
-		    ~(ME4000_AO_CTRL_BIT_ENABLE_FIFO |
-		      ME4000_AO_CTRL_BIT_ENABLE_IRQ);
-		me4000_outl(tmp, ao_context->ctrl_reg);
-		tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO;
-		me4000_outl(tmp, ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-		/* Clear the circular buffer */
-		ao_context->circ_buf.head = 0;
-		ao_context->circ_buf.tail = 0;
-
-		/* Reset the broken pipe flag */
-		ao_context->pipe_flag = 0;
-
-		/* Only able to write size of fifo or count */
-		c = ME4000_AO_FIFO_COUNT;
-		if (count < c)
-			c = count;
-
-		PDEBUG
-		    ("me4000_ao_write_cont():Write %d values to DAC on 0x%lX\n",
-		     c, ao_context->fifo_reg);
-
-		/* Write values to the fifo */
-		for (i = 0; i < c; i++) {
-			if (get_user(svalue, buffer))
-				return -EFAULT;
-
-			if (((ao_context->fifo_reg & 0xFF) ==
-			     ME4000_AO_01_FIFO_REG)
-			    || ((ao_context->fifo_reg & 0xFF) ==
-				ME4000_AO_03_FIFO_REG)) {
-				lvalue = ((u32) svalue) << 16;
-			} else
-				lvalue = (u32) svalue;
-
-			outl(lvalue, ao_context->fifo_reg);
-			buffer++;
-		}
-		count -= c;
-		ret += c;
-
-		while (1) {
-			/* Get free buffer */
-			c = me4000_space_to_end(ao_context->circ_buf,
-						ME4000_AO_BUFFER_COUNT);
-
-			if (c == 0)
-				return 2 * ret;
-
-			/* Only able to write size of free buffer or size of count */
-			if (count < c)
-				c = count;
-
-			/* If count = 0 return to user */
-			if (c <= 0) {
-				PDEBUG
-				    ("me4000_ao_write_cont():Count reached 0\n");
-				break;
-			}
-
-			k = 2 * c;
-			k -= copy_from_user(ao_context->circ_buf.buf +
-					    ao_context->circ_buf.head, buffer,
-					    k);
-			c = k / 2;
-			PDEBUG
-			    ("me4000_ao_write_cont():Wrote %d values to buffer\n",
-			     c);
-
-			if (!c)
-				return -EFAULT;
-
-			ao_context->circ_buf.head =
-			    (ao_context->circ_buf.head +
-			     c) & (ME4000_AO_BUFFER_COUNT - 1);
-			buffer += c;
-			count -= c;
-			ret += c;
-
-			/* If values in the buffer are available so enable interrupts */
-			spin_lock_irqsave(&ao_context->int_lock, flags);
-			if (me4000_buf_count
-			    (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
-				PDEBUG
-				    ("me4000_ao_write_cont():Enable Interrupts\n");
-				tmp = me4000_inl(ao_context->ctrl_reg);
-				tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ;
-				me4000_outl(tmp, ao_context->ctrl_reg);
-			}
-			spin_unlock_irqrestore(&ao_context->int_lock, flags);
-		}
-	}
-
-	if (filep->f_flags & O_NONBLOCK)
-		return (ret == 0) ? -EAGAIN : 2 * ret;
-
-	return 2 * ret;
-}
-
-static unsigned int me4000_ao_poll_cont(struct file *file_p, poll_table *wait)
-{
-	struct me4000_ao_context *ao_context;
-	unsigned long mask = 0;
-
-	CALL_PDEBUG("me4000_ao_poll_cont() is executed\n");
-
-	ao_context = file_p->private_data;
-
-	poll_wait(file_p, &ao_context->wait_queue, wait);
-
-	/* Get free buffer */
-	if (me4000_space_to_end(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT))
-		mask |= POLLOUT | POLLWRNORM;
-
-	CALL_PDEBUG("me4000_ao_poll_cont():Return mask %lX\n", mask);
-
-	return mask;
-}
-
-static int me4000_ao_fsync_cont(struct file *file_p, struct dentry *dentry_p,
-				int datasync)
-{
-	struct me4000_ao_context *ao_context;
-	wait_queue_head_t queue;
-
-	CALL_PDEBUG("me4000_ao_fsync_cont() is executed\n");
-
-	ao_context = file_p->private_data;
-	init_waitqueue_head(&queue);
-
-	while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-		interruptible_sleep_on_timeout(&queue, 1);
-			wait_event_interruptible_timeout(queue,
-			!(inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM),
-			1);
-		if (ao_context->pipe_flag) {
-			printk(KERN_ERR
-			       "%s:Broken pipe detected\n", __func__);
-			return -EPIPE;
-		}
-
-		if (signal_pending(current)) {
-			printk(KERN_ERR
-			       "%s:Wait on state machine interrupted\n",
-			       __func__);
-			return -EINTR;
-		}
-	}
-
-	return 0;
-}
-
-static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
-				unsigned int service, unsigned long arg)
-{
-	struct me4000_ao_context *ao_context;
-
-	CALL_PDEBUG("me4000_ao_ioctl_sing() is executed\n");
-
-	ao_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		return -ENOTTY;
-		PDEBUG("me4000_ao_ioctl_sing():Wrong magic number\n");
-	}
-
-	switch (service) {
-	case ME4000_AO_EX_TRIG_SETUP:
-		return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
-	case ME4000_AO_EX_TRIG_ENABLE:
-		return me4000_ao_ex_trig_enable(ao_context);
-	case ME4000_AO_EX_TRIG_DISABLE:
-		return me4000_ao_ex_trig_disable(ao_context);
-	case ME4000_AO_PRELOAD:
-		return me4000_ao_preload(ao_context);
-	case ME4000_AO_PRELOAD_UPDATE:
-		return me4000_ao_preload_update(ao_context);
-	case ME4000_GET_USER_INFO:
-		return me4000_get_user_info((struct me4000_user_info *)arg,
-					    ao_context->board_info);
-	case ME4000_AO_SIMULTANEOUS_EX_TRIG:
-		return me4000_ao_simultaneous_ex_trig(ao_context);
-	case ME4000_AO_SIMULTANEOUS_SW:
-		return me4000_ao_simultaneous_sw(ao_context);
-	case ME4000_AO_SIMULTANEOUS_DISABLE:
-		return me4000_ao_simultaneous_disable(ao_context);
-	case ME4000_AO_SIMULTANEOUS_UPDATE:
-		return
-		    me4000_ao_simultaneous_update(
-				(struct me4000_ao_channel_list *)arg,
-				ao_context);
-	case ME4000_AO_EX_TRIG_TIMEOUT:
-		return me4000_ao_ex_trig_timeout((unsigned long *)arg,
-						 ao_context);
-	case ME4000_AO_DISABLE_DO:
-		return me4000_ao_disable_do(ao_context);
-	default:
-		printk(KERN_ERR
-		       "me4000_ao_ioctl_sing():Service number invalid\n");
-		return -ENOTTY;
-	}
-
-	return 0;
-}
-
-static int me4000_ao_ioctl_wrap(struct inode *inode_p, struct file *file_p,
-				unsigned int service, unsigned long arg)
-{
-	struct me4000_ao_context *ao_context;
-
-	CALL_PDEBUG("me4000_ao_ioctl_wrap() is executed\n");
-
-	ao_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		return -ENOTTY;
-		PDEBUG("me4000_ao_ioctl_wrap():Wrong magic number\n");
-	}
-
-	switch (service) {
-	case ME4000_AO_START:
-		return me4000_ao_start((unsigned long *)arg, ao_context);
-	case ME4000_AO_STOP:
-		return me4000_ao_stop(ao_context);
-	case ME4000_AO_IMMEDIATE_STOP:
-		return me4000_ao_immediate_stop(ao_context);
-	case ME4000_AO_RESET:
-		return me4000_ao_reset(ao_context);
-	case ME4000_AO_TIMER_SET_DIVISOR:
-		return me4000_ao_timer_set_divisor((u32 *) arg, ao_context);
-	case ME4000_AO_EX_TRIG_SETUP:
-		return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
-	case ME4000_AO_EX_TRIG_ENABLE:
-		return me4000_ao_ex_trig_enable(ao_context);
-	case ME4000_AO_EX_TRIG_DISABLE:
-		return me4000_ao_ex_trig_disable(ao_context);
-	case ME4000_GET_USER_INFO:
-		return me4000_get_user_info((struct me4000_user_info *)arg,
-					    ao_context->board_info);
-	case ME4000_AO_FSM_STATE:
-		return me4000_ao_fsm_state((int *)arg, ao_context);
-	case ME4000_AO_ENABLE_DO:
-		return me4000_ao_enable_do(ao_context);
-	case ME4000_AO_DISABLE_DO:
-		return me4000_ao_disable_do(ao_context);
-	case ME4000_AO_SYNCHRONOUS_EX_TRIG:
-		return me4000_ao_synchronous_ex_trig(ao_context);
-	case ME4000_AO_SYNCHRONOUS_SW:
-		return me4000_ao_synchronous_sw(ao_context);
-	case ME4000_AO_SYNCHRONOUS_DISABLE:
-		return me4000_ao_synchronous_disable(ao_context);
-	default:
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_ao_ioctl_cont(struct inode *inode_p, struct file *file_p,
-				unsigned int service, unsigned long arg)
-{
-	struct me4000_ao_context *ao_context;
-
-	CALL_PDEBUG("me4000_ao_ioctl_cont() is executed\n");
-
-	ao_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		return -ENOTTY;
-		PDEBUG("me4000_ao_ioctl_cont():Wrong magic number\n");
-	}
-
-	switch (service) {
-	case ME4000_AO_START:
-		return me4000_ao_start((unsigned long *)arg, ao_context);
-	case ME4000_AO_STOP:
-		return me4000_ao_stop(ao_context);
-	case ME4000_AO_IMMEDIATE_STOP:
-		return me4000_ao_immediate_stop(ao_context);
-	case ME4000_AO_RESET:
-		return me4000_ao_reset(ao_context);
-	case ME4000_AO_TIMER_SET_DIVISOR:
-		return me4000_ao_timer_set_divisor((u32 *) arg, ao_context);
-	case ME4000_AO_EX_TRIG_SETUP:
-		return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
-	case ME4000_AO_EX_TRIG_ENABLE:
-		return me4000_ao_ex_trig_enable(ao_context);
-	case ME4000_AO_EX_TRIG_DISABLE:
-		return me4000_ao_ex_trig_disable(ao_context);
-	case ME4000_AO_ENABLE_DO:
-		return me4000_ao_enable_do(ao_context);
-	case ME4000_AO_DISABLE_DO:
-		return me4000_ao_disable_do(ao_context);
-	case ME4000_AO_FSM_STATE:
-		return me4000_ao_fsm_state((int *)arg, ao_context);
-	case ME4000_GET_USER_INFO:
-		return me4000_get_user_info((struct me4000_user_info *)arg,
-					    ao_context->board_info);
-	case ME4000_AO_SYNCHRONOUS_EX_TRIG:
-		return me4000_ao_synchronous_ex_trig(ao_context);
-	case ME4000_AO_SYNCHRONOUS_SW:
-		return me4000_ao_synchronous_sw(ao_context);
-	case ME4000_AO_SYNCHRONOUS_DISABLE:
-		return me4000_ao_synchronous_disable(ao_context);
-	case ME4000_AO_GET_FREE_BUFFER:
-		return me4000_ao_get_free_buffer((unsigned long *)arg,
-						 ao_context);
-	default:
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_ao_start(unsigned long *arg,
-			   struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	wait_queue_head_t queue;
-	unsigned long ref;
-	unsigned long timeout;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_start() is executed\n");
-
-	if (get_user(timeout, arg)) {
-		printk(KERN_ERR
-		       "me4000_ao_start():Cannot copy data from user\n");
-		return -EFAULT;
-	}
-
-	init_waitqueue_head(&queue);
-
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = inl(ao_context->ctrl_reg);
-	tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) {
-		if (timeout) {
-			ref = jiffies;
-			while (!
-			       (inl(ao_context->status_reg) &
-				ME4000_AO_STATUS_BIT_FSM)) {
-				interruptible_sleep_on_timeout(&queue, 1);
-				if (signal_pending(current)) {
-					printk(KERN_ERR
-					       "ME4000:me4000_ao_start():Wait on start of state machine interrupted\n");
-					return -EINTR;
-				}
-				/* 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;
-				}
-			}
-		}
-	} else {
-		me4000_outl(0x8000, ao_context->single_reg);
-	}
-
-	return 0;
-}
-
-static int me4000_ao_stop(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	wait_queue_head_t queue;
-	unsigned long flags;
-
-	init_waitqueue_head(&queue);
-
-	CALL_PDEBUG("me4000_ao_stop() is executed\n");
-
-	/* Set the stop bit */
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = inl(ao_context->ctrl_reg);
-	tmp |= ME4000_AO_CTRL_BIT_STOP;
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-		interruptible_sleep_on_timeout(&queue, 1);
-		if (signal_pending(current)) {
-			printk(KERN_ERR
-			       "me4000_ao_stop():Wait on state machine after stop interrupted\n");
-			return -EINTR;
-		}
-	}
-
-	/* Clear the stop bit */
-	/* tmp &= ~ME4000_AO_CTRL_BIT_STOP; */
-	/* me4000_outl(tmp, ao_context->ctrl_reg); */
-
-	return 0;
-}
-
-static int me4000_ao_immediate_stop(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	wait_queue_head_t queue;
-	unsigned long flags;
-
-	init_waitqueue_head(&queue);
-
-	CALL_PDEBUG("me4000_ao_immediate_stop() is executed\n");
-
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = inl(ao_context->ctrl_reg);
-	tmp |= ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
-		interruptible_sleep_on_timeout(&queue, 1);
-		if (signal_pending(current)) {
-			printk(KERN_ERR
-			       "me4000_ao_immediate_stop():Wait on state machine after stop interrupted\n");
-			return -EINTR;
-		}
-	}
-
-	/* Clear the stop bits */
-	/* tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); */
-	/* me4000_outl(tmp, ao_context->ctrl_reg); */
-
-	return 0;
-}
-
-static int me4000_ao_timer_set_divisor(u32 *arg,
-				       struct me4000_ao_context *ao_context)
-{
-	u32 divisor;
-	u32 tmp;
-
-	CALL_PDEBUG("me4000_ao_timer set_divisor() is executed\n");
-
-	if (get_user(divisor, arg))
-		return -EFAULT;
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "me4000_ao_timer_set_divisor():Can't set timer while DAC is running\n");
-		return -EBUSY;
-	}
-
-	PDEBUG("me4000_ao_timer set_divisor():Divisor from user = %d\n",
-	       divisor);
-
-	/* Check if the divisor is right. ME4000_AO_MIN_TICKS is the lowest */
-	if (divisor < ME4000_AO_MIN_TICKS) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ao_timer set_divisor():Divisor to low\n");
-		return -EINVAL;
-	}
-
-	/* Fix bug in Firmware */
-	divisor -= 2;
-
-	PDEBUG("me4000_ao_timer set_divisor():Divisor to HW = %d\n", divisor);
-
-	/* Write the divisor */
-	me4000_outl(divisor, ao_context->timer_reg);
-
-	return 0;
-}
-
-static int me4000_ao_ex_trig_set_edge(int *arg,
-				      struct me4000_ao_context *ao_context)
-{
-	int mode;
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_ex_trig_set_edge() is executed\n");
-
-	if (get_user(mode, arg))
-		return -EFAULT;
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "me4000_ao_ex_trig_set_edge():Can't set trigger while DAC is running\n");
-		return -EBUSY;
-	}
-
-	if (mode == ME4000_AO_TRIGGER_EXT_EDGE_RISING) {
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		tmp &=
-		    ~(ME4000_AO_CTRL_BIT_EX_TRIG_EDGE |
-		      ME4000_AO_CTRL_BIT_EX_TRIG_BOTH);
-		me4000_outl(tmp, ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-	} else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_FALLING) {
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		tmp &= ~ME4000_AO_CTRL_BIT_EX_TRIG_BOTH;
-		tmp |= ME4000_AO_CTRL_BIT_EX_TRIG_EDGE;
-		me4000_outl(tmp, ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-	} else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_BOTH) {
-		spin_lock_irqsave(&ao_context->int_lock, flags);
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		tmp |=
-		    ME4000_AO_CTRL_BIT_EX_TRIG_EDGE |
-		    ME4000_AO_CTRL_BIT_EX_TRIG_BOTH;
-		me4000_outl(tmp, ao_context->ctrl_reg);
-		spin_unlock_irqrestore(&ao_context->int_lock, flags);
-	} else {
-		printk(KERN_ERR
-		       "me4000_ao_ex_trig_set_edge():Invalid trigger mode\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int me4000_ao_ex_trig_enable(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_ex_trig_enable() is executed\n");
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "me4000_ao_ex_trig_enable():Can't enable trigger while DAC is running\n");
-		return -EBUSY;
-	}
-
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = me4000_inl(ao_context->ctrl_reg);
-	tmp |= ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ao_ex_trig_disable(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_ex_trig_disable() is executed\n");
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "me4000_ao_ex_trig_disable():Can't disable trigger while DAC is running\n");
-		return -EBUSY;
-	}
-
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = me4000_inl(ao_context->ctrl_reg);
-	tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-
-	CALL_PDEBUG("me4000_ao_simultaneous_disable() is executed\n");
-
-	/* Check if the state machine is stopped */
-	/* Be careful here because this function is called from
-	   me4000_ao_synchronous disable */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "me4000_ao_simultaneous_disable():Can't disable while DAC is running\n");
-		return -EBUSY;
-	}
-
-	spin_lock(&ao_context->board_info->preload_lock);
-	tmp = me4000_inl(ao_context->preload_reg);
-	/* 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);
-
-	return 0;
-}
-
-static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-
-	CALL_PDEBUG("me4000_ao_simultaneous_ex_trig() is executed\n");
-
-	spin_lock(&ao_context->board_info->preload_lock);
-	tmp = me4000_inl(ao_context->preload_reg);
-	/* 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);
-
-	return 0;
-}
-
-static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-
-	CALL_PDEBUG("me4000_ao_simultaneous_sw() is executed\n");
-
-	spin_lock(&ao_context->board_info->preload_lock);
-	tmp = me4000_inl(ao_context->preload_reg);
-	/* 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);
-
-	return 0;
-}
-
-static int me4000_ao_preload(struct me4000_ao_context *ao_context)
-{
-	CALL_PDEBUG("me4000_ao_preload() is executed\n");
-	return me4000_ao_simultaneous_sw(ao_context);
-}
-
-static int me4000_ao_preload_update(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	u32 ctrl;
-	struct list_head *entry;
-
-	CALL_PDEBUG("me4000_ao_preload_update() is executed\n");
-
-	spin_lock(&ao_context->board_info->preload_lock);
-	tmp = me4000_inl(ao_context->preload_reg);
-	list_for_each(entry, &ao_context->board_info->ao_context_list) {
-		/* The channels we update must be in the following state :
-		   - Mode A
-		   - Hardware trigger is disabled
-		   - Corresponding simultaneous bit is reset
-		 */
-		ctrl = me4000_inl(ao_context->ctrl_reg);
-		if (!
-		    (ctrl &
-		     (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1 |
-		      ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG))) {
-			if (!
-			    (tmp &
-			     (0x1 <<
-			      (((struct me4000_ao_context *)entry)->index
-								      + 16)))) {
-				tmp &=
-				    ~(0x1 <<
-				      (((struct me4000_ao_context *)entry)->
-									index));
-			}
-		}
-	}
-	me4000_outl(tmp, ao_context->preload_reg);
-	spin_unlock(&ao_context->board_info->preload_lock);
-
-	return 0;
-}
-
-static int me4000_ao_simultaneous_update(struct me4000_ao_channel_list *arg,
-					 struct me4000_ao_context *ao_context)
-{
-	int err;
-	int i;
-	u32 tmp;
-	struct me4000_ao_channel_list channels;
-
-	CALL_PDEBUG("me4000_ao_simultaneous_update() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&channels, arg,
-			sizeof(struct me4000_ao_channel_list));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ao_simultaneous_update():Can't copy command\n");
-		return -EFAULT;
-	}
-
-	channels.list =
-	    kzalloc(sizeof(unsigned long) * channels.count, GFP_KERNEL);
-	if (!channels.list) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ao_simultaneous_update():Can't get buffer\n");
-		return -ENOMEM;
-	}
-
-	/* Copy channel list from user */
-	err =
-	    copy_from_user(channels.list, arg->list,
-			   sizeof(unsigned long) * channels.count);
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ao_simultaneous_update():Can't copy list\n");
-		kfree(channels.list);
-		return -EFAULT;
-	}
-
-	spin_lock(&ao_context->board_info->preload_lock);
-	tmp = me4000_inl(ao_context->preload_reg);
-	for (i = 0; i < channels.count; i++) {
-		if (channels.list[i] >
-		    ao_context->board_info->board_p->ao.count) {
-			spin_unlock(&ao_context->board_info->preload_lock);
-			kfree(channels.list);
-			printk(KERN_ERR
-			       "ME4000:me4000_ao_simultaneous_update():Invalid board number specified\n");
-			return -EFAULT;
-		}
-		/* 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);
-	kfree(channels.list);
-
-	return 0;
-}
-
-static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_synchronous_ex_trig() is executed\n");
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "me4000_ao_synchronous_ex_trig(): DAC is running\n");
-		return -EBUSY;
-	}
-
-	spin_lock(&ao_context->board_info->preload_lock);
-	tmp = me4000_inl(ao_context->preload_reg);
-	/* 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);
-
-	/* Make runnable */
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = me4000_inl(ao_context->ctrl_reg);
-	if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) {
-		tmp &=
-		    ~(ME4000_AO_CTRL_BIT_STOP |
-		      ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-		me4000_outl(tmp, ao_context->ctrl_reg);
-	}
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_synchronous_sw() is executed\n");
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR "me4000_ao_synchronous_sw(): DAC is running\n");
-		return -EBUSY;
-	}
-
-	spin_lock(&ao_context->board_info->preload_lock);
-	tmp = me4000_inl(ao_context->preload_reg);
-	/* 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);
-
-	/* Make runnable */
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = me4000_inl(ao_context->ctrl_reg);
-	if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) {
-		tmp &=
-		    ~(ME4000_AO_CTRL_BIT_STOP |
-		      ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
-		me4000_outl(tmp, ao_context->ctrl_reg);
-	}
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ao_synchronous_disable(struct me4000_ao_context *ao_context)
-{
-	return me4000_ao_simultaneous_disable(ao_context);
-}
-
-static int me4000_ao_get_free_buffer(unsigned long *arg,
-				     struct me4000_ao_context *ao_context)
-{
-	unsigned long c;
-	int err;
-
-	c = me4000_buf_space(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT);
-
-	err = copy_to_user(arg, &c, sizeof(unsigned long));
-	if (err) {
-		printk(KERN_ERR
-		       "%s:Can't copy to user space\n", __func__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int me4000_ao_ex_trig_timeout(unsigned long *arg,
-				     struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	wait_queue_head_t queue;
-	unsigned long ref;
-	unsigned long timeout;
-
-	CALL_PDEBUG("me4000_ao_ex_trig_timeout() is executed\n");
-
-	if (get_user(timeout, arg)) {
-		printk(KERN_ERR
-		       "me4000_ao_ex_trig_timeout():Cannot copy data from user\n");
-		return -EFAULT;
-	}
-
-	init_waitqueue_head(&queue);
-
-	tmp = inl(ao_context->ctrl_reg);
-
-	if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) {
-		if (timeout) {
-			ref = jiffies;
-			while ((inl(ao_context->status_reg) &
-				ME4000_AO_STATUS_BIT_FSM)) {
-				interruptible_sleep_on_timeout(&queue, 1);
-				if (signal_pending(current)) {
-					printk(KERN_ERR
-					       "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
-					return -EINTR;
-				}
-				/* 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;
-				}
-			}
-		} else {
-			while ((inl(ao_context->status_reg) &
-				ME4000_AO_STATUS_BIT_FSM)) {
-				interruptible_sleep_on_timeout(&queue, 1);
-				if (signal_pending(current)) {
-					printk(KERN_ERR
-					       "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
-					return -EINTR;
-				}
-			}
-		}
-	} else {
-		printk(KERN_ERR
-		       "ME4000:me4000_ao_ex_trig_timeout():External Trigger is not enabled\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int me4000_ao_enable_do(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_enable_do() is executed\n");
-
-	/* Only available for analog output 3 */
-	if (ao_context->index != 3) {
-		printk(KERN_ERR
-		       "me4000_ao_enable_do():Only available for analog output 3\n");
-		return -ENOTTY;
-	}
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR "me4000_ao_enable_do(): DAC is running\n");
-		return -EBUSY;
-	}
-
-	/* Set the stop bit */
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = inl(ao_context->ctrl_reg);
-	tmp |= ME4000_AO_CTRL_BIT_ENABLE_DO;
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ao_disable_do(struct me4000_ao_context *ao_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ao_disable_do() is executed\n");
-
-	/* Only available for analog output 3 */
-	if (ao_context->index != 3) {
-		printk(KERN_ERR
-		       "me4000_ao_disable():Only available for analog output 3\n");
-		return -ENOTTY;
-	}
-
-	/* Check if the state machine is stopped */
-	tmp = me4000_inl(ao_context->status_reg);
-	if (tmp & ME4000_AO_STATUS_BIT_FSM) {
-		printk(KERN_ERR "me4000_ao_disable_do(): DAC is running\n");
-		return -EBUSY;
-	}
-
-	spin_lock_irqsave(&ao_context->int_lock, flags);
-	tmp = inl(ao_context->ctrl_reg);
-	tmp &= ~(ME4000_AO_CTRL_BIT_ENABLE_DO);
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	spin_unlock_irqrestore(&ao_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ao_fsm_state(int *arg, struct me4000_ao_context *ao_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ao_fsm_state() is executed\n");
-
-	tmp =
-	    (me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) ? 1
-	    : 0;
-
-	if (ao_context->pipe_flag) {
-		printk(KERN_ERR "me4000_ao_fsm_state():Broken pipe detected\n");
-		return -EPIPE;
-	}
-
-	if (put_user(tmp, arg)) {
-		printk(KERN_ERR "me4000_ao_fsm_state():Cannot copy to user\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-/*------------------------- Analog input stuff -------------------------------*/
-
-static int me4000_ai_prepare(struct me4000_ai_context *ai_context)
-{
-	wait_queue_head_t queue;
-	int err;
-
-	CALL_PDEBUG("me4000_ai_prepare() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	/* Set the new mode and stop bits */
-	me4000_outl(ai_context->
-		    mode | ME4000_AI_CTRL_BIT_STOP |
-		    ME4000_AI_CTRL_BIT_IMMEDIATE_STOP, ai_context->ctrl_reg);
-
-	/* Set the timer registers */
-	ai_context->chan_timer = 66;
-	ai_context->chan_pre_timer = 66;
-	ai_context->scan_timer_low = 0;
-	ai_context->scan_timer_high = 0;
-
-	me4000_outl(65, ai_context->chan_timer_reg);
-	me4000_outl(65, ai_context->chan_pre_timer_reg);
-	me4000_outl(0, ai_context->scan_timer_low_reg);
-	me4000_outl(0, ai_context->scan_timer_high_reg);
-	me4000_outl(0, ai_context->scan_pre_timer_low_reg);
-	me4000_outl(0, ai_context->scan_pre_timer_high_reg);
-
-	ai_context->channel_list_count = 0;
-
-	if (ai_context->mode) {
-		/* Request the interrupt line */
-		err =
-		    request_irq(ai_context->irq, me4000_ai_isr,
-				IRQF_DISABLED | IRQF_SHARED, ME4000_NAME,
-				ai_context);
-		if (err) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_prepare():Can't get interrupt line");
-			return -ENODEV;
-		}
-
-		/* Allocate circular buffer */
-		ai_context->circ_buf.buf =
-		    kzalloc(ME4000_AI_BUFFER_SIZE, GFP_KERNEL);
-		if (!ai_context->circ_buf.buf) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_prepare():Can't get circular buffer\n");
-			free_irq(ai_context->irq, ai_context);
-			return -ENOMEM;
-		}
-
-		/* Clear the circular buffer */
-		ai_context->circ_buf.head = 0;
-		ai_context->circ_buf.tail = 0;
-	}
-
-	return 0;
-}
-
-static int me4000_ai_reset(struct me4000_ai_context *ai_context)
-{
-	wait_queue_head_t queue;
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ai_reset() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	/*
-	 * First stop conversion of the state machine before reconfigure.
-	 * If not stopped before configuring mode, it could
-	 * walk in a undefined state.
-	 */
-	spin_lock_irqsave(&ai_context->int_lock, flags);
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-	spin_unlock_irqrestore(&ai_context->int_lock, flags);
-
-	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_ai_reset():Wait on state machine after stop interrupted\n");
-			return -EINTR;
-		}
-	}
-
-	/* Clear the control register and set the stop bits */
-	spin_lock_irqsave(&ai_context->int_lock, flags);
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
-		    ai_context->ctrl_reg);
-	spin_unlock_irqrestore(&ai_context->int_lock, flags);
-
-	/* Reset timer registers */
-	ai_context->chan_timer = 66;
-	ai_context->chan_pre_timer = 66;
-	ai_context->scan_timer_low = 0;
-	ai_context->scan_timer_high = 0;
-	ai_context->sample_counter = 0;
-	ai_context->sample_counter_reload = 0;
-
-	me4000_outl(65, ai_context->chan_timer_reg);
-	me4000_outl(65, ai_context->chan_pre_timer_reg);
-	me4000_outl(0, ai_context->scan_timer_low_reg);
-	me4000_outl(0, ai_context->scan_timer_high_reg);
-	me4000_outl(0, ai_context->scan_pre_timer_low_reg);
-	me4000_outl(0, ai_context->scan_pre_timer_high_reg);
-	me4000_outl(0, ai_context->sample_counter_reg);
-
-	ai_context->channel_list_count = 0;
-
-	/* Clear the circular buffer */
-	ai_context->circ_buf.head = 0;
-	ai_context->circ_buf.tail = 0;
-
-	return 0;
-}
-
-static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p,
-				unsigned int service, unsigned long arg)
-{
-	struct me4000_ai_context *ai_context;
-
-	CALL_PDEBUG("me4000_ai_ioctl_sing() is executed\n");
-
-	ai_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		printk(KERN_ERR "me4000_ai_ioctl_sing():Wrong magic number\n");
-		return -ENOTTY;
-	}
-	if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-		printk(KERN_ERR
-		       "me4000_ai_ioctl_sing():Service number to high\n");
-		return -ENOTTY;
-	}
-
-	switch (service) {
-	case ME4000_AI_SINGLE:
-		return me4000_ai_single((struct me4000_ai_single *)arg,
-								ai_context);
-	case ME4000_AI_EX_TRIG_ENABLE:
-		return me4000_ai_ex_trig_enable(ai_context);
-	case ME4000_AI_EX_TRIG_DISABLE:
-		return me4000_ai_ex_trig_disable(ai_context);
-	case ME4000_AI_EX_TRIG_SETUP:
-		return me4000_ai_ex_trig_setup((struct me4000_ai_trigger *)arg,
-					       ai_context);
-	case ME4000_GET_USER_INFO:
-		return me4000_get_user_info((struct me4000_user_info *)arg,
-					    ai_context->board_info);
-	case ME4000_AI_OFFSET_ENABLE:
-		return me4000_ai_offset_enable(ai_context);
-	case ME4000_AI_OFFSET_DISABLE:
-		return me4000_ai_offset_disable(ai_context);
-	case ME4000_AI_FULLSCALE_ENABLE:
-		return me4000_ai_fullscale_enable(ai_context);
-	case ME4000_AI_FULLSCALE_DISABLE:
-		return me4000_ai_fullscale_disable(ai_context);
-	case ME4000_AI_EEPROM_READ:
-		return me4000_eeprom_read((struct me4000_eeprom *)arg,
-								ai_context);
-	case ME4000_AI_EEPROM_WRITE:
-		return me4000_eeprom_write((struct me4000_eeprom *)arg,
-								ai_context);
-	default:
-		printk(KERN_ERR
-		       "me4000_ai_ioctl_sing():Invalid service number\n");
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_ai_single(struct me4000_ai_single *arg,
-			    struct me4000_ai_context *ai_context)
-{
-	struct me4000_ai_single cmd;
-	int err;
-	u32 tmp;
-	wait_queue_head_t queue;
-	unsigned long jiffy;
-
-	CALL_PDEBUG("me4000_ai_single() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_single));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_single():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	/* Check range parameter */
-	switch (cmd.range) {
-	case ME4000_AI_LIST_RANGE_BIPOLAR_10:
-	case ME4000_AI_LIST_RANGE_BIPOLAR_2_5:
-	case ME4000_AI_LIST_RANGE_UNIPOLAR_10:
-	case ME4000_AI_LIST_RANGE_UNIPOLAR_2_5:
-		break;
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_single():Invalid range specified\n");
-		return -EINVAL;
-	}
-
-	/* Check mode and channel number */
-	switch (cmd.mode) {
-	case ME4000_AI_LIST_INPUT_SINGLE_ENDED:
-		if (cmd.channel >= ai_context->board_info->board_p->ai.count) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_single():Analog input is not available\n");
-			return -EINVAL;
-		}
-		break;
-	case ME4000_AI_LIST_INPUT_DIFFERENTIAL:
-		if (cmd.channel >=
-		    ai_context->board_info->board_p->ai.diff_count) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_single():Analog input is not available in differential mode\n");
-			return -EINVAL;
-		}
-		break;
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_single():Invalid mode specified\n");
-		return -EINVAL;
-	}
-
-	/* Clear channel list, data fifo and both stop bits */
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &=
-	    ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO |
-	      ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	/* Enable channel list and data fifo */
-	tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	/* Generate channel list entry */
-	me4000_outl(cmd.channel | cmd.range | cmd.
-		    mode | ME4000_AI_LIST_LAST_ENTRY,
-		    ai_context->channel_list_reg);
-
-	/* Set the timer to maximum */
-	me4000_outl(66, ai_context->chan_timer_reg);
-	me4000_outl(66, ai_context->chan_pre_timer_reg);
-
-	if (tmp & ME4000_AI_CTRL_BIT_EX_TRIG) {
-		jiffy = jiffies;
-		while (!
-		       (me4000_inl(ai_context->status_reg) &
-			ME4000_AI_STATUS_BIT_EF_DATA)) {
-			interruptible_sleep_on_timeout(&queue, 1);
-			if (signal_pending(current)) {
-				printk(KERN_ERR
-				       "ME4000:me4000_ai_single():Wait on start of state machine interrupted\n");
-				return -EINTR;
-			}
-			/* 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;
-			}
-		}
-	} else {
-		/* Start conversion */
-		me4000_inl(ai_context->start_reg);
-
-		/* Wait until ready */
-		udelay(10);
-		if (!
-		    (me4000_inl(ai_context->status_reg) &
-		     ME4000_AI_STATUS_BIT_EF_DATA)) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_single():Value not available after wait\n");
-			return -EIO;
-		}
-	}
-
-	/* Read value from data fifo */
-	cmd.value = me4000_inl(ai_context->data_reg) & 0xFFFF;
-
-	/* Copy result back to user */
-	err = copy_to_user(arg, &cmd, sizeof(struct me4000_ai_single));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_single():Can't copy to user space\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p,
-			      unsigned int service, unsigned long arg)
-{
-	struct me4000_ai_context *ai_context;
-
-	CALL_PDEBUG("me4000_ai_ioctl_sw() is executed\n");
-
-	ai_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		printk(KERN_ERR "me4000_ai_ioctl_sw():Wrong magic number\n");
-		return -ENOTTY;
-	}
-	if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-		printk(KERN_ERR
-		       "me4000_ai_ioctl_sw():Service number to high\n");
-		return -ENOTTY;
-	}
-
-	switch (service) {
-	case ME4000_AI_SC_SETUP:
-		return me4000_ai_sc_setup((struct me4000_ai_sc *)arg,
-								ai_context);
-	case ME4000_AI_CONFIG:
-		return me4000_ai_config((struct me4000_ai_config *)arg,
-								ai_context);
-	case ME4000_AI_START:
-		return me4000_ai_start(ai_context);
-	case ME4000_AI_STOP:
-		return me4000_ai_stop(ai_context);
-	case ME4000_AI_IMMEDIATE_STOP:
-		return me4000_ai_immediate_stop(ai_context);
-	case ME4000_AI_FSM_STATE:
-		return me4000_ai_fsm_state((int *)arg, ai_context);
-	case ME4000_GET_USER_INFO:
-		return me4000_get_user_info((struct me4000_user_info *)arg,
-					    ai_context->board_info);
-	case ME4000_AI_EEPROM_READ:
-		return me4000_eeprom_read((struct me4000_eeprom *)arg,
-								ai_context);
-	case ME4000_AI_EEPROM_WRITE:
-		return me4000_eeprom_write((struct me4000_eeprom *)arg,
-								ai_context);
-	case ME4000_AI_GET_COUNT_BUFFER:
-		return me4000_ai_get_count_buffer((unsigned long *)arg,
-						  ai_context);
-	default:
-		printk(KERN_ERR
-		       "%s:Invalid service number %d\n", __func__, service);
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p,
-			       unsigned int service, unsigned long arg)
-{
-	struct me4000_ai_context *ai_context;
-
-	CALL_PDEBUG("me4000_ai_ioctl_ext() is executed\n");
-
-	ai_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		printk(KERN_ERR "me4000_ai_ioctl_ext():Wrong magic number\n");
-		return -ENOTTY;
-	}
-	if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-		printk(KERN_ERR
-		       "me4000_ai_ioctl_ext():Service number to high\n");
-		return -ENOTTY;
-	}
-
-	switch (service) {
-	case ME4000_AI_SC_SETUP:
-		return me4000_ai_sc_setup((struct me4000_ai_sc *)arg,
-								ai_context);
-	case ME4000_AI_CONFIG:
-		return me4000_ai_config((struct me4000_ai_config *)arg,
-								ai_context);
-	case ME4000_AI_START:
-		return me4000_ai_start_ex((unsigned long *)arg, ai_context);
-	case ME4000_AI_STOP:
-		return me4000_ai_stop(ai_context);
-	case ME4000_AI_IMMEDIATE_STOP:
-		return me4000_ai_immediate_stop(ai_context);
-	case ME4000_AI_EX_TRIG_ENABLE:
-		return me4000_ai_ex_trig_enable(ai_context);
-	case ME4000_AI_EX_TRIG_DISABLE:
-		return me4000_ai_ex_trig_disable(ai_context);
-	case ME4000_AI_EX_TRIG_SETUP:
-		return me4000_ai_ex_trig_setup((struct me4000_ai_trigger *)arg,
-					       ai_context);
-	case ME4000_AI_FSM_STATE:
-		return me4000_ai_fsm_state((int *)arg, ai_context);
-	case ME4000_GET_USER_INFO:
-		return me4000_get_user_info((struct me4000_user_info *)arg,
-					    ai_context->board_info);
-	case ME4000_AI_GET_COUNT_BUFFER:
-		return me4000_ai_get_count_buffer((unsigned long *)arg,
-						  ai_context);
-	default:
-		printk(KERN_ERR
-		       "%s:Invalid service number %d\n", __func__ , service);
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_ai_fasync(int fd, struct file *file_p, int mode)
-{
-	struct me4000_ai_context *ai_context;
-
-	CALL_PDEBUG("me4000_ao_fasync_cont() is executed\n");
-
-	ai_context = file_p->private_data;
-	return fasync_helper(fd, file_p, mode, &ai_context->fasync_p);
-}
-
-static int me4000_ai_config(struct me4000_ai_config *arg,
-			    struct me4000_ai_context *ai_context)
-{
-	struct me4000_ai_config cmd;
-	u32 *list = NULL;
-	u32 mode;
-	int i;
-	int err;
-	wait_queue_head_t queue;
-	u64 scan;
-	u32 tmp;
-
-	CALL_PDEBUG("me4000_ai_config() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	/* Check if conversion is stopped */
-	if (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_config():Conversion is not stopped\n");
-		err = -EBUSY;
-		goto AI_CONFIG_ERR;
-	}
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_config));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_config():Can't copy from user space\n");
-		err = -EFAULT;
-		goto AI_CONFIG_ERR;
-	}
-
-	PDEBUG
-	    ("me4000_ai_config():chan = %ld, pre_chan = %ld, scan_low = %ld, scan_high = %ld, count = %ld\n",
-	     cmd.timer.chan, cmd.timer.pre_chan, cmd.timer.scan_low,
-	     cmd.timer.scan_high, cmd.channel_list.count);
-
-	/* Check whether sample and hold is available for this board */
-	if (cmd.sh) {
-		if (!ai_context->board_info->board_p->ai.sh_count) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_config():Sample and Hold is not available for this board\n");
-			err = -ENODEV;
-			goto AI_CONFIG_ERR;
-		}
-	}
-
-	/* Check the channel list size */
-	if (cmd.channel_list.count > ME4000_AI_CHANNEL_LIST_COUNT) {
-		printk(KERN_ERR
-		       "me4000_ai_config():Channel list is to large\n");
-		err = -EINVAL;
-		goto AI_CONFIG_ERR;
-	}
-
-	/* Copy channel list from user */
-	list = kmalloc(sizeof(u32) * cmd.channel_list.count, GFP_KERNEL);
-	if (!list) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_config():Can't get memory for channel list\n");
-		err = -ENOMEM;
-		goto AI_CONFIG_ERR;
-	}
-	err =
-	    copy_from_user(list, cmd.channel_list.list,
-			   sizeof(u32) * cmd.channel_list.count);
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_config():Can't copy from user space\n");
-		err = -EFAULT;
-		goto AI_CONFIG_ERR;
-	}
-
-	/* Check if last entry bit is set */
-	if (!(list[cmd.channel_list.count - 1] & ME4000_AI_LIST_LAST_ENTRY)) {
-		printk(KERN_WARNING
-		       "me4000_ai_config():Last entry bit is not set\n");
-		list[cmd.channel_list.count - 1] |= ME4000_AI_LIST_LAST_ENTRY;
-	}
-
-	/* Check whether mode is equal for all entries */
-	mode = list[0] & 0x20;
-	for (i = 0; i < cmd.channel_list.count; i++) {
-		if ((list[i] & 0x20) != mode) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_config():Mode is not equal for all entries\n");
-			err = -EINVAL;
-			goto AI_CONFIG_ERR;
-		}
-	}
-
-	/* Check whether channels are available for this mode */
-	if (mode == ME4000_AI_LIST_INPUT_SINGLE_ENDED) {
-		for (i = 0; i < cmd.channel_list.count; i++) {
-			if ((list[i] & 0x1F) >=
-			    ai_context->board_info->board_p->ai.count) {
-				printk(KERN_ERR
-				       "ME4000:me4000_ai_config():Channel is not available for single ended\n");
-				err = -EINVAL;
-				goto AI_CONFIG_ERR;
-			}
-		}
-	} else if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) {
-		for (i = 0; i < cmd.channel_list.count; i++) {
-			if ((list[i] & 0x1F) >=
-			    ai_context->board_info->board_p->ai.diff_count) {
-				printk(KERN_ERR
-				       "ME4000:me4000_ai_config():Channel is not available for differential\n");
-				err = -EINVAL;
-				goto AI_CONFIG_ERR;
-			}
-		}
-	}
-
-	/* Check if bipolar is set for all entries when in differential mode */
-	if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) {
-		for (i = 0; i < cmd.channel_list.count; i++) {
-			if ((list[i] & 0xC0) != ME4000_AI_LIST_RANGE_BIPOLAR_10
-			    && (list[i] & 0xC0) !=
-			    ME4000_AI_LIST_RANGE_BIPOLAR_2_5) {
-				printk(KERN_ERR
-				       "ME4000:me4000_ai_config():Bipolar is not selected in differential mode\n");
-				err = -EINVAL;
-				goto AI_CONFIG_ERR;
-			}
-		}
-	}
-
-	if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE) {
-		/* Check for minimum channel divisor */
-		if (cmd.timer.chan < ME4000_AI_MIN_TICKS) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_config():Channel timer divisor is to low\n");
-			err = -EINVAL;
-			goto AI_CONFIG_ERR;
-		}
-
-		/* Check if minimum channel divisor is adjusted when sample and hold is activated */
-		if ((cmd.sh) && (cmd.timer.chan != ME4000_AI_MIN_TICKS)) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_config():Channel timer divisor must be at minimum when sample and hold is activated\n");
-			err = -EINVAL;
-			goto AI_CONFIG_ERR;
-		}
-
-		/* Check for minimum channel pre divisor */
-		if (cmd.timer.pre_chan < ME4000_AI_MIN_TICKS) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_config():Channel pre timer divisor is to low\n");
-			err = -EINVAL;
-			goto AI_CONFIG_ERR;
-		}
-
-		/* Write the channel timers */
-		me4000_outl(cmd.timer.chan - 1, ai_context->chan_timer_reg);
-		me4000_outl(cmd.timer.pre_chan - 1,
-			    ai_context->chan_pre_timer_reg);
-
-		/* Save the timer values in the board context */
-		ai_context->chan_timer = cmd.timer.chan;
-		ai_context->chan_pre_timer = cmd.timer.pre_chan;
-
-		if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST) {
-			/* Check for scan timer divisor */
-			scan =
-			    (u64) cmd.timer.scan_low | ((u64) cmd.timer.
-							scan_high << 32);
-			if (scan != 0) {
-				if (scan <
-				    cmd.channel_list.count * cmd.timer.chan +
-				    1) {
-					printk(KERN_ERR
-					       "ME4000:me4000_ai_config():Scan timer divisor is to low\n");
-					err = -EINVAL;
-					goto AI_CONFIG_ERR;
-				}
-			}
-
-			/* Write the scan timers */
-			if (scan != 0) {
-				scan--;
-				tmp = (u32) (scan & 0xFFFFFFFF);
-				me4000_outl(tmp,
-					    ai_context->scan_timer_low_reg);
-				tmp = (u32) ((scan >> 32) & 0xFFFFFFFF);
-				me4000_outl(tmp,
-					    ai_context->scan_timer_high_reg);
-
-				scan =
-				    scan - (cmd.timer.chan - 1) +
-				    (cmd.timer.pre_chan - 1);
-				tmp = (u32) (scan & 0xFFFFFFFF);
-				me4000_outl(tmp,
-					    ai_context->scan_pre_timer_low_reg);
-				tmp = (u32) ((scan >> 32) & 0xFFFFFFFF);
-				me4000_outl(tmp,
-					    ai_context->
-					    scan_pre_timer_high_reg);
-			} else {
-				me4000_outl(0x0,
-					    ai_context->scan_timer_low_reg);
-				me4000_outl(0x0,
-					    ai_context->scan_timer_high_reg);
-
-				me4000_outl(0x0,
-					    ai_context->scan_pre_timer_low_reg);
-				me4000_outl(0x0,
-					    ai_context->
-					    scan_pre_timer_high_reg);
-			}
-
-			ai_context->scan_timer_low = cmd.timer.scan_low;
-			ai_context->scan_timer_high = cmd.timer.scan_high;
-		}
-	}
-
-	/* Clear the channel list */
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &= ~ME4000_AI_CTRL_BIT_CHANNEL_FIFO;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-	tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	/* Write the channel list */
-	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) {
-		tmp |= ME4000_AI_CTRL_BIT_SAMPLE_HOLD;
-		me4000_outl(tmp, ai_context->ctrl_reg);
-	} else {
-		tmp &= ~ME4000_AI_CTRL_BIT_SAMPLE_HOLD;
-		me4000_outl(tmp, ai_context->ctrl_reg);
-	}
-
-	/* Save the channel list size in the board context */
-	ai_context->channel_list_count = cmd.channel_list.count;
-
-	kfree(list);
-
-	return 0;
-
-AI_CONFIG_ERR:
-
-	/* Reset the timers */
-	ai_context->chan_timer = 66;
-	ai_context->chan_pre_timer = 66;
-	ai_context->scan_timer_low = 0;
-	ai_context->scan_timer_high = 0;
-
-	me4000_outl(65, ai_context->chan_timer_reg);
-	me4000_outl(65, ai_context->chan_pre_timer_reg);
-	me4000_outl(0, ai_context->scan_timer_high_reg);
-	me4000_outl(0, ai_context->scan_timer_low_reg);
-	me4000_outl(0, ai_context->scan_pre_timer_high_reg);
-	me4000_outl(0, ai_context->scan_pre_timer_low_reg);
-
-	ai_context->channel_list_count = 0;
-
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &=
-	    ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_SAMPLE_HOLD);
-
-	kfree(list);
-
-	return err;
-
-}
-
-static int ai_common_start(struct me4000_ai_context *ai_context)
-{
-	u32 tmp;
-	CALL_PDEBUG("ai_common_start() is executed\n");
-
-	tmp = me4000_inl(ai_context->ctrl_reg);
-
-	/* Check if conversion is stopped */
-	if (tmp & ME4000_AI_STATUS_BIT_FSM) {
-		printk(KERN_ERR
-		       "ME4000:ai_common_start():Conversion is not stopped\n");
-		return -EBUSY;
-	}
-
-	/* Clear data fifo, disable all interrupts, clear sample counter reload */
-	tmp &= ~(ME4000_AI_CTRL_BIT_DATA_FIFO | ME4000_AI_CTRL_BIT_LE_IRQ |
-		 ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
-		 ME4000_AI_CTRL_BIT_SC_RELOAD);
-
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	/* Clear circular buffer */
-	ai_context->circ_buf.head = 0;
-	ai_context->circ_buf.tail = 0;
-
-	/* Enable data fifo */
-	tmp |= ME4000_AI_CTRL_BIT_DATA_FIFO;
-
-	/* Determine interrupt setup */
-	if (ai_context->sample_counter && !ai_context->sample_counter_reload) {
-		/* Enable Half Full Interrupt and Sample Counter Interrupt */
-		tmp |= ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ;
-	} else if (ai_context->sample_counter
-		   && ai_context->sample_counter_reload) {
-		if (ai_context->sample_counter <= ME4000_AI_FIFO_COUNT / 2) {
-			/* Enable only Sample Counter Interrupt */
-			tmp |=
-			    ME4000_AI_CTRL_BIT_SC_IRQ |
-			    ME4000_AI_CTRL_BIT_SC_RELOAD;
-		} else {
-			/* Enable Half Full Interrupt and Sample Counter Interrupt */
-			tmp |=
-			    ME4000_AI_CTRL_BIT_SC_IRQ |
-			    ME4000_AI_CTRL_BIT_HF_IRQ |
-			    ME4000_AI_CTRL_BIT_SC_RELOAD;
-		}
-	} else {
-		/* Enable only Half Full Interrupt */
-		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
-	}
-
-	/* Clear the stop bits */
-	tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
-
-	/* Write setup to hardware */
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	/* Write sample counter */
-	me4000_outl(ai_context->sample_counter, ai_context->sample_counter_reg);
-
-	return 0;
-}
-
-static int me4000_ai_start(struct me4000_ai_context *ai_context)
-{
-	int err;
-	CALL_PDEBUG("me4000_ai_start() is executed\n");
-
-	/* Prepare Hardware */
-	err = ai_common_start(ai_context);
-	if (err)
-		return err;
-
-	/* Start conversion by dummy read */
-	me4000_inl(ai_context->start_reg);
-
-	return 0;
-}
-
-static int me4000_ai_start_ex(unsigned long *arg,
-			      struct me4000_ai_context *ai_context)
-{
-	int err;
-	wait_queue_head_t queue;
-	unsigned long ref;
-	unsigned long timeout;
-
-	CALL_PDEBUG("me4000_ai_start_ex() is executed\n");
-
-	if (get_user(timeout, arg)) {
-		printk(KERN_ERR
-		       "me4000_ai_start_ex():Cannot copy data from user\n");
-		return -EFAULT;
-	}
-
-	init_waitqueue_head(&queue);
-
-	/* Prepare Hardware */
-	err = ai_common_start(ai_context);
-	if (err)
-		return err;
-
-	if (timeout) {
-		ref = jiffies;
-		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;
-			}
-			/* 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)) {
-			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;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int me4000_ai_stop(struct me4000_ai_context *ai_context)
-{
-	wait_queue_head_t queue;
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ai_stop() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	/* Disable irqs and clear data fifo */
-	spin_lock_irqsave(&ai_context->int_lock, flags);
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &=
-	    ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
-	      ME4000_AI_CTRL_BIT_DATA_FIFO);
-	/* Stop conversion of the state machine */
-	tmp |= ME4000_AI_CTRL_BIT_STOP;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-	spin_unlock_irqrestore(&ai_context->int_lock, flags);
-
-	/* Clear circular buffer */
-	ai_context->circ_buf.head = 0;
-	ai_context->circ_buf.tail = 0;
-
-	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_stop():Wait on state machine after stop interrupted\n");
-			return -EINTR;
-		}
-	}
-
-	return 0;
-}
-
-static int me4000_ai_immediate_stop(struct me4000_ai_context *ai_context)
-{
-	wait_queue_head_t queue;
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ai_stop() is executed\n");
-
-	init_waitqueue_head(&queue);
-
-	/* Disable irqs and clear data fifo */
-	spin_lock_irqsave(&ai_context->int_lock, flags);
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &=
-	    ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
-	      ME4000_AI_CTRL_BIT_DATA_FIFO);
-	/* Stop conversion of the state machine */
-	tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-	spin_unlock_irqrestore(&ai_context->int_lock, flags);
-
-	/* Clear circular buffer */
-	ai_context->circ_buf.head = 0;
-	ai_context->circ_buf.tail = 0;
-
-	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_stop():Wait on state machine after stop interrupted\n");
-			return -EINTR;
-		}
-	}
-
-	return 0;
-}
-
-static int me4000_ai_ex_trig_enable(struct me4000_ai_context *ai_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ai_ex_trig_enable() is executed\n");
-
-	spin_lock_irqsave(&ai_context->int_lock, flags);
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp |= ME4000_AI_CTRL_BIT_EX_TRIG;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-	spin_unlock_irqrestore(&ai_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ai_ex_trig_disable(struct me4000_ai_context *ai_context)
-{
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ai_ex_trig_disable() is executed\n");
-
-	spin_lock_irqsave(&ai_context->int_lock, flags);
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-	spin_unlock_irqrestore(&ai_context->int_lock, flags);
-
-	return 0;
-}
-
-static int me4000_ai_ex_trig_setup(struct me4000_ai_trigger *arg,
-				   struct me4000_ai_context *ai_context)
-{
-	struct me4000_ai_trigger cmd;
-	int err;
-	u32 tmp;
-	unsigned long flags;
-
-	CALL_PDEBUG("me4000_ai_ex_trig_setup() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_trigger));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_ex_trig_setup():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	spin_lock_irqsave(&ai_context->int_lock, flags);
-	tmp = me4000_inl(ai_context->ctrl_reg);
-
-	if (cmd.mode == ME4000_AI_TRIGGER_EXT_DIGITAL) {
-		tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG;
-	} else if (cmd.mode == ME4000_AI_TRIGGER_EXT_ANALOG) {
-		if (!ai_context->board_info->board_p->ai.ex_trig_analog) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_ex_trig_setup():No analog trigger available\n");
-			return -EINVAL;
-		}
-		tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG;
-	} else {
-		spin_unlock_irqrestore(&ai_context->int_lock, flags);
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_ex_trig_setup():Invalid trigger mode specified\n");
-		return -EINVAL;
-	}
-
-	if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_RISING) {
-		tmp &=
-		    ~(ME4000_AI_CTRL_BIT_EX_TRIG_BOTH |
-		      ME4000_AI_CTRL_BIT_EX_TRIG_FALLING);
-	} else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_FALLING) {
-		tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_FALLING;
-		tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_BOTH;
-	} else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_BOTH) {
-		tmp |=
-		    ME4000_AI_CTRL_BIT_EX_TRIG_BOTH |
-		    ME4000_AI_CTRL_BIT_EX_TRIG_FALLING;
-	} else {
-		spin_unlock_irqrestore(&ai_context->int_lock, flags);
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_ex_trig_setup():Invalid trigger edge specified\n");
-		return -EINVAL;
-	}
-
-	me4000_outl(tmp, ai_context->ctrl_reg);
-	spin_unlock_irqrestore(&ai_context->int_lock, flags);
-	return 0;
-}
-
-static int me4000_ai_sc_setup(struct me4000_ai_sc *arg,
-			      struct me4000_ai_context *ai_context)
-{
-	struct me4000_ai_sc cmd;
-	int err;
-
-	CALL_PDEBUG("me4000_ai_sc_setup() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_ai_sc));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_sc_setup():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	ai_context->sample_counter = cmd.value;
-	ai_context->sample_counter_reload = cmd.reload;
-
-	return 0;
-}
-
-static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt,
-			      loff_t *offp)
-{
-	struct me4000_ai_context *ai_context = filep->private_data;
-	s16 *buffer = (s16 *) buff;
-	size_t count = cnt / 2;
-	unsigned long flags;
-	int tmp;
-	int c = 0;
-	int k = 0;
-	int ret = 0;
-	wait_queue_t wait;
-
-	CALL_PDEBUG("me4000_ai_read() is executed\n");
-
-	init_waitqueue_entry(&wait, current);
-
-	/* Check count */
-	if (count <= 0) {
-		PDEBUG("me4000_ai_read():Count is 0\n");
-		return 0;
-	}
-
-	while (count > 0) {
-		if (filep->f_flags & O_NONBLOCK) {
-			c = me4000_values_to_end(ai_context->circ_buf,
-						 ME4000_AI_BUFFER_COUNT);
-			if (!c) {
-				PDEBUG
-				    ("me4000_ai_read():Returning from nonblocking read\n");
-				break;
-			}
-		} else {
-			/* Check if conversion is still running */
-			if (!
-			    (me4000_inl(ai_context->status_reg) &
-			     ME4000_AI_STATUS_BIT_FSM)) {
-				printk(KERN_ERR
-				       "ME4000:me4000_ai_read():Conversion interrupted\n");
-				return -EPIPE;
-			}
-
-			wait_event_interruptible(ai_context->wait_queue,
-						 (me4000_values_to_end
-						  (ai_context->circ_buf,
-						   ME4000_AI_BUFFER_COUNT)));
-			if (signal_pending(current)) {
-				printk(KERN_ERR
-				       "ME4000:me4000_ai_read():Wait on values interrupted from signal\n");
-				return -EINTR;
-			}
-		}
-
-		/* Only read count values or as much as available */
-		c = me4000_values_to_end(ai_context->circ_buf,
-					 ME4000_AI_BUFFER_COUNT);
-		PDEBUG("me4000_ai_read():%d values to end\n", c);
-		if (count < c)
-			c = count;
-
-		PDEBUG("me4000_ai_read():Copy %d values to user space\n", c);
-		k = 2 * c;
-		k -= copy_to_user(buffer,
-				  ai_context->circ_buf.buf +
-				  ai_context->circ_buf.tail, k);
-		c = k / 2;
-		if (!c) {
-			printk(KERN_ERR
-			       "ME4000:me4000_ai_read():Cannot copy new values to user\n");
-			return -EFAULT;
-		}
-
-		ai_context->circ_buf.tail =
-		    (ai_context->circ_buf.tail + c) & (ME4000_AI_BUFFER_COUNT -
-						       1);
-		buffer += c;
-		count -= c;
-		ret += c;
-
-		spin_lock_irqsave(&ai_context->int_lock, flags);
-		if (me4000_buf_space
-		    (ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
-			tmp = me4000_inl(ai_context->ctrl_reg);
-
-			/* Determine interrupt setup */
-			if (ai_context->sample_counter
-			    && !ai_context->sample_counter_reload) {
-				/* Enable Half Full Interrupt and Sample Counter Interrupt */
-				tmp |=
-				    ME4000_AI_CTRL_BIT_SC_IRQ |
-				    ME4000_AI_CTRL_BIT_HF_IRQ;
-			} else if (ai_context->sample_counter
-				   && ai_context->sample_counter_reload) {
-				if (ai_context->sample_counter <
-				    ME4000_AI_FIFO_COUNT / 2) {
-					/* Enable only Sample Counter Interrupt */
-					tmp |= ME4000_AI_CTRL_BIT_SC_IRQ;
-				} else {
-					/* Enable Half Full Interrupt and Sample Counter Interrupt */
-					tmp |=
-					    ME4000_AI_CTRL_BIT_SC_IRQ |
-					    ME4000_AI_CTRL_BIT_HF_IRQ;
-				}
-			} else {
-				/* Enable only Half Full Interrupt */
-				tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
-			}
-
-			me4000_outl(tmp, ai_context->ctrl_reg);
-		}
-		spin_unlock_irqrestore(&ai_context->int_lock, flags);
-	}
-
-	/* Check if conversion is still running */
-	if (!(me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
-		printk(KERN_ERR
-		       "ME4000:me4000_ai_read():Conversion not running after complete read\n");
-		return -EPIPE;
-	}
-
-	if (filep->f_flags & O_NONBLOCK)
-		return (k == 0) ? -EAGAIN : 2 * ret;
-
-	CALL_PDEBUG("me4000_ai_read() is leaved\n");
-	return ret * 2;
-}
-
-static unsigned int me4000_ai_poll(struct file *file_p, poll_table *wait)
-{
-	struct me4000_ai_context *ai_context;
-	unsigned long mask = 0;
-
-	CALL_PDEBUG("me4000_ai_poll() is executed\n");
-
-	ai_context = file_p->private_data;
-
-	/* Register wait queue */
-	poll_wait(file_p, &ai_context->wait_queue, wait);
-
-	/* Get available values */
-	if (me4000_values_to_end(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT))
-		mask |= POLLIN | POLLRDNORM;
-
-	PDEBUG("me4000_ai_poll():Return mask %lX\n", mask);
-
-	return mask;
-}
-
-static int me4000_ai_offset_enable(struct me4000_ai_context *ai_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ai_offset_enable() is executed\n");
-
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp |= ME4000_AI_CTRL_BIT_OFFSET;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	return 0;
-}
-
-static int me4000_ai_offset_disable(struct me4000_ai_context *ai_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ai_offset_disable() is executed\n");
-
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &= ~ME4000_AI_CTRL_BIT_OFFSET;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	return 0;
-}
-
-static int me4000_ai_fullscale_enable(struct me4000_ai_context *ai_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ai_fullscale_enable() is executed\n");
-
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp |= ME4000_AI_CTRL_BIT_FULLSCALE;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	return 0;
-}
-
-static int me4000_ai_fullscale_disable(struct me4000_ai_context *ai_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ai_fullscale_disable() is executed\n");
-
-	tmp = me4000_inl(ai_context->ctrl_reg);
-	tmp &= ~ME4000_AI_CTRL_BIT_FULLSCALE;
-	me4000_outl(tmp, ai_context->ctrl_reg);
-
-	return 0;
-}
-
-static int me4000_ai_fsm_state(int *arg, struct me4000_ai_context *ai_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ai_fsm_state() is executed\n");
-
-	tmp =
-	    (me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) ? 1
-	    : 0;
-
-	if (put_user(tmp, arg)) {
-		printk(KERN_ERR "me4000_ai_fsm_state():Cannot copy to user\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int me4000_ai_get_count_buffer(unsigned long *arg,
-				      struct me4000_ai_context *ai_context)
-{
-	unsigned long c;
-	int err;
-
-	c = me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT);
-
-	err = copy_to_user(arg, &c, sizeof(unsigned long));
-	if (err) {
-		printk(KERN_ERR
-		       "%s:Can't copy to user space\n", __func__);
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-/*---------------------------------- EEPROM stuff ---------------------------*/
-
-static int eeprom_write_cmd(struct me4000_ai_context *ai_context, unsigned long cmd,
-			    int length)
-{
-	int i;
-	unsigned long value;
-
-	CALL_PDEBUG("eeprom_write_cmd() is executed\n");
-
-	PDEBUG("eeprom_write_cmd():Write command 0x%08lX with length = %d\n",
-	       cmd, length);
-
-	/* Get the ICR register and clear the related bits */
-	value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR);
-	value &= ~(PLX_ICR_MASK_EEPROM);
-	me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-
-	/* Raise the chip select */
-	value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-	me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-	udelay(EEPROM_DELAY);
-
-	for (i = 0; i < length; i++) {
-		if (cmd & ((0x1 << (length - 1)) >> i))
-			value |= PLX_ICR_BIT_EEPROM_WRITE;
-		else
-			value &= ~PLX_ICR_BIT_EEPROM_WRITE;
-
-		/* Write to EEPROM */
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-
-		/* Raising edge of the clock */
-		value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-
-		/* Falling edge of the clock */
-		value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-	}
-
-	/* Clear the chip select */
-	value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-	me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-	udelay(EEPROM_DELAY);
-
-	/* Wait until hardware is ready for sure */
-	mdelay(10);
-
-	return 0;
-}
-
-static unsigned short eeprom_read_cmd(struct me4000_ai_context *ai_context,
-				      unsigned long cmd, int length)
-{
-	int i;
-	unsigned long value;
-	unsigned short id = 0;
-
-	CALL_PDEBUG("eeprom_read_cmd() is executed\n");
-
-	PDEBUG("eeprom_read_cmd():Read command 0x%08lX with length = %d\n", cmd,
-	       length);
-
-	/* Get the ICR register and clear the related bits */
-	value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR);
-	value &= ~(PLX_ICR_MASK_EEPROM);
-
-	me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-
-	/* Raise the chip select */
-	value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-	me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-	udelay(EEPROM_DELAY);
-
-	/* Write the read command to the eeprom */
-	for (i = 0; i < length; i++) {
-		if (cmd & ((0x1 << (length - 1)) >> i))
-			value |= PLX_ICR_BIT_EEPROM_WRITE;
-		else
-			value &= ~PLX_ICR_BIT_EEPROM_WRITE;
-
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-
-		/* Raising edge of the clock */
-		value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-
-		/* Falling edge of the clock */
-		value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-	}
-
-	/* Read the value from the eeprom */
-	for (i = 0; i < 16; i++) {
-		/* Raising edge of the clock */
-		value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-
-		if (me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR) &
-		    PLX_ICR_BIT_EEPROM_READ) {
-			id |= (0x8000 >> i);
-			PDEBUG("eeprom_read_cmd():OR with 0x%04X\n",
-			       (0x8000 >> i));
-		} else {
-			PDEBUG("eeprom_read_cmd():Dont't OR\n");
-		}
-
-		/* Falling edge of the clock */
-		value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
-		me4000_outl(value,
-			    ai_context->board_info->plx_regbase + PLX_ICR);
-		udelay(EEPROM_DELAY);
-	}
-
-	/* Clear the chip select */
-	value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT;
-	me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
-	udelay(EEPROM_DELAY);
-
-	return id;
-}
-
-static int me4000_eeprom_write(struct me4000_eeprom *arg,
-			       struct me4000_ai_context *ai_context)
-{
-	int err;
-	struct me4000_eeprom setup;
-	unsigned long cmd;
-	unsigned long date_high;
-	unsigned long date_low;
-
-	CALL_PDEBUG("me4000_eeprom_write() is executed\n");
-
-	err = copy_from_user(&setup, arg, sizeof(setup));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_eeprom_write():Cannot copy from user\n");
-		return err;
-	}
-
-	/* Enable writing */
-	eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_ENABLE,
-			 ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE);
-
-	/* Command for date */
-	date_high = (setup.date & 0xFFFF0000) >> 16;
-	date_low = (setup.date & 0x0000FFFF);
-
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_HIGH <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     date_high);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_LOW <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     date_low);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for unipolar 10V offset */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     uni_10_offset);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for unipolar 10V fullscale */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     uni_10_fullscale);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for unipolar 2,5V offset */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     uni_2_5_offset);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for unipolar 2,5V fullscale */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     uni_2_5_fullscale);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for bipolar 10V offset */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     bi_10_offset);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for bipolar 10V fullscale */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     bi_10_fullscale);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for bipolar 2,5V offset */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     bi_2_5_offset);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for bipolar 2,5V fullscale */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     bi_2_5_fullscale);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for differential 10V offset */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     diff_10_offset);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for differential 10V fullscale */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE
-				       << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-									(unsigned
-									 long)
-									setup.
-									diff_10_fullscale);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for differential 2,5V offset */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET <<
-				       ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-								     (unsigned
-								      long)
-								     setup.
-								     diff_2_5_offset);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Command for differential 2,5V fullscale */
-	cmd =
-	    ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE
-				       << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
-									(unsigned
-									 long)
-									setup.
-									diff_2_5_fullscale);
-	err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
-	if (err)
-		return err;
-
-	/* Disable writing */
-	eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_DISABLE,
-			 ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE);
-
-	return 0;
-}
-
-static int me4000_eeprom_read(struct me4000_eeprom *arg,
-			      struct me4000_ai_context *ai_context)
-{
-	int err;
-	unsigned long cmd;
-	struct me4000_eeprom setup;
-
-	CALL_PDEBUG("me4000_eeprom_read() is executed\n");
-
-	/* Command for date */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_HIGH;
-	setup.date =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-	setup.date <<= 16;
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_LOW;
-	setup.date |=
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for unipolar 10V offset */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET;
-	setup.uni_10_offset =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for unipolar 10V fullscale */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE;
-	setup.uni_10_fullscale =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for unipolar 2,5V offset */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET;
-	setup.uni_2_5_offset =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for unipolar 2,5V fullscale */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE;
-	setup.uni_2_5_fullscale =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for bipolar 10V offset */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET;
-	setup.bi_10_offset =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for bipolar 10V fullscale */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE;
-	setup.bi_10_fullscale =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for bipolar 2,5V offset */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET;
-	setup.bi_2_5_offset =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for bipolar 2,5V fullscale */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE;
-	setup.bi_2_5_fullscale =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for differntial 10V offset */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET;
-	setup.diff_10_offset =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for differential 10V fullscale */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE;
-	setup.diff_10_fullscale =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for differntial 2,5V offset */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET;
-	setup.diff_2_5_offset =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	/* Command for differential 2,5V fullscale */
-	cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE;
-	setup.diff_2_5_fullscale =
-	    eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
-
-	err = copy_to_user(arg, &setup, sizeof(setup));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_eeprom_read():Cannot copy to user\n");
-		return err;
-	}
-
-	return 0;
-}
-
-/*------------------------------------ DIO stuff ----------------------------------------------*/
-
-static int me4000_dio_ioctl(struct inode *inode_p, struct file *file_p,
-			    unsigned int service, unsigned long arg)
-{
-	struct me4000_dio_context *dio_context;
-
-	CALL_PDEBUG("me4000_dio_ioctl() is executed\n");
-
-	dio_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n");
-		return -ENOTTY;
-	}
-	if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-		printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n");
-		return -ENOTTY;
-	}
-
-	switch (service) {
-	case ME4000_DIO_CONFIG:
-		return me4000_dio_config((struct me4000_dio_config *)arg,
-					 dio_context);
-	case ME4000_DIO_SET_BYTE:
-		return me4000_dio_set_byte((struct me4000_dio_byte *)arg,
-					   dio_context);
-	case ME4000_DIO_GET_BYTE:
-		return me4000_dio_get_byte((struct me4000_dio_byte *)arg,
-					   dio_context);
-	case ME4000_DIO_RESET:
-		return me4000_dio_reset(dio_context);
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_ioctl():Invalid service number %d\n",
-		       service);
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_dio_config(struct me4000_dio_config *arg,
-			     struct me4000_dio_context *dio_context)
-{
-	struct me4000_dio_config cmd;
-	u32 tmp;
-	int err;
-
-	CALL_PDEBUG("me4000_dio_config() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_config));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_config():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	/* Check port parameter */
-	if (cmd.port >= dio_context->dio_count) {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_config():Port %d is not available\n",
-		       cmd.port);
-		return -EINVAL;
-	}
-
-	PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port,
-	       cmd.mode, cmd.function);
-
-	if (cmd.port == ME4000_DIO_PORT_A) {
-		if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-			/* Check if opto isolated version */
-			if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-				printk(KERN_ERR
-				       "ME4000:me4000_dio_config():Cannot set to input on opto isolated versions\n");
-				return -EIO;
-			}
-
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-			      ME4000_DIO_CTRL_BIT_MODE_1);
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-			      ME4000_DIO_CTRL_BIT_MODE_1);
-			tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-			      ME4000_DIO_CTRL_BIT_MODE_1 |
-			      ME4000_DIO_CTRL_BIT_FIFO_HIGH_0);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_0 |
-			    ME4000_DIO_CTRL_BIT_MODE_1;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_0 |
-			    ME4000_DIO_CTRL_BIT_MODE_1 |
-			    ME4000_DIO_CTRL_BIT_FIFO_HIGH_0;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_config():Mode %d is not available\n",
-			       cmd.mode);
-			return -EINVAL;
-		}
-	} else if (cmd.port == ME4000_DIO_PORT_B) {
-		if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-			/* Only do anything when TTL version is installed */
-			if ((me4000_inl(dio_context->dir_reg) & 0x1)) {
-				tmp = me4000_inl(dio_context->ctrl_reg);
-				tmp &=
-				    ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-				      ME4000_DIO_CTRL_BIT_MODE_3);
-				me4000_outl(tmp, dio_context->ctrl_reg);
-			}
-		} else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-			/* Check if opto isolated version */
-			if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-				printk(KERN_ERR
-				       "ME4000:me4000_dio_config():Cannot set to output on opto isolated versions\n");
-				return -EIO;
-			}
-
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-			      ME4000_DIO_CTRL_BIT_MODE_3);
-			tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-			/* Check if opto isolated version */
-			if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-				printk(KERN_ERR
-				       "ME4000:me4000_dio_config():Cannot set to FIFO low output on opto isolated versions\n");
-				return -EIO;
-			}
-
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-			      ME4000_DIO_CTRL_BIT_MODE_3 |
-			      ME4000_DIO_CTRL_BIT_FIFO_HIGH_1);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_2 |
-			    ME4000_DIO_CTRL_BIT_MODE_3;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-			/* Check if opto isolated version */
-			if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-				printk(KERN_ERR
-				       "ME4000:me4000_dio_config():Cannot set to FIFO high output on opto isolated versions\n");
-				return -EIO;
-			}
-
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_2 |
-			    ME4000_DIO_CTRL_BIT_MODE_3 |
-			    ME4000_DIO_CTRL_BIT_FIFO_HIGH_1;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_config():Mode %d is not available\n",
-			       cmd.mode);
-			return -EINVAL;
-		}
-	} else if (cmd.port == ME4000_DIO_PORT_C) {
-		if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-			      ME4000_DIO_CTRL_BIT_MODE_5);
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-			      ME4000_DIO_CTRL_BIT_MODE_5);
-			tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-			      ME4000_DIO_CTRL_BIT_MODE_5 |
-			      ME4000_DIO_CTRL_BIT_FIFO_HIGH_2);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_4 |
-			    ME4000_DIO_CTRL_BIT_MODE_5;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_4 |
-			    ME4000_DIO_CTRL_BIT_MODE_5 |
-			    ME4000_DIO_CTRL_BIT_FIFO_HIGH_2;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_config():Mode %d is not available\n",
-			       cmd.mode);
-			return -EINVAL;
-		}
-	} else if (cmd.port == ME4000_DIO_PORT_D) {
-		if (cmd.mode == ME4000_DIO_PORT_INPUT) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-			      ME4000_DIO_CTRL_BIT_MODE_7);
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-			      ME4000_DIO_CTRL_BIT_MODE_7);
-			tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp &=
-			    ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-			      ME4000_DIO_CTRL_BIT_MODE_7 |
-			      ME4000_DIO_CTRL_BIT_FIFO_HIGH_3);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_6 |
-			    ME4000_DIO_CTRL_BIT_MODE_7;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
-			tmp = me4000_inl(dio_context->ctrl_reg);
-			tmp |=
-			    ME4000_DIO_CTRL_BIT_MODE_6 |
-			    ME4000_DIO_CTRL_BIT_MODE_7 |
-			    ME4000_DIO_CTRL_BIT_FIFO_HIGH_3;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_config():Mode %d is not available\n",
-			       cmd.mode);
-			return -EINVAL;
-		}
-	} else {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_config():Port %d is not available\n",
-		       cmd.port);
-		return -EINVAL;
-	}
-
-	PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port,
-	       cmd.mode, cmd.function);
-
-	if ((cmd.mode == ME4000_DIO_FIFO_HIGH)
-	    || (cmd.mode == ME4000_DIO_FIFO_LOW)) {
-		tmp = me4000_inl(dio_context->ctrl_reg);
-		tmp &=
-		    ~(ME4000_DIO_CTRL_BIT_FUNCTION_0 |
-		      ME4000_DIO_CTRL_BIT_FUNCTION_1);
-		if (cmd.function == ME4000_DIO_FUNCTION_PATTERN) {
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.function == ME4000_DIO_FUNCTION_DEMUX) {
-			tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_0;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else if (cmd.function == ME4000_DIO_FUNCTION_MUX) {
-			tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_1;
-			me4000_outl(tmp, dio_context->ctrl_reg);
-		} else {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_config():Invalid port function specified\n");
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-static int me4000_dio_set_byte(struct me4000_dio_byte *arg,
-			       struct me4000_dio_context *dio_context)
-{
-	struct me4000_dio_byte cmd;
-	int err;
-
-	CALL_PDEBUG("me4000_dio_set_byte() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_byte));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_set_byte():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	/* Check port parameter */
-	if (cmd.port >= dio_context->dio_count) {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_set_byte():Port %d is not available\n",
-		       cmd.port);
-		return -EINVAL;
-	}
-
-	if (cmd.port == ME4000_DIO_PORT_A) {
-		if ((me4000_inl(dio_context->ctrl_reg) & 0x3) != 0x1) {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-			       cmd.port);
-			return -EIO;
-		}
-		me4000_outl(cmd.byte, dio_context->port_0_reg);
-	} else if (cmd.port == ME4000_DIO_PORT_B) {
-		if ((me4000_inl(dio_context->ctrl_reg) & 0xC) != 0x4) {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-			       cmd.port);
-			return -EIO;
-		}
-		me4000_outl(cmd.byte, dio_context->port_1_reg);
-	} else if (cmd.port == ME4000_DIO_PORT_C) {
-		if ((me4000_inl(dio_context->ctrl_reg) & 0x30) != 0x10) {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-			       cmd.port);
-			return -EIO;
-		}
-		me4000_outl(cmd.byte, dio_context->port_2_reg);
-	} else if (cmd.port == ME4000_DIO_PORT_D) {
-		if ((me4000_inl(dio_context->ctrl_reg) & 0xC0) != 0x40) {
-			printk(KERN_ERR
-			       "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
-			       cmd.port);
-			return -EIO;
-		}
-		me4000_outl(cmd.byte, dio_context->port_3_reg);
-	} else {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_set_byte():Port %d is not available\n",
-		       cmd.port);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int me4000_dio_get_byte(struct me4000_dio_byte *arg,
-			       struct me4000_dio_context *dio_context)
-{
-	struct me4000_dio_byte cmd;
-	int err;
-
-	CALL_PDEBUG("me4000_dio_get_byte() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_dio_byte));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_get_byte():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	/* Check port parameter */
-	if (cmd.port >= dio_context->dio_count) {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_get_byte():Port %d is not available\n",
-		       cmd.port);
-		return -EINVAL;
-	}
-
-	if (cmd.port == ME4000_DIO_PORT_A) {
-		cmd.byte = me4000_inl(dio_context->port_0_reg) & 0xFF;
-	} else if (cmd.port == ME4000_DIO_PORT_B) {
-		cmd.byte = me4000_inl(dio_context->port_1_reg) & 0xFF;
-	} else if (cmd.port == ME4000_DIO_PORT_C) {
-		cmd.byte = me4000_inl(dio_context->port_2_reg) & 0xFF;
-	} else if (cmd.port == ME4000_DIO_PORT_D) {
-		cmd.byte = me4000_inl(dio_context->port_3_reg) & 0xFF;
-	} else {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_get_byte():Port %d is not available\n",
-		       cmd.port);
-		return -EINVAL;
-	}
-
-	/* Copy result back to user */
-	err = copy_to_user(arg, &cmd, sizeof(struct me4000_dio_byte));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_get_byte():Can't copy to user space\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int me4000_dio_reset(struct me4000_dio_context *dio_context)
-{
-	CALL_PDEBUG("me4000_dio_reset() is executed\n");
-
-	/* Clear the control register */
-	me4000_outl(0, dio_context->ctrl_reg);
-
-	/* Check for opto isolated version */
-	if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
-		me4000_outl(0x1, dio_context->ctrl_reg);
-		me4000_outl(0x0, dio_context->port_0_reg);
-	}
-
-	return 0;
-}
-
-/*------------------------------------ COUNTER STUFF ------------------------------------*/
-
-static int me4000_cnt_ioctl(struct inode *inode_p, struct file *file_p,
-			    unsigned int service, unsigned long arg)
-{
-	struct me4000_cnt_context *cnt_context;
-
-	CALL_PDEBUG("me4000_cnt_ioctl() is executed\n");
-
-	cnt_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n");
-		return -ENOTTY;
-	}
-	if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-		printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n");
-		return -ENOTTY;
-	}
-
-	switch (service) {
-	case ME4000_CNT_READ:
-		return me4000_cnt_read((struct me4000_cnt *)arg, cnt_context);
-	case ME4000_CNT_WRITE:
-		return me4000_cnt_write((struct me4000_cnt *)arg, cnt_context);
-	case ME4000_CNT_CONFIG:
-		return me4000_cnt_config((struct me4000_cnt_config *)arg,
-					 cnt_context);
-	case ME4000_CNT_RESET:
-		return me4000_cnt_reset(cnt_context);
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_dio_ioctl():Invalid service number %d\n",
-		       service);
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_cnt_config(struct me4000_cnt_config *arg,
-			     struct me4000_cnt_context *cnt_context)
-{
-	struct me4000_cnt_config cmd;
-	u8 counter;
-	u8 mode;
-	int err;
-
-	CALL_PDEBUG("me4000_cnt_config() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt_config));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_config():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	/* Check counter parameter */
-	switch (cmd.counter) {
-	case ME4000_CNT_COUNTER_0:
-		counter = ME4000_CNT_CTRL_BIT_COUNTER_0;
-		break;
-	case ME4000_CNT_COUNTER_1:
-		counter = ME4000_CNT_CTRL_BIT_COUNTER_1;
-		break;
-	case ME4000_CNT_COUNTER_2:
-		counter = ME4000_CNT_CTRL_BIT_COUNTER_2;
-		break;
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_config():Counter %d is not available\n",
-		       cmd.counter);
-		return -EINVAL;
-	}
-
-	/* Check mode parameter */
-	switch (cmd.mode) {
-	case ME4000_CNT_MODE_0:
-		mode = ME4000_CNT_CTRL_BIT_MODE_0;
-		break;
-	case ME4000_CNT_MODE_1:
-		mode = ME4000_CNT_CTRL_BIT_MODE_1;
-		break;
-	case ME4000_CNT_MODE_2:
-		mode = ME4000_CNT_CTRL_BIT_MODE_2;
-		break;
-	case ME4000_CNT_MODE_3:
-		mode = ME4000_CNT_CTRL_BIT_MODE_3;
-		break;
-	case ME4000_CNT_MODE_4:
-		mode = ME4000_CNT_CTRL_BIT_MODE_4;
-		break;
-	case ME4000_CNT_MODE_5:
-		mode = ME4000_CNT_CTRL_BIT_MODE_5;
-		break;
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_config():Mode %d is not available\n",
-		       cmd.mode);
-		return -EINVAL;
-	}
-
-	/* Write the control word */
-	me4000_outb((counter | mode | 0x30), cnt_context->ctrl_reg);
-
-	return 0;
-}
-
-static int me4000_cnt_read(struct me4000_cnt *arg,
-			   struct me4000_cnt_context *cnt_context)
-{
-	struct me4000_cnt cmd;
-	u8 tmp;
-	int err;
-
-	CALL_PDEBUG("me4000_cnt_read() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_read():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	/* Read counter */
-	switch (cmd.counter) {
-	case ME4000_CNT_COUNTER_0:
-		tmp = me4000_inb(cnt_context->counter_0_reg);
-		cmd.value = tmp;
-		tmp = me4000_inb(cnt_context->counter_0_reg);
-		cmd.value |= ((u16) tmp) << 8;
-		break;
-	case ME4000_CNT_COUNTER_1:
-		tmp = me4000_inb(cnt_context->counter_1_reg);
-		cmd.value = tmp;
-		tmp = me4000_inb(cnt_context->counter_1_reg);
-		cmd.value |= ((u16) tmp) << 8;
-		break;
-	case ME4000_CNT_COUNTER_2:
-		tmp = me4000_inb(cnt_context->counter_2_reg);
-		cmd.value = tmp;
-		tmp = me4000_inb(cnt_context->counter_2_reg);
-		cmd.value |= ((u16) tmp) << 8;
-		break;
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_read():Counter %d is not available\n",
-		       cmd.counter);
-		return -EINVAL;
-	}
-
-	/* Copy result back to user */
-	err = copy_to_user(arg, &cmd, sizeof(struct me4000_cnt));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_read():Can't copy to user space\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int me4000_cnt_write(struct me4000_cnt *arg,
-			    struct me4000_cnt_context *cnt_context)
-{
-	struct me4000_cnt cmd;
-	u8 tmp;
-	int err;
-
-	CALL_PDEBUG("me4000_cnt_write() is executed\n");
-
-	/* Copy data from user */
-	err = copy_from_user(&cmd, arg, sizeof(struct me4000_cnt));
-	if (err) {
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_write():Can't copy from user space\n");
-		return -EFAULT;
-	}
-
-	/* Write counter */
-	switch (cmd.counter) {
-	case ME4000_CNT_COUNTER_0:
-		tmp = cmd.value & 0xFF;
-		me4000_outb(tmp, cnt_context->counter_0_reg);
-		tmp = (cmd.value >> 8) & 0xFF;
-		me4000_outb(tmp, cnt_context->counter_0_reg);
-		break;
-	case ME4000_CNT_COUNTER_1:
-		tmp = cmd.value & 0xFF;
-		me4000_outb(tmp, cnt_context->counter_1_reg);
-		tmp = (cmd.value >> 8) & 0xFF;
-		me4000_outb(tmp, cnt_context->counter_1_reg);
-		break;
-	case ME4000_CNT_COUNTER_2:
-		tmp = cmd.value & 0xFF;
-		me4000_outb(tmp, cnt_context->counter_2_reg);
-		tmp = (cmd.value >> 8) & 0xFF;
-		me4000_outb(tmp, cnt_context->counter_2_reg);
-		break;
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_cnt_write():Counter %d is not available\n",
-		       cmd.counter);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int me4000_cnt_reset(struct me4000_cnt_context *cnt_context)
-{
-	CALL_PDEBUG("me4000_cnt_reset() is executed\n");
-
-	/* Set the mode and value for counter 0 */
-	me4000_outb(0x30, cnt_context->ctrl_reg);
-	me4000_outb(0x00, cnt_context->counter_0_reg);
-	me4000_outb(0x00, cnt_context->counter_0_reg);
-
-	/* Set the mode and value for counter 1 */
-	me4000_outb(0x70, cnt_context->ctrl_reg);
-	me4000_outb(0x00, cnt_context->counter_1_reg);
-	me4000_outb(0x00, cnt_context->counter_1_reg);
-
-	/* Set the mode and value for counter 2 */
-	me4000_outb(0xB0, cnt_context->ctrl_reg);
-	me4000_outb(0x00, cnt_context->counter_2_reg);
-	me4000_outb(0x00, cnt_context->counter_2_reg);
-
-	return 0;
-}
-
-/*------------------------------------ External Interrupt stuff ------------------------------------*/
-
-static int me4000_ext_int_ioctl(struct inode *inode_p, struct file *file_p,
-				unsigned int service, unsigned long arg)
-{
-	struct me4000_ext_int_context *ext_int_context;
-
-	CALL_PDEBUG("me4000_ext_int_ioctl() is executed\n");
-
-	ext_int_context = file_p->private_data;
-
-	if (_IOC_TYPE(service) != ME4000_MAGIC) {
-		printk(KERN_ERR "me4000_ext_int_ioctl():Wrong magic number\n");
-		return -ENOTTY;
-	}
-	if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
-		printk(KERN_ERR
-		       "me4000_ext_int_ioctl():Service number to high\n");
-		return -ENOTTY;
-	}
-
-	switch (service) {
-	case ME4000_EXT_INT_ENABLE:
-		return me4000_ext_int_enable(ext_int_context);
-	case ME4000_EXT_INT_DISABLE:
-		return me4000_ext_int_disable(ext_int_context);
-	case ME4000_EXT_INT_COUNT:
-		return me4000_ext_int_count((unsigned long *)arg,
-					    ext_int_context);
-	default:
-		printk(KERN_ERR
-		       "ME4000:me4000_ext_int_ioctl():Invalid service number %d\n",
-		       service);
-		return -ENOTTY;
-	}
-	return 0;
-}
-
-static int me4000_ext_int_enable(struct me4000_ext_int_context *ext_int_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ext_int_enable() is executed\n");
-
-	tmp = me4000_inl(ext_int_context->ctrl_reg);
-	tmp |= ME4000_AI_CTRL_BIT_EX_IRQ;
-	me4000_outl(tmp, ext_int_context->ctrl_reg);
-
-	return 0;
-}
-
-static int me4000_ext_int_disable(struct me4000_ext_int_context *ext_int_context)
-{
-	unsigned long tmp;
-
-	CALL_PDEBUG("me4000_ext_int_disable() is executed\n");
-
-	tmp = me4000_inl(ext_int_context->ctrl_reg);
-	tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ;
-	me4000_outl(tmp, ext_int_context->ctrl_reg);
-
-	return 0;
-}
-
-static int me4000_ext_int_count(unsigned long *arg,
-				struct me4000_ext_int_context *ext_int_context)
-{
-
-	CALL_PDEBUG("me4000_ext_int_count() is executed\n");
-
-	put_user(ext_int_context->int_count, arg);
-	return 0;
-}
-
-/*------------------------------------ General stuff ------------------------------------*/
-
-static int me4000_get_user_info(struct me4000_user_info *arg,
-				struct me4000_info *board_info)
-{
-	struct me4000_user_info user_info;
-
-	CALL_PDEBUG("me4000_get_user_info() is executed\n");
-
-	user_info.board_count = board_info->board_count;
-	user_info.plx_regbase = board_info->plx_regbase;
-	user_info.plx_regbase_size = board_info->plx_regbase_size;
-	user_info.me4000_regbase = board_info->me4000_regbase;
-	user_info.me4000_regbase_size = board_info->me4000_regbase_size;
-	user_info.serial_no = board_info->serial_no;
-	user_info.hw_revision = board_info->hw_revision;
-	user_info.vendor_id = board_info->vendor_id;
-	user_info.device_id = board_info->device_id;
-	user_info.pci_bus_no = board_info->pci_bus_no;
-	user_info.pci_dev_no = board_info->pci_dev_no;
-	user_info.pci_func_no = board_info->pci_func_no;
-	user_info.irq = board_info->irq;
-	user_info.irq_count = board_info->irq_count;
-	user_info.driver_version = ME4000_DRIVER_VERSION;
-	user_info.ao_count = board_info->board_p->ao.count;
-	user_info.ao_fifo_count = board_info->board_p->ao.fifo_count;
-
-	user_info.ai_count = board_info->board_p->ai.count;
-	user_info.ai_sh_count = board_info->board_p->ai.sh_count;
-	user_info.ai_ex_trig_analog = board_info->board_p->ai.ex_trig_analog;
-
-	user_info.dio_count = board_info->board_p->dio.count;
-
-	user_info.cnt_count = board_info->board_p->cnt.count;
-
-	if (copy_to_user(arg, &user_info, sizeof(struct me4000_user_info)))
-		return -EFAULT;
-
-	return 0;
-}
-
-/*------------------------------------ ISR STUFF ------------------------------------*/
-
-static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode)
-{
-	int result = 0;
-	struct me4000_ext_int_context *ext_int_context;
-
-	CALL_PDEBUG("me4000_ext_int_fasync() is executed\n");
-
-	ext_int_context = file_ptr->private_data;
-
-	result =
-	    fasync_helper(fd, file_ptr, mode, &ext_int_context->fasync_ptr);
-
-	CALL_PDEBUG("me4000_ext_int_fasync() is leaved\n");
-	return result;
-}
-
-static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
-{
-	u32 tmp;
-	u32 value;
-	struct me4000_ao_context *ao_context;
-	int i;
-	int c = 0;
-	int c1 = 0;
-
-	ISR_PDEBUG("me4000_ao_isr() is executed\n");
-
-	ao_context = dev_id;
-
-	/* Check if irq number is right */
-	if (irq != ao_context->irq) {
-		ISR_PDEBUG("me4000_ao_isr():incorrect interrupt num: %d\n",
-			   irq);
-		return IRQ_NONE;
-	}
-
-	/* Check if this DAC rised an interrupt */
-	if (!
-	    ((0x1 << (ao_context->index + 3)) &
-	     me4000_inl(ao_context->irq_status_reg))) {
-		ISR_PDEBUG("me4000_ao_isr():Not this DAC\n");
-		return IRQ_NONE;
-	}
-
-	/* Read status register to find out what happened */
-	tmp = me4000_inl(ao_context->status_reg);
-
-	if (!(tmp & ME4000_AO_STATUS_BIT_EF) && (tmp & ME4000_AO_STATUS_BIT_HF)
-	    && (tmp & ME4000_AO_STATUS_BIT_HF)) {
-		c = ME4000_AO_FIFO_COUNT;
-		ISR_PDEBUG("me4000_ao_isr():Fifo empty\n");
-	} else if ((tmp & ME4000_AO_STATUS_BIT_EF)
-		   && (tmp & ME4000_AO_STATUS_BIT_HF)
-		   && (tmp & ME4000_AO_STATUS_BIT_HF)) {
-		c = ME4000_AO_FIFO_COUNT / 2;
-		ISR_PDEBUG("me4000_ao_isr():Fifo under half full\n");
-	} else {
-		c = 0;
-		ISR_PDEBUG("me4000_ao_isr():Fifo full\n");
-	}
-
-	ISR_PDEBUG("me4000_ao_isr():Try to write 0x%04X values\n", c);
-
-	while (1) {
-		c1 = me4000_values_to_end(ao_context->circ_buf,
-					  ME4000_AO_BUFFER_COUNT);
-		ISR_PDEBUG("me4000_ao_isr():Values to end = %d\n", c1);
-		if (c1 > c)
-			c1 = c;
-
-		if (c1 <= 0) {
-			ISR_PDEBUG
-			    ("me4000_ao_isr():Work done or buffer empty\n");
-			break;
-		}
-		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++) {
-				value =
-				    ((u32)
-				     (*
-				      (ao_context->circ_buf.buf +
-				       ao_context->circ_buf.tail + i))) << 16;
-				outl(value, ao_context->fifo_reg);
-			}
-		} else
-			outsw(ao_context->fifo_reg,
-			      ao_context->circ_buf.buf +
-			      ao_context->circ_buf.tail, c1);
-
-
-		ao_context->circ_buf.tail =
-		    (ao_context->circ_buf.tail + c1) & (ME4000_AO_BUFFER_COUNT -
-							1);
-		ISR_PDEBUG("me4000_ao_isr():%d values wrote to port 0x%04X\n",
-			   c1, ao_context->fifo_reg);
-		c -= c1;
-	}
-
-	/* If there are no values left in the buffer, disable interrupts */
-	spin_lock(&ao_context->int_lock);
-	if (!me4000_buf_count(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
-		ISR_PDEBUG
-		    ("me4000_ao_isr():Disable Interrupt because no values left in buffer\n");
-		tmp = me4000_inl(ao_context->ctrl_reg);
-		tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;
-		me4000_outl(tmp, ao_context->ctrl_reg);
-	}
-	spin_unlock(&ao_context->int_lock);
-
-	/* Reset the interrupt */
-	spin_lock(&ao_context->int_lock);
-	tmp = me4000_inl(ao_context->ctrl_reg);
-	tmp |= ME4000_AO_CTRL_BIT_RESET_IRQ;
-	me4000_outl(tmp, ao_context->ctrl_reg);
-	tmp &= ~ME4000_AO_CTRL_BIT_RESET_IRQ;
-	me4000_outl(tmp, ao_context->ctrl_reg);
-
-	/* 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");
-		/* 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);
-
-	/* Wake up waiting process */
-	wake_up_interruptible(&(ao_context->wait_queue));
-
-	/* Count the interrupt */
-	ao_context->board_info->irq_count++;
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
-{
-	u32 tmp;
-	struct me4000_ai_context *ai_context;
-	int i;
-	int c = 0;
-	int c1 = 0;
-#ifdef ME4000_ISR_DEBUG
-	unsigned long before;
-	unsigned long after;
-#endif
-
-	ISR_PDEBUG("me4000_ai_isr() is executed\n");
-
-#ifdef ME4000_ISR_DEBUG
-	rdtscl(before);
-#endif
-
-	ai_context = dev_id;
-
-	/* Check if irq number is right */
-	if (irq != ai_context->irq) {
-		ISR_PDEBUG("me4000_ai_isr():incorrect interrupt num: %d\n",
-			   irq);
-		return IRQ_NONE;
-	}
-
-	if (me4000_inl(ai_context->irq_status_reg) &
-	    ME4000_IRQ_STATUS_BIT_AI_HF) {
-		ISR_PDEBUG
-		    ("me4000_ai_isr():Fifo half full interrupt occured\n");
-
-		/* Read status register to find out what happened */
-		tmp = me4000_inl(ai_context->ctrl_reg);
-
-		if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-		    !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-		    && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-			ISR_PDEBUG("me4000_ai_isr():Fifo full\n");
-			c = ME4000_AI_FIFO_COUNT;
-
-			/* FIFO overflow, so stop conversion and disable all interrupts */
-			spin_lock(&ai_context->int_lock);
-			tmp = me4000_inl(ai_context->ctrl_reg);
-			tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-			tmp &=
-			    ~(ME4000_AI_CTRL_BIT_HF_IRQ |
-			      ME4000_AI_CTRL_BIT_SC_IRQ);
-			outl(tmp, ai_context->ctrl_reg);
-			spin_unlock(&ai_context->int_lock);
-		} else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-			   !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-			   && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-			ISR_PDEBUG("me4000_ai_isr():Fifo half full\n");
-			c = ME4000_AI_FIFO_COUNT / 2;
-		} else {
-			c = 0;
-			ISR_PDEBUG
-			    ("me4000_ai_isr():Can't determine state of fifo\n");
-		}
-
-		ISR_PDEBUG("me4000_ai_isr():Try to read %d values\n", c);
-
-		while (1) {
-			c1 = me4000_space_to_end(ai_context->circ_buf,
-						 ME4000_AI_BUFFER_COUNT);
-			ISR_PDEBUG("me4000_ai_isr():Space to end = %d\n", c1);
-			if (c1 > c)
-				c1 = c;
-
-			if (c1 <= 0) {
-				ISR_PDEBUG
-				    ("me4000_ai_isr():Work done or buffer full\n");
-				break;
-			}
-
-			insw(ai_context->data_reg,
-			     ai_context->circ_buf.buf +
-			     ai_context->circ_buf.head, c1);
-			ai_context->circ_buf.head =
-			    (ai_context->circ_buf.head +
-			     c1) & (ME4000_AI_BUFFER_COUNT - 1);
-			c -= c1;
-		}
-
-		/* Work is done, so reset the interrupt */
-		ISR_PDEBUG
-		    ("me4000_ai_isr():reset interrupt fifo half full interrupt\n");
-		spin_lock(&ai_context->int_lock);
-		tmp = me4000_inl(ai_context->ctrl_reg);
-		tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
-		me4000_outl(tmp, ai_context->ctrl_reg);
-		tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
-		me4000_outl(tmp, ai_context->ctrl_reg);
-		spin_unlock(&ai_context->int_lock);
-	}
-
-	if (me4000_inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
-		ISR_PDEBUG
-		    ("me4000_ai_isr():Sample counter interrupt occured\n");
-
-		if (!ai_context->sample_counter_reload) {
-			ISR_PDEBUG
-			    ("me4000_ai_isr():Single data block available\n");
-
-			/* Poll data until fifo empty */
-			for (i = 0;
-			     (i < ME4000_AI_FIFO_COUNT / 2)
-			     && (inl(ai_context->ctrl_reg) &
-				 ME4000_AI_STATUS_BIT_EF_DATA); i++) {
-				if (me4000_space_to_end
-				    (ai_context->circ_buf,
-				     ME4000_AI_BUFFER_COUNT)) {
-					*(ai_context->circ_buf.buf +
-					  ai_context->circ_buf.head) =
-		 inw(ai_context->data_reg);
-					ai_context->circ_buf.head =
-					    (ai_context->circ_buf.head +
-					     1) & (ME4000_AI_BUFFER_COUNT - 1);
-				} else
-					break;
-			}
-			ISR_PDEBUG("me4000_ai_isr():%d values read\n", i);
-		} else {
-			if (ai_context->sample_counter <=
-			    ME4000_AI_FIFO_COUNT / 2) {
-				ISR_PDEBUG
-				    ("me4000_ai_isr():Interrupt from adjustable half full threshold\n");
-
-				/* Read status register to find out what happened */
-				tmp = me4000_inl(ai_context->ctrl_reg);
-
-				if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-				    !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-				    && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-					ISR_PDEBUG
-					    ("me4000_ai_isr():Fifo full\n");
-					c = ME4000_AI_FIFO_COUNT;
-
-					/* FIFO overflow, so stop conversion */
-					spin_lock(&ai_context->int_lock);
-					tmp = me4000_inl(ai_context->ctrl_reg);
-					tmp |=
-					    ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-					outl(tmp, ai_context->ctrl_reg);
-					spin_unlock(&ai_context->int_lock);
-				} else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
-					   && !(tmp &
-						ME4000_AI_STATUS_BIT_HF_DATA)
-					   && (tmp &
-					       ME4000_AI_STATUS_BIT_EF_DATA)) {
-					ISR_PDEBUG
-					    ("me4000_ai_isr():Fifo half full\n");
-					c = ME4000_AI_FIFO_COUNT / 2;
-				} else {
-					c = ai_context->sample_counter;
-					ISR_PDEBUG
-					    ("me4000_ai_isr():Sample count values\n");
-				}
-
-				ISR_PDEBUG
-				    ("me4000_ai_isr():Try to read %d values\n",
-				     c);
-
-				while (1) {
-					c1 = me4000_space_to_end(ai_context->
-								 circ_buf,
-								 ME4000_AI_BUFFER_COUNT);
-					ISR_PDEBUG
-					    ("me4000_ai_isr():Space to end = %d\n",
-					     c1);
-					if (c1 > c)
-						c1 = c;
-
-					if (c1 <= 0) {
-						ISR_PDEBUG
-						    ("me4000_ai_isr():Work done or buffer full\n");
-						break;
-					}
-
-					insw(ai_context->data_reg,
-					     ai_context->circ_buf.buf +
-					     ai_context->circ_buf.head, c1);
-					ai_context->circ_buf.head =
-					    (ai_context->circ_buf.head +
-					     c1) & (ME4000_AI_BUFFER_COUNT - 1);
-					c -= c1;
-				}
-			} else {
-				ISR_PDEBUG
-				    ("me4000_ai_isr():Multiple data block available\n");
-
-				/* Read status register to find out what happened */
-				tmp = me4000_inl(ai_context->ctrl_reg);
-
-				if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
-				    !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
-				    && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
-					ISR_PDEBUG
-					    ("me4000_ai_isr():Fifo full\n");
-					c = ME4000_AI_FIFO_COUNT;
-
-					/* FIFO overflow, so stop conversion */
-					spin_lock(&ai_context->int_lock);
-					tmp = me4000_inl(ai_context->ctrl_reg);
-					tmp |=
-					    ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
-					outl(tmp, ai_context->ctrl_reg);
-					spin_unlock(&ai_context->int_lock);
-
-					while (1) {
-						c1 = me4000_space_to_end
-						    (ai_context->circ_buf,
-						     ME4000_AI_BUFFER_COUNT);
-						ISR_PDEBUG
-						    ("me4000_ai_isr():Space to end = %d\n",
-						     c1);
-						if (c1 > c)
-							c1 = c;
-
-						if (c1 <= 0) {
-							ISR_PDEBUG
-							    ("me4000_ai_isr():Work done or buffer full\n");
-							break;
-						}
-
-						insw(ai_context->data_reg,
-						     ai_context->circ_buf.buf +
-						     ai_context->circ_buf.head,
-						     c1);
-						ai_context->circ_buf.head =
-						    (ai_context->circ_buf.head +
-						     c1) &
-						    (ME4000_AI_BUFFER_COUNT -
-						     1);
-						c -= c1;
-					}
-				} else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
-					   && !(tmp &
-						ME4000_AI_STATUS_BIT_HF_DATA)
-					   && (tmp &
-					       ME4000_AI_STATUS_BIT_EF_DATA)) {
-					ISR_PDEBUG
-					    ("me4000_ai_isr():Fifo half full\n");
-					c = ME4000_AI_FIFO_COUNT / 2;
-
-					while (1) {
-						c1 = me4000_space_to_end
-						    (ai_context->circ_buf,
-						     ME4000_AI_BUFFER_COUNT);
-						ISR_PDEBUG
-						    ("me4000_ai_isr():Space to end = %d\n",
-						     c1);
-						if (c1 > c)
-							c1 = c;
-
-						if (c1 <= 0) {
-							ISR_PDEBUG
-							    ("me4000_ai_isr():Work done or buffer full\n");
-							break;
-						}
-
-						insw(ai_context->data_reg,
-						     ai_context->circ_buf.buf +
-						     ai_context->circ_buf.head,
-						     c1);
-						ai_context->circ_buf.head =
-						    (ai_context->circ_buf.head +
-						     c1) &
-						    (ME4000_AI_BUFFER_COUNT -
-						     1);
-						c -= c1;
-					}
-				} else {
-					/* Poll data until fifo empty */
-					for (i = 0;
-					     (i < ME4000_AI_FIFO_COUNT / 2)
-					     && (inl(ai_context->ctrl_reg) &
-						 ME4000_AI_STATUS_BIT_EF_DATA);
-					     i++) {
-						if (me4000_space_to_end
-						    (ai_context->circ_buf,
-						     ME4000_AI_BUFFER_COUNT)) {
-							*(ai_context->circ_buf.
-							  buf +
-							  ai_context->circ_buf.
-							  head) =
-				       inw(ai_context->data_reg);
-							ai_context->circ_buf.
-							    head =
-							    (ai_context->
-							     circ_buf.head +
-							     1) &
-							    (ME4000_AI_BUFFER_COUNT
-							     - 1);
-						} else
-							break;
-					}
-					ISR_PDEBUG
-					    ("me4000_ai_isr():%d values read\n",
-					     i);
-				}
-			}
-		}
-
-		/* Work is done, so reset the interrupt */
-		ISR_PDEBUG
-		    ("me4000_ai_isr():reset interrupt from sample counter\n");
-		spin_lock(&ai_context->int_lock);
-		tmp = me4000_inl(ai_context->ctrl_reg);
-		tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
-		me4000_outl(tmp, ai_context->ctrl_reg);
-		tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
-		me4000_outl(tmp, ai_context->ctrl_reg);
-		spin_unlock(&ai_context->int_lock);
-	}
-
-	/* Values are now available, so wake up waiting process */
-	if (me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
-		ISR_PDEBUG("me4000_ai_isr():Wake up waiting process\n");
-		wake_up_interruptible(&(ai_context->wait_queue));
-	}
-
-	/* If there is no space left in the buffer, disable interrupts */
-	spin_lock(&ai_context->int_lock);
-	if (!me4000_buf_space(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
-		ISR_PDEBUG
-		    ("me4000_ai_isr():Disable Interrupt because no space left in buffer\n");
-		tmp = me4000_inl(ai_context->ctrl_reg);
-		tmp &=
-		    ~(ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ |
-		      ME4000_AI_CTRL_BIT_LE_IRQ);
-		me4000_outl(tmp, ai_context->ctrl_reg);
-	}
-	spin_unlock(&ai_context->int_lock);
-
-#ifdef ME4000_ISR_DEBUG
-	rdtscl(after);
-	printk(KERN_ERR "ME4000:me4000_ai_isr():Time lapse = %lu\n",
-	       after - before);
-#endif
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t me4000_ext_int_isr(int irq, void *dev_id)
-{
-	struct me4000_ext_int_context *ext_int_context;
-	unsigned long tmp;
-
-	ISR_PDEBUG("me4000_ext_int_isr() is executed\n");
-
-	ext_int_context = dev_id;
-
-	/* Check if irq number is right */
-	if (irq != ext_int_context->irq) {
-		ISR_PDEBUG("me4000_ext_int_isr():incorrect interrupt num: %d\n",
-			   irq);
-		return IRQ_NONE;
-	}
-
-	if (me4000_inl(ext_int_context->irq_status_reg) &
-	    ME4000_IRQ_STATUS_BIT_EX) {
-		ISR_PDEBUG("me4000_ext_int_isr():External interrupt occured\n");
-		tmp = me4000_inl(ext_int_context->ctrl_reg);
-		tmp |= ME4000_AI_CTRL_BIT_EX_IRQ_RESET;
-		me4000_outl(tmp, ext_int_context->ctrl_reg);
-		tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ_RESET;
-		me4000_outl(tmp, ext_int_context->ctrl_reg);
-
-		ext_int_context->int_count++;
-
-		if (ext_int_context->fasync_ptr) {
-			ISR_PDEBUG
-			    ("me2600_ext_int_isr():Send signal to process\n");
-			kill_fasync(&ext_int_context->fasync_ptr, SIGIO,
-				    POLL_IN);
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
-static void __exit me4000_module_exit(void)
-{
-	struct me4000_info *board_info;
-
-	CALL_PDEBUG("cleanup_module() is executed\n");
-
-	unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME);
-
-	unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME);
-
-	unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME);
-
-	unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME);
-
-	unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME);
-
-	remove_proc_entry("me4000", NULL);
-
-	pci_unregister_driver(&me4000_driver);
-
-	/* Reset the boards */
-	list_for_each_entry(board_info, &me4000_board_info_list, list) {
-		me4000_reset_board(board_info);
-	}
-
-	clear_board_info_list();
-}
-
-module_exit(me4000_module_exit);
-
-static int me4000_read_procmem(char *buf, char **start, off_t offset, int count,
-			       int *eof, void *data)
-{
-	int len = 0;
-	int limit = count - 1000;
-	struct me4000_info *board_info;
-
-	len += sprintf(buf + len, "\nME4000 DRIVER VERSION %X.%X.%X\n\n",
-		       (ME4000_DRIVER_VERSION & 0xFF0000) >> 16,
-		       (ME4000_DRIVER_VERSION & 0xFF00) >> 8,
-		       (ME4000_DRIVER_VERSION & 0xFF));
-
-	/* Search for the board context */
-	list_for_each_entry(board_info, &me4000_board_info_list, list) {
-		len +=
-		    sprintf(buf + len, "Board number %d:\n",
-			    board_info->board_count);
-		len += sprintf(buf + len, "---------------\n");
-		len +=
-		    sprintf(buf + len, "PLX base register = 0x%lX\n",
-			    board_info->plx_regbase);
-		len +=
-		    sprintf(buf + len, "PLX base register size = 0x%X\n",
-			    (unsigned int)board_info->plx_regbase_size);
-		len +=
-		    sprintf(buf + len, "ME4000 base register = 0x%X\n",
-			    (unsigned int)board_info->me4000_regbase);
-		len +=
-		    sprintf(buf + len, "ME4000 base register size = 0x%X\n",
-			    (unsigned int)board_info->me4000_regbase_size);
-		len +=
-		    sprintf(buf + len, "Serial number = 0x%X\n",
-			    board_info->serial_no);
-		len +=
-		    sprintf(buf + len, "Hardware revision = 0x%X\n",
-			    board_info->hw_revision);
-		len +=
-		    sprintf(buf + len, "Vendor id = 0x%X\n",
-			    board_info->vendor_id);
-		len +=
-		    sprintf(buf + len, "Device id = 0x%X\n",
-			    board_info->device_id);
-		len +=
-		    sprintf(buf + len, "PCI bus number = %d\n",
-			    board_info->pci_bus_no);
-		len +=
-		    sprintf(buf + len, "PCI device number = %d\n",
-			    board_info->pci_dev_no);
-		len +=
-		    sprintf(buf + len, "PCI function number = %d\n",
-			    board_info->pci_func_no);
-		len += sprintf(buf + len, "IRQ = %u\n", board_info->irq);
-		len +=
-		    sprintf(buf + len,
-			    "Count of interrupts since module was loaded = %d\n",
-			    board_info->irq_count);
-
-		len +=
-		    sprintf(buf + len, "Count of analog outputs = %d\n",
-			    board_info->board_p->ao.count);
-		len +=
-		    sprintf(buf + len, "Count of analog output fifos = %d\n",
-			    board_info->board_p->ao.fifo_count);
-
-		len +=
-		    sprintf(buf + len, "Count of analog inputs = %d\n",
-			    board_info->board_p->ai.count);
-		len +=
-		    sprintf(buf + len,
-			    "Count of sample and hold devices for analog input = %d\n",
-			    board_info->board_p->ai.sh_count);
-		len +=
-		    sprintf(buf + len,
-			    "Analog external trigger available for analog input = %d\n",
-			    board_info->board_p->ai.ex_trig_analog);
-
-		len +=
-		    sprintf(buf + len, "Count of digital ports = %d\n",
-			    board_info->board_p->dio.count);
-
-		len +=
-		    sprintf(buf + len, "Count of counter devices = %d\n",
-			    board_info->board_p->cnt.count);
-		len +=
-		    sprintf(buf + len, "AI control register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AI_CTRL_REG));
-
-		len += sprintf(buf + len, "AO 0 control register = 0x%08X\n",
-			       inl(board_info->me4000_regbase +
-				   ME4000_AO_00_CTRL_REG));
-		len +=
-		    sprintf(buf + len, "AO 0 status register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AO_00_STATUS_REG));
-		len +=
-		    sprintf(buf + len, "AO 1 control register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AO_01_CTRL_REG));
-		len +=
-		    sprintf(buf + len, "AO 1 status register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AO_01_STATUS_REG));
-		len +=
-		    sprintf(buf + len, "AO 2 control register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AO_02_CTRL_REG));
-		len +=
-		    sprintf(buf + len, "AO 2 status register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AO_02_STATUS_REG));
-		len +=
-		    sprintf(buf + len, "AO 3 control register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AO_03_CTRL_REG));
-		len +=
-		    sprintf(buf + len, "AO 3 status register = 0x%08X\n",
-			    inl(board_info->me4000_regbase +
-				ME4000_AO_03_STATUS_REG));
-		if (len >= limit)
-			break;
-	}
-
-	*eof = 1;
-	return len;
-}
diff --git a/drivers/staging/me4000/me4000.h b/drivers/staging/me4000/me4000.h
deleted file mode 100644
index 81c6f4d..0000000
--- a/drivers/staging/me4000/me4000.h
+++ /dev/null
@@ -1,966 +0,0 @@
-/*
- * Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : me4000.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- */
-
-#ifndef _ME4000_H_
-#define _ME4000_H_
-
-#ifdef __KERNEL__
-
-/*=============================================================================
-  The version of the driver release
-  ===========================================================================*/
-
-#define ME4000_DRIVER_VERSION  0x10009	// Version 1.00.09
-
-/*=============================================================================
-  Debug section
-  ===========================================================================*/
-
-#undef ME4000_CALL_DEBUG	// Debug function entry and exit
-#undef ME4000_ISR_DEBUG		// Debug the interrupt service routine
-#undef ME4000_PORT_DEBUG	// Debug port access
-#undef ME4000_DEBUG		// General purpose debug masseges
-
-#ifdef ME4000_CALL_DEBUG
-#undef CALL_PDEBUG
-#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-#else
-# define CALL_PDEBUG(fmt, args...)	// no debugging, do nothing
-#endif
-
-#ifdef ME4000_ISR_DEBUG
-#undef ISR_PDEBUG
-#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-#else
-#define ISR_PDEBUG(fmt, args...)	// no debugging, do nothing
-#endif
-
-#ifdef ME4000_PORT_DEBUG
-#undef PORT_PDEBUG
-#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-#else
-#define PORT_PDEBUG(fmt, args...)	// no debugging, do nothing
-#endif
-
-#ifdef ME4000_DEBUG
-#undef PDEBUG
-#define PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
-#else
-#define PDEBUG(fmt, args...)	// no debugging, do nothing
-#endif
-
-/*=============================================================================
-  PCI vendor and device IDs
-  ===========================================================================*/
-
-#define PCI_VENDOR_ID_MEILHAUS 0x1402
-
-#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_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
-
-/*=============================================================================
-  Device names, for entries in /proc/..
-  ===========================================================================*/
-
-#define ME4000_NAME		"me4000"
-#define ME4000_AO_NAME		"me4000_ao"
-#define ME4000_AI_NAME		"me4000_ai"
-#define ME4000_DIO_NAME		"me4000_dio"
-#define ME4000_CNT_NAME		"me4000_cnt"
-#define ME4000_EXT_INT_NAME	"me4000_ext_int"
-
-/*=============================================================================
-  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_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_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_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_AO_LOADSETREG_XX			0xB4	// R/W
-
-#define ME4000_DIO_CTRL_REG			0xB8	// R/W
-
-#define ME4000_AO_DEMUX_ADJUST_REG		0xBC	// -/W
-
-#define ME4000_AI_SAMPLE_COUNTER_REG		0xC0	// _/W
-
-/*=============================================================================
-  Value to adjust Demux
-  ===========================================================================*/
-
-#define ME4000_AO_DEMUX_ADJUST_VALUE            0x4C
-
-/*=============================================================================
-  Counter base register offsets
-  ===========================================================================*/
-
-#define ME4000_CNT_COUNTER_0_REG		0x00
-#define ME4000_CNT_COUNTER_1_REG		0x01
-#define ME4000_CNT_COUNTER_2_REG		0x02
-#define ME4000_CNT_CTRL_REG			0x03
-
-/*=============================================================================
-  PLX base register offsets
-  ===========================================================================*/
-
-#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)
-
-/*=============================================================================
-  Bits for the PLX_ICR register
-  ===========================================================================*/
-
-#define PLX_ICR_BIT_EEPROM_CLOCK_SET		0x01000000
-#define PLX_ICR_BIT_EEPROM_CHIP_SELECT		0x02000000
-#define PLX_ICR_BIT_EEPROM_WRITE		0x04000000
-#define PLX_ICR_BIT_EEPROM_READ			0x08000000
-#define PLX_ICR_BIT_EEPROM_VALID		0x10000000
-
-#define PLX_ICR_MASK_EEPROM			0x1F000000
-
-#define EEPROM_DELAY				1
-
-/*=============================================================================
-  Bits for the ME4000_AO_CTRL_REG register
-  ===========================================================================*/
-
-#define ME4000_AO_CTRL_BIT_MODE_0		0x001
-#define ME4000_AO_CTRL_BIT_MODE_1		0x002
-#define ME4000_AO_CTRL_MASK_MODE		0x003
-#define ME4000_AO_CTRL_BIT_STOP			0x004
-#define ME4000_AO_CTRL_BIT_ENABLE_FIFO		0x008
-#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG	0x010
-#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE		0x020
-#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP	0x080
-#define ME4000_AO_CTRL_BIT_ENABLE_DO		0x100
-#define ME4000_AO_CTRL_BIT_ENABLE_IRQ		0x200
-#define ME4000_AO_CTRL_BIT_RESET_IRQ		0x400
-#define ME4000_AO_CTRL_BIT_EX_TRIG_BOTH		0x800
-
-/*=============================================================================
-  Bits for the ME4000_AO_STATUS_REG register
-  ===========================================================================*/
-
-#define ME4000_AO_STATUS_BIT_FSM		0x01
-#define ME4000_AO_STATUS_BIT_FF			0x02
-#define ME4000_AO_STATUS_BIT_HF			0x04
-#define ME4000_AO_STATUS_BIT_EF			0x08
-
-/*=============================================================================
-  Bits for the ME4000_AI_CTRL_REG register
-  ===========================================================================*/
-
-#define ME4000_AI_CTRL_BIT_MODE_0		0x00000001
-#define ME4000_AI_CTRL_BIT_MODE_1		0x00000002
-#define ME4000_AI_CTRL_BIT_MODE_2		0x00000004
-#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD		0x00000008
-#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP	0x00000010
-#define ME4000_AI_CTRL_BIT_STOP			0x00000020
-#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO		0x00000040
-#define ME4000_AI_CTRL_BIT_DATA_FIFO		0x00000080
-#define ME4000_AI_CTRL_BIT_FULLSCALE		0x00000100
-#define ME4000_AI_CTRL_BIT_OFFSET		0x00000200
-#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG	0x00000400
-#define ME4000_AI_CTRL_BIT_EX_TRIG		0x00000800
-#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING	0x00001000
-#define ME4000_AI_CTRL_BIT_EX_IRQ		0x00002000
-#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET		0x00004000
-#define ME4000_AI_CTRL_BIT_LE_IRQ		0x00008000
-#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET		0x00010000
-#define ME4000_AI_CTRL_BIT_HF_IRQ		0x00020000
-#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET		0x00040000
-#define ME4000_AI_CTRL_BIT_SC_IRQ		0x00080000
-#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET		0x00100000
-#define ME4000_AI_CTRL_BIT_SC_RELOAD		0x00200000
-#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH		0x80000000
-
-/*=============================================================================
-  Bits for the ME4000_AI_STATUS_REG register
-  ===========================================================================*/
-
-#define ME4000_AI_STATUS_BIT_EF_CHANNEL		0x00400000
-#define ME4000_AI_STATUS_BIT_HF_CHANNEL		0x00800000
-#define ME4000_AI_STATUS_BIT_FF_CHANNEL		0x01000000
-#define ME4000_AI_STATUS_BIT_EF_DATA		0x02000000
-#define ME4000_AI_STATUS_BIT_HF_DATA		0x04000000
-#define ME4000_AI_STATUS_BIT_FF_DATA		0x08000000
-#define ME4000_AI_STATUS_BIT_LE			0x10000000
-#define ME4000_AI_STATUS_BIT_FSM		0x20000000
-
-/*=============================================================================
-  Bits for the ME4000_IRQ_STATUS_REG register
-  ===========================================================================*/
-
-#define ME4000_IRQ_STATUS_BIT_EX		0x01
-#define ME4000_IRQ_STATUS_BIT_LE		0x02
-#define ME4000_IRQ_STATUS_BIT_AI_HF		0x04
-#define ME4000_IRQ_STATUS_BIT_AO_0_HF		0x08
-#define ME4000_IRQ_STATUS_BIT_AO_1_HF		0x10
-#define ME4000_IRQ_STATUS_BIT_AO_2_HF		0x20
-#define ME4000_IRQ_STATUS_BIT_AO_3_HF		0x40
-#define ME4000_IRQ_STATUS_BIT_SC		0x80
-
-/*=============================================================================
-  Bits for the ME4000_DIO_CTRL_REG register
-  ===========================================================================*/
-
-#define ME4000_DIO_CTRL_BIT_MODE_0		0X0001
-#define ME4000_DIO_CTRL_BIT_MODE_1		0X0002
-#define ME4000_DIO_CTRL_BIT_MODE_2		0X0004
-#define ME4000_DIO_CTRL_BIT_MODE_3		0X0008
-#define ME4000_DIO_CTRL_BIT_MODE_4		0X0010
-#define ME4000_DIO_CTRL_BIT_MODE_5		0X0020
-#define ME4000_DIO_CTRL_BIT_MODE_6		0X0040
-#define ME4000_DIO_CTRL_BIT_MODE_7		0X0080
-
-#define ME4000_DIO_CTRL_BIT_FUNCTION_0		0X0100
-#define ME4000_DIO_CTRL_BIT_FUNCTION_1		0X0200
-
-#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0		0X0400
-#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1		0X0800
-#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2		0X1000
-#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3		0X2000
-
-/*=============================================================================
-  Bits for the ME4000_CNT_CTRL_REG register
-  ===========================================================================*/
-
-#define ME4000_CNT_CTRL_BIT_COUNTER_0  0x00
-#define ME4000_CNT_CTRL_BIT_COUNTER_1  0x40
-#define ME4000_CNT_CTRL_BIT_COUNTER_2  0x80
-
-#define ME4000_CNT_CTRL_BIT_MODE_0     0x00	// Change state if zero crossing
-#define ME4000_CNT_CTRL_BIT_MODE_1     0x02	// Retriggerable One-Shot
-#define ME4000_CNT_CTRL_BIT_MODE_2     0x04	// Asymmetrical divider
-#define ME4000_CNT_CTRL_BIT_MODE_3     0x06	// Symmetrical divider
-#define ME4000_CNT_CTRL_BIT_MODE_4     0x08	// Counter start by software trigger
-#define ME4000_CNT_CTRL_BIT_MODE_5     0x0A	// Counter start by hardware trigger
-
-/*=============================================================================
-  Extract information from minor device number
-  ===========================================================================*/
-
-#define AO_BOARD(dev) ((MINOR(dev) >> 6) & 0x3)
-#define AO_PORT(dev)  ((MINOR(dev) >> 2) & 0xF)
-#define AO_MODE(dev)  (MINOR(dev) & 0x3)
-
-#define AI_BOARD(dev) ((MINOR(dev) >> 3) & 0x1F)
-#define AI_MODE(dev)  (MINOR(dev) & 0x7)
-
-#define DIO_BOARD(dev) (MINOR(dev))
-
-#define CNT_BOARD(dev) (MINOR(dev))
-
-#define EXT_INT_BOARD(dev) (MINOR(dev))
-
-/*=============================================================================
-  Circular buffer used for analog input/output reads/writes.
-  ===========================================================================*/
-
-struct me4000_circ_buf {
-	s16 *buf;
-	int volatile head;
-	int volatile tail;
-};
-
-/*=============================================================================
-  Information about the hardware capabilities
-  ===========================================================================*/
-
-struct me4000_ao_info {
-	int count;
-	int fifo_count;
-};
-
-struct me4000_ai_info {
-	int count;
-	int sh_count;
-	int diff_count;
-	int ex_trig_analog;
-};
-
-struct me4000_dio_info {
-	int count;
-};
-
-struct me4000_cnt_info {
-	int count;
-};
-
-struct me4000_board {
-	u16 vendor_id;
-	u16 device_id;
-	struct me4000_ao_info ao;
-	struct me4000_ai_info ai;
-	struct me4000_dio_info dio;
-	struct me4000_cnt_info cnt;
-};
-
-static struct me4000_board me4000_boards[] = {
-	{PCI_VENDOR_ID_MEILHAUS, 0x4610, {0, 0}, {16, 0, 0, 0}, {4}, {3}},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4660, {2, 0}, {16, 0, 0, 0}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4661, {2, 0}, {16, 0, 0, 0}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4662, {2, 0}, {16, 8, 0, 0}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4663, {2, 0}, {16, 8, 0, 0}, {4}, {3}},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
-
-	{0},
-};
-
-/*=============================================================================
-  PCI device table.
-  This is used by modprobe to translate PCI IDs to drivers.
-  ===========================================================================*/
-
-static struct pci_device_id me4000_pci_table[] __devinitdata = {
-	{PCI_VENDOR_ID_MEILHAUS, 0x4610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-
-	{0}
-};
-
-MODULE_DEVICE_TABLE(pci, me4000_pci_table);
-
-/*=============================================================================
-  Global board and subdevice information structures
-  ===========================================================================*/
-
-struct me4000_info {
-	struct list_head list;	// List of all detected boards
-	int board_count;	// Index of the board after detection
-
-	unsigned long plx_regbase;	// PLX configuration space base address
-	resource_size_t me4000_regbase;	// Base address of the ME4000
-	resource_size_t timer_regbase;	// Base address of the timer circuit
-	resource_size_t program_regbase;	// Base address to set the program pin for the xilinx
-
-	unsigned long plx_regbase_size;	// PLX register set space
-	resource_size_t me4000_regbase_size;	// ME4000 register set space
-	resource_size_t timer_regbase_size;	// Timer circuit register set space
-	resource_size_t 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 (0x1402)
-	unsigned short device_id;	// Device ID
-
-	int pci_bus_no;		// PCI bus number
-	int pci_dev_no;		// PCI device number
-	int pci_func_no;	// PCI function number
-	struct pci_dev *pci_dev_p;	// General PCI information
-
-	struct me4000_board *board_p;	// Holds the board capabilities
-
-	unsigned int irq;	// IRQ assigned from the PCI BIOS
-	unsigned int irq_count;	// Count of external interrupts
-
-	spinlock_t preload_lock;	// Guards the analog output preload register
-	spinlock_t ai_ctrl_lock;	// Guards the analog input control register
-
-	struct list_head ao_context_list;	// List with analog output specific context
-	struct me4000_ai_context *ai_context;	// Analog input  specific context
-	struct me4000_dio_context *dio_context;	// Digital I/O specific context
-	struct me4000_cnt_context *cnt_context;	// Counter specific context
-	struct me4000_ext_int_context *ext_int_context;	// External interrupt specific context
-};
-
-struct me4000_ao_context {
-	struct list_head list;	// linked list of me4000_ao_context_t
-	int index;		// Index in the list
-	int mode;		// Indicates mode (0 = single, 1 = wraparound, 2 = continous)
-	int dac_in_use;		// Indicates if already opend
-	spinlock_t use_lock;	// Guards in_use
-	spinlock_t int_lock;	// Used when locking out interrupts
-	struct me4000_circ_buf circ_buf;	// Circular buffer
-	wait_queue_head_t wait_queue;	// Wait queue to sleep while blocking write
-	struct me4000_info *board_info;
-	unsigned int irq;	// The irq associated with this ADC
-	int volatile pipe_flag;	// Indicates broken pipe set from me4000_ao_isr()
-	unsigned long ctrl_reg;
-	unsigned long status_reg;
-	unsigned long fifo_reg;
-	unsigned long single_reg;
-	unsigned long timer_reg;
-	unsigned long irq_status_reg;
-	unsigned long preload_reg;
-	struct fasync_struct *fasync_p;	// Queue for asynchronous notification
-};
-
-struct me4000_ai_context {
-	struct list_head list;	// linked list of me4000_ai_info_t
-	int mode;		// Indicates mode
-	int in_use;		// Indicates if already opend
-	spinlock_t use_lock;	// Guards in_use
-	spinlock_t int_lock;	// Used when locking out interrupts
-	int number;		// Number of the DAC
-	unsigned int irq;	// The irq associated with this ADC
-	struct me4000_circ_buf circ_buf;	// Circular buffer
-	wait_queue_head_t wait_queue;	// Wait queue to sleep while blocking read
-	struct me4000_info *board_info;
-
-	struct fasync_struct *fasync_p;	// Queue for asynchronous notification
-
-	unsigned long ctrl_reg;
-	unsigned long status_reg;
-	unsigned long channel_list_reg;
-	unsigned long data_reg;
-	unsigned long chan_timer_reg;
-	unsigned long chan_pre_timer_reg;
-	unsigned long scan_timer_low_reg;
-	unsigned long scan_timer_high_reg;
-	unsigned long scan_pre_timer_low_reg;
-	unsigned long scan_pre_timer_high_reg;
-	unsigned long start_reg;
-	unsigned long irq_status_reg;
-	unsigned long sample_counter_reg;
-
-	unsigned long chan_timer;
-	unsigned long chan_pre_timer;
-	unsigned long scan_timer_low;
-	unsigned long scan_timer_high;
-	unsigned long channel_list_count;
-	unsigned long sample_counter;
-	int sample_counter_reload;
-};
-
-struct me4000_dio_context {
-	struct list_head list;	// linked list of me4000_dio_context_t
-	int in_use;		// Indicates if already opend
-	spinlock_t use_lock;	// Guards in_use
-	int number;
-	int dio_count;
-	struct me4000_info *board_info;
-	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;
-};
-
-struct me4000_cnt_context {
-	struct list_head list;	// linked list of me4000_dio_context_t
-	int in_use;		// Indicates if already opend
-	spinlock_t use_lock;	// Guards in_use
-	int number;
-	int cnt_count;
-	struct me4000_info *board_info;
-	unsigned long ctrl_reg;
-	unsigned long counter_0_reg;
-	unsigned long counter_1_reg;
-	unsigned long counter_2_reg;
-};
-
-struct me4000_ext_int_context {
-	struct list_head list;	// linked list of me4000_dio_context_t
-	int in_use;		// Indicates if already opend
-	spinlock_t use_lock;	// Guards in_use
-	int number;
-	struct me4000_info *board_info;
-	unsigned int irq;
-	unsigned long int_count;
-	struct fasync_struct *fasync_ptr;
-	unsigned long ctrl_reg;
-	unsigned long irq_status_reg;
-};
-
-#endif
-
-/*=============================================================================
-  Application include section starts here
-  ===========================================================================*/
-
-/*-----------------------------------------------------------------------------
-  Defines for analog input
-  ----------------------------------------------------------------------------*/
-
-/* General stuff */
-#define ME4000_AI_FIFO_COUNT		2048
-
-#define ME4000_AI_MIN_TICKS		66
-#define ME4000_AI_MAX_SCAN_TICKS	0xFFFFFFFFFFLL
-
-#define ME4000_AI_BUFFER_SIZE 		(32 * 1024)	// Size in bytes
-
-#define ME4000_AI_BUFFER_COUNT		((ME4000_AI_BUFFER_SIZE) / 2)	// Size in values
-
-/* Channel list defines and masks */
-#define ME4000_AI_CHANNEL_LIST_COUNT		1024
-
-#define ME4000_AI_LIST_INPUT_SINGLE_ENDED	0x000
-#define ME4000_AI_LIST_INPUT_DIFFERENTIAL	0x020
-
-#define ME4000_AI_LIST_RANGE_BIPOLAR_10		0x000
-#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5	0x040
-#define ME4000_AI_LIST_RANGE_UNIPOLAR_10	0x080
-#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5	0x0C0
-
-#define ME4000_AI_LIST_LAST_ENTRY		0x100
-
-/* External trigger defines */
-#define ME4000_AI_TRIGGER_SOFTWARE		0x0	// Use only with API
-#define ME4000_AI_TRIGGER_EXT_DIGITAL		0x1
-#define ME4000_AI_TRIGGER_EXT_ANALOG		0x2
-
-#define ME4000_AI_TRIGGER_EXT_EDGE_RISING	0x0
-#define ME4000_AI_TRIGGER_EXT_EDGE_FALLING	0x1
-#define ME4000_AI_TRIGGER_EXT_EDGE_BOTH		0x2
-
-/* Sample and Hold */
-#define ME4000_AI_SIMULTANEOUS_DISABLE		0x0
-#define ME4000_AI_SIMULTANEOUS_ENABLE		0x1
-
-/* Defines for the Sample Counter */
-#define ME4000_AI_SC_RELOAD			0x0
-#define ME4000_AI_SC_ONCE			0x1
-
-/* Modes for analog input */
-#define ME4000_AI_ACQ_MODE_SINGLE		0x00	// Catch one single value
-#define ME4000_AI_ACQ_MODE_SOFTWARE		0x01	// Continous sampling with software start
-#define ME4000_AI_ACQ_MODE_EXT			0x02	// Continous sampling with external trigger start
-#define ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE	0x03	// Sample one value by external trigger
-#define ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST	0x04	// Sample one channel list by external trigger
-
-/* Staus of AI FSM */
-#define ME4000_AI_STATUS_IDLE			0x0
-#define ME4000_AI_STATUS_BUSY			0x1
-
-/* Voltages for calibration */
-#define ME4000_AI_GAIN_1_UNI_OFFSET		10.0E-3
-#define ME4000_AI_GAIN_1_UNI_FULLSCALE		9950.0E-3
-#define ME4000_AI_GAIN_1_BI_OFFSET		0.0
-#define ME4000_AI_GAIN_1_BI_FULLSCALE		9950.0E-3
-#define ME4000_AI_GAIN_4_UNI_OFFSET		10.0E-3
-#define ME4000_AI_GAIN_4_UNI_FULLSCALE		2450.0E-3
-#define ME4000_AI_GAIN_4_BI_OFFSET		0.0
-#define ME4000_AI_GAIN_4_BI_FULLSCALE		2450.0E-3
-
-/* Ideal digits for calibration */
-#define ME4000_AI_GAIN_1_UNI_OFFSET_DIGITS	(-32702)
-#define ME4000_AI_GAIN_1_UNI_FULLSCALE_DIGITS	32440
-#define ME4000_AI_GAIN_1_BI_OFFSET_DIGITS	0
-#define ME4000_AI_GAIN_1_BI_FULLSCALE_DIGITS	32604
-#define ME4000_AI_GAIN_4_UNI_OFFSET_DIGITS	(-32505)
-#define ME4000_AI_GAIN_4_UNI_FULLSCALE_DIGITS	31457
-#define ME4000_AI_GAIN_4_BI_OFFSET_DIGITS	0
-#define ME4000_AI_GAIN_4_BI_FULLSCALE_DIGITS	32113
-
-/*-----------------------------------------------------------------------------
-  Defines for analog output
-  ----------------------------------------------------------------------------*/
-
-/* General stuff */
-#define ME4000_AO_FIFO_COUNT			(4 * 1024)
-
-#define ME4000_AO_MIN_TICKS			66
-
-#define ME4000_AO_BUFFER_SIZE 			(32 * 1024)	// Size in bytes
-
-#define ME4000_AO_BUFFER_COUNT 			((ME4000_AO_BUFFER_SIZE) / 2)	// Size in values
-
-/* Conversion modes for analog output */
-#define ME4000_AO_CONV_MODE_SINGLE		0x0
-#define ME4000_AO_CONV_MODE_WRAPAROUND		0x1
-#define ME4000_AO_CONV_MODE_CONTINUOUS		0x2
-
-/* Trigger setup */
-#define ME4000_AO_TRIGGER_EXT_EDGE_RISING	0x0
-#define ME4000_AO_TRIGGER_EXT_EDGE_FALLING	0x1
-#define ME4000_AO_TRIGGER_EXT_EDGE_BOTH		0x2
-
-/* Status of AO FSM */
-#define ME4000_AO_STATUS_IDLE			0x0
-#define ME4000_AO_STATUS_BUSY			0x1
-
-/*-----------------------------------------------------------------------------
-  Defines for eeprom
-  ----------------------------------------------------------------------------*/
-
-#define ME4000_EEPROM_CMD_READ			0x180
-#define ME4000_EEPROM_CMD_WRITE_ENABLE		0x130
-#define ME4000_EEPROM_CMD_WRITE_DISABLE		0x100
-#define ME4000_EEPROM_CMD_WRITE			0x1400000
-
-#define ME4000_EEPROM_CMD_LENGTH_READ		9
-#define ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE	9
-#define ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE	9
-#define ME4000_EEPROM_CMD_LENGTH_WRITE		25
-
-#define ME4000_EEPROM_ADR_DATE_HIGH		0x32
-#define ME4000_EEPROM_ADR_DATE_LOW		0x33
-
-#define ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET	0x34
-#define ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE	0x35
-#define ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET	0x36
-#define ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE	0x37
-#define ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET	0x38
-#define ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE	0x39
-
-#define ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET	0x3A
-#define ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE	0x3B
-#define ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET	0x3C
-#define ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE	0x3D
-#define ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET	0x3E
-#define ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE	0x3F
-
-#define ME4000_EEPROM_ADR_LENGTH		6
-#define ME4000_EEPROM_DATA_LENGTH		16
-
-/*-----------------------------------------------------------------------------
-  Defines for digital I/O
-  ----------------------------------------------------------------------------*/
-
-#define ME4000_DIO_PORT_A		0x0
-#define ME4000_DIO_PORT_B		0x1
-#define ME4000_DIO_PORT_C		0x2
-#define ME4000_DIO_PORT_D		0x3
-
-#define ME4000_DIO_PORT_INPUT		0x0
-#define ME4000_DIO_PORT_OUTPUT		0x1
-#define ME4000_DIO_FIFO_LOW		0x2
-#define ME4000_DIO_FIFO_HIGH		0x3
-
-#define ME4000_DIO_FUNCTION_PATTERN	0x0
-#define ME4000_DIO_FUNCTION_DEMUX	0x1
-#define ME4000_DIO_FUNCTION_MUX		0x2
-
-/*-----------------------------------------------------------------------------
-  Defines for counters
-  ----------------------------------------------------------------------------*/
-
-#define ME4000_CNT_COUNTER_0  0
-#define ME4000_CNT_COUNTER_1  1
-#define ME4000_CNT_COUNTER_2  2
-
-#define ME4000_CNT_MODE_0     0	// Change state if zero crossing
-#define ME4000_CNT_MODE_1     1	// Retriggerable One-Shot
-#define ME4000_CNT_MODE_2     2	// Asymmetrical divider
-#define ME4000_CNT_MODE_3     3	// Symmetrical divider
-#define ME4000_CNT_MODE_4     4	// Counter start by software trigger
-#define ME4000_CNT_MODE_5     5	// Counter start by hardware trigger
-
-/*-----------------------------------------------------------------------------
-  General type definitions
-  ----------------------------------------------------------------------------*/
-
-struct me4000_user_info {
-	int board_count;	// Index of the board after detection
-	unsigned long plx_regbase;	// PLX configuration space base address
-	resource_size_t me4000_regbase;	// Base address of the ME4000
-	unsigned long plx_regbase_size;	// PLX register set space
-	resource_size_t me4000_regbase_size;	// ME4000 register set space
-	unsigned long serial_no;	// Serial number of the board
-	unsigned char hw_revision;	// Hardware revision of the board
-	unsigned short vendor_id;	// Meilhaus vendor id (0x1402)
-	unsigned short device_id;	// Device ID
-	int pci_bus_no;		// PCI bus number
-	int pci_dev_no;		// PCI device number
-	int pci_func_no;	// PCI function number
-	char irq;		// IRQ assigned from the PCI BIOS
-	int irq_count;		// Count of external interrupts
-
-	int driver_version;	// Version of the driver release
-
-	int ao_count;		// Count of analog output channels
-	int ao_fifo_count;	// Count fo analog output fifos
-
-	int ai_count;		// Count of analog input channels
-	int ai_sh_count;	// Count of sample and hold devices
-	int ai_ex_trig_analog;	// Flag to indicate if analogous external trigger is available
-
-	int dio_count;		// Count of digital I/O ports
-
-	int cnt_count;		// Count of counters
-};
-
-/*-----------------------------------------------------------------------------
-  Type definitions for analog output
-  ----------------------------------------------------------------------------*/
-
-struct me4000_ao_channel_list {
-	unsigned long count;
-	unsigned long *list;
-};
-
-/*-----------------------------------------------------------------------------
-  Type definitions for analog input
-  ----------------------------------------------------------------------------*/
-
-struct me4000_ai_channel_list {
-	unsigned long count;
-	unsigned long *list;
-};
-
-struct me4000_ai_timer {
-	unsigned long pre_chan;
-	unsigned long chan;
-	unsigned long scan_low;
-	unsigned long scan_high;
-};
-
-struct me4000_ai_config {
-	struct me4000_ai_timer timer;
-	struct me4000_ai_channel_list channel_list;
-	int sh;
-};
-
-struct me4000_ai_single {
-	int channel;
-	int range;
-	int mode;
-	short value;
-	unsigned long timeout;
-};
-
-struct me4000_ai_trigger {
-	int mode;
-	int edge;
-};
-
-struct me4000_ai_sc {
-	unsigned long value;
-	int reload;
-};
-
-/*-----------------------------------------------------------------------------
-  Type definitions for eeprom
-  ----------------------------------------------------------------------------*/
-
-struct me4000_eeprom {
-	unsigned long date;
-	short uni_10_offset;
-	short uni_10_fullscale;
-	short uni_2_5_offset;
-	short uni_2_5_fullscale;
-	short bi_10_offset;
-	short bi_10_fullscale;
-	short bi_2_5_offset;
-	short bi_2_5_fullscale;
-	short diff_10_offset;
-	short diff_10_fullscale;
-	short diff_2_5_offset;
-	short diff_2_5_fullscale;
-};
-
-/*-----------------------------------------------------------------------------
-  Type definitions for digital I/O
-  ----------------------------------------------------------------------------*/
-
-struct me4000_dio_config {
-	int port;
-	int mode;
-	int function;
-};
-
-struct me4000_dio_byte {
-	int port;
-	unsigned char byte;
-};
-
-/*-----------------------------------------------------------------------------
-  Type definitions for counters
-  ----------------------------------------------------------------------------*/
-
-struct me4000_cnt {
-	int counter;
-	unsigned short value;
-};
-
-struct me4000_cnt_config {
-	int counter;
-	int mode;
-};
-
-/*-----------------------------------------------------------------------------
-  Type definitions for external interrupt
-  ----------------------------------------------------------------------------*/
-
-struct me4000_int {
-	int int1_count;
-	int int2_count;
-};
-
-/*-----------------------------------------------------------------------------
-  The ioctls of the board
-  ----------------------------------------------------------------------------*/
-
-#define ME4000_IOCTL_MAXNR 50
-#define ME4000_MAGIC 'y'
-#define ME4000_GET_USER_INFO          _IOR (ME4000_MAGIC, 0, \
-					    struct me4000_user_info)
-
-#define ME4000_AO_START               _IOW (ME4000_MAGIC, 1, unsigned long)
-#define ME4000_AO_STOP                _IO  (ME4000_MAGIC, 2)
-#define ME4000_AO_IMMEDIATE_STOP      _IO  (ME4000_MAGIC, 3)
-#define ME4000_AO_RESET               _IO  (ME4000_MAGIC, 4)
-#define ME4000_AO_PRELOAD             _IO  (ME4000_MAGIC, 5)
-#define ME4000_AO_PRELOAD_UPDATE      _IO  (ME4000_MAGIC, 6)
-#define ME4000_AO_EX_TRIG_ENABLE      _IO  (ME4000_MAGIC, 7)
-#define ME4000_AO_EX_TRIG_DISABLE     _IO  (ME4000_MAGIC, 8)
-#define ME4000_AO_EX_TRIG_SETUP       _IOW (ME4000_MAGIC, 9, int)
-#define ME4000_AO_TIMER_SET_DIVISOR   _IOW (ME4000_MAGIC, 10, unsigned long)
-#define ME4000_AO_ENABLE_DO           _IO  (ME4000_MAGIC, 11)
-#define ME4000_AO_DISABLE_DO          _IO  (ME4000_MAGIC, 12)
-#define ME4000_AO_FSM_STATE           _IOR (ME4000_MAGIC, 13, int)
-
-#define ME4000_AI_SINGLE              _IOR (ME4000_MAGIC, 14, \
-					    struct me4000_ai_single)
-#define ME4000_AI_START               _IOW (ME4000_MAGIC, 15, unsigned long)
-#define ME4000_AI_STOP                _IO  (ME4000_MAGIC, 16)
-#define ME4000_AI_IMMEDIATE_STOP      _IO  (ME4000_MAGIC, 17)
-#define ME4000_AI_EX_TRIG_ENABLE      _IO  (ME4000_MAGIC, 18)
-#define ME4000_AI_EX_TRIG_DISABLE     _IO  (ME4000_MAGIC, 19)
-#define ME4000_AI_EX_TRIG_SETUP       _IOW (ME4000_MAGIC, 20, \
-					    struct me4000_ai_trigger)
-#define ME4000_AI_CONFIG              _IOW (ME4000_MAGIC, 21, \
-					    struct me4000_ai_config)
-#define ME4000_AI_SC_SETUP            _IOW (ME4000_MAGIC, 22, \
-					    struct me4000_ai_sc)
-#define ME4000_AI_FSM_STATE           _IOR (ME4000_MAGIC, 23, int)
-
-#define ME4000_DIO_CONFIG             _IOW (ME4000_MAGIC, 24, \
-					    struct me4000_dio_config)
-#define ME4000_DIO_GET_BYTE           _IOR (ME4000_MAGIC, 25, \
-					    struct me4000_dio_byte)
-#define ME4000_DIO_SET_BYTE           _IOW (ME4000_MAGIC, 26, \
-					    struct me4000_dio_byte)
-#define ME4000_DIO_RESET              _IO  (ME4000_MAGIC, 27)
-
-#define ME4000_CNT_READ               _IOR (ME4000_MAGIC, 28, \
-					    struct me4000_cnt)
-#define ME4000_CNT_WRITE              _IOW (ME4000_MAGIC, 29, \
-					    struct me4000_cnt)
-#define ME4000_CNT_CONFIG             _IOW (ME4000_MAGIC, 30, \
-					    struct me4000_cnt_config)
-#define ME4000_CNT_RESET              _IO  (ME4000_MAGIC, 31)
-
-#define ME4000_EXT_INT_DISABLE        _IO  (ME4000_MAGIC, 32)
-#define ME4000_EXT_INT_ENABLE         _IO  (ME4000_MAGIC, 33)
-#define ME4000_EXT_INT_COUNT          _IOR (ME4000_MAGIC, 34, int)
-
-#define ME4000_AI_OFFSET_ENABLE       _IO  (ME4000_MAGIC, 35)
-#define ME4000_AI_OFFSET_DISABLE      _IO  (ME4000_MAGIC, 36)
-#define ME4000_AI_FULLSCALE_ENABLE    _IO  (ME4000_MAGIC, 37)
-#define ME4000_AI_FULLSCALE_DISABLE   _IO  (ME4000_MAGIC, 38)
-
-#define ME4000_AI_EEPROM_READ         _IOR (ME4000_MAGIC, 39, \
-					    struct me4000_eeprom)
-#define ME4000_AI_EEPROM_WRITE        _IOW (ME4000_MAGIC, 40, \
-					    struct me4000_eeprom)
-
-#define ME4000_AO_SIMULTANEOUS_EX_TRIG _IO  (ME4000_MAGIC, 41)
-#define ME4000_AO_SIMULTANEOUS_SW      _IO  (ME4000_MAGIC, 42)
-#define ME4000_AO_SIMULTANEOUS_DISABLE _IO  (ME4000_MAGIC, 43)
-#define ME4000_AO_SIMULTANEOUS_UPDATE  _IOW (ME4000_MAGIC, 44, \
-					     struct me4000_ao_channel_list)
-
-#define ME4000_AO_SYNCHRONOUS_EX_TRIG  _IO  (ME4000_MAGIC, 45)
-#define ME4000_AO_SYNCHRONOUS_SW       _IO  (ME4000_MAGIC, 46)
-#define ME4000_AO_SYNCHRONOUS_DISABLE  _IO  (ME4000_MAGIC, 47)
-
-#define ME4000_AO_EX_TRIG_TIMEOUT      _IOW (ME4000_MAGIC, 48, unsigned long)
-#define ME4000_AO_GET_FREE_BUFFER      _IOR (ME4000_MAGIC, 49, unsigned long)
-
-#define ME4000_AI_GET_COUNT_BUFFER     _IOR (ME4000_MAGIC, 50, unsigned long)
-
-#endif
diff --git a/drivers/staging/me4000/me4000_firmware.h b/drivers/staging/me4000/me4000_firmware.h
deleted file mode 100644
index 87c23f6..0000000
--- a/drivers/staging/me4000/me4000_firmware.h
+++ /dev/null
@@ -1,10033 +0,0 @@
-/*
-   This file is copyright by Meilhaus Electronic GmbH 2003.
-   You are not allowed to distribute, sell, modify, reverse engineer or use this
-   code (or parts of it) for any other purpose or under any other conditions
-   than stated below.
-
-   1) You are allowed to distribute verbatim copies of this file together
-   with device drivers for the Meilhaus ME-4000, board family.
-
-   2) Derived work (device drivers using this file) can be published under
-   the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version. Any other license terms have
-   to be agreed by Meilhaus GmbH in written.
-
-   2) This file is distributed WITHOUT ANY WARRANTY;
-   without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE. Meilhaus is under
-   no means liable for products using this file or parts of it.
-
-   3) The copyright of this file has to be mentioned in derived work.
-
-   4) If this license terms are not valid due to any other law
-   or restrictions imposed on you, you are not allowed to use
-   this file in any way at all.
- */
-
-/* Version 18 of standard firmware */
-static unsigned char xilinx_firm[] = {
-0x00, 0x01, 0xfb, 0xdc, 0x01, 0x01, 0x04, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00,
-0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x99, 0xAA, 0x66, 0x0C, 0x00,
-0x01, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x0C, 0x80, 0x06, 0x80, 0x00, 0x00, 0x00,
-0xF0, 0x0C, 0x80, 0x04, 0x80, 0x00, 0x01, 0xFC, 0xB4, 0x0C, 0x00, 0x03, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x90, 0x0C,
-0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00,
-0x00, 0x80, 0x0C, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x6E, 0x0D, 0x01, 0x49, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x80, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x09, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xFE, 0x4B, 0x02, 0x3E, 0x00, 0xEA, 0x00, 0xA8, 0x00, 0xA0,
-0x0A, 0x80, 0x2A, 0x00, 0xAE, 0x00, 0xB8, 0x02, 0xA0, 0x02, 0x80, 0x28, 0x00,
-0xAA, 0x00, 0xB8, 0x02, 0x60, 0x02, 0x80, 0x0B, 0x00, 0x26, 0x00, 0xB8, 0x00,
-0xE0, 0x02, 0x80, 0x0B, 0x00, 0x2E, 0x00, 0xB8, 0x00, 0xE0, 0x02, 0x80, 0x0B,
-0x00, 0xAE, 0x00, 0xB8, 0x02, 0x80, 0x0A, 0xFC, 0x23, 0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0xA0, 0x5B, 0x00, 0xF3, 0x04, 0xCC, 0x01, 0xF2, 0x96, 0xC2,
-0xDF, 0x30, 0xBB, 0x43, 0xD0, 0x73, 0xB0, 0x8F, 0xC0, 0x3D, 0x02, 0xFB, 0x48,
-0xFC, 0x13, 0x30, 0x13, 0xC0, 0x4F, 0x02, 0x3F, 0x01, 0xDC, 0x13, 0xB0, 0x4F,
-0xC0, 0x4F, 0x00, 0x3B, 0xC9, 0xCC, 0x04, 0xF2, 0x13, 0xC0, 0xFC, 0x00, 0xFB,
-0xC9, 0x8C, 0x27, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x08, 0x57, 0x40, 0xE1, 0x08, 0x44, 0x03, 0xD0, 0x09, 0x40, 0x13,
-0x01, 0xD1, 0x04, 0xC4, 0x1B, 0x10, 0x6D, 0x40, 0x3C, 0x02, 0xDD, 0x06, 0xF4,
-0x0F, 0x10, 0x11, 0x40, 0x27, 0x11, 0x57, 0x81, 0xC4, 0x0F, 0xD0, 0xBF, 0x40,
-0x64, 0x00, 0x51, 0x04, 0x44, 0x04, 0xD0, 0x11, 0x50, 0x34, 0x00, 0xD1, 0x00,
-0x54, 0x11, 0x14, 0x19, 0x40, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x11, 0x00, 0x37, 0x00, 0xC1, 0x00, 0x04, 0x00, 0xD8, 0x48, 0x44, 0x21, 0x00,
-0xC9, 0x00, 0x14, 0x03, 0xD0, 0xCC, 0x64, 0x33, 0x11, 0xCD, 0x06, 0x34, 0x23,
-0x50, 0x00, 0x00, 0x02, 0x01, 0x8D, 0x00, 0x04, 0x23, 0xD0, 0x0C, 0x42, 0x01,
-0x00, 0xC1, 0x00, 0x14, 0x00, 0xD0, 0x00, 0x44, 0x30, 0x09, 0xCD, 0x44, 0x44,
-0x12, 0x10, 0x00, 0x44, 0x47, 0x88, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA8, 0xB5, 0x01, 0xD1, 0x00, 0x44, 0x0A, 0xD8, 0x09, 0x40, 0x27, 0x00, 0xD1,
-0x40, 0x44, 0x03, 0x50, 0x0D, 0x60, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x50,
-0x01, 0x40, 0x27, 0x10, 0xD5, 0x00, 0x44, 0x03, 0xCA, 0x0D, 0x40, 0x65, 0x00,
-0xC1, 0x00, 0x44, 0xC6, 0xD0, 0x19, 0x40, 0x30, 0x00, 0xD1, 0x00, 0x54, 0x09,
-0x14, 0x11, 0x40, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8,
-0xE3, 0x00, 0xD3, 0x00, 0x4C, 0x0A, 0xF0, 0x0D, 0xC4, 0xF7, 0x00, 0x9B, 0x40,
-0x5C, 0x03, 0xF2, 0x0D, 0xC6, 0x37, 0x10, 0xDB, 0x00, 0x74, 0x03, 0x70, 0xA1,
-0x81, 0x37, 0x00, 0xCF, 0x03, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0xC7, 0x01, 0x93,
-0x00, 0x5D, 0x0C, 0xF0, 0x31, 0xC0, 0x34, 0x00, 0x5F, 0xC0, 0x0C, 0x07, 0x30,
-0x71, 0x80, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D,
-0x08, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0xFF, 0x18, 0xFF, 0x04, 0xAC,
-0x03, 0xB1, 0x0D, 0xC8, 0x3D, 0x00, 0xFF, 0x80, 0x7C, 0x03, 0xB4, 0x13, 0xCA,
-0xFF, 0x00, 0xF7, 0x03, 0xE4, 0x43, 0xF0, 0x0E, 0xC1, 0x0E, 0x00, 0xFF, 0x00,
-0xFC, 0x40, 0xF0, 0x0B, 0xE2, 0x3F, 0x00, 0xFF, 0x83, 0xFD, 0x25, 0xF0, 0x0B,
-0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00,
-0xD3, 0x00, 0x4C, 0x0A, 0x30, 0x0D, 0xC0, 0xA4, 0x00, 0xD7, 0x00, 0x5C, 0x03,
-0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xD7, 0x00, 0x0C, 0x03, 0x30, 0x41, 0xC4, 0x35,
-0x00, 0xD3, 0x02, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x05, 0x00, 0xDF, 0x00, 0x7C,
-0x0E, 0x30, 0x01, 0xC1, 0x37, 0x10, 0xD7, 0x04, 0x4C, 0x0B, 0x30, 0x21, 0xC0,
-0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xF4, 0x01, 0xF5,
-0x00, 0x44, 0x2E, 0x10, 0x09, 0x40, 0x25, 0x00, 0xD1, 0x00, 0xC4, 0x03, 0x10,
-0x0F, 0xC0, 0x3E, 0x00, 0xF1, 0x00, 0xEC, 0x03, 0x10, 0x11, 0xC0, 0x35, 0x00,
-0xD1, 0x01, 0xDC, 0x07, 0x70, 0x2F, 0xC3, 0x23, 0x06, 0xDD, 0x20, 0x64, 0x02,
-0xB0, 0x38, 0x41, 0x37, 0x00, 0xD1, 0x03, 0x6C, 0x29, 0x50, 0xA9, 0x40, 0x4E,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x01, 0xD1, 0x00,
-0x04, 0x29, 0x90, 0x04, 0x40, 0x24, 0x00, 0xD5, 0x00, 0x34, 0x03, 0x50, 0x0D,
-0x40, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x5D, 0x00, 0x40, 0x12, 0x20, 0x01,
-0x04, 0x10, 0x0B, 0xD0, 0x1C, 0x42, 0x21, 0x80, 0x0D, 0x40, 0x34, 0x08, 0x90,
-0x30, 0x40, 0x31, 0x10, 0xD5, 0x03, 0x04, 0x05, 0x18, 0x18, 0x44, 0x1F, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x68, 0x00, 0xE5, 0x01, 0x84,
-0x07, 0x98, 0x1B, 0x40, 0x69, 0x80, 0xE1, 0x81, 0x24, 0x07, 0x10, 0x9E, 0x40,
-0x78, 0x80, 0xED, 0x01, 0xA4, 0x07, 0x50, 0x52, 0x61, 0x79, 0x00, 0x21, 0x19,
-0x90, 0x07, 0x51, 0x1C, 0x40, 0x6A, 0x00, 0x6D, 0x41, 0xA4, 0x06, 0xD2, 0x12,
-0x40, 0x7B, 0x00, 0xF1, 0x09, 0xE4, 0x45, 0x54, 0x1A, 0x40, 0x12, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x20, 0x02, 0xC3, 0x88, 0x44, 0x02,
-0xB0, 0x88, 0x40, 0x20, 0x00, 0xD7, 0x08, 0x34, 0x03, 0x70, 0x0C, 0x40, 0x37,
-0x02, 0xDD, 0x00, 0x04, 0x03, 0x71, 0x10, 0xC0, 0x16, 0x02, 0x01, 0x80, 0x1C,
-0xC3, 0xF0, 0x0C, 0x40, 0x21, 0x00, 0xCF, 0x09, 0x3C, 0x91, 0xB0, 0x88, 0xC0,
-0x37, 0x00, 0xC7, 0x10, 0x0C, 0x11, 0x38, 0x84, 0xC1, 0x4B, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xB0, 0x2D, 0x00, 0xFF, 0x02, 0xFC, 0x02, 0x60,
-0x0B, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC, 0x43, 0x70, 0x0F, 0xC0, 0x3F, 0x04,
-0xF3, 0x00, 0xFC, 0x0B, 0xB0, 0x02, 0xC0, 0x3F, 0x48, 0xFF, 0x00, 0x7C, 0x2B,
-0xF0, 0x8F, 0xC0, 0x2F, 0x00, 0xFF, 0x20, 0x3C, 0x03, 0x90, 0x09, 0xC0, 0x3F,
-0x00, 0xEE, 0x20, 0x7C, 0x01, 0xD4, 0x01, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0xA0, 0x27, 0x00, 0xDF, 0x0E, 0x7C, 0x00, 0xC0, 0x0D,
-0xC0, 0x75, 0x00, 0xD3, 0x00, 0x7C, 0x53, 0x70, 0x8D, 0xC6, 0xB4, 0x04, 0xDF,
-0x00, 0x7C, 0x13, 0xB0, 0x00, 0xC0, 0x34, 0x10, 0x07, 0x80, 0x5C, 0x13, 0x30,
-0x5C, 0xC1, 0x04, 0x00, 0x9F, 0x40, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00,
-0x5F, 0x00, 0x4C, 0x01, 0x30, 0x09, 0xC0, 0x47, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x0A, 0x40,
-0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x13, 0xD0, 0x4F, 0x40, 0x3A, 0x11, 0xED, 0x00,
-0xB4, 0x03, 0xD0, 0x02, 0x40, 0x39, 0x00, 0xAD, 0x00, 0x04, 0x03, 0x10, 0x2E,
-0x40, 0x08, 0x08, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x3B, 0x00, 0xED,
-0x20, 0xC4, 0x01, 0x10, 0x0A, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x00, 0x69, 0x00, 0xED, 0x01, 0xB4, 0x06, 0x90, 0x3E, 0x4C, 0x6F,
-0x10, 0xE1, 0x01, 0xB4, 0x17, 0xD0, 0x0E, 0x40, 0x7A, 0x00, 0xED, 0x0D, 0x94,
-0x27, 0xD0, 0x13, 0x41, 0x7A, 0x80, 0x6D, 0x01, 0x94, 0x37, 0x51, 0x5E, 0x40,
-0x6A, 0x04, 0xED, 0x01, 0xB4, 0x07, 0xD1, 0x1A, 0x48, 0x7B, 0x80, 0xAD, 0x01,
-0x84, 0x05, 0x14, 0x1E, 0x42, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x28, 0x23, 0x84, 0xCD, 0x00, 0x34, 0x2E, 0xD0, 0x08, 0x40, 0x23, 0x49,
-0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x36, 0x03,
-0xD0, 0x0C, 0x40, 0x33, 0x11, 0xCD, 0x03, 0x04, 0x03, 0x50, 0x0C, 0x40, 0x70,
-0x00, 0xCD, 0x00, 0x34, 0x6F, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x44, 0x05,
-0x21, 0x14, 0x1C, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
-0xA8, 0xD9, 0x00, 0x5F, 0x00, 0xFC, 0x01, 0xB0, 0x07, 0xC4, 0xDF, 0x01, 0x53,
-0x00, 0x7C, 0x01, 0x78, 0x05, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xB0,
-0x17, 0xC0, 0x9E, 0x01, 0x7F, 0x0E, 0x5C, 0x01, 0x74, 0x05, 0xC8, 0x1E, 0x00,
-0x7F, 0x02, 0xFC, 0x0D, 0xE0, 0x07, 0xC0, 0x17, 0x20, 0x7F, 0x07, 0xCC, 0x05,
-0x10, 0x07, 0xC1, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00,
-0x07, 0x02, 0x1F, 0x00, 0x3C, 0x40, 0xF0, 0x41, 0xC0, 0x07, 0x00, 0x1F, 0x60,
-0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
-0xC1, 0x05, 0x10, 0x1F, 0x00, 0x7C, 0x80, 0x91, 0x01, 0xD0, 0x87, 0x01, 0x1F,
-0x30, 0x70, 0x08, 0xF0, 0x41, 0xC0, 0x07, 0x18, 0x1F, 0x40, 0x7D, 0x00, 0xF0,
-0x11, 0xC0, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27,
-0x01, 0x9B, 0x00, 0x4D, 0x02, 0x30, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x74,
-0x02, 0xF0, 0x09, 0xC0, 0x23, 0x40, 0x93, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0,
-0x24, 0x00, 0x9F, 0x00, 0x44, 0x02, 0x70, 0x09, 0xC4, 0x67, 0x02, 0x9D, 0x00,
-0x4C, 0x16, 0xF0, 0x19, 0xC0, 0x27, 0x80, 0x9F, 0x03, 0x4C, 0x22, 0x34, 0x08,
-0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x00,
-0x95, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02,
-0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x06, 0xF0, 0xB8, 0x40, 0x24,
-0x00, 0x8D, 0x08, 0x01, 0x06, 0x30, 0x29, 0xC0, 0x27, 0x21, 0x8D, 0x00, 0x44,
-0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x8D, 0x03, 0x6C, 0x1E, 0x54, 0x29, 0x40,
-0x05, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x81,
-0x00, 0x44, 0x22, 0x10, 0x08, 0x40, 0x35, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0,
-0x09, 0x40, 0x26, 0x00, 0x99, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x60, 0x24, 0x80,
-0xDD, 0x80, 0x54, 0x12, 0x00, 0xA9, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02,
-0xD0, 0x4D, 0x43, 0x27, 0x00, 0x98, 0x10, 0x04, 0x02, 0x10, 0xA9, 0x40, 0x60,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x85, 0x04,
-0x04, 0x1A, 0x14, 0x08, 0x40, 0x20, 0x20, 0x8D, 0x08, 0x34, 0x12, 0xD0, 0x88,
-0x64, 0x23, 0x01, 0x89, 0x08, 0x34, 0x12, 0xD0, 0x09, 0x40, 0x20, 0x02, 0xDD,
-0x00, 0x14, 0x02, 0x14, 0x08, 0x44, 0x23, 0x00, 0x9D, 0x08, 0x04, 0x02, 0xD8,
-0x08, 0x42, 0x23, 0x02, 0x9D, 0x08, 0x24, 0x22, 0x10, 0x48, 0x40, 0x41, 0x88,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x13, 0x0A, 0x4C,
-0x09, 0x30, 0xA1, 0xC0, 0x85, 0x02, 0x1D, 0x02, 0x7C, 0x28, 0xF0, 0x61, 0xC1,
-0x87, 0x02, 0x19, 0x16, 0x74, 0x00, 0xF0, 0x05, 0xC0, 0x84, 0x00, 0x1F, 0x00,
-0x5C, 0x51, 0x70, 0x41, 0x45, 0x07, 0x10, 0x1F, 0x02, 0x4D, 0x01, 0xF0, 0x01,
-0xC4, 0x87, 0x00, 0x0D, 0x02, 0x4C, 0x88, 0x30, 0x01, 0xC4, 0x74, 0xC0, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x00, 0x9F, 0x08, 0xFC, 0x0A,
-0xF0, 0x0B, 0xC0, 0x2B, 0x00, 0xBF, 0x04, 0x7C, 0x22, 0xF0, 0x49, 0xC0, 0x27,
-0x02, 0x93, 0x04, 0x7C, 0x22, 0x70, 0x0B, 0xD0, 0x2F, 0x01, 0xBF, 0x00, 0x6C,
-0x02, 0x70, 0x09, 0xC0, 0x2D, 0x10, 0xBF, 0x04, 0xFC, 0x02, 0xF0, 0x0B, 0xC0,
-0x27, 0x01, 0xBF, 0x84, 0xFC, 0x12, 0xF0, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0x93, 0x8C, 0xE8, 0x02, 0xF0,
-0x09, 0xC0, 0x27, 0x02, 0x93, 0x60, 0x7C, 0x52, 0x30, 0xC9, 0xC0, 0x25, 0x00,
-0x9B, 0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xCC, 0x02,
-0xB0, 0x0B, 0xC0, 0x2B, 0x28, 0x9F, 0x40, 0xBC, 0x02, 0xF0, 0x0F, 0xC0, 0x24,
-0x20, 0xBF, 0x40, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x11, 0x0C, 0x44, 0x49, 0xD0, 0x01,
-0x41, 0x07, 0x00, 0x11, 0x14, 0x74, 0x10, 0x10, 0xC1, 0x48, 0x84, 0x04, 0x11,
-0x10, 0x44, 0x20, 0xD2, 0x01, 0x40, 0x07, 0x01, 0x1D, 0x00, 0x50, 0x08, 0x14,
-0x01, 0x40, 0x17, 0x00, 0x1D, 0x14, 0x64, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x0C,
-0x5D, 0x90, 0x54, 0x00, 0x14, 0x01, 0x50, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA0, 0x27, 0x40, 0x81, 0x04, 0x34, 0x32, 0xD0, 0x08, 0x40,
-0x27, 0x40, 0x85, 0x04, 0x34, 0x52, 0x10, 0x48, 0x40, 0x21, 0x03, 0x89, 0x08,
-0x14, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x05, 0x9D, 0x00, 0x04, 0x22, 0x12, 0x8C,
-0x42, 0x23, 0x00, 0x8D, 0x04, 0x34, 0x02, 0x50, 0x09, 0x40, 0x23, 0x01, 0x8D,
-0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA8, 0x25, 0x04, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x69, 0x60, 0x27,
-0x00, 0x95, 0x00, 0x34, 0x02, 0x10, 0x09, 0x60, 0x21, 0x00, 0x91, 0x00, 0x44,
-0x02, 0xD0, 0x29, 0x40, 0x27, 0x80, 0x9C, 0x02, 0x54, 0x02, 0x10, 0x09, 0x40,
-0x27, 0x00, 0x9D, 0x00, 0x64, 0x0A, 0xD0, 0x29, 0x40, 0x27, 0x80, 0x8D, 0x08,
-0x54, 0x12, 0x12, 0x19, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0xA8, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x0E, 0xF0, 0x39, 0xE0, 0x27, 0x21,
-0x97, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC2, 0x25, 0x00, 0x9B, 0x00, 0x5C, 0x02,
-0xF0, 0x29, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x4C, 0x02, 0xB0, 0x09, 0xC0, 0x67,
-0x00, 0x9F, 0x24, 0x7C, 0x02, 0xF8, 0x88, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C,
-0x02, 0x30, 0x59, 0xC0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x00, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x56, 0xF0, 0x19, 0xC0, 0x67, 0x01, 0x9B,
-0x04, 0x7C, 0x02, 0xF4, 0x08, 0xCC, 0x26, 0x00, 0x8F, 0x00, 0x7C, 0x02, 0xF0,
-0x39, 0xC2, 0x27, 0x00, 0x9F, 0x02, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x01,
-0x9F, 0x05, 0x7C, 0x22, 0xF0, 0x19, 0xC2, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0xF0, 0x08, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
-0x05, 0x00, 0x0F, 0x00, 0x5C, 0x08, 0xF0, 0x21, 0xC0, 0x85, 0x00, 0x1F, 0x00,
-0x7C, 0x00, 0xF0, 0x01, 0xE0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21,
-0xC1, 0x07, 0x00, 0x1B, 0x06, 0x4C, 0x40, 0xF0, 0x01, 0xC1, 0x04, 0x01, 0x13,
-0x02, 0x7C, 0x00, 0xB0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x4C, 0x20, 0x31,
-0x21, 0x80, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x18,
-0x00, 0x5D, 0x00, 0xC0, 0x05, 0x70, 0x05, 0x40, 0x10, 0x00, 0x5C, 0x00, 0x74,
-0x01, 0xD0, 0x05, 0xC0, 0x15, 0x00, 0x5D, 0x00, 0x74, 0x45, 0xD0, 0x07, 0xC0,
-0x15, 0x00, 0x61, 0x00, 0xDC, 0x4D, 0x70, 0x07, 0x40, 0xDD, 0x40, 0x51, 0x00,
-0xF4, 0x3D, 0x10, 0x77, 0x40, 0x17, 0x40, 0x71, 0x00, 0x84, 0x0D, 0xF0, 0xA7,
-0xC0, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x22, 0x20,
-0xCD, 0x80, 0x10, 0x0F, 0x50, 0x0C, 0x40, 0x33, 0x80, 0xCC, 0x00, 0x34, 0x03,
-0xD0, 0x0C, 0x00, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0xBC, 0x40, 0x33,
-0x00, 0xC9, 0x01, 0x24, 0x07, 0x50, 0x0C, 0x40, 0xF0, 0x00, 0xC1, 0x20, 0x34,
-0x07, 0x10, 0x4C, 0x60, 0x33, 0x90, 0xC9, 0x00, 0x04, 0x4F, 0x10, 0x2C, 0x42,
-0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xCD,
-0x04, 0x84, 0x0B, 0x50, 0x1E, 0x40, 0x3A, 0x03, 0xED, 0x08, 0xB4, 0x03, 0xD0,
-0x8E, 0x40, 0x39, 0xA1, 0xED, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x7D, 0x00,
-0xFD, 0x42, 0x90, 0x03, 0x50, 0x18, 0x40, 0xFD, 0x10, 0xE1, 0x04, 0xF4, 0x06,
-0x10, 0x0E, 0x40, 0x7B, 0x00, 0xE9, 0x00, 0xC5, 0x01, 0x90, 0x0C, 0x60, 0x12,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x07,
-0x94, 0x07, 0x70, 0x1F, 0xC8, 0x7B, 0x00, 0xEF, 0x05, 0xB4, 0x0F, 0xF0, 0x1E,
-0x40, 0x7B, 0x04, 0xED, 0x01, 0xBC, 0x07, 0xF2, 0x1A, 0xC8, 0x7B, 0x24, 0xFB,
-0x01, 0xAC, 0x84, 0x70, 0x1A, 0xC0, 0x78, 0x00, 0xE1, 0x09, 0xB4, 0x06, 0x34,
-0x1E, 0xC4, 0x7F, 0x08, 0x79, 0x01, 0xCC, 0x06, 0x32, 0x16, 0xC0, 0x50, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x10, 0xDF, 0x02, 0x7C,
-0x03, 0x70, 0xED, 0xC8, 0xB5, 0x21, 0xDF, 0x00, 0x7C, 0x43, 0xF0, 0x0D, 0xC8,
-0x37, 0x02, 0xDF, 0x88, 0x7C, 0x03, 0xD0, 0x09, 0xC0, 0x33, 0x01, 0x93, 0x80,
-0x7C, 0x01, 0x60, 0x01, 0xC0, 0x17, 0x00, 0xDF, 0x2A, 0x7C, 0x00, 0x60, 0x09,
-0xC0, 0xB7, 0x06, 0x97, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC2, 0x43, 0x60, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00, 0xFF, 0x03, 0xC8, 0x21,
-0xE0, 0x3E, 0xC2, 0xFC, 0x12, 0xFF, 0x09, 0xEC, 0x07, 0x30, 0x1F, 0xC0, 0x7F,
-0x02, 0xFB, 0x01, 0xDC, 0x27, 0xF0, 0x9F, 0xC0, 0x7D, 0x04, 0xB3, 0x41, 0xBC,
-0x27, 0xB0, 0x13, 0xC0, 0x7F, 0x00, 0xFF, 0x21, 0xFC, 0x06, 0xF0, 0x1F, 0xC0,
-0x7F, 0x00, 0xFF, 0x01, 0xBC, 0x87, 0x30, 0x1F, 0xC0, 0x0B, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x10, 0xFD, 0x04, 0x84, 0x01, 0xF0,
-0x0E, 0xC1, 0x3A, 0x00, 0xED, 0x00, 0xEC, 0x03, 0x15, 0x8E, 0x48, 0x3B, 0x40,
-0xF1, 0x00, 0x84, 0x23, 0xD0, 0xA8, 0x40, 0x3B, 0x20, 0x21, 0x00, 0xB4, 0x29,
-0x10, 0x62, 0x40, 0x3B, 0x00, 0xDF, 0x00, 0x84, 0x02, 0xF0, 0x0E, 0x40, 0x3B,
-0x02, 0xED, 0x08, 0xBC, 0x01, 0xB0, 0x0E, 0x41, 0x57, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x00, 0x86, 0x63, 0xD8, 0x0F,
-0x40, 0x38, 0x80, 0xFD, 0x40, 0x84, 0x23, 0x90, 0x0E, 0x40, 0x33, 0x10, 0xE1,
-0x00, 0xB4, 0x23, 0xD2, 0x22, 0x60, 0x39, 0x00, 0xA5, 0x00, 0xB4, 0x00, 0x12,
-0x02, 0x40, 0x2A, 0x00, 0xED, 0x10, 0x94, 0x02, 0xD0, 0x06, 0x40, 0x3B, 0x00,
-0x6D, 0x00, 0xF4, 0x02, 0x10, 0x06, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x06, 0x28, 0x23, 0x00, 0xCD, 0x00, 0x04, 0x06, 0x58, 0x3C, 0x40,
-0x32, 0x00, 0xCD, 0x08, 0x24, 0x03, 0x90, 0x0C, 0x42, 0x33, 0x20, 0xC1, 0x00,
-0x16, 0x03, 0xD0, 0x00, 0x40, 0xB3, 0x00, 0x05, 0x0B, 0x36, 0x01, 0x10, 0x00,
-0x40, 0x03, 0x10, 0xCD, 0x40, 0x04, 0x10, 0x51, 0x00, 0x40, 0x33, 0x00, 0x9D,
-0x12, 0x14, 0xAF, 0x90, 0x50, 0x00, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0xA8, 0x25, 0x01, 0xFF, 0x00, 0x4D, 0x22, 0xD0, 0x3F, 0xC0, 0x3C,
-0x00, 0xFF, 0x00, 0xCC, 0x03, 0xB0, 0x0F, 0xC0, 0x3F, 0x00, 0xF3, 0x00, 0x1C,
-0x02, 0xF0, 0x25, 0xC0, 0xBD, 0x02, 0x57, 0x0B, 0x7C, 0x03, 0x11, 0x09, 0xC0,
-0xF7, 0x02, 0xEF, 0x00, 0x5C, 0x0A, 0xD0, 0x9D, 0x40, 0x3F, 0x00, 0x9F, 0x02,
-0x70, 0x03, 0x10, 0x21, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x4D, 0xC4, 0x37, 0x10,
-0xDF, 0x80, 0x7C, 0x83, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xD7, 0x80, 0x64, 0x02,
-0xF0, 0x3D, 0xC0, 0x37, 0x48, 0x5A, 0x00, 0x7C, 0x03, 0x70, 0x29, 0xC0, 0x67,
-0x00, 0xD7, 0x00, 0x5C, 0x0A, 0xF0, 0x15, 0xC4, 0x37, 0x20, 0x5F, 0x02, 0x7C,
-0x09, 0xF0, 0x29, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x08, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0x30, 0x0F, 0xC0, 0x3D, 0x00, 0xFF,
-0x00, 0xFE, 0x03, 0xF2, 0x0F, 0xC2, 0x3F, 0x80, 0xFF, 0x00, 0xFC, 0x03, 0xB1,
-0x17, 0xC2, 0x3F, 0x00, 0xF3, 0x01, 0xFC, 0x06, 0xF0, 0x0B, 0xC0, 0x7F, 0x00,
-0xFF, 0x00, 0xCC, 0x02, 0xD0, 0x8F, 0xC0, 0x3F, 0x00, 0x31, 0x00, 0xCC, 0x62,
-0x30, 0x03, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
-0x56, 0x00, 0xDD, 0x00, 0x34, 0x0E, 0xD0, 0x0D, 0x40, 0x37, 0x80, 0xDD, 0x00,
-0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0xA0, 0xDF, 0x20, 0x74, 0x03, 0x31, 0x9D,
-0xC0, 0x31, 0x00, 0x91, 0x0A, 0x74, 0x0F, 0x78, 0x11, 0x40, 0x87, 0x01, 0xDD,
-0x00, 0x6C, 0x44, 0x70, 0x01, 0x41, 0x37, 0x00, 0x13, 0x0F, 0x14, 0x44, 0x10,
-0x39, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA6,
-0x02, 0xDD, 0x00, 0x74, 0x0C, 0x90, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x80, 0x74,
-0x03, 0xD2, 0x0D, 0x48, 0x37, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x05, 0x40,
-0x37, 0x00, 0x55, 0x82, 0x74, 0x12, 0xD0, 0x19, 0x40, 0x17, 0x02, 0xD9, 0x00,
-0x44, 0x04, 0xD0, 0x09, 0x42, 0x33, 0x00, 0x95, 0x00, 0x44, 0x03, 0x10, 0x19,
-0x41, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00,
-0xCD, 0x00, 0x74, 0x00, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x36, 0x03,
-0xD0, 0x0C, 0x40, 0x33, 0x20, 0xC5, 0x00, 0x34, 0x03, 0x10, 0x88, 0x48, 0x35,
-0x00, 0x45, 0x00, 0x34, 0x00, 0x58, 0x08, 0x60, 0x03, 0x00, 0xDD, 0x00, 0x25,
-0x00, 0x50, 0x00, 0x48, 0x33, 0x40, 0x45, 0x00, 0x44, 0x00, 0x11, 0x08, 0x40,
-0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0xFF,
-0x00, 0x7C, 0x00, 0x10, 0x0F, 0xC0, 0x3D, 0x00, 0xDD, 0x00, 0xF4, 0x03, 0xF0,
-0x0D, 0xC0, 0x3F, 0x00, 0xDD, 0x00, 0x7E, 0x03, 0xB0, 0x05, 0x48, 0x3B, 0x00,
-0xD5, 0x00, 0x7C, 0x02, 0xD0, 0x09, 0xC0, 0x07, 0x00, 0xFF, 0x08, 0x4C, 0x00,
-0xF0, 0x01, 0xC0, 0x3F, 0x00, 0x17, 0x00, 0x4D, 0x00, 0x30, 0x09, 0xC0, 0x03,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00, 0xFF, 0x00,
-0xFC, 0x02, 0x70, 0x0F, 0xC0, 0x3F, 0x00, 0xEF, 0x80, 0xFC, 0x03, 0xF0, 0x0F,
-0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0x71, 0x43, 0xC0, 0x3D, 0x00, 0x3B,
-0x00, 0xFC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xDC, 0x00, 0x78,
-0x03, 0xC0, 0x3F, 0x00, 0x33, 0x00, 0xFF, 0x80, 0xF0, 0x0B, 0xC2, 0x17, 0x60,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0F, 0x04, 0x33, 0x01, 0xC4,
-0x02, 0xB8, 0x0B, 0xC0, 0xBF, 0x01, 0xFB, 0x2C, 0xEC, 0x8E, 0x70, 0x2F, 0xC0,
-0x4F, 0x00, 0xF7, 0x18, 0x8C, 0x24, 0xF0, 0x4F, 0xC1, 0x4F, 0x02, 0xFF, 0x44,
-0xDC, 0x27, 0x30, 0x8F, 0xC0, 0x3F, 0x00, 0xE7, 0x00, 0xEC, 0x04, 0xF0, 0x0F,
-0xC0, 0x6C, 0x00, 0xFB, 0x10, 0x9C, 0x52, 0xF0, 0x13, 0xC0, 0x0C, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x87, 0x00, 0x11, 0x00, 0x6C, 0x02,
-0xF0, 0x09, 0x40, 0xBF, 0x00, 0xF1, 0x02, 0x4C, 0x13, 0x10, 0x8F, 0x40, 0x67,
-0x08, 0xF1, 0x02, 0x44, 0x10, 0xD2, 0x3F, 0xC2, 0x23, 0x08, 0xF1, 0x03, 0x44,
-0x13, 0x04, 0x6F, 0x40, 0xFC, 0x20, 0xF1, 0x0B, 0x44, 0x04, 0xD1, 0x3F, 0xC0,
-0x44, 0x00, 0xD5, 0x43, 0x74, 0x04, 0xD0, 0x15, 0xC0, 0x06, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0x01, 0x00, 0x15, 0x00, 0x92,
-0x08, 0x42, 0x33, 0x03, 0xC9, 0x0C, 0x34, 0x03, 0x50, 0x4C, 0x44, 0x07, 0x80,
-0xC5, 0x20, 0x04, 0x12, 0xD0, 0x0C, 0x42, 0x13, 0x10, 0xC9, 0x02, 0x14, 0x03,
-0x10, 0x2C, 0x40, 0xB1, 0x00, 0xC5, 0x00, 0x07, 0x00, 0x50, 0x2C, 0x40, 0x26,
-0x00, 0xC1, 0x20, 0x34, 0x02, 0xD0, 0x05, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x41, 0x04, 0x01, 0x01, 0x54, 0x0E, 0x50, 0x19,
-0x40, 0x37, 0x00, 0xD1, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x47, 0x00, 0xD1,
-0x00, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x25, 0x04, 0xD5, 0x00, 0x44, 0x03, 0x18,
-0x0D, 0x08, 0x34, 0x00, 0xD1, 0x00, 0x64, 0x04, 0xD0, 0x0D, 0x40, 0x64, 0x00,
-0xD5, 0x00, 0x74, 0x06, 0xD0, 0x35, 0x40, 0x0E, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0xA8, 0xC7, 0x00, 0x13, 0x03, 0x54, 0x0C, 0x90, 0x51, 0xC0,
-0x37, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC4, 0x43, 0x00, 0xD7, 0x00,
-0x4C, 0x0E, 0xF0, 0x0D, 0x48, 0x97, 0x02, 0xDF, 0x00, 0x5C, 0x03, 0x32, 0x0D,
-0xC0, 0x37, 0x10, 0xD7, 0x00, 0x6E, 0x44, 0xF0, 0x0D, 0xD0, 0x62, 0x00, 0xDB,
-0x00, 0x5C, 0x16, 0xF2, 0x1D, 0xE0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x07, 0x80, 0x05, 0x00, 0x3F, 0x00, 0x6D, 0x80, 0xF0, 0x03, 0xC0, 0x3F,
-0x00, 0xEF, 0x00, 0xEC, 0x03, 0xF8, 0x0D, 0xC0, 0x2F, 0x80, 0xEB, 0x40, 0xFC,
-0x00, 0xF2, 0x0F, 0xC0, 0x4F, 0x00, 0xEB, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0,
-0x3B, 0x04, 0xFD, 0x80, 0xDC, 0x40, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00,
-0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x08, 0x85, 0x00, 0x1B, 0x00, 0x4D, 0x08, 0x30, 0x09, 0xC3, 0x33, 0x00,
-0xDF, 0x00, 0x5C, 0x03, 0x70, 0x0D, 0xC0, 0x85, 0x00, 0xDF, 0x00, 0x4C, 0x0A,
-0x30, 0x0D, 0xC6, 0x16, 0x00, 0xD3, 0x10, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x36,
-0x00, 0xDF, 0x20, 0x4C, 0x08, 0x70, 0x0C, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7E,
-0x42, 0x70, 0x2D, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
-0xA0, 0x04, 0x00, 0x11, 0x01, 0x44, 0x4E, 0x00, 0x69, 0x40, 0x3F, 0x10, 0xFD,
-0x00, 0x4C, 0x03, 0x10, 0x0F, 0x40, 0xA4, 0x03, 0xFD, 0x00, 0x44, 0x00, 0x12,
-0x0F, 0x40, 0x24, 0x00, 0xF0, 0x03, 0x54, 0x03, 0xD0, 0x0F, 0x40, 0x7C, 0x04,
-0xED, 0x00, 0x45, 0x04, 0xD0, 0x1F, 0x40, 0x47, 0x00, 0xFD, 0x00, 0x74, 0x0E,
-0x10, 0x0D, 0x43, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0,
-0x42, 0x00, 0x09, 0x24, 0x00, 0x46, 0x90, 0x00, 0x40, 0x33, 0x20, 0xC9, 0x00,
-0x52, 0x02, 0xD0, 0x0C, 0x48, 0xA1, 0x00, 0xCC, 0x00, 0x14, 0x00, 0x10, 0x0C,
-0x48, 0x27, 0x60, 0xC1, 0x01, 0x44, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
-0x04, 0x24, 0x04, 0xD0, 0x8C, 0x49, 0x23, 0x12, 0xCD, 0x00, 0x16, 0x04, 0x51,
-0x0D, 0x41, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x48,
-0x24, 0x21, 0x01, 0x84, 0x07, 0x18, 0x1E, 0x40, 0x7B, 0x00, 0xCD, 0x01, 0x94,
-0x07, 0x90, 0x9E, 0x40, 0x78, 0xA0, 0xED, 0x01, 0xD4, 0x04, 0x14, 0x1E, 0x40,
-0x69, 0x00, 0xE1, 0x11, 0x94, 0x07, 0xC0, 0x1C, 0x40, 0x79, 0x00, 0xED, 0x95,
-0x84, 0x05, 0xD2, 0x1E, 0x40, 0x4B, 0x00, 0xED, 0x09, 0xB6, 0x44, 0x10, 0x1F,
-0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x00, 0x00,
-0x1B, 0x10, 0x0D, 0x21, 0xB0, 0x04, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x5C, 0x03,
-0xF0, 0x0C, 0xC8, 0x81, 0x00, 0xDE, 0x00, 0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x33,
-0x03, 0xC3, 0x80, 0x1C, 0x83, 0xF0, 0x4C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x0C,
-0x40, 0x70, 0x0C, 0xE4, 0x23, 0x22, 0xCF, 0x00, 0x1E, 0x14, 0x70, 0x0C, 0xC0,
-0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x12, 0x7F,
-0x08, 0xFC, 0x03, 0x54, 0x0F, 0xC0, 0x3F, 0x80, 0xFF, 0x02, 0xEC, 0x03, 0x70,
-0x0F, 0xC3, 0x1F, 0x00, 0xFF, 0x08, 0xEC, 0x03, 0xF0, 0x2E, 0xC4, 0x3E, 0x02,
-0xEF, 0x10, 0xF8, 0x23, 0xF0, 0x0F, 0xC1, 0x3E, 0x00, 0xFF, 0x06, 0xDC, 0x01,
-0xF0, 0x0F, 0xC0, 0x2F, 0x08, 0xFF, 0x20, 0xFE, 0x20, 0xF2, 0x0C, 0xC0, 0x0B,
-0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x07, 0x00, 0x03, 0x00,
-0x4C, 0x03, 0xF0, 0x05, 0xC0, 0xB7, 0x01, 0xDB, 0x0E, 0x7C, 0x03, 0xF0, 0x5D,
-0xC1, 0x24, 0x00, 0xDF, 0x86, 0x7C, 0x86, 0x70, 0x3D, 0xC0, 0x16, 0x00, 0xDF,
-0x10, 0x7C, 0x03, 0xF0, 0x4D, 0xC1, 0x36, 0x01, 0xDF, 0x01, 0x4C, 0x00, 0xF0,
-0xAC, 0xC0, 0x24, 0x00, 0xDF, 0x01, 0x4C, 0x06, 0x30, 0x0D, 0xC0, 0x54, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x08, 0x21, 0x00, 0x84,
-0x03, 0xD0, 0x0E, 0x40, 0xBB, 0x0D, 0xE1, 0x00, 0x9C, 0x03, 0xD0, 0x4E, 0x50,
-0x38, 0x80, 0xED, 0x12, 0xB4, 0x02, 0x10, 0x0E, 0x40, 0x18, 0x00, 0xED, 0x04,
-0xB0, 0x83, 0xD0, 0x4E, 0x42, 0xB8, 0x82, 0xCD, 0x04, 0xA5, 0x01, 0xD0, 0x4E,
-0x49, 0x29, 0x00, 0xED, 0x00, 0x94, 0x00, 0x11, 0x0E, 0xC0, 0x4A, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x49, 0x04, 0x21, 0x01, 0x84, 0x0D,
-0xD0, 0x16, 0x41, 0x73, 0x01, 0xE9, 0x05, 0x94, 0x07, 0xD0, 0x5E, 0x40, 0x68,
-0x00, 0xED, 0x05, 0xB4, 0x07, 0x50, 0x9C, 0x50, 0x79, 0x80, 0xED, 0x01, 0xB4,
-0x87, 0x58, 0x1E, 0x40, 0x78, 0x00, 0xED, 0x08, 0xA4, 0x04, 0x50, 0x1E, 0x40,
-0x78, 0x00, 0xCD, 0x01, 0x04, 0x06, 0x10, 0x1F, 0x40, 0x0C, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x77, 0x20, 0xD1, 0x04, 0x04, 0x07, 0xD0,
-0x3C, 0x41, 0x33, 0x00, 0xC1, 0x40, 0x14, 0xA7, 0xD8, 0x0C, 0x40, 0xB0, 0x00,
-0xCD, 0x00, 0x34, 0x0B, 0x10, 0x0C, 0x40, 0x71, 0x83, 0xCD, 0x00, 0x34, 0x03,
-0xD9, 0x0D, 0x50, 0x30, 0x00, 0xDD, 0x00, 0x24, 0x4B, 0xD1, 0x0C, 0x48, 0x11,
-0x14, 0xCD, 0x00, 0x16, 0x27, 0x10, 0x0C, 0x40, 0x4A, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x17, 0xA8, 0x5D, 0x40, 0x73, 0x00, 0xCD, 0x0D, 0xF0, 0x07,
-0xC0, 0x17, 0x00, 0x5B, 0x00, 0x5C, 0x01, 0xF0, 0x05, 0xC0, 0x18, 0x02, 0x5F,
-0x00, 0xFC, 0x01, 0x70, 0x05, 0xC0, 0x5D, 0x18, 0x5F, 0x00, 0x7C, 0x01, 0xF0,
-0x05, 0xC0, 0x14, 0x00, 0x5D, 0x80, 0xC5, 0x01, 0xF8, 0x05, 0xC0, 0x5C, 0x00,
-0x5F, 0x00, 0xCC, 0x01, 0x30, 0x67, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x10, 0xF0, 0x01, 0xC0,
-0x07, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00,
-0x7C, 0x00, 0xF0, 0x01, 0x40, 0x04, 0x20, 0x1F, 0x82, 0x7C, 0x00, 0xF0, 0x01,
-0xC0, 0x01, 0x00, 0x1F, 0x02, 0x5C, 0x80, 0xF0, 0x21, 0xC0, 0x07, 0x02, 0x1F,
-0x00, 0x7C, 0x8C, 0xF0, 0x01, 0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x08, 0x67, 0x02, 0x93, 0x00, 0x4C, 0x0E, 0xF0, 0x39, 0xC0, 0x27,
-0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x93, 0x00, 0x7C,
-0x42, 0xF0, 0x29, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0xB2, 0x09, 0xC2,
-0xE5, 0x00, 0x97, 0x05, 0x4C, 0x02, 0xF0, 0x08, 0xD0, 0x24, 0x00, 0x9F, 0x00,
-0x5E, 0x02, 0xF0, 0x29, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x20, 0xE6, 0x60, 0x91, 0x03, 0x44, 0x06, 0xD0, 0x19, 0x40, 0x27, 0x00,
-0x91, 0x00, 0x5C, 0x02, 0xD0, 0x09, 0x46, 0x27, 0x00, 0x95, 0x00, 0x74, 0x02,
-0xD0, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x03, 0x74, 0x02, 0x10, 0x09, 0x48, 0xE4,
-0x04, 0x91, 0x00, 0x44, 0x26, 0xD1, 0x49, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74,
-0x4E, 0xD2, 0x18, 0xC0, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA0, 0x24, 0x04, 0xD1, 0x08, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x95,
-0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x04, 0x99, 0x00, 0x74, 0x02, 0xD0,
-0x09, 0x40, 0x27, 0x00, 0x95, 0x02, 0x34, 0x02, 0x90, 0x09, 0x60, 0x25, 0x00,
-0x95, 0x40, 0x46, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x01, 0x9D, 0x00, 0x54, 0x22,
-0xD0, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
-0x20, 0x01, 0x81, 0x00, 0x04, 0x13, 0xD0, 0xC8, 0x40, 0x23, 0x11, 0x81, 0x0C,
-0x14, 0x22, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x85, 0x04, 0x34, 0x22, 0xD0, 0x48,
-0x60, 0x23, 0x02, 0x8D, 0x00, 0x34, 0x22, 0x10, 0x88, 0x40, 0x20, 0x08, 0x91,
-0x00, 0x04, 0x06, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x8D, 0x04, 0x34, 0x12, 0xD0,
-0x08, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x82,
-0x02, 0x53, 0x0A, 0x4D, 0x30, 0xF0, 0x45, 0xC1, 0x87, 0x02, 0x17, 0x02, 0x7C,
-0x08, 0xF0, 0xA0, 0xC0, 0x07, 0x08, 0x13, 0x0A, 0x3C, 0x08, 0xF0, 0x01, 0xC0,
-0x87, 0x00, 0x17, 0x14, 0x7C, 0x08, 0xB0, 0x60, 0xC1, 0x05, 0x85, 0x56, 0x14,
-0x44, 0x00, 0xF0, 0x41, 0xD1, 0x04, 0x00, 0x1F, 0x14, 0x5C, 0x00, 0xF0, 0x01,
-0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x90, 0x2F, 0x22,
-0xBF, 0x00, 0xFC, 0x33, 0xF0, 0x4B, 0xC0, 0x27, 0x02, 0x9F, 0x0C, 0xDC, 0x12,
-0xF0, 0x89, 0xC0, 0x2F, 0x30, 0x9F, 0x08, 0xFC, 0x12, 0xF0, 0x89, 0xC8, 0x2F,
-0x01, 0x9F, 0x40, 0x7C, 0x12, 0xF0, 0x49, 0xC2, 0x27, 0x08, 0x9F, 0x00, 0xFC,
-0x02, 0xD0, 0x09, 0xC0, 0x2F, 0x08, 0x9F, 0x00, 0xFC, 0x22, 0xF0, 0x0A, 0xC0,
-0x65, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x01, 0xBF,
-0x00, 0xCC, 0x32, 0xE0, 0x0B, 0xC8, 0x24, 0x00, 0x9F, 0x08, 0x6C, 0x02, 0xE0,
-0x49, 0xC1, 0x2E, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x0B, 0xD8, 0x24, 0x20,
-0xBF, 0x34, 0x7C, 0x22, 0xF0, 0x09, 0xE0, 0x2D, 0x00, 0xB3, 0x00, 0xEC, 0x02,
-0xF0, 0x4B, 0xC1, 0x2C, 0x20, 0x9F, 0x55, 0xF8, 0x02, 0xF0, 0x0A, 0xC0, 0x60,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x05, 0x1D, 0x04,
-0x44, 0xB0, 0xD0, 0x25, 0x41, 0x04, 0x04, 0x1D, 0x08, 0x44, 0x50, 0xD2, 0x41,
-0x44, 0x04, 0x00, 0x17, 0x12, 0x74, 0x40, 0x14, 0x81, 0x68, 0x04, 0x05, 0x1D,
-0x00, 0x74, 0x10, 0x71, 0x21, 0x41, 0x04, 0x00, 0x15, 0x08, 0x44, 0x00, 0xD0,
-0x01, 0x40, 0x05, 0x20, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0xC0, 0x72, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x03, 0x8D, 0x15, 0x04,
-0x92, 0xD0, 0xC8, 0x40, 0x20, 0x02, 0x8D, 0x00, 0x24, 0x12, 0xD0, 0x48, 0x41,
-0x22, 0x20, 0x8D, 0x0C, 0x36, 0x02, 0x10, 0x08, 0x40, 0x22, 0x21, 0x8D, 0x00,
-0x30, 0x12, 0xD1, 0xC8, 0x40, 0x31, 0x02, 0x81, 0x00, 0x14, 0x02, 0xD0, 0x08,
-0x40, 0x22, 0x00, 0x8D, 0x80, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x40, 0x88, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x65, 0x00, 0x8D, 0x00, 0x44, 0x02,
-0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x22, 0xD0, 0x09, 0x40, 0x24,
-0x00, 0x95, 0x00, 0x74, 0x42, 0x10, 0x09, 0x40, 0x26, 0x06, 0x9D, 0x00, 0x74,
-0x02, 0x50, 0x08, 0x48, 0x34, 0x08, 0x95, 0x20, 0x46, 0x43, 0xD0, 0x09, 0x40,
-0x67, 0x00, 0x9D, 0x00, 0x76, 0x0E, 0xD0, 0x49, 0x40, 0x62, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0x88, 0xE7, 0x04, 0x9F, 0x01, 0x4D, 0x02, 0xF0,
-0x39, 0xE0, 0x24, 0x00, 0x9D, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x04,
-0x9F, 0x00, 0x7C, 0x0A, 0x30, 0x09, 0x40, 0x66, 0x00, 0x9F, 0x20, 0x7C, 0x02,
-0xD0, 0x09, 0x40, 0x25, 0x00, 0x93, 0x00, 0x5D, 0x8A, 0xF0, 0x09, 0xC0, 0xE6,
-0x04, 0x9F, 0x00, 0x7C, 0x0E, 0xF0, 0x08, 0x40, 0x14, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x04, 0x7C, 0x66, 0xF3, 0x88,
-0xD1, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC8, 0x27, 0x00, 0x9F,
-0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x20, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x27, 0x00, 0x8F, 0x00, 0x5C, 0x02, 0xF0, 0x08, 0xC1, 0x25, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x08, 0x85, 0x02, 0x1F, 0x00, 0x4D, 0x08, 0xF8, 0x21, 0xC0,
-0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC4, 0x07, 0x00, 0x1F, 0x00,
-0x7C, 0x08, 0xF0, 0x00, 0xC0, 0x84, 0x00, 0x1F, 0x01, 0x4C, 0x00, 0xF0, 0x01,
-0xC0, 0x02, 0x00, 0x13, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F,
-0x00, 0x7C, 0x40, 0x32, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0xA0, 0x1C, 0x02, 0x7D, 0x02, 0xC4, 0x01, 0xD0, 0x37, 0xC0, 0x15,
-0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x48, 0x5F, 0x00, 0x5F, 0x00, 0x74,
-0x01, 0xD0, 0x15, 0x01, 0x14, 0x00, 0x7D, 0x05, 0x45, 0x01, 0xF0, 0x05, 0xC0,
-0x1D, 0x00, 0x7F, 0x20, 0xF4, 0x4D, 0xD0, 0x07, 0x40, 0x54, 0x20, 0x5D, 0x00,
-0xF4, 0x01, 0x34, 0x07, 0xD0, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0xA0, 0x72, 0x80, 0x8D, 0x10, 0x04, 0x03, 0xD0, 0xBC, 0x40, 0x31, 0x00,
-0xDD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x06, 0xCD, 0x00, 0x74, 0x03,
-0xD0, 0x18, 0x60, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x90, 0x0C, 0x40, 0xB0,
-0x01, 0xC1, 0x12, 0x34, 0x0B, 0xD0, 0x34, 0x50, 0x70, 0x00, 0xCD, 0x00, 0x34,
-0x03, 0x90, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0x80, 0x28, 0x01, 0x7D, 0x08, 0x84, 0x43, 0xD0, 0x0E, 0x40, 0x39, 0x00, 0xED,
-0x0C, 0xB4, 0x13, 0xDA, 0xCE, 0x40, 0x1B, 0x00, 0xED, 0x08, 0xB4, 0x13, 0xD1,
-0x0B, 0x40, 0x38, 0x21, 0x0D, 0x01, 0x86, 0x23, 0xD2, 0x4C, 0x40, 0x21, 0x00,
-0x65, 0x10, 0xB0, 0x01, 0xD0, 0x0E, 0x41, 0x38, 0x04, 0xED, 0x00, 0xF4, 0x47,
-0x10, 0x0F, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10,
-0xF8, 0x00, 0xAF, 0x05, 0x8C, 0x07, 0xD0, 0x16, 0xC0, 0x79, 0x00, 0xEF, 0x05,
-0xBC, 0x0F, 0xF0, 0x1E, 0xC4, 0x7B, 0x20, 0xED, 0x11, 0xB4, 0x87, 0xD0, 0x0F,
-0xC0, 0x78, 0x01, 0x2F, 0x21, 0x8C, 0x57, 0xF0, 0xBE, 0xC4, 0x68, 0x00, 0xE1,
-0x01, 0xB0, 0x05, 0xF0, 0x1C, 0xC4, 0x78, 0x00, 0xEF, 0x01, 0xF8, 0x05, 0xB0,
-0x1E, 0xD0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35,
-0x00, 0x8F, 0x40, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0xB5, 0x00, 0xDF, 0x00, 0x7C,
-0x03, 0xF1, 0x4D, 0xC1, 0x37, 0x00, 0xD6, 0x44, 0x7C, 0xAB, 0xF0, 0x0D, 0xCC,
-0xB7, 0x06, 0x1F, 0x00, 0x6C, 0x03, 0x60, 0x6D, 0xC0, 0x25, 0x00, 0x5F, 0x00,
-0x7C, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x03, 0xF0, 0x0D,
-0xC0, 0x41, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x4F, 0x00,
-0x23, 0x41, 0xDD, 0x27, 0xF8, 0x8F, 0xC0, 0xFF, 0x04, 0xFB, 0x01, 0xDC, 0x07,
-0xF0, 0x9F, 0xC0, 0x6C, 0x02, 0xFF, 0x01, 0xEC, 0x2F, 0xF2, 0x9B, 0xC2, 0x7F,
-0x42, 0x33, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x48, 0x00, 0xB3, 0x89, 0xAE,
-0x25, 0x30, 0x1F, 0xC2, 0x7F, 0x02, 0xFF, 0x01, 0xFC, 0x06, 0xF0, 0x1E, 0xC0,
-0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x09, 0x00, 0x61,
-0x08, 0x85, 0x01, 0xD8, 0x0E, 0x41, 0x3F, 0x00, 0xF1, 0x00, 0x84, 0x03, 0xD2,
-0x0F, 0x54, 0x88, 0x20, 0xE7, 0x00, 0x85, 0x23, 0xD0, 0xCA, 0x40, 0x3B, 0x02,
-0x21, 0x08, 0xAC, 0x03, 0x70, 0x0F, 0x48, 0x28, 0x00, 0xEB, 0x00, 0x8C, 0x01,
-0xB0, 0x4A, 0x40, 0x3B, 0x02, 0xED, 0x00, 0x34, 0x1B, 0xD0, 0x0E, 0x50, 0x54,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x04, 0x21, 0x02,
-0x94, 0xC3, 0xD0, 0x86, 0x40, 0x3B, 0x00, 0xE9, 0x00, 0x94, 0x23, 0xD0, 0x0E,
-0x42, 0x38, 0x90, 0xED, 0x00, 0x84, 0x03, 0xD2, 0x0A, 0x00, 0x3F, 0x04, 0x01,
-0x00, 0x84, 0x23, 0xD0, 0x0E, 0x40, 0x09, 0x00, 0xA1, 0x40, 0x97, 0x01, 0x12,
-0x0E, 0x48, 0x2B, 0x10, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x00, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0xA7, 0x01, 0x01, 0x81, 0x44,
-0x0E, 0xD0, 0x31, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD8, 0x0C, 0x40,
-0xB0, 0x08, 0xC5, 0x00, 0x04, 0x13, 0xD0, 0x08, 0x60, 0x33, 0x00, 0x01, 0x00,
-0x24, 0x03, 0x58, 0x0C, 0x50, 0x21, 0x00, 0xC9, 0x00, 0x04, 0x40, 0x12, 0x08,
-0x40, 0x23, 0x01, 0xCD, 0x00, 0x74, 0x9E, 0xD1, 0x8C, 0x40, 0x10, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0xFD, 0x40, 0x33, 0x01, 0x5C, 0x04,
-0xD0, 0x19, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xD4, 0x03, 0xF0, 0x0F, 0xC0, 0x74,
-0x00, 0xFE, 0x00, 0xCC, 0x03, 0xF0, 0x09, 0xC0, 0xBB, 0x80, 0x13, 0x00, 0xCC,
-0x03, 0xF0, 0x0F, 0x40, 0x25, 0x00, 0xD3, 0x00, 0x5C, 0x05, 0x10, 0x05, 0xC8,
-0x37, 0x00, 0xDF, 0x00, 0x7C, 0x4B, 0xF0, 0x0D, 0xC0, 0x54, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x08, 0x5F, 0x0A, 0x7C, 0x40, 0xF0,
-0x29, 0xC1, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x23, 0xF3, 0x0D, 0xC4, 0xC7, 0x00,
-0xC4, 0x80, 0x5C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x01, 0x1F, 0x00, 0x7C, 0x03,
-0x70, 0x0C, 0xC0, 0x26, 0x00, 0x5F, 0x02, 0x50, 0x05, 0xF0, 0x0D, 0xC0, 0x27,
-0x00, 0xDE, 0x40, 0x7C, 0x03, 0xF0, 0x2D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x02, 0x33, 0x20, 0xCC, 0x00, 0x30, 0x0B,
-0xC0, 0x3C, 0x00, 0xFE, 0x00, 0xFE, 0x03, 0xB2, 0x0F, 0xC2, 0x7F, 0x05, 0xFF,
-0x00, 0xCD, 0x83, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x33, 0x00, 0xFC, 0x03, 0xF0,
-0x0F, 0xC2, 0x0E, 0x00, 0x0F, 0x01, 0xCD, 0x01, 0x30, 0x4F, 0xC0, 0x7C, 0x01,
-0xEF, 0x00, 0xCC, 0x07, 0x30, 0x1B, 0xC0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x81, 0x20, 0x76, 0x20, 0x05, 0x04, 0x44, 0x04, 0x10, 0x39, 0x41,
-0x34, 0x00, 0xDD, 0x00, 0x34, 0x03, 0x70, 0x0D, 0x40, 0xA7, 0x80, 0xDD, 0x00,
-0x44, 0x03, 0xD0, 0x0D, 0xC0, 0x35, 0x00, 0x11, 0x03, 0x74, 0x03, 0x72, 0x0D,
-0x48, 0x45, 0x00, 0x1D, 0x05, 0x04, 0x08, 0x52, 0x0C, 0x40, 0x24, 0x00, 0xDD,
-0x00, 0x44, 0x09, 0x10, 0x9C, 0x40, 0x04, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0xA0, 0x14, 0x50, 0x11, 0x00, 0x44, 0x06, 0x10, 0x11, 0x60, 0x36,
-0x10, 0xDD, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x4A, 0x07, 0x80, 0xDD, 0x00, 0x44,
-0x03, 0xD0, 0x09, 0x68, 0x37, 0x00, 0x11, 0x03, 0x74, 0x03, 0xD0, 0x0D, 0x40,
-0x44, 0x00, 0x9D, 0x08, 0x44, 0x20, 0x10, 0x0D, 0x40, 0x35, 0x00, 0xDD, 0x00,
-0x54, 0x13, 0x50, 0x05, 0x41, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x22, 0x00, 0x00, 0x51, 0x00, 0x05, 0x04, 0x14, 0x08, 0x50, 0x32, 0x00,
-0xCD, 0x00, 0x74, 0x03, 0x50, 0x0C, 0x40, 0x03, 0x00, 0xCD, 0x80, 0x04, 0x03,
-0xD0, 0x08, 0x40, 0x34, 0x20, 0x01, 0x00, 0x34, 0x03, 0x52, 0x0C, 0x40, 0x21,
-0x10, 0xCD, 0x00, 0x44, 0x00, 0x50, 0x0C, 0x44, 0x20, 0x00, 0xCD, 0x00, 0x45,
-0x0B, 0x14, 0x0D, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xB0, 0x32, 0x00, 0x11, 0x00, 0x4D, 0x02, 0x30, 0x01, 0xC2, 0x3E, 0x10, 0xDF,
-0x00, 0x74, 0x03, 0x30, 0x0F, 0xC0, 0x17, 0x10, 0xED, 0x00, 0xCC, 0x03, 0xF0,
-0x09, 0x88, 0x3F, 0x40, 0x13, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xE0, 0x04, 0x20,
-0x1F, 0x00, 0x4E, 0x00, 0x30, 0x0D, 0xC0, 0x24, 0x00, 0xDF, 0x00, 0x4C, 0x0B,
-0x30, 0x01, 0xC0, 0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8,
-0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0xF1, 0x0B, 0xCA, 0x3D, 0x00, 0xFF, 0x20,
-0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B,
-0xC0, 0x39, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x40, 0x0F, 0xC0, 0x0D, 0x00, 0x3F,
-0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x13, 0xF0,
-0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x3F,
-0x00, 0xFB, 0x1C, 0xEC, 0x05, 0x30, 0x0B, 0xC0, 0x5F, 0x00, 0xBF, 0x00, 0xEC,
-0x03, 0xB0, 0x0F, 0xC1, 0x3F, 0x00, 0x3B, 0x81, 0xEC, 0x33, 0x70, 0x0F, 0xC0,
-0x4F, 0x00, 0x2F, 0x01, 0xFC, 0x84, 0xF0, 0x4F, 0x80, 0x7C, 0x00, 0x7B, 0x01,
-0xBC, 0x04, 0xF0, 0x13, 0xC2, 0x4E, 0x00, 0xFF, 0x01, 0xFE, 0x00, 0xF0, 0x03,
-0x44, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0xFF, 0x02,
-0xF1, 0x02, 0x44, 0x06, 0x14, 0x19, 0x40, 0x26, 0x00, 0x8D, 0x70, 0x74, 0xAF,
-0x10, 0x1F, 0x40, 0xFF, 0x00, 0x9D, 0x01, 0x74, 0x3B, 0x10, 0xBF, 0x40, 0x77,
-0x00, 0xDD, 0x01, 0x74, 0x07, 0xD0, 0xBF, 0x40, 0x38, 0x05, 0x91, 0x01, 0x74,
-0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0xDD, 0x00, 0x76, 0x86, 0xD2, 0x19, 0x40,
-0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x20, 0xC8,
-0x04, 0x64, 0x01, 0x50, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x04, 0x06, 0x03, 0x90,
-0x0C, 0x42, 0xB3, 0x00, 0x81, 0x00, 0x34, 0x13, 0x50, 0x0C, 0x60, 0x33, 0x20,
-0xCD, 0x80, 0x34, 0x02, 0x52, 0x0C, 0x60, 0x30, 0x40, 0x85, 0x40, 0x16, 0x00,
-0xD0, 0x00, 0x42, 0x03, 0x00, 0xC5, 0x80, 0x34, 0x00, 0xD2, 0x00, 0x42, 0x47,
-0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1, 0x00,
-0x44, 0x02, 0x50, 0x19, 0x40, 0x26, 0x00, 0x9D, 0x23, 0x74, 0x03, 0x50, 0x0D,
-0x40, 0x37, 0x00, 0x9C, 0x01, 0x34, 0x03, 0x10, 0x0D, 0x00, 0x37, 0x00, 0xDD,
-0x06, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x10, 0x95, 0x00, 0x74, 0x0E, 0xD0,
-0x11, 0x40, 0x67, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xC0, 0x19, 0x40, 0x0F, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0xDB, 0x80, 0x2C,
-0x12, 0x71, 0x11, 0xC1, 0x17, 0x01, 0x1F, 0x03, 0x4C, 0x03, 0xB0, 0x0D, 0xC0,
-0x37, 0x00, 0x13, 0x03, 0x6C, 0x03, 0x72, 0x0D, 0xC8, 0x07, 0x01, 0x1E, 0x00,
-0x7C, 0x01, 0xF0, 0x0C, 0xC0, 0x34, 0x00, 0x55, 0x05, 0x7C, 0x04, 0xD0, 0x31,
-0xC0, 0x47, 0x01, 0xDF, 0xA0, 0x74, 0x04, 0xF0, 0x19, 0xC1, 0x03, 0x20, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x39, 0x00, 0xEF, 0x00, 0xFC, 0x02,
-0xB0, 0x03, 0xC0, 0x2F, 0x00, 0xBF, 0x80, 0xBC, 0x03, 0xB0, 0x0F, 0xC0, 0x3F,
-0x00, 0x3F, 0x00, 0x7C, 0x03, 0xD0, 0x0F, 0xC0, 0x3F, 0x01, 0xFF, 0x41, 0xFC,
-0x03, 0xF0, 0x0F, 0xC1, 0x3F, 0x00, 0xB3, 0x09, 0xF8, 0x02, 0xF0, 0x03, 0xC0,
-0x0F, 0x00, 0xFF, 0x00, 0xF8, 0x40, 0xF0, 0x09, 0xC1, 0x1F, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0,
-0x29, 0xC0, 0x37, 0x00, 0x1F, 0x22, 0x6C, 0x03, 0x30, 0x8D, 0xC0, 0x37, 0x00,
-0x13, 0x46, 0x7C, 0x03, 0xB2, 0x0D, 0xC4, 0x34, 0x00, 0xDF, 0x02, 0x4C, 0x17,
-0xB0, 0x8D, 0xC2, 0x37, 0x10, 0x9F, 0x80, 0x7E, 0x08, 0xB4, 0x81, 0xC8, 0x27,
-0x11, 0xDF, 0x00, 0x5E, 0x00, 0xF0, 0x29, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0xA0, 0x3C, 0x00, 0xF1, 0x00, 0x44, 0x12, 0xD0, 0x09,
-0x40, 0x27, 0x22, 0x9D, 0xA0, 0xC4, 0x4B, 0x50, 0x1F, 0x40, 0x3F, 0x00, 0x1A,
-0x03, 0xF4, 0x03, 0x10, 0x0F, 0x40, 0x74, 0x01, 0xDD, 0x00, 0x44, 0x0B, 0x10,
-0x2F, 0x42, 0x37, 0x00, 0x91, 0x0B, 0x74, 0x02, 0x21, 0x01, 0x40, 0xA7, 0x01,
-0xDD, 0x00, 0x46, 0x1A, 0x90, 0x29, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xC5, 0x00, 0x14, 0x13, 0xD0, 0x00, 0x40,
-0x32, 0x02, 0x0D, 0x00, 0x24, 0x1F, 0x10, 0x0C, 0x48, 0x33, 0x00, 0x04, 0x00,
-0x34, 0x03, 0x90, 0x0C, 0x40, 0x43, 0x01, 0x0D, 0xA0, 0x26, 0x88, 0x10, 0x2C,
-0x48, 0x33, 0x00, 0xC4, 0x08, 0x34, 0x00, 0x10, 0x50, 0x48, 0x42, 0x20, 0xC9,
-0x80, 0x24, 0x02, 0xD2, 0x20, 0x40, 0x1E, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x04, 0x80, 0x70, 0x00, 0xC1, 0x01, 0x84, 0x06, 0xD0, 0x1E, 0x40, 0x6B,
-0x00, 0x6D, 0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x02, 0xAD, 0x29, 0xB4,
-0x07, 0x10, 0x1E, 0x40, 0x4B, 0x00, 0x2D, 0x41, 0xB4, 0x07, 0x10, 0x1E, 0x60,
-0x7B, 0x22, 0xE1, 0x41, 0xF4, 0x04, 0x90, 0x92, 0x40, 0x7B, 0x00, 0xED, 0x01,
-0x84, 0x06, 0x90, 0x12, 0x40, 0x1A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x1C, 0x03, 0xD0, 0x04, 0xC0, 0x23, 0x00,
-0xCF, 0x00, 0x2E, 0x03, 0x30, 0x0C, 0xE8, 0x33, 0x02, 0x87, 0x12, 0x3C, 0x03,
-0xB0, 0x0C, 0xC1, 0x03, 0x20, 0x0D, 0x01, 0x2D, 0x16, 0x30, 0x8C, 0xC0, 0x33,
-0x00, 0x87, 0x08, 0x34, 0x06, 0x30, 0x50, 0xC2, 0x13, 0x00, 0xCF, 0x00, 0x3C,
-0x03, 0xF0, 0x84, 0xC0, 0x4A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xB8, 0x3D, 0x00, 0xFC, 0x22, 0xDC, 0x02, 0xF0, 0x0F, 0x80, 0x2F, 0x02, 0xFF,
-0x00, 0x9C, 0x63, 0xF0, 0xAF, 0xC0, 0x33, 0x4A, 0x93, 0x00, 0xFC, 0x03, 0xF0,
-0x0E, 0xC1, 0x0C, 0x92, 0x1F, 0x80, 0x0C, 0x23, 0x74, 0x0F, 0xC0, 0x77, 0x00,
-0xB7, 0x08, 0x7C, 0x02, 0x70, 0x87, 0xE0, 0x3F, 0x00, 0xEF, 0x00, 0xFD, 0x02,
-0xF0, 0x0F, 0xC2, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0,
-0xB7, 0x03, 0xDF, 0x02, 0x7C, 0x02, 0x30, 0x05, 0xC0, 0x37, 0x00, 0x7F, 0x01,
-0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x86, 0x13, 0x01, 0x5C, 0x03, 0x71, 0x5D,
-0xC0, 0x40, 0x90, 0x13, 0x00, 0x7C, 0x01, 0x38, 0x0D, 0xC4, 0x37, 0x00, 0xD3,
-0x80, 0x7C, 0x02, 0xD0, 0x11, 0xC0, 0x24, 0x80, 0xCF, 0x00, 0x4C, 0x00, 0xF1,
-0x01, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39,
-0x03, 0xED, 0x02, 0xB4, 0x02, 0x10, 0x06, 0x40, 0x2B, 0x00, 0xFD, 0x00, 0x84,
-0x93, 0xD0, 0x2E, 0x42, 0x33, 0x21, 0xA1, 0x00, 0x84, 0x13, 0xD0, 0xCE, 0x68,
-0x39, 0x30, 0xE1, 0x00, 0xB4, 0x03, 0x10, 0xCE, 0x40, 0x3F, 0x19, 0xE1, 0x20,
-0xB4, 0x02, 0xD2, 0x02, 0x44, 0x38, 0x10, 0xED, 0x00, 0x84, 0x00, 0xD0, 0x02,
-0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00,
-0xED, 0x01, 0x94, 0x07, 0x10, 0x1E, 0x41, 0x7B, 0x08, 0x6D, 0x00, 0xB4, 0x07,
-0xD0, 0x5E, 0x40, 0x7B, 0x01, 0xB1, 0x21, 0xB4, 0x27, 0x50, 0x1C, 0x50, 0x3A,
-0x00, 0xE1, 0x01, 0x94, 0x07, 0x91, 0x9E, 0x44, 0x3B, 0x03, 0xA1, 0x01, 0xB4,
-0x46, 0xD8, 0x13, 0x44, 0x78, 0x00, 0xE5, 0x81, 0x84, 0xC7, 0xD0, 0x1A, 0x40,
-0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x08, 0xCD,
-0x00, 0x34, 0x2E, 0x15, 0x2C, 0x41, 0x23, 0x20, 0xCD, 0x13, 0x04, 0x03, 0xD0,
-0x0C, 0x40, 0x33, 0x00, 0xC1, 0x11, 0x24, 0x03, 0xD0, 0x0C, 0x44, 0x37, 0x00,
-0xC1, 0x00, 0x34, 0x87, 0x90, 0x0C, 0x40, 0x37, 0x00, 0x81, 0x00, 0x34, 0x47,
-0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x87, 0xD0, 0xEC, 0x40, 0x4B,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00,
-0xBC, 0x0D, 0x30, 0x07, 0xC0, 0x5F, 0x01, 0x7F, 0x40, 0x7C, 0x01, 0xD0, 0x05,
-0xC0, 0x17, 0x10, 0x73, 0x03, 0x7C, 0x01, 0x71, 0x05, 0xC0, 0x9E, 0xC0, 0x73,
-0x09, 0x9C, 0x05, 0x91, 0x05, 0xC0, 0x17, 0x00, 0x61, 0x00, 0xF4, 0x01, 0xF0,
-0x27, 0x40, 0x1C, 0x80, 0x4F, 0x00, 0xC4, 0x8D, 0xF0, 0x37, 0x40, 0x5F, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C,
-0x48, 0xF0, 0x01, 0xC0, 0x87, 0x20, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xE0,
-0x07, 0x40, 0x1F, 0x08, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x84, 0x26, 0x1F, 0x8A,
-0x7C, 0x20, 0x70, 0x21, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF2, 0x01,
-0xC0, 0x87, 0x39, 0x1F, 0x00, 0x7D, 0x40, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x06,
-0x30, 0x09, 0xC0, 0x67, 0x00, 0x83, 0x00, 0x0C, 0x02, 0xB2, 0x09, 0xC8, 0x27,
-0x02, 0x9B, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x91, 0x00, 0x7C,
-0x22, 0xB4, 0x98, 0xC0, 0x25, 0x00, 0x93, 0x40, 0x4C, 0x26, 0x30, 0x09, 0xC1,
-0x67, 0x02, 0x9B, 0x00, 0x0C, 0x02, 0x30, 0x39, 0xC0, 0x43, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x14,
-0x09, 0xC0, 0x21, 0x02, 0x95, 0x00, 0x44, 0x02, 0x30, 0x09, 0xC0, 0x23, 0x00,
-0x90, 0x01, 0x74, 0x02, 0xD0, 0x99, 0x40, 0x27, 0x00, 0x91, 0x04, 0x7C, 0x0E,
-0x10, 0x09, 0x40, 0x2C, 0x00, 0x9B, 0x12, 0x2C, 0x0E, 0x14, 0x99, 0x40, 0xE3,
-0x40, 0x91, 0x00, 0x44, 0x0A, 0x50, 0x39, 0x48, 0x07, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x80, 0x8D, 0x00, 0x54, 0x22, 0x10, 0x09,
-0x60, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x90, 0x09, 0x44, 0x27, 0x00, 0x99,
-0x00, 0x70, 0x02, 0xD8, 0x09, 0x40, 0x67, 0x00, 0x95, 0x20, 0x76, 0x0A, 0x18,
-0x09, 0x41, 0x25, 0x00, 0x91, 0x08, 0x40, 0x02, 0x10, 0x0D, 0x40, 0x27, 0x04,
-0x91, 0x01, 0x44, 0x47, 0x11, 0x29, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0xA0, 0x01, 0x8D, 0x04, 0x04, 0x02, 0x10, 0x48, 0x40,
-0xA5, 0xA0, 0x85, 0x14, 0x04, 0x02, 0x90, 0x08, 0x40, 0x21, 0x00, 0xC9, 0x00,
-0x34, 0x22, 0xD2, 0x08, 0x40, 0x27, 0x00, 0x85, 0x00, 0x74, 0x02, 0x1A, 0x08,
-0x40, 0x20, 0x02, 0x99, 0x20, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x27, 0x00, 0x81,
-0x01, 0x04, 0x12, 0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1D, 0x8A, 0x54, 0x01, 0x31, 0x01, 0xC1, 0x97,
-0x00, 0x13, 0x0A, 0x4C, 0x50, 0xB0, 0x41, 0x41, 0x07, 0x05, 0x1B, 0x00, 0x7C,
-0x58, 0xD0, 0x41, 0x41, 0x17, 0x00, 0x17, 0x20, 0x7E, 0x00, 0xB0, 0x41, 0xC1,
-0xC5, 0x00, 0x13, 0x00, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x0A,
-0x4C, 0x00, 0x33, 0x01, 0xC2, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x19, 0xB8, 0x67, 0x02, 0x9F, 0x08, 0xBC, 0x02, 0xD0, 0x0B, 0xC8, 0x2D, 0x01,
-0xBF, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0xA6, 0x00, 0x7C, 0x12,
-0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xBB, 0x00, 0x9C, 0x82, 0xF0, 0x09, 0xC0, 0xA7,
-0x09, 0xBF, 0x60, 0xDC, 0x82, 0xF0, 0x0A, 0xC0, 0x2F, 0x08, 0x97, 0x00, 0xFD,
-0x22, 0xF0, 0x8B, 0xC0, 0x67, 0x48, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA0, 0x27, 0x05, 0x9F, 0x0C, 0xFC, 0x02, 0xF0, 0x09, 0x40, 0x2F, 0x02, 0x9F,
-0x84, 0xF4, 0xD2, 0x70, 0x4B, 0xC0, 0x2C, 0x00, 0xBF, 0x00, 0x7C, 0x22, 0x70,
-0x4B, 0xC0, 0x2C, 0x00, 0xB7, 0x20, 0xFC, 0x02, 0xF0, 0x0B, 0xC2, 0x64, 0x03,
-0xA5, 0x80, 0xCC, 0x02, 0x71, 0x0B, 0x40, 0x2D, 0x00, 0xBB, 0x20, 0xCC, 0x02,
-0xF0, 0x0B, 0x82, 0x64, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
-0x47, 0x05, 0x1D, 0x4C, 0x74, 0x00, 0xC0, 0x01, 0x44, 0x07, 0x20, 0x1D, 0xB4,
-0x74, 0x00, 0x70, 0x81, 0x40, 0x84, 0x00, 0x19, 0x80, 0x74, 0xA0, 0xD0, 0x01,
-0x44, 0x06, 0x00, 0x13, 0x80, 0x5C, 0x00, 0xD0, 0x01, 0x40, 0x84, 0x10, 0x57,
-0x00, 0x4C, 0x00, 0xD0, 0x01, 0xC0, 0x15, 0x20, 0x19, 0x50, 0x6C, 0x00, 0xD0,
-0x01, 0x50, 0x70, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23,
-0x00, 0x8D, 0x04, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x0C, 0x34,
-0x02, 0x50, 0x08, 0x40, 0x20, 0x02, 0x8D, 0x00, 0x34, 0x02, 0x50, 0x88, 0x48,
-0x26, 0x80, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0xA0, 0x20, 0x85, 0x00,
-0x17, 0x82, 0x50, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x24, 0x02, 0xD0, 0x08,
-0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00,
-0x9D, 0x00, 0x74, 0x13, 0xD0, 0x09, 0x40, 0xA7, 0x00, 0x9D, 0x10, 0x74, 0x02,
-0x50, 0x09, 0x40, 0x24, 0x00, 0xD9, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x26,
-0x00, 0x91, 0x06, 0x56, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x10, 0x95, 0x08, 0x44,
-0x06, 0xD8, 0x19, 0x40, 0x25, 0x00, 0x99, 0x00, 0x64, 0x06, 0xD0, 0x19, 0x00,
-0x60, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x2D, 0x00, 0x9F,
-0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0xA7, 0x02, 0x9F, 0x03, 0x7C, 0x02, 0x70,
-0x09, 0xC4, 0x24, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x60, 0x01,
-0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x97, 0x00, 0x5C, 0x46,
-0x70, 0x59, 0xCE, 0xE5, 0x02, 0x9B, 0x00, 0x6C, 0x4E, 0xF0, 0x19, 0xC1, 0x14,
-0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x29, 0xC0, 0x67, 0x00, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x09,
-0x50, 0x27, 0x24, 0x9F, 0x09, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x65, 0x02, 0x9F,
-0x41, 0x78, 0x02, 0xF1, 0x08, 0xD0, 0x27, 0x08, 0x9F, 0x01, 0x78, 0x02, 0xF0,
-0x09, 0xC0, 0x67, 0x80, 0x9E, 0x00, 0x78, 0x02, 0xF1, 0x08, 0xC0, 0x53, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x5C,
-0x00, 0xF8, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x80, 0xC0,
-0x07, 0x00, 0x1F, 0x03, 0x7C, 0x00, 0xD2, 0x00, 0xD0, 0x04, 0x00, 0x1F, 0x12,
-0x4C, 0x40, 0xB0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x02, 0x7C, 0x18, 0xF0, 0x21,
-0xC0, 0x07, 0x04, 0x13, 0x00, 0x4C, 0x18, 0x30, 0x01, 0xC0, 0x53, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x5D, 0x00, 0xC4, 0x01,
-0x70, 0x05, 0x40, 0x9F, 0x08, 0x51, 0x00, 0xF4, 0x6D, 0xD0, 0x15, 0x40, 0x9F,
-0x00, 0x7D, 0x10, 0x74, 0x01, 0xD1, 0x15, 0x43, 0x9C, 0x10, 0x7D, 0x00, 0xEC,
-0x11, 0x70, 0x37, 0xC8, 0x16, 0x00, 0x6D, 0x10, 0xC5, 0x01, 0xD0, 0x87, 0x40,
-0x5F, 0x04, 0x61, 0x18, 0xC4, 0x09, 0xB0, 0x07, 0x40, 0x53, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x14, 0x01, 0x50,
-0x0C, 0x48, 0xB3, 0x04, 0xC1, 0x00, 0x36, 0x0E, 0xD0, 0x08, 0x40, 0xB3, 0x00,
-0xCD, 0x01, 0x34, 0x03, 0xD8, 0x1C, 0x44, 0xB2, 0x81, 0xCD, 0x0B, 0x24, 0x03,
-0x50, 0x3C, 0x41, 0x31, 0x00, 0xCD, 0x11, 0x04, 0x0E, 0xD0, 0x2C, 0x40, 0x73,
-0x00, 0xC1, 0x40, 0x04, 0x03, 0x10, 0xAC, 0x61, 0x53, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x01, 0xED, 0x09, 0x84, 0x01, 0x50, 0x0E,
-0x40, 0xFB, 0x40, 0xE1, 0x00, 0xB6, 0x02, 0xD0, 0x0E, 0x40, 0x3B, 0x04, 0xED,
-0x20, 0xB4, 0x93, 0xD0, 0x1E, 0x40, 0xAA, 0x08, 0xFD, 0x01, 0xA4, 0x00, 0x51,
-0x0E, 0x40, 0x3B, 0x02, 0x2D, 0x00, 0x86, 0x0A, 0xD0, 0x0E, 0x60, 0x7B, 0x08,
-0xE1, 0x00, 0x05, 0x87, 0x90, 0x0E, 0x60, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x10, 0x78, 0x01, 0xFF, 0x05, 0x9C, 0x05, 0x70, 0x1E, 0xC0,
-0x7F, 0x00, 0xE3, 0x0F, 0xBC, 0x06, 0xF0, 0x1A, 0x40, 0x7B, 0x00, 0x2D, 0x01,
-0xB4, 0x3F, 0xF0, 0x0C, 0xCC, 0x4A, 0x80, 0xEF, 0x01, 0xAE, 0x04, 0x70, 0x1C,
-0xC0, 0x79, 0x05, 0x2D, 0x01, 0x9C, 0x07, 0xE9, 0x1E, 0xC0, 0x7B, 0x40, 0xE1,
-0x21, 0x8C, 0x05, 0x30, 0x16, 0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x10, 0x7C, 0x01, 0x70, 0x0D, 0xC0, 0x37,
-0x00, 0xDF, 0x04, 0x7C, 0x02, 0xF2, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C,
-0x83, 0xF1, 0x0D, 0xC2, 0x25, 0x00, 0xCF, 0x40, 0x7C, 0x00, 0x60, 0x0D, 0xC0,
-0xB6, 0x20, 0x1F, 0x00, 0x58, 0x83, 0xFA, 0x09, 0xC0, 0x13, 0x08, 0xCF, 0x00,
-0x74, 0x02, 0xF1, 0x05, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xA2, 0x7F, 0x14, 0xFF, 0x01, 0xFC, 0x11, 0xF0, 0x1F, 0xC0, 0x7F, 0x02,
-0xFF, 0x09, 0xFC, 0x06, 0x30, 0x9F, 0xC0, 0x7E, 0x02, 0xFF, 0x09, 0xFC, 0x07,
-0x70, 0x1F, 0xC8, 0x6F, 0x02, 0xEF, 0x41, 0xDC, 0x24, 0xF0, 0x1E, 0xC0, 0x7C,
-0x00, 0x33, 0x09, 0xF8, 0x07, 0xF0, 0x9F, 0xC0, 0x7F, 0x02, 0xFB, 0x41, 0xCC,
-0x05, 0x30, 0x97, 0xC4, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x41, 0xD1, 0x0E, 0xC0, 0x39, 0x23, 0xED,
-0x08, 0xB4, 0x02, 0xB0, 0x8E, 0x08, 0x38, 0x00, 0xED, 0x08, 0xDC, 0x23, 0x30,
-0x4E, 0x44, 0x6B, 0x2A, 0xC9, 0xC0, 0x10, 0x20, 0xD0, 0x82, 0x40, 0x39, 0x00,
-0x2D, 0x0C, 0x34, 0x07, 0xD0, 0x04, 0x00, 0x3B, 0x07, 0xE7, 0x08, 0xAC, 0x29,
-0x30, 0xAE, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x79, 0x00, 0xED, 0x00, 0xB4, 0x21, 0xD0, 0x0E, 0x40, 0x1B, 0x24, 0xED, 0x40,
-0x96, 0x02, 0x90, 0x8E, 0x48, 0x29, 0x08, 0x2D, 0x00, 0x90, 0x03, 0x50, 0x0A,
-0x48, 0x0B, 0x07, 0x65, 0x18, 0x94, 0x40, 0xD0, 0x0E, 0x40, 0x31, 0x00, 0x2D,
-0x80, 0xB4, 0x43, 0xD0, 0x0E, 0x48, 0x2B, 0x00, 0x65, 0x00, 0x84, 0x01, 0x90,
-0x82, 0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33,
-0x00, 0xCD, 0x00, 0x34, 0x0D, 0xD0, 0x2C, 0x40, 0xE1, 0x04, 0xCD, 0x02, 0x34,
-0x02, 0x80, 0x0C, 0x50, 0x21, 0x10, 0xCD, 0x12, 0x14, 0x03, 0x10, 0x08, 0x40,
-0x63, 0x11, 0x49, 0x01, 0x04, 0x0C, 0xC0, 0x00, 0x42, 0x31, 0x00, 0x0D, 0x00,
-0x34, 0x4B, 0xD8, 0x90, 0x42, 0x73, 0x01, 0x45, 0x00, 0x24, 0x2E, 0x14, 0x18,
-0x40, 0x19, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00,
-0xFF, 0x00, 0x3C, 0x0F, 0xF0, 0x2D, 0xC1, 0x83, 0x00, 0xFF, 0x05, 0x5E, 0x03,
-0xB0, 0x08, 0xC0, 0x35, 0x00, 0xCF, 0x81, 0xDC, 0x83, 0x70, 0x09, 0xC2, 0x23,
-0x10, 0xD7, 0x00, 0x5C, 0x00, 0xF0, 0x0D, 0xC0, 0x3D, 0x08, 0x17, 0x18, 0x74,
-0x03, 0xF0, 0x39, 0x68, 0x37, 0x10, 0xD7, 0x00, 0x4C, 0x82, 0xB8, 0x59, 0xC0,
-0x77, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF,
-0x40, 0x7C, 0x11, 0xF0, 0x4D, 0xC2, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF1,
-0x0D, 0x40, 0xB4, 0x00, 0xDF, 0x01, 0x5C, 0x03, 0x70, 0x0D, 0x82, 0xA7, 0x00,
-0xDC, 0x44, 0x7C, 0x00, 0xF2, 0x0D, 0xC0, 0x33, 0x00, 0x16, 0x20, 0x7C, 0x03,
-0xF0, 0x09, 0xC5, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC9, 0x07,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFB, 0x00,
-0xFC, 0x0B, 0x30, 0x0E, 0xC0, 0x2C, 0x00, 0xF3, 0x10, 0xFC, 0x27, 0xF0, 0x09,
-0xC0, 0x38, 0x40, 0x33, 0x05, 0xCC, 0x03, 0xF0, 0x0A, 0xC0, 0x0C, 0x00, 0xF3,
-0xA0, 0xE8, 0xC0, 0x30, 0x13, 0xC0, 0x3F, 0x00, 0x3B, 0x01, 0xCC, 0x05, 0xF0,
-0x03, 0xC2, 0x3D, 0x00, 0xFB, 0x01, 0x7C, 0x42, 0xF0, 0x02, 0x40, 0x04, 0x28,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xD1, 0x00, 0x74,
-0x02, 0x14, 0x0D, 0x60, 0x64, 0x81, 0xD5, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40,
-0x35, 0x81, 0xD1, 0x23, 0x4C, 0x03, 0x30, 0x0D, 0x40, 0xE5, 0x00, 0xC1, 0x00,
-0x10, 0x20, 0xB0, 0x51, 0x40, 0x37, 0x00, 0x05, 0x43, 0x44, 0x15, 0xD0, 0x11,
-0x43, 0x13, 0x00, 0xD1, 0x00, 0x7C, 0x0E, 0xD1, 0x31, 0x50, 0x04, 0x06, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x32, 0x00, 0xD9, 0x00, 0x74, 0x03,
-0x92, 0x0D, 0x50, 0x44, 0x08, 0xD1, 0x00, 0x74, 0xC3, 0xDA, 0x0D, 0x00, 0x14,
-0x20, 0x11, 0x40, 0x64, 0x03, 0xD0, 0x49, 0x40, 0xC4, 0x00, 0x91, 0x08, 0x74,
-0x40, 0x90, 0x4D, 0x40, 0x37, 0x00, 0x15, 0x14, 0x64, 0x23, 0xD1, 0x19, 0x04,
-0x37, 0x00, 0x91, 0x04, 0x74, 0x04, 0xD9, 0x19, 0x40, 0x05, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x01, 0x90,
-0x0C, 0x40, 0x04, 0x00, 0xC5, 0x00, 0x34, 0x01, 0xD0, 0x0C, 0x40, 0x11, 0x10,
-0x01, 0x00, 0x24, 0x03, 0x50, 0x0C, 0x46, 0x05, 0xE1, 0x91, 0x02, 0x54, 0x20,
-0x90, 0x00, 0x40, 0x33, 0x00, 0x15, 0x00, 0x05, 0xB3, 0xD8, 0x00, 0x00, 0x33,
-0xC0, 0x81, 0x40, 0x24, 0x00, 0xD0, 0x08, 0x60, 0x40, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x90, 0x3E, 0x00, 0xFB, 0x00, 0x7C, 0x03, 0xB0, 0x0D,
-0x40, 0x04, 0x00, 0xF1, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x11,
-0x00, 0xEC, 0x03, 0xF0, 0x09, 0xC0, 0x04, 0x05, 0x13, 0x02, 0x6C, 0x00, 0xB0,
-0x01, 0x40, 0x3F, 0x00, 0x17, 0x00, 0x6C, 0x03, 0xF2, 0xA1, 0xC0, 0x27, 0x00,
-0x43, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x05, 0x40, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0x70, 0x0F, 0xC0,
-0x2F, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0x3F, 0x00,
-0xD0, 0x03, 0x30, 0x0B, 0xC0, 0x07, 0x10, 0x3F, 0x80, 0xEC, 0x90, 0xF0, 0x03,
-0xC0, 0x3F, 0x00, 0x3C, 0x00, 0x7C, 0x1B, 0xF0, 0x43, 0xC0, 0x3F, 0x00, 0x7F,
-0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC8, 0x17, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x80, 0x0F, 0x06, 0xAF, 0x00, 0xEC, 0x02, 0xE0, 0x1E, 0xC0, 0x0F,
-0x05, 0xFB, 0x0C, 0xFC, 0x50, 0x30, 0x43, 0xC0, 0x2C, 0x01, 0x33, 0x00, 0xCC,
-0x03, 0x30, 0x1F, 0xC0, 0x0F, 0x05, 0x23, 0x01, 0xEC, 0x03, 0xB0, 0x13, 0xC0,
-0x3F, 0x01, 0x3B, 0x01, 0xC4, 0x06, 0xB6, 0x83, 0xC0, 0x0D, 0x03, 0x37, 0x00,
-0xAC, 0x27, 0x30, 0x1E, 0xC0, 0x0E, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x10, 0x87, 0x01, 0x9D, 0x01, 0x44, 0x00, 0xD0, 0x0D, 0x40, 0x83, 0x00,
-0xF1, 0x08, 0x74, 0x10, 0x10, 0x09, 0x40, 0xB4, 0x07, 0x55, 0x10, 0x84, 0x2B,
-0x10, 0x41, 0xC3, 0x44, 0x00, 0x11, 0x01, 0xC4, 0x07, 0xB0, 0x15, 0xC0, 0xBD,
-0x12, 0xD1, 0x01, 0x44, 0x42, 0x10, 0xE1, 0x40, 0x90, 0x03, 0x11, 0x23, 0x44,
-0x12, 0x10, 0x11, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
-0xA0, 0x03, 0x00, 0x8D, 0x80, 0x14, 0x06, 0xC0, 0x0C, 0x40, 0x01, 0x00, 0xC9,
-0x04, 0x36, 0x40, 0x10, 0x64, 0x49, 0x20, 0x09, 0x01, 0x08, 0x04, 0xC3, 0x10,
-0x44, 0x40, 0x13, 0x00, 0x01, 0x00, 0x14, 0x0B, 0x98, 0x08, 0x42, 0x33, 0x95,
-0x15, 0x00, 0x64, 0x13, 0x10, 0x48, 0x48, 0x01, 0x00, 0x05, 0x82, 0x76, 0x11,
-0x11, 0x0C, 0x50, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
-0x45, 0x00, 0xDD, 0x22, 0x54, 0x04, 0xD1, 0x0D, 0x40, 0x47, 0x10, 0xD1, 0x00,
-0x74, 0x09, 0x10, 0x0D, 0x40, 0x34, 0x00, 0xD5, 0x10, 0x44, 0x03, 0x10, 0x21,
-0x40, 0x84, 0x00, 0x11, 0x01, 0x54, 0x03, 0x80, 0x0D, 0x42, 0x35, 0x00, 0x15,
-0x10, 0x64, 0x02, 0x10, 0x09, 0x44, 0x25, 0x04, 0xD5, 0x14, 0x54, 0x03, 0x10,
-0x09, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x47,
-0x00, 0x9F, 0x09, 0x7D, 0x04, 0xF0, 0x9D, 0xC0, 0xC7, 0x20, 0xDB, 0x80, 0x7C,
-0x09, 0x31, 0x51, 0xC0, 0x64, 0x02, 0x13, 0x02, 0x4C, 0x03, 0x30, 0x2D, 0xC0,
-0xC7, 0x42, 0x13, 0x01, 0x7C, 0x03, 0xB0, 0x89, 0xC0, 0x37, 0x00, 0x9F, 0x02,
-0x2D, 0x02, 0xB1, 0xB5, 0xC0, 0x85, 0x00, 0x05, 0x03, 0x7C, 0x6F, 0x24, 0x1C,
-0x80, 0x8A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00,
-0xAF, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0B, 0x10, 0xFF, 0x00, 0xBC, 0x02,
-0xF2, 0x91, 0xC0, 0x7B, 0x00, 0x2F, 0x00, 0xBC, 0x03, 0xF0, 0x57, 0xC0, 0x2D,
-0x00, 0x3E, 0x00, 0xAC, 0x83, 0xF0, 0x0B, 0xC8, 0x3B, 0x00, 0xFB, 0x49, 0xDC,
-0x02, 0xD0, 0x12, 0xC0, 0x1A, 0x40, 0xFB, 0x00, 0xEC, 0x03, 0xF4, 0x5F, 0xC0,
-0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x80, 0x9F,
-0x07, 0x6C, 0x02, 0x70, 0x8D, 0xC0, 0x06, 0x00, 0xD3, 0x20, 0x5E, 0x09, 0x38,
-0x00, 0xC0, 0x24, 0x02, 0x5F, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x93, 0x00,
-0x1F, 0x06, 0x4C, 0x63, 0x30, 0x09, 0xC0, 0x34, 0x20, 0x1B, 0x20, 0x4E, 0x03,
-0xF1, 0x0D, 0xC0, 0x96, 0x0A, 0x17, 0x02, 0x6C, 0x43, 0x30, 0x0D, 0xC0, 0x28,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x44, 0x86, 0xDD, 0xC2,
-0x44, 0xE8, 0x12, 0x1D, 0x40, 0x04, 0x00, 0xF1, 0x00, 0x6C, 0x03, 0x31, 0x01,
-0x40, 0xF4, 0x02, 0xDD, 0x04, 0xC4, 0x03, 0x10, 0x05, 0xC6, 0xE7, 0x81, 0x0F,
-0x40, 0xD0, 0x0B, 0xB1, 0x1D, 0x40, 0x3D, 0x00, 0x41, 0x00, 0x4C, 0x02, 0x70,
-0x09, 0x44, 0x34, 0x12, 0xDB, 0x1B, 0x08, 0x43, 0x10, 0x7D, 0x40, 0x4D, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x02, 0x30, 0x0D, 0x00, 0x04,
-0x06, 0x10, 0x58, 0x50, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x02, 0x90, 0x00, 0x40,
-0x30, 0x00, 0x8D, 0x01, 0x04, 0x27, 0x10, 0x09, 0x40, 0x23, 0x21, 0x09, 0x42,
-0x04, 0x0F, 0x50, 0xF4, 0x48, 0x30, 0x10, 0x41, 0x00, 0x06, 0x02, 0xDA, 0x00,
-0x00, 0x62, 0x40, 0xCC, 0x03, 0x01, 0x07, 0x58, 0x7C, 0x40, 0x0C, 0x20, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x4A, 0x00, 0x6D, 0x01, 0x84, 0x07,
-0x12, 0x1F, 0x44, 0x48, 0x00, 0xE1, 0x01, 0x24, 0x04, 0x10, 0x9A, 0x40, 0x78,
-0x80, 0x4D, 0x01, 0x84, 0x27, 0x10, 0x1A, 0x42, 0x59, 0x00, 0x35, 0x01, 0x94,
-0x03, 0xDC, 0x16, 0x60, 0x71, 0x02, 0xE1, 0x01, 0x84, 0x06, 0x50, 0x94, 0x40,
-0x78, 0x83, 0xE9, 0x09, 0xC4, 0x27, 0x50, 0x16, 0x40, 0x35, 0x20, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x82, 0x00, 0x8D, 0x00, 0x4C, 0x23, 0x70,
-0x88, 0xC0, 0x80, 0x42, 0xD3, 0x00, 0x34, 0x02, 0x90, 0x84, 0xC4, 0x30, 0x00,
-0x8D, 0x00, 0x0C, 0x03, 0x30, 0x44, 0x40, 0x33, 0x01, 0x0D, 0x08, 0x0C, 0x13,
-0x50, 0x04, 0x40, 0x30, 0x00, 0x03, 0x08, 0x0C, 0x83, 0xF0, 0xA0, 0xD0, 0x02,
-0x01, 0x07, 0x88, 0x0C, 0x23, 0x70, 0x4C, 0xC0, 0x48, 0x40, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x00, 0xFF, 0x08, 0xDE, 0x03, 0xF4, 0x0F,
-0xC2, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x8F, 0xC2, 0x3F, 0x00, 0xFF,
-0x40, 0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x3F, 0x08, 0xBC, 0x1B, 0x30,
-0x8E, 0xC0, 0x3F, 0x00, 0xA7, 0xA0, 0xFD, 0x02, 0xF0, 0x87, 0xC0, 0x2F, 0x41,
-0xEF, 0x08, 0x7C, 0x23, 0xB0, 0x0D, 0xC4, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA8, 0x0F, 0x00, 0x1F, 0x00, 0x4C, 0x01, 0xE1, 0x09, 0xC0,
-0x07, 0x08, 0xDF, 0x06, 0x5C, 0x03, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x93, 0x00,
-0x4C, 0x27, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x1B, 0x00, 0x7C, 0x23, 0xF8, 0x11,
-0xC0, 0x36, 0x03, 0xDB, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC0, 0x24, 0x00, 0x13,
-0x20, 0x4D, 0x03, 0x30, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x98, 0x29, 0x00, 0x6D, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x0B,
-0x00, 0xFD, 0x12, 0x84, 0x02, 0xD0, 0x0F, 0x48, 0x38, 0x00, 0x21, 0x00, 0x04,
-0x33, 0x14, 0x0A, 0x40, 0x3B, 0x40, 0x22, 0x00, 0xB4, 0x13, 0xD0, 0x0A, 0x40,
-0x3C, 0x02, 0xE1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x52, 0x3D, 0x00, 0xC5, 0x00,
-0x84, 0x02, 0x10, 0x0E, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x00, 0xF9, 0x00, 0x8D, 0x01, 0x94, 0x0F, 0xD0, 0x1A, 0x40, 0x5B, 0x08,
-0xED, 0x01, 0x94, 0x07, 0xD0, 0x3E, 0x40, 0x78, 0x40, 0xC1, 0x11, 0xA5, 0x07,
-0x18, 0x1E, 0x40, 0x73, 0x00, 0x21, 0x01, 0xB4, 0x07, 0x50, 0x17, 0x46, 0x79,
-0x01, 0xE9, 0x01, 0xB4, 0x07, 0xD2, 0x1C, 0x70, 0x58, 0x00, 0x21, 0x01, 0x86,
-0x47, 0x10, 0x1E, 0x41, 0x13, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-0x20, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0xB7, 0x00, 0xCD,
-0x00, 0x04, 0x17, 0xD8, 0x0C, 0x40, 0x34, 0x00, 0xC1, 0x00, 0x24, 0x03, 0x10,
-0x2C, 0x40, 0xB3, 0x01, 0xC1, 0x07, 0x34, 0x03, 0xD8, 0x2C, 0x40, 0x31, 0x00,
-0xC1, 0x48, 0x74, 0x02, 0xD0, 0x2C, 0x64, 0x71, 0x80, 0xC5, 0x0B, 0x04, 0x9B,
-0x12, 0x3C, 0x60, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0,
-0x1F, 0x00, 0x6F, 0x00, 0xDD, 0x0D, 0xF0, 0x05, 0xC0, 0x1F, 0x00, 0x5F, 0x00,
-0xDC, 0x49, 0xF0, 0x07, 0xD0, 0x14, 0x00, 0x73, 0x01, 0x6C, 0x01, 0x30, 0xD7,
-0xC0, 0x9B, 0x40, 0x73, 0x11, 0x7C, 0x01, 0xF0, 0xB7, 0x54, 0x17, 0x00, 0x7B,
-0x02, 0x7C, 0x01, 0xF0, 0x47, 0xC0, 0x5C, 0x09, 0x73, 0x80, 0x8C, 0x05, 0x35,
-0x06, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05,
-0x00, 0x1F, 0x00, 0x6C, 0x98, 0xF2, 0x01, 0xC0, 0x07, 0x04, 0x0F, 0x00, 0x7C,
-0x00, 0xF0, 0x41, 0xC0, 0x07, 0x08, 0x0F, 0x02, 0x5C, 0x80, 0xF0, 0x01, 0xC0,
-0x07, 0x00, 0x1F, 0x82, 0x7C, 0x80, 0xF0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x04,
-0x7C, 0x00, 0xB8, 0x01, 0xC1, 0x07, 0x00, 0x0F, 0x12, 0x7C, 0x00, 0xF0, 0x21,
-0xC5, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x61, 0x04,
-0x93, 0x00, 0x0D, 0x0E, 0x30, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x1C, 0x02,
-0xB4, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC8, 0x27,
-0x02, 0x9F, 0x40, 0x7C, 0x02, 0xF2, 0x89, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C,
-0x02, 0x30, 0x09, 0xC8, 0x23, 0x20, 0x9B, 0x01, 0x4D, 0x22, 0x70, 0x19, 0xC2,
-0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x02, 0x95,
-0x02, 0x44, 0x0E, 0x14, 0x09, 0x42, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x10,
-0x09, 0x48, 0x27, 0x08, 0x91, 0x12, 0x44, 0x42, 0xD0, 0x09, 0x44, 0x67, 0x10,
-0x91, 0x00, 0x74, 0x46, 0xD0, 0x39, 0xE0, 0x25, 0x00, 0x93, 0x00, 0x5C, 0x02,
-0x50, 0x09, 0x40, 0x27, 0x00, 0x91, 0x03, 0x4C, 0x02, 0x10, 0xA9, 0x40, 0x04,
-0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x91, 0x02,
-0x44, 0x02, 0x90, 0x89, 0x40, 0x27, 0x00, 0x91, 0x00, 0x54, 0x02, 0x10, 0x09,
-0x40, 0x27, 0x00, 0x9D, 0x40, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x20, 0xD5,
-0x00, 0x74, 0x12, 0xD8, 0x0D, 0x45, 0x23, 0x00, 0x95, 0x00, 0x74, 0x02, 0x10,
-0x09, 0x40, 0x27, 0x40, 0x99, 0x88, 0x44, 0x42, 0x50, 0x09, 0x42, 0x71, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x20, 0x01, 0x85, 0x04, 0x04,
-0x1B, 0x90, 0x28, 0x40, 0x23, 0x41, 0x81, 0x0C, 0x04, 0x12, 0x10, 0x48, 0x40,
-0x23, 0x01, 0x8D, 0x04, 0x06, 0x12, 0xD0, 0x88, 0x40, 0x23, 0x01, 0xC1, 0x00,
-0x36, 0x02, 0xD0, 0x08, 0x44, 0x23, 0x03, 0x81, 0x00, 0x14, 0x02, 0x50, 0x08,
-0x44, 0x23, 0x02, 0xC9, 0x00, 0x44, 0x22, 0x10, 0x0D, 0x60, 0x50, 0xA8, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x13, 0x00, 0x4C, 0x08,
-0xB0, 0x25, 0xC0, 0x87, 0x02, 0x13, 0x02, 0x5C, 0x28, 0x30, 0xA1, 0xC0, 0x83,
-0x42, 0x1F, 0x0A, 0x44, 0x28, 0xD0, 0x21, 0x00, 0x17, 0x00, 0x1F, 0x40, 0x7C,
-0x50, 0xF0, 0x01, 0x40, 0x87, 0x00, 0x17, 0x00, 0x7C, 0x28, 0x30, 0xE1, 0xC1,
-0x87, 0x45, 0x1B, 0x14, 0x0C, 0x08, 0x70, 0x01, 0xC0, 0x75, 0xC0, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x2F, 0x12, 0xBF, 0x08, 0xFC, 0x0A, 0x70,
-0x0B, 0xC2, 0x2F, 0x02, 0x9F, 0x0C, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x2F, 0x02,
-0xB3, 0x08, 0x7C, 0x22, 0xF2, 0x4F, 0xC0, 0x2F, 0x22, 0xBF, 0x00, 0x7C, 0x02,
-0xF0, 0x0A, 0xC0, 0x25, 0x03, 0xB6, 0x00, 0xD8, 0x02, 0xF0, 0x0B, 0xC0, 0x3F,
-0x41, 0xB7, 0x00, 0xDC, 0x12, 0xF4, 0x0F, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x05, 0xBF, 0x04, 0xCC, 0x02, 0xF0, 0x0B,
-0xC0, 0x33, 0x02, 0x93, 0x04, 0x7C, 0xD2, 0xB0, 0xC9, 0xC0, 0x2C, 0x00, 0xB3,
-0x00, 0xCC, 0x22, 0x34, 0x09, 0xC0, 0x28, 0x05, 0xBB, 0x00, 0xDC, 0x02, 0xB0,
-0x0B, 0xC0, 0x27, 0x02, 0xB3, 0x20, 0x5C, 0x8A, 0xF2, 0x49, 0xC2, 0x2D, 0x40,
-0xBE, 0x00, 0xCC, 0x02, 0x30, 0x0A, 0xD0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1C, 0x18, 0x15, 0x01, 0x1D, 0x08, 0x45, 0xC8, 0xD0, 0x01, 0x49,
-0x07, 0x02, 0x11, 0x14, 0x30, 0x10, 0x00, 0xC1, 0x42, 0x84, 0x04, 0x01, 0x10,
-0x44, 0x20, 0x11, 0x41, 0x83, 0x05, 0x20, 0x57, 0x40, 0x5C, 0x08, 0x01, 0x01,
-0x40, 0x03, 0x02, 0x11, 0x00, 0x64, 0x14, 0xD0, 0xD1, 0x41, 0x81, 0x44, 0x55,
-0x00, 0x04, 0x01, 0x50, 0x01, 0x40, 0x70, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x20, 0x31, 0x05, 0x8D, 0x00, 0x34, 0xB2, 0xD0, 0x08, 0x40, 0x23,
-0x00, 0x81, 0x2C, 0x34, 0x52, 0x98, 0x48, 0x48, 0x20, 0x03, 0x81, 0xC8, 0x04,
-0x02, 0x10, 0x49, 0x04, 0x20, 0x10, 0x81, 0x00, 0x14, 0x22, 0xD1, 0x08, 0x40,
-0x23, 0x20, 0x81, 0x00, 0x16, 0x12, 0xD0, 0x08, 0x40, 0x21, 0x4B, 0x8D, 0xC0,
-0x45, 0x02, 0x12, 0x09, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x00, 0x25, 0x01, 0x9D, 0x03, 0x74, 0x0A, 0xD2, 0x09, 0x40, 0xA3, 0x40,
-0x91, 0x40, 0x74, 0x02, 0x10, 0x08, 0x40, 0x30, 0x00, 0x91, 0x03, 0x04, 0x02,
-0x10, 0x49, 0x50, 0x26, 0x12, 0x95, 0x00, 0x54, 0x03, 0x50, 0xA9, 0x40, 0x27,
-0x00, 0x91, 0x00, 0x64, 0x12, 0xD0, 0x09, 0x40, 0x25, 0x40, 0x95, 0x08, 0x44,
-0x12, 0x50, 0x09, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0xA8, 0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x93,
-0x60, 0x7C, 0x02, 0xB0, 0x19, 0xD0, 0x24, 0x40, 0x93, 0x02, 0x44, 0x02, 0x30,
-0x08, 0xC2, 0x24, 0x08, 0x93, 0x02, 0x5C, 0x82, 0xF0, 0x19, 0xC8, 0x27, 0x40,
-0x91, 0x18, 0x5C, 0x06, 0xF0, 0x29, 0xC1, 0x25, 0x00, 0x9F, 0x00, 0x44, 0x02,
-0x20, 0x28, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80,
-0x65, 0x00, 0x8F, 0x00, 0x4C, 0x4E, 0xF0, 0x09, 0xC1, 0xE7, 0x30, 0x9F, 0x40,
-0x7C, 0x22, 0xF0, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x09,
-0xC0, 0x65, 0x00, 0x9F, 0x19, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x10, 0x9F,
-0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0xE7, 0x40, 0x8B, 0x10, 0x7C, 0x82, 0xF0,
-0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05,
-0x80, 0x1F, 0x06, 0x4E, 0x08, 0xF0, 0x01, 0xC4, 0x04, 0x80, 0x13, 0x00, 0x7E,
-0x80, 0xF0, 0x01, 0xC0, 0x07, 0x06, 0x1F, 0x12, 0x5C, 0x20, 0xF8, 0x21, 0xC0,
-0x07, 0x94, 0x13, 0x02, 0x3C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x00, 0x1B, 0x0A,
-0x7C, 0x00, 0xE1, 0x20, 0xC0, 0x80, 0x04, 0x17, 0x20, 0x4C, 0x00, 0x30, 0x81,
-0xC2, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x1C, 0x00,
-0x7D, 0x00, 0xC4, 0x01, 0x70, 0x57, 0x40, 0x15, 0x80, 0x5B, 0x40, 0x64, 0x01,
-0xB2, 0x05, 0xC2, 0x1F, 0x20, 0x7D, 0x11, 0xC4, 0x25, 0x78, 0x05, 0xE0, 0xDB,
-0x00, 0x7B, 0x04, 0xFC, 0x2D, 0x70, 0x37, 0x44, 0x17, 0x20, 0x53, 0x40, 0x58,
-0x01, 0x70, 0x05, 0xD0, 0x1C, 0x00, 0x71, 0x00, 0xC4, 0x05, 0x14, 0x17, 0x40,
-0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD,
-0x20, 0x06, 0x03, 0x50, 0x3C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x03, 0x50,
-0x0C, 0x60, 0xF3, 0x08, 0xDD, 0x02, 0x14, 0x0F, 0xD1, 0x0C, 0x40, 0x13, 0x02,
-0xC1, 0x03, 0x34, 0x0F, 0x41, 0x4C, 0x60, 0x37, 0x80, 0x81, 0x01, 0x34, 0x03,
-0x90, 0x0C, 0x40, 0x32, 0x00, 0xC5, 0x03, 0x44, 0x1F, 0x50, 0x4C, 0x40, 0x50,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x28, 0x00, 0xAD, 0x00,
-0x86, 0x41, 0x58, 0x1E, 0x60, 0x3D, 0x10, 0xE9, 0x40, 0xB4, 0x33, 0x10, 0x4E,
-0x40, 0x39, 0x08, 0xED, 0x00, 0x84, 0x03, 0x50, 0x4E, 0x40, 0x19, 0x08, 0xE9,
-0x00, 0x94, 0x09, 0x50, 0x26, 0x40, 0x3B, 0x03, 0xA1, 0x40, 0xB6, 0x13, 0x50,
-0x8E, 0x40, 0x08, 0x04, 0xC1, 0x02, 0x84, 0x40, 0x50, 0x0E, 0x40, 0x05, 0x20,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x68, 0x00, 0xCD, 0x01, 0x85,
-0x07, 0x70, 0x17, 0xC0, 0x78, 0x01, 0xE1, 0x01, 0xB4, 0x07, 0x50, 0x5E, 0x40,
-0x7B, 0x00, 0xED, 0x01, 0x9C, 0x85, 0xD0, 0x1E, 0x60, 0x7B, 0x00, 0xE1, 0x01,
-0xB4, 0x06, 0x70, 0x1E, 0xC0, 0x7B, 0x40, 0xA3, 0x01, 0xBC, 0x1F, 0xF1, 0x5F,
-0xC0, 0x7A, 0x00, 0xE7, 0x01, 0x8D, 0x07, 0x70, 0x1E, 0xC0, 0x44, 0x40, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x2D, 0x00, 0x9F, 0x00, 0x7C, 0x01,
-0x70, 0x0D, 0xC0, 0xB7, 0x00, 0xDF, 0x00, 0x6C, 0x43, 0xF1, 0x2D, 0xC1, 0x37,
-0x30, 0xDC, 0x00, 0x7C, 0x81, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C,
-0x02, 0x70, 0x0D, 0xC0, 0xB7, 0x04, 0x9B, 0x00, 0x58, 0x83, 0xFA, 0x0D, 0xCC,
-0x06, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xB0, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x6F, 0x00, 0xF3, 0x41, 0xCC, 0x13, 0xF0,
-0x1F, 0xC0, 0xFF, 0x04, 0xFB, 0x91, 0xEC, 0x07, 0x80, 0x9F, 0xC1, 0x5C, 0x08,
-0x7B, 0x89, 0xCC, 0x06, 0x30, 0x1F, 0xC1, 0x5F, 0x00, 0xB3, 0x01, 0xF8, 0xA7,
-0xB0, 0x1F, 0xD0, 0x7C, 0x00, 0xFF, 0x21, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7D,
-0x02, 0x77, 0x01, 0xCC, 0x07, 0xB0, 0x1F, 0xC0, 0x03, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x10, 0xAD, 0x40, 0xA1, 0x30, 0x84, 0x03, 0xD0, 0x0E,
-0x45, 0x3F, 0x00, 0xE1, 0x00, 0x84, 0x63, 0x10, 0x0E, 0x48, 0x0C, 0x02, 0x31,
-0x0C, 0xC5, 0x22, 0x10, 0x0E, 0x43, 0x9B, 0x02, 0xA1, 0x02, 0xB4, 0x01, 0x50,
-0xA2, 0x40, 0x38, 0x80, 0xED, 0x10, 0xB4, 0x03, 0x70, 0x4E, 0x50, 0x18, 0x47,
-0xFB, 0x00, 0xC4, 0x08, 0x14, 0x0A, 0x48, 0x57, 0x60, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x08, 0x28, 0x00, 0x61, 0x08, 0x84, 0x63, 0xD0, 0x86, 0x40,
-0x3B, 0x00, 0xE1, 0x00, 0x24, 0x03, 0x14, 0x0C, 0x50, 0x18, 0x44, 0x61, 0x00,
-0xA4, 0x00, 0x14, 0x0E, 0x40, 0x33, 0x44, 0x21, 0x10, 0xB4, 0x03, 0x11, 0x0E,
-0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x43, 0xD0, 0x0E, 0x44, 0x39, 0x80, 0xF5,
-0x00, 0x84, 0x43, 0x90, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x04, 0x20, 0x23, 0x14, 0x01, 0x20, 0x04, 0x0E, 0xD0, 0x18, 0x40, 0xB3,
-0x04, 0xC1, 0x00, 0x04, 0x03, 0x10, 0x2C, 0x41, 0x40, 0x00, 0x01, 0x03, 0x64,
-0x00, 0x11, 0x2C, 0x40, 0xF3, 0x00, 0x01, 0x12, 0x34, 0x03, 0x50, 0x38, 0x40,
-0x30, 0x00, 0xCD, 0x03, 0x76, 0x07, 0x50, 0x0D, 0x40, 0x54, 0x00, 0x49, 0x0C,
-0x05, 0x0E, 0x10, 0x9C, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x28, 0x25, 0x00, 0x93, 0x01, 0x45, 0x0A, 0xF8, 0x09, 0xC0, 0xBF, 0x40,
-0xF3, 0x00, 0xEC, 0x0F, 0x30, 0x2F, 0xC0, 0x64, 0x00, 0x93, 0x12, 0x6C, 0x03,
-0x30, 0x0E, 0xC0, 0x17, 0x10, 0x13, 0x03, 0x7C, 0x83, 0xB0, 0x18, 0xC0, 0x3C,
-0x20, 0x9F, 0x00, 0xF4, 0x07, 0xF0, 0x5F, 0xC0, 0x75, 0x00, 0x97, 0x22, 0x04,
-0x2F, 0xB0, 0xBC, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x00, 0x87, 0x00, 0x0F, 0x80, 0x7E, 0x00, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xD7,
-0x80, 0x7C, 0x13, 0x70, 0x0D, 0xC0, 0x87, 0x00, 0x97, 0x02, 0x5C, 0x0A, 0xF0,
-0x0D, 0xE0, 0x17, 0x00, 0x9F, 0x20, 0x3C, 0x08, 0xF0, 0xC1, 0xC8, 0x37, 0x00,
-0x9F, 0x04, 0x7C, 0x03, 0xF1, 0x0D, 0xC0, 0xA7, 0x44, 0xDF, 0x02, 0x7C, 0x88,
-0xF2, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08,
-0x2D, 0x00, 0x9F, 0x00, 0xEC, 0x42, 0xE0, 0x03, 0xE0, 0x3F, 0x00, 0xDF, 0x00,
-0xFC, 0x03, 0xF8, 0x0E, 0xD0, 0x2C, 0x02, 0x3F, 0x10, 0xCD, 0x07, 0x34, 0x0F,
-0xC1, 0x3C, 0x04, 0x3F, 0x00, 0xFC, 0x02, 0xB1, 0x8F, 0xC0, 0x3E, 0x00, 0xBF,
-0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x74, 0x40, 0xF7, 0x00, 0xFC, 0x17, 0x30,
-0x0F, 0x00, 0x10, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0xC6,
-0x08, 0x1D, 0x81, 0x44, 0x44, 0xD0, 0x11, 0x41, 0x37, 0x00, 0xDD, 0x00, 0x74,
-0x03, 0xD0, 0x0D, 0x40, 0xC4, 0x08, 0x19, 0x02, 0x4C, 0x0A, 0x10, 0x0D, 0x40,
-0x84, 0x00, 0x97, 0x03, 0x74, 0x06, 0xB8, 0x1D, 0x00, 0x34, 0x00, 0x8D, 0x01,
-0x54, 0x03, 0x10, 0x0D, 0x40, 0x24, 0x42, 0xD3, 0x09, 0x74, 0x05, 0x10, 0x05,
-0x48, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x64, 0x00,
-0x9D, 0x01, 0x64, 0x04, 0xD0, 0x19, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x54, 0x03,
-0xD0, 0x0D, 0x40, 0x34, 0x00, 0xCD, 0x03, 0x44, 0x19, 0x10, 0x0D, 0x50, 0x14,
-0x00, 0x18, 0x01, 0x74, 0x21, 0x10, 0x01, 0x00, 0x36, 0x00, 0x9D, 0x04, 0x44,
-0x03, 0x10, 0x0D, 0x40, 0x84, 0x40, 0xDD, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x40,
-0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x0D,
-0x01, 0x05, 0x00, 0xD1, 0x08, 0x48, 0x33, 0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0,
-0x0C, 0x40, 0x00, 0x00, 0x8D, 0x00, 0x06, 0x00, 0x10, 0x0D, 0x60, 0x10, 0x10,
-0x85, 0x00, 0x34, 0x00, 0x91, 0x01, 0x40, 0x30, 0x00, 0x9D, 0x80, 0x16, 0x03,
-0x10, 0x0C, 0x50, 0x00, 0x00, 0x81, 0x00, 0x74, 0x00, 0x50, 0x18, 0x50, 0x41,
-0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x26, 0x00, 0x1F, 0x00,
-0x6C, 0x02, 0xF1, 0x01, 0x40, 0x3F, 0x00, 0xDF, 0x00, 0xDC, 0x03, 0xD0, 0x0F,
-0xC0, 0x34, 0x00, 0x5D, 0x00, 0x4C, 0x01, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0x1F,
-0x00, 0x7C, 0x01, 0x11, 0x05, 0xC0, 0x3E, 0x00, 0x9F, 0x00, 0x4C, 0x03, 0x30,
-0x0D, 0xC0, 0x04, 0x00, 0xDF, 0x80, 0x7C, 0x00, 0x31, 0x0D, 0xC0, 0x00, 0xC0,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x0F, 0x00, 0x3F, 0x00, 0xFE,
-0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x0F, 0x00, 0x3B, 0x00, 0xDC, 0x00, 0xF0, 0x0F, 0xC4, 0x3F, 0x08, 0x37, 0x00,
-0xBC, 0x00, 0xF2, 0x02, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
-0xC0, 0x0F, 0x00, 0xF7, 0x40, 0xFC, 0x00, 0xB0, 0x0F, 0xC0, 0x16, 0x21, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x5F, 0x00, 0x73, 0x01, 0xCC, 0x07,
-0xF0, 0x1F, 0xC0, 0x3C, 0x01, 0xB3, 0x01, 0xAC, 0x05, 0xF0, 0x4F, 0xC0, 0x4D,
-0x08, 0x3F, 0x03, 0x4C, 0x04, 0xF0, 0x0F, 0xC0, 0x4F, 0x40, 0x33, 0x01, 0xFC,
-0x0C, 0x71, 0x90, 0xC0, 0x4C, 0x00, 0xA3, 0x01, 0xED, 0x04, 0xF0, 0x12, 0xC0,
-0x4F, 0x00, 0x3F, 0x02, 0xCE, 0x26, 0x34, 0x03, 0xC0, 0x0F, 0x08, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x53, 0x00, 0x51, 0x01, 0xEC, 0x07, 0xD0,
-0x1F, 0x40, 0x74, 0x00, 0x95, 0x01, 0x51, 0x06, 0xD0, 0x9F, 0x42, 0x44, 0x00,
-0x1D, 0x00, 0x4C, 0x04, 0xD0, 0x3F, 0x40, 0x47, 0x00, 0x11, 0x01, 0x74, 0x00,
-0x10, 0x45, 0x44, 0x45, 0x00, 0x11, 0x41, 0x44, 0x00, 0xD0, 0x11, 0x40, 0x47,
-0x00, 0x97, 0x82, 0x6C, 0x10, 0x10, 0x11, 0x48, 0x0F, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x11, 0xA0, 0x25, 0x00, 0x81, 0x00, 0x04, 0x03, 0x51, 0x0C,
-0x40, 0xB0, 0x00, 0x45, 0x00, 0x04, 0x01, 0x50, 0x0C, 0x40, 0x21, 0x00, 0x05,
-0x04, 0x24, 0x03, 0xD0, 0x2C, 0x40, 0x07, 0x00, 0x01, 0x00, 0x74, 0x10, 0xD0,
-0x09, 0x40, 0x35, 0x00, 0x95, 0x80, 0x14, 0x50, 0xD1, 0x00, 0x40, 0x01, 0x08,
-0x4D, 0x06, 0x44, 0x02, 0x10, 0x08, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0xA0, 0x27, 0x00, 0xC1, 0x00, 0x64, 0x03, 0xD0, 0x0D, 0x40,
-0x34, 0x00, 0x55, 0x06, 0x54, 0x02, 0xD0, 0x0D, 0x40, 0x44, 0x00, 0x0D, 0x81,
-0x44, 0x23, 0xD0, 0x0D, 0x40, 0x07, 0x00, 0x11, 0x04, 0x74, 0x46, 0x10, 0x0D,
-0x40, 0x35, 0x40, 0x15, 0x02, 0x50, 0x06, 0xD0, 0x11, 0x60, 0x07, 0x00, 0x95,
-0x08, 0x45, 0x06, 0x10, 0x11, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA8, 0x73, 0x00, 0x93, 0x02, 0x4C, 0x03, 0xF0, 0x0C, 0xD0, 0x34,
-0x80, 0xC7, 0x03, 0x6C, 0x1B, 0xF0, 0x0C, 0xC0, 0x65, 0x01, 0x9F, 0x01, 0x6C,
-0x4E, 0xF0, 0x0D, 0xC0, 0x83, 0x01, 0x13, 0x00, 0x3C, 0x04, 0x70, 0x3D, 0xC0,
-0xF5, 0x08, 0x87, 0x03, 0x54, 0x44, 0xF0, 0x31, 0xC1, 0x07, 0x11, 0x1F, 0x05,
-0x44, 0x06, 0x30, 0x31, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x07, 0x80, 0xFD, 0x40, 0xBF, 0x00, 0xFC, 0x03, 0xF2, 0x0F, 0xC0, 0x3B, 0x20,
-0xFF, 0x00, 0xE8, 0x96, 0xF0, 0x0F, 0xC0, 0x0F, 0x20, 0x3F, 0x00, 0xFC, 0x06,
-0xE0, 0x0D, 0xC4, 0x4E, 0x02, 0x3F, 0x41, 0xF4, 0x02, 0xF0, 0x2F, 0xC0, 0xBF,
-0x00, 0xBB, 0x02, 0xC4, 0x02, 0xD0, 0x03, 0x41, 0x0F, 0x00, 0x1F, 0x01, 0xFC,
-0x00, 0xF0, 0x03, 0xC4, 0x3F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x08, 0xA5, 0x00, 0x93, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
-0x00, 0x6E, 0x0B, 0x30, 0x0D, 0xC0, 0xA4, 0x80, 0x9F, 0x02, 0x7C, 0x02, 0xF0,
-0x8D, 0xC2, 0x07, 0x02, 0x1E, 0x00, 0x7C, 0x18, 0xF0, 0x0D, 0xC0, 0x36, 0x01,
-0x9F, 0x06, 0x6C, 0x08, 0xF2, 0x81, 0xC8, 0x16, 0x44, 0x83, 0x02, 0x4D, 0x8A,
-0x30, 0x29, 0xC4, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
-0x24, 0x00, 0x91, 0x00, 0x74, 0x03, 0x50, 0x0D, 0x40, 0x3F, 0x00, 0xDD, 0x07,
-0x76, 0x1E, 0xF0, 0xAF, 0x40, 0x44, 0x00, 0x9F, 0x80, 0x74, 0x4F, 0xD0, 0x1F,
-0xC0, 0xC4, 0x00, 0x1F, 0x0C, 0x70, 0x02, 0xF0, 0x0C, 0x40, 0xF0, 0x08, 0x9D,
-0x02, 0x50, 0x02, 0xD2, 0x11, 0x50, 0x54, 0x04, 0x91, 0x09, 0x64, 0x02, 0x34,
-0x39, 0xC0, 0x6C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x22,
-0x00, 0xC1, 0x40, 0x24, 0x03, 0x10, 0x4C, 0x60, 0x33, 0x00, 0x4D, 0x04, 0x34,
-0x1E, 0x10, 0x1C, 0x40, 0x40, 0x00, 0x89, 0x00, 0x36, 0x11, 0xD0, 0x4C, 0x60,
-0x02, 0x04, 0x09, 0x00, 0x34, 0x0C, 0xDA, 0x00, 0x00, 0x82, 0x02, 0x08, 0x00,
-0x14, 0x00, 0xD0, 0x20, 0x40, 0x40, 0x00, 0x09, 0x83, 0x64, 0x32, 0x90, 0xC8,
-0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x08, 0x7A, 0x40,
-0xE1, 0x01, 0x34, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0x6D, 0x81, 0xF6, 0x26,
-0xD0, 0x1C, 0x40, 0x48, 0x00, 0x25, 0x49, 0xB6, 0x25, 0xD0, 0x9E, 0x40, 0x48,
-0x00, 0x2D, 0x01, 0xB4, 0x05, 0xD1, 0x53, 0x40, 0x4A, 0x01, 0x7D, 0x81, 0x94,
-0x24, 0xD8, 0x12, 0x60, 0x4C, 0x80, 0x69, 0x21, 0xA4, 0x24, 0x10, 0x13, 0x40,
-0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0xA2, 0x00, 0x81,
-0x00, 0x2C, 0x23, 0x10, 0x0C, 0xC0, 0x33, 0x00, 0x4F, 0x00, 0x34, 0x22, 0x10,
-0x0C, 0xC1, 0x60, 0x05, 0x89, 0x07, 0x3C, 0x15, 0xF0, 0x8C, 0xC0, 0x03, 0x02,
-0x0F, 0x01, 0x38, 0x46, 0xF0, 0x50, 0xE8, 0x42, 0x10, 0xCD, 0x14, 0x14, 0x23,
-0xF0, 0x80, 0xC0, 0x00, 0x00, 0xCB, 0x10, 0x4C, 0x23, 0xB2, 0x2D, 0xE0, 0x4A,
-0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x2D, 0x00, 0xFF, 0x80,
-0xFC, 0x07, 0x70, 0x1F, 0xC0, 0x3F, 0x00, 0x7F, 0x08, 0xFC, 0x22, 0x70, 0x0D,
-0xD0, 0x27, 0x02, 0xBE, 0x00, 0xFC, 0x23, 0xF0, 0x8F, 0xC0, 0x0F, 0x02, 0x35,
-0x40, 0xFC, 0x03, 0x70, 0x0F, 0xE8, 0x3D, 0x00, 0x7F, 0x00, 0xDC, 0x23, 0xF0,
-0x03, 0xC8, 0x09, 0x02, 0xF7, 0x00, 0xDC, 0x23, 0xD0, 0x83, 0xD0, 0x0B, 0x60,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x67, 0x00, 0x93, 0x00, 0x7C,
-0x23, 0xF0, 0x1D, 0xD0, 0x34, 0x00, 0x57, 0x00, 0x7C, 0x03, 0x30, 0xDC, 0xC0,
-0x65, 0x20, 0x9B, 0x20, 0x6C, 0x04, 0xB0, 0x9D, 0xC0, 0x04, 0x00, 0x1F, 0x80,
-0x7C, 0x07, 0xBC, 0x01, 0xC0, 0x07, 0x00, 0x5F, 0x01, 0x6E, 0x07, 0x39, 0x01,
-0xC0, 0x07, 0x80, 0x5F, 0x00, 0x4C, 0x01, 0x33, 0x09, 0xC0, 0x40, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xAB, 0x00, 0xB4, 0x13,
-0xD0, 0x2C, 0x40, 0x38, 0x11, 0x61, 0x00, 0x8C, 0x02, 0x18, 0x4E, 0x41, 0x28,
-0x30, 0x31, 0x00, 0x84, 0x03, 0x11, 0xCC, 0x40, 0x08, 0x88, 0x2D, 0x00, 0xB4,
-0x03, 0x10, 0x0A, 0x42, 0x3B, 0x80, 0x6D, 0x00, 0x94, 0x03, 0x14, 0x02, 0x40,
-0x0B, 0x00, 0x7D, 0xC0, 0xC4, 0x01, 0xB0, 0x0A, 0x40, 0x4D, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x00, 0xA1, 0x03, 0x94, 0x07, 0x52,
-0x5E, 0x60, 0x70, 0x03, 0x65, 0x43, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x6D, 0x00,
-0xA5, 0x01, 0x84, 0x04, 0x10, 0x1E, 0x40, 0xC9, 0x00, 0x25, 0x01, 0xB4, 0x07,
-0x10, 0x16, 0x44, 0x4B, 0x10, 0xFD, 0x01, 0x94, 0x87, 0x10, 0x16, 0x44, 0x5B,
-0x20, 0xED, 0x01, 0xA4, 0x05, 0x10, 0x1C, 0x64, 0x10, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x16, 0x28, 0x23, 0x04, 0x89, 0x00, 0x34, 0x03, 0xD0, 0x0C,
-0x40, 0x30, 0x00, 0x41, 0x45, 0x30, 0x2E, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xC5,
-0x20, 0x04, 0x1F, 0x10, 0x0C, 0x50, 0xF1, 0x01, 0xCD, 0x48, 0x34, 0x0F, 0x12,
-0x3C, 0x41, 0xF3, 0x00, 0xCD, 0x22, 0x14, 0x13, 0x10, 0x1C, 0x40, 0xF3, 0x0C,
-0xCD, 0x07, 0x24, 0x4F, 0x10, 0x4C, 0x48, 0x59, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x17, 0xA0, 0x9F, 0x00, 0x73, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0,
-0x14, 0x00, 0x77, 0x00, 0xB4, 0x01, 0xB5, 0x05, 0xC0, 0xDD, 0x01, 0x77, 0x08,
-0xEC, 0x0D, 0xB0, 0x05, 0xE0, 0xDD, 0x00, 0x7F, 0x0B, 0xFC, 0x15, 0xB1, 0x37,
-0xC1, 0xDB, 0x16, 0x7F, 0x02, 0xDD, 0x09, 0x30, 0x27, 0xC1, 0x5F, 0x14, 0x7F,
-0x04, 0xE4, 0x1D, 0x10, 0x17, 0x45, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x24, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
-0x00, 0x1F, 0x80, 0x4C, 0x10, 0xF0, 0x21, 0xC0, 0x07, 0x04, 0x12, 0x00, 0x7D,
-0x20, 0xF0, 0x01, 0x00, 0x86, 0x00, 0x1F, 0x00, 0x7C, 0x48, 0xF2, 0x01, 0xC0,
-0x87, 0x00, 0x1F, 0x0A, 0x64, 0x20, 0xF0, 0x01, 0xC1, 0x87, 0x00, 0x1F, 0x40,
-0x5D, 0x00, 0xF4, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x00, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00,
-0x93, 0x80, 0x7C, 0x0A, 0x30, 0x19, 0x40, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02,
-0xF0, 0x19, 0xC8, 0x26, 0x00, 0x93, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0x93, 0x10, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0x6C,
-0x0A, 0x30, 0x58, 0xC4, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x26, 0x00, 0x8D, 0x00, 0xC4, 0x02, 0xD8, 0x1B, 0x40, 0x27, 0x00, 0x95,
-0x01, 0x74, 0x02, 0x50, 0x09, 0x44, 0x27, 0x00, 0x87, 0x00, 0x44, 0x06, 0xD0,
-0x29, 0x44, 0xE3, 0x1C, 0x91, 0x01, 0x74, 0x12, 0xD0, 0x09, 0x4A, 0x67, 0x00,
-0x95, 0x22, 0x74, 0x82, 0xD0, 0x18, 0x40, 0x24, 0x08, 0x9C, 0x03, 0x04, 0x42,
-0x14, 0x19, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0,
-0x24, 0x00, 0xDD, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x91, 0x04,
-0x54, 0x02, 0x10, 0x69, 0x44, 0x27, 0x80, 0x9D, 0x00, 0x44, 0x06, 0xD0, 0x89,
-0x41, 0x27, 0x41, 0xD1, 0x0A, 0x74, 0x02, 0xD2, 0x0D, 0x48, 0x37, 0x02, 0x91,
-0x82, 0x74, 0x02, 0x52, 0x89, 0x00, 0x24, 0x00, 0x8D, 0x00, 0x42, 0x03, 0x10,
-0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0xA0,
-0x00, 0x9D, 0x02, 0x04, 0x0A, 0xD0, 0x08, 0x40, 0xA3, 0x00, 0x85, 0x20, 0x74,
-0x03, 0x50, 0x08, 0x48, 0x23, 0x00, 0x95, 0x08, 0x04, 0x83, 0xD2, 0x08, 0x40,
-0x23, 0x00, 0x81, 0x00, 0x34, 0x22, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x85, 0x80,
-0x34, 0x22, 0xD0, 0x09, 0x50, 0x30, 0x90, 0xCD, 0x68, 0x45, 0xA2, 0x10, 0x48,
-0x50, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x02, 0x00,
-0x1F, 0x00, 0x4D, 0x04, 0xD0, 0x11, 0xC0, 0x07, 0x05, 0x13, 0x80, 0x5C, 0x80,
-0x30, 0x41, 0xC1, 0x07, 0x20, 0x1F, 0x02, 0x4D, 0x00, 0xF0, 0x41, 0xC1, 0x07,
-0x00, 0x13, 0x80, 0x38, 0x08, 0xF0, 0x21, 0xC0, 0x17, 0x20, 0x13, 0x00, 0x3E,
-0x08, 0x70, 0x01, 0xC0, 0x04, 0x08, 0x1F, 0x16, 0x4C, 0x08, 0x30, 0x05, 0xC0,
-0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x7F, 0x00, 0xBF,
-0x01, 0x7C, 0x0E, 0xD0, 0x29, 0xC0, 0x67, 0x10, 0xBF, 0x00, 0xBC, 0x02, 0xF0,
-0x09, 0xC0, 0x2B, 0x00, 0xB7, 0x04, 0x9C, 0x02, 0xF2, 0x09, 0xC0, 0x3F, 0x20,
-0xFF, 0x40, 0xFC, 0x12, 0xD0, 0x4B, 0xC0, 0x2F, 0x10, 0xAF, 0x80, 0xFE, 0x12,
-0xF0, 0x0B, 0xC8, 0x2F, 0x00, 0xBE, 0x44, 0xDC, 0x13, 0xF0, 0x8B, 0xC0, 0x77,
-0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x27, 0x00, 0x9F, 0x42,
-0x7C, 0x36, 0xF0, 0x1B, 0xC1, 0x27, 0x02, 0xBF, 0x00, 0xDC, 0x02, 0xF2, 0x4B,
-0xC1, 0x2F, 0x00, 0xDB, 0x80, 0xCC, 0x02, 0xF0, 0x0B, 0xC8, 0x2F, 0x00, 0xBF,
-0x00, 0xC4, 0x22, 0xF0, 0x09, 0x40, 0x28, 0x00, 0xBE, 0x00, 0x4C, 0x82, 0x30,
-0x0B, 0xC0, 0x2B, 0x08, 0xBF, 0x00, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x74, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x10, 0x47, 0x05, 0x1D, 0xC1, 0x34,
-0x0C, 0xD0, 0x21, 0x40, 0x43, 0x20, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40,
-0x07, 0x00, 0x1D, 0x70, 0x44, 0x00, 0xD0, 0x81, 0x40, 0x07, 0x00, 0x1D, 0x00,
-0x44, 0x11, 0x72, 0x01, 0x41, 0x04, 0x30, 0x1D, 0x20, 0x54, 0x50, 0x10, 0x01,
-0x40, 0x17, 0x00, 0x1D, 0x00, 0x0C, 0x00, 0x10, 0x01, 0x44, 0x61, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x21, 0x00, 0x8D, 0x00, 0x34, 0x32,
-0xD0, 0x08, 0x40, 0x23, 0x03, 0x8D, 0x00, 0x05, 0x02, 0xD0, 0x08, 0x40, 0x23,
-0x00, 0x89, 0x04, 0x05, 0x02, 0xD0, 0x08, 0x08, 0x33, 0x00, 0x9D, 0x00, 0x05,
-0x12, 0xD8, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x14, 0x92, 0x10, 0x08, 0x60,
-0x23, 0x00, 0x8D, 0x00, 0x04, 0x82, 0x10, 0x09, 0x40, 0x4A, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0,
-0x09, 0x40, 0x27, 0x08, 0xDD, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x67, 0x20,
-0x8D, 0x18, 0x44, 0x02, 0xD0, 0x09, 0x44, 0x66, 0x10, 0x9D, 0x00, 0x44, 0x02,
-0x50, 0x28, 0x54, 0xB4, 0x02, 0x9D, 0x10, 0x55, 0x02, 0x10, 0x09, 0x41, 0x27,
-0x00, 0xDD, 0x00, 0x04, 0x02, 0x90, 0x19, 0x60, 0x63, 0x28, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0xA8, 0xEF, 0x00, 0xBF, 0x0D, 0xFC, 0x82, 0xF2, 0x09,
-0xC0, 0x2F, 0x00, 0x9F, 0x13, 0x4C, 0x02, 0xF0, 0x09, 0xC4, 0xE7, 0x24, 0x9B,
-0x81, 0x44, 0x46, 0xF2, 0x09, 0xC8, 0x67, 0x20, 0x9F, 0x00, 0x4C, 0x02, 0xF0,
-0x09, 0xC0, 0xE4, 0x00, 0x9F, 0x20, 0x54, 0x1A, 0x30, 0x29, 0xC0, 0x27, 0x00,
-0x9F, 0x12, 0x4C, 0x0E, 0x34, 0x59, 0xC0, 0x16, 0x00, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x80, 0xE5, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x05, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01,
-0x7C, 0x62, 0xE0, 0x09, 0x00, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x72, 0x49,
-0xC0, 0x27, 0x00, 0x9F, 0x03, 0x7C, 0x22, 0xD4, 0x99, 0xC0, 0x27, 0x01, 0x9D,
-0x13, 0x7F, 0xD2, 0x70, 0x09, 0xC1, 0x59, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x08, 0x85, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xB0, 0x01, 0xD0, 0x06,
-0x00, 0x13, 0x02, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x80, 0x1F, 0x02, 0x5C,
-0x88, 0x30, 0x01, 0xC5, 0x85, 0x40, 0x13, 0x30, 0x4C, 0x00, 0xF0, 0x21, 0xC0,
-0x07, 0x01, 0x13, 0x23, 0x5C, 0x08, 0xF0, 0x01, 0xC1, 0x05, 0x14, 0x03, 0x00,
-0x4C, 0x00, 0x21, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0xA0, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x58, 0x77, 0x40, 0x14, 0x00,
-0x65, 0x02, 0xD8, 0x01, 0xD0, 0x17, 0x40, 0x17, 0x80, 0x5C, 0x00, 0xD4, 0x01,
-0x11, 0x07, 0x01, 0x9D, 0x00, 0x61, 0x02, 0xC4, 0x85, 0x32, 0x05, 0xC0, 0x9D,
-0x40, 0x61, 0x10, 0x48, 0x01, 0xD1, 0x07, 0x40, 0x5F, 0x04, 0x71, 0x00, 0xD4,
-0x81, 0x50, 0x07, 0x48, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x78, 0x40, 0x30, 0x00, 0x41,
-0x04, 0x24, 0x02, 0xD0, 0xDC, 0x40, 0x33, 0x20, 0xCD, 0x40, 0x14, 0x03, 0x10,
-0x0C, 0x0A, 0xB0, 0x0C, 0xC1, 0x08, 0x05, 0x07, 0xD0, 0x0C, 0x40, 0x71, 0x00,
-0xC1, 0x80, 0x50, 0x83, 0xD0, 0x0C, 0x40, 0x31, 0x00, 0xC1, 0x03, 0x04, 0x2B,
-0x1C, 0x2D, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80,
-0x38, 0x01, 0xED, 0x04, 0xB4, 0x27, 0x58, 0x1A, 0x40, 0x78, 0x01, 0xF5, 0x00,
-0x94, 0x02, 0xD8, 0x0A, 0x40, 0x3B, 0x00, 0xED, 0x0C, 0x94, 0x0C, 0x10, 0x1A,
-0x4A, 0x7D, 0x00, 0xE1, 0x20, 0x84, 0x43, 0x00, 0x4E, 0x40, 0x4D, 0x24, 0xF1,
-0x40, 0xA4, 0x03, 0xD0, 0x0E, 0x40, 0x7F, 0x08, 0xE1, 0x82, 0x84, 0x01, 0x10,
-0x06, 0x44, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0xF8,
-0x00, 0xEF, 0x03, 0xBC, 0x07, 0x30, 0x1A, 0xC2, 0x78, 0x01, 0x63, 0x01, 0xAC,
-0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x00, 0xFD, 0x31, 0x96, 0x04, 0x30, 0x1A, 0x40,
-0x79, 0x00, 0x63, 0x01, 0x8C, 0x07, 0xF0, 0x1E, 0xC1, 0x49, 0x20, 0xE3, 0x01,
-0x9E, 0x17, 0xF2, 0x1E, 0xC8, 0x79, 0x40, 0xF3, 0x01, 0x8D, 0x06, 0x30, 0x1E,
-0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x35, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x08, 0xC0, 0x37, 0x10, 0xCF, 0x00, 0x7C, 0x02,
-0xF1, 0x01, 0xC0, 0x37, 0x00, 0xDD, 0x02, 0x2C, 0x00, 0xF0, 0x08, 0xE0, 0x33,
-0x00, 0x4F, 0x00, 0x7C, 0x01, 0xA2, 0x4D, 0xC0, 0x05, 0x20, 0xCF, 0x20, 0x5C,
-0x1B, 0xF2, 0x09, 0xE0, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x00, 0xF0, 0x09, 0xC0,
-0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x79, 0x00, 0xE3,
-0x01, 0xCC, 0x13, 0xF8, 0x8F, 0xC0, 0x7D, 0x04, 0x7F, 0x09, 0xCC, 0x06, 0xF0,
-0x9F, 0xC0, 0x7F, 0x02, 0xF7, 0x01, 0x3C, 0x24, 0x70, 0x9B, 0xC0, 0x47, 0x22,
-0xBF, 0x0D, 0xCC, 0x06, 0xB0, 0x9D, 0x41, 0x4F, 0x02, 0xBF, 0x01, 0xCD, 0x4F,
-0x30, 0x9E, 0xC8, 0x7C, 0x12, 0x3B, 0x09, 0xCC, 0x07, 0x34, 0x97, 0xD8, 0x18,
-0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x38, 0x00, 0xE1, 0x18,
-0x84, 0x03, 0xD8, 0x0E, 0x40, 0x38, 0x20, 0xED, 0x0C, 0xAC, 0x02, 0xD0, 0x0A,
-0x44, 0x33, 0x00, 0xCD, 0x08, 0xB4, 0x24, 0x10, 0xCA, 0x08, 0x7B, 0x01, 0x4D,
-0x98, 0x44, 0x43, 0x10, 0x5E, 0x40, 0x03, 0x03, 0xAD, 0x04, 0x94, 0x23, 0x10,
-0x0E, 0x42, 0x29, 0x03, 0x2D, 0x0C, 0xFC, 0x11, 0x10, 0x86, 0x40, 0x54, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7D, 0x00, 0xF1, 0x01, 0x84,
-0x27, 0xD0, 0xC8, 0x40, 0x79, 0x02, 0x7D, 0x00, 0xA6, 0x02, 0x50, 0x0A, 0x48,
-0x3B, 0x80, 0xED, 0x00, 0xF4, 0x00, 0xD0, 0x02, 0x0A, 0x09, 0x08, 0x3D, 0x06,
-0xA6, 0x22, 0x10, 0x0E, 0x44, 0x0B, 0x14, 0xBD, 0x00, 0xC6, 0x03, 0x10, 0x0E,
-0x40, 0x19, 0x10, 0x2D, 0x40, 0xC4, 0x02, 0x12, 0x06, 0x42, 0x60, 0x02, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x31, 0x00, 0xC1, 0x00, 0x04, 0x03,
-0xD8, 0x08, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x22, 0xD0, 0x00, 0x40, 0x33,
-0x00, 0xCD, 0x20, 0x34, 0x4C, 0x90, 0x00, 0x40, 0xB2, 0x01, 0x4D, 0x01, 0x24,
-0x85, 0x9A, 0x2D, 0x48, 0xC3, 0x00, 0x8D, 0x10, 0x14, 0x9B, 0x10, 0x28, 0x41,
-0x81, 0x00, 0x8D, 0x08, 0x05, 0x08, 0x10, 0xB8, 0x40, 0x08, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x35, 0x41, 0xD3, 0x01, 0x4D, 0x03, 0xD0,
-0x09, 0xC0, 0x35, 0x00, 0x5F, 0x00, 0x2C, 0x03, 0x70, 0x05, 0xC0, 0x77, 0x04,
-0xFF, 0x11, 0x7C, 0x1C, 0xF0, 0x01, 0xC0, 0x35, 0x08, 0xDF, 0x02, 0x6D, 0x09,
-0x34, 0x0F, 0xC0, 0xC7, 0x20, 0xCD, 0x81, 0xC4, 0x03, 0x30, 0x2D, 0xC0, 0x21,
-0x00, 0xDB, 0x2B, 0x44, 0x0B, 0x30, 0xB9, 0xC0, 0x74, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0xF0, 0x29,
-0xC0, 0x37, 0x00, 0x5F, 0x42, 0x7C, 0x4A, 0xF0, 0x05, 0xC0, 0x27, 0x91, 0xDF,
-0x24, 0x7C, 0x00, 0x70, 0x09, 0xC0, 0x37, 0x0A, 0xDF, 0x02, 0x5C, 0x42, 0x70,
-0xCD, 0xC0, 0x07, 0x04, 0x9F, 0x01, 0x6C, 0x03, 0xF0, 0x25, 0x40, 0x07, 0x01,
-0xDF, 0x02, 0x7C, 0x09, 0xF0, 0x29, 0xC8, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x08, 0x3F, 0x00, 0xFF, 0x00, 0xC8, 0x03, 0x30, 0x1B, 0xC0,
-0x3F, 0x20, 0x7F, 0x41, 0xFC, 0x27, 0x30, 0x46, 0xC0, 0x7E, 0x01, 0xFF, 0x20,
-0xCC, 0x0C, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0xBF, 0x08, 0xF8, 0x05, 0xB4, 0x0F,
-0xC0, 0x0D, 0x08, 0xFF, 0x00, 0xDC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x10, 0xE7,
-0x01, 0xCC, 0x46, 0xF0, 0x09, 0xC0, 0x07, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x85, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x54, 0x03, 0x50, 0x19, 0x40, 0x37,
-0x00, 0x1D, 0x02, 0x74, 0x0D, 0x10, 0x15, 0x40, 0x24, 0x00, 0xDD, 0x00, 0x44,
-0x0C, 0xD1, 0x19, 0xC0, 0x07, 0x01, 0x9D, 0x02, 0x74, 0x08, 0x90, 0x0D, 0x40,
-0xC4, 0x00, 0x9D, 0x03, 0x6C, 0x03, 0xD2, 0xF5, 0x40, 0x47, 0x00, 0x11, 0x01,
-0x44, 0x02, 0xD0, 0x39, 0x48, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0xA0, 0x34, 0x00, 0xCD, 0x00, 0x54, 0x03, 0x90, 0x8D, 0x41, 0x37, 0x00,
-0x5D, 0x08, 0x74, 0x43, 0x50, 0x0D, 0x40, 0x36, 0x00, 0xC9, 0x00, 0x44, 0xC0,
-0xD8, 0x11, 0x00, 0x07, 0x02, 0x9D, 0x02, 0x36, 0x18, 0x12, 0x0D, 0x40, 0x46,
-0x00, 0x9D, 0x03, 0x60, 0x03, 0xD0, 0x0D, 0x40, 0xE7, 0x00, 0x11, 0x04, 0x44,
-0x9B, 0xD0, 0x11, 0x4D, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x28, 0x30, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x04, 0x40, 0x32, 0x00, 0xCD,
-0x00, 0x34, 0x02, 0x56, 0x0C, 0x42, 0x20, 0x80, 0xCD, 0x00, 0x05, 0x10, 0xD0,
-0x18, 0x40, 0x31, 0x09, 0x4D, 0x20, 0x34, 0x22, 0x11, 0x6C, 0x50, 0x02, 0x02,
-0x8D, 0x00, 0x24, 0x03, 0xD2, 0x0C, 0x42, 0x03, 0x80, 0x01, 0x00, 0x04, 0x00,
-0xD0, 0x08, 0x4A, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0,
-0x3E, 0x08, 0xFF, 0x00, 0xDC, 0x03, 0x30, 0x0D, 0xC0, 0x3F, 0x00, 0x5F, 0x00,
-0x74, 0x03, 0x70, 0x09, 0xC0, 0x36, 0x10, 0xFB, 0x00, 0x4C, 0x50, 0x71, 0x01,
-0x64, 0x07, 0x00, 0x9F, 0x08, 0x7C, 0x00, 0xB0, 0x6F, 0xC0, 0x07, 0xA0, 0x9F,
-0x80, 0xDC, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x40, 0x47, 0x80, 0x4E, 0x01, 0xF2,
-0x01, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA0, 0x3F,
-0x00, 0xFF, 0x00, 0xFC, 0x03, 0x70, 0x07, 0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xFC,
-0x01, 0xB0, 0x03, 0xC0, 0x2F, 0x04, 0xFC, 0x10, 0xFC, 0x40, 0xF0, 0x03, 0xC0,
-0x8F, 0x08, 0x2F, 0x00, 0xFC, 0x10, 0xD2, 0x8F, 0xC0, 0x0D, 0x01, 0x2E, 0x00,
-0xBC, 0x03, 0xE0, 0x0F, 0xC2, 0x0F, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0, 0x0B,
-0xC2, 0x17, 0x64, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x3F, 0x00,
-0xA3, 0x40, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x11, 0xB3, 0x20, 0xFC, 0x26,
-0xB0, 0x9F, 0xD2, 0x2C, 0x00, 0xFF, 0x21, 0xEC, 0x10, 0xB2, 0x8F, 0xC8, 0x3C,
-0x12, 0xFF, 0x04, 0xEC, 0x20, 0x72, 0x0F, 0xC0, 0x7F, 0x02, 0xF3, 0x03, 0xED,
-0x1B, 0xB0, 0x9B, 0xC0, 0x7C, 0x0A, 0xDF, 0x01, 0xFC, 0x1A, 0x34, 0x49, 0xC0,
-0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3F, 0x00, 0xB1,
-0x01, 0x44, 0x82, 0x70, 0x01, 0x02, 0x3F, 0x22, 0x91, 0x00, 0x34, 0x13, 0x10,
-0x4C, 0x48, 0xB4, 0x01, 0xD1, 0x01, 0x54, 0x24, 0xD0, 0x6F, 0x60, 0xBC, 0x01,
-0xFD, 0x09, 0x44, 0x18, 0x10, 0x9F, 0x40, 0x33, 0x01, 0xD1, 0x00, 0x84, 0x1B,
-0x14, 0x48, 0x50, 0x34, 0x21, 0xDD, 0x04, 0x74, 0x12, 0x11, 0x19, 0x40, 0x0D,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x31, 0x00, 0x81, 0x00,
-0x04, 0x02, 0xD0, 0x08, 0x40, 0x33, 0x20, 0xC5, 0x20, 0x14, 0x07, 0x50, 0x0C,
-0x40, 0x81, 0x04, 0xC5, 0x00, 0x04, 0x00, 0xD0, 0x6C, 0x48, 0xB0, 0x01, 0xCD,
-0x00, 0x24, 0x1C, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xC1, 0x04, 0x04, 0x0B, 0x50,
-0x0D, 0x40, 0x30, 0x01, 0xCD, 0x14, 0x34, 0x18, 0x10, 0x81, 0x40, 0x5C, 0x80,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x37, 0x00, 0x91, 0x41, 0x44,
-0x0E, 0x52, 0x11, 0x45, 0x37, 0x10, 0xD5, 0x43, 0x74, 0x07, 0x50, 0x0D, 0x44,
-0x55, 0x00, 0xD5, 0x04, 0x56, 0x88, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0xDD, 0x00,
-0x24, 0x02, 0x13, 0x0D, 0x40, 0x37, 0x80, 0xC1, 0x01, 0x44, 0x03, 0x50, 0x0D,
-0x40, 0x34, 0x00, 0xDD, 0x80, 0x74, 0x06, 0x10, 0x11, 0x40, 0x1D, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0x93, 0x01, 0x4D, 0x04,
-0xF0, 0x11, 0xC4, 0x37, 0xC0, 0xD7, 0x03, 0x7C, 0x07, 0xF0, 0x8D, 0xC0, 0xC5,
-0x00, 0xDF, 0x01, 0x4C, 0x0C, 0xB2, 0x0D, 0x40, 0x34, 0x00, 0xDF, 0x00, 0x6C,
-0x01, 0x70, 0x0D, 0xC0, 0x77, 0x0A, 0xD3, 0x80, 0x6C, 0x03, 0xF0, 0x08, 0xC4,
-0x34, 0x00, 0xDF, 0x00, 0x7C, 0x0E, 0x30, 0x39, 0xC0, 0x82, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x3D, 0x10, 0xEF, 0x00, 0xFC, 0x80, 0x70,
-0x03, 0xC0, 0x3F, 0x00, 0xFB, 0x80, 0xF8, 0x03, 0xB4, 0x0F, 0xC0, 0x1A, 0x00,
-0xFB, 0x00, 0x5C, 0x22, 0xF0, 0x0F, 0xC2, 0x37, 0x30, 0xEF, 0x00, 0x5C, 0x0D,
-0xF3, 0x0F, 0xC0, 0x7F, 0x40, 0xFF, 0x80, 0xDC, 0x03, 0xB0, 0x0B, 0xC0, 0x3F,
-0x20, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x0F, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x0A, 0x93, 0x00, 0x4C, 0x0A, 0xF2, 0x69,
-0xC0, 0x33, 0x20, 0xDF, 0x02, 0x5D, 0x83, 0xF0, 0xCD, 0xC0, 0x84, 0x00, 0xD3,
-0x01, 0x7C, 0x09, 0x70, 0x0D, 0xC0, 0x34, 0x40, 0xD3, 0x84, 0x7C, 0x81, 0x30,
-0x8D, 0xC0, 0x35, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x34, 0x00,
-0xDB, 0x00, 0x7C, 0x08, 0xF0, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x13, 0xA0, 0xF8, 0x02, 0x51, 0x20, 0x44, 0x02, 0xD0, 0x09, 0x45,
-0x3F, 0x00, 0xDD, 0x01, 0x7C, 0x83, 0x10, 0x3D, 0x40, 0x14, 0x08, 0xC0, 0x20,
-0x74, 0x03, 0x12, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x00, 0x74, 0x83, 0x10, 0x1F,
-0x40, 0x34, 0x00, 0xD1, 0x00, 0xF4, 0x03, 0x10, 0x09, 0x40, 0x34, 0x80, 0xD1,
-0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x20, 0x30, 0x00, 0x81, 0x12, 0x04, 0x4C, 0xD9, 0x38, 0x40, 0x33,
-0x00, 0xCD, 0x09, 0x54, 0x03, 0x10, 0x2D, 0x40, 0x20, 0x08, 0xC1, 0x00, 0x34,
-0x07, 0x11, 0xAC, 0x48, 0xB1, 0x00, 0xC1, 0x01, 0x34, 0x82, 0x10, 0x1C, 0x41,
-0x36, 0x00, 0xC9, 0x20, 0x74, 0x03, 0x50, 0x08, 0x40, 0x30, 0x00, 0xC1, 0x00,
-0x74, 0x00, 0xD0, 0x01, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x00, 0x70, 0x00, 0xA1, 0x89, 0x84, 0x07, 0xD8, 0x1E, 0x40, 0x7B, 0x02,
-0xFD, 0x09, 0xB4, 0x07, 0x12, 0x1E, 0x40, 0x68, 0x00, 0xE1, 0x81, 0xB4, 0x07,
-0x10, 0x1E, 0x40, 0x79, 0x05, 0xE1, 0x11, 0xB4, 0x27, 0x10, 0x1C, 0x40, 0xFA,
-0x00, 0xE9, 0x81, 0xB4, 0x07, 0x10, 0x1A, 0x40, 0x78, 0x00, 0xE8, 0x0B, 0xB4,
-0x84, 0xD0, 0x1A, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x18, 0x30, 0x00, 0x83, 0x20, 0x0C, 0x41, 0xF0, 0x8C, 0xC4, 0x33, 0x20, 0x4F,
-0x00, 0x1D, 0x23, 0x70, 0x8C, 0xC0, 0x84, 0x40, 0xC3, 0x00, 0x3C, 0x43, 0x74,
-0x0D, 0xC0, 0x31, 0x00, 0xC3, 0x00, 0x3C, 0x00, 0x30, 0x0C, 0xD0, 0x33, 0x00,
-0xCA, 0x08, 0x3C, 0x03, 0x74, 0x0C, 0xD0, 0x34, 0x00, 0xC3, 0x1D, 0x3C, 0x08,
-0xF0, 0x70, 0xC8, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38,
-0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x04, 0x6F, 0x00,
-0xFC, 0xA3, 0x70, 0x0F, 0xE0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x2F,
-0xC1, 0x3E, 0x0D, 0xFF, 0x00, 0xFE, 0x03, 0xF2, 0x0F, 0xC0, 0x3D, 0x00, 0xF7,
-0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xF5, 0x28, 0xFC, 0x00, 0xF0,
-0x83, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
-0x01, 0xB3, 0x02, 0x4D, 0x01, 0xF0, 0x05, 0xC0, 0xB7, 0x00, 0xD3, 0x80, 0x6C,
-0x03, 0xF2, 0x0D, 0xC2, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0x30, 0x2D, 0xC0,
-0xB4, 0x04, 0xD3, 0x04, 0x7C, 0x86, 0x30, 0x6D, 0xC0, 0x77, 0x00, 0xD3, 0x40,
-0x7C, 0x53, 0xB0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x44, 0x82, 0xF0, 0x11,
-0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x3D, 0x05,
-0xE1, 0x10, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x3F, 0x04, 0xE5, 0x00, 0x84, 0x03,
-0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xED, 0xA0, 0x9C, 0x02, 0x10, 0x4F, 0x42, 0x3C,
-0x21, 0xE1, 0x0A, 0x9C, 0x03, 0x18, 0x8E, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4,
-0x0B, 0x10, 0x0A, 0x48, 0x3B, 0x00, 0xFD, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40,
-0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x42, 0x81,
-0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0x49, 0x01, 0xA4, 0x47, 0x50,
-0x1E, 0x40, 0x5B, 0x00, 0xED, 0x01, 0x14, 0x05, 0x14, 0x1E, 0x50, 0x7A, 0x40,
-0xE1, 0x21, 0x34, 0x04, 0xD0, 0x9E, 0x60, 0x7B, 0x40, 0xE1, 0x01, 0x34, 0x17,
-0x90, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x01, 0x84, 0x04, 0xD0, 0x10, 0x40, 0x02,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0x41, 0x0A,
-0x04, 0xC3, 0xC1, 0xBC, 0x44, 0x33, 0x00, 0x5D, 0x01, 0x04, 0x05, 0xD0, 0x08,
-0x40, 0x73, 0x0A, 0x8D, 0x20, 0x14, 0x0F, 0x10, 0x0C, 0x40, 0x32, 0x80, 0xC1,
-0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x23, 0x00, 0x81, 0x40, 0x34, 0x03, 0x12,
-0x89, 0x42, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x83, 0xD8, 0x1C, 0x40, 0x5A, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x00, 0x73, 0x03, 0xCC,
-0x0D, 0xE0, 0x07, 0xC0, 0x17, 0x00, 0x7B, 0x00, 0xEC, 0x05, 0xF0, 0x15, 0xC2,
-0x1F, 0x00, 0x5F, 0x05, 0xDC, 0x61, 0x30, 0x05, 0xC0, 0x16, 0x60, 0x53, 0x80,
-0xF4, 0x01, 0xF1, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x7C, 0x01, 0xB0, 0x05,
-0xC0, 0x17, 0x10, 0x5F, 0x00, 0xCC, 0x39, 0xF0, 0x37, 0xC0, 0x5E, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x81, 0x00, 0x0F, 0x04, 0x7C, 0x28,
-0xF1, 0x01, 0xC3, 0x07, 0x10, 0x17, 0x08, 0x7C, 0x04, 0xF0, 0xA1, 0xC0, 0x07,
-0x01, 0x1F, 0x00, 0x1C, 0x00, 0xF0, 0x20, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x5C,
-0x80, 0x34, 0x21, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x3C, 0x80, 0xF0, 0x01, 0xC0,
-0x07, 0x80, 0x1E, 0x02, 0x7C, 0x00, 0xF0, 0x81, 0xC1, 0x49, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x93, 0x08, 0x6C, 0x06, 0xF0,
-0x89, 0xC0, 0x63, 0x00, 0x93, 0x02, 0x4C, 0x02, 0x31, 0x09, 0xD0, 0x24, 0x00,
-0x9B, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xD0, 0x64, 0xC0, 0x93, 0x08, 0x7C, 0x02,
-0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x24,
-0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x20, 0x64, 0x40, 0x91, 0x00, 0x44, 0x6E, 0xD2, 0x29,
-0x40, 0x27, 0x02, 0x91, 0x03, 0x04, 0x02, 0x10, 0x39, 0x41, 0x24, 0x08, 0x91,
-0x20, 0x7C, 0x26, 0x11, 0x29, 0x40, 0x24, 0x02, 0x91, 0x02, 0x74, 0x02, 0xD0,
-0x79, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0x40, 0x24, 0x00,
-0x9D, 0x04, 0x74, 0x02, 0xD0, 0x09, 0x42, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x91, 0x00, 0x64, 0x02, 0xD0, 0x29, 0x40,
-0x27, 0x00, 0x91, 0x10, 0x44, 0x02, 0x10, 0x88, 0x48, 0x20, 0x00, 0x99, 0x04,
-0x74, 0x02, 0x10, 0x09, 0x40, 0x20, 0x00, 0x91, 0x10, 0x74, 0x02, 0x50, 0x49,
-0x40, 0x67, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x64, 0x00, 0x95,
-0x01, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x20, 0x20, 0x41, 0x81, 0x04, 0x04, 0x1A, 0x90, 0x08, 0x40, 0x23,
-0xC1, 0x81, 0x04, 0x45, 0x02, 0x18, 0x08, 0x40, 0x20, 0x01, 0x89, 0x00, 0x34,
-0x12, 0x10, 0x4C, 0x40, 0x20, 0x01, 0x81, 0x04, 0x34, 0x12, 0xD0, 0x48, 0x40,
-0x23, 0x00, 0x8D, 0x00, 0x34, 0x22, 0x90, 0x08, 0x54, 0x20, 0x00, 0x8D, 0x00,
-0x34, 0x12, 0xD0, 0x48, 0x60, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1D, 0xB8, 0x96, 0x02, 0x13, 0x00, 0x6C, 0x08, 0xF0, 0x81, 0x44, 0x87, 0x02,
-0x13, 0x0A, 0x4C, 0x28, 0x30, 0xA1, 0xC0, 0x84, 0x02, 0x1B, 0x00, 0x7C, 0x00,
-0x30, 0xA1, 0x42, 0x84, 0x02, 0x11, 0x00, 0x7C, 0xA8, 0xF0, 0x01, 0xC0, 0x83,
-0x12, 0x1F, 0x0A, 0x7C, 0x58, 0x70, 0xA1, 0xC0, 0x84, 0x02, 0x17, 0x0A, 0x7C,
-0x28, 0xF0, 0x01, 0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xB0, 0x27, 0x02, 0xBF, 0x08, 0xF4, 0x0A, 0xF0, 0x8B, 0xC0, 0x27, 0x02, 0xFF,
-0x08, 0xFC, 0x02, 0xF4, 0x0B, 0xC2, 0x2F, 0x02, 0xB7, 0x00, 0xDC, 0x22, 0xF0,
-0x89, 0xC8, 0x27, 0x02, 0x9F, 0x08, 0xFC, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x08,
-0xBF, 0x00, 0x5C, 0x92, 0x70, 0x0B, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0x22,
-0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0,
-0x2F, 0x05, 0xB3, 0x84, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x04,
-0x5C, 0x02, 0x30, 0x8B, 0xE0, 0x25, 0x00, 0xB7, 0x00, 0xDC, 0x02, 0xF0, 0x4B,
-0xC0, 0x2F, 0x05, 0xBF, 0x04, 0x4C, 0x03, 0xF4, 0x0B, 0xC0, 0x2F, 0x02, 0xDF,
-0x00, 0x4C, 0x52, 0xB0, 0x89, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xE2,
-0x09, 0x00, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07,
-0x01, 0x11, 0x88, 0x74, 0x49, 0xD0, 0x05, 0x41, 0x07, 0x02, 0x15, 0x14, 0x44,
-0x90, 0x11, 0x41, 0x42, 0x87, 0x44, 0x11, 0x00, 0x74, 0x20, 0x72, 0x41, 0xC1,
-0x05, 0x01, 0x1C, 0x08, 0x54, 0x49, 0x10, 0x01, 0x44, 0x07, 0x00, 0x1D, 0x14,
-0x54, 0x10, 0x70, 0x41, 0x40, 0x07, 0x24, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01,
-0x42, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x20, 0x05,
-0x81, 0x00, 0x34, 0x32, 0xD0, 0x88, 0x40, 0x23, 0x20, 0x81, 0x2C, 0x44, 0x56,
-0x04, 0x48, 0x40, 0x25, 0x43, 0x85, 0x40, 0x14, 0x02, 0xD0, 0xC8, 0x40, 0x23,
-0x25, 0xCD, 0x00, 0x24, 0x32, 0x10, 0x88, 0x40, 0x33, 0x00, 0x9D, 0x04, 0x04,
-0x52, 0x90, 0x48, 0x44, 0x23, 0x01, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40,
-0x4B, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91,
-0x01, 0x74, 0x83, 0xD0, 0x89, 0x40, 0x23, 0x00, 0x95, 0x00, 0x44, 0x02, 0x10,
-0x19, 0x40, 0xA7, 0xC0, 0x91, 0x01, 0x74, 0x06, 0x50, 0x09, 0x00, 0x27, 0x08,
-0x99, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x50, 0x02,
-0x58, 0x09, 0x40, 0x27, 0x08, 0x9D, 0x00, 0x74, 0x12, 0xD0, 0x09, 0x43, 0x63,
-0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x24, 0x40, 0x93, 0x05,
-0x7C, 0x0E, 0xF0, 0x39, 0xC0, 0x27, 0x00, 0x93, 0x03, 0x1D, 0x02, 0x10, 0x09,
-0xC8, 0x25, 0x40, 0x97, 0x20, 0x5C, 0x02, 0xF3, 0x09, 0xC0, 0x27, 0x10, 0x9F,
-0x00, 0x6C, 0x02, 0x70, 0x09, 0xC0, 0x67, 0x20, 0x8F, 0x01, 0x49, 0x02, 0xB0,
-0x19, 0xC8, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x16, 0xF0, 0x29, 0xC0, 0x17, 0x08,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x21, 0x10, 0x9F, 0x20, 0x7C,
-0x12, 0xF0, 0x09, 0xC1, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x26, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x25, 0x04, 0x9F, 0x00,
-0x5C, 0x02, 0x70, 0x09, 0xC1, 0x27, 0x01, 0x9F, 0x84, 0x6C, 0x02, 0xB0, 0x59,
-0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0x5B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x04, 0x7E, 0x68,
-0xB4, 0x21, 0xD0, 0x04, 0x08, 0x1D, 0x02, 0x6C, 0x00, 0xF0, 0x01, 0xC8, 0x07,
-0x00, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x81, 0xC0, 0x07, 0x40, 0x13, 0x00, 0x5C,
-0x08, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0,
-0x07, 0x00, 0x1F, 0x0C, 0x7C, 0x08, 0x30, 0x21, 0xC2, 0x53, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x40, 0x71, 0x01, 0xE4, 0x0D, 0x30,
-0x07, 0x41, 0x14, 0x00, 0x7D, 0x0D, 0x44, 0x01, 0x70, 0x07, 0xC0, 0x11, 0x00,
-0x5D, 0x00, 0x76, 0x05, 0x90, 0x07, 0x40, 0x9F, 0x08, 0x61, 0x02, 0x44, 0x01,
-0x70, 0x17, 0xC8, 0x9E, 0x02, 0x5D, 0x00, 0x74, 0x01, 0x52, 0x05, 0x40, 0x17,
-0x01, 0x7D, 0x03, 0x74, 0x01, 0x10, 0x05, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA0, 0x72, 0x00, 0x81, 0x09, 0x24, 0x0B, 0x50, 0x2C,
-0x42, 0x30, 0x00, 0xDD, 0x03, 0x24, 0x03, 0xD0, 0x9C, 0x40, 0x33, 0x00, 0x8D,
-0x01, 0x34, 0x22, 0xD0, 0x1C, 0x40, 0x33, 0x00, 0xC1, 0x10, 0x54, 0x83, 0x50,
-0xB4, 0x40, 0x30, 0x00, 0xCD, 0x40, 0x74, 0x03, 0x10, 0x0C, 0x40, 0x72, 0x00,
-0xCD, 0x81, 0x36, 0x83, 0x10, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x80, 0x20, 0x05, 0xA1, 0x00, 0xA4, 0x07, 0x50, 0x1E, 0x60,
-0x38, 0x00, 0xAD, 0x04, 0x84, 0x13, 0xD0, 0x0E, 0x48, 0x3B, 0x00, 0xED, 0x80,
-0xB4, 0x03, 0x90, 0x0E, 0x44, 0x6B, 0x10, 0x21, 0x40, 0x84, 0x23, 0x40, 0x1E,
-0x40, 0x3A, 0x00, 0xED, 0x08, 0xB4, 0x13, 0x50, 0x4E, 0x40, 0x3B, 0x10, 0xAC,
-0x00, 0x34, 0x27, 0x10, 0x0E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x18, 0xE8, 0x00, 0xA1, 0x01, 0xF4, 0x07, 0x70, 0x17, 0xC0, 0x78,
-0x00, 0xEF, 0x03, 0xAC, 0x27, 0xF0, 0x1E, 0xC0, 0x7B, 0x22, 0xED, 0x01, 0xB6,
-0x07, 0xF0, 0x16, 0x82, 0x73, 0x00, 0x03, 0x01, 0x9C, 0x17, 0x60, 0x1E, 0xC0,
-0x78, 0x08, 0xEF, 0x89, 0x3C, 0x17, 0x38, 0xDE, 0xC8, 0x7B, 0x00, 0xAF, 0x01,
-0xBC, 0x27, 0x30, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xB8, 0x05, 0x00, 0x9F, 0x00, 0x74, 0x03, 0x30, 0x05, 0xC0, 0x37, 0x08,
-0x8F, 0x00, 0x7C, 0x03, 0x70, 0x01, 0xC0, 0x35, 0x03, 0xDF, 0x00, 0x7C, 0x83,
-0xB1, 0x0D, 0xC0, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x9B, 0x51, 0x0C, 0xC0, 0x37,
-0x00, 0xDF, 0x02, 0x7C, 0x4B, 0x70, 0x8D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C,
-0x03, 0xF2, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-0x20, 0x6D, 0x00, 0xF3, 0x01, 0xCC, 0x11, 0xB0, 0x1F, 0xC0, 0xFF, 0x00, 0xFF,
-0x01, 0xCC, 0x47, 0xF0, 0x1B, 0xC0, 0x7F, 0x00, 0xFF, 0x01, 0xBC, 0x07, 0x30,
-0x9F, 0xE0, 0x5C, 0x00, 0x3F, 0x01, 0xF8, 0x2F, 0x38, 0x1F, 0xC8, 0x6E, 0x28,
-0xF3, 0x81, 0xFC, 0x47, 0xFA, 0x9F, 0xC8, 0x6F, 0x00, 0x33, 0x21, 0x7C, 0x27,
-0x30, 0x9F, 0xC4, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00,
-0x29, 0x20, 0xE1, 0x08, 0x84, 0x21, 0x31, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00,
-0x84, 0x03, 0xD0, 0x0A, 0x40, 0x3B, 0x14, 0xED, 0x80, 0x9C, 0x23, 0x70, 0x8A,
-0xC0, 0x28, 0x01, 0x2D, 0x20, 0x9C, 0x03, 0x30, 0x4E, 0x40, 0x0C, 0x12, 0xE1,
-0x18, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x2F, 0x30, 0x01, 0x00, 0xB4, 0x07, 0xB0,
-0x0C, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
-0x00, 0xA1, 0x00, 0x84, 0x01, 0x10, 0x0E, 0x41, 0x3B, 0x00, 0x6D, 0x00, 0x84,
-0x0B, 0x50, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0x10, 0x06, 0x70,
-0x18, 0x10, 0x2D, 0x00, 0x14, 0x43, 0x1D, 0x0E, 0x40, 0x28, 0x44, 0xE5, 0x00,
-0xB4, 0x03, 0xD0, 0x0E, 0x44, 0x2B, 0x02, 0xA9, 0x00, 0xB4, 0x03, 0x10, 0x0E,
-0x40, 0x23, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00,
-0x81, 0x06, 0x05, 0x80, 0x10, 0x08, 0x40, 0x37, 0x00, 0x4D, 0x00, 0x04, 0x87,
-0xD0, 0x00, 0x46, 0x73, 0x08, 0xCD, 0x00, 0x14, 0x93, 0x51, 0x08, 0x40, 0x20,
-0x08, 0x0D, 0x00, 0x14, 0x03, 0x10, 0x0C, 0x40, 0x40, 0x10, 0xD5, 0x80, 0x34,
-0x03, 0x50, 0x0C, 0x60, 0x23, 0x00, 0x89, 0x20, 0x76, 0x13, 0x1C, 0xED, 0x48,
-0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x2D, 0x40, 0x93,
-0x00, 0x44, 0x06, 0x30, 0x09, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xCD, 0x07, 0xF0,
-0x05, 0xC0, 0xFF, 0x02, 0xDF, 0x00, 0x7C, 0x0B, 0x30, 0x09, 0xC4, 0x34, 0x00,
-0x1F, 0x00, 0xDC, 0x07, 0x30, 0x0D, 0xD0, 0x54, 0x00, 0xF7, 0x01, 0xFC, 0x03,
-0xF0, 0x0F, 0xC0, 0x37, 0x40, 0x1B, 0x00, 0xFC, 0x03, 0x10, 0x3D, 0xC4, 0x77,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x00, 0x0F, 0x01,
-0x7C, 0x68, 0x70, 0x29, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x23, 0xF0, 0x1D,
-0xC8, 0x37, 0x00, 0xDF, 0x01, 0x1C, 0x03, 0x72, 0x25, 0xC0, 0x95, 0x00, 0x1F,
-0x82, 0x1C, 0x03, 0x70, 0x0D, 0xC0, 0x17, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0x70,
-0x0D, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x87, 0xF0, 0x0D, 0xC4, 0x17, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x00, 0x93, 0x00, 0x4C,
-0x02, 0xF0, 0x02, 0xC1, 0x3C, 0x00, 0xF3, 0x02, 0xCC, 0x03, 0xF0, 0x07, 0xC0,
-0x3C, 0x00, 0xFF, 0x03, 0xCC, 0x03, 0x30, 0x82, 0xC0, 0x6C, 0x40, 0x33, 0x00,
-0xFC, 0x43, 0x30, 0x0D, 0xC0, 0x4F, 0x00, 0xF3, 0x00, 0x8D, 0x03, 0x30, 0x0F,
-0xC0, 0x6F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x30, 0x0F, 0xD0, 0x04, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x46, 0x02, 0x11, 0x02, 0x54, 0x06,
-0x90, 0x71, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44, 0x03, 0xD0, 0x20, 0x40, 0x34,
-0x00, 0xCD, 0x00, 0x6C, 0x03, 0x10, 0x25, 0x41, 0x84, 0x06, 0x11, 0x01, 0x74,
-0x03, 0x10, 0x1D, 0xC0, 0x41, 0x00, 0xD1, 0x00, 0x44, 0x03, 0x50, 0x0D, 0x40,
-0x67, 0x00, 0x9D, 0x05, 0x74, 0x03, 0x10, 0x0D, 0xC2, 0x06, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x22, 0x00, 0xD1, 0x02, 0x44, 0x06, 0xD0,
-0x11, 0x40, 0x64, 0x00, 0x81, 0x00, 0x44, 0x03, 0xD8, 0x21, 0x40, 0x34, 0x00,
-0xDD, 0x00, 0x44, 0x07, 0x10, 0x09, 0x40, 0x10, 0x80, 0x11, 0x03, 0x74, 0x03,
-0x90, 0x1D, 0x41, 0x37, 0x01, 0xD1, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37,
-0x01, 0x1D, 0x01, 0x74, 0x03, 0x14, 0x0D, 0x44, 0x04, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC1, 0x00, 0x14, 0x00, 0x98, 0x08,
-0x40, 0x20, 0x00, 0x81, 0x80, 0x05, 0x03, 0xD0, 0x09, 0x40, 0x30, 0x00, 0xDD,
-0x00, 0x24, 0x03, 0x14, 0x00, 0x50, 0x10, 0x00, 0x01, 0x00, 0x34, 0x03, 0x90,
-0x0C, 0x40, 0x57, 0x00, 0xC1, 0x00, 0x04, 0x03, 0x50, 0x0C, 0x40, 0x33, 0x80,
-0x0D, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x4C, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x98, 0x22, 0x40, 0x93, 0x00, 0x4C, 0x02, 0xF1, 0x01, 0x50,
-0x3C, 0x00, 0x43, 0x00, 0xCC, 0x03, 0xF0, 0x05, 0xD0, 0x3C, 0x00, 0xDF, 0x00,
-0x44, 0x03, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x13, 0x00, 0xFC, 0x03, 0xB0, 0x0D,
-0xC0, 0x27, 0x40, 0xF3, 0x00, 0xC4, 0x03, 0x30, 0x0F, 0xC0, 0x27, 0x00, 0x1F,
-0x02, 0xBC, 0x13, 0x30, 0xAD, 0xC2, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0xB0, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF8, 0x0B, 0xC0, 0x3F,
-0x00, 0x7F, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0x40, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
-0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x74, 0x0B, 0xE0,
-0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC8, 0x2F, 0x30, 0xBF, 0x04,
-0x7C, 0x0B, 0xF0, 0x4F, 0xC0, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA0, 0x7F, 0x00, 0x7E, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0x44, 0x3C, 0x05,
-0xF7, 0x00, 0xEC, 0x23, 0xB0, 0x4F, 0xC0, 0x49, 0x00, 0x37, 0x03, 0xFC, 0x03,
-0x32, 0x2F, 0x40, 0x3D, 0x02, 0x23, 0x03, 0xDC, 0x24, 0x78, 0x93, 0xC0, 0x48,
-0x00, 0x23, 0x01, 0xE4, 0x03, 0xB0, 0x17, 0xC0, 0x4C, 0x00, 0xFF, 0x21, 0xCC,
-0x06, 0xE0, 0x03, 0xC0, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x08, 0x7F, 0x00, 0xDD, 0x01, 0xF4, 0x07, 0x10, 0x1F, 0x40, 0xF4, 0x00, 0xF1,
-0x03, 0x84, 0x3B, 0x10, 0x9D, 0xC0, 0x64, 0x00, 0x1D, 0x00, 0xF4, 0x2F, 0x14,
-0x6F, 0x44, 0xBC, 0x03, 0x11, 0x84, 0x4C, 0x00, 0xD0, 0x41, 0xC0, 0x54, 0x48,
-0x51, 0x01, 0x44, 0x2F, 0x10, 0x11, 0x50, 0x44, 0x00, 0xFD, 0xA1, 0x44, 0x04,
-0xD1, 0x09, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
-0x33, 0x00, 0x0D, 0x40, 0x34, 0x03, 0x91, 0x0C, 0x40, 0x30, 0x00, 0xC5, 0x22,
-0x24, 0x13, 0x91, 0x0C, 0x40, 0x01, 0x08, 0x0D, 0x84, 0x34, 0x03, 0x90, 0x2C,
-0x40, 0x31, 0x21, 0x01, 0xC0, 0x14, 0x14, 0x50, 0x01, 0x40, 0x32, 0x20, 0x91,
-0x00, 0x04, 0x03, 0x90, 0x0D, 0x40, 0x02, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD0,
-0x01, 0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35,
-0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40, 0x34, 0x00, 0xD1, 0x60, 0x44,
-0x03, 0x10, 0x0D, 0x40, 0x64, 0x24, 0x1D, 0x01, 0x74, 0x03, 0x92, 0x0D, 0x40,
-0x32, 0x88, 0x01, 0x01, 0x54, 0x04, 0xC0, 0x19, 0x50, 0x94, 0x01, 0x90, 0x08,
-0x44, 0x03, 0xD0, 0x09, 0x40, 0x46, 0x04, 0xDD, 0x00, 0x44, 0x46, 0xD1, 0x31,
-0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00,
-0x9F, 0x04, 0x3C, 0x03, 0x94, 0x0C, 0xD0, 0x34, 0x10, 0xD7, 0x00, 0x6C, 0x03,
-0xB0, 0x0D, 0xC8, 0x45, 0x10, 0x9F, 0x03, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x35,
-0x00, 0x13, 0x11, 0x5C, 0x04, 0x71, 0x30, 0xC0, 0x26, 0x00, 0x13, 0x83, 0x6C,
-0x03, 0xB0, 0x48, 0xC0, 0xC6, 0x00, 0xCF, 0x00, 0x4D, 0x0E, 0xF0, 0x31, 0xD0,
-0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x3D, 0x00, 0xBF,
-0x00, 0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x3B, 0x00, 0xED, 0x40, 0xFC, 0x83, 0xF0,
-0x0E, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x70, 0x0E, 0xC4, 0x3D, 0x00,
-0xBF, 0x00, 0xEC, 0x02, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x7F, 0x00, 0x3C, 0x03,
-0x10, 0x4B, 0xC0, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x09, 0xC0, 0x1E,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x20, 0x9F, 0x00,
-0x7C, 0x03, 0xF0, 0x4D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x83, 0x70, 0x0D,
-0xC0, 0x07, 0x00, 0x93, 0x02, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x34, 0x00, 0x9F,
-0x02, 0x5C, 0x02, 0xF0, 0x29, 0xC2, 0xA7, 0x01, 0x93, 0x06, 0x7C, 0x47, 0x30,
-0x49, 0xC0, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC4, 0x08, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x20, 0x9D, 0x80, 0x74,
-0x03, 0xD0, 0x4D, 0x60, 0x3F, 0x00, 0xFD, 0x00, 0xC4, 0x83, 0x10, 0x0F, 0x44,
-0xA7, 0x1A, 0x91, 0x00, 0xBC, 0x13, 0xD0, 0x0F, 0x40, 0x3C, 0x00, 0x9D, 0x00,
-0x44, 0x02, 0xD0, 0x19, 0x40, 0x83, 0x01, 0xC1, 0x51, 0xC4, 0x0B, 0x50, 0x09,
-0x40, 0x87, 0x00, 0xDC, 0x00, 0x74, 0x0A, 0xD0, 0x99, 0x40, 0x6D, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x13,
-0xD0, 0x2C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x54, 0x03, 0x58, 0x0C, 0x41, 0x23,
-0x00, 0x81, 0x00, 0x34, 0x13, 0x90, 0x0C, 0x44, 0x30, 0x00, 0x0D, 0x80, 0x14,
-0x00, 0xD1, 0x00, 0x40, 0x82, 0x08, 0xC5, 0x63, 0x14, 0x03, 0x10, 0x3C, 0x40,
-0xC3, 0x03, 0xCD, 0x00, 0x34, 0x16, 0xD0, 0x19, 0x40, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x0D, 0x80, 0x78, 0x00, 0xED, 0x81, 0xB4, 0x27, 0xD0,
-0x1E, 0x40, 0x7B, 0x00, 0xCD, 0x89, 0x84, 0x07, 0x18, 0x1E, 0x40, 0x6F, 0x01,
-0x21, 0x01, 0xB4, 0x07, 0xC0, 0x1C, 0x48, 0x78, 0x00, 0xBD, 0x41, 0x84, 0x07,
-0xD0, 0x1A, 0x41, 0x5F, 0x00, 0xE5, 0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x4B,
-0x01, 0xED, 0x21, 0xB4, 0x04, 0xD0, 0x5A, 0x40, 0x3D, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0x8F, 0x08, 0x3C, 0x03, 0xF0, 0x8C,
-0x40, 0x33, 0x00, 0xCF, 0x00, 0x1C, 0x23, 0x70, 0x1C, 0xC0, 0x63, 0x21, 0x83,
-0x02, 0x3E, 0x03, 0xB0, 0x8C, 0xC0, 0x30, 0x00, 0xCF, 0x08, 0x1C, 0x02, 0xF0,
-0x04, 0xC0, 0x33, 0x01, 0x87, 0x04, 0x1C, 0x23, 0x38, 0x0C, 0xC1, 0x03, 0x02,
-0xCF, 0x00, 0x3C, 0xE3, 0xF0, 0x00, 0xC1, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0xB8, 0x7D, 0x00, 0xFF, 0x00, 0xFC, 0x87, 0xF0, 0x9F, 0xC0,
-0x3F, 0x00, 0xFF, 0x50, 0xFC, 0x03, 0xF2, 0x8F, 0xC0, 0x2F, 0x42, 0xBF, 0x08,
-0xDC, 0x03, 0xF8, 0x0F, 0xC2, 0x3F, 0x94, 0xFF, 0x40, 0xFC, 0x23, 0xF0, 0x8D,
-0x40, 0x3F, 0x40, 0xBB, 0x00, 0x5C, 0x63, 0xF0, 0x0F, 0xC8, 0x0F, 0x03, 0xFF,
-0x01, 0xFC, 0x03, 0xF0, 0x43, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0xA0, 0x37, 0x80, 0x9E, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x37,
-0x02, 0xDF, 0x11, 0x4C, 0x53, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F, 0x20, 0x4C,
-0x03, 0xF0, 0x4D, 0xC0, 0xF7, 0x01, 0x5B, 0x00, 0x7C, 0x01, 0x72, 0x1D, 0xC0,
-0x24, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x08, 0xC0, 0x44, 0xC0, 0xDB, 0x01,
-0x4C, 0x01, 0xD0, 0x1D, 0x40, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x13, 0x88, 0x39, 0x01, 0xAD, 0x00, 0x34, 0x8B, 0x10, 0x2E, 0x48, 0x3B, 0x31,
-0xED, 0x04, 0xAC, 0x03, 0xD0, 0x2E, 0x40, 0x0B, 0x28, 0x3D, 0x00, 0x84, 0x3B,
-0xD0, 0xAE, 0xC0, 0x39, 0x0A, 0xE1, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x00, 0x38,
-0x00, 0xED, 0x80, 0x84, 0x13, 0xD2, 0x0A, 0x40, 0x08, 0x00, 0xC5, 0x02, 0x94,
-0x01, 0xD0, 0x0F, 0x40, 0x4C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x00, 0x79, 0x02, 0xA5, 0x43, 0xB4, 0x17, 0x10, 0x5E, 0x40, 0x7B, 0x00, 0xED,
-0x01, 0x84, 0x27, 0x58, 0x5E, 0x44, 0x6B, 0x10, 0xAD, 0x11, 0x85, 0x07, 0xD0,
-0x1E, 0x46, 0x73, 0x01, 0xE9, 0x91, 0xB4, 0x87, 0x42, 0x1E, 0x40, 0x7A, 0x00,
-0xFD, 0x01, 0x94, 0x07, 0xD0, 0x0A, 0x41, 0xC8, 0x40, 0xED, 0x05, 0x84, 0x05,
-0xD0, 0x1A, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28,
-0x33, 0x00, 0x8D, 0x00, 0x34, 0x03, 0x14, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00,
-0x24, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x02, 0xCD, 0x03, 0x44, 0x03, 0xD0, 0x0C,
-0x40, 0x31, 0x00, 0xC9, 0x01, 0x34, 0x17, 0xD0, 0x5C, 0x42, 0xF2, 0x00, 0xCD,
-0x80, 0x04, 0x03, 0xD0, 0x38, 0x40, 0x70, 0x41, 0xCD, 0x40, 0x14, 0x63, 0xD0,
-0x3C, 0x49, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15,
-0x00, 0x7F, 0x00, 0x3C, 0x01, 0xB0, 0x04, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C,
-0x01, 0xF0, 0x04, 0xC0, 0x9F, 0x00, 0x7F, 0x01, 0x44, 0x01, 0xF0, 0x05, 0xC4,
-0x17, 0x00, 0x7B, 0x02, 0xF4, 0x15, 0x70, 0x17, 0xD0, 0x9A, 0x10, 0x7F, 0x10,
-0x5C, 0x01, 0xF0, 0x07, 0xC0, 0x1C, 0x00, 0x5F, 0x00, 0xCC, 0x05, 0xF0, 0x57,
-0xD0, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00,
-0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x3C, 0x00,
-0xF0, 0x01, 0xC4, 0x07, 0x00, 0x1D, 0x00, 0x7C, 0x88, 0xF0, 0x01, 0xC0, 0x05,
-0x00, 0x17, 0x10, 0x7C, 0x00, 0xF0, 0x81, 0xC0, 0x05, 0x02, 0x1F, 0x00, 0x75,
-0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x17, 0x80, 0x7C, 0x08, 0xF0, 0x01, 0xC0,
-0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F,
-0x00, 0x4C, 0x12, 0x30, 0x29, 0xC2, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30,
-0x49, 0xC0, 0x24, 0x06, 0x9F, 0x10, 0x4C, 0x22, 0x30, 0x09, 0xE0, 0x27, 0x00,
-0x97, 0x00, 0x7C, 0x02, 0x32, 0x59, 0xC0, 0x27, 0x26, 0x93, 0x80, 0x7D, 0x0A,
-0xF0, 0x19, 0xC1, 0x67, 0x02, 0x9F, 0x02, 0x7C, 0x02, 0x30, 0x59, 0xC0, 0x43,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x2E, 0x00, 0x8D, 0x00,
-0xC4, 0x1E, 0x10, 0x2B, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x79,
-0x40, 0x65, 0x00, 0x9D, 0x80, 0x68, 0x06, 0x50, 0x09, 0x60, 0x27, 0x00, 0x9D,
-0x00, 0x5C, 0x02, 0xB1, 0x39, 0xC2, 0xE7, 0x00, 0x81, 0x82, 0x6C, 0x1A, 0xD0,
-0x89, 0xC0, 0x25, 0x00, 0xBD, 0x03, 0x34, 0x1A, 0x12, 0x49, 0x40, 0x07, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x20, 0x9D, 0x40, 0x44,
-0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x18, 0x09, 0x42,
-0x24, 0x00, 0x8D, 0x00, 0x44, 0x82, 0x12, 0x09, 0x40, 0x27, 0x00, 0x95, 0x60,
-0x34, 0x02, 0x58, 0x2D, 0x40, 0xA7, 0x80, 0xD1, 0x98, 0x64, 0x02, 0xD0, 0x09,
-0x40, 0x27, 0x00, 0x9D, 0x40, 0x74, 0x22, 0x14, 0x09, 0x40, 0x63, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x9D, 0x02, 0x04, 0x02,
-0x10, 0x08, 0x40, 0xA0, 0x00, 0x8D, 0x06, 0x34, 0x02, 0x10, 0x08, 0x40, 0x21,
-0x00, 0x8D, 0x08, 0x45, 0x83, 0x5A, 0x88, 0x60, 0x23, 0x82, 0x8D, 0x08, 0x34,
-0x22, 0xD0, 0x88, 0x40, 0x27, 0x00, 0x81, 0x00, 0x24, 0x02, 0xD0, 0x08, 0x40,
-0x31, 0x80, 0xCD, 0x00, 0x74, 0x02, 0x10, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x46, 0x00, 0x1F, 0x00, 0x4D, 0x04, 0x34,
-0x11, 0x50, 0x04, 0x05, 0x0F, 0x00, 0x7C, 0x78, 0x30, 0x41, 0x41, 0x04, 0x00,
-0x1D, 0x02, 0x44, 0x50, 0x31, 0x61, 0x41, 0x87, 0x05, 0x17, 0x42, 0x74, 0x08,
-0x74, 0x20, 0xC0, 0x07, 0x00, 0x13, 0x40, 0x6C, 0x50, 0xF0, 0x01, 0xC0, 0x07,
-0x00, 0x1F, 0x81, 0x7C, 0x00, 0x30, 0xA1, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00, 0xBF, 0x01, 0x7C, 0x0A, 0xF1, 0x29,
-0xC0, 0x67, 0x00, 0x9F, 0x09, 0x7C, 0x82, 0xF4, 0x09, 0xC0, 0x2F, 0x20, 0xBF,
-0x04, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0xFF, 0x24, 0xDC, 0x12, 0x00,
-0x4B, 0xC0, 0x2D, 0x40, 0xAF, 0x00, 0x6C, 0x02, 0xF0, 0x0B, 0xC8, 0x39, 0x00,
-0x9F, 0x22, 0xFC, 0x03, 0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x67, 0x01, 0x93, 0x02, 0xCC, 0x06, 0xF0, 0x1B, 0xC0,
-0x25, 0x02, 0x9B, 0xE0, 0x7C, 0x12, 0xF0, 0x4B, 0xC5, 0x2F, 0x00, 0x93, 0x00,
-0xDC, 0x02, 0x38, 0x89, 0xC0, 0x27, 0x49, 0x93, 0x00, 0x5E, 0x22, 0x30, 0x0B,
-0x40, 0x2C, 0x00, 0xA3, 0x00, 0xCC, 0x12, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xBB,
-0x11, 0xFC, 0x82, 0xE0, 0x0B, 0xD0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1C, 0x08, 0x07, 0x08, 0x0B, 0x01, 0x45, 0x00, 0xD0, 0x01, 0x46, 0x47,
-0x01, 0x1D, 0x9D, 0x74, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x11, 0x10, 0x5C,
-0x00, 0x14, 0x81, 0x00, 0x07, 0x25, 0x11, 0x04, 0x5C, 0x10, 0x10, 0x01, 0x51,
-0x04, 0x20, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x05, 0x48, 0x07, 0x10, 0x13, 0x42,
-0x74, 0x00, 0xD0, 0x05, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0xA0, 0xA3, 0x00, 0x81, 0x00, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x23, 0x02,
-0x8D, 0x00, 0x34, 0x32, 0xD0, 0x08, 0x40, 0x21, 0x00, 0x81, 0x04, 0x14, 0x22,
-0x90, 0x08, 0x44, 0x23, 0x03, 0x89, 0x14, 0x54, 0x12, 0x18, 0x48, 0x40, 0x22,
-0x40, 0x81, 0x00, 0x04, 0x22, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x89, 0x00, 0x34,
-0x02, 0xD1, 0x08, 0x40, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x88, 0x25, 0x00, 0x89, 0x04, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0x9D,
-0x80, 0x74, 0x02, 0xD0, 0x09, 0x00, 0xA7, 0x42, 0x91, 0x02, 0x54, 0x02, 0x98,
-0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x54, 0x02, 0x10, 0x0C, 0x40, 0x26, 0x20,
-0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x91, 0x00, 0x74, 0x02,
-0xD0, 0x0D, 0x40, 0x60, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28,
-0x25, 0x00, 0xB3, 0x81, 0x4C, 0x02, 0xF0, 0x09, 0xC8, 0x2F, 0x08, 0xBB, 0x80,
-0x7C, 0x02, 0xF1, 0x09, 0x80, 0x65, 0x00, 0x93, 0x00, 0x1C, 0x02, 0x90, 0x09,
-0x48, 0x27, 0x00, 0x9B, 0x03, 0x1C, 0x1A, 0x30, 0x59, 0xC0, 0x22, 0x01, 0x83,
-0xA7, 0x4C, 0x02, 0xD0, 0x29, 0xC4, 0x67, 0x00, 0x9B, 0x80, 0x7C, 0x2A, 0xF0,
-0x29, 0xC0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x25,
-0x00, 0x9F, 0x01, 0x70, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x80, 0x9C, 0xA0, 0x7C,
-0x82, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x03, 0x7E, 0x02, 0x50, 0x09, 0xC4,
-0x27, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0xF4, 0x49, 0xE0, 0x65, 0x01, 0x9C, 0x44,
-0x5C, 0x42, 0xF0, 0x09, 0x00, 0x67, 0x04, 0x9F, 0x20, 0x7E, 0x06, 0xD0, 0x58,
-0xC1, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x00,
-0x1F, 0x00, 0x5C, 0x40, 0xF0, 0x01, 0xE0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00,
-0x31, 0x01, 0xE0, 0x06, 0x11, 0x1F, 0x00, 0x7C, 0x00, 0x90, 0x01, 0xC8, 0x03,
-0x00, 0x1F, 0x00, 0x7C, 0x80, 0xF8, 0x01, 0xC0, 0x86, 0x00, 0x1F, 0x80, 0x5C,
-0x00, 0x60, 0x01, 0xC0, 0x85, 0x00, 0x1F, 0x04, 0x4D, 0x00, 0xF0, 0x21, 0xC0,
-0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x5D,
-0x00, 0xD4, 0x0D, 0xD8, 0x07, 0x60, 0x17, 0x10, 0x5E, 0x00, 0x74, 0x01, 0x10,
-0x57, 0xE0, 0x9B, 0x80, 0x5D, 0x20, 0xF4, 0x01, 0xB2, 0x05, 0xC0, 0x17, 0x80,
-0x5D, 0x00, 0x7C, 0x01, 0x70, 0x17, 0xC0, 0x1C, 0x00, 0x7D, 0x02, 0xC4, 0x01,
-0xB0, 0x17, 0x40, 0x98, 0x00, 0x7F, 0x03, 0xC4, 0x45, 0xD2, 0x07, 0x48, 0x41,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00,
-0x04, 0x2E, 0x50, 0x08, 0x40, 0x31, 0x80, 0xC9, 0x00, 0x34, 0x03, 0x13, 0x18,
-0x60, 0x32, 0x80, 0xCD, 0x00, 0x34, 0x02, 0x18, 0x0C, 0x40, 0x33, 0x10, 0xCD,
-0x00, 0x34, 0x03, 0xD0, 0x7C, 0x50, 0x20, 0x00, 0xCD, 0x1A, 0x16, 0x0B, 0x10,
-0x04, 0x00, 0xF1, 0x02, 0x8D, 0x00, 0x04, 0x1E, 0xD0, 0x8C, 0x40, 0x40, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x04, 0x94,
-0x02, 0xD0, 0x0A, 0x40, 0x3B, 0x01, 0xED, 0x04, 0x34, 0x07, 0x18, 0x0A, 0x40,
-0x3B, 0x00, 0xED, 0x04, 0x34, 0x02, 0x92, 0x4E, 0x40, 0x3B, 0x01, 0xED, 0x00,
-0xB4, 0x03, 0x50, 0x0E, 0x41, 0x28, 0x10, 0xAD, 0x40, 0x84, 0x04, 0x90, 0x3E,
-0x40, 0x38, 0x00, 0xAD, 0x83, 0x86, 0x03, 0xD0, 0x0A, 0x40, 0x11, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x03, 0x94, 0x07,
-0x70, 0x1A, 0xC0, 0x79, 0x01, 0xED, 0x05, 0xB4, 0x37, 0x31, 0x1E, 0x40, 0x7A,
-0x08, 0xED, 0x0B, 0xB4, 0x06, 0x34, 0x1E, 0xC0, 0x7B, 0x02, 0xED, 0x85, 0xBC,
-0x27, 0xD8, 0x17, 0xE0, 0x68, 0x00, 0xAF, 0x81, 0x9C, 0x04, 0x78, 0x16, 0xC0,
-0x79, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0xF0, 0x1B, 0xC0, 0x50, 0x60, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x10, 0xDF, 0x40, 0x7C, 0x03, 0xF0,
-0x09, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x2B, 0xF4, 0x0D, 0xC0, 0x35, 0x00,
-0xDF, 0x00, 0x7C, 0x02, 0x70, 0x0D, 0xC0, 0x35, 0x82, 0xDF, 0x3E, 0x5C, 0x3B,
-0x70, 0x01, 0xE0, 0x25, 0x20, 0x9F, 0x00, 0x3C, 0x00, 0x70, 0x0D, 0xC2, 0x27,
-0x00, 0xC7, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xEF, 0x09, 0xCC, 0x32, 0xF8, 0x8B,
-0xC0, 0x7C, 0x04, 0xFF, 0x11, 0xFC, 0x07, 0xF0, 0x1B, 0xC8, 0x7F, 0x00, 0xFF,
-0x01, 0xDE, 0x06, 0xF0, 0xBD, 0xC1, 0x74, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0,
-0x1B, 0xC0, 0x6C, 0x00, 0x9B, 0x89, 0xFC, 0x25, 0xF0, 0x17, 0xC0, 0x7C, 0x00,
-0xBB, 0x01, 0xBC, 0x07, 0x38, 0x9F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0x80, 0x39, 0x00, 0xED, 0x1C, 0x84, 0x22, 0xD8, 0x0A, 0xC0,
-0x3A, 0xA0, 0xED, 0x08, 0xB4, 0x03, 0xD0, 0x08, 0x40, 0x13, 0x00, 0xED, 0x00,
-0x8C, 0x12, 0xD0, 0x5E, 0x40, 0x78, 0x02, 0xED, 0x00, 0x9C, 0x43, 0xD0, 0x0B,
-0x60, 0x28, 0x06, 0xAD, 0x05, 0xB4, 0x24, 0xD2, 0x0E, 0xC0, 0x3A, 0x80, 0xA5,
-0x00, 0xB4, 0x09, 0xF2, 0xC2, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x08, 0x39, 0x00, 0xFD, 0x81, 0xA4, 0x03, 0xD8, 0x88, 0x40, 0x78,
-0x02, 0xE5, 0x01, 0xB4, 0x03, 0x50, 0x0A, 0x40, 0x3B, 0x02, 0xFD, 0x18, 0x94,
-0x02, 0xD1, 0x4E, 0x54, 0x3A, 0x10, 0xED, 0x00, 0xB4, 0x23, 0xD0, 0x0E, 0x40,
-0x28, 0x00, 0xA9, 0x14, 0xB4, 0x80, 0xD8, 0x86, 0x40, 0x39, 0x00, 0xE1, 0x00,
-0xB4, 0x03, 0x10, 0x0E, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x06, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x01, 0xD0, 0x08, 0x64, 0x32, 0x00,
-0xCD, 0x80, 0x34, 0x03, 0xD0, 0x08, 0x60, 0x13, 0x00, 0xCD, 0x81, 0x04, 0x02,
-0xD0, 0x0D, 0x40, 0x36, 0x00, 0xDD, 0x40, 0x54, 0x0F, 0xD1, 0x28, 0x44, 0xE0,
-0x10, 0x8D, 0x40, 0x34, 0x00, 0xD0, 0x88, 0x40, 0x63, 0x00, 0xC5, 0x00, 0x34,
-0x09, 0x52, 0x30, 0x40, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0xA8, 0x35, 0x00, 0xDF, 0x41, 0x6D, 0x02, 0xD0, 0x0D, 0xC0, 0x34, 0x00, 0xDF,
-0x00, 0xFC, 0x03, 0xF0, 0x09, 0xC8, 0xF7, 0x08, 0xFF, 0x03, 0x54, 0x83, 0xD2,
-0x0F, 0x48, 0x3E, 0x00, 0xFF, 0x08, 0xF4, 0x0B, 0xD0, 0x2D, 0xD0, 0x34, 0x02,
-0x8B, 0x01, 0x7C, 0x00, 0xD0, 0x0C, 0xC0, 0xB5, 0x06, 0x93, 0x00, 0x7C, 0x0A,
-0x10, 0x21, 0xC0, 0x57, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x33, 0x00, 0xDF, 0x10, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x00,
-0x7C, 0x03, 0xF0, 0x29, 0xC4, 0x77, 0x04, 0xDF, 0x04, 0x1C, 0x0A, 0xF0, 0x0D,
-0xC0, 0x35, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x4D, 0xC0, 0xA7, 0x08, 0x9F,
-0x60, 0x7C, 0x88, 0xF1, 0x2D, 0x40, 0xB6, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
-0xA1, 0xC8, 0x37, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F,
-0x00, 0xF3, 0x00, 0xFC, 0x12, 0x30, 0x2F, 0xC0, 0x3F, 0x20, 0xF3, 0x40, 0xFC,
-0x03, 0xF0, 0x1F, 0xC0, 0x2C, 0x02, 0xFF, 0x80, 0xFC, 0x87, 0x30, 0x0F, 0xD0,
-0x3C, 0x00, 0xF5, 0x00, 0xCD, 0x43, 0xB0, 0x07, 0xC0, 0x7F, 0x00, 0xBF, 0x00,
-0xCC, 0x80, 0xF0, 0x0F, 0x80, 0x3C, 0x00, 0xB3, 0x04, 0xFC, 0x40, 0xF0, 0x0A,
-0xC1, 0x04, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x20,
-0xD1, 0x00, 0x74, 0x06, 0x94, 0x05, 0xC0, 0x35, 0x00, 0xD1, 0x00, 0x74, 0x03,
-0xD0, 0x84, 0x41, 0x25, 0x00, 0xDD, 0x20, 0x74, 0x01, 0x10, 0x0D, 0x40, 0x34,
-0x00, 0xD1, 0x00, 0x44, 0x03, 0xB0, 0x21, 0x40, 0x17, 0x00, 0x9D, 0x23, 0x44,
-0x4C, 0xD0, 0x0D, 0x50, 0x60, 0x84, 0x95, 0x07, 0x74, 0x0C, 0xD0, 0x39, 0x50,
-0x04, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0xC0, 0xD1,
-0x00, 0x74, 0x02, 0x90, 0x0D, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0,
-0x09, 0x40, 0x34, 0x00, 0xDD, 0x00, 0x64, 0x1B, 0x10, 0x0D, 0x40, 0x34, 0x00,
-0xD5, 0x00, 0x64, 0x03, 0x10, 0x01, 0x40, 0xB7, 0x01, 0x9D, 0x11, 0x44, 0x04,
-0xD0, 0x0D, 0x41, 0x45, 0x00, 0x91, 0x00, 0x74, 0x06, 0x50, 0x11, 0x40, 0x04,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0xC1, 0x00,
-0x34, 0x02, 0x90, 0x08, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x08,
-0x40, 0x11, 0x00, 0xCD, 0x00, 0x34, 0x02, 0x14, 0x4C, 0x40, 0x30, 0x04, 0xC5,
-0x20, 0x04, 0x03, 0xD4, 0x00, 0x44, 0x23, 0x80, 0x8D, 0x30, 0x05, 0x40, 0xD0,
-0x0D, 0x40, 0x25, 0x00, 0x85, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x42, 0x40, 0x81,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0xF3, 0x40, 0x7C,
-0x03, 0x30, 0x0D, 0xC4, 0x3F, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x2D, 0xC2,
-0xA4, 0x02, 0xFD, 0x00, 0x7C, 0x03, 0x30, 0x0E, 0xC0, 0x3C, 0x01, 0xF7, 0x00,
-0xCC, 0x03, 0x32, 0x05, 0xC2, 0x37, 0x00, 0x9F, 0x00, 0x4C, 0x10, 0xF0, 0x0D,
-0xC0, 0x25, 0x00, 0x51, 0x00, 0x7C, 0x00, 0x70, 0x09, 0xC0, 0x04, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xA8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x01,
-0x78, 0x07, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x47, 0xC1, 0x0F,
-0x00, 0xEF, 0x00, 0xFC, 0x01, 0xF0, 0x2F, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xFC,
-0x03, 0x30, 0x03, 0xC0, 0x1F, 0x00, 0x3F, 0x00, 0x7C, 0x00, 0xF0, 0x0A, 0x40,
-0x2A, 0x08, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x3F, 0x08, 0xA3, 0x00, 0xFC, 0x33, 0x30,
-0x9B, 0xC0, 0xEF, 0x00, 0xFF, 0x03, 0x9D, 0x27, 0xB0, 0x1F, 0xC0, 0x7C, 0x02,
-0xFB, 0x09, 0xCD, 0x07, 0x70, 0x1F, 0xC8, 0x7A, 0x08, 0xFF, 0x01, 0xFC, 0x07,
-0x31, 0x9F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0xFE, 0x27, 0x30, 0x1F, 0xC0, 0x7A,
-0x40, 0xB3, 0x01, 0xFC, 0x00, 0x30, 0x26, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x3B, 0x38, 0xD1, 0x43, 0xF4, 0x13, 0x12, 0x4C,
-0x44, 0x27, 0x11, 0x1C, 0x84, 0x44, 0x10, 0x10, 0x11, 0x50, 0x04, 0x01, 0x11,
-0x04, 0x44, 0xD0, 0x50, 0x11, 0x40, 0x07, 0x05, 0x0D, 0x10, 0x34, 0x40, 0x10,
-0x41, 0x40, 0x07, 0x00, 0x1D, 0x44, 0x5C, 0x10, 0x10, 0x11, 0x40, 0x44, 0x00,
-0x91, 0x01, 0x5C, 0x0C, 0x14, 0x45, 0x40, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x11, 0xA0, 0x23, 0x05, 0x81, 0x22, 0x14, 0x33, 0x10, 0x0C, 0x48,
-0x21, 0x01, 0xCD, 0x00, 0x44, 0x13, 0x54, 0x0D, 0x40, 0x31, 0x00, 0xC1, 0x80,
-0x04, 0x03, 0x56, 0x0C, 0x44, 0x33, 0x00, 0xCD, 0x04, 0x34, 0x13, 0x90, 0x4C,
-0x40, 0x33, 0x05, 0xCD, 0x20, 0x34, 0x13, 0x10, 0x0D, 0x40, 0x30, 0x00, 0x01,
-0x01, 0x34, 0x0A, 0xD0, 0x40, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x07, 0x88, 0x35, 0x40, 0xD1, 0x84, 0x74, 0x03, 0x14, 0x3D, 0x40, 0x27,
-0x20, 0x0D, 0x00, 0x54, 0x00, 0x90, 0x01, 0x42, 0x05, 0x00, 0x01, 0x00, 0x44,
-0x00, 0x54, 0x01, 0x60, 0x07, 0x00, 0x1D, 0x80, 0x70, 0x00, 0x90, 0x01, 0x40,
-0x07, 0x00, 0x1D, 0x20, 0x14, 0x00, 0x18, 0x01, 0x40, 0x04, 0x00, 0x51, 0x01,
-0x74, 0x00, 0xD1, 0x01, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA0, 0x37, 0x00, 0x93, 0x01, 0x5C, 0x03, 0x30, 0x3D, 0xC0, 0x65, 0x0A,
-0xDF, 0x00, 0x4C, 0x83, 0xF0, 0x0D, 0xC8, 0x35, 0x40, 0xDB, 0x80, 0x08, 0x03,
-0x74, 0x0D, 0xC4, 0x36, 0x10, 0xDF, 0x00, 0x78, 0x03, 0xA0, 0x0D, 0xC0, 0x37,
-0x80, 0xDF, 0x00, 0x74, 0x03, 0x34, 0x0C, 0xC2, 0x36, 0x00, 0x91, 0x01, 0x3C,
-0x15, 0xF0, 0x15, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x88, 0x3D, 0x00, 0xFF, 0x21, 0xF4, 0x03, 0xD0, 0x0F, 0xC0, 0x2F, 0x00, 0x3F,
-0x40, 0xE4, 0x00, 0x30, 0x03, 0xC0, 0x0E, 0x00, 0x3F, 0x00, 0xFC, 0x40, 0xF0,
-0x03, 0x00, 0x0F, 0x00, 0x3F, 0x30, 0xFC, 0x80, 0x70, 0x03, 0xC0, 0x0F, 0xA0,
-0x3F, 0x40, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x14, 0xFF, 0x00, 0xDC, 0x24,
-0x30, 0x47, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
-0x61, 0x10, 0x9B, 0x01, 0x6C, 0x03, 0x34, 0x3D, 0xC0, 0x24, 0x00, 0xD3, 0x50,
-0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x77, 0x00, 0xD3, 0x08, 0x4C, 0x07, 0xB0, 0x4D,
-0xC0, 0x37, 0x00, 0xD7, 0x01, 0x4C, 0x83, 0x30, 0x1D, 0xC1, 0x37, 0x00, 0xDF,
-0x01, 0x7C, 0x97, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x93, 0x10, 0x7C, 0x20, 0x30,
-0x25, 0xD0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4,
-0x02, 0xD1, 0x20, 0xD4, 0x2B, 0x10, 0x2D, 0x40, 0x64, 0x01, 0x1A, 0x03, 0x3C,
-0x00, 0x14, 0x40, 0x42, 0x87, 0x00, 0x11, 0x01, 0x44, 0x00, 0x10, 0x51, 0xC0,
-0x05, 0x40, 0x15, 0x01, 0x44, 0x04, 0x10, 0x11, 0x40, 0x07, 0x00, 0x1D, 0x21,
-0x74, 0x0C, 0xD0, 0x01, 0x44, 0xC0, 0x04, 0x59, 0x03, 0x74, 0x20, 0x00, 0xB5,
-0x40, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x20, 0x30, 0x00,
-0x89, 0x40, 0x44, 0x03, 0x90, 0x2C, 0x41, 0x60, 0x00, 0xC9, 0x02, 0x34, 0x03,
-0x10, 0x1C, 0x40, 0xB7, 0x04, 0xC1, 0x01, 0x14, 0x03, 0x90, 0x2C, 0x40, 0x33,
-0x00, 0xC9, 0x02, 0x54, 0x27, 0x91, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34,
-0x0B, 0xD0, 0x0C, 0x40, 0xF0, 0x40, 0x89, 0x03, 0x14, 0x0C, 0x10, 0x9C, 0x40,
-0x4C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x78, 0x00, 0xF1,
-0x01, 0x14, 0x07, 0x90, 0x1E, 0x40, 0x68, 0x00, 0x29, 0x11, 0xC4, 0x04, 0x10,
-0x92, 0x48, 0x4B, 0x00, 0x21, 0x03, 0x94, 0x04, 0x12, 0x12, 0x40, 0x4D, 0x20,
-0x29, 0x09, 0x95, 0x0C, 0x50, 0x12, 0x40, 0x4B, 0x20, 0x2C, 0x41, 0xB0, 0x04,
-0xD0, 0x13, 0x40, 0x48, 0x00, 0xA9, 0x29, 0xB4, 0x17, 0x10, 0x1F, 0x40, 0x3C,
-0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x18, 0x20, 0x00, 0x8B, 0x00,
-0x0C, 0x03, 0x30, 0x0C, 0xC0, 0x24, 0x00, 0xCB, 0x88, 0x34, 0x23, 0x31, 0x0C,
-0xC0, 0x37, 0x00, 0xD3, 0x80, 0x5C, 0x23, 0xB0, 0x8C, 0xC0, 0x33, 0x02, 0xCF,
-0x00, 0x1C, 0x23, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCE, 0x00, 0x3C, 0x03, 0xF2,
-0x0C, 0xC4, 0x30, 0x00, 0x43, 0x30, 0x1C, 0x03, 0x30, 0x7C, 0xC0, 0x48, 0x40,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x3D, 0x00, 0xFF, 0x00, 0xDC,
-0x4B, 0x50, 0x0F, 0xC0, 0x2F, 0x02, 0x3F, 0x28, 0xFE, 0x00, 0xF2, 0x03, 0x48,
-0x0F, 0x00, 0x3F, 0x00, 0xEC, 0x80, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x00,
-0xEC, 0x00, 0xB0, 0x83, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xFC, 0x00, 0xF0, 0x02,
-0xC0, 0x4F, 0x40, 0x77, 0x00, 0x3C, 0x13, 0xF2, 0x8D, 0xC0, 0x0B, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x01, 0x9F, 0x00, 0x7C, 0x13,
-0xF0, 0x0D, 0xC0, 0x24, 0x00, 0xDD, 0x00, 0x7C, 0x03, 0xF0, 0x1C, 0xC0, 0x30,
-0x40, 0xD3, 0x00, 0x6F, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4D,
-0x03, 0xF0, 0x1D, 0xD0, 0x34, 0x00, 0xDF, 0x21, 0x4D, 0x07, 0x24, 0x0D, 0xC0,
-0x33, 0x00, 0x53, 0x00, 0x4C, 0x07, 0x32, 0x15, 0xC0, 0x40, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x22, 0xED, 0x00, 0xB4, 0x03, 0xD0,
-0x0F, 0x50, 0x28, 0x00, 0x2D, 0x00, 0xBC, 0x00, 0xD0, 0x02, 0x48, 0x09, 0x00,
-0x21, 0x00, 0x84, 0x00, 0xD2, 0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0x84, 0x00,
-0xD0, 0x03, 0x40, 0x08, 0x00, 0x3D, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x44, 0x0B,
-0x00, 0xE1, 0x20, 0xAC, 0x03, 0xB0, 0x07, 0xC0, 0x4E, 0x68, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x69, 0x10, 0xED, 0x03, 0x94, 0x17, 0xD0, 0x1E,
-0x40, 0x68, 0x04, 0xED, 0x41, 0xB4, 0x07, 0x50, 0x1E, 0x44, 0x7C, 0x20, 0xF9,
-0x81, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xE5, 0x01, 0x84, 0x07, 0xD0,
-0x1E, 0x40, 0x79, 0x00, 0xED, 0x01, 0x84, 0x87, 0x18, 0x1E, 0x40, 0x7B, 0x40,
-0x71, 0x01, 0x04, 0x07, 0x10, 0x16, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0xD0, 0x24, 0x4C,
-0x30, 0x10, 0x0D, 0x00, 0x12, 0x00, 0xD0, 0x00, 0x40, 0x01, 0x10, 0x09, 0xC0,
-0x04, 0x80, 0xD0, 0x00, 0x42, 0x03, 0x08, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x00,
-0x40, 0x01, 0x00, 0x0D, 0x00, 0x06, 0x00, 0x10, 0x00, 0x40, 0x03, 0x00, 0x51,
-0x03, 0x24, 0xCF, 0x12, 0x34, 0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x17, 0xA0, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xD0, 0x27, 0xC0, 0x54,
-0x00, 0x5F, 0x00, 0x74, 0x01, 0x70, 0x05, 0xC4, 0x14, 0x00, 0x4B, 0x00, 0x6C,
-0x01, 0xF0, 0x04, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0xF0, 0x05, 0xC0,
-0x15, 0x00, 0x5F, 0x00, 0x44, 0x01, 0x30, 0x05, 0xC0, 0x13, 0x00, 0x71, 0x07,
-0xCC, 0x11, 0x14, 0x17, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x08, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC1, 0x07, 0x00,
-0x3D, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x02, 0xFC, 0x00,
-0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0E,
-0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x40, 0x1F, 0x06, 0x7C,
-0x00, 0xF0, 0xA1, 0xC9, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x21, 0x00, 0x93, 0x00, 0x3C, 0x02, 0xB0, 0x09, 0xC0, 0x24, 0x10, 0x9F,
-0x01, 0x4C, 0x02, 0xF0, 0x19, 0xC0, 0xE7, 0x00, 0x93, 0x00, 0x6C, 0x06, 0xF0,
-0x99, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x34, 0x59, 0xC0, 0x27, 0x00,
-0x9F, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9B, 0x00, 0x6C, 0x02,
-0xF0, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
-0x26, 0x40, 0x91, 0x80, 0x74, 0x42, 0x10, 0xA9, 0x41, 0x24, 0x00, 0x8D, 0x09,
-0x5E, 0x2A, 0xD0, 0x19, 0x40, 0x63, 0x40, 0x91, 0x02, 0x45, 0x1A, 0xD0, 0x69,
-0xC2, 0x26, 0x08, 0x9D, 0x02, 0x44, 0x42, 0x10, 0x39, 0x40, 0x27, 0x00, 0x9D,
-0x02, 0x74, 0x0A, 0xD0, 0x09, 0x48, 0x67, 0x04, 0x91, 0x82, 0x44, 0x86, 0xD0,
-0x69, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x64,
-0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x08, 0x40, 0x24, 0x00, 0x9D, 0x00, 0xC4,
-0x42, 0xD0, 0x4B, 0x40, 0x2F, 0x00, 0xB9, 0x03, 0xC4, 0x12, 0xD0, 0x0B, 0x40,
-0x2C, 0x00, 0xBD, 0x00, 0xC4, 0x06, 0x92, 0x0B, 0x44, 0x2F, 0x00, 0xBD, 0xC0,
-0xF4, 0x02, 0xD0, 0x1B, 0x40, 0x2F, 0x41, 0x91, 0x08, 0x64, 0x22, 0xD0, 0x09,
-0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x2A, 0x20, 0x01,
-0x81, 0x04, 0x34, 0x12, 0x18, 0x08, 0x50, 0x20, 0x00, 0xBC, 0x00, 0x84, 0x02,
-0xD0, 0x0A, 0x40, 0x6F, 0x00, 0xB9, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40, 0x2A,
-0x00, 0xAD, 0x01, 0x84, 0x02, 0x90, 0x1A, 0x40, 0x2B, 0x00, 0xAD, 0x41, 0xB4,
-0x06, 0xD0, 0x0A, 0x40, 0x2B, 0x00, 0x91, 0x00, 0x24, 0x02, 0xD0, 0x48, 0x40,
-0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0x86, 0x02, 0x13,
-0x00, 0x7C, 0x28, 0x34, 0xA1, 0xC0, 0x84, 0x02, 0x1F, 0x0A, 0x44, 0x28, 0xF0,
-0x01, 0xC0, 0x87, 0x02, 0x1B, 0x0A, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x85, 0x02,
-0x1F, 0x0A, 0x4C, 0x28, 0xB3, 0xA1, 0xC0, 0x87, 0x02, 0x1F, 0x0A, 0x7C, 0x28,
-0xF0, 0x01, 0xC0, 0x0F, 0x10, 0x53, 0x00, 0x6C, 0x51, 0xFA, 0xA1, 0xC0, 0x77,
-0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x88, 0x2F, 0x02, 0xBF, 0x08,
-0x7C, 0x22, 0x78, 0x0B, 0xC0, 0x2F, 0x20, 0x9E, 0x00, 0x5D, 0x02, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x87, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
-0x00, 0x7D, 0x02, 0x71, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x20, 0x7C, 0x82, 0xF0,
-0x09, 0xC2, 0x27, 0x00, 0xA7, 0x00, 0xDC, 0x02, 0xF0, 0x8B, 0xC0, 0x67, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x01, 0xB3, 0x14, 0xCC,
-0xB2, 0x30, 0x0F, 0xC0, 0x2D, 0x00, 0xBF, 0x08, 0xCC, 0x02, 0x10, 0x0B, 0xC0,
-0x2F, 0x02, 0xBF, 0x00, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x00,
-0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x08, 0xDC, 0x02, 0x30, 0x0B,
-0xC0, 0x2F, 0x00, 0xB3, 0x00, 0xFC, 0x82, 0x30, 0x0B, 0xC0, 0x67, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x0D, 0x11, 0x00, 0x45, 0x30,
-0x10, 0x01, 0x43, 0x04, 0x04, 0x1D, 0x00, 0x04, 0x50, 0x10, 0x01, 0x40, 0x03,
-0x01, 0x1D, 0x10, 0x4C, 0x40, 0x14, 0x01, 0x50, 0x04, 0x05, 0x01, 0x04, 0x74,
-0x10, 0xD0, 0x00, 0x41, 0x00, 0x24, 0x01, 0x40, 0x5C, 0x50, 0x10, 0x01, 0x40,
-0x07, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x81, 0x40, 0x73, 0x60, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x03, 0x91, 0x20, 0x04, 0x12, 0x90,
-0x49, 0x40, 0x21, 0x80, 0x8D, 0x00, 0x04, 0x12, 0x10, 0x0C, 0x40, 0x23, 0x01,
-0x8D, 0x04, 0x65, 0x02, 0x10, 0x09, 0x40, 0x24, 0x41, 0x81, 0x14, 0x34, 0x12,
-0xD8, 0x48, 0x50, 0x20, 0x00, 0x81, 0x00, 0x14, 0x12, 0x10, 0x08, 0x40, 0x23,
-0x00, 0x89, 0x00, 0x34, 0x02, 0x10, 0x08, 0x48, 0x4B, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x41, 0x91, 0x00, 0x44, 0x03, 0x90, 0x29,
-0x40, 0x24, 0x02, 0x8D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x8D,
-0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0,
-0x09, 0x40, 0x24, 0x00, 0xD1, 0x00, 0x54, 0x02, 0x10, 0x09, 0x40, 0x37, 0x20,
-0x99, 0x00, 0x74, 0x0A, 0x12, 0x89, 0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x00, 0x25, 0x00, 0x83, 0x89, 0x0C, 0x02, 0xB4, 0x18, 0xC0,
-0x65, 0x20, 0x9F, 0x00, 0x4D, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x80, 0x9F, 0x00,
-0x6C, 0x02, 0x30, 0x08, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x24, 0x40, 0x93, 0x00, 0x5C, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x00, 0x99,
-0x12, 0x7C, 0x02, 0x34, 0x19, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x41, 0x7C, 0x02, 0x74, 0x29, 0xC0, 0x27,
-0x00, 0x9F, 0x50, 0x7C, 0x42, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x97, 0x15,
-0x7E, 0x52, 0xF0, 0x09, 0xE0, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x08, 0x41, 0x40, 0x13, 0x00, 0x7C, 0x10, 0xF0, 0x41, 0xC0, 0x07, 0x00,
-0x1F, 0x08, 0x4C, 0x00, 0x34, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00,
-0xF0, 0x11, 0xF0, 0x04, 0x00, 0x1F, 0x20, 0x4C, 0x04, 0xD0, 0x01, 0xC0, 0x06,
-0x40, 0x13, 0x40, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x02, 0x0C,
-0x08, 0x14, 0x01, 0xC4, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA0, 0x5C, 0x00, 0x51, 0x00, 0xF4, 0x09, 0xD0, 0x27, 0xC0, 0x15, 0x00, 0x7D,
-0x00, 0xC6, 0x05, 0x50, 0x05, 0x40, 0x5F, 0x04, 0x73, 0x02, 0xB4, 0x29, 0xD1,
-0x07, 0xC2, 0x12, 0x00, 0x7D, 0x45, 0xC4, 0x15, 0xD0, 0x07, 0xC0, 0x14, 0x00,
-0x71, 0x02, 0xCC, 0x01, 0xD0, 0x15, 0x40, 0x9B, 0x08, 0x71, 0x02, 0xD4, 0x0D,
-0x50, 0xF7, 0x40, 0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
-0x32, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x31, 0x20, 0xCD, 0x00,
-0x64, 0x0F, 0x50, 0x08, 0x44, 0x73, 0x00, 0xC1, 0x04, 0x24, 0x03, 0xD0, 0x04,
-0x40, 0x32, 0x10, 0xCD, 0x01, 0x05, 0x03, 0x50, 0x0D, 0x40, 0x34, 0x00, 0xC1,
-0x06, 0x65, 0x07, 0xD0, 0x98, 0x40, 0x63, 0x03, 0x41, 0x08, 0x04, 0x23, 0x10,
-0x0C, 0x40, 0x52, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x08,
-0x04, 0xE1, 0x00, 0xB4, 0x43, 0x90, 0x0E, 0x40, 0x39, 0x00, 0x7D, 0x00, 0xA5,
-0x0B, 0x50, 0x0E, 0x40, 0x7B, 0x00, 0xE1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x41,
-0x38, 0x01, 0xED, 0x01, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x0A, 0xE1, 0x83,
-0xA4, 0x43, 0xD0, 0x0E, 0x40, 0x1F, 0x00, 0x71, 0x01, 0x14, 0x03, 0x10, 0x12,
-0x58, 0x06, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x60, 0x00,
-0xE3, 0x01, 0xBC, 0x07, 0xD0, 0x1E, 0xC0, 0x79, 0x00, 0xEF, 0x01, 0xA4, 0x06,
-0x70, 0x1E, 0xC0, 0x6B, 0x40, 0xE3, 0x01, 0xB0, 0x05, 0xF0, 0x1E, 0x40, 0x7A,
-0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70, 0x1E, 0xC0, 0x78, 0x05, 0xE3, 0x01, 0xAC,
-0x07, 0xF1, 0x1E, 0xC0, 0x6B, 0x00, 0x63, 0x81, 0x84, 0x07, 0x30, 0x18, 0xC0,
-0x46, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x05, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x35, 0x10, 0x0F, 0x00, 0x5C, 0x02, 0xB0,
-0x0D, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x80, 0xF0, 0x0C, 0xC0, 0x37, 0x04,
-0x5F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xD0, 0xB5, 0x00, 0x9F, 0x00, 0x5C, 0x01,
-0xF0, 0x0D, 0xC0, 0x33, 0x20, 0x4F, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x41,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x4D, 0x00, 0xE7, 0x21,
-0xCC, 0x07, 0xF8, 0x87, 0xC0, 0x7C, 0x02, 0xBF, 0x01, 0xCC, 0x07, 0x30, 0x1F,
-0xC0, 0x7C, 0x00, 0x73, 0x01, 0xEC, 0x05, 0x32, 0x1F, 0xC0, 0x7F, 0x04, 0xF3,
-0x01, 0xFC, 0x04, 0xB0, 0x1F, 0xC0, 0x7F, 0x10, 0xB3, 0x01, 0xCC, 0x07, 0xF0,
-0x1E, 0xC0, 0x3C, 0x00, 0xF3, 0x05, 0xCC, 0x06, 0xF0, 0x13, 0x84, 0x0B, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x8D, 0x10, 0xE1, 0x08, 0x84,
-0x21, 0x78, 0x0E, 0x44, 0x38, 0x00, 0x7D, 0x06, 0xC5, 0x03, 0x10, 0x0E, 0x40,
-0x28, 0x00, 0x71, 0x40, 0x84, 0xE0, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xA1, 0x10,
-0xB4, 0x01, 0x10, 0x0E, 0x40, 0x3B, 0x02, 0xBB, 0x18, 0x8C, 0x0A, 0xD0, 0x8E,
-0x40, 0x19, 0x02, 0xA1, 0x06, 0xAC, 0x03, 0xD0, 0x20, 0x40, 0x57, 0x60, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xE5, 0x00, 0x85, 0x01,
-0x50, 0x87, 0x40, 0x38, 0x8C, 0xAD, 0x00, 0x86, 0x01, 0x90, 0x0F, 0x40, 0x3A,
-0x40, 0xE1, 0x00, 0xC4, 0x01, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xF4,
-0x0A, 0x10, 0x0E, 0x40, 0x3F, 0x00, 0x61, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40,
-0x29, 0x42, 0x61, 0x0C, 0x94, 0x43, 0xD0, 0x02, 0x40, 0x23, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xC1, 0x00, 0x04, 0x01, 0x50,
-0x31, 0x40, 0x70, 0x00, 0x1D, 0x41, 0x02, 0x45, 0x90, 0x3C, 0x50, 0x82, 0x04,
-0x01, 0x10, 0x04, 0x08, 0x10, 0x2C, 0x42, 0x77, 0x01, 0x01, 0x05, 0x30, 0x04,
-0x10, 0xD0, 0x40, 0xB3, 0x04, 0x09, 0x05, 0x06, 0x34, 0xD0, 0x1C, 0x40, 0x91,
-0x00, 0x81, 0x13, 0x34, 0x0E, 0xD0, 0x00, 0x40, 0x1B, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x80, 0x05, 0x00, 0xD7, 0x00, 0x4C, 0x03, 0x70, 0xE9,
-0xC0, 0x74, 0x00, 0xDF, 0x05, 0x4C, 0x09, 0xB0, 0x0D, 0xC0, 0x16, 0x00, 0x93,
-0x01, 0x4C, 0x07, 0x34, 0x7C, 0x40, 0xBF, 0x00, 0x13, 0x03, 0x3C, 0x03, 0x10,
-0x21, 0xC0, 0x3B, 0x00, 0x53, 0x03, 0x4C, 0x08, 0xF0, 0x3D, 0xC0, 0xB5, 0x02,
-0x43, 0x11, 0x50, 0x0D, 0xF0, 0x09, 0x40, 0x77, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x00, 0x47, 0x00, 0x9F, 0x01, 0x7C, 0x83, 0x70, 0x09, 0xD2,
-0x27, 0x00, 0xDF, 0x04, 0x7C, 0x21, 0x70, 0x8D, 0xC0, 0xB5, 0x02, 0xDF, 0x08,
-0x7C, 0x8B, 0xF2, 0x0D, 0xC0, 0x37, 0x42, 0x9F, 0x00, 0x7C, 0x23, 0x70, 0x29,
-0xC0, 0x77, 0x00, 0x57, 0x02, 0x5C, 0x02, 0xF0, 0xCD, 0xC0, 0xF7, 0x40, 0x5F,
-0x40, 0x2C, 0x0B, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x80, 0x00, 0x0B, 0x40, 0xE3, 0x00, 0xEC, 0x03, 0xF0, 0x8F, 0xC0, 0x3C,
-0x00, 0xFB, 0x00, 0xCC, 0x02, 0x30, 0x0F, 0xC1, 0x0F, 0x00, 0xBF, 0x09, 0xFC,
-0x40, 0xF0, 0x0F, 0xC1, 0x3C, 0x00, 0x33, 0x05, 0xFC, 0x03, 0xB0, 0x47, 0xC0,
-0x3D, 0x00, 0x73, 0x00, 0xCC, 0x20, 0x30, 0x9F, 0xC0, 0xFF, 0x00, 0xB3, 0x00,
-0xCC, 0x43, 0x32, 0x0B, 0xC4, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x81, 0x20, 0xC6, 0x00, 0x91, 0x00, 0x44, 0x0F, 0xF0, 0x11, 0x60, 0x61, 0x02,
-0x91, 0x02, 0x44, 0x02, 0x10, 0x0D, 0x40, 0x87, 0x04, 0x1D, 0x00, 0x5C, 0x1E,
-0xD1, 0x1D, 0x40, 0x34, 0x08, 0x11, 0x12, 0x74, 0x00, 0x10, 0x71, 0x40, 0x34,
-0x00, 0x11, 0x02, 0x4C, 0x0C, 0x10, 0x0D, 0x40, 0x33, 0x00, 0x11, 0x01, 0x44,
-0x2F, 0x15, 0x19, 0x40, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0xA0, 0x46, 0x00, 0xD1, 0x04, 0x64, 0x04, 0xD0, 0x01, 0x40, 0x37, 0x20, 0x19,
-0x00, 0x04, 0x10, 0x10, 0x1D, 0x48, 0x17, 0x10, 0x1D, 0x00, 0x74, 0x05, 0x50,
-0x1D, 0x44, 0x34, 0x40, 0x51, 0x00, 0x74, 0x00, 0x10, 0x00, 0x40, 0x36, 0x00,
-0x81, 0x00, 0x04, 0x01, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xD9, 0x01, 0x64, 0xC3,
-0x10, 0x19, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
-0x00, 0x18, 0x81, 0x00, 0x04, 0x00, 0xD8, 0x08, 0x40, 0x26, 0x80, 0x41, 0x00,
-0x05, 0x04, 0x18, 0x0C, 0x40, 0x23, 0x00, 0x4D, 0x00, 0x34, 0x03, 0xD0, 0x1D,
-0x40, 0x30, 0x00, 0x81, 0x00, 0x74, 0x01, 0x18, 0x08, 0x50, 0x36, 0x00, 0x81,
-0x00, 0x04, 0x02, 0x14, 0x0C, 0x40, 0x37, 0x00, 0x89, 0x00, 0x04, 0x03, 0x10,
-0x00, 0x44, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x06,
-0x00, 0xD3, 0x00, 0x6C, 0x00, 0xF0, 0x05, 0x50, 0x37, 0x00, 0x1B, 0x00, 0x4C,
-0x00, 0x20, 0x0D, 0xC0, 0x13, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0x50,
-0x38, 0x00, 0x53, 0x00, 0x7C, 0x02, 0x30, 0x05, 0xC0, 0x3F, 0x00, 0x53, 0x00,
-0x4C, 0x01, 0x30, 0x0D, 0xC0, 0x37, 0x10, 0x9B, 0x20, 0x6C, 0x81, 0x30, 0xA9,
-0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00,
-0xBF, 0x00, 0xFC, 0x00, 0x70, 0x02, 0xC0, 0x2D, 0x00, 0x3F, 0x00, 0xFC, 0x00,
-0xF0, 0x0E, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0x9C, 0x02, 0xF0, 0x0B, 0xC0, 0x3F,
-0x00, 0x3F, 0x00, 0xBC, 0x00, 0x78, 0x03, 0xC0, 0x39, 0x00, 0x3E, 0x00, 0xDC,
-0x80, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0xA7, 0x00, 0xFE, 0x03, 0xF0, 0x4B, 0xE0,
-0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xDF, 0x00, 0xB3,
-0x08, 0xFC, 0x06, 0x70, 0x9F, 0xC8, 0x7E, 0x12, 0xF3, 0x09, 0xEC, 0x27, 0x11,
-0x1F, 0xC0, 0x7C, 0x00, 0xE3, 0x09, 0xDC, 0x27, 0xF0, 0x1F, 0xC0, 0x7C, 0x40,
-0xF3, 0x09, 0xBC, 0x0F, 0xF8, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0x9C, 0x07,
-0xF0, 0x1F, 0xC0, 0x5C, 0x00, 0x33, 0x01, 0xCC, 0x06, 0xF0, 0x1B, 0xC8, 0x0D,
-0x08, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x27, 0x01, 0x91, 0x20,
-0x44, 0x53, 0x10, 0x01, 0x40, 0x06, 0x00, 0x15, 0x00, 0x50, 0x00, 0x50, 0x11,
-0x40, 0x44, 0x08, 0x15, 0x00, 0x04, 0x10, 0xD2, 0x01, 0x41, 0x45, 0x00, 0x11,
-0x80, 0x74, 0x00, 0xD0, 0x11, 0x42, 0x03, 0x25, 0x11, 0x04, 0x64, 0x04, 0xD1,
-0x1F, 0x48, 0x74, 0x40, 0x15, 0x81, 0x54, 0x02, 0xD2, 0x09, 0x42, 0x0F, 0x60,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x00, 0xC1, 0x44, 0x14,
-0x13, 0x50, 0x4D, 0x48, 0x37, 0x11, 0xD1, 0x84, 0x46, 0x13, 0x10, 0x0C, 0x62,
-0x30, 0x20, 0xC5, 0x04, 0x14, 0x03, 0xD0, 0x4D, 0x40, 0x30, 0x00, 0xC9, 0x44,
-0x14, 0x13, 0xD0, 0x0C, 0x40, 0x36, 0x10, 0xD5, 0x00, 0x14, 0x03, 0x58, 0x0C,
-0x40, 0x21, 0x00, 0x15, 0x20, 0x14, 0x00, 0xD8, 0x00, 0x40, 0x4F, 0x80, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x25, 0x10, 0xD1, 0x21, 0x64, 0x07,
-0x10, 0x01, 0x40, 0x07, 0x00, 0x15, 0x00, 0x54, 0x00, 0x50, 0x01, 0x70, 0x04,
-0x00, 0x15, 0x00, 0x54, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x19, 0x00, 0x74,
-0x00, 0xD0, 0x01, 0x42, 0x07, 0x00, 0x11, 0x00, 0x64, 0x00, 0xD0, 0x0D, 0x00,
-0x25, 0x00, 0x15, 0x01, 0x54, 0x44, 0xD0, 0x11, 0x41, 0x0F, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x13, 0x03, 0xD3, 0x31, 0x7C, 0x17, 0x70,
-0x0C, 0xC0, 0x37, 0x00, 0xD3, 0x00, 0x0C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x30,
-0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0x02, 0x34, 0x00, 0xDB, 0x00, 0x7C, 0x03,
-0xD0, 0x0D, 0x40, 0x37, 0x20, 0xC7, 0x40, 0x5C, 0x03, 0xF0, 0x0D, 0xD0, 0x15,
-0x00, 0x06, 0x01, 0x5C, 0x0E, 0xF0, 0x39, 0xC0, 0x09, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0x80, 0x2D, 0x40, 0xDF, 0x00, 0xDC, 0x03, 0xF0, 0x03,
-0xC0, 0x0C, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x40, 0x3B,
-0x00, 0xEC, 0x00, 0xF0, 0x03, 0x08, 0x0F, 0x00, 0x37, 0x00, 0xFC, 0x00, 0xF0,
-0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xCC, 0x00, 0xD0, 0x0F, 0xC0, 0x3E, 0x81,
-0xBB, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x08, 0xB5, 0x00, 0xDF, 0x00, 0x4D, 0x03, 0x70, 0x8D, 0xC0,
-0x37, 0x01, 0xD3, 0x00, 0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x37, 0x01, 0xD7, 0x00,
-0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x01, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D,
-0xC2, 0x34, 0x00, 0xD7, 0x00, 0x6C, 0x13, 0xB0, 0x0C, 0xC0, 0x24, 0x01, 0x9F,
-0x00, 0x7C, 0x08, 0xF0, 0x21, 0x48, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x11, 0x40, 0x00,
-0x04, 0x0B, 0x00, 0x5C, 0x00, 0xB0, 0x00, 0x40, 0x83, 0x00, 0x1B, 0x00, 0x6E,
-0x00, 0x10, 0x00, 0x40, 0xC3, 0x00, 0x1D, 0x00, 0x5C, 0x00, 0x10, 0x01, 0xE8,
-0x03, 0x00, 0x11, 0x80, 0x44, 0x40, 0x10, 0x0D, 0xC0, 0x20, 0x01, 0x9D, 0x00,
-0x5C, 0x00, 0xD0, 0x11, 0x41, 0x4F, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0x20, 0x22, 0x00, 0x9D, 0x00, 0x44, 0x03, 0x50, 0x0C, 0x40, 0xB1, 0x00,
-0xC5, 0x00, 0x14, 0x03, 0x10, 0x1C, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x04, 0x03,
-0x10, 0x0C, 0x48, 0x73, 0x00, 0xC9, 0x00, 0x34, 0x83, 0x90, 0x0C, 0x40, 0x30,
-0x00, 0xC5, 0x00, 0x24, 0x07, 0x80, 0x0C, 0x40, 0xE3, 0x00, 0x4D, 0x05, 0x36,
-0x12, 0xD0, 0x48, 0x40, 0x4F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x08, 0x6A, 0x00, 0xED, 0x09, 0x86, 0x07, 0x10, 0x13, 0x60, 0x4C, 0x00, 0x2D,
-0x01, 0xD4, 0x04, 0x90, 0x12, 0x40, 0x4F, 0x00, 0x38, 0x01, 0xA4, 0x04, 0x1C,
-0x12, 0x40, 0x4B, 0x04, 0x2D, 0x01, 0xD4, 0x04, 0x00, 0x13, 0x40, 0x49, 0x00,
-0x21, 0x01, 0xC4, 0x04, 0x50, 0x1C, 0x40, 0x79, 0x00, 0xED, 0x11, 0x94, 0x07,
-0xD0, 0x9A, 0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10,
-0x32, 0x02, 0x0D, 0x08, 0x4C, 0x03, 0x50, 0x0C, 0x40, 0x31, 0x12, 0xD7, 0x00,
-0x1C, 0x03, 0x30, 0x0C, 0x40, 0x33, 0x00, 0xC7, 0x00, 0x04, 0x03, 0x30, 0x0C,
-0xC0, 0x33, 0x00, 0xCF, 0x08, 0x34, 0x13, 0xB0, 0x0D, 0x40, 0x30, 0x02, 0xD7,
-0x00, 0x2C, 0x03, 0xB0, 0x0C, 0xD0, 0x23, 0x02, 0xCF, 0x20, 0x3C, 0x42, 0xF0,
-0x8C, 0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x2D,
-0x00, 0x7F, 0x08, 0xF8, 0x03, 0xE0, 0x02, 0x80, 0x09, 0x00, 0x3B, 0x00, 0xA8,
-0x20, 0xF2, 0x81, 0xC0, 0x0B, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC8,
-0x07, 0x00, 0x3F, 0x28, 0x7C, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x40,
-0x54, 0x24, 0x20, 0x9D, 0xC0, 0x2C, 0x08, 0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x8F,
-0xC2, 0x0B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x27, 0x00,
-0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x1D, 0xC0, 0x35, 0x00, 0xDE, 0x00, 0x7C, 0x07,
-0x30, 0x1D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x30, 0x1D, 0xC0, 0x34,
-0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x3C,
-0x03, 0xB0, 0x0D, 0xC4, 0x24, 0x00, 0x5F, 0x00, 0x7C, 0x83, 0x30, 0x0D, 0xC2,
-0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xFD,
-0x00, 0x84, 0x03, 0xD0, 0x03, 0x40, 0x08, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0x50,
-0x02, 0x00, 0x08, 0x88, 0x2D, 0x00, 0xB4, 0x00, 0x50, 0x02, 0x40, 0x09, 0x00,
-0x2F, 0x00, 0xA4, 0x00, 0xD1, 0x02, 0x48, 0x0B, 0x00, 0x2D, 0x20, 0xB6, 0x00,
-0x18, 0x4E, 0x40, 0x38, 0x20, 0xED, 0x00, 0xF4, 0x01, 0x10, 0x07, 0x40, 0x4C,
-0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0x6D, 0x00,
-0x84, 0x47, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x81, 0xF4, 0x07, 0x18, 0x1F,
-0x48, 0x78, 0x80, 0xED, 0x01, 0xF6, 0x07, 0x13, 0x1F, 0x44, 0x7B, 0x80, 0xED,
-0x01, 0xB4, 0x87, 0x58, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xF4, 0x07, 0xD8,
-0xDE, 0x40, 0x6A, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x23, 0x00, 0x4C, 0x00, 0x04,
-0x05, 0xD0, 0x00, 0x40, 0x00, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00, 0x40,
-0x00, 0xA0, 0x0D, 0x00, 0x74, 0x00, 0x50, 0x00, 0x40, 0x03, 0x10, 0x05, 0x00,
-0x34, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x20, 0x34, 0x00, 0x51, 0x0C,
-0x50, 0x22, 0x00, 0x8D, 0x0F, 0x74, 0x0F, 0x1A, 0x6D, 0x40, 0x58, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x1F, 0x00, 0x7F, 0x10, 0xCC, 0x0D,
-0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xD0, 0x14,
-0x00, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5D, 0x00, 0x7C,
-0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x3C, 0x01, 0xF0, 0x04, 0xC0,
-0x1A, 0x00, 0x7F, 0x00, 0xFC, 0x0D, 0x34, 0x07, 0xD0, 0x5C, 0x20, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x20, 0x7C, 0x40, 0xF2,
-0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x8F, 0x00,
-0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3D, 0x00, 0xE4, 0x00,
-0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x08, 0x90, 0x01, 0xC0, 0x05,
-0x00, 0x1F, 0x00, 0x7C, 0x28, 0xF0, 0x81, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x00, 0x65, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x19,
-0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9F,
-0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0xE7, 0x80, 0x9F, 0x00, 0x4D, 0x02, 0x34,
-0x09, 0xC0, 0x27, 0x00, 0x9B, 0x00, 0x7C, 0x06, 0x72, 0x09, 0xC0, 0x24, 0x00,
-0x93, 0x05, 0x7C, 0x42, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x28, 0x66, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x19, 0x40,
-0x27, 0x00, 0x8D, 0x00, 0x44, 0x02, 0xD8, 0x19, 0x40, 0xE7, 0x20, 0x9D, 0x00,
-0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x04, 0x97, 0x20, 0x44, 0x02, 0x30, 0x09,
-0x40, 0x23, 0x00, 0x91, 0x20, 0x70, 0x16, 0x30, 0x0B, 0xD0, 0x24, 0x00, 0x91,
-0x00, 0x74, 0x96, 0x50, 0x39, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1C, 0xA0, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x89, 0x40, 0x6F,
-0x00, 0xBD, 0x00, 0xD4, 0x02, 0xD0, 0xAB, 0x40, 0x2F, 0x00, 0xBD, 0x00, 0xF4,
-0x02, 0x10, 0x0B, 0x60, 0x2F, 0x00, 0xAD, 0x00, 0x84, 0x02, 0x10, 0x0B, 0x40,
-0x2F, 0x80, 0xB9, 0x00, 0xF4, 0x12, 0x10, 0x69, 0x60, 0x36, 0x00, 0xD9, 0x02,
-0x74, 0x06, 0x10, 0x19, 0x41, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x28, 0xA0, 0x00, 0x8D, 0x1C, 0x34, 0x22, 0xD0, 0x2A, 0x40, 0xEB, 0x00,
-0xBD, 0x08, 0x84, 0x22, 0xD0, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB0, 0x22,
-0x10, 0x8A, 0x40, 0x2B, 0x00, 0xA5, 0x88, 0x84, 0x22, 0x10, 0x0A, 0x40, 0x2F,
-0x02, 0xA1, 0x08, 0xB4, 0x02, 0x14, 0x08, 0x64, 0x24, 0x08, 0x89, 0x00, 0x34,
-0x02, 0x50, 0x09, 0x40, 0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xB0, 0x06, 0x00, 0x1F, 0x06, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F,
-0x02, 0x5C, 0x08, 0xD0, 0x01, 0xC0, 0x17, 0x00, 0x1D, 0x8A, 0x7C, 0x08, 0x34,
-0x21, 0xC0, 0x07, 0x00, 0x1D, 0x02, 0x44, 0x08, 0x30, 0x01, 0xC0, 0x87, 0x00,
-0x1B, 0x02, 0xFC, 0x00, 0x70, 0x11, 0xC0, 0x06, 0x40, 0x1B, 0x00, 0x7C, 0x28,
-0x32, 0xA1, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0,
-0x6F, 0x00, 0xBF, 0x04, 0xFC, 0x12, 0xF0, 0x19, 0x40, 0x67, 0x00, 0x9F, 0x44,
-0x3C, 0x12, 0xF2, 0x08, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x7C, 0x12, 0xF0, 0x48,
-0xC0, 0x27, 0x00, 0x97, 0x84, 0x7C, 0x12, 0x70, 0x09, 0xC2, 0x27, 0x01, 0x9F,
-0x84, 0x7C, 0x02, 0x70, 0x28, 0xC0, 0x2D, 0x00, 0xB7, 0x00, 0xFC, 0x02, 0xF0,
-0x0B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F,
-0x00, 0x93, 0x2C, 0x7C, 0x02, 0xF0, 0x0B, 0xC0, 0xAB, 0x00, 0x97, 0x00, 0x7C,
-0x02, 0xF0, 0x0B, 0xC0, 0x28, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC8,
-0x2D, 0x00, 0x93, 0x08, 0x5C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x02, 0x9F, 0x00,
-0xDC, 0x02, 0xB0, 0x1B, 0xC3, 0x2B, 0x00, 0xBF, 0x60, 0xFC, 0x82, 0x30, 0x0B,
-0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x54, 0x45,
-0x51, 0x4C, 0x74, 0x40, 0xD0, 0x51, 0x41, 0x47, 0x01, 0x11, 0x14, 0x74, 0x10,
-0xD0, 0x01, 0x40, 0x04, 0x08, 0x1D, 0x05, 0x74, 0x80, 0xD2, 0x41, 0x41, 0x04,
-0x00, 0x11, 0x04, 0x4C, 0x40, 0x10, 0x01, 0xC0, 0x05, 0x00, 0x1D, 0x14, 0x74,
-0x00, 0x10, 0x21, 0x42, 0x07, 0x08, 0x5D, 0x00, 0x74, 0x00, 0x50, 0x05, 0x40,
-0x73, 0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x21, 0x00, 0x81,
-0x04, 0x34, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x01, 0x85, 0x04, 0x34, 0x52, 0xD0,
-0x09, 0x62, 0x21, 0x00, 0x8D, 0x10, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x25, 0x00,
-0x91, 0x04, 0x54, 0x12, 0x50, 0x08, 0x48, 0x23, 0x80, 0x8D, 0x04, 0x14, 0x02,
-0xD2, 0x08, 0x48, 0x23, 0x20, 0x8D, 0x20, 0x74, 0x02, 0x18, 0x08, 0x40, 0x4B,
-0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x25, 0x00, 0x91, 0x00,
-0x74, 0x0A, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09,
-0x00, 0x25, 0x80, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91,
-0x00, 0x54, 0x02, 0x10, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10,
-0x0D, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x76, 0x02, 0x50, 0x09, 0x40, 0x63, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x6F, 0x00, 0x93, 0x02, 0x78,
-0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x08, 0xC0,
-0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0x48, 0x21, 0x40, 0x81, 0x00,
-0x54, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x1C, 0x02, 0xB0, 0x09,
-0xC0, 0xE7, 0x81, 0x9F, 0x02, 0x78, 0x42, 0x32, 0x29, 0xC0, 0x17, 0x20, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xA5, 0x00, 0x9F, 0x04, 0x7C, 0x26,
-0xF1, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x26,
-0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27, 0x08, 0x9F, 0x00, 0x4C,
-0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xBC, 0x09, 0xC0,
-0x67, 0x01, 0x9F, 0x09, 0x7C, 0x02, 0xF1, 0x49, 0xC0, 0x4B, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x02, 0x4D, 0x00, 0xF0,
-0x01, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x7E, 0x00, 0x70, 0x01, 0xC0, 0x04, 0x00,
-0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xE2, 0x07, 0x08, 0x1B, 0x00, 0x4C, 0x00,
-0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0xF0, 0x41, 0xC8, 0x87,
-0x40, 0x17, 0x00, 0x7C, 0x00, 0x34, 0x01, 0x87, 0x40, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x80, 0x54, 0x80, 0x5D, 0x00, 0x44, 0x01, 0x70, 0x45,
-0x40, 0x1C, 0x00, 0x5B, 0x00, 0x74, 0x01, 0x70, 0x07, 0x60, 0x9C, 0x00, 0x51,
-0x00, 0x74, 0x01, 0xD8, 0x05, 0xC0, 0x1F, 0x00, 0x55, 0x00, 0x1E, 0x01, 0x72,
-0x05, 0x40, 0x17, 0x08, 0x53, 0x00, 0xCC, 0x0D, 0xC0, 0x07, 0xC0, 0xDD, 0x01,
-0x70, 0x0A, 0xF0, 0x35, 0x10, 0x17, 0x50, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0xA0, 0x36, 0x10, 0xCD, 0x00, 0x16, 0x03, 0x50, 0x0C, 0x40,
-0x62, 0x00, 0xC1, 0x00, 0x34, 0x03, 0x58, 0x98, 0x48, 0xF3, 0x06, 0xCD, 0x00,
-0x34, 0x03, 0xD2, 0x0D, 0x40, 0xB3, 0x01, 0xC1, 0x00, 0x04, 0x03, 0x50, 0x0C,
-0x40, 0x33, 0x80, 0xC9, 0x00, 0x14, 0x0A, 0x90, 0x34, 0x40, 0xE3, 0x01, 0x81,
-0x02, 0x74, 0x03, 0x90, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x88, 0xB8, 0x11, 0xED, 0xA5, 0x96, 0x13, 0x50, 0x5E, 0x40, 0x9C,
-0x01, 0xE9, 0x08, 0xB4, 0x03, 0x50, 0x0B, 0x40, 0x5F, 0x00, 0xE9, 0x04, 0xB4,
-0x13, 0xD8, 0x0E, 0x40, 0x3D, 0x00, 0xF5, 0x00, 0x96, 0x13, 0x50, 0x0E, 0x40,
-0x7F, 0x03, 0xE1, 0x05, 0x90, 0x0B, 0xD0, 0x26, 0x60, 0x6D, 0x00, 0xE1, 0x82,
-0xB4, 0x02, 0x90, 0x1E, 0x41, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x11, 0x10, 0xF8, 0x00, 0xFD, 0x07, 0x9C, 0x17, 0x70, 0x1F, 0xC0, 0xFA, 0x01,
-0xE3, 0x01, 0xB4, 0x17, 0x70, 0x1E, 0x50, 0x6B, 0x00, 0xED, 0x05, 0xBC, 0x47,
-0xD0, 0x9E, 0x68, 0x7B, 0x08, 0xEB, 0x01, 0x84, 0x17, 0x70, 0x1E, 0xC0, 0x7B,
-0x00, 0xFB, 0x09, 0x9C, 0x07, 0xF0, 0x1E, 0x80, 0x6B, 0x00, 0xE6, 0x21, 0xFC,
-0x06, 0xB0, 0x1B, 0xC0, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA8, 0x35, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0x70, 0x89, 0xC0, 0x17, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xC0, 0x24, 0x18, 0xD7, 0x00, 0x7C, 0xB3, 0xF0,
-0x4D, 0xC2, 0x23, 0x00, 0xC7, 0x92, 0x7C, 0x4B, 0x70, 0x0D, 0xC0, 0xB3, 0x04,
-0xDB, 0x08, 0x6C, 0x03, 0xF0, 0x0D, 0x80, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x02,
-0x70, 0x01, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-0x79, 0x00, 0xE3, 0x04, 0xCD, 0x53, 0x70, 0x1B, 0xC0, 0x7F, 0x40, 0xF2, 0x01,
-0xDC, 0x67, 0xF0, 0x1B, 0xC0, 0x6F, 0x00, 0xEF, 0x19, 0xCC, 0x07, 0x30, 0x1F,
-0x85, 0x7F, 0x00, 0xF3, 0x11, 0xFC, 0x67, 0x70, 0x1F, 0xC0, 0x7D, 0x00, 0xF7,
-0x01, 0xCD, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x00, 0xFF, 0xC1, 0xF4, 0x07, 0xF2,
-0x1B, 0xC4, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39,
-0x00, 0xE1, 0x00, 0xAC, 0x03, 0x10, 0x0A, 0x40, 0x1B, 0x00, 0xE1, 0x08, 0xDC,
-0xC3, 0x11, 0x0A, 0xC0, 0x09, 0x09, 0xED, 0x00, 0x94, 0x23, 0x50, 0x0E, 0x42,
-0x1B, 0x00, 0xE1, 0x04, 0xDC, 0x03, 0x10, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x00,
-0x84, 0x2B, 0xD0, 0x86, 0x40, 0x2B, 0x06, 0x6D, 0x08, 0xB4, 0x11, 0xD0, 0x4F,
-0xC0, 0x56, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00,
-0xF1, 0x00, 0xC4, 0x23, 0x50, 0x8E, 0x41, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x03,
-0x59, 0x8A, 0x41, 0x2A, 0x30, 0xFD, 0x10, 0xE6, 0x03, 0x90, 0x0E, 0x40, 0x3F,
-0x06, 0xE1, 0x20, 0xA6, 0x03, 0x51, 0x0F, 0x40, 0x39, 0x02, 0xED, 0x00, 0xA4,
-0x43, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x02, 0xD2, 0x0A, 0x40,
-0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x25, 0x02, 0xC1,
-0x09, 0x24, 0x07, 0x10, 0x08, 0x60, 0x53, 0x0E, 0xC1, 0x0A, 0x34, 0x07, 0x12,
-0x08, 0x41, 0xA3, 0x20, 0xCD, 0x02, 0x34, 0x1F, 0x50, 0x3C, 0x40, 0x43, 0x00,
-0xD1, 0x0B, 0x14, 0x37, 0x10, 0x3C, 0x40, 0x74, 0x00, 0xCD, 0x05, 0x24, 0x17,
-0xD1, 0x0C, 0x40, 0x23, 0x00, 0x4D, 0x26, 0x34, 0x18, 0xD0, 0x00, 0x42, 0x12,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x25, 0x40, 0xF3, 0x00,
-0xCD, 0x1B, 0x70, 0x2D, 0xC0, 0xB3, 0x00, 0xF3, 0x8A, 0xFC, 0x0B, 0x70, 0x18,
-0xC0, 0x26, 0x04, 0xFE, 0x01, 0xEC, 0x4F, 0xB0, 0x5F, 0xC0, 0x27, 0x40, 0xF3,
-0x00, 0xFC, 0x0B, 0x70, 0x9C, 0xC0, 0xBD, 0x02, 0xE7, 0x06, 0x6C, 0x0F, 0xD0,
-0x05, 0xC0, 0xE7, 0x00, 0x8D, 0x06, 0x7E, 0x00, 0xF0, 0x01, 0xD0, 0x56, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x04, 0xDF, 0x00, 0x7C,
-0x43, 0xF0, 0x0D, 0xC0, 0xB7, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0x70, 0x29, 0xC0,
-0x05, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0xA7, 0x88, 0xDF, 0x00,
-0x7C, 0x03, 0x72, 0x8D, 0xC0, 0x37, 0x82, 0xDF, 0x00, 0x5C, 0x0B, 0xB0, 0x25,
-0x88, 0xA7, 0x09, 0x9F, 0x02, 0x7C, 0x0C, 0xF0, 0x01, 0xC1, 0x05, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xFB, 0x00, 0xFC, 0x03,
-0xF0, 0x0F, 0xC1, 0x5F, 0x08, 0xF3, 0x00, 0xFC, 0x43, 0xF0, 0x03, 0xC2, 0x2C,
-0x0C, 0xFF, 0x10, 0xF8, 0x83, 0xF0, 0x0F, 0xC1, 0x0D, 0x04, 0xFB, 0x90, 0xCC,
-0x03, 0xF1, 0x0F, 0xC0, 0x3F, 0x00, 0xF7, 0x40, 0xE8, 0x03, 0xD0, 0x27, 0xC0,
-0x6F, 0x00, 0x33, 0x00, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x13, 0x22, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x08, 0xD1, 0x00, 0x74, 0x83, 0xD0,
-0x09, 0x60, 0x16, 0x0A, 0xD1, 0x00, 0x74, 0x03, 0xD2, 0x15, 0x40, 0x64, 0x00,
-0xDD, 0x00, 0x5C, 0x03, 0xD0, 0x0D, 0x40, 0xC4, 0x04, 0xDD, 0x00, 0x44, 0x03,
-0xD8, 0x0D, 0x40, 0x34, 0x00, 0xD1, 0x00, 0x44, 0x07, 0xC0, 0x25, 0x42, 0xE3,
-0xC0, 0x13, 0x05, 0x44, 0x4E, 0xD0, 0x31, 0x40, 0x17, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0xA2, 0x64, 0x20, 0xD9, 0x00, 0x74, 0x03, 0xD0, 0x09,
-0x48, 0x37, 0x04, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x19, 0x41, 0x45, 0x20, 0xDD,
-0x00, 0x74, 0x03, 0x50, 0x0C, 0x40, 0x67, 0x00, 0xDD, 0x00, 0x64, 0x03, 0xD0,
-0x0D, 0x40, 0x36, 0x00, 0xD5, 0x00, 0x76, 0x07, 0xD0, 0x05, 0x40, 0xB7, 0x01,
-0x91, 0x01, 0x44, 0x04, 0xD2, 0x39, 0x42, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x28, 0x20, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40,
-0x33, 0x08, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x09, 0x40, 0x40, 0x00, 0xCD, 0x00,
-0x14, 0x03, 0xD0, 0x0C, 0x40, 0x00, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0D,
-0x40, 0x30, 0x00, 0xD1, 0x00, 0x16, 0x83, 0xD0, 0x04, 0x40, 0x13, 0x10, 0x01,
-0x00, 0x05, 0x00, 0xD0, 0x08, 0x60, 0x43, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xB0, 0x26, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x48, 0x13,
-0x40, 0xD3, 0x80, 0x7C, 0x03, 0xF1, 0x01, 0xD0, 0x04, 0x00, 0xDE, 0x00, 0xFC,
-0x03, 0x72, 0x0F, 0xC4, 0x05, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0xD0, 0x0D, 0xC0,
-0x3E, 0x00, 0xE7, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC4, 0x37, 0x88, 0x11, 0x00,
-0x4C, 0x82, 0xF0, 0x09, 0xC0, 0x01, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0xA8, 0x2F, 0x10, 0xFF, 0x00, 0xBC, 0x03, 0xF0, 0x0B, 0xC0, 0x1E, 0x00,
-0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x07, 0xC0, 0x0E, 0x00, 0xFF, 0x00, 0x9C, 0x03,
-0xF0, 0x0F, 0xC8, 0x0B, 0x00, 0xFF, 0x00, 0xDC, 0x03, 0xF0, 0x0E, 0x40, 0x3F,
-0x00, 0xFF, 0x00, 0xEC, 0x01, 0xF0, 0x0B, 0xC2, 0x1F, 0x08, 0x37, 0x00, 0xFC,
-0x00, 0xE1, 0x03, 0xC0, 0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA0, 0x2F, 0x00, 0x3B, 0x14, 0xBC, 0x0F, 0x34, 0x1F, 0xC0, 0x7E, 0x02, 0xFF,
-0x09, 0xFC, 0x07, 0xB0, 0x1F, 0xC0, 0x7C, 0x00, 0xF3, 0x09, 0x8C, 0x27, 0x72,
-0x1F, 0xC4, 0x7E, 0x02, 0xFB, 0x29, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x20,
-0xF3, 0x09, 0xCC, 0x27, 0x30, 0x83, 0xC2, 0x7C, 0x02, 0xF3, 0x24, 0xEE, 0x1A,
-0x30, 0x4B, 0xC4, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
-0x27, 0x20, 0x01, 0x02, 0x74, 0x13, 0x18, 0x11, 0x40, 0x00, 0x00, 0x1D, 0x80,
-0x74, 0x04, 0x40, 0x11, 0x40, 0x00, 0x04, 0x11, 0x00, 0x44, 0x10, 0x10, 0x40,
-0x40, 0x00, 0x00, 0x11, 0x04, 0x44, 0x04, 0xD0, 0x11, 0x41, 0x44, 0x00, 0x13,
-0x44, 0x44, 0x10, 0x30, 0x65, 0x40, 0x34, 0x00, 0xF5, 0x0B, 0x6E, 0x10, 0x10,
-0x11, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x02,
-0x40, 0x01, 0x40, 0x36, 0x03, 0x50, 0x0D, 0x50, 0x30, 0x01, 0xCD, 0x84, 0x34,
-0x03, 0x81, 0x0D, 0x50, 0x30, 0x01, 0xC1, 0x00, 0x24, 0x13, 0xD0, 0x0C, 0x41,
-0x30, 0x01, 0xC1, 0x04, 0x24, 0x03, 0xD0, 0x4D, 0x40, 0x34, 0x00, 0xC9, 0x04,
-0x24, 0x03, 0x10, 0x28, 0x40, 0x31, 0x81, 0xCD, 0x20, 0x04, 0x1A, 0x11, 0x88,
-0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x15, 0x00,
-0x11, 0x22, 0x34, 0x03, 0x50, 0x01, 0x44, 0x04, 0x00, 0x1D, 0x00, 0x74, 0x80,
-0x90, 0x01, 0x40, 0x04, 0x00, 0x01, 0x00, 0x24, 0x00, 0x90, 0x01, 0x40, 0x04,
-0x00, 0x01, 0x00, 0x67, 0x00, 0xD0, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x64,
-0x00, 0x10, 0x4D, 0x42, 0x36, 0x08, 0xDD, 0x00, 0x47, 0x04, 0x10, 0x19, 0x41,
-0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x40, 0x1B,
-0x01, 0x7C, 0x27, 0x50, 0x0C, 0xC8, 0x34, 0x20, 0xDF, 0x80, 0x3C, 0x03, 0xB4,
-0x0C, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00,
-0xD3, 0x00, 0x6C, 0x03, 0xF2, 0x0C, 0x80, 0x30, 0x00, 0xDB, 0x00, 0x6D, 0x03,
-0x34, 0x01, 0xD1, 0x35, 0x00, 0xDF, 0x40, 0x44, 0x04, 0x22, 0x31, 0xC0, 0x01,
-0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x69, 0x01, 0x3F, 0x03,
-0xF8, 0x03, 0xB0, 0x03, 0x80, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0x70, 0x03,
-0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xDD, 0x00, 0x70, 0x03, 0xD0, 0x0D, 0x00, 0x37,
-0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC4, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1,
-0x07, 0xC0, 0x3D, 0x20, 0xF7, 0x00, 0xF4, 0x00, 0xF5, 0x03, 0xC3, 0x1E, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x81, 0x37, 0x0A, 0x4D,
-0x03, 0x30, 0x0D, 0xC0, 0x77, 0x41, 0xD3, 0x05, 0x5C, 0x03, 0x30, 0x8D, 0xC0,
-0x35, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x01,
-0x4C, 0x03, 0x70, 0x0D, 0xC0, 0x34, 0x02, 0xD7, 0x01, 0x7C, 0x03, 0xF0, 0x09,
-0xC0, 0x37, 0x00, 0xDF, 0x10, 0x74, 0x8A, 0x33, 0x21, 0xC4, 0x0B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4, 0x00, 0x11, 0x81, 0x44, 0x03,
-0x10, 0x41, 0x44, 0x47, 0x00, 0x11, 0x03, 0x74, 0x00, 0xB0, 0x11, 0x40, 0x04,
-0x00, 0x11, 0x20, 0x74, 0x00, 0x14, 0x01, 0x48, 0x04, 0x00, 0x10, 0x01, 0x44,
-0x44, 0xD0, 0x11, 0x40, 0x44, 0x08, 0x11, 0x01, 0x64, 0x00, 0xD0, 0x0D, 0xC0,
-0x37, 0x10, 0xE0, 0x13, 0x34, 0x04, 0x10, 0x30, 0x00, 0x4F, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x00, 0x41, 0x00, 0x25, 0x03, 0x50,
-0x1C, 0x40, 0xB3, 0x00, 0xC9, 0x02, 0x34, 0x43, 0x90, 0x0C, 0x41, 0x35, 0x80,
-0xC1, 0x00, 0x34, 0x03, 0x10, 0x0D, 0x40, 0x36, 0x00, 0xC1, 0x00, 0x34, 0x07,
-0x50, 0x8C, 0x40, 0x71, 0x80, 0xC9, 0x00, 0x74, 0x03, 0xD0, 0x01, 0x40, 0x36,
-0x08, 0xC4, 0x02, 0x34, 0x02, 0x54, 0x28, 0x02, 0x1F, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x80, 0x78, 0x40, 0x61, 0x09, 0xE4, 0x07, 0x10, 0x12,
-0x40, 0x4B, 0x00, 0x29, 0x09, 0xB4, 0x24, 0x90, 0x92, 0x40, 0x48, 0x00, 0x21,
-0x01, 0xF6, 0x24, 0x10, 0x12, 0x40, 0x4A, 0x00, 0x21, 0x01, 0xB4, 0x04, 0xD0,
-0x13, 0x40, 0x4D, 0x08, 0x29, 0x09, 0xA6, 0x04, 0xC0, 0x12, 0x40, 0x7B, 0x30,
-0xE9, 0x01, 0xB4, 0x66, 0x50, 0x12, 0x41, 0x1B, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x10, 0x04, 0x40, 0x45, 0x00, 0x2C, 0x03, 0x70, 0x8C, 0xC0,
-0x33, 0x00, 0xCB, 0x00, 0x1C, 0x23, 0x30, 0x0C, 0xC0, 0x31, 0x90, 0xC3, 0x00,
-0x3C, 0x03, 0x30, 0x0C, 0xC0, 0x32, 0x00, 0xD3, 0x00, 0x34, 0x03, 0x70, 0x0C,
-0xC0, 0x31, 0x00, 0xCE, 0x80, 0x3E, 0x03, 0xF0, 0x00, 0xC0, 0x37, 0x00, 0xC7,
-0x08, 0x3C, 0x22, 0x70, 0x08, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0xB0, 0x1D, 0x00, 0x7F, 0x00, 0xDE, 0x03, 0xF0, 0x03, 0x60, 0x0F,
-0x00, 0x37, 0x00, 0xBC, 0x20, 0xF0, 0x02, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xF4,
-0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3F, 0x00, 0xCD, 0x00, 0xF0, 0x02, 0xC0,
-0x0A, 0x00, 0x37, 0x80, 0xEE, 0x04, 0xF0, 0x03, 0xC0, 0x3D, 0x82, 0xF7, 0x38,
-0xBC, 0x22, 0xB0, 0x89, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0xA0, 0x37, 0x40, 0x13, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x40,
-0xD3, 0x01, 0x0D, 0x03, 0xB0, 0x1C, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x3C, 0x07,
-0xB4, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x0D, 0x07, 0x30, 0x0D, 0xC0, 0x37,
-0x00, 0xDF, 0x01, 0x6D, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x80, 0xDF, 0x04, 0x3C,
-0x00, 0x30, 0x19, 0xC0, 0x54, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x88, 0x39, 0x00, 0x31, 0x00, 0x85, 0x03, 0xD0, 0x02, 0x40, 0x0F, 0x00, 0x31,
-0x00, 0x84, 0x00, 0x30, 0x02, 0x40, 0x08, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0x10,
-0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0xA4, 0x00, 0x70, 0x02, 0x40, 0x0B, 0x00,
-0x37, 0x00, 0x8C, 0x80, 0xD0, 0x0E, 0xC0, 0x39, 0x00, 0xED, 0x14, 0x9C, 0x00,
-0x14, 0x03, 0xC0, 0x4A, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
-0x79, 0x00, 0x29, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xE1, 0x01,
-0x94, 0x07, 0x90, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xF4, 0x07, 0x10, 0x1E,
-0x40, 0x7B, 0x00, 0xED, 0x01, 0xA4, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x00, 0xED,
-0x01, 0x84, 0x87, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x85, 0x94, 0x06, 0x55,
-0x1B, 0x40, 0x0D, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x77,
-0x02, 0x91, 0x10, 0x04, 0x06, 0xD0, 0x00, 0x40, 0x07, 0x00, 0x01, 0x00, 0x14,
-0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x0C, 0x00, 0x34, 0x00, 0x10, 0x00, 0x40,
-0x03, 0x00, 0x0D, 0x00, 0x24, 0x00, 0x50, 0x01, 0x40, 0x03, 0x10, 0x05, 0x40,
-0x04, 0x00, 0xD0, 0xEC, 0x40, 0x31, 0x00, 0xCD, 0x00, 0x14, 0x0B, 0x50, 0x8C,
-0x40, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x9D, 0x00,
-0x7B, 0x87, 0x6C, 0x41, 0xF1, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x5C, 0x01,
-0xB4, 0x05, 0xC8, 0x14, 0x10, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC4, 0x17,
-0x00, 0x5F, 0x00, 0x44, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C,
-0x01, 0x70, 0x37, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x9E, 0x21, 0x50, 0xB7, 0x40,
-0x5D, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x04, 0x1F,
-0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xE8, 0x00, 0x70,
-0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
-0x3F, 0x00, 0xDC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x20, 0xDC, 0x00,
-0xF0, 0x01, 0xE0, 0x05, 0x00, 0x1F, 0x00, 0x5E, 0x80, 0x90, 0x01, 0x80, 0x4A,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x26, 0x02, 0x93, 0x00,
-0x5C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x16, 0x30, 0x09,
-0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93,
-0x00, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x30,
-0x09, 0xC0, 0x24, 0x10, 0x9F, 0x80, 0x7E, 0x26, 0x30, 0x89, 0xC2, 0x43, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x00, 0x91, 0x20, 0x44,
-0x02, 0x90, 0x19, 0x44, 0xA7, 0x00, 0x91, 0x02, 0x34, 0x02, 0x10, 0x09, 0x40,
-0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x08, 0x50, 0x20, 0x40, 0x91, 0x02,
-0x74, 0x02, 0xD0, 0x19, 0x40, 0x24, 0x00, 0x9F, 0x02, 0x34, 0x02, 0x10, 0x09,
-0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x06, 0x14, 0x39, 0x40, 0x07, 0x00, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x00, 0x44, 0x02,
-0xD0, 0x09, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40, 0x2F,
-0x00, 0xBD, 0x00, 0xF4, 0x82, 0xD0, 0x0B, 0x40, 0x2C, 0x00, 0xB1, 0x00, 0xF4,
-0x22, 0xD0, 0x4B, 0x40, 0x2E, 0x01, 0xBD, 0x00, 0xF4, 0x02, 0x10, 0x08, 0x40,
-0x24, 0x00, 0x9D, 0x0A, 0x54, 0x03, 0x10, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x41, 0x81, 0x04, 0x05, 0x02, 0x90,
-0x0A, 0x40, 0x6B, 0x00, 0xA1, 0x01, 0xF4, 0x02, 0x15, 0x0E, 0x42, 0x2B, 0x00,
-0xAD, 0x00, 0xB4, 0x82, 0xD0, 0x0B, 0x40, 0x2C, 0x00, 0xA1, 0x01, 0xB6, 0x02,
-0xD0, 0x0A, 0x40, 0x28, 0x00, 0xAD, 0x01, 0xF4, 0x02, 0x14, 0x48, 0x40, 0x20,
-0x02, 0x8D, 0x04, 0x34, 0x12, 0x10, 0x4C, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0xB0, 0x82, 0x02, 0x13, 0x0A, 0x5C, 0x28, 0xF0, 0x01,
-0xC0, 0x87, 0x42, 0x13, 0x0A, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x1F,
-0x0A, 0x7C, 0x28, 0xD0, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x00, 0xF0,
-0xA1, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0xFC, 0x28, 0x30, 0xA1, 0xD0, 0x84, 0x10,
-0x1F, 0x00, 0x7C, 0x28, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x19, 0xB8, 0x3F, 0x02, 0xBF, 0x08, 0xFC, 0x02, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0x80, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x8B, 0xC0, 0x27, 0x21, 0x9F,
-0x08, 0xFC, 0x23, 0xF8, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x19, 0xA0, 0x2F, 0x05, 0xA3, 0x8C, 0x5C, 0x02, 0x35, 0x0B, 0xC0, 0x2F,
-0x02, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x0B, 0xE0, 0x25, 0x00, 0x9F, 0x00, 0x4D,
-0x22, 0xF1, 0x09, 0xC0, 0x24, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0xF0, 0x0B, 0xC0,
-0x2E, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0x30, 0xC9, 0xE2, 0x24, 0x80, 0xBF, 0xA0,
-0xC8, 0x83, 0x30, 0x0B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1C, 0x08, 0x03, 0x01, 0x11, 0x0C, 0x45, 0x40, 0x10, 0x01, 0x40, 0x03, 0x00,
-0x1D, 0x14, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x04, 0x1D, 0x10, 0x44, 0x00,
-0xD0, 0x41, 0x41, 0x04, 0x01, 0x0D, 0x04, 0x74, 0x00, 0xD0, 0x01, 0x41, 0x04,
-0x10, 0x0D, 0x54, 0x74, 0x10, 0x50, 0xC1, 0x50, 0x04, 0x24, 0x1D, 0x00, 0x45,
-0x00, 0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA0, 0x23, 0x05, 0x81, 0x04, 0x04, 0x12, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D,
-0x04, 0x34, 0x02, 0x50, 0x08, 0x40, 0x20, 0x01, 0x8D, 0x00, 0x14, 0x02, 0xD0,
-0x49, 0x50, 0x20, 0x05, 0x8D, 0x04, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x22, 0x00,
-0x8D, 0x04, 0x34, 0x52, 0x50, 0x58, 0x40, 0x21, 0x01, 0x8D, 0xA8, 0x04, 0x82,
-0x10, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
-0x25, 0x40, 0x91, 0x02, 0x44, 0x22, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x00,
-0x74, 0x02, 0x50, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x56, 0x02, 0xC0, 0x09,
-0x40, 0x24, 0x00, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0xDD,
-0x00, 0x34, 0x02, 0x50, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x40, 0x06, 0x02, 0x14,
-0x49, 0x40, 0x63, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0xA3,
-0x00, 0x93, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0x50, 0x08, 0x50, 0x25, 0x08, 0x9F, 0x00, 0x5C, 0x02, 0xF2, 0x09, 0xC8,
-0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x00, 0x9D, 0x00,
-0x7C, 0x02, 0x34, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x80, 0x4C, 0x0A, 0x20, 0x09,
-0xC1, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x02,
-0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC4, 0x27,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x10, 0x64,
-0x02, 0xB0, 0x08, 0xC0, 0x27, 0x00, 0x8F, 0x10, 0x7C, 0x0A, 0xF0, 0x09, 0xC2,
-0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x85, 0x20, 0x13,
-0x40, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x4C, 0x90, 0xE2,
-0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x6C, 0x00, 0xD0, 0x01, 0xC0, 0x07, 0x00,
-0x1F, 0x08, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x13, 0x00, 0x4C, 0x00,
-0xF0, 0x01, 0xC0, 0x05, 0x08, 0x1D, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x50,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x1C, 0x02, 0x51, 0x81,
-0x45, 0x01, 0x70, 0x15, 0x40, 0x5F, 0x01, 0x71, 0x00, 0x84, 0x0D, 0x10, 0x97,
-0x40, 0x17, 0x00, 0x5D, 0x00, 0x70, 0x01, 0x98, 0x04, 0x40, 0x17, 0x00, 0x7D,
-0x00, 0x44, 0x01, 0x70, 0x05, 0x40, 0x57, 0x00, 0x7B, 0x03, 0x44, 0x01, 0xC0,
-0x05, 0x40, 0x17, 0x10, 0x7C, 0x02, 0x74, 0x01, 0x10, 0x07, 0x00, 0x50, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x72, 0x00, 0xD1, 0x00, 0x44,
-0x03, 0x50, 0x88, 0x40, 0x73, 0x40, 0xC5, 0x08, 0x04, 0x0B, 0x50, 0x2C, 0x40,
-0x33, 0x00, 0xDD, 0x00, 0x24, 0x03, 0xD2, 0x0C, 0x44, 0x33, 0x00, 0xCD, 0x10,
-0x25, 0x02, 0x50, 0x1D, 0x40, 0x63, 0x00, 0xC1, 0x0A, 0x25, 0x03, 0xD0, 0x0C,
-0x60, 0x33, 0x00, 0x4D, 0x0B, 0x34, 0x02, 0x50, 0x0C, 0x00, 0x50, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x04, 0xB1, 0x02, 0x84, 0x33,
-0x50, 0x0E, 0x40, 0x5B, 0x00, 0x65, 0x01, 0x84, 0x43, 0x10, 0x0A, 0x41, 0x3B,
-0x01, 0xED, 0x04, 0xB4, 0x23, 0x90, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x01, 0xA4,
-0x03, 0x50, 0x2E, 0x40, 0x7B, 0x00, 0xE9, 0x21, 0xA6, 0x03, 0xD0, 0x4E, 0x40,
-0x3B, 0x01, 0x69, 0x00, 0xB4, 0x03, 0x58, 0x1C, 0x44, 0x10, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x02, 0xE3, 0x01, 0x9C, 0x27, 0x71,
-0x1E, 0xC0, 0x7B, 0x20, 0xF7, 0x01, 0x8D, 0x06, 0x70, 0x1E, 0xC0, 0x7B, 0x00,
-0xED, 0x05, 0xAC, 0x87, 0xD0, 0x3E, 0xC0, 0x7B, 0x02, 0xEF, 0x01, 0xAC, 0x07,
-0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xE3, 0x01, 0xAC, 0x97, 0xF0, 0x9E, 0xE0, 0x7B,
-0x20, 0x6D, 0x21, 0xBC, 0x07, 0x74, 0x1E, 0xC2, 0x50, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xB0, 0xBD, 0x40, 0x9F, 0x06, 0x7C, 0x03, 0x70, 0x0D,
-0xC0, 0x17, 0x00, 0x5B, 0x00, 0x3C, 0x02, 0x70, 0x09, 0xC0, 0x37, 0x04, 0xDF,
-0x02, 0x7C, 0x0B, 0xF0, 0x2D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0x60,
-0x0D, 0xC0, 0x33, 0x00, 0x9F, 0x00, 0x5C, 0x0B, 0xF0, 0xAD, 0xC0, 0x37, 0x00,
-0x1F, 0x00, 0x3C, 0x5B, 0xB0, 0x09, 0xC2, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0xA0, 0x4F, 0x40, 0xB3, 0x03, 0xCC, 0x13, 0xF0, 0x1E, 0xC0,
-0x6C, 0x00, 0xBF, 0x01, 0x8C, 0x06, 0x30, 0x1B, 0xC0, 0x7B, 0x04, 0xF3, 0x13,
-0xCC, 0x0F, 0x30, 0x3F, 0xC0, 0x7F, 0x04, 0xFF, 0x81, 0xFC, 0x87, 0xB0, 0x1F,
-0xC0, 0x7F, 0x00, 0xBF, 0x01, 0xFC, 0x4F, 0xF0, 0x1F, 0xC0, 0x7C, 0x04, 0x7F,
-0x09, 0xCC, 0x06, 0x30, 0x9D, 0xC2, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0x88, 0x09, 0x00, 0xA1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x08,
-0x04, 0x2D, 0x44, 0x84, 0x02, 0x10, 0x0A, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xC4,
-0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xAD, 0x10, 0xB4, 0x03, 0x10, 0x0E, 0x40,
-0x3B, 0x00, 0xAD, 0x10, 0xBC, 0x23, 0xD0, 0x0E, 0xC0, 0x3A, 0x00, 0x6D, 0x08,
-0x84, 0x03, 0x11, 0x3E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x08, 0x00, 0x11, 0x00, 0x81, 0x00, 0x84, 0x63, 0xD0, 0x0F, 0x40, 0x2A, 0x00,
-0xAD, 0x00, 0xC6, 0x02, 0x10, 0x0A, 0x40, 0xBF, 0x00, 0xF1, 0x02, 0x84, 0x23,
-0x10, 0x0E, 0x40, 0x3B, 0x00, 0x6D, 0x08, 0xF4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
-0x02, 0x6D, 0x08, 0xB4, 0x03, 0xD0, 0x0C, 0x40, 0x38, 0x02, 0xCD, 0x48, 0x86,
-0x03, 0x50, 0x8E, 0x40, 0x23, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-0x28, 0x13, 0x00, 0x81, 0x42, 0x06, 0x07, 0xD0, 0x4C, 0x40, 0x42, 0x01, 0x0D,
-0x0D, 0x04, 0x0E, 0x10, 0x68, 0x40, 0x73, 0x00, 0xC1, 0x01, 0x04, 0x43, 0x10,
-0x1C, 0x41, 0x33, 0x04, 0x0D, 0x05, 0x34, 0x43, 0x18, 0x38, 0x40, 0x73, 0x00,
-0x1D, 0x05, 0x16, 0x2B, 0xD1, 0x0C, 0x50, 0x30, 0x08, 0x0D, 0x00, 0x40, 0x0B,
-0x58, 0x28, 0x41, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8,
-0x21, 0x11, 0xD1, 0x02, 0xCC, 0x07, 0xF0, 0x2C, 0xC0, 0xF6, 0x00, 0xDF, 0x02,
-0x4D, 0x44, 0x34, 0x1D, 0xC0, 0x3F, 0x00, 0xE3, 0x04, 0xC4, 0x07, 0x30, 0x0F,
-0x40, 0x7B, 0x00, 0x1F, 0x03, 0x3C, 0x0B, 0x30, 0x9D, 0x40, 0xB7, 0x04, 0x5F,
-0x03, 0xB4, 0x07, 0xF0, 0x0F, 0x00, 0x3C, 0x00, 0xDF, 0x00, 0x4C, 0x22, 0x72,
-0x3D, 0xC4, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x87,
-0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x8D, 0xC0, 0x37, 0x22, 0xDF, 0x00, 0x7C, 0x23, 0xF0, 0x8D, 0xC0,
-0x37, 0x02, 0x1F, 0x02, 0x7C, 0x07, 0x70, 0x8D, 0xC0, 0x37, 0x01, 0x5F, 0x40,
-0x7C, 0x43, 0xF0, 0x1D, 0xC0, 0x37, 0x00, 0xDD, 0x02, 0x7C, 0x07, 0x96, 0x1D,
-0x40, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x2F, 0x80,
-0xF3, 0x10, 0xCC, 0x03, 0xF0, 0x1F, 0xC0, 0x9C, 0x20, 0x7F, 0x00, 0xCC, 0x51,
-0x70, 0x0F, 0xC0, 0x3F, 0x00, 0xF3, 0x20, 0xCC, 0x03, 0xF0, 0x0F, 0xC4, 0x3F,
-0x80, 0x33, 0x00, 0xFC, 0x03, 0x31, 0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xCC,
-0x03, 0x30, 0x0E, 0xC0, 0x3C, 0x00, 0xFF, 0xA0, 0x4C, 0x83, 0x30, 0x17, 0xC2,
-0x07, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x20, 0x46, 0x01, 0xC1,
-0x09, 0x45, 0x03, 0xD0, 0x1D, 0x40, 0xC4, 0x10, 0x1D, 0x5B, 0x04, 0x1F, 0x50,
-0x75, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x42, 0x37, 0x40,
-0x11, 0x02, 0x74, 0x03, 0x50, 0x0D, 0x48, 0x37, 0x20, 0x1D, 0x02, 0x6C, 0x03,
-0xB0, 0x0D, 0x40, 0x35, 0x10, 0x8D, 0x07, 0x54, 0x03, 0x14, 0x3D, 0x40, 0x87,
-0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x44, 0x00, 0x99, 0x00,
-0x44, 0x03, 0xD0, 0x8D, 0x40, 0x34, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x50, 0x1D,
-0x40, 0x37, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xD1,
-0x08, 0x74, 0x07, 0x90, 0x0D, 0x40, 0x37, 0x02, 0x9D, 0x00, 0x44, 0x03, 0x10,
-0x0D, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x65, 0x02, 0x10, 0x8D, 0x40, 0x07, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x04, 0x00, 0x91, 0x80, 0x04,
-0x03, 0xD0, 0x0C, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x05, 0x03, 0x50, 0x0C, 0x40,
-0x37, 0x00, 0xD1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x37, 0x00, 0x81, 0x00,
-0x64, 0x03, 0x98, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x65, 0x03, 0x90, 0x0C,
-0x40, 0x30, 0x00, 0x8D, 0x00, 0x14, 0x03, 0x10, 0x4C, 0x40, 0x43, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x0E, 0x00, 0xBB, 0x40, 0xCC, 0x03,
-0xF0, 0x0D, 0xC0, 0x14, 0x00, 0x4F, 0x00, 0x4C, 0x03, 0x70, 0x0D, 0xC0, 0x3F,
-0x00, 0xF3, 0x00, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x3F, 0x00, 0x51, 0x00, 0x7C,
-0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x10, 0x5F, 0x40, 0xCC, 0x03, 0x30, 0x0F, 0xC0,
-0x34, 0x00, 0x9F, 0x20, 0xCC, 0x03, 0x30, 0x05, 0xC2, 0x07, 0x40, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0,
-0x0F, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00,
-0xEF, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xE0, 0x3F, 0x00, 0x3F, 0x80, 0xBC, 0x03,
-0x70, 0x0B, 0xC0, 0x3F, 0x10, 0x3F, 0x80, 0xDC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F,
-0x20, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA0, 0x7B, 0x00, 0xFF, 0x01, 0xCC, 0x27, 0xE0, 0x1F,
-0xC0, 0x7C, 0x02, 0xFB, 0x01, 0xBE, 0x0F, 0x11, 0x3F, 0xC0, 0x7C, 0x82, 0xF3,
-0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0xFF, 0x00, 0xFB, 0x01, 0xDC, 0x07, 0x30,
-0x9F, 0xC0, 0x5E, 0x02, 0xB3, 0x84, 0xEC, 0x31, 0xF0, 0x1F, 0xE4, 0x7F, 0x00,
-0xFF, 0xC1, 0xEC, 0x24, 0xB0, 0x17, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x08, 0x07, 0x00, 0x1D, 0x10, 0x69, 0x00, 0xF1, 0x11, 0x40,
-0x00, 0x20, 0x11, 0x01, 0x74, 0x00, 0x10, 0x01, 0x40, 0x00, 0x01, 0x17, 0x01,
-0x74, 0x04, 0xD0, 0x11, 0x40, 0x04, 0x20, 0x1D, 0x01, 0x44, 0x84, 0xB0, 0x01,
-0x40, 0x15, 0x01, 0xD5, 0x09, 0x44, 0xB3, 0xD0, 0x1F, 0x42, 0x7F, 0x00, 0xFD,
-0x01, 0x04, 0x10, 0x10, 0x19, 0x40, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x11, 0xA0, 0x33, 0x00, 0xDD, 0x84, 0x00, 0x13, 0xD0, 0x0D, 0x40, 0x30,
-0x21, 0xC9, 0x00, 0x30, 0x13, 0x10, 0x4D, 0x40, 0x34, 0x00, 0xC1, 0x00, 0x34,
-0x83, 0xC0, 0x0D, 0x00, 0x30, 0x01, 0xCD, 0x60, 0x40, 0x03, 0x92, 0x4C, 0x40,
-0x20, 0x00, 0x85, 0x00, 0x14, 0x01, 0x50, 0x0C, 0x40, 0x33, 0x80, 0xC5, 0x00,
-0x44, 0x10, 0x91, 0x0D, 0x64, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA8, 0x05, 0x00, 0x1D, 0x00, 0x46, 0x80, 0x50, 0x01, 0x40, 0x04, 0x00,
-0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x15, 0x00, 0x74, 0x00,
-0xD0, 0x01, 0x50, 0x04, 0x08, 0x1D, 0x00, 0x54, 0x00, 0x98, 0x01, 0x40, 0x21,
-0x00, 0x94, 0x00, 0x64, 0x11, 0xD0, 0x0D, 0x60, 0x37, 0x00, 0xDD, 0x00, 0x44,
-0x06, 0x10, 0x09, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x88, 0x37, 0x00, 0xCF, 0x00, 0x44, 0x03, 0xD1, 0x0C, 0xD0, 0x34, 0x00, 0xDB,
-0x00, 0x74, 0x03, 0x34, 0x0C, 0xD0, 0x30, 0x00, 0xD3, 0x80, 0x7C, 0x03, 0xF1,
-0x0D, 0x40, 0x36, 0x08, 0xDB, 0x00, 0x1C, 0x03, 0xB0, 0x0D, 0xC2, 0xA6, 0x00,
-0x87, 0x01, 0x7D, 0x01, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0xCF, 0x00, 0x2D, 0x04,
-0xB0, 0xD4, 0x40, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
-0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00,
-0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xF4, 0x00, 0xF0, 0x03,
-0xC0, 0x0D, 0x00, 0x3D, 0x00, 0xED, 0x40, 0xF0, 0x03, 0xC0, 0x3F, 0x08, 0xFF,
-0x05, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x3E, 0x20, 0xFF, 0x00, 0xFE, 0x00, 0xF0,
-0x1B, 0xD0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35,
-0x04, 0xD3, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x34, 0x10, 0xD7, 0x08, 0x6E,
-0xA3, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xDB, 0x84, 0x7C, 0x83, 0xF0, 0x0D, 0xC0,
-0x37, 0x00, 0xDF, 0x08, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0xA6, 0x20, 0x97, 0x24,
-0x6E, 0x09, 0xF0, 0x0D, 0xC0, 0x37, 0x28, 0xDF, 0x20, 0x7C, 0x02, 0x30, 0x2D,
-0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xC4, 0x01,
-0x11, 0x01, 0x74, 0x00, 0xD0, 0x01, 0xD0, 0x06, 0x00, 0x11, 0x01, 0x44, 0x04,
-0x14, 0x51, 0x40, 0x07, 0x30, 0x11, 0x10, 0x5C, 0x00, 0xD9, 0x00, 0xC1, 0x45,
-0x24, 0x0D, 0xAA, 0x64, 0x00, 0x70, 0x41, 0x40, 0x64, 0x00, 0x9B, 0x04, 0x74,
-0x01, 0xD0, 0x0D, 0x48, 0x37, 0x00, 0xDD, 0x04, 0x5C, 0x6E, 0x10, 0x09, 0xC0,
-0x4D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x80, 0xC1,
-0x00, 0x34, 0x03, 0xD0, 0x8C, 0x40, 0x34, 0x00, 0xC5, 0x01, 0x44, 0x07, 0x92,
-0x1C, 0x00, 0x33, 0x00, 0xC1, 0x02, 0x34, 0x03, 0xD0, 0x1C, 0x60, 0x73, 0x20,
-0xCD, 0x23, 0x34, 0x27, 0xD0, 0x1D, 0x40, 0xF0, 0x04, 0x81, 0x03, 0x34, 0x01,
-0xD0, 0x0C, 0x40, 0x73, 0x00, 0xCD, 0x05, 0x34, 0x0D, 0x10, 0x08, 0x40, 0x1F,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x4C, 0x00, 0x21, 0x01,
-0xB4, 0x04, 0xD0, 0x13, 0x40, 0x48, 0x00, 0x21, 0x01, 0xC4, 0x04, 0x98, 0x52,
-0x44, 0x4B, 0x00, 0x21, 0x05, 0x94, 0x04, 0xD0, 0x12, 0x68, 0x4B, 0x00, 0x2D,
-0x01, 0xB0, 0x04, 0x50, 0x12, 0x40, 0x79, 0x00, 0xE9, 0x01, 0xB4, 0x07, 0xD0,
-0x1E, 0x40, 0x7B, 0x00, 0xED, 0xA1, 0x94, 0x27, 0x10, 0x9A, 0x40, 0x19, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC3, 0x00, 0x3C,
-0x03, 0xF0, 0x8C, 0x40, 0x30, 0x20, 0xC7, 0x00, 0x05, 0x23, 0xB0, 0x5C, 0xC4,
-0x33, 0x00, 0xC1, 0x05, 0x3C, 0x03, 0xD0, 0x0C, 0xC0, 0x33, 0x20, 0xCF, 0x88,
-0x3C, 0x03, 0xF2, 0x0D, 0x50, 0xA0, 0x04, 0xC3, 0x00, 0x34, 0x03, 0xF0, 0x8C,
-0xC0, 0x33, 0x06, 0xCF, 0x00, 0x3C, 0x01, 0x30, 0x88, 0xC4, 0x4B, 0x40, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x00, 0x3F, 0x80, 0xFC, 0x00,
-0xF0, 0x82, 0xC0, 0x0F, 0x00, 0x2E, 0x08, 0xD4, 0x00, 0x71, 0x03, 0xC0, 0x07,
-0x02, 0x17, 0x08, 0xFC, 0x00, 0xF0, 0x01, 0xC0, 0x0D, 0x00, 0x1D, 0x80, 0x64,
-0x00, 0xF0, 0x11, 0xC0, 0x20, 0x02, 0xD8, 0x00, 0x7C, 0x03, 0xF0, 0x1F, 0xC0,
-0x7F, 0x08, 0xFF, 0x01, 0xDC, 0x03, 0xF0, 0x8B, 0xC0, 0x0B, 0x60, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC0, 0x35, 0x10, 0xCE, 0x01, 0x6C, 0x03, 0xD0, 0x0C, 0xC0, 0x34, 0x20,
-0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x73, 0x00, 0xD7, 0x00, 0x7C, 0x03,
-0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x01, 0x70, 0x8D, 0xC0, 0x37,
-0x02, 0xDF, 0x00, 0x7C, 0x07, 0x30, 0x1D, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xC0, 0x02,
-0x40, 0x0B, 0x00, 0x2D, 0x00, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x09, 0x00, 0x2D,
-0x00, 0xB4, 0x00, 0x50, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x00, 0xA4, 0x00, 0xD0,
-0x02, 0x40, 0x3B, 0x00, 0xED, 0x02, 0x9C, 0x1B, 0xF0, 0x4E, 0x48, 0x3B, 0x01,
-0xE9, 0x02, 0xB4, 0x03, 0x10, 0x0A, 0xC0, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x02, 0x79, 0x08, 0xED, 0x01, 0xB4, 0x07, 0xC0, 0x1E, 0x40,
-0x7B, 0x00, 0xFD, 0x01, 0x84, 0x07, 0xD0, 0x1F, 0x40, 0x78, 0x10, 0xE4, 0x01,
-0xB4, 0x07, 0x10, 0x1E, 0x08, 0x7F, 0x00, 0xE5, 0x01, 0xB4, 0x07, 0x40, 0x1E,
-0x60, 0x6B, 0x04, 0xE5, 0x05, 0x94, 0x17, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED,
-0x05, 0xB4, 0x07, 0x10, 0x1E, 0x44, 0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x28, 0x03, 0x80, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x44, 0x03,
-0x00, 0x0D, 0x00, 0x04, 0x00, 0xD8, 0x01, 0x42, 0x05, 0x00, 0x08, 0x00, 0x34,
-0x80, 0x52, 0x00, 0x40, 0x03, 0x00, 0x01, 0x00, 0x34, 0x00, 0x90, 0x00, 0x40,
-0xE3, 0x00, 0xCD, 0x00, 0x04, 0x06, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xC9, 0x00,
-0x34, 0x0E, 0x1C, 0x08, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00,
-0x5F, 0x00, 0x45, 0x01, 0xF0, 0x05, 0xC0, 0x14, 0x00, 0x57, 0x00, 0x7C, 0x01,
-0x30, 0x05, 0xC0, 0x17, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x1F,
-0x00, 0x4F, 0x00, 0xDC, 0x81, 0x78, 0x05, 0xC4, 0x17, 0x00, 0x5F, 0x80, 0xFC,
-0x25, 0x30, 0x47, 0x40, 0x5E, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x00, 0x8F, 0x20, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC0, 0x0F, 0x08, 0x3F,
-0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC0, 0x0F, 0x20, 0x3D, 0x00, 0xFC, 0x00, 0xF0,
-0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0x40, 0x87, 0x01,
-0x1F, 0x00, 0x5C, 0x20, 0x70, 0x00, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x20,
-0xF0, 0x01, 0xE0, 0x49, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08,
-0x67, 0x00, 0x9F, 0x08, 0x7C, 0x02, 0xF8, 0x29, 0xC0, 0x27, 0x00, 0x93, 0x04,
-0x7C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x20, 0x97, 0x09, 0x4C, 0x02, 0xB0, 0x09,
-0xC0, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x59, 0xC0, 0x24, 0x01, 0x9F,
-0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x16, 0xF0,
-0x09, 0xC8, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6,
-0x06, 0x9D, 0x20, 0x74, 0x06, 0xD8, 0x39, 0x44, 0x23, 0x20, 0x91, 0x01, 0x74,
-0x06, 0xD0, 0x09, 0x40, 0x24, 0x08, 0x83, 0x01, 0x04, 0x02, 0x10, 0x09, 0x44,
-0x27, 0x00, 0x9D, 0x10, 0x74, 0x06, 0xD0, 0x18, 0x50, 0xE4, 0x00, 0xBD, 0x00,
-0xC4, 0x02, 0xD0, 0x0B, 0x40, 0x2C, 0x01, 0xBD, 0x40, 0x74, 0x0E, 0xD2, 0x09,
-0x42, 0x07, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x08,
-0xBD, 0x00, 0xF4, 0x06, 0xD2, 0x0B, 0x40, 0x2F, 0x00, 0xB1, 0x40, 0xF4, 0x12,
-0x50, 0x8B, 0x40, 0x2C, 0x20, 0xBD, 0x00, 0xE4, 0x02, 0x90, 0x0B, 0x60, 0x2E,
-0x00, 0xB5, 0x01, 0xF4, 0x0A, 0xD0, 0x0B, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x64,
-0x13, 0xD2, 0x09, 0x40, 0x24, 0x80, 0x9D, 0x00, 0x74, 0x43, 0xD0, 0x09, 0x60,
-0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0x28, 0x00, 0xAD,
-0x02, 0xB4, 0x0A, 0xD0, 0x0E, 0x40, 0x2F, 0x00, 0xA1, 0x00, 0xB6, 0x0A, 0xD0,
-0x2A, 0x50, 0x28, 0x02, 0xBD, 0x00, 0xE5, 0x0A, 0x10, 0x0A, 0x60, 0xAB, 0x00,
-0xAD, 0x00, 0xB6, 0x02, 0xD0, 0x2B, 0x62, 0xA1, 0x00, 0x8D, 0x20, 0x04, 0x8A,
-0xD2, 0x28, 0x40, 0x20, 0x88, 0x8D, 0x80, 0x34, 0x22, 0xD0, 0x28, 0x40, 0x43,
-0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00,
-0x7C, 0x00, 0xD0, 0x01, 0xC0, 0x87, 0x42, 0x13, 0x00, 0x7E, 0x00, 0x70, 0x01,
-0xC0, 0x84, 0x00, 0x57, 0x00, 0x2C, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x1F,
-0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC2, 0x15, 0x00, 0x1F, 0x01, 0x4D, 0x04, 0xE0,
-0x11, 0xD0, 0x44, 0x00, 0x1D, 0x01, 0x3C, 0x08, 0xF0, 0x00, 0xE2, 0x77, 0xC0,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x0D, 0x9F, 0x01, 0x7C,
-0x86, 0xF2, 0x09, 0xC0, 0x27, 0x10, 0x9D, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0x44,
-0x27, 0x01, 0x93, 0x00, 0x5C, 0x06, 0xE0, 0x09, 0x40, 0x67, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x19, 0xC8, 0x6E, 0x00, 0xBF, 0x02, 0xF4, 0x0E, 0xF0, 0x39,
-0xC0, 0xA7, 0x08, 0x9F, 0x02, 0xFC, 0x12, 0xF0, 0x1F, 0xC0, 0x67, 0x60, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0xB3, 0x02, 0xFC, 0x02,
-0xD1, 0x0A, 0xC0, 0x27, 0x10, 0xBE, 0x00, 0xD8, 0x02, 0xF0, 0x0B, 0xC0, 0x27,
-0x02, 0xBF, 0x00, 0x74, 0x02, 0xF0, 0x0B, 0xC0, 0xAF, 0x00, 0xB7, 0x00, 0xDC,
-0x02, 0xC0, 0x2B, 0xC0, 0x2F, 0x00, 0xB3, 0x01, 0xBC, 0x46, 0x30, 0xD9, 0xC0,
-0x6C, 0x01, 0xB3, 0x11, 0xC8, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x05, 0x1B, 0x05, 0x74, 0x14, 0xD0,
-0x01, 0x40, 0x07, 0x04, 0x1D, 0x00, 0x74, 0x54, 0xD0, 0x11, 0x40, 0x07, 0x01,
-0x1D, 0x00, 0x74, 0x54, 0xD0, 0x01, 0xC0, 0x44, 0x00, 0x11, 0x00, 0x44, 0x00,
-0x90, 0x51, 0x40, 0x47, 0x05, 0x11, 0x20, 0x74, 0x14, 0x50, 0x31, 0x40, 0x85,
-0x00, 0x11, 0x02, 0x54, 0x00, 0xD0, 0x50, 0x41, 0x73, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x01, 0x81, 0x00, 0x34, 0x42, 0xD0, 0x08,
-0x40, 0x23, 0x00, 0xCD, 0x00, 0x14, 0x02, 0xD0, 0x48, 0x41, 0x23, 0x21, 0x8C,
-0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x20, 0x94, 0x00, 0x14, 0x02, 0x90,
-0x08, 0x40, 0x27, 0x00, 0x81, 0x02, 0x34, 0x52, 0x50, 0xC8, 0x40, 0x20, 0x02,
-0x85, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x99, 0x20, 0x74, 0x02, 0xD0, 0x09, 0x40,
-0x27, 0x10, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x80,
-0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x44, 0x02, 0x90, 0x09,
-0x00, 0xA7, 0x01, 0x91, 0x00, 0x70, 0x42, 0x50, 0x08, 0x40, 0x37, 0x00, 0x95,
-0x00, 0x56, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0x08, 0x25, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0x9D, 0x00, 0xFC,
-0x02, 0xF0, 0x09, 0xC0, 0x2B, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x90, 0x0B, 0xC0,
-0x2F, 0xC0, 0x93, 0x01, 0xFC, 0x2A, 0x71, 0x0B, 0xC8, 0x20, 0x40, 0x97, 0x40,
-0x4C, 0x9E, 0xF0, 0x2B, 0x40, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x00, 0x25, 0x04, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE1, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0xF0, 0x09, 0xC4, 0x25, 0x00, 0x9F, 0x20, 0x7C, 0x02, 0xB0, 0x09, 0xC2, 0x67,
-0x00, 0x9F, 0x89, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9B, 0x80, 0x7C,
-0x12, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x3A, 0x01, 0xD0, 0x06, 0x00, 0x13,
-0x00, 0x6C, 0x00, 0xF2, 0x01, 0xC0, 0x04, 0x80, 0x13, 0x28, 0x7C, 0x00, 0xB2,
-0x01, 0xD0, 0x05, 0x40, 0x13, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC2, 0x87, 0x00,
-0x1F, 0x00, 0x0C, 0x08, 0x31, 0x01, 0xD0, 0x04, 0x00, 0x03, 0x00, 0x4D, 0x88,
-0x30, 0x21, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20,
-0xDC, 0x00, 0x5D, 0x40, 0x74, 0x11, 0x15, 0x57, 0xC0, 0x14, 0x10, 0x55, 0x40,
-0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x7B, 0x00, 0x74, 0x01, 0x10, 0x05,
-0x40, 0x54, 0x00, 0x6B, 0x02, 0xF4, 0x0D, 0x34, 0x05, 0x40, 0x9B, 0x00, 0x7D,
-0x02, 0x6E, 0x01, 0xB0, 0x05, 0x40, 0x9C, 0x00, 0x7B, 0x1B, 0xC4, 0x05, 0x10,
-0x05, 0xC8, 0x52, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xF6,
-0x82, 0xCD, 0x09, 0x34, 0x03, 0x10, 0x38, 0x40, 0x30, 0x00, 0x81, 0x00, 0x34,
-0x03, 0xC0, 0x0C, 0x40, 0x30, 0x00, 0x45, 0x05, 0x34, 0x03, 0x90, 0x08, 0x40,
-0x32, 0x02, 0xC1, 0x04, 0x34, 0x01, 0x18, 0x0C, 0x40, 0xE3, 0x03, 0x8D, 0x10,
-0x24, 0x03, 0x10, 0x0C, 0x44, 0xA2, 0x01, 0x89, 0x03, 0x24, 0x1B, 0x1D, 0x0C,
-0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x18, 0x80,
-0xAD, 0x44, 0xF4, 0x17, 0x10, 0x1A, 0x44, 0x7C, 0x00, 0xE5, 0x00, 0xB4, 0x12,
-0xD2, 0x5A, 0x40, 0x7C, 0x01, 0xE9, 0x00, 0xF6, 0x17, 0x10, 0x1A, 0x40, 0x2A,
-0x00, 0xE1, 0x00, 0xF4, 0x0F, 0x90, 0x0E, 0x40, 0x3B, 0x01, 0x8D, 0x11, 0xF4,
-0x0B, 0x90, 0x8E, 0x40, 0x28, 0x04, 0xA9, 0x20, 0xA4, 0x0F, 0x10, 0x5E, 0x40,
-0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF,
-0x21, 0xBC, 0x1E, 0x10, 0x1E, 0xC0, 0x78, 0x02, 0xE3, 0x01, 0xBC, 0x07, 0xD2,
-0x5F, 0xC0, 0x78, 0x04, 0xE5, 0x01, 0xBC, 0x97, 0xB0, 0x1A, 0x60, 0x7E, 0x00,
-0xE1, 0x01, 0xBC, 0x07, 0x19, 0x3E, 0xC0, 0x7B, 0x11, 0xAF, 0x01, 0xA6, 0x0E,
-0x30, 0x1C, 0x88, 0x6A, 0x00, 0xAB, 0x01, 0xEC, 0x05, 0x30, 0x3E, 0xC0, 0x50,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x08, 0x9F, 0x00,
-0x3C, 0x02, 0xF0, 0x0D, 0xC8, 0xB1, 0x01, 0xDF, 0x00, 0x7C, 0x22, 0xF0, 0x89,
-0xDA, 0x33, 0x02, 0xDC, 0x00, 0x3C, 0x23, 0xF0, 0x08, 0x80, 0x25, 0x00, 0x9F,
-0x00, 0x3C, 0x03, 0x70, 0x09, 0x80, 0x17, 0x10, 0x9D, 0x00, 0x6C, 0x02, 0xC0,
-0x0D, 0xC0, 0x21, 0x00, 0x8F, 0x00, 0x5C, 0x01, 0xF0, 0x0D, 0xC8, 0x43, 0x60,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7B, 0x00, 0xF3, 0x11, 0xCC,
-0x07, 0xB8, 0x0B, 0xC0, 0x7F, 0x04, 0xFF, 0x01, 0xED, 0x07, 0x30, 0x1F, 0xC0,
-0x7F, 0x20, 0xEF, 0x09, 0x4C, 0x27, 0x30, 0x1B, 0xC0, 0x7D, 0x04, 0xFB, 0x01,
-0x9C, 0x07, 0xB0, 0x9E, 0xC2, 0x5D, 0x04, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x1F,
-0xC8, 0x6C, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1E, 0xC0, 0x08, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x19, 0x06, 0xF1, 0x40, 0xC4, 0x13,
-0x39, 0x4A, 0x40, 0x3B, 0x01, 0xED, 0x00, 0xC4, 0x02, 0x10, 0x08, 0x48, 0x3B,
-0x01, 0xC7, 0x02, 0x84, 0x77, 0x10, 0x0A, 0x40, 0x3C, 0x00, 0x61, 0x00, 0x84,
-0x03, 0x40, 0x1E, 0x40, 0x39, 0x00, 0xAD, 0x84, 0xA4, 0x13, 0xF0, 0x0E, 0x40,
-0x28, 0x00, 0xE5, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x54, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x00, 0xA1, 0x08, 0x84, 0x02, 0x01,
-0x8A, 0x41, 0x3B, 0x10, 0xFD, 0x00, 0x84, 0x43, 0x10, 0x0E, 0x40, 0x3B, 0x20,
-0xED, 0x02, 0x80, 0x17, 0x10, 0x0B, 0x41, 0x29, 0x00, 0xF1, 0x00, 0x94, 0x03,
-0x10, 0x4F, 0x40, 0x1A, 0x00, 0xAD, 0x80, 0xB4, 0x42, 0xD0, 0x1E, 0x40, 0x20,
-0x00, 0xE5, 0x00, 0xB4, 0x01, 0xD0, 0x1F, 0x40, 0x20, 0x01, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x28, 0x03, 0x00, 0x90, 0x02, 0x44, 0x0E, 0x10, 0x3C,
-0x40, 0xB3, 0x02, 0xCD, 0x02, 0x06, 0x0E, 0x00, 0x38, 0x40, 0xF3, 0x01, 0xC9,
-0x08, 0x04, 0x4F, 0x11, 0x68, 0x42, 0xA5, 0x02, 0x01, 0x0B, 0x04, 0x4B, 0x50,
-0x08, 0x41, 0x13, 0x22, 0x8D, 0x81, 0x66, 0x1A, 0x52, 0x0C, 0x44, 0x20, 0x00,
-0xC5, 0x80, 0x74, 0x08, 0xD0, 0x0C, 0x40, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0xA8, 0x65, 0x00, 0xD2, 0x01, 0x4C, 0x4F, 0x34, 0x18, 0xC0,
-0x7F, 0x00, 0xDF, 0x03, 0x0C, 0x07, 0x30, 0x3D, 0xC1, 0xBF, 0x04, 0xCD, 0x01,
-0x4D, 0x0B, 0x36, 0x2D, 0xE4, 0xB5, 0x02, 0x93, 0x02, 0x54, 0x42, 0x10, 0x19,
-0xC0, 0x36, 0x00, 0xDD, 0x05, 0x74, 0x0F, 0xD0, 0x0D, 0xD0, 0x34, 0x00, 0x97,
-0x20, 0x7C, 0x02, 0xF2, 0xBD, 0xD5, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x00, 0xA7, 0x20, 0x9F, 0x18, 0x7C, 0x03, 0x70, 0x29, 0xC0, 0x37,
-0x01, 0xDE, 0x08, 0x7C, 0x03, 0xF4, 0x4D, 0xC0, 0x37, 0x00, 0xD7, 0x02, 0x7C,
-0x03, 0xF0, 0x09, 0xC0, 0x26, 0x00, 0x97, 0x82, 0x7C, 0x0B, 0x70, 0x8D, 0xE0,
-0x35, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x9D, 0x02,
-0x7C, 0x2A, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x80, 0x0A, 0x2F, 0x00, 0xFF, 0x00, 0xCC, 0x43, 0x70, 0x0F, 0xC1, 0x3C, 0x00,
-0xFF, 0x15, 0xDC, 0x66, 0x30, 0x1B, 0xC0, 0x3F, 0x20, 0xFF, 0x00, 0xCC, 0x03,
-0xF0, 0x9F, 0xC0, 0x3F, 0x00, 0x33, 0x10, 0xFC, 0x03, 0xE0, 0x0B, 0xC0, 0x7F,
-0x10, 0xE3, 0x49, 0xCC, 0x03, 0x30, 0x0F, 0xC0, 0xBF, 0x00, 0xBF, 0x22, 0xFC,
-0x40, 0x30, 0x0F, 0xC0, 0x07, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
-0x20, 0x66, 0x00, 0x9D, 0x00, 0x44, 0x83, 0x10, 0x2D, 0x40, 0x34, 0x08, 0xDD,
-0x40, 0x74, 0x02, 0x50, 0x09, 0x44, 0x37, 0x08, 0xDD, 0x03, 0x44, 0x03, 0xD0,
-0x19, 0x68, 0x27, 0x80, 0x15, 0x13, 0x74, 0x47, 0xD2, 0x99, 0xC4, 0x51, 0x28,
-0xD1, 0x03, 0x6C, 0x27, 0xF0, 0x0D, 0x40, 0x27, 0x00, 0x9D, 0x04, 0x7C, 0x2F,
-0x11, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0,
-0x46, 0x04, 0xDD, 0x00, 0x44, 0x12, 0x12, 0x09, 0x41, 0x36, 0x00, 0xDD, 0x00,
-0x74, 0x03, 0x12, 0x8D, 0x42, 0x37, 0x00, 0xDD, 0x01, 0x44, 0x03, 0xD0, 0x0D,
-0x42, 0x37, 0x20, 0x91, 0x01, 0x74, 0x07, 0xD0, 0x09, 0x44, 0x17, 0x02, 0x95,
-0x50, 0x44, 0x02, 0x10, 0x0D, 0x48, 0x36, 0x00, 0x9D, 0x00, 0x74, 0x0A, 0x10,
-0x0D, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
-0x00, 0xCD, 0x00, 0x05, 0x02, 0x10, 0x08, 0x50, 0x32, 0x08, 0xCD, 0x00, 0x74,
-0x03, 0x50, 0x8C, 0x40, 0x33, 0x00, 0xDD, 0x02, 0x04, 0x13, 0xD0, 0x08, 0x40,
-0x36, 0x00, 0x05, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x61, 0x35, 0x40, 0x45, 0x80,
-0x24, 0x02, 0x98, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x20, 0x34, 0x00, 0x10, 0x0C,
-0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00,
-0x9F, 0x20, 0x4C, 0x02, 0x34, 0x01, 0xC0, 0x3E, 0x00, 0xDF, 0x00, 0x58, 0x82,
-0x30, 0x09, 0xC0, 0x3F, 0x08, 0xDF, 0x02, 0x84, 0x43, 0xF0, 0x0D, 0x40, 0x27,
-0x00, 0x11, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0x40, 0x17, 0x80, 0x97, 0x80, 0x4C,
-0x02, 0x30, 0x0E, 0x80, 0x17, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x34, 0x0F, 0xC8,
-0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, 0x2F, 0x00, 0xBF,
-0x40, 0xFC, 0x02, 0xB0, 0x07, 0xC0, 0x3D, 0x08, 0xEF, 0x00, 0xFC, 0x02, 0xF0,
-0x4B, 0xC8, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0A, 0xC0, 0x2F, 0x00,
-0x2F, 0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC0, 0x1F, 0x00, 0x7B, 0x00, 0xF8, 0x02,
-0xF0, 0x0F, 0xC2, 0x1F, 0x20, 0x7F, 0x00, 0xDC, 0x00, 0xF0, 0x0F, 0xC0, 0x17,
-0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x6F, 0x00, 0x2F, 0x04,
-0xCC, 0x06, 0x70, 0x43, 0xC1, 0x0F, 0x01, 0xE3, 0x01, 0xCC, 0x10, 0x74, 0x03,
-0xC0, 0x0F, 0x00, 0x33, 0x10, 0xCC, 0x80, 0x30, 0x03, 0xD0, 0x0C, 0x00, 0x33,
-0x04, 0xCC, 0x00, 0x34, 0x43, 0xC8, 0x7E, 0x02, 0xB3, 0x00, 0xFC, 0x53, 0xF0,
-0x12, 0xC0, 0x6D, 0x02, 0xAF, 0x01, 0xFC, 0x06, 0xF0, 0x4B, 0xC0, 0x0F, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x67, 0x00, 0x1D, 0xAB, 0x44,
-0x07, 0x10, 0x35, 0x48, 0xD7, 0x02, 0xD1, 0xA1, 0x44, 0x0D, 0x10, 0x35, 0x40,
-0x57, 0x02, 0x51, 0x43, 0x4C, 0x0D, 0x10, 0xB5, 0x40, 0xD4, 0x02, 0x51, 0x03,
-0x44, 0x0D, 0x10, 0x95, 0x40, 0x33, 0x11, 0xD1, 0x03, 0x74, 0x8F, 0xD0, 0x19,
-0x40, 0x27, 0x01, 0x9D, 0x01, 0x74, 0x04, 0xD2, 0x11, 0x40, 0x07, 0x60, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA8, 0x23, 0x00, 0x0D, 0x00, 0x44, 0x03,
-0x50, 0x08, 0x40, 0x21, 0x40, 0xC1, 0x00, 0x14, 0x0A, 0x18, 0x88, 0x40, 0x23,
-0x00, 0x81, 0x00, 0x04, 0x0A, 0x50, 0x08, 0x48, 0x20, 0x00, 0x89, 0x08, 0x06,
-0x0A, 0x10, 0x08, 0x40, 0x33, 0x01, 0x81, 0x02, 0x34, 0x03, 0xD0, 0x08, 0x40,
-0x01, 0x10, 0x85, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x47, 0x80, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x02, 0x1D, 0xC0, 0x64, 0xC7, 0x10,
-0x05, 0x44, 0x37, 0x02, 0xD1, 0x00, 0x56, 0x08, 0x10, 0x05, 0x40, 0xB7, 0x09,
-0x91, 0x03, 0x64, 0x03, 0x50, 0x09, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44, 0x0E,
-0x10, 0x09, 0x42, 0x37, 0x01, 0x91, 0x00, 0x74, 0x03, 0xD0, 0x19, 0x40, 0x57,
-0x00, 0xDD, 0x01, 0x74, 0x05, 0xD0, 0x19, 0x41, 0x0F, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xA8, 0x27, 0x00, 0xDF, 0x5A, 0x0C, 0x0F, 0x70, 0x91,
-0xC0, 0xC7, 0x04, 0xD3, 0x01, 0x5C, 0x24, 0x30, 0x11, 0xC2, 0xC7, 0x00, 0x13,
-0x02, 0x4C, 0x00, 0x70, 0x21, 0xC1, 0xC4, 0x86, 0x13, 0x1B, 0x4C, 0x08, 0x30,
-0x01, 0xC0, 0x36, 0x00, 0x93, 0x00, 0x7C, 0x03, 0xF0, 0x59, 0xC0, 0xE5, 0x00,
-0x9F, 0x07, 0x7C, 0x16, 0xF0, 0x39, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x07, 0x80, 0x2D, 0x20, 0xBF, 0x00, 0xDC, 0x03, 0xF0, 0x17, 0xC0,
-0x4F, 0x00, 0xFD, 0x02, 0xEC, 0x01, 0xB0, 0x3F, 0xC0, 0x1A, 0x40, 0x6F, 0x00,
-0x9C, 0x0D, 0xB0, 0x07, 0xC0, 0x5B, 0x20, 0x7F, 0x00, 0xFD, 0x01, 0xF0, 0x07,
-0xC2, 0x7F, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0x7F,
-0x00, 0xFC, 0x01, 0xF2, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x08, 0x25, 0x00, 0xD3, 0x13, 0x4C, 0x23, 0xF0, 0x09, 0xD0, 0xA0,
-0x00, 0xDF, 0x11, 0x1C, 0x0A, 0x70, 0x09, 0xE0, 0x27, 0x00, 0x1F, 0x02, 0x4C,
-0x2A, 0x30, 0x2C, 0xC0, 0xA7, 0x02, 0x83, 0x02, 0x0D, 0x02, 0xF0, 0x2D, 0x41,
-0x74, 0x01, 0xD3, 0x00, 0x4C, 0x03, 0xF0, 0x29, 0xC0, 0x94, 0x00, 0x9F, 0x0E,
-0x4C, 0x0A, 0xF0, 0x29, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x13, 0xA0, 0x64, 0x01, 0x81, 0x22, 0x44, 0x03, 0xD0, 0xB5, 0x40, 0xE4, 0x02,
-0xCD, 0x02, 0x44, 0x28, 0xD0, 0xAD, 0x41, 0xB7, 0x06, 0x1D, 0x1A, 0x44, 0x07,
-0x12, 0xAD, 0x42, 0xB7, 0x00, 0x91, 0x0B, 0x6C, 0x2A, 0xD0, 0x0D, 0x41, 0xB5,
-0x08, 0xD1, 0x01, 0xC4, 0x83, 0xD0, 0x0D, 0xC0, 0x14, 0x00, 0xD1, 0x01, 0x44,
-0x99, 0xD0, 0x19, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x20, 0xE2, 0x01, 0x01, 0x00, 0x14, 0x13, 0xD0, 0x00, 0x40, 0x00, 0x28, 0xCD,
-0x00, 0x20, 0x24, 0x80, 0x10, 0x40, 0x43, 0x00, 0x0D, 0x01, 0x06, 0x90, 0x10,
-0x90, 0x40, 0x43, 0x04, 0x01, 0x00, 0x24, 0x24, 0xD0, 0x10, 0x40, 0x34, 0x00,
-0x81, 0x80, 0x24, 0x83, 0x90, 0x08, 0x40, 0x20, 0x00, 0x01, 0x02, 0x04, 0x42,
-0xD1, 0x00, 0x43, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
-0x6A, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x98, 0x43, 0x58, 0x00, 0xED, 0x01,
-0xB4, 0x07, 0xD0, 0x12, 0x40, 0x6B, 0x00, 0x4C, 0x01, 0x04, 0x04, 0x10, 0x1E,
-0x40, 0x63, 0x00, 0xC1, 0x11, 0x84, 0x05, 0xD0, 0x14, 0x50, 0x78, 0x00, 0xE1,
-0x01, 0xA4, 0x07, 0xD0, 0x0B, 0x40, 0x7A, 0x12, 0xB1, 0x01, 0x85, 0x06, 0xD0,
-0x12, 0x48, 0x13, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x22,
-0x00, 0x03, 0x08, 0x1C, 0x03, 0xF0, 0xA8, 0xC8, 0x00, 0x84, 0xCF, 0x00, 0x3C,
-0x83, 0x70, 0x0C, 0x40, 0x13, 0x00, 0xCE, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA,
-0x13, 0x10, 0x43, 0x00, 0x24, 0x01, 0xF0, 0xE0, 0xC0, 0x30, 0x40, 0x83, 0x18,
-0x2C, 0x03, 0xF0, 0x88, 0xC0, 0x24, 0x40, 0x47, 0x08, 0x0C, 0x03, 0xF0, 0x00,
-0xC1, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x39, 0x40,
-0xFF, 0x00, 0xFC, 0x03, 0xF1, 0x8B, 0xC0, 0x1F, 0x20, 0xFF, 0x00, 0xCC, 0x03,
-0xF8, 0x07, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x8B, 0xC0, 0x3F,
-0x00, 0xFF, 0x08, 0xFC, 0x01, 0xF0, 0x83, 0xE0, 0x3F, 0x00, 0xAF, 0x00, 0xDD,
-0x43, 0xF0, 0x4F, 0xC0, 0x1D, 0x00, 0x7F, 0x00, 0xFC, 0x01, 0xF0, 0x83, 0xC0,
-0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x67, 0x00, 0x53,
-0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x00, 0xF0,
-0x01, 0xC0, 0x07, 0x00, 0x93, 0x80, 0x7C, 0x07, 0x32, 0x01, 0xC2, 0x44, 0x00,
-0x13, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x37, 0x00, 0x93, 0x00, 0x5C, 0x03,
-0xF0, 0x09, 0xC0, 0x57, 0x00, 0x53, 0x80, 0x7C, 0x01, 0x30, 0x19, 0xC0, 0x40,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x39, 0x00, 0xE1, 0x00,
-0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x08, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0A,
-0x40, 0x23, 0x40, 0xE1, 0x00, 0x36, 0x03, 0x04, 0x0C, 0x40, 0x28, 0x40, 0xE1,
-0x20, 0x04, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE5, 0x00, 0xB4, 0x13, 0xD0,
-0x0A, 0x40, 0x3B, 0x00, 0x61, 0x00, 0xF4, 0x01, 0xB1, 0x02, 0x40, 0x48, 0x60,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x00, 0x61, 0x01, 0xB4,
-0x07, 0xD0, 0x1C, 0x44, 0x78, 0x00, 0xE5, 0x11, 0xB6, 0x07, 0x50, 0x1E, 0x40,
-0x5B, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0x10, 0x16, 0x40, 0x50, 0x00, 0x41, 0x01,
-0x84, 0x07, 0x14, 0x3E, 0x40, 0x7F, 0x00, 0xE1, 0x01, 0x94, 0x07, 0xD0, 0x1A,
-0x40, 0xDF, 0x00, 0x61, 0x01, 0xF4, 0x07, 0x10, 0x18, 0x50, 0x10, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0xC1, 0x13, 0x34, 0x01,
-0xD0, 0x9C, 0x40, 0xB0, 0x04, 0x8D, 0x01, 0x36, 0x03, 0xD0, 0x0C, 0x40, 0x33,
-0x00, 0xC1, 0x02, 0x34, 0x07, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x04,
-0x03, 0x10, 0x2C, 0x40, 0x63, 0x02, 0xC5, 0x08, 0x34, 0x03, 0xD0, 0xAC, 0x41,
-0xD3, 0x00, 0x41, 0x62, 0x34, 0x85, 0x90, 0x1C, 0x40, 0x58, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x57, 0x04, 0x73, 0x07, 0xBC, 0x09, 0xF0,
-0x07, 0xD0, 0x9E, 0x04, 0x57, 0x00, 0xFC, 0x01, 0xF0, 0x87, 0xE0, 0x1F, 0x00,
-0x73, 0x02, 0xFC, 0x1D, 0x30, 0x17, 0xD1, 0x1C, 0x00, 0x73, 0x00, 0xCD, 0x01,
-0x30, 0x27, 0xC0, 0x17, 0x00, 0x53, 0x01, 0x5C, 0x01, 0xF0, 0x17, 0xC0, 0x1F,
-0x00, 0x63, 0x07, 0xBC, 0x05, 0x30, 0x77, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x40, 0x0F, 0x00, 0x7C, 0x40, 0xF0, 0x01,
-0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F,
-0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x04, 0xF0,
-0x01, 0xC1, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x44,
-0x1F, 0x06, 0x7C, 0x24, 0xF0, 0x41, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x08, 0xE0,
-0x20, 0x00, 0x93, 0x00, 0x3C, 0x02, 0x30, 0x08, 0xC0, 0x20, 0x00, 0x83, 0x10,
-0x4C, 0x02, 0xF0, 0x08, 0xC0, 0x24, 0x00, 0x8F, 0x00, 0x0C, 0x02, 0x70, 0x08,
-0xC0, 0x64, 0x00, 0x93, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F,
-0x08, 0x4C, 0x22, 0x30, 0x59, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x80, 0x44, 0x02, 0x10, 0x09, 0x10, 0x24,
-0x40, 0x91, 0x00, 0x74, 0x02, 0x14, 0x09, 0xD0, 0x24, 0x50, 0x91, 0x40, 0x4D,
-0x02, 0xD0, 0x09, 0x50, 0x24, 0x00, 0x9D, 0x00, 0x45, 0x02, 0x14, 0x09, 0x50,
-0x64, 0x42, 0x91, 0x00, 0x74, 0x06, 0x50, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x01,
-0x54, 0x06, 0x54, 0x29, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00,
-0x91, 0x00, 0x74, 0x02, 0x10, 0x09, 0x00, 0x26, 0x00, 0x99, 0x00, 0x44, 0x03,
-0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x90, 0x09, 0x40, 0x20,
-0x00, 0x91, 0x00, 0x74, 0x12, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x00, 0x44,
-0x42, 0x11, 0x29, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x28, 0x20, 0x00, 0x8D, 0x04, 0x05, 0x02, 0x10, 0x48, 0x40, 0x20, 0x01, 0x81,
-0x00, 0x34, 0x12, 0x10, 0x48, 0x44, 0x20, 0x01, 0x89, 0x04, 0x04, 0x12, 0xD0,
-0x48, 0x40, 0x20, 0x01, 0x8D, 0x04, 0x04, 0x12, 0x10, 0x48, 0x40, 0x60, 0x00,
-0x81, 0x04, 0x34, 0x12, 0x50, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x54, 0x02,
-0x50, 0x48, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0,
-0x06, 0x00, 0x1F, 0x00, 0x44, 0x00, 0x34, 0x01, 0x40, 0x04, 0x00, 0x13, 0x00,
-0x7C, 0x00, 0x30, 0x01, 0xC0, 0x06, 0x00, 0x1B, 0x20, 0x4C, 0x00, 0xF0, 0x01,
-0xC0, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x70, 0x01, 0xC0, 0x84, 0x02, 0x13,
-0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x5F, 0x80, 0x4C, 0x00, 0x32,
-0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x2B,
-0x00, 0xBF, 0x28, 0xFD, 0x02, 0xF1, 0x8B, 0xC0, 0x2F, 0x0A, 0xBF, 0x20, 0xFC,
-0x22, 0xF0, 0x8B, 0xC0, 0x2F, 0x02, 0xB7, 0x08, 0xDC, 0x22, 0xF2, 0x8B, 0xC0,
-0x2F, 0x22, 0xBF, 0x08, 0xFC, 0x22, 0xF2, 0x8B, 0xC0, 0x2B, 0x00, 0xBF, 0x08,
-0x7C, 0x22, 0xF0, 0x0B, 0xC0, 0x2B, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF1, 0x8B,
-0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27, 0x00,
-0x9F, 0x84, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x52,
-0x30, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x49, 0xC0, 0x24,
-0x05, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x2C, 0x02, 0xB3, 0x04, 0xCC,
-0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xBC, 0x02, 0xF2, 0x0B, 0xC0,
-0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00, 0x1D,
-0x28, 0x74, 0x80, 0xD0, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x00, 0x10,
-0x81, 0x40, 0x87, 0x00, 0x1D, 0x00, 0x74, 0xA0, 0x12, 0x01, 0x40, 0x04, 0x00,
-0x1D, 0x88, 0x74, 0x08, 0xD0, 0x03, 0x40, 0x04, 0x40, 0x11, 0x20, 0x45, 0x00,
-0xD0, 0x01, 0x40, 0x16, 0x14, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x73,
-0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x29, 0x00, 0xAD, 0x00,
-0xB4, 0x02, 0xD0, 0x9A, 0x40, 0x6B, 0x00, 0xA1, 0x00, 0xB4, 0x06, 0x10, 0x1A,
-0x40, 0x6B, 0x02, 0xAD, 0x09, 0xB4, 0x06, 0x10, 0x9A, 0x48, 0x68, 0x20, 0xAD,
-0x01, 0xB0, 0x26, 0xD0, 0x9A, 0x40, 0x20, 0x00, 0x81, 0x08, 0x04, 0x0A, 0xD0,
-0x08, 0x40, 0x23, 0x01, 0x8D, 0x80, 0x34, 0x02, 0xD0, 0x18, 0x40, 0x4B, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x65, 0x00, 0xBD, 0x00, 0xF4,
-0x8A, 0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40,
-0x6F, 0x00, 0xBD, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40, 0x6C, 0x00, 0xBD, 0x00,
-0xF4, 0x12, 0xD0, 0x0B, 0x50, 0x24, 0x00, 0x91, 0x04, 0x44, 0x02, 0xD0, 0x09,
-0x40, 0x26, 0x02, 0x9D, 0x02, 0x74, 0x0A, 0xD0, 0x19, 0x40, 0x63, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x26,
-0xF0, 0x29, 0xC8, 0xA7, 0x40, 0x91, 0x00, 0x7C, 0x2A, 0x34, 0x39, 0xC0, 0xA7,
-0x00, 0x9F, 0x0B, 0x7C, 0x0A, 0x34, 0xA9, 0xD0, 0xA4, 0x00, 0x9F, 0x03, 0x7C,
-0x0A, 0xF0, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x39, 0xC1,
-0xA7, 0x00, 0x9F, 0x82, 0x7C, 0x0E, 0xF0, 0x29, 0xC0, 0x17, 0x20, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x08, 0x9F, 0x00, 0x78, 0x06, 0xF0,
-0x09, 0x80, 0x27, 0x00, 0x9F, 0x09, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x00,
-0x9F, 0x01, 0x3C, 0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x09, 0x7C, 0x06,
-0xF0, 0x98, 0xC0, 0x27, 0x01, 0x8F, 0x01, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x27,
-0x00, 0x9F, 0x28, 0x7C, 0x66, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x08, 0x0D, 0x00, 0x3F, 0x00, 0xCC, 0x00, 0xF0, 0x03,
-0xC0, 0x0B, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0x70, 0x03, 0xC0, 0x0C, 0x00, 0x3F,
-0x00, 0xFE, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xB0,
-0x03, 0xC0, 0x44, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
-0x1F, 0x12, 0x7C, 0x08, 0x30, 0x01, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x5D, 0x20, 0x40, 0x01, 0x70, 0x05, 0x40,
-0x17, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x5D, 0x20,
-0x74, 0x01, 0xD2, 0x05, 0x48, 0x17, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x30, 0x05,
-0xC0, 0x1E, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x10, 0x7D,
-0x03, 0xF4, 0x4D, 0x50, 0x17, 0x50, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0xA0, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x50, 0x00, 0x40, 0x03,
-0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00, 0x40, 0x02, 0x00, 0x0D, 0x00, 0x36,
-0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x09, 0x00, 0x30, 0x00, 0x14, 0x00, 0x40,
-0x34, 0x08, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x00,
-0x34, 0x09, 0x10, 0x8C, 0x41, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x88, 0x38, 0x00, 0xCD, 0x01, 0x84, 0x03, 0x50, 0x0E, 0x40, 0x3B, 0x00,
-0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1E, 0x40, 0x3A, 0x00, 0xED, 0x00, 0xB4, 0x03,
-0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0x34, 0x07, 0x10, 0x0E, 0x40, 0x2A,
-0x00, 0xAD, 0x00, 0xB4, 0x42, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0x6D, 0x42, 0xB4,
-0x05, 0x50, 0x1E, 0x40, 0x05, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
-0x10, 0x48, 0x00, 0x2F, 0x01, 0x8D, 0x84, 0x70, 0x12, 0xC0, 0x4B, 0x00, 0x2F,
-0x01, 0xBC, 0x04, 0x72, 0x10, 0xD0, 0x4A, 0x08, 0x2D, 0x21, 0xB4, 0x04, 0xF0,
-0x12, 0xC0, 0x4B, 0x00, 0x2F, 0x01, 0xBC, 0x04, 0x30, 0x12, 0xC0, 0x58, 0x00,
-0xAF, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x03, 0xEF, 0x01, 0xBC, 0x05,
-0x30, 0x1E, 0xC0, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8,
-0x35, 0x00, 0xDF, 0x00, 0x7E, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00,
-0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
-0xC8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0x9F,
-0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0,
-0x0C, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x4D,
-0x00, 0x3F, 0x01, 0xCC, 0x20, 0xF0, 0x13, 0xC0, 0x4C, 0x00, 0x3F, 0x01, 0xCC,
-0x04, 0xF0, 0x13, 0xC0, 0x4E, 0x00, 0x33, 0x01, 0xCC, 0x84, 0xF0, 0x13, 0xC2,
-0x4F, 0x02, 0x3F, 0x09, 0xFC, 0x04, 0xF0, 0x13, 0xC0, 0x7C, 0x00, 0xBF, 0x01,
-0xFC, 0x07, 0xF0, 0x1E, 0xC0, 0x7C, 0x04, 0x73, 0x01, 0x8C, 0x07, 0x30, 0x17,
-0xC0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, 0x08,
-0xED, 0x00, 0x84, 0x03, 0xF0, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x30, 0x94, 0x03,
-0xD0, 0x0E, 0x50, 0x38, 0x42, 0xE1, 0x08, 0x85, 0x23, 0xD0, 0x0E, 0x40, 0x3B,
-0x00, 0xED, 0x08, 0xB4, 0x03, 0xF0, 0x0E, 0x40, 0x08, 0x00, 0xAD, 0x00, 0xB4,
-0x03, 0xF0, 0x0E, 0xC0, 0x3B, 0x00, 0x21, 0x00, 0xAC, 0x12, 0xB0, 0x5E, 0x40,
-0x57, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x2D,
-0x18, 0x84, 0x20, 0xD8, 0x00, 0x40, 0x08, 0x00, 0x3D, 0x00, 0x84, 0x00, 0xD0,
-0x00, 0x40, 0x80, 0x00, 0x01, 0x00, 0x94, 0x00, 0xD0, 0x22, 0x40, 0x8B, 0x20,
-0x2D, 0x08, 0xB4, 0x00, 0xD0, 0x10, 0x40, 0x18, 0x04, 0xAD, 0x00, 0xB4, 0x02,
-0xD0, 0x0F, 0x40, 0x38, 0x00, 0x61, 0x10, 0x84, 0x43, 0x18, 0x4E, 0x40, 0x03,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31, 0x00, 0xCD, 0x06,
-0x06, 0x0B, 0x50, 0x2C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x14, 0x0B, 0xD0, 0x0C,
-0x44, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
-0x02, 0x34, 0x03, 0x50, 0x0C, 0x50, 0x50, 0x00, 0x8D, 0x00, 0x34, 0x02, 0x50,
-0x7C, 0x40, 0xF3, 0x00, 0x81, 0x03, 0x24, 0x16, 0x90, 0x2D, 0x40, 0x13, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x05, 0x00, 0x1F, 0x01, 0x4C,
-0x28, 0xD0, 0x11, 0xD0, 0x44, 0x00, 0x1F, 0x00, 0x4C, 0x04, 0xF0, 0x31, 0xC0,
-0x44, 0x00, 0x13, 0x01, 0x5C, 0x04, 0xF0, 0x11, 0xC0, 0x47, 0x00, 0x1F, 0x01,
-0x7C, 0x04, 0xD0, 0x00, 0xC0, 0x74, 0x00, 0xDF, 0x01, 0x3C, 0x02, 0xD0, 0x0D,
-0xC1, 0xB8, 0x01, 0x43, 0x03, 0x4C, 0x05, 0x30, 0xBD, 0xC0, 0x57, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x77, 0x00, 0xDF, 0x20, 0x7D, 0x87,
-0xF0, 0x1D, 0xC1, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0xF0, 0x1D, 0xC0, 0x77,
-0x10, 0xDF, 0x01, 0x7C, 0x07, 0xF0, 0x1D, 0xC0, 0x73, 0x00, 0xDF, 0x81, 0x7C,
-0x07, 0xF0, 0x1D, 0xC0, 0x27, 0x10, 0x9F, 0x08, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
-0x35, 0x44, 0x5F, 0x10, 0x7C, 0x0B, 0xF2, 0x3D, 0xC4, 0x07, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0F, 0x00, 0x13, 0x00, 0xFC, 0x80, 0x30,
-0x03, 0xC0, 0x0B, 0x00, 0x33, 0x00, 0xBC, 0x40, 0x30, 0x02, 0xC1, 0x0C, 0x08,
-0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x32, 0x10, 0xFC, 0x80,
-0xF0, 0x03, 0xC0, 0x0C, 0x00, 0xEF, 0x09, 0xCC, 0x02, 0x30, 0x0F, 0xC0, 0x3F,
-0x00, 0xB3, 0x00, 0xCC, 0x00, 0x30, 0x5F, 0xC0, 0x10, 0x22, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x85, 0x20, 0x32, 0x00, 0xD1, 0x00, 0x34, 0x03, 0x92, 0x0D,
-0x42, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0x34, 0x00, 0xDD,
-0x00, 0x76, 0x03, 0xD0, 0x0D, 0x42, 0x37, 0x40, 0xD1, 0x00, 0x64, 0x03, 0xD2,
-0x0D, 0xC0, 0x24, 0x08, 0x9D, 0x01, 0x44, 0x02, 0x14, 0x0D, 0x40, 0x37, 0x00,
-0x95, 0x93, 0x14, 0x0C, 0x10, 0x4D, 0x40, 0x15, 0x02, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0xA0, 0x04, 0x00, 0x11, 0x40, 0x74, 0x00, 0x90, 0x01, 0x40,
-0x07, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00,
-0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x15, 0x00, 0x54, 0x00, 0xD0, 0x01,
-0x40, 0x76, 0x80, 0xD9, 0x00, 0x44, 0x03, 0x18, 0x0D, 0x40, 0x37, 0x00, 0xD1,
-0x21, 0x54, 0x0D, 0x12, 0x0D, 0x48, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x28, 0x34, 0x00, 0xC1, 0x00, 0x34, 0x03, 0x94, 0x0C, 0x40, 0x33,
-0x00, 0xC1, 0x00, 0x34, 0x03, 0x14, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x34,
-0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x48,
-0x00, 0x00, 0x8D, 0x00, 0x05, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x20, 0x15, 0x00,
-0x54, 0x02, 0x11, 0x0D, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xB0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x40,
-0x13, 0x00, 0x7C, 0x00, 0x32, 0x01, 0xD0, 0x04, 0x00, 0x1F, 0x00, 0x74, 0x00,
-0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xD0, 0x04,
-0x10, 0xDF, 0x00, 0x4C, 0x02, 0x30, 0x0D, 0xC0, 0x3B, 0x00, 0x93, 0x00, 0x4C,
-0x02, 0x32, 0x45, 0xC0, 0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0xA0, 0x3F, 0x40, 0xFF, 0x80, 0xFC, 0x03, 0x51, 0x0F, 0xC0, 0x3F, 0x00, 0xEF,
-0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC4, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
-0x0F, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x0D, 0x10,
-0xBD, 0x20, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x40, 0xAF, 0x80, 0xFD, 0x02,
-0xF0, 0x29, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
-0x2F, 0x01, 0x73, 0x01, 0xFC, 0x11, 0x34, 0x33, 0xC0, 0x1E, 0x01, 0xB3, 0x14,
-0xCC, 0x07, 0xF0, 0x0B, 0xC0, 0x3C, 0x01, 0xBF, 0x80, 0xCC, 0x27, 0xF0, 0x83,
-0xC0, 0x78, 0x00, 0x23, 0x01, 0xCC, 0xB3, 0xF0, 0x4B, 0xC0, 0x1A, 0x21, 0x73,
-0x01, 0xEC, 0x10, 0xF2, 0x13, 0xC0, 0x3C, 0x05, 0x7F, 0x01, 0xFC, 0x05, 0xF0,
-0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0xF7,
-0x00, 0xD1, 0x81, 0x74, 0x25, 0x12, 0x0D, 0x40, 0xD4, 0x02, 0x91, 0x03, 0x44,
-0x87, 0xD0, 0x39, 0x80, 0xFE, 0x02, 0x9D, 0x03, 0x44, 0x13, 0xD0, 0x61, 0x40,
-0x34, 0x44, 0x13, 0x81, 0xD4, 0x23, 0xD0, 0xB9, 0x40, 0xD4, 0x02, 0x91, 0x01,
-0x44, 0x31, 0xD1, 0x11, 0x40, 0xFC, 0x00, 0x9D, 0x81, 0x34, 0x87, 0xD0, 0x1D,
-0x44, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xA3, 0x00,
-0xC1, 0x00, 0x74, 0x01, 0x50, 0x4C, 0x40, 0x16, 0x00, 0xC5, 0x00, 0x04, 0x03,
-0xD0, 0x20, 0x40, 0x30, 0x00, 0x8D, 0x02, 0x04, 0x13, 0xD0, 0x28, 0x40, 0x30,
-0x01, 0x01, 0x00, 0x04, 0x13, 0xD0, 0x08, 0x60, 0x13, 0x00, 0x81, 0x80, 0x24,
-0x42, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x02, 0x50, 0x0C, 0x40,
-0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x75, 0x00, 0xD1,
-0x00, 0x74, 0x01, 0x10, 0x1D, 0x40, 0x34, 0x04, 0x95, 0x00, 0x44, 0x13, 0xD0,
-0x39, 0x60, 0x36, 0x00, 0x9D, 0x00, 0x44, 0x03, 0xD0, 0x01, 0x40, 0x74, 0x00,
-0x59, 0x00, 0x54, 0x03, 0xD0, 0x0D, 0x40, 0x15, 0x00, 0x91, 0x10, 0x44, 0x63,
-0xD0, 0x21, 0x40, 0x36, 0x00, 0x9D, 0x06, 0x74, 0x9B, 0xD8, 0x0D, 0x40, 0x0F,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA8, 0x23, 0x40, 0x93, 0x40,
-0x3C, 0x3B, 0x71, 0x1D, 0xC0, 0xD2, 0x00, 0x97, 0x00, 0x4C, 0x07, 0xF0, 0x1D,
-0xC0, 0x34, 0x00, 0x8F, 0x00, 0x4D, 0x03, 0xF0, 0x91, 0xD0, 0x34, 0x00, 0x11,
-0x07, 0x4C, 0x03, 0xF0, 0x0C, 0xC0, 0x13, 0x46, 0x53, 0x00, 0x6C, 0x0C, 0xF0,
-0x98, 0xE0, 0x36, 0x00, 0x5F, 0x00, 0x7C, 0x05, 0xE0, 0x0D, 0xC0, 0x0B, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x25, 0x00, 0xBF, 0x45, 0xFC,
-0x05, 0xF0, 0x0F, 0xC0, 0x9F, 0x40, 0xEB, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0,
-0x3F, 0x10, 0xDF, 0x04, 0xFC, 0x03, 0xF0, 0x0C, 0xC0, 0x3F, 0x40, 0xB7, 0x04,
-0xFC, 0x03, 0xF0, 0x0B, 0xC4, 0x7E, 0x00, 0xFF, 0x00, 0x7C, 0x84, 0xF0, 0x03,
-0x70, 0x35, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00, 0x93, 0x01, 0x7C, 0x03,
-0xF0, 0x0D, 0xC0, 0x17, 0x00, 0xD3, 0x10, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x34,
-0x00, 0x97, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x34, 0x00, 0xDB, 0x10, 0x5C,
-0x03, 0xF0, 0x0D, 0xC0, 0x96, 0x84, 0x93, 0x02, 0x7C, 0x08, 0xB4, 0x2D, 0xC0,
-0x37, 0x00, 0xD7, 0x02, 0x7C, 0x02, 0xB0, 0x0D, 0xC0, 0x29, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0xE4, 0x01, 0x91, 0x00, 0x76, 0x05, 0xD0,
-0x0D, 0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xF0, 0x0D, 0xC0, 0x3D, 0x01,
-0xD1, 0x00, 0x44, 0x83, 0xDA, 0x0D, 0x40, 0x34, 0x00, 0xCB, 0x82, 0xC4, 0x43,
-0xD1, 0x0D, 0xC0, 0x37, 0x10, 0x8B, 0x1A, 0x76, 0x00, 0x10, 0x05, 0x40, 0x3F,
-0x00, 0x91, 0x00, 0x74, 0x03, 0xB0, 0x1D, 0xC0, 0x4F, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x01, 0x01, 0x00, 0x34, 0x05, 0xD0, 0x0D,
-0x40, 0x33, 0x02, 0x81, 0x02, 0x34, 0x03, 0xD0, 0x08, 0x44, 0x30, 0x00, 0xC5,
-0x00, 0x24, 0x03, 0xD0, 0x04, 0x40, 0x34, 0x00, 0x01, 0x00, 0x14, 0x07, 0xC0,
-0x08, 0x40, 0xF0, 0x20, 0xC1, 0x03, 0x34, 0x00, 0x90, 0x04, 0x48, 0x33, 0x00,
-0x80, 0x00, 0x36, 0x02, 0x50, 0x8C, 0x40, 0x4E, 0x00, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0D, 0x80, 0x78, 0x20, 0xE1, 0x81, 0xB4, 0x47, 0xD0, 0x1E, 0x60,
-0x5B, 0x10, 0xA1, 0x81, 0xB4, 0x07, 0x50, 0x9B, 0x42, 0x79, 0x00, 0xA1, 0x01,
-0xA4, 0x07, 0xD8, 0x12, 0x40, 0x7C, 0x00, 0xF9, 0x01, 0xA4, 0x07, 0xD0, 0x1A,
-0x40, 0x5E, 0x04, 0xA9, 0x01, 0xB4, 0x05, 0x90, 0x52, 0x40, 0x7B, 0x00, 0xA1,
-0x01, 0xB4, 0x06, 0x90, 0x1E, 0x40, 0x36, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x10, 0x20, 0x00, 0x81, 0x00, 0x34, 0x01, 0xF2, 0x0C, 0xE0, 0x33,
-0x40, 0xC3, 0x00, 0x3C, 0x03, 0xD0, 0x0D, 0xC0, 0x30, 0x00, 0xC6, 0x20, 0x24,
-0x03, 0xD0, 0x4C, 0xC0, 0x30, 0x30, 0x83, 0x58, 0x1C, 0x03, 0xF0, 0x08, 0xC0,
-0x30, 0x00, 0x81, 0x00, 0x34, 0x02, 0xB4, 0x0C, 0xC0, 0x33, 0x40, 0x87, 0x00,
-0x3C, 0x02, 0x70, 0x0C, 0xC4, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3B, 0x02,
-0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0xB3, 0x00, 0xBF, 0x00, 0x5C, 0x03,
-0xF0, 0x03, 0xD0, 0x3F, 0x00, 0xFF, 0x20, 0xDC, 0x03, 0xF0, 0x0E, 0xC0, 0x1F,
-0x00, 0xBF, 0x00, 0xFC, 0x23, 0x70, 0x4B, 0xCA, 0xBF, 0x82, 0xBF, 0x00, 0xFC,
-0x02, 0xF0, 0x0E, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0xA8, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC2, 0x77, 0x00, 0x93,
-0x80, 0x5C, 0x83, 0x70, 0x09, 0x80, 0xB5, 0x22, 0xD3, 0x00, 0x5C, 0x03, 0xF0,
-0x05, 0xC0, 0x77, 0x20, 0x53, 0x00, 0x7C, 0x33, 0xE0, 0x0D, 0xC0, 0x37, 0x00,
-0xDF, 0x00, 0x78, 0x03, 0xB0, 0x1D, 0xC0, 0x36, 0x81, 0xDF, 0x00, 0x4C, 0x02,
-0xF0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98,
-0xB9, 0x10, 0xAD, 0x40, 0x9C, 0x0B, 0xD3, 0x0E, 0x40, 0x13, 0x01, 0xE1, 0x00,
-0x84, 0x03, 0xD0, 0x2A, 0x40, 0x30, 0x11, 0xE1, 0x22, 0xB4, 0x83, 0xD0, 0x0E,
-0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x53, 0x80, 0x0A, 0x40, 0xBB, 0x00, 0xED,
-0x00, 0x34, 0x03, 0x10, 0x0E, 0x60, 0x38, 0x08, 0xAD, 0x00, 0x94, 0x02, 0xD0,
-0x0E, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79,
-0x05, 0xAD, 0x03, 0xB4, 0x57, 0xD0, 0x1E, 0x40, 0x7B, 0x03, 0xC1, 0x09, 0x96,
-0x47, 0xD0, 0x7C, 0x4C, 0x79, 0x60, 0xE1, 0x05, 0xB6, 0x07, 0xD0, 0x1E, 0x40,
-0x7B, 0x00, 0xE1, 0x83, 0xB4, 0x07, 0xC0, 0xDE, 0x08, 0x7B, 0x01, 0xAD, 0x01,
-0xB4, 0x07, 0x10, 0x1F, 0x40, 0x7A, 0x92, 0xED, 0x43, 0x84, 0x06, 0xD0, 0x1E,
-0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x33, 0x00,
-0x8D, 0x40, 0x14, 0x02, 0xD0, 0x3D, 0x41, 0x23, 0x00, 0xC1, 0x00, 0x04, 0x06,
-0xD0, 0x1C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x03, 0xD0, 0xEC, 0x60, 0x23,
-0x00, 0xC1, 0x07, 0x34, 0x03, 0x91, 0x1C, 0x40, 0xA3, 0x09, 0x8D, 0x00, 0x34,
-0x1F, 0x10, 0x3C, 0x44, 0x30, 0x00, 0x8D, 0x00, 0x14, 0x02, 0xD0, 0x0C, 0x40,
-0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x11, 0x10, 0x6F,
-0x00, 0xBC, 0x21, 0xF0, 0x07, 0xC1, 0x1F, 0x40, 0x53, 0x00, 0x5C, 0x01, 0x72,
-0x17, 0xC2, 0x15, 0x00, 0x52, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xC0, 0x17, 0x00,
-0x73, 0x23, 0x7C, 0x01, 0xF2, 0x15, 0xC3, 0x9F, 0x01, 0x7F, 0x05, 0xFC, 0x1D,
-0x34, 0x17, 0xC5, 0x16, 0x00, 0x7F, 0x40, 0xCC, 0x81, 0xE0, 0x05, 0xC0, 0x5F,
-0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x20, 0x1F, 0x04,
-0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01,
-0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC8, 0x07, 0x42, 0x1F,
-0x02, 0x3C, 0x00, 0xB0, 0x01, 0xC2, 0x03, 0x00, 0x1F, 0x00, 0x3C, 0x00, 0x70,
-0x01, 0xC0, 0x07, 0x00, 0x1B, 0x20, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x27, 0x01, 0x9B, 0x01, 0x4C,
-0x22, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xD0,
-0x61, 0x00, 0x96, 0x04, 0x7C, 0x02, 0x70, 0x09, 0xC2, 0x24, 0x00, 0x9F, 0x00,
-0x5C, 0x02, 0x78, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x02, 0x30, 0x49,
-0xC9, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xEE, 0x00, 0x91, 0x89, 0xC4, 0x06,
-0x10, 0x09, 0x40, 0x6C, 0x00, 0xAD, 0x03, 0x44, 0x02, 0xD0, 0x0B, 0x42, 0x64,
-0x00, 0xB1, 0x07, 0x74, 0x02, 0x10, 0x09, 0x40, 0xA4, 0x82, 0x8D, 0x02, 0x44,
-0x02, 0x10, 0x0B, 0x48, 0x2F, 0x00, 0x91, 0x40, 0x74, 0x02, 0xB0, 0x79, 0x40,
-0x27, 0x00, 0x87, 0x00, 0x2C, 0x02, 0x50, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x04, 0x91, 0x00, 0x44, 0x02, 0x16,
-0x0D, 0x60, 0x24, 0x01, 0x9D, 0x0A, 0x40, 0x02, 0xD0, 0x08, 0x40, 0x24, 0x02,
-0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0xA4, 0x20, 0x9D, 0x18, 0x54, 0x02,
-0x50, 0x09, 0x41, 0x27, 0x00, 0x91, 0x00, 0x64, 0x02, 0x00, 0x09, 0x40, 0x27,
-0x00, 0x98, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x88,
-0x40, 0x20, 0x00, 0x8D, 0x00, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x20, 0x00, 0x89,
-0x00, 0x34, 0x22, 0x50, 0x88, 0x40, 0x20, 0x02, 0x8D, 0x40, 0x00, 0x0A, 0x10,
-0x08, 0x48, 0x23, 0x40, 0x81, 0x00, 0x34, 0x22, 0x98, 0x08, 0x40, 0x23, 0x20,
-0x95, 0xC2, 0x64, 0x0A, 0x10, 0x08, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1D, 0xB0, 0x46, 0x40, 0x13, 0x00, 0x4C, 0x04, 0x32, 0x21, 0xD0,
-0x44, 0x00, 0x1F, 0x01, 0x4D, 0x00, 0xF0, 0x11, 0xC0, 0x05, 0x15, 0x1F, 0x01,
-0x7C, 0x08, 0x70, 0x61, 0xD1, 0x80, 0x00, 0x1D, 0x00, 0x5C, 0x50, 0x50, 0x11,
-0x40, 0x47, 0x00, 0x53, 0x40, 0x6C, 0x58, 0x30, 0x01, 0xC0, 0x07, 0x05, 0x0F,
-0x00, 0x4D, 0x00, 0x34, 0x01, 0xC4, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x19, 0xB8, 0xAF, 0x08, 0xBF, 0x00, 0xFD, 0x0A, 0xF0, 0x4B, 0xC0, 0xAF,
-0x00, 0xBF, 0x02, 0xFC, 0x06, 0xF0, 0x3B, 0xC0, 0x27, 0x00, 0xB3, 0x02, 0x7C,
-0x12, 0xB1, 0x4B, 0x80, 0x2F, 0x01, 0xBF, 0x00, 0x7C, 0x06, 0xF0, 0x2B, 0xC0,
-0xAF, 0x08, 0xBF, 0x00, 0xF8, 0x12, 0xF2, 0x0A, 0xC4, 0x27, 0x00, 0xB7, 0x01,
-0xDC, 0x06, 0xF0, 0x09, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0xA0, 0x6F, 0x00, 0xBF, 0x40, 0xC4, 0x56, 0xF0, 0x09, 0xC0, 0x6F, 0x01,
-0xBF, 0x41, 0x7C, 0x02, 0x30, 0x79, 0xC0, 0x2C, 0x00, 0xFF, 0x31, 0x4C, 0x22,
-0xF0, 0x49, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xB0, 0x5B, 0xC1, 0x6D,
-0x14, 0xB3, 0x60, 0x4C, 0x52, 0x32, 0x0B, 0xC0, 0x27, 0x28, 0x9F, 0x02, 0x7C,
-0x0A, 0xF0, 0x0B, 0xC6, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
-0x08, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x08, 0xD0, 0x01, 0x43, 0x97, 0x00, 0x1D,
-0x02, 0x34, 0x54, 0x52, 0x75, 0x50, 0x84, 0x00, 0x1D, 0x02, 0x54, 0x00, 0x90,
-0x41, 0x11, 0x04, 0x41, 0x11, 0x00, 0x74, 0x9C, 0x10, 0x21, 0x40, 0x84, 0x00,
-0x51, 0x00, 0x54, 0x11, 0x50, 0x05, 0x00, 0x87, 0x10, 0x1D, 0x01, 0x74, 0x04,
-0xD0, 0x01, 0x40, 0x73, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0,
-0xA3, 0x80, 0xDD, 0x00, 0x14, 0x02, 0xD0, 0x08, 0x40, 0xB3, 0x30, 0x8C, 0x02,
-0x34, 0x02, 0x10, 0xC8, 0x40, 0x22, 0x02, 0x8D, 0x00, 0x04, 0x02, 0x50, 0xC8,
-0x40, 0x20, 0x25, 0x80, 0x00, 0x34, 0x62, 0x92, 0x08, 0x60, 0x23, 0x00, 0x95,
-0x00, 0x14, 0x52, 0xD0, 0x08, 0x42, 0x23, 0x82, 0x8D, 0x00, 0x34, 0x02, 0xD0,
-0x08, 0x40, 0x4B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25,
-0x00, 0x9D, 0x22, 0x54, 0x02, 0xD0, 0x69, 0x42, 0x27, 0x00, 0x9D, 0x00, 0x34,
-0x02, 0x50, 0x09, 0x40, 0x26, 0x80, 0x9D, 0x00, 0x54, 0x82, 0x90, 0x08, 0x41,
-0x20, 0x00, 0x91, 0x24, 0x76, 0x02, 0x10, 0x09, 0x40, 0x24, 0x02, 0xD5, 0x48,
-0x14, 0x02, 0x50, 0x09, 0x42, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x1A, 0xD0, 0x09,
-0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00,
-0x8F, 0x82, 0x5D, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9F, 0x00, 0xFC, 0x02,
-0x30, 0xAB, 0xC0, 0x26, 0x10, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x29, 0xC0, 0x24,
-0x00, 0x93, 0x04, 0xFC, 0x02, 0xB0, 0x18, 0xC8, 0x27, 0x40, 0x87, 0x00, 0x5C,
-0x0A, 0x60, 0x29, 0xC0, 0x27, 0x00, 0xBF, 0x24, 0xFC, 0x02, 0xF0, 0x09, 0xC0,
-0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x25, 0x00, 0x9F,
-0x00, 0x6C, 0x0E, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9E, 0x09, 0x7C, 0x0E, 0xF0,
-0x08, 0xC0, 0x25, 0x80, 0x8F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0xA7, 0x14,
-0x9F, 0x20, 0x3C, 0x02, 0x70, 0x59, 0xCA, 0x27, 0x08, 0x9B, 0x11, 0x7C, 0x02,
-0xF8, 0x49, 0xC0, 0x27, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x4B,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00,
-0x7C, 0x00, 0xB0, 0x01, 0xC0, 0x87, 0x00, 0x1B, 0x10, 0x7C, 0x00, 0x30, 0x21,
-0xD0, 0x04, 0x02, 0x1F, 0x08, 0x4D, 0x00, 0xF0, 0x01, 0xE0, 0x04, 0x00, 0x17,
-0x10, 0x4C, 0x00, 0xF0, 0x41, 0xC0, 0x02, 0x40, 0x13, 0x02, 0x4C, 0x08, 0xF2,
-0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x43, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x1C, 0x00, 0x5D, 0x00, 0x70,
-0x01, 0x18, 0x05, 0x48, 0x17, 0x00, 0x7C, 0x03, 0x74, 0x01, 0x10, 0x05, 0x50,
-0x54, 0x00, 0x7C, 0x03, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x9C, 0x01, 0x7D, 0x41,
-0x7C, 0x11, 0x70, 0x07, 0xC0, 0xDE, 0x01, 0x70, 0x03, 0x68, 0x01, 0x10, 0x37,
-0x05, 0x14, 0x80, 0x5D, 0x00, 0x74, 0x01, 0xC0, 0x45, 0x40, 0x53, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x22, 0x20, 0x8D, 0x00, 0x30, 0x06,
-0x10, 0x0C, 0x40, 0x23, 0x10, 0x8C, 0x08, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x30,
-0x00, 0x8D, 0x13, 0x24, 0x03, 0xC0, 0x0C, 0x40, 0xB0, 0x00, 0xCD, 0x00, 0x24,
-0x03, 0x50, 0x38, 0x40, 0x20, 0x29, 0xC0, 0x0A, 0x04, 0x03, 0x90, 0x38, 0x01,
-0x31, 0x00, 0xCD, 0x80, 0x36, 0x03, 0xC0, 0x0C, 0x40, 0x53, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x40, 0xB4, 0x0F, 0x10,
-0x0E, 0x48, 0x3B, 0x00, 0xAD, 0x00, 0xB4, 0x23, 0x10, 0x4C, 0x40, 0x28, 0x00,
-0xAD, 0x00, 0xA4, 0x03, 0xD0, 0x4E, 0x60, 0x38, 0x80, 0xFD, 0x03, 0xA4, 0x23,
-0x50, 0x28, 0x40, 0x3A, 0x00, 0xF1, 0x00, 0x26, 0x23, 0x10, 0x1B, 0x40, 0x38,
-0x00, 0xED, 0x04, 0xB4, 0x13, 0x90, 0x0E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x10, 0x68, 0x00, 0xEF, 0x01, 0x3C, 0x07, 0x34, 0x3E,
-0xC0, 0x7B, 0x00, 0xAF, 0x81, 0xBC, 0x07, 0x34, 0x7E, 0x40, 0x78, 0x00, 0xAD,
-0x01, 0xA4, 0x1F, 0xF9, 0xBF, 0x40, 0x48, 0x00, 0xE7, 0x01, 0xAC, 0x17, 0x70,
-0x16, 0xE0, 0x68, 0x00, 0xE3, 0x01, 0x8C, 0x57, 0xB0, 0x1E, 0xE0, 0x79, 0x00,
-0xED, 0x03, 0xBE, 0x0F, 0xF0, 0x1E, 0xC4, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xB8, 0x25, 0x20, 0xDF, 0x00, 0x7C, 0x03, 0xF1, 0x0D, 0x44,
-0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x10, 0x8F, 0x00,
-0x5C, 0x4B, 0xF0, 0x6D, 0xD0, 0x07, 0x00, 0x0F, 0x00, 0x7C, 0x83, 0x70, 0x05,
-0xC0, 0x33, 0x08, 0xCF, 0x00, 0x7C, 0x0B, 0x71, 0x0C, 0xC0, 0x37, 0x10, 0xDF,
-0x00, 0x74, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA0, 0x6F, 0x00, 0xF3, 0x09, 0xFC, 0x83, 0x30, 0x9F, 0xC0, 0x7F,
-0x02, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1E, 0x80, 0x7D, 0x00, 0xBF, 0x01, 0xFC,
-0x27, 0x30, 0x1F, 0xC0, 0x7E, 0x22, 0xFF, 0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xC0,
-0x6C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xB0, 0x1B, 0xC0, 0x7F, 0x02, 0xEF, 0x09,
-0x8C, 0x07, 0x30, 0x1F, 0xC0, 0x03, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x88, 0x39, 0x00, 0xE1, 0x80, 0xB0, 0x53, 0xB4, 0x0E, 0x46, 0x3B, 0x02,
-0xE1, 0x80, 0xB4, 0x03, 0x70, 0x4E, 0x48, 0x39, 0x00, 0xAD, 0x04, 0xB4, 0x03,
-0x10, 0x0E, 0x41, 0x38, 0x00, 0xED, 0x06, 0xB4, 0x02, 0x90, 0x0E, 0xC4, 0x39,
-0x00, 0x2F, 0x00, 0xF4, 0x83, 0x10, 0x4A, 0x00, 0x3B, 0x08, 0xED, 0x20, 0xAC,
-0x03, 0xF0, 0x0E, 0x40, 0x57, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x29, 0x04, 0xE1, 0x00, 0x30, 0x33, 0x18, 0x0E, 0x60, 0x33, 0xC0, 0xE9,
-0x10, 0xB4, 0x27, 0xD0, 0x1F, 0x72, 0x3B, 0x00, 0xAD, 0x80, 0xB4, 0x03, 0x98,
-0x0C, 0x40, 0x29, 0x20, 0xEC, 0x10, 0xA4, 0x02, 0xD0, 0x0E, 0x40, 0x2A, 0x00,
-0xED, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x48, 0x3B, 0xA0, 0xFD, 0x11, 0xC4, 0x07,
-0x10, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28,
-0x63, 0x00, 0xC1, 0x20, 0x34, 0x8B, 0x90, 0x1C, 0x40, 0xB3, 0x01, 0x49, 0x20,
-0x34, 0x07, 0x50, 0x2C, 0x40, 0x31, 0x00, 0x8D, 0x01, 0x34, 0x03, 0x94, 0x1C,
-0x64, 0x61, 0x00, 0x0D, 0x13, 0x74, 0x82, 0x90, 0x9C, 0x40, 0xF1, 0x00, 0x05,
-0x03, 0x34, 0x03, 0x11, 0x1C, 0x40, 0x33, 0x10, 0xCD, 0x03, 0x04, 0x0B, 0x58,
-0x0C, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x65,
-0x00, 0xC3, 0x04, 0x7C, 0x07, 0x10, 0x1F, 0x40, 0x37, 0x04, 0x8B, 0x01, 0x74,
-0x03, 0xF0, 0x0D, 0xD0, 0x37, 0x00, 0xDF, 0x11, 0xFC, 0x03, 0xB0, 0x2F, 0xC0,
-0x35, 0x11, 0x5F, 0x03, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0xA6, 0x08, 0x9D, 0x04,
-0xFC, 0x17, 0x54, 0x68, 0xC0, 0x37, 0x00, 0xDF, 0xC3, 0x45, 0x13, 0x15, 0x0D,
-0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x40,
-0xDF, 0x00, 0x7C, 0x13, 0x70, 0x8D, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x23,
-0xF0, 0x4D, 0xD0, 0x27, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0x70, 0x0D, 0x00, 0xB4,
-0x08, 0x5F, 0x80, 0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x06, 0x9F, 0x02, 0x3C,
-0x03, 0x50, 0x09, 0xC0, 0x33, 0x00, 0xDE, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0,
-0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x27, 0x00, 0xFF,
-0x90, 0xCD, 0x03, 0xF1, 0x0F, 0xC1, 0x3E, 0x00, 0xBF, 0x01, 0xCE, 0x03, 0x32,
-0x0F, 0xE0, 0x2C, 0x00, 0xBF, 0x01, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x5F, 0x00,
-0x7F, 0x01, 0xFC, 0x23, 0x38, 0x05, 0xE0, 0x2C, 0x01, 0x38, 0x90, 0xFC, 0x03,
-0x30, 0x4B, 0xDD, 0x3D, 0x00, 0xF3, 0x10, 0xCC, 0x43, 0x78, 0x9F, 0xC0, 0x13,
-0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x56, 0x00, 0xDD, 0x49,
-0x44, 0x03, 0x70, 0x0C, 0x40, 0x74, 0x08, 0x9D, 0x00, 0x04, 0x03, 0xB0, 0x0D,
-0xC0, 0x66, 0x80, 0x9D, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x15, 0x03, 0x1D,
-0x23, 0x5C, 0x02, 0xB0, 0x04, 0x44, 0x25, 0x00, 0x1D, 0x41, 0x74, 0x03, 0x70,
-0x09, 0x40, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xD0, 0x1D, 0x40, 0x17, 0x02,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA4, 0x01, 0xDD, 0x00, 0x44,
-0x07, 0xD0, 0x0D, 0x60, 0x36, 0x02, 0x9D, 0x04, 0x44, 0x03, 0x10, 0x0C, 0x48,
-0x34, 0x02, 0xDD, 0x06, 0x74, 0x03, 0xD0, 0x0D, 0x60, 0x07, 0x00, 0x9D, 0x44,
-0x74, 0x03, 0x93, 0x0D, 0x40, 0xA4, 0x00, 0x9D, 0x01, 0x74, 0x03, 0x10, 0x29,
-0x40, 0x34, 0x00, 0xC0, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x07, 0x20, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xDD, 0x20, 0x04, 0x03,
-0xD0, 0x0D, 0x40, 0x30, 0x80, 0x8D, 0x00, 0x45, 0x03, 0x99, 0x0C, 0x40, 0x30,
-0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x01, 0x00, 0x8D, 0x00, 0x10,
-0x02, 0x90, 0x0C, 0x60, 0x11, 0x00, 0x0D, 0x00, 0x34, 0x03, 0x50, 0x08, 0x40,
-0x30, 0x40, 0xC1, 0x00, 0x24, 0x03, 0xD0, 0x08, 0x40, 0x43, 0xA1, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x26, 0x00, 0xDD, 0x00, 0x44, 0x03, 0xF8,
-0x0D, 0xC0, 0x36, 0x00, 0xDF, 0x40, 0xC6, 0x03, 0x32, 0x0F, 0x50, 0x24, 0x20,
-0x5D, 0x00, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x07, 0x00, 0x9D, 0x00, 0x78, 0x03,
-0x90, 0x0D, 0x40, 0x24, 0x08, 0x1F, 0x00, 0xFC, 0x03, 0x31, 0x05, 0xC0, 0x35,
-0x00, 0xF3, 0x00, 0xCC, 0x03, 0xF0, 0x0D, 0xC0, 0x03, 0xC4, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x20, 0xFF, 0x00, 0xFC, 0x03, 0x7A, 0x0F,
-0xC0, 0x3F, 0x00, 0x7C, 0x00, 0xFC, 0x03, 0xF3, 0x0F, 0xC0, 0x2F, 0x00, 0x7F,
-0x00, 0xFC, 0x83, 0xF1, 0x0F, 0x80, 0x0D, 0x00, 0x3E, 0x00, 0xDC, 0x82, 0xF0,
-0x0F, 0xC0, 0x1F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x70, 0x07, 0x40, 0x3F, 0x00,
-0xF7, 0x00, 0xFC, 0x03, 0xF8, 0x0B, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x80, 0x5F, 0x00, 0x33, 0x8C, 0xCC, 0x10, 0x30, 0x1F, 0xC0,
-0x2F, 0x00, 0x33, 0x00, 0xCC, 0x02, 0x30, 0x1F, 0xE0, 0x7F, 0x00, 0xBB, 0x01,
-0xF4, 0x07, 0x70, 0x0B, 0xC0, 0x7C, 0x05, 0xFF, 0x42, 0xFC, 0x32, 0xF0, 0x4F,
-0xC8, 0x3F, 0x01, 0xFF, 0x01, 0xFC, 0x0C, 0x30, 0x4F, 0xC0, 0x4E, 0x00, 0xB3,
-0x00, 0x7C, 0x73, 0xF0, 0x4F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x08, 0x77, 0x00, 0x11, 0x0E, 0x6C, 0x24, 0x30, 0x1D, 0x40, 0x23,
-0x00, 0x51, 0x03, 0x14, 0x02, 0x50, 0x4D, 0x49, 0x33, 0x10, 0xC1, 0x10, 0x74,
-0x04, 0x10, 0xB9, 0xE0, 0xFE, 0x00, 0xFD, 0x0A, 0x74, 0x22, 0xD0, 0xBF, 0x40,
-0x3F, 0x0B, 0xCD, 0x00, 0x74, 0x00, 0x50, 0x3D, 0x40, 0x44, 0x00, 0x91, 0x0B,
-0xF4, 0x03, 0xD1, 0x1F, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x11, 0xA0, 0x27, 0x00, 0x41, 0x00, 0x05, 0x00, 0x10, 0x0C, 0x40, 0x23, 0x00,
-0x81, 0x02, 0x04, 0x03, 0x10, 0x4C, 0x40, 0x33, 0x00, 0xC9, 0x00, 0x74, 0x03,
-0x54, 0x04, 0x50, 0x32, 0x20, 0xC5, 0x84, 0x34, 0x12, 0xD0, 0x0C, 0x40, 0x31,
-0x04, 0xCD, 0x00, 0x54, 0x11, 0x10, 0x2C, 0x48, 0x46, 0x80, 0xC1, 0x00, 0x14,
-0x13, 0xD0, 0x2C, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA8, 0x25, 0x02, 0x51, 0x00, 0x44, 0x08, 0x10, 0x0D, 0x40, 0x27, 0x02, 0x51,
-0x00, 0x54, 0x03, 0x50, 0x0D, 0x48, 0x37, 0x00, 0xD9, 0x03, 0x74, 0x18, 0x14,
-0x15, 0x50, 0x36, 0x00, 0xD9, 0x00, 0x70, 0x22, 0xD0, 0x0D, 0x40, 0x37, 0x20,
-0xDD, 0x00, 0x74, 0x09, 0x50, 0x0D, 0x40, 0x46, 0x40, 0xD1, 0x11, 0x74, 0x03,
-0xD1, 0x0D, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8,
-0x53, 0x01, 0x13, 0x10, 0x44, 0x0C, 0x30, 0x0D, 0xC0, 0x27, 0x40, 0x13, 0x80,
-0x44, 0x06, 0x34, 0x0D, 0x40, 0x37, 0x00, 0xDB, 0x01, 0x3C, 0x09, 0x70, 0x31,
-0x40, 0x36, 0x30, 0xDF, 0x00, 0x78, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
-0x00, 0x7C, 0x0C, 0x30, 0x0D, 0xC0, 0x42, 0x10, 0xD3, 0x01, 0x7C, 0x03, 0xF1,
-0x0D, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x7D,
-0x50, 0xEF, 0x10, 0xBC, 0x22, 0x70, 0x0F, 0xC0, 0x2B, 0x00, 0x9F, 0x00, 0xB8,
-0x26, 0xB0, 0x0F, 0x88, 0x3F, 0x00, 0xF7, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0,
-0x3F, 0x00, 0xFF, 0x20, 0xF8, 0x06, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x10,
-0xFC, 0x24, 0xF0, 0x0E, 0xC0, 0x0D, 0x28, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
-0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x08,
-0x1F, 0x00, 0x6C, 0x29, 0x30, 0x0D, 0xC0, 0x27, 0x01, 0xC7, 0x80, 0x4C, 0x03,
-0x34, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x02, 0x4E, 0x08, 0x22, 0x05, 0xC8, 0x34,
-0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x6D,
-0x09, 0x70, 0x0D, 0xC0, 0x07, 0x00, 0xDF, 0x0A, 0x7C, 0x03, 0xF1, 0x0D, 0xC4,
-0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD,
-0x00, 0x45, 0x03, 0x10, 0x0D, 0x40, 0xA7, 0x00, 0xD1, 0x00, 0x4D, 0x03, 0x10,
-0x0D, 0xC0, 0x76, 0x02, 0xD1, 0x00, 0x45, 0x01, 0xB0, 0x04, 0xC1, 0x3E, 0x00,
-0xFD, 0x00, 0x7C, 0x03, 0xC1, 0x1F, 0xC1, 0x3E, 0x00, 0xDD, 0x00, 0x04, 0x01,
-0x10, 0x0F, 0xC0, 0x45, 0x00, 0xDD, 0x41, 0xF4, 0x83, 0xD0, 0x5F, 0x40, 0x4F,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x00, 0x8D, 0x01,
-0x04, 0x07, 0x10, 0x0C, 0x40, 0x32, 0x00, 0x05, 0x00, 0x04, 0x03, 0xD0, 0x0C,
-0x40, 0xF4, 0x00, 0xC5, 0x00, 0x04, 0x06, 0x18, 0x08, 0x40, 0x70, 0x00, 0xCD,
-0x80, 0x34, 0x03, 0xC0, 0x1C, 0x40, 0x30, 0x08, 0xCD, 0xC0, 0x04, 0x01, 0x50,
-0x0C, 0x40, 0x53, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x1F, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x68, 0x00, 0x2D, 0x19, 0x04,
-0x07, 0x10, 0x1E, 0x40, 0x6B, 0x00, 0x61, 0x01, 0xA4, 0x27, 0x90, 0x1E, 0x40,
-0x7A, 0x00, 0xE1, 0x01, 0xC4, 0x04, 0x99, 0x9A, 0x40, 0x7A, 0x00, 0xED, 0x81,
-0x94, 0x07, 0xD0, 0x9E, 0x40, 0x7A, 0x00, 0xED, 0x81, 0x84, 0x07, 0x10, 0x1E,
-0x40, 0x49, 0x00, 0x6D, 0x01, 0xB4, 0x27, 0xD0, 0x1E, 0x40, 0x13, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x20, 0x00, 0xDF, 0x00, 0x04, 0x03,
-0x30, 0x0C, 0xC0, 0x22, 0x02, 0x85, 0x08, 0x04, 0x23, 0xF0, 0x0D, 0x40, 0x30,
-0x04, 0xC7, 0x08, 0x04, 0x42, 0x30, 0x00, 0xC0, 0x30, 0x04, 0xCF, 0x00, 0x34,
-0x02, 0xF0, 0x8C, 0xC0, 0x30, 0x00, 0xCF, 0x80, 0x4C, 0x01, 0x70, 0x0C, 0xC0,
-0x13, 0x84, 0xCF, 0x00, 0x1C, 0x17, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x00, 0x7F, 0x00, 0xDD, 0x03, 0xD0,
-0x0F, 0xC0, 0x2F, 0x80, 0x7F, 0x00, 0xDE, 0xA3, 0x70, 0x0F, 0xC8, 0x3F, 0x00,
-0xF7, 0x00, 0xBC, 0x22, 0xF0, 0x0A, 0xC0, 0x3F, 0x00, 0xFF, 0x08, 0xFC, 0x22,
-0xF0, 0xAE, 0xC2, 0x3F, 0x20, 0xFF, 0x08, 0xDC, 0x21, 0xF0, 0x0F, 0xC4, 0x0F,
-0x10, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0xA8, 0x37, 0x00, 0x9F, 0x00, 0x4C, 0x00, 0x31, 0x0D,
-0xC0, 0x3F, 0x00, 0x1F, 0x00, 0x7C, 0x07, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
-0x00, 0x7C, 0x04, 0x30, 0x15, 0xC0, 0xB5, 0x04, 0xDF, 0x07, 0x6C, 0x03, 0xF0,
-0x5D, 0xC0, 0x36, 0x05, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x53, 0x00,
-0xD1, 0x40, 0x78, 0x17, 0x34, 0x2D, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x98, 0x39, 0x00, 0xED, 0x00, 0x84, 0x02, 0x10, 0x0E, 0x40,
-0x3B, 0x90, 0xAC, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x20,
-0xB4, 0x00, 0x50, 0x0E, 0x40, 0x38, 0x01, 0xCD, 0x12, 0x84, 0x03, 0xD0, 0x0E,
-0x40, 0xB8, 0x00, 0xE7, 0x00, 0x9C, 0x03, 0xD0, 0x6E, 0x40, 0x0B, 0x00, 0xE1,
-0x00, 0xF4, 0x2B, 0x10, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x00, 0xE9, 0x00, 0x8D, 0x03, 0x24, 0x05, 0x94, 0x1E, 0x40, 0x7B,
-0x10, 0xEC, 0x03, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x01, 0xF6,
-0x07, 0x10, 0x14, 0x41, 0x79, 0x02, 0xED, 0x05, 0x84, 0x07, 0x50, 0xDC, 0x40,
-0x7A, 0x00, 0xED, 0x01, 0x96, 0x05, 0xD0, 0x1E, 0x40, 0x5B, 0x80, 0xE1, 0x41,
-0xB4, 0x17, 0x10, 0x9E, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x20, 0x63, 0x00, 0xCD, 0x00, 0x05, 0x13, 0x90, 0x0C, 0x40, 0x33, 0x02,
-0xC9, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x42, 0x33, 0x00, 0x4C, 0x08, 0x34, 0x0B,
-0x50, 0x3C, 0x40, 0x30, 0x00, 0xCC, 0x00, 0x04, 0x07, 0xD1, 0x0C, 0x40, 0x32,
-0x20, 0xC5, 0x00, 0x54, 0x0B, 0xD0, 0x0C, 0x44, 0x23, 0x00, 0xC1, 0x07, 0x34,
-0x03, 0x10, 0x0C, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
-0xA8, 0x1D, 0x00, 0x7F, 0x0A, 0xEC, 0x1D, 0xB0, 0x05, 0x40, 0x57, 0x00, 0x7F,
-0x0A, 0x7C, 0x01, 0xB4, 0x05, 0xC0, 0x17, 0x10, 0x7D, 0x02, 0xFC, 0x21, 0x30,
-0x27, 0xC0, 0x15, 0x10, 0x5F, 0x00, 0x4C, 0x15, 0xF0, 0x05, 0xC0, 0x16, 0x80,
-0x5F, 0xC0, 0xDC, 0x01, 0xF1, 0x05, 0xC0, 0x1F, 0x02, 0x73, 0x02, 0x74, 0x01,
-0x30, 0x05, 0xC0, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00,
-0x07, 0x00, 0x0F, 0x02, 0x3C, 0x00, 0x70, 0x01, 0xC8, 0x07, 0x00, 0x1F, 0x00,
-0x7C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x20, 0xF0, 0x41,
-0xC0, 0x03, 0x80, 0x1F, 0x00, 0x5D, 0x00, 0xF0, 0x01, 0xC0, 0x01, 0x80, 0x1F,
-0x02, 0x5C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x08, 0x7C, 0x00, 0xF0,
-0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27,
-0x00, 0x9F, 0x00, 0x4C, 0x22, 0x34, 0x09, 0xC0, 0x23, 0x00, 0x83, 0x00, 0x4C,
-0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x00, 0x4C, 0xA2, 0xF0, 0x09, 0xC0,
-0x67, 0x00, 0x9B, 0x80, 0x7C, 0x02, 0xD2, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x84,
-0x7C, 0x02, 0xB0, 0x08, 0xC0, 0x64, 0x00, 0x8F, 0x01, 0x6C, 0x02, 0xF0, 0x09,
-0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00,
-0x9D, 0x03, 0x44, 0x06, 0x10, 0x09, 0x40, 0x27, 0x00, 0x95, 0x00, 0x6C, 0x22,
-0xD0, 0x09, 0x40, 0xA7, 0x00, 0x8D, 0x00, 0x6C, 0x06, 0xD0, 0x09, 0x40, 0x27,
-0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0xC4, 0x27, 0x00, 0x91, 0x03, 0x74,
-0x02, 0x50, 0x09, 0xC0, 0x66, 0x02, 0x9D, 0x09, 0x6C, 0x02, 0xD0, 0x09, 0x40,
-0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D,
-0x04, 0x44, 0x02, 0x19, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x58,
-0x09, 0x40, 0x27, 0x05, 0x9D, 0x00, 0x66, 0x02, 0x52, 0x8D, 0x40, 0x27, 0x01,
-0x99, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x26, 0x00, 0x90, 0x02, 0x74, 0x02,
-0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0xC0, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x63,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xA0, 0x00, 0x8D, 0x04,
-0x04, 0x12, 0x10, 0x08, 0x40, 0x33, 0x01, 0x85, 0x04, 0x24, 0x12, 0xD0, 0x08,
-0x40, 0x23, 0x00, 0x9D, 0x00, 0x04, 0x02, 0xD0, 0x48, 0x40, 0x23, 0x01, 0x81,
-0x04, 0x34, 0x12, 0xD0, 0x08, 0x48, 0x21, 0x01, 0x81, 0x00, 0x34, 0x22, 0x50,
-0x08, 0x4A, 0x22, 0x00, 0x8D, 0x04, 0x26, 0x12, 0xD0, 0x48, 0x48, 0x43, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x5F, 0x0A, 0x4C,
-0x00, 0x31, 0x01, 0x40, 0x87, 0x02, 0x13, 0x00, 0x0C, 0x28, 0x70, 0xA1, 0xC0,
-0x87, 0x02, 0x1F, 0x0A, 0x64, 0x00, 0x70, 0x01, 0xC4, 0x07, 0x00, 0x1B, 0x0A,
-0x74, 0x28, 0xF0, 0x41, 0x41, 0x87, 0x42, 0x13, 0x0A, 0x7C, 0x08, 0xB0, 0x41,
-0xC1, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x98, 0x6F, 0x00, 0xBF, 0x28, 0xF5, 0x22,
-0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF, 0x28, 0xFC, 0x22, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0xBE, 0x40, 0xBD, 0x02, 0xF0, 0x8B, 0xC0, 0x27, 0x02, 0x9F, 0x08, 0xFC,
-0x22, 0xF0, 0x09, 0xC2, 0x27, 0x02, 0x9F, 0x00, 0xFC, 0x12, 0xF0, 0x09, 0xC0,
-0x2F, 0x00, 0xBF, 0x08, 0x7C, 0x22, 0xF0, 0x89, 0xC0, 0x67, 0x60, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x27, 0x00, 0xBF, 0x14, 0xCC, 0x12, 0xF0,
-0x09, 0xC0, 0x2F, 0x00, 0x93, 0x00, 0xFC, 0x12, 0x70, 0x0B, 0xC0, 0x2F, 0x02,
-0x8F, 0x00, 0xBC, 0x02, 0x32, 0x0B, 0xC0, 0x2C, 0x01, 0x9F, 0x14, 0x4C, 0x32,
-0x30, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x08, 0x4C, 0x02, 0xF2, 0x49, 0xC1, 0x2F,
-0x00, 0xBF, 0x00, 0x7C, 0x02, 0x20, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1C, 0x08, 0x57, 0x05, 0x1D, 0x04, 0x44, 0x20, 0xD0, 0x01,
-0x48, 0x07, 0x04, 0x1B, 0x08, 0x74, 0x50, 0x10, 0x41, 0x40, 0x07, 0x81, 0x1D,
-0x50, 0x74, 0x00, 0x11, 0x81, 0xC0, 0x06, 0x00, 0x1D, 0x04, 0x45, 0x30, 0xB0,
-0x21, 0xC0, 0x06, 0x0C, 0x11, 0x00, 0x44, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00,
-0x1D, 0x02, 0x74, 0x40, 0x10, 0x01, 0xC0, 0x72, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x14, 0x05, 0x02, 0xD0, 0x08, 0x40,
-0x23, 0x02, 0x81, 0x01, 0x14, 0x32, 0x51, 0x48, 0x41, 0x23, 0x01, 0x8D, 0x05,
-0x74, 0x03, 0x10, 0x08, 0x40, 0x30, 0x02, 0x89, 0x14, 0x04, 0x12, 0x10, 0x88,
-0x40, 0x20, 0x42, 0x81, 0x00, 0x24, 0x12, 0x90, 0x08, 0x40, 0x23, 0x80, 0x8D,
-0x09, 0x34, 0x02, 0x14, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA8, 0x25, 0x02, 0x9D, 0x04, 0x44, 0x12, 0xD0, 0x09, 0x40, 0x27,
-0x02, 0x99, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74,
-0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x8D, 0x00, 0x44, 0x22, 0x94, 0x09, 0x40,
-0x26, 0x00, 0xD1, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0xA7, 0x00, 0x9D, 0x08,
-0x74, 0x02, 0x11, 0x09, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0x08, 0x2D, 0x10, 0x9F, 0x01, 0x4C, 0x06, 0xF0, 0x09, 0x40, 0x27, 0x00,
-0x93, 0x01, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9D, 0x00, 0x3C, 0x46,
-0x34, 0x09, 0x50, 0x24, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x24,
-0x00, 0x93, 0x00, 0x6D, 0x6E, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x02, 0x78,
-0x02, 0x30, 0x09, 0xC0, 0x14, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x00, 0x65, 0x00, 0x9F, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
-0x83, 0x7E, 0x0E, 0xF0, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x49, 0x7C, 0x26, 0xF0,
-0x49, 0xC0, 0x27, 0x08, 0x9F, 0x20, 0x3C, 0x06, 0x71, 0x09, 0xC0, 0x23, 0x00,
-0x9F, 0x00, 0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0x3C, 0x02,
-0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
-0x85, 0x00, 0x0F, 0x01, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x01, 0x1F, 0x00,
-0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1B, 0x00, 0x4F, 0x00, 0xB0, 0x01,
-0xC0, 0x06, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x00, 0xC0, 0x07, 0x00, 0x1F,
-0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0,
-0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14,
-0x00, 0x7D, 0x00, 0x74, 0x81, 0xD0, 0x05, 0xC0, 0x9D, 0x04, 0x5D, 0x00, 0x7E,
-0x01, 0xD0, 0x15, 0x40, 0x5F, 0x01, 0x51, 0x00, 0x44, 0x01, 0x14, 0x04, 0xD0,
-0x16, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x10, 0x45, 0xC0, 0x14, 0x00, 0x7D, 0x10,
-0x44, 0x01, 0xD0, 0x05, 0x44, 0x17, 0x20, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x04,
-0x40, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00,
-0xCD, 0x00, 0x34, 0x02, 0xDA, 0x0C, 0x48, 0x35, 0x20, 0xCD, 0x00, 0x74, 0x03,
-0xD0, 0x9C, 0x40, 0x33, 0x80, 0xC9, 0x20, 0x10, 0x02, 0x90, 0x8C, 0x40, 0x22,
-0x00, 0xCD, 0x00, 0x36, 0x03, 0x18, 0x08, 0x40, 0x31, 0x00, 0xDD, 0x01, 0x24,
-0x83, 0xD0, 0x0C, 0x40, 0x23, 0x82, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40,
-0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x81, 0xED,
-0x00, 0xB4, 0x43, 0xD9, 0x0E, 0x40, 0x39, 0x00, 0xED, 0x00, 0x94, 0x43, 0xD0,
-0x0E, 0x40, 0x6B, 0x01, 0xF1, 0x05, 0xD4, 0x03, 0x10, 0x0F, 0x50, 0x3A, 0x00,
-0xED, 0x08, 0x34, 0x03, 0x18, 0x0E, 0x40, 0x39, 0x08, 0xED, 0x00, 0xA4, 0x03,
-0xC0, 0x0E, 0x40, 0x3B, 0x80, 0xED, 0x00, 0xB4, 0x13, 0xD0, 0x0E, 0x40, 0x13,
-0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0xF8, 0x00, 0x2F, 0x01,
-0xBC, 0x07, 0xF0, 0x1E, 0xC0, 0x59, 0x00, 0xEF, 0x01, 0xB4, 0x06, 0xF0, 0x1E,
-0xE4, 0xFB, 0x00, 0xEB, 0x11, 0x94, 0x07, 0xB2, 0x1E, 0xD0, 0x7A, 0x00, 0xEF,
-0x15, 0xBC, 0x5F, 0x70, 0x1C, 0xC0, 0x79, 0x00, 0xFF, 0x01, 0xAC, 0x07, 0xE0,
-0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xB4, 0x37, 0xF0, 0x1A, 0xC0, 0x53, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C,
-0x03, 0xF0, 0x0D, 0xC4, 0x15, 0x10, 0xDF, 0x00, 0x7C, 0x0A, 0xB0, 0x0D, 0xC0,
-0x03, 0x00, 0xDF, 0x08, 0x6C, 0x03, 0xF2, 0x0C, 0xD0, 0x37, 0x00, 0xDF, 0x20,
-0x7C, 0x03, 0xF4, 0x0D, 0xC0, 0x34, 0x07, 0x5F, 0x00, 0x5C, 0x03, 0xF0, 0x0D,
-0xC8, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x23, 0xF0, 0x0D, 0xC0, 0x43, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7B, 0x00, 0xF3, 0x01, 0xCC, 0x07,
-0xFA, 0x8F, 0xC0, 0x6F, 0x02, 0xF3, 0x09, 0x8C, 0x0F, 0x30, 0x1F, 0xC0, 0x7F,
-0x00, 0xF3, 0x01, 0xEC, 0x07, 0x30, 0x1E, 0xC0, 0x7C, 0x30, 0xF7, 0x41, 0xCC,
-0x07, 0x70, 0x1F, 0xC4, 0x7C, 0x00, 0xF3, 0x01, 0xDC, 0x47, 0x72, 0x1F, 0xC8,
-0x7B, 0x22, 0xF7, 0xA1, 0xFC, 0x87, 0x32, 0x1B, 0xC2, 0x08, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0x61, 0x40, 0x84, 0x03, 0x78,
-0x0E, 0x44, 0x2B, 0x10, 0xE1, 0x20, 0xAC, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00,
-0xF1, 0x00, 0x84, 0x13, 0x50, 0x4E, 0x44, 0x39, 0x00, 0xF1, 0x00, 0xC4, 0x03,
-0x10, 0x0E, 0xC0, 0x3E, 0x02, 0xE1, 0x00, 0x86, 0x03, 0xF0, 0x0E, 0x40, 0x3B,
-0x40, 0xE5, 0x00, 0x34, 0x03, 0x10, 0x0E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x25, 0x00, 0x84, 0x03, 0x50, 0x8E,
-0x40, 0x0B, 0x00, 0xC0, 0x20, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE1,
-0x02, 0xC4, 0x03, 0x12, 0x0E, 0x60, 0x38, 0x00, 0xE5, 0x00, 0x84, 0x03, 0x10,
-0x0E, 0x40, 0x39, 0x00, 0xE1, 0x00, 0xD4, 0x03, 0x10, 0x0E, 0x40, 0x3F, 0x40,
-0xED, 0x00, 0x34, 0x03, 0x10, 0x08, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0x41, 0x03, 0x05, 0x1B, 0x50, 0x0C, 0x40,
-0x43, 0x40, 0xC1, 0x02, 0x24, 0x02, 0x10, 0x0C, 0x40, 0x13, 0x00, 0xC1, 0x41,
-0x04, 0x03, 0x51, 0x0C, 0x60, 0x31, 0x00, 0xC1, 0x00, 0x05, 0x03, 0x10, 0x0C,
-0x40, 0x33, 0x00, 0x41, 0x00, 0x04, 0x0B, 0xD0, 0x0C, 0x40, 0x33, 0x02, 0x8D,
-0x42, 0x34, 0x03, 0x14, 0x0C, 0x50, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0xA8, 0xB5, 0x42, 0xD7, 0x06, 0x0C, 0x03, 0x70, 0x0D, 0xC0, 0x27,
-0x04, 0xD3, 0x00, 0x4C, 0x02, 0x34, 0x0D, 0xC0, 0x3F, 0x40, 0xF1, 0x01, 0x0C,
-0x07, 0x30, 0xAC, 0x40, 0x30, 0x00, 0xF7, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0,
-0x3D, 0x00, 0xD3, 0x00, 0xDC, 0x23, 0x70, 0x0D, 0x40, 0xF7, 0x42, 0xDF, 0x02,
-0xFC, 0x03, 0x30, 0x09, 0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x37, 0x00, 0x9F, 0x10, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0xA7, 0x00,
-0xDF, 0x01, 0x5C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x08, 0x5C, 0x63,
-0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x36,
-0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C,
-0x03, 0xF0, 0x09, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x08, 0x3F, 0x00, 0x33, 0x00, 0xFC, 0x03, 0x30, 0x0F, 0xC0, 0x07, 0x00, 0xF7,
-0x10, 0xFC, 0x02, 0x30, 0x5F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0x30,
-0x9B, 0xC0, 0x34, 0x00, 0xE3, 0x00, 0xCC, 0x03, 0x30, 0x1D, 0xC0, 0x3F, 0x00,
-0xB3, 0x01, 0xFE, 0x03, 0xF0, 0x0F, 0xCA, 0xBF, 0x00, 0xFE, 0x10, 0xF4, 0x03,
-0x30, 0x5A, 0x80, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
-0x36, 0x00, 0x95, 0x00, 0x74, 0x07, 0x10, 0x0D, 0x40, 0xC7, 0x04, 0xD1, 0x00,
-0x74, 0x26, 0x10, 0x1D, 0x40, 0x07, 0x00, 0xD9, 0x00, 0x74, 0x03, 0x10, 0x1D,
-0x50, 0x35, 0x00, 0xDB, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x91,
-0x03, 0x76, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x20, 0xDD, 0x09, 0x74, 0x03, 0x10,
-0x09, 0xC0, 0x05, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x32,
-0x00, 0xD1, 0x01, 0x74, 0x23, 0x10, 0x0D, 0x40, 0x63, 0x00, 0xD5, 0x00, 0x34,
-0x03, 0x10, 0x09, 0x40, 0x37, 0x02, 0xDD, 0x00, 0x76, 0x07, 0x10, 0x0D, 0x40,
-0x74, 0x20, 0xD1, 0x00, 0x04, 0x03, 0x10, 0x4D, 0x40, 0x33, 0x28, 0xD1, 0x04,
-0x74, 0x03, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0xDD, 0x00, 0x24, 0x03, 0x00, 0x09,
-0x40, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00,
-0x05, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x03, 0x00, 0xC1, 0x00, 0x34, 0x03,
-0x10, 0x08, 0x40, 0x33, 0x00, 0xC9, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x30,
-0x00, 0xC9, 0x00, 0x05, 0x03, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x34,
-0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x23, 0x10, 0x08, 0x40,
-0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x3E, 0x00, 0x03,
-0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x00, 0xD7, 0x00, 0xFC, 0x02, 0x14,
-0x09, 0xC0, 0x23, 0x10, 0xFF, 0x00, 0x7C, 0x03, 0x34, 0x0D, 0xC0, 0x34, 0x00,
-0xF3, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x3F, 0x00, 0xC3, 0x20, 0x74, 0x03,
-0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0xFC, 0x03, 0x30, 0x09, 0xC0, 0x01,
-0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0x3F, 0x00,
-0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B,
-0x80, 0x0F, 0x00, 0xFA, 0x00, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF,
-0x00, 0xFC, 0x03, 0xF0, 0x0F, 0x80, 0x3F, 0x08, 0xFF, 0x00, 0xB0, 0x03, 0xF0,
-0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x13, 0xF0, 0x0B, 0xC0, 0x15, 0x60,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xBF, 0x8C, 0xCC,
-0x12, 0x32, 0xCF, 0xC0, 0x5E, 0x22, 0xB3, 0x21, 0xFC, 0x06, 0xF0, 0xCF, 0xC4,
-0x3D, 0x03, 0x23, 0x01, 0xFC, 0x23, 0xF0, 0x13, 0xC0, 0x3F, 0x00, 0xFF, 0x4C,
-0xCC, 0x06, 0xB0, 0x17, 0xD8, 0x5C, 0x00, 0xF7, 0x04, 0xAC, 0x04, 0xB0, 0x4F,
-0xC1, 0x7A, 0x08, 0x3F, 0x01, 0xDC, 0x30, 0xB0, 0x1B, 0xC4, 0x0F, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00, 0xDD, 0x0E, 0x44, 0x26,
-0x10, 0xEF, 0x40, 0x24, 0x01, 0xD1, 0x04, 0x74, 0x05, 0x70, 0x2F, 0x40, 0xBC,
-0x02, 0x91, 0x01, 0xF4, 0x1B, 0x90, 0x40, 0x40, 0xFF, 0x02, 0xFD, 0x08, 0x44,
-0xC3, 0x10, 0x19, 0x40, 0x34, 0x00, 0xF1, 0x01, 0x44, 0x05, 0x10, 0x3F, 0x40,
-0x74, 0x10, 0x1D, 0xA1, 0x34, 0x38, 0xB0, 0x1C, 0x40, 0x07, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x8D, 0x04, 0x04, 0x02, 0x10,
-0x4C, 0x40, 0x32, 0x00, 0xC1, 0x10, 0x14, 0x02, 0xD0, 0x6C, 0x48, 0x33, 0x11,
-0x45, 0x00, 0x34, 0x0B, 0xD0, 0x00, 0x41, 0x33, 0x10, 0xC5, 0x44, 0x04, 0x13,
-0x90, 0x08, 0x40, 0x00, 0x05, 0xC9, 0x08, 0x64, 0x01, 0xD0, 0x0C, 0x40, 0x30,
-0x20, 0x05, 0x00, 0x14, 0x00, 0xD0, 0x04, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x20, 0x44, 0x03, 0x10, 0x0D,
-0x40, 0xA4, 0x0A, 0xD1, 0x04, 0x74, 0x01, 0x50, 0x0D, 0x40, 0x34, 0x40, 0x95,
-0x02, 0x74, 0x03, 0xD1, 0x19, 0x42, 0x37, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x90,
-0x08, 0x40, 0xB4, 0x01, 0xD9, 0x00, 0x64, 0x05, 0xD0, 0x0D, 0x50, 0x36, 0x04,
-0x1D, 0x18, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0x9F, 0x09, 0x0C, 0x03, 0x34, 0x0D, 0xC0,
-0xD6, 0x08, 0x93, 0x01, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0xD7, 0x09,
-0x7C, 0x03, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0xB1, 0x25,
-0xC9, 0x34, 0x40, 0xDB, 0x00, 0x6C, 0x17, 0xF0, 0x0D, 0xC0, 0xA6, 0x00, 0x1F,
-0x02, 0x5C, 0x16, 0xF0, 0x39, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x07, 0x80, 0x3D, 0x00, 0xEF, 0xC1, 0x7C, 0x02, 0xF2, 0x0E, 0xC0, 0x6F,
-0x00, 0xFF, 0x80, 0xFC, 0x8D, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0xBB, 0x00, 0xFC,
-0x03, 0xB0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x10, 0xDD, 0x83, 0x70, 0x0B, 0xC0,
-0x3F, 0x00, 0xF7, 0x00, 0xDC, 0x03, 0x30, 0x0F, 0xC0, 0x3D, 0x00, 0x3F, 0x01,
-0xFC, 0x0E, 0xB4, 0x2F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x08, 0x35, 0x01, 0x93, 0x40, 0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x35, 0x08,
-0xDF, 0x00, 0x4C, 0x0B, 0xF0, 0x0D, 0xC0, 0x34, 0x88, 0xDF, 0x00, 0x5C, 0x03,
-0x70, 0x25, 0xC0, 0x34, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0x30, 0x2D, 0xE2, 0x27,
-0x00, 0xDF, 0x04, 0x7C, 0x09, 0xF0, 0x0D, 0xC1, 0x25, 0x00, 0x57, 0x00, 0x5C,
-0x02, 0x30, 0x05, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
-0xA0, 0x34, 0x00, 0xD1, 0x05, 0x74, 0x83, 0x18, 0x1F, 0x40, 0x24, 0x00, 0xDD,
-0x10, 0x44, 0x81, 0xD0, 0x0F, 0xC0, 0x3E, 0x88, 0x9F, 0x00, 0xC4, 0x03, 0x10,
-0x0D, 0x42, 0x3C, 0x00, 0xFD, 0x00, 0x74, 0x03, 0xB0, 0x09, 0x40, 0x77, 0x00,
-0xED, 0x00, 0x36, 0x05, 0x10, 0x6E, 0x40, 0xB4, 0x02, 0x1B, 0x11, 0x4C, 0x03,
-0x40, 0x05, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0,
-0xB2, 0x02, 0x81, 0x00, 0x34, 0x82, 0x10, 0x1C, 0x40, 0x65, 0x02, 0xCD, 0x01,
-0x04, 0x81, 0xD0, 0x0D, 0x40, 0x30, 0x08, 0x0D, 0x00, 0x14, 0x03, 0x52, 0x00,
-0x42, 0x32, 0x20, 0xCD, 0x43, 0x74, 0x02, 0x10, 0x0C, 0x40, 0x67, 0x02, 0xCD,
-0x03, 0x24, 0x03, 0x58, 0x0C, 0x44, 0x31, 0x08, 0x05, 0x01, 0x54, 0x11, 0x10,
-0x04, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78,
-0x00, 0xA1, 0x01, 0xB4, 0x06, 0x10, 0x1C, 0x40, 0x68, 0x00, 0xED, 0x01, 0x84,
-0x05, 0xD0, 0x1E, 0x48, 0x7A, 0x00, 0x35, 0x01, 0x84, 0x27, 0x10, 0x96, 0x50,
-0x7A, 0x00, 0xED, 0x19, 0xB4, 0x03, 0x10, 0x1A, 0x40, 0x6B, 0x00, 0xED, 0x01,
-0xF4, 0x05, 0x19, 0x1C, 0x40, 0x7C, 0x00, 0x39, 0x81, 0xA4, 0x24, 0x10, 0x1E,
-0x40, 0x1A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00,
-0xC3, 0x04, 0x34, 0x02, 0x10, 0x0C, 0xC0, 0x31, 0x00, 0xDF, 0x00, 0x0D, 0x01,
-0xF8, 0x0D, 0xC0, 0x30, 0x02, 0x4D, 0x00, 0x5C, 0x07, 0x70, 0x2C, 0xC0, 0x32,
-0x02, 0xCF, 0x00, 0x7C, 0x23, 0x10, 0x08, 0x40, 0x23, 0x00, 0xCF, 0x14, 0x34,
-0x43, 0x70, 0x0C, 0xC0, 0x31, 0x00, 0xC7, 0x00, 0x1E, 0x03, 0x34, 0x04, 0xC2,
-0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x39, 0x42, 0xFF,
-0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC1, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0,
-0x0F, 0x81, 0x3F, 0x00, 0xFF, 0x00, 0x7C, 0x2B, 0xB0, 0x0F, 0xC0, 0x3D, 0x04,
-0xFF, 0x10, 0xF4, 0x13, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xFF, 0x10, 0x7C, 0x21,
-0x70, 0x0F, 0xC0, 0x1F, 0x10, 0xEF, 0x00, 0xDC, 0x03, 0xF0, 0x07, 0xC0, 0x0B,
-0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0x9F, 0x00,
-0x4C, 0x03, 0xF0, 0x6D, 0xC0, 0x27, 0x10, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D,
-0xC0, 0x37, 0x05, 0x57, 0x00, 0x5C, 0x37, 0x34, 0x08, 0xC0, 0x36, 0x01, 0xDF,
-0x12, 0x4D, 0x03, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF2,
-0x4C, 0xC1, 0x66, 0x00, 0x9B, 0x01, 0x4C, 0x01, 0xB0, 0x05, 0xC0, 0x57, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xBD, 0x04, 0x85,
-0x0A, 0xD0, 0x0E, 0x40, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0x10, 0x8E, 0x40,
-0x3B, 0x01, 0x6D, 0x00, 0x9C, 0x13, 0x10, 0x0E, 0x40, 0x38, 0x03, 0xE7, 0x04,
-0x84, 0x03, 0xD0, 0x0A, 0x40, 0x2B, 0x08, 0xED, 0x14, 0xB4, 0x03, 0x70, 0x4E,
-0xC2, 0x3A, 0x40, 0x23, 0x00, 0x85, 0x00, 0xB0, 0x0E, 0x40, 0x4B, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x09, 0xA4, 0x17,
-0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x90, 0x5E, 0x40, 0x7B,
-0x02, 0xED, 0x31, 0x16, 0x07, 0x10, 0x1F, 0x42, 0x7A, 0x00, 0xE5, 0x01, 0x84,
-0x07, 0xD0, 0x1E, 0x40, 0x6B, 0x00, 0xED, 0x05, 0xB4, 0x07, 0x50, 0xDE, 0x40,
-0x69, 0x00, 0xE9, 0x81, 0x84, 0x87, 0x90, 0x16, 0x40, 0x0F, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x03, 0xD0,
-0x0C, 0x40, 0x23, 0x20, 0xDD, 0x40, 0x34, 0x45, 0x10, 0x0C, 0x40, 0x37, 0x08,
-0xCD, 0x06, 0x14, 0x03, 0x10, 0xBC, 0x40, 0x30, 0x00, 0xD5, 0x20, 0x04, 0x07,
-0xD0, 0x18, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x01, 0x50, 0x0C, 0x40, 0x53,
-0x30, 0xC1, 0x08, 0x04, 0x0B, 0x90, 0x04, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x17, 0x88, 0x15, 0x00, 0x5F, 0x00, 0x6C, 0x41, 0xF0, 0x05,
-0xC0, 0x1F, 0x00, 0x5F, 0x00, 0xBC, 0x4D, 0xB0, 0x05, 0xC0, 0x17, 0x00, 0x6F,
-0x01, 0x5C, 0x01, 0x30, 0x37, 0xC0, 0x16, 0x00, 0x57, 0x80, 0x4C, 0x91, 0xF0,
-0x47, 0xC0, 0x9F, 0x00, 0x5F, 0x00, 0xBC, 0x15, 0x70, 0x04, 0xC0, 0x5D, 0x0C,
-0x7B, 0x03, 0xCC, 0x09, 0xA0, 0x07, 0xC0, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0,
-0x07, 0x00, 0x1F, 0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00,
-0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01,
-0xC0, 0x07, 0x00, 0x0F, 0x02, 0x7C, 0x40, 0x70, 0x21, 0x80, 0x86, 0x00, 0x17,
-0x12, 0x3C, 0x10, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x08, 0x27, 0x08, 0x8F, 0x40, 0x4D, 0x16, 0xF0, 0x99, 0xC0, 0xE7,
-0x00, 0x93, 0x09, 0x4D, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x5C,
-0x02, 0xF0, 0x29, 0xC0, 0x23, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x34, 0x09, 0xC0,
-0x64, 0x06, 0x93, 0x03, 0x5C, 0xA2, 0x71, 0x99, 0xC0, 0x24, 0x00, 0x9F, 0x01,
-0x7C, 0x06, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x20, 0xA6, 0x00, 0xBD, 0x40, 0xC4, 0x06, 0x70, 0x09, 0x40, 0x63, 0x00,
-0x91, 0x01, 0x44, 0x02, 0x18, 0x09, 0x44, 0x27, 0x00, 0x99, 0x00, 0x44, 0x02,
-0xD0, 0x28, 0x40, 0x24, 0x08, 0x93, 0x20, 0x04, 0x02, 0x90, 0x08, 0x40, 0x60,
-0x00, 0x91, 0x04, 0x44, 0x4E, 0x10, 0x09, 0x50, 0x25, 0x10, 0x9D, 0x06, 0x74,
-0x06, 0x50, 0x09, 0x42, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA0, 0x24, 0x10, 0x9D, 0x00, 0x44, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91,
-0x80, 0x44, 0x03, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0,
-0x29, 0x40, 0x25, 0x00, 0x95, 0x00, 0x54, 0x02, 0x90, 0x09, 0x40, 0x24, 0x00,
-0x91, 0x00, 0x54, 0x02, 0x50, 0x29, 0x40, 0x24, 0x30, 0x9D, 0x08, 0x74, 0x52,
-0x10, 0x0D, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22,
-0x30, 0x00, 0x8D, 0x02, 0x04, 0x02, 0x58, 0x68, 0x40, 0xA7, 0x00, 0x81, 0x02,
-0x44, 0x0A, 0x10, 0x88, 0x40, 0x23, 0x02, 0x99, 0x00, 0x04, 0x22, 0xD0, 0x89,
-0x40, 0x20, 0x00, 0x89, 0x08, 0x44, 0x22, 0x90, 0x29, 0x40, 0xA4, 0x00, 0x81,
-0x00, 0x04, 0x02, 0x12, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x34, 0x22, 0x54,
-0x28, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06,
-0x00, 0x1F, 0x01, 0x4C, 0x04, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x13, 0x00, 0x0C,
-0x00, 0x14, 0x61, 0xC1, 0x87, 0x0D, 0x17, 0x00, 0x5C, 0x58, 0xF1, 0x21, 0xC0,
-0x05, 0x05, 0x07, 0x16, 0x5C, 0x88, 0x30, 0x01, 0xD0, 0x04, 0x40, 0x13, 0x54,
-0x5C, 0x80, 0x78, 0x41, 0xC1, 0x14, 0x10, 0x1F, 0x00, 0x3C, 0x58, 0x30, 0x01,
-0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x38, 0x27, 0x08,
-0xBF, 0x03, 0xFC, 0x0A, 0xF0, 0x99, 0xC0, 0x6F, 0x08, 0xBF, 0x01, 0xFC, 0x06,
-0xF0, 0x49, 0xC0, 0x27, 0x09, 0xB7, 0x00, 0x7C, 0x12, 0xF0, 0x4B, 0xC2, 0x25,
-0x00, 0x97, 0x04, 0xFC, 0x12, 0x70, 0x1B, 0xC0, 0x6F, 0x30, 0x9F, 0x00, 0xFC,
-0x02, 0xF8, 0x09, 0xD2, 0x2B, 0x80, 0xAF, 0x00, 0xFC, 0x12, 0xF0, 0x1B, 0xC0,
-0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2B, 0x00, 0xBF,
-0x13, 0xFC, 0x46, 0xF0, 0x0B, 0xC0, 0xAC, 0x00, 0xBF, 0x00, 0x7C, 0x0A, 0x30,
-0xC9, 0xC0, 0x26, 0x00, 0x9B, 0x00, 0x7C, 0x22, 0xF0, 0x0B, 0xC0, 0x24, 0x05,
-0xBF, 0x0C, 0x49, 0x02, 0xF2, 0x29, 0xC2, 0xAF, 0x00, 0xAF, 0x04, 0xFC, 0x02,
-0xF0, 0x4B, 0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x09, 0xC0, 0x67,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x07,
-0x74, 0x88, 0xD0, 0x51, 0x40, 0x44, 0x20, 0x1D, 0x05, 0x74, 0x04, 0x10, 0xC1,
-0x48, 0x84, 0x04, 0x11, 0x00, 0x74, 0x20, 0xD0, 0x45, 0x53, 0x04, 0x00, 0x1D,
-0x0C, 0x44, 0x40, 0xD0, 0x14, 0x40, 0x47, 0x00, 0x1D, 0x00, 0x74, 0x00, 0x10,
-0x81, 0x40, 0x14, 0x20, 0x5D, 0x20, 0x74, 0x20, 0x14, 0x11, 0x40, 0x73, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x04, 0x34,
-0x02, 0xD0, 0x88, 0x41, 0x20, 0x00, 0x8D, 0x10, 0x34, 0x02, 0x10, 0x48, 0x40,
-0x22, 0x03, 0x89, 0x00, 0x34, 0x02, 0xD1, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x04,
-0x26, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x10, 0x8D, 0x08, 0x34, 0x02, 0xDC, 0x08,
-0x40, 0x20, 0x10, 0x8D, 0x00, 0x34, 0x02, 0x94, 0x48, 0x41, 0x43, 0x80, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x20, 0x74, 0x82,
-0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x04, 0x34, 0x02, 0x10, 0x09, 0x40, 0x20,
-0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x88, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x66,
-0x82, 0xD0, 0x89, 0x66, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x51, 0x09, 0x58,
-0x24, 0x00, 0x9D, 0x01, 0x74, 0x2A, 0x10, 0x69, 0x40, 0x63, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0xBF, 0x01, 0x7C, 0x06, 0xF0,
-0x0B, 0xD0, 0x2C, 0x03, 0xBF, 0x00, 0xFC, 0x02, 0x10, 0x09, 0xC0, 0x26, 0x00,
-0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x24, 0x00, 0x9D, 0x80, 0x64, 0x22,
-0xF0, 0x3B, 0xC0, 0x2F, 0x08, 0x9D, 0x00, 0x34, 0x4A, 0xF0, 0x09, 0x40, 0xA4,
-0x00, 0x9F, 0x03, 0x70, 0x06, 0xB0, 0x3B, 0xC4, 0x17, 0xA0, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x04, 0x7C, 0x12, 0xF0, 0x09,
-0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF4, 0x08, 0xC0, 0x27, 0x10, 0x9F,
-0x04, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x40, 0x5C, 0x06, 0xF8,
-0x19, 0xC2, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x22, 0xB0, 0x09, 0x05, 0x27, 0x80,
-0x9E, 0x10, 0x6C, 0x06, 0xF0, 0x19, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x40, 0x7C, 0x00, 0xB4, 0x81, 0xC0,
-0x07, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x13, 0x02,
-0x7C, 0x00, 0xF0, 0xA1, 0xD0, 0x04, 0x00, 0x03, 0x00, 0x7C, 0x00, 0xF2, 0x21,
-0xC0, 0x04, 0x20, 0x13, 0x10, 0x5C, 0x98, 0xF0, 0x01, 0xD0, 0x84, 0x00, 0x1F,
-0x42, 0x2C, 0x00, 0x34, 0x21, 0xD0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0xA0, 0x1C, 0x01, 0x51, 0x01, 0xF4, 0x1D, 0x10, 0x15, 0x40, 0x17,
-0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x51, 0x00, 0x74,
-0x01, 0xD0, 0x97, 0xC0, 0x14, 0x00, 0x71, 0x03, 0x44, 0x01, 0x70, 0x05, 0x40,
-0x14, 0x00, 0x71, 0x01, 0xC4, 0x05, 0xD0, 0x16, 0x42, 0x1C, 0x00, 0x7D, 0x00,
-0xF4, 0x01, 0x14, 0x05, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0xA0, 0x62, 0x00, 0xC1, 0x00, 0x34, 0x1E, 0x10, 0x0D, 0x48, 0x33, 0x00,
-0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x31, 0xC0, 0xC1, 0x00, 0x34, 0x03,
-0xD0, 0x2C, 0x40, 0x32, 0x40, 0xC1, 0x11, 0x14, 0x03, 0x50, 0x0C, 0x40, 0x32,
-0x02, 0x81, 0x00, 0x14, 0x05, 0x90, 0x18, 0x40, 0x60, 0x01, 0xC9, 0x02, 0x24,
-0x03, 0x14, 0x0C, 0x60, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x80, 0x68, 0x00, 0xA1, 0x06, 0xB4, 0x06, 0x10, 0x8E, 0x40, 0x3B, 0x01, 0xAD,
-0x04, 0xB4, 0x13, 0xD0, 0x8E, 0x40, 0x38, 0x81, 0xE1, 0x00, 0xB4, 0x13, 0xD0,
-0x0E, 0x40, 0x78, 0x00, 0xC1, 0x10, 0x84, 0x13, 0x50, 0x5E, 0x40, 0x7A, 0x11,
-0xA1, 0x11, 0x86, 0x09, 0xD0, 0x2C, 0x42, 0xA8, 0x00, 0xED, 0x00, 0x34, 0x0B,
-0x10, 0x5F, 0x60, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10,
-0x68, 0x00, 0xE3, 0x07, 0xBC, 0x06, 0x30, 0x5A, 0xC0, 0xEB, 0x00, 0xEF, 0x03,
-0xB4, 0x0F, 0xF0, 0x1C, 0xC0, 0xF1, 0x00, 0xE1, 0x01, 0xBC, 0x17, 0xF0, 0x17,
-0xC4, 0x72, 0x00, 0xE3, 0x01, 0x9C, 0x17, 0x70, 0x3E, 0xC8, 0xFE, 0x40, 0xE3,
-0x01, 0x9C, 0x05, 0xB0, 0x1A, 0xC0, 0x68, 0x08, 0xED, 0x01, 0xAC, 0x05, 0x30,
-0x3E, 0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25,
-0x50, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C,
-0x03, 0xF0, 0x0D, 0xC2, 0xB7, 0x0D, 0xDF, 0x00, 0x7C, 0x4B, 0xF0, 0x05, 0xC0,
-0x37, 0x00, 0xDF, 0x00, 0x5C, 0x23, 0x72, 0x0D, 0xD0, 0x25, 0x00, 0xDF, 0x00,
-0x7E, 0x01, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF4, 0x0C,
-0xC0, 0x43, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00,
-0xFF, 0x09, 0xCC, 0x13, 0x30, 0x1F, 0xC0, 0x7B, 0x00, 0xF3, 0x01, 0xCC, 0x27,
-0x30, 0x5F, 0x80, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x47, 0x30, 0x1B, 0xC0, 0x7C,
-0x00, 0xBF, 0x01, 0xCC, 0x07, 0xF0, 0x1E, 0xC0, 0x68, 0x0A, 0xB1, 0x0C, 0xFC,
-0x25, 0xF0, 0x1F, 0xC0, 0x78, 0x42, 0xF3, 0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xC4,
-0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x80, 0x29, 0x00, 0xBD,
-0x18, 0x84, 0x43, 0x11, 0x0A, 0x48, 0x3B, 0x00, 0xA1, 0x10, 0x84, 0x23, 0x10,
-0x0E, 0x48, 0x3B, 0x00, 0xED, 0x00, 0x34, 0x03, 0x10, 0x8B, 0x41, 0x38, 0x00,
-0x7D, 0x00, 0x94, 0x03, 0xD0, 0x4E, 0x40, 0x38, 0x03, 0xA1, 0x04, 0xB4, 0x09,
-0xD0, 0x8E, 0x40, 0x19, 0x02, 0xE1, 0x00, 0xB4, 0x0A, 0xF0, 0x8E, 0x40, 0x54,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x40,
-0xA7, 0x22, 0x14, 0x0A, 0x40, 0x2F, 0x06, 0xB1, 0x08, 0xC4, 0x07, 0x12, 0x4E,
-0x60, 0x3B, 0x00, 0xED, 0x02, 0xB4, 0x03, 0x90, 0x02, 0x50, 0x38, 0x02, 0xAD,
-0x00, 0xA4, 0x03, 0xD0, 0x1F, 0x49, 0x2C, 0x04, 0xE9, 0x88, 0xB4, 0x01, 0xD0,
-0x0A, 0x40, 0x38, 0x80, 0x61, 0x10, 0xB4, 0x01, 0xD0, 0x1F, 0x40, 0x60, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x23, 0x00, 0x8D, 0x00, 0x24,
-0x06, 0x10, 0x09, 0x40, 0x77, 0x00, 0x81, 0x00, 0x04, 0x23, 0x10, 0x0C, 0x60,
-0x33, 0x00, 0xCD, 0x08, 0x34, 0x03, 0x91, 0x00, 0x41, 0x30, 0x00, 0x4D, 0x00,
-0x06, 0x03, 0xD2, 0x3C, 0x40, 0x60, 0x20, 0xC9, 0x00, 0x34, 0x09, 0xD0, 0x08,
-0x40, 0x31, 0x02, 0x01, 0x03, 0x30, 0x07, 0x50, 0x0C, 0x60, 0x18, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x01, 0x6C, 0x02,
-0x30, 0x0D, 0x40, 0xB7, 0x42, 0xD3, 0x21, 0x4D, 0x03, 0x14, 0x0F, 0xC2, 0x3F,
-0x00, 0xDF, 0x00, 0xF4, 0x03, 0x90, 0x1D, 0xC0, 0x34, 0x00, 0x5F, 0x00, 0xCD,
-0x17, 0xF0, 0x3D, 0xD0, 0xF4, 0x40, 0x9A, 0x00, 0x7C, 0x09, 0xF1, 0x0D, 0xC2,
-0xF0, 0x00, 0xD1, 0x23, 0x74, 0x07, 0xD0, 0x2D, 0x50, 0x74, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xB7, 0x00, 0xDF, 0x00, 0x5C, 0x02, 0xF0,
-0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x43, 0xF0, 0x0D, 0xC0, 0x37, 0x00,
-0xDF, 0x00, 0x3C, 0x03, 0x72, 0x2D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03,
-0xF0, 0x0D, 0xC0, 0x37, 0x01, 0x97, 0x22, 0x7C, 0x0D, 0xE0, 0x0D, 0xC0, 0xB7,
-0x04, 0xDF, 0x20, 0x7C, 0x21, 0xF0, 0xCD, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x08, 0x7F, 0x02, 0xFF, 0x00, 0x7C, 0x22, 0xF0, 0x0B,
-0xD0, 0x2C, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3E, 0x00, 0xFF,
-0x00, 0xDC, 0x03, 0x30, 0x9B, 0xC0, 0x3F, 0x00, 0x7F, 0x01, 0xEE, 0x03, 0xF0,
-0x0F, 0xC1, 0x3F, 0x00, 0xEF, 0x05, 0xCC, 0x41, 0xF0, 0x0B, 0xC0, 0x3D, 0x00,
-0xFB, 0x10, 0x8C, 0x10, 0x30, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x81, 0x20, 0xD6, 0x00, 0xDD, 0x09, 0x74, 0x0A, 0xD0, 0x0D, 0x40,
-0x64, 0x22, 0xD1, 0x20, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x00,
-0x74, 0x03, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x02, 0x7E, 0x03, 0xD0, 0x0D,
-0x40, 0x27, 0x00, 0xDD, 0x07, 0x44, 0x05, 0xD0, 0x38, 0xC8, 0x76, 0x01, 0x89,
-0x00, 0x54, 0x0C, 0x50, 0x0D, 0x42, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0xA0, 0x24, 0x04, 0x9D, 0x00, 0x74, 0x0B, 0xD2, 0x0D, 0x42, 0x34,
-0x40, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x74,
-0x03, 0x10, 0x05, 0x41, 0x37, 0x80, 0x1D, 0x66, 0x74, 0x03, 0xD0, 0x0D, 0x40,
-0x27, 0x00, 0x9D, 0x00, 0x64, 0x07, 0xD2, 0x35, 0x40, 0x75, 0x00, 0xD1, 0x00,
-0x44, 0x02, 0x11, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x08, 0x30, 0x00, 0x8D, 0x20, 0x36, 0x03, 0xD0, 0x08, 0x40, 0x20, 0x00,
-0x81, 0x00, 0x34, 0x03, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
-0x18, 0x04, 0x40, 0x33, 0xA0, 0x0D, 0x00, 0x14, 0x03, 0xD2, 0x0C, 0x48, 0x33,
-0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x5A, 0x36, 0x00, 0xD1, 0x00, 0x14,
-0x00, 0x50, 0x0C, 0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x20, 0x26, 0x00, 0x9F, 0x20, 0x7C, 0x01, 0xF0, 0x09, 0xE8, 0x24, 0x00, 0x93,
-0x40, 0xFC, 0x03, 0xF0, 0x0D, 0x40, 0x3F, 0x00, 0xDF, 0x00, 0xBC, 0x23, 0x34,
-0x01, 0xC0, 0x37, 0x00, 0x1F, 0x00, 0x64, 0x03, 0xF0, 0x0F, 0xC0, 0x27, 0x00,
-0xDF, 0x00, 0x6C, 0x01, 0xF0, 0x09, 0xC0, 0x35, 0x80, 0x5B, 0x80, 0x4E, 0x00,
-0x32, 0x0F, 0xC8, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8,
-0x1F, 0x00, 0xBF, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xAF, 0x20,
-0xBC, 0x03, 0xF0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x03,
-0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC2, 0x2F, 0x00, 0x3F,
-0x00, 0xDC, 0x00, 0xF0, 0x0A, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x80, 0xF8,
-0x0E, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xB0, 0x7F,
-0x00, 0x3F, 0x00, 0xEC, 0x07, 0x70, 0x03, 0xC0, 0x7D, 0x02, 0xF3, 0x09, 0xFC,
-0x10, 0xF0, 0x0B, 0xC0, 0x3C, 0x01, 0xBF, 0x21, 0xFC, 0x03, 0xF0, 0x0F, 0xC1,
-0x3F, 0x00, 0x3F, 0x18, 0xCD, 0x03, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0xFB, 0x00,
-0xFC, 0x03, 0xE0, 0x0F, 0xC0, 0x4C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0x30, 0x0F,
-0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x77, 0x00,
-0x5D, 0x01, 0x44, 0x07, 0x10, 0xB1, 0x40, 0x33, 0x00, 0xC1, 0x04, 0x74, 0x06,
-0xD0, 0x29, 0x41, 0x3D, 0x00, 0xDD, 0x01, 0xF4, 0x07, 0xD0, 0x0E, 0x40, 0x77,
-0x00, 0x1D, 0x82, 0x44, 0x07, 0x10, 0x2F, 0x40, 0x67, 0x00, 0x51, 0x01, 0x74,
-0x07, 0xD0, 0x15, 0x40, 0x44, 0x00, 0x5B, 0x01, 0x44, 0x05, 0x10, 0x1D, 0x40,
-0x04, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x0D,
-0x08, 0x04, 0x03, 0x50, 0x14, 0x68, 0x31, 0x01, 0xC1, 0x00, 0x34, 0x20, 0xD0,
-0x6C, 0x40, 0xB1, 0x04, 0xCD, 0x01, 0x34, 0x23, 0xD0, 0x4C, 0x41, 0x31, 0x02,
-0x0D, 0x05, 0x24, 0x03, 0x10, 0x2C, 0x40, 0x23, 0x00, 0x85, 0x00, 0x34, 0x02,
-0x50, 0x08, 0x40, 0x01, 0x00, 0x85, 0x20, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x44,
-0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x80, 0x5D, 0x14,
-0x65, 0x03, 0x10, 0x01, 0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x00, 0xD0, 0x0D,
-0x40, 0x35, 0x20, 0xDD, 0x01, 0x74, 0x03, 0xD1, 0x0D, 0x40, 0x37, 0x00, 0x1D,
-0x00, 0x64, 0x43, 0x10, 0x0D, 0x44, 0x67, 0x00, 0xD5, 0x06, 0x74, 0x03, 0xD1,
-0x0D, 0x51, 0x45, 0x40, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x8D, 0x40, 0x0C, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x37, 0x00, 0x9F, 0x01, 0x6C,
-0x07, 0x70, 0x01, 0xC0, 0x75, 0x40, 0xD3, 0x00, 0x7C, 0x11, 0xF0, 0x0D, 0xC0,
-0x35, 0x00, 0xDF, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x5F, 0x00,
-0x6C, 0x03, 0x30, 0x0D, 0xC0, 0xE7, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x3D,
-0xC0, 0xC1, 0x84, 0xD7, 0x00, 0x4C, 0x07, 0x30, 0x0D, 0xC0, 0x08, 0x20, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0x6F, 0x00, 0xDC, 0x0B,
-0xF0, 0x0F, 0xC0, 0x7F, 0x02, 0xFF, 0x00, 0xFC, 0x0F, 0xF0, 0x0D, 0xE0, 0x3F,
-0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC6, 0x3F, 0x80, 0x9F, 0x28, 0xDC,
-0x27, 0xF0, 0x0F, 0xC0, 0x2F, 0x40, 0x7B, 0x00, 0xFC, 0x03, 0xF0, 0x96, 0xC0,
-0x0E, 0x00, 0xE3, 0x00, 0xBC, 0x09, 0xF0, 0x1E, 0xC0, 0x1F, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x9F, 0x02, 0x4C, 0x03, 0xF0,
-0x05, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x5C, 0x05, 0x70, 0x0D, 0xC8, 0x35, 0x08,
-0xD3, 0x80, 0x7C, 0x07, 0xF1, 0x0D, 0xC2, 0x34, 0x00, 0x5F, 0x00, 0x0C, 0x23,
-0x30, 0x0D, 0xC0, 0xA3, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xB0, 0x29, 0xC0, 0x04,
-0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x2D, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0x5C, 0x00, 0x34, 0x3F, 0xD0, 0x0D,
-0xC0, 0x74, 0x01, 0xD1, 0x00, 0x44, 0x01, 0xD0, 0x9C, 0x48, 0x7C, 0x01, 0xD1,
-0x00, 0xF4, 0x03, 0xD0, 0x0F, 0x40, 0x3C, 0x01, 0x9D, 0x00, 0x6E, 0x03, 0xB0,
-0x4F, 0x40, 0x27, 0x08, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x4D, 0xC0, 0x04, 0x00,
-0xDD, 0x00, 0x44, 0x93, 0x10, 0x0D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x20, 0x32, 0x00, 0x0D, 0x00, 0x34, 0x0F, 0x90, 0x08, 0x40,
-0x34, 0x00, 0xC1, 0x00, 0x04, 0x00, 0x50, 0x08, 0x00, 0x31, 0x00, 0xC1, 0x00,
-0x34, 0x03, 0xD8, 0x0C, 0x40, 0x70, 0x00, 0x9D, 0x40, 0x04, 0x04, 0x90, 0x2C,
-0x41, 0x23, 0x00, 0xC5, 0x00, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x42, 0x02, 0xCD,
-0x00, 0x24, 0x02, 0x10, 0x00, 0x40, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x04, 0x00, 0x7A, 0x08, 0xAD, 0x21, 0xB4, 0x07, 0xD2, 0x10, 0x40, 0xF8,
-0x02, 0xE1, 0x0B, 0x94, 0x26, 0xD0, 0x1A, 0x41, 0xF8, 0x00, 0xE0, 0x01, 0xB4,
-0x07, 0xD8, 0x3E, 0x40, 0x78, 0x00, 0x6D, 0x01, 0x84, 0x06, 0x90, 0x1E, 0x40,
-0x63, 0x80, 0xE1, 0x01, 0x34, 0x27, 0x10, 0x1C, 0x40, 0x48, 0x00, 0x4D, 0x01,
-0x24, 0x07, 0x10, 0x14, 0x42, 0x10, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x00, 0x32, 0x00, 0x0F, 0x00, 0x3C, 0x23, 0xF0, 0x0C, 0xC0, 0x30, 0x02,
-0xC3, 0x00, 0x1C, 0x03, 0x70, 0x8C, 0x40, 0x35, 0x00, 0xC1, 0x00, 0x3C, 0x23,
-0xF0, 0x0C, 0xC0, 0x30, 0x00, 0x8F, 0x00, 0x04, 0x11, 0x30, 0x8C, 0xC0, 0xB3,
-0x82, 0xC7, 0x00, 0x3C, 0x02, 0x30, 0x0C, 0xC0, 0x02, 0x00, 0x8F, 0x00, 0x2C,
-0x02, 0x30, 0x2C, 0xC0, 0x48, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xA8, 0x3D, 0x00, 0xBF, 0x00, 0xFE, 0xA3, 0xF0, 0x83, 0xC0, 0x3F, 0x92, 0xFF,
-0x00, 0xEC, 0x83, 0xF0, 0x0F, 0xC0, 0xBF, 0x04, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
-0x0F, 0xC0, 0x3F, 0x04, 0x7F, 0x08, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00,
-0xFF, 0x00, 0xFC, 0x03, 0x75, 0x8F, 0xD0, 0x0F, 0x00, 0xFF, 0x00, 0x5C, 0x03,
-0xF0, 0x0F, 0xE0, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
-0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xD3, 0x01,
-0x0C, 0x04, 0x30, 0x0D, 0xC0, 0xB5, 0x01, 0xDB, 0x00, 0x7C, 0x7B, 0xF0, 0xED,
-0xC1, 0x34, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0xB8, 0x8D, 0xC1, 0x27, 0x00, 0xDF,
-0x01, 0x4C, 0x05, 0x10, 0x0D, 0xC4, 0x04, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30,
-0x19, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x39,
-0x00, 0xED, 0x00, 0xB4, 0x03, 0xD2, 0x0E, 0x40, 0x3B, 0x00, 0xF1, 0x00, 0x85,
-0x02, 0x50, 0x0E, 0x40, 0x33, 0x01, 0xE1, 0x00, 0xB4, 0x03, 0xD0, 0x0C, 0x40,
-0x38, 0x01, 0xCD, 0x00, 0xA4, 0x83, 0x10, 0x4E, 0xC0, 0x2B, 0x00, 0xED, 0x00,
-0x84, 0x03, 0x10, 0x0E, 0x40, 0x08, 0x00, 0xED, 0x80, 0x84, 0x03, 0x10, 0x0E,
-0x40, 0x48, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00,
-0xED, 0x01, 0xB4, 0x47, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xE1, 0x81, 0x84, 0x07,
-0x00, 0x1E, 0x41, 0x7B, 0x00, 0xE1, 0x03, 0xB4, 0x97, 0xD8, 0x5E, 0x40, 0x7A,
-0x00, 0xED, 0x01, 0x05, 0x07, 0x14, 0x5E, 0x44, 0x7B, 0x00, 0xC5, 0x01, 0x04,
-0x07, 0x90, 0x1C, 0x40, 0x4A, 0x00, 0xCD, 0x11, 0x04, 0x47, 0x10, 0x1C, 0x40,
-0x12, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0xA0, 0xCD,
-0x1A, 0x34, 0x86, 0xD0, 0x0C, 0x41, 0x23, 0x02, 0xC1, 0x00, 0x04, 0x27, 0x5B,
-0x1D, 0x42, 0x33, 0x40, 0x41, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x50, 0x32, 0x00,
-0xCD, 0x06, 0x04, 0x07, 0x10, 0x0D, 0x40, 0xB1, 0x00, 0xCD, 0x00, 0x05, 0x07,
-0x94, 0x0C, 0x50, 0xF2, 0x04, 0xCD, 0x00, 0x05, 0x03, 0x14, 0x0C, 0x78, 0x5A,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x7F, 0x03,
-0x7C, 0x01, 0xF0, 0x77, 0x40, 0x57, 0x40, 0x53, 0x00, 0xCC, 0x05, 0x30, 0x05,
-0xC0, 0x17, 0x00, 0x73, 0xC1, 0x74, 0x01, 0xF0, 0x05, 0xC8, 0x16, 0x10, 0x7F,
-0x02, 0xEC, 0x11, 0xB0, 0x05, 0x40, 0x1F, 0x00, 0x7F, 0x00, 0xCC, 0x15, 0xB0,
-0x07, 0xC0, 0xDA, 0x09, 0x7F, 0x03, 0xCC, 0x05, 0x30, 0x27, 0xC0, 0x5E, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x0F, 0x00, 0x74,
-0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0,
-0x07, 0x00, 0x17, 0x01, 0x3C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0xA0, 0x1B, 0x00,
-0x3E, 0x04, 0x70, 0x01, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0x74, 0x01,
-0xC0, 0x85, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x01, 0xC0, 0x49, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02,
-0xF0, 0x08, 0xD4, 0x24, 0x00, 0x93, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26,
-0x40, 0x93, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xD0, 0x24, 0x00, 0x9F, 0x00, 0x4C,
-0x82, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x08, 0xC0,
-0x24, 0x00, 0x93, 0x10, 0x4C, 0x02, 0x34, 0x09, 0xC1, 0x43, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x06, 0xD0,
-0x09, 0x40, 0x20, 0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x19, 0x48, 0xA4, 0x00,
-0x81, 0x00, 0x44, 0x02, 0x10, 0x29, 0xC0, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x02,
-0xB0, 0x09, 0xC0, 0xA6, 0x00, 0x9D, 0x02, 0x5C, 0x0A, 0xD0, 0x29, 0x40, 0x24,
-0x00, 0x91, 0x02, 0x4C, 0x0A, 0x10, 0x29, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x06, 0xD0, 0x09,
-0x48, 0x64, 0x00, 0x91, 0x00, 0x74, 0x06, 0x50, 0x89, 0x40, 0x62, 0x84, 0x99,
-0x00, 0x44, 0x06, 0x10, 0x19, 0x63, 0x64, 0x80, 0x8D, 0x00, 0x44, 0x02, 0x10,
-0x09, 0x42, 0x24, 0x04, 0x91, 0x10, 0x74, 0x42, 0xD0, 0x09, 0x51, 0x24, 0x00,
-0x99, 0x30, 0x44, 0xC3, 0x10, 0x09, 0x41, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x28, 0x20, 0x00, 0x8D, 0x04, 0x04, 0x02, 0xD0, 0x48, 0x40,
-0x34, 0x40, 0x81, 0x00, 0x34, 0x12, 0xD0, 0x4C, 0x40, 0x20, 0x81, 0x99, 0x00,
-0x04, 0x12, 0x10, 0x48, 0x40, 0x20, 0x21, 0x8D, 0x04, 0x06, 0x12, 0x90, 0x4C,
-0x48, 0x20, 0x01, 0x8D, 0x04, 0x14, 0x12, 0xD8, 0x48, 0x60, 0x20, 0x00, 0x89,
-0xC4, 0x04, 0x12, 0x10, 0x48, 0x60, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x4C, 0x01, 0xF0, 0x01, 0xC0, 0x80,
-0x02, 0x13, 0x0A, 0x74, 0x00, 0x70, 0xA1, 0xC0, 0x86, 0x22, 0x19, 0x00, 0x45,
-0x00, 0x30, 0xA1, 0x40, 0x04, 0x00, 0x1F, 0x0A, 0x4D, 0x00, 0x30, 0xA1, 0x40,
-0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0xC8, 0x14, 0x00, 0x13, 0x00,
-0x4C, 0x00, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x19, 0xA8, 0x27, 0x00, 0xBF, 0x88, 0xFD, 0x02, 0xF0, 0x8B, 0x80, 0x2F, 0x00,
-0x9F, 0x00, 0xFC, 0xA2, 0xF0, 0x8B, 0xC0, 0x27, 0x42, 0xB7, 0x00, 0x7C, 0x22,
-0xF4, 0x89, 0xC0, 0x27, 0x22, 0xBF, 0x08, 0xFC, 0x22, 0x74, 0x89, 0xD0, 0x2F,
-0x02, 0xBF, 0x08, 0xDC, 0x22, 0xF1, 0x8B, 0xC0, 0x2F, 0x40, 0xB7, 0x28, 0xDD,
-0x22, 0xF0, 0x8B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA8, 0x27, 0x00, 0x9F, 0x04, 0xFE, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF,
-0x00, 0xDC, 0x52, 0xB0, 0xCA, 0xC8, 0x2E, 0x08, 0xBF, 0xA0, 0xDC, 0x82, 0x32,
-0x4B, 0xC2, 0x6F, 0x01, 0xDF, 0x0C, 0xFC, 0x02, 0x34, 0x0B, 0xC0, 0x26, 0x00,
-0x93, 0x04, 0x5C, 0x52, 0xF0, 0x49, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0x30, 0x49, 0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
-0x07, 0x00, 0x1D, 0x08, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x14,
-0x74, 0x00, 0xD0, 0xC1, 0x40, 0x84, 0x04, 0x1D, 0x00, 0x5C, 0x20, 0x10, 0x41,
-0x43, 0x07, 0x00, 0x1D, 0x0C, 0x74, 0x08, 0x10, 0x01, 0x41, 0x04, 0x42, 0x13,
-0x00, 0x44, 0x00, 0xD0, 0x81, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x7C, 0x20, 0x10,
-0x03, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21,
-0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x04, 0x34,
-0x02, 0x90, 0x48, 0x40, 0x22, 0x03, 0x8D, 0x00, 0x34, 0x02, 0x10, 0xC8, 0x40,
-0x23, 0x02, 0x8D, 0x44, 0x34, 0x22, 0x12, 0x88, 0x48, 0x28, 0x80, 0xA1, 0x09,
-0xB4, 0x06, 0xD0, 0x1A, 0x40, 0x28, 0x00, 0xAD, 0x89, 0xB4, 0x06, 0x10, 0x9A,
-0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00,
-0x9D, 0x00, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02,
-0xD0, 0x0D, 0x60, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27,
-0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x0D, 0x40, 0xA4, 0x00, 0xB9, 0x00, 0xE4,
-0x02, 0xD0, 0x4B, 0x40, 0x2C, 0x00, 0xBC, 0x40, 0xF4, 0x02, 0x10, 0x8B, 0x40,
-0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F,
-0x00, 0x74, 0x02, 0xF0, 0x19, 0x40, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x6A, 0x90,
-0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x22, 0x30, 0x09, 0xD0, 0x60, 0x00, 0x93, 0x0B, 0x7C, 0x0A,
-0xF0, 0x39, 0xD0, 0x64, 0x04, 0x9F, 0x02, 0x7C, 0x0A, 0x34, 0x39, 0xC0, 0x17,
-0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x00, 0x9F, 0x20,
-0x7C, 0x42, 0xF0, 0x49, 0xC0, 0x67, 0x02, 0x9F, 0x00, 0x7C, 0x02, 0xD0, 0x98,
-0xC0, 0x27, 0x00, 0x9F, 0x09, 0x1C, 0x02, 0xF4, 0x09, 0xC0, 0x27, 0x80, 0x9F,
-0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x01, 0x87, 0x01, 0x5C, 0x16, 0xF0,
-0x19, 0xC0, 0x67, 0x01, 0x9E, 0x05, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x4B, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x4C,
-0x80, 0xF2, 0x01, 0xC2, 0x04, 0x04, 0x1F, 0x00, 0x7C, 0x08, 0x30, 0x01, 0xC0,
-0x07, 0x04, 0x13, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xD0, 0x04, 0x00, 0x1F, 0x00,
-0x4C, 0x80, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x70, 0x00,
-0xC0, 0x04, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0xF2, 0x01, 0xC0, 0x43, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x20, 0x5D, 0x00, 0xD0, 0x11,
-0x70, 0x05, 0x40, 0x9C, 0x00, 0x7D, 0x11, 0x74, 0x01, 0x00, 0x37, 0xC1, 0x5E,
-0x00, 0x51, 0x05, 0x40, 0x05, 0xD0, 0x17, 0x40, 0x54, 0x00, 0x5D, 0x00, 0x44,
-0x01, 0x30, 0x07, 0x40, 0x14, 0x00, 0x51, 0x00, 0x74, 0x01, 0x50, 0x05, 0x50,
-0x14, 0x10, 0x5D, 0x21, 0x54, 0x01, 0xD0, 0x15, 0x40, 0x53, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x04, 0x0D, 0x50,
-0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x06, 0x10, 0x34, 0x51, 0x71, 0x00,
-0x81, 0x01, 0x34, 0x26, 0xD0, 0x1C, 0x40, 0x60, 0x02, 0xCD, 0x00, 0x04, 0x22,
-0x10, 0x85, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x32,
-0x00, 0xC9, 0x01, 0x04, 0x03, 0xD0, 0x1C, 0x60, 0x53, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x00, 0xED, 0x21, 0x84, 0x03, 0x50, 0x1E,
-0x40, 0x38, 0xA0, 0xED, 0x00, 0x34, 0x0F, 0x10, 0x06, 0x40, 0x7A, 0x44, 0xA1,
-0x01, 0x94, 0x03, 0xD0, 0x1E, 0x41, 0x38, 0x00, 0xCD, 0x09, 0x04, 0x02, 0x10,
-0x06, 0x40, 0x32, 0x00, 0xE9, 0x00, 0xB4, 0x07, 0x50, 0x0A, 0x40, 0x2A, 0x00,
-0xCD, 0x11, 0x94, 0x02, 0xD0, 0x0E, 0x41, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x11, 0x10, 0x78, 0x00, 0xCF, 0x01, 0x85, 0x07, 0x70, 0x1C, 0xD0,
-0x58, 0x00, 0x2F, 0x01, 0xBC, 0x07, 0x34, 0x16, 0xC0, 0x5D, 0x00, 0xA1, 0x01,
-0xBC, 0x07, 0xF0, 0x17, 0xC0, 0x78, 0x00, 0xEE, 0x11, 0x8D, 0x06, 0x39, 0x14,
-0xC0, 0x5A, 0x00, 0x6F, 0x01, 0x3C, 0x05, 0x70, 0x14, 0xC0, 0x5A, 0x00, 0x6D,
-0x01, 0x8C, 0x05, 0xF0, 0x16, 0xC4, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x07,
-0x00, 0x1F, 0x00, 0x7C, 0x03, 0x78, 0x01, 0xC8, 0x07, 0x00, 0x8F, 0x00, 0x6C,
-0x03, 0xF0, 0x05, 0xC0, 0x37, 0x00, 0xDF, 0x82, 0x7E, 0x02, 0x74, 0x07, 0xC4,
-0x15, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xB4, 0x01, 0xC0, 0x05, 0x00, 0x5F, 0x20,
-0x6D, 0x00, 0xF0, 0x05, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x20, 0x7D, 0x00, 0xFF, 0x01, 0x8C, 0x13, 0x70, 0x1F, 0xC0, 0x7F, 0x00,
-0xF3, 0x01, 0xCC, 0x07, 0x30, 0x17, 0xC2, 0x6F, 0x10, 0xF2, 0x01, 0xFC, 0x07,
-0xF0, 0x1B, 0xC0, 0x7C, 0x20, 0xF7, 0x81, 0xFC, 0x06, 0xF0, 0x13, 0xC2, 0x79,
-0x00, 0xF3, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC8, 0x7F, 0x00, 0xBB, 0x01, 0xCC,
-0x87, 0x30, 0x1B, 0xC0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0x18, 0x39, 0x00, 0xED, 0x08, 0x8C, 0x03, 0x10, 0x0E, 0x40, 0x1F, 0x00, 0xE1,
-0x08, 0x84, 0x03, 0x14, 0x02, 0x40, 0x1B, 0x01, 0xE1, 0x00, 0xB4, 0x03, 0xD0,
-0x0A, 0x40, 0x38, 0x00, 0xE1, 0x10, 0xB4, 0x13, 0x10, 0x42, 0x40, 0x38, 0x01,
-0xE1, 0x00, 0x9C, 0x03, 0x10, 0x4A, 0x40, 0x2B, 0x20, 0xA1, 0x00, 0xAC, 0x02,
-0x10, 0x0A, 0x40, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x39, 0x00, 0xED, 0x10, 0xA4, 0x23, 0x50, 0x0E, 0x41, 0x3B, 0x44, 0x61, 0x00,
-0x84, 0x03, 0x50, 0x06, 0x40, 0x2B, 0x00, 0xE1, 0x00, 0xB4, 0x23, 0xD0, 0x02,
-0x40, 0x38, 0x00, 0xE5, 0x00, 0x34, 0x02, 0x50, 0x02, 0x60, 0x19, 0x10, 0x61,
-0x00, 0xB4, 0x01, 0x90, 0x06, 0x44, 0x1F, 0x02, 0x01, 0x00, 0x84, 0x01, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31,
-0x20, 0xCD, 0x03, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x03, 0x00, 0x51, 0x00, 0x04,
-0x4B, 0x50, 0x00, 0x40, 0x03, 0x00, 0xC1, 0x43, 0x36, 0x03, 0xD0, 0x00, 0x40,
-0x30, 0x00, 0xC1, 0x03, 0x34, 0x0B, 0x10, 0x00, 0x40, 0x90, 0x40, 0x41, 0x42,
-0x14, 0x01, 0x90, 0x20, 0x40, 0x83, 0x2E, 0x01, 0x02, 0x24, 0x08, 0x10, 0x00,
-0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00,
-0xDF, 0x03, 0x6D, 0x03, 0x70, 0x3D, 0xC0, 0x67, 0x00, 0xD3, 0x00, 0x4D, 0x0B,
-0x70, 0x0D, 0xC2, 0x37, 0x40, 0x93, 0x01, 0x3C, 0x03, 0xF0, 0x0D, 0xD0, 0x30,
-0x00, 0xF7, 0x23, 0x7C, 0x0A, 0x70, 0x05, 0xC0, 0xA1, 0x00, 0x93, 0x03, 0x7C,
-0x06, 0xB0, 0x3D, 0xC0, 0xF7, 0x00, 0xD3, 0xA3, 0x4D, 0x8F, 0x34, 0x1D, 0xD0,
-0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF,
-0x04, 0x5C, 0x0F, 0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x5F, 0x00, 0x3C, 0x03, 0xB0,
-0x09, 0xC0, 0x37, 0x20, 0x9F, 0x08, 0x7C, 0x83, 0xF0, 0x05, 0xC0, 0x37, 0x00,
-0xCF, 0x04, 0x7C, 0x02, 0x70, 0x20, 0xC0, 0x27, 0x04, 0x8F, 0x11, 0x1C, 0x46,
-0x74, 0x19, 0xC1, 0x27, 0x00, 0xD7, 0x01, 0x5C, 0x06, 0xF0, 0x1D, 0xC0, 0x07,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xDF, 0x00,
-0xFC, 0x03, 0xF0, 0x0E, 0xC1, 0x0C, 0x08, 0xBF, 0x03, 0x4C, 0x03, 0x30, 0x0E,
-0xD0, 0x14, 0x00, 0xBF, 0x19, 0xCC, 0x17, 0x30, 0x89, 0xC0, 0x34, 0x00, 0xF7,
-0x00, 0xCC, 0x42, 0xF0, 0x05, 0xC0, 0x8E, 0x00, 0x37, 0x08, 0x68, 0x20, 0x30,
-0x07, 0xC0, 0x1F, 0x00, 0x7F, 0x10, 0x7C, 0x41, 0xF0, 0x07, 0xC0, 0x13, 0x22,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74,
-0x0F, 0xD0, 0x0D, 0xC0, 0x46, 0x00, 0x1D, 0x01, 0x44, 0x27, 0x10, 0x31, 0x40,
-0x04, 0x00, 0x8D, 0x01, 0x44, 0x07, 0x10, 0x01, 0x40, 0x34, 0x00, 0xDB, 0x00,
-0x44, 0x02, 0xD0, 0x19, 0x40, 0x44, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01,
-0x40, 0x07, 0x00, 0x5D, 0x00, 0x74, 0x00, 0xD0, 0x05, 0x40, 0x17, 0x02, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x0F,
-0xD0, 0x0D, 0x40, 0x24, 0x01, 0x9D, 0x10, 0x54, 0x03, 0x14, 0x1D, 0x40, 0x24,
-0x20, 0x9D, 0x00, 0x46, 0x03, 0x10, 0x0C, 0x41, 0x36, 0x02, 0xD0, 0x00, 0x44,
-0x02, 0xD8, 0x11, 0x40, 0x27, 0x00, 0x95, 0x00, 0x74, 0x02, 0x50, 0x0D, 0x40,
-0x37, 0x00, 0x98, 0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0,
-0x0C, 0x50, 0x12, 0x00, 0x0D, 0x00, 0x14, 0x03, 0x10, 0x08, 0x40, 0x10, 0x00,
-0x9D, 0x00, 0x04, 0x03, 0x10, 0x04, 0x48, 0x30, 0x00, 0xC9, 0x00, 0x04, 0x03,
-0xD0, 0x00, 0x40, 0x25, 0x00, 0x81, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x23,
-0x80, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
-0xC0, 0x24, 0x00, 0x8F, 0x00, 0x5D, 0x03, 0x14, 0x05, 0xC0, 0x24, 0x20, 0x9E,
-0x00, 0x4D, 0x03, 0x34, 0x09, 0xD0, 0x34, 0x00, 0xF7, 0x00, 0x4D, 0x02, 0xF0,
-0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x70, 0x05, 0xC8, 0x17, 0x10,
-0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0xA8, 0x3F, 0x20, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0,
-0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xBF, 0x00,
-0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B,
-0xC0, 0x0E, 0x00, 0x3F, 0x20, 0xEC, 0x00, 0xB0, 0x03, 0xC0, 0x0B, 0x00, 0x3F,
-0x40, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0xB0, 0x1B, 0xC0, 0x2F,
-0x21, 0xF3, 0x24, 0xEC, 0x25, 0xF0, 0x1F, 0xD0, 0x3C, 0x00, 0xFB, 0x88, 0xCC,
-0x84, 0xB0, 0x4F, 0xC0, 0x7F, 0x22, 0x2F, 0x01, 0xF4, 0x05, 0x30, 0x0B, 0xC1,
-0xEF, 0x00, 0x2F, 0x01, 0xEC, 0x04, 0x30, 0x12, 0xC0, 0x5E, 0x08, 0x2F, 0x01,
-0xCE, 0x0D, 0x30, 0x0B, 0xC0, 0x0D, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x27, 0x10, 0x9D, 0x01, 0x44, 0x0F, 0x10, 0x15, 0x40, 0x67, 0x00,
-0xD1, 0x14, 0x44, 0x02, 0xD0, 0x4D, 0x40, 0xBC, 0x04, 0xF1, 0x0E, 0x44, 0x07,
-0x10, 0xBF, 0x40, 0x37, 0x00, 0x17, 0x94, 0x64, 0x05, 0x10, 0x39, 0x40, 0x37,
-0x11, 0x5D, 0x21, 0x44, 0x05, 0x51, 0x19, 0x40, 0x75, 0x30, 0x1D, 0x21, 0x46,
-0x02, 0x10, 0x11, 0xC0, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
-0xA0, 0x23, 0x00, 0x0D, 0x80, 0x05, 0x0B, 0xD8, 0x08, 0x40, 0x23, 0x02, 0xC1,
-0x0C, 0x24, 0x02, 0x50, 0x08, 0x41, 0xB0, 0x81, 0xC9, 0x04, 0x54, 0x07, 0x90,
-0x0C, 0x40, 0x33, 0x11, 0x0D, 0x00, 0x74, 0x00, 0x10, 0x0C, 0x44, 0x31, 0x01,
-0x49, 0x00, 0x24, 0x00, 0x12, 0x0D, 0x44, 0x31, 0x00, 0x1D, 0x40, 0x64, 0x13,
-0x90, 0x08, 0x40, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8,
-0x65, 0x00, 0x9D, 0x11, 0x44, 0x03, 0x18, 0x65, 0x40, 0x27, 0x00, 0xD1, 0x00,
-0x42, 0x02, 0xD0, 0x08, 0x40, 0x34, 0x08, 0xC1, 0x00, 0x55, 0x03, 0x10, 0x0D,
-0x40, 0x37, 0x00, 0x9D, 0x11, 0x64, 0x00, 0x1C, 0x0D, 0x40, 0x37, 0x10, 0x5D,
-0x11, 0x44, 0x45, 0x50, 0x89, 0x00, 0x75, 0x00, 0x1D, 0x10, 0x64, 0x43, 0x96,
-0x11, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x47,
-0x04, 0x9F, 0x21, 0x44, 0x03, 0xF2, 0x05, 0xC0, 0x33, 0x40, 0xD3, 0x00, 0x6C,
-0x03, 0xF1, 0x0D, 0xC0, 0x34, 0x00, 0xDB, 0x00, 0x54, 0x04, 0xB0, 0x0D, 0xC0,
-0x37, 0x00, 0x1F, 0x01, 0x7C, 0x14, 0x30, 0x09, 0xC0, 0x35, 0x00, 0x5B, 0x01,
-0x2C, 0x0D, 0x30, 0x31, 0x82, 0x77, 0x01, 0x1D, 0x22, 0x64, 0x0F, 0xB1, 0x31,
-0xC1, 0x81, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00,
-0xAF, 0x00, 0xBC, 0x03, 0xF0, 0x07, 0xC0, 0x3F, 0x02, 0xEF, 0x80, 0xFC, 0x82,
-0xF0, 0x8F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xEC, 0xA0, 0xF0, 0x0F, 0xC2, 0x3F,
-0x10, 0x37, 0x00, 0xEC, 0xA4, 0x70, 0x9B, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC,
-0x01, 0xF0, 0x13, 0xC0, 0x2F, 0x00, 0x3F, 0x08, 0xDD, 0x27, 0x70, 0x03, 0xC0,
-0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x02, 0x13,
-0x10, 0x7E, 0x23, 0xB0, 0x05, 0xC0, 0x37, 0x03, 0xDF, 0x80, 0x7C, 0x03, 0xF1,
-0x09, 0xC0, 0x35, 0x80, 0xDF, 0x08, 0x4C, 0x80, 0x70, 0x0D, 0xC1, 0x37, 0x00,
-0x93, 0x02, 0x5C, 0x08, 0xF8, 0x0D, 0xC2, 0x37, 0x00, 0x5F, 0x0E, 0x78, 0x1B,
-0x70, 0x25, 0xC4, 0xA5, 0x00, 0x53, 0x00, 0x6C, 0x4B, 0x31, 0x09, 0xC4, 0x0B,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xE4, 0x02, 0x91, 0x00,
-0xF4, 0x07, 0x10, 0x05, 0x41, 0x77, 0x00, 0xFD, 0x00, 0x44, 0x02, 0xD0, 0x19,
-0xC8, 0x3E, 0x20, 0xFF, 0x00, 0x00, 0x2C, 0x10, 0x1F, 0x40, 0x37, 0x00, 0x91,
-0x00, 0x04, 0x00, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0x4C, 0x01, 0x44, 0x05, 0xB0,
-0x04, 0x40, 0x24, 0x00, 0x4B, 0x04, 0x24, 0x83, 0x14, 0x71, 0x40, 0x6F, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x40, 0x00, 0x01, 0x00, 0x34,
-0x83, 0x14, 0x3C, 0x41, 0xA3, 0x10, 0xCD, 0x00, 0x14, 0x01, 0xD0, 0x9C, 0x40,
-0x35, 0x08, 0xCD, 0x01, 0x04, 0x08, 0x50, 0xBC, 0x60, 0x32, 0x00, 0x05, 0x00,
-0x14, 0x01, 0xD0, 0x68, 0x40, 0x23, 0x00, 0x49, 0x03, 0x14, 0x8C, 0xD1, 0xB4,
-0x41, 0x31, 0x00, 0x00, 0x00, 0x04, 0x23, 0x10, 0x48, 0x40, 0x0F, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x58, 0x00, 0x61, 0x01, 0xB4, 0x07,
-0x10, 0x16, 0x40, 0x6B, 0x00, 0xED, 0x01, 0x96, 0x06, 0xD0, 0x1E, 0x40, 0x7A,
-0x00, 0xC5, 0x41, 0x84, 0x47, 0x10, 0x1E, 0x68, 0x7B, 0x00, 0xF1, 0x00, 0x84,
-0x05, 0x50, 0x9A, 0x40, 0x7B, 0x02, 0x7D, 0x01, 0xC4, 0x14, 0x90, 0x1A, 0x48,
-0x79, 0x20, 0x39, 0x09, 0x85, 0x27, 0x15, 0x1A, 0x40, 0x3F, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x34, 0x02, 0x43, 0x04, 0x34, 0x03, 0x10,
-0x0C, 0xC0, 0x33, 0x10, 0xDF, 0x00, 0x1C, 0x02, 0xF0, 0x0C, 0xC0, 0x31, 0x00,
-0xCD, 0x00, 0x0C, 0x03, 0x70, 0xCC, 0xC0, 0x37, 0x42, 0x05, 0x00, 0x1C, 0x11,
-0xD0, 0x08, 0xC0, 0x33, 0x00, 0x4B, 0x00, 0x1C, 0x40, 0xF0, 0x8C, 0xC0, 0x31,
-0x02, 0xC3, 0x00, 0x6C, 0x23, 0x30, 0x88, 0xE0, 0x4B, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x40, 0x7F, 0x00, 0xBC, 0x03, 0x70, 0x07,
-0xC0, 0x3F, 0x02, 0xFF, 0x00, 0xCC, 0x02, 0xF0, 0x0C, 0xC0, 0xBF, 0x20, 0xDF,
-0x00, 0x3C, 0x03, 0xC0, 0x8F, 0xC8, 0x37, 0x08, 0xFF, 0x8C, 0x7C, 0x01, 0xF0,
-0x09, 0xC0, 0x3F, 0x00, 0xFF, 0x48, 0x1C, 0x11, 0xF0, 0x89, 0xC0, 0x3A, 0x00,
-0xBF, 0x00, 0xFC, 0x23, 0xF2, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA0, 0x17, 0x00, 0xDF, 0x01, 0x6C, 0x03, 0xF0, 0x0D, 0xC0,
-0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xC4, 0x74, 0x03, 0xD1, 0x0E,
-0x7C, 0x80, 0x70, 0x6D, 0xE0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x00, 0x70, 0x1D,
-0xC0, 0x36, 0x00, 0x5B, 0x00, 0x7C, 0x04, 0xB0, 0x05, 0xC0, 0x37, 0x00, 0x97,
-0x00, 0x4C, 0x03, 0x34, 0x01, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x80, 0x19, 0x00, 0xED, 0x00, 0x84, 0x0B, 0xC0, 0x06, 0x40, 0xAB,
-0x20, 0xED, 0x04, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x31, 0x00, 0xE1, 0x10, 0xB4,
-0x03, 0xD0, 0xEE, 0xC0, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x00, 0xD0, 0x4E, 0x40,
-0x38, 0x00, 0x61, 0x00, 0xA4, 0x00, 0x10, 0x0E, 0x60, 0x3B, 0x00, 0x2D, 0x00,
-0x8D, 0x03, 0xB0, 0x06, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0x85, 0x17, 0x50, 0x1E, 0x41, 0x7B, 0x01,
-0xED, 0x09, 0xB4, 0x07, 0x50, 0x1E, 0x40, 0x78, 0x41, 0xE1, 0x05, 0x94, 0x47,
-0x50, 0x1E, 0x02, 0x7B, 0x10, 0xED, 0x01, 0xB4, 0x04, 0xD2, 0xDC, 0x00, 0x7A,
-0x24, 0x6D, 0x01, 0xD6, 0x0D, 0xD8, 0x1E, 0x40, 0x7B, 0x04, 0xE5, 0x01, 0xF4,
-0x07, 0x10, 0x1A, 0x60, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-0x28, 0x33, 0x00, 0xCD, 0x1A, 0x04, 0x03, 0xD0, 0x14, 0x40, 0x73, 0x02, 0xCD,
-0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x13, 0xD0,
-0x0C, 0x48, 0x30, 0x00, 0xDD, 0x01, 0x34, 0x06, 0xD0, 0x8C, 0x40, 0x30, 0x00,
-0x45, 0x08, 0x34, 0x0D, 0xD0, 0x8C, 0x40, 0x73, 0x00, 0xCD, 0x01, 0x04, 0x03,
-0x17, 0x0C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0,
-0x1D, 0x06, 0x7D, 0x03, 0x6C, 0x01, 0xF0, 0x17, 0xC0, 0x17, 0x00, 0x5F, 0x00,
-0xF4, 0x2D, 0x70, 0x04, 0xC4, 0x14, 0x10, 0x53, 0x80, 0xFC, 0x0D, 0x71, 0x05,
-0xC0, 0x17, 0x00, 0x7F, 0x07, 0xFC, 0x19, 0xF0, 0x15, 0xC0, 0x56, 0x00, 0x6F,
-0x02, 0xFC, 0x05, 0xF0, 0x27, 0xC8, 0x1F, 0x20, 0x67, 0x07, 0xFC, 0x01, 0x10,
-0x97, 0xC2, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05,
-0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC1, 0x87, 0x00, 0x1F, 0x80, 0x7C,
-0x20, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC0,
-0x05, 0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x19, 0x50,
-0x6C, 0x18, 0x10, 0x21, 0xC1, 0xC7, 0x08, 0x1B, 0x30, 0x7E, 0x0C, 0xF0, 0x81,
-0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00,
-0x9F, 0x44, 0x7E, 0x0A, 0xF0, 0x09, 0xD0, 0x64, 0x10, 0x9F, 0x00, 0x7C, 0x06,
-0x30, 0x09, 0xD0, 0x24, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27,
-0x00, 0x93, 0xC0, 0x4C, 0x42, 0xF0, 0x29, 0xC0, 0x26, 0x00, 0x93, 0x80, 0x5C,
-0x0A, 0xF0, 0x19, 0xC0, 0x65, 0x00, 0x9F, 0x00, 0x5C, 0x26, 0x30, 0x29, 0xC0,
-0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x02, 0x9D,
-0x47, 0x74, 0x06, 0xD0, 0x48, 0x40, 0xEC, 0x10, 0x9D, 0x00, 0x34, 0x26, 0x10,
-0x09, 0xC0, 0x26, 0x10, 0x9D, 0x02, 0x74, 0x1A, 0xD0, 0x09, 0x44, 0x27, 0x00,
-0x91, 0x40, 0x4C, 0x02, 0x78, 0x1B, 0x40, 0x23, 0x00, 0x91, 0x10, 0x44, 0x0E,
-0xD0, 0x08, 0x42, 0x20, 0x10, 0x9B, 0x40, 0x0C, 0x1E, 0x54, 0x09, 0xC0, 0x07,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00,
-0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09,
-0x40, 0x24, 0x00, 0x99, 0x10, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x23, 0x00, 0x91,
-0x00, 0x64, 0x02, 0xD1, 0x29, 0x40, 0x27, 0x00, 0x91, 0x01, 0x54, 0x02, 0x50,
-0x4D, 0x40, 0x25, 0x02, 0x94, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x63, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x05, 0x8D, 0x14, 0x34,
-0x02, 0xD0, 0x09, 0x40, 0x20, 0x00, 0x8D, 0x08, 0x74, 0x0A, 0x10, 0x28, 0x40,
-0x22, 0x02, 0x8D, 0x08, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x02, 0x81, 0x08,
-0x04, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x02, 0x91, 0x40, 0x04, 0x02, 0xD2, 0x09,
-0x40, 0x24, 0x00, 0x99, 0x00, 0x46, 0x22, 0x51, 0x48, 0x44, 0x43, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x01, 0x1F, 0x04, 0x74, 0xD0,
-0xF0, 0x01, 0xC0, 0x54, 0x10, 0x1F, 0x16, 0x7E, 0x00, 0x34, 0x01, 0x40, 0x84,
-0x05, 0x19, 0x96, 0x7C, 0x00, 0xF0, 0x41, 0xC1, 0x87, 0x00, 0x13, 0x02, 0x6D,
-0x80, 0xD0, 0x11, 0x40, 0x83, 0x40, 0x13, 0x00, 0x54, 0x01, 0x70, 0x05, 0xC0,
-0x15, 0x00, 0x17, 0x00, 0x7C, 0x08, 0x30, 0x05, 0xC0, 0x77, 0xE0, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2F, 0x25, 0xAF, 0x20, 0x7C, 0x02, 0xF0,
-0x0B, 0xC8, 0xAF, 0x00, 0x9D, 0x04, 0xFC, 0x07, 0xF0, 0x1B, 0xC0, 0x27, 0x09,
-0x9F, 0x04, 0xFC, 0x02, 0xF2, 0x09, 0xC2, 0x27, 0x41, 0xBF, 0x04, 0xFC, 0x02,
-0x50, 0x2B, 0xC0, 0x2F, 0x01, 0xBF, 0x00, 0xB4, 0x02, 0xF2, 0x0B, 0xC0, 0x2F,
-0x00, 0xA7, 0x00, 0xBC, 0x12, 0xF4, 0x8B, 0xC0, 0x75, 0x60, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x05, 0xBF, 0x04, 0xFC, 0x02, 0xF0, 0x0B,
-0xD0, 0x6C, 0x04, 0x91, 0x24, 0xFC, 0x0A, 0xF0, 0x2B, 0xD0, 0x24, 0x00, 0xBF,
-0x00, 0x9E, 0x02, 0xF0, 0x4B, 0xC0, 0x26, 0x00, 0x9F, 0x08, 0x7C, 0x82, 0x34,
-0x5B, 0xD1, 0x24, 0x02, 0xBF, 0x00, 0xEC, 0x02, 0xF2, 0x0B, 0xC0, 0x2E, 0x80,
-0xA7, 0x00, 0xCE, 0x83, 0x30, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x00, 0x07, 0x11, 0x1D, 0x08, 0x74, 0x08, 0xD0, 0x01, 0x40,
-0x84, 0x00, 0x11, 0x14, 0x74, 0x04, 0xD0, 0x51, 0x40, 0x84, 0x04, 0x0D, 0x10,
-0x76, 0x00, 0xD1, 0x01, 0x00, 0x04, 0x01, 0x1D, 0x04, 0x74, 0x00, 0x19, 0x21,
-0x40, 0x04, 0x00, 0x19, 0x00, 0x5C, 0x00, 0xD2, 0x01, 0x40, 0x04, 0x10, 0x1D,
-0x00, 0x05, 0x00, 0xB4, 0x01, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x00, 0x34, 0x22, 0xD0, 0x09, 0x40, 0x20,
-0x00, 0x81, 0x0C, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x20, 0x83, 0x8D, 0x08, 0x14,
-0x02, 0xD3, 0x88, 0x00, 0x22, 0x05, 0x8D, 0x04, 0x74, 0x02, 0x10, 0x08, 0x40,
-0x20, 0x10, 0x8D, 0x00, 0x36, 0x82, 0xD0, 0x08, 0x40, 0x22, 0x00, 0x95, 0x00,
-0x54, 0x02, 0x14, 0x0C, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x2A, 0x25, 0x86, 0x9D, 0x20, 0x74, 0x02, 0xD2, 0x09, 0x40, 0x24, 0x00,
-0x91, 0x20, 0x74, 0x02, 0xD0, 0x1D, 0x40, 0x24, 0x00, 0x9D, 0x40, 0x74, 0x42,
-0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10, 0x09, 0x44, 0x24,
-0x01, 0x9D, 0x02, 0x55, 0x0B, 0xD1, 0x89, 0x40, 0xE4, 0x00, 0x9D, 0x03, 0x54,
-0x2A, 0x90, 0x2D, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0x02, 0x25, 0x10, 0x9F, 0x12, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93,
-0x00, 0xFC, 0x22, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x5C, 0x2A, 0xF0,
-0x09, 0xC2, 0x26, 0x00, 0x9F, 0x00, 0x3E, 0x3A, 0x10, 0x99, 0xC8, 0x24, 0x20,
-0x8F, 0x4B, 0x7C, 0x22, 0xF0, 0x49, 0xC0, 0xA6, 0x80, 0x87, 0x01, 0x54, 0x02,
-0x31, 0x09, 0xE0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08,
-0x25, 0x0C, 0x9F, 0x84, 0x7C, 0x02, 0xF8, 0x09, 0xE0, 0x23, 0x41, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x10, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C, 0x06, 0xF8, 0x19, 0xC4, 0x67, 0x00, 0x9B,
-0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE8, 0x27, 0x88, 0x9F, 0x00, 0x6C, 0x06, 0xD1,
-0x48, 0xD8, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05,
-0x00, 0x1F, 0x82, 0x7C, 0x80, 0xF8, 0x41, 0xD0, 0x06, 0x40, 0x13, 0x00, 0x7C,
-0x00, 0x70, 0x41, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x4D, 0xC8, 0x71, 0x01, 0x41,
-0x06, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC1, 0x07, 0x20, 0x1F, 0x30,
-0x5C, 0x10, 0x70, 0xC1, 0xC8, 0x87, 0x20, 0x1F, 0x10, 0x4C, 0x10, 0x32, 0x41,
-0xC4, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xDC, 0x04,
-0x7D, 0x07, 0x74, 0x15, 0x78, 0x76, 0xC0, 0x1C, 0x00, 0x51, 0x00, 0x74, 0x01,
-0x10, 0x16, 0x45, 0x14, 0x00, 0x71, 0x86, 0xC4, 0x09, 0x12, 0x16, 0x40, 0x17,
-0x00, 0x5D, 0x00, 0x74, 0x01, 0x70, 0x36, 0x40, 0x17, 0x10, 0x7D, 0x00, 0xF0,
-0x0D, 0x12, 0x36, 0x48, 0xDF, 0x02, 0x7D, 0x04, 0x80, 0x15, 0x50, 0x07, 0x50,
-0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xF2, 0x00, 0x8D,
-0x06, 0x34, 0x07, 0x50, 0x18, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x36, 0x23, 0x50,
-0x08, 0x40, 0x32, 0x40, 0xC9, 0x00, 0x04, 0x2F, 0x50, 0xBC, 0x40, 0x33, 0x00,
-0xCD, 0x00, 0x14, 0x03, 0x50, 0x28, 0x40, 0x33, 0x80, 0x4D, 0x0A, 0x34, 0x2F,
-0x50, 0x1C, 0x40, 0xD3, 0x00, 0xC9, 0x00, 0x04, 0x0B, 0x11, 0x0C, 0x40, 0x40,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x80, 0xAD, 0x00,
-0xB4, 0x03, 0x50, 0x02, 0x40, 0x28, 0x00, 0xE1, 0x00, 0xB4, 0x17, 0x18, 0x0E,
-0x40, 0x70, 0x02, 0xE9, 0x01, 0xC4, 0x07, 0x10, 0x0E, 0x40, 0x3B, 0x01, 0xED,
-0x08, 0xB4, 0x03, 0x50, 0x22, 0x40, 0x3B, 0xB0, 0x6D, 0x00, 0xB6, 0x07, 0x11,
-0x06, 0x40, 0x1B, 0x8C, 0xFD, 0x00, 0x85, 0x03, 0x10, 0x0C, 0x40, 0x10, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01, 0xBC,
-0x07, 0x70, 0x12, 0xC0, 0x68, 0x00, 0xE3, 0x01, 0xFC, 0x0F, 0x70, 0x1A, 0xD0,
-0x7A, 0x01, 0xE9, 0x01, 0x8C, 0x07, 0x70, 0x1E, 0xE8, 0x7B, 0x03, 0xEF, 0x01,
-0xBC, 0x07, 0x70, 0x12, 0xC0, 0x7B, 0x25, 0x6F, 0x01, 0x9E, 0x06, 0x70, 0x1A,
-0xC0, 0x6B, 0x00, 0xEF, 0x01, 0x8C, 0x06, 0x34, 0x1E, 0xC0, 0x50, 0x60, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF, 0x00, 0x7C, 0x03,
-0x70, 0x00, 0xC0, 0x21, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0xF2, 0x0C, 0xC0, 0x37,
-0x20, 0xD7, 0x80, 0x7C, 0x01, 0xF2, 0x0D, 0xC0, 0x37, 0x02, 0xDF, 0x10, 0x78,
-0x03, 0x70, 0x01, 0xC2, 0x37, 0x1A, 0x1F, 0x80, 0x3C, 0x02, 0xF0, 0x05, 0xC0,
-0x27, 0x20, 0xDF, 0x00, 0x7C, 0x02, 0xF6, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x5D, 0x00, 0xA3, 0x01, 0xCC, 0x13, 0xF8,
-0x03, 0xC0, 0x6D, 0x00, 0xFF, 0x11, 0xBC, 0x07, 0x20, 0xDB, 0xC0, 0x7C, 0x00,
-0x7F, 0x01, 0xCC, 0x07, 0xF0, 0x9F, 0xD0, 0x7C, 0x00, 0xDF, 0x09, 0xFC, 0x07,
-0xF0, 0x13, 0xC0, 0x7F, 0x20, 0x2F, 0x09, 0xEE, 0x17, 0xF0, 0x1F, 0xC0, 0x5F,
-0x00, 0xFF, 0x01, 0x8C, 0x05, 0x30, 0xDB, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0xA1, 0x00, 0x84, 0x03, 0x78, 0x42,
-0x40, 0x28, 0x02, 0xED, 0x00, 0xB4, 0x13, 0x10, 0x8A, 0x50, 0x38, 0x11, 0x2D,
-0x04, 0x8C, 0x1A, 0xD0, 0x8A, 0x40, 0x38, 0x00, 0xED, 0x05, 0xB4, 0x03, 0x90,
-0x02, 0x40, 0x3B, 0x00, 0x2D, 0x00, 0x9E, 0x03, 0xD0, 0x0E, 0x40, 0x9B, 0x22,
-0xAD, 0x04, 0xAC, 0x01, 0x10, 0xCE, 0x48, 0x55, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0xA1, 0x00, 0x85, 0x23, 0x50, 0x82, 0x43,
-0x29, 0x00, 0xED, 0x00, 0xF4, 0x02, 0x10, 0x4B, 0x48, 0x38, 0x80, 0x6D, 0x80,
-0x84, 0x03, 0xD2, 0x06, 0x00, 0x38, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x02,
-0x40, 0x3B, 0x00, 0x3D, 0x00, 0x84, 0x12, 0xD0, 0x0A, 0x40, 0x9B, 0x00, 0xF5,
-0x10, 0xD4, 0x20, 0x10, 0xC2, 0x44, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x28, 0xC3, 0x00, 0x01, 0x01, 0x00, 0x02, 0x50, 0x30, 0x40, 0x20,
-0x00, 0xCD, 0x00, 0x34, 0x22, 0x10, 0x08, 0x40, 0x30, 0x00, 0x1D, 0x00, 0x04,
-0x4C, 0xD0, 0x00, 0x40, 0x30, 0x00, 0xCD, 0x04, 0x34, 0x43, 0xD0, 0x00, 0x40,
-0x77, 0x00, 0x0D, 0x12, 0x14, 0xC6, 0xD9, 0x8C, 0x40, 0x13, 0x00, 0x8D, 0x23,
-0x05, 0x03, 0x14, 0x24, 0x40, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0xA0, 0xE5, 0x41, 0x93, 0x0A, 0x4C, 0x03, 0x70, 0x35, 0xC0, 0x35, 0x00,
-0xFF, 0x00, 0x74, 0x02, 0x34, 0x08, 0xC0, 0x3C, 0x00, 0x9F, 0x00, 0x4C, 0x4E,
-0xF0, 0x09, 0xC0, 0x3C, 0x00, 0xFF, 0x13, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x3F,
-0x01, 0x5F, 0x01, 0x4C, 0x07, 0xF1, 0xBD, 0xC0, 0xB7, 0x00, 0xD7, 0x03, 0x14,
-0x4F, 0x30, 0x94, 0xC0, 0x54, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0x08, 0x27, 0x00, 0x9F, 0x88, 0x7C, 0x03, 0x70, 0x21, 0xC0, 0xB7, 0x00, 0xDF,
-0x00, 0x7C, 0x42, 0xF0, 0x29, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x5D, 0x02, 0xF0,
-0x00, 0xC4, 0x37, 0x00, 0xDF, 0x20, 0x7C, 0x03, 0xB0, 0x25, 0xE4, 0x37, 0x00,
-0x5F, 0x01, 0x4D, 0x23, 0xF0, 0x05, 0xC0, 0xF7, 0x00, 0xDF, 0x02, 0x7C, 0x1B,
-0xF0, 0x3D, 0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
-0x27, 0x04, 0xFF, 0x02, 0xFC, 0x03, 0xF0, 0x17, 0xC1, 0x6B, 0x00, 0xF7, 0x00,
-0xFC, 0x07, 0xD0, 0x1B, 0xC0, 0x3C, 0x08, 0x1F, 0x00, 0xCC, 0x02, 0xF0, 0x09,
-0xC0, 0x3D, 0x80, 0xFF, 0x80, 0xCC, 0x03, 0xF8, 0x13, 0xC0, 0x3D, 0x00, 0xF3,
-0x00, 0xFC, 0x26, 0xF0, 0x03, 0xCC, 0x2F, 0x00, 0xF7, 0x10, 0xCC, 0x02, 0x30,
-0x11, 0xC8, 0x04, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66,
-0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x01, 0x40, 0x17, 0x00, 0xD1, 0x80, 0x74,
-0x07, 0xD0, 0x39, 0x50, 0x34, 0x00, 0x1D, 0x09, 0x44, 0x0C, 0xD0, 0x11, 0x40,
-0x34, 0x80, 0xDD, 0x00, 0x44, 0x03, 0xD8, 0x00, 0xC1, 0x34, 0x40, 0x11, 0x03,
-0x72, 0x0E, 0x70, 0x05, 0x41, 0x23, 0x00, 0xCB, 0x22, 0x44, 0x64, 0x14, 0x39,
-0xC0, 0x06, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x0C,
-0x9D, 0x00, 0x74, 0x03, 0xD0, 0x45, 0x41, 0xB7, 0x01, 0xD5, 0x00, 0x74, 0x12,
-0xD0, 0x81, 0x40, 0x36, 0x00, 0xDD, 0x02, 0x44, 0x04, 0xD2, 0x19, 0x41, 0x34,
-0x00, 0xCD, 0x00, 0x44, 0x03, 0xD0, 0x45, 0x40, 0x36, 0x20, 0x51, 0x11, 0x64,
-0x03, 0xD0, 0x19, 0x40, 0x37, 0x00, 0x51, 0x02, 0x44, 0x01, 0x10, 0x41, 0x40,
-0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x8D,
-0x00, 0x34, 0x03, 0xD0, 0x04, 0x40, 0x32, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0,
-0x00, 0x40, 0x32, 0x00, 0x8D, 0x00, 0x04, 0x00, 0xD2, 0x00, 0x40, 0x30, 0x00,
-0xCD, 0x10, 0x04, 0x03, 0xD0, 0x04, 0x60, 0x30, 0x00, 0x41, 0x20, 0x34, 0x01,
-0x50, 0x08, 0x40, 0x37, 0x80, 0x09, 0x00, 0x45, 0x00, 0x10, 0x0C, 0x44, 0x42,
-0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xDF, 0x00,
-0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x27, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0xF2, 0x01,
-0xD0, 0x36, 0x00, 0x5F, 0x00, 0x45, 0x00, 0xF0, 0x01, 0xD0, 0x3C, 0x20, 0xFD,
-0x00, 0x4D, 0x03, 0xD0, 0x05, 0xC0, 0x3F, 0x10, 0x53, 0x20, 0x74, 0x83, 0xF0,
-0x01, 0xC8, 0x37, 0x80, 0x57, 0x00, 0x4C, 0x00, 0x31, 0x01, 0xC0, 0x04, 0x44,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x00, 0x7F, 0x00, 0xFC,
-0x02, 0xF0, 0x06, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x02, 0xC0,
-0x3D, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0, 0x03, 0x82, 0x3F, 0x10, 0xFF, 0x80,
-0xFC, 0x03, 0xF0, 0x07, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0x70, 0x03,
-0xC0, 0x3F, 0x00, 0x2D, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0x80, 0x14, 0x20, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xF3, 0x09, 0x8C, 0x07,
-0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xFF, 0x01, 0xFC, 0x27, 0xF0, 0x9F, 0xC0, 0x7F,
-0x02, 0xFF, 0x09, 0xFC, 0x27, 0xF0, 0x9F, 0xC0, 0x7D, 0x02, 0xEF, 0x01, 0xCC,
-0x07, 0xF0, 0x1E, 0x40, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0xB0, 0x0F, 0xC0,
-0x3C, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0x40, 0x11, 0x00, 0x45, 0x04, 0xD0,
-0x11, 0x52, 0x04, 0x00, 0x0D, 0x00, 0x74, 0x10, 0xD0, 0x01, 0x40, 0x07, 0x01,
-0x1D, 0x04, 0x74, 0x10, 0xD0, 0x40, 0xC0, 0x06, 0x01, 0x1D, 0x81, 0x44, 0x04,
-0xD0, 0x11, 0x40, 0x74, 0x08, 0x51, 0x21, 0x44, 0x07, 0x10, 0x15, 0x42, 0x74,
-0x00, 0xD1, 0x00, 0x44, 0x07, 0x10, 0x19, 0x48, 0x07, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x00, 0xC1, 0x04, 0x14, 0x03, 0xD0, 0x0D,
-0x60, 0x30, 0x05, 0xCD, 0x14, 0x34, 0x03, 0xD0, 0x4C, 0x40, 0x33, 0x00, 0xC5,
-0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0,
-0x0C, 0x40, 0x32, 0x00, 0x81, 0x00, 0x04, 0x02, 0x50, 0x0C, 0x40, 0x32, 0x00,
-0xC5, 0x00, 0x44, 0x02, 0x14, 0x0C, 0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0xA8, 0x05, 0x00, 0x01, 0x40, 0x54, 0x00, 0xD0, 0x01, 0x60,
-0x04, 0x30, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x20,
-0x74, 0x00, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x64, 0x80, 0xC0, 0x01,
-0x40, 0x36, 0x00, 0xD1, 0x00, 0x44, 0x43, 0xD0, 0xAD, 0x40, 0x36, 0x04, 0xC5,
-0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA0, 0x33, 0x00, 0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x34,
-0x00, 0xDF, 0x80, 0x7C, 0x83, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C,
-0x03, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0x40,
-0x86, 0x04, 0xD3, 0x09, 0x4C, 0x25, 0xF0, 0x3D, 0xC0, 0x26, 0x00, 0xD7, 0x09,
-0x0D, 0x03, 0x30, 0x09, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x07, 0x88, 0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
-0x3F, 0x00, 0xF4, 0x00, 0xF1, 0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00,
-0xA0, 0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC8, 0x19,
-0x00, 0xCF, 0x21, 0xBC, 0x01, 0x30, 0x16, 0xC2, 0x39, 0x02, 0xFB, 0x00, 0xFC,
-0x13, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x08, 0x35, 0x00, 0xDF, 0x05, 0x7C, 0x03, 0x32, 0x0D, 0xC2, 0x37, 0x00, 0xDF,
-0x00, 0x4C, 0x07, 0xF0, 0x0D, 0xC0, 0x77, 0x00, 0xDF, 0x01, 0x7C, 0x07, 0xF0,
-0x0D, 0xC0, 0x74, 0x00, 0xDF, 0x01, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0xB5, 0x00,
-0x93, 0x00, 0x4C, 0x0A, 0x70, 0x0D, 0xC2, 0xA4, 0x00, 0xD7, 0x00, 0x4C, 0x02,
-0xF0, 0x09, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
-0x04, 0x10, 0x1D, 0x01, 0x74, 0x00, 0x14, 0xB0, 0x40, 0x07, 0x00, 0x1D, 0x00,
-0x44, 0x04, 0xC1, 0xA1, 0x42, 0x07, 0x00, 0x1D, 0x01, 0x74, 0x84, 0xD0, 0xE1,
-0x40, 0x44, 0x00, 0x0D, 0x00, 0x44, 0x00, 0xB0, 0x00, 0x40, 0x34, 0x00, 0xD1,
-0x80, 0x44, 0x13, 0x10, 0x0D, 0x40, 0x34, 0x10, 0xDD, 0x0A, 0x44, 0x46, 0xD0,
-0x1D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30,
-0x00, 0xCD, 0x02, 0x34, 0x03, 0x10, 0x3C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x04,
-0x1B, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x10, 0x34, 0x03, 0xD0, 0x0D, 0x40,
-0x30, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x50, 0x0C, 0x44, 0x30, 0x00, 0xC1, 0x00,
-0x04, 0x83, 0x14, 0x08, 0x40, 0x12, 0x00, 0xC4, 0x00, 0x04, 0x03, 0xD0, 0x1C,
-0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00,
-0x2D, 0x09, 0xF4, 0x24, 0x10, 0x12, 0x40, 0x4B, 0x00, 0x2D, 0x00, 0x84, 0x24,
-0xD0, 0x12, 0x40, 0x4B, 0x00, 0x2D, 0x41, 0xB4, 0x0C, 0xD0, 0x12, 0x60, 0xC8,
-0x00, 0x2D, 0x01, 0xC4, 0x04, 0xD2, 0x32, 0x40, 0x70, 0x00, 0x61, 0x01, 0x05,
-0x07, 0x10, 0x1C, 0x40, 0x7A, 0x00, 0xED, 0x01, 0x84, 0x07, 0xD1, 0x1A, 0x60,
-0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0xCF,
-0x00, 0x3C, 0x03, 0x30, 0x0C, 0xC3, 0x33, 0x02, 0xCF, 0x08, 0x0C, 0x03, 0xF0,
-0x0C, 0xC2, 0x32, 0x00, 0xCD, 0x00, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00,
-0xCF, 0x00, 0x0C, 0x03, 0x70, 0x0C, 0xC0, 0x31, 0x00, 0xC3, 0x04, 0x0C, 0x03,
-0x70, 0x0C, 0xC0, 0x32, 0x00, 0xD7, 0x00, 0x0D, 0x03, 0xF2, 0x8C, 0x51, 0x48,
-0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00,
-0xFC, 0x00, 0xF0, 0x03, 0xC8, 0x0F, 0x08, 0x3F, 0x04, 0xFC, 0x00, 0xF0, 0x03,
-0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F,
-0x40, 0xBC, 0x00, 0xB0, 0x13, 0xC4, 0x3F, 0x02, 0xFF, 0x00, 0xFE, 0x03, 0xF2,
-0x0F, 0xC0, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0A, 0xC2, 0x0B, 0xE0,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x37, 0x00, 0xDF, 0x01, 0x0D,
-0x07, 0x34, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x4C, 0x07, 0x3C, 0x0D, 0xC0,
-0x77, 0x00, 0xD7, 0x01, 0x4D, 0x87, 0x34, 0x1D, 0xC0, 0x75, 0x40, 0xD3, 0x00,
-0x7E, 0x03, 0xF0, 0x1D, 0xC0, 0x24, 0x00, 0xD3, 0x00, 0x4C, 0x03, 0xB8, 0x09,
-0xC0, 0x54, 0x00, 0xDB, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC0, 0x41, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x90, 0x08, 0x00, 0x2D, 0x00, 0x84, 0x00,
-0x18, 0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0xD4, 0x00, 0x10, 0x02, 0x40, 0x0F,
-0x00, 0x31, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x40, 0x0C, 0x00, 0x21, 0x00, 0x9C,
-0x80, 0xD0, 0x02, 0x40, 0x39, 0x00, 0xE1, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x42,
-0x38, 0x00, 0xF1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x4B, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0xC4, 0x87, 0x12,
-0x1E, 0x60, 0x7B, 0x80, 0xE9, 0x01, 0x84, 0x07, 0x10, 0x1E, 0x42, 0x7B, 0x20,
-0xE5, 0x01, 0xA0, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x00, 0xE9, 0x01, 0x94, 0x07,
-0xD0, 0x1F, 0x40, 0x72, 0x08, 0xC1, 0x01, 0x04, 0x07, 0x10, 0x1C, 0x40, 0x70,
-0x00, 0xE1, 0x01, 0x84, 0x06, 0xD0, 0x1A, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x16, 0x20, 0x03, 0x00, 0x0D, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x03, 0x00, 0x0D, 0x00, 0x14, 0x00, 0x18, 0x00, 0x40, 0x03, 0x00, 0x01,
-0x00, 0x24, 0x00, 0x10, 0x00, 0x40, 0x02, 0x00, 0x09, 0x00, 0x14, 0x00, 0xD0,
-0x00, 0x40, 0x33, 0x40, 0xC1, 0x00, 0x05, 0x03, 0x14, 0x0C, 0x50, 0x30, 0x52,
-0x91, 0x48, 0x04, 0x02, 0xD0, 0x1C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x17, 0x28, 0x15, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0x30, 0x05, 0xC0,
-0x17, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0x30, 0x04, 0xC0, 0x17, 0x10, 0x57, 0x00,
-0x64, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5B, 0x00, 0x5C, 0x01, 0xF0, 0x05,
-0xC0, 0x1E, 0x00, 0x73, 0x02, 0xCC, 0x09, 0x30, 0x07, 0xC0, 0x5C, 0x00, 0x53,
-0x01, 0x4C, 0x01, 0xF2, 0x05, 0xC1, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x00, 0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x23, 0xC0, 0x0F,
-0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xDC,
-0x00, 0xF0, 0x23, 0xC0, 0x0D, 0x20, 0x37, 0x02, 0xDC, 0x00, 0xF0, 0x03, 0xE2,
-0x41, 0x00, 0x0F, 0x10, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x02,
-0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x08, 0x25, 0x00, 0x9F, 0x05, 0x7C, 0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x0A, 0xF0, 0x29, 0xC0, 0x24, 0x01, 0x9F, 0x01, 0x5C, 0x02,
-0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x20, 0x09, 0xC0, 0x27,
-0x20, 0x93, 0x20, 0x0C, 0x02, 0x34, 0x08, 0xC0, 0x24, 0x00, 0x9F, 0x05, 0x4C,
-0x06, 0xF0, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x26, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x90, 0x49, 0x48, 0x27, 0x00, 0x9D,
-0x00, 0x74, 0x0A, 0xD9, 0x39, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x0A, 0xD0,
-0xD9, 0x40, 0xA7, 0x80, 0x9F, 0x12, 0x34, 0x02, 0xB0, 0x09, 0x40, 0xA7, 0x20,
-0x91, 0x82, 0x44, 0x0A, 0x30, 0x29, 0x40, 0xA4, 0x00, 0x9D, 0x02, 0x44, 0x06,
-0xD0, 0x08, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
-0x24, 0x00, 0xBD, 0x00, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xB5, 0x00,
-0xF4, 0x02, 0xD0, 0x0B, 0x60, 0x2C, 0x00, 0xBD, 0x08, 0xF6, 0x06, 0xD0, 0x0B,
-0x40, 0x6F, 0x10, 0xBD, 0x00, 0xF4, 0x02, 0x50, 0x1B, 0x42, 0x27, 0x04, 0x91,
-0x10, 0x64, 0x42, 0x00, 0x09, 0x41, 0x24, 0x84, 0x9D, 0x00, 0x64, 0x22, 0xD0,
-0x89, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x28,
-0x00, 0xAD, 0x01, 0xB4, 0x02, 0x91, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4,
-0x06, 0xD0, 0x0B, 0x42, 0x29, 0x00, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x0A, 0x60,
-0x6B, 0x00, 0xA5, 0x00, 0xF4, 0x02, 0xD2, 0x0A, 0x60, 0x23, 0x41, 0x81, 0x04,
-0x24, 0x92, 0x90, 0x48, 0x40, 0x20, 0x01, 0x8D, 0x40, 0x24, 0x02, 0xD0, 0x09,
-0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x00,
-0x0F, 0x0A, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x12, 0x17, 0x0A, 0x7C, 0x28,
-0xD0, 0xA5, 0xD0, 0x84, 0x02, 0x1D, 0x0A, 0x5C, 0x28, 0xF0, 0xA0, 0xC0, 0x87,
-0x02, 0x1D, 0x00, 0x7C, 0x00, 0x60, 0x03, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x65,
-0x00, 0x32, 0x01, 0xD0, 0x04, 0x00, 0x5F, 0x0A, 0x6C, 0x00, 0xF0, 0x01, 0xC0,
-0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x00, 0x9F,
-0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x08, 0xC0, 0x2F, 0x02, 0xBF, 0x08, 0xDC, 0x22,
-0x70, 0x8B, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xDD, 0x02, 0xF0, 0x0B, 0xC0, 0x77,
-0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x27, 0x00, 0xB3, 0x00,
-0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0xF0, 0x0A,
-0xC0, 0x2D, 0x02, 0xB7, 0x00, 0xFE, 0x02, 0xF0, 0x8B, 0xC0, 0x2F, 0x00, 0x9F,
-0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x34, 0x00, 0x9F, 0x00, 0x6D, 0x12, 0x30,
-0x49, 0xC1, 0x24, 0x01, 0xB3, 0x00, 0xCC, 0x03, 0xF0, 0x0B, 0xC0, 0x73, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05, 0x00, 0x11, 0x04, 0x45,
-0x00, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x45, 0x50, 0x70, 0x41, 0x40,
-0x04, 0x01, 0x11, 0x10, 0x74, 0x40, 0xD1, 0x01, 0x40, 0x07, 0x05, 0x1D, 0x00,
-0x74, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x1D, 0x08, 0x44, 0x00, 0x10, 0x01,
-0x40, 0x0C, 0x12, 0x01, 0x10, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x63, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x25, 0x40, 0x81, 0x14, 0x04, 0x02,
-0xD0, 0x08, 0x40, 0x20, 0x00, 0x9D, 0x00, 0x04, 0x12, 0xD0, 0x48, 0x41, 0x21,
-0x21, 0x85, 0x04, 0x30, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x01, 0xAD, 0x00, 0xB4,
-0x03, 0xD0, 0x0B, 0x40, 0x6A, 0x02, 0xAD, 0x01, 0x84, 0x26, 0x10, 0x1A, 0x40,
-0x68, 0x00, 0x99, 0x04, 0x05, 0x02, 0xD0, 0x0C, 0x40, 0x4B, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0xD1, 0x00, 0x44, 0x02, 0xD0,
-0x09, 0x40, 0x24, 0x80, 0x9D, 0x40, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00,
-0x91, 0x80, 0x74, 0x02, 0xD2, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0xF4, 0x82,
-0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xBD, 0x00, 0xC4, 0x02, 0x10, 0x0B, 0x40, 0x2C,
-0x10, 0x99, 0x01, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0x00, 0x25, 0x00, 0x93, 0x00, 0x48, 0x02, 0xF0, 0x08,
-0xC0, 0x24, 0x00, 0x9F, 0x20, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x95,
-0x00, 0x74, 0x02, 0xE0, 0x09, 0x80, 0x27, 0x00, 0x9F, 0x40, 0x7E, 0x02, 0xF0,
-0x09, 0xC0, 0xA6, 0x02, 0x9F, 0x03, 0x4C, 0x2A, 0x34, 0xB9, 0xC0, 0xA4, 0x00,
-0x8B, 0xA0, 0x4C, 0x82, 0xF0, 0x09, 0xC0, 0x17, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x16, 0x08, 0x24, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0xD0,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC8, 0x27, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x25, 0x00, 0x9F, 0x03, 0x5C, 0x06, 0xF0, 0x19, 0xD0, 0x27, 0x40, 0x97,
-0x20, 0x7C, 0x12, 0xF0, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07,
-0x00, 0x13, 0x10, 0x7C, 0x00, 0xF2, 0x81, 0xD1, 0x06, 0x00, 0x1F, 0x00, 0x7C,
-0x60, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0,
-0x07, 0x00, 0x03, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x03, 0x00, 0x1F, 0x00,
-0x4D, 0x04, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x20, 0x10, 0x00, 0x7D, 0x00, 0x76, 0x45, 0xD0, 0x07, 0xC0, 0x15, 0x20,
-0x65, 0x00, 0xF4, 0x09, 0xD0, 0x27, 0xD0, 0x16, 0x00, 0x77, 0x00, 0xF4, 0x09,
-0xD2, 0x07, 0x40, 0x1F, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x14, 0x04, 0xC0, 0x15,
-0x00, 0x51, 0x01, 0x74, 0x01, 0xD0, 0x15, 0x40, 0x57, 0x10, 0x7D, 0x41, 0xC4,
-0x01, 0xD0, 0x05, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA0, 0x32, 0x00, 0xDD, 0x40, 0x34, 0x07, 0xD0, 0x04, 0x40, 0x31, 0x80, 0x49,
-0x00, 0x34, 0x4B, 0xD0, 0x3D, 0x40, 0x36, 0x30, 0xCD, 0x00, 0x34, 0x07, 0xD8,
-0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x31, 0x00,
-0xC1, 0x21, 0x34, 0x03, 0xD0, 0x1C, 0x40, 0x73, 0x00, 0xCD, 0x00, 0x04, 0x07,
-0xD0, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80,
-0x38, 0x00, 0x6D, 0x00, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x79, 0x02, 0x6D, 0x10,
-0xB6, 0x03, 0xD0, 0x0E, 0x58, 0x2A, 0x00, 0x6D, 0x00, 0xB4, 0x01, 0xD9, 0x02,
-0x40, 0x1B, 0x00, 0xAD, 0x00, 0xB4, 0x07, 0x10, 0x06, 0x40, 0x71, 0x40, 0xE1,
-0x10, 0xB4, 0x02, 0xD0, 0x0E, 0x41, 0x3B, 0x04, 0xED, 0x02, 0x84, 0x43, 0xD0,
-0x0A, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78,
-0x00, 0xAF, 0x01, 0xB4, 0x07, 0xD0, 0x16, 0xC0, 0x7D, 0x00, 0x6B, 0x01, 0xBC,
-0x06, 0xF0, 0x16, 0xD0, 0x7A, 0x00, 0xAF, 0x01, 0xB4, 0x06, 0xF0, 0x1E, 0xC0,
-0x6B, 0x00, 0x6F, 0x01, 0xB8, 0x07, 0x30, 0x1A, 0xC0, 0x59, 0x00, 0x63, 0x01,
-0xBC, 0x05, 0xF0, 0x16, 0xC0, 0x5B, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0xF0, 0x1E,
-0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00,
-0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x75, 0x20, 0x57, 0x00, 0x7C, 0x00,
-0xF0, 0x05, 0xD0, 0x27, 0x00, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
-0x00, 0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC2, 0x15, 0x00, 0x5F, 0x00, 0x7C,
-0x00, 0xF8, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
-0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D, 0x00, 0xFF,
-0x01, 0xBC, 0x07, 0xF8, 0x87, 0xC0, 0x7C, 0x00, 0xB3, 0x89, 0xCC, 0x05, 0xA0,
-0x1B, 0xC0, 0x7F, 0x20, 0xF3, 0x01, 0xDC, 0x07, 0x30, 0x1F, 0xC0, 0x7C, 0x00,
-0xF3, 0x01, 0xCC, 0x06, 0xF2, 0x1F, 0xC0, 0x7F, 0x00, 0xBF, 0x01, 0xCC, 0x07,
-0xF0, 0x1B, 0xC0, 0x6C, 0x00, 0xF3, 0x01, 0xFC, 0x05, 0x30, 0x1F, 0xC0, 0x1B,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0x6D, 0x00,
-0x9C, 0x03, 0x18, 0x0A, 0x40, 0x38, 0x00, 0xA1, 0x00, 0xC4, 0x03, 0x11, 0x0A,
-0x40, 0x2B, 0x00, 0x71, 0x00, 0xC4, 0x02, 0x10, 0x02, 0x40, 0x1C, 0x00, 0xA1,
-0x00, 0x84, 0x0A, 0xD0, 0x06, 0x40, 0x3B, 0x00, 0xAD, 0x00, 0x84, 0x02, 0xD0,
-0x0A, 0x40, 0x28, 0x12, 0xE1, 0x00, 0xB4, 0x00, 0xB0, 0x0E, 0x40, 0x57, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xAD, 0x00, 0xB4,
-0x03, 0x50, 0x87, 0x40, 0x3C, 0x00, 0xB1, 0x00, 0x84, 0x20, 0x10, 0x02, 0x40,
-0xBF, 0x00, 0xA9, 0x00, 0x84, 0x01, 0x10, 0x0F, 0x40, 0x2A, 0x00, 0x79, 0x02,
-0x84, 0x02, 0xD0, 0x0A, 0x40, 0x1B, 0x00, 0x0D, 0x00, 0x84, 0x01, 0xD0, 0x80,
-0x40, 0x00, 0x00, 0xA1, 0x00, 0xF4, 0x40, 0x10, 0x0E, 0x40, 0x03, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0xF1, 0x00, 0x1D, 0x02, 0x34, 0x43,
-0x10, 0x00, 0x41, 0xB0, 0x04, 0x81, 0x04, 0x04, 0x34, 0x91, 0x38, 0x40, 0x23,
-0x00, 0x09, 0x0D, 0x04, 0x34, 0x10, 0x00, 0x41, 0x42, 0x43, 0x09, 0x20, 0x04,
-0x06, 0xD0, 0x10, 0x40, 0x13, 0x00, 0x0D, 0x12, 0x04, 0x00, 0xD0, 0x00, 0x40,
-0x80, 0x00, 0x01, 0x20, 0x34, 0x84, 0x90, 0x0C, 0x40, 0x0B, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0xB5, 0x00, 0xDF, 0x05, 0x7C, 0x07, 0x50,
-0x24, 0xC0, 0x38, 0x00, 0x93, 0x02, 0x44, 0x0B, 0xB0, 0x05, 0xC0, 0x73, 0x00,
-0xD9, 0x02, 0x44, 0x0B, 0x10, 0x2C, 0xC0, 0xB6, 0x00, 0xCB, 0x00, 0x0C, 0x69,
-0xF1, 0x2D, 0x41, 0x67, 0x00, 0xDF, 0x03, 0x4D, 0x07, 0xF0, 0xBD, 0xD0, 0x74,
-0x40, 0xD3, 0x00, 0x3C, 0x05, 0x30, 0x0D, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x06, 0x9F, 0x10, 0x5C, 0x23, 0x70, 0x1D,
-0xC0, 0x77, 0x00, 0x9F, 0x03, 0x7C, 0x02, 0x71, 0x85, 0xC0, 0x37, 0x22, 0x97,
-0x02, 0x7C, 0x01, 0xF0, 0x3D, 0xC0, 0x25, 0x00, 0x97, 0x08, 0x7C, 0x01, 0xF0,
-0x05, 0xC1, 0x63, 0x00, 0xDF, 0x81, 0x7C, 0x06, 0xF0, 0x1D, 0xC2, 0x77, 0x14,
-0xDF, 0x03, 0x7C, 0x01, 0xF0, 0x8D, 0xC2, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0x7F, 0x00, 0xCC, 0x0F, 0xF0, 0x07, 0xC0,
-0x3E, 0x00, 0xB3, 0x00, 0xFC, 0x17, 0x32, 0x03, 0xC5, 0x2C, 0x00, 0x73, 0x00,
-0xCE, 0x02, 0x30, 0x13, 0xC0, 0x1C, 0x01, 0x72, 0x00, 0xCC, 0x01, 0x30, 0x0B,
-0xC0, 0x0F, 0x02, 0x73, 0x00, 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0xFF,
-0x00, 0xCC, 0x01, 0x30, 0x0F, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x81, 0x20, 0x36, 0x00, 0x1D, 0x00, 0x44, 0x03, 0xD0, 0x05, 0x40, 0x34,
-0x20, 0x91, 0x09, 0x74, 0x04, 0x10, 0x10, 0x41, 0x24, 0x00, 0x11, 0x02, 0x44,
-0x00, 0x10, 0x11, 0x40, 0xC4, 0x01, 0x11, 0x00, 0x44, 0x09, 0x10, 0x01, 0xC0,
-0x05, 0x00, 0x51, 0x20, 0x74, 0x00, 0xD0, 0x05, 0x40, 0x17, 0x10, 0xDD, 0x00,
-0x44, 0x05, 0x10, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0xA0, 0x36, 0x00, 0xDD, 0x04, 0x44, 0x02, 0xD8, 0x85, 0x40, 0x36, 0x00,
-0x91, 0x02, 0x14, 0x01, 0x18, 0x15, 0x40, 0x34, 0x81, 0xC9, 0x06, 0x04, 0x03,
-0x10, 0x6D, 0x40, 0x32, 0x80, 0xD5, 0x00, 0x44, 0x00, 0x10, 0x0D, 0x40, 0x27,
-0x00, 0x91, 0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x86, 0x44,
-0x04, 0x10, 0x1D, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x00, 0x30, 0x00, 0x8D, 0x00, 0x05, 0x02, 0xD0, 0x0C, 0x40, 0x36, 0x00, 0x81,
-0x00, 0x34, 0x02, 0x14, 0x0D, 0x50, 0x34, 0x00, 0x80, 0x00, 0x05, 0x02, 0x14,
-0x0D, 0x60, 0x22, 0x40, 0x95, 0xA0, 0x04, 0x00, 0x10, 0x04, 0x40, 0x23, 0x40,
-0x81, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x04, 0x04,
-0x14, 0x0C, 0x40, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x36, 0x00, 0x5F, 0x00, 0x4C, 0x03, 0xF0, 0x05, 0xC0, 0x36, 0x00, 0x93, 0x00,
-0x7C, 0x01, 0x30, 0x01, 0xC0, 0x24, 0x10, 0x5B, 0x80, 0x46, 0x81, 0x30, 0x01,
-0xC0, 0x16, 0x00, 0x57, 0x00, 0x4C, 0x00, 0x30, 0x09, 0xC0, 0x07, 0x00, 0x13,
-0x00, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x4D, 0x00, 0x30,
-0x0D, 0xC0, 0x03, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F,
-0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x06, 0xC0, 0x39, 0x00, 0xAF, 0x80, 0xFC,
-0x00, 0xF0, 0x0B, 0xC0, 0x2B, 0x80, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x02, 0xC0,
-0x0D, 0x00, 0x2B, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3F, 0x00,
-0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0xF0, 0x0F,
-0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x2F, 0x00,
-0xFF, 0x01, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x5D, 0x00, 0x6F, 0x01, 0xCC, 0x06,
-0xF1, 0x0F, 0xC0, 0x7C, 0x00, 0x33, 0x03, 0xEC, 0x24, 0xB2, 0xCF, 0xC8, 0x3C,
-0x21, 0xFB, 0x84, 0xDC, 0x87, 0xB0, 0x0F, 0x40, 0x5C, 0x02, 0x3F, 0x08, 0xAC,
-0x85, 0xB0, 0x0F, 0xC2, 0x5F, 0x00, 0x37, 0x80, 0xCD, 0x06, 0x90, 0x0B, 0x80,
-0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0xDD,
-0x01, 0x74, 0x00, 0xD0, 0x3D, 0x42, 0x60, 0x00, 0x1D, 0x01, 0x44, 0x06, 0xD2,
-0x1D, 0x40, 0x7C, 0x00, 0x11, 0x20, 0x44, 0x10, 0x10, 0xAF, 0x40, 0x7C, 0x02,
-0xF1, 0x02, 0x44, 0x07, 0x14, 0x6D, 0x40, 0x04, 0x01, 0x9D, 0x04, 0x54, 0x85,
-0x10, 0x9F, 0x00, 0x47, 0x40, 0x93, 0x8B, 0x44, 0x52, 0x10, 0x09, 0x40, 0x0D,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0xCD, 0x00,
-0x34, 0x00, 0xD0, 0x2C, 0x40, 0x31, 0x00, 0x4D, 0x00, 0x04, 0x02, 0xD0, 0x0C,
-0x60, 0x30, 0x20, 0x10, 0x04, 0x64, 0x10, 0x90, 0x4C, 0x48, 0x30, 0x10, 0xC9,
-0x08, 0x34, 0x03, 0x02, 0x2C, 0x45, 0x12, 0x01, 0x0D, 0x00, 0x24, 0x01, 0xD0,
-0x0C, 0x42, 0x33, 0x10, 0x09, 0x20, 0x04, 0x03, 0x10, 0x00, 0x40, 0x4D, 0x80,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x64, 0x00, 0xDD, 0x00, 0x74,
-0x04, 0xC0, 0x0D, 0x60, 0x24, 0x00, 0x1D, 0x04, 0x45, 0x02, 0xD0, 0x0D, 0x40,
-0x34, 0x08, 0x11, 0x00, 0x64, 0x44, 0x10, 0x0D, 0x48, 0x34, 0x80, 0xD1, 0x00,
-0x64, 0x03, 0x50, 0x0D, 0x40, 0x06, 0x04, 0x8D, 0x11, 0x74, 0x85, 0x54, 0x0D,
-0x42, 0x07, 0x00, 0x55, 0x08, 0x44, 0x02, 0x10, 0x11, 0x41, 0x0D, 0x20, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x66, 0x00, 0xDF, 0x00, 0x78, 0x4E,
-0xE0, 0x0D, 0xC0, 0x25, 0x10, 0x4F, 0x07, 0x4C, 0x22, 0xF0, 0x9D, 0x40, 0x34,
-0x40, 0x13, 0x0D, 0x2C, 0x0C, 0xB2, 0x0D, 0xD0, 0x34, 0x10, 0xDB, 0x00, 0x74,
-0x03, 0x30, 0x0D, 0x50, 0x06, 0x28, 0x9E, 0x01, 0x6C, 0x14, 0xF0, 0x0D, 0xC0,
-0x13, 0x00, 0x1B, 0x03, 0x4C, 0x06, 0x30, 0x19, 0xC0, 0x21, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0,
-0x0E, 0xC0, 0x2F, 0x00, 0x7F, 0x00, 0xFC, 0x06, 0xF0, 0x0E, 0xC0, 0x3F, 0x00,
-0xFF, 0x00, 0xDC, 0x02, 0x70, 0x0E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xDC, 0x03,
-0xB0, 0x0F, 0xC2, 0x0D, 0x10, 0xBD, 0x00, 0xDC, 0x01, 0xB4, 0x0F, 0xC0, 0x8F,
-0x50, 0x6B, 0x00, 0xFC, 0x26, 0xF4, 0x0A, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x08, 0x85, 0x02, 0xDF, 0x00, 0x7C, 0x40, 0x30, 0x0D,
-0xC0, 0x37, 0x00, 0x57, 0x02, 0x4C, 0x42, 0xF0, 0x0D, 0xC0, 0x37, 0x02, 0xDF,
-0x00, 0x7C, 0x0A, 0xF0, 0x0D, 0xC4, 0x34, 0x0A, 0xDF, 0x00, 0x5C, 0x23, 0x70,
-0x0D, 0xC1, 0x15, 0x00, 0x13, 0x02, 0x4C, 0x00, 0x50, 0x0D, 0xC9, 0x36, 0x08,
-0x17, 0x12, 0x4D, 0x03, 0xF0, 0x09, 0x82, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD, 0x60, 0x70, 0x18, 0x10, 0x0F, 0x40,
-0x27, 0x00, 0x51, 0x05, 0x44, 0x4E, 0xD0, 0x0D, 0x40, 0x33, 0x00, 0xCD, 0x00,
-0x74, 0x02, 0xD0, 0xAF, 0x40, 0x38, 0x02, 0xFD, 0x00, 0x34, 0x2B, 0xB0, 0x2E,
-0x40, 0x04, 0x40, 0x11, 0x08, 0x2C, 0x03, 0x10, 0x2F, 0x48, 0x04, 0x02, 0x51,
-0x00, 0x44, 0x13, 0xD0, 0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x20, 0xC0, 0x04, 0xCD, 0x00, 0x34, 0x0E, 0x50, 0x0C, 0x40, 0x13,
-0x00, 0x05, 0x06, 0x05, 0x0E, 0xD0, 0x08, 0x40, 0xF3, 0x04, 0x0D, 0x00, 0x34,
-0x00, 0xD0, 0x0C, 0x60, 0x70, 0x00, 0xCD, 0x07, 0x34, 0x03, 0x10, 0x0C, 0x48,
-0x11, 0x80, 0x04, 0x00, 0x04, 0x00, 0x40, 0x3C, 0x40, 0x90, 0x00, 0x49, 0x02,
-0x44, 0x13, 0xD1, 0x50, 0x44, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x00, 0x58, 0x00, 0xED, 0x01, 0xB4, 0x01, 0x50, 0x1E, 0x40, 0x6B, 0x00,
-0x31, 0x01, 0x84, 0x06, 0xD0, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07,
-0xD0, 0x1C, 0x40, 0x78, 0x00, 0xED, 0x31, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x48,
-0x80, 0xE5, 0x01, 0xE4, 0x04, 0x10, 0x9C, 0x40, 0x4C, 0x01, 0xC9, 0x01, 0x84,
-0x16, 0xD8, 0x9A, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x1A, 0x90, 0x02, 0xCF, 0x00, 0x7C, 0x23, 0x70, 0x0C, 0xC0, 0x33, 0x00, 0x07,
-0x04, 0x0C, 0x02, 0xF0, 0x4C, 0xC0, 0x33, 0x01, 0xCD, 0x00, 0x3C, 0x02, 0xF0,
-0x8C, 0x40, 0x30, 0x02, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0xDD, 0xC0, 0x15, 0x2A,
-0x57, 0x24, 0x0C, 0x61, 0x70, 0x8C, 0xC9, 0x22, 0x90, 0x89, 0x12, 0x0C, 0x03,
-0xF0, 0x00, 0xC1, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38,
-0x3D, 0x08, 0xFF, 0x00, 0xFC, 0x13, 0xB0, 0x0F, 0xC1, 0x2F, 0x00, 0x3F, 0x00,
-0xFC, 0x22, 0xF0, 0x0F, 0xC0, 0x77, 0x00, 0xDF, 0x08, 0xFC, 0x23, 0xF0, 0x2D,
-0x52, 0x3F, 0x20, 0xDF, 0x00, 0x3C, 0x03, 0xF4, 0x0D, 0xC0, 0x07, 0x20, 0xDB,
-0x00, 0x7C, 0x81, 0xF0, 0x8F, 0xC2, 0x0B, 0x81, 0xF7, 0x00, 0xF0, 0x12, 0xF0,
-0x03, 0xC2, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
-0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x1F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x1F, 0x00, 0x6C, 0x01, 0xF0, 0x0D, 0xC0,
-0xB7, 0x00, 0xDF, 0x08, 0x3C, 0x03, 0x31, 0x1D, 0xC8, 0x07, 0x10, 0x9F, 0x00,
-0x4F, 0x00, 0xF0, 0x4D, 0xC8, 0x10, 0x08, 0x9B, 0x00, 0x4D, 0x83, 0x30, 0x01,
-0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00,
-0xED, 0x00, 0xB4, 0x03, 0xD3, 0x4E, 0x40, 0x2B, 0x00, 0x2D, 0x00, 0x9C, 0x02,
-0xD0, 0x0A, 0x60, 0xBB, 0x10, 0xFC, 0x00, 0x84, 0x03, 0xD0, 0x4E, 0x40, 0xBB,
-0x04, 0xED, 0x0C, 0xB4, 0x03, 0x40, 0x2E, 0x40, 0x0B, 0x00, 0xED, 0x20, 0x84,
-0x00, 0xD0, 0xAE, 0x40, 0x08, 0x00, 0xE7, 0x00, 0xC4, 0x83, 0x12, 0x0F, 0x40,
-0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x59, 0x18, 0xE5,
-0x01, 0xB4, 0x07, 0x50, 0x5E, 0x40, 0x7B, 0x00, 0x2D, 0x01, 0xB4, 0x06, 0x50,
-0x1E, 0x40, 0x7B, 0x01, 0xED, 0x11, 0x84, 0x07, 0xD0, 0xDE, 0x40, 0x7B, 0x01,
-0xED, 0x81, 0xB4, 0x07, 0x00, 0x4E, 0x40, 0x5B, 0x20, 0xED, 0x01, 0x94, 0x04,
-0xD1, 0x5C, 0x50, 0x69, 0x00, 0x85, 0x01, 0x94, 0x0F, 0x10, 0x16, 0x40, 0x12,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x80, 0xCD, 0x40,
-0x34, 0x27, 0xD0, 0x0C, 0x40, 0x23, 0x11, 0x8D, 0x03, 0x14, 0x07, 0xD0, 0x0C,
-0x40, 0x33, 0x00, 0xCD, 0x01, 0x04, 0x47, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
-0x00, 0x34, 0x83, 0x00, 0x0C, 0x44, 0xA3, 0x02, 0xDD, 0x02, 0x04, 0x05, 0xD0,
-0x0C, 0x44, 0x01, 0x00, 0xC5, 0x07, 0x14, 0x87, 0x10, 0x6C, 0x40, 0x5A, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x1D, 0x04, 0x5F, 0x00, 0xFC,
-0x09, 0xF0, 0x05, 0xC0, 0xDF, 0x01, 0x7F, 0x44, 0x74, 0x45, 0xF8, 0x05, 0xC0,
-0x17, 0x00, 0x7F, 0x02, 0xCD, 0x95, 0xF0, 0x05, 0x40, 0x17, 0x00, 0x5F, 0x80,
-0x3C, 0x01, 0x31, 0x05, 0xC0, 0x5F, 0x00, 0x7F, 0x02, 0x8C, 0xBD, 0xF1, 0x05,
-0xC0, 0x1D, 0x00, 0x67, 0x07, 0x5C, 0x01, 0x36, 0x27, 0xC4, 0x5E, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x04, 0x1F, 0x00, 0x7C, 0x80,
-0xF0, 0x01, 0xC0, 0x07, 0x08, 0x1F, 0x10, 0x70, 0x00, 0xF9, 0x01, 0xC4, 0x07,
-0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x42, 0x7C,
-0x08, 0xF4, 0x01, 0xC0, 0x07, 0x01, 0x1D, 0x82, 0x7C, 0x00, 0xF0, 0x01, 0xA0,
-0x86, 0x00, 0x16, 0x00, 0x68, 0x08, 0xF2, 0x01, 0xD0, 0x49, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x01, 0x97, 0x00, 0x7C, 0x4E, 0xF8,
-0x09, 0xC0, 0x27, 0x00, 0x93, 0x82, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x27, 0x89,
-0x93, 0x80, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x64, 0x00, 0x9F, 0x00, 0x7C, 0x16,
-0x30, 0x08, 0xC0, 0x24, 0x00, 0x9F, 0x39, 0x4C, 0x02, 0x34, 0x29, 0xD8, 0x24,
-0x40, 0x91, 0x09, 0x4C, 0x0E, 0x34, 0x08, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x01, 0x9D, 0x00, 0x74, 0x0E, 0xD0, 0x09,
-0x60, 0x23, 0x20, 0x91, 0x03, 0x76, 0x06, 0xD0, 0x09, 0x40, 0xEB, 0x81, 0x8B,
-0x00, 0x6C, 0x02, 0x50, 0x19, 0xD0, 0x64, 0x12, 0x9D, 0x02, 0x74, 0x02, 0xB0,
-0x09, 0xC0, 0x26, 0x00, 0x9D, 0x43, 0x45, 0x2E, 0x10, 0x38, 0x48, 0xA0, 0x11,
-0x91, 0x01, 0x44, 0x02, 0x12, 0x29, 0x40, 0x05, 0x80, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x24, 0x18, 0x9D, 0x00, 0x54, 0x0A, 0xD0, 0x09, 0x40,
-0x27, 0x00, 0x91, 0x10, 0x74, 0x0E, 0xD1, 0x09, 0x48, 0x25, 0x80, 0x91, 0x00,
-0x14, 0x02, 0x10, 0x88, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x54, 0x0A, 0x90, 0x09,
-0x44, 0x24, 0x00, 0x9D, 0x02, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x95,
-0x02, 0x25, 0x02, 0x10, 0x49, 0x60, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x22, 0x20, 0x05, 0x8D, 0x00, 0x34, 0x52, 0xD0, 0x08, 0x40, 0xA7,
-0x08, 0x81, 0x00, 0x36, 0x02, 0xDA, 0x08, 0x40, 0x23, 0x00, 0x91, 0x08, 0x04,
-0x22, 0x10, 0x8C, 0x60, 0x22, 0x80, 0x8D, 0x24, 0x34, 0x02, 0x94, 0x58, 0x40,
-0x22, 0x00, 0x8D, 0x0C, 0x44, 0x03, 0x10, 0x0C, 0x40, 0x24, 0x00, 0x85, 0x00,
-0x24, 0x22, 0x10, 0x48, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1D, 0xB8, 0x06, 0x11, 0x1F, 0x00, 0x5C, 0x10, 0xD0, 0x41, 0x41, 0x07, 0x40,
-0x13, 0x00, 0x76, 0x00, 0xF0, 0x01, 0xC0, 0x47, 0x40, 0x11, 0x02, 0x54, 0x08,
-0x34, 0x61, 0xC1, 0x14, 0x15, 0x1F, 0x8A, 0x7C, 0x00, 0xB4, 0xA1, 0xC4, 0x84,
-0x02, 0x0F, 0x02, 0x4C, 0x00, 0x30, 0x41, 0xC1, 0x04, 0x00, 0x15, 0x14, 0x6C,
-0x09, 0x30, 0xA5, 0xC0, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xB8, 0x2F, 0x05, 0x9F, 0x00, 0xFC, 0x52, 0xF0, 0x09, 0xC0, 0x6F, 0x20, 0xBF,
-0x00, 0xFC, 0x02, 0xF0, 0x2B, 0xC0, 0xA7, 0x00, 0xBF, 0x04, 0xFC, 0x12, 0xF0,
-0x49, 0x42, 0x25, 0x00, 0x9F, 0x08, 0x7C, 0x02, 0xF4, 0x89, 0xC0, 0x2D, 0x00,
-0xBF, 0x0C, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x3F, 0x00, 0xBB, 0x00, 0xDC, 0x12,
-0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8,
-0x2F, 0x01, 0x9F, 0x00, 0xFC, 0x32, 0xB0, 0x09, 0xC0, 0xA7, 0x20, 0xBF, 0x00,
-0xCD, 0x02, 0xF0, 0x49, 0xC5, 0x6F, 0x00, 0x9B, 0x80, 0x6E, 0x02, 0x79, 0x8B,
-0xC0, 0x2F, 0x01, 0xBB, 0x14, 0xAC, 0x82, 0x30, 0x0B, 0xCC, 0x21, 0x00, 0xBF,
-0x28, 0xCC, 0x82, 0x31, 0x4B, 0xC1, 0x2E, 0x68, 0xA3, 0x00, 0xBC, 0x02, 0xF0,
-0x0F, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07,
-0x05, 0x1D, 0x00, 0x70, 0x31, 0x14, 0x21, 0x40, 0x47, 0x00, 0x1D, 0x00, 0x44,
-0x00, 0xD0, 0x01, 0x00, 0x07, 0x00, 0x5A, 0x30, 0x44, 0xC0, 0xD8, 0x81, 0x40,
-0x07, 0x00, 0x11, 0x04, 0x51, 0x00, 0x10, 0x01, 0xC0, 0x05, 0x04, 0x5D, 0x08,
-0x4C, 0x00, 0x11, 0x01, 0x40, 0x07, 0x30, 0x11, 0x00, 0x64, 0x80, 0xD0, 0x01,
-0x40, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x03,
-0x8D, 0x00, 0x34, 0x12, 0x10, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x80, 0x04, 0x82,
-0xD2, 0x08, 0x0A, 0xA3, 0x00, 0x89, 0x04, 0x04, 0x02, 0x50, 0x08, 0x40, 0x23,
-0x02, 0x89, 0x14, 0x14, 0x02, 0x14, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x05,
-0x02, 0x18, 0x08, 0x48, 0x27, 0x20, 0x85, 0x00, 0x36, 0x02, 0xD0, 0x08, 0x40,
-0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0xA5, 0x00, 0x9D,
-0x00, 0x74, 0x12, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x10, 0x44, 0x02, 0xD0,
-0x09, 0x48, 0x26, 0x20, 0x89, 0x00, 0x44, 0x02, 0xD8, 0x09, 0x40, 0x27, 0x00,
-0x91, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x68, 0x25, 0x10, 0x9D, 0x04, 0x46, 0x02,
-0x99, 0x0D, 0x40, 0x27, 0x00, 0xD5, 0x00, 0x64, 0x22, 0xD0, 0x09, 0x41, 0x63,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x65, 0x00, 0x9D, 0x00,
-0x7C, 0x06, 0x30, 0x09, 0xC0, 0x2F, 0x06, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x9B, 0x02, 0x65, 0x42, 0x72, 0x09, 0xC2, 0x27, 0x00, 0x9B,
-0x00, 0x54, 0x02, 0x30, 0x09, 0xC0, 0x25, 0x33, 0x9F, 0x21, 0x4C, 0x46, 0x30,
-0x09, 0xC0, 0x22, 0x00, 0x95, 0xA7, 0x7E, 0x82, 0xE0, 0x39, 0xC0, 0x17, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x25, 0x25, 0x9F, 0x80, 0x3C,
-0x06, 0x70, 0x09, 0xE2, 0x27, 0x00, 0x9F, 0x10, 0x7C, 0x26, 0xF0, 0x59, 0xC0,
-0x27, 0x0C, 0x97, 0x02, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x50,
-0x5C, 0x02, 0x32, 0x09, 0xE8, 0x27, 0x10, 0x8F, 0x01, 0x5C, 0x0A, 0x74, 0x09,
-0xC1, 0xA6, 0x00, 0x9B, 0x05, 0x7E, 0x02, 0xF0, 0x59, 0xC0, 0x5B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x6C, 0x40,
-0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x80, 0xB0, 0x01, 0xC0, 0x03,
-0x00, 0x17, 0x02, 0x7C, 0x08, 0xF0, 0x01, 0xC2, 0x00, 0x01, 0x1F, 0x00, 0x4C,
-0x00, 0xB0, 0x81, 0xC1, 0x07, 0x40, 0x17, 0x22, 0x5C, 0x10, 0xF0, 0x01, 0xC0,
-0x07, 0x00, 0x13, 0x02, 0x4C, 0x40, 0x30, 0x01, 0x82, 0x53, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x9C, 0x00, 0x5D, 0x40, 0xF4, 0x05, 0xD8,
-0x05, 0xC0, 0x15, 0x20, 0x6C, 0x00, 0xF4, 0x49, 0x10, 0x05, 0x40, 0x9F, 0x80,
-0x5B, 0x00, 0x76, 0x01, 0xD0, 0x87, 0x40, 0x9C, 0x00, 0x7D, 0x02, 0x84, 0x01,
-0xF4, 0x27, 0xC0, 0x15, 0x00, 0x71, 0x00, 0x84, 0x89, 0x10, 0x77, 0x40, 0xDF,
-0x00, 0x70, 0x07, 0xC4, 0x01, 0x16, 0x97, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA8, 0xF2, 0x00, 0xCD, 0x00, 0x34, 0x23, 0xD0, 0x0C,
-0x48, 0x31, 0x00, 0x88, 0x02, 0x36, 0x1F, 0x90, 0x0C, 0x40, 0x13, 0x10, 0xC5,
-0x00, 0x34, 0x03, 0x90, 0x3C, 0x60, 0xB0, 0x00, 0xD5, 0x0B, 0x00, 0x03, 0x91,
-0x3C, 0x44, 0x31, 0x00, 0xC1, 0x01, 0x34, 0x0A, 0x50, 0x14, 0x40, 0xF2, 0x01,
-0xC1, 0x07, 0x24, 0x0B, 0x12, 0x8C, 0x44, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x80, 0x38, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40,
-0x39, 0x01, 0x6D, 0x10, 0xB4, 0x04, 0x18, 0x0E, 0x40, 0x1B, 0x00, 0xE1, 0x44,
-0xB4, 0x03, 0xD0, 0x36, 0x40, 0x38, 0x00, 0xED, 0x00, 0x85, 0x03, 0xD4, 0x06,
-0x60, 0x7D, 0x02, 0xE1, 0x02, 0xE6, 0x02, 0x10, 0x06, 0x40, 0xBB, 0x20, 0xE1,
-0x61, 0xE5, 0x8F, 0x50, 0x06, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x05, 0xD0, 0x1E, 0xC0, 0xF9,
-0x00, 0x2B, 0x01, 0xBC, 0x04, 0xB1, 0x1E, 0xC0, 0x73, 0x00, 0xE5, 0x35, 0xB4,
-0x2F, 0xB0, 0x1F, 0xD0, 0x78, 0x00, 0xCF, 0x41, 0x8C, 0x05, 0xB4, 0x16, 0xC0,
-0x79, 0x03, 0xF3, 0x01, 0xBD, 0x04, 0x70, 0x16, 0xC0, 0x7B, 0x40, 0x23, 0x01,
-0xAC, 0x07, 0x31, 0x1E, 0xC4, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0xFC, 0x01, 0xF0, 0x0D, 0xC0, 0x35, 0x00,
-0x1E, 0x00, 0x3C, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0xDF, 0x4A, 0x7C, 0x1B,
-0xF0, 0x05, 0xC8, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF6, 0x05, 0xC6, 0xB5,
-0x01, 0x5E, 0x00, 0x1C, 0x00, 0x50, 0x05, 0xC0, 0x33, 0x00, 0x1F, 0x00, 0x5C,
-0x03, 0xB0, 0x09, 0xC8, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-0x20, 0x5D, 0x00, 0xF3, 0x01, 0xFC, 0x27, 0xF8, 0x8F, 0xC0, 0x7B, 0x00, 0x3B,
-0x01, 0xFC, 0x04, 0x70, 0x1F, 0xC0, 0x5F, 0x00, 0xFF, 0x09, 0xFE, 0x27, 0xB0,
-0x1B, 0xC0, 0x76, 0x00, 0xFF, 0x01, 0x8C, 0x07, 0x30, 0x93, 0xC4, 0x7F, 0x00,
-0xB3, 0x01, 0xCC, 0x16, 0xF8, 0x97, 0xC0, 0x7B, 0x00, 0xFB, 0x41, 0xF8, 0x04,
-0x34, 0x9B, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00,
-0x19, 0x22, 0xE1, 0x40, 0xB4, 0x81, 0x78, 0x0E, 0x42, 0x3B, 0x00, 0x61, 0x00,
-0xB4, 0x00, 0xD0, 0x0E, 0x44, 0x1B, 0x21, 0xE6, 0x08, 0xF4, 0x23, 0x14, 0x0A,
-0x40, 0x78, 0x00, 0xBD, 0x00, 0x84, 0x23, 0xF0, 0x00, 0x40, 0x3B, 0x01, 0xA1,
-0x24, 0xAC, 0x12, 0xB0, 0x06, 0xC0, 0x3B, 0x06, 0xE1, 0x08, 0xB4, 0x20, 0xB0,
-0x03, 0x48, 0x55, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
-0x04, 0xE1, 0x00, 0xB4, 0x03, 0x58, 0x8E, 0x40, 0x7F, 0x04, 0x21, 0x00, 0xB4,
-0x00, 0x50, 0x0E, 0x40, 0x19, 0x08, 0xEC, 0x42, 0xB4, 0x03, 0x10, 0x02, 0x40,
-0x38, 0x00, 0x6D, 0x00, 0xA4, 0x01, 0x10, 0x02, 0x60, 0x39, 0x24, 0xE1, 0x80,
-0xB4, 0x72, 0x1C, 0x06, 0x46, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x40, 0x50, 0x0A,
-0x42, 0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x25, 0x00,
-0xC1, 0x20, 0x34, 0x08, 0x58, 0x0C, 0x40, 0xF3, 0x00, 0x49, 0x11, 0x34, 0x20,
-0xD8, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0x90, 0x01, 0x40, 0x02,
-0x80, 0x0D, 0x00, 0x24, 0x01, 0x90, 0x00, 0x40, 0xF3, 0x00, 0x41, 0x01, 0x34,
-0x06, 0x90, 0x04, 0x40, 0xF1, 0x00, 0xC1, 0x00, 0x36, 0x04, 0x18, 0x39, 0x40,
-0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0xA5, 0x40, 0xD3,
-0x00, 0x7C, 0x6E, 0x70, 0x0D, 0x40, 0xF7, 0x40, 0x0B, 0x07, 0x7C, 0x00, 0x70,
-0x0D, 0xC2, 0x15, 0x00, 0xFF, 0x01, 0xF4, 0x4F, 0x30, 0x0D, 0xC0, 0x24, 0x00,
-0x1F, 0x00, 0x24, 0x02, 0x30, 0x01, 0xC0, 0xF9, 0x00, 0x53, 0xA3, 0x3C, 0x02,
-0x30, 0x04, 0x40, 0x77, 0x08, 0xDF, 0x25, 0x7C, 0x07, 0x50, 0x61, 0xC0, 0x54,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x11, 0xDF, 0x00,
-0x7C, 0x0A, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0x57, 0x02, 0x7C, 0x00, 0xF0, 0x0D,
-0xC0, 0x17, 0x00, 0xD7, 0x08, 0x7C, 0x43, 0x70, 0x05, 0xD8, 0x25, 0x10, 0x9F,
-0x00, 0x5C, 0x02, 0xF0, 0x21, 0xC0, 0x37, 0x04, 0xDF, 0x08, 0x68, 0x0A, 0xF9,
-0x25, 0x80, 0x37, 0x01, 0x0E, 0x10, 0x7C, 0x0B, 0xF2, 0x21, 0xC0, 0xB7, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x07, 0x00, 0xF3, 0x00, 0xFC,
-0x00, 0xF0, 0x0E, 0xC0, 0x3E, 0x04, 0x33, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0,
-0x7F, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0x70, 0x2B, 0xC0, 0x2B, 0x00, 0x3B, 0x20,
-0xFC, 0x00, 0xB0, 0x03, 0xC0, 0x3F, 0x00, 0x23, 0x11, 0xCC, 0x42, 0x76, 0x87,
-0xC0, 0x3C, 0x00, 0x3F, 0x02, 0xC4, 0x07, 0xF0, 0x03, 0xC1, 0x04, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66, 0x08, 0xD1, 0x40, 0x76, 0x04,
-0xD0, 0x0D, 0x48, 0x35, 0x00, 0x11, 0x00, 0x44, 0x14, 0xD0, 0x0D, 0xC0, 0x27,
-0x80, 0xDD, 0x80, 0x7C, 0x03, 0xD0, 0x11, 0x40, 0xC4, 0x44, 0x91, 0x21, 0x7C,
-0x07, 0xB0, 0x51, 0x40, 0x37, 0x00, 0x11, 0x0B, 0x44, 0x07, 0x10, 0x0D, 0x48,
-0xF0, 0x00, 0x11, 0x03, 0x44, 0x00, 0xD2, 0x31, 0x40, 0x04, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0xA2, 0x46, 0x04, 0xD1, 0x00, 0x74, 0x0E, 0xD0,
-0x0D, 0x40, 0x30, 0x00, 0x11, 0x30, 0x64, 0x04, 0xD0, 0x0D, 0x48, 0x17, 0x01,
-0xDD, 0x00, 0x74, 0x03, 0xD2, 0x0D, 0x40, 0x44, 0x00, 0x91, 0x83, 0x76, 0x46,
-0x90, 0x11, 0x40, 0x37, 0x00, 0x11, 0x02, 0x46, 0x0E, 0x50, 0x05, 0x40, 0x64,
-0x44, 0xD1, 0x20, 0x54, 0x18, 0xD2, 0x39, 0x40, 0x04, 0x08, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x0C,
-0x40, 0x31, 0x00, 0x51, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x11, 0x00, 0xCD,
-0x00, 0x34, 0x03, 0xD0, 0x0C, 0x70, 0x00, 0x01, 0x81, 0x00, 0x34, 0x02, 0x99,
-0x00, 0x40, 0x37, 0x00, 0x81, 0x20, 0x04, 0x02, 0x10, 0x04, 0x40, 0x24, 0x00,
-0x01, 0x00, 0x14, 0x03, 0xD0, 0x00, 0x52, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0xF0, 0x0D, 0x40,
-0x3C, 0x80, 0x13, 0x00, 0x6C, 0x00, 0xF0, 0x0D, 0x60, 0x17, 0x00, 0xFD, 0x00,
-0xEC, 0x03, 0xF8, 0x00, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xB0, 0x81,
-0xC0, 0x3B, 0x40, 0x03, 0x00, 0x4C, 0x02, 0x70, 0x01, 0xC0, 0x24, 0x10, 0xD3,
-0x00, 0x1C, 0x00, 0xF0, 0x09, 0xC4, 0x04, 0x64, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC2, 0x3D,
-0x40, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC,
-0x03, 0xF0, 0x03, 0x00, 0x0F, 0x2A, 0x3F, 0x00, 0xDC, 0x03, 0x70, 0x03, 0xC0,
-0x3F, 0x00, 0x3F, 0x00, 0xBC, 0x03, 0xF0, 0x07, 0x40, 0x0F, 0x40, 0x37, 0x00,
-0xEC, 0x00, 0xF0, 0x0B, 0xC8, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA8, 0x7F, 0x00, 0x3E, 0x00, 0xFC, 0x04, 0x30, 0x1F, 0xC0, 0x2C, 0x00,
-0xBF, 0x24, 0xCC, 0x03, 0xF0, 0x43, 0xC1, 0x3D, 0x21, 0x3F, 0xA0, 0xDC, 0x13,
-0x30, 0x9E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0x98, 0x17, 0xF0, 0x1F, 0xC0, 0x4C,
-0x00, 0xFF, 0x03, 0xFC, 0x07, 0xF0, 0x4F, 0xC0, 0x7E, 0x02, 0xFF, 0x00, 0xCC,
-0x03, 0x30, 0x83, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x10, 0x36, 0x05, 0x1D, 0x02, 0x44, 0x00, 0x10, 0x0D, 0x50, 0x24, 0x08, 0x9D,
-0x08, 0xC4, 0x2B, 0x10, 0x39, 0x44, 0x7C, 0x02, 0x9D, 0x01, 0xC4, 0x23, 0x11,
-0x1D, 0x40, 0xFF, 0x01, 0x5D, 0x01, 0xC4, 0x0F, 0xD0, 0x0D, 0x40, 0x44, 0x00,
-0xDD, 0x00, 0x5C, 0x07, 0xD0, 0xBF, 0x40, 0x34, 0x01, 0xF7, 0x03, 0xC4, 0x2F,
-0x10, 0x09, 0x40, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0,
-0x33, 0x00, 0x0D, 0x03, 0x54, 0x00, 0x90, 0x0C, 0x40, 0x21, 0x00, 0x8D, 0x00,
-0x04, 0x83, 0x10, 0x01, 0x60, 0x30, 0x08, 0x05, 0x00, 0x24, 0x03, 0x10, 0x4C,
-0x40, 0x32, 0x06, 0x89, 0x00, 0x05, 0x23, 0xD2, 0x0C, 0x48, 0x00, 0x20, 0xCD,
-0x04, 0x36, 0x03, 0xD0, 0x0C, 0x40, 0x30, 0x01, 0xCD, 0x02, 0x05, 0x03, 0x14,
-0x40, 0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35,
-0x00, 0x1D, 0x01, 0x44, 0x46, 0x94, 0x0D, 0x40, 0xE5, 0x00, 0x9D, 0x20, 0x44,
-0x03, 0x10, 0x19, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x64, 0x03, 0x11, 0x0D, 0x40,
-0x37, 0x20, 0xDC, 0x10, 0x44, 0x03, 0xD0, 0x8C, 0x40, 0x44, 0x00, 0xDC, 0x00,
-0x54, 0x03, 0xD0, 0x0D, 0x40, 0x34, 0x00, 0xD5, 0x00, 0x44, 0x03, 0x10, 0x49,
-0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00,
-0x1F, 0x01, 0x7C, 0x0C, 0xB0, 0x0D, 0xC0, 0x65, 0x00, 0x9F, 0x80, 0x0C, 0x03,
-0xB4, 0x35, 0xC0, 0x35, 0x00, 0x9F, 0x01, 0x6C, 0x03, 0x34, 0x0D, 0xC2, 0x36,
-0x20, 0xDB, 0x80, 0x5C, 0x03, 0xE0, 0x1D, 0x80, 0x44, 0x04, 0x9F, 0x08, 0x7C,
-0x07, 0xF0, 0x0D, 0xC0, 0x36, 0x00, 0xDD, 0x00, 0x4C, 0x03, 0x30, 0x1D, 0xC0,
-0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0x2F,
-0x00, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x2E, 0x00, 0x9F, 0x00, 0xFD, 0x03, 0xB0,
-0x0F, 0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xDC, 0x03, 0xF0, 0x2F, 0xC6, 0x3F, 0x00,
-0x69, 0x08, 0xFC, 0x03, 0xF0, 0x1F, 0xD0, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x27,
-0xF1, 0x0E, 0xC4, 0x3F, 0x01, 0xDF, 0x00, 0xBC, 0x03, 0xF0, 0x17, 0xC8, 0x1F,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x04, 0x1F, 0x21,
-0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0xD3, 0x00, 0x4C, 0xC3, 0x30, 0x25,
-0xC0, 0x34, 0x00, 0x17, 0x00, 0x7C, 0x13, 0xF0, 0x0D, 0xD0, 0x34, 0x00, 0x9F,
-0x21, 0x6C, 0x43, 0x30, 0x0D, 0xD1, 0x44, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC2, 0x36, 0x00, 0xCF, 0x04, 0x4C, 0x13, 0xF0, 0x0D, 0xC0, 0x8B, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4, 0x00, 0x1D, 0x00, 0x34,
-0x12, 0xD0, 0xBD, 0x41, 0x27, 0x04, 0xD1, 0x00, 0xD4, 0x13, 0x10, 0x0C, 0x45,
-0x3C, 0x00, 0x1D, 0x00, 0xE4, 0x03, 0xD2, 0x0D, 0x40, 0x3C, 0x00, 0xDD, 0x00,
-0xC4, 0x07, 0x10, 0x0D, 0x40, 0x04, 0x00, 0xD1, 0x20, 0x74, 0x03, 0xD0, 0x1F,
-0x40, 0x34, 0x00, 0xFD, 0x82, 0xC4, 0x0B, 0xD0, 0x05, 0x40, 0x6F, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30, 0x00, 0x0D, 0x20, 0x34, 0x00,
-0xD0, 0x1D, 0x40, 0x33, 0x00, 0x94, 0x60, 0x24, 0x03, 0x10, 0x04, 0x40, 0x32,
-0x00, 0x0D, 0x00, 0x74, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x24,
-0x23, 0x50, 0x2C, 0x40, 0x03, 0x84, 0xC5, 0x12, 0x34, 0x03, 0xD0, 0x9C, 0x40,
-0x30, 0x00, 0xC9, 0x49, 0x24, 0x27, 0xD0, 0x05, 0x40, 0x1F, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x78, 0x00, 0x2D, 0x21, 0xB4, 0x07, 0xD0,
-0x9E, 0x40, 0x6B, 0x02, 0xA4, 0x01, 0xB4, 0x07, 0x10, 0x1F, 0x40, 0x7A, 0x00,
-0xED, 0x81, 0xA4, 0x07, 0xD0, 0x1F, 0x60, 0x7A, 0x00, 0xC9, 0x03, 0x84, 0x07,
-0x50, 0x1E, 0x40, 0x4B, 0x50, 0xE5, 0x89, 0xB4, 0x17, 0xD1, 0x1C, 0x40, 0x78,
-0x00, 0xED, 0x81, 0xA4, 0x07, 0xD0, 0x9E, 0x40, 0x37, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x8C,
-0xC0, 0x37, 0x08, 0x87, 0x00, 0x6C, 0x13, 0x30, 0x04, 0xC0, 0x32, 0x00, 0x4F,
-0x02, 0x3C, 0x23, 0xF0, 0x0C, 0xC0, 0x32, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0x70,
-0x0D, 0xC0, 0x03, 0x00, 0xC7, 0x08, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00,
-0xCB, 0x00, 0x2C, 0x03, 0xF0, 0x84, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x38, 0x3D, 0x00, 0x3F, 0x00, 0xFC, 0x23, 0xF0, 0x8F, 0xE8,
-0x3F, 0x40, 0xBB, 0x00, 0xDC, 0x03, 0xF0, 0x0E, 0xC0, 0x3D, 0x02, 0xFF, 0x00,
-0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x3D, 0x24, 0xFF, 0x00, 0xFC, 0x23, 0xB2, 0x0F,
-0xC0, 0x08, 0x02, 0xFB, 0x28, 0xFC, 0x93, 0xF0, 0x0F, 0xD0, 0x3D, 0x00, 0xFF,
-0x00, 0xDD, 0x03, 0xF2, 0x8F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xB0, 0x37, 0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF1, 0x1D, 0xC0, 0x34,
-0x00, 0x93, 0x00, 0x4C, 0x03, 0x70, 0x05, 0xC4, 0x77, 0x01, 0x9B, 0x00, 0x7C,
-0x4B, 0xE0, 0x1D, 0xC2, 0x35, 0x05, 0xCD, 0x01, 0x4C, 0x1B, 0xF0, 0x0D, 0xC0,
-0x07, 0x00, 0xDF, 0x01, 0x1C, 0x07, 0x70, 0xCD, 0xC0, 0x37, 0x20, 0xDF, 0x0A,
-0x3C, 0x4F, 0x30, 0x09, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x80, 0x39, 0x00, 0x2D, 0x00, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x1C, 0x00,
-0xA1, 0x00, 0xAC, 0x53, 0x10, 0x0E, 0x40, 0xBB, 0x04, 0xE1, 0x00, 0xB4, 0x03,
-0xD0, 0x0E, 0x40, 0x3C, 0x01, 0xE1, 0x00, 0x84, 0x53, 0xD0, 0x0E, 0x40, 0x0B,
-0x00, 0xFD, 0x00, 0x8C, 0x03, 0x10, 0x8E, 0x40, 0x3B, 0x00, 0xE7, 0x10, 0xB4,
-0x13, 0xB0, 0x00, 0xC0, 0x4E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x00, 0x79, 0x00, 0x6D, 0x01, 0x94, 0x06, 0xD0, 0x1E, 0x40, 0x78, 0x0C, 0xC1,
-0x01, 0x04, 0x27, 0x50, 0x1E, 0x40, 0x73, 0x01, 0xE1, 0x01, 0xB4, 0x27, 0x50,
-0x3E, 0x40, 0x7B, 0x00, 0xE5, 0x01, 0x85, 0x27, 0xD0, 0x1E, 0x43, 0x4B, 0x00,
-0xED, 0x01, 0x84, 0x07, 0x10, 0x5E, 0x40, 0x6B, 0x00, 0xE5, 0x25, 0xB6, 0x37,
-0x10, 0x1A, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28,
-0x33, 0x00, 0xCD, 0x01, 0x34, 0x4B, 0x50, 0x0C, 0x60, 0x70, 0x01, 0xC1, 0x01,
-0x24, 0x03, 0x10, 0x0C, 0x41, 0x33, 0x80, 0xC1, 0x10, 0x34, 0x03, 0xD0, 0x18,
-0x40, 0x32, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x09, 0x40, 0xF3, 0x00, 0xCD,
-0x01, 0x04, 0x06, 0x14, 0x0C, 0x40, 0x37, 0x10, 0xC5, 0x80, 0x36, 0x03, 0x90,
-0x41, 0x40, 0x4A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15,
-0x00, 0x7F, 0x05, 0xFC, 0x01, 0xF0, 0x05, 0xD0, 0x1C, 0x00, 0x53, 0x41, 0x4C,
-0x01, 0x70, 0x27, 0xC0, 0x17, 0x40, 0x73, 0xC2, 0x7C, 0x01, 0xF0, 0x05, 0xC0,
-0x17, 0x10, 0x7F, 0x00, 0x4C, 0x01, 0xF0, 0x15, 0xC0, 0x5F, 0x01, 0x5F, 0x01,
-0x5D, 0x15, 0x70, 0x04, 0xC2, 0x57, 0x01, 0x47, 0x00, 0x7C, 0x01, 0x30, 0x17,
-0xC1, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x85, 0x00,
-0x1F, 0x01, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x08, 0x3C, 0x00,
-0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x05,
-0x00, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x01, 0x1F, 0x08, 0x5C,
-0x00, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC8,
-0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F,
-0x05, 0x4C, 0x02, 0x36, 0x09, 0xC0, 0xA3, 0x40, 0x83, 0x05, 0x4C, 0x06, 0xB0,
-0x08, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
-0x9B, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x24, 0x20, 0x9F, 0x00, 0x7C, 0x26,
-0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9C, 0x00, 0x48, 0x02, 0xF0, 0x09, 0xC8, 0x40,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x64, 0x00, 0x9D, 0x00,
-0x44, 0x02, 0x10, 0x19, 0x40, 0x27, 0x40, 0x91, 0x01, 0x7C, 0x2A, 0x10, 0x09,
-0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0xE0, 0x27, 0x00, 0x91,
-0x10, 0x74, 0x1E, 0xD1, 0x99, 0x40, 0xA4, 0x00, 0x9D, 0x42, 0x5C, 0x02, 0xD0,
-0x09, 0xC0, 0x26, 0x00, 0x95, 0x80, 0x54, 0x1A, 0xD0, 0x09, 0xC0, 0x06, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x8D, 0x00, 0x04,
-0x02, 0x18, 0x49, 0x40, 0x27, 0x40, 0x91, 0x00, 0x44, 0x02, 0x90, 0x1D, 0x40,
-0x26, 0x00, 0x95, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x60, 0x23, 0x00, 0x99, 0x01,
-0x74, 0x12, 0xD0, 0x29, 0x40, 0x25, 0x00, 0x9D, 0x04, 0x74, 0x02, 0x50, 0x89,
-0x40, 0x24, 0x00, 0x95, 0x18, 0x54, 0x22, 0xD0, 0x09, 0x40, 0x60, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x04, 0x04, 0x02,
-0x10, 0x0C, 0x40, 0x23, 0x01, 0x81, 0x04, 0x14, 0x13, 0x10, 0x48, 0x40, 0x20,
-0x01, 0x8D, 0x04, 0x36, 0x16, 0xD1, 0x08, 0x42, 0x21, 0x01, 0x81, 0x04, 0x34,
-0x12, 0xD8, 0x08, 0x40, 0x61, 0x80, 0x8D, 0x01, 0x14, 0x02, 0xD0, 0x48, 0x40,
-0x22, 0x30, 0x85, 0x44, 0x16, 0x12, 0xD0, 0x48, 0x40, 0x42, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0x96, 0x02, 0x1F, 0x0A, 0x4D, 0x28, 0x30,
-0xA0, 0xC0, 0x87, 0x02, 0x13, 0x0A, 0x44, 0x28, 0xB0, 0x01, 0xC0, 0x06, 0x00,
-0x17, 0x10, 0x7C, 0x00, 0xF0, 0xA0, 0x40, 0x87, 0x02, 0x1B, 0x00, 0x74, 0x00,
-0xF0, 0xA1, 0xC8, 0x05, 0x00, 0x1F, 0x0A, 0x74, 0x00, 0xF0, 0x01, 0xC0, 0x84,
-0x00, 0x17, 0x00, 0x5C, 0x00, 0xF2, 0x21, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0x88, 0x27, 0x00, 0xFF, 0x08, 0xFC, 0x02, 0xF0, 0x09,
-0xC0, 0x2F, 0x02, 0xBF, 0x48, 0x7C, 0x22, 0xF0, 0x8B, 0xC4, 0x27, 0x02, 0xBF,
-0x00, 0x7C, 0x62, 0xF0, 0x0B, 0xC0, 0x27, 0x02, 0xBF, 0x08, 0x7C, 0x22, 0xF0,
-0x0B, 0xD8, 0x2E, 0x00, 0xBF, 0x40, 0xDC, 0x02, 0xF0, 0x89, 0xC2, 0x2F, 0x04,
-0x93, 0x08, 0x7C, 0x22, 0xF2, 0x8B, 0xC1, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1C, 0xA0, 0x2D, 0x00, 0xBF, 0x0C, 0xCC, 0x02, 0x30, 0x0B, 0xC0,
-0x2C, 0x02, 0xB3, 0x00, 0xFC, 0x52, 0x34, 0x4F, 0x80, 0x27, 0x00, 0x9F, 0x00,
-0xF8, 0x22, 0xF0, 0x09, 0xC0, 0x27, 0x25, 0xBF, 0x04, 0xD4, 0x02, 0x70, 0x0A,
-0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x4B, 0xC0, 0x27, 0x00, 0xA3,
-0x80, 0xBC, 0x02, 0xF0, 0x29, 0xC0, 0x61, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0x00, 0x07, 0x01, 0x0D, 0x2C, 0x44, 0x41, 0x10, 0x01, 0x41, 0x14,
-0x02, 0x01, 0x14, 0x74, 0x10, 0x13, 0x81, 0x40, 0x87, 0x00, 0x1D, 0x00, 0x74,
-0x20, 0xD0, 0x41, 0x41, 0x06, 0x01, 0x1D, 0x08, 0x44, 0x08, 0x10, 0x01, 0x41,
-0x04, 0x00, 0x1D, 0x14, 0x74, 0x00, 0xC0, 0x81, 0x44, 0x47, 0x05, 0x1B, 0x00,
-0x74, 0x20, 0xD0, 0x11, 0x40, 0x71, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x20, 0x21, 0x05, 0x8D, 0x04, 0x05, 0x12, 0x10, 0x08, 0x40, 0x20, 0x40,
-0x81, 0x04, 0x34, 0x52, 0x10, 0x08, 0x48, 0x22, 0x02, 0x88, 0x08, 0x34, 0x02,
-0xD0, 0x48, 0x40, 0x21, 0x05, 0x8D, 0x01, 0x14, 0x22, 0xD0, 0x08, 0x40, 0x61,
-0x00, 0x8D, 0x04, 0x24, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x81, 0x08, 0x34,
-0x02, 0xD0, 0x48, 0x40, 0x4B, 0x88, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x28, 0x25, 0x00, 0x9D, 0x00, 0x04, 0x02, 0x10, 0x09, 0x60, 0x24, 0x01, 0xD1,
-0x00, 0x34, 0x03, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x0A, 0x74, 0x02, 0xD0,
-0x19, 0x40, 0x24, 0x00, 0x9D, 0x08, 0x44, 0x02, 0x90, 0x08, 0x50, 0x25, 0x01,
-0x9D, 0x01, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x67, 0x00, 0x98, 0x00, 0x74, 0x02,
-0xD0, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20,
-0x25, 0x00, 0x9F, 0x02, 0x4C, 0x02, 0x30, 0x09, 0xD0, 0xE4, 0x08, 0x93, 0x01,
-0x7C, 0x02, 0x34, 0x69, 0xC8, 0x26, 0x00, 0x9B, 0x03, 0x7C, 0x02, 0xF0, 0x09,
-0xCC, 0x27, 0x00, 0x9F, 0x01, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x25, 0x00, 0x9E,
-0x00, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x90, 0x00, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25,
-0x00, 0x9F, 0x09, 0x7C, 0x02, 0xF4, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x04, 0x7C,
-0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0x7C, 0x82, 0xF0, 0x09, 0xC8,
-0x27, 0x00, 0x8F, 0x00, 0x7C, 0x42, 0x70, 0x49, 0xC0, 0x26, 0x08, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x08,
-0xC0, 0x59, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x01,
-0x1F, 0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC0, 0x84, 0x40, 0x13, 0x10, 0x4C, 0x00,
-0x30, 0x21, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xE0, 0x07,
-0x00, 0x1F, 0x00, 0x3C, 0x00, 0xB0, 0x11, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C,
-0x00, 0xF0, 0x11, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0,
-0x51, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x5C, 0x00, 0x5D,
-0x80, 0x44, 0x05, 0x30, 0x07, 0x40, 0x54, 0x40, 0x71, 0x05, 0xC6, 0x29, 0x10,
-0x05, 0x40, 0x17, 0x00, 0x5D, 0x00, 0xF4, 0x09, 0xD0, 0x05, 0xC0, 0x17, 0x00,
-0x7D, 0x0A, 0xF4, 0x01, 0x70, 0x17, 0x40, 0x9C, 0x00, 0x7D, 0x10, 0x5C, 0x01,
-0xD0, 0x17, 0x40, 0x17, 0x00, 0x71, 0x07, 0xC4, 0x19, 0x50, 0x05, 0x48, 0x50,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x72, 0x02, 0xDD, 0x00,
-0x04, 0x03, 0x50, 0x15, 0x49, 0x76, 0x20, 0xC1, 0x02, 0x24, 0x0F, 0x10, 0x0C,
-0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x37, 0xD0, 0x0D, 0x40, 0x33, 0x00, 0xCD,
-0x0B, 0x34, 0x07, 0x50, 0x9C, 0x42, 0xA0, 0x04, 0xCD, 0x05, 0x34, 0x03, 0xD0,
-0x1C, 0x40, 0x37, 0x00, 0x05, 0x04, 0x04, 0x10, 0x10, 0x0C, 0x40, 0x51, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x18, 0x00, 0xED, 0x00, 0x84,
-0x0A, 0x10, 0x2A, 0x40, 0x32, 0x24, 0xE1, 0x01, 0xA4, 0x0A, 0x10, 0x2E, 0x48,
-0x3B, 0x00, 0xED, 0x00, 0xB4, 0x83, 0xD0, 0x4E, 0x40, 0x39, 0x00, 0xAD, 0x00,
-0xB4, 0x09, 0x40, 0x0F, 0x40, 0x18, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E,
-0x49, 0x3B, 0x00, 0x25, 0x00, 0x84, 0x04, 0x50, 0x0E, 0x48, 0x10, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x69, 0x00, 0xEF, 0x01, 0xCC, 0x07,
-0x70, 0x1F, 0xD0, 0x7A, 0x00, 0xA3, 0x01, 0xE4, 0x07, 0x34, 0x1A, 0xC0, 0x7B,
-0x00, 0xED, 0x01, 0xBC, 0x05, 0xF0, 0x7E, 0x41, 0x7B, 0x05, 0xAF, 0x01, 0xB8,
-0x05, 0x70, 0x1E, 0xC0, 0x48, 0x00, 0xEF, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0,
-0x7F, 0x00, 0xA5, 0x00, 0x8C, 0x06, 0x30, 0x1F, 0xC0, 0x51, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x0D, 0x00, 0x9F, 0x02, 0x7D, 0x1A, 0x74,
-0x6B, 0xC0, 0x35, 0x00, 0x9F, 0x00, 0x5D, 0x1A, 0xF0, 0x09, 0xC0, 0x37, 0x00,
-0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x3C, 0x81,
-0x70, 0x0D, 0xD0, 0x17, 0x08, 0xDF, 0x00, 0x5C, 0x82, 0xF0, 0x0D, 0xC0, 0x37,
-0x00, 0xDA, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x20, 0x4D, 0x00, 0xF7, 0x03, 0xCC, 0x1B, 0x70, 0x3F,
-0xC0, 0x7C, 0x00, 0x73, 0x01, 0xCD, 0x0F, 0x30, 0x1B, 0xC0, 0x7F, 0x00, 0xF3,
-0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x04, 0xB3, 0x01, 0xCC, 0x85, 0xF0,
-0x1F, 0xC0, 0x4C, 0x20, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x00,
-0x23, 0x01, 0xCC, 0x05, 0xF0, 0x1F, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0x00, 0x0D, 0x00, 0xF1, 0x08, 0x84, 0xC3, 0x18, 0x0B, 0x40,
-0x28, 0x00, 0x71, 0x00, 0xC4, 0x22, 0x10, 0x0A, 0x40, 0x3B, 0x00, 0xE1, 0x00,
-0xB4, 0x23, 0x10, 0x0E, 0xC0, 0x39, 0x02, 0xE1, 0x02, 0x84, 0x00, 0x70, 0x07,
-0x40, 0x18, 0x20, 0xED, 0x80, 0xB4, 0x03, 0xD0, 0x02, 0x40, 0x3B, 0x00, 0x25,
-0x0A, 0xAC, 0x28, 0xD0, 0x0E, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x09, 0x00, 0xED, 0x00, 0xC4, 0x23, 0x50, 0x0A, 0x50, 0x28,
-0x00, 0x25, 0x08, 0x84, 0x03, 0x10, 0x0A, 0x40, 0x33, 0x00, 0xE1, 0x00, 0x34,
-0x02, 0x10, 0x0E, 0x40, 0x33, 0x00, 0x41, 0x00, 0xA4, 0x01, 0xD0, 0x0E, 0x40,
-0x88, 0x04, 0xED, 0x00, 0xB4, 0x02, 0xD0, 0x02, 0x40, 0x3F, 0x00, 0xA1, 0x00,
-0x94, 0x03, 0xD0, 0x0E, 0x40, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x28, 0x01, 0x00, 0x89, 0x00, 0x44, 0x0B, 0x10, 0x08, 0x40, 0xE4, 0x01,
-0x05, 0x00, 0x44, 0x02, 0x10, 0x28, 0x40, 0x33, 0x00, 0xC1, 0x11, 0x34, 0x02,
-0x10, 0x0C, 0x68, 0x31, 0x00, 0x41, 0x52, 0x24, 0x00, 0x50, 0x0C, 0x40, 0x50,
-0x00, 0xDD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x73, 0x02, 0x85, 0x00, 0x34,
-0x03, 0xD0, 0x0C, 0x40, 0x19, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0xA0, 0x25, 0x00, 0xDF, 0x00, 0x4D, 0x0B, 0x50, 0x05, 0xC0, 0x74, 0x40, 0x17,
-0x00, 0x44, 0x03, 0x34, 0x0C, 0xC0, 0x37, 0x00, 0xD3, 0x06, 0x7C, 0x02, 0x30,
-0x0F, 0xC0, 0x3F, 0x00, 0xD3, 0x02, 0x6C, 0x01, 0xF0, 0x1D, 0xC0, 0x44, 0x00,
-0xDF, 0x40, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x3F, 0x00, 0x53, 0x00, 0x5C, 0x00,
-0xF0, 0x2F, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08,
-0x87, 0x00, 0xD7, 0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x02, 0x1A, 0x02,
-0x7C, 0x02, 0xF1, 0x09, 0xC1, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xF0, 0x1D,
-0xC0, 0x37, 0x20, 0x1F, 0x03, 0x5C, 0x01, 0x70, 0x8D, 0xC0, 0x07, 0x28, 0xDF,
-0x02, 0x7C, 0x06, 0xF0, 0x05, 0xCA, 0x37, 0x00, 0x9F, 0x02, 0x2C, 0x0A, 0xF0,
-0x0D, 0xC0, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x0F,
-0x00, 0xFF, 0x00, 0xCC, 0x43, 0x30, 0x0F, 0xC0, 0x74, 0x01, 0x23, 0x01, 0xC4,
-0x03, 0x30, 0x0B, 0xC0, 0x3C, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0x30, 0x0F, 0xC0,
-0x3B, 0x00, 0xB3, 0x00, 0x8E, 0x00, 0x30, 0x0B, 0xC0, 0x0D, 0x00, 0x7B, 0x00,
-0xCC, 0x03, 0x30, 0x07, 0xC0, 0x3F, 0x10, 0x7F, 0x00, 0xCC, 0x0C, 0x30, 0x0F,
-0xC1, 0x03, 0x2A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0xC6, 0x24,
-0x8D, 0x00, 0x44, 0x02, 0x90, 0x19, 0xC0, 0x36, 0x40, 0x11, 0x03, 0x54, 0x0E,
-0x50, 0x09, 0x50, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x4C, 0x10, 0x0D, 0x40, 0x37,
-0x00, 0x01, 0x00, 0x54, 0x0C, 0x51, 0x09, 0x40, 0xC0, 0x00, 0xDB, 0x03, 0x04,
-0x07, 0x10, 0x15, 0xC0, 0x35, 0x00, 0xCD, 0x08, 0x54, 0x06, 0x10, 0x0D, 0x40,
-0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x80, 0xDD,
-0x00, 0x44, 0x03, 0x90, 0x18, 0x40, 0x25, 0x00, 0x51, 0x88, 0x54, 0x07, 0x10,
-0x89, 0x40, 0x34, 0x00, 0xD5, 0x00, 0x74, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x00,
-0x91, 0x00, 0x46, 0x45, 0x90, 0x1C, 0x40, 0x44, 0x44, 0xD9, 0x03, 0x44, 0x12,
-0x10, 0x11, 0x60, 0x37, 0x00, 0x5D, 0x00, 0x44, 0x01, 0x10, 0x0D, 0x40, 0x07,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xDD, 0x00,
-0x04, 0x03, 0x90, 0x08, 0x40, 0x22, 0x00, 0x41, 0x00, 0x14, 0x02, 0x14, 0x08,
-0x48, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x00, 0x10, 0x0C, 0x40, 0x33, 0x20, 0x41,
-0x00, 0x16, 0x00, 0xD0, 0x04, 0x40, 0x00, 0x40, 0xC9, 0x80, 0x45, 0x02, 0x14,
-0x10, 0x60, 0x31, 0x00, 0x4D, 0x00, 0x14, 0x01, 0x10, 0x0C, 0x40, 0x43, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xFF, 0x00, 0xCD,
-0x03, 0x34, 0x0B, 0xC0, 0x25, 0x00, 0x13, 0x00, 0xDC, 0x02, 0x30, 0x09, 0xC0,
-0x34, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0x11, 0x0F, 0xC0, 0x3F, 0x00, 0x53, 0x00,
-0x44, 0x00, 0xB0, 0x0D, 0xC8, 0x05, 0x40, 0x9B, 0x00, 0x4C, 0x03, 0x30, 0x01,
-0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x03, 0x40, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00, 0xBF, 0x00, 0xBC, 0x03,
-0x70, 0x0B, 0xC0, 0x2F, 0x00, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x0B, 0xC0, 0x3F,
-0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC,
-0x00, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xBF, 0x00, 0xF4, 0x03, 0xF1, 0x03, 0xCA,
-0x39, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x53, 0xF0,
-0x03, 0xC0, 0x0F, 0x00, 0xAF, 0x01, 0xFC, 0x87, 0xF0, 0x1F, 0xD0, 0x0C, 0x00,
-0xFF, 0x01, 0xCC, 0x03, 0xF0, 0x4F, 0xC0, 0x0D, 0x02, 0xB3, 0x01, 0xEC, 0x07,
-0xF0, 0x03, 0xC0, 0x0F, 0x08, 0xEF, 0x01, 0xBC, 0x05, 0xB4, 0x1A, 0xC0, 0x7B,
-0x00, 0x33, 0x04, 0xBC, 0x02, 0x20, 0x0B, 0xC8, 0x0C, 0x08, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0x1D, 0x00, 0xF4, 0x0B, 0xD0, 0x11,
-0x40, 0x47, 0x00, 0xDD, 0x01, 0x74, 0x07, 0xD0, 0x0D, 0x40, 0x20, 0x01, 0xCC,
-0x10, 0xC4, 0x2B, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0xD1, 0x01, 0x44, 0x03, 0xD0,
-0x11, 0x42, 0x07, 0x00, 0xDD, 0x01, 0x74, 0x07, 0x12, 0x19, 0x40, 0x57, 0x20,
-0x15, 0x83, 0x74, 0x06, 0x51, 0x01, 0x40, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40,
-0x03, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x20, 0x04, 0xCD, 0x04,
-0x05, 0x03, 0xD2, 0x8C, 0x42, 0x23, 0x08, 0xD1, 0x80, 0x34, 0x03, 0xD0, 0x08,
-0x40, 0x63, 0x00, 0xCD, 0x00, 0x34, 0x81, 0x10, 0x0C, 0x40, 0x27, 0x00, 0x81,
-0x08, 0x34, 0x02, 0x19, 0x08, 0x40, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0xA8, 0x65, 0x00, 0x1D, 0x21, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x47,
-0x00, 0xDD, 0x01, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0xE4, 0x00, 0xCD, 0x20, 0x44,
-0x03, 0xD1, 0x0D, 0x40, 0x63, 0x00, 0xD1, 0x03, 0x54, 0x03, 0x90, 0x19, 0x40,
-0x67, 0x10, 0xDD, 0x04, 0x74, 0x06, 0x11, 0x1D, 0x40, 0x37, 0x00, 0x55, 0x90,
-0x74, 0x06, 0x58, 0x19, 0x42, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA0, 0xE7, 0x00, 0x9F, 0x11, 0x5C, 0x03, 0xF1, 0x19, 0xC0, 0x67, 0x04,
-0xDF, 0x05, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xC4, 0x00, 0xDF, 0x01, 0x4C, 0x03,
-0xF0, 0x0D, 0xC0, 0x45, 0x40, 0xC3, 0x01, 0x7C, 0x03, 0xF0, 0x39, 0xC1, 0x67,
-0x00, 0xDF, 0x00, 0x3C, 0x0D, 0xB8, 0x39, 0xC0, 0x37, 0x00, 0x53, 0x02, 0x7C,
-0x04, 0x30, 0x11, 0xC0, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
-0x88, 0x2D, 0x00, 0xBF, 0x80, 0x7C, 0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xFF,
-0x00, 0xFC, 0x03, 0xF0, 0x8F, 0xC0, 0x2F, 0x00, 0xFF, 0x02, 0xFC, 0x03, 0xF2,
-0x0F, 0xE0, 0x27, 0x80, 0xFF, 0x00, 0xEC, 0x03, 0xF0, 0x09, 0xC0, 0x0F, 0x00,
-0xFF, 0x01, 0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x7F, 0x01, 0x3F, 0x04, 0xBC, 0x02,
-0xF0, 0x01, 0xC1, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
-0x05, 0x02, 0x9F, 0x02, 0x7C, 0x03, 0x30, 0x29, 0xC0, 0xA7, 0x00, 0xDF, 0x0A,
-0x6C, 0x03, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xD3, 0x04, 0x4C, 0x13, 0xF2, 0x8D,
-0xC2, 0xA7, 0x00, 0xD7, 0x03, 0x4C, 0x47, 0xF0, 0x29, 0xC0, 0x24, 0x04, 0xDB,
-0x04, 0x4C, 0x19, 0x70, 0x2D, 0xC5, 0x34, 0x00, 0x57, 0x02, 0x7C, 0x60, 0x74,
-0x01, 0xC0, 0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24,
-0x00, 0x9D, 0x18, 0xF4, 0x2B, 0x10, 0x01, 0x40, 0x27, 0x00, 0xDD, 0x00, 0x44,
-0x03, 0xD0, 0x8D, 0x40, 0x27, 0x00, 0xD1, 0x02, 0xC4, 0x4B, 0xD0, 0x2F, 0x40,
-0x27, 0x00, 0xD1, 0x80, 0x50, 0x0B, 0xF0, 0x49, 0x00, 0x85, 0x00, 0xDD, 0x41,
-0x6C, 0x4F, 0x10, 0x0D, 0x40, 0x30, 0x02, 0x5B, 0x00, 0x70, 0x0A, 0x10, 0x21,
-0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x04,
-0x0D, 0x00, 0x34, 0x03, 0x10, 0x00, 0x40, 0x23, 0x00, 0xCD, 0x01, 0x24, 0x03,
-0x50, 0x3D, 0x40, 0x03, 0x00, 0xC5, 0x00, 0x04, 0x03, 0xD0, 0x4C, 0x40, 0x02,
-0x00, 0xC9, 0x00, 0x04, 0x8B, 0xD0, 0x10, 0x40, 0x00, 0x20, 0xCD, 0x02, 0x04,
-0x0B, 0x50, 0x28, 0x40, 0x32, 0x00, 0x0D, 0x07, 0x34, 0x04, 0xD4, 0x19, 0x40,
-0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x58, 0x00, 0x6D,
-0x01, 0xB4, 0x27, 0x14, 0x16, 0x40, 0x7B, 0x00, 0xFD, 0x01, 0x84, 0x87, 0xD0,
-0x1E, 0x40, 0x7B, 0x10, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x48, 0x6B, 0x50,
-0xF9, 0x01, 0x94, 0x87, 0x58, 0x16, 0x50, 0x48, 0x02, 0xFD, 0x11, 0xE4, 0x17,
-0x10, 0x0F, 0x40, 0x7E, 0x8C, 0xA9, 0x01, 0xB4, 0x24, 0x90, 0x12, 0x48, 0x3E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1A, 0x90, 0x00, 0xCF, 0x00,
-0x3C, 0x03, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0x70, 0x0C,
-0xC1, 0x03, 0x40, 0xC5, 0x00, 0x0C, 0x23, 0xF0, 0x0C, 0x40, 0x12, 0x02, 0xD7,
-0x00, 0x0C, 0x03, 0xD0, 0x80, 0xC0, 0x30, 0x02, 0xCF, 0x00, 0x04, 0x03, 0x70,
-0x8C, 0xC0, 0x32, 0x00, 0xCF, 0x10, 0x3C, 0x22, 0xF4, 0x88, 0xC9, 0x48, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x1D, 0x00, 0xFF, 0x00, 0xFC,
-0x03, 0xF0, 0x8F, 0xC0, 0x3F, 0x10, 0xFF, 0x08, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x17, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x8F, 0xC8, 0x1F, 0x08, 0xF7, 0x00,
-0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x02, 0xFF, 0x00, 0xFC, 0x13, 0xF0, 0x4F,
-0xE0, 0x3D, 0x00, 0xFE, 0x08, 0xFC, 0x23, 0x74, 0x0F, 0xC0, 0x0B, 0x60, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x08, 0x5F, 0x01, 0x4C, 0x03,
-0x70, 0x09, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x17,
-0x00, 0xD7, 0x00, 0x5C, 0x1B, 0xF0, 0x0D, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x7C,
-0x03, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xC3, 0x00, 0x2C, 0x03, 0xB0, 0x0D, 0x40,
-0x37, 0x00, 0x9F, 0x40, 0x4C, 0x80, 0x20, 0x09, 0xC2, 0x43, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x82, 0x39, 0x00, 0x6D, 0x00, 0xC4, 0x2B, 0x10,
-0x0E, 0x40, 0x1B, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00,
-0xED, 0x00, 0xB4, 0x33, 0xD0, 0x2E, 0x40, 0x3B, 0x00, 0xEF, 0x00, 0xB4, 0x03,
-0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xE1, 0x00, 0x84, 0x03, 0x50, 0x0E, 0x00, 0x3B,
-0x00, 0x8D, 0x00, 0x84, 0x01, 0xB0, 0x02, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xCD, 0x03, 0xA5, 0x17, 0x50, 0x1E,
-0x40, 0x7B, 0x00, 0xED, 0x11, 0xB4, 0x07, 0xD0, 0x1E, 0x41, 0x7B, 0x00, 0xED,
-0x01, 0x96, 0x27, 0xD0, 0x1E, 0x40, 0x7B, 0x88, 0xED, 0x01, 0xB4, 0x07, 0xD0,
-0x36, 0x40, 0x73, 0x00, 0xE1, 0x01, 0xA4, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x00,
-0xED, 0x11, 0x14, 0x44, 0x19, 0x3E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x16, 0x28, 0x73, 0x00, 0xCD, 0x01, 0x24, 0x03, 0x10, 0x0C, 0x40,
-0x33, 0x00, 0x49, 0x05, 0x34, 0x03, 0xD0, 0x18, 0x40, 0xF3, 0x00, 0x8D, 0x01,
-0x74, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x02, 0x45, 0x1A, 0x34, 0x03, 0xD0, 0x5C,
-0x40, 0x77, 0x00, 0x81, 0x00, 0x04, 0x07, 0x50, 0x2C, 0x60, 0xB3, 0x00, 0xCD,
-0x47, 0x14, 0x07, 0x90, 0x1C, 0x40, 0x5B, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x17, 0xA0, 0x1D, 0x00, 0x7F, 0x02, 0x6C, 0x01, 0x70, 0x27, 0xC0, 0x9F,
-0x00, 0x7F, 0x01, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x1F, 0x00, 0x5F, 0x01, 0x5C,
-0x01, 0xF0, 0x05, 0xC0, 0xDF, 0x00, 0x7D, 0x02, 0x7C, 0x81, 0xF1, 0x37, 0xC0,
-0xDF, 0x40, 0x43, 0x00, 0xEC, 0x01, 0xB0, 0x27, 0xC0, 0x1B, 0x01, 0x7F, 0x23,
-0x9D, 0xA5, 0x20, 0xB7, 0xC0, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x08, 0x45, 0x02, 0x1F, 0x02, 0x1C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
-0x1D, 0x20, 0x7C, 0x00, 0xF2, 0x21, 0xC8, 0x07, 0x06, 0x1F, 0x0A, 0x7C, 0x00,
-0xF0, 0x21, 0xC0, 0x07, 0x04, 0x1F, 0x80, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x87,
-0x06, 0x1F, 0x42, 0x7C, 0x28, 0xB0, 0x41, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x64,
-0x88, 0xF0, 0x21, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x25, 0x00, 0x9F, 0x19, 0x7C, 0x06, 0x30, 0x08, 0xC5, 0x24, 0x04, 0x9F,
-0x08, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x23, 0x00, 0x9B, 0x01, 0x7C, 0x02, 0x30,
-0x09, 0xC2, 0x23, 0x80, 0x93, 0x04, 0x4C, 0x02, 0xF0, 0x59, 0xC0, 0x27, 0x00,
-0x93, 0x03, 0x5C, 0x02, 0x71, 0x59, 0xC0, 0xA7, 0x40, 0x83, 0x00, 0x4C, 0x22,
-0x30, 0x28, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
-0x64, 0x00, 0x9D, 0x12, 0x74, 0x0A, 0x14, 0x09, 0x50, 0x24, 0x00, 0x97, 0x01,
-0x74, 0x02, 0xD8, 0x49, 0x40, 0x27, 0x40, 0x91, 0x11, 0x74, 0x0A, 0x50, 0x29,
-0x40, 0x27, 0xC0, 0x8B, 0x01, 0x44, 0x4A, 0xD0, 0x09, 0x44, 0xE7, 0x40, 0x91,
-0x86, 0x00, 0x12, 0x20, 0x19, 0x40, 0xE7, 0x10, 0x91, 0x01, 0x44, 0x06, 0x14,
-0x39, 0x41, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x24,
-0x25, 0x9D, 0x00, 0x74, 0x62, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74,
-0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x74, 0x0A, 0x10, 0x09, 0x40,
-0x37, 0x08, 0x91, 0x00, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x99, 0x00,
-0x50, 0x03, 0x50, 0x0D, 0x40, 0x36, 0x00, 0x99, 0x04, 0x44, 0x03, 0x10, 0x0D,
-0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0x20, 0x05,
-0x8D, 0x14, 0x36, 0x12, 0x10, 0x48, 0x40, 0x20, 0x01, 0x85, 0x80, 0x34, 0x02,
-0xD0, 0x08, 0x40, 0x23, 0x01, 0x81, 0x08, 0x74, 0x12, 0x50, 0x08, 0x40, 0x23,
-0x01, 0x91, 0x00, 0x04, 0x02, 0xD2, 0x48, 0x40, 0x33, 0x01, 0x89, 0x00, 0x44,
-0x02, 0x10, 0x08, 0x44, 0x33, 0x00, 0x89, 0x01, 0x05, 0x93, 0x10, 0x48, 0x50,
-0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x01, 0x1F,
-0x04, 0x7C, 0x28, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xD0,
-0xA1, 0xC0, 0x87, 0x02, 0x13, 0x02, 0x7C, 0x28, 0x30, 0xE5, 0xC5, 0x87, 0x02,
-0x11, 0x00, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x87, 0x22, 0x1B, 0x00, 0x5C, 0x00,
-0x72, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x14, 0x4C, 0x00, 0x30, 0xA1, 0xC0, 0x74,
-0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2F, 0x05, 0xBF, 0x14,
-0x74, 0xA2, 0xF2, 0x8B, 0xC0, 0x2F, 0x22, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x0B,
-0xC0, 0x2F, 0x0A, 0xB7, 0x04, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF,
-0x00, 0x7D, 0x02, 0xF0, 0x8F, 0x00, 0x2F, 0x02, 0xB7, 0x80, 0xFC, 0x02, 0x70,
-0x0B, 0xC0, 0x2F, 0x08, 0xF7, 0x00, 0xFD, 0x23, 0xF0, 0x8B, 0xC2, 0x77, 0x60,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x05, 0xBF, 0x0C, 0xFC,
-0x82, 0x32, 0x09, 0xC0, 0x24, 0x00, 0xB3, 0x00, 0x7C, 0x02, 0xF0, 0x8A, 0xC0,
-0x24, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0x30, 0x4B, 0xC0, 0x26, 0x05, 0xBF, 0x00,
-0xFC, 0x02, 0x30, 0x0B, 0xE0, 0x2F, 0x02, 0xFF, 0x00, 0xCD, 0x02, 0xB0, 0x0F,
-0xC2, 0x2F, 0x48, 0xB3, 0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC4, 0x74, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x1D, 0x0C, 0x74, 0x48,
-0x10, 0x05, 0x40, 0x04, 0x02, 0x51, 0x00, 0x74, 0x00, 0xD0, 0x41, 0x48, 0x84,
-0x04, 0x1D, 0x10, 0x74, 0x20, 0x14, 0x41, 0x41, 0x04, 0x01, 0x57, 0x80, 0x74,
-0x40, 0x10, 0x01, 0x60, 0x07, 0x02, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40,
-0x17, 0x50, 0x11, 0x00, 0x45, 0x00, 0xF0, 0x01, 0xC0, 0x62, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x05, 0x36, 0x32, 0x14,
-0x88, 0x40, 0x62, 0x60, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x48, 0x50, 0x20, 0x03,
-0x8D, 0x00, 0x34, 0x02, 0x10, 0xCC, 0x40, 0x22, 0x05, 0xCD, 0x00, 0x36, 0x13,
-0x10, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x24, 0x02, 0x94, 0x18, 0x40, 0x23,
-0x00, 0x85, 0x40, 0x14, 0x02, 0xD2, 0x08, 0x40, 0x48, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x04, 0x9D, 0x80, 0x74, 0x02, 0x10, 0x09,
-0x50, 0x26, 0x01, 0x91, 0x01, 0x74, 0x02, 0xD0, 0x09, 0x40, 0xA4, 0x00, 0x9D,
-0x00, 0x74, 0x02, 0x11, 0x09, 0x40, 0x64, 0x10, 0x9D, 0x01, 0x74, 0x02, 0x10,
-0x09, 0x40, 0xE7, 0x10, 0x9D, 0x00, 0x64, 0x12, 0x12, 0x09, 0x40, 0x27, 0x08,
-0xD5, 0x04, 0x44, 0x02, 0xD0, 0x29, 0x40, 0x62, 0x28, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0,
-0x66, 0x00, 0x93, 0x03, 0x7C, 0x02, 0xF0, 0x19, 0xC0, 0xA4, 0x00, 0x9F, 0x01,
-0x7C, 0x02, 0x30, 0x09, 0xC0, 0xA6, 0x04, 0x9F, 0x03, 0x74, 0x02, 0x34, 0x29,
-0x40, 0xA7, 0x00, 0x8F, 0x00, 0x2C, 0x82, 0xB0, 0x29, 0xC0, 0xA3, 0x00, 0x97,
-0x02, 0x5C, 0x06, 0xF0, 0x29, 0xC0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x16, 0x08, 0x65, 0x0A, 0x9F, 0x14, 0x7C, 0x02, 0xF2, 0x48, 0xC0, 0x21,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x7C,
-0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x97, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0x82,
-0x27, 0x00, 0x9F, 0x18, 0x5C, 0x02, 0xD0, 0x99, 0xC0, 0xA7, 0x64, 0x9B, 0x00,
-0x7C, 0x8E, 0x78, 0x38, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x08, 0x85, 0x04, 0x1F, 0x08, 0x7C, 0x40, 0xF1, 0x01, 0xC0, 0x07, 0x80,
-0x13, 0x20, 0x7C, 0x00, 0xF2, 0x41, 0xD0, 0x84, 0x00, 0x1F, 0x00, 0x0C, 0x00,
-0x30, 0x01, 0xC2, 0x87, 0x08, 0x1F, 0x02, 0x7E, 0x00, 0xF2, 0x21, 0xF0, 0x04,
-0x0C, 0x1B, 0x80, 0x7C, 0x00, 0x70, 0x01, 0xC9, 0x87, 0x00, 0x07, 0x80, 0x4D,
-0x08, 0x32, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x00, 0xDC, 0x20, 0x7D, 0x01, 0xF6, 0x1D, 0x70, 0x05, 0x60, 0x17, 0x00, 0x51,
-0x00, 0x74, 0x01, 0xD0, 0x07, 0xC0, 0x16, 0x00, 0x7D, 0x05, 0xCD, 0x19, 0x30,
-0x27, 0x60, 0x17, 0x20, 0x5D, 0x00, 0xFC, 0xA9, 0x72, 0x45, 0x62, 0x1C, 0x11,
-0x71, 0x25, 0xDC, 0x8D, 0x14, 0x27, 0xC0, 0x9D, 0x01, 0x71, 0x89, 0xCC, 0x01,
-0x10, 0x37, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
-0xF2, 0x02, 0xCD, 0x02, 0x74, 0x03, 0x52, 0x0C, 0x44, 0x33, 0x00, 0x81, 0x00,
-0x34, 0x03, 0xD0, 0x2D, 0x40, 0x30, 0x00, 0xCD, 0x01, 0x24, 0x1F, 0x10, 0x2C,
-0x49, 0x33, 0x10, 0x8D, 0x00, 0x74, 0x03, 0x51, 0x18, 0x40, 0x30, 0x00, 0x41,
-0x01, 0x34, 0x40, 0x10, 0x0C, 0x40, 0xA3, 0x20, 0xC5, 0x09, 0x20, 0x07, 0x10,
-0x2C, 0x41, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38,
-0x00, 0xED, 0x00, 0xB4, 0x01, 0x50, 0x0E, 0x40, 0x33, 0x40, 0xE1, 0x80, 0xB4,
-0x03, 0xD8, 0x0F, 0x41, 0x38, 0x00, 0x6D, 0x01, 0x84, 0x03, 0x10, 0x0E, 0x48,
-0x3B, 0x02, 0xED, 0x40, 0xB4, 0x01, 0x50, 0x1E, 0x48, 0x59, 0x00, 0x61, 0x81,
-0xD4, 0x42, 0x10, 0x06, 0x40, 0x2D, 0x00, 0x61, 0x00, 0x04, 0x46, 0x10, 0x0E,
-0x41, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00,
-0x6F, 0x01, 0xB4, 0x07, 0x70, 0x1E, 0x40, 0x7B, 0x08, 0xE1, 0x01, 0xBC, 0x07,
-0xF0, 0x1E, 0x40, 0x78, 0x81, 0xBD, 0x01, 0xEC, 0x05, 0x34, 0x1E, 0x40, 0x7B,
-0x02, 0xEF, 0x01, 0xB4, 0x07, 0x70, 0x1E, 0x40, 0x7C, 0x40, 0x6B, 0x00, 0xBC,
-0x06, 0x30, 0x1A, 0xC0, 0x6B, 0x00, 0xE7, 0x01, 0xAC, 0x07, 0x34, 0x17, 0xC0,
-0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF,
-0x00, 0x7C, 0x81, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC0, 0x37, 0x04, 0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0xB7, 0x00,
-0xDF, 0x00, 0x5C, 0x83, 0x72, 0x0C, 0xE0, 0x16, 0x08, 0xDF, 0x00, 0x3C, 0x02,
-0xC4, 0x01, 0xC0, 0x23, 0x00, 0x0F, 0x00, 0x7C, 0x83, 0xF0, 0x01, 0xD0, 0x43,
-0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x7D, 0x00, 0xF3, 0x01,
-0xCC, 0x13, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F,
-0xC0, 0x7F, 0x04, 0xF3, 0x01, 0xCC, 0x13, 0x30, 0x17, 0xC0, 0x7C, 0x02, 0xFF,
-0x89, 0xFC, 0x87, 0x30, 0x9F, 0xC0, 0x7F, 0x00, 0x73, 0x01, 0xFC, 0x26, 0xF0,
-0x17, 0xC8, 0x6B, 0x20, 0xBB, 0x01, 0xFC, 0x07, 0xD0, 0x13, 0xC0, 0x1B, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x3D, 0x50, 0x71, 0x20, 0x84,
-0x83, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x2A, 0x48,
-0x3F, 0x00, 0x61, 0x00, 0xD4, 0x08, 0x11, 0x0B, 0xC0, 0x38, 0x00, 0xE9, 0x88,
-0xDC, 0x82, 0x10, 0xCE, 0x40, 0x3B, 0x01, 0x61, 0x00, 0xB4, 0x32, 0xD0, 0x06,
-0x42, 0x3B, 0x12, 0x21, 0x30, 0xB4, 0x02, 0xD0, 0x4A, 0x42, 0x57, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x61, 0x00, 0x84, 0x20,
-0xD0, 0x0E, 0x40, 0x3B, 0x09, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x86, 0x40, 0x3B,
-0x00, 0xB1, 0x00, 0xA4, 0x21, 0x10, 0x0E, 0x40, 0x38, 0x20, 0xED, 0x08, 0xB6,
-0x03, 0x10, 0x0E, 0x49, 0x2B, 0x00, 0x61, 0x10, 0xB4, 0x02, 0xD1, 0x02, 0x40,
-0x2F, 0x00, 0x29, 0x00, 0xB4, 0x03, 0xD0, 0x02, 0x44, 0x23, 0x02, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xE1, 0x00, 0x01, 0x07, 0x04, 0x00, 0xD0,
-0x0C, 0x40, 0x73, 0x00, 0xCD, 0x03, 0x34, 0x03, 0xD1, 0x00, 0x44, 0x33, 0x00,
-0x11, 0x00, 0x34, 0x00, 0x14, 0x09, 0x50, 0xB6, 0x10, 0xCD, 0x03, 0x34, 0x02,
-0x14, 0x3C, 0x40, 0xA3, 0x40, 0x41, 0x01, 0x34, 0x4A, 0xD0, 0x20, 0x40, 0x23,
-0x02, 0x01, 0x03, 0x34, 0x6F, 0xD0, 0x11, 0x41, 0x0B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0xA0, 0xC5, 0x00, 0x93, 0x04, 0x47, 0x02, 0xF1, 0x2D,
-0x80, 0xF7, 0x01, 0xDF, 0x07, 0x74, 0x03, 0xF0, 0x01, 0x40, 0x3F, 0x42, 0xD3,
-0x00, 0x6C, 0x02, 0x30, 0x09, 0xC0, 0x3C, 0x00, 0xDF, 0x05, 0x74, 0x02, 0x30,
-0x1D, 0xC4, 0x27, 0x00, 0x53, 0x01, 0x7C, 0x12, 0xF0, 0x25, 0xC0, 0x73, 0x00,
-0xDB, 0x03, 0x7C, 0x0B, 0xF2, 0x69, 0x40, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x08, 0x27, 0x03, 0x9F, 0x00, 0x7E, 0x0A, 0xF0, 0x1D, 0xC0,
-0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x39, 0xC0, 0x77, 0x10, 0xDF, 0x03,
-0x5C, 0x0A, 0xF0, 0x29, 0xC0, 0x35, 0x00, 0xDB, 0x10, 0x54, 0x80, 0xF0, 0x0D,
-0xCD, 0x27, 0x01, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x85, 0xC1, 0xB7, 0x04, 0xDF,
-0x04, 0x7C, 0x02, 0xF0, 0x29, 0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x80, 0x08, 0x0B, 0x00, 0x33, 0x00, 0xFC, 0x82, 0xF0, 0x0F, 0xC1, 0x3F,
-0x24, 0xFF, 0x30, 0xFC, 0x03, 0xF2, 0x03, 0xC4, 0x3B, 0x00, 0x73, 0x05, 0x8D,
-0x02, 0x30, 0x03, 0xC2, 0x3C, 0x04, 0xF3, 0x04, 0xFC, 0x00, 0xF1, 0x0E, 0xC0,
-0x06, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0x70, 0x27, 0xC0, 0x3C, 0x40, 0xF3, 0x02,
-0xCC, 0x01, 0xF1, 0x0B, 0xC0, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x81, 0x20, 0xC6, 0x34, 0x91, 0x13, 0x5C, 0x16, 0xD0, 0x0D, 0x40, 0x37, 0x00,
-0xDD, 0x00, 0x74, 0x03, 0xD9, 0x39, 0x40, 0x37, 0x00, 0x51, 0x04, 0x44, 0x0E,
-0x10, 0x71, 0x40, 0x34, 0x00, 0xD3, 0x01, 0x74, 0x0C, 0xD0, 0x0D, 0x40, 0x44,
-0x00, 0x5D, 0x03, 0x34, 0x17, 0x11, 0x34, 0x40, 0xF4, 0x04, 0x81, 0x00, 0x44,
-0x07, 0xD0, 0x59, 0x48, 0x84, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0xA0, 0x46, 0x00, 0x91, 0x01, 0x74, 0x06, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD,
-0x04, 0x74, 0x83, 0xD0, 0x19, 0x40, 0x37, 0x00, 0x91, 0x40, 0x44, 0x06, 0x90,
-0x11, 0x40, 0x34, 0x20, 0xD1, 0x00, 0x74, 0x46, 0xD0, 0x1D, 0x40, 0x66, 0x04,
-0x5D, 0x11, 0x74, 0x06, 0x50, 0x25, 0x40, 0x74, 0x00, 0xD1, 0x00, 0x44, 0x0E,
-0xD0, 0x11, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
-0x20, 0x00, 0x81, 0x20, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00,
-0x34, 0x03, 0xD0, 0x08, 0x40, 0x33, 0x48, 0x81, 0x00, 0x06, 0x00, 0x90, 0x08,
-0x40, 0x30, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x42, 0x20, 0x00, 0x49,
-0x00, 0x74, 0x02, 0x18, 0x04, 0x40, 0x10, 0x00, 0xC1, 0x20, 0x04, 0x02, 0xD0,
-0x08, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-0x40, 0x13, 0x40, 0x7E, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x7E,
-0x03, 0xD0, 0x01, 0xC2, 0x3F, 0x00, 0x13, 0x00, 0x4C, 0x02, 0xB0, 0x01, 0xC0,
-0x3C, 0x00, 0xD3, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC0, 0x06, 0x00, 0x5F, 0x00,
-0x7C, 0x02, 0x70, 0x05, 0xD0, 0x34, 0x10, 0x53, 0x00, 0x4C, 0x00, 0xF2, 0x01,
-0xD0, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x2F, 0x10,
-0xBF, 0x00, 0xDE, 0x00, 0xF0, 0x0F, 0xC6, 0x3F, 0x00, 0xFF, 0x80, 0xFC, 0x03,
-0xD0, 0x03, 0xE0, 0x3F, 0x00, 0x2F, 0x00, 0xF4, 0x00, 0x70, 0x03, 0xD0, 0x3F,
-0x00, 0xF7, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0x7F, 0x00, 0xFC,
-0x02, 0xF0, 0x07, 0xC8, 0x3F, 0x00, 0x3F, 0xA0, 0xFD, 0x02, 0xF0, 0x0B, 0xC0,
-0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x3F, 0x00, 0xB3,
-0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0x30,
-0x0A, 0xC0, 0x0C, 0x01, 0x33, 0x00, 0xCC, 0x00, 0xF0, 0x03, 0xC0, 0x0B, 0x00,
-0xFB, 0x06, 0xEC, 0x05, 0x30, 0x4F, 0xC1, 0x2F, 0x00, 0xF3, 0x14, 0xFC, 0x23,
-0xF0, 0x0B, 0xC0, 0x0F, 0x00, 0xF7, 0x04, 0xCC, 0x22, 0x34, 0x03, 0xC0, 0x0C,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x07, 0x10, 0x91, 0x80,
-0x44, 0x00, 0x70, 0x01, 0x40, 0x07, 0x00, 0x9D, 0x00, 0x44, 0x43, 0x10, 0x09,
-0x48, 0x84, 0x00, 0x91, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x27, 0x00, 0xF9,
-0x0B, 0x44, 0x55, 0x15, 0x2F, 0x40, 0x6F, 0x00, 0xD1, 0x03, 0x70, 0x3B, 0xD0,
-0x39, 0x40, 0x47, 0x40, 0xF1, 0x00, 0x6C, 0x0A, 0x10, 0x15, 0x40, 0x0D, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x05, 0x01, 0x20, 0x14,
-0x00, 0xD0, 0x00, 0x40, 0x23, 0x00, 0x0D, 0x20, 0x14, 0x13, 0x10, 0x00, 0x40,
-0x01, 0x02, 0x01, 0x20, 0x04, 0x02, 0xD0, 0x08, 0x42, 0x23, 0x00, 0xC1, 0x04,
-0x24, 0x81, 0x10, 0x0C, 0x4A, 0x27, 0x08, 0xCD, 0x00, 0x34, 0x03, 0xD1, 0x88,
-0x40, 0x03, 0x00, 0xC5, 0x08, 0x44, 0xA2, 0x13, 0x08, 0x46, 0x4C, 0x80, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x05, 0x11, 0x11, 0x04, 0x54, 0x04,
-0xD0, 0x11, 0x41, 0x47, 0x00, 0x1D, 0x11, 0x74, 0x03, 0x10, 0x15, 0x40, 0x41,
-0x00, 0x11, 0x01, 0x44, 0x04, 0xD2, 0x31, 0x4C, 0xE7, 0x00, 0xD1, 0x00, 0x64,
-0x21, 0x10, 0x0D, 0x40, 0x27, 0x01, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x19, 0x48,
-0x87, 0x00, 0xD1, 0x00, 0x64, 0x46, 0x10, 0x0D, 0x40, 0x0D, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x00, 0x93, 0x00, 0x5D, 0x46, 0xF0,
-0x39, 0xC0, 0x47, 0x01, 0x1F, 0x03, 0x5C, 0x03, 0x10, 0x29, 0xE1, 0x45, 0x40,
-0x93, 0x05, 0x4C, 0x0C, 0xD0, 0x19, 0xC0, 0xC7, 0x00, 0xDB, 0x00, 0x6C, 0x17,
-0x30, 0x0D, 0x60, 0x23, 0x40, 0xDF, 0x80, 0x7C, 0x03, 0xF2, 0x09, 0xC0, 0xC7,
-0x00, 0xD7, 0x00, 0x0C, 0x0E, 0x30, 0xB1, 0x81, 0x00, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0x80, 0x69, 0x40, 0x9F, 0x01, 0xEC, 0x00, 0x70, 0x0B,
-0xC0, 0x0F, 0x00, 0xAF, 0x20, 0x8C, 0x03, 0xF0, 0x0B, 0xE2, 0x0E, 0x00, 0xAF,
-0x00, 0xFD, 0x00, 0xF0, 0x01, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC, 0x06, 0xF8,
-0x0F, 0xC1, 0x6F, 0x00, 0xF2, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0x40, 0x4F, 0x02,
-0xFF, 0x00, 0xDF, 0x02, 0xF0, 0x07, 0xE0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x83, 0x00, 0x4D, 0x0A, 0xF0, 0x21, 0xC0,
-0x24, 0x81, 0x1F, 0x02, 0x5C, 0x03, 0x30, 0xA5, 0xC0, 0x44, 0x00, 0x1B, 0x00,
-0x7C, 0x0A, 0x32, 0x29, 0xC9, 0xA6, 0x42, 0xC3, 0x00, 0x5C, 0x01, 0x34, 0x0D,
-0xC0, 0x27, 0x80, 0xD3, 0x08, 0x7C, 0x03, 0x30, 0x49, 0xC0, 0x07, 0x10, 0xDF,
-0x00, 0x4C, 0x22, 0x30, 0x09, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0xA0, 0x2C, 0x14, 0x91, 0x20, 0x44, 0x2A, 0xD0, 0x89, 0x41, 0x84,
-0x00, 0x1D, 0x09, 0xF0, 0x03, 0x30, 0x85, 0x00, 0x24, 0x00, 0x11, 0x1A, 0x74,
-0x82, 0x30, 0x01, 0x40, 0xA4, 0x00, 0xFB, 0x40, 0x44, 0x01, 0x10, 0x0F, 0x40,
-0x27, 0x00, 0xF1, 0x01, 0xF4, 0x03, 0x50, 0x79, 0x40, 0x03, 0x00, 0xFD, 0x24,
-0x54, 0x02, 0xB0, 0x1C, 0x40, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0x20, 0x30, 0x08, 0x81, 0x00, 0x20, 0x26, 0xD1, 0x38, 0x40, 0x60, 0x20,
-0x8D, 0x20, 0x34, 0x03, 0x10, 0x39, 0x40, 0x00, 0x00, 0x09, 0x03, 0x16, 0x02,
-0x10, 0x20, 0x40, 0x04, 0x01, 0xC1, 0x00, 0x54, 0x02, 0x10, 0x3C, 0x40, 0x31,
-0x00, 0xC8, 0x01, 0x14, 0x03, 0x90, 0x28, 0x40, 0x13, 0x00, 0xD9, 0x00, 0x06,
-0x03, 0x10, 0x8C, 0x40, 0x5F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x02, 0x50, 0x00, 0xE1, 0x01, 0xA4, 0x07, 0xD0, 0x16, 0x60, 0x7A, 0x20, 0xED,
-0x01, 0xB4, 0x03, 0x90, 0x1E, 0x40, 0x40, 0x00, 0xE1, 0x41, 0xB6, 0x0D, 0x94,
-0x16, 0x42, 0x4A, 0x00, 0xC9, 0x01, 0x84, 0x05, 0x10, 0x1E, 0x40, 0x7B, 0x00,
-0xE9, 0x01, 0xB4, 0x27, 0xD0, 0x1A, 0x40, 0x5B, 0x00, 0xCD, 0x01, 0x16, 0x26,
-0x90, 0x9A, 0x40, 0x3F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18,
-0x30, 0x02, 0x01, 0x00, 0x0D, 0x01, 0xF0, 0x8D, 0xC0, 0x30, 0x04, 0xCD, 0x30,
-0x7C, 0x23, 0x10, 0x08, 0xC0, 0x00, 0x01, 0x0B, 0x00, 0x7C, 0x0B, 0x30, 0x88,
-0xC0, 0x12, 0x02, 0xC3, 0x00, 0x5C, 0x22, 0x32, 0x0C, 0xC1, 0x23, 0x00, 0xC9,
-0x08, 0x7C, 0x03, 0x30, 0x08, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x0C, 0x03, 0x30,
-0x04, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x1D,
-0x14, 0x7F, 0x00, 0xDD, 0x01, 0xF2, 0x87, 0xD0, 0x3D, 0x00, 0xFF, 0x08, 0xFC,
-0x13, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0x70, 0x0F, 0xC8,
-0x1D, 0x40, 0xFF, 0x10, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0xAB, 0x42, 0xF7, 0x20,
-0xFC, 0x03, 0x70, 0x0B, 0xC8, 0x2F, 0x12, 0xFC, 0x00, 0xFC, 0x02, 0xF0, 0x03,
-0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x27, 0x00,
-0xDF, 0x00, 0x4E, 0x03, 0x31, 0x0D, 0xC0, 0x17, 0x00, 0x5F, 0x01, 0xCC, 0x03,
-0xF0, 0x0D, 0xC0, 0x04, 0x00, 0xD3, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x1F,
-0x20, 0xDF, 0x06, 0x5C, 0x00, 0xF0, 0x2D, 0xC1, 0xB6, 0x00, 0xD3, 0x00, 0x7C,
-0x03, 0xA8, 0x1D, 0xC0, 0x15, 0x00, 0xDF, 0x06, 0x4D, 0x01, 0x30, 0x1D, 0xC0,
-0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x29, 0x09, 0xED,
-0x20, 0xC4, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xFD, 0x00, 0x84, 0x07, 0xD0,
-0x0C, 0x40, 0x08, 0x00, 0xE1, 0x00, 0xB4, 0x03, 0xD8, 0x0E, 0x40, 0x3B, 0x08,
-0xFD, 0x10, 0xAC, 0x00, 0xD0, 0x2E, 0x44, 0x3B, 0x00, 0xE1, 0x02, 0xF4, 0x03,
-0x10, 0x0E, 0x40, 0x18, 0x00, 0xED, 0x16, 0xC4, 0x02, 0xB0, 0x0A, 0xC0, 0x4E,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xF9, 0x00, 0xED, 0x81,
-0x84, 0x07, 0x11, 0x1E, 0x48, 0xFB, 0x08, 0xED, 0x11, 0x84, 0x07, 0xD0, 0x1E,
-0x40, 0x48, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x41, 0xFB, 0x00, 0xED,
-0x05, 0x94, 0x44, 0xD9, 0x5E, 0x40, 0x73, 0x00, 0xE5, 0x05, 0xB4, 0x07, 0x90,
-0x1C, 0x44, 0x79, 0x00, 0xED, 0x41, 0x84, 0x07, 0x10, 0x14, 0x40, 0x04, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x04, 0xCD, 0x02, 0x05,
-0x83, 0x12, 0x6C, 0x60, 0x73, 0x10, 0xCD, 0x03, 0x04, 0x03, 0xD0, 0x1C, 0x50,
-0x30, 0x02, 0xC1, 0x09, 0x34, 0x0B, 0xD0, 0x3C, 0x44, 0x73, 0x01, 0xCD, 0x40,
-0x24, 0x04, 0xD8, 0x0C, 0x40, 0x73, 0x80, 0xC5, 0x00, 0x34, 0x03, 0x10, 0x0C,
-0x42, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x02, 0x90, 0x00, 0x50, 0x4A, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x5D, 0x00, 0x7F, 0x00, 0xCC, 0x05,
-0x30, 0x27, 0xC0, 0x1F, 0x00, 0x7F, 0x08, 0x4D, 0x01, 0xF0, 0x17, 0xC1, 0x5C,
-0x40, 0x73, 0x01, 0xFC, 0x01, 0xF0, 0x27, 0x40, 0x5F, 0x00, 0x5F, 0x00, 0xDC,
-0x01, 0xF0, 0x05, 0xC0, 0x56, 0x41, 0x57, 0x00, 0x7C, 0x01, 0xB0, 0x05, 0xC0,
-0x1D, 0x89, 0x5F, 0x00, 0x8C, 0x01, 0x30, 0x07, 0xC0, 0x5C, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x81, 0x08, 0x1F, 0x10, 0x7C, 0x24, 0xF4,
-0xA1, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x47, 0x08,
-0x1F, 0x26, 0x7C, 0x00, 0xF0, 0x41, 0xC2, 0x87, 0x00, 0x0F, 0x00, 0x7C, 0x00,
-0xF2, 0x00, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0, 0x03,
-0x00, 0x1F, 0x00, 0x5C, 0x04, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x83, 0x00, 0x0C, 0x02, 0x30, 0x89,
-0xC0, 0x27, 0x00, 0x9F, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x60, 0x02, 0x93,
-0x01, 0x7C, 0x46, 0xF0, 0x59, 0xC0, 0x23, 0x00, 0x9B, 0x00, 0x4C, 0x42, 0xB0,
-0x09, 0xC0, 0x22, 0x01, 0x93, 0x00, 0x3C, 0x02, 0x90, 0x49, 0xC0, 0xA7, 0x40,
-0x93, 0x00, 0x4D, 0x02, 0x14, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x00, 0xE4, 0x21, 0x91, 0x00, 0x44, 0x0E, 0x14, 0x29, 0xC0,
-0x25, 0x02, 0x9D, 0x1B, 0x74, 0x02, 0xD0, 0x09, 0xC0, 0x24, 0x00, 0x95, 0x12,
-0x5C, 0x22, 0xD2, 0x19, 0x40, 0x67, 0x00, 0x91, 0x80, 0x44, 0x02, 0x10, 0x29,
-0x41, 0x64, 0x00, 0x91, 0x00, 0x74, 0x02, 0x50, 0x39, 0x41, 0x67, 0x00, 0x91,
-0x02, 0x44, 0x02, 0x10, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA0, 0x64, 0x00, 0x91, 0x00, 0x44, 0x22, 0x10, 0x09, 0x41, 0x27,
-0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x08, 0x40, 0x24, 0x00, 0x99, 0x08, 0x74,
-0x02, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x99, 0x00, 0x04, 0x82, 0x94, 0x09, 0x40,
-0x26, 0x00, 0x95, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x27, 0x20, 0x89, 0x42,
-0x44, 0x02, 0x50, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x20, 0x20, 0x01, 0x81, 0x04, 0x04, 0x12, 0x10, 0x08, 0x40, 0x21, 0x82,
-0x8D, 0x10, 0x34, 0x12, 0xD0, 0x58, 0x40, 0x20, 0x01, 0x8D, 0x10, 0x14, 0x42,
-0xD0, 0x78, 0x41, 0x33, 0x06, 0x81, 0x00, 0x04, 0x02, 0x10, 0x48, 0x40, 0x20,
-0x01, 0x85, 0x04, 0x34, 0x52, 0x59, 0x48, 0x40, 0x23, 0x01, 0x89, 0x04, 0x44,
-0x12, 0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xB8, 0x86, 0x42, 0x03, 0x0A, 0x45, 0x31, 0x30, 0xE1, 0x40, 0x97, 0x04, 0x1F,
-0x08, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x80, 0x02, 0x1B, 0x06, 0x7C, 0x19, 0xF0,
-0x21, 0xC0, 0x87, 0x01, 0x1B, 0x1E, 0x4C, 0x28, 0xB1, 0xA1, 0xC0, 0x06, 0x40,
-0x17, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0x80, 0x07, 0x00, 0x0B, 0x0A, 0x4C, 0x28,
-0x70, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8,
-0x2F, 0x0A, 0xBF, 0x08, 0xFC, 0x0A, 0xF2, 0xCB, 0xC0, 0x2D, 0x00, 0xBF, 0x00,
-0x7C, 0x22, 0xF0, 0x8B, 0xC8, 0x2D, 0x02, 0xB7, 0x14, 0xDC, 0x52, 0xF0, 0x0B,
-0xC2, 0x3F, 0x00, 0x9F, 0x00, 0xFD, 0x83, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9B,
-0x08, 0x7C, 0x02, 0x70, 0x8B, 0xC8, 0x2E, 0x02, 0x97, 0x08, 0xFC, 0x22, 0xB0,
-0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8, 0x2F,
-0x05, 0xD3, 0x4C, 0xCC, 0x02, 0xF1, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x04, 0xFC,
-0x52, 0x30, 0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x22, 0xF0, 0x4B, 0xC0,
-0x2D, 0x05, 0x9F, 0x0C, 0x5C, 0x02, 0xB0, 0x0B, 0xC0, 0x2C, 0x00, 0xB3, 0x05,
-0x5C, 0x16, 0xB0, 0x0F, 0xC0, 0x2C, 0x00, 0xBF, 0x80, 0xCD, 0x02, 0x31, 0x0B,
-0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01,
-0x11, 0x0C, 0x45, 0x48, 0xD0, 0x01, 0x41, 0x07, 0x02, 0x11, 0x54, 0x74, 0x00,
-0x38, 0xC1, 0xC0, 0x90, 0x04, 0x11, 0x10, 0x44, 0x20, 0xD2, 0x41, 0x41, 0x07,
-0x21, 0x1D, 0x0C, 0x44, 0x40, 0x40, 0x01, 0x41, 0x04, 0x02, 0x1B, 0x00, 0x70,
-0x54, 0x10, 0x01, 0xC0, 0x96, 0x00, 0x03, 0x10, 0x45, 0x20, 0x50, 0x01, 0x40,
-0x71, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81,
-0x04, 0x04, 0x32, 0xD0, 0x88, 0x60, 0x23, 0x00, 0x81, 0x2C, 0x36, 0x02, 0x18,
-0x4C, 0x62, 0x21, 0x4B, 0x80, 0x08, 0x24, 0x02, 0xD0, 0xC8, 0x40, 0x21, 0x2D,
-0x8D, 0x44, 0x74, 0x12, 0x80, 0x88, 0x50, 0x20, 0x00, 0x85, 0x02, 0x14, 0x0A,
-0x50, 0x0C, 0x48, 0x22, 0x12, 0x8D, 0x08, 0x24, 0x02, 0x10, 0x08, 0x40, 0x48,
-0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91, 0x82,
-0x44, 0x42, 0xD0, 0x0D, 0x40, 0x27, 0x05, 0x91, 0x00, 0x74, 0x02, 0x10, 0x49,
-0x40, 0x25, 0x01, 0xD1, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x02, 0x8D,
-0x00, 0x64, 0x02, 0x10, 0x08, 0x40, 0x24, 0x01, 0x9D, 0x00, 0x74, 0x02, 0x50,
-0x0D, 0x40, 0x26, 0x00, 0x91, 0x00, 0x64, 0x02, 0x50, 0x29, 0x40, 0x61, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x42, 0x93, 0x00, 0x4D,
-0x02, 0xF0, 0x79, 0xC0, 0x67, 0x40, 0x93, 0x11, 0x7C, 0x02, 0x34, 0x39, 0xC1,
-0x25, 0x00, 0x93, 0x10, 0x6D, 0x4E, 0xF0, 0x69, 0xC0, 0xE5, 0x00, 0x9F, 0x00,
-0x7C, 0x8A, 0xB0, 0x09, 0xC0, 0x64, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x70, 0x09,
-0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x6D, 0x1A, 0x30, 0x29, 0xC0, 0x14, 0xA0, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x65, 0x00, 0x9F, 0x20, 0x7C, 0x26,
-0xF0, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x04, 0x3C, 0x02, 0xF0, 0x19, 0xD0, 0x24,
-0x00, 0x9F, 0x00, 0x4C, 0x26, 0xF0, 0x09, 0xC0, 0x67, 0x84, 0x9F, 0x00, 0x5C,
-0x22, 0x70, 0x09, 0xC0, 0x67, 0x08, 0x9B, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0,
-0x67, 0x82, 0x9F, 0x00, 0x5D, 0x02, 0xF0, 0x09, 0xC0, 0x5B, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x00, 0x0F, 0x00, 0x4E, 0x48, 0xF2,
-0x41, 0xE4, 0x87, 0x01, 0x1F, 0x08, 0x7C, 0x80, 0x70, 0x00, 0xC0, 0x84, 0x00,
-0x13, 0x01, 0x7C, 0x00, 0xF8, 0x21, 0xC4, 0x87, 0x08, 0x1F, 0x00, 0x5C, 0x08,
-0xF0, 0x01, 0xC0, 0x03, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x87,
-0x40, 0x13, 0x00, 0x0C, 0x00, 0xF0, 0xA0, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x00, 0x5D, 0x20, 0xC6, 0x1D, 0x70, 0x27,
-0x40, 0x5F, 0x04, 0x7D, 0x08, 0x74, 0x15, 0xD0, 0x27, 0xC0, 0x14, 0x00, 0x71,
-0x00, 0xDC, 0x09, 0xF0, 0x37, 0x60, 0x9F, 0x00, 0x5D, 0x00, 0x04, 0x01, 0x30,
-0x47, 0x40, 0x17, 0x40, 0x52, 0x00, 0x5C, 0x01, 0xD0, 0x26, 0x40, 0x17, 0x04,
-0x74, 0x82, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA0, 0xF2, 0x04, 0xCD, 0x00, 0x24, 0x0F, 0x50, 0x8C, 0x40,
-0x77, 0x00, 0xCD, 0x03, 0x34, 0x03, 0xD0, 0x2C, 0x41, 0x36, 0x00, 0xD1, 0x20,
-0x34, 0x47, 0xD2, 0x0C, 0x41, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x1C,
-0x40, 0x23, 0x08, 0x88, 0x20, 0x74, 0x03, 0xD0, 0x20, 0x60, 0x63, 0x00, 0x90,
-0x12, 0x05, 0x03, 0xD0, 0x1C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x04, 0x80, 0xA8, 0x10, 0xED, 0x00, 0xA4, 0x01, 0x50, 0x0E, 0x40, 0x3B,
-0x20, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0B, 0x60, 0x28, 0x00, 0xE1, 0x00, 0x94,
-0x09, 0x10, 0x0E, 0x41, 0x9B, 0x08, 0xCD, 0x04, 0xC4, 0x13, 0x12, 0x06, 0x40,
-0x2B, 0x00, 0xE9, 0x00, 0xB6, 0x03, 0xD0, 0x06, 0x40, 0x63, 0x00, 0xE5, 0x00,
-0x84, 0x02, 0xD0, 0x0E, 0x60, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x18, 0x48, 0x10, 0xFF, 0x01, 0xA5, 0x07, 0x70, 0x1E, 0x40, 0x5B, 0x00,
-0xED, 0x01, 0xBC, 0x87, 0xF0, 0x16, 0xC0, 0x7A, 0x42, 0xE1, 0x01, 0xBC, 0x07,
-0xD0, 0x16, 0x40, 0x7B, 0x00, 0xEF, 0x09, 0x9D, 0x5F, 0x70, 0x16, 0xE4, 0x73,
-0x00, 0xAB, 0x01, 0xBC, 0x07, 0xF0, 0x12, 0x80, 0x7B, 0x00, 0x21, 0x01, 0x8C,
-0x07, 0xF0, 0x1E, 0xD0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xB8, 0x05, 0x00, 0xDF, 0x16, 0x5C, 0x01, 0x70, 0x0D, 0xC0, 0x17, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xA1, 0x42, 0xD1, 0x37, 0x20, 0x1F, 0x00, 0x7C, 0x01, 0xF0,
-0x05, 0xC0, 0x27, 0x00, 0xDF, 0x08, 0x3C, 0x1B, 0x70, 0x05, 0xC0, 0x37, 0x40,
-0xD3, 0x00, 0x5C, 0x83, 0xF0, 0x0D, 0x80, 0x37, 0x00, 0x5B, 0x20, 0x7C, 0x02,
-0xF0, 0x0C, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20,
-0x4D, 0x00, 0xF7, 0x31, 0xCC, 0x13, 0xF0, 0x97, 0xC0, 0x7C, 0x00, 0xFF, 0x01,
-0xFC, 0x06, 0xB0, 0x9F, 0xC0, 0x7C, 0x00, 0x73, 0x09, 0xFC, 0x27, 0xF0, 0x1F,
-0xC0, 0x7F, 0x00, 0xFF, 0x81, 0xCC, 0x07, 0x70, 0x9F, 0xC0, 0x6C, 0x40, 0xB7,
-0x41, 0xCC, 0x07, 0xB0, 0x1A, 0xC0, 0x6C, 0x20, 0xBF, 0x21, 0xCC, 0x07, 0xF0,
-0x1B, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x0D,
-0x00, 0xEB, 0x00, 0x84, 0x03, 0xD0, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4,
-0x22, 0xD0, 0xC6, 0x50, 0x28, 0x30, 0x60, 0x18, 0x9C, 0x23, 0xD0, 0x0E, 0xC0,
-0x39, 0x02, 0xED, 0x04, 0x84, 0x13, 0x40, 0x03, 0xC0, 0x2A, 0x00, 0xE5, 0x00,
-0xAC, 0x23, 0x10, 0x0E, 0xC2, 0x2A, 0x00, 0xE9, 0x00, 0x85, 0x42, 0xD0, 0x0E,
-0x40, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
-0xE5, 0x10, 0x84, 0x23, 0xD0, 0x06, 0x42, 0x18, 0x04, 0x6D, 0x00, 0xB4, 0x02,
-0xD0, 0x06, 0x42, 0x38, 0x00, 0x61, 0x80, 0xB4, 0x02, 0xD0, 0x8A, 0x40, 0xBB,
-0x00, 0xED, 0x20, 0xC4, 0x4B, 0x42, 0x06, 0x40, 0x32, 0x00, 0xA5, 0x00, 0xA4,
-0x03, 0x90, 0x02, 0x40, 0x28, 0x00, 0xA5, 0x08, 0xA4, 0x03, 0xD0, 0x0A, 0x40,
-0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xD1,
-0x01, 0x04, 0x02, 0xD0, 0x28, 0x50, 0x80, 0x04, 0x8D, 0x47, 0x34, 0x02, 0xD0,
-0x05, 0x58, 0x34, 0x42, 0x01, 0x91, 0x14, 0xCE, 0xD0, 0x39, 0x40, 0x01, 0x20,
-0xCD, 0x00, 0x04, 0x07, 0x00, 0x00, 0x40, 0x32, 0x40, 0xC5, 0x00, 0x24, 0x03,
-0x10, 0x0C, 0x40, 0x22, 0x00, 0xC9, 0x00, 0x24, 0x0E, 0xD0, 0x8C, 0x40, 0x1B,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x05, 0x06, 0xF5, 0x20,
-0x4C, 0x02, 0xF0, 0xB9, 0xC1, 0xA4, 0x00, 0x1F, 0x05, 0x74, 0x82, 0xB0, 0x09,
-0xC0, 0x74, 0x00, 0x93, 0x03, 0x7C, 0x42, 0xD0, 0x39, 0xC1, 0xB7, 0x00, 0xFF,
-0x00, 0xCC, 0x07, 0x70, 0x05, 0xC0, 0x26, 0x40, 0x85, 0x00, 0xEC, 0x03, 0xB0,
-0x01, 0xC8, 0x24, 0x00, 0x57, 0x80, 0x6C, 0x0E, 0xF0, 0x0D, 0xC0, 0x57, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x07, 0x20, 0xDF, 0x00, 0x7C,
-0x28, 0xF0, 0x21, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF2, 0x19, 0xC0,
-0x27, 0x04, 0x9F, 0x02, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x17, 0x00, 0xCF, 0x00,
-0x7D, 0x03, 0xF0, 0x05, 0xC0, 0x23, 0x40, 0x9E, 0x00, 0x7C, 0x03, 0xF0, 0x01,
-0xC0, 0x27, 0x00, 0x5C, 0x00, 0x1C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x0B, 0x00, 0xFB, 0x00, 0xCC, 0x42,
-0xF0, 0x09, 0xC0, 0x2B, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x01, 0xC0, 0x34,
-0x00, 0xB3, 0x00, 0xB4, 0x00, 0x30, 0x03, 0xC0, 0x3C, 0x00, 0xDF, 0x00, 0xCC,
-0x03, 0xF0, 0x06, 0xC0, 0xEC, 0x00, 0x93, 0x08, 0x0C, 0x03, 0x34, 0x53, 0x40,
-0x38, 0x00, 0xE3, 0xC0, 0xCC, 0x56, 0x31, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6, 0x01, 0xD1, 0x00, 0x44, 0x14, 0xD0,
-0x39, 0x40, 0x47, 0x01, 0x91, 0x01, 0x74, 0x02, 0xC8, 0x11, 0x50, 0x34, 0x00,
-0x1F, 0x83, 0x74, 0x0C, 0x12, 0x31, 0x44, 0xC4, 0x0C, 0xDF, 0x00, 0x54, 0x03,
-0xF0, 0x25, 0x44, 0x24, 0x00, 0x91, 0x01, 0x45, 0x03, 0xB0, 0x04, 0x40, 0x35,
-0x00, 0xD3, 0x03, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x40, 0xD1, 0x00, 0x44, 0x04, 0xD0, 0x11,
-0x40, 0x67, 0x00, 0x11, 0x11, 0x76, 0x06, 0xD1, 0x19, 0x54, 0x34, 0x00, 0x91,
-0x01, 0x76, 0x46, 0x10, 0x39, 0x60, 0x64, 0x10, 0xDD, 0x40, 0x44, 0x03, 0xD0,
-0x25, 0x40, 0x24, 0x18, 0x91, 0x40, 0x54, 0x03, 0x10, 0x0D, 0x40, 0x25, 0x40,
-0xD1, 0x0A, 0x44, 0x02, 0x10, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0xC1, 0x40, 0x04, 0x00, 0xD0, 0x00, 0x42,
-0x23, 0x00, 0x01, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x20, 0x00, 0x81, 0x00,
-0x34, 0x02, 0x10, 0x00, 0x70, 0x00, 0x00, 0xC5, 0x00, 0x14, 0x03, 0x10, 0x00,
-0x50, 0x20, 0x20, 0x81, 0x00, 0x14, 0x03, 0x90, 0x0C, 0x48, 0x21, 0x00, 0xC9,
-0x80, 0x14, 0x02, 0x10, 0x0C, 0x4C, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x06, 0x00, 0xE3, 0x00, 0x4C, 0x02, 0xD0, 0x01, 0xC2, 0x27,
-0x00, 0x13, 0x00, 0x7E, 0x02, 0xC0, 0x03, 0xC0, 0x3C, 0x40, 0x91, 0x00, 0x7C,
-0x00, 0x38, 0x09, 0xC0, 0x24, 0x00, 0xFC, 0x00, 0xCC, 0x83, 0xD0, 0x05, 0xC0,
-0x24, 0x40, 0x93, 0x40, 0x5C, 0x03, 0x10, 0x09, 0xC0, 0x25, 0x00, 0xC3, 0x80,
-0x4C, 0x02, 0x34, 0x09, 0xC0, 0x07, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0xB8, 0x0D, 0x00, 0xF7, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x40,
-0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x00,
-0xF0, 0x03, 0xC4, 0x0F, 0x00, 0xFF, 0x00, 0xB8, 0x03, 0xF0, 0x03, 0xC4, 0x2F,
-0x40, 0xBF, 0x00, 0xEC, 0x03, 0x70, 0x0F, 0xC0, 0x2F, 0x00, 0xF7, 0x00, 0xFC,
-0x02, 0xF0, 0x0F, 0xC0, 0x17, 0xE0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x80, 0x7F, 0x00, 0xBF, 0x20, 0xCC, 0x13, 0x70, 0x1F, 0xC0, 0x7F, 0x02, 0xF3,
-0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x7B, 0x00, 0xFF, 0x01, 0x8C, 0x07, 0x30,
-0x1F, 0xC0, 0x7D, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x00,
-0xF3, 0x03, 0xEC, 0x07, 0xB0, 0x16, 0xC0, 0x5C, 0x00, 0x2B, 0x01, 0xEC, 0x05,
-0x30, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
-0x37, 0x00, 0x9D, 0x00, 0xEC, 0x0B, 0x10, 0x01, 0x40, 0x07, 0x01, 0x11, 0x00,
-0x44, 0x00, 0x14, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x20, 0x40, 0x00, 0x10, 0x01,
-0x40, 0x04, 0x00, 0x13, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x11,
-0x84, 0x4C, 0x04, 0x52, 0x1D, 0x40, 0x55, 0x00, 0x11, 0x01, 0x54, 0x03, 0xB4,
-0x01, 0x40, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
-0x00, 0x8D, 0x00, 0x04, 0x23, 0xD0, 0x0C, 0x60, 0x33, 0x01, 0xC1, 0x00, 0x44,
-0x83, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, 0x04, 0x03, 0x10, 0x0D, 0x48,
-0x34, 0x80, 0xC1, 0x00, 0x44, 0x03, 0x10, 0x0C, 0x40, 0x35, 0x00, 0xC1, 0x04,
-0x64, 0x03, 0x10, 0x04, 0x44, 0x16, 0x80, 0x59, 0x00, 0x66, 0x83, 0x5C, 0x00,
-0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00,
-0x9D, 0x21, 0x44, 0x03, 0x91, 0x01, 0x60, 0x03, 0x00, 0x11, 0x00, 0x60, 0x00,
-0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04,
-0x80, 0x19, 0x20, 0x44, 0x00, 0x10, 0x01, 0x40, 0x06, 0x00, 0x11, 0x00, 0x44,
-0x00, 0x50, 0x1D, 0x4C, 0x17, 0x04, 0x51, 0x10, 0x54, 0x0B, 0xDC, 0x11, 0x40,
-0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, 0x1F,
-0x33, 0x44, 0x03, 0xD0, 0x0D, 0xC0, 0x37, 0x10, 0xD3, 0x00, 0x4C, 0x03, 0x30,
-0x0D, 0xC0, 0x37, 0x00, 0xDD, 0x00, 0x4D, 0x03, 0x34, 0x0C, 0xC0, 0x30, 0x00,
-0xD3, 0x20, 0x0C, 0x03, 0x10, 0x0D, 0xC0, 0x31, 0x00, 0xD3, 0x00, 0x2C, 0x03,
-0xB0, 0x18, 0xC0, 0x92, 0x00, 0x9B, 0x01, 0x2C, 0x0B, 0x70, 0x59, 0xC2, 0x00,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x10, 0xAF, 0x00,
-0xFC, 0x03, 0x72, 0x03, 0xCB, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03,
-0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC8, 0x0E, 0x04, 0x37,
-0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x04, 0x3F, 0x00, 0xFC, 0x00, 0xF0,
-0x0F, 0xC0, 0x8D, 0x10, 0xBF, 0x08, 0xFC, 0x23, 0xB0, 0x09, 0xC0, 0x3F, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x06, 0x1F, 0x00, 0x7C,
-0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x01, 0x7C, 0x43, 0xF0, 0x0D, 0xC0,
-0x34, 0x1B, 0xD3, 0x00, 0x4C, 0x47, 0x30, 0x1D, 0xC0, 0x77, 0x00, 0xD7, 0x01,
-0x7C, 0x47, 0xF0, 0x0D, 0xC0, 0x34, 0x02, 0xDF, 0x00, 0x4D, 0x43, 0x30, 0x0D,
-0xC0, 0x35, 0x00, 0x9F, 0x06, 0x4C, 0x0B, 0x30, 0x01, 0xC0, 0x29, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x74, 0x10, 0x9D, 0x08, 0xF4, 0x03,
-0xD1, 0x21, 0x40, 0x04, 0x00, 0x1D, 0x03, 0x1C, 0x00, 0xD0, 0x81, 0x40, 0xC4,
-0x00, 0x01, 0x00, 0x44, 0x0C, 0x12, 0x31, 0x40, 0x47, 0x00, 0x15, 0x03, 0x74,
-0x04, 0xD0, 0x21, 0x40, 0x44, 0x00, 0x1D, 0x0B, 0x46, 0x40, 0xB2, 0xAD, 0x48,
-0xC4, 0x22, 0x8B, 0x07, 0x6C, 0x0B, 0xA0, 0x91, 0xC0, 0x4C, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0xF2, 0x00, 0x0D, 0x09, 0x74, 0x17, 0xD0,
-0x0C, 0x40, 0x32, 0x00, 0xDD, 0x04, 0x34, 0x0B, 0xD0, 0x2C, 0x40, 0xF0, 0x00,
-0xC1, 0x0C, 0x54, 0x03, 0x14, 0x4C, 0x40, 0x33, 0x00, 0xD9, 0x04, 0x34, 0x0B,
-0xD0, 0x4C, 0x40, 0xB0, 0x20, 0xD9, 0x00, 0x04, 0x0B, 0x10, 0x24, 0x40, 0x53,
-0x00, 0xC1, 0x01, 0x24, 0x22, 0x90, 0x99, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0x6D, 0x01, 0xB4, 0x47, 0xD8, 0x13,
-0x40, 0x4A, 0x00, 0x2D, 0x01, 0xB4, 0x04, 0xD0, 0x12, 0x40, 0x4C, 0x00, 0x21,
-0x01, 0xC4, 0x04, 0x10, 0x12, 0x40, 0x4F, 0x00, 0x2D, 0x08, 0xB4, 0x00, 0xD0,
-0x12, 0x40, 0x48, 0x00, 0x2D, 0x31, 0x84, 0x04, 0x90, 0x9F, 0x44, 0x5E, 0x08,
-0x79, 0x21, 0xA4, 0x0F, 0x90, 0x12, 0x48, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x23, 0xF0, 0x0C, 0xC0,
-0x32, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0xF0, 0x0D, 0xC0, 0x30, 0x00, 0xD3, 0x00,
-0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x37, 0x80, 0xC9, 0x00, 0x3C, 0x03, 0xD0, 0x0D,
-0x40, 0x30, 0x00, 0xDD, 0x00, 0x04, 0x23, 0x30, 0x04, 0xC0, 0x13, 0x14, 0xC3,
-0x00, 0x4C, 0x23, 0xB0, 0x88, 0xC6, 0x4B, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x83, 0xF0, 0x02, 0xC0, 0x0D,
-0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x02, 0x3F, 0x08, 0x7C,
-0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x36, 0x08, 0xFC, 0x10, 0xF0, 0x01, 0x80,
-0x0F, 0x00, 0x3E, 0x00, 0xBC, 0x84, 0xF9, 0x0F, 0xC8, 0x19, 0x00, 0x7F, 0x00,
-0xFC, 0x23, 0xF0, 0x03, 0xC8, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0xA0, 0x37, 0x10, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00,
-0xDF, 0x00, 0x7C, 0x07, 0x34, 0x1D, 0xD0, 0x30, 0x00, 0xD3, 0x01, 0x4D, 0x03,
-0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x1D, 0xD0, 0x34,
-0x00, 0xD7, 0x00, 0x4C, 0x03, 0xF0, 0x1C, 0xD0, 0x54, 0x00, 0xD3, 0x00, 0x4C,
-0x03, 0xD1, 0x09, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x88, 0x39, 0x00, 0x6D, 0x00, 0xB4, 0x2B, 0xD0, 0x02, 0x40, 0x0B, 0x00, 0x2D,
-0x00, 0xF4, 0x00, 0x10, 0x03, 0x40, 0x08, 0x00, 0x31, 0x00, 0x84, 0x00, 0xD0,
-0x02, 0x40, 0x0B, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x03, 0x40, 0x08, 0x10,
-0x2D, 0x00, 0xA4, 0x00, 0xD0, 0x0E, 0x40, 0x18, 0x40, 0xE1, 0x00, 0x94, 0x03,
-0xD0, 0x0E, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
-0x79, 0x00, 0xED, 0x03, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01,
-0xB4, 0x07, 0x10, 0x1E, 0x40, 0x7C, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E,
-0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x78, 0x00, 0xED,
-0x01, 0xA5, 0x07, 0xD0, 0x1F, 0x49, 0x58, 0x80, 0xF5, 0x01, 0x84, 0x07, 0xD0,
-0x1E, 0x42, 0x13, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33,
-0x00, 0xDD, 0x01, 0x34, 0x03, 0xD0, 0x01, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x34,
-0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0xD0, 0x00, 0x44,
-0x07, 0x00, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x00, 0x00, 0x0D, 0x00,
-0x24, 0x00, 0xD0, 0x5C, 0x44, 0xD0, 0x01, 0xC5, 0x13, 0x14, 0x4F, 0xD8, 0x5D,
-0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00,
-0x7F, 0x02, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01,
-0x30, 0x05, 0xC0, 0x14, 0x50, 0x53, 0x00, 0x4C, 0x01, 0xF0, 0x05, 0xC0, 0x17,
-0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0x44,
-0x01, 0xD0, 0x27, 0xC0, 0xDC, 0x00, 0x67, 0x07, 0x8C, 0x01, 0xF0, 0x57, 0x44,
-0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F,
-0x12, 0x7C, 0x00, 0xF2, 0x23, 0xC0, 0x0F, 0x00, 0x3F, 0x02, 0xFC, 0x00, 0xF0,
-0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x23, 0xC0, 0x0F, 0x00,
-0x3F, 0x02, 0xFC, 0x80, 0xF3, 0x23, 0xC0, 0x8F, 0x00, 0x3F, 0x22, 0xDC, 0x00,
-0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1B, 0x00, 0x7C, 0x20, 0xF0, 0x21, 0xC0, 0x4B,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x05,
-0x4C, 0x06, 0xF0, 0x99, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x67, 0x40, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x67, 0x40, 0x93,
-0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x4C, 0x22, 0xF0,
-0x49, 0xE0, 0xA7, 0x00, 0x9F, 0x00, 0x5E, 0x0A, 0x30, 0x09, 0xC0, 0x40, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6, 0x04, 0x9D, 0x12, 0x44,
-0x02, 0xD0, 0x29, 0x41, 0x20, 0x00, 0x91, 0x00, 0x74, 0x0E, 0xD0, 0x19, 0x41,
-0x27, 0x00, 0x91, 0x03, 0x74, 0x02, 0xD0, 0x19, 0x40, 0x67, 0x00, 0x91, 0x02,
-0x74, 0x02, 0xD8, 0x39, 0x40, 0x27, 0x01, 0x9D, 0x00, 0x45, 0x86, 0xD0, 0x39,
-0x40, 0x67, 0x14, 0x97, 0x0A, 0x44, 0x0A, 0x56, 0x49, 0x40, 0x04, 0x08, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x9D, 0x00, 0x64, 0x2A,
-0xD0, 0x09, 0x40, 0x2C, 0x08, 0xB1, 0x00, 0xF4, 0x0E, 0xD0, 0x1B, 0x40, 0xAF,
-0x02, 0xB1, 0x03, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x2F, 0x02, 0xB1, 0x02, 0xF4,
-0x0A, 0xD1, 0x1B, 0x41, 0x2F, 0x01, 0xA9, 0x00, 0xC6, 0x02, 0x91, 0x09, 0x40,
-0x25, 0x00, 0x9D, 0x42, 0x54, 0x02, 0x15, 0x49, 0x40, 0x60, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x14, 0x25, 0x12, 0xD0,
-0x0A, 0x40, 0x2C, 0x00, 0xE1, 0x80, 0xB4, 0x02, 0xD0, 0x0A, 0x4A, 0x2B, 0x00,
-0xA1, 0x00, 0xB4, 0x06, 0xD0, 0x0E, 0x40, 0x6B, 0x00, 0xA1, 0x00, 0xB4, 0x02,
-0xD2, 0x0A, 0x40, 0x2B, 0x00, 0xED, 0x08, 0x84, 0x02, 0xD2, 0x0C, 0x4A, 0x23,
-0x00, 0x95, 0x00, 0x64, 0x06, 0x58, 0x48, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x04, 0x6C, 0x28, 0xF0, 0xA1,
-0xC8, 0x84, 0x42, 0x13, 0x0A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x87, 0x02, 0x13,
-0x0A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x87, 0x02, 0x13, 0x0A, 0x7C, 0x28, 0xD0,
-0xA1, 0xC0, 0x87, 0x02, 0x0F, 0x82, 0xCC, 0x01, 0xF8, 0x01, 0xCA, 0x05, 0x00,
-0x1F, 0x00, 0x5C, 0x28, 0x30, 0xA1, 0xC0, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x19, 0xB8, 0x27, 0x05, 0xBF, 0x14, 0x5C, 0x22, 0xF0, 0x09, 0xD0,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x27, 0x20, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x9F, 0x04, 0x7C, 0x02, 0xE0, 0x0B, 0xC0, 0x2B, 0x00, 0xA7,
-0x40, 0xDC, 0x02, 0xF0, 0x8B, 0xD4, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0x80, 0x2F, 0x00, 0xBF, 0x14, 0xFC, 0x32, 0x30, 0x0A, 0xC0, 0x24,
-0x00, 0xAF, 0x08, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x00, 0xFC,
-0x02, 0xF0, 0x8B, 0xC8, 0x2F, 0x08, 0xBF, 0x00, 0xFC, 0x22, 0x70, 0x0B, 0xC0,
-0x2F, 0x00, 0xB3, 0x28, 0xCE, 0x02, 0xF0, 0x0A, 0xC0, 0x2E, 0x00, 0xB3, 0x00,
-0xFC, 0x02, 0xC1, 0x0B, 0xC2, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1C, 0x00, 0x07, 0x05, 0x1D, 0x04, 0x74, 0x30, 0x10, 0x01, 0x41, 0x04, 0x04,
-0x1D, 0x20, 0x74, 0x50, 0xD0, 0x41, 0x4C, 0x07, 0x01, 0x11, 0x10, 0x74, 0x40,
-0xD0, 0x01, 0x40, 0x07, 0x05, 0x1D, 0x04, 0x74, 0x10, 0xD0, 0x01, 0x41, 0x07,
-0x04, 0x01, 0x00, 0x44, 0x00, 0xD0, 0x01, 0xC0, 0x16, 0x00, 0x1B, 0x00, 0x74,
-0x00, 0xD0, 0x01, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA2, 0x23, 0x21, 0x8D, 0x14, 0x34, 0x12, 0x10, 0x48, 0x40, 0x20, 0x00, 0x8D,
-0x00, 0x34, 0x12, 0xD0, 0x48, 0x41, 0x23, 0x01, 0x81, 0x04, 0x34, 0x02, 0xD0,
-0x08, 0x40, 0x23, 0x01, 0x8D, 0x14, 0x34, 0x12, 0x50, 0x48, 0x40, 0x27, 0x00,
-0x85, 0x00, 0x05, 0x02, 0xD0, 0x08, 0x44, 0x24, 0x00, 0x85, 0x40, 0x34, 0x82,
-0xD1, 0x08, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
-0x25, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x12, 0x09, 0x50, 0x24, 0x20, 0x9D, 0x00,
-0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x40, 0x99, 0x00, 0x74, 0x02, 0xD0, 0x09,
-0x40, 0x27, 0x00, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x20, 0x91,
-0x00, 0x64, 0x82, 0xD1, 0x19, 0x40, 0x26, 0x00, 0x9D, 0x01, 0x74, 0x0A, 0xD8,
-0x09, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x88, 0x27,
-0x00, 0x9D, 0x01, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF1, 0x09, 0xC0, 0x27, 0x20, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0x40,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00,
-0x4C, 0x02, 0xF0, 0x09, 0x80, 0x20, 0x00, 0x97, 0x00, 0x7C, 0x06, 0xF0, 0x49,
-0xCA, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00,
-0x9F, 0x08, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x40, 0x7C, 0x02,
-0xF0, 0x09, 0xC8, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF1, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC6, 0x27, 0x50, 0x9F, 0x80, 0x5C,
-0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x9B, 0x00, 0x7E, 0x12, 0xF0, 0x49, 0xD1,
-0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F,
-0x04, 0x3C, 0x40, 0x30, 0x01, 0xD0, 0x06, 0x00, 0x13, 0x00, 0x4D, 0x00, 0xF0,
-0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x11, 0xC0, 0x06, 0x00,
-0x1F, 0x01, 0x7C, 0x20, 0xF0, 0x91, 0xC0, 0x07, 0x04, 0x13, 0x80, 0x7C, 0x40,
-0xF0, 0x11, 0xC4, 0x84, 0x04, 0x1F, 0x10, 0x5C, 0x48, 0xF0, 0x21, 0xC0, 0x53,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x9C, 0x00, 0x7D, 0x12,
-0xF4, 0x01, 0x12, 0x17, 0xC0, 0x14, 0x20, 0x71, 0x0A, 0xEC, 0x01, 0xD0, 0x87,
-0x48, 0x9F, 0x80, 0x7D, 0x00, 0xF4, 0x6D, 0xD0, 0x07, 0xC0, 0x1E, 0x00, 0x7D,
-0x00, 0xF4, 0x29, 0x70, 0x07, 0xC0, 0x99, 0x00, 0x71, 0x81, 0xCC, 0x0D, 0xD1,
-0x16, 0x44, 0x1C, 0x20, 0x7D, 0x02, 0xC4, 0x15, 0xC0, 0x27, 0x40, 0x43, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xF2, 0x03, 0xCD, 0x01, 0x34,
-0x03, 0x10, 0x9D, 0x41, 0x30, 0x00, 0xC1, 0x02, 0x04, 0x13, 0xD0, 0x2C, 0x48,
-0xB7, 0x01, 0xCD, 0x10, 0x34, 0x0B, 0xD0, 0x0C, 0x42, 0x30, 0x01, 0xCD, 0x00,
-0x34, 0x07, 0xD0, 0x1C, 0x40, 0x31, 0x00, 0xD1, 0x08, 0x14, 0x09, 0xD8, 0x9C,
-0x40, 0x31, 0x10, 0x0D, 0x01, 0x14, 0x0F, 0xD0, 0x8D, 0x40, 0x43, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0x34, 0x01,
-0x10, 0x0F, 0x40, 0x78, 0x41, 0xF1, 0x01, 0x84, 0x43, 0xD0, 0x0E, 0x41, 0x3B,
-0x10, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1E, 0x60, 0x38, 0x00, 0xED, 0x10, 0xB4,
-0x01, 0x50, 0x0E, 0x42, 0x39, 0x40, 0x21, 0x00, 0xA4, 0x08, 0xD0, 0x0E, 0x40,
-0x29, 0x00, 0x7D, 0x11, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x13, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x58, 0x08, 0xEF, 0x01, 0xBC, 0x07, 0x30,
-0x1E, 0xC0, 0x7C, 0x05, 0xE3, 0x01, 0x84, 0x07, 0xF0, 0x16, 0xC0, 0x7B, 0x00,
-0xED, 0x01, 0xB4, 0x05, 0xF0, 0x1F, 0x40, 0x58, 0x00, 0xEF, 0x01, 0xBC, 0x07,
-0xF0, 0x1E, 0xC0, 0x7D, 0x00, 0xE3, 0x01, 0x9C, 0x05, 0xF0, 0x0E, 0xC0, 0x69,
-0x10, 0x2F, 0x01, 0x9C, 0x05, 0xF2, 0x1E, 0xC4, 0x53, 0x60, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xBA, 0x15, 0x00, 0xDF, 0x20, 0x7C, 0x02, 0xF4, 0x0D,
-0xC8, 0x35, 0x23, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F,
-0x00, 0x7C, 0x01, 0xF0, 0x09, 0xD8, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC4, 0x25, 0x80, 0xDF, 0x00, 0x5C, 0x00, 0xF2, 0x0D, 0xC0, 0x26, 0x00,
-0x8F, 0x20, 0x7C, 0x00, 0xF2, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xA0, 0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x87, 0xF9, 0x0F, 0xC0,
-0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x25, 0xF0, 0x1E, 0xC0, 0x7C, 0x00, 0xFF, 0x09,
-0xDC, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x0A, 0x7F, 0x81, 0xCC, 0x87, 0xF0, 0x17,
-0xC0, 0x5F, 0x22, 0xF3, 0x01, 0xCC, 0x25, 0x30, 0x1A, 0xC0, 0x78, 0x02, 0x23,
-0x01, 0xCC, 0x06, 0xF0, 0x9B, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0x88, 0x39, 0x22, 0x6D, 0x00, 0xB4, 0x19, 0xD8, 0x46, 0x40, 0x3B,
-0x05, 0xED, 0x04, 0xB4, 0x83, 0xD0, 0x8E, 0x40, 0x38, 0x00, 0x6D, 0x00, 0xB4,
-0x88, 0xD0, 0x2E, 0x40, 0x3B, 0x00, 0xAD, 0x18, 0x85, 0x0A, 0xD0, 0xAE, 0x40,
-0x1F, 0x03, 0x21, 0x84, 0xC4, 0x01, 0xB0, 0x4A, 0x40, 0xA8, 0x02, 0x2F, 0x00,
-0x94, 0x02, 0xD0, 0x8A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x19, 0x00, 0xED, 0x00, 0xB4, 0x81, 0xD0, 0x8A, 0x41, 0x39, 0x20,
-0x6D, 0x90, 0xB4, 0x08, 0xD1, 0x23, 0x40, 0x38, 0x00, 0xED, 0x20, 0x96, 0x23,
-0xD0, 0x0E, 0x40, 0x1B, 0x10, 0xFD, 0x00, 0x84, 0x03, 0xD0, 0x22, 0x40, 0x3B,
-0x60, 0xB1, 0x00, 0xD6, 0x01, 0x11, 0x0E, 0x48, 0x28, 0x00, 0x25, 0x0A, 0x84,
-0x40, 0xD0, 0x8A, 0x41, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x28, 0x05, 0x00, 0x8D, 0x03, 0x74, 0x00, 0xD0, 0x30, 0x44, 0xF3, 0x00, 0x1D,
-0x03, 0x74, 0x02, 0xD0, 0x08, 0x40, 0xC0, 0x00, 0x0D, 0x02, 0x74, 0x0C, 0xD0,
-0x39, 0x00, 0xE7, 0x00, 0x9D, 0x02, 0x44, 0x0E, 0xD0, 0x08, 0x40, 0xE3, 0x00,
-0x81, 0x02, 0x14, 0x08, 0x90, 0x1C, 0x44, 0x20, 0x04, 0x0D, 0x00, 0x56, 0x0C,
-0xD0, 0x28, 0x41, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x28,
-0x25, 0x00, 0x1F, 0x06, 0x7E, 0x02, 0xD8, 0x91, 0xC8, 0xB9, 0x00, 0x1F, 0x01,
-0x7C, 0x16, 0xF0, 0x59, 0xC0, 0x84, 0x04, 0x1D, 0x07, 0x5C, 0x06, 0xF0, 0x19,
-0xC0, 0x27, 0x04, 0x9F, 0x01, 0x4C, 0x06, 0xF0, 0x58, 0xC0, 0x67, 0x02, 0xC3,
-0x00, 0x1C, 0x4D, 0x10, 0x8C, 0xD0, 0xE0, 0x01, 0x17, 0x00, 0x4C, 0x0E, 0xF0,
-0x01, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27,
-0x00, 0x9F, 0x02, 0x7C, 0x82, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0x9F, 0x10, 0x7C,
-0x0A, 0xF0, 0x09, 0xC0, 0x07, 0x08, 0x1F, 0x02, 0x7C, 0x6A, 0xF0, 0x89, 0xC1,
-0xA7, 0x04, 0x9F, 0x10, 0x7C, 0x60, 0xF0, 0x09, 0xC8, 0x87, 0x02, 0x1F, 0x23,
-0x6C, 0x00, 0xF0, 0x8D, 0xC2, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
-0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2D, 0x00,
-0x33, 0x10, 0xFC, 0x02, 0x30, 0x0B, 0xE2, 0x3F, 0x04, 0xB3, 0x00, 0xCC, 0x00,
-0x38, 0x0B, 0xC0, 0x2F, 0x04, 0xBF, 0x10, 0xFC, 0x02, 0x30, 0x03, 0xC2, 0x2C,
-0x80, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xC0, 0x2C, 0x00, 0x7F, 0x10, 0xCC,
-0x41, 0x31, 0x0F, 0xC0, 0x2D, 0x10, 0x33, 0x00, 0xFC, 0x42, 0x30, 0x0A, 0xC0,
-0x04, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x00, 0x91,
-0x05, 0x74, 0x06, 0x12, 0x39, 0x40, 0x37, 0x00, 0x91, 0x81, 0x44, 0x04, 0xB8,
-0x19, 0x44, 0x47, 0x30, 0x9D, 0x43, 0x5C, 0x0E, 0x10, 0x31, 0x40, 0x65, 0x00,
-0x1F, 0x01, 0x44, 0x0C, 0x10, 0x11, 0x40, 0x44, 0x01, 0x5D, 0x02, 0x4C, 0x0C,
-0x70, 0x3D, 0x40, 0xE4, 0x00, 0x95, 0x01, 0x74, 0x0C, 0x12, 0x71, 0x40, 0x04,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xC4, 0x40, 0x11, 0x01,
-0x74, 0x06, 0x14, 0x39, 0x44, 0x37, 0x00, 0x11, 0x03, 0x44, 0x46, 0x1A, 0x11,
-0x41, 0x67, 0x00, 0x9D, 0x43, 0x74, 0x06, 0x10, 0x11, 0x40, 0x44, 0x04, 0x11,
-0x01, 0x44, 0x06, 0x10, 0x19, 0x64, 0x66, 0x00, 0xDD, 0x02, 0x44, 0x45, 0x10,
-0xA5, 0x40, 0x66, 0x20, 0x19, 0x81, 0x74, 0x0E, 0x11, 0x11, 0x54, 0x04, 0x08,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x01, 0x00, 0x34,
-0x02, 0x10, 0x00, 0x68, 0x37, 0x00, 0x81, 0x00, 0x05, 0x02, 0x10, 0x00, 0x40,
-0x63, 0x00, 0x0D, 0x00, 0x16, 0x00, 0x14, 0x08, 0x50, 0x00, 0x40, 0x81, 0x00,
-0x05, 0x02, 0x1C, 0x09, 0x64, 0x02, 0x00, 0x1D, 0x00, 0x45, 0x00, 0x94, 0x0D,
-0x40, 0x02, 0x00, 0x0D, 0x00, 0x34, 0x02, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x00, 0x11, 0x00, 0x7C, 0x00,
-0x30, 0x09, 0x60, 0x3F, 0x40, 0x13, 0x00, 0x4C, 0x00, 0x14, 0x01, 0xC0, 0x27,
-0x20, 0x9F, 0x00, 0x7E, 0x82, 0x30, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x4C,
-0x00, 0x30, 0x01, 0xC0, 0x26, 0x00, 0x1F, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xD0,
-0x27, 0x08, 0x1B, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xD0, 0x04, 0x64, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x00, 0xF1,
-0x03, 0xC2, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x80, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
-0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x08, 0x2F, 0x00, 0xFC, 0x00,
-0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x2F, 0x40, 0xCC, 0x00, 0x59, 0x0F, 0xC8, 0x2D,
-0x00, 0x37, 0x80, 0xFC, 0x02, 0xF4, 0x0B, 0xC8, 0x17, 0x60, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA0, 0x0F, 0x00, 0x3F, 0x41, 0xEC, 0x02, 0xF0, 0x0F,
-0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xBE, 0x07, 0xF0, 0x03, 0xC1, 0x3E, 0x00, 0xA3,
-0x01, 0xDC, 0x00, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0xAC, 0x01, 0xDC, 0x33, 0x34,
-0x3F, 0xC0, 0x2F, 0x80, 0xA3, 0x01, 0xFC, 0x53, 0xF0, 0x83, 0xC0, 0x4F, 0x00,
-0x33, 0x01, 0xBC, 0x0C, 0x30, 0x13, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x08, 0x27, 0x12, 0x1D, 0x00, 0x44, 0x02, 0xD0, 0x0F, 0x44,
-0x04, 0x14, 0x1D, 0x00, 0x55, 0x07, 0xD0, 0x21, 0x50, 0x3C, 0x00, 0x91, 0x41,
-0x44, 0x02, 0x10, 0x01, 0x40, 0x27, 0x20, 0x9D, 0x11, 0x54, 0x3B, 0x10, 0x4D,
-0x40, 0x27, 0x20, 0x91, 0x10, 0x74, 0x0F, 0xD2, 0x0B, 0x40, 0x07, 0x08, 0x11,
-0x80, 0x74, 0x00, 0x14, 0x05, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0xA0, 0x03, 0x00, 0x0D, 0x00, 0x05, 0x00, 0xD0, 0x0C, 0x40, 0x20,
-0x08, 0x8D, 0x00, 0x35, 0x02, 0x50, 0x00, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x14,
-0x02, 0x10, 0x08, 0x44, 0x03, 0x00, 0x9D, 0x00, 0x14, 0x03, 0x90, 0x0C, 0x60,
-0x23, 0x00, 0x81, 0x04, 0x34, 0x03, 0xD0, 0x58, 0x48, 0x23, 0x15, 0x81, 0x14,
-0x34, 0x10, 0x10, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0x88, 0x65, 0x10, 0x1D, 0x03, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x44, 0x00,
-0x1D, 0x01, 0x54, 0x12, 0xD0, 0x00, 0x40, 0x35, 0x00, 0xD1, 0x00, 0x44, 0x06,
-0x14, 0x19, 0x40, 0x47, 0x14, 0x9D, 0x00, 0x54, 0x03, 0x90, 0x0D, 0x40, 0x27,
-0x42, 0x91, 0x20, 0x74, 0x03, 0xD0, 0x1D, 0x40, 0x23, 0x00, 0x91, 0x00, 0x74,
-0x04, 0x10, 0x05, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x88, 0x47, 0x04, 0x1F, 0x01, 0x4C, 0x8E, 0xF1, 0x0D, 0xC8, 0x64, 0x20, 0x0F,
-0x43, 0x7D, 0x07, 0x70, 0x55, 0xC0, 0x35, 0x40, 0xC3, 0x00, 0x5C, 0x14, 0x30,
-0x59, 0xC0, 0xE7, 0x00, 0x8E, 0x00, 0x5C, 0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x20,
-0xD1, 0x20, 0x7C, 0x03, 0xF2, 0x19, 0xC2, 0x47, 0x00, 0x13, 0x81, 0x3C, 0x02,
-0x34, 0x01, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80,
-0x2D, 0x08, 0x3F, 0x00, 0xFC, 0x42, 0xF0, 0x0E, 0xC0, 0x2F, 0x00, 0x3F, 0x00,
-0xFC, 0x03, 0xF0, 0x87, 0xC0, 0x38, 0x00, 0xFF, 0x00, 0xBC, 0x42, 0xF0, 0x0B,
-0xC1, 0x2F, 0x00, 0xBF, 0x04, 0xBC, 0x03, 0x70, 0x0F, 0xC0, 0x7B, 0x20, 0xBF,
-0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC0, 0x4F, 0x02, 0x3F, 0x09, 0xFC, 0x02, 0xF0,
-0x07, 0xC1, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x05,
-0x00, 0x13, 0x02, 0x5D, 0x0A, 0xF0, 0x0D, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C,
-0x82, 0x30, 0x27, 0xC0, 0x34, 0x44, 0xD3, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC6,
-0x87, 0x04, 0x9F, 0x00, 0x5C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xD3, 0x20,
-0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x64, 0x00, 0x93, 0x01, 0x7C, 0x02, 0x30, 0x01,
-0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00,
-0x01, 0x00, 0x44, 0x06, 0xD0, 0x2F, 0xC5, 0x26, 0x00, 0x9B, 0x20, 0x74, 0x02,
-0xB0, 0x45, 0x40, 0x7C, 0x40, 0xD1, 0x01, 0x6C, 0x02, 0xD0, 0x29, 0x40, 0x87,
-0x00, 0x9D, 0x00, 0xC4, 0x03, 0x12, 0x0D, 0x40, 0xB7, 0x06, 0x91, 0x0A, 0xC4,
-0x03, 0xD0, 0x0D, 0x50, 0xE4, 0x00, 0x91, 0x03, 0x74, 0x42, 0x10, 0x05, 0x40,
-0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x80, 0x01,
-0x12, 0x04, 0x20, 0xD0, 0x3C, 0x41, 0x00, 0x00, 0x81, 0x09, 0x24, 0x03, 0x10,
-0x00, 0x40, 0x30, 0x20, 0x8D, 0x13, 0x24, 0x08, 0x90, 0x20, 0x40, 0x83, 0x00,
-0xCD, 0x00, 0x14, 0x03, 0x50, 0x0C, 0x00, 0x23, 0x00, 0x81, 0x02, 0x04, 0x03,
-0xC0, 0x08, 0x40, 0x90, 0x14, 0x41, 0x12, 0x34, 0x85, 0x10, 0x08, 0x40, 0x1F,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x68, 0x40, 0x21, 0x01,
-0x84, 0x07, 0xD0, 0x1C, 0x40, 0x5A, 0x00, 0xE9, 0x01, 0xF4, 0x07, 0x90, 0x10,
-0x54, 0x70, 0x26, 0xAD, 0x91, 0xA4, 0x05, 0xD0, 0x12, 0x08, 0x6B, 0x02, 0xFD,
-0x01, 0x84, 0x07, 0x10, 0x1E, 0x40, 0x6B, 0x00, 0xB5, 0x01, 0x84, 0x07, 0xD0,
-0x9A, 0x40, 0x58, 0x02, 0x61, 0x81, 0xF4, 0x0D, 0x12, 0x9E, 0x40, 0x13, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x24, 0x02, 0x11, 0x00, 0x1D,
-0x21, 0xF0, 0x0C, 0x40, 0xB4, 0x00, 0xC3, 0x02, 0x3C, 0x03, 0x30, 0x40, 0xC0,
-0x30, 0x02, 0xCF, 0x00, 0x2C, 0x00, 0xB3, 0x84, 0xC0, 0x13, 0x8A, 0xCF, 0x00,
-0x5C, 0x03, 0x70, 0x0C, 0xC0, 0x27, 0x40, 0x83, 0x08, 0x0C, 0x03, 0xF0, 0x0C,
-0xC0, 0x34, 0x02, 0xC3, 0x04, 0x3C, 0x01, 0x30, 0x08, 0xC0, 0x4B, 0x40, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x00, 0x7F, 0x88, 0xFC, 0x01,
-0xC0, 0x0F, 0xC1, 0x1D, 0x00, 0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x03, 0xC0, 0xBF,
-0x06, 0xF3, 0x08, 0xFC, 0x21, 0xF0, 0x8F, 0xC8, 0x3F, 0xA2, 0xFF, 0x08, 0xFC,
-0x23, 0xF0, 0x0F, 0xC0, 0x3E, 0x02, 0xBB, 0x20, 0xFD, 0x43, 0xF0, 0x0F, 0xC0,
-0x3F, 0x02, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x0F, 0xC2, 0x0B, 0x60, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x2F, 0x00, 0x0F, 0x00, 0x4C, 0x01, 0xF0,
-0x4D, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF8, 0x01, 0xC0, 0xB6, 0x40,
-0xD3, 0x01, 0x7C, 0x81, 0xF2, 0x05, 0xC8, 0x77, 0x00, 0x93, 0x00, 0x6C, 0x23,
-0x30, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x29, 0xC0, 0x54,
-0x00, 0x53, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x56, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0x88, 0x29, 0x00, 0x2D, 0x00, 0x84, 0x03, 0xD0, 0x0E,
-0x41, 0x3B, 0x00, 0x6D, 0x00, 0xB4, 0x03, 0xD0, 0x03, 0x50, 0x38, 0x01, 0xE1,
-0x00, 0x84, 0x03, 0xD1, 0x0E, 0x40, 0x3F, 0x00, 0xA1, 0x00, 0x94, 0x83, 0x10,
-0x0E, 0x40, 0x3B, 0x00, 0xA1, 0x00, 0xB6, 0x13, 0xD0, 0x8A, 0x40, 0x19, 0x00,
-0x61, 0x00, 0x84, 0x03, 0xD2, 0x0E, 0x40, 0x48, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x00, 0x69, 0x00, 0x3D, 0x01, 0x84, 0x0F, 0xD1, 0x5E, 0x40,
-0x7B, 0x00, 0xED, 0x81, 0xB4, 0x07, 0xD2, 0x12, 0x40, 0x71, 0x00, 0xE1, 0x11,
-0x94, 0x07, 0xD0, 0x16, 0x40, 0x7B, 0x00, 0xB9, 0x43, 0x24, 0x07, 0x50, 0x1E,
-0x40, 0x73, 0x00, 0xED, 0x01, 0xB4, 0x17, 0xD0, 0x1C, 0x41, 0x78, 0x00, 0xE1,
-0x01, 0x84, 0x07, 0xD0, 0x1A, 0x40, 0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x28, 0x73, 0x10, 0xCD, 0x40, 0x04, 0x0F, 0xD0, 0x0C, 0x40, 0xB3,
-0x00, 0xCD, 0x02, 0x34, 0x03, 0xD0, 0x69, 0x40, 0x37, 0x00, 0xC1, 0x00, 0x06,
-0x27, 0xD0, 0x9D, 0x40, 0x33, 0x00, 0x99, 0x00, 0x14, 0x03, 0x10, 0x0D, 0x40,
-0x77, 0x02, 0x89, 0x08, 0x34, 0x03, 0xD0, 0x6D, 0x42, 0x31, 0x00, 0xD1, 0x00,
-0x44, 0x03, 0xD0, 0x0C, 0x50, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x17, 0xA8, 0x5D, 0x01, 0x7F, 0x02, 0xCD, 0x05, 0xF0, 0x05, 0xC0, 0x5F, 0x04,
-0x7D, 0x0B, 0x7C, 0x81, 0xF0, 0x37, 0xC0, 0x15, 0x00, 0x53, 0x00, 0xDC, 0x09,
-0xF0, 0xA7, 0xC0, 0x1F, 0x41, 0x5B, 0x00, 0x6C, 0x01, 0x34, 0x05, 0xC0, 0x17,
-0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xE0, 0x14, 0x40, 0x53, 0x00, 0x4D,
-0x01, 0xF0, 0x05, 0xC0, 0x5E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x00, 0x07, 0x00, 0x1F, 0x12, 0x7C, 0x00, 0xF0, 0x01, 0xCC, 0x07, 0x00, 0x1F,
-0x0A, 0x7C, 0x00, 0xF8, 0x81, 0x40, 0x04, 0x10, 0x1F, 0x02, 0x5C, 0x48, 0xF8,
-0x21, 0xC2, 0x07, 0x01, 0x17, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0xC0, 0x87, 0x40,
-0x17, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x04,
-0xF0, 0x01, 0xC8, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08,
-0x23, 0x00, 0x9B, 0x00, 0x4E, 0x62, 0xF0, 0x19, 0xC0, 0x27, 0x04, 0x87, 0x04,
-0x4C, 0x82, 0xF0, 0x09, 0xC4, 0x24, 0x10, 0x93, 0x40, 0x7C, 0x02, 0xF2, 0x09,
-0xC0, 0x24, 0x00, 0x9E, 0x80, 0x2C, 0x02, 0x70, 0x09, 0xC0, 0x64, 0x08, 0x93,
-0x05, 0x78, 0x06, 0xF0, 0x09, 0x40, 0x26, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0x30,
-0x39, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26,
-0x00, 0x81, 0x04, 0x44, 0x0A, 0xD0, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x10, 0x44,
-0x02, 0xD0, 0x09, 0xC0, 0x26, 0x40, 0x91, 0x01, 0x74, 0x16, 0xD0, 0x19, 0x40,
-0xA4, 0x00, 0x9D, 0x80, 0x4C, 0x82, 0x10, 0x09, 0x40, 0x24, 0x41, 0x91, 0x01,
-0x74, 0x06, 0xD2, 0x09, 0x40, 0xA4, 0x20, 0x9D, 0x03, 0x44, 0x02, 0x12, 0x08,
-0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x08,
-0x99, 0x00, 0x44, 0x8A, 0xD0, 0x69, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x82,
-0x50, 0x09, 0x40, 0x24, 0x02, 0x99, 0x21, 0x56, 0x12, 0x90, 0x69, 0x42, 0x24,
-0x86, 0x9D, 0x00, 0x64, 0x02, 0x50, 0x09, 0x40, 0x24, 0x02, 0x91, 0x00, 0x74,
-0x22, 0xD0, 0x09, 0x40, 0x67, 0x00, 0xBD, 0x04, 0xC4, 0x02, 0x1C, 0x0F, 0x40,
-0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x01, 0x91,
-0x00, 0x04, 0x82, 0xD0, 0x68, 0x40, 0x23, 0x00, 0x8D, 0x02, 0x04, 0x02, 0xD2,
-0x48, 0x40, 0x30, 0x01, 0xC9, 0x00, 0x34, 0x1A, 0xD8, 0x08, 0x41, 0x20, 0x80,
-0x8D, 0x00, 0x04, 0x22, 0x10, 0x08, 0x50, 0x20, 0x01, 0x81, 0x00, 0x34, 0x12,
-0xD0, 0x48, 0x40, 0x69, 0x00, 0xAD, 0x01, 0x84, 0x06, 0x00, 0x0B, 0x40, 0x40,
-0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x22, 0x1B, 0x0A,
-0x45, 0x18, 0xF0, 0x21, 0xC0, 0x87, 0x02, 0x1F, 0x06, 0x4C, 0x00, 0xF0, 0xA1,
-0x50, 0x84, 0x02, 0x1B, 0x00, 0x5C, 0x08, 0xB0, 0x61, 0xD0, 0x84, 0x00, 0x1F,
-0x0A, 0x6C, 0x58, 0x71, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x00, 0xF0,
-0xA1, 0xC0, 0x83, 0x02, 0x0F, 0x4A, 0x4C, 0x28, 0x30, 0xA2, 0xD0, 0x74, 0xC0,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x12, 0xBF, 0x00, 0xFC,
-0x5A, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0xBF, 0x46, 0xFD, 0x02, 0xF0, 0x8B, 0xC0,
-0x27, 0x22, 0xA7, 0x20, 0xFC, 0x0A, 0xF0, 0x4B, 0xC3, 0x2F, 0x27, 0xAF, 0x00,
-0x5C, 0x12, 0xF0, 0x09, 0xC8, 0x2F, 0x02, 0xBD, 0x00, 0x7C, 0x22, 0xF0, 0x8B,
-0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x60, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x27, 0x05, 0xBF, 0x08, 0xEC, 0x02,
-0x30, 0x0B, 0xC0, 0x24, 0x00, 0xBF, 0x04, 0x7C, 0x02, 0x30, 0xCA, 0xC0, 0x2C,
-0x00, 0x83, 0x40, 0xD0, 0x22, 0xF0, 0x4B, 0xC0, 0x2F, 0x05, 0x8F, 0x88, 0x5C,
-0x82, 0xB0, 0x09, 0xC0, 0x2F, 0x02, 0xB3, 0x00, 0xFC, 0x16, 0xF0, 0x49, 0xD0,
-0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x22, 0x30, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x03, 0x01, 0x5D, 0x04, 0x44, 0x48, 0x14,
-0x01, 0x49, 0x04, 0x02, 0x17, 0x14, 0x74, 0x00, 0x14, 0xC1, 0x44, 0x80, 0x04,
-0x11, 0x00, 0x44, 0x20, 0xD2, 0x41, 0x49, 0x07, 0x21, 0x1D, 0x04, 0x44, 0x48,
-0x10, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x81, 0x40, 0x16,
-0x04, 0x5D, 0x90, 0x44, 0x00, 0x10, 0x01, 0x40, 0x71, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0xA0, 0x23, 0x05, 0x8D, 0x04, 0x05, 0x32, 0x10, 0x88,
-0x40, 0x20, 0x00, 0x8D, 0x8D, 0x74, 0x02, 0x11, 0x58, 0x40, 0x20, 0x43, 0x81,
-0x40, 0x16, 0x02, 0xD0, 0xC8, 0x40, 0x23, 0x05, 0x8D, 0x24, 0x14, 0x32, 0x90,
-0x08, 0x40, 0x23, 0x00, 0x81, 0x00, 0x34, 0x0A, 0xD0, 0x08, 0x40, 0x21, 0x01,
-0x8D, 0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x04, 0x44, 0x42, 0x10, 0x09, 0x40,
-0xA4, 0x01, 0x95, 0x40, 0x74, 0x06, 0x10, 0x09, 0x42, 0x24, 0x00, 0x91, 0x00,
-0x46, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09,
-0x40, 0x27, 0x40, 0x91, 0x20, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x24, 0x00, 0x8D,
-0x20, 0x45, 0x02, 0x00, 0x09, 0x40, 0x61, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0xA8, 0x27, 0x02, 0x9F, 0x01, 0x44, 0x02, 0x30, 0x09, 0xD0, 0x24,
-0x00, 0x9F, 0x01, 0x3C, 0x02, 0x30, 0x09, 0xF0, 0x24, 0x00, 0x83, 0x01, 0x5C,
-0x1A, 0xD2, 0x39, 0xC5, 0x27, 0x24, 0x9E, 0x00, 0x5E, 0x02, 0xB0, 0x09, 0xC0,
-0x67, 0x40, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x02,
-0x4C, 0x02, 0x30, 0x09, 0xC0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x16, 0x80, 0x65, 0x00, 0x9F, 0x00, 0x1C, 0x26, 0xF0, 0x08, 0xC0, 0x67, 0x00,
-0x97, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0xDF, 0x82, 0x7C, 0xC2,
-0xF0, 0x49, 0xC0, 0xE7, 0x00, 0x9D, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0xE7,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C,
-0x42, 0xF4, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x08, 0x05, 0x00, 0x13, 0x00, 0x4C, 0x48, 0xF0, 0x01, 0xD3, 0x04, 0x00, 0x1F,
-0x00, 0x7C, 0x80, 0xF0, 0x81, 0xC0, 0x04, 0x40, 0x13, 0x00, 0x4C, 0x08, 0xF3,
-0x21, 0xC5, 0xC7, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
-0x1B, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC0, 0x84, 0x41, 0x13, 0x02, 0x4D, 0x00,
-0xF0, 0x41, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80,
-0x14, 0x00, 0x71, 0x07, 0xC5, 0x0D, 0x70, 0x17, 0x40, 0x14, 0x00, 0x7D, 0x04,
-0x74, 0x01, 0xD0, 0x05, 0x42, 0x58, 0x00, 0x51, 0x00, 0xD4, 0x09, 0xD0, 0x27,
-0x40, 0x1F, 0x00, 0x5D, 0x00, 0x44, 0x01, 0x78, 0x05, 0x40, 0x5F, 0x00, 0x71,
-0x00, 0x74, 0x01, 0xD0, 0x05, 0xC0, 0x1E, 0x00, 0x71, 0x11, 0x84, 0x05, 0xD2,
-0x27, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32,
-0x00, 0x91, 0x07, 0x24, 0x2F, 0x50, 0x1C, 0x40, 0x30, 0x80, 0x4D, 0x11, 0x34,
-0x03, 0xD0, 0x0D, 0x40, 0x32, 0x10, 0xC9, 0x06, 0x04, 0x07, 0xD0, 0x3C, 0x40,
-0x33, 0x80, 0xDD, 0x00, 0x14, 0x03, 0x50, 0x0C, 0x40, 0x37, 0x86, 0x8D, 0x00,
-0x34, 0x02, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x2F, 0xD0, 0x01,
-0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x78, 0x00,
-0x21, 0x24, 0x84, 0x03, 0x50, 0x0E, 0x41, 0x38, 0x02, 0x6D, 0x00, 0xB4, 0x03,
-0xD0, 0x0B, 0x50, 0x28, 0x05, 0x69, 0x10, 0xB4, 0x09, 0xD0, 0x2E, 0x42, 0x3B,
-0x04, 0xFD, 0x00, 0x84, 0x03, 0x51, 0x0E, 0x40, 0x1B, 0x00, 0x25, 0x00, 0xB4,
-0x02, 0xD2, 0x4F, 0x64, 0x7A, 0x20, 0xE1, 0x00, 0x84, 0x03, 0xD0, 0x0A, 0x60,
-0x17, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0x23,
-0x07, 0xAD, 0x05, 0x70, 0x14, 0xC0, 0x78, 0x01, 0xEF, 0x01, 0xBC, 0x07, 0xF0,
-0x9E, 0xC0, 0x68, 0x41, 0xA9, 0x09, 0x8C, 0x07, 0xF3, 0x1E, 0xC0, 0x7B, 0x10,
-0xEF, 0x01, 0x94, 0x17, 0x70, 0x3E, 0x80, 0x7F, 0x00, 0xEF, 0x01, 0xBC, 0x07,
-0xF0, 0x5E, 0x80, 0x7C, 0x00, 0xF1, 0x01, 0x8C, 0x07, 0xF0, 0x16, 0xC0, 0x57,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0xB5, 0x42, 0x0F, 0x00,
-0x7C, 0x01, 0x72, 0x05, 0xC0, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x49,
-0xD0, 0x07, 0x0A, 0x17, 0x00, 0x5C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
-0x06, 0x7C, 0x03, 0x70, 0x1D, 0xC0, 0x27, 0x40, 0x5B, 0x00, 0x7C, 0x03, 0xF0,
-0x1C, 0xC0, 0x27, 0x00, 0xDE, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0xFF, 0x00, 0xB3, 0x01, 0xCC,
-0x23, 0xF0, 0x5F, 0xC2, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC0,
-0x6C, 0x00, 0xFB, 0x41, 0xC8, 0x27, 0x30, 0x17, 0xC0, 0x5F, 0x20, 0xFF, 0x13,
-0xDC, 0x47, 0xB0, 0x1F, 0xC8, 0x7F, 0x00, 0xBF, 0x01, 0xDC, 0x06, 0x30, 0x1F,
-0xD1, 0x7C, 0x00, 0xFF, 0x81, 0xFC, 0x87, 0xF0, 0x1B, 0xC0, 0x03, 0x08, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x3D, 0x00, 0xA1, 0x0A, 0x84, 0x09,
-0x70, 0x0E, 0x48, 0x3B, 0x04, 0xAD, 0x00, 0xB4, 0x03, 0x10, 0x0F, 0x40, 0x28,
-0x10, 0x61, 0x04, 0xC4, 0x23, 0x10, 0x86, 0x40, 0x3B, 0x0A, 0xED, 0x00, 0xC4,
-0x03, 0xB2, 0x0E, 0x40, 0x3B, 0x00, 0x3D, 0x00, 0x84, 0x02, 0xB0, 0x0E, 0x40,
-0x38, 0x00, 0xAD, 0x88, 0xB4, 0x22, 0xD0, 0x02, 0x40, 0x57, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x39, 0x00, 0x31, 0x00, 0x84, 0x23, 0xD8,
-0x46, 0x40, 0x3B, 0x00, 0xED, 0x02, 0xF4, 0x03, 0x90, 0x2E, 0x40, 0x20, 0x00,
-0xA1, 0x20, 0x86, 0x22, 0x98, 0x2A, 0x40, 0x8B, 0x00, 0xED, 0x00, 0x94, 0x03,
-0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0x94, 0x23, 0x10, 0x0C, 0x40, 0x18,
-0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x41, 0x03, 0x08, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x20, 0x33, 0x04, 0x01, 0x03, 0x45, 0x00, 0x50, 0x01,
-0x40, 0xF3, 0x00, 0x9D, 0x40, 0x36, 0x83, 0x90, 0x0C, 0x40, 0x04, 0x00, 0x01,
-0x20, 0x06, 0x02, 0x90, 0x08, 0x44, 0x23, 0x08, 0xCD, 0x00, 0x04, 0x03, 0x90,
-0x0C, 0x40, 0x33, 0x02, 0x4D, 0x08, 0x04, 0x03, 0x90, 0x1C, 0x40, 0x20, 0x00,
-0xCD, 0x00, 0x74, 0x02, 0xD0, 0x14, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1D, 0xA0, 0xBD, 0x40, 0x73, 0x11, 0x4C, 0x0A, 0xF0, 0x09, 0xC0,
-0x3F, 0x10, 0x5F, 0x03, 0x74, 0x83, 0xB4, 0x09, 0x40, 0x2C, 0x00, 0xD3, 0x00,
-0x4C, 0x1A, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0xFF, 0x00, 0xDC, 0x03, 0x30, 0x0F,
-0x40, 0x27, 0x00, 0x5F, 0x00, 0x1C, 0x02, 0x30, 0xBF, 0xC1, 0x34, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x14, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x00, 0x77, 0x00, 0x5F, 0x06, 0x7C, 0x62, 0xF0, 0x09, 0xC0, 0x37,
-0x01, 0x5F, 0x01, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x27, 0x00, 0xD7, 0x02, 0x7D,
-0x00, 0x70, 0x01, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF2, 0x0D, 0xC4,
-0x27, 0x00, 0x5F, 0x02, 0x7C, 0x02, 0xF0, 0x0D, 0xE0, 0x37, 0x00, 0xDF, 0x02,
-0x7C, 0x0B, 0xF1, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x3F, 0x00, 0x73, 0x08, 0xCC, 0x00, 0x30, 0x0B, 0xC2, 0x38, 0x00,
-0xF3, 0x00, 0xCC, 0x03, 0x31, 0x1B, 0xC0, 0x2E, 0x00, 0xF3, 0x00, 0xCC, 0x40,
-0xF0, 0x0A, 0xC4, 0x08, 0x00, 0xF3, 0x00, 0xBC, 0x03, 0x30, 0x0F, 0xC0, 0x2F,
-0x00, 0x7F, 0x01, 0x4C, 0x06, 0x30, 0x0E, 0xC8, 0x3C, 0x00, 0x7F, 0x00, 0xFC,
-0x03, 0x30, 0x83, 0xC0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x36, 0x00, 0x51, 0x00, 0x45, 0x0C, 0x11, 0x39, 0x41, 0x34, 0x00, 0xD1,
-0x01, 0x2C, 0x03, 0x50, 0x09, 0x40, 0x44, 0x00, 0xC1, 0x02, 0x7C, 0x0C, 0xD0,
-0x31, 0xC0, 0x46, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x0D, 0xC0, 0x65, 0x00,
-0x5D, 0x02, 0x6C, 0x06, 0x14, 0x0D, 0x40, 0x34, 0x00, 0xDD, 0x04, 0x70, 0x07,
-0x10, 0x09, 0x40, 0x04, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA8,
-0x30, 0x40, 0x01, 0x00, 0x64, 0x06, 0x90, 0x11, 0x40, 0x34, 0x00, 0xD1, 0x01,
-0x44, 0x03, 0x18, 0x88, 0x40, 0x24, 0x01, 0xD1, 0x14, 0x44, 0x06, 0xD0, 0x11,
-0x40, 0x44, 0x00, 0xD1, 0x00, 0x54, 0x03, 0x90, 0x0D, 0x40, 0x67, 0x04, 0x49,
-0x06, 0x44, 0x22, 0x10, 0x0D, 0x40, 0x34, 0x22, 0xDD, 0x40, 0x74, 0x0F, 0x10,
-0x0D, 0x40, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30,
-0x00, 0x01, 0x00, 0x05, 0x02, 0x90, 0x08, 0x56, 0x30, 0x40, 0xC1, 0x00, 0x45,
-0x03, 0x50, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x14, 0x02, 0xD0, 0x00, 0x40,
-0x60, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD2, 0x0C, 0x40, 0x21, 0x00, 0x4D, 0x00,
-0x24, 0x02, 0x10, 0x0C, 0x00, 0x30, 0x08, 0x8D, 0x00, 0x34, 0x03, 0x10, 0x05,
-0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3E, 0x10,
-0x13, 0x00, 0x4D, 0x02, 0xB0, 0x01, 0x42, 0x34, 0x00, 0x93, 0x20, 0x46, 0x03,
-0x30, 0x0B, 0xC0, 0x26, 0x00, 0x53, 0x00, 0x44, 0x00, 0xF1, 0x09, 0x40, 0x04,
-0x40, 0xE3, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x27, 0x00, 0x5F, 0x00, 0x4C,
-0x02, 0x30, 0x0D, 0x90, 0x14, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0x30, 0x09, 0xD0,
-0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x98, 0x3F, 0x00, 0x2F,
-0x00, 0xFC, 0x02, 0x70, 0x0B, 0xC4, 0x3F, 0x00, 0xBF, 0x00, 0xBC, 0x03, 0xF0,
-0x0B, 0xC0, 0x0F, 0x00, 0x2F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC2, 0x0F, 0x00,
-0xFF, 0x20, 0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x2D, 0x00, 0x7F, 0x00, 0xFC, 0x02,
-0xF0, 0x0F, 0xC0, 0x3F, 0x08, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x17,
-0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0xFF, 0x00, 0xFF, 0x09,
-0xFC, 0x32, 0xF0, 0x4F, 0xE1, 0x2D, 0x21, 0xFF, 0x09, 0xFC, 0x00, 0xF0, 0x0F,
-0xC0, 0x3C, 0x00, 0xFF, 0x1C, 0xCC, 0x52, 0xF0, 0x4F, 0xC0, 0x7C, 0x80, 0xFF,
-0x00, 0xCC, 0x13, 0xB0, 0x0F, 0xC0, 0x7C, 0x00, 0xFF, 0x84, 0xBC, 0x05, 0x30,
-0x1F, 0xC0, 0x7C, 0x40, 0xFB, 0x01, 0xCC, 0x04, 0xB0, 0x0B, 0xC0, 0x0C, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xCD, 0x00, 0x74,
-0x3A, 0xD0, 0x3F, 0x40, 0xA7, 0x03, 0xDD, 0x04, 0x74, 0x06, 0xD0, 0x2F, 0x40,
-0xFC, 0x00, 0xFD, 0x06, 0x44, 0x1A, 0xD0, 0xBF, 0x46, 0x74, 0x00, 0xFD, 0x06,
-0xC4, 0x3B, 0x34, 0xAF, 0x40, 0x74, 0x00, 0xFC, 0x02, 0x74, 0x05, 0x10, 0x1D,
-0x40, 0x74, 0x00, 0x91, 0x01, 0x54, 0x03, 0x52, 0x01, 0x40, 0x0D, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x01, 0xCD, 0x00, 0x34, 0x00,
-0xD0, 0x0C, 0x40, 0x03, 0x04, 0xCD, 0x04, 0x34, 0x02, 0xD0, 0x8C, 0x40, 0x32,
-0x02, 0xCD, 0x00, 0x04, 0x40, 0xD1, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x18, 0x04,
-0x43, 0x10, 0x0C, 0x42, 0x30, 0x00, 0xCD, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x40,
-0x31, 0x00, 0x49, 0x80, 0x04, 0x01, 0x80, 0x08, 0x60, 0x4C, 0x80, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x0C, 0xD0,
-0x0D, 0x40, 0x47, 0x00, 0xDD, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40, 0x36, 0x00,
-0xDD, 0x00, 0x45, 0x06, 0xD0, 0x0D, 0x40, 0x34, 0x10, 0xDD, 0x00, 0x44, 0x03,
-0x10, 0x0D, 0x40, 0x34, 0x14, 0xDD, 0x00, 0x74, 0x21, 0x10, 0x0D, 0x60, 0x74,
-0x90, 0x11, 0x00, 0x56, 0x01, 0x09, 0x31, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0C, 0xF0, 0x0D,
-0xC0, 0x67, 0x04, 0xDF, 0x00, 0x7C, 0x04, 0xF0, 0x0D, 0x40, 0x36, 0x00, 0xDF,
-0x20, 0x4C, 0x1E, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDD, 0x00, 0x4C, 0x03, 0x30,
-0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x81, 0x31, 0x2C, 0xC0, 0xF0, 0x04,
-0xDB, 0x00, 0x4C, 0x16, 0xA0, 0x31, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x07, 0x88, 0x3D, 0x00, 0xFF, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0xC2,
-0x2F, 0x00, 0xFF, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0xD0, 0x35, 0x00, 0xDF, 0x00,
-0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xFC, 0x43, 0xF0, 0x0F,
-0xC4, 0x3F, 0x02, 0xFD, 0x00, 0xF8, 0x01, 0xF4, 0x2F, 0x40, 0x3F, 0x40, 0xFF,
-0x00, 0xFC, 0x67, 0xF0, 0x02, 0xC2, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x08, 0x35, 0x80, 0xDF, 0x00, 0x5C, 0x08, 0x30, 0x0D, 0xC0, 0xA4,
-0x08, 0xDF, 0x00, 0x4C, 0x08, 0x30, 0x5C, 0xC0, 0x34, 0x00, 0xC3, 0x40, 0x4C,
-0x48, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x3C, 0x83, 0xF0, 0x0C, 0xC0,
-0x34, 0x04, 0xD7, 0x91, 0x4C, 0x13, 0x74, 0x0D, 0xC5, 0x35, 0x00, 0xDF, 0x84,
-0x4C, 0x05, 0xE0, 0x29, 0x81, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x44, 0x04, 0x10, 0x0F, 0x40, 0xE4, 0x02,
-0xDD, 0x00, 0x44, 0x00, 0xB0, 0x2F, 0x40, 0x3D, 0x00, 0xF1, 0x01, 0x44, 0x16,
-0xD0, 0x0F, 0xC0, 0x34, 0x00, 0xF7, 0x04, 0xF4, 0x4B, 0xD0, 0xAF, 0x40, 0xB5,
-0x00, 0xF0, 0x02, 0x04, 0x15, 0x10, 0x3D, 0x44, 0x34, 0x10, 0xC9, 0x80, 0x44,
-0x85, 0x90, 0x31, 0x41, 0x6D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
-0x20, 0x30, 0x10, 0xCD, 0x00, 0x04, 0x4E, 0x11, 0x0C, 0x44, 0x40, 0x00, 0xCD,
-0x00, 0x04, 0x00, 0x10, 0x2C, 0x40, 0x30, 0x08, 0xC1, 0x04, 0x24, 0x04, 0xD0,
-0x0C, 0x50, 0x32, 0x00, 0xC1, 0x07, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0xD0, 0x00,
-0xC5, 0x02, 0x00, 0x09, 0x10, 0x14, 0x40, 0x83, 0x41, 0xC1, 0x02, 0x64, 0x00,
-0xD0, 0x18, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
-0x78, 0x00, 0xED, 0x01, 0x85, 0x07, 0x14, 0x1C, 0x50, 0x78, 0x04, 0xED, 0x01,
-0x85, 0x06, 0x10, 0x1E, 0x40, 0x78, 0x80, 0xE1, 0x11, 0xA4, 0x05, 0xD0, 0x1C,
-0x40, 0x7C, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x59, 0x06, 0xE5,
-0x01, 0x84, 0x05, 0x10, 0x9E, 0x40, 0x7A, 0x07, 0xA1, 0x01, 0xA4, 0x06, 0x91,
-0x1A, 0x40, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0x30,
-0x00, 0xCD, 0x00, 0x1C, 0x43, 0x30, 0x0C, 0xC0, 0x10, 0x00, 0xDF, 0x00, 0x04,
-0x03, 0x10, 0x0D, 0xC0, 0x30, 0x00, 0xC3, 0x00, 0x2C, 0x21, 0xF0, 0x0C, 0xC0,
-0x36, 0x02, 0xC3, 0x00, 0x3C, 0x03, 0xF2, 0x0D, 0xE0, 0x20, 0x00, 0xD7, 0x00,
-0x0C, 0x33, 0x30, 0x8C, 0xC1, 0x23, 0x03, 0x4B, 0x20, 0x2C, 0x20, 0xF0, 0x09,
-0xC0, 0x4B, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x10,
-0xFF, 0x48, 0xFC, 0x23, 0xF8, 0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x03,
-0xF0, 0x0F, 0xC0, 0x3F, 0x10, 0xFF, 0x02, 0x5D, 0x21, 0xF0, 0x0F, 0xC0, 0x3F,
-0x00, 0xF7, 0x10, 0x7C, 0x43, 0xF0, 0x0D, 0xC1, 0x2A, 0x00, 0xFB, 0x02, 0x7C,
-0x21, 0xF2, 0x88, 0x00, 0x28, 0x03, 0x2F, 0x08, 0xDC, 0x22, 0xF2, 0x8B, 0xC4,
-0x09, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x80, 0xDF,
-0x00, 0x7E, 0x01, 0x30, 0x4D, 0xC1, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0,
-0xAD, 0xD0, 0x34, 0x01, 0xDF, 0x02, 0x5C, 0x03, 0xF0, 0xCD, 0xC0, 0x37, 0x00,
-0xDF, 0x04, 0x7C, 0x1B, 0xF8, 0x6D, 0xC0, 0x37, 0x00, 0xD3, 0x0E, 0x7C, 0x01,
-0xF0, 0x1D, 0xC0, 0x22, 0x40, 0xCB, 0x00, 0x4C, 0x02, 0xF0, 0x11, 0x40, 0x40,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xED, 0x00,
-0xF4, 0x03, 0x10, 0x4E, 0x40, 0x3B, 0x00, 0xEC, 0x00, 0xB4, 0x03, 0xD0, 0x8E,
-0x40, 0xB8, 0x05, 0xFD, 0x04, 0x84, 0x03, 0xD0, 0x0E, 0x41, 0x3B, 0x00, 0xED,
-0x0C, 0xB4, 0x53, 0x70, 0xCE, 0x40, 0x3B, 0x00, 0xE5, 0x00, 0xB4, 0x00, 0xD0,
-0x0E, 0x40, 0x28, 0x00, 0xEB, 0x00, 0x84, 0x03, 0xD0, 0x06, 0x40, 0x4C, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xE5, 0x01, 0xB4,
-0x87, 0x92, 0xDE, 0x42, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x5C, 0x40,
-0x78, 0x00, 0xFD, 0x4D, 0x94, 0x07, 0xD0, 0x5E, 0x40, 0x7B, 0x00, 0xED, 0x05,
-0xB4, 0x07, 0xD0, 0x1E, 0x44, 0x7F, 0x00, 0xE1, 0x05, 0xB4, 0x07, 0xD0, 0x1E,
-0x41, 0x6E, 0x80, 0xF9, 0x01, 0x84, 0x07, 0xD0, 0x1C, 0x60, 0x10, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xDD, 0x00, 0x74, 0x43,
-0x94, 0x0C, 0x40, 0xF3, 0x01, 0xCD, 0x00, 0x36, 0x3F, 0xD0, 0x0D, 0x40, 0x30,
-0x10, 0xDD, 0x00, 0x04, 0x47, 0x90, 0x0C, 0x42, 0x33, 0x00, 0xDD, 0x00, 0x74,
-0x03, 0x52, 0x0C, 0x40, 0xB3, 0x02, 0xC5, 0x00, 0x34, 0x00, 0xD0, 0x4C, 0x46,
-0x60, 0xA2, 0xC9, 0x09, 0x44, 0x03, 0xC0, 0x1C, 0x40, 0x58, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x08, 0x5F, 0x00, 0xF4, 0x15, 0xB0,
-0x05, 0xC0, 0x9F, 0x01, 0x5F, 0x00, 0xFC, 0x01, 0xF2, 0x05, 0xC0, 0x14, 0x08,
-0x5F, 0x00, 0xDC, 0x19, 0xF3, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01,
-0xF0, 0x05, 0xC0, 0x5F, 0x20, 0x53, 0x00, 0xFC, 0x15, 0xF0, 0x07, 0xCC, 0x9A,
-0x20, 0x6B, 0x02, 0xCD, 0x09, 0xF0, 0x37, 0xD0, 0x5C, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x0A, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01,
-0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F,
-0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70,
-0x21, 0xC0, 0x87, 0x01, 0x1F, 0x02, 0x7E, 0x00, 0xF2, 0x01, 0xC0, 0x07, 0x04,
-0x1F, 0x10, 0x7C, 0x48, 0xB0, 0xE1, 0xC8, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x80, 0x4C, 0x02, 0x30, 0x09, 0xC0,
-0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x80, 0x9F, 0x08,
-0x0C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x0E, 0x30, 0x08,
-0xC0, 0x24, 0x00, 0x97, 0x00, 0x7C, 0x86, 0x72, 0x29, 0xCA, 0xA7, 0x08, 0x97,
-0x05, 0x5C, 0x02, 0x30, 0x19, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x20, 0x24, 0x08, 0x9D, 0x20, 0x44, 0x36, 0x04, 0x09, 0x44, 0xE7,
-0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x25, 0x90, 0x9C, 0x01, 0x44,
-0x0A, 0x14, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x03, 0x45, 0x0A, 0xA4, 0x09, 0x51,
-0xA0, 0x00, 0x90, 0x12, 0x34, 0x26, 0x10, 0x29, 0x40, 0x27, 0x00, 0x99, 0x00,
-0x6C, 0x8A, 0x50, 0x19, 0x41, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x45, 0x02, 0x00, 0x09, 0x40, 0x27, 0x00,
-0x9D, 0x00, 0x40, 0x02, 0xD0, 0x09, 0x00, 0x24, 0x20, 0x9C, 0x10, 0x44, 0x22,
-0x10, 0x09, 0x44, 0x25, 0x00, 0x9D, 0x14, 0x44, 0x42, 0x90, 0x19, 0x40, 0x24,
-0x04, 0x95, 0x00, 0x54, 0x02, 0x40, 0x0D, 0x41, 0x26, 0x00, 0x9D, 0x42, 0x54,
-0x12, 0x10, 0x49, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x20, 0x20, 0x00, 0x8D, 0x00, 0x04, 0x12, 0x11, 0x48, 0x40, 0x33, 0x01, 0x8D,
-0x00, 0x34, 0x12, 0xD0, 0x4D, 0x4C, 0x21, 0x11, 0x8D, 0x04, 0x04, 0x13, 0x10,
-0x48, 0x60, 0x23, 0x00, 0x8D, 0x04, 0x04, 0x12, 0x90, 0x48, 0x44, 0x24, 0x00,
-0x81, 0x84, 0x76, 0x02, 0x1A, 0x08, 0x40, 0x23, 0x88, 0x89, 0x80, 0x24, 0x02,
-0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x38,
-0x86, 0x0A, 0x1F, 0x0A, 0x4C, 0x28, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x1F, 0x0A,
-0x7C, 0x00, 0xF0, 0xA1, 0xC0, 0x04, 0x00, 0x1D, 0x0A, 0x4D, 0x28, 0x32, 0x01,
-0xC4, 0x07, 0x00, 0x1F, 0x0A, 0x4C, 0x28, 0x30, 0xA1, 0x40, 0x04, 0x08, 0x17,
-0x4A, 0x5C, 0x00, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x17, 0x00, 0x5C, 0x29, 0x30,
-0xA1, 0xC0, 0x77, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB2, 0x25,
-0x00, 0x9F, 0x40, 0xFC, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9F, 0x00, 0xFC,
-0x22, 0xF0, 0x89, 0xC0, 0x27, 0x02, 0x9F, 0x48, 0xFC, 0x22, 0xF0, 0x89, 0xC2,
-0x27, 0x00, 0x9F, 0x08, 0x7C, 0x22, 0x70, 0x89, 0xC0, 0x3B, 0x00, 0x9F, 0x08,
-0xFC, 0x02, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xB7, 0x80, 0xDC, 0x02, 0xF1, 0x8F,
-0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x80, 0x27, 0x00,
-0x9F, 0x08, 0xFC, 0x02, 0x30, 0x09, 0xC0, 0x2C, 0x02, 0x93, 0x00, 0x7C, 0x52,
-0xF0, 0xCB, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x49, 0xC0, 0x27,
-0x00, 0xBF, 0x0C, 0xFC, 0x02, 0xE0, 0x0B, 0xC0, 0x2D, 0x00, 0xB3, 0x04, 0xDC,
-0x02, 0xB0, 0x0B, 0xC0, 0x2A, 0x40, 0xB3, 0x00, 0xBC, 0x03, 0x30, 0x0B, 0xC0,
-0x77, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x1D,
-0x04, 0x74, 0x49, 0x10, 0x01, 0x44, 0x14, 0x42, 0x01, 0x14, 0x74, 0x00, 0xD0,
-0xC1, 0x4C, 0x87, 0x10, 0x1D, 0x50, 0x74, 0x20, 0x10, 0x01, 0x40, 0x07, 0x00,
-0x1D, 0x0C, 0x74, 0x48, 0xD0, 0x01, 0x45, 0x07, 0x00, 0x11, 0x14, 0x74, 0x00,
-0xD0, 0x05, 0x40, 0x04, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x63,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x04,
-0x34, 0xB2, 0x14, 0x88, 0x40, 0x20, 0x00, 0x81, 0x04, 0x36, 0x02, 0xD0, 0x48,
-0x48, 0x23, 0x82, 0x8D, 0x08, 0x34, 0x02, 0x14, 0x88, 0x60, 0x23, 0x00, 0x8D,
-0x04, 0x34, 0x32, 0xD0, 0x88, 0x40, 0x27, 0x00, 0x81, 0x0C, 0x36, 0x02, 0x52,
-0x08, 0x40, 0x23, 0x00, 0x81, 0x00, 0x14, 0x02, 0x18, 0x08, 0x40, 0x4B, 0x80,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x9D, 0x00, 0x74,
-0x12, 0x10, 0x09, 0x50, 0x24, 0x01, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40,
-0x27, 0x00, 0x9D, 0x00, 0x74, 0x0B, 0x10, 0x09, 0x40, 0x27, 0x00, 0xDD, 0x00,
-0x74, 0x02, 0xD8, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09,
-0x40, 0x27, 0x04, 0x91, 0x02, 0x70, 0x12, 0x19, 0x09, 0x40, 0x63, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x24, 0x00, 0x9F, 0x00, 0x78, 0x06,
-0x30, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x00, 0x7C, 0x4E, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF2, 0x09, 0xC0, 0x67, 0x40, 0x93, 0x00, 0x7C, 0x42, 0xB0, 0xB9, 0xC0,
-0x27, 0x00, 0x93, 0x00, 0x7C, 0x46, 0x34, 0x19, 0xC0, 0x17, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x3C, 0x06, 0xF0,
-0x08, 0xC0, 0x67, 0x00, 0x9C, 0x00, 0x7C, 0x12, 0xF0, 0x09, 0xC1, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0xF0, 0x09, 0xC1, 0x27, 0x02, 0x9F, 0xB0, 0x7C, 0x42, 0xF0, 0x19, 0x02, 0x24,
-0x01, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x99, 0xC1, 0x5B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01,
-0xC0, 0xC7, 0x00, 0x1F, 0x00, 0x4C, 0x08, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F,
-0x01, 0x7C, 0x30, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x01, 0x5C, 0x04, 0xF0,
-0x01, 0xC8, 0x86, 0x09, 0x13, 0x08, 0x6D, 0x08, 0xE0, 0x41, 0xC0, 0x84, 0x00,
-0x17, 0x40, 0x6C, 0x10, 0x10, 0xA1, 0xC2, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x00, 0x14, 0x00, 0x5D, 0x80, 0xF4, 0x1D, 0x70, 0x05, 0x40,
-0x5F, 0x20, 0x5D, 0x00, 0x4C, 0x01, 0x10, 0x27, 0x40, 0x14, 0x00, 0x7D, 0x00,
-0xF4, 0x0D, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x01, 0xC4, 0x05, 0x70, 0x27,
-0x40, 0x18, 0x00, 0x71, 0x82, 0xC4, 0x19, 0xD0, 0x16, 0x41, 0x18, 0x01, 0x71,
-0x1B, 0xE4, 0x45, 0x10, 0x07, 0x40, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x1F, 0x58, 0x0C, 0x40, 0x77,
-0x00, 0xC9, 0x00, 0x25, 0x03, 0x14, 0x2C, 0x50, 0x30, 0x00, 0xCD, 0x01, 0x74,
-0x07, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x1C, 0x50,
-0xB0, 0x42, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x2C, 0x40, 0x50, 0x40, 0xC5, 0x02,
-0x64, 0x07, 0x94, 0x1C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x80, 0x38, 0x02, 0xED, 0x08, 0xB4, 0x03, 0x58, 0x0E, 0x40, 0x3B, 0x0C,
-0xED, 0x05, 0x04, 0x07, 0x10, 0x1E, 0x41, 0x38, 0x00, 0x6D, 0x10, 0xB4, 0x03,
-0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x03, 0x84, 0x09, 0x50, 0x36, 0x40, 0x3C,
-0x00, 0xE1, 0x01, 0x84, 0x03, 0xD0, 0x0F, 0x40, 0x1C, 0x00, 0xE1, 0x00, 0xE6,
-0x82, 0x90, 0x16, 0x40, 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x18, 0x78, 0x00, 0xEF, 0x11, 0xBC, 0x05, 0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xEF,
-0x87, 0xAC, 0x87, 0x30, 0x1F, 0xC0, 0x78, 0x00, 0xED, 0x21, 0xBC, 0x07, 0xF0,
-0x1E, 0xC0, 0x7B, 0x00, 0xCF, 0x81, 0x9C, 0x07, 0x78, 0x1F, 0xC0, 0x78, 0x00,
-0xC3, 0x81, 0x8C, 0x07, 0xDA, 0x0A, 0xC4, 0x58, 0x20, 0xE7, 0x21, 0xAE, 0x07,
-0xB1, 0x1B, 0xC4, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8,
-0x35, 0x01, 0xDF, 0x06, 0x7E, 0x01, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x16,
-0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
-0xC0, 0x37, 0x20, 0xDF, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0, 0x31, 0x00, 0x5F,
-0x00, 0x5C, 0x03, 0xF8, 0x0C, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x70, 0x02, 0x70,
-0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0xFD,
-0x02, 0xF3, 0x01, 0xFC, 0x23, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xF3, 0x81, 0xFC,
-0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x02, 0xFF, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0,
-0x7F, 0x00, 0xF7, 0x01, 0xCC, 0x27, 0x38, 0x1F, 0xC0, 0x7F, 0x00, 0x73, 0x01,
-0x8C, 0x87, 0xB8, 0x97, 0xC0, 0x5C, 0x00, 0xEF, 0x21, 0xCC, 0x05, 0xF0, 0x17,
-0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00,
-0xE1, 0x00, 0xB4, 0x03, 0xD8, 0x0E, 0x40, 0x3B, 0x02, 0xE1, 0x00, 0xB4, 0x03,
-0xD0, 0x82, 0x40, 0x3B, 0x00, 0x7D, 0x08, 0xC4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
-0x00, 0x7D, 0x04, 0x84, 0x01, 0x14, 0x4E, 0x40, 0x3B, 0x01, 0x3B, 0x00, 0x85,
-0x43, 0x10, 0xCE, 0x40, 0x18, 0x01, 0xED, 0x08, 0x94, 0x62, 0xD0, 0x62, 0x40,
-0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x08, 0xE1,
-0x00, 0xB4, 0x23, 0xD8, 0x0E, 0x40, 0x9B, 0x04, 0xE1, 0x00, 0xB4, 0x23, 0xD0,
-0x0E, 0x40, 0x3B, 0x88, 0x6D, 0x00, 0x84, 0x09, 0x10, 0x0E, 0x40, 0x3B, 0x00,
-0xE5, 0x80, 0x94, 0x03, 0x18, 0x0A, 0x4C, 0x3B, 0x10, 0xE1, 0x00, 0xB4, 0x03,
-0x90, 0x0F, 0x44, 0x89, 0x10, 0xED, 0x00, 0x84, 0x00, 0xD0, 0x0A, 0x61, 0x60,
-0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0xC1, 0x40,
-0x34, 0x1A, 0xD0, 0x0C, 0x40, 0x67, 0xC0, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x00,
-0x40, 0x33, 0x80, 0x0D, 0x00, 0x05, 0x02, 0x10, 0x0C, 0x40, 0x33, 0x10, 0x8D,
-0x40, 0x44, 0x00, 0x18, 0x08, 0x40, 0x33, 0x20, 0x01, 0x00, 0x24, 0x03, 0x10,
-0x2C, 0x40, 0x50, 0x10, 0xCD, 0x01, 0x14, 0x0A, 0xD8, 0x20, 0x42, 0x08, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x3D, 0x00, 0xF3, 0x00, 0x7C,
-0x16, 0xD0, 0x0D, 0xC4, 0x47, 0x00, 0xF3, 0x00, 0x7C, 0x0B, 0xD0, 0x01, 0xC0,
-0x37, 0x00, 0x9F, 0x00, 0x4C, 0x04, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x00,
-0x5C, 0x02, 0x30, 0x09, 0x00, 0x37, 0x00, 0x91, 0x00, 0x6C, 0x8B, 0xB0, 0x2C,
-0xC1, 0x50, 0x01, 0xDF, 0x00, 0x40, 0x08, 0xD0, 0x89, 0xC0, 0x74, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02,
-0xF0, 0x0D, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x43, 0xF0, 0x01, 0xC0, 0x33,
-0x00, 0x1F, 0x02, 0x7C, 0x20, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0x9F, 0x02, 0x7C,
-0x0A, 0xF0, 0x09, 0xE0, 0xA7, 0x08, 0x9F, 0x42, 0x5C, 0x43, 0xF2, 0x0D, 0xD0,
-0xB7, 0x08, 0xDF, 0x2A, 0x7C, 0x08, 0xF0, 0x29, 0xD0, 0x17, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xF3, 0x00, 0xFC, 0x00, 0xF0,
-0x0F, 0xC0, 0x27, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x40,
-0xB3, 0x00, 0x9C, 0x02, 0x30, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0x7C, 0x02,
-0xB0, 0x03, 0xC0, 0x3F, 0x20, 0xAF, 0x20, 0xDC, 0x03, 0x30, 0x0F, 0xC1, 0x1D,
-0x00, 0xB6, 0x00, 0xCC, 0x42, 0x80, 0x09, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x40, 0xD1, 0x00, 0x74, 0x04, 0xD0, 0x0D,
-0x60, 0x67, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x37, 0x00, 0x91,
-0x03, 0x5C, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x9D, 0x01, 0x74, 0x46, 0x10,
-0x11, 0x41, 0x67, 0x01, 0x19, 0x01, 0x04, 0x06, 0xB0, 0x3D, 0x40, 0x74, 0x01,
-0x01, 0x45, 0x44, 0x4E, 0x90, 0x19, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xD1, 0x00, 0x76, 0x04, 0xD0, 0x0D, 0x4A,
-0x47, 0x04, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x37, 0x00, 0x91, 0x11,
-0x74, 0x04, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x1D, 0x01, 0x74, 0x04, 0x10, 0x19,
-0x40, 0x77, 0x00, 0x9D, 0x03, 0x40, 0x47, 0x10, 0x8D, 0x01, 0x55, 0x00, 0xD5,
-0x81, 0x44, 0x84, 0x90, 0x11, 0x48, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x00, 0x30, 0x00, 0xC1, 0x00, 0x34, 0x06, 0xD0, 0x0C, 0x40, 0x03,
-0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0x33, 0x00, 0x01, 0x00, 0x14,
-0x00, 0x10, 0x0C, 0x40, 0x33, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x90, 0x08, 0x64,
-0x33, 0x00, 0x89, 0x00, 0x47, 0x01, 0x90, 0x0C, 0x40, 0x30, 0x08, 0xD5, 0x00,
-0x04, 0x00, 0x90, 0x00, 0x44, 0x43, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x38, 0x3A, 0x00, 0xF3, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0x40, 0x07, 0x00,
-0xF3, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x93, 0x00, 0x5C, 0x00,
-0x30, 0x0D, 0xC0, 0x37, 0x00, 0x1D, 0x00, 0x7C, 0x02, 0x30, 0x01, 0xC0, 0x37,
-0x00, 0x9F, 0x00, 0x5C, 0x03, 0x30, 0x0D, 0xC0, 0x15, 0x08, 0xD7, 0x00, 0x4D,
-0x80, 0xB0, 0x09, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC4, 0x2F, 0x00, 0xFF,
-0x00, 0xFC, 0x03, 0xF2, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xDC, 0x02, 0xF0,
-0x0F, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x03, 0xC0, 0x1B, 0x80,
-0x3F, 0x00, 0xFC, 0x01, 0xD0, 0x0E, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xFE, 0x02,
-0xF0, 0x0B, 0xC0, 0x17, 0x42, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
-0x6F, 0x00, 0xF3, 0x01, 0xFC, 0x40, 0xF0, 0x02, 0xC0, 0x2C, 0x00, 0xB3, 0x40,
-0xEC, 0x02, 0x70, 0x1F, 0xC0, 0x2F, 0x00, 0xFB, 0x10, 0xFC, 0x02, 0x30, 0x03,
-0xC0, 0x68, 0x00, 0xFF, 0x00, 0xCC, 0x07, 0xB0, 0x0F, 0xC0, 0x3E, 0x09, 0xFF,
-0x01, 0xAC, 0x07, 0xF0, 0x4F, 0xC0, 0x7B, 0x00, 0xB3, 0x00, 0xCD, 0x03, 0x34,
-0x0F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x21,
-0x00, 0xD1, 0x10, 0x5C, 0x00, 0xD0, 0x11, 0x40, 0x6C, 0x08, 0x91, 0x0B, 0x58,
-0x00, 0x10, 0x1D, 0xC0, 0xA5, 0x06, 0xC1, 0x12, 0x74, 0x02, 0x10, 0x11, 0xC8,
-0x65, 0x00, 0xCD, 0x00, 0x54, 0x07, 0x10, 0x0D, 0x40, 0x74, 0x12, 0xDD, 0x01,
-0x54, 0x07, 0xD2, 0xBD, 0x40, 0x77, 0x40, 0x91, 0x10, 0x44, 0x0B, 0x10, 0x1D,
-0x00, 0x0F, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x33, 0x00,
-0xC1, 0x00, 0x34, 0x04, 0xD0, 0x10, 0x40, 0x20, 0x00, 0xD1, 0x00, 0x04, 0x00,
-0x50, 0x0C, 0x40, 0x23, 0x09, 0xC1, 0x84, 0x34, 0x02, 0x12, 0x00, 0x40, 0x20,
-0x00, 0xC1, 0x00, 0x04, 0x03, 0x90, 0x0C, 0x40, 0x30, 0x00, 0xDD, 0x00, 0x04,
-0x03, 0x90, 0x0C, 0x40, 0x35, 0x80, 0x95, 0x84, 0x04, 0x70, 0x14, 0x0C, 0x40,
-0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1,
-0x00, 0x74, 0x04, 0xD0, 0x41, 0x40, 0x64, 0x40, 0xD1, 0x08, 0x74, 0x44, 0x10,
-0x0D, 0x40, 0x27, 0x40, 0xD1, 0x00, 0x74, 0x06, 0x10, 0x01, 0x40, 0x26, 0x00,
-0xDD, 0x00, 0x54, 0x83, 0x10, 0x0D, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x54, 0x13,
-0xD0, 0x0D, 0x40, 0x27, 0x40, 0xD5, 0x18, 0x44, 0x02, 0x10, 0x0D, 0x48, 0x0F,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x88, 0x36, 0x00, 0xD3, 0x00,
-0x7C, 0x04, 0xF2, 0x14, 0xD0, 0x64, 0x00, 0x83, 0x80, 0x4C, 0x0E, 0x70, 0x0D,
-0xC0, 0x27, 0x00, 0xDB, 0x00, 0x7C, 0x1E, 0x30, 0x15, 0xD0, 0x24, 0x00, 0xDF,
-0x00, 0x0C, 0x03, 0xB1, 0x0D, 0xC0, 0x36, 0x00, 0xCF, 0x81, 0x4C, 0x03, 0xF0,
-0x0D, 0xC0, 0x33, 0x00, 0x87, 0x03, 0x4C, 0x27, 0x30, 0x0D, 0xC0, 0x03, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0xDC,
-0x40, 0xF0, 0x07, 0xC0, 0x3F, 0x08, 0xBF, 0x00, 0x9C, 0x02, 0xD0, 0x0F, 0xC0,
-0x21, 0x00, 0xFF, 0x00, 0xBC, 0x02, 0xF0, 0x96, 0xC0, 0x6D, 0x01, 0xEF, 0x00,
-0xFC, 0x03, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xDC, 0x07, 0xF0, 0x0F,
-0xC0, 0x3F, 0x00, 0xFB, 0x01, 0xFC, 0x03, 0xF0, 0x0D, 0xC0, 0x1F, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xD3, 0x00, 0x74, 0x00,
-0x30, 0x85, 0xC0, 0x25, 0x00, 0xD3, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC0, 0x37,
-0x00, 0xDF, 0x00, 0x4C, 0x3A, 0xD0, 0x05, 0x40, 0x24, 0x20, 0xD3, 0x08, 0x4D,
-0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x02, 0x70, 0x0D, 0xC0,
-0x37, 0x00, 0x93, 0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x28, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xD5, 0x05, 0x74, 0x14, 0x10,
-0x07, 0xC0, 0xB2, 0x00, 0xD1, 0x00, 0x74, 0x28, 0xD0, 0x0D, 0x40, 0x37, 0x00,
-0xF1, 0x00, 0x7C, 0x06, 0xD1, 0x0D, 0x43, 0x25, 0x00, 0xF5, 0x00, 0x54, 0x2F,
-0xD0, 0x0F, 0x40, 0x7C, 0x00, 0x51, 0x11, 0x7C, 0x02, 0x10, 0x1F, 0x40, 0x37,
-0x00, 0xD1, 0x04, 0x2C, 0x2F, 0xD0, 0x0F, 0x50, 0x4C, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0xA0, 0x26, 0x00, 0xC1, 0x01, 0x34, 0x0C, 0x18, 0x10,
-0x40, 0x20, 0x04, 0x81, 0x00, 0x34, 0x06, 0xD8, 0x0C, 0x40, 0x23, 0x00, 0xC9,
-0x40, 0x14, 0x0C, 0xD0, 0x04, 0x70, 0x20, 0x40, 0xC1, 0x00, 0x04, 0x03, 0xD8,
-0x0C, 0x40, 0x71, 0x00, 0xC1, 0x00, 0x34, 0x02, 0x18, 0x1C, 0x40, 0x33, 0x00,
-0x88, 0x80, 0x14, 0x07, 0xD0, 0x0C, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0F, 0x80, 0x68, 0x00, 0xE1, 0x01, 0xB4, 0x24, 0x18, 0x3B, 0x40,
-0x62, 0x00, 0xA0, 0x01, 0xB4, 0x45, 0xD8, 0x1E, 0x42, 0x6B, 0x60, 0xE1, 0x03,
-0xA4, 0x26, 0xD0, 0x14, 0x40, 0x6D, 0x00, 0xE5, 0x01, 0x94, 0x07, 0xD0, 0x1E,
-0x40, 0x79, 0x00, 0xE1, 0x01, 0xF4, 0x06, 0x10, 0x1E, 0x40, 0x7F, 0x40, 0x49,
-0x81, 0xB4, 0x47, 0xD0, 0x1E, 0x40, 0x7C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x10, 0x30, 0x08, 0xC3, 0x08, 0x7C, 0x20, 0x30, 0x00, 0x40, 0xA1,
-0x40, 0xC3, 0x00, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x1C,
-0x03, 0xF0, 0x84, 0x42, 0x20, 0x02, 0xC3, 0x00, 0x0C, 0x43, 0xF0, 0x0D, 0x48,
-0x31, 0x44, 0xC3, 0x88, 0x3E, 0x02, 0x71, 0x0C, 0xC1, 0x33, 0x00, 0x0B, 0x00,
-0x1C, 0x01, 0xF0, 0x8C, 0xC0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x20, 0xC4, 0x8B, 0xC0, 0x1F, 0x02,
-0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xF7, 0x10, 0xFC, 0x03,
-0xA0, 0x87, 0xC0, 0x2E, 0x10, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x3A,
-0x02, 0x7F, 0x08, 0xDC, 0x22, 0xF4, 0x8F, 0xC0, 0x2F, 0x42, 0xF7, 0x00, 0xCE,
-0x03, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7E, 0x04, 0x30, 0x01, 0xC0, 0x2C, 0x01, 0x93,
-0x00, 0xEC, 0x07, 0x30, 0x0D, 0xC0, 0x26, 0x00, 0xDF, 0x00, 0x1C, 0x02, 0x30,
-0x05, 0xC0, 0x26, 0x00, 0xFF, 0x00, 0x4C, 0x03, 0xF0, 0x8D, 0xE0, 0x37, 0x00,
-0xD3, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x13, 0x81, 0x4C, 0x07,
-0x34, 0x0F, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x88,
-0x39, 0x00, 0xED, 0x00, 0xB6, 0x00, 0x12, 0x62, 0xC0, 0x38, 0x04, 0xE1, 0x00,
-0xF4, 0x03, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xFB, 0x01, 0x84, 0x02, 0x10, 0x06,
-0x40, 0x3B, 0x00, 0xFD, 0x01, 0x85, 0x03, 0xD0, 0x4E, 0x40, 0x3B, 0x00, 0xE1,
-0x40, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1, 0x00, 0xAD, 0x03, 0x10,
-0x1E, 0x40, 0x4F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79,
-0x00, 0xED, 0x01, 0xB4, 0x86, 0x12, 0x13, 0x40, 0x60, 0x00, 0xED, 0x21, 0xB4,
-0x0F, 0xD0, 0x1E, 0x40, 0x73, 0x00, 0xE5, 0x05, 0xD4, 0x07, 0xD9, 0x16, 0x41,
-0x6B, 0x00, 0xED, 0x21, 0xA4, 0x07, 0x50, 0x1E, 0x40, 0x72, 0x20, 0xE1, 0x03,
-0xB4, 0x06, 0xD0, 0x1C, 0x40, 0x7E, 0x00, 0x25, 0x03, 0x84, 0x07, 0x10, 0x1E,
-0x40, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x73, 0x02,
-0xCD, 0x00, 0x34, 0x03, 0x10, 0x48, 0x06, 0x52, 0x00, 0xC9, 0x00, 0x34, 0xCF,
-0x90, 0x0C, 0x40, 0x73, 0x00, 0xC9, 0x00, 0x04, 0x13, 0x90, 0x7C, 0x40, 0x23,
-0x00, 0xDD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x49, 0x01, 0x34,
-0x02, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC5, 0x04, 0x24, 0x4B, 0x10, 0x0C, 0x40,
-0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x55, 0x00, 0x5F,
-0x00, 0xFC, 0x49, 0x34, 0x47, 0xD0, 0x5C, 0x41, 0x5F, 0x11, 0xFC, 0x01, 0xF4,
-0x05, 0xC0, 0x57, 0x00, 0x57, 0x00, 0xDC, 0x01, 0xE0, 0x27, 0xE0, 0x17, 0x00,
-0x5F, 0x00, 0x6E, 0x81, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x63, 0x01, 0x3C, 0x15,
-0xF2, 0x05, 0xF0, 0x54, 0x01, 0x77, 0x03, 0xC4, 0x1D, 0x30, 0x05, 0xC0, 0x5F,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x02,
-0x7C, 0xC0, 0xF0, 0x01, 0xC0, 0x85, 0x00, 0x17, 0x00, 0x7C, 0x08, 0x72, 0x01,
-0xC0, 0x07, 0x02, 0x1F, 0x02, 0x7C, 0x00, 0x74, 0x01, 0xC0, 0x07, 0x02, 0x1F,
-0x40, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x17, 0x00, 0x7C, 0x00, 0xF0,
-0x21, 0xE0, 0x07, 0x40, 0x1A, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC8, 0x4B, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x02, 0x7C,
-0x02, 0xF0, 0x08, 0xC0, 0x20, 0x00, 0x83, 0x03, 0x6C, 0x06, 0xF0, 0x09, 0xC0,
-0x23, 0x40, 0x91, 0x00, 0x04, 0x26, 0x34, 0x09, 0x00, 0x27, 0x00, 0x9F, 0x00,
-0x68, 0x06, 0xD0, 0x09, 0xE0, 0xE7, 0x08, 0x93, 0x45, 0x4C, 0x06, 0x32, 0x09,
-0xC0, 0x27, 0x08, 0x93, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x22, 0x40, 0x91, 0x01, 0x74, 0x82,
-0xD0, 0x09, 0x40, 0xA4, 0x04, 0x91, 0x01, 0x44, 0x36, 0xD0, 0x09, 0x40, 0x27,
-0x00, 0x95, 0x12, 0x6C, 0x0A, 0x10, 0x19, 0x42, 0x27, 0x00, 0x9D, 0x20, 0x44,
-0x06, 0xF0, 0x09, 0x40, 0x63, 0x01, 0x9B, 0x01, 0x44, 0x06, 0xB0, 0x29, 0x44,
-0x23, 0x40, 0x93, 0x0E, 0x5C, 0x1E, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x20, 0x91, 0x00, 0x54, 0x06, 0xD2,
-0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00,
-0x8D, 0x01, 0x74, 0x02, 0x50, 0x89, 0x64, 0x27, 0x00, 0x9D, 0x00, 0x75, 0x12,
-0xD2, 0x09, 0x00, 0x27, 0x80, 0x91, 0x00, 0x45, 0x12, 0x50, 0x89, 0x41, 0x27,
-0x00, 0x99, 0x00, 0x74, 0x02, 0xD2, 0x09, 0x44, 0x63, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x22, 0x24, 0x00, 0x81, 0x00, 0x34, 0x12, 0xD0, 0x48,
-0x50, 0x20, 0x01, 0x81, 0x84, 0x04, 0x02, 0xD8, 0x08, 0x40, 0x23, 0x01, 0x89,
-0x04, 0x34, 0x13, 0x00, 0x48, 0x60, 0x23, 0x20, 0x8D, 0x04, 0x14, 0x02, 0x50,
-0xC8, 0x40, 0x23, 0x01, 0x89, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x00,
-0x81, 0x04, 0x34, 0x12, 0xD0, 0x48, 0x48, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x53, 0x0A, 0x1C, 0x28, 0xF0, 0x05, 0x50,
-0x04, 0x40, 0x13, 0x00, 0x6C, 0x08, 0xF0, 0x01, 0xC4, 0x87, 0x02, 0x1D, 0x0A,
-0x7C, 0x28, 0x50, 0x01, 0xC0, 0x07, 0x00, 0x1D, 0x0A, 0x7C, 0x80, 0xC2, 0x61,
-0x40, 0x07, 0x05, 0x13, 0x00, 0x4C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1B,
-0x8A, 0x38, 0x28, 0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x19, 0xB8, 0x2F, 0x00, 0x9F, 0x00, 0xFC, 0x22, 0xF2, 0x8A, 0xD0, 0x2F,
-0x02, 0xBF, 0x08, 0xFC, 0x62, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0x97, 0x08, 0xEC,
-0x22, 0xF2, 0x8B, 0xC0, 0x2F, 0x00, 0x9B, 0x08, 0x6C, 0x02, 0xF0, 0x29, 0xCA,
-0x27, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xB0, 0x89, 0xC2, 0x2B, 0x00, 0xA7, 0x08,
-0xDC, 0x22, 0xF0, 0x89, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x19, 0xA0, 0x27, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x2C, 0x00,
-0xBF, 0x04, 0xFC, 0x52, 0xB0, 0x0B, 0xC0, 0x27, 0x40, 0xBB, 0x00, 0xC8, 0x22,
-0x34, 0x4B, 0xC0, 0x24, 0x00, 0xBF, 0x0C, 0xDD, 0x02, 0xB0, 0x19, 0xC0, 0x6F,
-0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x5B, 0xC0, 0x20, 0x00, 0xB3, 0x00, 0xCC,
-0x22, 0x30, 0x4B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
-0x08, 0x07, 0x01, 0x1D, 0x04, 0x36, 0xC9, 0x10, 0x05, 0xE2, 0x04, 0x02, 0x1D,
-0x00, 0x74, 0x10, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x13, 0x00, 0x54, 0x20, 0x18,
-0x01, 0xE0, 0x06, 0x80, 0x0D, 0x0C, 0x44, 0x00, 0x50, 0x11, 0x40, 0x07, 0x02,
-0x11, 0x00, 0x74, 0x00, 0xD0, 0xA1, 0x40, 0x04, 0x00, 0x11, 0x10, 0x44, 0x20,
-0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0,
-0x23, 0x05, 0x8D, 0x04, 0x34, 0xB2, 0x10, 0x88, 0x40, 0x20, 0x00, 0x8D, 0x08,
-0x34, 0x52, 0xD0, 0x08, 0x42, 0x23, 0x00, 0x85, 0x00, 0x04, 0x02, 0x54, 0x88,
-0x42, 0x22, 0x00, 0x8D, 0x04, 0x14, 0x02, 0x10, 0x68, 0x41, 0x23, 0x00, 0x81,
-0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x26, 0x10, 0x85, 0x48, 0x04, 0x07, 0x14,
-0x88, 0x40, 0x4B, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25,
-0x00, 0x9D, 0x00, 0x74, 0x06, 0x14, 0x09, 0x40, 0x26, 0x04, 0x9D, 0x01, 0x74,
-0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x89, 0x00, 0x54, 0x52, 0x10, 0x09, 0x40,
-0x26, 0x01, 0x9D, 0x00, 0x44, 0x02, 0x52, 0x09, 0x40, 0x27, 0x40, 0x91, 0x08,
-0x74, 0x12, 0xD0, 0x0D, 0x40, 0x66, 0x40, 0x95, 0x04, 0x04, 0x06, 0x10, 0x09,
-0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00,
-0x9F, 0x00, 0x74, 0x0E, 0x30, 0x29, 0x50, 0xE4, 0x00, 0x9F, 0x01, 0x7C, 0x46,
-0xF0, 0x09, 0xC0, 0x67, 0x00, 0x97, 0x00, 0x4C, 0x02, 0x50, 0x09, 0x41, 0x26,
-0x80, 0x9D, 0x00, 0x5C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x92, 0x03, 0x7C,
-0x06, 0xF2, 0x09, 0xD0, 0x22, 0x00, 0x97, 0x07, 0x4D, 0x02, 0x30, 0x09, 0xC0,
-0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x65, 0x02, 0x9F,
-0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x05, 0x9F, 0x00, 0x7C, 0x4E, 0xF0,
-0x09, 0xC0, 0x67, 0x02, 0x97, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x67, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0x80, 0x23, 0x00, 0x9F, 0x00, 0x7C, 0x06,
-0xF0, 0x08, 0xC0, 0x25, 0x00, 0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x5B,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00,
-0x7C, 0x18, 0x94, 0x31, 0x50, 0x06, 0x40, 0x13, 0x00, 0x7C, 0x20, 0x70, 0x01,
-0xC0, 0x07, 0x00, 0x1D, 0x48, 0x78, 0x48, 0x32, 0x21, 0xC0, 0x07, 0x00, 0x1F,
-0x00, 0x4C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x00, 0xF0,
-0x41, 0xC0, 0x07, 0x00, 0x03, 0x02, 0x4C, 0x04, 0x30, 0x01, 0xC0, 0x50, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x7D, 0x04, 0xF4,
-0x01, 0x30, 0x46, 0x40, 0x5C, 0x00, 0x51, 0x11, 0xF4, 0x09, 0x70, 0x55, 0x40,
-0x17, 0x00, 0x7D, 0x00, 0xF4, 0x09, 0x10, 0x14, 0x40, 0x17, 0x00, 0x5D, 0x00,
-0x84, 0x41, 0x70, 0x05, 0x40, 0x1F, 0x01, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x27,
-0x40, 0x17, 0x00, 0x72, 0x00, 0xC4, 0x01, 0x14, 0x05, 0xC1, 0x52, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x03, 0x74, 0x03,
-0x10, 0x1C, 0x60, 0xB0, 0x00, 0xC1, 0x00, 0x34, 0x0B, 0x58, 0x0C, 0x40, 0x37,
-0x00, 0x8D, 0x01, 0x74, 0x09, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x01, 0x14,
-0x8F, 0xD0, 0x0C, 0x40, 0xF3, 0x01, 0x89, 0x00, 0x34, 0x03, 0xD0, 0x24, 0x40,
-0x33, 0x80, 0x49, 0x0D, 0x04, 0x02, 0x12, 0x18, 0x00, 0x50, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x01, 0xA9, 0x00, 0xB4, 0x18, 0x10,
-0x02, 0x40, 0x70, 0x04, 0xE1, 0x00, 0xB4, 0x01, 0x50, 0x0E, 0x40, 0x3A, 0x01,
-0x29, 0x00, 0xA4, 0x00, 0x14, 0x0A, 0x41, 0x3B, 0x00, 0xED, 0x02, 0x84, 0x03,
-0x40, 0x4E, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4, 0x03, 0xD0, 0x06, 0x41, 0x3F,
-0x00, 0x61, 0x00, 0x84, 0x02, 0x10, 0x18, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x01, 0xAD, 0x01, 0xBC, 0x0E, 0x30, 0x14,
-0xD0, 0x78, 0x00, 0xE3, 0x41, 0xBE, 0x07, 0x70, 0x1E, 0xC0, 0x7B, 0x01, 0x6D,
-0x01, 0x3C, 0x05, 0x30, 0x1A, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0x9D, 0x07, 0xD0,
-0x5E, 0xC2, 0x7B, 0x00, 0xAB, 0x01, 0xB4, 0x06, 0xF0, 0x16, 0xC0, 0x7B, 0x00,
-0xF9, 0x01, 0x8D, 0x07, 0x30, 0x1A, 0xC4, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xB8, 0xB5, 0x00, 0xBF, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0,
-0x17, 0x00, 0xDF, 0x00, 0x7E, 0x03, 0xC0, 0x0D, 0xC0, 0x77, 0x00, 0x5F, 0x00,
-0xFC, 0x00, 0xF0, 0x09, 0x80, 0x37, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0x70, 0x8D,
-0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x37, 0x40, 0xDF,
-0x00, 0x3C, 0x00, 0xF4, 0x09, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0xA0, 0xFF, 0x04, 0xB3, 0x01, 0xFC, 0x23, 0x38, 0x03, 0xC0, 0x6C,
-0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0x40, 0x7F, 0x06, 0xF3, 0x01, 0xCC,
-0x85, 0x30, 0x1B, 0xE0, 0x7F, 0x02, 0xAF, 0x03, 0xCC, 0x06, 0xF0, 0x1F, 0xC0,
-0x4F, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x16, 0xC0, 0x7C, 0x40, 0xFB, 0x81,
-0xFC, 0x06, 0x31, 0x1A, 0xC0, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x88, 0x3D, 0x00, 0xA1, 0x00, 0xB4, 0x13, 0x18, 0x42, 0x00, 0x28, 0x40,
-0xE1, 0x50, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x3F, 0x00, 0x6F, 0x00, 0x94, 0x02,
-0x10, 0x0A, 0xC0, 0x3B, 0x00, 0xED, 0x24, 0x84, 0x03, 0xD0, 0x8E, 0x40, 0x1B,
-0x00, 0xAD, 0x00, 0xB4, 0x23, 0xD0, 0x06, 0xC0, 0x38, 0x00, 0xE1, 0x00, 0xB4,
-0x02, 0x10, 0x0A, 0x40, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-0x00, 0x39, 0x00, 0x21, 0x00, 0xB4, 0x22, 0x18, 0x83, 0x40, 0x20, 0x00, 0xE9,
-0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x40, 0x61, 0x00, 0x04, 0x01, 0x90,
-0x0A, 0x40, 0x3B, 0x20, 0xAD, 0x40, 0xA4, 0x03, 0xD0, 0x0E, 0x40, 0x2B, 0x00,
-0xAD, 0x00, 0xB4, 0x02, 0xD0, 0x06, 0x40, 0x3D, 0x00, 0xE1, 0x00, 0x34, 0x0B,
-0x10, 0x0A, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28,
-0x33, 0x00, 0x11, 0x00, 0x34, 0x02, 0x12, 0x20, 0x40, 0x00, 0x00, 0xC9, 0x00,
-0x34, 0x26, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x00, 0x14, 0x00, 0x90, 0x28,
-0x40, 0x71, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
-0x02, 0x24, 0x02, 0xD0, 0x04, 0x40, 0x30, 0x10, 0x81, 0x02, 0x34, 0x03, 0x11,
-0x08, 0x40, 0x19, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x3D,
-0x40, 0x93, 0x00, 0xFC, 0x03, 0x14, 0x21, 0xC0, 0xE4, 0x02, 0xDB, 0x01, 0x74,
-0x2A, 0xF0, 0x0C, 0xC0, 0x3F, 0x00, 0x93, 0x00, 0x4C, 0x01, 0xB4, 0x09, 0x40,
-0x37, 0x00, 0x9F, 0x00, 0x6D, 0x01, 0xF0, 0x0F, 0xC0, 0x37, 0x00, 0x8F, 0x13,
-0x7C, 0x02, 0xF0, 0x04, 0xC0, 0x34, 0x00, 0x53, 0x0B, 0x7C, 0x82, 0x30, 0x0D,
-0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00,
-0x9F, 0x00, 0x7C, 0x20, 0xF0, 0x00, 0xD0, 0xE7, 0x10, 0xD7, 0x00, 0x7C, 0x80,
-0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x00, 0x3C, 0x40, 0x70, 0x09, 0xC0, 0x37,
-0x02, 0x9F, 0x00, 0x5C, 0x83, 0xF2, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C,
-0x02, 0xF0, 0x05, 0xC0, 0x75, 0x00, 0x47, 0x81, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
-0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x3F, 0x00, 0xBF,
-0x00, 0x8C, 0x23, 0xB0, 0x03, 0xD1, 0x28, 0x00, 0xB3, 0x05, 0xFC, 0x00, 0xF0,
-0x0F, 0xC0, 0x38, 0x00, 0x6B, 0x00, 0xCC, 0x00, 0xB0, 0x8B, 0xE1, 0x3F, 0x00,
-0xBF, 0x00, 0xCC, 0x01, 0xF0, 0x0F, 0xC0, 0x4F, 0x00, 0xBF, 0x14, 0xDC, 0x0F,
-0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x8C, 0x22, 0x10, 0x9F, 0xC0, 0x07,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x36, 0x00, 0x9D, 0x01,
-0x44, 0x04, 0x90, 0x11, 0x58, 0x44, 0x04, 0x91, 0x00, 0x76, 0x04, 0xD0, 0x0D,
-0xE0, 0x36, 0x00, 0x51, 0x00, 0x44, 0x04, 0x10, 0x09, 0xC0, 0x36, 0x00, 0x9D,
-0x00, 0x6C, 0x47, 0xD0, 0x0D, 0x40, 0x97, 0x02, 0xDD, 0x01, 0x6C, 0x07, 0xD0,
-0x3D, 0xC0, 0x32, 0x00, 0xD1, 0x01, 0x44, 0x04, 0x10, 0x1D, 0xC2, 0x25, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x10, 0x9D, 0x01, 0x44,
-0x03, 0x90, 0x11, 0x40, 0x46, 0x40, 0xD1, 0x00, 0x74, 0x0E, 0xD1, 0x19, 0x42,
-0x34, 0x00, 0xD9, 0x00, 0x44, 0x05, 0x9A, 0x09, 0x40, 0x37, 0x20, 0x8D, 0x08,
-0x46, 0x07, 0xD0, 0x0D, 0x42, 0x17, 0x04, 0x9D, 0x00, 0x54, 0x02, 0xD0, 0x1D,
-0x40, 0x34, 0x00, 0xD1, 0x01, 0x40, 0x02, 0x50, 0x09, 0x40, 0x07, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x8D, 0x00, 0x04, 0x03,
-0x90, 0x10, 0x40, 0x02, 0x00, 0xC1, 0x00, 0x34, 0x00, 0xD2, 0x08, 0x40, 0x32,
-0x00, 0x41, 0x00, 0x04, 0x02, 0x10, 0x08, 0x60, 0x31, 0x00, 0x8D, 0x00, 0x05,
-0x03, 0xD8, 0x0C, 0x40, 0x03, 0x00, 0xDD, 0x00, 0x04, 0x02, 0xD0, 0x0C, 0x48,
-0x36, 0x00, 0xC1, 0x00, 0x04, 0x02, 0x50, 0x08, 0x40, 0x41, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3E, 0x00, 0x1F, 0x00, 0x05, 0x03, 0xB0,
-0x01, 0xC0, 0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0xF0, 0x09, 0x40, 0x34, 0x00,
-0x4B, 0x00, 0x4C, 0x00, 0xB0, 0x09, 0x44, 0x37, 0x00, 0xBF, 0x00, 0x44, 0x03,
-0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F, 0x00, 0x54, 0x03, 0xF0, 0x0D, 0xC0, 0x34,
-0x00, 0xD3, 0x00, 0x4D, 0x02, 0x70, 0x09, 0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x78, 0x02,
-0xC0, 0x0D, 0x00, 0xFF, 0x40, 0xF6, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0x7F,
-0x00, 0xFD, 0x00, 0xF0, 0x0B, 0xC8, 0x3E, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0,
-0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3B, 0x00,
-0xFF, 0x00, 0xFC, 0x02, 0xB0, 0x0B, 0xC0, 0x15, 0x60, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0xA0, 0x7F, 0x02, 0xF3, 0x01, 0xFC, 0x27, 0xF0, 0x1F, 0xC0,
-0x7F, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x09,
-0xCC, 0x07, 0xF0, 0x3F, 0xC0, 0x7C, 0x02, 0xFF, 0x21, 0xCC, 0x07, 0x30, 0x9F,
-0xC0, 0x78, 0x00, 0xF3, 0x01, 0xFC, 0x22, 0xF0, 0x3F, 0xC0, 0x5E, 0x10, 0xBB,
-0x01, 0xEC, 0x84, 0x38, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x00, 0x07, 0x00, 0x11, 0x01, 0x74, 0x10, 0xD1, 0x01, 0x40, 0x47,
-0x00, 0x11, 0x04, 0x74, 0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0x1D, 0x04, 0x44,
-0x84, 0xD0, 0x01, 0x48, 0x04, 0x01, 0x1D, 0x01, 0x44, 0x04, 0x12, 0x41, 0x40,
-0x44, 0x40, 0x11, 0x01, 0x74, 0x38, 0xD0, 0x0D, 0x40, 0x55, 0x00, 0xD1, 0x01,
-0x54, 0x03, 0xB0, 0x01, 0x40, 0x0D, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x11, 0xA0, 0x33, 0x11, 0xC1, 0x00, 0x34, 0x83, 0xD0, 0x4C, 0x41, 0x37, 0x00,
-0xC1, 0x10, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, 0x04, 0x03,
-0xD0, 0x4D, 0x40, 0x30, 0x01, 0xD5, 0xA0, 0x64, 0x83, 0x10, 0x4C, 0x40, 0x35,
-0x00, 0xC9, 0x00, 0x34, 0x10, 0xD0, 0x4C, 0x40, 0x30, 0x60, 0xD9, 0x40, 0x24,
-0x01, 0x10, 0x08, 0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA8, 0x05, 0x40, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x01, 0x40, 0x07, 0x00, 0x11,
-0x00, 0x74, 0x00, 0xD1, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0,
-0x01, 0x48, 0x04, 0x00, 0x1D, 0x00, 0x64, 0x00, 0x10, 0x01, 0x40, 0x04, 0x20,
-0x19, 0x00, 0x74, 0x0C, 0xD0, 0x1C, 0x40, 0x75, 0x00, 0xD1, 0x01, 0x54, 0x0B,
-0x15, 0x19, 0x41, 0x0D, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
-0x37, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x00,
-0x7C, 0x03, 0xD0, 0x0D, 0xC0, 0x37, 0x00, 0xCF, 0x00, 0x4C, 0x03, 0xF0, 0x0D,
-0xD0, 0x34, 0x00, 0xD7, 0x00, 0x6C, 0x03, 0x30, 0x0D, 0xD0, 0x34, 0x00, 0xDB,
-0x00, 0x7C, 0x0E, 0xE0, 0x1D, 0xC0, 0xC0, 0x04, 0xCB, 0x01, 0x6C, 0x04, 0x10,
-0x19, 0xC0, 0x20, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x0D,
-0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0x40, 0x0F, 0x00, 0x3F, 0x00, 0xFC,
-0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC4,
-0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC8, 0x0F, 0x00, 0x37, 0x40,
-0x7C, 0x42, 0xF0, 0x07, 0xC2, 0x1F, 0x00, 0xFF, 0x00, 0xEC, 0xA4, 0xF0, 0x00,
-0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x75, 0x01,
-0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xD0, 0x74, 0x00, 0xD3, 0x00, 0x4D, 0x03,
-0xF0, 0x0D, 0xC8, 0x37, 0x40, 0xD3, 0x00, 0x7C, 0x07, 0x30, 0x8D, 0xC1, 0x37,
-0x14, 0xDF, 0x01, 0x4C, 0x23, 0xF0, 0x0D, 0xC0, 0x76, 0x04, 0xD3, 0x40, 0x6C,
-0x28, 0x30, 0x09, 0xC0, 0x37, 0x01, 0xD3, 0x00, 0x7C, 0xC8, 0x20, 0x29, 0xC6,
-0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0x1D,
-0x0F, 0x74, 0x10, 0x10, 0x11, 0x42, 0x04, 0x00, 0x11, 0x0A, 0x44, 0x00, 0xD0,
-0x01, 0x40, 0x07, 0x00, 0x11, 0x13, 0x74, 0x00, 0x10, 0x00, 0x40, 0xC7, 0x10,
-0x0D, 0x00, 0x34, 0x04, 0xD0, 0x31, 0x40, 0x83, 0x00, 0x11, 0xA5, 0x74, 0x08,
-0x10, 0x05, 0x40, 0x37, 0x00, 0xD1, 0x11, 0x74, 0x0E, 0xB0, 0x09, 0x40, 0x4C,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xB4, 0x00, 0xCD, 0x03,
-0x34, 0x43, 0x10, 0x6C, 0x40, 0x30, 0x00, 0xC1, 0x01, 0x04, 0x03, 0xD0, 0x0C,
-0x40, 0x73, 0x00, 0xC1, 0x00, 0x14, 0x03, 0x10, 0x2C, 0x44, 0x33, 0x00, 0xCD,
-0x00, 0x34, 0x07, 0xD0, 0x7D, 0x40, 0x33, 0x80, 0xC1, 0x81, 0x34, 0x0E, 0xD0,
-0x0C, 0x40, 0xB3, 0x00, 0xC1, 0x11, 0x64, 0x02, 0x10, 0x00, 0x40, 0x0C, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00, 0x2D, 0x01, 0xF4,
-0x04, 0x10, 0x13, 0x48, 0x4C, 0x00, 0x21, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x40,
-0x4B, 0x04, 0x21, 0x03, 0xF4, 0x04, 0x10, 0x12, 0x40, 0x4B, 0x14, 0x2D, 0x01,
-0xB4, 0x04, 0xD0, 0x12, 0x40, 0x4F, 0x40, 0x21, 0x01, 0xB4, 0x05, 0xD0, 0x1E,
-0x40, 0x7F, 0x00, 0x61, 0x01, 0xB4, 0xA7, 0x90, 0x12, 0x40, 0x3C, 0x20, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x92, 0xCF, 0x00, 0x3C, 0x03,
-0x30, 0x0C, 0xC1, 0x30, 0x00, 0xD3, 0x10, 0x0C, 0x23, 0xF0, 0x0C, 0xC0, 0x33,
-0x00, 0xC3, 0x00, 0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x1C,
-0x03, 0xF0, 0x0C, 0xC1, 0x33, 0x20, 0xC1, 0x00, 0x3E, 0x23, 0xF4, 0x0C, 0xC0,
-0x33, 0x80, 0xC3, 0x08, 0x7C, 0x63, 0x30, 0x80, 0xD0, 0x48, 0x40, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0xF0,
-0x02, 0xC0, 0x0B, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x83, 0xC0, 0x03, 0x00,
-0x1F, 0x40, 0xBC, 0x20, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x1F, 0x00, 0x7C, 0x00,
-0xF0, 0x81, 0xC0, 0x07, 0x02, 0x1F, 0x41, 0xFC, 0xA3, 0x20, 0x8F, 0xC8, 0x3B,
-0x00, 0x7F, 0x00, 0xFC, 0x23, 0xF0, 0x07, 0xC0, 0x0B, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
-0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xD0, 0x74, 0x40, 0xD3, 0x00, 0x7C, 0x03, 0xF0,
-0x1D, 0xD0, 0x30, 0x00, 0xC3, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x80,
-0xDF, 0x00, 0x7C, 0x00, 0x30, 0x09, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x32, 0x88, 0x09, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40,
-0x0B, 0x20, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40, 0x08, 0x00, 0x2D, 0x00,
-0xB4, 0x00, 0xD0, 0x03, 0x40, 0x0C, 0x00, 0x21, 0x00, 0xB4, 0x00, 0xD0, 0x03,
-0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x83, 0xD0, 0x06, 0x40, 0x3B, 0x20, 0x6D,
-0x40, 0xF4, 0x01, 0x10, 0x02, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B,
-0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1F, 0x40, 0x7A, 0x00, 0xED, 0x01, 0xB4,
-0x87, 0xD0, 0x1E, 0x40, 0x7A, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40,
-0x78, 0x00, 0xF1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x51,
-0xB4, 0x87, 0x10, 0x1E, 0x41, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x36, 0x28, 0x03, 0x00, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00,
-0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x02, 0x10, 0x1D, 0x20, 0x34, 0x00,
-0xD0, 0x00, 0x40, 0x02, 0x00, 0x01, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x00,
-0x10, 0x01, 0x00, 0x14, 0x9B, 0xD0, 0x04, 0x42, 0x33, 0x00, 0x4D, 0x01, 0x34,
-0x03, 0x11, 0x2C, 0x41, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
-0xA0, 0x15, 0x00, 0x4F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC4, 0x13, 0x00, 0x5F,
-0x00, 0x7C, 0x01, 0xF0, 0x05, 0xD0, 0x16, 0x00, 0x5F, 0x00, 0x74, 0x01, 0xF0,
-0x05, 0xC2, 0x16, 0x00, 0x51, 0x00, 0x3C, 0x01, 0xF0, 0x05, 0xC4, 0x14, 0x40,
-0x53, 0x00, 0xCC, 0x09, 0xD1, 0x87, 0x40, 0x1F, 0x00, 0x7D, 0x01, 0xBC, 0x05,
-0x14, 0x27, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08,
-0x0D, 0x08, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x3F, 0x00,
-0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x20, 0x3F, 0x80, 0xFC, 0x00, 0xB0, 0x03,
-0xC0, 0x0D, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x3F,
-0x00, 0x65, 0x20, 0xF0, 0x81, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x7C, 0x38, 0xF0,
-0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25,
-0x02, 0x9F, 0x00, 0x6C, 0x0E, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x05, 0x7C,
-0x02, 0x30, 0x09, 0xC0, 0x67, 0x02, 0x9F, 0x08, 0x6C, 0x82, 0xF0, 0x49, 0xC0,
-0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC8, 0x27, 0x00, 0x93, 0x05,
-0x0C, 0x02, 0x32, 0x09, 0xC2, 0x27, 0x02, 0x9D, 0x04, 0x5C, 0x02, 0x34, 0x09,
-0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00,
-0x9D, 0x02, 0x44, 0x0E, 0xD8, 0x29, 0x40, 0x27, 0x00, 0x9B, 0x43, 0x34, 0x02,
-0x10, 0x09, 0x40, 0x27, 0x08, 0x9F, 0x02, 0x44, 0x02, 0xE0, 0x29, 0x40, 0xA7,
-0x00, 0x9D, 0x00, 0x74, 0x02, 0xB0, 0x29, 0x40, 0x23, 0x10, 0x8B, 0x01, 0x44,
-0x16, 0x10, 0x09, 0x48, 0xA7, 0x04, 0x8D, 0x00, 0x6C, 0x4E, 0x10, 0x09, 0x48,
-0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x24, 0x00, 0xBD,
-0x50, 0xE6, 0x02, 0xD0, 0x8B, 0x41, 0x6F, 0x08, 0xB5, 0x40, 0xF4, 0x02, 0x10,
-0x0B, 0x40, 0x2F, 0x00, 0xBD, 0x10, 0xC4, 0x06, 0xC0, 0x0B, 0x40, 0x2F, 0x01,
-0xBD, 0x08, 0xF4, 0x06, 0x10, 0x8B, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0x45, 0x22,
-0x18, 0x09, 0x40, 0x27, 0x00, 0xDC, 0x00, 0x64, 0x06, 0x10, 0x09, 0x40, 0x73,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x68, 0x00, 0xAD, 0x00,
-0x86, 0x86, 0xD0, 0x0A, 0x40, 0x2B, 0x80, 0xA1, 0x01, 0xF4, 0x02, 0x10, 0x0A,
-0x40, 0x2B, 0x00, 0xA5, 0x00, 0x84, 0x02, 0x50, 0x1A, 0x40, 0x6B, 0x00, 0xAD,
-0x00, 0xB4, 0x02, 0x90, 0x1A, 0x40, 0x2B, 0x00, 0xB9, 0x00, 0x04, 0x12, 0x14,
-0x08, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x64, 0x02, 0x10, 0x48, 0x40, 0x53, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x1F, 0x00, 0x6C,
-0x28, 0xD0, 0xA1, 0xC0, 0x07, 0x00, 0x15, 0x4A, 0x7C, 0x00, 0x34, 0x01, 0xC0,
-0x07, 0x00, 0x1D, 0x0A, 0x4D, 0x00, 0xD0, 0xA1, 0xC0, 0x87, 0x02, 0x1F, 0x00,
-0x7C, 0x00, 0x30, 0xA1, 0x40, 0x07, 0x00, 0x33, 0x00, 0x4C, 0x28, 0x30, 0xA1,
-0xC0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x28, 0x39, 0xA1, 0xC0, 0x77, 0xC0, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x82,
-0xF0, 0x09, 0xC0, 0x27, 0x48, 0x9F, 0x00, 0x7C, 0x02, 0xF1, 0x08, 0xC0, 0x27,
-0x08, 0x9F, 0x40, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF2, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0xA2, 0xF0, 0x0B, 0xC0,
-0x2F, 0x00, 0xBF, 0x20, 0xFC, 0x02, 0xF0, 0x8F, 0xC0, 0x67, 0x20, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0x30,
-0x0B, 0xC2, 0x2C, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x28,
-0xBF, 0x00, 0xDC, 0x02, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x02,
-0xF0, 0x0B, 0x80, 0x2F, 0x10, 0xBF, 0x00, 0xDC, 0x52, 0x30, 0x88, 0xC2, 0x29,
-0x00, 0xB3, 0x00, 0xDC, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x11, 0x00, 0x74, 0x40, 0x12, 0x01,
-0x49, 0x04, 0x00, 0x1D, 0x14, 0x74, 0x00, 0xD0, 0x01, 0x48, 0x07, 0x20, 0x17,
-0x10, 0x74, 0x00, 0x50, 0x41, 0x41, 0x07, 0x01, 0x1D, 0x80, 0x74, 0x00, 0xD0,
-0x01, 0x49, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x10, 0x10, 0x41, 0x44, 0x07, 0x00,
-0x11, 0x00, 0x5C, 0x81, 0xD2, 0x41, 0x45, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81, 0x60, 0x14, 0x12, 0x14, 0x08, 0x40,
-0x20, 0x00, 0x8D, 0x04, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x33, 0x00, 0x8D, 0x00,
-0x14, 0x03, 0x10, 0x48, 0x40, 0x33, 0x85, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x08,
-0x40, 0x23, 0x00, 0x8D, 0x00, 0x14, 0x52, 0xD0, 0x48, 0x40, 0x21, 0x00, 0x89,
-0x00, 0x14, 0x02, 0xD9, 0x48, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0x08, 0x25, 0x00, 0x91, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x50, 0x24,
-0x10, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x95, 0x00, 0x74,
-0x02, 0x51, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x40,
-0x27, 0x00, 0x9D, 0x00, 0x74, 0x06, 0xD0, 0x89, 0x40, 0xE7, 0x00, 0x99, 0x01,
-0x50, 0x12, 0xD0, 0x09, 0x60, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0x20, 0x25, 0x00, 0x93, 0x80, 0x5C, 0x02, 0x31, 0x09, 0xC2, 0x24, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x27, 0x00, 0x9F, 0x40, 0x5C, 0x02,
-0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x80, 0x5C, 0x12, 0xB4, 0x09, 0xC0, 0xE1, 0x40, 0x9B, 0x01, 0x58,
-0x06, 0xF0, 0x09, 0xC4, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-0x08, 0x25, 0x40, 0x9F, 0x00, 0x7C, 0x02, 0xF3, 0x09, 0x40, 0x27, 0x10, 0x9F,
-0x00, 0x7C, 0x02, 0xF0, 0x09, 0x80, 0x27, 0x00, 0x96, 0x00, 0x70, 0x02, 0x70,
-0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27, 0x04,
-0x9F, 0xA0, 0x7C, 0x02, 0x20, 0x09, 0xC0, 0x27, 0x00, 0x96, 0x00, 0x5C, 0x42,
-0xF1, 0x49, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
-0x05, 0x06, 0x1F, 0x01, 0x6C, 0x10, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00,
-0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
-0xC3, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x08, 0x13,
-0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC0, 0x05, 0x08, 0x17, 0x00, 0x6C, 0x28, 0xF0,
-0x21, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x5C,
-0x00, 0x7D, 0x11, 0xC4, 0x0D, 0x72, 0x57, 0x40, 0x14, 0x04, 0x7F, 0x41, 0x44,
-0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x20, 0x34, 0x01, 0x72, 0x07, 0xC9,
-0x1E, 0x02, 0x51, 0x00, 0x74, 0x01, 0x70, 0xD7, 0x00, 0x9F, 0x04, 0x51, 0x01,
-0xC4, 0x15, 0x00, 0x05, 0x40, 0x1C, 0x00, 0x71, 0x05, 0xE4, 0x0D, 0xD0, 0x05,
-0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xF6, 0x00,
-0x4D, 0x21, 0x64, 0x2F, 0x50, 0x4D, 0x40, 0x20, 0x20, 0xCD, 0x04, 0x04, 0x03,
-0xD0, 0x0C, 0x40, 0x23, 0x00, 0xCD, 0x0D, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0xB0,
-0x00, 0x89, 0x00, 0x34, 0x02, 0x50, 0x2C, 0x40, 0xF3, 0x00, 0x81, 0x89, 0x44,
-0x13, 0x91, 0x0C, 0x40, 0x01, 0x00, 0x85, 0x01, 0x24, 0x0F, 0xD0, 0x0C, 0x42,
-0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED,
-0x01, 0x86, 0x01, 0x50, 0x0E, 0x50, 0x38, 0x00, 0xF5, 0x11, 0x84, 0x03, 0xD0,
-0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1F, 0x40, 0x5A, 0x40,
-0xE9, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x40, 0x6B, 0x40, 0xE1, 0x01, 0xC6, 0x03,
-0x10, 0x5F, 0x40, 0x2C, 0x08, 0x61, 0x00, 0xA4, 0x03, 0xD2, 0x4E, 0x60, 0x07,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01,
-0xAC, 0x07, 0x70, 0x1F, 0xC0, 0x78, 0x20, 0xED, 0x01, 0x85, 0x07, 0xF0, 0x1E,
-0xC6, 0x7B, 0x00, 0xED, 0x01, 0xBC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xEB,
-0x01, 0xBC, 0x07, 0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xE3, 0x01, 0xCC, 0x05, 0xB0,
-0x9E, 0xC0, 0x79, 0x00, 0x65, 0x41, 0xAC, 0x04, 0xF0, 0x5E, 0xC0, 0x47, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xCF, 0x00, 0x7C,
-0x01, 0x71, 0x0D, 0xC4, 0x37, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x40,
-0x37, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x17, 0x10, 0xD7, 0x80,
-0x7C, 0x83, 0x70, 0x0D, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x7C, 0x01, 0xF0, 0x8D,
-0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x00, 0xF0, 0x8D, 0xC0, 0x43, 0x60, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x5D, 0x00, 0xFF, 0x01, 0xCC, 0x13,
-0xF0, 0x5F, 0xC0, 0x7B, 0x62, 0x73, 0x41, 0xBC, 0x07, 0x30, 0x1F, 0xC0, 0x7F,
-0x00, 0xF3, 0x01, 0xFC, 0x27, 0xF0, 0x17, 0xC0, 0x78, 0x00, 0xFB, 0x09, 0xEC,
-0x27, 0x30, 0x1E, 0xC0, 0x78, 0x00, 0xF3, 0x00, 0xFC, 0x07, 0xF0, 0x1F, 0xC0,
-0x4C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x08, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x16, 0xED, 0x00, 0x84, 0x01, 0xD0,
-0x06, 0x40, 0x3B, 0x06, 0x65, 0x00, 0xB4, 0x03, 0x10, 0x8E, 0x40, 0x3B, 0x02,
-0x61, 0x08, 0xB4, 0x03, 0xD2, 0x47, 0x40, 0x38, 0x00, 0xE1, 0x08, 0x84, 0x03,
-0x10, 0x0E, 0x40, 0x38, 0x04, 0xE5, 0x08, 0xB4, 0x29, 0xD0, 0x0F, 0x40, 0x29,
-0x02, 0x6D, 0x00, 0xB4, 0x22, 0xD0, 0x0E, 0xC0, 0x56, 0x60, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0xFD, 0x00, 0x84, 0x23, 0xD0, 0x4E,
-0x48, 0x3B, 0x12, 0x60, 0x00, 0xF4, 0x03, 0x10, 0x2E, 0x40, 0x3F, 0x00, 0xE1,
-0x00, 0xB4, 0x03, 0xC1, 0x06, 0x60, 0x9C, 0x00, 0xF1, 0x80, 0xC6, 0x03, 0x10,
-0x87, 0x40, 0xB8, 0x00, 0xE1, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x00,
-0x6D, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x60, 0x08, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xCD, 0x12, 0x44, 0x2C, 0xD0, 0xA8, 0x40,
-0xB3, 0x04, 0x11, 0x03, 0x34, 0x0B, 0x10, 0x0C, 0x40, 0xB3, 0x04, 0x91, 0x03,
-0x34, 0x0B, 0x90, 0x20, 0x40, 0x00, 0x00, 0xC1, 0x02, 0x04, 0x0B, 0x10, 0x08,
-0x41, 0x30, 0x40, 0xC5, 0x01, 0x74, 0x40, 0xD0, 0x1C, 0x40, 0x31, 0x10, 0x4D,
-0x0A, 0x30, 0x02, 0xC1, 0x2D, 0x48, 0x1A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0xA0, 0x61, 0x00, 0xCF, 0x00, 0x4C, 0x22, 0xF0, 0x21, 0xC0, 0xF7,
-0x00, 0x93, 0x11, 0x7C, 0x0B, 0x34, 0x5C, 0xC0, 0x33, 0x00, 0x13, 0x01, 0x7C,
-0x23, 0xF0, 0x79, 0xD0, 0x64, 0x01, 0xC3, 0x08, 0x4C, 0x23, 0x30, 0x51, 0xC0,
-0x34, 0x00, 0xD3, 0x00, 0x7C, 0x06, 0xF0, 0x5F, 0xC0, 0x10, 0x20, 0xCF, 0x23,
-0x7C, 0x08, 0xC0, 0xBF, 0x80, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0x08, 0x27, 0x20, 0xDF, 0x01, 0x7C, 0x02, 0xF1, 0x21, 0xC8, 0x37, 0x00,
-0x9F, 0x02, 0x7C, 0x23, 0xF1, 0x0D, 0xC0, 0x77, 0x00, 0x1F, 0x1A, 0x7C, 0x07,
-0xF0, 0x29, 0xC8, 0x87, 0x00, 0xDF, 0x01, 0x7C, 0x07, 0xF0, 0x21, 0xC0, 0x87,
-0x00, 0xDF, 0x08, 0x7C, 0x22, 0xF0, 0x0D, 0xC0, 0x37, 0x02, 0x5F, 0x04, 0x7C,
-0x3A, 0xF1, 0x8D, 0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0x08, 0x0F, 0x00, 0xF3, 0x00, 0xCC, 0x00, 0x30, 0x03, 0xC1, 0x7C, 0x08, 0x3F,
-0x90, 0xCC, 0x43, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0x33, 0x00, 0xCC, 0x07, 0x30,
-0x03, 0xC1, 0x2F, 0x00, 0xFF, 0x00, 0xCC, 0x07, 0xF0, 0x03, 0xC0, 0x3F, 0x00,
-0xFF, 0x12, 0xFC, 0x00, 0x30, 0x0F, 0xC1, 0x7F, 0x01, 0x73, 0x01, 0xCC, 0x00,
-0xF1, 0x0D, 0xC0, 0x14, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
-0xE6, 0x09, 0xD0, 0x01, 0x44, 0x04, 0x12, 0x30, 0x42, 0x34, 0x08, 0x9D, 0x03,
-0x4C, 0x03, 0xD0, 0x0D, 0x60, 0x34, 0x00, 0x11, 0x25, 0x04, 0x07, 0x12, 0x39,
-0x40, 0xC7, 0x00, 0xDD, 0x80, 0x6C, 0x03, 0xD0, 0x11, 0x40, 0x87, 0x00, 0xDD,
-0x01, 0x70, 0x0C, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x51, 0x08, 0x7D, 0x4C, 0xD2,
-0x0D, 0x4C, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x66,
-0x00, 0xD1, 0x01, 0x44, 0x06, 0x98, 0x19, 0x40, 0x36, 0x01, 0x9D, 0x11, 0x64,
-0x03, 0xD0, 0x0D, 0x40, 0x74, 0x00, 0x90, 0x01, 0x44, 0x23, 0x10, 0x19, 0x41,
-0x67, 0x04, 0xDD, 0x04, 0x54, 0xA3, 0xD1, 0x19, 0x40, 0x37, 0x04, 0xDD, 0x00,
-0x74, 0x06, 0x18, 0x0D, 0x40, 0x17, 0x00, 0xD1, 0x00, 0x44, 0x04, 0xD0, 0x0D,
-0x58, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x24, 0x00,
-0x91, 0x01, 0x04, 0x02, 0x94, 0x01, 0x50, 0x32, 0x00, 0x8D, 0x00, 0x04, 0x03,
-0xD0, 0x0D, 0x40, 0x34, 0x00, 0x01, 0x00, 0x45, 0x03, 0x10, 0x08, 0x40, 0x23,
-0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x08, 0x48, 0x33, 0x00, 0xCD, 0x00, 0x34,
-0x02, 0x10, 0x0C, 0x40, 0x37, 0x00, 0x51, 0x00, 0x24, 0x02, 0x90, 0x0C, 0x40,
-0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xD3,
-0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC4, 0x36, 0x00, 0x1F, 0x00, 0x6D, 0x03, 0xF0,
-0x0D, 0x40, 0x34, 0x00, 0x93, 0x00, 0x4C, 0x03, 0x30, 0x01, 0xC4, 0x27, 0x00,
-0xDF, 0x00, 0x5C, 0x03, 0xF1, 0x01, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02,
-0x34, 0x0F, 0xC0, 0x37, 0x00, 0x53, 0x00, 0x4C, 0x00, 0xF0, 0x0D, 0xC0, 0x04,
-0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x98, 0x2F, 0x00, 0xAF, 0x00,
-0xF4, 0x02, 0x70, 0x0B, 0xC4, 0x3D, 0x10, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
-0x80, 0x3B, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xEF,
-0x00, 0xB8, 0x03, 0xF0, 0x0B, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0,
-0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC, 0x02, 0xF8, 0x0F, 0xC0, 0x17, 0x24,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x0B, 0x80, 0x33, 0x00, 0xFC,
-0x10, 0x30, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x27, 0x30, 0x03, 0xC8,
-0x2C, 0x05, 0xB5, 0x00, 0xCC, 0x02, 0x30, 0x83, 0xC0, 0x2F, 0x03, 0x33, 0x01,
-0xCC, 0x01, 0xF0, 0x1B, 0xC0, 0x2F, 0x01, 0x3F, 0x01, 0xCC, 0x26, 0xB0, 0x0B,
-0xC0, 0x7C, 0x00, 0xBF, 0x14, 0xFC, 0x27, 0x30, 0x4F, 0xC1, 0x0C, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x10, 0x11, 0x0A, 0x74, 0x28,
-0x12, 0x4F, 0x40, 0x7C, 0x10, 0xD5, 0x01, 0x04, 0x02, 0x10, 0x01, 0x50, 0xE4,
-0x08, 0x91, 0x08, 0x54, 0x02, 0x10, 0x0B, 0x40, 0xAF, 0x00, 0x91, 0x00, 0x44,
-0x2C, 0xD0, 0x19, 0x40, 0xE7, 0x00, 0x1D, 0x01, 0x44, 0x02, 0x14, 0x08, 0x40,
-0x74, 0x00, 0x9D, 0x03, 0x74, 0x03, 0x10, 0x3D, 0x40, 0x04, 0x60, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x23, 0x00, 0x01, 0x20, 0x34, 0x00, 0x50,
-0x0C, 0x51, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x02, 0x10, 0x00, 0x40, 0x20, 0x00,
-0x85, 0x00, 0x04, 0x02, 0x14, 0x48, 0x40, 0xB7, 0x20, 0x91, 0x14, 0x16, 0x81,
-0x90, 0x0C, 0x42, 0xB3, 0x00, 0x1D, 0x00, 0x64, 0x02, 0x10, 0x08, 0x40, 0x30,
-0x00, 0x09, 0x01, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x00, 0x11, 0x01, 0x74, 0x44, 0x10, 0x8D,
-0x40, 0x34, 0x00, 0xD5, 0x00, 0x44, 0x02, 0x10, 0x01, 0x40, 0x24, 0x01, 0xD1,
-0x20, 0x54, 0x46, 0x10, 0x19, 0x40, 0x27, 0x00, 0x91, 0x01, 0x54, 0x40, 0xD0,
-0x15, 0x40, 0x77, 0x00, 0x1D, 0x11, 0x64, 0x12, 0x10, 0x09, 0x41, 0x74, 0x00,
-0xDD, 0x44, 0x74, 0x23, 0x10, 0x0D, 0x40, 0x1C, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x47, 0x42, 0x11, 0x81, 0x7C, 0x0C, 0x34, 0x1D, 0xC0,
-0x34, 0x00, 0xD3, 0x00, 0x49, 0x03, 0x30, 0x15, 0xD0, 0x24, 0x00, 0x97, 0x80,
-0x4C, 0x06, 0x30, 0x39, 0xC0, 0x63, 0x40, 0x83, 0x01, 0x5D, 0x01, 0xF0, 0x19,
-0xC0, 0x77, 0x00, 0x0F, 0x01, 0x2D, 0x07, 0xB0, 0x29, 0xD0, 0x34, 0x00, 0x9F,
-0x01, 0x7E, 0x06, 0x30, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x07, 0x88, 0x6D, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0xE2, 0x1E, 0xE1, 0x3F,
-0x00, 0xFF, 0x00, 0xF8, 0x03, 0xF0, 0x4E, 0xE0, 0x6B, 0x00, 0x8F, 0x20, 0x7C,
-0x02, 0xF0, 0x0F, 0xC0, 0x67, 0x22, 0xBF, 0x10, 0xEC, 0x25, 0xF0, 0x0B, 0xC0,
-0x3F, 0x08, 0x3F, 0x00, 0xDC, 0x03, 0xF0, 0x47, 0xC0, 0x3F, 0x00, 0xBF, 0x81,
-0xFE, 0x06, 0xF4, 0x0C, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x08, 0x21, 0x00, 0x13, 0x80, 0x6C, 0x18, 0x32, 0x0D, 0xC0, 0x73, 0x00,
-0xD3, 0x00, 0x7C, 0x03, 0x30, 0x05, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x4C, 0x3A,
-0x34, 0x2D, 0xC0, 0x3C, 0x00, 0x93, 0x00, 0x7C, 0x01, 0x30, 0x0D, 0xC0, 0x77,
-0x00, 0x1F, 0x02, 0x7C, 0x23, 0x30, 0x24, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x4C,
-0x02, 0xF0, 0x0D, 0xE0, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
-0xA0, 0x6C, 0x01, 0x91, 0x01, 0x44, 0x0C, 0x10, 0x1D, 0xE4, 0x3F, 0x00, 0xE1,
-0x00, 0x74, 0x07, 0x10, 0x0D, 0x48, 0x24, 0x00, 0xD1, 0x00, 0x6C, 0x0A, 0x12,
-0x0D, 0x48, 0x24, 0x30, 0x9B, 0x00, 0x70, 0x15, 0x11, 0x05, 0x40, 0x34, 0x00,
-0x1D, 0x00, 0x74, 0x07, 0x10, 0xA5, 0x40, 0x34, 0x00, 0xDD, 0x84, 0x44, 0x02,
-0xD0, 0x0F, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20,
-0x40, 0x00, 0x01, 0x00, 0x24, 0x84, 0x10, 0x08, 0x40, 0x33, 0x40, 0xC1, 0x80,
-0x74, 0x07, 0x90, 0x20, 0x41, 0x20, 0x40, 0x81, 0x00, 0x44, 0x03, 0x91, 0x08,
-0x40, 0x21, 0x20, 0x81, 0x02, 0x30, 0x41, 0x16, 0x0C, 0x52, 0x33, 0x00, 0x4D,
-0x00, 0x34, 0x06, 0x10, 0x08, 0x40, 0x30, 0x00, 0x8D, 0x01, 0x44, 0x02, 0xD0,
-0x0C, 0x40, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x6C,
-0x00, 0x01, 0x11, 0x84, 0x64, 0x10, 0x1E, 0x40, 0x79, 0x40, 0xE1, 0x61, 0xB4,
-0x4E, 0x90, 0x12, 0x50, 0x78, 0x00, 0xA1, 0x11, 0xA4, 0x26, 0x90, 0x0A, 0x40,
-0x69, 0x00, 0xE9, 0x01, 0xB4, 0x06, 0x10, 0x1F, 0x40, 0x5A, 0x00, 0x6D, 0x01,
-0xB4, 0x06, 0x10, 0x1A, 0x40, 0x78, 0x20, 0x8D, 0x01, 0x84, 0x06, 0xD0, 0x1E,
-0x40, 0x19, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0x20, 0x00,
-0x03, 0x20, 0x6E, 0x20, 0x34, 0x08, 0x41, 0x33, 0x00, 0xC3, 0x00, 0x3C, 0x02,
-0x90, 0x01, 0xC1, 0x20, 0x00, 0x83, 0x00, 0x0C, 0x23, 0xB4, 0x89, 0xC0, 0x31,
-0x09, 0x83, 0x00, 0x3C, 0x00, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0x0F, 0x00, 0x7C,
-0x02, 0x34, 0x08, 0xC0, 0x30, 0x00, 0xCF, 0x08, 0x0D, 0x02, 0xF2, 0x0C, 0xD0,
-0x48, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x2D, 0x40, 0x3F,
-0x00, 0xF6, 0x20, 0xF5, 0x0F, 0xC0, 0x3B, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0x50,
-0x03, 0xC0, 0x3B, 0x02, 0xFF, 0x08, 0xFC, 0xA1, 0x70, 0xCB, 0xE0, 0xBE, 0x00,
-0xBF, 0x00, 0xBC, 0x02, 0xF0, 0x06, 0xC0, 0x3D, 0x00, 0x3F, 0x00, 0xFC, 0x02,
-0xF0, 0x8B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x0A,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x07, 0x00, 0x13, 0x00,
-0xCC, 0x00, 0x30, 0x59, 0xC8, 0x30, 0x13, 0xF7, 0x00, 0x74, 0x03, 0x70, 0x01,
-0xC0, 0x24, 0x00, 0x9E, 0x00, 0x4C, 0x03, 0x30, 0x2D, 0xC1, 0xAC, 0x00, 0x93,
-0x00, 0x7C, 0x01, 0xC0, 0x1D, 0xC0, 0x34, 0x00, 0x5B, 0x00, 0x7C, 0x02, 0x30,
-0x05, 0xD0, 0x30, 0x00, 0x93, 0x00, 0x7C, 0x07, 0x30, 0x0D, 0xC0, 0x53, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xA9, 0x00, 0x21, 0xC0, 0x84,
-0x02, 0x11, 0x0E, 0xC1, 0x38, 0x04, 0xE1, 0x01, 0xB4, 0x03, 0xD0, 0x0F, 0x40,
-0x38, 0x00, 0xAD, 0x00, 0xBC, 0x03, 0x10, 0x0E, 0x42, 0x20, 0x00, 0xE1, 0xC0,
-0xB4, 0x03, 0xC0, 0x0E, 0xC0, 0x38, 0x00, 0x6D, 0x00, 0xB4, 0x02, 0x50, 0x0C,
-0x40, 0x38, 0x00, 0xA5, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x4B, 0x60, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x01, 0x21, 0x01, 0x84, 0x07,
-0x10, 0x18, 0x00, 0x78, 0x01, 0xE5, 0x01, 0xB4, 0x47, 0xD1, 0x12, 0x50, 0x6A,
-0x00, 0x8D, 0x01, 0x04, 0x07, 0x10, 0x1C, 0x48, 0x78, 0x00, 0xA0, 0x01, 0xB4,
-0x05, 0xD0, 0x1F, 0x50, 0x78, 0x00, 0x2D, 0x01, 0xB4, 0x06, 0x18, 0x1E, 0x40,
-0x68, 0x00, 0xE9, 0x01, 0xF4, 0x07, 0x10, 0x1E, 0x40, 0x03, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xD1, 0x53, 0x04, 0x03, 0x10,
-0x0C, 0x50, 0x32, 0x00, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0D, 0x40, 0x32, 0x00,
-0xCD, 0x40, 0x34, 0x2B, 0x10, 0x5C, 0x60, 0x30, 0x00, 0x81, 0x00, 0x34, 0x03,
-0xD0, 0x04, 0x40, 0xF2, 0x00, 0x8D, 0x00, 0x34, 0x26, 0x50, 0x7C, 0x42, 0x30,
-0x00, 0xCD, 0x00, 0x34, 0x07, 0x14, 0x0C, 0x40, 0x5B, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x17, 0xA0, 0x1D, 0x00, 0x73, 0x27, 0xCC, 0x0D, 0x34, 0x05,
-0xC8, 0x10, 0x00, 0x57, 0x20, 0x7C, 0x05, 0xF0, 0x27, 0xC1, 0x16, 0x00, 0x5F,
-0x00, 0xCC, 0x05, 0x34, 0x57, 0xD0, 0x14, 0x40, 0x73, 0x00, 0xFC, 0x01, 0xF0,
-0x07, 0xC0, 0x1C, 0x01, 0x6B, 0x00, 0x7C, 0x01, 0x30, 0x77, 0xD0, 0x14, 0x00,
-0x6B, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x08, 0x05, 0x40, 0x1F, 0x00, 0x7D, 0x20, 0xF0, 0x01, 0xC0,
-0x05, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF2, 0x01, 0xC5, 0x05, 0x00, 0x1F, 0x00,
-0x7C, 0x40, 0xF0, 0x00, 0xC0, 0x03, 0x40, 0x1F, 0x04, 0x7C, 0x20, 0xF0, 0x01,
-0xC0, 0x05, 0x30, 0x1F, 0x01, 0x7C, 0x00, 0xF4, 0x21, 0xC4, 0x07, 0x00, 0x17,
-0x01, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x08, 0x25, 0x00, 0x97, 0x00, 0x4C, 0x4A, 0x30, 0x59, 0xC0, 0xE7,
-0x00, 0x8B, 0x01, 0x6C, 0x02, 0xF0, 0x19, 0x80, 0x24, 0x10, 0x8F, 0x89, 0x4C,
-0x02, 0x38, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
-0x23, 0x04, 0x93, 0x01, 0x6D, 0x02, 0x30, 0x59, 0x40, 0xA4, 0x00, 0x93, 0x00,
-0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x20, 0x24, 0x00, 0x91, 0x00, 0x44, 0x0A, 0x10, 0x19, 0x40, 0x27, 0x00,
-0x91, 0x03, 0x44, 0x02, 0xD0, 0x19, 0x40, 0x24, 0x00, 0x9D, 0x01, 0x6C, 0x02,
-0x10, 0x09, 0x40, 0x24, 0x00, 0x91, 0x03, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x27,
-0x20, 0x9B, 0x00, 0x2C, 0x12, 0x50, 0x79, 0x50, 0x60, 0x00, 0x9B, 0x00, 0x44,
-0x02, 0xD2, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA0, 0x20, 0x40, 0x95, 0x20, 0x04, 0x0A, 0x56, 0x29, 0x40, 0x27, 0x40, 0x99,
-0xA8, 0x64, 0x06, 0xD8, 0x89, 0x60, 0x25, 0xA0, 0x9D, 0x00, 0x04, 0x02, 0x14,
-0x0D, 0x40, 0x26, 0x00, 0xD1, 0x00, 0x74, 0x06, 0xD8, 0x09, 0x40, 0x77, 0x00,
-0x91, 0x08, 0x66, 0x92, 0x12, 0x08, 0x42, 0x25, 0xA0, 0x99, 0x00, 0x44, 0x02,
-0xD0, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
-0x20, 0x01, 0x81, 0x04, 0x04, 0x12, 0x50, 0x48, 0x40, 0x23, 0x01, 0x81, 0x04,
-0x00, 0x06, 0xD0, 0x48, 0x50, 0x21, 0x01, 0x8D, 0x04, 0x25, 0x13, 0x10, 0x48,
-0x40, 0x22, 0x11, 0xC1, 0x00, 0x36, 0x12, 0xD0, 0x08, 0x42, 0x23, 0x21, 0x99,
-0x00, 0x64, 0x02, 0x50, 0x48, 0x40, 0x25, 0x00, 0x89, 0x04, 0x05, 0x02, 0xD0,
-0x48, 0x41, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x83,
-0x02, 0x07, 0x0A, 0x0C, 0x28, 0x72, 0xA1, 0x40, 0x07, 0x00, 0x5B, 0x00, 0x6C,
-0x28, 0xF0, 0xA1, 0xC0, 0x05, 0x00, 0x1F, 0x0A, 0x4C, 0x28, 0x10, 0xA1, 0x50,
-0x86, 0x02, 0x13, 0x0A, 0x7C, 0x01, 0xD1, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00,
-0x6D, 0x28, 0x30, 0xA1, 0xC0, 0x05, 0x00, 0x1B, 0x00, 0x4C, 0x08, 0xF0, 0x01,
-0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x3F, 0x02,
-0xBF, 0x08, 0xFD, 0x22, 0xB0, 0x8B, 0xC0, 0x27, 0x42, 0x9F, 0x08, 0xFC, 0x02,
-0xF0, 0x8B, 0xC8, 0x2E, 0x12, 0xBF, 0x48, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x2D,
-0x42, 0xBF, 0x00, 0xFC, 0x22, 0xF0, 0x0A, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xBD,
-0x02, 0xF0, 0x8B, 0xC0, 0x2E, 0x00, 0xBF, 0x08, 0xBC, 0x42, 0xF0, 0x09, 0xC0,
-0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x3F, 0x05, 0xB3,
-0x0C, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xA3, 0x04, 0x8C, 0x02, 0xF0,
-0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x22, 0xF0, 0x4B, 0xC0, 0x24, 0x05,
-0xAF, 0x08, 0xFC, 0x16, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x02,
-0xF0, 0xCA, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x7C, 0x22, 0xF0, 0x19, 0xC0, 0x67,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x51, 0x0C,
-0x4C, 0x48, 0x14, 0x01, 0xC1, 0x04, 0x02, 0x11, 0x60, 0x44, 0x10, 0x70, 0xC0,
-0x40, 0x05, 0x00, 0x11, 0x10, 0x44, 0x20, 0xD0, 0x05, 0x40, 0x04, 0x01, 0x1D,
-0x04, 0x74, 0x08, 0xC0, 0x01, 0x40, 0x07, 0x02, 0x1D, 0x00, 0x74, 0x10, 0xD2,
-0xC1, 0x40, 0x04, 0x00, 0x55, 0x00, 0x74, 0x04, 0xD0, 0x01, 0x40, 0x73, 0x60,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81, 0x04, 0x24,
-0x32, 0x10, 0x88, 0x40, 0x21, 0x00, 0x81, 0x08, 0x04, 0x52, 0xD2, 0x48, 0x40,
-0x20, 0x00, 0x81, 0x00, 0x04, 0x06, 0xD0, 0x88, 0x44, 0x20, 0x05, 0x8D, 0x04,
-0x34, 0x22, 0xD8, 0x18, 0x40, 0x63, 0x00, 0x8D, 0x20, 0x34, 0x52, 0xD0, 0x48,
-0x40, 0x20, 0x00, 0x81, 0x08, 0x34, 0x12, 0xD0, 0x28, 0x40, 0x4B, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x65, 0x58, 0x81, 0x00, 0x44, 0x02,
-0x10, 0x09, 0x40, 0x26, 0x00, 0x91, 0x00, 0x45, 0x12, 0x50, 0x08, 0x50, 0x25,
-0x00, 0x91, 0x04, 0x45, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x20, 0x9D, 0x24, 0x74,
-0x83, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x06, 0x74, 0x02, 0xD0, 0x49, 0x41,
-0x24, 0x00, 0x95, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x93, 0x82, 0x6D, 0x1A, 0x32,
-0x09, 0xC0, 0x25, 0x40, 0x93, 0x00, 0x4C, 0x06, 0xF2, 0x09, 0xC0, 0x24, 0x00,
-0x93, 0x00, 0x4C, 0x06, 0xF0, 0xB9, 0xC0, 0x24, 0x00, 0x9F, 0x06, 0x7C, 0x02,
-0xF0, 0x09, 0xC0, 0xE7, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x24,
-0x02, 0x93, 0x09, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x03, 0x7C, 0x26, 0xF0, 0x09,
-0xC1, 0x21, 0x00, 0x8F, 0x00, 0x7C, 0x46, 0x70, 0x09, 0x40, 0x26, 0x40, 0x9F,
-0x01, 0x7C, 0x0A, 0xF0, 0x18, 0xD0, 0x67, 0x01, 0x9F, 0x00, 0x7C, 0x12, 0xF0,
-0x39, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x19, 0xD0, 0x27, 0x80,
-0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x08, 0x85, 0x00, 0x13, 0x02, 0x4C, 0x00, 0xB0, 0x01, 0xC0,
-0x04, 0x40, 0x13, 0x04, 0x4C, 0x20, 0x30, 0x01, 0xC0, 0x04, 0x80, 0x1F, 0x00,
-0x4C, 0x00, 0x34, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x82, 0x4C, 0x84, 0xB0, 0x01,
-0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F,
-0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x00, 0x14, 0x48, 0x51, 0x00, 0xD4, 0x01, 0x34, 0x07, 0x40, 0x14,
-0x00, 0x71, 0x00, 0xC4, 0x01, 0x10, 0x07, 0x50, 0x10, 0x00, 0x5D, 0x10, 0xFC,
-0x11, 0x12, 0x05, 0x40, 0x14, 0x00, 0x71, 0x02, 0xC0, 0x05, 0x30, 0x05, 0x40,
-0x57, 0x04, 0x5D, 0x01, 0xF4, 0x41, 0xD0, 0x07, 0x40, 0x10, 0x00, 0x5D, 0x01,
-0x74, 0x01, 0x10, 0x05, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xA0, 0x36, 0x00, 0xC1, 0x00, 0x44, 0x03, 0x10, 0x2D, 0x40, 0x30, 0x00,
-0x81, 0x00, 0x04, 0x0F, 0xD4, 0x1C, 0x40, 0x30, 0x00, 0xDD, 0x00, 0x04, 0x07,
-0x10, 0x1C, 0x40, 0x30, 0x20, 0xC1, 0x12, 0x00, 0x03, 0x0C, 0x0C, 0x40, 0x23,
-0x00, 0xCD, 0x01, 0x34, 0x01, 0x90, 0x09, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x34,
-0x03, 0x10, 0x0C, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x80, 0x30, 0x08, 0xC1, 0x00, 0x94, 0x03, 0x10, 0x02, 0x40, 0x38, 0x00, 0xA1,
-0x02, 0xC4, 0x07, 0xD0, 0x0E, 0x41, 0x38, 0x04, 0xCD, 0x00, 0xB4, 0x05, 0x10,
-0x2C, 0x40, 0x7A, 0x00, 0xF1, 0x01, 0x84, 0x0F, 0x10, 0x0E, 0x40, 0x3B, 0x00,
-0xED, 0x10, 0xB4, 0x01, 0xD0, 0x03, 0x40, 0x28, 0x00, 0xAD, 0x02, 0xB4, 0x07,
-0x10, 0x0E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18,
-0x78, 0x40, 0xE3, 0x01, 0xCC, 0x04, 0x33, 0x12, 0x50, 0x60, 0x20, 0x23, 0x01,
-0x8D, 0x07, 0xF0, 0x1A, 0xC2, 0x78, 0x00, 0xED, 0x01, 0xC8, 0x85, 0x30, 0x1E,
-0xD0, 0x7C, 0x41, 0xE3, 0x01, 0x8D, 0x06, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xEF,
-0x01, 0xBC, 0x07, 0xF0, 0x1E, 0xD0, 0x78, 0x00, 0xAD, 0x01, 0xFC, 0x07, 0x34,
-0x1E, 0xC0, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0xB5,
-0x05, 0xDF, 0x02, 0x7C, 0x02, 0x70, 0x00, 0xC0, 0x37, 0x00, 0x1C, 0x00, 0x7C,
-0x03, 0x30, 0x29, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x81, 0xF0, 0x0D, 0xC0,
-0x35, 0x02, 0xDF, 0x00, 0x3D, 0x00, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00,
-0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
-0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00,
-0xF3, 0x03, 0xCC, 0x13, 0x30, 0x17, 0xC0, 0x7C, 0x10, 0xF3, 0x01, 0xFC, 0x07,
-0xF0, 0x3F, 0xC0, 0x78, 0x00, 0xF3, 0x01, 0xCC, 0x06, 0x30, 0x1A, 0xC0, 0x7D,
-0x00, 0xFF, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x01, 0xFC,
-0x27, 0xF0, 0x1B, 0xD0, 0x6C, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0,
-0x0B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x40, 0xF1,
-0x00, 0x86, 0x03, 0x10, 0x02, 0x40, 0x38, 0x02, 0xE1, 0x04, 0xB4, 0x00, 0xD0,
-0x8E, 0x40, 0x38, 0x00, 0xB1, 0x00, 0x84, 0x01, 0x10, 0x8A, 0x43, 0x38, 0x08,
-0xED, 0x02, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x23,
-0xD0, 0x82, 0x40, 0x28, 0x00, 0xED, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x57,
-0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x02, 0xE1, 0x00,
-0x84, 0x20, 0x10, 0x00, 0x41, 0x20, 0x00, 0xA9, 0x40, 0xB4, 0x03, 0xD0, 0x08,
-0x40, 0x38, 0x06, 0xA1, 0x00, 0x84, 0x60, 0x10, 0x0B, 0x40, 0x38, 0x04, 0xED,
-0x00, 0x04, 0x00, 0x50, 0x2E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x23, 0xD8,
-0x0E, 0x40, 0x3A, 0x00, 0xA9, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x23, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0xC1, 0x0A, 0x44,
-0x42, 0x10, 0x00, 0x48, 0x30, 0x00, 0x89, 0x00, 0x34, 0x07, 0xD0, 0xB9, 0x40,
-0x70, 0x48, 0x91, 0x01, 0x04, 0x01, 0x10, 0x28, 0x40, 0x30, 0x00, 0xDD, 0x10,
-0x04, 0x24, 0x10, 0x0C, 0x40, 0x33, 0x90, 0xCD, 0x02, 0x34, 0x02, 0xD0, 0x2D,
-0x40, 0x32, 0x00, 0xCD, 0x03, 0x34, 0x83, 0xD2, 0x0C, 0x40, 0x5B, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x25, 0x00, 0xD3, 0x03, 0x4D, 0x0B,
-0x30, 0x10, 0xC0, 0x34, 0x50, 0x9B, 0x00, 0x7C, 0x47, 0xF0, 0x2D, 0xD0, 0x60,
-0x00, 0xD3, 0x05, 0x4D, 0x0E, 0x34, 0x19, 0xD0, 0x7C, 0x00, 0xDF, 0x01, 0x4D,
-0x22, 0x70, 0x0D, 0xC0, 0xB7, 0x02, 0xCF, 0x0A, 0x7C, 0x01, 0xF0, 0xF5, 0xD0,
-0x66, 0x00, 0x9F, 0x09, 0xFC, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x77, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
-0x21, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x27, 0x00,
-0xDF, 0x00, 0x7C, 0x40, 0xF1, 0x08, 0xC1, 0x37, 0x00, 0xDF, 0x01, 0x7C, 0x02,
-0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x25,
-0x02, 0x9F, 0x08, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x40, 0xF3, 0x10, 0xDC, 0x04, 0x30, 0x03,
-0xC0, 0xF8, 0x00, 0x33, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC1, 0xAC, 0x40, 0xF3,
-0x00, 0x4C, 0x04, 0xF0, 0x0B, 0xE0, 0x3C, 0x00, 0xBF, 0x00, 0xCC, 0x00, 0xD0,
-0x0F, 0xC0, 0x7F, 0x01, 0xB7, 0x01, 0xCC, 0x03, 0xF0, 0x3F, 0xC0, 0xEC, 0x00,
-0xBF, 0x03, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10, 0x71, 0x40,
-0x74, 0x00, 0x11, 0x40, 0x74, 0x03, 0xD0, 0x31, 0x41, 0x24, 0x50, 0xD1, 0x08,
-0x44, 0x00, 0xD0, 0x99, 0x40, 0x34, 0x00, 0x9C, 0x03, 0x44, 0x0C, 0xD0, 0x0D,
-0x48, 0x37, 0x00, 0x9D, 0x09, 0x44, 0x07, 0xD0, 0x1D, 0x40, 0x24, 0x00, 0x8D,
-0x00, 0x45, 0x03, 0xD0, 0x0D, 0x40, 0x17, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0xA0, 0x66, 0x00, 0xD1, 0x08, 0x74, 0x23, 0x90, 0x11, 0x40, 0x34,
-0x80, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x1D, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44,
-0x12, 0xD0, 0x09, 0x40, 0x36, 0x00, 0x5D, 0x01, 0x44, 0x06, 0xD1, 0x0D, 0x40,
-0x37, 0x00, 0xDD, 0x00, 0x74, 0x07, 0xD0, 0x05, 0x41, 0x24, 0x00, 0xDD, 0x00,
-0x44, 0x03, 0xD0, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x00, 0x30, 0x00, 0x81, 0x00, 0x34, 0x02, 0x90, 0x00, 0x42, 0x30, 0xC0,
-0xC1, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x50, 0x30, 0x00, 0x81, 0x00, 0x04, 0x00,
-0xD0, 0x08, 0x48, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD8, 0x0C, 0x42, 0x33,
-0x00, 0xCD, 0x80, 0x35, 0x03, 0xD0, 0x0C, 0x70, 0x20, 0x00, 0xDD, 0x00, 0x04,
-0x03, 0xD0, 0x0C, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x2E, 0x00, 0xF3, 0x00, 0x1C, 0x00, 0xB0, 0x01, 0xD0, 0x34, 0x00, 0x93,
-0x00, 0x7C, 0x03, 0xF2, 0x0B, 0xC0, 0x34, 0x00, 0x93, 0x80, 0x4C, 0x80, 0xF0,
-0x09, 0xD0, 0x34, 0x00, 0x9F, 0x00, 0x4D, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x20,
-0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xD0, 0x24, 0x00, 0xDF, 0x00, 0x4C, 0x03,
-0xF0, 0x0D, 0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8,
-0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00,
-0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x40, 0xFC, 0x00, 0xF0, 0x0B,
-0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x20, 0xFF,
-0x00, 0xCC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
-0x0F, 0xC8, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x2F,
-0x00, 0xBF, 0x0C, 0xCC, 0x12, 0xF0, 0x1F, 0xC0, 0xBE, 0x09, 0xBF, 0xC0, 0x9D,
-0x40, 0xB0, 0x8F, 0xC0, 0x2F, 0x01, 0xB3, 0x10, 0xDC, 0xE2, 0x30, 0x1F, 0xC0,
-0x3F, 0x01, 0xF3, 0x02, 0xCC, 0x02, 0x33, 0x16, 0xC4, 0x3C, 0x00, 0xEF, 0x01,
-0xCC, 0x33, 0x30, 0x1F, 0xC0, 0x5A, 0x00, 0xFB, 0x01, 0xAC, 0x27, 0xB0, 0x0B,
-0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x07, 0x00,
-0x1D, 0x0E, 0x44, 0x12, 0xD0, 0x4D, 0x40, 0x3C, 0x03, 0x1D, 0x03, 0x44, 0x0F,
-0x10, 0x2F, 0x40, 0x27, 0x05, 0xD1, 0x06, 0x44, 0x12, 0x10, 0x1D, 0x48, 0xBF,
-0x00, 0xF1, 0x06, 0x44, 0x2C, 0x10, 0x05, 0x41, 0xBC, 0x02, 0xDD, 0x01, 0xD4,
-0x0B, 0x10, 0x1D, 0x40, 0x74, 0x00, 0xD1, 0x01, 0x44, 0x03, 0x10, 0x01, 0x40,
-0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0xA3, 0x05, 0x8D,
-0x01, 0x06, 0x62, 0xD0, 0x09, 0x41, 0x30, 0x20, 0x8D, 0x08, 0x15, 0x03, 0x92,
-0xCC, 0x40, 0x43, 0x03, 0xC5, 0x10, 0x34, 0x10, 0x12, 0x0C, 0x42, 0xB2, 0x25,
-0xC1, 0x8C, 0x04, 0x04, 0x50, 0x01, 0x50, 0x30, 0x0C, 0x5D, 0x00, 0x24, 0x33,
-0x10, 0x0C, 0x40, 0x06, 0x00, 0xD9, 0xA0, 0x64, 0x12, 0x90, 0x08, 0x40, 0x4F,
-0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x65, 0x00, 0x1D, 0x01,
-0x44, 0x06, 0xD0, 0x19, 0x50, 0x34, 0x00, 0x9D, 0x03, 0x55, 0x0F, 0x10, 0x0D,
-0x42, 0x67, 0x00, 0xD5, 0x00, 0x64, 0x0C, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xD1,
-0x00, 0x44, 0x04, 0x40, 0x05, 0x40, 0x34, 0x00, 0xDD, 0x80, 0x74, 0x03, 0x10,
-0x0D, 0x40, 0x74, 0x00, 0x59, 0x01, 0x44, 0x03, 0x18, 0x11, 0x41, 0x0F, 0xA0,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x04, 0x1F, 0x01, 0x4C,
-0x14, 0xF0, 0x5C, 0xC0, 0x34, 0x00, 0x9F, 0x01, 0x5D, 0x0F, 0xB0, 0x0D, 0xC0,
-0x47, 0x00, 0xD7, 0x00, 0x7C, 0x06, 0x30, 0x0D, 0xE0, 0x37, 0x00, 0xD1, 0x20,
-0x4C, 0x06, 0x60, 0x04, 0xC0, 0x34, 0x00, 0x9F, 0x01, 0x6E, 0x03, 0x30, 0x0C,
-0xC0, 0x76, 0x00, 0xDB, 0x05, 0x2C, 0x03, 0xB0, 0x19, 0x44, 0x23, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x05, 0x00, 0x1F, 0x10, 0xFC, 0x02,
-0xF0, 0x0F, 0xC0, 0x3F, 0x04, 0x3F, 0x40, 0xAC, 0x03, 0xF2, 0x0F, 0xC0, 0x07,
-0x0C, 0xEB, 0x05, 0x1C, 0x02, 0xF0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0x3C,
-0x00, 0xB2, 0x0F, 0xC0, 0x3F, 0x00, 0xBF, 0x89, 0x9C, 0x03, 0xF0, 0x5F, 0xC8,
-0x3F, 0x40, 0xF7, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x1F, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xA5, 0x80, 0x93, 0x00, 0x4C, 0x00, 0xF0,
-0x09, 0xC0, 0x37, 0x00, 0x93, 0x80, 0x6C, 0x0B, 0x3C, 0x0D, 0xC0, 0x04, 0x00,
-0xD3, 0x00, 0x7C, 0x02, 0x30, 0x0D, 0xC0, 0x32, 0x00, 0xDB, 0x00, 0x4C, 0x02,
-0x31, 0x0D, 0xE0, 0x34, 0x10, 0x93, 0x02, 0x4C, 0x03, 0x34, 0x4D, 0xC0, 0x74,
-0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x10, 0x9B, 0x06, 0x44, 0x02, 0xD0, 0x09,
-0x40, 0x3F, 0x00, 0x81, 0x0B, 0x68, 0x07, 0xB0, 0x1F, 0xC0, 0xE4, 0x00, 0xD0,
-0x00, 0x74, 0x02, 0x10, 0x0D, 0x48, 0x3F, 0x00, 0xFB, 0x10, 0x44, 0x02, 0x00,
-0x0D, 0xC0, 0x3F, 0x00, 0x81, 0x81, 0xC4, 0x2B, 0x10, 0x2D, 0x40, 0x70, 0x00,
-0x05, 0x05, 0x6C, 0x2F, 0x10, 0x49, 0xC0, 0x6E, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x07, 0xA0, 0x02, 0x00, 0x91, 0x02, 0x24, 0x00, 0xD0, 0x08, 0x64,
-0xF3, 0x00, 0x01, 0x03, 0x20, 0x07, 0x10, 0x5C, 0x48, 0xE4, 0x00, 0xC5, 0x00,
-0x34, 0x00, 0x11, 0x0C, 0x40, 0x31, 0x02, 0xD5, 0x01, 0x04, 0x02, 0x50, 0x14,
-0x40, 0x70, 0x01, 0xC1, 0x00, 0x24, 0x23, 0x90, 0x2C, 0x40, 0x10, 0x00, 0xC1,
-0x01, 0x04, 0x07, 0x50, 0x60, 0x44, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x04, 0x80, 0x58, 0x00, 0xE9, 0x01, 0xA4, 0x05, 0xD0, 0x1A, 0x60, 0x7B,
-0x04, 0x61, 0x01, 0xE4, 0x07, 0x94, 0x1E, 0x40, 0x78, 0x00, 0xE5, 0x01, 0xB4,
-0x07, 0x10, 0x1E, 0x00, 0xFB, 0x00, 0xED, 0x03, 0x84, 0x07, 0x58, 0x37, 0x41,
-0x79, 0x04, 0xF1, 0x00, 0xA0, 0x07, 0x91, 0x0E, 0x40, 0x78, 0x00, 0xF5, 0x01,
-0xE4, 0x27, 0x18, 0x12, 0x48, 0x3E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x10, 0x10, 0x00, 0xC1, 0x00, 0x24, 0x03, 0xF0, 0x08, 0xC0, 0x37, 0x00,
-0x43, 0x14, 0x2C, 0x43, 0x10, 0x8D, 0xC1, 0x10, 0x04, 0xC7, 0x00, 0x34, 0x21,
-0x30, 0x0C, 0xC0, 0x37, 0x00, 0xD7, 0x88, 0x0C, 0x01, 0x70, 0x00, 0x40, 0x34,
-0x00, 0xC3, 0x18, 0x64, 0x13, 0xB0, 0x8C, 0x40, 0x10, 0x00, 0xC3, 0x00, 0x0C,
-0x42, 0x70, 0x09, 0xC0, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x98, 0x3D, 0x20, 0xF7, 0x00, 0xDC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x40, 0xEF,
-0x00, 0xFC, 0x23, 0xF5, 0x0F, 0xC4, 0x35, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0xF0,
-0x0F, 0xC0, 0xBF, 0x02, 0xF3, 0x00, 0xFC, 0x01, 0xB0, 0x07, 0xC0, 0x3F, 0x00,
-0xFF, 0x0C, 0xDC, 0x03, 0x70, 0x4E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xFE, 0x83,
-0x70, 0x07, 0xC8, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0,
-0x37, 0x80, 0x5B, 0x00, 0x5C, 0x01, 0x34, 0x09, 0xC0, 0xB7, 0x04, 0xCF, 0x80,
-0x5C, 0x03, 0xF8, 0x4D, 0xC9, 0x37, 0x00, 0xDF, 0x01, 0x4C, 0x01, 0xF0, 0x0D,
-0xC0, 0x37, 0x03, 0xDF, 0x02, 0x7E, 0x03, 0xF0, 0x05, 0xC0, 0xB6, 0x02, 0xDF,
-0x00, 0x5C, 0x5B, 0xF0, 0x1D, 0xC0, 0x36, 0x00, 0xCF, 0x20, 0x4C, 0x03, 0x22,
-0x01, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x1D,
-0x08, 0x63, 0x00, 0xB4, 0x01, 0x10, 0x0A, 0x40, 0xBB, 0x11, 0x6D, 0x00, 0x94,
-0x03, 0x30, 0x6E, 0x48, 0x3B, 0x00, 0xED, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40,
-0x3B, 0x01, 0xED, 0x48, 0xB4, 0x03, 0xD0, 0x0F, 0x40, 0x38, 0x04, 0xAD, 0x00,
-0xB4, 0x0B, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x80, 0xD4, 0x83, 0x10, 0x06,
-0xC0, 0x4E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00,
-0xE1, 0x01, 0xB4, 0x47, 0x10, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x11, 0xD4, 0x47,
-0x50, 0x1E, 0x48, 0x5B, 0x00, 0xED, 0x01, 0xA5, 0x05, 0xD0, 0x1E, 0x40, 0x7B,
-0x00, 0xED, 0x09, 0xB4, 0x07, 0xD2, 0x1E, 0x55, 0x78, 0x00, 0xAD, 0x01, 0xB4,
-0x07, 0xD0, 0x1B, 0x40, 0x7A, 0x00, 0xF5, 0x01, 0x84, 0x06, 0x14, 0x18, 0x40,
-0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x10, 0xC1,
-0x0D, 0x34, 0x07, 0x90, 0x00, 0x40, 0x33, 0x00, 0xCD, 0x03, 0x14, 0x0B, 0x90,
-0x0C, 0x40, 0xF3, 0x04, 0xCD, 0x08, 0x04, 0x07, 0xD0, 0x0C, 0x40, 0x37, 0x20,
-0xCD, 0x00, 0x34, 0x27, 0xD0, 0x4C, 0x40, 0x30, 0x00, 0x8D, 0x04, 0x34, 0x03,
-0xD0, 0x18, 0x40, 0x70, 0x08, 0xCD, 0x01, 0x14, 0x03, 0x10, 0xAD, 0x43, 0x5A,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x1D, 0x04, 0x73, 0x02,
-0xFC, 0x01, 0x30, 0x27, 0xC0, 0x17, 0x10, 0x7F, 0x02, 0xDD, 0xA9, 0x74, 0x05,
-0xC0, 0x9F, 0x00, 0x5F, 0x00, 0xEC, 0x15, 0xF0, 0x05, 0x40, 0x17, 0x80, 0x5F,
-0x00, 0xFC, 0x09, 0xF0, 0x36, 0xC0, 0x14, 0x00, 0x7F, 0x02, 0x7C, 0x01, 0xF9,
-0x15, 0xC2, 0x1E, 0x04, 0x67, 0x81, 0x44, 0x01, 0x10, 0x27, 0xC0, 0x5C, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x47, 0x40, 0x1F, 0x00, 0x7C,
-0x40, 0x70, 0x41, 0xC0, 0x83, 0x00, 0x1F, 0x12, 0x7C, 0x00, 0x74, 0x01, 0xC0,
-0x07, 0x02, 0x1F, 0x00, 0x5C, 0x04, 0xF0, 0x01, 0xC2, 0x87, 0x00, 0x1F, 0x00,
-0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x0A, 0x7C, 0x00, 0xF0, 0x81,
-0xC0, 0x07, 0x10, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x4B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x80, 0x93, 0x05, 0x3C, 0x02,
-0x30, 0x09, 0xC0, 0x67, 0x02, 0x83, 0x00, 0x4C, 0x02, 0xB0, 0x28, 0xC0, 0x64,
-0x01, 0x9E, 0x00, 0x78, 0x02, 0x30, 0x09, 0xC0, 0xA7, 0x40, 0x9B, 0x01, 0x7C,
-0x42, 0xF0, 0x59, 0xC0, 0x20, 0x01, 0x93, 0x42, 0x7C, 0x82, 0xF0, 0x39, 0xC0,
-0x27, 0x04, 0x97, 0x08, 0x6C, 0x16, 0x30, 0x89, 0xC0, 0x40, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10,
-0x09, 0xC0, 0xA7, 0x04, 0x91, 0x86, 0x0C, 0x02, 0xB0, 0x09, 0x40, 0x64, 0x00,
-0x9D, 0x00, 0x7C, 0x02, 0x10, 0x09, 0x40, 0xE7, 0x00, 0x91, 0x01, 0x74, 0x02,
-0xD0, 0x49, 0xC0, 0xE6, 0x04, 0x91, 0x20, 0x74, 0x0E, 0xD0, 0x29, 0x40, 0x23,
-0x40, 0x9B, 0x41, 0x44, 0x46, 0x14, 0x39, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0xA0, 0x20, 0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x09,
-0x60, 0x27, 0x00, 0x91, 0x00, 0x65, 0x22, 0x94, 0x09, 0x58, 0x26, 0x00, 0x9D,
-0x00, 0x36, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x74, 0x02, 0xD0,
-0x09, 0x60, 0x24, 0x00, 0xD1, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x40, 0x67, 0x00,
-0x95, 0x00, 0x04, 0x02, 0x12, 0x29, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0x20, 0x81, 0x81, 0x05, 0x34, 0x12, 0x10, 0x08, 0x40,
-0x21, 0x09, 0x81, 0x04, 0x44, 0x12, 0x90, 0x58, 0x40, 0x62, 0x01, 0x8D, 0x04,
-0x14, 0x12, 0x10, 0x08, 0x40, 0x23, 0x01, 0xC1, 0x04, 0x34, 0x12, 0xD0, 0x09,
-0x68, 0x22, 0x01, 0xC1, 0x00, 0x36, 0x12, 0xD0, 0x0C, 0x40, 0x23, 0x08, 0x99,
-0x00, 0x05, 0x22, 0x10, 0x48, 0x50, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1D, 0xB0, 0x86, 0x02, 0x11, 0x0A, 0x3C, 0x28, 0x30, 0xA1, 0x40, 0x87,
-0x02, 0x13, 0x40, 0x6C, 0x00, 0xB4, 0xA1, 0xC8, 0x86, 0x02, 0x0F, 0x0A, 0x74,
-0x28, 0x34, 0x01, 0x84, 0x97, 0x02, 0x1B, 0x0A, 0x7C, 0x00, 0xD0, 0xA1, 0xC0,
-0x84, 0x42, 0x13, 0x40, 0x7C, 0x29, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00,
-0x4C, 0x08, 0x30, 0xA1, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x19, 0x98, 0x2F, 0x4A, 0xBF, 0x08, 0xFC, 0x22, 0xD4, 0x0B, 0xC0, 0x27, 0x62,
-0xBF, 0x88, 0xBC, 0x22, 0xF4, 0x89, 0xC0, 0x2D, 0x02, 0xBF, 0x08, 0xFC, 0x22,
-0xF0, 0x09, 0xC4, 0x27, 0x02, 0x9F, 0x08, 0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x27,
-0x02, 0xBF, 0x40, 0x7C, 0x22, 0xD0, 0x0A, 0xC0, 0x2F, 0x80, 0xBF, 0x00, 0xDE,
-0x92, 0xF0, 0x8B, 0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA0, 0x27, 0x01, 0xB3, 0x14, 0x7C, 0x32, 0x30, 0x09, 0xD0, 0x2C, 0x40, 0xA3,
-0x00, 0x9C, 0x12, 0x30, 0x4B, 0xC1, 0x2C, 0x03, 0x9F, 0x25, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x2D, 0x01, 0xBF, 0x14, 0x4C, 0x12, 0x70, 0x0B, 0xC0, 0x2F, 0x40,
-0xB3, 0x00, 0xFC, 0x12, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xAB, 0x00, 0x8C, 0x02,
-0xF0, 0x0B, 0xC0, 0x76, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
-0x17, 0x0D, 0x11, 0x44, 0x74, 0xB0, 0x10, 0x00, 0x41, 0x04, 0x04, 0x11, 0x08,
-0x44, 0x00, 0x90, 0x41, 0x40, 0x04, 0x03, 0x1D, 0x1A, 0x74, 0x40, 0xD0, 0x01,
-0x40, 0x07, 0x05, 0x1D, 0x04, 0x44, 0x20, 0xD0, 0x01, 0x43, 0x07, 0x04, 0x11,
-0x00, 0x74, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x11, 0x40, 0x45, 0x00, 0xD2,
-0x05, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23,
-0x03, 0x81, 0x34, 0x34, 0x12, 0x10, 0x48, 0x40, 0x20, 0x02, 0x81, 0x00, 0x54,
-0x27, 0x90, 0x48, 0x41, 0x20, 0x01, 0x8D, 0x04, 0x34, 0x22, 0xD0, 0x08, 0x40,
-0x21, 0x03, 0x8D, 0xB4, 0x04, 0x82, 0x50, 0x48, 0x40, 0x23, 0x02, 0xC5, 0x00,
-0x34, 0x32, 0xD0, 0x08, 0x40, 0x27, 0x80, 0x89, 0x00, 0x24, 0x82, 0xD0, 0x0C,
-0x40, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x40,
-0x91, 0x06, 0x74, 0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x91, 0x04, 0x44, 0x02,
-0x90, 0x09, 0x50, 0x24, 0x01, 0x9D, 0x08, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27,
-0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x48, 0x37, 0x00, 0x95, 0x10, 0x74,
-0x82, 0xD0, 0x8D, 0x44, 0x67, 0x88, 0x91, 0x08, 0x64, 0x82, 0xD0, 0x19, 0x40,
-0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x25, 0x00, 0x93,
-0x82, 0x7C, 0x1E, 0x31, 0x09, 0xC0, 0x24, 0x10, 0x93, 0x06, 0x5C, 0x0A, 0x34,
-0x09, 0xC4, 0x24, 0x01, 0x9E, 0x00, 0x7C, 0x32, 0xF0, 0x09, 0xC0, 0x25, 0x00,
-0x9F, 0x00, 0x4C, 0x1E, 0x70, 0xE9, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x74, 0x02,
-0xF0, 0x09, 0xC0, 0x23, 0x00, 0x9B, 0x04, 0x6E, 0x26, 0xD2, 0x09, 0xC0, 0x16,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xE1, 0x00, 0x9F, 0x00,
-0x7C, 0x16, 0xF6, 0x99, 0xC0, 0x23, 0x28, 0x9F, 0x20, 0x7C, 0x12, 0x70, 0x09,
-0xC5, 0x27, 0x0C, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x27, 0xA0, 0x8F,
-0x00, 0x7D, 0x12, 0xF0, 0x19, 0xC3, 0x27, 0x00, 0x9B, 0x02, 0x7C, 0x42, 0xF0,
-0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5E, 0x06, 0xF2, 0x08, 0xC0, 0x59, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x02, 0x7C,
-0x00, 0x30, 0x01, 0xC0, 0x06, 0x01, 0x1F, 0x02, 0x6C, 0x00, 0xB0, 0x00, 0xC0,
-0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x04, 0x13, 0x00,
-0x7C, 0x08, 0xF0, 0x21, 0xC0, 0x06, 0x41, 0x13, 0x00, 0x4C, 0x00, 0x31, 0x01,
-0xC1, 0x07, 0x20, 0x1F, 0x02, 0x4D, 0x00, 0x70, 0x01, 0xC1, 0x50, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x7D, 0x02, 0x74, 0x01,
-0x12, 0x05, 0xC0, 0x9C, 0x04, 0x6D, 0x21, 0x04, 0x81, 0x10, 0x57, 0x40, 0x5F,
-0x01, 0x5D, 0x80, 0x74, 0x01, 0xD0, 0x05, 0x42, 0x1F, 0x20, 0x71, 0x08, 0x74,
-0x01, 0xD0, 0x57, 0xC0, 0x1C, 0x01, 0x71, 0x00, 0xC4, 0x05, 0x10, 0x27, 0xC1,
-0x9D, 0x04, 0x41, 0x05, 0xC4, 0xAD, 0x10, 0x07, 0x50, 0x40, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x13, 0x74, 0x03, 0x10,
-0x0D, 0x42, 0x30, 0x10, 0xCD, 0x04, 0x24, 0x02, 0x90, 0x3C, 0x40, 0x73, 0x00,
-0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0xF3, 0x00, 0xC1, 0x00, 0x34, 0x03,
-0xD0, 0x0C, 0x40, 0x34, 0x80, 0x49, 0x50, 0x05, 0x07, 0x10, 0x18, 0x40, 0xD3,
-0x01, 0xC5, 0x01, 0x04, 0x07, 0x50, 0x0C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x88, 0x38, 0x02, 0xED, 0x02, 0x34, 0x03, 0x14, 0x4E,
-0x40, 0x38, 0x00, 0xED, 0x02, 0xC4, 0x03, 0x10, 0x0E, 0x42, 0x3B, 0x08, 0xED,
-0x0C, 0xB6, 0x03, 0xD0, 0x0E, 0x40, 0xF3, 0x00, 0xE1, 0x10, 0xB4, 0x03, 0xD0,
-0x1E, 0x40, 0x38, 0x80, 0x69, 0x01, 0x84, 0x45, 0x12, 0x0A, 0x40, 0x19, 0x00,
-0xB1, 0x00, 0xC4, 0x45, 0x10, 0x0A, 0x42, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x47, 0x30, 0x5E, 0xC2,
-0x78, 0x10, 0x6F, 0x01, 0xAC, 0x07, 0xB0, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01,
-0xB4, 0x17, 0xF0, 0x1E, 0x80, 0x7B, 0x40, 0xE3, 0x01, 0xB4, 0x07, 0xF0, 0x17,
-0xD0, 0x70, 0x00, 0xEB, 0x01, 0xCC, 0x07, 0x34, 0x1A, 0xC0, 0x5B, 0x00, 0xE7,
-0x01, 0x8C, 0x07, 0x70, 0x17, 0xC0, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xA8, 0x35, 0x04, 0xDF, 0x00, 0x7C, 0x33, 0xF0, 0x8D, 0xD0, 0x15,
-0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC4, 0x37, 0x10, 0xDF, 0x06, 0x7C,
-0x53, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x83, 0xF0, 0x05, 0xC0,
-0x35, 0x00, 0xC7, 0x00, 0x7C, 0x01, 0xF0, 0x09, 0xC4, 0x13, 0x00, 0x97, 0x00,
-0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xA0, 0x7F, 0x00, 0x7F, 0x21, 0xCC, 0x07, 0xF8, 0xAE, 0xC0, 0x5F, 0x08,
-0xEF, 0x01, 0xCC, 0x07, 0x70, 0x9F, 0xC4, 0x5C, 0x02, 0xF3, 0x0B, 0xCC, 0x47,
-0x31, 0x1F, 0x40, 0x5F, 0x20, 0x7F, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C,
-0x00, 0xFF, 0x01, 0xFC, 0x07, 0x31, 0x9B, 0xC0, 0x7F, 0x00, 0xEF, 0x01, 0xCF,
-0x36, 0x30, 0xDF, 0xD0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0x88, 0x39, 0x00, 0x7D, 0x10, 0x84, 0x23, 0xD8, 0x4E, 0x04, 0xB8, 0x00, 0xAD,
-0x04, 0x81, 0x03, 0x10, 0xAF, 0x40, 0x1C, 0x02, 0xF1, 0x20, 0xD5, 0x03, 0x14,
-0x0E, 0x40, 0x1A, 0x01, 0x6D, 0x08, 0x85, 0x03, 0xD0, 0x8E, 0x00, 0x39, 0x02,
-0xED, 0x00, 0xA4, 0x11, 0x10, 0x8A, 0x40, 0xBB, 0x01, 0xED, 0x04, 0xDC, 0x20,
-0x10, 0xCA, 0x40, 0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x39, 0x00, 0x6D, 0x00, 0x85, 0x03, 0xD0, 0x8F, 0x40, 0x19, 0x00, 0x6D, 0x40,
-0xC0, 0x03, 0x50, 0x0E, 0x42, 0x18, 0x64, 0xE1, 0x00, 0x80, 0x43, 0x10, 0x0E,
-0x40, 0x3A, 0x08, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x07, 0x40, 0x18, 0x00, 0xED,
-0x00, 0x34, 0x03, 0x12, 0x0A, 0x48, 0x3B, 0x24, 0xFD, 0x20, 0x84, 0x52, 0x12,
-0xCA, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x73,
-0x12, 0x0D, 0x02, 0x04, 0x4B, 0xD0, 0x2C, 0x40, 0x04, 0x00, 0x0D, 0x08, 0x04,
-0x6F, 0x10, 0x08, 0x40, 0x40, 0x00, 0xC1, 0x40, 0x04, 0x0F, 0x10, 0x0C, 0x40,
-0x22, 0x00, 0x0D, 0x00, 0x04, 0x0F, 0xD2, 0x00, 0x40, 0x21, 0x00, 0xCD, 0x85,
-0x24, 0x00, 0x10, 0x08, 0x40, 0x73, 0x11, 0xCD, 0x00, 0x14, 0x04, 0x10, 0x38,
-0x40, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x3D, 0x00,
-0x9F, 0x00, 0xCC, 0x1F, 0xD0, 0x2F, 0x80, 0x25, 0x00, 0x8F, 0x20, 0x4C, 0x0F,
-0x74, 0x01, 0xD2, 0xE4, 0x00, 0xF3, 0x00, 0xC4, 0x07, 0x30, 0x0D, 0xC0, 0x26,
-0x00, 0x9F, 0x00, 0x4C, 0x0B, 0xF0, 0x39, 0xC1, 0x04, 0x00, 0x4F, 0x47, 0x74,
-0x02, 0x34, 0x09, 0xC0, 0xF3, 0x00, 0xDF, 0x00, 0x44, 0x07, 0x34, 0x21, 0x80,
-0x54, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x21, 0x9F,
-0x10, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xA5, 0x00, 0x9F, 0x10, 0x7D, 0x03, 0xF0,
-0x09, 0xC0, 0xA7, 0x04, 0xDF, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x86, 0x00,
-0x9F, 0x02, 0x7C, 0x23, 0xF0, 0x41, 0xC0, 0x87, 0x00, 0x5F, 0x40, 0x6C, 0x02,
-0xF0, 0x29, 0xC0, 0xB7, 0x00, 0x9F, 0x90, 0x5C, 0x09, 0xF0, 0xC9, 0xC0, 0x37,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x80, 0x3F, 0x00,
-0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x2F, 0x00, 0x33, 0x89, 0xCC, 0x07, 0x10, 0x03,
-0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xF4, 0x43, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xBF,
-0x00, 0xFC, 0x43, 0xC0, 0x0B, 0xC0, 0x2C, 0x00, 0xFF, 0x00, 0xDC, 0x02, 0xF0,
-0x0B, 0xC0, 0x3F, 0x00, 0xB7, 0x00, 0xFC, 0x07, 0x34, 0x01, 0xC8, 0x07, 0x24,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x80, 0x9D, 0x07, 0x74,
-0x83, 0xD0, 0x0D, 0x42, 0xE7, 0x20, 0x11, 0x87, 0x04, 0x07, 0xB0, 0x31, 0x40,
-0xE7, 0x00, 0xDD, 0x20, 0x64, 0x03, 0xD0, 0x0D, 0x40, 0x46, 0x00, 0x99, 0x01,
-0x74, 0x83, 0x91, 0x30, 0x40, 0xE5, 0x00, 0xDD, 0x01, 0x44, 0x06, 0xD0, 0x39,
-0x40, 0x77, 0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x31, 0x44, 0x87, 0x00, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x20, 0x9D, 0x01, 0x74, 0x03,
-0xD0, 0x0D, 0x64, 0x47, 0x40, 0x91, 0x00, 0x44, 0x23, 0x50, 0x11, 0x40, 0x67,
-0x04, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0xC7, 0x00, 0x1D, 0x03, 0x74,
-0x03, 0xD0, 0x19, 0x40, 0x47, 0x00, 0x9D, 0x01, 0x54, 0xC4, 0xD0, 0x1D, 0x40,
-0x77, 0x00, 0xD5, 0x01, 0x34, 0x1A, 0x10, 0x31, 0x40, 0x07, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0,
-0x0C, 0x60, 0x23, 0x00, 0x81, 0x00, 0x44, 0x03, 0xD4, 0x08, 0x40, 0x23, 0x20,
-0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x03, 0x00, 0x09, 0x00, 0x34, 0x03,
-0x90, 0x09, 0x40, 0x03, 0x00, 0xCD, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x33,
-0x00, 0xC1, 0x00, 0x34, 0x01, 0x10, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x3E, 0x00, 0x1D, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
-0xC0, 0x07, 0x08, 0x93, 0x00, 0x4D, 0x03, 0x70, 0x01, 0xC0, 0x07, 0x00, 0xFF,
-0x00, 0xFC, 0x03, 0xF0, 0x0D, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0,
-0x09, 0xD0, 0x06, 0x00, 0xDF, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00,
-0x97, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x60, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x2F, 0x00, 0x3F, 0x00, 0xBC, 0x03, 0xA0, 0x0B, 0xC0, 0x2F, 0x00, 0xFE, 0x00,
-0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x0E, 0x00, 0xBA, 0x00, 0xFC, 0x03, 0xB0, 0x0A,
-0xC0, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC2, 0x2F, 0x00, 0xBF,
-0x00, 0xFC, 0x00, 0xF2, 0x0B, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0xA0, 0x2F, 0x40, 0x23, 0x10, 0xCD, 0x00, 0x30, 0x03, 0xC0, 0x4C,
-0x40, 0x33, 0x81, 0xCC, 0x24, 0x30, 0x13, 0xD0, 0x2C, 0x05, 0xF3, 0x09, 0xDC,
-0x00, 0x30, 0x4E, 0xC0, 0x2C, 0x00, 0x3F, 0x01, 0xCD, 0x04, 0xF1, 0x13, 0xC0,
-0x4C, 0x08, 0x33, 0x01, 0xFC, 0x04, 0xB0, 0x13, 0xD4, 0x4C, 0x40, 0xF3, 0x00,
-0xCD, 0x07, 0xF0, 0x4F, 0xC1, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x27, 0x00, 0x51, 0x92, 0x04, 0x08, 0x13, 0x09, 0x40, 0x04, 0x05,
-0x11, 0x10, 0x44, 0x01, 0x10, 0x01, 0x41, 0xA4, 0x05, 0xC1, 0x04, 0x44, 0x2C,
-0x10, 0x3F, 0xC0, 0x64, 0x02, 0x1D, 0x00, 0x64, 0x04, 0xD0, 0x05, 0xC0, 0x04,
-0x20, 0x11, 0x01, 0x74, 0x04, 0x10, 0x01, 0x60, 0x04, 0x00, 0xC1, 0x00, 0x44,
-0x07, 0xD1, 0x2D, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
-0xA0, 0x27, 0x00, 0x01, 0x05, 0x06, 0x0C, 0x10, 0x00, 0x40, 0x20, 0x01, 0x81,
-0x00, 0x14, 0x02, 0x10, 0x48, 0x48, 0x21, 0x00, 0x81, 0x04, 0x34, 0x00, 0xD4,
-0x8C, 0x44, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x01, 0xD0, 0x00, 0x42, 0x46, 0x20,
-0x0D, 0x01, 0x74, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0xC9, 0x00, 0x24, 0x03,
-0xD0, 0x0C, 0x40, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8,
-0x25, 0x02, 0x51, 0x44, 0x14, 0x04, 0x14, 0x1D, 0x40, 0x20, 0x00, 0x80, 0x00,
-0x55, 0x03, 0x14, 0x09, 0x40, 0x64, 0x00, 0x51, 0x00, 0x64, 0x0C, 0xC0, 0x1D,
-0x44, 0x76, 0x04, 0x8D, 0x00, 0x74, 0x89, 0xD0, 0x05, 0x50, 0x04, 0x00, 0x15,
-0x00, 0x74, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0x99, 0x00, 0x44, 0x03, 0xD0,
-0x1C, 0x40, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x43,
-0x00, 0x13, 0x00, 0x4C, 0x04, 0x30, 0x31, 0xC2, 0x04, 0x00, 0x13, 0x01, 0x5C,
-0x00, 0x30, 0x11, 0xC0, 0xE4, 0x04, 0xD3, 0x04, 0x7C, 0x0C, 0xF0, 0x35, 0xC0,
-0xE4, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x21, 0xC0, 0x12, 0x00, 0x57, 0x00,
-0x3C, 0x01, 0xB0, 0x01, 0x40, 0x04, 0x00, 0xDB, 0x00, 0x4C, 0x03, 0xF0, 0x1D,
-0xC0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x4D, 0x00,
-0x7F, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0F, 0x12, 0x3F, 0x09, 0xEC, 0x01,
-0xF0, 0x93, 0x80, 0x2F, 0x50, 0xFF, 0x00, 0x5C, 0x00, 0x30, 0x06, 0xC0, 0x25,
-0x00, 0x3F, 0x08, 0xCC, 0x00, 0xF2, 0x07, 0xC4, 0x1F, 0x00, 0x7B, 0x00, 0xFC,
-0x81, 0xF0, 0x83, 0xC0, 0x0F, 0x02, 0xE7, 0x08, 0xFC, 0x03, 0xF0, 0x0F, 0xD4,
-0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x40, 0x33,
-0x00, 0x4C, 0x00, 0x32, 0x31, 0xC0, 0x64, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0,
-0x09, 0xC0, 0x24, 0x00, 0x53, 0x04, 0x6C, 0x88, 0xB0, 0x2D, 0xC0, 0x34, 0x11,
-0x97, 0x05, 0x7C, 0x01, 0x30, 0x41, 0xC0, 0x17, 0x02, 0x5B, 0x10, 0x4C, 0x03,
-0x30, 0x19, 0xC0, 0x64, 0x00, 0x9F, 0x04, 0x4C, 0x03, 0xF0, 0x15, 0xC0, 0x08,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x20, 0x41, 0x01,
-0x44, 0x14, 0x10, 0xBD, 0x40, 0x64, 0x00, 0x9D, 0x0B, 0x44, 0x2F, 0xD0, 0xA8,
-0xC2, 0x26, 0x00, 0xD1, 0x82, 0x04, 0x00, 0x10, 0xAD, 0x40, 0xB4, 0x00, 0x91,
-0x03, 0x70, 0x09, 0x11, 0x35, 0x40, 0x97, 0x02, 0x51, 0x13, 0x44, 0x43, 0x10,
-0xB9, 0x40, 0x64, 0x00, 0x9D, 0x02, 0x45, 0x13, 0xD0, 0x15, 0x40, 0x6C, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x20, 0x02, 0x01, 0x1A, 0x20,
-0x00, 0x14, 0x21, 0x40, 0x10, 0x00, 0x4D, 0x00, 0x60, 0x2C, 0xD0, 0x14, 0x40,
-0x34, 0x40, 0xD1, 0x02, 0x24, 0x00, 0xD0, 0x2C, 0x40, 0x00, 0x20, 0x45, 0x02,
-0x30, 0x62, 0x10, 0x19, 0x40, 0x21, 0x00, 0x80, 0x41, 0x04, 0x04, 0x10, 0x04,
-0x40, 0x10, 0x00, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x08, 0x40, 0x1C, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x68, 0x00, 0x31, 0x01, 0xA5, 0x04,
-0x10, 0x1B, 0x40, 0x58, 0x00, 0x6D, 0x01, 0xA4, 0x05, 0xD0, 0x16, 0x40, 0x6A,
-0x00, 0xE1, 0x01, 0x84, 0x24, 0x50, 0x9E, 0x40, 0x58, 0x00, 0x61, 0x01, 0xB6,
-0x06, 0x10, 0x1E, 0x40, 0x6F, 0x00, 0xB1, 0x81, 0xC4, 0x04, 0x10, 0x16, 0x40,
-0x58, 0x00, 0xED, 0x09, 0x84, 0x07, 0xD0, 0x2F, 0x40, 0x74, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x24, 0x01, 0x03, 0x08, 0x24, 0x00, 0x30,
-0x64, 0xC0, 0x30, 0x00, 0xDF, 0x00, 0x2C, 0x02, 0xF0, 0x0C, 0xC1, 0x14, 0x20,
-0x83, 0x00, 0x2C, 0x20, 0xF2, 0x08, 0xD0, 0x10, 0x00, 0xC7, 0x00, 0x3C, 0x03,
-0x30, 0x48, 0xC1, 0x23, 0x10, 0x83, 0x00, 0x0C, 0x02, 0x32, 0x0D, 0xD0, 0x30,
-0x00, 0x8F, 0x00, 0x0D, 0x03, 0xF0, 0x8C, 0xC8, 0x48, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x40, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x0E,
-0xC0, 0x3F, 0x00, 0xFF, 0x08, 0xDD, 0x03, 0xF2, 0x8E, 0xC4, 0x2F, 0x20, 0xFF,
-0x00, 0xFC, 0x20, 0xB0, 0x0F, 0xC2, 0x1F, 0x02, 0xFF, 0x08, 0xBC, 0x23, 0xF0,
-0x0F, 0xC0, 0x2B, 0x00, 0xA7, 0x00, 0xBC, 0x02, 0xF1, 0x0F, 0xC0, 0x3F, 0x00,
-0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x4E, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0xA0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x34, 0x05, 0xC0,
-0x14, 0x00, 0x5F, 0x01, 0x4C, 0x00, 0xF0, 0x05, 0xC0, 0x34, 0x00, 0xCF, 0x00,
-0x4C, 0x04, 0x30, 0x4C, 0xC0, 0x34, 0x00, 0x5B, 0x00, 0x7C, 0x02, 0xF0, 0x09,
-0xD0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0xDF,
-0x00, 0x0D, 0x03, 0x30, 0x0C, 0xD0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x80, 0x0D, 0x10, 0x21, 0x00, 0xF4, 0x02, 0x10, 0x0E, 0x40, 0x18,
-0x30, 0x6D, 0x00, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x28, 0x00, 0xED, 0x00, 0xAC,
-0x00, 0x90, 0x0E, 0x43, 0x38, 0x48, 0x61, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x42,
-0x38, 0x00, 0xE1, 0x00, 0xB4, 0x01, 0xD0, 0x06, 0x40, 0x1B, 0x00, 0xFD, 0x00,
-0x84, 0x03, 0x10, 0x0E, 0x60, 0x4C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x79, 0x00, 0x21, 0x01, 0xB4, 0x04, 0x10, 0x1E, 0x40, 0x78, 0x00,
-0xED, 0x01, 0x84, 0x06, 0xD0, 0x1E, 0x60, 0x78, 0x00, 0xFD, 0x01, 0x04, 0x40,
-0xD0, 0x1A, 0x40, 0x78, 0x00, 0xE9, 0x21, 0xB6, 0x07, 0xD0, 0x1A, 0x40, 0x78,
-0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0x84,
-0x07, 0x10, 0x17, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-0x28, 0x33, 0x02, 0x81, 0x00, 0x74, 0x27, 0x10, 0x7C, 0x40, 0x30, 0x00, 0xCD,
-0x00, 0x44, 0x03, 0xD0, 0x0C, 0x62, 0x20, 0x01, 0xCD, 0x83, 0x24, 0x07, 0xD0,
-0x2C, 0x40, 0x70, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x42, 0x34, 0x00,
-0xC1, 0x40, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x09, 0x04, 0x03,
-0x15, 0x04, 0x60, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20,
-0x19, 0x40, 0x73, 0x42, 0xFC, 0x05, 0x30, 0x57, 0xD0, 0x14, 0x00, 0x5F, 0x00,
-0x4D, 0x01, 0xF0, 0x05, 0xD0, 0x1C, 0x20, 0x7F, 0x05, 0xCC, 0x09, 0x74, 0x27,
-0xC0, 0xDC, 0x03, 0x5B, 0x80, 0x3C, 0x01, 0xF1, 0x05, 0xC0, 0x14, 0x00, 0x53,
-0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x0C, 0x01, 0x30,
-0x27, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x85,
-0x14, 0x0F, 0x24, 0x7C, 0x04, 0xF4, 0x21, 0xC0, 0x07, 0x00, 0x1F, 0x80, 0x7C,
-0x00, 0xF0, 0x01, 0xC0, 0x03, 0x00, 0x1F, 0x10, 0x7C, 0x10, 0x30, 0x61, 0xD0,
-0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xD1, 0x01, 0xC8, 0x07, 0x40, 0x1F, 0x00,
-0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
-0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00,
-0x93, 0x01, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0x30, 0x89, 0xC0, 0x24, 0x00, 0x93, 0x04, 0x0C, 0x0A, 0x30, 0x29, 0xC0, 0x22,
-0x70, 0x93, 0x80, 0x7C, 0x06, 0x30, 0x09, 0xC0, 0x64, 0x02, 0x93, 0x05, 0x7C,
-0x02, 0xF0, 0x49, 0xC0, 0x27, 0x02, 0x9F, 0x01, 0x4C, 0x02, 0x30, 0x09, 0xC0,
-0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x10, 0x91,
-0x28, 0x44, 0x02, 0x10, 0x28, 0x40, 0xA4, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10,
-0x39, 0x40, 0x24, 0x20, 0x81, 0x00, 0x6C, 0x02, 0x10, 0x28, 0x40, 0xA4, 0x00,
-0x91, 0x02, 0x5C, 0x02, 0x10, 0x09, 0x40, 0xE4, 0x08, 0x91, 0x21, 0x74, 0x82,
-0xD0, 0x29, 0x40, 0xE7, 0x00, 0x9D, 0x03, 0x45, 0x02, 0x14, 0x09, 0x40, 0x04,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x46, 0x91, 0x20,
-0x44, 0x02, 0x12, 0x29, 0x40, 0x24, 0x01, 0xBD, 0x04, 0xF4, 0x02, 0x18, 0x0A,
-0x40, 0x24, 0x00, 0x91, 0x80, 0x64, 0x02, 0x19, 0x0D, 0x40, 0x26, 0x00, 0x91,
-0x00, 0xF4, 0x22, 0x1C, 0x0F, 0x40, 0x2C, 0x04, 0xB1, 0x00, 0xF4, 0x06, 0xD0,
-0x0B, 0x40, 0x2F, 0x00, 0x8D, 0x0A, 0x64, 0x02, 0x10, 0x18, 0x40, 0x62, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x24, 0x01, 0x81, 0x04, 0x04,
-0x12, 0x10, 0x48, 0x50, 0x68, 0x00, 0xAD, 0x01, 0xB4, 0x02, 0x10, 0x1A, 0x42,
-0x20, 0x01, 0x91, 0x00, 0x24, 0x12, 0x10, 0x48, 0x40, 0x32, 0x01, 0xA1, 0x01,
-0xD4, 0x03, 0x10, 0x0A, 0x40, 0x28, 0x20, 0xA1, 0x01, 0xB4, 0x02, 0xD0, 0x1A,
-0x40, 0x6B, 0x00, 0x8D, 0x04, 0x25, 0x02, 0x10, 0x58, 0x50, 0x42, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x86, 0x02, 0x53, 0x0A, 0x4D, 0x28,
-0x34, 0xA0, 0x40, 0x84, 0x02, 0x0F, 0x0A, 0x7C, 0x29, 0x30, 0xA2, 0x40, 0x84,
-0x02, 0x13, 0x0A, 0x6C, 0x00, 0x30, 0x05, 0xC0, 0x06, 0x00, 0x13, 0x0A, 0x7C,
-0x00, 0x30, 0xA0, 0xD0, 0x80, 0x02, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0xA1, 0xC0,
-0x8F, 0x02, 0x1F, 0x0A, 0x6C, 0x00, 0x30, 0xA1, 0xC0, 0x76, 0xC0, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x2F, 0x02, 0xBF, 0x08, 0xFC, 0x22, 0xF0,
-0x8B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF4, 0x09, 0xD0, 0x2F, 0x42,
-0xBF, 0x80, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x29, 0x82, 0x9F, 0x00, 0x5C, 0x02,
-0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0xBF, 0x08, 0x5C, 0x02, 0xF0, 0x8B, 0xC0, 0x65, 0x60, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x01, 0xA3, 0x14, 0xFC, 0x32, 0xF0, 0x0B,
-0xD0, 0x2C, 0x00, 0xB3, 0x08, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x26, 0x19, 0xB3,
-0x00, 0xCC, 0x06, 0x30, 0x1B, 0xC1, 0x6E, 0x04, 0xBF, 0x00, 0xFC, 0x02, 0x30,
-0x0B, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0x31, 0x0B, 0xC0, 0x2C, 0x02,
-0xBF, 0x00, 0xCC, 0x02, 0xF0, 0x8F, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x00, 0x17, 0x45, 0x11, 0x04, 0x74, 0x30, 0xD0, 0x20, 0x41,
-0x14, 0x44, 0x51, 0x00, 0x74, 0x50, 0x10, 0x41, 0x50, 0x04, 0x02, 0x13, 0x00,
-0x6C, 0x28, 0x14, 0x01, 0x40, 0x04, 0x00, 0x5D, 0x04, 0x74, 0x00, 0x10, 0x01,
-0x41, 0x04, 0x04, 0x11, 0x00, 0x44, 0x00, 0x10, 0x45, 0x40, 0x14, 0x01, 0x1D,
-0x12, 0x45, 0x00, 0xD0, 0x81, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x00, 0x21, 0x43, 0x81, 0x14, 0x34, 0x12, 0xD0, 0xC8, 0x50, 0x20,
-0x10, 0x81, 0x00, 0x74, 0x16, 0x14, 0x48, 0x41, 0x24, 0x00, 0x81, 0x00, 0x24,
-0x02, 0x90, 0x08, 0x40, 0x22, 0x00, 0x8D, 0x94, 0x74, 0x02, 0x98, 0x49, 0x40,
-0x22, 0x00, 0x91, 0x00, 0x14, 0x02, 0x90, 0x48, 0x41, 0x22, 0x11, 0x8D, 0x0C,
-0x04, 0x02, 0xD0, 0x18, 0x40, 0x48, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x28, 0x25, 0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x49, 0x41, 0x20, 0x00,
-0x91, 0x00, 0x74, 0x02, 0x10, 0x29, 0x40, 0xA4, 0x00, 0x91, 0x00, 0x64, 0x62,
-0x98, 0x19, 0x44, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0x9C, 0x09, 0x50, 0x22,
-0x00, 0x91, 0x00, 0x54, 0x02, 0x90, 0x08, 0x50, 0x26, 0x00, 0x9D, 0x08, 0x44,
-0x02, 0xD0, 0x08, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0x00, 0x25, 0x00, 0x93, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0xA4, 0x00, 0x93,
-0x02, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x40, 0x93, 0x10, 0x6D, 0x0A, 0xB0,
-0x79, 0xC0, 0x26, 0x10, 0x9F, 0x02, 0x3C, 0x02, 0xB0, 0x08, 0xC2, 0x26, 0x40,
-0x83, 0x00, 0x5C, 0x42, 0xB4, 0x29, 0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x4C, 0x02,
-0xF0, 0x19, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08,
-0xE5, 0x00, 0x9F, 0x10, 0x7C, 0xA6, 0xF0, 0x18, 0xD0, 0x27, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x25, 0x00, 0x97, 0x15, 0x7E, 0x06, 0x70, 0x09,
-0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x26, 0x72, 0x09, 0xC1, 0x25, 0x00, 0x9F,
-0x00, 0x6D, 0x02, 0x70, 0x09, 0xC0, 0x25, 0x04, 0x9F, 0x10, 0x7E, 0x02, 0xF0,
-0x49, 0xD1, 0x5B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x81,
-0x01, 0x13, 0x02, 0x4C, 0x20, 0x34, 0x81, 0xC0, 0x86, 0x44, 0x13, 0x12, 0x6D,
-0x04, 0xF0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x02, 0x4C, 0x88, 0x30, 0x20, 0xC0,
-0x04, 0x08, 0x1F, 0x02, 0x4D, 0x40, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x13, 0x00,
-0x7C, 0x40, 0xF0, 0x21, 0xD0, 0x84, 0x40, 0x13, 0x08, 0x4C, 0x00, 0xF0, 0x01,
-0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x1C, 0x00,
-0x71, 0x82, 0x44, 0x05, 0x10, 0x17, 0xC0, 0x9C, 0x00, 0x71, 0x02, 0x84, 0x05,
-0xD0, 0x16, 0x40, 0x10, 0x00, 0x7D, 0x00, 0x14, 0x01, 0x14, 0x37, 0x40, 0x9C,
-0x00, 0x7D, 0x03, 0xC4, 0x11, 0xD0, 0x17, 0xC0, 0x1C, 0x00, 0x71, 0x00, 0xB0,
-0x4D, 0xD0, 0x07, 0x40, 0x1C, 0x00, 0x71, 0x01, 0x45, 0x01, 0xD0, 0x17, 0x41,
-0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x40, 0x81,
-0x02, 0x24, 0x07, 0x10, 0x0C, 0x40, 0xB0, 0x00, 0xC1, 0x02, 0x04, 0x27, 0xD0,
-0x08, 0x40, 0x30, 0x00, 0x5D, 0x00, 0x04, 0x03, 0x90, 0xB8, 0x51, 0xB0, 0x21,
-0xCD, 0x05, 0x00, 0x07, 0xD0, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x13, 0x34, 0x0B,
-0xD8, 0x0C, 0x40, 0x30, 0x00, 0x91, 0x03, 0x04, 0x02, 0xD0, 0x2C, 0x40, 0x50,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x28, 0x00, 0x31, 0x01,
-0xA4, 0x06, 0x10, 0x06, 0x40, 0x38, 0x00, 0xE1, 0x01, 0x84, 0x03, 0xD0, 0x0E,
-0x42, 0x38, 0x21, 0xED, 0x00, 0x94, 0x03, 0x90, 0x08, 0x40, 0x18, 0x04, 0xED,
-0x03, 0x84, 0x01, 0xD1, 0x2F, 0x50, 0x38, 0x00, 0x21, 0x10, 0xB4, 0x03, 0xD0,
-0x0E, 0x40, 0x78, 0x00, 0xA1, 0x00, 0x84, 0x02, 0xD0, 0x08, 0x40, 0x14, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x5C, 0x02, 0x63, 0x01, 0xEC,
-0x07, 0x30, 0x1E, 0xD1, 0x7C, 0x00, 0xF3, 0x01, 0x8C, 0x07, 0xF0, 0x1A, 0xD0,
-0xF8, 0x21, 0x3F, 0x01, 0x84, 0x07, 0xB0, 0x16, 0xC0, 0x78, 0x00, 0xFF, 0x21,
-0x8C, 0x07, 0xF0, 0x1E, 0xC0, 0x7C, 0x40, 0x23, 0x01, 0xBC, 0x07, 0xF0, 0x1F,
-0xC0, 0x7C, 0x00, 0x73, 0x01, 0x84, 0x06, 0xF0, 0x1E, 0xD0, 0x54, 0x40, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x9D, 0x00, 0x1F, 0x80, 0x5D, 0x12,
-0xF0, 0x07, 0xC0, 0x35, 0x08, 0x5F, 0x00, 0x7C, 0x03, 0xF2, 0x00, 0xC0, 0x77,
-0x00, 0x9F, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C,
-0x03, 0xF0, 0x0C, 0xC0, 0x35, 0x08, 0x1F, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
-0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00, 0x23, 0x01, 0xCC, 0x3F, 0xF8,
-0x8B, 0xC0, 0x7C, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xB0, 0x9B, 0xC0, 0x7F, 0x00,
-0xE7, 0x01, 0x8C, 0x87, 0x24, 0x1E, 0xC0, 0x5D, 0x00, 0xF3, 0x01, 0xD4, 0x25,
-0xB0, 0x1F, 0xD8, 0x7C, 0x00, 0x32, 0x01, 0xFC, 0x05, 0xF0, 0x1F, 0xC0, 0x7C,
-0x00, 0x73, 0x01, 0xCC, 0x06, 0xF0, 0x17, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x00, 0x29, 0x00, 0x21, 0x82, 0x84, 0x62, 0x30, 0x47,
-0x40, 0x3C, 0x00, 0xE1, 0x00, 0xBC, 0x02, 0x10, 0xCE, 0x40, 0x3B, 0x00, 0xEB,
-0x00, 0xAC, 0x13, 0x30, 0x0E, 0x40, 0x98, 0x40, 0xE1, 0x08, 0x84, 0x01, 0x14,
-0x4B, 0xC1, 0x3C, 0x00, 0x21, 0x08, 0xB4, 0x08, 0xD0, 0x2E, 0x40, 0x3C, 0x00,
-0xE1, 0x00, 0x84, 0x02, 0xD0, 0x82, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x61, 0x00, 0x04, 0x13, 0x50, 0x8A, 0x50,
-0x38, 0x00, 0xE9, 0x00, 0xF4, 0x03, 0x10, 0x0A, 0x60, 0x33, 0x00, 0xB5, 0x00,
-0xA4, 0x83, 0x80, 0x0F, 0x50, 0x3B, 0x00, 0x61, 0x00, 0x94, 0x00, 0x94, 0x0E,
-0x60, 0x38, 0x00, 0x29, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1,
-0x00, 0x84, 0x02, 0xD0, 0x06, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x28, 0x51, 0x00, 0x01, 0x06, 0x05, 0x0A, 0x12, 0xB5, 0x41, 0x30,
-0x00, 0xC9, 0x00, 0x34, 0x02, 0x10, 0x04, 0x60, 0xF3, 0x40, 0x89, 0x03, 0x24,
-0x23, 0x10, 0x1C, 0x40, 0x32, 0x00, 0xD1, 0x00, 0x04, 0x01, 0x90, 0x08, 0x40,
-0x30, 0x00, 0x09, 0x00, 0x34, 0x00, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xD1, 0x00,
-0x05, 0x02, 0xD0, 0x18, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0xA0, 0x65, 0x40, 0x13, 0x07, 0x4C, 0x0E, 0x70, 0x09, 0xC0, 0x34, 0x00,
-0xDB, 0x00, 0x7C, 0x03, 0xB0, 0x08, 0xC2, 0x3F, 0x20, 0x07, 0x0D, 0x0C, 0x0A,
-0xB0, 0x5D, 0xC0, 0x73, 0x04, 0xD3, 0x00, 0x5C, 0x02, 0xB0, 0x0D, 0xC0, 0x34,
-0x00, 0x0B, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0, 0x34, 0x00, 0x93, 0x05, 0x4C,
-0x03, 0xF0, 0x0C, 0xC1, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0x08, 0x27, 0x02, 0x3F, 0x00, 0x7C, 0x02, 0x70, 0x21, 0xC0, 0x27, 0x20, 0x97,
-0x00, 0x5C, 0x07, 0xF0, 0x29, 0xC0, 0x37, 0x06, 0x97, 0x00, 0x7C, 0x42, 0xF0,
-0x0D, 0xC0, 0x35, 0x20, 0x9F, 0x00, 0x7C, 0x00, 0x72, 0x25, 0xC0, 0xA5, 0x00,
-0x13, 0x00, 0x7C, 0x08, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0xF0, 0x09, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
-0x0F, 0x60, 0x73, 0x00, 0xAC, 0x42, 0xB0, 0x03, 0xC0, 0x1C, 0x00, 0xFF, 0x00,
-0xFC, 0x03, 0x30, 0x4B, 0xC0, 0x3E, 0x00, 0x33, 0x05, 0xCC, 0x07, 0x30, 0x4F,
-0x40, 0x37, 0x00, 0xF3, 0x00, 0xEC, 0x02, 0xE0, 0x3F, 0xC0, 0x1C, 0x00, 0x31,
-0x00, 0xCC, 0x01, 0xF0, 0x07, 0x80, 0x5C, 0x00, 0x53, 0x00, 0xCC, 0x07, 0xF0,
-0x3F, 0xE0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6,
-0x00, 0x11, 0x22, 0x44, 0x06, 0x10, 0x31, 0x40, 0x14, 0x00, 0x5D, 0x01, 0x34,
-0x07, 0x10, 0x59, 0x42, 0x30, 0x40, 0x91, 0x40, 0x54, 0x03, 0x10, 0x7D, 0x40,
-0xF7, 0x00, 0x9B, 0x01, 0x44, 0x06, 0xD0, 0x05, 0x50, 0x34, 0x00, 0x11, 0x07,
-0x4C, 0x0C, 0xD0, 0x3D, 0x40, 0xD4, 0x02, 0xD1, 0x00, 0x44, 0x02, 0xD0, 0x39,
-0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xC2, 0x00,
-0x01, 0x00, 0x64, 0x13, 0x90, 0x19, 0x41, 0x76, 0x00, 0xDD, 0x88, 0x74, 0x07,
-0x14, 0x09, 0x48, 0x34, 0x00, 0x99, 0x40, 0x46, 0x12, 0x10, 0x0D, 0x48, 0x67,
-0x00, 0xD1, 0x04, 0x64, 0x04, 0xD0, 0x2C, 0x40, 0xB2, 0x01, 0x15, 0x01, 0x64,
-0x05, 0xD0, 0x8D, 0x40, 0x31, 0x04, 0x51, 0x00, 0x44, 0x13, 0xD0, 0x2D, 0x40,
-0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x01,
-0x00, 0x04, 0x02, 0x10, 0x00, 0x50, 0x62, 0x00, 0x8D, 0x00, 0x34, 0x07, 0x14,
-0x09, 0x42, 0x34, 0x00, 0x91, 0x00, 0x14, 0x02, 0x10, 0x0C, 0x60, 0x23, 0x40,
-0xC9, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x22, 0x80, 0x05, 0x80, 0x04, 0x00,
-0xD0, 0x08, 0x40, 0x21, 0x00, 0xC1, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x40,
-0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0E, 0x00, 0x53, 0x00,
-0xEC, 0x03, 0xB2, 0x03, 0xD0, 0x36, 0x00, 0xDF, 0x80, 0x7C, 0x03, 0x14, 0x09,
-0xD0, 0x36, 0x00, 0x92, 0x00, 0x4C, 0x03, 0x34, 0x0D, 0x40, 0x27, 0x10, 0x43,
-0x00, 0x6C, 0x00, 0xF0, 0x0D, 0xD0, 0x16, 0x00, 0x17, 0x00, 0x6C, 0x01, 0xF0,
-0x04, 0xD0, 0x35, 0x00, 0xD3, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x00, 0xC0,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0B, 0x00, 0x3F, 0x00, 0xFC,
-0x02, 0xF1, 0x03, 0xC0, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0xF4, 0x0B, 0xC0,
-0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00,
-0xB4, 0x00, 0xF0, 0x0F, 0xC0, 0x3D, 0x00, 0x3B, 0x00, 0xFC, 0x00, 0xF0, 0x0F,
-0xC0, 0x3E, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x17, 0x60, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x02,
-0xF0, 0x1F, 0xC8, 0x3F, 0x01, 0xBF, 0x22, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0xBF,
-0x05, 0xEF, 0x09, 0xEC, 0x10, 0xB0, 0x3F, 0xC0, 0xBD, 0x00, 0xB3, 0x04, 0xCC,
-0x82, 0x32, 0x2F, 0xC4, 0x2F, 0x40, 0xF2, 0x01, 0xCC, 0x13, 0xF0, 0x12, 0x44,
-0x7A, 0x20, 0x33, 0xCC, 0xEC, 0x06, 0x90, 0x1F, 0x40, 0x0E, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x77, 0x00, 0xDD, 0x01, 0x74, 0x26, 0xD0,
-0x1D, 0x40, 0xBF, 0x05, 0x1D, 0x02, 0x74, 0x38, 0x10, 0xC1, 0x40, 0xBF, 0x00,
-0xDD, 0x00, 0x64, 0x2C, 0x04, 0x4D, 0x40, 0xBF, 0x08, 0x11, 0x14, 0x74, 0x40,
-0x10, 0x6F, 0x40, 0xE7, 0x00, 0xD5, 0x01, 0xC4, 0x0F, 0xD0, 0x19, 0x40, 0x74,
-0x00, 0x01, 0x22, 0x44, 0x06, 0x12, 0x1D, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0xA0, 0x31, 0x00, 0xCD, 0x00, 0x34, 0x80, 0xD8, 0x0C,
-0x40, 0xB3, 0x00, 0x8D, 0x26, 0x34, 0x02, 0x10, 0x00, 0x41, 0x33, 0x11, 0xCD,
-0x80, 0x24, 0x02, 0x00, 0x0C, 0x40, 0x31, 0x83, 0x81, 0x8C, 0x04, 0xB2, 0x12,
-0x2C, 0x60, 0x03, 0x42, 0xD5, 0x00, 0x14, 0x23, 0xD0, 0x08, 0x40, 0x33, 0x00,
-0x45, 0x26, 0x64, 0x01, 0x90, 0x0C, 0x40, 0x4E, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x28, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x04, 0xD0, 0x0D, 0x44,
-0x37, 0x00, 0x9D, 0x01, 0x74, 0x04, 0x10, 0x11, 0x44, 0x37, 0x00, 0xDD, 0x00,
-0x66, 0x84, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x91, 0x01, 0x74, 0x06, 0x18, 0x0D,
-0x40, 0x47, 0x00, 0x55, 0x11, 0x54, 0x03, 0xD0, 0x19, 0x43, 0x37, 0x80, 0x11,
-0x18, 0x44, 0x0E, 0x10, 0x0D, 0x42, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x20, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x1E, 0xF0, 0x0D, 0xC0, 0x37,
-0x00, 0x9F, 0x87, 0x7C, 0xC4, 0x30, 0x19, 0xC2, 0x37, 0x18, 0xDF, 0x00, 0x6C,
-0x04, 0x30, 0x0D, 0xC4, 0x35, 0x08, 0x13, 0x01, 0x4C, 0x1E, 0x34, 0x0D, 0xC2,
-0x67, 0x40, 0xD7, 0x01, 0x5C, 0x03, 0xF0, 0x19, 0xC0, 0x37, 0x00, 0x95, 0x02,
-0x2C, 0x0E, 0xB0, 0x0D, 0xC0, 0x22, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x82, 0xF0, 0x0F, 0xC0, 0x3F, 0x90,
-0x3F, 0x90, 0xBC, 0x00, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x03, 0x9C, 0x40,
-0x70, 0x0F, 0xC0, 0x37, 0x40, 0x3F, 0x40, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x2F,
-0x00, 0xBF, 0x00, 0xEC, 0x03, 0xF0, 0x0B, 0xC0, 0x3C, 0x0C, 0x2F, 0x01, 0xFC,
-0x02, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x08, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x93,
-0x02, 0x7C, 0x0A, 0x30, 0x01, 0xC0, 0x34, 0x40, 0xD3, 0x04, 0x4E, 0x02, 0xF1,
-0x0D, 0xC0, 0x30, 0x00, 0x13, 0x08, 0x7C, 0x0A, 0xF0, 0x0D, 0xC0, 0x24, 0x00,
-0xD3, 0x22, 0x7C, 0x03, 0x30, 0x29, 0xC0, 0x34, 0x00, 0x13, 0x02, 0x4C, 0x0D,
-0xF0, 0x0D, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0,
-0x34, 0x00, 0xDD, 0x00, 0x74, 0x12, 0xD1, 0x0D, 0x00, 0x3F, 0x00, 0x91, 0x80,
-0x74, 0x00, 0x10, 0x01, 0x40, 0x3C, 0x24, 0xDB, 0x02, 0x66, 0x4A, 0xD0, 0x0D,
-0x48, 0xBC, 0x42, 0x1B, 0x8B, 0x74, 0x02, 0xF0, 0x3F, 0xC1, 0x62, 0x01, 0x8A,
-0x04, 0xF0, 0x03, 0xB1, 0xA8, 0x40, 0x30, 0x00, 0x1B, 0x0E, 0x44, 0x0F, 0xD0,
-0x0C, 0x40, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32,
-0x00, 0xCD, 0x00, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x01, 0x00, 0x34,
-0x02, 0x10, 0x08, 0x40, 0xF0, 0x09, 0xD1, 0x81, 0x24, 0x0E, 0xD0, 0x0C, 0x48,
-0x70, 0x00, 0x89, 0x03, 0x74, 0x00, 0xD0, 0x6C, 0x42, 0x02, 0x01, 0xC5, 0x30,
-0x20, 0x07, 0x00, 0xBC, 0x40, 0x30, 0x00, 0x00, 0x00, 0x04, 0x03, 0xD0, 0x0C,
-0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x80, 0x78, 0x00,
-0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0x61, 0x11, 0xB4, 0x07,
-0x10, 0x16, 0x40, 0x78, 0x00, 0xE1, 0x01, 0xA4, 0x25, 0xD0, 0x1E, 0x40, 0x78,
-0x00, 0x61, 0x01, 0xB4, 0x05, 0x50, 0x1E, 0x40, 0x7A, 0x00, 0xED, 0x01, 0xB4,
-0x07, 0x90, 0x0F, 0x40, 0x78, 0x04, 0xE9, 0x01, 0x84, 0x0E, 0xD0, 0x1E, 0x40,
-0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF,
-0x00, 0x3C, 0x01, 0xD0, 0x8C, 0xC0, 0x37, 0x00, 0x43, 0x00, 0x7C, 0x03, 0x10,
-0x8D, 0xD0, 0x34, 0x22, 0xC1, 0x90, 0x04, 0x2B, 0xD8, 0x0D, 0xD0, 0x30, 0x06,
-0xC9, 0x00, 0x3C, 0x01, 0xD0, 0x4D, 0xC0, 0x12, 0x00, 0xC3, 0x04, 0x2C, 0x53,
-0x30, 0x8C, 0x80, 0x30, 0x00, 0xC3, 0xE4, 0x0C, 0x83, 0xF0, 0x0C, 0xC0, 0x4B,
-0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00,
-0xFC, 0x01, 0xF0, 0x0F, 0xC0, 0x3F, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF4, 0x8F,
-0xC0, 0x3F, 0x02, 0xFF, 0x00, 0x5D, 0xA1, 0xF8, 0x0F, 0xC0, 0xBF, 0x00, 0xFF,
-0x80, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x1B, 0x02, 0xFB, 0x00, 0xB0, 0x4B, 0xF0,
-0xCF, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x0B, 0x60,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x80, 0xDF, 0x00, 0x7C,
-0x01, 0x70, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x05, 0x30, 0x0D, 0xC2,
-0xB5, 0x02, 0xCF, 0x00, 0x5D, 0x03, 0x38, 0x1D, 0xC0, 0x35, 0x01, 0xDF, 0x00,
-0x7C, 0x03, 0xF0, 0x6D, 0xC0, 0x10, 0x00, 0xC3, 0x00, 0x6C, 0x13, 0xF0, 0x09,
-0xC0, 0x37, 0xA0, 0xDF, 0x00, 0x4C, 0x03, 0xD0, 0x0C, 0xC0, 0x42, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03,
-0xD0, 0x0E, 0x00, 0x3B, 0x13, 0x6C, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
-0x04, 0xED, 0x00, 0x94, 0x03, 0x41, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4,
-0x01, 0xD0, 0x8F, 0xC0, 0x3A, 0x00, 0xE5, 0x00, 0x84, 0x03, 0xD0, 0x0A, 0x42,
-0x3B, 0x80, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x4C, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79, 0x88, 0xE5, 0x21, 0xB4, 0x47, 0xD0,
-0x1E, 0x44, 0x7B, 0x12, 0xEC, 0x01, 0x34, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x01,
-0xED, 0x21, 0x14, 0x07, 0x01, 0x1E, 0x4C, 0x79, 0x02, 0xED, 0x01, 0xB4, 0x07,
-0xD8, 0x5F, 0x40, 0x78, 0x00, 0xF5, 0x11, 0xB4, 0x17, 0xD0, 0x3A, 0x40, 0x7B,
-0x00, 0xED, 0x21, 0x84, 0x47, 0xD0, 0x1E, 0x48, 0x12, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x36, 0x0F, 0xD0, 0x0C,
-0x40, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0x10, 0x9C, 0x40, 0x33, 0x00, 0x8D,
-0xA0, 0x15, 0x07, 0x10, 0x0C, 0x40, 0x30, 0x10, 0xDD, 0x03, 0x34, 0x07, 0xD0,
-0x0C, 0x40, 0xF2, 0x00, 0xC5, 0x01, 0x14, 0x03, 0xD0, 0x08, 0x40, 0x33, 0x80,
-0xDD, 0x0D, 0x04, 0x07, 0xD0, 0x0C, 0x40, 0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x17, 0xA8, 0x15, 0x08, 0x5F, 0x00, 0xFC, 0x01, 0xF0, 0x05, 0xC0,
-0x17, 0x00, 0x7F, 0x0E, 0xF4, 0x01, 0xB0, 0xA7, 0xC2, 0x15, 0x08, 0x4F, 0x05,
-0xDC, 0x1D, 0x35, 0x05, 0xC4, 0x15, 0x00, 0x7F, 0x85, 0xFC, 0xED, 0xF0, 0x05,
-0xC0, 0x1C, 0x81, 0x77, 0x01, 0x7C, 0x01, 0xF1, 0x06, 0xC0, 0x17, 0x08, 0x7D,
-0x02, 0xCD, 0x05, 0xF0, 0x04, 0xC0, 0x5E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07,
-0x00, 0x1F, 0x02, 0x78, 0x04, 0x74, 0x01, 0x00, 0x07, 0x00, 0x1E, 0x00, 0x7D,
-0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x06, 0x7C, 0x00, 0xC0, 0x00, 0xC0,
-0x87, 0x81, 0x1F, 0x10, 0x64, 0x08, 0xF2, 0x21, 0xC1, 0x87, 0x20, 0x1F, 0x02,
-0x7D, 0x08, 0xF0, 0x01, 0xC0, 0x49, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xE0, 0x27, 0x00,
-0x83, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC8, 0x26, 0x02, 0x9F, 0x04, 0x0C, 0x02,
-0x34, 0x09, 0xC0, 0x27, 0x01, 0x9C, 0x08, 0x0C, 0x02, 0x30, 0x59, 0xC0, 0xA0,
-0x20, 0x93, 0x00, 0x5C, 0x86, 0xF0, 0x19, 0xC0, 0xA4, 0x00, 0x9F, 0x00, 0x4C,
-0x06, 0xF0, 0x09, 0xD0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x14, 0x09, 0x40, 0x27, 0x00, 0x91,
-0x00, 0x45, 0x02, 0xD0, 0x09, 0xD0, 0xA4, 0x00, 0x9D, 0x02, 0x6C, 0x42, 0x50,
-0x09, 0x40, 0x27, 0x21, 0x9D, 0x02, 0x45, 0x02, 0x14, 0x29, 0x50, 0xE4, 0x40,
-0x81, 0x13, 0x44, 0x86, 0xD0, 0x89, 0x40, 0x64, 0x08, 0x9D, 0x02, 0x44, 0x1A,
-0xD0, 0x19, 0x40, 0x04, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
-0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x23, 0x00, 0x91, 0x08,
-0x44, 0x02, 0xD9, 0x0C, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x65, 0x22, 0x92, 0x09,
-0x44, 0x27, 0x00, 0xDD, 0x02, 0x56, 0x02, 0x50, 0x09, 0x48, 0x34, 0x04, 0x91,
-0xA4, 0x54, 0x2A, 0xD1, 0x29, 0x50, 0xA6, 0x00, 0x9D, 0x0A, 0x64, 0x22, 0xD0,
-0x89, 0x60, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20,
-0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x08, 0x40, 0x23, 0x31, 0x81, 0x04, 0x04,
-0x12, 0xD8, 0x48, 0x4C, 0x20, 0x01, 0x8D, 0x01, 0x24, 0x12, 0x90, 0x08, 0x40,
-0x23, 0x21, 0x8D, 0x24, 0x16, 0x12, 0x50, 0x4C, 0x04, 0x20, 0x01, 0x90, 0x20,
-0x00, 0x12, 0xD0, 0x08, 0x40, 0x22, 0x00, 0x8D, 0x08, 0x24, 0x02, 0xD0, 0x08,
-0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00,
-0x1F, 0x00, 0x74, 0x00, 0x30, 0x01, 0x40, 0x87, 0x0A, 0x53, 0x0A, 0x4C, 0x28,
-0xF0, 0xA1, 0xC2, 0x94, 0x02, 0x1F, 0x0A, 0x6C, 0x00, 0x30, 0xA0, 0xC0, 0x87,
-0x02, 0x1F, 0x0A, 0x5C, 0x28, 0x70, 0xA1, 0x80, 0x04, 0x10, 0x12, 0x00, 0x5C,
-0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1D, 0x36, 0x6D, 0x00, 0xF0, 0x01, 0xC0,
-0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F,
-0x00, 0xFC, 0x23, 0xF0, 0x09, 0xC0, 0x27, 0x42, 0xBF, 0x08, 0xFC, 0x22, 0xF0,
-0x8B, 0x40, 0x27, 0x02, 0xBF, 0x20, 0xFD, 0x22, 0x70, 0x09, 0xC0, 0x27, 0x02,
-0xBF, 0x08, 0xE8, 0x22, 0xB0, 0x89, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0x7C, 0x22,
-0xF3, 0x0B, 0xC0, 0x25, 0x00, 0xBF, 0x04, 0xDC, 0x02, 0xF0, 0x09, 0xC0, 0x77,
-0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0x9F, 0x20,
-0xFC, 0x16, 0x30, 0x09, 0xC0, 0xE7, 0x20, 0xBF, 0x21, 0x6C, 0x13, 0xF0, 0xD9,
-0xC6, 0xEF, 0x08, 0xB3, 0x02, 0xCC, 0x16, 0xF0, 0x09, 0xC0, 0x6F, 0x04, 0xB3,
-0x07, 0x4C, 0x1E, 0xF0, 0x5B, 0xC0, 0x68, 0x00, 0xB3, 0x00, 0xFC, 0x12, 0x34,
-0x0B, 0xC2, 0x2F, 0x20, 0xBF, 0x00, 0xC4, 0x02, 0xB4, 0x0B, 0xC0, 0x77, 0x80,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x00, 0x74,
-0x28, 0x10, 0x01, 0x4C, 0x47, 0x08, 0x1C, 0x17, 0x45, 0x51, 0xD0, 0xF5, 0x40,
-0xC7, 0x40, 0x11, 0x05, 0x54, 0x08, 0x70, 0x51, 0x41, 0x47, 0x40, 0x11, 0x03,
-0x45, 0x0D, 0xD0, 0x71, 0x51, 0x84, 0x40, 0x15, 0x00, 0x74, 0x00, 0x11, 0x01,
-0x40, 0x07, 0x00, 0x1D, 0x20, 0x44, 0x01, 0x10, 0x01, 0x40, 0x62, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x03,
-0x10, 0x08, 0x40, 0xA3, 0x01, 0x8D, 0x02, 0x04, 0xB2, 0xD0, 0x08, 0x40, 0xA3,
-0x01, 0x81, 0x00, 0x25, 0x0E, 0xC1, 0x08, 0x40, 0x21, 0x04, 0x81, 0x07, 0x24,
-0x32, 0x50, 0x88, 0x40, 0xA2, 0x20, 0x81, 0x40, 0x34, 0x22, 0x50, 0x08, 0x40,
-0x23, 0x00, 0x8D, 0x00, 0x46, 0x03, 0xD1, 0x08, 0x40, 0x4B, 0x80, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x22, 0x10,
-0x09, 0x40, 0x27, 0x00, 0x9D, 0x14, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x37, 0x00,
-0x91, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x80, 0x91, 0x40, 0x64, 0x12,
-0xD8, 0x09, 0x60, 0x26, 0x01, 0x95, 0x02, 0x64, 0x02, 0x58, 0x0D, 0x40, 0x27,
-0x00, 0xDD, 0x04, 0x44, 0x02, 0x50, 0x09, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x0A, 0x34, 0x09,
-0xC0, 0x27, 0x08, 0x9F, 0x42, 0x4C, 0x02, 0xF0, 0x29, 0xC0, 0x27, 0x20, 0x91,
-0x08, 0x6D, 0x0A, 0xF0, 0x09, 0xC0, 0x25, 0x20, 0x93, 0x00, 0x6C, 0x06, 0x70,
-0x09, 0x42, 0xA6, 0xA1, 0x93, 0x22, 0x74, 0x02, 0x78, 0x09, 0xC1, 0x27, 0x00,
-0x9F, 0x06, 0x4D, 0x02, 0xF4, 0x09, 0xC0, 0x17, 0x80, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x16, 0x00, 0x25, 0x08, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x80, 0x7C, 0x22, 0xF0, 0x99, 0xC0, 0x27, 0x00, 0x9F, 0x11,
-0x5C, 0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x8F, 0x13, 0x5C, 0x06, 0xF0, 0x09,
-0xC0, 0x65, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC1, 0x27, 0x00, 0x9F,
-0x01, 0x7E, 0x22, 0xB4, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF8, 0x01, 0xC0, 0x07,
-0x80, 0x13, 0x06, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x47, 0x80, 0x1F, 0x00, 0x4C,
-0x00, 0x70, 0x01, 0xC0, 0x47, 0x10, 0x1F, 0x00, 0x7C, 0x08, 0x34, 0x11, 0xC0,
-0x87, 0x04, 0x13, 0x26, 0x2C, 0x10, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x04,
-0x7C, 0x48, 0x30, 0x81, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x20, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x17, 0xC0,
-0x70, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x00, 0x5F, 0x80, 0x6F, 0x46, 0xC5, 0x05,
-0x70, 0x05, 0x40, 0x1F, 0x00, 0x7D, 0x81, 0x74, 0x01, 0x30, 0x47, 0x40, 0x1B,
-0x00, 0x71, 0x03, 0xCC, 0x09, 0x60, 0x37, 0x40, 0x1C, 0xA0, 0x7D, 0x02, 0xB4,
-0x09, 0x10, 0x05, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x31, 0x10, 0xD1,
-0x03, 0x34, 0x03, 0xD2, 0x0C, 0x48, 0x77, 0x0A, 0xCD, 0x03, 0x04, 0x07, 0xD3,
-0x0C, 0x44, 0x37, 0x00, 0xCD, 0x08, 0x36, 0x03, 0x10, 0x1D, 0x40, 0xB1, 0x60,
-0x01, 0x02, 0x04, 0x23, 0xD0, 0x3C, 0x40, 0x81, 0x04, 0xDD, 0x80, 0x34, 0x0B,
-0x04, 0x1C, 0x60, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80,
-0x38, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x7B, 0x00, 0xE1, 0x02,
-0xB6, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xE5, 0x80, 0x85, 0x08, 0x50, 0x0E,
-0x60, 0x9B, 0x00, 0x6D, 0x40, 0x36, 0x07, 0x18, 0x0E, 0x40, 0x3B, 0x40, 0x21,
-0x10, 0x86, 0x03, 0x50, 0x17, 0x49, 0x08, 0x00, 0xAD, 0x02, 0xB6, 0x03, 0x10,
-0x0E, 0x60, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78,
-0x00, 0xEF, 0x01, 0xBC, 0x06, 0xD0, 0x1E, 0xC2, 0x71, 0x02, 0x61, 0x01, 0xBC,
-0x3F, 0xF0, 0xFE, 0xC0, 0x5B, 0x00, 0xED, 0x01, 0x8D, 0x05, 0x78, 0x3E, 0x41,
-0x7B, 0x00, 0xED, 0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC2, 0x69, 0x00, 0x63, 0xA0,
-0x8C, 0x07, 0xD1, 0x12, 0xC0, 0x49, 0x00, 0xED, 0x81, 0xBC, 0x06, 0x38, 0x1E,
-0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x35, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x00, 0x5F, 0x00, 0x7C, 0x03,
-0xC0, 0x0D, 0x40, 0x17, 0x00, 0xCF, 0x00, 0x7C, 0x00, 0xF1, 0x2D, 0xC0, 0x37,
-0x20, 0x5F, 0x80, 0x7C, 0xB3, 0xC0, 0x0D, 0xC8, 0x27, 0x00, 0x4F, 0x00, 0x7C,
-0x03, 0xF0, 0x04, 0xC0, 0x17, 0x00, 0x9D, 0x00, 0x3C, 0x00, 0xF1, 0x0D, 0xC8,
-0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xFF,
-0x01, 0xFC, 0x13, 0xF8, 0x8F, 0xC0, 0x7F, 0x04, 0xF7, 0x09, 0xCC, 0x87, 0xF0,
-0x1F, 0xC0, 0x7C, 0x00, 0xEB, 0x01, 0xEC, 0x07, 0xF9, 0x9F, 0xC0, 0x7F, 0x00,
-0xFF, 0x09, 0xCC, 0x0F, 0xB1, 0x1F, 0xC0, 0x3B, 0x00, 0x33, 0x01, 0xEE, 0x27,
-0x30, 0x17, 0xC0, 0x4F, 0x00, 0x7F, 0x81, 0xCC, 0x05, 0xC0, 0x9A, 0xC0, 0x1A,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0xED, 0x08,
-0xB4, 0x23, 0xD0, 0x0E, 0x48, 0x3B, 0x01, 0xED, 0x00, 0x84, 0x03, 0xD1, 0x0E,
-0x4E, 0x38, 0x40, 0xE1, 0x00, 0x84, 0x00, 0x78, 0x0E, 0x40, 0x1B, 0x08, 0xFD,
-0x00, 0x84, 0x13, 0x10, 0x0E, 0x42, 0x3B, 0x03, 0xA1, 0x80, 0xBC, 0x03, 0x14,
-0x06, 0x40, 0x0B, 0x08, 0x2D, 0x98, 0x84, 0x20, 0x90, 0x0A, 0x40, 0x54, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xED, 0x00, 0xB4,
-0x0B, 0xD0, 0x8E, 0x40, 0x3B, 0x28, 0xED, 0x00, 0xA4, 0x03, 0xD0, 0x0E, 0x40,
-0x1A, 0x00, 0xE1, 0x00, 0x84, 0x41, 0xD0, 0x0E, 0x44, 0x1B, 0x00, 0xED, 0x90,
-0xA4, 0xC3, 0x18, 0x86, 0x40, 0xAB, 0x0A, 0x61, 0x08, 0xA4, 0x01, 0x54, 0x06,
-0x40, 0x0B, 0x00, 0x6D, 0x00, 0x84, 0x40, 0xD0, 0x0E, 0x40, 0x22, 0x01, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
-0xD0, 0x0C, 0x00, 0x33, 0x10, 0x9D, 0x0B, 0x24, 0x2F, 0xD0, 0x1C, 0x5A, 0x02,
-0x00, 0xC1, 0x40, 0x05, 0x01, 0x50, 0x0C, 0x40, 0x07, 0x00, 0x8D, 0x02, 0x24,
-0x07, 0x1A, 0x08, 0x40, 0x63, 0xC0, 0x41, 0x00, 0x14, 0x01, 0x50, 0x24, 0x40,
-0x13, 0x20, 0x0D, 0x03, 0x05, 0x0C, 0x90, 0x0C, 0x40, 0x08, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x3C, 0x42, 0xD0,
-0x0D, 0xC0, 0x3F, 0x00, 0x9F, 0x00, 0xEC, 0x03, 0xF0, 0x1F, 0xC0, 0x26, 0x00,
-0xC1, 0x00, 0x4C, 0x23, 0xF0, 0x0F, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0xEC, 0x0F,
-0x14, 0x01, 0xE2, 0x77, 0x04, 0x13, 0x02, 0x64, 0x03, 0x50, 0xA5, 0x40, 0x07,
-0x00, 0xDF, 0x03, 0x4C, 0x0F, 0xD0, 0x0D, 0xC2, 0x56, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x03, 0xF1, 0x0D,
-0x40, 0x37, 0x20, 0x9F, 0x10, 0x5C, 0x03, 0xF0, 0xCD, 0xC0, 0xA1, 0x10, 0x97,
-0x01, 0x7D, 0x00, 0x70, 0x0D, 0xC0, 0x87, 0x00, 0x1F, 0x04, 0x5C, 0x43, 0x72,
-0x21, 0xE0, 0xA7, 0x80, 0x1F, 0x28, 0x74, 0x03, 0xA0, 0x05, 0xC0, 0x07, 0x00,
-0x9D, 0x04, 0x7C, 0x0B, 0xB0, 0x0D, 0xC0, 0xB7, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x20, 0xFC, 0x02, 0xB0, 0x0F, 0xE0,
-0x3B, 0xA0, 0x1B, 0x00, 0xCE, 0x43, 0x30, 0x0C, 0xC0, 0x24, 0x00, 0xFB, 0x00,
-0xAC, 0x01, 0xB0, 0x0F, 0xC0, 0x2F, 0x00, 0xA3, 0x00, 0xCC, 0x03, 0xF0, 0x0A,
-0xC0, 0x28, 0x10, 0x73, 0x59, 0x8C, 0x03, 0x32, 0x47, 0xC0, 0x0C, 0x00, 0xED,
-0x02, 0xCC, 0x47, 0x30, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40, 0x37,
-0x98, 0x11, 0x01, 0x44, 0x03, 0x10, 0x0D, 0x42, 0x64, 0x08, 0xD1, 0x01, 0x6C,
-0x04, 0xB0, 0x0D, 0xC2, 0xE7, 0x04, 0x11, 0x01, 0x44, 0x03, 0xD0, 0x39, 0x44,
-0x64, 0x01, 0x41, 0x01, 0x6C, 0x07, 0x10, 0x24, 0x40, 0x84, 0x02, 0x1D, 0x00,
-0x05, 0x01, 0x10, 0x0D, 0x4E, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0xA0, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x48, 0x37, 0x20,
-0x11, 0x01, 0x04, 0x03, 0x10, 0x0D, 0x60, 0x44, 0x00, 0xD1, 0x11, 0x64, 0x07,
-0x92, 0x0D, 0x42, 0x67, 0x80, 0x11, 0x01, 0x64, 0x83, 0x50, 0x11, 0x41, 0x56,
-0x00, 0x19, 0x00, 0x46, 0x07, 0x10, 0x05, 0x40, 0x04, 0x04, 0x5D, 0x00, 0x44,
-0x1B, 0x14, 0x09, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x40, 0x33, 0x00, 0x81,
-0x01, 0x04, 0x03, 0x14, 0x0C, 0x60, 0x20, 0x20, 0xC1, 0x00, 0x24, 0x00, 0x92,
-0x0C, 0x60, 0x01, 0x90, 0x01, 0x01, 0x24, 0x03, 0xD0, 0x00, 0x42, 0x22, 0x00,
-0xCD, 0x00, 0x24, 0x03, 0x14, 0x04, 0x40, 0x20, 0x00, 0xCD, 0x00, 0x04, 0x02,
-0x10, 0x08, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0x40, 0x3F, 0x00, 0x11, 0x20,
-0xC4, 0x03, 0x30, 0x0F, 0xC0, 0x04, 0x20, 0xDB, 0x00, 0x6D, 0x01, 0xB1, 0x0F,
-0x40, 0x27, 0x18, 0x93, 0x00, 0xAC, 0x03, 0x70, 0x01, 0xC0, 0x26, 0x00, 0x5B,
-0x00, 0x4C, 0x01, 0x30, 0x05, 0xE0, 0x04, 0x00, 0x0F, 0x00, 0x4C, 0x03, 0x30,
-0x0D, 0xC2, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x3F,
-0x00, 0xFF, 0x00, 0xFC, 0x03, 0x78, 0x0F, 0xC0, 0x3F, 0x10, 0xB7, 0x00, 0xFC,
-0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x10, 0x7F, 0x00, 0xFC, 0x00, 0x70, 0x0F, 0xC0,
-0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x03, 0xF0, 0x0B, 0xC0, 0x2D, 0x00, 0x73, 0x00,
-0xBC, 0x00, 0xF0, 0x07, 0x00, 0x0F, 0x08, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x0F,
-0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7B, 0x00,
-0x33, 0x00, 0xCC, 0x03, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xA3, 0x00, 0x8C, 0x06,
-0xB0, 0x03, 0xC0, 0x68, 0x02, 0x3F, 0x01, 0x8C, 0x04, 0x70, 0x1B, 0xC0, 0x3F,
-0x00, 0x33, 0x0C, 0xCC, 0x04, 0xB0, 0x2B, 0x10, 0x4C, 0x00, 0xF3, 0x01, 0xCC,
-0x02, 0x30, 0x0B, 0xD0, 0x4C, 0x00, 0xB3, 0x00, 0xCC, 0x07, 0xF0, 0x0F, 0xC0,
-0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x14, 0x11,
-0x00, 0xC4, 0x03, 0x11, 0x49, 0x40, 0x6F, 0x00, 0x91, 0x0B, 0x44, 0x84, 0x50,
-0x01, 0x40, 0x24, 0x21, 0x1D, 0x21, 0x44, 0x84, 0x10, 0x19, 0x40, 0x3F, 0x04,
-0x11, 0x02, 0x44, 0x04, 0x10, 0x2F, 0x42, 0x24, 0x10, 0xD1, 0x20, 0x44, 0x02,
-0x10, 0x0C, 0x41, 0x44, 0x00, 0x8B, 0x00, 0x54, 0x07, 0xD0, 0x1D, 0x40, 0x0C,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x21, 0x00, 0x00,
-0x04, 0x03, 0x10, 0x08, 0x41, 0x23, 0x00, 0xC1, 0x00, 0x44, 0x02, 0x10, 0x00,
-0x40, 0x20, 0x10, 0x1D, 0x00, 0x05, 0x00, 0x52, 0x08, 0x42, 0x33, 0x82, 0x81,
-0x02, 0x04, 0x00, 0x12, 0x68, 0x60, 0x00, 0x00, 0xD1, 0x40, 0x04, 0x06, 0x50,
-0x58, 0x40, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x4E, 0x80,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x08, 0x51, 0x01, 0x44,
-0x03, 0x10, 0x09, 0x40, 0x67, 0x40, 0xD1, 0x00, 0x45, 0x00, 0x50, 0x11, 0x50,
-0x34, 0x00, 0x1D, 0x01, 0x44, 0x44, 0x11, 0x19, 0x41, 0x37, 0x00, 0x91, 0x00,
-0x40, 0x04, 0x18, 0x0C, 0x60, 0x40, 0x40, 0xD1, 0x04, 0x44, 0x06, 0x50, 0x41,
-0x40, 0x44, 0x20, 0xD9, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x0E, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x73, 0x00, 0x13, 0x13, 0x4D, 0x03,
-0x34, 0x01, 0xC0, 0x67, 0x00, 0x93, 0x00, 0x4C, 0x03, 0x30, 0x39, 0xC8, 0x24,
-0x10, 0x0F, 0x03, 0x4C, 0x0C, 0x70, 0x19, 0xC8, 0x37, 0x40, 0x13, 0x04, 0x4C,
-0x18, 0x34, 0x09, 0xC0, 0xE4, 0x00, 0xC3, 0x00, 0x4D, 0x06, 0x70, 0x1D, 0xC0,
-0xC4, 0x00, 0x93, 0x01, 0x6C, 0x03, 0xF0, 0x4D, 0xD0, 0x02, 0x20, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0xFD, 0x40, 0x2F, 0x00, 0xBC, 0x03, 0xF1,
-0x93, 0xC0, 0x37, 0x00, 0xAF, 0x02, 0xFC, 0x02, 0x70, 0x0D, 0xC0, 0x2F, 0x00,
-0x3F, 0x10, 0xFC, 0x80, 0xF0, 0x03, 0xC8, 0x3F, 0x20, 0x3F, 0x23, 0xFC, 0x00,
-0x70, 0x9D, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xB4, 0x1F, 0xC0, 0x0F,
-0x00, 0xAF, 0x09, 0xDC, 0x03, 0xF0, 0x01, 0xC0, 0x1D, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00, 0x53, 0x00, 0x6D, 0x03, 0x32, 0x09,
-0xD0, 0x24, 0x00, 0xD3, 0x80, 0x4C, 0x03, 0x34, 0x6D, 0xC0, 0x24, 0x00, 0x13,
-0x42, 0x7C, 0x10, 0x30, 0x29, 0xD1, 0x30, 0x00, 0x83, 0x00, 0x4C, 0x18, 0x30,
-0x09, 0xC0, 0x84, 0x00, 0xD3, 0x00, 0x3C, 0x02, 0xB0, 0x11, 0xC0, 0x04, 0x00,
-0xDB, 0x00, 0x4D, 0x03, 0xF0, 0x0C, 0xC0, 0xA8, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xD1, 0x00, 0xC4, 0x43, 0x10, 0x09, 0x40,
-0x10, 0x00, 0xD1, 0x00, 0x04, 0x46, 0x10, 0x2D, 0x50, 0x34, 0x00, 0x13, 0x82,
-0x34, 0x08, 0x10, 0x79, 0x40, 0x7C, 0x04, 0xB5, 0x20, 0x2C, 0x0C, 0xB2, 0xAD,
-0x40, 0xC4, 0x06, 0xD1, 0x01, 0x74, 0x2A, 0x10, 0x08, 0x40, 0x40, 0x00, 0xDB,
-0x00, 0x44, 0x03, 0xD0, 0x01, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x20, 0x30, 0x40, 0x81, 0x21, 0x04, 0x03, 0x14, 0x08, 0x08, 0x20,
-0x89, 0x81, 0x00, 0x06, 0x06, 0x10, 0x01, 0x40, 0x20, 0x00, 0x08, 0x03, 0x34,
-0x0C, 0x18, 0x08, 0x40, 0x70, 0x00, 0x09, 0x00, 0x14, 0x2C, 0x94, 0x8C, 0x40,
-0x02, 0x00, 0xC1, 0x41, 0x34, 0x02, 0x90, 0x0C, 0x40, 0x52, 0x40, 0xC9, 0x00,
-0x05, 0x03, 0xD0, 0x0C, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x00, 0x7C, 0x40, 0xF1, 0x19, 0x04, 0x07, 0x10, 0x18, 0x40, 0x68, 0x00,
-0xB1, 0x81, 0xC6, 0x04, 0x10, 0x96, 0x40, 0x6C, 0x40, 0x21, 0x21, 0xB4, 0x44,
-0x18, 0x16, 0x62, 0x78, 0x10, 0x0D, 0x01, 0xB4, 0x04, 0x94, 0x1E, 0x40, 0x6A,
-0x00, 0xE1, 0x50, 0x36, 0x06, 0x10, 0x3E, 0x50, 0x4E, 0x04, 0xE9, 0x01, 0x86,
-0x07, 0xD0, 0x16, 0x60, 0x3C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x18, 0x30, 0x00, 0x83, 0x08, 0x0D, 0x03, 0x10, 0x08, 0xC0, 0x20, 0x40, 0xC3,
-0x00, 0x0D, 0x22, 0x30, 0x04, 0x48, 0x20, 0xB2, 0x09, 0x52, 0x3C, 0x20, 0x34,
-0x88, 0xC0, 0x30, 0x00, 0x0B, 0x00, 0x1C, 0x00, 0x90, 0x0C, 0xC0, 0x86, 0x00,
-0xC3, 0x00, 0x3C, 0x02, 0xB0, 0x00, 0xC0, 0x92, 0x10, 0xCB, 0x04, 0x0C, 0x03,
-0xF0, 0x0C, 0xD0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38,
-0x3D, 0x00, 0xEF, 0x68, 0xFE, 0x0B, 0xF0, 0x0F, 0xC0, 0xBF, 0x00, 0xFF, 0x00,
-0xFC, 0x00, 0xF0, 0x07, 0xC0, 0x3F, 0x20, 0xBF, 0x00, 0xFC, 0x20, 0xF0, 0x8E,
-0xC0, 0x3B, 0x00, 0xB7, 0x80, 0xAD, 0x22, 0xF0, 0x8F, 0xC0, 0x2D, 0x40, 0xFF,
-0x04, 0xFC, 0x02, 0xE0, 0x0B, 0xE0, 0x09, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
-0x07, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
-0x00, 0xD7, 0x60, 0x4C, 0x0B, 0x34, 0x01, 0xC0, 0x6F, 0x00, 0x97, 0x00, 0x7C,
-0x03, 0xF0, 0x09, 0xD0, 0x24, 0x00, 0x9F, 0x01, 0x4C, 0x00, 0xF0, 0x01, 0xC0,
-0x37, 0x81, 0x12, 0x08, 0x0C, 0x00, 0x31, 0x4D, 0xC0, 0x24, 0x00, 0xD3, 0x00,
-0x4C, 0x02, 0xB0, 0x1D, 0xD0, 0x54, 0x00, 0xD3, 0xA0, 0x4C, 0x83, 0xF0, 0x0D,
-0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x3D, 0x00,
-0xE1, 0x00, 0x06, 0x13, 0x10, 0x02, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x02,
-0xD0, 0x0E, 0x42, 0x28, 0x20, 0xA8, 0x00, 0x84, 0x00, 0xD0, 0x0E, 0x40, 0x3F,
-0x05, 0x31, 0x00, 0x84, 0x00, 0xD4, 0x0F, 0x51, 0x2C, 0x00, 0xE1, 0x00, 0x04,
-0x02, 0x14, 0x0C, 0x40, 0x08, 0x40, 0xF1, 0x00, 0x94, 0x03, 0xD0, 0x0A, 0x44,
-0x4F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xC5,
-0x01, 0x84, 0x27, 0x00, 0x1E, 0x40, 0x63, 0x00, 0xED, 0x01, 0xB4, 0x47, 0xD0,
-0x3C, 0x40, 0x68, 0x08, 0xAC, 0x11, 0x84, 0x05, 0xD0, 0x1A, 0x40, 0x7B, 0x43,
-0x29, 0x05, 0xA5, 0x04, 0x98, 0x1E, 0x40, 0x68, 0x80, 0xE1, 0x01, 0x84, 0x07,
-0x10, 0x12, 0x60, 0x5C, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x07,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x10, 0xD1, 0x00,
-0x04, 0x03, 0x10, 0x0C, 0x40, 0x53, 0x22, 0xC9, 0x00, 0x34, 0x0A, 0xD0, 0x15,
-0x40, 0x30, 0x00, 0xC9, 0x82, 0x04, 0x6B, 0xD0, 0x2C, 0x40, 0x33, 0x00, 0xD9,
-0x01, 0x24, 0x03, 0xD0, 0x0C, 0x50, 0xF0, 0x81, 0x91, 0x01, 0x04, 0x07, 0x10,
-0x08, 0x60, 0x20, 0x00, 0xC1, 0x00, 0x14, 0x03, 0xD0, 0x98, 0x40, 0x4B, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x15, 0x00, 0x77, 0x8A, 0x4D,
-0x81, 0x30, 0x76, 0xC0, 0x9F, 0x00, 0x5F, 0x01, 0xFC, 0x0D, 0xF1, 0xB7, 0xC0,
-0x14, 0x20, 0x7F, 0x4B, 0xCC, 0x0D, 0xF0, 0x26, 0xC0, 0x17, 0x10, 0x7B, 0x01,
-0xAC, 0x05, 0x34, 0x05, 0xC2, 0x9C, 0x04, 0x53, 0x01, 0xCC, 0x09, 0x30, 0x07,
-0xC1, 0x1C, 0x00, 0x53, 0x00, 0x4D, 0x01, 0xF2, 0x27, 0xC2, 0x5F, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x10, 0x1F, 0x00, 0x3C, 0x00,
-0xF0, 0x01, 0xC1, 0x07, 0x00, 0x17, 0x08, 0x7C, 0x10, 0xF0, 0x21, 0xC0, 0x07,
-0x00, 0x1B, 0x02, 0x7D, 0x08, 0xF0, 0x41, 0xC0, 0x87, 0x00, 0x17, 0x08, 0x5C,
-0x28, 0x70, 0x20, 0xD0, 0x07, 0x40, 0x1F, 0x08, 0x7D, 0x60, 0x70, 0x11, 0xC0,
-0x47, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC1, 0x4B, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x93, 0x00, 0x4C, 0x26, 0x30,
-0x09, 0xC0, 0x24, 0x04, 0x9F, 0x00, 0x7C, 0x16, 0xF0, 0x09, 0xC0, 0x24, 0x00,
-0x9F, 0x04, 0x7C, 0x82, 0xB0, 0x09, 0xC4, 0x26, 0x40, 0x93, 0x04, 0x4C, 0x12,
-0x34, 0x19, 0xC0, 0x24, 0x01, 0x93, 0x08, 0x0C, 0x02, 0x30, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x20, 0x22, 0x00, 0x91, 0x00, 0x44, 0x02, 0x11, 0x09,
-0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0xA9, 0x41, 0x24, 0x00, 0x9D,
-0x00, 0x34, 0x0A, 0x10, 0x69, 0x40, 0x24, 0x00, 0x91, 0x01, 0x44, 0x16, 0x10,
-0x19, 0xD0, 0x22, 0x00, 0x91, 0x02, 0x45, 0x02, 0x10, 0x09, 0x40, 0x27, 0x20,
-0x9D, 0x09, 0x6C, 0x02, 0xD0, 0x09, 0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x20, 0x44, 0x02, 0x11, 0x09, 0x40,
-0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x50, 0x25, 0x00, 0x9D, 0x00,
-0x74, 0x06, 0x90, 0x09, 0x40, 0x22, 0x02, 0x91, 0x00, 0x64, 0x02, 0x14, 0x49,
-0x48, 0x24, 0x00, 0x91, 0x02, 0x64, 0x22, 0x18, 0x19, 0x40, 0x27, 0x00, 0x8D,
-0x00, 0x65, 0x02, 0xD0, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x20, 0x24, 0x00, 0x81, 0x04, 0x24, 0x12, 0x10, 0x49, 0x40, 0x61,
-0x91, 0x8D, 0x04, 0x34, 0x02, 0xC0, 0x48, 0x40, 0x21, 0x00, 0x8D, 0x20, 0x74,
-0x02, 0x00, 0x08, 0x42, 0x20, 0x89, 0x81, 0x44, 0x26, 0x02, 0x18, 0x48, 0x40,
-0x26, 0x40, 0x81, 0x00, 0x24, 0x12, 0x14, 0x58, 0x40, 0x23, 0x00, 0x8D, 0x04,
-0x24, 0x02, 0xD0, 0x48, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1D, 0xB8, 0x86, 0x02, 0x13, 0x0A, 0x4C, 0x28, 0x34, 0xA1, 0xD0, 0x05, 0x00,
-0x1F, 0x00, 0x7C, 0x00, 0xF0, 0xA1, 0xC0, 0x85, 0x02, 0x5F, 0x00, 0x74, 0x01,
-0xB1, 0x01, 0xC8, 0x96, 0x42, 0x13, 0x0A, 0x6D, 0x00, 0x30, 0xA5, 0x40, 0x84,
-0x0A, 0x03, 0x4A, 0x6C, 0x28, 0x30, 0xA1, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0x6D,
-0x00, 0xF0, 0x01, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xB8, 0x2F, 0x10, 0xBF, 0x08, 0x5D, 0x22, 0xF0, 0x8B, 0xC0, 0x3E, 0x02, 0xBF,
-0x08, 0xF4, 0x02, 0xF0, 0x8B, 0xC0, 0x2E, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0xF2,
-0x0B, 0x00, 0x27, 0x02, 0xBF, 0x88, 0xDC, 0x82, 0xF2, 0x8B, 0xC0, 0x3F, 0x00,
-0xBF, 0x00, 0xDC, 0x22, 0xD0, 0x8B, 0xC0, 0x2B, 0x00, 0xBF, 0x08, 0x7C, 0x02,
-0xF0, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8,
-0x3B, 0x00, 0xF2, 0x14, 0xCC, 0x32, 0x34, 0x0B, 0xC0, 0x2C, 0x00, 0x93, 0x00,
-0xCC, 0x02, 0xF0, 0x4B, 0xC1, 0x24, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0x30, 0x0B,
-0xC0, 0xED, 0x00, 0xB3, 0x03, 0xCC, 0x02, 0x30, 0x3B, 0xC0, 0x2C, 0x00, 0xBF,
-0x88, 0xFC, 0x12, 0x30, 0x4A, 0xC1, 0x2C, 0x00, 0xB3, 0x00, 0x4D, 0x02, 0xF0,
-0x09, 0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05,
-0x05, 0x01, 0x04, 0x04, 0x30, 0x11, 0x21, 0x43, 0x04, 0x08, 0x11, 0x08, 0x44,
-0x00, 0xD0, 0x41, 0x50, 0x04, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40,
-0xC4, 0x08, 0x41, 0x43, 0x44, 0x01, 0x10, 0x30, 0x40, 0x00, 0x04, 0x1D, 0x00,
-0x5C, 0x51, 0x10, 0x41, 0x42, 0x04, 0x08, 0x0B, 0x12, 0x54, 0x00, 0xD0, 0x81,
-0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x25, 0x01,
-0x81, 0x94, 0x05, 0x92, 0x90, 0xCC, 0x40, 0x20, 0x02, 0x91, 0x20, 0x04, 0x02,
-0xD0, 0x48, 0x41, 0x20, 0x00, 0x81, 0x01, 0x74, 0x02, 0x10, 0x0D, 0x40, 0xA1,
-0x09, 0x81, 0x06, 0x04, 0x82, 0x10, 0x68, 0x48, 0x20, 0x00, 0x8D, 0x00, 0x34,
-0x32, 0x10, 0x48, 0x51, 0x20, 0x00, 0x89, 0x0C, 0x04, 0x02, 0xD0, 0x08, 0x40,
-0x48, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x4A, 0x91,
-0x10, 0x44, 0x02, 0x90, 0x39, 0x40, 0x24, 0x40, 0x91, 0x00, 0x44, 0x02, 0xD0,
-0x09, 0x40, 0x24, 0x00, 0x91, 0x40, 0x74, 0x12, 0x10, 0x09, 0x40, 0x24, 0x00,
-0x91, 0x00, 0x45, 0x12, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x14, 0x02,
-0x10, 0x69, 0x40, 0x24, 0x20, 0x89, 0x00, 0x54, 0x02, 0xD0, 0x09, 0x40, 0x60,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x21, 0x00, 0x93, 0x00,
-0x4C, 0x02, 0xB0, 0x29, 0xD0, 0xA4, 0x02, 0x83, 0x00, 0x4D, 0x02, 0xF0, 0x09,
-0xC9, 0x24, 0x40, 0x93, 0x03, 0x7C, 0x4E, 0x34, 0x48, 0xC0, 0x25, 0x40, 0x93,
-0x0B, 0x4C, 0x06, 0x24, 0x09, 0xD0, 0x64, 0x02, 0x9F, 0x00, 0x7C, 0x0E, 0x34,
-0x09, 0xC0, 0xA4, 0x24, 0x9B, 0x01, 0x4D, 0x02, 0xF0, 0x09, 0xD0, 0x14, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x65, 0x10, 0x9F, 0x04, 0x3C,
-0x42, 0x70, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0xF1, 0x48, 0xC0,
-0xE7, 0x00, 0x9F, 0x02, 0x7C, 0x06, 0xF1, 0x09, 0xC8, 0x23, 0x40, 0x9F, 0x01,
-0x7C, 0x06, 0xF0, 0x08, 0xC0, 0x67, 0x00, 0x9F, 0x05, 0x7C, 0x12, 0xF0, 0x19,
-0xC1, 0x27, 0x00, 0x9F, 0x04, 0x7D, 0x02, 0xF0, 0x08, 0xC0, 0x5B, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x80, 0x4C, 0x00,
-0x30, 0x00, 0xC0, 0x83, 0x40, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x04,
-0x00, 0x1F, 0x10, 0x7E, 0x08, 0xF2, 0x01, 0xD1, 0x06, 0x01, 0x03, 0x82, 0x4C,
-0x40, 0x31, 0x01, 0xC1, 0xC6, 0x00, 0x13, 0x00, 0x4C, 0x04, 0x30, 0x20, 0xC0,
-0x84, 0x00, 0x1F, 0x00, 0x4D, 0x00, 0xF0, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x04, 0x51, 0x01, 0xC5, 0x09, 0x10,
-0x05, 0xC0, 0x5D, 0x00, 0x51, 0x00, 0x74, 0x01, 0xD0, 0x17, 0x60, 0x14, 0x00,
-0x7D, 0x03, 0xB4, 0x01, 0xD0, 0x27, 0x44, 0x5C, 0x00, 0x5B, 0x11, 0xAC, 0x15,
-0xB1, 0x57, 0xC0, 0x1E, 0x40, 0x70, 0x00, 0xC4, 0x11, 0x14, 0x37, 0x40, 0x10,
-0x00, 0x5D, 0x11, 0x44, 0x01, 0xD0, 0x05, 0x50, 0x50, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x40, 0xD1, 0x00, 0x24, 0x07, 0x11, 0x0C,
-0x40, 0x31, 0x04, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x1C, 0x48, 0x34, 0x00, 0xCD,
-0x02, 0x34, 0x02, 0xD8, 0x2C, 0x60, 0x32, 0x90, 0xC9, 0x21, 0x04, 0x87, 0x58,
-0x0C, 0x42, 0x30, 0x00, 0xC0, 0x04, 0x04, 0x03, 0x10, 0x3C, 0x40, 0x20, 0x00,
-0xCD, 0x00, 0x04, 0x83, 0xD0, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x80, 0x3C, 0x20, 0xA1, 0x10, 0xA5, 0x1A, 0x10, 0x0E, 0x40,
-0x31, 0x04, 0xE1, 0x00, 0xB4, 0x0A, 0xD0, 0x04, 0x41, 0x38, 0x01, 0x6D, 0x02,
-0xB6, 0x40, 0xD8, 0x03, 0x40, 0xAA, 0x82, 0xE9, 0x00, 0xA4, 0x00, 0xD0, 0x0E,
-0x40, 0x7A, 0x00, 0xE1, 0x01, 0x84, 0x03, 0x10, 0x0F, 0x41, 0x28, 0x00, 0xED,
-0x00, 0x85, 0x03, 0xD0, 0x0E, 0x40, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x18, 0x78, 0x00, 0xE3, 0x01, 0xAC, 0x16, 0x34, 0x1E, 0xC0, 0x79,
-0x00, 0xE3, 0x01, 0xBC, 0x06, 0xD0, 0x16, 0x40, 0xF8, 0x01, 0x2D, 0x01, 0xB4,
-0x05, 0xF0, 0x16, 0xD0, 0x72, 0x00, 0xAB, 0x01, 0x8C, 0x04, 0x74, 0x9E, 0xC0,
-0x78, 0x00, 0xF3, 0x81, 0xCC, 0x07, 0x34, 0x1E, 0xC0, 0x68, 0x00, 0xAF, 0x01,
-0x84, 0x07, 0xF0, 0x1C, 0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xB8, 0x35, 0x40, 0x9F, 0x14, 0x5C, 0x22, 0xF0, 0x0D, 0xC0, 0x35, 0x00,
-0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xD0, 0x77, 0x00, 0x5F, 0x00, 0x6C, 0x00,
-0xF0, 0x00, 0xD0, 0x25, 0x20, 0x9F, 0x02, 0x3C, 0x00, 0xB1, 0x09, 0xD0, 0x37,
-0x00, 0xDF, 0x00, 0x7D, 0x03, 0xE0, 0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7D,
-0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-0x20, 0x7D, 0x00, 0xFF, 0x21, 0x8C, 0x06, 0x38, 0x8F, 0xC0, 0x6D, 0x00, 0xF3,
-0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xD0, 0x7C, 0x00, 0x3F, 0x01, 0xFC, 0x06, 0xF0,
-0x13, 0xC0, 0x5F, 0x20, 0xF7, 0x23, 0xCC, 0x04, 0x31, 0x9F, 0xC0, 0x7C, 0x08,
-0xF3, 0x01, 0x8C, 0x07, 0x31, 0x0B, 0xC0, 0x6F, 0x00, 0xEF, 0x03, 0xCC, 0x07,
-0xF2, 0x1F, 0xC2, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00,
-0x39, 0x00, 0xED, 0x00, 0x84, 0x02, 0x38, 0x0F, 0x40, 0x08, 0x40, 0xE1, 0x00,
-0xBC, 0x02, 0xD0, 0x26, 0x40, 0x38, 0x02, 0x6D, 0x10, 0xB4, 0xA0, 0xD0, 0x82,
-0x40, 0x0F, 0x10, 0xE1, 0x04, 0x94, 0x10, 0x10, 0xE6, 0x41, 0x3C, 0x00, 0xF1,
-0x10, 0x84, 0x83, 0x14, 0x8A, 0x40, 0x2B, 0x04, 0xED, 0x08, 0x84, 0x03, 0xD0,
-0x0E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
-0x00, 0xED, 0x00, 0x84, 0x02, 0x90, 0x8E, 0x40, 0x29, 0x00, 0xE1, 0x00, 0xB4,
-0x42, 0xD0, 0x06, 0x40, 0x38, 0x04, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40,
-0x2B, 0x02, 0xED, 0x80, 0xC4, 0x00, 0x10, 0x04, 0x40, 0x38, 0x04, 0x61, 0x00,
-0xF4, 0x03, 0x10, 0x8A, 0x41, 0x2B, 0x02, 0xAD, 0x00, 0x84, 0x03, 0xD0, 0x2C,
-0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x31, 0x00,
-0xCD, 0x00, 0x44, 0x02, 0x10, 0x1C, 0x40, 0x00, 0x04, 0xC1, 0x49, 0x34, 0x02,
-0xD0, 0x25, 0x40, 0x70, 0x00, 0x4D, 0x01, 0x34, 0x00, 0xD2, 0x10, 0x40, 0x23,
-0x00, 0xC9, 0x0A, 0x14, 0xC8, 0x14, 0x04, 0x50, 0xF0, 0x00, 0x41, 0x00, 0x34,
-0x0B, 0x10, 0x18, 0x40, 0x23, 0x00, 0x9D, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40,
-0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x35, 0x00, 0xDF,
-0x07, 0xCC, 0x02, 0xB0, 0x4D, 0xC0, 0xE5, 0x00, 0xD3, 0x00, 0x3C, 0x02, 0xF0,
-0x05, 0xD0, 0x3C, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF0, 0x21, 0xC1, 0x3F, 0x00,
-0xDF, 0x23, 0x0D, 0x08, 0x30, 0x11, 0xC0, 0xF4, 0x08, 0xD3, 0x00, 0x7C, 0x23,
-0x30, 0x0D, 0xC0, 0xB7, 0x00, 0x9F, 0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x74,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x37, 0x10, 0x9F, 0x00,
-0x7E, 0x02, 0x70, 0x0D, 0xC2, 0x63, 0x10, 0xDF, 0x00, 0x5C, 0x02, 0xF0, 0xC5,
-0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x10, 0xF0, 0x41, 0xC0, 0x37, 0x00, 0xD7,
-0x10, 0x7C, 0x0C, 0xF0, 0x00, 0xC0, 0x37, 0x04, 0xDF, 0x00, 0x44, 0x0B, 0xF0,
-0x0C, 0xC1, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC2, 0x07, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xEF, 0x10, 0xCC,
-0x06, 0x30, 0x0F, 0xC0, 0x04, 0x00, 0xF3, 0x00, 0xFE, 0x52, 0x30, 0x05, 0xC0,
-0x3C, 0x00, 0x37, 0x10, 0xFC, 0x80, 0xF0, 0x03, 0xC0, 0x7B, 0x00, 0x93, 0x00,
-0xCC, 0x00, 0xB0, 0x03, 0x40, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x83, 0x32, 0x8F,
-0xC2, 0xBC, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0xF0, 0x0E, 0xC0, 0x04, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0x9D, 0x20, 0x44, 0x0A,
-0x10, 0x0C, 0x50, 0xC4, 0x00, 0xD1, 0x00, 0x74, 0x06, 0x50, 0x15, 0x50, 0x35,
-0x00, 0x5D, 0x07, 0x74, 0x0C, 0xD0, 0x11, 0xC0, 0x35, 0x02, 0x81, 0x00, 0x44,
-0x4C, 0x11, 0x31, 0xC0, 0x36, 0x00, 0xD1, 0x02, 0x44, 0x43, 0x10, 0x21, 0x42,
-0x24, 0x00, 0x9D, 0x09, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x04, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x66, 0x00, 0xDD, 0x00, 0x44, 0x28, 0x10,
-0x19, 0x40, 0xE6, 0x00, 0xD1, 0x00, 0x74, 0x02, 0xD0, 0x11, 0x40, 0x36, 0x00,
-0x1D, 0x01, 0x74, 0x44, 0xD0, 0x31, 0x40, 0x17, 0x40, 0xD1, 0x00, 0x44, 0x84,
-0x10, 0x11, 0x02, 0xD3, 0x00, 0xC1, 0x11, 0x06, 0x04, 0x10, 0x29, 0x40, 0x36,
-0x00, 0xDD, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x06, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD, 0x00, 0x05, 0x00, 0x10, 0x09,
-0x40, 0x02, 0x40, 0xC1, 0x00, 0x34, 0x82, 0x50, 0x00, 0x40, 0x33, 0x08, 0x4D,
-0x40, 0x36, 0x00, 0xD0, 0x00, 0x40, 0x11, 0x80, 0xD1, 0x00, 0x44, 0x00, 0x10,
-0x00, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x06, 0x02, 0x10, 0x08, 0x50, 0x22, 0x00,
-0xCD, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x98, 0x26, 0x00, 0xEF, 0x00, 0x4C, 0x00, 0x34, 0x09, 0xC0,
-0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0x70, 0x05, 0xC0, 0x36, 0x00, 0x17, 0x00,
-0x74, 0x00, 0xF2, 0x01, 0xC2, 0x27, 0x20, 0xF3, 0x20, 0x4C, 0x00, 0xB0, 0x03,
-0xD0, 0x07, 0x00, 0x93, 0x00, 0x4C, 0x01, 0x30, 0x09, 0xC0, 0x36, 0x00, 0xBF,
-0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x06, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC0, 0x0D,
-0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x07, 0xC0, 0x3D, 0x00, 0x7F, 0x00, 0xFC,
-0x00, 0xD0, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xBD, 0x00, 0xF4, 0x03, 0xC2,
-0x3E, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2D, 0x00, 0xBF, 0x00,
-0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x15, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x27, 0x30, 0x1F, 0xC8, 0x7F, 0x0A,
-0xFF, 0x01, 0xCC, 0x27, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xF3, 0x09, 0xFC, 0x27,
-0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xCC, 0x27, 0x30, 0x9F, 0xC0, 0x78,
-0x00, 0xFF, 0x09, 0xCC, 0x07, 0xB0, 0x13, 0xC0, 0x7E, 0x00, 0xEF, 0x01, 0xFC,
-0x07, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x08, 0x77, 0x00, 0xDD, 0x01, 0x74, 0x00, 0x10, 0x11, 0x40, 0x07, 0x01, 0x1D,
-0x01, 0x44, 0x00, 0x90, 0x11, 0x40, 0x04, 0x01, 0x11, 0x00, 0x74, 0x10, 0xD0,
-0x01, 0x40, 0x47, 0x00, 0x11, 0x01, 0x44, 0x00, 0x10, 0x01, 0x48, 0x44, 0x00,
-0x1D, 0x00, 0x44, 0x87, 0x51, 0x11, 0x40, 0x74, 0x00, 0x9D, 0x01, 0x74, 0x13,
-0x10, 0x1D, 0x40, 0x0F, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0,
-0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00,
-0x04, 0x03, 0xD0, 0x0D, 0x48, 0x34, 0x14, 0xC1, 0x20, 0x34, 0x03, 0xD0, 0x4C,
-0x40, 0x37, 0x00, 0xD9, 0x00, 0x64, 0x03, 0x10, 0x0D, 0x40, 0x31, 0x00, 0xCD,
-0x04, 0x24, 0x03, 0x10, 0x01, 0x48, 0x32, 0x80, 0x8D, 0x00, 0x34, 0x43, 0x19,
-0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35,
-0x00, 0xDD, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44,
-0x00, 0x90, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x74, 0x80, 0xD0, 0x01, 0x40,
-0x07, 0x00, 0x19, 0x00, 0x64, 0x00, 0x11, 0x01, 0x42, 0x05, 0x08, 0x1D, 0x20,
-0x64, 0x07, 0x50, 0x11, 0x41, 0x34, 0x80, 0x1D, 0x01, 0x34, 0x03, 0x18, 0x0D,
-0x42, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x18, 0xCF, 0x00, 0x4C, 0x03,
-0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33,
-0x00, 0xCB, 0x00, 0x6C, 0x03, 0x30, 0x0C, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x6D,
-0x07, 0x30, 0x10, 0xC2, 0x36, 0x00, 0x9F, 0x13, 0x7C, 0x03, 0x30, 0x0D, 0xC2,
-0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF,
-0x00, 0xFC, 0x40, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0,
-0x03, 0xD2, 0x0F, 0x00, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x03, 0xC2, 0x0F, 0x00,
-0x37, 0x00, 0xDC, 0x00, 0xF6, 0x03, 0xC0, 0x0E, 0x20, 0x3F, 0x00, 0xDC, 0x03,
-0xF0, 0x07, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x1F,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00,
-0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x36, 0x00, 0xDF, 0x01, 0x4C, 0x23, 0xF0, 0x0D,
-0xC2, 0x34, 0x04, 0xDF, 0x01, 0x4C, 0x43, 0xF0, 0x0D, 0xE0, 0x37, 0x00, 0xDB,
-0x01, 0x4C, 0x13, 0xF0, 0x8D, 0x80, 0x34, 0x02, 0xD3, 0x18, 0x4C, 0x0E, 0xF0,
-0x01, 0xC0, 0x37, 0x00, 0x93, 0x02, 0x4C, 0x43, 0xF0, 0x0D, 0xC0, 0x2B, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74,
-0x00, 0x11, 0x01, 0x40, 0x84, 0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x10, 0x40,
-0x80, 0x00, 0x1D, 0x80, 0x44, 0x9C, 0xD0, 0x51, 0x40, 0xC7, 0x0A, 0x1D, 0x00,
-0x04, 0x48, 0xD0, 0x21, 0x40, 0x44, 0x20, 0x11, 0xA0, 0x2C, 0x02, 0xD0, 0xA5,
-0x40, 0x77, 0x04, 0x91, 0x00, 0x68, 0x07, 0xD0, 0x0D, 0x40, 0x4F, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x74, 0x0F,
-0x10, 0x1C, 0x40, 0x32, 0x02, 0xCD, 0x00, 0x04, 0x43, 0xD0, 0x8C, 0x40, 0xF0,
-0x08, 0xCD, 0x00, 0x04, 0x03, 0xD0, 0x4C, 0x40, 0x73, 0x02, 0xCD, 0x00, 0x04,
-0x0F, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xD1, 0x00, 0x24, 0x03, 0xD0, 0x04, 0x48,
-0x73, 0x00, 0x88, 0x00, 0x04, 0x27, 0xD0, 0x0C, 0x40, 0x0F, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0xED, 0x01, 0xF4, 0x64, 0x10,
-0x12, 0x40, 0xC8, 0x00, 0x3D, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x50, 0x48, 0x04,
-0x2D, 0x03, 0x84, 0x04, 0xD0, 0x12, 0x40, 0x4B, 0x02, 0x3D, 0x01, 0x84, 0x04,
-0xD0, 0x33, 0x40, 0x4C, 0x00, 0x31, 0x01, 0xA4, 0x07, 0xD0, 0x16, 0x40, 0x3B,
-0x00, 0xB9, 0x01, 0xA4, 0x07, 0xD0, 0x1E, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0x0C,
-0xC0, 0x32, 0x00, 0xCF, 0x00, 0x0C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x02, 0xDF,
-0x00, 0x0C, 0x03, 0xF0, 0x0C, 0x40, 0x33, 0x00, 0xCF, 0x04, 0x0C, 0x23, 0xF2,
-0x0D, 0x40, 0x30, 0x00, 0xC3, 0x00, 0x2C, 0x0B, 0xF0, 0x00, 0xC0, 0x33, 0x02,
-0x8B, 0x80, 0x0C, 0x23, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0xF0, 0x82, 0x80,
-0x0F, 0x02, 0x2F, 0x00, 0xFC, 0x00, 0xF1, 0x02, 0xC0, 0x0F, 0x08, 0x3F, 0x00,
-0x7C, 0x00, 0xF0, 0x83, 0xC0, 0x0F, 0x08, 0x2F, 0x00, 0x7C, 0x00, 0xF0, 0x03,
-0xD0, 0x0F, 0x00, 0x2F, 0x09, 0xFC, 0x03, 0xF0, 0x83, 0xC4, 0x3B, 0x01, 0xB7,
-0x00, 0xFC, 0x23, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0x34, 0x0D, 0xC0, 0x77,
-0x40, 0xD3, 0x00, 0x7C, 0x07, 0x34, 0x0D, 0xC0, 0x37, 0x08, 0xDF, 0x00, 0x7C,
-0x07, 0x30, 0x1D, 0xD0, 0x70, 0x00, 0xC3, 0x01, 0x4C, 0x03, 0xF0, 0x0D, 0xC0,
-0x37, 0x20, 0xDF, 0x40, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x34, 0x00, 0x9F, 0x00,
-0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xF4, 0x00, 0x10, 0x02, 0x48, 0x0F, 0x00,
-0x21, 0x00, 0xF4, 0x00, 0x10, 0x02, 0x40, 0x0B, 0x00, 0x2D, 0x00, 0xF4, 0x00,
-0x13, 0x03, 0x40, 0x08, 0x00, 0x25, 0x00, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x0B,
-0x00, 0x2D, 0x00, 0xB4, 0x01, 0xD0, 0x06, 0x40, 0x38, 0x00, 0xA9, 0x00, 0xB4,
-0x03, 0xD0, 0x0E, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x00, 0x79, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xE1,
-0x01, 0xB4, 0x07, 0x10, 0x1E, 0x00, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x54,
-0x1E, 0x40, 0x78, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00,
-0xED, 0x01, 0xB4, 0x07, 0xD0, 0x12, 0x40, 0x78, 0x80, 0xAD, 0x11, 0xB4, 0x07,
-0xD0, 0x1E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28,
-0x33, 0x00, 0xCD, 0x00, 0x34, 0x80, 0x50, 0x00, 0x40, 0x03, 0x00, 0x01, 0x00,
-0x34, 0x00, 0x10, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00,
-0x40, 0x00, 0x00, 0x05, 0x00, 0x16, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D,
-0x00, 0x34, 0x07, 0xD0, 0x6C, 0x40, 0x30, 0x80, 0x89, 0x01, 0x34, 0x03, 0xD0,
-0x0C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15,
-0x00, 0x5F, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x7C,
-0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0,
-0x14, 0x00, 0x51, 0x00, 0x4D, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00,
-0xBC, 0x95, 0xF0, 0x27, 0xD0, 0x14, 0x00, 0x6F, 0x02, 0x7C, 0x01, 0xD0, 0x05,
-0xC0, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00,
-0x1F, 0x00, 0xFC, 0x00, 0x90, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00,
-0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0x90, 0x03, 0xC0, 0x0F,
-0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0x7C,
-0x40, 0xE0, 0x21, 0xC0, 0x07, 0x08, 0x1F, 0x10, 0x74, 0x00, 0xF0, 0x01, 0xC0,
-0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F,
-0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x27, 0x01,
-0x9F, 0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06,
-0x70, 0x49, 0xC0, 0xE5, 0x00, 0x9F, 0x00, 0x4C, 0x16, 0xF0, 0x09, 0xC0, 0x43,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00,
-0x74, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x04, 0x9D, 0x00, 0x74, 0x2E, 0xD0, 0x09,
-0x46, 0xA7, 0x00, 0x9D, 0x03, 0x74, 0x2A, 0xD0, 0x29, 0x40, 0x67, 0x80, 0x9D,
-0x00, 0x74, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x43, 0x74, 0xA2, 0x30,
-0x38, 0x40, 0x24, 0x01, 0x9D, 0x80, 0x6C, 0x0E, 0xD1, 0x09, 0x40, 0x07, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74,
-0x12, 0xD0, 0x4B, 0x40, 0x6F, 0x00, 0xBD, 0x01, 0xF4, 0x02, 0xD0, 0x1B, 0x40,
-0x6F, 0x00, 0xBD, 0x08, 0xF4, 0x02, 0xD0, 0x8B, 0x40, 0x2F, 0x18, 0xBD, 0x01,
-0xF4, 0x02, 0xD0, 0x1B, 0x41, 0x6F, 0x00, 0xBD, 0x04, 0x64, 0x02, 0x58, 0x09,
-0x40, 0x25, 0x08, 0x9D, 0x00, 0x44, 0x0A, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x00, 0xB4, 0x06,
-0xD0, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4, 0x06, 0xD2, 0x0A, 0x40, 0x6B,
-0x00, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x1A, 0x48, 0x6B, 0x20, 0xAD, 0xC0, 0xB4,
-0x06, 0xD0, 0x0A, 0x48, 0x2B, 0x00, 0xAD, 0x01, 0x74, 0x02, 0x10, 0x09, 0x40,
-0x20, 0x00, 0x9D, 0x00, 0x25, 0x22, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x7C, 0x28, 0xF0,
-0x01, 0xC2, 0x87, 0x02, 0x1F, 0x00, 0x7C, 0x28, 0xF0, 0x01, 0xC0, 0x87, 0x22,
-0x1F, 0x2A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x07, 0x00, 0x1D, 0x00, 0x7C, 0x28,
-0xF0, 0xA1, 0x40, 0x07, 0x00, 0x3F, 0x0A, 0x6C, 0x00, 0x72, 0x05, 0xC0, 0x05,
-0x00, 0x1F, 0x00, 0x4C, 0x08, 0xF0, 0x01, 0xC8, 0x77, 0xE0, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF1, 0x09,
-0xCA, 0x27, 0x08, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
-0x00, 0x74, 0x82, 0xF1, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0xF8, 0x02, 0x72, 0x0B, 0xC0, 0x27, 0x00,
-0xBF, 0x00, 0x7C, 0x12, 0xF8, 0x09, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0x22, 0xF0, 0x0B, 0xC6,
-0xAC, 0x18, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x0B, 0xC0, 0xAF, 0x20, 0xBF, 0x02,
-0xCC, 0x0A, 0xF0, 0x0B, 0xC0, 0x2C, 0x00, 0xB7, 0x00, 0xFC, 0x0A, 0x30, 0x2B,
-0xC0, 0x2C, 0x20, 0xBF, 0x48, 0xBC, 0x02, 0x30, 0x0F, 0xC0, 0x2F, 0x20, 0x9F,
-0x00, 0xF4, 0x02, 0x30, 0x09, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x14, 0xD0, 0x01, 0x40, 0x44,
-0x00, 0x1D, 0x00, 0x74, 0x14, 0xD0, 0x01, 0x48, 0x47, 0x01, 0x1D, 0x81, 0x44,
-0x94, 0x90, 0x11, 0x52, 0x04, 0x00, 0x11, 0x00, 0x74, 0x04, 0x10, 0x51, 0x40,
-0x04, 0x00, 0x1D, 0x05, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00,
-0x64, 0x00, 0x14, 0x01, 0x40, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x50, 0x21, 0x01,
-0x8D, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x40, 0x23, 0x01, 0xC5, 0x04, 0x15, 0x03,
-0xD0, 0x4D, 0x41, 0x20, 0x00, 0x81, 0x00, 0x34, 0x13, 0x10, 0x08, 0x14, 0x32,
-0x20, 0x8D, 0x00, 0x76, 0x82, 0x50, 0x08, 0x48, 0x23, 0x10, 0x8D, 0x00, 0x34,
-0x02, 0x10, 0x08, 0x40, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x9D,
-0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0,
-0x0D, 0x40, 0x24, 0x00, 0x91, 0xC0, 0x74, 0x02, 0x12, 0x09, 0x00, 0x24, 0x00,
-0x9D, 0x00, 0x74, 0x12, 0x54, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x24, 0x02,
-0x10, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x5C, 0x02, 0xF0, 0x09,
-0xC0, 0x24, 0x40, 0x95, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x26, 0x00, 0x9F,
-0x00, 0x7C, 0x4E, 0x70, 0x69, 0xC0, 0x27, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0x10,
-0x09, 0x40, 0x17, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x04, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02, 0xB0, 0x09, 0xC0,
-0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x25, 0x20, 0x9F, 0x00,
-0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x04, 0x9F, 0x04, 0x6C, 0x02, 0xF0, 0x09,
-0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00,
-0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7E, 0x00,
-0x34, 0x01, 0xC0, 0x07, 0x40, 0x1B, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x47,
-0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x41, 0xC2, 0x04, 0x00, 0x13, 0x00, 0x7C,
-0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x10, 0xF0, 0x01, 0xC0,
-0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x5D,
-0x00, 0xF4, 0x01, 0xD0, 0x04, 0x40, 0x9F, 0x04, 0x5D, 0x01, 0xF4, 0x21, 0x10,
-0x05, 0x00, 0xDF, 0x02, 0x71, 0x88, 0xF0, 0x01, 0xD0, 0x86, 0xC0, 0x19, 0x01,
-0x5D, 0x11, 0xF4, 0x09, 0x10, 0x37, 0x48, 0x14, 0x20, 0x7B, 0x91, 0x74, 0x01,
-0x10, 0xB7, 0x40, 0x1F, 0x00, 0x5D, 0x00, 0xF4, 0x45, 0xD0, 0x05, 0x40, 0x43,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00,
-0x34, 0x43, 0xD0, 0x08, 0x40, 0xF3, 0x00, 0x8D, 0x08, 0x34, 0x03, 0x10, 0x08,
-0x40, 0xF3, 0x20, 0xD0, 0x02, 0x34, 0x13, 0xD0, 0x2C, 0x40, 0x53, 0x00, 0x8D,
-0x40, 0x76, 0x43, 0x14, 0x3D, 0x40, 0x20, 0x00, 0xC1, 0x04, 0x74, 0x02, 0x50,
-0x30, 0x48, 0x43, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x43, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0xB4,
-0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x07, 0x10, 0x0E, 0x40,
-0x7B, 0x14, 0xE1, 0x40, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x39, 0x00, 0xED, 0x00,
-0xB4, 0x03, 0x12, 0x2E, 0x50, 0x78, 0x00, 0xE9, 0x00, 0xF4, 0xC2, 0x00, 0x02,
-0x41, 0x0B, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x13, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x07,
-0xF0, 0x1E, 0xC2, 0x5B, 0x00, 0xEF, 0x01, 0xF4, 0x07, 0x30, 0x1E, 0xC8, 0x7F,
-0x10, 0xE3, 0x01, 0xBC, 0x07, 0xD0, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xFC,
-0x07, 0x30, 0x17, 0xC8, 0x78, 0x08, 0xE3, 0x21, 0xBC, 0x07, 0x70, 0x16, 0xC0,
-0x4B, 0x00, 0xEF, 0x21, 0xBC, 0x05, 0xF0, 0x1E, 0xC0, 0x53, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC0, 0x17, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x40, 0x17, 0x00,
-0xD7, 0x20, 0x7C, 0x01, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01,
-0xF3, 0x05, 0xC0, 0x32, 0x10, 0x5F, 0x00, 0x7C, 0x03, 0xE0, 0x05, 0xC0, 0x07,
-0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF1, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x05, 0xF0, 0x1F,
-0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xFF,
-0x21, 0xBC, 0x85, 0x30, 0x1F, 0xC0, 0x78, 0x02, 0xF3, 0x01, 0xFC, 0x05, 0xF0,
-0x5F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0xFC, 0x16, 0xF0, 0x17, 0xC4, 0x6D, 0x00,
-0xFF, 0x09, 0xF4, 0x27, 0x30, 0x9F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0x80, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x09, 0xD0, 0x0E, 0x40,
-0x3B, 0x00, 0xE1, 0x28, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x08,
-0xB4, 0x03, 0x12, 0x0F, 0x40, 0x38, 0x06, 0xE1, 0x18, 0xB4, 0x43, 0xD0, 0x06,
-0x41, 0x3B, 0x00, 0xED, 0x0A, 0xB4, 0x03, 0xD0, 0x07, 0x40, 0x28, 0x00, 0xED,
-0x08, 0xF4, 0x0B, 0x14, 0x0E, 0x40, 0x57, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x8E, 0x40, 0x1F,
-0x00, 0xE1, 0x00, 0xB4, 0x09, 0xD0, 0x8F, 0x40, 0x39, 0x02, 0x6D, 0x02, 0xF4,
-0x09, 0x10, 0x26, 0x40, 0xBC, 0x08, 0xE1, 0x00, 0xB4, 0x01, 0xD0, 0x4E, 0x40,
-0x3B, 0x02, 0xED, 0x80, 0xB4, 0x93, 0xD0, 0x07, 0x40, 0x19, 0x00, 0xED, 0x40,
-0xB4, 0x01, 0x12, 0x0E, 0x40, 0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x08, 0xD0, 0x0C, 0x41, 0x07, 0x01,
-0xC1, 0x01, 0x34, 0x82, 0xD0, 0x2C, 0x4D, 0x65, 0x02, 0x8D, 0x88, 0x74, 0x24,
-0x10, 0x08, 0x40, 0x30, 0x00, 0xC1, 0x02, 0x34, 0x0C, 0xD0, 0x00, 0x40, 0x73,
-0x04, 0x9D, 0x0F, 0x34, 0x02, 0xD0, 0x24, 0x40, 0x00, 0x20, 0xCD, 0x09, 0x74,
-0x00, 0x10, 0x0C, 0x60, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x36, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0xC3,
-0x12, 0x3C, 0x14, 0xF0, 0x2D, 0xC0, 0x85, 0x00, 0x0F, 0x00, 0x7C, 0x02, 0x30,
-0x51, 0x40, 0x74, 0x80, 0xD3, 0x09, 0x74, 0x26, 0xF0, 0x19, 0xC0, 0x33, 0x04,
-0x1E, 0x00, 0x7C, 0x02, 0xF0, 0x14, 0xC0, 0x05, 0x00, 0xDF, 0x01, 0x7C, 0x02,
-0x30, 0x0D, 0xC8, 0x77, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC8, 0xC7, 0x20, 0xDF, 0x04,
-0x7C, 0x00, 0xF0, 0x1D, 0x00, 0x26, 0x01, 0x1D, 0x80, 0x7C, 0x0A, 0xF0, 0x01,
-0xD0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x09, 0x41, 0x37, 0x20, 0x9F,
-0x00, 0x78, 0x02, 0xC0, 0x15, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0,
-0x0D, 0xC0, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F,
-0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x2C, 0x00, 0xF3, 0x05, 0xEC,
-0x00, 0xB0, 0x5F, 0xC0, 0x0F, 0x00, 0x33, 0x20, 0xCC, 0x02, 0x30, 0x03, 0xC0,
-0x3F, 0x00, 0xFF, 0x04, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x3F, 0x20, 0x33, 0x20,
-0xCC, 0x17, 0xF0, 0x17, 0xD1, 0x0C, 0x00, 0xFF, 0x10, 0xFC, 0x00, 0x10, 0x0F,
-0xC2, 0x27, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00,
-0xDD, 0x00, 0x74, 0x06, 0xD1, 0x0C, 0x40, 0x44, 0x08, 0xD1, 0x01, 0x44, 0x04,
-0x10, 0x1D, 0x40, 0x47, 0x01, 0x11, 0x01, 0x44, 0x06, 0x10, 0x31, 0x40, 0xF7,
-0x04, 0xDD, 0x01, 0x74, 0x1E, 0xD0, 0x51, 0x40, 0x37, 0x20, 0x11, 0x03, 0x44,
-0x03, 0xD0, 0xC5, 0x40, 0x44, 0x01, 0xDD, 0x00, 0x74, 0x2C, 0x10, 0x0D, 0x46,
-0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD,
-0x00, 0x74, 0x06, 0xD0, 0x1D, 0x40, 0x64, 0x04, 0xD1, 0x00, 0x64, 0x0E, 0x10,
-0x0D, 0x40, 0x47, 0x80, 0x91, 0x03, 0x44, 0x0C, 0x10, 0x19, 0x42, 0x77, 0x00,
-0xDD, 0x00, 0x74, 0x04, 0xD0, 0x19, 0x40, 0x37, 0x09, 0x11, 0x01, 0x44, 0x02,
-0xD0, 0x05, 0x40, 0x44, 0x00, 0xDD, 0x00, 0x74, 0x82, 0x40, 0x0D, 0x40, 0x07,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x00, 0xCD, 0x00,
-0x34, 0x02, 0xD0, 0x0D, 0x40, 0x20, 0x40, 0xC1, 0x00, 0x44, 0x02, 0x10, 0x0C,
-0x40, 0x23, 0x60, 0x91, 0x00, 0x04, 0x02, 0x16, 0x08, 0x40, 0x33, 0x20, 0xCD,
-0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x37, 0x08, 0x81, 0x20, 0x05, 0x02, 0xD0,
-0x04, 0x40, 0x00, 0x00, 0xCD, 0x00, 0x34, 0x00, 0x50, 0x0C, 0x40, 0x43, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x36, 0x00, 0xDF, 0x00, 0x7C,
-0x00, 0xF0, 0x0D, 0xC2, 0x24, 0x00, 0xD3, 0x00, 0x6C, 0x00, 0x30, 0x0D, 0xC0,
-0x07, 0x00, 0x13, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x37, 0x00, 0xDF, 0x00,
-0x7C, 0x00, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x13, 0x40, 0x4C, 0x03, 0xF0, 0x05,
-0xC0, 0x04, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x74, 0x0D, 0xC0, 0x07, 0x40, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02,
-0xF0, 0x0F, 0xC8, 0x2B, 0x08, 0xFF, 0x20, 0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x2F,
-0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC2, 0x2F, 0x00, 0xFF, 0x00, 0xFC,
-0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xB0, 0x0F, 0xC0, 0x17, 0x22, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x4F, 0x00, 0x33, 0x01, 0xCC, 0x24, 0x30,
-0x13, 0xC0, 0x2C, 0x02, 0xF3, 0x00, 0x8C, 0x07, 0x30, 0xCF, 0xC0, 0x2C, 0x40,
-0x33, 0x08, 0xCC, 0x23, 0x72, 0xC7, 0xC0, 0xCE, 0x00, 0x33, 0x04, 0xDC, 0x00,
-0x30, 0x13, 0xC0, 0xCF, 0x00, 0x3F, 0x01, 0xED, 0x04, 0x30, 0x13, 0xC0, 0x4C,
-0x00, 0x33, 0x01, 0xCC, 0x04, 0x30, 0x13, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x21, 0x11, 0x00, 0x44, 0x00, 0x10, 0x04,
-0x40, 0x24, 0x09, 0xF1, 0x00, 0x44, 0x03, 0x30, 0x21, 0x40, 0xB0, 0x05, 0x01,
-0x26, 0x05, 0x3B, 0x30, 0xE1, 0x40, 0x05, 0x21, 0x51, 0x0B, 0x44, 0x18, 0x15,
-0x41, 0xC0, 0x23, 0x00, 0x1D, 0x00, 0x44, 0x82, 0x10, 0x01, 0x42, 0x44, 0x00,
-0x11, 0x80, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x11, 0xA0, 0x03, 0x04, 0x11, 0x01, 0x04, 0x12, 0x10, 0x00, 0x40,
-0x00, 0x00, 0xC1, 0x00, 0x64, 0x53, 0x90, 0x3C, 0x48, 0x24, 0x02, 0x01, 0x06,
-0x25, 0x83, 0xD0, 0x05, 0x40, 0x00, 0x00, 0x09, 0x00, 0x34, 0x48, 0x90, 0x00,
-0x41, 0x03, 0x01, 0x89, 0x00, 0x44, 0x00, 0x90, 0x01, 0x40, 0x46, 0x00, 0x89,
-0x00, 0x24, 0x02, 0x10, 0x08, 0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0xA8, 0x05, 0x00, 0x11, 0x40, 0x04, 0x02, 0x10, 0x05, 0x40, 0x04,
-0x12, 0xC1, 0x00, 0x64, 0x03, 0x14, 0x09, 0x40, 0x34, 0x02, 0x11, 0x01, 0x64,
-0x07, 0x10, 0x01, 0x40, 0x45, 0x04, 0x59, 0x20, 0x64, 0x44, 0x92, 0x11, 0x42,
-0x27, 0x00, 0x8C, 0x00, 0x44, 0x02, 0x98, 0x11, 0x00, 0x06, 0x00, 0x89, 0x00,
-0x24, 0x02, 0x10, 0x08, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA0, 0x37, 0x40, 0x43, 0x00, 0x4C, 0x04, 0x30, 0x21, 0xC1, 0x64, 0x00,
-0xD3, 0x00, 0x2D, 0x03, 0xB0, 0x0D, 0xC4, 0xC0, 0x40, 0x13, 0x00, 0x6C, 0x07,
-0xF2, 0x0D, 0xC0, 0x84, 0x40, 0x5B, 0x81, 0x7C, 0x0C, 0xB1, 0x51, 0xE0, 0x07,
-0x00, 0x1F, 0x00, 0x4C, 0x01, 0xB0, 0x08, 0xC0, 0x12, 0x18, 0x1B, 0x01, 0x6C,
-0x04, 0x30, 0x11, 0xC0, 0x09, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
-0x88, 0x3D, 0x20, 0x7F, 0x00, 0xFC, 0x24, 0xF0, 0x07, 0xC0, 0x73, 0x00, 0xFF,
-0x00, 0xDC, 0x02, 0xF0, 0x26, 0xC0, 0x0F, 0x30, 0x3F, 0x20, 0x9C, 0x03, 0xF0,
-0x05, 0xC0, 0x0D, 0x00, 0x77, 0x03, 0xDC, 0x00, 0x72, 0x03, 0xC0, 0x2D, 0x02,
-0x3F, 0x08, 0xDC, 0x03, 0x74, 0x0B, 0xC0, 0x1D, 0x18, 0x36, 0x49, 0xDC, 0x24,
-0xF0, 0x93, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
-0x75, 0x00, 0x53, 0x10, 0x4C, 0x06, 0x32, 0x01, 0xCA, 0x24, 0x00, 0xD3, 0x00,
-0x4D, 0x03, 0x30, 0x0D, 0xC0, 0x24, 0x00, 0x13, 0x02, 0x6C, 0x02, 0x30, 0x0D,
-0xC1, 0x86, 0x00, 0x4F, 0x50, 0xCC, 0x18, 0x30, 0x01, 0xC8, 0x07, 0x40, 0x93,
-0x05, 0x7C, 0x01, 0xF0, 0x09, 0xC0, 0x14, 0x04, 0x93, 0x11, 0x4C, 0x46, 0x30,
-0x59, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x74,
-0x00, 0x51, 0x80, 0x44, 0x06, 0x12, 0x05, 0x40, 0x34, 0x09, 0xF1, 0x00, 0x44,
-0x0B, 0x10, 0xBD, 0x40, 0xA4, 0x02, 0x35, 0x00, 0x44, 0x00, 0x10, 0x7C, 0x40,
-0x04, 0x06, 0x5D, 0x11, 0x2C, 0x08, 0x10, 0x11, 0x00, 0x67, 0x08, 0x9B, 0x23,
-0x34, 0x2B, 0xD0, 0xA9, 0x40, 0x94, 0x04, 0x91, 0x03, 0x44, 0x0E, 0x10, 0x39,
-0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x04, 0x00,
-0x89, 0x00, 0x04, 0x01, 0x10, 0x09, 0x40, 0x60, 0x00, 0xC1, 0x01, 0x04, 0x4B,
-0x14, 0x3C, 0x40, 0xA0, 0x00, 0x11, 0x00, 0x24, 0x03, 0x18, 0x24, 0x40, 0x06,
-0x08, 0x8D, 0x02, 0x14, 0x00, 0x11, 0x10, 0x48, 0x53, 0x02, 0x45, 0x00, 0x34,
-0x00, 0xD0, 0x04, 0x40, 0x61, 0x00, 0x41, 0x02, 0x04, 0x09, 0x10, 0x04, 0x02,
-0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00, 0xB9,
-0x09, 0x84, 0x0D, 0x10, 0x1E, 0x42, 0xF8, 0x00, 0xE1, 0x01, 0xC4, 0x87, 0x14,
-0x1C, 0x41, 0x68, 0x02, 0xA5, 0x01, 0x84, 0x07, 0x10, 0x92, 0x50, 0x48, 0x20,
-0xAD, 0x21, 0x36, 0x84, 0x18, 0x12, 0x40, 0x7B, 0x00, 0x6D, 0x01, 0xB4, 0x06,
-0xD0, 0x97, 0x40, 0x6D, 0x00, 0x61, 0x09, 0x84, 0x25, 0x10, 0x16, 0x40, 0x10,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x00, 0x40, 0x8B, 0x08,
-0x4C, 0x13, 0x30, 0x08, 0xC0, 0x00, 0x42, 0xD3, 0x10, 0x0C, 0x03, 0x30, 0x0C,
-0x40, 0x20, 0x02, 0x83, 0x00, 0x2C, 0x03, 0x12, 0x04, 0xC2, 0x02, 0x00, 0x8F,
-0x08, 0x1C, 0x12, 0x30, 0x00, 0xE5, 0x13, 0x00, 0xC7, 0x00, 0x3C, 0x20, 0xF0,
-0x04, 0xC0, 0x21, 0x00, 0xD3, 0x08, 0x4C, 0x23, 0x30, 0x0D, 0xC0, 0x48, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0xA7, 0x08, 0xFC,
-0x03, 0xF0, 0x0F, 0xC8, 0x1F, 0x00, 0xFF, 0x80, 0xFD, 0x03, 0xF0, 0x0F, 0xC0,
-0x3F, 0x0A, 0xBE, 0x80, 0xFC, 0x03, 0xF4, 0x03, 0xC2, 0x0F, 0x02, 0xEF, 0x20,
-0xEC, 0x02, 0xF0, 0x83, 0xC0, 0x3F, 0x02, 0xFB, 0x00, 0xFC, 0x02, 0xF1, 0x06,
-0xC0, 0x2A, 0x02, 0xFF, 0x08, 0xFC, 0x23, 0xF0, 0x8F, 0xC0, 0x0B, 0x60, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xCF, 0x00, 0x5C, 0x05,
-0x30, 0x09, 0xC0, 0x24, 0x00, 0xDF, 0x0D, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x27,
-0x00, 0x13, 0x00, 0xCD, 0x03, 0x34, 0x0D, 0xD8, 0x05, 0x10, 0x13, 0x00, 0x7C,
-0x02, 0x70, 0x01, 0xC4, 0x13, 0x00, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0,
-0x34, 0x00, 0x5F, 0x00, 0x4E, 0x01, 0x30, 0x15, 0xC0, 0x54, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xED, 0x80, 0x84, 0x01, 0x10,
-0x0E, 0x40, 0x38, 0x00, 0xCD, 0x10, 0x84, 0x02, 0xD0, 0x0E, 0x40, 0x2B, 0x10,
-0x81, 0x04, 0x84, 0x03, 0x10, 0x04, 0xC0, 0x0A, 0x00, 0x21, 0x00, 0xB4, 0x02,
-0x11, 0x06, 0x48, 0x3B, 0x00, 0x61, 0x00, 0xB4, 0x03, 0xD2, 0x0F, 0x40, 0x38,
-0x20, 0x6D, 0x00, 0x84, 0x01, 0x10, 0x06, 0x40, 0x48, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0x94, 0x07, 0x10, 0x1A,
-0x50, 0x68, 0x00, 0xED, 0x05, 0x84, 0x47, 0xD8, 0x1E, 0x40, 0x6F, 0x00, 0xA1,
-0x1D, 0x85, 0x07, 0x10, 0x1E, 0x40, 0xC9, 0x18, 0xE1, 0x01, 0xF4, 0x0E, 0x50,
-0x12, 0x40, 0x5B, 0x00, 0xE1, 0x01, 0xB4, 0x05, 0xD0, 0x1E, 0x42, 0x78, 0x00,
-0xED, 0x01, 0x84, 0x87, 0x10, 0x1E, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x16, 0x28, 0x73, 0x02, 0xDD, 0x00, 0x04, 0x03, 0x10, 0x0C, 0x40,
-0xB0, 0x00, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x0D, 0x40, 0xA3, 0x01, 0xC1, 0x40,
-0x04, 0x09, 0x10, 0x8D, 0x40, 0x76, 0x00, 0xC1, 0x03, 0x34, 0x0F, 0x10, 0x88,
-0x42, 0x33, 0x00, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD,
-0x00, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x17, 0xA0, 0x95, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x34, 0x05, 0xC0, 0x1C,
-0x01, 0x5F, 0x00, 0x4C, 0x01, 0xF0, 0x07, 0xC0, 0xDF, 0x44, 0x73, 0x00, 0xCC,
-0x31, 0x30, 0x17, 0xC2, 0x9D, 0x40, 0x73, 0x07, 0xFC, 0x29, 0x72, 0x16, 0xC0,
-0x17, 0x50, 0x53, 0x20, 0x7C, 0x01, 0xF1, 0x05, 0xC0, 0x14, 0x10, 0x5F, 0x00,
-0x4D, 0x01, 0x34, 0x05, 0xD0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x08, 0x05, 0x04, 0x1D, 0x00, 0x7C, 0x00, 0xF2, 0x01, 0xC8, 0x03, 0x04,
-0x1F, 0x40, 0x7D, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x10, 0x1F, 0x20, 0x7C, 0x00,
-0xF2, 0x11, 0xD0, 0x07, 0x04, 0x0F, 0x12, 0x3C, 0x08, 0xF1, 0x41, 0xC0, 0x07,
-0x00, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x11, 0xC8, 0x07, 0x00, 0x1F, 0x00, 0x7C,
-0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x25, 0x00, 0x9F, 0x02, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x02, 0x90,
-0x01, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x83, 0x00, 0x4C, 0x02, 0x30,
-0x09, 0xC0, 0x64, 0x00, 0x93, 0x05, 0x4C, 0x06, 0x10, 0x09, 0xC8, 0x24, 0x00,
-0x93, 0x00, 0x64, 0x0A, 0x30, 0x09, 0xC0, 0xE4, 0x10, 0x9F, 0x02, 0x4D, 0x0A,
-0x30, 0x59, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0xA6, 0x10, 0x9D, 0x00, 0x45, 0x0A, 0xD0, 0x08, 0xC0, 0x66, 0x00, 0x91, 0x01,
-0x34, 0x1A, 0x12, 0x09, 0x48, 0xA4, 0x02, 0x95, 0x00, 0x44, 0x02, 0x12, 0x99,
-0x51, 0x24, 0x08, 0x91, 0x25, 0x44, 0xA6, 0x10, 0x09, 0x40, 0x20, 0x00, 0x91,
-0x02, 0x04, 0x0A, 0x10, 0x29, 0x50, 0x64, 0x08, 0x9D, 0x42, 0x44, 0x0A, 0x10,
-0x39, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24,
-0x80, 0xBD, 0x00, 0xC4, 0x02, 0xD0, 0x0B, 0x40, 0x24, 0x40, 0x95, 0x08, 0x74,
-0x22, 0x14, 0x09, 0x48, 0xB0, 0x00, 0xD9, 0x04, 0x24, 0x02, 0x14, 0x09, 0x40,
-0x24, 0x42, 0xD1, 0x00, 0x45, 0x42, 0x50, 0x09, 0x52, 0x24, 0x40, 0xA1, 0x00,
-0xF4, 0x02, 0x10, 0x2A, 0x42, 0x2C, 0x00, 0xAD, 0x00, 0xA4, 0x02, 0x10, 0x0B,
-0x42, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x68, 0x00,
-0xED, 0x00, 0x84, 0x06, 0xD0, 0x0B, 0x40, 0x22, 0x01, 0x85, 0x04, 0x74, 0x02,
-0x10, 0x48, 0x40, 0x20, 0x01, 0x8D, 0x04, 0x25, 0x12, 0x10, 0x48, 0x40, 0x60,
-0x20, 0x81, 0x84, 0x05, 0x12, 0x14, 0x08, 0x40, 0x2C, 0x00, 0xA1, 0x01, 0xD4,
-0x02, 0x10, 0x0A, 0x42, 0x68, 0x80, 0xAD, 0x01, 0xA4, 0x06, 0x10, 0x1A, 0x40,
-0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x86, 0x02, 0x1F,
-0x0A, 0x0D, 0x28, 0xF0, 0xA2, 0xC0, 0x94, 0x02, 0x17, 0x0A, 0x7C, 0x28, 0x30,
-0xA5, 0xD0, 0x84, 0x02, 0x1B, 0x0A, 0x2C, 0x28, 0x31, 0xA1, 0xD0, 0x80, 0x22,
-0x13, 0x00, 0x4C, 0x28, 0x70, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x29,
-0x30, 0xA1, 0xC0, 0x04, 0x00, 0x0F, 0x0A, 0x2C, 0x28, 0x32, 0xA2, 0xC0, 0x77,
-0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0x9B, 0x08, 0xEC, 0x02, 0xF4, 0x8B,
-0xC8, 0x2B, 0x02, 0xB7, 0x08, 0xDC, 0x23, 0xF0, 0x8B, 0xC2, 0x2F, 0x00, 0xBF,
-0x68, 0xBC, 0x22, 0xF0, 0x0B, 0xC2, 0x27, 0x00, 0x9F, 0x20, 0x6C, 0x02, 0xF4,
-0x09, 0xC8, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF4, 0x09, 0xC0, 0x67, 0x60,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x00, 0xF3, 0x28, 0xDC,
-0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x42, 0xB3, 0x04, 0xCC, 0x02, 0x30, 0xCF, 0xC0,
-0x2B, 0x00, 0xA3, 0x05, 0x4D, 0x16, 0x32, 0x9B, 0xC0, 0xAF, 0x10, 0xB3, 0x05,
-0xDC, 0x36, 0x30, 0x0B, 0xC4, 0x2C, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x8B,
-0xC0, 0x3C, 0x18, 0xBF, 0x40, 0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x63, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x01, 0x04, 0x44, 0x41,
-0xD0, 0x01, 0x41, 0x07, 0x02, 0x11, 0x14, 0x44, 0x10, 0x10, 0xC0, 0x40, 0x87,
-0x44, 0x11, 0x17, 0x44, 0x5C, 0x14, 0x31, 0x44, 0x47, 0x00, 0x11, 0x22, 0x44,
-0x04, 0x10, 0x55, 0x41, 0x44, 0x05, 0x51, 0x14, 0x74, 0x10, 0xD0, 0x41, 0x50,
-0x04, 0x00, 0x5D, 0x10, 0x74, 0x01, 0xD0, 0x45, 0x41, 0x73, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x45, 0x81, 0x04, 0x14, 0x12, 0xD0,
-0x08, 0x40, 0x23, 0x00, 0x81, 0x0C, 0x24, 0x52, 0x10, 0x48, 0x44, 0x23, 0x03,
-0x81, 0x08, 0x04, 0x22, 0x10, 0x68, 0x40, 0x27, 0x01, 0x89, 0x08, 0x34, 0x1A,
-0x14, 0x09, 0x50, 0x24, 0x00, 0x89, 0x24, 0x34, 0x52, 0xD1, 0x48, 0x40, 0x20,
-0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x28, 0x21, 0x00, 0x91, 0x00, 0x44, 0x02, 0xD2, 0x09,
-0x40, 0x27, 0x00, 0x91, 0x00, 0x65, 0x02, 0x14, 0x29, 0x40, 0xA7, 0x01, 0x91,
-0x11, 0x44, 0x12, 0x10, 0x09, 0x40, 0x67, 0x00, 0x99, 0x06, 0x64, 0x0A, 0x10,
-0x19, 0x40, 0x24, 0x40, 0x99, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00,
-0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x93, 0x00, 0x5C, 0x0A, 0xF0, 0x09, 0xC0,
-0xA7, 0x01, 0x93, 0x00, 0x6D, 0x06, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x01,
-0x4C, 0x0A, 0x30, 0x69, 0xC0, 0x23, 0x24, 0x9B, 0x00, 0x7C, 0x06, 0x32, 0x18,
-0xC0, 0x24, 0x00, 0x9A, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x80, 0x9F,
-0x02, 0x7C, 0x0A, 0xF0, 0x29, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x16, 0x08, 0x25, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x23,
-0x00, 0x8F, 0x00, 0x5C, 0x4E, 0xF0, 0x09, 0xC0, 0x27, 0x44, 0x8F, 0x40, 0x7C,
-0x02, 0xF2, 0x09, 0xC2, 0x27, 0x40, 0x87, 0x01, 0x54, 0xCA, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF1, 0x09, 0xC0, 0x27, 0x0C, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x08, 0x05, 0x04, 0x1F, 0x04, 0x4C, 0x08, 0xB4, 0x01, 0xD0, 0x04, 0x01,
-0x13, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x13, 0x02, 0x4C, 0x08,
-0x30, 0x21, 0xC0, 0x84, 0x00, 0x13, 0x01, 0x0C, 0x00, 0xB4, 0x01, 0xC0, 0x07,
-0x00, 0x1F, 0x06, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x02, 0x4D,
-0x48, 0x34, 0x21, 0xD0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x00, 0xDC, 0x00, 0x6D, 0x00, 0xC4, 0x05, 0x30, 0x05, 0x40, 0x1C, 0x00, 0x51,
-0x00, 0xC5, 0x05, 0x10, 0x07, 0x48, 0x1C, 0x00, 0x51, 0x20, 0x44, 0x01, 0x50,
-0x67, 0x40, 0x1C, 0x48, 0x71, 0x10, 0xEC, 0x09, 0x10, 0x15, 0x40, 0x13, 0x00,
-0x7D, 0x83, 0xC4, 0x01, 0x00, 0x17, 0x40, 0x1F, 0x00, 0x7D, 0x00, 0xC4, 0x09,
-0x10, 0x07, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
-0xF2, 0x02, 0x8D, 0x02, 0x04, 0x07, 0x50, 0x0C, 0x40, 0xB0, 0x40, 0xC5, 0x00,
-0x44, 0x0F, 0x10, 0x8C, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x45, 0x03, 0x18, 0x6C,
-0x44, 0x30, 0x20, 0xC1, 0x01, 0x04, 0x07, 0x10, 0x18, 0x40, 0x33, 0x08, 0xCD,
-0x03, 0x04, 0x05, 0x10, 0x89, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x05, 0x0B, 0x10,
-0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38,
-0x10, 0x2D, 0x04, 0x84, 0x47, 0x50, 0xDF, 0x42, 0x08, 0x04, 0xE5, 0x00, 0x84,
-0x41, 0x10, 0x1E, 0x40, 0x2C, 0x00, 0xF1, 0x00, 0x84, 0x13, 0x50, 0x1E, 0x50,
-0x3C, 0x05, 0x41, 0x20, 0xA4, 0x0B, 0x10, 0x0E, 0x41, 0x3B, 0x00, 0xED, 0x03,
-0x84, 0x0D, 0x11, 0x02, 0x40, 0x0B, 0x00, 0xED, 0x01, 0x84, 0x07, 0x10, 0x1E,
-0x44, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x00,
-0xAF, 0x07, 0xCD, 0x07, 0x70, 0x1E, 0xC0, 0x40, 0x40, 0x87, 0x89, 0x8C, 0x04,
-0x34, 0x1E, 0x10, 0x78, 0x40, 0xE3, 0x31, 0xCC, 0x0F, 0x34, 0x1E, 0xC0, 0xE8,
-0x00, 0x63, 0x01, 0x0C, 0x04, 0x34, 0x1A, 0xC0, 0x7B, 0x00, 0xFF, 0x01, 0xCC,
-0x06, 0x34, 0x12, 0xC0, 0x4B, 0x00, 0xFD, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0,
-0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x1F,
-0x20, 0x7C, 0x03, 0x30, 0x2C, 0xC0, 0x07, 0x00, 0xDB, 0x04, 0x3C, 0x00, 0xF2,
-0x05, 0xC0, 0x37, 0x00, 0xDF, 0x06, 0x7C, 0x5B, 0xB0, 0x88, 0xC0, 0x13, 0x00,
-0x5F, 0x20, 0x7C, 0x00, 0xF0, 0x0F, 0xC0, 0xB7, 0x0D, 0xDF, 0x00, 0xFC, 0x80,
-0xF0, 0x09, 0xC0, 0x07, 0x00, 0xDF, 0x20, 0x7C, 0x01, 0xF0, 0x09, 0xC2, 0x43,
-0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00, 0x2F, 0x01,
-0xDC, 0x13, 0xF0, 0x3F, 0xC0, 0x4C, 0x10, 0xF7, 0x01, 0xDC, 0x04, 0x30, 0x1F,
-0xC8, 0x6C, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x31, 0x1B, 0xD0, 0x6D, 0x00, 0x73,
-0x01, 0x9D, 0x04, 0xB2, 0x4F, 0xC0, 0x7C, 0x00, 0xF3, 0x01, 0xDC, 0x05, 0x30,
-0x1F, 0xC0, 0x4C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x03, 0x08,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0x27, 0x00, 0x84,
-0x0A, 0xD0, 0x8F, 0x41, 0x0C, 0x00, 0xE1, 0x00, 0xEC, 0x00, 0x12, 0x4A, 0x40,
-0x08, 0x02, 0xE0, 0x00, 0x84, 0x13, 0xA1, 0x0B, 0x40, 0x38, 0x00, 0x61, 0x08,
-0x84, 0x02, 0x50, 0x0F, 0x40, 0x3C, 0x02, 0xA7, 0x00, 0xC4, 0x21, 0x12, 0x07,
-0x40, 0x08, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x2E, 0x40, 0x57, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xAD, 0x00, 0x94, 0x23,
-0xD0, 0x0E, 0x40, 0x08, 0x00, 0x85, 0x00, 0x94, 0x40, 0x10, 0x0E, 0x40, 0x3C,
-0x00, 0xE1, 0x08, 0x84, 0x03, 0x80, 0x02, 0x40, 0x29, 0x02, 0x21, 0x00, 0xD4,
-0x00, 0x14, 0x2E, 0x40, 0x38, 0x00, 0x61, 0x00, 0x94, 0x02, 0x10, 0x06, 0x40,
-0x08, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0x05, 0x00, 0x04, 0x02, 0xD0,
-0x1C, 0x40, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x00, 0x12, 0x31, 0x40, 0x30, 0x00,
-0xC1, 0x00, 0x05, 0x83, 0x90, 0x10, 0x40, 0x10, 0x04, 0x41, 0x61, 0x04, 0x04,
-0x54, 0x9C, 0x44, 0x30, 0x08, 0x95, 0x00, 0x04, 0x00, 0x10, 0x0C, 0x40, 0x00,
-0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0xA0, 0x35, 0x00, 0xFF, 0x00, 0x5C, 0x03, 0xF0, 0x1F,
-0xD0, 0x24, 0x00, 0xD7, 0x00, 0x1C, 0x04, 0x30, 0x8D, 0xD5, 0x60, 0x00, 0xD3,
-0x0A, 0xCC, 0x0B, 0xB0, 0x83, 0xD1, 0x39, 0x48, 0x13, 0x10, 0x5D, 0x02, 0x30,
-0x0D, 0xC4, 0xA4, 0x00, 0xD3, 0x00, 0x5C, 0x09, 0x30, 0x0D, 0xC0, 0x00, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x08, 0x27, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
-0x07, 0x02, 0xDF, 0x20, 0x5C, 0x08, 0xF4, 0x2D, 0xC0, 0xE7, 0x40, 0xDF, 0x08,
-0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x02, 0x1F, 0x20, 0x7C, 0xA2, 0x74, 0x0D,
-0xC0, 0x37, 0x01, 0xD7, 0x40, 0x7C, 0x11, 0xF0, 0x2D, 0xC0, 0x07, 0x00, 0x9F,
-0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x80, 0x08, 0x1F, 0x00, 0xB3, 0x00, 0xCC, 0x01, 0xF0, 0x0F, 0xC0, 0x0B,
-0x00, 0xB2, 0x00, 0xCC, 0x00, 0x30, 0x1F, 0xC0, 0x2C, 0x40, 0x97, 0x00, 0x7C,
-0x43, 0x32, 0x53, 0xD0, 0x2E, 0x00, 0x13, 0x00, 0xFC, 0x20, 0x20, 0x1F, 0xC0,
-0x2F, 0x00, 0xFD, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0C, 0x10, 0x72, 0x00,
-0xFC, 0x27, 0xF0, 0x07, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x81, 0x00, 0x06, 0x08, 0x11, 0x00, 0x45, 0x0B, 0xD0, 0x0D, 0xC8, 0x45, 0x00,
-0xD1, 0x00, 0x44, 0x04, 0x10, 0xBD, 0x41, 0x64, 0x20, 0x91, 0x08, 0x34, 0x03,
-0x12, 0x09, 0x40, 0x15, 0x00, 0x11, 0x01, 0x7C, 0x00, 0x50, 0x1D, 0x40, 0x77,
-0x00, 0xDD, 0x09, 0x44, 0x04, 0xD0, 0x3D, 0x48, 0xC4, 0x04, 0xD1, 0x00, 0x74,
-0x05, 0xD0, 0xBD, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0xA0, 0x76, 0x00, 0x41, 0x08, 0x44, 0x23, 0xD0, 0x0D, 0x40, 0x47, 0x00, 0xC5,
-0x00, 0x44, 0x0C, 0x10, 0x0D, 0x40, 0xE5, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x12,
-0x00, 0x41, 0x26, 0x00, 0x11, 0x23, 0x34, 0x00, 0xD8, 0x4D, 0x40, 0x27, 0x01,
-0xDD, 0x00, 0x64, 0x44, 0xD0, 0x6C, 0x40, 0x44, 0x80, 0xD5, 0x01, 0x74, 0x03,
-0xD0, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
-0x70, 0x00, 0x41, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x01, 0x00, 0xC5, 0x00,
-0x04, 0x80, 0x14, 0x0C, 0x50, 0x21, 0x00, 0xC1, 0x00, 0x74, 0x83, 0x18, 0x08,
-0x50, 0x31, 0x00, 0x01, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
-0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x00, 0x80, 0x85, 0x01, 0x34, 0x02, 0xD0,
-0x0C, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x36,
-0x00, 0x93, 0x80, 0x4C, 0x81, 0xF0, 0x0F, 0xC0, 0x07, 0x20, 0xB7, 0x00, 0x4D,
-0x00, 0x30, 0x0C, 0x44, 0x25, 0x00, 0xB3, 0x00, 0xFC, 0x03, 0x31, 0x01, 0xC4,
-0x22, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC2, 0x2F, 0x00, 0x4F, 0x40,
-0x6C, 0x00, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x57, 0x00, 0x7C, 0x03, 0xF0, 0x05,
-0xC4, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00,
-0x3F, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFB, 0x40, 0xFC, 0x00,
-0xF0, 0x0F, 0xC0, 0x2A, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0x40, 0x1F,
-0x40, 0x3F, 0x00, 0xD8, 0x00, 0x72, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
-0x00, 0xF0, 0x0F, 0xC8, 0x0F, 0x08, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF,
-0x01, 0xFC, 0x13, 0x32, 0x8B, 0xC2, 0x2C, 0x09, 0xFF, 0x01, 0xFC, 0x63, 0x30,
-0x4B, 0xC2, 0x7C, 0x00, 0xBF, 0x04, 0xCC, 0x82, 0x30, 0x2F, 0xC1, 0x7C, 0x00,
-0xF3, 0x01, 0xFC, 0x43, 0x30, 0x4F, 0x50, 0x28, 0x00, 0xF3, 0x01, 0xFE, 0x07,
-0xB0, 0x1F, 0xC0, 0x7C, 0x00, 0xF9, 0x01, 0xFC, 0x03, 0xF0, 0x1F, 0xC0, 0x0F,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00, 0xDD, 0x01,
-0xF4, 0x63, 0x10, 0x81, 0x46, 0xE4, 0x0A, 0xDD, 0x41, 0xF4, 0x0B, 0x50, 0x91,
-0x42, 0x74, 0x00, 0x9C, 0x22, 0x44, 0x08, 0x10, 0x2F, 0xC4, 0x34, 0x08, 0xD5,
-0x21, 0xF4, 0x0F, 0x41, 0x9F, 0x40, 0xC4, 0x02, 0xD1, 0x01, 0x74, 0x07, 0x10,
-0x15, 0x40, 0x74, 0x00, 0xD9, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x40, 0x0F, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x28, 0xCD, 0x80, 0x34,
-0x13, 0x00, 0x08, 0x48, 0x40, 0x20, 0xCD, 0x80, 0x30, 0x03, 0x12, 0x10, 0x40,
-0x30, 0x10, 0x0D, 0x1C, 0x04, 0x76, 0x10, 0x4C, 0x40, 0x33, 0x05, 0xC1, 0x40,
-0x34, 0x83, 0x80, 0x0C, 0x40, 0x20, 0x08, 0xC1, 0x80, 0x34, 0x03, 0x90, 0x0D,
-0x40, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x4F, 0x80, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x03,
-0x11, 0x11, 0x40, 0x64, 0x00, 0xDD, 0x40, 0x64, 0x03, 0x10, 0x11, 0x40, 0x34,
-0x20, 0x09, 0x03, 0x04, 0x06, 0x10, 0x0D, 0x44, 0x35, 0x00, 0xD1, 0x00, 0x74,
-0x03, 0x90, 0x0D, 0x40, 0x64, 0x04, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x19, 0x40,
-0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x00, 0x0F, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x74, 0x03, 0x30,
-0x31, 0xC0, 0x44, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0x32, 0x19, 0xC0, 0x34, 0x08,
-0x9F, 0x01, 0x4C, 0x04, 0x30, 0x0D, 0xC6, 0x37, 0x00, 0xD1, 0x80, 0x7C, 0x83,
-0xA0, 0x0D, 0xC0, 0x64, 0x00, 0xD3, 0x00, 0x74, 0x03, 0xB0, 0x3D, 0xC1, 0x36,
-0x00, 0xDF, 0x00, 0x7C, 0x03, 0xD0, 0x0D, 0xC0, 0x83, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0x7C, 0x03, 0xF0, 0x02,
-0xC0, 0x07, 0x00, 0xFF, 0x40, 0xFC, 0x03, 0xF0, 0x00, 0x40, 0x3F, 0x00, 0x9F,
-0x20, 0x7C, 0x80, 0xF1, 0x0F, 0xC0, 0x3E, 0x00, 0xFD, 0x00, 0xFC, 0x03, 0x72,
-0x0F, 0x40, 0x0B, 0x00, 0xFD, 0x00, 0xFC, 0x03, 0xB0, 0x0F, 0x40, 0x3D, 0x00,
-0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x30, 0xA9, 0xC0,
-0x04, 0x00, 0xD3, 0x60, 0x2C, 0x63, 0x30, 0x09, 0xC0, 0x34, 0x00, 0x9B, 0x20,
-0x4C, 0x00, 0x30, 0x8C, 0xC0, 0x34, 0x00, 0xD2, 0x00, 0x3C, 0x03, 0x30, 0x0C,
-0xC0, 0x27, 0x00, 0xD7, 0x00, 0x7C, 0x23, 0xF1, 0x2D, 0xC0, 0x37, 0x10, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0xF4, 0x03, 0x10, 0x31, 0x40, 0x24,
-0x00, 0xD1, 0x00, 0xF4, 0x0B, 0x10, 0x09, 0x44, 0x34, 0x00, 0x9D, 0x00, 0x44,
-0x02, 0x12, 0xAF, 0x40, 0x74, 0x20, 0xD1, 0x00, 0xF4, 0x03, 0x10, 0x0F, 0x40,
-0x27, 0x00, 0xD1, 0x80, 0x34, 0x0F, 0xD0, 0x0C, 0x40, 0x37, 0x00, 0xDD, 0x00,
-0xF4, 0x03, 0xD0, 0x0D, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x14, 0x08, 0x41, 0x20, 0x00,
-0xC1, 0x00, 0x34, 0x0B, 0x10, 0x08, 0x40, 0x30, 0x00, 0x0D, 0x00, 0x04, 0x02,
-0x10, 0x2C, 0x40, 0x34, 0x02, 0xC1, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x03,
-0x00, 0xC5, 0x20, 0x34, 0x4F, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34,
-0x03, 0xD0, 0x0C, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x80, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x27, 0x10, 0x1E, 0x40, 0x78, 0x00, 0xE1,
-0x01, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x78, 0x00, 0xED, 0x01, 0x84, 0x05, 0x10,
-0x1E, 0x40, 0xF8, 0x00, 0xE1, 0x01, 0xF4, 0x07, 0x10, 0x1E, 0x40, 0x5B, 0x00,
-0xE1, 0x01, 0xB0, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07,
-0xD0, 0x1E, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10,
-0x30, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0x2D, 0xC0, 0x10, 0x08, 0xC3, 0x08,
-0x7C, 0x03, 0x30, 0x44, 0xC0, 0x30, 0x02, 0x4F, 0x00, 0x0C, 0x03, 0x30, 0x8D,
-0xE0, 0x34, 0x00, 0xC3, 0x08, 0x7C, 0x23, 0x30, 0x0C, 0xC0, 0x13, 0x00, 0xC7,
-0x00, 0x3C, 0x03, 0xF1, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0xF0,
-0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x35,
-0x10, 0xDF, 0x00, 0x7C, 0x0B, 0xC0, 0x0D, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x74,
-0x03, 0xF0, 0x05, 0xC0, 0x37, 0x20, 0xDE, 0x00, 0x7C, 0x03, 0xF0, 0x2D, 0xC0,
-0x37, 0x00, 0xDF, 0x08, 0x7C, 0x83, 0xB4, 0x0D, 0xC1, 0x37, 0x00, 0xDF, 0x00,
-0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
-0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00,
-0xDF, 0x00, 0x7C, 0xB3, 0x30, 0x15, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x4B,
-0xF0, 0x0D, 0xC8, 0x37, 0x28, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0xAD, 0xC0, 0x37,
-0x00, 0xDF, 0x00, 0x7C, 0x53, 0xF0, 0x1D, 0xC4, 0x34, 0x10, 0xD3, 0x00, 0x7C,
-0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
-0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED,
-0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x13, 0xD0,
-0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD3, 0x4E, 0x40, 0x3B, 0x00,
-0xED, 0x00, 0xB4, 0x1B, 0xD0, 0x4E, 0x41, 0x18, 0x08, 0xE1, 0x80, 0xB4, 0x03,
-0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x0B, 0xD0, 0x0E, 0x40, 0x4F,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x01,
-0xB0, 0x17, 0x10, 0x1C, 0x51, 0x58, 0x00, 0xED, 0x01, 0xB4, 0x27, 0xD0, 0x1E,
-0x40, 0x7B, 0x00, 0x6D, 0x21, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED,
-0x01, 0xB4, 0x07, 0xD0, 0x1C, 0x40, 0x70, 0x40, 0xE1, 0x01, 0xB4, 0x07, 0xD0,
-0x1E, 0x41, 0x7B, 0x80, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x13, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x74,
-0x83, 0x10, 0x3C, 0x45, 0xF0, 0x02, 0xCD, 0x00, 0x34, 0x03, 0xD8, 0xBC, 0x40,
-0x33, 0x00, 0xDD, 0x01, 0x34, 0x2B, 0xD1, 0x0D, 0x40, 0x33, 0x00, 0xCD, 0x00,
-0x34, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xD1, 0x80, 0x34, 0x03, 0xD0, 0x7C,
-0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x60, 0x5B, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0xC0, 0x7C, 0x01,
-0x30, 0x17, 0xC0, 0xDC, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x17, 0xC0, 0x17,
-0x00, 0x7F, 0x05, 0xFC, 0x25, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C,
-0x01, 0xF0, 0x05, 0xC0, 0x58, 0x01, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xC0,
-0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x5F, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF4,
-0x01, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x06, 0x10,
-0x1F, 0x41, 0x7C, 0x00, 0xE0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00,
-0xF0, 0x01, 0xD0, 0xC7, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07,
-0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x59,
-0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F,
-0x00, 0x4C, 0x02, 0xF0, 0x99, 0xC0, 0x64, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x67, 0x00, 0x97, 0x00, 0x4C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x19, 0x40,
-0x27, 0x00, 0x9D, 0x00, 0x76, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00,
-0x44, 0x02, 0xD0, 0x69, 0xC0, 0xA4, 0x01, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09,
-0x40, 0xA7, 0x12, 0x91, 0x40, 0x0C, 0x9A, 0x11, 0x09, 0x40, 0x27, 0x00, 0x9D,
-0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27,
-0x00, 0x9D, 0x40, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x20, 0x44,
-0x82, 0xD0, 0x09, 0x40, 0x24, 0x0A, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40,
-0xA7, 0x00, 0x95, 0x00, 0x44, 0x02, 0x50, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00,
-0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x20, 0x20, 0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x58, 0x40, 0x23, 0x01,
-0x8D, 0x40, 0x34, 0x16, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x8D, 0x44, 0x04, 0x12,
-0xD0, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x34, 0x12, 0xD8, 0x48, 0x40, 0x23,
-0x01, 0x91, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34,
-0x12, 0xD0, 0x08, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xB0, 0x06, 0x00, 0x1F, 0x00, 0x3C, 0x28, 0x30, 0xA1, 0xC0, 0x07, 0x00, 0x1F,
-0x00, 0x74, 0x28, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0x4D, 0x28, 0xF1,
-0xA1, 0x40, 0x84, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
-0x17, 0x00, 0x4D, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00,
-0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF4, 0x8B, 0xC0, 0x2F, 0x0A, 0x9F, 0x00,
-0x7C, 0x22, 0xF0, 0x8B, 0xC0, 0x27, 0x00, 0xFF, 0x08, 0xFC, 0x22, 0xF0, 0x89,
-0xD0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9F,
-0x00, 0x5C, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0,
-0x09, 0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27,
-0x00, 0x9F, 0x00, 0x7C, 0x1E, 0xF0, 0xDB, 0xC0, 0x67, 0x01, 0x9F, 0x00, 0xFC,
-0x36, 0x34, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x07, 0x4C, 0x1E, 0xF1, 0x7B, 0xD0,
-0xAC, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0x6F, 0x01, 0x9B, 0x00,
-0xFC, 0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00,
-0x1D, 0x00, 0x74, 0x3C, 0xD0, 0xF5, 0x42, 0x87, 0x02, 0x1D, 0x00, 0x74, 0x3C,
-0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x05, 0x44, 0x1D, 0xD0, 0x71, 0x40, 0x44,
-0x01, 0x1D, 0x00, 0x74, 0x08, 0xD0, 0x21, 0x40, 0x97, 0x02, 0x11, 0x00, 0x74,
-0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x20, 0xD0, 0x01, 0x40,
-0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D,
-0x00, 0x34, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x02, 0x10,
-0x28, 0x40, 0x23, 0x00, 0x8D, 0x06, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x20, 0x00,
-0x8D, 0x00, 0x34, 0x0A, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x89, 0x00, 0x34, 0x02,
-0xD0, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x4B,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00,
-0x74, 0x02, 0xD0, 0x49, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x69,
-0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x24, 0x00, 0x9D,
-0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x80, 0x74, 0x82, 0xD0,
-0x89, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x16, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x39, 0xC0,
-0x27, 0x00, 0x9F, 0x08, 0x4C, 0x06, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x23, 0x00, 0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x19,
-0x41, 0x27, 0x20, 0x9D, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x17, 0x80, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x19, 0xC0, 0x27,
-0x00, 0x8F, 0x00, 0x7D, 0x16, 0xF1, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xCA, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x19, 0xC0,
-0x27, 0x00, 0x9F, 0x00, 0x74, 0x02, 0xF0, 0x09, 0x80, 0x5B, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0,
-0x21, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x07, 0x00,
-0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x00,
-0xF0, 0x01, 0xC0, 0x87, 0x04, 0x17, 0x00, 0x7C, 0x40, 0xF2, 0x21, 0xC0, 0x04,
-0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x27,
-0x40, 0x17, 0x00, 0x5D, 0x00, 0xF4, 0x19, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x5D,
-0x00, 0x74, 0x01, 0xD0, 0xC7, 0x40, 0x9F, 0x83, 0x5D, 0x00, 0x74, 0x01, 0xD0,
-0x05, 0x40, 0x5F, 0x01, 0x51, 0x00, 0xF4, 0x01, 0x70, 0x05, 0x40, 0x14, 0x00,
-0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x2C, 0x41,
-0x33, 0x00, 0xCD, 0x00, 0x34, 0x47, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00,
-0x34, 0x03, 0xD0, 0x2C, 0x40, 0xF3, 0x00, 0xCD, 0x40, 0x34, 0x03, 0xD0, 0x0C,
-0x40, 0x53, 0x08, 0xC5, 0x00, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD,
-0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x13, 0xD0, 0x0E, 0x41, 0x3B,
-0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x04, 0xB4,
-0x13, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40,
-0x1B, 0x00, 0xE1, 0x40, 0xB4, 0x09, 0x50, 0x0F, 0x40, 0x38, 0x00, 0xED, 0x00,
-0xB4, 0x03, 0xD0, 0x0E, 0x42, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x17, 0xF0, 0x1E, 0xC0, 0x7B, 0x08,
-0xEF, 0x01, 0xBC, 0x07, 0xF0, 0x1E, 0xC2, 0x7B, 0x00, 0xEF, 0x0D, 0xBC, 0x37,
-0xF0, 0x16, 0xC0, 0x7B, 0x00, 0xED, 0x41, 0xBC, 0x07, 0xF0, 0x1E, 0xC0, 0x5B,
-0x00, 0xE7, 0x01, 0xBC, 0x04, 0xF0, 0x0E, 0xC4, 0x78, 0x00, 0xED, 0x01, 0xBC,
-0x07, 0xF0, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x53, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
-0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x08, 0x7C, 0x03, 0xF0,
-0x05, 0xC4, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x13, 0x10,
-0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC8, 0x37, 0x08, 0xDF, 0x00, 0x7C, 0x03,
-0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
-0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x63, 0xF0, 0x17, 0xC0, 0x7F, 0x00, 0xFF, 0x09,
-0xFC, 0x27, 0xF3, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x81, 0xF8, 0x47, 0x30, 0x1F,
-0x48, 0x5F, 0x02, 0xFE, 0x21, 0xFC, 0x07, 0xD0, 0x9F, 0x80, 0x5D, 0x00, 0xF3,
-0x09, 0xFC, 0x27, 0xF0, 0x1F, 0xC0, 0x7F, 0x02, 0xFF, 0x09, 0xFC, 0x07, 0xF0,
-0x1F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39,
-0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x86, 0x41, 0x3B, 0x00, 0xED, 0x00, 0xB4,
-0x01, 0xC0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x08, 0xB4, 0x03, 0x14, 0x8E, 0x40,
-0x1A, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x0F, 0x42, 0x1C, 0x05, 0xE5, 0x08,
-0xB4, 0x09, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x8E,
-0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00,
-0xED, 0x00, 0xB4, 0x23, 0x58, 0x06, 0x40, 0x3B, 0x06, 0xED, 0x80, 0xB0, 0x03,
-0xD1, 0x8E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
-0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0F, 0x44, 0x3D, 0x00, 0xE5, 0x40, 0xB4,
-0x81, 0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xED, 0x40, 0xB4, 0x23, 0xD0, 0x0E, 0x40,
-0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x33, 0x00, 0xCD,
-0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0xB3, 0x00, 0xCD, 0x00, 0x74, 0x00, 0x90,
-0x1C, 0x40, 0x37, 0x10, 0xCD, 0x02, 0x74, 0x27, 0x10, 0x08, 0x08, 0x02, 0x00,
-0xC9, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC5, 0x40, 0x34, 0x01,
-0xD1, 0x0C, 0x40, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x0B,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00,
-0xFC, 0x03, 0x70, 0x19, 0xC0, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x2D,
-0xC3, 0x37, 0x00, 0xFF, 0x44, 0xFC, 0x03, 0x31, 0x09, 0x80, 0x27, 0x10, 0xDE,
-0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x45, 0x00, 0xD7, 0x40, 0x78, 0x01, 0xD0,
-0x0D, 0xC1, 0x37, 0x10, 0xDD, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x20, 0xDF, 0x00, 0x7C,
-0x03, 0xF0, 0x49, 0xC4, 0x37, 0x04, 0xDF, 0x20, 0x7C, 0x0A, 0xF0, 0x0D, 0xC8,
-0x37, 0x10, 0xDF, 0x10, 0x7C, 0x43, 0xF0, 0x29, 0xC4, 0x26, 0x20, 0xDB, 0x80,
-0x7C, 0x03, 0xF2, 0x0D, 0xC0, 0x87, 0x04, 0xDE, 0x00, 0x7C, 0x09, 0xF1, 0x4D,
-0xC0, 0x37, 0x10, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03,
-0xF0, 0x03, 0xC0, 0x3B, 0x00, 0xF3, 0x00, 0xFC, 0x00, 0x30, 0x0F, 0xC1, 0x3F,
-0x08, 0xF3, 0x00, 0x7C, 0x03, 0x30, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xBC,
-0x03, 0x34, 0x0F, 0xC0, 0x5F, 0x02, 0xFF, 0x00, 0xFC, 0x05, 0xD0, 0x0F, 0xC4,
-0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x03, 0x30, 0x0F, 0xC4, 0x07, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0,
-0x79, 0x48, 0x37, 0x30, 0xD1, 0x00, 0x74, 0x1C, 0x10, 0x0D, 0x40, 0x37, 0x00,
-0xD1, 0x00, 0x74, 0x03, 0x10, 0x31, 0x40, 0x67, 0x04, 0xDD, 0x00, 0x74, 0x03,
-0x10, 0x0D, 0x40, 0x17, 0x01, 0xDD, 0x40, 0x74, 0x8D, 0xD0, 0x0C, 0x48, 0x34,
-0x00, 0xDD, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x48, 0x87, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x19,
-0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x40, 0xD1,
-0x00, 0x74, 0x03, 0x10, 0x11, 0x48, 0x47, 0x20, 0xDD, 0x00, 0x74, 0x03, 0x90,
-0x0D, 0x40, 0x17, 0x00, 0xDC, 0x00, 0x74, 0x11, 0xD0, 0x0D, 0x42, 0x35, 0x00,
-0xDD, 0x40, 0x74, 0x03, 0x10, 0x0D, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD2, 0x08, 0x40,
-0x33, 0x00, 0xC1, 0x80, 0x34, 0x02, 0x15, 0x0C, 0x40, 0x37, 0x20, 0xC1, 0xC0,
-0x34, 0x03, 0x14, 0x08, 0x44, 0x03, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x90, 0x0C,
-0x40, 0x13, 0x00, 0xCD, 0x00, 0x34, 0x01, 0xD0, 0x0D, 0x44, 0x30, 0x00, 0xCD,
-0x00, 0x34, 0x03, 0x10, 0x0C, 0x48, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0xFC, 0x03, 0xF0, 0x01, 0xC4, 0x37,
-0x40, 0xD3, 0x00, 0x7C, 0x02, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xF3, 0x00, 0xFC,
-0x03, 0x30, 0x01, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0,
-0x17, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF8, 0x0D, 0xC0, 0x35, 0x80, 0xDF, 0x00,
-0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0x40, 0x3F, 0x20,
-0xFF, 0xC0, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x83,
-0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xF8, 0x03, 0x70, 0x0F, 0xC0, 0x1F,
-0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x20, 0xFC,
-0x03, 0xF2, 0x0F, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA0, 0x7F, 0x00, 0xB3, 0x02, 0xCD, 0x27, 0x30, 0x0B, 0xC0, 0x0C, 0x05, 0x3F,
-0x04, 0xFC, 0x07, 0x30, 0x47, 0xC8, 0x3F, 0x05, 0xFF, 0x04, 0xBC, 0xD3, 0x30,
-0x9B, 0xC0, 0x2C, 0x01, 0x23, 0x89, 0xCC, 0x12, 0xF0, 0x03, 0xC8, 0x2C, 0x02,
-0x33, 0x04, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x7C, 0x18, 0xB3, 0x00, 0xCC, 0x04,
-0xF0, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
-0x37, 0x11, 0x91, 0x02, 0x44, 0x03, 0x10, 0x1B, 0x50, 0x84, 0x10, 0x1D, 0x0B,
-0x74, 0x07, 0x14, 0xBD, 0x40, 0xF7, 0x00, 0xFD, 0x49, 0xF4, 0x0F, 0x12, 0x48,
-0x50, 0xFC, 0x40, 0x11, 0x84, 0x44, 0x4A, 0xD0, 0x31, 0x44, 0xAC, 0x23, 0x13,
-0x0A, 0x74, 0x03, 0xD1, 0x04, 0x40, 0x34, 0x00, 0xD1, 0x03, 0x45, 0x05, 0xD0,
-0x1D, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
-0x04, 0x91, 0x8C, 0x34, 0x13, 0x14, 0x08, 0x40, 0x20, 0x00, 0x0D, 0x00, 0x34,
-0x03, 0x10, 0x0C, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x08, 0x40,
-0xA0, 0x00, 0x05, 0x00, 0x04, 0x0A, 0xD2, 0x21, 0x40, 0x20, 0x41, 0x81, 0x00,
-0x34, 0x03, 0xD8, 0x08, 0x60, 0x32, 0x10, 0xC1, 0x82, 0x04, 0x00, 0xD0, 0x0C,
-0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x40,
-0x91, 0x01, 0x64, 0x03, 0x10, 0x89, 0x40, 0x64, 0x00, 0x1C, 0x11, 0x74, 0x03,
-0x10, 0x1D, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x14, 0x09, 0x40, 0x34,
-0x00, 0x15, 0x01, 0x45, 0x42, 0xD0, 0x49, 0x40, 0x20, 0xC2, 0x91, 0x03, 0x74,
-0x03, 0xD0, 0x0D, 0x50, 0x36, 0x40, 0xD1, 0x01, 0x46, 0x07, 0xD0, 0x0D, 0x40,
-0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0x83,
-0x01, 0x6C, 0x03, 0x30, 0x08, 0xC0, 0x44, 0x20, 0x1E, 0x01, 0x7C, 0x03, 0x30,
-0x3D, 0xC0, 0x37, 0x00, 0xDF, 0xC0, 0x7C, 0x03, 0x30, 0x99, 0xC0, 0x24, 0x02,
-0x17, 0x81, 0x4C, 0x02, 0xF1, 0x00, 0xD0, 0x24, 0x00, 0x13, 0x01, 0x7C, 0x03,
-0xF0, 0x0D, 0xE0, 0x36, 0x00, 0x93, 0x01, 0x4C, 0x04, 0xF2, 0x0D, 0xC2, 0x0B,
-0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xBF, 0x00,
-0xDC, 0x03, 0xF0, 0x19, 0xC0, 0x0F, 0x10, 0x3F, 0x00, 0xF4, 0x03, 0xF1, 0x0D,
-0xC0, 0x7F, 0x12, 0xFF, 0x10, 0xBC, 0x03, 0xC0, 0x0B, 0xC0, 0x7F, 0x20, 0x3B,
-0x00, 0xF8, 0x26, 0xE1, 0x03, 0xC0, 0x27, 0x00, 0x14, 0x00, 0xFC, 0x03, 0xF0,
-0x5F, 0xC0, 0xBD, 0x00, 0xEF, 0x00, 0xFC, 0x81, 0xF1, 0x0F, 0xC0, 0x1F, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x93, 0x04, 0x4C,
-0x13, 0xF0, 0x09, 0xC4, 0x24, 0x00, 0x13, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
-0x24, 0x00, 0xDF, 0x40, 0x4C, 0x03, 0xB0, 0x09, 0xC8, 0x20, 0x40, 0x13, 0x02,
-0x6C, 0x0E, 0xB0, 0x03, 0xC0, 0x37, 0x00, 0x93, 0x06, 0x6C, 0x03, 0xD0, 0x08,
-0xC0, 0x34, 0x80, 0x5F, 0x00, 0x7C, 0x00, 0x30, 0x0D, 0xC0, 0x0B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x30, 0x00, 0x91, 0x00, 0x44, 0x0B,
-0xD0, 0x09, 0x50, 0x64, 0x08, 0x91, 0x00, 0x34, 0x2B, 0xD0, 0x0D, 0x40, 0xB4,
-0x02, 0xFD, 0x06, 0xC5, 0x6F, 0x10, 0x49, 0x54, 0xB4, 0x03, 0x10, 0x24, 0x44,
-0x06, 0x10, 0xB9, 0x45, 0x37, 0x00, 0x91, 0x83, 0x44, 0x03, 0xD1, 0xAD, 0x40,
-0xB4, 0x02, 0xDD, 0x00, 0x74, 0x47, 0x10, 0x1D, 0x43, 0x4F, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x72, 0x00, 0xC1, 0x02, 0x44, 0x8B, 0xD0,
-0x68, 0x40, 0x60, 0x00, 0x05, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x12, 0x20,
-0xCD, 0x02, 0x04, 0x03, 0x90, 0x09, 0x48, 0xF0, 0x10, 0x11, 0x20, 0x04, 0x4A,
-0x92, 0x10, 0x40, 0x23, 0x20, 0x09, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x36,
-0x10, 0xC5, 0x08, 0x34, 0x04, 0x10, 0x0C, 0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x40, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x9E,
-0x40, 0x68, 0x04, 0x25, 0x01, 0xB4, 0x07, 0xD1, 0x1A, 0x50, 0x58, 0x00, 0xCD,
-0x89, 0x84, 0x07, 0x10, 0x9A, 0x40, 0x78, 0x00, 0x31, 0x29, 0x85, 0x04, 0x10,
-0x12, 0x40, 0x6B, 0x08, 0xA9, 0x01, 0x84, 0x07, 0xD0, 0x16, 0x50, 0x7A, 0x80,
-0xED, 0x41, 0xB4, 0x05, 0x10, 0x1E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x10, 0x30, 0x04, 0x53, 0x00, 0x0E, 0x03, 0xF0, 0x08, 0xD0,
-0xA4, 0x40, 0x07, 0x08, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x02, 0xCF, 0x00,
-0x0C, 0x03, 0xB0, 0x08, 0xC0, 0x30, 0x00, 0x03, 0x4A, 0x6C, 0x02, 0xB0, 0x00,
-0xC0, 0x33, 0x41, 0xCB, 0x10, 0x2C, 0x23, 0xF0, 0x0C, 0xD0, 0x32, 0x02, 0xCF,
-0x00, 0x3C, 0x00, 0x34, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0xB8, 0x39, 0x00, 0xFF, 0x00, 0xFD, 0x03, 0xF0, 0x0B, 0xC0, 0x2F,
-0x10, 0x7B, 0x00, 0xFC, 0x03, 0xF8, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
-0x03, 0xF0, 0x0B, 0xC4, 0x3B, 0x00, 0x3F, 0x28, 0xFC, 0x00, 0xF0, 0x0F, 0xC0,
-0x3F, 0x00, 0xF7, 0x00, 0xFC, 0x83, 0xF0, 0x0F, 0xD0, 0x3D, 0x00, 0xFF, 0x08,
-0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0xA0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x49, 0xD0, 0x2C, 0x00,
-0x33, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0xDF, 0x04, 0x5C, 0x4F,
-0x30, 0x09, 0xC0, 0xB5, 0x00, 0x13, 0x00, 0x6C, 0x02, 0xF2, 0x01, 0xC0, 0xA7,
-0x01, 0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C,
-0x00, 0xF0, 0x0D, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x88, 0x39, 0x00, 0xAD, 0x40, 0xB4, 0x03, 0xD0, 0x8C, 0x44, 0x28, 0x00, 0x2B,
-0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xCD, 0x0E, 0x04, 0x03, 0x10,
-0x0E, 0x40, 0x30, 0x02, 0x61, 0x00, 0x86, 0x00, 0xD0, 0x02, 0x44, 0x23, 0x04,
-0xF1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x00, 0xB4, 0x01,
-0xD0, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
-0x79, 0x00, 0xAD, 0x01, 0xB4, 0x07, 0xD0, 0x1A, 0x40, 0x60, 0x00, 0xA1, 0x41,
-0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x05, 0x94, 0x37, 0x10, 0x3B,
-0x40, 0x79, 0x08, 0x29, 0x11, 0x84, 0x06, 0xD0, 0x12, 0x40, 0xFB, 0x00, 0xE1,
-0x81, 0x94, 0x87, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x05, 0xD0,
-0x1E, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33,
-0x10, 0x8D, 0x09, 0x34, 0x03, 0xD0, 0x9C, 0x50, 0x70, 0x00, 0xC9, 0x06, 0x34,
-0x03, 0xD0, 0x3C, 0x40, 0xB3, 0x04, 0xCD, 0x00, 0x04, 0x03, 0x14, 0x1C, 0x40,
-0x30, 0xC0, 0x99, 0x06, 0x05, 0x01, 0xD1, 0x0C, 0x44, 0x73, 0x20, 0xC1, 0x03,
-0x04, 0x03, 0xD1, 0x0D, 0x41, 0x63, 0x00, 0xCD, 0x06, 0x34, 0x07, 0xD0, 0x0C,
-0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00,
-0x7F, 0x02, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x58, 0x01, 0x73, 0x02, 0x7C, 0x01,
-0xF0, 0x16, 0xC0, 0x9F, 0x10, 0x5F, 0x00, 0x5C, 0x01, 0x30, 0x04, 0xC4, 0x15,
-0x00, 0x7B, 0x00, 0xCC, 0x45, 0xF1, 0x07, 0xC0, 0x17, 0x48, 0x73, 0x05, 0x5C,
-0x01, 0xF0, 0x27, 0xC0, 0x57, 0x00, 0x7F, 0x02, 0xFC, 0x05, 0xF0, 0x05, 0xC0,
-0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F,
-0x00, 0x7C, 0x00, 0xF0, 0x01, 0xD0, 0x07, 0x10, 0x1F, 0x00, 0x7C, 0x00, 0xF0,
-0x81, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x00,
-0x17, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x00,
-0xF0, 0x01, 0xC0, 0x07, 0x12, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x4B,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x11,
-0x4C, 0x22, 0xF0, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x02, 0x7C, 0x02, 0xF0, 0x09,
-0xC1, 0x20, 0x00, 0x83, 0x00, 0x6D, 0x0E, 0xF0, 0x59, 0xC0, 0x20, 0x00, 0x91,
-0x40, 0x4C, 0x02, 0x10, 0x89, 0xC0, 0x24, 0x00, 0x83, 0x08, 0x4C, 0x02, 0xF0,
-0x19, 0xC0, 0x64, 0x01, 0x90, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x43, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6, 0x02, 0x91, 0x01, 0x44,
-0x06, 0xD0, 0x39, 0x41, 0x64, 0x10, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x50,
-0x24, 0x40, 0x91, 0x40, 0x44, 0x02, 0xD0, 0x19, 0x44, 0xE4, 0x40, 0x91, 0x01,
-0x04, 0x02, 0x15, 0x08, 0x40, 0x20, 0x00, 0x9B, 0x03, 0x44, 0x02, 0xD0, 0x19,
-0x40, 0x20, 0x20, 0x91, 0x09, 0x34, 0x02, 0x10, 0x19, 0x40, 0x07, 0x00, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x20, 0x44, 0xC1, 0x04, 0x45, 0x02,
-0xD0, 0x49, 0x40, 0x24, 0x01, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x50, 0x34,
-0x10, 0x99, 0x00, 0x65, 0x02, 0xC0, 0x09, 0x40, 0x24, 0x01, 0x95, 0x04, 0x44,
-0x12, 0x51, 0x29, 0x50, 0x24, 0x20, 0x91, 0x00, 0x44, 0x02, 0xD0, 0x49, 0x50,
-0x24, 0x40, 0xDD, 0x80, 0x74, 0x12, 0x10, 0x89, 0x40, 0x63, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x04, 0x04, 0x02, 0xD0,
-0x48, 0x40, 0x20, 0x01, 0x81, 0x04, 0x34, 0x02, 0xD0, 0x49, 0x40, 0x20, 0x01,
-0x89, 0x04, 0x04, 0x13, 0xD0, 0x08, 0x40, 0x60, 0x81, 0x85, 0x20, 0x46, 0x12,
-0x50, 0x48, 0x40, 0x24, 0x01, 0xC9, 0x04, 0x04, 0x02, 0xD0, 0x48, 0x40, 0x24,
-0x00, 0x8D, 0x04, 0x74, 0x02, 0x14, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x13, 0x0A, 0x4C, 0x29, 0xF0, 0x01,
-0xC0, 0x84, 0x02, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1B,
-0x00, 0x6C, 0x00, 0xD2, 0xA1, 0xC0, 0x04, 0x20, 0x07, 0x2A, 0x4C, 0x28, 0x70,
-0x01, 0xD0, 0x84, 0x42, 0x13, 0x0A, 0x4D, 0x28, 0xF0, 0xA1, 0xC0, 0x84, 0x02,
-0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xD0,
-0x2F, 0x42, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xD0, 0x2F, 0x02, 0x97, 0x08,
-0x7C, 0x22, 0xF0, 0x0A, 0xD0, 0x2F, 0x22, 0xBB, 0x00, 0xFD, 0x22, 0xB0, 0x8B,
-0xD0, 0x2F, 0x02, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xC0, 0x2F, 0x10, 0xB3,
-0x08, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA0, 0x2F, 0x00, 0xB7, 0x0C, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2C,
-0x02, 0xB3, 0x04, 0x3C, 0x02, 0xF0, 0x49, 0xC0, 0x24, 0x00, 0x9F, 0x01, 0xCC,
-0x16, 0x30, 0x0A, 0xC0, 0x6C, 0x28, 0xBF, 0x00, 0xCC, 0x1E, 0x30, 0x5B, 0xC0,
-0x6F, 0x41, 0xB3, 0x05, 0xCC, 0x02, 0xF0, 0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00,
-0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1C, 0x08, 0x07, 0x01, 0x11, 0x0C, 0x6C, 0x40, 0xD0, 0x01, 0x40, 0x04, 0x02,
-0x11, 0x00, 0x74, 0x00, 0xD0, 0x81, 0x40, 0x84, 0x10, 0x3D, 0x02, 0x45, 0x08,
-0xB0, 0x51, 0x40, 0x04, 0x00, 0x1D, 0x15, 0x45, 0x14, 0x10, 0x01, 0x40, 0xC3,
-0x15, 0x11, 0x14, 0x44, 0x10, 0xD1, 0xC1, 0x40, 0x04, 0x04, 0x11, 0x00, 0x74,
-0x00, 0xD0, 0x01, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA0, 0x23, 0x05, 0x85, 0x04, 0x04, 0x12, 0xD0, 0x88, 0x40, 0x70, 0x60, 0x81,
-0x08, 0xB4, 0x02, 0xD0, 0x1A, 0x50, 0x6A, 0x02, 0xAD, 0x02, 0x04, 0x22, 0x10,
-0x08, 0x61, 0xA0, 0x00, 0x8D, 0x81, 0x04, 0x1A, 0x90, 0x38, 0x40, 0x23, 0x42,
-0x81, 0x06, 0x04, 0x52, 0xD1, 0x58, 0x40, 0x20, 0x41, 0xC1, 0x08, 0x34, 0x06,
-0xD0, 0x0C, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
-0x21, 0x00, 0x91, 0x10, 0x64, 0x02, 0xD0, 0x89, 0x10, 0x20, 0x01, 0x91, 0x04,
-0x74, 0x02, 0xD0, 0x0B, 0x40, 0x2E, 0x01, 0xBD, 0x00, 0x44, 0x02, 0x90, 0x09,
-0x60, 0x24, 0x00, 0x9D, 0x40, 0x44, 0x02, 0x90, 0x09, 0x40, 0x27, 0x20, 0x91,
-0x04, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x30, 0x00, 0x91, 0x11, 0x74, 0x02, 0xD0,
-0x09, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25,
-0x00, 0x97, 0x00, 0x4C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C,
-0x02, 0xF0, 0x09, 0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xD0,
-0x24, 0x20, 0x9F, 0x02, 0x4C, 0x06, 0xB0, 0x29, 0xE0, 0x67, 0x02, 0x93, 0x04,
-0x4D, 0x02, 0xF0, 0x19, 0xD0, 0x64, 0x00, 0x93, 0x03, 0x7C, 0x02, 0xF2, 0x09,
-0xD0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x01, 0x7C, 0x02,
-0xF0, 0x98, 0xC0, 0x25, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x09, 0x7C, 0x0E, 0x70, 0x89, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x39, 0xC0, 0xE7, 0x00, 0x9F, 0x40, 0x7C, 0x12, 0xF0, 0x09, 0xC0,
-0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x0F,
-0x03, 0x4D, 0x04, 0xF0, 0x11, 0xC0, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30,
-0x11, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x2C, 0x00, 0xF8, 0x01, 0xC1, 0x06, 0x04,
-0x13, 0x00, 0x0C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x02, 0x13, 0x02, 0x7C, 0x00,
-0xF0, 0x41, 0xC0, 0x44, 0x02, 0x13, 0x02, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x53,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xDC, 0x00, 0x7D, 0x01,
-0xC4, 0x15, 0x70, 0x16, 0x40, 0x9C, 0x00, 0x51, 0x01, 0x74, 0x01, 0x14, 0x05,
-0x40, 0x57, 0x00, 0x41, 0x00, 0xC4, 0x41, 0xD0, 0x07, 0x40, 0x1C, 0x20, 0x51,
-0x04, 0xC4, 0x09, 0xD1, 0x57, 0x40, 0x14, 0x10, 0x7B, 0x00, 0x74, 0x01, 0xD0,
-0x37, 0x40, 0x1C, 0x00, 0x51, 0x00, 0x45, 0x01, 0xD0, 0x04, 0x40, 0x53, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x04, 0xCD, 0x01, 0x04,
-0x03, 0x50, 0x1C, 0x40, 0xB1, 0x04, 0x81, 0x01, 0x34, 0x03, 0x10, 0x0C, 0x40,
-0x73, 0x00, 0xC1, 0x00, 0x24, 0x13, 0xD0, 0x2D, 0x40, 0x72, 0x00, 0xD1, 0x40,
-0x04, 0x2A, 0x58, 0x7C, 0x40, 0x34, 0x00, 0xD1, 0x00, 0x34, 0x27, 0xD0, 0x0D,
-0x40, 0x30, 0x00, 0x81, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x53, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x04, 0xFD, 0x10, 0x84, 0x03,
-0x50, 0x06, 0x41, 0x29, 0x01, 0xA1, 0x10, 0xB4, 0x05, 0x10, 0x0E, 0x40, 0x53,
-0x04, 0x01, 0x00, 0x84, 0x00, 0xD0, 0x0B, 0x40, 0x4A, 0xC4, 0xA1, 0x00, 0x84,
-0x05, 0xD0, 0x12, 0x40, 0x38, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x2E, 0x40,
-0x38, 0x00, 0xC1, 0x01, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x17, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70,
-0x10, 0xC0, 0xFD, 0x40, 0xE3, 0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC0, 0x7B, 0x40,
-0xE3, 0x01, 0xAC, 0x04, 0xD0, 0x1A, 0xC0, 0x42, 0x00, 0xA3, 0x01, 0x8D, 0x02,
-0x78, 0x10, 0xC0, 0x78, 0x04, 0xE3, 0x01, 0xBC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C,
-0x00, 0xE1, 0x01, 0x8C, 0x07, 0xF0, 0x1A, 0xC0, 0x57, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0x70, 0x01,
-0xD0, 0x26, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x17, 0x00, 0x1F,
-0x00, 0x7C, 0x00, 0xF0, 0x09, 0xC0, 0x05, 0x00, 0x8F, 0x02, 0xFC, 0x00, 0xF0,
-0x01, 0xD0, 0xB7, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xD0, 0x37, 0x50,
-0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0xA0, 0x6B, 0x00, 0xF3, 0x01, 0xCC, 0x23, 0xB4, 0x13, 0xC0,
-0x6C, 0x20, 0xF3, 0x01, 0xCC, 0x07, 0xF0, 0x16, 0xC0, 0x6C, 0x00, 0xF3, 0x01,
-0xBC, 0x04, 0x30, 0x1F, 0xD0, 0x4D, 0x00, 0xF3, 0x03, 0xCC, 0x24, 0xF0, 0x13,
-0xC0, 0x7F, 0x08, 0xF3, 0x01, 0xDC, 0x06, 0x30, 0x1F, 0xC0, 0x7C, 0x10, 0xF3,
-0x81, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0x80, 0xB9, 0x00, 0x71, 0x02, 0x84, 0x03, 0x10, 0x02, 0x40, 0x28,
-0x00, 0xE1, 0x00, 0xAC, 0x01, 0xC0, 0x06, 0xC0, 0x08, 0x00, 0x21, 0x00, 0x84,
-0x08, 0x00, 0x4B, 0x40, 0x08, 0x01, 0xA5, 0x04, 0x94, 0x00, 0xD0, 0x02, 0xC0,
-0x39, 0x00, 0xE5, 0x02, 0xC4, 0x02, 0x50, 0x0E, 0x40, 0x1C, 0x00, 0xE1, 0x14,
-0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x08, 0x09, 0x00, 0xE1, 0x00, 0x84, 0x22, 0x18, 0x02, 0x41, 0x38, 0x00,
-0xA1, 0x10, 0x84, 0x03, 0xD0, 0x26, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x94, 0x00,
-0x10, 0x0A, 0x45, 0x09, 0x20, 0xE1, 0x80, 0x84, 0x08, 0xD8, 0x02, 0x40, 0x33,
-0x00, 0xE1, 0x00, 0x94, 0x02, 0x10, 0x0C, 0x40, 0x38, 0x00, 0xE1, 0x00, 0xB4,
-0x0B, 0xD0, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
-0x28, 0x13, 0x00, 0x41, 0x00, 0x44, 0x02, 0x14, 0x00, 0x40, 0x20, 0x02, 0x81,
-0x01, 0x24, 0x01, 0xD0, 0x04, 0x40, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x14,
-0x18, 0x40, 0x40, 0x0A, 0x81, 0x53, 0x14, 0x04, 0xD0, 0x30, 0x40, 0x31, 0x20,
-0xC5, 0x02, 0x04, 0x02, 0x50, 0x2C, 0x40, 0x50, 0x00, 0xC1, 0x00, 0x34, 0x23,
-0xD0, 0x0C, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8,
-0x21, 0x00, 0xD3, 0x02, 0x4C, 0x03, 0x34, 0x01, 0xD0, 0x1C, 0x50, 0x83, 0x03,
-0x4D, 0x02, 0xF0, 0x09, 0xC0, 0x74, 0x40, 0xD3, 0x00, 0x5C, 0x00, 0x30, 0x1D,
-0xC8, 0x45, 0xE0, 0x93, 0x05, 0x0C, 0x12, 0xF0, 0x69, 0xC0, 0x37, 0x00, 0xD3,
-0x02, 0x5C, 0x02, 0x31, 0x0D, 0xC4, 0x74, 0x24, 0xD3, 0x80, 0x7C, 0x07, 0xF0,
-0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA7,
-0x40, 0xDF, 0x42, 0x7C, 0x03, 0x70, 0x01, 0xC0, 0x97, 0x08, 0x9F, 0x10, 0x5C,
-0x00, 0xF0, 0x09, 0xC0, 0x51, 0x00, 0x1F, 0x00, 0x5C, 0x08, 0xF0, 0x0D, 0xC0,
-0x83, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x37, 0x00, 0xDF, 0x00,
-0x7C, 0x02, 0xF0, 0x75, 0xD0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D,
-0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x6F, 0x21,
-0xB3, 0x90, 0xCC, 0x03, 0x30, 0x00, 0xC0, 0x1C, 0x00, 0xDF, 0x00, 0xCC, 0x06,
-0xF0, 0x0B, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x8C, 0x04, 0x30, 0x4B, 0xC8, 0x04,
-0x00, 0xBD, 0x05, 0xFC, 0x02, 0x10, 0x03, 0xC1, 0x7B, 0x00, 0x33, 0x19, 0xCC,
-0x02, 0xF0, 0x0A, 0xC0, 0x2C, 0x00, 0xF1, 0x10, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x40, 0x91,
-0x02, 0x44, 0x07, 0x10, 0x11, 0x40, 0x94, 0x02, 0xDD, 0x00, 0x44, 0x00, 0xD0,
-0x08, 0x40, 0x14, 0x00, 0x01, 0x00, 0x44, 0x00, 0x10, 0x49, 0x40, 0xC4, 0x00,
-0x91, 0x00, 0x64, 0x04, 0x10, 0x11, 0x40, 0x37, 0x12, 0xD5, 0x03, 0x44, 0x06,
-0xD0, 0x11, 0x50, 0xA4, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x07,
-0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x00, 0xC1, 0x01,
-0x44, 0x07, 0x92, 0x11, 0x40, 0xA4, 0x00, 0xDD, 0x00, 0x44, 0x22, 0x50, 0x11,
-0x40, 0x24, 0x00, 0xD1, 0x00, 0x44, 0x20, 0x14, 0x04, 0x40, 0x44, 0x04, 0x91,
-0x00, 0x74, 0x04, 0xD0, 0x11, 0x44, 0x27, 0x00, 0xC1, 0x00, 0x44, 0x12, 0xD0,
-0x4D, 0x51, 0x70, 0x00, 0xD5, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x48, 0x07, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC1, 0x00, 0x04,
-0x07, 0x90, 0x10, 0x50, 0x20, 0x00, 0xCD, 0x00, 0x05, 0x00, 0xD0, 0x00, 0x40,
-0x00, 0x40, 0x01, 0x00, 0x06, 0x00, 0x50, 0x04, 0x40, 0x00, 0x00, 0x81, 0x00,
-0x64, 0x00, 0xD0, 0x00, 0x00, 0x23, 0x40, 0xC5, 0x20, 0x04, 0x02, 0xD0, 0x0C,
-0x48, 0x30, 0x00, 0xC5, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x43, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x26, 0x00, 0xD3, 0x40, 0x4C, 0x03,
-0xB4, 0x01, 0xC0, 0x30, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x70, 0x01, 0xC0, 0x24,
-0x20, 0xD3, 0x00, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00, 0xAB, 0x00, 0x7C,
-0x00, 0xF4, 0x01, 0xC8, 0x2F, 0x40, 0x03, 0x00, 0x4D, 0x02, 0xF0, 0x0D, 0xC0,
-0x34, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x80, 0x03, 0xC0, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x2F, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0x70,
-0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
-0x3F, 0x00, 0xFC, 0x00, 0x91, 0x03, 0xC0, 0x0F, 0x10, 0xBB, 0x00, 0xEC, 0x00,
-0x30, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F,
-0x00, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xA3, 0x80, 0xC0, 0x0E, 0x02, 0x3A, 0x08, 0xE8, 0x28,
-0xB8, 0xA3, 0xC0, 0x8E, 0x02, 0x3A, 0x08, 0xEC, 0x28, 0xA0, 0x83, 0xE0, 0x8E,
-0x82, 0x3B, 0x0A, 0xEC, 0x28, 0xA8, 0x83, 0xC0, 0x8E, 0x82, 0x3B, 0x0E, 0xE6,
-0x28, 0xA0, 0x83, 0xE0, 0x8E, 0x82, 0x3B, 0x0A, 0xEC, 0x20, 0xB8, 0x83, 0xE0,
-0x0E, 0x82, 0x3A, 0x0A, 0xEE, 0x20, 0xB0, 0x03, 0x8C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x83, 0x22, 0x20, 0x8E, 0x80, 0x3B, 0x02, 0xCA, 0x08, 0xA8,
-0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xE8, 0x08, 0xA8, 0x23, 0xE0, 0x8E, 0x00,
-0x13, 0x02, 0xE8, 0x08, 0xA8, 0x23, 0xA0, 0x84, 0x00, 0x3B, 0x02, 0xEC, 0x08,
-0x28, 0x23, 0xE0, 0x8A, 0x00, 0x39, 0x02, 0xE8, 0x08, 0xBA, 0x23, 0x40, 0x84,
-0x80, 0x3B, 0x00, 0xEE, 0x08, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x21, 0x40, 0x80, 0x04, 0x01, 0x12, 0x04, 0x40, 0x10, 0x20, 0x41,
-0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x84, 0x01, 0x12,
-0x06, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x00,
-0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01,
-0x12, 0x04, 0x48, 0x10, 0x20, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x83, 0x00, 0x80, 0x0E, 0x00, 0x1A, 0x00, 0x6A, 0x08, 0xA2, 0x61, 0x80,
-0x86, 0xA0, 0x1A, 0x00, 0x28, 0x08, 0xA8, 0x01, 0x80, 0x06, 0x00, 0x1A, 0x80,
-0x68, 0x08, 0xAA, 0x01, 0x80, 0x86, 0x01, 0x1A, 0x00, 0x68, 0x08, 0xA8, 0x00,
-0x80, 0x86, 0x00, 0x3A, 0x02, 0x68, 0x00, 0xA0, 0x01, 0x80, 0x0E, 0x00, 0x0A,
-0x04, 0x60, 0x00, 0xA0, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xA0, 0x12, 0xA0, 0x4E, 0x80, 0x3A, 0x01, 0xEA, 0x04, 0xA0, 0x13, 0xA0, 0x4E,
-0x81, 0x3A, 0x01, 0xE8, 0x04, 0xA8, 0x13, 0xA0, 0xCE, 0x80, 0x3A, 0x01, 0xE8,
-0x34, 0xA8, 0x13, 0xA0, 0xCE, 0x80, 0x3A, 0x01, 0xEA, 0x04, 0xA8, 0x13, 0xA0,
-0x4E, 0x80, 0x2A, 0x01, 0xA8, 0x04, 0xA8, 0x12, 0xA0, 0x4E, 0x80, 0x32, 0x01,
-0xEA, 0x04, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3,
-0x02, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x06, 0x00,
-0x18, 0x01, 0x62, 0x00, 0x80, 0x81, 0x00, 0x06, 0x01, 0x18, 0x00, 0x42, 0x00,
-0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x08, 0x60, 0x10, 0x80, 0x01, 0x00, 0x06,
-0x03, 0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60,
-0x00, 0x80, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x82,
-0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x14, 0x00, 0x10, 0x20, 0x84, 0x80, 0x10,
-0x08, 0x42, 0x10, 0x08, 0x11, 0x20, 0x04, 0x80, 0x10, 0x0C, 0x42, 0x08, 0x08,
-0x11, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x11, 0x20, 0x04, 0x80,
-0x10, 0x04, 0x42, 0x04, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x01, 0x42, 0x04,
-0x08, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xF2, 0xA0,
-0x02, 0x03, 0x0A, 0x04, 0x28, 0x1C, 0xAA, 0x50, 0xA0, 0x02, 0x01, 0x0A, 0x06,
-0x2A, 0x10, 0xA0, 0xD0, 0x80, 0x02, 0x01, 0x0A, 0x04, 0x0A, 0x30, 0xA0, 0x50,
-0xA0, 0x02, 0x01, 0x0A, 0x0E, 0x28, 0x10, 0xA0, 0x50, 0x80, 0x82, 0x01, 0x0A,
-0x04, 0x2A, 0x14, 0xA0, 0x40, 0x80, 0x02, 0x01, 0x2A, 0x05, 0x28, 0x3C, 0xA8,
-0x00, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x80, 0xC8,
-0x00, 0xA2, 0x03, 0xA8, 0x2E, 0xA0, 0x32, 0x80, 0xEA, 0x00, 0xAA, 0x03, 0x08,
-0x0C, 0xA0, 0x3A, 0x80, 0x6A, 0x00, 0x82, 0x01, 0x08, 0x0C, 0x20, 0x3A, 0x80,
-0x6A, 0x00, 0x82, 0x03, 0x08, 0x0C, 0xA0, 0x3A, 0x80, 0xEA, 0x01, 0xA2, 0x03,
-0x08, 0x0E, 0xA0, 0x3A, 0x80, 0xE0, 0x00, 0xAA, 0x03, 0x08, 0x1C, 0x20, 0x02,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x08, 0x80,
-0x30, 0x01, 0x20, 0x18, 0x80, 0x00, 0x00, 0xC2, 0x01, 0x08, 0x02, 0x00, 0x04,
-0x80, 0x00, 0x00, 0x82, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x02, 0x00, 0x82,
-0x00, 0x10, 0x06, 0x00, 0x04, 0x80, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x80, 0x00, 0x00, 0x44, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x82, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x16, 0x40, 0x18, 0x00, 0x61,
-0x00, 0x04, 0x21, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x01, 0x06, 0x01, 0x10,
-0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x10, 0x06, 0x40, 0x10, 0x80,
-0x41, 0x00, 0x06, 0x01, 0x10, 0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01,
-0x10, 0x04, 0x60, 0x14, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x82, 0x8C, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xA0, 0x06, 0x80, 0x9A, 0x00,
-0x6D, 0x02, 0xA0, 0x01, 0xA0, 0x26, 0x40, 0x9B, 0x00, 0x4A, 0x00, 0xB0, 0x09,
-0x88, 0x26, 0x80, 0x92, 0x00, 0x48, 0x00, 0x80, 0x09, 0xA0, 0x26, 0x40, 0x92,
-0x00, 0x48, 0x00, 0xB0, 0x09, 0x80, 0x26, 0x80, 0x9A, 0x00, 0x4A, 0x02, 0xA8,
-0x09, 0xA0, 0x24, 0x80, 0x9B, 0x00, 0x4A, 0x00, 0xA8, 0x01, 0x8C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xC0, 0x06, 0x00, 0x1A, 0x01, 0x68,
-0x00, 0xB0, 0x01, 0xC0, 0x46, 0x80, 0x1A, 0x00, 0x6E, 0x04, 0xA8, 0x01, 0xC0,
-0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xB0, 0x01, 0xE0, 0x06, 0x80, 0x1B, 0x00,
-0x6E, 0x04, 0xA8, 0x01, 0xC8, 0x06, 0x00, 0x1A, 0x00, 0x6E, 0x00, 0xB0, 0x01,
-0xE0, 0x46, 0x80, 0x1A, 0x00, 0x6E, 0x00, 0xB0, 0x01, 0x8C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xA3, 0x42, 0x20, 0x0C, 0x81, 0x31, 0x0C, 0x82, 0x10,
-0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x20, 0x0C,
-0x01, 0x30, 0x0C, 0xC2, 0x30, 0x10, 0x43, 0x20, 0x0C, 0x03, 0x30, 0x0C, 0xC0,
-0x30, 0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x0C, 0xC0, 0x10, 0x08, 0x43, 0x00,
-0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00,
-0x03, 0x00, 0x0C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x4C, 0x00,
-0x30, 0x01, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00,
-0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x13, 0x08, 0x08,
-0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x21, 0x40, 0x80, 0x4C, 0x23, 0x32, 0x04, 0xCA, 0x10, 0x20, 0x43,
-0x80, 0x0C, 0x03, 0x32, 0x0C, 0xCA, 0x10, 0x20, 0x43, 0x88, 0x4C, 0x23, 0x32,
-0x05, 0xC8, 0x14, 0x20, 0x43, 0x80, 0x4C, 0x81, 0x32, 0x05, 0xCA, 0x10, 0x20,
-0x43, 0x80, 0x48, 0x03, 0x32, 0x05, 0x88, 0x10, 0x20, 0xD3, 0xA0, 0x0C, 0x03,
-0x32, 0x04, 0xCA, 0x10, 0x20, 0x03, 0x84, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA2, 0x42, 0xA0, 0x06, 0x83, 0x3A, 0x04, 0x6A, 0x10, 0xA8, 0x41, 0xA0,
-0x06, 0x83, 0x1A, 0x0C, 0x4A, 0x30, 0xA8, 0x41, 0xA0, 0x06, 0x81, 0x1A, 0x0C,
-0x4A, 0x30, 0xA8, 0x41, 0x80, 0x0E, 0x83, 0x1A, 0x0C, 0x4A, 0x30, 0x88, 0x41,
-0xA0, 0x06, 0x01, 0x0A, 0x0C, 0x08, 0x10, 0xA8, 0x41, 0xA0, 0x06, 0x83, 0x1A,
-0x04, 0x6A, 0x10, 0xA8, 0x01, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xA3, 0x40, 0x00, 0x04, 0x01, 0x18, 0x04, 0xC0, 0x10, 0x00, 0x41, 0x00, 0x04,
-0x01, 0x20, 0x04, 0x40, 0x10, 0x00, 0x42, 0x00, 0x00, 0x01, 0x10, 0x04, 0x40,
-0x10, 0x80, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x00, 0x10, 0x00, 0x43, 0x00,
-0x00, 0x81, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x30, 0x04,
-0x40, 0x10, 0x00, 0x01, 0x8C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3,
-0x4A, 0x20, 0x2C, 0x81, 0x10, 0x0C, 0x82, 0x12, 0x88, 0x41, 0x20, 0x26, 0x81,
-0xB0, 0x04, 0x42, 0x10, 0x08, 0x43, 0x20, 0x26, 0x83, 0x90, 0x04, 0x02, 0x12,
-0x08, 0x41, 0x00, 0x26, 0x81, 0x90, 0x04, 0x42, 0x10, 0x08, 0x43, 0x20, 0x26,
-0x83, 0x90, 0x04, 0x40, 0x10, 0x88, 0xC9, 0x20, 0x0C, 0x81, 0xB0, 0x04, 0x62,
-0x12, 0x88, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x06,
-0x20, 0x1A, 0x00, 0x62, 0x00, 0x88, 0x01, 0xA8, 0x06, 0xA0, 0x1A, 0x80, 0x62,
-0x00, 0x80, 0x01, 0x28, 0x06, 0xA0, 0x1A, 0x80, 0x42, 0x00, 0x0A, 0x01, 0xA0,
-0x06, 0x80, 0x18, 0x00, 0x6A, 0x00, 0x88, 0x01, 0x28, 0x06, 0xA0, 0x1A, 0x80,
-0x6A, 0x80, 0x08, 0x01, 0xA8, 0x06, 0x80, 0x18, 0x80, 0x62, 0x00, 0xA8, 0x01,
-0x88, 0x02, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80,
-0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06,
-0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60,
-0xA0, 0x82, 0x01, 0x2A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A,
-0x06, 0xAA, 0x18, 0xA0, 0x60, 0x80, 0x8A, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x80, 0x20,
-0x81, 0x02, 0x84, 0x08, 0x12, 0x20, 0x40, 0x80, 0x20, 0x81, 0x82, 0x04, 0x08,
-0x10, 0x20, 0x40, 0x80, 0x20, 0x01, 0x82, 0x04, 0x4A, 0x12, 0x20, 0x40, 0x80,
-0x20, 0x01, 0x82, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x20, 0x01, 0x82, 0x04,
-0x08, 0x10, 0x20, 0x48, 0x80, 0x00, 0x01, 0x82, 0x04, 0x48, 0x12, 0x20, 0x00,
-0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x62, 0xC0, 0x80, 0x01,
-0x03, 0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAE, 0x18,
-0xB0, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAC, 0x18, 0xA0, 0x62, 0xC0, 0x8A,
-0x81, 0x29, 0x06, 0xAE, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xA6,
-0x18, 0xB0, 0x62, 0x60, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x8C,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0x80, 0x8E, 0x01, 0x3A,
-0x06, 0xEE, 0x18, 0xA4, 0x63, 0x80, 0x8E, 0x81, 0x3A, 0x06, 0xE8, 0x18, 0xB0,
-0x63, 0x80, 0x8E, 0x01, 0x3A, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0x80, 0x8E, 0x81,
-0x3A, 0x06, 0xE0, 0x18, 0xB0, 0x63, 0x80, 0x8E, 0x81, 0x3B, 0x06, 0xE8, 0x18,
-0xA8, 0x63, 0x20, 0x8E, 0x81, 0x3B, 0x06, 0xEA, 0x18, 0xA8, 0x03, 0x8C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0xC0, 0x8E, 0x01, 0x3A, 0x06,
-0xE8, 0x18, 0xB0, 0x63, 0xC0, 0x8E, 0x01, 0x3A, 0x06, 0xCC, 0x18, 0xA0, 0x63,
-0xC0, 0x8E, 0x01, 0x3B, 0x86, 0xEA, 0x18, 0x30, 0x63, 0xC0, 0x8E, 0x01, 0x3B,
-0x06, 0xCC, 0x18, 0xA0, 0x63, 0xC0, 0x8E, 0x01, 0x3B, 0x06, 0xEC, 0x18, 0xB0,
-0x63, 0xE0, 0x8E, 0x81, 0x3A, 0x06, 0xEE, 0x18, 0xB0, 0x03, 0x88, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0xA0, 0x8E, 0x81, 0x31, 0x06, 0xC2,
-0x18, 0xA8, 0x63, 0xA0, 0x8E, 0x81, 0x30, 0x06, 0xC2, 0x18, 0x0A, 0x63, 0xA0,
-0x8E, 0x01, 0x10, 0x06, 0xC4, 0x18, 0x30, 0x63, 0x00, 0x8C, 0x21, 0x10, 0x06,
-0xC0, 0x18, 0x08, 0x61, 0xA0, 0x8E, 0xA1, 0x38, 0x86, 0x80, 0x18, 0xA8, 0x63,
-0x00, 0x84, 0x81, 0x38, 0x06, 0xEE, 0x18, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x04, 0x01, 0x1A, 0x04, 0xE8, 0x10,
-0x20, 0x41, 0x80, 0x04, 0x01, 0x3A, 0x04, 0x48, 0x10, 0xA0, 0x43, 0x80, 0x04,
-0x01, 0x12, 0x04, 0x68, 0x10, 0x20, 0x41, 0x00, 0x04, 0x01, 0x12, 0x04, 0x48,
-0x10, 0x20, 0x43, 0x80, 0x04, 0x01, 0x32, 0x04, 0x68, 0x10, 0x20, 0x41, 0x80,
-0x04, 0x01, 0x32, 0x04, 0x48, 0x10, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x86, 0x01, 0x12, 0x06, 0x6A, 0x18, 0xA0,
-0x60, 0x88, 0x86, 0x81, 0x1A, 0x06, 0x48, 0x18, 0xA8, 0x60, 0x00, 0x82, 0x01,
-0x02, 0x86, 0x48, 0x18, 0xA0, 0x61, 0x80, 0x84, 0x01, 0x1A, 0x06, 0x48, 0x18,
-0xA8, 0x61, 0x88, 0x86, 0x01, 0x1A, 0x06, 0x48, 0x18, 0xA0, 0x61, 0x80, 0x84,
-0x01, 0x18, 0x06, 0x68, 0x18, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA2, 0x02, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xCA, 0x00, 0x28, 0x03,
-0xA0, 0x0A, 0x80, 0x32, 0x00, 0xC8, 0x00, 0xA8, 0x02, 0xA0, 0x0C, 0x00, 0x32,
-0x00, 0xC8, 0x00, 0xA8, 0x03, 0xA0, 0x0C, 0x00, 0x32, 0x00, 0xC8, 0x00, 0xA8,
-0x03, 0xA0, 0x0C, 0x00, 0x32, 0x00, 0xE8, 0x00, 0x28, 0x03, 0xA0, 0x0C, 0x80,
-0x32, 0x00, 0xCA, 0x00, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA2, 0x42, 0x00, 0x06, 0x01, 0x18, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00,
-0x06, 0x01, 0x10, 0x0C, 0x42, 0x10, 0x80, 0x41, 0x00, 0x04, 0x83, 0x10, 0x0C,
-0x40, 0x10, 0x80, 0xC1, 0x00, 0x04, 0x83, 0x10, 0x04, 0x42, 0x10, 0x80, 0xC1,
-0x00, 0x04, 0x83, 0x10, 0x0C, 0x42, 0x30, 0x00, 0xC0, 0x00, 0x04, 0x03, 0x10,
-0x04, 0x60, 0x10, 0x80, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xA2, 0x42, 0x20, 0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x04,
-0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x60,
-0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20,
-0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x05,
-0x42, 0x10, 0x08, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2,
-0x42, 0xA0, 0x02, 0x01, 0x0A, 0x0C, 0xA8, 0x30, 0xA8, 0x42, 0xA0, 0x02, 0x03,
-0x2A, 0x04, 0xAA, 0x10, 0xA0, 0xC0, 0xA0, 0x0A, 0x81, 0x2A, 0x84, 0xA0, 0x10,
-0xA0, 0x40, 0xA0, 0x0A, 0x81, 0x2A, 0x0C, 0xAA, 0x10, 0xA0, 0x40, 0xA8, 0x0A,
-0x81, 0x2A, 0x04, 0x2A, 0x10, 0xA8, 0x42, 0xA0, 0x0A, 0x81, 0x2A, 0x0C, 0xA8,
-0x10, 0xA8, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-0x80, 0x0A, 0x01, 0x2A, 0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x03, 0x2A,
-0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x04, 0xA8, 0x30, 0xA0,
-0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01,
-0x2A, 0x04, 0xA8, 0x30, 0xA0, 0x42, 0x80, 0x0A, 0x03, 0x2A, 0x05, 0xA8, 0x30,
-0xA0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00,
-0x42, 0x80, 0x08, 0x00, 0x20, 0x00, 0x80, 0x10, 0x00, 0x02, 0x80, 0x08, 0x00,
-0x20, 0x04, 0x82, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x22, 0x04, 0x80, 0x00,
-0x00, 0x02, 0x20, 0x08, 0x00, 0x20, 0x04, 0x80, 0x00, 0x00, 0x02, 0x20, 0x08,
-0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x60, 0x04, 0x80,
-0x01, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x40, 0x00,
-0x01, 0x01, 0x05, 0x04, 0x14, 0x10, 0x40, 0x40, 0x40, 0x01, 0x01, 0x0C, 0x44,
-0x10, 0x10, 0x50, 0x40, 0x00, 0x81, 0x01, 0x04, 0x00, 0x30, 0x00, 0x50, 0x00,
-0x00, 0x81, 0x01, 0x0C, 0x06, 0x10, 0x10, 0x50, 0x40, 0x00, 0x01, 0x01, 0x04,
-0x46, 0x14, 0x10, 0x40, 0x60, 0x44, 0x01, 0x01, 0x04, 0x04, 0x30, 0x10, 0x00,
-0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0xA0, 0x06, 0x80,
-0x1A, 0x00, 0x6E, 0x00, 0xA8, 0x01, 0x80, 0x06, 0x80, 0x1A, 0x00, 0x6A, 0x00,
-0xB8, 0x01, 0xA0, 0x06, 0x80, 0x1A, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0xA0, 0x06,
-0x80, 0x1A, 0x00, 0x68, 0x00, 0xB0, 0x01, 0x80, 0x06, 0x80, 0x1A, 0x00, 0x6A,
-0x00, 0xA8, 0x01, 0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0x88,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xC0, 0x06, 0x00, 0x12,
-0x00, 0xE8, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x80, 0x3A, 0x00, 0x4C, 0x00, 0xA0,
-0x03, 0xC0, 0x06, 0x80, 0x13, 0x00, 0x4E, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00,
-0x13, 0x00, 0x6E, 0x00, 0xA0, 0x03, 0xC0, 0x06, 0x00, 0x1B, 0x00, 0x4C, 0x00,
-0xB0, 0x01, 0xC0, 0x04, 0x00, 0x3A, 0x00, 0x6E, 0x00, 0xB0, 0x01, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x80, 0x11, 0x00,
-0x62, 0x00, 0x08, 0x02, 0x20, 0x0C, 0x80, 0x18, 0x00, 0x42, 0x00, 0x8A, 0x01,
-0x20, 0x0C, 0x02, 0x10, 0x00, 0x44, 0x00, 0x10, 0x01, 0x00, 0x0C, 0x02, 0x10,
-0x00, 0x40, 0x00, 0x80, 0x01, 0x20, 0x0C, 0x00, 0x10, 0x00, 0x40, 0x00, 0x08,
-0x83, 0x00, 0x04, 0x80, 0x18, 0x00, 0xC2, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x90, 0x00, 0x40,
-0x02, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x90, 0x12, 0x40, 0x02, 0x00, 0x21, 0x00,
-0xA8, 0x01, 0x90, 0x12, 0x40, 0x02, 0x00, 0x21, 0x02, 0xAC, 0x08, 0x90, 0x22,
-0x40, 0x02, 0x00, 0x21, 0x00, 0xAC, 0x05, 0x90, 0x22, 0x40, 0x08, 0x00, 0x2B,
-0x02, 0xA4, 0x00, 0x90, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x8C, 0x00, 0x32, 0x0A, 0xCA, 0x28,
-0x22, 0xA3, 0x80, 0x8C, 0x02, 0x32, 0x06, 0x48, 0x28, 0x28, 0xA2, 0x88, 0x8C,
-0x82, 0x12, 0x00, 0x48, 0x08, 0x20, 0xA1, 0x80, 0x8C, 0x03, 0x32, 0x00, 0x48,
-0x28, 0x28, 0xA2, 0x80, 0x8C, 0x00, 0x22, 0x06, 0x08, 0x38, 0x20, 0xA3, 0x80,
-0x84, 0x82, 0x32, 0x02, 0xCA, 0x08, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xC4, 0xA0, 0x16, 0x83, 0x5A, 0x0C, 0x4A, 0x31, 0xA8,
-0xC5, 0xA0, 0x16, 0x83, 0x5A, 0x0E, 0x68, 0x31, 0xA8, 0x85, 0xA0, 0x16, 0x83,
-0x5A, 0x0C, 0x60, 0x31, 0xA8, 0x85, 0xA0, 0x16, 0x03, 0x5A, 0x0C, 0x6A, 0x31,
-0xA8, 0xC5, 0xA0, 0x16, 0x03, 0x58, 0x0E, 0x28, 0x31, 0xA8, 0xE4, 0x80, 0x12,
-0x82, 0x5A, 0x0C, 0x6A, 0x31, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x90, 0x01, 0x40, 0x06, 0x00, 0x09,
-0x00, 0x64, 0x00, 0x90, 0x00, 0x42, 0x02, 0x00, 0x91, 0x00, 0xA4, 0x00, 0x90,
-0x00, 0x40, 0x02, 0x00, 0x91, 0x00, 0xA4, 0x80, 0x90, 0x08, 0x40, 0x02, 0x00,
-0x31, 0x00, 0xA4, 0x80, 0x80, 0x00, 0x42, 0x0C, 0x00, 0x09, 0x20, 0x64, 0x02,
-0x90, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x22, 0x42, 0x88, 0x18, 0x20, 0x42, 0x80, 0x88, 0x11, 0x22,
-0x06, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20,
-0x60, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x21,
-0x26, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x21, 0x22, 0x06, 0x88, 0x18,
-0x20, 0x62, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA2, 0x0A, 0x08, 0x2A, 0x20, 0x08, 0x00, 0xA8, 0x02, 0xA2, 0x0A,
-0x84, 0x2A, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA6, 0x0A, 0x1C, 0x2A, 0x28, 0xA8,
-0xC0, 0xA0, 0x02, 0xA2, 0x0A, 0x88, 0x2A, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA2,
-0x0A, 0x88, 0x2A, 0xA0, 0xAA, 0x80, 0xA9, 0x02, 0xA2, 0x0A, 0x18, 0x28, 0x20,
-0xA8, 0x80, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x84, 0x42, 0x10, 0x0A, 0x41, 0xA8, 0x04, 0xA0, 0x12, 0x80, 0x42, 0x10,
-0x2A, 0x41, 0x28, 0x84, 0xA1, 0x10, 0x84, 0x4A, 0x10, 0x2A, 0x61, 0xA8, 0x04,
-0xA1, 0x10, 0x84, 0x4A, 0x18, 0x2A, 0x61, 0xA8, 0x44, 0xA1, 0x10, 0x84, 0x4A,
-0x14, 0x2A, 0x61, 0xA8, 0x04, 0xA1, 0x12, 0x84, 0x4A, 0x10, 0x2A, 0x01, 0xA8,
-0x04, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
-0x80, 0x40, 0x81, 0x02, 0x8D, 0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x83, 0x02,
-0x05, 0x08, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05, 0x08, 0x14, 0x20,
-0x50, 0x00, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x28, 0x50, 0x80, 0x40, 0x01,
-0x02, 0x85, 0x00, 0x14, 0x20, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x00, 0x14,
-0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0,
-0xCA, 0x00, 0x2B, 0x03, 0xA4, 0x0C, 0x10, 0x32, 0xC0, 0xCA, 0x00, 0x01, 0x03,
-0x0C, 0x0C, 0xB0, 0x32, 0x40, 0xC0, 0x80, 0x21, 0x03, 0x86, 0x0C, 0xA1, 0x32,
-0x00, 0xC8, 0x80, 0x01, 0x03, 0x86, 0x0C, 0xA0, 0x32, 0x40, 0xC8, 0x00, 0x20,
-0x03, 0x86, 0x0C, 0x10, 0x30, 0x60, 0xC8, 0x20, 0x21, 0x03, 0x84, 0x0C, 0xB0,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA2, 0x4E,
-0x80, 0x3A, 0x09, 0xEE, 0x04, 0xA0, 0x13, 0x80, 0x4E, 0x82, 0x3A, 0x11, 0xEA,
-0x04, 0xB8, 0x13, 0x90, 0x4E, 0x90, 0x3A, 0x21, 0x6A, 0x04, 0xA8, 0x13, 0xA0,
-0x4E, 0x88, 0x3A, 0x21, 0xCA, 0x04, 0xA8, 0x13, 0x10, 0x4C, 0x84, 0x32, 0x01,
-0xE8, 0x04, 0xA8, 0x13, 0xA0, 0x4E, 0x80, 0x3B, 0x01, 0xEA, 0x04, 0xA9, 0x03,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x12, 0x03,
-0x08, 0x8C, 0x20, 0x32, 0x80, 0xC4, 0x08, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31,
-0x82, 0xC0, 0x18, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31, 0x80, 0xC0, 0x18, 0x02,
-0x03, 0x08, 0x0C, 0x20, 0x31, 0x82, 0xC0, 0x18, 0x02, 0x03, 0x08, 0x0C, 0x20,
-0x30, 0x86, 0xC0, 0x00, 0x02, 0x23, 0x08, 0x0C, 0x20, 0x31, 0x84, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB,
-0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF,
-0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF,
-0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF,
-0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xDF, 0xD0, 0x6C, 0x43, 0xB3, 0x0D,
-0xED, 0xBF, 0x34, 0xFB, 0xD2, 0xFE, 0xCB, 0xFF, 0x0D, 0xCD, 0xBE, 0x7C, 0xDB,
-0xF0, 0xFF, 0xCB, 0xFF, 0x2F, 0xED, 0xBF, 0x7C, 0xDB, 0xF0, 0xFF, 0xCB, 0xFF,
-0x2F, 0xCD, 0xBE, 0x7C, 0xDB, 0xF0, 0xFF, 0xCB, 0xB7, 0x2F, 0xDF, 0x36, 0x7C,
-0xDB, 0xF0, 0x6D, 0x43, 0xB3, 0x2F, 0xED, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x3F, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0xF3,
-0xBF, 0xCC, 0xFC, 0x32, 0xFF, 0xCB, 0xFF, 0x23, 0x33, 0xBF, 0xFC, 0x3C, 0xF2,
-0xFF, 0xCB, 0xFF, 0x2F, 0xF3, 0xBF, 0xFC, 0x3C, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F,
-0x33, 0xBF, 0xFC, 0x3C, 0xF2, 0xFF, 0xCB, 0xCF, 0x2F, 0x3F, 0x8F, 0xFC, 0x3C,
-0xF2, 0xF3, 0xC8, 0xCC, 0x2F, 0xF3, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xDC, 0x78, 0x72, 0x63, 0x48, 0xEC, 0x21, 0xB1, 0x9F,
-0xDC, 0x7E, 0x12, 0x7B, 0x48, 0x8C, 0x21, 0xB7, 0x87, 0xC4, 0x7E, 0x12, 0x63,
-0x48, 0x8C, 0x21, 0x37, 0x86, 0xC4, 0x7E, 0x12, 0x63, 0x48, 0x8C, 0x21, 0xB7,
-0x87, 0xC4, 0x7E, 0x12, 0x63, 0x48, 0x8C, 0x21, 0xB1, 0x9F, 0xC4, 0x18, 0x12,
-0x7B, 0x48, 0x8C, 0x27, 0x37, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x00, 0x0E, 0x02, 0x39, 0x0A, 0xE4, 0x20, 0x90, 0x83,
-0x00, 0x0E, 0x02, 0x39, 0x08, 0xE0, 0x20, 0x80, 0x83, 0x40, 0x0E, 0x02, 0x39,
-0x08, 0xE4, 0x20, 0x90, 0x83, 0x00, 0x0E, 0x02, 0x38, 0x0A, 0xE4, 0x20, 0x80,
-0x83, 0x40, 0x0E, 0x02, 0x38, 0x06, 0xE6, 0x20, 0x90, 0xA3, 0x40, 0x0E, 0x02,
-0x39, 0x08, 0xE4, 0x28, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x20, 0x60, 0x8E, 0x00, 0x3A, 0x02, 0xEA, 0x08, 0xA0, 0x23, 0xA0,
-0x8E, 0x00, 0x3A, 0x02, 0xEA, 0x08, 0xB8, 0x23, 0xA0, 0x8E, 0x00, 0x3A, 0x02,
-0xE8, 0x08, 0xA0, 0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23,
-0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEE, 0x08, 0xA8, 0x23, 0xA0, 0x8E, 0x80, 0x3A,
-0x02, 0xEA, 0x08, 0xA8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x40, 0x80, 0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04,
-0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48,
-0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80,
-0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x20, 0x61, 0x80, 0x04, 0x01, 0x12, 0x04,
-0x48, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x80, 0x0E, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x20, 0x06, 0x00,
-0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00,
-0x80, 0x01, 0x28, 0x06, 0x80, 0x18, 0x02, 0x60, 0x00, 0x88, 0x01, 0x00, 0x06,
-0x80, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60,
-0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x20, 0x4E, 0x00, 0x38, 0x05, 0xE2, 0x04, 0x80, 0x13, 0x20, 0x4E, 0x00, 0x38,
-0x09, 0xE2, 0x04, 0x88, 0x13, 0x20, 0x4E, 0x00, 0x38, 0x01, 0xE0, 0x04, 0x80,
-0x13, 0x20, 0x4E, 0x82, 0x38, 0x05, 0xE2, 0x04, 0x88, 0x12, 0x20, 0x4E, 0x80,
-0x38, 0xA1, 0xE2, 0x04, 0x28, 0x51, 0x20, 0x4E, 0x80, 0x30, 0x01, 0xE2, 0x14,
-0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x06, 0x80, 0x18, 0x00, 0x60, 0x00, 0x88, 0x01, 0x00, 0x06, 0x80, 0x18, 0x00,
-0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x81,
-0x00, 0x06, 0x02, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18,
-0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x08, 0x10, 0x00, 0x60, 0x00, 0x80,
-0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x24,
-0x80, 0x90, 0x01, 0x42, 0x02, 0x08, 0x29, 0x20, 0x24, 0x80, 0x90, 0x02, 0x42,
-0x02, 0x08, 0x11, 0x20, 0x24, 0x80, 0x90, 0x00, 0x42, 0x02, 0x08, 0x09, 0x20,
-0xA4, 0x80, 0x90, 0x01, 0x42, 0x02, 0x08, 0x11, 0x20, 0xA4, 0x80, 0x90, 0x01,
-0x42, 0x04, 0x08, 0x39, 0x20, 0x44, 0x80, 0x18, 0x01, 0x42, 0x06, 0x08, 0x01,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x12, 0x81,
-0x48, 0x05, 0x22, 0x11, 0x88, 0x44, 0x00, 0x12, 0x81, 0x48, 0x04, 0x20, 0x31,
-0x80, 0x54, 0x20, 0x12, 0x81, 0x48, 0x04, 0x22, 0x11, 0x88, 0xC4, 0x00, 0x12,
-0x03, 0x48, 0x0D, 0x22, 0x11, 0x80, 0x54, 0x20, 0x12, 0x01, 0x48, 0x05, 0x20,
-0x15, 0x88, 0x54, 0x20, 0x52, 0x81, 0x68, 0x0D, 0x22, 0x1D, 0x88, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x30, 0x00, 0xC8, 0x00, 0x00,
-0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA, 0x00, 0x20, 0x03, 0xA0, 0x0C, 0x00,
-0x32, 0x00, 0xC0, 0x02, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA, 0x00,
-0x28, 0x03, 0x80, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x0C,
-0x80, 0x72, 0x00, 0xCA, 0x00, 0x28, 0x03, 0x80, 0x1C, 0x80, 0x02, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x20, 0x2C, 0x00, 0x90, 0x00,
-0x00, 0x02, 0x00, 0x78, 0x00, 0x26, 0x00, 0x90, 0x03, 0x60, 0x02, 0x08, 0x03,
-0x00, 0x20, 0x00, 0x90, 0x00, 0x40, 0x02, 0x00, 0x19, 0x00, 0xE2, 0x00, 0x88,
-0x00, 0x80, 0x06, 0x80, 0x00, 0x00, 0xE2, 0x01, 0x88, 0x00, 0x20, 0x00, 0x80,
-0x28, 0x00, 0x02, 0x00, 0x08, 0x00, 0x80, 0x0A, 0x80, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x02, 0x40, 0x08, 0x80, 0x01, 0x00, 0x04,
-0x00, 0x18, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40,
-0x00, 0x82, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x84, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x03, 0x02, 0x20, 0x06, 0x80, 0x10, 0x00, 0x42, 0x00,
-0x08, 0x01, 0x60, 0x06, 0x80, 0x10, 0x00, 0x66, 0x00, 0x88, 0x01, 0x20, 0x04,
-0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x01, 0x40, 0x06, 0x80, 0x19, 0x00, 0x62,
-0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x19, 0x00, 0x62, 0x00, 0x88, 0x01, 0x20,
-0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x08, 0x80, 0x02, 0x00, 0x06, 0x00, 0x19, 0x00, 0x64, 0x00, 0x90,
-0x11, 0x00, 0x06, 0x00, 0x19, 0x01, 0x60, 0x00, 0x80, 0x01, 0x40, 0x06, 0x00,
-0x19, 0x00, 0x64, 0x00, 0x90, 0x11, 0x00, 0x46, 0x00, 0x18, 0x00, 0x64, 0x04,
-0x80, 0x01, 0x40, 0x46, 0x00, 0x18, 0x00, 0x66, 0x00, 0x90, 0x01, 0x40, 0x06,
-0x00, 0x19, 0x00, 0x64, 0x00, 0x90, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0xA2, 0x42, 0x60, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x10, 0x00, 0x43,
-0x20, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x10, 0x18, 0x43, 0x20, 0x0C, 0x01, 0x30,
-0x04, 0xC0, 0x10, 0x00, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08,
-0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x0C, 0x81,
-0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x00, 0x10, 0x00, 0x4C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00,
-0x4C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01,
-0xC0, 0x04, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03,
-0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30,
-0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x00, 0xD0, 0x00, 0x4C, 0x03, 0x30, 0x04, 0xC0, 0x34, 0x00, 0xC3, 0x20, 0x4C,
-0x03, 0x30, 0x0C, 0xC2, 0x34, 0x00, 0x43, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0,
-0x34, 0x00, 0xC3, 0x20, 0x0C, 0x83, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x00,
-0x0C, 0x83, 0x30, 0x04, 0xC2, 0x10, 0x00, 0x43, 0x00, 0x0C, 0x01, 0x30, 0x04,
-0xC0, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2,
-0xC2, 0x20, 0x0E, 0x03, 0x10, 0x04, 0x62, 0x30, 0x00, 0xC1, 0x20, 0x06, 0x03,
-0x10, 0x0C, 0x62, 0x30, 0x88, 0x43, 0x20, 0x06, 0x03, 0x18, 0x0C, 0x40, 0x30,
-0x00, 0xC1, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x30, 0x88, 0x41, 0x20, 0x06,
-0x83, 0x18, 0x04, 0x60, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62,
-0x10, 0x88, 0x01, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x42,
-0x00, 0x06, 0x81, 0x10, 0x04, 0x40, 0x10, 0x08, 0x41, 0x00, 0x0C, 0x81, 0x10,
-0x04, 0xC0, 0x10, 0x80, 0x41, 0x00, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08,
-0x41, 0x00, 0x08, 0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00, 0x04, 0x01,
-0x30, 0x04, 0x42, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10,
-0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x42, 0x20,
-0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x0C, 0x81, 0x10, 0x04,
-0xC2, 0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, 0x41,
-0x20, 0x0C, 0x83, 0x30, 0x04, 0x62, 0x10, 0x08, 0x43, 0x20, 0x06, 0x81, 0x30,
-0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88,
-0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02, 0x00, 0x08,
-0x80, 0x00, 0x00, 0xA2, 0x00, 0x08, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
-0x00, 0x00, 0x02, 0x20, 0x0A, 0x80, 0x20, 0x00, 0x82, 0x00, 0x08, 0x02, 0x00,
-0x08, 0x00, 0x20, 0x00, 0xA2, 0x00, 0x00, 0x02, 0x20, 0x0A, 0x00, 0x20, 0x00,
-0xA0, 0x00, 0x88, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00, 0xA2, 0x00, 0x88, 0x42,
-0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x60, 0x00, 0x82, 0x01,
-0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18,
-0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82,
-0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20,
-0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x28, 0x06, 0x20, 0x18, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0xA0, 0x00, 0x01, 0x02,
-0x04, 0x08, 0x10, 0x20, 0x41, 0x80, 0x00, 0x01, 0x02, 0x04, 0x48, 0x10, 0x28,
-0x40, 0x80, 0x04, 0x01, 0x02, 0x04, 0x48, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01,
-0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10,
-0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06,
-0xAC, 0x18, 0xB8, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x62,
-0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAE, 0x18, 0xB8, 0x62, 0xC0, 0x8A, 0x01, 0x2B,
-0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0,
-0x62, 0xC0, 0x8A, 0x01, 0x29, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x88, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x62, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2,
-0x18, 0x88, 0x63, 0x60, 0x8E, 0x81, 0x38, 0x06, 0xE6, 0x18, 0x88, 0x63, 0x20,
-0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x88, 0x63, 0x50, 0x8E, 0x81, 0x39, 0x06,
-0xE2, 0x18, 0x98, 0x63, 0x20, 0x8E, 0x81, 0x39, 0x04, 0xE2, 0x18, 0x88, 0x63,
-0x20, 0x8E, 0x81, 0x3A, 0x06, 0xE2, 0x18, 0x88, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x80, 0x62, 0x00, 0x8E, 0x01, 0x3B, 0x06, 0xE4, 0x18,
-0xB0, 0x63, 0x00, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0x80, 0x63, 0x40, 0x8E,
-0x01, 0x39, 0x06, 0xEC, 0x18, 0xB0, 0x63, 0x80, 0x8E, 0x01, 0x38, 0x06, 0xE4,
-0x18, 0x80, 0x63, 0x40, 0x8E, 0x01, 0x38, 0x06, 0xE4, 0x18, 0x90, 0x63, 0x40,
-0x0E, 0x01, 0x39, 0x06, 0xE4, 0x18, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0A, 0xA2, 0x62, 0x60, 0x8C, 0x01, 0x30, 0x06, 0xEA, 0x18, 0x80,
-0x63, 0x20, 0x8C, 0x01, 0x30, 0x06, 0xC2, 0x18, 0x18, 0x63, 0xA0, 0x8E, 0x01,
-0x30, 0x06, 0xC0, 0x18, 0x00, 0x63, 0x20, 0x8E, 0x81, 0x30, 0x06, 0xEA, 0x18,
-0x08, 0x63, 0xA0, 0x8E, 0x81, 0x30, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0xA0, 0x8E,
-0x81, 0x3A, 0x06, 0xEA, 0x18, 0xA8, 0x43, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x00, 0x48, 0x00, 0x24, 0x01, 0x9A, 0x04, 0x48, 0x12, 0x20, 0x49,
-0x80, 0x2E, 0x01, 0x90, 0x04, 0xE8, 0x12, 0x00, 0x49, 0x80, 0x24, 0x01, 0x90,
-0x04, 0x68, 0x12, 0xA0, 0x41, 0x80, 0x2C, 0x01, 0xBA, 0x04, 0x48, 0x10, 0xA0,
-0x43, 0x80, 0x24, 0x01, 0xBA, 0x04, 0x48, 0x10, 0x20, 0x49, 0x80, 0x04, 0x01,
-0x92, 0x04, 0x48, 0x12, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x00, 0x60, 0x00, 0x84, 0x01, 0x10, 0x06, 0x60, 0x18, 0x00, 0x61, 0x20,
-0x86, 0x01, 0x10, 0x06, 0x62, 0x18, 0x00, 0x61, 0x00, 0x86, 0x01, 0x10, 0x06,
-0x40, 0x18, 0x00, 0x61, 0x20, 0x86, 0x81, 0x18, 0x06, 0x60, 0x18, 0x88, 0x61,
-0x00, 0x86, 0x81, 0x58, 0x06, 0x60, 0x18, 0x80, 0x61, 0x00, 0x86, 0x01, 0x18,
-0x06, 0x60, 0x18, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xA2, 0x06, 0x20, 0x1E, 0x00, 0x70, 0x00, 0xC2, 0x01, 0x00, 0x07, 0x20, 0x1E,
-0x00, 0x70, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20, 0x1C, 0x00, 0x70, 0x00, 0xC0,
-0x01, 0x00, 0x07, 0x20, 0x1C, 0x80, 0x70, 0x00, 0xE2, 0x01, 0x88, 0x07, 0x20,
-0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20, 0x1E, 0x80, 0x78, 0x00,
-0xE2, 0x01, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
-0x4A, 0x00, 0x26, 0x83, 0x90, 0x04, 0x40, 0x12, 0x08, 0x49, 0x00, 0x26, 0x81,
-0x90, 0x04, 0x40, 0x12, 0x80, 0x49, 0x00, 0x24, 0x81, 0x90, 0x04, 0x42, 0x12,
-0x08, 0x41, 0x00, 0x24, 0x01, 0x90, 0x04, 0x60, 0x10, 0x80, 0x41, 0x00, 0x26,
-0x01, 0x98, 0x04, 0x40, 0x10, 0x80, 0x49, 0x00, 0x06, 0x01, 0x98, 0x04, 0x60,
-0x12, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x42,
-0x20, 0x04, 0x81, 0x18, 0x05, 0x62, 0x10, 0x88, 0x41, 0x20, 0x04, 0x81, 0x18,
-0x04, 0x62, 0x10, 0x08, 0x51, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88,
-0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81,
-0x10, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10,
-0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x00,
-0x02, 0x81, 0x28, 0x0C, 0xA2, 0x30, 0x88, 0x42, 0x00, 0x02, 0x83, 0x28, 0x0C,
-0xA0, 0x10, 0x80, 0xC0, 0x20, 0x0A, 0x83, 0x28, 0x0C, 0xA2, 0x30, 0x88, 0xC2,
-0x00, 0x0A, 0x03, 0x28, 0x04, 0x22, 0x10, 0x80, 0x40, 0x20, 0x02, 0x01, 0x08,
-0x04, 0xA2, 0x10, 0x88, 0x40, 0x20, 0x02, 0x81, 0x08, 0x04, 0x22, 0x10, 0x88,
-0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0A,
-0x01, 0x28, 0x05, 0xA0, 0x10, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x0C, 0xA0,
-0x10, 0x80, 0x52, 0x00, 0x0A, 0x01, 0x28, 0x04, 0xA0, 0x10, 0x80, 0xC2, 0x00,
-0x0A, 0x03, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x0C,
-0x80, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x04, 0xA0, 0x30, 0x80, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x20, 0x06, 0x00,
-0x08, 0x00, 0x60, 0x00, 0x80, 0x11, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x04,
-0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02,
-0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x00, 0x80,
-0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x40, 0x00, 0x81, 0x01,
-0x04, 0x04, 0x10, 0x18, 0x40, 0x40, 0x00, 0x83, 0x01, 0x05, 0x04, 0x10, 0x10,
-0x40, 0x40, 0x00, 0x81, 0x01, 0x04, 0x06, 0x10, 0x18, 0x50, 0x40, 0x40, 0x01,
-0x01, 0x0C, 0x04, 0x10, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x84, 0x10,
-0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x20, 0x06, 0x80, 0x18, 0x00,
-0x62, 0x00, 0x88, 0x01, 0x60, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01,
-0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x60, 0x06, 0x80, 0x19,
-0x00, 0x62, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x19, 0x00, 0x62, 0x00, 0x88,
-0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x24, 0x00, 0x99, 0x00, 0x64,
-0x02, 0x10, 0x09, 0x00, 0x2E, 0x00, 0x91, 0x00, 0xE0, 0x00, 0x00, 0x09, 0x40,
-0x26, 0x00, 0x91, 0x00, 0x44, 0x02, 0x10, 0x09, 0x00, 0x2E, 0x00, 0xB8, 0x00,
-0x64, 0x00, 0x80, 0x0B, 0x40, 0x26, 0x00, 0xB8, 0x00, 0x64, 0x02, 0x98, 0x09,
-0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xA2, 0x06, 0x60, 0x14, 0x00, 0x50, 0x00, 0xC2, 0x01,
-0x00, 0x05, 0x20, 0x16, 0x00, 0x50, 0x00, 0x62, 0x01, 0x18, 0x05, 0x20, 0x1C,
-0x00, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x20, 0x16, 0x80, 0x58, 0x00, 0xC2,
-0x01, 0x88, 0x05, 0x28, 0x1C, 0x80, 0x58, 0x00, 0xC2, 0x01, 0x08, 0x07, 0x20,
-0x1C, 0x80, 0x70, 0x08, 0xC2, 0x01, 0x08, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0A, 0x00, 0x80, 0x00, 0x04, 0x02, 0x10, 0x08, 0xC0, 0x20, 0x00,
-0xA1, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x0C, 0x02,
-0x10, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x0A, 0xC0, 0x20,
-0x00, 0xA1, 0x00, 0x8C, 0x02, 0x10, 0x08, 0xC0, 0x28, 0x00, 0xE3, 0x00, 0x1C,
-0x02, 0x30, 0x0A, 0xC0, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x00, 0x20, 0x00, 0xA4, 0x00, 0x90, 0x02, 0xC0, 0x0A, 0x00, 0xA9,
-0x20, 0xAC, 0x00, 0xB0, 0x0A, 0xC2, 0x08, 0x00, 0x29, 0x00, 0xAC, 0x00, 0xB0,
-0x02, 0xC0, 0x0A, 0x00, 0xAB, 0x20, 0xAC, 0x82, 0xB0, 0x06, 0xC0, 0x28, 0x08,
-0xAB, 0x00, 0xAC, 0x82, 0xB0, 0x0A, 0xC0, 0x3A, 0x08, 0xAB, 0x00, 0xAC, 0x02,
-0xB0, 0x0E, 0xC0, 0x28, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xA2, 0xC2, 0x20, 0x06, 0x03, 0x18, 0x0C, 0x62, 0x30, 0x80, 0xE1, 0x20,
-0x06, 0x03, 0x18, 0x0C, 0x62, 0x30, 0x88, 0xC1, 0x20, 0x06, 0x03, 0x18, 0x0C,
-0x60, 0x30, 0x80, 0xC1, 0x20, 0x06, 0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xE1,
-0x20, 0x06, 0x83, 0x18, 0x0C, 0x62, 0x38, 0x80, 0xE1, 0x20, 0x06, 0x83, 0x18,
-0x0E, 0x62, 0x30, 0x88, 0x01, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x80, 0x02, 0x00, 0x04, 0x80, 0x10, 0x00, 0x40, 0x00, 0x08, 0x01, 0x00, 0x04,
-0x80, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x80, 0x10, 0x00, 0x42,
-0x00, 0x08, 0x11, 0x00, 0x44, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x84, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
-0x12, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x11, 0x20, 0x06, 0x88,
-0x18, 0x20, 0x62, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80,
-0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x01, 0x62, 0x84, 0x88, 0x31, 0x20, 0x46,
-0x80, 0x18, 0x20, 0x62, 0x04, 0x80, 0x11, 0x20, 0x46, 0x88, 0x18, 0x01, 0x62,
-0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02,
-0x02, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x80, 0x88, 0x22, 0x00, 0x0A, 0x88, 0x28,
-0x00, 0xA0, 0x80, 0x80, 0x02, 0x22, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x80, 0x88,
-0x02, 0x02, 0x0A, 0x00, 0x28, 0x20, 0xA2, 0x80, 0x80, 0x02, 0x22, 0x0A, 0x02,
-0x28, 0x20, 0xA2, 0x80, 0x80, 0x02, 0x20, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00,
-0x88, 0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x04,
-0x42, 0x10, 0x28, 0x01, 0xA0, 0x04, 0x81, 0x12, 0x04, 0x42, 0x10, 0x28, 0x41,
-0xA0, 0x04, 0x81, 0x10, 0x04, 0x4A, 0x10, 0x28, 0x41, 0xA0, 0x04, 0x81, 0x12,
-0x04, 0x4A, 0x10, 0x28, 0x01, 0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08,
-0x01, 0xA0, 0x04, 0x81, 0x10, 0x00, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xA0, 0x40,
-0x01, 0x00, 0x05, 0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x00,
-0x14, 0x28, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x00, 0x14, 0x20, 0x50, 0x00,
-0x40, 0x01, 0x00, 0x85, 0x08, 0x34, 0x20, 0x50, 0x80, 0x40, 0x03, 0x02, 0x05,
-0x00, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0xB2, 0xC0, 0xCA, 0x82,
-0x21, 0x0B, 0xA4, 0x2C, 0x18, 0xB2, 0xC0, 0xCA, 0x02, 0x28, 0x0B, 0x84, 0x2C,
-0xB0, 0xB2, 0x40, 0xC8, 0x82, 0x21, 0x0B, 0x86, 0x2C, 0x80, 0xB2, 0x40, 0xC8,
-0x02, 0x21, 0x0B, 0xAC, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2B, 0x0B, 0x84,
-0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2B, 0x0B, 0xAC, 0x2C, 0xB0, 0x02, 0x88,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x20, 0x4E, 0x80, 0x38,
-0x01, 0xEA, 0x04, 0x88, 0x13, 0x60, 0x4E, 0x80, 0x3A, 0x01, 0xE6, 0x04, 0x88,
-0x13, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0xA8, 0x13, 0x60, 0x4E, 0x00,
-0x39, 0x01, 0xE2, 0x24, 0x98, 0x13, 0x20, 0x4E, 0x82, 0x39, 0x01, 0xE2, 0x04,
-0x88, 0x13, 0x20, 0x4E, 0x82, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x03, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x02, 0x03, 0x08, 0x0C,
-0x20, 0x30, 0x80, 0xC0, 0x00, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31, 0x80, 0xC0,
-0x10, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x30, 0x80, 0xC0, 0x08, 0x02, 0x03, 0x08,
-0x0C, 0x20, 0x31, 0x82, 0xC0, 0x18, 0x02, 0x43, 0x08, 0x0C, 0x20, 0x30, 0x86,
-0xC0, 0x00, 0x02, 0x63, 0x08, 0x0C, 0x21, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F,
-0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF,
-0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF,
-0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC,
-0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x34, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x2F, 0xCD, 0x36,
-0xFC, 0xDF, 0xD0, 0x6C, 0x43, 0xFB, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0, 0x6C,
-0x43, 0xB3, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0, 0x7E, 0xC3, 0xB7, 0x2F, 0xCD,
-0x36, 0x7C, 0xDB, 0xF0, 0x7F, 0x43, 0xB3, 0x2F, 0xDF, 0x36, 0xFC, 0xFF, 0xD2,
-0x6C, 0xC3, 0xB7, 0x0D, 0xED, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xCC, 0x3C, 0x32, 0xF3, 0xC8, 0xCC, 0x2F, 0x33, 0x8F, 0xFC,
-0x3F, 0x32, 0xF3, 0xC8, 0xFC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xF3, 0xC8,
-0xCC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xFF, 0xC8, 0xCF, 0x2F, 0x33, 0x8F,
-0xFC, 0x3C, 0xF2, 0xFF, 0xC8, 0xCC, 0x2F, 0x3F, 0x8F, 0xFC, 0xFF, 0x32, 0xF3,
-0xC8, 0xCF, 0x23, 0xF3, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xDC, 0x18, 0x12, 0x63, 0x48, 0x8C, 0x27, 0x31, 0x86, 0xDC, 0x1E,
-0x12, 0x63, 0x48, 0xEC, 0x21, 0x37, 0x86, 0xC4, 0x78, 0x12, 0x63, 0x48, 0x8C,
-0x21, 0x31, 0x86, 0xC4, 0x1E, 0x12, 0x7B, 0xC8, 0x8D, 0x27, 0xB7, 0x87, 0xDC,
-0x7E, 0x72, 0x7B, 0x48, 0x8C, 0x27, 0xB7, 0x9F, 0xDC, 0x7E, 0x12, 0xFB, 0xC9,
-0x8D, 0x27, 0xB7, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x40, 0xE1, 0x0C, 0x85, 0x33, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00,
-0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02,
-0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0xCE, 0x50, 0x08, 0x40, 0x21,
-0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0xE1, 0x0C, 0x85, 0x00, 0x14,
-0x02, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
-0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
-0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x01, 0x02,
-0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00,
-0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
-0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84,
-0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
-0x0C, 0x80, 0x33, 0x00, 0x02, 0x04, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00,
-0x02, 0x00, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10,
-0x20, 0x00, 0x80, 0x00, 0x00, 0xCE, 0x00, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00,
-0x00, 0x02, 0x04, 0x08, 0x00, 0xE0, 0x4C, 0x80, 0x00, 0x01, 0x02, 0x00, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x04, 0x00, 0x10, 0xCC, 0x40, 0x00, 0x10, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x44, 0x00, 0x10, 0x01, 0x00, 0x04, 0x33, 0x10, 0x00, 0x40, 0x00, 0x00, 0xC1,
-0x0C, 0x04, 0x00, 0x10, 0xCC, 0x40, 0x30, 0x03, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0xC1, 0x0C, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
-0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
-0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
-0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04,
-0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44,
-0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
-0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x01, 0x00, 0x04, 0x30, 0x13, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02,
-0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21,
-0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15,
-0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50,
-0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
-0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
-0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02,
-0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
-0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
-0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84,
-0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
-0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
-0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03,
-0xE0, 0x0C, 0x80, 0x33, 0x00, 0x02, 0x00, 0x38, 0x03, 0x20, 0x00, 0x80, 0x33,
-0x00, 0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x08,
-0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80,
-0x00, 0x00, 0xCE, 0x00, 0x38, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x33, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21,
-0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10,
-0xCE, 0x40, 0x08, 0x00, 0xE1, 0x0C, 0x84, 0x00, 0x10, 0xCE, 0x40, 0x38, 0x03,
-0x21, 0x00, 0x84, 0x33, 0x10, 0xCE, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x33,
-0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x02,
-0x10, 0x00, 0x40, 0x20, 0x00, 0x01, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x00,
-0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04,
-0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
-0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40,
-0x00, 0x00, 0x21, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00,
-0x84, 0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01,
-0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00,
-0x00, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00,
-0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
-0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
-0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
-0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
-0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85,
-0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50,
-0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00,
-0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02,
-0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
-0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08,
-0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
-0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10,
-0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00,
-0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00,
-0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
-0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02,
-0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20,
-0x40, 0x80, 0x00, 0x01, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00,
-0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04,
-0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40,
-0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
-0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11,
-0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10,
-0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
-0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x10, 0x00, 0x44, 0x00,
-0x10, 0x01, 0x00, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
-0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0xCE, 0x54,
-0x08, 0x50, 0x21, 0x40, 0x85, 0x33, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40,
-0x85, 0x00, 0x15, 0x02, 0x54, 0x38, 0x53, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02,
-0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21,
-0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08,
-0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
-0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
-0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00,
-0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00,
-0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
-0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84,
-0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0,
-0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00,
-0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03,
-0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0x20, 0x00, 0x80, 0x33,
-0x00, 0xCE, 0x00, 0x38, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
-0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02,
-0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21,
-0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10,
-0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
-0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
-0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
-0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
-0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
-0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x04, 0x80,
-0x40, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x04, 0x80, 0x40,
-0x40, 0x00, 0x00, 0x0C, 0x00, 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, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x80, 0x00,
-0x00, 0x22, 0x25, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0x00,
-0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 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, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x05, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x87, 0xE8, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00
-};
diff --git a/drivers/staging/me4000/me4610_firmware.h b/drivers/staging/me4000/me4610_firmware.h
deleted file mode 100644
index c550d99..0000000
--- a/drivers/staging/me4000/me4610_firmware.h
+++ /dev/null
@@ -1,5409 +0,0 @@
-/*
-   This file is copyright by Meilhaus Electronic GmbH 2003.
-   You are not allowed to distribute, sell, modify, reverse engineer or use this
-   code (or parts of it) for any other purpose or under any other conditions
-   than stated below.
-
-   1) You are allowed to distribute verbatim copies of this file together
-   with device drivers for the Meilhaus ME-4000, board family.
-
-   2) Derived work (device drivers using this file) can be published under
-   the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version. Any other license terms have
-   to be agreed by Meilhaus GmbH in written.
-
-   2) This file is distributed WITHOUT ANY WARRANTY;
-   without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE. Meilhaus is under
-   no means liable for products using this file or parts of it.
-
-   3) The copyright of this file has to be mentioned in derived work.
-
-   4) If this license terms are not valid due to any other law
-   or restrictions imposed on you, you are not allowed to use
-   this file in any way at all.
- */
-
-/* Version 0 of ME-4610 firmware */
-static unsigned char xilinx_firm_4610[] = {
-0x00, 0x01, 0x11, 0x0c, 0x01, 0x01, 0x04, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00,
-0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x99, 0xAA, 0x66, 0x0C, 0x00,
-0x01, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x0C, 0x80, 0x06, 0x80, 0x00, 0x00, 0x00,
-0xD0, 0x0C, 0x80, 0x04, 0x80, 0x00, 0x01, 0xFC, 0xB4, 0x0C, 0x00, 0x03, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x90, 0x0C,
-0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00,
-0x00, 0x80, 0x0C, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x7C, 0x20, 0x40, 0x58, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x20, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x40, 0x48, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x58, 0x80, 0x54, 0x00,
-0x44, 0x01, 0x18, 0x05, 0x60, 0x04, 0x80, 0x01, 0x00, 0x66, 0x00, 0xD8, 0x00,
-0x60, 0x0A, 0x80, 0x2D, 0x00, 0xF6, 0x00, 0xD8, 0x03, 0x60, 0x0A, 0x80, 0x69,
-0x00, 0xC6, 0x01, 0x98, 0x05, 0x20, 0x16, 0xFC, 0x23, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0xFF, 0x00, 0xBF, 0x00, 0xDC, 0x32, 0xF0,
-0x13, 0xC0, 0x4F, 0x00, 0xFB, 0x28, 0xBC, 0x04, 0xB0, 0x17, 0xC0, 0x4E, 0x12,
-0x1B, 0x10, 0xFC, 0x13, 0x30, 0x93, 0xC0, 0x4B, 0x00, 0x1F, 0x01, 0xFC, 0x24,
-0x30, 0xCF, 0xE2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x08, 0x37, 0x01, 0x9D, 0x06, 0x44, 0x30, 0xD1, 0x11, 0x40, 0x47, 0x00,
-0xFD, 0x0A, 0x74, 0x06, 0x10, 0x09, 0x40, 0x17, 0x09, 0x11, 0x42, 0xF4, 0x0B,
-0x50, 0x49, 0x40, 0x06, 0x0C, 0x1D, 0x00, 0x74, 0x00, 0x10, 0x8F, 0x40, 0x04,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x33, 0x00,
-0x8D, 0x18, 0x05, 0x16, 0xDA, 0x08, 0x40, 0x33, 0x00, 0xCD, 0x40, 0x74, 0x03,
-0x91, 0x0C, 0x40, 0x35, 0x01, 0x0D, 0x20, 0x34, 0xA3, 0x10, 0x48, 0x40, 0x01,
-0x01, 0xCD, 0xA0, 0x74, 0x13, 0xD2, 0x4C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x34, 0x00, 0x9D, 0x01, 0x44, 0x86,
-0xD0, 0x39, 0x40, 0x07, 0x00, 0xDD, 0x00, 0x64, 0x8A, 0x10, 0x89, 0x02, 0x37,
-0x00, 0x15, 0x10, 0x74, 0x03, 0x50, 0x19, 0x07, 0x47, 0x20, 0x5D, 0x04, 0x74,
-0xA3, 0xDA, 0x0D, 0x48, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA8, 0x77, 0x00, 0x1F, 0x91, 0x4C, 0x86, 0xE0, 0x19, 0xC0, 0x57,
-0x21, 0xDB, 0x00, 0x7C, 0x01, 0xB0, 0x05, 0x80, 0x06, 0x91, 0x1B, 0x0B, 0x7C,
-0x03, 0x31, 0x31, 0xC0, 0x47, 0x01, 0x9F, 0x44, 0x7C, 0x02, 0xD0, 0x0D, 0x60,
-0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D,
-0x02, 0x3E, 0x40, 0xE8, 0x00, 0xF0, 0x0B, 0x40, 0x8F, 0x00, 0xFE, 0x00, 0xF4,
-0x48, 0xF0, 0x0B, 0xC0, 0x1F, 0x80, 0x1A, 0x20, 0xBC, 0x03, 0xE1, 0x0B, 0xC8,
-0x0E, 0x00, 0x3E, 0x01, 0xF8, 0x02, 0x30, 0x0F, 0xD1, 0x1F, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x9F, 0x00, 0x5C,
-0x46, 0x70, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x7C, 0x21, 0x30, 0x0D, 0xC4,
-0x34, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0xB0, 0x29, 0xC0, 0x84, 0x08, 0x9F, 0x44,
-0x7C, 0x43, 0xF0, 0x0C, 0xC4, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0x9D, 0x00, 0x74, 0x0A, 0x90, 0x09, 0x40,
-0x67, 0x00, 0xF0, 0x80, 0x34, 0x04, 0xB0, 0xB9, 0x40, 0x32, 0x00, 0xD1, 0x41,
-0xC0, 0x03, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x51, 0x00, 0x34, 0x43, 0xD0, 0x3F,
-0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0,
-0x32, 0x10, 0x1D, 0x40, 0x30, 0x00, 0x90, 0x10, 0x40, 0xA3, 0x84, 0xC9, 0x00,
-0x34, 0x00, 0x10, 0x08, 0x40, 0x20, 0x00, 0xC0, 0x21, 0x00, 0x03, 0x90, 0x00,
-0x40, 0x00, 0x00, 0x49, 0x83, 0x04, 0x89, 0xD8, 0x0C, 0x40, 0x1C, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x82, 0x78, 0x02, 0xEC, 0x81,
-0xB4, 0x05, 0x9A, 0x92, 0x60, 0x4B, 0x90, 0xE1, 0xA9, 0xB6, 0x06, 0x90, 0x1A,
-0x60, 0x7A, 0x00, 0xE1, 0x13, 0xA4, 0x07, 0xC0, 0x12, 0x40, 0x4F, 0x00, 0x61,
-0x35, 0xB4, 0x25, 0xC0, 0x9F, 0x61, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x10, 0x4D, 0x00, 0x1C, 0xA1, 0x78, 0x80,
-0xE1, 0x33, 0x25, 0xCF, 0x20, 0x3C, 0x23, 0x30, 0x2C, 0xC1, 0x34, 0x08, 0x07,
-0x05, 0x0D, 0x03, 0xB0, 0xC0, 0xE8, 0x10, 0x22, 0xCF, 0x41, 0x3C, 0x17, 0xF2,
-0xDD, 0xD0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xB2, 0x3D, 0x08, 0xFF, 0x00, 0xFE, 0xA3, 0x80, 0x8F, 0xC2, 0x1B, 0x00, 0xFF,
-0x80, 0xFE, 0x03, 0xF0, 0x0B, 0x40, 0x3F, 0x10, 0x37, 0x08, 0xDC, 0x63, 0xF0,
-0x87, 0xC6, 0x3F, 0x08, 0xDF, 0x00, 0x7C, 0x23, 0xFA, 0x8F, 0xC2, 0x09, 0x60,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x77, 0x00, 0x57,
-0x00, 0x7C, 0x03, 0xF0, 0x11, 0xC0, 0x35, 0x00, 0xDF, 0x10, 0x5C, 0x01, 0xF0,
-0x18, 0xC0, 0x66, 0x00, 0xD3, 0x00, 0x6C, 0x13, 0xF0, 0x01, 0xC8, 0x17, 0x10,
-0x9F, 0x00, 0x7C, 0x03, 0x32, 0xBD, 0xC5, 0x54, 0x20, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x3D, 0x00, 0x61, 0x80, 0xB6, 0x01, 0xD0,
-0x0A, 0x48, 0x38, 0x00, 0xFD, 0x06, 0x84, 0x03, 0xD2, 0x0A, 0x40, 0x39, 0x40,
-0xF1, 0x80, 0x86, 0x43, 0xD0, 0x0A, 0x48, 0x1B, 0x00, 0xED, 0x00, 0xB4, 0x03,
-0x10, 0x0F, 0x40, 0x48, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0x00, 0x79, 0x80, 0xE5, 0x01, 0x94, 0x07, 0xD0, 0x17, 0x40, 0x79, 0x08,
-0xEC, 0x01, 0x94, 0x07, 0xD0, 0x1F, 0x40, 0x7B, 0x00, 0xE1, 0x01, 0x84, 0x07,
-0xD0, 0x1E, 0x60, 0x79, 0x00, 0xAD, 0x11, 0xA4, 0x07, 0x50, 0x1E, 0x40, 0x0C,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x23, 0x00,
-0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x42, 0x31, 0x02, 0xCD, 0x00, 0x14, 0x4B,
-0xD1, 0x08, 0x40, 0x31, 0x00, 0xC1, 0x0D, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x73,
-0x01, 0xCD, 0x80, 0x74, 0x0B, 0x50, 0x0C, 0x40, 0x48, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x14, 0x01, 0x77, 0x03, 0xFC, 0x29,
-0xD0, 0x17, 0xC1, 0x5D, 0x00, 0x5F, 0x00, 0x9C, 0x19, 0xD0, 0x07, 0xC0, 0x1E,
-0x00, 0x73, 0x02, 0x4C, 0x01, 0xF0, 0x47, 0xC0, 0x1F, 0x8C, 0x7F, 0x00, 0xFC,
-0x09, 0x72, 0x05, 0x40, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0xD0, 0x11, 0x40, 0x46,
-0x00, 0x0E, 0x40, 0x68, 0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x42, 0x5C,
-0x00, 0xB2, 0x11, 0xC0, 0x07, 0x00, 0x1B, 0x10, 0x7C, 0x10, 0x82, 0x01, 0xC0,
-0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x27,
-0x00, 0x8F, 0x10, 0x54, 0x0A, 0xF2, 0x09, 0x40, 0x27, 0x00, 0x9B, 0x00, 0x4C,
-0x06, 0xD0, 0x99, 0xC0, 0x27, 0x00, 0x8F, 0x04, 0x5C, 0x82, 0xE0, 0x09, 0xC0,
-0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0x30, 0x89, 0xC2, 0x43, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x10, 0x9C, 0x00, 0x54,
-0x02, 0xD0, 0xB9, 0x40, 0xE7, 0x00, 0x9D, 0x00, 0x44, 0x6A, 0x10, 0x19, 0x04,
-0x27, 0x00, 0x9D, 0x02, 0x45, 0x02, 0xC2, 0x09, 0x40, 0x27, 0x00, 0x90, 0x13,
-0x74, 0x22, 0x10, 0x59, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x90, 0x09, 0x40,
-0xE7, 0x00, 0x9D, 0x80, 0x45, 0x02, 0x90, 0x09, 0x41, 0x26, 0x00, 0x9D, 0x02,
-0x44, 0x82, 0x90, 0x09, 0x40, 0x23, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10, 0x09,
-0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
-0x20, 0x02, 0x8D, 0x14, 0x14, 0x56, 0xD0, 0x0C, 0x40, 0x23, 0x08, 0x8D, 0x00,
-0x04, 0x02, 0x10, 0x08, 0x40, 0x23, 0x02, 0x8D, 0x00, 0x04, 0x02, 0xD0, 0x88,
-0x00, 0x23, 0x02, 0x81, 0x00, 0x30, 0x02, 0x14, 0x48, 0x49, 0x43, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x00, 0x1F, 0x24,
-0x4C, 0x10, 0xF0, 0x01, 0xC0, 0x07, 0x10, 0x1E, 0x14, 0x4C, 0x00, 0xB0, 0xA1,
-0xC2, 0x83, 0x00, 0x1F, 0x1E, 0x4C, 0x78, 0xF0, 0x21, 0xC0, 0x87, 0x00, 0x17,
-0x0A, 0x3C, 0x81, 0x30, 0x41, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x19, 0xB0, 0x2F, 0x01, 0xBF, 0x94, 0xFC, 0x52, 0xF2, 0x0A,
-0xC8, 0x2F, 0x00, 0x9C, 0x14, 0xFC, 0x02, 0xB0, 0x1F, 0x80, 0x2F, 0x01, 0xBF,
-0x81, 0x70, 0x06, 0xF1, 0x4F, 0xC0, 0x2F, 0x41, 0xBF, 0x01, 0xFC, 0x53, 0xF0,
-0x49, 0x41, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
-0x80, 0x23, 0x00, 0x97, 0x08, 0xF0, 0x37, 0x30, 0x0A, 0xC0, 0x2F, 0x20, 0x9F,
-0x0C, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0xA2, 0x00, 0xBF, 0x10, 0x4C, 0x02, 0xF0,
-0x29, 0xC0, 0x25, 0x02, 0xB3, 0x00, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x64, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x01, 0x01,
-0x05, 0x74, 0x3D, 0xB0, 0x01, 0x40, 0x17, 0x00, 0x1D, 0x01, 0x74, 0x01, 0xD1,
-0x01, 0x40, 0x04, 0x00, 0x0D, 0x02, 0x51, 0x28, 0x91, 0x01, 0x40, 0x14, 0x11,
-0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x48, 0x71, 0x00, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x04, 0x85, 0x42, 0x34, 0x02, 0x59,
-0x08, 0x40, 0x23, 0x08, 0x8D, 0x02, 0x34, 0x02, 0xD0, 0x09, 0x42, 0x22, 0x10,
-0x8D, 0x00, 0x16, 0x82, 0xD0, 0x09, 0x40, 0x21, 0x00, 0xC5, 0x20, 0x74, 0x02,
-0x11, 0x08, 0x50, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0xA8, 0x21, 0x00, 0x91, 0x04, 0x74, 0x03, 0xD0, 0x39, 0x60, 0x27, 0x08,
-0x9D, 0x00, 0x74, 0x02, 0xD0, 0x8D, 0x42, 0x24, 0x00, 0x9D, 0x00, 0x54, 0x02,
-0xD0, 0x09, 0x40, 0x24, 0x40, 0x95, 0x04, 0x74, 0x02, 0x52, 0x09, 0x40, 0x61,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x08,
-0x97, 0x93, 0x78, 0x0A, 0x74, 0x19, 0xC0, 0xE7, 0x00, 0x9F, 0x00, 0x7C, 0x0A,
-0xF0, 0x08, 0xC8, 0xE6, 0x01, 0x9F, 0xB8, 0x5C, 0x02, 0xF0, 0x28, 0xC2, 0x25,
-0x00, 0x97, 0x04, 0x3C, 0x0E, 0x20, 0x09, 0xC4, 0x14, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x64, 0x02, 0x9F, 0x00, 0x3C, 0x16,
-0xB0, 0x09, 0xC4, 0xE7, 0x00, 0x9F, 0x80, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x27,
-0x01, 0x9F, 0x01, 0x68, 0x02, 0xB0, 0x29, 0xC4, 0x27, 0x01, 0x9B, 0x00, 0x7C,
-0x0E, 0xB4, 0x08, 0x40, 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x02, 0x4C, 0x08, 0xF0, 0x61, 0xC0, 0x07,
-0x00, 0x17, 0x00, 0x4C, 0x40, 0xF0, 0x21, 0x40, 0x04, 0x00, 0x03, 0x42, 0x5C,
-0x00, 0x30, 0x21, 0xC0, 0x87, 0x10, 0x1F, 0x00, 0x4C, 0x08, 0xF0, 0x01, 0xD1,
-0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14,
-0x00, 0x51, 0x00, 0xC4, 0x0D, 0xD0, 0x37, 0x40, 0x1C, 0x02, 0x51, 0x20, 0xCC,
-0x41, 0xD2, 0x07, 0x48, 0x14, 0x00, 0x71, 0x49, 0x44, 0x81, 0x50, 0x05, 0x40,
-0x17, 0x00, 0x7C, 0x82, 0xC4, 0x69, 0xD0, 0x07, 0x40, 0x50, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x60, 0xC1, 0x40, 0x14,
-0xCF, 0xC0, 0xB4, 0x40, 0x72, 0x02, 0xC5, 0x00, 0x24, 0x03, 0xD0, 0x8C, 0x40,
-0x30, 0x10, 0xC1, 0x0B, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x00, 0xC9, 0x04,
-0x04, 0x80, 0xD0, 0x30, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x82, 0x3C, 0x22, 0xE1, 0x0D, 0x94, 0x43, 0xD0, 0x12, 0x40,
-0x7E, 0x00, 0xC1, 0x01, 0x84, 0x01, 0xD0, 0x0E, 0x40, 0x7C, 0x43, 0x61, 0x00,
-0xA4, 0x27, 0x50, 0x0E, 0x40, 0x3B, 0x10, 0xAD, 0x21, 0x84, 0x01, 0xD0, 0x23,
-0x44, 0x10, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10,
-0x78, 0x01, 0xE3, 0x91, 0x9D, 0x07, 0xF0, 0x16, 0xC0, 0x4A, 0x00, 0xE7, 0x01,
-0xAD, 0x07, 0xE1, 0x13, 0xC0, 0x78, 0x02, 0xA3, 0x61, 0xFC, 0x37, 0x30, 0x5E,
-0xC1, 0x7B, 0x00, 0xBB, 0x01, 0x8C, 0x06, 0xFA, 0x1B, 0xC0, 0x50, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x35, 0x04, 0xDF, 0x40,
-0x6C, 0x03, 0xF3, 0x01, 0xC0, 0x00, 0x20, 0xDF, 0x00, 0x7C, 0x01, 0xD0, 0x05,
-0x90, 0x37, 0x01, 0x1F, 0x00, 0x5C, 0x93, 0xF1, 0xAD, 0x80, 0xB7, 0x03, 0x9C,
-0x40, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xDC, 0x25, 0x30, 0x1F,
-0xC0, 0x7F, 0x00, 0xF7, 0x11, 0xFC, 0x26, 0x10, 0x1F, 0xC0, 0x7F, 0x10, 0x7F,
-0x09, 0xCC, 0x87, 0x30, 0x9F, 0xC0, 0xFC, 0x8A, 0xBF, 0x0D, 0xEC, 0x24, 0xF1,
-0x17, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0x88, 0x39, 0x24, 0xED, 0x00, 0xF4, 0x03, 0xB0, 0x4A, 0x48, 0x0B, 0x00, 0xED,
-0x04, 0xB4, 0x21, 0x10, 0x4E, 0x42, 0x7B, 0x01, 0x29, 0x01, 0x84, 0x03, 0xF0,
-0x0E, 0x44, 0x38, 0x00, 0x8D, 0x43, 0x34, 0x21, 0xD0, 0x84, 0x40, 0x57, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x39, 0x00, 0xED,
-0x10, 0x94, 0x01, 0x98, 0x02, 0x40, 0x0B, 0x04, 0xED, 0x80, 0xF4, 0x00, 0x90,
-0x02, 0x41, 0x3B, 0x01, 0x0D, 0x08, 0x94, 0x03, 0x10, 0x0E, 0x48, 0x38, 0x20,
-0x25, 0x02, 0xB4, 0x20, 0xD8, 0x0E, 0x40, 0x23, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0xCD, 0x01, 0x74, 0x42, 0x90,
-0x00, 0x40, 0x03, 0x00, 0xCD, 0x00, 0x34, 0x2D, 0x90, 0x10, 0x40, 0x37, 0x00,
-0x19, 0x00, 0x14, 0x03, 0xD0, 0x2D, 0x40, 0xB0, 0x00, 0x0D, 0x08, 0x34, 0x03,
-0xD0, 0x0C, 0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0x88, 0x3D, 0x00, 0xFF, 0x01, 0x5C, 0x02, 0xB0, 0xA5, 0xC0, 0x27, 0x90,
-0xF7, 0x00, 0x7C, 0x27, 0xB6, 0xB9, 0xC8, 0x3F, 0x00, 0x9F, 0x20, 0xDC, 0x03,
-0x30, 0xAF, 0xC8, 0x3C, 0x08, 0x8F, 0x01, 0x6C, 0x83, 0xD0, 0x0D, 0xC8, 0x57,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00,
-0xDF, 0x10, 0x7C, 0x28, 0xF0, 0x15, 0xC0, 0xA7, 0x00, 0xDF, 0x00, 0x7C, 0x03,
-0x70, 0x21, 0xC0, 0x77, 0x00, 0x1E, 0x42, 0x25, 0x83, 0xB0, 0x8D, 0xC0, 0x37,
-0x00, 0x1D, 0x02, 0x7C, 0x03, 0xD0, 0x0D, 0xC4, 0x27, 0x00, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x3F, 0x28, 0xFB, 0x40, 0xFC, 0x02,
-0x30, 0x37, 0xC0, 0x2F, 0x04, 0xFF, 0x00, 0xFC, 0x16, 0xF0, 0x03, 0xC0, 0x3F,
-0x00, 0x33, 0x00, 0xCC, 0x03, 0x71, 0x0F, 0xE0, 0x3C, 0x0C, 0xBF, 0x20, 0xDC,
-0x03, 0xF2, 0x0B, 0xC2, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA1, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xB0, 0x05, 0xC0, 0xE7,
-0x00, 0xDD, 0x00, 0x74, 0x0A, 0xD0, 0x11, 0x40, 0x36, 0x00, 0x1B, 0x00, 0x6C,
-0x03, 0x10, 0x0D, 0x40, 0x35, 0x00, 0x1C, 0x03, 0x40, 0x04, 0xD0, 0x35, 0x40,
-0x84, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34,
-0x00, 0xDD, 0x00, 0x74, 0x04, 0x18, 0x0D, 0x40, 0x67, 0x04, 0xDD, 0x00, 0x64,
-0x0A, 0xD0, 0x1B, 0x40, 0x37, 0x00, 0x31, 0x06, 0xC0, 0x03, 0x00, 0x0D, 0x44,
-0x36, 0x00, 0xBD, 0x01, 0x44, 0xA3, 0xD0, 0x64, 0x50, 0x04, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x80, 0xCD, 0x00, 0x36,
-0x00, 0x18, 0x0C, 0x40, 0x01, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD1, 0x00, 0x42,
-0x36, 0x21, 0x19, 0x24, 0x24, 0x03, 0x15, 0x0C, 0x40, 0x30, 0x00, 0x1D, 0x04,
-0x04, 0xA6, 0xD0, 0x28, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0xB0, 0x3E, 0x08, 0xFB, 0x80, 0x7C, 0x00, 0x14, 0x01, 0x40,
-0x27, 0x08, 0xDF, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC2, 0x3F, 0x05, 0x13, 0x16,
-0x8C, 0x03, 0x70, 0x0E, 0xD0, 0x3C, 0x10, 0x1F, 0x1C, 0x5C, 0x01, 0xF0, 0x21,
-0xC0, 0x04, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0,
-0x3F, 0x00, 0xFF, 0x40, 0xFC, 0x02, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x40,
-0xBC, 0x00, 0xF0, 0x03, 0xC0, 0x36, 0x00, 0x1F, 0x14, 0xFC, 0x03, 0xF0, 0x0F,
-0xC4, 0x3F, 0x00, 0x1F, 0x04, 0xFD, 0x10, 0xF2, 0x43, 0x00, 0x17, 0x60, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7D, 0x02, 0xFA, 0x00,
-0xFC, 0x20, 0xB0, 0x0F, 0xC0, 0x3F, 0x20, 0xF7, 0xA0, 0xEC, 0x03, 0x30, 0x4F,
-0xC4, 0x0D, 0x10, 0x33, 0x01, 0xFC, 0x27, 0xF1, 0x33, 0xC0, 0x3E, 0x00, 0x2F,
-0x01, 0x6C, 0x80, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x08, 0x37, 0x20, 0xF1, 0x82, 0x34, 0x3A, 0x10, 0x3F,
-0x40, 0xBE, 0x16, 0xF1, 0x89, 0xF4, 0x0F, 0x10, 0x9F, 0xC8, 0x45, 0x32, 0x95,
-0x00, 0x74, 0x11, 0xD1, 0x41, 0x40, 0x3F, 0x20, 0x1D, 0x54, 0x44, 0x04, 0xD0,
-0x01, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
-0x20, 0x33, 0x11, 0xC1, 0x36, 0x74, 0x03, 0x11, 0x2C, 0x44, 0x33, 0x01, 0xC5,
-0x80, 0x34, 0x23, 0x10, 0x0C, 0x40, 0x03, 0x00, 0x01, 0x00, 0x34, 0x13, 0x90,
-0x00, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x24, 0x80, 0xD8, 0x00, 0x40, 0x47, 0x80,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x75, 0x20, 0xD1,
-0x00, 0x74, 0x07, 0x10, 0x0D, 0x40, 0x36, 0x20, 0xD1, 0x00, 0x74, 0x83, 0x10,
-0x0D, 0x40, 0x97, 0x00, 0x94, 0x04, 0x74, 0x21, 0xD0, 0x11, 0x43, 0x3F, 0x00,
-0x1D, 0x10, 0xC0, 0x60, 0xC0, 0x3B, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x40, 0xDB, 0x00, 0x3C, 0x06, 0xB4,
-0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x6E, 0x03, 0x30, 0x0D, 0xC0, 0x83, 0x00,
-0xD3, 0x80, 0x7C, 0x97, 0xF0, 0x11, 0xC8, 0x36, 0x00, 0xDF, 0x00, 0x6C, 0x00,
-0xF1, 0x31, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x07, 0x80, 0x3D, 0x00, 0xFF, 0x80, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x20,
-0xDF, 0x00, 0xFA, 0x43, 0xF0, 0x0D, 0xC2, 0x4D, 0x01, 0xFF, 0x01, 0xFC, 0x01,
-0xF0, 0x03, 0xC0, 0x3F, 0x00, 0x3F, 0x09, 0xFC, 0x00, 0xF0, 0x03, 0x40, 0x1F,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x01,
-0xDF, 0x08, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x33, 0x00, 0xDF, 0x40, 0x3C, 0x03,
-0xF0, 0x0D, 0xC0, 0x27, 0x08, 0xDB, 0x00, 0x7C, 0x03, 0x30, 0x21, 0xC0, 0x37,
-0x04, 0xDF, 0x02, 0x4C, 0x00, 0xF0, 0x09, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xF4, 0x09, 0xFD, 0xC1, 0x74, 0x83,
-0x50, 0x3F, 0x44, 0x3F, 0x00, 0xFC, 0x0A, 0xC4, 0x8F, 0xD0, 0x0F, 0x41, 0x34,
-0x00, 0xDD, 0x01, 0x74, 0x81, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x1C, 0x00, 0x44,
-0x12, 0xD0, 0x39, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x07, 0xA0, 0x76, 0x00, 0xC9, 0x47, 0x34, 0x03, 0x18, 0x0C, 0x49, 0x33,
-0x00, 0xCD, 0x03, 0x04, 0x2F, 0xD0, 0x5C, 0x40, 0x31, 0x00, 0x49, 0x00, 0x34,
-0x02, 0x10, 0x00, 0x40, 0xF3, 0x00, 0x1D, 0x00, 0x14, 0x04, 0xD0, 0x00, 0x01,
-0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78,
-0x00, 0xED, 0x01, 0xB4, 0x27, 0x50, 0x9E, 0x40, 0x7B, 0x00, 0xED, 0x35, 0x85,
-0x07, 0xD0, 0x5E, 0x40, 0x69, 0x80, 0xED, 0x03, 0xF4, 0x06, 0x90, 0x92, 0x02,
-0x7B, 0x00, 0x3D, 0x01, 0x96, 0x24, 0xD0, 0x9A, 0x48, 0x13, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x02, 0xCF, 0x08, 0x3C,
-0x03, 0x3A, 0x0C, 0xC1, 0x33, 0x00, 0xCF, 0x0D, 0x2C, 0x03, 0xF0, 0x5C, 0xC0,
-0x11, 0x00, 0x4B, 0x10, 0x3C, 0x06, 0x30, 0x00, 0xC2, 0x33, 0x06, 0xCF, 0x00,
-0x1C, 0x14, 0xF0, 0x00, 0xC1, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFE, 0x00, 0xF8, 0x03, 0xF8, 0x0F, 0xC9,
-0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x1C, 0x00, 0xFF, 0x08,
-0x3C, 0x02, 0x75, 0x07, 0xC6, 0x3F, 0x00, 0xFF, 0x00, 0xED, 0x20, 0xF0, 0x0B,
-0xE8, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0,
-0x37, 0x10, 0xDE, 0x44, 0x7C, 0x03, 0x30, 0x5D, 0xC2, 0x34, 0x11, 0xD3, 0x04,
-0x7C, 0x0B, 0xF3, 0x3D, 0xD1, 0x34, 0x00, 0xD3, 0x01, 0x4C, 0x03, 0xF0, 0x01,
-0xD0, 0xB4, 0x07, 0xCE, 0x00, 0x4C, 0x04, 0x32, 0x19, 0xC0, 0x54, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x38, 0x00, 0xED, 0x96,
-0xF4, 0x03, 0xB0, 0x0C, 0x55, 0x38, 0x14, 0xE1, 0x16, 0xB4, 0x5B, 0xD0, 0x4C,
-0x40, 0x20, 0x10, 0xF1, 0x80, 0x84, 0x03, 0xD0, 0x02, 0x40, 0x38, 0x01, 0xED,
-0x00, 0x84, 0x02, 0x11, 0x0B, 0xC0, 0x4A, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0x00, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x10, 0x1E,
-0x4A, 0x70, 0x13, 0xE1, 0x01, 0xA4, 0x07, 0xD0, 0x5E, 0x40, 0x78, 0x40, 0xE1,
-0x01, 0x84, 0x07, 0xD0, 0x16, 0x43, 0x78, 0x81, 0xFD, 0x01, 0x04, 0x84, 0x18,
-0x1A, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x28, 0x23, 0x02, 0xDD, 0x00, 0x34, 0x03, 0x92, 0x0C, 0x40, 0x30, 0x40, 0xC1,
-0x20, 0x34, 0x03, 0xD0, 0x0C, 0x48, 0x30, 0x04, 0xC1, 0x08, 0x04, 0x07, 0xD0,
-0x2C, 0x41, 0x30, 0x00, 0xDD, 0x10, 0x04, 0x0F, 0x18, 0x3C, 0x40, 0x4A, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x55, 0x00, 0x5F,
-0x80, 0xFC, 0x29, 0x30, 0x05, 0xC0, 0x14, 0x00, 0x43, 0x00, 0x7C, 0x01, 0xF0,
-0x05, 0x82, 0x1C, 0x00, 0x73, 0x03, 0xCD, 0x15, 0xF0, 0x37, 0xC0, 0x14, 0x00,
-0x7F, 0x12, 0xCC, 0x15, 0x30, 0x17, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x20, 0x7C, 0x00, 0xF0,
-0x01, 0xC0, 0x07, 0x08, 0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01, 0xC8, 0x87, 0x00,
-0x1F, 0x10, 0x7C, 0x80, 0xF3, 0x01, 0xC0, 0x07, 0x30, 0x1F, 0x00, 0x7D, 0x10,
-0xF1, 0x81, 0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x08, 0x67, 0x00, 0x93, 0x00, 0x4C, 0x02, 0x70, 0x19, 0xC0, 0x27, 0x00,
-0x97, 0x01, 0x5C, 0x26, 0xF0, 0x19, 0xC0, 0x23, 0x00, 0x90, 0x80, 0x7C, 0x02,
-0x30, 0x09, 0xC0, 0xA4, 0x00, 0x9F, 0x05, 0x4C, 0x12, 0xF0, 0x29, 0xC0, 0x43,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE2, 0x22,
-0x91, 0x00, 0x14, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x03, 0x44, 0x8A,
-0xD0, 0x99, 0x44, 0x27, 0x02, 0x91, 0x02, 0x74, 0x82, 0x12, 0x08, 0x42, 0x24,
-0x00, 0x9D, 0x01, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x44, 0x91, 0x21, 0x54, 0x03,
-0x50, 0x49, 0x41, 0x23, 0x00, 0x95, 0x86, 0x54, 0x0A, 0xD1, 0x09, 0x40, 0x27,
-0x00, 0x95, 0x01, 0x34, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44,
-0x02, 0xD0, 0x09, 0x41, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x20, 0x24, 0x00, 0xC1, 0x00, 0x54, 0x52, 0x54, 0x08, 0x40, 0x23,
-0x02, 0x81, 0x80, 0x00, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x40, 0x85, 0x01, 0x34,
-0x22, 0x10, 0x89, 0x42, 0x60, 0x01, 0x8D, 0x08, 0x04, 0x12, 0xD0, 0x48, 0x48,
-0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06,
-0x00, 0x13, 0x94, 0x5C, 0x10, 0x74, 0x41, 0xC1, 0x87, 0x05, 0x16, 0x94, 0x5C,
-0x50, 0xF1, 0x45, 0xC1, 0x17, 0x05, 0x17, 0x0A, 0x7C, 0x08, 0x34, 0x20, 0xC0,
-0xC4, 0x02, 0x1F, 0x02, 0x4D, 0x04, 0xF0, 0xB1, 0xC0, 0x77, 0xC0, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x05, 0x9F, 0x34, 0xFC,
-0x52, 0xB0, 0x09, 0xC2, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
-0x2F, 0x00, 0xBB, 0x01, 0xFC, 0x12, 0xF0, 0x4B, 0xD0, 0x67, 0x02, 0xBF, 0x04,
-0xFC, 0x22, 0xF0, 0x9B, 0xC2, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x2F, 0x02, 0xBF, 0x86, 0x0C, 0x16, 0xB0, 0x4B, 0xC0,
-0x27, 0x05, 0xBB, 0x00, 0xDC, 0x82, 0x30, 0x0B, 0xC0, 0x2D, 0x00, 0xBF, 0xC0,
-0x7C, 0x22, 0x30, 0x29, 0xC0, 0x2F, 0x00, 0xB1, 0x02, 0xCC, 0x02, 0xE0, 0x0B,
-0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
-0x47, 0x01, 0x1D, 0x01, 0x44, 0x5C, 0x10, 0x01, 0x40, 0x87, 0x01, 0x1D, 0x00,
-0x44, 0x00, 0x14, 0xA1, 0x40, 0x04, 0x00, 0x0D, 0x00, 0x74, 0x00, 0x10, 0x01,
-0x40, 0x07, 0x00, 0x15, 0x04, 0x45, 0x00, 0xD2, 0x01, 0x48, 0x70, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x06,
-0x04, 0x22, 0x92, 0x28, 0x40, 0x23, 0x04, 0x8D, 0x22, 0x04, 0x8A, 0x10, 0x08,
-0x50, 0xA0, 0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x08, 0x60, 0x23, 0x10, 0x81,
-0x20, 0x05, 0x83, 0xD0, 0x09, 0x60, 0x42, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x80, 0x9D, 0x00, 0x45, 0x02, 0x10, 0x09,
-0x60, 0x27, 0x00, 0x9D, 0x00, 0x47, 0x02, 0x10, 0x09, 0x00, 0x24, 0x01, 0x9D,
-0x00, 0x74, 0x02, 0x10, 0xA9, 0x40, 0x27, 0x00, 0x95, 0x14, 0x45, 0x0E, 0xD1,
-0x69, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0x88, 0x67, 0x02, 0x9F, 0x00, 0x4C, 0x36, 0xB0, 0x09, 0xC8, 0x27, 0x00, 0x9B,
-0x40, 0x5C, 0x02, 0x12, 0x09, 0xC0, 0x24, 0x01, 0x9E, 0x00, 0x7C, 0x02, 0x34,
-0x29, 0xC0, 0x27, 0x00, 0x83, 0x01, 0x4C, 0x0E, 0xF2, 0x29, 0xD0, 0x16, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x10, 0x9F,
-0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x50, 0x3C, 0x02, 0xF0,
-0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
-0x9F, 0x01, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x51, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x04, 0x00, 0x03, 0x00, 0x4D, 0x00, 0x50,
-0x01, 0xC0, 0x05, 0x00, 0x03, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x87, 0x01,
-0x13, 0x00, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x01, 0x01, 0x13, 0x02, 0x4C, 0x00,
-0x30, 0x21, 0xC1, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0xA0, 0xDC, 0x00, 0x75, 0x19, 0x44, 0x01, 0x50, 0x27, 0xC0, 0x16, 0x50,
-0x71, 0x23, 0xF4, 0x21, 0xD0, 0x06, 0x41, 0x1F, 0x20, 0x75, 0x01, 0x44, 0x01,
-0xD0, 0x05, 0x48, 0x1F, 0x18, 0x75, 0x0A, 0x44, 0x01, 0x11, 0x27, 0xC0, 0x52,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x72, 0x81,
-0xC9, 0x03, 0x04, 0x03, 0x10, 0x9C, 0x41, 0x33, 0x00, 0x81, 0x03, 0x34, 0x2B,
-0xD0, 0x2C, 0x40, 0x33, 0x00, 0xC5, 0x11, 0x44, 0x03, 0xD0, 0x0C, 0x40, 0xF1,
-0x80, 0xC9, 0x01, 0x04, 0x03, 0x12, 0x8D, 0x40, 0x52, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x78, 0x04, 0xED, 0x20, 0xC4, 0x03,
-0x50, 0x1A, 0x40, 0x7A, 0x00, 0xE1, 0x00, 0xB0, 0x01, 0xD0, 0x0E, 0x40, 0x7B,
-0x48, 0xE5, 0x11, 0x84, 0x23, 0xC0, 0x8E, 0x40, 0x13, 0x04, 0xED, 0x10, 0xC4,
-0x07, 0x1C, 0x0B, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0x10, 0x7C, 0x00, 0xFB, 0x81, 0x8C, 0x47, 0x74, 0x1E, 0xC0, 0x73,
-0x01, 0xA3, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x00, 0x67, 0x81, 0x84,
-0xD7, 0xF0, 0x1E, 0xC1, 0x69, 0x20, 0xBB, 0x01, 0x8D, 0x07, 0x30, 0x1B, 0xC0,
-0x56, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15,
-0x00, 0xD7, 0x00, 0x7C, 0x33, 0xF0, 0x00, 0xC0, 0xB5, 0x20, 0x9F, 0x00, 0x7C,
-0x00, 0xF1, 0x09, 0xC0, 0x33, 0x00, 0x1B, 0x00, 0x75, 0x03, 0xF2, 0x6D, 0xC0,
-0x07, 0x00, 0x97, 0x00, 0x3C, 0x02, 0xF1, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x5F, 0x00, 0x7F, 0x01, 0xFC,
-0x07, 0x70, 0x1F, 0xC0, 0xFF, 0x44, 0xB3, 0x09, 0x9C, 0x27, 0x70, 0x9F, 0xC0,
-0x7F, 0x00, 0xA3, 0x41, 0xEC, 0x07, 0x31, 0x1D, 0xC0, 0x4F, 0x00, 0xF3, 0x01,
-0xCC, 0x07, 0x30, 0x9B, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0x88, 0xB9, 0x00, 0x6D, 0x02, 0xB4, 0x03, 0xB0, 0x0A, 0x60,
-0x3B, 0x00, 0xC1, 0x08, 0xB4, 0x82, 0x10, 0x04, 0x48, 0x3B, 0x00, 0x21, 0x00,
-0x04, 0x37, 0x10, 0x1E, 0xC0, 0x0F, 0x00, 0xFB, 0x18, 0xC4, 0x23, 0xB2, 0xCA,
-0x50, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x19, 0x00, 0x6D, 0x08, 0xF4, 0x03, 0x50, 0x0A, 0x40, 0x39, 0x00, 0xA9, 0x80,
-0x94, 0x02, 0x50, 0x0E, 0x60, 0x1B, 0x02, 0x39, 0x00, 0xC4, 0x13, 0x10, 0x0E,
-0x41, 0x0B, 0x00, 0xB1, 0x00, 0xC4, 0x43, 0x50, 0x0A, 0x40, 0x01, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x43, 0x20, 0x0D, 0x80,
-0x34, 0x03, 0x90, 0x00, 0x40, 0x37, 0x08, 0x49, 0x40, 0x34, 0x02, 0x10, 0x00,
-0x44, 0x53, 0x42, 0x09, 0x02, 0x04, 0x03, 0x94, 0x1D, 0x40, 0x01, 0x00, 0x89,
-0x10, 0x04, 0x06, 0xD8, 0x60, 0x40, 0x11, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0xA8, 0x64, 0x01, 0x9F, 0x00, 0xFC, 0x03, 0x74, 0x01,
-0xC0, 0x3F, 0x00, 0x9B, 0x00, 0x5C, 0x02, 0x50, 0x01, 0xC0, 0x37, 0x08, 0x13,
-0x02, 0xCC, 0x03, 0x30, 0xBF, 0x40, 0x37, 0x00, 0x53, 0x00, 0x4D, 0xAB, 0x50,
-0x09, 0xC1, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x00, 0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x43, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xD7,
-0x20, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x33, 0x00, 0x17, 0x82, 0x5C, 0x43, 0x70,
-0x0D, 0xC0, 0x87, 0x00, 0x5F, 0xC2, 0x7C, 0x03, 0xB0, 0x29, 0x88, 0x06, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x20, 0x2F,
-0x80, 0xD4, 0x03, 0x3C, 0x02, 0xC8, 0x34, 0x00, 0xB3, 0x00, 0xDC, 0x00, 0xF0,
-0x2B, 0xE0, 0x24, 0x20, 0x33, 0x10, 0xF4, 0x03, 0xB0, 0x0F, 0xC0, 0x0C, 0x00,
-0x7F, 0x00, 0xCC, 0x27, 0xF0, 0x09, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x00, 0x9D, 0x43, 0x06, 0x03, 0x10,
-0x11, 0x40, 0x34, 0x00, 0x81, 0x00, 0x44, 0x14, 0xD0, 0x18, 0xE0, 0x26, 0x00,
-0x11, 0x04, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x44, 0x01, 0x47, 0x85, 0x7C, 0x02,
-0xD0, 0x51, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0xA0, 0x44, 0x00, 0x9D, 0x21, 0x40, 0x03, 0x92, 0x39, 0x44, 0x34, 0x00,
-0x91, 0x00, 0x56, 0x06, 0xD2, 0x25, 0x48, 0x74, 0x00, 0x31, 0x84, 0x74, 0x83,
-0xD8, 0x0D, 0x40, 0x4C, 0x00, 0x9D, 0x01, 0x45, 0x02, 0xD0, 0x13, 0x40, 0x07,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00,
-0x8D, 0x20, 0x54, 0x03, 0x12, 0x08, 0x40, 0x30, 0x20, 0xC1, 0x40, 0x16, 0x02,
-0xD0, 0x24, 0x44, 0x32, 0x10, 0x01, 0x00, 0x34, 0x33, 0xD8, 0x0C, 0x45, 0x00,
-0x10, 0x85, 0x00, 0x34, 0x22, 0xD0, 0x00, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x08, 0x1F, 0x00, 0xD4, 0x03,
-0x32, 0x09, 0xC2, 0x3C, 0x00, 0x93, 0x2A, 0x54, 0x00, 0xD9, 0x0D, 0x40, 0x04,
-0x00, 0x13, 0x00, 0xFC, 0x9B, 0xB1, 0x0F, 0xC0, 0x04, 0x00, 0x9F, 0x00, 0x4C,
-0x02, 0xF1, 0x01, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0xB2, 0x2F, 0x00, 0xBF, 0x00, 0xAD, 0x03, 0xF1, 0x03, 0xC0, 0x3F,
-0x10, 0x7F, 0x04, 0xEC, 0x00, 0xF0, 0x03, 0xC6, 0x0F, 0x40, 0x3F, 0x00, 0x3C,
-0x0B, 0xF0, 0x0F, 0xC0, 0x0D, 0x10, 0xB7, 0x00, 0xFC, 0x12, 0xF8, 0x03, 0xC0,
-0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x2F,
-0x01, 0xBF, 0x08, 0xFC, 0x43, 0x30, 0x8F, 0xC0, 0x3F, 0x05, 0x3F, 0x03, 0xDC,
-0x23, 0xF0, 0x3B, 0xD0, 0x3C, 0x00, 0xFB, 0x00, 0xFC, 0x13, 0x30, 0x13, 0xC0,
-0x7C, 0x10, 0x3D, 0x61, 0xCC, 0x18, 0x30, 0x43, 0xC1, 0x0C, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x87, 0x1D, 0x9D, 0x02, 0xDC,
-0x0F, 0x00, 0x6F, 0x40, 0xBF, 0x01, 0x1D, 0x04, 0xC4, 0x0B, 0x70, 0x0D, 0x40,
-0xFC, 0x00, 0xF1, 0x03, 0xF4, 0xA7, 0x10, 0x11, 0x40, 0x04, 0x08, 0x1D, 0x00,
-0x04, 0xAB, 0x10, 0x29, 0x51, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x13, 0xA0, 0x21, 0x82, 0x0D, 0x08, 0x14, 0x03, 0x10, 0x6C, 0x48,
-0x33, 0x14, 0x9D, 0x00, 0x14, 0x33, 0xD2, 0x48, 0x60, 0x30, 0x0A, 0xC9, 0x08,
-0x34, 0x03, 0x10, 0x01, 0x40, 0x30, 0x20, 0x1D, 0x00, 0x04, 0x10, 0x10, 0x40,
-0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
-0x47, 0x00, 0x9D, 0x03, 0x54, 0x83, 0x14, 0x0D, 0x40, 0x37, 0x00, 0x9D, 0x01,
-0x44, 0x03, 0x50, 0x0C, 0x60, 0x34, 0x10, 0xD0, 0x00, 0x74, 0x03, 0x14, 0x15,
-0x18, 0x24, 0x00, 0x1D, 0x01, 0x44, 0x81, 0x16, 0x01, 0x41, 0x0D, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA8, 0xC7, 0x00, 0x9F, 0x01,
-0x5C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x0F, 0x03, 0x5C, 0x83, 0xF0, 0x8D,
-0xC0, 0x30, 0x08, 0xDB, 0x60, 0x3C, 0x03, 0x30, 0x20, 0xC4, 0x34, 0x00, 0x0F,
-0x53, 0x4C, 0x24, 0x30, 0x11, 0xC4, 0x29, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0xBF, 0x00, 0xDC, 0x03, 0xF1, 0x0D,
-0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xD0, 0x1F, 0xC0, 0x3F, 0x00, 0xFF,
-0x50, 0xF0, 0x83, 0xF0, 0x03, 0xC8, 0x8F, 0x00, 0x3F, 0x00, 0xBC, 0xC7, 0xF0,
-0x3D, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
-0x08, 0xA5, 0x00, 0x1F, 0x00, 0x0C, 0x03, 0xF0, 0x0D, 0xC4, 0x35, 0x00, 0x1F,
-0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0,
-0x05, 0xC0, 0x34, 0x10, 0x1F, 0x00, 0x4C, 0x22, 0x34, 0x2C, 0xC0, 0x28, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x64, 0x04, 0x9D,
-0x00, 0xC4, 0x3B, 0xD0, 0x0F, 0x40, 0x3C, 0x00, 0x9D, 0x00, 0xFC, 0x03, 0xD0,
-0x0D, 0x48, 0x3F, 0x00, 0xF1, 0x03, 0xF4, 0x2B, 0xD0, 0xA5, 0xC0, 0x26, 0x08,
-0x1D, 0x00, 0x44, 0x0F, 0x10, 0x3D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xE2, 0x34, 0x0D, 0x40, 0x04, 0x07, 0x90,
-0x0C, 0x44, 0x30, 0x08, 0x8C, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x48, 0x32, 0x00,
-0xC0, 0x01, 0x34, 0x27, 0xD0, 0x20, 0x40, 0x30, 0x04, 0x0D, 0x00, 0x04, 0x00,
-0x10, 0x04, 0x41, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x0D, 0x02, 0x7A, 0x02, 0x6D, 0x01, 0x84, 0x07, 0xD0, 0x9E, 0x42, 0x78, 0x00,
-0xAD, 0x01, 0x94, 0x07, 0xD0, 0x1E, 0x40, 0x73, 0x02, 0xE5, 0x01, 0xB4, 0x07,
-0xD0, 0x17, 0x40, 0x5B, 0x04, 0x3D, 0x01, 0x84, 0x06, 0x12, 0x92, 0x41, 0x34,
-0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x32, 0x00,
-0x5F, 0x08, 0x0D, 0x03, 0xF0, 0x0C, 0xC0, 0x31, 0x02, 0x8F, 0x08, 0x34, 0x03,
-0xF0, 0x4C, 0xC0, 0x33, 0x0A, 0xC7, 0x10, 0x3C, 0x03, 0xF0, 0xA1, 0xE0, 0x30,
-0x00, 0x5F, 0x00, 0x0C, 0x80, 0x30, 0x50, 0xD0, 0x48, 0x40, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xBA, 0x3D, 0x20, 0xFF, 0x00, 0xFC, 0x03,
-0xF0, 0x0F, 0xC3, 0x3F, 0x00, 0xBF, 0x28, 0xFC, 0x23, 0xF0, 0x0F, 0xC4, 0x3F,
-0x02, 0xDB, 0x10, 0xFC, 0x23, 0xF0, 0x07, 0xE0, 0x3E, 0x80, 0x7F, 0x00, 0xFC,
-0x00, 0xF8, 0x81, 0xC2, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xA0, 0x57, 0x00, 0xD3, 0x00, 0x7C, 0x6F, 0xB0, 0x5D, 0xE0, 0xB7,
-0x14, 0x1F, 0x00, 0x7C, 0x13, 0xF0, 0x0D, 0xC0, 0xB7, 0x03, 0xD3, 0x15, 0x4C,
-0x53, 0xF0, 0x05, 0xE0, 0x77, 0x00, 0x53, 0x00, 0x7C, 0x01, 0x30, 0x0D, 0xC0,
-0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x1D,
-0x00, 0xEB, 0x00, 0xB4, 0x03, 0x18, 0xCF, 0x60, 0xB8, 0x01, 0xED, 0x00, 0xB4,
-0x4B, 0xD0, 0x0E, 0x40, 0x3B, 0x03, 0xC1, 0x04, 0x84, 0x1B, 0xD0, 0x06, 0x40,
-0x1B, 0x20, 0x61, 0x20, 0xF4, 0x03, 0x14, 0x0F, 0x40, 0x4C, 0x60, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x79, 0x14, 0x61, 0x21, 0x36,
-0x07, 0x18, 0x5E, 0x4C, 0x79, 0x00, 0x6D, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x64,
-0x71, 0x01, 0xE1, 0x41, 0x96, 0x17, 0xD0, 0x16, 0x40, 0x7F, 0x00, 0x65, 0x01,
-0xB6, 0x07, 0x94, 0x1E, 0x42, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0xC9, 0x0B, 0x34, 0x83, 0x10, 0x0C, 0x40,
-0x30, 0x00, 0xCD, 0x07, 0x74, 0x03, 0xD0, 0x9C, 0x60, 0x33, 0x40, 0xC1, 0x00,
-0x15, 0x03, 0xD1, 0x1C, 0x42, 0x33, 0x00, 0xC4, 0x06, 0x34, 0x17, 0x90, 0x9C,
-0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8,
-0x1F, 0x00, 0x73, 0x02, 0x7C, 0x01, 0xB0, 0x05, 0xC2, 0x17, 0x00, 0x7F, 0x10,
-0x7C, 0x01, 0xF0, 0x15, 0xC0, 0x13, 0x00, 0x51, 0x00, 0x5C, 0x01, 0xF0, 0x46,
-0xC0, 0x1F, 0x00, 0x77, 0x12, 0xFA, 0x1D, 0xB0, 0xB7, 0xC4, 0x5C, 0x20, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x04,
-0x7C, 0x00, 0xF4, 0x01, 0xC8, 0x07, 0x00, 0x1C, 0x00, 0x7C, 0x00, 0xF0, 0x01,
-0xC0, 0x07, 0x00, 0x1F, 0x00, 0x64, 0x00, 0xF0, 0x01, 0xC4, 0x07, 0x40, 0x1B,
-0x00, 0x7C, 0x08, 0x70, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x08, 0xE5, 0x04, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x9F, 0xA0, 0x4C, 0x02, 0x32, 0x09, 0xC8, 0x27, 0x09, 0x93,
-0x00, 0x3C, 0x92, 0x30, 0x19, 0xC1, 0x26, 0x01, 0x9F, 0x00, 0x3C, 0x06, 0x30,
-0x89, 0xC0, 0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x26, 0x10, 0x9D, 0x80, 0x74, 0x32, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D,
-0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x09, 0x91, 0x23, 0x74, 0x4E, 0x14,
-0x99, 0x42, 0xA4, 0x04, 0x9D, 0x00, 0x74, 0x0A, 0x10, 0x29, 0x44, 0x04, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x34, 0x00, 0x9D,
-0x00, 0x54, 0x02, 0xC0, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x00, 0x44, 0x02, 0x50,
-0x09, 0x42, 0x25, 0x40, 0x91, 0x18, 0x74, 0x02, 0x90, 0x29, 0x40, 0x26, 0x00,
-0x9D, 0x00, 0x74, 0x22, 0x08, 0x08, 0x40, 0x71, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x30, 0x05, 0x8D, 0x54, 0x34, 0x02, 0xD0,
-0x88, 0x40, 0x23, 0x02, 0x8D, 0x88, 0x05, 0x22, 0x10, 0x88, 0x40, 0x23, 0x00,
-0x81, 0x00, 0x30, 0x02, 0x10, 0x08, 0x42, 0x20, 0x00, 0x8D, 0x00, 0x36, 0x23,
-0x10, 0x08, 0x40, 0x50, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1D, 0xB0, 0x06, 0x21, 0x1F, 0x24, 0x5C, 0xD0, 0xF0, 0x61, 0xC5, 0x87, 0x05,
-0x1F, 0x02, 0x4C, 0x58, 0x70, 0x21, 0xC0, 0x05, 0x05, 0x13, 0x34, 0x7C, 0x50,
-0x30, 0x01, 0xC0, 0x86, 0x02, 0x1F, 0x0A, 0x7C, 0x58, 0x34, 0x45, 0xC1, 0x75,
-0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x05,
-0xBF, 0x34, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0xBF, 0x04, 0x7C, 0x12,
-0xF4, 0x4B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x0B, 0xC0, 0x6B,
-0x00, 0xBF, 0x21, 0xFC, 0x12, 0xF0, 0x4B, 0xC1, 0x67, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0x93, 0x02, 0xDC, 0x02,
-0xF0, 0x89, 0xC0, 0xA6, 0x15, 0x9B, 0x00, 0x5C, 0x42, 0x30, 0x09, 0xC0, 0x2E,
-0x04, 0xBF, 0x00, 0xDC, 0x02, 0xB2, 0x0B, 0xC0, 0x2F, 0x08, 0x9F, 0x00, 0xCC,
-0xC2, 0x32, 0x0B, 0xD0, 0x60, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1C, 0x18, 0x07, 0x01, 0x1B, 0x60, 0x74, 0xA8, 0xD0, 0xA0, 0x42, 0x84,
-0x00, 0x11, 0x20, 0x74, 0x08, 0x10, 0x41, 0x40, 0x84, 0x00, 0x17, 0x4A, 0x44,
-0x28, 0x10, 0x01, 0x44, 0x07, 0x20, 0x1D, 0x00, 0x44, 0x08, 0x14, 0x01, 0x40,
-0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0xA1,
-0x84, 0x81, 0x02, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x22, 0x01, 0x85, 0x14, 0x34,
-0x52, 0x12, 0x09, 0x61, 0x22, 0x00, 0x8D, 0x00, 0x14, 0x02, 0x10, 0x08, 0x40,
-0x33, 0x80, 0x8D, 0x00, 0x04, 0x02, 0x10, 0x08, 0x62, 0x4A, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x99, 0x80, 0x74,
-0x02, 0xC0, 0x08, 0x40, 0x26, 0x20, 0x95, 0x02, 0x34, 0x02, 0x10, 0x09, 0x4A,
-0x24, 0x00, 0x95, 0x00, 0x54, 0x02, 0x10, 0x0D, 0x40, 0xA7, 0x00, 0x8D, 0x14,
-0x45, 0x02, 0x10, 0x0D, 0x40, 0x62, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0xA8, 0x27, 0x01, 0x93, 0x87, 0x7C, 0x02, 0xF0, 0x09, 0xC8,
-0x26, 0x08, 0x97, 0x00, 0x5E, 0x02, 0x10, 0x08, 0xC0, 0x26, 0x20, 0x9F, 0x20,
-0x5C, 0x02, 0xB0, 0x59, 0xC0, 0x27, 0x20, 0x9E, 0x23, 0x4C, 0x42, 0x30, 0x49,
-0xC0, 0x16, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80,
-0x61, 0x02, 0x9F, 0x05, 0x7C, 0x02, 0xD0, 0x09, 0xC0, 0x21, 0x40, 0x9B, 0x84,
-0x7C, 0x02, 0xF4, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x42, 0xD4, 0x39,
-0xC0, 0x27, 0x00, 0x9F, 0x21, 0x7C, 0x02, 0xF0, 0x48, 0xC0, 0x49, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x84, 0x04, 0x1F, 0x02,
-0x6C, 0x00, 0xE0, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x80, 0x7C, 0x00, 0x30, 0x01,
-0xC0, 0x05, 0x04, 0x1F, 0x10, 0x4C, 0x00, 0x70, 0x11, 0xC2, 0x07, 0x01, 0x1F,
-0xA2, 0x3C, 0x20, 0x10, 0x41, 0xC2, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0xA0, 0xDC, 0x00, 0x5D, 0x20, 0xD4, 0x65, 0xC0, 0x05,
-0x40, 0x14, 0x00, 0x50, 0x00, 0x74, 0x81, 0x10, 0x05, 0xC0, 0x1C, 0x00, 0x6D,
-0x20, 0x80, 0x0D, 0x70, 0x07, 0x80, 0x1D, 0x10, 0x5D, 0x80, 0xF4, 0x01, 0x10,
-0x37, 0x42, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0xA0, 0xF2, 0x02, 0xCD, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x50, 0x30, 0x80, 0xC1,
-0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x31, 0x00, 0xCD, 0x0A, 0x00, 0x0B, 0xD8,
-0x8C, 0x48, 0xB2, 0x00, 0xCC, 0x00, 0x36, 0x93, 0x90, 0x00, 0x44, 0x53, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x00, 0xCD,
-0x01, 0x94, 0x00, 0xD0, 0x0E, 0x40, 0x38, 0xC2, 0xE1, 0x04, 0xB4, 0x23, 0x11,
-0x0E, 0x40, 0x38, 0x80, 0x8D, 0x00, 0x85, 0x0B, 0xD8, 0x06, 0x40, 0x09, 0x20,
-0xED, 0x04, 0x34, 0x00, 0x94, 0x0A, 0x41, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x78, 0x00, 0xEF, 0x0D, 0x84, 0x04, 0xF0,
-0x1E, 0xC1, 0x70, 0x05, 0xE1, 0x0D, 0x34, 0x57, 0x34, 0x3F, 0xC0, 0x79, 0x00,
-0xAF, 0x01, 0x8C, 0x07, 0x70, 0x16, 0xC0, 0x6B, 0x00, 0xEF, 0x0B, 0xBC, 0x07,
-0xB0, 0x16, 0xC0, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xA2, 0x15, 0x10, 0xDF, 0x84, 0x5C, 0x00, 0xF0, 0x4D, 0xC0, 0x37, 0x00,
-0xDF, 0x04, 0x7C, 0x1B, 0xF0, 0x6D, 0xC9, 0x37, 0x20, 0x1B, 0x00, 0x7C, 0x00,
-0x78, 0x05, 0xC0, 0x07, 0x10, 0xDF, 0x00, 0x7C, 0x00, 0x74, 0x0D, 0xC0, 0x43,
-0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7D, 0x00,
-0xFF, 0x11, 0x8C, 0x24, 0x70, 0x1F, 0xC5, 0x7C, 0x00, 0xF3, 0x11, 0xFC, 0x07,
-0x30, 0x1F, 0xC0, 0x7F, 0x02, 0xB7, 0x05, 0xFC, 0x07, 0xF8, 0x96, 0xC0, 0x6C,
-0x02, 0xF3, 0x89, 0xCC, 0x07, 0x24, 0x1B, 0xC4, 0x00, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x08, 0x39, 0x20, 0xED, 0x04, 0x84, 0x00,
-0x18, 0x0E, 0x50, 0x38, 0x22, 0xE1, 0x00, 0xB4, 0x23, 0x10, 0x0E, 0x40, 0x3B,
-0x00, 0xA7, 0x00, 0xB4, 0x23, 0xD0, 0x06, 0x48, 0x0D, 0x02, 0xFB, 0x40, 0x85,
-0x00, 0xF0, 0x88, 0xE1, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x39, 0x04, 0xED, 0x80, 0xA4, 0x00, 0x58, 0x0C, 0x40, 0x39,
-0x00, 0xE9, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x1B, 0x00, 0xA5, 0x04, 0xB4,
-0x03, 0xD0, 0x03, 0x46, 0x08, 0x82, 0xE1, 0x00, 0x84, 0x03, 0x50, 0x0C, 0x40,
-0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x61,
-0x00, 0xCD, 0x41, 0x04, 0x00, 0x10, 0x0C, 0x40, 0x34, 0x00, 0xD1, 0x42, 0x34,
-0x03, 0x12, 0x8C, 0x40, 0x13, 0x00, 0x05, 0x00, 0x34, 0x00, 0xD0, 0xB0, 0x44,
-0x01, 0x00, 0xC9, 0x02, 0x04, 0x41, 0xD0, 0x34, 0x50, 0x10, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x45, 0x20, 0xFF, 0x9A, 0x6C,
-0x00, 0x41, 0x0F, 0xC0, 0x3D, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0x30, 0x1F, 0xC0,
-0x37, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0x44, 0x00, 0x06, 0xF3, 0x42,
-0x4C, 0x4B, 0x30, 0x25, 0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x00, 0xA7, 0x01, 0xDF, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC0,
-0x37, 0x20, 0xDF, 0x08, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x9F, 0x80,
-0x3C, 0x8B, 0xF0, 0x01, 0xC8, 0x87, 0x00, 0xDF, 0x00, 0x3C, 0x00, 0x96, 0x65,
-0xC0, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08,
-0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x10,
-0x5C, 0x03, 0xE0, 0x0F, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xFC, 0x83, 0x30, 0x03,
-0xC1, 0x0D, 0x20, 0xF3, 0x10, 0x7C, 0x07, 0x30, 0x97, 0xC2, 0x13, 0x22, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0xC6, 0x04, 0xDD, 0x00,
-0x74, 0x0C, 0xD0, 0x0D, 0x50, 0x34, 0x20, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D,
-0x40, 0x27, 0x00, 0x19, 0x01, 0x74, 0x18, 0x00, 0x31, 0xC0, 0x47, 0x01, 0xD1,
-0x00, 0x74, 0x20, 0x10, 0x29, 0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0xA0, 0x44, 0x00, 0xDD, 0x00, 0x74, 0x44, 0xD0, 0x0C,
-0x40, 0x34, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x80, 0x1D,
-0x03, 0x74, 0x10, 0x10, 0x11, 0x40, 0x4F, 0x00, 0xF1, 0x00, 0x74, 0x43, 0x19,
-0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x28, 0x20, 0x20, 0xCD, 0x80, 0x24, 0x00, 0xD2, 0x0C, 0x40, 0x30, 0x20, 0xC1,
-0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x80, 0x09, 0x00, 0x34, 0x00, 0x10,
-0x00, 0x44, 0x07, 0x40, 0xC1, 0x00, 0x34, 0x02, 0x13, 0x84, 0x40, 0x43, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x00, 0xEF,
-0x80, 0x7C, 0x80, 0xF0, 0x0F, 0xC0, 0x38, 0x00, 0xF3, 0x00, 0xC5, 0x03, 0xF0,
-0x0F, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x05, 0x00,
-0xF3, 0x00, 0x7C, 0x00, 0x30, 0x09, 0xC8, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x85, 0xA8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0,
-0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xEC, 0x83, 0xF0, 0x0F, 0xC0, 0x0F, 0x00,
-0x3B, 0x40, 0xFC, 0x00, 0xF0, 0x03, 0xE8, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x00,
-0xF0, 0x43, 0xC0, 0x17, 0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA8, 0x3F, 0x04, 0xB3, 0x08, 0xCC, 0x93, 0xF1, 0xCF, 0xC0, 0x3C, 0x42,
-0xF3, 0x00, 0xFC, 0x03, 0x30, 0x13, 0xC0, 0x3D, 0x05, 0xF7, 0x2C, 0xFC, 0x04,
-0xB0, 0x0F, 0xC0, 0x3E, 0x06, 0x3F, 0x04, 0xEC, 0x03, 0xF0, 0x83, 0xC0, 0x0F,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0xBF, 0x00,
-0x1B, 0x04, 0xC4, 0xAF, 0xD0, 0x6F, 0x40, 0xBC, 0x03, 0xF1, 0x84, 0xF4, 0x0F,
-0x10, 0x09, 0xC4, 0x7D, 0x08, 0xD5, 0x08, 0x74, 0x00, 0x50, 0x2F, 0x42, 0x3C,
-0x10, 0x1D, 0x12, 0xC4, 0x87, 0xD0, 0x40, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x04, 0x81, 0x22, 0x04, 0x03,
-0xD0, 0x2C, 0x44, 0x31, 0x01, 0xC1, 0x18, 0x24, 0x0B, 0x50, 0x04, 0x40, 0x31,
-0x00, 0xC5, 0x00, 0x74, 0x02, 0x10, 0x2C, 0x44, 0x33, 0x01, 0x8D, 0x06, 0x24,
-0x03, 0xD0, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0xA0, 0x34, 0x30, 0x09, 0x41, 0x46, 0x03, 0xD0, 0x0D, 0x40, 0x35,
-0x00, 0xD1, 0x00, 0x74, 0x03, 0x14, 0x0D, 0x40, 0x35, 0x00, 0xD4, 0x00, 0x74,
-0x22, 0x50, 0x0D, 0x40, 0x35, 0x00, 0xDD, 0x00, 0xC4, 0x03, 0xD0, 0x33, 0x40,
-0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37,
-0x00, 0x93, 0x03, 0x4C, 0x83, 0xF0, 0x0D, 0xC0, 0x35, 0x20, 0xD3, 0x80, 0x7C,
-0x03, 0x72, 0x91, 0xC8, 0x35, 0x00, 0xD7, 0x80, 0x7C, 0x45, 0xB0, 0x0D, 0xC0,
-0x37, 0x18, 0x1F, 0xA2, 0x6C, 0x03, 0xF0, 0x11, 0xC0, 0x03, 0x20, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xBF, 0x40, 0xFD,
-0x03, 0xF0, 0x0D, 0xC2, 0x36, 0x00, 0xFF, 0x00, 0xBC, 0x03, 0xF0, 0x03, 0xC1,
-0x3F, 0x00, 0xD9, 0x00, 0xFC, 0x41, 0xF0, 0x0D, 0xC0, 0x3E, 0x08, 0xFC, 0x09,
-0xFC, 0x03, 0xF0, 0x03, 0x80, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x08, 0x31, 0x01, 0x9F, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
-0x31, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x35, 0x00, 0xD7, 0x00,
-0x4C, 0x22, 0xB0, 0x0C, 0xC8, 0x34, 0x08, 0x07, 0x00, 0x5C, 0x03, 0x30, 0x21,
-0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
-0xFC, 0x0C, 0x9D, 0x00, 0xFC, 0x0F, 0xD0, 0x0F, 0x44, 0x3C, 0x00, 0xF1, 0x00,
-0xF4, 0x07, 0xD0, 0x15, 0xC2, 0x39, 0x08, 0xF0, 0x03, 0x2C, 0x8B, 0xD0, 0x0F,
-0x48, 0x3C, 0x00, 0xD5, 0x10, 0xC4, 0x2F, 0x10, 0x09, 0x40, 0x4C, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x32, 0x00, 0x0D, 0x00,
-0x34, 0x43, 0xD0, 0x0D, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x1B, 0xD2, 0x14,
-0x48, 0x32, 0x00, 0xC8, 0x87, 0x04, 0x0D, 0xD0, 0x0C, 0x00, 0x31, 0x00, 0x41,
-0x10, 0x14, 0x23, 0x10, 0x00, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x88, 0x78, 0x00, 0x6D, 0x01, 0xB4, 0x67, 0xD0, 0x9E,
-0x40, 0x78, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x73, 0x48, 0xED,
-0x01, 0xA4, 0x05, 0xD1, 0x1E, 0x40, 0x71, 0x00, 0xE5, 0x01, 0xC4, 0x17, 0x14,
-0x92, 0x40, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x10, 0x30, 0x02, 0xCF, 0x0C, 0x34, 0x03, 0xF0, 0x0C, 0x48, 0x31, 0x00, 0xC3,
-0x00, 0x3C, 0x43, 0xF0, 0x04, 0xC1, 0x32, 0x00, 0xCF, 0x10, 0x0C, 0x00, 0xB0,
-0x8C, 0xD0, 0x31, 0xA0, 0x17, 0x22, 0x5C, 0x17, 0x30, 0x50, 0xD0, 0x48, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x3D, 0x0C, 0xFF,
-0x88, 0xDC, 0x83, 0xF0, 0x2F, 0x00, 0x3F, 0x00, 0xDF, 0x00, 0xF4, 0x03, 0xF0,
-0x0F, 0xC0, 0x3D, 0x30, 0xF3, 0x08, 0x7C, 0x01, 0xF0, 0x0F, 0xC0, 0x3E, 0xA0,
-0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x89, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x24, 0x5F, 0x40, 0x7C, 0x6F, 0x30,
-0xBD, 0xC0, 0xF4, 0x05, 0xD3, 0x68, 0x1C, 0x63, 0x70, 0x01, 0xD0, 0x36, 0x01,
-0xDF, 0x49, 0x4C, 0x05, 0x30, 0x4D, 0xC9, 0x37, 0x03, 0x1F, 0x00, 0x4D, 0x63,
-0xF0, 0x11, 0x84, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x88, 0x39, 0x01, 0x6D, 0x60, 0x36, 0x13, 0x10, 0x4E, 0x40, 0xB8, 0x01,
-0xE1, 0x0C, 0x84, 0x03, 0x10, 0x07, 0xC0, 0xB8, 0x04, 0xED, 0x84, 0xAC, 0x01,
-0x10, 0x4E, 0x48, 0x3B, 0x04, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x02, 0x40, 0x48,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x01,
-0xED, 0x03, 0x94, 0x07, 0x18, 0x1E, 0x50, 0x7A, 0x00, 0xC5, 0x01, 0x94, 0x17,
-0x50, 0x12, 0x41, 0x78, 0x00, 0xCD, 0x01, 0xC4, 0x04, 0x92, 0x9E, 0x42, 0x7B,
-0x01, 0x2D, 0x21, 0x84, 0x07, 0xD0, 0x10, 0x40, 0x0D, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
-0x15, 0x0C, 0x60, 0x30, 0x00, 0xC1, 0x00, 0x24, 0x03, 0x10, 0x14, 0x41, 0x30,
-0x00, 0xCD, 0x40, 0x24, 0x21, 0x90, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x04, 0x04,
-0x03, 0xD0, 0x8C, 0x40, 0x49, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x17, 0xA8, 0x15, 0x00, 0x7F, 0x0A, 0x7C, 0x81, 0x38, 0x05, 0xC0, 0x16,
-0x00, 0x53, 0x00, 0x5C, 0x01, 0x70, 0x27, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0xCC,
-0x85, 0xB0, 0x05, 0xC0, 0x17, 0x10, 0x7F, 0x04, 0x4C, 0x01, 0xF0, 0x17, 0xC0,
-0x5D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x07,
-0x08, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x00, 0x1C,
-0x00, 0xF0, 0x01, 0xC4, 0x05, 0x80, 0x1F, 0x00, 0x7C, 0x00, 0x74, 0x01, 0xC2,
-0x07, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF2, 0x41, 0x80, 0x4A, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x9F, 0x40, 0x7C,
-0x06, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x08, 0x4C, 0x16, 0x30, 0x39, 0xC0,
-0x24, 0x00, 0x9D, 0x00, 0x74, 0x12, 0xF0, 0x09, 0xC0, 0x23, 0x00, 0x97, 0x08,
-0x5C, 0x06, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x20, 0x66, 0x0E, 0x9D, 0x20, 0x74, 0x0A, 0xD2, 0x09, 0x40,
-0x27, 0x00, 0x9D, 0x03, 0x44, 0x0E, 0x15, 0x08, 0x40, 0x64, 0x20, 0x9D, 0x1B,
-0x70, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x11, 0x04, 0xAE, 0x10, 0x09,
-0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
-0x24, 0x00, 0xDD, 0x00, 0x74, 0x62, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x8D, 0x02,
-0x44, 0x42, 0x11, 0x09, 0x40, 0x27, 0x09, 0x9D, 0x00, 0x70, 0x42, 0xD2, 0x09,
-0x40, 0x27, 0x00, 0x81, 0x00, 0x54, 0x0A, 0x10, 0x09, 0x40, 0x63, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, 0x05, 0x8D, 0x14,
-0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x22, 0x8D, 0x48, 0x04, 0x02, 0x11, 0x09,
-0x40, 0x21, 0x10, 0x8D, 0x08, 0x34, 0x02, 0xD8, 0x08, 0x40, 0x23, 0x40, 0x81,
-0x08, 0x04, 0x92, 0x10, 0x48, 0x48, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x01, 0x1F, 0x04, 0x7C, 0x50, 0x70, 0x60,
-0xC1, 0x83, 0x05, 0x1F, 0x96, 0x4C, 0x50, 0x30, 0xA1, 0xD0, 0x05, 0x05, 0x1F,
-0x16, 0x7C, 0x28, 0xE0, 0xE1, 0xC9, 0x07, 0x15, 0x17, 0x16, 0x5C, 0x04, 0x30,
-0x11, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
-0xA8, 0x27, 0x25, 0xBF, 0x34, 0x7E, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0x9F,
-0x04, 0x7D, 0x02, 0xF0, 0x1B, 0xC0, 0x26, 0x20, 0x9F, 0x04, 0xBC, 0x07, 0xF0,
-0x19, 0xC0, 0x27, 0x05, 0xBF, 0x04, 0x7C, 0x22, 0xF4, 0xCB, 0xC1, 0x67, 0x60,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x03, 0x93,
-0x03, 0xCC, 0x12, 0x70, 0x29, 0xC0, 0xA5, 0x00, 0xBF, 0x00, 0xCC, 0x42, 0x30,
-0x0B, 0xC0, 0x2E, 0x00, 0xB3, 0x00, 0xCC, 0x02, 0xB0, 0x09, 0xC0, 0x24, 0x0B,
-0xB3, 0x40, 0xCC, 0x02, 0x30, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x47, 0x01, 0x1B, 0x43, 0x68, 0x28, 0x10,
-0x01, 0x40, 0x84, 0x02, 0x1D, 0x0E, 0x45, 0x08, 0x10, 0x01, 0x40, 0x85, 0x02,
-0x11, 0x20, 0x44, 0x00, 0x13, 0x21, 0xC0, 0x46, 0x01, 0x1B, 0x00, 0x44, 0x00,
-0x10, 0x01, 0x44, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xA2, 0xA3, 0x10, 0x81, 0x06, 0x04, 0x02, 0x50, 0x68, 0x40, 0x21, 0x81,
-0x8D, 0x90, 0x06, 0x02, 0x10, 0x09, 0x40, 0x21, 0x40, 0x81, 0x16, 0x44, 0x02,
-0x90, 0x28, 0x40, 0xA0, 0x01, 0x81, 0x40, 0x05, 0x02, 0x90, 0x08, 0x40, 0x43,
-0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x20,
-0x99, 0x02, 0x66, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x8D, 0x20, 0x46, 0x02,
-0x04, 0x09, 0x40, 0x25, 0x00, 0xC1, 0x00, 0x44, 0x03, 0x18, 0x09, 0x40, 0x27,
-0x20, 0x89, 0x00, 0x44, 0x02, 0x84, 0x69, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x20, 0x93, 0x21, 0x4C, 0x02,
-0x70, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x80, 0x4C, 0x02, 0x32, 0x09, 0xC8, 0x27,
-0x00, 0x93, 0x00, 0x4C, 0x02, 0xB1, 0x09, 0xC4, 0x24, 0x10, 0x93, 0x13, 0x4C,
-0x02, 0xB0, 0x09, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x00, 0x21, 0x00, 0x8F, 0x04, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x89, 0xC0, 0x23, 0x00, 0x9F, 0x00, 0x7D,
-0x26, 0xF1, 0x09, 0xC4, 0x26, 0xA8, 0x9F, 0x03, 0x3C, 0x82, 0x70, 0x09, 0xC0,
-0x53, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05,
-0x04, 0x1F, 0x40, 0x4C, 0x10, 0xF0, 0x00, 0xC0, 0x07, 0x80, 0x13, 0x10, 0x5C,
-0x84, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x20, 0x4C, 0x08, 0x30, 0x01, 0xC0,
-0x07, 0x00, 0x1F, 0x26, 0x4C, 0x00, 0x30, 0x21, 0xC0, 0x53, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x5C, 0x04, 0x5D, 0x00, 0x84,
-0x01, 0xD0, 0x05, 0x44, 0x17, 0x40, 0x71, 0x83, 0xF4, 0x01, 0xD0, 0x07, 0x40,
-0x14, 0x00, 0x7D, 0x00, 0x84, 0xC5, 0x34, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x01,
-0xC4, 0x1D, 0x50, 0x05, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0xA0, 0xB2, 0x20, 0xCD, 0x20, 0x24, 0x2B, 0xD1, 0x0C, 0x40,
-0x33, 0x00, 0xC9, 0x08, 0x14, 0x07, 0x52, 0x0D, 0x21, 0x72, 0x80, 0xCD, 0x01,
-0x04, 0x07, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xCD, 0x00, 0x07, 0x4F, 0x50, 0x0C,
-0x46, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82,
-0x38, 0x00, 0xCD, 0x04, 0xA4, 0x01, 0xD0, 0x4E, 0x40, 0x7B, 0x02, 0xE9, 0x00,
-0xB4, 0x0A, 0xD0, 0x27, 0x48, 0x38, 0x04, 0xED, 0x02, 0x84, 0x03, 0x10, 0x0E,
-0x40, 0x3B, 0x00, 0xED, 0x82, 0xC4, 0x03, 0x50, 0x0E, 0x40, 0x17, 0x08, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x05,
-0xAD, 0x07, 0xF0, 0x5E, 0xC0, 0x7F, 0x01, 0x69, 0x41, 0x9C, 0x05, 0x70, 0x1E,
-0xE0, 0x7A, 0x00, 0xFE, 0x01, 0xCD, 0x84, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xFF,
-0x01, 0xCC, 0x07, 0x70, 0x9E, 0xC2, 0x57, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF, 0x42, 0x5C, 0x00, 0xF0, 0xAD,
-0xC0, 0x37, 0x00, 0x57, 0x00, 0x7C, 0x02, 0xF0, 0x04, 0xC0, 0x35, 0x00, 0x1F,
-0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC1, 0x37, 0x02, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
-0x4D, 0xC0, 0x43, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xA0, 0x5F, 0x00, 0xF3, 0x53, 0xFC, 0x26, 0x30, 0x3F, 0xC0, 0xFF, 0x00, 0xFF,
-0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xC0, 0x7F, 0x22, 0xBF, 0x01, 0xCC, 0x07, 0xF0,
-0x1F, 0xC1, 0x7C, 0x00, 0xF3, 0x01, 0xEC, 0x07, 0x30, 0x1F, 0xC1, 0x08, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0xBD, 0x00, 0xE1,
-0x00, 0xB4, 0x0A, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x22, 0x80, 0x02, 0xD0,
-0x02, 0x40, 0x3B, 0x00, 0xAD, 0x08, 0x84, 0x23, 0xD2, 0x0E, 0x60, 0x3D, 0x00,
-0xEB, 0x00, 0x04, 0x15, 0x10, 0xDD, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x19, 0x00, 0xE1, 0x00, 0xB4, 0x02, 0x94,
-0x0E, 0x40, 0x3B, 0x00, 0x8D, 0x00, 0x84, 0x00, 0xD0, 0x0E, 0x40, 0x3B, 0x80,
-0xED, 0x00, 0x84, 0x41, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1, 0x08, 0x24, 0x12,
-0x10, 0x4E, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x06, 0x28, 0x07, 0x10, 0xD1, 0x11, 0x36, 0x02, 0x98, 0x0C, 0x40, 0x33, 0x88,
-0x9D, 0x40, 0x04, 0x02, 0xD1, 0x30, 0x40, 0x33, 0x08, 0x1D, 0x00, 0x04, 0x00,
-0xD0, 0x0C, 0x40, 0x31, 0x00, 0x09, 0x05, 0x04, 0x80, 0x18, 0x3C, 0x50, 0x58,
-0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x24, 0x00,
-0xF3, 0x13, 0x7C, 0x02, 0xB0, 0x0F, 0xC0, 0x3F, 0x00, 0x9F, 0x40, 0x4E, 0x02,
-0xF0, 0x29, 0xC1, 0x37, 0x00, 0x5F, 0x00, 0x4C, 0x02, 0xD1, 0x0F, 0x40, 0x3C,
-0x00, 0x13, 0x13, 0x2C, 0x03, 0x30, 0x0F, 0xC1, 0x74, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xA7, 0x00, 0xDF, 0x80, 0x7C, 0x00,
-0x70, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x42, 0x3F, 0x02, 0xF0, 0x01, 0xC0, 0x37,
-0x00, 0x5F, 0x82, 0x7C, 0x00, 0xF0, 0x0D, 0xC8, 0x37, 0x10, 0x1F, 0xA2, 0x7C,
-0x02, 0xF5, 0x4D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x81, 0x09, 0x2F, 0x10, 0xF3, 0x00, 0x44, 0x00, 0xF0, 0x0F, 0xC0, 0x3F,
-0x00, 0x3F, 0x08, 0xCD, 0x00, 0x30, 0x0B, 0xC1, 0x7F, 0x00, 0xFF, 0x00, 0xCC,
-0x00, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0x03, 0x02, 0xCC, 0x25, 0x32, 0x0F, 0xC0,
-0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66,
-0x00, 0xD5, 0x00, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0x1D, 0x02, 0x44,
-0x06, 0x50, 0x31, 0x41, 0x37, 0x00, 0x1D, 0x02, 0x44, 0x0C, 0xD0, 0x0D, 0x40,
-0x37, 0x00, 0x11, 0x02, 0x44, 0x44, 0x50, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x00, 0xD1, 0x00, 0x54,
-0x06, 0xD8, 0x0D, 0x40, 0x37, 0x00, 0x5D, 0x00, 0x44, 0x44, 0x10, 0x13, 0x40,
-0x37, 0x12, 0x1D, 0x00, 0xE4, 0x06, 0xD0, 0x0F, 0x40, 0x37, 0x00, 0x11, 0x50,
-0x44, 0x83, 0x50, 0x0D, 0x48, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC5, 0x00, 0x14, 0x02, 0xD8, 0x0C, 0x40,
-0x33, 0x08, 0x4C, 0x00, 0x05, 0x00, 0x50, 0x00, 0x40, 0x33, 0x00, 0x0D, 0x00,
-0x04, 0x00, 0xD0, 0x0C, 0x48, 0x33, 0x00, 0xC1, 0x00, 0x04, 0x10, 0x51, 0x4C,
-0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90,
-0x06, 0x00, 0xF3, 0x40, 0x5C, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x1F, 0x00,
-0x4C, 0x00, 0x32, 0x01, 0xC0, 0x27, 0x00, 0xCF, 0x00, 0x4C, 0x00, 0xF0, 0x0E,
-0xC4, 0x37, 0x00, 0x13, 0x00, 0x4D, 0x60, 0x30, 0xAF, 0xC0, 0x07, 0xC0, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x20, 0xFF, 0x00,
-0xEC, 0x00, 0xF1, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x40, 0xFC, 0x00, 0xF0, 0x03,
-0xC2, 0x2F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xE0, 0x3F, 0x00, 0x3F,
-0x40, 0x7C, 0x10, 0xE0, 0x6D, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x3F, 0x0B, 0xFF, 0x2C, 0xFC, 0x0A, 0xD0, 0x8F,
-0xC0, 0x4C, 0x00, 0x3F, 0x49, 0xEC, 0x93, 0x30, 0x4F, 0xC0, 0x0F, 0x10, 0x33,
-0x00, 0xFC, 0x24, 0xB0, 0x4F, 0xC0, 0x6C, 0x00, 0xF3, 0x00, 0x8C, 0x03, 0xB1,
-0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x10, 0xBF, 0x01, 0xFD, 0x08, 0x74, 0x8A, 0xD0, 0x6F, 0x44, 0x64, 0x00, 0x19,
-0x00, 0xF4, 0x0F, 0x51, 0xAF, 0x40, 0x27, 0x12, 0x11, 0x41, 0x74, 0x12, 0x10,
-0x9F, 0x40, 0x74, 0x00, 0xF1, 0x42, 0x44, 0x87, 0x10, 0x11, 0x40, 0x0F, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA8, 0xB3, 0x01, 0xCD,
-0x00, 0x36, 0x1A, 0xD0, 0x2C, 0x50, 0x20, 0x00, 0x8D, 0x44, 0x24, 0x0B, 0x11,
-0x0C, 0x40, 0x01, 0x00, 0x05, 0x80, 0x74, 0x90, 0x90, 0x0C, 0x40, 0x35, 0x00,
-0xC1, 0x02, 0x04, 0x07, 0x90, 0x00, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xD0,
-0x0D, 0x40, 0xE4, 0x00, 0x19, 0x01, 0x74, 0x03, 0x50, 0x0D, 0x60, 0x07, 0x00,
-0x31, 0x01, 0x74, 0x0E, 0x10, 0x0D, 0x00, 0x74, 0x00, 0xD1, 0x00, 0x44, 0x87,
-0x00, 0x11, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA8, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x8C, 0xF0, 0x0D, 0xC0, 0xC4, 0x30,
-0x9F, 0x01, 0x6C, 0x03, 0x34, 0x0D, 0xC0, 0x07, 0x00, 0x12, 0x05, 0x3C, 0x0E,
-0xB1, 0x0C, 0xC0, 0x60, 0x00, 0xD3, 0x00, 0x4C, 0x80, 0xB0, 0x19, 0xC0, 0x23,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00,
-0xFF, 0x00, 0xFC, 0x02, 0xF2, 0x0E, 0x40, 0x2F, 0x08, 0x3D, 0x40, 0xFC, 0x03,
-0xB0, 0x0F, 0xC0, 0x6B, 0xD1, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x0F, 0xC0, 0x2F,
-0x00, 0xEF, 0x10, 0xFD, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x08, 0xDF, 0x05, 0x7C, 0x10,
-0x70, 0x0D, 0xC6, 0x25, 0x00, 0x9F, 0xC0, 0x3C, 0x03, 0xF0, 0x0D, 0xC0, 0x37,
-0x09, 0x1F, 0x10, 0x7C, 0x02, 0xF0, 0x4D, 0xC0, 0x06, 0x01, 0xD7, 0x00, 0x0C,
-0x01, 0x30, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0xA0, 0x3C, 0x20, 0xFD, 0x42, 0x74, 0x0E, 0xD0, 0x0F, 0x50, 0x64,
-0x00, 0x1D, 0x80, 0xF0, 0x13, 0xD0, 0xAF, 0x40, 0xB7, 0x01, 0x9D, 0x23, 0x74,
-0x02, 0xD0, 0x3F, 0x40, 0xA7, 0x80, 0xF1, 0x01, 0x54, 0x01, 0x14, 0x09, 0x41,
-0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30,
-0x00, 0xCD, 0x02, 0x34, 0x2C, 0x50, 0x0C, 0x48, 0x00, 0x02, 0x09, 0x40, 0x30,
-0x03, 0xD0, 0x1C, 0x40, 0x13, 0x00, 0x0D, 0x0B, 0x34, 0x00, 0x90, 0x3C, 0x4C,
-0xA2, 0x08, 0xCD, 0x41, 0x04, 0x03, 0x51, 0x08, 0x40, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x78, 0x00, 0xED, 0x01, 0xB4,
-0x05, 0xD1, 0x1C, 0x40, 0xC8, 0x00, 0x2D, 0x01, 0xB6, 0x0F, 0xD0, 0x1E, 0x41,
-0x7B, 0x02, 0x2D, 0x01, 0xB4, 0x04, 0xD0, 0x1E, 0x40, 0x7F, 0x00, 0xE1, 0x41,
-0xD4, 0x2F, 0x50, 0x16, 0x60, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x02, 0x30, 0x08, 0xCF, 0x00, 0x3C, 0x03, 0x70, 0x8C, 0xC0,
-0x01, 0x00, 0x8F, 0x8A, 0x3E, 0x23, 0xF0, 0x0C, 0xC0, 0x13, 0x00, 0x4F, 0x00,
-0x3C, 0x80, 0xF1, 0x0C, 0xC1, 0x32, 0x00, 0xD7, 0x10, 0x0C, 0x23, 0x70, 0x4C,
-0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28,
-0x3D, 0x24, 0xFF, 0x00, 0xF8, 0x03, 0xF0, 0x0F, 0x80, 0x1F, 0x00, 0xFF, 0x28,
-0xFC, 0x63, 0xF0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7C, 0x03, 0xF0, 0x0F,
-0xE9, 0x3B, 0x00, 0xFF, 0x00, 0xFC, 0x23, 0xB4, 0x0D, 0xE0, 0x0B, 0x60, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0xF7, 0x04, 0xD7, 0x02,
-0x7C, 0x05, 0x30, 0xCD, 0xC0, 0x07, 0x00, 0x9B, 0x00, 0x7C, 0x13, 0xF1, 0xCD,
-0xD0, 0x04, 0x40, 0xD3, 0x01, 0x4D, 0x00, 0xF0, 0x6D, 0xC0, 0x27, 0x80, 0xD7,
-0x02, 0x7C, 0x03, 0x34, 0x18, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0x80, 0x30, 0x00, 0xE1, 0x56, 0xB4, 0x03, 0xB0, 0x8E,
-0x44, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x33, 0xD0, 0x0F, 0x41, 0x2C, 0x00, 0xE1,
-0x00, 0x84, 0x01, 0xD0, 0x4E, 0x41, 0x3B, 0x80, 0xED, 0x0E, 0xB4, 0x03, 0xB0,
-0x06, 0x40, 0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x00, 0x78, 0x01, 0xED, 0x01, 0x36, 0x05, 0x10, 0x5E, 0x40, 0x7B, 0x18, 0xAD,
-0x01, 0xA4, 0x17, 0xD0, 0x5E, 0x40, 0x7A, 0x00, 0xC1, 0x01, 0xA4, 0x06, 0xD0,
-0x1E, 0x40, 0x5B, 0x04, 0xED, 0x25, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xC9,
-0x00, 0x34, 0x43, 0x98, 0x0C, 0x40, 0x33, 0x22, 0xCD, 0x0A, 0x34, 0x03, 0xD0,
-0x0C, 0x40, 0xB2, 0x03, 0xC1, 0x0A, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x01,
-0xCD, 0x00, 0x34, 0x03, 0x90, 0x6C, 0x40, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x17, 0x10, 0x5F, 0x00, 0xFC, 0x81, 0x30,
-0x05, 0xE0, 0x5B, 0x00, 0x7B, 0x61, 0x3C, 0x01, 0xF2, 0x05, 0xC0, 0xDE, 0x00,
-0x73, 0x01, 0xEC, 0x05, 0xF0, 0x05, 0xCA, 0x1B, 0x00, 0x5F, 0x00, 0xFC, 0x01,
-0x30, 0x07, 0xD4, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x00, 0x05, 0x08, 0x17, 0x00, 0x78, 0x20, 0xF0, 0x01, 0xC6, 0x47, 0x08,
-0x1F, 0x10, 0x7C, 0x00, 0xF0, 0x20, 0xC8, 0x01, 0x00, 0x1F, 0x04, 0x5C, 0x24,
-0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x04, 0xF1, 0x21, 0xC0, 0x4B,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00,
-0x8F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9B, 0x20, 0x4C, 0x82,
-0xB0, 0x19, 0x80, 0x24, 0x00, 0x91, 0x01, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0xE5,
-0x00, 0x93, 0x00, 0x7C, 0x02, 0x32, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x03, 0x45, 0x8E,
-0xD0, 0x09, 0x40, 0xE7, 0x10, 0x80, 0x00, 0x44, 0x06, 0x10, 0x49, 0x50, 0x24,
-0x02, 0x91, 0x02, 0x74, 0x02, 0x10, 0x09, 0x40, 0xA7, 0x00, 0x91, 0x0B, 0x34,
-0x02, 0x14, 0x29, 0x44, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x18, 0x54, 0x2B, 0xD0, 0x09, 0x40, 0x27,
-0x00, 0x98, 0x20, 0x44, 0x52, 0x92, 0x49, 0x48, 0x25, 0x08, 0x95, 0x38, 0x34,
-0x02, 0x00, 0x09, 0x42, 0x27, 0x40, 0x91, 0x00, 0x74, 0x06, 0x1C, 0x2D, 0x40,
-0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20,
-0x00, 0x89, 0x14, 0x14, 0x52, 0xD1, 0x88, 0x40, 0x23, 0x08, 0x91, 0x48, 0x00,
-0x02, 0x00, 0x08, 0x60, 0x21, 0x00, 0x85, 0x04, 0x36, 0x22, 0x14, 0x08, 0x40,
-0x23, 0x00, 0xC1, 0x14, 0x34, 0x56, 0x10, 0x48, 0x41, 0x43, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x05, 0x1F, 0x04, 0x5C,
-0x10, 0xF0, 0x61, 0xC1, 0x17, 0x00, 0x1A, 0x02, 0x4C, 0x50, 0xB0, 0xE1, 0xC1,
-0x85, 0x47, 0x17, 0x01, 0x7C, 0x08, 0x20, 0x41, 0xC1, 0x15, 0x00, 0x13, 0x0E,
-0x7C, 0x10, 0x30, 0x41, 0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x9F, 0x14, 0xEC, 0x52, 0xF0, 0x49, 0xC2,
-0x2F, 0x10, 0xBF, 0x44, 0x7D, 0x02, 0xF0, 0x19, 0xC2, 0x6E, 0x00, 0xBB, 0x08,
-0xFC, 0x12, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0x9F, 0x81, 0xBC, 0x02, 0xF0, 0x0B,
-0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00,
-0xA7, 0x10, 0xBF, 0x06, 0xCC, 0x46, 0x10, 0x29, 0xC0, 0x2D, 0x00, 0x9F, 0x82,
-0xDC, 0x12, 0xF0, 0x0B, 0xC0, 0x2C, 0x05, 0xB3, 0x00, 0x7C, 0x82, 0x30, 0x4B,
-0xC1, 0x2F, 0x00, 0xB3, 0x00, 0xBC, 0x93, 0x30, 0x0B, 0xC0, 0x77, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x87, 0x00, 0x11, 0x0A,
-0x45, 0x0C, 0xB0, 0xE0, 0x40, 0x07, 0x08, 0x17, 0x00, 0x44, 0x00, 0xD0, 0xA1,
-0x40, 0x84, 0x08, 0x11, 0x00, 0x74, 0x50, 0x10, 0x21, 0x40, 0x17, 0x00, 0x11,
-0x00, 0x74, 0x00, 0x10, 0x01, 0x44, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x20, 0xA1, 0x01, 0x85, 0x04, 0x04, 0x52, 0x58, 0x48,
-0x40, 0x23, 0x00, 0x89, 0x00, 0x14, 0x0B, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x85,
-0x80, 0x34, 0x02, 0x10, 0x08, 0x42, 0x25, 0x00, 0xC1, 0x00, 0x34, 0x8A, 0x10,
-0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x28, 0x25, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD1, 0x09, 0x40, 0x27, 0x0C, 0x95,
-0x04, 0x44, 0x02, 0xD0, 0x09, 0x10, 0x24, 0x14, 0x94, 0x04, 0x74, 0x0A, 0x14,
-0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x12, 0x18, 0x49, 0x40, 0x63, 0x28,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA2, 0x27, 0x10, 0x97,
-0x00, 0x48, 0x1A, 0x70, 0x09, 0xE0, 0xA5, 0x00, 0x9F, 0x93, 0x54, 0x02, 0xF0,
-0x09, 0xC4, 0xE4, 0x40, 0x97, 0x00, 0x7C, 0x02, 0x33, 0x09, 0xC0, 0x67, 0x00,
-0x91, 0x00, 0x7C, 0x06, 0x34, 0x49, 0x42, 0x17, 0x08, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x20, 0x00, 0x9F, 0x90, 0x7C, 0x12, 0xB0,
-0x09, 0xC0, 0x67, 0x09, 0x97, 0x21, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x23, 0x11,
-0x9B, 0x00, 0x7C, 0x0A, 0xF0, 0x09, 0xC0, 0x27, 0x41, 0x9F, 0x20, 0x7C, 0x06,
-0xF0, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x08, 0x04, 0x00, 0x1F, 0x00, 0x6C, 0x08, 0xF2, 0x01, 0xC0, 0x86, 0x14,
-0x1F, 0x02, 0x4C, 0x40, 0xF0, 0x01, 0xC0, 0x86, 0x03, 0x1F, 0x28, 0x7C, 0x00,
-0xF0, 0x11, 0xC4, 0x04, 0x01, 0x13, 0x10, 0x7C, 0x40, 0x30, 0x21, 0xC0, 0x50,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x00,
-0x7D, 0x85, 0xC4, 0x81, 0xD0, 0x05, 0x58, 0xDC, 0x00, 0x5C, 0x00, 0xEC, 0x01,
-0xD0, 0x27, 0x41, 0x1F, 0x10, 0x7D, 0x00, 0x74, 0x01, 0xD0, 0x07, 0x40, 0xD8,
-0x40, 0x73, 0x02, 0xB4, 0x09, 0x15, 0x07, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x00, 0xDD, 0x03, 0x74, 0x33,
-0xD0, 0x0C, 0x40, 0x71, 0x00, 0xDD, 0x00, 0x04, 0x0B, 0xD0, 0x2C, 0x41, 0xB2,
-0x00, 0xCC, 0x04, 0x74, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC1, 0x02, 0x34,
-0x03, 0x90, 0x0C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x00, 0x94, 0x03, 0xD1, 0x9E, 0x40, 0x99,
-0x28, 0xFD, 0x08, 0xA0, 0x03, 0xDA, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB6,
-0x13, 0xD0, 0x1E, 0x50, 0x3C, 0x04, 0xA9, 0x00, 0xF4, 0x03, 0x90, 0x1C, 0x41,
-0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78,
-0x10, 0xFF, 0x01, 0xBC, 0x07, 0xF1, 0x5E, 0xC1, 0x6B, 0x00, 0xFE, 0x11, 0x8C,
-0x06, 0xC0, 0x12, 0xC0, 0x6A, 0x00, 0xEF, 0x21, 0xBC, 0x47, 0xF0, 0x1C, 0xE2,
-0x58, 0x00, 0xA3, 0x01, 0xBC, 0x07, 0xB0, 0x1E, 0xD0, 0x50, 0x60, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0xB5, 0x05, 0x5F, 0x00, 0x6C,
-0x01, 0xF1, 0x2D, 0xC0, 0x06, 0x00, 0xDF, 0x06, 0x7C, 0x00, 0xF0, 0x01, 0xC0,
-0x27, 0x10, 0xDF, 0x00, 0x7C, 0x2B, 0xF0, 0x0D, 0xC0, 0x13, 0x00, 0x17, 0x40,
-0x7C, 0x03, 0x74, 0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x06, 0x28, 0x7D, 0x04, 0x73, 0x01, 0xCD, 0x27, 0x30, 0x1F, 0xC2,
-0x7F, 0x02, 0xF7, 0x01, 0xCC, 0x05, 0xB4, 0x9F, 0xC8, 0x5F, 0x92, 0x6F, 0x09,
-0xDC, 0x07, 0xF0, 0x1F, 0xC0, 0x58, 0x40, 0xB3, 0x09, 0xCC, 0xA5, 0x30, 0x1F,
-0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x08,
-0x39, 0xA0, 0x61, 0x00, 0xAC, 0x03, 0x10, 0x4E, 0x48, 0x2B, 0x82, 0xE1, 0x00,
-0x84, 0x08, 0x10, 0x06, 0x40, 0x1B, 0x00, 0xED, 0x08, 0x84, 0x03, 0xD0, 0x06,
-0x50, 0x18, 0x02, 0xA1, 0x00, 0x85, 0x33, 0xB0, 0x0A, 0xC8, 0x56, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x39, 0x00, 0xC1, 0x08,
-0x94, 0x43, 0x18, 0x0E, 0x60, 0x2F, 0x84, 0xE5, 0x00, 0x84, 0x00, 0x10, 0x06,
-0x08, 0x1B, 0x00, 0x2D, 0x00, 0x94, 0x43, 0xD0, 0x8E, 0x40, 0x0E, 0x00, 0x81,
-0x80, 0xC4, 0x01, 0x18, 0x0E, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0x01, 0x00, 0x50, 0x02, 0x18, 0x0D,
-0x44, 0x63, 0x00, 0xC5, 0x02, 0x04, 0x00, 0x10, 0x00, 0x44, 0x83, 0x00, 0x8D,
-0x02, 0x04, 0x4F, 0xD0, 0x04, 0x40, 0xC2, 0x02, 0x01, 0x00, 0x44, 0x01, 0x90,
-0xA8, 0x40, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0xA8, 0x3D, 0x00, 0x93, 0x00, 0x54, 0x28, 0x30, 0x0F, 0xC0, 0x67, 0x00, 0xF7,
-0x00, 0x4C, 0x02, 0x30, 0x09, 0x40, 0x27, 0x00, 0x9F, 0x06, 0xDC, 0x0F, 0xF0,
-0x0C, 0x40, 0x62, 0x08, 0x91, 0x00, 0x4C, 0x03, 0x11, 0x3D, 0xC8, 0x54, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x00, 0x9F,
-0x02, 0x64, 0x02, 0xF0, 0x0D, 0xC0, 0x87, 0x28, 0xDA, 0x11, 0x7C, 0x0A, 0x70,
-0x09, 0xC0, 0x87, 0x10, 0xDF, 0x10, 0x7C, 0x03, 0xF0, 0x09, 0xC4, 0x05, 0x04,
-0x9F, 0xC0, 0x6C, 0x03, 0xF0, 0x2D, 0xC2, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x3F, 0x00, 0xB3, 0x80, 0x7C, 0x00, 0x31,
-0x0F, 0xE0, 0x0C, 0x04, 0xF7, 0x00, 0x7C, 0x02, 0xF0, 0x03, 0x40, 0x2F, 0x04,
-0x37, 0x00, 0xCC, 0x03, 0xF0, 0x0D, 0xC0, 0x0C, 0x40, 0xB2, 0x00, 0xFC, 0x02,
-0x70, 0x05, 0xC1, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xA1, 0x20, 0x36, 0x00, 0x91, 0x03, 0x74, 0x04, 0x10, 0x0D, 0x48, 0x44, 0x01,
-0xDD, 0x00, 0x74, 0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0x4D, 0x00, 0x6C, 0x03,
-0xD0, 0x09, 0x40, 0x44, 0x00, 0x11, 0x07, 0x74, 0x02, 0x10, 0x44, 0x42, 0x84,
-0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x00,
-0x11, 0x01, 0x74, 0x04, 0x10, 0x0D, 0x40, 0x64, 0x18, 0xDD, 0x00, 0x74, 0x06,
-0xD0, 0x1B, 0x60, 0xCF, 0x00, 0x1D, 0x58, 0x44, 0x03, 0xD0, 0x1D, 0x70, 0xC4,
-0x00, 0x35, 0x81, 0x74, 0x21, 0x50, 0x0D, 0x40, 0x05, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x01, 0x00, 0x24, 0x02,
-0x10, 0x0C, 0x40, 0x20, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x02,
-0x20, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x00, 0x40, 0x04, 0x00, 0x05, 0x00, 0x64,
-0x83, 0x14, 0x08, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x10, 0x3A, 0x08, 0x93, 0x00, 0x7C, 0x00, 0x30, 0x0F, 0x40, 0x04,
-0x10, 0xE7, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x60, 0xCC,
-0x03, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x71, 0x05, 0xC0,
-0x05, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x38, 0x3F,
-0x20, 0xBF, 0x80, 0xFE, 0x02, 0xF0, 0x0F, 0xC0, 0x0B, 0x00, 0xFF, 0x00, 0xFC,
-0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x83, 0xF0, 0x03, 0xC8,
-0x0F, 0x00, 0x3B, 0x00, 0xBC, 0x00, 0xF0, 0x03, 0xC2, 0x17, 0x62, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x7F, 0x02, 0xFB, 0x09, 0xAC,
-0x07, 0xB0, 0x1F, 0xC0, 0x7A, 0x00, 0xFD, 0x21, 0xEC, 0x07, 0xB0, 0x1F, 0xC0,
-0x7A, 0x08, 0xFB, 0x89, 0xCC, 0x07, 0xF2, 0x1F, 0xC0, 0x7D, 0x12, 0xFB, 0x09,
-0xEC, 0x87, 0x33, 0x1E, 0xD2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x00, 0x07, 0x01, 0x11, 0x04, 0x44, 0x04, 0x30, 0x11, 0x40,
-0x44, 0x00, 0x11, 0x01, 0x40, 0x00, 0x10, 0x40, 0x47, 0x44, 0x00, 0x0D, 0x00,
-0x44, 0x04, 0x10, 0x11, 0xC0, 0x05, 0x39, 0x11, 0x24, 0x44, 0x10, 0xB2, 0x11,
-0x44, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
-0x35, 0x18, 0xD9, 0x60, 0x34, 0x03, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0xD9, 0xA0,
-0x64, 0x53, 0x92, 0x0D, 0x40, 0x33, 0x00, 0xD5, 0x00, 0x44, 0x03, 0x90, 0x0C,
-0x40, 0x36, 0x00, 0xDD, 0x04, 0x34, 0x43, 0x19, 0x0C, 0x40, 0x4C, 0x80, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, 0x07, 0x08, 0x11, 0x00,
-0x44, 0x00, 0xD1, 0x01, 0x40, 0x04, 0x08, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01,
-0x40, 0x05, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x05, 0x18, 0x15,
-0x00, 0x14, 0x00, 0x90, 0x01, 0x40, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xA0, 0x32, 0x20, 0xCB, 0x20, 0x6C, 0x03, 0xF0, 0x0D,
-0xC0, 0x36, 0x80, 0xCF, 0x00, 0x2C, 0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x08, 0xDB,
-0x00, 0x4C, 0x03, 0xB0, 0x0C, 0x80, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x32,
-0x0C, 0xC8, 0x20, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x88, 0x0D, 0x00, 0x3F, 0x80, 0xF8, 0x40, 0x30, 0x03, 0xC3, 0x0D, 0x80, 0x3E,
-0x00, 0xF8, 0x00, 0xF0, 0x03, 0xC0, 0x0E, 0x08, 0x3D, 0x00, 0xF8, 0x00, 0xB0,
-0x03, 0x82, 0x0F, 0x00, 0x3B, 0x30, 0xE8, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xD7,
-0x00, 0x6C, 0x03, 0x71, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC0, 0x36, 0x04, 0xDF, 0x00, 0x5C, 0x93, 0x31, 0x0D, 0xC1, 0x34, 0x02,
-0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC1, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x84, 0x06, 0x11, 0x40, 0x34, 0x4C, 0x10,
-0x20, 0x41, 0x83, 0x24, 0x10, 0x00, 0x74, 0x04, 0x10, 0xB0, 0x00, 0x04, 0x00,
-0x02, 0x00, 0x04, 0x0C, 0x10, 0x31, 0x42, 0x03, 0x00, 0x0C, 0x03, 0x70, 0x80,
-0x10, 0x21, 0x40, 0x6C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x13, 0x20, 0x70, 0x10, 0xC5, 0x80, 0x24, 0x07, 0x40, 0x0C, 0x40, 0x33, 0x01,
-0xC5, 0x00, 0x24, 0x47, 0x50, 0xAC, 0x40, 0x31, 0x08, 0xC4, 0x00, 0x14, 0x0B,
-0x14, 0x3C, 0x00, 0x30, 0x04, 0xCD, 0x00, 0x34, 0x03, 0x98, 0x2C, 0x40, 0x0F,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x4C, 0x0A,
-0x21, 0x09, 0xF4, 0x04, 0x10, 0x12, 0x40, 0x4F, 0x00, 0x25, 0x37, 0xF6, 0x04,
-0x12, 0x12, 0x60, 0x49, 0x02, 0x21, 0x01, 0x84, 0x04, 0x00, 0x12, 0x41, 0x4B,
-0x02, 0x2D, 0x11, 0xB4, 0x24, 0x80, 0x12, 0x42, 0x3E, 0x20, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0xC7, 0x00, 0x2C, 0x23,
-0x51, 0x8C, 0xC0, 0x33, 0x00, 0xCF, 0x08, 0x3C, 0x43, 0x70, 0x0C, 0xC4, 0x31,
-0x06, 0xC7, 0x00, 0x1C, 0x43, 0x30, 0x0C, 0xC0, 0x30, 0x00, 0xCF, 0x00, 0x7C,
-0x03, 0xF0, 0x0C, 0xE4, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x38, 0x09, 0x20, 0x3F, 0x00, 0xF0, 0x00, 0xF0, 0x03, 0xC2, 0x0F,
-0x00, 0x3B, 0x2C, 0xBC, 0x20, 0x70, 0x03, 0xC0, 0x0C, 0x02, 0x3F, 0x00, 0xBC,
-0x20, 0xF8, 0x83, 0xC0, 0x0F, 0x00, 0x1F, 0x00, 0xFC, 0x00, 0x71, 0x11, 0xC8,
-0x09, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x77,
-0x00, 0xC3, 0x40, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x73, 0x00, 0xC7, 0x01, 0x6C,
-0x07, 0x36, 0x0D, 0xC4, 0x70, 0x00, 0xDB, 0x40, 0x6C, 0x03, 0xF0, 0x0C, 0xD0,
-0x34, 0x40, 0xD3, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x0D, 0x08, 0x2B, 0x00, 0x84,
-0x00, 0xD2, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x60, 0x84, 0x00, 0x10, 0x02, 0x42,
-0x08, 0x00, 0x31, 0x00, 0x84, 0x00, 0x90, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
-0xB4, 0x00, 0x10, 0x02, 0x40, 0x4F, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0xF9, 0x01, 0xA6, 0x07, 0xD9, 0x1E, 0x40,
-0x7B, 0x00, 0xF5, 0x01, 0xA4, 0x07, 0x10, 0x1E, 0x40, 0x78, 0x10, 0xE9, 0x01,
-0xB4, 0x07, 0xD0, 0x1E, 0x60, 0x78, 0x00, 0xE1, 0x01, 0xD4, 0x07, 0x90, 0x1E,
-0x60, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20,
-0x03, 0x00, 0x19, 0x00, 0x06, 0x00, 0xD0, 0x00, 0x42, 0x03, 0x00, 0x05, 0x00,
-0x04, 0x00, 0x18, 0x00, 0x50, 0x01, 0x00, 0x01, 0x00, 0x14, 0x00, 0x90, 0x00,
-0x60, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x10, 0x00, 0x40, 0x5B, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15, 0x00, 0x5B, 0x80,
-0x2C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x57, 0x40, 0x6C, 0x01, 0x30, 0x05,
-0xCA, 0x14, 0x10, 0x5B, 0x00, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x10, 0x00, 0x53,
-0x00, 0x7C, 0x01, 0xB0, 0x05, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x00, 0x8D, 0x08, 0x3F, 0x00, 0xFC, 0x08, 0xE0, 0x03,
-0xC0, 0x0F, 0x20, 0x39, 0x20, 0xFC, 0x08, 0xF0, 0x03, 0x00, 0x0E, 0x00, 0x3F,
-0x40, 0xE4, 0x80, 0xC2, 0x03, 0xC0, 0x8F, 0x00, 0x3B, 0x20, 0xFC, 0x00, 0xF0,
-0x03, 0xC0, 0x4B, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x22, 0x30, 0x49, 0xC0, 0x25, 0x00, 0x9F,
-0xC0, 0x7C, 0x02, 0xF1, 0x09, 0x80, 0xE5, 0x08, 0x9F, 0x00, 0x5C, 0x02, 0x70,
-0x09, 0xC0, 0x24, 0x00, 0x97, 0x01, 0x7C, 0x16, 0x30, 0x09, 0x80, 0x41, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xE4, 0x23, 0x9D,
-0x00, 0x45, 0x0A, 0x10, 0x18, 0x80, 0x26, 0x00, 0x9C, 0x11, 0x70, 0x06, 0xD0,
-0x28, 0x40, 0x64, 0x04, 0x8D, 0x80, 0x04, 0x02, 0x00, 0x09, 0x40, 0x64, 0x03,
-0x91, 0x02, 0x74, 0x0E, 0x10, 0x18, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x80, 0xBD, 0x80, 0xC4, 0x02, 0x50,
-0x0B, 0x40, 0x2C, 0x01, 0xBC, 0x08, 0xF0, 0x22, 0xD2, 0x0B, 0x41, 0x2D, 0x00,
-0xBD, 0x00, 0xD4, 0x02, 0x42, 0x0B, 0x40, 0x2C, 0x00, 0xB5, 0x0A, 0xF4, 0xC2,
-0x00, 0x4B, 0x40, 0x71, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x20, 0x29, 0x00, 0xAD, 0x00, 0xD4, 0x03, 0x54, 0x1B, 0x40, 0x6A, 0x20,
-0xAC, 0xA0, 0xB0, 0xA3, 0xD1, 0x8B, 0x40, 0x29, 0x00, 0xBD, 0x68, 0xC4, 0x02,
-0x51, 0x0B, 0x40, 0x28, 0x02, 0xA1, 0x08, 0xB0, 0x22, 0x11, 0x0B, 0x44, 0x51,
-0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x07, 0x08,
-0x1F, 0x80, 0x4C, 0x00, 0x74, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x38, 0x08,
-0xF0, 0x20, 0xC0, 0x05, 0x00, 0x1F, 0x22, 0x5C, 0x00, 0x72, 0x01, 0xD0, 0x80,
-0x00, 0x17, 0x02, 0x78, 0x08, 0x34, 0x03, 0xC0, 0x75, 0xC0, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x9F, 0x14, 0x6C, 0x02,
-0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x12, 0xF0, 0x49, 0x80, 0x26,
-0x00, 0x9F, 0x04, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x01, 0x9F, 0x04, 0x3C,
-0x12, 0xF4, 0x09, 0xC0, 0x66, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1D, 0xA8, 0xAF, 0x00, 0x9F, 0x02, 0xF4, 0x02, 0x30, 0x0B, 0xC0, 0x2B,
-0x00, 0xBF, 0x80, 0xCC, 0x82, 0xF0, 0x0B, 0xD0, 0x2C, 0x00, 0x8B, 0x82, 0x8C,
-0x02, 0xB0, 0x0B, 0xC0, 0x2E, 0x00, 0xAF, 0x00, 0xCD, 0x0A, 0xB0, 0x0A, 0xC0,
-0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x47,
-0x01, 0x0D, 0x05, 0x74, 0x00, 0xB0, 0x01, 0x40, 0x07, 0x08, 0x1D, 0x00, 0x6C,
-0x10, 0xD0, 0x41, 0x40, 0x04, 0x00, 0x11, 0x00, 0x54, 0x00, 0x10, 0x01, 0x40,
-0x00, 0x01, 0x1D, 0x00, 0x45, 0x10, 0x10, 0x01, 0x42, 0x70, 0x60, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x21, 0x00, 0x8D, 0x00, 0x34,
-0x02, 0x10, 0x0C, 0x40, 0x23, 0x08, 0x9D, 0xA0, 0x04, 0x42, 0xD0, 0x08, 0x41,
-0x24, 0x00, 0x89, 0x00, 0x64, 0x02, 0x90, 0x09, 0x40, 0x22, 0x04, 0x8D, 0x00,
-0x44, 0x02, 0x90, 0x08, 0x50, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x20, 0x25, 0x10, 0x9D, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40,
-0x27, 0x00, 0x9D, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00,
-0x74, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x8C, 0x00, 0x44, 0x02, 0x10, 0x09,
-0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28,
-0x25, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x20,
-0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x20, 0x00, 0x9B, 0x00, 0x2C, 0x02, 0xB0, 0x08,
-0xC0, 0x26, 0x00, 0x9E, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC0, 0x14, 0x28, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x25, 0x00, 0x9F, 0x00,
-0x7C, 0x02, 0xF8, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x82, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x9F, 0x00, 0x58, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
-0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x01, 0x1F, 0x00, 0x4D, 0x10, 0xF0, 0x01,
-0xC0, 0x07, 0x04, 0x17, 0x40, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x17,
-0x00, 0x5C, 0x40, 0x30, 0x81, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x5C, 0x90, 0x34,
-0x01, 0xC0, 0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA0, 0xDC, 0x01, 0x5D, 0x00, 0xC4, 0x05, 0xD0, 0x87, 0x48, 0x5F, 0x04, 0x71,
-0x07, 0xF4, 0x01, 0x10, 0x07, 0x40, 0x1F, 0x02, 0x51, 0x00, 0xC0, 0x11, 0x10,
-0xB7, 0x40, 0x5F, 0x00, 0x70, 0x01, 0x84, 0x01, 0x10, 0x06, 0x40, 0x50, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xB2, 0x08, 0xCD,
-0x00, 0x14, 0x0A, 0xD8, 0x2C, 0x40, 0xB3, 0x00, 0xD4, 0x11, 0x34, 0x07, 0x10,
-0x1D, 0x40, 0xA3, 0x00, 0xD5, 0x00, 0x14, 0x0E, 0x14, 0x1C, 0x40, 0x63, 0x00,
-0xC4, 0x05, 0x14, 0x2B, 0x14, 0x24, 0x40, 0x51, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x39, 0x00, 0xED, 0x01, 0x84, 0x08, 0xD1,
-0x0E, 0x40, 0x7F, 0x00, 0x61, 0x80, 0xB0, 0x0F, 0x10, 0x0E, 0x4D, 0x2F, 0x00,
-0xF1, 0x00, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x6B, 0x04, 0xF5, 0x30, 0x84, 0x03,
-0x14, 0x07, 0x40, 0x04, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x18, 0x59, 0x00, 0xEF, 0x09, 0x9C, 0x05, 0xF1, 0x1A, 0xC0, 0x4B, 0x00,
-0xE7, 0x41, 0xFC, 0x07, 0x34, 0x16, 0xC0, 0x7B, 0x00, 0xE7, 0x77, 0x9C, 0x06,
-0x30, 0x1E, 0xC2, 0x7B, 0x00, 0x67, 0xE1, 0xDC, 0x06, 0x30, 0x16, 0x80, 0x45,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00,
-0xDF, 0x00, 0x7C, 0x00, 0xF2, 0x01, 0xC4, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x00,
-0xE0, 0x05, 0xC0, 0x33, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC4, 0x17,
-0x00, 0x5B, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xC8, 0x43, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7F, 0x22, 0xFF, 0x11, 0xF8, 0x04,
-0xF0, 0x9F, 0xC0, 0x7F, 0x00, 0xAF, 0x01, 0xDC, 0x86, 0x30, 0x9F, 0xC8, 0x6B,
-0x00, 0xFB, 0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xE4, 0x6F, 0x00, 0xB3, 0x09, 0xC4,
-0x07, 0x30, 0x16, 0xC8, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0x00, 0x39, 0x00, 0xED, 0x04, 0xBC, 0x40, 0xD8, 0x8A, 0x40, 0x2B,
-0x01, 0x2D, 0x00, 0x84, 0x22, 0x10, 0x8A, 0x42, 0x2B, 0x00, 0xE1, 0x08, 0x84,
-0x42, 0xD0, 0x02, 0x40, 0x2B, 0x01, 0xBB, 0x0C, 0xC4, 0x13, 0xB0, 0x0E, 0x40,
-0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x19,
-0x30, 0xED, 0x40, 0xB4, 0x01, 0xD0, 0x0A, 0x48, 0x0B, 0x80, 0xED, 0x00, 0xB4,
-0x03, 0x94, 0x86, 0x44, 0x3F, 0x04, 0xE9, 0x00, 0x84, 0x03, 0xD0, 0x8A, 0x41,
-0x2B, 0x24, 0x21, 0x40, 0xD5, 0x00, 0x11, 0x07, 0x40, 0x22, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x83, 0x00, 0xCD, 0x09, 0x36,
-0x85, 0xD0, 0xA0, 0x40, 0xE3, 0x84, 0xCD, 0x0C, 0x74, 0x08, 0x90, 0x01, 0x40,
-0xD3, 0x00, 0xD1, 0x52, 0x04, 0x06, 0xD0, 0x00, 0x48, 0xD3, 0x80, 0x09, 0x03,
-0x14, 0x28, 0x90, 0xAC, 0x40, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1D, 0xA0, 0xE5, 0x2C, 0xFF, 0x0B, 0x7C, 0x2C, 0xF0, 0x30, 0xC0,
-0x67, 0x01, 0xDF, 0x02, 0x7C, 0x19, 0xB0, 0xD9, 0xC0, 0xA7, 0x02, 0xFB, 0x87,
-0x4F, 0x02, 0xE0, 0x2C, 0x00, 0x07, 0x02, 0xD3, 0x11, 0x5D, 0x0D, 0x31, 0x95,
-0xC0, 0x56, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08,
-0xA7, 0x00, 0xDE, 0x60, 0x5C, 0x00, 0xF0, 0x21, 0xC0, 0x27, 0x00, 0x1F, 0x02,
-0x40, 0x01, 0x70, 0x25, 0xC0, 0x27, 0x20, 0xDF, 0x80, 0x7C, 0xCA, 0xF0, 0x09,
-0xC9, 0x07, 0x00, 0xDF, 0x52, 0x68, 0x41, 0xF0, 0x05, 0xC0, 0xA7, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x09, 0x2F, 0x14, 0xFF, 0x00,
-0xFC, 0x01, 0xF8, 0x03, 0xC1, 0x0E, 0x00, 0xFF, 0x01, 0xCC, 0x43, 0x30, 0x8B,
-0xC0, 0x6C, 0x20, 0xFF, 0x00, 0xCD, 0x06, 0xF0, 0x8F, 0xC8, 0x3C, 0x00, 0x77,
-0x05, 0xFC, 0x07, 0x34, 0x03, 0xC0, 0x15, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x89, 0x20, 0x66, 0x01, 0xDD, 0x00, 0x74, 0x08, 0xD8, 0x31,
-0x40, 0x64, 0x00, 0x8D, 0x05, 0x44, 0x08, 0x50, 0x05, 0x40, 0x34, 0x00, 0xDE,
-0x00, 0x44, 0x62, 0xD0, 0x19, 0x44, 0x90, 0x00, 0x91, 0x04, 0x74, 0x4B, 0x30,
-0x00, 0x40, 0x14, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0xA0, 0x46, 0x00, 0xDD, 0x80, 0x74, 0x00, 0xD0, 0x19, 0x00, 0x46, 0x00, 0x1D,
-0x08, 0x44, 0x08, 0x10, 0x09, 0x41, 0x25, 0x02, 0xD9, 0x00, 0x64, 0x03, 0xD0,
-0x09, 0x40, 0x84, 0x30, 0x95, 0x00, 0x30, 0x20, 0x02, 0x45, 0x40, 0x05, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD,
-0x00, 0x34, 0x00, 0xD0, 0x08, 0x44, 0x40, 0x00, 0x0D, 0x00, 0x05, 0x00, 0x50,
-0x00, 0x50, 0x20, 0x10, 0xC5, 0x00, 0x04, 0x01, 0xD0, 0x01, 0x10, 0x04, 0x88,
-0x41, 0x00, 0x34, 0x00, 0x11, 0x0C, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x19, 0x06, 0x00, 0xFF, 0x00, 0x7C, 0x01, 0xD0,
-0x09, 0xC0, 0x06, 0x00, 0x5F, 0x00, 0x0C, 0x03, 0x30, 0x09, 0xC0, 0x24, 0x10,
-0xED, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x20, 0x20, 0x17, 0x00, 0x7C, 0x00,
-0x34, 0x01, 0xC0, 0x05, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0xB8, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
-0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC4, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x01,
-0xF1, 0x03, 0xE0, 0x1F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0x70, 0x0B, 0xD0, 0x17,
-0x24, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x2F, 0x04,
-0xFF, 0x01, 0xEC, 0x52, 0xD0, 0x1F, 0xC0, 0x3E, 0x21, 0x2F, 0x01, 0xFC, 0x13,
-0x30, 0x0D, 0xC0, 0x57, 0x00, 0x8B, 0x21, 0xCE, 0x23, 0xB0, 0x6F, 0xC0, 0xBC,
-0x09, 0x3F, 0x04, 0xCC, 0x93, 0x33, 0x03, 0xC2, 0x0F, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x87, 0x10, 0xDD, 0x00, 0x74, 0x0E,
-0xD8, 0x1D, 0x40, 0x7F, 0x0A, 0x9D, 0x01, 0xF4, 0x2F, 0x10, 0x2F, 0x44, 0x57,
-0x10, 0x91, 0x00, 0x44, 0x33, 0x10, 0x2F, 0x40, 0xBC, 0x01, 0x5D, 0x09, 0xC4,
-0xDB, 0x10, 0x01, 0x40, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0xA0, 0x03, 0x05, 0xCD, 0x54, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x33,
-0x00, 0xCD, 0x01, 0x34, 0x03, 0x18, 0x2C, 0x40, 0x14, 0x00, 0xDD, 0x00, 0x15,
-0x13, 0xD0, 0x6C, 0x40, 0xB1, 0x08, 0x8D, 0x00, 0x54, 0x23, 0x10, 0x00, 0x40,
-0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x45,
-0x00, 0xDD, 0x04, 0x74, 0x84, 0xD1, 0x0D, 0x40, 0x37, 0x00, 0xDC, 0x00, 0x74,
-0x03, 0x10, 0x0D, 0x40, 0x17, 0x00, 0x95, 0x00, 0x64, 0x03, 0x50, 0x0D, 0x4A,
-0x35, 0x00, 0xDD, 0x00, 0x54, 0x03, 0x10, 0x11, 0x40, 0x0F, 0x20, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x00, 0xDF, 0x20, 0x6C,
-0x14, 0xD0, 0x0D, 0xC0, 0x36, 0x00, 0x5F, 0xE8, 0x7C, 0x03, 0x31, 0x0D, 0xC0,
-0x42, 0x00, 0x8B, 0x40, 0x4C, 0x03, 0xF0, 0x0D, 0x40, 0x35, 0x10, 0x4E, 0x52,
-0x1C, 0x03, 0x14, 0x19, 0xC0, 0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0F, 0x80, 0x05, 0x00, 0xFF, 0x41, 0xFC, 0x02, 0xF2, 0x2F, 0xC1,
-0x3F, 0x0C, 0x7F, 0x01, 0xB0, 0x03, 0xF0, 0x0F, 0xC0, 0x4F, 0x02, 0xB8, 0x40,
-0xD8, 0x03, 0xB0, 0x0F, 0xC0, 0x3E, 0x00, 0xFF, 0x03, 0xEC, 0x23, 0xF4, 0x03,
-0x40, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08,
-0x65, 0x01, 0xD3, 0x00, 0x7C, 0x0C, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0x5B, 0x00,
-0x4C, 0x43, 0xF0, 0x8D, 0xC0, 0x97, 0x00, 0xDF, 0x08, 0x5C, 0x03, 0xF1, 0x0D,
-0xC0, 0x37, 0x00, 0x5F, 0x00, 0x5C, 0x43, 0xF0, 0x89, 0xC0, 0x2B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0xD1, 0x0B,
-0x74, 0x00, 0xD0, 0x3D, 0x40, 0xBF, 0x24, 0x51, 0x0A, 0xC4, 0x1B, 0xD0, 0xBF,
-0x40, 0x17, 0x06, 0x9C, 0x00, 0xC4, 0x03, 0xD0, 0x0F, 0x04, 0x3C, 0x10, 0xDC,
-0x01, 0x40, 0x0B, 0x10, 0xB9, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0x20, 0xA0, 0x00, 0xC1, 0x01, 0x24, 0x02, 0xD0, 0x1C,
-0x40, 0x33, 0x00, 0x09, 0x0B, 0x34, 0x03, 0xD0, 0x1C, 0x60, 0x83, 0x08, 0x88,
-0x01, 0x54, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0x4D, 0x13, 0x10, 0x2F, 0x50,
-0x08, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F,
-0x00, 0x78, 0x40, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x49, 0x7B, 0x00, 0xB5,
-0x09, 0xA4, 0x87, 0xD0, 0x5E, 0x40, 0x4B, 0x09, 0xAD, 0x25, 0x80, 0x07, 0xD0,
-0x1C, 0x40, 0x78, 0x00, 0xCD, 0x21, 0xC0, 0x27, 0x00, 0x12, 0x40, 0x3F, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x10, 0x02, 0xC3,
-0x18, 0x3C, 0x23, 0xF8, 0x0C, 0xC0, 0x33, 0x01, 0x8B, 0x08, 0x2C, 0x03, 0xF0,
-0x5C, 0x80, 0x43, 0x01, 0xCF, 0x05, 0x1C, 0x03, 0xF0, 0x4C, 0xC0, 0x31, 0x00,
-0x4F, 0x10, 0x5C, 0x37, 0x70, 0x0C, 0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x00, 0xFF, 0x08, 0xFC, 0x23, 0xF0,
-0x0F, 0xC8, 0x3B, 0x00, 0xFB, 0x68, 0xDC, 0x23, 0xF0, 0x2F, 0xC1, 0x0F, 0x20,
-0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xFF, 0x08, 0x7C, 0xAB,
-0x52, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x78, 0x01, 0xF0, 0x0D, 0xC0, 0x36, 0x04,
-0x1F, 0x00, 0x4C, 0x63, 0xF0, 0x4D, 0xC8, 0x06, 0x08, 0x93, 0x00, 0x7C, 0x03,
-0xF1, 0xFD, 0xC0, 0xB6, 0x01, 0x5F, 0x01, 0x6C, 0x0A, 0x30, 0x0D, 0xC0, 0x40,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x90, 0x39, 0x00,
-0xED, 0x80, 0xB4, 0x03, 0xC1, 0x0E, 0xC0, 0x39, 0x01, 0xED, 0x00, 0x84, 0x03,
-0xD1, 0x4E, 0x42, 0x0A, 0x00, 0xA5, 0x00, 0xB4, 0x13, 0xD1, 0x0E, 0x41, 0x38,
-0x0D, 0xED, 0x00, 0x84, 0x02, 0x12, 0x06, 0xC0, 0x4E, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x28, 0xED, 0x21, 0xB0, 0x07,
-0xD9, 0x1E, 0x40, 0x7B, 0x03, 0xAD, 0x01, 0xA4, 0x17, 0xD0, 0x5E, 0x40, 0x4A,
-0x08, 0xE1, 0x21, 0xB4, 0x27, 0xD0, 0x1C, 0x40, 0x7A, 0x02, 0x7D, 0x01, 0xA4,
-0x06, 0x10, 0x1C, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x16, 0x00, 0x37, 0x04, 0x9D, 0x41, 0x34, 0x47, 0xD0, 0x08, 0x40, 0x31,
-0x00, 0xCD, 0x08, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x62, 0x80, 0x85, 0x00, 0x34,
-0x03, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x03, 0x04, 0x02, 0x10, 0x2D, 0x40,
-0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x9F,
-0x00, 0x5D, 0x01, 0xFE, 0x1D, 0xF0, 0x15, 0xE1, 0x16, 0x00, 0x6F, 0x03, 0x6F,
-0x01, 0xF0, 0x05, 0xC0, 0x5A, 0x04, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0,
-0x16, 0x00, 0x7F, 0x10, 0x6C, 0x45, 0x30, 0x47, 0xC0, 0x5C, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x05, 0x00, 0x1F, 0x08, 0x7E,
-0x00, 0xF0, 0x01, 0xA0, 0x07, 0x00, 0x1F, 0x04, 0x5E, 0x00, 0xF0, 0x20, 0x08,
-0x07, 0x01, 0x1F, 0x80, 0x7C, 0x00, 0xD0, 0x01, 0xC0, 0x03, 0x20, 0x1D, 0x24,
-0x7C, 0x00, 0xF0, 0x21, 0xD8, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x93, 0xC1, 0x2C, 0x82, 0xE1, 0x19, 0xC0,
-0x25, 0x09, 0x9F, 0x00, 0x4C, 0x92, 0xD0, 0x19, 0xC0, 0x64, 0x10, 0x93, 0x08,
-0x3C, 0x02, 0x40, 0x09, 0xC4, 0x27, 0x00, 0x93, 0x80, 0x7C, 0x02, 0x75, 0x09,
-0xC1, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
-0x66, 0x00, 0x91, 0x81, 0x4C, 0x02, 0x10, 0x98, 0x00, 0xA5, 0x00, 0x9D, 0x18,
-0x45, 0x0A, 0xD0, 0xA9, 0x50, 0x24, 0x03, 0x95, 0x00, 0x74, 0x02, 0x13, 0x09,
-0x44, 0x27, 0x00, 0x91, 0x1B, 0x34, 0x06, 0x12, 0x69, 0x50, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x34, 0x82, 0x99, 0x08,
-0x64, 0x06, 0x10, 0x09, 0x00, 0xA4, 0x00, 0x99, 0x00, 0x54, 0x42, 0xD2, 0x09,
-0x45, 0x34, 0x00, 0x91, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x27, 0x40, 0x91,
-0x00, 0x74, 0x12, 0x51, 0x0D, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x22, 0x30, 0x15, 0xC1, 0x00, 0x04, 0x52, 0x12, 0x19,
-0x42, 0x21, 0x80, 0x8D, 0x40, 0x06, 0x82, 0xD0, 0x08, 0x40, 0x24, 0x00, 0x85,
-0x00, 0x34, 0x22, 0x50, 0x88, 0x40, 0x23, 0x02, 0x81, 0x00, 0x70, 0xD2, 0x10,
-0x48, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0x38, 0x07, 0x01, 0x1B, 0x00, 0x6C, 0x10, 0x70, 0x01, 0xC0, 0x05, 0x05, 0x1B,
-0x40, 0x48, 0xD0, 0xF0, 0xE1, 0xC1, 0x04, 0x00, 0x53, 0x0A, 0x7C, 0x58, 0x71,
-0x61, 0xC1, 0x87, 0x05, 0x13, 0x14, 0x38, 0x11, 0x70, 0x41, 0xC0, 0x74, 0xE0,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2D, 0x45, 0xBF,
-0x14, 0xDC, 0x02, 0xB4, 0x0B, 0xC0, 0x27, 0x00, 0xAC, 0x00, 0x7C, 0x02, 0xF0,
-0x19, 0xC0, 0x2B, 0x08, 0xBF, 0x01, 0x7C, 0x12, 0xB1, 0x49, 0xC0, 0x27, 0x11,
-0xAF, 0x00, 0xFC, 0x52, 0xF0, 0x4B, 0xC1, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0xBF, 0x00, 0xB3, 0x00, 0xFC, 0x52, 0xF0,
-0x0B, 0xC0, 0x2D, 0x05, 0xB3, 0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2C, 0x00,
-0xBF, 0x80, 0x6C, 0x02, 0x10, 0x09, 0xC0, 0x24, 0x00, 0xBF, 0x00, 0xCC, 0x02,
-0x32, 0x0B, 0xD0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x00, 0x87, 0x00, 0x1B, 0xA4, 0x74, 0x08, 0xD0, 0x01, 0x40, 0x84, 0x48,
-0x11, 0x20, 0x44, 0x00, 0xD2, 0xA1, 0x40, 0x05, 0x00, 0x1D, 0x00, 0x40, 0x90,
-0x10, 0x41, 0x40, 0x04, 0x01, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x60,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0xA1, 0x21,
-0x81, 0x10, 0x30, 0x02, 0xD0, 0x08, 0x40, 0x21, 0x00, 0xD5, 0x00, 0x04, 0x0B,
-0xD0, 0x0D, 0x40, 0x20, 0x00, 0x8D, 0x80, 0x30, 0x4A, 0x11, 0x28, 0x41, 0xA2,
-0x04, 0x8D, 0x00, 0x05, 0x82, 0x14, 0x08, 0x40, 0x49, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x99, 0x04, 0x74, 0x02,
-0xD0, 0x49, 0x40, 0x26, 0x08, 0x95, 0x00, 0x44, 0x02, 0xC0, 0x09, 0x40, 0x25,
-0x0D, 0x9D, 0x80, 0x14, 0x02, 0x10, 0x08, 0x46, 0x26, 0x00, 0x9D, 0x10, 0x44,
-0x02, 0x10, 0x0D, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0x20, 0xE5, 0x06, 0x93, 0x40, 0x78, 0x1A, 0xD1, 0x09, 0xC0, 0x25,
-0x00, 0x97, 0x0F, 0x45, 0x02, 0xF0, 0x09, 0xC0, 0xA4, 0x00, 0x8F, 0x81, 0x7E,
-0x02, 0x34, 0x09, 0xD0, 0x26, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x49, 0xC0,
-0x15, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x24,
-0x00, 0x9F, 0xC0, 0x7C, 0x12, 0xF0, 0x09, 0xC8, 0x25, 0x00, 0x9B, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x05, 0x6C, 0x02, 0xF0, 0x09, 0xC0,
-0x25, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x49, 0xC1, 0x5B, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x10, 0x78,
-0x08, 0xF0, 0x01, 0xC1, 0x01, 0x04, 0x1F, 0x04, 0x7C, 0x90, 0xB0, 0x01, 0xC0,
-0x84, 0x00, 0x1F, 0x10, 0x4C, 0x00, 0xF1, 0x01, 0xC0, 0x07, 0x10, 0x07, 0x10,
-0x3C, 0x04, 0x30, 0x21, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0xDC, 0x01, 0x7D, 0x07, 0x74, 0x01, 0x10, 0x26, 0x40,
-0x1F, 0x19, 0x6D, 0x00, 0xF4, 0x09, 0x10, 0x07, 0x40, 0xDC, 0x02, 0x7D, 0x03,
-0x44, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x71, 0x45, 0xF4, 0x41, 0x11, 0x27,
-0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
-0xF6, 0x01, 0xCD, 0x03, 0x34, 0x22, 0x58, 0x2C, 0x48, 0x73, 0x00, 0xCC, 0x00,
-0x34, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xCD, 0x0A, 0x32, 0x03, 0xD0, 0x0C,
-0x40, 0x33, 0x80, 0xC5, 0x00, 0x34, 0x04, 0x90, 0xAD, 0x40, 0x40, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0x6D, 0x00,
-0xB4, 0x07, 0x5A, 0x2A, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB0, 0x07, 0x52, 0x0A,
-0x40, 0x98, 0x00, 0xED, 0x00, 0x84, 0x13, 0xD0, 0x4E, 0x40, 0x7B, 0x81, 0xE1,
-0x00, 0xB4, 0x02, 0x90, 0x04, 0x44, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x08, 0xEF, 0x01, 0xBC, 0x87, 0x70, 0x1E,
-0xC0, 0x5B, 0x00, 0xEE, 0x01, 0xBC, 0x06, 0xF0, 0x1F, 0xC0, 0x78, 0x00, 0xBF,
-0x01, 0x9C, 0x07, 0xF0, 0xBE, 0xC4, 0x7F, 0x21, 0xE7, 0x01, 0xFC, 0x04, 0xB0,
-0x1E, 0xD0, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xB2, 0x35, 0x00, 0x5F, 0x60, 0x3C, 0x03, 0x38, 0x01, 0xC8, 0x07, 0x00, 0xDF,
-0x00, 0x3C, 0x00, 0xB0, 0x05, 0xC0, 0x37, 0x00, 0x9F, 0x20, 0x7C, 0x2B, 0xF0,
-0x6D, 0xC8, 0xB7, 0x20, 0x9D, 0x00, 0x7C, 0x82, 0x71, 0x05, 0xC0, 0x43, 0x60,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D, 0x02, 0xFF,
-0x81, 0xCC, 0x17, 0x71, 0x17, 0xC0, 0x6F, 0x02, 0xFF, 0x81, 0xFC, 0x85, 0xF0,
-0x9F, 0x40, 0x78, 0x02, 0xB3, 0x29, 0xFE, 0x2F, 0xB0, 0x1F, 0xE0, 0xFF, 0x04,
-0x73, 0x09, 0xFC, 0x27, 0xF1, 0x5F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x26, 0x6D, 0x08, 0xAC, 0x83, 0xD0,
-0x22, 0x40, 0x8B, 0x00, 0x2D, 0x00, 0xB4, 0x08, 0xD0, 0x1A, 0x40, 0x98, 0x00,
-0xA1, 0x01, 0xB4, 0x03, 0xD0, 0x0E, 0xC0, 0x39, 0x01, 0xEB, 0x00, 0x34, 0x07,
-0xD0, 0x0A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x48, 0x08, 0x39, 0x18, 0xFD, 0x00, 0xA4, 0x13, 0xD0, 0x02, 0x40, 0x0B, 0x00,
-0xED, 0x10, 0xB4, 0x20, 0xD0, 0x0E, 0x40, 0x2B, 0x40, 0x21, 0x00, 0xB4, 0x83,
-0x91, 0x0E, 0x40, 0x39, 0x10, 0x61, 0x10, 0xB4, 0x02, 0xD0, 0x4E, 0x40, 0x23,
-0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x21, 0x00,
-0x1D, 0x01, 0x26, 0x07, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x03, 0x34, 0x80,
-0xD0, 0x00, 0x40, 0xA3, 0x00, 0x01, 0x01, 0x34, 0x03, 0xD0, 0x0C, 0x48, 0x31,
-0x80, 0x85, 0x00, 0x34, 0x81, 0xD0, 0x29, 0x40, 0x0B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x04, 0x00, 0x9F, 0x01, 0x64, 0x0B,
-0x71, 0x09, 0xC0, 0x27, 0x90, 0x1F, 0x03, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x27,
-0x20, 0xD3, 0x11, 0xFC, 0x03, 0xB0, 0x0F, 0xC0, 0x3D, 0x00, 0x81, 0x01, 0x7C,
-0x01, 0xD0, 0x29, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x0D, 0x00, 0x87, 0x01, 0x9F, 0x08, 0x7C, 0x23, 0xF0, 0x19, 0xC0, 0x27,
-0x00, 0x1F, 0x32, 0x3E, 0x0A, 0xF0, 0x01, 0x40, 0x14, 0xA1, 0x9F, 0x00, 0x70,
-0x03, 0xD0, 0x0D, 0xC8, 0x35, 0x40, 0x9B, 0x10, 0x74, 0x01, 0xE0, 0x21, 0xC0,
-0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x08, 0x0B,
-0x00, 0xBB, 0x00, 0x8C, 0x43, 0xB0, 0x0B, 0xC4, 0x2B, 0x00, 0xF3, 0x00, 0xFC,
-0x02, 0x32, 0x01, 0xC4, 0x2F, 0x01, 0xBF, 0x40, 0xEC, 0x03, 0xF0, 0x0F, 0xC4,
-0x3B, 0x00, 0x37, 0x05, 0x94, 0x81, 0x33, 0x03, 0x81, 0x04, 0x28, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6, 0x21, 0x91, 0x07, 0x44,
-0x83, 0xB0, 0x31, 0x40, 0xE7, 0x00, 0xD1, 0x06, 0x74, 0x04, 0x10, 0x31, 0x48,
-0x77, 0x10, 0x9C, 0x01, 0x74, 0x03, 0x71, 0x0D, 0x40, 0x37, 0x00, 0x11, 0x32,
-0x44, 0x0B, 0x10, 0x31, 0x40, 0x85, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0xA0, 0x64, 0x00, 0x19, 0x01, 0x54, 0x07, 0x90, 0x19, 0x00,
-0x66, 0x00, 0x11, 0x01, 0x74, 0x06, 0x10, 0x13, 0x41, 0x07, 0x00, 0xB9, 0x01,
-0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0x55, 0x00, 0x54, 0x47, 0x50, 0x19,
-0x40, 0x05, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
-0x00, 0x00, 0x01, 0x20, 0x14, 0x03, 0x90, 0x08, 0x62, 0x03, 0x00, 0x00, 0x00,
-0x34, 0x02, 0x14, 0x40, 0x40, 0x13, 0x00, 0x8D, 0x04, 0x34, 0x03, 0x50, 0x0C,
-0x40, 0x33, 0x08, 0xC1, 0x00, 0x14, 0x20, 0x10, 0x08, 0x42, 0x41, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x08, 0x9B, 0x00,
-0x5E, 0x03, 0xB1, 0x09, 0xC0, 0x27, 0x40, 0xD1, 0x00, 0x7C, 0x02, 0x30, 0x41,
-0xC0, 0x07, 0x10, 0x1F, 0x1C, 0xEC, 0x03, 0xF1, 0x0F, 0xE4, 0x3B, 0x00, 0x57,
-0x00, 0x5C, 0x12, 0x34, 0x01, 0xC0, 0x05, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x45, 0xA8, 0x2F, 0x00, 0xAF, 0x00, 0xEC, 0x03, 0x70, 0x03,
-0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0xC1, 0xC1, 0x0F, 0x04, 0x1F,
-0x04, 0xFC, 0x03, 0x72, 0x0F, 0xC4, 0x3F, 0x00, 0x3F, 0x00, 0x6C, 0x30, 0xF0,
-0x03, 0xC4, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA0, 0x2D, 0x11, 0xBF, 0x00, 0xFC, 0x13, 0xB2, 0x93, 0xC8, 0x3D, 0x11, 0x13,
-0x08, 0xDC, 0x22, 0x32, 0x4F, 0xC8, 0x0F, 0x20, 0x7B, 0x41, 0xEC, 0x03, 0xF0,
-0x17, 0xC0, 0x3C, 0x00, 0xBF, 0x01, 0xEC, 0x00, 0x30, 0x03, 0xC4, 0x0C, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x47, 0x02, 0x9C,
-0x8C, 0xF4, 0x27, 0x04, 0x09, 0x4C, 0x7D, 0x22, 0x1D, 0x04, 0x74, 0x12, 0x50,
-0xAF, 0x42, 0x07, 0x00, 0x99, 0x81, 0x44, 0x0B, 0xD0, 0x09, 0x40, 0x3C, 0x10,
-0x9D, 0x40, 0x44, 0x00, 0x10, 0x11, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x21, 0x08, 0x0D, 0x50, 0x34, 0x03, 0x18,
-0x51, 0x44, 0x31, 0x00, 0x0D, 0x20, 0x74, 0x02, 0x10, 0x0C, 0x64, 0x01, 0x00,
-0x89, 0x00, 0x24, 0x0B, 0xD0, 0x01, 0x50, 0x30, 0x00, 0x9D, 0x00, 0x24, 0x00,
-0x10, 0x00, 0x40, 0x4C, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA8, 0x47, 0x80, 0x1D, 0x51, 0x74, 0x03, 0x10, 0x11, 0x40, 0x35, 0x00,
-0x3D, 0x02, 0xF4, 0x02, 0x50, 0x0D, 0x00, 0x4F, 0x08, 0x89, 0x08, 0x44, 0x03,
-0xD2, 0x19, 0x00, 0x3C, 0x00, 0x9D, 0x01, 0x44, 0x04, 0x10, 0x11, 0x42, 0x0C,
-0xA0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x67, 0x00,
-0x9F, 0x03, 0x7C, 0x03, 0x30, 0x18, 0xCC, 0x35, 0x18, 0x1B, 0x01, 0x5E, 0x06,
-0x20, 0x0D, 0xC0, 0xC7, 0x00, 0xDB, 0x00, 0x6C, 0x03, 0xF0, 0x1C, 0xC0, 0x34,
-0x20, 0xCF, 0x01, 0x6C, 0x84, 0x30, 0x11, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00, 0xBF, 0x80, 0xBC, 0x03,
-0xF0, 0x0B, 0xC0, 0x3E, 0x80, 0x1D, 0x03, 0xFC, 0x26, 0xF0, 0x0F, 0xC0, 0x2F,
-0x00, 0xBF, 0x01, 0xFC, 0x03, 0xF2, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
-0x00, 0xF4, 0x09, 0xD0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x08, 0x25, 0x18, 0x93, 0x01, 0x7C, 0xA3, 0xF0, 0x01, 0xC0, 0x77,
-0x00, 0x1B, 0x02, 0x4C, 0x42, 0xF0, 0x0D, 0xC0, 0x87, 0x00, 0x9F, 0x00, 0x7C,
-0x03, 0x30, 0x09, 0x80, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC1,
-0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x64,
-0x04, 0x91, 0x02, 0xF4, 0x2F, 0xD0, 0x01, 0x40, 0xBF, 0x00, 0x11, 0x80, 0x45,
-0x47, 0xD1, 0x0F, 0x44, 0x27, 0x00, 0x9D, 0x00, 0xF4, 0x03, 0x10, 0x09, 0x40,
-0x3F, 0x00, 0x5D, 0x00, 0x34, 0x44, 0x10, 0x38, 0x58, 0x6C, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x00, 0x60, 0x08, 0x30, 0x36,
-0x0F, 0xD8, 0x00, 0x40, 0x33, 0x01, 0x09, 0x00, 0x50, 0x0E, 0xD0, 0x9C, 0x22,
-0x43, 0x02, 0x4C, 0x80, 0x34, 0x03, 0x10, 0x00, 0x40, 0x33, 0x00, 0xCD, 0x06,
-0x34, 0x00, 0x14, 0xA0, 0x40, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0F, 0x00, 0x58, 0x02, 0xE9, 0x81, 0xB4, 0x07, 0xD0, 0x1A, 0x40,
-0x7B, 0x00, 0x21, 0x09, 0x84, 0x06, 0xD1, 0x9E, 0x40, 0x5B, 0x00, 0xAD, 0x01,
-0xB4, 0x07, 0x10, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x41, 0xB4, 0x07, 0x18, 0x9A,
-0x40, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1A,
-0x30, 0x00, 0x4B, 0x08, 0x3C, 0x03, 0xF0, 0x80, 0xC0, 0x33, 0x00, 0x0B, 0x05,
-0x0C, 0x02, 0xF0, 0x0C, 0xC0, 0x43, 0x01, 0xCF, 0x00, 0x7C, 0x23, 0x34, 0x00,
-0x40, 0x33, 0x00, 0xCF, 0x00, 0x3C, 0x01, 0x30, 0x04, 0xC8, 0x48, 0x68, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x19, 0x00, 0xF0, 0x60,
-0xFC, 0x63, 0xF0, 0x0F, 0xC0, 0x3B, 0x02, 0xFF, 0x08, 0xF0, 0x23, 0xF0, 0x0F,
-0xC4, 0x1F, 0x02, 0xBF, 0x00, 0xFC, 0x83, 0xF0, 0x0B, 0xC0, 0xBF, 0x10, 0xFF,
-0x00, 0xBC, 0x03, 0xF1, 0x0D, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA0, 0x17, 0x10, 0x53, 0x00, 0x74, 0x5F, 0x34, 0x09,
-0xC0, 0x37, 0x00, 0x1F, 0x00, 0x4C, 0x02, 0x31, 0x9D, 0x80, 0x74, 0x00, 0xD3,
-0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x82, 0xCF, 0x00, 0x2C, 0x02, 0x30,
-0x15, 0xD0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
-0x8A, 0x39, 0x00, 0xE1, 0x00, 0x34, 0x13, 0x10, 0x0A, 0x40, 0xBB, 0x03, 0x8D,
-0x80, 0x84, 0x02, 0x12, 0x8C, 0x42, 0x3C, 0x08, 0xA1, 0x00, 0xB4, 0x13, 0xD0,
-0x0A, 0x40, 0x3A, 0x80, 0xED, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x40, 0x4C, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x40, 0x69,
-0x01, 0xB4, 0x17, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0x6D, 0x11, 0x94, 0x46, 0x90,
-0x5E, 0x40, 0x68, 0x00, 0xE1, 0x01, 0xB4, 0x37, 0x90, 0x1E, 0x40, 0x7B, 0x00,
-0x7D, 0x61, 0xA4, 0x07, 0x14, 0x14, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x00, 0xC9, 0x01, 0x34, 0x03, 0x50,
-0x8C, 0x40, 0x33, 0x00, 0xCD, 0xC3, 0x54, 0x07, 0x90, 0x0C, 0x50, 0x70, 0x01,
-0x81, 0x00, 0x34, 0x03, 0xD0, 0x48, 0x40, 0x36, 0x00, 0x4D, 0x09, 0x04, 0x03,
-0x10, 0x1C, 0x41, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x17, 0xA0, 0x1F, 0x20, 0x7B, 0x85, 0x7C, 0x01, 0x78, 0x17, 0xC6, 0x17, 0x08,
-0x7F, 0x03, 0x5C, 0x05, 0xB6, 0x05, 0xC0, 0x5C, 0x01, 0x73, 0x02, 0x7C, 0x01,
-0xB0, 0x37, 0xC1, 0x17, 0x00, 0x7F, 0x09, 0xAC, 0x01, 0x30, 0x77, 0xC0, 0x5C,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x05, 0x24,
-0x17, 0x46, 0x7C, 0x00, 0xA0, 0x01, 0xE0, 0x83, 0x20, 0x1E, 0xA0, 0x6C, 0x00,
-0x70, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x06,
-0x00, 0x1F, 0x02, 0x7C, 0x04, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0xA1, 0x00, 0x93, 0x08, 0x7C, 0x86,
-0xF0, 0x09, 0xC1, 0x25, 0x08, 0x93, 0x10, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x67,
-0x00, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x48,
-0x16, 0x30, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x20, 0x26, 0x00, 0x95, 0x03, 0x74, 0x66, 0xD0, 0x09, 0x40, 0x27,
-0x20, 0x91, 0x00, 0x44, 0x0A, 0x10, 0x39, 0x44, 0xA7, 0x02, 0x8D, 0x20, 0x44,
-0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x85, 0x40, 0x44, 0x42, 0x10, 0x49, 0x40,
-0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x34,
-0x00, 0x91, 0x82, 0x74, 0x82, 0xD0, 0x09, 0x40, 0x67, 0x00, 0x81, 0x00, 0x54,
-0x0A, 0x10, 0x49, 0x49, 0xB7, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x40,
-0x27, 0x00, 0x91, 0x00, 0x55, 0x03, 0x10, 0x0D, 0x40, 0x63, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0xA5, 0x85, 0x14, 0x34,
-0x82, 0xD0, 0x88, 0x40, 0x33, 0x60, 0x81, 0x4C, 0x04, 0x32, 0x18, 0x08, 0x40,
-0x23, 0x01, 0x9D, 0x02, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x01, 0x85, 0x00,
-0x14, 0xD2, 0x10, 0x48, 0x41, 0x43, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1D, 0xB0, 0x07, 0x01, 0x13, 0x24, 0x7C, 0x50, 0xF0, 0x21, 0xC4,
-0x05, 0x05, 0x13, 0x03, 0x09, 0x0C, 0x30, 0xE1, 0xC1, 0xC7, 0x02, 0x1F, 0x00,
-0x4D, 0x78, 0xF0, 0xA1, 0xC8, 0xC7, 0x0A, 0x53, 0x00, 0x5C, 0x10, 0x32, 0x41,
-0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8,
-0x2B, 0x00, 0xBF, 0x14, 0x7C, 0x02, 0xF0, 0x4B, 0xC0, 0x27, 0x00, 0xBF, 0x0C,
-0xFC, 0x32, 0xF4, 0x19, 0xC2, 0x6F, 0x02, 0xBD, 0x01, 0x7C, 0x06, 0xF0, 0x1B,
-0xC0, 0x67, 0x02, 0xFF, 0x14, 0xE4, 0x52, 0xF4, 0x0B, 0xC0, 0x77, 0x40, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x7F, 0x04, 0xBF, 0x02,
-0xFC, 0x02, 0xF0, 0x29, 0xC0, 0x2D, 0x20, 0x9F, 0x00, 0xFC, 0x0A, 0x30, 0x4B,
-0xC0, 0x2C, 0x00, 0x93, 0x02, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0xB3,
-0x00, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x08, 0x17, 0x00, 0x1D, 0x02, 0x74, 0x28, 0xD0, 0x00,
-0x48, 0x87, 0x02, 0x1D, 0x04, 0x5C, 0x10, 0x14, 0xA1, 0x50, 0x04, 0x00, 0x15,
-0x01, 0x74, 0x28, 0x10, 0x01, 0x40, 0x05, 0x00, 0x1B, 0x00, 0x74, 0x10, 0x10,
-0x01, 0xC0, 0x62, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x00, 0x21, 0x20, 0x8D, 0x86, 0x34, 0x02, 0xC0, 0x08, 0x40, 0x23, 0x00, 0x8D,
-0x10, 0x30, 0x12, 0x18, 0x08, 0x40, 0x24, 0x00, 0x81, 0x01, 0x34, 0x02, 0x14,
-0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x34, 0x13, 0x10, 0x08, 0x44, 0x48, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0xDD,
-0x0A, 0x74, 0x02, 0xC0, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x02, 0x14, 0x22, 0x10,
-0x09, 0x40, 0x24, 0x00, 0x95, 0x01, 0x34, 0x02, 0x10, 0x49, 0x44, 0x25, 0x00,
-0x99, 0x00, 0x34, 0x06, 0x14, 0x49, 0x40, 0x62, 0x20, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0x0A, 0x25, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xE0,
-0x29, 0xC1, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x30, 0x08, 0xC6, 0x64, 0x02,
-0xB3, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x02, 0x7C, 0x06,
-0x30, 0x09, 0xC0, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x16, 0x00, 0xA5, 0x20, 0x9F, 0x21, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x27, 0x04,
-0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x09, 0x40, 0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02,
-0xF2, 0x19, 0xC0, 0x23, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x08, 0xC0, 0x5B,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00,
-0x1F, 0x04, 0x6C, 0x00, 0x70, 0x21, 0xC0, 0x04, 0x02, 0x1F, 0x02, 0x7C, 0x00,
-0x31, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x40, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
-0x08, 0x13, 0x0A, 0x7C, 0x04, 0x30, 0xC1, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xDC, 0x0E, 0x7D, 0x06, 0xF4, 0x41,
-0x10, 0x05, 0x80, 0x5E, 0x00, 0x5D, 0x60, 0xF4, 0x6D, 0x10, 0x37, 0x40, 0x1C,
-0x00, 0x51, 0x00, 0x6C, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x75, 0x40, 0xF4,
-0x01, 0x10, 0x17, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xA0, 0xE2, 0x00, 0xCD, 0x41, 0x24, 0x17, 0x80, 0x0C, 0x58, 0xF0,
-0x20, 0xCD, 0x00, 0x34, 0x0F, 0x90, 0x2C, 0x41, 0x74, 0x04, 0xC1, 0x00, 0x04,
-0x03, 0xD1, 0x0D, 0x40, 0x33, 0x00, 0x81, 0x10, 0x34, 0x03, 0x10, 0x2C, 0x40,
-0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x88, 0x29,
-0x80, 0xED, 0x80, 0xB4, 0x07, 0x94, 0xDE, 0x40, 0x28, 0x20, 0xEC, 0x08, 0x34,
-0x03, 0x90, 0x2C, 0x50, 0x20, 0x04, 0xF1, 0x45, 0xA4, 0x23, 0xD0, 0x0E, 0x40,
-0x3B, 0x00, 0x25, 0x00, 0x34, 0x03, 0x12, 0x0A, 0x40, 0x13, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x79, 0x00, 0xEF, 0x01, 0xAC,
-0x05, 0xB1, 0x5E, 0x41, 0x78, 0x00, 0xEF, 0x05, 0xBC, 0x05, 0xB0, 0x1A, 0xC0,
-0x78, 0x00, 0xF3, 0x43, 0x8C, 0x57, 0xF0, 0x1E, 0xC3, 0x73, 0x00, 0xA3, 0x01,
-0xBC, 0x07, 0x34, 0x12, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA8, 0x35, 0x00, 0x5F, 0x40, 0x3C, 0x00, 0x31, 0x4D, 0xC8,
-0x27, 0x08, 0xDF, 0x10, 0x7C, 0x01, 0x70, 0x09, 0xC8, 0x37, 0x40, 0xDF, 0x00,
-0x7C, 0x13, 0xF0, 0xCD, 0xC0, 0xB7, 0x02, 0x1F, 0x00, 0x7C, 0x03, 0xB4, 0x09,
-0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20,
-0x6D, 0x00, 0xFF, 0x01, 0xCC, 0x06, 0xF0, 0x9F, 0xC0, 0x5F, 0x02, 0xFF, 0x09,
-0xCC, 0x27, 0xF0, 0x1B, 0xC0, 0x7D, 0x00, 0xEF, 0x41, 0xCC, 0x87, 0x70, 0x1F,
-0xC0, 0xFC, 0x00, 0xE3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC8, 0x1B, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x29, 0x20, 0xFD, 0x00,
-0xAC, 0x1A, 0xD2, 0xCE, 0x40, 0x2B, 0x00, 0xFD, 0x00, 0x84, 0x04, 0xD0, 0x0F,
-0xC0, 0x20, 0x01, 0xED, 0x25, 0xC4, 0x07, 0x50, 0x0E, 0xC1, 0x3A, 0x20, 0x6B,
-0x00, 0x94, 0x03, 0xB0, 0x0A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x08, 0x00, 0x29, 0x00, 0xED, 0x00, 0xB4, 0x02, 0xD2, 0x0E,
-0x60, 0x0B, 0x20, 0xED, 0x00, 0x96, 0x03, 0xD0, 0x02, 0x40, 0x1B, 0x80, 0xFD,
-0x05, 0xC4, 0x03, 0x11, 0x8E, 0x40, 0x38, 0x00, 0xF1, 0x00, 0x84, 0x43, 0x10,
-0x2E, 0x40, 0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x28, 0xF1, 0x04, 0x8D, 0x13, 0x34, 0x02, 0xD0, 0x2D, 0x40, 0x23, 0x00, 0xC9,
-0x03, 0x54, 0x04, 0xD0, 0x00, 0x40, 0xC0, 0x10, 0xCD, 0x04, 0x04, 0x03, 0x58,
-0x3C, 0x41, 0x32, 0x00, 0x59, 0x00, 0x14, 0x07, 0x91, 0x0C, 0x40, 0x0B, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x25, 0x10, 0x1F,
-0x12, 0x7C, 0x02, 0xF0, 0x2F, 0xC0, 0x27, 0x00, 0xFF, 0x05, 0x5C, 0x46, 0xF0,
-0x05, 0xC0, 0x07, 0x01, 0xDF, 0x07, 0xCD, 0x03, 0x32, 0x0F, 0x40, 0x3C, 0x00,
-0x53, 0x00, 0x4C, 0x07, 0x30, 0x25, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x27, 0x02, 0x9F, 0x00, 0x64, 0x08, 0xF0,
-0xCD, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x6C, 0x02, 0xF0, 0x05, 0xC0, 0x87, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0xE0, 0x0D, 0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x03,
-0xF0, 0x01, 0xC2, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x89, 0x09, 0x3F, 0x10, 0x2F, 0x00, 0xCC, 0x80, 0xF0, 0x0F, 0xC0, 0x08, 0x00,
-0xF3, 0x10, 0xFC, 0x20, 0x30, 0x03, 0xC0, 0x0F, 0x04, 0xFF, 0x00, 0xBC, 0x03,
-0x10, 0x0F, 0xC0, 0x3F, 0x10, 0xFF, 0x01, 0x4C, 0x65, 0xF0, 0x97, 0xC0, 0x07,
-0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xB6, 0x00,
-0x1D, 0x21, 0x54, 0x04, 0xD0, 0x0D, 0x40, 0xC4, 0x00, 0xD1, 0x40, 0x74, 0x00,
-0x10, 0x21, 0x40, 0xC6, 0x01, 0xDD, 0x00, 0x74, 0x03, 0xB0, 0x0D, 0xC0, 0x35,
-0x00, 0xDD, 0x0B, 0x54, 0x00, 0xD0, 0x2D, 0x44, 0x87, 0x02, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x24, 0x14, 0x1D, 0x01, 0x46, 0x06,
-0xD0, 0x0D, 0x40, 0x44, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x13, 0x41, 0x4F,
-0x80, 0xDD, 0x00, 0xF4, 0x03, 0x50, 0x0F, 0x40, 0x3F, 0x00, 0x9D, 0x10, 0x44,
-0x03, 0x90, 0x25, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x22, 0x20, 0x00, 0x8D, 0x80, 0x14, 0x00, 0xD8, 0x0C, 0x40, 0x20,
-0x00, 0xC1, 0x22, 0x34, 0x40, 0x14, 0x00, 0x40, 0x03, 0x00, 0xCD, 0x04, 0x34,
-0x13, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x14, 0x07, 0xD0, 0x00, 0x40,
-0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, 0x06,
-0x00, 0x1F, 0x00, 0x4C, 0x02, 0xF0, 0x0F, 0xC0, 0x04, 0x00, 0xF1, 0x02, 0x74,
-0x13, 0x30, 0x01, 0xC0, 0x87, 0x02, 0xFF, 0x10, 0xFC, 0x53, 0x70, 0x0E, 0xC0,
-0x3B, 0x00, 0x9F, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x60, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB0, 0x1F, 0x00, 0xBF, 0x80, 0xF8,
-0x00, 0xF0, 0x0F, 0xC2, 0x0F, 0x00, 0xFF, 0x20, 0x7C, 0x00, 0xF0, 0x03, 0xC0,
-0x0E, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB1, 0x0F, 0xC0, 0x3D, 0x00, 0xBF, 0x00,
-0xFC, 0x83, 0xF0, 0x0F, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x09, 0xFC, 0x02, 0x30, 0x4B, 0xC1,
-0x3F, 0x13, 0xFF, 0x00, 0xCC, 0x13, 0x70, 0x83, 0xC0, 0x3C, 0x40, 0xF3, 0x00,
-0xBC, 0x06, 0xB0, 0x0F, 0xC0, 0x2C, 0x17, 0x3B, 0x0C, 0xCC, 0x00, 0xB0, 0x03,
-0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18,
-0x37, 0x01, 0xCD, 0x04, 0x74, 0xEA, 0x10, 0x69, 0xC8, 0xBD, 0x22, 0xFD, 0xDE,
-0xD4, 0x2F, 0x10, 0x01, 0x40, 0xFC, 0x00, 0xD1, 0x02, 0x44, 0x87, 0x10, 0x1F,
-0x40, 0xA5, 0x01, 0x11, 0x0E, 0x44, 0x08, 0x10, 0x01, 0x40, 0x0F, 0x60, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x33, 0x04, 0xCD, 0x00,
-0x34, 0x10, 0x50, 0x00, 0x41, 0x33, 0x09, 0xCD, 0x44, 0x14, 0x03, 0x10, 0x50,
-0x60, 0xB1, 0x00, 0xC5, 0x02, 0x14, 0x82, 0x90, 0x0D, 0x60, 0x34, 0x01, 0xC9,
-0x00, 0x04, 0x08, 0x12, 0x00, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x04, 0x36, 0x0E, 0x54, 0x19,
-0x42, 0x37, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x12, 0x40, 0x35, 0x00, 0xD5,
-0x20, 0x55, 0x03, 0x10, 0x0F, 0x40, 0x55, 0x00, 0xC1, 0x18, 0x45, 0x63, 0x10,
-0x11, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xA8, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x06, 0x70, 0x31, 0xC0, 0x37, 0x00, 0xDF,
-0x00, 0x4C, 0x03, 0x30, 0x11, 0x40, 0x35, 0x00, 0xD6, 0x00, 0x7C, 0x02, 0xB0,
-0x0D, 0xC0, 0x64, 0x80, 0x1B, 0x03, 0x4E, 0x07, 0x30, 0x19, 0xC0, 0x2B, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0xFD, 0x20, 0xFF,
-0x81, 0x7E, 0x02, 0xB0, 0x01, 0xC4, 0x3D, 0x00, 0xDF, 0x00, 0xBC, 0x43, 0xB0,
-0x0B, 0xC0, 0x3E, 0x10, 0xFA, 0x00, 0xEC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00,
-0xFF, 0x80, 0x7C, 0x01, 0x70, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x4C, 0x08, 0x38,
-0x21, 0xC0, 0x34, 0x08, 0xD7, 0xC0, 0x4C, 0x03, 0x70, 0x01, 0xD1, 0x30, 0x00,
-0xDF, 0x84, 0x4D, 0x42, 0x32, 0x4D, 0xC0, 0x27, 0x00, 0x1B, 0x12, 0x3C, 0x02,
-0x30, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1B, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x6C, 0x82, 0x10, 0x19, 0x41, 0x3C, 0x00,
-0xF1, 0x00, 0xC4, 0x4B, 0xD0, 0x19, 0x40, 0x3C, 0x01, 0xE7, 0x01, 0x04, 0x46,
-0x12, 0x3F, 0xC0, 0x11, 0x00, 0xDD, 0x00, 0x74, 0x1B, 0x10, 0xB9, 0x41, 0x4F,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x32, 0x00,
-0xCD, 0x00, 0x24, 0x00, 0x10, 0x58, 0x40, 0x30, 0x00, 0xD5, 0x00, 0x04, 0x0B,
-0x50, 0x20, 0x40, 0x32, 0x00, 0xC8, 0x2B, 0x04, 0x0A, 0x12, 0x0D, 0x44, 0x23,
-0x10, 0x09, 0x08, 0x34, 0x40, 0x90, 0x18, 0x40, 0x0E, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00, 0xED, 0x01, 0xA4, 0x05,
-0x10, 0x1E, 0x40, 0x78, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x41, 0x78,
-0x80, 0xE5, 0x01, 0xC4, 0x07, 0x10, 0x1E, 0x40, 0x79, 0x00, 0xED, 0x01, 0xB4,
-0x15, 0x90, 0x12, 0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x10, 0x32, 0x00, 0xCE, 0x40, 0x2C, 0x21, 0x10, 0x84, 0xC0, 0x34,
-0x02, 0xC7, 0x08, 0x06, 0x03, 0x70, 0x05, 0xC0, 0x32, 0x00, 0xCF, 0x40, 0x0C,
-0x02, 0x30, 0x0C, 0xC1, 0x23, 0x00, 0x0B, 0x04, 0x3C, 0x02, 0xB0, 0x0C, 0xC0,
-0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x3D,
-0x20, 0xFF, 0x80, 0xDD, 0x81, 0xF0, 0x8F, 0xC0, 0x3F, 0x00, 0xFF, 0x20, 0xFE,
-0x03, 0xF0, 0x0F, 0xC0, 0xBD, 0x04, 0xEF, 0x00, 0xFC, 0x03, 0xF5, 0x0F, 0xC0,
-0x1F, 0x00, 0xDF, 0x00, 0x7C, 0x13, 0x72, 0x0F, 0xC0, 0x0B, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x37, 0x20, 0xDF, 0x00, 0x7C,
-0x03, 0x70, 0x0D, 0xC0, 0x37, 0x01, 0xDF, 0x04, 0x7C, 0x13, 0xD1, 0x11, 0xD0,
-0x30, 0x01, 0xD3, 0x08, 0x4C, 0x06, 0x30, 0x5D, 0xC8, 0x20, 0x00, 0x17, 0x00,
-0x5C, 0x00, 0xB4, 0x0D, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x13, 0x88, 0x38, 0x10, 0xED, 0x20, 0xB6, 0x03, 0xD0, 0x0E, 0x40,
-0xBB, 0x03, 0xED, 0x28, 0xB4, 0x23, 0xD0, 0x0B, 0x40, 0x38, 0x00, 0xE1, 0x00,
-0xAC, 0x02, 0x50, 0xAE, 0x40, 0x38, 0x00, 0xE1, 0x40, 0xB4, 0x01, 0x10, 0x06,
-0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
-0x79, 0x80, 0xED, 0x81, 0x94, 0x07, 0xD8, 0x16, 0x40, 0x7B, 0x00, 0xED, 0x09,
-0xB4, 0x27, 0xD0, 0x16, 0x49, 0x78, 0x01, 0xE1, 0x05, 0x94, 0x06, 0x90, 0x5E,
-0x58, 0x6C, 0x40, 0x21, 0x03, 0x34, 0x06, 0x50, 0x1C, 0x40, 0x10, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x23, 0x80, 0x8D, 0x00,
-0x34, 0x07, 0xD8, 0xAC, 0x40, 0x33, 0x10, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x2C,
-0x40, 0x30, 0x80, 0xC1, 0x00, 0x34, 0x86, 0xD0, 0x0C, 0x40, 0x10, 0x00, 0xC1,
-0x10, 0x74, 0x2F, 0x50, 0x2D, 0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x01, 0x5F, 0x00, 0xFC, 0x0D, 0x72, 0x17,
-0xCA, 0x17, 0x08, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0x48, 0x14, 0x00, 0x43,
-0x00, 0x54, 0x01, 0xB0, 0x05, 0xC4, 0x1C, 0x01, 0x73, 0x03, 0xDC, 0x2D, 0x70,
-0x47, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x00, 0x05, 0x20, 0x1F, 0x00, 0x7C, 0x60, 0xF8, 0x01, 0xC1, 0x07, 0x00, 0x0F,
-0x00, 0x7C, 0x08, 0xF0, 0x41, 0xC8, 0x03, 0x40, 0x1F, 0x00, 0x64, 0x20, 0x73,
-0x01, 0xC0, 0x07, 0x20, 0x19, 0x02, 0x7C, 0x00, 0xB0, 0x21, 0xD0, 0x4B, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F,
-0x00, 0x78, 0x02, 0xF0, 0x89, 0xC2, 0x27, 0x00, 0x9B, 0x00, 0x4C, 0x06, 0xF0,
-0x09, 0xC0, 0x25, 0x01, 0x93, 0x09, 0x5C, 0x02, 0xF0, 0x99, 0xC0, 0x23, 0x00,
-0x97, 0x28, 0x44, 0x82, 0x31, 0x09, 0xC1, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0,
-0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x0E, 0xD0, 0x29, 0x40, 0x27, 0x00,
-0x91, 0x03, 0x44, 0x02, 0xD0, 0x39, 0x40, 0x27, 0x00, 0x91, 0x07, 0x44, 0x0A,
-0x10, 0x29, 0x51, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x70, 0x02, 0xD0, 0x0D, 0x40, 0x27, 0x00,
-0x9D, 0x00, 0x44, 0x1A, 0xD0, 0x29, 0x00, 0x27, 0x40, 0x91, 0x02, 0x54, 0x02,
-0xD8, 0x09, 0x41, 0x27, 0x00, 0x85, 0x00, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x70,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x20, 0x00,
-0x8D, 0x00, 0x34, 0x52, 0xD0, 0x4C, 0x41, 0x23, 0x02, 0x8D, 0x08, 0x04, 0x82,
-0xD0, 0xC8, 0x40, 0x23, 0x00, 0x81, 0x14, 0x04, 0x03, 0xD9, 0x48, 0x40, 0x23,
-0x00, 0x81, 0x08, 0x14, 0x82, 0x14, 0x48, 0x41, 0x50, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x40, 0x7C, 0x10,
-0xF0, 0x41, 0xC0, 0x87, 0x05, 0x1B, 0x16, 0x4C, 0x50, 0xF0, 0x31, 0xC0, 0x05,
-0x05, 0x03, 0x0E, 0x5C, 0x00, 0xF0, 0x11, 0xC0, 0x87, 0x05, 0x17, 0x16, 0x5D,
-0x51, 0x30, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x19, 0xB8, 0x2F, 0x0D, 0xBF, 0x34, 0xFC, 0x52, 0xF0, 0x4B, 0xC1, 0x27,
-0x01, 0x9F, 0x04, 0x7D, 0x82, 0xF0, 0xCB, 0x80, 0x27, 0x00, 0x9F, 0x01, 0xBC,
-0x02, 0xF0, 0x88, 0xC0, 0x2F, 0x04, 0xBF, 0x04, 0xEC, 0x52, 0xF8, 0x4B, 0xC1,
-0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0xA7,
-0x00, 0xDF, 0x02, 0x54, 0x1E, 0xF0, 0x2B, 0xC0, 0x25, 0x01, 0x9F, 0x54, 0xFC,
-0x12, 0x30, 0x8B, 0xC0, 0x2E, 0x05, 0xB3, 0x01, 0xCC, 0x02, 0xF0, 0x0B, 0xC0,
-0xA4, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0x32, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x03, 0x20, 0x1D, 0x01, 0x6E,
-0x08, 0x10, 0x85, 0x40, 0x00, 0x05, 0x0D, 0x04, 0x74, 0x80, 0x10, 0x01, 0x50,
-0x84, 0x00, 0x11, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x54, 0x01, 0x1D, 0x40,
-0x44, 0x00, 0xBA, 0x05, 0xC0, 0x72, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0xA0, 0x21, 0x81, 0x9D, 0x00, 0x04, 0xB2, 0x58, 0x48, 0x40,
-0x21, 0x02, 0x8D, 0x14, 0x34, 0x0A, 0x12, 0x48, 0x44, 0x20, 0x00, 0x81, 0x22,
-0x04, 0x02, 0xD0, 0x08, 0x50, 0x21, 0x01, 0x8D, 0x00, 0x14, 0x02, 0x10, 0x08,
-0x40, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20,
-0x25, 0x80, 0x9D, 0x00, 0x64, 0x62, 0x58, 0x0D, 0x40, 0x24, 0x00, 0x9C, 0x00,
-0x70, 0x02, 0x00, 0x0C, 0x60, 0x24, 0x40, 0x91, 0x00, 0x45, 0x02, 0xD0, 0x0D,
-0x40, 0x25, 0x22, 0x9D, 0x80, 0x54, 0x2A, 0x90, 0x09, 0x40, 0x62, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x67, 0x00, 0x8D, 0x40,
-0x44, 0x06, 0x68, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x19,
-0xC4, 0x26, 0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0x40, 0x25, 0x00, 0x9D,
-0x0F, 0x5C, 0x06, 0x30, 0x29, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x80, 0x24, 0x01, 0x9F, 0x04, 0x3C, 0x02, 0xB0, 0x59,
-0xC0, 0x27, 0x08, 0x9F, 0x00, 0x7E, 0x02, 0xF4, 0x49, 0xC0, 0x21, 0x00, 0x9F,
-0x00, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x66, 0x00, 0x9F, 0x11, 0x6D, 0x42, 0xF2,
-0x49, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x05, 0x48, 0x1B, 0x00, 0x7C, 0x00, 0xB8, 0x21, 0xC1, 0x07, 0x00, 0x17,
-0x00, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x5C, 0x20, 0xF0,
-0x11, 0xC0, 0x05, 0x00, 0x07, 0x22, 0x4C, 0x08, 0xE0, 0x21, 0xD0, 0x40, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x51,
-0x00, 0x74, 0x01, 0xB8, 0x07, 0x40, 0x17, 0x00, 0x51, 0x00, 0xC4, 0x09, 0xD0,
-0x17, 0xC0, 0x14, 0x00, 0x73, 0x81, 0xC4, 0x29, 0xD0, 0x07, 0x40, 0x14, 0x00,
-0x71, 0x02, 0xC0, 0x45, 0xD1, 0x07, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xC1, 0x80, 0x34, 0x03, 0x93,
-0x8D, 0x46, 0x33, 0x00, 0xC5, 0x00, 0x14, 0x17, 0xD0, 0x0C, 0x40, 0x22, 0x30,
-0x59, 0x8F, 0x14, 0x02, 0xC8, 0x1C, 0x40, 0x31, 0x80, 0xC5, 0x03, 0x45, 0x0B,
-0xD0, 0x8D, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x88, 0x78, 0x09, 0xE1, 0x00, 0xB4, 0x13, 0x10, 0x0E, 0x40, 0x7B, 0x03,
-0xE4, 0x0D, 0x91, 0x43, 0xD0, 0x28, 0x40, 0x30, 0x00, 0x01, 0x00, 0xA4, 0x01,
-0xD1, 0x0E, 0x41, 0x78, 0x00, 0xE1, 0x02, 0x84, 0x03, 0xD0, 0x04, 0x40, 0x04,
-0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x79, 0x04,
-0xE3, 0x0D, 0xB4, 0x0F, 0x90, 0x1E, 0xC0, 0x7B, 0x04, 0xE7, 0x15, 0x9C, 0x07,
-0xF0, 0x16, 0xE0, 0x6A, 0x00, 0x2B, 0x01, 0x9C, 0x04, 0xF0, 0x1E, 0xC0, 0x7D,
-0x00, 0x77, 0x01, 0x8D, 0x07, 0xF0, 0x1E, 0xC4, 0x44, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x35, 0x23, 0xD7, 0x80, 0x7C, 0x43,
-0xF0, 0x0D, 0xC0, 0xB7, 0x01, 0xDB, 0x04, 0x6C, 0x03, 0xF0, 0x01, 0xC2, 0x27,
-0x40, 0x1F, 0x22, 0x5C, 0x01, 0xF0, 0x08, 0xC0, 0x37, 0x08, 0x5F, 0x00, 0x7C,
-0x01, 0xF2, 0x05, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x20, 0x7D, 0x00, 0xF3, 0x19, 0xF8, 0x27, 0x78, 0x9F, 0xC0, 0x7D,
-0x00, 0xF3, 0x01, 0xBC, 0x06, 0x30, 0x1F, 0xC0, 0x6F, 0x00, 0x63, 0x83, 0xCC,
-0x04, 0xF0, 0x17, 0xC4, 0x78, 0x00, 0xB3, 0x01, 0xCE, 0x25, 0x30, 0x1F, 0xC0,
-0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39,
-0x1A, 0xEB, 0x38, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x38, 0x02, 0xE1, 0x00, 0xB4,
-0x80, 0x10, 0x0E, 0x40, 0x3B, 0x01, 0x65, 0x00, 0x84, 0x08, 0xD0, 0x56, 0x40,
-0x39, 0x00, 0xA1, 0x02, 0x84, 0x28, 0x10, 0x62, 0xC0, 0x56, 0x60, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x04, 0xE1, 0x88, 0xB4,
-0x03, 0xD8, 0x06, 0x45, 0x31, 0x40, 0xE9, 0x00, 0xB4, 0x23, 0x90, 0x06, 0x40,
-0x23, 0x80, 0xA9, 0x00, 0x84, 0x00, 0xD0, 0x4C, 0x40, 0x3E, 0x00, 0x05, 0x08,
-0x05, 0x81, 0x10, 0x06, 0x40, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x20, 0x75, 0x00, 0xD8, 0x00, 0x74, 0x07, 0xDA, 0x19, 0x41,
-0x30, 0x00, 0xC9, 0x00, 0x34, 0x01, 0x93, 0x25, 0x40, 0x27, 0x00, 0x1D, 0x00,
-0x04, 0x20, 0xD0, 0x08, 0x40, 0x71, 0x40, 0x45, 0x01, 0x44, 0x80, 0x18, 0x21,
-0x40, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8,
-0x7D, 0x00, 0xF3, 0x01, 0xFC, 0x13, 0xF0, 0x01, 0xC4, 0x3D, 0x00, 0xFB, 0x80,
-0x7E, 0x01, 0xB0, 0x5D, 0xC0, 0x27, 0x00, 0x1B, 0x00, 0x4D, 0x84, 0xF0, 0x09,
-0xC0, 0x7C, 0x04, 0xD5, 0x13, 0x4C, 0x3E, 0x36, 0x29, 0xC0, 0x55, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x40,
-0x7C, 0x43, 0x70, 0x01, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x3E, 0x08, 0x72, 0x01,
-0xC0, 0x37, 0x00, 0x17, 0x02, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x37, 0x0C, 0xDA,
-0x04, 0x7C, 0x0A, 0xF0, 0x29, 0x80, 0x06, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xF3, 0x00, 0xCE, 0x83, 0x30, 0x01,
-0xC0, 0x38, 0x00, 0xF3, 0x00, 0xFE, 0x83, 0x32, 0x1F, 0xC1, 0x2C, 0x10, 0x33,
-0x00, 0xCC, 0x14, 0xF0, 0x0B, 0x80, 0x3B, 0x00, 0x63, 0x08, 0xCC, 0x02, 0xF0,
-0x09, 0xD1, 0x10, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
-0x20, 0x36, 0x00, 0xD1, 0x20, 0x44, 0x03, 0x18, 0x11, 0x40, 0x35, 0x00, 0xD1,
-0x00, 0x74, 0x12, 0x50, 0x21, 0xC0, 0x26, 0x00, 0x1B, 0x23, 0x6C, 0x09, 0xD0,
-0x21, 0x00, 0x37, 0x00, 0x91, 0x02, 0x44, 0x04, 0x10, 0x19, 0x40, 0x14, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x10, 0xD1,
-0x00, 0x44, 0x03, 0x10, 0x19, 0x40, 0x34, 0x40, 0xD1, 0x00, 0x54, 0x10, 0x50,
-0x49, 0x40, 0x24, 0x00, 0x31, 0x11, 0x44, 0x00, 0xD0, 0x15, 0x40, 0x37, 0x00,
-0x91, 0x00, 0x44, 0x86, 0x50, 0x19, 0x40, 0x04, 0x08, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x2A, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x83, 0x10,
-0x08, 0x48, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x00, 0x10, 0x01, 0x40, 0x36, 0x80,
-0x19, 0x00, 0x20, 0x01, 0xD0, 0x44, 0x44, 0x33, 0x00, 0x01, 0x60, 0x04, 0x82,
-0x12, 0x08, 0x40, 0x40, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x30, 0x3C, 0x08, 0xF3, 0x00, 0xC4, 0x03, 0x10, 0x01, 0x40, 0x3C, 0x00,
-0xF3, 0x00, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x24, 0x00, 0x33, 0x00, 0x4C, 0x00,
-0xF1, 0x4D, 0xC1, 0x37, 0x40, 0x13, 0x00, 0x4D, 0x02, 0x70, 0x01, 0xC0, 0x00,
-0xC4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xA8, 0x3B, 0x00,
-0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x40, 0xF4, 0x00,
-0xF1, 0x03, 0xC8, 0x2F, 0x00, 0x3E, 0x20, 0xFC, 0x81, 0xF0, 0x01, 0xC0, 0x3F,
-0x20, 0x3F, 0x00, 0xFD, 0x00, 0xE0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x3B, 0x04, 0xFF, 0xC0, 0xFC, 0x43,
-0xB2, 0x4F, 0xC0, 0x3D, 0x00, 0xEF, 0x04, 0xEC, 0x23, 0xF1, 0x12, 0xC0, 0x35,
-0x03, 0x7B, 0x01, 0xFC, 0x42, 0xB0, 0x13, 0xC0, 0x2E, 0x00, 0xBB, 0x01, 0xEC,
-0x86, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x08, 0xFF, 0x00, 0xFD, 0x0C, 0xF4, 0x8F, 0xD0, 0x9F, 0x48, 0xFC,
-0x22, 0xDD, 0x03, 0xC4, 0x3B, 0xD2, 0x19, 0x40, 0xB4, 0x01, 0x91, 0xE1, 0x74,
-0x0E, 0x10, 0x05, 0x43, 0x74, 0x00, 0x91, 0x01, 0x44, 0x03, 0x13, 0x11, 0x48,
-0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
-0x18, 0xCD, 0x50, 0x34, 0x03, 0xC0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x42, 0x24,
-0x13, 0xD2, 0x01, 0x60, 0xB1, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x41, 0x40,
-0x22, 0x00, 0x4D, 0x00, 0x74, 0x04, 0x10, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x34, 0x08, 0xDD, 0x00, 0x74,
-0x83, 0xD0, 0x0D, 0x40, 0x36, 0x08, 0xDD, 0x00, 0x44, 0x83, 0xD0, 0x11, 0x48,
-0x34, 0x08, 0x99, 0x00, 0x74, 0x07, 0x51, 0x81, 0x41, 0x34, 0x00, 0xD5, 0x08,
-0x56, 0x91, 0x10, 0x19, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xA0, 0x0D, 0xC0,
-0x36, 0x20, 0xDF, 0x20, 0x6C, 0x03, 0xF2, 0x38, 0xC8, 0x35, 0x30, 0xDB, 0x08,
-0x7C, 0x02, 0xF0, 0x35, 0x86, 0x62, 0x00, 0xCF, 0x03, 0x3C, 0x07, 0x30, 0x11,
-0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
-0x3D, 0x24, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xFF, 0x00,
-0xFC, 0x03, 0xE0, 0x0B, 0x80, 0x36, 0x00, 0xB5, 0x00, 0xBC, 0x43, 0xB0, 0x17,
-0xC0, 0x7F, 0x0A, 0xFB, 0x00, 0xEC, 0x01, 0xF2, 0x0B, 0xC0, 0x1F, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x04,
-0x7C, 0x03, 0x71, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x21,
-0xC0, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x22, 0xF0, 0x21, 0xC0, 0x27, 0x00, 0x5F,
-0x00, 0x7C, 0x11, 0x30, 0x81, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0xA0, 0x3C, 0x00, 0xF1, 0x82, 0xF4, 0x8F, 0x18, 0x5E,
-0x44, 0xFF, 0x24, 0xED, 0x02, 0xC4, 0x03, 0xD2, 0x81, 0x41, 0x7C, 0x00, 0x9B,
-0x00, 0x74, 0x0F, 0xC0, 0x00, 0x40, 0x37, 0x00, 0xDC, 0x09, 0x40, 0x09, 0x10,
-0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
-0xA0, 0xF2, 0x00, 0xC5, 0x01, 0x34, 0x17, 0x51, 0x0C, 0x40, 0xB2, 0x04, 0xCD,
-0x10, 0x14, 0x03, 0xD0, 0x00, 0x40, 0x37, 0x02, 0x05, 0x00, 0x34, 0x0B, 0xC0,
-0x00, 0x4A, 0x33, 0x10, 0x4C, 0x01, 0x14, 0x03, 0x10, 0x00, 0x41, 0x1F, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x78, 0x06, 0xE1,
-0xB1, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x89, 0x94, 0x07, 0xD0,
-0x1E, 0x42, 0x7A, 0x01, 0xA9, 0x81, 0xB4, 0x87, 0xD0, 0x16, 0x40, 0x6B, 0x00,
-0x6D, 0x31, 0xC0, 0x07, 0x10, 0x12, 0x40, 0x1B, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x3C, 0x43, 0x50,
-0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x20, 0x1C, 0x03, 0xF0, 0x40, 0xC0, 0x73, 0x81,
-0xC7, 0x00, 0x3C, 0x32, 0xF0, 0x40, 0xC0, 0x33, 0x00, 0x4F, 0x22, 0x1C, 0x12,
-0x30, 0x84, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x40, 0xBC, 0x2B, 0xB1, 0x0F, 0xC0, 0x3F, 0x00,
-0xFF, 0x90, 0xE4, 0x03, 0xF0, 0x0B, 0xC0, 0x3D, 0x00, 0xB7, 0x00, 0xFC, 0x63,
-0xF0, 0x07, 0xC0, 0x2F, 0x02, 0x6F, 0x00, 0x1C, 0x03, 0xF0, 0x8D, 0xC2, 0x0B,
-0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x73, 0x01,
-0xDB, 0x0A, 0x7C, 0x97, 0x39, 0x6D, 0xC1, 0xB7, 0x01, 0xDF, 0x00, 0x5C, 0x4B,
-0x71, 0x18, 0xC0, 0x36, 0x20, 0x9F, 0x20, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x32,
-0x00, 0x5B, 0x00, 0x7C, 0x03, 0x36, 0x05, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0xB9, 0x05, 0xE1, 0x54, 0xB4, 0x13,
-0x18, 0x2E, 0x60, 0xBB, 0x03, 0xED, 0x04, 0x04, 0x03, 0x10, 0x0E, 0x60, 0x38,
-0x01, 0xA7, 0x00, 0xB4, 0x13, 0xD0, 0x07, 0x42, 0x28, 0x10, 0x61, 0x20, 0xB4,
-0x01, 0x10, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x00, 0x79, 0x00, 0xE9, 0x05, 0x34, 0x27, 0x12, 0x5E, 0x40, 0x7B,
-0x00, 0xCD, 0x05, 0x94, 0x27, 0x52, 0x1A, 0x64, 0x7A, 0x02, 0xED, 0x01, 0xB4,
-0x0E, 0xD0, 0x1E, 0x40, 0x7A, 0x20, 0x6D, 0x21, 0xF4, 0x07, 0x10, 0x16, 0x40,
-0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x33,
-0x08, 0xC1, 0x00, 0x34, 0x83, 0x10, 0x0C, 0x40, 0x33, 0x10, 0xCD, 0x20, 0x04,
-0x03, 0x10, 0x0C, 0x40, 0x32, 0x00, 0x85, 0x00, 0x34, 0x03, 0xD0, 0x25, 0x41,
-0x20, 0x00, 0x45, 0x08, 0x34, 0x8F, 0x10, 0xEC, 0x40, 0x4B, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x00, 0x5B, 0x20, 0x7C,
-0x01, 0x35, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x70, 0x27, 0xC2,
-0x16, 0x00, 0x7F, 0x22, 0x7C, 0x01, 0xF8, 0x27, 0xD3, 0x16, 0x20, 0x6F, 0x20,
-0xF4, 0x0D, 0x30, 0x17, 0xC2, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF0, 0x21, 0xC4,
-0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x05, 0x00, 0x17, 0x04,
-0x7C, 0x08, 0xF2, 0x01, 0xC0, 0x87, 0x00, 0x1A, 0x02, 0x74, 0x60, 0xF0, 0x01,
-0xC0, 0x4B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
-0x27, 0x02, 0x9F, 0x09, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x67, 0x80, 0x83, 0x08,
-0x5C, 0x02, 0x30, 0x99, 0xC3, 0x23, 0x00, 0x92, 0x00, 0x0C, 0x86, 0x70, 0x09,
-0xC0, 0x21, 0x01, 0x93, 0x04, 0x5C, 0x06, 0x32, 0x08, 0xC2, 0x40, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00, 0x9D, 0x03,
-0x74, 0x02, 0xD0, 0xA9, 0x41, 0xE3, 0x04, 0x9B, 0x01, 0x44, 0x02, 0x10, 0x09,
-0x40, 0x27, 0x00, 0x81, 0x00, 0xC4, 0x0A, 0xB0, 0x09, 0x40, 0xA4, 0x00, 0x95,
-0x00, 0x04, 0x0E, 0x10, 0x09, 0x40, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x88, 0x24, 0x04, 0x9D, 0x10, 0x74, 0x22, 0xD0, 0x09,
-0x40, 0x27, 0x01, 0x91, 0x00, 0x14, 0x02, 0x14, 0x0D, 0x41, 0x27, 0x41, 0x95,
-0x00, 0x54, 0x12, 0x50, 0x09, 0x40, 0xA5, 0x00, 0x91, 0x00, 0x54, 0x12, 0x14,
-0x89, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x20, 0x20, 0x05, 0x8D, 0x34, 0x36, 0x52, 0xD2, 0x08, 0x40, 0x23, 0x40, 0x89,
-0xC0, 0x04, 0x22, 0x10, 0x08, 0x40, 0xA3, 0x00, 0x95, 0x02, 0x14, 0x03, 0x90,
-0x88, 0x40, 0x20, 0x05, 0x94, 0x00, 0x44, 0x06, 0x10, 0x48, 0x41, 0x41, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x01, 0x1F,
-0x24, 0x7C, 0x91, 0xF0, 0x41, 0xC1, 0x07, 0x05, 0x11, 0x54, 0x5C, 0x58, 0x30,
-0x01, 0xCA, 0x07, 0x05, 0x17, 0x00, 0x5D, 0x04, 0x70, 0x21, 0xC0, 0x05, 0x01,
-0x53, 0x00, 0x5C, 0x00, 0x30, 0x45, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F, 0x54, 0x7C, 0x02, 0xF0,
-0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x12, 0xF2, 0x0B, 0xC0, 0x67, 0x00,
-0xBB, 0x01, 0xEC, 0x0A, 0x70, 0x4B, 0xC8, 0x2F, 0x00, 0xFF, 0x00, 0xAE, 0x52,
-0xF4, 0x0B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x19, 0xA8, 0x6F, 0x04, 0xBF, 0x36, 0xFC, 0x42, 0xF0, 0x0A, 0xC0, 0x2C, 0x00,
-0xBF, 0x90, 0x7F, 0x32, 0xF0, 0x0F, 0xC0, 0xAF, 0x04, 0x9F, 0x02, 0xCD, 0x86,
-0x34, 0x89, 0xC0, 0x2F, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x64,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00,
-0x1D, 0x02, 0x74, 0x08, 0xD0, 0xA1, 0x52, 0x84, 0x02, 0x1D, 0x02, 0x44, 0x00,
-0x70, 0x05, 0x40, 0xC7, 0x00, 0x1D, 0x01, 0x44, 0x88, 0x10, 0x05, 0x48, 0x04,
-0x00, 0x1D, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x04, 0x34, 0x02,
-0xD0, 0x08, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x14, 0x1A, 0xD0, 0x08, 0x62, 0x23,
-0x00, 0x8D, 0x00, 0x04, 0x0A, 0x10, 0x48, 0x40, 0x22, 0x00, 0x8D, 0x00, 0x74,
-0x03, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA0, 0x25, 0x00, 0x9D, 0xA0, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24,
-0x20, 0x9D, 0x00, 0x44, 0x02, 0x50, 0x09, 0x48, 0x27, 0x00, 0x8D, 0x00, 0x44,
-0x02, 0x11, 0x89, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x29, 0x40,
-0x60, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27,
-0x10, 0x9F, 0x00, 0x78, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x08, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0x40, 0x2F, 0x00, 0xBE, 0x07, 0x4C, 0x02, 0x31, 0x39, 0xC2,
-0x27, 0x00, 0x9F, 0x00, 0x3C, 0x16, 0x20, 0x09, 0xD0, 0x14, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x24, 0x00, 0x9F, 0x80, 0x7C,
-0x42, 0xF0, 0x08, 0xE0, 0x27, 0x0C, 0x8F, 0x10, 0x7D, 0x02, 0xF0, 0x39, 0xC0,
-0x27, 0x00, 0x9F, 0x02, 0x7C, 0x4A, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x23,
-0x7C, 0x16, 0xF4, 0x59, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x08, 0x05, 0x01, 0x1F, 0x00, 0x4C, 0x20, 0x30, 0x41, 0xC0,
-0x04, 0x00, 0x12, 0x00, 0x5C, 0x80, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x02,
-0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x24, 0x1F, 0x22, 0x5C, 0x00, 0x30, 0x41,
-0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
-0xDC, 0x04, 0x7D, 0x00, 0xC4, 0x09, 0xF0, 0x17, 0x44, 0xDD, 0x4C, 0x71, 0x03,
-0x44, 0x01, 0x10, 0x77, 0xC0, 0x55, 0x00, 0x5B, 0x00, 0xB4, 0x11, 0xD0, 0x05,
-0x40, 0x5F, 0x00, 0x7D, 0x03, 0xC4, 0x01, 0x50, 0x36, 0x40, 0x50, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x00, 0xCD, 0x45,
-0x14, 0x0A, 0x10, 0x24, 0x40, 0x70, 0x80, 0x81, 0x00, 0x14, 0x03, 0x10, 0x48,
-0x40, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x02, 0xD0, 0x0D, 0x42, 0xA3, 0x00, 0x8D,
-0x12, 0x14, 0x03, 0x10, 0x8C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x03, 0x94, 0x05, 0x51, 0x22,
-0x40, 0x61, 0x00, 0x81, 0x10, 0x84, 0x17, 0x14, 0x0A, 0x40, 0xFD, 0x01, 0xED,
-0x04, 0xB4, 0x02, 0xD0, 0x4E, 0x00, 0x2B, 0x04, 0xBD, 0x11, 0x84, 0x03, 0x52,
-0x00, 0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x10, 0x68, 0x00, 0xCF, 0x01, 0x15, 0x04, 0x10, 0x16, 0xE0, 0x78, 0x88, 0xA3,
-0x01, 0xDC, 0x47, 0x30, 0x1E, 0xE8, 0x7F, 0x01, 0xE7, 0x03, 0xBC, 0x06, 0xF0,
-0x1E, 0xC0, 0x6B, 0x00, 0xAF, 0x41, 0xDC, 0x07, 0x32, 0x1E, 0xC0, 0x50, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x5F,
-0x00, 0x6C, 0x01, 0xF0, 0x01, 0xC2, 0x27, 0x00, 0x9F, 0x20, 0x7E, 0x23, 0xF0,
-0x09, 0xC0, 0x37, 0x12, 0xDB, 0x00, 0x7C, 0x02, 0xF0, 0x8D, 0xC0, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x40, 0x73, 0x81, 0xE4, 0x04, 0xF1,
-0x17, 0xC0, 0x78, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1B, 0xC0, 0x6F, 0x80,
-0xE7, 0x09, 0xCC, 0x07, 0xF0, 0x1F, 0xC2, 0x7C, 0x00, 0xFF, 0x01, 0xFC, 0x07,
-0x30, 0x17, 0xC0, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x88, 0x29, 0x00, 0x61, 0x00, 0x84, 0x10, 0x70, 0x02, 0x40, 0x98, 0x02,
-0xE1, 0x80, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x2B, 0x81, 0xE1, 0x00, 0x84, 0x02,
-0xD0, 0x8E, 0xC0, 0x3A, 0x00, 0xED, 0x00, 0xF4, 0x23, 0x18, 0x26, 0x40, 0x54,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x21, 0x00,
-0xE1, 0x00, 0x84, 0x00, 0xD1, 0x08, 0x40, 0x38, 0x00, 0xE1, 0x08, 0xB4, 0x03,
-0xD0, 0x0E, 0x41, 0x2B, 0x30, 0xF5, 0x01, 0x84, 0x03, 0xD0, 0x0F, 0x40, 0x28,
-0x04, 0xAD, 0x00, 0xB4, 0x02, 0x50, 0x26, 0x40, 0x20, 0x01, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x13, 0x00, 0x11, 0x40, 0x04, 0x01,
-0x50, 0x08, 0x4C, 0x10, 0x00, 0xC9, 0x00, 0x34, 0x03, 0xD0, 0x24, 0x40, 0x23,
-0x00, 0xC1, 0x04, 0x04, 0x05, 0xD0, 0x2C, 0x40, 0x22, 0x80, 0x4D, 0x00, 0x36,
-0x0C, 0x50, 0x0C, 0x52, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0xA8, 0x25, 0x00, 0x93, 0x00, 0x4C, 0x00, 0xF0, 0x05, 0xC4, 0x14,
-0x00, 0x93, 0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC4, 0x37, 0x00, 0xD7, 0x04, 0x4D,
-0x12, 0xF0, 0x3F, 0xC1, 0x24, 0x00, 0x9F, 0x0A, 0x7C, 0x0C, 0x70, 0x29, 0xC0,
-0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37,
-0x10, 0x9F, 0x82, 0x5C, 0x01, 0xF0, 0x05, 0xC0, 0x03, 0x00, 0x97, 0x80, 0x7E,
-0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC1,
-0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x60, 0xB4, 0x29, 0xC0, 0x27, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x0A, 0x2B, 0x20, 0x93, 0x80, 0xCC,
-0x00, 0x30, 0x07, 0xC0, 0xAF, 0x00, 0xA3, 0x09, 0x8D, 0x03, 0x32, 0x0F, 0xC1,
-0x77, 0x00, 0xFB, 0x00, 0xCC, 0x02, 0x34, 0x0F, 0x00, 0x2E, 0x00, 0xBF, 0x00,
-0xFC, 0x00, 0x30, 0x09, 0xC0, 0x07, 0x2A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x81, 0x21, 0x36, 0x00, 0x91, 0x11, 0x14, 0x41, 0x51, 0x95, 0x40,
-0xA7, 0x00, 0x91, 0x02, 0x44, 0x03, 0x10, 0x09, 0x44, 0x67, 0x02, 0xDD, 0x00,
-0x04, 0x02, 0x30, 0x0D, 0x40, 0x27, 0x04, 0x9D, 0x00, 0x34, 0x1C, 0x10, 0xBD,
-0x44, 0x87, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0,
-0x24, 0x10, 0x11, 0x81, 0x64, 0x80, 0x18, 0x05, 0x40, 0x17, 0x00, 0x91, 0x02,
-0x44, 0x03, 0x14, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x10, 0x0D,
-0x40, 0x36, 0x02, 0xDD, 0x00, 0x74, 0x04, 0x10, 0x01, 0x40, 0x07, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, 0x00, 0x01, 0x00,
-0x16, 0x80, 0x50, 0x04, 0x40, 0x13, 0x00, 0x01, 0x00, 0x04, 0x03, 0x10, 0x08,
-0x48, 0xB3, 0x20, 0xCD, 0x00, 0x05, 0x02, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xCD,
-0x00, 0x74, 0x00, 0x10, 0x0C, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0xB0, 0x26, 0x00, 0x93, 0x00, 0x4C, 0x00, 0x30, 0x09,
-0xC0, 0x27, 0x00, 0xD1, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x27, 0x08, 0xFB,
-0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x16, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x30,
-0x01, 0xC4, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0xA8, 0x1F, 0x00, 0xBF, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x0F, 0x00, 0x7F,
-0x40, 0xFC, 0x03, 0xF1, 0x07, 0xC0, 0x2F, 0x01, 0xFF, 0x00, 0xFC, 0x01, 0x70,
-0x0E, 0xC0, 0x1F, 0x00, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x17, 0x60,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x88, 0x7B, 0x22, 0xFB,
-0x29, 0xEC, 0x27, 0xF0, 0x9F, 0xC4, 0x7C, 0x02, 0xEF, 0x09, 0xCC, 0x07, 0x30,
-0x9F, 0xC0, 0x7C, 0x00, 0xE3, 0x01, 0xCC, 0x07, 0xF0, 0x9F, 0xC0, 0x7C, 0x00,
-0xEF, 0x09, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x07, 0x00, 0x11, 0x04, 0x4C, 0x00, 0xD1,
-0x01, 0x00, 0x04, 0x31, 0x1D, 0x04, 0x44, 0x04, 0x50, 0x41, 0x00, 0x05, 0x05,
-0x11, 0x00, 0x5C, 0x10, 0xD0, 0x41, 0x40, 0x00, 0x25, 0x1D, 0x04, 0x44, 0x00,
-0xD0, 0x01, 0x40, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x13, 0xA0, 0x35, 0x00, 0xD9, 0x00, 0x24, 0x13, 0x52, 0x4C, 0x42, 0x31, 0x01,
-0xCD, 0x04, 0x44, 0x83, 0x50, 0x0D, 0x0A, 0x30, 0x00, 0xD5, 0x00, 0x04, 0x43,
-0xD0, 0x4C, 0x60, 0x30, 0x00, 0xCD, 0x00, 0x05, 0x03, 0xD0, 0x0C, 0x40, 0x4D,
-0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x07, 0x00,
-0x11, 0x00, 0x40, 0x80, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x1D, 0x00, 0x47, 0x00,
-0x50, 0x01, 0x48, 0x01, 0x40, 0x15, 0x20, 0x74, 0x00, 0xD0, 0x00, 0x48, 0x05,
-0x00, 0x0D, 0x00, 0x54, 0x00, 0xC0, 0x01, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x36, 0x00, 0xDB, 0x00, 0x6C, 0x03,
-0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x40, 0x0C, 0x03, 0x70, 0x0D, 0x40, 0x34,
-0x00, 0xD7, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x4C,
-0x03, 0xE0, 0x0D, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00, 0xDC, 0x40, 0xF3, 0x03, 0xD4, 0x0E,
-0x10, 0x3F, 0x00, 0xF8, 0x40, 0xF0, 0x03, 0xC0, 0x0F, 0x20, 0x3B, 0x00, 0xDC,
-0x00, 0xF1, 0x03, 0xC0, 0x0E, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0,
-0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35,
-0x00, 0xD7, 0x04, 0x7C, 0x03, 0xF0, 0x4D, 0xC0, 0x37, 0x00, 0xD7, 0x60, 0x5C,
-0x07, 0xB0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x4C, 0x13, 0xF0, 0x0D, 0xC0,
-0x34, 0x40, 0xD3, 0x04, 0x4C, 0x43, 0xF0, 0x0D, 0xC0, 0xAB, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x00, 0x06, 0x01, 0x12, 0x74,
-0x14, 0xD0, 0x71, 0x60, 0x07, 0x00, 0x11, 0x00, 0x6C, 0x00, 0x10, 0x00, 0x40,
-0xC7, 0x02, 0x0D, 0x11, 0x6C, 0x18, 0xD2, 0x01, 0x40, 0x04, 0x00, 0x11, 0x12,
-0x6C, 0x00, 0xD0, 0xB1, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x20, 0xF0, 0x10, 0xC5, 0x80, 0x34, 0x03, 0xD1, 0x0D, 0x42,
-0x33, 0x00, 0xDD, 0x00, 0x24, 0x0B, 0x90, 0x0C, 0x40, 0xB3, 0x00, 0xC5, 0x01,
-0x04, 0x0F, 0xD8, 0x0C, 0x40, 0x32, 0x00, 0xC1, 0x01, 0x04, 0x0B, 0xD2, 0x1C,
-0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02,
-0x4C, 0x00, 0x21, 0x01, 0xB4, 0x04, 0xD9, 0x12, 0x40, 0x4F, 0x02, 0x39, 0x01,
-0xA4, 0x04, 0x10, 0x12, 0x40, 0x4B, 0x04, 0x3D, 0x01, 0xA6, 0x24, 0xD0, 0x12,
-0x68, 0x4A, 0x00, 0x31, 0x01, 0xA4, 0x04, 0xD0, 0x12, 0x53, 0x3C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x00,
-0x3C, 0x03, 0xF0, 0x0C, 0x48, 0x33, 0x10, 0xCF, 0x00, 0x3C, 0x03, 0xB0, 0x0C,
-0x40, 0x33, 0x00, 0xC7, 0x00, 0x0C, 0xA3, 0xF1, 0x0D, 0xCC, 0x32, 0x80, 0xC3,
-0x00, 0x0C, 0x03, 0xF0, 0x0D, 0xC0, 0x49, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF8, 0x03,
-0x80, 0x0B, 0x08, 0x36, 0x00, 0xBC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F,
-0x00, 0xFC, 0x20, 0xD2, 0x03, 0xC0, 0x0D, 0x10, 0x3F, 0x00, 0xFC, 0x00, 0xFA,
-0x11, 0xC0, 0x09, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xA8, 0x77, 0x20, 0xD7, 0x41, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x74, 0x00, 0xC3,
-0x01, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x01, 0x4D, 0x03, 0x70,
-0x1D, 0xC0, 0x30, 0x00, 0xD3, 0x01, 0x4C, 0x07, 0x30, 0x1D, 0xD0, 0x40, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x80, 0x0D, 0x48, 0x21,
-0x40, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x09, 0x00, 0x25, 0x00, 0x90, 0x00, 0xD0,
-0x02, 0x40, 0x0B, 0x00, 0x35, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x40, 0x09, 0x00,
-0x2B, 0x40, 0x84, 0x00, 0xB0, 0x03, 0xC0, 0x4E, 0x08, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xF9, 0x01, 0xA4, 0x07, 0xC2,
-0x1F, 0x40, 0x7C, 0x00, 0xF5, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7F, 0x00,
-0xE1, 0x01, 0x94, 0x07, 0x50, 0x1F, 0x48, 0x7C, 0x80, 0xE1, 0x01, 0xC4, 0x07,
-0x18, 0x1E, 0x48, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x16, 0x28, 0x03, 0x00, 0x09, 0x00, 0x40, 0x00, 0xD8, 0x00, 0x42, 0x01, 0x00,
-0x05, 0x20, 0x14, 0x00, 0xD0, 0x00, 0x40, 0x07, 0x00, 0x05, 0x00, 0x14, 0x00,
-0x50, 0x00, 0x40, 0x05, 0x08, 0x09, 0x00, 0x04, 0x00, 0x98, 0x00, 0x40, 0x5A,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15, 0x00,
-0x5B, 0x00, 0x6C, 0x01, 0xD0, 0x04, 0xC0, 0x14, 0x00, 0x57, 0x00, 0x4C, 0x01,
-0xF0, 0x05, 0xC4, 0x17, 0x00, 0x53, 0x00, 0x1C, 0x01, 0x70, 0x05, 0xC0, 0x14,
-0x08, 0x53, 0x60, 0x4C, 0x01, 0x30, 0x05, 0x40, 0x5C, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x8D, 0x00, 0x37, 0x02, 0xFC, 0x00,
-0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x08, 0xF0, 0x03, 0xC8, 0x0F,
-0x00, 0x3F, 0x02, 0xE4, 0x08, 0xB0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xFD,
-0x00, 0xF0, 0x03, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0x40, 0x24,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C,
-0x16, 0x30, 0x09, 0xC0, 0x27, 0x40, 0x93, 0x04, 0x78, 0x16, 0xF0, 0x09, 0xC0,
-0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24,
-0x01, 0x9D, 0x00, 0x74, 0x42, 0x14, 0x59, 0xC0, 0x26, 0x00, 0x9D, 0x00, 0x74,
-0x0A, 0xD0, 0x09, 0x40, 0xA4, 0x00, 0x91, 0x9A, 0x74, 0x8E, 0xB2, 0x09, 0x40,
-0x27, 0x10, 0x91, 0x02, 0x64, 0x16, 0xD1, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x6C, 0x80, 0xBD, 0x01, 0xE4,
-0x06, 0x10, 0x4B, 0x40, 0x2D, 0x00, 0xBD, 0x00, 0xF4, 0x0E, 0xD0, 0x0A, 0x40,
-0x2C, 0x04, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x00, 0x2F, 0x00, 0xB1, 0x10,
-0xF4, 0x02, 0xD0, 0x0B, 0x41, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0x28, 0x00, 0xEC, 0x00, 0xB4, 0x02, 0x10, 0x0B, 0x40,
-0x2B, 0x22, 0xAD, 0x08, 0xB4, 0x82, 0xD0, 0x8A, 0x60, 0x28, 0x42, 0xA1, 0x40,
-0xF4, 0x02, 0x90, 0x8A, 0x40, 0x2B, 0x0A, 0xA1, 0x08, 0xA4, 0x02, 0xD0, 0x0A,
-0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8,
-0x06, 0x00, 0x1F, 0x40, 0x6C, 0x00, 0x30, 0x01, 0xC0, 0x85, 0x00, 0x1D, 0x02,
-0x7C, 0x00, 0xF0, 0x21, 0xD0, 0x84, 0x00, 0x13, 0x0A, 0x7C, 0x01, 0x30, 0x21,
-0xC0, 0x87, 0x08, 0x03, 0x22, 0x7C, 0x00, 0xF0, 0x03, 0xE0, 0x77, 0xE0, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x8D, 0x14,
-0x7C, 0x52, 0xF0, 0x48, 0xC1, 0x22, 0x01, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x49,
-0xC0, 0x27, 0x01, 0x9F, 0x81, 0x7C, 0x52, 0xF0, 0x48, 0xC0, 0x27, 0x01, 0x9F,
-0x24, 0x3C, 0x52, 0xF0, 0x49, 0xC1, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0xA0, 0xAF, 0x00, 0xB7, 0x02, 0xDC, 0x0A, 0xB0, 0x2B,
-0xC0, 0x27, 0x00, 0x9F, 0x02, 0xDC, 0x02, 0x30, 0x89, 0xC0, 0x2F, 0x10, 0xB3,
-0x00, 0xFC, 0x02, 0xF0, 0x29, 0xC0, 0xA7, 0x10, 0xBF, 0x00, 0xCC, 0x02, 0xB0,
-0x0B, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x00, 0x05, 0x01, 0x11, 0x81, 0x44, 0x00, 0x10, 0x41, 0x40, 0x07, 0x05, 0x1D,
-0x00, 0x44, 0x00, 0x50, 0x01, 0x40, 0x07, 0x01, 0x11, 0x00, 0x74, 0x50, 0xD0,
-0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x50, 0x01, 0x40, 0x63, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x21, 0x01, 0x85,
-0x00, 0x54, 0x12, 0x90, 0x48, 0x40, 0x23, 0x80, 0x8D, 0x04, 0x44, 0x02, 0x10,
-0x48, 0x40, 0x23, 0x44, 0x81, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x80,
-0x8D, 0x00, 0x06, 0x02, 0x90, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91, 0x00, 0x44, 0x03, 0x08,
-0x09, 0x40, 0x27, 0x00, 0x8C, 0x00, 0x45, 0x82, 0x50, 0x09, 0x42, 0x23, 0x08,
-0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02,
-0xD8, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0x20, 0x25, 0x00, 0x97, 0x00, 0x1C, 0x02, 0xB0, 0x09, 0xC4, 0x27, 0x00,
-0x9F, 0x00, 0x5C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x92, 0x00, 0x7C, 0x02,
-0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC8, 0x17,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x88, 0x25, 0x00,
-0x9F, 0x00, 0x7C, 0x02, 0xF8, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C, 0x02,
-0xF0, 0x09, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x80, 0x7D, 0x42, 0x70, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1D, 0x10, 0x7C, 0x10,
-0xD0, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x5C, 0x00, 0x70, 0x01, 0xC0, 0x04,
-0x00, 0x1B, 0x49, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C,
-0x00, 0xB4, 0x41, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xA0, 0xDC, 0x00, 0x7D, 0x23, 0xF4, 0x9D, 0x10, 0x97, 0x40, 0x17,
-0x00, 0x5D, 0x00, 0xB4, 0x21, 0xD0, 0x05, 0x40, 0x1C, 0x00, 0x7D, 0x01, 0xF4,
-0x01, 0xD0, 0x05, 0x40, 0x15, 0x20, 0x7D, 0x02, 0xF4, 0x09, 0x10, 0x07, 0x40,
-0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xB6,
-0x06, 0xDD, 0x0B, 0x34, 0x03, 0x50, 0xAC, 0x40, 0x33, 0x00, 0xCD, 0x80, 0x14,
-0x8F, 0xD0, 0x0C, 0x50, 0x70, 0x80, 0xC9, 0x21, 0x32, 0x27, 0xD0, 0x0C, 0x40,
-0x32, 0x00, 0xDD, 0x12, 0x74, 0x23, 0x10, 0x1C, 0x40, 0x43, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x39, 0x00, 0xED, 0x00, 0xF4,
-0x03, 0x10, 0x0E, 0x40, 0x3B, 0x03, 0xEC, 0x04, 0xB4, 0x0A, 0xC0, 0x5E, 0x40,
-0x38, 0x04, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x5F, 0x40, 0x3B, 0x00, 0x2D, 0x10,
-0xB4, 0x03, 0x10, 0x2E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x18, 0x79, 0x00, 0xEF, 0x01, 0xBC, 0x07, 0x70, 0x1E, 0xC0,
-0x7B, 0x05, 0xEB, 0x89, 0x9C, 0x07, 0x70, 0xBF, 0xC0, 0x78, 0x20, 0x2B, 0x21,
-0xBC, 0x07, 0xF0, 0x3E, 0xC0, 0x7A, 0x05, 0xEF, 0x01, 0xFC, 0x07, 0x31, 0x1E,
-0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8,
-0x15, 0x10, 0x5F, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0x80, 0xB7, 0x01, 0xDF, 0x0C,
-0x7C, 0x00, 0xF0, 0x4D, 0xC0, 0x17, 0x00, 0x1F, 0x20, 0x7C, 0x03, 0xF0, 0x0C,
-0x41, 0x35, 0x08, 0x1F, 0x00, 0x7C, 0x01, 0x70, 0x0D, 0xC0, 0x43, 0x60, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x7D, 0x00, 0xFF, 0x89,
-0xF8, 0x05, 0x70, 0x1F, 0xC2, 0x7D, 0x00, 0xFB, 0x01, 0xFC, 0x07, 0xF0, 0x1F,
-0xC0, 0x6F, 0x00, 0xF7, 0x01, 0xCE, 0x25, 0x30, 0x1F, 0xC0, 0x7F, 0x04, 0xF3,
-0x01, 0x8C, 0x25, 0x30, 0x1E, 0xC0, 0x18, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x08, 0x39, 0x04, 0xED, 0x08, 0xF4, 0x11, 0x00, 0x0E,
-0x40, 0x3F, 0x00, 0xE0, 0x10, 0xB4, 0x42, 0xD0, 0x8E, 0x41, 0x3B, 0x00, 0xF5,
-0x02, 0x94, 0x0B, 0x50, 0x0E, 0xC0, 0x3B, 0x00, 0x3B, 0x08, 0x85, 0x39, 0xB0,
-0x0A, 0x40, 0x55, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
-0x00, 0x39, 0x02, 0xED, 0x08, 0xB0, 0x01, 0xD1, 0x06, 0x40, 0x39, 0x04, 0xE9,
-0x08, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x2F, 0x00, 0x71, 0x08, 0xC4, 0x01, 0x90,
-0x0E, 0x40, 0x3F, 0x00, 0xE9, 0x00, 0xC4, 0x00, 0x18, 0x07, 0x40, 0x20, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x21, 0x10, 0x9D,
-0x03, 0x34, 0x00, 0x90, 0x89, 0x40, 0xF2, 0x80, 0xC1, 0x02, 0x34, 0x0C, 0xD0,
-0x1C, 0x60, 0x57, 0x00, 0x05, 0x06, 0x14, 0x0E, 0xD8, 0x2C, 0x40, 0xB1, 0x00,
-0xCD, 0x0A, 0x00, 0xAC, 0x98, 0x00, 0x42, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x55, 0xA0, 0xC4, 0x20, 0x1F, 0x52, 0x7C, 0x0A, 0xD0,
-0xA1, 0xC0, 0xFD, 0x80, 0xFB, 0x01, 0x7C, 0x2C, 0xF0, 0x0F, 0xC8, 0xD7, 0x01,
-0x93, 0x11, 0x4C, 0x12, 0xB0, 0x3F, 0x41, 0xBF, 0x00, 0xC9, 0x08, 0x48, 0x0E,
-0x10, 0x91, 0xC0, 0x74, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x0D, 0x08, 0x27, 0x20, 0x9F, 0x84, 0x7E, 0x60, 0x70, 0x21, 0xC8, 0x37, 0x09,
-0xDF, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC1, 0xA6, 0x00, 0x9E, 0x40, 0x7E, 0x40,
-0x70, 0x0D, 0xC1, 0x37, 0x22, 0x1B, 0x00, 0x7C, 0x1A, 0xF0, 0x89, 0xC4, 0x97,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x0B, 0x84,
-0x33, 0x80, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x3E, 0x00, 0xF7, 0x10, 0xF8, 0x00,
-0xF2, 0x0F, 0xC0, 0x1C, 0x04, 0x33, 0x80, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F,
-0x04, 0xFF, 0x00, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x04, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x46, 0x08, 0x17, 0x11, 0x4C, 0x06,
-0xD0, 0x11, 0x40, 0x34, 0x00, 0xD1, 0x80, 0x74, 0x04, 0xF0, 0x0C, 0x40, 0x85,
-0x02, 0x11, 0x03, 0x64, 0x06, 0xD0, 0x0D, 0x40, 0x37, 0x08, 0x1D, 0x11, 0x6C,
-0x04, 0xD0, 0x38, 0xC8, 0x06, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0xA0, 0x44, 0x04, 0x11, 0x21, 0x54, 0x06, 0xD8, 0x39, 0x66, 0x32,
-0x00, 0xD5, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40, 0x04, 0x04, 0x31, 0x21, 0x74,
-0x04, 0xD8, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x08, 0x44, 0x06, 0xD0, 0x31, 0x40,
-0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x24,
-0x00, 0x85, 0x00, 0x05, 0x00, 0xD2, 0x08, 0x60, 0x30, 0x00, 0xC1, 0x00, 0x34,
-0x02, 0xD0, 0x0D, 0x40, 0x21, 0x20, 0x01, 0x00, 0x34, 0x00, 0xD2, 0x0C, 0x40,
-0x33, 0x00, 0x1D, 0x00, 0x24, 0x02, 0xD0, 0x09, 0x40, 0x42, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x06, 0x00, 0x11, 0x00, 0x5C,
-0x82, 0xF8, 0x01, 0xC0, 0x3E, 0x00, 0xF6, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0x40,
-0x04, 0x00, 0x13, 0x00, 0x74, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x90, 0x1F, 0x00,
-0x4C, 0x02, 0xF0, 0x01, 0xC0, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x85, 0xA8, 0x2F, 0x00, 0xB6, 0x00, 0xCC, 0x02, 0xF8, 0x0B, 0xC0,
-0x3F, 0x00, 0xFE, 0x80, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x0B, 0x40, 0x3F, 0x00,
-0xA4, 0x02, 0xF2, 0x0F, 0xC0, 0x3B, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03,
-0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8,
-0x7F, 0x40, 0xF3, 0x46, 0xFC, 0x03, 0x30, 0x4F, 0xC0, 0x4F, 0x12, 0x3B, 0x4C,
-0xCC, 0x23, 0x30, 0x4F, 0xC2, 0x0C, 0x80, 0x3F, 0x01, 0xFC, 0x07, 0x71, 0x8F,
-0xC0, 0x0F, 0x08, 0x73, 0x01, 0xFC, 0x00, 0x30, 0x03, 0xC0, 0x0C, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x7D, 0x00, 0xE1, 0x08,
-0xF4, 0xAF, 0x10, 0xBF, 0x40, 0x27, 0x01, 0x5D, 0x08, 0xC4, 0x3B, 0x50, 0x9F,
-0x40, 0x44, 0x00, 0x5D, 0x00, 0xF4, 0x07, 0x10, 0x0F, 0x40, 0x07, 0x00, 0xD5,
-0x81, 0x74, 0x00, 0xB1, 0x01, 0x80, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0x20, 0x33, 0x00, 0xC4, 0x04, 0x34, 0x03, 0x55, 0x0C,
-0x40, 0x43, 0x01, 0x8D, 0x44, 0x14, 0x03, 0x50, 0x0C, 0x50, 0x00, 0x00, 0x0D,
-0x80, 0x34, 0x03, 0x10, 0x4C, 0x40, 0x07, 0x00, 0x41, 0x00, 0x34, 0x00, 0xD0,
-0x00, 0x40, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA0, 0x35, 0x00, 0xD5, 0x00, 0x70, 0x03, 0x50, 0x0D, 0x40, 0x67, 0x00, 0x5D,
-0x14, 0x54, 0x03, 0x10, 0x0D, 0x00, 0x6C, 0x00, 0x5D, 0x10, 0x74, 0x03, 0x10,
-0x0F, 0x40, 0x6F, 0x00, 0xD5, 0x04, 0x70, 0x06, 0xD0, 0x11, 0x40, 0x0F, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x36, 0x00, 0xD7,
-0x00, 0x7E, 0x03, 0x70, 0x0D, 0xC4, 0x47, 0x00, 0x1B, 0x03, 0x5D, 0x03, 0x70,
-0x0D, 0x80, 0x44, 0x20, 0xDD, 0x00, 0x3C, 0x03, 0x74, 0x0D, 0xC4, 0x47, 0x00,
-0x93, 0x06, 0x78, 0x04, 0x70, 0x51, 0xC0, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFB, 0x00, 0xBC, 0x03, 0xB0,
-0x0F, 0xC0, 0x0F, 0x00, 0x6A, 0x20, 0xEC, 0x03, 0xF0, 0x0F, 0x84, 0x0F, 0x08,
-0xFC, 0x00, 0xFE, 0x03, 0xE0, 0x0F, 0x80, 0x0F, 0x00, 0xBF, 0x01, 0xB8, 0x02,
-0xB0, 0x09, 0xC2, 0x3E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x08, 0x31, 0x10, 0xD3, 0x40, 0x5C, 0x03, 0xF3, 0x0D, 0xC0, 0x06, 0x00,
-0x9F, 0x02, 0x2C, 0x03, 0x70, 0x4C, 0xC0, 0x26, 0x04, 0xD7, 0x22, 0x7C, 0x13,
-0x30, 0x0D, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x28,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x34, 0x00,
-0xF1, 0x20, 0xC4, 0x17, 0xD0, 0x4F, 0x40, 0x24, 0x00, 0x5D, 0x40, 0xC0, 0x17,
-0x10, 0x7F, 0x40, 0xE7, 0x00, 0xDD, 0x06, 0x70, 0x03, 0x11, 0xAF, 0x10, 0x24,
-0x00, 0x9D, 0x45, 0x44, 0x46, 0x11, 0x19, 0x11, 0x4C, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x72, 0x40, 0xC9, 0x20, 0x24, 0x03,
-0xD0, 0x6C, 0x40, 0x22, 0x00, 0x08, 0x20, 0x20, 0x03, 0xD0, 0x1C, 0x40, 0xC2,
-0x88, 0x84, 0x20, 0x30, 0x0B, 0x10, 0x0C, 0x40, 0x04, 0x00, 0x8D, 0x21, 0x25,
-0x04, 0x14, 0x11, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x0F, 0x00, 0x70, 0x04, 0xE9, 0x01, 0xB4, 0x17, 0xD8, 0x1E, 0x40, 0x6A,
-0x08, 0xAD, 0x05, 0xA4, 0x07, 0x90, 0x1E, 0x4A, 0x5B, 0x0A, 0xED, 0x6B, 0x34,
-0x07, 0x81, 0x9E, 0x42, 0x58, 0x00, 0xAD, 0x01, 0xB6, 0x05, 0x10, 0xB6, 0x40,
-0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30,
-0x00, 0xCB, 0x00, 0x2C, 0x03, 0xF0, 0x0C, 0xC0, 0x22, 0x01, 0x9F, 0x00, 0x6C,
-0x03, 0xF0, 0x0C, 0xC0, 0x02, 0x04, 0x87, 0x05, 0x3C, 0x43, 0x20, 0x0D, 0xC0,
-0x10, 0x00, 0xCF, 0x00, 0x6C, 0x01, 0x30, 0x00, 0xC0, 0x48, 0x68, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x7D, 0x00, 0xF7, 0x10, 0xC1,
-0x53, 0xF0, 0x0E, 0xC0, 0x3D, 0x00, 0xBB, 0x04, 0xDC, 0x0B, 0x7A, 0x8F, 0xC1,
-0x3F, 0x08, 0xFF, 0x28, 0xFC, 0x07, 0x72, 0x2F, 0xC0, 0x3F, 0x00, 0xEF, 0x00,
-0x4C, 0x03, 0xF0, 0x07, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xDF, 0x03, 0x5C, 0x4F, 0x30, 0x3D, 0xC9,
-0x04, 0x10, 0x5F, 0x40, 0x4C, 0x37, 0x30, 0x2D, 0xC0, 0x56, 0x40, 0xDB, 0x01,
-0x4C, 0x03, 0xB3, 0x2D, 0xC2, 0x14, 0x00, 0x8F, 0x00, 0x4C, 0x00, 0xF0, 0x0D,
-0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x80,
-0x39, 0x01, 0xCD, 0x14, 0x02, 0x13, 0xB0, 0x4C, 0x4A, 0x08, 0x00, 0xCC, 0x00,
-0x84, 0x13, 0xB0, 0x4E, 0x41, 0x1B, 0x00, 0xE1, 0x00, 0x84, 0x0B, 0xD0, 0x0F,
-0x40, 0x18, 0x00, 0xAD, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0xC0, 0x4E, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x02, 0xED, 0x01,
-0x94, 0x17, 0x10, 0x9E, 0x40, 0x79, 0x00, 0xED, 0x01, 0x04, 0x17, 0x10, 0x1E,
-0x40, 0x61, 0x88, 0xE1, 0x21, 0x96, 0x17, 0xD0, 0x9E, 0x44, 0x78, 0x00, 0xBD,
-0x01, 0x85, 0x05, 0xD0, 0x1C, 0x40, 0x11, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x90, 0x0C,
-0x40, 0x71, 0x01, 0xCD, 0x88, 0x04, 0x03, 0x90, 0x0C, 0x40, 0x33, 0x00, 0xC1,
-0x3A, 0x14, 0x03, 0xD0, 0x0C, 0x42, 0xF0, 0x04, 0x8D, 0x03, 0x44, 0x0B, 0xD0,
-0x8D, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
-0x20, 0x15, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x30, 0x05, 0x40, 0xDD, 0x01, 0x7F,
-0xC1, 0x4D, 0x01, 0x31, 0x05, 0xC0, 0x9E, 0x04, 0x71, 0x03, 0x5C, 0x01, 0xB0,
-0x05, 0xC4, 0xDC, 0x01, 0x7F, 0x59, 0xCC, 0x09, 0xF0, 0xB7, 0x40, 0x5D, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x00, 0x1F,
-0x00, 0x64, 0x00, 0xF0, 0x21, 0x50, 0x06, 0x20, 0x0B, 0x80, 0x7C, 0x00, 0xF0,
-0x01, 0xC0, 0x86, 0x04, 0x17, 0x00, 0x68, 0x08, 0xA2, 0x01, 0xD0, 0x07, 0x08,
-0x1F, 0x22, 0x7C, 0x48, 0xF0, 0x01, 0xC0, 0x4A, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x9F, 0x00, 0x6C, 0x82, 0xF0,
-0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x6C, 0x22, 0xF0, 0x49, 0xC4, 0x27, 0x00,
-0x9F, 0x00, 0x7C, 0x0A, 0xD0, 0x29, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x50, 0x02,
-0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x20, 0x2C, 0x00, 0x9D, 0x40, 0x74, 0x02, 0xD0, 0xA9, 0x40, 0x27, 0x10,
-0x94, 0x00, 0x44, 0x02, 0xD0, 0x29, 0x04, 0xA7, 0x01, 0x9D, 0x11, 0xF4, 0x4E,
-0xC2, 0x29, 0x50, 0x24, 0x00, 0x8D, 0x04, 0x44, 0x2A, 0x50, 0x09, 0x40, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02,
-0x9D, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x90, 0x40, 0x64, 0x02,
-0xD0, 0x09, 0x01, 0x26, 0x82, 0x9D, 0x01, 0x74, 0x02, 0xC0, 0x28, 0x40, 0x24,
-0x00, 0x9C, 0x80, 0x54, 0x02, 0x12, 0x29, 0x46, 0x60, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x21, 0x00, 0x8D, 0x48, 0x34, 0x02,
-0xD1, 0x08, 0x40, 0x23, 0x62, 0x81, 0x08, 0x04, 0x0A, 0xD0, 0x08, 0x40, 0x23,
-0x21, 0x8D, 0x20, 0x34, 0x02, 0xD0, 0xC8, 0x40, 0x20, 0x01, 0x8D, 0x80, 0x10,
-0x53, 0x52, 0x48, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1D, 0xB8, 0x46, 0x00, 0x1F, 0x36, 0x7C, 0x50, 0xF0, 0x45, 0xC1, 0x87,
-0x00, 0x12, 0x16, 0x6C, 0x50, 0xF1, 0x41, 0x81, 0x46, 0x00, 0x0F, 0x0A, 0x7C,
-0x04, 0xF0, 0x31, 0xC4, 0xC4, 0x02, 0x1F, 0x00, 0x58, 0x10, 0x30, 0x41, 0xE2,
-0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0xA7,
-0x00, 0x9F, 0x24, 0x78, 0x82, 0xF0, 0x09, 0xCA, 0x2F, 0x01, 0xFC, 0x04, 0x7C,
-0x06, 0xF1, 0x09, 0x80, 0x2F, 0x02, 0xBF, 0x01, 0x7C, 0x0A, 0xB0, 0xC9, 0xC0,
-0x6F, 0x02, 0xBF, 0x00, 0xEC, 0x52, 0xF0, 0x4B, 0xD1, 0x77, 0x60, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x6F, 0x00, 0x9F, 0x16, 0xFC,
-0x02, 0x34, 0x4B, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0xFC, 0x22, 0xF0, 0x0B, 0xC0,
-0x2C, 0x60, 0xB3, 0x00, 0xFC, 0x46, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x80,
-0xCD, 0x82, 0xF0, 0x0B, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x00, 0x87, 0x00, 0x1D, 0x02, 0x74, 0x00, 0x10, 0x01, 0x40,
-0x04, 0x01, 0x0D, 0x8A, 0x74, 0x04, 0xD0, 0xA1, 0x40, 0x04, 0x08, 0x11, 0x00,
-0x74, 0x08, 0xD0, 0x41, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0xD1, 0x01,
-0x42, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0,
-0xA1, 0x00, 0x8D, 0x00, 0x34, 0x0A, 0x11, 0x2C, 0x40, 0x20, 0x24, 0x89, 0x40,
-0x34, 0x1A, 0xD0, 0x08, 0x40, 0x20, 0x10, 0x85, 0x00, 0x34, 0x02, 0xD8, 0x08,
-0x61, 0x20, 0x40, 0x95, 0x00, 0x14, 0x06, 0xD0, 0x08, 0x40, 0x4B, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x9D, 0x00,
-0x70, 0x02, 0x12, 0x09, 0x40, 0xA4, 0x0A, 0x9D, 0x20, 0x74, 0x02, 0xD0, 0x09,
-0x10, 0x24, 0x10, 0x95, 0x20, 0x74, 0x82, 0xD0, 0x08, 0x4C, 0x24, 0x04, 0x95,
-0x08, 0x54, 0xA3, 0xD0, 0x09, 0x40, 0x63, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0x2A, 0x25, 0x20, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09,
-0xD0, 0x64, 0x00, 0x9F, 0x02, 0xFC, 0x02, 0xF0, 0x09, 0xC4, 0xA4, 0x04, 0x97,
-0x00, 0x7C, 0x02, 0xF2, 0x09, 0x50, 0x64, 0x02, 0x87, 0x00, 0x5C, 0x02, 0xF0,
-0x09, 0xC0, 0x17, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-0x00, 0x25, 0x00, 0x9F, 0x00, 0x7E, 0x02, 0xF0, 0x08, 0xC0, 0x67, 0x20, 0x9F,
-0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC3, 0x27, 0x02, 0x9B, 0x10, 0x7C, 0x82, 0xF0,
-0x09, 0xC0, 0x67, 0x00, 0x9A, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x5B, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x17,
-0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC8, 0x07, 0x00, 0x13, 0x02, 0x6C, 0x20, 0xF0,
-0x81, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x34, 0x01, 0xC0, 0x87, 0x00,
-0x13, 0x04, 0x7C, 0x04, 0x30, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x04, 0x51, 0x00, 0x2C, 0x01, 0xD0,
-0xA7, 0x48, 0x17, 0x08, 0x51, 0x00, 0x44, 0x01, 0xD0, 0x26, 0x40, 0x5B, 0x20,
-0x7C, 0x83, 0xC4, 0x01, 0x11, 0x07, 0x41, 0x17, 0x00, 0x70, 0x00, 0xF4, 0x01,
-0x10, 0x07, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x80, 0x32, 0x00, 0xC5, 0x00, 0x14, 0x27, 0x9A, 0x0C, 0x44, 0x33, 0x00,
-0xC0, 0x00, 0x24, 0x07, 0xD0, 0x2C, 0x40, 0x63, 0x20, 0xCD, 0x00, 0x00, 0x02,
-0x90, 0x5C, 0x40, 0x37, 0x00, 0x81, 0x03, 0x30, 0x03, 0x94, 0x1C, 0x40, 0x43,
-0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x79, 0x00,
-0xE1, 0x01, 0xA5, 0x03, 0xD0, 0x06, 0x40, 0x7B, 0x02, 0xE1, 0x49, 0x84, 0x02,
-0xD0, 0x06, 0x40, 0xBB, 0x80, 0x6D, 0x03, 0x84, 0x46, 0x92, 0x06, 0x40, 0x33,
-0x00, 0xE1, 0x02, 0xB4, 0x07, 0x90, 0x26, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x00, 0xF7, 0x09, 0x9C, 0x06,
-0xB0, 0x1E, 0xC0, 0x7F, 0x45, 0xE2, 0x15, 0xAC, 0x07, 0xF0, 0x1A, 0xC0, 0x6B,
-0x20, 0xBF, 0x01, 0x8C, 0x06, 0xA0, 0x1A, 0xC0, 0x7B, 0x05, 0xA3, 0x01, 0xFC,
-0x07, 0xB0, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0xB8, 0x31, 0x00, 0xDF, 0x0C, 0x5C, 0x02, 0xF1, 0x01, 0xC0, 0xB7,
-0x01, 0xDF, 0x86, 0x7C, 0x22, 0xF0, 0x09, 0xE0, 0x26, 0x00, 0x1F, 0x00, 0x3C,
-0x02, 0x70, 0x09, 0xC0, 0x37, 0x01, 0xDF, 0x80, 0x7C, 0x02, 0x72, 0x05, 0xC0,
-0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D,
-0x00, 0xFF, 0x01, 0xDE, 0x27, 0x70, 0x9B, 0xC0, 0x7F, 0x00, 0xFF, 0x21, 0xDC,
-0x27, 0xF0, 0x1F, 0xC0, 0x6F, 0x00, 0x7B, 0x09, 0xCC, 0x07, 0x30, 0x1F, 0xC0,
-0x7C, 0x26, 0xBF, 0x81, 0xFC, 0x27, 0x31, 0x9F, 0xC0, 0x18, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x39, 0x00, 0xED, 0x00, 0x84,
-0x02, 0xC0, 0x22, 0x42, 0x3B, 0x00, 0xE9, 0x00, 0x80, 0x02, 0xD0, 0x22, 0x40,
-0x3B, 0x00, 0x19, 0x01, 0x94, 0x0A, 0x50, 0x06, 0x40, 0x79, 0x0A, 0xED, 0x00,
-0xB4, 0x33, 0x30, 0x22, 0x40, 0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x88, 0x00, 0x39, 0x00, 0xED, 0x00, 0x94, 0x82, 0x50, 0x02, 0x00,
-0x3B, 0x00, 0xED, 0x08, 0x94, 0x03, 0xD1, 0x0A, 0x40, 0x2B, 0x00, 0x39, 0x10,
-0x24, 0x03, 0xD0, 0x04, 0x40, 0x38, 0x00, 0xAD, 0x00, 0xB4, 0x09, 0x12, 0x0E,
-0x60, 0x61, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20,
-0x21, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD0, 0x00, 0x40, 0xF3, 0x00, 0xCD, 0x02,
-0x04, 0x02, 0xD0, 0x08, 0x48, 0x73, 0x84, 0x09, 0x01, 0x34, 0x03, 0xD0, 0x04,
-0x64, 0x31, 0x82, 0xCD, 0x00, 0x34, 0x04, 0x11, 0x00, 0x40, 0x09, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x10, 0xFF, 0x00,
-0x54, 0x03, 0x70, 0x09, 0xC0, 0x3F, 0x03, 0xFF, 0x01, 0x5C, 0x03, 0xF0, 0x09,
-0xC8, 0xA7, 0x01, 0x9B, 0x01, 0x64, 0x02, 0xB0, 0x0D, 0xCC, 0xFC, 0x12, 0x9D,
-0x0A, 0x7C, 0x90, 0x33, 0x19, 0xC2, 0x75, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0D, 0x00, 0x37, 0x20, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x29,
-0xC0, 0x37, 0x08, 0xDB, 0x18, 0x7E, 0x02, 0xF2, 0x01, 0x40, 0x37, 0x00, 0x1E,
-0x00, 0x5C, 0x0A, 0x38, 0x05, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x08, 0x74,
-0x81, 0x50, 0x16, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
-0x08, 0x3F, 0x10, 0xDF, 0x00, 0xFC, 0x0B, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xDF,
-0x00, 0xFC, 0x07, 0xF1, 0x0A, 0xC0, 0x2C, 0x40, 0x32, 0x01, 0xFC, 0x02, 0xF2,
-0x1A, 0x80, 0x3C, 0x00, 0xB3, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x07, 0x26,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD,
-0x00, 0x64, 0x07, 0xD0, 0x19, 0x42, 0x33, 0x00, 0xD1, 0x80, 0x74, 0x07, 0xD0,
-0x39, 0x40, 0x00, 0x00, 0x11, 0x07, 0x74, 0x00, 0xD0, 0x19, 0xC0, 0x37, 0x00,
-0x9B, 0x18, 0x64, 0x0C, 0xD0, 0x31, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD8,
-0x19, 0x40, 0x37, 0x00, 0xD9, 0x00, 0x74, 0x13, 0xD0, 0x11, 0x40, 0xA6, 0x00,
-0x35, 0x08, 0x74, 0x03, 0xC8, 0x49, 0x46, 0x39, 0x00, 0x91, 0x00, 0x60, 0x04,
-0xD0, 0x19, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x02, 0xD8, 0x08, 0x40, 0x37, 0x00,
-0xC1, 0x00, 0x34, 0x82, 0xD0, 0x00, 0x40, 0x30, 0x80, 0x05, 0x00, 0x34, 0x02,
-0xD0, 0x00, 0x40, 0x32, 0x01, 0xC9, 0xA0, 0x24, 0x00, 0xD0, 0x00, 0x40, 0x43,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0x36, 0x00,
-0xFF, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0x74, 0x02,
-0xD1, 0x01, 0xC0, 0x24, 0x00, 0x17, 0x04, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x3D,
-0x05, 0x13, 0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC2, 0x07, 0x64, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xEC, 0x02,
-0xF0, 0x03, 0xCC, 0x3F, 0x00, 0xFB, 0x00, 0xF8, 0x02, 0xF2, 0x03, 0x88, 0x1F,
-0x00, 0x1B, 0x16, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x37, 0x00, 0x7F, 0x00, 0xFC,
-0x00, 0xF0, 0x03, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0xAA, 0x7B, 0x12, 0xEF, 0x09, 0xEC, 0x07, 0xB0, 0x9E, 0xC0, 0x7A,
-0x00, 0xF7, 0x09, 0xEC, 0x07, 0xF0, 0x3F, 0xC0, 0x7B, 0x00, 0xF7, 0x29, 0xCC,
-0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xFC, 0xA7, 0xB0, 0x1F, 0xC0,
-0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x07,
-0x00, 0x1D, 0x44, 0x44, 0x04, 0x32, 0x01, 0x40, 0x44, 0x20, 0x11, 0x04, 0x4C,
-0x10, 0x10, 0x01, 0xC0, 0x44, 0x00, 0x11, 0x00, 0x44, 0x10, 0xD0, 0x01, 0x40,
-0x44, 0x10, 0x11, 0x20, 0x74, 0x00, 0x10, 0x11, 0xC0, 0x0E, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x33, 0x11, 0xDD, 0x00, 0x24,
-0x03, 0x91, 0x4D, 0x42, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x43, 0xD0, 0x4C, 0x40,
-0x32, 0x00, 0xC5, 0x44, 0x14, 0x43, 0xD0, 0x0C, 0x62, 0x32, 0x00, 0xC1, 0x80,
-0x34, 0x13, 0x90, 0x0D, 0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0xA0, 0x05, 0x00, 0x1D, 0x00, 0x54, 0x00, 0x90, 0x01, 0x40,
-0x05, 0x08, 0x01, 0x00, 0x34, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x05, 0x00,
-0x54, 0x00, 0xDA, 0x01, 0x44, 0x04, 0x40, 0x11, 0x00, 0x34, 0x00, 0x11, 0x01,
-0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
-0x37, 0x08, 0xDF, 0x80, 0x6C, 0x83, 0xB0, 0x0D, 0xC0, 0x37, 0x00, 0xD6, 0x00,
-0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD7, 0x00, 0x5C, 0x03, 0xE0, 0x0D,
-0xC0, 0x32, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xB1, 0x0C, 0xC0, 0x21, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00,
-0xEC, 0x00, 0x70, 0x03, 0xC8, 0x0E, 0x20, 0x3E, 0x00, 0xCC, 0x00, 0xF0, 0x03,
-0xC0, 0x0C, 0x08, 0x3B, 0x00, 0xEC, 0x00, 0xF2, 0x03, 0xC0, 0x0E, 0x00, 0x3F,
-0x00, 0xE4, 0x00, 0xF0, 0x03, 0xC0, 0x1E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0A, 0x00, 0x35, 0x20, 0xD7, 0xC8, 0x5C, 0x83, 0xC0, 0x0D,
-0xC0, 0x35, 0x01, 0xD7, 0x00, 0x5C, 0x03, 0xF0, 0x4D, 0xC0, 0x36, 0x00, 0xD7,
-0x00, 0x7C, 0x13, 0x30, 0x4D, 0xC4, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xD0, 0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
-0xA0, 0xC4, 0x00, 0x01, 0x83, 0x04, 0x04, 0x10, 0xE0, 0x40, 0x80, 0x00, 0x11,
-0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x48, 0xB0,
-0x50, 0x40, 0xC7, 0x00, 0x11, 0x00, 0x70, 0x24, 0xD1, 0x01, 0x40, 0x4D, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0xB0, 0x04, 0xC5,
-0x53, 0x14, 0x03, 0x50, 0x0C, 0x42, 0x31, 0x00, 0xC5, 0x00, 0x14, 0x03, 0xD0,
-0x0D, 0x00, 0x32, 0x00, 0xC5, 0x00, 0x34, 0x0F, 0x92, 0x3C, 0x44, 0xB2, 0x09,
-0xC5, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x0F, 0x08, 0x4C, 0x06, 0x31, 0x01, 0xC4, 0x04, 0x11,
-0x13, 0x40, 0x48, 0x08, 0x25, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x40, 0x4B, 0x00,
-0x21, 0x01, 0xF4, 0x04, 0xD2, 0x92, 0x40, 0x4B, 0x0C, 0x21, 0x01, 0xB4, 0x14,
-0xD0, 0x92, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x1C, 0x63, 0x72, 0x0C, 0xC0, 0x31, 0x02,
-0xD5, 0x00, 0x1C, 0x13, 0xF0, 0x4C, 0xC0, 0x32, 0x01, 0xC7, 0x28, 0x3C, 0x23,
-0xB0, 0x8C, 0xC0, 0x32, 0x00, 0xC6, 0x00, 0x3C, 0x63, 0xF2, 0x8C, 0xC0, 0x4A,
-0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x0D, 0x00,
-0x3F, 0x00, 0xBC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x0A, 0x3B, 0x08, 0xFC, 0x00,
-0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x08, 0xBC, 0xA0, 0xA0, 0x81, 0xC0, 0x0B,
-0x10, 0x1F, 0x00, 0xFC, 0x30, 0xF0, 0x90, 0xC0, 0x09, 0x60, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xD3, 0x00, 0x7E, 0x03,
-0x70, 0x0D, 0x80, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x30,
-0x00, 0xDA, 0x00, 0x5C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00, 0xD3, 0x00, 0x7C,
-0x03, 0x34, 0x0D, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0x80, 0x0D, 0x08, 0x20, 0x00, 0xB2, 0x00, 0xD1, 0x02, 0x40, 0x0B,
-0x00, 0x2D, 0x00, 0xB4, 0x00, 0x50, 0x02, 0xC0, 0x09, 0x00, 0x21, 0xA0, 0xB4,
-0x00, 0xD0, 0x02, 0xC4, 0x0A, 0x00, 0x2B, 0x80, 0xB4, 0x00, 0x10, 0x02, 0xC0,
-0x4E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x79,
-0x20, 0xE9, 0x01, 0x94, 0x87, 0xD0, 0x1E, 0x60, 0x7B, 0x00, 0xED, 0x01, 0xF4,
-0x07, 0xD0, 0x1F, 0x40, 0x7B, 0x00, 0xE9, 0x01, 0xB4, 0x07, 0xD0, 0x1F, 0x40,
-0x7E, 0x00, 0xE9, 0x21, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x02, 0x00, 0x09, 0x00, 0x34,
-0x00, 0xD2, 0x01, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x74, 0x00, 0xD0, 0x00, 0x40,
-0x01, 0x80, 0x0D, 0x00, 0x34, 0x80, 0xD0, 0x00, 0x40, 0x02, 0x00, 0x09, 0x00,
-0x36, 0x00, 0x10, 0x00, 0x40, 0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x17, 0xA0, 0x11, 0x00, 0x5B, 0x00, 0x78, 0x01, 0x70, 0x05, 0xE0,
-0x17, 0x00, 0x5F, 0x00, 0x7E, 0x01, 0xB1, 0x04, 0xC0, 0x16, 0x00, 0x5B, 0x20,
-0x5C, 0x01, 0xF0, 0x05, 0xC4, 0x14, 0x00, 0x5B, 0x20, 0x7C, 0x01, 0x30, 0x05,
-0xC0, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88,
-0x8F, 0x40, 0x37, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xE0, 0x0F, 0x00, 0x3F, 0x00,
-0xFA, 0x00, 0x70, 0x23, 0xC0, 0x0F, 0x00, 0x33, 0x00, 0xF4, 0x08, 0xF0, 0x23,
-0xC0, 0x8F, 0x00, 0x3F, 0x40, 0xF4, 0x08, 0xF0, 0x03, 0xC0, 0x4B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x01, 0x97, 0x00,
-0x7C, 0x16, 0x50, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0xA0, 0x7C, 0x02, 0x33, 0x09,
-0xC2, 0x25, 0x20, 0x93, 0x40, 0x74, 0x02, 0x02, 0x09, 0x54, 0xA4, 0x00, 0x97,
-0x00, 0x7C, 0x06, 0x32, 0x29, 0xC2, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00, 0x91, 0x05, 0x34, 0x86, 0x10, 0x39,
-0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x10, 0xA0, 0x04, 0x91,
-0x00, 0x34, 0x06, 0xB2, 0x28, 0x40, 0xE0, 0x08, 0x95, 0x00, 0x30, 0x06, 0x51,
-0x08, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA0, 0x24, 0x00, 0xB5, 0x04, 0xF4, 0x02, 0x50, 0x6B, 0x40, 0x2D, 0x00, 0xBD,
-0x80, 0xD4, 0x82, 0x18, 0x0B, 0x41, 0x2C, 0xC0, 0xB1, 0x00, 0xD4, 0x12, 0x10,
-0x2B, 0x40, 0x2D, 0x90, 0xB0, 0x80, 0xF4, 0x22, 0x12, 0x0B, 0x42, 0x60, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x3D, 0x00, 0xA1,
-0x00, 0xF4, 0x02, 0x50, 0x0A, 0x40, 0x28, 0x20, 0xAC, 0x28, 0xB4, 0x22, 0x50,
-0x0A, 0x40, 0x28, 0x00, 0xA1, 0xC8, 0xF4, 0x03, 0xD0, 0x0A, 0x40, 0x2D, 0x00,
-0xA4, 0x00, 0xF4, 0x23, 0x50, 0x0E, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0x38, 0x06, 0x00, 0x17, 0x80, 0x7C, 0x00, 0x70,
-0x01, 0xC0, 0x07, 0x00, 0x1C, 0x02, 0x7C, 0x08, 0x30, 0x01, 0xC0, 0x05, 0x00,
-0x13, 0x02, 0x5C, 0x00, 0x32, 0xA1, 0xC0, 0x15, 0x00, 0x17, 0x0A, 0x38, 0x08,
-0x30, 0x03, 0xC8, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1D, 0xB0, 0x25, 0x05, 0x9F, 0x34, 0x7C, 0x02, 0xB0, 0x49, 0xC1, 0x27, 0x00,
-0x9F, 0x04, 0x2C, 0x12, 0xF0, 0x48, 0xC9, 0x27, 0x00, 0x9F, 0x04, 0x7C, 0x52,
-0xB0, 0x19, 0xC0, 0x26, 0x00, 0x9F, 0x01, 0x7C, 0x12, 0xF0, 0x08, 0xC0, 0x77,
-0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x80, 0x2F, 0x00,
-0xBF, 0x08, 0xDC, 0x02, 0xF8, 0x0B, 0xC2, 0x2F, 0x00, 0x8F, 0x02, 0x7C, 0x02,
-0x34, 0x0B, 0xC0, 0x2C, 0x00, 0x93, 0x00, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0x2C,
-0x40, 0x83, 0x00, 0xCC, 0x02, 0xB0, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x47, 0x01, 0x1D, 0x25, 0x44, 0x00,
-0xD1, 0x41, 0x41, 0x07, 0x00, 0x1D, 0x04, 0x74, 0x80, 0x10, 0x01, 0x42, 0x05,
-0x08, 0x11, 0x00, 0x74, 0x00, 0xB0, 0x01, 0x42, 0x04, 0x00, 0x11, 0x40, 0x44,
-0x00, 0x11, 0x01, 0x40, 0x61, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x00, 0x31, 0x15, 0x8D, 0x44, 0x10, 0x02, 0xD8, 0x0C, 0x40, 0x23,
-0x00, 0x8D, 0x04, 0x34, 0x42, 0x10, 0x09, 0x40, 0x20, 0x00, 0x81, 0x14, 0x34,
-0x02, 0x10, 0x08, 0x50, 0x20, 0x80, 0x81, 0x20, 0x15, 0x02, 0xD0, 0x09, 0x40,
-0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2A, 0x25,
-0x00, 0x9D, 0x00, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74,
-0x02, 0x11, 0x09, 0x40, 0x25, 0x20, 0x91, 0x00, 0x74, 0x02, 0x90, 0x08, 0x60,
-0x24, 0x00, 0x91, 0x00, 0x54, 0x02, 0xD0, 0x09, 0x40, 0x61, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x22, 0x25, 0x10, 0x9F, 0x00, 0x5C,
-0x02, 0xD0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0,
-0x20, 0x08, 0x93, 0x80, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x20, 0x00, 0x93, 0x00,
-0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9F, 0x00,
-0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x27, 0x04, 0x9F, 0x00, 0x6C, 0x42, 0x30, 0x09,
-0x40, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
-0x05, 0x00, 0x17, 0x00, 0x4C, 0x00, 0xF0, 0x41, 0xC4, 0x07, 0x01, 0x17, 0x00,
-0x4C, 0x00, 0x70, 0x01, 0xC3, 0x07, 0x00, 0x1F, 0x00, 0x5C, 0x40, 0xB0, 0x01,
-0xC0, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC1, 0x51, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x02, 0x7D, 0xD8,
-0x44, 0x01, 0x70, 0x27, 0x40, 0x9F, 0x00, 0x51, 0x20, 0x6C, 0x01, 0xD0, 0x76,
-0x42, 0xDF, 0x00, 0x5D, 0x40, 0xEC, 0x0D, 0x11, 0x27, 0x40, 0x1C, 0x00, 0x59,
-0x00, 0xD4, 0x01, 0x14, 0x06, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x00, 0xD5, 0x40, 0x04, 0x26, 0xD0, 0x0C,
-0x40, 0xA3, 0x00, 0xC5, 0x00, 0x44, 0x03, 0x58, 0x0C, 0x48, 0xF3, 0x03, 0xCD,
-0x00, 0x46, 0x07, 0x90, 0x2C, 0x40, 0x32, 0x00, 0xDD, 0x00, 0x40, 0x0F, 0x00,
-0x3C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x80, 0x38, 0x20, 0xED, 0x40, 0x85, 0x03, 0x58, 0x0E, 0x68, 0xEF, 0x00, 0xF5,
-0x09, 0xA4, 0x23, 0xD0, 0x06, 0x40, 0x3B, 0x00, 0xFD, 0x45, 0xA4, 0x0B, 0x10,
-0x02, 0x41, 0x2A, 0x04, 0xF9, 0x04, 0x96, 0x0B, 0x12, 0x0E, 0x45, 0x10, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x59, 0x00, 0x77,
-0x01, 0x8C, 0x07, 0xF1, 0x1E, 0x40, 0x6B, 0x00, 0xE7, 0x15, 0x8C, 0x07, 0x70,
-0x16, 0x80, 0x7B, 0x00, 0xEF, 0x01, 0xDC, 0x05, 0xB0, 0x1E, 0xD0, 0x5A, 0x08,
-0xEF, 0x07, 0xCC, 0x06, 0x30, 0x1E, 0xC0, 0x51, 0x60, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0x5F, 0x40, 0x7C, 0x83, 0xF0,
-0x0D, 0xC0, 0x23, 0x00, 0xDB, 0x06, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x37, 0x00,
-0xCF, 0x08, 0x7E, 0x83, 0xF0, 0x60, 0xD5, 0x15, 0x20, 0xDB, 0x06, 0x7C, 0x02,
-0xD0, 0x0C, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x06, 0x20, 0x7D, 0x0A, 0xFF, 0x01, 0xDC, 0xA7, 0xF0, 0x1F, 0xC0, 0x7F, 0x00,
-0xE7, 0x01, 0x8C, 0x0F, 0xB0, 0x13, 0xC8, 0x7B, 0x00, 0xF3, 0x03, 0xCC, 0x07,
-0x30, 0x1B, 0xD0, 0x78, 0xA2, 0xFB, 0x03, 0xCC, 0x07, 0xF0, 0x1A, 0xC0, 0x18,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00,
-0xEC, 0x18, 0xB4, 0x83, 0xD0, 0x0E, 0x42, 0x3B, 0x28, 0xE1, 0x10, 0x94, 0x03,
-0x50, 0x22, 0x44, 0x3B, 0x06, 0xE5, 0x00, 0xD4, 0x03, 0x50, 0x43, 0x40, 0x28,
-0x02, 0xE1, 0x04, 0x84, 0x13, 0x71, 0x4A, 0x48, 0x54, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x02, 0x39, 0x10, 0xED, 0x00, 0x94, 0x03,
-0xC0, 0x06, 0x40, 0x3B, 0x04, 0xF5, 0x00, 0xE4, 0x43, 0x10, 0x02, 0x40, 0x3F,
-0x00, 0xFD, 0x00, 0xD4, 0x01, 0x50, 0x0A, 0x61, 0x18, 0x84, 0xE1, 0xB0, 0x84,
-0x42, 0xD2, 0x0A, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x28, 0x65, 0x00, 0x8D, 0x00, 0x36, 0x13, 0xD0, 0x39, 0x40, 0xF3,
-0x00, 0xC5, 0x03, 0x34, 0x0B, 0x50, 0xA0, 0x40, 0xF3, 0x00, 0xDD, 0x02, 0x14,
-0x2A, 0x50, 0x38, 0x62, 0x40, 0x04, 0xC9, 0x53, 0x05, 0x04, 0x50, 0x28, 0x40,
-0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0xE5,
-0x10, 0x9F, 0x01, 0x5C, 0x43, 0xD0, 0xA1, 0xC4, 0x07, 0x02, 0xF7, 0x01, 0xEC,
-0x07, 0x30, 0xB1, 0xC8, 0xB7, 0x00, 0xFF, 0x01, 0x5E, 0x0E, 0x10, 0x99, 0xC4,
-0x44, 0x00, 0xEB, 0x00, 0x0C, 0x81, 0xF3, 0x3D, 0xC6, 0x54, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x06, 0x9F, 0x04, 0x7C,
-0x03, 0xF0, 0x81, 0xC0, 0xA7, 0x10, 0xDA, 0x00, 0x5C, 0x43, 0x78, 0x21, 0x80,
-0x37, 0x0C, 0xD7, 0xB8, 0x78, 0x00, 0xF0, 0x09, 0xC0, 0xA7, 0x40, 0xD7, 0x00,
-0x7C, 0x81, 0x70, 0xAD, 0xC1, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x81, 0x08, 0x0F, 0x00, 0x3B, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0,
-0x0E, 0x00, 0xF3, 0x10, 0xCC, 0x03, 0xF0, 0x03, 0x40, 0x3E, 0x00, 0xF3, 0x00,
-0xFC, 0x40, 0xF0, 0x0B, 0xC0, 0x0C, 0x00, 0xF7, 0x00, 0xD4, 0x54, 0x30, 0x0F,
-0xC0, 0x04, 0x28, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
-0xC6, 0x00, 0x11, 0x03, 0x74, 0x03, 0xD0, 0x19, 0x40, 0x60, 0x01, 0xDB, 0x00,
-0x54, 0x03, 0xD0, 0x11, 0x40, 0xD3, 0x00, 0xDB, 0x00, 0x44, 0x0C, 0xD0, 0x18,
-0xC0, 0x83, 0x20, 0xD1, 0x00, 0x54, 0x89, 0x51, 0x4C, 0x50, 0x84, 0x04, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xC6, 0x00, 0x19, 0x03,
-0x74, 0x13, 0xD8, 0x31, 0x40, 0x66, 0x00, 0xC1, 0x80, 0x44, 0x03, 0xD0, 0x11,
-0x40, 0x66, 0x04, 0xD1, 0x00, 0x44, 0xC6, 0x90, 0x1B, 0x40, 0x04, 0x06, 0xF5,
-0x00, 0x40, 0x09, 0x50, 0x45, 0x48, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x81, 0x00, 0x34, 0x83, 0xD0, 0x00,
-0x40, 0x24, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x00, 0x40, 0x27, 0x00, 0xC9,
-0x00, 0x04, 0x82, 0xC2, 0x19, 0x40, 0x02, 0xA0, 0xD1, 0x40, 0x54, 0x02, 0x50,
-0x04, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x18, 0x06, 0x10, 0x1B, 0x00, 0x7C, 0x03, 0xDA, 0x01, 0xC0, 0x26, 0x00, 0xF3,
-0x00, 0xC4, 0x03, 0xF0, 0x01, 0xC4, 0x26, 0x00, 0xF3, 0x00, 0x5D, 0x00, 0xF0,
-0x0B, 0xC0, 0x04, 0x00, 0xE7, 0x00, 0x5C, 0x00, 0x30, 0x09, 0xD0, 0x04, 0x60,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB8, 0x2F, 0x00, 0xBF,
-0x00, 0xFC, 0x03, 0xD0, 0x0B, 0xC0, 0x2B, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0xE0,
-0x03, 0xC0, 0x2F, 0x00, 0xEF, 0x00, 0xFC, 0x02, 0xF1, 0x0B, 0xC2, 0x0F, 0x00,
-0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC4, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x6F, 0x00, 0xBF, 0x10, 0xFC, 0x05, 0x30,
-0x16, 0xC8, 0x3F, 0x10, 0xFF, 0x14, 0xFC, 0x00, 0x30, 0x17, 0xC0, 0x2C, 0x00,
-0x63, 0x01, 0xFC, 0x0F, 0x30, 0x4B, 0xC0, 0x5F, 0x00, 0xF3, 0x01, 0xBC, 0x02,
-0xB0, 0x1F, 0xC8, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x67, 0x00, 0xDD, 0x01, 0x74, 0x05, 0x00, 0x19, 0x40, 0xFF, 0x30,
-0xFD, 0x03, 0x74, 0x0D, 0x10, 0x1D, 0x42, 0xE4, 0x00, 0x95, 0x01, 0xF4, 0x13,
-0x12, 0x19, 0x40, 0x77, 0x00, 0xF1, 0x41, 0x74, 0x02, 0x50, 0x11, 0x40, 0x0F,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00,
-0x8D, 0x40, 0x74, 0x00, 0x00, 0x08, 0x40, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x08,
-0x14, 0x0D, 0x48, 0xB0, 0x10, 0x84, 0x00, 0x34, 0x13, 0x10, 0x8C, 0x40, 0x23,
-0x00, 0xC1, 0x00, 0x54, 0x02, 0x90, 0x0C, 0x40, 0x4F, 0x80, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, 0x35, 0x00, 0x9D, 0x00, 0x74, 0x10,
-0x18, 0x09, 0x40, 0x37, 0x20, 0xDD, 0x00, 0x76, 0x23, 0x10, 0x0D, 0x48, 0x30,
-0x00, 0x91, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x04, 0x23, 0x00, 0xD1, 0x40, 0x74,
-0x06, 0x50, 0x0D, 0x42, 0x0F, 0xA0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA0, 0x77, 0x00, 0x9F, 0x01, 0x3C, 0x09, 0x30, 0x0D, 0xC2, 0x37,
-0x00, 0xDF, 0x60, 0x5C, 0x13, 0x31, 0x08, 0xC8, 0x64, 0x02, 0xD3, 0x00, 0x7C,
-0x03, 0x34, 0x0D, 0xC0, 0xD7, 0x00, 0xD3, 0x00, 0x7C, 0x17, 0xB2, 0x6D, 0xC0,
-0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x3D,
-0x21, 0x9F, 0x04, 0xFC, 0x45, 0xF4, 0x0B, 0xC2, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
-0x03, 0xF0, 0x2B, 0xD0, 0x3F, 0x40, 0xFD, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x7F, 0x01, 0xFF, 0x80, 0xFC, 0x03, 0xF1, 0x23, 0xC0, 0x1F, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x01, 0x9F, 0x00, 0x5C,
-0x09, 0xB8, 0x0D, 0xC1, 0x34, 0x00, 0xDB, 0x50, 0x7C, 0x01, 0xB0, 0x0D, 0xC0,
-0x27, 0x80, 0x9E, 0x04, 0x0C, 0x03, 0xD0, 0x0D, 0xC4, 0xB7, 0x08, 0xDF, 0x40,
-0x7C, 0x13, 0x32, 0x0D, 0xC2, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x13, 0x80, 0x34, 0x00, 0x9D, 0x00, 0x44, 0x0D, 0xF0, 0x29, 0x40,
-0x3C, 0x00, 0xFD, 0x01, 0x34, 0x0B, 0x10, 0x0D, 0x48, 0x37, 0x80, 0x9F, 0x12,
-0x44, 0x2B, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x11, 0x34, 0x03, 0xB0, 0x1D,
-0x41, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20,
-0x30, 0x00, 0x8D, 0x00, 0x14, 0x0C, 0xD0, 0xB4, 0x50, 0x70, 0x01, 0xCD, 0x02,
-0x20, 0x10, 0x92, 0x00, 0x4C, 0x23, 0x00, 0x4D, 0x01, 0x24, 0x23, 0xD0, 0x08,
-0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x08, 0x1C, 0x0C, 0x40, 0x0F, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x78, 0x00, 0xED, 0x01,
-0x84, 0x44, 0x50, 0x1B, 0x40, 0x78, 0x00, 0xED, 0x01, 0x34, 0x06, 0x10, 0x1A,
-0x40, 0x7B, 0x00, 0xB5, 0x09, 0xA6, 0x97, 0xD0, 0x1A, 0x40, 0x6B, 0x00, 0xED,
-0x01, 0xF4, 0x86, 0x90, 0x12, 0x40, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x04, 0xCF, 0x08, 0x1C, 0x00, 0xDA, 0x08,
-0xC8, 0x30, 0x14, 0xCB, 0x10, 0x2C, 0x20, 0xB0, 0x48, 0xC0, 0x23, 0x02, 0x8D,
-0x00, 0x2C, 0x23, 0xF0, 0x8C, 0x40, 0xA3, 0x00, 0xCF, 0x8C, 0x3E, 0x00, 0x30,
-0x0C, 0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x38, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF,
-0x12, 0xF4, 0x23, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xDD, 0x37, 0xF0,
-0x0F, 0x00, 0x2F, 0x00, 0xDF, 0x29, 0x7E, 0x22, 0xF4, 0x0F, 0xC0, 0x0B, 0x60,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x33, 0x00, 0xD3,
-0x48, 0x7C, 0x00, 0x60, 0x0C, 0xC0, 0xB4, 0x04, 0xDF, 0x04, 0x5C, 0x00, 0xF0,
-0x09, 0xC0, 0x24, 0x00, 0xD7, 0x01, 0x6C, 0x27, 0x30, 0x0D, 0xC0, 0x27, 0x00,
-0xDF, 0x00, 0x7C, 0x00, 0x30, 0x00, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xE1, 0xC0, 0xB4, 0x00, 0xD0,
-0x0A, 0x44, 0x38, 0x00, 0xED, 0x04, 0xB4, 0x02, 0xD0, 0x0A, 0x40, 0x38, 0x00,
-0xED, 0x00, 0x04, 0x13, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xED, 0x04, 0xB4, 0x02,
-0x50, 0x02, 0x40, 0x4C, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x79, 0x10, 0xE1, 0x05, 0xB4, 0x44, 0xD8, 0x1F, 0x51, 0x78, 0x13,
-0xE9, 0x05, 0x94, 0x25, 0xD0, 0x3A, 0x40, 0xE8, 0x02, 0xAD, 0x01, 0xA4, 0x07,
-0x90, 0x1E, 0x40, 0x6B, 0x04, 0xED, 0x09, 0xF4, 0x0C, 0x10, 0x02, 0x40, 0x10,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00,
-0xC1, 0x01, 0x34, 0x16, 0xD0, 0x38, 0x40, 0x30, 0x10, 0xCD, 0x00, 0x34, 0x07,
-0xD0, 0x18, 0x41, 0x70, 0x00, 0x8D, 0x00, 0x04, 0x03, 0x90, 0x9C, 0x40, 0x63,
-0x00, 0xCD, 0x00, 0x34, 0x06, 0x50, 0x8C, 0x40, 0x58, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x15, 0x00, 0x43, 0x11, 0xFC, 0x05,
-0xF0, 0x36, 0xC0, 0x14, 0x20, 0x4F, 0x00, 0xDC, 0x15, 0xF1, 0x27, 0xD4, 0x14,
-0x00, 0x77, 0x1B, 0x6C, 0x01, 0xB5, 0x15, 0xC0, 0x1F, 0x00, 0x5F, 0x00, 0xBC,
-0x01, 0x34, 0x37, 0xC4, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x08, 0x05, 0x42, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC0, 0x07,
-0x20, 0x1F, 0x00, 0x70, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C,
-0x08, 0x71, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x22, 0x7C, 0x00, 0xF0, 0x01, 0xC1,
-0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25,
-0x00, 0x93, 0x00, 0x45, 0x06, 0x50, 0x19, 0xD1, 0x24, 0x40, 0x93, 0x08, 0x5C,
-0x42, 0xF0, 0x09, 0x40, 0x22, 0x40, 0x93, 0x02, 0x7C, 0x16, 0xF0, 0x29, 0xC0,
-0x27, 0x00, 0x93, 0x82, 0x7C, 0x06, 0x34, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x20, 0x00, 0xB1, 0x03, 0x44,
-0x02, 0xD0, 0x29, 0x40, 0x20, 0x13, 0x91, 0x40, 0xC4, 0x02, 0xD0, 0x09, 0x40,
-0x2C, 0x00, 0x91, 0x40, 0xF4, 0x0E, 0xD0, 0x09, 0x40, 0x22, 0x20, 0xB1, 0x83,
-0x74, 0x06, 0x10, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x08, 0x54, 0x1B, 0xD0, 0x69, 0x40,
-0x24, 0x00, 0x91, 0x50, 0x50, 0x1A, 0xD0, 0x08, 0x40, 0x27, 0x00, 0x91, 0x00,
-0x74, 0x0A, 0xD8, 0x09, 0x40, 0x27, 0x00, 0x91, 0x40, 0x74, 0x52, 0x10, 0x09,
-0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
-0x21, 0x00, 0x81, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x80, 0x00,
-0x04, 0x02, 0xD0, 0x28, 0x40, 0xA0, 0x00, 0x81, 0x00, 0x34, 0x0A, 0x80, 0x08,
-0x40, 0xA6, 0x00, 0x81, 0x00, 0x74, 0x02, 0x14, 0x08, 0x40, 0x43, 0x80, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x07, 0x00, 0x53, 0x01,
-0x5C, 0x00, 0x70, 0x01, 0xC0, 0x04, 0x05, 0x12, 0x14, 0x5C, 0x04, 0xF0, 0x00,
-0xC0, 0x47, 0x00, 0x13, 0x00, 0x7C, 0x04, 0xF0, 0x11, 0xC0, 0x07, 0x40, 0x53,
-0x81, 0x7C, 0x00, 0x34, 0x01, 0xC0, 0x77, 0xE0, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0xB8, 0x2F, 0x00, 0xBF, 0x02, 0xFC, 0x02, 0xF0, 0x0B,
-0xC0, 0x27, 0x08, 0x9F, 0x40, 0xFC, 0x0A, 0xF1, 0x1B, 0xC0, 0xEF, 0x00, 0xEF,
-0x00, 0x7C, 0x0E, 0xF0, 0x2B, 0x00, 0x6E, 0x20, 0x9F, 0x82, 0xBC, 0x5A, 0xE0,
-0x0B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xA0, 0x29, 0x00, 0xBF, 0x01, 0xCC, 0x02, 0x34, 0x0B, 0xD0, 0x2C, 0x40, 0xA3,
-0x00, 0xBC, 0x46, 0xB0, 0x09, 0x40, 0x67, 0x00, 0xBB, 0x00, 0xC4, 0x16, 0x24,
-0x5B, 0xC0, 0xA7, 0x10, 0xB3, 0x15, 0xCD, 0x42, 0xB0, 0x0B, 0xC0, 0x74, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x00, 0x1D,
-0x00, 0x44, 0x00, 0x10, 0x05, 0x40, 0x85, 0x02, 0x11, 0x40, 0x74, 0x08, 0x30,
-0x55, 0x41, 0xC3, 0x01, 0x11, 0x00, 0x54, 0x14, 0x10, 0x01, 0x40, 0x47, 0x08,
-0x11, 0x02, 0x44, 0x08, 0x11, 0x01, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x22, 0x21, 0x00, 0x8D, 0x02, 0x14, 0x02, 0x90,
-0x08, 0x68, 0x20, 0x00, 0x81, 0x02, 0x34, 0x02, 0x90, 0x08, 0x40, 0xA3, 0x04,
-0x99, 0x00, 0x04, 0x4A, 0x10, 0x28, 0x40, 0x23, 0x00, 0x81, 0x20, 0x04, 0x52,
-0x91, 0x09, 0x42, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x28, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x64, 0x24, 0x00,
-0x90, 0x00, 0x74, 0x06, 0x10, 0x89, 0x4C, 0x27, 0x00, 0x91, 0x00, 0x14, 0x02,
-0x10, 0x09, 0x40, 0x23, 0x40, 0x91, 0x00, 0x44, 0x02, 0x90, 0x19, 0x40, 0x60,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x65, 0x02,
-0x8F, 0x09, 0x5C, 0x12, 0xB0, 0x18, 0x40, 0x24, 0x00, 0x93, 0x00, 0x7C, 0x4A,
-0xB0, 0x3B, 0xC0, 0x6F, 0x00, 0x9B, 0x00, 0xCC, 0x02, 0x30, 0x19, 0xC0, 0xEF,
-0x01, 0x93, 0x80, 0x4C, 0x02, 0xB0, 0x49, 0xD0, 0x14, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x6D, 0x12,
-0xF0, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x23,
-0x01, 0x9F, 0x02, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x67, 0x01, 0x9F, 0x00, 0x7C,
-0x02, 0x71, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x08, 0x05, 0x10, 0x13, 0x08, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x05,
-0xC1, 0x13, 0x08, 0x1C, 0x10, 0x34, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C,
-0x00, 0x30, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0x31, 0x01, 0xC0,
-0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xDC,
-0x06, 0x71, 0x00, 0xB0, 0x1D, 0x50, 0x07, 0x42, 0x1B, 0x80, 0x71, 0x01, 0xC4,
-0x0D, 0x10, 0x05, 0x40, 0x17, 0x00, 0x71, 0x02, 0xF4, 0x61, 0xB0, 0x05, 0x40,
-0x17, 0x00, 0x6D, 0x00, 0xF4, 0x01, 0x11, 0x04, 0x40, 0x43, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xE2, 0x00, 0x81, 0x10, 0x34,
-0x1E, 0x18, 0x04, 0x40, 0x23, 0x10, 0x85, 0x51, 0x14, 0x0D, 0x10, 0x0C, 0x40,
-0x33, 0x00, 0xD9, 0x13, 0x34, 0x06, 0x14, 0x1C, 0x40, 0x33, 0x00, 0x8D, 0x10,
-0x74, 0x02, 0x10, 0x08, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x82, 0x7C, 0x00, 0xA1, 0x00, 0xF4, 0x03, 0x50, 0x06, 0x40,
-0x33, 0x00, 0xA5, 0x01, 0x84, 0x09, 0x11, 0x4E, 0x40, 0x3B, 0x03, 0xE1, 0x02,
-0xB4, 0x33, 0x90, 0x0E, 0x61, 0x3B, 0x09, 0xED, 0x00, 0xB4, 0x02, 0x10, 0x0E,
-0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18,
-0x68, 0x00, 0xA3, 0x01, 0xBC, 0x06, 0x30, 0x16, 0xC0, 0x6B, 0x00, 0xE5, 0x01,
-0x9C, 0x05, 0x30, 0x3E, 0xC0, 0x7B, 0x00, 0xEB, 0x01, 0xBC, 0x07, 0x30, 0x1E,
-0xC0, 0xFB, 0x00, 0xAF, 0x01, 0x3C, 0x01, 0x30, 0x1A, 0xC0, 0x53, 0x60, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x40, 0x9D, 0x00,
-0x3C, 0x02, 0xF0, 0x05, 0xC0, 0x27, 0x00, 0xDB, 0x00, 0x7C, 0x01, 0xF0, 0x0D,
-0xC0, 0x37, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x28, 0x6D, 0x00, 0xBB, 0x21, 0xFC, 0x06, 0xF0, 0x17,
-0xC0, 0x6F, 0x00, 0xB3, 0x01, 0xDE, 0x07, 0x31, 0x9E, 0xC8, 0x7C, 0x00, 0xAE,
-0x01, 0xEC, 0x07, 0xF8, 0x9F, 0xC0, 0x78, 0x00, 0xB3, 0x41, 0xCC, 0x06, 0x30,
-0x1B, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0x10, 0x29, 0x00, 0xAD, 0x08, 0xB4, 0x03, 0xD0, 0x06, 0x40, 0x3B, 0x08, 0xA1,
-0x00, 0x84, 0x13, 0xB0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x02, 0x84, 0x03, 0xD0,
-0x0E, 0xC0, 0x3A, 0x02, 0xA1, 0x00, 0x94, 0x02, 0xB0, 0x0E, 0x44, 0x54, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x29, 0x00, 0xAD,
-0x00, 0xB4, 0x02, 0xD0, 0x06, 0x40, 0x23, 0x00, 0xA1, 0x00, 0xD4, 0x01, 0x11,
-0x1F, 0x00, 0x78, 0x00, 0xED, 0x00, 0xA4, 0x03, 0xD0, 0x0E, 0x44, 0x7C, 0x00,
-0x81, 0x00, 0x84, 0x01, 0x50, 0x0B, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x21, 0x00, 0x8D, 0x01, 0x34, 0x41, 0xD0,
-0x04, 0x40, 0x03, 0x00, 0x41, 0x00, 0x04, 0x33, 0x90, 0x2C, 0x41, 0x30, 0x20,
-0xCD, 0x0C, 0x04, 0x01, 0xD0, 0x0C, 0x40, 0x32, 0x04, 0xC1, 0x00, 0x54, 0x03,
-0xD0, 0x3C, 0x40, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1D, 0xA8, 0x25, 0x10, 0xDF, 0x11, 0x7C, 0x8A, 0xF0, 0x8D, 0xC1, 0x27, 0x00,
-0x93, 0x00, 0x5C, 0x05, 0x31, 0x0D, 0xD0, 0x34, 0x01, 0x4F, 0x02, 0x6C, 0x01,
-0xF1, 0x0C, 0xC0, 0xB4, 0x40, 0x93, 0x00, 0x4C, 0xAA, 0x70, 0x29, 0xC0, 0x74,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x25, 0xC0, 0x37, 0x00, 0x8F, 0x00, 0x7E, 0x01,
-0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x09, 0xF0, 0x0D, 0xC0, 0x37,
-0x08, 0xDF, 0x00, 0x7C, 0x02, 0xB0, 0x89, 0xC0, 0x17, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x6F, 0x00, 0xAF, 0x00, 0xDC, 0x02,
-0x34, 0x1F, 0x00, 0x6F, 0x00, 0xDF, 0x00, 0xEC, 0x89, 0xF1, 0x0F, 0xC0, 0x3F,
-0x00, 0x7F, 0x00, 0xCC, 0x01, 0x70, 0x4D, 0xD0, 0x3C, 0x00, 0xBF, 0x00, 0xCD,
-0x00, 0x34, 0x0B, 0xC1, 0x07, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA1, 0x20, 0x36, 0x10, 0x9D, 0x03, 0x04, 0x02, 0x10, 0x89, 0x43, 0x37,
-0x00, 0xDD, 0x00, 0x44, 0x05, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x03, 0x44,
-0x19, 0x10, 0x0D, 0x42, 0x34, 0x00, 0xCD, 0x02, 0x44, 0x06, 0x10, 0x19, 0x40,
-0x27, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA6,
-0x01, 0xDD, 0x06, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x27, 0x01, 0x9D, 0x00, 0x60,
-0x03, 0xD0, 0x0D, 0x44, 0x37, 0x00, 0xDD, 0x01, 0x04, 0x85, 0x50, 0x0D, 0x40,
-0x34, 0x10, 0x9D, 0x50, 0x44, 0x06, 0x10, 0x49, 0x40, 0x07, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xCD, 0x00, 0x04,
-0x03, 0x10, 0x04, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40,
-0x33, 0x80, 0xDD, 0xA0, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x30, 0x00, 0x8D, 0xC0,
-0x44, 0x02, 0x10, 0x08, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x18, 0x26, 0x00, 0x5F, 0x00, 0x5C, 0x02, 0x30, 0x0D, 0xC0,
-0x27, 0x00, 0x9F, 0x00, 0x6C, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xDF, 0x00,
-0x4C, 0x01, 0x70, 0x09, 0x80, 0x3C, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x09,
-0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8,
-0x1F, 0x00, 0x7F, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x1F, 0x00, 0x7F, 0x00,
-0xBC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFD, 0x01, 0xD0, 0x0B,
-0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xBC, 0x02, 0xF0, 0x0A, 0xC4, 0x17, 0x62, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xB3, 0x0C,
-0xDC, 0x00, 0x30, 0x4F, 0xC0, 0x3C, 0x01, 0xF3, 0x18, 0xFC, 0x32, 0x70, 0x17,
-0xC0, 0x7F, 0x00, 0x5B, 0x01, 0x8C, 0x06, 0x32, 0x1A, 0xC2, 0x7E, 0x00, 0x3B,
-0x08, 0xCD, 0x00, 0xB0, 0x03, 0xC2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0x18, 0x37, 0x01, 0x91, 0x8E, 0x44, 0x27, 0x10, 0x3F,
-0x40, 0xBC, 0x40, 0xF5, 0x26, 0x74, 0x38, 0x10, 0x05, 0x44, 0x77, 0x00, 0x53,
-0x01, 0x54, 0x05, 0x52, 0x19, 0x40, 0x55, 0x00, 0x11, 0x06, 0x44, 0x82, 0x10,
-0x01, 0xC0, 0x0E, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
-0xA0, 0x33, 0x04, 0x81, 0x00, 0x54, 0x03, 0x10, 0x2C, 0x44, 0xB2, 0x05, 0xC1,
-0x00, 0x34, 0x02, 0x50, 0x44, 0x41, 0x31, 0x00, 0x4D, 0x00, 0x54, 0x03, 0x10,
-0x08, 0x40, 0x22, 0x00, 0x89, 0x02, 0x04, 0x21, 0xD0, 0x10, 0x42, 0x4F, 0x80,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x31, 0x00, 0x91,
-0x01, 0x44, 0x07, 0x10, 0x0D, 0x40, 0x36, 0x00, 0xD1, 0x00, 0x74, 0x84, 0x10,
-0x05, 0x41, 0x37, 0x01, 0x51, 0x01, 0x54, 0x09, 0x50, 0x1D, 0x00, 0x35, 0x00,
-0x11, 0x02, 0x44, 0x83, 0x51, 0x11, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x36, 0x00, 0x13, 0x07, 0x10, 0x17, 0x30,
-0x0D, 0xC0, 0x36, 0x08, 0xD3, 0x40, 0x7C, 0x44, 0x50, 0xB1, 0xE0, 0x35, 0x20,
-0x5B, 0x07, 0x5C, 0x0B, 0x30, 0x18, 0x80, 0x36, 0x00, 0x1B, 0x02, 0x4C, 0x28,
-0xF4, 0x19, 0xC0, 0x2B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x0F, 0x80, 0x3D, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF4, 0x0F, 0xC0, 0x39, 0x00,
-0xDF, 0x00, 0x7C, 0x40, 0xF0, 0x13, 0xC0, 0x7F, 0x00, 0x79, 0x10, 0xFC, 0x13,
-0xE0, 0x0F, 0xC0, 0x1F, 0x00, 0x5F, 0x02, 0xBC, 0x04, 0xB0, 0x02, 0xC0, 0x1E,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00,
-0x1F, 0x04, 0x4C, 0x03, 0x70, 0x0C, 0xE1, 0x35, 0x04, 0xD7, 0x08, 0x4C, 0x02,
-0x70, 0x25, 0xC0, 0x37, 0x00, 0x57, 0x02, 0x5C, 0x0B, 0xB0, 0x49, 0xC0, 0x34,
-0x00, 0x5B, 0x00, 0x4C, 0x49, 0x34, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x34, 0x00, 0x9D, 0x00, 0x44, 0x03,
-0x11, 0x1F, 0xC4, 0xFC, 0x04, 0xF1, 0x00, 0x44, 0x10, 0x10, 0x05, 0x40, 0x70,
-0x00, 0x4B, 0x41, 0x68, 0x2F, 0xB0, 0x2D, 0x40, 0xB0, 0x01, 0x51, 0x00, 0x44,
-0x89, 0x00, 0x19, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x20, 0x32, 0x00, 0x1D, 0x00, 0x34, 0x83, 0x50, 0x1C, 0x40, 0x73,
-0x80, 0xC1, 0x26, 0x64, 0x0E, 0x10, 0x00, 0x48, 0x31, 0x00, 0xC5, 0x03, 0x70,
-0x0F, 0x90, 0x00, 0x48, 0x31, 0x21, 0x59, 0x0F, 0x04, 0x24, 0x10, 0x08, 0x60,
-0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x7A,
-0x80, 0x6D, 0x51, 0x95, 0x47, 0x10, 0x9E, 0x41, 0x70, 0x80, 0xE1, 0x81, 0xA6,
-0x07, 0x14, 0x12, 0x00, 0x78, 0x00, 0x69, 0x05, 0xB4, 0x47, 0x99, 0xDA, 0x40,
-0x5D, 0x00, 0xA1, 0x49, 0x04, 0x26, 0x10, 0x32, 0x41, 0x37, 0x20, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x32, 0x00, 0xCF, 0x20, 0x1C,
-0x03, 0x50, 0x8C, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x2C, 0x13, 0x30, 0x41, 0xC0,
-0x33, 0x24, 0x47, 0x15, 0x3C, 0x03, 0xB0, 0x5C, 0xC8, 0x21, 0x08, 0x8B, 0x05,
-0x0D, 0x08, 0x30, 0x0C, 0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0xB8, 0x3D, 0x20, 0xFF, 0x00, 0xE8, 0x03, 0xF0, 0xAE, 0xC0,
-0x3F, 0x40, 0xFB, 0x00, 0xDD, 0x03, 0xF1, 0x03, 0xC0, 0x3B, 0x00, 0x45, 0x80,
-0xEC, 0x03, 0xF0, 0x0D, 0xC0, 0x3A, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF4, 0x8F,
-0xC0, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0,
-0x77, 0x20, 0x53, 0x20, 0x7E, 0x83, 0xF0, 0xCD, 0xC0, 0x34, 0x11, 0xDF, 0x44,
-0x5C, 0x01, 0xF0, 0x11, 0xC0, 0x32, 0x00, 0x1B, 0x00, 0x1C, 0x03, 0x70, 0x0D,
-0xC2, 0x36, 0x00, 0xDF, 0x00, 0x4D, 0x03, 0x30, 0x0D, 0xC2, 0x40, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x3D, 0x00, 0x61, 0x00,
-0xB4, 0x83, 0x14, 0x0E, 0x40, 0xB8, 0x05, 0xFD, 0x16, 0x84, 0x03, 0xD0, 0x02,
-0x40, 0x38, 0x80, 0x27, 0x40, 0x84, 0x03, 0x11, 0x0E, 0x40, 0x18, 0x00, 0xED,
-0x00, 0x85, 0x03, 0x10, 0x07, 0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0xE1, 0x01, 0xF6, 0x87, 0xD2, 0x4E,
-0x40, 0x7B, 0x00, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x33, 0x40, 0x7B, 0x00, 0x31,
-0x01, 0x94, 0x07, 0x58, 0x1F, 0x41, 0x7A, 0x00, 0xED, 0x01, 0x04, 0x07, 0x54,
-0x1E, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-0x20, 0x33, 0x00, 0xC1, 0x43, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xDD,
-0x00, 0x44, 0x1F, 0xD0, 0x48, 0x60, 0x21, 0x02, 0x05, 0x01, 0x06, 0x0F, 0x10,
-0x3C, 0x40, 0x72, 0x00, 0xCD, 0x19, 0x04, 0x23, 0x50, 0x2D, 0x40, 0x58, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x71,
-0x05, 0xFC, 0x49, 0xF0, 0x05, 0xC0, 0x16, 0x00, 0x5F, 0x00, 0xDC, 0x0D, 0xF0,
-0x17, 0xC0, 0x17, 0x00, 0x63, 0x02, 0x9C, 0x6D, 0x70, 0x27, 0xE0, 0x1E, 0x09,
-0x7F, 0x02, 0xCC, 0x25, 0x70, 0x87, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x40, 0x1F, 0x30, 0x7C, 0x10, 0x74,
-0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7E, 0x28, 0xF0, 0x01, 0xC0, 0x06, 0x08,
-0x17, 0x58, 0x7C, 0x00, 0xF0, 0x61, 0xC0, 0x85, 0x00, 0x1E, 0x82, 0x3C, 0x00,
-0x90, 0x21, 0xD0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x67, 0x01,
-0x9F, 0x01, 0x68, 0x06, 0x32, 0x09, 0xC2, 0x27, 0x00, 0x92, 0x20, 0x5C, 0x06,
-0x70, 0x19, 0xD0, 0x24, 0x00, 0x8A, 0x05, 0x44, 0x02, 0x70, 0x09, 0xC2, 0x40,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00,
-0x9D, 0x11, 0x34, 0x02, 0x10, 0x59, 0x40, 0xE7, 0x00, 0x9D, 0x8B, 0x44, 0x06,
-0x10, 0x09, 0x40, 0x23, 0x00, 0x91, 0x08, 0x44, 0x8A, 0x10, 0x88, 0x40, 0xE4,
-0x20, 0x9D, 0x07, 0x44, 0x0A, 0x50, 0x29, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x08, 0x74, 0x12,
-0x50, 0x89, 0x42, 0x27, 0x04, 0x9D, 0x00, 0x74, 0x52, 0x50, 0x09, 0x48, 0x27,
-0x40, 0x9D, 0x90, 0x54, 0xA2, 0x53, 0x0D, 0x61, 0x64, 0x00, 0x98, 0x00, 0x54,
-0x2A, 0x51, 0x39, 0x40, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x28, 0x20, 0x00, 0x8D, 0x14, 0x74, 0x52, 0x15, 0x48, 0x41, 0x23,
-0x25, 0xCD, 0x14, 0x14, 0x52, 0x50, 0x08, 0x40, 0x23, 0x00, 0x95, 0x00, 0x04,
-0x02, 0x11, 0x08, 0x60, 0x20, 0x00, 0x8D, 0x08, 0x14, 0x02, 0x50, 0x48, 0x51,
-0x50, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06,
-0x00, 0x1F, 0x04, 0x7C, 0x10, 0x70, 0x41, 0xC8, 0x07, 0x01, 0x1F, 0x04, 0x7C,
-0x10, 0x70, 0x01, 0xC8, 0x07, 0x08, 0x17, 0x00, 0x58, 0x01, 0x72, 0x01, 0xD0,
-0x14, 0x00, 0x0B, 0x16, 0x5C, 0x50, 0x70, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x25, 0x05, 0xBF, 0x34, 0xBC,
-0x02, 0xF6, 0x08, 0xC0, 0x27, 0x05, 0x9F, 0x14, 0xE4, 0x52, 0xB4, 0x4A, 0xC1,
-0x2F, 0x10, 0xAB, 0x00, 0xFC, 0x02, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xBF, 0x04,
-0xED, 0x52, 0xF0, 0x4B, 0xC1, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0xBF, 0x11, 0xBC, 0x02, 0xC4, 0x0B, 0xC0,
-0x6E, 0x01, 0xBF, 0x54, 0xFC, 0x32, 0xF0, 0x09, 0xC8, 0x29, 0x90, 0xB3, 0x00,
-0xAD, 0x02, 0xB0, 0x0B, 0xC0, 0x2C, 0x00, 0xB7, 0x00, 0xCC, 0x12, 0x36, 0x0F,
-0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18,
-0x47, 0x05, 0x1D, 0x87, 0x74, 0x00, 0x10, 0x81, 0x40, 0x07, 0x05, 0x1D, 0x04,
-0x7C, 0x30, 0xD0, 0x05, 0x40, 0x07, 0x80, 0x55, 0x40, 0x44, 0x00, 0x12, 0x05,
-0x54, 0x04, 0x00, 0x11, 0x00, 0x45, 0x28, 0x54, 0x01, 0x40, 0x73, 0x60, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0x21, 0x00, 0xCD, 0x10,
-0x74, 0x27, 0xC0, 0x0C, 0x40, 0xA3, 0x00, 0x8D, 0x14, 0x34, 0x13, 0xD2, 0x08,
-0x40, 0x27, 0x00, 0x81, 0x00, 0x24, 0x03, 0x90, 0x09, 0x40, 0x24, 0x00, 0x85,
-0x80, 0x04, 0x02, 0x18, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D, 0x02, 0x76, 0x02, 0x10, 0x09,
-0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xC2, 0x09, 0x48, 0x27, 0x01, 0x95,
-0x00, 0x44, 0x22, 0x10, 0x09, 0x44, 0xA4, 0x02, 0x91, 0x00, 0x44, 0x22, 0x50,
-0x09, 0x00, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0xA8, 0x27, 0x00, 0x9D, 0x01, 0x3C, 0x0A, 0xF0, 0x09, 0xC0, 0x26, 0x08, 0x9F,
-0x40, 0x7A, 0x42, 0xF0, 0xB9, 0xC0, 0x21, 0x80, 0x91, 0x00, 0x2C, 0x02, 0xB0,
-0x19, 0xC0, 0x64, 0x00, 0x97, 0x04, 0x4C, 0x02, 0x30, 0x49, 0xC0, 0x17, 0x28,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x20, 0x9F,
-0x04, 0x7C, 0x16, 0xF4, 0x09, 0xC0, 0x27, 0x0C, 0x9F, 0x20, 0x5E, 0x52, 0xF0,
-0x19, 0xC0, 0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x89, 0xC1, 0x27, 0x00,
-0x9F, 0x53, 0x7C, 0x02, 0xF0, 0x49, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x42, 0x7C, 0x00, 0x70,
-0x11, 0xCC, 0x07, 0x00, 0x1B, 0x00, 0x4C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x00,
-0x12, 0x30, 0x4C, 0x40, 0x70, 0x01, 0xC0, 0x85, 0x09, 0x0F, 0x8A, 0x5C, 0x00,
-0x34, 0x21, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0xA0, 0x14, 0x00, 0x7D, 0x0A, 0x74, 0x01, 0x10, 0x07, 0x40, 0x9F, 0x00,
-0x71, 0x80, 0xC4, 0x01, 0xD0, 0x05, 0xC0, 0x9F, 0x00, 0x61, 0x41, 0xC5, 0x09,
-0x10, 0x06, 0x42, 0x58, 0x08, 0x7D, 0x21, 0xC4, 0x09, 0x10, 0x07, 0x40, 0x50,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00,
-0xCD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x48, 0x73, 0x80, 0xC9, 0x11, 0x14, 0x03,
-0xD0, 0x0C, 0x40, 0xB3, 0x06, 0xC1, 0x88, 0x04, 0x03, 0x51, 0x2C, 0x40, 0x31,
-0x02, 0xCD, 0x01, 0x54, 0x43, 0x90, 0x2C, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x01, 0xED, 0x80, 0xF4, 0x03,
-0x14, 0x02, 0x40, 0xFB, 0x00, 0xE1, 0x03, 0x94, 0x03, 0xD0, 0x8E, 0x64, 0x2B,
-0x40, 0xF1, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x44, 0x18, 0x00, 0xAD, 0x00, 0xC4,
-0x03, 0x91, 0x1C, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x11, 0x10, 0x78, 0x00, 0xEF, 0x81, 0xB4, 0x07, 0x70, 0x12, 0xCA, 0x7F,
-0x00, 0x4B, 0x01, 0x9D, 0x05, 0xF2, 0x1E, 0xC8, 0x7B, 0x80, 0x62, 0x01, 0x8C,
-0x07, 0x70, 0x1E, 0xE8, 0x69, 0x20, 0xFF, 0x01, 0xDC, 0x85, 0xB0, 0x1E, 0xD0,
-0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0xB5,
-0x0A, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x6C,
-0x03, 0xF0, 0x0D, 0xC0, 0x25, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0x40,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x70, 0x09, 0xC2, 0x40, 0x00, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFD, 0x00, 0xFF, 0x01, 0xCC,
-0x87, 0xB0, 0x17, 0x80, 0x5F, 0x00, 0xFF, 0x41, 0xFC, 0x07, 0xF9, 0x9E, 0xC0,
-0x58, 0x00, 0x73, 0x81, 0x8C, 0x86, 0xB0, 0x9E, 0xC0, 0x7D, 0x08, 0xDF, 0x01,
-0xFC, 0x07, 0x34, 0x17, 0xC2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0x18, 0x39, 0x00, 0x7D, 0x08, 0x84, 0x23, 0x10, 0x82, 0x40,
-0x1B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x62, 0x18, 0x01, 0x6B, 0x04,
-0x84, 0x22, 0x10, 0x1C, 0xC0, 0x2A, 0x04, 0x8D, 0x0D, 0xB4, 0x29, 0xB4, 0x07,
-0x40, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x39, 0x00, 0xED, 0x00, 0xC4, 0x03, 0x90, 0x02, 0x40, 0x3B, 0x00, 0x6D, 0x00,
-0xB4, 0x01, 0xD0, 0x0F, 0x5A, 0x18, 0x20, 0x71, 0x00, 0xF4, 0x43, 0xD0, 0x4F,
-0x40, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0x90, 0x0E, 0x40, 0x00, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31, 0x80, 0x8D, 0x22,
-0x04, 0x0B, 0x19, 0x08, 0x40, 0x07, 0x00, 0x8D, 0x00, 0x34, 0x08, 0xD1, 0x2C,
-0x40, 0x50, 0x00, 0x49, 0x00, 0x34, 0x4A, 0x51, 0x3C, 0x40, 0xE3, 0x04, 0x0D,
-0x10, 0x34, 0x00, 0x90, 0x28, 0x51, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0xA8, 0x3D, 0x10, 0x1F, 0x01, 0x4C, 0x0B, 0xB0, 0x01,
-0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x1A, 0xF0, 0x2F, 0xC0, 0x30, 0x04, 0xC1,
-0x20, 0x7C, 0x80, 0xF0, 0x0C, 0xCC, 0xA3, 0x00, 0x5D, 0x20, 0x7C, 0x0A, 0x90,
-0x29, 0x48, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x00, 0x37, 0x28, 0x9F, 0x0C, 0x7D, 0x23, 0xF0, 0x01, 0xC0, 0x27, 0x00, 0x1F,
-0x02, 0x7C, 0x4A, 0xF0, 0x0D, 0xC0, 0x27, 0xC0, 0xD7, 0x50, 0x49, 0x0A, 0xA0,
-0xCD, 0x00, 0xA6, 0x00, 0x0F, 0x08, 0x78, 0x12, 0x74, 0x01, 0xC0, 0x07, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x10, 0x2F,
-0x00, 0xEC, 0x47, 0xB0, 0x02, 0xD0, 0x2C, 0x00, 0x33, 0x00, 0xBC, 0x80, 0xB0,
-0x0F, 0xC3, 0x3F, 0x00, 0x7F, 0xC0, 0xEC, 0x80, 0x71, 0x0B, 0xC0, 0x2E, 0x08,
-0x73, 0x00, 0x0D, 0x02, 0x14, 0x0A, 0xD0, 0x11, 0x22, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00, 0x9D, 0x25, 0x04, 0x27, 0x10,
-0x21, 0x40, 0x64, 0x00, 0x11, 0x05, 0x74, 0x16, 0x12, 0x0D, 0x40, 0x27, 0x10,
-0xD5, 0x01, 0x04, 0x24, 0x10, 0x19, 0x45, 0xE4, 0x01, 0x55, 0x0A, 0x44, 0x06,
-0x54, 0x71, 0x42, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0xA0, 0x34, 0x00, 0x1D, 0x81, 0x64, 0x03, 0x90, 0x05, 0x49, 0xC4, 0x80,
-0x91, 0x01, 0x76, 0x06, 0x90, 0x0D, 0x40, 0xB7, 0x00, 0x55, 0x01, 0x66, 0x8A,
-0x50, 0x1D, 0x60, 0x66, 0x80, 0x55, 0x02, 0x44, 0x06, 0x54, 0x11, 0x40, 0x04,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x08,
-0x0D, 0x00, 0x44, 0x03, 0x14, 0x00, 0x40, 0x00, 0x48, 0x81, 0x40, 0x36, 0x02,
-0x10, 0x0C, 0x40, 0x33, 0x00, 0x11, 0x08, 0x44, 0x02, 0x10, 0x4D, 0x60, 0x04,
-0xC0, 0x05, 0x06, 0x04, 0x00, 0x58, 0x00, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x3E, 0x00, 0x1F, 0x00, 0x6C, 0x83,
-0xB0, 0x01, 0xC0, 0x24, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xB0, 0x0D, 0xC8, 0x37,
-0x40, 0x1F, 0x02, 0x6C, 0x02, 0x70, 0xE9, 0xC3, 0x26, 0x80, 0x93, 0x16, 0x4C,
-0x02, 0x70, 0x09, 0xC2, 0x01, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x85, 0xA0, 0x3F, 0x20, 0xBF, 0x00, 0xBC, 0x03, 0xF0, 0x03, 0xC0, 0x2F,
-0x00, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x0F, 0xC0, 0x3F, 0x08, 0x2F, 0x00, 0xFC,
-0x02, 0xF0, 0x41, 0xC0, 0x2F, 0x00, 0x3F, 0x04, 0xFC, 0x00, 0xF0, 0x03, 0xC0,
-0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F,
-0x00, 0x63, 0x04, 0xCC, 0x32, 0x72, 0x1F, 0xC8, 0x2C, 0x03, 0x72, 0x01, 0xCC,
-0x05, 0x70, 0x0B, 0xC0, 0x3D, 0x00, 0xBB, 0x80, 0xEC, 0x04, 0xD0, 0x9B, 0xD0,
-0x5C, 0x4A, 0xF3, 0x01, 0xCC, 0x12, 0xF1, 0x17, 0xC0, 0x0C, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x7F, 0x00, 0x51, 0x03, 0x44,
-0xB2, 0x12, 0x1F, 0x40, 0x24, 0x13, 0xD1, 0x01, 0x44, 0x07, 0x10, 0x3D, 0x40,
-0xFC, 0x00, 0xB1, 0x03, 0x44, 0x80, 0xD0, 0x45, 0x40, 0x04, 0x01, 0xF1, 0x21,
-0x44, 0x26, 0xD0, 0x1D, 0x40, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x55, 0x02, 0x04, 0x12, 0x50, 0x0C, 0x40,
-0x21, 0x01, 0x91, 0x00, 0x16, 0x02, 0x50, 0x88, 0x40, 0x31, 0x02, 0x89, 0x08,
-0x24, 0x00, 0xD8, 0x08, 0x40, 0x30, 0x88, 0xC1, 0x00, 0x14, 0x82, 0xD2, 0x08,
-0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8,
-0x35, 0x00, 0xD5, 0x00, 0x44, 0x82, 0x50, 0x0D, 0x40, 0x25, 0x00, 0xD1, 0x00,
-0x10, 0x22, 0x00, 0x09, 0x40, 0x35, 0x80, 0x95, 0x04, 0x44, 0x06, 0xC0, 0x81,
-0x00, 0x34, 0x04, 0xD1, 0x40, 0x54, 0x12, 0xD0, 0x0C, 0x40, 0x0D, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x33, 0x40, 0xC7, 0x00,
-0x4C, 0x26, 0x71, 0x0D, 0xD0, 0x64, 0x00, 0x83, 0x80, 0x5C, 0x07, 0x70, 0x05,
-0xC0, 0x35, 0x00, 0x9B, 0x00, 0x6C, 0x4C, 0xF0, 0x09, 0xC8, 0x24, 0x00, 0xD3,
-0x00, 0x5C, 0x07, 0xF0, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x10, 0x7B, 0x09, 0xFC, 0x03, 0xB3, 0x0F,
-0xC0, 0x3E, 0x41, 0xBF, 0x00, 0xED, 0x83, 0xF0, 0x9F, 0x82, 0x36, 0x20, 0x9B,
-0x01, 0xFC, 0x00, 0xF0, 0x1F, 0xC0, 0x2F, 0x00, 0xFD, 0x80, 0xEC, 0x02, 0xF2,
-0x8F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x08, 0x35, 0x12, 0xDF, 0x0A, 0x4D, 0x03, 0xF0, 0x8C, 0xC4, 0x34, 0x00, 0x9F,
-0x00, 0x7C, 0x03, 0xF0, 0x00, 0xC0, 0x73, 0x00, 0x8B, 0x00, 0x5C, 0x08, 0xF0,
-0x09, 0xC0, 0xA7, 0x00, 0xCF, 0x00, 0x7C, 0x42, 0xF2, 0x09, 0xC2, 0x08, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA2, 0x34, 0x00, 0xDD,
-0x80, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x74, 0x00, 0x9D, 0x00, 0x74, 0x03, 0xD0,
-0x0B, 0x02, 0x3F, 0x00, 0x91, 0x01, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x67, 0x04,
-0xDD, 0x00, 0x74, 0x02, 0xD2, 0x0D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x0C, 0x4C, 0x00, 0x44, 0x03, 0xD0,
-0x0C, 0x51, 0x34, 0x02, 0x4D, 0x00, 0x30, 0x00, 0xD0, 0x08, 0x40, 0x32, 0x00,
-0x81, 0x00, 0x14, 0x00, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xCD, 0x20, 0x34, 0x2E,
-0xD0, 0x00, 0x50, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x04, 0x80, 0x78, 0x00, 0x6D, 0x41, 0x84, 0x46, 0xD0, 0x1E, 0x48, 0x68, 0x00,
-0xED, 0x01, 0xB4, 0x06, 0xD0, 0x1E, 0x42, 0x7B, 0x60, 0xA1, 0x21, 0x84, 0x84,
-0xD0, 0x5E, 0x41, 0x6B, 0x00, 0xEC, 0x81, 0xB4, 0x07, 0xD2, 0x1B, 0x40, 0x18,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00,
-0xCF, 0x00, 0x0C, 0x02, 0xF2, 0x0C, 0xC0, 0x20, 0x00, 0x8F, 0x00, 0x3C, 0x12,
-0xF0, 0x48, 0xC0, 0x33, 0x00, 0x83, 0x10, 0x1C, 0x80, 0xF8, 0x08, 0xE0, 0x33,
-0x00, 0xCF, 0x48, 0x3C, 0x03, 0xF0, 0x09, 0xC0, 0x48, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x7D, 0x00, 0xFF, 0x00, 0xFC, 0x42,
-0xF0, 0x1E, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F,
-0x00, 0xB7, 0x00, 0xEC, 0x22, 0xF2, 0x4B, 0xC0, 0x3F, 0x00, 0xFE, 0x01, 0xFC,
-0x43, 0xF0, 0x09, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x11, 0xA0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37,
-0x00, 0x9F, 0x00, 0x78, 0x02, 0xF0, 0x85, 0xC0, 0xF0, 0x22, 0xDB, 0x14, 0x74,
-0x00, 0xE0, 0x1C, 0xC0, 0x24, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0,
-0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0xB9,
-0x00, 0x6D, 0x04, 0xB4, 0x13, 0xD0, 0x4E, 0x40, 0x3B, 0x00, 0xAD, 0x00, 0xB6,
-0x02, 0xD0, 0x4E, 0x50, 0x38, 0x04, 0xA1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40,
-0x28, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x4B, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x89, 0xED, 0x09, 0xB4,
-0x07, 0xD0, 0x9E, 0x40, 0x79, 0x03, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x14, 0x62,
-0x78, 0x01, 0xE9, 0x11, 0xB4, 0x04, 0xD0, 0x1F, 0x40, 0x69, 0x88, 0xED, 0x0D,
-0xB4, 0x57, 0xD0, 0x1A, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0x8D, 0xA0, 0x34, 0x07, 0xD0, 0x0C, 0x40,
-0x73, 0x10, 0x8D, 0x0B, 0x34, 0x2A, 0xD0, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x01,
-0x34, 0x03, 0xD0, 0xDC, 0x40, 0x21, 0x23, 0xCD, 0x00, 0x34, 0x07, 0xD0, 0x08,
-0x41, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8,
-0x11, 0x00, 0x7F, 0x20, 0x7C, 0x11, 0xF0, 0x05, 0xC0, 0x17, 0x24, 0x7F, 0x02,
-0xFC, 0x0D, 0xF0, 0x07, 0xC0, 0x14, 0x00, 0x5B, 0x01, 0xFC, 0x31, 0xF0, 0x07,
-0xD0, 0x9D, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x27, 0xC0, 0x5F, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x01,
-0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x70, 0x40, 0xF0, 0x80,
-0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0x80, 0x06, 0x28, 0x1F,
-0x80, 0x78, 0x08, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x08, 0x67, 0x00, 0x93, 0x00, 0x7C, 0x26, 0xF0, 0x39,
-0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4D, 0x02, 0x32, 0x09, 0xC3, 0x64, 0x00, 0x8F,
-0x01, 0x4C, 0x02, 0xF1, 0x29, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4C, 0x06, 0x30,
-0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x20, 0x2E, 0x00, 0xB1, 0x03, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x6F, 0x00, 0x9D,
-0x00, 0x04, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x01, 0x44, 0x02, 0xD0,
-0x09, 0x40, 0x67, 0x08, 0xBD, 0x00, 0x84, 0x0E, 0x10, 0x08, 0x40, 0x04, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0xD1,
-0x08, 0x74, 0x02, 0xD0, 0x09, 0x41, 0x27, 0x00, 0x8D, 0x00, 0x44, 0x02, 0x10,
-0x09, 0x50, 0x24, 0x01, 0x9D, 0x04, 0x44, 0x02, 0xD0, 0x0D, 0x42, 0x27, 0x00,
-0x8D, 0x00, 0x44, 0x1A, 0x10, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x00, 0x34, 0x0A, 0xD0,
-0x08, 0x42, 0xA3, 0x08, 0x8D, 0x02, 0x44, 0x0A, 0x10, 0x68, 0x41, 0x20, 0x05,
-0x8D, 0x14, 0x05, 0x02, 0xD0, 0x28, 0x40, 0xA3, 0x08, 0x8D, 0x02, 0x05, 0x02,
-0x10, 0x29, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1D, 0xB0, 0x56, 0x40, 0x53, 0x01, 0x7C, 0x04, 0xF0, 0x11, 0xC0, 0x47, 0x00,
-0x1F, 0x00, 0x4C, 0x00, 0x34, 0x41, 0xC0, 0x04, 0x01, 0x1F, 0x04, 0x4C, 0x28,
-0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x01, 0x4C, 0x04, 0x34, 0x01, 0xD0, 0x74,
-0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00,
-0xBF, 0x02, 0xFC, 0x0E, 0xF0, 0x29, 0xC0, 0xEF, 0x00, 0xBF, 0x01, 0xFC, 0x06,
-0xF0, 0x1B, 0xC0, 0x27, 0x00, 0xBF, 0x80, 0xFC, 0x06, 0xF0, 0x1B, 0xC0, 0x6F,
-0x08, 0x9F, 0x23, 0xFC, 0x0A, 0xF0, 0x1B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x6F, 0x00, 0xFB, 0x11, 0xCD, 0x16,
-0xF0, 0x1B, 0xC0, 0x6F, 0x01, 0x93, 0x00, 0x6C, 0x0A, 0x20, 0x59, 0x80, 0x6D,
-0x01, 0xA3, 0x05, 0x0C, 0x02, 0xF0, 0x2B, 0xC8, 0x2B, 0x00, 0x9D, 0x85, 0xCC,
-0x06, 0x30, 0x29, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x1C, 0x08, 0x07, 0x00, 0x11, 0x42, 0x44, 0x14, 0xD0, 0x21, 0x40, 0xC7,
-0x03, 0x51, 0x15, 0x64, 0x04, 0x10, 0x30, 0x40, 0x04, 0x00, 0x11, 0x00, 0x54,
-0x00, 0xD0, 0x51, 0x40, 0x57, 0x00, 0x1D, 0x07, 0x44, 0x28, 0x10, 0x11, 0x40,
-0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xA3,
-0x00, 0x89, 0x00, 0x04, 0x4A, 0xD0, 0x28, 0x42, 0x23, 0x04, 0x81, 0x20, 0x24,
-0x02, 0x10, 0xC8, 0x61, 0xA3, 0x00, 0x81, 0x02, 0x04, 0x02, 0x50, 0x48, 0x60,
-0x33, 0x05, 0x8D, 0x12, 0x14, 0x02, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x91, 0x40, 0x44,
-0x02, 0xD0, 0x09, 0x42, 0x27, 0x60, 0x91, 0x08, 0x24, 0x02, 0x10, 0x09, 0x42,
-0x26, 0x00, 0x91, 0x04, 0x54, 0x0A, 0xD0, 0x89, 0x42, 0x27, 0x01, 0x9D, 0x00,
-0x54, 0x06, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0x9B, 0x0E, 0xCC, 0x22, 0xF0, 0x09, 0xC0,
-0x2F, 0x00, 0xB3, 0x03, 0xEC, 0x12, 0x30, 0x1B, 0xC0, 0x27, 0x00, 0x93, 0x00,
-0x4C, 0x06, 0xE0, 0x1B, 0xC0, 0xEF, 0x20, 0xBF, 0x00, 0x5D, 0x02, 0xF0, 0x6B,
-0xC0, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
-0x25, 0x00, 0x9F, 0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x21,
-0x7C, 0x12, 0xF4, 0x38, 0xD0, 0x21, 0x40, 0x9F, 0x00, 0x7C, 0x0A, 0xF2, 0x09,
-0xC0, 0x67, 0x08, 0x9F, 0x00, 0x2C, 0x82, 0x34, 0x39, 0xC0, 0x53, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x01, 0x0F, 0x00,
-0x4D, 0x80, 0x30, 0x81, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01,
-0xC0, 0x04, 0x10, 0x17, 0x00, 0x4C, 0x08, 0x72, 0x01, 0xD0, 0x04, 0x40, 0x03,
-0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x20, 0xDC, 0x20, 0x7D, 0x00, 0x44, 0x05, 0x10, 0x07,
-0x40, 0x17, 0x04, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0xC0, 0x16, 0x00, 0x41,
-0x11, 0x44, 0x01, 0x10, 0x15, 0x43, 0x14, 0x00, 0x51, 0x00, 0xF0, 0x01, 0xC0,
-0x05, 0x40, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0xA0, 0xE2, 0x00, 0x8D, 0x00, 0x04, 0x07, 0x10, 0x08, 0x42, 0x37, 0x00, 0xCD,
-0x00, 0x30, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0x85, 0x01, 0x05, 0x03, 0x50,
-0x0C, 0x40, 0x32, 0x00, 0xC1, 0x80, 0x34, 0x02, 0xC0, 0x0C, 0x40, 0x53, 0x00,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0xB8, 0x00, 0xAD,
-0x00, 0x04, 0x77, 0x14, 0x0E, 0x40, 0x2B, 0x82, 0xED, 0x04, 0xB4, 0x13, 0xD0,
-0x4E, 0x40, 0x2A, 0x00, 0xF5, 0x00, 0xC4, 0x07, 0x50, 0xDE, 0x40, 0x7E, 0x01,
-0xE1, 0x0C, 0xB4, 0x03, 0xD1, 0x4E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xAF, 0x01, 0x84, 0x06, 0x30,
-0x1A, 0xC0, 0x7B, 0x01, 0xEF, 0x03, 0xBC, 0x0F, 0xF0, 0x5E, 0xC0, 0x6A, 0x00,
-0xE7, 0x01, 0x8C, 0x07, 0x70, 0x1F, 0x80, 0xFA, 0x00, 0xE3, 0x01, 0xBC, 0x06,
-0xF0, 0x3E, 0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xB8, 0x35, 0x00, 0x8F, 0x00, 0x7C, 0x02, 0xC0, 0x0D, 0xC0, 0x27, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0xE0, 0x8D, 0xC4, 0x23, 0x00, 0xDB, 0x00, 0x7C, 0x63,
-0xB8, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43,
-0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00,
-0xB3, 0x01, 0xFC, 0x87, 0x30, 0x1B, 0x80, 0x7F, 0x02, 0xE3, 0x01, 0x8C, 0x07,
-0x30, 0x1F, 0x40, 0x7C, 0x01, 0xFF, 0x01, 0xEC, 0x07, 0x30, 0x1B, 0xC0, 0x78,
-0x28, 0xF3, 0x21, 0xFC, 0x06, 0x30, 0x1E, 0xC8, 0x08, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29, 0x40, 0xA1, 0x00, 0xF4, 0x03,
-0x14, 0x0A, 0x40, 0x2B, 0x48, 0xE1, 0x00, 0x84, 0x23, 0x10, 0x8E, 0x40, 0x29,
-0x00, 0xED, 0x00, 0xC4, 0x43, 0xB0, 0x0A, 0xC0, 0x3A, 0x02, 0xE1, 0x00, 0xB4,
-0x0B, 0x10, 0x8E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x21, 0x00, 0xA1, 0x10, 0xB4, 0x02, 0x10, 0x0A, 0x40, 0x3B,
-0x80, 0xF1, 0x01, 0xC4, 0x07, 0x10, 0x1F, 0x40, 0x28, 0x01, 0xCD, 0x00, 0xA4,
-0x03, 0x10, 0x0B, 0x41, 0x3D, 0x00, 0xE1, 0x01, 0xB4, 0x62, 0x14, 0x1F, 0x40,
-0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x13,
-0x00, 0x81, 0x01, 0x34, 0x86, 0x10, 0x0C, 0x40, 0x63, 0x00, 0xC1, 0x07, 0x04,
-0x0B, 0x18, 0x3C, 0x40, 0x21, 0x00, 0xCD, 0x00, 0x04, 0x17, 0x90, 0x3C, 0x43,
-0x67, 0x00, 0xC1, 0x00, 0x34, 0x07, 0x10, 0x1C, 0x40, 0x18, 0x20, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x25, 0x00, 0xD3, 0x03, 0x7C,
-0x13, 0x30, 0x09, 0xC2, 0x77, 0x04, 0xD3, 0x04, 0x45, 0x2B, 0x34, 0x6D, 0xC0,
-0x24, 0x00, 0xDF, 0x11, 0xEC, 0x03, 0x30, 0x3C, 0xC0, 0x65, 0x44, 0xD3, 0x20,
-0x3C, 0x02, 0x30, 0x6D, 0xD0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x2D, 0xC0,
-0x27, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDD, 0x40,
-0x7C, 0x83, 0xF2, 0x0D, 0xC0, 0x26, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x4D,
-0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
-0x2F, 0x00, 0xBF, 0x10, 0x8C, 0x06, 0x31, 0x0B, 0xD0, 0xB4, 0x00, 0xFF, 0x00,
-0xCC, 0x03, 0xF0, 0x0F, 0xC1, 0xEF, 0x00, 0xFF, 0x85, 0xCC, 0x03, 0x30, 0x4F,
-0xC0, 0xEC, 0x00, 0xF3, 0x00, 0x4C, 0x16, 0x30, 0x0F, 0xC0, 0x04, 0x20, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD, 0x03,
-0x44, 0x02, 0x11, 0x24, 0x40, 0x74, 0x00, 0xDD, 0x40, 0x44, 0x03, 0xD0, 0x0D,
-0x42, 0x67, 0x20, 0xCD, 0x01, 0x44, 0x03, 0x10, 0x19, 0x48, 0x74, 0x20, 0xD1,
-0x00, 0x44, 0x01, 0x00, 0x0D, 0x40, 0x84, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x00, 0xDD, 0x06, 0x44, 0xA3, 0x14, 0x09,
-0x41, 0x34, 0x00, 0xCD, 0x00, 0x64, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x10, 0xDD,
-0x00, 0x84, 0x03, 0x10, 0x09, 0x40, 0x24, 0x40, 0xC1, 0x00, 0x44, 0x02, 0x10,
-0x0C, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x00, 0x20, 0x00, 0xCD, 0x00, 0x14, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0xCD,
-0x00, 0x05, 0x03, 0xD0, 0x0C, 0x40, 0x23, 0x80, 0xDD, 0x40, 0x04, 0x03, 0x14,
-0x09, 0x50, 0x20, 0x00, 0xC1, 0x40, 0x04, 0x02, 0x16, 0x0C, 0x54, 0x40, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0x1F,
-0x00, 0x4C, 0x03, 0x30, 0x09, 0xCA, 0x24, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0xF0,
-0x0F, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0xCD, 0x03, 0x30, 0x09, 0xC0, 0x24, 0x00,
-0xF3, 0x00, 0x4D, 0x02, 0x30, 0x0F, 0xC0, 0x04, 0x40, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00, 0x7F, 0x00, 0xED, 0x02, 0xF0,
-0x07, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0, 0x2F, 0x00,
-0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x01,
-0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA0, 0x7F, 0x00, 0xF7, 0x0C, 0xCC, 0x1B, 0x70, 0x3A, 0xC0, 0xEC, 0x00,
-0xBB, 0x04, 0xFC, 0x03, 0x30, 0x1E, 0xC0, 0x3E, 0x00, 0xA7, 0x01, 0x8C, 0x06,
-0x30, 0x1B, 0xC0, 0x7E, 0x12, 0xBF, 0x04, 0xCC, 0x07, 0xF0, 0x03, 0xC4, 0x0E,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00,
-0xF1, 0x8E, 0xC4, 0x3B, 0x10, 0x49, 0x40, 0x24, 0x00, 0x91, 0x0E, 0xF4, 0x2F,
-0x50, 0x19, 0x40, 0xF4, 0x00, 0x5D, 0x01, 0x44, 0x50, 0x10, 0x19, 0x40, 0x34,
-0x00, 0xC9, 0x14, 0x44, 0x03, 0xD0, 0x19, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA2, 0x33, 0x20, 0xC5, 0x04, 0x04, 0x13,
-0x50, 0x49, 0x40, 0x30, 0x01, 0x09, 0x10, 0x14, 0x03, 0x12, 0x08, 0x60, 0x32,
-0x02, 0xCD, 0x80, 0x44, 0x10, 0x10, 0x08, 0x40, 0x33, 0x00, 0x8D, 0x0C, 0x04,
-0x03, 0xD0, 0x08, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1, 0x00, 0x46, 0x03, 0x10, 0x19, 0x41, 0x70,
-0x00, 0x11, 0x01, 0x74, 0x03, 0x10, 0x19, 0x40, 0x34, 0x00, 0xDD, 0x84, 0x46,
-0x84, 0x10, 0x09, 0x40, 0x35, 0x00, 0x99, 0x00, 0x44, 0x03, 0xD0, 0x19, 0x41,
-0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xA8, 0x36,
-0x08, 0xD7, 0x00, 0x48, 0x03, 0x70, 0x39, 0xC0, 0x44, 0x01, 0x9B, 0x05, 0x5C,
-0x83, 0x30, 0x19, 0xC0, 0x36, 0x80, 0xD7, 0x00, 0x4C, 0x4E, 0x31, 0x08, 0xC0,
-0x37, 0x02, 0x9F, 0x00, 0x4D, 0x07, 0xF0, 0x30, 0xC0, 0x03, 0x20, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x82, 0x3D, 0x10, 0xEF, 0x00, 0xFC,
-0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x80, 0xFC, 0x43, 0xF0, 0x0B, 0xC0,
-0x3F, 0xA4, 0xFF, 0x01, 0xFD, 0x03, 0xF0, 0x0F, 0xC2, 0x3E, 0x00, 0xEF, 0x02,
-0xFC, 0x8F, 0xF0, 0x03, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x21, 0xC0,
-0x35, 0x00, 0x97, 0x08, 0x0C, 0x03, 0x70, 0x01, 0xC0, 0x34, 0x02, 0xD7, 0x10,
-0x4C, 0x00, 0xB1, 0x0D, 0xC0, 0x37, 0x04, 0xD3, 0x18, 0x44, 0x03, 0xF0, 0x21,
-0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
-0x70, 0x00, 0xFD, 0x0F, 0xF4, 0x03, 0xD0, 0x0C, 0x60, 0x34, 0x00, 0x91, 0x03,
-0xC4, 0x4F, 0x30, 0xC0, 0xC0, 0x3C, 0x08, 0xC1, 0x11, 0x2C, 0x00, 0x10, 0x8D,
-0x40, 0xF4, 0x00, 0xD5, 0x00, 0x44, 0x0B, 0xD0, 0xB1, 0x40, 0x4C, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x72, 0x00, 0xCD, 0x03,
-0x74, 0x07, 0x50, 0x08, 0x44, 0x31, 0x00, 0x05, 0x12, 0x14, 0x0B, 0xD0, 0x18,
-0x40, 0xF0, 0x20, 0xC5, 0x00, 0x24, 0x02, 0xD2, 0x00, 0x06, 0xF3, 0x00, 0x89,
-0x01, 0x04, 0x37, 0xD0, 0x90, 0x40, 0x1D, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x82, 0x78, 0x04, 0xED, 0x81, 0xB4, 0x4F, 0xD0, 0x1B,
-0x48, 0x7D, 0x08, 0xE1, 0x09, 0x95, 0x07, 0x00, 0x9B, 0x40, 0x78, 0x00, 0x61,
-0x01, 0xE4, 0x04, 0x10, 0x9A, 0x40, 0x78, 0x06, 0xAD, 0x01, 0x84, 0x07, 0xD9,
-0x1A, 0x48, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
-0x10, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x70, 0x08, 0x40, 0x31, 0x00, 0x57,
-0x00, 0x1C, 0x03, 0xF0, 0x88, 0xC0, 0x30, 0x00, 0xC7, 0x00, 0x2C, 0x00, 0xB0,
-0x00, 0xC0, 0x37, 0x00, 0x8B, 0x0C, 0x0C, 0x03, 0xF0, 0x0C, 0xC0, 0x49, 0x48,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB0, 0x3D, 0x00, 0xFF,
-0x02, 0xFC, 0x4B, 0xF0, 0x8B, 0x80, 0x3A, 0x02, 0xFF, 0x00, 0xAC, 0x63, 0xF1,
-0x8B, 0xD0, 0x3B, 0x00, 0xFF, 0x48, 0xFC, 0x00, 0xF0, 0x0A, 0xC2, 0x3F, 0x00,
-0x97, 0x28, 0xFD, 0x03, 0xF0, 0x8E, 0xC0, 0x09, 0x60, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x0C, 0x7C, 0x0B, 0xF0,
-0x09, 0xC0, 0x34, 0x00, 0x57, 0x01, 0x4C, 0x1B, 0xF1, 0x09, 0xC0, 0x34, 0x12,
-0xCF, 0x00, 0x4C, 0x03, 0xB0, 0x01, 0xC0, 0x76, 0x90, 0xDB, 0x00, 0x7C, 0x83,
-0x30, 0x05, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x88, 0x39, 0x00, 0xED, 0x04, 0xB4, 0x13, 0xD0, 0x0F, 0x44, 0x38, 0x00,
-0xE1, 0x00, 0x84, 0x33, 0xD8, 0x0A, 0x42, 0x38, 0x00, 0xED, 0xA0, 0x84, 0x81,
-0x14, 0x0E, 0x44, 0x39, 0x00, 0xE5, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x40, 0x48,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x79, 0x00,
-0xED, 0x05, 0xB4, 0x07, 0xD0, 0x1A, 0x54, 0x7C, 0x00, 0x45, 0x01, 0x84, 0x17,
-0xC0, 0x13, 0x48, 0x78, 0x01, 0xEC, 0x01, 0xC5, 0x05, 0x12, 0x16, 0x40, 0x7D,
-0x80, 0xE1, 0xA1, 0xF4, 0x8F, 0x11, 0x1C, 0x60, 0x0C, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
-0xD8, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x03, 0x04, 0x03, 0xD0, 0x80, 0x40, 0x30,
-0x20, 0xCD, 0x05, 0x04, 0x15, 0x10, 0x0C, 0x40, 0x21, 0x00, 0xC5, 0x08, 0x74,
-0x06, 0x50, 0x2C, 0x41, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xD0, 0x47, 0xC0, 0x98,
-0x00, 0x77, 0x49, 0x4C, 0x01, 0xF0, 0xA7, 0xC8, 0x14, 0x00, 0x7F, 0x07, 0x8C,
-0x15, 0x30, 0x47, 0xC0, 0x55, 0x00, 0x5B, 0x21, 0x7C, 0x01, 0x10, 0x27, 0xD1,
-0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07,
-0x00, 0x1F, 0x82, 0x7C, 0x00, 0xF1, 0x01, 0xC1, 0x07, 0x01, 0x1F, 0xA8, 0x7D,
-0x08, 0xD0, 0x21, 0xD4, 0x87, 0x00, 0x1F, 0x40, 0x7C, 0x00, 0x70, 0x21, 0xC0,
-0x05, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x4B, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x01, 0x9F, 0x03, 0x3C,
-0x02, 0x30, 0x09, 0xC0, 0x24, 0x08, 0x97, 0x01, 0x7C, 0x12, 0xF2, 0x29, 0xC0,
-0x26, 0x00, 0x9F, 0x08, 0x5C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x8F, 0x09,
-0x4D, 0x02, 0x30, 0x48, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x03, 0x74, 0x0A, 0x10, 0x09, 0x40,
-0x24, 0x00, 0x91, 0x01, 0x74, 0x1A, 0xD0, 0x08, 0x41, 0xE4, 0x01, 0x8D, 0x60,
-0x44, 0x02, 0x12, 0x68, 0x40, 0x24, 0x03, 0x9D, 0x02, 0x44, 0x02, 0x30, 0x29,
-0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
-0x24, 0x00, 0x9D, 0x00, 0x74, 0x46, 0x50, 0x08, 0x42, 0x24, 0x00, 0x95, 0x08,
-0x74, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x02, 0x9D, 0x00, 0x54, 0x02, 0x52, 0x0D,
-0x40, 0x24, 0x00, 0x9D, 0x02, 0x44, 0x0A, 0x10, 0x09, 0x40, 0x60, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD, 0x14,
-0x34, 0x52, 0x54, 0x08, 0x40, 0x24, 0x0A, 0xC1, 0x94, 0x30, 0xD2, 0xD0, 0x09,
-0x40, 0x21, 0x00, 0x8D, 0x00, 0x44, 0x02, 0x19, 0x09, 0x70, 0x20, 0x10, 0x8D,
-0x08, 0x04, 0x02, 0x14, 0x4C, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1D, 0xB0, 0x07, 0x00, 0x1F, 0x04, 0x7C, 0x10, 0x70, 0x01,
-0xD0, 0x84, 0x00, 0x17, 0x04, 0x78, 0x10, 0xF0, 0x01, 0xC4, 0x07, 0x05, 0x1D,
-0x40, 0x5C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x16, 0x4C, 0x00, 0x30,
-0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
-0xB0, 0x27, 0x00, 0x9F, 0x14, 0x7C, 0x52, 0xB1, 0x4B, 0xC1, 0x2B, 0x01, 0xBF,
-0x94, 0x7C, 0x02, 0xF2, 0x0A, 0xC0, 0x26, 0x10, 0xFE, 0x00, 0xBC, 0x53, 0xF0,
-0x0A, 0xC0, 0x2B, 0x15, 0xBF, 0x04, 0xBC, 0x52, 0x70, 0x0B, 0xC0, 0x67, 0x60,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x00, 0xBF,
-0x01, 0xCC, 0x5E, 0xE0, 0x28, 0xC0, 0xA7, 0x00, 0xB7, 0x09, 0xEC, 0x12, 0x70,
-0x0A, 0xC0, 0x2F, 0x04, 0xAD, 0x00, 0x4C, 0x02, 0x30, 0x0A, 0xC0, 0xAE, 0x00,
-0xBB, 0x00, 0xCD, 0x02, 0xB0, 0x0B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x0F, 0x44, 0x08, 0xD0,
-0x01, 0x40, 0x07, 0x01, 0x11, 0x0B, 0x44, 0x00, 0x10, 0x01, 0x40, 0x87, 0x00,
-0x19, 0x00, 0x44, 0x10, 0x10, 0x01, 0x40, 0x04, 0x01, 0x11, 0x00, 0x44, 0x00,
-0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x10, 0xA0, 0x23, 0x00, 0x8D, 0x10, 0x04, 0x12, 0xD0, 0x48, 0x40, 0x67, 0x00,
-0x85, 0x04, 0x24, 0x0B, 0x50, 0x08, 0x40, 0x33, 0x00, 0x99, 0x00, 0x04, 0x42,
-0x10, 0x09, 0x40, 0x22, 0x01, 0x89, 0x00, 0x24, 0x02, 0x90, 0x08, 0x40, 0x43,
-0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00,
-0x9D, 0x60, 0x44, 0x02, 0xC8, 0x09, 0x41, 0x27, 0x02, 0x91, 0x00, 0x64, 0x02,
-0x10, 0x09, 0x44, 0x27, 0x00, 0x99, 0x00, 0x00, 0x02, 0x11, 0x09, 0x00, 0x64,
-0x00, 0x91, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02,
-0xC1, 0x39, 0xC8, 0x67, 0x00, 0x95, 0x51, 0x6C, 0x02, 0x70, 0x79, 0xC0, 0x27,
-0x00, 0x9B, 0x01, 0x4C, 0x0E, 0x30, 0x19, 0xC0, 0x26, 0x00, 0x9B, 0x00, 0x4C,
-0x06, 0xB0, 0x09, 0xC1, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x29, 0xC0, 0x67,
-0x00, 0x8F, 0x05, 0x1C, 0x02, 0xF0, 0x99, 0xC4, 0x27, 0x24, 0x9B, 0x03, 0x7D,
-0x12, 0xF4, 0x99, 0xC3, 0x27, 0x00, 0x9F, 0x13, 0x7C, 0xD6, 0xF0, 0x49, 0xC1,
-0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x04,
-0x00, 0x0F, 0x04, 0x7C, 0x00, 0xF4, 0x21, 0xC2, 0x04, 0x40, 0x13, 0x00, 0x6C,
-0x40, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x02, 0x5C, 0x08, 0x31, 0x01, 0xC0,
-0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x54, 0x04, 0x7D, 0x00, 0xF4,
-0x61, 0x10, 0x05, 0xC0, 0x12, 0x00, 0x71, 0x07, 0xC4, 0x09, 0xD0, 0x27, 0x40,
-0x1C, 0x00, 0x6D, 0x60, 0x44, 0x01, 0x12, 0x36, 0x41, 0x1C, 0x01, 0x7D, 0x47,
-0xC4, 0x85, 0x50, 0x27, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0xA0, 0x32, 0x80, 0xCD, 0x00, 0x34, 0x0F, 0x10, 0x0C, 0x40,
-0x30, 0x00, 0xC1, 0x07, 0x24, 0x09, 0xD1, 0xC4, 0x40, 0xB3, 0x00, 0x8D, 0x00,
-0x14, 0x03, 0x10, 0x00, 0x48, 0x35, 0x09, 0xDD, 0x03, 0x45, 0xAF, 0x10, 0xAC,
-0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x88,
-0x28, 0x00, 0x6D, 0x82, 0xB4, 0x07, 0x10, 0xDF, 0x40, 0x3A, 0x03, 0xE1, 0x00,
-0x84, 0x03, 0xD0, 0x13, 0x48, 0x39, 0x80, 0x7D, 0x80, 0xD4, 0x13, 0x1C, 0x02,
-0x40, 0x39, 0x10, 0xED, 0x20, 0xC4, 0x03, 0x41, 0x1C, 0x40, 0x10, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x01,
-0x3C, 0x05, 0x30, 0xDE, 0xC0, 0x7C, 0x00, 0x73, 0x01, 0xAC, 0x07, 0xF0, 0x1E,
-0xC0, 0x5B, 0x00, 0xAF, 0x01, 0x9C, 0x17, 0x30, 0x12, 0xD0, 0x79, 0x90, 0xBF,
-0x01, 0xCC, 0x07, 0x20, 0x1E, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA8, 0x25, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0x31, 0x0D,
-0xC8, 0xB7, 0x05, 0x5F, 0x20, 0x70, 0x03, 0xF1, 0x01, 0xC0, 0x16, 0x00, 0x5F,
-0x80, 0x2C, 0x6B, 0xF0, 0x01, 0xD0, 0x36, 0x00, 0x9F, 0x00, 0x7C, 0x01, 0xF0,
-0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xA0, 0x6F, 0x02, 0xF7, 0x09, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x78, 0x00, 0xFB,
-0x01, 0xFC, 0x07, 0xF0, 0x17, 0xC0, 0x7E, 0x00, 0xBB, 0x01, 0xCC, 0x17, 0xB0,
-0x97, 0xC0, 0x7C, 0x08, 0x7F, 0x01, 0xCC, 0x05, 0xF1, 0x1F, 0xC0, 0x0B, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29, 0x00, 0x6D,
-0x48, 0xB0, 0x03, 0xD0, 0x4E, 0xC0, 0x3B, 0x01, 0x61, 0x22, 0xB4, 0x8B, 0xD0,
-0x46, 0x40, 0xB8, 0x08, 0x71, 0x00, 0xFC, 0x13, 0x10, 0xC6, 0x40, 0x38, 0x00,
-0x6D, 0x48, 0x84, 0x00, 0xD0, 0x42, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x29, 0x20, 0xE5, 0x40, 0xB4, 0x03, 0xD0,
-0x0F, 0x40, 0x3C, 0x10, 0xE9, 0x08, 0xB4, 0x03, 0xD0, 0x07, 0x41, 0x1B, 0x02,
-0xB9, 0x08, 0xA4, 0x73, 0x92, 0x06, 0x41, 0x18, 0x00, 0x2D, 0x00, 0xA4, 0x61,
-0xD0, 0x0E, 0x60, 0x23, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x06, 0x28, 0x23, 0x00, 0x9D, 0x00, 0x34, 0x02, 0xD0, 0xEC, 0x60, 0xB2, 0x04,
-0x09, 0x01, 0x34, 0x03, 0xD0, 0x10, 0x40, 0x10, 0x00, 0x41, 0x23, 0x36, 0x0F,
-0x12, 0x34, 0x41, 0x20, 0x20, 0x0D, 0x09, 0x60, 0x04, 0xD0, 0x00, 0x40, 0x1B,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xA8, 0x25, 0x00,
-0x97, 0x00, 0x74, 0x02, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0x9B, 0x02, 0x7C, 0x03,
-0xF0, 0x05, 0x80, 0x37, 0x00, 0x4B, 0x05, 0xEC, 0x07, 0xB0, 0x34, 0xD0, 0x04,
-0x80, 0xDF, 0x01, 0x6D, 0x06, 0xD0, 0x0D, 0x48, 0x57, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x02,
-0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x97, 0x0E, 0x74, 0x0B, 0xE0, 0x01, 0xA0, 0x36,
-0x10, 0x5F, 0x02, 0x5C, 0x13, 0xF0, 0x05, 0xC0, 0x87, 0x0A, 0xDF, 0x02, 0x5C,
-0x02, 0xF0, 0x0D, 0xC8, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x81, 0x08, 0xAF, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x3E,
-0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF1, 0x07, 0xC8, 0x17, 0x20, 0x3B, 0x18, 0xCC,
-0x03, 0xB2, 0x07, 0xD0, 0x0E, 0x00, 0xBF, 0x01, 0xFC, 0x02, 0x30, 0x23, 0xC1,
-0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x26,
-0x20, 0x1D, 0x01, 0x44, 0x04, 0xD0, 0x0C, 0xC0, 0x36, 0x00, 0x1D, 0x01, 0x74,
-0x0F, 0xD0, 0x31, 0x42, 0xD7, 0x00, 0x5D, 0x52, 0x04, 0x03, 0x10, 0x35, 0x40,
-0x44, 0x04, 0x1D, 0x03, 0x74, 0x8C, 0x10, 0x21, 0x40, 0x87, 0x02, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x80, 0x9D, 0x31, 0x64,
-0x0C, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0x9D, 0x01, 0x74, 0x07, 0x50, 0x15, 0x41,
-0x77, 0x00, 0x5D, 0x00, 0x47, 0x03, 0x90, 0x1D, 0x41, 0x64, 0x00, 0x5D, 0x94,
-0x74, 0x46, 0x10, 0x2D, 0x48, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x0D, 0x00, 0x04, 0x02, 0xD0, 0x0D, 0x40,
-0x32, 0x00, 0x8D, 0x20, 0x34, 0x83, 0xD0, 0x00, 0x40, 0x23, 0x00, 0x4D, 0x00,
-0x46, 0x03, 0x10, 0x04, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x26, 0x82, 0x1C, 0x00,
-0x40, 0x43, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10,
-0x24, 0x00, 0x9F, 0x80, 0x6C, 0x00, 0xF1, 0x0F, 0xC0, 0x3E, 0x00, 0x9F, 0x00,
-0x7C, 0x03, 0x70, 0x05, 0xC4, 0x17, 0x00, 0x1B, 0x00, 0xCC, 0x03, 0xB4, 0x05,
-0xC0, 0x04, 0x00, 0x4F, 0x00, 0x7C, 0x02, 0x30, 0x01, 0xC4, 0x07, 0x40, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, 0x2F, 0x00, 0xBE, 0x00,
-0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x02,
-0xC0, 0x3F, 0x20, 0x7F, 0x40, 0xFC, 0x03, 0xF0, 0x06, 0xC0, 0x2F, 0x00, 0x3F,
-0x00, 0xFC, 0x00, 0xF2, 0x03, 0xE0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xBF, 0x01, 0xEC, 0x32, 0xF2, 0xC7,
-0xC8, 0x5F, 0x02, 0x33, 0xA1, 0xFC, 0x07, 0x30, 0x6B, 0xC8, 0x3F, 0x08, 0xB3,
-0x00, 0xEC, 0x04, 0x10, 0x1B, 0xC8, 0x1F, 0x03, 0xFD, 0x09, 0xCC, 0x82, 0x32,
-0x1F, 0xC6, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x08, 0x7F, 0x00, 0xDD, 0x81, 0x74, 0x32, 0xD2, 0xC5, 0x40, 0x07, 0x11, 0xD1,
-0x01, 0xF4, 0x07, 0x10, 0x69, 0x48, 0xFF, 0x00, 0x95, 0x03, 0x74, 0x04, 0x10,
-0x1D, 0x40, 0x97, 0x01, 0xED, 0x04, 0x44, 0x0E, 0x10, 0x1F, 0x40, 0x0F, 0x60,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0xCD,
-0x00, 0x24, 0x03, 0xD0, 0x44, 0x40, 0x37, 0x01, 0xC5, 0x01, 0x14, 0x83, 0x10,
-0x28, 0x40, 0x33, 0x0A, 0x01, 0x08, 0x74, 0x00, 0x10, 0x0C, 0x40, 0x93, 0x00,
-0xCD, 0x00, 0x14, 0x22, 0x1A, 0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x88, 0x35, 0x00, 0xDD, 0x01, 0x74, 0x82, 0xD0,
-0x65, 0x40, 0x27, 0x00, 0xD0, 0x01, 0x74, 0x03, 0x50, 0x0D, 0x42, 0x37, 0x08,
-0x95, 0x20, 0x74, 0x04, 0x10, 0x1D, 0x42, 0x37, 0x09, 0xDC, 0x00, 0x54, 0x13,
-0x10, 0x0D, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xA8, 0x37, 0x00, 0xDF, 0x05, 0x6C, 0x02, 0xF0, 0x05, 0xC0, 0xB3, 0x01,
-0xD7, 0x21, 0x3C, 0x03, 0x34, 0x1D, 0xC0, 0x37, 0x10, 0x93, 0x80, 0x28, 0x0C,
-0x32, 0x1D, 0xC1, 0x57, 0x00, 0xDF, 0x80, 0x5C, 0x86, 0x31, 0x0D, 0xC0, 0x0B,
-0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00,
-0xFE, 0x00, 0xFC, 0x23, 0xF1, 0x0F, 0xC0, 0xBF, 0x40, 0xFF, 0x00, 0xFC, 0x03,
-0xA0, 0x3B, 0xC0, 0x37, 0x04, 0xBF, 0x23, 0xF0, 0x00, 0xF0, 0x0F, 0xC1, 0x1F,
-0x00, 0xFF, 0x00, 0x2C, 0x02, 0xF0, 0x0F, 0xC4, 0x1F, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x07,
-0x70, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x80, 0x7C, 0x43, 0x34, 0x0D, 0xC0, 0x33,
-0x42, 0x13, 0x00, 0x4C, 0x00, 0xF0, 0x0D, 0xC0, 0xB7, 0x08, 0xC3, 0x00, 0x4C,
-0x43, 0x70, 0x0D, 0xC1, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x13, 0xA0, 0x34, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0xB4,
-0x08, 0xDA, 0x01, 0x74, 0x07, 0x00, 0x4D, 0x46, 0xBF, 0x00, 0xB1, 0x00, 0x44,
-0x48, 0xD0, 0x2D, 0x40, 0x77, 0x04, 0xD1, 0x00, 0x40, 0x0F, 0x10, 0x3D, 0x40,
-0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32,
-0x00, 0xC1, 0x00, 0x20, 0x02, 0x10, 0x9C, 0x40, 0x60, 0x26, 0xC5, 0x01, 0x24,
-0x27, 0x10, 0x08, 0x00, 0xF3, 0x00, 0x89, 0x01, 0x35, 0x44, 0xD0, 0x2C, 0x40,
-0x33, 0x00, 0xC5, 0x29, 0x04, 0x2F, 0x90, 0xBC, 0x42, 0x0F, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0xE1, 0x01, 0xB6,
-0x06, 0x10, 0x14, 0x58, 0x68, 0x10, 0xED, 0x51, 0x34, 0x07, 0x10, 0x1A, 0x42,
-0x7B, 0x10, 0x89, 0x01, 0x94, 0x04, 0xD0, 0x1E, 0x40, 0x5B, 0xC2, 0xE5, 0x03,
-0x84, 0x06, 0x90, 0x1E, 0x40, 0x77, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x00, 0x7E, 0x02, 0x70, 0x04, 0xC0,
-0x20, 0x82, 0xC7, 0x80, 0x2C, 0x13, 0x38, 0x0C, 0xE0, 0x33, 0x00, 0x0B, 0x90,
-0x1C, 0x30, 0xF0, 0x0C, 0xC0, 0xB7, 0xA0, 0xC7, 0x80, 0x0C, 0x03, 0xF0, 0x0C,
-0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8,
-0x79, 0xC0, 0xFF, 0x00, 0xF4, 0x02, 0xF8, 0x07, 0xC8, 0x2B, 0x08, 0xFB, 0x08,
-0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xB7, 0x10, 0xEC, 0xA0, 0xF0, 0x0F,
-0xC0, 0x3F, 0x00, 0xFB, 0x01, 0x7E, 0x23, 0x70, 0x1D, 0xC1, 0x0B, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00,
-0x7C, 0x83, 0xF0, 0x8D, 0x80, 0x27, 0x00, 0xDF, 0x40, 0x7E, 0x83, 0xF0, 0x89,
-0x40, 0x37, 0x03, 0x9F, 0x00, 0x6E, 0x00, 0xF0, 0x0D, 0xC0, 0x17, 0x10, 0xD3,
-0x00, 0x7E, 0x02, 0xF0, 0x0D, 0xC0, 0x40, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x1B, 0xD0, 0x0E,
-0x40, 0x2B, 0x00, 0xED, 0x00, 0xB6, 0x0B, 0xD0, 0x4A, 0x44, 0x3B, 0x02, 0x8D,
-0x04, 0x84, 0x80, 0xD0, 0x0E, 0x40, 0x93, 0x01, 0xE1, 0x04, 0xB4, 0x82, 0xD8,
-0x4C, 0x40, 0x4D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0x00, 0x79, 0x02, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x1E, 0x60, 0x6B, 0x24, 0xED,
-0x01, 0xB4, 0x97, 0xD0, 0x5E, 0x62, 0x7B, 0x18, 0x2D, 0x01, 0xA4, 0xC4, 0xD2,
-0x1E, 0x41, 0xFB, 0x00, 0xE1, 0x0D, 0xB4, 0x2F, 0xD1, 0x1E, 0x40, 0x10, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x10, 0x4D,
-0x07, 0x74, 0x07, 0xD0, 0x38, 0x49, 0xE3, 0x20, 0xCD, 0x05, 0x34, 0x03, 0xD0,
-0x1C, 0x40, 0x33, 0x80, 0xCD, 0x00, 0x04, 0x0F, 0xD0, 0x74, 0x40, 0x63, 0x40,
-0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0x59, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x7F, 0x10, 0x7C, 0x41, 0xF0,
-0x17, 0xC0, 0xDF, 0x00, 0x7F, 0x04, 0x3C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00,
-0x7F, 0x11, 0xAC, 0x05, 0xF0, 0x27, 0xC8, 0xDF, 0x08, 0x53, 0x80, 0x7C, 0x01,
-0xF1, 0x04, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x00, 0x87, 0x08, 0x1F, 0x80, 0x78, 0x00, 0xF0, 0x81, 0xC8, 0x87, 0x00,
-0x1C, 0x00, 0x7C, 0x08, 0xF0, 0x81, 0x82, 0x02, 0x00, 0x0F, 0x00, 0x7C, 0x10,
-0xF0, 0x21, 0xC0, 0x03, 0x00, 0x1F, 0x02, 0x74, 0x00, 0xF0, 0x01, 0xC8, 0x4B,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x67, 0x02,
-0x9F, 0x00, 0x7C, 0x06, 0x30, 0x49, 0xC0, 0x67, 0x04, 0x9F, 0xC8, 0x7C, 0x02,
-0x31, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x4D, 0x8A, 0x30, 0x49, 0xC0, 0x67,
-0x04, 0x93, 0x08, 0x4C, 0x22, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xEE, 0x00, 0x9D, 0x40, 0xF0, 0x06,
-0x10, 0x0B, 0x40, 0xA7, 0x02, 0x9D, 0x01, 0xF4, 0x0A, 0x10, 0x9B, 0x40, 0x27,
-0x01, 0x9B, 0x80, 0x44, 0x06, 0x10, 0x29, 0x44, 0x2F, 0x00, 0xB1, 0x03, 0x84,
-0x02, 0x10, 0x0B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA0, 0x24, 0x04, 0x9D, 0x80, 0x70, 0x22, 0x10, 0x09, 0x40, 0x27,
-0x00, 0x9D, 0x00, 0x74, 0x42, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x44,
-0x43, 0x14, 0x29, 0x40, 0x27, 0x02, 0x80, 0x00, 0x44, 0xC2, 0x10, 0x09, 0x40,
-0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20,
-0x18, 0x8D, 0x42, 0x34, 0x0A, 0x14, 0x28, 0x44, 0xB3, 0x00, 0x8D, 0x00, 0x36,
-0x02, 0x11, 0x28, 0x40, 0x23, 0x45, 0x89, 0x14, 0x04, 0x02, 0x10, 0x08, 0x40,
-0xA3, 0x00, 0x81, 0x02, 0x04, 0x02, 0x10, 0x08, 0x40, 0x50, 0xA0, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x46, 0x00, 0x1F, 0x00, 0x7C,
-0x04, 0x12, 0x11, 0xC2, 0x07, 0x10, 0x1F, 0x00, 0x7C, 0x04, 0x34, 0x11, 0xC0,
-0x07, 0x01, 0x13, 0x04, 0x4C, 0x00, 0x32, 0x01, 0xC0, 0x47, 0x40, 0x53, 0x01,
-0x4C, 0x04, 0x34, 0x11, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00, 0xBF, 0x01, 0xFC, 0x8E, 0xF0, 0x3B, 0xC0,
-0x7F, 0x20, 0xBE, 0x00, 0x7C, 0x0A, 0xF0, 0x3B, 0xC0, 0x27, 0x00, 0xF7, 0x00,
-0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0xEF, 0x00, 0x9C, 0x23, 0xFD, 0x0A, 0xF0, 0x29,
-0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
-0x6B, 0x00, 0x93, 0x82, 0xFC, 0x16, 0xF0, 0x7B, 0xC1, 0x2C, 0x00, 0xB3, 0x00,
-0xFC, 0x06, 0xF0, 0x7B, 0xC1, 0x6C, 0x01, 0xBE, 0x81, 0xCC, 0x02, 0xF0, 0x0B,
-0xD0, 0xEC, 0x01, 0xBF, 0x07, 0xFC, 0x16, 0xF0, 0x1B, 0xC0, 0x60, 0x00, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x87, 0x00, 0x51, 0x05,
-0x74, 0x54, 0xD0, 0x31, 0x40, 0x40, 0x05, 0x11, 0x00, 0x74, 0x00, 0xD1, 0x31,
-0x44, 0x05, 0x00, 0x1D, 0x0A, 0x44, 0x01, 0xD0, 0x01, 0x40, 0x44, 0x20, 0x1D,
-0x03, 0x74, 0x28, 0xD2, 0x01, 0x48, 0x70, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA0, 0xA3, 0x40, 0x85, 0x44, 0x36, 0x0A, 0xD8, 0x49,
-0x40, 0x22, 0x00, 0x81, 0x21, 0x34, 0x0A, 0xD1, 0x48, 0x40, 0xA0, 0x00, 0x8D,
-0xA0, 0x04, 0x02, 0xD1, 0x08, 0x60, 0xA2, 0x11, 0xCD, 0x06, 0x34, 0x82, 0xD0,
-0x28, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0xA8, 0x25, 0x80, 0x95, 0x01, 0x74, 0x82, 0xD0, 0x19, 0x41, 0x22, 0x40, 0x91,
-0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0,
-0x09, 0x41, 0x26, 0x05, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x60, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0xB7,
-0x00, 0xFC, 0x06, 0xF2, 0x0A, 0xD0, 0xAE, 0x10, 0x93, 0x0B, 0x7C, 0x02, 0xF0,
-0x0B, 0xC0, 0x24, 0x20, 0x9F, 0x03, 0x4C, 0x8E, 0xF0, 0x08, 0xC0, 0xEE, 0x00,
-0xBF, 0x00, 0x7C, 0x06, 0xF0, 0x08, 0xD0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9B, 0x00, 0x7C, 0x0E, 0xF0,
-0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x27, 0x0C,
-0x8F, 0x49, 0x7D, 0x12, 0xF1, 0x49, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x52,
-0xF0, 0x09, 0x81, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x08, 0x01, 0x01, 0x13, 0x02, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00,
-0x1B, 0x08, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x17, 0x88, 0x7C, 0x00,
-0xF1, 0x21, 0xC0, 0x05, 0x00, 0x1B, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x43,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xDC, 0x00,
-0x50, 0x00, 0x74, 0x01, 0x10, 0x05, 0x42, 0x5C, 0x02, 0x51, 0x00, 0xF4, 0x05,
-0xD0, 0x15, 0x41, 0x1C, 0x00, 0x51, 0x81, 0xF4, 0x05, 0xD0, 0x07, 0x41, 0x14,
-0x04, 0x71, 0x40, 0xF4, 0x0D, 0xD0, 0x27, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x00, 0xC9, 0x00, 0x34, 0x07,
-0x90, 0x9C, 0x40, 0x20, 0x22, 0x89, 0x20, 0x34, 0x06, 0xD0, 0x0D, 0x40, 0xB0,
-0x0A, 0x85, 0x01, 0x34, 0x23, 0xD0, 0x08, 0x43, 0x73, 0x00, 0x89, 0x00, 0x34,
-0x0E, 0xD0, 0xA8, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0x80, 0xA8, 0x00, 0xE9, 0x04, 0x34, 0x0E, 0x90, 0xCA, 0x50, 0x38,
-0x01, 0xE1, 0x00, 0xB4, 0x0A, 0xD0, 0x0E, 0x70, 0x48, 0x00, 0xE1, 0x00, 0xB4,
-0x00, 0xD0, 0x02, 0x40, 0x7A, 0x00, 0x61, 0x00, 0xB4, 0x42, 0xD1, 0x0A, 0x60,
-0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x68,
-0x00, 0xEB, 0x07, 0xBC, 0x07, 0xB0, 0x1C, 0xC0, 0xD8, 0x00, 0xEB, 0x01, 0xBC,
-0x06, 0xF0, 0x5F, 0xC0, 0x58, 0x00, 0xE7, 0x01, 0xBC, 0x04, 0xF1, 0x16, 0xC2,
-0x73, 0x00, 0xEB, 0x07, 0xBC, 0x06, 0xF0, 0x1A, 0xC0, 0x47, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x40, 0xD7, 0x00, 0x7C,
-0x02, 0x74, 0x09, 0xC0, 0x17, 0x00, 0xDE, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
-0x03, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xF0, 0x04, 0xC6, 0x35, 0x02, 0x5F, 0x00,
-0x7C, 0x02, 0xFA, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xF3, 0x01, 0xDC, 0x47, 0x30, 0x1F, 0xC2,
-0x78, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0x30, 0x1B, 0x41, 0x4D, 0x00, 0xF1, 0x09,
-0xCC, 0x06, 0xE0, 0x16, 0xE0, 0x6C, 0x01, 0xE3, 0x01, 0xCC, 0x07, 0x30, 0x9B,
-0xC2, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88,
-0xB9, 0x10, 0xE1, 0x10, 0x84, 0x02, 0x12, 0x0B, 0x41, 0x38, 0x20, 0xE1, 0x00,
-0xB4, 0x02, 0x10, 0x0A, 0x40, 0x08, 0x01, 0xE1, 0x08, 0x84, 0x00, 0xD1, 0x0E,
-0xD0, 0x2C, 0x41, 0x61, 0x00, 0xC4, 0x02, 0x10, 0x8A, 0x40, 0x57, 0x60, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xF9, 0x01,
-0x94, 0x03, 0x14, 0x8E, 0x40, 0x1C, 0x00, 0xE1, 0x00, 0x34, 0x03, 0x90, 0x0A,
-0x40, 0x08, 0x00, 0xF9, 0x00, 0xA4, 0x00, 0xD0, 0x8E, 0x41, 0x28, 0x13, 0xE1,
-0x00, 0xD4, 0x23, 0x90, 0x0A, 0x44, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x04, 0x28, 0x23, 0x00, 0xC9, 0x02, 0x06, 0x06, 0x10, 0x09,
-0x42, 0x10, 0x00, 0xC1, 0x06, 0x34, 0x02, 0x90, 0x08, 0x40, 0x00, 0x00, 0xC9,
-0x01, 0x26, 0x4C, 0xD0, 0x0C, 0x42, 0x20, 0x04, 0x41, 0x00, 0x14, 0x81, 0x90,
-0x08, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0xA8, 0x25, 0x00, 0xDB, 0x00, 0x5C, 0x03, 0x30, 0x1D, 0xC0, 0x74, 0x48, 0xD3,
-0x13, 0x7C, 0x02, 0xB4, 0x1D, 0xC0, 0x05, 0x00, 0xCB, 0x01, 0x6C, 0x46, 0xF0,
-0x1D, 0xE0, 0x74, 0x00, 0xD3, 0x40, 0x1D, 0x06, 0xB0, 0x0D, 0xC0, 0x57, 0x20,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x40, 0xD7,
-0x00, 0x7C, 0x22, 0xF0, 0x49, 0xD0, 0x37, 0x02, 0xDF, 0x00, 0x7C, 0x0A, 0x70,
-0x8D, 0xD0, 0x07, 0x00, 0xD7, 0x0C, 0x5D, 0x00, 0xF0, 0x05, 0xC9, 0x35, 0x02,
-0x4F, 0x00, 0x64, 0x22, 0x74, 0x29, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x00, 0xFF, 0x10, 0x4C, 0x0B, 0xF0,
-0x0F, 0xC0, 0x5C, 0x00, 0xFF, 0x80, 0xEC, 0x0E, 0xF0, 0x8C, 0xC0, 0x04, 0x00,
-0xFF, 0x08, 0xCC, 0x00, 0xF0, 0x87, 0xC0, 0x7E, 0x20, 0xF3, 0x08, 0xCC, 0x02,
-0x33, 0x2F, 0xC6, 0x13, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x81, 0x00, 0x26, 0x00, 0xDD, 0x00, 0x44, 0x87, 0xD0, 0x19, 0xC0, 0xF6, 0x00,
-0xCD, 0x09, 0x44, 0x00, 0xD2, 0x19, 0x40, 0x44, 0x04, 0xDC, 0x20, 0x6C, 0x04,
-0x90, 0x04, 0x40, 0x21, 0x00, 0xD3, 0x02, 0x44, 0x02, 0x10, 0x19, 0x40, 0x17,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x82,
-0xCD, 0x00, 0x44, 0x03, 0xD0, 0x4D, 0x50, 0xB4, 0x02, 0xDD, 0x00, 0x64, 0x03,
-0xD8, 0x09, 0x40, 0x44, 0x20, 0xDD, 0x00, 0x44, 0x06, 0xD0, 0x05, 0x44, 0x24,
-0x01, 0xD0, 0x10, 0x44, 0x03, 0x10, 0x0D, 0x41, 0x07, 0x00, 0x02, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02,
-0xD0, 0x0C, 0x40, 0x12, 0x00, 0xDD, 0x00, 0x04, 0x03, 0xD0, 0x08, 0x40, 0x00,
-0x00, 0xCD, 0x00, 0x26, 0x00, 0x90, 0x0D, 0x40, 0x35, 0x40, 0x41, 0x00, 0x05,
-0x02, 0x1C, 0x04, 0x44, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xB0, 0x16, 0x00, 0xFF, 0x40, 0x4C, 0x02, 0xF0, 0x09, 0x40, 0x14,
-0x20, 0xDF, 0x00, 0x6C, 0x03, 0xD0, 0x0D, 0xC4, 0x04, 0x08, 0xDF, 0x00, 0x4C,
-0x00, 0xF0, 0x0D, 0xC0, 0x26, 0x10, 0x53, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC2,
-0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F,
-0x00, 0xEF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x1D, 0x00, 0xFF, 0x00, 0xFC,
-0x01, 0xF0, 0x0B, 0xD0, 0x0F, 0x00, 0xEF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0,
-0x2F, 0x00, 0x77, 0x40, 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x17, 0x22, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x7F, 0x00, 0xEF, 0x09, 0xDC,
-0x06, 0xF2, 0x1F, 0xC0, 0x7D, 0x00, 0xE3, 0x01, 0xDC, 0x12, 0x30, 0x13, 0xC0,
-0x4E, 0x10, 0xB3, 0x00, 0xDC, 0x32, 0x70, 0x2B, 0xC0, 0xBC, 0x00, 0xB3, 0x20,
-0xFC, 0x10, 0x30, 0x02, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0x18, 0x77, 0x00, 0xDD, 0x04, 0x44, 0x06, 0x10, 0x1D, 0x40,
-0x74, 0x00, 0xD1, 0x01, 0x44, 0x0E, 0x10, 0x11, 0x40, 0x74, 0x00, 0x51, 0x43,
-0x44, 0xB2, 0x10, 0xA1, 0x40, 0xBC, 0x03, 0x11, 0x32, 0x74, 0x26, 0x50, 0x11,
-0x40, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
-0x33, 0x00, 0xCD, 0x04, 0x14, 0x03, 0x58, 0x0C, 0x40, 0x27, 0x00, 0xD5, 0x00,
-0x17, 0x08, 0x10, 0x01, 0x60, 0x06, 0x08, 0x81, 0x28, 0x16, 0x12, 0xD8, 0x40,
-0x40, 0x30, 0x00, 0x05, 0x86, 0x34, 0x00, 0x18, 0x08, 0x60, 0x4E, 0x80, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x04,
-0x54, 0x07, 0x10, 0x0D, 0x46, 0x26, 0x00, 0xD5, 0x11, 0x44, 0x0C, 0x12, 0x11,
-0x40, 0x74, 0x00, 0x91, 0x01, 0x44, 0x46, 0x18, 0x10, 0x40, 0x36, 0x00, 0x15,
-0x01, 0x74, 0x43, 0x52, 0x19, 0x41, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x08, 0xDF, 0x00, 0x1E, 0x06, 0x70, 0xD5,
-0xC0, 0xD3, 0x00, 0xC7, 0x03, 0x5C, 0x0C, 0x30, 0x30, 0xC4, 0x52, 0x04, 0x92,
-0x07, 0x5D, 0x04, 0x70, 0x39, 0xC0, 0x34, 0x00, 0x97, 0x61, 0x7C, 0x8D, 0x30,
-0x39, 0xC0, 0x2A, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
-0x80, 0x3D, 0x30, 0xFF, 0x01, 0xEC, 0x02, 0xF0, 0x0F, 0xC0, 0x7D, 0x02, 0xFB,
-0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6F, 0x20, 0xBC, 0x00, 0xF0,
-0x03, 0xD0, 0x3D, 0x00, 0x3B, 0x20, 0xFC, 0x24, 0xF1, 0x0B, 0xC0, 0x1F, 0x00,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xDF,
-0x00, 0x5C, 0x03, 0xB0, 0x49, 0xC0, 0xA5, 0x00, 0xDB, 0x02, 0x4C, 0x00, 0xF0,
-0x21, 0xC0, 0x17, 0x02, 0xD7, 0x05, 0x6C, 0x02, 0xF1, 0x09, 0xC0, 0x37, 0x44,
-0x93, 0x02, 0x6C, 0x0B, 0xF0, 0x29, 0xC4, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x4D, 0x40, 0x0F, 0x15,
-0x38, 0x40, 0x24, 0x10, 0x91, 0x00, 0x2C, 0x44, 0xD1, 0xB1, 0x44, 0x54, 0x10,
-0xD1, 0x01, 0x74, 0xB2, 0xD2, 0x01, 0x4A, 0xFF, 0x00, 0x90, 0x30, 0x34, 0x83,
-0xD1, 0x08, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x13, 0xA0, 0x32, 0x00, 0xDD, 0x00, 0x14, 0x26, 0x10, 0x9C, 0x48, 0x31, 0x00,
-0xCC, 0x08, 0x25, 0x02, 0xD0, 0x10, 0x40, 0x11, 0x00, 0x85, 0x02, 0x34, 0x00,
-0xD0, 0x08, 0x42, 0x36, 0x00, 0x85, 0x25, 0x24, 0x00, 0xD0, 0xB0, 0x41, 0x0D,
-0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00,
-0xFD, 0x01, 0xC4, 0x1E, 0x18, 0x9F, 0x40, 0x7C, 0x10, 0xF5, 0x41, 0xB4, 0x07,
-0xD0, 0x12, 0x00, 0x58, 0x00, 0xA0, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x00, 0x73,
-0x04, 0xE5, 0x01, 0xB4, 0x04, 0xD1, 0x16, 0x00, 0x34, 0x20, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x1C, 0x02,
-0x30, 0x8C, 0xC0, 0xB1, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0xF0, 0xE0, 0xC3, 0x11,
-0x00, 0x87, 0x00, 0x28, 0x01, 0xF0, 0x04, 0xC0, 0x32, 0x30, 0x47, 0x00, 0x2C,
-0x03, 0xF0, 0x00, 0xC0, 0x49, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0xA0, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x12, 0x70, 0x8E, 0xC0, 0x3B,
-0x02, 0xFB, 0x88, 0xEC, 0x23, 0xF0, 0x82, 0xC0, 0x19, 0x00, 0xBB, 0x00, 0xFC,
-0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x20, 0x7B, 0x40, 0xFC, 0x23, 0xF0, 0x8F, 0xC0,
-0x09, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
-0x00, 0x9F, 0x00, 0x3C, 0x06, 0x70, 0x0D, 0xE0, 0x35, 0x00, 0xDF, 0x00, 0x44,
-0x01, 0xB2, 0x05, 0xC2, 0x13, 0x00, 0xCB, 0x00, 0x6C, 0x05, 0x72, 0x0D, 0xC2,
-0xB7, 0x03, 0xDD, 0x00, 0x6C, 0x00, 0xF0, 0x15, 0x80, 0x40, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x39, 0x10, 0xEC, 0x00, 0xB4,
-0x82, 0x10, 0x0E, 0x52, 0x38, 0x00, 0x6D, 0x00, 0x94, 0x03, 0x90, 0x06, 0x40,
-0x1B, 0x00, 0xE1, 0x00, 0xC5, 0x01, 0x10, 0x0E, 0x48, 0x3B, 0x05, 0xED, 0x00,
-0x84, 0x00, 0x90, 0x0E, 0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x00, 0x79, 0x20, 0xAC, 0x91, 0xB4, 0x06, 0xD0, 0x1F, 0x48,
-0x79, 0x20, 0xFD, 0x01, 0xB4, 0x47, 0x90, 0x1E, 0x60, 0x5B, 0x00, 0xE9, 0x01,
-0xA4, 0x07, 0x50, 0x1E, 0x41, 0x7B, 0x00, 0xCD, 0x03, 0xB4, 0x07, 0xD8, 0x14,
-0x64, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20,
-0x33, 0x00, 0xCD, 0x01, 0x34, 0x40, 0xD0, 0x5C, 0x40, 0x31, 0x00, 0xCD, 0x05,
-0x34, 0x03, 0x98, 0x24, 0x40, 0x93, 0x08, 0xC1, 0x08, 0x04, 0x03, 0x10, 0x2C,
-0x41, 0x33, 0x88, 0xDD, 0x00, 0x14, 0x1F, 0x90, 0x2C, 0x40, 0x58, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x5F, 0x01,
-0xFC, 0x09, 0xF0, 0x07, 0x40, 0x1D, 0x00, 0x7F, 0x01, 0xFC, 0x01, 0xB0, 0x77,
-0xC0, 0x5B, 0x00, 0x6B, 0x01, 0xEC, 0x29, 0x70, 0x07, 0xC0, 0x17, 0x00, 0x7F,
-0x08, 0xFC, 0x01, 0xF0, 0x47, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0xC2, 0x7C, 0x00, 0x00, 0xA1,
-0x80, 0x06, 0x01, 0x1C, 0x08, 0x58, 0x00, 0xC3, 0x01, 0x88, 0x07, 0x02, 0x1F,
-0x42, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x87, 0x20, 0x1F, 0x40, 0x60, 0x20, 0xB0,
-0x01, 0xD0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x25, 0x00, 0x9F, 0x03, 0x7C, 0x12, 0xF9, 0x09, 0xC8, 0x25, 0x00, 0x9F,
-0x04, 0x1C, 0x56, 0x31, 0x89, 0xC3, 0x27, 0x04, 0x97, 0x05, 0x40, 0x06, 0xF0,
-0x09, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4C, 0x82, 0xF3, 0x39, 0xC1, 0x43, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D,
-0x03, 0x74, 0x0A, 0xD8, 0x48, 0x40, 0x24, 0x10, 0x8D, 0x00, 0x44, 0x06, 0x14,
-0x19, 0x44, 0xE7, 0x81, 0x9B, 0x12, 0x44, 0x0E, 0xD0, 0x09, 0x40, 0x67, 0x20,
-0x9D, 0x0E, 0x44, 0x02, 0x78, 0x39, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x0B, 0x98,
-0x09, 0x40, 0x25, 0x00, 0x9D, 0x02, 0x56, 0x02, 0x50, 0x09, 0x48, 0x67, 0x00,
-0x95, 0x00, 0x54, 0x1A, 0xD0, 0x0D, 0x60, 0x27, 0x00, 0xDD, 0x00, 0x44, 0x02,
-0x50, 0x29, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x14, 0x28, 0x20, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x20, 0x00,
-0x8D, 0x80, 0x14, 0xD2, 0x50, 0x0C, 0x40, 0x23, 0x00, 0x81, 0x00, 0x10, 0x52,
-0xD0, 0x48, 0x61, 0x33, 0x0D, 0x8D, 0x14, 0x14, 0x02, 0x50, 0x48, 0x41, 0x53,
-0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x04, 0x00,
-0x1F, 0x00, 0x7C, 0x00, 0x90, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x80, 0x5C, 0x10,
-0x70, 0x01, 0xC0, 0x07, 0x20, 0x14, 0x14, 0x4D, 0x10, 0xF0, 0x41, 0xC0, 0x07,
-0x01, 0x1F, 0x04, 0x4D, 0x50, 0x70, 0x41, 0xE2, 0x77, 0xC0, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x27, 0x00, 0xBF, 0x94, 0xFC, 0x02,
-0xC0, 0x0E, 0x40, 0x3F, 0x00, 0xAF, 0x80, 0xEC, 0x02, 0xB0, 0x0B, 0xC0, 0x2F,
-0x00, 0xBF, 0x00, 0xEC, 0x52, 0xF0, 0x4B, 0x41, 0x27, 0x05, 0xBF, 0x14, 0xEC,
-0x02, 0x70, 0x0B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA0, 0x27, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0x79, 0x0A, 0xC0, 0x25,
-0x00, 0xBF, 0x00, 0xCC, 0x06, 0xB1, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xDD,
-0x12, 0xF0, 0x99, 0xC0, 0x6D, 0x03, 0xB9, 0x0D, 0xF8, 0x02, 0x30, 0x0B, 0xC8,
-0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07,
-0x00, 0x1D, 0x41, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x44,
-0x28, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x40, 0x44, 0x10, 0xD0, 0xB1, 0x40,
-0xC4, 0x03, 0x11, 0x0F, 0x74, 0x00, 0x10, 0x01, 0x50, 0x70, 0x60, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x23, 0x00, 0x8D, 0x04, 0x74,
-0x02, 0xD4, 0x08, 0x40, 0x21, 0x20, 0x9D, 0x00, 0x17, 0x02, 0x90, 0x08, 0x40,
-0x23, 0x00, 0x9D, 0x00, 0x36, 0x62, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x89, 0x00,
-0x34, 0x02, 0x14, 0x08, 0x48, 0x49, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0xA0, 0x25, 0x00, 0x9D, 0x80, 0x74, 0x42, 0x12, 0x09, 0x44,
-0x24, 0x00, 0x9D, 0x40, 0x52, 0x46, 0x00, 0x09, 0x41, 0x27, 0x00, 0x9D, 0x00,
-0x74, 0x8E, 0xD0, 0x09, 0x61, 0x24, 0x00, 0x91, 0x10, 0x74, 0x02, 0x10, 0x09,
-0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8,
-0x26, 0x00, 0x9D, 0x00, 0x78, 0x0A, 0xF2, 0x08, 0xC0, 0x25, 0x80, 0x9F, 0x04,
-0x5C, 0x0A, 0xB2, 0x09, 0xC2, 0x27, 0x08, 0x9F, 0x19, 0x7C, 0x02, 0xF0, 0x39,
-0xC0, 0x25, 0x20, 0x9A, 0x03, 0x7E, 0x16, 0x20, 0x09, 0xE5, 0x15, 0x20, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x00, 0x9F, 0x00,
-0x7C, 0x12, 0xF0, 0x29, 0xC0, 0xA6, 0x00, 0x9F, 0x28, 0x2C, 0x02, 0xF0, 0x09,
-0xC0, 0x27, 0x00, 0x9F, 0x90, 0x4C, 0x02, 0xF0, 0x48, 0xC4, 0x27, 0x00, 0x9F,
-0x89, 0x7E, 0x22, 0xF2, 0x08, 0xE0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x04, 0x7C, 0x18, 0xB2, 0x41,
-0xC0, 0x04, 0x20, 0x1F, 0x06, 0x4C, 0x28, 0xF2, 0x61, 0xC0, 0x05, 0x02, 0x1F,
-0x02, 0x6C, 0x08, 0xB0, 0x21, 0xC2, 0x07, 0x00, 0x1F, 0x12, 0x1C, 0x08, 0x30,
-0x21, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0xA0, 0x14, 0x00, 0x7D, 0x11, 0xB0, 0x0D, 0x10, 0x17, 0x58, 0x14, 0x00, 0x6D,
-0x03, 0x45, 0x05, 0xD0, 0x17, 0x44, 0x9F, 0x02, 0x6D, 0x00, 0xC0, 0x01, 0x10,
-0x05, 0x40, 0x9F, 0x02, 0x7D, 0x80, 0x44, 0x01, 0x10, 0x27, 0x00, 0x50, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD,
-0x00, 0x34, 0x8A, 0x90, 0xAC, 0x04, 0x30, 0x00, 0x45, 0x02, 0x12, 0x06, 0xD1,
-0x2C, 0x40, 0x91, 0x00, 0xCD, 0x22, 0x24, 0x17, 0x90, 0x0C, 0x40, 0x37, 0xA2,
-0xCD, 0x08, 0x16, 0xA7, 0x10, 0x4C, 0x50, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x38, 0x00, 0x6D, 0x00, 0xF4, 0x0A, 0x10,
-0x0E, 0x40, 0x38, 0x00, 0x6D, 0x10, 0xB4, 0x03, 0xD0, 0x0E, 0x61, 0x1B, 0x80,
-0xFD, 0x30, 0xA0, 0x47, 0x90, 0x4E, 0x40, 0x3B, 0xA0, 0x6D, 0x01, 0x84, 0x03,
-0x50, 0x2C, 0x40, 0x04, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x11, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x06, 0xB0, 0x1E, 0xC0, 0x78, 0x20,
-0x6F, 0x01, 0x9C, 0x07, 0xF0, 0x1E, 0xE0, 0x59, 0x00, 0xEF, 0x01, 0xE8, 0x07,
-0xB0, 0xBE, 0xC0, 0x7B, 0x20, 0xFF, 0x21, 0x1C, 0x07, 0x34, 0x1E, 0xC0, 0x44,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00,
-0xDF, 0x00, 0x3C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0x4F, 0x00, 0x4D, 0x83,
-0xF0, 0x0D, 0xE0, 0x17, 0x00, 0xCF, 0x00, 0x5C, 0x03, 0x70, 0x6D, 0xC4, 0x17,
-0x08, 0x5E, 0x40, 0x7C, 0x03, 0xB0, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x07,
-0x30, 0x17, 0xC0, 0x7D, 0x00, 0x7F, 0x01, 0xDC, 0x27, 0xF1, 0x9F, 0xC0, 0x5F,
-0x00, 0xEF, 0x01, 0xEC, 0x85, 0xB0, 0x9F, 0x00, 0x5F, 0x02, 0xF3, 0x4D, 0xC8,
-0x07, 0x20, 0x1F, 0xC0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0x18, 0x39, 0x00, 0x6D, 0x42, 0xB4, 0x12, 0x10, 0x0E, 0x40, 0x38,
-0x00, 0x29, 0x44, 0x80, 0x03, 0xD0, 0x0E, 0x40, 0x1B, 0x00, 0x6D, 0x02, 0x94,
-0x01, 0xD0, 0x0E, 0x43, 0x1A, 0x00, 0xE1, 0x18, 0x84, 0x53, 0x10, 0x07, 0x41,
-0x55, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
-0x00, 0xED, 0x00, 0xF4, 0x02, 0x18, 0x2E, 0x50, 0xB9, 0x00, 0x6D, 0xB2, 0x80,
-0x43, 0xD0, 0x0E, 0x42, 0x1B, 0x04, 0xED, 0x18, 0x95, 0x01, 0x90, 0x0E, 0x42,
-0x3A, 0x30, 0xE1, 0x44, 0xB5, 0x03, 0x1C, 0x0F, 0x40, 0x00, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x30, 0x00, 0x8D, 0x00, 0x34,
-0x0A, 0x18, 0x0C, 0x58, 0x31, 0x08, 0x49, 0x01, 0x04, 0x07, 0xD0, 0x08, 0x40,
-0xD3, 0x00, 0x4D, 0x03, 0x04, 0x9C, 0xD0, 0x1D, 0x48, 0x02, 0x80, 0x91, 0x01,
-0x34, 0x13, 0x10, 0x30, 0x00, 0x11, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0x9F, 0x00, 0x74, 0x0B, 0x30, 0x2D, 0xC0,
-0x31, 0x00, 0xCF, 0x02, 0x4D, 0x23, 0xF2, 0x0D, 0xC0, 0xD7, 0x00, 0xCF, 0x09,
-0x5C, 0x1A, 0xB0, 0x3F, 0x40, 0x26, 0x20, 0x91, 0x02, 0x7C, 0x02, 0x30, 0x2D,
-0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-0x37, 0x00, 0x1F, 0x01, 0x7C, 0x43, 0xF0, 0x0D, 0x40, 0x36, 0x00, 0xDB, 0x02,
-0x7C, 0x03, 0xF0, 0x6D, 0xC4, 0x17, 0x01, 0xDF, 0x00, 0x74, 0x00, 0xD0, 0x0D,
-0xC1, 0x26, 0x00, 0x1F, 0x02, 0x4C, 0x02, 0xF1, 0x4D, 0xC0, 0x07, 0x00, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x08, 0x3F, 0x00,
-0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3D, 0x08, 0x77, 0x00, 0xCC, 0x03, 0xE0, 0x9F,
-0xD0, 0x1C, 0x00, 0xF9, 0x00, 0x8D, 0x02, 0xB0, 0x0F, 0xC0, 0x24, 0x00, 0x9F,
-0x10, 0x48, 0x82, 0xD0, 0x07, 0xC0, 0x13, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00, 0x1D, 0x03, 0x74, 0x86, 0xD2, 0x3C,
-0x41, 0x34, 0x00, 0x51, 0x21, 0x44, 0x03, 0xD0, 0x5C, 0x40, 0x54, 0x08, 0xDD,
-0x43, 0x44, 0x4E, 0x10, 0x0D, 0x40, 0x64, 0x00, 0x1D, 0x07, 0x6C, 0xA2, 0xD2,
-0x01, 0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0xA0, 0x34, 0x00, 0x9D, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x40, 0x35, 0x00, 0x55,
-0x03, 0x45, 0x07, 0xD2, 0x0D, 0x42, 0x55, 0x04, 0x9D, 0x81, 0x54, 0x06, 0x90,
-0x0D, 0x50, 0xC4, 0x00, 0x1D, 0x01, 0x54, 0x03, 0xD0, 0x89, 0x41, 0x07, 0x08,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x00, 0x0D,
-0x00, 0x34, 0x07, 0xD0, 0x09, 0x40, 0x34, 0x00, 0x51, 0x00, 0x04, 0x03, 0xD0,
-0x04, 0x40, 0x10, 0x00, 0x4D, 0x00, 0x04, 0x00, 0x18, 0x0C, 0x40, 0x00, 0x00,
-0x1D, 0x00, 0x36, 0x83, 0xD0, 0x00, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x36, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
-0x0D, 0xC0, 0x35, 0x00, 0x57, 0x00, 0x48, 0x03, 0xF0, 0x0D, 0x40, 0x34, 0x10,
-0x5B, 0x00, 0x48, 0x02, 0xB0, 0x0F, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x5C, 0x03,
-0xF0, 0x01, 0xC8, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0xA0, 0x3F, 0x00, 0xBF, 0x00, 0xB4, 0x00, 0xF0, 0x0A, 0xC0, 0x3F, 0x20,
-0x6F, 0x00, 0xFC, 0x03, 0xE0, 0x0F, 0xC0, 0x2F, 0x00, 0x7E, 0x00, 0xFC, 0x02,
-0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xEC, 0x03, 0xF0, 0x03, 0xC0, 0x17,
-0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x7F, 0x00,
-0xEF, 0x09, 0xCC, 0x27, 0xF2, 0x1F, 0xC0, 0x7C, 0x00, 0xFF, 0x01, 0xBC, 0x27,
-0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0xEE, 0x09, 0xCC, 0x07, 0x31, 0x1E, 0xC0, 0x7C,
-0x00, 0xF3, 0x09, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x47, 0x10, 0x1D, 0x44, 0x44, 0x10,
-0xD0, 0x11, 0x40, 0x44, 0x00, 0x1D, 0x01, 0x74, 0x00, 0xD2, 0x01, 0x48, 0x47,
-0x00, 0x1D, 0x44, 0x44, 0x04, 0x50, 0x11, 0x40, 0x44, 0x00, 0x11, 0x84, 0x74,
-0x04, 0x14, 0x11, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x11, 0xA0, 0x33, 0x00, 0xDD, 0x00, 0x14, 0x03, 0xD0, 0x0D, 0x40, 0x30,
-0x08, 0xCC, 0x80, 0x36, 0x13, 0xD0, 0x4C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x04,
-0x03, 0x11, 0x0C, 0x40, 0x30, 0x00, 0xC1, 0x80, 0x74, 0x03, 0x18, 0x0C, 0x40,
-0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x05,
-0x00, 0x1D, 0x00, 0x54, 0x80, 0xD0, 0x01, 0x40, 0x04, 0x18, 0x1D, 0x00, 0x74,
-0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x0D, 0x00, 0x45, 0x00, 0x50, 0x01, 0x40,
-0x04, 0x00, 0x11, 0x60, 0x76, 0x00, 0x10, 0x01, 0x40, 0x0C, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0xDF, 0x20, 0x5C,
-0x03, 0xF2, 0x0D, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
-0x37, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0x30, 0x0C, 0xC0, 0x30, 0x00, 0xD3, 0x00,
-0x3C, 0x83, 0x31, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0,
-0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0xB0,
-0xFC, 0x00, 0xF2, 0x03, 0xD0, 0x0F, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF0, 0x03,
-0xD1, 0x1F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
-0x35, 0x00, 0xDF, 0x01, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x80,
-0x4C, 0x23, 0x34, 0x8D, 0xC0, 0x74, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x0D,
-0xC0, 0x34, 0x01, 0xD3, 0x00, 0x4C, 0x83, 0xF0, 0x0D, 0xC0, 0x0B, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0x0D, 0x00,
-0x40, 0x40, 0x10, 0x10, 0x50, 0x04, 0x00, 0x1A, 0x05, 0x44, 0x00, 0x10, 0x11,
-0xC0, 0x86, 0x00, 0x1D, 0x03, 0x04, 0x04, 0x10, 0x11, 0x40, 0x85, 0x08, 0x11,
-0x11, 0x6E, 0x2C, 0xD0, 0x30, 0x40, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x07, 0xA8, 0x72, 0x02, 0xCD, 0x00, 0x06, 0x07, 0x00, 0x9C,
-0x40, 0x70, 0x80, 0xC1, 0x01, 0x20, 0x87, 0x10, 0x0C, 0x42, 0x30, 0x04, 0xCD,
-0x20, 0x04, 0x23, 0x1A, 0x1C, 0x40, 0x30, 0x00, 0xC1, 0x81, 0x24, 0x07, 0xD0,
-0x3C, 0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x80, 0x48, 0x02, 0x3D, 0x01, 0x84, 0x04, 0x10, 0x92, 0x40, 0x48, 0x00, 0x39,
-0x01, 0xE4, 0x04, 0x10, 0x33, 0x40, 0x4A, 0x20, 0x2D, 0x91, 0x85, 0x14, 0x18,
-0x13, 0x41, 0x49, 0x00, 0x21, 0x01, 0xA4, 0x44, 0xD0, 0x12, 0x41, 0x1B, 0x00,
-0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF,
-0x80, 0x44, 0x23, 0x34, 0x0C, 0xC0, 0x30, 0x26, 0xC3, 0x00, 0x2D, 0x23, 0x30,
-0x0C, 0x40, 0x30, 0x20, 0xCF, 0x44, 0x0E, 0x03, 0x34, 0x0C, 0xC0, 0x30, 0x40,
-0xD3, 0x08, 0x25, 0x03, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x08, 0x3F, 0x80, 0xFD, 0x00, 0xF0,
-0x02, 0xC0, 0x0B, 0x80, 0x2F, 0x00, 0xDC, 0x20, 0xF0, 0x82, 0xE0, 0x0F, 0x02,
-0x3F, 0x00, 0xBC, 0x10, 0xF0, 0x03, 0xC0, 0x0B, 0x00, 0x3F, 0x00, 0x5E, 0x00,
-0xF0, 0x13, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0xA0, 0x33, 0x00, 0xD7, 0x00, 0x7C, 0x83, 0xF0, 0x1D, 0xC0, 0x34, 0x00,
-0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x73, 0x00, 0xD3, 0x00, 0x1C, 0x03,
-0x30, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x00, 0x7E, 0x03, 0xF0, 0x1D, 0xC0, 0x54,
-0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x20,
-0x21, 0x20, 0xB4, 0x00, 0xD0, 0x02, 0x40, 0x08, 0x10, 0x2D, 0x40, 0xB4, 0x00,
-0xD0, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x00, 0x84, 0x00, 0x52, 0x02, 0x40, 0x0B,
-0x00, 0x21, 0x00, 0xB6, 0x00, 0xD1, 0x02, 0x40, 0x48, 0x60, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xE5, 0xC1, 0xB4, 0x07,
-0xD8, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x4A, 0x7B,
-0x88, 0xE1, 0x01, 0x94, 0x07, 0x94, 0x1E, 0x40, 0x7F, 0x00, 0xE9, 0x01, 0xB4,
-0x87, 0xD2, 0x1E, 0x52, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x28, 0x03, 0x00, 0x01, 0x00, 0x34, 0x00, 0xD9, 0x00, 0x56, 0x00,
-0x08, 0x0D, 0x80, 0x76, 0x00, 0xD0, 0x00, 0x44, 0x03, 0x00, 0x01, 0x40, 0x04,
-0x00, 0xD0, 0x00, 0x48, 0x03, 0x08, 0x09, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40,
-0x48, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x11,
-0x00, 0x57, 0x00, 0x3C, 0x01, 0xF0, 0x05, 0xC0, 0x10, 0x00, 0x5F, 0x00, 0x7C,
-0x01, 0xF0, 0x04, 0xC0, 0x17, 0x40, 0x43, 0x00, 0x1C, 0x01, 0xB4, 0x05, 0xC0,
-0x17, 0x00, 0x5B, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x5C, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x0F, 0x00, 0x3F, 0x00, 0xFC,
-0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xF4, 0x00, 0xF0, 0x03, 0xC4,
-0x8F, 0x00, 0x3F, 0x00, 0xFD, 0x08, 0x70, 0x23, 0xC0, 0x8F, 0x40, 0x37, 0x00,
-0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x09, 0x7C, 0x26, 0x30, 0x19, 0xC0,
-0x67, 0x00, 0x93, 0x08, 0x7C, 0x0A, 0x31, 0x19, 0xC8, 0x66, 0x02, 0x9F, 0x80,
-0x6C, 0x02, 0x34, 0x09, 0xC0, 0x67, 0x40, 0x92, 0x05, 0x7C, 0x02, 0xF0, 0x09,
-0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
-0x26, 0x00, 0x91, 0x01, 0x74, 0x02, 0x51, 0x19, 0x40, 0x27, 0x00, 0x91, 0x01,
-0x74, 0x02, 0x10, 0x89, 0x40, 0x64, 0x01, 0x9D, 0x00, 0x44, 0x12, 0x10, 0x39,
-0x48, 0x23, 0x02, 0x91, 0x01, 0x74, 0x0E, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x01, 0xB1, 0x80,
-0xF4, 0x02, 0x10, 0x8B, 0x40, 0x2F, 0x01, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B,
-0x40, 0x2E, 0x20, 0xBD, 0x00, 0xC4, 0x02, 0x10, 0x8B, 0x40, 0x2F, 0x80, 0xB5,
-0x00, 0xF4, 0x52, 0xD0, 0x0B, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x20, 0x2C, 0x00, 0xA1, 0x02, 0xF4, 0x0A, 0x50, 0x0A,
-0x40, 0x2F, 0x00, 0xA1, 0x00, 0xB4, 0x0A, 0x04, 0x1A, 0x40, 0x2A, 0x00, 0xBD,
-0x00, 0x85, 0x02, 0x18, 0x0E, 0x40, 0x2B, 0x00, 0xA5, 0x02, 0xB4, 0x02, 0xD0,
-0x0A, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
-0xB0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x40, 0x13,
-0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x06, 0x00, 0x0F, 0x40, 0x4C, 0x00, 0x32,
-0x01, 0xC2, 0x17, 0x40, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x77, 0xC0,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x40, 0x9F,
-0x01, 0x7C, 0x86, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF2,
-0x49, 0x41, 0x25, 0x20, 0x9F, 0x14, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
-0x9B, 0x01, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0xF0,
-0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x30, 0x0A, 0xC0, 0x2B, 0x20,
-0xAF, 0x42, 0x8D, 0x02, 0x30, 0x0B, 0xC0, 0x28, 0x00, 0xB3, 0x02, 0xCC, 0x02,
-0xF0, 0x0A, 0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x1C, 0x08, 0x07, 0x00, 0x1D, 0x15, 0x44, 0x54, 0xD0, 0x01, 0x48, 0x07, 0x00,
-0x1D, 0x00, 0x74, 0x14, 0x10, 0x51, 0x41, 0x07, 0x00, 0x1D, 0x81, 0x44, 0x00,
-0x50, 0x01, 0x48, 0x04, 0x10, 0x15, 0x01, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x71,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00,
-0x8D, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x48, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x42,
-0x10, 0x08, 0x40, 0x23, 0xA0, 0x8D, 0x00, 0x44, 0x03, 0x10, 0x08, 0x52, 0x20,
-0x00, 0xD1, 0x04, 0x04, 0x02, 0xD0, 0x09, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02,
-0xD0, 0x09, 0x40, 0x27, 0x10, 0x9D, 0x00, 0x74, 0x02, 0x14, 0x09, 0x44, 0x27,
-0x00, 0x8D, 0x00, 0x44, 0x82, 0x50, 0x09, 0x46, 0x24, 0x00, 0x95, 0x00, 0x44,
-0x02, 0xD0, 0x09, 0x40, 0x61, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x05, 0x28, 0x25, 0x00, 0xBF, 0x00, 0xCD, 0x82, 0xF0, 0x09, 0xC0, 0x27,
-0x00, 0x9F, 0x00, 0xFC, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C,
-0x02, 0x30, 0x09, 0xC0, 0x20, 0x08, 0xA3, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC0,
-0x14, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x82, 0xF0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x02, 0x1F, 0x00, 0x4C,
-0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xD0,
-0x04, 0x40, 0x13, 0x00, 0x4C, 0x10, 0x30, 0x01, 0xC0, 0x07, 0x40, 0x13, 0x00,
-0x7C, 0x04, 0x30, 0x01, 0xC1, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x5D, 0x20, 0x44, 0x01, 0xD1, 0x05, 0x40,
-0x17, 0x10, 0x5D, 0x01, 0x70, 0x01, 0xD0, 0x07, 0x40, 0xDC, 0x00, 0x71, 0x81,
-0x94, 0x01, 0x50, 0x16, 0x41, 0x1F, 0x00, 0x51, 0x00, 0xF4, 0x05, 0x11, 0x26,
-0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0,
-0x62, 0x00, 0xDD, 0x08, 0x04, 0x07, 0xD0, 0x88, 0x48, 0x33, 0x00, 0x8D, 0x80,
-0x74, 0x03, 0x50, 0x04, 0x40, 0xA0, 0x06, 0xC9, 0x11, 0x06, 0x01, 0x10, 0x4C,
-0x48, 0x33, 0x0C, 0xC1, 0x80, 0x34, 0x05, 0x90, 0x18, 0x44, 0x50, 0x00, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x08,
-0x84, 0x53, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x10, 0xB4, 0x43, 0xD0, 0x1F,
-0x40, 0x5C, 0x20, 0xF9, 0x50, 0xD4, 0x80, 0x50, 0x0A, 0x40, 0x1F, 0x20, 0xE1,
-0x08, 0xF4, 0x47, 0x91, 0x2B, 0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xFF, 0x05, 0x8C, 0x07, 0xF0, 0x1E,
-0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xBC, 0x87, 0x70, 0x1E, 0xC0, 0x48, 0x00, 0xEB,
-0x01, 0x8C, 0x07, 0x30, 0x12, 0xC0, 0x7B, 0x00, 0xA3, 0x81, 0xBC, 0x07, 0xB4,
-0x1A, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xB8, 0x35, 0x10, 0xDF, 0x00, 0x7C, 0x23, 0xF1, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x0F, 0xC0, 0x06, 0x00, 0xD7, 0x00, 0x78, 0x02, 0xF0,
-0x01, 0xC0, 0x37, 0x00, 0x9D, 0x00, 0x3C, 0x03, 0x70, 0x09, 0xC0, 0x43, 0x60,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x7F, 0x00, 0xBF,
-0x00, 0xFC, 0x06, 0x30, 0x9F, 0xC0, 0x7F, 0x00, 0xE3, 0x01, 0x8C, 0x47, 0x30,
-0x17, 0xC0, 0x4F, 0x00, 0x3F, 0x01, 0x9C, 0x04, 0x70, 0x16, 0xC4, 0x5C, 0x00,
-0xEF, 0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xC2, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x15, 0x98, 0x39, 0x04, 0xAD, 0x0C, 0xB4, 0x02, 0x11,
-0x8E, 0x40, 0x3B, 0x10, 0xE1, 0x00, 0x84, 0x23, 0x10, 0x0E, 0x40, 0x0B, 0x10,
-0x6D, 0x0A, 0x85, 0x60, 0x55, 0x86, 0xC0, 0x9A, 0x10, 0xED, 0x00, 0x84, 0x03,
-0xD0, 0x0A, 0x44, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x39, 0x00, 0xAD, 0x08, 0xF4, 0x02, 0x10, 0x8E, 0x40, 0x3F, 0x04,
-0xE1, 0x10, 0xE4, 0x03, 0x10, 0x0E, 0x41, 0x0B, 0x00, 0x2D, 0x10, 0x94, 0x00,
-0xD0, 0x07, 0x41, 0x3A, 0x00, 0xBD, 0x0A, 0xA4, 0x03, 0xD0, 0x0A, 0x41, 0x23,
-0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x33, 0x00,
-0x8D, 0x03, 0x74, 0x0A, 0x10, 0x5C, 0x40, 0xE3, 0x00, 0xC1, 0x41, 0x24, 0x0E,
-0x10, 0x1D, 0x40, 0x83, 0x02, 0x5D, 0x03, 0x04, 0x04, 0xD0, 0x14, 0x40, 0x72,
-0x10, 0x9D, 0x01, 0x24, 0x0B, 0xD1, 0x18, 0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x89, 0x7C, 0x03,
-0x30, 0x2D, 0xC0, 0x77, 0x40, 0xD3, 0x01, 0x6C, 0x46, 0x34, 0x19, 0xC0, 0x83,
-0x00, 0x5F, 0x41, 0x1C, 0x08, 0xF0, 0xB1, 0xC0, 0x76, 0x04, 0xDF, 0x11, 0x2C,
-0x02, 0xF0, 0x1D, 0xC2, 0x77, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x08, 0x78, 0x17, 0xF0, 0x8D, 0xC0, 0x37,
-0x00, 0xDF, 0x10, 0x5C, 0x02, 0xF0, 0x0D, 0xC1, 0x07, 0x04, 0xDF, 0x00, 0x7C,
-0x48, 0x60, 0x01, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x0F, 0xF0, 0x2D, 0xC1,
-0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F,
-0x06, 0xF3, 0x04, 0xFC, 0x0B, 0x30, 0x9F, 0xC8, 0x3F, 0x04, 0xFF, 0x80, 0xCC,
-0x56, 0xF0, 0x0F, 0xD0, 0x0C, 0x00, 0x73, 0x10, 0xCC, 0x00, 0xB0, 0x03, 0xC0,
-0x2F, 0x04, 0xB2, 0x03, 0xC8, 0x43, 0x30, 0x0F, 0xC0, 0x07, 0x24, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x72, 0x40, 0x91, 0x01, 0x74,
-0x06, 0x10, 0x1D, 0x44, 0x37, 0x08, 0xCD, 0x40, 0x44, 0x06, 0xD0, 0x3D, 0x40,
-0x44, 0x30, 0xDF, 0xC0, 0x45, 0x04, 0x10, 0x71, 0x44, 0x63, 0x10, 0xD1, 0x01,
-0x44, 0x17, 0xB0, 0x0D, 0x40, 0x27, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x01, 0xA0, 0x36, 0x00, 0x91, 0x80, 0x74, 0x02, 0x10, 0x0D, 0x40,
-0x37, 0x00, 0xDD, 0x04, 0x44, 0x02, 0xD0, 0x19, 0x41, 0x46, 0x00, 0x11, 0x00,
-0x44, 0x0C, 0x9A, 0x15, 0x42, 0x77, 0x00, 0xD5, 0x00, 0x77, 0x07, 0x00, 0x49,
-0x41, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
-0x34, 0x00, 0x81, 0x00, 0x34, 0x02, 0x14, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00,
-0x06, 0x03, 0xD0, 0x0C, 0x40, 0x44, 0x28, 0x45, 0x00, 0x04, 0x00, 0x10, 0x04,
-0x40, 0x33, 0x60, 0x85, 0x00, 0x34, 0x03, 0x90, 0x04, 0x40, 0x43, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x36, 0x00, 0xD3, 0x00,
-0x7C, 0x03, 0x10, 0x0D, 0xC0, 0x37, 0x20, 0xDF, 0x00, 0x4D, 0x02, 0xF0, 0x0D,
-0xC0, 0x04, 0x00, 0x01, 0x80, 0x4C, 0x00, 0xB4, 0x05, 0xC0, 0x27, 0x00, 0x97,
-0x00, 0x7C, 0x03, 0x30, 0x09, 0xC0, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xBF, 0x00, 0xBC, 0x02, 0xF1, 0x0F,
-0xC0, 0x2B, 0x10, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0x80, 0x0F, 0x20, 0x7F,
-0x00, 0xFD, 0x00, 0xF0, 0x07, 0xC0, 0x2F, 0x00, 0xBB, 0x40, 0xCC, 0x83, 0xF0,
-0x07, 0xC4, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-0xA0, 0x7F, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70, 0x1B, 0xD0, 0x28, 0x01, 0xA7,
-0x01, 0xFC, 0x32, 0x30, 0x1A, 0xC0, 0x3C, 0x00, 0xB3, 0x14, 0xEC, 0x12, 0x30,
-0x8B, 0xC0, 0x3D, 0x0C, 0xBF, 0x08, 0xCC, 0x02, 0xF1, 0x0F, 0xC0, 0x0F, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x77, 0x00, 0x9D,
-0x01, 0x44, 0x06, 0x10, 0x11, 0x42, 0x64, 0x00, 0x51, 0x01, 0x44, 0x0A, 0x10,
-0x19, 0x40, 0xFC, 0x12, 0x91, 0x02, 0x44, 0x3A, 0x10, 0x49, 0x40, 0xBC, 0x00,
-0x9D, 0x00, 0x44, 0x2A, 0xD0, 0x0D, 0x44, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x31, 0x00, 0xDD, 0x00, 0x44, 0x85, 0x50,
-0x04, 0x48, 0x00, 0x82, 0xD5, 0x00, 0x14, 0x18, 0x50, 0x09, 0x40, 0x32, 0x00,
-0x85, 0x00, 0x34, 0x40, 0x50, 0x88, 0x42, 0x31, 0x24, 0x09, 0x06, 0x04, 0x00,
-0xD0, 0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x03, 0xA0, 0x37, 0x00, 0xDD, 0x11, 0x45, 0x05, 0x10, 0x11, 0x44, 0x44, 0x00,
-0xD1, 0x03, 0x04, 0x8C, 0x11, 0x89, 0x40, 0x36, 0x80, 0x94, 0x41, 0x14, 0x04,
-0x50, 0x19, 0x40, 0x34, 0x00, 0x0D, 0x11, 0x44, 0x0C, 0xD0, 0x0D, 0x20, 0x0F,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00,
-0xCF, 0x01, 0x0C, 0x04, 0x70, 0x10, 0x40, 0x44, 0x20, 0xC7, 0x03, 0x5C, 0x0E,
-0x70, 0x40, 0xD0, 0x32, 0x08, 0x17, 0xA3, 0x7C, 0x96, 0x71, 0x11, 0xC0, 0x35,
-0x10, 0x1F, 0x03, 0x4E, 0x0E, 0xF8, 0x0D, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x80, 0xFC, 0x00,
-0xF0, 0x03, 0xC0, 0x2B, 0x00, 0x7F, 0x00, 0x7C, 0x02, 0xF2, 0x0B, 0xC0, 0x3D,
-0x60, 0x9B, 0x00, 0xEC, 0x02, 0xB0, 0x00, 0xC0, 0x3F, 0x00, 0xBF, 0xA0, 0xFF,
-0x02, 0xF0, 0x0D, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x2A, 0x08, 0x35, 0x00, 0xDF, 0x03, 0x4C, 0x01, 0x30, 0x05, 0xC0, 0x07,
-0x24, 0xD3, 0x04, 0x5C, 0x02, 0x30, 0x21, 0xC0, 0x36, 0x01, 0x17, 0x00, 0x5C,
-0x82, 0xF0, 0x29, 0xC0, 0x76, 0x04, 0x13, 0x02, 0x7C, 0x06, 0x30, 0x0D, 0xC2,
-0xA9, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34,
-0x08, 0xDC, 0x01, 0x46, 0x05, 0x10, 0x41, 0x48, 0x27, 0x00, 0x51, 0x81, 0x44,
-0x02, 0x10, 0x19, 0xC4, 0xBE, 0x00, 0x9B, 0x00, 0x44, 0x02, 0xD1, 0x09, 0x48,
-0xBC, 0x00, 0x11, 0x80, 0x74, 0x22, 0x10, 0x0F, 0x40, 0x4C, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x32, 0x08, 0xCD, 0x00, 0x06,
-0x33, 0x10, 0x04, 0x40, 0x23, 0x02, 0x49, 0x02, 0x14, 0x00, 0x10, 0x2C, 0x51,
-0x33, 0x00, 0x14, 0x00, 0x10, 0x00, 0xD0, 0x00, 0x40, 0xB2, 0x00, 0x81, 0x80,
-0x34, 0x00, 0x11, 0x0C, 0x48, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00, 0xFD, 0x01, 0x84, 0x07, 0x11, 0x12, 0x40,
-0x7B, 0x10, 0x79, 0x11, 0x94, 0x07, 0x10, 0x1F, 0x41, 0x7B, 0x00, 0x6C, 0x01,
-0x94, 0x07, 0xD8, 0x1E, 0x40, 0x70, 0x42, 0xE1, 0x01, 0xB4, 0x07, 0x5C, 0x1E,
-0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10,
-0x32, 0x00, 0xCF, 0x00, 0x04, 0x21, 0x12, 0x84, 0xC0, 0x33, 0x01, 0xCB, 0x00,
-0x1C, 0x21, 0x30, 0x4C, 0xC0, 0x33, 0x00, 0xC7, 0xE8, 0x1C, 0x81, 0xF0, 0x24,
-0xC0, 0x32, 0x02, 0xC3, 0x00, 0x7C, 0x11, 0x30, 0x0C, 0xC0, 0x4B, 0x40, 0x08,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x3D, 0x00, 0xFF, 0x00,
-0xFC, 0x81, 0xF0, 0x83, 0xC0, 0x3F, 0x00, 0xF7, 0x00, 0xEC, 0x03, 0xF0, 0x0F,
-0xCC, 0x3A, 0x00, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0xBF, 0x02, 0xFF,
-0x48, 0xFC, 0x01, 0xB0, 0x0F, 0xC0, 0x08, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0xA2, 0x37, 0x20, 0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x05,
-0xC2, 0x13, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xF0, 0x1D, 0xC0, 0x36, 0x00, 0x5F,
-0x40, 0x7C, 0x01, 0x70, 0x15, 0xC0, 0x34, 0x01, 0x53, 0x01, 0x4D, 0x01, 0x10,
-0x0D, 0xC4, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
-0x98, 0x39, 0x08, 0xED, 0x00, 0x84, 0x01, 0xD0, 0x02, 0x40, 0x3B, 0x00, 0x61,
-0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3A, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0,
-0x07, 0x50, 0xBC, 0x00, 0xF1, 0x00, 0xC4, 0x03, 0x10, 0x4E, 0x40, 0x4F, 0x60,
-0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xFD,
-0x11, 0xA6, 0x05, 0xD0, 0x16, 0x40, 0x5B, 0x04, 0x65, 0x01, 0xB4, 0x05, 0xD0,
-0x0A, 0x50, 0x7A, 0x93, 0x6D, 0x01, 0xB4, 0x05, 0x50, 0x1E, 0x40, 0x78, 0x41,
-0xE5, 0x03, 0x84, 0x07, 0x10, 0x9E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0x4D, 0x12, 0x06, 0xBD, 0xD0,
-0x20, 0x40, 0x33, 0x00, 0x41, 0x01, 0x74, 0x47, 0xD0, 0xEC, 0x40, 0x32, 0x80,
-0xCD, 0x0A, 0x34, 0x2B, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0xC5, 0x00, 0x04, 0x8B,
-0x10, 0x0C, 0x40, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x17, 0xA8, 0x17, 0x00, 0x6F, 0x02, 0xEC, 0x09, 0xF2, 0x07, 0xC0, 0x1B, 0x0A,
-0x77, 0x07, 0xFC, 0x15, 0xF0, 0x06, 0xC0, 0x16, 0x00, 0x7F, 0x21, 0xF4, 0x2D,
-0x78, 0x87, 0xC1, 0x14, 0x00, 0x77, 0x00, 0xCC, 0x39, 0x30, 0x05, 0xC0, 0x5F,
-0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00,
-0x1F, 0x82, 0x7D, 0x00, 0xF3, 0x01, 0x01, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x00,
-0xC0, 0x21, 0xC0, 0x05, 0x20, 0x1F, 0x10, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
-0x00, 0x19, 0x04, 0x7C, 0x08, 0xF4, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x04, 0x5C, 0x0E,
-0xF0, 0x49, 0xC4, 0x24, 0x08, 0x9B, 0x00, 0x4D, 0x02, 0x30, 0x99, 0x02, 0x67,
-0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x97, 0x80, 0x3C,
-0x0E, 0x70, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x1A, 0xD0, 0x78, 0x44, 0x24,
-0x10, 0x81, 0x00, 0x44, 0x02, 0x10, 0x29, 0x44, 0xA4, 0x08, 0x9D, 0x00, 0x74,
-0x82, 0xD1, 0x09, 0x40, 0x67, 0x00, 0x91, 0x80, 0x74, 0x06, 0x10, 0x09, 0x40,
-0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24,
-0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0, 0x0D, 0x44, 0x34, 0x20, 0x99, 0x08, 0x44,
-0x02, 0x10, 0x09, 0x60, 0x27, 0x04, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40,
-0x27, 0x01, 0x95, 0x00, 0x74, 0x42, 0x50, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x20, 0x00, 0xCD, 0x00, 0x04,
-0x02, 0xD0, 0x09, 0x48, 0x20, 0x05, 0x81, 0x00, 0x04, 0x52, 0x10, 0x0C, 0x40,
-0x21, 0x15, 0x8D, 0x14, 0x34, 0x52, 0xD0, 0x48, 0x41, 0x33, 0x05, 0x81, 0x14,
-0x34, 0x52, 0x10, 0x48, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0,
-0x04, 0x01, 0x1B, 0x00, 0x4C, 0x10, 0x34, 0x01, 0xC0, 0x07, 0x21, 0x1F, 0x06,
-0x7C, 0x10, 0xF0, 0x41, 0xC8, 0x07, 0x01, 0x17, 0x04, 0x7C, 0x10, 0x70, 0x01,
-0xC4, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0,
-0x27, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0xF2, 0x0B, 0xD0, 0x2F, 0x00, 0xBF, 0x00,
-0xFC, 0x52, 0xF0, 0x0A, 0xC0, 0x26, 0x00, 0xBF, 0x10, 0xFC, 0x52, 0xF0, 0x4B,
-0xC1, 0x27, 0x05, 0xBF, 0x14, 0xFC, 0x52, 0xF0, 0x69, 0xC3, 0x67, 0x20, 0x0E,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x25, 0x00, 0xBF, 0x00,
-0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x6F, 0x60, 0xB3, 0x00, 0x7C, 0x26, 0xF0, 0x0A,
-0xC0, 0x2D, 0x00, 0x93, 0x02, 0x7C, 0x52, 0x30, 0x39, 0xC1, 0xAF, 0x00, 0x9F,
-0x09, 0xCC, 0x06, 0xF0, 0x5B, 0xE0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00, 0x5D, 0x00, 0x44, 0x00, 0xD0, 0x01,
-0x40, 0x07, 0x00, 0x11, 0x00, 0x74, 0x2C, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x11,
-0x01, 0x74, 0x18, 0x10, 0x21, 0x40, 0x47, 0x09, 0x1D, 0x0B, 0x44, 0x00, 0xD0,
-0x01, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x20, 0x21, 0x00, 0x8D, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0xA3, 0x00, 0x85,
-0x01, 0x34, 0x12, 0xD0, 0x09, 0x40, 0xA3, 0x80, 0x81, 0x26, 0x34, 0x42, 0x14,
-0x08, 0x40, 0xA3, 0x00, 0x8D, 0x04, 0x04, 0x0A, 0xD0, 0x68, 0x41, 0x4B, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D,
-0x00, 0x46, 0x06, 0xD3, 0x19, 0x40, 0x27, 0x04, 0x95, 0x04, 0x76, 0x12, 0xD2,
-0x49, 0x40, 0x24, 0xC0, 0x91, 0x02, 0x74, 0x82, 0x00, 0x09, 0x41, 0x27, 0x00,
-0x9D, 0x02, 0x44, 0x02, 0xD2, 0x09, 0x48, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x8F, 0x02, 0x44, 0x16, 0xF2,
-0x39, 0xC1, 0xA7, 0x00, 0x97, 0x02, 0x7C, 0x16, 0xF2, 0x09, 0xC0, 0x25, 0x00,
-0x93, 0xC2, 0x7C, 0x12, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x09, 0x4D, 0x6E,
-0xD8, 0x09, 0x48, 0x17, 0x28, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x80, 0x25, 0x00, 0x9F, 0x02, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x63, 0x02,
-0x9B, 0xA0, 0x7C, 0x02, 0xF1, 0x19, 0xC0, 0x27, 0x20, 0x9F, 0x05, 0x7C, 0x16,
-0xF0, 0x59, 0xC0, 0x27, 0x00, 0x8F, 0x01, 0x7C, 0x46, 0xF0, 0x09, 0xC0, 0x4B,
-0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00,
-0x1F, 0x04, 0x6C, 0x08, 0xF0, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x08,
-0xF0, 0x01, 0xD0, 0x00, 0x00, 0x17, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC2, 0x04,
-0x04, 0x1F, 0x02, 0x4C, 0x08, 0x30, 0x01, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x7D, 0x02, 0xC4, 0x45,
-0xC2, 0x07, 0x00, 0x1F, 0x20, 0x7D, 0x21, 0x7C, 0x01, 0xD0, 0x16, 0x58, 0x1C,
-0x00, 0x5D, 0x00, 0x74, 0x01, 0xD1, 0x05, 0xC0, 0x1E, 0x04, 0x5D, 0x00, 0xC4,
-0x89, 0x10, 0x05, 0x50, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0xA0, 0x32, 0x00, 0x8D, 0x8B, 0x24, 0x06, 0xC8, 0xCC, 0x00, 0x53,
-0x04, 0x0C, 0x05, 0x34, 0x03, 0xD1, 0xD4, 0x40, 0x40, 0x00, 0xC5, 0x00, 0x74,
-0x03, 0xD0, 0x0C, 0x60, 0x72, 0x00, 0xCD, 0x00, 0x04, 0x0B, 0x15, 0x8C, 0x40,
-0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x38,
-0x00, 0xAD, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40, 0xBB, 0x80, 0x2D, 0x82, 0x94,
-0x03, 0xD0, 0x07, 0x40, 0x88, 0x00, 0xED, 0x24, 0xB4, 0x23, 0xD0, 0x1F, 0x40,
-0x3A, 0x00, 0xFD, 0x80, 0x04, 0x07, 0x12, 0x1E, 0x40, 0x04, 0x20, 0x02, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x79, 0x00, 0xAF, 0x01, 0xAC,
-0x06, 0xF0, 0x1A, 0xC8, 0x5B, 0x00, 0x2F, 0x01, 0xB0, 0x07, 0xF0, 0x12, 0xCA,
-0x78, 0x00, 0xE7, 0xA3, 0xBC, 0x87, 0xF0, 0x7F, 0xC4, 0x5A, 0x00, 0xFF, 0x0F,
-0x89, 0x07, 0x32, 0x1F, 0xC0, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x8F, 0x00, 0x5C, 0x00, 0xF0, 0x09, 0xC0,
-0x37, 0x00, 0x1F, 0x80, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x17, 0x10, 0xDF, 0x00,
-0x7C, 0x0B, 0xF0, 0x2D, 0xC4, 0x37, 0x00, 0xDF, 0xA4, 0x7C, 0x02, 0xF0, 0x0D,
-0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-0x7D, 0x00, 0xBF, 0x01, 0xCC, 0x26, 0xF0, 0x9B, 0xC0, 0x6F, 0x02, 0x33, 0x09,
-0xDC, 0xEF, 0x73, 0x17, 0xC8, 0x5C, 0x22, 0xFD, 0x09, 0xFC, 0x0F, 0xF1, 0x3F,
-0xC0, 0x7F, 0x02, 0xF7, 0x81, 0xDC, 0x05, 0x10, 0x9B, 0xC0, 0x00, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, 0x00, 0xAD, 0x48,
-0x85, 0x22, 0xD0, 0x0A, 0x00, 0x3B, 0x00, 0x21, 0xC0, 0x84, 0xE3, 0x10, 0x86,
-0x41, 0x98, 0x00, 0xED, 0x18, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xE1,
-0x00, 0xF4, 0x11, 0x12, 0xCB, 0x40, 0x55, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x2D, 0x10, 0x84, 0x2A, 0xD8, 0x0A,
-0x61, 0x2B, 0x60, 0x31, 0x50, 0x94, 0x23, 0x51, 0x06, 0x50, 0x3A, 0x98, 0xED,
-0x08, 0xB4, 0x23, 0xD0, 0x0E, 0x41, 0x1B, 0x00, 0xE1, 0x00, 0x94, 0x43, 0x99,
-0x0F, 0x44, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
-0x20, 0x31, 0x00, 0x0D, 0x47, 0x04, 0x00, 0xD8, 0x58, 0x40, 0xB3, 0x02, 0x01,
-0x53, 0x04, 0x07, 0x58, 0x34, 0x40, 0x12, 0x80, 0xCD, 0x41, 0x24, 0x33, 0xD0,
-0x3C, 0x40, 0x23, 0x50, 0xC1, 0x42, 0x34, 0x46, 0x98, 0x0C, 0x40, 0x11, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x10, 0x9D,
-0x00, 0x4C, 0x02, 0xD0, 0x19, 0xC0, 0x93, 0x40, 0x13, 0x01, 0xDC, 0x0B, 0x70,
-0x05, 0xC0, 0x06, 0x00, 0xFF, 0x03, 0xFC, 0x0B, 0xF8, 0x3F, 0xC4, 0x27, 0x00,
-0xF3, 0x0F, 0x5C, 0x02, 0xB4, 0x0D, 0x40, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x22, 0xF0,
-0x09, 0xC0, 0x37, 0x01, 0x9F, 0x00, 0x7C, 0x13, 0x90, 0x45, 0xC0, 0x05, 0x00,
-0xDF, 0x10, 0x74, 0x03, 0xF0, 0x4D, 0xC0, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x00,
-0x70, 0x0D, 0x88, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x84, 0x08, 0x3E, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xC0, 0x03, 0xC8, 0x1F, 0x00,
-0x3B, 0x02, 0x7C, 0x03, 0xF0, 0x07, 0xC0, 0x18, 0x00, 0xFA, 0x00, 0xAC, 0x03,
-0xB0, 0x0F, 0xC8, 0x06, 0x10, 0xEF, 0x00, 0xDC, 0x02, 0xF0, 0x0F, 0x80, 0x13,
-0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00,
-0x9D, 0x01, 0x74, 0x05, 0xD0, 0x11, 0x40, 0x37, 0x00, 0xD1, 0x83, 0x74, 0x03,
-0xD0, 0x14, 0x40, 0x94, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0xC4,
-0x04, 0xDD, 0x00, 0x44, 0x1C, 0xD2, 0x0D, 0x42, 0x17, 0x00, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0x9D, 0x01, 0x74, 0x06,
-0xD0, 0x69, 0x40, 0x27, 0x00, 0x19, 0x10, 0x74, 0x03, 0xD0, 0x35, 0x60, 0x14,
-0x00, 0xD5, 0x00, 0x64, 0x03, 0xD0, 0x0C, 0x60, 0x65, 0x00, 0xDD, 0x20, 0x54,
-0x04, 0xD8, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x28, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x33,
-0x00, 0x00, 0x20, 0x34, 0x83, 0xD0, 0x05, 0x40, 0x10, 0x00, 0xC5, 0x00, 0x34,
-0x03, 0x10, 0x0C, 0x60, 0x20, 0x00, 0xCD, 0x00, 0x06, 0x00, 0xD8, 0x08, 0x40,
-0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x36,
-0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x1B, 0x20, 0xFC,
-0x03, 0xF2, 0x05, 0xD0, 0x14, 0x10, 0xD7, 0x00, 0xEC, 0x03, 0xB0, 0x0F, 0xC0,
-0x04, 0x10, 0xFF, 0x20, 0x5C, 0x02, 0xF0, 0x0D, 0xC8, 0x03, 0xC0, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xA8, 0x3F, 0x00, 0x2F, 0x00, 0xFC,
-0x80, 0xF1, 0x0B, 0xC0, 0x3B, 0x00, 0x2F, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0,
-0x1F, 0x20, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x20, 0xFF, 0x00,
-0xFC, 0x00, 0xF0, 0x0F, 0xE0, 0x17, 0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x03, 0xA0, 0x5F, 0x40, 0xB3, 0x00, 0xFC, 0x12, 0xF0, 0x17, 0xC0,
-0x7F, 0x00, 0x73, 0x81, 0xFC, 0x10, 0xF1, 0xC3, 0xC0, 0x2C, 0x02, 0x33, 0x81,
-0xCC, 0x23, 0x30, 0x0F, 0xC0, 0x48, 0x10, 0xBF, 0x20, 0xFC, 0x05, 0x30, 0x1F,
-0xC0, 0x0C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
-0x77, 0x08, 0x91, 0x4B, 0x74, 0x2E, 0xD2, 0x19, 0x00, 0x7F, 0x00, 0x51, 0x01,
-0x74, 0x2C, 0xD0, 0xE1, 0x40, 0xA4, 0x01, 0x11, 0x01, 0xC4, 0x1B, 0x51, 0xBB,
-0x48, 0x64, 0x00, 0x8D, 0x4E, 0x74, 0x07, 0x10, 0x0F, 0x48, 0x04, 0x60, 0x0C,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x23, 0x00, 0x81, 0x40,
-0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x81, 0x00, 0x34, 0x00, 0xD0, 0x09,
-0x40, 0xA0, 0x80, 0x15, 0x00, 0x04, 0x1B, 0x10, 0x0C, 0x40, 0x00, 0x00, 0x8D,
-0x10, 0x34, 0x82, 0x10, 0x0C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x20, 0xD1, 0x00, 0x74, 0x02, 0xD0, 0x0D,
-0x40, 0x37, 0x00, 0x91, 0x82, 0x74, 0x04, 0xD0, 0x09, 0x48, 0x25, 0x84, 0x11,
-0x01, 0x45, 0x07, 0x53, 0x89, 0x40, 0x64, 0x00, 0x9D, 0x40, 0x34, 0x43, 0x10,
-0x0D, 0x40, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x88, 0x23, 0x00, 0xD3, 0x08, 0x7C, 0x02, 0xF0, 0x0D, 0x44, 0x33, 0x40, 0xD3,
-0x00, 0x7C, 0x0C, 0xF0, 0x88, 0xC0, 0x64, 0x40, 0x13, 0x81, 0x4C, 0x05, 0x30,
-0x1D, 0x90, 0x44, 0x00, 0x9E, 0x40, 0x7C, 0x2D, 0x34, 0x0D, 0xC0, 0x00, 0x20,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0xAD, 0x00, 0xBF,
-0x81, 0xFC, 0x13, 0xD0, 0x4B, 0x48, 0x3F, 0x00, 0xFF, 0x09, 0x7C, 0x00, 0xF0,
-0x1B, 0xC0, 0x6E, 0x2A, 0x3E, 0x10, 0xBC, 0x83, 0xF0, 0x09, 0xC4, 0x2F, 0x28,
-0xBF, 0x00, 0xF4, 0x03, 0xF1, 0x0F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x02, 0xD3, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC0, 0x37, 0x02, 0x93, 0x02, 0x7C, 0x00, 0x34, 0x09, 0xE0, 0x24, 0x20,
-0x1B, 0x01, 0x7C, 0x03, 0x30, 0x0D, 0xC8, 0x04, 0x44, 0xD3, 0x00, 0x4C, 0x02,
-0xF0, 0x0D, 0xC5, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x13, 0xA0, 0x24, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x35, 0x02,
-0x95, 0x00, 0x74, 0x04, 0x10, 0x0B, 0x42, 0x64, 0x04, 0x01, 0x03, 0x5C, 0xAF,
-0x51, 0x18, 0xC0, 0xE6, 0x18, 0xD1, 0x01, 0x6C, 0x03, 0xD0, 0x6D, 0x40, 0x4C,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x12, 0x04,
-0x81, 0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0x33, 0x00, 0x81, 0x00, 0x34, 0x10,
-0x12, 0x00, 0x01, 0x64, 0x88, 0x09, 0x00, 0x34, 0x0F, 0x51, 0xBC, 0x41, 0x81,
-0x10, 0x85, 0x11, 0x04, 0x82, 0xD2, 0x2D, 0x42, 0x1C, 0x00, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x82, 0xA1, 0x21, 0xB4, 0x16,
-0xD0, 0x1A, 0x40, 0x73, 0x08, 0xA5, 0x01, 0xB4, 0x04, 0x18, 0x92, 0x40, 0x68,
-0x08, 0x29, 0x01, 0x14, 0x27, 0x52, 0x1E, 0x64, 0x6F, 0x00, 0xA5, 0x29, 0xA4,
-0x06, 0xD0, 0x1E, 0x40, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x10, 0x20, 0x00, 0xC3, 0x08, 0x3C, 0x02, 0xF0, 0x08, 0x42, 0x33,
-0x02, 0x83, 0x00, 0x34, 0x48, 0x30, 0x08, 0x40, 0x20, 0x01, 0x0B, 0x00, 0x3C,
-0x43, 0x70, 0x0C, 0xC0, 0x01, 0x04, 0x87, 0x50, 0x0A, 0x02, 0xF0, 0x0D, 0xC0,
-0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x29,
-0x40, 0xFF, 0x08, 0xFC, 0x12, 0xF0, 0x0B, 0xC0, 0x7D, 0x08, 0xBF, 0x00, 0xFC,
-0x00, 0xD0, 0x0E, 0x52, 0x2B, 0x00, 0x37, 0x00, 0xFC, 0x0B, 0xF0, 0x0F, 0xE0,
-0x3E, 0x10, 0x9B, 0x00, 0xFC, 0x22, 0xF0, 0x1F, 0xC0, 0x0B, 0x60, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x77, 0x00, 0x93, 0x00, 0x7C,
-0x23, 0x30, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0xFC, 0x00, 0xF0, 0x09, 0xC0,
-0x06, 0x10, 0x93, 0x80, 0x3C, 0x08, 0x34, 0x4D, 0xE1, 0x07, 0x08, 0x9F, 0x01,
-0x4C, 0x02, 0xF0, 0x0D, 0xD0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xA1, 0x04, 0xB4, 0x13, 0x10, 0x0A, 0x40,
-0xBB, 0x28, 0xEC, 0x20, 0xB4, 0x82, 0xD0, 0x6E, 0x48, 0x08, 0x00, 0xA1, 0x00,
-0xB4, 0x02, 0x50, 0x0E, 0x4A, 0x3B, 0x00, 0xBD, 0x40, 0xBC, 0x02, 0xD0, 0x4E,
-0x40, 0x48, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
-0xED, 0x00, 0xE9, 0x09, 0x34, 0x0F, 0x10, 0x1A, 0x40, 0x7B, 0x01, 0xAD, 0x01,
-0xB4, 0x04, 0xD0, 0x18, 0x40, 0x48, 0x00, 0xA1, 0x01, 0xB4, 0x07, 0x90, 0x1E,
-0x40, 0x6B, 0x10, 0xED, 0x01, 0xA4, 0x06, 0xD0, 0x9E, 0x50, 0x0C, 0x00, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0xE3, 0x00, 0xC9, 0x88,
-0x34, 0x07, 0x10, 0x28, 0x41, 0x33, 0x00, 0x8D, 0x23, 0x34, 0x07, 0xD0, 0x0D,
-0x40, 0x14, 0x02, 0xC1, 0x01, 0x34, 0xCB, 0xD0, 0x0C, 0x40, 0x73, 0x04, 0xCD,
-0x00, 0x34, 0x02, 0xD0, 0x0D, 0x50, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x17, 0xA8, 0xDD, 0x20, 0x5B, 0x21, 0x7C, 0x05, 0x34, 0x07,
-0xC0, 0x17, 0x00, 0x7F, 0x03, 0xFC, 0x01, 0xF1, 0x07, 0xC0, 0x5C, 0x40, 0x73,
-0x05, 0xBC, 0x1D, 0xB0, 0x05, 0xC4, 0xDF, 0x21, 0x5F, 0x00, 0xEC, 0x01, 0xF0,
-0x05, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
-0x00, 0x87, 0x41, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F,
-0x08, 0x6C, 0x30, 0xF0, 0x31, 0xD0, 0x45, 0x00, 0x1F, 0x01, 0x7C, 0x00, 0x70,
-0x21, 0xC0, 0x87, 0x10, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x21, 0xC8, 0x4B, 0x00,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x8F,
-0x80, 0x4C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x10, 0x4C, 0x02, 0xF0,
-0x09, 0xC0, 0x66, 0x01, 0x9B, 0x01, 0x4C, 0x02, 0xB0, 0x19, 0xC0, 0x27, 0x00,
-0x9F, 0x04, 0x7C, 0x82, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x01, 0xBD, 0x00, 0x85, 0x02, 0x10,
-0x08, 0xC0, 0x2C, 0x00, 0x9D, 0x00, 0x54, 0x0A, 0xD2, 0x29, 0x40, 0xE4, 0x20,
-0x81, 0x4F, 0x54, 0x02, 0xB0, 0xD9, 0x46, 0xA7, 0x1E, 0x9D, 0x00, 0x34, 0x02,
-0x10, 0x6B, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0xA0, 0x24, 0x80, 0x9D, 0x00, 0x44, 0x62, 0x10, 0x09, 0x40, 0x24, 0x00,
-0x8D, 0x00, 0x40, 0x2A, 0xD0, 0x19, 0x60, 0x26, 0x00, 0xD1, 0x20, 0x44, 0x2A,
-0x80, 0x09, 0x20, 0x37, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x60,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x10,
-0x8D, 0x02, 0x04, 0x02, 0x10, 0x29, 0x40, 0x20, 0x00, 0x8D, 0x02, 0x14, 0x52,
-0xD0, 0x48, 0x41, 0x20, 0x0D, 0x91, 0x20, 0x54, 0x52, 0x98, 0x48, 0x49, 0x23,
-0x00, 0x8D, 0x95, 0x76, 0x0A, 0x10, 0x08, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x01, 0x4C, 0x84,
-0x30, 0x01, 0xD0, 0x44, 0x00, 0x1D, 0x00, 0x4C, 0x10, 0xF0, 0x45, 0xD0, 0x12,
-0x01, 0x13, 0x00, 0x4C, 0x90, 0xB0, 0x41, 0xC0, 0x07, 0x00, 0x1F, 0x24, 0x7C,
-0x00, 0x34, 0x10, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x19, 0xB8, 0x3B, 0x10, 0xBF, 0x03, 0xFC, 0x0A, 0xC0, 0x1F, 0xC0, 0xA5,
-0x00, 0xFF, 0x01, 0xFC, 0x02, 0xF0, 0x4B, 0xC3, 0x2F, 0x45, 0xBF, 0x00, 0xFC,
-0x52, 0x80, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x14, 0xFC, 0x06, 0xF0, 0x69, 0xC1,
-0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F,
-0x00, 0x9F, 0x07, 0xCC, 0x86, 0x34, 0x29, 0xC0, 0x6C, 0x04, 0x8F, 0x00, 0xFC,
-0x06, 0xF0, 0x5F, 0xC0, 0x6C, 0x05, 0xBB, 0x40, 0xCC, 0x06, 0x30, 0x1B, 0xC2,
-0x2C, 0x08, 0xF3, 0x05, 0x4C, 0x0A, 0xF0, 0x7B, 0xC0, 0x64, 0x00, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x01, 0x44,
-0x80, 0x10, 0x11, 0x50, 0x84, 0x00, 0x1D, 0x21, 0x74, 0x20, 0xD0, 0x50, 0xC1,
-0x42, 0x01, 0x11, 0x00, 0x44, 0x6D, 0x50, 0x01, 0x50, 0x04, 0x00, 0x01, 0x55,
-0x44, 0x05, 0xD0, 0x61, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x02, 0x05, 0x0A, 0x10, 0x08, 0x40,
-0x22, 0x00, 0x8D, 0x14, 0x34, 0x02, 0xD0, 0xC8, 0x40, 0x20, 0x05, 0x85, 0x00,
-0x05, 0x92, 0x58, 0x88, 0x40, 0x60, 0x40, 0x81, 0x08, 0x04, 0x82, 0xD0, 0x88,
-0x40, 0x42, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
-0x25, 0x80, 0x8D, 0x01, 0x44, 0x12, 0x10, 0x08, 0x40, 0x26, 0x00, 0x9D, 0x80,
-0x74, 0x22, 0xD0, 0x09, 0x50, 0x26, 0x20, 0x95, 0x08, 0x04, 0x02, 0x58, 0x09,
-0x40, 0x34, 0x02, 0x91, 0x00, 0x45, 0x22, 0xD0, 0x09, 0x40, 0x62, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x67, 0x00, 0xBF, 0x80,
-0x4C, 0x06, 0x30, 0x1B, 0xC0, 0x26, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x49,
-0xC0, 0x64, 0x00, 0x97, 0x00, 0x4C, 0x86, 0x72, 0x09, 0xCA, 0x64, 0x20, 0x93,
-0x21, 0xCC, 0x0E, 0xF0, 0x09, 0xD0, 0x16, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x02, 0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x49,
-0xC0, 0x25, 0x04, 0x9F, 0x03, 0x7C, 0x06, 0xF0, 0x58, 0xD0, 0x27, 0x02, 0x93,
-0x20, 0x7C, 0x22, 0xF0, 0x08, 0xC0, 0x67, 0x00, 0x8F, 0x09, 0x7C, 0x02, 0xD0,
-0x09, 0xC0, 0x51, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
-0x08, 0x05, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x40, 0x13,
-0x02, 0x4D, 0x00, 0x32, 0x21, 0xF0, 0x00, 0x00, 0x13, 0x44, 0x4C, 0x20, 0x34,
-0x41, 0xC0, 0x04, 0x0A, 0x13, 0x00, 0x4C, 0x00, 0xF0, 0x81, 0xC6, 0x50, 0x20,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x5C, 0x00, 0x51,
-0x00, 0xB4, 0x01, 0xD0, 0x05, 0x40, 0x1F, 0x80, 0x51, 0x00, 0xC4, 0x09, 0x50,
-0x27, 0x50, 0x1D, 0x00, 0x61, 0xD2, 0xC4, 0x05, 0x20, 0x07, 0x40, 0x18, 0x00,
-0x75, 0x08, 0x6C, 0x01, 0xD0, 0x17, 0xD0, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x62, 0x00, 0xC9, 0x00, 0x34, 0x02, 0xD0,
-0x0C, 0x40, 0x23, 0x08, 0xC1, 0x00, 0x04, 0x4A, 0x10, 0x3C, 0x49, 0x30, 0x00,
-0xC0, 0x01, 0x05, 0x17, 0x19, 0x28, 0x40, 0x30, 0x84, 0xC1, 0x01, 0x04, 0x03,
-0xD0, 0x19, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0x80, 0xFC, 0x00, 0xE9, 0x04, 0xB4, 0x42, 0xD0, 0x4E, 0x40, 0xFB, 0x00,
-0xF5, 0x25, 0x84, 0x46, 0x50, 0x6E, 0x68, 0x69, 0x21, 0x21, 0x20, 0x84, 0x01,
-0x18, 0x06, 0x41, 0x38, 0x00, 0xE5, 0x10, 0xA6, 0x13, 0xD0, 0x0E, 0x40, 0x12,
-0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x68, 0x00,
-0xEB, 0x07, 0xBC, 0x06, 0xF0, 0x3E, 0xC0, 0x6B, 0x00, 0xE1, 0x03, 0x8C, 0x06,
-0x32, 0x72, 0x40, 0x28, 0x41, 0x23, 0x01, 0x84, 0x07, 0x32, 0x10, 0xC0, 0x78,
-0x00, 0xE3, 0x01, 0x8C, 0x0F, 0xF0, 0x10, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x31, 0x40, 0xD7, 0x00, 0x7C, 0x02,
-0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xDB, 0x00, 0x3C, 0x02, 0xF0, 0x01, 0xD8, 0x27,
-0x02, 0x0F, 0x20, 0x3C, 0x00, 0xF0, 0x01, 0xD2, 0x33, 0x10, 0x5F, 0x12, 0x7C,
-0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA2, 0x6F, 0x00, 0xFF, 0x01, 0xCC, 0x07, 0xF0, 0x1E, 0xC0, 0x6C,
-0x00, 0xEF, 0x01, 0xCC, 0x07, 0x32, 0x1F, 0xC0, 0x78, 0x10, 0x23, 0x01, 0x8C,
-0x05, 0x30, 0x13, 0xC0, 0x7F, 0x08, 0x7F, 0x01, 0xBC, 0x07, 0x30, 0x1F, 0xC0,
-0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29,
-0x00, 0xED, 0x00, 0x84, 0x03, 0xD2, 0x0E, 0x40, 0xA8, 0x00, 0xED, 0x08, 0x84,
-0x03, 0xB0, 0x2F, 0x40, 0x28, 0x01, 0x21, 0x80, 0x94, 0x00, 0x52, 0x02, 0x40,
-0x3B, 0x0A, 0x6D, 0x04, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x57, 0x20, 0x06, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x01, 0x84,
-0x03, 0xD0, 0x1F, 0x40, 0x28, 0x00, 0xFD, 0x01, 0x84, 0x22, 0x10, 0x8E, 0x40,
-0x2C, 0x10, 0x39, 0x08, 0x84, 0x03, 0x10, 0x02, 0x40, 0x3B, 0x00, 0x2D, 0x00,
-0xF4, 0x07, 0x10, 0x06, 0x40, 0x63, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x04, 0x28, 0x23, 0x01, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x0C, 0x41,
-0x20, 0x00, 0xCD, 0x00, 0x06, 0x45, 0x90, 0x1C, 0x40, 0x20, 0x00, 0x09, 0x01,
-0x16, 0x19, 0x50, 0x90, 0x40, 0xB3, 0x00, 0x5D, 0x00, 0x34, 0x6F, 0x10, 0x0C,
-0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8,
-0xA5, 0x00, 0xDF, 0x04, 0x4C, 0x12, 0xF0, 0x0D, 0xD0, 0x24, 0x00, 0xDF, 0x00,
-0x4D, 0x12, 0x30, 0x1B, 0xC0, 0x3C, 0x41, 0x1B, 0x05, 0x4C, 0x01, 0x34, 0x01,
-0xC0, 0x47, 0x12, 0x9F, 0x00, 0x7C, 0x0F, 0x36, 0x01, 0xC8, 0x57, 0x20, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xB7, 0x00, 0xDF, 0x40,
-0x7C, 0x02, 0xF0, 0x8D, 0xC0, 0x33, 0x10, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x80,
-0xC0, 0xA7, 0x00, 0x17, 0x40, 0x7C, 0x08, 0xF1, 0x00, 0xC0, 0xD7, 0x00, 0x1F,
-0x40, 0x7C, 0x03, 0xF0, 0x0D, 0xCC, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x08, 0x6F, 0x00, 0xEF, 0x00, 0x8C, 0x0E, 0x30, 0x0F,
-0xC0, 0x2C, 0x00, 0xF3, 0x00, 0xCC, 0x02, 0xF0, 0x33, 0xC4, 0x0C, 0x00, 0x33,
-0x00, 0xBC, 0x09, 0x30, 0x03, 0xC0, 0x1C, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0x30,
-0x0B, 0xD0, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
-0x20, 0xD6, 0x10, 0xDD, 0x40, 0x44, 0x4A, 0x10, 0x0D, 0x40, 0xF5, 0x50, 0xD1,
-0x00, 0x44, 0x02, 0xD0, 0x31, 0x42, 0x01, 0x08, 0x11, 0x23, 0x74, 0x0D, 0x10,
-0x51, 0xC0, 0xB6, 0x00, 0x1D, 0x61, 0x44, 0x03, 0x11, 0x2D, 0x40, 0x04, 0x02,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA4, 0x01, 0xDD,
-0x00, 0x44, 0x02, 0x10, 0x0C, 0x40, 0x24, 0x02, 0xC1, 0x20, 0x44, 0x03, 0xD0,
-0x0D, 0x40, 0xB4, 0x90, 0x19, 0x51, 0x74, 0x09, 0x10, 0x11, 0x00, 0x14, 0x02,
-0x1D, 0x03, 0x05, 0x83, 0x10, 0x24, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02, 0x14,
-0x0C, 0x40, 0x11, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x04, 0x40, 0x25, 0x00,
-0x01, 0x00, 0x34, 0x01, 0x14, 0x00, 0x60, 0x32, 0x00, 0x1D, 0x00, 0x04, 0x03,
-0x10, 0x0C, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xB0, 0x26, 0x00, 0xEF, 0x00, 0x4D, 0x01, 0x30, 0x0F, 0xC0, 0x24, 0x00,
-0xF3, 0x00, 0x45, 0x02, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x01,
-0x30, 0x01, 0xC0, 0x14, 0x00, 0x3F, 0x00, 0xCC, 0x03, 0x34, 0x0D, 0xC8, 0x04,
-0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00,
-0xFF, 0x00, 0xFC, 0x81, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xBC, 0x01,
-0xE2, 0x07, 0x98, 0x0F, 0x40, 0x3F, 0x40, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x3F,
-0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFB, 0x10, 0x9C, 0x07,
-0xF0, 0x1F, 0xC0, 0x4F, 0x00, 0xBF, 0x01, 0xFC, 0x05, 0xF0, 0x17, 0xC8, 0x2E,
-0x10, 0xBF, 0x04, 0xFC, 0x03, 0x30, 0x1F, 0xC0, 0x7F, 0x08, 0xB6, 0x00, 0xFC,
-0x27, 0x70, 0x02, 0xC0, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x08, 0x77, 0x00, 0xFD, 0x03, 0x44, 0x06, 0x10, 0x1D, 0x40, 0x47,
-0x00, 0xDD, 0x01, 0x74, 0x00, 0x10, 0x1D, 0x40, 0xE4, 0x02, 0x1D, 0x04, 0xF4,
-0x5B, 0x10, 0x01, 0x40, 0x47, 0x08, 0x9D, 0x01, 0x74, 0x03, 0xD0, 0x19, 0x40,
-0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
-0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x03, 0x00, 0x8D, 0x40, 0x74,
-0x51, 0x90, 0x05, 0x48, 0x02, 0x00, 0x0D, 0x12, 0x34, 0x1B, 0x10, 0x4C, 0x49,
-0x33, 0x00, 0x0D, 0x02, 0x34, 0x13, 0xD0, 0x00, 0x40, 0x4E, 0x80, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x20, 0x40,
-0x07, 0x10, 0x0D, 0x40, 0x67, 0x00, 0xDD, 0x23, 0x74, 0x81, 0x14, 0x1D, 0x41,
-0x44, 0x00, 0x1D, 0x01, 0x74, 0x03, 0x14, 0x01, 0x40, 0x07, 0x08, 0x9D, 0x51,
-0x74, 0x03, 0xD0, 0x19, 0x41, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x88, 0x37, 0x00, 0xDF, 0x00, 0x54, 0x1F, 0xF0, 0x0D, 0xC0,
-0x47, 0x00, 0x9F, 0x01, 0x7C, 0x19, 0xF0, 0x14, 0xC0, 0xC6, 0x00, 0x9F, 0x07,
-0x74, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x01, 0x7C, 0x03, 0x79, 0x39,
-0xC0, 0x22, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
-0x3C, 0x00, 0xEF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x40,
-0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x27, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x03,
-0xC4, 0x0F, 0x30, 0x1F, 0x20, 0xFE, 0xA7, 0xF0, 0x0B, 0x40, 0x1F, 0x00, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00,
-0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x5C, 0x49, 0xB0, 0x25,
-0xC0, 0x06, 0x00, 0x9B, 0x00, 0x4E, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0x17,
-0x02, 0x4C, 0x13, 0xF2, 0x29, 0xC5, 0x29, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xFD, 0x00, 0x34, 0x07, 0x10, 0x0D,
-0xC0, 0x07, 0x00, 0xDD, 0x05, 0x04, 0x1D, 0x10, 0x0D, 0x40, 0x64, 0x00, 0x11,
-0x00, 0xEC, 0x63, 0xD0, 0x71, 0x40, 0x84, 0x0B, 0x11, 0x01, 0x44, 0x43, 0xD0,
-0x18, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
-0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x3B, 0x10, 0x0C, 0x40, 0x03, 0x00, 0xCD,
-0x00, 0x14, 0x0B, 0x94, 0x00, 0x42, 0x62, 0x00, 0x89, 0x80, 0x54, 0x07, 0xD0,
-0x4C, 0x40, 0xF1, 0x10, 0x85, 0x00, 0x04, 0x03, 0xD0, 0xB0, 0x40, 0x0D, 0x00,
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x80, 0xED,
-0x41, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x49, 0x30, 0xED, 0xC9, 0x94, 0x06, 0x10,
-0x17, 0x00, 0x78, 0x00, 0xF0, 0x49, 0xB4, 0x07, 0xD0, 0x13, 0x40, 0x48, 0x00,
-0xE1, 0x11, 0x84, 0x07, 0xD0, 0x16, 0x40, 0x3E, 0x20, 0x08, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x01, 0x30,
-0x8C, 0x40, 0x03, 0x00, 0xCF, 0x00, 0x5C, 0x33, 0xB0, 0x00, 0xC0, 0x32, 0x04,
-0x5B, 0x80, 0x14, 0x03, 0xF2, 0x0C, 0xD0, 0x30, 0x03, 0x46, 0x08, 0x0D, 0x03,
-0xF0, 0x00, 0xC0, 0x49, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xB0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC2, 0x37, 0x00,
-0xCF, 0x00, 0x6C, 0xA3, 0xF0, 0x0C, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x6C, 0x43,
-0xF0, 0x80, 0xC0, 0x03, 0x0A, 0xDF, 0x08, 0x7C, 0x23, 0xF0, 0x8D, 0xC0, 0x09,
-0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00,
-0xDF, 0x1E, 0x7C, 0x03, 0x30, 0x0D, 0xC4, 0x07, 0x00, 0xDF, 0x00, 0x5C, 0x01,
-0xF0, 0x15, 0xC0, 0x14, 0x00, 0xDF, 0x00, 0x4C, 0x4F, 0x71, 0x0D, 0xC8, 0x34,
-0x10, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03,
-0x10, 0x0E, 0x48, 0x0B, 0x10, 0xED, 0x00, 0x84, 0x02, 0xD0, 0x0E, 0x40, 0x38,
-0x08, 0xFD, 0x80, 0x04, 0x03, 0x12, 0x02, 0x40, 0x08, 0x04, 0xED, 0x00, 0xB4,
-0x03, 0xD0, 0x06, 0x60, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x01, 0xF4, 0x07, 0x14, 0x1E, 0x40, 0x4B,
-0x00, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x17, 0x50, 0x58, 0x00, 0xED, 0x01, 0x85,
-0x07, 0x50, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x87, 0xD0, 0x1C, 0x40,
-0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33,
-0x00, 0xCD, 0x00, 0x34, 0x4F, 0x90, 0x0C, 0x48, 0xC3, 0x83, 0xCD, 0x12, 0x04,
-0x4B, 0xD0, 0x7C, 0x40, 0xB0, 0x0C, 0xCD, 0x02, 0x04, 0x03, 0x10, 0x01, 0x40,
-0x00, 0x00, 0xCD, 0x88, 0x30, 0x22, 0xD0, 0x1C, 0x40, 0x58, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0xBC,
-0x49, 0x30, 0x05, 0xC2, 0x9F, 0x00, 0x6F, 0x02, 0x9C, 0x09, 0xF0, 0x27, 0xC8,
-0x1C, 0x00, 0x7F, 0x00, 0x4C, 0x01, 0x70, 0x05, 0xD0, 0x14, 0x00, 0x7D, 0x21,
-0x7C, 0x05, 0xD0, 0x27, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0,
-0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x81, 0xC0, 0x07, 0x00, 0x1F, 0x18,
-0x7C, 0x00, 0xF0, 0x23, 0xC0, 0x8F, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0xA1,
-0xD1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08,
-0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x08,
-0x6C, 0x26, 0x71, 0x09, 0xC0, 0x27, 0x00, 0x9E, 0x00, 0x4C, 0x16, 0xF0, 0x09,
-0xC0, 0x25, 0x20, 0x93, 0x38, 0x78, 0x0E, 0xF2, 0x18, 0xC0, 0x40, 0x20, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00,
-0x74, 0x02, 0x11, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x40, 0x44, 0x06, 0x11, 0x09,
-0x44, 0x27, 0x00, 0x9D, 0x80, 0x44, 0x8E, 0xD1, 0x29, 0x40, 0x20, 0x04, 0x91,
-0x01, 0x74, 0x06, 0xD0, 0x89, 0x41, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x12, 0x1C, 0x09,
-0x40, 0x27, 0x00, 0x9D, 0x00, 0x64, 0x42, 0x40, 0x09, 0x42, 0x37, 0x80, 0x8D,
-0x00, 0x44, 0x02, 0xD0, 0x19, 0x41, 0x2D, 0x40, 0x91, 0x00, 0x74, 0x42, 0xD0,
-0x09, 0x40, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x00, 0x20, 0x00, 0x8D, 0x14, 0x74, 0x02, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D,
-0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x23, 0x05, 0x8D, 0x34, 0x04, 0x52, 0xD0,
-0x0A, 0x40, 0x2C, 0x20, 0x81, 0x14, 0x34, 0x02, 0xD0, 0x48, 0x51, 0x50, 0xA0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06, 0x00, 0x1F,
-0x04, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x00, 0x1F, 0x00, 0x6C, 0x00, 0x70,
-0x01, 0xC0, 0x07, 0x21, 0x1F, 0x04, 0x4C, 0x11, 0xF0, 0x01, 0xC0, 0x0D, 0x00,
-0x13, 0xC4, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x19, 0xB0, 0x27, 0x00, 0x9F, 0x00, 0xBC, 0x03, 0xF0,
-0x09, 0xC0, 0x2F, 0x00, 0xEF, 0x80, 0xFC, 0x52, 0xF0, 0x0A, 0xC0, 0x2F, 0x00,
-0xBF, 0x14, 0x7D, 0x52, 0xF0, 0x48, 0xC5, 0x27, 0x00, 0xBF, 0x40, 0xFC, 0x52,
-0xF0, 0x0B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0xA0, 0x27, 0x00, 0x9F, 0x01, 0xFC, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x60,
-0xB3, 0x00, 0x9C, 0x0A, 0x70, 0x09, 0xC0, 0x3D, 0x00, 0x93, 0x02, 0xCC, 0xC6,
-0xF0, 0x2B, 0xC2, 0x2F, 0x00, 0xBF, 0x80, 0xCC, 0x0A, 0xD0, 0x0B, 0xC0, 0x67,
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00,
-0x1D, 0x0A, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x11, 0x00, 0x44, 0x04,
-0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x10, 0xD0, 0x01, 0x40, 0x07,
-0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x74, 0x02,
-0x90, 0x08, 0x40, 0x27, 0x00, 0x81, 0x00, 0x54, 0x02, 0x52, 0x09, 0x40, 0xA1,
-0x00, 0x81, 0x22, 0x04, 0x42, 0xD2, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x02, 0x04,
-0x02, 0xD0, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x06, 0x10, 0x09, 0x40, 0x27,
-0x00, 0x91, 0x00, 0x44, 0x1A, 0x12, 0x29, 0x42, 0x24, 0x40, 0x91, 0x80, 0x45,
-0x82, 0xD0, 0x09, 0x40, 0x27, 0x08, 0x9D, 0x00, 0x44, 0x03, 0xD0, 0x29, 0x40,
-0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27,
-0x00, 0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC4, 0xE3, 0x04, 0x93, 0x02, 0x5C,
-0x0E, 0x70, 0x08, 0xC0, 0xE5, 0x04, 0x92, 0x1B, 0x48, 0x02, 0xE0, 0x09, 0xC0,
-0x27, 0x00, 0x9F, 0x19, 0x4D, 0x06, 0xF0, 0x09, 0xC0, 0x17, 0x28, 0x0E, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x00, 0x7C,
-0x02, 0xF0, 0x09, 0xC4, 0x67, 0x02, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0,
-0x27, 0x01, 0x8F, 0x21, 0x7C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x8F, 0x01,
-0x7C, 0x12, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x6C, 0x08, 0xF0, 0x01, 0xC0,
-0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0x31, 0x21, 0xC8, 0x87, 0x00, 0x1E, 0x02,
-0x7C, 0x00, 0x32, 0x81, 0x81, 0x04, 0x04, 0x1F, 0x80, 0x4C, 0x00, 0x34, 0x01,
-0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0,
-0x14, 0x00, 0x5D, 0x00, 0x84, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x10, 0x6D, 0x80,
-0xB4, 0x05, 0x10, 0x05, 0x40, 0x13, 0x00, 0x5D, 0x00, 0xF4, 0x01, 0x10, 0x27,
-0x40, 0xDC, 0x00, 0x5D, 0x05, 0xC4, 0x61, 0x12, 0x07, 0x40, 0x53, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00,
-0x24, 0x05, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x0C, 0x34, 0x0F, 0x14, 0x0C,
-0x40, 0x33, 0x02, 0xCD, 0x00, 0x34, 0x1F, 0x50, 0x2C, 0x44, 0xD0, 0x20, 0x8D,
-0x00, 0x04, 0x0F, 0x10, 0x2C, 0x41, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x01, 0x84, 0x0B, 0xD0, 0x0E,
-0x40, 0x3B, 0x80, 0xAD, 0x00, 0xF4, 0x43, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xED,
-0x48, 0xB4, 0x47, 0x50, 0x1E, 0x50, 0x38, 0x04, 0xED, 0x00, 0x84, 0x05, 0x10,
-0x2E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0x10, 0x78, 0x00, 0xCF, 0x01, 0xAC, 0x05, 0xF0, 0x1E, 0xC4, 0x7B, 0x10, 0xAF,
-0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x8D, 0xFC, 0x07, 0x70,
-0x17, 0xC0, 0x78, 0x08, 0xEE, 0x01, 0xCD, 0x07, 0x30, 0x1E, 0xC0, 0x47, 0x40,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF,
-0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0,
-0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x42, 0x7C, 0x03, 0xB4, 0x0D, 0xC0, 0x37, 0x00,
-0xCF, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC8, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x85, 0xF0,
-0x1F, 0xC0, 0x7F, 0x02, 0x2F, 0x09, 0x8C, 0x05, 0xF0, 0x9F, 0xC2, 0x6D, 0x02,
-0xFB, 0x09, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x20, 0xFF, 0x01, 0xFC, 0x07,
-0x30, 0x1F, 0xC0, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00,
-0x2D, 0x10, 0x84, 0x01, 0x12, 0x0E, 0x40, 0x38, 0x04, 0xE9, 0x00, 0x84, 0x11,
-0x10, 0x06, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xA4, 0x11, 0x18, 0x0A, 0x40, 0x54,
-0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00,
-0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x39, 0x20, 0x3D, 0x00, 0xC5, 0x01,
-0xD0, 0x0F, 0x09, 0x29, 0x00, 0xED, 0x40, 0x96, 0x83, 0x14, 0x06, 0x40, 0x3B,
-0x02, 0xED, 0x00, 0xF4, 0x83, 0x10, 0x0E, 0x41, 0x22, 0x00, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x33, 0x00, 0xCD, 0x40, 0x34, 0x03,
-0xD0, 0x0C, 0x64, 0xB3, 0x04, 0x0D, 0x07, 0x04, 0x0C, 0x90, 0x3C, 0x40, 0x70,
-0x00, 0xCD, 0x03, 0x04, 0x02, 0x10, 0xA1, 0x44, 0x73, 0x00, 0xCD, 0x02, 0x64,
-0x24, 0x10, 0x10, 0x40, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0xF0, 0x0D, 0xC0, 0x77,
-0x14, 0x9F, 0x03, 0x0C, 0x4E, 0xF0, 0x9D, 0xC0, 0xF5, 0x00, 0xFF, 0x12, 0x78,
-0x00, 0x30, 0x39, 0x40, 0x73, 0x01, 0xDD, 0x10, 0x7C, 0x02, 0x14, 0x1D, 0xC0,
-0x56, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37,
-0x00, 0xDF, 0x00, 0x7C, 0x22, 0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x9F, 0x02, 0x7C,
-0x08, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xDB, 0x04, 0x7C, 0x0A, 0xF0, 0x09, 0xC4,
-0x37, 0x00, 0xDF, 0x30, 0x6C, 0x82, 0xF0, 0x6D, 0xC0, 0xA7, 0x00, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x80, 0xFC,
-0x83, 0xF0, 0x0F, 0xC0, 0x3F, 0x08, 0xBF, 0x00, 0xDC, 0x42, 0x70, 0x0F, 0xC0,
-0x3D, 0x04, 0xDF, 0x40, 0x78, 0x00, 0xE0, 0x03, 0x01, 0x3C, 0x24, 0xF2, 0x80,
-0xFC, 0x00, 0x30, 0x09, 0xE0, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x81, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x1F, 0xD0, 0x0D, 0xC0,
-0x35, 0x00, 0x8D, 0x41, 0x46, 0x16, 0x10, 0x0C, 0x46, 0x24, 0x20, 0xDD, 0x00,
-0x74, 0x0E, 0xD0, 0x19, 0xC1, 0xF6, 0x01, 0xD1, 0x00, 0x74, 0x04, 0x30, 0x41,
-0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0,
-0x34, 0x80, 0xDD, 0x00, 0x74, 0x07, 0xD0, 0x0D, 0x48, 0x35, 0x10, 0x9D, 0x03,
-0x54, 0x06, 0x50, 0x0D, 0x40, 0x25, 0x00, 0xDD, 0x00, 0x54, 0x0C, 0xD0, 0x19,
-0x60, 0x75, 0x10, 0xD5, 0x04, 0x74, 0x06, 0x10, 0x85, 0x40, 0x05, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x80, 0xCD, 0x00,
-0x34, 0x03, 0xD0, 0x0C, 0x42, 0x31, 0x00, 0xDD, 0x20, 0x44, 0x00, 0x18, 0x0D,
-0x40, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x00, 0xD0, 0x09, 0x48, 0x27, 0x80, 0xC5,
-0x00, 0x34, 0x02, 0x93, 0x00, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
-0xC0, 0x35, 0x00, 0x9F, 0x00, 0x54, 0x02, 0x70, 0x0D, 0xC0, 0x25, 0x20, 0xFD,
-0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x35, 0x80, 0xD7, 0x80, 0x7C, 0x02, 0x24,
-0x01, 0xC0, 0x07, 0xC4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
-0xB8, 0x3F, 0x10, 0xFF, 0x20, 0xFC, 0x03, 0xF0, 0x0F, 0xC4, 0x3D, 0x00, 0xBF,
-0x80, 0xF4, 0x02, 0xF2, 0x0E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0,
-0x0B, 0xC0, 0x2E, 0x40, 0xFB, 0x00, 0xBC, 0x02, 0x70, 0x03, 0xC8, 0x17, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x5F, 0x00, 0x7F,
-0x41, 0xFC, 0x85, 0xF0, 0x1B, 0xC0, 0x5C, 0x02, 0xAF, 0x14, 0xCC, 0x04, 0xF0,
-0xC3, 0xC0, 0x0C, 0x04, 0xB3, 0x10, 0xCC, 0x0C, 0x30, 0x8B, 0xC0, 0x3F, 0x00,
-0xB3, 0x14, 0xCC, 0x53, 0x30, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x57, 0x00, 0x9D, 0x01, 0x74, 0x05, 0xD1,
-0x15, 0x44, 0x14, 0x21, 0xFD, 0x03, 0x44, 0x10, 0xD0, 0xE1, 0x00, 0x84, 0x01,
-0xAB, 0x06, 0x44, 0x00, 0x10, 0xE9, 0x40, 0x77, 0x00, 0xB5, 0x06, 0xD4, 0x0F,
-0x10, 0x09, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x11, 0xA0, 0x33, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x20, 0x20,
-0xCD, 0x00, 0x16, 0x40, 0xD2, 0x01, 0x50, 0x04, 0x44, 0x81, 0x10, 0x05, 0x10,
-0x10, 0x00, 0x40, 0x33, 0x00, 0xC1, 0x10, 0x04, 0x03, 0xD0, 0x48, 0x41, 0x44,
-0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x01,
-0x9D, 0x04, 0x74, 0x02, 0xD0, 0x85, 0x40, 0x24, 0x00, 0xDD, 0x00, 0x55, 0x04,
-0xD0, 0x01, 0x46, 0x64, 0x00, 0x99, 0x48, 0x44, 0x04, 0x10, 0x31, 0x48, 0x37,
-0x00, 0xC5, 0x00, 0x54, 0x03, 0xD0, 0x09, 0x40, 0x0C, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA7, 0x01, 0xDF, 0x01, 0x7C, 0x27,
-0xF0, 0x0D, 0xD0, 0x74, 0x12, 0x8F, 0x00, 0x5C, 0x44, 0xF0, 0x20, 0xC1, 0xC0,
-0x00, 0x93, 0x00, 0x4C, 0x14, 0x34, 0x1D, 0xC0, 0x37, 0x00, 0x93, 0x80, 0x4C,
-0x03, 0xF4, 0x39, 0xD0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x07, 0x80, 0x6D, 0x00, 0xBF, 0x01, 0xF8, 0x07, 0xF0, 0x0F, 0xC8, 0x3F,
-0x00, 0xF8, 0x10, 0xEC, 0x00, 0xF0, 0x23, 0xC0, 0x0F, 0x00, 0xBF, 0x00, 0xFC,
-0x40, 0xF0, 0x0F, 0xC0, 0x3B, 0x10, 0x9F, 0x09, 0xB8, 0x83, 0x30, 0x3B, 0xC0,
-0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25,
-0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x80, 0x4C,
-0x00, 0x32, 0x01, 0xD0, 0x8C, 0x00, 0x93, 0x00, 0x4C, 0x00, 0xF0, 0x25, 0xC0,
-0x34, 0x00, 0xD3, 0x04, 0x4D, 0x03, 0xF0, 0x28, 0xC0, 0x0B, 0x20, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0x9C, 0x00, 0x70,
-0x02, 0xD0, 0x0C, 0x60, 0x67, 0x00, 0xDD, 0x03, 0x40, 0x2C, 0x10, 0x03, 0x40,
-0x64, 0x00, 0x91, 0x0F, 0x6D, 0x08, 0x91, 0xB5, 0x40, 0xBC, 0x40, 0xD5, 0x13,
-0xC4, 0x03, 0xC0, 0x49, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x07, 0xA0, 0x22, 0x20, 0x4D, 0x80, 0x34, 0x02, 0xC0, 0x04, 0x48,
-0x63, 0x00, 0x8D, 0x01, 0x24, 0x04, 0x10, 0x08, 0x42, 0x40, 0x00, 0x91, 0x01,
-0x44, 0x04, 0xD1, 0x18, 0x40, 0xB0, 0x04, 0xC1, 0x02, 0x04, 0x03, 0xD0, 0x08,
-0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
-0x68, 0x00, 0xED, 0x21, 0xB4, 0x06, 0xD0, 0x16, 0x40, 0x6B, 0x06, 0xED, 0x11,
-0xA5, 0x44, 0x14, 0x98, 0x50, 0x6C, 0x04, 0xE1, 0x09, 0xA4, 0x04, 0x90, 0x1E,
-0x40, 0x78, 0x02, 0xE5, 0x21, 0x84, 0x07, 0xD1, 0x16, 0x40, 0x13, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0x8F, 0x00,
-0x3C, 0x02, 0xF0, 0x04, 0x40, 0x23, 0x0A, 0xCF, 0x00, 0x6C, 0x00, 0x32, 0x88,
-0xC8, 0x80, 0x40, 0xC3, 0x08, 0x0C, 0x40, 0xF2, 0x8D, 0xD1, 0x30, 0x02, 0xC3,
-0x00, 0x0D, 0x03, 0xF0, 0x04, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xBF, 0x80, 0xF0, 0x02, 0xF0, 0x07,
-0xC0, 0x2F, 0x0A, 0xFF, 0x02, 0xDC, 0x00, 0xF0, 0x8B, 0xD0, 0x3B, 0x42, 0xFF,
-0x08, 0xF4, 0x00, 0xB0, 0x8F, 0xC0, 0x3B, 0x02, 0xFF, 0x00, 0xFC, 0x43, 0xF0,
-0x87, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
-0xA0, 0x67, 0x00, 0xD3, 0x20, 0x7C, 0x07, 0x34, 0x05, 0xC0, 0x70, 0x00, 0x93,
-0x06, 0x5C, 0x00, 0xF0, 0x81, 0xD0, 0x00, 0x10, 0x93, 0x86, 0x4D, 0x04, 0x30,
-0x0D, 0xC0, 0x37, 0x00, 0xD3, 0x04, 0x0D, 0x13, 0x31, 0x05, 0xC0, 0x54, 0x00,
-0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xE1,
-0x00, 0xB4, 0x03, 0x10, 0x06, 0xC0, 0x3A, 0x10, 0xE1, 0x00, 0x84, 0x02, 0xD0,
-0x43, 0x40, 0x29, 0x00, 0xEB, 0x08, 0x84, 0x01, 0x51, 0x0E, 0x40, 0x3B, 0x01,
-0xF1, 0x08, 0x94, 0x43, 0x10, 0x0F, 0xC0, 0x4A, 0x20, 0x06, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x6D, 0x00, 0xA1, 0x01, 0xF6, 0x06, 0x10,
-0x16, 0x40, 0x6C, 0x10, 0xF0, 0x01, 0xB4, 0x04, 0xD0, 0x3A, 0x40, 0x4C, 0x00,
-0xC1, 0x01, 0xC6, 0x04, 0x10, 0x3E, 0x40, 0x73, 0x02, 0xE9, 0x01, 0x84, 0x03,
-0x10, 0x1E, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x12, 0x28, 0x63, 0x00, 0x81, 0x04, 0x36, 0x16, 0x10, 0x14, 0x44, 0x22, 0x02,
-0xC1, 0x00, 0x24, 0x0B, 0xD1, 0x0D, 0x41, 0x30, 0x08, 0xC9, 0x00, 0x04, 0x1F,
-0x50, 0x1D, 0x40, 0x33, 0x10, 0xD9, 0x00, 0x15, 0x03, 0x10, 0xEC, 0x40, 0x4A,
-0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x1D, 0x01,
-0x73, 0x80, 0xFC, 0x05, 0x33, 0xE7, 0xCC, 0xDC, 0x40, 0x53, 0xC0, 0xBC, 0x15,
-0xF1, 0x27, 0xD0, 0x1C, 0x08, 0x53, 0x00, 0xCD, 0x05, 0x32, 0x17, 0xC0, 0x17,
-0x40, 0x5B, 0x00, 0x4C, 0x01, 0x30, 0x37, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x54, 0x1F, 0x00, 0x7C, 0x20,
-0xF0, 0x01, 0xC0, 0x07, 0x24, 0x1F, 0x02, 0x5C, 0x48, 0xF0, 0x01, 0xC0, 0x03,
-0x00, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x20, 0x7C,
-0x80, 0xF0, 0x00, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24,
-0x00, 0x9F, 0x05, 0x4C, 0x0E, 0x30, 0x09, 0xC0, 0x64, 0x20, 0x8A, 0x01, 0x6C,
-0x02, 0xF0, 0x09, 0xC8, 0x60, 0x00, 0x93, 0x00, 0x4C, 0x22, 0xF0, 0x89, 0xC2,
-0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26,
-0x00, 0x9D, 0x00, 0x70, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x8C, 0x00, 0x44,
-0x12, 0x10, 0x09, 0x40, 0x65, 0x08, 0x9B, 0x01, 0x6C, 0x02, 0xD0, 0xA9, 0x41,
-0xE4, 0x01, 0x91, 0x02, 0x45, 0x06, 0xD0, 0x19, 0x40, 0x04, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x20, 0x70,
-0x03, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0x9C, 0x10, 0x44, 0x02, 0x14, 0x09, 0x40,
-0x24, 0x02, 0x9D, 0x48, 0x65, 0x12, 0xD2, 0x09, 0x40, 0x24, 0x42, 0x91, 0x14,
-0x44, 0x82, 0xD0, 0x0D, 0x44, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0xA0, 0x10, 0x8D, 0x02, 0x34, 0x0A, 0xD0, 0x28, 0x40,
-0x21, 0x10, 0x9D, 0x14, 0x46, 0x02, 0x18, 0x48, 0x45, 0x21, 0x45, 0xCD, 0x14,
-0x24, 0x02, 0xD0, 0x48, 0x71, 0x20, 0x85, 0x81, 0x14, 0x04, 0x52, 0xD0, 0x48,
-0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0,
-0x06, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xD0, 0x00, 0x40, 0x04, 0x10, 0x1F, 0x04,
-0x4C, 0x00, 0x30, 0x41, 0xC4, 0x14, 0x21, 0x1F, 0x44, 0x6C, 0x00, 0xF1, 0x41,
-0xC0, 0x04, 0x01, 0x13, 0xC4, 0x4C, 0x10, 0xF0, 0x41, 0xD0, 0x74, 0xC0, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x7B, 0x00, 0xFF, 0x01,
-0xBC, 0x06, 0xF0, 0x1B, 0xC0, 0x2F, 0x05, 0xAE, 0x00, 0xFD, 0x52, 0xF1, 0x4F,
-0xC1, 0x2F, 0x45, 0xBB, 0x14, 0xBC, 0x52, 0xF0, 0x4B, 0xC1, 0x27, 0x40, 0xBF,
-0x14, 0x7C, 0x02, 0xF2, 0x4B, 0xC1, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x19, 0xA0, 0xA7, 0x00, 0x93, 0x02, 0x4C, 0x02, 0x30, 0x28,
-0xC0, 0xAF, 0x00, 0xAF, 0x01, 0xDC, 0x0A, 0xF0, 0x39, 0xC0, 0xED, 0x05, 0xB3,
-0x03, 0xDC, 0x02, 0x32, 0x5B, 0xC1, 0x2C, 0x00, 0xB3, 0x01, 0xCC, 0x06, 0x30,
-0x6A, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
-0x08, 0x47, 0x01, 0x1B, 0x01, 0x6C, 0x14, 0xB0, 0x51, 0x40, 0x47, 0x00, 0x1D,
-0x02, 0x45, 0x04, 0xD1, 0x10, 0x40, 0xC0, 0x00, 0x11, 0x01, 0x45, 0x14, 0x10,
-0x75, 0xC0, 0x07, 0x10, 0x11, 0x05, 0x54, 0x00, 0x10, 0x61, 0x40, 0x70, 0x20,
-0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x81,
-0x20, 0x04, 0x42, 0x10, 0x08, 0x40, 0x23, 0x08, 0x8D, 0x02, 0x14, 0x12, 0xD0,
-0x28, 0x40, 0x21, 0x00, 0x85, 0x02, 0x14, 0x46, 0x10, 0x08, 0x49, 0x21, 0x00,
-0x81, 0x12, 0x04, 0x0A, 0x10, 0x28, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x21, 0x00, 0x89, 0x00, 0x24, 0x42, 0x90,
-0x09, 0x40, 0x27, 0x00, 0x9D, 0x04, 0x44, 0x12, 0xD0, 0x19, 0x40, 0xA4, 0x00,
-0x95, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x90, 0x04, 0x54, 0x02,
-0x10, 0x39, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x05, 0xA8, 0x2F, 0x02, 0xB3, 0x00, 0xCC, 0x0A, 0x30, 0x0B, 0xC0, 0xA7, 0x04,
-0x9F, 0x01, 0x5C, 0x02, 0xF0, 0x29, 0xC8, 0x25, 0x40, 0x97, 0x00, 0x5C, 0x0A,
-0x34, 0x09, 0xC8, 0x25, 0x40, 0x93, 0x00, 0x4D, 0x02, 0x34, 0x29, 0xD0, 0x14,
-0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x00,
-0x9F, 0x03, 0x7C, 0x0A, 0xE0, 0x09, 0xC0, 0xA7, 0x00, 0x8F, 0x00, 0x7C, 0x02,
-0xF0, 0x08, 0xC4, 0x27, 0x01, 0x8B, 0x45, 0x7C, 0x02, 0xF0, 0x98, 0xE0, 0x21,
-0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x00, 0x4D, 0x08,
-0xF0, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x10, 0x6C, 0x00, 0xF0, 0x01, 0xD0, 0x04,
-0x40, 0x13, 0x00, 0x6C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x04, 0x03, 0x80, 0x7C,
-0x00, 0x34, 0x20, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x14, 0xA0, 0x14, 0x10, 0x51, 0x00, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x54,
-0x01, 0x75, 0x02, 0xC4, 0x05, 0xD0, 0x05, 0x50, 0xD8, 0x40, 0x75, 0x00, 0xC4,
-0x11, 0x10, 0x47, 0x50, 0x1C, 0x00, 0x71, 0x00, 0x74, 0x01, 0x10, 0x15, 0x40,
-0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32,
-0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x20, 0x00, 0xC1, 0x0A, 0x24,
-0x26, 0xD0, 0x0C, 0x44, 0xF0, 0x86, 0xC4, 0x09, 0x65, 0x07, 0x50, 0x0C, 0x00,
-0xF0, 0x00, 0xC5, 0x20, 0x34, 0x02, 0x10, 0x1C, 0x40, 0x50, 0x00, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x3C, 0x01, 0xF1, 0x04, 0x84,
-0xA3, 0xD0, 0x1F, 0x40, 0x78, 0x00, 0x25, 0x00, 0x84, 0x00, 0xD0, 0x4E, 0x40,
-0x28, 0x00, 0x65, 0x00, 0x85, 0x13, 0x50, 0x0A, 0x40, 0x90, 0x00, 0xA5, 0x00,
-0xB0, 0x02, 0x10, 0x0F, 0x41, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0xE3, 0x07, 0x8C, 0x17, 0xF0, 0x7E, 0xD0,
-0x6C, 0x00, 0xA3, 0x01, 0xAC, 0x05, 0xF0, 0x3E, 0xC1, 0x68, 0x00, 0x77, 0x01,
-0xED, 0x0F, 0x74, 0x13, 0x84, 0x48, 0x00, 0xA7, 0x01, 0x3C, 0x06, 0x30, 0x1E,
-0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8,
-0x31, 0x40, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x3F, 0x00, 0x9F, 0x00,
-0xFD, 0x00, 0xF0, 0x2D, 0xC0, 0x27, 0x02, 0x5D, 0x00, 0x7C, 0x03, 0x90, 0x01,
-0xC0, 0x07, 0x40, 0x1B, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xD0, 0x43, 0x60, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x04, 0xF3, 0x01,
-0xCC, 0x27, 0x3C, 0x1F, 0xC0, 0x7B, 0x00, 0x37, 0x01, 0xDC, 0x06, 0x72, 0x1F,
-0xC0, 0x6D, 0x00, 0xF7, 0x81, 0xCC, 0x06, 0x31, 0x1B, 0xC0, 0x4C, 0x10, 0xE3,
-0x01, 0xCC, 0x06, 0xF0, 0x1F, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0xE1, 0x00, 0xAC, 0x23, 0x18, 0x4E,
-0x40, 0x3B, 0x00, 0x21, 0x04, 0x84, 0x80, 0xD0, 0x4E, 0x40, 0x2C, 0x00, 0x61,
-0x02, 0x8C, 0x02, 0x10, 0x0A, 0x40, 0x09, 0x00, 0xAB, 0x00, 0x94, 0x02, 0xD0,
-0x0E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x00, 0x79, 0x00, 0xE1, 0x11, 0x84, 0x07, 0x12, 0x1E, 0x40, 0x3B, 0x00, 0x05,
-0x00, 0x90, 0x00, 0x50, 0x0E, 0x44, 0x09, 0x04, 0x3D, 0x10, 0x84, 0x03, 0x10,
-0x02, 0x41, 0x0A, 0x00, 0xA1, 0x00, 0x84, 0x02, 0xD0, 0x2E, 0x40, 0x03, 0x00,
-0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x40, 0xC1,
-0x10, 0x24, 0x03, 0x11, 0x8C, 0x40, 0x33, 0x00, 0x01, 0x00, 0x04, 0x0C, 0xD0,
-0x8C, 0x40, 0x80, 0x01, 0x09, 0x40, 0x24, 0x0F, 0x11, 0x11, 0x44, 0x03, 0x00,
-0x09, 0x00, 0x14, 0x02, 0xD0, 0x0C, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x35, 0x00, 0xD3, 0x00, 0x0C, 0x03, 0x30,
-0x3D, 0xC0, 0x37, 0x00, 0x87, 0x00, 0x5C, 0x1E, 0x70, 0x1F, 0xC0, 0x4D, 0x00,
-0x9F, 0x00, 0xCD, 0x13, 0x34, 0x09, 0xC0, 0x06, 0x08, 0xD3, 0x00, 0x4C, 0x03,
-0xF3, 0x0D, 0xC4, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC1, 0x37, 0x00,
-0x1F, 0x08, 0x7C, 0x40, 0xF0, 0x0D, 0xC4, 0x83, 0x00, 0x47, 0x00, 0x5C, 0x00,
-0xF0, 0x01, 0xC0, 0x85, 0x10, 0xCF, 0x00, 0x3C, 0x03, 0xF0, 0x8D, 0xC4, 0x07,
-0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x3F, 0x00,
-0xFF, 0x00, 0xCC, 0x03, 0x30, 0x0F, 0xC0, 0x3F, 0x00, 0xB3, 0x40, 0xEC, 0x00,
-0x30, 0x0D, 0xC0, 0x4D, 0x00, 0xB3, 0x02, 0xCC, 0x43, 0x10, 0x01, 0x40, 0x04,
-0x00, 0xBF, 0x01, 0xCC, 0x16, 0x30, 0x0F, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xCD, 0x00, 0x44, 0x03,
-0x14, 0x0D, 0x44, 0x73, 0x02, 0x91, 0x01, 0x04, 0x04, 0x14, 0x0D, 0x50, 0x04,
-0x86, 0x51, 0x02, 0x6C, 0x3C, 0x50, 0x31, 0x40, 0xC5, 0x01, 0x1D, 0x01, 0x44,
-0x02, 0xB0, 0x09, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37,
-0x00, 0x11, 0x01, 0x64, 0x06, 0x10, 0x0C, 0x4A, 0x04, 0x00, 0x95, 0x00, 0x04,
-0x02, 0x50, 0x39, 0x40, 0x45, 0x10, 0xDD, 0x04, 0x40, 0x03, 0x11, 0x1D, 0x40,
-0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30,
-0x00, 0xDD, 0x00, 0x45, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x40, 0x01, 0x00, 0x44,
-0x00, 0x10, 0x0C, 0x40, 0x01, 0x80, 0x41, 0x00, 0x24, 0x00, 0x40, 0x00, 0x40,
-0x01, 0x00, 0xCD, 0x00, 0x05, 0x03, 0x80, 0x0C, 0x40, 0x43, 0x80, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3A, 0x10, 0xEF, 0x00, 0x8C,
-0x03, 0x30, 0x0F, 0x40, 0x37, 0x00, 0x13, 0x00, 0x6C, 0x00, 0x38, 0x0F, 0xD0,
-0x04, 0x00, 0x95, 0x00, 0x0D, 0x03, 0x61, 0x01, 0x80, 0x05, 0x20, 0x9F, 0x00,
-0x4D, 0x02, 0x30, 0x0D, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
-0x3F, 0x20, 0x3F, 0x00, 0xFC, 0x00, 0xF1, 0x0F, 0xC0, 0x0E, 0x00, 0x2E, 0x00,
-0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0xF1, 0x0F,
-0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1,
-0x82, 0xC0, 0x0E, 0x02, 0x3B, 0x08, 0xE0, 0x28, 0xB0, 0x83, 0xE0, 0x0E, 0x82,
-0x38, 0x08, 0xEC, 0x20, 0x90, 0x83, 0xC8, 0x0E, 0x02, 0x1B, 0x08, 0xEC, 0x28,
-0xA8, 0x83, 0xA0, 0x0E, 0x02, 0x3A, 0x08, 0xCC, 0x20, 0x98, 0x03, 0x8C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x22, 0xA0, 0x8E, 0xA0,
-0x3A, 0x02, 0xEA, 0x08, 0xA0, 0x23, 0x20, 0x8E, 0xA0, 0x3B, 0x02, 0xEA, 0x08,
-0xA8, 0x23, 0xA0, 0x8E, 0xA0, 0x32, 0x02, 0x4A, 0x08, 0xA8, 0x23, 0x88, 0x8E,
-0x80, 0x3A, 0x02, 0xCA, 0x08, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x18,
-0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04,
-0x01, 0x12, 0x04, 0x48, 0x18, 0x20, 0x41, 0xA0, 0x04, 0x01, 0x12, 0x04, 0x48,
-0x10, 0x20, 0x01, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x21, 0x00, 0x80, 0x02, 0x80, 0x1A, 0x00, 0x68, 0x00, 0xA0, 0x01, 0xA0, 0x0E,
-0x20, 0x1A, 0x00, 0x68, 0x00, 0xA0, 0x01, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x28,
-0x10, 0xA8, 0x01, 0x88, 0x06, 0x80, 0x1A, 0x00, 0x68, 0x00, 0x88, 0x01, 0x04,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x12, 0xA0, 0x4E,
-0x80, 0x3A, 0x01, 0xEA, 0x14, 0xA0, 0x13, 0xA0, 0x4A, 0x80, 0x3A, 0x01, 0xEA,
-0x04, 0xA8, 0x13, 0xA0, 0x4E, 0x82, 0x3A, 0x01, 0xEA, 0x04, 0xA0, 0x13, 0x80,
-0x4A, 0x80, 0x3A, 0x01, 0xEA, 0x0C, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60,
-0x00, 0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00,
-0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00,
-0x60, 0x00, 0x80, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xA3, 0x20, 0x20, 0x04, 0x80, 0x10, 0x01, 0x42, 0x00, 0x08, 0x11, 0x20,
-0x04, 0x80, 0x10, 0x01, 0x42, 0x04, 0x08, 0x11, 0x20, 0xC0, 0x80, 0x10, 0x01,
-0x42, 0x00, 0x00, 0x11, 0x00, 0x04, 0x80, 0x10, 0x01, 0x42, 0x04, 0x08, 0x01,
-0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xD2, 0xA0,
-0x02, 0x01, 0x0A, 0x05, 0x2A, 0x10, 0xA8, 0x50, 0x80, 0x02, 0x01, 0x0A, 0x07,
-0x2A, 0x1C, 0xA8, 0x50, 0xA0, 0x42, 0x83, 0x0A, 0x05, 0x2A, 0x10, 0xA0, 0x50,
-0x88, 0x02, 0x01, 0x0A, 0x05, 0x2A, 0x3C, 0xA0, 0x00, 0x8C, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x80, 0xC8, 0x00, 0xAA, 0x03,
-0xA8, 0x0E, 0x20, 0x38, 0x80, 0xE0, 0x00, 0xAA, 0x07, 0x08, 0x1E, 0xA0, 0x32,
-0x80, 0xCA, 0x00, 0x22, 0x03, 0xA8, 0x0C, 0xA0, 0x3A, 0xA0, 0xCA, 0x00, 0x2A,
-0x03, 0xA8, 0x0C, 0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x21, 0x72, 0x00, 0x48, 0x20, 0x18, 0x80, 0x22, 0x00, 0x00, 0x00,
-0x08, 0x40, 0x20, 0x08, 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0x82, 0x00, 0x20,
-0x00, 0x20, 0x04, 0x80, 0x00, 0x08, 0x42, 0x00, 0x18, 0x00, 0x20, 0x08, 0x00,
-0x82, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x16,
-0x40, 0x18, 0x00, 0x41, 0x00, 0x04, 0x01, 0x1A, 0x04, 0x40, 0x10, 0x20, 0x41,
-0x80, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x61, 0x00, 0x04, 0x01, 0x10,
-0x04, 0x08, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x82, 0x8C, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xA0, 0x06, 0x80, 0x9A,
-0x00, 0x6A, 0x02, 0x28, 0x09, 0xA0, 0x24, 0x00, 0x9B, 0x00, 0x48, 0x02, 0xA8,
-0x01, 0xA0, 0x06, 0x00, 0x1A, 0x00, 0x6A, 0x00, 0xB8, 0x09, 0xA0, 0x06, 0xA0,
-0x1B, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xA3, 0x00, 0xC0, 0x46, 0x00, 0x1A, 0x00, 0x6C, 0x00, 0xBC,
-0x01, 0x90, 0x46, 0x00, 0x1B, 0x00, 0x6C, 0x00, 0xA8, 0x01, 0xC0, 0x06, 0x20,
-0x1B, 0x80, 0x6C, 0x04, 0xA0, 0x01, 0xE8, 0x46, 0x00, 0x1A, 0x00, 0x6C, 0x00,
-0x32, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2,
-0x42, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x08, 0x81,
-0x30, 0x04, 0xC2, 0x10, 0x18, 0x43, 0x28, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x30,
-0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x8C, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x0C, 0x00,
-0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x80, 0x00,
-0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x08,
-0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8, 0x34,
-0x28, 0x43, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8, 0x10, 0x20, 0x43, 0x80, 0x0C,
-0x01, 0x32, 0x04, 0xC8, 0x10, 0x28, 0x43, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8,
-0x10, 0x20, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xA3, 0x42, 0xA0, 0x06, 0x83, 0x1A, 0x04, 0x6A, 0x30, 0xA8, 0x41, 0xA0, 0x06,
-0x83, 0x1A, 0x04, 0x6A, 0x10, 0xA8, 0x41, 0xA0, 0x06, 0x81, 0x1A, 0x04, 0x6A,
-0x30, 0xA8, 0x41, 0x80, 0x0E, 0x83, 0x0A, 0x04, 0x6A, 0x10, 0xA8, 0x01, 0x8C,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x42, 0x00, 0x04,
-0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x30, 0x04, 0xC0,
-0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00,
-0x00, 0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x4A, 0x20, 0x06, 0x81, 0x30, 0x04, 0x62,
-0x12, 0x08, 0x4B, 0x20, 0x06, 0x81, 0xB0, 0x04, 0x62, 0x12, 0x88, 0x41, 0x20,
-0x26, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x43, 0x00, 0x06, 0x81, 0x30, 0x04,
-0x62, 0x12, 0x88, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x23, 0x06, 0xA0, 0x1A, 0x00, 0x62, 0x00, 0xAA, 0x01, 0x20, 0x04, 0xA0,
-0x18, 0x00, 0x62, 0x00, 0x8A, 0x01, 0xA0, 0x06, 0xA0, 0x1A, 0x80, 0x6A, 0x80,
-0xAA, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0xAA, 0x01, 0xA8, 0x02,
-0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x60, 0x80,
-0x82, 0x01, 0x2A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06,
-0x28, 0x18, 0xA0, 0x60, 0x00, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60,
-0xA0, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x00, 0x04, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x80, 0x00, 0x01, 0x02, 0x04,
-0x48, 0x12, 0x20, 0x49, 0xA0, 0x00, 0x01, 0x92, 0x04, 0x48, 0x12, 0x28, 0x41,
-0x80, 0x20, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x88, 0x00, 0x01, 0x02,
-0x04, 0x08, 0x12, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA3, 0x62, 0xC0, 0x8A, 0x01, 0x01, 0x06, 0xAC, 0x18, 0xB0, 0x63,
-0xC0, 0x8A, 0x01, 0x2B, 0x06, 0x8C, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2A,
-0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0x8C, 0x18, 0xB0,
-0x02, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x62,
-0xA0, 0x8E, 0x01, 0x3B, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0xA0, 0x8E, 0x81, 0x3A,
-0x06, 0x68, 0x18, 0x88, 0x63, 0xA0, 0x8E, 0x81, 0x3A, 0x06, 0xEA, 0x18, 0x98,
-0x63, 0x20, 0x8E, 0x81, 0x3B, 0x06, 0xCA, 0x18, 0x88, 0x03, 0x8C, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0x80, 0x8E, 0x01, 0x3A,
-0x06, 0xEC, 0x18, 0xA0, 0x61, 0xC0, 0x8E, 0x01, 0x3A, 0x06, 0xE8, 0x18, 0xA0,
-0x63, 0xE0, 0x8E, 0x01, 0x1B, 0x06, 0xE0, 0x18, 0xA0, 0x63, 0xC0, 0x8E, 0x01,
-0x3A, 0x06, 0xEE, 0x18, 0xB0, 0x03, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xA2, 0x62, 0xA0, 0x8E, 0x81, 0x32, 0x06, 0xEA, 0x18, 0x08,
-0x63, 0xA0, 0x8E, 0xA1, 0x38, 0x86, 0xEA, 0x18, 0x28, 0x61, 0x20, 0x8E, 0x81,
-0x32, 0x86, 0xE8, 0x18, 0xA8, 0x63, 0xA0, 0x8E, 0xA1, 0x30, 0x06, 0xEA, 0x18,
-0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x40, 0x80, 0x04, 0x01, 0x1A, 0x84, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01,
-0x32, 0x04, 0x48, 0x10, 0x22, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10,
-0x20, 0x41, 0x88, 0x04, 0x01, 0x3A, 0x04, 0x48, 0x10, 0x20, 0x01, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x86, 0x81,
-0x1A, 0x06, 0x68, 0x18, 0xA0, 0x61, 0x80, 0x86, 0x81, 0x18, 0x06, 0x68, 0x18,
-0xA0, 0x61, 0x80, 0x84, 0x01, 0x1A, 0x06, 0x68, 0x18, 0xA8, 0x61, 0x80, 0x86,
-0x81, 0x1A, 0x06, 0x6A, 0x18, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xA2, 0x02, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xCA, 0x00,
-0x22, 0x03, 0xA0, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0x80, 0x0E,
-0x80, 0x2A, 0x00, 0xEA, 0x00, 0xA8, 0x03, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xE8,
-0x00, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xA2, 0x42, 0x00, 0x06, 0x01, 0x08, 0x04, 0x40, 0x10, 0x08, 0x41, 0x00, 0x04,
-0x01, 0x00, 0x0C, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x18, 0x04, 0x60,
-0x10, 0x80, 0x41, 0x00, 0x04, 0x01, 0x18, 0x04, 0x60, 0x10, 0x80, 0x01, 0x88,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x20, 0x04,
-0x81, 0x10, 0x04, 0x22, 0x10, 0x88, 0x51, 0x20, 0x06, 0x81, 0x18, 0x05, 0x62,
-0x10, 0x08, 0x41, 0x00, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x0A, 0x41, 0x20,
-0x06, 0x81, 0x10, 0x04, 0x40, 0x10, 0x08, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0xA0, 0x02, 0x01, 0x0A, 0x0C, 0xAA,
-0x30, 0xA8, 0xC2, 0xA0, 0x0A, 0x03, 0x2A, 0x04, 0xAA, 0x30, 0xA8, 0x42, 0xA0,
-0x02, 0x81, 0x0A, 0x04, 0x2A, 0x10, 0xA0, 0xC0, 0xA0, 0x02, 0x21, 0x0A, 0x04,
-0x28, 0x10, 0xA8, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x40, 0x80, 0x0A, 0x03, 0x2A, 0x0C, 0xA8, 0x10, 0xA0, 0x52, 0x80,
-0x0A, 0x03, 0x2A, 0x05, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x0C,
-0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x03, 0x2A, 0x0C, 0xA8, 0x10, 0xA0, 0x02,
-0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
-0x42, 0x00, 0x08, 0x00, 0x20, 0x00, 0x88, 0x01, 0x00, 0x02, 0x00, 0x08, 0x80,
-0x20, 0x00, 0x88, 0x10, 0x00, 0x42, 0x20, 0x08, 0x01, 0x20, 0x04, 0x82, 0x00,
-0x00, 0x42, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x40, 0x00, 0x01, 0x01, 0x04,
-0x04, 0x10, 0x10, 0x41, 0x40, 0x44, 0x01, 0x01, 0x04, 0x04, 0x14, 0x10, 0x40,
-0x40, 0x00, 0x01, 0x01, 0x04, 0x00, 0x10, 0x10, 0x50, 0x40, 0x00, 0x01, 0x01,
-0x04, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xA2, 0x02, 0xE0, 0x06, 0x80, 0x1B, 0x00, 0x68, 0x00, 0xA8, 0x01,
-0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6E, 0x00, 0xA8, 0x01, 0x80, 0x06, 0x80, 0x1A,
-0x00, 0x6E, 0x00, 0xB8, 0x01, 0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xA8,
-0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02,
-0xC0, 0x06, 0x00, 0x3B, 0x00, 0x6C, 0x00, 0xA0, 0x01, 0xC0, 0x06, 0x00, 0x3A,
-0x00, 0x68, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x1A, 0x00, 0x6C, 0x00, 0xA0,
-0x03, 0xC0, 0x06, 0x00, 0x3A, 0x00, 0x4C, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x80, 0x18,
-0x00, 0xC2, 0x00, 0x08, 0x01, 0x28, 0x0C, 0x80, 0x18, 0x80, 0xC0, 0x00, 0x08,
-0x03, 0x20, 0x0C, 0x82, 0x38, 0x00, 0xC2, 0x00, 0x88, 0x01, 0x20, 0x0C, 0x80,
-0x18, 0x00, 0xC2, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x10, 0x00, 0xC0, 0x02, 0x00,
-0x63, 0x00, 0x2C, 0x00, 0x10, 0x00, 0xC2, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00,
-0x10, 0x00, 0xC0, 0x02, 0x00, 0x21, 0x00, 0x2C, 0x00, 0x10, 0x00, 0x40, 0x00,
-0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x20, 0x80, 0x8C, 0x82, 0x32, 0x0A, 0xC8, 0x08, 0x20, 0x21, 0x80, 0x8C, 0x82,
-0x32, 0x02, 0x88, 0x28, 0x20, 0xA3, 0x80, 0x8C, 0x02, 0x22, 0x0A, 0xC8, 0x28,
-0x28, 0xA3, 0x80, 0x8C, 0x82, 0x32, 0x0A, 0xC8, 0x08, 0x20, 0x03, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xA0, 0x16, 0x83,
-0x5A, 0x0C, 0x6A, 0x31, 0xA0, 0xC4, 0xA0, 0x16, 0x83, 0x5A, 0x0C, 0x6A, 0x31,
-0xA8, 0xC5, 0xA0, 0x16, 0x83, 0x4A, 0x0C, 0x6A, 0x31, 0xA8, 0xE5, 0xA0, 0x16,
-0x83, 0x5A, 0x0C, 0x6A, 0x31, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x10, 0x01, 0x40, 0x02,
-0x08, 0x21, 0x00, 0x64, 0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04,
-0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x91, 0x00, 0x24, 0x00, 0x00, 0x00, 0x40,
-0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62, 0x80, 0x8A, 0x01, 0x26, 0x06,
-0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x11, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62,
-0x84, 0x88, 0x01, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62, 0x84, 0x88, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x0A,
-0x08, 0x2A, 0x20, 0xAA, 0x80, 0x88, 0x02, 0xA2, 0x0A, 0x08, 0x2A, 0x20, 0xAA,
-0x00, 0xAA, 0x02, 0xA2, 0x0A, 0x88, 0x28, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA6,
-0x0A, 0x08, 0x2A, 0x20, 0xAA, 0x80, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x42, 0x10, 0x0A, 0x41, 0x28,
-0x44, 0xA1, 0x10, 0x8C, 0x4A, 0x10, 0x2A, 0x41, 0x28, 0x04, 0xA1, 0x10, 0x04,
-0x42, 0x10, 0x0A, 0x41, 0x28, 0x84, 0x81, 0x10, 0x84, 0x4A, 0x10, 0x0A, 0x41,
-0x20, 0x04, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x00, 0x50, 0x80,
-0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05,
-0x08, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x20, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0,
-0xCA, 0x20, 0x2B, 0x03, 0x8C, 0x0C, 0x30, 0x32, 0x40, 0xC0, 0x00, 0x01, 0x03,
-0x88, 0x0C, 0x30, 0x32, 0xC0, 0xCA, 0x00, 0x2B, 0x03, 0xAC, 0x0C, 0xB0, 0x32,
-0x40, 0xC0, 0x00, 0x2B, 0x03, 0xAC, 0x0C, 0xB0, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA4, 0x4E, 0x80, 0x3A, 0x01,
-0xEA, 0x04, 0xB8, 0x13, 0xA0, 0x4E, 0x80, 0x3B, 0x41, 0xEA, 0x04, 0xA8, 0x13,
-0xA0, 0x4E, 0x84, 0x3B, 0x01, 0xEA, 0x04, 0xB8, 0x13, 0xA0, 0x4E, 0x80, 0x3B,
-0x01, 0xE2, 0x44, 0xA8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xC4, 0x10, 0x12, 0x23, 0x08, 0x8C, 0x21, 0x30, 0x80, 0xC0,
-0x10, 0x02, 0x23, 0x08, 0x0C, 0x21, 0x30, 0x84, 0xC4, 0x18, 0x12, 0x43, 0x48,
-0x8C, 0x21, 0x31, 0x82, 0xC0, 0x18, 0x12, 0xA3, 0x48, 0x8C, 0x21, 0x31, 0x84,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
-0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB,
-0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF,
-0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xB4, 0xDF, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xCD, 0xBE,
-0x7C, 0xDB, 0xD0, 0x6C, 0x43, 0xFB, 0x0D, 0xED, 0x37, 0x34, 0xDB, 0xD0, 0x7E,
-0x43, 0xB3, 0x0D, 0xCD, 0xBE, 0x7C, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xED,
-0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xCC, 0x3F, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0x33, 0xBF, 0xFC, 0x3C, 0x32, 0xF3,
-0xC8, 0xFC, 0x23, 0xF3, 0x8F, 0xCC, 0x3C, 0x32, 0xFF, 0xC8, 0xCC, 0x23, 0x33,
-0xBF, 0xFC, 0x3C, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0xF3, 0x8F, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x78, 0x72, 0x7B,
-0x48, 0xEC, 0x27, 0x31, 0x86, 0xC4, 0x78, 0x12, 0x7B, 0x48, 0x8C, 0x27, 0xB1,
-0x9F, 0xDC, 0x7E, 0x72, 0xE3, 0xC9, 0xED, 0x27, 0xB7, 0x87, 0xC4, 0x7E, 0x72,
-0x7B, 0xC8, 0xED, 0x27, 0x37, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x8E, 0x02, 0x39, 0x08, 0xE4, 0x20,
-0x80, 0x83, 0x40, 0x0E, 0x02, 0x39, 0x08, 0xE4, 0x20, 0x90, 0x83, 0x40, 0x0E,
-0x02, 0x39, 0x08, 0xE0, 0x20, 0x90, 0x83, 0x40, 0x8E, 0x02, 0x39, 0x0A, 0xE0,
-0x28, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x20, 0xA0, 0x8E, 0x81, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23, 0xA0, 0x8E,
-0x80, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEA,
-0x08, 0xAA, 0x23, 0xA0, 0x8E, 0x81, 0x3A, 0x06, 0xEA, 0x18, 0xB8, 0x03, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x04,
-0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48,
-0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80,
-0x84, 0x01, 0x12, 0x06, 0x48, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x18, 0x00, 0x60,
-0x00, 0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x20,
-0x06, 0x00, 0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00,
-0x62, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x93, 0x20,
-0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x13, 0x20, 0x4A, 0x80, 0x38, 0x01,
-0xE2, 0x04, 0x88, 0x13, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x03,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00,
-0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01,
-0x00, 0x06, 0x00, 0x18, 0x08, 0x60, 0x28, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x64, 0x80, 0x10, 0x01,
-0x42, 0x0A, 0x08, 0x31, 0x20, 0x44, 0x80, 0x10, 0x01, 0x42, 0x0C, 0x08, 0x09,
-0x20, 0x44, 0x80, 0x90, 0x00, 0x42, 0x04, 0x08, 0x11, 0x20, 0x64, 0x80, 0x90,
-0x00, 0x42, 0x02, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xD4, 0x20, 0x52, 0x81, 0x48, 0x05, 0x22, 0x11, 0x80, 0x54,
-0x20, 0x52, 0x81, 0x48, 0x05, 0x22, 0x15, 0x88, 0x44, 0x00, 0x52, 0x81, 0x48,
-0x04, 0x20, 0x15, 0x88, 0x54, 0x20, 0x52, 0x81, 0x48, 0x0C, 0x20, 0x11, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x30,
-0x00, 0xC8, 0x00, 0x28, 0x03, 0xA0, 0x3C, 0x20, 0x30, 0x00, 0xCA, 0x00, 0x00,
-0x03, 0xA0, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x0C, 0x80,
-0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x04, 0x00, 0x02, 0x08, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x28, 0x00, 0x08,
-0x00, 0x20, 0x0E, 0x80, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x18, 0x80,
-0x18, 0x00, 0x02, 0x00, 0x88, 0x01, 0x60, 0x00, 0x80, 0x00, 0x00, 0x22, 0x00,
-0x88, 0x01, 0x20, 0x0A, 0x08, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x03, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00, 0x04, 0x20, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03,
-0x02, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80,
-0x10, 0x00, 0x62, 0x00, 0x88, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00,
-0x88, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x0C, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x40, 0x06, 0x00,
-0x19, 0x00, 0x64, 0x04, 0x80, 0x01, 0x40, 0x06, 0x00, 0x18, 0x00, 0x64, 0x00,
-0x90, 0x11, 0x00, 0x06, 0x00, 0x19, 0x01, 0x60, 0x00, 0x90, 0x01, 0x40, 0x06,
-0x00, 0x19, 0x01, 0x62, 0x00, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10,
-0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x28, 0x0C,
-0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2,
-0x10, 0x18, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x00, 0x00, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C,
-0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0,
-0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0C,
-0x01, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x00, 0x0C, 0x01, 0x30, 0x04, 0xC0,
-0x10, 0x00, 0xC3, 0x20, 0x0C, 0x01, 0x30, 0x0C, 0xC2, 0x10, 0x00, 0x43, 0x00,
-0x0C, 0x01, 0x30, 0x0C, 0xC2, 0x34, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62,
-0x30, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, 0xC1, 0x20,
-0x06, 0x81, 0x18, 0x0C, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x0C,
-0x60, 0x10, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x80, 0x42, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00,
-0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x10, 0x04,
-0xC0, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0xC0, 0x10, 0x80, 0x01,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x42, 0x20,
-0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x43, 0x20, 0x06, 0x81, 0x18, 0x04,
-0x62, 0x10, 0x88, 0x41, 0x20, 0x0C, 0x81, 0x18, 0x04, 0xC2, 0x10, 0x88, 0x41,
-0x20, 0x06, 0x81, 0x18, 0x04, 0xC0, 0x30, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00,
-0xA2, 0x00, 0x00, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00, 0xA2, 0x00, 0x88, 0x02,
-0x00, 0x08, 0x80, 0x28, 0x00, 0x80, 0x00, 0x88, 0x02, 0x20, 0x0A, 0x80, 0x28,
-0x80, 0x80, 0x00, 0x00, 0x42, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x12, 0x00, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60,
-0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08,
-0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40,
-0x80, 0x00, 0x01, 0x12, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x81, 0x02,
-0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x48, 0x10, 0x20,
-0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x62, 0xC0, 0x8A, 0x01, 0x2B,
-0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0,
-0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01,
-0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x80, 0x62, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x98,
-0x63, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x88, 0x63, 0x40, 0x8E, 0x81,
-0x38, 0x06, 0xE6, 0x18, 0x88, 0x63, 0x20, 0x8E, 0x81, 0x38, 0x86, 0xE6, 0x18,
-0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
-0x62, 0x40, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0xA0, 0x63, 0x40, 0x8E, 0x01,
-0x39, 0x06, 0xE4, 0x18, 0x90, 0x63, 0x00, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18,
-0x90, 0x63, 0x40, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0x80, 0x03, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xA2, 0x62, 0xA0, 0x8E, 0x81,
-0x3A, 0x06, 0xE8, 0x18, 0x88, 0x63, 0xA0, 0x8E, 0xA1, 0x3A, 0x06, 0xEA, 0x18,
-0xA8, 0x63, 0x20, 0x8C, 0x81, 0x3A, 0x06, 0xC2, 0x18, 0xA8, 0x63, 0xA0, 0x8E,
-0x81, 0x3A, 0x06, 0xC2, 0x18, 0x18, 0x43, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x00, 0x48, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x12,
-0x20, 0x4B, 0x80, 0x24, 0x01, 0x12, 0x04, 0x48, 0x12, 0x20, 0x41, 0x80, 0x0E,
-0x01, 0x12, 0x04, 0xE8, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0xE8,
-0x12, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0x00, 0x60, 0x00, 0x86, 0x01, 0x18, 0x06, 0x60, 0x18, 0x88, 0x61, 0x00, 0x86,
-0x01, 0x18, 0x06, 0x60, 0x18, 0x80, 0x61, 0x20, 0x86, 0x01, 0x18, 0x06, 0x62,
-0x18, 0x80, 0x61, 0x00, 0x86, 0x01, 0x18, 0x06, 0x62, 0x18, 0x00, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x06, 0x20, 0x1E,
-0x80, 0x70, 0x00, 0xE2, 0x01, 0x08, 0x07, 0x20, 0x1E, 0x80, 0x70, 0x00, 0xE2,
-0x01, 0x88, 0x07, 0x20, 0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20,
-0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x4A, 0x00, 0x06, 0x01, 0x10, 0x04, 0x60,
-0x12, 0x00, 0x49, 0x00, 0x26, 0x01, 0x10, 0x04, 0x60, 0x12, 0x80, 0x41, 0x00,
-0x06, 0x01, 0x18, 0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x18, 0x04,
-0x40, 0x12, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x80, 0x42, 0x20, 0x04, 0x81, 0x18, 0x04, 0x42, 0x10, 0x88, 0x41, 0x20,
-0x44, 0x81, 0x18, 0x04, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04,
-0x62, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x08, 0x01,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20,
-0x02, 0x83, 0x28, 0x04, 0x22, 0x30, 0x80, 0x42, 0x20, 0x02, 0x83, 0x28, 0x04,
-0x22, 0x10, 0x88, 0x40, 0x00, 0x02, 0x81, 0x08, 0x0C, 0xA0, 0x10, 0x88, 0x40,
-0x20, 0x02, 0x81, 0x08, 0x0C, 0xA0, 0x10, 0x80, 0x00, 0x88, 0x0A, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0A, 0x03, 0x28, 0x0C,
-0xA0, 0x30, 0x80, 0xC2, 0x00, 0x4A, 0x01, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2,
-0x00, 0x0A, 0x03, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28,
-0x0C, 0xA0, 0x10, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0x00, 0x10, 0x00, 0x06, 0x00, 0x08, 0x01, 0x20, 0x00, 0x80, 0x10,
-0x00, 0x02, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08,
-0x00, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x00, 0x20, 0x04, 0x88,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42,
-0x40, 0x40, 0x01, 0x01, 0x04, 0x00, 0x14, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01,
-0x04, 0x04, 0x10, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x04, 0x10, 0x10,
-0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x20, 0x06, 0x80, 0x18,
-0x00, 0x66, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88,
-0x01, 0x60, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x20, 0x06, 0x80,
-0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x02, 0x80, 0x02, 0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x02, 0x80,
-0x0B, 0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x00, 0x90, 0x01, 0x00, 0x0E, 0x00,
-0x98, 0x00, 0xE0, 0x00, 0x90, 0x01, 0x40, 0x06, 0x80, 0x99, 0x00, 0xE0, 0x00,
-0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2,
-0x06, 0x20, 0x1C, 0x80, 0x70, 0x00, 0xC2, 0x01, 0x88, 0x05, 0x20, 0x1C, 0x82,
-0x70, 0x00, 0xC2, 0x01, 0x08, 0x07, 0x20, 0x16, 0x00, 0x70, 0x00, 0x62, 0x01,
-0x08, 0x07, 0x28, 0x1C, 0x00, 0x70, 0x00, 0x62, 0x01, 0x18, 0x01, 0x88, 0x0A,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x80, 0x00, 0x0C, 0x02,
-0x30, 0x0E, 0xC0, 0x20, 0x00, 0xE1, 0x00, 0x0C, 0x02, 0x30, 0x0A, 0xC0, 0x20,
-0x00, 0x83, 0x00, 0x04, 0x02, 0x30, 0x08, 0x40, 0x20, 0x00, 0x83, 0x00, 0x0C,
-0x02, 0x30, 0x0A, 0x40, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0xAC, 0x02, 0xB0, 0x0A, 0xC0, 0x2A,
-0x08, 0xAB, 0x00, 0xAC, 0x02, 0xB0, 0x0A, 0xC0, 0x28, 0x00, 0xA3, 0x20, 0x8C,
-0x02, 0xB0, 0x0A, 0xC2, 0x28, 0x00, 0xA3, 0x00, 0x8C, 0x82, 0xB0, 0x1E, 0xC2,
-0x08, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
-0xA2, 0xC2, 0x20, 0x06, 0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xE1, 0x20, 0x06,
-0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xC1, 0x20, 0x06, 0x83, 0x18, 0x0C, 0x62,
-0x30, 0x88, 0xC1, 0x20, 0x06, 0x03, 0x18, 0x1E, 0x62, 0x30, 0x88, 0x01, 0x88,
-0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x44,
-0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x08, 0x40,
-0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x04, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x22, 0x06, 0x88, 0x18, 0x01, 0x62,
-0x80, 0x88, 0x11, 0x20, 0x06, 0x88, 0x18, 0x01, 0x62, 0x84, 0x88, 0x11, 0x22,
-0x46, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x11, 0x22, 0x46, 0x08, 0x18, 0x40,
-0x62, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0xA2, 0x02, 0x22, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00, 0x80, 0x02, 0x20,
-0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00, 0x88, 0x02, 0x02, 0x0A, 0x88, 0x28, 0x20,
-0xA0, 0x80, 0x88, 0x02, 0x22, 0x0A, 0x08, 0x28, 0x20, 0xA0, 0x40, 0x80, 0x02,
-0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x04,
-0x42, 0x00, 0x28, 0x41, 0x20, 0x04, 0x81, 0x12, 0x04, 0x42, 0x10, 0x0A, 0x41,
-0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, 0x41, 0xA0, 0x04, 0x81, 0x10,
-0x04, 0x42, 0x00, 0x08, 0x00, 0xA0, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05,
-0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05, 0x08, 0x14, 0x20, 0x50,
-0x80, 0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02,
-0x6D, 0x00, 0x94, 0x28, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x02, 0xA2, 0xB2, 0xC0, 0xCA, 0x02, 0x21, 0x0B, 0xAC, 0x2C, 0x10, 0xB2,
-0xC0, 0xCA, 0x02, 0x23, 0x0B, 0xAC, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2A,
-0x0B, 0x84, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2A, 0x2B, 0x84, 0x6C, 0xB0,
-0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12,
-0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x98, 0x13, 0x20, 0x4E, 0x80, 0x38,
-0x01, 0xE2, 0x04, 0x80, 0x13, 0x60, 0x4E, 0x80, 0x39, 0x01, 0xE6, 0x04, 0x88,
-0x13, 0x20, 0x4E, 0x80, 0x38, 0x09, 0xE6, 0x00, 0x89, 0x03, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x02, 0x23, 0x08,
-0x8C, 0x21, 0x30, 0x80, 0xC0, 0x10, 0x02, 0x43, 0x08, 0x8C, 0x21, 0x31, 0x84,
-0xC4, 0x08, 0x12, 0x63, 0x08, 0x8C, 0x20, 0x31, 0x86, 0xC4, 0x18, 0x12, 0x23,
-0x08, 0x8C, 0x20, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF,
-0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF,
-0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF,
-0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xDB, 0xD0, 0xEC,
-0xCB, 0xB7, 0x0D, 0xED, 0x37, 0xFC, 0xDF, 0xD0, 0x6C, 0xC3, 0xB7, 0x0D, 0xED,
-0x37, 0x34, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0,
-0xEC, 0xCB, 0xB7, 0x2F, 0xED, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x3C, 0x32, 0xF3, 0xCB, 0xCF, 0x23, 0xF3,
-0x8F, 0xFC, 0x3F, 0x32, 0xF3, 0xC8, 0xCF, 0x23, 0xF3, 0x8F, 0xCC, 0x3C, 0x32,
-0xF3, 0xC8, 0xCC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xF3, 0xCB, 0xCF, 0x2F,
-0xF3, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xDC, 0x78, 0x12, 0xFB, 0xC9, 0xED, 0x27, 0xB1, 0x87, 0xDC, 0x7E, 0x12,
-0xE3, 0xC9, 0xED, 0x27, 0xB7, 0x9F, 0xDC, 0x1E, 0x72, 0xFB, 0x49, 0xEC, 0x21,
-0xB7, 0x9F, 0xDC, 0x7E, 0x72, 0xFB, 0x49, 0xEC, 0x21, 0x37, 0x86, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x21, 0x00,
-0x85, 0x33, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0xCE,
-0x50, 0x30, 0x43, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x38, 0x43, 0xE1,
-0x0C, 0x85, 0x00, 0x14, 0xCE, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02,
-0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20,
-0x00, 0x80, 0x00, 0x00, 0x02, 0x04, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00, 0x00,
-0x02, 0x00, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10, 0x21,
-0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11,
-0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x18, 0x02,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01,
-0xCE, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x02, 0x00, 0x38, 0x03,
-0xE0, 0x4C, 0x80, 0x00, 0x01, 0xCE, 0x00, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0xCC, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x33, 0x10, 0x00, 0x40, 0x30, 0x03,
-0x01, 0x00, 0x04, 0x33, 0x10, 0xCC, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0xCC, 0x40, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40,
-0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10,
-0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
-0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
-0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x01, 0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x33, 0x01, 0x00, 0x04, 0x30,
-0x13, 0x00, 0x40, 0x00, 0x33, 0x01, 0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
-0x00, 0x01, 0xCC, 0x04, 0x30, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x38,
-0x53, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85,
-0x33, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x00, 0x54,
-0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
-0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
-0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x86, 0x04, 0x08, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84,
-0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
-0x08, 0x00, 0x21, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
-0x84, 0x00, 0x10, 0x86, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x00, 0x00, 0xCE, 0x00,
-0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C,
-0x80, 0x00, 0x00, 0xCE, 0x00, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE,
-0x00, 0x08, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
-0x84, 0x33, 0x10, 0x02, 0x40, 0x38, 0x03, 0x21, 0x00, 0x84, 0x33, 0x10, 0xCE,
-0x40, 0x38, 0x03, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
-0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x00,
-0x10, 0x08, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x00,
-0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x40, 0x08, 0x00, 0x01,
-0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00,
-0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02,
-0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21,
-0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14,
-0x02, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20,
-0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x01,
-0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
-0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11,
-0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10,
-0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00,
-0x02, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00,
-0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00,
-0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10,
-0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x00, 0x04, 0x00,
-0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40,
-0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
-0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
-0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
-0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
-0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04,
-0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
-0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
-0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
-0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85,
-0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x33, 0x15, 0x02, 0x54,
-0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80,
-0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
-0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
-0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
-0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
-0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02,
-0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0x02, 0x00, 0x38, 0x03, 0x20, 0x00,
-0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE,
-0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x43, 0x20,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00,
-0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02,
-0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21,
-0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
-0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
-0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
-0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
-0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
-0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
-0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
-0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
-0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
-0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x04, 0x80,
-0x40, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xC2, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x04, 0x80, 0x40,
-0x40, 0x00, 0x00, 0x0C, 0x00, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-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, 0x00,
-0x00, 0x80, 0x00, 0x00, 0xA4, 0x07, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
-0xC0, 0x0C, 0x00, 0x02, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 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, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x05, 0x80,
-0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x87, 0x5A, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00
-};
diff --git a/drivers/staging/meilhaus/Kconfig b/drivers/staging/meilhaus/Kconfig
deleted file mode 100644
index 923af22..0000000
--- a/drivers/staging/meilhaus/Kconfig
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# Meilhaus configuration
-#
-
-menuconfig MEILHAUS
-	tristate "Meilhaus support"
-	depends on m
-	---help---
-	  If you have a Meilhaus card, say Y (or M) here.
-
-	  You need both this driver, and the driver for the particular
-	  data collection card.
-
-	  To compile this driver as a module, choose M here. The module will
-	  be called memain.
-
-if MEILHAUS
-
-config ME0600
-	tristate "Meilhaus ME-600 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-600 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me0600.
-
-config ME0900
-	tristate "Meilhaus ME-900 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-900 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me0900.
-
-config ME1000
-	tristate "Meilhaus ME-1000 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-1000 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me1000.
-
-config ME1400
-	tristate "Meilhaus ME-1400 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-1400 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me1400.
-
-config ME1600
-	tristate "Meilhaus ME-1600 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-1600 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me1600.
-
-config ME4600
-	tristate "Meilhaus ME-4600 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-4600 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me4600.
-
-config ME6000
-	tristate "Meilhaus ME-6000 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-6000 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me6000.
-
-config ME8100
-	tristate "Meilhaus ME-8100 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-8100 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me8100.
-
-config ME8200
-	tristate "Meilhaus ME-8200 support"
-	default n
-	depends on PCI && m
-	help
-	  This driver supports the Meilhaus ME-8200 family of boards
-	  that do data collection and multipurpose I/O.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called me8200.
-
-config MEDUMMY
-	tristate "Meilhaus dummy driver"
-	default n
-	depends on PCI && m
-	help
-	  This provides a dummy driver for the Meilhaus driver package
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called medummy.
-
-endif # MEILHAUS
diff --git a/drivers/staging/meilhaus/Makefile b/drivers/staging/meilhaus/Makefile
deleted file mode 100644
index 5ab2c1c..0000000
--- a/drivers/staging/meilhaus/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Makefile for Meilhaus linux driver system
-#
-
-obj-$(CONFIG_MEILHAUS) += memain.o
-obj-$(CONFIG_ME1600) += me1600.o
-obj-$(CONFIG_ME1000) += me1000.o
-obj-$(CONFIG_ME1400) += me1400.o
-obj-$(CONFIG_ME4600) += me4600.o
-obj-$(CONFIG_ME6000) += me6000.o
-obj-$(CONFIG_ME0600) += me0600.o
-obj-$(CONFIG_ME8100) += me8100.o
-obj-$(CONFIG_ME8200) += me8200.o
-obj-$(CONFIG_ME0900) += me0900.o
-obj-$(CONFIG_MEDUMMY) += medummy.o
-
-
-me1600-objs := medevice.o medlist.o medlock.o me1600_device.o
-me1600-objs += mesubdevice.o meslist.o meslock.o me1600_ao.o
-
-me1000-objs := medevice.o medlist.o medlock.o me1000_device.o
-me1000-objs += mesubdevice.o meslist.o meslock.o me1000_dio.o
-
-me1400-objs := medevice.o medlist.o medlock.o me1400_device.o
-me1400-objs += mesubdevice.o meslist.o meslock.o me8254.o me8255.o me1400_ext_irq.o
-
-me4600-objs := medevice.o medlist.o medlock.o mefirmware.o me4600_device.o
-me4600-objs += mesubdevice.o meslist.o meslock.o me4600_do.o me4600_di.o me4600_dio.o me8254.o me4600_ai.o me4600_ao.o me4600_ext_irq.o
-
-me6000-objs := medevice.o medlist.o medlock.o mefirmware.o me6000_device.o
-me6000-objs += mesubdevice.o meslist.o meslock.o me6000_dio.o me6000_ao.o
-
-me0600-objs := medevice.o medlist.o medlock.o me0600_device.o
-me0600-objs += mesubdevice.o meslist.o meslock.o me0600_relay.o me0600_ttli.o me0600_optoi.o me0600_dio.o me0600_ext_irq.o
-
-me8100-objs := medevice.o medlist.o medlock.o me8100_device.o
-me8100-objs += mesubdevice.o meslist.o meslock.o me8100_di.o me8100_do.o me8254.o
-
-me8200-objs := medevice.o medlist.o medlock.o me8200_device.o
-me8200-objs += mesubdevice.o meslist.o meslock.o me8200_di.o me8200_do.o me8200_dio.o
-
-me0900-objs := medevice.o medlist.o medlock.o me0900_device.o
-me0900-objs += mesubdevice.o meslist.o meslock.o me0900_do.o me0900_di.o
diff --git a/drivers/staging/meilhaus/TODO b/drivers/staging/meilhaus/TODO
deleted file mode 100644
index d6ce398..0000000
--- a/drivers/staging/meilhaus/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
-TODO:
-	- checkpatch.pl cleanups
-	- sparse issues
-	- Lindent
-	- audit userspace interface
-	- handle firmware properly
-	- possible comedi merge
-
-Please send cleanup patches to Greg Kroah-Hartman <greg@kroah.com>
-and CC: David Kiliani <mail@davidkiliani.de> and Meilhaus Support <support@meilhaus.de>
diff --git a/drivers/staging/meilhaus/me0600_device.c b/drivers/staging/meilhaus/me0600_device.c
deleted file mode 100644
index bae17d2..0000000
--- a/drivers/staging/meilhaus/me0600_device.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * @file me0600_device.c
- *
- * @brief ME-630 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me0600_device.h"
-#include "mesubdevice.h"
-#include "me0600_relay.h"
-#include "me0600_ttli.h"
-#include "me0600_optoi.h"
-#include "me0600_dio.h"
-#include "me0600_ext_irq.h"
-
-me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
-{
-	me0600_device_t *me0600_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	int err;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me0600_device = kmalloc(sizeof(me0600_device_t), GFP_KERNEL);
-
-	if (!me0600_device) {
-		PERROR("Cannot get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(me0600_device, 0, sizeof(me0600_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me0600_device, pci_device);
-
-	if (err) {
-		kfree(me0600_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-
-	/* Get the index in the device version information table. */
-	version_idx =
-	    me0600_versions_get_device_index(me0600_device->base.info.pci.
-					     device_id);
-
-	// Initialize spin lock .
-	spin_lock_init(&me0600_device->dio_ctrl_reg_lock);
-	spin_lock_init(&me0600_device->intcsr_lock);
-
-	// Create subdevice instances.
-
-	for (i = 0; i < me0600_versions[version_idx].optoi_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me0600_optoi_constructor(me0600_device->
-								base.info.pci.
-								reg_bases[2]);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me0600_device);
-			kfree(me0600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me0600_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me0600_versions[version_idx].relay_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me0600_relay_constructor(me0600_device->
-								base.info.pci.
-								reg_bases[2]);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me0600_device);
-			kfree(me0600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me0600_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me0600_versions[version_idx].ttli_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me0600_ttli_constructor(me0600_device->
-							       base.info.pci.
-							       reg_bases[2]);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me0600_device);
-			kfree(me0600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me0600_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me0600_versions[version_idx].dio_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me0600_dio_constructor(me0600_device->
-							      base.info.pci.
-							      reg_bases[2], i,
-							      &me0600_device->
-							      dio_ctrl_reg_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me0600_device);
-			kfree(me0600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me0600_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me0600_versions[version_idx].ext_irq_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *)
-		    me0600_ext_irq_constructor(me0600_device->base.info.pci.
-					       reg_bases[1],
-					       me0600_device->base.info.pci.
-					       reg_bases[2],
-					       &me0600_device->intcsr_lock, i,
-					       me0600_device->base.irq);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me0600_device);
-			kfree(me0600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me0600_device->base.slist,
-					    subdevice);
-	}
-
-	return (me_device_t *) me0600_device;
-}
-EXPORT_SYMBOL(me0600_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me0600_init(void)
-{
-	PDEBUG("executed.\n");
-	return 0;
-}
-
-static void __exit me0600_exit(void)
-{
-	PDEBUG("executed.\n");
-}
-
-module_init(me0600_init);
-
-module_exit(me0600_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me0600_device.h b/drivers/staging/meilhaus/me0600_device.h
deleted file mode 100644
index d93a8ae..0000000
--- a/drivers/staging/meilhaus/me0600_device.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file me0600_device.h
- *
- * @brief ME-630 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_DEVICE_H
-#define _ME0600_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-630 device capabilities.
- */
-typedef struct me0600_version {
-	uint16_t device_id;
-	unsigned int relay_subdevices;
-	unsigned int ttli_subdevices;
-	unsigned int optoi_subdevices;
-	unsigned int dio_subdevices;
-	unsigned int ext_irq_subdevices;
-} me0600_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me0600_version_t me0600_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME0630, 1, 1, 1, 2, 2},
-	{0},
-};
-
-#define ME0600_DEVICE_VERSIONS (sizeof(me0600_versions) / sizeof(me0600_version_t) - 1)	/**< Returns the number of entries in #me0600_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me0600_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me0600_versions.
- */
-static inline unsigned int me0600_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME0600_DEVICE_VERSIONS; i++)
-		if (me0600_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The ME-630 device class structure.
- */
-typedef struct me0600_device {
-	me_device_t base;			/**< The Meilhaus device base class. */
-
-	/* Child class attributes. */
-	spinlock_t dio_ctrl_reg_lock;
-	spinlock_t intcsr_lock;
-} me0600_device_t;
-
-/**
- * @brief The ME-630 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-630 device instance. \n
- *         NULL on error.
- */
-me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_dio.c b/drivers/staging/meilhaus/me0600_dio.c
deleted file mode 100644
index d293035..0000000
--- a/drivers/staging/meilhaus/me0600_dio.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * @file me0600_dio.c
- *
- * @brief ME-630 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_dio_reg.h"
-#include "me0600_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
-					 struct file *filep, int flags)
-{
-	me0600_dio_subdevice_t *instance;
-	uint8_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_dio_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inb(instance->ctrl_reg);
-	mode &= ~(0x3 << (instance->dio_idx * 2));
-	outb(mode, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, mode);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outb(0x00, instance->port_reg);
-	PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0x00);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_dio_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)
-{
-	me0600_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-	int size =
-	    flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
-		     | ME_IO_SINGLE_CONFIG_DIO_WORD |
-		     ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inb(instance->ctrl_reg);
-	switch (size) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-				mode &=
-				    ~((ME0600_DIO_CONFIG_BIT_OUT_0) <<
-				      (instance->dio_idx * 2));
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-				mode &=
-				    ~((ME0600_DIO_CONFIG_BIT_OUT_0) <<
-				      (instance->dio_idx * 2));
-				mode |=
-				    ME0600_DIO_CONFIG_BIT_OUT_0 << (instance->
-								    dio_idx *
-								    2);
-			} else {
-				PERROR
-				    ("Invalid port configuration specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!err) {
-		outb(mode, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, mode);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_dio_io_single_read(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int *value, int time_out, int flags)
-{
-	me0600_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
-					     (instance->dio_idx * 2));
-
-			if ((mode ==
-			     (ME0600_DIO_CONFIG_BIT_OUT_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value =
-				    inb(instance->
-					port_reg) & (0x0001 << channel);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
-					     (instance->dio_idx * 2));
-
-			if ((mode ==
-			     (ME0600_DIO_CONFIG_BIT_OUT_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value = inb(instance->port_reg) & 0x00FF;
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-
-		break;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_dio_io_single_write(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int value, int time_out, int flags)
-{
-	me0600_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-	uint8_t byte;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME0600_DIO_CONFIG_BIT_OUT_0 <<
-			     (instance->dio_idx * 2))) {
-				byte = inb(instance->port_reg);
-
-				if (value)
-					byte |= 0x1 << channel;
-				else
-					byte &= ~(0x1 << channel);
-
-				outb(byte, instance->port_reg);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME0600_DIO_CONFIG_BIT_OUT_0) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME0600_DIO_CONFIG_BIT_OUT_0 <<
-			     (instance->dio_idx * 2))) {
-				outb(value, instance->port_reg);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-
-		break;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_dio_query_number_channels(me_subdevice_t *subdevice,
-					    int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_dio_query_subdevice_type(me_subdevice_t *subdevice,
-					   int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DIO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
-					   int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_DIO_DIR_BYTE;
-	return ME_ERRNO_SUCCESS;
-}
-
-me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t *ctrl_reg_lock)
-{
-	me0600_dio_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me0600_dio_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me0600_dio_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	/* Initialize spin locks. */
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save digital i/o index */
-	subdevice->dio_idx = dio_idx;
-
-	/* Save the subdevice index */
-	subdevice->ctrl_reg = reg_base + ME0600_DIO_CONFIG_REG;
-	subdevice->port_reg = reg_base + ME0600_DIO_PORT_REG + dio_idx;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me0600_dio_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me0600_dio_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me0600_dio_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me0600_dio_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me0600_dio_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me0600_dio_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me0600_dio_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_dio.h b/drivers/staging/meilhaus/me0600_dio.h
deleted file mode 100644
index 5d075c7..0000000
--- a/drivers/staging/meilhaus/me0600_dio.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me0600_dio.h
- *
- * @brief ME-630 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_DIO_H_
-#define _ME0600_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_dio_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-	unsigned int dio_idx;			/**< The index of the digital i/o on the device. */
-
-	unsigned long port_reg;			/**< Register holding the port status. */
-	unsigned long ctrl_reg;			/**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me0600_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_dio_reg.h b/drivers/staging/meilhaus/me0600_dio_reg.h
deleted file mode 100644
index f116ea3..0000000
--- a/drivers/staging/meilhaus/me0600_dio_reg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file me0600_dio_reg.h
- *
- * @brief ME-630 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_DIO_REG_H_
-#define _ME0600_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_DIO_CONFIG_REG		0x0007
-#define ME0600_DIO_PORT_0_REG		0x0008
-#define ME0600_DIO_PORT_1_REG		0x0009
-#define ME0600_DIO_PORT_REG			ME0600_DIO_PORT_0_REG
-
-#define ME0600_DIO_CONFIG_BIT_OUT_0	0x0001
-#define ME0600_DIO_CONFIG_BIT_OUT_1	0x0004
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.c b/drivers/staging/meilhaus/me0600_ext_irq.c
deleted file mode 100644
index 1d09842..0000000
--- a/drivers/staging/meilhaus/me0600_ext_irq.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/**
- * @file me0600_ext_irq.c
- *
- * @brief ME-630 external interrupt subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "meids.h"
-#include "medebug.h"
-
-#include "meplx_reg.h"
-#include "me0600_ext_irq_reg.h"
-#include "me0600_ext_irq.h"
-
-/*
- * Functions
- */
-
-static int me0600_ext_irq_io_irq_start(struct me_subdevice *subdevice,
-				       struct file *filep,
-				       int channel,
-				       int irq_source,
-				       int irq_edge, int irq_arg, int flags)
-{
-	me0600_ext_irq_subdevice_t *instance;
-	uint32_t tmp;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (instance->lintno > 1) {
-		PERROR("Wrong idx=%d.\n", instance->lintno);
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
-		PERROR("Invalid irq source specified.\n");
-		return ME_ERRNO_INVALID_IRQ_SOURCE;
-	}
-
-	if (irq_edge != ME_IRQ_EDGE_RISING) {
-		PERROR("Invalid irq edge specified.\n");
-		return ME_ERRNO_INVALID_IRQ_EDGE;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->intcsr_lock);
-	tmp = inl(instance->intcsr);
-	switch (instance->lintno) {
-	case 0:
-		tmp |=
-		    PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL |
-		    PLX_INTCSR_PCI_INT_EN;
-		break;
-	case 1:
-		tmp |=
-		    PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL |
-		    PLX_INTCSR_PCI_INT_EN;
-		break;
-	}
-	outl(tmp, instance->intcsr);
-	PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
-	spin_unlock(instance->intcsr_lock);
-	instance->rised = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int *irq_count,
-				      int *value, int time_out, int flags)
-{
-	me0600_ext_irq_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->rised <= 0) {
-		instance->rised = 0;
-
-		if (time_out) {
-			t = wait_event_interruptible_timeout(instance->
-							     wait_queue,
-							     (instance->rised !=
-							      0), t);
-
-			if (t == 0) {
-				PERROR("Wait on interrupt timed out.\n");
-				err = ME_ERRNO_TIMEOUT;
-			}
-		} else {
-			wait_event_interruptible(instance->wait_queue,
-						 (instance->rised != 0));
-		}
-
-		if (instance->rised < 0) {
-			PERROR("Wait on interrupt aborted by user.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-	}
-
-	if (signal_pending(current)) {
-		PERROR("Wait on interrupt aborted by signal.\n");
-		err = ME_ERRNO_SIGNAL;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	instance->rised = 0;
-	*irq_count = instance->n;
-	*value = 1;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
-				      struct file *filep,
-				      int channel, int flags)
-{
-	me0600_ext_irq_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t tmp;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (instance->lintno > 1) {
-		PERROR("Wrong idx=%d.\n", instance->lintno);
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->intcsr_lock);
-	tmp = inl(instance->intcsr);
-	switch (instance->lintno) {
-	case 0:
-		tmp &= ~PLX_INTCSR_LOCAL_INT1_EN;
-		break;
-	case 1:
-		tmp &= ~PLX_INTCSR_LOCAL_INT2_EN;
-		break;
-	}
-	outl(tmp, instance->intcsr);
-	PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
-	spin_unlock(instance->intcsr_lock);
-	instance->rised = -1;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
-					     struct file *filep, int flags)
-{
-	me0600_ext_irq_subdevice_t *instance;
-	uint32_t tmp;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->intcsr_lock);
-	tmp = inl(instance->intcsr);
-	switch (instance->lintno) {
-	case 0:
-		tmp |= PLX_INTCSR_LOCAL_INT1_POL | PLX_INTCSR_PCI_INT_EN;
-		tmp &= ~PLX_INTCSR_LOCAL_INT1_EN;
-		break;
-	case 1:
-		tmp |= PLX_INTCSR_LOCAL_INT2_POL | PLX_INTCSR_PCI_INT_EN;
-		tmp &= ~PLX_INTCSR_LOCAL_INT2_EN;
-		break;
-	}
-	outl(tmp, instance->intcsr);
-	PDEBUG_REG("intcsr outl(plx:0x%X)=0x%x\n", instance->intcsr, tmp);
-	spin_unlock(instance->intcsr_lock);
-
-	instance->rised = -1;
-	instance->n = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_query_number_channels(struct me_subdevice *subdevice,
-						int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 1;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
-					       int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_EXT_IRQ;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
-					       int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
-	return ME_ERRNO_SUCCESS;
-}
-
-static void me0600_ext_irq_destructor(struct me_subdevice *subdevice)
-{
-	me0600_ext_irq_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_ext_irq_subdevice_t *) subdevice;
-
-	free_irq(instance->irq, (void *)instance);
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-static irqreturn_t me0600_isr(int irq, void *dev_id)
-{
-	me0600_ext_irq_subdevice_t *instance;
-	uint32_t status;
-	uint32_t mask = PLX_INTCSR_PCI_INT_EN;
-	irqreturn_t ret = IRQ_HANDLED;
-
-	instance = (me0600_ext_irq_subdevice_t *) dev_id;
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	PDEBUG("executed.\n");
-
-	if (instance->lintno > 1) {
-		PERROR_CRITICAL
-		    ("%s():Wrong subdevice index=%d plx:irq_status_reg=0x%04X.\n",
-		     __func__, instance->lintno, inl(instance->intcsr));
-		return IRQ_NONE;
-	}
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->intcsr_lock);
-	status = inl(instance->intcsr);
-	switch (instance->lintno) {
-	case 0:
-		mask |= PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_LOCAL_INT1_EN;
-		break;
-	case 1:
-		mask |= PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_LOCAL_INT2_EN;
-		break;
-	}
-
-	if ((status & mask) == mask) {
-		instance->rised = 1;
-		instance->n++;
-		inb(instance->reset_reg);
-		PDEBUG("Interrupt detected.\n");
-	} else {
-		PINFO
-		    ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n",
-		     jiffies, __func__, status);
-		ret = IRQ_NONE;
-	}
-	spin_unlock(instance->intcsr_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return ret;
-}
-
-me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
-						       uint32_t me0600_reg_base,
-						       spinlock_t *intcsr_lock,
-						       unsigned ext_irq_idx,
-						       int irq)
-{
-	me0600_ext_irq_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me0600_ext_irq_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for 630_ext_irq instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me0600_ext_irq_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->intcsr_lock = intcsr_lock;
-
-	/* Initialize wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	subdevice->lintno = ext_irq_idx;
-
-	/* Request interrupt line */
-	subdevice->irq = irq;
-
-	err = request_irq(subdevice->irq, me0600_isr,
-			  IRQF_DISABLED | IRQF_SHARED,
-			  ME0600_NAME, (void *)subdevice);
-
-	if (err) {
-		PERROR("Cannot get interrupt line.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	PINFO("Registered irq=%d.\n", subdevice->irq);
-
-	/* Initialize registers */
-	subdevice->intcsr = plx_reg_base + PLX_INTCSR;
-	subdevice->reset_reg =
-	    me0600_reg_base + ME0600_INT_0_RESET_REG + ext_irq_idx;
-
-	/* Initialize the subdevice methods */
-	subdevice->base.me_subdevice_io_irq_start = me0600_ext_irq_io_irq_start;
-	subdevice->base.me_subdevice_io_irq_wait = me0600_ext_irq_io_irq_wait;
-	subdevice->base.me_subdevice_io_irq_stop = me0600_ext_irq_io_irq_stop;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me0600_ext_irq_io_reset_subdevice;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me0600_ext_irq_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me0600_ext_irq_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me0600_ext_irq_query_subdevice_caps;
-	subdevice->base.me_subdevice_destructor = me0600_ext_irq_destructor;
-
-	subdevice->rised = 0;
-	subdevice->n = 0;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.h b/drivers/staging/meilhaus/me0600_ext_irq.h
deleted file mode 100644
index f5f2204..0000000
--- a/drivers/staging/meilhaus/me0600_ext_irq.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file me0600_ext_irq.h
- *
- * @brief ME-630 external interrupt implementation.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME0600_EXT_IRQ_H_
-#define _ME0600_EXT_IRQ_H_
-
-#include <linux/sched.h>
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The ME-630 external interrupt subdevice class.
- */
-typedef struct me0600_ext_irq_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *intcsr_lock;		/**< Spin lock to protect #intcsr. */
-
-	wait_queue_head_t wait_queue;		/**< Queue to put on threads waiting for an interrupt. */
-
-	int irq;				/**< The irq number assigned by PCI BIOS. */
-	int rised;				/**< If true an interrupt has occured. */
-	unsigned int n;				/**< The number of interrupt since the driver was loaded. */
-	unsigned int lintno;			/**< The number of the local PCI interrupt. */
-
-	uint32_t intcsr;			/**< The PLX interrupt control and status register. */
-	uint32_t reset_reg;			/**< The control register. */
-} me0600_ext_irq_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 external interrupt instance.
- *
- * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS.
- * @param me0600_reg_base The register base address of the ME-630 device as returned by the PCI BIOS.
- * @param irq The irq assigned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
-						       uint32_t me0600_reg_base,
-						       spinlock_t * intcsr_lock,
-						       unsigned int ext_irq_idx,
-						       int irq);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ext_irq_reg.h b/drivers/staging/meilhaus/me0600_ext_irq_reg.h
deleted file mode 100644
index f6198fa..0000000
--- a/drivers/staging/meilhaus/me0600_ext_irq_reg.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * @file me0600_ext_irq_reg.h
- *
- * @brief ME-630 external interrupt register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME0600_EXT_IRQ_REG_H_
-#define _ME0600_EXT_IRQ_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_INT_0_RESET_REG     0x0005
-#define ME0600_INT_1_RESET_REG     0x0006
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_optoi.c b/drivers/staging/meilhaus/me0600_optoi.c
deleted file mode 100644
index 43f710f..0000000
--- a/drivers/staging/meilhaus/me0600_optoi.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * @file me0600_optoi.c
- *
- * @brief ME-630 Optoisolated input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_optoi_reg.h"
-#include "me0600_optoi.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice,
-					   struct file *filep, int flags)
-{
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	PDEBUG("executed.\n");
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_optoi_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)
-{
-	me0600_optoi_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_optoi_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
-				PERROR("Invalid port direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-
-		break;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_optoi_io_single_read(me_subdevice_t *subdevice,
-				       struct file *filep,
-				       int channel,
-				       int *value, int time_out, int flags)
-{
-	me0600_optoi_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_optoi_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = inb(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inb(instance->port_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_optoi_query_number_channels(me_subdevice_t *subdevice,
-					      int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_optoi_query_subdevice_type(me_subdevice_t *subdevice,
-					     int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DI;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_optoi_query_subdevice_caps(me_subdevice_t *subdevice,
-					     int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base)
-{
-	me0600_optoi_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me0600_optoi_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me0600_optoi_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	/* Initialize spin locks. */
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	/* Save the subdevice index */
-	subdevice->port_reg = reg_base + ME0600_OPTO_INPUT_REG;
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me0600_optoi_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me0600_optoi_io_single_config;
-	subdevice->base.me_subdevice_io_single_read =
-	    me0600_optoi_io_single_read;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me0600_optoi_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me0600_optoi_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me0600_optoi_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_optoi.h b/drivers/staging/meilhaus/me0600_optoi.h
deleted file mode 100644
index e7e69bc..0000000
--- a/drivers/staging/meilhaus/me0600_optoi.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file me0600_optoi.h
- *
- * @brief ME-630 Optoisolated input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_OPTOI_H_
-#define _ME0600_OPTOI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_optoi_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-
-	uint32_t port_reg;			/**< Register holding the port status. */
-} me0600_optoi_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 Optoisolated input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_optoi_reg.h b/drivers/staging/meilhaus/me0600_optoi_reg.h
deleted file mode 100644
index e0bc450..0000000
--- a/drivers/staging/meilhaus/me0600_optoi_reg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file me0600_optoi_reg.h
- *
- * @brief ME-630 Optoisolated input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_OPTOI_REG_H_
-#define _ME0600_OPTOI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_OPTO_INPUT_REG      0x0004
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_relay.c b/drivers/staging/meilhaus/me0600_relay.c
deleted file mode 100644
index 03835e3..0000000
--- a/drivers/staging/meilhaus/me0600_relay.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/**
- * @file me0600_relay.c
- *
- * @brief ME-630 relay subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_relay_reg.h"
-#include "me0600_relay.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_relay_io_reset_subdevice(struct me_subdevice *subdevice,
-					   struct file *filep, int flags)
-{
-	me0600_relay_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_relay_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	outb(0x0, instance->port_0_reg);
-	PDEBUG_REG("port_0_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_0_reg - instance->reg_base, 0);
-	outb(0x0, instance->port_1_reg);
-	PDEBUG_REG("port_1_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_1_reg - instance->reg_base, 0);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_relay_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)
-{
-	me0600_relay_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_relay_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_WORD:
-		if (channel == 0) {
-			if (single_config != ME_SINGLE_CONFIG_DIO_OUTPUT) {
-				PERROR("Invalid word direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-
-		break;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_relay_io_single_read(me_subdevice_t *subdevice,
-				       struct file *filep,
-				       int channel,
-				       int *value, int time_out, int flags)
-{
-	me0600_relay_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_relay_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = inb(instance->port_0_reg) & (0x1 << channel);
-		} else if ((channel >= 8) && (channel < 16)) {
-			*value =
-			    inb(instance->port_1_reg) & (0x1 << (channel - 8));
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inb(instance->port_0_reg);
-		} else if (channel == 1) {
-			*value = inb(instance->port_1_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_WORD:
-		if (channel == 0) {
-			*value = (uint32_t) inb(instance->port_1_reg) << 8;
-			*value |= inb(instance->port_0_reg);
-		} else {
-			PERROR("Invalid word number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_relay_io_single_write(me_subdevice_t *subdevice,
-					struct file *filep,
-					int channel,
-					int value, int time_out, int flags)
-{
-	me0600_relay_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t state;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_relay_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			state = inb(instance->port_0_reg);
-			state =
-			    value ? (state | (0x1 << channel)) : (state &
-								  ~(0x1 <<
-								    channel));
-			outb(state, instance->port_0_reg);
-		} else if ((channel >= 8) && (channel < 16)) {
-			state = inb(instance->port_1_reg);
-			state =
-			    value ? (state | (0x1 << (channel - 8))) : (state &
-									~(0x1 <<
-									  (channel
-									   -
-									   8)));
-			outb(state, instance->port_1_reg);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			outb(value, instance->port_0_reg);
-		} else if (channel == 1) {
-			outb(value, instance->port_1_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_WORD:
-		if (channel == 0) {
-			outb(value, instance->port_0_reg);
-			outb(value >> 8, instance->port_1_reg);
-		} else {
-			PERROR("Invalid word number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-		break;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_relay_query_number_channels(me_subdevice_t *subdevice,
-					      int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 16;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_relay_query_subdevice_type(me_subdevice_t *subdevice,
-					     int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_relay_query_subdevice_caps(me_subdevice_t *subdevice,
-					     int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base)
-{
-	me0600_relay_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me0600_relay_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me0600_relay_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	/* Save the subdevice index */
-	subdevice->port_0_reg = reg_base + ME0600_RELAIS_0_REG;
-	subdevice->port_1_reg = reg_base + ME0600_RELAIS_1_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me0600_relay_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me0600_relay_io_single_config;
-	subdevice->base.me_subdevice_io_single_read =
-	    me0600_relay_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me0600_relay_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me0600_relay_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me0600_relay_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me0600_relay_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_relay.h b/drivers/staging/meilhaus/me0600_relay.h
deleted file mode 100644
index 2ce7dca..0000000
--- a/drivers/staging/meilhaus/me0600_relay.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file me0600_relay.h
- *
- * @brief ME-630 relay subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_RELAY_H_
-#define _ME0600_RELAY_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_relay_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-
-	unsigned long port_0_reg;			/**< Register holding the port status. */
-	unsigned long port_1_reg;			/**< Register holding the port status. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me0600_relay_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 relay subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_relay_subdevice_t *me0600_relay_constructor(uint32_t reg_base);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_relay_reg.h b/drivers/staging/meilhaus/me0600_relay_reg.h
deleted file mode 100644
index ba4db2e..0000000
--- a/drivers/staging/meilhaus/me0600_relay_reg.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @file me0600_relay_reg.h
- *
- * @brief ME-630 relay subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_RELAY_REG_H_
-#define _ME0600_RELAY_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_RELAIS_0_REG        0x0001
-#define ME0600_RELAIS_1_REG        0x0002
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ttli.c b/drivers/staging/meilhaus/me0600_ttli.c
deleted file mode 100644
index 7d970f5..0000000
--- a/drivers/staging/meilhaus/me0600_ttli.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * @file me0600_ttli.c
- *
- * @brief ME-630 TTL input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0600_ttli_reg.h"
-#include "me0600_ttli.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0600_ttli_io_reset_subdevice(struct me_subdevice *subdevice,
-					  struct file *filep, int flags)
-{
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	PDEBUG("executed.\n");
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ttli_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)
-{
-	me0600_ttli_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_ttli_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
-				PERROR("Invalid port direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-
-		break;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_ttli_io_single_read(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int *value, int time_out, int flags)
-{
-	me0600_ttli_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0600_ttli_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = inb(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inb(instance->port_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0600_ttli_query_number_channels(me_subdevice_t *subdevice,
-					     int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ttli_query_subdevice_type(me_subdevice_t *subdevice,
-					    int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DI;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0600_ttli_query_subdevice_caps(me_subdevice_t *subdevice,
-					    int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base)
-{
-	me0600_ttli_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me0600_ttli_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me0600_ttli_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	/* Save the subdevice index */
-	subdevice->port_reg = reg_base + ME0600_TTL_INPUT_REG;
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me0600_ttli_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me0600_ttli_io_single_config;
-	subdevice->base.me_subdevice_io_single_read =
-	    me0600_ttli_io_single_read;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me0600_ttli_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me0600_ttli_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me0600_ttli_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0600_ttli.h b/drivers/staging/meilhaus/me0600_ttli.h
deleted file mode 100644
index 6c90396..0000000
--- a/drivers/staging/meilhaus/me0600_ttli.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file me0600_ttli.h
- *
- * @brief ME-630 TTL input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_TTLI_H_
-#define _ME0600_TTLI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0600_ttli_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-
-	uint32_t port_reg;			/**< Register holding the port status. */
-} me0600_ttli_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-630 TTL input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0600_ttli_subdevice_t *me0600_ttli_constructor(uint32_t reg_base);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0600_ttli_reg.h b/drivers/staging/meilhaus/me0600_ttli_reg.h
deleted file mode 100644
index 4f986d1..0000000
--- a/drivers/staging/meilhaus/me0600_ttli_reg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file me0600_ttli_reg.h
- *
- * @brief ME-630 TTL input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0600_TTLI_REG_H_
-#define _ME0600_TTLI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0600_TTL_INPUT_REG       0x0003
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_device.c b/drivers/staging/meilhaus/me0900_device.c
deleted file mode 100644
index e9c6884..0000000
--- a/drivers/staging/meilhaus/me0900_device.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * @file me0900_device.c
- *
- * @brief ME-9x device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
-*/
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me0900_device.h"
-#include "me0900_reg.h"
-#include "mesubdevice.h"
-#include "me0900_do.h"
-#include "me0900_di.h"
-
-me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
-{
-	me0900_device_t *me0900_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	int err;
-	int i;
-	int port_shift;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me0900_device = kmalloc(sizeof(me0900_device_t), GFP_KERNEL);
-
-	if (!me0900_device) {
-		PERROR("Cannot get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(me0900_device, 0, sizeof(me0900_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me0900_device, pci_device);
-
-	if (err) {
-		kfree(me0900_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-
-	/* Get the index in the device version information table. */
-	version_idx =
-	    me0900_versions_get_device_index(me0900_device->base.info.pci.
-					     device_id);
-
-	/* Initialize 8255 chip to desired mode */
-	if (me0900_device->base.info.pci.device_id ==
-	    PCI_DEVICE_ID_MEILHAUS_ME0940) {
-		outb(0x9B,
-		     me0900_device->base.info.pci.reg_bases[2] +
-		     ME0900_CTRL_REG);
-	} else if (me0900_device->base.info.pci.device_id ==
-		   PCI_DEVICE_ID_MEILHAUS_ME0950) {
-		outb(0x89,
-		     me0900_device->base.info.pci.reg_bases[2] +
-		     ME0900_CTRL_REG);
-		outb(0x00,
-		     me0900_device->base.info.pci.reg_bases[2] +
-		     ME0900_WRITE_ENABLE_REG);
-	} else if (me0900_device->base.info.pci.device_id ==
-		   PCI_DEVICE_ID_MEILHAUS_ME0960) {
-		outb(0x8B,
-		     me0900_device->base.info.pci.reg_bases[2] +
-		     ME0900_CTRL_REG);
-		outb(0x00,
-		     me0900_device->base.info.pci.reg_bases[2] +
-		     ME0900_WRITE_ENABLE_REG);
-	}
-
-	port_shift =
-	    (me0900_device->base.info.pci.device_id ==
-	     PCI_DEVICE_ID_MEILHAUS_ME0960) ? 1 : 0;
-	// Create subdevice instances.
-
-	for (i = 0; i < me0900_versions[version_idx].di_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me0900_di_constructor(me0900_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     i + port_shift);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me0900_device);
-			kfree(me0900_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me0900_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me0900_versions[version_idx].do_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me0900_do_constructor(me0900_device->
-							     base.info.pci.
-							     reg_bases[2], i);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me0900_device);
-			kfree(me0900_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me0900_device->base.slist,
-					    subdevice);
-	}
-
-	return (me_device_t *) me0900_device;
-}
-EXPORT_SYMBOL(me0900_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me0900_init(void)
-{
-	PDEBUG("executed.\n.");
-	return 0;
-}
-
-static void __exit me0900_exit(void)
-{
-	PDEBUG("executed.\n.");
-}
-
-module_init(me0900_init);
-module_exit(me0900_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-9x Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me0900_device.h b/drivers/staging/meilhaus/me0900_device.h
deleted file mode 100644
index bd17f25..0000000
--- a/drivers/staging/meilhaus/me0900_device.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file me0900_device.h
- *
- * @brief ME-0900 (ME-9x) device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0900_DEVICE_H
-#define _ME0900_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-0900 (ME-9x) device capabilities.
- */
-typedef struct me0900_version {
-	uint16_t device_id;
-	unsigned int di_subdevices;
-	unsigned int do_subdevices;
-} me0900_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me0900_version_t me0900_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME0940, 2, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME0950, 0, 2},
-	{PCI_DEVICE_ID_MEILHAUS_ME0960, 1, 1},
-	{0},
-};
-
-#define ME0900_DEVICE_VERSIONS (sizeof(me0900_versions) / sizeof(me0900_version_t) - 1)	/**< Returns the number of entries in #me0900_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me0900_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me0900_versions.
- */
-static inline unsigned int me0900_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME0900_DEVICE_VERSIONS; i++)
-		if (me0900_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The ME-0900 (ME-9x) device class structure.
- */
-typedef struct me0900_device {
-	me_device_t base;			/**< The Meilhaus device base class. */
-} me0900_device_t;
-
-/**
- * @brief The ME-9x device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-0900 (ME-9x) device instance. \n
- *         NULL on error.
- */
-me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_di.c b/drivers/staging/meilhaus/me0900_di.c
deleted file mode 100644
index b8c448f..0000000
--- a/drivers/staging/meilhaus/me0900_di.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/**
- * @file me0900_di.c
- *
- * @brief ME-9x digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "meplx_reg.h"
-#include "me0900_reg.h"
-#include "me0900_di.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0900_di_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	PDEBUG("executed.\n");
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_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)
-{
-	me0900_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0900_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-			} else {
-				PERROR("Invalid byte direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0900_di_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me0900_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0900_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = (~inb(instance->port_reg)) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = ~inb(instance->port_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0900_di_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_di_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DI;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-me0900_di_subdevice_t *me0900_di_constructor(uint32_t reg_base,
-					     unsigned int di_idx)
-{
-	me0900_di_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me0900_di_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me0900_di_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	/* Save the subdevice index. */
-	subdevice->di_idx = di_idx;
-
-	/* Initialize registers */
-	if (di_idx == 0) {
-		subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
-		subdevice->port_reg = reg_base + ME0900_PORT_A_REG;
-	} else {
-		subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
-		subdevice->port_reg = reg_base + ME0900_PORT_B_REG;
-	}
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me0900_di_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me0900_di_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me0900_di_io_single_read;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me0900_di_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me0900_di_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me0900_di_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0900_di.h b/drivers/staging/meilhaus/me0900_di.h
deleted file mode 100644
index 014f134..0000000
--- a/drivers/staging/meilhaus/me0900_di.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file me0900_di.h
- *
- * @brief ME-9x digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0900_DI_H_
-#define _ME0900_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0900_di_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-
-	unsigned int di_idx;
-
-	unsigned long ctrl_reg;
-	unsigned long port_reg;
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me0900_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-9x digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0900_di_subdevice_t *me0900_di_constructor(uint32_t me0900_reg_base,
-					     unsigned int di_idx);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_do.c b/drivers/staging/meilhaus/me0900_do.c
deleted file mode 100644
index a2275fa..0000000
--- a/drivers/staging/meilhaus/me0900_do.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/**
- * @file me0900_do.c
- *
- * @brief ME-9x digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me0900_reg.h"
-#include "me0900_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me0900_do_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	me0900_do_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0900_do_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	outb(0xFF, instance->port_reg);
-	PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0xff);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_do_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)
-{
-	me0900_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0900_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-			} else {
-				PERROR("Invalid byte direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0900_do_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me0900_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0900_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = (~inb(instance->port_reg)) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = ~inb(instance->port_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0900_do_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me0900_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long state;
-
-	PDEBUG("executed.\n");
-
-	instance = (me0900_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			state = inb(instance->port_reg);
-			state =
-			    (!value) ? (state | (0x1 << channel)) : (state &
-								     ~(0x1 <<
-								       channel));
-			outb(state, instance->port_reg);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			outb(~(value), instance->port_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me0900_do_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_do_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me0900_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base,
-					     unsigned int do_idx)
-{
-	me0900_do_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me0900_do_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me0900_do_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	/* Save the subdevice index */
-	subdevice->do_idx = do_idx;
-
-	/* Initialize registers */
-	if (do_idx == 0) {
-		subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
-		subdevice->port_reg = reg_base + ME0900_PORT_A_REG;
-		subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG;
-		subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG;
-	} else {
-		subdevice->ctrl_reg = reg_base + ME0900_CTRL_REG;
-		subdevice->port_reg = reg_base + ME0900_PORT_B_REG;
-		subdevice->enable_reg = reg_base + ME0900_WRITE_ENABLE_REG;
-		subdevice->disable_reg = reg_base + ME0900_WRITE_DISABLE_REG;
-	}
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me0900_do_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me0900_do_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me0900_do_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me0900_do_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me0900_do_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me0900_do_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me0900_do_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me0900_do.h b/drivers/staging/meilhaus/me0900_do.h
deleted file mode 100644
index 13e8a8b..0000000
--- a/drivers/staging/meilhaus/me0900_do.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me0900_do.h
- *
- * @brief ME-9x digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0900_DO_H_
-#define _ME0900_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me0900_do_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-
-	unsigned int do_idx;
-
-	unsigned long ctrl_reg;
-	unsigned long port_reg;
-	unsigned long enable_reg;
-	unsigned long disable_reg;
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me0900_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-9x digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param do_idx The index of the digital output subdevice on this device.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me0900_do_subdevice_t *me0900_do_constructor(uint32_t reg_base,
-					     unsigned int do_idx);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me0900_reg.h b/drivers/staging/meilhaus/me0900_reg.h
deleted file mode 100644
index 3bf163b..0000000
--- a/drivers/staging/meilhaus/me0900_reg.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file me0900_reg.h
- *
- * @brief ME-9x register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME0900_REG_H_
-#define _ME0900_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME0900_PORT_A_REG          0x00
-#define ME0900_PORT_B_REG          0x01
-#define ME0900_PORT_C_REG          0x02
-#define ME0900_CTRL_REG            0x03	// ( ,w)
-#define ME0900_WRITE_ENABLE_REG    0x04	// (r,w)
-#define ME0900_WRITE_DISABLE_REG   0x08	// (r,w)
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1000_device.c b/drivers/staging/meilhaus/me1000_device.c
deleted file mode 100644
index cf0fb92..0000000
--- a/drivers/staging/meilhaus/me1000_device.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/**
- * @file me1000_device.c
- *
- * @brief ME-1000 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me1000_device.h"
-#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)
-{
-	me1000_device_t *me1000_device;
-	me1000_dio_subdevice_t *dio;
-
-	PDEBUG("executed.\n");
-
-	me1000_device = (me1000_device_t *) me_device;
-
-	if (config->count == 2) {
-		if (me_slist_get_number_subdevices(&me1000_device->base.slist)
-		    == 2) {
-			// Nothing to do.
-		} else {
-			// Remove 2 extra subdevices
-			dio =
-			    (me1000_dio_subdevice_t *)
-			    me_slist_del_subdevice_tail(&me1000_device->base.
-							slist);
-			if (dio)
-				dio->base.
-				    me_subdevice_destructor((me_subdevice_t *)
-							    dio);
-
-			dio =
-			    (me1000_dio_subdevice_t *)
-			    me_slist_del_subdevice_tail(&me1000_device->base.
-							slist);
-			if (dio)
-				dio->base.
-				    me_subdevice_destructor((me_subdevice_t *)
-							    dio);
-		}
-	} else if (config->count == 4) {
-		//Add 2 subdevices
-		if (me_slist_get_number_subdevices(&me1000_device->base.slist)
-		    == 2) {
-			dio =
-			    me1000_dio_constructor(me1000_device->base.info.pci.
-						   reg_bases[2], 2,
-						   &me1000_device->ctrl_lock);
-			if (!dio) {
-				PERROR("Cannot create dio subdevice.\n");
-				return ME_ERRNO_INTERNAL;
-			}
-			me_slist_add_subdevice_tail(&me1000_device->base.slist,
-						    (me_subdevice_t *) dio);
-
-			dio =
-			    me1000_dio_constructor(me1000_device->base.info.pci.
-						   reg_bases[2], 3,
-						   &me1000_device->ctrl_lock);
-			if (!dio) {
-				dio =
-				    (me1000_dio_subdevice_t *)
-				    me_slist_del_subdevice_tail(&me1000_device->
-								base.slist);
-				if (dio)
-					dio->base.
-					    me_subdevice_destructor((me_subdevice_t *) dio);
-
-				PERROR("Cannot create dio subdevice.\n");
-				return ME_ERRNO_INTERNAL;
-			}
-			me_slist_add_subdevice_tail(&me1000_device->base.slist,
-						    (me_subdevice_t *) dio);
-		} else {
-			// Nothing to do.
-		}
-	} else {
-		PERROR("Invalid configuration.\n");
-		return ME_ERRNO_INTERNAL;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-me_device_t *me1000_pci_constructor(struct pci_dev * pci_device)
-{
-	me1000_device_t *me1000_device;
-	me_subdevice_t *subdevice;
-	int err;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me1000_device = kmalloc(sizeof(me1000_device_t), GFP_KERNEL);
-
-	if (!me1000_device) {
-		PERROR("Cannot get memory for ME-1000 device instance.\n");
-		return NULL;
-	}
-
-	memset(me1000_device, 0, sizeof(me1000_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me1000_device, pci_device);
-
-	if (err) {
-		kfree(me1000_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-	// Initialize spin lock .
-	spin_lock_init(&me1000_device->ctrl_lock);
-
-	for (i = 0; i < 4; i++) {
-		subdevice =
-		    (me_subdevice_t *) me1000_dio_constructor(me1000_device->
-							      base.info.pci.
-							      reg_bases[2], i,
-							      &me1000_device->
-							      ctrl_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me1000_device);
-			kfree(me1000_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me1000_device->base.slist,
-					    subdevice);
-	}
-
-	// Overwrite base class methods.
-	me1000_device->base.me_device_config_load = me1000_config_load;
-
-	return (me_device_t *) me1000_device;
-}
-EXPORT_SYMBOL(me1000_pci_constructor);
-
-// Init and exit of module.
-static int __init me1000_init(void)
-{
-	PDEBUG("executed.\n");
-	return 0;
-}
-
-static void __exit me1000_exit(void)
-{
-	PDEBUG("executed.\n");
-}
-
-module_init(me1000_init);
-module_exit(me1000_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me1000_device.h b/drivers/staging/meilhaus/me1000_device.h
deleted file mode 100644
index cbbe126..0000000
--- a/drivers/staging/meilhaus/me1000_device.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file me1000_device.h
- *
- * @brief ME-1000 device class instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1000_H_
-#define _ME1000_H_
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-#define ME1000_MAGIC_NUMBER	1000
-
-/**
- * @brief The ME-1000 device class structure.
- */
-typedef struct me1000_device {
-	me_device_t base;		/**< The Meilhaus device base class. */
-	spinlock_t ctrl_lock;		/**< Guards the DIO mode register. */
-} me1000_device_t;
-
-/**
- * @brief The ME-1000 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-1000 device instance. \n
- *         NULL on error.
- */
-me_device_t *me1000_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1000_dio.c b/drivers/staging/meilhaus/me1000_dio.c
deleted file mode 100644
index 2d7ed07..0000000
--- a/drivers/staging/meilhaus/me1000_dio.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/**
- * @file me1000_dio.c
- *
- * @brief ME-1000 DIO subdevice instance.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-
-#include "me1000_dio_reg.h"
-#include "me1000_dio.h"
-
-/*
- * Defines
- */
-#define ME1000_DIO_MAGIC_NUMBER	0x1000	/**< The magic number of the class structure. */
-
-/*
- * Functions
- */
-
-static int me1000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
-					 struct file *filep, int flags)
-{
-	me1000_dio_subdevice_t *instance;
-	uint32_t tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1000_dio_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	tmp = inl(instance->ctrl_reg);
-	tmp &= ~(0x1 << instance->dio_idx);
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outl(0x00000000, instance->port_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, 0);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1000_dio_io_single_config(struct me_subdevice *subdevice,
-				       struct file *filep,
-				       int channel,
-				       int single_config,
-				       int ref,
-				       int trig_chan,
-				       int trig_type, int trig_edge, int flags)
-{
-	me1000_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	int ctrl;
-	int size =
-	    flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
-		     | ME_IO_SINGLE_CONFIG_DIO_WORD |
-		     ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
-	PDEBUG("executed.\n");
-
-	instance = (me1000_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	ctrl = inl(instance->ctrl_reg);
-
-	switch (size) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_DWORD:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-				ctrl &= ~(0x1 << instance->dio_idx);
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-				ctrl |= 0x1 << instance->dio_idx;
-			} else {
-				PERROR("Invalid port direction.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!err) {
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me1000_dio_io_single_read(struct me_subdevice *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int *value, int time_out, int flags)
-{
-	me1000_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1000_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 32)) {
-			*value = inl(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if ((channel >= 0) && (channel < 4)) {
-			*value =
-			    (inl(instance->port_reg) >> (channel * 8)) & 0xFF;
-		} else {
-			PERROR("Invalid byte number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_WORD:
-		if ((channel >= 0) && (channel < 2)) {
-			*value =
-			    (inl(instance->port_reg) >> (channel * 16)) &
-			    0xFFFF;
-		} else {
-			PERROR("Invalid word number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_DWORD:
-		if (channel == 0) {
-			*value = inl(instance->port_reg);
-		} else {
-			PERROR("Invalid dword number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me1000_dio_io_single_write(struct me_subdevice *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int value, int time_out, int flags)
-{
-	me1000_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t config;
-	uint32_t state;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1000_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	config = inl(instance->ctrl_reg) & (0x1 << instance->dio_idx);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 32)) {
-			if (config) {
-				state = inl(instance->port_reg);
-				state =
-				    value ? (state | (0x1 << channel)) : (state
-									  &
-									  ~(0x1
-									    <<
-									    channel));
-				outl(state, instance->port_reg);
-				PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->port_reg -
-					   instance->reg_base, state);
-			} else {
-				PERROR("Port is not in output mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if ((channel >= 0) && (channel < 4)) {
-			if (config) {
-				state = inl(instance->port_reg);
-				state &= ~(0xFF << (channel * 8));
-				state |= (value & 0xFF) << (channel * 8);
-				outl(state, instance->port_reg);
-				PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->port_reg -
-					   instance->reg_base, state);
-			} else {
-				PERROR("Port is not in output mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_WORD:
-		if ((channel >= 0) && (channel < 2)) {
-			if (config) {
-				state = inl(instance->port_reg);
-				state &= ~(0xFFFF << (channel * 16));
-				state |= (value & 0xFFFF) << (channel * 16);
-				outl(state, instance->port_reg);
-				PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->port_reg -
-					   instance->reg_base, state);
-			} else {
-				PERROR("Port is not in output mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid word number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_DWORD:
-		if (channel == 0) {
-			if (config) {
-				outl(value, instance->port_reg);
-				PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->port_reg -
-					   instance->reg_base, value);
-			} else {
-				PERROR("Port is not in output mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid dword number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me1000_dio_query_number_channels(struct me_subdevice *subdevice,
-					    int *number)
-{
-	PDEBUG("executed.\n");
-	*number = ME1000_DIO_NUMBER_CHANNELS;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1000_dio_query_subdevice_type(struct me_subdevice *subdevice,
-					   int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DIO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1000_dio_query_subdevice_caps(struct me_subdevice *subdevice,
-					   int *caps)
-{
-	me1000_dio_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1000_dio_subdevice_t *) subdevice;
-
-	*caps = ME_CAPS_DIO_DIR_DWORD;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t *ctrl_reg_lock)
-{
-	me1000_dio_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me1000_dio_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for ME-1000 DIO instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me1000_dio_subdevice_t));
-
-	/* Check if counter index is out of range */
-
-	if (dio_idx >= ME1000_DIO_NUMBER_PORTS) {
-		PERROR("DIO index is out of range.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save the DIO index */
-	subdevice->dio_idx = dio_idx;
-
-	/* Initialize registers. */
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-	subdevice->ctrl_reg = reg_base + ME1000_PORT_MODE;
-	subdevice->port_reg =
-	    reg_base + ME1000_PORT + (dio_idx * ME1000_PORT_STEP);
-
-	/* Override base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me1000_dio_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me1000_dio_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me1000_dio_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me1000_dio_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me1000_dio_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me1000_dio_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me1000_dio_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me1000_dio.h b/drivers/staging/meilhaus/me1000_dio.h
deleted file mode 100644
index d26e93f..0000000
--- a/drivers/staging/meilhaus/me1000_dio.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * @file me1000_dio.h
- *
- * @brief Meilhaus ME-1000 digital i/o implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1000_DIO_H_
-#define _ME1000_DIO_H_
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The ME-1000 DIO subdevice class.
- */
-typedef struct me1000_dio_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-//      uint32_t magic;                                 /**< The magic number unique for this structure. */
-
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */
-	int dio_idx;					/**< The index of the DIO port on the device. */
-
-	unsigned long port_reg;			/**< Register to read or write a value from or to the port respectively. */
-	unsigned long ctrl_reg;			/**< Register to configure the DIO modes. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me1000_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-1000 DIO instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the DIO on the device.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register and from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1000_dio_reg.h b/drivers/staging/meilhaus/me1000_dio_reg.h
deleted file mode 100644
index 4d5b38d..0000000
--- a/drivers/staging/meilhaus/me1000_dio_reg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file me1000_dio_reg.h
- *
- * @brief ME-1000 digital i/o register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1000_DIO_REG_H_
-# define _ME1000_DIO_REG_H_
-
-# ifdef __KERNEL__
-
-# define ME1000_DIO_NUMBER_CHANNELS	32				/**< The number of channels per DIO port. */
-# define ME1000_DIO_NUMBER_PORTS	4				/**< The number of ports per ME-1000. */
-
-// # define ME1000_PORT_A                               0x0000                  /**< Port A base register offset. */
-// # define ME1000_PORT_B                               0x0004                  /**< Port B base register offset. */
-// # define ME1000_PORT_C                               0x0008                  /**< Port C base register offset. */
-// # define ME1000_PORT_D                               0x000C                  /**< Port D base register offset. */
-# define ME1000_PORT				0x0000			/**< Base for port's register. */
-# define ME1000_PORT_STEP			4				/**< Distance between port's register. */
-
-# define ME1000_PORT_MODE			0x0010			/**< Configuration register to switch the port direction. */
-// # define ME1000_PORT_MODE_OUTPUT_A   (1 << 0)                /**< If set, port A is in output, otherwise in input mode. */
-// # define ME1000_PORT_MODE_OUTPUT_B   (1 << 1)                /**< If set, port B is in output, otherwise in input mode. */
-// # define ME1000_PORT_MODE_OUTPUT_C   (1 << 2)                /**< If set, port C is in output, otherwise in input mode. */
-// # define ME1000_PORT_MODE_OUTPUT_D   (1 << 3)                /**< If set, port D is in output, otherwise in input mode. */
-
-# endif	//__KERNEL__
-#endif //_ME1000_DIO_REG_H_
diff --git a/drivers/staging/meilhaus/me1400_device.c b/drivers/staging/meilhaus/me1400_device.c
deleted file mode 100644
index a018b5f..0000000
--- a/drivers/staging/meilhaus/me1400_device.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/**
- * @file me1400_device.c
- *
- * @brief ME-1400 device instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- */
-
-/*
- * User application could also include the kernel header files. But the
- * real kernel functions are protected by #ifdef __KERNEL__.
- */
-#ifndef __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * This must be defined before module.h is included. Not needed, when
- * it is a built in driver.
- */
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-
-#include "me1400_device.h"
-#include "me8254.h"
-#include "me8254_reg.h"
-#include "me8255.h"
-#include "me1400_ext_irq.h"
-
-me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
-{
-	int err;
-	me1400_device_t *me1400_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	unsigned int me8255_idx;
-	unsigned int dio_idx;
-	unsigned int me8254_idx;
-	unsigned int ctr_idx;
-	unsigned int ext_irq_idx;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me1400_device = kmalloc(sizeof(me1400_device_t), GFP_KERNEL);
-
-	if (!me1400_device) {
-		PERROR("Cannot get memory for 1400ate device instance.\n");
-		return NULL;
-	}
-
-	memset(me1400_device, 0, sizeof(me1400_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me1400_device, pci_device);
-
-	if (err) {
-		kfree(me1400_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-
-	/* Check for ME1400 extension device. If detected we fake a ME-1400 D device id. */
-	if (me1400_device->base.info.pci.device_id ==
-	    PCI_DEVICE_ID_MEILHAUS_ME140C) {
-		uint8_t ctrl;
-		ctrl =
-		    inb(me1400_device->base.info.pci.reg_bases[2] +
-			ME1400D_CLK_SRC_2_REG);
-		PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
-			   me1400_device->base.info.pci.reg_bases[2],
-			   ME1400D_CLK_SRC_2_REG, ctrl);
-		outb(ctrl | 0xF0,
-		     me1400_device->base.info.pci.reg_bases[2] +
-		     ME1400D_CLK_SRC_2_REG);
-		PDEBUG_REG("xxx_reg outb(0x%X+0x%X)=0x%x\n",
-			   me1400_device->base.info.pci.reg_bases[2],
-			   ME1400D_CLK_SRC_2_REG, ctrl | 0xF0);
-		ctrl =
-		    inb(me1400_device->base.info.pci.reg_bases[2] +
-			ME1400D_CLK_SRC_2_REG);
-		PDEBUG_REG("xxx_reg inb(0x%X+0x%X)=0x%x\n",
-			   me1400_device->base.info.pci.reg_bases[2],
-			   ME1400D_CLK_SRC_2_REG, ctrl);
-
-		if ((ctrl & 0xF0) == 0xF0) {
-			PINFO("ME1400 D detected.\n");
-			me1400_device->base.info.pci.device_id =
-			    PCI_DEVICE_ID_MEILHAUS_ME140D;
-		}
-	}
-
-	/* Initialize global stuff of digital i/o subdevices. */
-	for (me8255_idx = 0; me8255_idx < ME1400_MAX_8255; me8255_idx++) {
-		me1400_device->dio_current_mode[me8255_idx] = 0;
-		spin_lock_init(&me1400_device->dio_ctrl_reg_lock[me8255_idx]);
-	}
-
-	/* Initialize global stuff of counter subdevices. */
-	spin_lock_init(&me1400_device->clk_src_reg_lock);
-
-	for (me8254_idx = 0; me8254_idx < ME1400_MAX_8254; me8254_idx++)
-		spin_lock_init(&me1400_device->ctr_ctrl_reg_lock[me8254_idx]);
-
-	/* Get the index in the device version information table. */
-	version_idx =
-	    me1400_versions_get_device_index(me1400_device->base.info.pci.
-					     device_id);
-
-	/* Generate DIO subdevice instances. */
-	for (me8255_idx = 0;
-	     me8255_idx < me1400_versions[version_idx].dio_chips;
-	     me8255_idx++) {
-		for (dio_idx = 0; dio_idx < 3; dio_idx++) {
-			subdevice =
-			    (me_subdevice_t *)
-			    me8255_constructor(me1400_versions[version_idx].
-					       device_id,
-					       me1400_device->base.info.pci.
-					       reg_bases[2], me8255_idx,
-					       dio_idx,
-					       &me1400_device->
-					       dio_current_mode[me8255_idx],
-					       &me1400_device->
-					       dio_ctrl_reg_lock[me8255_idx]);
-
-			if (!subdevice) {
-				me_device_deinit((me_device_t *) me1400_device);
-				kfree(me1400_device);
-				PERROR("Cannot get memory for subdevice.\n");
-				return NULL;
-			}
-
-			me_slist_add_subdevice_tail(&me1400_device->base.slist,
-						    subdevice);
-		}
-	}
-
-	/* Generate counter subdevice instances. */
-	for (me8254_idx = 0;
-	     me8254_idx < me1400_versions[version_idx].ctr_chips;
-	     me8254_idx++) {
-		for (ctr_idx = 0; ctr_idx < 3; ctr_idx++) {
-			subdevice =
-			    (me_subdevice_t *)
-			    me8254_constructor(me1400_device->base.info.pci.
-					       device_id,
-					       me1400_device->base.info.pci.
-					       reg_bases[2], me8254_idx,
-					       ctr_idx,
-					       &me1400_device->
-					       ctr_ctrl_reg_lock[me8254_idx],
-					       &me1400_device->
-					       clk_src_reg_lock);
-
-			if (!subdevice) {
-				me_device_deinit((me_device_t *) me1400_device);
-				kfree(me1400_device);
-				PERROR("Cannot get memory for subdevice.\n");
-				return NULL;
-			}
-
-			me_slist_add_subdevice_tail(&me1400_device->base.slist,
-						    subdevice);
-		}
-	}
-
-	/* Generate external interrupt subdevice instances. */
-	for (ext_irq_idx = 0;
-	     ext_irq_idx < me1400_versions[version_idx].ext_irq_subdevices;
-	     ext_irq_idx++) {
-		subdevice =
-		    (me_subdevice_t *)
-		    me1400_ext_irq_constructor(me1400_device->base.info.pci.
-					       device_id,
-					       me1400_device->base.info.pci.
-					       reg_bases[1],
-					       me1400_device->base.info.pci.
-					       reg_bases[2],
-					       &me1400_device->clk_src_reg_lock,
-					       me1400_device->base.irq);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me1400_device);
-			kfree(me1400_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me1400_device->base.slist,
-					    subdevice);
-	}
-
-	return (me_device_t *) me1400_device;
-}
-EXPORT_SYMBOL(me1400_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me1400_init(void)
-{
-	PDEBUG("executed.\n");
-	return 0;
-}
-
-static void __exit me1400_exit(void)
-{
-	PDEBUG("executed.\n");
-}
-
-module_init(me1400_init);
-module_exit(me1400_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-14xx devices");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-14xx MIO devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me1400_device.h b/drivers/staging/meilhaus/me1400_device.h
deleted file mode 100644
index 6215b25..0000000
--- a/drivers/staging/meilhaus/me1400_device.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * @file me1400_device.c
- *
- * @brief ME-1400 device family instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1400_DEVICE_H_
-#define _ME1400_DEVICE_H_
-
-#include "metypes.h"
-#include "medefines.h"
-#include "meinternal.h"
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure to store device capabilities.
- */
-typedef struct me1400_version {
-	uint16_t device_id;					/**< The PCI device id of the device. */
-	unsigned int dio_chips;				/**< The number of 8255 chips on the device. */
-	unsigned int ctr_chips;				/**< The number of 8254 chips on the device. */
-	unsigned int ext_irq_subdevices;	/**< The number of external interrupt inputs on the device. */
-} me1400_version_t;
-
-/**
-  * @brief Defines for each ME-1400 device version its capabilities.
- */
-static me1400_version_t me1400_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME1400, 1, 0, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME140A, 1, 1, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME140B, 2, 2, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME14E0, 1, 0, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME14EA, 1, 1, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME14EB, 2, 2, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME140C, 1, 5, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME140D, 2, 10, 1},
-	{0}
-};
-
-#define ME1400_DEVICE_VERSIONS (sizeof(me1400_versions) / sizeof(me1400_version_t) - 1)	/**< Returns the number of entries in #me1400_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me1400_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me1400_versions.
- */
-static inline unsigned int me1400_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME1400_DEVICE_VERSIONS; i++)
-		if (me1400_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-#define ME1400_MAX_8254		10	/**< The maximum number of 8254 counter subdevices available on any ME-1400 device. */
-#define ME1400_MAX_8255		2	/**< The maximum number of 8255 digital i/o subdevices available on any ME-1400 device. */
-
-/**
- * @brief The ME-1400 device class.
- */
-typedef struct me1400_device {
-	me_device_t base;									/**< The Meilhaus device base class. */
-
-	spinlock_t clk_src_reg_lock;						/**< Guards the 8254 clock source registers. */
-	spinlock_t ctr_ctrl_reg_lock[ME1400_MAX_8254];		/**< Guards the 8254 ctrl registers. */
-
-	int dio_current_mode[ME1400_MAX_8255];				/**< Saves the current mode setting of a single 8255 DIO chip. */
-	spinlock_t dio_ctrl_reg_lock[ME1400_MAX_8255];		/**< Guards the 8255 ctrl register and #dio_current_mode. */
-} me1400_device_t;
-
-/**
- * @brief The ME-1400 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-1400 device instance. \n
- *         NULL on error.
- */
-me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.c b/drivers/staging/meilhaus/me1400_ext_irq.c
deleted file mode 100644
index 6841f41..0000000
--- a/drivers/staging/meilhaus/me1400_ext_irq.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/**
- * @file me1400_ext_irq.c
- *
- * @brief ME-1400 external interrupt subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-#include "meids.h"
-
-#include "me1400_ext_irq.h"
-#include "me1400_ext_irq_reg.h"
-
-/*
- * Defines
- */
-#define ME1400_EXT_IRQ_MAGIC_NUMBER	0x1401	/**< The magic number of the class structure. */
-#define ME1400_EXT_IRQ_NUMBER_CHANNELS 1	/**< One channel per counter. */
-
-/*
- * Functions
- */
-
-static int me1400_ext_irq_io_irq_start(struct me_subdevice *subdevice,
-				       struct file *filep,
-				       int channel,
-				       int irq_source,
-				       int irq_edge, int irq_arg, int flags)
-{
-	me1400_ext_irq_subdevice_t *instance;
-	unsigned long cpu_flags;
-	uint8_t tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
-	if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
-		PERROR("Invalid irq source.\n");
-		return ME_ERRNO_INVALID_IRQ_SOURCE;
-	}
-
-	if (irq_edge != ME_IRQ_EDGE_RISING) {
-		PERROR("Invalid irq edge.\n");
-		return ME_ERRNO_INVALID_IRQ_EDGE;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	spin_lock(instance->clk_src_reg_lock);
-//                      // Enable IRQ on PLX
-//                      tmp = inb(instance->plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN);
-//                      outb(tmp, instance->plx_intcs_reg);
-//                      PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
-
-	// Enable IRQ
-	switch (instance->device_id) {
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		tmp = inb(instance->ctrl_reg);
-		tmp |= ME1400CD_EXT_IRQ_CLK_EN;
-		outb(tmp, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, tmp);
-		break;
-
-	default:
-		outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base,
-			   ME1400AB_EXT_IRQ_IRQ_EN);
-		break;
-	}
-	spin_unlock(instance->clk_src_reg_lock);
-	instance->rised = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int *irq_count,
-				      int *value, int time_out, int flags)
-{
-	me1400_ext_irq_subdevice_t *instance;
-	unsigned long cpu_flags;
-	long t = 0;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time out.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		/* Convert to ticks */
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->rised <= 0) {
-		instance->rised = 0;
-		if (time_out) {
-			t = wait_event_interruptible_timeout(instance->
-							     wait_queue,
-							     (instance->rised !=
-							      0), t);
-
-			if (t == 0) {
-				PERROR("Wait on interrupt timed out.\n");
-				err = ME_ERRNO_TIMEOUT;
-			}
-		} else {
-			wait_event_interruptible(instance->wait_queue,
-						 (instance->rised != 0));
-		}
-
-		if (instance->rised < 0) {
-			PERROR("Wait on interrupt aborted by user.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-	}
-
-	if (signal_pending(current)) {
-		PERROR("Wait on interrupt aborted by signal.\n");
-		err = ME_ERRNO_SIGNAL;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	instance->rised = 0;
-	*irq_count = instance->n;
-	*value = 1;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me1400_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
-				      struct file *filep,
-				      int channel, int flags)
-{
-	me1400_ext_irq_subdevice_t *instance;
-	unsigned long cpu_flags;
-	uint8_t tmp;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->clk_src_reg_lock);
-//                      // Disable IRQ on PLX
-//                      tmp = inb(instance->plx_intcs_reg) & ( ~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN));
-//                      outb(tmp, instance->plx_intcs_reg);
-//                      PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
-
-	switch (instance->device_id) {
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		tmp = inb(instance->ctrl_reg);
-		tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
-		outb(tmp, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, tmp);
-
-		break;
-
-	default:
-		outb(0x00, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, 0x00);
-		break;
-	}
-	spin_unlock(instance->clk_src_reg_lock);
-	instance->rised = -1;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me1400_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
-					     struct file *filep, int flags)
-{
-	me1400_ext_irq_subdevice_t *instance =
-	    (me1400_ext_irq_subdevice_t *) subdevice;
-
-	PDEBUG("executed.\n");
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	instance->n = 0;
-	return me1400_ext_irq_io_irq_stop(subdevice, filep, 0, flags);
-}
-
-static int me1400_ext_irq_query_number_channels(struct me_subdevice *subdevice,
-						int *number)
-{
-	PDEBUG("executed.\n");
-	*number = ME1400_EXT_IRQ_NUMBER_CHANNELS;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
-					       int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_EXT_IRQ;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
-					       int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice
-						    *subdevice, int cap,
-						    int *args, int count)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
-{
-	me1400_ext_irq_subdevice_t *instance;
-	uint32_t status;
-	uint8_t tmp;
-
-	instance = (me1400_ext_irq_subdevice_t *) dev_id;
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	spin_lock(&instance->subdevice_lock);
-	status = inl(instance->plx_intcs_reg);
-//              if (!((status & PLX_LOCAL_INT1_STATE) && (status & PLX_LOCAL_INT1_EN) && (status & PLX_PCI_INT_EN)))
-	if ((status &
-	     (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) !=
-	    (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) {
-		spin_unlock(&instance->subdevice_lock);
-		PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
-		      jiffies, __func__, status);
-		return IRQ_NONE;
-	}
-
-	inl(instance->ctrl_reg);
-
-	PDEBUG("executed.\n");
-
-	instance->n++;
-	instance->rised = 1;
-
-	switch (instance->device_id) {
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		spin_lock(instance->clk_src_reg_lock);
-		tmp = inb(instance->ctrl_reg);
-		tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
-		outb(tmp, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, tmp);
-		tmp |= ME1400CD_EXT_IRQ_CLK_EN;
-		outb(tmp, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, tmp);
-		spin_unlock(instance->clk_src_reg_lock);
-
-		break;
-
-	default:
-		outb(0, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, 0);
-		outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base,
-			   ME1400AB_EXT_IRQ_IRQ_EN);
-		break;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-static void me1400_ext_irq_destructor(struct me_subdevice *subdevice)
-{
-	me1400_ext_irq_subdevice_t *instance;
-	uint8_t tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1400_ext_irq_subdevice_t *) subdevice;
-
-	// Disable IRQ on PLX
-	tmp =
-	    inb(instance->
-		plx_intcs_reg) & (~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
-				    PLX_PCI_INT_EN));
-	outb(tmp, instance->plx_intcs_reg);
-	PDEBUG_REG("ctrl_reg outb(plx:0x%lX)=0x%x\n", instance->plx_intcs_reg,
-		   tmp);
-
-	free_irq(instance->irq, (void *)instance);
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id,
-						       uint32_t plx_reg_base,
-						       uint32_t me1400_reg_base,
-						       spinlock_t *
-						       clk_src_reg_lock,
-						       int irq)
-{
-	me1400_ext_irq_subdevice_t *subdevice;
-	int err;
-	uint8_t tmp;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me1400_ext_irq_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for 1400_ext_irq instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me1400_ext_irq_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-	subdevice->clk_src_reg_lock = clk_src_reg_lock;
-
-	/* Initialize wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	subdevice->irq = irq;
-
-	err = request_irq(irq, me1400_ext_irq_isr,
-			  IRQF_DISABLED | IRQF_SHARED,
-			  ME1400_NAME, (void *)subdevice);
-
-	if (err) {
-		PERROR("Can't get irq.\n");
-		me_subdevice_deinit(&subdevice->base);
-		kfree(subdevice);
-		return NULL;
-	}
-	PINFO("Registered irq=%d.\n", subdevice->irq);
-
-	/* Initialize registers */
-	subdevice->plx_intcs_reg = plx_reg_base + PLX_INTCSR_REG;
-	subdevice->ctrl_reg = me1400_reg_base + ME1400AB_EXT_IRQ_CTRL_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = me1400_reg_base;
-#endif
-
-	// Enable IRQ on PLX
-	tmp =
-	    inb(subdevice->
-		plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
-				  PLX_PCI_INT_EN);
-	outb(tmp, subdevice->plx_intcs_reg);
-	PDEBUG_REG("ctrl_reg outb(Pplx:0x%lX)=0x%x\n", subdevice->plx_intcs_reg,
-		   tmp);
-
-	/* Initialize the subdevice methods */
-	subdevice->base.me_subdevice_io_irq_start = me1400_ext_irq_io_irq_start;
-	subdevice->base.me_subdevice_io_irq_wait = me1400_ext_irq_io_irq_wait;
-	subdevice->base.me_subdevice_io_irq_stop = me1400_ext_irq_io_irq_stop;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me1400_ext_irq_io_reset_subdevice;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me1400_ext_irq_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me1400_ext_irq_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me1400_ext_irq_query_subdevice_caps;
-	subdevice->base.me_subdevice_query_subdevice_caps_args =
-	    me1400_ext_irq_query_subdevice_caps_args;
-	subdevice->base.me_subdevice_destructor = me1400_ext_irq_destructor;
-
-	subdevice->rised = 0;
-	subdevice->n = 0;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.h b/drivers/staging/meilhaus/me1400_ext_irq.h
deleted file mode 100644
index 9b72a04..0000000
--- a/drivers/staging/meilhaus/me1400_ext_irq.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file me1400_ext_irq.h
- *
- * @brief ME-1400 external interrupt implementation.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME1400_EXT_IRQ_H_
-#define _ME1400_EXT_IRQ_H_
-
-#include <linux/sched.h>
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The ME-1400 external interrupt subdevice class.
- */
-typedef struct me1400_ext_irq_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *clk_src_reg_lock;	/**< Lock protecting the clock control register. */
-
-	wait_queue_head_t wait_queue;	/**< Queue to put on threads waiting for an interrupt. */
-
-	uint32_t device_id;				/**< The device id of the device holding the subdevice. */
-	int irq;						/**< The irq number assigned by PCI BIOS. */
-	int rised;						/**< If true an interrupt has occured. */
-	unsigned int n;					/**< The number of interrupt since the driver was loaded. */
-
-	unsigned long plx_intcs_reg;	/**< The PLX interrupt control and status register. */
-	unsigned long ctrl_reg;			/**< The control register. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me1400_ext_irq_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-1400 external interrupt instance.
- *
- * @param plx_reg_base The register base address of the PLX chip as returned by the PCI BIOS.
- * @param me1400_reg_base The register base address of the ME-1400 device as returned by the PCI BIOS.
- * @param irq The irq assigned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id,
-						       uint32_t plx_reg_base,
-						       uint32_t me1400_reg_base,
-						       spinlock_t *
-						       clk_src_reg_lock,
-						       int irq);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1400_ext_irq_reg.h b/drivers/staging/meilhaus/me1400_ext_irq_reg.h
deleted file mode 100644
index c9740f2..0000000
--- a/drivers/staging/meilhaus/me1400_ext_irq_reg.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @file me1400_ext_irq_reg.h
- *
- * @brief ME-1400 external interrupt register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1400_EXT_IRQ_REG_H_
-# define _ME1400_EXT_IRQ_REG_H_
-
-# ifdef __KERNEL__
-
-#  define PLX_INTCSR_REG				0x4C	/**< The PLX interrupt control and status register offset. */
-#  define PLX_ICR_REG					0x50	/**< The PLX initialization control register offset. */
-
-#  define PLX_LOCAL_INT1_EN				0x01	/**< If set the local interrupt 1 is enabled. */
-#  define PLX_LOCAL_INT1_POL			0x02	/**< If set the local interrupt 1 polarity is high active. */
-#  define PLX_LOCAL_INT1_STATE			0x04	/**< If set the local interrupt 1 is activ. */
-#  define PLX_LOCAL_INT2_EN				0x08	/**< If set the local interrupt 2 is enabled. */
-#  define PLX_LOCAL_INT2_POL			0x10	/**< If set the local interrupt 2 polarity is high active. */
-#  define PLX_LOCAL_INT2_STATE			0x20	/**< If set the local interrupt 2 is activ. */
-#  define PLX_PCI_INT_EN				0x40	/**< If set the PCI interrupt is enabled. */
-#  define PLX_SOFT_INT					0x80	/**< If set an interrupt is generated. */
-
-#  define ME1400AB_EXT_IRQ_CTRL_REG		0x11	/**< The external interrupt control register offset. */
-
-#  define ME1400AB_EXT_IRQ_CLK_EN		0x01	/**< If this bit is set, the clock output is enabled. */
-#  define ME1400AB_EXT_IRQ_IRQ_EN		0x02	/**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt. */
-
-#  define ME1400CD_EXT_IRQ_CTRL_REG		0x11	/**< The external interrupt control register offset. */
-
-#  define ME1400CD_EXT_IRQ_CLK_EN		0x10	/**< If set the external interrupt is enabled. Clearing this bit clears a pending interrupt.*/
-
-# endif	//__KERNEL__
-
-#endif //_ME1400_EXT_IRQ_REG_H_
diff --git a/drivers/staging/meilhaus/me1600_ao.c b/drivers/staging/meilhaus/me1600_ao.c
deleted file mode 100644
index 12e3c70..0000000
--- a/drivers/staging/meilhaus/me1600_ao.c
+++ /dev/null
@@ -1,1017 +0,0 @@
-/**
- * @file me1600_ao.c
- *
- * @brief ME-1600 analog output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/* Includes
- */
-
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-
-#include <linux/workqueue.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-
-#include "me1600_ao_reg.h"
-#include "me1600_ao.h"
-
-/* Defines
- */
-
-static void me1600_ao_destructor(struct me_subdevice *subdevice);
-
-static void me1600_ao_work_control_task(struct work_struct *work);
-
-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,
-				      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,
-				    struct file *filep, int channel, int *value,
-				    int time_out, int flags);
-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,
-					   int *number);
-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,
-					  int *caps);
-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,
-					 int *count);
-static int me1600_ao_query_range_info(me_subdevice_t *subdevice, int range,
-				      int *unit, int *min, int *max,
-				      int *maxdata);
-
-/* Functions
- */
-
-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,
-					     struct workqueue_struct *me1600_wq)
-{
-	me1600_ao_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed. idx=%d\n", ao_idx);
-
-	// Allocate memory for subdevice instance.
-	subdevice = kmalloc(sizeof(me1600_ao_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR
-		    ("Cannot get memory for analog output subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me1600_ao_subdevice_t));
-
-	// Initialize subdevice base class.
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-	subdevice->config_regs_lock = config_regs_lock;
-	subdevice->ao_shadows_lock = ao_shadows_lock;
-
-	// Save the subdevice index.
-	subdevice->ao_idx = ao_idx;
-
-	// Initialize range lists.
-	subdevice->u_ranges_count = 2;
-
-	subdevice->u_ranges[0].min = 0;	//0V
-	subdevice->u_ranges[0].max = 9997558;	//10V
-
-	subdevice->u_ranges[1].min = -10E6;	//-10V
-	subdevice->u_ranges[1].max = 9995117;	//10V
-
-	if (curr) {		// This is version with current outputs.
-		subdevice->i_ranges_count = 2;
-
-		subdevice->i_ranges[0].min = 0;	//0mA
-		subdevice->i_ranges[0].max = 19995117;	//20mA
-
-		subdevice->i_ranges[1].min = 4E3;	//4mA
-		subdevice->i_ranges[1].max = 19995118;	//20mA
-	} else {		// This is version without current outputs.
-		subdevice->i_ranges_count = 0;
-
-		subdevice->i_ranges[0].min = 0;	//0mA
-		subdevice->i_ranges[0].max = 0;	//0mA
-
-		subdevice->i_ranges[1].min = 0;	//0mA
-		subdevice->i_ranges[1].max = 0;	//0mA
-	}
-
-	// Initialize registers.
-	subdevice->uni_bi_reg = reg_base + ME1600_UNI_BI_REG;
-	subdevice->i_range_reg = reg_base + ME1600_020_420_REG;
-	subdevice->sim_output_reg = reg_base + ME1600_SIM_OUTPUT_REG;
-	subdevice->current_on_reg = reg_base + ME1600_CURRENT_ON_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	// Initialize shadow structure.
-	subdevice->ao_regs_shadows = ao_regs_shadows;
-
-	// Override base class methods.
-	subdevice->base.me_subdevice_destructor = me1600_ao_destructor;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me1600_ao_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me1600_ao_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me1600_ao_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me1600_ao_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me1600_ao_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me1600_ao_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me1600_ao_query_subdevice_caps;
-	subdevice->base.me_subdevice_query_range_by_min_max =
-	    me1600_ao_query_range_by_min_max;
-	subdevice->base.me_subdevice_query_number_ranges =
-	    me1600_ao_query_number_ranges;
-	subdevice->base.me_subdevice_query_range_info =
-	    me1600_ao_query_range_info;
-
-	// Initialize wait queue.
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	// Prepare work queue.
-	subdevice->me1600_workqueue = me1600_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
-	INIT_DELAYED_WORK(&subdevice->ao_control_task,
-			  me1600_ao_work_control_task);
-	return subdevice;
-}
-
-static void me1600_ao_destructor(struct me_subdevice *subdevice)
-{
-	me1600_ao_subdevice_t *instance;
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	instance->ao_control_task_flag = 0;
-
-	// Reset subdevice to asure clean exit.
-	me1600_ao_io_reset_subdevice(subdevice, NULL,
-				     ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
-	// Remove any tasks from work queue. This is paranoic because it was done allready in reset().
-	if (!cancel_delayed_work(&instance->ao_control_task)) {	//Wait 2 ticks to be sure that control task is removed from queue.
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(2);
-	}
-}
-
-static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
-					struct file *filep, int flags)
-{
-	me1600_ao_subdevice_t *instance;
-	uint16_t tmp;
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-	(instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx);	//Cancell waiting for trigger.
-
-	// Reset all settings.
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ao_shadows_lock);
-	(instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0;
-	(instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0;
-	(instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx);	//Not waiting for triggering.
-	(instance->ao_regs_shadows)->synchronous &= ~(0x1 << instance->ao_idx);	//Individual triggering.
-
-	// Set output to default (safe) state.
-	spin_lock(instance->config_regs_lock);
-	tmp = inw(instance->uni_bi_reg);	// unipolar
-	tmp |= (0x1 << instance->ao_idx);
-	outw(tmp, instance->uni_bi_reg);
-	PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->uni_bi_reg - instance->reg_base, tmp);
-
-	tmp = inw(instance->current_on_reg);	// Volts only!
-	tmp &= ~(0x1 << instance->ao_idx);
-	tmp &= 0x00FF;
-	outw(tmp, instance->current_on_reg);
-	PDEBUG_REG("current_on_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->current_on_reg - instance->reg_base, tmp);
-
-	tmp = inw(instance->i_range_reg);	// 0..20mA <= If exists.
-	tmp &= ~(0x1 << instance->ao_idx);
-	outw(tmp, instance->i_range_reg);
-	PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->i_range_reg - instance->reg_base, tmp);
-
-	outw(0, (instance->ao_regs_shadows)->registry[instance->ao_idx]);
-	PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   (instance->ao_regs_shadows)->registry[instance->ao_idx] -
-		   instance->reg_base, 0);
-
-	// Trigger output.
-	outw(0x0000, instance->sim_output_reg);
-	PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->sim_output_reg - instance->reg_base, 0x0000);
-	outw(0xFFFF, instance->sim_output_reg);
-	PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->sim_output_reg - instance->reg_base, 0xFFFF);
-	spin_unlock(instance->config_regs_lock);
-	spin_unlock(instance->ao_shadows_lock);
-
-	// Set status to 'none'
-	instance->status = ao_status_none;
-	spin_unlock(&instance->subdevice_lock);
-
-	//Signal reset if user is on wait.
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-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)
-{
-	me1600_ao_subdevice_t *instance;
-	uint16_t tmp;
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	// Checking parameters.
-	if (flags) {
-		PERROR
-		    ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (trig_edge != ME_TRIG_EDGE_NONE) {
-		PERROR
-		    ("Invalid trigger edge. Software trigger has not edge. Must be ME_TRIG_EDGE_NONE\n");
-		return ME_ERRNO_INVALID_TRIG_EDGE;
-	}
-
-	if (trig_type != ME_TRIG_TYPE_SW) {
-		PERROR("Invalid trigger edge. Must be ME_TRIG_TYPE_SW.\n");
-		return ME_ERRNO_INVALID_TRIG_TYPE;
-	}
-
-	if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
-	    && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
-		PERROR("Invalid trigger channel specified.\n");
-		return ME_ERRNO_INVALID_TRIG_CHAN;
-	}
-
-	if (ref != ME_REF_AO_GROUND) {
-		PERROR
-		    ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if (((single_config + 1) >
-	     (instance->u_ranges_count + instance->i_ranges_count))
-	    || (single_config < 0)) {
-		PERROR("Invalid range specified.\n");
-		return ME_ERRNO_INVALID_SINGLE_CONFIG;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-	// Checking parameters - done. All is fine. Do config.
-
-	ME_SUBDEVICE_ENTER;
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ao_shadows_lock);
-	(instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx);	//Cancell waiting for trigger.
-	(instance->ao_regs_shadows)->shadow[instance->ao_idx] = 0;
-	(instance->ao_regs_shadows)->mirror[instance->ao_idx] = 0;
-
-	spin_lock(instance->config_regs_lock);
-	switch (single_config) {
-	case 0:		// 0V 10V
-		tmp = inw(instance->current_on_reg);	// Volts
-		tmp &= ~(0x1 << instance->ao_idx);
-		outw(tmp, instance->current_on_reg);
-		PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->current_on_reg - instance->reg_base, tmp);
-
-		// 0V
-		outw(0,
-		     (instance->ao_regs_shadows)->registry[instance->ao_idx]);
-		PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   (instance->ao_regs_shadows)->registry[instance->
-								 ao_idx] -
-			   instance->reg_base, 0);
-
-		tmp = inw(instance->uni_bi_reg);	// unipolar
-		tmp |= (0x1 << instance->ao_idx);
-		outw(tmp, instance->uni_bi_reg);
-		PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->uni_bi_reg - instance->reg_base, tmp);
-
-		tmp = inw(instance->i_range_reg);	// 0..20mA <= If exists.
-		tmp &= ~(0x1 << instance->ao_idx);
-		outw(tmp, instance->i_range_reg);
-		PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->i_range_reg - instance->reg_base, tmp);
-		break;
-
-	case 1:		// -10V 10V
-		tmp = inw(instance->current_on_reg);	// Volts
-		tmp &= ~(0x1 << instance->ao_idx);
-		outw(tmp, instance->current_on_reg);
-		PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->current_on_reg - instance->reg_base, tmp);
-
-		// 0V
-		outw(0x0800,
-		     (instance->ao_regs_shadows)->registry[instance->ao_idx]);
-		PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   (instance->ao_regs_shadows)->registry[instance->
-								 ao_idx] -
-			   instance->reg_base, 0x0800);
-
-		tmp = inw(instance->uni_bi_reg);	// bipolar
-		tmp &= ~(0x1 << instance->ao_idx);
-		outw(tmp, instance->uni_bi_reg);
-		PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->uni_bi_reg - instance->reg_base, tmp);
-
-		tmp = inw(instance->i_range_reg);	// 0..20mA <= If exists.
-		tmp &= ~(0x1 << instance->ao_idx);
-		outw(tmp, instance->i_range_reg);
-		PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->i_range_reg - instance->reg_base, tmp);
-		break;
-
-	case 2:		// 0mA 20mA
-		tmp = inw(instance->current_on_reg);	// mAmpers
-		tmp |= (0x1 << instance->ao_idx);
-		outw(tmp, instance->current_on_reg);
-		PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->current_on_reg - instance->reg_base, tmp);
-
-		tmp = inw(instance->i_range_reg);	// 0..20mA
-		tmp &= ~(0x1 << instance->ao_idx);
-		outw(tmp, instance->i_range_reg);
-		PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->i_range_reg - instance->reg_base, tmp);
-
-		// 0mA
-		outw(0,
-		     (instance->ao_regs_shadows)->registry[instance->ao_idx]);
-		PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   (instance->ao_regs_shadows)->registry[instance->
-								 ao_idx] -
-			   instance->reg_base, 0);
-
-		tmp = inw(instance->uni_bi_reg);	// unipolar
-		tmp |= (0x1 << instance->ao_idx);
-		outw(tmp, instance->uni_bi_reg);
-		PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->uni_bi_reg - instance->reg_base, tmp);
-		break;
-
-	case 3:		// 4mA 20mA
-		tmp = inw(instance->current_on_reg);	// mAmpers
-		tmp |= (0x1 << instance->ao_idx);
-		outw(tmp, instance->current_on_reg);
-		PDEBUG_REG("current_on_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->current_on_reg - instance->reg_base, tmp);
-
-		tmp = inw(instance->i_range_reg);	// 4..20mA
-		tmp |= (0x1 << instance->ao_idx);
-		outw(tmp, instance->i_range_reg);
-		PDEBUG_REG("i_range_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->i_range_reg - instance->reg_base, tmp);
-
-		// 4mA
-		outw(0,
-		     (instance->ao_regs_shadows)->registry[instance->ao_idx]);
-		PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   (instance->ao_regs_shadows)->registry[instance->
-								 ao_idx] -
-			   instance->reg_base, 0);
-
-		tmp = inw(instance->uni_bi_reg);	// unipolar
-		tmp |= (0x1 << instance->ao_idx);
-		outw(tmp, instance->uni_bi_reg);
-		PDEBUG_REG("uni_bi_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->uni_bi_reg - instance->reg_base, tmp);
-		break;
-	}
-
-	// Trigger output.
-	outw(0x0000, instance->sim_output_reg);
-	PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->sim_output_reg - instance->reg_base, 0x0000);
-	outw(0xFFFF, instance->sim_output_reg);
-	PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->sim_output_reg - instance->reg_base, 0xFFFF);
-
-	if (trig_chan == ME_TRIG_CHAN_DEFAULT) {	// Individual triggering.
-		(instance->ao_regs_shadows)->synchronous &=
-		    ~(0x1 << instance->ao_idx);
-		PDEBUG("Individual triggering.\n");
-	} else if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS) {	// Synchronous triggering.
-		(instance->ao_regs_shadows)->synchronous |=
-		    (0x1 << instance->ao_idx);
-		PDEBUG("Synchronous triggering.\n");
-	}
-	spin_unlock(instance->config_regs_lock);
-	spin_unlock(instance->ao_shadows_lock);
-
-	instance->status = ao_status_single_configured;
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me1600_ao_subdevice_t *instance;
-	unsigned long delay = 0;
-	unsigned long j = 0;
-	int err = ME_ERRNO_SUCCESS;
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
-		PERROR("Invalid flag specified. %d\n", flags);
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if ((!flags) && ((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)
-				delay = 1;
-		}
-
-		j = jiffies;
-
-		//Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (!((instance->
-						     ao_regs_shadows)->
-						    trigger & instance->
-						    ao_idx)),
-						 (delay) ? delay : LONG_MAX);
-
-		if (instance == ao_status_none) {	// Reset was called.
-			PDEBUG("Single canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		if ((delay) && ((jiffies - j) >= delay)) {
-			PDEBUG("Timeout reached.\n");
-			err = ME_ERRNO_TIMEOUT;
-		}
-	}
-
-	*value = (instance->ao_regs_shadows)->mirror[instance->ao_idx];
-
-	return err;
-}
-
-static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me1600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long delay = 0;
-	int i;
-	unsigned long j = 0;
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags &
-	    ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
-	      ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (value & ~ME1600_AO_MAX_DATA) {
-		PERROR("Invalid value provided.\n");
-		return ME_ERRNO_VALUE_OUT_OF_RANGE;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-	(instance->ao_regs_shadows)->trigger &= ~(0x1 << instance->ao_idx);	//Cancell waiting for trigger.
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-
-		if (delay == 0)
-			delay = 1;
-	}
-	//Write value.
-	spin_lock(instance->ao_shadows_lock);
-	(instance->ao_regs_shadows)->shadow[instance->ao_idx] =
-	    (uint16_t) value;
-
-	if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {	// Trigger all outputs from synchronous list.
-		for (i = 0; i < (instance->ao_regs_shadows)->count; i++) {
-			if (((instance->ao_regs_shadows)->synchronous & (0x1 << i)) || (i == instance->ao_idx)) {	// Set all from synchronous list to correct state.
-				PDEBUG
-				    ("Synchronous triggering: output %d. idx=%d\n",
-				     i, instance->ao_idx);
-				(instance->ao_regs_shadows)->mirror[i] =
-				    (instance->ao_regs_shadows)->shadow[i];
-
-				outw((instance->ao_regs_shadows)->shadow[i],
-				     (instance->ao_regs_shadows)->registry[i]);
-				PDEBUG_REG
-				    ("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     (instance->ao_regs_shadows)->registry[i] -
-				     instance->reg_base,
-				     (instance->ao_regs_shadows)->shadow[i]);
-
-				(instance->ao_regs_shadows)->trigger &=
-				    ~(0x1 << i);
-			}
-		}
-
-		// Trigger output.
-		outw(0x0000, instance->sim_output_reg);
-		PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->sim_output_reg - instance->reg_base, 0);
-		outw(0xFFFF, instance->sim_output_reg);
-		PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->sim_output_reg - instance->reg_base,
-			   0xFFFF);
-		instance->status = ao_status_single_end;
-	} else {		// Individual mode.
-		if ((instance->ao_regs_shadows)->synchronous & (0x1 << instance->ao_idx)) {	// Put on synchronous start list. Set output as waiting for trigger.
-			PDEBUG("Add to synchronous list. idx=%d\n",
-			       instance->ao_idx);
-			(instance->ao_regs_shadows)->trigger |=
-			    (0x1 << instance->ao_idx);
-			instance->status = ao_status_single_run;
-			PDEBUG("Synchronous list: 0x%x.\n",
-			       (instance->ao_regs_shadows)->synchronous);
-		} else {	// Fired this one.
-			PDEBUG("Triggering. idx=%d\n", instance->ao_idx);
-			(instance->ao_regs_shadows)->mirror[instance->ao_idx] =
-			    (instance->ao_regs_shadows)->shadow[instance->
-								ao_idx];
-
-			outw((instance->ao_regs_shadows)->
-			     shadow[instance->ao_idx],
-			     (instance->ao_regs_shadows)->registry[instance->
-								   ao_idx]);
-			PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   (instance->ao_regs_shadows)->
-				   registry[instance->ao_idx] -
-				   instance->reg_base,
-				   (instance->ao_regs_shadows)->
-				   shadow[instance->ao_idx]);
-
-			// Set output as triggered.
-			(instance->ao_regs_shadows)->trigger &=
-			    ~(0x1 << instance->ao_idx);
-
-			// Trigger output.
-			outw(0x0000, instance->sim_output_reg);
-			PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->sim_output_reg -
-				   instance->reg_base, 0);
-			outw(0xFFFF, instance->sim_output_reg);
-			PDEBUG_REG("sim_output_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->sim_output_reg -
-				   instance->reg_base, 0xFFFF);
-			instance->status = ao_status_single_end;
-		}
-	}
-	spin_unlock(instance->ao_shadows_lock);
-
-	//Init control task
-	instance->timeout.delay = delay;
-	instance->timeout.start_time = jiffies;
-	instance->ao_control_task_flag = 1;
-	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 (time_out) {
-			delay = (time_out * HZ) / 1000;
-			if (delay == 0)
-				delay = 1;
-		}
-
-		j = jiffies;
-
-		//Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (!((instance->
-						     ao_regs_shadows)->
-						    trigger & instance->
-						    ao_idx)),
-						 (delay) ? delay : LONG_MAX);
-
-		if (instance == ao_status_none) {
-			PDEBUG("Single canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		if ((delay) && ((jiffies - j) >= delay)) {
-			PDEBUG("Timeout reached.\n");
-			err = ME_ERRNO_TIMEOUT;
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	me1600_ao_subdevice_t *instance;
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*number = 1;		//Every subdevice has only 1 channel.
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
-					  int *subtype)
-{
-	me1600_ao_subdevice_t *instance;
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*type = ME_TYPE_AO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-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,
-					    int unit,
-					    int *min,
-					    int *max, int *maxdata, int *range)
-{
-	me1600_ao_subdevice_t *instance;
-	int i;
-	int r = -1;
-	int diff = 21E6;
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if ((*max - *min) < 0) {
-		PERROR("Invalid minimum and maximum values specified.\n");
-		return ME_ERRNO_INVALID_MIN_MAX;
-	}
-	// Maximum ranges are slightly less then 10V or 20mA. For convenient we accepted this value as valid one.
-	if (unit == ME_UNIT_VOLT) {
-		for (i = 0; i < instance->u_ranges_count; i++) {
-			if ((instance->u_ranges[i].min <= *min)
-			    && ((instance->u_ranges[i].max + 5000) >= *max)) {
-				if ((instance->u_ranges[i].max -
-				     instance->u_ranges[i].min) - (*max -
-								   *min) <
-				    diff) {
-					r = i;
-					diff =
-					    (instance->u_ranges[i].max -
-					     instance->u_ranges[i].min) -
-					    (*max - *min);
-				}
-			}
-		}
-
-		if (r < 0) {
-			PERROR("No matching range found.\n");
-			return ME_ERRNO_NO_RANGE;
-		} else {
-			*min = instance->u_ranges[r].min;
-			*max = instance->u_ranges[r].max;
-			*range = r;
-		}
-	} else if (unit == ME_UNIT_AMPERE) {
-		for (i = 0; i < instance->i_ranges_count; i++) {
-			if ((instance->i_ranges[i].min <= *min)
-			    && (instance->i_ranges[i].max + 5000 >= *max)) {
-				if ((instance->i_ranges[i].max -
-				     instance->i_ranges[i].min) - (*max -
-								   *min) <
-				    diff) {
-					r = i;
-					diff =
-					    (instance->i_ranges[i].max -
-					     instance->i_ranges[i].min) -
-					    (*max - *min);
-				}
-			}
-		}
-
-		if (r < 0) {
-			PERROR("No matching range found.\n");
-			return ME_ERRNO_NO_RANGE;
-		} else {
-			*min = instance->i_ranges[r].min;
-			*max = instance->i_ranges[r].max;
-			*range = r + instance->u_ranges_count;
-		}
-	} else {
-		PERROR("Invalid physical unit specified.\n");
-		return ME_ERRNO_INVALID_UNIT;
-	}
-	*maxdata = ME1600_AO_MAX_DATA;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice,
-					 int unit, int *count)
-{
-	me1600_ao_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-	switch (unit) {
-	case ME_UNIT_VOLT:
-		*count = instance->u_ranges_count;
-		break;
-	case ME_UNIT_AMPERE:
-		*count = instance->i_ranges_count;
-		break;
-	case ME_UNIT_ANY:
-		*count = instance->u_ranges_count + instance->i_ranges_count;
-		break;
-	default:
-		*count = 0;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1600_ao_query_range_info(me_subdevice_t *subdevice,
-				      int range,
-				      int *unit,
-				      int *min, int *max, int *maxdata)
-{
-	me1600_ao_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me1600_ao_subdevice_t *) subdevice;
-
-	if (((range + 1) >
-	     (instance->u_ranges_count + instance->i_ranges_count))
-	    || (range < 0)) {
-		PERROR("Invalid range number specified.\n");
-		return ME_ERRNO_INVALID_RANGE;
-	}
-
-	if (range < instance->u_ranges_count) {
-		*unit = ME_UNIT_VOLT;
-		*min = instance->u_ranges[range].min;
-		*max = instance->u_ranges[range].max;
-	} else if (range < instance->u_ranges_count + instance->i_ranges_count) {
-		*unit = ME_UNIT_AMPERE;
-		*min = instance->i_ranges[range - instance->u_ranges_count].min;
-		*max = instance->i_ranges[range - instance->u_ranges_count].max;
-	}
-	*maxdata = ME1600_AO_MAX_DATA;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static void me1600_ao_work_control_task(struct work_struct *work)
-{
-	me1600_ao_subdevice_t *instance;
-	int reschedule = 1;
-	int signaling = 0;
-
-	instance =
-	    container_of((void *)work, me1600_ao_subdevice_t, ao_control_task);
-
-	PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
-	      instance->ao_idx);
-
-	if (!((instance->ao_regs_shadows)->trigger & instance->ao_idx)) {	// Output was triggerd.
-		// Signal the end.
-		signaling = 1;
-		reschedule = 0;
-		if (instance->status == ao_status_single_run) {
-			instance->status = ao_status_single_end;
-		}
-
-	} else if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) {	// Timeout
-		PDEBUG("Timeout reached.\n");
-		spin_lock(instance->ao_shadows_lock);
-		// Restore old settings.
-		PDEBUG("Write old value back to register.\n");
-		(instance->ao_regs_shadows)->shadow[instance->ao_idx] =
-		    (instance->ao_regs_shadows)->mirror[instance->ao_idx];
-
-		outw((instance->ao_regs_shadows)->mirror[instance->ao_idx],
-		     (instance->ao_regs_shadows)->registry[instance->ao_idx]);
-		PDEBUG_REG("channel_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   (instance->ao_regs_shadows)->registry[instance->
-								 ao_idx] -
-			   instance->reg_base,
-			   (instance->ao_regs_shadows)->mirror[instance->
-							       ao_idx]);
-
-		//Remove from synchronous strt list.
-		(instance->ao_regs_shadows)->trigger &=
-		    ~(0x1 << instance->ao_idx);
-		if (instance->status == ao_status_none) {
-			instance->status = ao_status_single_end;
-		}
-		spin_unlock(instance->ao_shadows_lock);
-
-		// Signal the end.
-		signaling = 1;
-		reschedule = 0;
-	}
-
-	if (signaling) {	//Signal it.
-		wake_up_interruptible_all(&instance->wait_queue);
-	}
-
-	if (instance->ao_control_task_flag && reschedule) {	// Reschedule task
-		queue_delayed_work(instance->me1600_workqueue,
-				   &instance->ao_control_task, 1);
-	} else {
-		PINFO("<%s> Ending control task.\n", __func__);
-	}
-
-}
diff --git a/drivers/staging/meilhaus/me1600_ao.h b/drivers/staging/meilhaus/me1600_ao.h
deleted file mode 100644
index 4827dcb..0000000
--- a/drivers/staging/meilhaus/me1600_ao.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * @file me1600_ao.h
- *
- * @brief Meilhaus ME-1600 analog output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1600_AO_H_
-#define _ME1600_AO_H_
-
-# include <linux/version.h>
-# include "mesubdevice.h"
-
-# ifdef __KERNEL__
-
-#  define ME1600_MAX_RANGES	2	/**< Specifies the maximum number of ranges in me1600_ao_subdevice_t::u_ranges und me1600_ao_subdevice_t::i_ranges. */
-
-/**
- * @brief Defines a entry in the range table.
- */
-typedef struct me1600_ao_range_entry {
-	int32_t min;
-	int32_t max;
-} me1600_ao_range_entry_t;
-
-typedef struct me1600_ao_timeout {
-	unsigned long start_time;
-	unsigned long delay;
-} me1600_ao_timeout_t;
-
-typedef struct me1600_ao_shadow {
-	int count;
-	unsigned long *registry;
-	uint16_t *shadow;
-	uint16_t *mirror;
-	uint16_t synchronous;									/**< Synchronization list. */
-	uint16_t trigger;										/**< Synchronization flag. */
-} me1600_ao_shadow_t;
-
-typedef enum ME1600_AO_STATUS {
-	ao_status_none = 0,
-	ao_status_single_configured,
-	ao_status_single_run,
-	ao_status_single_end,
-	ao_status_last
-} ME1600_AO_STATUS;
-
-/**
- * @brief The ME-1600 analog output subdevice class.
- */
-typedef struct me1600_ao_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;									/**< The subdevice base class. */
-
-	/* Attributes */
-	int ao_idx;												/**< The index of the analog output subdevice on the device. */
-
-	spinlock_t subdevice_lock;								/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *config_regs_lock;							/**< Spin lock to protect configuration registers from concurrent access. */
-
-	int u_ranges_count;										/**< The number of voltage ranges available on this subdevice. */
-	me1600_ao_range_entry_t u_ranges[ME1600_MAX_RANGES];	/**< Array holding the voltage ranges on this subdevice. */
-	int i_ranges_count;										/**< The number of current ranges available on this subdevice. */
-	me1600_ao_range_entry_t i_ranges[ME1600_MAX_RANGES];	/**< Array holding the current ranges on this subdevice. */
-
-	/* Registers */
-	unsigned long uni_bi_reg;								/**< Register for switching between unipoar and bipolar output mode. */
-	unsigned long i_range_reg;								/**< Register for switching between ranges. */
-	unsigned long sim_output_reg;							/**< Register used in order to update all channels simultaneously. */
-	unsigned long current_on_reg;							/**< Register enabling current output on the fourth subdevice. */
-#   ifdef PDEBUG_REG
-	unsigned long reg_base;
-#   endif
-
-	ME1600_AO_STATUS status;
-	me1600_ao_shadow_t *ao_regs_shadows;					/**< Addresses and shadows of output's registers. */
-	spinlock_t *ao_shadows_lock;							/**< Protects the shadow's struct. */
-	int mode;												/**< Mode in witch output should works. */
-	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;
-	struct delayed_work ao_control_task;
-
-	volatile int ao_control_task_flag;						/**< Flag controling reexecuting of control task */
-} me1600_ao_subdevice_t;
-
-/**
- * @brief The constructor to generate a subdevice template instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ao_idx The index of the analog output subdevice on the device.
- * @param current Flag indicating that analog output with #ao_idx of 3 is capable of current output.
- * @param config_regs_lock Pointer to spin lock protecting the configuration registers and from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-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,
-					     struct workqueue_struct
-					     *me1600_wq);
-
-# endif	//__KERNEL__
-#endif //_ME1600_AO_H_
diff --git a/drivers/staging/meilhaus/me1600_ao_reg.h b/drivers/staging/meilhaus/me1600_ao_reg.h
deleted file mode 100644
index 31e7800..0000000
--- a/drivers/staging/meilhaus/me1600_ao_reg.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file me1600_ao_reg.h
- *
- * @brief ME-1600 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1600_AO_REG_H_
-#define _ME1600_AO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME1600_CHANNEL_0_REG    0x00	/**< Register to set a digital value on channel 0. */
-#define ME1600_CHANNEL_1_REG    0x02	/**< Register to set a digital value on channel 1. */
-#define ME1600_CHANNEL_2_REG    0x04	/**< Register to set a digital value on channel 2. */
-#define ME1600_CHANNEL_3_REG    0x06	/**< Register to set a digital value on channel 3. */
-#define ME1600_CHANNEL_4_REG    0x08	/**< Register to set a digital value on channel 4. */
-#define ME1600_CHANNEL_5_REG    0x0A	/**< Register to set a digital value on channel 5. */
-#define ME1600_CHANNEL_6_REG    0x0C	/**< Register to set a digital value on channel 6. */
-#define ME1600_CHANNEL_7_REG    0x0E	/**< Register to set a digital value on channel 7. */
-#define ME1600_CHANNEL_8_REG    0x10	/**< Register to set a digital value on channel 8. */
-#define ME1600_CHANNEL_9_REG    0x12	/**< Register to set a digital value on channel 9. */
-#define ME1600_CHANNEL_10_REG   0x14	/**< Register to set a digital value on channel 10. */
-#define ME1600_CHANNEL_11_REG   0x16	/**< Register to set a digital value on channel 11. */
-#define ME1600_CHANNEL_12_REG   0x18	/**< Register to set a digital value on channel 12. */
-#define ME1600_CHANNEL_13_REG   0x1A	/**< Register to set a digital value on channel 13. */
-#define ME1600_CHANNEL_14_REG   0x1C	/**< Register to set a digital value on channel 14. */
-#define ME1600_CHANNEL_15_REG   0x1E	/**< Register to set a digital value on channel 15. */
-
-/* Every channel one bit: bipolar = 0, unipolar = 1 */
-#define ME1600_UNI_BI_REG		0x20	/**< Register to switch between unipolar and bipolar. */
-
-/* Every channel one bit (only lower 8 Bits): 0..20mA = 0, 4..20mA = 1 */
-#define ME1600_020_420_REG		0x22	/**< Register to switch between the two current ranges. */
-
-/* If a bit is set, the corresponding DAC (4 ports each) is
-   not set at the moment you write to an output of it.
-   Clearing the bit updates the port. */
-#define ME1600_SIM_OUTPUT_REG	0x24	/**< Register to update all channels of a subdevice simultaneously. */
-
-/* Current on/off (only lower 8 bits): off = 0, on  = 1 */
-#define ME1600_CURRENT_ON_REG	0x26	/**< Register to swicht between voltage and current output. */
-
-#define ME1600_AO_MAX_DATA		0x0FFF	/**< The maximum digital data accepted by an analog output channel. */
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me1600_device.c b/drivers/staging/meilhaus/me1600_device.c
deleted file mode 100644
index c244e98..0000000
--- a/drivers/staging/meilhaus/me1600_device.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/**
- * @file me1600_device.c
- *
- * @brief ME-1600 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "mesubdevice.h"
-#include "me1600_device.h"
-
-static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base);
-static void me1600_destructor(struct me_device *device);
-
-/**
- * @brief Global variable.
- * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
- */
-static struct workqueue_struct *me1600_workqueue;
-
-me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
-{
-	int err;
-	me1600_device_t *me1600_device;
-	me_subdevice_t *subdevice;
-	unsigned int chip_idx;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me1600_device = kmalloc(sizeof(me1600_device_t), GFP_KERNEL);
-
-	if (!me1600_device) {
-		PERROR("Cannot get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(me1600_device, 0, sizeof(me1600_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me1600_device, pci_device);
-
-	if (err) {
-		kfree(me1600_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-	// Initialize spin lock .
-	spin_lock_init(&me1600_device->config_regs_lock);
-	spin_lock_init(&me1600_device->ao_shadows_lock);
-
-	// Get the number of analog output subdevices.
-	chip_idx =
-	    me1600_versions_get_device_index(me1600_device->base.info.pci.
-					     device_id);
-
-	// Create shadow instance.
-	me1600_device->ao_regs_shadows.count =
-	    me1600_versions[chip_idx].ao_chips;
-	me1600_device->ao_regs_shadows.registry =
-	    kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(unsigned long),
-		    GFP_KERNEL);
-	me1600_set_registry(me1600_device,
-			    me1600_device->base.info.pci.reg_bases[2]);
-	me1600_device->ao_regs_shadows.shadow =
-	    kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t),
-		    GFP_KERNEL);
-	me1600_device->ao_regs_shadows.mirror =
-	    kmalloc(me1600_versions[chip_idx].ao_chips * sizeof(uint16_t),
-		    GFP_KERNEL);
-
-	// Create subdevice instances.
-	for (i = 0; i < me1600_versions[chip_idx].ao_chips; i++) {
-		subdevice =
-		    (me_subdevice_t *) me1600_ao_constructor(me1600_device->
-							     base.info.pci.
-							     reg_bases[2], i,
-							     ((me1600_versions
-							       [chip_idx].curr >
-							       i) ? 1 : 0),
-							     &me1600_device->
-							     config_regs_lock,
-							     &me1600_device->
-							     ao_shadows_lock,
-							     &me1600_device->
-							     ao_regs_shadows,
-							     me1600_workqueue);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me1600_device);
-			kfree(me1600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me1600_device->base.slist,
-					    subdevice);
-	}
-
-	// Overwrite base class methods.
-	me1600_device->base.me_device_destructor = me1600_destructor;
-
-	return (me_device_t *) me1600_device;
-}
-EXPORT_SYMBOL(me1600_pci_constructor);
-
-static void me1600_destructor(struct me_device *device)
-{
-	me1600_device_t *me1600_device = (me1600_device_t *) device;
-	PDEBUG("executed.\n");
-
-	// Destroy shadow instance.
-	kfree(me1600_device->ao_regs_shadows.registry);
-	kfree(me1600_device->ao_regs_shadows.shadow);
-	kfree(me1600_device->ao_regs_shadows.mirror);
-
-	me_device_deinit((me_device_t *) me1600_device);
-	kfree(me1600_device);
-}
-
-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] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_0_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 2) {
-		subdevice->ao_regs_shadows.registry[1] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_1_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 3) {
-		subdevice->ao_regs_shadows.registry[2] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_2_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 4) {
-		subdevice->ao_regs_shadows.registry[3] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_3_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 5) {
-		subdevice->ao_regs_shadows.registry[4] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_4_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 6) {
-		subdevice->ao_regs_shadows.registry[5] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_5_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 7) {
-		subdevice->ao_regs_shadows.registry[6] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_6_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 8) {
-		subdevice->ao_regs_shadows.registry[7] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_7_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 9) {
-		subdevice->ao_regs_shadows.registry[8] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_8_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 10) {
-		subdevice->ao_regs_shadows.registry[9] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_9_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 11) {
-		subdevice->ao_regs_shadows.registry[10] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_10_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 12) {
-		subdevice->ao_regs_shadows.registry[11] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_11_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 13) {
-		subdevice->ao_regs_shadows.registry[12] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_12_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 14) {
-		subdevice->ao_regs_shadows.registry[13] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_13_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 15) {
-		subdevice->ao_regs_shadows.registry[14] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_14_REG);
-	}
-	if (subdevice->ao_regs_shadows.count >= 16) {
-		subdevice->ao_regs_shadows.registry[15] =
-		    (unsigned long)(reg_base + ME1600_CHANNEL_15_REG);
-	}
-	if (subdevice->ao_regs_shadows.count > 16) {
-		PERROR("More than 16 outputs! (%d)\n",
-		       subdevice->ao_regs_shadows.count);
-	}
-}
-
-// Init and exit of module.
-
-static int __init me1600_init(void)
-{
-	PDEBUG("executed\n.");
-
-	me1600_workqueue = create_singlethread_workqueue("me1600");
-	return 0;
-}
-
-static void __exit me1600_exit(void)
-{
-	PDEBUG("executed\n.");
-
-	flush_workqueue(me1600_workqueue);
-	destroy_workqueue(me1600_workqueue);
-}
-
-module_init(me1600_init);
-module_exit(me1600_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-1600 Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-1600 Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me1600_device.h b/drivers/staging/meilhaus/me1600_device.h
deleted file mode 100644
index f7b231f..0000000
--- a/drivers/staging/meilhaus/me1600_device.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * @file me1600_device.h
- *
- * @brief ME-1600 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME1600_H
-#define _ME1600_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-#include "me1600_ao.h"
-#include "me1600_ao_reg.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure to store device capabilities.
- */
-typedef struct me1600_version {
-	uint16_t device_id;				/**< The PCI device id of the device. */
-	unsigned int ao_chips;			/**< The number of analog outputs on the device. */
-	int curr;						/**< Flag to identify amounts of current output. */
-} me1600_version_t;
-
-/**
-  * @brief Defines for each ME-1600 device version its capabilities.
- */
-static me1600_version_t me1600_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME1600_4U, 4, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME1600_8U, 8, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME1600_12U, 12, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME1600_16U, 16, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I, 16, 8},
-	{0}
-};
-
-/**< Returns the number of entries in #me1600_versions. */
-#define ME1600_DEVICE_VERSIONS (sizeof(me1600_versions) / sizeof(me1600_version_t) - 1)
-
-/**
- * @brief Returns the index of the device entry in #me1600_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me1600_versions.
- */
-static inline unsigned int me1600_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME1600_DEVICE_VERSIONS; i++)
-		if (me1600_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The ME-1600 device class structure.
- */
-typedef struct me1600_device {
-	me_device_t base;						/**< The Meilhaus device base class. */
-	spinlock_t config_regs_lock;			/**< Protects the configuration registers. */
-
-	me1600_ao_shadow_t ao_regs_shadows;		/**< Addresses and shadows of output's registers. */
-	spinlock_t ao_shadows_lock;				/**< Protects the shadow's struct. */
-} me1600_device_t;
-
-/**
- * @brief The ME-1600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-1600 device instance. \n
- *         NULL on error.
- */
-me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ai.c b/drivers/staging/meilhaus/me4600_ai.c
deleted file mode 100644
index e496d0c..0000000
--- a/drivers/staging/meilhaus/me4600_ai.c
+++ /dev/null
@@ -1,3405 +0,0 @@
-/**
- * @file me4600_ai.c
- *
- * @brief ME-4000 analog input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-# define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-#include "meids.h"
-
-#include "me4600_reg.h"
-#include "me4600_ai_reg.h"
-#include "me4600_ai.h"
-
-/*
- * Declarations (local)
- */
-
-static void me4600_ai_destructor(struct me_subdevice *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,
-				      struct file *filep,
-				      int channel,
-				      int single_config,
-				      int ref,
-				      int trig_chan,
-				      int trig_type, int trig_edge, int flags);
-
-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,
-				      struct file *filep,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      meIOStreamTrigger_t *trigger,
-				      int fifo_irq_threshold, int flags);
-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,
-					  struct file *filep,
-					  int time_out, int *count, int flags);
-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,
-				     struct file *filep,
-				     int start_mode, int time_out, int flags);
-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,
-				      struct file *filep,
-				      int wait,
-				      int *status, int *values, int flags);
-
-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,
-					 int unit, int *count);
-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,
-				 int timer,
-				 int *base_frequency,
-				 long long *min_ticks, long long *max_ticks);
-static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
-					   int *number);
-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,
-					  int *caps);
-static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
-					       int cap, int *args, int count);
-
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id);
-
-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);
-
-/** Immidiate stop.
-* Reset all IRQ's sources. (block laches)
-* Reset data FIFO
-*/
-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,
-		    const uint32_t ctrl_status);
-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.(!!!)
-*/
-inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance);
-
-/** Read datas from FIFO and copy them to buffer */
-static inline int ai_read_data(me4600_ai_subdevice_t *instance,
-			       const int count);
-
-/** Copy rest of data from fifo to circular buffer.*/
-static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance);
-
-/** Set ISM to next state for infinite data aqusation mode*/
-inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance);
-
-/** Set ISM to next state for define amount of data aqusation mode*/
-inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
-			   uint32_t irq_status);
-
-/** Set ISM to next stage for limited mode */
-inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance);
-
-static void me4600_ai_work_control_task(struct work_struct *work);
-
-/* Definitions
- */
-
-me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
-					     unsigned int channels,
-					     unsigned int ranges,
-					     int isolated,
-					     int sh,
-					     int irq,
-					     spinlock_t *ctrl_reg_lock,
-					     struct workqueue_struct *me4600_wq)
-{
-	me4600_ai_subdevice_t *subdevice;
-	int err;
-	unsigned int i;
-
-	PDEBUG("executed. idx=0\n");
-
-	// Allocate memory for subdevice instance.
-	subdevice = kmalloc(sizeof(me4600_ai_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me4600_ai_subdevice_t));
-
-	// Initialize subdevice base class.
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	// Initialize circular buffer.
-	subdevice->circ_buf.mask = ME4600_AI_CIRC_BUF_COUNT - 1;
-
-	subdevice->circ_buf.buf =
-	    (void *)__get_free_pages(GFP_KERNEL, ME4600_AI_CIRC_BUF_SIZE_ORDER);
-	PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
-	       ME4600_AI_CIRC_BUF_SIZE);
-
-	if (!subdevice->circ_buf.buf) {
-		PERROR("Cannot get circular buffer.\n");
-		me_subdevice_deinit((me_subdevice_t *) subdevice);
-		kfree(subdevice);
-		return NULL;
-	}
-
-	memset(subdevice->circ_buf.buf, 0, ME4600_AI_CIRC_BUF_SIZE);
-	subdevice->circ_buf.head = 0;
-	subdevice->circ_buf.tail = 0;
-	subdevice->status = ai_status_none;
-
-	// Initialize wait queue.
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	// Save the number of channels.
-	subdevice->channels = channels;
-
-	/* Initialize the single config entries to reset values */
-	for (i = 0; i < channels; i++) {
-		subdevice->single_config[i].status = ME_SINGLE_CHANNEL_NOT_CONFIGURED;	//not configured
-	}
-
-	// Save if isolated device.
-	subdevice->isolated = isolated;
-
-	// Save if sample and hold is available.
-	subdevice->sh = sh;
-
-	// Set stream config to not configured state.
-	subdevice->fifo_irq_threshold = 0;
-	subdevice->data_required = 0;
-	subdevice->chan_list_len = 0;
-
-	// Initialize registers addresses.
-	subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG;
-	subdevice->status_reg = reg_base + ME4600_AI_STATUS_REG;
-	subdevice->channel_list_reg = reg_base + ME4600_AI_CHANNEL_LIST_REG;
-	subdevice->data_reg = reg_base + ME4600_AI_DATA_REG;
-	subdevice->chan_timer_reg = reg_base + ME4600_AI_CHAN_TIMER_REG;
-	subdevice->chan_pre_timer_reg = reg_base + ME4600_AI_CHAN_PRE_TIMER_REG;
-	subdevice->scan_timer_low_reg = reg_base + ME4600_AI_SCAN_TIMER_LOW_REG;
-	subdevice->scan_timer_high_reg =
-	    reg_base + ME4600_AI_SCAN_TIMER_HIGH_REG;
-	subdevice->scan_pre_timer_low_reg =
-	    reg_base + ME4600_AI_SCAN_PRE_TIMER_LOW_REG;
-	subdevice->scan_pre_timer_high_reg =
-	    reg_base + ME4600_AI_SCAN_PRE_TIMER_HIGH_REG;
-	subdevice->start_reg = reg_base + ME4600_AI_START_REG;
-	subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
-	subdevice->sample_counter_reg = reg_base + ME4600_AI_SAMPLE_COUNTER_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	// Initialize ranges.
-	subdevice->ranges_len = ranges;
-	subdevice->ranges[0].min = -10E6;
-	subdevice->ranges[0].max = 9999694;
-
-	subdevice->ranges[1].min = 0;
-	subdevice->ranges[1].max = 9999847;
-
-	subdevice->ranges[2].min = -25E5;
-	subdevice->ranges[2].max = 2499923;
-
-	subdevice->ranges[3].min = 0;
-	subdevice->ranges[3].max = 2499961;
-
-	// We have to switch the mux in order to get it work correctly.
-	ai_mux_toggler(subdevice);
-
-	// Register interrupt service routine.
-	subdevice->irq = irq;
-	if (request_irq(subdevice->irq, me4600_ai_isr,
-			IRQF_DISABLED | IRQF_SHARED,
-			ME4600_NAME, subdevice)) {
-		PERROR("Cannot register interrupt service routine.\n");
-		me_subdevice_deinit((me_subdevice_t *) subdevice);
-		free_pages((unsigned long)subdevice->circ_buf.buf,
-			   ME4600_AI_CIRC_BUF_SIZE_ORDER);
-		subdevice->circ_buf.buf = NULL;
-		kfree(subdevice);
-		return NULL;
-	}
-	PINFO("Registered irq=%d.\n", subdevice->irq);
-
-	// Override base class methods.
-	subdevice->base.me_subdevice_destructor = me4600_ai_destructor;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me4600_ai_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me4600_ai_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me4600_ai_io_single_read;
-	subdevice->base.me_subdevice_io_stream_config =
-	    me4600_ai_io_stream_config;
-	subdevice->base.me_subdevice_io_stream_new_values =
-	    me4600_ai_io_stream_new_values;
-	subdevice->base.me_subdevice_io_stream_read = me4600_ai_io_stream_read;
-	subdevice->base.me_subdevice_io_stream_start =
-	    me4600_ai_io_stream_start;
-	subdevice->base.me_subdevice_io_stream_status =
-	    me4600_ai_io_stream_status;
-	subdevice->base.me_subdevice_io_stream_stop = me4600_ai_io_stream_stop;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me4600_ai_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me4600_ai_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me4600_ai_query_subdevice_caps;
-	subdevice->base.me_subdevice_query_subdevice_caps_args =
-	    me4600_ai_query_subdevice_caps_args;
-	subdevice->base.me_subdevice_query_range_by_min_max =
-	    me4600_ai_query_range_by_min_max;
-	subdevice->base.me_subdevice_query_number_ranges =
-	    me4600_ai_query_number_ranges;
-	subdevice->base.me_subdevice_query_range_info =
-	    me4600_ai_query_range_info;
-	subdevice->base.me_subdevice_query_timer = me4600_ai_query_timer;
-
-	// Prepare work queue.
-	subdevice->me4600_workqueue = me4600_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
-	INIT_DELAYED_WORK(&subdevice->ai_control_task,
-			  me4600_ai_work_control_task);
-
-	return subdevice;
-}
-
-static void me4600_ai_destructor(struct me_subdevice *subdevice)
-{
-	me4600_ai_subdevice_t *instance;
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance->ai_control_task_flag = 0;
-	// Reset subdevice to asure clean exit.
-	me4600_ai_io_reset_subdevice(subdevice, NULL,
-				     ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
-	// Remove any tasks from work queue. This is paranoic because it was done allready in reset().
-	if (!cancel_delayed_work(&instance->ai_control_task)) {	//Wait 2 ticks to be sure that control task is removed from queue.
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(2);
-	}
-
-	free_irq(instance->irq, instance);
-	free_pages((unsigned long)instance->circ_buf.buf,
-		   ME4600_AI_CIRC_BUF_SIZE_ORDER);
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
-					struct file *filep, int flags)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	volatile uint32_t ctrl;
-	unsigned long status;
-	const int timeout = HZ / 10;	//100ms
-	int i;
-
-	PDEBUG("executed. idx=0\n");
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	instance->ai_control_task_flag = 0;
-	instance->status = ai_status_none;
-
-	for (i = 0; i <= timeout; i++) {
-		spin_lock_irqsave(instance->ctrl_reg_lock, status);
-		ctrl = inl(instance->ctrl_reg);
-		//Stop DMA
-		ctrl &= ~ME4600_AI_CTRL_RPCI_FIFO;
-		// Stop all actions. No conditions!
-		ctrl &= ~ME4600_AI_CTRL_BIT_STOP;
-		ctrl |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
-
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		spin_unlock_irqrestore(instance->ctrl_reg_lock, status);
-
-		if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM))
-			break;
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
-	}
-
-	if (i > timeout) {
-		PERROR("FSM is still busy.\n");
-		ME_SUBDEVICE_EXIT;
-		return ME_ERRNO_INTERNAL;
-	}
-
-	spin_lock_irqsave(instance->ctrl_reg_lock, status);
-	ctrl = inl(instance->ctrl_reg);
-	// Clear all features. Dissable interrupts.
-	ctrl &= ~(ME4600_AI_CTRL_BIT_STOP
-		  | ME4600_AI_CTRL_BIT_LE_IRQ
-		  | ME4600_AI_CTRL_BIT_HF_IRQ | ME4600_AI_CTRL_BIT_SC_IRQ);
-	ctrl |= (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP
-		 | ME4600_AI_CTRL_BIT_LE_IRQ_RESET
-		 | ME4600_AI_CTRL_BIT_HF_IRQ_RESET
-		 | ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
-
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock_irqrestore(instance->ctrl_reg_lock, status);
-
-	outl(ME4600_AI_MIN_CHAN_TICKS - 1, instance->chan_timer_reg);
-	PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llx\n",
-		   instance->reg_base,
-		   instance->chan_timer_reg - instance->reg_base,
-		   ME4600_AI_MIN_CHAN_TICKS);
-	outl(ME4600_AI_MIN_ACQ_TICKS - 1, instance->chan_pre_timer_reg);
-	PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llx\n",
-		   instance->reg_base,
-		   instance->chan_pre_timer_reg - instance->reg_base,
-		   ME4600_AI_MIN_ACQ_TICKS);
-	outl(0, instance->scan_timer_low_reg);
-	PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_timer_low_reg - instance->reg_base, 0);
-	outl(0, instance->scan_timer_high_reg);
-	PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_timer_high_reg - instance->reg_base, 0);
-	outl(0, instance->scan_pre_timer_low_reg);
-	PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_low_reg - instance->reg_base, 0);
-	outl(0, instance->scan_pre_timer_high_reg);
-	PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_high_reg - instance->reg_base, 0);
-	outl(0xEFFFFFFF, instance->sample_counter_reg);
-	PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->sample_counter_reg - instance->reg_base,
-		   0xEFFFFFFF);
-
-	instance->circ_buf.head = 0;
-	instance->circ_buf.tail = 0;
-
-	instance->fifo_irq_threshold = 0;
-	instance->data_required = 0;
-	instance->chan_list_len = 0;
-
-	// Initialize the single config entries to reset values.
-	for (i = 0; i < instance->channels; i++) {
-		instance->single_config[i].status =
-		    ME_SINGLE_CHANNEL_NOT_CONFIGURED;
-	}
-	instance->status = ai_status_none;
-
-	//Signal reset if user is on wait.
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ai_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)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags;
-	int i;
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=0\n");
-
-	if (flags & ~ME_IO_SINGLE_CONFIG_CONTINUE) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	switch (trig_type) {
-	case ME_TRIG_TYPE_SW:
-		if (trig_edge != ME_TRIG_EDGE_NONE) {
-			PERROR
-			    ("Invalid trigger edge. Software trigger has not edge.\n");
-			return ME_ERRNO_INVALID_TRIG_EDGE;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		if (instance->channels <= 16)	//Only versions with 32 channels have analog trigger (4670 and 4680)
-		{
-			PERROR("Invalid trigger type specified.\n");
-			return ME_ERRNO_INVALID_TRIG_TYPE;
-		}
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		if ((trig_edge != ME_TRIG_EDGE_ANY)
-		    && (trig_edge != ME_TRIG_EDGE_RISING)
-		    && (trig_edge != ME_TRIG_EDGE_FALLING)) {
-			PERROR("Invalid trigger edge specified.\n");
-			return ME_ERRNO_INVALID_TRIG_EDGE;
-		}
-		break;
-
-	default:
-		PERROR("Invalid trigger type specified.\n");
-		return ME_ERRNO_INVALID_TRIG_TYPE;
-	}
-
-	if (trig_chan != ME_TRIG_CHAN_DEFAULT) {
-		PERROR("Invalid trigger channel specified.\n");
-		return ME_ERRNO_INVALID_TRIG_CHAN;
-	}
-
-	if ((single_config < 0) || (single_config >= instance->ranges_len)) {
-		PERROR("Invalid single config specified.\n");
-		return ME_ERRNO_INVALID_SINGLE_CONFIG;
-	}
-
-	if ((ref != ME_REF_AI_GROUND) && (ref != ME_REF_AI_DIFFERENTIAL)) {
-		PERROR("Invalid analog reference specified.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if ((single_config % 2) && (ref != ME_REF_AI_GROUND)) {
-		PERROR("Invalid analog reference specified.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if ((ref == ME_REF_AI_DIFFERENTIAL)
-	    && ((instance->channels == 16) || (channel >= 16))) {
-		PERROR("Invalid analog reference specified.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if (channel < 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (channel >= instance->channels) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	//Prepare data entry.
-	// Common for all modes.
-	instance->single_config[channel].entry =
-	    channel | ME4600_AI_LIST_LAST_ENTRY;
-
-	if (ref == ME_REF_AI_DIFFERENTIAL) {	// ME_REF_AI_DIFFERENTIAL
-		instance->single_config[channel].entry |=
-		    ME4600_AI_LIST_INPUT_DIFFERENTIAL;
-	}
-/*
-		// ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000
-		// 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' <== Do nothing. Removed.
-		else
-		{// ME_REF_AI_GROUND
-			instance->single_config[channel].entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED;
-		}
-*/
-	switch (single_config) {
-	case 0:		//-10V..10V
-/*
-					// ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000
-					// 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed.
-					instance->single_config[channel].entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10;
-*/ break;
-
-	case 1:		//0V..10V
-		instance->single_config[channel].entry |=
-		    ME4600_AI_LIST_RANGE_UNIPOLAR_10;
-		break;
-
-	case 2:		//-2.5V..2.5V
-		instance->single_config[channel].entry |=
-		    ME4600_AI_LIST_RANGE_BIPOLAR_2_5;
-		break;
-
-	case 3:		//0V..2.5V
-		instance->single_config[channel].entry |=
-		    ME4600_AI_LIST_RANGE_UNIPOLAR_2_5;
-		break;
-	}
-
-	// Prepare control register.
-	// Common for all modes.
-	instance->single_config[channel].ctrl =
-	    ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
-
-	switch (trig_type) {
-	case ME_TRIG_TYPE_SW:
-		// Nothing to set.
-		break;
-
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		instance->single_config[channel].ctrl |=
-		    ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		instance->single_config[channel].ctrl |=
-		    ME4600_AI_CTRL_BIT_EX_TRIG;
-		break;
-	}
-
-	switch (trig_edge) {
-	case ME_TRIG_EDGE_RISING:
-		// Nothing to set.
-		break;
-
-	case ME_TRIG_EDGE_ANY:
-		instance->single_config[channel].ctrl |=
-		    ME4600_AI_CTRL_BIT_EX_TRIG_BOTH;
-
-	case ME_TRIG_EDGE_FALLING:
-		instance->single_config[channel].ctrl |=
-		    ME4600_AI_CTRL_BIT_EX_TRIG_FALLING;
-		break;
-	}
-
-	// Enable this channel
-	instance->single_config[channel].status = ME_SINGLE_CHANNEL_CONFIGURED;
-
-	// Copy this settings to other outputs.
-	if (flags == ME_IO_SINGLE_CONFIG_CONTINUE) {
-		for (i = channel + 1; i < instance->channels; i++) {
-			instance->single_config[i].ctrl =
-			    instance->single_config[channel].ctrl;
-			instance->single_config[i].entry =
-			    instance->single_config[channel].entry;
-			instance->single_config[i].status =
-			    ME_SINGLE_CHANNEL_CONFIGURED;
-		}
-	}
-
-	instance->status = ai_status_single_configured;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me4600_ai_subdevice_t *instance;
-	volatile uint32_t tmp;
-	volatile uint32_t val;
-	unsigned long cpu_flags;
-	int err = ME_ERRNO_SUCCESS;
-
-	unsigned long j;
-	unsigned long delay = 0;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (instance->status != ai_status_single_configured) {
-		PERROR("Subdevice not configured to work in single mode!\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	if ((channel > instance->channels) || (channel < 0)) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (instance->single_config[channel].status !=
-	    ME_SINGLE_CHANNEL_CONFIGURED) {
-		PERROR("Channel is not configured to work in single mode!\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) {
-		PERROR("Subdevice is busy.\n");
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	// Cancel control task
-	PDEBUG("Cancel control task.\n");
-	instance->ai_control_task_flag = 0;
-	cancel_delayed_work(&instance->ai_control_task);
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-
-		if (delay == 0)
-			delay = 1;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	// Mark that StreamConfig is removed.
-	instance->chan_list_len = 0;
-
-	spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-	/// @note Imprtant: Preserve EXT IRQ settings.
-	tmp = inl(instance->ctrl_reg);
-	// Clear FIFOs and dissable interrupts
-	tmp &=
-	    ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
-
-	tmp &=
-	    ~(ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ |
-	      ME4600_AI_CTRL_BIT_LE_IRQ);
-	tmp |=
-	    ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
-	    ME4600_AI_CTRL_BIT_LE_IRQ_RESET;
-
-	tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	outl(0, instance->scan_pre_timer_low_reg);
-	PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_low_reg - instance->reg_base, 0);
-	outl(0, instance->scan_pre_timer_high_reg);
-	PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_high_reg - instance->reg_base, 0);
-	outl(0, instance->scan_timer_low_reg);
-	PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_timer_low_reg - instance->reg_base, 0);
-	outl(0, instance->scan_timer_high_reg);
-	PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_timer_high_reg - instance->reg_base, 0);
-	outl(65, instance->chan_timer_reg);
-	PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->chan_timer_reg - instance->reg_base, 65);
-	outl(65, instance->chan_pre_timer_reg);
-	PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->chan_pre_timer_reg - instance->reg_base, 65);
-
-	//Reactive FIFOs. Enable work.
-	tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	outl(instance->single_config[channel].entry,
-	     instance->channel_list_reg);
-	PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->channel_list_reg - instance->reg_base,
-		   instance->single_config[channel].entry);
-
-	// Preserve EXT IRQ settings.
-	tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
-	outl(instance->single_config[channel].ctrl | tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base,
-		   instance->single_config[channel].ctrl | tmp);
-
-	spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
-	if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) {	// Software start
-		inl(instance->start_reg);
-		PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
-			   instance->start_reg - instance->reg_base);
-
-		delay = 2;
-	}
-
-	j = jiffies;
-
-	while (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) {
-		if (delay && ((jiffies - j) >= delay)) {
-			if (!(instance->single_config[channel].ctrl & ME4600_AI_CTRL_BIT_EX_TRIG)) {	// Software start.
-				PERROR("Value not available after wait.\n");
-				err = ME_ERRNO_INTERNAL;
-			} else {	// External start.
-				PERROR("Timeout reached.\n");
-				err = ME_ERRNO_TIMEOUT;
-			}
-			break;
-		}
-		// Wait
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
-
-		if (signal_pending(current)) {
-			PERROR
-			    ("Wait on external trigger interrupted by signal.\n");
-			err = ME_ERRNO_SIGNAL;
-			break;
-		}
-
-		if (instance->status != ai_status_single_configured) {
-			PERROR("Wait interrupted by reset.\n");
-			err = ME_ERRNO_CANCELLED;
-			break;
-		}
-	}
-
-	// Read value.
-	if (!err) {
-		val = inl(instance->data_reg) ^ 0x8000;
-		PDEBUG_REG("data_reg inl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->data_reg - instance->reg_base, val);
-		*value = val & ME4600_AI_MAX_DATA;
-	} else {
-		*value = 0xFFFFFFFF;
-	}
-
-	// Restore settings.
-	spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-	tmp = inl(instance->ctrl_reg);
-	// Clear FIFOs and dissable interrupts.
-	tmp &=
-	    ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
-	tmp |= ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_HF_IRQ;
-	tmp |=
-	    ME4600_AI_CTRL_BIT_SC_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
-	    ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      meIOStreamTrigger_t *trigger,
-				      int fifo_irq_threshold, int flags)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	int i;			// internal multipurpose variable
-	unsigned long long data_required;
-
-	volatile uint32_t entry;
-	volatile uint32_t ctrl = ME4600_AI_CTRL_BIT_IMMEDIATE_STOP;
-	volatile uint32_t tmp;	// use when current copy of register's value needed
-	unsigned long cpu_flags;
-
-	uint64_t acq_ticks;
-	uint64_t scan_ticks;
-	uint64_t conv_ticks;
-	unsigned int acq_start_ticks_low = trigger->iAcqStartTicksLow;
-	unsigned int acq_start_ticks_high = trigger->iAcqStartTicksHigh;
-	unsigned int scan_start_ticks_low = trigger->iScanStartTicksLow;
-	unsigned int scan_start_ticks_high = trigger->iScanStartTicksHigh;
-	unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
-	unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER
-	    // Convert ticks to 64 bit long values
-	    acq_ticks =
-	    (uint64_t) acq_start_ticks_low +
-	    ((uint64_t) acq_start_ticks_high << 32);
-	scan_ticks =
-	    (uint64_t) scan_start_ticks_low +
-	    ((uint64_t) scan_start_ticks_high << 32);
-	conv_ticks =
-	    (uint64_t) conv_start_ticks_low +
-	    ((uint64_t) conv_start_ticks_high << 32);
-
-	// Check settings - begin
-	switch (trigger->iAcqStartTrigType) {
-	case ME_TRIG_TYPE_SW:
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		break;
-
-	default:
-		PERROR("Invalid acquisition start trigger type specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
-		goto ERROR;
-		break;
-	}
-
-	if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW)
-	    && (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE)) {
-		PERROR("Invalid acquisition start trigger edge specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-		goto ERROR;
-	}
-
-	if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW) {
-		switch (trigger->iAcqStartTrigEdge) {
-		case ME_TRIG_EDGE_RISING:
-		case ME_TRIG_EDGE_FALLING:
-		case ME_TRIG_EDGE_ANY:
-			break;
-
-		default:
-			PERROR
-			    ("Invalid acquisition start trigger edge specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-			goto ERROR;
-			break;
-		}
-	}
-
-	if (trigger->iAcqStartTrigChan != ME_TRIG_CHAN_DEFAULT) {
-		PERROR
-		    ("Invalid acquisition start trigger channel specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
-		goto ERROR;
-	}
-
-	if ((acq_ticks < ME4600_AI_MIN_ACQ_TICKS)
-	    || (acq_ticks > ME4600_AI_MAX_ACQ_TICKS)) {
-		PERROR
-		    ("Invalid acquisition start trigger argument specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_START_ARG;
-		goto ERROR;
-	}
-
-	switch (trigger->iScanStartTrigType) {
-
-	case ME_TRIG_TYPE_TIMER:
-		if ((scan_ticks < ME4600_AI_MIN_SCAN_TICKS)
-		    || (scan_ticks > ME4600_AI_MAX_SCAN_TICKS)
-		    || (scan_ticks < count * conv_ticks)
-		    ) {
-			PERROR("Invalid scan start argument specified.\n");
-			err = ME_ERRNO_INVALID_SCAN_START_ARG;
-			goto ERROR;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL) {
-			PERROR
-			    ("Invalid scan start trigger type specified (Acq is HW digital)\n");
-			err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-			goto ERROR;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		if (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_ANALOG) {
-			PERROR
-			    ("Invalid scan start trigger type specified (Acq is HW analog)\n");
-			err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-			goto ERROR;
-		}
-		break;
-
-	case ME_TRIG_TYPE_FOLLOW:
-		break;
-
-	default:
-		PERROR("Invalid scan start trigger type specified.\n");
-		err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-		goto ERROR;
-		break;
-	}
-
-	switch (trigger->iConvStartTrigType) {
-
-	case ME_TRIG_TYPE_TIMER:
-		if ((conv_ticks < ME4600_AI_MIN_CHAN_TICKS)
-		    || (conv_ticks > ME4600_AI_MAX_CHAN_TICKS)) {
-			PERROR
-			    ("Invalid conv start trigger argument specified.\n");
-			err = ME_ERRNO_INVALID_CONV_START_ARG;
-			goto ERROR;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW)
-		    || (trigger->iAcqStartTrigType !=
-			ME_TRIG_TYPE_EXT_DIGITAL)) {
-			PERROR("Invalid conv start trigger type specified.\n");
-			err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-			goto ERROR;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		if ((trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW)
-		    || (trigger->iAcqStartTrigType !=
-			ME_TRIG_TYPE_EXT_ANALOG)) {
-			PERROR("Invalid conv start trigger type specified.\n");
-			err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-			goto ERROR;
-		}
-		break;
-
-	default:
-		PERROR("Invalid conv start trigger type specified.\n");
-		err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-		goto ERROR;
-
-		break;
-	}
-/**
-* Aceptable settings:
-* iScanStopTrigType		:	iAcqStopTrigType
-*
-* ME_TRIG_TYPE_NONE		:	ME_TRIG_TYPE_NONE	-> infinite count with manual stop
-* ME_TRIG_TYPE_NONE		:	ME_TRIG_TYPE_COUNT	-> stop after getting iScanStopCount list of values (iScanStopCount * count)
-* ME_TRIG_TYPE_COUNT	:	ME_TRIG_TYPE_FOLLOW	-> stop after getting iAcqStopCount values (it can stops in midle of the list)
-*/
-	switch (trigger->iScanStopTrigType) {
-
-	case ME_TRIG_TYPE_NONE:
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (trigger->iScanStopCount <= 0) {
-			PERROR("Invalid scan stop argument specified.\n");
-			err = ME_ERRNO_INVALID_SCAN_STOP_ARG;
-			goto ERROR;
-		}
-		break;
-
-	default:
-		PERROR("Invalid scan stop trigger type specified.\n");
-		err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
-		goto ERROR;
-		break;
-	}
-
-	switch (trigger->iAcqStopTrigType) {
-
-	case ME_TRIG_TYPE_NONE:
-		if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
-			PERROR("Invalid acq stop trigger type specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-			goto ERROR;
-		}
-		break;
-
-	case ME_TRIG_TYPE_FOLLOW:
-		if (trigger->iScanStopTrigType != ME_TRIG_TYPE_COUNT) {
-			PERROR("Invalid acq stop trigger type specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-			goto ERROR;
-		}
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
-			PERROR("Invalid acq stop trigger type specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-			goto ERROR;
-		}
-
-		if (trigger->iAcqStopCount <= 0) {
-			PERROR
-			    ("Invalid acquisition or scan stop argument specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_STOP_ARG;
-			goto ERROR;
-		}
-		break;
-
-	default:
-		PERROR("Invalid acq stop trigger type specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-		goto ERROR;
-		break;
-	}
-
-	if ((count <= 0) || (count > ME4600_AI_LIST_COUNT)) {
-		PERROR("Invalid channel list count specified.\n");
-		err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
-		goto ERROR;
-	}
-///This is general limitation
-//      if (fifo_irq_threshold < 0 || fifo_irq_threshold >= ME4600_AI_CIRC_BUF_COUNT)
-///This is limitation from Windows. I use it for compatibility.
-	if (fifo_irq_threshold < 0
-	    || fifo_irq_threshold >= ME4600_AI_FIFO_COUNT) {
-		PERROR("Invalid fifo irq threshold specified.\n");
-		err = ME_ERRNO_INVALID_FIFO_IRQ_THRESHOLD;
-		goto ERROR;
-	}
-
-	if ((config_list[0].iRef == ME_REF_AI_DIFFERENTIAL)
-	    && (instance->channels == 16)) {
-		PERROR
-		    ("Differential reference is not available on this subdevice.\n");
-		err = ME_ERRNO_INVALID_REF;
-		goto ERROR;
-	}
-
-	if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) {
-		if (!instance->sh) {
-			PERROR
-			    ("Sample and hold is not available for this board.\n");
-			err = ME_ERRNO_INVALID_FLAGS;
-			goto ERROR;
-		}
-		if (config_list[0].iRef == ME_REF_AI_DIFFERENTIAL) {
-			PERROR
-			    ("Sample and hold is not available in differential mode.\n");
-			err = ME_ERRNO_INVALID_FLAGS;
-			goto ERROR;
-		}
-	}
-
-	for (i = 0; i < count; i++) {
-		if ((config_list[i].iStreamConfig < 0)
-		    || (config_list[i].iStreamConfig >= instance->ranges_len)) {
-			PERROR("Invalid stream config specified.\n");
-			err = ME_ERRNO_INVALID_STREAM_CONFIG;
-			goto ERROR;
-		}
-
-		if ((config_list[i].iRef != ME_REF_AI_GROUND)
-		    && (config_list[i].iRef != ME_REF_AI_DIFFERENTIAL)) {
-			PERROR("Invalid references in the list. Ref=0x%x\n",
-			       config_list[i].iRef);
-			err = ME_ERRNO_INVALID_REF;
-			goto ERROR;
-		}
-
-		if (config_list[i].iStreamConfig % 2) {	// StreamConfig: 1 or 3
-			if (config_list[i].iRef == ME_REF_AI_DIFFERENTIAL) {
-				PERROR
-				    ("Only bipolar modes support differential measurement.\n");
-				err = ME_ERRNO_INVALID_REF;
-				goto ERROR;
-			}
-		}
-
-		if (config_list[i].iRef != config_list[0].iRef) {
-			PERROR
-			    ("Not all references in the configuration list are equal. Ref[0]=0x%x Ref[%d]=0x%x\n",
-			     config_list[0].iRef, i, config_list[i].iRef);
-			err = ME_ERRNO_INVALID_REF;
-			goto ERROR;
-		}
-
-		if ((config_list[i].iRef == ME_REF_AI_DIFFERENTIAL)
-		    && (config_list[i].iChannel >= 16)) {
-			PERROR("Channel not available in differential mode.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-			goto ERROR;
-		}
-
-		if ((config_list[i].iChannel < 0)
-		    || (config_list[i].iChannel >= instance->channels)) {
-			PERROR("Invalid channel number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-			goto ERROR;
-		}
-	}
-
-	// Check settings - end
-
-	//Cancel control task
-	PDEBUG("Cancel control task.\n");
-	instance->ai_control_task_flag = 0;
-	cancel_delayed_work(&instance->ai_control_task);
-
-	// Work around from Keith Hartley - begin
-	if (trigger->iScanStartTrigType == ME_TRIG_TYPE_TIMER) {
-		if (count == 1) {
-			// The hardware does not work properly with a non-zero scan time
-			// if there is only ONE channel in the channel list. In this case
-			// we must set the scan time to zero and use the channel time.
-
-			conv_ticks = scan_ticks;
-			trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW;
-		} else if (scan_ticks == count * conv_ticks) {
-			// Another hardware problem. If the number of scan ticks is
-			// exactly equal to the number of channel ticks multiplied by
-			// the number of channels then the sampling rate is reduced
-			// by half.
-			trigger->iScanStartTrigType = ME_TRIG_TYPE_FOLLOW;
-		}
-	}
-	// Work around from Keith Hartley - end
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	if (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) {
-		PERROR("Subdevice is busy.\n");
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-		ME_SUBDEVICE_EXIT;
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-
-	instance->status = ai_status_none;
-	spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-	// Stop all actions. Block all interrupts. Clear (disable) FIFOs.
-	ctrl =
-	    ME4600_AI_CTRL_BIT_LE_IRQ_RESET | ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
-	    ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-
-	tmp = inl(instance->ctrl_reg);
-	// Preserve EXT IRQ and OFFSET settings. Clean other bits.
-	tmp &=
-	    (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET |
-	     ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET);
-
-	// Send it to register.
-	outl(tmp | ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp | ctrl);
-
-	// Enable channel fifo -> data fifo in stream_start().
-	ctrl |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO;
-	outl(tmp | ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp | ctrl);
-	spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
-	// Write the channel list
-	for (i = 0; i < count; i++) {
-		entry = config_list[i].iChannel;
-
-		switch (config_list[i].iStreamConfig) {
-		case 0:	//BIPOLAR 10V
-/*
-				// ME4600_AI_LIST_RANGE_BIPOLAR_10 = 0x0000
-				// 'entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10' <== Do nothing. Removed.
-				entry |= ME4600_AI_LIST_RANGE_BIPOLAR_10;
-*/
-			break;
-		case 1:	//UNIPOLAR 10V
-			entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_10;
-			break;
-		case 2:	//BIPOLAR 2.5V
-			entry |= ME4600_AI_LIST_RANGE_BIPOLAR_2_5;
-			break;
-		case 3:	//UNIPOLAR 2.5V
-			entry |= ME4600_AI_LIST_RANGE_UNIPOLAR_2_5;
-			break;
-		default:
-			PERROR_CRITICAL("UNCHECK ERROR in config_list!\n");
-			PERROR_CRITICAL
-			    ("WRONG range\nPosition:%d Range:0x%04X\n", i,
-			     config_list[i].iStreamConfig);
-			goto VERIFY_ERROR;
-			break;
-		}
-
-		switch (config_list[i].iRef) {
-		case ME_REF_AI_GROUND:	//SINGLE ENDED
-/*
-				// ME4600_AI_LIST_INPUT_SINGLE_ENDED = 0x0000
-				// 'entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED' ==> Do nothing. Removed.
-				entry |= ME4600_AI_LIST_INPUT_SINGLE_ENDED;
-*/ break;
-		case ME_REF_AI_DIFFERENTIAL:	//DIFFERENTIAL
-			entry |= ME4600_AI_LIST_INPUT_DIFFERENTIAL;
-			break;
-		default:
-			PERROR_CRITICAL("UNCHECK ERROR in config_list!\n");
-			PERROR_CRITICAL
-			    ("WRONG reference\nPosition:%d Reference:0x%04X\n",
-			     i, config_list[i].iRef);
-			goto VERIFY_ERROR;
-			break;
-		}
-
-		//Add last entry flag
-		if (i == (count - 1)) {
-			entry |= ME4600_AI_LIST_LAST_ENTRY;
-		}
-
-		outl(entry, instance->channel_list_reg);
-		PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->channel_list_reg - instance->reg_base,
-			   entry);
-	}
-
-	// Set triggering registers
-	--acq_ticks;
-	outl(acq_ticks, instance->chan_pre_timer_reg);
-	PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%llX\n",
-		   instance->reg_base,
-		   instance->chan_pre_timer_reg - instance->reg_base,
-		   acq_ticks);
-	outl(acq_ticks, instance->scan_pre_timer_low_reg);
-	PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_low_reg - instance->reg_base,
-		   acq_ticks & 0xFFFFFFFF);
-	outl((acq_ticks >> 32), instance->scan_pre_timer_high_reg);
-	PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_high_reg - instance->reg_base,
-		   (acq_ticks >> 32) & 0xFFFFFFFF);
-
-	// Set triggers
-	switch (trigger->iAcqStartTrigType) {
-		// Internal
-	case ME_TRIG_TYPE_SW:
-		// Nothing to set.
-		break;
-
-		// External
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG;
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG;
-
-		// External trigger needs edge's definition
-		switch (trigger->iAcqStartTrigEdge) {
-		case ME_TRIG_EDGE_RISING:
-			// Nothing to set.
-			break;
-
-		case ME_TRIG_EDGE_FALLING:
-			ctrl |= ME4600_AI_CTRL_BIT_EX_TRIG_FALLING;
-			break;
-
-		case ME_TRIG_EDGE_ANY:
-			ctrl |=
-			    ME4600_AI_CTRL_BIT_EX_TRIG_FALLING |
-			    ME4600_AI_CTRL_BIT_EX_TRIG_BOTH;
-			break;
-
-		default:
-			PERROR_CRITICAL
-			    ("UNCHECK TRIGGER EDGE in triggers structure!\n");
-			PERROR_CRITICAL
-			    ("WRONG acquisition start trigger:0x%04X.\n",
-			     trigger->iAcqStartTrigEdge);
-			err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-			goto VERIFY_ERROR;
-			break;
-		}
-		break;
-
-	default:
-		PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
-		PERROR_CRITICAL("WRONG acquisition start trigger:0x%04X.\n",
-				trigger->iAcqStartTrigType);
-		err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
-		goto VERIFY_ERROR;
-		break;
-	}
-
-	switch (trigger->iScanStartTrigType) {
-	case ME_TRIG_TYPE_TIMER:
-		--scan_ticks;
-		outl(scan_ticks, instance->scan_timer_low_reg);
-		PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%llX\n",
-			   instance->reg_base,
-			   instance->scan_timer_low_reg - instance->reg_base,
-			   scan_ticks & 0xFFFFFFFF);
-		outl((scan_ticks >> 32), instance->scan_timer_high_reg);
-		PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%llX\n",
-			   instance->reg_base,
-			   instance->scan_timer_high_reg - instance->reg_base,
-			   (scan_ticks >> 32) & 0xFFFFFFFF);
-
-		if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
-			ctrl |= ME4600_AI_CTRL_BIT_MODE_0;
-		} else {
-			ctrl |= ME4600_AI_CTRL_BIT_MODE_1;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		outl(0, instance->scan_timer_low_reg);
-		PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->scan_timer_low_reg - instance->reg_base,
-			   0);
-		outl(0, instance->scan_timer_high_reg);
-		PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->scan_timer_high_reg - instance->reg_base,
-			   0);
-		ctrl |= ME4600_AI_CTRL_BIT_MODE_2;
-		break;
-
-	case ME_TRIG_TYPE_FOLLOW:
-		outl(0, instance->scan_timer_low_reg);
-		PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->scan_timer_low_reg - instance->reg_base,
-			   0);
-		outl(0, instance->scan_timer_high_reg);
-		PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->scan_timer_high_reg - instance->reg_base,
-			   0);
-
-		if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
-			ctrl |= ME4600_AI_CTRL_BIT_MODE_0;
-		} else {
-			ctrl |= ME4600_AI_CTRL_BIT_MODE_1;
-		}
-		break;
-
-	default:
-		PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
-		PERROR_CRITICAL("WRONG scan start trigger:0x%04X.\n",
-				trigger->iScanStartTrigType);
-		err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-		goto VERIFY_ERROR;
-		break;
-	}
-
-	switch (trigger->iConvStartTrigType) {
-
-	case ME_TRIG_TYPE_TIMER:
-		--conv_ticks;
-		outl(conv_ticks, instance->chan_timer_reg);
-		PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%llX\n",
-			   instance->reg_base,
-			   instance->chan_timer_reg - instance->reg_base,
-			   conv_ticks);
-		break;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-	case ME_TRIG_TYPE_EXT_ANALOG:
-		outl(0, instance->chan_timer_reg);
-		PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->chan_timer_reg - instance->reg_base, 0);
-		ctrl |= ME4600_AI_CTRL_BIT_MODE_0 | ME4600_AI_CTRL_BIT_MODE_1;
-		break;
-
-	default:
-		PERROR_CRITICAL("UNCHECK TRIGGER in triggers structure!\n");
-		PERROR_CRITICAL("WRONG conv start trigger:0x%04X.\n",
-				trigger->iConvStartTrigType);
-		err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-		goto VERIFY_ERROR;
-
-		break;
-	}
-
-	//Sample & Hold feature
-	if (flags & ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD) {
-		if (instance->sh) {
-			ctrl |= ME4600_AI_CTRL_BIT_SAMPLE_HOLD;
-		} else {
-			PERROR_CRITICAL("UNCHECK S&H feature!\n");
-			err = ME_ERRNO_INVALID_FLAGS;
-			goto VERIFY_ERROR;
-		}
-	}
-	//Enable IRQs sources but leave latches blocked.
-	ctrl |= (ME4600_AI_CTRL_BIT_HF_IRQ | ME4600_AI_CTRL_BIT_SC_IRQ | ME4600_AI_CTRL_BIT_LE_IRQ);	//The last IRQ source (ME4600_AI_CTRL_BIT_LE_IRQ) is unused!
-
-	//Everything is good. Finalize
-	spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-	tmp = inl(instance->ctrl_reg);
-
-	//Preserve EXT IRQ and OFFSET settings. Clean other bits.
-	tmp &=
-	    (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET |
-	     ME4600_AI_CTRL_BIT_FULLSCALE | ME4600_AI_CTRL_BIT_OFFSET);
-
-	// write the control word
-	outl(ctrl | tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl | tmp);
-	spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
-	//Set the global parameters end exit.
-	instance->chan_list_len = count;
-	instance->fifo_irq_threshold = fifo_irq_threshold;
-
-	if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) {
-		data_required =
-		    (unsigned long long)trigger->iAcqStopCount *
-		    (unsigned long long)count;
-		if (data_required > UINT_MAX)
-			data_required = UINT_MAX;
-		instance->data_required = (unsigned int)data_required;
-	} else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT)
-		instance->data_required =
-		    (unsigned long long)trigger->iScanStopCount;
-	else
-		instance->data_required = 0;
-
-	// Mark subdevice as configured to work in stream mode.
-	instance->status = ai_status_stream_configured;
-
-	// Deinit single config. Set all entries to NOT_CONFIGURED.
-	for (i = 0; i < instance->channels; i++) {
-		instance->single_config[i].status =
-		    ME_SINGLE_CHANNEL_NOT_CONFIGURED;
-	}
-
-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.
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
-					  struct file *filep,
-					  int time_out, int *count, int flags)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long t;
-	unsigned long j;
-	int volatile head;
-
-	PDEBUG("executed. idx=0\n");
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	} else {		// Max time.
-		t = LONG_MAX;
-	}
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	j = jiffies;
-
-	while (1) {
-		// Only runing device can generate break.
-		head = instance->circ_buf.head;
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 ((head !=
-						   instance->circ_buf.head)
-						  ||
-						  ((instance->status <=
-						    ai_status_stream_run_wait)
-						   && (instance->status >=
-						       ai_status_stream_end_wait))),
-						 t);
-
-		if (head != instance->circ_buf.head) {	// New data in buffer.
-			break;
-		} else if (instance->status == ai_status_stream_end) {	// End of work.
-			break;
-		} else if (instance->status == ai_status_stream_fifo_error) {
-			err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-			break;
-		} else if (instance->status == ai_status_stream_buffer_error) {
-			err = ME_ERRNO_RING_BUFFER_OVERFLOW;
-			break;
-		} else if (instance->status == ai_status_stream_error) {
-			err = ME_ERRNO_INTERNAL;
-			break;
-		} else if ((jiffies - j) >= t) {
-			PERROR("Wait on values timed out.\n");
-			err = ME_ERRNO_TIMEOUT;
-			break;
-		} else if (signal_pending(current)) {
-			PERROR("Wait on values interrupted from signal.\n");
-			err = ME_ERRNO_SIGNAL;
-			break;
-		}
-		// Correct timeout.
-		t -= jiffies - j;
-	}
-
-	*count = me_circ_buf_values(&instance->circ_buf);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
-						     instance, int *values,
-						     const int count,
-						     const int flags)
-{
-	int n;
-	int i;
-	uint32_t value;
-
-	///Checking how many datas can be copied.
-	n = me_circ_buf_values(&instance->circ_buf);
-	if (n <= 0)
-		return 0;
-
-	if (n > count)
-		n = count;
-
-	if (flags & ME_IO_STREAM_READ_FRAMES) {
-		if (n < instance->chan_list_len)	//Not enough data!
-			return 0;
-		n -= n % instance->chan_list_len;
-	}
-
-	for (i = 0; i < n; i++) {
-		value = *(instance->circ_buf.buf + instance->circ_buf.tail);
-		if (put_user(value, values + i)) {
-			PERROR("Cannot copy new values to user.\n");
-			return -ME_ERRNO_INTERNAL;
-		}
-		instance->circ_buf.tail++;
-		instance->circ_buf.tail &= instance->circ_buf.mask;
-	}
-	return n;
-}
-
-static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int read_mode,
-				    int *values, int *count, int flags)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	int ret;
-
-	int c = *count;
-	int min = c;
-
-	PDEBUG("executed. idx=0\n");
-
-	if (flags & ~ME_IO_STREAM_READ_FRAMES) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!values || !count) {
-		PERROR("Request has invalid pointer.\n");
-		return ME_ERRNO_INVALID_POINTER;
-	}
-
-	if (c < 0) {
-		PERROR("Request has invalid value's counter.\n");
-		return ME_ERRNO_INVALID_VALUE_COUNT;
-	}
-
-	if ((read_mode != ME_READ_MODE_BLOCKING)
-	    && (read_mode != ME_READ_MODE_NONBLOCKING)) {
-		PERROR("Invalid read mode specified.\n");
-		return ME_ERRNO_INVALID_READ_MODE;
-	}
-
-	if (c == 0) {		//You get what you want! Nothing more or less.
-		return ME_ERRNO_SUCCESS;
-	}
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-	ME_SUBDEVICE_ENTER;
-
-	//Check if subdevice is configured.
-	if (instance->chan_list_len <= 0) {
-		PERROR("Subdevice wasn't configured.\n");
-		ME_SUBDEVICE_EXIT;
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	if (flags & ME_IO_STREAM_READ_FRAMES) {
-		if (c < instance->chan_list_len) {	//Not enough data requested.
-			PERROR
-			    ("When using FRAME_READ mode minimal size is defined by channel list.\n");
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INVALID_VALUE_COUNT;
-		}
-	}
-
-	if (c > (ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len)) {	// To return acceptable amount of data when user pass too big value.
-		min = ME4600_AI_CIRC_BUF_COUNT - instance->chan_list_len;
-	}
-
-	if (flags & ME_IO_STREAM_READ_FRAMES) {
-		//Wait for whole list.
-		if (read_mode == ME_READ_MODE_BLOCKING) {
-			min = c - (c % instance->chan_list_len);
-		}
-
-		if (read_mode == ME_READ_MODE_NONBLOCKING) {
-			min = instance->chan_list_len;
-		}
-	}
-
-	if ((inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) {	//Working
-		//If blocking mode -> wait for data.
-		if ((me_circ_buf_values(&instance->circ_buf) < min)
-		    && (read_mode == ME_READ_MODE_BLOCKING)) {
-			wait_event_interruptible(instance->wait_queue,
-						 ((me_circ_buf_values
-						   (&instance->circ_buf) >= min)
-						  || !(inl(instance->status_reg)
-						       &
-						       ME4600_AI_STATUS_BIT_FSM)));
-
-			if (signal_pending(current)) {
-				PERROR
-				    ("Wait on values interrupted from signal.\n");
-				err = ME_ERRNO_SIGNAL;
-			}
-		}
-	}
-
-	ret = me4600_ai_io_stream_read_get_value(instance, values, c, flags);
-	if (ret < 0) {
-		err = -ret;
-		*count = 0;
-	} else if (ret == 0) {
-		*count = 0;
-		if (instance->status == ai_status_stream_fifo_error) {
-			err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-			instance->status = ai_status_stream_end;
-		} else if (instance->status == ai_status_stream_buffer_error) {
-			err = ME_ERRNO_RING_BUFFER_OVERFLOW;
-			instance->status = ai_status_stream_end;
-		} else if (instance->status == ai_status_stream_end) {
-			err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-		} else if (instance->status == ai_status_stream_error) {
-			err = ME_ERRNO_INTERNAL;
-		} else if (instance->status == ai_status_none) {
-			PDEBUG("Stream canceled.\n");
-			err = ME_ERRNO_INTERNAL;
-		}
-	} else {
-		*count = ret;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-/** @brief Stop aqusation. Preserve FIFOs.
-*
-* @param instance The subdevice instance (pointer).
-*/
-
-static int ai_stop_immediately(me4600_ai_subdevice_t *instance)
-{
-	unsigned long cpu_flags = 0;
-	volatile uint32_t ctrl;
-	const int timeout = HZ / 10;	//100ms
-	int i;
-
-	for (i = 0; i <= timeout; i++) {
-		spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-		ctrl = inl(instance->ctrl_reg);
-		ctrl &= ~ME4600_AI_CTRL_BIT_STOP;
-		ctrl |=
-		    (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP |
-		     ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
-		     ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
-		if (!(inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM)) {	// Exit.
-			break;
-		}
-
-		PINFO("Wait for stop: %d\n", i + 1);
-		//Still working!
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
-	}
-
-	if (i > timeout) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		return ME_ERRNO_INTERNAL;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int start_mode, int time_out, int flags)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags = 0;
-	unsigned long ref;
-	unsigned long delay = 0;
-
-	volatile uint32_t tmp;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((start_mode != ME_START_MODE_BLOCKING)
-	    && (start_mode != ME_START_MODE_NONBLOCKING)) {
-		PERROR("Invalid start mode specified.\n");
-		return ME_ERRNO_INVALID_START_MODE;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-
-		if (delay == 0)
-			delay = 1;
-	}
-
-	ME_SUBDEVICE_ENTER
-	    spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-
-	tmp = inl(instance->ctrl_reg);
-
-	if ((tmp & ME4600_AI_STATUS_BIT_FSM)) {
-		PERROR("Conversion is already running.\n");
-		spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-		err = ME_ERRNO_SUBDEVICE_BUSY;
-		goto ERROR;
-	}
-
-	if (instance->chan_list_len == 0) {	//Not configured!
-		PERROR("Subdevice is not configured to work in stream mode!\n");
-		spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-		goto ERROR;
-	}
-
-	if (!(tmp & (ME4600_AI_CTRL_BIT_MODE_0 | ME4600_AI_CTRL_BIT_MODE_1 | ME4600_AI_CTRL_BIT_MODE_2))) {	//Mode 0 = single work => no stream config
-		PERROR("Subdevice is configured to work in single mode.\n");
-		spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-		goto ERROR;
-	}
-	//Reset stop bits.
-	tmp |= ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	//Start datas' FIFO.
-	tmp |= ME4600_AI_CTRL_BIT_DATA_FIFO;
-	//Free stop bits.
-	tmp &= ~(ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_STOP);
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
-	//Cancel control task
-	PDEBUG("Cancel control task.\n");
-	instance->ai_control_task_flag = 0;
-	cancel_delayed_work(&instance->ai_control_task);
-
-	//Set the starting values.
-	instance->ISM.global_read = 0;
-	instance->ISM.read = 0;
-	//Clear circular buffer
-	instance->circ_buf.head = 0;
-	instance->circ_buf.tail = 0;
-
-	//Set everything.
-	ai_data_acquisition_logic(instance);
-
-	//Set status to 'wait for start'
-	instance->status = ai_status_stream_run_wait;
-
-	// Set control task's timeout
-	instance->timeout.delay = delay;
-	instance->timeout.start_time = jiffies;
-
-	//Lets go! Start work
-	inl(instance->start_reg);
-	PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
-		   instance->start_reg - instance->reg_base);
-
-	// Schedule control task
-	instance->ai_control_task_flag = 1;
-	queue_delayed_work(instance->me4600_workqueue,
-			   &instance->ai_control_task, 1);
-
-	PDEVELOP("Delay:%ld\n", delay);
-
-	if (start_mode == ME_START_MODE_BLOCKING) {	//Wait for start.
-		ref = jiffies;
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ai_status_stream_run_wait),
-						 (delay) ? delay +
-						 1 : LONG_MAX);
-
-		if ((instance->status != ai_status_stream_run)
-		    && (instance->status != ai_status_stream_end)) {
-			PDEBUG("Starting stream canceled. %d\n",
-			       instance->status);
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			instance->status = ai_status_none;
-			ai_stop_isr(instance);
-			err = ME_ERRNO_SIGNAL;
-		} else if ((delay) && ((jiffies - ref) > delay)) {
-			if (instance->status != ai_status_stream_run) {
-				if (instance->status == ai_status_stream_end) {
-					PDEBUG("Timeout reached.\n");
-				} else if ((jiffies - ref) > delay + 1) {
-					PERROR
-					    ("Timeout reached. Not handled by control task!\n");
-					ai_stop_isr(instance);
-					instance->status =
-					    ai_status_stream_error;
-				} else {
-					PERROR
-					    ("Timeout reached. Signal come but status is strange: %d\n",
-					     instance->status);
-					ai_stop_isr(instance);
-					instance->status =
-					    ai_status_stream_error;
-				}
-
-				instance->ai_control_task_flag = 0;
-				cancel_delayed_work(&instance->ai_control_task);
-				err = ME_ERRNO_TIMEOUT;
-			}
-		}
-	}
-#ifdef MEDEBUG_INFO
-	tmp = inl(instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	PINFO("STATUS_BIT_FSM=%s.\n",
-	      (tmp & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
-	PINFO("CTRL_BIT_HF_IRQ=%s.\n",
-	      (tmp & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable");
-	PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
-	      (tmp & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" : "work");
-	PINFO("CTRL_BIT_SC_IRQ=%s.\n",
-	      (tmp & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
-	PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
-	      (tmp & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
-	PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
-	      (tmp & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : "work");
-#endif
-
-ERROR:
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int wait,
-				      int *status, int *values, int flags)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	switch (instance->status) {
-	case ai_status_single_configured:
-	case ai_status_stream_configured:
-	case ai_status_stream_end:
-	case ai_status_stream_fifo_error:
-	case ai_status_stream_buffer_error:
-	case ai_status_stream_error:
-		*status = ME_STATUS_IDLE;
-		break;
-
-	case ai_status_stream_run_wait:
-	case ai_status_stream_run:
-	case ai_status_stream_end_wait:
-		*status = ME_STATUS_BUSY;
-		break;
-
-	case ai_status_none:
-	default:
-		*status =
-		    (inl(instance->status_reg) & ME4600_AI_STATUS_BIT_FSM) ?
-		    ME_STATUS_BUSY : ME_STATUS_IDLE;
-		break;
-	}
-
-	if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
-		// Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 ((instance->status !=
-						   ai_status_stream_run_wait)
-						  && (instance->status !=
-						      ai_status_stream_run)
-						  && (instance->status !=
-						      ai_status_stream_end_wait)),
-						 LONG_MAX);
-
-		if (instance->status != ai_status_stream_end) {
-			PDEBUG("Wait for IDLE canceled. %d\n",
-			       instance->status);
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait for IDLE interrupted.\n");
-			instance->status = ai_status_none;
-			ai_stop_isr(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		*status = ME_STATUS_IDLE;
-	}
-
-	*values = me_circ_buf_values(&instance->circ_buf);
-	PDEBUG("me_circ_buf_values(&instance->circ_buf)=%d.\n", *values);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int stop_mode, int flags)
-{
-/**
- @note Stop is implemented only in blocking mode.
- @note Function return when state machine is stoped.
-*/
-	me4600_ai_subdevice_t *instance;
-	unsigned long cpu_flags;
-	uint32_t ctrl;
-	int ret;
-
-	PDEBUG("executed. idx=0\n");
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
-	    && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
-		PERROR("Invalid stop mode specified.\n");
-		return ME_ERRNO_INVALID_STOP_MODE;
-	}
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	// Mark as stopping. => Software stop.
-	instance->status = ai_status_stream_end_wait;
-
-	if (stop_mode == ME_STOP_MODE_IMMEDIATE) {
-		ret = ai_stop_immediately(instance);
-
-		if (ret) {
-			PERROR("FSM is still busy.\n");
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_SUBDEVICE_BUSY;
-		}
-		instance->ai_control_task_flag = 0;
-
-	} else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
-		// Set stop bit in registry.
-		spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-		ctrl = inl(instance->ctrl_reg);
-		ctrl |= ME4600_AI_CTRL_BIT_STOP;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-
-		// Only runing process will interrupt this call. Events are signaled when status change.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ai_status_stream_end_wait),
-						 LONG_MAX);
-
-		if (instance->status != ai_status_stream_end) {
-			PDEBUG("Stopping stream canceled.\n");
-			ret = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Stopping stream interrupted.\n");
-			instance->status = ai_status_none;
-			ret = ME_ERRNO_SIGNAL;
-		}
-		// End of work.
-		ai_stop_immediately(instance);
-
-	}
-
-	ret = ai_read_data_pooling(instance);
-	if (ret > 0) {		// Everything fine. More datas put to software buffer.
-		instance->status = ai_status_stream_end;
-		ret = ME_ERRNO_SUCCESS;
-		// Signal that we put last data to software buffer.
-		wake_up_interruptible_all(&instance->wait_queue);
-	} else if (ret == 0) {	// Everything fine. No more datas in FIFO.
-		instance->status = ai_status_stream_end;
-		ret = ME_ERRNO_SUCCESS;
-	} else if (ret == -ME_ERRNO_RING_BUFFER_OVERFLOW) {	// Stop is unsuccessful, buffer is overflow.
-		instance->status = ai_status_stream_buffer_error;
-		ret = ME_ERRNO_SUCCESS;
-	} else {		// Stop is unsuccessful
-		instance->status = ai_status_stream_end;
-		ret = -ret;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return ret;
-}
-
-static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
-					    int unit,
-					    int *min,
-					    int *max, int *maxdata, int *range)
-{
-	me4600_ai_subdevice_t *instance;
-	int i;
-	int r = -1;
-	int diff = 21E6;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	if ((*max - *min) < 0) {
-		PERROR("Invalid minimum and maximum values specified.\n");
-		return ME_ERRNO_INVALID_MIN_MAX;
-	}
-
-	if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
-		for (i = 0; i < instance->ranges_len; i++) {
-			if ((instance->ranges[i].min <= *min)
-			    && ((instance->ranges[i].max + 1000) >= *max)) {
-				if ((instance->ranges[i].max -
-				     instance->ranges[i].min) - (*max - *min) <
-				    diff) {
-					r = i;
-					diff =
-					    (instance->ranges[i].max -
-					     instance->ranges[i].min) - (*max -
-									 *min);
-				}
-			}
-		}
-
-		if (r < 0) {
-			PERROR("No matching range found.\n");
-			return ME_ERRNO_NO_RANGE;
-		} else {
-			*min = instance->ranges[r].min;
-			*max = instance->ranges[r].max;
-			*maxdata = ME4600_AI_MAX_DATA;
-			*range = r;
-		}
-	} else {
-		PERROR("Invalid physical unit specified.\n");
-		return ME_ERRNO_INVALID_UNIT;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
-					 int unit, int *count)
-{
-	me4600_ai_subdevice_t *instance;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
-		*count = instance->ranges_len;
-	} else {
-		*count = 0;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
-				      int range,
-				      int *unit,
-				      int *min, int *max, int *maxdata)
-{
-	me4600_ai_subdevice_t *instance;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	if ((range < instance->ranges_len) && (range >= 0)) {
-		*unit = ME_UNIT_VOLT;
-		*min = instance->ranges[range].min;
-		*max = instance->ranges[range].max;
-		*maxdata = ME4600_AI_MAX_DATA;
-	} else {
-		PERROR("Invalid range number specified.\n");
-		return ME_ERRNO_INVALID_RANGE;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_timer(me_subdevice_t *subdevice,
-				 int timer,
-				 int *base_frequency,
-				 long long *min_ticks, long long *max_ticks)
-{
-	me4600_ai_subdevice_t *instance;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	switch (timer) {
-
-	case ME_TIMER_ACQ_START:
-		*base_frequency = ME4600_AI_BASE_FREQUENCY;
-		*min_ticks = ME4600_AI_MIN_ACQ_TICKS;
-		*max_ticks = ME4600_AI_MAX_ACQ_TICKS;
-		break;
-
-	case ME_TIMER_SCAN_START:
-		*base_frequency = ME4600_AI_BASE_FREQUENCY;
-		*min_ticks = ME4600_AI_MIN_SCAN_TICKS;
-		*max_ticks = ME4600_AI_MAX_SCAN_TICKS;
-		break;
-
-	case ME_TIMER_CONV_START:
-		*base_frequency = ME4600_AI_BASE_FREQUENCY;
-		*min_ticks = ME4600_AI_MIN_CHAN_TICKS;
-		*max_ticks = ME4600_AI_MAX_CHAN_TICKS;
-		break;
-
-	default:
-		PERROR("Invalid timer specified.(0x%04x)\n", timer);
-
-		return ME_ERRNO_INVALID_TIMER;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	me4600_ai_subdevice_t *instance;
-
-	PDEBUG("executed. idx=0\n");
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-	*number = instance->channels;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed. idx=0\n");
-
-	*type = ME_TYPE_AI;
-	*subtype = ME_SUBTYPE_STREAMING;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	PDEBUG("executed. idx=0\n");
-
-	*caps =
-	    ME_CAPS_AI_TRIG_SYNCHRONOUS | ME_CAPS_AI_FIFO |
-	    ME_CAPS_AI_FIFO_THRESHOLD;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
-					       int cap, int *args, int count)
-{
-	me4600_ai_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	instance = (me4600_ai_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=0\n");
-
-	if (count != 1) {
-		PERROR("Invalid capability argument count.\n");
-		return ME_ERRNO_INVALID_CAP_ARG_COUNT;
-	}
-
-	switch (cap) {
-	case ME_CAP_AI_FIFO_SIZE:
-		args[0] = ME4600_AI_FIFO_COUNT;
-		break;
-
-	case ME_CAP_AI_BUFFER_SIZE:
-		args[0] =
-		    (instance->circ_buf.buf) ? ME4600_AI_CIRC_BUF_COUNT : 0;
-		break;
-
-	default:
-		PERROR("Invalid capability.\n");
-		err = ME_ERRNO_INVALID_CAP;
-		args[0] = 0;
-	}
-
-	return err;
-}
-
-void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
-		    const uint32_t ctrl_status)
-{
-	int to_read;
-
-	if (!instance->fifo_irq_threshold) {	//No threshold provided. SC ends work. HF need reseting.
-		if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
-			if (ai_read_data(instance, instance->ISM.next) != instance->ISM.next) {	//ERROR!
-				PERROR
-				    ("Limited amounts aqusition with TH=0: Circular buffer full!\n");
-				instance->status =
-				    ai_status_stream_buffer_error;
-			} else {
-				instance->status = ai_status_stream_end;
-			}
-			//End of work.
-			ai_stop_isr(instance);
-		} else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
-			instance->ISM.global_read += ME4600_AI_FIFO_HALF;
-
-			if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) {	//ERROR!
-				PERROR
-				    ("Limited amounts aqusition with TH = 0: Circular buffer full!\n");
-				//End of work.
-				ai_stop_isr(instance);
-				instance->status =
-				    ai_status_stream_buffer_error;
-			} else {
-				//Continue.
-				ai_limited_ISM(instance, irq_status);
-			}
-		}
-		//Signal user.
-		wake_up_interruptible_all(&instance->wait_queue);
-	} else			//if(instance->fifo_irq_threshold)
-	{
-		if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
-			instance->ISM.read = 0;
-			if ((instance->fifo_irq_threshold < ME4600_AI_FIFO_HALF)
-			    && (!(ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA)))
-			{
-				to_read =
-				    ME4600_AI_FIFO_HALF -
-				    (ME4600_AI_FIFO_HALF %
-				     instance->fifo_irq_threshold);
-				PDEBUG
-				    ("Limited amounts aqusition with TH != 0: Not fast enough data aqusition! correction=%d\n",
-				     to_read);
-			} else {
-				to_read = instance->ISM.next;
-			}
-			instance->ISM.global_read += to_read;
-
-			ai_reschedule_SC(instance);
-
-			if (ai_read_data(instance, to_read) != to_read) {	//ERROR!
-				PERROR
-				    ("Limited amounts aqusition with TH != 0: Circular buffer full!\n");
-				//End of work.
-				ai_stop_isr(instance);
-				instance->status =
-				    ai_status_stream_buffer_error;
-			} else {
-				//Continue.
-				ai_limited_ISM(instance, irq_status);
-			}
-
-			//Signal user.
-			wake_up_interruptible_all(&instance->wait_queue);
-		} else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
-			instance->ISM.read += ME4600_AI_FIFO_HALF;
-			instance->ISM.global_read += ME4600_AI_FIFO_HALF;
-
-			if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) {	//ERROR!
-				PERROR
-				    ("Limited amounts aqusition with TH != 0: Circular buffer full!\n");
-				ai_stop_isr(instance);
-
-				instance->status =
-				    ai_status_stream_buffer_error;
-				//Signal user.
-				wake_up_interruptible_all(&instance->
-							  wait_queue);
-			} else {
-				//Countinue.
-				ai_limited_ISM(instance, irq_status);
-			}
-		}
-
-		if (instance->ISM.global_read >= instance->data_required) {	//End of work. Next paranoid pice of code: '>=' instead od '==' only to be sure.
-			ai_stop_isr(instance);
-			if (instance->status < ai_status_stream_end) {
-				instance->status = ai_status_stream_end;
-			}
-#ifdef MEDEBUG_ERROR
-			if (instance->ISM.global_read > instance->data_required) {	//This is security check case. This should never ever happend!
-				PERROR
-				    ("Limited amounts aqusition: Read more data than necessary! data_required=%d < read=%d\n",
-				     instance->data_required,
-				     instance->ISM.global_read);
-				//Signal error (warning??).
-				instance->status = ai_status_stream_error;
-			}
-#endif
-		}
-	}
-}
-
-void ai_infinite_isr(me4600_ai_subdevice_t *instance,
-		     const uint32_t irq_status, const uint32_t ctrl_status)
-{
-	int to_read;
-
-	if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {	//next chunck of data -> read fifo
-		//Set new state in ISM.
-		if ((instance->fifo_irq_threshold < ME4600_AI_FIFO_HALF) && (!(ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA))) {	//There is more data than we ecpected. Propably we aren't fast enough. Read as many as possible.
-			if (instance->fifo_irq_threshold) {
-				to_read =
-				    ME4600_AI_FIFO_HALF -
-				    (ME4600_AI_FIFO_HALF %
-				     instance->fifo_irq_threshold);
-				if (to_read > instance->fifo_irq_threshold) {
-					PDEBUG
-					    ("Infinite aqusition: Not fast enough data aqusition! TH != 0: correction=%d\n",
-					     to_read);
-				}
-			} else {	//No threshold specified.
-				to_read = ME4600_AI_FIFO_HALF;
-			}
-		} else {
-			to_read = instance->ISM.next;
-		}
-
-		instance->ISM.read += to_read;
-
-		//Get data
-		if (ai_read_data(instance, to_read) != to_read) {	//ERROR!
-			PERROR("Infinite aqusition: Circular buffer full!\n");
-			ai_stop_isr(instance);
-			instance->status = ai_status_stream_buffer_error;
-		} else {
-			ai_infinite_ISM(instance);
-			instance->ISM.global_read += instance->ISM.read;
-			instance->ISM.read = 0;
-		}
-
-		//Signal data to user
-		wake_up_interruptible_all(&instance->wait_queue);
-	} else if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {	//fifo is half full -> read fifo       Large blocks only!
-		instance->ISM.read += ME4600_AI_FIFO_HALF;
-
-		if (ai_read_data(instance, ME4600_AI_FIFO_HALF) != ME4600_AI_FIFO_HALF) {	//ERROR!
-			PERROR("Infinite aqusition: Circular buffer full!\n");
-			ai_stop_isr(instance);
-			instance->status = ai_status_stream_buffer_error;
-
-			//Signal it.
-			wake_up_interruptible_all(&instance->wait_queue);
-		} else {
-			ai_infinite_ISM(instance);
-		}
-	}
-}
-
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id)
-{				/// @note This is time critical function!
-	uint32_t irq_status;
-	uint32_t ctrl_status;
-	me4600_ai_subdevice_t *instance = dev_id;
-	//int to_read;
-
-	PDEBUG("executed. idx=0\n");
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	irq_status = inl(instance->irq_status_reg);
-	if (!
-	    (irq_status &
-	     (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC))) {
-#ifdef MEDEBUG_INFO
-		if ((irq_status & (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC | ME4600_IRQ_STATUS_BIT_LE)) == ME4600_IRQ_STATUS_BIT_LE) {	//This is security check case. LE is unused. This should never ever happend.
-			PINFO
-			    ("%ld Shared interrupt. %s(): irq_status_reg=LE_IRQ\n",
-			     jiffies, __func__);
-		} else {
-			PINFO
-			    ("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
-			     jiffies, __func__, irq_status);
-		}
-#endif
-		return IRQ_NONE;
-	}
-
-	if (!instance->circ_buf.buf) {	//Security check.
-		PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
-		ai_stop_isr(instance);
-		return IRQ_HANDLED;
-	}
-	//Get the status register.
-	ctrl_status = inl(instance->status_reg);
-
-#ifdef MEDEBUG_INFO
-	if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF)
-		PINFO("HF interrupt active\n");
-	if (irq_status & ME4600_IRQ_STATUS_BIT_SC)
-		PINFO("SC interrupt active\n");
-	if (irq_status & ME4600_IRQ_STATUS_BIT_LE)
-		PINFO("LE interrupt active\n");
-#endif
-
-	//This is safety check!
-	if ((irq_status & ME4600_IRQ_STATUS_BIT_AI_HF)
-	    && (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA)) {
-		PDEBUG("HF interrupt active but FIFO under half\n");
-		//Reset HF interrupt latch.
-		spin_lock(instance->ctrl_reg_lock);
-		outl(ctrl_status | ME4600_AI_CTRL_BIT_HF_IRQ_RESET,
-		     instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base,
-			   ctrl_status);
-		outl(ctrl_status, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base,
-			   ctrl_status);
-		spin_unlock(instance->ctrl_reg_lock);
-		return IRQ_HANDLED;
-	}
-#ifdef MEDEBUG_INFO
-	PINFO("STATUS_BIT_FSM=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
-
-	PINFO("STATUS_BIT_EF_CHANNEL=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" :
-	      "empty");
-	PINFO("STATUS_BIT_HF_CHANNEL=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" :
-	      " > HF");
-	PINFO("STATUS_BIT_FF_CHANNEL=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" :
-	      "full");
-
-	PINFO("STATUS_BIT_EF_DATA=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" :
-	      "empty");
-	PINFO("STATUS_BIT_HF_DATA=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF");
-	PINFO("STATUS_BIT_FF_DATA=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" :
-	      "full");
-
-	PINFO("CTRL_BIT_HF_IRQ=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ) ? "enable" : "disable");
-	PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" :
-	      "work");
-	PINFO("CTRL_BIT_SC_IRQ=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
-	PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
-	PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" :
-	      "work");
-#endif
-
-	//Look for overflow error.
-	if (!(ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA)) {
-		//FIFO is full. Read datas and reset all settings.
-		PERROR("FIFO overflow.\n");
-		ai_read_data(instance, ME4600_AI_FIFO_COUNT);
-		ai_stop_isr(instance);
-
-		instance->status = ai_status_stream_fifo_error;
-		//Signal it.
-		wake_up_interruptible_all(&instance->wait_queue);
-
-		return IRQ_HANDLED;
-	}
-
-	if (!instance->data_required) {	//This is infinite aqusition.
-#ifdef MEDEBUG_ERROR
-		if ((irq_status &
-		     (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC))
-		    ==
-		    (ME4600_IRQ_STATUS_BIT_AI_HF | ME4600_IRQ_STATUS_BIT_SC)) {
-			///In infinite mode only one interrupt source should be reported!
-			PERROR
-			    ("Error in ISM! Infinite aqusition: HF and SC interrupts active! threshold=%d next=%d ctrl=0x%04X irq_status_reg=0x%04X",
-			     instance->fifo_irq_threshold, instance->ISM.next,
-			     ctrl_status, irq_status);
-		}
-#endif
-
-		ai_infinite_isr(instance, irq_status, ctrl_status);
-
-#ifdef MEDEBUG_INFO
-		ctrl_status = inl(instance->ctrl_reg);
-#endif
-	} else {
-
-		ai_limited_isr(instance, irq_status, ctrl_status);
-		ctrl_status = inl(instance->status_reg);
-		if (!(ctrl_status & (ME4600_AI_STATUS_BIT_HF_DATA | ME4600_AI_CTRL_BIT_HF_IRQ_RESET))) {	//HF active, but we have more than half already => HF will never come
-			PDEBUG
-			    ("MISSED HF. data_required=%d ISM.read=%d ISM.global=%d ISM.next=%d\n",
-			     instance->data_required, instance->ISM.read,
-			     instance->ISM.global_read, instance->ISM.next);
-			ai_limited_isr(instance, ME4600_IRQ_STATUS_BIT_AI_HF,
-				       ctrl_status);
-		}
-	}
-
-#ifdef MEDEBUG_INFO
-	PINFO("STATUS_BIT_FSM=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_FSM) ? "on" : "off");
-
-	PINFO("STATUS_BIT_EF_CHANNEL=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_EF_CHANNEL) ? "not empty" :
-	      "empty");
-	PINFO("STATUS_BIT_HF_CHANNEL=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_HF_CHANNEL) ? " < HF" :
-	      " > HF");
-	PINFO("STATUS_BIT_FF_CHANNEL=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_FF_CHANNEL) ? "not full" :
-	      "full");
-
-	PINFO("STATUS_BIT_EF_DATA=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_EF_DATA) ? "not empty" :
-	      "empty");
-	PINFO("STATUS_BIT_HF_DATA=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_HF_DATA) ? " < HF" : " > HF");
-	PINFO("STATUS_BIT_FF_DATA=%s.\n",
-	      (ctrl_status & ME4600_AI_STATUS_BIT_FF_DATA) ? "not full" :
-	      "full");
-
-	PINFO("CTRL_BIT_HF_IRQ_RESET=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_HF_IRQ_RESET) ? "reset" :
-	      "work");
-	PINFO("CTRL_BIT_SC_IRQ=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ) ? "enable" : "disable");
-	PINFO("CTRL_BIT_SC_RELOAD=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_SC_RELOAD) ? "on" : "off");
-	PINFO("CTRL_BIT_SC_IRQ_RESET=%s.\n",
-	      (ctrl_status & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" :
-	      "work");
-	PINFO("%ld END\n", jiffies);
-#endif
-
-	return IRQ_HANDLED;
-}
-
-/** @brief Stop aqusation of data. Reset interrupts' laches. Clear data's FIFO.
-*
-* @param instance The subdevice instance (pointer).
-*/
-inline void ai_stop_isr(me4600_ai_subdevice_t *instance)
-{				/// @note This is soft time critical function!
-	register uint32_t tmp;
-
-	spin_lock(instance->ctrl_reg_lock);
-	//Stop all. Reset interrupt laches. Reset data FIFO.
-	tmp = inl(instance->ctrl_reg);
-	tmp |=
-	    (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP | ME4600_AI_CTRL_BIT_HF_IRQ_RESET
-	     | ME4600_AI_CTRL_BIT_LE_IRQ_RESET |
-	     ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
-	tmp &= ~ME4600_AI_CTRL_BIT_DATA_FIFO;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->ctrl_reg_lock);
-}
-
-/** @brief Copy data from fifo to circular buffer.
-*
-* @param instance The subdevice instance (pointer).
-* @param count The number of requested data.
-*
-* @return On success: Number of copied values.
-* @return On error: -ME_ERRNO_RING_BUFFER_OVERFLOW.
-*/
-static inline int ai_read_data(me4600_ai_subdevice_t *instance,
-			       const int count)
-{				/// @note This is time critical function!
-	int c = count;
-	int empty_space;
-	int copied = 0;
-	int i, j;
-
-	empty_space = me_circ_buf_space_to_end(&instance->circ_buf);
-	if (empty_space <= 0) {
-		PDEBUG("Circular buffer full.\n");
-		return -ME_ERRNO_RING_BUFFER_OVERFLOW;
-	}
-
-	if (empty_space < c) {	//Copy first part. Max to end of buffer.
-		PDEBUG
-		    ("Try to copy %d values from FIFO to circular buffer (pass 1).\n",
-		     empty_space);
-		for (i = 0; i < empty_space; i++) {
-			*(instance->circ_buf.buf + instance->circ_buf.head) =
-			    (inw(instance->data_reg) ^ 0x8000);
-			instance->circ_buf.head++;
-		}
-		instance->circ_buf.head &= instance->circ_buf.mask;
-		c -= empty_space;
-		copied = empty_space;
-
-		empty_space = me_circ_buf_space_to_end(&instance->circ_buf);
-	}
-
-	if (empty_space > 0) {
-		j = (empty_space < c) ? empty_space : c;
-		PDEBUG
-		    ("Try to copy %d values from FIFO to circular buffer (pass 2).\n",
-		     c);
-		for (i = 0; i < j; i++) {
-			*(instance->circ_buf.buf + instance->circ_buf.head) =
-			    (inw(instance->data_reg) ^ 0x8000);
-			instance->circ_buf.head++;
-		}
-		instance->circ_buf.head &= instance->circ_buf.mask;
-		copied += j;
-	}
-	return copied;
-}
-
-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;
-
-	if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) {	// Only sample counter with reloadnig is working. Reset it.
-		PINFO
-		    ("Only sample counter with reloadnig is working. Reset it.\n");
-		ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-		ctrl_reset = ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-	} else if (instance->fifo_irq_threshold == instance->ISM.read) {	//This is SC interrupt for large block. The whole section is done. Reset SC_IRQ an HF_IRQ and start everything again from beginning.
-		PINFO
-		    ("This is SC interrupt for large block. The whole section is done. Reset SC_IRQ an HF_IRQ and start everything again from beginning.\n");
-		ctrl_set =
-		    ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
-		    ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-		ctrl_reset =
-		    ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
-		      ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
-	} else if (instance->fifo_irq_threshold >= (ME4600_AI_FIFO_MAX_SC + instance->ISM.read)) {	//This is HF interrupt for large block.The next interrupt should be from HF, also. Reset HF.
-		PINFO
-		    ("This is HF interrupt for large block.The next interrupt should be from HF, also. Reset HF.\n");
-		ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-		ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-	} else {		//This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF!
-		PINFO
-		    ("This is HF interrupt for large block.The next interrupt should be from SC. Don't reset HF!\n");
-		ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-		ctrl_reset = 0xFFFFFFFF;
-	}
-
-	//Reset interrupt latch.
-	spin_lock(instance->ctrl_reg_lock);
-	tmp = inl(instance->ctrl_reg);
-	PINFO("ctrl=0x%x ctrl_set=0x%x ctrl_reset=0x%x\n", tmp, ctrl_set,
-	      ctrl_reset);
-	tmp |= ctrl_set;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	if (ctrl_reset != 0xFFFFFFFF) {
-		outl(tmp & ctrl_reset, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reset outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base,
-			   tmp & ctrl_reset);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-
-}
-
-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;
-
-	if (!instance->fifo_irq_threshold) {	//No threshold provided. SC ends work.
-		PINFO("No threshold provided. SC ends work.\n");
-		ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-		if (instance->data_required > (ME4600_AI_FIFO_COUNT - 1 + instance->ISM.global_read)) {	//HF need reseting.
-			ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-		}
-	} else			//if(instance->fifo_irq_threshold)
-	{
-		if (irq_status & ME4600_IRQ_STATUS_BIT_AI_HF) {
-			PINFO("Threshold provided. Clear HF latch.\n");
-			ctrl_set = ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-
-			if (instance->fifo_irq_threshold >= (ME4600_AI_FIFO_MAX_SC + instance->ISM.read)) {	//This is not the last one. HF need reseting.
-				PINFO
-				    ("The next interrupt is HF. HF need be activating.\n");
-				ctrl_reset = ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-			}
-		}
-
-		if (irq_status & ME4600_IRQ_STATUS_BIT_SC) {
-			PINFO("Threshold provided. Restart SC.\n");
-			ctrl_set = ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-			ctrl_reset &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-
-			if (instance->fifo_irq_threshold >= ME4600_AI_FIFO_MAX_SC) {	//This is not the last one. HF need to be activating.
-				PINFO
-				    ("The next interrupt is HF. HF need to be activating.\n");
-				ctrl_reset &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-			}
-		}
-	}
-
-	//Reset interrupt latch.
-	spin_lock(instance->ctrl_reg_lock);
-	tmp = inl(instance->ctrl_reg);
-	tmp |= ctrl_set;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	if (ctrl_reset != 0xFFFFFFFF) {
-		outl(tmp & ctrl_reset, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base,
-			   tmp & ctrl_reset);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-
-}
-
-/** @brief Last chunck of datas. We must reschedule sample counter.
-*	@note Last chunck.
-*	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.(!!!)
-*/
-inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance)
-{
-	register uint32_t rest;
-
-	if (instance->data_required <= instance->ISM.global_read)
-		return;
-
-	rest = instance->data_required - instance->ISM.global_read;
-	if (rest < instance->fifo_irq_threshold) {	//End of work soon ....
-		PDEBUG("Rescheduling SC from %d to %d.\n",
-		       instance->fifo_irq_threshold, rest);
-		/// @note Write new value to SC <==  DANGER! This is not safe solution! We can miss some inputs.
-		outl(rest, instance->sample_counter_reg);
-		PDEBUG_REG("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->sample_counter_reg - instance->reg_base,
-			   rest);
-		instance->fifo_irq_threshold = rest;
-
-		if (rest < ME4600_AI_FIFO_MAX_SC) {
-			instance->ISM.next = rest;
-		} else {
-			instance->ISM.next = rest % ME4600_AI_FIFO_HALF;
-			if (instance->ISM.next + ME4600_AI_FIFO_HALF <
-			    ME4600_AI_FIFO_MAX_SC) {
-				instance->ISM.next += ME4600_AI_FIFO_HALF;
-			}
-		}
-	}
-}
-
-/** Start the ISM. All must be reseted before enter to this function. */
-inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance)
-{
-	register uint32_t tmp;
-
-	if (!instance->data_required) {	//This is infinite aqusition.
-		if (!instance->fifo_irq_threshold) {	//No threshold provided. Set SC to 0.5*FIFO. Clear the SC's latch.
-			//Set the sample counter
-			outl(ME4600_AI_FIFO_HALF, instance->sample_counter_reg);
-			PDEBUG_REG
-			    ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
-			     instance->reg_base,
-			     instance->sample_counter_reg - instance->reg_base,
-			     ME4600_AI_FIFO_HALF);
-		} else {	//Threshold provided. Set SC to treshold. Clear the SC's latch.
-			//Set the sample counter
-			outl(instance->fifo_irq_threshold,
-			     instance->sample_counter_reg);
-			PDEBUG_REG
-			    ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
-			     instance->reg_base,
-			     instance->sample_counter_reg - instance->reg_base,
-			     instance->fifo_irq_threshold);
-		}
-
-		if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) {	//Enable only sample counter's interrupt. Set reload bit. Clear the SC's latch.
-			spin_lock(instance->ctrl_reg_lock);
-			tmp = inl(instance->ctrl_reg);
-			tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
-			tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-			outl(tmp, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   tmp);
-			spin_unlock(instance->ctrl_reg_lock);
-			if (!instance->fifo_irq_threshold) {	//No threshold provided. Set ISM.next to 0.5*FIFO.
-				instance->ISM.next = ME4600_AI_FIFO_HALF;
-			} else {	//Threshold provided. Set ISM.next to treshold.
-				instance->ISM.next =
-				    instance->fifo_irq_threshold;
-			}
-		} else {	//Enable sample counter's and HF's interrupts.
-			spin_lock(instance->ctrl_reg_lock);
-			tmp = inl(instance->ctrl_reg);
-			tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
-			tmp &=
-			    ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
-			      ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
-			outl(tmp, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   tmp);
-			spin_unlock(instance->ctrl_reg_lock);
-
-			instance->ISM.next =
-			    instance->fifo_irq_threshold % ME4600_AI_FIFO_HALF;
-			if (instance->ISM.next + ME4600_AI_FIFO_HALF <
-			    ME4600_AI_FIFO_MAX_SC) {
-				instance->ISM.next += ME4600_AI_FIFO_HALF;
-			}
-		}
-	} else {		//This aqusition is limited to set number of data.
-		if (instance->fifo_irq_threshold >= instance->data_required) {	//Stupid situation.
-			instance->fifo_irq_threshold = 0;
-			PDEBUG
-			    ("Stupid situation: data_required(%d) < threshold(%d).\n",
-			     instance->fifo_irq_threshold,
-			     instance->data_required);
-		}
-
-		if (!instance->fifo_irq_threshold) {	//No threshold provided. Easy case: HF=read and SC=end.
-			//Set the sample counter to data_required.
-			outl(instance->data_required,
-			     instance->sample_counter_reg);
-			PDEBUG_REG
-			    ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
-			     instance->reg_base,
-			     instance->sample_counter_reg - instance->reg_base,
-			     instance->data_required);
-
-			//Reset the latches of sample counter and HF (if SC>FIFO).
-			//No SC reload!
-			spin_lock(instance->ctrl_reg_lock);
-			tmp = inl(instance->ctrl_reg);
-			tmp &=
-			    ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
-			      ME4600_AI_CTRL_BIT_SC_RELOAD);
-			if (instance->data_required >
-			    (ME4600_AI_FIFO_COUNT - 1)) {
-				tmp &= ~ME4600_AI_CTRL_BIT_HF_IRQ_RESET;
-				instance->ISM.next =
-				    instance->data_required %
-				    ME4600_AI_FIFO_HALF;
-				instance->ISM.next += ME4600_AI_FIFO_HALF;
-
-			} else {
-				instance->ISM.next = instance->data_required;
-			}
-			outl(tmp, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   tmp);
-			spin_unlock(instance->ctrl_reg_lock);
-
-		} else {	//The most general case. We have concret numbe of required data and threshold. SC=TH
-			//Set the sample counter to threshold.
-			outl(instance->fifo_irq_threshold,
-			     instance->sample_counter_reg);
-			PDEBUG_REG
-			    ("sample_counter_reg outl(0x%lX+0x%lX)=0x%x\n",
-			     instance->reg_base,
-			     instance->sample_counter_reg - instance->reg_base,
-			     instance->fifo_irq_threshold);
-
-			spin_lock(instance->ctrl_reg_lock);
-			tmp = inl(instance->ctrl_reg);
-			//In this moment we are sure that SC will come more than once.
-			tmp |= ME4600_AI_CTRL_BIT_SC_RELOAD;
-
-			if (instance->fifo_irq_threshold < ME4600_AI_FIFO_MAX_SC) {	//The threshold is so small that we do need HF.
-				tmp &= ~ME4600_AI_CTRL_BIT_SC_IRQ_RESET;
-				instance->ISM.next =
-				    instance->fifo_irq_threshold;
-			} else {	//The threshold is large. The HF must be use.
-				tmp &=
-				    ~(ME4600_AI_CTRL_BIT_SC_IRQ_RESET |
-				      ME4600_AI_CTRL_BIT_HF_IRQ_RESET);
-				instance->ISM.next =
-				    instance->fifo_irq_threshold %
-				    ME4600_AI_FIFO_HALF;
-				if (instance->ISM.next + ME4600_AI_FIFO_HALF <
-				    ME4600_AI_FIFO_MAX_SC) {
-					instance->ISM.next +=
-					    ME4600_AI_FIFO_HALF;
-				}
-			}
-			outl(tmp, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   tmp);
-			spin_unlock(instance->ctrl_reg_lock);
-		}
-	}
-}
-
-static int ai_mux_toggler(me4600_ai_subdevice_t *instance)
-{
-	uint32_t tmp;
-
-	PDEBUG("executed. idx=0\n");
-
-	outl(0, instance->scan_pre_timer_low_reg);
-	PDEBUG_REG("scan_pre_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_low_reg - instance->reg_base, 0);
-	outl(0, instance->scan_pre_timer_high_reg);
-	PDEBUG_REG("scan_pre_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_pre_timer_high_reg - instance->reg_base, 0);
-	outl(0, instance->scan_timer_low_reg);
-	PDEBUG_REG("scan_timer_low_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_timer_low_reg - instance->reg_base, 0);
-	outl(0, instance->scan_timer_high_reg);
-	PDEBUG_REG("scan_timer_high_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->scan_timer_high_reg - instance->reg_base, 0);
-	outl(65, instance->chan_timer_reg);
-	PDEBUG_REG("chan_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->chan_timer_reg - instance->reg_base, 65);
-	outl(65, instance->chan_pre_timer_reg);
-	PDEBUG_REG("chan_pre_timer_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->chan_pre_timer_reg - instance->reg_base, 65);
-
-	// Turn on internal reference.
-	tmp = inl(instance->ctrl_reg);
-	tmp |= ME4600_AI_CTRL_BIT_FULLSCALE;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	// Clear data and channel fifo.
-	tmp &=
-	    ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	// Write channel entry.
-	outl(ME4600_AI_LIST_INPUT_DIFFERENTIAL |
-	     ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31,
-	     instance->channel_list_reg);
-	PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->channel_list_reg - instance->reg_base,
-		   ME4600_AI_LIST_INPUT_DIFFERENTIAL |
-		   ME4600_AI_LIST_RANGE_UNIPOLAR_2_5 | 31);
-
-	// Start conversion.
-	inl(instance->start_reg);
-	PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
-		   instance->start_reg - instance->reg_base);
-	udelay(10);
-
-	// Clear data and channel fifo.
-	tmp &=
-	    ~(ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO);
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	tmp |= ME4600_AI_CTRL_BIT_CHANNEL_FIFO | ME4600_AI_CTRL_BIT_DATA_FIFO;
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	// Write channel entry.
-	// ME4600_AI_LIST_INPUT_SINGLE_ENDED | ME4600_AI_LIST_RANGE_BIPOLAR_10 <= 0x0000
-	outl(ME4600_AI_LIST_INPUT_SINGLE_ENDED |
-	     ME4600_AI_LIST_RANGE_BIPOLAR_10, instance->channel_list_reg);
-	PDEBUG_REG("channel_list_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->channel_list_reg - instance->reg_base,
-		   ME4600_AI_LIST_INPUT_SINGLE_ENDED |
-		   ME4600_AI_LIST_RANGE_BIPOLAR_10);
-
-	// Start conversion.
-	inl(instance->start_reg);
-	PDEBUG_REG("start_reg inl(0x%lX+0x%lX)\n", instance->reg_base,
-		   instance->start_reg - instance->reg_base);
-	udelay(10);
-
-	// Clear control register.
-	tmp &= (ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-/** @brief Copy rest of data from fifo to circular buffer.
-* @note Helper for STOP command. After FSM is stopped.
-* @note This is slow function that copy all remainig data from FIFO to buffer.
-*
-* @param instance The subdevice instance (pointer).
-*
-* @return On success: Number of copied values.
-* @return On error: Negative error code -ME_ERRNO_RING_BUFFER_OVERFLOW.
-*/
-static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance)
-{				/// @note This is time critical function!
-	int empty_space;
-	int copied = 0;
-	int status = ME_ERRNO_SUCCESS;
-
-	PDEBUG("Space left in circular buffer = %d.\n",
-	       me_circ_buf_space(&instance->circ_buf));
-
-	while ((empty_space = me_circ_buf_space(&instance->circ_buf))) {
-		if (!(status = inl(instance->status_reg) & ME4600_AI_STATUS_BIT_EF_DATA)) {	//No more data. status = ME_ERRNO_SUCCESS = 0
-			break;
-		}
-		*(instance->circ_buf.buf + instance->circ_buf.head) =
-		    (inw(instance->data_reg) ^ 0x8000);
-		instance->circ_buf.head++;
-		instance->circ_buf.head &= instance->circ_buf.mask;
-	}
-
-#ifdef MEDEBUG_ERROR
-	if (!status)
-		PDEBUG
-		    ("Copied all remaining datas (%d) from FIFO to circular buffer.\n",
-		     copied);
-	else {
-		PDEBUG("No more empty space in buffer.\n");
-		PDEBUG("Copied %d datas from FIFO to circular buffer.\n",
-		       copied);
-		PDEBUG("FIFO still not empty.\n");
-	}
-#endif
-	return (!status) ? copied : -ME_ERRNO_RING_BUFFER_OVERFLOW;
-}
-
-static void me4600_ai_work_control_task(struct work_struct *work)
-{
-	me4600_ai_subdevice_t *instance;
-	uint32_t status;
-	uint32_t ctrl;
-	unsigned long cpu_flags = 0;
-	int reschedule = 0;
-	int signaling = 0;
-
-	instance =
-	    container_of((void *)work, me4600_ai_subdevice_t, ai_control_task);
-	PINFO("<%s: %ld> executed.\n", __func__, jiffies);
-
-	status = inl(instance->status_reg);
-	PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->status_reg - instance->reg_base, status);
-
-	switch (instance->status) {	// Checking actual mode.
-		// Not configured for work.
-	case ai_status_none:
-		break;
-
-		//This are stable modes. No need to do anything. (?)
-	case ai_status_single_configured:
-	case ai_status_stream_configured:
-	case ai_status_stream_fifo_error:
-	case ai_status_stream_buffer_error:
-	case ai_status_stream_error:
-		PERROR("Shouldn't be running!.\n");
-		break;
-
-		// Stream modes
-	case ai_status_stream_run_wait:
-		if (status & ME4600_AI_STATUS_BIT_FSM) {	// ISM started..
-			instance->status = ai_status_stream_run;
-			// Signal the end of wait for start.
-			signaling = 1;
-			// Wait now for stop.
-			reschedule = 1;
-			break;
-
-			// Check timeout.
-			if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) {	// Timeout
-				PDEBUG("Timeout reached.\n");
-				// Stop all actions. No conditions! Block interrupts. Reset FIFO => Too late!
-				ai_stop_isr(instance);
-
-				instance->status = ai_status_stream_end;
-
-				// Signal the end.
-				signaling = 1;
-			}
-		}
-		break;
-
-	case ai_status_stream_run:
-		// Wait for stop ISM.
-		reschedule = 1;
-		break;
-
-	case ai_status_stream_end_wait:
-		if (!(status & ME4600_AI_STATUS_BIT_FSM)) {	// ISM stoped. Overwrite ISR.
-			instance->status = ai_status_stream_end;
-			// Signal the end of wait for stop.
-			signaling = 1;
-		} else {
-			// Wait for stop ISM.
-			reschedule = 1;
-		}
-		break;
-
-	case ai_status_stream_end:
-		//End work.
-		if (status & ME4600_AI_STATUS_BIT_FSM) {	// Still working? Stop it!
-			PERROR
-			    ("Status is 'ai_status_stream_end' but hardware is still working!\n");
-			spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |=
-			    (ME4600_AI_CTRL_BIT_IMMEDIATE_STOP |
-			     ME4600_AI_CTRL_BIT_HF_IRQ_RESET |
-			     ME4600_AI_CTRL_BIT_SC_IRQ_RESET);
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(instance->ctrl_reg_lock,
-					       cpu_flags);
-		}
-		break;
-
-	default:
-		PERROR_CRITICAL("Status is in wrong state (%d)!\n",
-				instance->status);
-		instance->status = ai_status_stream_error;
-		// Signal the end.
-		signaling = 1;
-		break;
-
-	}
-
-	if (signaling) {	//Signal it.
-		wake_up_interruptible_all(&instance->wait_queue);
-	}
-
-	if (instance->ai_control_task_flag && reschedule) {	// Reschedule task
-		queue_delayed_work(instance->me4600_workqueue,
-				   &instance->ai_control_task, 1);
-	} else {
-		PINFO("<%s> Ending control task.\n", __func__);
-	}
-
-}
diff --git a/drivers/staging/meilhaus/me4600_ai.h b/drivers/staging/meilhaus/me4600_ai.h
deleted file mode 100644
index 7055e44..0000000
--- a/drivers/staging/meilhaus/me4600_ai.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * @file me4600_ai.h
- *
- * @brief Meilhaus ME-4000 analog input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke  (k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_AI_H_
-#define _ME4600_AI_H_
-
-#include "mesubdevice.h"
-#include "meioctl.h"
-#include "mecirc_buf.h"
-
-#ifdef __KERNEL__
-
-#define ME4600_AI_MAX_DATA				0xFFFF
-
-#ifdef ME_SYNAPSE
-# define ME4600_AI_CIRC_BUF_SIZE_ORDER	8	// 2^n PAGES =>> Maximum value of 1MB for Synapse
-#else
-# define ME4600_AI_CIRC_BUF_SIZE_ORDER	5	// 2^n PAGES =>> 128KB
-#endif
-#define ME4600_AI_CIRC_BUF_SIZE 		PAGE_SIZE<<ME4600_AI_CIRC_BUF_SIZE_ORDER	// Buffer size in bytes.
-
-#ifdef _CBUFF_32b_t
-# define ME4600_AI_CIRC_BUF_COUNT		((ME4600_AI_CIRC_BUF_SIZE) / sizeof(uint32_t))	// Size in values
-#else
-# define ME4600_AI_CIRC_BUF_COUNT		((ME4600_AI_CIRC_BUF_SIZE) / sizeof(uint16_t))	// Size in values
-#endif
-
-#define ME4600_AI_FIFO_HALF				1024	//ME4600_AI_FIFO_COUNT/2                //1024
-#define ME4600_AI_FIFO_MAX_SC			1352	//0.66*ME4600_AI_FIFO_COUNT             //1352
-
-typedef enum ME4600_AI_STATUS {
-	ai_status_none = 0,
-	ai_status_single_configured,
-	ai_status_stream_configured,
-	ai_status_stream_run_wait,
-	ai_status_stream_run,
-	ai_status_stream_end_wait,
-	ai_status_stream_end,
-	ai_status_stream_fifo_error,
-	ai_status_stream_buffer_error,
-	ai_status_stream_error,
-	ai_status_last
-} ME4600_AI_STATUS;
-
-typedef struct me4600_single_config_entry {
-	unsigned short status;
-	uint32_t entry;
-	uint32_t ctrl;
-} me4600_single_config_entry_t;
-
-typedef struct me4600_range_entry {
-	int min;
-	int max;
-} me4600_range_entry_t;
-
-typedef struct me4600_ai_ISM {
-	volatile unsigned int global_read;				/**< The number of data read in total. */
-	volatile unsigned int read;						/**< The number of data read for this chunck. */
-	volatile unsigned int next;						/**< The number of data request by user. */
-} me4600_ai_ISM_t;
-
-typedef struct me4600_ai_timeout {
-	unsigned long start_time;
-	unsigned long delay;
-} me4600_ai_timeout_t;
-
-/**
- * @brief The ME-4000 analog input subdevice class.
- */
-typedef struct me4600_ai_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;							/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;						/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;						/**< Spin lock to protect #ctrl_reg from concurrent access. */
-
-	/* Hardware feautres */
-	unsigned int irq;								/**< The interrupt request number assigned by the PCI BIOS. */
-	int isolated;									/**< Marks if this subdevice is on an optoisolated device. */
-	int sh;											/**< Marks if this subdevice has sample and hold devices. */
-
-	unsigned int channels;							/**< The number of channels available on this subdevice. */
-	me4600_single_config_entry_t single_config[32];	/**< The configuration set for single acquisition. */
-
-	unsigned int data_required;						/**< The number of data request by user. */
-	unsigned int fifo_irq_threshold;				/**< The user adjusted FIFO high water interrupt level. */
-	unsigned int chan_list_len;						/**< The length of the user defined channel list. */
-
-	me4600_ai_ISM_t ISM;							/**< The information request by Interrupt-State-Machine. */
-	volatile enum ME4600_AI_STATUS status;			/**< The current stream status flag. */
-	me4600_ai_timeout_t timeout;					/**< The timeout for start in blocking and non-blocking mode. */
-
-											/* Registers *//**< All registers are 32 bits long. */
-	unsigned long ctrl_reg;
-	unsigned long status_reg;
-	unsigned long channel_list_reg;
-	unsigned long data_reg;
-	unsigned long chan_timer_reg;
-	unsigned long chan_pre_timer_reg;
-	unsigned long scan_timer_low_reg;
-	unsigned long scan_timer_high_reg;
-	unsigned long scan_pre_timer_low_reg;
-	unsigned long scan_pre_timer_high_reg;
-	unsigned long start_reg;
-	unsigned long irq_status_reg;
-	unsigned long sample_counter_reg;
-
-	unsigned int ranges_len;
-	me4600_range_entry_t ranges[4];					/**< The ranges available on this subdevice. */
-
-	/* Software buffer */
-	me_circ_buf_t circ_buf;							/**< Circular buffer holding measurment data. */
-	wait_queue_head_t wait_queue;					/**< Wait queue to put on tasks waiting for data to arrive. */
-
-	struct workqueue_struct *me4600_workqueue;
-	struct delayed_work ai_control_task;
-
-	volatile int ai_control_task_flag;				/**< Flag controling reexecuting of control task */
-
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me4600_ai_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 analog input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param channels The number of analog input channels available on this subdevice.
- * @param channels The number of analog input ranges available on this subdevice.
- * @param isolated Flag indicating if this device is opto isolated.
- * @param sh Flag indicating if sample and hold devices are available.
- * @param irq The irq number assigned by PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
-					     unsigned int channels,
-					     unsigned int ranges,
-					     int isolated,
-					     int sh,
-					     int irq,
-					     spinlock_t * ctrl_reg_lock,
-					     struct workqueue_struct
-					     *me4600_wq);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ai_reg.h b/drivers/staging/meilhaus/me4600_ai_reg.h
deleted file mode 100644
index 083fac7..0000000
--- a/drivers/staging/meilhaus/me4600_ai_reg.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * @file me4600_ai_reg.h
- *
- * @brief ME-4000 analog input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_AI_REG_H_
-#define _ME4600_AI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_AI_CTRL_REG					0x74	// _/W
-#define ME4600_AI_STATUS_REG				0x74	// R/_
-#define ME4600_AI_CHANNEL_LIST_REG			0x78	// _/W
-#define ME4600_AI_DATA_REG					0x7C	// R/_
-#define ME4600_AI_CHAN_TIMER_REG			0x80	// _/W
-#define ME4600_AI_CHAN_PRE_TIMER_REG		0x84	// _/W
-#define ME4600_AI_SCAN_TIMER_LOW_REG		0x88	// _/W
-#define ME4600_AI_SCAN_TIMER_HIGH_REG		0x8C	// _/W
-#define ME4600_AI_SCAN_PRE_TIMER_LOW_REG	0x90	// _/W
-#define ME4600_AI_SCAN_PRE_TIMER_HIGH_REG	0x94	// _/W
-#define ME4600_AI_START_REG					0x98	// R/_
-
-#define ME4600_AI_SAMPLE_COUNTER_REG		0xC0	// _/W
-
-#define ME4600_AI_CTRL_BIT_MODE_0			0x00000001
-#define ME4600_AI_CTRL_BIT_MODE_1			0x00000002
-#define ME4600_AI_CTRL_BIT_MODE_2			0x00000004
-#define ME4600_AI_CTRL_BIT_SAMPLE_HOLD		0x00000008
-#define ME4600_AI_CTRL_BIT_IMMEDIATE_STOP	0x00000010
-#define ME4600_AI_CTRL_BIT_STOP				0x00000020
-#define ME4600_AI_CTRL_BIT_CHANNEL_FIFO		0x00000040
-#define ME4600_AI_CTRL_BIT_DATA_FIFO		0x00000080
-#define ME4600_AI_CTRL_BIT_FULLSCALE		0x00000100
-#define ME4600_AI_CTRL_BIT_OFFSET			0x00000200
-#define ME4600_AI_CTRL_BIT_EX_TRIG_ANALOG	0x00000400
-#define ME4600_AI_CTRL_BIT_EX_TRIG			0x00000800
-#define ME4600_AI_CTRL_BIT_EX_TRIG_FALLING	0x00001000
-#define ME4600_AI_CTRL_BIT_EX_IRQ			0x00002000
-#define ME4600_AI_CTRL_BIT_EX_IRQ_RESET		0x00004000
-#define ME4600_AI_CTRL_BIT_LE_IRQ			0x00008000
-#define ME4600_AI_CTRL_BIT_LE_IRQ_RESET		0x00010000
-#define ME4600_AI_CTRL_BIT_HF_IRQ			0x00020000
-#define ME4600_AI_CTRL_BIT_HF_IRQ_RESET		0x00040000
-#define ME4600_AI_CTRL_BIT_SC_IRQ			0x00080000
-#define ME4600_AI_CTRL_BIT_SC_IRQ_RESET		0x00100000
-#define ME4600_AI_CTRL_BIT_SC_RELOAD		0x00200000
-#define ME4600_AI_CTRL_BIT_EX_TRIG_BOTH		0x80000000
-
-#define ME4600_AI_STATUS_BIT_EF_CHANNEL		0x00400000
-#define ME4600_AI_STATUS_BIT_HF_CHANNEL		0x00800000
-#define ME4600_AI_STATUS_BIT_FF_CHANNEL		0x01000000
-#define ME4600_AI_STATUS_BIT_EF_DATA		0x02000000
-#define ME4600_AI_STATUS_BIT_HF_DATA		0x04000000
-#define ME4600_AI_STATUS_BIT_FF_DATA		0x08000000
-#define ME4600_AI_STATUS_BIT_LE				0x10000000
-#define ME4600_AI_STATUS_BIT_FSM			0x20000000
-
-#define ME4600_AI_CTRL_RPCI_FIFO			0x40000000	//Always set to zero!
-
-#define ME4600_AI_BASE_FREQUENCY			33E6
-
-#define ME4600_AI_MIN_ACQ_TICKS				66LL
-#define ME4600_AI_MAX_ACQ_TICKS				0xFFFFFFFFLL
-
-#define ME4600_AI_MIN_SCAN_TICKS			66LL
-#define ME4600_AI_MAX_SCAN_TICKS			0xFFFFFFFFFLL
-
-#define ME4600_AI_MIN_CHAN_TICKS			66LL
-#define ME4600_AI_MAX_CHAN_TICKS			0xFFFFFFFFLL
-
-#define ME4600_AI_FIFO_COUNT				2048
-
-#define ME4600_AI_LIST_COUNT				1024
-
-#define ME4600_AI_LIST_INPUT_SINGLE_ENDED	0x000
-#define ME4600_AI_LIST_INPUT_DIFFERENTIAL	0x020
-
-#define ME4600_AI_LIST_RANGE_BIPOLAR_10		0x000
-#define ME4600_AI_LIST_RANGE_BIPOLAR_2_5	0x040
-#define ME4600_AI_LIST_RANGE_UNIPOLAR_10	0x080
-#define ME4600_AI_LIST_RANGE_UNIPOLAR_2_5	0x0C0
-
-#define ME4600_AI_LIST_LAST_ENTRY		0x100
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ao.c b/drivers/staging/meilhaus/me4600_ao.c
deleted file mode 100644
index 4000dac..0000000
--- a/drivers/staging/meilhaus/me4600_ao.c
+++ /dev/null
@@ -1,5974 +0,0 @@
-/**
- * @file me4600_ao.c
- *
- * @brief ME-4000 analog output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-///Common part. (For normal and Bosch builds.)
-
-/* Includes
- */
-
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/types.h>
-#include <linux/version.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meids.h"
-#include "me4600_reg.h"
-#include "me4600_ao_reg.h"
-#include "me4600_ao.h"
-
-/* Defines
- */
-
-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,
-					 int unit, int *count);
-
-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,
-				 int timer,
-				 int *base_frequency,
-				 long long *min_ticks, long long *max_ticks);
-
-static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
-					   int *number);
-
-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,
-					  int *caps);
-
-static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
-					       int cap, int *args, int count);
-
-#ifndef BOSCH
-/// @note NORMAL BUILD
-/// @author Krzysztof Gantzke   (k.gantzke@meilhaus.de)
-/* Includes
- */
-
-# include <linux/workqueue.h>
-
-/* Defines
- */
-
-/** Remove subdevice.
-*/
-static void me4600_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 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,
-				      struct file *filep,
-				      int channel,
-				      int single_config,
-				      int ref,
-				      int trig_chan,
-				      int trig_type, int trig_edge, int flags);
-
-/** Pass to user actual value of output.
-*/
-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,
-				     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,
-				      struct file *filep,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      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,
-					  struct file *filep,
-					  int time_out, int *count, int flags);
-
-/** Start streaming.
-*/
-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,
-				      struct file *filep,
-				      int wait,
-				      int *status, int *values, int flags);
-
-/** Stop streaming.
-*/
-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,
-				     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);
-/** Copy data from circular buffer to fifo (fast) in wraparound mode.
-*/
-inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
-				    int start_pos);
-
-/** Copy data from circular buffer to fifo (fast).
-*/
-inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
-			 int start_pos);
-
-/** Copy data from circular buffer to fifo (slow).
-*/
-inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
-				 int start_pos);
-
-/** Copy data from user space to circular buffer.
-*/
-inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
-				 int *user_values);
-
-/** Stop presentation. Preserve FIFOs.
-*/
-inline int ao_stop_immediately(me4600_ao_subdevice_t *instance);
-
-/** Task for asynchronical state verifying.
-*/
-static void me4600_ao_work_control_task(struct work_struct *work);
-/* Functions
- */
-
-static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
-					struct file *filep, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t tmp;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	instance->status = ao_status_none;
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-	instance->timeout.delay = 0;
-	instance->timeout.start_time = jiffies;
-
-	//Stop state machine.
-	err = ao_stop_immediately(instance);
-
-	//Remove from synchronous start.
-	spin_lock(instance->preload_reg_lock);
-	tmp = inl(instance->preload_reg);
-	tmp &=
-	    ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
-	      ao_idx);
-	outl(tmp, instance->preload_reg);
-	PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, tmp);
-	*instance->preload_flags &=
-	    ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
-	      ao_idx);
-	spin_unlock(instance->preload_reg_lock);
-
-	//Set single mode, dissable FIFO, dissable external trigger, set output to analog, block interrupt.
-	outl(ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP |
-	     ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_RESET_IRQ,
-	     instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base,
-		   ME4600_AO_MODE_SINGLE | ME4600_AO_CTRL_BIT_STOP |
-		   ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
-		   ME4600_AO_CTRL_BIT_RESET_IRQ);
-
-	//Set output to 0V
-	outl(0x8000, instance->single_reg);
-	PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->single_reg - instance->reg_base, 0x8000);
-
-	instance->circ_buf.head = 0;
-	instance->circ_buf.tail = 0;
-	instance->preloaded_count = 0;
-	instance->data_count = 0;
-	instance->single_value = 0x8000;
-	instance->single_value_in_fifo = 0x8000;
-
-	//Set status to signal that device is unconfigured.
-	instance->status = ao_status_none;
-
-	//Signal reset if user is on wait.
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_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)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t ctrl;
-	uint32_t sync;
-	unsigned long cpu_flags;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	// Checking parameters
-	if (flags) {
-		PERROR
-		    ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	switch (trig_type) {
-	case ME_TRIG_TYPE_SW:
-		if (trig_edge != ME_TRIG_EDGE_NONE) {
-			PERROR
-			    ("Invalid trigger edge. Software trigger has not edge.\n");
-			return ME_ERRNO_INVALID_TRIG_EDGE;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		switch (trig_edge) {
-		case ME_TRIG_EDGE_ANY:
-		case ME_TRIG_EDGE_RISING:
-		case ME_TRIG_EDGE_FALLING:
-			break;
-
-		default:
-			PERROR("Invalid trigger edge.\n");
-			return ME_ERRNO_INVALID_TRIG_EDGE;
-		}
-		break;
-
-	default:
-		PERROR
-		    ("Invalid trigger type. Trigger must be software or digital.\n");
-		return ME_ERRNO_INVALID_TRIG_TYPE;
-	}
-
-	if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
-	    && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
-		PERROR("Invalid trigger channel specified.\n");
-		return ME_ERRNO_INVALID_TRIG_CHAN;
-	}
-
-	if (ref != ME_REF_AO_GROUND) {
-		PERROR
-		    ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if (single_config != 0) {
-		PERROR
-		    ("Invalid single config specified. Only one range for anlog outputs is available.\n");
-		return ME_ERRNO_INVALID_SINGLE_CONFIG;
-	}
-
-	if (channel != 0) {
-		PERROR
-		    ("Invalid channel number specified. Analog output have only one channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	//Subdevice running in stream mode!
-	if ((instance->status >= ao_status_stream_run_wait)
-	    && (instance->status < ao_status_stream_end)) {
-		PERROR("Subdevice is busy.\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-/// @note For single all calls (config and write) are erasing previous state!
-
-	instance->status = ao_status_none;
-
-	// Correct single mirrors
-	instance->single_value_in_fifo = instance->single_value;
-
-	//Stop device
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-	// Set control register.
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	// Set stop bit. Stop streaming mode.
-	ctrl = inl(instance->ctrl_reg);
-	//Reset all bits.
-	ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP;
-
-	if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
-		PINFO("External digital trigger.\n");
-
-		if (trig_edge == ME_TRIG_EDGE_ANY) {
-//                              ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-			instance->ctrl_trg =
-			    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
-			    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-		} else if (trig_edge == ME_TRIG_EDGE_FALLING) {
-//                              ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-			instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-		} else if (trig_edge == ME_TRIG_EDGE_RISING) {
-			instance->ctrl_trg = 0x0;
-		}
-	} else if (trig_type == ME_TRIG_TYPE_SW) {
-		PDEBUG("Software trigger\n");
-		instance->ctrl_trg = 0x0;
-	}
-
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	// Set preload/synchronization register.
-	spin_lock(instance->preload_reg_lock);
-	if (trig_type == ME_TRIG_TYPE_SW) {
-		*instance->preload_flags &=
-		    ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
-	} else			//if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL)
-	{
-		*instance->preload_flags |=
-		    ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx;
-	}
-
-	if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
-		*instance->preload_flags &=
-		    ~(ME4600_AO_SYNC_HOLD << instance->ao_idx);
-	} else			//if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS)
-	{
-		*instance->preload_flags |=
-		    ME4600_AO_SYNC_HOLD << instance->ao_idx;
-	}
-
-	//Reset hardware register
-	sync = inl(instance->preload_reg);
-	PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, sync);
-	sync &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
-	sync |= ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
-	//Output configured in default (safe) mode.
-	outl(sync, instance->preload_reg);
-	PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, sync);
-	spin_unlock(instance->preload_reg_lock);
-
-	instance->status = ao_status_single_configured;
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	unsigned long j;
-	unsigned long delay = 0;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
-		PERROR("Invalid flag specified. %d\n", flags);
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (channel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if ((instance->status >= ao_status_stream_configured)
-	    && (instance->status <= ao_status_stream_end)) {
-		PERROR("Subdevice not configured to work in single mode!\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	ME_SUBDEVICE_ENTER;
-	if ((!flags) && (instance->status == ao_status_single_run_wait)) {	//Blocking mode. Wait for trigger.
-		if (time_out) {
-			delay = (time_out * HZ) / 1000;
-			if (delay == 0)
-				delay = 1;
-		}
-
-		j = jiffies;
-
-		//Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_single_run_wait),
-						 (delay) ? delay +
-						 1 : LONG_MAX);
-
-		if (instance->status == ao_status_none) {
-			PDEBUG("Single canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		if ((delay) && ((jiffies - j) >= delay)) {
-
-			PDEBUG("Timeout reached.\n");
-			err = ME_ERRNO_TIMEOUT;
-		}
-
-		*value =
-		    (!err) ? instance->single_value_in_fifo : instance->
-		    single_value;
-	} else {		//Non-blocking mode
-		//Read value
-		*value = instance->single_value;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags;
-	unsigned long j;
-	unsigned long delay = 0x0;
-
-	//Registry handling variables.
-	uint32_t sync_mask;
-	uint32_t mode;
-	uint32_t tmp;
-	uint32_t ctrl;
-	uint32_t status;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags &
-	    ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
-	      ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (value & ~ME4600_AO_MAX_DATA) {
-		PERROR("Invalid value provided.\n");
-		return ME_ERRNO_VALUE_OUT_OF_RANGE;
-	}
-
-	if (channel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if ((instance->status == ao_status_none)
-	    || (instance->status > ao_status_single_end)) {
-		PERROR("Subdevice not configured to work in single mode!\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-/// @note For single all calls (config and write) are erasing previous state!
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-
-	// Correct single mirrors
-	instance->single_value_in_fifo = instance->single_value;
-
-	//Stop device
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-
-		if (delay == 0)
-			delay = 1;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	instance->single_value_in_fifo = value;
-
-	ctrl = inl(instance->ctrl_reg);
-
-	if (!instance->fifo) {	//No FIFO
-		//Set the single mode.
-		ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
-
-		//Write value
-		PDEBUG("Write value\n");
-		outl(value, instance->single_reg);
-		PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->single_reg - instance->reg_base, value);
-	} else {		// mix-mode
-		//Set speed
-		outl(ME4600_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
-		PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->timer_reg - instance->reg_base,
-			   (int)ME4600_AO_MIN_CHAN_TICKS);
-		instance->hardware_stop_delay = HZ / 10;	//100ms
-
-		status = inl(instance->status_reg);
-
-		//Set the continous mode.
-		ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
-		ctrl |= ME4600_AO_MODE_CONTINUOUS;
-
-		//Prepare FIFO
-		if (!(ctrl & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) {	//FIFO wasn't enabeled. Do it.
-			PINFO("Enableing FIFO.\n");
-			ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			ctrl |=
-			    ME4600_AO_CTRL_BIT_ENABLE_FIFO |
-			    ME4600_AO_CTRL_BIT_RESET_IRQ;
-		} else {	//Check if FIFO is empty
-			if (status & ME4600_AO_STATUS_BIT_EF) {	//FIFO not empty
-				PINFO("Reseting FIFO.\n");
-				ctrl &=
-				    ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO |
-				      ME4600_AO_CTRL_BIT_ENABLE_IRQ);
-				ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-				outl(ctrl, instance->ctrl_reg);
-				PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->ctrl_reg -
-					   instance->reg_base, ctrl);
-
-				ctrl |=
-				    ME4600_AO_CTRL_BIT_ENABLE_FIFO |
-				    ME4600_AO_CTRL_BIT_RESET_IRQ;
-			} else {	//FIFO empty, only interrupt needs to be disabled!
-				ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-				ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-			}
-		}
-
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		//Write output - 1 value to FIFO
-		if (instance->ao_idx & 0x1) {
-			outl(value <<= 16, instance->fifo_reg);
-			PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->fifo_reg - instance->reg_base,
-				   value <<= 16);
-		} else {
-			outl(value, instance->fifo_reg);
-			PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->fifo_reg - instance->reg_base,
-				   value);
-		}
-	}
-
-	mode = *instance->preload_flags >> instance->ao_idx;
-	mode &= (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG);
-
-	PINFO("Triggering mode: 0x%x\n", mode);
-
-	spin_lock(instance->preload_reg_lock);
-	sync_mask = inl(instance->preload_reg);
-	PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, sync_mask);
-	switch (mode) {
-	case 0:		//Individual software
-		ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-		if (!instance->fifo) {	// No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output.
-			if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD) {	//Now we can set correct mode. This is exception. It is set to synchronous and triggered later.
-				sync_mask &=
-				    ~(ME4600_AO_SYNC_EXT_TRIG << instance->
-				      ao_idx);
-				sync_mask |=
-				    ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		} else {	// FIFO
-			if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) {	//Now we can set correct mode.
-				sync_mask &=
-				    ~((ME4600_AO_SYNC_EXT_TRIG |
-				       ME4600_AO_SYNC_HOLD) << instance->
-				      ao_idx);
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		}
-		instance->single_value = value;
-		break;
-
-	case ME4600_AO_SYNC_EXT_TRIG:	//Individual hardware
-		ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-		if (!instance->fifo) {	// No FIFO - In this case resetting 'ME4600_AO_SYNC_HOLD' will trigger output.
-			if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD) {	//Now we can set correct mode
-				sync_mask &=
-				    ~(ME4600_AO_SYNC_EXT_TRIG << instance->
-				      ao_idx);
-				sync_mask |=
-				    ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		} else {	// FIFO
-			if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) {	//Now we can set correct mode.
-				sync_mask &=
-				    ~((ME4600_AO_SYNC_EXT_TRIG |
-				       ME4600_AO_SYNC_HOLD) << instance->
-				      ao_idx);
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		}
-		break;
-
-	case ME4600_AO_SYNC_HOLD:	//Synchronous software
-		ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-//                                      if((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME4600_AO_SYNC_HOLD)
-		if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG)) {	//Now we can set correct mode
-			sync_mask |=
-			    ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx;
-//                                              sync_mask &= ~(ME4600_AO_SYNC_EXT_TRIG << instance->ao_idx);
-			sync_mask |= ME4600_AO_SYNC_HOLD << instance->ao_idx;
-
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-		}
-		break;
-
-	case (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG):	//Synchronous hardware
-		ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-		if ((sync_mask & ((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG)) {	//Now we can set correct mode
-			sync_mask |=
-			    (ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
-			    instance->ao_idx;
-
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-		}
-		break;
-	}
-//              spin_unlock(instance->preload_reg_lock);        // Moved down.
-
-	//Activate ISM (remove 'stop' bits)
-	ctrl &=
-	    ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
-	      ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
-	ctrl |= instance->ctrl_trg;
-	ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS!
-
-	if (!instance->fifo) {	//No FIFO
-		if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {	//Fired all software synchronous outputs.
-			tmp = ~(*instance->preload_flags | 0xFFFF0000);
-			PINFO
-			    ("Fired all software synchronous outputs. mask:0x%08x\n",
-			     tmp);
-			tmp |= sync_mask & 0xFFFF0000;
-			// Add this channel to list
-			tmp &= ~(ME4600_AO_SYNC_HOLD << instance->ao_idx);
-
-			//Fire
-			PINFO("Software trigger.\n");
-			outl(tmp, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   tmp);
-
-			//Restore save settings
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-		} else if (!mode) {	// Add this channel to list
-			outl(sync_mask &
-			     ~(ME4600_AO_SYNC_HOLD << instance->ao_idx),
-			     instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask & ~(ME4600_AO_SYNC_HOLD <<
-						 instance->ao_idx));
-
-			//Fire
-			PINFO("Software trigger.\n");
-
-			//Restore save settings
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-		}
-
-	} else {		// mix-mode - begin
-		if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {	//Trigger outputs
-			//Add channel to start list
-			outl(sync_mask |
-			     (ME4600_AO_SYNC_HOLD << instance->ao_idx),
-			     instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask | (ME4600_AO_SYNC_HOLD <<
-						instance->ao_idx));
-
-			//Fire
-			PINFO
-			    ("Fired all software synchronous outputs by software trigger.\n");
-			outl(0x8000, instance->single_reg);
-			PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->single_reg - instance->reg_base,
-				   0x8000);
-
-			//Restore save settings
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-		} else if (!mode) {	//Trigger outputs
-/*			//Remove channel from start list //<== Unnecessary. Removed.
-			outl(sync_mask & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, tmp);
-*/
-			//Fire
-			PINFO("Software trigger.\n");
-			outl(0x8000, instance->single_reg);
-			PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->single_reg - instance->reg_base,
-				   0x8000);
-
-/*			//Restore save settings //<== Unnecessary. Removed.
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask);
-*/
-		}
-	}
-	spin_unlock(instance->preload_reg_lock);
-
-	j = jiffies;
-	instance->status = ao_status_single_run_wait;
-
-	instance->timeout.delay = delay;
-	instance->timeout.start_time = j;
-	instance->ao_control_task_flag = 1;
-	queue_delayed_work(instance->me4600_workqueue,
-			   &instance->ao_control_task, 1);
-
-	if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_single_run_wait),
-						 (delay) ? delay +
-						 1 : LONG_MAX);
-
-		if (((!delay) || ((jiffies - j) <= delay))
-		    && (instance->status != ao_status_single_end)) {
-			PDEBUG("Single canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			instance->ao_control_task_flag = 0;
-			cancel_delayed_work(&instance->ao_control_task);
-			ao_stop_immediately(instance);
-			instance->status = ao_status_none;
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		if ((delay) && ((jiffies - j) >= delay)) {
-			if (instance->status == ao_status_single_end) {
-				PDEBUG("Timeout reached.\n");
-			} else {
-				if ((jiffies - j) > delay) {
-					PERROR
-					    ("Timeout reached. Not handled by control task!\n");
-				} else {
-					PERROR
-					    ("Timeout reached. Signal come but status is strange: %d\n",
-					     instance->status);
-				}
-
-				ao_stop_immediately(instance);
-			}
-
-			instance->ao_control_task_flag = 0;
-			cancel_delayed_work(&instance->ao_control_task);
-			instance->status = ao_status_single_end;
-			err = ME_ERRNO_TIMEOUT;
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      meIOStreamTrigger_t *trigger,
-				      int fifo_irq_threshold, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t ctrl;
-	unsigned long cpu_flags;
-	uint64_t conv_ticks;
-	unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
-	unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	conv_ticks =
-	    (uint64_t) conv_start_ticks_low +
-	    ((uint64_t) conv_start_ticks_high << 32);
-
-	if (flags &
-	    ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY | ME_IO_STREAM_CONFIG_WRAPAROUND
-	      | ME_IO_STREAM_CONFIG_BIT_PATTERN)) {
-		PERROR("Invalid flags.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
-		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;
-		}
-
-		if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE)
-		    || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) {
-			PERROR
-			    ("Hardware wraparound mode must be in infinite mode.\n");
-			return ME_ERRNO_INVALID_FLAGS;
-		}
-	}
-
-	if (count != 1) {
-		PERROR("Only 1 entry in config list acceptable.\n");
-		return ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
-	}
-
-	if (config_list[0].iChannel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (config_list[0].iStreamConfig != 0) {
-		PERROR("Only one range available.\n");
-		return ME_ERRNO_INVALID_STREAM_CONFIG;
-	}
-
-	if (config_list[0].iRef != ME_REF_AO_GROUND) {
-		PERROR("Output is referenced to ground.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if ((trigger->iAcqStartTicksLow != 0)
-	    || (trigger->iAcqStartTicksHigh != 0)) {
-		PERROR
-		    ("Invalid acquisition start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_ARG;
-	}
-
-	if (config_list[0].iFlags) {
-		PERROR("Invalid config list flag.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	switch (trigger->iAcqStartTrigType) {
-	case ME_TRIG_TYPE_SW:
-		if (trigger->iAcqStartTrigEdge != ME_TRIG_EDGE_NONE) {
-			PERROR
-			    ("Invalid acquisition start trigger edge specified.\n");
-			return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-		}
-		break;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		switch (trigger->iAcqStartTrigEdge) {
-		case ME_TRIG_EDGE_ANY:
-		case ME_TRIG_EDGE_RISING:
-		case ME_TRIG_EDGE_FALLING:
-			break;
-
-		default:
-			PERROR
-			    ("Invalid acquisition start trigger edge specified.\n");
-			return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-		}
-		break;
-
-	default:
-		PERROR("Invalid acquisition start trigger type specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
-	}
-
-	if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) {
-		PERROR("Invalid scan start trigger type specified.\n");
-		return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-	}
-
-	if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) {
-		PERROR("Invalid conv start trigger type specified.\n");
-		return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-	}
-
-	if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS)
-	    || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) {
-		PERROR("Invalid conv start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_CONV_START_ARG;
-	}
-
-	if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) {
-		PERROR("Invalid acq start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_ARG;
-	}
-
-	if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) {
-		PERROR("Invalid scan start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_SCAN_START_ARG;
-	}
-
-	switch (trigger->iScanStopTrigType) {
-	case ME_TRIG_TYPE_NONE:
-		if (trigger->iScanStopCount != 0) {
-			PERROR("Invalid scan stop count specified.\n");
-			return ME_ERRNO_INVALID_SCAN_STOP_ARG;
-		}
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-			if (trigger->iScanStopCount <= 0) {
-				PERROR("Invalid scan stop count specified.\n");
-				return ME_ERRNO_INVALID_SCAN_STOP_ARG;
-			}
-		} else {
-			PERROR("The continous mode has not 'scan' contects.\n");
-			return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-		}
-		break;
-
-	default:
-		PERROR("Invalid scan stop trigger type specified.\n");
-		return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
-	}
-
-	switch (trigger->iAcqStopTrigType) {
-	case ME_TRIG_TYPE_NONE:
-		if (trigger->iAcqStopCount != 0) {
-			PERROR("Invalid acq stop count specified.\n");
-			return ME_ERRNO_INVALID_ACQ_STOP_ARG;
-		}
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
-			PERROR("Invalid acq stop trigger type specified.\n");
-			return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-		}
-
-		if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-			if (trigger->iAcqStopCount <= 0) {
-				PERROR
-				    ("The continous mode has not 'scan' contects.\n");
-				return ME_ERRNO_INVALID_ACQ_STOP_ARG;
-			}
-		}
-		break;
-
-	default:
-		PERROR("Invalid acq stop trigger type specified.\n");
-		return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-	}
-
-	switch (trigger->iAcqStartTrigChan) {
-	case ME_TRIG_CHAN_DEFAULT:
-	case ME_TRIG_CHAN_SYNCHRONOUS:
-		break;
-
-	default:
-		PERROR("Invalid acq start trigger channel specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if ((flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) && !instance->bitpattern) {
-		PERROR("This subdevice not support output redirection.\n");
-		ME_SUBDEVICE_EXIT;
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-	//Stop device
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-
-	//Check if state machine is stopped.
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	//Reset control register. Block all actions. Disable IRQ. Disable FIFO.
-	ctrl =
-	    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP |
-	    ME4600_AO_CTRL_BIT_RESET_IRQ;
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-
-	//This is paranoic, but to be sure.
-	instance->preloaded_count = 0;
-	instance->data_count = 0;
-	instance->circ_buf.head = 0;
-	instance->circ_buf.tail = 0;
-
-	/* Set mode. */
-	if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {	//Wraparound
-		if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {	//Hardware wraparound
-			PINFO("Hardware wraparound.\n");
-			ctrl |= ME4600_AO_MODE_WRAPAROUND;
-			instance->mode = ME4600_AO_HW_WRAP_MODE;
-		} else {	//Software wraparound
-			PINFO("Software wraparound.\n");
-			ctrl |= ME4600_AO_MODE_CONTINUOUS;
-			instance->mode = ME4600_AO_SW_WRAP_MODE;
-		}
-	} else {		//Continous
-		PINFO("Continous.\n");
-		ctrl |= ME4600_AO_MODE_CONTINUOUS;
-		instance->mode = ME4600_AO_CONTINOUS;
-	}
-
-	//Set the trigger edge.
-	if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) {	//Set the trigger type and edge for external trigger.
-		PINFO("External digital trigger.\n");
-		instance->start_mode = ME4600_AO_EXT_TRIG;
-/*
-			ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-*/
-		switch (trigger->iAcqStartTrigEdge) {
-		case ME_TRIG_EDGE_RISING:
-			PINFO("Set the trigger edge: rising.\n");
-			instance->ctrl_trg = 0x0;
-			break;
-
-		case ME_TRIG_EDGE_FALLING:
-			PINFO("Set the trigger edge: falling.\n");
-//                                      ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-			instance->ctrl_trg = ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-			break;
-
-		case ME_TRIG_EDGE_ANY:
-			PINFO("Set the trigger edge: both edges.\n");
-//                                      ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE | ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-			instance->ctrl_trg =
-			    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
-			    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-			break;
-		}
-	} else {
-		PINFO("Internal software trigger.\n");
-		instance->start_mode = 0;
-	}
-
-	//Set the stop mode and value.
-	if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) {	//Amount of data
-		instance->stop_mode = ME4600_AO_ACQ_STOP_MODE;
-		instance->stop_count = trigger->iAcqStopCount;
-	} else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) {	//Amount of 'scans'
-		instance->stop_mode = ME4600_AO_SCAN_STOP_MODE;
-		instance->stop_count = trigger->iScanStopCount;
-	} else {		//Infinite
-		instance->stop_mode = ME4600_AO_INF_STOP_MODE;
-		instance->stop_count = 0;
-	}
-
-	PINFO("Stop count: %d.\n", instance->stop_count);
-
-	if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) {	//Synchronous start
-		instance->start_mode |= ME4600_AO_SYNC_HOLD;
-		if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) {	//Externaly triggered
-			PINFO("Synchronous start. Externaly trigger active.\n");
-			instance->start_mode |= ME4600_AO_SYNC_EXT_TRIG;
-		}
-#ifdef MEDEBUG_INFO
-		else {
-			PINFO
-			    ("Synchronous start. Externaly trigger dissabled.\n");
-		}
-#endif
-
-	}
-	//Set speed
-	outl(conv_ticks - 2, instance->timer_reg);
-	PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base,
-		   instance->timer_reg - instance->reg_base, conv_ticks - 2);
-	instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME4600_AO_BASE_FREQUENCY;	//<== MUST be with cast!
-
-	//Conect outputs to analog or digital port.
-	if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) {
-		ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO;
-	}
-	// Write the control word
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-
-	//Set status.
-	instance->status = ao_status_stream_configured;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
-					  struct file *filep,
-					  int time_out, int *count, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	long j;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!instance->circ_buf.buf) {
-		PERROR("Circular buffer not exists.\n");
-		return ME_ERRNO_INTERNAL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (me_circ_buf_space(&instance->circ_buf)) {	//The buffer is NOT full.
-		*count = me_circ_buf_space(&instance->circ_buf);
-	} else {		//The buffer is full.
-		if (time_out) {
-			t = (time_out * HZ) / 1000;
-
-			if (t == 0)
-				t = 1;
-		} else {	//Max time.
-			t = LONG_MAX;
-		}
-
-		*count = 0;
-
-		j = jiffies;
-
-		//Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 ((me_circ_buf_space
-						   (&instance->circ_buf))
-						  || !(inl(instance->status_reg)
-						       &
-						       ME4600_AO_STATUS_BIT_FSM)),
-						 t);
-
-		if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
-			PERROR("AO subdevice is not running.\n");
-			err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-		} else if (signal_pending(current)) {
-			PERROR("Wait on values interrupted from signal.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		} else if ((jiffies - j) >= t) {
-			PERROR("Wait on values timed out.\n");
-			err = ME_ERRNO_TIMEOUT;
-		} else {	//Uff... all is good. Inform user about empty space.
-			*count = me_circ_buf_space(&instance->circ_buf);
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int start_mode, int time_out, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags = 0;
-	uint32_t status;
-	uint32_t ctrl;
-	uint32_t synch;
-	int count = 0;
-	int circ_buffer_count;
-
-	unsigned long ref;
-	unsigned long delay = 0;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
-		PERROR("Invalid flags.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if ((start_mode != ME_START_MODE_BLOCKING)
-	    && (start_mode != ME_START_MODE_NONBLOCKING)) {
-		PERROR("Invalid start mode specified.\n");
-		return ME_ERRNO_INVALID_START_MODE;
-	}
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-		if (delay == 0)
-			delay = 1;
-	}
-
-	switch (instance->status) {	//Checking actual mode.
-	case ao_status_stream_configured:
-	case ao_status_stream_end:
-		//Correct modes!
-		break;
-
-		//The device is in wrong mode.
-	case ao_status_none:
-	case ao_status_single_configured:
-	case ao_status_single_run_wait:
-	case ao_status_single_run:
-	case ao_status_single_end_wait:
-		PERROR
-		    ("Subdevice must be preinitialize correctly for streaming.\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-
-	case ao_status_stream_fifo_error:
-	case ao_status_stream_buffer_error:
-	case ao_status_stream_error:
-		PDEBUG("Before restart broke stream 'STOP' must be caled.\n");
-		return ME_STATUS_ERROR;
-
-	case ao_status_stream_run_wait:
-	case ao_status_stream_run:
-	case ao_status_stream_end_wait:
-		PDEBUG("Stream is already working.\n");
-		return ME_ERRNO_SUBDEVICE_BUSY;
-
-	default:
-		instance->status = ao_status_stream_error;
-		PERROR_CRITICAL("Status is in wrong state!\n");
-		return ME_ERRNO_INTERNAL;
-
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->mode == ME4600_AO_CONTINOUS) {	//Continous
-		instance->circ_buf.tail += instance->preloaded_count;
-		instance->circ_buf.tail &= instance->circ_buf.mask;
-	}
-	circ_buffer_count = me_circ_buf_values(&instance->circ_buf);
-
-	if (!circ_buffer_count && !instance->preloaded_count) {	//No values in buffer
-		ME_SUBDEVICE_EXIT;
-		PERROR("No values in buffer!\n");
-		return ME_ERRNO_LACK_OF_RESOURCES;
-	}
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-
-	//Stop device
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-	//Set values for single_read()
-	instance->single_value = ME4600_AO_MAX_DATA + 1;
-	instance->single_value_in_fifo = ME4600_AO_MAX_DATA + 1;
-
-	//Setting stop points
-	if (instance->stop_mode == ME4600_AO_SCAN_STOP_MODE) {
-		instance->stop_data_count =
-		    instance->stop_count * circ_buffer_count;
-	} else {
-		instance->stop_data_count = instance->stop_count;
-	}
-
-	if ((instance->stop_data_count != 0)
-	    && (instance->stop_data_count < circ_buffer_count)) {
-		PERROR("More data in buffer than previously set limit!\n");
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	ctrl = inl(instance->ctrl_reg);
-	//Check FIFO
-	if (!(ctrl & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) {	//FIFO wasn't enabeled. Do it. <= This should be done by user call with ME_WRITE_MODE_PRELOAD
-		PINFO("Enableing FIFO.\n");
-		ctrl |=
-		    ME4600_AO_CTRL_BIT_ENABLE_FIFO |
-		    ME4600_AO_CTRL_BIT_RESET_IRQ;
-
-		instance->preloaded_count = 0;
-		instance->data_count = 0;
-	} else {		//Block IRQ
-		ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-	}
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base,
-		   ctrl | ME4600_AO_CTRL_BIT_RESET_IRQ);
-
-	//Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it.
-	status = inl(instance->status_reg);
-	if (!(status & ME4600_AO_STATUS_BIT_EF)) {	//FIFO empty
-		if (instance->stop_data_count == 0) {
-			count = ME4600_AO_FIFO_COUNT;
-		} else {
-			count =
-			    (ME4600_AO_FIFO_COUNT <
-			     instance->
-			     stop_data_count) ? ME4600_AO_FIFO_COUNT :
-			    instance->stop_data_count;
-		}
-
-		//Copy data
-		count =
-		    ao_write_data(instance, count, instance->preloaded_count);
-
-		if (count < 0) {	//This should never happend!
-			PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-	}
-	//Set pre-load features.
-	spin_lock(instance->preload_reg_lock);
-	synch = inl(instance->preload_reg);
-	synch &=
-	    ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) << instance->
-	      ao_idx);
-	synch |=
-	    (instance->start_mode & ~ME4600_AO_EXT_TRIG) << instance->ao_idx;
-	outl(synch, instance->preload_reg);
-	PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, synch);
-	spin_unlock(instance->preload_reg_lock);
-
-	//Default count is '0'
-	if (instance->mode == ME4600_AO_CONTINOUS) {	//Continous
-		instance->preloaded_count = 0;
-		instance->circ_buf.tail += count;
-		instance->circ_buf.tail &= instance->circ_buf.mask;
-	} else {		//Wraparound
-		instance->preloaded_count += count;
-		instance->data_count += count;
-
-		//Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode.
-		if ((instance->stop_mode == ME4600_AO_INF_STOP_MODE)
-		    && (circ_buffer_count <= ME4600_AO_FIFO_COUNT)) {	//Change to hardware wraparound
-			PDEBUG
-			    ("Changeing mode from software wraparound to hardware wraparound.\n");
-			//Copy all data
-			count =
-			    ao_write_data(instance, circ_buffer_count,
-					  instance->preloaded_count);
-			ctrl &= ~ME4600_AO_CTRL_MODE_MASK;
-			ctrl |= ME4600_AO_MODE_WRAPAROUND;
-		}
-
-		if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) {	//Reset position indicator.
-			instance->preloaded_count = 0;
-		} else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) {	//This should never happend!
-			PERROR_CRITICAL
-			    ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-	}
-
-	//Set status to 'wait for start'
-	instance->status = ao_status_stream_run_wait;
-
-	status = inl(instance->status_reg);
-	//Start state machine and interrupts
-	ctrl &= ~(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-	if (instance->start_mode == ME4600_AO_EXT_TRIG) {	// External trigger.
-		PINFO("External trigger.\n");
-		ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-	}
-	if (!(status & ME4600_AO_STATUS_BIT_HF)) {	//More than half!
-		if ((ctrl & ME4600_AO_CTRL_MODE_MASK) == ME4600_AO_MODE_CONTINUOUS) {	//Enable IRQ only when hardware_continous is set and FIFO is more than half
-			ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-			ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-		}
-	}
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	//Trigger output
-	if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {	//Trigger outputs
-		spin_lock(instance->preload_reg_lock);
-		synch = inl(instance->preload_reg);
-		//Add channel to start list
-		outl(synch | (ME4600_AO_SYNC_HOLD << instance->ao_idx),
-		     instance->preload_reg);
-		PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->preload_reg - instance->reg_base,
-			   synch | (ME4600_AO_SYNC_HOLD << instance->ao_idx));
-
-		//Fire
-		PINFO
-		    ("Fired all software synchronous outputs by software trigger.\n");
-		outl(0x8000, instance->single_reg);
-		PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->single_reg - instance->reg_base, 0x8000);
-
-		//Restore save settings
-		outl(synch, instance->preload_reg);
-		PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->preload_reg - instance->reg_base, synch);
-		spin_unlock(instance->preload_reg_lock);
-	} else if (!instance->start_mode) {	//Trigger outputs
-/*
-		//Remove channel from start list.	// <== Unnecessary. Removed.
-		spin_lock(instance->preload_reg_lock);
-			synch = inl(instance->preload_reg);
-			outl(synch & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch & ~(ME4600_AO_SYNC_HOLD << instance->ao_idx));
-*/
-		//Fire
-		PINFO("Software trigger.\n");
-		outl(0x8000, instance->single_reg);
-		PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->single_reg - instance->reg_base, 0x8000);
-
-/*
-			//Restore save settings.	// <== Unnecessary. Removed.
-			outl(synch, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch);
-		spin_unlock(instance->preload_reg_lock);
-*/
-	}
-	// Set control task's timeout
-	ref = jiffies;
-	instance->timeout.delay = delay;
-	instance->timeout.start_time = ref;
-
-	if (status & ME4600_AO_STATUS_BIT_HF) {	//Less than half but not empty!
-		PINFO("Less than half.\n");
-		if (instance->stop_data_count != 0) {
-			count = ME4600_AO_FIFO_COUNT / 2;
-		} else {
-			count =
-			    ((ME4600_AO_FIFO_COUNT / 2) <
-			     instance->stop_data_count) ? ME4600_AO_FIFO_COUNT /
-			    2 : instance->stop_data_count;
-		}
-
-		//Copy data
-		count =
-		    ao_write_data(instance, count, instance->preloaded_count);
-
-		if (count < 0) {	//This should never happend!
-			PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-
-		if (instance->mode == ME4600_AO_CONTINOUS) {	//Continous
-			instance->circ_buf.tail += count;
-			instance->circ_buf.tail &= instance->circ_buf.mask;
-		} else {	//Wraparound
-			instance->data_count += count;
-			instance->preloaded_count += count;
-
-			if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) {	//Reset position indicator.
-				instance->preloaded_count = 0;
-			} else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) {	//This should never happend!
-				PERROR_CRITICAL
-				    ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
-				ME_SUBDEVICE_EXIT;
-				return ME_ERRNO_INTERNAL;
-			}
-		}
-
-		status = inl(instance->status_reg);
-		if (!(status & ME4600_AO_STATUS_BIT_HF)) {	//More than half!
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-			ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		}
-	}
-	//Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt.
-	if ((instance->stop_mode != ME4600_AO_INF_STOP_MODE)
-	    && (instance->mode == ME4600_AO_SW_WRAP_MODE)
-	    && (circ_buffer_count <= (ME4600_AO_FIFO_COUNT / 2))) {	//Put more data to FIFO
-		PINFO("Limited wraparound with less than HALF FIFO datas.\n");
-		if (instance->preloaded_count) {	//This should never happend!
-			PERROR_CRITICAL
-			    ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-
-		while (instance->stop_data_count > instance->data_count) {	//Maximum data not set jet.
-			//Copy to buffer
-			if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) {	//This should never happend!
-				PERROR_CRITICAL
-				    ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
-				ME_SUBDEVICE_EXIT;
-				return ME_ERRNO_INTERNAL;
-			}
-			instance->data_count += circ_buffer_count;
-
-			if (!((status = inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF)) {	//FIFO is more than half. Enable IRQ and end copy.
-				spin_lock_irqsave(&instance->subdevice_lock,
-						  cpu_flags);
-				ctrl = inl(instance->ctrl_reg);
-				ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-				ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-				outl(ctrl, instance->ctrl_reg);
-				PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->ctrl_reg -
-					   instance->reg_base, ctrl);
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				break;
-			}
-		}
-	}
-	// Schedule control task.
-	instance->ao_control_task_flag = 1;
-	queue_delayed_work(instance->me4600_workqueue,
-			   &instance->ao_control_task, 1);
-
-	if (start_mode == ME_START_MODE_BLOCKING) {	//Wait for start.
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_stream_run_wait),
-						 (delay) ? delay +
-						 1 : LONG_MAX);
-
-		if ((instance->status != ao_status_stream_run)
-		    && (instance->status != ao_status_stream_end)) {
-			PDEBUG("Starting stream canceled. %d\n",
-			       instance->status);
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		} else if ((delay) && ((jiffies - ref) >= delay)) {
-			if (instance->status != ao_status_stream_run) {
-				if (instance->status == ao_status_stream_end) {
-					PDEBUG("Timeout reached.\n");
-				} else {
-					if ((jiffies - ref) > delay) {
-						PERROR
-						    ("Timeout reached. Not handled by control task!\n");
-					} else {
-						PERROR
-						    ("Timeout reached. Signal come but status is strange: %d\n",
-						     instance->status);
-					}
-					ao_stop_immediately(instance);
-				}
-
-				instance->ao_control_task_flag = 0;
-				cancel_delayed_work(&instance->ao_control_task);
-				instance->status = ao_status_stream_end;
-				err = ME_ERRNO_TIMEOUT;
-			}
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-	return err;
-}
-
-static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int wait,
-				      int *status, int *values, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) {
-		PERROR("Invalid wait argument specified.\n");
-		*status = ME_STATUS_INVALID;
-		return ME_ERRNO_INVALID_WAIT;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	switch (instance->status) {
-	case ao_status_single_configured:
-	case ao_status_single_end:
-	case ao_status_stream_configured:
-	case ao_status_stream_end:
-	case ao_status_stream_fifo_error:
-	case ao_status_stream_buffer_error:
-	case ao_status_stream_error:
-		*status = ME_STATUS_IDLE;
-		break;
-
-	case ao_status_single_run_wait:
-	case ao_status_single_run:
-	case ao_status_single_end_wait:
-	case ao_status_stream_run_wait:
-	case ao_status_stream_run:
-	case ao_status_stream_end_wait:
-		*status = ME_STATUS_BUSY;
-		break;
-
-	case ao_status_none:
-	default:
-		*status =
-		    (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ?
-		    ME_STATUS_BUSY : ME_STATUS_IDLE;
-		break;
-	}
-
-	if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 ((instance->status !=
-						   ao_status_single_run_wait)
-						  && (instance->status !=
-						      ao_status_single_run)
-						  && (instance->status !=
-						      ao_status_single_end_wait)
-						  && (instance->status !=
-						      ao_status_stream_run_wait)
-						  && (instance->status !=
-						      ao_status_stream_run)
-						  && (instance->status !=
-						      ao_status_stream_end_wait)),
-						 LONG_MAX);
-
-		if (instance->status != ao_status_stream_end) {
-			PDEBUG("Wait for IDLE canceled. %d\n",
-			       instance->status);
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait for IDLE interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		*status = ME_STATUS_IDLE;
-	}
-
-	*values = me_circ_buf_space(&instance->circ_buf);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-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
-	int err = ME_ERRNO_SUCCESS;
-	me4600_ao_subdevice_t *instance;
-	unsigned long cpu_flags;
-	volatile uint32_t ctrl;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
-	    && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
-		PERROR("Invalid stop mode specified.\n");
-		return ME_ERRNO_INVALID_STOP_MODE;
-	}
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (instance->status < ao_status_stream_configured) {
-		//There is nothing to stop!
-		PERROR("Subdevice not in streaming mode. %d\n",
-		       instance->status);
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	//Mark as stopping. => Software stop.
-	instance->status = ao_status_stream_end_wait;
-
-	if (stop_mode == ME_STOP_MODE_IMMEDIATE) {	//Stopped now!
-		err = ao_stop_immediately(instance);
-	} else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
-		ctrl = inl(instance->ctrl_reg) & ME4600_AO_CTRL_MODE_MASK;
-		if (ctrl == ME4600_AO_MODE_WRAPAROUND) {	//Hardware wraparound => Hardware stop.
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |=
-			    ME4600_AO_CTRL_BIT_STOP |
-			    ME4600_AO_CTRL_BIT_RESET_IRQ;
-			ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		}
-		//Only runing process will interrupt this call. Events are signaled when status change.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_stream_end_wait),
-						 LONG_MAX);
-
-		if (instance->status != ao_status_stream_end) {
-			PDEBUG("Stopping stream canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Stopping stream interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	ctrl = inl(instance->ctrl_reg);
-	ctrl |=
-	    ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
-	    ME4600_AO_CTRL_BIT_RESET_IRQ;
-	ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-	if (!flags) {		//Reset FIFO
-		ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
-	}
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	if (!flags) {		//Reset software buffer
-		instance->circ_buf.head = 0;
-		instance->circ_buf.tail = 0;
-		instance->preloaded_count = 0;
-		instance->data_count = 0;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int write_mode,
-				     int *values, int *count, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me4600_ao_subdevice_t *instance;
-	unsigned long cpu_flags = 0;
-	uint32_t reg_copy;
-
-	int copied_from_user = 0;
-	int left_to_copy_from_user = *count;
-
-	int copied_values;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	//Checking arguments
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (*count <= 0) {
-		PERROR("Invalid count of values specified.\n");
-		return ME_ERRNO_INVALID_VALUE_COUNT;
-	}
-
-	if (values == NULL) {
-		PERROR("Invalid address of values specified.\n");
-		return ME_ERRNO_INVALID_POINTER;
-	}
-
-	if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) {	//The device is in single mode.
-		PERROR
-		    ("Subdevice must be preinitialize correctly for streaming.\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-/// @note If no 'pre-load' is used. stream_start() will move data to FIFO.
-	switch (write_mode) {
-	case ME_WRITE_MODE_PRELOAD:
-
-		//Device must be stopped.
-		if ((instance->status != ao_status_stream_configured)
-		    && (instance->status != ao_status_stream_end)) {
-			PERROR
-			    ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
-			return ME_ERRNO_PREVIOUS_CONFIG;
-		}
-		break;
-	case ME_WRITE_MODE_NONBLOCKING:
-	case ME_WRITE_MODE_BLOCKING:
-		/// @note In blocking mode: When device is not runing and there is not enought space call will blocked up!
-		/// @note Some other thread must empty buffer by starting engine.
-		break;
-
-	default:
-		PERROR("Invalid write mode specified.\n");
-		return ME_ERRNO_INVALID_WRITE_MODE;
-	}
-
-	if (instance->mode & ME4600_AO_WRAP_MODE) {	//Wraparound mode. Device must be stopped.
-		if ((instance->status != ao_status_stream_configured)
-		    && (instance->status != ao_status_stream_end)) {
-			PERROR
-			    ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
-			return ME_ERRNO_INVALID_WRITE_MODE;
-		}
-	}
-
-	if ((instance->mode == ME4600_AO_HW_WRAP_MODE) && (write_mode != ME_WRITE_MODE_PRELOAD)) {	// hardware wrap_around mode.
-		//This is transparent for user.
-		PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n");
-		write_mode = ME_WRITE_MODE_PRELOAD;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (write_mode == ME_WRITE_MODE_PRELOAD) {	//Init enviroment - preload
-		spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-		reg_copy = inl(instance->ctrl_reg);
-		//Check FIFO
-		if (!(reg_copy & ME4600_AO_CTRL_BIT_ENABLE_FIFO)) {	//FIFO not active. Enable it.
-			reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
-			outl(reg_copy, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   reg_copy);
-			instance->preloaded_count = 0;
-		}
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	}
-
-	while (1) {
-		//Copy to buffer. This step is common for all modes.
-		copied_from_user =
-		    ao_get_data_from_user(instance, left_to_copy_from_user,
-					  values + (*count -
-						    left_to_copy_from_user));
-		left_to_copy_from_user -= copied_from_user;
-
-		reg_copy = inl(instance->status_reg);
-		if ((instance->status == ao_status_stream_run) && !(reg_copy & ME4600_AO_STATUS_BIT_FSM)) {	//BROKEN PIPE! The state machine is stoped but logical status show that should be working.
-			PERROR("Broken pipe in write.\n");
-			err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-			break;
-		}
-
-		if ((instance->status == ao_status_stream_run) && (instance->mode == ME4600_AO_CONTINOUS) && (reg_copy & ME4600_AO_STATUS_BIT_HF)) {	//Continous mode runing and data are below half!
-
-			// Block interrupts.
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			reg_copy = inl(instance->ctrl_reg);
-			//reg_copy &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			reg_copy |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-			outl(reg_copy, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   reg_copy);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			//Fast copy
-			copied_values =
-			    ao_write_data(instance, ME4600_AO_FIFO_COUNT / 2,
-					  0);
-			if (copied_values > 0) {
-				instance->circ_buf.tail += copied_values;
-				instance->circ_buf.tail &=
-				    instance->circ_buf.mask;
-				continue;
-			}
-			// Activate interrupts.
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			reg_copy = inl(instance->ctrl_reg);
-			//reg_copy |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			reg_copy &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-			outl(reg_copy, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   reg_copy);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if (copied_values == 0) {	//This was checked and never should happend!
-				PERROR_CRITICAL("COPING FINISH WITH 0!\n");
-			}
-
-			if (copied_values < 0) {	//This was checked and never should happend!
-				PERROR_CRITICAL
-				    ("COPING FINISH WITH AN ERROR!\n");
-				instance->status = ao_status_stream_fifo_error;
-				err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-				break;
-			}
-		}
-
-		if (!left_to_copy_from_user) {	//All datas were copied.
-			break;
-		} else {	//Not all datas were copied.
-			if (instance->mode & ME4600_AO_WRAP_MODE) {	//Error too much datas! Wraparound is limited in size!
-				PERROR
-				    ("Too much data for wraparound mode!  Exceeded size of %ld.\n",
-				     ME4600_AO_CIRC_BUF_COUNT - 1);
-				err = ME_ERRNO_RING_BUFFER_OVERFLOW;
-				break;
-			}
-
-			if (write_mode != ME_WRITE_MODE_BLOCKING) {	//Non blocking calls
-				break;
-			}
-
-			wait_event_interruptible(instance->wait_queue,
-						 me_circ_buf_space(&instance->
-								   circ_buf));
-
-			if (signal_pending(current)) {
-				PERROR("Writing interrupted by signal.\n");
-				instance->status = ao_status_none;
-				ao_stop_immediately(instance);
-				err = ME_ERRNO_SIGNAL;
-				break;
-			}
-
-			if (instance->status == ao_status_none) {	//Reset
-				PERROR("Writing interrupted by reset.\n");
-				err = ME_ERRNO_CANCELLED;
-				break;
-			}
-		}
-	}
-
-	if (write_mode == ME_WRITE_MODE_PRELOAD) {	//Copy data to FIFO - preload
-		copied_values =
-		    ao_write_data_pooling(instance, ME4600_AO_FIFO_COUNT,
-					  instance->preloaded_count);
-		instance->preloaded_count += copied_values;
-		instance->data_count += copied_values;
-
-		if ((instance->mode == ME4600_AO_HW_WRAP_MODE)
-		    && (me_circ_buf_values(&instance->circ_buf) >
-			ME4600_AO_FIFO_COUNT)) {
-			PERROR
-			    ("Too much data for hardware wraparound mode! Exceeded size of %d.\n",
-			     ME4600_AO_FIFO_COUNT);
-			err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-		}
-	}
-
-	*count = *count - left_to_copy_from_user;
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
-{
-	me4600_ao_subdevice_t *instance = dev_id;
-	uint32_t irq_status;
-	uint32_t ctrl;
-	uint32_t status;
-	int count = 0;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	irq_status = inl(instance->irq_status_reg);
-	if (!(irq_status & (ME4600_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) {
-		PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n",
-		      jiffies, __func__, instance->ao_idx, irq_status);
-		return IRQ_NONE;
-	}
-
-	if (!instance->circ_buf.buf) {
-		instance->status = ao_status_stream_error;
-		PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
-		//Block interrupts. Stop machine.
-		ctrl = inl(instance->ctrl_reg);
-		ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-		ctrl |=
-		    ME4600_AO_CTRL_BIT_RESET_IRQ |
-		    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		//Inform user
-		wake_up_interruptible_all(&instance->wait_queue);
-		return IRQ_HANDLED;
-	}
-
-	status = inl(instance->status_reg);
-	if (!(status & ME4600_AO_STATUS_BIT_FSM)) {	//Too late. Not working! END? BROKEN PIPE?
-		PDEBUG("Interrupt come but ISM is not working!\n");
-		//Block interrupts. Stop machine.
-		ctrl = inl(instance->ctrl_reg);
-		ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-		ctrl |=
-		    ME4600_AO_CTRL_BIT_RESET_IRQ | ME4600_AO_CTRL_BIT_STOP |
-		    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		return IRQ_HANDLED;
-	}
-	//General procedure. Process more datas.
-
-#ifdef MEDEBUG_DEBUG
-	if (!me_circ_buf_values(&instance->circ_buf)) {	//Buffer is empty!
-		PDEBUG("Circular buffer empty!\n");
-	}
-#endif
-
-	//Check FIFO
-	if (status & ME4600_AO_STATUS_BIT_HF) {	//OK less than half
-
-		//Block interrupts
-		ctrl = inl(instance->ctrl_reg);
-		ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-		ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		do {
-			//Calculate how many should be copied.
-			count =
-			    (instance->stop_data_count) ? instance->
-			    stop_data_count -
-			    instance->data_count : ME4600_AO_FIFO_COUNT / 2;
-			if (ME4600_AO_FIFO_COUNT / 2 < count) {
-				count = ME4600_AO_FIFO_COUNT / 2;
-			}
-			//Copy data
-			if (instance->mode == ME4600_AO_CONTINOUS) {	//Continous
-				count = ao_write_data(instance, count, 0);
-				if (count > 0) {
-					instance->circ_buf.tail += count;
-					instance->circ_buf.tail &=
-					    instance->circ_buf.mask;
-					instance->data_count += count;
-
-					if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) {	//Stoping. Whole buffer was copied.
-						break;
-					}
-				}
-			} else if ((instance->mode == ME4600_AO_SW_WRAP_MODE) && ((ctrl & ME4600_AO_CTRL_MODE_MASK) == ME4600_AO_MODE_CONTINUOUS)) {	//Wraparound (software)
-				if (instance->status == ao_status_stream_end_wait) {	//We stoping => Copy to the end of the buffer.
-					count =
-					    ao_write_data(instance, count, 0);
-				} else {	//Copy in wraparound mode.
-					count =
-					    ao_write_data_wraparound(instance,
-								     count,
-								     instance->
-								     preloaded_count);
-				}
-
-				if (count > 0) {
-					instance->data_count += count;
-					instance->preloaded_count += count;
-					instance->preloaded_count %=
-					    me_circ_buf_values(&instance->
-							       circ_buf);
-
-					if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) {	//Stoping. Whole buffer was copied.
-						break;
-					}
-				}
-			}
-
-			if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) {	//End of work.
-				break;
-			}
-		}		//Repeat if still is under half fifo
-		while ((status =
-			inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_HF);
-
-		//Unblock interrupts
-		ctrl = inl(instance->ctrl_reg);
-		if (count >= 0) {	//Copy was successful.
-			if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) {	//Finishing work. No more interrupts.
-				PDEBUG("Finishing work. Interrupt disabled.\n");
-				instance->status = ao_status_stream_end_wait;
-			} else if (count > 0) {	//Normal work. Enable interrupt.
-				PDEBUG("Normal work. Enable interrupt.\n");
-				ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-				ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			} else {	//Normal work but there are no more data in buffer. Interrupt active but blocked. stream_write() will unblock it.
-				PDEBUG
-				    ("No data in software buffer. Interrupt blocked.\n");
-				ctrl |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			}
-		} else {	//Error during copy.
-			instance->status = ao_status_stream_fifo_error;
-		}
-
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-	} else {		//?? more than half
-		PDEBUG
-		    ("Interrupt come but FIFO more than half full! Reset interrupt.\n");
-		//Reset pending interrupt
-		ctrl = inl(instance->ctrl_reg);
-		ctrl |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		ctrl &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-	}
-
-	PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n",
-	      me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail,
-	      instance->circ_buf.head);
-	PINFO("ISR: Stop count: %d.\n", instance->stop_count);
-	PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count);
-	PINFO("ISR: Data count: %d.\n", instance->data_count);
-
-	//Inform user
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-static void me4600_ao_destructor(struct me_subdevice *subdevice)
-{
-	me4600_ao_subdevice_t *instance;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	instance->ao_control_task_flag = 0;
-
-	// Reset subdevice to asure clean exit.
-	me4600_ao_io_reset_subdevice(subdevice, NULL,
-				     ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
-	// Remove any tasks from work queue. This is paranoic because it was done allready in reset().
-	if (!cancel_delayed_work(&instance->ao_control_task)) {	//Wait 2 ticks to be sure that control task is removed from queue.
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(2);
-	}
-
-	if (instance->fifo) {
-		if (instance->irq) {
-			free_irq(instance->irq, instance);
-			instance->irq = 0;
-		}
-
-		if (instance->circ_buf.buf) {
-			free_pages((unsigned long)instance->circ_buf.buf,
-				   ME4600_AO_CIRC_BUF_SIZE_ORDER);
-		}
-		instance->circ_buf.buf = NULL;
-	}
-
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
-					     spinlock_t *preload_reg_lock,
-					     uint32_t *preload_flags,
-					     int ao_idx,
-					     int fifo,
-					     int irq,
-					     struct workqueue_struct *me4600_wq)
-{
-	me4600_ao_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed. idx=%d\n", ao_idx);
-
-	// Allocate memory for subdevice instance.
-	subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me4600_ao_subdevice_t));
-
-	// Initialize subdevice base class.
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->preload_reg_lock = preload_reg_lock;
-	subdevice->preload_flags = preload_flags;
-
-	// Store analog output index.
-	subdevice->ao_idx = ao_idx;
-
-	// Store if analog output has fifo.
-	subdevice->fifo = (ao_idx < fifo) ? 1 : 0;
-
-	if (subdevice->fifo) {	// Allocate and initialize circular buffer.
-		subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1;
-
-		subdevice->circ_buf.buf =
-		    (void *)__get_free_pages(GFP_KERNEL,
-					     ME4600_AO_CIRC_BUF_SIZE_ORDER);
-		PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
-		       ME4600_AO_CIRC_BUF_SIZE);
-
-		if (!subdevice->circ_buf.buf) {
-			PERROR
-			    ("Cannot initialize subdevice base class instance.\n");
-			kfree(subdevice);
-			return NULL;
-		}
-
-		memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE);
-	} else {		// No FIFO.
-		subdevice->circ_buf.mask = 0;
-		subdevice->circ_buf.buf = NULL;
-	}
-
-	subdevice->circ_buf.head = 0;
-	subdevice->circ_buf.tail = 0;
-
-	subdevice->status = ao_status_none;
-	subdevice->ao_control_task_flag = 0;
-	subdevice->timeout.delay = 0;
-	subdevice->timeout.start_time = jiffies;
-
-	// Initialize wait queue.
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	// Initialize single value to 0V.
-	subdevice->single_value = 0x8000;
-	subdevice->single_value_in_fifo = 0x8000;
-
-	// Register interrupt service routine.
-	if (subdevice->fifo) {
-		subdevice->irq = irq;
-		if (request_irq(subdevice->irq, me4600_ao_isr,
-				IRQF_DISABLED | IRQF_SHARED,
-				ME4600_NAME, subdevice)) {
-			PERROR("Cannot get interrupt line.\n");
-			PDEBUG("free circ_buf = %p size=%d",
-			       subdevice->circ_buf.buf,
-			       PAGE_SHIFT << ME4600_AO_CIRC_BUF_SIZE_ORDER);
-			free_pages((unsigned long)subdevice->circ_buf.buf,
-				   ME4600_AO_CIRC_BUF_SIZE_ORDER);
-			me_subdevice_deinit((me_subdevice_t *) subdevice);
-			kfree(subdevice);
-			return NULL;
-		}
-		PINFO("Registered irq=%d.\n", subdevice->irq);
-	} else {
-		subdevice->irq = 0;
-	}
-
-	// Initialize registers.
-	subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
-	subdevice->preload_reg = reg_base + ME4600_AO_SYNC_REG;
-	if (ao_idx == 0) {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG;
-		subdevice->reg_base = reg_base;
-		subdevice->bitpattern = 0;
-	} else if (ao_idx == 1) {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG;
-		subdevice->reg_base = reg_base;
-		subdevice->bitpattern = 0;
-	} else if (ao_idx == 2) {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG;
-		subdevice->reg_base = reg_base;
-		subdevice->bitpattern = 0;
-	} else if (ao_idx == 3) {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG;
-		subdevice->reg_base = reg_base;
-		subdevice->bitpattern = 1;
-	} else {
-		PERROR_CRITICAL("WRONG SUBDEVICE idx=%d!", ao_idx);
-		me_subdevice_deinit((me_subdevice_t *) subdevice);
-		if (subdevice->fifo) {
-			free_pages((unsigned long)subdevice->circ_buf.buf,
-				   ME4600_AO_CIRC_BUF_SIZE_ORDER);
-		}
-		subdevice->circ_buf.buf = NULL;
-		kfree(subdevice);
-		return NULL;
-	}
-
-	// Override base class methods.
-	subdevice->base.me_subdevice_destructor = me4600_ao_destructor;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me4600_ao_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me4600_ao_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me4600_ao_io_single_write;
-	subdevice->base.me_subdevice_io_stream_config =
-	    me4600_ao_io_stream_config;
-	subdevice->base.me_subdevice_io_stream_new_values =
-	    me4600_ao_io_stream_new_values;
-	subdevice->base.me_subdevice_io_stream_write =
-	    me4600_ao_io_stream_write;
-	subdevice->base.me_subdevice_io_stream_start =
-	    me4600_ao_io_stream_start;
-	subdevice->base.me_subdevice_io_stream_status =
-	    me4600_ao_io_stream_status;
-	subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me4600_ao_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me4600_ao_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me4600_ao_query_subdevice_caps;
-	subdevice->base.me_subdevice_query_subdevice_caps_args =
-	    me4600_ao_query_subdevice_caps_args;
-	subdevice->base.me_subdevice_query_range_by_min_max =
-	    me4600_ao_query_range_by_min_max;
-	subdevice->base.me_subdevice_query_number_ranges =
-	    me4600_ao_query_number_ranges;
-	subdevice->base.me_subdevice_query_range_info =
-	    me4600_ao_query_range_info;
-	subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer;
-
-	// Prepare work queue
-	subdevice->me4600_workqueue = me4600_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
-	INIT_DELAYED_WORK(&subdevice->ao_control_task,
-			  me4600_ao_work_control_task);
-
-	if (subdevice->fifo) {	// Set speed for single operations.
-		outl(ME4600_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
-		subdevice->hardware_stop_delay = HZ / 10;	//100ms
-	}
-
-	return subdevice;
-}
-
-/** @brief Stop presentation. Preserve FIFOs.
-*
-* @param instance The subdevice instance (pointer).
-*/
-inline int ao_stop_immediately(me4600_ao_subdevice_t *instance)
-{
-	unsigned long cpu_flags;
-	uint32_t ctrl;
-	int timeout;
-	int i;
-
-	timeout =
-	    (instance->hardware_stop_delay >
-	     (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10;
-	for (i = 0; i <= timeout; i++) {
-		spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-		// Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
-		ctrl = inl(instance->ctrl_reg);
-		ctrl |=
-		    ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
-		    | ME4600_AO_CTRL_BIT_RESET_IRQ;
-		ctrl &=
-		    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-		      ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-		if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {	// Exit.
-			break;
-		}
-		//Still working!
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
-	}
-
-	if (i > timeout) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		return ME_ERRNO_INTERNAL;
-	}
-	return ME_ERRNO_SUCCESS;
-}
-
-/** @brief Copy data from circular buffer to fifo (fast) in wraparound.
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0.	No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-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;
-	uint32_t value;
-	int pos =
-	    (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
-	int local_count = count;
-	int i = 1;
-
-	if (count <= 0) {	//Wrong count!
-		return 0;
-	}
-
-	while (i < local_count) {
-		//Get value from buffer
-		value = *(instance->circ_buf.buf + pos);
-		//Prepare it
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-
-		pos++;
-		pos &= instance->circ_buf.mask;
-		if (pos == instance->circ_buf.head) {
-			pos = instance->circ_buf.tail;
-		}
-		i++;
-	}
-
-	status = inl(instance->status_reg);
-	if (!(status & ME4600_AO_STATUS_BIT_FF)) {	//FIFO is full before all datas were copied!
-		PERROR("FIFO was full before all datas were copied! idx=%d\n",
-		       instance->ao_idx);
-		return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-	} else {		//Add last value
-		value = *(instance->circ_buf.buf + pos);
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-	}
-
-	PINFO("WRAPAROUND LOADED %d values. idx=%d\n", local_count,
-	      instance->ao_idx);
-	return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (fast).
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0.	No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
-			 int start_pos)
-{				/// @note This is time critical function!
-	uint32_t status;
-	uint32_t value;
-	int pos =
-	    (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
-	int local_count = count;
-	int max_count;
-	int i = 1;
-
-	if (count <= 0) {	//Wrong count!
-		return 0;
-	}
-
-	max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
-	if (max_count <= 0) {	//No data to copy!
-		return 0;
-	}
-
-	if (max_count < count) {
-		local_count = max_count;
-	}
-
-	while (i < local_count) {
-		//Get value from buffer
-		value = *(instance->circ_buf.buf + pos);
-		//Prepare it
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-
-		pos++;
-		pos &= instance->circ_buf.mask;
-		i++;
-	}
-
-	status = inl(instance->status_reg);
-	if (!(status & ME4600_AO_STATUS_BIT_FF)) {	//FIFO is full before all datas were copied!
-		PERROR("FIFO was full before all datas were copied! idx=%d\n",
-		       instance->ao_idx);
-		return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-	} else {		//Add last value
-		value = *(instance->circ_buf.buf + pos);
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-	}
-
-	PINFO("FAST LOADED %d values. idx=%d\n", local_count, instance->ao_idx);
-	return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (slow).
-* @note This is slow function that copy all data from buffer to FIFO with full control.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied values.
-* @return On error/success: 0.	FIFO was full at begining.
-* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
-*/
-inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
-				 int start_pos)
-{				/// @note This is slow function!
-	uint32_t status;
-	uint32_t value;
-	int pos =
-	    (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
-	int local_count = count;
-	int i;
-	int max_count;
-
-	if (count <= 0) {	//Wrong count!
-		PERROR("SLOW LOADED: Wrong count! idx=%d\n", instance->ao_idx);
-		return 0;
-	}
-
-	max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
-	if (max_count <= 0) {	//No data to copy!
-		PERROR("SLOW LOADED: No data to copy! idx=%d\n",
-		       instance->ao_idx);
-		return 0;
-	}
-
-	if (max_count < count) {
-		local_count = max_count;
-	}
-
-	for (i = 0; i < local_count; i++) {
-		status = inl(instance->status_reg);
-		if (!(status & ME4600_AO_STATUS_BIT_FF)) {	//FIFO is full!
-			return i;
-		}
-		//Get value from buffer
-		value = *(instance->circ_buf.buf + pos);
-		//Prepare it
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-
-		pos++;
-		pos &= instance->circ_buf.mask;
-	}
-
-	PINFO("SLOW LOADED %d values. idx=%d\n", local_count, instance->ao_idx);
-	return local_count;
-}
-
-/** @brief Copy data from user space to circular buffer.
-* @param instance The subdevice instance (pointer).
-* @param count Number of datas in user space.
-* @param user_values Buffer's pointer.
-*
-* @return On success: Number of copied values.
-* @return On error: -ME_ERRNO_INTERNAL.
-*/
-inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
-				 int *user_values)
-{
-	int i, err;
-	int empty_space;
-	int copied;
-	int value;
-
-	empty_space = me_circ_buf_space(&instance->circ_buf);
-	//We have only this space free.
-	copied = (count < empty_space) ? count : empty_space;
-	for (i = 0; i < copied; i++) {	//Copy from user to buffer
-		if ((err = get_user(value, (int *)(user_values + i)))) {
-			PERROR
-			    ("BUFFER LOADED: get_user(0x%p) return an error: %d. idx=%d\n",
-			     user_values + i, err, instance->ao_idx);
-			return -ME_ERRNO_INTERNAL;
-		}
-		/// @note The analog output in me4600 series has size of 16 bits.
-		*(instance->circ_buf.buf + instance->circ_buf.head) =
-		    (uint16_t) value;
-		instance->circ_buf.head++;
-		instance->circ_buf.head &= instance->circ_buf.mask;
-	}
-
-	PINFO("BUFFER LOADED %d values. idx=%d\n", copied, instance->ao_idx);
-	return copied;
-}
-
-/** @brief Checking actual hardware and logical state.
-* @param instance The subdevice instance (pointer).
-*/
-static void me4600_ao_work_control_task(struct work_struct *work)
-{
-	me4600_ao_subdevice_t *instance;
-	unsigned long cpu_flags = 0;
-	uint32_t status;
-	uint32_t ctrl;
-	uint32_t synch;
-	int reschedule = 0;
-	int signaling = 0;
-
-	instance =
-	    container_of((void *)work, me4600_ao_subdevice_t, ao_control_task);
-	PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
-	      instance->ao_idx);
-
-	status = inl(instance->status_reg);
-	PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->status_reg - instance->reg_base, status);
-
-	switch (instance->status) {	// Checking actual mode.
-
-		// Not configured for work.
-	case ao_status_none:
-		break;
-
-		//This are stable modes. No need to do anything. (?)
-	case ao_status_single_configured:
-	case ao_status_stream_configured:
-	case ao_status_stream_fifo_error:
-	case ao_status_stream_buffer_error:
-	case ao_status_stream_error:
-		PERROR("Shouldn't be running!.\n");
-		break;
-
-	case ao_status_stream_end:
-		if (!instance->fifo) {
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-	case ao_status_single_end:
-		if (status & ME4600_AO_STATUS_BIT_FSM) {	// State machine is working but the status is set to end. Force stop.
-
-			// Wait for stop.
-			reschedule = 1;
-		}
-
-		spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-		// Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
-		ctrl = inl(instance->ctrl_reg);
-		ctrl |=
-		    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP | ME4600_AO_CTRL_BIT_STOP
-		    | ME4600_AO_CTRL_BIT_RESET_IRQ;
-		ctrl &=
-		    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-		      ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
-		ctrl &=
-		    ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
-		      ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-		break;
-
-		// Single modes
-	case ao_status_single_run_wait:
-	case ao_status_single_run:
-	case ao_status_single_end_wait:
-
-		if (!(status & ME4600_AO_STATUS_BIT_FSM)) {	// State machine is not working.
-			if (((instance->fifo)
-			     && (!(status & ME4600_AO_STATUS_BIT_EF)))
-			    || (!(instance->fifo))) {	// Single is in end state.
-				PDEBUG("Single call has been complited.\n");
-
-				// Set correct value for single_read();
-				instance->single_value =
-				    instance->single_value_in_fifo;
-
-				// Set status as 'ao_status_single_end'
-				instance->status = ao_status_single_end;
-
-				// Signal the end.
-				signaling = 1;
-				// Wait for stop ISM.
-				reschedule = 1;
-
-				break;
-			}
-		}
-		// Check timeout.
-		if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) {	// Timeout
-			PDEBUG("Timeout reached.\n");
-			// Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |=
-			    ME4600_AO_CTRL_BIT_STOP |
-			    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
-			    ME4600_AO_CTRL_BIT_RESET_IRQ;
-			ctrl &=
-			    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
-			/// Fix for timeout error.
-			ctrl &=
-			    ~(ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
-			      ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
-			if (instance->fifo) {	//Disabling FIFO
-				ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
-			}
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			spin_lock(instance->preload_reg_lock);
-			//Remove from synchronous start. Block triggering from this output.
-			synch = inl(instance->preload_reg);
-			synch &=
-			    ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
-			      instance->ao_idx);
-			if (!(instance->fifo)) {	// No FIFO - set to single safe mode
-				synch |=
-				    ME4600_AO_SYNC_HOLD << instance->ao_idx;
-			}
-			outl(synch, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   synch);
-			spin_unlock(instance->preload_reg_lock);
-
-			if (!(instance->fifo)) {	// No FIFO
-				// Restore old settings.
-				PDEBUG("Write old value back to register.\n");
-				outl(instance->single_value,
-				     instance->single_reg);
-				PDEBUG_REG
-				    ("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->single_reg - instance->reg_base,
-				     instance->single_value);
-			}
-			// Set correct value for single_read();
-			instance->single_value_in_fifo = instance->single_value;
-
-			instance->status = ao_status_single_end;
-
-			// Signal the end.
-			signaling = 1;
-		}
-		// Wait for stop.
-		reschedule = 1;
-		break;
-
-		// Stream modes
-	case ao_status_stream_run_wait:
-		if (!instance->fifo) {
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-
-		if (status & ME4600_AO_STATUS_BIT_FSM) {	// State machine is working. Waiting for start finish.
-			instance->status = ao_status_stream_run;
-
-			// Signal end of this step
-			signaling = 1;
-		} else {	// State machine is not working.
-			if (!(status & ME4600_AO_STATUS_BIT_EF)) {	// FIFO is empty. Procedure has started and finish already!
-				instance->status = ao_status_stream_end;
-
-				// Signal the end.
-				signaling = 1;
-				// Wait for stop.
-				reschedule = 1;
-				break;
-			}
-		}
-
-		// Check timeout.
-		if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) {	// Timeout
-			PDEBUG("Timeout reached.\n");
-			// Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |=
-			    ME4600_AO_CTRL_BIT_STOP |
-			    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP |
-			    ME4600_AO_CTRL_BIT_RESET_IRQ;
-			ctrl &=
-			    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-			spin_lock(instance->preload_reg_lock);
-			//Remove from synchronous start. Block triggering from this output.
-			synch = inl(instance->preload_reg);
-			synch &=
-			    ~((ME4600_AO_SYNC_HOLD | ME4600_AO_SYNC_EXT_TRIG) <<
-			      instance->ao_idx);
-			outl(synch, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   synch);
-			spin_unlock(instance->preload_reg_lock);
-
-			instance->status = ao_status_stream_end;
-
-			// Signal the end.
-			signaling = 1;
-		}
-		// Wait for stop.
-		reschedule = 1;
-		break;
-
-	case ao_status_stream_run:
-		if (!instance->fifo) {
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-
-		if (!(status & ME4600_AO_STATUS_BIT_FSM)) {	// State machine is not working. This is an error.
-			// BROKEN PIPE!
-			if (!(status & ME4600_AO_STATUS_BIT_EF)) {	// FIFO is empty.
-				if (me_circ_buf_values(&instance->circ_buf)) {	// Software buffer is not empty.
-					if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) {	//Finishing work. Requed data shown.
-						PDEBUG
-						    ("ISM stoped. No data in FIFO. Buffer is not empty.\n");
-						instance->status =
-						    ao_status_stream_end;
-					} else {
-						PERROR
-						    ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n");
-						instance->status =
-						    ao_status_stream_buffer_error;
-					}
-				} else {	// Software buffer is empty.
-					PDEBUG
-					    ("ISM stoped. No data in FIFO. Buffer is empty.\n");
-					instance->status = ao_status_stream_end;
-				}
-			} else {	// There are still datas in FIFO.
-				if (me_circ_buf_values(&instance->circ_buf)) {	// Software buffer is not empty.
-					PERROR
-					    ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n");
-				} else {	// Software buffer is empty.
-					PERROR
-					    ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n");
-				}
-				instance->status = ao_status_stream_fifo_error;
-
-			}
-
-			// Signal the failure.
-			signaling = 1;
-			break;
-		}
-		// Wait for stop.
-		reschedule = 1;
-		break;
-
-	case ao_status_stream_end_wait:
-		if (!instance->fifo) {
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-
-		if (!(status & ME4600_AO_STATUS_BIT_FSM)) {	// State machine is not working. Waiting for stop finish.
-			instance->status = ao_status_stream_end;
-			signaling = 1;
-		}
-		// State machine is working.
-		reschedule = 1;
-		break;
-
-	default:
-		PERROR_CRITICAL("Status is in wrong state (%d)!\n",
-				instance->status);
-		instance->status = ao_status_stream_error;
-		// Signal the end.
-		signaling = 1;
-		break;
-
-	}
-
-	if (signaling) {	//Signal it.
-		wake_up_interruptible_all(&instance->wait_queue);
-	}
-
-	if (instance->ao_control_task_flag && reschedule) {	// Reschedule task
-		queue_delayed_work(instance->me4600_workqueue,
-				   &instance->ao_control_task, 1);
-	} else {
-		PINFO("<%s> Ending control task.\n", __func__);
-	}
-
-}
-#else
-/// @note SPECIAL BUILD FOR BOSCH
-/// @author Guenter Gebhardt
-static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
-					struct file *filep, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t tmp;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status);
-	spin_lock(instance->preload_reg_lock);
-	tmp = inl(instance->preload_reg);
-	tmp &= ~(0x10001 << instance->ao_idx);
-	outl(tmp, instance->preload_reg);
-	*instance->preload_flags &= ~(0x1 << instance->ao_idx);
-	spin_unlock(instance->preload_reg_lock);
-
-	tmp = inl(instance->ctrl_reg);
-	tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-	outl(tmp, instance->ctrl_reg);
-
-	while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
-
-	outl(ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP,
-	     instance->ctrl_reg);
-
-	outl(0x8000, instance->single_reg);
-
-	instance->single_value = 0x8000;
-	instance->circ_buf.head = 0;
-	instance->circ_buf.tail = 0;
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_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)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t tmp;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER
-	    spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	if (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) {
-		PERROR("Subdevice is busy.\n");
-		err = ME_ERRNO_SUBDEVICE_BUSY;
-		goto ERROR;
-	}
-
-	if (channel == 0) {
-		if (single_config == 0) {
-			if (ref == ME_REF_AO_GROUND) {
-				if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
-					if (trig_type == ME_TRIG_TYPE_SW) {
-						tmp = inl(instance->ctrl_reg);
-						tmp |=
-						    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-						outl(tmp, instance->ctrl_reg);
-						tmp =
-						    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-						outl(tmp, instance->ctrl_reg);
-
-						spin_lock(instance->
-							  preload_reg_lock);
-						tmp =
-						    inl(instance->preload_reg);
-						tmp &=
-						    ~(0x10001 << instance->
-						      ao_idx);
-						outl(tmp,
-						     instance->preload_reg);
-						*instance->preload_flags &=
-						    ~(0x1 << instance->ao_idx);
-						spin_unlock(instance->
-							    preload_reg_lock);
-					} else if (trig_type ==
-						   ME_TRIG_TYPE_EXT_DIGITAL) {
-						if (trig_edge ==
-						    ME_TRIG_EDGE_RISING) {
-							tmp =
-							    inl(instance->
-								ctrl_reg);
-							tmp |=
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-							tmp =
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
-							    |
-							    ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-						} else if (trig_edge ==
-							   ME_TRIG_EDGE_FALLING)
-						{
-							tmp =
-							    inl(instance->
-								ctrl_reg);
-							tmp |=
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-							tmp =
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
-							    |
-							    ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG
-							    |
-							    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-						} else if (trig_edge ==
-							   ME_TRIG_EDGE_ANY) {
-							tmp =
-							    inl(instance->
-								ctrl_reg);
-							tmp |=
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-							tmp =
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
-							    |
-							    ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG
-							    |
-							    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE
-							    |
-							    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-						} else {
-							PERROR
-							    ("Invalid trigger edge.\n");
-							err =
-							    ME_ERRNO_INVALID_TRIG_EDGE;
-							goto ERROR;
-						}
-
-						spin_lock(instance->
-							  preload_reg_lock);
-
-						tmp =
-						    inl(instance->preload_reg);
-						tmp &=
-						    ~(0x10001 << instance->
-						      ao_idx);
-						tmp |= 0x1 << instance->ao_idx;
-						outl(tmp,
-						     instance->preload_reg);
-						*instance->preload_flags &=
-						    ~(0x1 << instance->ao_idx);
-						spin_unlock(instance->
-							    preload_reg_lock);
-					} else {
-						PERROR
-						    ("Invalid trigger type.\n");
-						err =
-						    ME_ERRNO_INVALID_TRIG_TYPE;
-						goto ERROR;
-					}
-				} else if (trig_chan ==
-					   ME_TRIG_CHAN_SYNCHRONOUS) {
-					if (trig_type == ME_TRIG_TYPE_SW) {
-						tmp = inl(instance->ctrl_reg);
-						tmp |=
-						    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-						outl(tmp, instance->ctrl_reg);
-						tmp =
-						    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-						outl(tmp, instance->ctrl_reg);
-
-						spin_lock(instance->
-							  preload_reg_lock);
-						tmp =
-						    inl(instance->preload_reg);
-						tmp &=
-						    ~(0x10001 << instance->
-						      ao_idx);
-						tmp |= 0x1 << instance->ao_idx;
-						outl(tmp,
-						     instance->preload_reg);
-						*instance->preload_flags |=
-						    0x1 << instance->ao_idx;
-						spin_unlock(instance->
-							    preload_reg_lock);
-					} else if (trig_type ==
-						   ME_TRIG_TYPE_EXT_DIGITAL) {
-						if (trig_edge ==
-						    ME_TRIG_EDGE_RISING) {
-							tmp =
-							    inl(instance->
-								ctrl_reg);
-							tmp |=
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-							tmp =
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-						} else if (trig_edge ==
-							   ME_TRIG_EDGE_FALLING)
-						{
-							tmp =
-							    inl(instance->
-								ctrl_reg);
-							tmp |=
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-							tmp =
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
-							    |
-							    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-						} else if (trig_edge ==
-							   ME_TRIG_EDGE_ANY) {
-							tmp =
-							    inl(instance->
-								ctrl_reg);
-							tmp |=
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-							tmp =
-							    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP
-							    |
-							    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE
-							    |
-							    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-							outl(tmp,
-							     instance->
-							     ctrl_reg);
-						} else {
-							PERROR
-							    ("Invalid trigger edge.\n");
-							err =
-							    ME_ERRNO_INVALID_TRIG_EDGE;
-							goto ERROR;
-						}
-
-						spin_lock(instance->
-							  preload_reg_lock);
-
-						tmp =
-						    inl(instance->preload_reg);
-						tmp |=
-						    0x10001 << instance->ao_idx;
-						outl(tmp,
-						     instance->preload_reg);
-						*instance->preload_flags &=
-						    ~(0x1 << instance->ao_idx);
-						spin_unlock(instance->
-							    preload_reg_lock);
-					} else {
-						PERROR
-						    ("Invalid trigger type.\n");
-						err =
-						    ME_ERRNO_INVALID_TRIG_TYPE;
-						goto ERROR;
-					}
-				} else {
-					PERROR
-					    ("Invalid trigger channel specified.\n");
-					err = ME_ERRNO_INVALID_REF;
-					goto ERROR;
-				}
-			} else {
-				PERROR("Invalid analog reference specified.\n");
-				err = ME_ERRNO_INVALID_REF;
-				goto ERROR;
-			}
-		} else {
-			PERROR("Invalid single config specified.\n");
-			err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			goto ERROR;
-		}
-	} else {
-		PERROR("Invalid channel number specified.\n");
-		err = ME_ERRNO_INVALID_CHANNEL;
-		goto ERROR;
-	}
-
-ERROR:
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long tmp;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	if (channel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER
-	    spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	tmp = inl(instance->ctrl_reg);
-
-	if (tmp & 0x3) {
-		PERROR("Not in single mode.\n");
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-	} else {
-		*value = instance->single_value;
-	}
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long mask = 0;
-	unsigned long tmp;
-	unsigned long cpu_flags;
-	int i;
-	wait_queue_head_t queue;
-	unsigned long j;
-	unsigned long delay = 0;
-
-	PDEBUG("executed.\n");
-
-	init_waitqueue_head(&queue);
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	if (channel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-
-		if (delay == 0)
-			delay = 1;
-	}
-
-	ME_SUBDEVICE_ENTER
-	    spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	tmp = inl(instance->ctrl_reg);
-
-	if (tmp & 0x3) {
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-		PERROR("Not in single mode.\n");
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-		goto ERROR;
-	}
-
-	if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) {
-		outl(value, instance->single_reg);
-		instance->single_value = value;
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-		if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-			j = jiffies;
-
-			while (inl(instance->status_reg) &
-			       ME4600_AO_STATUS_BIT_FSM) {
-				interruptible_sleep_on_timeout(&queue, 1);
-
-				if (signal_pending(current)) {
-					PERROR
-					    ("Wait on external trigger interrupted by signal.\n");
-					err = ME_ERRNO_SIGNAL;
-					goto ERROR;
-				}
-
-				if (delay && ((jiffies - j) > delay)) {
-					PERROR("Timeout reached.\n");
-					err = ME_ERRNO_TIMEOUT;
-					goto ERROR;
-				}
-			}
-		}
-	} else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx))
-		   == (0x10001 << instance->ao_idx)) {
-		if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {
-			tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-			outl(tmp, instance->ctrl_reg);
-			outl(value, instance->single_reg);
-			instance->single_value = value;
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-				j = jiffies;
-
-				while (inl(instance->status_reg) &
-				       ME4600_AO_STATUS_BIT_FSM) {
-					interruptible_sleep_on_timeout(&queue,
-								       1);
-
-					if (signal_pending(current)) {
-						PERROR
-						    ("Wait on external trigger interrupted by signal.\n");
-						err = ME_ERRNO_SIGNAL;
-						goto ERROR;
-					}
-
-					if (delay && ((jiffies - j) > delay)) {
-						PERROR("Timeout reached.\n");
-						err = ME_ERRNO_TIMEOUT;
-						goto ERROR;
-					}
-				}
-			}
-		} else {
-			outl(value, instance->single_reg);
-			instance->single_value = value;
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		}
-	} else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx))
-		   == (0x1 << instance->ao_idx)) {
-		outl(value, instance->single_reg);
-		instance->single_value = value;
-
-		PDEBUG("Synchronous SW, flags = 0x%X.\n", flags);
-
-		if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {
-			PDEBUG("Trigger synchronous SW.\n");
-			spin_lock(instance->preload_reg_lock);
-			tmp = inl(instance->preload_reg);
-
-			for (i = 0; i < ME4600_AO_MAX_SUBDEVICES; i++) {
-				if ((*instance->preload_flags & (0x1 << i))) {
-					if ((tmp & (0x10001 << i)) ==
-					    (0x1 << i)) {
-						mask |= 0x1 << i;
-					}
-				}
-			}
-
-			tmp &= ~(mask);
-
-			outl(tmp, instance->preload_reg);
-			spin_unlock(instance->preload_reg_lock);
-		}
-
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	} else {
-		outl(value, instance->single_reg);
-		instance->single_value = value;
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	}
-
-ERROR:
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      meIOStreamTrigger_t *trigger,
-				      int fifo_irq_threshold, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long ctrl;
-	unsigned long tmp;
-	unsigned long cpu_flags;
-	uint64_t conv_ticks;
-	unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
-	unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	conv_ticks =
-	    (uint64_t) conv_start_ticks_low +
-	    ((uint64_t) conv_start_ticks_high << 32);
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	ME_SUBDEVICE_ENTER
-	    spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	if ((inl(instance->status_reg)) & ME4600_AO_STATUS_BIT_FSM) {
-		PERROR("Subdevice is busy.\n");
-		err = ME_ERRNO_SUBDEVICE_BUSY;
-		goto ERROR;
-	}
-
-	ctrl = inl(instance->ctrl_reg);
-	ctrl |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-	outl(ctrl, instance->ctrl_reg);
-	ctrl = ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-	outl(ctrl, instance->ctrl_reg);
-
-	if (count != 1) {
-		PERROR("Invalid stream configuration list count specified.\n");
-		err = ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
-		goto ERROR;
-	}
-
-	if (config_list[0].iChannel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		err = ME_ERRNO_INVALID_CHANNEL;
-		goto ERROR;
-	}
-
-	if (config_list[0].iStreamConfig != 0) {
-		PERROR("Invalid stream config specified.\n");
-		err = ME_ERRNO_INVALID_STREAM_CONFIG;
-		goto ERROR;
-	}
-
-	if (config_list[0].iRef != ME_REF_AO_GROUND) {
-		PERROR("Invalid analog reference.\n");
-		err = ME_ERRNO_INVALID_REF;
-		goto ERROR;
-	}
-
-	if ((trigger->iAcqStartTicksLow != 0)
-	    || (trigger->iAcqStartTicksHigh != 0)) {
-		PERROR
-		    ("Invalid acquisition start trigger argument specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_START_ARG;
-		goto ERROR;
-	}
-
-	switch (trigger->iAcqStartTrigType) {
-
-	case ME_TRIG_TYPE_SW:
-		break;
-
-	case ME_TRIG_TYPE_EXT_DIGITAL:
-		ctrl |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-		switch (trigger->iAcqStartTrigEdge) {
-
-		case ME_TRIG_EDGE_RISING:
-			break;
-
-		case ME_TRIG_EDGE_FALLING:
-			ctrl |= ME4600_AO_CTRL_BIT_EX_TRIG_EDGE;
-
-			break;
-
-		case ME_TRIG_EDGE_ANY:
-			ctrl |=
-			    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE |
-			    ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-
-			break;
-
-		default:
-			PERROR
-			    ("Invalid acquisition start trigger edge specified.\n");
-
-			err = ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-
-			goto ERROR;
-
-			break;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid acquisition start trigger type specified.\n");
-
-		err = ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
-
-		goto ERROR;
-
-		break;
-	}
-
-	switch (trigger->iScanStartTrigType) {
-
-	case ME_TRIG_TYPE_FOLLOW:
-		break;
-
-	default:
-		PERROR("Invalid scan start trigger type specified.\n");
-
-		err = ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-
-		goto ERROR;
-
-		break;
-	}
-
-	switch (trigger->iConvStartTrigType) {
-
-	case ME_TRIG_TYPE_TIMER:
-		if ((conv_ticks < ME4600_AO_MIN_CHAN_TICKS)
-		    || (conv_ticks > ME4600_AO_MAX_CHAN_TICKS)) {
-			PERROR
-			    ("Invalid conv start trigger argument specified.\n");
-			err = ME_ERRNO_INVALID_CONV_START_ARG;
-			goto ERROR;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid conv start trigger type specified.\n");
-
-		err = ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-
-		goto ERROR;
-
-		break;
-	}
-
-	/* Preset to hardware wraparound mode */
-	instance->flags &= ~(ME4600_AO_FLAGS_SW_WRAP_MODE_MASK);
-
-	switch (trigger->iScanStopTrigType) {
-
-	case ME_TRIG_TYPE_NONE:
-		if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-			/* Set flags to indicate usage of software mode. */
-			instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_INF;
-			instance->wrap_count = 0;
-			instance->wrap_remaining = 0;
-		}
-
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-			if (trigger->iScanStopCount <= 0) {
-				PERROR("Invalid scan stop count specified.\n");
-				err = ME_ERRNO_INVALID_SCAN_STOP_ARG;
-				goto ERROR;
-			}
-
-			/* Set flags to indicate usage of software mode. */
-			instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN;
-			instance->wrap_count = trigger->iScanStopCount;
-			instance->wrap_remaining = trigger->iScanStopCount;
-		} else {
-			PERROR("Invalid scan stop trigger type specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-			goto ERROR;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid scan stop trigger type specified.\n");
-
-		err = ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
-
-		goto ERROR;
-
-		break;
-	}
-
-	switch (trigger->iAcqStopTrigType) {
-
-	case ME_TRIG_TYPE_NONE:
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
-			PERROR("Invalid acq stop trigger type specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-			goto ERROR;
-		}
-
-		if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-			if (trigger->iAcqStopCount <= 0) {
-				PERROR("Invalid acq stop count specified.\n");
-				err = ME_ERRNO_INVALID_ACQ_STOP_ARG;
-				goto ERROR;
-			}
-
-			/* Set flags to indicate usage of software mode. */
-			instance->flags |= ME4600_AO_FLAGS_SW_WRAP_MODE_FIN;
-			instance->wrap_count = trigger->iAcqStopCount;
-			instance->wrap_remaining = trigger->iAcqStopCount;
-		} else {
-			PERROR("Invalid acp stop trigger type specified.\n");
-			err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-			goto ERROR;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid acq stop trigger type specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-		goto ERROR;
-		break;
-	}
-
-	switch (trigger->iAcqStartTrigChan) {
-
-	case ME_TRIG_CHAN_DEFAULT:
-		spin_lock(instance->preload_reg_lock);
-		tmp = inl(instance->preload_reg);
-		tmp &= ~(0x10001 << instance->ao_idx);
-		outl(tmp, instance->preload_reg);
-		spin_unlock(instance->preload_reg_lock);
-
-		break;
-
-	case ME_TRIG_CHAN_SYNCHRONOUS:
-		if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW) {
-			spin_lock(instance->preload_reg_lock);
-			tmp = inl(instance->preload_reg);
-			tmp &= ~(0x10001 << instance->ao_idx);
-			outl(tmp, instance->preload_reg);
-			tmp |= 0x1 << instance->ao_idx;
-			outl(tmp, instance->preload_reg);
-			spin_unlock(instance->preload_reg_lock);
-		} else {
-			ctrl &= ~(ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG);
-			spin_lock(instance->preload_reg_lock);
-			tmp = inl(instance->preload_reg);
-			tmp &= ~(0x10001 << instance->ao_idx);
-			outl(tmp, instance->preload_reg);
-			tmp |= 0x10000 << instance->ao_idx;
-			outl(tmp, instance->preload_reg);
-			spin_unlock(instance->preload_reg_lock);
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid acq start trigger channel specified.\n");
-		err = ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
-		goto ERROR;
-
-		break;
-	}
-
-	outl(conv_ticks - 2, instance->timer_reg);
-
-	if (flags & ME_IO_STREAM_CONFIG_BIT_PATTERN) {
-		if (instance->ao_idx == 3) {
-			ctrl |= ME4600_AO_CTRL_BIT_ENABLE_DO;
-		} else {
-			err = ME_ERRNO_INVALID_FLAGS;
-			goto ERROR;
-		}
-	} else {
-		if (instance->ao_idx == 3) {
-			ctrl &= ~ME4600_AO_CTRL_BIT_ENABLE_DO;
-		}
-	}
-
-	/* Set hardware mode. */
-	if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-		ctrl |= ME4600_AO_CTRL_BIT_MODE_0;
-	} else {
-		ctrl |= ME4600_AO_CTRL_BIT_MODE_1;
-	}
-
-	PDEBUG("Preload word = 0x%X.\n", inl(instance->preload_reg));
-
-	PDEBUG("Ctrl word = 0x%lX.\n", ctrl);
-	outl(ctrl, instance->ctrl_reg);	// Write the control word
-
-ERROR:
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
-					  struct file *filep,
-					  int time_out, int *count, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	long j;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	}
-
-	*count = 0;
-
-	ME_SUBDEVICE_ENTER;
-
-	if (t) {
-		j = jiffies;
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 ((me_circ_buf_space
-						   (&instance->circ_buf))
-						  || !(inl(instance->status_reg)
-						       &
-						       ME4600_AO_STATUS_BIT_FSM)),
-						 t);
-
-		if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
-			PERROR("AO subdevice is not running.\n");
-			err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-		} else if (signal_pending(current)) {
-			PERROR("Wait on values interrupted from signal.\n");
-			err = ME_ERRNO_SIGNAL;
-		} else if ((jiffies - j) >= t) {
-			PERROR("Wait on values timed out.\n");
-			err = ME_ERRNO_TIMEOUT;
-		} else {
-			*count = me_circ_buf_space(&instance->circ_buf);
-		}
-	} else {
-		wait_event_interruptible(instance->wait_queue,
-					 ((me_circ_buf_space
-					   (&instance->circ_buf))
-					  || !(inl(instance->status_reg) &
-					       ME4600_AO_STATUS_BIT_FSM)));
-
-		if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
-			PERROR("AO subdevice is not running.\n");
-			err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-		} else if (signal_pending(current)) {
-			PERROR("Wait on values interrupted from signal.\n");
-			err = ME_ERRNO_SIGNAL;
-		} else {
-			*count = me_circ_buf_space(&instance->circ_buf);
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static void stop_immediately(me4600_ao_subdevice_t *instance)
-{
-	unsigned long cpu_flags;
-	uint32_t tmp;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	tmp = inl(instance->ctrl_reg);
-	tmp |= ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-	outl(tmp, instance->ctrl_reg);
-
-	while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-}
-
-static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int start_mode, int time_out, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags = 0;
-	unsigned long ref;
-	unsigned long tmp;
-	unsigned long delay = 0;
-	wait_queue_head_t queue;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	init_waitqueue_head(&queue);
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-
-		if (delay == 0)
-			delay = 1;
-	}
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	ME_SUBDEVICE_ENTER
-	    spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	tmp = inl(instance->ctrl_reg);
-
-	switch (tmp & (ME4600_AO_CTRL_MASK_MODE)) {
-
-	case 0:		// Single mode
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-		PERROR("Subdevice is configured in single mode.\n");
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-		goto ERROR;
-
-	case 1:		// Wraparound mode
-		if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) {	// Normal wraparound with external trigger
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp &=
-			    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME4600_AO_CTRL_BIT_STOP |
-			      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
-			outl(tmp, instance->ctrl_reg);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if (start_mode == ME_START_MODE_BLOCKING) {
-				init_waitqueue_head(&queue);
-
-				if (delay) {
-					ref = jiffies;
-
-					while (!
-					       (inl(instance->status_reg) &
-						ME4600_AO_STATUS_BIT_FSM)) {
-						interruptible_sleep_on_timeout
-						    (&queue, 1);
-
-						if (signal_pending(current)) {
-							PERROR
-							    ("Wait on start of state machine interrupted.\n");
-							stop_immediately
-							    (instance);
-							err = ME_ERRNO_SIGNAL;
-							goto ERROR;
-						}
-
-						if (((jiffies - ref) >= delay)) {
-							PERROR
-							    ("Timeout reached.\n");
-							stop_immediately
-							    (instance);
-							err = ME_ERRNO_TIMEOUT;
-							goto ERROR;
-						}
-					}
-				} else {
-					while (!
-					       (inl(instance->status_reg) &
-						ME4600_AO_STATUS_BIT_FSM)) {
-						interruptible_sleep_on_timeout
-						    (&queue, 1);
-
-						if (signal_pending(current)) {
-							PERROR
-							    ("Wait on start of state machine interrupted.\n");
-							stop_immediately
-							    (instance);
-							err = ME_ERRNO_SIGNAL;
-							goto ERROR;
-						}
-					}
-				}
-			} else if (start_mode == ME_START_MODE_NONBLOCKING) {
-			} else {
-				PERROR("Invalid start mode specified.\n");
-				err = ME_ERRNO_INVALID_START_MODE;
-				goto ERROR;
-			}
-		} else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) {	// Synchronous with external trigger
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
-				tmp |= ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG;
-				tmp &=
-				    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-				      ME4600_AO_CTRL_BIT_STOP |
-				      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-				outl(tmp, instance->ctrl_reg);
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-
-				if (start_mode == ME_START_MODE_BLOCKING) {
-					init_waitqueue_head(&queue);
-
-					if (delay) {
-						ref = jiffies;
-
-						while (!
-						       (inl
-							(instance->
-							 status_reg) &
-							ME4600_AO_STATUS_BIT_FSM))
-						{
-							interruptible_sleep_on_timeout
-							    (&queue, 1);
-
-							if (signal_pending
-							    (current)) {
-								PERROR
-								    ("Wait on start of state machine interrupted.\n");
-								stop_immediately
-								    (instance);
-								err =
-								    ME_ERRNO_SIGNAL;
-								goto ERROR;
-							}
-
-							if (((jiffies - ref) >=
-							     delay)) {
-								PERROR
-								    ("Timeout reached.\n");
-								stop_immediately
-								    (instance);
-								err =
-								    ME_ERRNO_TIMEOUT;
-								goto ERROR;
-							}
-						}
-					} else {
-						while (!
-						       (inl
-							(instance->
-							 status_reg) &
-							ME4600_AO_STATUS_BIT_FSM))
-						{
-							interruptible_sleep_on_timeout
-							    (&queue, 1);
-
-							if (signal_pending
-							    (current)) {
-								PERROR
-								    ("Wait on start of state machine interrupted.\n");
-								stop_immediately
-								    (instance);
-								err =
-								    ME_ERRNO_SIGNAL;
-								goto ERROR;
-							}
-						}
-					}
-				} else if (start_mode ==
-					   ME_START_MODE_NONBLOCKING) {
-				} else {
-					PERROR
-					    ("Invalid start mode specified.\n");
-					err = ME_ERRNO_INVALID_START_MODE;
-					goto ERROR;
-				}
-			} else {
-				tmp &=
-				    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-				      ME4600_AO_CTRL_BIT_STOP |
-				      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-				outl(tmp, instance->ctrl_reg);
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-			}
-		} else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) {	// Synchronous wraparound with sw trigger
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp &=
-			    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME4600_AO_CTRL_BIT_STOP |
-			      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
-			outl(tmp, instance->ctrl_reg);
-
-			if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
-				outl(0x8000, instance->single_reg);
-				instance->single_value = 0x8000;
-			}
-
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		} else {	// Software start
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp &=
-			    ~(ME4600_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME4600_AO_CTRL_BIT_STOP |
-			      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
-			outl(tmp, instance->ctrl_reg);
-
-			outl(0x8000, instance->single_reg);
-			instance->single_value = 0x8000;
-
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		}
-
-		break;
-
-	case 2:		// Continuous mode
-		if (tmp & ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG) {	// Externally triggered
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp &=
-			    ~(ME4600_AO_CTRL_BIT_STOP |
-			      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-			tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(tmp, instance->ctrl_reg);
-			instance->wrap_remaining = instance->wrap_count;
-			instance->circ_buf.tail = 0;
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if (start_mode == ME_START_MODE_BLOCKING) {
-				init_waitqueue_head(&queue);
-
-				if (delay) {
-					ref = jiffies;
-
-					while (!
-					       (inl(instance->status_reg) &
-						ME4600_AO_STATUS_BIT_FSM)) {
-						interruptible_sleep_on_timeout
-						    (&queue, 1);
-
-						if (signal_pending(current)) {
-							PERROR
-							    ("Wait on start of state machine interrupted.\n");
-							stop_immediately
-							    (instance);
-							err = ME_ERRNO_SIGNAL;
-							goto ERROR;
-						}
-
-						if (((jiffies - ref) >= delay)) {
-							PERROR
-							    ("Timeout reached.\n");
-							stop_immediately
-							    (instance);
-							err = ME_ERRNO_TIMEOUT;
-							goto ERROR;
-						}
-					}
-				} else {
-					while (!
-					       (inl(instance->status_reg) &
-						ME4600_AO_STATUS_BIT_FSM)) {
-						interruptible_sleep_on_timeout
-						    (&queue, 1);
-
-						if (signal_pending(current)) {
-							PERROR
-							    ("Wait on start of state machine interrupted.\n");
-							stop_immediately
-							    (instance);
-							err = ME_ERRNO_SIGNAL;
-							goto ERROR;
-						}
-					}
-				}
-			} else if (start_mode == ME_START_MODE_NONBLOCKING) {
-				/* Do nothing */
-			} else {
-				PERROR("Invalid start mode specified.\n");
-				stop_immediately(instance);
-				err = ME_ERRNO_INVALID_START_MODE;
-				goto ERROR;
-			}
-		} else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x10000 << instance->ao_idx)) {	// Synchronous with external trigger
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
-				tmp |=
-				    ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG |
-				    ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-				tmp &=
-				    ~(ME4600_AO_CTRL_BIT_STOP |
-				      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-				outl(tmp, instance->ctrl_reg);
-				instance->wrap_remaining = instance->wrap_count;
-				instance->circ_buf.tail = 0;
-
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-
-				if (start_mode == ME_START_MODE_BLOCKING) {
-					init_waitqueue_head(&queue);
-
-					if (delay) {
-						ref = jiffies;
-
-						while (!
-						       (inl
-							(instance->
-							 status_reg) &
-							ME4600_AO_STATUS_BIT_FSM))
-						{
-							interruptible_sleep_on_timeout
-							    (&queue, 1);
-
-							if (signal_pending
-							    (current)) {
-								PERROR
-								    ("Wait on start of state machine interrupted.\n");
-								stop_immediately
-								    (instance);
-								err =
-								    ME_ERRNO_SIGNAL;
-								goto ERROR;
-							}
-
-							if (((jiffies - ref) >=
-							     delay)) {
-								PERROR
-								    ("Timeout reached.\n");
-								stop_immediately
-								    (instance);
-								err =
-								    ME_ERRNO_TIMEOUT;
-								goto ERROR;
-							}
-						}
-					} else {
-						while (!
-						       (inl
-							(instance->
-							 status_reg) &
-							ME4600_AO_STATUS_BIT_FSM))
-						{
-							interruptible_sleep_on_timeout
-							    (&queue, 1);
-
-							if (signal_pending
-							    (current)) {
-								PERROR
-								    ("Wait on start of state machine interrupted.\n");
-								stop_immediately
-								    (instance);
-								err =
-								    ME_ERRNO_SIGNAL;
-								goto ERROR;
-							}
-						}
-					}
-				} else if (start_mode ==
-					   ME_START_MODE_NONBLOCKING) {
-				} else {
-					PERROR
-					    ("Invalid start mode specified.\n");
-					stop_immediately(instance);
-					err = ME_ERRNO_INVALID_START_MODE;
-					goto ERROR;
-				}
-			} else {
-				tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-				tmp &=
-				    ~(ME4600_AO_CTRL_BIT_STOP |
-				      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-				outl(tmp, instance->ctrl_reg);
-				instance->wrap_remaining = instance->wrap_count;
-				instance->circ_buf.tail = 0;
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-			}
-		} else if ((inl(instance->preload_reg) & (0x10001 << instance->ao_idx)) == (0x1 << instance->ao_idx)) {	// Synchronous wraparound with sw trigger
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp &=
-			    ~(ME4600_AO_CTRL_BIT_STOP |
-			      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-			tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			instance->wrap_remaining = instance->wrap_count;
-			instance->circ_buf.tail = 0;
-			PDEBUG("CTRL Reg = 0x%X.\n", inl(instance->ctrl_reg));
-			outl(tmp, instance->ctrl_reg);
-
-			if (flags & ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
-				outl(0x8000, instance->single_reg);
-				instance->single_value = 0x8000;
-			}
-
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		} else {	// Software start
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR("Conversion is already running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp &=
-			    ~(ME4600_AO_CTRL_BIT_STOP |
-			      ME4600_AO_CTRL_BIT_IMMEDIATE_STOP);
-
-			tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(tmp, instance->ctrl_reg);
-			outl(0x8000, instance->single_reg);
-			instance->single_value = 0x8000;
-			instance->wrap_remaining = instance->wrap_count;
-			instance->circ_buf.tail = 0;
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		}
-
-		break;
-
-	default:
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-		PERROR("Invalid mode configured.\n");
-		err = ME_ERRNO_INTERNAL;
-		goto ERROR;
-	}
-
-ERROR:
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int wait,
-				      int *status, int *values, int flags)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	wait_queue_head_t queue;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	init_waitqueue_head(&queue);
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (wait == ME_WAIT_NONE) {
-		*status =
-		    (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ?
-		    ME_STATUS_BUSY : ME_STATUS_IDLE;
-		*values = me_circ_buf_space(&instance->circ_buf);
-	} else if (wait == ME_WAIT_IDLE) {
-		while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) {
-			interruptible_sleep_on_timeout(&queue, 1);
-
-			if (instance->flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
-				PERROR("Output stream was interrupted.\n");
-				*status = ME_STATUS_ERROR;
-				err = ME_ERRNO_SUCCESS;
-				goto ERROR;
-			}
-
-			if (signal_pending(current)) {
-				PERROR
-				    ("Wait on state machine interrupted by signal.\n");
-				*status = ME_STATUS_INVALID;
-				err = ME_ERRNO_SIGNAL;
-				goto ERROR;
-			}
-		}
-
-		*status = ME_STATUS_IDLE;
-
-		*values = me_circ_buf_space(&instance->circ_buf);
-	} else {
-		PERROR("Invalid wait argument specified.\n");
-		*status = ME_STATUS_INVALID;
-		err = ME_ERRNO_INVALID_WAIT;
-		goto ERROR;
-	}
-
-ERROR:
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int stop_mode, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me4600_ao_subdevice_t *instance;
-	unsigned long cpu_flags;
-	unsigned long tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (stop_mode == ME_STOP_MODE_IMMEDIATE) {
-		spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-		tmp = inl(instance->ctrl_reg);
-		tmp |=
-		    ME4600_AO_CTRL_BIT_STOP | ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-		outl(tmp, instance->ctrl_reg);
-
-		while (inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM) ;
-
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	} else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
-		spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-		tmp = inl(instance->ctrl_reg);
-		tmp |= ME4600_AO_CTRL_BIT_STOP;
-		outl(tmp, instance->ctrl_reg);
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	} else {
-		PERROR("Invalid stop mode specified.\n");
-		err = ME_ERRNO_INVALID_STOP_MODE;
-		goto ERROR;
-	}
-
-ERROR:
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int write_mode,
-				     int *values, int *count, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me4600_ao_subdevice_t *instance;
-	unsigned long tmp;
-	int i;
-	int value;
-	int cnt = *count;
-	int c;
-	int k;
-	int ret = 0;
-	unsigned long cpu_flags = 0;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	if (!instance->fifo) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (*count <= 0) {
-		PERROR("Invalid count of values specified.\n");
-		err = ME_ERRNO_INVALID_VALUE_COUNT;
-		goto ERROR;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	tmp = inl(instance->ctrl_reg);
-
-	switch (tmp & 0x3) {
-
-	case 1:		// Wraparound mode
-		if (instance->bosch_fw) {	// Bosch firmware
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if (cnt != 7) {
-				PERROR
-				    ("Invalid count of values specified. 7 expected.\n");
-				err = ME_ERRNO_INVALID_VALUE_COUNT;
-				goto ERROR;
-			}
-
-			for (i = 0; i < 7; i++) {
-				if (get_user(value, values)) {
-					PERROR
-					    ("Can't copy value from user space.\n");
-					err = ME_ERRNO_INTERNAL;
-					goto ERROR;
-				}
-
-				if (i == 0) {
-					/* Maximum voltage */
-					value <<= 16;
-					value |=
-					    inl(instance->reg_base +
-						0xD4) & 0xFFFF;
-					outl(value, instance->reg_base + 0xD4);
-				} else if (i == 1) {
-					/* Minimum voltage */
-					value &= 0xFFFF;
-					value |=
-					    inl(instance->reg_base +
-						0xD4) & 0xFFFF0000;
-					outl(value, instance->reg_base + 0xD4);
-				} else if (i == 2) {
-					/* Delta up */
-					value <<= 16;
-					value |=
-					    inl(instance->reg_base +
-						0xD8) & 0xFFFF;
-					outl(value, instance->reg_base + 0xD8);
-				} else if (i == 3) {
-					/* Delta down */
-					value &= 0xFFFF;
-					value |=
-					    inl(instance->reg_base +
-						0xD8) & 0xFFFF0000;
-					outl(value, instance->reg_base + 0xD8);
-				} else if (i == 4) {
-					/* Start value */
-					outl(value, instance->reg_base + 0xDC);
-				} else if (i == 5) {
-					/* Invert */
-					if (value) {
-						value = inl(instance->ctrl_reg);
-						value |= 0x100;
-						outl(value, instance->ctrl_reg);
-					} else {
-						value = inl(instance->ctrl_reg);
-						value &= ~0x100;
-						outl(value, instance->ctrl_reg);
-					}
-				} else if (i == 6) {
-					/* Timer for positive ramp */
-					outl(value, instance->reg_base + 0xE0);
-				}
-
-				values++;
-			}
-		} else {	// Normal firmware
-			PDEBUG("Write for wraparound mode.\n");
-
-			if (inl(instance->status_reg) &
-			    ME4600_AO_STATUS_BIT_FSM) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR
-				    ("There is already a conversion running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp |= ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-			tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_FIFO;
-			outl(tmp, instance->ctrl_reg);
-			tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
-
-			if ((*count > ME4600_AO_FIFO_COUNT) ||
-			    ((instance->
-			      flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
-			     ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) {
-				tmp &=
-				    ~(ME4600_AO_CTRL_BIT_MODE_0 |
-				      ME4600_AO_CTRL_BIT_MODE_1);
-				tmp |= ME4600_AO_CTRL_BIT_MODE_1;
-			}
-
-			outl(tmp, instance->ctrl_reg);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if ((*count <= ME4600_AO_FIFO_COUNT) &&
-			    ((instance->
-			      flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
-			     ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) {
-				for (i = 0; i < *count; i++) {
-					if (get_user(value, values + i)) {
-						PERROR
-						    ("Cannot copy value from user space.\n");
-						err = ME_ERRNO_INTERNAL;
-						goto ERROR;
-					}
-
-					if (instance->ao_idx & 0x1)
-						value <<= 16;
-
-					outl(value, instance->fifo_reg);
-				}
-			} else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) &&
-				   ((instance->
-				     flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK)
-				    == ME4600_AO_FLAGS_SW_WRAP_MODE_INF)) {
-				for (i = 0; i < *count; i++) {
-					if (get_user(value, values + i)) {
-						PERROR
-						    ("Cannot copy value from user space.\n");
-						err = ME_ERRNO_INTERNAL;
-						goto ERROR;
-					}
-
-					instance->circ_buf.buf[i] = value;	/* Used to hold the values. */
-				}
-
-				instance->circ_buf.tail = 0;	/* Used as the current read position. */
-				instance->circ_buf.head = *count;	/* Used as the buffer size. */
-
-				/* Preload the FIFO. */
-
-				for (i = 0; i < ME4600_AO_FIFO_COUNT;
-				     i++, instance->circ_buf.tail++) {
-					if (instance->circ_buf.tail >=
-					    instance->circ_buf.head)
-						instance->circ_buf.tail = 0;
-
-					if (instance->ao_idx & 0x1)
-						outl(instance->circ_buf.
-						     buf[instance->circ_buf.
-							 tail] << 16,
-						     instance->fifo_reg);
-					else
-						outl(instance->circ_buf.
-						     buf[instance->circ_buf.
-							 tail],
-						     instance->fifo_reg);
-				}
-			} else if ((*count <= ME4600_AO_CIRC_BUF_COUNT) &&
-				   ((instance->
-				     flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK)
-				    == ME4600_AO_FLAGS_SW_WRAP_MODE_FIN)) {
-				unsigned int preload_count;
-
-				for (i = 0; i < *count; i++) {
-					if (get_user(value, values + i)) {
-						PERROR
-						    ("Cannot copy value from user space.\n");
-						err = ME_ERRNO_INTERNAL;
-						goto ERROR;
-					}
-
-					instance->circ_buf.buf[i] = value;	/* Used to hold the values. */
-				}
-
-				instance->circ_buf.tail = 0;	/* Used as the current read position. */
-				instance->circ_buf.head = *count;	/* Used as the buffer size. */
-
-				/* Try to preload the whole FIFO. */
-				preload_count = ME4600_AO_FIFO_COUNT;
-
-				if (preload_count > instance->wrap_count)
-					preload_count = instance->wrap_count;
-
-				/* Preload the FIFO. */
-				for (i = 0; i < preload_count;
-				     i++, instance->circ_buf.tail++) {
-					if (instance->circ_buf.tail >=
-					    instance->circ_buf.head)
-						instance->circ_buf.tail = 0;
-
-					if (instance->ao_idx & 0x1)
-						outl(instance->circ_buf.
-						     buf[instance->circ_buf.
-							 tail] << 16,
-						     instance->fifo_reg);
-					else
-						outl(instance->circ_buf.
-						     buf[instance->circ_buf.
-							 tail],
-						     instance->fifo_reg);
-				}
-
-				instance->wrap_remaining =
-				    instance->wrap_count - preload_count;
-			} else {
-				PERROR("To many values written.\n");
-				err = ME_ERRNO_INVALID_VALUE_COUNT;
-				goto ERROR;
-			}
-		}
-
-		break;
-
-	case 2:		// Continuous mode
-		/* Check if in SW wrapround mode */
-		if (instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) {
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-			PERROR("Subdevice is configured SW wrapround mode.\n");
-			err = ME_ERRNO_PREVIOUS_CONFIG;
-			goto ERROR;
-		}
-
-		switch (write_mode) {
-
-		case ME_WRITE_MODE_BLOCKING:
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			PDEBUG("Write for blocking continuous mode.\n");
-
-			while (cnt > 0) {
-				wait_event_interruptible(instance->wait_queue,
-							 (c =
-							  me_circ_buf_space_to_end
-							  (&instance->
-							   circ_buf)));
-
-				if (instance->
-				    flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
-					PERROR
-					    ("Broken pipe in blocking write.\n");
-					err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-					goto ERROR;
-				} else if (signal_pending(current)) {
-					PERROR
-					    ("Wait for free buffer interrupted from signal.\n");
-					err = ME_ERRNO_SIGNAL;
-					goto ERROR;
-				}
-
-				PDEBUG("Space to end = %d.\n", c);
-
-				/* Only able to write size of free buffer or size of count */
-
-				if (cnt < c)
-					c = cnt;
-				k = sizeof(int) * c;
-				k -= copy_from_user(instance->circ_buf.buf +
-						    instance->circ_buf.head,
-						    values, k);
-				c = k / sizeof(int);
-
-				PDEBUG("Copy %d values from user space.\n", c);
-
-				if (!c) {
-					PERROR
-					    ("Cannot copy values from user space.\n");
-					err = ME_ERRNO_INTERNAL;
-					goto ERROR;
-				}
-
-				instance->circ_buf.head =
-				    (instance->circ_buf.head +
-				     c) & (instance->circ_buf.mask);
-
-				values += c;
-				cnt -= c;
-				ret += c;
-
-				/* Values are now available so enable interrupts */
-				spin_lock_irqsave(&instance->subdevice_lock,
-						  cpu_flags);
-
-				if (me_circ_buf_space(&instance->circ_buf)) {
-					tmp = inl(instance->ctrl_reg);
-					tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-					outl(tmp, instance->ctrl_reg);
-				}
-
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-			}
-
-			*count = ret;
-
-			break;
-
-		case ME_WRITE_MODE_NONBLOCKING:
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			PDEBUG("Write for non blocking continuous mode.\n");
-
-			while (cnt > 0) {
-				if (instance->
-				    flags & ME4600_AO_FLAGS_BROKEN_PIPE) {
-					PERROR
-					    ("ME4600:Broken pipe in nonblocking write.\n");
-					err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-					goto ERROR;
-				}
-
-				c = me_circ_buf_space_to_end(&instance->
-							     circ_buf);
-
-				if (!c) {
-					PDEBUG
-					    ("Returning from nonblocking write.\n");
-					break;
-				}
-
-				PDEBUG("Space to end = %d.\n", c);
-
-				/* Only able to write size of free buffer or size of count */
-
-				if (cnt < c)
-					c = cnt;
-				k = sizeof(int) * c;
-				k -= copy_from_user(instance->circ_buf.buf +
-						    instance->circ_buf.head,
-						    values, k);
-				c = k / sizeof(int);
-
-				PDEBUG("Copy %d values from user space.\n", c);
-
-				if (!c) {
-					PERROR
-					    ("Cannot copy values from user space.\n");
-					err = ME_ERRNO_INTERNAL;
-					goto ERROR;
-				}
-
-				instance->circ_buf.head =
-				    (instance->circ_buf.head +
-				     c) & (instance->circ_buf.mask);
-
-				values += c;
-				cnt -= c;
-				ret += c;
-
-				/* Values are now available so enable interrupts */
-				spin_lock_irqsave(&instance->subdevice_lock,
-						  cpu_flags);
-
-				if (me_circ_buf_space(&instance->circ_buf)) {
-					tmp = inl(instance->ctrl_reg);
-					tmp |= ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-					outl(tmp, instance->ctrl_reg);
-				}
-
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-			}
-
-			*count = ret;
-
-			break;
-
-		case ME_WRITE_MODE_PRELOAD:
-			PDEBUG("Write for preload continuous mode.\n");
-
-			if ((inl(instance->status_reg) &
-			     ME4600_AO_STATUS_BIT_FSM)) {
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				PERROR
-				    ("Can't Preload DAC FIFO while conversion is running.\n");
-				err = ME_ERRNO_SUBDEVICE_BUSY;
-				goto ERROR;
-			}
-
-			tmp = inl(instance->ctrl_reg);
-
-			tmp |=
-			    ME4600_AO_CTRL_BIT_STOP |
-			    ME4600_AO_CTRL_BIT_IMMEDIATE_STOP;
-			outl(tmp, instance->ctrl_reg);
-			tmp &=
-			    ~(ME4600_AO_CTRL_BIT_ENABLE_FIFO |
-			      ME4600_AO_CTRL_BIT_ENABLE_IRQ);
-			outl(tmp, instance->ctrl_reg);
-			tmp |= ME4600_AO_CTRL_BIT_ENABLE_FIFO;
-			outl(tmp, instance->ctrl_reg);
-
-			instance->circ_buf.head = 0;
-			instance->circ_buf.tail = 0;
-			instance->flags &= ~ME4600_AO_FLAGS_BROKEN_PIPE;
-
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			c = ME4600_AO_FIFO_COUNT;
-
-			if (cnt < c)
-				c = cnt;
-
-			for (i = 0; i < c; i++) {
-				if (get_user(value, values)) {
-					PERROR
-					    ("Can't copy value from user space.\n");
-					err = ME_ERRNO_INTERNAL;
-					goto ERROR;
-				}
-
-				if (instance->ao_idx & 0x1)
-					value <<= 16;
-
-				outl(value, instance->fifo_reg);
-
-				values++;
-			}
-
-			cnt -= c;
-
-			ret += c;
-
-			PDEBUG("Wrote %d values to fifo.\n", c);
-
-			while (1) {
-				c = me_circ_buf_space_to_end(&instance->
-							     circ_buf);
-
-				if (c == 0)
-					break;
-
-				if (cnt < c)
-					c = cnt;
-
-				if (c <= 0)
-					break;
-
-				k = sizeof(int) * c;
-
-				k -= copy_from_user(instance->circ_buf.buf +
-						    instance->circ_buf.head,
-						    values, k);
-
-				c = k / sizeof(int);
-
-				PDEBUG("Wrote %d values to circular buffer.\n",
-				       c);
-
-				if (!c) {
-					PERROR
-					    ("Can't copy values from user space.\n");
-					err = ME_ERRNO_INTERNAL;
-					goto ERROR;
-				}
-
-				instance->circ_buf.head =
-				    (instance->circ_buf.head +
-				     c) & (instance->circ_buf.mask);
-
-				values += c;
-				cnt -= c;
-				ret += c;
-			}
-
-			*count = ret;
-
-			break;
-
-		default:
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			PERROR("Invalid write mode specified.\n");
-
-			err = ME_ERRNO_INVALID_WRITE_MODE;
-
-			goto ERROR;
-		}
-
-		break;
-
-	default:		// Single mode of invalid
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-		PERROR("Subdevice is configured in single mode.\n");
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-		goto ERROR;
-	}
-
-ERROR:
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
-{
-	unsigned long tmp;
-	int value;
-	me4600_ao_subdevice_t *instance = dev_id;
-	int i;
-	int c = 0;
-	int c1 = 0;
-
-	if (irq != instance->irq) {
-		PDEBUG("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	if (!((0x1 << (instance->ao_idx + 3)) & inl(instance->irq_status_reg))) {
-		return IRQ_NONE;
-	}
-
-	PDEBUG("executed.\n");
-
-	tmp = inl(instance->status_reg);
-
-	if (!(tmp & ME4600_AO_STATUS_BIT_EF) &&
-	    (tmp & ME4600_AO_STATUS_BIT_HF) &&
-	    (tmp & ME4600_AO_STATUS_BIT_HF)) {
-		c = ME4600_AO_FIFO_COUNT;
-		PDEBUG("Fifo empty.\n");
-	} else if ((tmp & ME4600_AO_STATUS_BIT_EF) &&
-		   (tmp & ME4600_AO_STATUS_BIT_HF) &&
-		   (tmp & ME4600_AO_STATUS_BIT_HF)) {
-		c = ME4600_AO_FIFO_COUNT / 2;
-		PDEBUG("Fifo under half full.\n");
-	} else {
-		c = 0;
-		PDEBUG("Fifo full.\n");
-	}
-
-	PDEBUG("Try to write 0x%04X values.\n", c);
-
-	if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
-	    ME4600_AO_FLAGS_SW_WRAP_MODE_INF) {
-		while (c) {
-			c1 = c;
-
-			if (c1 > (instance->circ_buf.head - instance->circ_buf.tail))	/* Only up to the end of the buffer */
-				c1 = (instance->circ_buf.head -
-				      instance->circ_buf.tail);
-
-			/* Write the values to the FIFO */
-			for (i = 0; i < c1; i++, instance->circ_buf.tail++, c--) {
-				if (instance->ao_idx & 0x1)
-					outl(instance->circ_buf.
-					     buf[instance->circ_buf.tail] << 16,
-					     instance->fifo_reg);
-				else
-					outl(instance->circ_buf.
-					     buf[instance->circ_buf.tail],
-					     instance->fifo_reg);
-			}
-
-			if (instance->circ_buf.tail >= instance->circ_buf.head)	/* Start from beginning */
-				instance->circ_buf.tail = 0;
-		}
-
-		spin_lock(&instance->subdevice_lock);
-
-		tmp = inl(instance->ctrl_reg);
-		tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-		outl(tmp, instance->ctrl_reg);
-		tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-		outl(tmp, instance->ctrl_reg);
-
-		if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
-			PERROR("Broken pipe.\n");
-			instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
-			tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(tmp, instance->ctrl_reg);
-		}
-
-		spin_unlock(&instance->subdevice_lock);
-	} else if ((instance->flags & ME4600_AO_FLAGS_SW_WRAP_MODE_MASK) ==
-		   ME4600_AO_FLAGS_SW_WRAP_MODE_FIN) {
-		while (c && instance->wrap_remaining) {
-			c1 = c;
-
-			if (c1 > (instance->circ_buf.head - instance->circ_buf.tail))	/* Only up to the end of the buffer */
-				c1 = (instance->circ_buf.head -
-				      instance->circ_buf.tail);
-
-			if (c1 > instance->wrap_remaining)	/* Only up to count of user defined number of values */
-				c1 = instance->wrap_remaining;
-
-			/* Write the values to the FIFO */
-			for (i = 0; i < c1;
-			     i++, instance->circ_buf.tail++, c--,
-			     instance->wrap_remaining--) {
-				if (instance->ao_idx & 0x1)
-					outl(instance->circ_buf.
-					     buf[instance->circ_buf.tail] << 16,
-					     instance->fifo_reg);
-				else
-					outl(instance->circ_buf.
-					     buf[instance->circ_buf.tail],
-					     instance->fifo_reg);
-			}
-
-			if (instance->circ_buf.tail >= instance->circ_buf.head)	/* Start from beginning */
-				instance->circ_buf.tail = 0;
-		}
-
-		spin_lock(&instance->subdevice_lock);
-
-		tmp = inl(instance->ctrl_reg);
-
-		if (!instance->wrap_remaining) {
-			PDEBUG("Finite SW wraparound done.\n");
-			tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-		}
-
-		tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-
-		outl(tmp, instance->ctrl_reg);
-		tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-		outl(tmp, instance->ctrl_reg);
-
-		if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
-			PERROR("Broken pipe.\n");
-			instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
-			tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(tmp, instance->ctrl_reg);
-		}
-
-		spin_unlock(&instance->subdevice_lock);
-
-	} else {		/* Regular continuous mode */
-
-		while (1) {
-			c1 = me_circ_buf_values_to_end(&instance->circ_buf);
-			PDEBUG("Values to end = %d.\n", c1);
-
-			if (c1 > c)
-				c1 = c;
-
-			if (c1 <= 0) {
-				PDEBUG("Work done or buffer empty.\n");
-				break;
-			}
-
-			if (instance->ao_idx & 0x1) {
-				for (i = 0; i < c1; i++) {
-					value =
-					    *(instance->circ_buf.buf +
-					      instance->circ_buf.tail +
-					      i) << 16;
-					outl(value, instance->fifo_reg);
-				}
-			} else
-				outsl(instance->fifo_reg,
-				      instance->circ_buf.buf +
-				      instance->circ_buf.tail, c1);
-
-			instance->circ_buf.tail =
-			    (instance->circ_buf.tail +
-			     c1) & (instance->circ_buf.mask);
-
-			PDEBUG("%d values wrote to port 0x%04X.\n", c1,
-			       instance->fifo_reg);
-
-			c -= c1;
-		}
-
-		spin_lock(&instance->subdevice_lock);
-
-		tmp = inl(instance->ctrl_reg);
-
-		if (!me_circ_buf_values(&instance->circ_buf)) {
-			PDEBUG
-			    ("Disable Interrupt because no values left in buffer.\n");
-			tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-		}
-
-		tmp |= ME4600_AO_CTRL_BIT_RESET_IRQ;
-
-		outl(tmp, instance->ctrl_reg);
-		tmp &= ~ME4600_AO_CTRL_BIT_RESET_IRQ;
-		outl(tmp, instance->ctrl_reg);
-
-		if (!(inl(instance->status_reg) & ME4600_AO_STATUS_BIT_FSM)) {
-			PDEBUG("Broken pipe in me4600_ao_isr.\n");
-			instance->flags |= ME4600_AO_FLAGS_BROKEN_PIPE;
-			tmp &= ~ME4600_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(tmp, instance->ctrl_reg);
-		}
-
-		spin_unlock(&instance->subdevice_lock);
-
-		wake_up_interruptible(&instance->wait_queue);
-	}
-
-	return IRQ_HANDLED;
-}
-
-static void me4600_ao_destructor(struct me_subdevice *subdevice)
-{
-	me4600_ao_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	free_irq(instance->irq, instance);
-	kfree(instance->circ_buf.buf);
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
-					     spinlock_t *preload_reg_lock,
-					     uint32_t *preload_flags,
-					     int ao_idx, int fifo, int irq)
-{
-	me4600_ao_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me4600_ao_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me4600_ao_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->preload_reg_lock = preload_reg_lock;
-	subdevice->preload_flags = preload_flags;
-
-	/* Allocate and initialize circular buffer */
-	subdevice->circ_buf.mask = ME4600_AO_CIRC_BUF_COUNT - 1;
-	subdevice->circ_buf.buf = kmalloc(ME4600_AO_CIRC_BUF_SIZE, GFP_KERNEL);
-
-	if (!subdevice->circ_buf.buf) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		me_subdevice_deinit((me_subdevice_t *) subdevice);
-		kfree(subdevice);
-		return NULL;
-	}
-
-	memset(subdevice->circ_buf.buf, 0, ME4600_AO_CIRC_BUF_SIZE);
-
-	subdevice->circ_buf.head = 0;
-	subdevice->circ_buf.tail = 0;
-
-	/* Initialize wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	/* Initialize single value to 0V */
-	subdevice->single_value = 0x8000;
-
-	/* Store analog output index */
-	subdevice->ao_idx = ao_idx;
-
-	/* Store if analog output has fifo */
-	subdevice->fifo = fifo;
-
-	/* Initialize registers */
-
-	if (ao_idx == 0) {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_00_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_00_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_00_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_00_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_00_TIMER_REG;
-		subdevice->reg_base = reg_base;
-
-		if (inl(subdevice->reg_base + ME4600_AO_BOSCH_REG) == 0x20000) {
-			PINFO("Bosch firmware in use for channel 0.\n");
-			subdevice->bosch_fw = 1;
-		} else {
-			subdevice->bosch_fw = 0;
-		}
-	} else if (ao_idx == 1) {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_01_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_01_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_01_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_01_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_01_TIMER_REG;
-		subdevice->reg_base = reg_base;
-		subdevice->bosch_fw = 0;
-	} else if (ao_idx == 2) {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_02_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_02_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_02_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_02_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_02_TIMER_REG;
-		subdevice->reg_base = reg_base;
-		subdevice->bosch_fw = 0;
-	} else {
-		subdevice->ctrl_reg = reg_base + ME4600_AO_03_CTRL_REG;
-		subdevice->status_reg = reg_base + ME4600_AO_03_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME4600_AO_03_FIFO_REG;
-		subdevice->single_reg = reg_base + ME4600_AO_03_SINGLE_REG;
-		subdevice->timer_reg = reg_base + ME4600_AO_03_TIMER_REG;
-		subdevice->reg_base = reg_base;
-		subdevice->bosch_fw = 0;
-	}
-
-	subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
-	subdevice->preload_reg = reg_base + ME4600_AO_LOADSETREG_XX;
-
-	/* Register interrupt service routine */
-	subdevice->irq = irq;
-
-	if (request_irq
-	    (subdevice->irq, me4600_ao_isr, IRQF_DISABLED | IRQF_SHARED,
-	     ME4600_NAME, subdevice)) {
-		PERROR("Cannot get interrupt line.\n");
-		me_subdevice_deinit((me_subdevice_t *) subdevice);
-		kfree(subdevice->circ_buf.buf);
-		kfree(subdevice);
-		return NULL;
-	}
-
-	/* Override base class methods. */
-	subdevice->base.me_subdevice_destructor = me4600_ao_destructor;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me4600_ao_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me4600_ao_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me4600_ao_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me4600_ao_io_single_write;
-	subdevice->base.me_subdevice_io_stream_config =
-	    me4600_ao_io_stream_config;
-	subdevice->base.me_subdevice_io_stream_new_values =
-	    me4600_ao_io_stream_new_values;
-	subdevice->base.me_subdevice_io_stream_write =
-	    me4600_ao_io_stream_write;
-	subdevice->base.me_subdevice_io_stream_start =
-	    me4600_ao_io_stream_start;
-	subdevice->base.me_subdevice_io_stream_status =
-	    me4600_ao_io_stream_status;
-	subdevice->base.me_subdevice_io_stream_stop = me4600_ao_io_stream_stop;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me4600_ao_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me4600_ao_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me4600_ao_query_subdevice_caps;
-	subdevice->base.me_subdevice_query_subdevice_caps_args =
-	    me4600_ao_query_subdevice_caps_args;
-	subdevice->base.me_subdevice_query_range_by_min_max =
-	    me4600_ao_query_range_by_min_max;
-	subdevice->base.me_subdevice_query_number_ranges =
-	    me4600_ao_query_number_ranges;
-	subdevice->base.me_subdevice_query_range_info =
-	    me4600_ao_query_range_info;
-	subdevice->base.me_subdevice_query_timer = me4600_ao_query_timer;
-
-	return subdevice;
-}
-
-#endif // BOSCH
-
-/* Common functions
-*/
-
-static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
-					    int unit,
-					    int *min,
-					    int *max, int *maxdata, int *range)
-{
-	me4600_ao_subdevice_t *instance;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if ((*max - *min) < 0) {
-		PERROR("Invalid minimum and maximum values specified.\n");
-		return ME_ERRNO_INVALID_MIN_MAX;
-	}
-
-	if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
-		if ((*max <= (ME4600_AO_MAX_RANGE + 1000))
-		    && (*min >= ME4600_AO_MIN_RANGE)) {
-			*min = ME4600_AO_MIN_RANGE;
-			*max = ME4600_AO_MAX_RANGE;
-			*maxdata = ME4600_AO_MAX_DATA;
-			*range = 0;
-		} else {
-			PERROR("No matching range available.\n");
-			return ME_ERRNO_NO_RANGE;
-		}
-	} else {
-		PERROR("Invalid physical unit specified.\n");
-		return ME_ERRNO_INVALID_UNIT;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
-					 int unit, int *count)
-{
-	me4600_ao_subdevice_t *instance;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
-		*count = 1;
-	} else {
-		*count = 0;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
-				      int range,
-				      int *unit,
-				      int *min, int *max, int *maxdata)
-{
-	me4600_ao_subdevice_t *instance;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (range == 0) {
-		*unit = ME_UNIT_VOLT;
-		*min = ME4600_AO_MIN_RANGE;
-		*max = ME4600_AO_MAX_RANGE;
-		*maxdata = ME4600_AO_MAX_DATA;
-	} else {
-		PERROR("Invalid range number specified.\n");
-		return ME_ERRNO_INVALID_RANGE;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_timer(me_subdevice_t *subdevice,
-				 int timer,
-				 int *base_frequency,
-				 long long *min_ticks, long long *max_ticks)
-{
-	me4600_ao_subdevice_t *instance;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if ((timer != ME_TIMER_ACQ_START) && (timer != ME_TIMER_CONV_START)) {
-		PERROR("Invalid timer specified.\n");
-		return ME_ERRNO_INVALID_TIMER;
-	}
-
-	if (instance->fifo) {	//Streaming device.
-		*base_frequency = ME4600_AO_BASE_FREQUENCY;
-		if (timer == ME_TIMER_ACQ_START) {
-			*min_ticks = ME4600_AO_MIN_ACQ_TICKS;
-			*max_ticks = ME4600_AO_MAX_ACQ_TICKS;
-		} else if (timer == ME_TIMER_CONV_START) {
-			*min_ticks = ME4600_AO_MIN_CHAN_TICKS;
-			*max_ticks = ME4600_AO_MAX_CHAN_TICKS;
-		}
-	} else {		//Not streaming device!
-		*base_frequency = 0;
-		*min_ticks = 0;
-		*max_ticks = 0;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	me4600_ao_subdevice_t *instance;
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*number = 1;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	me4600_ao_subdevice_t *instance;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*type = ME_TYPE_AO;
-	*subtype = (instance->fifo) ? ME_SUBTYPE_STREAMING : ME_SUBTYPE_SINGLE;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	me4600_ao_subdevice_t *instance;
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*caps =
-	    ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO :
-					   ME_CAPS_NONE);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
-					       int cap, int *args, int count)
-{
-	me4600_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	instance = (me4600_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (count != 1) {
-		PERROR("Invalid capability argument count.\n");
-		return ME_ERRNO_INVALID_CAP_ARG_COUNT;
-	}
-
-	switch (cap) {
-	case ME_CAP_AI_FIFO_SIZE:
-		args[0] = (instance->fifo) ? ME4600_AO_FIFO_COUNT : 0;
-		break;
-
-	case ME_CAP_AI_BUFFER_SIZE:
-		args[0] =
-		    (instance->circ_buf.buf) ? ME4600_AO_CIRC_BUF_COUNT : 0;
-		break;
-
-	default:
-		PERROR("Invalid capability.\n");
-		err = ME_ERRNO_INVALID_CAP;
-		args[0] = 0;
-	}
-
-	return err;
-}
diff --git a/drivers/staging/meilhaus/me4600_ao.h b/drivers/staging/meilhaus/me4600_ao.h
deleted file mode 100644
index 7579435..0000000
--- a/drivers/staging/meilhaus/me4600_ao.h
+++ /dev/null
@@ -1,259 +0,0 @@
-/**
- * @file me4600_ao.h
- *
- * @brief Meilhaus ME-4000 analog output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_AO_H_
-# define _ME4600_AO_H_
-
-# include <linux/version.h>
-# include "mesubdevice.h"
-# include "mecirc_buf.h"
-# include "meioctl.h"
-
-# ifdef __KERNEL__
-
-#  ifdef BOSCH
-#   undef ME_SYNAPSE
-#   ifndef _CBUFF_32b_t
-# 	 define _CBUFF_32b_t
-#   endif //_CBUFF_32b_t
-#  endif //BOSCH
-
-#  define ME4600_AO_MAX_SUBDEVICES		4
-#  define ME4600_AO_FIFO_COUNT			4096
-
-#  define ME4600_AO_BASE_FREQUENCY		33000000LL
-
-#  define ME4600_AO_MIN_ACQ_TICKS		0LL
-#  define ME4600_AO_MAX_ACQ_TICKS		0LL
-
-#  define ME4600_AO_MIN_CHAN_TICKS		66LL
-#  define ME4600_AO_MAX_CHAN_TICKS		0xFFFFFFFFLL
-
-#  define ME4600_AO_MIN_RANGE			-10000000
-#  define ME4600_AO_MAX_RANGE			9999694
-
-#  define ME4600_AO_MAX_DATA			0xFFFF
-
-#  ifdef ME_SYNAPSE
-#   define ME4600_AO_CIRC_BUF_SIZE_ORDER 		8	// 2^n PAGES =>> Maximum value of 1MB for Synapse
-#  else
-#   define ME4600_AO_CIRC_BUF_SIZE_ORDER 		5	// 2^n PAGES =>> 128KB
-#  endif
-#  define ME4600_AO_CIRC_BUF_SIZE 		PAGE_SIZE<<ME4600_AO_CIRC_BUF_SIZE_ORDER	// Buffer size in bytes.
-
-#  ifdef _CBUFF_32b_t
-#   define ME4600_AO_CIRC_BUF_COUNT	((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint32_t))	// Size in values
-#  else
-#   define ME4600_AO_CIRC_BUF_COUNT	((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint16_t))	// Size in values
-#  endif
-
-#  define ME4600_AO_CONTINOUS					0x0
-#  define ME4600_AO_WRAP_MODE					0x1
-#  define ME4600_AO_HW_MODE						0x2
-
-#  define ME4600_AO_HW_WRAP_MODE				(ME4600_AO_WRAP_MODE | ME4600_AO_HW_MODE)
-#  define ME4600_AO_SW_WRAP_MODE				ME4600_AO_WRAP_MODE
-
-#  define ME4600_AO_INF_STOP_MODE				0x0
-#  define ME4600_AO_ACQ_STOP_MODE				0x1
-#  define ME4600_AO_SCAN_STOP_MODE				0x2
-
-#  ifdef BOSCH			//SPECIAL BUILD FOR BOSCH
-
-/* Bits for flags attribute. */
-#   define ME4600_AO_FLAGS_BROKEN_PIPE			0x1
-#   define ME4600_AO_FLAGS_SW_WRAP_MODE_0		0x2
-#   define ME4600_AO_FLAGS_SW_WRAP_MODE_1		0x4
-#   define ME4600_AO_FLAGS_SW_WRAP_MODE_MASK	(ME4600_AO_FLAGS_SW_WRAP_MODE_0 | ME4600_AO_FLAGS_SW_WRAP_MODE_1)
-
-#   define ME4600_AO_FLAGS_SW_WRAP_MODE_NONE	0x0
-#   define ME4600_AO_FLAGS_SW_WRAP_MODE_INF		0x2
-#   define ME4600_AO_FLAGS_SW_WRAP_MODE_FIN		0x4
-
-	/**
-	* @brief The ME-4000 analog output subdevice class.
-	*/
-typedef struct me4600_ao_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;				/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;			/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *preload_reg_lock;		/**< Spin lock to protect #preload_reg from concurrent access. */
-	uint32_t *preload_flags;
-
-	unsigned int irq;					/**< The interrupt request number assigned by the PCI BIOS. */
-	me_circ_buf_t circ_buf;				/**< Circular buffer holding measurment data. */
-	wait_queue_head_t wait_queue;		/**< Wait queue to put on tasks waiting for data to arrive. */
-
-	int single_value;					/**< Mirror of the value written in single mode. */
-
-	int volatile flags;					/**< Flags used for storing SW wraparound setup and error signalling from ISR. */
-	unsigned int wrap_count;			/**< The user defined wraparound cycle count. */
-	unsigned int wrap_remaining;		/**< The wraparound cycle down counter used by a running conversion. */
-	unsigned int ao_idx;				/**< The index of this analog output on this device. */
-	int fifo;							/**< If set this device has a FIFO. */
-
-	int bosch_fw;						/**< If set the bosch firmware is in PROM. */
-
-	/* Registers */
-	uint32_t ctrl_reg;
-	uint32_t status_reg;
-	uint32_t fifo_reg;
-	uint32_t single_reg;
-	uint32_t timer_reg;
-	uint32_t irq_status_reg;
-	uint32_t preload_reg;
-	uint32_t reg_base;
-} me4600_ao_subdevice_t;
-
-	/**
-	* @brief The constructor to generate a ME-4000 analog output subdevice instance for BOSCH project.
-	*
-	* @param reg_base The register base address of the device as returned by the PCI BIOS.
-	* @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
-	* @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
-	* @param ao_idx Subdevice number.
-	* @param fifo Flag set if subdevice has hardware FIFO.
-	* @param irq IRQ number.
-	*
-	* @return Pointer to new instance on success.\n
-	* NULL on error.
-	*/
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
-					     spinlock_t * preload_reg_lock,
-					     uint32_t * preload_flags,
-					     int ao_idx, int fifo, int irq);
-
-#  else	//~BOSCH
-
-//ME4600_AO_FLAGS_BROKEN_PIPE is OBSOLETE => Now problems are reported in status.
-
-typedef enum ME4600_AO_STATUS {
-	ao_status_none = 0,
-	ao_status_single_configured,
-	ao_status_single_run_wait,
-	ao_status_single_run,
-	ao_status_single_end_wait,
-	ao_status_single_end,
-	ao_status_stream_configured,
-	ao_status_stream_run_wait,
-	ao_status_stream_run,
-	ao_status_stream_end_wait,
-	ao_status_stream_end,
-	ao_status_stream_fifo_error,
-	ao_status_stream_buffer_error,
-	ao_status_stream_error,
-	ao_status_last
-} ME4600_AO_STATUS;
-
-typedef struct me4600_ao_timeout {
-	unsigned long start_time;
-	unsigned long delay;
-} me4600_ao_timeout_t;
-
-	/**
-	* @brief The ME-4600 analog output subdevice class.
-	*/
-typedef struct me4600_ao_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;						/**< The subdevice base class. */
-	unsigned int ao_idx;						/**< The index of this analog output on this device. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;					/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *preload_reg_lock;				/**< Spin lock to protect preload_reg from concurrent access. */
-
-	uint32_t *preload_flags;
-
-	/* Hardware feautres */
-	unsigned int irq;							/**< The interrupt request number assigned by the PCI BIOS. */
-	int fifo;									/**< If set this device has a FIFO. */
-	int bitpattern;								/**< If set this device use bitpattern. */
-
-	int single_value;							/**< Mirror of the output value in single mode. */
-	int single_value_in_fifo;					/**< Mirror of the value written in single mode. */
-	uint32_t ctrl_trg;							/**< Mirror of the trigger settings. */
-
-	volatile int mode;							/**< Flags used for storing SW wraparound setup*/
-	int stop_mode;								/**< The user defined stop condition flag. */
-	unsigned int start_mode;
-	unsigned int stop_count;					/**< The user defined dates presentation end count. */
-	unsigned int stop_data_count;				/**< The stop presentation count. */
-	unsigned int data_count;					/**< The real presentation count. */
-	unsigned int preloaded_count;				/**< The next data addres in buffer. <= for wraparound mode. */
-	int hardware_stop_delay;					/**< The time that stop can take. This is only to not show hardware bug to user. */
-
-	volatile enum ME4600_AO_STATUS status;		/**< The current stream status flag. */
-	me4600_ao_timeout_t timeout;				/**< The timeout for start in blocking and non-blocking mode. */
-
-										/* Registers *//**< All registers are 32 bits long. */
-	unsigned long ctrl_reg;
-	unsigned long status_reg;
-	unsigned long fifo_reg;
-	unsigned long single_reg;
-	unsigned long timer_reg;
-	unsigned long irq_status_reg;
-	unsigned long preload_reg;
-	unsigned long reg_base;
-
-	/* Software buffer */
-	me_circ_buf_t circ_buf;						/**< Circular buffer holding measurment data. 32 bit long */
-	wait_queue_head_t wait_queue;				/**< Wait queue to put on tasks waiting for data to arrive. */
-
-	struct workqueue_struct *me4600_workqueue;
-	struct delayed_work ao_control_task;
-
-	volatile int ao_control_task_flag;			/**< Flag controling reexecuting of control task */
-
-} me4600_ao_subdevice_t;
-
-	/**
-	* @brief The constructor to generate a ME-4600 analog output subdevice instance.
-	*
-	* @param reg_base The register base address of the device as returned by the PCI BIOS.
-	* @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
-	* @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
-	* @param ao_idx Subdevice number.
-	* @param fifo Flag set if subdevice has hardware FIFO.
-	* @param irq IRQ number.
-	* @param me4600_wq Queue for asynchronous task (1 queue for all subdevice on 1 board).
-	*
-	* @return Pointer to new instance on success.\n
-	* NULL on error.
-	*/
-me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
-					     spinlock_t * preload_reg_lock,
-					     uint32_t * preload_flags,
-					     int ao_idx,
-					     int fifo,
-					     int irq,
-					     struct workqueue_struct
-					     *me4600_wq);
-
-#  endif //BOSCH
-# endif	//__KERNEL__
-#endif // ~_ME4600_AO_H_
diff --git a/drivers/staging/meilhaus/me4600_ao_reg.h b/drivers/staging/meilhaus/me4600_ao_reg.h
deleted file mode 100644
index f83d82e..0000000
--- a/drivers/staging/meilhaus/me4600_ao_reg.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * @file me4600_ao_reg.h
- *
- * @brief ME-4000 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_AO_REG_H_
-#define _ME4600_AO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_AO_00_CTRL_REG					0x00	// R/W
-#define ME4600_AO_00_STATUS_REG					0x04	// R/_
-#define ME4600_AO_00_FIFO_REG					0x08	// _/W
-#define ME4600_AO_00_SINGLE_REG					0x0C	// R/W
-#define ME4600_AO_00_TIMER_REG					0x10	// _/W
-
-#define ME4600_AO_01_CTRL_REG					0x18	// R/W
-#define ME4600_AO_01_STATUS_REG					0x1C	// R/_
-#define ME4600_AO_01_FIFO_REG					0x20	// _/W
-#define ME4600_AO_01_SINGLE_REG					0x24	// R/W
-#define ME4600_AO_01_TIMER_REG					0x28	// _/W
-
-#define ME4600_AO_02_CTRL_REG					0x30	// R/W
-#define ME4600_AO_02_STATUS_REG					0x34	// R/_
-#define ME4600_AO_02_FIFO_REG					0x38	// _/W
-#define ME4600_AO_02_SINGLE_REG					0x3C	// R/W
-#define ME4600_AO_02_TIMER_REG					0x40	// _/W
-
-#define ME4600_AO_03_CTRL_REG					0x48	// R/W
-#define ME4600_AO_03_STATUS_REG					0x4C	// R/_
-#define ME4600_AO_03_FIFO_REG					0x50	// _/W
-#define ME4600_AO_03_SINGLE_REG					0x54	// R/W
-#define ME4600_AO_03_TIMER_REG					0x58	// _/W
-
-#define ME4600_AO_DEMUX_ADJUST_REG				0xBC	// -/W
-#define ME4600_AO_DEMUX_ADJUST_VALUE			0x4C
-
-#ifdef BOSCH
-# define ME4600_AO_BOSCH_REG					0xC4
-
-# define ME4600_AO_LOADSETREG_XX				0xB4	// R/W
-
-# define ME4600_AO_CTRL_BIT_MODE_0				0x001
-# define ME4600_AO_CTRL_BIT_MODE_1				0x002
-# define ME4600_AO_CTRL_MASK_MODE				0x003
-
-#else //~BOSCH
-
-#define ME4600_AO_SYNC_REG						0xB4	// R/W    ///ME4600_AO_SYNC_REG <==> ME4600_AO_PRELOAD_REG <==> ME4600_AO_LOADSETREG_XX
-
-# define ME4600_AO_MODE_SINGLE					0x00000000
-# define ME4600_AO_MODE_WRAPAROUND				0x00000001
-# define ME4600_AO_MODE_CONTINUOUS				0x00000002
-# define ME4600_AO_CTRL_MODE_MASK				(ME4600_AO_MODE_WRAPAROUND | ME4600_AO_MODE_CONTINUOUS)
-#endif //BOSCH
-
-#define ME4600_AO_CTRL_BIT_MODE_WRAPAROUND		ME4600_AO_MODE_WRAPAROUND
-#define ME4600_AO_CTRL_BIT_MODE_CONTINOUS		ME4600_AO_MODE_CONTINUOUS
-#define ME4600_AO_CTRL_BIT_STOP					0x00000004
-#define ME4600_AO_CTRL_BIT_ENABLE_FIFO			0x00000008
-#define ME4600_AO_CTRL_BIT_ENABLE_EX_TRIG		0x00000010
-#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE			0x00000020
-#define ME4600_AO_CTRL_BIT_IMMEDIATE_STOP		0x00000080
-#define ME4600_AO_CTRL_BIT_ENABLE_DO			0x00000100
-#define ME4600_AO_CTRL_BIT_ENABLE_IRQ			0x00000200
-#define ME4600_AO_CTRL_BIT_RESET_IRQ			0x00000400
-#define ME4600_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH	0x00000800
-/*
-#define ME4600_AO_SYNC_HOLD_0					0x00000001
-#define ME4600_AO_SYNC_HOLD_1					0x00000002
-#define ME4600_AO_SYNC_HOLD_2					0x00000004
-#define ME4600_AO_SYNC_HOLD_3					0x00000008
-*/
-#define ME4600_AO_SYNC_HOLD						0x00000001
-
-/*
-#define ME4600_AO_SYNC_EXT_TRIG_0				0x00010000
-#define ME4600_AO_SYNC_EXT_TRIG_1				0x00020000
-#define ME4600_AO_SYNC_EXT_TRIG_2				0x00040000
-#define ME4600_AO_SYNC_EXT_TRIG_3				0x00080000
-*/
-#define ME4600_AO_SYNC_EXT_TRIG					0x00010000
-
-#define ME4600_AO_EXT_TRIG						0x80000000
-
-#define ME4600_AO_STATUS_BIT_FSM				0x00000001
-#define ME4600_AO_STATUS_BIT_FF					0x00000002
-#define ME4600_AO_STATUS_BIT_HF					0x00000004
-#define ME4600_AO_STATUS_BIT_EF					0x00000008
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_device.c b/drivers/staging/meilhaus/me4600_device.c
deleted file mode 100644
index 457666e..0000000
--- a/drivers/staging/meilhaus/me4600_device.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/**
- * @file me4600_device.c
- *
- * @brief ME-4600 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me4600_device.h"
-#include "meplx_reg.h"
-
-#include "mefirmware.h"
-
-#include "mesubdevice.h"
-#include "me4600_do.h"
-#include "me4600_di.h"
-#include "me4600_dio.h"
-#include "me8254.h"
-#include "me4600_ai.h"
-#include "me4600_ao.h"
-#include "me4600_ext_irq.h"
-
-/**
- * @brief Global variable.
- * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
- */
-static struct workqueue_struct *me4600_workqueue;
-
-#ifdef BOSCH
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw)
-#else //~BOSCH
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
-#endif				//BOSCH
-{
-	me4600_device_t *me4600_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	int err;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me4600_device = kmalloc(sizeof(me4600_device_t), GFP_KERNEL);
-
-	if (!me4600_device) {
-		PERROR("Cannot get memory for ME-4600 device instance.\n");
-		return NULL;
-	}
-
-	memset(me4600_device, 0, sizeof(me4600_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me4600_device, pci_device);
-
-	if (err) {
-		kfree(me4600_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-	// Download the xilinx firmware.
-	if (me4600_device->base.info.pci.device_id == PCI_DEVICE_ID_MEILHAUS_ME4610) {	//Jekyll <=> me4610
-		err =
-		    me_xilinx_download(me4600_device->base.info.pci.
-				       reg_bases[1],
-				       me4600_device->base.info.pci.
-				       reg_bases[5], &pci_device->dev,
-				       "me4610.bin");
-	} else {		// General me4600 firmware
-#ifdef BOSCH
-		err =
-		    me_xilinx_download(me4600_device->base.info.pci.
-				       reg_bases[1],
-				       me4600_device->base.info.pci.
-				       reg_bases[5], &pci_device->dev,
-				       (me_bosch_fw) ? "me4600_bosch.bin" :
-				       "me4600.bin");
-#else //~BOSCH
-		err =
-		    me_xilinx_download(me4600_device->base.info.pci.
-				       reg_bases[1],
-				       me4600_device->base.info.pci.
-				       reg_bases[5], &pci_device->dev,
-				       "me4600.bin");
-#endif
-	}
-
-	if (err) {
-		me_device_deinit((me_device_t *) me4600_device);
-		kfree(me4600_device);
-		PERROR("Cannot download firmware.\n");
-		return NULL;
-	}
-	// Get the index in the device version information table.
-	version_idx =
-	    me4600_versions_get_device_index(me4600_device->base.info.pci.
-					     device_id);
-
-	// Initialize spin locks.
-	spin_lock_init(&me4600_device->preload_reg_lock);
-
-	me4600_device->preload_flags = 0;
-
-	spin_lock_init(&me4600_device->dio_lock);
-	spin_lock_init(&me4600_device->ai_ctrl_lock);
-	spin_lock_init(&me4600_device->ctr_ctrl_reg_lock);
-	spin_lock_init(&me4600_device->ctr_clk_src_reg_lock);
-
-	// Create digital input instances.
-	for (i = 0; i < me4600_versions[version_idx].di_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me4600_di_constructor(me4600_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     &me4600_device->
-							     dio_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me4600_device);
-			kfree(me4600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me4600_device->base.slist,
-					    subdevice);
-	}
-
-	// Create digital output instances.
-	for (i = 0; i < me4600_versions[version_idx].do_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me4600_do_constructor(me4600_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     &me4600_device->
-							     dio_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me4600_device);
-			kfree(me4600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me4600_device->base.slist,
-					    subdevice);
-	}
-
-	// Create digital input/output instances.
-	for (i = 0; i < me4600_versions[version_idx].dio_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me4600_dio_constructor(me4600_device->
-							      base.info.pci.
-							      reg_bases[2],
-							      me4600_versions
-							      [version_idx].
-							      do_subdevices +
-							      me4600_versions
-							      [version_idx].
-							      di_subdevices + i,
-							      &me4600_device->
-							      dio_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me4600_device);
-			kfree(me4600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me4600_device->base.slist,
-					    subdevice);
-	}
-
-	// Create analog input instances.
-	for (i = 0; i < me4600_versions[version_idx].ai_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me4600_ai_constructor(me4600_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     me4600_versions
-							     [version_idx].
-							     ai_channels,
-							     me4600_versions
-							     [version_idx].
-							     ai_ranges,
-							     me4600_versions
-							     [version_idx].
-							     ai_isolated,
-							     me4600_versions
-							     [version_idx].
-							     ai_sh,
-							     me4600_device->
-							     base.irq,
-							     &me4600_device->
-							     ai_ctrl_lock,
-							     me4600_workqueue);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me4600_device);
-			kfree(me4600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me4600_device->base.slist,
-					    subdevice);
-	}
-
-	// Create analog output instances.
-	for (i = 0; i < me4600_versions[version_idx].ao_subdevices; i++) {
-#ifdef BOSCH
-		subdevice =
-		    (me_subdevice_t *) me4600_ao_constructor(me4600_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     &me4600_device->
-							     preload_reg_lock,
-							     &me4600_device->
-							     preload_flags, i,
-							     me4600_versions
-							     [version_idx].
-							     ao_fifo,
-							     me4600_device->
-							     base.irq);
-#else //~BOSCH
-		subdevice =
-		    (me_subdevice_t *) me4600_ao_constructor(me4600_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     &me4600_device->
-							     preload_reg_lock,
-							     &me4600_device->
-							     preload_flags, i,
-							     me4600_versions
-							     [version_idx].
-							     ao_fifo,
-							     me4600_device->
-							     base.irq,
-							     me4600_workqueue);
-#endif
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me4600_device);
-			kfree(me4600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me4600_device->base.slist,
-					    subdevice);
-	}
-
-	// Create counter instances.
-	for (i = 0; i < me4600_versions[version_idx].ctr_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me8254_constructor(me4600_device->base.
-							  info.pci.device_id,
-							  me4600_device->base.
-							  info.pci.reg_bases[3],
-							  0, i,
-							  &me4600_device->
-							  ctr_ctrl_reg_lock,
-							  &me4600_device->
-							  ctr_clk_src_reg_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me4600_device);
-			kfree(me4600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me4600_device->base.slist,
-					    subdevice);
-	}
-
-	// Create external interrupt instances.
-	for (i = 0; i < me4600_versions[version_idx].ext_irq_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *)
-		    me4600_ext_irq_constructor(me4600_device->base.info.pci.
-					       reg_bases[2],
-					       me4600_device->base.irq,
-					       &me4600_device->ai_ctrl_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me4600_device);
-			kfree(me4600_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me4600_device->base.slist,
-					    subdevice);
-	}
-
-	return (me_device_t *) me4600_device;
-}
-EXPORT_SYMBOL(me4600_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me4600_init(void)
-{
-	PDEBUG("executed.\n");
-
-#ifndef BOSCH
-	me4600_workqueue = create_singlethread_workqueue("me4600");
-#endif
-	return 0;
-}
-
-static void __exit me4600_exit(void)
-{
-	PDEBUG("executed.\n");
-
-#ifndef BOSCH
-	flush_workqueue(me4600_workqueue);
-	destroy_workqueue(me4600_workqueue);
-#endif
-}
-
-module_init(me4600_init);
-module_exit(me4600_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-46xx Devices");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-46xx Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me4600_device.h b/drivers/staging/meilhaus/me4600_device.h
deleted file mode 100644
index fa812d4..0000000
--- a/drivers/staging/meilhaus/me4600_device.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * @file me4600_device.h
- *
- * @brief ME-4600 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_DEVICE_H
-#define _ME4600_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-4600 device capabilities.
- */
-typedef struct me4600_version {
-	uint16_t device_id;
-	unsigned int do_subdevices;
-	unsigned int di_subdevices;
-	unsigned int dio_subdevices;
-	unsigned int ctr_subdevices;
-	unsigned int ai_subdevices;
-	unsigned int ai_channels;
-	unsigned int ai_ranges;
-	unsigned int ai_isolated;
-	unsigned int ai_sh;
-	unsigned int ao_subdevices;
-	unsigned int ao_fifo;	//How many devices have FIFO
-	unsigned int ext_irq_subdevices;
-} me4600_version_t;
-
-/**
- * @brief ME-4600 device capabilities.
- */
-static me4600_version_t me4600_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME4610, 0, 0, 4, 3, 1, 16, 1, 0, 0, 0, 0, 1},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME4650, 0, 0, 4, 0, 1, 16, 4, 0, 0, 0, 0, 1},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME4660, 0, 0, 4, 3, 1, 16, 4, 0, 0, 2, 0, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4660I, 1, 1, 2, 3, 1, 16, 4, 1, 0, 2, 0, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4660S, 0, 0, 4, 3, 1, 16, 4, 0, 1, 2, 0, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4660IS, 1, 1, 2, 3, 1, 16, 4, 1, 1, 2, 0, 1},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME4670, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 0, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4670I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 0, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4670S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 0, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4670IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 0, 1},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME4680, 0, 0, 4, 3, 1, 32, 4, 0, 0, 4, 4, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4680I, 1, 1, 2, 3, 1, 32, 4, 1, 0, 4, 4, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4680S, 0, 0, 4, 3, 1, 32, 4, 0, 1, 4, 4, 1},
-	{PCI_DEVICE_ID_MEILHAUS_ME4680IS, 1, 1, 2, 3, 1, 32, 4, 1, 1, 4, 4, 1},
-
-	{0},
-};
-
-#define ME4600_DEVICE_VERSIONS (sizeof(me4600_versions) / sizeof(me4600_version_t) - 1)	/**< Returns the number of entries in #me4600_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me4600_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me4600_versions.
- */
-static inline unsigned int me4600_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME4600_DEVICE_VERSIONS; i++)
-		if (me4600_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The ME-4600 device class structure.
- */
-typedef struct me4600_device {
-	me_device_t base;					/**< The Meilhaus device base class. */
-
-	/* Child class attributes. */
-	spinlock_t preload_reg_lock;		/**< Guards the preload register of the anaolog output devices. */
-	unsigned int preload_flags;			/**< Used in conjunction with #preload_reg_lock. */
-	spinlock_t dio_lock;				/**< Locks the control register of the digital input/output subdevices. */
-	spinlock_t ai_ctrl_lock;			/**< Locks the control register of the analog input subdevice. */
-	spinlock_t ctr_ctrl_reg_lock;		/**< Locks the counter control register. */
-	spinlock_t ctr_clk_src_reg_lock;	/**< Not used on this device but needed for the me8254 subdevice constructor call. */
-} me4600_device_t;
-
-/**
- * @brief The ME-4600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- * @param me_bosch_fw If set the device shall use the bosch firmware. (Only for special BOSCH build)
- *
- * @return On succes a new ME-4600 device instance. \n
- *         NULL on error.
- */
-
-#ifdef BOSCH
-/**
- * @brief The ME-4600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- * @param me_bosch_fw If set the device shall use the bosch firmware.
- *
- * @return On succes a new ME-4600 device instance. \n
- *         NULL on error.
- */
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device, int me_bosch_fw)
-    __attribute__ ((weak));
-#else //~BOSCH
-/**
- * @brief The ME-4600 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-4600 device instance. \n
- *         NULL on error.
- */
-me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-#endif
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_di.c b/drivers/staging/meilhaus/me4600_di.c
deleted file mode 100644
index e107e50..0000000
--- a/drivers/staging/meilhaus/me4600_di.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/**
- * @file me4600_di.c
- *
- * @brief ME-4000 digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me4600_dio_reg.h"
-#include "me4600_di.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_di_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	me4600_di_subdevice_t *instance;
-	uint32_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_di_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inl(instance->ctrl_reg);
-	mode &= ~(ME4600_DIO_CTRL_BIT_MODE_2 | ME4600_DIO_CTRL_BIT_MODE_3);	//0xFFF3
-	outl(mode, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, mode);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outl(0, instance->port_reg);
-	PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_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)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me4600_di_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-			} else {
-				PERROR("Invalid port direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_di_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me4600_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = inl(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inl(instance->port_reg) & 0xFF;
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_di_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_di_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DI;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
-					     spinlock_t *ctrl_reg_lock)
-{
-	me4600_di_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me4600_di_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me4600_di_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save the subdevice index */
-	subdevice->port_reg = reg_base + ME4600_DIO_PORT_1_REG;
-	subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me4600_di_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me4600_di_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me4600_di_io_single_read;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me4600_di_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me4600_di_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me4600_di_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_di.h b/drivers/staging/meilhaus/me4600_di.h
deleted file mode 100644
index ec8b175..0000000
--- a/drivers/staging/meilhaus/me4600_di.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file me4600_di.h
- *
- * @brief ME-4000 digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_DI_H_
-#define _ME4600_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me4600_di_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-
-	unsigned long port_reg;			/**< Register holding the port status. */
-	unsigned long ctrl_reg;			/**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me4600_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
-					     spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_dio.c b/drivers/staging/meilhaus/me4600_dio.c
deleted file mode 100644
index baa28ff..0000000
--- a/drivers/staging/meilhaus/me4600_dio.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/**
- * @file me4600_dio.c
- *
- * @brief ME-4000 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me4600_dio_reg.h"
-#include "me4600_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
-					 struct file *filep, int flags)
-{
-	me4600_dio_subdevice_t *instance;
-	uint32_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_dio_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	/* Set port to input mode */
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inl(instance->ctrl_reg);
-	mode &=
-	    ~((ME4600_DIO_CTRL_BIT_MODE_0 | ME4600_DIO_CTRL_BIT_MODE_1) <<
-	      (instance->dio_idx * 2));
-	outl(mode, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, mode);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outl(0, instance->port_reg);
-	PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_dio_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)
-{
-	me4600_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t mode;
-	uint32_t size =
-	    flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
-		     | ME_IO_SINGLE_CONFIG_DIO_WORD |
-		     ME_IO_SINGLE_CONFIG_DIO_DWORD);
-	uint32_t mask;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inl(instance->ctrl_reg);
-	switch (size) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-				mode &=
-				    ~((ME4600_DIO_CTRL_BIT_MODE_0 |
-				       ME4600_DIO_CTRL_BIT_MODE_1) <<
-				      (instance->dio_idx * 2));
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-				mode &=
-				    ~((ME4600_DIO_CTRL_BIT_MODE_0 |
-				       ME4600_DIO_CTRL_BIT_MODE_1) <<
-				      (instance->dio_idx * 2));
-				mode |=
-				    ME4600_DIO_CTRL_BIT_MODE_0 << (instance->
-								   dio_idx * 2);
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
-				mask =
-				    (ME4600_DIO_CTRL_BIT_MODE_0 |
-				     ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
-								     dio_idx *
-								     2);
-				mask |=
-				    ME4600_DIO_CTRL_BIT_FUNCTION_0 |
-				    ME4600_DIO_CTRL_BIT_FUNCTION_1;
-				mask |=
-				    ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
-				    instance->dio_idx;
-				mode &= ~mask;
-
-				if (ref == ME_REF_DIO_FIFO_LOW) {
-					mode |=
-					    (ME4600_DIO_CTRL_BIT_MODE_0 |
-					     ME4600_DIO_CTRL_BIT_MODE_1) <<
-					    (instance->dio_idx * 2);
-					mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
-				} else if (ref == ME_REF_DIO_FIFO_HIGH) {
-					mode |=
-					    (ME4600_DIO_CTRL_BIT_MODE_0 |
-					     ME4600_DIO_CTRL_BIT_MODE_1) <<
-					    (instance->dio_idx * 2);
-					mode |= ME4600_DIO_CTRL_BIT_FUNCTION_1;
-					mode |=
-					    ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
-					    instance->dio_idx;
-				} else {
-					PERROR
-					    ("Invalid port reference specified.\n");
-					err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-				}
-			} else if (single_config ==
-				   ME_SINGLE_CONFIG_DIO_DEMUX32) {
-				mask =
-				    (ME4600_DIO_CTRL_BIT_MODE_0 |
-				     ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
-								     dio_idx *
-								     2);
-				mask |=
-				    ME4600_DIO_CTRL_BIT_FUNCTION_0 |
-				    ME4600_DIO_CTRL_BIT_FUNCTION_1;
-				mask |=
-				    ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
-				    instance->dio_idx;
-				mode &= ~mask;
-
-				if (ref == ME_REF_DIO_FIFO_LOW) {
-					mode |=
-					    (ME4600_DIO_CTRL_BIT_MODE_0 |
-					     ME4600_DIO_CTRL_BIT_MODE_1) <<
-					    (instance->dio_idx * 2);
-					mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
-				} else if (ref == ME_REF_DIO_FIFO_HIGH) {
-					mode |=
-					    (ME4600_DIO_CTRL_BIT_MODE_0 |
-					     ME4600_DIO_CTRL_BIT_MODE_1) <<
-					    (instance->dio_idx * 2);
-					mode |= ME4600_DIO_CTRL_BIT_FUNCTION_0;
-					mode |=
-					    ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
-					    instance->dio_idx;
-				} else {
-					PERROR
-					    ("Invalid port reference specified.\n");
-					err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-				}
-			} else if (single_config ==
-				   ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
-				mask =
-				    (ME4600_DIO_CTRL_BIT_MODE_0 |
-				     ME4600_DIO_CTRL_BIT_MODE_1) << (instance->
-								     dio_idx *
-								     2);
-				mask |=
-				    ME4600_DIO_CTRL_BIT_FUNCTION_0 |
-				    ME4600_DIO_CTRL_BIT_FUNCTION_1;
-				mask |=
-				    ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
-				    instance->dio_idx;
-				mode &= ~mask;
-
-				if (ref == ME_REF_DIO_FIFO_LOW) {
-					mode |=
-					    (ME4600_DIO_CTRL_BIT_MODE_0 |
-					     ME4600_DIO_CTRL_BIT_MODE_1) <<
-					    (instance->dio_idx * 2);
-				} else if (ref == ME_REF_DIO_FIFO_HIGH) {
-					mode |=
-					    (ME4600_DIO_CTRL_BIT_MODE_0 |
-					     ME4600_DIO_CTRL_BIT_MODE_1) <<
-					    (instance->dio_idx * 2);
-					mode |=
-					    ME4600_DIO_CTRL_BIT_FIFO_HIGH_0 <<
-					    instance->dio_idx;
-				} else {
-					PERROR
-					    ("Invalid port reference specified.\n");
-					err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-				}
-			} else {
-				PERROR
-				    ("Invalid port configuration specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!err) {
-		outl(mode, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, mode);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_dio_io_single_read(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int *value, int time_out, int flags)
-{
-	me4600_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inl(instance->
-				ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
-					      ME4600_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-			if ((mode ==
-			     (ME4600_DIO_CTRL_BIT_MODE_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value =
-				    inl(instance->port_reg) & (0x1 << channel);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inl(instance->
-				ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
-					      ME4600_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-			if ((mode ==
-			     (ME4600_DIO_CTRL_BIT_MODE_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value = inl(instance->port_reg) & 0xFF;
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_dio_io_single_write(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int value, int time_out, int flags)
-{
-	me4600_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t mode;
-	uint32_t byte;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inl(instance->
-				ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
-					      ME4600_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME4600_DIO_CTRL_BIT_MODE_0 <<
-			     (instance->dio_idx * 2))) {
-				byte = inl(instance->port_reg) & 0xFF;
-
-				if (value)
-					byte |= 0x1 << channel;
-				else
-					byte &= ~(0x1 << channel);
-
-				outl(byte, instance->port_reg);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inl(instance->
-				ctrl_reg) & ((ME4600_DIO_CTRL_BIT_MODE_0 |
-					      ME4600_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME4600_DIO_CTRL_BIT_MODE_0 <<
-			     (instance->dio_idx * 2))) {
-				outl(value, instance->port_reg);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_dio_query_number_channels(me_subdevice_t *subdevice,
-					    int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_dio_query_subdevice_type(me_subdevice_t *subdevice,
-					   int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DIO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
-					   int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_DIO_DIR_BYTE;
-	return ME_ERRNO_SUCCESS;
-}
-
-me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t *ctrl_reg_lock)
-{
-	me4600_dio_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me4600_dio_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me4600_dio_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save digital i/o index */
-	subdevice->dio_idx = dio_idx;
-
-	/* Save the subdevice index */
-	subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
-	subdevice->port_reg = reg_base + ME4600_DIO_PORT_REG + (dio_idx * 4);
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me4600_dio_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me4600_dio_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me4600_dio_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me4600_dio_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me4600_dio_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me4600_dio_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me4600_dio_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_dio.h b/drivers/staging/meilhaus/me4600_dio.h
deleted file mode 100644
index 4625ba9..0000000
--- a/drivers/staging/meilhaus/me4600_dio.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file me4600_dio.h
- *
- * @brief ME-4000 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_DIO_H_
-#define _ME4600_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me4600_dio_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-	unsigned int dio_idx;			/**< The index of the digital i/o on the device. */
-
-	/* Registers */
-	unsigned long port_reg;			/**< Register holding the port status. */
-	unsigned long ctrl_reg;			/**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me4600_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_dio_reg.h b/drivers/staging/meilhaus/me4600_dio_reg.h
deleted file mode 100644
index 7a4016a..0000000
--- a/drivers/staging/meilhaus/me4600_dio_reg.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file me4600_dio_reg.h
- *
- * @brief ME-4000 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_DIO_REG_H_
-#define _ME4600_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_DIO_PORT_0_REG				0xA0					/**< Port 0 register. */
-#define ME4600_DIO_PORT_1_REG				0xA4					/**< Port 1 register. */
-#define ME4600_DIO_PORT_2_REG				0xA8					/**< Port 2 register. */
-#define ME4600_DIO_PORT_3_REG				0xAC					/**< Port 3 register. */
-
-#define ME4600_DIO_DIR_REG					0xB0					/**< Direction register. */
-#define ME4600_DIO_PORT_REG					ME4600_DIO_PORT_0_REG	/**< Base for port's register. */
-
-#define ME4600_DIO_CTRL_REG					0xB8					/**< Control register. */
-/** Port A - DO */
-#define ME4600_DIO_CTRL_BIT_MODE_0			0x0001
-#define ME4600_DIO_CTRL_BIT_MODE_1			0x0002
-/** Port B - DI */
-#define ME4600_DIO_CTRL_BIT_MODE_2			0x0004
-#define ME4600_DIO_CTRL_BIT_MODE_3			0x0008
-/** Port C - DIO */
-#define ME4600_DIO_CTRL_BIT_MODE_4			0x0010
-#define ME4600_DIO_CTRL_BIT_MODE_5			0x0020
-/** Port D - DIO */
-#define ME4600_DIO_CTRL_BIT_MODE_6			0x0040
-#define ME4600_DIO_CTRL_BIT_MODE_7			0x0080
-
-#define ME4600_DIO_CTRL_BIT_FUNCTION_0		0x0100
-#define ME4600_DIO_CTRL_BIT_FUNCTION_1		0x0200
-
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_0		0x0400
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_1		0x0800
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_2		0x1000
-#define ME4600_DIO_CTRL_BIT_FIFO_HIGH_3		0x2000
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_do.c b/drivers/staging/meilhaus/me4600_do.c
deleted file mode 100644
index 39510f3..0000000
--- a/drivers/staging/meilhaus/me4600_do.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/**
- * @file me4600_do.c
- *
- * @brief ME-4000 digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me4600_dio_reg.h"
-#include "me4600_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_do_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	me4600_do_subdevice_t *instance;
-	uint32_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_do_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	/* Set port to output mode */
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inl(instance->ctrl_reg);
-	mode &= ~ME4600_DIO_CTRL_BIT_MODE_1;	//0xFFFD
-	mode |= ME4600_DIO_CTRL_BIT_MODE_0;	//0x1
-	outl(mode, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, mode);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outl(0, instance->port_reg);
-	PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_do_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)
-{
-	me4600_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t mode;
-	int size =
-	    flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
-		     | ME_IO_SINGLE_CONFIG_DIO_WORD |
-		     ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inl(instance->ctrl_reg);
-
-	switch (size) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-				mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
-					  ME4600_DIO_CTRL_BIT_MODE_1);
-				mode |= (ME4600_DIO_CTRL_BIT_MODE_0);
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_MUX32M) {
-				mode &= ~(ME4600_DIO_CTRL_BIT_MODE_0 |
-					  ME4600_DIO_CTRL_BIT_MODE_1 |
-					  ME4600_DIO_CTRL_BIT_FUNCTION_0 |
-					  ME4600_DIO_CTRL_BIT_FUNCTION_1 |
-					  ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-
-				if (ref == ME_REF_DIO_FIFO_LOW) {
-					mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
-						 ME4600_DIO_CTRL_BIT_MODE_1 |
-						 ME4600_DIO_CTRL_BIT_FUNCTION_1);
-				} else if (ref == ME_REF_DIO_FIFO_HIGH) {
-					mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
-						 ME4600_DIO_CTRL_BIT_MODE_1 |
-						 ME4600_DIO_CTRL_BIT_FUNCTION_1
-						 |
-						 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-				} else {
-					PERROR
-					    ("Invalid port reference specified.\n");
-					err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-				}
-			} else if (single_config ==
-				   ME_SINGLE_CONFIG_DIO_DEMUX32) {
-				mode &=
-				    ~(ME4600_DIO_CTRL_BIT_MODE_0 |
-				      ME4600_DIO_CTRL_BIT_MODE_1 |
-				      ME4600_DIO_CTRL_BIT_FUNCTION_0 |
-				      ME4600_DIO_CTRL_BIT_FUNCTION_1 |
-				      ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-
-				if (ref == ME_REF_DIO_FIFO_LOW) {
-					mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
-						 ME4600_DIO_CTRL_BIT_MODE_1 |
-						 ME4600_DIO_CTRL_BIT_FUNCTION_0);
-				} else if (ref == ME_REF_DIO_FIFO_HIGH) {
-					mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
-						 ME4600_DIO_CTRL_BIT_MODE_1 |
-						 ME4600_DIO_CTRL_BIT_FUNCTION_0
-						 |
-						 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-				} else {
-					PERROR
-					    ("Invalid port reference specified.\n");
-					err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-				}
-			} else if (single_config ==
-				   ME_SINGLE_CONFIG_DIO_BIT_PATTERN) {
-				mode &=
-				    ~(ME4600_DIO_CTRL_BIT_MODE_0 |
-				      ME4600_DIO_CTRL_BIT_MODE_1 |
-				      ME4600_DIO_CTRL_BIT_FUNCTION_0 |
-				      ME4600_DIO_CTRL_BIT_FUNCTION_1 |
-				      ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-
-				if (ref == ME_REF_DIO_FIFO_LOW) {
-					mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
-						 ME4600_DIO_CTRL_BIT_MODE_1);
-				} else if (ref == ME_REF_DIO_FIFO_HIGH) {
-					mode |= (ME4600_DIO_CTRL_BIT_MODE_0 |
-						 ME4600_DIO_CTRL_BIT_MODE_1 |
-						 ME4600_DIO_CTRL_BIT_FIFO_HIGH_0);
-				} else {
-					PERROR
-					    ("Invalid port reference specified.\n");
-					err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-				}
-			} else {
-				PERROR("Invalid port direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!err) {
-		outl(mode, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, mode);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_do_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me4600_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode =
-	    inl(instance->
-		ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
-			     ME4600_DIO_CTRL_BIT_MODE_1);
-
-	if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
-		switch (flags) {
-		case ME_IO_SINGLE_TYPE_DIO_BIT:
-			if ((channel >= 0) && (channel < 8)) {
-				*value =
-				    inl(instance->port_reg) & (0x1 << channel);
-			} else {
-				PERROR("Invalid bit number specified.\n");
-				err = ME_ERRNO_INVALID_CHANNEL;
-			}
-			break;
-
-		case ME_IO_SINGLE_NO_FLAGS:
-		case ME_IO_SINGLE_TYPE_DIO_BYTE:
-			if (channel == 0) {
-				*value = inl(instance->port_reg) & 0xFF;
-			} else {
-				PERROR("Invalid byte number specified.\n");
-				err = ME_ERRNO_INVALID_CHANNEL;
-			}
-			break;
-
-		default:
-			PERROR("Invalid flags specified.\n");
-			err = ME_ERRNO_INVALID_FLAGS;
-		}
-	} else {
-		PERROR("Port not in output mode.\n");
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_do_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me4600_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t byte;
-	uint32_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode =
-	    inl(instance->
-		ctrl_reg) & (ME4600_DIO_CTRL_BIT_MODE_0 |
-			     ME4600_DIO_CTRL_BIT_MODE_1);
-
-	if (mode == ME4600_DIO_CTRL_BIT_MODE_0) {
-		switch (flags) {
-
-		case ME_IO_SINGLE_TYPE_DIO_BIT:
-			if ((channel >= 0) && (channel < 8)) {
-				byte = inl(instance->port_reg) & 0xFF;
-
-				if (value)
-					byte |= 0x1 << channel;
-				else
-					byte &= ~(0x1 << channel);
-
-				outl(byte, instance->port_reg);
-			} else {
-				PERROR("Invalid bit number specified.\n");
-				err = ME_ERRNO_INVALID_CHANNEL;
-			}
-			break;
-
-		case ME_IO_SINGLE_NO_FLAGS:
-		case ME_IO_SINGLE_TYPE_DIO_BYTE:
-			if (channel == 0) {
-				outl(value, instance->port_reg);
-			} else {
-				PERROR("Invalid byte number specified.\n");
-				err = ME_ERRNO_INVALID_CHANNEL;
-			}
-			break;
-
-		default:
-			PERROR("Invalid flags specified.\n");
-			err = ME_ERRNO_INVALID_FLAGS;
-		}
-	} else {
-		PERROR("Port not in output mode.\n");
-		err = ME_ERRNO_PREVIOUS_CONFIG;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_do_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_do_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
-					     spinlock_t *ctrl_reg_lock)
-{
-	me4600_do_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me4600_do_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me4600_do_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save the subdevice index */
-	subdevice->ctrl_reg = reg_base + ME4600_DIO_CTRL_REG;
-	subdevice->port_reg = reg_base + ME4600_DIO_PORT_0_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me4600_do_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me4600_do_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me4600_do_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me4600_do_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me4600_do_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me4600_do_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me4600_do_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_do.h b/drivers/staging/meilhaus/me4600_do.h
deleted file mode 100644
index e838564..0000000
--- a/drivers/staging/meilhaus/me4600_do.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file me4600_do.h
- *
- * @brief ME-4000 digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_DO_H_
-#define _ME4600_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me4600_do_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-
-	unsigned long port_reg;			/**< Register holding the port status. */
-	unsigned long ctrl_reg;			/**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me4600_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-4000 digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
-					     spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.c b/drivers/staging/meilhaus/me4600_ext_irq.c
deleted file mode 100644
index cfb4adb..0000000
--- a/drivers/staging/meilhaus/me4600_ext_irq.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/**
- * @file me4600_ext_irq.c
- *
- * @brief ME-4000 external interrupt subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meids.h"
-#include "me4600_reg.h"
-#include "me4600_ai_reg.h"
-#include "me4600_ext_irq_reg.h"
-#include "me4600_ext_irq.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me4600_ext_irq_io_irq_start(me_subdevice_t *subdevice,
-				       struct file *filep,
-				       int channel,
-				       int irq_source,
-				       int irq_edge, int irq_arg, int flags)
-{
-	me4600_ext_irq_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags;
-	uint32_t tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((irq_edge != ME_IRQ_EDGE_RISING)
-	    && (irq_edge != ME_IRQ_EDGE_FALLING)
-	    && (irq_edge != ME_IRQ_EDGE_ANY)
-	    ) {
-		PERROR("Invalid irq edge specified.\n");
-		return ME_ERRNO_INVALID_IRQ_EDGE;
-	}
-
-	if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
-		PERROR("Invalid irq source specified.\n");
-		return ME_ERRNO_INVALID_IRQ_SOURCE;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	tmp = 0x0;		//inl(instance->ext_irq_config_reg);
-
-	if (irq_edge == ME_IRQ_EDGE_RISING) {
-		//tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
-		//tmp |= ME4600_EXT_IRQ_CONFIG_MASK_RISING;
-	} else if (irq_edge == ME_IRQ_EDGE_FALLING) {
-		//tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
-		//tmp |= ME4600_EXT_IRQ_CONFIG_MASK_FALLING;
-		tmp = ME4600_EXT_IRQ_CONFIG_MASK_FALLING;
-	} else if (irq_edge == ME_IRQ_EDGE_ANY) {
-		//tmp &= ~ME4600_EXT_IRQ_CONFIG_MASK;
-		//tmp |= ME4600_EXT_IRQ_CONFIG_MASK_ANY;
-		tmp = ME4600_EXT_IRQ_CONFIG_MASK_ANY;
-	}
-
-	outl(tmp, instance->ext_irq_config_reg);
-	PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->ext_irq_config_reg - instance->reg_base, tmp);
-
-	spin_lock_irqsave(instance->ctrl_reg_lock, cpu_flags);
-	tmp = inl(instance->ctrl_reg);
-	tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
-	tmp |= ME4600_AI_CTRL_BIT_EX_IRQ;
-	outl(tmp, instance->ctrl_reg);
-	spin_unlock_irqrestore(instance->ctrl_reg_lock, cpu_flags);
-	instance->rised = 0;
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ext_irq_io_irq_wait(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int *irq_count,
-				      int *value, int time_out, int flags)
-{
-	me4600_ext_irq_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->rised <= 0) {
-		instance->rised = 0;
-		if (time_out) {
-			t = wait_event_interruptible_timeout(instance->
-							     wait_queue,
-							     (instance->rised !=
-							      0), t);
-
-			if (t == 0) {
-				PERROR
-				    ("Wait on external interrupt timed out.\n");
-				err = ME_ERRNO_TIMEOUT;
-			}
-		} else {
-			wait_event_interruptible(instance->wait_queue,
-						 (instance->rised != 0));
-		}
-
-		if (instance->rised < 0) {
-			PERROR("Wait on interrupt aborted by user.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-	}
-
-	if (signal_pending(current)) {
-		PERROR("Wait on external interrupt aborted by signal.\n");
-		err = ME_ERRNO_SIGNAL;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	instance->rised = 0;
-	*irq_count = instance->count;
-	*value = instance->value;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ext_irq_io_irq_stop(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int channel, int flags)
-{
-	me4600_ext_irq_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags;
-	uint32_t tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->ctrl_reg_lock);
-	tmp = inl(instance->ctrl_reg);
-	tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->ctrl_reg_lock);
-	instance->rised = -1;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t *subdevice,
-					     struct file *filep, int flags)
-{
-	me4600_ext_irq_subdevice_t *instance;
-	unsigned long cpu_flags;
-	uint32_t tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me4600_ext_irq_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->ctrl_reg_lock);
-	tmp = inl(instance->ctrl_reg);
-	tmp &= ~(ME4600_AI_CTRL_BIT_EX_IRQ | ME4600_AI_CTRL_BIT_EX_IRQ_RESET);
-	outl(tmp, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_regv outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->ctrl_reg_lock);
-	instance->rised = -1;
-	instance->count = 0;
-	outl(ME4600_EXT_IRQ_CONFIG_MASK_ANY, instance->ext_irq_config_reg);
-	PDEBUG_REG("ext_irq_config_reg outl(0x%lX+0x%lX)=0x%x\n",
-		   instance->reg_base,
-		   instance->ext_irq_config_reg - instance->reg_base,
-		   ME4600_EXT_IRQ_CONFIG_MASK_ANY);
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static void me4600_ext_irq_destructor(struct me_subdevice *subdevice)
-{
-	me4600_ext_irq_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-	instance = (me4600_ext_irq_subdevice_t *) subdevice;
-	me_subdevice_deinit(&instance->base);
-	free_irq(instance->irq, instance);
-	kfree(instance);
-}
-
-static int me4600_ext_irq_query_number_channels(me_subdevice_t *subdevice,
-						int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 1;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ext_irq_query_subdevice_type(me_subdevice_t *subdevice,
-					       int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_EXT_IRQ;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t *subdevice,
-					       int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps =
-	    ME_CAPS_EXT_IRQ_EDGE_RISING | ME_CAPS_EXT_IRQ_EDGE_FALLING |
-	    ME_CAPS_EXT_IRQ_EDGE_ANY;
-	return ME_ERRNO_SUCCESS;
-}
-
-static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id)
-{
-	me4600_ext_irq_subdevice_t *instance;
-	uint32_t ctrl;
-	uint32_t irq_status;
-
-	instance = (me4600_ext_irq_subdevice_t *) dev_id;
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	irq_status = inl(instance->irq_status_reg);
-	if (!(irq_status & ME4600_IRQ_STATUS_BIT_EX)) {
-		PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
-		      jiffies, __func__, irq_status);
-		return IRQ_NONE;
-	}
-
-	PDEBUG("executed.\n");
-
-	spin_lock(&instance->subdevice_lock);
-	instance->rised = 1;
-	instance->value = inl(instance->ext_irq_value_reg);
-	instance->count++;
-
-	spin_lock(instance->ctrl_reg_lock);
-	ctrl = inl(instance->ctrl_reg);
-	ctrl |= ME4600_AI_CTRL_BIT_EX_IRQ_RESET;
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	ctrl &= ~ME4600_AI_CTRL_BIT_EX_IRQ_RESET;
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	spin_unlock(&instance->subdevice_lock);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base,
-						       int irq,
-						       spinlock_t *
-						       ctrl_reg_lock)
-{
-	me4600_ext_irq_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me4600_ext_irq_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me4600_ext_irq_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Initialize wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	/* Register interrupt */
-	subdevice->irq = irq;
-
-	if (request_irq(subdevice->irq, me4600_ext_irq_isr,
-			IRQF_DISABLED | IRQF_SHARED,
-			ME4600_NAME, subdevice)) {
-		PERROR("Cannot register interrupt.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	PINFO("Registered irq=%d.\n", subdevice->irq);
-
-	/* Initialize registers */
-	subdevice->irq_status_reg = reg_base + ME4600_IRQ_STATUS_REG;
-	subdevice->ctrl_reg = reg_base + ME4600_AI_CTRL_REG;
-	subdevice->ext_irq_config_reg = reg_base + ME4600_EXT_IRQ_CONFIG_REG;
-	subdevice->ext_irq_value_reg = reg_base + ME4600_EXT_IRQ_VALUE_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Override base class methods. */
-	subdevice->base.me_subdevice_destructor = me4600_ext_irq_destructor;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me4600_ext_irq_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_irq_start = me4600_ext_irq_io_irq_start;
-	subdevice->base.me_subdevice_io_irq_wait = me4600_ext_irq_io_irq_wait;
-	subdevice->base.me_subdevice_io_irq_stop = me4600_ext_irq_io_irq_stop;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me4600_ext_irq_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me4600_ext_irq_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me4600_ext_irq_query_subdevice_caps;
-
-	subdevice->rised = 0;
-	subdevice->count = 0;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.h b/drivers/staging/meilhaus/me4600_ext_irq.h
deleted file mode 100644
index 3c7b27f..0000000
--- a/drivers/staging/meilhaus/me4600_ext_irq.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file me4600_ext_irq.h
- *
- * @brief Meilhaus ME-4000 external interrupt subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_EXT_IRQ_H_
-#define _ME4600_EXT_IRQ_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The subdevice class.
- */
-typedef struct me4600_ext_irq_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-
-	wait_queue_head_t wait_queue;
-
-	int irq;
-
-	int rised;
-	int value;
-	int count;
-
-	unsigned long ctrl_reg;
-	unsigned long irq_status_reg;
-	unsigned long ext_irq_config_reg;
-	unsigned long ext_irq_value_reg;
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me4600_ext_irq_subdevice_t;
-
-/**
- * @brief The constructor to generate a external interrupt subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param irq The interrupt number assigned by the PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me4600_ext_irq_subdevice_t *me4600_ext_irq_constructor(uint32_t reg_base,
-						       int irq,
-						       spinlock_t *
-						       ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_ext_irq_reg.h b/drivers/staging/meilhaus/me4600_ext_irq_reg.h
deleted file mode 100644
index 898e1e7..0000000
--- a/drivers/staging/meilhaus/me4600_ext_irq_reg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file me4600_ext_irq_reg.h
- *
- * @brief ME-4000 external interrupt subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_EXT_IRQ_REG_H_
-#define _ME4600_EXT_IRQ_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_EXT_IRQ_CONFIG_REG		0xCC	// R/_
-#define ME4600_EXT_IRQ_VALUE_REG		0xD0	// R/_
-
-#define ME4600_EXT_IRQ_CONFIG_MASK_RISING	0x0
-#define ME4600_EXT_IRQ_CONFIG_MASK_FALLING	0x1
-#define ME4600_EXT_IRQ_CONFIG_MASK_ANY		0x3
-#define ME4600_EXT_IRQ_CONFIG_MASK		0x3
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me4600_reg.h b/drivers/staging/meilhaus/me4600_reg.h
deleted file mode 100644
index ae152bb..0000000
--- a/drivers/staging/meilhaus/me4600_reg.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file me4600_reg.h
- *
- * @brief ME-4000 register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME4600_REG_H_
-#define _ME4600_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME4600_IRQ_STATUS_REG			0x9C	// R/_
-
-#define ME4600_IRQ_STATUS_BIT_EX		0x01
-#define ME4600_IRQ_STATUS_BIT_LE		0x02
-#define ME4600_IRQ_STATUS_BIT_AI_HF		0x04
-#define ME4600_IRQ_STATUS_BIT_AO_0_HF	0x08
-#define ME4600_IRQ_STATUS_BIT_AO_1_HF	0x10
-#define ME4600_IRQ_STATUS_BIT_AO_2_HF	0x20
-#define ME4600_IRQ_STATUS_BIT_AO_3_HF	0x40
-#define ME4600_IRQ_STATUS_BIT_SC		0x80
-
-#define ME4600_IRQ_STATUS_BIT_AO_HF		ME4600_IRQ_STATUS_BIT_AO_0_HF
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_ao.c b/drivers/staging/meilhaus/me6000_ao.c
deleted file mode 100644
index 66652dc..0000000
--- a/drivers/staging/meilhaus/me6000_ao.c
+++ /dev/null
@@ -1,3709 +0,0 @@
-/**
- * @file me6000_ao.c
- *
- * @brief ME-6000 analog output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/* Includes
- */
-#include <linux/version.h>
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <linux/workqueue.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meids.h"
-#include "me6000_reg.h"
-#include "me6000_ao_reg.h"
-#include "me6000_ao.h"
-
-/* Defines
- */
-
-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,
-					 int unit, int *count);
-
-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,
-				 int timer,
-				 int *base_frequency,
-				 long long *min_ticks, long long *max_ticks);
-
-static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
-					   int *number);
-
-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,
-					  int *caps);
-
-static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
-					       int cap, int *args, int count);
-
-/** Remove subdevice. */
-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,
-					struct file *filep, int flags);
-
-/** Set output as single */
-static int me6000_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);
-
-/** Pass to user actual value of output. */
-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,
-				     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,
-				      struct file *filep,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      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,
-					  struct file *filep,
-					  int time_out, int *count, int flags);
-
-/** Start streaming. */
-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,
-				      struct file *filep,
-				      int wait,
-				      int *status, int *values, int flags);
-
-/** Stop streaming. */
-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,
-				     struct file *filep,
-				     int write_mode,
-				     int *values, int *count, int flags);
-
-/** Interrupt handler. Copy from buffer to FIFO. */
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id);
-
-/** Copy data from circular buffer to fifo (fast) in wraparound mode. */
-inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
-				    int start_pos);
-
-/** Copy data from circular buffer to fifo (fast).*/
-inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
-			 int start_pos);
-
-/** Copy data from circular buffer to fifo (slow).*/
-inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
-				 int start_pos);
-
-/** Copy data from user space to circular buffer. */
-inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
-				 int *user_values);
-
-/** Stop presentation. Preserve FIFOs. */
-inline int ao_stop_immediately(me6000_ao_subdevice_t *instance);
-
-/** Function for checking timeout in non-blocking mode. */
-static void me6000_ao_work_control_task(struct work_struct *work);
-
-/* Functions
- */
-
-static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
-					struct file *filep, int flags)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t tmp;
-	uint32_t ctrl;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	instance->status = ao_status_none;
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-	instance->timeout.delay = 0;
-	instance->timeout.start_time = jiffies;
-
-	//Stop state machine.
-	err = ao_stop_immediately(instance);
-
-	//Remove from synchronous start.
-	spin_lock(instance->preload_reg_lock);
-	tmp = inl(instance->preload_reg);
-	tmp &=
-	    ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
-	      ao_idx);
-	outl(tmp, instance->preload_reg);
-	PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, tmp);
-	*instance->preload_flags &=
-	    ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
-	      ao_idx);
-
-	//Reset triggering flag
-	*instance->triggering_flags &= ~(0x1 << instance->ao_idx);
-	spin_unlock(instance->preload_reg_lock);
-
-	if (instance->fifo) {
-		//Set single mode, dissable FIFO, dissable external trigger, block interrupt.
-		ctrl = ME6000_AO_MODE_SINGLE;
-
-		//Block ISM.
-		ctrl |=
-		    (ME6000_AO_CTRL_BIT_STOP |
-		     ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
-
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		//Set speed
-		outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
-		//Reset interrupt latch
-		inl(instance->irq_reset_reg);
-	}
-
-	instance->hardware_stop_delay = HZ / 10;	//100ms
-
-	//Set output to 0V
-	outl(0x8000, instance->single_reg);
-	PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->single_reg - instance->reg_base, 0x8000);
-
-	instance->circ_buf.head = 0;
-	instance->circ_buf.tail = 0;
-	instance->preloaded_count = 0;
-	instance->data_count = 0;
-	instance->single_value = 0x8000;
-	instance->single_value_in_fifo = 0x8000;
-
-	//Set status to signal that device is unconfigured.
-	instance->status = ao_status_none;
-	//Signal reset if user is on wait.
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_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)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t ctrl;
-	uint32_t sync;
-	unsigned long cpu_flags;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. ID=%d\n", instance->ao_idx);
-
-	// Checking parameters
-	if (flags) {
-		PERROR
-		    ("Invalid flag specified. Must be ME_IO_SINGLE_CONFIG_NO_FLAGS.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (instance->fifo) {	//Stream hardware (with or without fifo)
-		if ((trig_edge == ME_TRIG_TYPE_SW)
-		    && (trig_edge != ME_TRIG_EDGE_NONE)) {
-			PERROR
-			    ("Invalid trigger edge. Software trigger has not edge.\n");
-			return ME_ERRNO_INVALID_TRIG_EDGE;
-		}
-
-		if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
-			switch (trig_edge) {
-			case ME_TRIG_EDGE_ANY:
-			case ME_TRIG_EDGE_RISING:
-			case ME_TRIG_EDGE_FALLING:
-				break;
-
-			default:
-				PERROR("Invalid trigger edge.\n");
-				return ME_ERRNO_INVALID_TRIG_EDGE;
-			}
-		}
-
-		if ((trig_type != ME_TRIG_TYPE_SW)
-		    && (trig_type != ME_TRIG_TYPE_EXT_DIGITAL)) {
-			PERROR
-			    ("Invalid trigger type. Trigger must be software or digital.\n");
-			return ME_ERRNO_INVALID_TRIG_TYPE;
-		}
-	} else {		//Single
-		if (trig_edge != ME_TRIG_EDGE_NONE) {
-			PERROR
-			    ("Invalid trigger edge. Single output trigger hasn't own edge.\n");
-			return ME_ERRNO_INVALID_TRIG_EDGE;
-		}
-
-		if (trig_type != ME_TRIG_TYPE_SW) {
-			PERROR
-			    ("Invalid trigger type. Trigger must be software.\n");
-			return ME_ERRNO_INVALID_TRIG_TYPE;
-		}
-
-	}
-
-	if ((trig_chan != ME_TRIG_CHAN_DEFAULT)
-	    && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS)) {
-		PERROR("Invalid trigger channel specified.\n");
-		return ME_ERRNO_INVALID_TRIG_CHAN;
-	}
-/*
-	if ((trig_type == ME_TRIG_TYPE_EXT_DIGITAL) && (trig_chan != ME_TRIG_CHAN_SYNCHRONOUS))
-	{
-		PERROR("Invalid trigger channel specified. Must be synchronous when digital is choose.\n");
-		return ME_ERRNO_INVALID_TRIG_CHAN;
-	}
-*/
-	if (ref != ME_REF_AO_GROUND) {
-		PERROR
-		    ("Invalid reference. Analog outputs have to have got REF_AO_GROUND.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if (single_config != 0) {
-		PERROR
-		    ("Invalid single config specified. Only one range for anlog outputs is available.\n");
-		return ME_ERRNO_INVALID_SINGLE_CONFIG;
-	}
-
-	if (channel != 0) {
-		PERROR
-		    ("Invalid channel number specified. Analog output have only one channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	//Subdevice running in stream mode!
-	if ((instance->status >= ao_status_stream_run_wait)
-	    && (instance->status < ao_status_stream_end)) {
-		PERROR("Subdevice is busy.\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-/// @note For single all calls (config and write) are erasing previous state!
-
-	instance->status = ao_status_none;
-
-	// Correct single mirrors
-	instance->single_value_in_fifo = instance->single_value;
-
-	//Stop device
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-
-	if (instance->fifo) {	// Set control register.
-		spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-		// Set stop bit. Stop streaming mode (If running.).
-		ctrl = inl(instance->ctrl_reg);
-		//Reset all bits.
-		ctrl =
-		    ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
-		if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL) {
-			PINFO("External digital trigger.\n");
-
-			if (trig_edge == ME_TRIG_EDGE_ANY) {
-//                                      ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-				instance->ctrl_trg =
-				    ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
-				    ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-			} else if (trig_edge == ME_TRIG_EDGE_FALLING) {
-//                                      ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
-				instance->ctrl_trg =
-				    ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
-			} else if (trig_edge == ME_TRIG_EDGE_RISING) {
-				instance->ctrl_trg = 0x0;
-			}
-		} else if (trig_type == ME_TRIG_TYPE_SW) {
-			PDEBUG("SOFTWARE TRIGGER\n");
-			instance->ctrl_trg = 0x0;
-		}
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	} else {
-		PDEBUG("SOFTWARE TRIGGER\n");
-	}
-
-	// Set preload/synchronization register.
-	spin_lock(instance->preload_reg_lock);
-
-	if (trig_type == ME_TRIG_TYPE_SW) {
-		*instance->preload_flags &=
-		    ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx);
-	} else			//if (trig_type == ME_TRIG_TYPE_EXT_DIGITAL)
-	{
-		*instance->preload_flags |=
-		    ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx;
-	}
-
-	if (trig_chan == ME_TRIG_CHAN_DEFAULT) {
-		*instance->preload_flags &=
-		    ~(ME6000_AO_SYNC_HOLD << instance->ao_idx);
-	} else			//if (trig_chan == ME_TRIG_CHAN_SYNCHRONOUS)
-	{
-		*instance->preload_flags |=
-		    ME6000_AO_SYNC_HOLD << instance->ao_idx;
-	}
-
-	//Reset hardware register
-	sync = inl(instance->preload_reg);
-	PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, sync);
-	sync &= ~(ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx);
-	sync |= ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
-	//Output configured in default mode (safe one)
-	outl(sync, instance->preload_reg);
-	PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, sync);
-	spin_unlock(instance->preload_reg_lock);
-
-	instance->status = ao_status_single_configured;
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	unsigned long j;
-	unsigned long delay = 0;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags & ~ME_IO_SINGLE_NONBLOCKING) {
-		PERROR("Invalid flag specified. %d\n", flags);
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((instance->status >= ao_status_stream_configured)
-	    && (instance->status <= ao_status_stream_end)) {
-		PERROR("Subdevice not configured to work in single mode!\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	if (channel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	ME_SUBDEVICE_ENTER;
-	if ((!flags) && (instance->status == ao_status_single_run_wait)) {	//Blocking mode. Wait for trigger.
-		if (time_out) {
-			delay = (time_out * HZ) / 1000;
-			if (delay == 0)
-				delay = 1;
-		}
-
-		j = jiffies;
-
-		//Only runing process will interrupt this call. Events are signaled when status change. This procedure has own timeout.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_single_run_wait),
-						 (delay) ? delay : LONG_MAX);
-
-		if (instance->status == ao_status_none) {
-			PDEBUG("Single canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		if ((delay) && ((jiffies - j) >= delay)) {
-			PDEBUG("Timeout reached.\n");
-			err = ME_ERRNO_TIMEOUT;
-		}
-
-		*value =
-		    (!err) ? instance->single_value_in_fifo : instance->
-		    single_value;
-	} else {		//Non-blocking mode
-		//Read value
-		*value = instance->single_value;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags;
-	unsigned long j;
-	unsigned long delay = 0;
-
-	uint32_t sync_mask;
-	uint32_t mode;
-
-	uint32_t tmp;
-
-/// Workaround for mix-mode - begin
-	uint32_t ctrl = 0x0;
-	uint32_t status;
-/// Workaround for mix-mode - end
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags &
-	    ~(ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS |
-	      ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((instance->status == ao_status_none)
-	    || (instance->status > ao_status_single_end)) {
-		PERROR("Subdevice not configured to work in single mode!\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	if (channel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (value & ~ME6000_AO_MAX_DATA) {
-		PERROR("Invalid value provided.\n");
-		return ME_ERRNO_VALUE_OUT_OF_RANGE;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-/// @note For single all calls (config and write) are erasing previous state!
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-
-	// Correct single mirrors
-	instance->single_value_in_fifo = instance->single_value;
-
-	//Stop device
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-
-		if (delay == 0)
-			delay = 1;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-
-	instance->single_value_in_fifo = value;
-
-	if (instance->fifo) {
-		ctrl = inl(instance->ctrl_reg);
-	}
-
-	if (instance->fifo & ME6000_AO_HAS_FIFO) {	/// Workaround for mix-mode - begin
-		//Set speed
-		outl(ME6000_AO_MIN_CHAN_TICKS - 1, instance->timer_reg);
-		PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->timer_reg - instance->reg_base,
-			   (int)ME6000_AO_MIN_CHAN_TICKS);
-		instance->hardware_stop_delay = HZ / 10;	//100ms
-
-		status = inl(instance->status_reg);
-
-		//Set the continous mode.
-		ctrl &= ~ME6000_AO_CTRL_MODE_MASK;
-		ctrl |= ME6000_AO_MODE_CONTINUOUS;
-
-		//Prepare FIFO
-		if (!(ctrl & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) {	//FIFO wasn't enabeled. Do it.
-			PINFO("Enableing FIFO.\n");
-			ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-			ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
-		} else {	//Check if FIFO is empty
-			if (status & ME6000_AO_STATUS_BIT_EF) {	//FIFO not empty
-				PINFO("Reseting FIFO.\n");
-				ctrl &=
-				    ~(ME6000_AO_CTRL_BIT_ENABLE_FIFO |
-				      ME6000_AO_CTRL_BIT_ENABLE_IRQ);
-				outl(ctrl, instance->ctrl_reg);
-				PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->ctrl_reg -
-					   instance->reg_base, ctrl);
-
-				ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
-			} else {	//FIFO empty, only interrupt needs to be disabled!
-				ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-			}
-		}
-
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		//Reset interrupt latch
-		inl(instance->irq_reset_reg);
-
-		//Write output - 1 value to FIFO
-		if (instance->ao_idx & 0x1) {
-			outl(value <<= 16, instance->fifo_reg);
-			PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->fifo_reg - instance->reg_base,
-				   value <<= 16);
-		} else {
-			outl(value, instance->fifo_reg);
-			PDEBUG_REG("fifo_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->fifo_reg - instance->reg_base,
-				   value);
-		}
-		/// Workaround for mix-mode - end
-	} else {		//No FIFO - always in single mode
-		//Write value
-		PDEBUG("Write value\n");
-		outl(value, instance->single_reg);
-		PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->single_reg - instance->reg_base, value);
-	}
-
-	mode = *instance->preload_flags >> instance->ao_idx;
-	mode &= (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG);
-
-	PINFO("Triggering mode: 0x%08x\n", mode);
-
-	spin_lock(instance->preload_reg_lock);
-	sync_mask = inl(instance->preload_reg);
-	PDEBUG_REG("preload_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, sync_mask);
-	switch (mode) {
-	case 0:		//0x00000000: Individual software
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-		if (instance->fifo & ME6000_AO_HAS_FIFO) {	// FIFO - Continous mode
-			ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-			if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) {	//Now we can set correct mode.
-				sync_mask &=
-				    ~((ME6000_AO_SYNC_EXT_TRIG |
-				       ME6000_AO_SYNC_HOLD) << instance->
-				      ao_idx);
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		} else {	// No FIFO - Single mode: In this case resetting 'ME6000_AO_SYNC_HOLD' will trigger output.
-			if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != ME6000_AO_SYNC_HOLD) {	//Now we can set correct mode. This is exception. It is set to synchronous and triggered later.
-				sync_mask &=
-				    ~(ME6000_AO_SYNC_EXT_TRIG << instance->
-				      ao_idx);
-				sync_mask |=
-				    ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		}
-		instance->single_value = value;
-		break;
-
-	case ME6000_AO_SYNC_EXT_TRIG:	//0x00010000: Individual hardware
-		PDEBUG("DIGITAL TRIGGER\n");
-		ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-		if (instance->fifo & ME6000_AO_HAS_FIFO) {	// FIFO - Continous mode
-			if ((sync_mask & ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->ao_idx)) != 0x0) {	//Now we can set correct mode.
-				sync_mask &=
-				    ~((ME6000_AO_SYNC_EXT_TRIG |
-				       ME6000_AO_SYNC_HOLD) << instance->
-				      ao_idx);
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		} else {	// No FIFO - Single mode
-			if ((sync_mask &
-			     ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
-			      instance->ao_idx)) != ME6000_AO_SYNC_HOLD) {
-				//Now we can set correct mode
-				sync_mask &=
-				    ~(ME6000_AO_SYNC_EXT_TRIG << instance->
-				      ao_idx);
-				sync_mask |=
-				    ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
-				outl(sync_mask, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     sync_mask);
-			}
-		}
-		break;
-
-	case ME6000_AO_SYNC_HOLD:	//0x00000001: Synchronous software
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-		if ((sync_mask &
-		     ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
-		      instance->ao_idx)) !=
-		    (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) {
-			//Now we can set correct mode
-			sync_mask |=
-			    ME6000_AO_SYNC_EXT_TRIG << instance->ao_idx;
-			sync_mask |= ME6000_AO_SYNC_HOLD << instance->ao_idx;
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-		}
-		//Set triggering flag
-		*instance->triggering_flags |= 0x1 << instance->ao_idx;
-		break;
-
-	case (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG):	//0x00010001: Synchronous hardware
-		PDEBUG("DIGITAL TRIGGER\n");
-		ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-
-		if ((sync_mask &
-		     ((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
-		      instance->ao_idx)) !=
-		    (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG)) {
-			//Now we can set correct mode
-			sync_mask |=
-			    (ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
-			    instance->ao_idx;
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-		}
-		//Set triggering flag
-		*instance->triggering_flags |= 0x1 << instance->ao_idx;
-		break;
-	}
-//              spin_unlock(instance->preload_reg_lock);        // Moved down.
-
-	if (instance->fifo) {	//Activate ISM (remove 'stop' bits)
-		ctrl &=
-		    ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
-		      ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
-		ctrl |= instance->ctrl_trg;
-		ctrl &=
-		    ~(ME6000_AO_CTRL_BIT_STOP |
-		      ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
-
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-	}
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-/// @note When flag 'ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS' is set than output is triggered. ALWAYS!
-
-	PINFO("<%s> start mode= 0x%08x %s\n", __func__, mode,
-	      (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" :
-	      "");
-	if (instance->fifo & ME6000_AO_HAS_FIFO) {	// FIFO - Continous mode
-		if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {	//Trigger outputs
-			//Add channel to start list
-			outl(sync_mask |
-			     (ME6000_AO_SYNC_HOLD << instance->ao_idx),
-			     instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask | (ME6000_AO_SYNC_HOLD <<
-						instance->ao_idx));
-
-			//Fire
-			PINFO
-			    ("Fired all software synchronous outputs by software trigger.\n");
-			outl(0x8000, instance->single_reg);
-			PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->single_reg - instance->reg_base,
-				   0x8000);
-
-			//Restore save settings
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-
-		} else if (!mode) {	//Trigger outputs
-/*			//Remove channel from start list
-			outl(sync_mask & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx));
-*/
-			//Fire
-			PINFO("Software trigger.\n");
-			outl(0x8000, instance->single_reg);
-			PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->single_reg - instance->reg_base,
-				   0x8000);
-
-/*			//Restore save settings
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, sync_mask);
-*/
-		}
-/// @note This is mix-mode case. For now I do not have possibility to trigger first 4 channels (continous mode) and other (single) ones at once.
-/// @note Because triggering is not working it can not be add to synchronous list. First 4 channels don't need this information, anyway.
-		*instance->triggering_flags &= 0xFFFFFFF0;
-	} else {		// No FIFO - Single mode
-		if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {	//Fired all software synchronous outputs.
-			tmp = ~(*instance->preload_flags | 0xFFFF0000);
-			PINFO
-			    ("Fired all software synchronous outputs. mask:0x%08x\n",
-			     tmp);
-			tmp |= sync_mask & 0xFFFF0000;
-			// Add this channel to list
-			tmp &= ~(ME6000_AO_SYNC_HOLD << instance->ao_idx);
-
-			//Fire
-			PINFO("Software trigger.\n");
-			outl(tmp, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   tmp);
-
-			//Restore save settings
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-
-			//Set all as triggered.
-			*instance->triggering_flags = 0x0;
-		} else if (!mode) {	// Add this channel to list
-			outl(sync_mask &
-			     ~(ME6000_AO_SYNC_HOLD << instance->ao_idx),
-			     instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask & ~(ME6000_AO_SYNC_HOLD <<
-						 instance->ao_idx));
-
-			//Fire
-			PINFO("Software trigger.\n");
-
-			//Restore save settings
-			outl(sync_mask, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   sync_mask);
-
-			//Set all as triggered.
-			*instance->triggering_flags = 0x0;
-		}
-
-	}
-	spin_unlock(instance->preload_reg_lock);
-
-	instance->status = ao_status_single_run_wait;
-
-	instance->timeout.delay = delay;
-	instance->timeout.start_time = jiffies;
-	instance->ao_control_task_flag = 1;
-	queue_delayed_work(instance->me6000_workqueue,
-			   &instance->ao_control_task, 1);
-
-	if (!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) {
-		j = jiffies;
-
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_single_run_wait),
-						 (delay) ? delay +
-						 1 : LONG_MAX);
-
-		if (instance->status != ao_status_single_end) {
-			PDEBUG("Single canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			instance->ao_control_task_flag = 0;
-			cancel_delayed_work(&instance->ao_control_task);
-			ao_stop_immediately(instance);
-			instance->status = ao_status_none;
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		if ((delay) && ((jiffies - j) >= delay)) {
-			if (instance->status == ao_status_single_end) {
-				PDEBUG("Timeout reached.\n");
-			} else if ((jiffies - j) > delay) {
-				PERROR
-				    ("Timeout reached. Not handled by control task!\n");
-				ao_stop_immediately(instance);
-			} else {
-				PERROR
-				    ("Timeout reached. Signal come but status is strange: %d\n",
-				     instance->status);
-				ao_stop_immediately(instance);
-			}
-
-			instance->ao_control_task_flag = 0;
-			cancel_delayed_work(&instance->ao_control_task);
-			instance->status = ao_status_single_end;
-			err = ME_ERRNO_TIMEOUT;
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      meIOStreamTrigger_t *trigger,
-				      int fifo_irq_threshold, int flags)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t ctrl;
-	unsigned long cpu_flags;
-	uint64_t conv_ticks;
-	unsigned int conv_start_ticks_low = trigger->iConvStartTicksLow;
-	unsigned int conv_start_ticks_high = trigger->iConvStartTicksHigh;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	conv_ticks =
-	    (uint64_t) conv_start_ticks_low +
-	    ((uint64_t) conv_start_ticks_high << 32);
-
-	if (flags &
-	    ~(ME_IO_STREAM_CONFIG_HARDWARE_ONLY |
-	      ME_IO_STREAM_CONFIG_WRAPAROUND)) {
-		PERROR("Invalid flags.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
-		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;
-		}
-
-		if ((trigger->iAcqStopTrigType != ME_TRIG_TYPE_NONE)
-		    || (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE)) {
-			PERROR
-			    ("Hardware wraparound mode must be in infinite mode.\n");
-			return ME_ERRNO_INVALID_FLAGS;
-		}
-	}
-
-	if (count != 1) {
-		PERROR("Only 1 entry in config list acceptable.\n");
-		return ME_ERRNO_INVALID_CONFIG_LIST_COUNT;
-	}
-
-	if (config_list[0].iChannel != 0) {
-		PERROR("Invalid channel number specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (config_list[0].iStreamConfig != 0) {
-		PERROR("Only one range available.\n");
-		return ME_ERRNO_INVALID_STREAM_CONFIG;
-	}
-
-	if (config_list[0].iRef != ME_REF_AO_GROUND) {
-		PERROR("Output is referenced to ground.\n");
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	if ((trigger->iAcqStartTicksLow != 0)
-	    || (trigger->iAcqStartTicksHigh != 0)) {
-		PERROR
-		    ("Invalid acquisition start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_ARG;
-	}
-
-	if (config_list[0].iFlags) {
-		PERROR("Invalid config list flag.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((trigger->iAcqStartTrigType != ME_TRIG_TYPE_SW)
-	    && (trigger->iAcqStartTrigType != ME_TRIG_TYPE_EXT_DIGITAL)) {
-		PERROR("Invalid acquisition start trigger type specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE;
-	}
-
-	if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) {
-		switch (trigger->iAcqStartTrigEdge) {
-		case ME_TRIG_EDGE_RISING:
-		case ME_TRIG_EDGE_FALLING:
-		case ME_TRIG_EDGE_ANY:
-			break;
-
-		default:
-			PERROR
-			    ("Invalid acquisition start trigger edge specified.\n");
-			return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-		}
-	}
-
-	if ((trigger->iAcqStartTrigType == ME_TRIG_TYPE_SW)
-	    && (trigger->iAcqStartTrigEdge != ME_TRIG_TYPE_NONE)) {
-		PERROR("Invalid acquisition start trigger edge specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE;
-	}
-
-	if (trigger->iScanStartTrigType != ME_TRIG_TYPE_FOLLOW) {
-		PERROR("Invalid scan start trigger type specified.\n");
-		return ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE;
-	}
-
-	if (trigger->iConvStartTrigType != ME_TRIG_TYPE_TIMER) {
-		PERROR("Invalid conv start trigger type specified.\n");
-		return ME_ERRNO_INVALID_CONV_START_TRIG_TYPE;
-	}
-
-	if ((conv_ticks < ME6000_AO_MIN_CHAN_TICKS)
-	    || (conv_ticks > ME6000_AO_MAX_CHAN_TICKS)) {
-		PERROR("Invalid conv start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_CONV_START_ARG;
-	}
-
-	if (trigger->iAcqStartTicksLow || trigger->iAcqStartTicksHigh) {
-		PERROR("Invalid acq start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_ARG;
-	}
-
-	if (trigger->iScanStartTicksLow || trigger->iScanStartTicksHigh) {
-		PERROR("Invalid scan start trigger argument specified.\n");
-		return ME_ERRNO_INVALID_SCAN_START_ARG;
-	}
-
-	switch (trigger->iScanStopTrigType) {
-	case ME_TRIG_TYPE_NONE:
-		if (trigger->iScanStopCount != 0) {
-			PERROR("Invalid scan stop count specified.\n");
-			return ME_ERRNO_INVALID_SCAN_STOP_ARG;
-		}
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-			if (trigger->iScanStopCount <= 0) {
-				PERROR("Invalid scan stop count specified.\n");
-				return ME_ERRNO_INVALID_SCAN_STOP_ARG;
-			}
-		} else {
-			PERROR("The continous mode has not 'scan' contects.\n");
-			return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-		}
-		break;
-
-	default:
-		PERROR("Invalid scan stop trigger type specified.\n");
-		return ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE;
-	}
-
-	switch (trigger->iAcqStopTrigType) {
-	case ME_TRIG_TYPE_NONE:
-		if (trigger->iAcqStopCount != 0) {
-			PERROR("Invalid acq stop count specified.\n");
-			return ME_ERRNO_INVALID_ACQ_STOP_ARG;
-		}
-		break;
-
-	case ME_TRIG_TYPE_COUNT:
-		if (trigger->iScanStopTrigType != ME_TRIG_TYPE_NONE) {
-			PERROR("Invalid acq stop trigger type specified.\n");
-			return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-		}
-
-		if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
-			if (trigger->iAcqStopCount <= 0) {
-				PERROR
-				    ("The continous mode has not 'scan' contects.\n");
-				return ME_ERRNO_INVALID_ACQ_STOP_ARG;
-			}
-		}
-//                      else
-//                      {
-//                              PERROR("Invalid acq stop trigger type specified.\n");
-//                              return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-//                      }
-
-		break;
-
-	default:
-		PERROR("Invalid acq stop trigger type specified.\n");
-		return ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE;
-	}
-
-	switch (trigger->iAcqStartTrigChan) {
-	case ME_TRIG_CHAN_DEFAULT:
-	case ME_TRIG_CHAN_SYNCHRONOUS:
-		break;
-
-	default:
-		PERROR("Invalid acq start trigger channel specified.\n");
-		return ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	//Stop device
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-
-	//Check if state machine is stopped.
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	//Reset control register. Block all actions. Disable IRQ. Disable FIFO.
-	ctrl = ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-
-	//Reset interrupt latch
-	inl(instance->irq_reset_reg);
-
-	//This is paranoic, but to be sure.
-	instance->preloaded_count = 0;
-	instance->data_count = 0;
-	instance->circ_buf.head = 0;
-	instance->circ_buf.tail = 0;
-
-	/* Set mode. */
-	if (flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {	//Wraparound
-		if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {	//Hardware wraparound
-			PINFO("Hardware wraparound.\n");
-			ctrl |= ME6000_AO_MODE_WRAPAROUND;
-			instance->mode = ME6000_AO_HW_WRAP_MODE;
-		} else {	//Software wraparound
-			PINFO("Software wraparound.\n");
-			ctrl |= ME6000_AO_MODE_CONTINUOUS;
-			instance->mode = ME6000_AO_SW_WRAP_MODE;
-		}
-	} else {		//Continous
-		PINFO("Continous.\n");
-		ctrl |= ME6000_AO_MODE_CONTINUOUS;
-		instance->mode = ME6000_AO_CONTINOUS;
-	}
-
-	//Set the trigger edge.
-	if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) {	//Set the trigger type and edge for external trigger.
-		PINFO("External digital trigger.\n");
-		instance->start_mode = ME6000_AO_EXT_TRIG;
-
-		switch (trigger->iAcqStartTrigEdge) {
-		case ME_TRIG_EDGE_RISING:
-			PINFO("Set the trigger edge: rising.\n");
-			instance->ctrl_trg = 0x0;
-			break;
-
-		case ME_TRIG_EDGE_FALLING:
-			PINFO("Set the trigger edge: falling.\n");
-//                                      ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
-			instance->ctrl_trg = ME6000_AO_CTRL_BIT_EX_TRIG_EDGE;
-			break;
-
-		case ME_TRIG_EDGE_ANY:
-			PINFO("Set the trigger edge: both edges.\n");
-//                                      ctrl |= ME6000_AO_CTRL_BIT_EX_TRIG_EDGE | ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-			instance->ctrl_trg =
-			    ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
-			    ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH;
-			break;
-		}
-	} else {
-		PINFO("Internal software trigger.\n");
-		instance->start_mode = 0;
-	}
-
-	//Set the stop mode and value.
-	if (trigger->iAcqStopTrigType == ME_TRIG_TYPE_COUNT) {	//Amount of data
-		instance->stop_mode = ME6000_AO_ACQ_STOP_MODE;
-		instance->stop_count = trigger->iAcqStopCount;
-	} else if (trigger->iScanStopTrigType == ME_TRIG_TYPE_COUNT) {	//Amount of 'scans'
-		instance->stop_mode = ME6000_AO_SCAN_STOP_MODE;
-		instance->stop_count = trigger->iScanStopCount;
-	} else {		//Infinite
-		instance->stop_mode = ME6000_AO_INF_STOP_MODE;
-		instance->stop_count = 0;
-	}
-
-	PINFO("Stop count: %d.\n", instance->stop_count);
-
-	if (trigger->iAcqStartTrigChan == ME_TRIG_CHAN_SYNCHRONOUS) {	//Synchronous start
-		instance->start_mode |= ME6000_AO_SYNC_HOLD;
-		if (trigger->iAcqStartTrigType == ME_TRIG_TYPE_EXT_DIGITAL) {	//Externaly triggered
-			PINFO("Synchronous start. Externaly trigger active.\n");
-			instance->start_mode |= ME6000_AO_SYNC_EXT_TRIG;
-		}
-#ifdef MEDEBUG_INFO
-		else {
-			PINFO
-			    ("Synchronous start. Externaly trigger dissabled.\n");
-		}
-#endif
-
-	}
-	//Set speed
-	outl(conv_ticks - 2, instance->timer_reg);
-	PDEBUG_REG("timer_reg outl(0x%lX+0x%lX)=0x%llx\n", instance->reg_base,
-		   instance->timer_reg - instance->reg_base, conv_ticks - 2);
-	instance->hardware_stop_delay = (int)(conv_ticks * HZ) / ME6000_AO_BASE_FREQUENCY;	//<== MUST be with cast!
-
-	// Write the control word
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-
-	//Set status.
-	instance->status = ao_status_stream_configured;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
-					  struct file *filep,
-					  int time_out, int *count, int flags)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	long j;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!instance->circ_buf.buf) {
-		PERROR("Circular buffer not exists.\n");
-		return ME_ERRNO_INTERNAL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (me_circ_buf_space(&instance->circ_buf)) {	//The buffer is NOT full.
-		*count = me_circ_buf_space(&instance->circ_buf);
-	} else {		//The buffer is full.
-		if (time_out) {
-			t = (time_out * HZ) / 1000;
-
-			if (t == 0)
-				t = 1;
-		} else {	//Max time.
-			t = LONG_MAX;
-		}
-
-		*count = 0;
-
-		j = jiffies;
-
-		//Only runing process will interrupt this call. Interrupts are when FIFO HF is signaled.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 ((me_circ_buf_space
-						   (&instance->circ_buf))
-						  || !(inl(instance->status_reg)
-						       &
-						       ME6000_AO_STATUS_BIT_FSM)),
-						 t);
-
-		if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) {
-			PERROR("AO subdevice is not running.\n");
-			err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-		} else if (signal_pending(current)) {
-			PERROR("Wait on values interrupted from signal.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		} else if ((jiffies - j) >= t) {
-			PERROR("Wait on values timed out.\n");
-			err = ME_ERRNO_TIMEOUT;
-		} else {	//Uff... all is good. Inform user about empty space.
-			*count = me_circ_buf_space(&instance->circ_buf);
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int start_mode, int time_out, int flags)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long cpu_flags = 0;
-	uint32_t status;
-	uint32_t ctrl;
-	uint32_t synch;
-	int count = 0;
-	int circ_buffer_count;
-
-	unsigned long ref;
-	unsigned long delay = 0;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags & ~ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS) {
-		PERROR("Invalid flags.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid timeout specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if ((start_mode != ME_START_MODE_BLOCKING)
-	    && (start_mode != ME_START_MODE_NONBLOCKING)) {
-		PERROR("Invalid start mode specified.\n");
-		return ME_ERRNO_INVALID_START_MODE;
-	}
-
-	if (time_out) {
-		delay = (time_out * HZ) / 1000;
-		if (delay == 0)
-			delay = 1;
-	}
-
-	switch (instance->status) {	//Checking actual mode.
-	case ao_status_stream_configured:
-	case ao_status_stream_end:
-		//Correct modes!
-		break;
-
-		//The device is in wrong mode.
-	case ao_status_none:
-	case ao_status_single_configured:
-	case ao_status_single_run_wait:
-	case ao_status_single_run:
-	case ao_status_single_end_wait:
-		PERROR
-		    ("Subdevice must be preinitialize correctly for streaming.\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-
-	case ao_status_stream_fifo_error:
-	case ao_status_stream_buffer_error:
-	case ao_status_stream_error:
-		PDEBUG("Before restart broke stream 'STOP' must be caled.\n");
-		return ME_STATUS_ERROR;
-
-	case ao_status_stream_run_wait:
-	case ao_status_stream_run:
-	case ao_status_stream_end_wait:
-		PDEBUG("Stream is already working.\n");
-		return ME_ERRNO_SUBDEVICE_BUSY;
-
-	default:
-		instance->status = ao_status_stream_error;
-		PERROR_CRITICAL("Status is in wrong state!\n");
-		return ME_ERRNO_INTERNAL;
-
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->mode == ME6000_AO_CONTINOUS) {	//Continous
-		instance->circ_buf.tail += instance->preloaded_count;
-		instance->circ_buf.tail &= instance->circ_buf.mask;
-	}
-	circ_buffer_count = me_circ_buf_values(&instance->circ_buf);
-
-	if (!circ_buffer_count && !instance->preloaded_count) {	//No values in buffer
-		ME_SUBDEVICE_EXIT;
-		PERROR("No values in buffer!\n");
-		return ME_ERRNO_LACK_OF_RESOURCES;
-	}
-
-	//Cancel control task
-	PDEBUG("Cancel control task. idx=%d\n", instance->ao_idx);
-	instance->ao_control_task_flag = 0;
-	cancel_delayed_work(&instance->ao_control_task);
-
-	//Stop device
-	err = ao_stop_immediately(instance);
-	if (err) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		ME_SUBDEVICE_EXIT;
-
-		return ME_ERRNO_SUBDEVICE_BUSY;
-	}
-	//Set values for single_read()
-	instance->single_value = ME6000_AO_MAX_DATA + 1;
-	instance->single_value_in_fifo = ME6000_AO_MAX_DATA + 1;
-
-	//Setting stop points
-	if (instance->stop_mode == ME6000_AO_SCAN_STOP_MODE) {
-		instance->stop_data_count =
-		    instance->stop_count * circ_buffer_count;
-	} else {
-		instance->stop_data_count = instance->stop_count;
-	}
-
-	if ((instance->stop_data_count != 0)
-	    && (instance->stop_data_count < circ_buffer_count)) {
-		PERROR("More data in buffer than previously set limit!\n");
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	ctrl = inl(instance->ctrl_reg);
-	//Check FIFO
-	if (!(ctrl & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) {	//FIFO wasn't enabeled. Do it. <= This should be done by user call with ME_WRITE_MODE_PRELOAD
-		PINFO("Enableing FIFO.\n");
-		ctrl |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-
-		instance->preloaded_count = 0;
-		instance->data_count = 0;
-	} else {		//Block IRQ
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-	}
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-
-	//Reset interrupt latch
-	inl(instance->irq_reset_reg);
-
-	//Fill FIFO <= Generaly this should be done by user pre-load call but this is second place to do it.
-	status = inl(instance->status_reg);
-	if (!(status & ME6000_AO_STATUS_BIT_EF)) {	//FIFO empty
-		if (instance->stop_data_count != 0) {
-			count = ME6000_AO_FIFO_COUNT;
-		} else {
-			count =
-			    (ME6000_AO_FIFO_COUNT <
-			     instance->
-			     stop_data_count) ? ME6000_AO_FIFO_COUNT :
-			    instance->stop_data_count;
-		}
-
-		//Copy data
-		count =
-		    ao_write_data(instance, count, instance->preloaded_count);
-
-		if (count < 0) {	//This should never happend!
-			PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-	}
-	//Set pre-load features.
-	spin_lock(instance->preload_reg_lock);
-	synch = inl(instance->preload_reg);
-	synch &=
-	    ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) << instance->
-	      ao_idx);
-	synch |=
-	    (instance->start_mode & ~ME6000_AO_EXT_TRIG) << instance->ao_idx;
-	outl(synch, instance->preload_reg);
-	PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->preload_reg - instance->reg_base, synch);
-	spin_unlock(instance->preload_reg_lock);
-
-	//Default count is '0'
-	if (instance->mode == ME6000_AO_CONTINOUS) {	//Continous
-		instance->preloaded_count = 0;
-		instance->circ_buf.tail += count;
-		instance->circ_buf.tail &= instance->circ_buf.mask;
-	} else {		//Wraparound
-		instance->preloaded_count += count;
-		instance->data_count += count;
-
-		//Special case: Infinite wraparound with less than FIFO datas always should runs in hardware mode.
-		if ((instance->stop_mode == ME6000_AO_INF_STOP_MODE)
-		    && (circ_buffer_count <= ME6000_AO_FIFO_COUNT)) {	//Change to hardware wraparound
-			PDEBUG
-			    ("Changeing mode from software wraparound to hardware wraparound.\n");
-			//Copy all data
-			count =
-			    ao_write_data(instance, circ_buffer_count,
-					  instance->preloaded_count);
-			ctrl &= ~ME6000_AO_CTRL_MODE_MASK;
-			ctrl |= ME6000_AO_MODE_WRAPAROUND;
-		}
-
-		if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) {	//Reset position indicator.
-			instance->preloaded_count = 0;
-		} else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) {	//This should never happend!
-			PERROR_CRITICAL
-			    ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-	}
-
-	//Set status to 'wait for start'
-	instance->status = ao_status_stream_run_wait;
-
-	status = inl(instance->status_reg);
-	//Start state machine and interrupts
-	PINFO("<%s:%d> Start state machine.\n", __func__, __LINE__);
-	ctrl &= ~(ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP);
-	if (instance->start_mode == ME6000_AO_EXT_TRIG) {
-		PDEBUG("DIGITAL TRIGGER\n");
-		ctrl |= ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG;
-	}
-	if (!(status & ME6000_AO_STATUS_BIT_HF)) {	//More than half!
-		if ((ctrl & ME6000_AO_CTRL_MODE_MASK) == ME6000_AO_MODE_CONTINUOUS) {	//Enable IRQ only when hardware_continous is set and FIFO is more than half
-			PINFO("<%s:%d> Start interrupts.\n", __func__,
-			      __LINE__);
-			ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-		}
-	}
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	//Trigger output
-	PINFO("<%s> start mode= 0x%x %s\n", __func__, instance->start_mode,
-	      (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) ? "SYNCHRONOUS" :
-	      "");
-	if (flags & ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS) {	//Trigger outputs
-		spin_lock(instance->preload_reg_lock);
-		synch = inl(instance->preload_reg);
-		//Add channel to start list
-		outl(synch | (ME6000_AO_SYNC_HOLD << instance->ao_idx),
-		     instance->preload_reg);
-		PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->preload_reg - instance->reg_base,
-			   synch | (ME6000_AO_SYNC_HOLD << instance->ao_idx));
-
-		//Fire
-		PINFO
-		    ("Fired all software synchronous outputs by software trigger.\n");
-		outl(0x8000, instance->single_reg);
-		PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->single_reg - instance->reg_base, 0x8000);
-
-		//Restore save settings
-		outl(synch, instance->preload_reg);
-		PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->preload_reg - instance->reg_base, synch);
-		spin_unlock(instance->preload_reg_lock);
-	} else if (!instance->start_mode) {	//Trigger outputs
-/*
-		spin_lock(instance->preload_reg_lock);
-			synch = inl(instance->preload_reg);
-			//Remove channel from start list
-			outl(synch & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx), instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch & ~(ME6000_AO_SYNC_HOLD << instance->ao_idx));
-*/
-		//Fire
-		PINFO("Software trigger.\n");
-		outl(0x8000, instance->single_reg);
-		PDEBUG_REG("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->single_reg - instance->reg_base, 0x8000);
-
-/*
-			//Restore save settings
-			outl(synch, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base, instance->preload_reg - instance->reg_base, synch);
-		spin_unlock(instance->preload_reg_lock);
-*/
-	}
-	// Set control task's timeout
-	instance->timeout.delay = delay;
-	instance->timeout.start_time = jiffies;
-
-	if (status & ME6000_AO_STATUS_BIT_HF) {	//Less than half but not empty!
-		PINFO("Less than half.\n");
-		if (instance->stop_data_count == 0) {
-			count = ME6000_AO_FIFO_COUNT / 2;
-		} else {
-			count =
-			    ((ME6000_AO_FIFO_COUNT / 2) <
-			     instance->stop_data_count) ? ME6000_AO_FIFO_COUNT /
-			    2 : instance->stop_data_count;
-		}
-
-		//Copy data
-		count =
-		    ao_write_data(instance, count, instance->preloaded_count);
-
-		if (count < 0) {	//This should never happend!
-			PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-
-		if (instance->mode == ME6000_AO_CONTINOUS) {	//Continous
-			instance->circ_buf.tail += count;
-			instance->circ_buf.tail &= instance->circ_buf.mask;
-		} else {	//Wraparound
-			instance->data_count += count;
-			instance->preloaded_count += count;
-
-			if (instance->preloaded_count == me_circ_buf_values(&instance->circ_buf)) {	//Reset position indicator.
-				instance->preloaded_count = 0;
-			} else if (instance->preloaded_count > me_circ_buf_values(&instance->circ_buf)) {	//This should never happend!
-				PERROR_CRITICAL
-				    ("PRELOADED MORE VALUES THAN ARE IN BUFFER!\n");
-				ME_SUBDEVICE_EXIT;
-				return ME_ERRNO_INTERNAL;
-			}
-		}
-
-		status = inl(instance->status_reg);
-		if (!(status & ME6000_AO_STATUS_BIT_HF)) {	//More than half!
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			PINFO("<%s:%d> Start interrupts.\n", __func__,
-			      __LINE__);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-		}
-	}
-	//Special case: Limited wraparound with less than HALF FIFO datas need work around to generate first interrupt.
-	if ((instance->stop_mode != ME6000_AO_INF_STOP_MODE)
-	    && (instance->mode == ME6000_AO_SW_WRAP_MODE)
-	    && (circ_buffer_count <= (ME6000_AO_FIFO_COUNT / 2))) {	//Put more data to FIFO
-		PINFO("Limited wraparound with less than HALF FIFO datas.\n");
-		if (instance->preloaded_count) {	//This should never happend!
-			PERROR_CRITICAL
-			    ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
-			ME_SUBDEVICE_EXIT;
-			return ME_ERRNO_INTERNAL;
-		}
-
-		while (instance->stop_data_count > instance->data_count) {	//Maximum data not set jet.
-			//Copy to buffer
-			if (circ_buffer_count != ao_write_data(instance, circ_buffer_count, 0)) {	//This should never happend!
-				PERROR_CRITICAL
-				    ("ERROR WHEN LOADING VALUES FOR WRAPAROUND!\n");
-				ME_SUBDEVICE_EXIT;
-				return ME_ERRNO_INTERNAL;
-			}
-			instance->data_count += circ_buffer_count;
-
-			if (!((status = inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF)) {	//FIFO is more than half. Enable IRQ and end copy.
-				//Reset interrupt latch
-				inl(instance->irq_reset_reg);
-
-				spin_lock_irqsave(&instance->subdevice_lock,
-						  cpu_flags);
-				PINFO("<%s:%d> Start interrupts.\n",
-				      __func__, __LINE__);
-				ctrl = inl(instance->ctrl_reg);
-				ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-				outl(ctrl, instance->ctrl_reg);
-				PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->ctrl_reg -
-					   instance->reg_base, ctrl);
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-				break;
-			}
-		}
-	}
-	// Schedule control task
-	instance->ao_control_task_flag = 1;
-	queue_delayed_work(instance->me6000_workqueue,
-			   &instance->ao_control_task, 1);
-
-	if (start_mode == ME_START_MODE_BLOCKING) {	//Wait for start.
-		ref = jiffies;
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_stream_run_wait),
-						 (delay) ? delay +
-						 1 : LONG_MAX);
-
-		if ((instance->status != ao_status_stream_run)
-		    && (instance->status != ao_status_stream_end)) {
-			PDEBUG("Starting stream canceled. %d\n",
-			       instance->status);
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait on start of state machine interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		if ((delay) && ((jiffies - ref) >= delay)) {
-			if (instance->status != ao_status_stream_run) {
-				if (instance->status == ao_status_stream_end) {
-					PDEBUG("Timeout reached.\n");
-				} else if ((jiffies - ref) > delay) {
-					PERROR
-					    ("Timeout reached. Not handled by control task!\n");
-					ao_stop_immediately(instance);
-				} else {
-					PERROR
-					    ("Timeout reached. Signal come but status is strange: %d\n",
-					     instance->status);
-					ao_stop_immediately(instance);
-				}
-
-				instance->ao_control_task_flag = 0;
-				cancel_delayed_work(&instance->ao_control_task);
-				instance->status = ao_status_stream_end;
-				err = ME_ERRNO_TIMEOUT;
-			}
-		}
-	}
-
-	ME_SUBDEVICE_EXIT;
-	return err;
-}
-
-static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int wait,
-				      int *status, int *values, int flags)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((wait != ME_WAIT_NONE) && (wait != ME_WAIT_IDLE)) {
-		PERROR("Invalid wait argument specified.\n");
-		*status = ME_STATUS_INVALID;
-		return ME_ERRNO_INVALID_WAIT;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	switch (instance->status) {
-	case ao_status_single_configured:
-	case ao_status_single_end:
-	case ao_status_stream_configured:
-	case ao_status_stream_end:
-	case ao_status_stream_fifo_error:
-	case ao_status_stream_buffer_error:
-	case ao_status_stream_error:
-		*status = ME_STATUS_IDLE;
-		break;
-
-	case ao_status_single_run_wait:
-	case ao_status_single_run:
-	case ao_status_single_end_wait:
-	case ao_status_stream_run_wait:
-	case ao_status_stream_run:
-	case ao_status_stream_end_wait:
-		*status = ME_STATUS_BUSY;
-		break;
-
-	case ao_status_none:
-	default:
-		*status =
-		    (inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM) ?
-		    ME_STATUS_BUSY : ME_STATUS_IDLE;
-		break;
-	}
-
-	if ((wait == ME_WAIT_IDLE) && (*status == ME_STATUS_BUSY)) {
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 ((instance->status !=
-						   ao_status_single_run_wait)
-						  && (instance->status !=
-						      ao_status_single_run)
-						  && (instance->status !=
-						      ao_status_single_end_wait)
-						  && (instance->status !=
-						      ao_status_stream_run_wait)
-						  && (instance->status !=
-						      ao_status_stream_run)
-						  && (instance->status !=
-						      ao_status_stream_end_wait)),
-						 LONG_MAX);
-
-		if (instance->status != ao_status_stream_end) {
-			PDEBUG("Wait for IDLE canceled. %d\n",
-			       instance->status);
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Wait for IDLE interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-
-		*status = ME_STATUS_IDLE;
-	}
-
-	*values = me_circ_buf_space(&instance->circ_buf);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-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
-	int err = ME_ERRNO_SUCCESS;
-	me6000_ao_subdevice_t *instance;
-	unsigned long cpu_flags;
-	volatile uint32_t ctrl;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (flags & ~ME_IO_STREAM_STOP_PRESERVE_BUFFERS) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if ((stop_mode != ME_STOP_MODE_IMMEDIATE)
-	    && (stop_mode != ME_STOP_MODE_LAST_VALUE)) {
-		PERROR("Invalid stop mode specified.\n");
-		return ME_ERRNO_INVALID_STOP_MODE;
-	}
-
-	if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (instance->status < ao_status_stream_configured) {
-		//There is nothing to stop!
-		PERROR("Subdevice not in streaming mode. %d\n",
-		       instance->status);
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	//Mark as stopping. => Software stop.
-	instance->status = ao_status_stream_end_wait;
-
-	if (stop_mode == ME_STOP_MODE_IMMEDIATE) {	//Stopped now!
-		err = ao_stop_immediately(instance);
-	} else if (stop_mode == ME_STOP_MODE_LAST_VALUE) {
-		ctrl = inl(instance->ctrl_reg) & ME6000_AO_CTRL_MODE_MASK;
-		if (ctrl == ME6000_AO_MODE_WRAPAROUND) {	//Hardware wraparound => Hardware stop.
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |= ME6000_AO_CTRL_BIT_STOP;
-			ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			//Reset interrupt latch
-			inl(instance->irq_reset_reg);
-		}
-		//Only runing process will interrupt this call. Events are signaled when status change. Extra timeout add for safe reason.
-		wait_event_interruptible_timeout(instance->wait_queue,
-						 (instance->status !=
-						  ao_status_stream_end_wait),
-						 LONG_MAX);
-
-		if (instance->status != ao_status_stream_end) {
-			PDEBUG("Stopping stream canceled.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-
-		if (signal_pending(current)) {
-			PERROR("Stopping stream interrupted.\n");
-			instance->status = ao_status_none;
-			ao_stop_immediately(instance);
-			err = ME_ERRNO_SIGNAL;
-		}
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	ctrl = inl(instance->ctrl_reg);
-	ctrl |= ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
-	ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-	if (!flags) {		//Reset FIFO
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO;
-	}
-	outl(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	//Reset interrupt latch
-	inl(instance->irq_reset_reg);
-
-	if (!flags) {		//Reset software buffer
-		instance->circ_buf.head = 0;
-		instance->circ_buf.tail = 0;
-		instance->preloaded_count = 0;
-		instance->data_count = 0;
-	}
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int write_mode,
-				     int *values, int *count, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me6000_ao_subdevice_t *instance;
-	unsigned long cpu_flags = 0;
-	uint32_t reg_copy;
-
-	int copied_from_user = 0;
-	int left_to_copy_from_user = *count;
-
-	int copied_values;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	//Checking arguments
-	if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {
-		PERROR("Not a streaming ao.\n");
-		return ME_ERRNO_NOT_SUPPORTED;
-	}
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (*count <= 0) {
-		PERROR("Invalid count of values specified.\n");
-		return ME_ERRNO_INVALID_VALUE_COUNT;
-	}
-
-	if (values == NULL) {
-		PERROR("Invalid address of values specified.\n");
-		return ME_ERRNO_INVALID_POINTER;
-	}
-
-	if ((instance->status == ao_status_none) || (instance->status == ao_status_single_configured)) {	//The device is in single mode.
-		PERROR
-		    ("Subdevice must be preinitialize correctly for streaming.\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-	}
-
-	switch (write_mode) {
-	case ME_WRITE_MODE_PRELOAD:
-
-		//Device must be stopped.
-		if ((instance->status != ao_status_stream_configured)
-		    && (instance->status != ao_status_stream_end)) {
-			PERROR
-			    ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
-			return ME_ERRNO_PREVIOUS_CONFIG;
-		}
-		break;
-	case ME_WRITE_MODE_NONBLOCKING:
-	case ME_WRITE_MODE_BLOCKING:
-		/// @note In blocking mode: When device is not runing and there is not enought space call will blocked up!
-		/// @note Some other thread must empty buffer by strating engine.
-		break;
-
-	default:
-		PERROR("Invalid write mode specified.\n");
-		return ME_ERRNO_INVALID_WRITE_MODE;
-	}
-
-	if (instance->mode & ME6000_AO_WRAP_MODE) {	//Wraparound mode. Device must be stopped.
-		if ((instance->status != ao_status_stream_configured)
-		    && (instance->status != ao_status_stream_end)) {
-			PERROR
-			    ("Subdevice mustn't be runing when 'pre-load' mode is used.\n");
-			return ME_ERRNO_INVALID_WRITE_MODE;
-		}
-	}
-
-	if ((instance->mode == ME6000_AO_HW_WRAP_MODE)
-	    && (write_mode != ME_WRITE_MODE_PRELOAD)) {
-/*
-		PERROR("Only 'pre-load' write is acceptable in hardware wraparound mode.\n");
-		return ME_ERRNO_PREVIOUS_CONFIG;
-*/
-		//This is transparent for user.
-		PDEBUG("Changing write_mode to ME_WRITE_MODE_PRELOAD.\n");
-		write_mode = ME_WRITE_MODE_PRELOAD;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (write_mode == ME_WRITE_MODE_PRELOAD) {	//Init enviroment - preload
-		spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-		reg_copy = inl(instance->ctrl_reg);
-		//Check FIFO
-		if (!(reg_copy & ME6000_AO_CTRL_BIT_ENABLE_FIFO)) {	//FIFO not active. Enable it.
-			reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_FIFO;
-			outl(reg_copy, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   reg_copy);
-			instance->preloaded_count = 0;
-		}
-		spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	}
-
-	while (1) {
-		//Copy to buffer. This step is common for all modes.
-		copied_from_user =
-		    ao_get_data_from_user(instance, left_to_copy_from_user,
-					  values + (*count -
-						    left_to_copy_from_user));
-		left_to_copy_from_user -= copied_from_user;
-
-		reg_copy = inl(instance->status_reg);
-		if ((instance->status == ao_status_stream_run) && !(reg_copy & ME6000_AO_STATUS_BIT_FSM)) {	//BROKEN PIPE! The state machine is stoped but logical status show that should be working.
-			PERROR("Broken pipe in write.\n");
-			err = ME_ERRNO_SUBDEVICE_NOT_RUNNING;
-			break;
-		}
-
-		if ((instance->status == ao_status_stream_run) && (instance->mode == ME6000_AO_CONTINOUS) && (reg_copy & ME6000_AO_STATUS_BIT_HF)) {	//Continous mode runing and data are below half!
-
-			// Block interrupts.
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			reg_copy = inl(instance->ctrl_reg);
-			reg_copy &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(reg_copy, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   reg_copy);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			//Fast copy
-			copied_values =
-			    ao_write_data(instance, ME6000_AO_FIFO_COUNT / 2,
-					  0);
-			if (copied_values > 0) {
-				instance->circ_buf.tail += copied_values;
-				instance->circ_buf.tail &=
-				    instance->circ_buf.mask;
-				continue;
-			}
-			//Reset interrupt latch
-			inl(instance->irq_reset_reg);
-
-			// Activate interrupts.
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			reg_copy = inl(instance->ctrl_reg);
-			reg_copy |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-			outl(reg_copy, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   reg_copy);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if (copied_values == 0) {	//This was checked and never should happend!
-				PERROR_CRITICAL("COPY FINISH WITH 0!\n");
-			}
-
-			if (copied_values < 0) {	//This was checked and never should happend!
-				PERROR_CRITICAL("COPY FINISH WITH ERROR!\n");
-				instance->status = ao_status_stream_fifo_error;
-				err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-				break;
-			}
-		}
-
-		if (!left_to_copy_from_user) {	//All datas were copied.
-			break;
-		} else {	//Not all datas were copied.
-			if (instance->mode & ME6000_AO_WRAP_MODE) {	//Error too much datas! Wraparound is limited in size!
-				PERROR
-				    ("Too much data for wraparound mode!  Exceeded size of %ld.\n",
-				     ME6000_AO_CIRC_BUF_COUNT - 1);
-				err = ME_ERRNO_RING_BUFFER_OVERFLOW;
-				break;
-			}
-
-			if (write_mode != ME_WRITE_MODE_BLOCKING) {	//Non blocking calls
-				break;
-			}
-
-			wait_event_interruptible(instance->wait_queue,
-						 me_circ_buf_space(&instance->
-								   circ_buf));
-
-			if (signal_pending(current)) {
-				PERROR("Writing interrupted by signal.\n");
-				instance->status = ao_status_none;
-				ao_stop_immediately(instance);
-				err = ME_ERRNO_SIGNAL;
-				break;
-			}
-
-			if (instance->status == ao_status_none) {	//Reset
-				PERROR("Writing interrupted by reset.\n");
-				err = ME_ERRNO_CANCELLED;
-				break;
-			}
-		}
-	}
-
-	if (write_mode == ME_WRITE_MODE_PRELOAD) {	//Copy data to FIFO - preload
-		copied_values =
-		    ao_write_data_pooling(instance, ME6000_AO_FIFO_COUNT,
-					  instance->preloaded_count);
-		instance->preloaded_count += copied_values;
-		instance->data_count += copied_values;
-
-		if ((instance->mode == ME6000_AO_HW_WRAP_MODE)
-		    && (me_circ_buf_values(&instance->circ_buf) >
-			ME6000_AO_FIFO_COUNT)) {
-			PERROR
-			    ("Too much data for hardware wraparound mode! Exceeded size of %d.\n",
-			     ME6000_AO_FIFO_COUNT);
-			err = ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-		}
-	}
-
-	*count = *count - left_to_copy_from_user;
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id)
-{
-	me6000_ao_subdevice_t *instance = dev_id;
-	uint32_t irq_status;
-	uint32_t ctrl;
-	uint32_t status;
-	int count = 0;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	irq_status = inl(instance->irq_status_reg);
-	if (!(irq_status & (ME6000_IRQ_STATUS_BIT_AO_HF << instance->ao_idx))) {
-		PINFO("%ld Shared interrupt. %s(): ID=%d: status_reg=0x%04X\n",
-		      jiffies, __func__, instance->ao_idx, irq_status);
-		return IRQ_NONE;
-	}
-
-	if (!instance->circ_buf.buf) {
-		instance->status = ao_status_stream_error;
-		PERROR_CRITICAL("CIRCULAR BUFFER NOT EXISTS!\n");
-		//Block interrupts. Stop machine.
-		ctrl = inl(instance->ctrl_reg);
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-		ctrl |=
-		    ME6000_AO_CTRL_BIT_IMMEDIATE_STOP | ME6000_AO_CTRL_BIT_STOP;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		//Inform user
-		wake_up_interruptible_all(&instance->wait_queue);
-		return IRQ_HANDLED;
-	}
-
-	status = inl(instance->status_reg);
-	if (!(status & ME6000_AO_STATUS_BIT_FSM)) {	//Too late. Not working! END? BROKEN PIPE?
-		/// @note Error checking was moved to separate task.
-		PDEBUG("Interrupt come but ISM is not working!\n");
-		//Block interrupts. Stop machine.
-		ctrl = inl(instance->ctrl_reg);
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-		ctrl |=
-		    ME6000_AO_CTRL_BIT_STOP | ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		//Reset interrupt latch
-		inl(instance->irq_reset_reg);
-
-		/// @note User notification was also moved to separate task.
-		return IRQ_HANDLED;
-	}
-	//General procedure. Process more datas.
-
-#ifdef MEDEBUG_DEBUG
-	if (!me_circ_buf_values(&instance->circ_buf)) {	//Buffer is empty!
-		PDEBUG("Circular buffer empty!\n");
-	}
-#endif
-
-	//Check FIFO
-	if (status & ME6000_AO_STATUS_BIT_HF) {	//OK less than half
-
-		//Block interrupts
-		ctrl = inl(instance->ctrl_reg);
-		ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-
-		do {
-			//Calculate how many should be copied.
-			count =
-			    (instance->stop_data_count) ? instance->
-			    stop_data_count -
-			    instance->data_count : ME6000_AO_FIFO_COUNT / 2;
-			if (ME6000_AO_FIFO_COUNT / 2 < count) {
-				count = ME6000_AO_FIFO_COUNT / 2;
-			}
-			//Copy data
-			if (instance->mode == ME6000_AO_CONTINOUS) {	//Continous
-				count = ao_write_data(instance, count, 0);
-				if (count > 0) {
-					instance->circ_buf.tail += count;
-					instance->circ_buf.tail &=
-					    instance->circ_buf.mask;
-					instance->data_count += count;
-
-					if ((instance->status == ao_status_stream_end_wait) && !me_circ_buf_values(&instance->circ_buf)) {	//Stoping. Whole buffer was copied.
-						break;
-					}
-				}
-			} else if ((instance->mode == ME6000_AO_SW_WRAP_MODE) && ((ctrl & ME6000_AO_CTRL_MODE_MASK) == ME6000_AO_MODE_CONTINUOUS)) {	//Wraparound (software)
-				if (instance->status == ao_status_stream_end_wait) {	//We stoping => Copy to the end of the buffer.
-					count =
-					    ao_write_data(instance, count, 0);
-				} else {	//Copy in wraparound mode.
-					count =
-					    ao_write_data_wraparound(instance,
-								     count,
-								     instance->
-								     preloaded_count);
-				}
-
-				if (count > 0) {
-					instance->data_count += count;
-					instance->preloaded_count += count;
-					instance->preloaded_count %=
-					    me_circ_buf_values(&instance->
-							       circ_buf);
-
-					if ((instance->status == ao_status_stream_end_wait) && !instance->preloaded_count) {	//Stoping. Whole buffer was copied.
-						break;
-					}
-				}
-			}
-
-			if ((count <= 0) || (instance->stop_data_count && (instance->stop_data_count <= instance->data_count))) {	//End of work.
-				break;
-			}
-		}		//Repeat if still is under half fifo
-		while ((status =
-			inl(instance->status_reg)) & ME6000_AO_STATUS_BIT_HF);
-
-		//Unblock interrupts
-		ctrl = inl(instance->ctrl_reg);
-		if (count >= 0) {	//Copy was successful.
-			if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) {	//Finishing work. No more interrupts.
-				PDEBUG("Finishing work. Interrupt disabled.\n");
-				instance->status = ao_status_stream_end_wait;
-			} else if (count > 0) {	//Normal work. Enable interrupt.
-				PDEBUG("Normal work. Enable interrupt.\n");
-				ctrl |= ME6000_AO_CTRL_BIT_ENABLE_IRQ;
-			} else {	//Normal work but there are no more data in buffer. Interrupt blocked. stream_write() will unblock it.
-				PDEBUG
-				    ("No data in software buffer. Interrupt blocked.\n");
-			}
-		} else {	//Error during copy.
-			instance->status = ao_status_stream_fifo_error;
-		}
-
-		outl(ctrl, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, ctrl);
-	} else {		//?? more than half
-		PDEBUG
-		    ("Interrupt come but FIFO more than half full! Reset interrupt.\n");
-	}
-
-	PINFO("ISR: Buffer count: %d.(T:%d H:%d)\n",
-	      me_circ_buf_values(&instance->circ_buf), instance->circ_buf.tail,
-	      instance->circ_buf.head);
-	PINFO("ISR: Stop count: %d.\n", instance->stop_count);
-	PINFO("ISR: Stop data count: %d.\n", instance->stop_data_count);
-	PINFO("ISR: Data count: %d.\n", instance->data_count);
-
-	//Reset interrupt latch
-	inl(instance->irq_reset_reg);
-
-	//Inform user
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-static void me6000_ao_destructor(struct me_subdevice *subdevice)
-{
-	me6000_ao_subdevice_t *instance;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	instance->ao_control_task_flag = 0;
-
-	// Reset subdevice to asure clean exit.
-	me6000_ao_io_reset_subdevice(subdevice, NULL,
-				     ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-
-	// Remove any tasks from work queue. This is paranoic because it was done allready in reset().
-	if (!cancel_delayed_work(&instance->ao_control_task)) {	//Wait 2 ticks to be sure that control task is removed from queue.
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(2);
-	}
-
-	if (instance->fifo & ME6000_AO_HAS_FIFO) {
-		if (instance->irq) {
-			free_irq(instance->irq, instance);
-			instance->irq = 0;
-		}
-
-		if (instance->circ_buf.buf) {
-			PDEBUG("free circ_buf = %p size=%d",
-			       instance->circ_buf.buf,
-			       PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER);
-			free_pages((unsigned long)instance->circ_buf.buf,
-				   ME6000_AO_CIRC_BUF_SIZE_ORDER);
-		}
-		instance->circ_buf.buf = NULL;
-	}
-
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
-					     spinlock_t *preload_reg_lock,
-					     uint32_t *preload_flags,
-					     uint32_t *triggering_flags,
-					     int ao_idx,
-					     int fifo,
-					     int irq,
-					     int high_range,
-					     struct workqueue_struct *me6000_wq)
-{
-	me6000_ao_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed ID=%d.\n", ao_idx);
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me6000_ao_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me6000_ao_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->preload_reg_lock = preload_reg_lock;
-	subdevice->preload_flags = preload_flags;
-	subdevice->triggering_flags = triggering_flags;
-
-	/* Store analog output index */
-	subdevice->ao_idx = ao_idx;
-
-	/* Store if analog output has fifo */
-	subdevice->fifo = fifo;
-
-	if (subdevice->fifo & ME6000_AO_HAS_FIFO) {
-		/* Allocate and initialize circular buffer */
-		subdevice->circ_buf.mask = ME6000_AO_CIRC_BUF_COUNT - 1;
-		subdevice->circ_buf.buf =
-		    (void *)__get_free_pages(GFP_KERNEL,
-					     ME6000_AO_CIRC_BUF_SIZE_ORDER);
-		PDEBUG("circ_buf = %p size=%ld\n", subdevice->circ_buf.buf,
-		       ME6000_AO_CIRC_BUF_SIZE);
-
-		if (!subdevice->circ_buf.buf) {
-			PERROR
-			    ("Cannot initialize subdevice base class instance.\n");
-			kfree(subdevice);
-			return NULL;
-		}
-
-		memset(subdevice->circ_buf.buf, 0, ME6000_AO_CIRC_BUF_SIZE);
-	} else {
-		subdevice->circ_buf.mask = 0;
-		subdevice->circ_buf.buf = NULL;
-	}
-	subdevice->circ_buf.head = 0;
-	subdevice->circ_buf.tail = 0;
-
-	subdevice->status = ao_status_none;
-	subdevice->ao_control_task_flag = 0;
-	subdevice->timeout.delay = 0;
-	subdevice->timeout.start_time = jiffies;
-
-	/* Initialize wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	/* Initialize single value to 0V */
-	subdevice->single_value = 0x8000;
-	subdevice->single_value_in_fifo = 0x8000;
-
-	/* Initialize range boarders */
-	if (high_range) {
-		subdevice->min = ME6000_AO_MIN_RANGE_HIGH;
-		subdevice->max = ME6000_AO_MAX_RANGE_HIGH;
-	} else {
-		subdevice->min = ME6000_AO_MIN_RANGE;
-		subdevice->max = ME6000_AO_MAX_RANGE;
-	}
-
-	/* Register interrupt service routine */
-
-	if (subdevice->fifo & ME6000_AO_HAS_FIFO) {
-		subdevice->irq = irq;
-		if (request_irq(subdevice->irq, me6000_ao_isr,
-				IRQF_DISABLED | IRQF_SHARED,
-				ME6000_NAME, subdevice)) {
-			PERROR("Cannot get interrupt line.\n");
-			PDEBUG("free circ_buf = %p size=%d",
-			       subdevice->circ_buf.buf,
-			       PAGE_SHIFT << ME6000_AO_CIRC_BUF_SIZE_ORDER);
-			free_pages((unsigned long)subdevice->circ_buf.buf,
-				   ME6000_AO_CIRC_BUF_SIZE_ORDER);
-			subdevice->circ_buf.buf = NULL;
-			kfree(subdevice);
-			return NULL;
-		}
-		PINFO("Registered irq=%d.\n", subdevice->irq);
-	} else {
-		subdevice->irq = 0;
-	}
-
-	/* Initialize registers */
-	// Only streamed subdevices support interrupts. For the rest this register has no meaning.
-	subdevice->irq_status_reg = reg_base + ME6000_AO_IRQ_STATUS_REG;
-	subdevice->preload_reg = reg_base + ME6000_AO_PRELOAD_REG;
-
-	if (ao_idx == 0) {
-		subdevice->ctrl_reg = reg_base + ME6000_AO_00_CTRL_REG;
-		subdevice->status_reg = reg_base + ME6000_AO_00_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME6000_AO_00_FIFO_REG;
-		subdevice->timer_reg = reg_base + ME6000_AO_00_TIMER_REG;
-		subdevice->irq_reset_reg =
-		    reg_base + ME6000_AO_00_IRQ_RESET_REG;
-		subdevice->single_reg = reg_base + ME6000_AO_00_SINGLE_REG;
-	} else if (ao_idx == 1) {
-		subdevice->ctrl_reg = reg_base + ME6000_AO_01_CTRL_REG;
-		subdevice->status_reg = reg_base + ME6000_AO_01_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME6000_AO_01_FIFO_REG;
-		subdevice->timer_reg = reg_base + ME6000_AO_01_TIMER_REG;
-		subdevice->irq_reset_reg =
-		    reg_base + ME6000_AO_01_IRQ_RESET_REG;
-		subdevice->single_reg = reg_base + ME6000_AO_01_SINGLE_REG;
-	} else if (ao_idx == 2) {
-		subdevice->ctrl_reg = reg_base + ME6000_AO_02_CTRL_REG;
-		subdevice->status_reg = reg_base + ME6000_AO_02_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME6000_AO_02_FIFO_REG;
-		subdevice->timer_reg = reg_base + ME6000_AO_02_TIMER_REG;
-		subdevice->irq_reset_reg =
-		    reg_base + ME6000_AO_02_IRQ_RESET_REG;
-		subdevice->single_reg = reg_base + ME6000_AO_02_SINGLE_REG;
-	} else if (ao_idx == 3) {
-		subdevice->ctrl_reg = reg_base + ME6000_AO_03_CTRL_REG;
-		subdevice->status_reg = reg_base + ME6000_AO_03_STATUS_REG;
-		subdevice->fifo_reg = reg_base + ME6000_AO_03_FIFO_REG;
-		subdevice->timer_reg = reg_base + ME6000_AO_03_TIMER_REG;
-		subdevice->irq_reset_reg =
-		    reg_base + ME6000_AO_03_IRQ_RESET_REG;
-		subdevice->single_reg = reg_base + ME6000_AO_03_SINGLE_REG;
-	} else {
-		subdevice->ctrl_reg = reg_base + ME6000_AO_DUMY;
-		subdevice->fifo_reg = reg_base + ME6000_AO_DUMY;
-		subdevice->timer_reg = reg_base + ME6000_AO_DUMY;
-		subdevice->irq_reset_reg = reg_base + ME6000_AO_DUMY;
-		subdevice->single_reg = reg_base + ME6000_AO_DUMY;
-
-		subdevice->status_reg = reg_base + ME6000_AO_SINGLE_STATUS_REG;
-		if (ao_idx == 4) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_04_SINGLE_REG;
-		} else if (ao_idx == 5) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_05_SINGLE_REG;
-		} else if (ao_idx == 6) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_06_SINGLE_REG;
-		} else if (ao_idx == 7) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_07_SINGLE_REG;
-		} else if (ao_idx == 8) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_08_SINGLE_REG;
-		} else if (ao_idx == 9) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_09_SINGLE_REG;
-		} else if (ao_idx == 10) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_10_SINGLE_REG;
-		} else if (ao_idx == 11) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_11_SINGLE_REG;
-		} else if (ao_idx == 12) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_12_SINGLE_REG;
-		} else if (ao_idx == 13) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_13_SINGLE_REG;
-		} else if (ao_idx == 14) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_14_SINGLE_REG;
-		} else if (ao_idx == 15) {
-			subdevice->single_reg =
-			    reg_base + ME6000_AO_15_SINGLE_REG;
-		} else {
-			PERROR_CRITICAL("WRONG SUBDEVICE ID=%d!", ao_idx);
-			me_subdevice_deinit((me_subdevice_t *) subdevice);
-			if (subdevice->fifo) {
-				free_pages((unsigned long)subdevice->circ_buf.
-					   buf, ME6000_AO_CIRC_BUF_SIZE_ORDER);
-			}
-			subdevice->circ_buf.buf = NULL;
-			kfree(subdevice);
-			return NULL;
-		}
-	}
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Override base class methods. */
-	subdevice->base.me_subdevice_destructor = me6000_ao_destructor;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me6000_ao_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me6000_ao_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me6000_ao_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me6000_ao_io_single_write;
-	subdevice->base.me_subdevice_io_stream_config =
-	    me6000_ao_io_stream_config;
-	subdevice->base.me_subdevice_io_stream_new_values =
-	    me6000_ao_io_stream_new_values;
-	subdevice->base.me_subdevice_io_stream_write =
-	    me6000_ao_io_stream_write;
-	subdevice->base.me_subdevice_io_stream_start =
-	    me6000_ao_io_stream_start;
-	subdevice->base.me_subdevice_io_stream_status =
-	    me6000_ao_io_stream_status;
-	subdevice->base.me_subdevice_io_stream_stop = me6000_ao_io_stream_stop;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me6000_ao_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me6000_ao_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me6000_ao_query_subdevice_caps;
-	subdevice->base.me_subdevice_query_subdevice_caps_args =
-	    me6000_ao_query_subdevice_caps_args;
-	subdevice->base.me_subdevice_query_range_by_min_max =
-	    me6000_ao_query_range_by_min_max;
-	subdevice->base.me_subdevice_query_number_ranges =
-	    me6000_ao_query_number_ranges;
-	subdevice->base.me_subdevice_query_range_info =
-	    me6000_ao_query_range_info;
-	subdevice->base.me_subdevice_query_timer = me6000_ao_query_timer;
-
-	//prepare work queue and work function
-	subdevice->me6000_workqueue = me6000_wq;
-
-/* workqueue API changed in kernel 2.6.20 */
-	INIT_DELAYED_WORK(&subdevice->ao_control_task,
-			  me6000_ao_work_control_task);
-
-	if (subdevice->fifo) {	//Set speed
-		outl(ME6000_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
-		subdevice->hardware_stop_delay = HZ / 10;	//100ms
-	}
-
-	return subdevice;
-}
-
-/** @brief Stop presentation. Preserve FIFOs.
-*
-* @param instance The subdevice instance (pointer).
-*/
-inline int ao_stop_immediately(me6000_ao_subdevice_t *instance)
-{
-	unsigned long cpu_flags;
-	uint32_t ctrl;
-	int timeout;
-	int i;
-	uint32_t single_mask;
-
-	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 >
-	     (HZ / 10)) ? instance->hardware_stop_delay : HZ / 10;
-	for (i = 0; i <= timeout; i++) {
-		if (instance->fifo) {
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			// Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |=
-			    ME6000_AO_CTRL_BIT_STOP |
-			    ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
-			ctrl &=
-			    ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			if (!(inl(instance->status_reg) & ME6000_AO_STATUS_BIT_FSM)) {	// Exit.
-				break;
-			}
-		} else {
-			if (!(inl(instance->status_reg) & single_mask)) {	// Exit.
-				break;
-			}
-		}
-
-		PINFO("<%s> Wait for stop: %d\n", __func__, i);
-
-		//Still working!
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
-	}
-
-	if (i > timeout) {
-		PERROR_CRITICAL("FSM IS BUSY!\n");
-		return ME_ERRNO_INTERNAL;
-	}
-	return ME_ERRNO_SUCCESS;
-}
-
-/** @brief Copy data from circular buffer to fifo (fast) in wraparound.
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0.	No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-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;
-	uint32_t value;
-	int pos =
-	    (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
-	int local_count = count;
-	int i = 1;
-
-	if (count <= 0) {	//Wrong count!
-		return 0;
-	}
-
-	while (i < local_count) {
-		//Get value from buffer
-		value = *(instance->circ_buf.buf + pos);
-		//Prepare it
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-
-		pos++;
-		pos &= instance->circ_buf.mask;
-		if (pos == instance->circ_buf.head) {
-			pos = instance->circ_buf.tail;
-		}
-		i++;
-	}
-
-	status = inl(instance->status_reg);
-	if (!(status & ME6000_AO_STATUS_BIT_FF)) {	//FIFO is full before all datas were copied!
-		PERROR("idx=%d FIFO is full before all datas were copied!\n",
-		       instance->ao_idx);
-		return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-	} else {		//Add last value
-		value = *(instance->circ_buf.buf + pos);
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-	}
-
-	PINFO("idx=%d WRAPAROUND LOADED %d values\n", instance->ao_idx,
-	      local_count);
-	return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (fast).
-* @note This is time critical function. Checking is done at begining and end only.
-* @note The is not reasonable way to check how many walues was in FIFO at begining. The count must be managed externaly.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied data.
-* @return On error/success: 0.	No datas were copied => no data in buffer.
-* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
-*/
-inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
-			 int start_pos)
-{				/// @note This is time critical function!
-	uint32_t status;
-	uint32_t value;
-	int pos =
-	    (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
-	int local_count = count;
-	int max_count;
-	int i = 1;
-
-	if (count <= 0) {	//Wrong count!
-		return 0;
-	}
-
-	max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
-	if (max_count <= 0) {	//No data to copy!
-		return 0;
-	}
-
-	if (max_count < count) {
-		local_count = max_count;
-	}
-
-	while (i < local_count) {
-		//Get value from buffer
-		value = *(instance->circ_buf.buf + pos);
-		//Prepare it
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-
-		pos++;
-		pos &= instance->circ_buf.mask;
-		i++;
-	}
-
-	status = inl(instance->status_reg);
-	if (!(status & ME6000_AO_STATUS_BIT_FF)) {	//FIFO is full before all datas were copied!
-		PERROR("idx=%d FIFO is full before all datas were copied!\n",
-		       instance->ao_idx);
-		return -ME_ERRNO_FIFO_BUFFER_OVERFLOW;
-	} else {		//Add last value
-		value = *(instance->circ_buf.buf + pos);
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-	}
-
-	PINFO("idx=%d FAST LOADED %d values\n", instance->ao_idx, local_count);
-	return local_count;
-}
-
-/** @brief Copy data from software buffer to fifo (slow).
-* @note This is slow function that copy all data from buffer to FIFO with full control.
-*
-* @param instance The subdevice instance (pointer).
-* @param count Maximum number of copied data.
-* @param start_pos Position of the firs value in buffer.
-*
-* @return On success: Number of copied values.
-* @return On error/success: 0.	FIFO was full at begining.
-* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
-*/
-inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
-				 int start_pos)
-{				/// @note This is slow function!
-	uint32_t status;
-	uint32_t value;
-	int pos =
-	    (instance->circ_buf.tail + start_pos) & instance->circ_buf.mask;
-	int local_count = count;
-	int i;
-	int max_count;
-
-	if (count <= 0) {	//Wrong count!
-		PERROR("idx=%d SLOW LOADED: Wrong count!\n", instance->ao_idx);
-		return 0;
-	}
-
-	max_count = me_circ_buf_values(&instance->circ_buf) - start_pos;
-	if (max_count <= 0) {	//No data to copy!
-		PERROR("idx=%d SLOW LOADED: No data to copy!\n",
-		       instance->ao_idx);
-		return 0;
-	}
-
-	if (max_count < count) {
-		local_count = max_count;
-	}
-
-	for (i = 0; i < local_count; i++) {
-		status = inl(instance->status_reg);
-		if (!(status & ME6000_AO_STATUS_BIT_FF)) {	//FIFO is full!
-			return i;
-		}
-		//Get value from buffer
-		value = *(instance->circ_buf.buf + pos);
-		//Prepare it
-		if (instance->ao_idx & 0x1) {
-			value <<= 16;
-		}
-		//Put value to FIFO
-		outl(value, instance->fifo_reg);
-		//PDEBUG_REG("idx=%d fifo_reg outl(0x%lX+0x%lX)=0x%x\n", instance->ao_idx, instance->reg_base, instance->fifo_reg - instance->reg_base, value);
-
-		pos++;
-		pos &= instance->circ_buf.mask;
-	}
-
-	PINFO("idx=%d SLOW LOADED %d values\n", instance->ao_idx, local_count);
-	return local_count;
-}
-
-/** @brief Copy data from user space to circular buffer.
-* @param instance The subdevice instance (pointer).
-* @param count Number of datas in user space.
-* @param user_values Buffer's pointer.
-*
-* @return On success: Number of copied values.
-* @return On error: -ME_ERRNO_INTERNAL.
-*/
-inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
-				 int *user_values)
-{
-	int i, err;
-	int empty_space;
-	int copied;
-	int value;
-
-	empty_space = me_circ_buf_space(&instance->circ_buf);
-	//We have only this space free.
-	copied = (count < empty_space) ? count : empty_space;
-	for (i = 0; i < copied; i++) {	//Copy from user to buffer
-		if ((err = get_user(value, (int *)(user_values + i)))) {
-			PERROR
-			    ("idx=%d BUFFER LOADED: get_user(0x%p) return an error: %d\n",
-			     instance->ao_idx, user_values + i, err);
-			return -ME_ERRNO_INTERNAL;
-		}
-		/// @note The analog output in me6000 series has size of 16 bits.
-		*(instance->circ_buf.buf + instance->circ_buf.head) =
-		    (uint16_t) value;
-		instance->circ_buf.head++;
-		instance->circ_buf.head &= instance->circ_buf.mask;
-	}
-
-	PINFO("idx=%d BUFFER LOADED %d values\n", instance->ao_idx, copied);
-	return copied;
-}
-
-static void me6000_ao_work_control_task(struct work_struct *work)
-{
-	me6000_ao_subdevice_t *instance;
-	unsigned long cpu_flags = 0;
-	uint32_t status;
-	uint32_t ctrl;
-	uint32_t synch;
-	int reschedule = 0;
-	int signaling = 0;
-	uint32_t single_mask;
-
-	instance =
-	    container_of((void *)work, me6000_ao_subdevice_t, ao_control_task);
-	PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
-	      instance->ao_idx);
-
-	status = inl(instance->status_reg);
-	PDEBUG_REG("status_reg inl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->status_reg - instance->reg_base, status);
-
-/// @note AO_STATUS_BIT_FSM doesn't work as should be for pure single channels (idx>=4)
-//      single_mask = (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET < 0) ? 0x0000 : (0x0001 << (instance->ao_idx-ME6000_AO_SINGLE_STATUS_OFFSET));
-	single_mask = *instance->triggering_flags & (0x1 << instance->ao_idx);
-
-	switch (instance->status) {	// Checking actual mode.
-
-		// Not configured for work.
-	case ao_status_none:
-		break;
-
-		//This are stable modes. No need to do anything. (?)
-	case ao_status_single_configured:
-	case ao_status_stream_configured:
-	case ao_status_stream_fifo_error:
-	case ao_status_stream_buffer_error:
-	case ao_status_stream_error:
-		PERROR("Shouldn't be running!.\n");
-		break;
-
-		// Single modes
-	case ao_status_single_run_wait:
-	case ao_status_single_run:
-	case ao_status_single_end_wait:
-		if (instance->fifo) {	// Extra registers.
-			if (!(status & ME6000_AO_STATUS_BIT_FSM)) {	// State machine is not working.
-				if (((instance->fifo & ME6000_AO_HAS_FIFO)
-				     && (!(status & ME6000_AO_STATUS_BIT_EF)))
-				    || (!(instance->fifo & ME6000_AO_HAS_FIFO))) {	// Single is in end state.
-					PDEBUG
-					    ("Single call has been complited.\n");
-
-					// Set correct value for single_read();
-					instance->single_value =
-					    instance->single_value_in_fifo;
-
-					// Set status as 'ao_status_single_end'
-					instance->status = ao_status_single_end;
-
-					spin_lock(instance->preload_reg_lock);
-					if ((single_mask) && (*instance->preload_flags & (ME6000_AO_SYNC_HOLD << instance->ao_idx))) {	// This is one of synchronous start channels. Set all as triggered.
-						*instance->triggering_flags =
-						    0x00000000;
-					} else {
-						//Set this channel as triggered (none active).
-						*instance->triggering_flags &=
-						    ~(0x1 << instance->ao_idx);
-					}
-					spin_unlock(instance->preload_reg_lock);
-
-					// Signal the end.
-					signaling = 1;
-					// Wait for stop ISM.
-					reschedule = 1;
-
-					break;
-				}
-			}
-			// Check timeout.
-			if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) {	// Timeout
-				PDEBUG("Timeout reached.\n");
-				// Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
-				spin_lock_irqsave(&instance->subdevice_lock,
-						  cpu_flags);
-				ctrl = inl(instance->ctrl_reg);
-				ctrl |=
-				    ME6000_AO_CTRL_BIT_STOP |
-				    ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
-				ctrl &=
-				    ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
-				      ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
-				ctrl &=
-				    ~(ME6000_AO_CTRL_BIT_EX_TRIG_EDGE |
-				      ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH);
-				//Disabling FIFO
-				ctrl &= ~ME6000_AO_CTRL_BIT_ENABLE_FIFO;
-
-				outl(ctrl, instance->ctrl_reg);
-				PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->ctrl_reg -
-					   instance->reg_base, ctrl);
-				spin_unlock_irqrestore(&instance->
-						       subdevice_lock,
-						       cpu_flags);
-
-				//Reset interrupt latch
-				inl(instance->irq_reset_reg);
-
-				spin_lock(instance->preload_reg_lock);
-				//Remove from synchronous start. Block triggering from this output.
-				synch = inl(instance->preload_reg);
-				synch &=
-				    ~((ME6000_AO_SYNC_HOLD |
-				       ME6000_AO_SYNC_EXT_TRIG) << instance->
-				      ao_idx);
-				if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {	// No FIFO - set to single safe mode
-					synch |=
-					    ME6000_AO_SYNC_HOLD << instance->
-					    ao_idx;
-				}
-				outl(synch, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     synch);
-				//Set this channel as triggered (none active).
-				*instance->triggering_flags &=
-				    ~(0x1 << instance->ao_idx);
-				spin_unlock(instance->preload_reg_lock);
-
-				// Set correct value for single_read();
-				instance->single_value_in_fifo =
-				    instance->single_value;
-
-				instance->status = ao_status_single_end;
-
-				// Signal the end.
-				signaling = 1;
-			}
-		} else {	// No extra registers.
-/*
-				if (!(status & single_mask))
-				{// State machine is not working.
-					PDEBUG("Single call has been complited.\n");
-
-					// Set correct value for single_read();
-					instance->single_value = instance->single_value_in_fifo;
-
-					// Set status as 'ao_status_single_end'
-					instance->status = ao_status_single_end;
-
-					// Signal the end.
-					signaling = 1;
-					// Wait for stop ISM.
-					reschedule = 1;
-
-					break;
-				}
-*/
-			if (!single_mask) {	// Was triggered.
-				PDEBUG("Single call has been complited.\n");
-
-				// Set correct value for single_read();
-				instance->single_value =
-				    instance->single_value_in_fifo;
-
-				// Set status as 'ao_status_single_end'
-				instance->status = ao_status_single_end;
-
-				// Signal the end.
-				signaling = 1;
-
-				break;
-			}
-			// Check timeout.
-			if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) {	// Timeout
-				PDEBUG("Timeout reached.\n");
-
-				spin_lock(instance->preload_reg_lock);
-				//Remove from synchronous start. Block triggering from this output.
-				synch = inl(instance->preload_reg);
-				synch &=
-				    ~(ME6000_AO_SYNC_EXT_TRIG << instance->
-				      ao_idx);
-				synch |=
-				    ME6000_AO_SYNC_HOLD << instance->ao_idx;
-
-				outl(synch, instance->preload_reg);
-				PDEBUG_REG
-				    ("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->preload_reg - instance->reg_base,
-				     synch);
-				//Set this channel as triggered (none active).
-				*instance->triggering_flags &=
-				    ~(0x1 << instance->ao_idx);
-				spin_unlock(instance->preload_reg_lock);
-
-				// Restore old settings.
-				PDEBUG("Write old value back to register.\n");
-				outl(instance->single_value,
-				     instance->single_reg);
-				PDEBUG_REG
-				    ("single_reg outl(0x%lX+0x%lX)=0x%x\n",
-				     instance->reg_base,
-				     instance->single_reg - instance->reg_base,
-				     instance->single_value);
-
-				// Set correct value for single_read();
-				instance->single_value_in_fifo =
-				    instance->single_value;
-
-				instance->status = ao_status_single_end;
-
-				// Signal the end.
-				signaling = 1;
-			}
-		}
-
-		// Wait for stop.
-		reschedule = 1;
-		break;
-
-	case ao_status_stream_end:
-		if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {	// No FIFO
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-	case ao_status_single_end:
-		if (instance->fifo) {	// Extra registers.
-			if (status & ME6000_AO_STATUS_BIT_FSM) {	// State machine is working but the status is set to end. Force stop.
-
-				// Wait for stop.
-				reschedule = 1;
-			}
-
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			// Stop all actions. No conditions! Block interrupts and trigger. Leave FIFO untouched!
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |=
-			    ME6000_AO_CTRL_BIT_IMMEDIATE_STOP |
-			    ME6000_AO_CTRL_BIT_STOP;
-			ctrl &=
-			    ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			//Reset interrupt latch
-			inl(instance->irq_reset_reg);
-		} else {	// No extra registers.
-/*
-				if (status & single_mask)
-				{// State machine is working but the status is set to end. Force stop.
-
-					// Wait for stop.
-					reschedule = 1;
-				}
-*/
-		}
-		break;
-
-		// Stream modes
-	case ao_status_stream_run_wait:
-		if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {	// No FIFO
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-
-		if (status & ME6000_AO_STATUS_BIT_FSM) {	// State machine is working. Waiting for start finish.
-			instance->status = ao_status_stream_run;
-
-			// Signal end of this step
-			signaling = 1;
-		} else {	// State machine is not working.
-			if (!(status & ME6000_AO_STATUS_BIT_EF)) {	// FIFO is empty. Procedure has started and finish already!
-				instance->status = ao_status_stream_end;
-
-				// Signal the end.
-				signaling = 1;
-				// Wait for stop.
-				reschedule = 1;
-				break;
-			}
-		}
-
-		// Check timeout.
-		if ((instance->timeout.delay) && ((jiffies - instance->timeout.start_time) >= instance->timeout.delay)) {	// Timeout
-			PDEBUG("Timeout reached.\n");
-			// Stop all actions. No conditions! Block interrupts. Leave FIFO untouched!
-			spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-			ctrl = inl(instance->ctrl_reg);
-			ctrl |=
-			    ME6000_AO_CTRL_BIT_STOP |
-			    ME6000_AO_CTRL_BIT_IMMEDIATE_STOP;
-			ctrl &=
-			    ~(ME6000_AO_CTRL_BIT_ENABLE_IRQ |
-			      ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG);
-			outl(ctrl, instance->ctrl_reg);
-			PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->ctrl_reg - instance->reg_base,
-				   ctrl);
-			spin_unlock_irqrestore(&instance->subdevice_lock,
-					       cpu_flags);
-
-			//Reset interrupt latch
-			inl(instance->irq_reset_reg);
-
-			spin_lock(instance->preload_reg_lock);
-			//Remove from synchronous start. Block triggering from this output.
-			synch = inl(instance->preload_reg);
-			synch &=
-			    ~((ME6000_AO_SYNC_HOLD | ME6000_AO_SYNC_EXT_TRIG) <<
-			      instance->ao_idx);
-			outl(synch, instance->preload_reg);
-			PDEBUG_REG("preload_reg outl(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->preload_reg - instance->reg_base,
-				   synch);
-			spin_unlock(instance->preload_reg_lock);
-
-			instance->status = ao_status_stream_end;
-
-			// Signal the end.
-			signaling = 1;
-		}
-		// Wait for stop.
-		reschedule = 1;
-		break;
-
-	case ao_status_stream_run:
-		if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {	// No FIFO
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-
-		if (!(status & ME6000_AO_STATUS_BIT_FSM)) {	// State machine is not working. This is an error.
-			// BROKEN PIPE!
-			if (!(status & ME6000_AO_STATUS_BIT_EF)) {	// FIFO is empty.
-				if (me_circ_buf_values(&instance->circ_buf)) {	// Software buffer is not empty.
-					if (instance->stop_data_count && (instance->stop_data_count <= instance->data_count)) {	//Finishing work. Requed data shown.
-						PDEBUG
-						    ("ISM stoped. No data in FIFO. Buffer is not empty.\n");
-						instance->status =
-						    ao_status_stream_end;
-					} else {
-						PERROR
-						    ("Output stream has been broken. ISM stoped. No data in FIFO. Buffer is not empty.\n");
-						instance->status =
-						    ao_status_stream_buffer_error;
-					}
-				} else {	// Software buffer is empty.
-					PDEBUG
-					    ("ISM stoped. No data in FIFO. Buffer is empty.\n");
-					instance->status = ao_status_stream_end;
-				}
-			} else {	// There are still datas in FIFO.
-				if (me_circ_buf_values(&instance->circ_buf)) {	// Software buffer is not empty.
-					PERROR
-					    ("Output stream has been broken. ISM stoped but some data in FIFO and buffer.\n");
-				} else {	// Software buffer is empty.
-					PERROR
-					    ("Output stream has been broken. ISM stoped but some data in FIFO. Buffer is empty.\n");
-				}
-				instance->status = ao_status_stream_fifo_error;
-
-			}
-
-			// Signal the failure.
-			signaling = 1;
-			break;
-		}
-		// Wait for stop.
-		reschedule = 1;
-		break;
-
-	case ao_status_stream_end_wait:
-		if (!(instance->fifo & ME6000_AO_HAS_FIFO)) {	// No FIFO
-			PERROR_CRITICAL
-			    ("Streaming on single device! This feature is not implemented in this version!\n");
-			instance->status = ao_status_stream_error;
-			// Signal the end.
-			signaling = 1;
-			break;
-		}
-
-		if (!(status & ME6000_AO_STATUS_BIT_FSM)) {	// State machine is not working. Waiting for stop finish.
-			instance->status = ao_status_stream_end;
-			signaling = 1;
-		}
-		// State machine is working.
-		reschedule = 1;
-		break;
-
-	default:
-		PERROR_CRITICAL("Status is in wrong state (%d)!\n",
-				instance->status);
-		instance->status = ao_status_stream_error;
-		// Signal the end.
-		signaling = 1;
-		break;
-
-	}
-
-	if (signaling) {	//Signal it.
-		wake_up_interruptible_all(&instance->wait_queue);
-	}
-
-	if (instance->ao_control_task_flag && reschedule) {	// Reschedule task
-		queue_delayed_work(instance->me6000_workqueue,
-				   &instance->ao_control_task, 1);
-	} else {
-		PINFO("<%s> Ending control task.\n", __func__);
-	}
-
-}
-
-static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
-					    int unit,
-					    int *min,
-					    int *max, int *maxdata, int *range)
-{
-	me6000_ao_subdevice_t *instance;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if ((*max - *min) < 0) {
-		PERROR("Invalid minimum and maximum values specified.\n");
-		return ME_ERRNO_INVALID_MIN_MAX;
-	}
-
-	if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
-		if ((*max <= (instance->max + 1000)) && (*min >= instance->min)) {
-			*min = instance->min;
-			*max = instance->max;
-			*maxdata = ME6000_AO_MAX_DATA;
-			*range = 0;
-		} else {
-			PERROR("No matching range available.\n");
-			return ME_ERRNO_NO_RANGE;
-		}
-	} else {
-		PERROR("Invalid physical unit specified.\n");
-		return ME_ERRNO_INVALID_UNIT;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
-					 int unit, int *count)
-{
-	me6000_ao_subdevice_t *instance;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if ((unit == ME_UNIT_VOLT) || (unit == ME_UNIT_ANY)) {
-		*count = 1;
-	} else {
-		*count = 0;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
-				      int range,
-				      int *unit,
-				      int *min, int *max, int *maxdata)
-{
-	me6000_ao_subdevice_t *instance;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (range == 0) {
-		*unit = ME_UNIT_VOLT;
-		*min = instance->min;
-		*max = instance->max;
-		*maxdata = ME6000_AO_MAX_DATA;
-	} else {
-		PERROR("Invalid range number specified.\n");
-		return ME_ERRNO_INVALID_RANGE;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_timer(me_subdevice_t *subdevice,
-				 int timer,
-				 int *base_frequency,
-				 long long *min_ticks, long long *max_ticks)
-{
-	me6000_ao_subdevice_t *instance;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (instance->fifo) {	//Streaming device.
-		*base_frequency = ME6000_AO_BASE_FREQUENCY;
-		if (timer == ME_TIMER_ACQ_START) {
-			*min_ticks = ME6000_AO_MIN_ACQ_TICKS;
-			*max_ticks = ME6000_AO_MAX_ACQ_TICKS;
-		} else if (timer == ME_TIMER_CONV_START) {
-			*min_ticks = ME6000_AO_MIN_CHAN_TICKS;
-			*max_ticks = ME6000_AO_MAX_CHAN_TICKS;
-		}
-	} else {		//Not streaming device!
-		*base_frequency = 0;
-		*min_ticks = 0;
-		*max_ticks = 0;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	me6000_ao_subdevice_t *instance;
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*number = 1;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	me6000_ao_subdevice_t *instance;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*type = ME_TYPE_AO;
-	*subtype =
-	    (instance->
-	     fifo & ME6000_AO_HAS_FIFO) ? ME_SUBTYPE_STREAMING :
-	    ME_SUBTYPE_SINGLE;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	me6000_ao_subdevice_t *instance;
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	*caps =
-	    ME_CAPS_AO_TRIG_SYNCHRONOUS | ((instance->fifo) ? ME_CAPS_AO_FIFO :
-					   ME_CAPS_NONE);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
-					       int cap, int *args, int count)
-{
-	me6000_ao_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	instance = (me6000_ao_subdevice_t *) subdevice;
-
-	PDEBUG("executed. idx=%d\n", instance->ao_idx);
-
-	if (count != 1) {
-		PERROR("Invalid capability argument count.\n");
-		return ME_ERRNO_INVALID_CAP_ARG_COUNT;
-	}
-
-	switch (cap) {
-	case ME_CAP_AI_FIFO_SIZE:
-		args[0] = (instance->fifo) ? ME6000_AO_FIFO_COUNT : 0;
-		break;
-
-	case ME_CAP_AI_BUFFER_SIZE:
-		args[0] =
-		    (instance->circ_buf.buf) ? ME6000_AO_CIRC_BUF_COUNT : 0;
-		break;
-
-	default:
-		PERROR("Invalid capability.\n");
-		err = ME_ERRNO_INVALID_CAP;
-		args[0] = 0;
-	}
-
-	return err;
-}
diff --git a/drivers/staging/meilhaus/me6000_ao.h b/drivers/staging/meilhaus/me6000_ao.h
deleted file mode 100644
index d86fb29..0000000
--- a/drivers/staging/meilhaus/me6000_ao.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * @file me6000_ao.h
- *
- * @brief Meilhaus ME-6000 analog output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME6000_AO_H_
-#define _ME6000_AO_H_
-
-#include "mesubdevice.h"
-#include "mecirc_buf.h"
-#include "meioctl.h"
-
-#ifdef __KERNEL__
-
-#define ME6000_AO_MAX_SUBDEVICES	16
-#define ME6000_AO_FIFO_COUNT		8192
-
-#define ME6000_AO_BASE_FREQUENCY	33000000L
-
-#define ME6000_AO_MIN_ACQ_TICKS		0LL
-#define ME6000_AO_MAX_ACQ_TICKS		0LL
-
-#define ME6000_AO_MIN_CHAN_TICKS	66LL
-#define ME6000_AO_MAX_CHAN_TICKS	0xFFFFFFFFLL
-
-#define ME6000_AO_MIN_RANGE			-10000000
-#define ME6000_AO_MAX_RANGE			9999694
-
-#define ME6000_AO_MIN_RANGE_HIGH	0
-#define ME6000_AO_MAX_RANGE_HIGH	49999237
-
-#define ME6000_AO_MAX_DATA			0xFFFF
-
-#ifdef ME_SYNAPSE
-# define ME6000_AO_CIRC_BUF_SIZE_ORDER 		8	// 2^n PAGES =>> Maximum value of 1MB for Synapse
-#else
-# define ME6000_AO_CIRC_BUF_SIZE_ORDER 		5	// 2^n PAGES =>> 128KB
-#endif
-#define ME6000_AO_CIRC_BUF_SIZE 		PAGE_SIZE<<ME6000_AO_CIRC_BUF_SIZE_ORDER	// Buffer size in bytes.
-
-#  ifdef _CBUFF_32b_t
-#   define ME6000_AO_CIRC_BUF_COUNT	((ME6000_AO_CIRC_BUF_SIZE) / sizeof(uint32_t))	// Size in values
-#  else
-#   define ME6000_AO_CIRC_BUF_COUNT	((ME6000_AO_CIRC_BUF_SIZE) / sizeof(uint16_t))	// Size in values
-#  endif
-
-#  define ME6000_AO_CONTINOUS					0x0
-#  define ME6000_AO_WRAP_MODE					0x1
-#  define ME6000_AO_HW_MODE						0x2
-
-#  define ME6000_AO_HW_WRAP_MODE				(ME6000_AO_WRAP_MODE | ME6000_AO_HW_MODE)
-#  define ME6000_AO_SW_WRAP_MODE				ME6000_AO_WRAP_MODE
-
-#  define ME6000_AO_INF_STOP_MODE				0x0
-#  define ME6000_AO_ACQ_STOP_MODE				0x1
-#  define ME6000_AO_SCAN_STOP_MODE				0x2
-
-#  define ME6000_AO_EXTRA_HARDWARE				0x1
-#  define ME6000_AO_HAS_FIFO					0x2
-
-typedef enum ME6000_AO_STATUS {
-	ao_status_none = 0,
-	ao_status_single_configured,
-	ao_status_single_run_wait,
-	ao_status_single_run,
-	ao_status_single_end_wait,
-	ao_status_single_end,
-	ao_status_stream_configured,
-	ao_status_stream_run_wait,
-	ao_status_stream_run,
-	ao_status_stream_end_wait,
-	ao_status_stream_end,
-	ao_status_stream_fifo_error,
-	ao_status_stream_buffer_error,
-	ao_status_stream_error,
-	ao_status_last
-} ME6000_AO_STATUS;
-
-typedef struct me6000_ao_timeout {
-	unsigned long start_time;
-	unsigned long delay;
-} me6000_ao_timeout_t;
-
-/**
- * @brief The ME-6000 analog output subdevice class.
- */
-typedef struct me6000_ao_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;					/**< The subdevice base class. */
-	unsigned int ao_idx;
-
-	/* Attributes */
-	spinlock_t subdevice_lock;				/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *preload_reg_lock;			/**< Spin lock to protect preload_reg from concurrent access. */
-
-	uint32_t *preload_flags;
-	uint32_t *triggering_flags;
-
-	/* Hardware feautres */
-	unsigned int irq;						/**< The interrupt request number assigned by the PCI BIOS. */
-	int fifo;								/**< If set this device has a FIFO. */
-
-	//Range
-	int min;
-	int max;
-
-	int single_value;						/**< Mirror of the output value in single mode. */
-	int single_value_in_fifo;				/**< Mirror of the value written in single mode. */
-	uint32_t ctrl_trg;						/**< Mirror of the trigger settings. */
-
-	volatile int mode;						/**< Flags used for storing SW wraparound setup*/
-	int stop_mode;							/**< The user defined stop condition flag. */
-	unsigned int start_mode;
-	unsigned int stop_count;				/**< The user defined dates presentation end count. */
-	unsigned int stop_data_count;			/**< The stop presentation count. */
-	unsigned int data_count;				/**< The real presentation count. */
-	unsigned int preloaded_count;			/**< The next data addres in buffer. <= for wraparound mode. */
-	int hardware_stop_delay;				/**< The time that stop can take. This is only to not show hardware bug to user. */
-
-	volatile enum ME6000_AO_STATUS status;	/**< The current stream status flag. */
-	me6000_ao_timeout_t timeout;			/**< The timeout for start in blocking and non-blocking mode. */
-
-									/* Registers *//**< All registers are 32 bits long. */
-	unsigned long ctrl_reg;
-	unsigned long status_reg;
-	unsigned long fifo_reg;
-	unsigned long single_reg;
-	unsigned long timer_reg;
-	unsigned long irq_status_reg;
-	unsigned long preload_reg;
-	unsigned long irq_reset_reg;
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-
-	/* Software buffer */
-	me_circ_buf_t circ_buf;					/**< Circular buffer holding measurment data. */
-	wait_queue_head_t wait_queue;			/**< Wait queue to put on tasks waiting for data to arrive. */
-
-	struct workqueue_struct *me6000_workqueue;
-	struct delayed_work ao_control_task;
-
-	volatile int ao_control_task_flag;		/**< Flag controling reexecuting of control task */
-
-} me6000_ao_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-6000 analog output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
- * @param ao_idx Subdevice number.
- * @param fifo Flag set if subdevice has hardware FIFO.
- * @param irq IRQ number.
- * @param high_range Flag set if subdevice has high curren output.
- * @param me6000_wq Queue for asynchronous task (1 queue for all subdevice on 1 board).
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
-					     spinlock_t * preload_reg_lock,
-					     uint32_t * preload_flags,
-					     uint32_t * triggering_flags,
-					     int ao_idx,
-					     int fifo,
-					     int irq,
-					     int high_range,
-					     struct workqueue_struct
-					     *me6000_wq);
-
-#endif //__KERNEL__
-#endif //_ME6000_AO_H_
diff --git a/drivers/staging/meilhaus/me6000_ao_reg.h b/drivers/staging/meilhaus/me6000_ao_reg.h
deleted file mode 100644
index eb8f46e..0000000
--- a/drivers/staging/meilhaus/me6000_ao_reg.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * @file me6000_ao_reg.h
- *
- * @brief ME-6000 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME6000_AO_REG_H_
-#define _ME6000_AO_REG_H_
-
-#ifdef __KERNEL__
-
-// AO
-#define ME6000_AO_00_CTRL_REG					0x00	// R/W
-#define ME6000_AO_00_STATUS_REG					0x04	// R/_
-#define ME6000_AO_00_FIFO_REG					0x08	// _/W
-#define ME6000_AO_00_SINGLE_REG					0x0C	// R/W
-#define ME6000_AO_00_TIMER_REG					0x10	// _/W
-
-#define ME6000_AO_01_CTRL_REG					0x18	// R/W
-#define ME6000_AO_01_STATUS_REG					0x1C	// R/_
-#define ME6000_AO_01_FIFO_REG					0x20	// _/W
-#define ME6000_AO_01_SINGLE_REG					0x24	// R/W
-#define ME6000_AO_01_TIMER_REG					0x28	// _/W
-
-#define ME6000_AO_02_CTRL_REG					0x30	// R/W
-#define ME6000_AO_02_STATUS_REG					0x34	// R/_
-#define ME6000_AO_02_FIFO_REG					0x38	// _/W
-#define ME6000_AO_02_SINGLE_REG					0x3C	// R/W
-#define ME6000_AO_02_TIMER_REG					0x40	// _/W
-
-#define ME6000_AO_03_CTRL_REG					0x48	// R/W
-#define ME6000_AO_03_STATUS_REG					0x4C	// R/_
-#define ME6000_AO_03_FIFO_REG					0x50	// _/W
-#define ME6000_AO_03_SINGLE_REG					0x54	// R/W
-#define ME6000_AO_03_TIMER_REG					0x58	// _/W
-
-#define ME6000_AO_SINGLE_STATUS_REG				0xA4	// R/_
-#define ME6000_AO_SINGLE_STATUS_OFFSET			4	//The first single subdevice => bit 0 in ME6000_AO_SINGLE_STATUS_REG.
-
-#define ME6000_AO_04_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_04_SINGLE_REG					0x74	// _/W
-
-#define ME6000_AO_05_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_05_SINGLE_REG					0x78	// _/W
-
-#define ME6000_AO_06_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_06_SINGLE_REG					0x7C	// _/W
-
-#define ME6000_AO_07_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_07_SINGLE_REG					0x80	// _/W
-
-#define ME6000_AO_08_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_08_SINGLE_REG					0x84	// _/W
-
-#define ME6000_AO_09_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_09_SINGLE_REG					0x88	// _/W
-
-#define ME6000_AO_10_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_10_SINGLE_REG					0x8C	// _/W
-
-#define ME6000_AO_11_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_11_SINGLE_REG					0x90	// _/W
-
-#define ME6000_AO_12_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_12_SINGLE_REG					0x94	// _/W
-
-#define ME6000_AO_13_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_13_SINGLE_REG					0x98	// _/W
-
-#define ME6000_AO_14_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_14_SINGLE_REG					0x9C	// _/W
-
-#define ME6000_AO_15_STATUS_REG					ME6000_AO_SINGLE_STATUS_REG
-#define ME6000_AO_15_SINGLE_REG					0xA0	// _/W
-
-//ME6000_AO_CTRL_REG
-#define ME6000_AO_MODE_SINGLE					0x00
-#define ME6000_AO_MODE_WRAPAROUND				0x01
-#define ME6000_AO_MODE_CONTINUOUS				0x02
-#define ME6000_AO_CTRL_MODE_MASK				(ME6000_AO_MODE_WRAPAROUND | ME6000_AO_MODE_CONTINUOUS)
-
-#define ME6000_AO_CTRL_BIT_MODE_WRAPAROUND		0x001
-#define ME6000_AO_CTRL_BIT_MODE_CONTINUOUS		0x002
-#define ME6000_AO_CTRL_BIT_STOP					0x004
-#define ME6000_AO_CTRL_BIT_ENABLE_FIFO			0x008
-#define ME6000_AO_CTRL_BIT_ENABLE_EX_TRIG		0x010
-#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE			0x020
-#define ME6000_AO_CTRL_BIT_ENABLE_IRQ			0x040
-#define ME6000_AO_CTRL_BIT_IMMEDIATE_STOP		0x080
-#define ME6000_AO_CTRL_BIT_EX_TRIG_EDGE_BOTH 	0x800
-
-//ME6000_AO_STATUS_REG
-#define ME6000_AO_STATUS_BIT_FSM				0x01
-#define ME6000_AO_STATUS_BIT_FF					0x02
-#define ME6000_AO_STATUS_BIT_HF					0x04
-#define ME6000_AO_STATUS_BIT_EF					0x08
-
-#define ME6000_AO_PRELOAD_REG					0xA8	// R/W    ///ME6000_AO_SYNC_REG <==> ME6000_AO_PRELOAD_REG
-/*
-#define ME6000_AO_SYNC_HOLD_0					0x00000001
-#define ME6000_AO_SYNC_HOLD_1					0x00000002
-#define ME6000_AO_SYNC_HOLD_2					0x00000004
-#define ME6000_AO_SYNC_HOLD_3					0x00000008
-#define ME6000_AO_SYNC_HOLD_4					0x00000010
-#define ME6000_AO_SYNC_HOLD_5					0x00000020
-#define ME6000_AO_SYNC_HOLD_6					0x00000040
-#define ME6000_AO_SYNC_HOLD_7					0x00000080
-#define ME6000_AO_SYNC_HOLD_8					0x00000100
-#define ME6000_AO_SYNC_HOLD_9					0x00000200
-#define ME6000_AO_SYNC_HOLD_10					0x00000400
-#define ME6000_AO_SYNC_HOLD_11					0x00000800
-#define ME6000_AO_SYNC_HOLD_12					0x00001000
-#define ME6000_AO_SYNC_HOLD_13					0x00002000
-#define ME6000_AO_SYNC_HOLD_14					0x00004000
-#define ME6000_AO_SYNC_HOLD_15					0x00008000
-*/
-#define ME6000_AO_SYNC_HOLD						0x00000001
-/*
-#define ME6000_AO_SYNC_EXT_TRIG_0				0x00010000
-#define ME6000_AO_SYNC_EXT_TRIG_1				0x00020000
-#define ME6000_AO_SYNC_EXT_TRIG_2				0x00040000
-#define ME6000_AO_SYNC_EXT_TRIG_3				0x00080000
-#define ME6000_AO_SYNC_EXT_TRIG_4				0x00100000
-#define ME6000_AO_SYNC_EXT_TRIG_5				0x00200000
-#define ME6000_AO_SYNC_EXT_TRIG_6				0x00400000
-#define ME6000_AO_SYNC_EXT_TRIG_7				0x00800000
-#define ME6000_AO_SYNC_EXT_TRIG_8				0x01000000
-#define ME6000_AO_SYNC_EXT_TRIG_9				0x02000000
-#define ME6000_AO_SYNC_EXT_TRIG_10				0x04000000
-#define ME6000_AO_SYNC_EXT_TRIG_11				0x08000000
-#define ME6000_AO_SYNC_EXT_TRIG_12				0x10000000
-#define ME6000_AO_SYNC_EXT_TRIG_13				0x20000000
-#define ME6000_AO_SYNC_EXT_TRIG_14				0x40000000
-#define ME6000_AO_SYNC_EXT_TRIG_15				0x80000000
-*/
-#define ME6000_AO_SYNC_EXT_TRIG					0x00010000
-
-#define ME6000_AO_EXT_TRIG						0x80000000
-
-// AO-IRQ
-#define ME6000_AO_IRQ_STATUS_REG				0x60	// R/_
-#define ME6000_AO_00_IRQ_RESET_REG				0x64	// R/_
-#define ME6000_AO_01_IRQ_RESET_REG				0x68	// R/_
-#define ME6000_AO_02_IRQ_RESET_REG				0x6C	// R/_
-#define ME6000_AO_03_IRQ_RESET_REG				0x70	// R/_
-
-#define ME6000_IRQ_STATUS_BIT_0					0x01
-#define ME6000_IRQ_STATUS_BIT_1					0x02
-#define ME6000_IRQ_STATUS_BIT_2					0x04
-#define ME6000_IRQ_STATUS_BIT_3					0x08
-
-#define ME6000_IRQ_STATUS_BIT_AO_HF				ME6000_IRQ_STATUS_BIT_0
-
-//DUMY register
-#define ME6000_AO_DUMY									0xFC
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_device.c b/drivers/staging/meilhaus/me6000_device.c
deleted file mode 100644
index 1a6cf7f..0000000
--- a/drivers/staging/meilhaus/me6000_device.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * @file me6000_device.c
- *
- * @brief Device class template implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "mefirmware.h"
-
-#include "mesubdevice.h"
-#include "medebug.h"
-#include "medevice.h"
-#include "me6000_reg.h"
-#include "me6000_device.h"
-#include "meplx_reg.h"
-#include "me6000_dio.h"
-#include "me6000_ao.h"
-
-/**
- * @brief Global variable.
- * This is working queue for runing a separate atask that will be responsible for work status (start, stop, timeouts).
- */
-static struct workqueue_struct *me6000_workqueue;
-
-me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
-{
-	me6000_device_t *me6000_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	int err;
-	int i;
-	int high_range = 0;
-	int fifo;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me6000_device = kmalloc(sizeof(me6000_device_t), GFP_KERNEL);
-
-	if (!me6000_device) {
-		PERROR("Cannot get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(me6000_device, 0, sizeof(me6000_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me6000_device, pci_device);
-
-	if (err) {
-		kfree(me6000_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-
-	/* Download the xilinx firmware */
-	err = me_xilinx_download(me6000_device->base.info.pci.reg_bases[1],
-				 me6000_device->base.info.pci.reg_bases[2],
-				 &pci_device->dev, "me6000.bin");
-
-	if (err) {
-		me_device_deinit((me_device_t *) me6000_device);
-		kfree(me6000_device);
-		PERROR("Can't download firmware.\n");
-		return NULL;
-	}
-
-	/* Get the index in the device version information table. */
-	version_idx =
-	    me6000_versions_get_device_index(me6000_device->base.info.pci.
-					     device_id);
-
-	// Initialize spin lock .
-	spin_lock_init(&me6000_device->preload_reg_lock);
-	spin_lock_init(&me6000_device->dio_ctrl_reg_lock);
-
-	/* Create digital input/output instances. */
-	for (i = 0; i < me6000_versions[version_idx].dio_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me6000_dio_constructor(me6000_device->
-							      base.info.pci.
-							      reg_bases[3], i,
-							      &me6000_device->
-							      dio_ctrl_reg_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me6000_device);
-			kfree(me6000_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me6000_device->base.slist,
-					    subdevice);
-	}
-
-	/* Create analog output instances. */
-	for (i = 0; i < me6000_versions[version_idx].ao_subdevices; i++) {
-		high_range = ((i == 8)
-			      &&
-			      ((me6000_device->base.info.pci.device_id ==
-				PCI_DEVICE_ID_MEILHAUS_ME6359)
-			       || (me6000_device->base.info.pci.device_id ==
-				   PCI_DEVICE_ID_MEILHAUS_ME6259)
-			      )
-		    )? 1 : 0;
-
-		fifo =
-		    (i <
-		     me6000_versions[version_idx].
-		     ao_fifo) ? ME6000_AO_HAS_FIFO : 0x0;
-		fifo |= (i < 4) ? ME6000_AO_EXTRA_HARDWARE : 0x0;
-
-		subdevice =
-		    (me_subdevice_t *) me6000_ao_constructor(me6000_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     &me6000_device->
-							     preload_reg_lock,
-							     &me6000_device->
-							     preload_flags,
-							     &me6000_device->
-							     triggering_flags,
-							     i, fifo,
-							     me6000_device->
-							     base.irq,
-							     high_range,
-							     me6000_workqueue);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me6000_device);
-			kfree(me6000_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me6000_device->base.slist,
-					    subdevice);
-	}
-
-	return (me_device_t *) me6000_device;
-}
-EXPORT_SYMBOL(me6000_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me6000_init(void)
-{
-	PDEBUG("executed.\n");
-
-	me6000_workqueue = create_singlethread_workqueue("me6000");
-	return 0;
-}
-
-static void __exit me6000_exit(void)
-{
-	PDEBUG("executed.\n");
-
-	flush_workqueue(me6000_workqueue);
-	destroy_workqueue(me6000_workqueue);
-}
-
-module_init(me6000_init);
-module_exit(me6000_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for ME-6000 Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-6000 Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me6000_device.h b/drivers/staging/meilhaus/me6000_device.h
deleted file mode 100644
index 18cc7d1..0000000
--- a/drivers/staging/meilhaus/me6000_device.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * @file me6000_device.h
- *
- * @brief ME-6000 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME6000_DEVICE_H
-#define _ME6000_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-6000 device capabilities.
- */
-typedef struct me6000_version {
-	uint16_t device_id;
-	unsigned int dio_subdevices;
-	unsigned int ao_subdevices;
-	unsigned int ao_fifo;	//How many devices have FIFO
-} me6000_version_t;
-
-/**
- * @brief ME-6000 device capabilities.
- */
-static me6000_version_t me6000_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME6004, 0, 4, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME6008, 0, 8, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME600F, 0, 16, 0},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6014, 0, 4, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME6018, 0, 8, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME601F, 0, 16, 0},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6034, 0, 4, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME6038, 0, 8, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME603F, 0, 16, 0},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6104, 0, 4, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME6108, 0, 8, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME610F, 0, 16, 4},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6114, 0, 4, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME6118, 0, 8, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME611F, 0, 16, 4},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6134, 0, 4, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME6138, 0, 8, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME613F, 0, 16, 4},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6044, 2, 4, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME6048, 2, 8, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME604F, 2, 16, 0},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6054, 2, 4, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME6058, 2, 8, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME605F, 2, 16, 0},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6074, 2, 4, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME6078, 2, 8, 0},
-	{PCI_DEVICE_ID_MEILHAUS_ME607F, 2, 16, 0},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6144, 2, 4, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME6148, 2, 8, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME614F, 2, 16, 4},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6154, 2, 4, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME6158, 2, 8, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME615F, 2, 16, 4},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6174, 2, 4, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME6178, 2, 8, 4},
-	{PCI_DEVICE_ID_MEILHAUS_ME617F, 2, 16, 4},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6259, 2, 9, 0},
-
-	{PCI_DEVICE_ID_MEILHAUS_ME6359, 2, 9, 4},
-
-	{0},
-};
-
-#define ME6000_DEVICE_VERSIONS (sizeof(me6000_versions) / sizeof(me6000_version_t) - 1)	/**< Returns the number of entries in #me6000_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me6000_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me6000_versions.
- */
-static inline unsigned int me6000_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME6000_DEVICE_VERSIONS; i++)
-		if (me6000_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The ME-6000 device class structure.
- */
-typedef struct me6000_device {
-	me_device_t base;			/**< The Meilhaus device base class. */
-
-	/* Child class attributes. */
-	spinlock_t preload_reg_lock;		/**< Guards the preload register. */
-	uint32_t preload_flags;
-	uint32_t triggering_flags;
-
-	spinlock_t dio_ctrl_reg_lock;
-} me6000_device_t;
-
-/**
- * @brief The ME-6000 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-6000 device instance. \n
- *         NULL on error.
- */
-me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_dio.c b/drivers/staging/meilhaus/me6000_dio.c
deleted file mode 100644
index c90686e..0000000
--- a/drivers/staging/meilhaus/me6000_dio.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/**
- * @file me6000_dio.c
- *
- * @brief ME-6000 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me6000_dio_reg.h"
-#include "me6000_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me6000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
-					 struct file *filep, int flags)
-{
-	me6000_dio_subdevice_t *instance;
-	uint8_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me6000_dio_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inb(instance->ctrl_reg);
-	mode &= ~(0x3 << (instance->dio_idx * 2));
-	outb(mode, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, mode);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outb(0x00, instance->port_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, 0x00);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_dio_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)
-{
-	me6000_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-	int size =
-	    flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
-		     | ME_IO_SINGLE_CONFIG_DIO_WORD |
-		     ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
-	PDEBUG("executed.\n");
-
-	instance = (me6000_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inb(instance->ctrl_reg);
-	switch (size) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-				mode &=
-				    ~((ME6000_DIO_CTRL_BIT_MODE_0 |
-				       ME6000_DIO_CTRL_BIT_MODE_1) <<
-				      (instance->dio_idx * 2));
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-				mode &=
-				    ~((ME6000_DIO_CTRL_BIT_MODE_0 |
-				       ME6000_DIO_CTRL_BIT_MODE_1) <<
-				      (instance->dio_idx * 2));
-				mode |=
-				    ME6000_DIO_CTRL_BIT_MODE_0 << (instance->
-								   dio_idx * 2);
-			} else {
-				PERROR
-				    ("Invalid port configuration specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!err) {
-		outb(mode, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, mode);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_dio_io_single_read(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int *value, int time_out, int flags)
-{
-	me6000_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me6000_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
-					      ME6000_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-			if ((mode ==
-			     (ME6000_DIO_CTRL_BIT_MODE_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value =
-				    inb(instance->port_reg) & (0x1 << channel);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
-					      ME6000_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-			if ((mode ==
-			     (ME6000_DIO_CTRL_BIT_MODE_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value = inb(instance->port_reg) & 0x00FF;
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_dio_io_single_write(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int value, int time_out, int flags)
-{
-	me6000_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-	uint8_t byte;
-
-	PDEBUG("executed.\n");
-
-	instance = (me6000_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
-					      ME6000_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME6000_DIO_CTRL_BIT_MODE_0 <<
-			     (instance->dio_idx * 2))) {
-				byte = inb(instance->port_reg) & 0x00FF;
-
-				if (value)
-					byte |= 0x1 << channel;
-				else
-					byte &= ~(0x1 << channel);
-
-				outb(byte, instance->port_reg);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME6000_DIO_CTRL_BIT_MODE_0 |
-					      ME6000_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME6000_DIO_CTRL_BIT_MODE_0 <<
-			     (instance->dio_idx * 2))) {
-				outb(value, instance->port_reg);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me6000_dio_query_number_channels(me_subdevice_t *subdevice,
-					    int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_dio_query_subdevice_type(me_subdevice_t *subdevice,
-					   int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DIO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me6000_dio_query_subdevice_caps(me_subdevice_t *subdevice,
-					   int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_DIO_DIR_BYTE;
-	return ME_ERRNO_SUCCESS;
-}
-
-me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t *ctrl_reg_lock)
-{
-	me6000_dio_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me6000_dio_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me6000_dio_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-
-	/* Set the subdevice ports */
-	subdevice->ctrl_reg = reg_base + ME6000_DIO_CTRL_REG;
-	switch (dio_idx) {
-	case 0:
-		subdevice->port_reg = reg_base + ME6000_DIO_PORT_0_REG;
-		break;
-	case 1:
-		subdevice->port_reg = reg_base + ME6000_DIO_PORT_1_REG;
-		break;
-	default:
-		err = ME_ERRNO_INVALID_SUBDEVICE;
-	}
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save digital i/o index */
-	subdevice->dio_idx = dio_idx;
-
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me6000_dio_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me6000_dio_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me6000_dio_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me6000_dio_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me6000_dio_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me6000_dio_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me6000_dio_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me6000_dio.h b/drivers/staging/meilhaus/me6000_dio.h
deleted file mode 100644
index 858bec1..0000000
--- a/drivers/staging/meilhaus/me6000_dio.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me6000_dio.h
- *
- * @brief ME-6000 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME6000_DIO_H_
-#define _ME6000_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me6000_dio_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-	unsigned int dio_idx;			/**< The index of the digital i/o on the device. */
-
-	unsigned long port_reg;			/**< Register holding the port status. */
-	unsigned long ctrl_reg;			/**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me6000_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-6000 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_dio_reg.h b/drivers/staging/meilhaus/me6000_dio_reg.h
deleted file mode 100644
index e67a791..0000000
--- a/drivers/staging/meilhaus/me6000_dio_reg.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file me6000_dio_reg.h
- *
- * @brief ME-6000 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME6000_DIO_REG_H_
-#define _ME6000_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME6000_DIO_CTRL_REG				0x00	// R/W
-#define ME6000_DIO_PORT_0_REG			0x01	// R/W
-#define ME6000_DIO_PORT_1_REG			0x02	// R/W
-#define ME6000_DIO_PORT_REG				ME6000_DIO_PORT_0_REG	// R/W
-
-#define ME6000_DIO_CTRL_BIT_MODE_0		0x01
-#define ME6000_DIO_CTRL_BIT_MODE_1		0x02
-#define ME6000_DIO_CTRL_BIT_MODE_2		0x04
-#define ME6000_DIO_CTRL_BIT_MODE_3		0x08
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me6000_reg.h b/drivers/staging/meilhaus/me6000_reg.h
deleted file mode 100644
index d352730..0000000
--- a/drivers/staging/meilhaus/me6000_reg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file me6000_reg.h
- *
- * @brief ME-6000 device register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME6000_REG_H_
-#define _ME6000_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME6000_INIT_XILINX_REG		0xAC	// R/-
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_device.c b/drivers/staging/meilhaus/me8100_device.c
deleted file mode 100644
index 41a9345..0000000
--- a/drivers/staging/meilhaus/me8100_device.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * @file me8100_device.c
- *
- * @brief ME-8100 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "me8100_device.h"
-#include "mesubdevice.h"
-#include "me8100_di.h"
-#include "me8100_do.h"
-#include "me8254.h"
-
-me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
-{
-	me8100_device_t *me8100_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	int err;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me8100_device = kmalloc(sizeof(me8100_device_t), GFP_KERNEL);
-
-	if (!me8100_device) {
-		PERROR("Cannot get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(me8100_device, 0, sizeof(me8100_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me8100_device, pci_device);
-
-	if (err) {
-		kfree(me8100_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-
-	/* Get the index in the device version information table. */
-	version_idx =
-	    me8100_versions_get_device_index(me8100_device->base.info.pci.
-					     device_id);
-
-	// Initialize spin lock .
-	spin_lock_init(&me8100_device->dio_ctrl_reg_lock);
-	spin_lock_init(&me8100_device->ctr_ctrl_reg_lock);
-	spin_lock_init(&me8100_device->clk_src_reg_lock);
-
-	// Create subdevice instances.
-
-	for (i = 0; i < me8100_versions[version_idx].di_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me8100_di_constructor(me8100_device->
-							     base.info.pci.
-							     reg_bases[2],
-							     me8100_device->
-							     base.info.pci.
-							     reg_bases[1], i,
-							     me8100_device->
-							     base.irq,
-							     &me8100_device->
-							     dio_ctrl_reg_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me8100_device);
-			kfree(me8100_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me8100_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me8100_versions[version_idx].do_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me8100_do_constructor(me8100_device->
-							     base.info.pci.
-							     reg_bases[2], i,
-							     &me8100_device->
-							     dio_ctrl_reg_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me8100_device);
-			kfree(me8100_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me8100_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me8100_versions[version_idx].ctr_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me8254_constructor(me8100_device->base.
-							  info.pci.device_id,
-							  me8100_device->base.
-							  info.pci.reg_bases[2],
-							  0, i,
-							  &me8100_device->
-							  ctr_ctrl_reg_lock,
-							  &me8100_device->
-							  clk_src_reg_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me8100_device);
-			kfree(me8100_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me8100_device->base.slist,
-					    subdevice);
-	}
-
-	return (me_device_t *) me8100_device;
-}
-EXPORT_SYMBOL(me8100_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me8100_init(void)
-{
-	PDEBUG("executed.\n.");
-	return ME_ERRNO_SUCCESS;
-}
-
-static void __exit me8100_exit(void)
-{
-	PDEBUG("executed.\n.");
-}
-
-module_init(me8100_init);
-
-module_exit(me8100_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Template Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me8100_device.h b/drivers/staging/meilhaus/me8100_device.h
deleted file mode 100644
index 44c42ef..0000000
--- a/drivers/staging/meilhaus/me8100_device.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file me8100_device.h
- *
- * @brief ME-8100 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8100_DEVICE_H
-#define _ME8100_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-8100 device capabilities.
- */
-typedef struct me8100_version {
-	uint16_t device_id;
-	unsigned int di_subdevices;
-	unsigned int do_subdevices;
-	unsigned int ctr_subdevices;
-} me8100_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me8100_version_t me8100_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME8100_A, 1, 1, 3},
-	{PCI_DEVICE_ID_MEILHAUS_ME8100_B, 2, 2, 3},
-	{0},
-};
-
-#define ME8100_DEVICE_VERSIONS (sizeof(me8100_versions) / sizeof(me8100_version_t) - 1)	/**< Returns the number of entries in #me8100_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me8100_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me8100_versions.
- */
-static inline unsigned int me8100_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME8100_DEVICE_VERSIONS; i++)
-		if (me8100_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The ME-8100 device class structure.
- */
-typedef struct me8100_device {
-	me_device_t base;			/**< The Meilhaus device base class. */
-
-	/* Child class attributes. */
-	spinlock_t dio_ctrl_reg_lock;
-	spinlock_t ctr_ctrl_reg_lock;
-	spinlock_t clk_src_reg_lock;
-} me8100_device_t;
-
-/**
- * @brief The ME-8100 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-8100 device instance. \n
- *         NULL on error.
- */
-me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_di.c b/drivers/staging/meilhaus/me8100_di.c
deleted file mode 100644
index 1a3f269..0000000
--- a/drivers/staging/meilhaus/me8100_di.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/**
- * @file me8100_di.c
- *
- * @brief ME-8100 digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "meplx_reg.h"
-#include "me8100_reg.h"
-#include "me8100_di_reg.h"
-#include "me8100_di.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8100_di_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	me8100_di_subdevice_t *instance;
-	unsigned short ctrl;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_di_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->ctrl_reg_lock);
-	ctrl = inw(instance->ctrl_reg);
-	ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0);
-	outw(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outw(0, instance->mask_reg);
-	PDEBUG_REG("mask_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->mask_reg - instance->reg_base, 0);
-	outw(0, instance->pattern_reg);
-	PDEBUG_REG("pattern_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->pattern_reg - instance->reg_base, 0);
-	instance->rised = -1;
-	instance->irq_count = 0;
-	instance->filtering_flag = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	outl(PLX_INTCSR_LOCAL_INT1_EN |
-	     PLX_INTCSR_LOCAL_INT1_POL |
-	     PLX_INTCSR_LOCAL_INT2_EN |
-	     PLX_INTCSR_LOCAL_INT2_POL |
-	     PLX_INTCSR_PCI_INT_EN, instance->irq_status_reg);
-	PDEBUG_REG("plx:irq_status_reg outl(0x%lX)=0x%x\n",
-		   instance->irq_status_reg,
-		   PLX_INTCSR_LOCAL_INT1_EN | PLX_INTCSR_LOCAL_INT1_POL |
-		   PLX_INTCSR_LOCAL_INT2_EN | PLX_INTCSR_LOCAL_INT2_POL |
-		   PLX_INTCSR_PCI_INT_EN);
-
-	wake_up_interruptible_all(&instance->wait_queue);
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_di_io_irq_start(me_subdevice_t *subdevice,
-				  struct file *filep,
-				  int channel,
-				  int irq_source,
-				  int irq_edge, int irq_arg, int flags)
-{
-	me8100_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint16_t ctrl;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_di_subdevice_t *) subdevice;
-
-	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
-		if (flags &
-		    ~(ME_IO_IRQ_START_PATTERN_FILTERING |
-		      ME_IO_IRQ_START_DIO_WORD)) {
-			PERROR("Invalid flag specified.\n");
-			return ME_ERRNO_INVALID_FLAGS;
-		}
-
-		if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
-			PERROR("Invalid irq edge specified.\n");
-			return ME_ERRNO_INVALID_IRQ_EDGE;
-		}
-	} else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
-		if (flags &
-		    ~(ME_IO_IRQ_START_EXTENDED_STATUS |
-		      ME_IO_IRQ_START_DIO_WORD)) {
-			PERROR("Invalid flag specified.\n");
-			return ME_ERRNO_INVALID_FLAGS;
-		}
-
-		if (irq_edge != ME_IRQ_EDGE_ANY) {
-			PERROR("Invalid irq edge specified.\n");
-			return ME_ERRNO_INVALID_IRQ_EDGE;
-		}
-
-		if (!(irq_arg & 0xFFFF)) {
-			PERROR("No mask specified.\n");
-			return ME_ERRNO_INVALID_IRQ_ARG;
-		}
-	} else {
-		PERROR("Invalid irq source specified.\n");
-		return ME_ERRNO_INVALID_IRQ_SOURCE;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
-		outw(irq_arg, instance->pattern_reg);
-		instance->compare_value = irq_arg;
-		instance->filtering_flag =
-		    (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0;
-	}
-	if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
-		outw(irq_arg, instance->mask_reg);
-	}
-
-	spin_lock(instance->ctrl_reg_lock);
-	ctrl = inw(instance->ctrl_reg);
-	ctrl |= ME8100_DIO_CTRL_BIT_INTB_0;
-	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
-		ctrl &= ~ME8100_DIO_CTRL_BIT_INTB_1;
-	}
-
-	if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
-		ctrl |= ME8100_DIO_CTRL_BIT_INTB_1;
-	}
-	outw(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	instance->rised = 0;
-	instance->status_value = 0;
-	instance->status_value_edges = 0;
-	instance->line_value = inw(instance->port_reg);
-	instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8100_di_io_irq_wait(me_subdevice_t *subdevice,
-				 struct file *filep,
-				 int channel,
-				 int *irq_count,
-				 int *value, int time_out, int flags)
-{
-	me8100_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	unsigned long cpu_flags;
-	int count;
-
-	PDEBUG("executed.\n");
-	PDEVELOP("PID: %d.\n", current->pid);
-
-	instance = (me8100_di_subdevice_t *) subdevice;
-
-	if (flags &
-	    ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->rised <= 0) {
-		instance->rised = 0;
-		count = instance->irq_count;
-
-		if (time_out) {
-			t = wait_event_interruptible_timeout(instance->
-							     wait_queue,
-							     ((count !=
-							       instance->
-							       irq_count)
-							      || (instance->
-								  rised < 0)),
-							     t);
-//                      t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
-			if (t == 0) {
-				PERROR("Wait on interrupt timed out.\n");
-				err = ME_ERRNO_TIMEOUT;
-			}
-		} else {
-			wait_event_interruptible(instance->wait_queue,
-						 ((count != instance->irq_count)
-						  || (instance->rised < 0)));
-//                      wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
-		}
-
-		if (instance->rised < 0) {
-			PERROR("Wait on interrupt aborted by user.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-	}
-
-	if (signal_pending(current)) {
-		PERROR("Wait on interrupt aborted by signal.\n");
-		err = ME_ERRNO_SIGNAL;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	*irq_count = instance->irq_count;
-	if (!err) {
-		if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) {
-			*value = instance->status_value;
-		} else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) {
-			*value = instance->status_value_edges;
-		} else {	// Use default
-			if (!instance->status_flag) {
-				*value = instance->status_value;
-			} else {
-				*value = instance->status_value_edges;
-			}
-		}
-		instance->rised = 0;
-/*
-			instance->status_value = 0;
-			instance->status_value_edges = 0;
-*/
-	} else {
-		*value = 0;
-	}
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8100_di_io_irq_stop(me_subdevice_t *subdevice,
-				 struct file *filep, int channel, int flags)
-{
-	me8100_di_subdevice_t *instance;
-	uint16_t ctrl;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_di_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->ctrl_reg_lock);
-	ctrl = inw(instance->ctrl_reg);
-	ctrl &= ~(ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0);
-	outw(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock(instance->ctrl_reg_lock);
-	instance->rised = -1;
-	instance->status_value = 0;
-	instance->status_value_edges = 0;
-	instance->filtering_flag = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_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)
-{
-	me8100_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_WORD:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-			} else {
-				PERROR
-				    ("Invalid port configuration specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8100_di_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me8100_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-
-	switch (flags) {
-
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 16)) {
-			*value = inw(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inw(instance->port_reg) & 0xFF;
-		} else if (channel == 1) {
-			*value = (inw(instance->port_reg) >> 8) & 0xFF;
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_WORD:
-		if (channel == 0) {
-			*value = inw(instance->port_reg);
-		} else {
-			PERROR("Invalid word number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8100_di_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 16;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_di_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DI;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-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;
-	return ME_ERRNO_SUCCESS;
-}
-
-static void me8100_di_destructor(struct me_subdevice *subdevice)
-{
-	me8100_di_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_di_subdevice_t *) subdevice;
-
-	free_irq(instance->irq, (void *)instance);
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-static irqreturn_t me8100_isr(int irq, void *dev_id)
-{
-	me8100_di_subdevice_t *instance;
-	uint32_t icsr;
-
-	uint16_t irq_status;
-	uint16_t line_value = 0;
-
-	uint32_t status_val = 0;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_di_subdevice_t *) dev_id;
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	icsr = inl(instance->irq_status_reg);
-	if (instance->di_idx == 0) {
-
-		if ((icsr &
-		     (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN |
-		      PLX_INTCSR_LOCAL_INT1_EN)) !=
-		    (PLX_INTCSR_LOCAL_INT1_STATE | PLX_INTCSR_PCI_INT_EN |
-		     PLX_INTCSR_LOCAL_INT1_EN)) {
-			PINFO
-			    ("%ld Shared interrupt. %s(): idx=0 plx:irq_status_reg=0x%04X\n",
-			     jiffies, __func__, icsr);
-			return IRQ_NONE;
-		}
-	} else if (instance->di_idx == 1) {
-		if ((icsr &
-		     (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN |
-		      PLX_INTCSR_LOCAL_INT2_EN)) !=
-		    (PLX_INTCSR_LOCAL_INT2_STATE | PLX_INTCSR_PCI_INT_EN |
-		     PLX_INTCSR_LOCAL_INT2_EN)) {
-			PINFO
-			    ("%ld Shared interrupt. %s(): idx=1 plx:irq_status_reg=0x%04X\n",
-			     jiffies, __func__, icsr);
-			return IRQ_NONE;
-		}
-	} else {
-		PERROR("%s():Wrong interrupt idx=%d csr=0x%X.\n", __func__,
-		       instance->di_idx, icsr);
-		return IRQ_NONE;
-	}
-
-	PDEBUG("me8100_isr():Interrupt from idx=%d occured.\n",
-	       instance->di_idx);
-	spin_lock(&instance->subdevice_lock);
-	inw(instance->irq_reset_reg);
-	line_value = inw(instance->port_reg);
-
-	irq_status = instance->line_value ^ line_value;
-
-	// Make extended information.
-	status_val |= (0x00FF & (~(uint16_t) instance->line_value & line_value)) << 16;	//Raise
-	status_val |= (0x00FF & ((uint16_t) instance->line_value & ~line_value));	//Fall
-
-	instance->line_value = line_value;
-
-	if (instance->rised == 0) {
-		instance->status_value = irq_status;
-		instance->status_value_edges = status_val;
-	} else {
-		instance->status_value |= irq_status;
-		instance->status_value_edges |= status_val;
-	}
-
-	if (instance->filtering_flag) {	// For compare mode only.
-		if (instance->compare_value == instance->line_value) {
-			instance->rised = 1;
-			instance->irq_count++;
-		}
-	} else {
-		instance->rised = 1;
-		instance->irq_count++;
-	}
-
-	spin_unlock(&instance->subdevice_lock);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
-					     uint32_t plx_reg_base,
-					     unsigned int di_idx,
-					     int irq,
-					     spinlock_t *ctrl_reg_lock)
-{
-	me8100_di_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me8100_di_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me8100_di_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save the subdevice index. */
-	subdevice->di_idx = di_idx;
-
-	/* Initialize wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	/* Register interrupt service routine. */
-	subdevice->irq = irq;
-	err = request_irq(subdevice->irq, me8100_isr,
-			  IRQF_DISABLED | IRQF_SHARED,
-			  ME8100_NAME, (void *)subdevice);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	PINFO("Registered irq=%d.\n", subdevice->irq);
-
-	/* Initialize the registers */
-	subdevice->ctrl_reg =
-	    me8100_reg_base + ME8100_CTRL_REG_A + di_idx * ME8100_REG_OFFSET;
-	subdevice->port_reg =
-	    me8100_reg_base + ME8100_DI_REG_A + di_idx * ME8100_REG_OFFSET;
-	subdevice->mask_reg =
-	    me8100_reg_base + ME8100_MASK_REG_A + di_idx * ME8100_REG_OFFSET;
-	subdevice->pattern_reg =
-	    me8100_reg_base + ME8100_PATTERN_REG_A + di_idx * ME8100_REG_OFFSET;
-	subdevice->din_int_reg =
-	    me8100_reg_base + ME8100_INT_DI_REG_A + di_idx * ME8100_REG_OFFSET;
-	subdevice->irq_reset_reg =
-	    me8100_reg_base + ME8100_RES_INT_REG_A + di_idx * ME8100_REG_OFFSET;
-	subdevice->irq_status_reg = plx_reg_base + PLX_INTCSR;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = me8100_reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_irq_start = me8100_di_io_irq_start;
-	subdevice->base.me_subdevice_io_irq_wait = me8100_di_io_irq_wait;
-	subdevice->base.me_subdevice_io_irq_stop = me8100_di_io_irq_stop;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me8100_di_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me8100_di_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me8100_di_io_single_read;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me8100_di_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me8100_di_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me8100_di_query_subdevice_caps;
-	subdevice->base.me_subdevice_destructor = me8100_di_destructor;
-
-	subdevice->rised = 0;
-	subdevice->irq_count = 0;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8100_di.h b/drivers/staging/meilhaus/me8100_di.h
deleted file mode 100644
index e1db791..0000000
--- a/drivers/staging/meilhaus/me8100_di.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file me8100_di.h
- *
- * @brief ME-8100 digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8100_DI_H_
-#define _ME8100_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8100_di_subdevice {
-	// Inheritance
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;
-
-	unsigned di_idx;
-
-	int irq;
-	volatile int rised;
-	unsigned int irq_count;
-
-	uint status_flag;				/**< Default interupt status flag */
-	uint status_value;				/**< Interupt status */
-	uint status_value_edges;		/**< Extended interupt status */
-	uint line_value;
-
-	uint16_t compare_value;
-	uint8_t filtering_flag;
-
-	wait_queue_head_t wait_queue;
-
-	unsigned long ctrl_reg;
-	unsigned long port_reg;
-	unsigned long mask_reg;
-	unsigned long pattern_reg;
-	unsigned long long din_int_reg;
-	unsigned long irq_reset_reg;
-	unsigned long irq_status_reg;
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-
-} me8100_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8100 digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
-					     uint32_t plx_reg_base,
-					     unsigned int di_idx,
-					     int irq,
-					     spinlock_t * ctrl_leg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_di_reg.h b/drivers/staging/meilhaus/me8100_di_reg.h
deleted file mode 100644
index 063bd19..0000000
--- a/drivers/staging/meilhaus/me8100_di_reg.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * @file me8100_di_reg.h
- *
- * @brief ME-8100 digital input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8100_DI_REG_H_
-#define _ME8100_DI_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8100_RES_INT_REG_A		0x02	//(r, )
-#define ME8100_DI_REG_A			0x04	//(r, )
-#define ME8100_PATTERN_REG_A		0x08	//( ,w)
-#define ME8100_MASK_REG_A		0x0A	//( ,w)
-#define ME8100_INT_DI_REG_A		0x0A	//(r, )
-
-#define ME8100_RES_INT_REG_B		0x0E	//(r, )
-#define ME8100_DI_REG_B			0x10	//(r, )
-#define ME8100_PATTERN_REG_B		0x14	//( ,w)
-#define ME8100_MASK_REG_B		0x16	//( ,w)
-#define ME8100_INT_DI_REG_B		0x16	//(r, )
-
-#define ME8100_REG_OFFSET		0x0C
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_do.c b/drivers/staging/meilhaus/me8100_do.c
deleted file mode 100644
index 81651a9..0000000
--- a/drivers/staging/meilhaus/me8100_do.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/**
- * @file me8100_do.c
- *
- * @brief ME-8100 digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me8100_reg.h"
-#include "me8100_do_reg.h"
-#include "me8100_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8100_do_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	me8100_do_subdevice_t *instance;
-	uint16_t ctrl;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_do_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	ctrl = inw(instance->ctrl_reg);
-	ctrl &= ME8100_DIO_CTRL_BIT_INTB_1 | ME8100_DIO_CTRL_BIT_INTB_0;
-	outw(ctrl, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock(instance->ctrl_reg_lock);
-	outw(0, instance->port_reg);
-	instance->port_reg_mirror = 0;
-	PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_do_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)
-{
-	me8100_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	int config;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	config = inw(instance->ctrl_reg);
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_WORD:
-		if (channel == 0) {
-			if (single_config ==
-			    ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE) {
-				config &= ~(ME8100_DIO_CTRL_BIT_ENABLE_DIO);
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_SINK) {
-				config |= ME8100_DIO_CTRL_BIT_ENABLE_DIO;
-				config &= ~ME8100_DIO_CTRL_BIT_SOURCE;
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_SOURCE) {
-				config |=
-				    ME8100_DIO_CTRL_BIT_ENABLE_DIO |
-				    ME8100_DIO_CTRL_BIT_SOURCE;
-			} else {
-				PERROR
-				    ("Invalid port configuration specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid word number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!err) {
-		outw(config, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outw(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, config);
-	}
-
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8100_do_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me8100_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 16)) {
-			*value = instance->port_reg_mirror & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = instance->port_reg_mirror & 0xFF;
-		} else if (channel == 1) {
-			*value = (instance->port_reg_mirror >> 8) & 0xFF;
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_WORD:
-		if (channel == 0) {
-			*value = instance->port_reg_mirror;
-		} else {
-			PERROR("Invalid word number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8100_do_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me8100_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8100_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 16)) {
-			instance->port_reg_mirror =
-			    value ? (instance->
-				     port_reg_mirror | (0x1 << channel))
-			    : (instance->port_reg_mirror & ~(0x1 << channel));
-			outw(instance->port_reg_mirror, instance->port_reg);
-			PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->port_reg - instance->reg_base,
-				   instance->port_reg_mirror);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			instance->port_reg_mirror &= ~0xFF;
-			instance->port_reg_mirror |= value & 0xFF;
-			outw(instance->port_reg_mirror, instance->port_reg);
-			PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->port_reg - instance->reg_base,
-				   instance->port_reg_mirror);
-		} else if (channel == 1) {
-			instance->port_reg_mirror &= ~0xFF00;
-			instance->port_reg_mirror |= (value << 8) & 0xFF00;
-			outw(instance->port_reg_mirror, instance->port_reg);
-			PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->port_reg - instance->reg_base,
-				   instance->port_reg_mirror);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_WORD:
-		if (channel == 0) {
-			instance->port_reg_mirror = value;
-			outw(value, instance->port_reg);
-			PDEBUG_REG("port_reg outw(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->port_reg - instance->reg_base,
-				   value);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8100_do_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 16;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_do_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_DIO_SINK_SOURCE;
-	return ME_ERRNO_SUCCESS;
-}
-
-me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
-					     unsigned int do_idx,
-					     spinlock_t *ctrl_reg_lock)
-{
-	me8100_do_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me8100_do_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me8100_do_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-
-	/* Initialize registers */
-	if (do_idx == 0) {
-		subdevice->port_reg = reg_base + ME8100_DO_REG_A;
-		subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_A;
-	} else if (do_idx == 1) {
-		subdevice->port_reg = reg_base + ME8100_DO_REG_B;
-		subdevice->ctrl_reg = reg_base + ME8100_CTRL_REG_B;
-	} else {
-		PERROR("Wrong subdevice idx=%d.\n", do_idx);
-		kfree(subdevice);
-		return NULL;
-	}
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save the subdevice index */
-	subdevice->do_idx = do_idx;
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me8100_do_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me8100_do_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me8100_do_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me8100_do_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me8100_do_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me8100_do_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me8100_do_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8100_do.h b/drivers/staging/meilhaus/me8100_do.h
deleted file mode 100644
index acf8801..0000000
--- a/drivers/staging/meilhaus/me8100_do.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file me8100_do.h
- *
- * @brief ME-8100 digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8100_DO_H_
-#define _ME8100_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8100_do_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect the #ctrl_reg. */
-
-	unsigned int do_idx;
-
-	uint16_t port_reg_mirror;		/**< Mirror used to store current port register setting which is write only. */
-
-	unsigned long port_reg;			/**< Register holding the port status. */
-	unsigned long ctrl_reg;			/**< Control register. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me8100_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8100 digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param do_idx The index of the digital output subdevice on this device.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
-					     unsigned int do_idx,
-					     spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_do_reg.h b/drivers/staging/meilhaus/me8100_do_reg.h
deleted file mode 100644
index 13a2380..0000000
--- a/drivers/staging/meilhaus/me8100_do_reg.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * @file me8100_ao_reg.h
- *
- * @brief ME-8100 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8100_DO_REG_H_
-#define _ME8100_DO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8100_DO_REG_A			0x06	//( ,w)
-#define ME8100_DO_REG_B			0x12	//( ,w)
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8100_reg.h b/drivers/staging/meilhaus/me8100_reg.h
deleted file mode 100644
index d8c4b1c..0000000
--- a/drivers/staging/meilhaus/me8100_reg.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file me8100_reg.h
- *
- * @brief ME-8100 register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8100_REG_H_
-#define _ME8100_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8100_CTRL_REG_A			0x00	//( ,w)
-#define ME8100_CTRL_REG_B			0x0C	//( ,w)
-
-#define ME8100_DIO_CTRL_BIT_SOURCE		0x10
-#define ME8100_DIO_CTRL_BIT_INTB_1		0x20
-#define ME8100_DIO_CTRL_BIT_INTB_0		0x40
-#define ME8100_DIO_CTRL_BIT_ENABLE_DIO		0x80
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_device.c b/drivers/staging/meilhaus/me8200_device.c
deleted file mode 100644
index b313679..0000000
--- a/drivers/staging/meilhaus/me8200_device.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * @file me8200_device.c
- *
- * @brief ME-8200 device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include "meids.h"
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "meplx_reg.h"
-#include "medevice.h"
-#include "me8200_device.h"
-#include "mesubdevice.h"
-#include "me8200_di.h"
-#include "me8200_do.h"
-#include "me8200_dio.h"
-
-me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
-{
-	me8200_device_t *me8200_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	int err;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	me8200_device = kmalloc(sizeof(me8200_device_t), GFP_KERNEL);
-
-	if (!me8200_device) {
-		PERROR("Cannot get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(me8200_device, 0, sizeof(me8200_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) me8200_device, pci_device);
-
-	if (err) {
-		kfree(me8200_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-
-	/* Get the index in the device version information table. */
-	version_idx =
-	    me8200_versions_get_device_index(me8200_device->base.info.pci.
-					     device_id);
-
-	// Initialize spin lock .
-	spin_lock_init(&me8200_device->irq_ctrl_lock);
-	spin_lock_init(&me8200_device->irq_mode_lock);
-	spin_lock_init(&me8200_device->dio_ctrl_lock);
-
-	/* Setup the PLX interrupt configuration */
-	outl(PLX_INTCSR_LOCAL_INT1_EN |
-	     PLX_INTCSR_LOCAL_INT1_POL |
-	     PLX_INTCSR_LOCAL_INT2_EN |
-	     PLX_INTCSR_LOCAL_INT2_POL |
-	     PLX_INTCSR_PCI_INT_EN,
-	     me8200_device->base.info.pci.reg_bases[1] + PLX_INTCSR);
-
-	// Create subdevice instances.
-
-	for (i = 0; i < me8200_versions[version_idx].di_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me8200_di_constructor(me8200_device->
-							     base.info.pci.
-							     reg_bases[2], i,
-							     me8200_device->
-							     base.irq,
-							     &me8200_device->
-							     irq_ctrl_lock,
-							     &me8200_device->
-							     irq_mode_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me8200_device);
-			kfree(me8200_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me8200_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me8200_versions[version_idx].do_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me8200_do_constructor(me8200_device->
-							     base.info.pci.
-							     reg_bases[2], i,
-							     me8200_device->
-							     base.irq,
-							     &me8200_device->
-							     irq_mode_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me8200_device);
-			kfree(me8200_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me8200_device->base.slist,
-					    subdevice);
-	}
-
-	for (i = 0; i < me8200_versions[version_idx].dio_subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) me8200_dio_constructor(me8200_device->
-							      base.info.pci.
-							      reg_bases[2], i,
-							      &me8200_device->
-							      dio_ctrl_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) me8200_device);
-			kfree(me8200_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&me8200_device->base.slist,
-					    subdevice);
-	}
-
-	return (me_device_t *) me8200_device;
-}
-EXPORT_SYMBOL(me8200_pci_constructor);
-
-// Init and exit of module.
-
-static int __init me8200_init(void)
-{
-	PDEBUG("executed.\n.");
-	return 0;
-}
-
-static void __exit me8200_exit(void)
-{
-	PDEBUG("executed.\n.");
-}
-
-module_init(me8200_init);
-
-module_exit(me8200_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Template Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/me8200_device.h b/drivers/staging/meilhaus/me8200_device.h
deleted file mode 100644
index cbd2a01..0000000
--- a/drivers/staging/meilhaus/me8200_device.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * @file me8200_device.h
- *
- * @brief ME-8200 device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_DEVICE_H
-#define _ME8200_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding ME-8200 device capabilities.
- */
-typedef struct me8200_version {
-	uint16_t device_id;
-	unsigned int di_subdevices;
-	unsigned int do_subdevices;
-	unsigned int dio_subdevices;
-} me8200_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static me8200_version_t me8200_versions[] = {
-	{PCI_DEVICE_ID_MEILHAUS_ME8200_A, 1, 1, 2},
-	{PCI_DEVICE_ID_MEILHAUS_ME8200_B, 2, 2, 2},
-	{0},
-};
-
-#define ME8200_DEVICE_VERSIONS (sizeof(me8200_versions) / sizeof(me8200_version_t) - 1)	/**< Returns the number of entries in #me8200_versions. */
-
-/**
- * @brief Returns the index of the device entry in #me8200_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #me8200_versions.
- */
-static inline unsigned int me8200_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < ME8200_DEVICE_VERSIONS; i++)
-		if (me8200_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The ME-8200 device class structure.
- */
-typedef struct me8200_device {
-	me_device_t base;		/**< The Meilhaus device base class. */
-
-	/* Child class attributes. */
-	spinlock_t irq_ctrl_lock;	/**< Lock for the interrupt control register. */
-	spinlock_t irq_mode_lock;	/**< Lock for the interrupt mode register. */
-	spinlock_t dio_ctrl_lock;	/**< Lock for the digital i/o control register. */
-} me8200_device_t;
-
-/**
- * @brief The ME-8200 device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new ME-8200 device instance. \n
- *         NULL on error.
- */
-me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_di.c b/drivers/staging/meilhaus/me8200_di.c
deleted file mode 100644
index fd1af0f..0000000
--- a/drivers/staging/meilhaus/me8200_di.c
+++ /dev/null
@@ -1,832 +0,0 @@
-/**
- * @file me8200_di.c
- *
- * @brief ME-8200 digital input subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-///Includes
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-
-#include "medefines.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "me8200_reg.h"
-#include "me8200_di_reg.h"
-#include "me8200_di.h"
-
-/// Defines
-static void me8200_di_destructor(struct me_subdevice *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,
-				 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,
-				 struct file *filep, int channel, int flags);
-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,
-				    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,
-					   int *number);
-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,
-					  int *caps);
-static irqreturn_t me8200_isr(int irq, void *dev_id);
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id);
-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,
-				  struct file *filep,
-				  int channel,
-				  int irq_source,
-				  int irq_edge, int irq_arg, int flags)
-{
-	me8200_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	volatile uint8_t tmp;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_di_subdevice_t *) subdevice;
-
-	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
-		if (flags &
-		    ~(ME_IO_IRQ_START_PATTERN_FILTERING |
-		      ME_IO_IRQ_START_DIO_BYTE)) {
-			PERROR("Invalid flag specified.\n");
-			return ME_ERRNO_INVALID_FLAGS;
-		}
-
-		if (irq_edge != ME_IRQ_EDGE_NOT_USED) {
-			PERROR("Invalid irq edge specified.\n");
-			return ME_ERRNO_INVALID_IRQ_EDGE;
-		}
-	} else if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
-		if (flags &
-		    ~(ME_IO_IRQ_START_EXTENDED_STATUS |
-		      ME_IO_IRQ_START_DIO_BYTE)) {
-			PERROR("Invalid flag specified.\n");
-			return ME_ERRNO_INVALID_FLAGS;
-		}
-
-		if ((irq_edge != ME_IRQ_EDGE_RISING)
-		    && (irq_edge != ME_IRQ_EDGE_FALLING)
-		    && (irq_edge != ME_IRQ_EDGE_ANY)) {
-			PERROR("Invalid irq edge specified.\n");
-			return ME_ERRNO_INVALID_IRQ_EDGE;
-		}
-
-		if (!(irq_arg & 0xFF)) {
-			PERROR("No mask specified.\n");
-			return ME_ERRNO_INVALID_IRQ_ARG;
-		}
-	} else {
-		PERROR("Invalid irq source specified.\n");
-		return ME_ERRNO_INVALID_IRQ_SOURCE;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, status);
-	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
-		outb(irq_arg, instance->compare_reg);
-		PDEBUG_REG("compare_reg outb(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->compare_reg - instance->reg_base, irq_arg);
-		outb(0xFF, instance->mask_reg);
-		PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->mask_reg - instance->reg_base, 0xff);
-		instance->compare_value = irq_arg;
-		instance->filtering_flag =
-		    (flags & ME_IO_IRQ_START_PATTERN_FILTERING) ? 1 : 0;
-	}
-	if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
-		outb(irq_arg, instance->mask_reg);
-		PDEBUG_REG("mask_reg outb(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->mask_reg - instance->reg_base, irq_arg);
-		instance->filtering_flag = 0;
-	}
-
-	spin_lock(instance->irq_mode_lock);
-	tmp = inb(instance->irq_mode_reg);
-	tmp &=
-	    ~(ME8200_IRQ_MODE_MASK <<
-	      (ME8200_IRQ_MODE_DI_SHIFT * instance->di_idx));
-	if (irq_source == ME_IRQ_SOURCE_DIO_PATTERN) {
-		tmp |=
-		    ME8200_IRQ_MODE_MASK_COMPARE << (ME8200_IRQ_MODE_DI_SHIFT *
-						     instance->di_idx);
-	}
-
-	if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
-		tmp |=
-		    ME8200_IRQ_MODE_MASK_MASK << (ME8200_IRQ_MODE_DI_SHIFT *
-						  instance->di_idx);
-	}
-	outb(tmp, instance->irq_mode_reg);
-	PDEBUG_REG("irq_mode_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_mode_reg - instance->reg_base, tmp);
-	spin_unlock(instance->irq_mode_lock);
-
-	spin_lock(instance->irq_ctrl_lock);
-	tmp = inb(instance->irq_ctrl_reg);
-	tmp |=
-	    (ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
-	     (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-	tmp |=
-	    ME8200_DI_IRQ_CTRL_BIT_ENABLE << (ME8200_DI_IRQ_CTRL_SHIFT *
-					      instance->di_idx);
-
-	if (irq_source == ME_IRQ_SOURCE_DIO_MASK) {
-		tmp &=
-		    ~(ME8200_DI_IRQ_CTRL_MASK_EDGE <<
-		      (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-		if (irq_edge == ME_IRQ_EDGE_RISING) {
-			tmp |=
-			    ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING <<
-			    (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
-		} else if (irq_edge == ME_IRQ_EDGE_FALLING) {
-			tmp |=
-			    ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING <<
-			    (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
-		} else if (irq_edge == ME_IRQ_EDGE_ANY) {
-			tmp |=
-			    ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY <<
-			    (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx);
-		}
-	}
-	outb(tmp, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, tmp);
-	tmp &=
-	    ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
-	      (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-	outb(tmp, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, tmp);
-
-	instance->line_value = inb(instance->port_reg);
-	spin_unlock(instance->irq_ctrl_lock);
-
-	instance->rised = 0;
-	instance->status_value = 0;
-	instance->status_value_edges = 0;
-	instance->status_flag = flags & ME_IO_IRQ_START_EXTENDED_STATUS;
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-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)
-{
-	me8200_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	unsigned long cpu_flags;
-	int count;
-
-	PDEBUG("executed.\n");
-	PDEVELOP("PID: %d.\n", current->pid);
-
-	instance = (me8200_di_subdevice_t *) subdevice;
-
-	if (flags &
-	    ~(ME_IO_IRQ_WAIT_NORMAL_STATUS | ME_IO_IRQ_WAIT_EXTENDED_STATUS)) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->rised <= 0) {
-		instance->rised = 0;
-		count = instance->count;
-
-		if (time_out) {
-			t = wait_event_interruptible_timeout(instance->
-							     wait_queue,
-							     ((count !=
-							       instance->count)
-							      || (instance->
-								  rised < 0)),
-							     t);
-//                      t = wait_event_interruptible_timeout(instance->wait_queue, (instance->rised != 0), t);
-			if (t == 0) {
-				PERROR("Wait on interrupt timed out.\n");
-				err = ME_ERRNO_TIMEOUT;
-			}
-		} else {
-			wait_event_interruptible(instance->wait_queue,
-						 ((count != instance->count)
-						  || (instance->rised < 0)));
-//                      wait_event_interruptible(instance->wait_queue, (instance->rised != 0));
-		}
-
-		if (instance->rised < 0) {
-			PERROR("Wait on interrupt aborted by user.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-	}
-
-	if (signal_pending(current)) {
-		PERROR("Wait on interrupt aborted by signal.\n");
-		err = ME_ERRNO_SIGNAL;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	*irq_count = instance->count;
-	if (!err) {
-		if (flags & ME_IO_IRQ_WAIT_NORMAL_STATUS) {
-			*value = instance->status_value;
-		} else if (flags & ME_IO_IRQ_WAIT_EXTENDED_STATUS) {
-			*value = instance->status_value_edges;
-		} else {	// Use default
-			if (!instance->status_flag) {
-				*value = instance->status_value;
-			} else {
-				*value = instance->status_value_edges;
-			}
-		}
-		instance->rised = 0;
-/*
-			instance->status_value = 0;
-			instance->status_value_edges = 0;
-*/
-	} else {
-		*value = 0;
-	}
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
-				 struct file *filep, int channel, int flags)
-{
-	me8200_di_subdevice_t *instance;
-	uint8_t tmp;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_di_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER spin_lock_irqsave(&instance->subdevice_lock, status);
-	spin_lock(instance->irq_ctrl_lock);
-	tmp = inb(instance->irq_ctrl_reg);
-	tmp |=
-	    (ME8200_DI_IRQ_CTRL_BIT_ENABLE <<
-	     (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-	outb(tmp, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, tmp);
-	tmp &=
-	    ~(ME8200_DI_IRQ_CTRL_BIT_ENABLE <<
-	      (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-	tmp |=
-	    (ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
-	     (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-//                      tmp &= ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-	outb(tmp, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->irq_ctrl_lock);
-
-	instance->rised = -1;
-	instance->status_value = 0;
-	instance->status_value_edges = 0;
-	instance->filtering_flag = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-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)
-{
-	me8200_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, status);
-
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-			} else {
-				PERROR("Invalid port direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_di_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me8200_di_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_di_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, status);
-
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = inb(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inb(instance->port_reg);
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	me8200_di_subdevice_t *instance = (me8200_di_subdevice_t *) subdevice;
-
-	PDEBUG("executed.\n");
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	instance->count = 0;
-	return me8200_di_io_irq_stop(subdevice, filep, 0, 0);
-}
-
-static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DI;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_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_RISING |
-	    ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING |
-	    ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
-	return ME_ERRNO_SUCCESS;
-}
-
-static irqreturn_t me8200_isr(int irq, void *dev_id)
-{
-	me8200_di_subdevice_t *instance;
-	uint8_t ctrl;
-	uint8_t irq_status;
-	uint8_t line_value = 0;
-	uint8_t line_status = 0;
-	uint32_t status_val = 0;
-
-	instance = (me8200_di_subdevice_t *) dev_id;
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	irq_status = inb(instance->irq_status_reg);
-	if (!irq_status) {
-		PINFO
-		    ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
-		     jiffies, __func__, instance->di_idx, irq_status);
-		return IRQ_NONE;
-	}
-
-	PDEBUG("executed.\n");
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->irq_ctrl_lock);
-	ctrl = inb(instance->irq_ctrl_reg);
-	ctrl |=
-	    ME8200_DI_IRQ_CTRL_BIT_CLEAR << (ME8200_DI_IRQ_CTRL_SHIFT *
-					     instance->di_idx);
-	outb(ctrl, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, ctrl);
-	ctrl &=
-	    ~(ME8200_DI_IRQ_CTRL_BIT_CLEAR <<
-	      (ME8200_DI_IRQ_CTRL_SHIFT * instance->di_idx));
-	outb(ctrl, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, ctrl);
-
-	line_value = inb(instance->port_reg);
-	spin_unlock(instance->irq_ctrl_lock);
-
-	line_status = ((uint8_t) instance->line_value ^ line_value);
-
-	// Make extended information.
-	status_val |= (0x00FF & (~(uint8_t) instance->line_value & line_value)) << 16;	//Raise
-	status_val |= (0x00FF & ((uint8_t) instance->line_value & ~line_value));	//Fall
-
-	instance->line_value = (int)line_value;
-
-	if (instance->rised == 0) {
-		instance->status_value = irq_status | line_status;
-		instance->status_value_edges = status_val;
-	} else {
-		instance->status_value |= irq_status | line_status;
-		instance->status_value_edges |= status_val;
-	}
-
-	if (instance->filtering_flag) {	// For compare mode only.
-		if (instance->compare_value == instance->line_value) {
-			instance->rised = 1;
-			instance->count++;
-		}
-	} else {
-		instance->rised = 1;
-		instance->count++;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	spin_unlock(&instance->subdevice_lock);
-
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id)
-{
-	me8200_di_subdevice_t *instance;
-	uint8_t irq_status = 0;
-	uint16_t irq_status_EX = 0;
-	uint32_t status_val = 0;
-	int i, j;
-
-	instance = (me8200_di_subdevice_t *) dev_id;
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	PDEBUG("executed.\n");
-
-	//Reset latches. Copy status to extended registers.
-	irq_status = inb(instance->irq_status_reg);
-	PDEBUG_REG("idx=%d irq_status_reg=0x%02X\n", instance->di_idx,
-		   irq_status);
-
-	if (!irq_status) {
-		PINFO
-		    ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
-		     jiffies, __func__, instance->di_idx, irq_status);
-		return IRQ_NONE;
-	}
-
-	irq_status_EX = inb(instance->irq_status_low_reg);
-	irq_status_EX |= (inb(instance->irq_status_high_reg) << 8);
-
-	PDEVELOP("EXTENDED REG: 0x%04x\n", irq_status_EX);
-	instance->line_value = inb(instance->port_reg);
-
-	// Format extended information.
-	for (i = 0, j = 0; i < 8; i++, j += 2) {
-		status_val |= ((0x01 << j) & irq_status_EX) >> (j - i);	//Fall
-		status_val |= ((0x01 << (j + 1)) & irq_status_EX) << (15 - j + i);	//Raise
-	}
-
-	spin_lock(&instance->subdevice_lock);
-	if (instance->rised == 0) {
-		instance->status_value = irq_status;
-		instance->status_value_edges = status_val;
-	} else {
-		instance->status_value |= irq_status;
-		instance->status_value_edges |= status_val;
-	}
-
-	if (instance->filtering_flag) {	// For compare mode only.
-		if (instance->compare_value == instance->line_value) {
-			instance->rised = 1;
-			instance->count++;
-		}
-	} else {
-		instance->rised = 1;
-		instance->count++;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-static void me8200_di_destructor(struct me_subdevice *subdevice)
-{
-	me8200_di_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_di_subdevice_t *) subdevice;
-
-	free_irq(instance->irq, (void *)instance);
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-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)
-{
-	me8200_di_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me8200_di_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me8200_di_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Check firmware version.
-	me8200_di_check_version(subdevice,
-				me8200_regbase + ME8200_FIRMWARE_VERSION_REG);
-
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->irq_ctrl_lock = irq_ctrl_lock;
-	subdevice->irq_mode_lock = irq_mode_lock;
-
-	/* Save the subdevice index. */
-	subdevice->di_idx = di_idx;
-
-	/* Initialize registers */
-	if (di_idx == 0) {
-		subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_0_REG;
-		subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_0_REG;
-		subdevice->compare_reg =
-		    me8200_regbase + ME8200_DI_COMPARE_0_REG;
-		subdevice->irq_status_reg =
-		    me8200_regbase + ME8200_DI_CHANGE_0_REG;
-
-		subdevice->irq_status_low_reg =
-		    me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_LOW_REG;
-		subdevice->irq_status_high_reg =
-		    me8200_regbase + ME8200_DI_EXTEND_CHANGE_0_HIGH_REG;
-	} else if (di_idx == 1) {
-		subdevice->port_reg = me8200_regbase + ME8200_DI_PORT_1_REG;
-		subdevice->mask_reg = me8200_regbase + ME8200_DI_MASK_1_REG;
-		subdevice->compare_reg =
-		    me8200_regbase + ME8200_DI_COMPARE_1_REG;
-		subdevice->irq_status_reg =
-		    me8200_regbase + ME8200_DI_CHANGE_1_REG;
-
-		subdevice->irq_status_low_reg =
-		    me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_LOW_REG;
-		subdevice->irq_status_high_reg =
-		    me8200_regbase + ME8200_DI_EXTEND_CHANGE_1_HIGH_REG;
-	} else {
-		PERROR("Wrong subdevice idx=%d.\n", di_idx);
-		kfree(subdevice);
-		return NULL;
-	}
-	subdevice->irq_ctrl_reg = me8200_regbase + ME8200_DI_IRQ_CTRL_REG;
-	subdevice->irq_mode_reg = me8200_regbase + ME8200_IRQ_MODE_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = me8200_regbase;
-#endif
-
-	/* Initialize wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_irq_start = me8200_di_io_irq_start;
-	subdevice->base.me_subdevice_io_irq_wait = me8200_di_io_irq_wait;
-	subdevice->base.me_subdevice_io_irq_stop = me8200_di_io_irq_stop;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me8200_di_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me8200_di_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me8200_di_io_single_read;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me8200_di_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me8200_di_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me8200_di_query_subdevice_caps;
-	subdevice->base.me_subdevice_destructor = me8200_di_destructor;
-
-	subdevice->rised = 0;
-	subdevice->count = 0;
-
-	/* Register interrupt service routine. */
-	subdevice->irq = irq;
-	if (subdevice->version > 0) {	// NEW
-		err = request_irq(subdevice->irq, me8200_isr_EX,
-				  IRQF_DISABLED | IRQF_SHARED,
-				  ME8200_NAME, (void *)subdevice);
-	} else {		//OLD
-		err = request_irq(subdevice->irq, me8200_isr,
-				  IRQF_DISABLED | IRQF_SHARED,
-				  ME8200_NAME, (void *)subdevice);
-	}
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	PDEBUG("Registred irq=%d.\n", subdevice->irq);
-
-	return subdevice;
-}
-
-static void me8200_di_check_version(me8200_di_subdevice_t *instance,
-				    unsigned long addr)
-{
-
-	PDEBUG("executed.\n");
-	instance->version = 0x000000FF & inb(addr);
-	PDEVELOP("me8200 firmware version: %d\n", instance->version);
-
-	/// @note Fix for wrong values in this registry.
-	if ((instance->version < 0x7) || (instance->version > 0x1F))
-		instance->version = 0x0;
-}
diff --git a/drivers/staging/meilhaus/me8200_di.h b/drivers/staging/meilhaus/me8200_di.h
deleted file mode 100644
index 2a3b005..0000000
--- a/drivers/staging/meilhaus/me8200_di.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file me8200_di.h
- *
- * @brief ME-8200 digital input subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_DI_H_
-#define _ME8200_DI_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8200_di_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;
-	spinlock_t *irq_ctrl_lock;
-	spinlock_t *irq_mode_lock;
-
-	unsigned int di_idx;
-	unsigned int version;
-
-	int irq;						/**< The number of the interrupt request. */
-	volatile int rised;				/**< Flag to indicate if an interrupt occured. */
-	uint status_flag;				/**< Default interupt status flag */
-	uint status_value;				/**< Interupt status */
-	uint status_value_edges;			/**< Extended interupt status */
-	uint line_value;
-	int count;						/**< Counts the number of interrupts occured. */
-	uint8_t compare_value;
-	uint8_t filtering_flag;
-
-	wait_queue_head_t wait_queue;	/**< To wait on interrupts. */
-
-	unsigned long port_reg;			/**< The digital input port. */
-	unsigned long compare_reg;		/**< The register to hold the value to compare with. */
-	unsigned long mask_reg;			/**< The register to hold the mask. */
-	unsigned long irq_mode_reg;		/**< The interrupt mode register. */
-	unsigned long irq_ctrl_reg;		/**< The interrupt control register. */
-	unsigned long irq_status_reg;	/**< The interrupt status register. Also interrupt reseting register (firmware version 7 and later).*/
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-	unsigned long firmware_version_reg;	/**< The interrupt reseting register. */
-
-	unsigned long irq_status_low_reg;	/**< The interrupt extended status register (low part). */
-	unsigned long irq_status_high_reg;	/**< The interrupt extended status register (high part). */
-} me8200_di_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8200 digital input subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_reg_base,
-					     unsigned int di_idx,
-					     int irq,
-					     spinlock_t * irq_ctrl_lock,
-					     spinlock_t * irq_mode_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_di_reg.h b/drivers/staging/meilhaus/me8200_di_reg.h
deleted file mode 100644
index b9a619d..0000000
--- a/drivers/staging/meilhaus/me8200_di_reg.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * @file me8200_di_reg.h
- *
- * @brief ME-8200 digital input subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_DI_REG_H_
-#define _ME8200_DI_REG_H_
-
-#ifdef __KERNEL__
-
-// Common registry for whole family.
-#define ME8200_DI_PORT_0_REG					0x3	// R
-#define ME8200_DI_PORT_1_REG					0x4	// R
-
-#define ME8200_DI_MASK_0_REG					0x5	// R/W
-#define ME8200_DI_MASK_1_REG					0x6	// R/W
-
-#define ME8200_DI_COMPARE_0_REG					0xA	// R/W
-#define ME8200_DI_COMPARE_1_REG					0xB	// R/W
-
-#define ME8200_DI_IRQ_CTRL_REG					0xC	// R/W
-
-#ifndef ME8200_IRQ_MODE_REG
-# define ME8200_IRQ_MODE_REG					0xD	// R/W
-#endif
-
-// This registry are for all versions
-#define ME8200_DI_CHANGE_0_REG					0xE	// R
-#define ME8200_DI_CHANGE_1_REG					0xF	// R
-
-#define ME8200_DI_IRQ_CTRL_BIT_CLEAR			0x4
-#define ME8200_DI_IRQ_CTRL_BIT_ENABLE			0x8
-
-// This registry are for firmware versions 7 and later
-#define ME8200_DI_EXTEND_CHANGE_0_LOW_REG		0x10	// R
-#define ME8200_DI_EXTEND_CHANGE_0_HIGH_REG		0x11	// R
-#define ME8200_DI_EXTEND_CHANGE_1_LOW_REG		0x12	// R
-#define ME8200_DI_EXTEND_CHANGE_1_HIGH_REG		0x13	// R
-
-#ifndef ME8200_FIRMWARE_VERSION_REG
-# define ME8200_FIRMWARE_VERSION_REG			0x14	// R
-#endif
-
-// Bit definitions
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE			0x3
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE_RISING		0x0
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE_FALLING	0x1
-#define ME8200_DI_IRQ_CTRL_MASK_EDGE_ANY		0x3
-
-// Others
-#define ME8200_DI_IRQ_CTRL_SHIFT				4
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_dio.c b/drivers/staging/meilhaus/me8200_dio.c
deleted file mode 100644
index c7f43f0..0000000
--- a/drivers/staging/meilhaus/me8200_dio.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/**
- * @file me8200_dio.c
- *
- * @brief ME-8200 digital input/output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me8200_dio_reg.h"
-#include "me8200_dio.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8200_dio_io_reset_subdevice(struct me_subdevice *subdevice,
-					 struct file *filep, int flags)
-{
-	me8200_dio_subdevice_t *instance;
-	uint8_t mode;
-
-	PDEBUG("executed.\n");
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	instance = (me8200_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inb(instance->ctrl_reg);
-	mode &= ~(0x3 << (instance->dio_idx * 2));
-	outb(mode, instance->ctrl_reg);
-	PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->ctrl_reg - instance->reg_base, mode);
-	spin_unlock(instance->ctrl_reg_lock);
-	outb(0x00, instance->port_reg);
-	PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0x00);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_dio_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)
-{
-	me8200_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint32_t mode;
-	uint32_t size =
-	    flags & (ME_IO_SINGLE_CONFIG_DIO_BIT | ME_IO_SINGLE_CONFIG_DIO_BYTE
-		     | ME_IO_SINGLE_CONFIG_DIO_WORD |
-		     ME_IO_SINGLE_CONFIG_DIO_DWORD);
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	mode = inb(instance->ctrl_reg);
-	switch (size) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-				mode &=
-				    ~((ME8200_DIO_CTRL_BIT_MODE_0 |
-				       ME8200_DIO_CTRL_BIT_MODE_1) <<
-				      (instance->dio_idx * 2));
-			} else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-				mode &=
-				    ~((ME8200_DIO_CTRL_BIT_MODE_0 |
-				       ME8200_DIO_CTRL_BIT_MODE_1) <<
-				      (instance->dio_idx * 2));
-				mode |=
-				    ME8200_DIO_CTRL_BIT_MODE_0 << (instance->
-								   dio_idx * 2);
-			} else {
-				PERROR
-				    ("Invalid port configuration specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid channel number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid flags.\n");
-
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (!err) {
-		outb(mode, instance->ctrl_reg);
-		PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
-			   instance->reg_base,
-			   instance->ctrl_reg - instance->reg_base, mode);
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_dio_io_single_read(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int *value, int time_out, int flags)
-{
-	me8200_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
-					      ME8200_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if ((mode ==
-			     (ME8200_DIO_CTRL_BIT_MODE_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value =
-				    inb(instance->
-					port_reg) & (0x0001 << channel);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
-					      ME8200_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if ((mode ==
-			     (ME8200_DIO_CTRL_BIT_MODE_0 <<
-			      (instance->dio_idx * 2))) || !mode) {
-				*value = inb(instance->port_reg) & 0x00FF;
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_dio_io_single_write(me_subdevice_t *subdevice,
-				      struct file *filep,
-				      int channel,
-				      int value, int time_out, int flags)
-{
-	me8200_dio_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t mode;
-	uint8_t byte;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_dio_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
-					      ME8200_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME8200_DIO_CTRL_BIT_MODE_0 <<
-			     (instance->dio_idx * 2))) {
-				byte = inb(instance->port_reg);
-
-				if (value)
-					byte |= 0x1 << channel;
-				else
-					byte &= ~(0x1 << channel);
-
-				outb(byte, instance->port_reg);
-				PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->port_reg -
-					   instance->reg_base, byte);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			mode =
-			    inb(instance->
-				ctrl_reg) & ((ME8200_DIO_CTRL_BIT_MODE_0 |
-					      ME8200_DIO_CTRL_BIT_MODE_1) <<
-					     (instance->dio_idx * 2));
-
-			if (mode ==
-			    (ME8200_DIO_CTRL_BIT_MODE_0 <<
-			     (instance->dio_idx * 2))) {
-				outb(value, instance->port_reg);
-				PDEBUG_REG("port_reg outl(0x%lX+0x%lX)=0x%x\n",
-					   instance->reg_base,
-					   instance->port_reg -
-					   instance->reg_base, value);
-			} else {
-				PERROR("Port not in output or input mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(instance->ctrl_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_dio_query_number_channels(me_subdevice_t *subdevice,
-					    int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_dio_query_subdevice_type(me_subdevice_t *subdevice,
-					   int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DIO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_dio_query_subdevice_caps(me_subdevice_t *subdevice,
-					   int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_DIO_DIR_BYTE;
-	return ME_ERRNO_SUCCESS;
-}
-
-me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t *ctrl_reg_lock)
-{
-	me8200_dio_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me8200_dio_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me8200_dio_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save digital i/o index */
-	subdevice->dio_idx = dio_idx;
-
-	/* Save the subdevice index */
-	subdevice->ctrl_reg = reg_base + ME8200_DIO_CTRL_REG;
-	subdevice->port_reg = reg_base + ME8200_DIO_PORT_REG + dio_idx;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me8200_dio_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me8200_dio_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me8200_dio_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me8200_dio_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me8200_dio_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me8200_dio_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me8200_dio_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8200_dio.h b/drivers/staging/meilhaus/me8200_dio.h
deleted file mode 100644
index 9ddd93d..0000000
--- a/drivers/staging/meilhaus/me8200_dio.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file me8200_dio.h
- *
- * @brief ME-8200 digital input/output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_DIO_H_
-#define _ME8200_DIO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8200_dio_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-	unsigned int dio_idx;			/**< The index of the digital i/o on the device. */
-
-	unsigned long port_reg;			/**< Register holding the port status. */
-	unsigned long ctrl_reg;			/**< Register to configure the port direction. */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me8200_dio_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8200 digital input/ouput subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param dio_idx The index of the digital i/o port on the device.
- * @param ctrl_reg_lock Spin lock protecting the control register.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
-					       unsigned int dio_idx,
-					       spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_dio_reg.h b/drivers/staging/meilhaus/me8200_dio_reg.h
deleted file mode 100644
index ac94a13..0000000
--- a/drivers/staging/meilhaus/me8200_dio_reg.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file me8200_dio_reg.h
- *
- * @brief ME-8200 digital input/output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_DIO_REG_H_
-#define _ME8200_DIO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8200_DIO_CTRL_REG					0x7	// R/W
-#define ME8200_DIO_PORT_0_REG				0x8	// R/W
-#define ME8200_DIO_PORT_1_REG				0x9	// R/W
-#define ME8200_DIO_PORT_REG					ME8200_DIO_PORT_0_REG	// R/W
-
-#define ME8200_DIO_CTRL_BIT_MODE_0			0x01
-#define ME8200_DIO_CTRL_BIT_MODE_1			0x02
-#define ME8200_DIO_CTRL_BIT_MODE_2			0x04
-#define ME8200_DIO_CTRL_BIT_MODE_3			0x08
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_do.c b/drivers/staging/meilhaus/me8200_do.c
deleted file mode 100644
index e42a137..0000000
--- a/drivers/staging/meilhaus/me8200_do.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/**
- * @file me8200_do.c
- *
- * @brief ME-8200 digital output subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "meids.h"
-#include "medebug.h"
-#include "me8200_reg.h"
-#include "me8200_do_reg.h"
-#include "me8200_do.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static int me8200_do_io_irq_start(me_subdevice_t *subdevice,
-				  struct file *filep,
-				  int channel,
-				  int irq_source,
-				  int irq_edge, int irq_arg, int flags)
-{
-	me8200_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t tmp;
-	unsigned long status;
-
-	if (flags & ~ME_IO_IRQ_START_DIO_BYTE) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel != 0) {
-		PERROR("Invalid channel specified.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	if (irq_source != ME_IRQ_SOURCE_DIO_OVER_TEMP) {
-		PERROR("Invalid interrupt source specified.\n");
-		return ME_ERRNO_INVALID_IRQ_SOURCE;
-	}
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, status);
-	spin_lock(instance->irq_mode_lock);
-	tmp = inb(instance->irq_ctrl_reg);
-	tmp |=
-	    ME8200_IRQ_MODE_BIT_ENABLE_POWER << (ME8200_IRQ_MODE_POWER_SHIFT *
-						 instance->do_idx);
-	outb(tmp, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->irq_mode_lock);
-	instance->rised = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_do_io_irq_wait(me_subdevice_t *subdevice,
-				 struct file *filep,
-				 int channel,
-				 int *irq_count,
-				 int *value, int time_out, int flags)
-{
-	me8200_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	long t = 0;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (time_out < 0) {
-		PERROR("Invalid time_out specified.\n");
-		return ME_ERRNO_INVALID_TIMEOUT;
-	}
-
-	if (time_out) {
-		t = (time_out * HZ) / 1000;
-
-		if (t == 0)
-			t = 1;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	if (instance->rised <= 0) {
-		instance->rised = 0;
-
-		if (time_out) {
-			t = wait_event_interruptible_timeout(instance->
-							     wait_queue,
-							     (instance->rised !=
-							      0), t);
-
-			if (t == 0) {
-				PERROR
-				    ("Wait on external interrupt timed out.\n");
-				err = ME_ERRNO_TIMEOUT;
-			}
-		} else {
-			wait_event_interruptible(instance->wait_queue,
-						 (instance->rised != 0));
-		}
-
-		if (instance->rised < 0) {
-			PERROR("Wait on interrupt aborted by user.\n");
-			err = ME_ERRNO_CANCELLED;
-		}
-	}
-
-	if (signal_pending(current)) {
-		PERROR("Wait on external interrupt aborted by signal.\n");
-		err = ME_ERRNO_SIGNAL;
-	}
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	instance->rised = 0;
-	*irq_count = instance->count;
-	*value = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_do_io_irq_stop(me_subdevice_t *subdevice,
-				 struct file *filep, int channel, int flags)
-{
-	me8200_do_subdevice_t *instance;
-	uint8_t tmp;
-	unsigned long cpu_flags;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	spin_lock(instance->irq_mode_lock);
-	tmp = inb(instance->irq_ctrl_reg);
-	tmp &=
-	    ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
-	      (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
-	outb(tmp, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->irq_mode_lock);
-	instance->rised = -1;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_io_reset_subdevice(struct me_subdevice *subdevice,
-					struct file *filep, int flags)
-{
-	me8200_do_subdevice_t *instance;
-	unsigned long cpu_flags;
-	uint8_t tmp;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
-	outb(0x00, instance->port_reg);
-	PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->port_reg - instance->reg_base, 0x00);
-	spin_lock(instance->irq_mode_lock);
-	tmp = inb(instance->irq_ctrl_reg);
-	tmp &=
-	    ~(ME8200_IRQ_MODE_BIT_ENABLE_POWER <<
-	      (ME8200_IRQ_MODE_POWER_SHIFT * instance->do_idx));
-	outb(tmp, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outb(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, tmp);
-	spin_unlock(instance->irq_mode_lock);
-	instance->rised = -1;
-	instance->count = 0;
-	spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_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)
-{
-	me8200_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, status);
-	switch (flags) {
-	case ME_IO_SINGLE_CONFIG_NO_FLAGS:
-	case ME_IO_SINGLE_CONFIG_DIO_BYTE:
-		if (channel == 0) {
-			if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-			} else {
-				PERROR("Invalid byte direction specified.\n");
-				err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_do_io_single_read(me_subdevice_t *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	me8200_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, status);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = inb(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inb(instance->port_reg);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_do_io_single_write(me_subdevice_t *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	me8200_do_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-	uint8_t state;
-	unsigned long status;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock_irqsave(&instance->subdevice_lock, status);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			state = inb(instance->port_reg);
-			state =
-			    value ? (state | (0x1 << channel)) : (state &
-								  ~(0x1 <<
-								    channel));
-			outb(state, instance->port_reg);
-			PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->port_reg - instance->reg_base,
-				   state);
-		} else {
-			PERROR("Invalid bit number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			outb(value, instance->port_reg);
-			PDEBUG_REG("port_reg outb(0x%lX+0x%lX)=0x%x\n",
-				   instance->reg_base,
-				   instance->port_reg - instance->reg_base,
-				   value);
-		} else {
-			PERROR("Invalid byte number specified.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock_irqrestore(&instance->subdevice_lock, status);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8200_do_query_number_channels(me_subdevice_t *subdevice,
-					   int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 8;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_query_subdevice_type(me_subdevice_t *subdevice,
-					  int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8200_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_DIO_OVER_TEMP_IRQ;
-	return ME_ERRNO_SUCCESS;
-}
-
-static void me8200_do_destructor(struct me_subdevice *subdevice)
-{
-	me8200_do_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8200_do_subdevice_t *) subdevice;
-
-	free_irq(instance->irq, (void *)instance);
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-static irqreturn_t me8200_do_isr(int irq, void *dev_id)
-{
-	me8200_do_subdevice_t *instance;
-	uint16_t ctrl;
-	uint8_t irq_status;
-
-	instance = (me8200_do_subdevice_t *) dev_id;
-
-	if (irq != instance->irq) {
-		PERROR("Incorrect interrupt num: %d.\n", irq);
-		return IRQ_NONE;
-	}
-
-	irq_status = inb(instance->irq_status_reg);
-	if (!
-	    (irq_status &
-	     (ME8200_DO_IRQ_STATUS_BIT_ACTIVE << instance->do_idx))) {
-		PINFO
-		    ("%ld Shared interrupt. %s(): idx=%d irq_status_reg=0x%04X\n",
-		     jiffies, __func__, instance->do_idx, irq_status);
-		return IRQ_NONE;
-	}
-
-	PDEBUG("executed.\n");
-
-	spin_lock(&instance->subdevice_lock);
-	instance->rised = 1;
-	instance->count++;
-
-	spin_lock(instance->irq_mode_lock);
-	ctrl = inw(instance->irq_ctrl_reg);
-	ctrl |= ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx;
-	outw(ctrl, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, ctrl);
-	ctrl &= ~(ME8200_IRQ_MODE_BIT_CLEAR_POWER << instance->do_idx);
-	outw(ctrl, instance->irq_ctrl_reg);
-	PDEBUG_REG("irq_ctrl_reg outw(0x%lX+0x%lX)=0x%x\n", instance->reg_base,
-		   instance->irq_ctrl_reg - instance->reg_base, ctrl);
-	spin_unlock(instance->irq_mode_lock);
-	spin_unlock(&instance->subdevice_lock);
-	wake_up_interruptible_all(&instance->wait_queue);
-
-	return IRQ_HANDLED;
-}
-
-me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
-					     unsigned int do_idx,
-					     int irq,
-					     spinlock_t *irq_mode_lock)
-{
-	me8200_do_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me8200_do_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me8200_do_subdevice_t));
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->irq_mode_lock = irq_mode_lock;
-
-	/* Save the index of the digital output */
-	subdevice->do_idx = do_idx;
-	subdevice->irq = irq;
-
-	/* Initialize the registers */
-	if (do_idx == 0) {
-		subdevice->port_reg = reg_base + ME8200_DO_PORT_0_REG;
-	} else if (do_idx == 1) {
-		subdevice->port_reg = reg_base + ME8200_DO_PORT_1_REG;
-	} else {
-		PERROR("Wrong subdevice idx=%d.\n", do_idx);
-		kfree(subdevice);
-		return NULL;
-	}
-	subdevice->irq_ctrl_reg = reg_base + ME8200_IRQ_MODE_REG;
-	subdevice->irq_status_reg = reg_base + ME8200_DO_IRQ_STATUS_REG;
-#ifdef MEDEBUG_DEBUG_REG
-	subdevice->reg_base = reg_base;
-#endif
-
-	/* Initialize the wait queue */
-	init_waitqueue_head(&subdevice->wait_queue);
-
-	/* Request the interrupt line */
-	err = request_irq(irq, me8200_do_isr,
-			  IRQF_DISABLED | IRQF_SHARED,
-			  ME8200_NAME, (void *)subdevice);
-
-	if (err) {
-		PERROR("Cannot get interrupt line.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	PINFO("Registered irq=%d.\n", irq);
-
-	/* Overload base class methods. */
-	subdevice->base.me_subdevice_io_irq_start = me8200_do_io_irq_start;
-	subdevice->base.me_subdevice_io_irq_wait = me8200_do_io_irq_wait;
-	subdevice->base.me_subdevice_io_irq_stop = me8200_do_io_irq_stop;
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me8200_do_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config =
-	    me8200_do_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me8200_do_io_single_read;
-	subdevice->base.me_subdevice_io_single_write =
-	    me8200_do_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me8200_do_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me8200_do_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me8200_do_query_subdevice_caps;
-	subdevice->base.me_subdevice_destructor = me8200_do_destructor;
-
-	subdevice->rised = 0;
-	subdevice->count = 0;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8200_do.h b/drivers/staging/meilhaus/me8200_do.h
deleted file mode 100644
index 2758125..0000000
--- a/drivers/staging/meilhaus/me8200_do.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * @file me8200_do.h
- *
- * @brief ME-8200 digital output subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_DO_H_
-#define _ME8200_DO_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The template subdevice class.
- */
-typedef struct me8200_do_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *irq_mode_lock;
-
-	int irq;				/**< The number of the interrupt request */
-	int rised;				/**< Flag to indicate if an interrupt occured */
-	int count;				/**< Counts the number of interrupts occured */
-	wait_queue_head_t wait_queue;		/**< To wait on interrupts */
-
-	unsigned int do_idx;			/**< The number of the digital output */
-
-	unsigned long port_reg;			/**< The digital output port */
-	unsigned long irq_ctrl_reg;		/**< The interrupt control register */
-	unsigned long irq_status_reg;		/**< The interrupt status register */
-#ifdef MEDEBUG_DEBUG_REG
-	unsigned long reg_base;
-#endif
-} me8200_do_subdevice_t;
-
-/**
- * @brief The constructor to generate a ME-8200 digital output subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param do_idx The index of the digital output subdevice on this device.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
-					     unsigned int do_idx,
-					     int irq,
-					     spinlock_t * irq_mode_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_do_reg.h b/drivers/staging/meilhaus/me8200_do_reg.h
deleted file mode 100644
index 4109504..0000000
--- a/drivers/staging/meilhaus/me8200_do_reg.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file me8200_ao_reg.h
- *
- * @brief ME-8200 analog output subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_DO_REG_H_
-#define _ME8200_DO_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8200_DO_IRQ_STATUS_REG			0x0	// R
-#define ME8200_DO_PORT_0_REG				0x1	// R/W
-#define ME8200_DO_PORT_1_REG				0x2	// R/W
-
-#define ME8200_DO_IRQ_STATUS_BIT_ACTIVE		0x1
-#define ME8200_DO_IRQ_STATUS_SHIFT			1
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8200_reg.h b/drivers/staging/meilhaus/me8200_reg.h
deleted file mode 100644
index a73fe4d..0000000
--- a/drivers/staging/meilhaus/me8200_reg.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file me8200_reg.h
- *
- * @brief ME-8200 register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8200_REG_H_
-#define _ME8200_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8200_IRQ_MODE_REG				0xD	// R/W
-
-#define ME8200_IRQ_MODE_MASK     			0x3
-
-#define ME8200_IRQ_MODE_MASK_MASK			0x0
-#define ME8200_IRQ_MODE_MASK_COMPARE			0x1
-
-#define ME8200_IRQ_MODE_BIT_ENABLE_POWER		0x10
-#define ME8200_IRQ_MODE_BIT_CLEAR_POWER			0x40
-
-#define ME8200_IRQ_MODE_DI_SHIFT			2
-#define ME8200_IRQ_MODE_POWER_SHIFT			1
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8254.c b/drivers/staging/meilhaus/me8254.c
deleted file mode 100644
index d8f742a..0000000
--- a/drivers/staging/meilhaus/me8254.c
+++ /dev/null
@@ -1,1176 +0,0 @@
-/**
- * @file me8254.c
- *
- * @brief 8254 subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "me8254_reg.h"
-#include "me8254.h"
-
-/*
- * Defines
- */
-#define ME8254_NUMBER_CHANNELS 1	/**< One channel per counter. */
-#define ME8254_CTR_WIDTH 16			/**< One counter has 16 bits. */
-
-/*
- * Functions
- */
-
-static int me8254_io_reset_subdevice(struct me_subdevice *subdevice,
-				     struct file *filep, int flags)
-{
-	me8254_subdevice_t *instance;
-	uint8_t clk_src;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8254_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	if (instance->ctr_idx == 0)
-		outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
-		     ME8254_CTRL_BIN, instance->ctrl_reg);
-	else if (instance->ctr_idx == 1)
-		outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
-		     ME8254_CTRL_BIN, instance->ctrl_reg);
-	else
-		outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
-		     ME8254_CTRL_BIN, instance->ctrl_reg);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outb(0x00, instance->val_reg);
-	outb(0x00, instance->val_reg);
-
-	spin_lock(instance->clk_src_reg_lock);
-	clk_src = inb(instance->clk_src_reg);
-
-	switch (instance->device_id) {
-	case PCI_DEVICE_ID_MEILHAUS_ME1400:
-	case PCI_DEVICE_ID_MEILHAUS_ME140A:
-	case PCI_DEVICE_ID_MEILHAUS_ME140B:
-	case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-	case PCI_DEVICE_ID_MEILHAUS_ME14EA:
-	case PCI_DEVICE_ID_MEILHAUS_ME14EB:
-		if (instance->me8254_idx == 0) {
-			if (instance->ctr_idx == 0)
-				clk_src &=
-				    ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ |
-				      ME1400AB_8254_A_0_CLK_SRC_QUARZ);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV);
-			else
-				clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV);
-		} else {
-			if (instance->ctr_idx == 0)
-				clk_src &=
-				    ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ |
-				      ME1400AB_8254_B_0_CLK_SRC_QUARZ);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV);
-			else
-				clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV);
-		}
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		switch (instance->me8254_idx) {
-		case 0:
-		case 2:
-		case 4:
-		case 6:
-		case 8:
-			if (instance->ctr_idx == 0)
-				clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
-			else
-				clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
-			break;
-
-		default:
-			if (instance->ctr_idx == 0)
-				clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
-			else
-				clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
-			break;
-		}
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4610:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
-
-		/* No clock source register available */
-		break;
-
-	default:
-		PERROR("Invalid device type.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	if (!err)
-		outb(clk_src, instance->clk_src_reg);
-
-	spin_unlock(instance->clk_src_reg_lock);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me1400_ab_ref_config(me8254_subdevice_t *instance, int ref)
-{
-	uint8_t clk_src;
-
-	spin_lock(instance->clk_src_reg_lock);
-	clk_src = inb(instance->clk_src_reg);
-
-	switch (ref) {
-	case ME_REF_CTR_EXTERNAL:
-		if (instance->me8254_idx == 0) {
-			if (instance->ctr_idx == 0)
-				clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_QUARZ);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400AB_8254_A_1_CLK_SRC_PREV);
-			else
-				clk_src &= ~(ME1400AB_8254_A_2_CLK_SRC_PREV);
-		} else {
-			if (instance->ctr_idx == 0)
-				clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_QUARZ);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400AB_8254_B_1_CLK_SRC_PREV);
-			else
-				clk_src &= ~(ME1400AB_8254_B_2_CLK_SRC_PREV);
-		}
-
-		break;
-
-	case ME_REF_CTR_PREVIOUS:
-		if (instance->me8254_idx == 0) {
-			if (instance->ctr_idx == 0) {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_SINGLE_CONFIG;
-			} else if (instance->ctr_idx == 1)
-				clk_src |= (ME1400AB_8254_A_1_CLK_SRC_PREV);
-			else
-				clk_src |= (ME1400AB_8254_A_2_CLK_SRC_PREV);
-		} else {
-			if (instance->ctr_idx == 0) {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_SINGLE_CONFIG;
-			} else if (instance->ctr_idx == 1)
-				clk_src |= (ME1400AB_8254_B_1_CLK_SRC_PREV);
-			else
-				clk_src |= (ME1400AB_8254_B_2_CLK_SRC_PREV);
-		}
-
-		break;
-
-	case ME_REF_CTR_INTERNAL_1MHZ:
-		if (instance->me8254_idx == 0) {
-			if (instance->ctr_idx == 0) {
-				clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
-				clk_src &= ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			if (instance->ctr_idx == 0) {
-				clk_src |= (ME1400AB_8254_B_0_CLK_SRC_QUARZ);
-				clk_src &= ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		}
-
-		break;
-
-	case ME_REF_CTR_INTERNAL_10MHZ:
-		if (instance->me8254_idx == 0) {
-			if (instance->ctr_idx == 0) {
-				clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
-				clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		} else {
-			if (instance->ctr_idx == 0) {
-				clk_src |= (ME1400AB_8254_A_0_CLK_SRC_QUARZ);
-				clk_src |= (ME1400AB_8254_A_0_CLK_SRC_10MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_SINGLE_CONFIG;
-			}
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid reference.\n");
-		spin_unlock(instance->clk_src_reg_lock);
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	outb(clk_src, instance->clk_src_reg);
-	spin_unlock(instance->clk_src_reg_lock);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me1400_cd_ref_config(me8254_subdevice_t *instance, int ref)
-{
-	uint8_t clk_src;
-
-	spin_lock(instance->clk_src_reg_lock);
-	clk_src = inb(instance->clk_src_reg);
-
-	switch (ref) {
-	case ME_REF_CTR_EXTERNAL:
-		switch (instance->me8254_idx) {
-		case 0:
-		case 2:
-		case 4:
-		case 6:
-		case 8:
-			if (instance->ctr_idx == 0)
-				clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
-			else
-				clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
-			break;
-
-		default:
-			if (instance->ctr_idx == 0)
-				clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
-			else if (instance->ctr_idx == 1)
-				clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
-			else
-				clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
-			break;
-		}
-		break;
-
-	case ME_REF_CTR_PREVIOUS:
-		switch (instance->me8254_idx) {
-		case 0:
-		case 2:
-		case 4:
-		case 6:
-		case 8:
-			if (instance->ctr_idx == 0) {
-				clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_PREV);
-			} else if (instance->ctr_idx == 1) {
-				clk_src &= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_ACE_1_CLK_SRC_PREV);
-			} else {
-				clk_src &= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_ACE_2_CLK_SRC_PREV);
-			}
-			break;
-
-		default:
-			if (instance->ctr_idx == 0) {
-				clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_PREV);
-			} else if (instance->ctr_idx == 1) {
-				clk_src &= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_BD_1_CLK_SRC_PREV);
-			} else {
-				clk_src &= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_BD_2_CLK_SRC_PREV);
-			}
-			break;
-		}
-
-		break;
-
-	case ME_REF_CTR_INTERNAL_1MHZ:
-		switch (instance->me8254_idx) {
-		case 0:
-		case 2:
-		case 4:
-		case 6:
-		case 8:
-			if (instance->ctr_idx == 0) {
-				clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_1MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_REF;
-			}
-
-			break;
-
-		default:
-			if (instance->ctr_idx == 0) {
-				clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_1MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_REF;
-			}
-			break;
-		}
-
-		break;
-
-	case ME_REF_CTR_INTERNAL_10MHZ:
-		switch (instance->me8254_idx) {
-		case 0:
-		case 2:
-		case 4:
-		case 6:
-		case 8:
-			if (instance->ctr_idx == 0) {
-				clk_src &= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_ACE_0_CLK_SRC_10MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_REF;
-			}
-			break;
-
-		default:
-			if (instance->ctr_idx == 0) {
-				clk_src &= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK);
-				clk_src |= (ME1400CD_8254_BD_0_CLK_SRC_10MHZ);
-			} else {
-				PERROR("Invalid reference.\n");
-				spin_unlock(instance->clk_src_reg_lock);
-				return ME_ERRNO_INVALID_REF;
-			}
-
-			break;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid reference.\n");
-		spin_unlock(instance->clk_src_reg_lock);
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	outb(clk_src, instance->clk_src_reg);
-	spin_unlock(instance->clk_src_reg_lock);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me4600_ref_config(me8254_subdevice_t *instance, int ref)
-{
-	switch (ref) {
-
-	case ME_REF_CTR_EXTERNAL:
-		// Nothing to do
-		break;
-
-	default:
-		PERROR("Invalid reference.\n");
-//                      spin_unlock(instance->clk_src_reg_lock);
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8100_ref_config(me8254_subdevice_t *instance, int ref)
-{
-	switch (ref) {
-
-	case ME_REF_CTR_EXTERNAL:
-		// Nothing to do
-		break;
-
-	default:
-		PERROR("Invalid reference.\n");
-//                      spin_unlock(instance->clk_src_reg_lock);
-		return ME_ERRNO_INVALID_REF;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_io_single_config(struct me_subdevice *subdevice,
-				   struct file *filep,
-				   int channel,
-				   int single_config,
-				   int ref,
-				   int trig_chan,
-				   int trig_type, int trig_edge, int flags)
-{
-	me8254_subdevice_t *instance;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	if (channel) {
-		PERROR("Invalid channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	instance = (me8254_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	// Configure the counter modes
-	if (instance->ctr_idx == 0) {
-		if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
-			outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
-			outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
-			outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
-			outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
-			outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
-			outb(ME8254_CTRL_SC0 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else {
-			PERROR("Invalid single configuration.\n");
-			spin_unlock(&instance->subdevice_lock);
-			return ME_ERRNO_INVALID_SINGLE_CONFIG;
-		}
-	} else if (instance->ctr_idx == 1) {
-		if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
-			outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
-			outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
-			outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
-			outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
-			outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
-			outb(ME8254_CTRL_SC1 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else {
-			PERROR("Invalid single configuration.\n");
-			spin_unlock(&instance->subdevice_lock);
-			return ME_ERRNO_INVALID_SINGLE_CONFIG;
-		}
-	} else {
-		if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_0) {
-			outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M0 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_1) {
-			outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M1 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_2) {
-			outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M2 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_3) {
-			outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M3 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_4) {
-			outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M4 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else if (single_config == ME_SINGLE_CONFIG_CTR_8254_MODE_5) {
-			outb(ME8254_CTRL_SC2 | ME8254_CTRL_LM | ME8254_CTRL_M5 |
-			     ME8254_CTRL_BIN, instance->ctrl_reg);
-		} else {
-			PERROR("Invalid single configuration.\n");
-			spin_unlock(&instance->subdevice_lock);
-			return ME_ERRNO_INVALID_SINGLE_CONFIG;
-		}
-	}
-
-	switch (instance->device_id) {
-	case PCI_DEVICE_ID_MEILHAUS_ME1400:
-	case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-	case PCI_DEVICE_ID_MEILHAUS_ME140A:
-	case PCI_DEVICE_ID_MEILHAUS_ME14EA:
-	case PCI_DEVICE_ID_MEILHAUS_ME140B:
-	case PCI_DEVICE_ID_MEILHAUS_ME14EB:
-		err = me1400_ab_ref_config(instance, ref);
-
-		if (err) {
-			spin_unlock(&instance->subdevice_lock);
-			return err;
-		}
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		err = me1400_cd_ref_config(instance, ref);
-
-		if (err) {
-			spin_unlock(&instance->subdevice_lock);
-			return err;
-		}
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4610:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
-		err = me4600_ref_config(instance, ref);
-
-		if (err) {
-			spin_unlock(&instance->subdevice_lock);
-			return err;
-		}
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
-		err = me8100_ref_config(instance, ref);
-
-		if (err) {
-			spin_unlock(&instance->subdevice_lock);
-			return err;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid device type.\n");
-
-		spin_unlock(&instance->subdevice_lock);
-//                              spin_unlock(instance->clk_src_reg_lock);
-		return ME_ERRNO_INVALID_SINGLE_CONFIG;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_io_single_read(struct me_subdevice *subdevice,
-				 struct file *filep,
-				 int channel,
-				 int *value, int time_out, int flags)
-{
-	me8254_subdevice_t *instance;
-	uint16_t lo_byte;
-	uint16_t hi_byte;
-
-	PDEBUG("executed.\n");
-
-	if (channel) {
-		PERROR("Invalid channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	instance = (me8254_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	if (instance->ctr_idx == 0)
-		outb(ME8254_CTRL_SC0 | ME8254_CTRL_TLO, instance->ctrl_reg);
-	else if (instance->ctr_idx == 1)
-		outb(ME8254_CTRL_SC1 | ME8254_CTRL_TLO, instance->ctrl_reg);
-	else
-		outb(ME8254_CTRL_SC2 | ME8254_CTRL_TLO, instance->ctrl_reg);
-
-	lo_byte = inb(instance->val_reg);
-	hi_byte = inb(instance->val_reg);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	*value = lo_byte | (hi_byte << 8);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_io_single_write(struct me_subdevice *subdevice,
-				  struct file *filep,
-				  int channel,
-				  int value, int time_out, int flags)
-{
-	me8254_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	if (channel) {
-		PERROR("Invalid channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	instance = (me8254_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	outb(value, instance->val_reg);
-	outb((value >> 8), instance->val_reg);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_number_channels(struct me_subdevice *subdevice,
-					int *number)
-{
-	PDEBUG("executed.\n");
-	*number = ME8254_NUMBER_CHANNELS;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_subdevice_type(struct me_subdevice *subdevice,
-				       int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_CTR;
-	*subtype = ME_SUBTYPE_CTR_8254;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_subdevice_caps(struct me_subdevice *subdevice,
-				       int *caps)
-{
-	me8254_subdevice_t *instance;
-	PDEBUG("executed.\n");
-	instance = (me8254_subdevice_t *) subdevice;
-	*caps = instance->caps;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8254_query_subdevice_caps_args(struct me_subdevice *subdevice,
-					    int cap, int *args, int count)
-{
-	PDEBUG("executed.\n");
-
-	if (count != 1) {
-		PERROR("Invalid capability argument count.\n");
-		return ME_ERRNO_INVALID_CAP_ARG_COUNT;
-	}
-
-	if (cap == ME_CAP_CTR_WIDTH) {
-		args[0] = ME8254_CTR_WIDTH;
-	} else {
-		PERROR("Invalid capability.\n");
-		return ME_ERRNO_INVALID_CAP;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static uint32_t me1400AB_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
-				     unsigned int ctr_idx)
-{
-	switch (me8254_idx) {
-
-	case 0:
-		return (reg_base + ME1400AB_8254_A_0_VAL_REG + ctr_idx);
-
-	default:
-		return (reg_base + ME1400AB_8254_B_0_VAL_REG + ctr_idx);
-	}
-
-	return 0;
-}
-
-static uint32_t me1400AB_get_ctrl_reg(uint32_t reg_base,
-				      unsigned int me8254_idx,
-				      unsigned int ctr_idx)
-{
-	switch (me8254_idx) {
-	case 0:
-		return (reg_base + ME1400AB_8254_A_CTRL_REG);
-
-	default:
-		return (reg_base + ME1400AB_8254_B_CTRL_REG);
-	}
-
-	return 0;
-}
-
-static uint32_t me1400AB_get_clk_src_reg(uint32_t reg_base,
-					 unsigned int me8254_idx,
-					 unsigned int ctr_idx)
-{
-	switch (me8254_idx) {
-	case 0:
-		return (reg_base + ME1400AB_CLK_SRC_REG);
-
-	default:
-		return (reg_base + ME1400AB_CLK_SRC_REG);
-	}
-
-	return 0;
-}
-
-static uint32_t me1400CD_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
-				     unsigned int ctr_idx)
-{
-	switch (me8254_idx) {
-	case 0:
-		return (reg_base + ME1400C_8254_A_0_VAL_REG + ctr_idx);
-
-	case 1:
-		return (reg_base + ME1400C_8254_B_0_VAL_REG + ctr_idx);
-
-	case 2:
-		return (reg_base + ME1400C_8254_C_0_VAL_REG + ctr_idx);
-
-	case 3:
-		return (reg_base + ME1400C_8254_D_0_VAL_REG + ctr_idx);
-
-	case 4:
-		return (reg_base + ME1400C_8254_E_0_VAL_REG + ctr_idx);
-
-	case 5:
-		return (reg_base + ME1400D_8254_A_0_VAL_REG + ctr_idx);
-
-	case 6:
-		return (reg_base + ME1400D_8254_B_0_VAL_REG + ctr_idx);
-
-	case 7:
-		return (reg_base + ME1400D_8254_C_0_VAL_REG + ctr_idx);
-
-	case 8:
-		return (reg_base + ME1400D_8254_D_0_VAL_REG + ctr_idx);
-
-	default:
-		return (reg_base + ME1400D_8254_E_0_VAL_REG + ctr_idx);
-	}
-
-	return 0;
-}
-
-static uint32_t me1400CD_get_ctrl_reg(uint32_t reg_base,
-				      unsigned int me8254_idx,
-				      unsigned int ctr_idx)
-{
-	switch (me8254_idx) {
-	case 0:
-		return (reg_base + ME1400C_8254_A_CTRL_REG);
-
-	case 1:
-		return (reg_base + ME1400C_8254_B_CTRL_REG);
-
-	case 2:
-		return (reg_base + ME1400C_8254_C_CTRL_REG);
-
-	case 3:
-		return (reg_base + ME1400C_8254_D_CTRL_REG);
-
-	case 4:
-		return (reg_base + ME1400C_8254_E_CTRL_REG);
-
-	case 5:
-		return (reg_base + ME1400D_8254_A_CTRL_REG);
-
-	case 6:
-		return (reg_base + ME1400D_8254_B_CTRL_REG);
-
-	case 7:
-		return (reg_base + ME1400D_8254_C_CTRL_REG);
-
-	case 8:
-		return (reg_base + ME1400D_8254_D_CTRL_REG);
-
-	default:
-		return (reg_base + ME1400D_8254_E_CTRL_REG);
-	}
-
-	return 0;
-}
-
-static uint32_t me1400CD_get_clk_src_reg(uint32_t reg_base,
-					 unsigned int me8254_idx,
-					 unsigned int ctr_idx)
-{
-	switch (me8254_idx) {
-	case 0:
-		return (reg_base + ME1400C_CLK_SRC_0_REG);
-
-	case 1:
-		return (reg_base + ME1400C_CLK_SRC_0_REG);
-
-	case 2:
-		return (reg_base + ME1400C_CLK_SRC_1_REG);
-
-	case 3:
-		return (reg_base + ME1400C_CLK_SRC_1_REG);
-
-	case 4:
-		return (reg_base + ME1400C_CLK_SRC_2_REG);
-
-	case 5:
-		return (reg_base + ME1400D_CLK_SRC_0_REG);
-
-	case 6:
-		return (reg_base + ME1400D_CLK_SRC_0_REG);
-
-	case 7:
-		return (reg_base + ME1400D_CLK_SRC_1_REG);
-
-	case 8:
-		return (reg_base + ME1400D_CLK_SRC_1_REG);
-
-	default:
-		return (reg_base + ME1400D_CLK_SRC_2_REG);
-	}
-
-	return 0;
-}
-
-static uint32_t me4600_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
-				   unsigned int ctr_idx)
-{
-	return (reg_base + ME4600_8254_0_VAL_REG + ctr_idx);
-}
-
-static uint32_t me4600_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx,
-				    unsigned int ctr_idx)
-{
-	return (reg_base + ME4600_8254_CTRL_REG);
-}
-
-static uint32_t me8100_get_val_reg(uint32_t reg_base, unsigned int me8254_idx,
-				   unsigned int ctr_idx)
-{
-	return (reg_base + ME8100_COUNTER_REG_0 + ctr_idx * 2);
-}
-
-static uint32_t me8100_get_ctrl_reg(uint32_t reg_base, unsigned int me8254_idx,
-				    unsigned int ctr_idx)
-{
-	return (reg_base + ME8100_COUNTER_CTRL_REG);
-}
-
-me8254_subdevice_t *me8254_constructor(uint32_t device_id,
-				       uint32_t reg_base,
-				       unsigned int me8254_idx,
-				       unsigned int ctr_idx,
-				       spinlock_t *ctrl_reg_lock,
-				       spinlock_t *clk_src_reg_lock)
-{
-	me8254_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	// Allocate memory for subdevice instance
-	subdevice = kmalloc(sizeof(me8254_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for 8254 instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me8254_subdevice_t));
-
-	// Check if counter index is out of range
-
-	if (ctr_idx > 2) {
-		PERROR("Counter index is out of range.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize subdevice base class
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-	subdevice->clk_src_reg_lock = clk_src_reg_lock;
-
-	// Save type of Meilhaus device
-	subdevice->device_id = device_id;
-
-	// Save the indices
-	subdevice->me8254_idx = me8254_idx;
-	subdevice->ctr_idx = ctr_idx;
-
-	// Do device specific initialization
-	switch (device_id) {
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140A:
-	case PCI_DEVICE_ID_MEILHAUS_ME14EA:
-		// Check if 8254 index is out of range
-		if (me8254_idx > 0) {
-			PERROR("8254 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140B:	// Fall through
-	case PCI_DEVICE_ID_MEILHAUS_ME14EB:
-		// Check if 8254 index is out of range
-		if (me8254_idx > 1) {
-			PERROR("8254 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-		// Initialize the counters capabilities
-		if (ctr_idx == 0)
-			subdevice->caps =
-			    ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
-			    ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
-			    ME_CAPS_CTR_CLK_EXTERNAL;
-		else
-			subdevice->caps =
-			    ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL;
-
-		// Get the counters registers
-		subdevice->val_reg =
-		    me1400AB_get_val_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->ctrl_reg =
-		    me1400AB_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->clk_src_reg =
-		    me1400AB_get_clk_src_reg(reg_base, me8254_idx, ctr_idx);
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-		// Check if 8254 index is out of range
-		if (me8254_idx > 4) {
-			PERROR("8254 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		// Check if 8254 index is out of range
-		if (me8254_idx > 9) {
-			PERROR("8254 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-		// Initialize the counters capabilities
-		if (ctr_idx == 0) {
-			if (me8254_idx == 0)
-				subdevice->caps =
-				    ME_CAPS_CTR_CLK_PREVIOUS |
-				    ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
-				    ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
-				    ME_CAPS_CTR_CLK_EXTERNAL;
-			else
-				subdevice->caps =
-				    ME_CAPS_CTR_CLK_INTERNAL_1MHZ |
-				    ME_CAPS_CTR_CLK_INTERNAL_10MHZ |
-				    ME_CAPS_CTR_CLK_EXTERNAL;
-		} else
-			subdevice->caps =
-			    ME_CAPS_CTR_CLK_PREVIOUS | ME_CAPS_CTR_CLK_EXTERNAL;
-
-		// Get the counters registers
-		subdevice->val_reg =
-		    me1400CD_get_val_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->ctrl_reg =
-		    me1400CD_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->clk_src_reg =
-		    me1400CD_get_clk_src_reg(reg_base, me8254_idx, ctr_idx);
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4610:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680I:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680S:
-	case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
-		// Check if 8254 index is out of range
-		if (me8254_idx > 0) {
-			PERROR("8254 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-		// Initialize the counters capabilities
-		subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL;
-
-		// Get the counters registers
-		subdevice->val_reg =
-		    me4600_get_val_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->ctrl_reg =
-		    me4600_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->clk_src_reg = 0;	// Not used
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
-		// Check if 8254 index is out of range
-		if (me8254_idx > 0) {
-			PERROR("8254 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-		// Initialize the counters capabilities
-		subdevice->caps = ME_CAPS_CTR_CLK_EXTERNAL;
-
-		// Get the counters registers
-		subdevice->val_reg =
-		    me8100_get_val_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->ctrl_reg =
-		    me8100_get_ctrl_reg(reg_base, me8254_idx, ctr_idx);
-		subdevice->clk_src_reg = 0;	// Not used
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4650:
-	case PCI_DEVICE_ID_MEILHAUS_ME1400:
-	case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-		PERROR("No 8254 subdevices available for subdevice device.\n");
-		me_subdevice_deinit(&subdevice->base);
-		kfree(subdevice);
-		return NULL;
-
-	default:
-		PERROR("Unknown device type.\n");
-		me_subdevice_deinit(&subdevice->base);
-		kfree(subdevice);
-		return NULL;
-	}
-
-	// Overload subdevice base class methods.
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me8254_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config = me8254_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me8254_io_single_read;
-	subdevice->base.me_subdevice_io_single_write = me8254_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me8254_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me8254_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me8254_query_subdevice_caps;
-	subdevice->base.me_subdevice_query_subdevice_caps_args =
-	    me8254_query_subdevice_caps_args;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8254.h b/drivers/staging/meilhaus/me8254.h
deleted file mode 100644
index 572b719..0000000
--- a/drivers/staging/meilhaus/me8254.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file me8254.h
- *
- * @brief 8254 counter implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _ME8254_H_
-#define _ME8254_H_
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The 8254 subdevice class.
- */
-typedef struct me8254_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect the control register from concurrent access. */
-	spinlock_t *clk_src_reg_lock;		/**< Spin lock to protect the clock source register from concurrent access. */
-
-	uint32_t device_id;			/**< The Meilhaus device type carrying the 8254 chip. */
-	int me8254_idx;				/**< The index of the 8254 chip on the device. */
-	int ctr_idx;				/**< The index of the counter on the 8254 chip. */
-
-	int caps;				/**< Holds the device capabilities. */
-
-	unsigned long val_reg;			/**< Holds the actual counter value. */
-	unsigned long ctrl_reg;			/**< Register to configure the 8254 modes. */
-	unsigned long clk_src_reg;		/**< Register to configure the counter connections. */
-} me8254_subdevice_t;
-
-/**
- * @brief The constructor to generate a 8254 instance.
- *
- * @param device_id The kind of Meilhaus device holding the 8254.
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param me8254_idx The index of the 8254 chip on the Meilhaus device.
- * @param ctr_idx The index of the counter inside a 8254 chip.
- * @param ctrl_reg_lock Pointer to spin lock protecting the 8254 control register from concurrent access.
- * @param clk_src_reg_lock Pointer to spin lock protecting the clock source register from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8254_subdevice_t *me8254_constructor(uint32_t device_id,
-				       uint32_t reg_base,
-				       unsigned int me8254_idx,
-				       unsigned int ctr_idx,
-				       spinlock_t * ctrl_reg_lock,
-				       spinlock_t * clk_src_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8254_reg.h b/drivers/staging/meilhaus/me8254_reg.h
deleted file mode 100644
index 7e2c36b..0000000
--- a/drivers/staging/meilhaus/me8254_reg.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * @file me8254_reg.h
- *
- * @brief 8254 counter register definitions.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME8254_REG_H_
-#define _ME8254_REG_H_
-
-#ifdef __KERNEL__
-
-/* ME1400 A/B register offsets */
-#define ME1400AB_8254_A_0_VAL_REG		0x0004 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400AB_8254_A_1_VAL_REG		0x0005 /**< Offset of 8254 A counter 1 value register. */
-#define ME1400AB_8254_A_2_VAL_REG		0x0006 /**< Offset of 8254 A counter 2 value register. */
-#define ME1400AB_8254_A_CTRL_REG		0x0007 /**< Offset of 8254 A control register. */
-
-#define ME1400AB_8254_B_0_VAL_REG		0x000C /**< Offset of 8254 B counter 0 value register. */
-#define ME1400AB_8254_B_1_VAL_REG		0x000D /**< Offset of 8254 B counter 1 value register. */
-#define ME1400AB_8254_B_2_VAL_REG		0x000E /**< Offset of 8254 B counter 2 value register. */
-#define ME1400AB_8254_B_CTRL_REG		0x000F /**< Offset of 8254 B control register. */
-
-#define ME1400AB_CLK_SRC_REG			0x0010 /**< Offset of clock source register. */
-
-/* ME1400 C register offsets */
-#define ME1400C_8254_A_0_VAL_REG		0x0004 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400C_8254_A_1_VAL_REG		0x0005 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400C_8254_A_2_VAL_REG		0x0006 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400C_8254_A_CTRL_REG			0x0007 /**< Offset of 8254 A control register. */
-
-#define ME1400C_8254_B_0_VAL_REG		0x000C /**< Offset of 8254 B counter 0 value register. */
-#define ME1400C_8254_B_1_VAL_REG		0x000D /**< Offset of 8254 B counter 0 value register. */
-#define ME1400C_8254_B_2_VAL_REG		0x000E /**< Offset of 8254 B counter 0 value register. */
-#define ME1400C_8254_B_CTRL_REG			0x000F /**< Offset of 8254 B control register. */
-
-#define ME1400C_8254_C_0_VAL_REG		0x0010 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400C_8254_C_1_VAL_REG		0x0011 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400C_8254_C_2_VAL_REG		0x0012 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400C_8254_C_CTRL_REG			0x0013 /**< Offset of 8254 C control register. */
-
-#define ME1400C_8254_D_0_VAL_REG		0x0014 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400C_8254_D_1_VAL_REG		0x0015 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400C_8254_D_2_VAL_REG		0x0016 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400C_8254_D_CTRL_REG			0x0017 /**< Offset of 8254 D control register. */
-
-#define ME1400C_8254_E_0_VAL_REG		0x0018 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400C_8254_E_1_VAL_REG		0x0019 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400C_8254_E_2_VAL_REG		0x001A /**< Offset of 8254 E counter 0 value register. */
-#define ME1400C_8254_E_CTRL_REG			0x001B /**< Offset of 8254 E control register. */
-
-#define ME1400C_CLK_SRC_0_REG  			0x001C /**< Offset of clock source register 0. */
-#define ME1400C_CLK_SRC_1_REG  			0x001D /**< Offset of clock source register 1. */
-#define ME1400C_CLK_SRC_2_REG  			0x001E /**< Offset of clock source register 2. */
-
-/* ME1400 D register offsets */
-#define ME1400D_8254_A_0_VAL_REG		0x0044 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400D_8254_A_1_VAL_REG		0x0045 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400D_8254_A_2_VAL_REG		0x0046 /**< Offset of 8254 A counter 0 value register. */
-#define ME1400D_8254_A_CTRL_REG			0x0047 /**< Offset of 8254 A control register. */
-
-#define ME1400D_8254_B_0_VAL_REG		0x004C /**< Offset of 8254 B counter 0 value register. */
-#define ME1400D_8254_B_1_VAL_REG		0x004D /**< Offset of 8254 B counter 0 value register. */
-#define ME1400D_8254_B_2_VAL_REG		0x004E /**< Offset of 8254 B counter 0 value register. */
-#define ME1400D_8254_B_CTRL_REG			0x004F /**< Offset of 8254 B control register. */
-
-#define ME1400D_8254_C_0_VAL_REG		0x0050 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400D_8254_C_1_VAL_REG		0x0051 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400D_8254_C_2_VAL_REG		0x0052 /**< Offset of 8254 C counter 0 value register. */
-#define ME1400D_8254_C_CTRL_REG			0x0053 /**< Offset of 8254 C control register. */
-
-#define ME1400D_8254_D_0_VAL_REG		0x0054 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400D_8254_D_1_VAL_REG		0x0055 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400D_8254_D_2_VAL_REG		0x0056 /**< Offset of 8254 D counter 0 value register. */
-#define ME1400D_8254_D_CTRL_REG			0x0057 /**< Offset of 8254 D control register. */
-
-#define ME1400D_8254_E_0_VAL_REG		0x0058 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400D_8254_E_1_VAL_REG		0x0059 /**< Offset of 8254 E counter 0 value register. */
-#define ME1400D_8254_E_2_VAL_REG		0x005A /**< Offset of 8254 E counter 0 value register. */
-#define ME1400D_8254_E_CTRL_REG			0x005B /**< Offset of 8254 E control register. */
-
-#define ME1400D_CLK_SRC_0_REG  			0x005C /**< Offset of clock source register 0. */
-#define ME1400D_CLK_SRC_1_REG  			0x005D /**< Offset of clock source register 1. */
-#define ME1400D_CLK_SRC_2_REG  			0x005E /**< Offset of clock source register 2. */
-
-/* ME4600 register offsets */
-#define ME4600_8254_0_VAL_REG			0x0000 /**< Offset of 8254 A counter 0 value register. */
-#define ME4600_8254_1_VAL_REG			0x0001 /**< Offset of 8254 A counter 0 value register. */
-#define ME4600_8254_2_VAL_REG			0x0002 /**< Offset of 8254 A counter 0 value register. */
-#define ME4600_8254_CTRL_REG			0x0003 /**< Offset of 8254 A control register. */
-
-/* Command words for 8254 control register */
-#define ME8254_CTRL_SC0   0x00	 /**< Counter 0 selection. */
-#define ME8254_CTRL_SC1   0x40	 /**< Counter 1 selection. */
-#define ME8254_CTRL_SC2   0x80	 /**< Counter 2 selection. */
-
-#define ME8254_CTRL_TLO   0x00	 /**< Counter latching operation. */
-#define ME8254_CTRL_LSB   0x10	 /**< Only read LSB. */
-#define ME8254_CTRL_MSB   0x20	 /**< Only read MSB. */
-#define ME8254_CTRL_LM    0x30	 /**< First read LSB, then MSB.  */
-
-#define ME8254_CTRL_M0    0x00	 /**< Mode 0 selection. */
-#define ME8254_CTRL_M1    0x02	 /**< Mode 1 selection. */
-#define ME8254_CTRL_M2    0x04	 /**< Mode 2 selection. */
-#define ME8254_CTRL_M3    0x06	 /**< Mode 3 selection. */
-#define ME8254_CTRL_M4    0x08	 /**< Mode 4 selection. */
-#define ME8254_CTRL_M5    0x0A	 /**< Mode 5 selection. */
-
-#define ME8254_CTRL_BIN   0x00	 /**< Binary counter. */
-#define ME8254_CTRL_BCD   0x01	 /**< BCD counter. */
-
-/* ME-1400 A/B clock source register bits */
-#define ME1400AB_8254_A_0_CLK_SRC_1MHZ		(0 << 7)	/**< 1MHz clock. */
-#define ME1400AB_8254_A_0_CLK_SRC_10MHZ		(1 << 7)	/**< 10MHz clock. */
-#define ME1400AB_8254_A_0_CLK_SRC_PIN		(0 << 6)	/**< CLK 0 to SUB-D. */
-#define ME1400AB_8254_A_0_CLK_SRC_QUARZ		(1 << 6)	/**< Connect CLK 0 with quarz. */
-
-#define ME1400AB_8254_A_1_CLK_SRC_PIN		(0 << 5)	/**< CLK 1 to SUB-D. */
-#define ME1400AB_8254_A_1_CLK_SRC_PREV		(1 << 5)	/**< Connect OUT 0 with CLK 1. */
-
-#define ME1400AB_8254_A_2_CLK_SRC_PIN		(0 << 4)	/**< CLK 2 to SUB-D. */
-#define ME1400AB_8254_A_2_CLK_SRC_PREV		(1 << 4)	/**< Connect OUT 1 with CLK 2. */
-
-#define ME1400AB_8254_B_0_CLK_SRC_1MHZ		(0 << 3)	/**< 1MHz clock. */
-#define ME1400AB_8254_B_0_CLK_SRC_10MHZ		(1 << 3)	/**< 10MHz clock. */
-#define ME1400AB_8254_B_0_CLK_SRC_PIN		(0 << 2)	/**< CLK 0 to SUB-D. */
-#define ME1400AB_8254_B_0_CLK_SRC_QUARZ		(1 << 2)	/**< Connect CLK 0 with quarz. */
-
-#define ME1400AB_8254_B_1_CLK_SRC_PIN		(0 << 1)	/**< CLK 1 to SUB-D. */
-#define ME1400AB_8254_B_1_CLK_SRC_PREV		(1 << 1)	/**< Connect OUT 0 with CLK 1. */
-
-#define ME1400AB_8254_B_2_CLK_SRC_PIN		(0 << 0)	/**< CLK 2 to SUB-D. */
-#define ME1400AB_8254_B_2_CLK_SRC_PREV		(1 << 0)	/**< Connect OUT 1 with CLK 2. */
-
-/* ME-1400 C/D clock source registers bits */
-#define ME1400CD_8254_ACE_0_CLK_SRC_MASK	0x03	/**< Masks all CLK source bits. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_PIN		0x00	/**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_1MHZ	0x01	/**< Connect CLK to 1MHz. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_10MHZ	0x02	/**< Connect CLK to 10MHz. */
-#define ME1400CD_8254_ACE_0_CLK_SRC_PREV	0x03	/**< Connect CLK to previous counter output on ME-1400 D extension. */
-
-#define ME1400CD_8254_ACE_1_CLK_SRC_MASK	0x04	/**< Masks all CLK source bits. */
-#define ME1400CD_8254_ACE_1_CLK_SRC_PIN		0x00	/**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_ACE_1_CLK_SRC_PREV	0x04	/**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_ACE_2_CLK_SRC_MASK	0x08	/**< Masks all CLK source bits. */
-#define ME1400CD_8254_ACE_2_CLK_SRC_PIN		0x00	/**< Connect to SUB-D. */
-#define ME1400CD_8254_ACE_2_CLK_SRC_PREV	0x08	/**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_BD_0_CLK_SRC_MASK		0x30	/**< Masks all CLK source bits. */
-#define ME1400CD_8254_BD_0_CLK_SRC_PIN		0x00	/**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_BD_0_CLK_SRC_1MHZ		0x10	/**< Connect CLK to 1MHz. */
-#define ME1400CD_8254_BD_0_CLK_SRC_10MHZ	0x20	/**< Connect CLK to 10MHz. */
-#define ME1400CD_8254_BD_0_CLK_SRC_PREV		0x30	/**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_BD_1_CLK_SRC_MASK		0x40	/**< Masks all CLK source bits. */
-#define ME1400CD_8254_BD_1_CLK_SRC_PIN		0x00	/**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_BD_1_CLK_SRC_PREV		0x40	/**< Connect CLK to previous counter output. */
-
-#define ME1400CD_8254_BD_2_CLK_SRC_MASK		0x80	/**< Masks all CLK source bits. */
-#define ME1400CD_8254_BD_2_CLK_SRC_PIN		0x00	/**< Connect CLK to SUB-D. */
-#define ME1400CD_8254_BD_2_CLK_SRC_PREV		0x80	/**< Connect CLK to previous counter output. */
-
-/* ME-8100 counter registers */
-#define ME8100_COUNTER_REG_0				0x18	//(r,w)
-#define ME8100_COUNTER_REG_1				0x1A	//(r,w)
-#define ME8100_COUNTER_REG_2				0x1C	//(r,w)
-#define ME8100_COUNTER_CTRL_REG				0x1E	//(r,w)
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8255.c b/drivers/staging/meilhaus/me8255.c
deleted file mode 100644
index ec9c638..0000000
--- a/drivers/staging/meilhaus/me8255.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/**
- * @file me8255.c
- *
- * @brief 8255 subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-#include "medebug.h"
-
-#include "me8255_reg.h"
-#include "me8255.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static uint8_t get_mode_from_mirror(uint32_t mirror)
-{
-	PDEBUG("executed.\n");
-
-	if (mirror & ME8255_PORT_0_OUTPUT) {
-		if (mirror & ME8255_PORT_1_OUTPUT) {
-			if (mirror & ME8255_PORT_2_OUTPUT) {
-				return ME8255_MODE_OOO;
-			} else {
-				return ME8255_MODE_IOO;
-			}
-		} else {
-			if (mirror & ME8255_PORT_2_OUTPUT) {
-				return ME8255_MODE_OIO;
-			} else {
-				return ME8255_MODE_IIO;
-			}
-		}
-	} else {
-		if (mirror & ME8255_PORT_1_OUTPUT) {
-			if (mirror & ME8255_PORT_2_OUTPUT) {
-				return ME8255_MODE_OOI;
-			} else {
-				return ME8255_MODE_IOI;
-			}
-		} else {
-			if (mirror & ME8255_PORT_2_OUTPUT) {
-				return ME8255_MODE_OII;
-			} else {
-				return ME8255_MODE_III;
-			}
-		}
-	}
-}
-
-static int me8255_io_reset_subdevice(struct me_subdevice *subdevice,
-				     struct file *filep, int flags)
-{
-	me8255_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8255_subdevice_t *) subdevice;
-
-	if (flags) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	spin_lock(instance->ctrl_reg_lock);
-	*instance->ctrl_reg_mirror &=
-	    ~(ME8255_PORT_0_OUTPUT << instance->dio_idx);
-	outb(get_mode_from_mirror(*instance->ctrl_reg_mirror),
-	     instance->ctrl_reg);
-	spin_unlock(instance->ctrl_reg_lock);
-
-	outb(0, instance->port_reg);
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8255_io_single_config(struct me_subdevice *subdevice,
-				   struct file *filep,
-				   int channel,
-				   int single_config,
-				   int ref,
-				   int trig_chan,
-				   int trig_type, int trig_edge, int flags)
-{
-	me8255_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8255_subdevice_t *) subdevice;
-
-	if (flags & ~ME_IO_SINGLE_CONFIG_DIO_BYTE) {
-		PERROR("Invalid flag specified.\n");
-		return ME_ERRNO_INVALID_FLAGS;
-	}
-
-	if (channel) {
-		PERROR("Invalid channel.\n");
-		return ME_ERRNO_INVALID_CHANNEL;
-	}
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	if (single_config == ME_SINGLE_CONFIG_DIO_INPUT) {
-		spin_lock(instance->ctrl_reg_lock);
-		*instance->ctrl_reg_mirror &=
-		    ~(ME8255_PORT_0_OUTPUT << instance->dio_idx);
-		outb(get_mode_from_mirror(*instance->ctrl_reg_mirror),
-		     instance->ctrl_reg);
-		spin_unlock(instance->ctrl_reg_lock);
-	} else if (single_config == ME_SINGLE_CONFIG_DIO_OUTPUT) {
-		spin_lock(instance->ctrl_reg_lock);
-		*instance->ctrl_reg_mirror |=
-		    (ME8255_PORT_0_OUTPUT << instance->dio_idx);
-		outb(get_mode_from_mirror(*instance->ctrl_reg_mirror),
-		     instance->ctrl_reg);
-		spin_unlock(instance->ctrl_reg_lock);
-	} else {
-		PERROR("Invalid port direction.\n");
-		err = ME_ERRNO_INVALID_SINGLE_CONFIG;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8255_io_single_read(struct me_subdevice *subdevice,
-				 struct file *filep,
-				 int channel,
-				 int *value, int time_out, int flags)
-{
-	me8255_subdevice_t *instance;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8255_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			*value = inb(instance->port_reg) & (0x1 << channel);
-		} else {
-			PERROR("Invalid bit number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			*value = inb(instance->port_reg);
-		} else {
-			PERROR("Invalid byte number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8255_io_single_write(struct me_subdevice *subdevice,
-				  struct file *filep,
-				  int channel,
-				  int value, int time_out, int flags)
-{
-	me8255_subdevice_t *instance;
-	uint8_t byte;
-	int err = ME_ERRNO_SUCCESS;
-
-	PDEBUG("executed.\n");
-
-	instance = (me8255_subdevice_t *) subdevice;
-
-	ME_SUBDEVICE_ENTER;
-
-	spin_lock(&instance->subdevice_lock);
-	switch (flags) {
-	case ME_IO_SINGLE_TYPE_DIO_BIT:
-		if ((channel >= 0) && (channel < 8)) {
-			if (*instance->
-			    ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT <<
-					       instance->dio_idx)) {
-				byte = inb(instance->port_reg);
-
-				if (value)
-					byte |= 0x1 << channel;
-				else
-					byte &= ~(0x1 << channel);
-
-				outb(byte, instance->port_reg);
-			} else {
-				PERROR("Port not in output mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid bit number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	case ME_IO_SINGLE_NO_FLAGS:
-	case ME_IO_SINGLE_TYPE_DIO_BYTE:
-		if (channel == 0) {
-			if (*instance->
-			    ctrl_reg_mirror & (ME8255_PORT_0_OUTPUT <<
-					       instance->dio_idx)) {
-				outb(value, instance->port_reg);
-			} else {
-				PERROR("Port not in output mode.\n");
-				err = ME_ERRNO_PREVIOUS_CONFIG;
-			}
-		} else {
-			PERROR("Invalid byte number.\n");
-			err = ME_ERRNO_INVALID_CHANNEL;
-		}
-		break;
-
-	default:
-		PERROR("Invalid flags specified.\n");
-		err = ME_ERRNO_INVALID_FLAGS;
-	}
-	spin_unlock(&instance->subdevice_lock);
-
-	ME_SUBDEVICE_EXIT;
-
-	return err;
-}
-
-static int me8255_query_number_channels(struct me_subdevice *subdevice,
-					int *number)
-{
-	PDEBUG("executed.\n");
-	*number = ME8255_NUMBER_CHANNELS;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8255_query_subdevice_type(struct me_subdevice *subdevice,
-				       int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = ME_TYPE_DIO;
-	*subtype = ME_SUBTYPE_SINGLE;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me8255_query_subdevice_caps(struct me_subdevice *subdevice,
-				       int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = ME_CAPS_DIO_DIR_BYTE;
-	return ME_ERRNO_SUCCESS;
-}
-
-me8255_subdevice_t *me8255_constructor(uint32_t device_id,
-				       uint32_t reg_base,
-				       unsigned int me8255_idx,
-				       unsigned int dio_idx,
-				       int *ctrl_reg_mirror,
-				       spinlock_t *ctrl_reg_lock)
-{
-	me8255_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(me8255_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for 8255 instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(me8255_subdevice_t));
-
-	/* Check if counter index is out of range */
-
-	if (dio_idx > 2) {
-		PERROR("DIO index is out of range.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save the pointer to global port settings */
-	subdevice->ctrl_reg_mirror = ctrl_reg_mirror;
-
-	/* Save type of Meilhaus device */
-	subdevice->device_id = device_id;
-
-	/* Save the indices */
-	subdevice->me8255_idx = me8255_idx;
-	subdevice->dio_idx = dio_idx;
-
-	/* Do device specific initialization */
-	switch (device_id) {
-	case PCI_DEVICE_ID_MEILHAUS_ME1400:
-	case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140A:
-	case PCI_DEVICE_ID_MEILHAUS_ME14EA:
-		/* Check if 8255 index is out of range */
-		if (me8255_idx > 0) {
-			PERROR("8255 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140B:	/* Fall through */
-	case PCI_DEVICE_ID_MEILHAUS_ME14EB:
-		/* Check if 8255 index is out of range */
-		if (me8255_idx > 1) {
-			PERROR("8255 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-
-		/* Get the registers */
-		if (me8255_idx == 0) {
-			subdevice->ctrl_reg = reg_base + ME1400AB_PORT_A_CTRL;
-			subdevice->port_reg =
-			    reg_base + ME1400AB_PORT_A_0 + dio_idx;
-		} else if (me8255_idx == 1) {
-			subdevice->ctrl_reg = reg_base + ME1400AB_PORT_B_CTRL;
-			subdevice->port_reg =
-			    reg_base + ME1400AB_PORT_B_0 + dio_idx;
-		}
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-		/* Check if 8255 index is out of range */
-		if (me8255_idx > 0) {
-			PERROR("8255 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:	/* Fall through */
-		/* Check if 8255 index is out of range */
-		if (me8255_idx > 1) {
-			PERROR("8255 index is out of range.\n");
-			me_subdevice_deinit(&subdevice->base);
-			kfree(subdevice);
-			return NULL;
-		}
-
-		/* Get the registers */
-		if (me8255_idx == 0) {
-			subdevice->ctrl_reg = reg_base + ME1400CD_PORT_A_CTRL;
-			subdevice->port_reg =
-			    reg_base + ME1400CD_PORT_A_0 + dio_idx;
-		} else if (me8255_idx == 1) {
-			subdevice->ctrl_reg = reg_base + ME1400CD_PORT_B_CTRL;
-			subdevice->port_reg =
-			    reg_base + ME1400CD_PORT_B_0 + dio_idx;
-		}
-
-		break;
-
-	default:
-		PERROR("Unknown device type. dev ID: 0x%04x\n", device_id);
-
-		me_subdevice_deinit(&subdevice->base);
-
-		kfree(subdevice);
-
-		return NULL;
-	}
-
-	/* Overload subdevice base class methods. */
-	subdevice->base.me_subdevice_io_reset_subdevice =
-	    me8255_io_reset_subdevice;
-	subdevice->base.me_subdevice_io_single_config = me8255_io_single_config;
-	subdevice->base.me_subdevice_io_single_read = me8255_io_single_read;
-	subdevice->base.me_subdevice_io_single_write = me8255_io_single_write;
-	subdevice->base.me_subdevice_query_number_channels =
-	    me8255_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    me8255_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    me8255_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/me8255.h b/drivers/staging/meilhaus/me8255.h
deleted file mode 100644
index 3382300..0000000
--- a/drivers/staging/meilhaus/me8255.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file me8255.h
- *
- * @brief Meilhaus PIO 8255 implementation.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME8255_H_
-#define _ME8255_H_
-
-#include "mesubdevice.h"
-#include "meslock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The 8255 subdevice class.
- */
-typedef struct me8255_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-
-	int *ctrl_reg_mirror;			/**< Pointer to mirror of the control register. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg and #ctrl_reg_mirror from concurrent access. */
-
-	uint32_t device_id;				/**< The PCI device id of the device holding the 8255 chip. */
-	int me8255_idx;					/**< The index of the 8255 chip on the device. */
-	int dio_idx;					/**< The index of the DIO port on the 8255 chip. */
-
-	unsigned long port_reg;			/**< Register to read or write a value from or to the port respectively. */
-	unsigned long ctrl_reg;			/**< Register to configure the 8255 modes. */
-} me8255_subdevice_t;
-
-/**
- * @brief The constructor to generate a 8255 instance.
- *
- * @param device_id The kind of Meilhaus device holding the 8255.
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param me8255_idx The index of the 8255 chip on the Meilhaus device.
- * @param dio_idx The index of the counter inside a 8255 chip.
- * @param ctr_reg_mirror Pointer to mirror of control register.
- * @param ctrl_reg_lock Pointer to spin lock protecting the 8255 control register and #ctrl_reg_mirror from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-me8255_subdevice_t *me8255_constructor(uint32_t device_id,
-				       uint32_t reg_base,
-				       unsigned int me8255_idx,
-				       unsigned int dio_idx,
-				       int *ctrl_reg_mirror,
-				       spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/me8255_reg.h b/drivers/staging/meilhaus/me8255_reg.h
deleted file mode 100644
index d1dea1a..0000000
--- a/drivers/staging/meilhaus/me8255_reg.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file me8255_reg.h
- *
- * @brief 8255 counter register definitions.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME8255_REG_H_
-#define _ME8255_REG_H_
-
-#ifdef __KERNEL__
-
-#define ME8255_NUMBER_CHANNELS		8		/**< The number of channels per 8255 port. */
-
-#define ME1400AB_PORT_A_0			0x0000	/**< Port 0 offset. */
-#define ME1400AB_PORT_A_1			0x0001	/**< Port 1 offset. */
-#define ME1400AB_PORT_A_2			0x0002	/**< Port 2 offset. */
-#define ME1400AB_PORT_A_CTRL		0x0003	/**< Control register for 8255 A. */
-
-#define ME1400AB_PORT_B_0			0x0008	/**< Port 0 offset. */
-#define ME1400AB_PORT_B_1			0x0009	/**< Port 1 offset. */
-#define ME1400AB_PORT_B_2			0x000A	/**< Port 2 offset. */
-#define ME1400AB_PORT_B_CTRL		0x000B	/**< Control register for 8255 B. */
-
-#define ME1400CD_PORT_A_0			0x0000	/**< Port 0 offset. */
-#define ME1400CD_PORT_A_1			0x0001	/**< Port 1 offset. */
-#define ME1400CD_PORT_A_2			0x0002	/**< Port 2 offset. */
-#define ME1400CD_PORT_A_CTRL		0x0003	/**< Control register for 8255 A. */
-
-#define ME1400CD_PORT_B_0			0x0040	/**< Port 0 offset. */
-#define ME1400CD_PORT_B_1			0x0041	/**< Port 1 offset. */
-#define ME1400CD_PORT_B_2			0x0042	/**< Port 2 offset. */
-#define ME1400CD_PORT_B_CTRL		0x0043	/**< Control register for 8255 B. */
-
-#define ME8255_MODE_OOO				0x80	/**< Port 2 = Output, Port 1 = Output, Port 0 = Output */
-#define ME8255_MODE_IOO				0x89	/**< Port 2 = Input,  Port 1 = Output, Port 0 = Output */
-#define ME8255_MODE_OIO				0x82	/**< Port 2 = Output, Port 1 = Input,  Port 0 = Output */
-#define ME8255_MODE_IIO				0x8B	/**< Port 2 = Input,  Port 1 = Input,  Port 0 = Output */
-#define ME8255_MODE_OOI				0x90	/**< Port 2 = Output, Port 1 = Output, Port 0 = Input */
-#define ME8255_MODE_IOI				0x99	/**< Port 2 = Input,  Port 1 = Output, Port 0 = Input */
-#define ME8255_MODE_OII				0x92	/**< Port 2 = Output, Port 1 = Input,  Port 0 = Input */
-#define ME8255_MODE_III				0x9B	/**< Port 2 = Input,  Port 1 = Input,  Port 0 = Input */
-
-#define ME8255_PORT_0_OUTPUT		0x1		/**< If set in mirror then port 0 is in output mode. */
-#define ME8255_PORT_1_OUTPUT		0x2		/**< If set in mirror then port 1 is in output mode. */
-#define ME8255_PORT_2_OUTPUT		0x4		/**< If set in mirror then port 2 is in output mode. */
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/mecirc_buf.h b/drivers/staging/meilhaus/mecirc_buf.h
deleted file mode 100644
index 5166585..0000000
--- a/drivers/staging/meilhaus/mecirc_buf.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * @file mecirc_buf.h
- *
- * @brief Meilhaus circular buffer implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke  (k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _MECIRC_BUF_H_
-#define _MECIRC_BUF_H_
-
-# ifdef __KERNEL__
-
-#  ifdef BOSCH
-
-typedef struct me_circ_buf {
-	unsigned int mask;
-//      unsigned int count;
-	uint32_t *buf;
-	int volatile head;
-	int volatile tail;
-} me_circ_buf_t;
-
-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 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 inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
-{
-	int end;
-	int n;
-//      end = buf->count - buf->tail;
-//      n = (buf->head + end) & (buf->count - 1);
-	end = buf->mask + 1 - buf->tail;
-	n = (buf->head + end) & (buf->mask);
-	return (n < end) ? n : end;
-}
-
-static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
-{
-	int end;
-	int n;
-
-//      end = buf->count - 1 - buf->head;
-//      n = (end + buf->tail) & (buf->count - 1);
-	end = buf->mask - buf->head;
-	n = (end + buf->tail) & (buf->mask);
-	return (n <= end) ? n : (end + 1);
-}
-
-#define _CBUFF_32b_t
-
-#  else	//~BOSCH
-/// @note buf->mask = buf->count-1 = ME4600_AI_CIRC_BUF_COUNT-1
-
-#   ifdef _CBUFF_32b_t
-	//32 bit
-typedef struct me_circ_buf_32b {
-	int volatile head;
-	int volatile tail;
-	unsigned int mask;	//buffor size-1 must be 2^n-1 to work
-	uint32_t *buf;
-} me_circ_buf_t;
-#   else
-	//16 bit
-typedef struct me_circ_buf_16b {
-	int volatile head;
-	int volatile tail;
-	unsigned int mask;	//buffor size-1 must be 2^n-1 to work
-	uint16_t *buf;
-} me_circ_buf_t;
-#   endif //_CBUFF_32b_t
-
-/** How many values is in buffer */
-static inline int me_circ_buf_values(me_circ_buf_t * buf)
-{
-	return ((buf->head - buf->tail) & (buf->mask));
-}
-
-/** How many space left */
-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 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 +
-							1);
-}
-
-/** How many values can be write to buffer in one chunck. */
-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 -
-							    buf->head - 1);
-}
-
-#  endif //BOSCH
-# endif	//__KERNEL__
-#endif //_MECIRC_BUF_H_
diff --git a/drivers/staging/meilhaus/mecommon.h b/drivers/staging/meilhaus/mecommon.h
deleted file mode 100644
index ef47c38..0000000
--- a/drivers/staging/meilhaus/mecommon.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File	:mecommon.h
- * Author	:GG (Guenter Gebhardt)	<g.gebhardt@meilhaus.de>
- * Author	:KG (Krzysztof Gantzke)	<k.gantzke@meilhaus.de>
- */
-
-#ifndef _MECOMMON_H_
-#define _MECOMMON_H_
-
-/*==================================================================
-  The version of this release
-  ================================================================*/
-
-#ifndef ME_VERSION_DRIVER
-/* Unknown version */
-# define ME_VERSION_DRIVER	0xFFFFFFFF
-#endif
-
-#ifndef LIBMEDRIVER_VERSION
-/* Unknown version */
-# define LIBMEDRIVER_VERSION	0xFFFFFFFF
-#endif
-
-#endif
diff --git a/drivers/staging/meilhaus/medebug.h b/drivers/staging/meilhaus/medebug.h
deleted file mode 100644
index dcfb97c..0000000
--- a/drivers/staging/meilhaus/medebug.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * @file medebug.h
- *
- * @brief Debugging defines.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-#ifndef _MEDEBUG_H_
-#define _MEDEBUG_H_
-
-#ifdef __KERNEL__
-
-#include <linux/kernel.h>
-
-//Messages control.
-
-#ifdef MEDEBUG_TEST_ALL		/* Switch to enable all info messages. */
-# ifndef MEDEBUG_TEST
-#  define MEDEBUG_TEST
-# endif
-# ifndef MEDEBUG_TEST_INFO
-#  define MEDEBUG_TEST_INFO
-# endif
-# ifndef MEDEBUG_DEBUG_REG
-#  define MEDEBUG_DEBUG_REG	/* Switch to enable registry access debuging messages. */
-# endif
-# ifndef MEDEBUG_DEBUG_LOCKS
-#  define MEDEBUG_DEBUG_LOCKS	/* Switch to enable locking messages. */
-# endif
-#endif
-
-#ifdef MEDEBUG_TEST_INFO	/* Switch to enable info  and test messages. */
-# ifndef MEDEBUG_INFO
-#  define MEDEBUG_INFO		/* Switch to enable info messages. */
-# endif
-# ifndef MEDEBUG_TEST
-#  define MEDEBUG_TEST
-# endif
-#endif
-
-#ifdef MEDEBUG_TEST		/* Switch to enable debug test messages. */
-# ifndef MEDEBUG_DEBUG
-#  define MEDEBUG_DEBUG		/* Switch to enable debug messages. */
-# endif
-# ifndef MEDEBUG_ERROR
-#  define MEDEBUG_ERROR		/* Switch to enable error messages. */
-# endif
-#endif
-
-#ifdef MEDEBUG_ERROR		/* Switch to enable error messages. */
-# ifndef MEDEBUG_ERROR_CRITICAL	/* Also critical error messages. */
-#  define MEDEBUG_ERROR_CRITICAL	/* Switch to enable high importance error messages. */
-# endif
-#endif
-
-#undef PDEBUG			/* Only to be sure. */
-#undef PINFO			/* Only to be sure. */
-#undef PERROR			/* Only to be sure. */
-#undef PERROR_CRITICAL		/* Only to be sure. */
-#undef PDEBUG_REG		/* Only to be sure. */
-#undef PDEBUG_LOCKS		/* Only to be sure. */
-#undef PSECURITY		/* Only to be sure. */
-#undef PLOG			/* Only to be sure. */
-
-#ifdef MEDEBUG_DEBUG
-# define PDEBUG(fmt, args...) \
-	printk(KERN_DEBUG"ME_DRV D: <%s> " fmt, __func__, ##args)
-#else
-# define PDEBUG(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_DEBUG_LOCKS
-# define PDEBUG_LOCKS(fmt, args...) \
-	printk(KERN_DEBUG"ME_DRV L: <%s> " fmt, __func__, ##args)
-#else
-# define PDEBUG_LOCKS(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_DEBUG_REG
-# define PDEBUG_REG(fmt, args...) \
-	printk(KERN_DEBUG"ME_DRV R: <%s:%d> REG:" fmt, __func__, __LINE__, ##args)
-#else
-# define PDEBUG_REG(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_INFO
-# define PINFO(fmt, args...) \
-	printk(KERN_INFO"ME_DRV I: " fmt, ##args)
-#else
-# define PINFO(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_ERROR
-# define PERROR(fmt, args...) \
-	printk(KERN_ERR"ME_DRV E: <%s:%i> " fmt, __FILE__, __LINE__, ##args)
-#else
-# define PERROR(fmt, args...)
-#endif
-
-#ifdef MEDEBUG_ERROR_CRITICAL
-# define PERROR_CRITICAL(fmt, args...) \
-	printk(KERN_CRIT"ME_DRV C: <%s:%i> " fmt, __FILE__, __LINE__, ##args)
-#else
-# define PERROR_CRITICAL(fmt, args...)
-#endif
-
-//This debug is only to detect logical errors!
-# define PSECURITY(fmt, args...) \
-	printk(KERN_CRIT"ME_DRV SECURITY: <%s:%s:%i> " fmt, __FILE__, __func__, __LINE__, ##args)
-//This debug is to keep track in customers' system
-# define PLOG(fmt, args...) \
-	printk(KERN_INFO"ME_DRV: " fmt, ##args)
-
-//This debug is to check new parts during development
-#ifdef MEDEBUG_DEVELOP
-# define PDEVELOP(fmt, args...) \
-	printk(KERN_CRIT"ME_DRV: <%s:%s:%i> " fmt, __FILE__, __func__, __LINE__, ##args)
-#else
-# define PDEVELOP(fmt, args...)
-#endif
-
-#endif //__KERNEL__
-#endif //_MEDEBUG_H_
diff --git a/drivers/staging/meilhaus/medefines.h b/drivers/staging/meilhaus/medefines.h
deleted file mode 100644
index 6158ef5..0000000
--- a/drivers/staging/meilhaus/medefines.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : medefines.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- * Author      : KG (Krzysztof Gantzke)  <k.gantzke@meilhaus.de>
- */
-
-#ifndef _MEDEFINES_H_
-#define _MEDEFINES_H_
-
-/*==================================================================
-  General
-  ================================================================*/
-
-#define ME_VALUE_NOT_USED							0x0
-#define ME_VALUE_INVALID							~0x0
-
-/*==================================================================
-  Defines common to access functions
-  ================================================================*/
-
-#define ME_LOCK_RELEASE								0x00010001
-#define ME_LOCK_SET									0x00010002
-#define ME_LOCK_CHECK								0x00010003
-
-/*==================================================================
-  Defines meOpen function
-  ================================================================*/
-
-#define ME_OPEN_NO_FLAGS							0x0
-
-/*==================================================================
-  Defines meClose function
-  ================================================================*/
-
-#define ME_CLOSE_NO_FLAGS							0x0
-
-/*==================================================================
-  Defines meLockDriver function
-  ================================================================*/
-
-#define ME_LOCK_DRIVER_NO_FLAGS						0x0
-
-/*==================================================================
-  Defines meLockDevice function
-  ================================================================*/
-
-#define ME_LOCK_DEVICE_NO_FLAGS						0x0
-
-/*==================================================================
-  Defines meLockSubdevice function
-  ================================================================*/
-
-#define ME_LOCK_SUBDEVICE_NO_FLAGS					0x0
-
-
-/*==================================================================
-  Defines common to error functions
-  ================================================================*/
-
-#define ME_ERROR_MSG_MAX_COUNT						256
-
-#define ME_SWITCH_DISABLE							0x00020001
-#define ME_SWITCH_ENABLE							0x00020002
-
-/*==================================================================
-  Defines common to io functions
-  ================================================================*/
-
-#define ME_REF_DIO_FIFO_LOW							0x00030001
-#define ME_REF_DIO_FIFO_HIGH						0x00030002
-
-#define ME_REF_CTR_PREVIOUS							0x00040001
-#define ME_REF_CTR_INTERNAL_1MHZ					0x00040002
-#define ME_REF_CTR_INTERNAL_10MHZ					0x00040003
-#define ME_REF_CTR_EXTERNAL							0x00040004
-
-#define ME_REF_AI_GROUND							0x00050001
-#define ME_REF_AI_DIFFERENTIAL						0x00050002
-
-#define ME_REF_AO_GROUND							0x00060001
-
-#define ME_TRIG_CHAN_DEFAULT						0x00070001
-#define ME_TRIG_CHAN_SYNCHRONOUS					0x00070002
-
-#define ME_TRIG_TYPE_NONE							0x00000000
-#define ME_TRIG_TYPE_SW								0x00080001
-#define ME_TRIG_TYPE_THRESHOLD						0x00080002
-#define ME_TRIG_TYPE_WINDOW							0x00080003
-#define ME_TRIG_TYPE_EDGE							0x00080004
-#define ME_TRIG_TYPE_SLOPE							0x00080005
-#define ME_TRIG_TYPE_EXT_DIGITAL					0x00080006
-#define ME_TRIG_TYPE_EXT_ANALOG						0x00080007
-#define ME_TRIG_TYPE_PATTERN						0x00080008
-#define ME_TRIG_TYPE_TIMER							0x00080009
-#define ME_TRIG_TYPE_COUNT							0x0008000A
-#define ME_TRIG_TYPE_FOLLOW							0x0008000B
-
-#define ME_TRIG_EDGE_NONE							0x00000000
-#define ME_TRIG_EDGE_ABOVE							0x00090001
-#define ME_TRIG_EDGE_BELOW							0x00090002
-#define ME_TRIG_EDGE_ENTRY							0x00090003
-#define ME_TRIG_EDGE_EXIT							0x00090004
-#define ME_TRIG_EDGE_RISING							0x00090005
-#define ME_TRIG_EDGE_FALLING						0x00090006
-#define ME_TRIG_EDGE_ANY							0x00090007
-
-#define ME_TIMER_ACQ_START							0x000A0001
-#define ME_TIMER_SCAN_START							0x000A0002
-#define ME_TIMER_CONV_START							0x000A0003
-
-/*==================================================================
-  Defines for meIOFrequencyToTicks function
-  ================================================================*/
-
-#define ME_IO_FREQUENCY_TO_TICKS_NO_FLAGS			0x0
-
-/*==================================================================
-  Defines for meIOIrqStart function
-  ================================================================*/
-
-#define ME_IRQ_SOURCE_DIO_PATTERN					0x000B0001
-#define ME_IRQ_SOURCE_DIO_MASK						0x000B0002
-#define ME_IRQ_SOURCE_DIO_LINE						0x000B0003
-#define ME_IRQ_SOURCE_DIO_OVER_TEMP					0x000B0004
-
-#define ME_IRQ_EDGE_NOT_USED						0x00000000
-#define ME_IRQ_EDGE_RISING							0x000C0001
-#define ME_IRQ_EDGE_FALLING							0x000C0002
-#define ME_IRQ_EDGE_ANY								0x000C0003
-
-/*==================================================================
-  Defines for meIOIrqStart function
-  ================================================================*/
-
-#define ME_IO_IRQ_START_NO_FLAGS					0x000000
-#define ME_IO_IRQ_START_DIO_BIT						0x000001
-#define ME_IO_IRQ_START_DIO_BYTE					0x000002
-#define ME_IO_IRQ_START_DIO_WORD					0x000004
-#define ME_IO_IRQ_START_DIO_DWORD					0x000008
-#define ME_IO_IRQ_START_PATTERN_FILTERING			0x000010
-#define ME_IO_IRQ_START_EXTENDED_STATUS				0x000020
-
-/*==================================================================
-  Defines for meIOIrqWait function
-  ================================================================*/
-
-#define ME_IO_IRQ_WAIT_NO_FLAGS						0x000000
-#define ME_IO_IRQ_WAIT_NORMAL_STATUS				0x000001
-#define ME_IO_IRQ_WAIT_EXTENDED_STATUS				0x000002
-
-/*==================================================================
-  Defines for meIOIrqStop function
-  ================================================================*/
-
-#define ME_IO_IRQ_STOP_NO_FLAGS						0x000000
-
-/*==================================================================
-  Defines for meIOIrqSetCallback function
-  ================================================================*/
-
-#define ME_IO_IRQ_SET_CALLBACK_NO_FLAGS				0x0
-
-/*==================================================================
-  Defines for meIOResetDevice function
-  ================================================================*/
-
-#define ME_IO_RESET_DEVICE_NO_FLAGS					0x0
-
-/*==================================================================
-  Defines for meIOResetSubdevice function
-  ================================================================*/
-
-#define ME_IO_RESET_SUBDEVICE_NO_FLAGS				0x0
-
-/*==================================================================
-  Defines for meIOSingleConfig function
-  ================================================================*/
-
-#define ME_SINGLE_CONFIG_DIO_INPUT					0x000D0001
-#define ME_SINGLE_CONFIG_DIO_OUTPUT					0x000D0002
-#define ME_SINGLE_CONFIG_DIO_HIGH_IMPEDANCE			0x000D0003
-#define ME_SINGLE_CONFIG_DIO_SINK					0x000D0004
-#define ME_SINGLE_CONFIG_DIO_SOURCE					0x000D0005
-#define ME_SINGLE_CONFIG_DIO_MUX32M					0x000D0006
-#define ME_SINGLE_CONFIG_DIO_DEMUX32				0x000D0007
-#define ME_SINGLE_CONFIG_DIO_BIT_PATTERN			0x000D0008
-
-#define ME_SINGLE_CONFIG_CTR_8254_MODE_0			0x000E0001
-#define ME_SINGLE_CONFIG_CTR_8254_MODE_1			0x000E0002
-#define ME_SINGLE_CONFIG_CTR_8254_MODE_2			0x000E0003
-#define ME_SINGLE_CONFIG_CTR_8254_MODE_3			0x000E0004
-#define ME_SINGLE_CONFIG_CTR_8254_MODE_4			0x000E0005
-#define ME_SINGLE_CONFIG_CTR_8254_MODE_5			0x000E0006
-
-#define ME_IO_SINGLE_CONFIG_NO_FLAGS				0x00
-#define ME_IO_SINGLE_CONFIG_DIO_BIT					0x01
-#define ME_IO_SINGLE_CONFIG_DIO_BYTE				0x02
-#define ME_IO_SINGLE_CONFIG_DIO_WORD				0x04
-#define ME_IO_SINGLE_CONFIG_DIO_DWORD				0x08
-#define ME_IO_SINGLE_CONFIG_MULTISIG_LED_ON			0x10
-#define ME_IO_SINGLE_CONFIG_MULTISIG_LED_OFF		0x20
-#define ME_IO_SINGLE_CONFIG_AI_RMS					0x40
-#define ME_IO_SINGLE_CONFIG_CONTINUE				0x80
-
-/*==================================================================
-  Defines for meIOSingle function
-  ================================================================*/
-
-#define ME_IO_SINGLE_NO_FLAGS						0x0
-#define ME_IO_SINGLE_NONBLOCKING					0x20
-
-#define ME_DIR_INPUT								0x000F0001
-#define ME_DIR_OUTPUT								0x000F0002
-
-#define ME_IO_SINGLE_TYPE_NO_FLAGS					0x00
-#define ME_IO_SINGLE_TYPE_DIO_BIT					0x01
-#define ME_IO_SINGLE_TYPE_DIO_BYTE					0x02
-#define ME_IO_SINGLE_TYPE_DIO_WORD					0x04
-#define ME_IO_SINGLE_TYPE_DIO_DWORD					0x08
-#define ME_IO_SINGLE_TYPE_TRIG_SYNCHRONOUS			0x10
-#define ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING			0x20
-
-/*==================================================================
-  Defines for meIOStreamConfig function
-  ================================================================*/
-
-#define ME_IO_STREAM_CONFIG_NO_FLAGS				0x0
-#define ME_IO_STREAM_CONFIG_BIT_PATTERN				0x1
-#define ME_IO_STREAM_CONFIG_WRAPAROUND				0x2
-#define ME_IO_STREAM_CONFIG_SAMPLE_AND_HOLD			0x4
-#define ME_IO_STREAM_CONFIG_HARDWARE_ONLY			0x8
-
-#define ME_IO_STREAM_CONFIG_TYPE_NO_FLAGS			0x0
-
-#define ME_IO_STREAM_TRIGGER_TYPE_NO_FLAGS			0x0
-
-/*==================================================================
-  Defines for meIOStreamRead function
-  ================================================================*/
-
-#define ME_READ_MODE_BLOCKING						0x00100001
-#define ME_READ_MODE_NONBLOCKING					0x00100002
-
-#define ME_IO_STREAM_READ_NO_FLAGS					0x0
-#define ME_IO_STREAM_READ_FRAMES					0x1
-
-/*==================================================================
-  Defines for meIOStreamWrite function
-  ================================================================*/
-
-#define ME_WRITE_MODE_BLOCKING						0x00110001
-#define ME_WRITE_MODE_NONBLOCKING					0x00110002
-#define ME_WRITE_MODE_PRELOAD						0x00110003
-
-#define ME_IO_STREAM_WRITE_NO_FLAGS					0x00000000
-
-/*==================================================================
-  Defines for meIOStreamStart function
-  ================================================================*/
-
-#define ME_IO_STREAM_START_NO_FLAGS					0x00000000
-
-#define ME_START_MODE_BLOCKING						0x00120001
-#define ME_START_MODE_NONBLOCKING					0x00120002
-
-#define ME_IO_STREAM_START_TYPE_NO_FLAGS			0x0
-#define ME_IO_STREAM_START_TYPE_TRIG_SYNCHRONOUS	0x1
-
-/*==================================================================
-  Defines for meIOStreamStop function
-  ================================================================*/
-
-#define ME_IO_STREAM_STOP_NO_FLAGS					0x00000000
-#define ME_IO_STREAM_STOP_PRESERVE_BUFFERS			0x00000001
-
-#define ME_STOP_MODE_IMMEDIATE						0x00130001
-#define ME_STOP_MODE_LAST_VALUE						0x00130002
-
-#define ME_IO_STREAM_STOP_TYPE_NO_FLAGS				0x00000000
-
-/*==================================================================
-  Defines for meIOStreamStatus function
-  ================================================================*/
-
-#define ME_WAIT_NONE								0x00140001
-#define ME_WAIT_IDLE								0x00140002
-
-#define ME_STATUS_INVALID							0x00000000
-#define ME_STATUS_IDLE								0x00150001
-#define ME_STATUS_BUSY								0x00150002
-#define ME_STATUS_ERROR								0x00150003
-
-#define ME_IO_STREAM_STATUS_NO_FLAGS				0x00000000
-
-/*==================================================================
-  Defines for meIOStreamSetCallbacks function
-  ================================================================*/
-
-#define ME_IO_STREAM_SET_CALLBACKS_NO_FLAGS			0x00000000
-
-/*==================================================================
-  Defines for meIOStreamNewValues function
-  ================================================================*/
-
-#define ME_IO_STREAM_NEW_VALUES_NO_FLAGS			0x00000000
-
-/*==================================================================
-  Defines for meIOTimeToTicks function
-  ================================================================*/
-
-#define ME_IO_STREAM_TIME_TO_TICKS_NO_FLAGS			0x00000000
-
-/*==================================================================
-  Defines for module types
-  ================================================================*/
-
-#define ME_MODULE_TYPE_MULTISIG_NONE				0x00000000
-#define ME_MODULE_TYPE_MULTISIG_DIFF16_10V			0x00160001
-#define ME_MODULE_TYPE_MULTISIG_DIFF16_20V			0x00160002
-#define ME_MODULE_TYPE_MULTISIG_DIFF16_50V			0x00160003
-#define ME_MODULE_TYPE_MULTISIG_CURRENT16_0_20MA	0x00160004
-#define ME_MODULE_TYPE_MULTISIG_RTD8_PT100			0x00160005
-#define ME_MODULE_TYPE_MULTISIG_RTD8_PT500			0x00160006
-#define ME_MODULE_TYPE_MULTISIG_RTD8_PT1000			0x00160007
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_B			0x00160008
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_E			0x00160009
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_J			0x0016000A
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_K			0x0016000B
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_N			0x0016000C
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_R			0x0016000D
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_S			0x0016000E
-#define ME_MODULE_TYPE_MULTISIG_TE8_TYPE_T			0x0016000F
-#define ME_MODULE_TYPE_MULTISIG_TE8_TEMP_SENSOR		0x00160010
-
-/*==================================================================
-  Defines for meQuerySubdeviceCaps function
-  ================================================================*/
-
-#define ME_CAPS_NONE								0x00000000
-
-#define ME_CAPS_DIO_DIR_BIT							0x00000001
-#define ME_CAPS_DIO_DIR_BYTE						0x00000002
-#define ME_CAPS_DIO_DIR_WORD						0x00000004
-#define ME_CAPS_DIO_DIR_DWORD						0x00000008
-#define ME_CAPS_DIO_SINK_SOURCE						0x00000010
-#define ME_CAPS_DIO_BIT_PATTERN_IRQ					0x00000020
-#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_RISING		0x00000040
-#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_FALLING		0x00000080
-#define ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY			0x00000100
-#define ME_CAPS_DIO_OVER_TEMP_IRQ					0x00000200
-
-#define ME_CAPS_CTR_CLK_PREVIOUS					0x00000001
-#define ME_CAPS_CTR_CLK_INTERNAL_1MHZ				0x00000002
-#define ME_CAPS_CTR_CLK_INTERNAL_10MHZ				0x00000004
-#define ME_CAPS_CTR_CLK_EXTERNAL					0x00000008
-
-#define ME_CAPS_AI_TRIG_SYNCHRONOUS					0x00000001
-/// @note Backward compatibility for me1600 in old style.
-#define ME_CAPS_AI_TRIG_SIMULTANEOUS				ME_CAPS_AI_TRIG_SYNCHRONOUS
-#define ME_CAPS_AI_FIFO								0x00000002
-#define ME_CAPS_AI_FIFO_THRESHOLD					0x00000004
-
-#define ME_CAPS_AO_TRIG_SYNCHRONOUS					0x00000001
-/// @note Backward compatibility for me1600 in old style.
-#define ME_CAPS_AO_TRIG_SIMULTANEOUS				ME_CAPS_AO_TRIG_SYNCHRONOUS
-#define ME_CAPS_AO_FIFO								0x00000002
-#define ME_CAPS_AO_FIFO_THRESHOLD					0x00000004
-
-#define ME_CAPS_EXT_IRQ_EDGE_RISING					0x00000001
-#define ME_CAPS_EXT_IRQ_EDGE_FALLING				0x00000002
-#define ME_CAPS_EXT_IRQ_EDGE_ANY					0x00000004
-
-/*==================================================================
-  Defines for meQuerySubdeviceCapsArgs function
-  ================================================================*/
-
-#define ME_CAP_AI_FIFO_SIZE							0x001D0000
-#define ME_CAP_AI_BUFFER_SIZE						0x001D0001
-
-#define ME_CAP_AO_FIFO_SIZE							0x001F0000
-#define ME_CAP_AO_BUFFER_SIZE						0x001F0001
-
-#define ME_CAP_CTR_WIDTH							0x00200000
-
-/*==================================================================
-  Defines common to query functions
-  ================================================================*/
-
-#define ME_UNIT_INVALID								0x00000000
-#define ME_UNIT_VOLT								0x00170001
-#define ME_UNIT_AMPERE								0x00170002
-#define ME_UNIT_ANY									0x00170003
-
-#define ME_TYPE_INVALID								0x00000000
-#define ME_TYPE_AO									0x00180001
-#define ME_TYPE_AI									0x00180002
-#define ME_TYPE_DIO									0x00180003
-#define ME_TYPE_DO									0x00180004
-#define ME_TYPE_DI									0x00180005
-#define ME_TYPE_CTR									0x00180006
-#define ME_TYPE_EXT_IRQ								0x00180007
-
-#define ME_SUBTYPE_INVALID							0x00000000
-#define ME_SUBTYPE_SINGLE							0x00190001
-#define ME_SUBTYPE_STREAMING						0x00190002
-#define ME_SUBTYPE_CTR_8254							0x00190003
-#define ME_SUBTYPE_ANY								0x00190004
-
-#define ME_DEVICE_DRIVER_NAME_MAX_COUNT				64
-#define ME_DEVICE_NAME_MAX_COUNT					64
-
-#define ME_DEVICE_DESCRIPTION_MAX_COUNT				256
-
-#define ME_BUS_TYPE_INVALID							0x00000000
-#define ME_BUS_TYPE_PCI								0x001A0001
-#define ME_BUS_TYPE_USB								0x001A0002
-
-#define ME_PLUGGED_INVALID							0x00000000
-#define ME_PLUGGED_IN								0x001B0001
-#define ME_PLUGGED_OUT								0x001B0002
-
-#define ME_EXTENSION_TYPE_INVALID					0x00000000
-#define ME_EXTENSION_TYPE_NONE						0x001C0001
-#define ME_EXTENSION_TYPE_MUX32M					0x001C0002
-#define ME_EXTENSION_TYPE_DEMUX32					0x001C0003
-#define ME_EXTENSION_TYPE_MUX32S					0x001C0004
-
-#define ME_ACCESS_TYPE_INVALID						0x00000000
-#define ME_ACCESS_TYPE_LOCAL						0x001D0001
-#define ME_ACCESS_TYPE_REMOTE						0x001D0002
-
-/// @note Add by KG
-
-/*==================================================================
-  Defines for meUtilityPWM
-  ================================================================*/
-#define ME_PWM_START_CONNECT_INTERNAL				0x00200001
-
-/* Flags for SingleConfig channels configure */
-#define ME_SINGLE_CHANNEL_NOT_CONFIGURED			0x00
-#define ME_SINGLE_CHANNEL_CONFIGURED				0x01
-
-/* Define if configuration should be downloaded to driver */
-#define ME_CONFIG_LOAD_NO_FLAGS						0x0
-#define ME_CONFIG_LOAD_TO_DRIVER					0x1
-
-#endif
diff --git a/drivers/staging/meilhaus/medevice.c b/drivers/staging/meilhaus/medevice.c
deleted file mode 100644
index 75aaec0..0000000
--- a/drivers/staging/meilhaus/medevice.c
+++ /dev/null
@@ -1,1740 +0,0 @@
-/**
- * @file medevice.c
- *
- * @brief Meilhaus device base class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- */
-
-#include "mecommon.h"
-#include "meinternal.h"
-#include "medefines.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "medevice.h"
-
-#ifndef __KERNEL__
-#  define __KERNEL__
-#endif
-
-static int me_device_io_irq_start(struct me_device *device,
-				  struct file *filep,
-				  int subdevice,
-				  int channel,
-				  int irq_source,
-				  int irq_edge, int irq_arg, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_irq_start(s,
-						   filep,
-						   channel,
-						   irq_source,
-						   irq_edge, irq_arg, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_irq_wait(struct me_device *device,
-				 struct file *filep,
-				 int subdevice,
-				 int channel,
-				 int *irq_count,
-				 int *value, int time_out, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_irq_wait(s,
-						  filep,
-						  channel,
-						  irq_count,
-						  value, time_out, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_irq_stop(struct me_device *device,
-				 struct file *filep,
-				 int subdevice, int channel, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_irq_stop(s, filep, channel, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_reset_device(struct me_device *device,
-				     struct file *filep, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-	int i, n;
-
-	PDEBUG("executed.\n");
-
-	/* Get the number of subdevices. */
-	n = me_slist_get_number_subdevices(&device->slist);
-
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-
-	/* Reset every subdevice in list. */
-	for (i = 0; i < n; i++) {
-		s = me_slist_get_subdevice(&device->slist, i);
-		err = s->me_subdevice_io_reset_subdevice(s, filep, flags);
-
-		if (err) {
-			PERROR("Cannot reset subdevice.\n");
-			break;
-		}
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_reset_subdevice(struct me_device *device,
-					struct file *filep,
-					int subdevice, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_reset_subdevice(s, filep, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_single_config(struct me_device *device,
-				      struct file *filep,
-				      int subdevice,
-				      int channel,
-				      int single_config,
-				      int ref,
-				      int trig_chan,
-				      int trig_type, int trig_edge, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_single_config(s,
-						       filep,
-						       channel,
-						       single_config,
-						       ref,
-						       trig_chan,
-						       trig_type,
-						       trig_edge, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_single_read(struct me_device *device,
-				    struct file *filep,
-				    int subdevice,
-				    int channel,
-				    int *value, int time_out, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_single_read(s,
-						     filep,
-						     channel,
-						     value, time_out, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_single_write(struct me_device *device,
-				     struct file *filep,
-				     int subdevice,
-				     int channel,
-				     int value, int time_out, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_single_write(s,
-						      filep,
-						      channel,
-						      value, time_out, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_stream_config(struct me_device *device,
-				      struct file *filep,
-				      int subdevice,
-				      meIOStreamConfig_t *config_list,
-				      int count,
-				      meIOStreamTrigger_t *trigger,
-				      int fifo_irq_threshold, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_stream_config(s,
-						       filep,
-						       config_list,
-						       count,
-						       trigger,
-						       fifo_irq_threshold,
-						       flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_stream_new_values(struct me_device *device,
-					  struct file *filep,
-					  int subdevice,
-					  int time_out, int *count, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_stream_new_values(s,
-							   filep,
-							   time_out,
-							   count, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_stream_read(struct me_device *device,
-				    struct file *filep,
-				    int subdevice,
-				    int read_mode,
-				    int *values, int *count, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_stream_read(s,
-						     filep,
-						     read_mode,
-						     values, count, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_stream_start(struct me_device *device,
-				     struct file *filep,
-				     int subdevice,
-				     int start_mode, int time_out, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_stream_start(s,
-						      filep,
-						      start_mode,
-						      time_out, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_stream_status(struct me_device *device,
-				      struct file *filep,
-				      int subdevice,
-				      int wait,
-				      int *status, int *count, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_stream_status(s,
-						       filep,
-						       wait,
-						       status, count, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_stream_stop(struct me_device *device,
-				    struct file *filep,
-				    int subdevice, int stop_mode, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_stream_stop(s,
-						     filep, stop_mode, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_io_stream_write(struct me_device *device,
-				     struct file *filep,
-				     int subdevice,
-				     int write_mode,
-				     int *values, int *count, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_io_stream_write(s,
-						      filep,
-						      write_mode,
-						      values, count, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_lock_device(struct me_device *device,
-				 struct file *filep, int lock, int flags)
-{
-	PDEBUG("executed.\n");
-
-	return me_dlock_lock(&device->dlock,
-			     filep, lock, flags, &device->slist);
-}
-
-static int me_device_lock_subdevice(struct me_device *device,
-				    struct file *filep,
-				    int subdevice, int lock, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Enter device.
-	err = me_dlock_enter(&device->dlock, filep);
-
-	if (err) {
-		PERROR("Cannot enter device.\n");
-		return err;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_lock_subdevice(s, filep, lock, flags);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	// Exit device.
-	me_dlock_exit(&device->dlock, filep);
-
-	return err;
-}
-
-static int me_device_query_description_device(struct me_device *device,
-					      char **description)
-{
-	PDEBUG("executed.\n");
-	*description = device->device_description;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me_device_query_info_device(struct me_device *device,
-				       int *vendor_id,
-				       int *device_id,
-				       int *serial_no,
-				       int *bus_type,
-				       int *bus_no,
-				       int *dev_no, int *func_no, int *plugged)
-{
-	PDEBUG("executed.\n");
-
-	if (device->bus_type == ME_BUS_TYPE_PCI) {
-		*vendor_id = device->info.pci.vendor_id;
-		*device_id = device->info.pci.device_id;
-		*serial_no = device->info.pci.serial_no;
-		*bus_type = ME_BUS_TYPE_PCI;
-		*bus_no = device->info.pci.pci_bus_no;
-		*dev_no = device->info.pci.pci_dev_no;
-		*func_no = device->info.pci.pci_func_no;
-		*plugged = ME_PLUGGED_IN;
-	} else {
-		*plugged = ME_PLUGGED_OUT;
-	}
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me_device_query_name_device(struct me_device *device, char **name)
-{
-	PDEBUG("executed.\n");
-	*name = device->device_name;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me_device_query_name_device_driver(struct me_device *device,
-					      char **name)
-{
-	PDEBUG("executed.\n");
-	*name = device->driver_name;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me_device_query_number_subdevices(struct me_device *device,
-					     int *number)
-{
-	PDEBUG("executed.\n");
-	return me_slist_query_number_subdevices(&device->slist, number);
-}
-
-static int me_device_query_number_channels(struct me_device *device,
-					   int subdevice, int *number)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_number_channels(s, number);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_number_ranges(struct me_device *device,
-					 int subdevice, int unit, int *count)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_number_ranges(s, unit, count);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_range_by_min_max(struct me_device *device,
-					    int subdevice,
-					    int unit,
-					    int *min,
-					    int *max, int *maxdata, int *range)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_range_by_min_max(s,
-							     unit,
-							     min,
-							     max,
-							     maxdata, range);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_range_info(struct me_device *device,
-				      int subdevice,
-				      int range,
-				      int *unit,
-				      int *min, int *max, int *maxdata)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_range_info(s,
-						       range,
-						       unit, min, max, maxdata);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_subdevice_by_type(struct me_device *device,
-					     int start_subdevice,
-					     int type,
-					     int subtype, int *subdevice)
-{
-	PDEBUG("executed.\n");
-
-	return me_slist_get_subdevice_by_type(&device->slist,
-					      start_subdevice,
-					      type, subtype, subdevice);
-}
-
-static int me_device_query_subdevice_type(struct me_device *device,
-					  int subdevice,
-					  int *type, int *subtype)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_subdevice_type(s, type, subtype);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_subdevice_caps(struct me_device *device,
-					  int subdevice, int *caps)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_subdevice_caps(s, caps);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_subdevice_caps_args(struct me_device *device,
-					       int subdevice,
-					       int cap, int *args, int count)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_subdevice_caps_args(s,
-								cap,
-								args, count);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_timer(struct me_device *device,
-				 int subdevice,
-				 int timer,
-				 int *base_frequency,
-				 uint64_t *min_ticks, uint64_t *max_ticks)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_subdevice_t *s;
-
-	PDEBUG("executed.\n");
-
-	// Check subdevice index.
-
-	if (subdevice >= me_slist_get_number_subdevices(&device->slist)) {
-		PERROR("Invalid subdevice.\n");
-		return ME_ERRNO_INVALID_SUBDEVICE;
-	}
-	// Get subdevice instance.
-	s = me_slist_get_subdevice(&device->slist, subdevice);
-
-	if (s) {
-		// Call subdevice method.
-		err = s->me_subdevice_query_timer(s,
-						  timer,
-						  base_frequency,
-						  min_ticks, max_ticks);
-	} else {
-		// Something really bad happened.
-		PERROR("Cannot get subdevice instance.\n");
-		err = ME_ERRNO_INTERNAL;
-	}
-
-	return err;
-}
-
-static int me_device_query_version_device_driver(struct me_device *device,
-						 int *version)
-/** @todo Versions shold be read from driver. I must overwrite this function in each module. Here should be returned an error!
-*/
-{
-	PDEBUG("executed.\n");
-	*version = ME_VERSION_DRIVER;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me_device_config_load(struct me_device *device, struct file *filep,
-				 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)
-{
-	PDEBUG("executed.\n");
-	me_device_deinit(me_device);
-	kfree(me_device);
-}
-
-/* //me_device_usb_init
-int me_device_usb_init(me_device_t *me_device, struct usb_interface *interface)
-{
-	PDEBUG("executed.\n");
-	return -1;
-}
-*/
-
-static int get_device_descriptions(uint16_t device_id,
-				   char **device_name,
-				   char **device_description,
-				   char **driver_name)
-/** @todo This is wrong concept! Static table has too strong limitations!
-* 'device_name' and 'driver_name' should be calculated from 'device_id'
-* 'device_description' should be read from device or moved to user space and handled by library!
-*/
-{
-	PDEBUG("executed.\n");
-
-	switch (device_id) {
-	case PCI_DEVICE_ID_MEILHAUS_ME1000:
-	case PCI_DEVICE_ID_MEILHAUS_ME1000_A:
-	case PCI_DEVICE_ID_MEILHAUS_ME1000_B:
-		*device_name = ME1000_NAME_DEVICE_ME1000;
-		*device_description = ME1000_DESCRIPTION_DEVICE_ME1000;
-		*driver_name = ME1000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1400:
-		*device_name = ME1400_NAME_DEVICE_ME1400;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140A:
-		*device_name = ME1400_NAME_DEVICE_ME1400A;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400A;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140B:
-		*device_name = ME1400_NAME_DEVICE_ME1400B;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400B;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-		*device_name = ME1400_NAME_DEVICE_ME1400E;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400E;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14EA:
-		*device_name = ME1400_NAME_DEVICE_ME1400EA;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400EA;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14EB:
-		*device_name = ME1400_NAME_DEVICE_ME1400EB;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400EB;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-		*device_name = ME1400_NAME_DEVICE_ME1400C;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400C;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		*device_name = ME1400_NAME_DEVICE_ME1400D;
-		*device_description = ME1400_DESCRIPTION_DEVICE_ME1400D;
-		*driver_name = ME1400_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_4U:
-		*device_name = ME1600_NAME_DEVICE_ME16004U;
-		*device_description = ME1600_DESCRIPTION_DEVICE_ME16004U;
-		*driver_name = ME1600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_8U:
-		*device_name = ME1600_NAME_DEVICE_ME16008U;
-		*device_description = ME1600_DESCRIPTION_DEVICE_ME16008U;
-		*driver_name = ME1600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_12U:
-		*device_name = ME1600_NAME_DEVICE_ME160012U;
-		*device_description = ME1600_DESCRIPTION_DEVICE_ME160012U;
-		*driver_name = ME1600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_16U:
-		*device_name = ME1600_NAME_DEVICE_ME160016U;
-		*device_description = ME1600_DESCRIPTION_DEVICE_ME160016U;
-		*driver_name = ME1600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I:
-		*device_name = ME1600_NAME_DEVICE_ME160016U8I;
-		*device_description = ME1600_DESCRIPTION_DEVICE_ME160016U8I;
-		*driver_name = ME1600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4610:
-		*device_name = ME4600_NAME_DEVICE_ME4610;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4610;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4650:
-		*device_name = ME4600_NAME_DEVICE_ME4650;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4650;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660:
-		*device_name = ME4600_NAME_DEVICE_ME4660;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4660;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660I:
-		*device_name = ME4600_NAME_DEVICE_ME4660I;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4660I;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660S:
-		*device_name = ME4600_NAME_DEVICE_ME4660S;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4660S;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
-		*device_name = ME4600_NAME_DEVICE_ME4660IS;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4660IS;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670:
-		*device_name = ME4600_NAME_DEVICE_ME4670;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4670;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670I:
-		*device_name = ME4600_NAME_DEVICE_ME4670I;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4670I;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670S:
-		*device_name = ME4600_NAME_DEVICE_ME4670S;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4670S;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
-		*device_name = ME4600_NAME_DEVICE_ME4670IS;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4670IS;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680:
-		*device_name = ME4600_NAME_DEVICE_ME4680;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4680;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680I:
-		*device_name = ME4600_NAME_DEVICE_ME4680I;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4680I;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680S:
-		*device_name = ME4600_NAME_DEVICE_ME4680S;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4680S;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
-		*device_name = ME4600_NAME_DEVICE_ME4680IS;
-		*device_description = ME4600_DESCRIPTION_DEVICE_ME4680IS;
-		*driver_name = ME4600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6004:
-		*device_name = ME6000_NAME_DEVICE_ME60004;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME60004;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6008:
-		*device_name = ME6000_NAME_DEVICE_ME60008;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME60008;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME600F:
-		*device_name = ME6000_NAME_DEVICE_ME600016;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME600016;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6014:
-		*device_name = ME6000_NAME_DEVICE_ME6000I4;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6018:
-		*device_name = ME6000_NAME_DEVICE_ME6000I8;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME601F:
-		*device_name = ME6000_NAME_DEVICE_ME6000I16;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6034:
-		*device_name = ME6000_NAME_DEVICE_ME6000ISLE4;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6038:
-		*device_name = ME6000_NAME_DEVICE_ME6000ISLE8;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME603F:
-		*device_name = ME6000_NAME_DEVICE_ME6000ISLE16;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6104:
-		*device_name = ME6000_NAME_DEVICE_ME61004;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME61004;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6108:
-		*device_name = ME6000_NAME_DEVICE_ME61008;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME61008;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME610F:
-		*device_name = ME6000_NAME_DEVICE_ME610016;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME610016;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6114:
-		*device_name = ME6000_NAME_DEVICE_ME6100I4;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6118:
-		*device_name = ME6000_NAME_DEVICE_ME6100I8;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME611F:
-		*device_name = ME6000_NAME_DEVICE_ME6100I16;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6134:
-		*device_name = ME6000_NAME_DEVICE_ME6100ISLE4;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6138:
-		*device_name = ME6000_NAME_DEVICE_ME6100ISLE8;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME613F:
-		*device_name = ME6000_NAME_DEVICE_ME6100ISLE16;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6044:
-		*device_name = ME6000_NAME_DEVICE_ME60004DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME60004DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6048:
-		*device_name = ME6000_NAME_DEVICE_ME60008DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME60008DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME604F:
-		*device_name = ME6000_NAME_DEVICE_ME600016DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME600016DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6054:
-		*device_name = ME6000_NAME_DEVICE_ME6000I4DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000I4DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6058:
-		*device_name = ME6000_NAME_DEVICE_ME6000I8DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000I8DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME605F:
-		*device_name = ME6000_NAME_DEVICE_ME6000I16DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000I16DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6074:
-		*device_name = ME6000_NAME_DEVICE_ME6000ISLE4DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6078:
-		*device_name = ME6000_NAME_DEVICE_ME6000ISLE8DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME607F:
-		*device_name = ME6000_NAME_DEVICE_ME6000ISLE16DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6144:
-		*device_name = ME6000_NAME_DEVICE_ME61004DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME61004DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6148:
-		*device_name = ME6000_NAME_DEVICE_ME61008DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME61008DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME614F:
-		*device_name = ME6000_NAME_DEVICE_ME610016DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME610016DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6154:
-		*device_name = ME6000_NAME_DEVICE_ME6100I4DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100I4DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6158:
-		*device_name = ME6000_NAME_DEVICE_ME6100I8DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100I8DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME615F:
-		*device_name = ME6000_NAME_DEVICE_ME6100I16DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100I16DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6174:
-		*device_name = ME6000_NAME_DEVICE_ME6100ISLE4DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6178:
-		*device_name = ME6000_NAME_DEVICE_ME6100ISLE8DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME617F:
-		*device_name = ME6000_NAME_DEVICE_ME6100ISLE16DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6259:
-		*device_name = ME6000_NAME_DEVICE_ME6200I9DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6200I9DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6359:
-		*device_name = ME6000_NAME_DEVICE_ME6300I9DIO;
-		*device_description = ME6000_DESCRIPTION_DEVICE_ME6300I9DIO;
-		*driver_name = ME6000_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0630:
-		*device_name = ME0600_NAME_DEVICE_ME0630;
-		*device_description = ME0600_DESCRIPTION_DEVICE_ME0630;
-		*driver_name = ME0600_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
-		*device_name = ME8100_NAME_DEVICE_ME8100A;
-		*device_description = ME8100_DESCRIPTION_DEVICE_ME8100A;
-		*driver_name = ME8100_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
-		*device_name = ME8100_NAME_DEVICE_ME8100B;
-		*device_description = ME8100_DESCRIPTION_DEVICE_ME8100B;
-		*driver_name = ME8100_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8200_A:
-		*device_name = ME8200_NAME_DEVICE_ME8200A;
-		*device_description = ME8200_DESCRIPTION_DEVICE_ME8200A;
-		*driver_name = ME8200_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8200_B:
-		*device_name = ME8200_NAME_DEVICE_ME8200B;
-		*device_description = ME8200_DESCRIPTION_DEVICE_ME8200B;
-		*driver_name = ME8200_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0940:
-		*device_name = ME0900_NAME_DEVICE_ME0940;
-		*device_description = ME0900_DESCRIPTION_DEVICE_ME0940;
-		*driver_name = ME0900_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0950:
-		*device_name = ME0900_NAME_DEVICE_ME0950;
-		*device_description = ME0900_DESCRIPTION_DEVICE_ME0950;
-		*driver_name = ME0900_NAME_DRIVER;
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0960:
-		*device_name = ME0900_NAME_DEVICE_ME0960;
-		*device_description = ME0900_DESCRIPTION_DEVICE_ME0960;
-		*driver_name = ME0900_NAME_DRIVER;
-		break;
-/*
-		case USB_DEVICE_ID_MEPHISTO_S1:
-			*device_name = MEPHISTO_S1_NAME_DEVICE;
-			*device_description = MEPHISTO_S1_DESCRIPTION_DEVICE;
-			*driver_name = MEPHISTO_S1_NAME_DRIVER;
-			break;
-*/
-	default:
-		*device_name = EMPTY_NAME_DEVICE;
-		*device_description = EMPTY_DESCRIPTION_DEVICE;
-		*driver_name = EMPTY_NAME_DRIVER;
-
-		PERROR("Invalid device id.\n");
-
-		return 1;
-	}
-
-	return 0;
-}
-
-int me_device_pci_init(me_device_t *me_device, struct pci_dev *pci_device)
-{
-	int err;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Initialize device list head.
-	INIT_LIST_HEAD(&me_device->list);
-
-	// Initialize device description strings.
-	err = get_device_descriptions(pci_device->device,
-				      &me_device->device_name,
-				      &me_device->device_description,
-				      &me_device->driver_name);
-
-	if (err) {
-		PERROR("Cannot initialize device description strings.\n");
-		return 1;
-	}
-	// Enable the pci device.
-	err = pci_enable_device(pci_device);
-
-	if (err < 0) {
-		PERROR("Cannot enable PCI device.\n");
-		return 1;
-	}
-	// Request the PCI register regions.
-	err = pci_request_regions(pci_device, me_device->device_name);
-
-	if (err < 0) {
-		PERROR("Cannot request PCI regions.\n");
-		goto ERROR_0;
-	}
-	// The bus carrying the device is a PCI bus.
-	me_device->bus_type = ME_BUS_TYPE_PCI;
-
-	// Store the PCI information for later usage.
-	me_device->info.pci.pci_device = pci_device;
-
-	// Get PCI register bases and sizes.
-	for (i = 0; i < 6; i++) {
-		me_device->info.pci.reg_bases[i] =
-		    pci_resource_start(pci_device, i);
-		me_device->info.pci.reg_sizes[i] =
-		    pci_resource_len(pci_device, i);
-	}
-
-	// Get the PCI location.
-	me_device->info.pci.pci_bus_no = pci_device->bus->number;
-	me_device->info.pci.pci_dev_no = PCI_SLOT(pci_device->devfn);
-	me_device->info.pci.pci_func_no = PCI_FUNC(pci_device->devfn);
-
-	// Get Meilhaus specific device information.
-	me_device->info.pci.vendor_id = pci_device->vendor;
-	me_device->info.pci.device_id = pci_device->device;
-	pci_read_config_byte(pci_device, 0x08,
-			     &me_device->info.pci.hw_revision);
-	pci_read_config_dword(pci_device, 0x2C, &me_device->info.pci.serial_no);
-
-	// Get the interrupt request number.
-	me_device->irq = pci_device->irq;
-
-	// Initialize device lock instance.
-	err = me_dlock_init(&me_device->dlock);
-
-	if (err) {
-		PERROR("Cannot initialize device lock instance.\n");
-		goto ERROR_1;
-	}
-	// Initialize subdevice list instance.
-	me_slist_init(&me_device->slist);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice list instance.\n");
-		goto ERROR_2;
-	}
-	// Initialize method pointers.
-	me_device->me_device_io_irq_start = me_device_io_irq_start;
-	me_device->me_device_io_irq_wait = me_device_io_irq_wait;
-	me_device->me_device_io_irq_stop = me_device_io_irq_stop;
-	me_device->me_device_io_reset_device = me_device_io_reset_device;
-	me_device->me_device_io_reset_subdevice = me_device_io_reset_subdevice;
-	me_device->me_device_io_single_config = me_device_io_single_config;
-	me_device->me_device_io_single_read = me_device_io_single_read;
-	me_device->me_device_io_single_write = me_device_io_single_write;
-	me_device->me_device_io_stream_config = me_device_io_stream_config;
-	me_device->me_device_io_stream_new_values =
-	    me_device_io_stream_new_values;
-	me_device->me_device_io_stream_read = me_device_io_stream_read;
-	me_device->me_device_io_stream_start = me_device_io_stream_start;
-	me_device->me_device_io_stream_status = me_device_io_stream_status;
-	me_device->me_device_io_stream_stop = me_device_io_stream_stop;
-	me_device->me_device_io_stream_write = me_device_io_stream_write;
-	me_device->me_device_lock_device = me_device_lock_device;
-	me_device->me_device_lock_subdevice = me_device_lock_subdevice;
-	me_device->me_device_query_description_device =
-	    me_device_query_description_device;
-	me_device->me_device_query_info_device = me_device_query_info_device;
-	me_device->me_device_query_name_device = me_device_query_name_device;
-	me_device->me_device_query_name_device_driver =
-	    me_device_query_name_device_driver;
-	me_device->me_device_query_number_subdevices =
-	    me_device_query_number_subdevices;
-	me_device->me_device_query_number_channels =
-	    me_device_query_number_channels;
-	me_device->me_device_query_number_ranges =
-	    me_device_query_number_ranges;
-	me_device->me_device_query_range_by_min_max =
-	    me_device_query_range_by_min_max;
-	me_device->me_device_query_range_info = me_device_query_range_info;
-	me_device->me_device_query_subdevice_by_type =
-	    me_device_query_subdevice_by_type;
-	me_device->me_device_query_subdevice_type =
-	    me_device_query_subdevice_type;
-	me_device->me_device_query_subdevice_caps =
-	    me_device_query_subdevice_caps;
-	me_device->me_device_query_subdevice_caps_args =
-	    me_device_query_subdevice_caps_args;
-	me_device->me_device_query_timer = me_device_query_timer;
-	me_device->me_device_query_version_device_driver =
-	    me_device_query_version_device_driver;
-	me_device->me_device_config_load = me_device_config_load;
-	me_device->me_device_destructor = me_device_destructor;
-
-	return 0;
-
-      ERROR_0:
-	me_dlock_deinit(&me_device->dlock);
-
-      ERROR_1:
-	pci_release_regions(pci_device);
-
-      ERROR_2:
-	pci_disable_device(pci_device);
-
-	return 1;
-}
-
-void me_device_deinit(me_device_t *me_device)
-{
-	PDEBUG("executed.\n");
-
-	me_slist_deinit(&me_device->slist);
-	me_dlock_deinit(&me_device->dlock);
-
-	if (me_device->bus_type == ME_BUS_TYPE_PCI) {
-		pci_release_regions(me_device->info.pci.pci_device);
-		pci_disable_device(me_device->info.pci.pci_device);
-	}
-/*
-	else
-	{
-		// Must be an USB device.
-	}
-*/
-}
diff --git a/drivers/staging/meilhaus/medevice.h b/drivers/staging/meilhaus/medevice.h
deleted file mode 100644
index 25da828..0000000
--- a/drivers/staging/meilhaus/medevice.h
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : medevice.h
- * Author      : GG (Guenter Gebhardt)  <support@meilhaus.de>
- */
-
-#ifndef _MEDEVICE_H_
-#define _MEDEVICE_H_
-
-#ifndef KBUILD_MODNAME
-#  define KBUILD_MODNAME KBUILD_STR(memain)
-#endif
-
-#include <linux/pci.h>
-//#include <linux/usb.h>
-#include <linux/fs.h>
-#include <linux/spinlock.h>
-
-#include "metypes.h"
-#include "meslist.h"
-#include "medlock.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Defines a pointer type to a PCI constructor function.
- */
-typedef struct me_device *(*me_pci_constructor_t) (struct pci_dev *);
-
-/**
- * @brief Defines a pointer type to a ME-4000 PCI constructor function.
- */
-#ifdef BOSCH
-typedef struct me_device *(*me_bosch_constructor_t) (struct pci_dev *,
-						     int me_bosch_fw);
-#endif
-
-/**
- * @brief Defines a pointer type to a USB constructor function.
- */
-//typedef struct me_device *(*me_usb_constructor_t)(struct usb_interface *);
-
-/**
- * @brief Defines a pointer type to the dummy constructor function.
- */
-typedef struct me_device *(*me_dummy_constructor_t) (unsigned short vendor_id,
-						     unsigned short device_id,
-						     unsigned int serial_no,
-						     int bus_type,
-						     int bus_no,
-						     int dev_no, int func_no);
-
-//extern me_usb_constructor_t mephisto_s1_constructor __attribute__ ((weak));
-
-/**
- * @brief Holds the PCI device information.
- */
-typedef struct me_pci_info {
-	struct pci_dev *pci_device;			/**< Kernel PCI device structure. */
-	uint32_t reg_bases[6];				/**< The base adresses of the PCI bars. */
-	uint32_t reg_sizes[6];				/**< The sizes of the PCI bars. */
-
-	uint32_t pci_bus_no;				/**< PCI bus number. */
-	uint32_t pci_dev_no;				/**< PCI device number. */
-	uint32_t pci_func_no;				/**< PCI function number. */
-
-	uint16_t vendor_id;					/**< Meilhaus PCI vendor id. */
-	uint16_t device_id;					/**< Meilhaus device id. */
-	uint8_t hw_revision;				/**< Hardware revision of the device. */
-	uint32_t serial_no;					/**< Serial number of the device. */
-} me_pci_info_t;
-
-/**
- * @brief Holds the USB device information.
- */
-//typedef struct me_usb_info {
-//} me_usb_info_t;
-
-/**
- * @brief The Meilhaus device base class structure.
- */
-typedef struct me_device {
-	/* Attributes */
-	struct list_head list;				/**< Enables the device to be added to a dynamic list. */
-//      int magic;                                                      /**< The magic number of the structure. */
-
-	int bus_type;						/**< The descriminator for the union. */
-	union {
-		me_pci_info_t pci;				/**< PCI specific device information. */
-//              me_usb_info_t usb;                              /**< USB specific device information. */
-	} info;								/**< Holds the device information. */
-
-	int irq;							/**< The irq assigned to this device. */
-
-	me_dlock_t dlock;					/**< The device locking structure. */
-	me_slist_t slist;					/**< The container holding all subdevices belonging to this device. */
-
-	char *device_name;					/**< The name of the Meilhaus device. */
-	char *device_description;			/**< The description of the Meilhaus device. */
-	char *driver_name;					/**< The name of the device driver module supporting the device family. */
-
-	/* Methods */
-	int (*me_device_io_irq_start) (struct me_device * device,
-				       struct file * filep,
-				       int subdevice,
-				       int channel,
-				       int irq_source,
-				       int irq_edge, int irq_arg, int flags);
-
-	int (*me_device_io_irq_wait) (struct me_device * device,
-				      struct file * filep,
-				      int subdevice,
-				      int channel,
-				      int *irq_count,
-				      int *value, int time_out, int flags);
-
-	int (*me_device_io_irq_stop) (struct me_device * device,
-				      struct file * filep,
-				      int subdevice, int channel, int flags);
-
-	int (*me_device_io_reset_device) (struct me_device * device,
-					  struct file * filep, int flags);
-
-	int (*me_device_io_reset_subdevice) (struct me_device * device,
-					     struct file * filep,
-					     int subdevice, int flags);
-
-	int (*me_device_io_single_config) (struct me_device * device,
-					   struct file * filep,
-					   int subdevice,
-					   int channel,
-					   int single_config,
-					   int ref,
-					   int trig_chan,
-					   int trig_type,
-					   int trig_edge, int flags);
-
-	int (*me_device_io_single_read) (struct me_device * device,
-					 struct file * filep,
-					 int subdevice,
-					 int channel,
-					 int *value, int time_out, int flags);
-
-	int (*me_device_io_single_write) (struct me_device * device,
-					  struct file * filep,
-					  int subdevice,
-					  int channel,
-					  int value, int time_out, int flags);
-
-	int (*me_device_io_stream_config) (struct me_device * device,
-					   struct file * filep,
-					   int subdevice,
-					   meIOStreamConfig_t * config_list,
-					   int count,
-					   meIOStreamTrigger_t * trigger,
-					   int fifo_irq_threshold, int flags);
-
-	int (*me_device_io_stream_new_values) (struct me_device * device,
-					       struct file * filep,
-					       int subdevice,
-					       int time_out,
-					       int *count, int flags);
-
-	int (*me_device_io_stream_read) (struct me_device * device,
-					 struct file * filep,
-					 int subdevice,
-					 int read_mode,
-					 int *values, int *count, int flags);
-
-	int (*me_device_io_stream_start) (struct me_device * device,
-					  struct file * filep,
-					  int subdevice,
-					  int start_mode,
-					  int time_out, int flags);
-
-	int (*me_device_io_stream_status) (struct me_device * device,
-					   struct file * filep,
-					   int subdevice,
-					   int wait,
-					   int *status, int *count, int flags);
-
-	int (*me_device_io_stream_stop) (struct me_device * device,
-					 struct file * filep,
-					 int subdevice,
-					 int stop_mode, int flags);
-
-	int (*me_device_io_stream_write) (struct me_device * device,
-					  struct file * filep,
-					  int subdevice,
-					  int write_mode,
-					  int *values, int *count, int flags);
-
-	int (*me_device_lock_device) (struct me_device * device,
-				      struct file * filep, int lock, int flags);
-
-	int (*me_device_lock_subdevice) (struct me_device * device,
-					 struct file * filep,
-					 int subdevice, int lock, int flags);
-
-	int (*me_device_query_description_device) (struct me_device * device,
-						   char **description);
-
-	int (*me_device_query_info_device) (struct me_device * device,
-					    int *vendor_id,
-					    int *device_id,
-					    int *serial_no,
-					    int *bus_type,
-					    int *bus_no,
-					    int *dev_no,
-					    int *func_no, int *plugged);
-
-	int (*me_device_query_name_device) (struct me_device * device,
-					    char **name);
-
-	int (*me_device_query_name_device_driver) (struct me_device * device,
-						   char **name);
-
-	int (*me_device_query_number_subdevices) (struct me_device * device,
-						  int *number);
-
-	int (*me_device_query_number_channels) (struct me_device * device,
-						int subdevice, int *number);
-
-	int (*me_device_query_number_ranges) (struct me_device * device,
-					      int subdevice,
-					      int unit, int *count);
-
-	int (*me_device_query_range_by_min_max) (struct me_device * device,
-						 int subdevice,
-						 int unit,
-						 int *min,
-						 int *max,
-						 int *maxdata, int *range);
-
-	int (*me_device_query_range_info) (struct me_device * device,
-					   int subdevice,
-					   int range,
-					   int *unit,
-					   int *min, int *max, int *maxdata);
-
-	int (*me_device_query_subdevice_by_type) (struct me_device * device,
-						  int start_subdevice,
-						  int type,
-						  int subtype, int *subdevice);
-
-	int (*me_device_query_subdevice_type) (struct me_device * device,
-					       int subdevice,
-					       int *type, int *subtype);
-
-	int (*me_device_query_subdevice_caps) (struct me_device * device,
-					       int subdevice, int *caps);
-
-	int (*me_device_query_subdevice_caps_args) (struct me_device * device,
-						    int subdevice,
-						    int cap,
-						    int *args, int count);
-
-	int (*me_device_query_timer) (struct me_device * device,
-				      int subdevice,
-				      int timer,
-				      int *base_frequency,
-				      uint64_t * min_ticks,
-				      uint64_t * max_ticks);
-
-	int (*me_device_query_version_device_driver) (struct me_device * device,
-						      int *version);
-
-	int (*me_device_config_load) (struct me_device * device,
-				      struct file * filep,
-				      me_cfg_device_entry_t * config);
-
-	void (*me_device_destructor) (struct me_device * device);
-} me_device_t;
-
-/**
- * @brief Initializes a PCI device base class structure.
- *
- * @param pci_device The PCI device context as handed over by kernel.
- *
- * @return 0 on success.
- */
-int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device);
-
-/**
- * @brief Initializes a USB device base class structure.
- *
- * @param usb_interface The USB device interface as handed over by kernel.
- *
- * @return 0 on success.
- */
-//int me_device_usb_init(me_device_t *me_device, struct usb_interface *interface);
-
-/**
-  * @brief Deinitializes a device base class structure and frees any previously
-  * requested resources related with this structure. It also frees any subdevice
-  * instance hold by the subdevice list.
-  *
-  * @param me_device The device class to deinitialize.
-  */
-void me_device_deinit(me_device_t * me_device);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/medlist.c b/drivers/staging/meilhaus/medlist.c
deleted file mode 100644
index b6a4065..0000000
--- a/drivers/staging/meilhaus/medlist.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file me_dlist.c
- *
- * @brief Implements the device list class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- */
-
-#include "meerror.h"
-#include "medefines.h"
-
-#include "medlist.h"
-#include "medebug.h"
-
-int me_dlist_query_number_devices(struct me_dlist *dlist, int *number)
-{
-	PDEBUG_LOCKS("called.\n");
-	*number = dlist->n;
-	return ME_ERRNO_SUCCESS;
-}
-
-unsigned int me_dlist_get_number_devices(struct me_dlist *dlist)
-{
-	PDEBUG_LOCKS("called.\n");
-	return dlist->n;
-}
-
-me_device_t *me_dlist_get_device(struct me_dlist * dlist, unsigned int index)
-{
-
-	struct list_head *pos;
-	me_device_t *device = NULL;
-	unsigned int i = 0;
-
-	PDEBUG_LOCKS("called.\n");
-
-	if (index >= dlist->n) {
-		PERROR("Index out of range.\n");
-		return NULL;
-	}
-
-	list_for_each(pos, &dlist->head) {
-		if (i == index) {
-			device = list_entry(pos, me_device_t, list);
-			break;
-		}
-
-		++i;
-	}
-
-	return device;
-}
-
-void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t *device)
-{
-	PDEBUG_LOCKS("called.\n");
-
-	list_add_tail(&device->list, &dlist->head);
-	++dlist->n;
-}
-
-me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist)
-{
-
-	struct list_head *last;
-	me_device_t *device;
-
-	PDEBUG_LOCKS("called.\n");
-
-	if (list_empty(&dlist->head))
-		return NULL;
-
-	last = dlist->head.prev;
-
-	device = list_entry(last, me_device_t, list);
-
-	list_del(last);
-
-	--dlist->n;
-
-	return device;
-}
-
-int me_dlist_init(me_dlist_t *dlist)
-{
-	PDEBUG_LOCKS("called.\n");
-
-	INIT_LIST_HEAD(&dlist->head);
-	dlist->n = 0;
-	return 0;
-}
-
-void me_dlist_deinit(me_dlist_t *dlist)
-{
-
-	struct list_head *s;
-	me_device_t *device;
-
-	PDEBUG_LOCKS("called.\n");
-
-	while (!list_empty(&dlist->head)) {
-		s = dlist->head.next;
-		list_del(s);
-		device = list_entry(s, me_device_t, list);
-		device->me_device_destructor(device);
-	}
-
-	dlist->n = 0;
-}
diff --git a/drivers/staging/meilhaus/medlist.h b/drivers/staging/meilhaus/medlist.h
deleted file mode 100644
index 091c11e..0000000
--- a/drivers/staging/meilhaus/medlist.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * @file me_dlist.h
- *
- * @brief Provides the device list class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME_DLIST_H_
-#define _ME_DLIST_H_
-
-#include <linux/list.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The device list container.
- */
-typedef struct me_dlist {
-	struct list_head head;		/**< The head of the internal list. */
-	unsigned int n;			/**< The number of devices in the list. */
-} me_dlist_t;
-
-/**
- * @brief Queries the number of devices currently inside the list.
- *
- * @param dlist The device list to query.
- * @param[out] number The number of devices.
- *
- * @return ME-iDS error code.
- */
-int me_dlist_query_number_devices(struct me_dlist *dlist, int *number);
-
-/**
- * @brief Returns the number of devices currently inside the list.
- *
- * @param dlist The device list to query.
- *
- * @return The number of devices in the list.
- */
-unsigned int me_dlist_get_number_devices(struct me_dlist *dlist);
-
-/**
- * @brief Get a device by index.
- *
- * @param dlist The device list to query.
- * @param index The index of the device to get in the list.
- *
- * @return The device at index if available.\n
- *         NULL if the index is out of range.
- */
-me_device_t *me_dlist_get_device(struct me_dlist *dlist, unsigned int index);
-
-/**
- * @brief Adds a device to the tail of the list.
- *
- * @param dlist The device list to add a device to.
- * @param device The device to add to the list.
- */
-void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t * device);
-
-/**
- * @brief Removes a device from the tail of the list.
- *
- * @param dlist The device list.
- *
- * @return Pointer to the removed subdeivce.\n
- *         NULL in cases where the list was empty.
- */
-me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist);
-
-/**
- * @brief Initializes a device list structure.
- *
- * @param lock The device list structure to initialize.
- * @return 0 on success.
- */
-int me_dlist_init(me_dlist_t * dlist);
-
-/**
- * @brief Deinitializes a device list structure and destructs every device in it.
- *
- * @param dlist The device list structure to deinitialize.
- * @return 0 on success.
- */
-void me_dlist_deinit(me_dlist_t * dlist);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/medlock.c b/drivers/staging/meilhaus/medlock.c
deleted file mode 100644
index 8ded397..0000000
--- a/drivers/staging/meilhaus/medlock.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * @file medlock.c
- *
- * @brief Implements the device lock class.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- */
-
-#include <linux/spinlock.h>
-
-#include "medefines.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meslist.h"
-#include "mesubdevice.h"
-#include "medlock.h"
-
-int me_dlock_enter(struct me_dlock *dlock, struct file *filep)
-{
-	PDEBUG_LOCKS("executed.\n");
-
-	spin_lock(&dlock->spin_lock);
-
-	if ((dlock->filep) != NULL && (dlock->filep != filep)) {
-		PERROR("Device is locked by another process.\n");
-		spin_unlock(&dlock->spin_lock);
-		return ME_ERRNO_LOCKED;
-	}
-
-	dlock->count++;
-
-	spin_unlock(&dlock->spin_lock);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-int me_dlock_exit(struct me_dlock *dlock, struct file *filep)
-{
-	PDEBUG_LOCKS("executed.\n");
-
-	spin_lock(&dlock->spin_lock);
-	dlock->count--;
-	spin_unlock(&dlock->spin_lock);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-int me_dlock_lock(struct me_dlock *dlock,
-		  struct file *filep, int lock, int flags, me_slist_t *slist)
-{
-	int err = ME_ERRNO_SUCCESS;
-	int i;
-	me_subdevice_t *subdevice;
-
-	PDEBUG_LOCKS("executed.\n");
-
-	spin_lock(&dlock->spin_lock);
-
-	switch (lock) {
-
-	case ME_LOCK_RELEASE:
-		if ((dlock->filep == filep) || (dlock->filep == NULL)) {
-			dlock->filep = NULL;
-
-			/* Unlock all possibly locked subdevices. */
-
-			for (i = 0; i < me_slist_get_number_subdevices(slist);
-			     i++) {
-				subdevice = me_slist_get_subdevice(slist, i);
-
-				if (subdevice)
-					err =
-					    subdevice->
-					    me_subdevice_lock_subdevice
-					    (subdevice, filep, ME_LOCK_RELEASE,
-					     flags);
-				else
-					err = ME_ERRNO_INTERNAL;
-			}
-		}
-
-		break;
-
-	case ME_LOCK_SET:
-		if (dlock->count) {
-			PERROR("Device is used by another process.\n");
-			err = ME_ERRNO_USED;
-		} else if ((dlock->filep != NULL) && (dlock->filep != filep)) {
-			PERROR("Device is locked by another process.\n");
-			err = ME_ERRNO_LOCKED;
-		} else if (dlock->filep == NULL) {
-			/* Check any subdevice is locked by another process. */
-
-			for (i = 0; i < me_slist_get_number_subdevices(slist);
-			     i++) {
-				subdevice = me_slist_get_subdevice(slist, i);
-
-				if (subdevice) {
-					if ((err =
-					     subdevice->
-					     me_subdevice_lock_subdevice
-					     (subdevice, filep, ME_LOCK_CHECK,
-					      flags))) {
-						PERROR
-						    ("A subdevice is locked by another process.\n");
-						break;
-					}
-				} else {
-					err = ME_ERRNO_INTERNAL;
-				}
-			}
-
-			/* If no subdevices are locked by other processes,
-			   we can take ownership of the device. Otherwise we jump ahead. */
-			if (!err)
-				dlock->filep = filep;
-		}
-
-		break;
-
-	case ME_LOCK_CHECK:
-		if (dlock->count) {
-			err = ME_ERRNO_USED;
-		} else if ((dlock->filep != NULL) && (dlock->filep != filep)) {
-			err = ME_ERRNO_LOCKED;
-		} else if (dlock->filep == NULL) {
-			for (i = 0; i < me_slist_get_number_subdevices(slist);
-			     i++) {
-				subdevice = me_slist_get_subdevice(slist, i);
-
-				if (subdevice) {
-					if ((err =
-					     subdevice->
-					     me_subdevice_lock_subdevice
-					     (subdevice, filep, ME_LOCK_CHECK,
-					      flags))) {
-						PERROR
-						    ("A subdevice is locked by another process.\n");
-						break;
-					}
-				} else {
-					err = ME_ERRNO_INTERNAL;
-				}
-			}
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid lock.\n");
-
-		err = ME_ERRNO_INVALID_LOCK;
-
-		break;
-	}
-
-	spin_unlock(&dlock->spin_lock);
-
-	return err;
-}
-
-void me_dlock_deinit(struct me_dlock *dlock)
-{
-	PDEBUG_LOCKS("executed.\n");
-}
-
-int me_dlock_init(me_dlock_t *dlock)
-{
-	PDEBUG_LOCKS("executed.\n");
-
-	dlock->filep = NULL;
-	dlock->count = 0;
-	spin_lock_init(&dlock->spin_lock);
-
-	return 0;
-}
diff --git a/drivers/staging/meilhaus/medlock.h b/drivers/staging/meilhaus/medlock.h
deleted file mode 100644
index 4d6ddc8..0000000
--- a/drivers/staging/meilhaus/medlock.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * @file medlock.h
- *
- * @brief Provides the device lock class.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _MEDLOCK_H_
-#define _MEDLOCK_H_
-
-#include <linux/spinlock.h>
-
-#ifdef __KERNEL__
-
-/**
- * @brief The device lock class.
- */
-typedef struct me_dlock {
-	struct file *filep;		/**< Pointer to file structure holding the device. */
-	int count;				/**< Number of tasks which are inside the device. */
-	spinlock_t spin_lock;	/**< Spin lock protecting the attributes from concurrent access. */
-} me_dlock_t;
-
-/**
- * @brief Tries to enter a device.
- *
- * @param dlock The device lock instance.
- * @param filep The file structure identifying the calling process.
- *
- * @return 0 on success.
- */
-int me_dlock_enter(struct me_dlock *dlock, struct file *filep);
-
-/**
- * @brief Exits a device.
- *
- * @param dlock The device lock instance.
- * @param filep The file structure identifying the calling process.
- *
- * @return 0 on success.
- */
-int me_dlock_exit(struct me_dlock *dlock, struct file *filep);
-
-/**
- * @brief Tries to perform a locking action on a device.
- *
- * @param dlock The device lock instance.
- * @param filep The file structure identifying the calling process.
- * @param The action to be done.
- * @param flags Flags from user space.
- * @param slist The subdevice list of the device.
- *
- * @return 0 on success.
- */
-int me_dlock_lock(struct me_dlock *dlock,
-		  struct file *filep, int lock, int flags, me_slist_t * slist);
-
-/**
- * @brief Initializes a lock structure.
- *
- * @param dlock The lock structure to initialize.
- * @return 0 on success.
- */
-int me_dlock_init(me_dlock_t * dlock);
-
-/**
- * @brief Deinitializes a lock structure.
- *
- * @param dlock The lock structure to deinitialize.
- * @return 0 on success.
- */
-void me_dlock_deinit(me_dlock_t * dlock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/medriver.h b/drivers/staging/meilhaus/medriver.h
deleted file mode 100644
index 02e2408..0000000
--- a/drivers/staging/meilhaus/medriver.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : medriver.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- *  Author:	Krzysztof Gantzke	<k.gantzke@meilhaus.de>
- */
-
-#ifndef _MEDRIVER_H_
-#define _MEDRIVER_H_
-
-#include "metypes.h"
-#include "meerror.h"
-#include "medefines.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-	/*===========================================================================
-	  Functions to access the driver system
-	  =========================================================================*/
-
-	int meOpen(int iFlags);
-	int meClose(int iFlags);
-
-	int meLockDriver(int iLock, int iFlags);
-	int meLockDevice(int iDevice, int iLock, int iFlags);
-	int meLockSubdevice(int iDevice, int iSubdevice, int iLock, int iFlags);
-
-	/*===========================================================================
-	  Error handling functions
-	  =========================================================================*/
-
-	int meErrorGetLastMessage(char *pcErrorMsg, int iCount);
-	int meErrorGetMessage(int iErrorCode, char *pcErrorMsg, int iCount);
-	int meErrorSetDefaultProc(int iSwitch);
-	int meErrorSetUserProc(meErrorCB_t pErrorProc);
-
-
-	/*===========================================================================
-	  Functions to perform I/O on a device
-	  =========================================================================*/
-
-	int meIOIrqSetCallback(
-			int iDevice,
-			int iSubdevice,
-			meIOIrqCB_t pCallback,
-			void *pCallbackContext,
-			int iFlags);
-	int meIOIrqStart(
-			int iDevice,
-			int iSubdevice,
-			int iChannel,
-			int iIrqSource,
-			int iIrqEdge,
-			int iIrqArg,
-			int iFlags);
-	int meIOIrqStop(
-			int iDevice,
-			int iSubdevice,
-			int iChannel,
-			int iFlags);
-	int meIOIrqWait(
-			int iDevice,
-			int iSubdevice,
-			int iChannel,
-			int *piIrqCount,
-			int *piValue,
-			int iTimeOut,
-			int iFlags);
-
-	int meIOResetDevice(int iDevice, int iFlags);
-	int meIOResetSubdevice(int iDevice, int iSubdevice, int iFlags);
-
-	int meIOStreamFrequencyToTicks(
-			int iDevice,
-			int iSubdevice,
-			int iTimer,
-			double *pdFrequency,
-			int *piTicksLow,
-			int *piTicksHigh,
-			int iFlags);
-
-	int meIOSingleConfig(
-			int iDevice,
-			int iSubdevice,
-			int iChannel,
-			int iSingleConfig,
-			int iRef,
-			int iTrigChan,
-			int iTrigType,
-			int iTrigEdge,
-			int iFlags);
-	int meIOSingle(meIOSingle_t *pSingleList, int iCount, int iFlags);
-
-	int meIOStreamConfig(
-			int iDevice,
-			int iSubdevice,
-			meIOStreamConfig_t *pConfigList,
-			int iCount,
-			meIOStreamTrigger_t *pTrigger,
-			int iFifoIrqThreshold,
-			int iFlags);
-	int meIOStreamNewValues(
-			int iDevice,
-			int iSubdevice,
-			int iTimeOut,
-			int *piCount,
-			int iFlags);
-	int meIOStreamRead(
-			int iDevice,
-			int iSubdevice,
-			int iReadMode,
-			int *piValues,
-			int *piCount,
-			int iFlags);
-	int meIOStreamWrite(
-			int iDevice,
-			int iSubdevice,
-			int iWriteMode,
-			int *piValues,
-			int *piCount,
-			int iFlags);
-	int meIOStreamStart(meIOStreamStart_t *pStartList, int iCount, int iFlags);
-	int meIOStreamStop(meIOStreamStop_t *pStopList, int iCount, int iFlags);
-	int meIOStreamStatus(
-			int iDevice,
-			int iSubdevice,
-			int iWait,
-			int *piStatus,
-			int *piCount,
-			int iFlags);
-	int meIOStreamSetCallbacks(
-			int iDevice,
-			int iSubdevice,
-			meIOStreamCB_t pStartCB,
-			void *pStartCBContext,
-			meIOStreamCB_t pNewValuesCB,
-			void *pNewValuesCBContext,
-			meIOStreamCB_t pEndCB,
-			void *pEndCBContext,
-			int iFlags);
-	int meIOStreamTimeToTicks(
-			int iDevice,
-			int iSubdevice,
-			int iTimer,
-			double *pdTime,
-			int *piTicksLow,
-			int *piTicksHigh,
-			int iFlags);
-
-
-	/*===========================================================================
-	  Functions to query the driver system
-	  =========================================================================*/
-
-	int meQueryDescriptionDevice(int iDevice, char *pcDescription, int iCount);
-
-	int meQueryInfoDevice(
-			int iDevice,
-			int *piVendorId,
-			int *piDeviceId,
-			int *piSerialNo,
-			int *piBusType,
-			int *piBusNo,
-			int *piDevNo,
-			int *piFuncNo,
-			int *piPlugged);
-
-	int meQueryNameDevice(int iDevice, char *pcName, int iCount);
-	int meQueryNameDeviceDriver(int iDevice, char *pcName, int iCount);
-
-	int meQueryNumberDevices(int *piNumber);
-	int meQueryNumberSubdevices(int iDevice, int *piNumber);
-	int meQueryNumberChannels(int iDevice, int iSubdevice, int *piNumber);
-	int meQueryNumberRanges(
-			int iDevice,
-			int iSubdevice,
-			int iUnit,
-			int *piNumber);
-
-	int meQueryRangeByMinMax(
-			int iDevice,
-			int iSubdevice,
-			int iUnit,
-			double *pdMin,
-			double *pdMax,
-			int *piMaxData,
-			int *piRange);
-	int meQueryRangeInfo(
-			int iDevice,
-			int iSubdevice,
-			int iRange,
-			int *piUnit,
-			double *pdMin,
-			double *pdMax,
-			int *piMaxData);
-
-	int meQuerySubdeviceByType(
-			int iDevice,
-			int iStartSubdevice,
-			int iType,
-			int iSubtype,
-			int *piSubdevice);
-	int meQuerySubdeviceType(
-			int iDevice,
-			int iSubdevice,
-			int *piType,
-			int *piSubtype);
-	int meQuerySubdeviceCaps(
-			int iDevice,
-			int iSubdevice,
-			int *piCaps);
-	int meQuerySubdeviceCapsArgs(
-			int iDevice,
-			int iSubdevice,
-			int iCap,
-			int *piArgs,
-			int iCount);
-
-	int meQueryVersionLibrary(int *piVersion);
-	int meQueryVersionMainDriver(int *piVersion);
-	int meQueryVersionDeviceDriver(int iDevice, int *piVersion);
-
-
-	/*===========================================================================
-	  Common utility functions
-	  =========================================================================*/
-
-	int meUtilityExtractValues(
-			int iChannel,
-			int *piAIBuffer,
-			int iAIBufferCount,
-			meIOStreamConfig_t *pConfigList,
-			int iConfigListCount,
-			int *piChanBuffer,
-			int *piChanBufferCount);
-	int meUtilityDigitalToPhysical(
-			double dMin,
-			double dMax,
-			int iMaxData,
-			int iData,
-			int iModuleType,
-			double dRefValue,
-			double *pdPhysical);
-	int meUtilityDigitalToPhysicalV(
-			double dMin,
-			double dMax,
-			int iMaxData,
-			int *piDataBuffer,
-			int iCount,
-			int iModuleType,
-			double dRefValue,
-			double *pdPhysicalBuffer);
-	int meUtilityPhysicalToDigital(
-			double dMin,
-			double dMax,
-			int iMaxData,
-			double dPhysical,
-			int *piData);
-	int meUtilityPWMStart(
-			int iDevice,
-			int iSubdevice1,
-			int iSubdevice2,
-			int iSubdevice3,
-			int iRef,
-			int iPrescaler,
-			int iDutyCycle,
-			int iFlag);
-	int meUtilityPWMStop(int iDevice,
-			int iSubdevice1);
-	int meUtilityPWMRestart(
-			int iDevice,
-			int iSubdevice1,
-			int iRef,
-			int iPrescaler);
-
-
-	/*===========================================================================
-	  Load configuration from file into driver system
-	  =========================================================================*/
-
-	int meConfigLoad(char *pcConfigFile);
-
-
-	/*===========================================================================
-	  Functions to query a remote driver system
-	  =========================================================================*/
-
-	int meRQueryDescriptionDevice(
-			char *location,
-			int iDevice,
-			char *pcDescription,
-			int iCount);
-
-	int meRQueryInfoDevice(
-			char *location,
-			int iDevice,
-			int *piVendorId,
-			int *piDeviceId,
-			int *piSerialNo,
-			int *piBusType,
-			int *piBusNo,
-			int *piDevNo,
-			int *piFuncNo,
-			int *piPlugged);
-
-	int meRQueryNameDevice(
-			char *location,
-			int iDevice,
-			char *pcName,
-			int iCount);
-
-	int meRQueryNumberDevices(char *location, int *piNumber);
-	int meRQueryNumberSubdevices(char *location, int iDevice, int *piNumber);
-	int meRQueryNumberChannels(
-			char *location,
-			int iDevice,
-			int iSubdevice,
-			int *piNumber);
-	int meRQueryNumberRanges(
-			char *location,
-			int iDevice,
-			int iSubdevice,
-			int iUnit,
-			int *piNumber);
-
-	int meRQueryRangeInfo(
-			char *location,
-			int iDevice,
-			int iSubdevice,
-			int iRange,
-			int *piUnit,
-			double *pdMin,
-			double *pdMax,
-			int *piMaxData);
-
-	int meRQuerySubdeviceType(
-			char *location,
-			int iDevice,
-			int iSubdevice,
-			int *piType,
-			int *piSubtype);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/staging/meilhaus/medummy.c b/drivers/staging/meilhaus/medummy.c
deleted file mode 100644
index 2423745..0000000
--- a/drivers/staging/meilhaus/medummy.c
+++ /dev/null
@@ -1,1264 +0,0 @@
-/* Device driver for Meilhaus ME-DUMMY devices.
- * ===========================================
- *
- *    Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- *    This file is free software; you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation; either version 2 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU 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.
- */
-
-/*
- * User application could also include the kernel header files. But the
- * real kernel functions are protected by #ifdef __KERNEL__.
- */
-#ifndef __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * This must be defined before module.h is included. Not needed, when
- * it is a built in driver.
- */
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include "meerror.h"
-#include "meinternal.h"
-
-#include "meids.h"
-#include "mecommon.h"
-#include "medevice.h"
-#include "medebug.h"
-
-#include "medummy.h"
-
-static int medummy_io_irq_start(me_device_t *device,
-				struct file *filep,
-				int subdevice,
-				int channel,
-				int irq_source,
-				int irq_edge, int irq_arg, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_irq_wait(me_device_t *device,
-			       struct file *filep,
-			       int subdevice,
-			       int channel,
-			       int *irq_count,
-			       int *value, int timeout, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_irq_stop(me_device_t *device,
-			       struct file *filep,
-			       int subdevice, int channel, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-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,
-				      struct file *filep,
-				      int subdevice, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_single_config(me_device_t *device,
-				    struct file *filep,
-				    int subdevice,
-				    int channel,
-				    int single_config,
-				    int ref,
-				    int trig_chan,
-				    int trig_type, int trig_edge, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_single_read(me_device_t *device,
-				  struct file *filep,
-				  int subdevice,
-				  int channel,
-				  int *value, int time_out, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_single_write(me_device_t *device,
-				   struct file *filep,
-				   int subdevice,
-				   int channel,
-				   int value, int time_out, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_stream_config(me_device_t *device,
-				    struct file *filep,
-				    int subdevice,
-				    meIOStreamConfig_t *config_list,
-				    int count,
-				    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,
-					struct file *filep,
-					int subdevice,
-					int timeout, int *count, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_stream_read(me_device_t *device,
-				  struct file *filep,
-				  int subdevice,
-				  int read_mode,
-				  int *values, int *count, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_stream_start(me_device_t *device,
-				   struct file *filep,
-				   int subdevice,
-				   int start_mode, int time_out, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_stream_status(me_device_t *device,
-				    struct file *filep,
-				    int subdevice,
-				    int wait,
-				    int *status, int *values, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_stream_stop(me_device_t *device,
-				  struct file *filep,
-				  int subdevice, int stop_mode, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_io_stream_write(me_device_t *device,
-				   struct file *filep,
-				   int subdevice,
-				   int write_mode,
-				   int *values, int *count, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-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,
-				  struct file *filep,
-				  int subdevice, int lock, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_query_description_device(me_device_t *device,
-					    char **description)
-{
-	medummy_device_t *instance = (medummy_device_t *) device;
-
-	PDEBUG("executed.\n");
-
-//      if (instance->magic != MEDUMMY_MAGIC_NUMBER)
-//      {
-//              PERROR("Wrong magic number.\n");
-//              return ME_ERRNO_INTERNAL;
-//      }
-
-	switch (instance->device_id) {
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1000:
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1000_A:
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1000_B:
-		*description = ME1000_DESCRIPTION_DEVICE_ME1000;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1400:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140A:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400A;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140B:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400B;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400E;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14EA:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400EA;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14EB:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400EB;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400C;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		*description = ME1400_DESCRIPTION_DEVICE_ME1400D;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_4U:
-		*description = ME1600_DESCRIPTION_DEVICE_ME16004U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_8U:
-		*description = ME1600_DESCRIPTION_DEVICE_ME16008U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_12U:
-		*description = ME1600_DESCRIPTION_DEVICE_ME160012U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_16U:
-		*description = ME1600_DESCRIPTION_DEVICE_ME160016U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I:
-		*description = ME1600_DESCRIPTION_DEVICE_ME160016U8I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4610:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4610;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4650:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4650;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4660;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660I:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4660I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660S:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4660S;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660IS:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4660IS;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4670;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670I:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4670I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670S:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4670S;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4670IS;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4680;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680I:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4680I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680S:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4680S;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
-		*description = ME4600_DESCRIPTION_DEVICE_ME4680IS;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6004:
-		*description = ME6000_DESCRIPTION_DEVICE_ME60004;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6008:
-		*description = ME6000_DESCRIPTION_DEVICE_ME60008;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME600F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME600016;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6014:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000I4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6018:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000I8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME601F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000I16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6034:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6038:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME603F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6104:
-		*description = ME6000_DESCRIPTION_DEVICE_ME61004;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6108:
-		*description = ME6000_DESCRIPTION_DEVICE_ME61008;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME610F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME610016;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6114:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100I4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6118:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100I8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME611F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100I16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6134:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6138:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME613F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6044:
-		*description = ME6000_DESCRIPTION_DEVICE_ME60004DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6048:
-		*description = ME6000_DESCRIPTION_DEVICE_ME60008DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME604F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME600016DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6054:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000I4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6058:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000I8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME605F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000I16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6074:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6078:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME607F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6144:
-		*description = ME6000_DESCRIPTION_DEVICE_ME61004DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6148:
-		*description = ME6000_DESCRIPTION_DEVICE_ME61008DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME614F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME610016DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6154:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100I4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6158:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100I8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME615F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100I16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6174:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6178:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME617F:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6259:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6200I9DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6359:
-		*description = ME6000_DESCRIPTION_DEVICE_ME6300I9DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0630:
-		*description = ME0600_DESCRIPTION_DEVICE_ME0630;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
-		*description = ME8100_DESCRIPTION_DEVICE_ME8100A;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
-		*description = ME8100_DESCRIPTION_DEVICE_ME8100B;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0940:
-		*description = ME0900_DESCRIPTION_DEVICE_ME0940;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0950:
-		*description = ME0900_DESCRIPTION_DEVICE_ME0950;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0960:
-		*description = ME0900_DESCRIPTION_DEVICE_ME0960;
-
-		break;
-/*
-		case USB_DEVICE_ID_MEPHISTO_S1:
-			*description = MEPHISTO_S1_DESCRIPTION_DEVICE;
-
-			break;
-*/
-	default:
-		*description = EMPTY_DESCRIPTION_DEVICE;
-		PERROR("Invalid device id in device info.\n");
-
-		return ME_ERRNO_INTERNAL;
-	}
-
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_query_info_device(me_device_t *device,
-				     int *vendor_id,
-				     int *device_id,
-				     int *serial_no,
-				     int *bus_type,
-				     int *bus_no,
-				     int *dev_no, int *func_no, int *plugged)
-{
-	medummy_device_t *instance = (medummy_device_t *) device;
-
-	PDEBUG("executed.\n");
-
-//      if (instance->magic != MEDUMMY_MAGIC_NUMBER)
-//      {
-//              PERROR("Wrong magic number.\n");
-//              return ME_ERRNO_INTERNAL;
-//      }
-
-	*vendor_id = instance->vendor_id;
-	*device_id = instance->device_id;
-	*serial_no = instance->serial_no;
-	*bus_type = instance->bus_type;
-	*bus_no = instance->bus_no;
-	*dev_no = instance->dev_no;
-	*func_no = instance->func_no;
-	*plugged = ME_PLUGGED_OUT;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-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)
-{
-	medummy_device_t *instance = (medummy_device_t *) device;
-
-	PDEBUG("executed.\n");
-
-// // //        if (instance->magic != MEDUMMY_MAGIC_NUMBER)
-// // //        {
-// // //                PERROR("Wrong magic number.\n");
-// // //                return ME_ERRNO_INTERNAL;
-// // //        }
-
-	switch (instance->device_id) {
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1000:
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1000_A:
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1000_B:
-		*name = ME1000_NAME_DEVICE_ME1000;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1400:
-		*name = ME1400_NAME_DEVICE_ME1400;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140A:
-		*name = ME1400_NAME_DEVICE_ME1400A;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140B:
-		*name = ME1400_NAME_DEVICE_ME1400B;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14E0:
-		*name = ME1400_NAME_DEVICE_ME1400E;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14EA:
-		*name = ME1400_NAME_DEVICE_ME1400EA;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME14EB:
-		*name = ME1400_NAME_DEVICE_ME1400EB;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140C:
-		*name = ME1400_NAME_DEVICE_ME1400C;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME140D:
-		*name = ME1400_NAME_DEVICE_ME1400D;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_4U:
-		*name = ME1600_NAME_DEVICE_ME16004U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_8U:
-		*name = ME1600_NAME_DEVICE_ME16008U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_12U:
-		*name = ME1600_NAME_DEVICE_ME160012U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_16U:
-		*name = ME1600_NAME_DEVICE_ME160016U;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I:
-		*name = ME1600_NAME_DEVICE_ME160016U8I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4610:
-		*name = ME4600_NAME_DEVICE_ME4610;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4650:
-		*name = ME4600_NAME_DEVICE_ME4650;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660:
-		*name = ME4600_NAME_DEVICE_ME4660;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4660I:
-		*name = ME4600_NAME_DEVICE_ME4660I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670:
-		*name = ME4600_NAME_DEVICE_ME4670;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670I:
-		*name = ME4600_NAME_DEVICE_ME4670I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670S:
-		*name = ME4600_NAME_DEVICE_ME4670S;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4670IS:
-		*name = ME4600_NAME_DEVICE_ME4670IS;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680:
-		*name = ME4600_NAME_DEVICE_ME4680;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680I:
-		*name = ME4600_NAME_DEVICE_ME4680I;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680S:
-		*name = ME4600_NAME_DEVICE_ME4680S;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME4680IS:
-		*name = ME4600_NAME_DEVICE_ME4680IS;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6004:
-		*name = ME6000_NAME_DEVICE_ME60004;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6008:
-		*name = ME6000_NAME_DEVICE_ME60008;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME600F:
-		*name = ME6000_NAME_DEVICE_ME600016;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6014:
-		*name = ME6000_NAME_DEVICE_ME6000I4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6018:
-		*name = ME6000_NAME_DEVICE_ME6000I8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME601F:
-		*name = ME6000_NAME_DEVICE_ME6000I16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6034:
-		*name = ME6000_NAME_DEVICE_ME6000ISLE4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6038:
-		*name = ME6000_NAME_DEVICE_ME6000ISLE8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME603F:
-		*name = ME6000_NAME_DEVICE_ME6000ISLE16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6104:
-		*name = ME6000_NAME_DEVICE_ME61004;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6108:
-		*name = ME6000_NAME_DEVICE_ME61008;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME610F:
-		*name = ME6000_NAME_DEVICE_ME610016;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6114:
-		*name = ME6000_NAME_DEVICE_ME6100I4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6118:
-		*name = ME6000_NAME_DEVICE_ME6100I8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME611F:
-		*name = ME6000_NAME_DEVICE_ME6100I16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6134:
-		*name = ME6000_NAME_DEVICE_ME6100ISLE4;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6138:
-		*name = ME6000_NAME_DEVICE_ME6100ISLE8;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME613F:
-		*name = ME6000_NAME_DEVICE_ME6100ISLE16;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6044:
-		*name = ME6000_NAME_DEVICE_ME60004DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6048:
-		*name = ME6000_NAME_DEVICE_ME60008DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME604F:
-		*name = ME6000_NAME_DEVICE_ME600016DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6054:
-		*name = ME6000_NAME_DEVICE_ME6000I4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6058:
-		*name = ME6000_NAME_DEVICE_ME6000I8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME605F:
-		*name = ME6000_NAME_DEVICE_ME6000I16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6074:
-		*name = ME6000_NAME_DEVICE_ME6000ISLE4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6078:
-		*name = ME6000_NAME_DEVICE_ME6000ISLE8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME607F:
-		*name = ME6000_NAME_DEVICE_ME6000ISLE16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6144:
-		*name = ME6000_NAME_DEVICE_ME61004DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6148:
-		*name = ME6000_NAME_DEVICE_ME61008DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME614F:
-		*name = ME6000_NAME_DEVICE_ME610016DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6154:
-		*name = ME6000_NAME_DEVICE_ME6100I4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6158:
-		*name = ME6000_NAME_DEVICE_ME6100I8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME615F:
-		*name = ME6000_NAME_DEVICE_ME6100I16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6174:
-		*name = ME6000_NAME_DEVICE_ME6100ISLE4DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME6178:
-		*name = ME6000_NAME_DEVICE_ME6100ISLE8DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME617F:
-		*name = ME6000_NAME_DEVICE_ME6100ISLE16DIO;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0630:
-		*name = ME0600_NAME_DEVICE_ME0630;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_A:
-		*name = ME8100_NAME_DEVICE_ME8100A;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME8100_B:
-		*name = ME8100_NAME_DEVICE_ME8100B;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0940:
-		*name = ME0900_NAME_DEVICE_ME0940;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0950:
-		*name = ME0900_NAME_DEVICE_ME0950;
-
-		break;
-
-	case PCI_DEVICE_ID_MEILHAUS_ME0960:
-		*name = ME0900_NAME_DEVICE_ME0960;
-
-		break;
-/*
-		case USB_DEVICE_ID_MEPHISTO_S1:
-			*name = MEPHISTO_S1_NAME_DEVICE;
-
-			break;
-*/
-	default:
-		*name = EMPTY_NAME_DEVICE;
-		PERROR("Invalid PCI device id.\n");
-
-		return ME_ERRNO_INTERNAL;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-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,
-					 int subdevice, int *number)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-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,
-					int subdevice, int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-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,
-					     int subdevice,
-					     int cap, int *args, int count)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int medummy_query_subdevice_by_type(me_device_t *device,
-					   int start_subdevice,
-					   int type,
-					   int subtype, int *subdevice)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_query_range_by_min_max(me_device_t *device,
-					  int subdevice,
-					  int unit,
-					  int *min,
-					  int *max, int *maxdata, int *range)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-static int medummy_query_range_info(me_device_t *device,
-				    int subdevice,
-				    int range,
-				    int *unit, int *min, int *max, int *maxdata)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_DEVICE_UNPLUGGED;
-}
-
-int medummy_query_timer(me_device_t *device,
-			int subdevice,
-			int timer,
-			int *base_frequency,
-			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,
-					       int *version)
-{
-	PDEBUG("executed.\n");
-
-	*version = ME_VERSION_DRIVER;
-	return ME_ERRNO_SUCCESS;
-}
-
-static void medummy_destructor(me_device_t *device)
-{
-	PDEBUG("executed.\n");
-	kfree(device);
-}
-
-static int init_device_info(unsigned short vendor_id,
-			    unsigned short device_id,
-			    unsigned int serial_no,
-			    int bus_type,
-			    int bus_no,
-			    int dev_no,
-			    int func_no, medummy_device_t *instance)
-{
-	PDEBUG("executed.\n");
-
-//      instance->magic = MEDUMMY_MAGIC_NUMBER;
-	instance->vendor_id = vendor_id;
-	instance->device_id = device_id;
-	instance->serial_no = serial_no;
-	instance->bus_type = bus_type;
-	instance->bus_no = bus_no;
-	instance->dev_no = dev_no;
-	instance->func_no = func_no;
-
-	return 0;
-}
-
-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)
-{
-	PDEBUG("executed.\n");
-
-	INIT_LIST_HEAD(&device->list);
-
-	device->me_device_io_irq_start = medummy_io_irq_start;
-	device->me_device_io_irq_wait = medummy_io_irq_wait;
-	device->me_device_io_irq_stop = medummy_io_irq_stop;
-	device->me_device_io_reset_device = medummy_io_reset_device;
-	device->me_device_io_reset_subdevice = medummy_io_reset_subdevice;
-	device->me_device_io_single_config = medummy_io_single_config;
-	device->me_device_io_single_read = medummy_io_single_read;
-	device->me_device_io_single_write = medummy_io_single_write;
-	device->me_device_io_stream_config = medummy_io_stream_config;
-	device->me_device_io_stream_new_values = medummy_io_stream_new_values;
-	device->me_device_io_stream_read = medummy_io_stream_read;
-	device->me_device_io_stream_start = medummy_io_stream_start;
-	device->me_device_io_stream_status = medummy_io_stream_status;
-	device->me_device_io_stream_stop = medummy_io_stream_stop;
-	device->me_device_io_stream_write = medummy_io_stream_write;
-
-	device->me_device_lock_device = medummy_lock_device;
-	device->me_device_lock_subdevice = medummy_lock_subdevice;
-
-	device->me_device_query_description_device =
-	    medummy_query_description_device;
-	device->me_device_query_info_device = medummy_query_info_device;
-	device->me_device_query_name_device_driver =
-	    medummy_query_name_device_driver;
-	device->me_device_query_name_device = medummy_query_name_device;
-
-	device->me_device_query_number_subdevices =
-	    medummy_query_number_subdevices;
-	device->me_device_query_number_channels = medummy_query_number_channels;
-	device->me_device_query_number_ranges = medummy_query_number_ranges;
-
-	device->me_device_query_range_by_min_max =
-	    medummy_query_range_by_min_max;
-	device->me_device_query_range_info = medummy_query_range_info;
-
-	device->me_device_query_subdevice_type = medummy_query_subdevice_type;
-	device->me_device_query_subdevice_by_type =
-	    medummy_query_subdevice_by_type;
-	device->me_device_query_subdevice_caps = medummy_query_subdevice_caps;
-	device->me_device_query_subdevice_caps_args =
-	    medummy_query_subdevice_caps_args;
-
-	device->me_device_query_timer = medummy_query_timer;
-
-	device->me_device_query_version_device_driver =
-	    medummy_query_version_device_driver;
-
-	device->me_device_destructor = medummy_destructor;
-	device->me_device_config_load = medummy_config_load;
-	return 0;
-}
-
-me_device_t *medummy_constructor(unsigned short vendor_id,
-				 unsigned short device_id,
-				 unsigned int serial_no,
-				 int bus_type,
-				 int bus_no, int dev_no, int func_no)
-{
-	int result = 0;
-	medummy_device_t *instance;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate structure for device attributes */
-	instance = kmalloc(sizeof(medummy_device_t), GFP_KERNEL);
-
-	if (!instance) {
-		PERROR("Can't get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(instance, 0, sizeof(medummy_device_t));
-
-	/* Initialize device info */
-	result = init_device_info(vendor_id,
-				  device_id,
-				  serial_no,
-				  bus_type, bus_no, dev_no, func_no, instance);
-
-	if (result) {
-		PERROR("Cannot init baord info.\n");
-		kfree(instance);
-		return NULL;
-	}
-
-	/* Initialize device instance */
-	result = init_device_instance((me_device_t *) instance);
-
-	if (result) {
-		PERROR("Cannot init baord info.\n");
-		kfree(instance);
-		return NULL;
-	}
-
-	return (me_device_t *) instance;
-}
-EXPORT_SYMBOL(medummy_constructor);
-
-// Init and exit of module.
-
-static int __init dummy_init(void)
-{
-	PDEBUG("executed.\n");
-	return 0;
-}
-
-static void __exit dummy_exit(void)
-{
-	PDEBUG("executed.\n");
-}
-
-module_init(dummy_init);
-
-module_exit(dummy_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-DUMMY Devices");
-MODULE_SUPPORTED_DEVICE("Meilhaus ME-DUMMY Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/medummy.h b/drivers/staging/meilhaus/medummy.h
deleted file mode 100644
index 717000f..0000000
--- a/drivers/staging/meilhaus/medummy.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : medummy.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- */
-
-#ifndef _MEDUMMY_H_
-#define _MEDUMMY_H_
-
-#include "metypes.h"
-#include "medefines.h"
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-#define MEDUMMY_MAGIC_NUMBER	0xDDDD
-
-typedef struct medummy_device {
-	me_device_t base;			/**< The Meilhaus device base class. */
-//      int magic;                                      /**< The magic number of the structure */
-	unsigned short vendor_id;	/**< Vendor ID */
-	unsigned short device_id;	/**< Device ID */
-	unsigned int serial_no;		/**< Serial number of the device */
-	int bus_type;				/**< Bus type */
-	int bus_no;					/**< Bus number */
-	int dev_no;					/**< Device number */
-	int func_no;				/**< Function number */
-} medummy_device_t;
-
-me_device_t *medummy_constructor(unsigned short vendor_id,
-				 unsigned short device_id,
-				 unsigned int serial_no,
-				 int bus_type,
-				 int bus_no,
-				 int dev_no,
-				 int func_no) __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/meerror.h b/drivers/staging/meilhaus/meerror.h
deleted file mode 100644
index 9eda4bf..0000000
--- a/drivers/staging/meilhaus/meerror.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : meerror.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- * Author      : KG (Krzysztof Gantzke)	<k.gantzke@meilhaus.de>
- */
-
-#ifndef _MEERROR_H_
-#define _MEERROR_H_
-
-extern char *meErrorMsgTable[];
-
-#define ME_ERRNO_SUCCESS						0
-#define ME_ERRNO_INVALID_DEVICE					1
-#define ME_ERRNO_INVALID_SUBDEVICE				2
-#define ME_ERRNO_INVALID_CHANNEL				3
-#define ME_ERRNO_INVALID_SINGLE_CONFIG			4
-#define ME_ERRNO_INVALID_REF					5
-#define ME_ERRNO_INVALID_TRIG_CHAN				6
-#define ME_ERRNO_INVALID_TRIG_TYPE				7
-#define ME_ERRNO_INVALID_TRIG_EDGE				8
-#define ME_ERRNO_INVALID_TIMEOUT				9
-#define ME_ERRNO_INVALID_FLAGS					10
-#define ME_ERRNO_OPEN							11
-#define ME_ERRNO_CLOSE							12
-#define ME_ERRNO_NOT_OPEN						13
-#define ME_ERRNO_INVALID_DIR					14
-#define ME_ERRNO_PREVIOUS_CONFIG				15
-#define ME_ERRNO_NOT_SUPPORTED					16
-#define ME_ERRNO_SUBDEVICE_TYPE					17
-#define ME_ERRNO_USER_BUFFER_SIZE				18
-#define ME_ERRNO_LOCKED							19
-#define ME_ERRNO_NOMORE_SUBDEVICE_TYPE			20
-#define ME_ERRNO_TIMEOUT						21
-#define ME_ERRNO_SIGNAL							22
-#define ME_ERRNO_INVALID_IRQ_SOURCE				23
-#define ME_ERRNO_THREAD_RUNNING					24
-#define ME_ERRNO_START_THREAD					25
-#define ME_ERRNO_CANCEL_THREAD					26
-#define ME_ERRNO_NO_CALLBACK					27
-#define ME_ERRNO_USED							28
-#define ME_ERRNO_INVALID_UNIT					29
-#define ME_ERRNO_INVALID_MIN_MAX				30
-#define ME_ERRNO_NO_RANGE						31
-#define ME_ERRNO_INVALID_RANGE					32
-#define ME_ERRNO_SUBDEVICE_BUSY					33
-#define ME_ERRNO_INVALID_LOCK					34
-#define ME_ERRNO_INVALID_SWITCH					35
-#define ME_ERRNO_INVALID_ERROR_MSG_COUNT		36
-#define ME_ERRNO_INVALID_STREAM_CONFIG			37
-#define ME_ERRNO_INVALID_CONFIG_LIST_COUNT		38
-#define ME_ERRNO_INVALID_ACQ_START_TRIG_TYPE	39
-#define ME_ERRNO_INVALID_ACQ_START_TRIG_EDGE	40
-#define ME_ERRNO_INVALID_ACQ_START_TRIG_CHAN	41
-#define ME_ERRNO_INVALID_ACQ_START_TIMEOUT		42
-#define ME_ERRNO_INVALID_ACQ_START_ARG			43
-#define ME_ERRNO_INVALID_SCAN_START_TRIG_TYPE	44
-#define ME_ERRNO_INVALID_SCAN_START_ARG			45
-#define ME_ERRNO_INVALID_CONV_START_TRIG_TYPE	46
-#define ME_ERRNO_INVALID_CONV_START_ARG			47
-#define ME_ERRNO_INVALID_SCAN_STOP_TRIG_TYPE	48
-#define ME_ERRNO_INVALID_SCAN_STOP_ARG			49
-#define ME_ERRNO_INVALID_ACQ_STOP_TRIG_TYPE		50
-#define ME_ERRNO_INVALID_ACQ_STOP_ARG			51
-#define ME_ERRNO_SUBDEVICE_NOT_RUNNING			52
-#define ME_ERRNO_INVALID_READ_MODE				53
-#define ME_ERRNO_INVALID_VALUE_COUNT			54
-#define ME_ERRNO_INVALID_WRITE_MODE				55
-#define ME_ERRNO_INVALID_TIMER					56
-#define ME_ERRNO_DEVICE_UNPLUGGED				57
-#define ME_ERRNO_USED_INTERNAL					58
-#define ME_ERRNO_INVALID_DUTY_CYCLE				59
-#define ME_ERRNO_INVALID_WAIT					60
-#define ME_ERRNO_CONNECT_REMOTE					61
-#define ME_ERRNO_COMMUNICATION					62
-#define ME_ERRNO_INVALID_SINGLE_LIST			63
-#define ME_ERRNO_INVALID_MODULE_TYPE			64
-#define ME_ERRNO_INVALID_START_MODE				65
-#define ME_ERRNO_INVALID_STOP_MODE				66
-#define ME_ERRNO_INVALID_FIFO_IRQ_THRESHOLD		67
-#define ME_ERRNO_INVALID_POINTER				68
-#define ME_ERRNO_CREATE_EVENT					69
-#define ME_ERRNO_LACK_OF_RESOURCES				70
-#define ME_ERRNO_CANCELLED						71
-#define ME_ERRNO_RING_BUFFER_OVERFLOW			72
-#define ME_ERRNO_RING_BUFFER_UNDEFFLOW			73
-#define ME_ERRNO_INVALID_IRQ_EDGE				74
-#define ME_ERRNO_INVALID_IRQ_ARG				75
-#define ME_ERRNO_INVALID_CAP					76
-#define ME_ERRNO_INVALID_CAP_ARG_COUNT			77
-#define ME_ERRNO_INTERNAL						78
-
-/** New error for range check */
-#define ME_ERRNO_VALUE_OUT_OF_RANGE				79
-#define ME_ERRNO_FIFO_BUFFER_OVERFLOW			80
-#define ME_ERRNO_FIFO_BUFFER_UNDEFFLOW			81
-
-#define ME_ERRNO_INVALID_ERROR_NUMBER			82
-#endif
diff --git a/drivers/staging/meilhaus/mefirmware.c b/drivers/staging/meilhaus/mefirmware.c
deleted file mode 100644
index c07d202..0000000
--- a/drivers/staging/meilhaus/mefirmware.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- * @file mefirmware.c
- *
- * @brief Implements the firmware handling.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/***************************************************************************
- *   Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)     *
- *   Copyright (C) 2007 by Krzysztof Gantzke k.gantzke@meilhaus.de         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU 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 __KERNEL__
-# define __KERNEL__
-#endif
-
-#ifndef KBUILD_MODNAME
-#  define KBUILD_MODNAME KBUILD_STR(mefirmware)
-#endif
-
-#include <linux/pci.h>
-#include <linux/delay.h>
-
-#include <linux/firmware.h>
-
-#include "meplx_reg.h"
-#include "medebug.h"
-
-#include "mefirmware.h"
-
-int me_xilinx_download(unsigned long register_base_control,
-		       unsigned long register_base_data,
-		       struct device *dev, const char *firmware_name)
-{
-	int err = ME_ERRNO_FIRMWARE;
-	uint32_t value = 0;
-	int idx = 0;
-
-	const struct firmware *fw;
-
-	PDEBUG("executed.\n");
-
-	if (!firmware_name) {
-		PERROR("Request for firmware failed. No name provided. \n");
-		return err;
-	}
-
-	PINFO("Request '%s' firmware.\n", firmware_name);
-	err = request_firmware(&fw, firmware_name, dev);
-
-	if (err) {
-		PERROR("Request for firmware failed.\n");
-		return err;
-	}
-	// Set PLX local interrupt 2 polarity to high.
-	// Interrupt is thrown by init pin of xilinx.
-	outl(PLX_INTCSR_LOCAL_INT2_POL, register_base_control + PLX_INTCSR);
-
-	// Set /CS and /WRITE of the Xilinx
-	value = inl(register_base_control + PLX_ICR);
-	value |= ME_FIRMWARE_CS_WRITE;
-	outl(value, register_base_control + PLX_ICR);
-
-	// Init Xilinx with CS1
-	inl(register_base_data + ME_XILINX_CS1_REG);
-
-	// Wait for init to complete
-	udelay(20);
-
-	// Checkl /INIT pin
-	if (!
-	    (inl(register_base_control + PLX_INTCSR) &
-	     PLX_INTCSR_LOCAL_INT2_STATE)) {
-		PERROR("Can't init Xilinx.\n");
-		release_firmware(fw);
-		return -EIO;
-	}
-	// Reset /CS and /WRITE of the Xilinx
-	value = inl(register_base_control + PLX_ICR);
-	value &= ~ME_FIRMWARE_CS_WRITE;
-	outl(value, register_base_control + PLX_ICR);
-
-	// Download Xilinx firmware
-	udelay(10);
-
-	for (idx = 0; idx < fw->size; idx++) {
-		outl(fw->data[idx], register_base_data);
-#ifdef ME6000_v2_4
-///     This checking only for board's version 2.4
-		// Check if BUSY flag is set (low = ready, high = busy)
-		if (inl(register_base_control + PLX_ICR) &
-		    ME_FIRMWARE_BUSY_FLAG) {
-			PERROR("Xilinx is still busy (idx = %d)\n", idx);
-			release_firmware(fw);
-			return -EIO;
-		}
-#endif //ME6000_v2_4
-	}
-	PDEBUG("Download finished. %d bytes written to PLX.\n", idx);
-
-	// If done flag is high download was successful
-	if (inl(register_base_control + PLX_ICR) & ME_FIRMWARE_DONE_FLAG) {
-		PDEBUG("SUCCESS. Done flag is set.\n");
-	} else {
-		PERROR("FAILURE. DONE flag is not set.\n");
-		release_firmware(fw);
-		return -EIO;
-	}
-
-	// Set /CS and /WRITE
-	value = inl(register_base_control + PLX_ICR);
-	value |= ME_FIRMWARE_CS_WRITE;
-	outl(value, register_base_control + PLX_ICR);
-
-	PDEBUG("Enable interrupts on the PCI interface.\n");
-	outl(ME_PLX_PCI_ACTIVATE, register_base_control + PLX_INTCSR);
-	release_firmware(fw);
-
-	return 0;
-}
diff --git a/drivers/staging/meilhaus/mefirmware.h b/drivers/staging/meilhaus/mefirmware.h
deleted file mode 100644
index a268508..0000000
--- a/drivers/staging/meilhaus/mefirmware.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file mefirmware.h
- *
- * @brief Definitions of the firmware handling functions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/***************************************************************************
- *   Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)     *
- *   Copyright (C) 2007 by Krzysztof Gantzke k.gantzke@meilhaus.de         *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU 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 _MEFIRMWARE_H
-# define _MEFIRMWARE_H
-
-# ifdef __KERNEL__
-
-#define ME_ERRNO_FIRMWARE		-1
-
-/**
-* Registry
-*/
-#define ME_XILINX_CS1_REG		0x00C8
-
-/**
-* Flags (bits)
-*/
-
-#define ME_FIRMWARE_BUSY_FLAG	0x00000020
-#define ME_FIRMWARE_DONE_FLAG	0x00000004
-#define ME_FIRMWARE_CS_WRITE	0x00000100
-
-#define ME_PLX_PCI_ACTIVATE		0x43
-
-int me_xilinx_download(unsigned long register_base_control,
-		       unsigned long register_base_data,
-		       struct device *dev, const char *firmware_name);
-
-# endif	//__KERNEL__
-
-#endif //_MEFIRMWARE_H
diff --git a/drivers/staging/meilhaus/meids.h b/drivers/staging/meilhaus/meids.h
deleted file mode 100644
index b3e757c..0000000
--- a/drivers/staging/meilhaus/meids.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : meids.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- */
-
-#ifndef _MEIDS_H_
-#define _MEIDS_H_
-
-#ifdef __KERNEL__
-
-/*=============================================================================
-  Driver names
-  ===========================================================================*/
-
-#define MEMAIN_NAME				"memain"
-#define ME1000_NAME				"me1000"
-#define ME1400_NAME				"me1400"
-#define ME1600_NAME				"me1600"
-#define ME4600_NAME				"me4600"
-#define ME6000_NAME				"me6000"
-#define ME0600_NAME				"me0600"	//"me630"
-#define ME8100_NAME				"me8100"
-#define ME8200_NAME				"me8200"
-#define ME0900_NAME				"me0900"	//"me9x"
-//#define MEPHISTO_S1_NAME                      "mephisto_s1"
-#define MEDUMMY_NAME			"medummy"
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/meinternal.h b/drivers/staging/meilhaus/meinternal.h
deleted file mode 100644
index 8d126b4..0000000
--- a/drivers/staging/meilhaus/meinternal.h
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : meinternal.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- */
-
-#ifndef _MEINTERNAL_H_
-#define _MEINTERNAL_H_
-
-/*=============================================================================
-  PCI Vendor IDs
-  ===========================================================================*/
-
-#define PCI_VENDOR_ID_MEILHAUS						0x1402
-
-/*=============================================================================
-  PCI Device IDs
-  ===========================================================================*/
-
-#define PCI_DEVICE_ID_MEILHAUS_ME1000				0x1000
-#define PCI_DEVICE_ID_MEILHAUS_ME1000_A				0x100A
-#define PCI_DEVICE_ID_MEILHAUS_ME1000_B				0x100B
-
-#define PCI_DEVICE_ID_MEILHAUS_ME1400				0x1400
-#define PCI_DEVICE_ID_MEILHAUS_ME140A				0x140A
-#define PCI_DEVICE_ID_MEILHAUS_ME140B				0x140B
-#define PCI_DEVICE_ID_MEILHAUS_ME14E0				0x14E0
-#define PCI_DEVICE_ID_MEILHAUS_ME14EA				0x14EA
-#define PCI_DEVICE_ID_MEILHAUS_ME14EB				0x14EB
-#define PCI_DEVICE_ID_MEILHAUS_ME140C				0X140C
-#define PCI_DEVICE_ID_MEILHAUS_ME140D				0X140D
-
-#define PCI_DEVICE_ID_MEILHAUS_ME1600_4U			0x1604 // 4 voltage outputs
-#define PCI_DEVICE_ID_MEILHAUS_ME1600_8U			0x1608 // 8 voltage outputs
-#define PCI_DEVICE_ID_MEILHAUS_ME1600_12U			0x160C // 12 voltage outputs
-#define PCI_DEVICE_ID_MEILHAUS_ME1600_16U			0x160F // 16 voltage outputs
-#define PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I		0x168F // 16 voltage/8 current o.
-
-#define PCI_DEVICE_ID_MEILHAUS_ME4610				0x4610 // Jekyll
-
-#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_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
-
-/* ME6000 standard version */
-#define PCI_DEVICE_ID_MEILHAUS_ME6004   			0x6004
-#define PCI_DEVICE_ID_MEILHAUS_ME6008   			0x6008
-#define PCI_DEVICE_ID_MEILHAUS_ME600F   			0x600F
-
-/* ME6000 isolated version */
-#define PCI_DEVICE_ID_MEILHAUS_ME6014   			0x6014
-#define PCI_DEVICE_ID_MEILHAUS_ME6018   			0x6018
-#define PCI_DEVICE_ID_MEILHAUS_ME601F   			0x601F
-
-/* ME6000 isle version */
-#define PCI_DEVICE_ID_MEILHAUS_ME6034   			0x6034
-#define PCI_DEVICE_ID_MEILHAUS_ME6038   			0x6038
-#define PCI_DEVICE_ID_MEILHAUS_ME603F   			0x603F
-
-/* ME6000 standard version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6044   			0x6044
-#define PCI_DEVICE_ID_MEILHAUS_ME6048   			0x6048
-#define PCI_DEVICE_ID_MEILHAUS_ME604F   			0x604F
-
-/* ME6000 isolated version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6054   			0x6054
-#define PCI_DEVICE_ID_MEILHAUS_ME6058   			0x6058
-#define PCI_DEVICE_ID_MEILHAUS_ME605F   			0x605F
-
-/* ME6000 isle version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6074   			0x6074
-#define PCI_DEVICE_ID_MEILHAUS_ME6078   			0x6078
-#define PCI_DEVICE_ID_MEILHAUS_ME607F   			0x607F
-
-/* ME6100 standard version */
-#define PCI_DEVICE_ID_MEILHAUS_ME6104   			0x6104
-#define PCI_DEVICE_ID_MEILHAUS_ME6108   			0x6108
-#define PCI_DEVICE_ID_MEILHAUS_ME610F   			0x610F
-
-/* ME6100 isolated version */
-#define PCI_DEVICE_ID_MEILHAUS_ME6114   			0x6114
-#define PCI_DEVICE_ID_MEILHAUS_ME6118   			0x6118
-#define PCI_DEVICE_ID_MEILHAUS_ME611F   			0x611F
-
-/* ME6100 isle version */
-#define PCI_DEVICE_ID_MEILHAUS_ME6134   			0x6134
-#define PCI_DEVICE_ID_MEILHAUS_ME6138   			0x6138
-#define PCI_DEVICE_ID_MEILHAUS_ME613F   			0x613F
-
-/* ME6100 standard version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6144				0x6144
-#define PCI_DEVICE_ID_MEILHAUS_ME6148   			0x6148
-#define PCI_DEVICE_ID_MEILHAUS_ME614F   			0x614F
-
-/* ME6100 isolated version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6154   			0x6154
-#define PCI_DEVICE_ID_MEILHAUS_ME6158   			0x6158
-#define PCI_DEVICE_ID_MEILHAUS_ME615F   			0x615F
-
-/* ME6100 isle version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6174   			0x6174
-#define PCI_DEVICE_ID_MEILHAUS_ME6178   			0x6178
-#define PCI_DEVICE_ID_MEILHAUS_ME617F   			0x617F
-
-/* ME6200 isolated version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6259				0x6259
-
-/* ME6300 isolated version with DIO */
-#define PCI_DEVICE_ID_MEILHAUS_ME6359				0x6359
-
-/* ME0630 */
-#define PCI_DEVICE_ID_MEILHAUS_ME0630				0x0630
-
-/* ME8100 */
-#define PCI_DEVICE_ID_MEILHAUS_ME8100_A				0x810A
-#define PCI_DEVICE_ID_MEILHAUS_ME8100_B  			0x810B
-
-/* ME8200 */
-#define PCI_DEVICE_ID_MEILHAUS_ME8200_A				0x820A
-#define PCI_DEVICE_ID_MEILHAUS_ME8200_B  			0x820B
-
-/* ME0900 */
-#define PCI_DEVICE_ID_MEILHAUS_ME0940				0x0940
-#define PCI_DEVICE_ID_MEILHAUS_ME0950				0x0950
-#define PCI_DEVICE_ID_MEILHAUS_ME0960				0x0960
-
-
-/*=============================================================================
-  USB Vendor IDs
-  ===========================================================================*/
-
-//#define USB_VENDOR_ID_MEPHISTO_S1					0x0403
-
-
-/*=============================================================================
-  USB Device IDs
-  ===========================================================================*/
-
-//#define USB_DEVICE_ID_MEPHISTO_S1					0xDCD0
-
-
-/* ME-1000 defines */
-#define ME1000_NAME_DRIVER							"ME-1000"
-
-#define ME1000_NAME_DEVICE_ME1000					"ME-1000"
-
-#define ME1000_DESCRIPTION_DEVICE_ME1000			"ME-1000 device, 128 digital i/o lines."
-
-/* ME-1400 defines */
-#define ME1400_NAME_DRIVER							"ME-1400"
-
-#define ME1400_NAME_DEVICE_ME1400					"ME-1400"
-#define ME1400_NAME_DEVICE_ME1400E					"ME-1400E"
-#define ME1400_NAME_DEVICE_ME1400A					"ME-1400A"
-#define ME1400_NAME_DEVICE_ME1400EA					"ME-1400EA"
-#define ME1400_NAME_DEVICE_ME1400B					"ME-1400B"
-#define ME1400_NAME_DEVICE_ME1400EB					"ME-1400EB"
-#define ME1400_NAME_DEVICE_ME1400C					"ME-1400C"
-#define ME1400_NAME_DEVICE_ME1400D					"ME-1400D"
-
-#define ME1400_DESCRIPTION_DEVICE_ME1400			"ME-1400 device, 24 digital i/o lines."
-#define ME1400_DESCRIPTION_DEVICE_ME1400E			"ME-1400E device, 24 digital i/o lines."
-#define ME1400_DESCRIPTION_DEVICE_ME1400A			"ME-1400A device, 24 digital i/o lines, 3 counters."
-#define ME1400_DESCRIPTION_DEVICE_ME1400EA			"ME-1400EA device, 24 digital i/o lines, 3 counters."
-#define ME1400_DESCRIPTION_DEVICE_ME1400B			"ME-1400B device, 48 digital i/o lines, 6 counters."
-#define ME1400_DESCRIPTION_DEVICE_ME1400EB			"ME-1400EB device, 48 digital i/o lines, 6 counters."
-#define ME1400_DESCRIPTION_DEVICE_ME1400C			"ME-1400C device, 24 digital i/o lines, 15 counters."
-#define ME1400_DESCRIPTION_DEVICE_ME1400D			"ME-1400D device, 48 digital i/o lines, 30 counters."
-
-/* ME-1600 defines */
-#define ME1600_NAME_DRIVER							"ME-1600"
-
-#define ME1600_NAME_DEVICE_ME16004U					"ME-1600/4U"
-#define ME1600_NAME_DEVICE_ME16008U					"ME-1600/8U"
-#define ME1600_NAME_DEVICE_ME160012U				"ME-1600/12U"
-#define ME1600_NAME_DEVICE_ME160016U				"ME-1600/16U"
-#define ME1600_NAME_DEVICE_ME160016U8I				"ME-1600/16U8I"
-
-#define ME1600_DESCRIPTION_DEVICE_ME16004U			"ME-1600/4U device, 4 voltage outputs."
-#define ME1600_DESCRIPTION_DEVICE_ME16008U			"ME-1600/8U device, 8 voltage outputs."
-#define ME1600_DESCRIPTION_DEVICE_ME160012U			"ME-1600/12U device, 12 voltage outputs."
-#define ME1600_DESCRIPTION_DEVICE_ME160016U			"ME-1600/16U device, 16 voltage outputs."
-#define ME1600_DESCRIPTION_DEVICE_ME160016U8I		"ME-1600/16U8I device, 16 voltage, 8 current outputs."
-
-/* ME-4000 defines */
-#define ME4600_NAME_DRIVER							"ME-4600"
-
-#define ME4600_NAME_DEVICE_ME4610					"ME-4610"
-#define ME4600_NAME_DEVICE_ME4650					"ME-4650"
-#define ME4600_NAME_DEVICE_ME4660					"ME-4660"
-#define ME4600_NAME_DEVICE_ME4660I					"ME-4660I"
-#define ME4600_NAME_DEVICE_ME4660S					"ME-4660S"
-#define ME4600_NAME_DEVICE_ME4660IS					"ME-4660IS"
-#define ME4600_NAME_DEVICE_ME4670					"ME-4670"
-#define ME4600_NAME_DEVICE_ME4670I					"ME-4670I"
-#define ME4600_NAME_DEVICE_ME4670S					"ME-4670S"
-#define ME4600_NAME_DEVICE_ME4670IS					"ME-4670IS"
-#define ME4600_NAME_DEVICE_ME4680					"ME-4680"
-#define ME4600_NAME_DEVICE_ME4680I					"ME-4680I"
-#define ME4600_NAME_DEVICE_ME4680S					"ME-4680S"
-#define ME4600_NAME_DEVICE_ME4680IS					"ME-4680IS"
-
-#define ME4600_DESCRIPTION_DEVICE_ME4610			"ME-4610 device, 16 streaming analog inputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4650			"ME-4650 device, 16 streaming analog inputs, 32 digital i/o lines, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4660			"ME-4660 device, 16 streaming analog inputs, 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4660I			"ME-4660I opto isolated device, 16 streaming analog inputs, 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4660S			"ME-4660 device, 16 streaming analog inputs (8 S&H), 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4660IS			"ME-4660I opto isolated device, 16 streaming analog inputs (8 S&H), 2 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4670			"ME-4670 device, 32 streaming analog inputs, 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4670I			"ME-4670I opto isolated device, 32 streaming analog inputs, 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4670S			"ME-4670S device, 32 streaming analog inputs (8 S&H), 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4670IS			"ME-4670IS opto isolated device, 32 streaming analog inputs (8 S&H), 4 single analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4680			"ME-4680 device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4680I			"ME-4680I opto isolated device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4680S			"ME-4680S device, 32 streaming analog inputs, 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-#define ME4600_DESCRIPTION_DEVICE_ME4680IS			"ME-4680IS opto isolated device, 32 streaming analog inputs (8 S&H), 4 streaming analog outputs, 32 digital i/o lines, 3 counters, 1 external interrupt."
-
-/* ME-6000 defines */
-#define ME6000_NAME_DRIVER							"ME-6000"
-
-#define ME6000_NAME_DEVICE_ME60004					"ME-6000/4"
-#define ME6000_NAME_DEVICE_ME60008					"ME-6000/8"
-#define ME6000_NAME_DEVICE_ME600016					"ME-6000/16"
-#define ME6000_NAME_DEVICE_ME6000I4					"ME-6000I/4"
-#define ME6000_NAME_DEVICE_ME6000I8					"ME-6000I/8"
-#define ME6000_NAME_DEVICE_ME6000I16				"ME-6000I/16"
-#define ME6000_NAME_DEVICE_ME6000ISLE4				"ME-6000ISLE/4"
-#define ME6000_NAME_DEVICE_ME6000ISLE8				"ME-6000ISLE/8"
-#define ME6000_NAME_DEVICE_ME6000ISLE16				"ME-6000ISLE/16"
-#define ME6000_NAME_DEVICE_ME61004					"ME-6100/4"
-#define ME6000_NAME_DEVICE_ME61008					"ME-6100/8"
-#define ME6000_NAME_DEVICE_ME610016					"ME-6100/16"
-#define ME6000_NAME_DEVICE_ME6100I4					"ME-6100I/4"
-#define ME6000_NAME_DEVICE_ME6100I8					"ME-6100I/8"
-#define ME6000_NAME_DEVICE_ME6100I16				"ME-6100I/16"
-#define ME6000_NAME_DEVICE_ME6100ISLE4				"ME-6100ISLE/4"
-#define ME6000_NAME_DEVICE_ME6100ISLE8				"ME-6100ISLE/8"
-#define ME6000_NAME_DEVICE_ME6100ISLE16				"ME-6100ISLE/16"
-#define ME6000_NAME_DEVICE_ME60004DIO				"ME-6000/4/DIO"
-#define ME6000_NAME_DEVICE_ME60008DIO				"ME-6000/8/DIO"
-#define ME6000_NAME_DEVICE_ME600016DIO				"ME-6000/16/DIO"
-#define ME6000_NAME_DEVICE_ME6000I4DIO				"ME-6000I/4/DIO"
-#define ME6000_NAME_DEVICE_ME6000I8DIO				"ME-6000I/8/DIO"
-#define ME6000_NAME_DEVICE_ME6000I16DIO				"ME-6000I/16/DIO"
-#define ME6000_NAME_DEVICE_ME6000ISLE4DIO			"ME-6000ISLE/4/DIO"
-#define ME6000_NAME_DEVICE_ME6000ISLE8DIO			"ME-6000ISLE/8/DIO"
-#define ME6000_NAME_DEVICE_ME6000ISLE16DIO			"ME-6000ISLE/16/DIO"
-#define ME6000_NAME_DEVICE_ME61004DIO				"ME-6100/4/DIO"
-#define ME6000_NAME_DEVICE_ME61008DIO				"ME-6100/8/DIO"
-#define ME6000_NAME_DEVICE_ME610016DIO				"ME-6100/16/DIO"
-#define ME6000_NAME_DEVICE_ME6100I4DIO				"ME-6100I/4/DIO"
-#define ME6000_NAME_DEVICE_ME6100I8DIO				"ME-6100I/8/DIO"
-#define ME6000_NAME_DEVICE_ME6100I16DIO				"ME-6100I/16/DIO"
-#define ME6000_NAME_DEVICE_ME6100ISLE4DIO			"ME-6100ISLE/4/DIO"
-#define ME6000_NAME_DEVICE_ME6100ISLE8DIO			"ME-6100ISLE/8/DIO"
-#define ME6000_NAME_DEVICE_ME6100ISLE16DIO			"ME-6100ISLE/16/DIO"
-#define ME6000_NAME_DEVICE_ME6200I9DIO				"ME-6200I/9/DIO"
-#define ME6000_NAME_DEVICE_ME6300I9DIO				"ME-6300I/9/DIO"
-
-#define ME6000_DESCRIPTION_DEVICE_ME60004			"ME-6000/4 device, 4 single analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME60008			"ME-6000/8 device, 8 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME600016			"ME-6000/16 device, 16 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME6000I4			"ME-6000I/4 isolated device, 4 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME6000I8			"ME-6000I/8 isolated device, 8 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME6000I16			"ME-6000I/16 isolated device, 16 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE4		"ME-6000ISLE/4 isle device, 4 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE8		"ME-6000ISLE/8 isle device, 8 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE16		"ME-6000ISLE/16 isle device, 16 single analog outputs"
-#define ME6000_DESCRIPTION_DEVICE_ME61004			"ME-6100/4 device, 4 streaming analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME61008			"ME-6100/8 device, 4 streaming, 4 single analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME610016			"ME-6100/16 device, 4 streaming, 12 single analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME6100I4			"ME-6100I/4 isolated device, 4 streaming analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME6100I8			"ME-6100I/8 isolated device, 4 streaming, 4 single analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME6100I16			"ME-6100I/16 isolated device, 4 streaming, 12 single analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE4		"ME-6100ISLE/4 isle device, 4 streaming analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE8		"ME-6100ISLE/8 isle device, 4 streaming, 4 single analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE16		"ME-6100ISLE/16 isle device, 4 streaming, 12 single analog outputs."
-#define ME6000_DESCRIPTION_DEVICE_ME60004DIO		"ME-6000/4/DIO device, 4 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME60008DIO		"ME-6000/8/DIO device, 8 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME600016DIO		"ME-6000/16/DIO device, 8 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6000I4DIO		"ME-6000I/4/DIO isolated device, 4 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6000I8DIO		"ME-6000I/8/DIO isolated device, 8 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6000I16DIO		"ME-6000I/16/DIO isolated device, 16 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE4DIO	"ME-6000ISLE/4/DIO isle device, 4 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE8DIO	"ME-6000ISLE/8/DIO isle device, 8 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6000ISLE16DIO	"ME-6000ISLE/16/DIO isle device, 16 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME61004DIO		"ME-6100/4/DIO device, 4 streaming analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME61008DIO		"ME-6100/8/DIO device, 4 streaming, 4 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME610016DIO		"ME-6100/16/DIO device, 4 streaming, 12 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6100I4DIO		"ME-6100I/4/DIO isolated device, 4 streaming analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6100I8DIO		"ME-6100I/8/DIO isolated device, 4 streaming, 4 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6100I16DIO		"ME-6100I/16/DIO isolated device, 4 streaming, 12 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE4DIO	"ME-6100ISLE/4/DIO isle device, 4 streaming analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE8DIO	"ME-6100ISLE/8/DIO isle device, 4 streaming, 4 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6100ISLE16DIO	"ME-6100ISLE/16/DIO isle device, 4 streaming, 12 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6200I9DIO		"ME-6200I/9/DIO isolated device, 9 single analog outputs, 16 digital i/o lines."
-#define ME6000_DESCRIPTION_DEVICE_ME6300I9DIO		"ME-6300I/9/DIO isolated device, 4 streaming, 5 single analog outputs, 16 digital i/o lines."
-
-/* ME-630 defines */
-#define ME0600_NAME_DRIVER							"ME-0600"
-
-#define ME0600_NAME_DEVICE_ME0630					"ME-630"
-
-#define ME0600_DESCRIPTION_DEVICE_ME0630			"ME-630 device, up to 16 relay, 8 digital ttl input lines, 8 isolated digital input lines, 16 digital i/o lines, 2 external interrupts."
-
-/* ME-8100 defines */
-#define ME8100_NAME_DRIVER							"ME-8100"
-
-#define ME8100_NAME_DEVICE_ME8100A					"ME-8100A"
-#define ME8100_NAME_DEVICE_ME8100B					"ME-8100B"
-
-#define ME8100_DESCRIPTION_DEVICE_ME8100A			"ME-8100A opto isolated device, 16 digital input lines, 16 digital output lines."
-#define ME8100_DESCRIPTION_DEVICE_ME8100B			"ME-8100B opto isolated device, 32 digital input lines, 32 digital output lines, 3 counters."
-
-/* ME-8200 defines */
-#define ME8200_NAME_DRIVER							"ME-8200"
-
-#define ME8200_NAME_DEVICE_ME8200A					"ME-8200A"
-#define ME8200_NAME_DEVICE_ME8200B					"ME-8200B"
-
-#define ME8200_DESCRIPTION_DEVICE_ME8200A			"ME-8200A opto isolated device, 8 digital output lines, 8 digital input lines, 16 digital i/o lines."
-#define ME8200_DESCRIPTION_DEVICE_ME8200B			"ME-8200B opto isolated device, 16 digital output lines, 16 digital input lines, 16 digital i/o lines."
-
-/* ME-0900 defines */
-#define ME0900_NAME_DRIVER							"ME-0900"
-
-#define ME0900_NAME_DEVICE_ME0940					"ME-94"
-#define ME0900_NAME_DEVICE_ME0950					"ME-95"
-#define ME0900_NAME_DEVICE_ME0960					"ME-96"
-
-#define ME0900_DESCRIPTION_DEVICE_ME0940			"ME-94 device, 16 digital input lines, 2 external interrupt lines."
-#define ME0900_DESCRIPTION_DEVICE_ME0950			"ME-95 device, 16 digital output lines."
-#define ME0900_DESCRIPTION_DEVICE_ME0960			"ME-96 device, 8 digital input lines, 8 digital output lines, 2 external interrupt lines."
-
-/* ME-DUMMY defines */
-#define MEDUMMY_NAME_DRIVER							"ME-Dummy"
-
-/* MEPHISTO_S1 defines */
-/*
-#define MEPHISTO_S1_NAME_DRIVER						"MEphisto Scope 1"
-#define MEPHISTO_S1_NAME_DEVICE						"MEphisto Scope 1"
-#define MEPHISTO_S1_DESCRIPTION_DEVICE				"MEphisto Scope 1 device, 2 analog inputs, 24 digital i/o."
-*/
-/* Error defines */
-#define EMPTY_NAME_DRIVER							"ME-???"
-#define EMPTY_NAME_DEVICE							"ME-???"
-#define EMPTY_DESCRIPTION_DEVICE					"ME-??? unknown device"
-
-#endif
diff --git a/drivers/staging/meilhaus/meioctl.h b/drivers/staging/meilhaus/meioctl.h
deleted file mode 100644
index 6dc719f..0000000
--- a/drivers/staging/meilhaus/meioctl.h
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : meioctl.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- */
-
-#ifndef _MEIOCTL_H_
-#define _MEIOCTL_H_
-
-
-/*=============================================================================
-  Types for the input/output ioctls
-  ===========================================================================*/
-
-typedef struct me_io_irq_start {
-	int device;
-	int subdevice;
-	int channel;
-	int irq_source;
-	int irq_edge;
-	int irq_arg;
-	int flags;
-	int errno;
-} me_io_irq_start_t;
-
-
-typedef struct me_io_irq_wait {
-	int device;
-	int subdevice;
-	int channel;
-	int irq_count;
-	int value;
-	int time_out;
-	int flags;
-	int errno;
-} me_io_irq_wait_t;
-
-
-typedef struct me_io_irq_stop {
-	int device;
-	int subdevice;
-	int channel;
-	int flags;
-	int errno;
-} me_io_irq_stop_t;
-
-
-typedef struct me_io_reset_device {
-	int device;
-	int flags;
-	int errno;
-} me_io_reset_device_t;
-
-
-typedef struct me_io_reset_subdevice {
-	int device;
-	int subdevice;
-	int flags;
-	int errno;
-} me_io_reset_subdevice_t;
-
-
-typedef struct me_io_single_config {
-	int device;
-	int subdevice;
-	int channel;
-	int single_config;
-	int ref;
-	int trig_chan;
-	int trig_type;
-	int trig_edge;
-	int flags;
-	int errno;
-} me_io_single_config_t;
-
-
-typedef struct me_io_single {
-	meIOSingle_t *single_list;
-	int count;
-	int flags;
-	int errno;
-} me_io_single_t;
-
-
-typedef struct me_io_stream_config {
-	int device;
-	int subdevice;
-	meIOStreamConfig_t *config_list;
-	int count;
-	meIOStreamTrigger_t trigger;
-	int fifo_irq_threshold;
-	int flags;
-	int errno;
-} me_io_stream_config_t;
-
-
-typedef struct me_io_stream_new_values {
-	int device;
-	int subdevice;
-	int time_out;
-	int count;
-	int flags;
-	int errno;
-} me_io_stream_new_values_t;
-
-
-typedef struct me_io_stream_read {
-	int device;
-	int subdevice;
-	int read_mode;
-	int *values;
-	int count;
-	int flags;
-	int errno;
-} me_io_stream_read_t;
-
-
-typedef struct me_io_stream_start {
-	meIOStreamStart_t *start_list;
-	int count;
-	int flags;
-	int errno;
-} me_io_stream_start_t;
-
-
-typedef struct me_io_stream_status {
-	int device;
-	int subdevice;
-	int wait;
-	int status;
-	int count;
-	int flags;
-	int errno;
-} me_io_stream_status_t;
-
-
-typedef struct me_io_stream_stop {
-	meIOStreamStop_t *stop_list;
-	int count;
-	int flags;
-	int errno;
-} me_io_stream_stop_t;
-
-
-typedef struct me_io_stream_write {
-	int device;
-	int subdevice;
-	int write_mode;
-	int *values;
-	int count;
-	int flags;
-	int errno;
-} me_io_stream_write_t;
-
-
-/*=============================================================================
-  Types for the lock ioctls
-  ===========================================================================*/
-
-typedef struct me_lock_device {
-	int device;
-	int lock;
-	int flags;
-	int errno;
-} me_lock_device_t;
-
-
-typedef struct me_lock_driver {
-	int flags;
-	int lock;
-	int errno;
-} me_lock_driver_t;
-
-
-typedef struct me_lock_subdevice {
-	int device;
-	int subdevice;
-	int lock;
-	int flags;
-	int errno;
-} me_lock_subdevice_t;
-
-
-/*=============================================================================
-  Types for the query ioctls
-  ===========================================================================*/
-
-typedef struct me_query_info_device {
-	int device;
-	int vendor_id;
-	int device_id;
-	int serial_no;
-	int bus_type;
-	int bus_no;
-	int dev_no;
-	int func_no;
-	int plugged;
-	int errno;
-} me_query_info_device_t;
-
-
-typedef struct me_query_description_device {
-	int device;
-	char *name;
-	int count;
-	int errno;
-} me_query_description_device_t;
-
-
-typedef struct me_query_name_device {
-	int device;
-	char *name;
-	int count;
-	int errno;
-} me_query_name_device_t;
-
-
-typedef struct me_query_name_device_driver {
-	int device;
-	char *name;
-	int count;
-	int errno;
-} me_query_name_device_driver_t;
-
-
-typedef struct me_query_version_main_driver {
-	int version;
-	int errno;
-} me_query_version_main_driver_t;
-
-
-typedef struct me_query_version_device_driver {
-	int device;
-	int version;
-	int errno;
-} me_query_version_device_driver_t;
-
-
-typedef struct me_query_number_devices {
-	int number;
-	int errno;
-} me_query_number_devices_t;
-
-
-typedef struct me_query_number_subdevices {
-	int device;
-	int number;
-	int errno;
-} me_query_number_subdevices_t;
-
-
-typedef struct me_query_number_channels {
-	int device;
-	int subdevice;
-	int number;
-	int errno;
-} me_query_number_channels_t;
-
-
-typedef struct me_query_number_ranges {
-	int device;
-	int subdevice;
-	int channel;
-	int unit;
-	int number;
-	int errno;
-} me_query_number_ranges_t;
-
-
-typedef struct me_query_subdevice_by_type {
-	int device;
-	int start_subdevice;
-	int type;
-	int subtype;
-	int subdevice;
-	int errno;
-} me_query_subdevice_by_type_t;
-
-
-typedef struct me_query_subdevice_type {
-	int device;
-	int subdevice;
-	int type;
-	int subtype;
-	int errno;
-} me_query_subdevice_type_t;
-
-
-typedef struct me_query_subdevice_caps {
-	int device;
-	int subdevice;
-	int caps;
-	int errno;
-} me_query_subdevice_caps_t;
-
-
-typedef struct me_query_subdevice_caps_args {
-	int device;
-	int subdevice;
-	int cap;
-	int args[8];
-	int count;
-	int errno;
-} me_query_subdevice_caps_args_t;
-
-
-typedef struct me_query_timer {
-	int device;
-	int subdevice;
-	int timer;
-	int base_frequency;
-	long long min_ticks;
-	long long max_ticks;
-	int errno;
-} me_query_timer_t;
-
-
-typedef struct me_query_range_by_min_max {
-	int device;
-	int subdevice;
-	int channel;
-	int unit;
-	int min;
-	int max;
-	int max_data;
-	int range;
-	int errno;
-} me_query_range_by_min_max_t;
-
-
-typedef struct me_query_range_info {
-	int device;
-	int subdevice;
-	int channel;
-	int unit;
-	int range;
-	int min;
-	int max;
-	int max_data;
-	int errno;
-} me_query_range_info_t;
-
-
-/*=============================================================================
-  Types for the configuration ioctls
-  ===========================================================================*/
-
-typedef struct me_cfg_tcpip_location {
-	int access_type;
-	char *remote_host;
-	int remote_device_number;
-} me_cfg_tcpip_location_t;
-
-
-typedef union me_cfg_tcpip {
-	int access_type;
-	me_cfg_tcpip_location_t location;
-} me_cfg_tcpip_t;
-
-
-typedef struct me_cfg_pci_hw_location {
-	unsigned int bus_type;
-	unsigned int bus_no;
-	unsigned int device_no;
-	unsigned int function_no;
-} me_cfg_pci_hw_location_t;
-
-/*
-typedef struct me_cfg_usb_hw_location {
-	unsigned int bus_type;
-	unsigned int root_hub_no;
-} me_cfg_usb_hw_location_t;
-*/
-
-typedef union me_cfg_hw_location {
-	unsigned int bus_type;
-	me_cfg_pci_hw_location_t pci;
-//	me_cfg_usb_hw_location_t usb;
-} me_cfg_hw_location_t;
-
-
-typedef struct me_cfg_device_info {
-	unsigned int vendor_id;
-	unsigned int device_id;
-	unsigned int serial_no;
-	me_cfg_hw_location_t hw_location;
-} me_cfg_device_info_t;
-
-
-typedef struct me_cfg_subdevice_info {
-	int type;
-	int sub_type;
-	unsigned int number_channels;
-} me_cfg_subdevice_info_t;
-
-
-typedef struct me_cfg_range_entry {
-	int unit;
-	double min;
-	double max;
-	unsigned int max_data;
-} me_cfg_range_entry_t;
-
-
-typedef struct me_cfg_mux32m_device {
-	int type;
-	int timed;
-	unsigned int ai_channel;
-	unsigned int dio_device;
-	unsigned int dio_subdevice;
-	unsigned int timer_device;
-	unsigned int timer_subdevice;
-	unsigned int mux32s_count;
-} me_cfg_mux32m_device_t;
-
-
-typedef struct me_cfg_demux32_device {
-	int type;
-	int timed;
-	unsigned int ao_channel;
-	unsigned int dio_device;
-	unsigned int dio_subdevice;
-	unsigned int timer_device;
-	unsigned int timer_subdevice;
-} me_cfg_demux32_device_t;
-
-
-typedef union me_cfg_external_device {
-	int type;
-	me_cfg_mux32m_device_t mux32m;
-	me_cfg_demux32_device_t demux32;
-} me_cfg_external_device_t;
-
-
-typedef struct me_cfg_subdevice_entry {
-	me_cfg_subdevice_info_t info;
-	me_cfg_range_entry_t *range_list;
-	unsigned int count;
-	int locked;
-	me_cfg_external_device_t external_device;
-} me_cfg_subdevice_entry_t;
-
-
-typedef struct me_cfg_device_entry {
-	me_cfg_tcpip_t tcpip;
-	me_cfg_device_info_t info;
-	me_cfg_subdevice_entry_t *subdevice_list;
-	unsigned int count;
-} me_cfg_device_entry_t;
-
-
-typedef struct me_config_load {
-	me_cfg_device_entry_t *device_list;
-	unsigned int count;
-	int errno;
-} me_config_load_t;
-
-
-/*=============================================================================
-  The ioctls of the board
-  ===========================================================================*/
-
-#define MEMAIN_MAGIC 'y'
-
-#define ME_IO_IRQ_ENABLE				_IOR (MEMAIN_MAGIC, 1, me_io_irq_start_t)
-#define ME_IO_IRQ_WAIT					_IOR (MEMAIN_MAGIC, 2, me_io_irq_wait_t)
-#define ME_IO_IRQ_DISABLE				_IOR (MEMAIN_MAGIC, 3, me_io_irq_stop_t)
-
-#define ME_IO_RESET_DEVICE				_IOW (MEMAIN_MAGIC, 4, me_io_reset_device_t)
-#define ME_IO_RESET_SUBDEVICE			_IOW (MEMAIN_MAGIC, 5, me_io_reset_subdevice_t)
-
-#define ME_IO_SINGLE					_IOWR(MEMAIN_MAGIC, 6, me_io_single_t)
-#define ME_IO_SINGLE_CONFIG				_IOW (MEMAIN_MAGIC, 7, me_io_single_config_t)
-
-#define ME_IO_STREAM_CONFIG				_IOW (MEMAIN_MAGIC, 8, me_io_stream_config_t)
-#define ME_IO_STREAM_NEW_VALUES			_IOR (MEMAIN_MAGIC, 9, me_io_stream_new_values_t)
-#define ME_IO_STREAM_READ				_IOR (MEMAIN_MAGIC, 10, me_io_stream_read_t)
-#define ME_IO_STREAM_START				_IOW (MEMAIN_MAGIC, 11, me_io_stream_start_t)
-#define ME_IO_STREAM_STATUS				_IOR (MEMAIN_MAGIC, 12, me_io_stream_status_t)
-#define ME_IO_STREAM_STOP				_IOW (MEMAIN_MAGIC, 13, me_io_stream_stop_t)
-#define ME_IO_STREAM_WRITE				_IOW (MEMAIN_MAGIC, 14, me_io_stream_write_t)
-
-#define ME_LOCK_DRIVER					_IOW (MEMAIN_MAGIC, 15, me_lock_driver_t)
-#define ME_LOCK_DEVICE					_IOW (MEMAIN_MAGIC, 16, me_lock_device_t)
-#define ME_LOCK_SUBDEVICE				_IOW (MEMAIN_MAGIC, 17, me_lock_subdevice_t)
-
-#define ME_QUERY_DESCRIPTION_DEVICE		_IOR (MEMAIN_MAGIC, 18, me_query_description_device_t)
-
-#define ME_QUERY_INFO_DEVICE			_IOR (MEMAIN_MAGIC, 19, me_query_info_device_t)
-
-#define ME_QUERY_NAME_DEVICE			_IOR (MEMAIN_MAGIC, 20, me_query_name_device_t)
-#define ME_QUERY_NAME_DEVICE_DRIVER		_IOR (MEMAIN_MAGIC, 21, me_query_name_device_driver_t)
-
-#define ME_QUERY_NUMBER_DEVICES			_IOR (MEMAIN_MAGIC, 22, me_query_number_devices_t)
-#define ME_QUERY_NUMBER_SUBDEVICES		_IOR (MEMAIN_MAGIC, 23, me_query_number_subdevices_t)
-#define ME_QUERY_NUMBER_CHANNELS		_IOR (MEMAIN_MAGIC, 24, me_query_number_channels_t)
-#define ME_QUERY_NUMBER_RANGES			_IOR (MEMAIN_MAGIC, 25, me_query_number_ranges_t)
-
-#define ME_QUERY_RANGE_BY_MIN_MAX		_IOR (MEMAIN_MAGIC, 26, me_query_range_by_min_max_t)
-#define ME_QUERY_RANGE_INFO				_IOR (MEMAIN_MAGIC, 27, me_query_range_info_t)
-
-#define ME_QUERY_SUBDEVICE_BY_TYPE		_IOR (MEMAIN_MAGIC, 28, me_query_subdevice_by_type_t)
-#define ME_QUERY_SUBDEVICE_TYPE			_IOR (MEMAIN_MAGIC, 29, me_query_subdevice_type_t)
-#define ME_QUERY_SUBDEVICE_CAPS			_IOR (MEMAIN_MAGIC, 29, me_query_subdevice_caps_t)
-#define ME_QUERY_SUBDEVICE_CAPS_ARGS	_IOR (MEMAIN_MAGIC, 30, me_query_subdevice_caps_args_t)
-
-#define ME_QUERY_TIMER					_IOR (MEMAIN_MAGIC, 31, me_query_timer_t)
-
-#define ME_QUERY_VERSION_DEVICE_DRIVER	_IOR (MEMAIN_MAGIC, 32, me_query_version_device_driver_t)
-#define ME_QUERY_VERSION_MAIN_DRIVER	_IOR (MEMAIN_MAGIC, 33, me_query_version_main_driver_t)
-
-#define ME_CONFIG_LOAD					_IOWR(MEMAIN_MAGIC, 34, me_config_load_t)
-
-#endif
diff --git a/drivers/staging/meilhaus/memain.c b/drivers/staging/meilhaus/memain.c
deleted file mode 100644
index c490854..0000000
--- a/drivers/staging/meilhaus/memain.c
+++ /dev/null
@@ -1,2084 +0,0 @@
-/**
- * @file memain.c
- *
- * @brief Main Meilhaus device driver.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- * @author Krzysztof Gantzke	(k.gantzke@meilhaus.de)
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-#include <linux/pci.h>
-//#include <linux/usb.h>
-#include <linux/errno.h>
-#include <linux/uaccess.h>
-#include <linux/miscdevice.h>
-#include <linux/rwsem.h>
-
-#include "medefines.h"
-#include "metypes.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "memain.h"
-#include "medevice.h"
-#include "meioctl.h"
-#include "mecommon.h"
-
-/* Module parameters
-*/
-
-#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);
-# else
-MODULE_PARM(me_bosch_fw, "i");
-# endif
-
-MODULE_PARM_DESC(me_bosch_fw,
-		 "Flags which signals the ME-4600 driver to load the bosch firmware (default = 0).");
-#endif //BOSCH
-
-/* Global Driver Lock
-*/
-
-static struct file *me_filep = NULL;
-static int me_count = 0;
-static DEFINE_SPINLOCK(me_lock);
-static DECLARE_RWSEM(me_rwsem);
-
-/* Board instances are kept in a global list */
-LIST_HEAD(me_device_list);
-
-/* Prototypes
-*/
-
-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 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);
-static int me_release(struct inode *, struct file *);
-static int me_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-//static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id);
-//static void me_disconnect_usb(struct usb_interface *interface);
-
-/* File operations provided by the module
-*/
-
-static const struct file_operations me_file_operations = {
-	.owner = THIS_MODULE,
-	.ioctl = me_ioctl,
-	.open = me_open,
-	.release = me_release,
-};
-
-static const struct pci_device_id me_pci_table[] = {
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_A) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1000_B) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1400) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140A) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140B) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14E0) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EA) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME14EB) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140C) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME140D) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_4U) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_8U) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_12U) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME1600_16U_8I) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4610) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4650) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4660I) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670I) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670S) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4670IS) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680I) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680S) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME4680IS) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6004) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6008) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME600F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6014) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6018) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME601F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6034) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6038) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME603F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6104) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6108) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME610F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6114) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6118) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME611F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6134) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6138) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME613F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6044) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6048) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME604F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6054) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6058) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME605F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6074) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6078) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME607F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6144) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6148) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME614F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6154) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6158) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME615F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6174) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6178) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME617F) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6259) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME6359) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0630) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_A) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8100_B) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_A) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME8200_B) },
-
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0940) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0950) },
-	{ PCI_VDEVICE(MEILHAUS, PCI_DEVICE_ID_MEILHAUS_ME0960) },
-
-	{ }
-};
-MODULE_DEVICE_TABLE(pci, me_pci_table);
-
-static struct pci_driver me_pci_driver = {
-	.name = MEMAIN_NAME,
-	.id_table = me_pci_table,
-	.probe = me_probe_pci,
-	.remove = __devexit_p(me_remove_pci),
-};
-
-/*
-static struct usb_device_id me_usb_table[] = {
-	{ USB_DEVICE(USB_VENDOR_ID_MEPHISTO_S1, USB_DEVICE_ID_MEPHISTO_S1) },
-	{ 0 }
-};
-MODULE_DEVICE_TABLE (usb, me_usb_table);
-
-static struct usb_driver me_usb_driver =
-{
-	.name = MEMAIN_NAME,
-	.id_table = me_usb_table,
-	.probe = me_probe_usb,
-	.disconnect = me_disconnect_usb
-};
-*/
-
-#ifdef ME_LOCK_MULTIPLEX_TEMPLATE
-ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_device",
-			   me_lock_device_t,
-			   me_lock_device,
-			   me_device_lock_device,
-			   (device, filep, karg.lock, karg.flags))
-
-    ME_LOCK_MULTIPLEX_TEMPLATE("me_lock_subdevice",
-			   me_lock_subdevice_t,
-			   me_lock_subdevice,
-			   me_device_lock_subdevice,
-			   (device, filep, karg.subdevice, karg.lock,
-			karg.flags))
-#else
-#error macro ME_LOCK_MULTIPLEX_TEMPLATE not defined
-#endif
-
-#ifdef ME_IO_MULTIPLEX_TEMPLATE
-ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_start",
-			 me_io_irq_start_t,
-			 me_io_irq_start,
-			 me_device_io_irq_start,
-			 (device,
-			  filep,
-			  karg.subdevice,
-			  karg.channel,
-			  karg.irq_source,
-			  karg.irq_edge, karg.irq_arg, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_wait",
-			 me_io_irq_wait_t,
-			 me_io_irq_wait,
-			 me_device_io_irq_wait,
-			 (device,
-		      filep,
-		      karg.subdevice,
-		      karg.channel,
-		      &karg.irq_count, &karg.value, karg.time_out, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_irq_stop",
-			 me_io_irq_stop_t,
-			 me_io_irq_stop,
-			 me_device_io_irq_stop,
-			 (device,
-		      filep, karg.subdevice, karg.channel, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_device",
-			 me_io_reset_device_t,
-			 me_io_reset_device,
-			 me_device_io_reset_device, (device, filep, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_reset_subdevice",
-			 me_io_reset_subdevice_t,
-			 me_io_reset_subdevice,
-			 me_device_io_reset_subdevice,
-			 (device, filep, karg.subdevice, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_single_config",
-			 me_io_single_config_t,
-			 me_io_single_config,
-			 me_device_io_single_config,
-			 (device,
-		      filep,
-		      karg.subdevice,
-		      karg.channel,
-		      karg.single_config,
-		      karg.ref,
-		      karg.trig_chan,
-		      karg.trig_type, karg.trig_edge, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_new_values",
-			 me_io_stream_new_values_t,
-			 me_io_stream_new_values,
-			 me_device_io_stream_new_values,
-			 (device,
-		      filep,
-		      karg.subdevice, karg.time_out, &karg.count, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_read",
-			 me_io_stream_read_t,
-			 me_io_stream_read,
-			 me_device_io_stream_read,
-			 (device,
-		      filep,
-		      karg.subdevice,
-		      karg.read_mode, karg.values, &karg.count, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_status",
-			 me_io_stream_status_t,
-			 me_io_stream_status,
-			 me_device_io_stream_status,
-			 (device,
-		      filep,
-		      karg.subdevice,
-		      karg.wait, &karg.status, &karg.count, karg.flags))
-
-    ME_IO_MULTIPLEX_TEMPLATE("me_io_stream_write",
-			 me_io_stream_write_t,
-			 me_io_stream_write,
-			 me_device_io_stream_write,
-			 (device,
-		      filep,
-		      karg.subdevice,
-		      karg.write_mode, karg.values, &karg.count, karg.flags))
-#else
-#error macro ME_IO_MULTIPLEX_TEMPLATE not defined
-#endif
-
-#ifdef ME_QUERY_MULTIPLEX_STR_TEMPLATE
-ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device",
-				me_query_name_device_t,
-				me_query_name_device,
-				me_device_query_name_device, (device, &msg))
-
-    ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_name_device_driver",
-				me_query_name_device_driver_t,
-				me_query_name_device_driver,
-				me_device_query_name_device_driver,
-				(device, &msg))
-
-    ME_QUERY_MULTIPLEX_STR_TEMPLATE("me_query_description_device",
-				me_query_description_device_t,
-				me_query_description_device,
-				me_device_query_description_device,
-				(device, &msg))
-#else
-#error macro ME_QUERY_MULTIPLEX_STR_TEMPLATE not defined
-#endif
-
-#ifdef ME_QUERY_MULTIPLEX_TEMPLATE
-ME_QUERY_MULTIPLEX_TEMPLATE("me_query_info_device",
-			    me_query_info_device_t,
-			    me_query_info_device,
-			    me_device_query_info_device,
-			    (device,
-			     &karg.vendor_id,
-			     &karg.device_id,
-			     &karg.serial_no,
-			     &karg.bus_type,
-			     &karg.bus_no,
-			     &karg.dev_no, &karg.func_no, &karg.plugged))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_subdevices",
-			    me_query_number_subdevices_t,
-			    me_query_number_subdevices,
-			    me_device_query_number_subdevices,
-			    (device, &karg.number))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_channels",
-			    me_query_number_channels_t,
-			    me_query_number_channels,
-			    me_device_query_number_channels,
-			    (device, karg.subdevice, &karg.number))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_by_type",
-			    me_query_subdevice_by_type_t,
-			    me_query_subdevice_by_type,
-			    me_device_query_subdevice_by_type,
-			    (device,
-			 karg.start_subdevice,
-			 karg.type, karg.subtype, &karg.subdevice))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_type",
-			    me_query_subdevice_type_t,
-			    me_query_subdevice_type,
-			    me_device_query_subdevice_type,
-			    (device, karg.subdevice, &karg.type, &karg.subtype))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps",
-			    me_query_subdevice_caps_t,
-			    me_query_subdevice_caps,
-			    me_device_query_subdevice_caps,
-			    (device, karg.subdevice, &karg.caps))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_subdevice_caps_args",
-			    me_query_subdevice_caps_args_t,
-			    me_query_subdevice_caps_args,
-			    me_device_query_subdevice_caps_args,
-			    (device, karg.subdevice, karg.cap, karg.args,
-			 karg.count))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_number_ranges",
-			    me_query_number_ranges_t,
-			    me_query_number_ranges,
-			    me_device_query_number_ranges,
-			    (device, karg.subdevice, karg.unit, &karg.number))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_by_min_max",
-			    me_query_range_by_min_max_t,
-			    me_query_range_by_min_max,
-			    me_device_query_range_by_min_max,
-			    (device,
-			 karg.subdevice,
-			 karg.unit,
-			 &karg.min, &karg.max, &karg.max_data, &karg.range))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_range_info",
-			    me_query_range_info_t,
-			    me_query_range_info,
-			    me_device_query_range_info,
-			    (device,
-			 karg.subdevice,
-			 karg.range,
-			 &karg.unit, &karg.min, &karg.max, &karg.max_data))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_timer",
-			    me_query_timer_t,
-			    me_query_timer,
-			    me_device_query_timer,
-			    (device,
-			 karg.subdevice,
-			 karg.timer,
-			 &karg.base_frequency,
-			 &karg.min_ticks, &karg.max_ticks))
-
-    ME_QUERY_MULTIPLEX_TEMPLATE("me_query_version_device_driver",
-			    me_query_version_device_driver_t,
-			    me_query_version_device_driver,
-			    me_device_query_version_device_driver,
-			    (device, &karg.version))
-#else
-#error macro ME_QUERY_MULTIPLEX_TEMPLATE not defined
-#endif
-
-/** ******************************************************************************** **/
-
-static me_device_t *get_dummy_instance(unsigned short vendor_id,
-				       unsigned short device_id,
-				       unsigned int serial_no,
-				       int bus_type,
-				       int bus_no, int dev_no, int func_no)
-{
-	int err;
-	me_dummy_constructor_t constructor = NULL;
-	me_device_t *instance;
-
-	PDEBUG("executed.\n");
-
-	if ((constructor = symbol_get(medummy_constructor)) == NULL) {
-		err = request_module(MEDUMMY_NAME);
-
-		if (err) {
-			PERROR("Error while request for module %s.\n",
-			       MEDUMMY_NAME);
-			return NULL;
-		}
-
-		if ((constructor = symbol_get(medummy_constructor)) == NULL) {
-			PERROR("Can't get %s driver module constructor.\n",
-			       MEDUMMY_NAME);
-			return NULL;
-		}
-	}
-
-	if ((instance = (*constructor) (vendor_id,
-					device_id,
-					serial_no,
-					bus_type,
-					bus_no, dev_no, func_no)) == NULL)
-		symbol_put(medummy_constructor);
-
-	return instance;
-}
-
-static int __devinit me_probe_pci(struct pci_dev *dev,
-		const struct pci_device_id *id)
-{
-	int err;
-	me_pci_constructor_t constructor = NULL;
-#ifdef BOSCH
-	me_bosch_constructor_t constructor_bosch = NULL;
-#endif
-	me_device_t *n_device = NULL;
-	uint32_t device;
-
-	char constructor_name[24] = "me0000_pci_constructor";
-	char module_name[7] = "me0000";
-
-	PDEBUG("executed.\n");
-	device = dev->device;
-	if ((device & 0xF000) == 0x6000) {	// Exceptions: me61xx, me62xx, me63xx are handled by one driver.
-		device &= 0xF0FF;
-	}
-
-	constructor_name[2] += (char)((device >> 12) & 0x000F);
-	constructor_name[3] += (char)((device >> 8) & 0x000F);
-	PDEBUG("constructor_name: %s\n", constructor_name);
-	module_name[2] += (char)((device >> 12) & 0x000F);
-	module_name[3] += (char)((device >> 8) & 0x000F);
-	PDEBUG("module_name: %s\n", module_name);
-
-	if ((constructor =
-	     (me_pci_constructor_t) symbol_get(constructor_name)) == NULL) {
-		if (request_module("%s", module_name)) {
-			PERROR("Error while request for module %s.\n",
-			       module_name);
-			return -ENODEV;
-		}
-
-		if ((constructor =
-		     (me_pci_constructor_t) symbol_get(constructor_name)) ==
-		    NULL) {
-			PERROR("Can't get %s driver module constructor.\n",
-			       module_name);
-			return -ENODEV;
-		}
-	}
-#ifdef BOSCH
-	if ((device & 0xF000) == 0x4000) {	// Bosch build has differnt constructor for me4600.
-		if ((n_device =
-		     (*constructor_bosch) (dev, me_bosch_fw)) == NULL) {
-			symbol_put(constructor_name);
-			PERROR
-			    ("Can't get device instance of %s driver module.\n",
-			     module_name);
-			return -ENODEV;
-		}
-	} else {
-#endif
-		if ((n_device = (*constructor) (dev)) == NULL) {
-			symbol_put(constructor_name);
-			PERROR
-			    ("Can't get device instance of %s driver module.\n",
-			     module_name);
-			return -ENODEV;
-		}
-#ifdef BOSCH
-	}
-#endif
-
-	insert_to_device_list(n_device);
-	err =
-	    n_device->me_device_io_reset_device(n_device, NULL,
-						ME_IO_RESET_DEVICE_NO_FLAGS);
-	if (err) {
-		PERROR("Error while reseting device.\n");
-	} else {
-		PDEBUG("Reseting device was sucessful.\n");
-	}
-	return ME_ERRNO_SUCCESS;
-}
-
-static void release_instance(me_device_t *device)
-{
-	int vendor_id;
-	int device_id;
-	int serial_no;
-	int bus_type;
-	int bus_no;
-	int dev_no;
-	int func_no;
-	int plugged;
-
-	uint32_t dev_id;
-
-	char constructor_name[24] = "me0000_pci_constructor";
-
-	PDEBUG("executed.\n");
-
-	device->me_device_query_info_device(device,
-					    &vendor_id,
-					    &device_id,
-					    &serial_no,
-					    &bus_type,
-					    &bus_no,
-					    &dev_no, &func_no, &plugged);
-
-	dev_id = device_id;
-	device->me_device_destructor(device);
-
-	if (plugged != ME_PLUGGED_IN) {
-		PDEBUG("release: medummy_constructor\n");
-
-		symbol_put("medummy_constructor");
-	} else {
-		if ((dev_id & 0xF000) == 0x6000) {	// Exceptions: me61xx, me62xx, me63xx are handled by one driver.
-			dev_id &= 0xF0FF;
-		}
-
-		constructor_name[2] += (char)((dev_id >> 12) & 0x000F);
-		constructor_name[3] += (char)((dev_id >> 8) & 0x000F);
-		PDEBUG("release: %s\n", constructor_name);
-
-		symbol_put(constructor_name);
-	}
-}
-
-static int insert_to_device_list(me_device_t *n_device)
-{
-	me_device_t *o_device = NULL;
-
-	struct list_head *pos;
-	int n_vendor_id;
-	int n_device_id;
-	int n_serial_no;
-	int n_bus_type;
-	int n_bus_no;
-	int n_dev_no;
-	int n_func_no;
-	int n_plugged;
-	int o_vendor_id;
-	int o_device_id;
-	int o_serial_no;
-	int o_bus_type;
-	int o_bus_no;
-	int o_dev_no;
-	int o_func_no;
-	int o_plugged;
-
-	PDEBUG("executed.\n");
-
-	n_device->me_device_query_info_device(n_device,
-					      &n_vendor_id,
-					      &n_device_id,
-					      &n_serial_no,
-					      &n_bus_type,
-					      &n_bus_no,
-					      &n_dev_no,
-					      &n_func_no, &n_plugged);
-
-	down_write(&me_rwsem);
-
-	list_for_each(pos, &me_device_list) {
-		o_device = list_entry(pos, me_device_t, list);
-		o_device->me_device_query_info_device(o_device,
-						      &o_vendor_id,
-						      &o_device_id,
-						      &o_serial_no,
-						      &o_bus_type,
-						      &o_bus_no,
-						      &o_dev_no,
-						      &o_func_no, &o_plugged);
-
-		if (o_plugged == ME_PLUGGED_OUT) {
-			if (((o_vendor_id == n_vendor_id) &&
-			     (o_device_id == n_device_id) &&
-			     (o_serial_no == n_serial_no) &&
-			     (o_bus_type == n_bus_type)) ||
-			    ((o_vendor_id == n_vendor_id) &&
-			     (o_device_id == n_device_id) &&
-			     (o_bus_type == n_bus_type) &&
-			     (o_bus_no == n_bus_no) &&
-			     (o_dev_no == n_dev_no) &&
-			     (o_func_no == n_func_no))) {
-				n_device->list.prev = pos->prev;
-				n_device->list.next = pos->next;
-				pos->prev->next = &n_device->list;
-				pos->next->prev = &n_device->list;
-				release_instance(o_device);
-				break;
-			}
-		}
-	}
-
-	if (pos == &me_device_list) {
-		list_add_tail(&n_device->list, &me_device_list);
-	}
-
-	up_write(&me_rwsem);
-
-	return 0;
-}
-
-static void __devexit me_remove_pci(struct pci_dev *dev)
-{
-	int vendor_id = dev->vendor;
-	int device_id = dev->device;
-	int subsystem_vendor = dev->subsystem_vendor;
-	int subsystem_device = dev->subsystem_device;
-	int serial_no = (subsystem_device << 16) | subsystem_vendor;
-
-	PDEBUG("executed.\n");
-
-	PINFO("Vendor id = 0x%08X\n", vendor_id);
-	PINFO("Device id = 0x%08X\n", device_id);
-	PINFO("Serial Number = 0x%08X\n", serial_no);
-
-	replace_with_dummy(vendor_id, device_id, serial_no);
-}
-
-static int replace_with_dummy(int vendor_id, int device_id, int serial_no)
-{
-
-	struct list_head *pos;
-	me_device_t *n_device = NULL;
-	me_device_t *o_device = NULL;
-	int o_vendor_id;
-	int o_device_id;
-	int o_serial_no;
-	int o_bus_type;
-	int o_bus_no;
-	int o_dev_no;
-	int o_func_no;
-	int o_plugged;
-
-	PDEBUG("executed.\n");
-
-	down_write(&me_rwsem);
-
-	list_for_each(pos, &me_device_list) {
-		o_device = list_entry(pos, me_device_t, list);
-		o_device->me_device_query_info_device(o_device,
-						      &o_vendor_id,
-						      &o_device_id,
-						      &o_serial_no,
-						      &o_bus_type,
-						      &o_bus_no,
-						      &o_dev_no,
-						      &o_func_no, &o_plugged);
-
-		if (o_plugged == ME_PLUGGED_IN) {
-			if (((o_vendor_id == vendor_id) &&
-			     (o_device_id == device_id) &&
-			     (o_serial_no == serial_no))) {
-				n_device = get_dummy_instance(o_vendor_id,
-							      o_device_id,
-							      o_serial_no,
-							      o_bus_type,
-							      o_bus_no,
-							      o_dev_no,
-							      o_func_no);
-
-				if (!n_device) {
-					up_write(&me_rwsem);
-					PERROR("Cannot get dummy instance.\n");
-					return 1;
-				}
-
-				n_device->list.prev = pos->prev;
-
-				n_device->list.next = pos->next;
-				pos->prev->next = &n_device->list;
-				pos->next->prev = &n_device->list;
-				release_instance(o_device);
-				break;
-			}
-		}
-	}
-
-	up_write(&me_rwsem);
-
-	return 0;
-}
-
-static void clear_device_list(void)
-{
-
-	struct list_head *entry;
-	me_device_t *device;
-
-	// Clear the device info list .
-	down_write(&me_rwsem);
-
-	while (!list_empty(&me_device_list)) {
-		entry = me_device_list.next;
-		device = list_entry(entry, me_device_t, list);
-		list_del(entry);
-		release_instance(device);
-	}
-
-	up_write(&me_rwsem);
-}
-
-static int lock_driver(struct file *filep, int lock, int flags)
-{
-	int err = ME_ERRNO_SUCCESS;
-	me_device_t *device;
-
-	PDEBUG("executed.\n");
-
-	down_read(&me_rwsem);
-
-	spin_lock(&me_lock);
-
-	switch (lock) {
-
-	case ME_LOCK_SET:
-		if (me_count) {
-			PERROR
-			    ("Driver System is currently used by another process.\n");
-			err = ME_ERRNO_USED;
-		} else if ((me_filep != NULL) && (me_filep != filep)) {
-			PERROR
-			    ("Driver System is already logged by another process.\n");
-			err = ME_ERRNO_LOCKED;
-		} else {
-			list_for_each_entry(device, &me_device_list, list) {
-				err =
-				    device->me_device_lock_device(device, filep,
-								  ME_LOCK_CHECK,
-								  flags);
-
-				if (err)
-					break;
-			}
-
-			if (!err)
-				me_filep = filep;
-		}
-
-		break;
-
-	case ME_LOCK_RELEASE:
-		if ((me_filep != NULL) && (me_filep != filep)) {
-			err = ME_ERRNO_SUCCESS;
-		} else {
-			list_for_each_entry(device, &me_device_list, list) {
-				device->me_device_lock_device(device, filep,
-							      ME_LOCK_RELEASE,
-							      flags);
-			}
-
-			me_filep = NULL;
-		}
-
-		break;
-
-	default:
-		PERROR("Invalid lock specified.\n");
-
-		err = ME_ERRNO_INVALID_LOCK;
-
-		break;
-	}
-
-	spin_unlock(&me_lock);
-
-	up_read(&me_rwsem);
-
-	return err;
-}
-
-static int me_lock_driver(struct file *filep, me_lock_driver_t *arg)
-{
-	int err = 0;
-
-	me_lock_driver_t lock;
-
-	PDEBUG("executed.\n");
-
-	err = copy_from_user(&lock, arg, sizeof(me_lock_driver_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to kernel space.\n");
-		return -EFAULT;
-	}
-
-	lock.errno = lock_driver(filep, lock.lock, lock.flags);
-
-	err = copy_to_user(arg, &lock, sizeof(me_lock_driver_t));
-
-	if (err) {
-		PERROR("Can't copy query back to user space.\n");
-		return -EFAULT;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me_open(struct inode *inode_ptr, struct file *filep)
-{
-
-	PDEBUG("executed.\n");
-	// Nothing to do here.
-	return 0;
-}
-
-static int me_release(struct inode *inode_ptr, struct file *filep)
-{
-
-	PDEBUG("executed.\n");
-	lock_driver(filep, ME_LOCK_RELEASE, ME_LOCK_DRIVER_NO_FLAGS);
-
-	return 0;
-}
-
-static int me_query_version_main_driver(struct file *filep,
-					me_query_version_main_driver_t *arg)
-{
-	int err;
-	me_query_version_main_driver_t karg;
-
-	PDEBUG("executed.\n");
-
-	karg.version = ME_VERSION_DRIVER;
-	karg.errno = ME_ERRNO_SUCCESS;
-
-	err = copy_to_user(arg, &karg, sizeof(me_query_version_main_driver_t));
-
-	if (err) {
-		PERROR("Can't copy query back to user space.\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int me_config_load_device(struct file *filep,
-				 me_cfg_device_entry_t *karg, int device_no)
-{
-
-	int err = ME_ERRNO_SUCCESS;
-	int k = 0;
-
-	struct list_head *pos = NULL;
-	me_device_t *device = NULL;
-
-	PDEBUG("executed.\n");
-
-	list_for_each(pos, &me_device_list) {
-		if (k == device_no) {
-			device = list_entry(pos, me_device_t, list);
-			break;
-		}
-
-		k++;
-	}
-
-	if (pos == &me_device_list) {
-		PERROR("Invalid device number specified.\n");
-		return ME_ERRNO_INVALID_DEVICE;
-	} else {
-		spin_lock(&me_lock);
-
-		if ((me_filep != NULL) && (me_filep != filep)) {
-			spin_unlock(&me_lock);
-			PERROR("Resource is locked by another process.\n");
-			return ME_ERRNO_LOCKED;
-		} else {
-			me_count++;
-			spin_unlock(&me_lock);
-
-			err =
-			    device->me_device_config_load(device, filep, karg);
-
-			spin_lock(&me_lock);
-			me_count--;
-			spin_unlock(&me_lock);
-		}
-	}
-
-	return err;
-}
-
-static int me_config_load(struct file *filep, me_config_load_t *arg)
-{
-	int err;
-	int i;
-	me_config_load_t cfg_setup;
-	me_config_load_t karg_cfg_setup;
-
-	struct list_head *pos = NULL;
-
-	struct list_head new_list;
-	me_device_t *o_device;
-	me_device_t *n_device;
-	int o_vendor_id;
-	int o_device_id;
-	int o_serial_no;
-	int o_bus_type;
-	int o_bus_no;
-	int o_dev_no;
-	int o_func_no;
-	int o_plugged;
-
-	PDEBUG("executed.\n");
-
-	// Copy argument to kernel space.
-	err = copy_from_user(&karg_cfg_setup, arg, sizeof(me_config_load_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to kernel space.\n");
-		return -EFAULT;
-	}
-	// Allocate kernel buffer for device list.
-	cfg_setup.device_list =
-	    kmalloc(sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count,
-		    GFP_KERNEL);
-
-	if (!cfg_setup.device_list) {
-		PERROR("Can't get buffer %li for device list.\n",
-		       sizeof(me_cfg_device_entry_t) * karg_cfg_setup.count);
-		return -ENOMEM;
-	}
-	// Copy device list to kernel space.
-	err =
-	    copy_from_user(cfg_setup.device_list, karg_cfg_setup.device_list,
-			   sizeof(me_cfg_device_entry_t) *
-			   karg_cfg_setup.count);
-
-	if (err) {
-		PERROR("Can't copy device list to kernel space.\n");
-		kfree(cfg_setup.device_list);
-		return -EFAULT;
-	}
-
-	cfg_setup.count = karg_cfg_setup.count;
-
-	INIT_LIST_HEAD(&new_list);
-
-	down_write(&me_rwsem);
-
-	spin_lock(&me_lock);
-
-	if ((me_filep != NULL) && (me_filep != filep)) {
-		spin_unlock(&me_lock);
-		PERROR("Driver System is logged by another process.\n");
-		karg_cfg_setup.errno = ME_ERRNO_LOCKED;
-	} else {
-		me_count++;
-		spin_unlock(&me_lock);
-
-		for (i = 0; i < karg_cfg_setup.count; i++) {
-			PDEBUG("me_config_load() device=%d.\n", i);
-			if (cfg_setup.device_list[i].tcpip.access_type ==
-			    ME_ACCESS_TYPE_LOCAL) {
-				list_for_each(pos, &me_device_list) {
-					o_device =
-					    list_entry(pos, me_device_t, list);
-					o_device->
-					    me_device_query_info_device
-					    (o_device, &o_vendor_id,
-					     &o_device_id, &o_serial_no,
-					     &o_bus_type, &o_bus_no, &o_dev_no,
-					     &o_func_no, &o_plugged);
-
-					if (cfg_setup.device_list[i].info.
-					    hw_location.bus_type ==
-					    ME_BUS_TYPE_PCI) {
-						if (((o_vendor_id ==
-						      cfg_setup.device_list[i].
-						      info.vendor_id)
-						     && (o_device_id ==
-							 cfg_setup.
-							 device_list[i].info.
-							 device_id)
-						     && (o_serial_no ==
-							 cfg_setup.
-							 device_list[i].info.
-							 serial_no)
-						     && (o_bus_type ==
-							 cfg_setup.
-							 device_list[i].info.
-							 hw_location.bus_type))
-						    ||
-						    ((o_vendor_id ==
-						      cfg_setup.device_list[i].
-						      info.vendor_id)
-						     && (o_device_id ==
-							 cfg_setup.
-							 device_list[i].info.
-							 device_id)
-						     && (o_bus_type ==
-							 cfg_setup.
-							 device_list[i].info.
-							 hw_location.bus_type)
-						     && (o_bus_no ==
-							 cfg_setup.
-							 device_list[i].info.
-							 hw_location.pci.bus_no)
-						     && (o_dev_no ==
-							 cfg_setup.
-							 device_list[i].info.
-							 hw_location.pci.
-							 device_no)
-						     && (o_func_no ==
-							 cfg_setup.
-							 device_list[i].info.
-							 hw_location.pci.
-							 function_no))) {
-							list_move_tail(pos,
-								       &new_list);
-							break;
-						}
-					}
-/*
-					else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB)
-					{
-						if (((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) &&
-						        (o_device_id == cfg_setup.device_list[i].info.device_id) &&
-						        (o_serial_no == cfg_setup.device_list[i].info.serial_no) &&
-						        (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type)) ||
-						        ((o_vendor_id == cfg_setup.device_list[i].info.vendor_id) &&
-						         (o_device_id == cfg_setup.device_list[i].info.device_id) &&
-						         (o_bus_type == cfg_setup.device_list[i].info.hw_location.bus_type) &&
-						         (o_bus_no == cfg_setup.device_list[i].info.hw_location.usb.root_hub_no)))
-						{
-							list_move_tail(pos, &new_list);
-							break;
-						}
-					}
-*/
-					else {
-						PERROR("Wrong bus type: %d.\n",
-						       cfg_setup.device_list[i].
-						       info.hw_location.
-						       bus_type);
-					}
-				}
-
-				if (pos == &me_device_list) {	// Device is not already in the list
-					if (cfg_setup.device_list[i].info.
-					    hw_location.bus_type ==
-					    ME_BUS_TYPE_PCI) {
-						n_device =
-						    get_dummy_instance
-						    (cfg_setup.device_list[i].
-						     info.vendor_id,
-						     cfg_setup.device_list[i].
-						     info.device_id,
-						     cfg_setup.device_list[i].
-						     info.serial_no,
-						     cfg_setup.device_list[i].
-						     info.hw_location.bus_type,
-						     cfg_setup.device_list[i].
-						     info.hw_location.pci.
-						     bus_no,
-						     cfg_setup.device_list[i].
-						     info.hw_location.pci.
-						     device_no,
-						     cfg_setup.device_list[i].
-						     info.hw_location.pci.
-						     function_no);
-
-						if (!n_device) {
-							PERROR
-							    ("Can't get dummy instance.\n");
-							kfree(cfg_setup.
-							      device_list);
-							spin_lock(&me_lock);
-							me_count--;
-							spin_unlock(&me_lock);
-							up_write(&me_rwsem);
-							return -EFAULT;
-						}
-
-						list_add_tail(&n_device->list,
-							      &new_list);
-					}
-/*
-					else if (cfg_setup.device_list[i].info.hw_location.bus_type == ME_BUS_TYPE_USB)
-					{
-						n_device = get_dummy_instance(
-						               cfg_setup.device_list[i].info.vendor_id,
-						               cfg_setup.device_list[i].info.device_id,
-						               cfg_setup.device_list[i].info.serial_no,
-						               cfg_setup.device_list[i].info.hw_location.bus_type,
-						               cfg_setup.device_list[i].info.hw_location.usb.root_hub_no,
-						               0,
-						               0);
-
-						if (!n_device)
-						{
-							PERROR("Can't get dummy instance.\n");
-							kfree(cfg_setup.device_list);
-							spin_lock(&me_lock);
-							me_count--;
-							spin_unlock(&me_lock);
-							up_write(&me_rwsem);
-							return -EFAULT;
-						}
-
-						list_add_tail(&n_device->list, &new_list);
-					}
-*/
-				}
-			} else {
-				n_device = get_dummy_instance(0,
-							      0, 0, 0, 0, 0, 0);
-
-				if (!n_device) {
-					PERROR("Can't get dummy instance.\n");
-					kfree(cfg_setup.device_list);
-					spin_lock(&me_lock);
-					me_count--;
-					spin_unlock(&me_lock);
-					up_write(&me_rwsem);
-					return -EFAULT;
-				}
-
-				list_add_tail(&n_device->list, &new_list);
-			}
-		}
-
-		while (!list_empty(&me_device_list)) {
-			o_device =
-			    list_entry(me_device_list.next, me_device_t, list);
-			o_device->me_device_query_info_device(o_device,
-							      &o_vendor_id,
-							      &o_device_id,
-							      &o_serial_no,
-							      &o_bus_type,
-							      &o_bus_no,
-							      &o_dev_no,
-							      &o_func_no,
-							      &o_plugged);
-
-			if (o_plugged == ME_PLUGGED_IN) {
-				list_move_tail(me_device_list.next, &new_list);
-			} else {
-				list_del(me_device_list.next);
-				release_instance(o_device);
-			}
-		}
-
-		// Move temporary new list to global driver list.
-		list_splice(&new_list, &me_device_list);
-
-		karg_cfg_setup.errno = ME_ERRNO_SUCCESS;
-	}
-
-	for (i = 0; i < cfg_setup.count; i++) {
-
-		karg_cfg_setup.errno =
-		    me_config_load_device(filep, &cfg_setup.device_list[i], i);
-		if (karg_cfg_setup.errno) {
-			PERROR("me_config_load_device(%d)=%d\n", i,
-			       karg_cfg_setup.errno);
-			break;
-		}
-	}
-
-	spin_lock(&me_lock);
-
-	me_count--;
-	spin_unlock(&me_lock);
-	up_write(&me_rwsem);
-
-	err = copy_to_user(arg, &karg_cfg_setup, sizeof(me_config_load_t));
-
-	if (err) {
-		PERROR("Can't copy config list to user space.\n");
-		kfree(cfg_setup.device_list);
-		return -EFAULT;
-	}
-
-	kfree(cfg_setup.device_list);
-	return 0;
-}
-
-static int me_io_stream_start(struct file *filep, me_io_stream_start_t *arg)
-{
-	int err;
-	int i, k;
-
-	struct list_head *pos;
-	me_device_t *device;
-	me_io_stream_start_t karg;
-	meIOStreamStart_t *list;
-
-	PDEBUG("executed.\n");
-
-	err = copy_from_user(&karg, arg, sizeof(me_io_stream_start_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to kernel space.\n");
-		return -EFAULT;
-	}
-
-	karg.errno = ME_ERRNO_SUCCESS;
-
-	list = kmalloc(sizeof(meIOStreamStart_t) * karg.count, GFP_KERNEL);
-
-	if (!list) {
-		PERROR("Can't get buffer for start list.\n");
-		return -ENOMEM;
-	}
-
-	err =
-	    copy_from_user(list, karg.start_list,
-			   sizeof(meIOStreamStart_t) * karg.count);
-
-	if (err) {
-		PERROR("Can't copy start list to kernel space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	spin_lock(&me_lock);
-
-	if ((me_filep != NULL) && (me_filep != filep)) {
-		spin_unlock(&me_lock);
-		PERROR("Driver System is logged by another process.\n");
-
-		for (i = 0; i < karg.count; i++) {
-			list[i].iErrno = ME_ERRNO_LOCKED;
-		}
-	} else {
-		me_count++;
-		spin_unlock(&me_lock);
-
-		for (i = 0; i < karg.count; i++) {
-			down_read(&me_rwsem);
-			k = 0;
-			list_for_each(pos, &me_device_list) {
-				if (k == list[i].iDevice) {
-					device =
-					    list_entry(pos, me_device_t, list);
-					break;
-				}
-
-				k++;
-			}
-
-			if (pos == &me_device_list) {
-				up_read(&me_rwsem);
-				PERROR("Invalid device number specified.\n");
-				list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
-				karg.errno = ME_ERRNO_INVALID_DEVICE;
-				break;
-			} else {
-				list[i].iErrno =
-				    device->me_device_io_stream_start(device,
-								      filep,
-								      list[i].
-								      iSubdevice,
-								      list[i].
-								      iStartMode,
-								      list[i].
-								      iTimeOut,
-								      list[i].
-								      iFlags);
-
-				if (list[i].iErrno) {
-					up_read(&me_rwsem);
-					karg.errno = list[i].iErrno;
-					break;
-				}
-			}
-
-			up_read(&me_rwsem);
-		}
-
-		spin_lock(&me_lock);
-
-		me_count--;
-		spin_unlock(&me_lock);
-	}
-
-	err = copy_to_user(arg, &karg, sizeof(me_io_stream_start_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to user space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	err =
-	    copy_to_user(karg.start_list, list,
-			 sizeof(meIOStreamStart_t) * karg.count);
-
-	if (err) {
-		PERROR("Can't copy start list to user space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	kfree(list);
-
-	return err;
-}
-
-static int me_io_single(struct file *filep, me_io_single_t *arg)
-{
-	int err;
-	int i, k;
-
-	struct list_head *pos;
-	me_device_t *device;
-	me_io_single_t karg;
-	meIOSingle_t *list;
-
-	PDEBUG("executed.\n");
-
-	err = copy_from_user(&karg, arg, sizeof(me_io_single_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to kernel space.\n");
-		return -EFAULT;
-	}
-
-	karg.errno = ME_ERRNO_SUCCESS;
-
-	list = kmalloc(sizeof(meIOSingle_t) * karg.count, GFP_KERNEL);
-
-	if (!list) {
-		PERROR("Can't get buffer for single list.\n");
-		return -ENOMEM;
-	}
-
-	err =
-	    copy_from_user(list, karg.single_list,
-			   sizeof(meIOSingle_t) * karg.count);
-
-	if (err) {
-		PERROR("Can't copy single list to kernel space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	spin_lock(&me_lock);
-
-	if ((me_filep != NULL) && (me_filep != filep)) {
-		spin_unlock(&me_lock);
-		PERROR("Driver System is logged by another process.\n");
-
-		for (i = 0; i < karg.count; i++) {
-			list[i].iErrno = ME_ERRNO_LOCKED;
-		}
-	} else {
-		me_count++;
-		spin_unlock(&me_lock);
-
-		for (i = 0; i < karg.count; i++) {
-			k = 0;
-
-			down_read(&me_rwsem);
-
-			list_for_each(pos, &me_device_list) {
-				if (k == list[i].iDevice) {
-					device =
-					    list_entry(pos, me_device_t, list);
-					break;
-				}
-
-				k++;
-			}
-
-			if (pos == &me_device_list) {
-				up_read(&me_rwsem);
-				PERROR("Invalid device number specified.\n");
-				list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
-				karg.errno = ME_ERRNO_INVALID_DEVICE;
-				break;
-			} else {
-				if (list[i].iDir == ME_DIR_OUTPUT) {
-					list[i].iErrno =
-					    device->
-					    me_device_io_single_write(device,
-								      filep,
-								      list[i].
-								      iSubdevice,
-								      list[i].
-								      iChannel,
-								      list[i].
-								      iValue,
-								      list[i].
-								      iTimeOut,
-								      list[i].
-								      iFlags);
-
-					if (list[i].iErrno) {
-						up_read(&me_rwsem);
-						karg.errno = list[i].iErrno;
-						break;
-					}
-				} else if (list[i].iDir == ME_DIR_INPUT) {
-					list[i].iErrno =
-					    device->
-					    me_device_io_single_read(device,
-								     filep,
-								     list[i].
-								     iSubdevice,
-								     list[i].
-								     iChannel,
-								     &list[i].
-								     iValue,
-								     list[i].
-								     iTimeOut,
-								     list[i].
-								     iFlags);
-
-					if (list[i].iErrno) {
-						up_read(&me_rwsem);
-						karg.errno = list[i].iErrno;
-						break;
-					}
-				} else {
-					up_read(&me_rwsem);
-					PERROR
-					    ("Invalid single direction specified.\n");
-					list[i].iErrno = ME_ERRNO_INVALID_DIR;
-					karg.errno = ME_ERRNO_INVALID_DIR;
-					break;
-				}
-			}
-
-			up_read(&me_rwsem);
-		}
-
-		spin_lock(&me_lock);
-
-		me_count--;
-		spin_unlock(&me_lock);
-	}
-
-	err = copy_to_user(arg, &karg, sizeof(me_io_single_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to user space.\n");
-		return -EFAULT;
-	}
-
-	err =
-	    copy_to_user(karg.single_list, list,
-			 sizeof(meIOSingle_t) * karg.count);
-
-	if (err) {
-		PERROR("Can't copy single list to user space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	kfree(list);
-
-	return err;
-}
-
-static int me_io_stream_config(struct file *filep, me_io_stream_config_t *arg)
-{
-	int err;
-	int k = 0;
-
-	struct list_head *pos;
-	me_device_t *device;
-	me_io_stream_config_t karg;
-	meIOStreamConfig_t *list;
-
-	PDEBUG("executed.\n");
-
-	err = copy_from_user(&karg, arg, sizeof(me_io_stream_config_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to kernel space.\n");
-		return -EFAULT;
-	}
-
-	list = kmalloc(sizeof(meIOStreamConfig_t) * karg.count, GFP_KERNEL);
-
-	if (!list) {
-		PERROR("Can't get buffer for config list.\n");
-		return -ENOMEM;
-	}
-
-	err =
-	    copy_from_user(list, karg.config_list,
-			   sizeof(meIOStreamConfig_t) * karg.count);
-
-	if (err) {
-		PERROR("Can't copy config list to kernel space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	spin_lock(&me_lock);
-
-	if ((me_filep != NULL) && (me_filep != filep)) {
-		spin_unlock(&me_lock);
-		PERROR("Driver System is logged by another process.\n");
-		karg.errno = ME_ERRNO_LOCKED;
-	} else {
-		me_count++;
-		spin_unlock(&me_lock);
-
-		down_read(&me_rwsem);
-
-		list_for_each(pos, &me_device_list) {
-			if (k == karg.device) {
-				device = list_entry(pos, me_device_t, list);
-				break;
-			}
-
-			k++;
-		}
-
-		if (pos == &me_device_list) {
-			PERROR("Invalid device number specified.\n");
-			karg.errno = ME_ERRNO_INVALID_DEVICE;
-		} else {
-			karg.errno =
-			    device->me_device_io_stream_config(device, filep,
-							       karg.subdevice,
-							       list, karg.count,
-							       &karg.trigger,
-							       karg.
-							       fifo_irq_threshold,
-							       karg.flags);
-		}
-
-		up_read(&me_rwsem);
-
-		spin_lock(&me_lock);
-		me_count--;
-		spin_unlock(&me_lock);
-	}
-
-	err = copy_to_user(arg, &karg, sizeof(me_io_stream_config_t));
-
-	if (err) {
-		PERROR("Can't copy back to user space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	kfree(list);
-
-	return err;
-}
-
-static int me_query_number_devices(struct file *filep,
-				   me_query_number_devices_t *arg)
-{
-	int err;
-	me_query_number_devices_t karg;
-
-	struct list_head *pos;
-
-	PDEBUG("executed.\n");
-
-	karg.number = 0;
-	down_read(&me_rwsem);
-	list_for_each(pos, &me_device_list) {
-		karg.number++;
-	}
-
-	up_read(&me_rwsem);
-
-	karg.errno = ME_ERRNO_SUCCESS;
-
-	err = copy_to_user(arg, &karg, sizeof(me_query_number_devices_t));
-
-	if (err) {
-		PERROR("Can't copy query back to user space.\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
-static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t *arg)
-{
-	int err;
-	int i, k;
-
-	struct list_head *pos;
-	me_device_t *device;
-	me_io_stream_stop_t karg;
-	meIOStreamStop_t *list;
-
-	PDEBUG("executed.\n");
-
-	err = copy_from_user(&karg, arg, sizeof(me_io_stream_stop_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to kernel space.\n");
-		return -EFAULT;
-	}
-
-	karg.errno = ME_ERRNO_SUCCESS;
-
-	list = kmalloc(sizeof(meIOStreamStop_t) * karg.count, GFP_KERNEL);
-
-	if (!list) {
-		PERROR("Can't get buffer for stop list.\n");
-		return -ENOMEM;
-	}
-
-	err =
-	    copy_from_user(list, karg.stop_list,
-			   sizeof(meIOStreamStop_t) * karg.count);
-
-	if (err) {
-		PERROR("Can't copy stop list to kernel space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	spin_lock(&me_lock);
-
-	if ((me_filep != NULL) && (me_filep != filep)) {
-		spin_unlock(&me_lock);
-		PERROR("Driver System is logged by another process.\n");
-
-		for (i = 0; i < karg.count; i++) {
-			list[i].iErrno = ME_ERRNO_LOCKED;
-		}
-	} else {
-		me_count++;
-		spin_unlock(&me_lock);
-
-		for (i = 0; i < karg.count; i++) {
-			k = 0;
-			down_read(&me_rwsem);
-			list_for_each(pos, &me_device_list) {
-				if (k == list[i].iDevice) {
-					device =
-					    list_entry(pos, me_device_t, list);
-					break;
-				}
-
-				k++;
-			}
-
-			if (pos == &me_device_list) {
-				up_read(&me_rwsem);
-				PERROR("Invalid device number specified.\n");
-				list[i].iErrno = ME_ERRNO_INVALID_DEVICE;
-				karg.errno = ME_ERRNO_INVALID_DEVICE;
-				break;
-			} else {
-				list[i].iErrno =
-				    device->me_device_io_stream_stop(device,
-								     filep,
-								     list[i].
-								     iSubdevice,
-								     list[i].
-								     iStopMode,
-								     list[i].
-								     iFlags);
-
-				if (list[i].iErrno) {
-					up_read(&me_rwsem);
-					karg.errno = list[i].iErrno;
-					break;
-				}
-			}
-
-			up_read(&me_rwsem);
-		}
-
-		spin_lock(&me_lock);
-
-		me_count--;
-		spin_unlock(&me_lock);
-	}
-
-	err = copy_to_user(arg, &karg, sizeof(me_io_stream_stop_t));
-
-	if (err) {
-		PERROR("Can't copy arguments to user space.\n");
-		return -EFAULT;
-	}
-
-	err =
-	    copy_to_user(karg.stop_list, list,
-			 sizeof(meIOStreamStop_t) * karg.count);
-
-	if (err) {
-		PERROR("Can't copy stop list to user space.\n");
-		kfree(list);
-		return -EFAULT;
-	}
-
-	kfree(list);
-
-	return err;
-}
-
-/*  //me_probe_usb
-static int me_probe_usb(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	//int err;
-	//me_usb_constructor_t *constructor = NULL;
-	me_device_t *n_device = NULL;
-
-	PDEBUG("executed.\n");
-
-	switch (id->idProduct)
-	{
-			case USB_DEVICE_ID_MEPHISTO_S1:
-				if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){
-					err = request_module(MEPHISTO_S1_NAME);
-					if(err){
-						PERROR("Error while request for module %s.\n", MEPHISTO_S1_NAME);
-						return -ENODEV;
-					}
-					if((constructor = symbol_get(mephisto_s1_constructor)) == NULL){
-						PERROR("Can't get %s driver module constructor.\n", MEPHISTO_S1_NAME);
-						return -ENODEV;
-					}
-				}
-
-				if((n_device = (*constructor)(interface)) == NULL){
-					symbol_put(mephisto_s1_constructor);
-					PERROR("Can't get device instance of %s driver module.\n", MEPHISTO_S1_NAME);
-					return -ENODEV;
-				}
-
-				break;
-
-		default:
-			PERROR("Invalid product id.\n");
-
-			return -EINVAL;
-	}
-
-	return insert_to_device_list(n_device);
-}
-*/
-
-/*  //me_disconnect_usb
-static void me_disconnect_usb(struct usb_interface *interface)
-{
-
-	struct usb_device *device = interface_to_usbdev(interface);
-	int vendor_id = device->descriptor.idVendor;
-	int device_id = device->descriptor.idProduct;
-	int serial_no;
-
-	sscanf(&device->serial[2], "%x", &serial_no);
-
-	PDEBUG("executed.\n");
-
-	PINFO("Vendor id = 0x%08X\n", vendor_id);
-	PINFO("Device id = 0x%08X\n", device_id);
-	PINFO("Serial Number = 0x%08X\n", serial_no);
-
-	replace_with_dummy(vendor_id, device_id, serial_no);
-}
-*/
-
-static int me_ioctl(struct inode *inodep,
-		    struct file *filep, unsigned int service, unsigned long arg)
-{
-
-	PDEBUG("executed.\n");
-
-	if (_IOC_TYPE(service) != MEMAIN_MAGIC) {
-		PERROR("Invalid magic number.\n");
-		return -ENOTTY;
-	}
-
-	PDEBUG("service number: 0x%x.\n", service);
-
-	switch (service) {
-	case ME_IO_IRQ_ENABLE:
-		return me_io_irq_start(filep, (me_io_irq_start_t *) arg);
-
-	case ME_IO_IRQ_WAIT:
-		return me_io_irq_wait(filep, (me_io_irq_wait_t *) arg);
-
-	case ME_IO_IRQ_DISABLE:
-		return me_io_irq_stop(filep, (me_io_irq_stop_t *) arg);
-
-	case ME_IO_RESET_DEVICE:
-		return me_io_reset_device(filep, (me_io_reset_device_t *) arg);
-
-	case ME_IO_RESET_SUBDEVICE:
-		return me_io_reset_subdevice(filep,
-					     (me_io_reset_subdevice_t *) arg);
-
-	case ME_IO_SINGLE_CONFIG:
-		return me_io_single_config(filep,
-					   (me_io_single_config_t *) arg);
-
-	case ME_IO_SINGLE:
-		return me_io_single(filep, (me_io_single_t *) arg);
-
-	case ME_IO_STREAM_CONFIG:
-		return me_io_stream_config(filep,
-					   (me_io_stream_config_t *) arg);
-
-	case ME_IO_STREAM_NEW_VALUES:
-		return me_io_stream_new_values(filep,
-					       (me_io_stream_new_values_t *)
-					       arg);
-
-	case ME_IO_STREAM_READ:
-		return me_io_stream_read(filep, (me_io_stream_read_t *) arg);
-
-	case ME_IO_STREAM_START:
-		return me_io_stream_start(filep, (me_io_stream_start_t *) arg);
-
-	case ME_IO_STREAM_STATUS:
-		return me_io_stream_status(filep,
-					   (me_io_stream_status_t *) arg);
-
-	case ME_IO_STREAM_STOP:
-		return me_io_stream_stop(filep, (me_io_stream_stop_t *) arg);
-
-	case ME_IO_STREAM_WRITE:
-		return me_io_stream_write(filep, (me_io_stream_write_t *) arg);
-
-	case ME_LOCK_DRIVER:
-		return me_lock_driver(filep, (me_lock_driver_t *) arg);
-
-	case ME_LOCK_DEVICE:
-		return me_lock_device(filep, (me_lock_device_t *) arg);
-
-	case ME_LOCK_SUBDEVICE:
-		return me_lock_subdevice(filep, (me_lock_subdevice_t *) arg);
-
-	case ME_QUERY_INFO_DEVICE:
-		return me_query_info_device(filep,
-					    (me_query_info_device_t *) arg);
-
-	case ME_QUERY_DESCRIPTION_DEVICE:
-		return me_query_description_device(filep,
-						   (me_query_description_device_t
-						    *) arg);
-
-	case ME_QUERY_NAME_DEVICE:
-		return me_query_name_device(filep,
-					    (me_query_name_device_t *) arg);
-
-	case ME_QUERY_NAME_DEVICE_DRIVER:
-		return me_query_name_device_driver(filep,
-						   (me_query_name_device_driver_t
-						    *) arg);
-
-	case ME_QUERY_NUMBER_DEVICES:
-		return me_query_number_devices(filep,
-					       (me_query_number_devices_t *)
-					       arg);
-
-	case ME_QUERY_NUMBER_SUBDEVICES:
-		return me_query_number_subdevices(filep,
-						  (me_query_number_subdevices_t
-						   *) arg);
-
-	case ME_QUERY_NUMBER_CHANNELS:
-		return me_query_number_channels(filep,
-						(me_query_number_channels_t *)
-						arg);
-
-	case ME_QUERY_NUMBER_RANGES:
-		return me_query_number_ranges(filep,
-					      (me_query_number_ranges_t *) arg);
-
-	case ME_QUERY_RANGE_BY_MIN_MAX:
-		return me_query_range_by_min_max(filep,
-						 (me_query_range_by_min_max_t *)
-						 arg);
-
-	case ME_QUERY_RANGE_INFO:
-		return me_query_range_info(filep,
-					   (me_query_range_info_t *) arg);
-
-	case ME_QUERY_SUBDEVICE_BY_TYPE:
-		return me_query_subdevice_by_type(filep,
-						  (me_query_subdevice_by_type_t
-						   *) arg);
-
-	case ME_QUERY_SUBDEVICE_TYPE:
-		return me_query_subdevice_type(filep,
-					       (me_query_subdevice_type_t *)
-					       arg);
-
-	case ME_QUERY_SUBDEVICE_CAPS:
-		return me_query_subdevice_caps(filep,
-					       (me_query_subdevice_caps_t *)
-					       arg);
-
-	case ME_QUERY_SUBDEVICE_CAPS_ARGS:
-		return me_query_subdevice_caps_args(filep,
-						    (me_query_subdevice_caps_args_t
-						     *) arg);
-
-	case ME_QUERY_TIMER:
-		return me_query_timer(filep, (me_query_timer_t *) arg);
-
-	case ME_QUERY_VERSION_MAIN_DRIVER:
-		return me_query_version_main_driver(filep,
-						    (me_query_version_main_driver_t
-						     *) arg);
-
-	case ME_QUERY_VERSION_DEVICE_DRIVER:
-		return me_query_version_device_driver(filep,
-						      (me_query_version_device_driver_t
-						       *) arg);
-
-	case ME_CONFIG_LOAD:
-		return me_config_load(filep, (me_config_load_t *) arg);
-	}
-
-	PERROR("Invalid ioctl number.\n");
-	return -ENOTTY;
-}
-
-static struct miscdevice me_miscdev = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = MEMAIN_NAME,
-	.fops = &me_file_operations,
-};
-
-// Init and exit of module.
-static int memain_init(void)
-{
-	int result = 0;
-
-	PDEBUG("executed.\n");
-
-	// Register pci driver. This will return 0 if the PCI subsystem is not available.
-	result = pci_register_driver(&me_pci_driver);
-
-	if (result < 0) {
-		PERROR("Can't register pci driver.\n");
-		goto INIT_ERROR_1;
-	}
-
-/*
-	// Register usb driver. This will return -ENODEV if no USB subsystem is available.
-	result = usb_register(&me_usb_driver);
-
-	if (result)
-	{
-		if (result == -ENODEV)
-		{
-			PERROR("No USB subsystem available.\n");
-		}
-		else
-		{
-			PERROR("Can't register usb driver.\n");
-			goto INIT_ERROR_2;
-		}
-	}
-*/
-	result = misc_register(&me_miscdev);
-	if (result < 0) {
-		printk(KERN_ERR MEMAIN_NAME ": can't register misc device\n");
-		goto INIT_ERROR_3;
-	}
-
-	return 0;
-
-      INIT_ERROR_3:
-//      usb_deregister(&me_usb_driver);
-
-//INIT_ERROR_2:
-	pci_unregister_driver(&me_pci_driver);
-	clear_device_list();
-
-      INIT_ERROR_1:
-	return result;
-}
-
-static void __exit memain_exit(void)
-{
-	PDEBUG("executed.\n");
-
-	misc_deregister(&me_miscdev);
-	pci_unregister_driver(&me_pci_driver);
-//      usb_deregister(&me_usb_driver);
-	clear_device_list();
-}
-
-module_init(memain_init);
-module_exit(memain_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR
-    ("Guenter Gebhardt <g.gebhardt@meilhaus.de> & Krzysztof Gantzke <k.gantzke@meilhaus.de>");
-MODULE_DESCRIPTION("Central module for Meilhaus Driver System.");
-MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/memain.h b/drivers/staging/meilhaus/memain.h
deleted file mode 100644
index 48f8367..0000000
--- a/drivers/staging/meilhaus/memain.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : memain.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- */
-
-#ifndef _MEMAIN_H_
-#define _MEMAIN_H_
-
-#include "meinternal.h"
-
-#include "meids.h"
-#include "medebug.h"
-
-#include "medevice.h"
-/*#include "me1000_device.h"
-#include "me1400_device.h"
-#include "me1600_device.h"*/
-#include "me4600_device.h"
-/*#include "me6000_device.h"
-#include "me0600_device.h"
-#include "me8100_device.h"
-#include "me8200_device.h"
-#include "me0900_device.h"*/
-#include "medummy.h"
-
-#ifdef __KERNEL__
-
-/*=============================================================================
-  Templates
-  ===========================================================================*/
-
-#define ME_LOCK_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)	\
-static int CALL(struct file *filep, TYPE *arg){	\
-	int err = 0; \
-	int k = 0; \
-	struct list_head *pos; \
-	me_device_t *device; \
-	TYPE karg; \
-	\
-	PDEBUG("executed.\n"); \
-	\
-	err = copy_from_user(&karg, arg, sizeof(TYPE)); \
-	if(err){ \
-		PERROR("Can't copy arguments to kernel space\n"); \
-		return -EFAULT; \
-	} \
-	\
-	down_read(&me_rwsem);	\
-	\
-	list_for_each(pos, &me_device_list){	\
-		if(k == karg.device){	\
-			device = list_entry(pos, me_device_t, list);	\
-				break;	\
-		}	\
-		k++;	\
-	}	\
-	\
-	if(pos == &me_device_list){ \
-		PERROR("Invalid device number specified\n"); \
-		karg.errno = ME_ERRNO_INVALID_DEVICE; \
-	} \
-	else{ \
-		spin_lock(&me_lock);	\
-		if((me_filep != NULL) && (me_filep != filep)){	\
-			spin_unlock(&me_lock);	\
-			PERROR("Resource is locked by another process\n");	\
-			if(karg.lock == ME_LOCK_SET)	\
-				karg.errno = ME_ERRNO_LOCKED;	\
-			else if(karg.lock == ME_LOCK_RELEASE)	\
-				karg.errno = ME_ERRNO_SUCCESS;	\
-			else{	\
-				PERROR("Invalid lock specified\n");	\
-				karg.errno = ME_ERRNO_INVALID_LOCK;	\
-			}\
-		}	\
-		else {	\
-			me_count++;	\
-			spin_unlock(&me_lock);	\
-			\
-			karg.errno = device->DEV_CALL ARGS;	\
-			\
-			spin_lock(&me_lock);	\
-			me_count--;	\
-			spin_unlock(&me_lock);	\
-		}	\
-	} \
-	\
-	up_read(&me_rwsem);	\
-	\
-	err = copy_to_user(arg, &karg, sizeof(TYPE)); \
-	if(err){ \
-		PERROR("Can't copy arguments back to user space\n"); \
-		return -EFAULT; \
-	} \
-	\
-	return ME_ERRNO_SUCCESS; \
-}
-
-#define ME_IO_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)	\
-static int CALL(struct file *filep, TYPE *arg){	\
-	int err = 0; \
-	int k = 0; \
-	struct list_head *pos; \
-	me_device_t *device; \
-	TYPE karg; \
-	\
-	PDEBUG("executed.\n"); \
-	\
-	err = copy_from_user(&karg, arg, sizeof(TYPE)); \
-	if(err){ \
-		PERROR("Can't copy arguments to kernel space\n"); \
-		return -EFAULT; \
-	} \
-	\
-	down_read(&me_rwsem);	\
-	\
-	list_for_each(pos, &me_device_list){	\
-		if(k == karg.device){	\
-			device = list_entry(pos, me_device_t, list);	\
-				break;	\
-		}	\
-		k++;	\
-	}	\
-	\
-	if(pos == &me_device_list){ \
-		PERROR("Invalid device number specified\n"); \
-		karg.errno = ME_ERRNO_INVALID_DEVICE; \
-	} \
-	else{ \
-		spin_lock(&me_lock);	\
-		if((me_filep != NULL) && (me_filep != filep)){	\
-			spin_unlock(&me_lock);	\
-			PERROR("Resource is locked by another process\n");	\
-			karg.errno = ME_ERRNO_LOCKED;	\
-		}	\
-		else {	\
-			me_count++;	\
-			spin_unlock(&me_lock);	\
-			\
-			karg.errno = device->DEV_CALL ARGS;	\
-			\
-			spin_lock(&me_lock);	\
-			me_count--;	\
-			spin_unlock(&me_lock);	\
-		}	\
-	} \
-	\
-	up_read(&me_rwsem);	\
-	\
-	err = copy_to_user(arg, &karg, sizeof(TYPE)); \
-	if(err){ \
-		PERROR("Can't copy arguments back to user space\n"); \
-		return -EFAULT; \
-	} \
- \
-	return ME_ERRNO_SUCCESS; \
-}
-
-#define ME_QUERY_MULTIPLEX_STR_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)	\
-static int CALL(struct file *filep, TYPE *arg){	\
-	int err = 0;	\
-	int k = 0;	\
-	struct list_head *pos;	\
-	me_device_t *device;	\
-	char *msg = NULL;	\
-	TYPE karg;	\
-	\
-	PDEBUG("executed.\n"); \
-	\
-	err = copy_from_user(&karg, arg, sizeof(TYPE));	\
-	if(err){	\
-		PERROR("Can't copy arguments to kernel space\n");	\
-		return -EFAULT;	\
-	}	\
-	\
-	down_read(&me_rwsem);	\
-	\
-	list_for_each(pos, &me_device_list){	\
-		if(k == karg.device){	\
-			device = list_entry(pos, me_device_t, list);	\
-				break;	\
-		}	\
-		k++;	\
-	}	\
-	\
-	if(pos == &me_device_list){	\
-		PERROR("Invalid device number specified\n");	\
-		karg.errno = ME_ERRNO_INVALID_DEVICE;	\
-	}	\
-	else{	\
-		karg.errno = device->DEV_CALL ARGS;	\
-		if(!karg.errno){	\
-			if((strlen(msg) + 1) > karg.count){	\
-				PERROR("User buffer for device name is to little\n");	\
-				karg.errno = ME_ERRNO_USER_BUFFER_SIZE;	\
-			}	\
-			else{	\
-				err = copy_to_user(karg.name, msg, strlen(msg) + 1);	\
-				if(err){	\
-					PERROR("Can't copy device name to user space\n");	\
-					return -EFAULT;	\
-				}	\
-			}	\
-		}	\
-	}	\
-	\
-	up_read(&me_rwsem);	\
-	\
-	err = copy_to_user(arg, &karg, sizeof(TYPE));	\
-	if(err){	\
-		PERROR("Can't copy query back to user space\n");	\
-		return -EFAULT;	\
-	}	\
-	\
-	return ME_ERRNO_SUCCESS;	\
-}
-
-#define ME_QUERY_MULTIPLEX_TEMPLATE(NAME, TYPE, CALL, DEV_CALL, ARGS)	\
-static int CALL(struct file *filep, TYPE *arg){	\
-	int err = 0;	\
-	int k = 0;	\
-	struct list_head *pos;	\
-	me_device_t *device;	\
-	TYPE karg;	\
-		\
-	PDEBUG("executed.\n"); \
-	 \
-	err = copy_from_user(&karg, arg, sizeof(TYPE));	\
-	if(err){	\
-		PERROR("Can't copy arguments from user space\n");	\
-		return -EFAULT;	\
-	}	\
-	\
-	down_read(&me_rwsem);	\
-	\
-	list_for_each(pos, &me_device_list){	\
-		if(k == karg.device){	\
-			device = list_entry(pos, me_device_t, list);	\
-			break;	\
-		}	\
-		k++;	\
-	}	\
-		\
-	if(pos == &me_device_list){	\
-		PERROR("Invalid device number specified\n");	\
-		karg.errno = ME_ERRNO_INVALID_DEVICE;	\
-	}	\
-	else{	\
-		karg.errno = device->DEV_CALL ARGS;	\
-	}	\
-	\
-	up_read(&me_rwsem);	\
-	\
-	err = copy_to_user(arg, &karg, sizeof(TYPE));	\
-	if(err){	\
-		PERROR("Can't copy arguments to user space\n");	\
-		return -EFAULT;	\
-	}	\
-		\
-	return ME_ERRNO_SUCCESS;	\
-}
-
-#endif //__KERNEL__
-#endif
diff --git a/drivers/staging/meilhaus/meplx_reg.h b/drivers/staging/meilhaus/meplx_reg.h
deleted file mode 100644
index 1868614..0000000
--- a/drivers/staging/meilhaus/meplx_reg.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @file meplx_reg.h
- *
- * @brief PLX 9052 PCI bridge register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _MEPLX_REG_H_
-#define _MEPLX_REG_H_
-
-#ifdef __KERNEL__
-
-#define PLX_INTCSR				0x4C		/**< Interrupt control and status 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_ICR					0x50		/**< Initialization control register. */
-#define PLX_ICR_BIT_EEPROM_CLOCK_SET		0x01000000
-#define PLX_ICR_BIT_EEPROM_CHIP_SELECT		0x02000000
-#define PLX_ICR_BIT_EEPROM_WRITE		0x04000000
-#define PLX_ICR_BIT_EEPROM_READ			0x08000000
-#define PLX_ICR_BIT_EEPROM_VALID		0x10000000
-
-#define PLX_ICR_MASK_EEPROM			0x1F000000
-#define EEPROM_DELAY				1
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/meslist.c b/drivers/staging/meilhaus/meslist.c
deleted file mode 100644
index ce49114..0000000
--- a/drivers/staging/meilhaus/meslist.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * @file me_slist.c
- *
- * @brief Implements the subdevice list class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- */
-
-#include "meerror.h"
-#include "medefines.h"
-
-#include "meslist.h"
-#include "medebug.h"
-
-int me_slist_query_number_subdevices(struct me_slist *slist, int *number)
-{
-	PDEBUG_LOCKS("called.\n");
-	*number = slist->n;
-	return ME_ERRNO_SUCCESS;
-}
-
-unsigned int me_slist_get_number_subdevices(struct me_slist *slist)
-{
-	PDEBUG_LOCKS("called.\n");
-	return slist->n;
-}
-
-me_subdevice_t *me_slist_get_subdevice(struct me_slist * slist,
-				       unsigned int index)
-{
-
-	struct list_head *pos;
-	me_subdevice_t *subdevice = NULL;
-	unsigned int i = 0;
-
-	PDEBUG_LOCKS("called.\n");
-
-	if (index >= slist->n) {
-		PERROR("Index out of range.\n");
-		return NULL;
-	}
-
-	list_for_each(pos, &slist->head) {
-		if (i == index) {
-			subdevice = list_entry(pos, me_subdevice_t, list);
-			break;
-		}
-
-		++i;
-	}
-
-	return subdevice;
-}
-
-int me_slist_get_subdevice_by_type(struct me_slist *slist,
-				   unsigned int start_subdevice,
-				   int type, int subtype, int *subdevice)
-{
-	me_subdevice_t *pos;
-	int s_type, s_subtype;
-	unsigned int index = 0;
-
-	PDEBUG_LOCKS("called.\n");
-
-	if (start_subdevice >= slist->n) {
-		PERROR("Start index out of range.\n");
-		return ME_ERRNO_NOMORE_SUBDEVICE_TYPE;
-	}
-
-	list_for_each_entry(pos, &slist->head, list) {
-		if (index < start_subdevice) {	// Go forward to start subdevice.
-			++index;
-			continue;
-		}
-
-		pos->me_subdevice_query_subdevice_type(pos,
-						       &s_type, &s_subtype);
-
-		if (subtype == ME_SUBTYPE_ANY) {
-			if (s_type == type)
-				break;
-		} else {
-			if ((s_type == type) && (s_subtype == subtype))
-				break;
-		}
-
-		++index;
-	}
-
-	if (index >= slist->n) {
-		return ME_ERRNO_NOMORE_SUBDEVICE_TYPE;
-	}
-
-	*subdevice = index;
-
-	return ME_ERRNO_SUCCESS;
-}
-
-void me_slist_add_subdevice_tail(struct me_slist *slist,
-				 me_subdevice_t *subdevice)
-{
-	PDEBUG_LOCKS("called.\n");
-
-	list_add_tail(&subdevice->list, &slist->head);
-	++slist->n;
-}
-
-me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist)
-{
-
-	struct list_head *last;
-	me_subdevice_t *subdevice;
-
-	PDEBUG_LOCKS("called.\n");
-
-	if (list_empty(&slist->head))
-		return NULL;
-
-	last = slist->head.prev;
-
-	subdevice = list_entry(last, me_subdevice_t, list);
-
-	list_del(last);
-
-	--slist->n;
-
-	return subdevice;
-}
-
-int me_slist_init(me_slist_t *slist)
-{
-	PDEBUG_LOCKS("called.\n");
-
-	INIT_LIST_HEAD(&slist->head);
-	slist->n = 0;
-	return 0;
-}
-
-void me_slist_deinit(me_slist_t *slist)
-{
-
-	struct list_head *s;
-	me_subdevice_t *subdevice;
-
-	PDEBUG_LOCKS("called.\n");
-
-	while (!list_empty(&slist->head)) {
-		s = slist->head.next;
-		list_del(s);
-		subdevice = list_entry(s, me_subdevice_t, list);
-		subdevice->me_subdevice_destructor(subdevice);
-	}
-
-	slist->n = 0;
-}
diff --git a/drivers/staging/meilhaus/meslist.h b/drivers/staging/meilhaus/meslist.h
deleted file mode 100644
index d26c896..0000000
--- a/drivers/staging/meilhaus/meslist.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * @file me_slist.h
- *
- * @brief Provides the subdevice list class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _ME_SLIST_H_
-#define _ME_SLIST_H_
-
-#include <linux/list.h>
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The subdevice list container.
- */
-typedef struct me_slist {
-	struct list_head head;		/**< The head of the internal list. */
-	unsigned int n;			/**< The number of subdevices in the list. */
-} me_slist_t;
-
-/**
- * @brief Queries the number of subdevices currently inside the list.
- *
- * @param slist The subdevice list to query.
- * @param[out] number The number of subdevices of the device.
- *
- * @return ME-iDS error code.
- */
-int me_slist_query_number_subdevices(struct me_slist *slist, int *number);
-
-/**
- * @brief Returns the number of subdevices currently inside the list.
- *
- * @param slist The subdevice list to query.
- *
- * @return The number of subdevices in the list.
- */
-unsigned int me_slist_get_number_subdevices(struct me_slist *slist);
-
-/**
- * @brief Get a subdevice by index.
- *
- * @param slist The subdevice list to query.
- * @param index The index of the subdevice to get in the list.
- *
- * @return The subdevice at index if available.\n
- *         NULL if the index is out of range.
- */
-me_subdevice_t *me_slist_get_subdevice(struct me_slist *slist,
-				       unsigned int index);
-
-/**
- * @brief Get a subdevice index by type and subtype.
- *
- * @param slist The subdevice list to query.
- * @param start_subdevice The subdevice index at which the start shall begin.
- * @param type The type of the subdevice to query.
- * @param subtype The subtype of the subdevice to query.
- * @param[out] subdevice On success this parameter returns the index of the subdevice matching the requested type.
- *
- * @return ME_ERRNO_SUCCESS on success.
- */
-int me_slist_get_subdevice_by_type(struct me_slist *slist,
-				   unsigned int start_subdevice,
-				   int type, int subtype, int *subdevice);
-
-/**
- * @brief Adds a subdevice to the tail of the list.
- *
- * @param slist The subdevice list to add a subdevice to.
- * @param subdevice The subdevice to add to the list.
- */
-void me_slist_add_subdevice_tail(struct me_slist *slist,
-				 me_subdevice_t * subdevice);
-
-/**
- * @brief Removes a subdevice from the tail of the list.
- *
- * @param slist The subdevice list.
- *
- * @return Pointer to the removed subdeivce.\n
- *         NULL in cases where the list was empty.
- */
-me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist);
-
-/**
- * @brief Initializes a subdevice list structure.
- *
- * @param lock The subdevice list structure to initialize.
- * @return 0 on success.
- */
-int me_slist_init(me_slist_t * slist);
-
-/**
- * @brief Deinitializes a subdevice list structure and destructs every subdevice in it.
- *
- * @param slist The subdevice list structure to deinitialize.
- * @return 0 on success.
- */
-void me_slist_deinit(me_slist_t * slist);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/meslock.c b/drivers/staging/meilhaus/meslock.c
deleted file mode 100644
index abcdb4a..0000000
--- a/drivers/staging/meilhaus/meslock.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * @file meslock.c
- *
- * @brief Implements the subdevice lock class.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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.
- */
-
-#include <linux/spinlock.h>
-
-#include "medefines.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "meslock.h"
-
-int me_slock_enter(struct me_slock *slock, struct file *filep)
-{
-	PDEBUG_LOCKS("executed.\n");
-
-	spin_lock(&slock->spin_lock);
-
-	if ((slock->filep) != NULL && (slock->filep != filep)) {
-		PERROR("Subdevice is locked by another process.\n");
-		spin_unlock(&slock->spin_lock);
-		return ME_ERRNO_LOCKED;
-	}
-
-	slock->count++;
-
-	spin_unlock(&slock->spin_lock);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-int me_slock_exit(struct me_slock *slock, struct file *filep)
-{
-	PDEBUG_LOCKS("executed.\n");
-
-	spin_lock(&slock->spin_lock);
-	slock->count--;
-	spin_unlock(&slock->spin_lock);
-
-	return ME_ERRNO_SUCCESS;
-}
-
-int me_slock_lock(struct me_slock *slock, struct file *filep, int lock)
-{
-	PDEBUG_LOCKS("executed.\n");
-
-	switch (lock) {
-
-	case ME_LOCK_RELEASE:
-		spin_lock(&slock->spin_lock);
-
-		if (slock->filep == filep)
-			slock->filep = NULL;
-
-		spin_unlock(&slock->spin_lock);
-
-		break;
-
-	case ME_LOCK_SET:
-		spin_lock(&slock->spin_lock);
-
-		if (slock->count) {
-			spin_unlock(&slock->spin_lock);
-			PERROR("Subdevice is used by another process.\n");
-			return ME_ERRNO_USED;
-		} else if (slock->filep == NULL)
-			slock->filep = filep;
-		else if (slock->filep != filep) {
-			spin_unlock(&slock->spin_lock);
-			PERROR("Subdevice is locked by another process.\n");
-			return ME_ERRNO_LOCKED;
-		}
-
-		spin_unlock(&slock->spin_lock);
-
-		break;
-
-	case ME_LOCK_CHECK:
-		spin_lock(&slock->spin_lock);
-
-		if (slock->count) {
-			spin_unlock(&slock->spin_lock);
-			return ME_ERRNO_USED;
-		} else if ((slock->filep != NULL) && (slock->filep != filep)) {
-			spin_unlock(&slock->spin_lock);
-			return ME_ERRNO_LOCKED;
-		}
-
-		spin_unlock(&slock->spin_lock);
-
-		break;
-
-	default:
-		break;
-	}
-
-	return ME_ERRNO_SUCCESS;
-}
-
-void me_slock_deinit(struct me_slock *slock)
-{
-	PDEBUG_LOCKS("executed.\n");
-}
-
-int me_slock_init(me_slock_t *slock)
-{
-	PDEBUG_LOCKS("executed.\n");
-
-	slock->filep = NULL;
-	slock->count = 0;
-	spin_lock_init(&slock->spin_lock);
-
-	return 0;
-}
diff --git a/drivers/staging/meilhaus/meslock.h b/drivers/staging/meilhaus/meslock.h
deleted file mode 100644
index f42b25c..0000000
--- a/drivers/staging/meilhaus/meslock.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file meslock.h
- *
- * @brief Provides the subdevice lock class.
- * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _MESLOCK_H_
-#define _MESLOCK_H_
-
-#include <linux/spinlock.h>
-
-#ifdef __KERNEL__
-
-/**
- * @brief The subdevice lock class.
- */
-typedef struct me_slock {
-	struct file *filep;		/**< Pointer to file structure holding the subdevice. */
-	int count;			/**< Number of tasks which are inside the subdevice. */
-	spinlock_t spin_lock;		/**< Spin lock protecting the attributes from concurrent access. */
-} me_slock_t;
-
-/**
- * @brief Tries to enter a subdevice.
- *
- * @param slock The subdevice lock instance.
- * @param filep The file structure identifying the calling process.
- *
- * @return 0 on success.
- */
-int me_slock_enter(struct me_slock *slock, struct file *filep);
-
-/**
- * @brief Exits a subdevice.
- *
- * @param slock The subdevice lock instance.
- * @param filep The file structure identifying the calling process.
- *
- * @return 0 on success.
- */
-int me_slock_exit(struct me_slock *slock, struct file *filep);
-
-/**
- * @brief Tries to perform a locking action on a subdevice.
- *
- * @param slock The subdevice lock instance.
- * @param filep The file structure identifying the calling process.
- * @param The action to be done.
- *
- * @return 0 on success.
- */
-int me_slock_lock(struct me_slock *slock, struct file *filep, int lock);
-
-/**
- * @brief Initializes a lock structure.
- *
- * @param slock The lock structure to initialize.
- * @return 0 on success.
- */
-int me_slock_init(me_slock_t * slock);
-
-/**
- * @brief Deinitializes a lock structure.
- *
- * @param slock The lock structure to deinitialize.
- * @return 0 on success.
- */
-void me_slock_deinit(me_slock_t * slock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/mesubdevice.c b/drivers/staging/meilhaus/mesubdevice.c
deleted file mode 100644
index b2e9567..0000000
--- a/drivers/staging/meilhaus/mesubdevice.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/**
- * @file mesubdevice.c
- *
- * @brief Subdevice base class implemention.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#include <linux/slab.h>
-
-#include "medefines.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "mesubdevice.h"
-
-static int me_subdevice_io_irq_start(struct me_subdevice *subdevice,
-				     struct file *filep,
-				     int channel,
-				     int irq_source,
-				     int irq_edge, int irq_arg, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_irq_wait(struct me_subdevice *subdevice,
-				    struct file *filep,
-				    int channel,
-				    int *irq_count,
-				    int *value, int time_out, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_irq_stop(struct me_subdevice *subdevice,
-				    struct file *filep, int channel, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_reset_subdevice(struct me_subdevice *subdevice,
-					   struct file *filep, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_single_config(struct me_subdevice *subdevice,
-					 struct file *filep,
-					 int channel,
-					 int single_config,
-					 int ref,
-					 int trig_chan,
-					 int trig_type,
-					 int trig_edge, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_single_read(struct me_subdevice *subdevice,
-				       struct file *filep,
-				       int channel,
-				       int *value, int time_out, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_single_write(struct me_subdevice *subdevice,
-					struct file *filep,
-					int channel,
-					int value, int time_out, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_stream_config(struct me_subdevice *subdevice,
-					 struct file *filep,
-					 meIOStreamConfig_t *config_list,
-					 int count,
-					 meIOStreamTrigger_t *trigger,
-					 int fifo_irq_threshold, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_stream_new_values(struct me_subdevice *subdevice,
-					     struct file *filep,
-					     int time_out,
-					     int *count, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_stream_read(struct me_subdevice *subdevice,
-				       struct file *filep,
-				       int read_mode,
-				       int *values, int *count, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_stream_start(struct me_subdevice *subdevice,
-					struct file *filep,
-					int start_mode, int time_out, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_stream_status(struct me_subdevice *subdevice,
-					 struct file *filep,
-					 int wait,
-					 int *status, int *count, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_stream_stop(struct me_subdevice *subdevice,
-				       struct file *filep,
-				       int stop_mode, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_io_stream_write(struct me_subdevice *subdevice,
-					struct file *filep,
-					int write_mode,
-					int *values, int *count, int flags)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_lock_subdevice(me_subdevice_t *subdevice,
-				       struct file *filep, int lock, int flags)
-{
-	PDEBUG("executed.\n");
-	return me_slock_lock(&subdevice->lock, filep, lock);
-}
-
-static int me_subdevice_query_number_channels(struct me_subdevice *subdevice,
-					      int *number)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_query_number_ranges(struct me_subdevice *subdevice,
-					    int unit, int *count)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_query_range_by_min_max(struct me_subdevice *subdevice,
-					       int unit,
-					       int *min,
-					       int *max,
-					       int *maxdata, int *range)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_query_range_info(struct me_subdevice *subdevice,
-					 int range,
-					 int *unit,
-					 int *min, int *max, int *maxdata)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_query_subdevice_type(struct me_subdevice *subdevice,
-					     int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_query_subdevice_caps(struct me_subdevice *subdevice,
-					     int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int me_subdevice_query_subdevice_caps_args(struct me_subdevice
-						  *subdevice, int cap,
-						  int *args, int count)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_query_timer(struct me_subdevice *subdevice,
-				    int timer,
-				    int *base_frequency,
-				    long long *min_ticks, long long *max_ticks)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_NOT_SUPPORTED;
-}
-
-static int me_subdevice_config_load(struct me_subdevice *subdevice,
-				    me_cfg_device_entry_t *config)
-{
-	PDEBUG("executed.\n");
-	return ME_ERRNO_SUCCESS;
-}
-
-static void me_subdevice_destructor(struct me_subdevice *subdevice)
-{
-	PDEBUG("executed.\n");
-	me_subdevice_deinit(subdevice);
-	kfree(subdevice);
-}
-
-int me_subdevice_init(me_subdevice_t *subdevice)
-{
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Init list head */
-	INIT_LIST_HEAD(&subdevice->list);
-
-	/* Initialize the subdevice lock instance */
-
-	err = me_slock_init(&subdevice->lock);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice lock instance.\n");
-		return 1;
-	}
-
-	/* Subdevice base class methods */
-	subdevice->me_subdevice_io_irq_start = me_subdevice_io_irq_start;
-	subdevice->me_subdevice_io_irq_wait = me_subdevice_io_irq_wait;
-	subdevice->me_subdevice_io_irq_stop = me_subdevice_io_irq_stop;
-	subdevice->me_subdevice_io_reset_subdevice =
-	    me_subdevice_io_reset_subdevice;
-	subdevice->me_subdevice_io_single_config =
-	    me_subdevice_io_single_config;
-	subdevice->me_subdevice_io_single_read = me_subdevice_io_single_read;
-	subdevice->me_subdevice_io_single_write = me_subdevice_io_single_write;
-	subdevice->me_subdevice_io_stream_config =
-	    me_subdevice_io_stream_config;
-	subdevice->me_subdevice_io_stream_new_values =
-	    me_subdevice_io_stream_new_values;
-	subdevice->me_subdevice_io_stream_read = me_subdevice_io_stream_read;
-	subdevice->me_subdevice_io_stream_start = me_subdevice_io_stream_start;
-	subdevice->me_subdevice_io_stream_status =
-	    me_subdevice_io_stream_status;
-	subdevice->me_subdevice_io_stream_stop = me_subdevice_io_stream_stop;
-	subdevice->me_subdevice_io_stream_write = me_subdevice_io_stream_write;
-	subdevice->me_subdevice_lock_subdevice = me_subdevice_lock_subdevice;
-	subdevice->me_subdevice_query_number_channels =
-	    me_subdevice_query_number_channels;
-	subdevice->me_subdevice_query_number_ranges =
-	    me_subdevice_query_number_ranges;
-	subdevice->me_subdevice_query_range_by_min_max =
-	    me_subdevice_query_range_by_min_max;
-	subdevice->me_subdevice_query_range_info =
-	    me_subdevice_query_range_info;
-	subdevice->me_subdevice_query_subdevice_type =
-	    me_subdevice_query_subdevice_type;
-	subdevice->me_subdevice_query_subdevice_caps =
-	    me_subdevice_query_subdevice_caps;
-	subdevice->me_subdevice_query_subdevice_caps_args =
-	    me_subdevice_query_subdevice_caps_args;
-	subdevice->me_subdevice_query_timer = me_subdevice_query_timer;
-	subdevice->me_subdevice_config_load = me_subdevice_config_load;
-	subdevice->me_subdevice_destructor = me_subdevice_destructor;
-
-	return 0;
-}
-
-void me_subdevice_deinit(me_subdevice_t *subdevice)
-{
-	PDEBUG("executed.\n");
-	me_subdevice_io_reset_subdevice(subdevice, NULL,
-					ME_IO_RESET_SUBDEVICE_NO_FLAGS);
-	me_slock_deinit(&subdevice->lock);
-}
diff --git a/drivers/staging/meilhaus/mesubdevice.h b/drivers/staging/meilhaus/mesubdevice.h
deleted file mode 100644
index 19ec2b5..0000000
--- a/drivers/staging/meilhaus/mesubdevice.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/**
- * @file mesubdevice.h
- *
- * @brief Provides the subdevice base class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-#ifndef _MESUBDEVICE_H_
-#define _MESUBDEVICE_H_
-
-#include <linux/list.h>
-
-#include "metypes.h"
-#include "meioctl.h"
-#include "meslock.h"
-
-# include <linux/workqueue.h>
-
-#ifdef __KERNEL__
-
-/**
- * @brief Macro used to enter a subdevice.
- */
-#define ME_SUBDEVICE_ENTER	\
-{ \
-	int err; \
-	err = me_slock_enter(&instance->base.lock, filep); \
-	if(err){ \
-		PERROR("Cannot enter subdevice.\n"); \
-		return err; \
-	} \
-}
-
-/**
- * @brief Macro used to exit a subdevice.
- */
-#define ME_SUBDEVICE_EXIT	\
-{\
-	int err; \
-	err = me_slock_exit(&instance->base.lock, filep); \
-	if(err){ \
-		PERROR("Cannot exit subdevice.\n"); \
-		return err; \
-	} \
-}
-
-/**
- * @brief The subdevice base class.
- */
-typedef struct me_subdevice {
-	/* Attributes */
-	struct list_head list;		/**< Enables the subdevice to be added to a dynamic list. */
-	me_slock_t lock;		/**< Used by user application in order to lock the subdevice for exclusive usage. */
-
-	/* Methods */
-	int (*me_subdevice_io_irq_start) (struct me_subdevice * subdevice,
-					  struct file * filep,
-					  int channel,
-					  int irq_source,
-					  int irq_edge, int irq_arg, int flags);
-
-	int (*me_subdevice_io_irq_wait) (struct me_subdevice * subdevice,
-					 struct file * filep,
-					 int channel,
-					 int *irq_count,
-					 int *value, int time_out, int flags);
-
-	int (*me_subdevice_io_irq_stop) (struct me_subdevice * subdevice,
-					 struct file * filep,
-					 int channel, int flags);
-
-	int (*me_subdevice_io_reset_subdevice) (struct me_subdevice * subdevice,
-						struct file * filep, int flags);
-
-	int (*me_subdevice_io_single_config) (struct me_subdevice * subdevice,
-					      struct file * filep,
-					      int channel,
-					      int single_config,
-					      int ref,
-					      int trig_chan,
-					      int trig_type,
-					      int trig_edge, int flags);
-
-	int (*me_subdevice_io_single_read) (struct me_subdevice * subdevice,
-					    struct file * filep,
-					    int channel,
-					    int *value,
-					    int time_out, int flags);
-
-	int (*me_subdevice_io_single_write) (struct me_subdevice * subdevice,
-					     struct file * filep,
-					     int channel,
-					     int value,
-					     int time_out, int flags);
-
-	int (*me_subdevice_io_stream_config) (struct me_subdevice * subdevice,
-					      struct file * filep,
-					      meIOStreamConfig_t * config_list,
-					      int count,
-					      meIOStreamTrigger_t * trigger,
-					      int fifo_irq_threshold,
-					      int flags);
-
-	int (*me_subdevice_io_stream_new_values) (struct me_subdevice *
-						  subdevice,
-						  struct file * filep,
-						  int time_out, int *count,
-						  int flags);
-
-	int (*me_subdevice_io_stream_read) (struct me_subdevice * subdevice,
-					    struct file * filep,
-					    int read_mode,
-					    int *values, int *count, int flags);
-
-	int (*me_subdevice_io_stream_start) (struct me_subdevice * subdevice,
-					     struct file * filep,
-					     int start_mode,
-					     int time_out, int flags);
-
-	int (*me_subdevice_io_stream_status) (struct me_subdevice * subdevice,
-					      struct file * filep,
-					      int wait,
-					      int *status,
-					      int *count, int flags);
-
-	int (*me_subdevice_io_stream_stop) (struct me_subdevice * subdevice,
-					    struct file * filep,
-					    int stop_mode, int flags);
-
-	int (*me_subdevice_io_stream_write) (struct me_subdevice * subdevice,
-					     struct file * filep,
-					     int write_mode,
-					     int *values,
-					     int *count, int flags);
-
-	int (*me_subdevice_lock_subdevice) (struct me_subdevice * subdevice,
-					    struct file * filep,
-					    int lock, int flags);
-
-	int (*me_subdevice_query_number_channels) (struct me_subdevice *
-						   subdevice, int *number);
-
-	int (*me_subdevice_query_number_ranges) (struct me_subdevice *
-						 subdevice, int unit,
-						 int *count);
-
-	int (*me_subdevice_query_range_by_min_max) (struct me_subdevice *
-						    subdevice, int unit,
-						    int *min, int *max,
-						    int *maxdata, int *range);
-
-	int (*me_subdevice_query_range_info) (struct me_subdevice * subdevice,
-					      int range,
-					      int *unit,
-					      int *min, int *max, int *maxdata);
-
-	int (*me_subdevice_query_subdevice_type) (struct me_subdevice *
-						  subdevice, int *type,
-						  int *subtype);
-
-	int (*me_subdevice_query_subdevice_caps) (struct me_subdevice *
-						  subdevice, int *caps);
-
-	int (*me_subdevice_query_subdevice_caps_args) (struct me_subdevice *
-						       subdevice, int cap,
-						       int *args, int count);
-
-	int (*me_subdevice_query_timer) (struct me_subdevice * subdevice,
-					 int timer,
-					 int *base_frequency,
-					 long long *min_ticks,
-					 long long *max_ticks);
-
-	int (*me_subdevice_config_load) (struct me_subdevice * subdevice,
-					 me_cfg_device_entry_t * config);
-
-	void (*me_subdevice_destructor) (struct me_subdevice * subdevice);
-} me_subdevice_t;
-
-/**
- * @brief Initializes a subdevice structure.
- *
- * @param subdevice The subdevice structure to initialize.
- * @return 0 on success.
- */
-int me_subdevice_init(me_subdevice_t * subdevice);
-
-/**
- * @brief Deinitializes a subdevice structure.
- *
- * @param subdevice The subdevice structure to initialize.
- */
-void me_subdevice_deinit(me_subdevice_t * subdevice);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/metempl_device.c b/drivers/staging/meilhaus/metempl_device.c
deleted file mode 100644
index bdaf6df..0000000
--- a/drivers/staging/meilhaus/metempl_device.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * @file metempl_device.c
- *
- * @brief template device class implementation.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-#ifndef MODULE
-#  define MODULE
-#endif
-
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-
-#include <meids.h>
-#include "meerror.h"
-#include "mecommon.h"
-#include "meinternal.h"
-
-#include "medebug.h"
-#include "medevice.h"
-#include "metempl_device.h"
-#include "mesubdevice.h"
-#include "metempl_sub.h"
-
-me_device_t *metempl_pci_constructor(struct pci_dev *pci_device)
-{
-	metempl_device_t *metempl_device;
-	me_subdevice_t *subdevice;
-	unsigned int version_idx;
-	int err;
-	int i;
-
-	PDEBUG("executed.\n");
-
-	// Allocate structure for device instance.
-	metempl_device = kmalloc(sizeof(metempl_device_t), GFP_KERNEL);
-
-	if (!metempl_device) {
-		PERROR("Cannot get memory for device instance.\n");
-		return NULL;
-	}
-
-	memset(metempl_device, 0, sizeof(metempl_device_t));
-
-	// Initialize base class structure.
-	err = me_device_pci_init((me_device_t *) metempl_device, pci_device);
-
-	if (err) {
-		kfree(metempl_device);
-		PERROR("Cannot initialize device base class.\n");
-		return NULL;
-	}
-
-	/* Get the index in the device version information table. */
-	version_idx =
-	    metempl_versions_get_device_index(metempl_device->base.info.pci.
-					      device_id);
-
-	// Initialize spin lock .
-	spin_lock_init(&metempl_device->ctrl_reg_lock);
-
-	// Create subdevice instances.
-	for (i = 0; i < metempl_versions[version_idx].subdevices; i++) {
-		subdevice =
-		    (me_subdevice_t *) metempl_sub_constructor(metempl_device->
-							       base.info.pci.
-							       reg_bases[2], i,
-							       &metempl_device->
-							       ctrl_reg_lock);
-
-		if (!subdevice) {
-			me_device_deinit((me_device_t *) metempl_device);
-			kfree(metempl_device);
-			PERROR("Cannot get memory for subdevice.\n");
-			return NULL;
-		}
-
-		me_slist_add_subdevice_tail(&metempl_device->base.slist,
-					    subdevice);
-	}
-
-	/* Overwrite base class methods if applicable. */
-
-	return (me_device_t *) metempl_device;
-}
-EXPORT_SYMBOL(metempl_pci_constructor);
-
-// Init and exit of module.
-
-static int __init metempl_init(void)
-{
-	PDEBUG("executed.\n.");
-	return 0;
-}
-
-static void __exit metempl_exit(void)
-{
-	PDEBUG("executed.\n.");
-}
-
-module_init(metempl_init);
-
-module_exit(metempl_exit);
-
-// Administrative stuff for modinfo.
-MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
-MODULE_DESCRIPTION("Device Driver Module for Template Device");
-MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/meilhaus/metempl_device.h b/drivers/staging/meilhaus/metempl_device.h
deleted file mode 100644
index 3c3702c..0000000
--- a/drivers/staging/meilhaus/metempl_device.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * @file metempl_device.h
- *
- * @brief template device class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _METEMPL_DEVICE_H
-#define _METEMPL_DEVICE_H
-
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-
-#include "medevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief Structure holding template device capabilities.
- */
-typedef struct metempl_version {
-	uint16_t device_id;
-	unsigned int subdevices;
-} metempl_version_t;
-
-/**
- * @brief Device capabilities.
- */
-static metempl_version_t metempl_versions[] = {
-	{0xDEAD, 1},
-	{0},
-};
-
-#define METEMPL_DEVICE_VERSIONS (sizeof(metempl_versions) / sizeof(metempl_version_t) - 1) /**< Returns the number of entries in #metempl_versions. */
-
-/**
- * @brief Returns the index of the device entry in #metempl_versions.
- *
- * @param device_id The PCI device id of the device to query.
- * @return The index of the device in #metempl_versions.
- */
-static inline unsigned int metempl_versions_get_device_index(uint16_t device_id)
-{
-	unsigned int i;
-	for (i = 0; i < METEMPL_DEVICE_VERSIONS; i++)
-		if (metempl_versions[i].device_id == device_id)
-			break;
-	return i;
-}
-
-/**
- * @brief The template device class structure.
- */
-typedef struct metempl_device {
-	me_device_t base;			/**< The Meilhaus device base class. */
-
-	/* Child class attributes. */
-	spinlock_t ctrl_reg_lock;
-} metempl_device_t;
-
-/**
- * @brief The template device class constructor.
- *
- * @param pci_device The pci device structure given by the PCI subsystem.
- *
- * @return On succes a new template device instance. \n
- *         NULL on error.
- */
-me_device_t *metempl_pci_constructor(struct pci_dev *pci_device)
-    __attribute__ ((weak));
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/metempl_sub.c b/drivers/staging/meilhaus/metempl_sub.c
deleted file mode 100644
index b5a6a97..0000000
--- a/drivers/staging/meilhaus/metempl_sub.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * @file metempl_sub.c
- *
- * @brief Subdevice instance.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 __KERNEL__
-#  define __KERNEL__
-#endif
-
-/*
- * Includes
- */
-#include <linux/module.h>
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/types.h>
-
-#include "medefines.h"
-#include "meinternal.h"
-#include "meerror.h"
-
-#include "medebug.h"
-#include "metempl_sub_reg.h"
-#include "metempl_sub.h"
-
-/*
- * Defines
- */
-
-/*
- * Functions
- */
-
-static void metempl_sub_destructor(struct me_subdevice *subdevice)
-{
-	metempl_sub_subdevice_t *instance;
-
-	PDEBUG("executed.\n");
-	instance = (metempl_sub_subdevice_t *) subdevice;
-
-	/* Until there this was the things the default constructor does.
-	   If you do not have any additional things to do you can wipe it out. */
-
-	me_subdevice_deinit(&instance->base);
-	kfree(instance);
-}
-
-static int metempl_sub_query_number_channels(me_subdevice_t *subdevice,
-					     int *number)
-{
-	PDEBUG("executed.\n");
-	*number = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int metempl_sub_query_subdevice_type(me_subdevice_t *subdevice,
-					    int *type, int *subtype)
-{
-	PDEBUG("executed.\n");
-	*type = 0;
-	*subtype = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-static int metempl_sub_query_subdevice_caps(me_subdevice_t *subdevice,
-					    int *caps)
-{
-	PDEBUG("executed.\n");
-	*caps = 0;
-	return ME_ERRNO_SUCCESS;
-}
-
-metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base,
-						 unsigned int sub_idx,
-						 spinlock_t *ctrl_reg_lock)
-{
-	metempl_sub_subdevice_t *subdevice;
-	int err;
-
-	PDEBUG("executed.\n");
-
-	/* Allocate memory for subdevice instance */
-	subdevice = kmalloc(sizeof(metempl_sub_subdevice_t), GFP_KERNEL);
-
-	if (!subdevice) {
-		PERROR("Cannot get memory for subdevice instance.\n");
-		return NULL;
-	}
-
-	memset(subdevice, 0, sizeof(metempl_sub_subdevice_t));
-
-	/* Check if subdevice index is out of range */
-
-	if (sub_idx >= 2) {
-		PERROR("Template subdevice index is out of range.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-
-	/* Initialize subdevice base class */
-	err = me_subdevice_init(&subdevice->base);
-
-	if (err) {
-		PERROR("Cannot initialize subdevice base class instance.\n");
-		kfree(subdevice);
-		return NULL;
-	}
-	// Initialize spin locks.
-	spin_lock_init(&subdevice->subdevice_lock);
-
-	subdevice->ctrl_reg_lock = ctrl_reg_lock;
-
-	/* Save the subdevice index */
-	subdevice->sub_idx = sub_idx;
-
-	/* Override base class methods. */
-	subdevice->base.me_subdevice_destructor = metempl_sub_destructor;
-	subdevice->base.me_subdevice_query_number_channels =
-	    metempl_sub_query_number_channels;
-	subdevice->base.me_subdevice_query_subdevice_type =
-	    metempl_sub_query_subdevice_type;
-	subdevice->base.me_subdevice_query_subdevice_caps =
-	    metempl_sub_query_subdevice_caps;
-
-	return subdevice;
-}
diff --git a/drivers/staging/meilhaus/metempl_sub.h b/drivers/staging/meilhaus/metempl_sub.h
deleted file mode 100644
index 80c8af9..0000000
--- a/drivers/staging/meilhaus/metempl_sub.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file metempl_sub.h
- *
- * @brief Meilhaus subdevice class.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _METEMPL_SUB_H_
-#define _METEMPL_SUB_H_
-
-#include "mesubdevice.h"
-
-#ifdef __KERNEL__
-
-/**
- * @brief The subdevice class.
- */
-typedef struct metempl_sub_subdevice {
-	/* Inheritance */
-	me_subdevice_t base;			/**< The subdevice base class. */
-
-	/* Attributes */
-	spinlock_t subdevice_lock;		/**< Spin lock to protect the subdevice from concurrent access. */
-	spinlock_t *ctrl_reg_lock;		/**< Spin lock to protect #ctrl_reg from concurrent access. */
-	int sub_idx;				/**< The index of the subdevice on the device. */
-
-	unsigned long ctrl_reg;			/**< Register to configure the modes. */
-} metempl_sub_subdevice_t;
-
-/**
- * @brief The constructor to generate a subdevice instance.
- *
- * @param reg_base The register base address of the device as returned by the PCI BIOS.
- * @param sub_idx The index of the subdevice on the device.
- * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
- *
- * @return Pointer to new instance on success.\n
- * NULL on error.
- */
-metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base,
-						 unsigned int sub_idx,
-						 spinlock_t * ctrl_reg_lock);
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/metempl_sub_reg.h b/drivers/staging/meilhaus/metempl_sub_reg.h
deleted file mode 100644
index 1a2cab7..0000000
--- a/drivers/staging/meilhaus/metempl_sub_reg.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * @file metempl_sub_reg.h
- *
- * @brief Subdevice register definitions.
- * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- * @author Guenter Gebhardt
- */
-
-/*
- * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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 _METEMPL_SUB_REG_H_
-#define _METEMPL_SUB_REG_H_
-
-#ifdef __KERNEL__
-
-#define METEMPL_PORT_MODE			0x0010		/**< Configuration register. */
-
-#endif
-#endif
diff --git a/drivers/staging/meilhaus/metypes.h b/drivers/staging/meilhaus/metypes.h
deleted file mode 100644
index 228ea15..0000000
--- a/drivers/staging/meilhaus/metypes.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2005 Meilhaus Electronic GmbH (support@meilhaus.de)
- *
- * Source File : metypes.h
- * Author      : GG (Guenter Gebhardt)  <g.gebhardt@meilhaus.de>
- */
-
-#ifndef _METYPES_H_
-#define _METYPES_H_
-
-
-typedef int (*meErrorCB_t)(char *pcFunctionName, int iErrorCode);
-
-typedef int (*meIOStreamCB_t)(
-		int iDevice,
-		int iSubdevice,
-		int iCount,
-	   	void *pvContext,
-	   	int iErrorCode);
-
-typedef int (*meIOIrqCB_t)(
-		int iDevice,
-	   	int iSubdevice,
-	   	int iChannel,
-		int iIrqCount,
-	   	int iValue,
-	   	void *pvContext,
-	   	int iErrorCode);
-
-
-typedef struct meIOSingle {
-	int iDevice;
-	int iSubdevice;
-	int iChannel;
-	int iDir;
-	int iValue;
-	int iTimeOut;
-	int iFlags;
-	int iErrno;
-} meIOSingle_t;
-
-
-typedef struct meIOStreamConfig {
-	int iChannel;
-	int iStreamConfig;
-	int iRef;
-	int iFlags;
-} meIOStreamConfig_t;
-
-
-typedef struct meIOStreamTrigger {
-	int iAcqStartTrigType;
-	int iAcqStartTrigEdge;
-	int iAcqStartTrigChan;
-	int iAcqStartTicksLow;
-	int iAcqStartTicksHigh;
-	int iAcqStartArgs[10];
-	int iScanStartTrigType;
-	int iScanStartTicksLow;
-	int iScanStartTicksHigh;
-	int iScanStartArgs[10];
-	int iConvStartTrigType;
-	int iConvStartTicksLow;
-	int iConvStartTicksHigh;
-	int iConvStartArgs[10];
-	int iScanStopTrigType;
-	int iScanStopCount;
-	int iScanStopArgs[10];
-	int iAcqStopTrigType;
-	int iAcqStopCount;
-	int iAcqStopArgs[10];
-	int iFlags;
-} meIOStreamTrigger_t;
-
-
-typedef struct meIOStreamStart {
-	int iDevice;
-	int iSubdevice;
-	int iStartMode;
-	int iTimeOut;
-	int iFlags;
-	int iErrno;
-} meIOStreamStart_t;
-
-
-typedef struct meIOStreamStop {
-	int iDevice;
-	int iSubdevice;
-	int iStopMode;
-	int iFlags;
-	int iErrno;
-} meIOStreamStop_t;
-
-
-#endif
diff --git a/drivers/staging/octeon/cvmx-mdio.h b/drivers/staging/octeon/cvmx-mdio.h
index c987a75..f45dc49 100644
--- a/drivers/staging/octeon/cvmx-mdio.h
+++ b/drivers/staging/octeon/cvmx-mdio.h
@@ -421,7 +421,7 @@ static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device,
 	do {
 		cvmx_wait(1000);
 		smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id));
-	} while (smi_rd.s.pending && timeout--);
+	} while (smi_rd.s.pending && --timeout);
 
 	if (timeout <= 0) {
 		cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d "
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 93cab0a..42230e6 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -170,7 +170,7 @@ static u32 cvm_oct_get_link(struct net_device *dev)
 	return ret;
 }
 
-struct ethtool_ops cvm_oct_ethtool_ops = {
+struct const ethtool_ops cvm_oct_ethtool_ops = {
 	.get_drvinfo = cvm_oct_get_drvinfo,
 	.get_settings = cvm_oct_get_settings,
 	.set_settings = cvm_oct_set_settings,
diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h
index 6314141..b3328ae 100644
--- a/drivers/staging/octeon/ethernet-mdio.h
+++ b/drivers/staging/octeon/ethernet-mdio.h
@@ -41,6 +41,6 @@
 #include <net/xfrm.h>
 #endif /* CONFIG_XFRM */
 
-extern struct ethtool_ops cvm_oct_ethtool_ops;
+extern const struct ethtool_ops cvm_oct_ethtool_ops;
 int cvm_oct_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 int cvm_oct_mdio_setup_device(struct net_device *dev);
diff --git a/drivers/staging/otus/80211core/cagg.c b/drivers/staging/otus/80211core/cagg.c
index 4942190..dbd0a5f 100644
--- a/drivers/staging/otus/80211core/cagg.c
+++ b/drivers/staging/otus/80211core/cagg.c
@@ -2845,7 +2845,7 @@ u16_t   zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
 
 
     /*
-     * TBD : Maximum size of managment frame
+     * TBD : Maximum size of management frame
      */
     if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
     {
@@ -3286,7 +3286,7 @@ u16_t   zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
 
 
     /*
-     * TBD : Maximum size of managment frame
+     * TBD : Maximum size of management frame
      */
     if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
     {
@@ -3439,7 +3439,7 @@ u16_t   zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarCon
 
 
     /*
-     * TBD : Maximum size of managment frame
+     * TBD : Maximum size of management frame
      */
     if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
     {
diff --git a/drivers/staging/otus/80211core/cmm.c b/drivers/staging/otus/80211core/cmm.c
index b74379d..bed16b5 100644
--- a/drivers/staging/otus/80211core/cmm.c
+++ b/drivers/staging/otus/80211core/cmm.c
@@ -871,7 +871,7 @@ void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst,
     zmw_declare_for_critical_section();
 
     zm_msg2_mm(ZM_LV_2, "Send mm frame, type=", frameType);
-    /* TBD : Maximum size of managment frame */
+    /* TBD : Maximum size of management frame */
     if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
     {
         zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
@@ -1099,7 +1099,7 @@ void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst,
             }
 
             if ((wd->sta.capability[1] & ZM_BIT_0) == 1)
-            {   //spectrum managment flag enable
+            {   //spectrum management flag enable
                 offset = zfStaAddIePowerCap(dev, buf, offset);
                 offset = zfStaAddIeSupportCh(dev, buf, offset);
             }
diff --git a/drivers/staging/otus/80211core/performance.c b/drivers/staging/otus/80211core/performance.c
index 51b42d5..4c10e1d 100644
--- a/drivers/staging/otus/80211core/performance.c
+++ b/drivers/staging/otus/80211core/performance.c
@@ -27,9 +27,9 @@
 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
 
 #define ZM_TP_SIZE 50
-struct zsSummary zm_summary;
-struct zsVariation zm_var;
-struct zsThroughput zm_tp;
+static struct zsSummary zm_summary;
+static struct zsVariation zm_var;
+static struct zsThroughput zm_tp;
 
 void zfiPerformanceInit(zdev_t* dev)
 {
diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c
index 322585b..94f9cbb 100644
--- a/drivers/staging/otus/hal/hpmain.c
+++ b/drivers/staging/otus/hal/hpmain.c
@@ -76,7 +76,7 @@ u32_t zfHpEchoCommand(zdev_t* dev, u32_t value);
 
 
 #define zm_hp_priv(x) (((struct zsHpPriv*)wd->hpPrivate)->x)
-struct zsHpPriv zgHpPriv;
+static struct zsHpPriv zgHpPriv;
 
 #define ZM_FIRMWARE_WLAN_ADDR           0x200000
 #define ZM_FIRMWARE_SPI_ADDR      0x114000
diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c
index ce04218..6808e69 100644
--- a/drivers/staging/otus/ioctl.c
+++ b/drivers/staging/otus/ioctl.c
@@ -58,9 +58,7 @@
 #define ZD_MAX_KEY_SIZE			    32
 #define ZD_MAX_GENERIC_SIZE		    64
 
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 extern u16_t zfLnxGetVapId(zdev_t *dev);
 
@@ -248,7 +246,6 @@ int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
 	return 0;
 }
 
-#if WIRELESS_EXT > 14
 /*
  * Encode a WPA or RSN information element as a custom
  * element using the hostap format.
@@ -269,7 +266,6 @@ u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen,
 		p += sprintf(p, "%02x", ie[i]);
 	return (i == ielen ? p - (u8 *)buf:0);
 }
-#endif  /* WIRELESS_EXT > 14 */
 
 /*
  * Translate scan data returned from the card to a card independent
@@ -284,9 +280,7 @@ char *usbdrv_translate_scan(struct net_device *dev,
 	char *current_val;     /* For rates */
 	char *last_ev;
 	int i;
-	#if WIRELESS_EXT > 14
-		char    buf[64*2 + 30];
-	#endif
+	char    buf[64*2 + 30];
 
 	last_ev = current_ev;
 
@@ -365,10 +359,8 @@ char *usbdrv_translate_scan(struct net_device *dev,
 
 	/* 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;
@@ -441,7 +433,6 @@ char *usbdrv_translate_scan(struct net_device *dev,
 	/* 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;
@@ -503,7 +494,6 @@ char *usbdrv_translate_scan(struct net_device *dev,
 			last_ev = current_ev;
 		}
 	}
-	#endif
 	/* The other data in the scan result are not really
 	* interesting, so for now drop it
 	*/
@@ -697,12 +687,9 @@ int usbdrvwext_giwrange(struct net_device *dev,
 	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 > 10
 	range->we_version_compiled = WIRELESS_EXT;
 	range->we_version_source = 13;
 
@@ -710,7 +697,6 @@ int usbdrvwext_giwrange(struct net_device *dev,
 	range->retry_flags = IW_RETRY_LIMIT;
 	range->min_retry = 0;
 	range->max_retry = 255;
-	#endif  /* WIRELESS_EXT > 10 */
 
 	channel_num = zfiWlanQueryAllowChannels(dev, channels);
 
@@ -917,13 +903,11 @@ int usbdrvwext_giwscan(struct net_device *dev,
 		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
 	}
 
 	/* Length of data */
@@ -2045,6 +2029,7 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
 	struct zsKeyInfo keyInfo;
 	struct usbdrv_private *macp = dev->ml_priv;
 	u16_t vapId = 0;
+	int ii;
 
 	/* zmw_get_wlan_dev(dev); */
 
@@ -2168,7 +2153,6 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
 		/* 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; ) {
@@ -2266,7 +2250,6 @@ int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
 		/* 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;
 
@@ -2401,7 +2384,7 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	struct athr_wlan_param zdparm;
 	struct usbdrv_private *macp = dev->ml_priv;
 
-	int err = 0;
+	int err = 0, val = 0;
 	int changed = 0;
 
 	/* regp = macp->regp; */
@@ -2445,7 +2428,7 @@ int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			err = -EPERM;
 			break;
 		}
-		int val = *((int *) wrq->u.name);
+		val = *((int *) wrq->u.name);
 		if ((val < 0) || (val > 2)) {
 			err = -EINVAL;
 			break;
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index 540cbbb..48aa30a 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -39,9 +39,7 @@
 #include "linux/netlink.h"
 #include "linux/rtnetlink.h"
 
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 #ifdef ZM_HOSTAPD_SUPPORT
 #include "athr_common.h"
@@ -113,9 +111,6 @@ extern u8_t zfLnxCreateThread(zdev_t *dev);
 
 /* Definition of Wireless Extension */
 
-#if WIRELESS_EXT > 12
-#include <net/iw_handler.h>
-#endif
 //wireless extension helper functions
 extern int usbdrv_ioctl_setessid(struct net_device *dev, struct iw_point *erq);
 extern int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq);
@@ -203,7 +198,6 @@ struct iw_priv_args usbdrv_private_args[] = {
 //    { SIOCIWFIRSTPRIV + 0xC, 0, IW_PRIV_TYPE_CHAR | 12, "get_mac_mode" },
 };
 
-#if WIRELESS_EXT > 12
 static iw_handler usbdrvwext_handler[] = {
     (iw_handler) NULL,                              /* SIOCSIWCOMMIT */
     (iw_handler) usbdrvwext_giwname,                /* SIOCGIWNAME */
@@ -229,13 +223,8 @@ static iw_handler usbdrvwext_handler[] = {
     (iw_handler) usbdrvwext_giwap,                  /* SIOCGIWAP */
     (iw_handler) NULL,              /* -- hole -- */
     (iw_handler) usbdrvwext_iwaplist,               /* SIOCGIWAPLIST */
-#if WIRELESS_EXT > 13
     (iw_handler) usbdrvwext_siwscan,                /* SIOCSIWSCAN */
     (iw_handler) usbdrvwext_giwscan,                /* SIOCGIWSCAN */
-#else /* WIRELESS_EXT > 13 */
-    (iw_handler) NULL, /* null */                   /* SIOCSIWSCAN */
-    (iw_handler) NULL, /* null */                   /* SIOCGIWSCAN */
-#endif /* WIRELESS_EXT > 13 */
     (iw_handler) usbdrvwext_siwessid,               /* SIOCSIWESSID */
     (iw_handler) usbdrvwext_giwessid,               /* SIOCGIWESSID */
 
@@ -291,7 +280,6 @@ static struct iw_handler_def p80211wext_handler_def = {
     .private = (iw_handler *) usbdrv_private_handler,
     .private_args = (struct iw_priv_args *) usbdrv_private_args
 };
-#endif
 
 /* WDS */
 //struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
@@ -659,7 +647,7 @@ int usbdrv_xmit_frame(struct sk_buff *skb, struct net_device *dev)
         netif_stop_queue(dev);
     }
 
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 
@@ -796,13 +784,13 @@ int zfLnxVapXmitFrame(struct sk_buff *skb, struct net_device *dev)
     if (vapId >= ZM_VAP_PORT_NUMBER)
     {
         dev_kfree_skb_irq(skb);
-        return 0;
+        return NETDEV_TX_OK;
     }
 #if 1
     if (vap[vapId].openFlag == 0)
     {
         dev_kfree_skb_irq(skb);
-        return 0;
+        return NETDEV_TX_OK;
     }
 #endif
 
@@ -819,7 +807,7 @@ int zfLnxVapXmitFrame(struct sk_buff *skb, struct net_device *dev)
         netif_stop_queue(dev);
     }
 
-    return 0;
+    return NETDEV_TX_OK;
 }
 
 static const struct net_device_ops vap_netdev_ops = {
@@ -1106,9 +1094,7 @@ u8_t zfLnxInitSetup(struct net_device *dev, struct usbdrv_private *macp)
     dev->dev_addr[4] = addr[4];
     dev->dev_addr[5] = addr[5];
 #endif
-#if WIRELESS_EXT > 12
     dev->wireless_handlers = (struct iw_handler_def *)&p80211wext_handler_def;
-#endif
 
     dev->netdev_ops = &otus_netdev_ops;
 
diff --git a/drivers/staging/otus/usbdrv.h b/drivers/staging/otus/usbdrv.h
index a11b3b3..7800406 100644
--- a/drivers/staging/otus/usbdrv.h
+++ b/drivers/staging/otus/usbdrv.h
@@ -61,10 +61,6 @@
 #define USB_REG_IN_PIPE                     3
 #define USB_REG_OUT_PIPE                    4
 
-#if (WLAN_HOSTIF == WLAN_USB)
-#include <linux/usb.h>
-#endif
-
 #ifdef ZM_HOSTAPD_SUPPORT
 #include "athr_common.h"
 #endif
diff --git a/drivers/staging/otus/wrap_buf.c b/drivers/staging/otus/wrap_buf.c
index 62496a0..a0f677a 100644
--- a/drivers/staging/otus/wrap_buf.c
+++ b/drivers/staging/otus/wrap_buf.c
@@ -30,10 +30,7 @@
 
 #include <linux/netlink.h>
 
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
-
 
 
 /* Called to allocate buffer, must return a continue buffer space */
diff --git a/drivers/staging/otus/wrap_dbg.c b/drivers/staging/otus/wrap_dbg.c
index 53763d9..d47e9ab 100644
--- a/drivers/staging/otus/wrap_dbg.c
+++ b/drivers/staging/otus/wrap_dbg.c
@@ -27,10 +27,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 void zfwDumpBuf(zdev_t* dev, zbuf_t* buf)
 {
diff --git a/drivers/staging/otus/wrap_ev.c b/drivers/staging/otus/wrap_ev.c
index 966b787..bcda0b9 100644
--- a/drivers/staging/otus/wrap_ev.c
+++ b/drivers/staging/otus/wrap_ev.c
@@ -28,10 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 
 /***** Management *****/
@@ -75,7 +72,6 @@ u16_t zfLnxAsocNotify(zdev_t* dev, u16_t* macAddr, u8_t* body, u16_t bodySize, u
     //            //wireless_send_event(macp->device, SIOCGIWSCAN, &wreq, NULL);
     //    wireless_send_event(macp->device, SIOCGIWAP, &wreq, NULL);
     //}
-#if WIRELESS_EXT >= 15
     //else if(macp->cardSetting.BssType == AP_BSS) {
 //        if (port == 0)
 //        {
@@ -94,7 +90,6 @@ u16_t zfLnxAsocNotify(zdev_t* dev, u16_t* macAddr, u8_t* body, u16_t bodySize, u
 //            }
 //        }
     //}
-#endif
 //#endif
 
     return 0;
@@ -185,7 +180,6 @@ void zfLnxConnectNotify(zdev_t* dev, u16_t status, u16_t* bssid)
         //            //wireless_send_event(dev, SIOCGIWSCAN, &wreq, NULL);
             wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
         }
-#if WIRELESS_EXT >= 15
         else if(zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
             //if (port == 0)
             //{
@@ -204,7 +198,6 @@ void zfLnxConnectNotify(zdev_t* dev, u16_t status, u16_t* bssid)
             //    }
             //}
         }
-#endif
     }
     //return 0;
 }
diff --git a/drivers/staging/otus/wrap_mem.c b/drivers/staging/otus/wrap_mem.c
index 8081bb2..32416d7 100644
--- a/drivers/staging/otus/wrap_mem.c
+++ b/drivers/staging/otus/wrap_mem.c
@@ -27,10 +27,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 /* Memory management */
 /* Called to allocate uncached memory, allocated memory must    */
diff --git a/drivers/staging/otus/wrap_mis.c b/drivers/staging/otus/wrap_mis.c
index 337918b..ea2199f 100644
--- a/drivers/staging/otus/wrap_mis.c
+++ b/drivers/staging/otus/wrap_mis.c
@@ -28,10 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 //extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
 extern struct zsVapStruct vap[ZM_VAP_PORT_NUMBER];
diff --git a/drivers/staging/otus/wrap_pkt.c b/drivers/staging/otus/wrap_pkt.c
index 5db0004..0d5920f 100644
--- a/drivers/staging/otus/wrap_pkt.c
+++ b/drivers/staging/otus/wrap_pkt.c
@@ -28,11 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
-
 
 
 //extern struct zsWdsStruct wds[ZM_WDS_PORT_NUMBER];
@@ -156,10 +152,7 @@ void zfLnxRecvEth(zdev_t* dev, zbuf_t* buf, u16_t port)
     switch(netif_rx(buf))
 #endif
     {
-    case NET_RX_BAD:
     case NET_RX_DROP:
-    case NET_RX_CN_MOD:
-    case NET_RX_CN_HIGH:
         break;
     default:
             macp->drv_stats.net_stats.rx_packets++;
diff --git a/drivers/staging/otus/wrap_sec.c b/drivers/staging/otus/wrap_sec.c
index f688d06..0f780ba 100644
--- a/drivers/staging/otus/wrap_sec.c
+++ b/drivers/staging/otus/wrap_sec.c
@@ -28,10 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 #ifdef ZM_ENABLE_CENC
 extern int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len);
diff --git a/drivers/staging/otus/wrap_usb.c b/drivers/staging/otus/wrap_usb.c
index c076e56..70fd410 100644
--- a/drivers/staging/otus/wrap_usb.c
+++ b/drivers/staging/otus/wrap_usb.c
@@ -28,10 +28,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 extern void zfLnxInitUsbTxQ(zdev_t* dev);
 extern void zfLnxInitUsbRxQ(zdev_t* dev);
diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c
index 4db8f6e..53d2a45 100644
--- a/drivers/staging/otus/wwrap.c
+++ b/drivers/staging/otus/wwrap.c
@@ -26,10 +26,7 @@
 #include "usbdrv.h"
 
 #include <linux/netlink.h>
-
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 
 extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo);
 extern void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo);
@@ -1018,11 +1015,6 @@ void kevent(struct work_struct *work)
                container_of(work, struct usbdrv_private, kevent);
     zdev_t *dev = macp->device;
 
-    if (macp == NULL)
-    {
-        return;
-    }
-
     if (test_and_set_bit(0, (void *)&smp_kevent_Lock))
     {
         //schedule_work(&macp->kevent);
diff --git a/drivers/staging/otus/zdcompat.h b/drivers/staging/otus/zdcompat.h
index d9a3b2d..84ac433 100644
--- a/drivers/staging/otus/zdcompat.h
+++ b/drivers/staging/otus/zdcompat.h
@@ -35,16 +35,6 @@
 #undef netdevice_t
 typedef struct net_device netdevice_t;
 
-#ifdef WIRELESS_EXT
-#if (WIRELESS_EXT < 13)
-struct iw_request_info
-{
-        __u16           cmd;            /* Wireless Extension command */
-        __u16           flags;          /* More to come ;-) */
-};
-#endif
-#endif
-
 #ifndef in_atomic
 #define in_atomic()  0
 #endif
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index c2747bc..dd7d3fd 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -243,6 +243,7 @@ static unsigned char lcd_bits[LCD_PORTS][LCD_BITS][BIT_STATES];
  */
 #define LCD_PROTO_PARALLEL      0
 #define LCD_PROTO_SERIAL        1
+#define LCD_PROTO_TI_DA8XX_LCD	2
 
 /*
  * LCD character sets
@@ -440,7 +441,8 @@ MODULE_PARM_DESC(lcd_type,
 
 static int lcd_proto = -1;
 module_param(lcd_proto, int, 0000);
-MODULE_PARM_DESC(lcd_proto, "LCD communication: 0=parallel (//), 1=serial");
+MODULE_PARM_DESC(lcd_proto, "LCD communication: 0=parallel (//), 1=serial,"
+		"2=TI LCD Interface");
 
 static int lcd_charset = -1;
 module_param(lcd_charset, int, 0000);
@@ -797,6 +799,26 @@ static void lcd_write_data_p8(int data)
 	spin_unlock(&pprt_lock);
 }
 
+/* send a command to the TI LCD panel */
+static void lcd_write_cmd_tilcd(int cmd)
+{
+	spin_lock(&pprt_lock);
+	/* present the data to the control port */
+	w_ctr(pprt, cmd);
+	udelay(60);
+	spin_unlock(&pprt_lock);
+}
+
+/* send data to the TI LCD panel */
+static void lcd_write_data_tilcd(int data)
+{
+	spin_lock(&pprt_lock);
+	/* present the data to the data port */
+	w_dtr(pprt, data);
+	udelay(60);
+	spin_unlock(&pprt_lock);
+}
+
 static void lcd_gotoxy(void)
 {
 	lcd_write_cmd(0x80	/* set DDRAM address */
@@ -870,6 +892,26 @@ static void lcd_clear_fast_p8(void)
 	lcd_gotoxy();
 }
 
+/* fills the display with spaces and resets X/Y */
+static void lcd_clear_fast_tilcd(void)
+{
+	int pos;
+	lcd_addr_x = lcd_addr_y = 0;
+	lcd_gotoxy();
+
+	spin_lock(&pprt_lock);
+	for (pos = 0; pos < lcd_height * lcd_hwidth; pos++) {
+		/* present the data to the data port */
+		w_dtr(pprt, ' ');
+		udelay(60);
+	}
+
+	spin_unlock(&pprt_lock);
+
+	lcd_addr_x = lcd_addr_y = 0;
+	lcd_gotoxy();
+}
+
 /* clears the display and resets X/Y */
 static void lcd_clear_display(void)
 {
@@ -1396,7 +1438,7 @@ void lcd_init(void)
 		if (lcd_da_pin == PIN_NOT_SET)
 			lcd_da_pin = DEFAULT_LCD_PIN_SDA;
 
-	} else {		/* PARALLEL */
+	} else if (lcd_proto == LCD_PROTO_PARALLEL) {	/* PARALLEL */
 		lcd_write_cmd = lcd_write_cmd_p8;
 		lcd_write_data = lcd_write_data_p8;
 		lcd_clear_fast = lcd_clear_fast_p8;
@@ -1407,6 +1449,10 @@ void lcd_init(void)
 			lcd_rs_pin = DEFAULT_LCD_PIN_RS;
 		if (lcd_rw_pin == PIN_NOT_SET)
 			lcd_rw_pin = DEFAULT_LCD_PIN_RW;
+	} else {
+		lcd_write_cmd = lcd_write_cmd_tilcd;
+		lcd_write_data = lcd_write_data_tilcd;
+		lcd_clear_fast = lcd_clear_fast_tilcd;
 	}
 
 	if (lcd_bl_pin == PIN_NOT_SET)
diff --git a/drivers/staging/pata_rdc/Kconfig b/drivers/staging/pata_rdc/Kconfig
deleted file mode 100644
index 7a406b0..0000000
--- a/drivers/staging/pata_rdc/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config RDC_17F3101X
-	tristate "RDC_17F3101X IDE support"
-	depends on PCI && ATA && ATA_SFF
-	---help---
-	  This is an experimental driver for RDC_17F31011 and
-	  RDC_17F31012 IDE driver.
diff --git a/drivers/staging/pata_rdc/Makefile b/drivers/staging/pata_rdc/Makefile
deleted file mode 100644
index f952c16..0000000
--- a/drivers/staging/pata_rdc/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-$(CONFIG_RDC_17F3101X)	+= pata_rdc.o
-
diff --git a/drivers/staging/pata_rdc/pata_rdc.c b/drivers/staging/pata_rdc/pata_rdc.c
deleted file mode 100644
index 6252745..0000000
--- a/drivers/staging/pata_rdc/pata_rdc.c
+++ /dev/null
@@ -1,955 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <linux/pci.h>
-#include <linux/device.h>
-
-#include <scsi/scsi_host.h>
-#include <linux/libata.h>
-
-#include "pata_rdc.h"
-
-static const struct pci_device_id rdc_pata_id_table[] = {
-	{ PCI_DEVICE(0x17F3, 0x1011), RDC_17F31011},
-	{ PCI_DEVICE(0x17F3, 0x1012), RDC_17F31012},
-	{ }	/* terminate list */
-};
-MODULE_DEVICE_TABLE(pci, rdc_pata_id_table);
-
-/* see ATA Host Adapters Standards. */
-static struct pci_bits ATA_Decode_Enable_Bits[] = {
-	{ 0x41U, 1U, 0x80UL, 0x80UL },	/* port (Channel) 0 */
-	{ 0x43U, 1U, 0x80UL, 0x80UL },	/* port (Channel) 1 */
-};
-
-static uint PCIDeviceIO_ReadPCIConfiguration(struct pci_dev *pdev, uint Offset, uint Length, void *pBuffer)
-{
-	uint funcresult;
-	unchar *pchar;
-	uint i;
-
-	funcresult = TRUE;
-
-	pchar = pBuffer;
-
-	for (i = 0; i < Length; i++) {
-		pci_read_config_byte(pdev, Offset, pchar);
-		Offset++;
-		pchar++;
-	}
-
-	funcresult = TRUE;
-
-	goto funcexit;
-funcexit:
-
-	return funcresult;
-}
-
-static uint PCIDeviceIO_WritePCIConfiguration(struct pci_dev *pdev, uint Offset, uint Length, void *pBuffer)
-{
-	uint funcresult;
-	unchar *pchar;
-	uint i;
-
-	funcresult = TRUE;
-
-	pchar = pBuffer;
-
-	for (i = 0; i < Length; i++) {
-		pci_write_config_byte(pdev, Offset, *pchar);
-		Offset++;
-		pchar++;
-	}
-
-	funcresult = TRUE;
-
-	goto funcexit;
-funcexit:
-
-	return funcresult;
-}
-
-static uint ATAHostAdapter_SetPrimaryPIO(struct pci_dev *pdev, uint DeviceID,
-					 uint PIOTimingMode, uint DMAEnable,
-					 uint PrefetchPostingEnable)
-{
-	uint funcresult;
-	uint result;
-	uint ATATimingRegister;
-	uint Device1TimingRegister;
-
-	funcresult = TRUE;
-
-	ATATimingRegister = 0;
-	Device1TimingRegister = 0;
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						 ATAConfiguration_ID_PrimaryTiming + ATAConfiguration_PCIOffset,
-						 ATAConfiguration_ID_PrimaryTiming_Size,
-						 &ATATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_Device1Timing_Size,
-						  &Device1TimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable;
-
-	switch (DeviceID) {
-	case 0:
-		/* mask clear */
-		ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device0FastTimingEnable |
-				      ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable |
-				      ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable |
-				      ATAConfiguration_PrimaryTiming_Device0DMATimingEnable |
-				      ATAConfiguration_PrimaryTiming_Device0RecoveryMode |
-				      ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode);
-
-		if (PIOTimingMode > PIO0)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0FastTimingEnable;
-
-		if (PIOTimingMode >= PIO3)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable;
-
-		if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable;
-
-		if (DMAEnable == TRUE && PIOTimingMode >= PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0DMATimingEnable;
-
-		if (PIOTimingMode <= PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0;
-		else if (PIOTimingMode == PIO3)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1;
-		else if (PIOTimingMode == PIO4)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3;
-
-		if (PIOTimingMode <= PIO1)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0;
-		else if (PIOTimingMode == PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1;
-		else if (PIOTimingMode <= PIO4)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2;
-		break;
-	case 1:
-		ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device1FastTimingEnable |
-				       ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable |
-				       ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable |
-				       ATAConfiguration_PrimaryTiming_Device1DMATimingEnable);
-
-		if (PIOTimingMode > PIO0)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1FastTimingEnable;
-
-		if (PIOTimingMode >= PIO3)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable;
-
-		if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable;
-
-		if (DMAEnable == TRUE && PIOTimingMode >= PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1DMATimingEnable;
-
-		Device1TimingRegister &= ~(ATAConfiguration_Device1Timing_PrimaryRecoveryMode |
-					   ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode);
-
-		if (PIOTimingMode <= PIO2)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_0;
-		else if (PIOTimingMode == PIO3)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_1;
-		else if (PIOTimingMode == PIO4)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryRecoveryMode_3;
-
-		if (PIOTimingMode <= PIO1)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_0;
-		else if (PIOTimingMode == PIO2)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_1;
-		else if (PIOTimingMode <= PIO4)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_2;
-		break;
-	default:
-		funcresult = FALSE;
-		goto funcexit;
-		break;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_PrimaryTiming + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_PrimaryTiming_Size,
-						   &ATATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_Device1Timing_Size,
-						   &Device1TimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	goto funcexit;
-funcexit:
-
-	return funcresult;
-}
-
-static uint ATAHostAdapter_SetSecondaryPIO(struct pci_dev *pdev, uint DeviceID,
-					   uint PIOTimingMode, uint DMAEnable,
-					   uint PrefetchPostingEnable)
-{
-	uint funcresult;
-	uint result;
-	uint ATATimingRegister;
-	uint Device1TimingRegister;
-
-	funcresult = TRUE;
-
-	ATATimingRegister = 0;
-	Device1TimingRegister = 0;
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_SecondaryTiming + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_SecondaryTiming_Size,
-						  &ATATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_Device1Timing_Size,
-						  &Device1TimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable;
-
-	switch (DeviceID) {
-	case 0:
-		/* mask clear */
-		ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device0FastTimingEnable |
-				       ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable |
-				       ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable |
-				       ATAConfiguration_PrimaryTiming_Device0DMATimingEnable |
-				       ATAConfiguration_PrimaryTiming_Device0RecoveryMode |
-				       ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode);
-
-		if (PIOTimingMode > PIO0)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0FastTimingEnable;
-
-		if (PIOTimingMode >= PIO3)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable;
-
-		if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable;
-
-		if (DMAEnable == TRUE && PIOTimingMode >= PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0DMATimingEnable;
-
-		if (PIOTimingMode <= PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0;
-		else if (PIOTimingMode == PIO3)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1;
-		else if (PIOTimingMode == PIO4)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3;
-
-		if (PIOTimingMode <= PIO1)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0;
-		else if (PIOTimingMode == PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1;
-		else if (PIOTimingMode <= PIO4)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2;
-		break;
-	case 1:
-		ATATimingRegister &= ~(ATAConfiguration_PrimaryTiming_Device1FastTimingEnable |
-				       ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable |
-				       ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable |
-				       ATAConfiguration_PrimaryTiming_Device1DMATimingEnable);
-
-		if (PIOTimingMode > PIO0)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1FastTimingEnable;
-
-		if (PIOTimingMode >= PIO3)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable;
-
-		if (PIOTimingMode >= PIO2 && PrefetchPostingEnable == TRUE)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable;
-
-		if (DMAEnable == TRUE && PIOTimingMode >= PIO2)
-			ATATimingRegister |= ATAConfiguration_PrimaryTiming_Device1DMATimingEnable;
-
-		Device1TimingRegister &= ~(ATAConfiguration_Device1Timing_SecondaryRecoveryMode |
-					   ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode);
-
-		if (PIOTimingMode <= PIO2)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_0;
-		else if (PIOTimingMode == PIO3)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_1;
-		else if (PIOTimingMode == PIO4)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryRecoveryMode_3;
-
-		if (PIOTimingMode <= PIO1)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_0;
-		else if (PIOTimingMode == PIO2)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_1;
-		else if (PIOTimingMode <= PIO4)
-			Device1TimingRegister |= ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_2;
-		break;
-	default:
-		funcresult = FALSE;
-		goto funcexit;
-		break;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_SecondaryTiming + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_SecondaryTiming_Size,
-						   &ATATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_Device1Timing + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_Device1Timing_Size,
-						   &Device1TimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	goto funcexit;
-funcexit:
-	return funcresult;
-}
-
-static uint ATAHostAdapter_SetPrimaryUDMA(struct pci_dev *pdev, uint DeviceID,
-					  uint UDMAEnable, uint UDMATimingMode)
-{
-	uint funcresult;
-	uint result;
-	uint UDMAControlRegister;
-	uint UDMATimingRegister;
-	ulong IDEIOConfigurationRegister;
-
-	funcresult = TRUE;
-	UDMAControlRegister = 0;
-	UDMATimingRegister = 0;
-	IDEIOConfigurationRegister = 0;
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_UDMAControl_Size,
-						  &UDMAControlRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_UDMATiming_Size,
-						  &UDMATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_IDEIOConfiguration_Size,
-						  &IDEIOConfigurationRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	/*Rom Code will determine the device cable type and ATA 100.*/
-	/*IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_DeviceCable80Report;*/
-	/*IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_ATA100IsSupported;*/
-
-	switch (DeviceID) {
-	case 0:
-		UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable);
-		if (UDMAEnable == TRUE)
-			UDMAControlRegister |= ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable;
-
-		IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable |
-						ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable);
-
-		if (UDMATimingMode >= UDMA5)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable;
-		else if (UDMATimingMode >= UDMA3)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable;
-
-		/* if 80 cable report */
-		UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime);
-
-		if (UDMATimingMode == UDMA0) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_0;
-		} else if (UDMATimingMode == UDMA1 ||
-			   UDMATimingMode == UDMA3 ||
-			   UDMATimingMode == UDMA5) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_1;
-		} else if (UDMATimingMode == UDMA2 ||
-			   UDMATimingMode == UDMA4) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_2;
-		}
-		break;
-	case 1:
-		UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable);
-		if (UDMAEnable == TRUE)
-			UDMAControlRegister |= ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable;
-
-		IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable |
-						ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable);
-
-		if (UDMATimingMode >= UDMA5)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable;
-		else if (UDMATimingMode >= UDMA3)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable;
-
-		/* if 80 cable report */
-		UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime);
-
-		if (UDMATimingMode == UDMA0) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_0;
-		} else if (UDMATimingMode == UDMA1 ||
-			   UDMATimingMode == UDMA3 ||
-			   UDMATimingMode == UDMA5) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_1;
-		} else if (UDMATimingMode == UDMA2 ||
-			   UDMATimingMode == UDMA4) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_2;
-		}
-		break;
-	default:
-		funcresult = FALSE;
-		goto funcexit;
-		break;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_UDMAControl_Size,
-						   &UDMAControlRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_UDMATiming_Size,
-						   &UDMATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_IDEIOConfiguration_Size,
-						   &IDEIOConfigurationRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	goto funcexit;
-funcexit:
-	return funcresult;
-}
-
-static uint ATAHostAdapter_SetSecondaryUDMA(struct pci_dev *pdev, uint DeviceID,
-					    uint UDMAEnable, uint UDMATimingMode)
-{
-	uint funcresult;
-	uint result;
-	uint UDMAControlRegister;
-	uint UDMATimingRegister;
-	ulong IDEIOConfigurationRegister;
-
-	funcresult = TRUE;
-
-	UDMAControlRegister = 0;
-	UDMATimingRegister = 0;
-	IDEIOConfigurationRegister = 0;
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_UDMAControl_Size,
-						  &UDMAControlRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_UDMATiming_Size,
-						  &UDMATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_ReadPCIConfiguration(pdev,
-						  ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset,
-						  ATAConfiguration_ID_IDEIOConfiguration_Size,
-						  &IDEIOConfigurationRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	/* Rom Code will determine the device cable type and ATA 100. */
-	/* IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_DeviceCable80Report; */
-	/* IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_ATA100IsSupported; */
-
-	switch (DeviceID) {
-	case 0:
-		UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable);
-		if (UDMAEnable == TRUE)
-			UDMAControlRegister |= ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable;
-
-		IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable |
-						ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable);
-
-		if (UDMATimingMode >= UDMA5)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable;
-		else if (UDMATimingMode >= UDMA3)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable;
-
-		/* if 80 cable report */
-		UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime);
-
-		if (UDMATimingMode == UDMA0) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_0;
-		} else if (UDMATimingMode == UDMA1 ||
-			   UDMATimingMode == UDMA3 ||
-			   UDMATimingMode == UDMA5) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_1;
-		} else if (UDMATimingMode == UDMA2 ||
-			   UDMATimingMode == UDMA4) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_2;
-		}
-		break;
-	case 1:
-		UDMAControlRegister &= ~(ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable);
-		if (UDMAEnable == TRUE)
-			UDMAControlRegister |= ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable;
-
-		IDEIOConfigurationRegister &= ~(ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable |
-						ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable);
-
-		if (UDMATimingMode >= UDMA5)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable;
-		else if (UDMATimingMode >= UDMA3)
-			IDEIOConfigurationRegister |= ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable;
-
-		/* if 80 cable report */
-		UDMATimingRegister &= ~(ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime);
-
-		if (UDMATimingMode == UDMA0) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_0;
-		} else if (UDMATimingMode == UDMA1 ||
-			   UDMATimingMode == UDMA3 ||
-			   UDMATimingMode == UDMA5) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_1;
-		} else if (UDMATimingMode == UDMA2 ||
-			   UDMATimingMode == UDMA4) {
-			UDMATimingRegister |= ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_2;
-		}
-		break;
-	default:
-		funcresult = FALSE;
-		goto funcexit;
-		break;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_UDMAControl + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_UDMAControl_Size,
-						   &UDMAControlRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_UDMATiming + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_UDMATiming_Size,
-						   &UDMATimingRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	result = PCIDeviceIO_WritePCIConfiguration(pdev,
-						   ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset,
-						   ATAConfiguration_ID_IDEIOConfiguration_Size,
-						   &IDEIOConfigurationRegister);
-	if (result == FALSE) {
-		funcresult = FALSE;
-		goto funcexit;
-	}
-
-	goto funcexit;
-funcexit:
-	return funcresult;
-}
-
-static int rdc_pata_port_start(struct ata_port *ap)
-{
-	uint    Channel;
-
-	Channel = ap->port_no;
-	dev_dbg(ap->dev, "%s: Channel: %u\n", __func__, Channel);
-	if (ap->ioaddr.bmdma_addr) {
-		return ata_port_start(ap);
-	} else {
-		dev_dbg(ap->dev, "%s: return 0!!!\n", __func__);
-		return 0;
-	}
-}
-
-static void rdc_pata_port_stop(struct ata_port *ap)
-{
-	uint    Channel;
-
-	Channel = ap->port_no;
-
-	dev_dbg(ap->dev, "%s Channel: %u\n", __func__, Channel);
-}
-
-static int rdc_pata_prereset(struct ata_link *link, unsigned long deadline)
-{
-	struct pci_dev *pdev;
-	struct ata_port *ap;
-	uint Channel;
-
-	dev_dbg(link->ap->dev, "%s\n", __func__);
-
-	ap = link->ap;
-	pdev = to_pci_dev(ap->host->dev);
-
-	Channel = ap->port_no;
-
-	/* test ATA Decode Enable Bits, should be enable. */
-	if (!pci_test_config_bits(pdev, &ATA_Decode_Enable_Bits[Channel])) {
-		dev_dbg(link->ap->dev, "%s: Channel: %u, Decode Disable\n",
-			__func__, Channel);
-		return -ENOENT;
-	} else {
-		dev_dbg(link->ap->dev, "%s: Channel: %u, Decode Enable\n",
-			__func__, Channel);
-		return ata_std_prereset(link, deadline);
-	}
-}
-
-static int rdc_pata_cable_detect(struct ata_port *ap)
-{
-	struct pci_dev *pdev;
-	uint Channel;
-	uint Mask;
-	u32 u32Value;
-
-	dev_dbg(ap->dev, "%s\n", __func__);
-
-	pdev = to_pci_dev(ap->host->dev);
-
-	Channel = ap->port_no;
-
-	if (Channel == 0)
-		Mask = ATAConfiguration_IDEIOConfiguration_PrimaryDeviceCable80Report;
-	else
-		Mask = ATAConfiguration_IDEIOConfiguration_SecondaryDeviceCable80Report;
-
-	/* check BIOS cable detect results */
-	pci_read_config_dword(pdev, ATAConfiguration_ID_IDEIOConfiguration + ATAConfiguration_PCIOffset, &u32Value);
-
-	if ((u32Value & Mask) == 0) {
-		dev_dbg(ap->dev, "%s: Channel: %u, PATA40 \n",
-			__func__, Channel);
-		return ATA_CBL_PATA40;
-	} else {
-		dev_dbg(ap->dev, "%s: Channel: %u, PATA80 \n",
-			__func__, Channel);
-		return ATA_CBL_PATA80;
-	}
-}
-
-static void rdc_pata_set_piomode(struct ata_port *ap, struct ata_device *adev)
-{
-	struct pci_dev *pdev;
-	uint    Channel;
-	uint    DeviceID;
-	uint    PIOTimingMode;
-	uint    PrefetchPostingEnable;
-
-	dev_dbg(ap->dev, "%s\n", __func__);
-
-	pdev = to_pci_dev(ap->host->dev);
-
-	Channel = ap->port_no;
-	DeviceID = adev->devno;
-	/*
-	 * piomode = 0, 1, 2, 3... ; adev->pio_mode = XFER_PIO_0, XFER_PIO_1,
-	 * XFER_PIO_2, XFER_PIO_3...
-	 */
-	PIOTimingMode = adev->pio_mode - XFER_PIO_0;
-
-	if (adev->class == ATA_DEV_ATA) {
-		PrefetchPostingEnable = TRUE;
-	} else {
-		/* ATAPI, CD DVD Rom */
-		PrefetchPostingEnable = FALSE;
-	}
-
-	/* PIO configuration clears DTE unconditionally.  It will be
-	 * programmed in set_dmamode which is guaranteed to be called
-	 * after set_piomode if any DMA mode is available.
-	 */
-
-	/* Ensure the UDMA bit is off - it will be turned back on if UDMA is
-	 * selected */
-
-	if (Channel == 0) {
-		ATAHostAdapter_SetPrimaryPIO(
-		    pdev,
-		    DeviceID,
-		    PIOTimingMode,
-		    TRUE,
-		    PrefetchPostingEnable
-		    );
-
-		ATAHostAdapter_SetPrimaryUDMA(
-		    pdev,
-		    DeviceID,
-		    FALSE,
-		    UDMA0
-		    );
-	} else {
-		ATAHostAdapter_SetSecondaryPIO(
-		    pdev,
-		    DeviceID,
-		    PIOTimingMode,
-		    TRUE,
-		    PrefetchPostingEnable
-		    );
-
-		ATAHostAdapter_SetSecondaryUDMA(
-		    pdev,
-		    DeviceID,
-		    FALSE,
-		    UDMA0
-		    );
-	}
-	dev_dbg(ap->dev, "%s: Channel: %u, DeviceID: %u, PIO: %d\n",
-		__func__, Channel, DeviceID, PIOTimingMode);
-}
-
-static void rdc_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev)
-{
-	struct pci_dev *pdev;
-	uint    Channel;
-	uint    DeviceID;
-	uint    PIOTimingMode;
-	uint    PrefetchPostingEnable;
-	uint    DMATimingMode;
-	uint    UDMAEnable;
-
-	dev_dbg(ap->dev, "%s\n", __func__);
-
-	pdev = to_pci_dev(ap->host->dev);
-
-	Channel = ap->port_no;
-	DeviceID = adev->devno;
-	PIOTimingMode = adev->pio_mode - XFER_PIO_0;  /* piomode = 0, 1, 2, 3... ; adev->pio_mode = XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3... */
-	DMATimingMode = adev->dma_mode; /* UDMA or MDMA */
-
-	if (adev->class == ATA_DEV_ATA) {
-		PrefetchPostingEnable = TRUE;
-	} else {
-		/* ATAPI, CD DVD Rom */
-		PrefetchPostingEnable = FALSE;
-	}
-
-	if (ap->udma_mask == 0) {
-		/* ata_port dont support udma. depend on hardware spec. */
-		UDMAEnable = FALSE;
-	} else {
-		UDMAEnable = TRUE;
-	}
-
-	if (Channel == 0) {
-		if (DMATimingMode >= XFER_UDMA_0) {
-			/* UDMA */
-			ATAHostAdapter_SetPrimaryPIO(pdev,
-				DeviceID,
-				PIOTimingMode,
-				TRUE,
-				PrefetchPostingEnable);
-
-			ATAHostAdapter_SetPrimaryUDMA(pdev,
-				DeviceID,
-				UDMAEnable,
-				DMATimingMode - XFER_UDMA_0);
-			dev_dbg(ap->dev,
-				"%s: Channel: %u, DeviceID: %u, UDMA: %u\n",
-				__func__, Channel, DeviceID,
-				(uint)(DMATimingMode - XFER_UDMA_0));
-		} else {
-			/* MDMA */
-			ATAHostAdapter_SetPrimaryPIO(pdev,
-				DeviceID,
-				(DMATimingMode - XFER_MW_DMA_0) + PIO2, /* MDMA0 = PIO2 */
-				TRUE,
-				PrefetchPostingEnable);
-
-			ATAHostAdapter_SetPrimaryUDMA(pdev,
-				DeviceID,
-				FALSE,
-				UDMA0);
-			dev_dbg(ap->dev,
-				"%s: Channel: %u, DeviceID: %u, MDMA: %u\n",
-				__func__, Channel, DeviceID,
-				(uint)(DMATimingMode - XFER_MW_DMA_0));
-		}
-	} else {
-		if (DMATimingMode >= XFER_UDMA_0) {
-			/* UDMA */
-			ATAHostAdapter_SetSecondaryPIO(pdev,
-				DeviceID,
-				PIOTimingMode,
-				TRUE,
-				PrefetchPostingEnable);
-
-			ATAHostAdapter_SetSecondaryUDMA(pdev,
-				DeviceID,
-				UDMAEnable,
-				DMATimingMode - XFER_UDMA_0);
-			dev_dbg(ap->dev,
-				"%s: Channel: %u, DeviceID: %u, UDMA: %u\n",
-				__func__, Channel, DeviceID,
-				(uint)(DMATimingMode - XFER_UDMA_0));
-		} else {
-			/* MDMA */
-			ATAHostAdapter_SetSecondaryPIO(pdev,
-				DeviceID,
-				(DMATimingMode - XFER_MW_DMA_0) + PIO2, /* MDMA0 = PIO2 */
-				TRUE,
-				PrefetchPostingEnable);
-
-			ATAHostAdapter_SetSecondaryUDMA(pdev,
-				DeviceID,
-				FALSE,
-				UDMA0);
-			dev_dbg(ap->dev,
-				"%s: Channel: %u, DeviceID: %u, MDMA: %u \n",
-				__func__, Channel, DeviceID,
-				(uint)(DMATimingMode - XFER_MW_DMA_0));
-		}
-	}
-}
-
-static struct scsi_host_template rdc_pata_sht = {
-	ATA_BMDMA_SHT(KBUILD_MODNAME),
-};
-
-static struct ata_port_operations rdc_pata_ops = {
-	.inherits	= &ata_bmdma_port_ops,
-
-	.port_start	= rdc_pata_port_start,
-	.port_stop	= rdc_pata_port_stop,
-	.prereset	= rdc_pata_prereset,
-	.cable_detect	= rdc_pata_cable_detect,
-	.set_piomode	= rdc_pata_set_piomode,
-	.set_dmamode	= rdc_pata_set_dmamode,
-};
-
-static struct ata_port_info rdc_pata_port_info[] = {
-	[RDC_17F31011] = {
-	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,		/* pio0-4 */
-	.mwdma_mask	= 0x07,		/* mwdma0-2 */
-	.udma_mask	= ATA_UDMA5,	/* udma0-5 */
-	.port_ops	= &rdc_pata_ops,
-	},
-
-	[RDC_17F31012] = {
-	.flags		= ATA_FLAG_SLAVE_POSS,
-	.pio_mask	= 0x1f,		/* pio0-4 */
-	.mwdma_mask	= 0x07,		/* mwdma0-2 */
-	.udma_mask	= ATA_UDMA5,	/* udma0-5 */
-	.port_ops	= &rdc_pata_ops,
-	},
-};
-
-static int __devinit rdc_init_one(struct pci_dev *pdev,
-				  const struct pci_device_id *ent)
-{
-	struct ata_port_info port_info[2];
-	const struct ata_port_info *ppinfo[] = { &port_info[0], &port_info[1] };
-
-	int rc;
-
-	dev_dbg(&pdev->dev, "%s\n", __func__);
-
-	port_info[0] = rdc_pata_port_info[ent->driver_data];
-	port_info[1] = rdc_pata_port_info[ent->driver_data];
-
-	rc = pci_enable_device(pdev);
-	if (rc) {
-		dev_dbg(&pdev->dev, "%s pci_enable_device failed\n", __func__);
-		return rc;
-	}
-	pci_intx(pdev, 1);
-
-	return ata_pci_sff_init_one(pdev, ppinfo, &rdc_pata_sht, NULL);
-}
-
-static struct pci_driver rdc_pata_driver = {
-	.name		= KBUILD_MODNAME,
-	.id_table	= rdc_pata_id_table,
-	.probe		= rdc_init_one,
-	.remove		= ata_pci_remove_one,
-#ifdef CONFIG_PM
-	.suspend	= ata_pci_device_suspend,
-	.resume		= ata_pci_device_resume,
-#endif
-};
-
-static int __init pata_rdc_init(void)
-{
-	return pci_register_driver(&rdc_pata_driver);
-}
-
-static void __exit pata_rdc_exit(void)
-{
-	pci_unregister_driver(&rdc_pata_driver);
-}
-
-module_init(pata_rdc_init);
-module_exit(pata_rdc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("RDC PCI IDE Driver");
diff --git a/drivers/staging/pata_rdc/pata_rdc.h b/drivers/staging/pata_rdc/pata_rdc.h
deleted file mode 100644
index a833339..0000000
--- a/drivers/staging/pata_rdc/pata_rdc.h
+++ /dev/null
@@ -1,144 +0,0 @@
-#ifndef pata_rdc_H
-#define pata_rdc_H
-
-#ifndef TRUE
-#define TRUE	1
-#endif
-
-#ifndef FALSE
-#define FALSE	0
-#endif
-
-/* ATA Configuration Register ID offset address size */
-#define ATAConfiguration_PCIOffset			0x40
-#define ATAConfiguration_ID_PrimaryTiming		0x00
-#define ATAConfiguration_ID_SecondaryTiming		0x02
-#define ATAConfiguration_ID_Device1Timing		0x04
-#define ATAConfiguration_ID_UDMAControl			0x08
-#define ATAConfiguration_ID_UDMATiming			0x0A
-#define ATAConfiguration_ID_IDEIOConfiguration		0x14
-
-#define ATAConfiguration_ID_PrimaryTiming_Size		2
-#define ATAConfiguration_ID_SecondaryTiming_Size	2
-#define ATAConfiguration_ID_Device1Timing_Size		1
-#define ATAConfiguration_ID_UDMAControl_Size		1
-#define ATAConfiguration_ID_UDMATiming_Size		2
-#define ATAConfiguration_ID_IDEIOConfiguration_Size	4
-
-/* ATA Configuration Register bit define */
-#define ATAConfiguration_PrimaryTiming_Device0FastTimingEnable		0x0001
-#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleModeEnable	0x0002	/* PIO 3 or greater */
-#define ATAConfiguration_PrimaryTiming_Device0PrefetchandPostingEnable	0x0004	/* PIO 2 or greater */
-#define ATAConfiguration_PrimaryTiming_Device0DMATimingEnable		0x0008
-#define ATAConfiguration_PrimaryTiming_Device1FastTimingEnable		0x0010
-#define ATAConfiguration_PrimaryTiming_Device1IORDYSampleModeEnable	0x0020	/* PIO 3 or greater */
-#define ATAConfiguration_PrimaryTiming_Device1PrefetchandPostingEnable	0x0040	/* PIO 2 or greater */
-#define ATAConfiguration_PrimaryTiming_Device1DMATimingEnable		0x0080
-#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode		0x0300
-#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_0		0x0000	/* PIO 0, PIO 2, MDMA 0 */
-#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_1		0x0100	/* PIO 3, MDMA 1 */
-#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_2		0x0200	/* X */
-#define ATAConfiguration_PrimaryTiming_Device0RecoveryMode_3		0x0300	/* PIO 4, MDMA 2 */
-#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode		0x3000
-#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_0		0x0000	/* PIO 0 */
-#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_1		0x1000	/* PIO 2, MDMA 0 */
-#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_2		0x2000	/* PIO 3, PIO 4, MDMA 1, MDMA 2 */
-#define ATAConfiguration_PrimaryTiming_Device0IORDYSampleMode_3		0x3000	/* X */
-#define ATAConfiguration_PrimaryTiming_Device1TimingRegisterEnable	0x4000
-#define ATAConfiguration_PrimaryTiming_IDEDecodeEnable			0x8000
-
-#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode		0x0003
-#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_0		0x0000
-#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_1		0x0001
-#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_2		0x0002
-#define ATAConfiguration_Device1Timing_PrimaryRecoveryMode_3		0x0003
-#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode		0x000C
-#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_0		0x0000
-#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_1		0x0004
-#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_2		0x0008
-#define ATAConfiguration_Device1Timing_PrimaryIORDYSampleMode_3		0x000C
-#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode		0x0030
-#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_0		0x0000
-#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_1		0x0010
-#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_2		0x0020
-#define ATAConfiguration_Device1Timing_SecondaryRecoveryMode_3		0x0030
-#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode		0x00C0
-#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_0	0x0000
-#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_1	0x0040
-#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_2	0x0080
-#define ATAConfiguration_Device1Timing_SecondaryIORDYSampleMode_3	0x00C0
-
-#define ATAConfiguration_UDMAControl_PrimaryDevice0UDMAModeEnable	0x0001
-#define ATAConfiguration_UDMAControl_PrimaryDevice1UDMAModeEnable	0x0002
-#define ATAConfiguration_UDMAControl_SecondaryDevice0UDMAModeEnable	0x0004
-#define ATAConfiguration_UDMAControl_SecondaryDevice1UDMAModeEnable	0x0008
-
-#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime		0x0003
-#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_0		0x0000	/* UDMA 0 */
-#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_1		0x0001	/* UDMA 1, UDMA 3, UDMA 5 */
-#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_2		0x0002	/* UDMA 2, UDMA 4 */
-#define ATAConfiguration_UDMATiming_PrimaryDevice0CycleTime_3		0x0003	/* X */
-#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime		0x0030
-#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_0		0x0000	/* UDMA 0 */
-#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_1		0x0010	/* UDMA 1, UDMA 3, UDMA 5 */
-#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_2		0x0020	/* UDMA 2, UDMA 4 */
-#define ATAConfiguration_UDMATiming_PrimaryDevice1CycleTime_3		0x0030	/* X */
-#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime		0x0300
-#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_0		0x0000	/* UDMA 0 */
-#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_1		0x0100	/* UDMA 1, UDMA 3, UDMA 5 */
-#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_2		0x0200	/* UDMA 2, UDMA 4 */
-#define ATAConfiguration_UDMATiming_SecondaryDevice0CycleTime_3		0x0300	/* X */
-#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime		0x3000
-#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_0		0x0000	/* UDMA 0 */
-#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_1		0x1000	/* UDMA 1, UDMA 3, UDMA 5 */
-#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_2		0x2000	/* UDMA 2, UDMA 4 */
-#define ATAConfiguration_UDMATiming_SecondaryDevice1CycleTime_3		0x3000	/* X */
-
-#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice066MhzEnable		0x00000001	/* UDMA 3, UDMA 4 */
-#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice166MhzEnable		0x00000002
-#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice066MhzEnable		0x00000004
-#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice166MhzEnable		0x00000008
-#define ATAConfiguration_IDEIOConfiguration_DeviceCable80Report			0x000000F0
-#define ATAConfiguration_IDEIOConfiguration_PrimaryDeviceCable80Report		0x00000030
-#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice0Cable80Report		0x00000010	/* UDMA 3, UDMA 4, UDMA 5 */
-#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice1Cable80Report		0x00000020
-#define ATAConfiguration_IDEIOConfiguration_SecondaryDeviceCable80Report	0x000000C0
-#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice0Cable80Report	0x00000040
-#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice1Cable80Report	0x00000080
-#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice0100MhzEnable		0x00001000	/* UDMA 5 */
-#define ATAConfiguration_IDEIOConfiguration_PrimaryDevice1100MhzEnable		0x00002000
-#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice0100MhzEnable	0x00004000
-#define ATAConfiguration_IDEIOConfiguration_SecondaryDevice1100MhzEnable	0x00008000
-#define ATAConfiguration_IDEIOConfiguration_ATA100IsSupported			0x00F00000
-
-enum _PIOTimingMode {
-	PIO0 = 0,
-	PIO1,
-	PIO2,	/* MDMA 0 */
-	PIO3,	/* MDMA 1 */
-	PIO4	/* MDMA 2 */
-};
-
-enum _DMATimingMode {
-	MDMA0 = 0,
-	MDMA1,
-	MDMA2
-};
-
-enum _UDMATimingMode {
-	UDMA0 = 0,
-	UDMA1,
-	UDMA2,
-	UDMA3,
-	UDMA4,
-	UDMA5
-};
-
-
-enum rdc_controller_ids {
-	/* controller IDs */
-	RDC_17F31011,
-	RDC_17F31012
-};
-
-#endif
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
index a6eaa42..90f962e 100644
--- a/drivers/staging/pohmelfs/config.c
+++ b/drivers/staging/pohmelfs/config.c
@@ -284,9 +284,91 @@ static int pohmelfs_cn_disp(struct cn_msg *msg)
 		i += 1;
 	}
 
+ out_unlock:
+	mutex_unlock(&pohmelfs_config_lock);
+	return err;
+}
+
+static int pohmelfs_cn_dump(struct cn_msg *msg)
+{
+	struct pohmelfs_config_group *g;
+	struct pohmelfs_config *c, *tmp;
+	int err = 0, i = 1;
+	int total_msg = 0;
+
+	if (msg->len != sizeof(struct pohmelfs_ctl))
+		return -EBADMSG;
+
+	mutex_lock(&pohmelfs_config_lock);
+
+	list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+		if (g)
+			total_msg += g->num_entry;
+	}
+	if (total_msg == 0) {
+		if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+			err = -ENOMEM;
+		goto out_unlock;
+	}
+
+	list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+		if (g) {
+			list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+				struct pohmelfs_ctl *sc = &c->state.ctl;
+				if (pohmelfs_send_reply(err, total_msg - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
+					err = -ENOMEM;
+					goto out_unlock;
+				}
+				i += 1;
+			}
+		}
+	}
+
 out_unlock:
-        mutex_unlock(&pohmelfs_config_lock);
-        return err;
+	mutex_unlock(&pohmelfs_config_lock);
+	return err;
+}
+
+static int pohmelfs_cn_flush(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;
+
+	if (msg->len != sizeof(struct pohmelfs_ctl))
+		return -EBADMSG;
+
+	mutex_lock(&pohmelfs_config_lock);
+
+	if (ctl->idx != POHMELFS_NULL_IDX) {
+		g = pohmelfs_find_config_group(ctl->idx);
+
+		if (!g)
+			goto out_unlock;
+
+		list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+			list_del(&c->config_entry);
+			g->num_entry--;
+			kfree(c);
+		}
+	} else {
+		list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+			if (g) {
+				list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+					list_del(&c->config_entry);
+					g->num_entry--;
+					kfree(c);
+				}
+			}
+		}
+	}
+
+out_unlock:
+	mutex_unlock(&pohmelfs_config_lock);
+	pohmelfs_cn_dump(msg);
+
+	return err;
 }
 
 static int pohmelfs_modify_config(struct pohmelfs_ctl *old, struct pohmelfs_ctl *new)
@@ -350,7 +432,7 @@ static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
 
 	list_add_tail(&c->config_entry, &g->config_list);
 
-out_unlock:
+ out_unlock:
 	mutex_unlock(&pohmelfs_config_lock);
 	if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
 		err = -ENOMEM;
@@ -408,7 +490,6 @@ static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct p
 	return 0;
 }
 
-
 static int pohmelfs_cn_crypto(struct cn_msg *msg)
 {
 	struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
@@ -446,9 +527,8 @@ out_unlock:
 	return err;
 }
 
-static void pohmelfs_cn_callback(void *data)
+static void pohmelfs_cn_callback(struct cn_msg *msg)
 {
-	struct cn_msg *msg = data;
 	int err;
 
 	switch (msg->flags) {
@@ -457,9 +537,15 @@ static void pohmelfs_cn_callback(void *data)
 		case POHMELFS_FLAGS_MODIFY:
 			err = pohmelfs_cn_ctl(msg, msg->flags);
 			break;
+		case POHMELFS_FLAGS_FLUSH:
+			err = pohmelfs_cn_flush(msg);
+			break;
 		case POHMELFS_FLAGS_SHOW:
 			err = pohmelfs_cn_disp(msg);
 			break;
+		case POHMELFS_FLAGS_DUMP:
+			err = pohmelfs_cn_dump(msg);
+			break;
 		case POHMELFS_FLAGS_CRYPTO:
 			err = pohmelfs_cn_crypto(msg);
 			break;
@@ -498,7 +584,8 @@ int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
 
 int __init pohmelfs_config_init(void)
 {
-	return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", pohmelfs_cn_callback);
+	/* XXX remove (void *) cast when vanilla connector got synced */
+	return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", (void *)pohmelfs_cn_callback);
 }
 
 void pohmelfs_config_exit(void)
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
index 19781ad..884183c 100644
--- a/drivers/staging/pohmelfs/crypto.c
+++ b/drivers/staging/pohmelfs/crypto.c
@@ -176,7 +176,7 @@ static int pohmelfs_crypto_process(struct ablkcipher_request *req,
 					timeout);
 			if (!err)
 				err = -ETIMEDOUT;
-			else
+			else if (err > 0)
 				err = complete.error;
 			break;
 		default:
@@ -738,7 +738,7 @@ static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb)
 			psb->wait_on_page_timeout);
 	if (!err)
 		err = -ETIMEDOUT;
-	else
+	else if (err > 0)
 		err = -psb->flags;
 
 	if (!err)
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
index 4c58e22..6c5b261 100644
--- a/drivers/staging/pohmelfs/dir.c
+++ b/drivers/staging/pohmelfs/dir.c
@@ -352,7 +352,9 @@ static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
 			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;
+		err = ret;
+		if (!err)
+			err = -ETIMEDOUT;
 		goto err_out_exit;
 	}
 
@@ -412,7 +414,7 @@ static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
 				__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;
+		file->private_data = (void *)(unsigned long)n->hash;
 
 		len = n->len;
 		err = filldir(dirent, n->data, n->len, file->f_pos, n->ino, mode);
@@ -472,10 +474,11 @@ static int pohmelfs_lookup_single(struct pohmelfs_inode *parent,
 	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 (ret <= 0) {
+		err = ret;
+		if (!err)
+			err = -ETIMEDOUT;
+	}
 
 	if (err)
 		goto err_out_exit;
@@ -505,13 +508,21 @@ struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct
 	struct pohmelfs_name *n;
 	struct inode *inode = NULL;
 	unsigned long ino = 0;
-	int err, lock_type = POHMELFS_READ_LOCK, need_lock;
+	int err, lock_type = POHMELFS_READ_LOCK, need_lock = 1;
 	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);
+	if (test_bit(NETFS_INODE_OWNED, &parent->state)) {
+		if (lock_type == parent->lock_type)
+			need_lock = 0;
+		if ((lock_type == POHMELFS_READ_LOCK) && (parent->lock_type == POHMELFS_WRITE_LOCK))
+			need_lock = 0;
+	}
+
+	if ((lock_type == POHMELFS_READ_LOCK) && !test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state))
+		need_lock = 1;
 
 	str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
 
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index e63c9be..c94de31 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -921,16 +921,16 @@ ssize_t pohmelfs_write(struct file *file, const char __user *buf,
 	if (ret)
 		goto err_out_unlock;
 
-	ret = generic_file_aio_write_nolock(&kiocb, &iov, 1, pos);
+	ret = __generic_file_aio_write(&kiocb, &iov, 1, &kiocb.ki_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))) {
+	if (ret > 0) {
 		ssize_t err;
 
-		err = sync_page_range(inode, mapping, pos, ret);
+		err = generic_write_sync(file, pos, ret);
 		if (err < 0)
 			ret = err;
 		WARN_ON(ret < 0);
@@ -1504,7 +1504,9 @@ static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
 		inode->i_sb->s_op->write_inode(inode, 0);
 	}
 
+#ifdef POHMELFS_TRUNCATE_ON_INODE_FLUSH
 	truncate_inode_pages(inode->i_mapping, 0);
+#endif
 
 	pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
 	mutex_unlock(&inode->i_mutex);
@@ -1743,11 +1745,10 @@ static int pohmelfs_root_handshake(struct pohmelfs_sb *psb)
 	err = wait_event_interruptible_timeout(psb->wait,
 			(psb->flags != ~0),
 			psb->wait_on_page_timeout);
-	if (!err) {
+	if (!err)
 		err = -ETIMEDOUT;
-	} else {
+	else if (err > 0)
 		err = -psb->flags;
-	}
 
 	if (err)
 		goto err_out_exit;
@@ -1865,7 +1866,7 @@ static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
 	INIT_LIST_HEAD(&psb->crypto_active_list);
 
 	atomic_set(&psb->trans_gen, 1);
-	atomic_set(&psb->total_inodes, 0);
+	atomic_long_set(&psb->total_inodes, 0);
 
 	mutex_init(&psb->state_lock);
 	INIT_LIST_HEAD(&psb->state_list);
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
index 5f312c9..af7f262 100644
--- a/drivers/staging/pohmelfs/net.c
+++ b/drivers/staging/pohmelfs/net.c
@@ -680,7 +680,7 @@ static int pohmelfs_root_cap_response(struct netfs_state *st)
 		printk(KERN_INFO "Mounting POHMELFS (%d) "
 			"with extended attributes support.\n", psb->idx);
 
-	if (atomic_read(&psb->total_inodes) <= 1)
+	if (atomic_long_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",
@@ -1005,13 +1005,12 @@ int netfs_state_init(struct netfs_state *st)
 
 	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));
+		printk(KERN_INFO "%s: (re)connected to peer %pi4:%d.\n", __func__,
+			&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));
+		printk(KERN_INFO "%s: (re)connected to peer %pi6:%d", __func__,
+				&sin->sin6_addr, ntohs(sin->sin6_port));
 	}
 
 	return 0;
@@ -1031,13 +1030,12 @@ void netfs_state_exit(struct netfs_state *st)
 
 		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));
+			printk(KERN_INFO "%s: disconnected from peer %pi4:%d.\n", __func__,
+				&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));
+			printk(KERN_INFO "%s: disconnected from peer %pi6:%d", __func__,
+				&sin->sin6_addr, ntohs(sin->sin6_port));
 		}
 
 		sock_release(st->socket);
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
index 3b60c61..623a07d 100644
--- a/drivers/staging/pohmelfs/netfs.h
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -25,6 +25,7 @@
 #define POHMELFS_CTLINFO_ACK		1
 #define POHMELFS_NOINFO_ACK		2
 
+#define POHMELFS_NULL_IDX		65535
 
 /*
  * Network command structure.
@@ -87,6 +88,8 @@ enum {
 	POHMELFS_FLAGS_SHOW,    /* Network state control message for SHOW */
 	POHMELFS_FLAGS_CRYPTO,	/* Crypto data control message */
 	POHMELFS_FLAGS_MODIFY,	/* Network state modification message */
+	POHMELFS_FLAGS_DUMP,	/* Network state control message for SHOW ALL */
+	POHMELFS_FLAGS_FLUSH,	/* Network state control message for FLUSH */
 };
 
 /*
@@ -905,6 +908,8 @@ static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
 		pohmelfs_mcache_free(psb, m);
 }
 
+//#define POHMELFS_TRUNCATE_ON_INODE_FLUSH
+
 #endif /* __KERNEL__*/
 
 #endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
index 4587f6d..36a2535 100644
--- a/drivers/staging/pohmelfs/trans.c
+++ b/drivers/staging/pohmelfs/trans.c
@@ -468,7 +468,8 @@ int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
 				continue;
 		}
 
-		if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio))
+		if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio) &&
+				(t->flags & NETFS_TRANS_SINGLE_DST))
 			st = &psb->active_state->state;
 
 		err = netfs_trans_push(t, st);
diff --git a/drivers/staging/quatech_usb2/Kconfig b/drivers/staging/quatech_usb2/Kconfig
new file mode 100644
index 0000000..1494f42
--- /dev/null
+++ b/drivers/staging/quatech_usb2/Kconfig
@@ -0,0 +1,15 @@
+config USB_SERIAL_QUATECH_USB2
+	tristate "USB Quatech xSU2-[14]00 USB Serial Driver"
+	depends on USB_SERIAL
+	help
+	  Say Y here if you want to use a Quatech USB2.0 to serial adaptor. This
+	  driver supports the SSU2-100, DSU2-100, DSU2-400, QSU2-100, QSU2-400,
+	  ESU2-400 and ESU2-100 USB2.0 to RS232 / 485 / 422 serial adaptors.
+
+	  Some hardware has an incorrect product string and announces itself as
+	  ESU-100 (which uses the serqt driver) even though it is an ESU2-100.
+	  Check the label on the bottom of your device.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called quatech_usb2 .
+
diff --git a/drivers/staging/quatech_usb2/Makefile b/drivers/staging/quatech_usb2/Makefile
new file mode 100644
index 0000000..bcd1f89
--- /dev/null
+++ b/drivers/staging/quatech_usb2/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SERIAL_QUATECH_USB2)		+= quatech_usb2.o
diff --git a/drivers/staging/quatech_usb2/TODO b/drivers/staging/quatech_usb2/TODO
new file mode 100644
index 0000000..67f61db
--- /dev/null
+++ b/drivers/staging/quatech_usb2/TODO
@@ -0,0 +1,8 @@
+Incomplete list of things that this driver does not yet implement completely or
+at all. some of these may not be possible to implement because the hardware
+support does not exist. Others may be possible, but the magic control codes to
+make them happen are unknown, and some may just need the driver support to
+implement them writing.
+
+* Mark/Space parity is not implemented (reported back correctly)
+* IXANY flow control mode is not implemented (flag ignored completely)
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
new file mode 100644
index 0000000..2acef94
--- /dev/null
+++ b/drivers/staging/quatech_usb2/quatech_usb2.c
@@ -0,0 +1,2025 @@
+/*
+ * Driver for Quatech Inc USB2.0 to serial adaptors. Largely unrelated to the
+ * serqt_usb driver, based on a re-write of the vendor supplied serqt_usb2 code,
+ * which is unrelated to the serqt_usb2 in the staging kernel
+ */
+
+#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/usb.h>
+#include <linux/usb/serial.h>
+#include <linux/uaccess.h>
+
+static int debug;
+
+/* Version Information */
+#define DRIVER_VERSION "v2.00"
+#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc"
+#define DRIVER_DESC "Quatech USB 2.0 to Serial Driver"
+
+/* vendor and device IDs */
+#define	USB_VENDOR_ID_QUATECH 0x061d	/* Quatech VID */
+#define QUATECH_SSU2_100 0xC120		/* RS232 single port */
+#define QUATECH_DSU2_100 0xC140		/* RS232 dual port */
+#define QUATECH_DSU2_400 0xC150		/* RS232/422/485 dual port */
+#define QUATECH_QSU2_100 0xC160		/* RS232 four port */
+#define QUATECH_QSU2_400 0xC170		/* RS232/422/485 four port */
+#define QUATECH_ESU2_100 0xC1A0		/* RS232 eight port */
+#define QUATECH_ESU2_400 0xC180		/* RS232/422/485 eight port */
+
+/* magic numbers go here, when we find out which ones are needed */
+
+#define QU2BOXPWRON 0x8000		/* magic number to turn FPGA power on */
+#define QU2BOX232 0x40			/* RS232 mode on MEI devices */
+#define QU2BOXSPD9600 0x60		/* set speed to 9600 baud */
+#define QT2_FIFO_DEPTH 1024			/* size of hardware fifos */
+#define QT2_TX_HEADER_LENGTH	5
+/* length of the header sent to the box with each write URB */
+
+/* directions for USB transfers */
+#define USBD_TRANSFER_DIRECTION_IN    0xc0
+#define USBD_TRANSFER_DIRECTION_OUT   0x40
+
+/* special Quatech command IDs. These are pushed down the
+ USB control pipe to get the box on the end to do things */
+#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 QT2_GET_SET_REGISTER			0xc0
+#define QT2_GET_SET_UART			0xc1
+#define QT2_HW_FLOW_CONTROL_MASK		0xc5
+#define QT2_SW_FLOW_CONTROL_MASK		0xc6
+#define QT2_SW_FLOW_CONTROL_DISABLE		0xc7
+#define QT2_BREAK_CONTROL 			0xc8
+#define QT2_STOP_RECEIVE			0xe0
+#define QT2_FLUSH_DEVICE			0xc4
+#define QT2_GET_SET_QMCR			0xe1
+
+/* sorts of flush we can do on */
+#define QT2_FLUSH_RX			0x00
+#define QT2_FLUSH_TX			0x01
+
+/* port setting constants, used to set up serial port speeds, flow
+ * control and so on */
+#define QT2_SERIAL_MCR_DTR	0x01
+#define QT2_SERIAL_MCR_RTS	0x02
+#define QT2_SERIAL_MCR_LOOP	0x10
+
+#define QT2_SERIAL_MSR_CTS	0x10
+#define QT2_SERIAL_MSR_CD	0x80
+#define QT2_SERIAL_MSR_RI	0x40
+#define QT2_SERIAL_MSR_DSR	0x20
+#define QT2_SERIAL_MSR_MASK	0xf0
+
+#define QT2_SERIAL_8_DATA	0x03
+#define QT2_SERIAL_7_DATA	0x02
+#define QT2_SERIAL_6_DATA	0x01
+#define QT2_SERIAL_5_DATA	0x00
+
+#define QT2_SERIAL_ODD_PARITY	0x08
+#define QT2_SERIAL_EVEN_PARITY	0x18
+#define QT2_SERIAL_TWO_STOPB	0x04
+#define QT2_SERIAL_ONE_STOPB	0x00
+
+#define QT2_MAX_BAUD_RATE	921600
+#define QT2_MAX_BAUD_REMAINDER	4608
+
+#define QT2_SERIAL_LSR_OE	0x02
+#define QT2_SERIAL_LSR_PE	0x04
+#define QT2_SERIAL_LSR_FE	0x08
+#define QT2_SERIAL_LSR_BI	0x10
+
+/* value of Line Status Register when UART has completed
+ * emptying data out on the line */
+#define QT2_LSR_TEMT     0x40
+
+/* register numbers on each UART, for use with  qt2_box_[get|set]_register*/
+#define  QT2_XMT_HOLD_REGISTER          0x00
+#define  QT2_XVR_BUFFER_REGISTER        0x00
+#define  QT2_FIFO_CONTROL_REGISTER      0x02
+#define  QT2_LINE_CONTROL_REGISTER      0x03
+#define  QT2_MODEM_CONTROL_REGISTER     0x04
+#define  QT2_LINE_STATUS_REGISTER       0x05
+#define  QT2_MODEM_STATUS_REGISTER      0x06
+
+/* handy macros for doing escape sequence parsing on data reads */
+#define THISCHAR	((unsigned char *)(urb->transfer_buffer))[i]
+#define NEXTCHAR	((unsigned char *)(urb->transfer_buffer))[i + 1]
+#define THIRDCHAR	((unsigned char *)(urb->transfer_buffer))[i + 2]
+#define FOURTHCHAR	((unsigned char *)(urb->transfer_buffer))[i + 3]
+#define FIFTHCHAR	((unsigned char *)(urb->transfer_buffer))[i + 4]
+
+static struct usb_device_id quausb2_id_table[] = {
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_SSU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_DSU2_400)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_QSU2_400)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_100)},
+	{USB_DEVICE(USB_VENDOR_ID_QUATECH, QUATECH_ESU2_400)},
+	{}	/* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, quausb2_id_table);
+
+/* custom structures we need go here */
+static struct usb_driver quausb2_usb_driver = {
+	.name = "quatech-usb2-serial",
+	.probe = usb_serial_probe,
+	.disconnect = usb_serial_disconnect,
+	.id_table = quausb2_id_table,
+	.no_dynamic_id = 1,
+};
+
+/**
+ * quatech2_port: Structure in which to keep all the messy stuff that this
+ * driver needs alongside the usb_serial_port structure
+ * @read_urb_busy: Flag indicating that port->read_urb is in use
+ * @close_pending: flag indicating that this port is in the process of
+ * being closed (and so no new reads / writes should be started).
+ * @shadowLSR: Last received state of the line status register, holds the
+ * value of the line status flags from the port
+ * @shadowMSR: Last received state of the modem status register, holds
+ * the value of the modem status received from the port
+ * @rcv_flush: Flag indicating that a receive flush has occured on
+ * the hardware.
+ * @xmit_flush: Flag indicating that a transmit flush has been processed by
+ * the hardware.
+ * @tx_pending_bytes: Number of bytes waiting to be sent. This total
+ * includes the size (excluding header) of URBs that have been submitted but
+ * have not yet been sent to to the device, and bytes that have been sent out
+ * of the port but not yet reported sent by the "xmit_empty" messages (which
+ * indicate the number of bytes sent each time they are recieved, despite the
+ * misleading name).
+ * - Starts at zero when port is initialised.
+ * - is incremented by the size of the data to be written (no headers)
+ * each time a write urb is dispatched.
+ * - is decremented each time a "transmit empty" message is received
+ * by the driver in the data stream.
+ * @lock: Mutex to lock access to this structure when we need to ensure that
+ * races don't occur to access bits of it.
+ * @open_count: The number of uses of the port currently having
+ * it open, i.e. the reference count.
+ */
+struct quatech2_port {
+	int	magic;
+	bool	read_urb_busy;
+	bool	close_pending;
+	__u8	shadowLSR;
+	__u8	shadowMSR;
+	bool	rcv_flush;
+	bool	xmit_flush;
+	int	tx_pending_bytes;
+	struct mutex modelock;
+	int	open_count;
+
+	char	active;		/* someone has this device open */
+	unsigned char		*xfer_to_tty_buffer;
+	wait_queue_head_t	wait;
+	__u8	shadowLCR;	/* last LCR value received */
+	__u8	shadowMCR;	/* last MCR value received */
+	char	RxHolding;
+	struct semaphore	pend_xmit_sem;	/* locks this structure */
+	spinlock_t lock;
+};
+
+/**
+ * Structure to hold device-wide internal status information
+ * @param ReadBulkStopped The last bulk read attempt ended in tears
+ * @param open_ports The number of serial ports currently in use on the box
+ * @param current_port Pointer to the serial port structure of the port which
+ * the read stream is currently directed to. Escape sequences in the read
+ * stream will change this around as data arrives from different ports on the
+ * box
+ * @buffer_size: The max size buffer each URB can take, used to set the size of
+ * the buffers allocated for writing to each port on the device (we need to
+ * store this because it is known only to the endpoint, but used each time a
+ * port is opened and a new buffer is allocated.
+ */
+struct quatech2_dev {
+	bool	ReadBulkStopped;
+	char	open_ports;
+	struct usb_serial_port *current_port;
+	int 	buffer_size;
+};
+
+/* structure which holds line and modem status flags */
+struct qt2_status_data {
+	__u8 line_status;
+	__u8 modem_status;
+};
+
+/* Function prototypes */
+static int qt2_boxpoweron(struct usb_serial *serial);
+static int qt2_boxsetQMCR(struct usb_serial *serial, __u16 Uart_Number,
+			__u8 QMCR_Value);
+static int port_paranoia_check(struct usb_serial_port *port,
+			const char *function);
+static int serial_paranoia_check(struct usb_serial *serial,
+			 const char *function);
+static inline struct quatech2_port *qt2_get_port_private(struct usb_serial_port
+			*port);
+static inline void qt2_set_port_private(struct usb_serial_port *port,
+			struct quatech2_port *data);
+static inline struct quatech2_dev *qt2_get_dev_private(struct usb_serial
+			*serial);
+static inline void qt2_set_dev_private(struct usb_serial *serial,
+			struct quatech2_dev *data);
+static int qt2_openboxchannel(struct usb_serial *serial, __u16
+			Uart_Number, struct qt2_status_data *pDeviceData);
+static int qt2_closeboxchannel(struct usb_serial *serial, __u16
+			Uart_Number);
+static int qt2_conf_uart(struct usb_serial *serial,  unsigned short Uart_Number,
+			 unsigned short divisor, unsigned char LCR);
+static void qt2_read_bulk_callback(struct urb *urb);
+static void qt2_write_bulk_callback(struct urb *urb);
+static void qt2_process_line_status(struct usb_serial_port *port,
+			      unsigned char LineStatus);
+static void qt2_process_modem_status(struct usb_serial_port *port,
+			       unsigned char ModemStatus);
+static void qt2_process_xmit_empty(struct usb_serial_port *port,
+	unsigned char fourth_char, unsigned char fifth_char);
+static void qt2_process_port_change(struct usb_serial_port *port,
+			      unsigned char New_Current_Port);
+static void qt2_process_rcv_flush(struct usb_serial_port *port);
+static void qt2_process_xmit_flush(struct usb_serial_port *port);
+static void qt2_process_rx_char(struct usb_serial_port *port,
+				unsigned char data);
+static int qt2_box_get_register(struct usb_serial *serial,
+		unsigned char uart_number, unsigned short register_num,
+		__u8 *pValue);
+static int qt2_box_set_register(struct usb_serial *serial,
+		unsigned short Uart_Number, unsigned short Register_Num,
+		unsigned short Value);
+static int qt2_box_flush(struct usb_serial *serial,  unsigned char uart_number,
+		unsigned short rcv_or_xmit);
+static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
+		unsigned short default_divisor, unsigned char default_LCR);
+static int qt2_boxsethw_flowctl(struct usb_serial *serial,
+		unsigned int UartNumber, bool bSet);
+static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber,
+		unsigned char stop_char,  unsigned char start_char);
+static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber);
+static int qt2_boxstoprx(struct usb_serial *serial, unsigned short uart_number,
+			 unsigned short stop);
+
+/* implementation functions, roughly in order of use, are here */
+static int qt2_calc_num_ports(struct usb_serial *serial)
+{
+	int num_ports;
+	int flag_as_400;
+	switch (serial->dev->descriptor.idProduct) {
+	case QUATECH_SSU2_100:
+		num_ports = 1;
+		break;
+
+	case QUATECH_DSU2_400:
+		flag_as_400 = true;
+	case QUATECH_DSU2_100:
+		num_ports = 2;
+	break;
+
+	case QUATECH_QSU2_400:
+		flag_as_400 = true;
+	case QUATECH_QSU2_100:
+		num_ports = 4;
+	break;
+
+	case QUATECH_ESU2_400:
+		flag_as_400 = true;
+	case QUATECH_ESU2_100:
+		num_ports = 8;
+	break;
+	default:
+	num_ports = 1;
+	break;
+	}
+	return num_ports;
+}
+
+static int qt2_attach(struct usb_serial *serial)
+{
+	struct usb_serial_port *port;
+	struct quatech2_port *qt2_port;	/* port-specific private data pointer */
+	struct quatech2_dev  *qt2_dev;	/* dev-specific private data pointer */
+	int i;
+	/* stuff for storing endpoint addresses now */
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_host_interface *iface_desc;
+	struct usb_serial_port *port0;	/* first port structure on device */
+
+	/* check how many endpoints there are on the device, for
+	 * sanity's sake */
+	dbg("%s(): Endpoints: %d bulk in, %d bulk out, %d interrupt in",
+			__func__, serial->num_bulk_in,
+			serial->num_bulk_out, serial->num_interrupt_in);
+	if ((serial->num_bulk_in != 1) || (serial->num_bulk_out != 1)) {
+		dbg("Device has wrong number of bulk endpoints!");
+		return -ENODEV;
+	}
+	iface_desc = serial->interface->cur_altsetting;
+
+	/* Set up per-device private data, storing extra data alongside
+	 * struct usb_serial */
+	qt2_dev = kzalloc(sizeof(*qt2_dev), GFP_KERNEL);
+	if (!qt2_dev) {
+		dbg("%s: kmalloc for quatech2_dev failed!",
+		    __func__);
+		return -ENOMEM;
+	}
+	qt2_dev->open_ports = 0;	/* no ports open */
+	qt2_set_dev_private(serial, qt2_dev);	/* store private data */
+
+	/* Now setup per port private data, which replaces all the things
+	 * that quatech added to standard kernel structures in their driver */
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		qt2_port = kzalloc(sizeof(*qt2_port), GFP_KERNEL);
+		if (!qt2_port) {
+			dbg("%s: kmalloc for quatech2_port (%d) failed!.",
+			    __func__, i);
+			return -ENOMEM;
+		}
+		/* initialise stuff in the structure */
+		qt2_port->open_count = 0;	/* port is not open */
+		spin_lock_init(&qt2_port->lock);
+		mutex_init(&qt2_port->modelock);
+		qt2_set_port_private(port, qt2_port);
+	}
+
+	/* gain access to port[0]'s structure because we want to store
+	 * device-level stuff in it */
+	if (serial_paranoia_check(serial, __func__))
+		return -ENODEV;
+	port0 = serial->port[0]; /* get the first port's device structure */
+
+	/* print endpoint addresses so we can check them later
+	 * by hand */
+	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 */
+			dbg("found bulk in at %#.2x",
+				endpoint->bEndpointAddress);
+		}
+
+		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+			((endpoint->bmAttributes & 3) == 0x02)) {
+			/* we found a bulk out endpoint */
+			dbg("found bulk out at %#.2x",
+				endpoint->bEndpointAddress);
+			qt2_dev->buffer_size = endpoint->wMaxPacketSize;
+			/* max size of URB needs recording for the device */
+		}
+	}	/* end printing endpoint addresses */
+
+	/* switch on power to the hardware */
+	if (qt2_boxpoweron(serial) < 0) {
+		dbg("qt2_boxpoweron() failed");
+		goto startup_error;
+	}
+	/* set all ports to RS232 mode */
+	for (i = 0; i < serial->num_ports; ++i) {
+		if (qt2_boxsetQMCR(serial, i, QU2BOX232) < 0) {
+			dbg("qt2_boxsetQMCR() on port %d failed",
+				i);
+			goto startup_error;
+		}
+	}
+
+	return 0;
+
+startup_error:
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		qt2_port = qt2_get_port_private(port);
+		kfree(qt2_port);
+		qt2_set_port_private(port, NULL);
+	}
+	qt2_dev = qt2_get_dev_private(serial);
+	kfree(qt2_dev);
+	qt2_set_dev_private(serial, NULL);
+
+	dbg("Exit fail %s\n", __func__);
+	return -EIO;
+}
+
+static void qt2_release(struct usb_serial *serial)
+{
+	struct usb_serial_port *port;
+	struct quatech2_port *qt_port;
+	int i;
+
+	dbg("enterting %s", __func__);
+
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		if (!port)
+			continue;
+
+		qt_port = usb_get_serial_port_data(port);
+		kfree(qt_port);
+		usb_set_serial_port_data(port, NULL);
+	}
+}
+/* This function is called once per serial port on the device, when
+ * that port is opened by a userspace application.
+ * The tty_struct and the usb_serial_port belong to this port,
+ * i.e. there are multiple ones for a multi-port device.
+ * However the usb_serial_port structure has a back-pointer
+ * to the parent usb_serial structure which belongs to the device,
+ * so we can access either the device-wide information or
+ * any other port's information (because there are also forward
+ * pointers) via that pointer.
+ * This is most helpful if the device shares resources (e.g. end
+ * points) between different ports
+ */
+int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
+{
+	struct usb_serial *serial;	/* device structure */
+	struct usb_serial_port *port0;	/* first port structure on device */
+	struct quatech2_port *port_extra;       /* extra data for this port */
+	struct quatech2_port *port0_extra;	/* extra data for first port */
+	struct quatech2_dev *dev_extra;		/* extra data for the device */
+	struct qt2_status_data ChannelData;
+	unsigned short default_divisor = QU2BOXSPD9600;
+	unsigned char  default_LCR = QT2_SERIAL_8_DATA;
+	int status;
+	int result;
+
+	if (port_paranoia_check(port, __func__))
+		return -ENODEV;
+
+	dbg("%s(): port %d", __func__, port->number);
+
+	serial = port->serial;	/* get the parent device structure */
+	if (serial_paranoia_check(serial, __func__)) {
+		dbg("usb_serial struct failed sanity check");
+		return -ENODEV;
+	}
+	dev_extra = qt2_get_dev_private(serial);
+	/* get the device private data */
+	if (dev_extra == NULL) {
+		dbg("device extra data pointer is null");
+		return -ENODEV;
+	}
+	port0 = serial->port[0]; /* get the first port's device structure */
+	if (port_paranoia_check(port0, __func__)) {
+		dbg("port0 usb_serial_port struct failed sanity check");
+		return -ENODEV;
+	}
+
+	port_extra = qt2_get_port_private(port);
+	port0_extra = qt2_get_port_private(port0);
+	if (port_extra == NULL || port0_extra == NULL) {
+		dbg("failed to get private data for port or port0");
+		return -ENODEV;
+	}
+
+	/* FIXME: are these needed?  Does it even do anything useful? */
+	/* get the modem and line status values from the UART */
+	status = qt2_openboxchannel(serial, port->number,
+			&ChannelData);
+	if (status < 0) {
+		dbg("qt2_openboxchannel on channel %d failed",
+		    port->number);
+		return status;
+	}
+	port_extra->shadowLSR = ChannelData.line_status &
+			(QT2_SERIAL_LSR_OE | QT2_SERIAL_LSR_PE |
+			QT2_SERIAL_LSR_FE | QT2_SERIAL_LSR_BI);
+	port_extra->shadowMSR = ChannelData.modem_status &
+			(QT2_SERIAL_MSR_CTS | QT2_SERIAL_MSR_DSR |
+			QT2_SERIAL_MSR_RI | QT2_SERIAL_MSR_CD);
+
+/*	port_extra->fifo_empty_flag = true;*/
+	dbg("qt2_openboxchannel on channel %d completed.",
+	    port->number);
+
+	/* Set Baud rate to default and turn off flow control here */
+	status = qt2_conf_uart(serial, port->number, default_divisor,
+				default_LCR);
+	if (status < 0) {
+		dbg("qt2_conf_uart() failed on channel %d",
+		    port->number);
+		return status;
+	}
+	dbg("qt2_conf_uart() completed on channel %d",
+		port->number);
+
+	/*
+	 * At this point we will need some end points to make further progress.
+	 * Handlily, the correct endpoint addresses have been filled out into
+	 * the usb_serial_port structure for us by the driver core, so we
+	 * already have access to them.
+	 * As there is only one bulk in and one bulk out end-point, these are in
+	 * port[0]'s structure, and the rest are uninitialised. Handily,
+	 * when we do a write to a port, we will use the same endpoint
+	 * regardless of the port, with a 5-byte header added on to
+	 * tell the box which port it should eventually come out of, so we only
+	 * need the one set of endpoints. We will have one URB per port for
+	 * writing, so that multiple ports can be writing at once.
+	 * Finally we need a bulk in URB to use for background reads from the
+	 * device, which will deal with uplink data from the box to host.
+	 */
+	dbg("port0 bulk in endpoint is %#.2x", port0->bulk_in_endpointAddress);
+	dbg("port0 bulk out endpoint is %#.2x",
+		port0->bulk_out_endpointAddress);
+
+	/* set up write_urb for bulk out transfers on this port. The USB
+	 * serial framework will have allocated a blank URB, buffer etc for
+	 * port0 when it put the endpoints there, but not for any of the other
+	 * ports on the device because there are no more endpoints. Thus we
+	 * have to allocate our own URBs for ports 1-7
+	 */
+	if (port->write_urb == NULL) {
+		dbg("port->write_urb == NULL, allocating one");
+		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!port->write_urb) {
+			err("Allocating write URB failed");
+			return -ENOMEM;
+		}
+		/* buffer same size as port0 */
+		port->bulk_out_size = dev_extra->buffer_size;
+		port->bulk_out_buffer = kmalloc(port->bulk_out_size,
+						GFP_KERNEL);
+		if (!port->bulk_out_buffer) {
+			err("Couldn't allocate bulk_out_buffer");
+			return -ENOMEM;
+		}
+	}
+	if (serial->dev == NULL)
+		dbg("serial->dev == NULL");
+	dbg("port->bulk_out_size is %d", port->bulk_out_size);
+
+	usb_fill_bulk_urb(port->write_urb, serial->dev,
+			usb_sndbulkpipe(serial->dev,
+			port0->bulk_out_endpointAddress),
+			port->bulk_out_buffer,
+			port->bulk_out_size,
+			qt2_write_bulk_callback,
+			port);
+	port_extra->tx_pending_bytes = 0;
+
+	if (dev_extra->open_ports == 0) {
+		/* this is first port to be opened, so need the read URB
+		 * initialised for bulk in transfers (this is shared amongst
+		 * all the ports on the device) */
+		usb_fill_bulk_urb(port0->read_urb, serial->dev,
+			usb_rcvbulkpipe(serial->dev,
+			port0->bulk_in_endpointAddress),
+			port0->bulk_in_buffer,
+			port0->bulk_in_size,
+			qt2_read_bulk_callback, serial);
+		dbg("port0 bulk in URB intialised");
+
+		/* submit URB, i.e. start reading from device (async) */
+		dev_extra->ReadBulkStopped = false;
+		port_extra->read_urb_busy = true;
+		result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+		if (result) {
+			dev_err(&port->dev,
+				 "%s(): Error %d submitting bulk in urb",
+				__func__, result);
+			port_extra->read_urb_busy = false;
+			dev_extra->ReadBulkStopped = true;
+		}
+
+		/* When the first port is opened, initialise the value of
+		 * current_port in dev_extra to this port, so it is set
+		 * to something. Once the box sends data it will send the
+		 * relevant escape sequences to get it to the right port anyway
+		 */
+		dev_extra->current_port = port;
+	}
+
+	/* initialize our wait queues */
+	init_waitqueue_head(&port_extra->wait);
+	/* increment the count of openings of this port by one */
+	port_extra->open_count++;
+
+	/* remember to store dev_extra, port_extra and port0_extra back again at
+	 * end !*/
+	qt2_set_port_private(port, port_extra);
+	qt2_set_port_private(serial->port[0], port0_extra);
+	qt2_set_dev_private(serial, dev_extra);
+
+	dev_extra->open_ports++; /* one more port opened */
+
+	return 0;
+}
+
+/* called when a port is closed by userspace. It won't be called, however,
+ * until calls to chars_in_buffer() reveal that the port has completed
+ * sending buffered data, and there is nothing else to do. Thus we don't have
+ * to rely on forcing data through in this function. */
+/* Setting close_pending should keep new data from being written out,
+ * once all the data in the enpoint buffers is moved out we won't get
+ * any more. */
+/* BoxStopReceive would keep any more data from coming from a given
+ * port, but isn't called by the vendor driver, although their comments
+ * mention it. Should it be used here to stop the inbound data
+ * flow?
+ */
+static void qt2_close(struct usb_serial_port *port)
+{
+	/* time out value for flush loops */
+	unsigned long jift;
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	struct usb_serial *serial;	/* device structure */
+	struct quatech2_dev *dev_extra; /* extra data for the device */
+	__u8  lsr_value = 0;	/* value of Line Status Register */
+	int status;	/* result of last USB comms function */
+
+	dbg("%s(): port %d", __func__, port->number);
+	serial = port->serial;	/* get the parent device structure */
+	dev_extra = qt2_get_dev_private(serial);
+	/* get the device private data */
+	port_extra = qt2_get_port_private(port); /* port private data */
+
+	/* we don't need to force flush though the hardware, so we skip using
+	 * qt2_box_flush() here */
+
+	/* we can now (and only now) stop reading data */
+	port_extra->close_pending = true;
+	dbg("%s(): port_extra->close_pending = true", __func__);
+	/* although the USB side is now empty, the UART itself may
+	 * still be pushing characters out over the line, so we have to
+	 * wait testing the actual line status until the lines change
+	 * indicating that the data is done transfering. */
+	/* FIXME: slow this polling down so it doesn't run the USB bus flat out
+	 * if it actually has to spend any time in this loop (which it normally
+	 * doesn't because the buffer is nearly empty) */
+	jift = jiffies + (10 * HZ);	/* 10 sec timeout */
+	do {
+		status = qt2_box_get_register(serial, port->number,
+			QT2_LINE_STATUS_REGISTER, &lsr_value);
+		if (status < 0) {
+			dbg("%s(): qt2_box_get_register failed", __func__);
+			break;
+		}
+		if ((lsr_value & QT2_LSR_TEMT)) {
+			dbg("UART done sending");
+			break;
+		}
+		schedule();
+	} while (jiffies <= jift);
+
+	status = qt2_closeboxchannel(serial, port->number);
+	if (status < 0)
+		dbg("%s(): port %d qt2_box_open_close_channel failed",
+			__func__, port->number);
+	/* to avoid leaking URBs, we should now free the write_urb for this
+	 * port and set the pointer to null so that next time the port is opened
+	 * a new URB is allocated. This avoids leaking URBs when the device is
+	 * removed */
+	usb_free_urb(port->write_urb);
+	kfree(port->bulk_out_buffer);
+	port->bulk_out_buffer = NULL;
+	port->bulk_out_size = 0;
+
+	/* decrement the count of openings of this port by one */
+	port_extra->open_count--;
+	/* one less overall open as well */
+	dev_extra->open_ports--;
+	dbg("%s(): Exit, dev_extra->open_ports  = %d", __func__,
+		dev_extra->open_ports);
+}
+
+/**
+ * qt2_write - write bytes from the tty layer out to the USB device.
+ * @buf: The data to be written, size at least count.
+ * @count: The number of bytes requested for transmission.
+ * @return The number of bytes actually accepted for transmission to the device.
+ */
+static int qt2_write(struct tty_struct *tty, struct usb_serial_port *port,
+		const unsigned char *buf, int count)
+{
+	struct usb_serial *serial;	/* parent device struct */
+	__u8 header_array[5];	/* header used to direct writes to the correct
+	port on the device */
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	int result;
+
+	serial = port->serial; /* get the parent device of the port */
+	port_extra = qt2_get_port_private(port); /* port extra info */
+	if (serial == NULL)
+		return -ENODEV;
+	dbg("%s(): port %d, requested to write %d bytes, %d already pending",
+		__func__, port->number, count, port_extra->tx_pending_bytes);
+
+	if (count <= 0)	{
+		dbg("%s(): write request of <= 0 bytes", __func__);
+		return 0;	/* no bytes written */
+	}
+
+	/* check if the write urb is already in use, i.e. data already being
+	 * sent to this port */
+	if ((port->write_urb->status == -EINPROGRESS)) {
+		/* Fifo hasn't been emptied since last write to this port */
+		dbg("%s(): already writing, port->write_urb->status == "
+			"-EINPROGRESS", __func__);
+		/* schedule_work(&port->work); commented in vendor driver */
+		return 0;
+	} else if (port_extra->tx_pending_bytes >= QT2_FIFO_DEPTH) {
+		/* buffer is full (==). > should not occur, but would indicate
+		 * that an overflow had occured */
+		dbg("%s(): port transmit buffer is full!", __func__);
+		/* schedule_work(&port->work); commented in vendor driver */
+		return 0;
+	}
+
+	/* We must fill the first 5 bytes of anything we sent with a transmit
+	 * header which directes the data to the correct port. The maximum
+	 * size we can send out in one URB is port->bulk_out_size, which caps
+	 * the number of bytes of real data we can send in each write. As the
+	 * semantics of write allow us to write less than we were give, we cap
+	 * the maximum we will ever write to the device as 5 bytes less than
+	 * one URB's worth, by reducing the value of the count argument
+	 * appropriately*/
+	if (count > port->bulk_out_size - QT2_TX_HEADER_LENGTH) {
+		count = port->bulk_out_size - QT2_TX_HEADER_LENGTH;
+		dbg("%s(): write request bigger than urb, only accepting "
+			"%d bytes", __func__, count);
+	}
+	/* we must also ensure that the FIFO at the other end can cope with the
+	 * URB we send it, otherwise it will have problems. As above, we can
+	 * restrict the write size by just shrinking count.*/
+	if (count > (QT2_FIFO_DEPTH - port_extra->tx_pending_bytes)) {
+		count = QT2_FIFO_DEPTH - port_extra->tx_pending_bytes;
+		dbg("%s(): not enough room in buffer, only accepting %d bytes",
+			__func__, count);
+	}
+	/* now build the header for transmission */
+	header_array[0] = 0x1b;
+	header_array[1] = 0x1b;
+	header_array[2] = (__u8)port->number;
+	header_array[3] = (__u8)count;
+	header_array[4] = (__u8)count >> 8;
+	/* copy header into URB */
+	memcpy(port->write_urb->transfer_buffer, header_array,
+		QT2_TX_HEADER_LENGTH);
+	/* and actual data to write */
+	memcpy(port->write_urb->transfer_buffer + 5, buf, count);
+
+	dbg("%s(): first data byte to send = %#.2x", __func__, *buf);
+
+	/* 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 + 5,
+			(qt2_write_bulk_callback), port);
+	/* send the data out the bulk port */
+	result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+	if (result) {
+		/* error couldn't submit urb */
+		result = 0;	/* return 0 as nothing got written */
+		dbg("%s(): failed submitting write urb, error %d",
+			__func__, result);
+	} else {
+		port_extra->tx_pending_bytes += count;
+		result = count;	/* return number of bytes written, i.e. count */
+		dbg("%s(): submitted write urb, wrote %d bytes, "
+			"total pending bytes %d",
+			__func__, result, port_extra->tx_pending_bytes);
+	}
+	return result;
+}
+
+/* This is used by the next layer up to know how much space is available
+ * in the buffer on the device. It is used on a device closure to avoid
+ * calling close() until the buffer is reported to be empty.
+ * The returned value must never go down by more than the number of bytes
+ * written for correct behaviour further up the driver stack, i.e. if I call
+ * it, then write 6 bytes, then call again I should get 6 less, or possibly
+ * only 5 less if one was written in the meantime, etc. I should never get 7
+ * less (or any bigger number) because I only wrote 6 bytes.
+ */
+static int qt2_write_room(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+		/* parent usb_serial_port pointer */
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	int room = 0;
+	port_extra = qt2_get_port_private(port);
+
+	if (port_extra->close_pending == true) {
+		dbg("%s(): port_extra->close_pending == true", __func__);
+		return -ENODEV;
+	}
+	/* Q: how many bytes would a write() call actually succeed in writing
+	 * if it happened now?
+	 * A: one QT2_FIFO_DEPTH, less the number of bytes waiting to be sent
+	 * out of the port, unless this is more than the size of the
+	 * write_urb output buffer less the header, which is the maximum
+	 * size write we can do.
+
+	 * Most of the implementation of this is done when writes to the device
+	 * are started or terminate. When we send a write to the device, we
+	 * reduce the free space count by the size of the dispatched write.
+	 * When a "transmit empty" message comes back up the USB read stream,
+	 * we decrement the count by the number of bytes reported sent, thus
+	 * keeping track of the difference between sent and recieved bytes.
+	 */
+
+	room = (QT2_FIFO_DEPTH - port_extra->tx_pending_bytes);
+	/* space in FIFO */
+	if (room > port->bulk_out_size - QT2_TX_HEADER_LENGTH)
+		room = port->bulk_out_size - QT2_TX_HEADER_LENGTH;
+	/* if more than the URB can hold, then cap to that limit */
+
+	dbg("%s(): port %d: write room is %d", __func__, port->number, room);
+	return room;
+}
+
+static int qt2_chars_in_buffer(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	/* parent usb_serial_port pointer */
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	port_extra = qt2_get_port_private(port);
+
+	dbg("%s(): port %d: chars_in_buffer = %d", __func__,
+		port->number, port_extra->tx_pending_bytes);
+	return port_extra->tx_pending_bytes;
+}
+
+/* called when userspace does an ioctl() on the device. Note that
+ * TIOCMGET and TIOCMSET are filtered off to their own methods before they get
+ * here, so we don't have to handle them.
+ */
+static int qt2_ioctl(struct tty_struct *tty, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
+	__u8 mcr_value;	/* Modem Control Register value */
+	__u8 msr_value; /* Modem Status Register value */
+	unsigned short prev_msr_value; /* Previous value of Modem Status
+	 * Register used to implement waiting for a line status change to
+	 * occur */
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	DECLARE_WAITQUEUE(wait, current);
+	/* Declare a wait queue named "wait" */
+
+	unsigned int value;
+	unsigned int UartNumber;
+
+	if (serial == NULL)
+		return -ENODEV;
+	UartNumber = tty->index - serial->minor;
+	port_extra = qt2_get_port_private(port);
+
+	dbg("%s(): port %d, UartNumber %d, tty =0x%p", __func__,
+	    port->number, UartNumber, tty);
+
+	if (cmd == TIOCMBIS || cmd == TIOCMBIC) {
+		if (qt2_box_get_register(port->serial, UartNumber,
+			QT2_MODEM_CONTROL_REGISTER, &mcr_value) < 0)
+			return -ESPIPE;
+		if (copy_from_user(&value, (unsigned int *)arg,
+			sizeof(value)))
+			return -EFAULT;
+
+		switch (cmd) {
+		case TIOCMBIS:
+			if (value & TIOCM_RTS)
+				mcr_value |= QT2_SERIAL_MCR_RTS;
+			if (value & TIOCM_DTR)
+				mcr_value |= QT2_SERIAL_MCR_DTR;
+			if (value & TIOCM_LOOP)
+				mcr_value |= QT2_SERIAL_MCR_LOOP;
+		break;
+		case TIOCMBIC:
+			if (value & TIOCM_RTS)
+				mcr_value &= ~QT2_SERIAL_MCR_RTS;
+			if (value & TIOCM_DTR)
+				mcr_value &= ~QT2_SERIAL_MCR_DTR;
+			if (value & TIOCM_LOOP)
+				mcr_value &= ~QT2_SERIAL_MCR_LOOP;
+		break;
+		default:
+		break;
+		}	/* end of local switch on cmd */
+		if (qt2_box_set_register(port->serial,  UartNumber,
+		    QT2_MODEM_CONTROL_REGISTER, mcr_value) < 0) {
+			return -ESPIPE;
+		} else {
+			port_extra->shadowMCR = mcr_value;
+			return 0;
+		}
+	} else if (cmd == TIOCMIWAIT) {
+		dbg("%s() port %d, cmd == TIOCMIWAIT enter",
+			__func__, port->number);
+		prev_msr_value = port_extra->shadowMSR  & QT2_SERIAL_MSR_MASK;
+		while (1) {
+			add_wait_queue(&port_extra->wait, &wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule();
+			dbg("%s(): port %d, cmd == TIOCMIWAIT here\n",
+				__func__, port->number);
+			remove_wait_queue(&port_extra->wait, &wait);
+			/* see if a signal woke us up */
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+			msr_value = port_extra->shadowMSR & QT2_SERIAL_MSR_MASK;
+			if (msr_value == prev_msr_value)
+				return -EIO;  /* no change - error */
+			if ((arg & TIOCM_RNG &&
+				((prev_msr_value & QT2_SERIAL_MSR_RI) ==
+					(msr_value & QT2_SERIAL_MSR_RI))) ||
+				(arg & TIOCM_DSR &&
+				((prev_msr_value & QT2_SERIAL_MSR_DSR) ==
+					(msr_value & QT2_SERIAL_MSR_DSR))) ||
+				(arg & TIOCM_CD &&
+				((prev_msr_value & QT2_SERIAL_MSR_CD) ==
+					(msr_value & QT2_SERIAL_MSR_CD))) ||
+				(arg & TIOCM_CTS &&
+				((prev_msr_value & QT2_SERIAL_MSR_CTS) ==
+					(msr_value & QT2_SERIAL_MSR_CTS)))) {
+				return 0;
+			}
+		} /* end inifinite while */
+		/* FIXME: This while loop needs a way to break out if the device
+		 * is disconnected while a process is waiting for the MSR to
+		 * change, because once it's disconnected, it isn't going to
+		 * change state ... */
+	} else {
+		/* any other ioctls we don't know about come here */
+		dbg("%s(): No ioctl for that one. port = %d", __func__,
+			port->number);
+		return -ENOIOCTLCMD;
+	}
+}
+
+/* Called when the user wishes to change the port settings using the termios
+ * userspace interface */
+static void qt2_set_termios(struct tty_struct *tty,
+	struct usb_serial_port *port, struct ktermios *old_termios)
+{
+	struct usb_serial *serial; /* parent serial device */
+	int baud, divisor, remainder;
+	unsigned char LCR_change_to = 0;
+	int status;
+	__u16 UartNumber;
+
+	dbg("%s(): port %d", __func__, port->number);
+
+	serial = port->serial;
+
+	UartNumber = port->number;
+
+	if (old_termios && !tty_termios_hw_change(old_termios, tty->termios))
+		return;
+
+	switch (tty->termios->c_cflag) {
+	case CS5:
+		LCR_change_to |= QT2_SERIAL_5_DATA;
+		break;
+	case CS6:
+		LCR_change_to |= QT2_SERIAL_6_DATA;
+		break;
+	case CS7:
+		LCR_change_to |= QT2_SERIAL_7_DATA;
+		break;
+	default:
+	case CS8:
+		LCR_change_to |= QT2_SERIAL_8_DATA;
+		break;
+	}
+
+	/* Parity stuff */
+	if (tty->termios->c_cflag & PARENB) {
+		if (tty->termios->c_cflag & PARODD)
+			LCR_change_to |= QT2_SERIAL_ODD_PARITY;
+		else
+			LCR_change_to |= QT2_SERIAL_EVEN_PARITY;
+	}
+	/* Because LCR_change_to is initialised to zero, we don't have to worry
+	 * about the case where PARENB is not set or clearing bits, because by
+	 * default all of them are cleared, turning parity off.
+	 * as we don't support mark/space parity, we should clear the
+	 * mark/space parity bit in c_cflag, so the caller can tell we have
+	 * ignored the request */
+	tty->termios->c_cflag &= ~CMSPAR;
+
+	if (tty->termios->c_cflag & CSTOPB)
+		LCR_change_to |= QT2_SERIAL_TWO_STOPB;
+	else
+		LCR_change_to |= QT2_SERIAL_ONE_STOPB;
+
+	/* Thats the LCR stuff, next we need to work out the divisor as the
+	 * LCR and the divisor are set together */
+	baud = tty_get_baud_rate(tty);
+	if (!baud) {
+		/* pick a default, any default... */
+		baud = 9600;
+	}
+	dbg("%s(): got baud = %d", __func__, baud);
+
+	divisor = QT2_MAX_BAUD_RATE / baud;
+	remainder = QT2_MAX_BAUD_RATE % baud;
+	/* Round to nearest divisor */
+	if (((remainder * 2) >= baud) && (baud != 110))
+		divisor++;
+	dbg("%s(): setting divisor = %d, QT2_MAX_BAUD_RATE = %d , LCR = %#.2x",
+	      __func__, divisor, QT2_MAX_BAUD_RATE, LCR_change_to);
+
+	status = qt2_boxsetuart(serial, UartNumber, (unsigned short) divisor,
+			    LCR_change_to);
+	if (status < 0)	{
+		dbg("qt2_boxsetuart() failed");
+		return;
+	} else {
+		/* now encode the baud rate we actually set, which may be
+		 * different to the request */
+		baud = QT2_MAX_BAUD_RATE / divisor;
+		tty_encode_baud_rate(tty, baud, baud);
+	}
+
+	/* Now determine flow control */
+	if (tty->termios->c_cflag & CRTSCTS) {
+		dbg("%s(): Enabling HW flow control port %d", __func__,
+		      port->number);
+		/* Enable  RTS/CTS flow control */
+		status = qt2_boxsethw_flowctl(serial, UartNumber, true);
+		if (status < 0) {
+			dbg("qt2_boxsethw_flowctl() failed");
+			return;
+		}
+	} else {
+		/* Disable RTS/CTS flow control */
+		dbg("%s(): disabling HW flow control port %d", __func__,
+			port->number);
+		status = qt2_boxsethw_flowctl(serial, UartNumber, false);
+		if (status < 0)	{
+			dbg("qt2_boxsethw_flowctl failed");
+			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 = qt2_boxsetsw_flowctl(serial, UartNumber, stop_char,
+				start_char);
+		if (status < 0)
+			dbg("qt2_boxsetsw_flowctl (enabled) failed");
+	} else {
+		/* disable SW flow control */
+		status = qt2_boxunsetsw_flowctl(serial, UartNumber);
+		if (status < 0)
+			dbg("qt2_boxunsetsw_flowctl (disabling) failed");
+	}
+}
+
+static int qt2_tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
+
+	__u8 mcr_value;	/* Modem Control Register value */
+	__u8 msr_value;	/* Modem Status Register value */
+	unsigned int result = 0;
+	int status;
+	unsigned int UartNumber;
+
+	if (serial == NULL)
+		return -ENODEV;
+
+	dbg("%s(): port %d, tty =0x%p", __func__, port->number, tty);
+	UartNumber = tty->index - serial->minor;
+	dbg("UartNumber is %d", UartNumber);
+
+	status = qt2_box_get_register(port->serial, UartNumber,
+			QT2_MODEM_CONTROL_REGISTER,	&mcr_value);
+	if (status >= 0) {
+		status = qt2_box_get_register(port->serial,  UartNumber,
+				QT2_MODEM_STATUS_REGISTER, &msr_value);
+	}
+	if (status >= 0) {
+		result = ((mcr_value & QT2_SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
+				/*DTR set */
+			| ((mcr_value & QT2_SERIAL_MCR_RTS)  ? TIOCM_RTS : 0)
+				/*RTS set */
+			| ((msr_value & QT2_SERIAL_MSR_CTS)  ? TIOCM_CTS : 0)
+				/* CTS set */
+			| ((msr_value & QT2_SERIAL_MSR_CD)  ? TIOCM_CAR : 0)
+				/*Carrier detect set */
+			| ((msr_value & QT2_SERIAL_MSR_RI)  ? TIOCM_RI : 0)
+				/* Ring indicator set */
+			| ((msr_value & QT2_SERIAL_MSR_DSR)  ? TIOCM_DSR : 0);
+				/* DSR set */
+		return result;
+	} else {
+		return -ESPIPE;
+	}
+}
+
+static int qt2_tiocmset(struct tty_struct *tty, struct file *file,
+		       unsigned int set, unsigned int clear)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
+	__u8 mcr_value;	/* Modem Control Register value */
+	int status;
+	unsigned int UartNumber;
+
+	if (serial == NULL)
+		return -ENODEV;
+
+	UartNumber = tty->index - serial->minor;
+	dbg("%s(): port %d, UartNumber %d", __func__, port->number, UartNumber);
+
+	status = qt2_box_get_register(port->serial, UartNumber,
+			QT2_MODEM_CONTROL_REGISTER, &mcr_value);
+	if (status < 0)
+		return -ESPIPE;
+
+	/* Turn off RTS, DTR and loopback, then only turn on what was asked
+	 * for */
+	mcr_value &= ~(QT2_SERIAL_MCR_RTS | QT2_SERIAL_MCR_DTR |
+			QT2_SERIAL_MCR_LOOP);
+	if (set & TIOCM_RTS)
+		mcr_value |= QT2_SERIAL_MCR_RTS;
+	if (set & TIOCM_DTR)
+		mcr_value |= QT2_SERIAL_MCR_DTR;
+	if (set & TIOCM_LOOP)
+		mcr_value |= QT2_SERIAL_MCR_LOOP;
+
+	status = qt2_box_set_register(port->serial, UartNumber,
+			QT2_MODEM_CONTROL_REGISTER, mcr_value);
+	if (status < 0)
+		return -ESPIPE;
+	else
+		return 0;
+}
+
+/** qt2_break - Turn BREAK on and off on the UARTs
+ */
+static void qt2_break(struct tty_struct *tty, int break_state)
+{
+	struct usb_serial_port *port = tty->driver_data; /* parent port */
+	struct usb_serial *serial = port->serial;	/* parent device */
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	__u16 break_value;
+	unsigned int result;
+
+	port_extra = qt2_get_port_private(port);
+	if (!serial) {
+		dbg("%s(): port %d: no serial object", __func__, port->number);
+		return;
+	}
+
+	if (break_state == -1)
+		break_value = 1;
+	else
+		break_value = 0;
+	dbg("%s(): port %d, break_value %d", __func__, port->number,
+		break_value);
+
+	mutex_lock(&port_extra->modelock);
+	if (!port_extra->open_count) {
+		dbg("%s(): port not open", __func__);
+		goto exit;
+	}
+
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				QT2_BREAK_CONTROL, 0x40, break_value,
+				port->number, NULL, 0, 300);
+exit:
+	mutex_unlock(&port_extra->modelock);
+	dbg("%s(): exit port %d", __func__, port->number);
+
+}
+/**
+ * qt2_throttle: - stop reading new data from the port
+ */
+static void qt2_throttle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	dbg("%s(): port %d", __func__, port->number);
+
+	port_extra = qt2_get_port_private(port);
+	if (!serial) {
+		dbg("%s(): enter port %d no serial object", __func__,
+		      port->number);
+		return;
+	}
+
+	mutex_lock(&port_extra->modelock);	/* lock structure */
+	if (!port_extra->open_count) {
+		dbg("%s(): port not open", __func__);
+		goto exit;
+	}
+	/* Send command to box to stop receiving stuff. This will stop this
+	 * particular UART from filling the endpoint - in the multiport case the
+	 * FPGA UART will handle any flow control implmented, but for the single
+	 * port it's handed differently and we just quit submitting urbs
+	 */
+	if (serial->dev->descriptor.idProduct != QUATECH_SSU2_100)
+		qt2_boxstoprx(serial, port->number, 1);
+
+	port->throttled = 1;
+exit:
+	mutex_unlock(&port_extra->modelock);
+	dbg("%s(): port %d: setting port->throttled", __func__, port->number);
+	return;
+}
+
+/**
+ * qt2_unthrottle: - start receiving data through the port again after being
+ * throttled
+ */
+static void qt2_unthrottle(struct tty_struct *tty)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
+	struct quatech2_port *port_extra;	/* extra data for this port */
+	struct usb_serial_port *port0;	/* first port structure on device */
+	struct quatech2_dev *dev_extra;		/* extra data for the device */
+
+	if (!serial) {
+		dbg("%s() enter port %d no serial object!", __func__,
+			port->number);
+		return;
+	}
+	dbg("%s(): enter port %d", __func__, port->number);
+	dev_extra = qt2_get_dev_private(serial);
+	port_extra = qt2_get_port_private(port);
+	port0 = serial->port[0]; /* get the first port's device structure */
+
+	mutex_lock(&port_extra->modelock);
+	if (!port_extra->open_count) {
+		dbg("%s(): port %d not open", __func__, port->number);
+		goto exit;
+	}
+
+	if (port->throttled != 0) {
+		dbg("%s(): port %d: unsetting port->throttled", __func__,
+		    port->number);
+		port->throttled = 0;
+		/* Send command to box to start receiving stuff */
+		if (serial->dev->descriptor.idProduct != QUATECH_SSU2_100) {
+			qt2_boxstoprx(serial,  port->number, 0);
+		} else if (dev_extra->ReadBulkStopped == true) {
+			usb_fill_bulk_urb(port0->read_urb, serial->dev,
+				usb_rcvbulkpipe(serial->dev,
+				port0->bulk_in_endpointAddress),
+				port0->bulk_in_buffer,
+				port0->bulk_in_size,
+				qt2_read_bulk_callback,
+				serial);
+		}
+	}
+exit:
+	mutex_unlock(&port_extra->modelock);
+	dbg("%s(): exit port %d", __func__, port->number);
+	return;
+}
+
+/* internal, private helper functions for the driver */
+
+/* Power up the FPGA in the box to get it working */
+static int qt2_boxpoweron(struct usb_serial *serial)
+{
+	int result;
+	__u8  Direcion;
+	unsigned int pipe;
+	Direcion = USBD_TRANSFER_DIRECTION_OUT;
+	pipe = usb_rcvctrlpipe(serial->dev, 0);
+	result = usb_control_msg(serial->dev, pipe, QT_SET_GET_DEVICE,
+				Direcion, QU2BOXPWRON, 0x00, NULL, 0x00,
+				5000);
+	return result;
+}
+
+/*
+ * qt2_boxsetQMCR Issue a QT2_GET_SET_QMCR vendor-spcific request on the
+ * default control pipe. If successful return the number of bytes written,
+ * otherwise return a negative error number of the problem.
+ */
+static int qt2_boxsetQMCR(struct usb_serial *serial, __u16 Uart_Number,
+			  __u8 QMCR_Value)
+{
+	int result;
+	__u16 PortSettings;
+
+	PortSettings = (__u16)(QMCR_Value);
+
+	dbg("%s(): Port = %d, PortSettings = 0x%x", __func__,
+			Uart_Number, PortSettings);
+
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				QT2_GET_SET_QMCR, 0x40, PortSettings,
+				(__u16)Uart_Number, NULL, 0, 5000);
+	return result;
+}
+
+static 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;
+	}
+	return 0;
+}
+
+static int serial_paranoia_check(struct usb_serial *serial,
+				 const char *function)
+{
+	if (!serial) {
+		dbg("%s - serial == NULL\n", function);
+		return -1;
+	}
+
+	if (!serial->type) {
+		dbg("%s - serial->type == NULL!", function);
+		return -1;
+	}
+
+	return 0;
+}
+
+static inline struct quatech2_port *qt2_get_port_private(struct usb_serial_port
+		*port)
+{
+	return (struct quatech2_port *)usb_get_serial_port_data(port);
+}
+
+static inline void qt2_set_port_private(struct usb_serial_port *port,
+		struct quatech2_port *data)
+{
+	usb_set_serial_port_data(port, (void *)data);
+}
+
+static inline struct quatech2_dev *qt2_get_dev_private(struct usb_serial
+		*serial)
+{
+	return (struct quatech2_dev *)usb_get_serial_data(serial);
+}
+static inline void qt2_set_dev_private(struct usb_serial *serial,
+		struct quatech2_dev *data)
+{
+	usb_set_serial_data(serial, (void *)data);
+}
+
+static int qt2_openboxchannel(struct usb_serial *serial, __u16
+		Uart_Number, struct qt2_status_data *status)
+{
+	int result;
+	__u16 length;
+	__u8  Direcion;
+	unsigned int pipe;
+	length = sizeof(struct qt2_status_data);
+	Direcion = USBD_TRANSFER_DIRECTION_IN;
+	pipe = usb_rcvctrlpipe(serial->dev, 0);
+	result = usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+			Direcion, 0x00, Uart_Number, status, length, 5000);
+	return result;
+}
+static int qt2_closeboxchannel(struct usb_serial *serial, __u16 Uart_Number)
+{
+	int result;
+	__u8  direcion;
+	unsigned int pipe;
+	direcion = USBD_TRANSFER_DIRECTION_OUT;
+	pipe = usb_sndctrlpipe(serial->dev, 0);
+	result = usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+		  direcion, 0, Uart_Number, NULL, 0, 5000);
+	return result;
+}
+
+/* qt2_conf_uart Issue a SET_UART vendor-spcific request on the default
+ * control pipe. If successful sets baud rate divisor and LCR value
+ */
+static int qt2_conf_uart(struct usb_serial *serial,  unsigned short Uart_Number,
+		      unsigned short divisor, unsigned char LCR)
+{
+	int result;
+	unsigned short UartNumandLCR;
+
+	UartNumandLCR = (LCR << 8) + Uart_Number;
+
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+				QT2_GET_SET_UART, 0x40, divisor, UartNumandLCR,
+				NULL, 0, 300);
+	return result;
+}
+
+/** @brief Callback for asynchronous submission of read URBs on bulk in
+ * endpoints
+ *
+ * Registered in qt2_open_port(), used to deal with incomming data
+ * from the box.
+ */
+static void qt2_read_bulk_callback(struct urb *urb)
+{
+	/* Get the device pointer (struct usb_serial) back out of the URB */
+	struct usb_serial *serial = urb->context;
+	/* get the extra struct for the device */
+	struct quatech2_dev *dev_extra = qt2_get_dev_private(serial);
+	/* Get first port structure from the device */
+	struct usb_serial_port *port0 = serial->port[0];
+	/* Get the currently active port structure from serial struct */
+	struct usb_serial_port *active = dev_extra->current_port;
+	/* get the extra struct for port 0 */
+	struct quatech2_port *port0_extra = qt2_get_port_private(port0);
+	/* and for the currently active port */
+	struct quatech2_port *active_extra = qt2_get_port_private(active);
+	/* When we finally get to doing some tty stuff, we will need this */
+	struct tty_struct *tty_st;
+	unsigned int RxCount;	/* the length of the data to process */
+	unsigned int i;	/* loop counter over the data to process */
+	int result;	/* return value cache variable */
+	bool escapeflag;	/* flag set to true if this loop iteration is
+				 * parsing an escape sequence, rather than
+				 * ordinary data */
+	dbg("%s(): callback running, active port is %d", __func__,
+		active->number);
+
+	if (urb->status) {
+		/* read didn't go well */
+		dev_extra->ReadBulkStopped = true;
+		dbg("%s(): nonzero bulk read status received: %d",
+			__func__, urb->status);
+		return;
+	}
+
+	/* inline port_sofrint() here */
+	if (port_paranoia_check(port0, __func__) != 0) {
+		dbg("%s - port_paranoia_check on port0 failed, exiting\n",
+__func__);
+		return;
+	}
+	if (port_paranoia_check(active, __func__) != 0) {
+		dbg("%s - port_paranoia_check on current_port "
+			"failed, exiting", __func__);
+		return;
+	}
+
+/* This single callback function has to do for all the ports on
+ * the device. Data being read up the USB can contain certain
+ * escape sequences which are used to communicate out-of-band
+ * information from the serial port in-band over the USB.
+ * These escapes include sending modem and flow control line
+ * status, and switching the port. The concept of a "Current Port"
+ * is used, which is where data is going until a port change
+ * escape seqence is received. This Current Port is kept between
+ * callbacks so that when this function enters we know which the
+ * currently active port is and can get to work right away without
+ * the box having to send repeat escape sequences (anyway, how
+ * would it know to do so?).
+ */
+
+	if (active_extra->close_pending == true) {
+		/* We are closing , stop reading */
+		dbg("%s - (active->close_pending == true", __func__);
+		if (dev_extra->open_ports <= 0) {
+			/* If this is the only port left open - stop the
+			 * bulk read */
+			dev_extra->ReadBulkStopped = true;
+			dbg("%s - (ReadBulkStopped == true;", __func__);
+			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 ((port0_extra->RxHolding == true) &&
+		    (serial->dev->descriptor.idProduct == QUATECH_SSU2_100)) {
+		/* single port device, input is already stopped, so we don't
+		 * need any more input data */
+		dev_extra->ReadBulkStopped = true;
+		return;
+	}
+	/* finally, we are in a situation where we might consider the data
+	 * that is contained within the URB, and what to do about it.
+	 * This is likely to involved communicating up to the TTY layer, so
+	 * we will need to get hold of the tty for the port we are currently
+	 * dealing with */
+
+	/* active is a usb_serial_port. It has a member port which is a
+	 * tty_port. From this we get a tty_struct pointer which is what we
+	 * actually wanted, and keep it on tty_st */
+	tty_st = tty_port_tty_get(&active->port);
+	if (!tty_st) {
+		dbg("%s - bad tty pointer - exiting", __func__);
+		return;
+	}
+	RxCount = urb->actual_length;	/* grab length of data handy */
+
+	if (RxCount) {
+		/* skip all this if no data to process */
+		for (i = 0; i < RxCount ; ++i) {
+			/* Look ahead code here -works on several bytes at onc*/
+			if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b)
+				&& (NEXTCHAR == 0x1b)) {
+				/* we are in an escape sequence, type
+				 * determined by the 3rd char */
+				escapeflag = false;
+				switch (THIRDCHAR) {
+				case 0x00:
+					/* Line status change 4th byte must
+					 * follow */
+					if (i > (RxCount - 4)) {
+						dbg("Illegal escape sequences "
+						"in received data");
+						break;
+					}
+					qt2_process_line_status(active,
+						FOURTHCHAR);
+					i += 3;
+					escapeflag = true;
+					break;
+				case 0x01:
+					/* Modem status status change 4th byte
+					 * must follow */
+					if (i > (RxCount - 4)) {
+						dbg("Illegal escape sequences "
+						"in received data");
+						break;
+					}
+					qt2_process_modem_status(active,
+						FOURTHCHAR);
+					i += 3;
+					escapeflag = true;
+					break;
+				case 0x02:
+					/* xmit hold empty 4th byte
+					 * must follow */
+					if (i > (RxCount - 4)) {
+						dbg("Illegal escape sequences "
+						"in received data");
+						break;
+					}
+					qt2_process_xmit_empty(active,
+						FOURTHCHAR, FIFTHCHAR);
+					i += 4;
+					escapeflag = true;
+					break;
+				case 0x03:
+					/* Port number change 4th byte
+					 * must follow */
+					if (i > (RxCount - 4)) {
+						dbg("Illegal escape sequences "
+						"in received data");
+						break;
+					}
+					/* Port change. If port open push
+					 * current data up to tty layer */
+					if (active_extra->open_count > 0)
+						tty_flip_buffer_push(tty_st);
+
+					dbg("Port Change: new port = %d",
+						FOURTHCHAR);
+					qt2_process_port_change(active,
+						FOURTHCHAR);
+					i += 3;
+					escapeflag = true;
+					/* having changed port, the pointers for
+					 * the currently active port are all out
+					 * of date and need updating */
+					active = dev_extra->current_port;
+					active_extra =
+						qt2_get_port_private(active);
+					tty_st = tty_port_tty_get(
+						&active->port);
+					break;
+				case 0x04:
+					/* Recv flush 3rd byte must
+					 * follow */
+					if (i > (RxCount - 3)) {
+						dbg("Illegal escape sequences "
+							"in received data");
+						break;
+					}
+					qt2_process_rcv_flush(active);
+					i += 2;
+					escapeflag = true;
+					break;
+				case 0x05:
+					/* xmit flush 3rd byte must follow */
+					if (i > (RxCount - 3)) {
+						dbg("Illegal escape sequences "
+						"in received data");
+						break;
+					}
+					qt2_process_xmit_flush(active);
+					i += 2;
+					escapeflag = true;
+					break;
+				case 0xff:
+					dbg("No status sequence");
+					qt2_process_rx_char(active, THISCHAR);
+					qt2_process_rx_char(active, NEXTCHAR);
+					i += 2;
+					break;
+				default:
+					qt2_process_rx_char(active, THISCHAR);
+					i += 1;
+					break;
+				} /*end switch*/
+				if (escapeflag == true)
+					continue;
+				/* if we did an escape char, we don't need
+				 * to mess around pushing data through the
+				 * tty layer, and can go round again */
+			} /*endif*/
+			if (tty_st && urb->actual_length) {
+				tty_buffer_request_room(tty_st, 1);
+				tty_insert_flip_string(tty_st,
+					&((unsigned char *)(urb->transfer_buffer)
+						)[i],
+					1);
+			}
+		} /*endfor*/
+		tty_flip_buffer_push(tty_st);
+	} /*endif*/
+
+	/* at this point we have complete dealing with the data for this
+	 * callback. All we have to do now is to start the async read process
+	 * back off again. */
+
+	usb_fill_bulk_urb(port0->read_urb, serial->dev,
+		usb_rcvbulkpipe(serial->dev, port0->bulk_in_endpointAddress),
+		port0->bulk_in_buffer, port0->bulk_in_size,
+		qt2_read_bulk_callback, serial);
+	result = usb_submit_urb(port0->read_urb, GFP_ATOMIC);
+	if (result) {
+		dbg("%s(): failed resubmitting read urb, error %d",
+			__func__, result);
+	} else {
+		dbg("%s() sucessfully resumitted read urb", __func__);
+		if (tty_st && RxCount) {
+			/* if some inbound data was processed, then
+			 * we need to push that through the tty layer
+			 */
+			tty_flip_buffer_push(tty_st);
+			tty_schedule_flip(tty_st);
+		}
+	}
+
+	/* cribbed from serqt_usb2 driver, but not sure which work needs
+	 * scheduling - port0 or currently active port? */
+	/* schedule_work(&port->work); */
+	dbg("%s() completed", __func__);
+	return;
+}
+
+/** @brief Callback for asynchronous submission of write URBs on bulk in
+ * endpoints
+ *
+ * Registered in qt2_write(), used to deal with outgoing data
+ * to the box.
+ */
+static void qt2_write_bulk_callback(struct urb *urb)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+	struct usb_serial *serial = port->serial;
+	dbg("%s(): port %d", __func__, port->number);
+	if (!serial) {
+		dbg("%s(): bad serial pointer, exiting", __func__);
+		return;
+	}
+	if (urb->status) {
+		dbg("%s(): nonzero write bulk status received: %d",
+			__func__, urb->status);
+		return;
+	}
+	/* FIXME What is supposed to be going on here?
+	 * does this actually do anything useful, and should it?
+	 */
+	/*port_softint((void *) serial); commented in vendor driver */
+	schedule_work(&port->work);
+	dbg("%s(): port %d exit", __func__, port->number);
+	return;
+}
+
+static void qt2_process_line_status(struct usb_serial_port *port,
+	unsigned char LineStatus)
+{
+	/* obtain the private structure for the port */
+	struct quatech2_port *port_extra = qt2_get_port_private(port);
+	port_extra->shadowLSR = LineStatus & (QT2_SERIAL_LSR_OE |
+		QT2_SERIAL_LSR_PE | QT2_SERIAL_LSR_FE | QT2_SERIAL_LSR_BI);
+}
+static void qt2_process_modem_status(struct usb_serial_port *port,
+	unsigned char ModemStatus)
+{
+	/* obtain the private structure for the port */
+	struct quatech2_port *port_extra = qt2_get_port_private(port);
+	port_extra->shadowMSR = ModemStatus;
+	wake_up_interruptible(&port_extra->wait);
+	/* this wakes up the otherwise indefinitely waiting code for
+	 * the TIOCMIWAIT ioctl, so that it can notice that
+	 * port_extra->shadowMSR has changed and the ioctl needs to return.
+	 */
+}
+
+static void qt2_process_xmit_empty(struct usb_serial_port *port,
+	unsigned char fourth_char, unsigned char fifth_char)
+{
+	int byte_count;
+	/* obtain the private structure for the port */
+	struct quatech2_port *port_extra = qt2_get_port_private(port);
+
+	byte_count = (int)(fifth_char * 16);
+	byte_count +=  (int)fourth_char;
+	/* byte_count indicates how many bytes the device has written out. This
+	 * message appears to occur regularly, and is used in the vendor driver
+	 * to keep track of the fill state of the port transmit buffer */
+	port_extra->tx_pending_bytes -= byte_count;
+	/* reduce the stored data queue length by the known number of bytes
+	 * sent */
+	dbg("port %d: %d bytes reported sent, %d still pending", port->number,
+			byte_count, port_extra->tx_pending_bytes);
+
+	/*port_extra->xmit_fifo_room_bytes = FIFO_DEPTH; ???*/
+}
+
+static void qt2_process_port_change(struct usb_serial_port *port,
+	unsigned char New_Current_Port)
+{
+	/* obtain the parent usb serial device structure */
+	struct usb_serial *serial = port->serial;
+	/* obtain the private structure for the device */
+	struct quatech2_dev *dev_extra = qt2_get_dev_private(serial);
+	dev_extra->current_port = serial->port[New_Current_Port];
+	/* what should I do with this? commented out in upstream
+	 * driver */
+	/*schedule_work(&port->work);*/
+}
+
+static void qt2_process_rcv_flush(struct usb_serial_port *port)
+{
+	/* obtain the private structure for the port */
+	struct quatech2_port *port_extra = qt2_get_port_private(port);
+	port_extra->rcv_flush = true;
+}
+static void qt2_process_xmit_flush(struct usb_serial_port *port)
+{
+	/* obtain the private structure for the port */
+	struct quatech2_port *port_extra = qt2_get_port_private(port);
+	port_extra->xmit_flush = true;
+}
+
+static void qt2_process_rx_char(struct usb_serial_port *port,
+	unsigned char data)
+{
+	/* get the tty_struct for this port */
+	struct tty_struct *tty = tty_port_tty_get(&(port->port));
+	/* get the URB with the data in to push */
+	struct urb *urb = port->serial->port[0]->read_urb;
+
+	if (tty && urb->actual_length) {
+		tty_buffer_request_room(tty, 1);
+		tty_insert_flip_string(tty, &data, 1);
+		/* should this be commented out here? */
+		/*tty_flip_buffer_push(tty);*/
+	}
+}
+
+/** @brief Retreive the value of a register from the device
+ *
+ * Issues a GET_REGISTER vendor-spcific request over the USB control
+ * pipe to obtain a value back from a specific register on a specific
+ * UART
+ * @param serial Serial device handle to access the device through
+ * @param uart_number Which UART the value is wanted from
+ * @param register_num Which register to read the value from
+ * @param pValue Pointer to somewhere to put the retrieved value
+ */
+static int qt2_box_get_register(struct usb_serial *serial,
+		unsigned char uart_number, unsigned short register_num,
+		__u8 *pValue)
+{
+	int result;
+	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+			QT2_GET_SET_REGISTER, 0xC0, register_num,
+			uart_number, (void *)pValue, sizeof(*pValue), 300);
+	return result;
+}
+
+/** qt2_box_set_register
+ * Issue a SET_REGISTER vendor-specific request on the default control pipe
+ */
+static int qt2_box_set_register(struct usb_serial *serial,
+		unsigned short Uart_Number, unsigned short Register_Num,
+		unsigned short Value)
+{
+	int result;
+	unsigned short reg_and_byte;
+
+	reg_and_byte = Value;
+	reg_and_byte = reg_and_byte << 8;
+	reg_and_byte = reg_and_byte + Register_Num;
+
+	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			QT2_GET_SET_REGISTER, 0x40, reg_and_byte,
+			Uart_Number, NULL, 0, 300);
+	return result;
+}
+
+
+/** @brief Request the Tx or Rx buffers on the USB side be flushed
+ *
+ * Tx flush: When all the currently buffered data has been sent, send an escape
+ * sequence back up the data stream to us
+ * Rx flush: add a flag in the data stream now so we know when it's made it's
+ * way up to us.
+ */
+static int qt2_box_flush(struct usb_serial *serial,  unsigned char uart_number,
+		    unsigned short rcv_or_xmit)
+{
+	int result;
+	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+		QT2_FLUSH_DEVICE, 0x40, rcv_or_xmit, uart_number, NULL, 0,
+		300);
+	return result;
+}
+
+/** qt2_boxsetuart - Issue a SET_UART vendor-spcific request on the default
+ * control pipe. If successful sets baud rate divisor and LCR value.
+ */
+static int qt2_boxsetuart(struct usb_serial *serial, unsigned short Uart_Number,
+		unsigned short default_divisor, unsigned char default_LCR)
+{
+	unsigned short UartNumandLCR;
+
+	UartNumandLCR = (default_LCR << 8) + Uart_Number;
+
+	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			QT2_GET_SET_UART, 0x40, default_divisor, UartNumandLCR,
+			NULL, 0, 300);
+}
+/** qt2_boxsethw_flowctl - Turn hardware (RTS/CTS) flow control on and off for
+ * a hardware UART.
+ */
+static int qt2_boxsethw_flowctl(struct usb_serial *serial,
+		unsigned int UartNumber, bool bSet)
+{
+	__u8 MCR_Value = 0;
+	__u8 MSR_Value = 0;
+	__u16 MOUT_Value = 0;
+
+	if (bSet == true) {
+		MCR_Value =  QT2_SERIAL_MCR_RTS;
+		/* flow control, box will clear RTS line to prevent remote
+		 * device from transmitting more chars */
+	} else {
+		/* no flow control to remote device */
+		MCR_Value =  0;
+	}
+	MOUT_Value = MCR_Value << 8;
+
+	if (bSet == true) {
+		MSR_Value = QT2_SERIAL_MSR_CTS;
+		/* flow control on, box will inhibit tx data if CTS line is
+		 * asserted */
+	} else {
+		/* Box will not inhibit tx data due to CTS line */
+		MSR_Value = 0;
+	}
+	MOUT_Value |= MSR_Value;
+	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			QT2_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value, UartNumber,
+			NULL, 0, 300);
+}
+
+/** qt2_boxsetsw_flowctl - Turn software (XON/XOFF) flow control on for
+ * a hardware UART, and set the XON and XOFF characters.
+ */
+static int qt2_boxsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber,
+			unsigned char stop_char,  unsigned char start_char)
+{
+	__u16 nSWflowout;
+
+	nSWflowout = start_char << 8;
+	nSWflowout = (unsigned short)stop_char;
+	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			QT2_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout, UartNumber,
+			NULL, 0, 300);
+}
+
+/** qt2_boxunsetsw_flowctl - Turn software (XON/XOFF) flow control off for
+ * a hardware UART.
+ */
+static int qt2_boxunsetsw_flowctl(struct usb_serial *serial, __u16 UartNumber)
+{
+	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+			QT2_SW_FLOW_CONTROL_DISABLE, 0x40, 0, UartNumber, NULL,
+			0, 300);
+}
+
+/**
+ * qt2_boxstoprx - Start and stop reception of data by the FPGA UART in
+ * response to requests from the tty layer
+ * @serial: pointer to the usb_serial structure for the parent device
+ * @uart_number: which UART on the device we are addressing
+ * @stop: Whether to start or stop data reception. Set to 1 to stop data being
+ * received, and to 0 to start it being received.
+ */
+static int qt2_boxstoprx(struct usb_serial *serial, unsigned short uart_number,
+		unsigned short stop)
+{
+	return usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+		QT2_STOP_RECEIVE, 0x40, stop, uart_number, NULL, 0, 300);
+}
+
+
+/*
+ * last things in file: stuff to register this driver into the generic
+ * USB serial framework.
+ */
+
+static struct usb_serial_driver quatech2_device = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "quatech_usb2",
+	},
+	.description = DRIVER_DESC,
+	.usb_driver = &quausb2_usb_driver,
+	.id_table = quausb2_id_table,
+	.num_ports = 8,
+	.open = qt2_open,
+	.close = qt2_close,
+	.write = qt2_write,
+	.write_room = qt2_write_room,
+	.chars_in_buffer = qt2_chars_in_buffer,
+	.throttle = qt2_throttle,
+	.unthrottle = qt2_unthrottle,
+	.calc_num_ports = qt2_calc_num_ports,
+	.ioctl = qt2_ioctl,
+	.set_termios = qt2_set_termios,
+	.break_ctl = qt2_break,
+	.tiocmget = qt2_tiocmget,
+	.tiocmset = qt2_tiocmset,
+	.attach = qt2_attach,
+	.release = qt2_release,
+	.read_bulk_callback = qt2_read_bulk_callback,
+	.write_bulk_callback = qt2_write_bulk_callback,
+};
+
+static int __init quausb2_usb_init(void)
+{
+	int retval;
+
+	dbg("%s\n", __func__);
+
+	/* register with usb-serial */
+	retval = usb_serial_register(&quatech2_device);
+
+	if (retval)
+		goto failed_usb_serial_register;
+
+	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+			DRIVER_DESC "\n");
+
+	/* register with usb */
+
+	retval = usb_register(&quausb2_usb_driver);
+	if (retval == 0)
+		return 0;
+
+	/* if we're here, usb_register() failed */
+	usb_serial_deregister(&quatech2_device);
+failed_usb_serial_register:
+		return retval;
+}
+
+static void __exit quausb2_usb_exit(void)
+{
+	usb_deregister(&quausb2_usb_driver);
+	usb_serial_deregister(&quatech2_device);
+}
+
+module_init(quausb2_usb_init);
+module_exit(quausb2_usb_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/staging/rar/Kconfig b/drivers/staging/rar/Kconfig
new file mode 100644
index 0000000..17f8bf3
--- /dev/null
+++ b/drivers/staging/rar/Kconfig
@@ -0,0 +1,17 @@
+#
+# RAR device configuration
+#
+
+menu "RAR Register Driver"
+#
+#	Restricted Access Register Manager
+#
+config RAR_REGISTER
+	tristate "Restricted Access Region Register Driver"
+	default n
+	---help---
+		This driver allows other kernel drivers access to the
+		contents of the restricted access region control
+		registers.
+
+endmenu
diff --git a/drivers/staging/rar/Makefile b/drivers/staging/rar/Makefile
new file mode 100644
index 0000000..5422ed0
--- /dev/null
+++ b/drivers/staging/rar/Makefile
@@ -0,0 +1,2 @@
+EXTRA_CFLAGS += -DLITTLE__ENDIAN
+obj-$(CONFIG_RAR_REGISTER) += rar_driver.o
diff --git a/drivers/staging/rar/rar_driver.c b/drivers/staging/rar/rar_driver.c
new file mode 100644
index 0000000..9805d74
--- /dev/null
+++ b/drivers/staging/rar/rar_driver.c
@@ -0,0 +1,444 @@
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/kdev_t.h>
+#include <linux/semaphore.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/ioctl.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/pci.h>
+#include <linux/firmware.h>
+#include <linux/sched.h>
+#include "rar_driver.h"
+
+/* The following defines are for the IPC process to retrieve RAR in */
+
+/* === Lincroft Message Bus Interface === */
+/* Message Control Register */
+#define LNC_MCR_OFFSET 0xD0
+
+/* Message Data Register */
+#define LNC_MDR_OFFSET 0xD4
+
+/* Message Opcodes */
+#define LNC_MESSAGE_READ_OPCODE  0xD0
+#define LNC_MESSAGE_WRITE_OPCODE 0xE0
+
+/* Message Write Byte Enables */
+#define LNC_MESSAGE_BYTE_WRITE_ENABLES 0xF
+
+/* B-unit Port */
+#define LNC_BUNIT_PORT 0x3
+
+/* === Lincroft B-Unit Registers - Programmed by IA32 firmware === */
+#define LNC_BRAR0L  0x10
+#define LNC_BRAR0H  0x11
+#define LNC_BRAR1L  0x12
+#define LNC_BRAR1H  0x13
+
+/* Reserved for SeP */
+#define LNC_BRAR2L  0x14
+#define LNC_BRAR2H  0x15
+
+
+/* This structure is only used during module initialization. */
+struct RAR_offsets {
+	int low; /* Register offset for low RAR physical address. */
+	int high; /* Register offset for high RAR physical address. */
+};
+
+struct pci_dev *rar_dev;
+static uint32_t registered;
+
+/* Moorestown supports three restricted access regions. */
+#define MRST_NUM_RAR 3
+
+struct RAR_address_struct rar_addr[MRST_NUM_RAR];
+
+/* prototype for init */
+static int __init rar_init_handler(void);
+static void __exit rar_exit_handler(void);
+
+/*
+  function that is activated on the succesfull probe of the RAR device
+*/
+static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+
+static struct pci_device_id rar_pci_id_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4110) },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl);
+
+/* field for registering driver to PCI device */
+static struct pci_driver rar_pci_driver = {
+	.name = "rar_driver",
+	.id_table = rar_pci_id_tbl,
+	.probe = rar_probe
+};
+
+/* This function is used to retrieved RAR info using the IPC message
+   bus interface */
+static int memrar_get_rar_addr(struct pci_dev* pdev,
+	                      int offset,
+	                      u32 *addr)
+{
+	/*
+	 * ======== The Lincroft Message Bus Interface ========
+	 * Lincroft registers may be obtained from the PCI
+	 * (the Host Bridge) using the Lincroft Message Bus
+	 * Interface.  That message bus interface is generally
+	 * comprised of two registers: a control register (MCR, 0xDO)
+	 * and a data register (MDR, 0xD4).
+	 *
+	 * The MCR (message control register) format is the following:
+	 *   1.  [31:24]: Opcode
+	 *   2.  [23:16]: Port
+	 *   3.  [15:8]: Register Offset
+	 *   4.  [7:4]: Byte Enables (use 0xF to set all of these bits
+	 *              to 1)
+	 *   5.  [3:0]: reserved
+	 *
+	 *  Read (0xD0) and write (0xE0) opcodes are written to the
+	 *  control register when reading and writing to Lincroft
+	 *  registers, respectively.
+	 *
+	 *  We're interested in registers found in the Lincroft
+	 *  B-unit.  The B-unit port is 0x3.
+	 *
+	 *  The six B-unit RAR register offsets we use are listed
+	 *  earlier in this file.
+	 *
+	 *  Lastly writing to the MCR register requires the "Byte
+	 *  enables" bits to be set to 1.  This may be achieved by
+	 *  writing 0xF at bit 4.
+	 *
+	 * The MDR (message data register) format is the following:
+	 *   1. [31:0]: Read/Write Data
+	 *
+	 *  Data being read from this register is only available after
+	 *  writing the appropriate control message to the MCR
+	 *  register.
+	 *
+	 *  Data being written to this register must be written before
+	 *  writing the appropriate control message to the MCR
+	 *  register.
+	 */
+
+	int result = 0; /* result */
+	/* Construct control message */
+	u32 const message =
+	       (LNC_MESSAGE_READ_OPCODE << 24)
+	       | (LNC_BUNIT_PORT << 16)
+	       | (offset << 8)
+	       | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
+
+	printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
+
+	if (addr == 0)
+		return -EINVAL;
+
+	/* Send the control message */
+	result = pci_write_config_dword(pdev,
+	                          LNC_MCR_OFFSET,
+	                          message);
+
+	printk(KERN_WARNING "rar- result from send ctl register is %x\n"
+	  ,result);
+
+	if (!result)
+		result = pci_read_config_dword(pdev,
+		                              LNC_MDR_OFFSET,
+				              addr);
+
+	printk(KERN_WARNING "rar- result from read data register is %x\n",
+	  result);
+
+	printk(KERN_WARNING "rar- value read from data register is %x\n",
+	  *addr);
+
+	if (result)
+		return -1;
+	else
+		return 0;
+}
+
+static int memrar_set_rar_addr(struct pci_dev* pdev,
+	                      int offset,
+	                      u32 addr)
+{
+	/*
+	 * ======== The Lincroft Message Bus Interface ========
+	 * Lincroft registers may be obtained from the PCI
+	 * (the Host Bridge) using the Lincroft Message Bus
+	 * Interface.  That message bus interface is generally
+	 * comprised of two registers: a control register (MCR, 0xDO)
+	 * and a data register (MDR, 0xD4).
+	 *
+	 * The MCR (message control register) format is the following:
+	 *   1.  [31:24]: Opcode
+	 *   2.  [23:16]: Port
+	 *   3.  [15:8]: Register Offset
+	 *   4.  [7:4]: Byte Enables (use 0xF to set all of these bits
+	 *              to 1)
+	 *   5.  [3:0]: reserved
+	 *
+	 *  Read (0xD0) and write (0xE0) opcodes are written to the
+	 *  control register when reading and writing to Lincroft
+	 *  registers, respectively.
+	 *
+	 *  We're interested in registers found in the Lincroft
+	 *  B-unit.  The B-unit port is 0x3.
+	 *
+	 *  The six B-unit RAR register offsets we use are listed
+	 *  earlier in this file.
+	 *
+	 *  Lastly writing to the MCR register requires the "Byte
+	 *  enables" bits to be set to 1.  This may be achieved by
+	 *  writing 0xF at bit 4.
+	 *
+	 * The MDR (message data register) format is the following:
+	 *   1. [31:0]: Read/Write Data
+	 *
+	 *  Data being read from this register is only available after
+	 *  writing the appropriate control message to the MCR
+	 *  register.
+	 *
+	 *  Data being written to this register must be written before
+	 *  writing the appropriate control message to the MCR
+	 *  register.
+	 */
+
+	int result = 0; /* result */
+
+	/* Construct control message */
+	u32 const message =
+	       (LNC_MESSAGE_WRITE_OPCODE << 24)
+	       | (LNC_BUNIT_PORT << 16)
+	       | (offset << 8)
+	       | (LNC_MESSAGE_BYTE_WRITE_ENABLES << 4);
+
+	printk(KERN_WARNING "rar- offset to LNC MSG is %x\n",offset);
+
+	if (addr == 0)
+		return -EINVAL;
+
+	/* Send the control message */
+	result = pci_write_config_dword(pdev,
+	                          LNC_MDR_OFFSET,
+	                          addr);
+
+	printk(KERN_WARNING "rar- result from send ctl register is %x\n"
+	  ,result);
+
+	if (!result)
+		result = pci_write_config_dword(pdev,
+		                              LNC_MCR_OFFSET,
+				              message);
+
+	printk(KERN_WARNING "rar- result from write data register is %x\n",
+	  result);
+
+	printk(KERN_WARNING "rar- value read to data register is %x\n",
+	  addr);
+
+	if (result)
+		return -1;
+	else
+		return 0;
+}
+
+/*
+
+ * Initialize RAR parameters, such as physical addresses, etc.
+
+ */
+static int memrar_init_rar_params(struct pci_dev *pdev)
+{
+	struct RAR_offsets const offsets[] = {
+	       { LNC_BRAR0L, LNC_BRAR0H },
+	       { LNC_BRAR1L, LNC_BRAR1H },
+	       { LNC_BRAR2L, LNC_BRAR2H }
+	};
+
+	size_t const num_offsets = sizeof(offsets) / sizeof(offsets[0]);
+	struct RAR_offsets const *end = offsets + num_offsets;
+	struct RAR_offsets const *i;
+	unsigned int n = 0;
+	int result = 0;
+
+	/* Retrieve RAR start and end physical addresses. */
+
+	/*
+	 * Access the RAR registers through the Lincroft Message Bus
+	 * Interface on PCI device: 00:00.0 Host bridge.
+	 */
+
+	/* struct pci_dev *pdev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); */
+
+	if (pdev == NULL)
+	       return -ENODEV;
+
+	for (i = offsets; i != end; ++i, ++n) {
+	       if (memrar_get_rar_addr (pdev,
+		                       (*i).low,
+		                       &(rar_addr[n].low)) != 0
+		   || memrar_get_rar_addr (pdev,
+		                          (*i).high,
+		                          &(rar_addr[n].high)) != 0) {
+		       result = -1;
+		       break;
+	       }
+	}
+
+	/* Done accessing the device. */
+	/* pci_dev_put(pdev); */
+
+	if (result == 0) {
+	if(1) {
+	       size_t z;
+	       for (z = 0; z != MRST_NUM_RAR; ++z) {
+			printk(KERN_WARNING "rar - BRAR[%Zd] physical address low\n"
+			     "\tlow:  0x%08x\n"
+			     "\thigh: 0x%08x\n",
+			     z,
+			     rar_addr[z].low,
+			     rar_addr[z].high);
+			}
+	       }
+	}
+
+	return result;
+}
+
+/*
+  function that is activaed on the succesfull probe of the RAR device
+*/
+static int __devinit rar_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	/* error */
+	int error;
+
+	/*------------------------
+	CODE
+	---------------------------*/
+
+	DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
+	  "Rar pci probe starting\n");
+	error = 0;
+
+	/* enable the device */
+	error = pci_enable_device(pdev);
+	if (error) {
+		DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
+		  "error enabling pci device\n");
+		goto end_function;
+	}
+
+	rar_dev = pdev;
+	registered = 1;
+
+	/* Initialize the RAR parameters, which have to be retrieved */
+	/* via the message bus service */
+	error=memrar_init_rar_params(rar_dev);
+
+	if (error) {
+		DEBUG_PRINT_0(RAR_DEBUG_LEVEL_EXTENDED,
+		  "error getting RAR addresses device\n");
+		registered = 0;
+		goto end_function;
+		}
+
+end_function:
+
+	return error;
+}
+
+/*
+  this function registers th driver to
+  the device subsystem( either PCI, USB, etc)
+*/
+static int __init rar_init_handler(void)
+{
+	return pci_register_driver(&rar_pci_driver);
+}
+
+static void __exit rar_exit_handler(void)
+{
+	pci_unregister_driver(&rar_pci_driver);
+}
+
+module_init(rar_init_handler);
+module_exit(rar_exit_handler);
+
+MODULE_LICENSE("GPL");
+
+
+/* The get_rar_address function is used by other device drivers
+ * to obtain RAR address information on a RAR. It takes two
+ * parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar for which you wish to retrieve
+ * the address information.
+ * Values can be 0,1, or 2.
+ *
+ * struct RAR_address_struct is a pointer to a place to which the function
+ * can return the address structure for the RAR.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int get_rar_address(int rar_index,struct RAR_address_struct *addresses)
+{
+	if (registered && (rar_index < 3) && (rar_index >= 0)) {
+		*addresses=rar_addr[rar_index];
+		/* strip off lock bit information  */
+		addresses->low = addresses->low & 0xfffffff0;
+		addresses->high = addresses->high & 0xfffffff0;
+		return 0;
+		}
+
+	else {
+		return -ENODEV;
+		}
+}
+
+
+EXPORT_SYMBOL(get_rar_address);
+
+/* The lock_rar function is ued by other device drivers to lock an RAR.
+ * once an RAR is locked, it stays locked until the next system reboot.
+ * The function takes one parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar that you want to lock.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int lock_rar(int rar_index)
+{
+	u32 working_addr;
+	int result;
+if (registered && (rar_index < 3) && (rar_index >= 0)) {
+	/* first make sure that lock bits are clear (this does lock) */
+	working_addr=rar_addr[rar_index].low & 0xfffffff0;
+
+	/* now send that value to the register using the IPC */
+        result=memrar_set_rar_addr(rar_dev,rar_index,working_addr);
+	return result;
+	}
+
+else {
+	return -ENODEV;
+	}
+}
diff --git a/drivers/staging/rar/rar_driver.h b/drivers/staging/rar/rar_driver.h
new file mode 100644
index 0000000..3690f98
--- /dev/null
+++ b/drivers/staging/rar/rar_driver.h
@@ -0,0 +1,99 @@
+/* === RAR Physical Addresses === */
+struct RAR_address_struct {
+        u32 low;
+        u32 high;
+};
+
+/* The get_rar_address function is used by other device drivers
+ * to obtain RAR address information on a RAR. It takes two
+ * parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar for which you wish to retrieve
+ * the address information.
+ * Values can be 0,1, or 2.
+ *
+ * struct RAR_address_struct is a pointer to a place to which the function
+ * can return the address structure for the RAR.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int get_rar_address(int rar_index,struct RAR_address_struct *addresses);
+
+
+/* The lock_rar function is ued by other device drivers to lock an RAR.
+ * once an RAR is locked, it stays locked until the next system reboot.
+ * The function takes one parameter:
+ *
+ * int rar_index
+ * The rar_index is an index to the rar that you want to lock.
+ * Values can be 0,1, or 2.
+ *
+ * The function returns a 0 upon success or a -1 if there is no RAR
+ * facility on this system.
+ */
+int lock_rar(int rar_index);
+
+
+/* DEBUG LEVEL MASKS */
+#define RAR_DEBUG_LEVEL_BASIC       0x1
+
+#define RAR_DEBUG_LEVEL_REGISTERS   0x2
+
+#define RAR_DEBUG_LEVEL_EXTENDED    0x4
+
+#define DEBUG_LEVEL	0x7
+
+/* FUNCTIONAL MACROS */
+
+/* debug macro without paramaters */
+#define DEBUG_PRINT_0(DEBUG_LEVEL , info) \
+do \
+{ \
+  if(DEBUG_LEVEL) \
+  { \
+    printk(KERN_WARNING info); \
+  } \
+}while(0)
+
+/* debug macro with 1 paramater */
+#define DEBUG_PRINT_1(DEBUG_LEVEL , info , param1) \
+do \
+{ \
+  if(DEBUG_LEVEL) \
+  { \
+    printk(KERN_WARNING info , param1); \
+  } \
+}while(0)
+
+/* debug macro with 2 paramaters */
+#define DEBUG_PRINT_2(DEBUG_LEVEL , info , param1, param2) \
+do \
+{ \
+  if(DEBUG_LEVEL) \
+  { \
+    printk(KERN_WARNING info , param1, param2); \
+  } \
+}while(0)
+
+/* debug macro with 3 paramaters */
+#define DEBUG_PRINT_3(DEBUG_LEVEL , info , param1, param2 , param3) \
+do \
+{ \
+  if(DEBUG_LEVEL) \
+  { \
+    printk(KERN_WARNING info , param1, param2 , param3); \
+  } \
+}while(0)
+
+/* debug macro with 4 paramaters */
+#define DEBUG_PRINT_4(DEBUG_LEVEL , info , param1, param2 , param3 , param4) \
+do \
+{ \
+  if(DEBUG_LEVEL) \
+  { \
+    printk(KERN_WARNING info , param1, param2 , param3 , param4); \
+  } \
+}while(0)
+
diff --git a/drivers/staging/rspiusb/Kconfig b/drivers/staging/rspiusb/Kconfig
deleted file mode 100644
index d225f67..0000000
--- a/drivers/staging/rspiusb/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-config USB_RSPI
-	tristate "Princeton Instruments USB camera support"
-	default n
-	depends on USB && BROKEN
-	help
-	  This driver is for the Princeton Instruments USB camera device.
diff --git a/drivers/staging/rspiusb/Makefile b/drivers/staging/rspiusb/Makefile
deleted file mode 100644
index cc7aed9..0000000
--- a/drivers/staging/rspiusb/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_USB_RSPI)		+= rspiusb.o
diff --git a/drivers/staging/rspiusb/TODO b/drivers/staging/rspiusb/TODO
deleted file mode 100644
index cd6336a..0000000
--- a/drivers/staging/rspiusb/TODO
+++ /dev/null
@@ -1,22 +0,0 @@
-This driver is for the Princeton Instruments USB camera.
-
-It needs lots of work to get it into the main drivers/usb/ subdirectory:
-
-Any patches to do any of the following changes are greatly appreciated:
-
-	- make checkpatch.pl clean
-	- coding style fixups (typedefs, etc.)
-	- get it to build properly
-	- audit ioctls
-	- remove ioctls if possible
-	- assign proper minor number
-	- remove dbg() macro
-	- lots of general cleanups
-	- review locking
-
-Please send patches to:
-	Greg Kroah-Hartman <gregkh@suse.de>
-and CC:
-	Judd Montgomery <judd@jpilot.org>
-	Jeff Frontz <jeff.frontz@gmail.com>
-as they have this device and can test any needed changes.
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c
deleted file mode 100644
index 04e2f92..0000000
--- a/drivers/staging/rspiusb/rspiusb.c
+++ /dev/null
@@ -1,923 +0,0 @@
-/*
- * rspiusb.c
- *
- * Copyright (C) 2005, 2006 Princeton Instruments
- *
- * This program is free software; 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/vmalloc.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/smp_lock.h>
-#include <linux/completion.h>
-#include <linux/scatterlist.h>
-#include <linux/usb.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/ioctl.h>
-#include "rspiusb.h"
-
-#ifdef CONFIG_USB_DEBUG
-static int debug = 1;
-#else
-static int debug;
-#endif
-/* Use our own dbg macro */
-#undef dbg
-#define dbg(format, arg...) \
-	do { \
-		if (debug) \
-			printk(KERN_DEBUG __FILE__ ": " format "\n" , ##arg); \
-	} while (0)
-
-/* Version Information */
-#define DRIVER_VERSION "V1.0.1"
-#define DRIVER_AUTHOR  "Princeton Instruments"
-#define DRIVER_DESC    "PI USB2.0 Device Driver for Linux"
-
-/* Define these values to match your devices */
-#define VENDOR_ID   0x0BD7
-#define ST133_PID   0xA010
-#define PIXIS_PID   0xA026
-
-/* Get a minor range for your devices from the usb maintainer */
-#ifdef CONFIG_USB_DYNAMIC_MINORS
-#define PIUSB_MINOR_BASE    0
-#else
-#define PIUSB_MINOR_BASE    192
-#endif
-
-/* prevent races between open() and disconnect() */
-static DECLARE_MUTEX(disconnect_sem);
-
-/* Structure to hold all of our device specific stuff */
-struct device_extension {
-	struct usb_device *udev;	 /* save off the usb device pointer */
-	struct usb_interface *interface; /* the interface for this device */
-	unsigned char minor;		 /* the starting minor number
-					  * for this device
-					  */
-	size_t bulk_in_size_returned;
-	int bulk_in_byte_trk;
-	struct urb ***PixelUrb;
-	int frameIdx;
-	int urbIdx;
-	unsigned int *maplist_numPagesMapped;
-	int open;		  /* if the port is open or not */
-	int present;		  /* if the device is not disconnected */
-	int userBufMapped;	  /* has the user buffer been mapped ? */
-	struct scatterlist **sgl; /* scatter-gather list for user buffer */
-	unsigned int *sgEntries;
-	struct kref kref;
-	int gotPixelData;
-	int pendingWrite;
-	char **pendedPixelUrbs;
-	int iama;		 /* PIXIS or ST133 */
-	int num_frames;		 /* the number of frames that will fit
-				  * in the user buffer
-				  */
-	int active_frame;
-	unsigned long frameSize;
-	struct semaphore sem;
-	unsigned int hEP[8];	 /* FX2 specific endpoints */
-};
-
-#define to_pi_dev(d) container_of(d, struct device_extension, kref)
-
-/* Prototypes */
-static int MapUserBuffer(struct ioctl_struct *, struct device_extension *);
-static int UnMapUserBuffer(struct device_extension *);
-static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		       unsigned long arg);
-static int piusb_output(struct ioctl_struct *, unsigned char *, int,
-		struct device_extension *);
-static struct usb_driver piusb_driver;
-
-/* table of devices that work with this driver */
-static struct usb_device_id pi_device_table[] = {
-	{USB_DEVICE(VENDOR_ID, ST133_PID)},
-	{USB_DEVICE(VENDOR_ID, PIXIS_PID)},
-	{0, } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE(usb, pi_device_table);
-
-static int lastErr;
-static int errCnt;
-
-static void piusb_delete(struct kref *kref)
-{
-	struct device_extension *pdx = to_pi_dev(kref);
-
-	dev_dbg(&pdx->udev->dev, "%s\n", __func__);
-	usb_put_dev(pdx->udev);
-	kfree(pdx);
-}
-
-static int piusb_open(struct inode *inode, struct file *file)
-{
-	struct device_extension *pdx = NULL;
-	struct usb_interface *interface;
-	int subminor;
-	int retval = 0;
-
-	dbg("Piusb_Open()");
-	subminor = iminor(inode);
-	interface = usb_find_interface(&piusb_driver, subminor);
-	if (!interface) {
-		printk(KERN_ERR "%s - error, can't find device for minor %d\n",
-		       __func__, subminor);
-		retval = -ENODEV;
-		goto exit_no_device;
-	}
-
-	pdx = usb_get_intfdata(interface);
-	if (!pdx) {
-		retval = -ENODEV;
-		goto exit_no_device;
-	}
-	dbg("Alternate Setting = %d", interface->num_altsetting);
-
-	pdx->bulk_in_size_returned = 0;
-	pdx->bulk_in_byte_trk = 0;
-	pdx->PixelUrb = NULL;
-	pdx->frameIdx = 0;
-	pdx->urbIdx = 0;
-	pdx->maplist_numPagesMapped = NULL;
-	pdx->userBufMapped = 0;
-	pdx->sgl = NULL;
-	pdx->sgEntries = NULL;
-	pdx->gotPixelData = 0;
-	pdx->pendingWrite = 0;
-	pdx->pendedPixelUrbs = NULL;
-	pdx->num_frames = 0;
-	pdx->active_frame = 0;
-	pdx->frameSize = 0;
-
-	/* increment our usage count for the device */
-	kref_get(&pdx->kref);
-
-	/* save our object in the file's private structure */
-	file->private_data = pdx;
-
-exit_no_device:
-	return retval;
-}
-
-static int piusb_release(struct inode *inode, struct file *file)
-{
-	struct device_extension *pdx;
-	int retval = 0;
-
-	dbg("Piusb_Release()");
-	pdx = (struct device_extension *)file->private_data;
-	if (pdx == NULL) {
-		dbg("%s - object is NULL", __func__);
-		retval = -ENODEV;
-		goto object_null;
-	}
-	/* decrement the count on our device */
-	kref_put(&pdx->kref, piusb_delete);
-
-object_null:
-	return retval;
-}
-
-static int pixis_io(struct ioctl_struct *ctrl, struct device_extension *pdx,
-		struct ioctl_struct *arg)
-{
-	unsigned int numToRead = 0;
-	unsigned int totalRead = 0;
-	unsigned char *uBuf;
-	int numbytes;
-	int i;
-
-	uBuf = kmalloc(ctrl->numbytes, GFP_KERNEL);
-	if (!uBuf) {
-		dbg("Alloc for uBuf failed");
-		return 0;
-	}
-	numbytes = (int) ctrl->numbytes;
-	numToRead = (unsigned int) ctrl->numbytes;
-	dbg("numbytes to read = %d", numbytes);
-	dbg("endpoint # %d", ctrl->endpoint);
-
-	if (copy_from_user(uBuf, ctrl->pData, numbytes)) {
-		dbg("copying ctrl->pData to dummyBuf failed");
-		return -EFAULT;
-	}
-
-	do {
-		i = usb_bulk_msg(pdx->udev, pdx->hEP[ctrl->endpoint],
-				(uBuf + totalRead),
-				/* EP0 can only handle 64 bytes at a time */
-				(numToRead > 64) ? 64 : numToRead,
-				&numbytes, HZ * 10);
-		if (i) {
-			dbg("CMD = %s, Address = 0x%02X",
-					((uBuf[3] == 0x02) ? "WRITE" : "READ"),
-					uBuf[1]);
-			dbg("Number of bytes Attempted to read = %d",
-					(int)ctrl->numbytes);
-			dbg("Blocking ReadI/O Failed with status %d", i);
-			kfree(uBuf);
-			return -1;
-		}
-		dbg("Pixis EP0 Read %d bytes", numbytes);
-		totalRead += numbytes;
-		numToRead -= numbytes;
-	} while (numToRead);
-
-	memcpy(ctrl->pData, uBuf, totalRead);
-	dbg("Total Bytes Read from PIXIS EP0 = %d", totalRead);
-	ctrl->numbytes = totalRead;
-
-	if (copy_to_user(arg, ctrl, sizeof(struct ioctl_struct)))
-		dbg("copy_to_user failed in IORB");
-
-	kfree(uBuf);
-	return ctrl->numbytes;
-}
-
-static int pixel_data(struct ioctl_struct *ctrl, struct device_extension *pdx)
-{
-	int i;
-
-	if (!pdx->gotPixelData)
-		return 0;
-
-	pdx->gotPixelData = 0;
-	ctrl->numbytes = pdx->bulk_in_size_returned;
-	pdx->bulk_in_size_returned -= pdx->frameSize;
-
-	for (i = 0; i < pdx->maplist_numPagesMapped[pdx->active_frame]; i++)
-		SetPageDirty(sg_page(&pdx->sgl[pdx->active_frame][i]));
-
-	pdx->active_frame = ((pdx->active_frame + 1) % pdx->num_frames);
-
-	return ctrl->numbytes;
-}
-
-/**
- *	piusb_ioctl
- */
-static int piusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		       unsigned long arg)
-{
-	struct device_extension *pdx;
-	char dummyCtlBuf[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-	unsigned long devRB = 0;
-	int err = 0;
-	int retval = 0;
-	struct ioctl_struct ctrl;
-	unsigned short controlData = 0;
-
-	pdx = (struct device_extension *)file->private_data;
-	/* verify that the device wasn't unplugged */
-	if (!pdx->present) {
-		dbg("No Device Present\n");
-		return -ENODEV;
-	}
-	/* fill in your device specific stuff here */
-	if (_IOC_DIR(cmd) & _IOC_READ)
-		err = !access_ok(VERIFY_WRITE, (void __user *)arg,
-				_IOC_SIZE(cmd));
-	else if (_IOC_DIR(cmd) & _IOC_WRITE)
-		err = !access_ok(VERIFY_READ, (void __user *)arg,
-			       _IOC_SIZE(cmd));
-	if (err) {
-		dev_err(&pdx->udev->dev, "return with error = %d\n", err);
-		return -EFAULT;
-	}
-	switch (cmd) {
-	case PIUSB_GETVNDCMD:
-		if (__copy_from_user
-		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
-			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
-			return -EFAULT;
-		}
-		dbg("%s %x\n", "Get Vendor Command = ", ctrl.cmd);
-		retval =
-		    usb_control_msg(pdx->udev, usb_rcvctrlpipe(pdx->udev, 0),
-				    ctrl.cmd, USB_DIR_IN, 0, 0, &devRB,
-				    ctrl.numbytes, HZ * 10);
-		if (ctrl.cmd == 0xF1) {
-			dbg("FW Version returned from HW = %ld.%ld",
-			    (devRB >> 8), (devRB & 0xFF));
-		}
-		if (retval >= 0)
-			retval = (int)devRB;
-		return retval;
-
-	case PIUSB_SETVNDCMD:
-		if (__copy_from_user
-		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
-			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
-			return -EFAULT;
-		}
-		/* dbg( "%s %x", "Set Vendor Command = ",ctrl.cmd ); */
-		controlData = ctrl.pData[0];
-		controlData |= (ctrl.pData[1] << 8);
-		/* dbg( "%s %d", "Vendor Data =",controlData ); */
-		retval = usb_control_msg(pdx->udev,
-				usb_sndctrlpipe(pdx->udev, 0),
-				ctrl.cmd,
-				(USB_DIR_OUT | USB_TYPE_VENDOR
-				 /* | USB_RECIP_ENDPOINT */),
-				controlData, 0,
-				&dummyCtlBuf, ctrl.numbytes, HZ * 10);
-		return retval;
-
-	case PIUSB_ISHIGHSPEED:
-		return ((pdx->udev->speed == USB_SPEED_HIGH) ? 1 : 0);
-
-	case PIUSB_WRITEPIPE:
-		if (__copy_from_user(&ctrl, (void __user *)arg, _IOC_SIZE(cmd))) {
-			dev_err(&pdx->udev->dev,
-					"copy_from_user WRITE_DUMMY failed\n");
-			return -EFAULT;
-		}
-		if (!access_ok(VERIFY_READ, ctrl.pData, ctrl.numbytes)) {
-			dbg("can't access pData");
-			return 0;
-		}
-		piusb_output(&ctrl, ctrl.pData /* uBuf */, ctrl.numbytes, pdx);
-		return ctrl.numbytes;
-
-	case PIUSB_USERBUFFER:
-		if (__copy_from_user
-		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
-			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
-			return -EFAULT;
-		}
-		return MapUserBuffer((struct ioctl_struct *) &ctrl, pdx);
-
-	case PIUSB_UNMAP_USERBUFFER:
-		retval = UnMapUserBuffer(pdx);
-		return retval;
-
-	case PIUSB_READPIPE:
-		if (__copy_from_user(&ctrl, (void __user *)arg,
-					sizeof(struct ioctl_struct))) {
-			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
-			return -EFAULT;
-		}
-		if (((0 == ctrl.endpoint) && (PIXIS_PID == pdx->iama)) ||
-				(1 == ctrl.endpoint) ||	/* ST133IO */
-				(4 == ctrl.endpoint))	/* PIXIS IO */
-			return pixis_io(&ctrl, pdx,
-					(struct ioctl_struct *)arg);
-		else if ((0 == ctrl.endpoint) || /* ST133 Pixel Data */
-				(2 == ctrl.endpoint) || /* PIXIS Ping */
-				(3 == ctrl.endpoint))	/* PIXIS Pong */
-			return pixel_data(&ctrl, pdx);
-
-		break;
-
-	case PIUSB_WHATCAMERA:
-		return pdx->iama;
-
-	case PIUSB_SETFRAMESIZE:
-		dbg("PIUSB_SETFRAMESIZE");
-		if (__copy_from_user
-		    (&ctrl, (void __user *)arg, sizeof(struct ioctl_struct))) {
-			dev_err(&pdx->udev->dev, "copy_from_user failed\n");
-			return -EFAULT;
-		}
-		pdx->frameSize = ctrl.numbytes;
-		pdx->num_frames = ctrl.numFrames;
-		if (!pdx->sgl)
-			pdx->sgl =
-			    kmalloc(sizeof(struct scatterlist *) *
-				    pdx->num_frames, GFP_KERNEL);
-		if (!pdx->sgEntries)
-			pdx->sgEntries =
-			    kmalloc(sizeof(unsigned int) * pdx->num_frames,
-				    GFP_KERNEL);
-		if (!pdx->PixelUrb)
-			pdx->PixelUrb =
-			    kmalloc(sizeof(struct urb **) * pdx->num_frames,
-				    GFP_KERNEL);
-		if (!pdx->maplist_numPagesMapped)
-			pdx->maplist_numPagesMapped =
-			    vmalloc(sizeof(unsigned int) * pdx->num_frames);
-		if (!pdx->pendedPixelUrbs)
-			pdx->pendedPixelUrbs =
-			    kmalloc(sizeof(char *) * pdx->num_frames,
-				    GFP_KERNEL);
-		return 0;
-
-	default:
-		dbg("%s\n", "No IOCTL found");
-		break;
-
-	}
-	/* return that we did not understand this ioctl call */
-	dbg("Returning -ENOTTY");
-	return -ENOTTY;
-}
-
-static void piusb_write_bulk_callback(struct urb *urb)
-{
-	struct device_extension *pdx = urb->context;
-	int status = urb->status;
-
-	/* sync/async unlink faults aren't errors */
-	if (status && !(status == -ENOENT || status == -ECONNRESET))
-		dev_dbg(&urb->dev->dev,
-			"%s - nonzero write bulk status received: %d",
-			__func__, status);
-
-	pdx->pendingWrite = 0;
-	kfree(urb->transfer_buffer);
-}
-
-int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len,
-		 struct device_extension *pdx)
-{
-	struct urb *urb = NULL;
-	int err = 0;
-	unsigned char *kbuf = NULL;
-
-	urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (urb != NULL) {
-		kbuf = kmalloc(len, GFP_KERNEL);
-		if (!kbuf) {
-			dev_err(&pdx->udev->dev, "buffer_alloc failed\n");
-			return -ENOMEM;
-		}
-		if(__copy_from_user(kbuf, uBuf, len)) {
-			dev_err(&pdx->udev->dev, "__copy_from_user failed\n");
-			return -EFAULT;
-		}
-		usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf,
-				  len, piusb_write_bulk_callback, pdx);
-		err = usb_submit_urb(urb, GFP_KERNEL);
-		if (err) {
-			dev_err(&pdx->udev->dev,
-				"WRITE ERROR:submit urb error = %d\n", err);
-		}
-		pdx->pendingWrite = 1;
-		usb_free_urb(urb);
-	}
-	return -EINPROGRESS;
-}
-
-static int UnMapUserBuffer(struct device_extension *pdx)
-{
-	int i = 0;
-	int k = 0;
-	unsigned int epAddr;
-
-	for (k = 0; k < pdx->num_frames; k++) {
-		dbg("Killing Urbs for Frame %d", k);
-		for (i = 0; i < pdx->sgEntries[k]; i++) {
-			usb_kill_urb(pdx->PixelUrb[k][i]);
-			usb_free_urb(pdx->PixelUrb[k][i]);
-			pdx->pendedPixelUrbs[k][i] = 0;
-		}
-		dbg("Urb error count = %d", errCnt);
-		errCnt = 0;
-		dbg("Urbs free'd and Killed for Frame %d", k);
-	}
-
-	for (k = 0; k < pdx->num_frames; k++) {
-		if (pdx->iama == PIXIS_PID)
-			/* which EP should we map this frame to ? */
-			/* PONG, odd frames: hEP[3] */
-			/* PING, even frames and zero hEP[2] */
-			epAddr = (k % 2) ? pdx->hEP[3] : pdx->hEP[2];
-		else
-			/* ST133 only has 1 endpoint for Pixel data transfer */
-			epAddr = pdx->hEP[0];
-
-		usb_buffer_unmap_sg(pdx->udev, epAddr, pdx->sgl[k],
-				    pdx->maplist_numPagesMapped[k]);
-		for (i = 0; i < pdx->maplist_numPagesMapped[k]; i++)
-			page_cache_release(sg_page(&pdx->sgl[k][i]));
-		kfree(pdx->sgl[k]);
-		kfree(pdx->PixelUrb[k]);
-		kfree(pdx->pendedPixelUrbs[k]);
-		pdx->sgl[k] = NULL;
-		pdx->PixelUrb[k] = NULL;
-		pdx->pendedPixelUrbs[k] = NULL;
-	}
-
-	kfree(pdx->sgEntries);
-	vfree(pdx->maplist_numPagesMapped);
-	pdx->sgEntries = NULL;
-	pdx->maplist_numPagesMapped = NULL;
-	kfree(pdx->sgl);
-	kfree(pdx->pendedPixelUrbs);
-	kfree(pdx->PixelUrb);
-	pdx->sgl = NULL;
-	pdx->pendedPixelUrbs = NULL;
-	pdx->PixelUrb = NULL;
-
-	return 0;
-}
-
-static void piusb_readPIXEL_callback(struct urb *urb)
-{
-	int i = 0;
-	struct device_extension *pdx = urb->context;
-	int status = urb->status;
-
-	if (status && !(status == -ENOENT || status == -ECONNRESET)) {
-		dbg("%s - nonzero read bulk status received: %d", __func__,
-		    status);
-		dbg("Error in read EP2 callback");
-		dbg("FrameIndex = %d", pdx->frameIdx);
-		dbg("Bytes received before problem occurred = %d",
-		    pdx->bulk_in_byte_trk);
-		dbg("Urb Idx = %d", pdx->urbIdx);
-		pdx->pendedPixelUrbs[pdx->frameIdx][pdx->urbIdx] = 0;
-	} else {
-		pdx->bulk_in_byte_trk += urb->actual_length;
-		i = usb_submit_urb(urb, GFP_ATOMIC);	/* resubmit the URB */
-		if (i) {
-			errCnt++;
-			if (i != lastErr) {
-				dbg("submit urb in callback failed "
-						"with error code %d", i);
-				lastErr = i;
-			}
-		} else {
-			pdx->urbIdx++; /* point to next URB when we callback */
-			if (pdx->bulk_in_byte_trk >= pdx->frameSize) {
-				pdx->bulk_in_size_returned =
-					pdx->bulk_in_byte_trk;
-				pdx->bulk_in_byte_trk = 0;
-				pdx->gotPixelData = 1;
-				pdx->frameIdx =
-					((pdx->frameIdx +
-					  1) % pdx->num_frames);
-				pdx->urbIdx = 0;
-			}
-		}
-	}
-}
-
-/* MapUserBuffer(
-	inputs:
-	struct ioctl_struct *io - structure containing user address,
-				frame #, and size
-	struct device_extension *pdx - the PIUSB device extension
-
-	returns:
-	int - status of the task
-
-	Notes:
-	MapUserBuffer maps a buffer passed down through an ioctl.
-	The user buffer is Page Aligned by the app and then passed down.
-	The function get_free_pages(...) does the actual mapping of the buffer
-	from user space to kernel space.
-	From there a scatterlist is created from all the pages.
-	The next function called is to usb_buffer_map_sg which allocated
-	DMA addresses for each page, even coalescing them if possible.
-	The DMA address is placed in the scatterlist structure.
-	The function returns the number of DMA addresses.
-	This may or may not be equal to the number of pages that
-	the user buffer uses.
-	We then build an URB for each DMA address and then submit them.
-*/
-
-/*
-int MapUserBuffer(unsigned long uaddr, unsigned long numbytes,
-		unsigned long frameInfo, struct device_extension *pdx)
-*/
-static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
-{
-	unsigned long uaddr;
-	unsigned long numbytes;
-	int frameInfo;	/* which frame we're mapping */
-	unsigned int epAddr = 0;
-	unsigned long count = 0;
-	int i = 0;
-	int k = 0;
-	int err = 0;
-	struct page **maplist_p;
-	int numPagesRequired;
-
-	frameInfo = io->numFrames;
-	uaddr = (unsigned long)io->pData;
-	numbytes = io->numbytes;
-
-	if (pdx->iama == PIXIS_PID) {
-		/* which EP should we map this frame to ? */
-		/* PONG, odd frames: hEP[3] */
-		/* PING, even frames and zero hEP[2] */
-		epAddr = (frameInfo % 2) ? pdx->hEP[3] : pdx->hEP[2];
-		dbg("Pixis Frame #%d: EP=%d", frameInfo,
-		    (epAddr == pdx->hEP[2]) ? 2 : 4);
-	} else { /* ST133 only has 1 endpoint for Pixel data transfer */
-		epAddr = pdx->hEP[0];
-		dbg("ST133 Frame #%d: EP=2", frameInfo);
-	}
-	count = numbytes;
-	dbg("UserAddress = 0x%08lX", uaddr);
-	dbg("numbytes = %d", (int)numbytes);
-
-	/* number of pages to map the entire user space DMA buffer */
-	numPagesRequired =
-	    ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
-	dbg("Number of pages needed = %d", numPagesRequired);
-	maplist_p = vmalloc(numPagesRequired * sizeof(struct page *));
-	if (!maplist_p) {
-		dbg("Can't Allocate Memory for maplist_p");
-		return -ENOMEM;
-	}
-
-	/* map the user buffer to kernel memory */
-	down_write(&current->mm->mmap_sem);
-	pdx->maplist_numPagesMapped[frameInfo] = get_user_pages(current,
-			current->mm, (uaddr & PAGE_MASK), numPagesRequired,
-			WRITE, 0 /* Don't Force*/, maplist_p, NULL);
-	up_write(&current->mm->mmap_sem);
-	dbg("Number of pages mapped = %d",
-	    pdx->maplist_numPagesMapped[frameInfo]);
-
-	for (i = 0; i < pdx->maplist_numPagesMapped[frameInfo]; i++)
-		flush_dcache_page(maplist_p[i]);
-	if (!pdx->maplist_numPagesMapped[frameInfo]) {
-		dbg("get_user_pages() failed");
-		vfree(maplist_p);
-		return -ENOMEM;
-	}
-
-	/* need to create a scatterlist that spans each frame
-	 * that can fit into the mapped buffer
-	 */
-	pdx->sgl[frameInfo] =
-	    kmalloc((pdx->maplist_numPagesMapped[frameInfo] *
-		     sizeof(struct scatterlist)), GFP_ATOMIC);
-	if (!pdx->sgl[frameInfo]) {
-		vfree(maplist_p);
-		dbg("can't allocate mem for sgl");
-		return -ENOMEM;
-	}
-	sg_assign_page(&pdx->sgl[frameInfo][0], maplist_p[0]);
-	pdx->sgl[frameInfo][0].offset = uaddr & ~PAGE_MASK;
-	if (pdx->maplist_numPagesMapped[frameInfo] > 1) {
-		pdx->sgl[frameInfo][0].length =
-		    PAGE_SIZE - pdx->sgl[frameInfo][0].offset;
-		count -= pdx->sgl[frameInfo][0].length;
-		for (k = 1; k < pdx->maplist_numPagesMapped[frameInfo]; k++) {
-			pdx->sgl[frameInfo][k].offset = 0;
-			sg_assign_page(&pdx->sgl[frameInfo][k], maplist_p[k]);
-			pdx->sgl[frameInfo][k].length =
-			    (count < PAGE_SIZE) ? count : PAGE_SIZE;
-			count -= PAGE_SIZE; /* example had PAGE_SIZE here */
-		}
-	} else {
-		pdx->sgl[frameInfo][0].length = count;
-	}
-	pdx->sgEntries[frameInfo] =
-	    usb_buffer_map_sg(pdx->udev, epAddr, pdx->sgl[frameInfo],
-			      pdx->maplist_numPagesMapped[frameInfo]);
-	dbg("number of sgEntries = %d", pdx->sgEntries[frameInfo]);
-	pdx->userBufMapped = 1;
-	vfree(maplist_p);
-
-	/* Create and Send the URB's for each s/g entry */
-	pdx->PixelUrb[frameInfo] =
-	    kmalloc(pdx->sgEntries[frameInfo] * sizeof(struct urb *),
-		    GFP_KERNEL);
-	if (!pdx->PixelUrb[frameInfo]) {
-		dbg("Can't Allocate Memory for Urb");
-		return -ENOMEM;
-	}
-	for (i = 0; i < pdx->sgEntries[frameInfo]; i++) {
-		/* 0 iso packets because we're using BULK transfers */
-		pdx->PixelUrb[frameInfo][i] = usb_alloc_urb(0, GFP_KERNEL);
-		usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i],
-				  pdx->udev,
-				  epAddr,
-				  NULL, // non-DMA HC? buy a better hardware
-				  sg_dma_len(&pdx->sgl[frameInfo][i]),
-				  piusb_readPIXEL_callback, (void *)pdx);
-		pdx->PixelUrb[frameInfo][i]->transfer_dma =
-		    sg_dma_address(&pdx->sgl[frameInfo][i]);
-		pdx->PixelUrb[frameInfo][i]->transfer_flags =
-		    URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT;
-	}
-	if (i == 0)
-		return -EINVAL;
-	/* only interrupt when last URB completes */
-	pdx->PixelUrb[frameInfo][--i]->transfer_flags &= ~URB_NO_INTERRUPT;
-	pdx->pendedPixelUrbs[frameInfo] =
-	    kmalloc((pdx->sgEntries[frameInfo] * sizeof(char)), GFP_KERNEL);
-	if (!pdx->pendedPixelUrbs[frameInfo])
-		dbg("Can't allocate Memory for pendedPixelUrbs");
-	for (i = 0; i < pdx->sgEntries[frameInfo]; i++) {
-		err = usb_submit_urb(pdx->PixelUrb[frameInfo][i], GFP_ATOMIC);
-		if (err) {
-			dbg("%s %d\n", "submit urb error =", err);
-			pdx->pendedPixelUrbs[frameInfo][i] = 0;
-			return err;
-		}
-		pdx->pendedPixelUrbs[frameInfo][i] = 1;
-	}
-	return 0;
-}
-
-static const struct file_operations piusb_fops = {
-	.owner = THIS_MODULE,
-	.ioctl = piusb_ioctl,
-	.open = piusb_open,
-	.release = piusb_release,
-};
-
-static struct usb_class_driver piusb_class = {
-	.name = "usb/rspiusb%d",
-	.fops = &piusb_fops,
-	.minor_base = PIUSB_MINOR_BASE,
-};
-
-/**
- *	piusb_probe
- *
- *	Called by the usb core when a new device is connected that it thinks
- *	this driver might be interested in.
- */
-static int piusb_probe(struct usb_interface *interface,
-		       const struct usb_device_id *id)
-{
-	struct device_extension *pdx = NULL;
-	struct usb_host_interface *iface_desc;
-	struct usb_endpoint_descriptor *endpoint;
-	int i;
-	int retval = -ENOMEM;
-
-	dev_dbg(&interface->dev, "%s - Looking for PI USB Hardware", __func__);
-
-	pdx = kzalloc(sizeof(struct device_extension), GFP_KERNEL);
-	if (pdx == NULL) {
-		dev_err(&interface->dev, "Out of memory\n");
-		goto error;
-	}
-	kref_init(&pdx->kref);
-	pdx->udev = usb_get_dev(interface_to_usbdev(interface));
-	pdx->interface = interface;
-	iface_desc = interface->cur_altsetting;
-
-	/* See if the device offered us matches what we can accept */
-	if ((pdx->udev->descriptor.idVendor != VENDOR_ID)
-	    || ((pdx->udev->descriptor.idProduct != PIXIS_PID)
-		&& (pdx->udev->descriptor.idProduct != ST133_PID)))
-		return -ENODEV;
-
-	pdx->iama = pdx->udev->descriptor.idProduct;
-
-	if (debug) {
-		if (pdx->udev->descriptor.idProduct == PIXIS_PID)
-			dbg("PIUSB:Pixis Camera Found");
-		else
-			dbg("PIUSB:ST133 USB Controller Found");
-		if (pdx->udev->speed == USB_SPEED_HIGH)
-			dbg("Highspeed(USB2.0) Device Attached");
-		else
-			dbg("Lowspeed (USB1.1) Device Attached");
-
-		dbg("NumEndpoints in Configuration: %d",
-		    iface_desc->desc.bNumEndpoints);
-	}
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-		endpoint = &iface_desc->endpoint[i].desc;
-		if (debug) {
-			dbg("Endpoint[%d]->bDescriptorType = %d", i,
-			    endpoint->bDescriptorType);
-			dbg("Endpoint[%d]->bEndpointAddress = 0x%02X", i,
-			    endpoint->bEndpointAddress);
-			dbg("Endpoint[%d]->bbmAttributes = %d", i,
-			    endpoint->bmAttributes);
-			dbg("Endpoint[%d]->MaxPacketSize = %d\n", i,
-			    endpoint->wMaxPacketSize);
-		}
-		if (usb_endpoint_xfer_bulk(endpoint)) {
-			if (usb_endpoint_dir_in(endpoint))
-				pdx->hEP[i] =
-				    usb_rcvbulkpipe(pdx->udev,
-						    endpoint->bEndpointAddress);
-			else
-				pdx->hEP[i] =
-				    usb_sndbulkpipe(pdx->udev,
-						    endpoint->bEndpointAddress);
-		}
-	}
-	usb_set_intfdata(interface, pdx);
-	retval = usb_register_dev(interface, &piusb_class);
-	if (retval) {
-		err("Not able to get a minor for this device.");
-		usb_set_intfdata(interface, NULL);
-		goto error;
-	}
-	pdx->present = 1;
-
-	/* we can register the device now, as it is ready */
-	pdx->minor = interface->minor;
-	/* let the user know what node this device is now attached to */
-	dbg("PI USB2.0 device now attached to piusb-%d", pdx->minor);
-	return 0;
-
-error:
-	if (pdx)
-		kref_put(&pdx->kref, piusb_delete);
-	return retval;
-}
-
-/**
- *	piusb_disconnect
- *
- *	Called by the usb core when the device is removed from the system.
- *
- *	This routine guarantees that the driver will not submit any more urbs
- *	by clearing pdx->udev.  It is also supposed to terminate any currently
- *	active urbs.  Unfortunately, usb_bulk_msg(), used in piusb_read(), does
- *	not provide any way to do this.  But at least we can cancel an active
- *	write.
- */
-static void piusb_disconnect(struct usb_interface *interface)
-{
-	struct device_extension *pdx;
-	int minor = interface->minor;
-
-	lock_kernel();
-
-	pdx = usb_get_intfdata(interface);
-	usb_set_intfdata(interface, NULL);
-
-	/* give back our minor */
-	usb_deregister_dev(interface, &piusb_class);
-
-	unlock_kernel();
-
-	/* prevent device read, write and ioctl */
-	pdx->present = 0;
-	kref_put(&pdx->kref, piusb_delete);
-	dbg("PI USB2.0 device #%d now disconnected\n", minor);
-}
-
-static struct usb_driver piusb_driver = {
-	.name = "sub",
-	.probe = piusb_probe,
-	.disconnect = piusb_disconnect,
-	.id_table = pi_device_table,
-};
-
-/**
- *	piusb_init
- */
-static int __init piusb_init(void)
-{
-	int result;
-
-	lastErr = 0;
-	errCnt = 0;
-
-	/* register this driver with the USB subsystem */
-	result = usb_register(&piusb_driver);
-	if (result)
-		printk(KERN_ERR KBUILD_MODNAME
-				": usb_register failed. Error number %d\n",
-				result);
-	else
-		printk(KERN_INFO KBUILD_MODNAME ":%s: %s\n", DRIVER_DESC,
-				DRIVER_VERSION);
-	return result;
-}
-
-/**
- *	piusb_exit
- */
-static void __exit piusb_exit(void)
-{
-	/* deregister this driver with the USB subsystem */
-	usb_deregister(&piusb_driver);
-}
-
-module_init(piusb_init);
-module_exit(piusb_exit);
-
-/* Module parameters */
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/rspiusb/rspiusb.h b/drivers/staging/rspiusb/rspiusb.h
deleted file mode 100644
index 3fc1db7..0000000
--- a/drivers/staging/rspiusb/rspiusb.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __RSPIUSB_H
-#define __RSPIUSB_H
-
-#define PIUSB_MAGIC		'm'
-#define PIUSB_IOCTL_BASE	192
-
-#define PIUSB_IOR(offset) \
-	_IOR(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
-#define PIUSB_IOW(offset) \
-	_IOW(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset, struct ioctl_struct)
-#define PIUSB_IO(offset) \
-	_IO(PIUSB_MAGIC, PIUSB_IOCTL_BASE + offset)
-
-#define PIUSB_GETVNDCMD		PIUSB_IOR(1)
-#define PIUSB_SETVNDCMD		PIUSB_IOW(2)
-#define PIUSB_WRITEPIPE		PIUSB_IOW(3)
-#define PIUSB_READPIPE		PIUSB_IOR(4)
-#define PIUSB_SETFRAMESIZE	PIUSB_IOW(5)
-#define PIUSB_WHATCAMERA	PIUSB_IO(6)
-#define PIUSB_USERBUFFER	PIUSB_IOW(7)
-#define PIUSB_ISHIGHSPEED	PIUSB_IO(8)
-#define PIUSB_UNMAP_USERBUFFER	PIUSB_IOW(9)
-
-struct ioctl_struct {
-	unsigned char cmd;
-	unsigned long numbytes;
-	unsigned char dir;	/* 1=out; 0=in */
-	int endpoint;
-	int numFrames;
-	unsigned char *pData;
-};
-
-#endif
diff --git a/drivers/staging/rt2860/2860_main_dev.c b/drivers/staging/rt2860/2860_main_dev.c
index c7038e0..c2f0296 100644
--- a/drivers/staging/rt2860/2860_main_dev.c
+++ b/drivers/staging/rt2860/2860_main_dev.c
@@ -99,6 +99,13 @@ static struct pci_device_id rt2860_pci_tbl[] __devinitdata =
 	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
 	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
 	{PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)},
+	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)},
     {0,}		// terminate list
 };
 
diff --git a/drivers/staging/rt2860/ap.h b/drivers/staging/rt2860/ap.h
index a814d55..fcdb358 100644
--- a/drivers/staging/rt2860/ap.h
+++ b/drivers/staging/rt2860/ap.h
@@ -40,290 +40,8 @@
 #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,
-	IN HT_CAPABILITY_IE		*pHtCapability,
-	IN UCHAR		 HtCapabilityLen,
-    OUT USHORT *pAid);
-
-// 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);
-
-// 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,
@@ -336,34 +54,8 @@ 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);
 
@@ -382,150 +74,5 @@ 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);
-
-VOID APUpdateOperationMode(
-    IN PRTMP_ADAPTER pAd);
-
-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,
-    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/rt2860/chlist.h b/drivers/staging/rt2860/chlist.h
index 1ad26b5..f49a35c 100644
--- a/drivers/staging/rt2860/chlist.h
+++ b/drivers/staging/rt2860/chlist.h
@@ -524,12 +524,7 @@ static CH_REGION ChRegion[] =
 			JAP,
 			{
 				{ 1,   14,  20, BOTH, FALSE},	// 2.4 G, ch 1~14
-#ifndef RT30xx
 				{ 36, 	4,  23, IDOR, FALSE},	// 5G, ch 36~48
-#endif
-#ifdef RT30xx
-				{ 34, 	4,  23, IDOR, FALSE},	// 5G, ch 34~46
-#endif
 				{ 0},							// end
 			}
 		},
diff --git a/drivers/staging/rt2860/common/action.c b/drivers/staging/rt2860/common/action.c
index a4d9fdc..256cb67 100644
--- a/drivers/staging/rt2860/common/action.c
+++ b/drivers/staging/rt2860/common/action.c
@@ -528,15 +528,8 @@ VOID SendRefreshBAR(
 							  sizeof(FRAME_BAR),	  &FrameBar,
 							  END_OF_ARGS);
 
-			if (1)	// Now we always send BAR.
-			{
-#ifndef RT30xx
-				MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-#endif
-#ifdef RT30xx
-				MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-#endif
-			}
+			MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+
 			MlmeFreeMemory(pAd, pOutBuffer);
 		}
 	}
diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c
index b95a341..b7bbe99 100644
--- a/drivers/staging/rt2860/common/ba_action.c
+++ b/drivers/staging/rt2860/common/ba_action.c
@@ -531,12 +531,10 @@ VOID BAOriSessionSetUp(
 	pBAEntry->TimeOutValue = TimeOut;
 	pBAEntry->pAdapter = pAd;
 
-#ifdef RT30xx
 	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));
-#endif
 
 	if (!(pEntry->TXBAbitmap & (1<<TID)))
 	{
@@ -869,6 +867,8 @@ VOID BAOriSessionTearDown(
 			// 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);
+			if (Elem == NULL)
+				return;
 
 			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 			NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
@@ -902,6 +902,8 @@ VOID BAOriSessionTearDown(
 	{
 		MLME_DELBA_REQ_STRUCT   DelbaReq;
 		MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+		if (Elem == NULL)
+			return;
 
 		NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
 		NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
@@ -1078,16 +1080,11 @@ VOID BAOriSessionSetupTimeout(
 		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);
-#ifndef RT30xx
-		DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
-#endif
-#ifdef RT30xx
 		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));
-#endif
 		pBAEntry->Token++;
 		RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
 	}
@@ -1391,10 +1388,8 @@ VOID SendPSMPAction(
 	//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)
@@ -1410,7 +1405,6 @@ VOID SendPSMPAction(
 	switch (Psmp)
 	{
 		case MMPS_ENABLE:
-#ifdef RT30xx
 			if (IS_RT3090(pAd))
 			{
 				// disable MMPS BBP control register
@@ -1423,11 +1417,9 @@ VOID SendPSMPAction(
 				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
@@ -1440,11 +1432,9 @@ VOID SendPSMPAction(
 				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
@@ -1457,7 +1447,6 @@ VOID SendPSMPAction(
 				macdata |= 0x09;	//bit 0, 3
 				RTMP_IO_WRITE32(pAd, 0x1210, macdata);
 			}
-#endif // RT30xx //
 			Frame.Psmp = 1;
 			break;
 	}
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
index 66eca20..774fabb 100644
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -252,114 +252,6 @@ NDIS_STATUS MiniportMMRequestUnlock(
 	return Status;
 }
 #endif
-#ifdef RT30xx
-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;
-}
-#endif /* RT30xx */
 
 /*
 	========================================================================
@@ -588,24 +480,6 @@ NDIS_STATUS MlmeHardTransmitTxRing(
 }
 #endif /* RT2860 */
 
-#ifdef RT30xx
-NDIS_STATUS MlmeDataHardTransmit(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR	QueIdx,
-	IN	PNDIS_PACKET	pPacket)
-{
-	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-		)
-	{
-		return NDIS_STATUS_FAILURE;
-	}
-
-#ifdef RT2870
-	return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
-#endif // RT2870 //
-}
-#endif /* RT30xx */
-
 NDIS_STATUS MlmeHardTransmitMgmtRing(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UCHAR	QueIdx,
@@ -1013,11 +887,6 @@ BOOLEAN RTMP_FillTxBlkInfo(
 	}
 
 	return TRUE;
-
-#ifdef RT30xx
-FillTxBlkErr:
-	return FALSE;
-#endif
 }
 
 
@@ -1096,10 +965,6 @@ VOID RTMPDeQueuePacket(
 	TX_BLK			TxBlk;
 	TX_BLK			*pTxBlk;
 
-#ifdef DBG_DIAGNOSE
-	BOOLEAN			firstRound;
-	RtmpDiagStruct	*pDiagStruct = &pAd->DiagStruct;
-#endif
 
 
 	if (QIdx == NUM_OF_TX_RING)
@@ -1119,9 +984,6 @@ VOID RTMPDeQueuePacket(
 
 		RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
 
-#ifdef DBG_DIAGNOSE
-		firstRound = ((QueIdx == 0) ? TRUE : FALSE);
-#endif // DBG_DIAGNOSE //
 
 		while (1)
 		{
@@ -1141,31 +1003,12 @@ VOID RTMPDeQueuePacket(
 			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;
 			}
 #ifdef RT2860
 			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
 
-#ifdef DBG_DIAGNOSE
-			if (firstRound == TRUE)
-			{
-				UCHAR	txDescNumLevel, txSwQNumLevel;
-
-				txDescNumLevel = (TX_RING_SIZE - FreeNumber[QueIdx]); // Number of occupied hw desc.
-				txDescNumLevel = ((txDescNumLevel <=15) ? txDescNumLevel : 15);
-				pDiagStruct->TxDescCnt[pDiagStruct->ArrayCurIdx][txDescNumLevel]++;
-
-				txSwQNumLevel = ((pAd->TxSwQueue[QueIdx].Number <=7) ? pAd->TxSwQueue[QueIdx].Number : 8);
-				pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][txSwQNumLevel]++;
-
-				firstRound = FALSE;
-			}
-#endif // DBG_DIAGNOSE //
 
 			if (FreeNumber[QueIdx] <= 5)
 			{
@@ -1533,13 +1376,6 @@ VOID RTMPWriteTxWI_Data(
 		}
 	}
 
-#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;
@@ -1598,13 +1434,6 @@ VOID RTMPWriteTxWI_Cache(
 		}
 	}
 
-#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;
 
@@ -2062,119 +1891,6 @@ VOID	RTMPHandleRxCoherentInterrupt(
 
 	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
 }
-
-
-VOID DBGPRINT_TX_RING(
-	IN PRTMP_ADAPTER  pAd,
-	IN UCHAR          QueIdx)
-{
-	UINT32		Ac0Base;
-	UINT32		Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
-	int			i;
-	PULONG	ptemp;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
-	switch (QueIdx)
-	{
-		case QID_AC_BE:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR0, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX0, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX0, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BE DESCRIPTOR  \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_AC_BK:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR1, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX1, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX1, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BK DESCRIPTOR  \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_BK].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_AC_VI:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR2, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX2, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX2, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VI DESCRIPTOR \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_VI].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_AC_VO:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR3, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX3, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX3, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VO DESCRIPTOR \n "  ));
-			for (i=0;i<TX_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->TxRing[QID_AC_VO].Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-		case QID_MGMT:
-			RTMP_IO_READ32(pAd, TX_BASE_PTR5, &Ac0Base);
-			RTMP_IO_READ32(pAd, TX_CTX_IDX5, &Ac0SwIdx);
-			RTMP_IO_READ32(pAd, TX_DTX_IDX5, &Ac0HwIdx);
-			DBGPRINT_RAW(RT_DEBUG_TRACE, (" All QID_MGMT  DESCRIPTOR \n "  ));
-			for (i=0;i<MGMT_RING_SIZE;i++)
-			{
-				ptemp= (PULONG)pAd->MgmtRing.Cell[i].AllocVa;
-				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-			}
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
-			break;
-
-		default:
-			DBGPRINT_ERR(("DBGPRINT_TX_RING(Ring %d) not supported\n", QueIdx));
-			break;
-	}
-	AC0freeIdx = pAd->TxRing[QueIdx].TxSwFreeIdx;
-
-	DBGPRINT(RT_DEBUG_TRACE,("TxRing%d, TX_DTX_IDX=%d, TX_CTX_IDX=%d\n", QueIdx, Ac0HwIdx, Ac0SwIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,(" 	TxSwFreeIdx[%d]", AC0freeIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,("	pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
-
-
-}
-
-
-VOID DBGPRINT_RX_RING(
-	IN PRTMP_ADAPTER  pAd)
-{
-	UINT32		Ac0Base;
-	UINT32		Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
-	int			i;
-	UINT32	*ptemp;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
-	RTMP_IO_READ32(pAd, RX_BASE_PTR, &Ac0Base);
-	RTMP_IO_READ32(pAd, RX_CRX_IDX, &Ac0SwIdx);
-	RTMP_IO_READ32(pAd, RX_DRX_IDX, &Ac0HwIdx);
-	AC0freeIdx = pAd->RxRing.RxSwReadIdx;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("All RX DSP  \n "  ));
-	for (i=0;i<RX_RING_SIZE;i++)
-	{
-		ptemp = (UINT32 *)pAd->RxRing.Cell[i].AllocVa;
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08x: %08x: %08x: %08x\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
-	}
-	DBGPRINT(RT_DEBUG_TRACE,("RxRing, RX_DRX_IDX=%d, RX_CRX_IDX=%d \n", Ac0HwIdx, Ac0SwIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,(" 	RxSwReadIdx [%d]=", AC0freeIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,("	pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
-}
 #endif /* RT2860 */
 
 /*
@@ -2235,7 +1951,6 @@ VOID RTMPResumeMsduTransmission(
 {
 	DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
 
-#ifdef RT30xx
 	// After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
 	// R66 should not be 0
 	if (pAd->BbpTuning.R66CurrentValue == 0)
@@ -2243,7 +1958,7 @@ VOID RTMPResumeMsduTransmission(
 		pAd->BbpTuning.R66CurrentValue = 0x38;
 		DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
 	}
-#endif
+
 	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
 
 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
@@ -2296,6 +2011,8 @@ UINT deaggregate_AMSDU_announce(
 		{
 		    // avoid local heap overflow, use dyanamic allocation
 		   MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+		   if (Elem == NULL)
+			return;
 		   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);
@@ -2617,11 +2334,12 @@ BOOLEAN MacTableDeleteEntry(
 	if (pAd->MacTab.Size == 0)
 	{
 		pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
-#ifndef RT30xx
+#ifdef RT2860
 		AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
-#endif
-#ifdef RT30xx
-		RT28XX_UPDATE_PROTECT(pAd);  // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+#else
+		// edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+		// Set MAC register value according operation mode
+		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
 #endif
 	}
 
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index 306c3a2..9d589c2 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -1419,17 +1419,6 @@ VOID	RTMPSetHT(
 		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
 	}
 
-#ifndef RT30xx
-#ifdef RT2870
-	/* Frank recommend ,If not, Tx maybe block in high power. Rx has no problem*/
-	if(IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
-	{
-		pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 0;
-		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
-	}
-#endif // RT2870 //
-#endif
-
 	if(pHTPhyMode->SHORTGI == GI_400)
 	{
 		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
@@ -2491,24 +2480,19 @@ INT	Set_HtAutoBa_Proc(
 	if (Value == 0)
 	{
 		pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-#ifdef RT30xx
 		pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-#endif
 	}
     else if (Value == 1)
 	{
 		pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-#ifdef RT30xx
 		pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-#endif
 	}
 	else
 		return FALSE; //Invalid argument
 
     pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
-#ifdef RT30xx
     pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
-#endif
+
 	SetCommonHT(pAd);
 
 	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
@@ -2725,9 +2709,6 @@ PCHAR   RTMPGetRalinkAuthModeStr(
 	{
 		case Ndis802_11AuthModeOpen:
 			return "OPEN";
-#if defined(RT2860) || defined(RT30xx)
-        default:
-#endif
 		case Ndis802_11AuthModeWPAPSK:
 			return "WPAPSK";
 		case Ndis802_11AuthModeShared:
@@ -2742,14 +2723,10 @@ PCHAR   RTMPGetRalinkAuthModeStr(
 			return "WPAPSKWPA2PSK";
         case Ndis802_11AuthModeWPA1WPA2:
 			return "WPA1WPA2";
-#ifndef RT30xx
 		case Ndis802_11AuthModeWPANone:
 			return "WPANONE";
-#ifdef RT2870
 		default:
 			return "UNKNOW";
-#endif
-#endif
 	}
 }
 
diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c
index 843e44e..85855f7 100644
--- a/drivers/staging/rt2860/common/cmm_sanity.c
+++ b/drivers/staging/rt2860/common/cmm_sanity.c
@@ -1052,187 +1052,3 @@ NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
 
 	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;
-
-}
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
index bda69e7..2de29fd 100644
--- a/drivers/staging/rt2860/common/cmm_wpa.c
+++ b/drivers/staging/rt2860/common/cmm_wpa.c
@@ -39,14 +39,10 @@
 // WPA OUI
 UCHAR		OUI_WPA_NONE_AKM[4]		= {0x00, 0x50, 0xF2, 0x00};
 UCHAR       OUI_WPA_VERSION[4]      = {0x00, 0x50, 0xF2, 0x01};
-#ifndef RT30xx
 UCHAR       OUI_WPA_WEP40[4]      = {0x00, 0x50, 0xF2, 0x01};
-#endif
 UCHAR       OUI_WPA_TKIP[4]     = {0x00, 0x50, 0xF2, 0x02};
 UCHAR       OUI_WPA_CCMP[4]     = {0x00, 0x50, 0xF2, 0x04};
-#ifndef RT30xx
 UCHAR       OUI_WPA_WEP104[4]      = {0x00, 0x50, 0xF2, 0x05};
-#endif
 UCHAR       OUI_WPA_8021X_AKM[4]	= {0x00, 0x50, 0xF2, 0x01};
 UCHAR       OUI_WPA_PSK_AKM[4]      = {0x00, 0x50, 0xF2, 0x02};
 // WPA2 OUI
@@ -55,9 +51,7 @@ 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};
-#ifndef RT30xx
 UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
-#endif
 // 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
@@ -376,7 +370,6 @@ static VOID RTMPInsertRsnIeCipher(
                 break;
         }
 
-#ifndef RT30xx
 		if ((pAd->OpMode == OPMODE_STA) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
@@ -392,7 +385,7 @@ static VOID RTMPInsertRsnIeCipher(
 					break;
 			}
 		}
-#endif
+
 		// swap for big-endian platform
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
 	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
@@ -453,7 +446,6 @@ static VOID RTMPInsertRsnIeCipher(
                 break;
         }
 
-#ifndef RT30xx
 		if ((pAd->OpMode == OPMODE_STA) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
 			(pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
@@ -469,7 +461,7 @@ static VOID RTMPInsertRsnIeCipher(
 					break;
 			}
 		}
-#endif
+
 		// swap for big-endian platform
 		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
 	    pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
@@ -771,70 +763,6 @@ BOOLEAN RTMPCheckWPAframe(
     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];
-    }
-}
-
-
 /*
 	========================================================================
 
@@ -906,733 +834,3 @@ VOID	AES_GTK_KEY_UNWRAP(
 
 	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;
-    }
-
-	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/rt2860/common/eeprom.c b/drivers/staging/rt2860/common/eeprom.c
index 9729323..ffcb4ce 100644
--- a/drivers/staging/rt2860/common/eeprom.c
+++ b/drivers/staging/rt2860/common/eeprom.c
@@ -73,16 +73,12 @@ USHORT ShiftInBits(
         RaiseClock(pAd, &x);
 
         RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-#ifdef RT30xx
-		LowerClock(pAd, &x); //prevent read failed
-#endif
+
+	LowerClock(pAd, &x); /* prevent read failed */
+
         x &= ~(EEDI);
         if(x & EEDO)
             data |= 1;
-
-#ifndef RT30xx
-        LowerClock(pAd, &x);
-#endif
     }
 
     return data;
@@ -185,14 +181,11 @@ USHORT RTMP_EEPROM_READ16(
     UINT32		x;
     USHORT		data;
 
-#ifdef RT30xx
+#ifdef RT2870
 	if (pAd->NicConfig2.field.AntDiversity)
     {
     	pAd->EepromAccess = TRUE;
     }
-//2008/09/11:KH add to support efuse<--
-//2008/09/11:KH add to support efuse-->
-{
 #endif
     Offset /= 2;
     // reset bits and set EECS
@@ -201,17 +194,13 @@ USHORT RTMP_EEPROM_READ16(
     x |= EECS;
     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
 
-#ifdef RT30xx
 	// patch can not access e-Fuse issue
     if (!IS_RT3090(pAd))
     {
-#endif
 	// kick a pulse
 	RaiseClock(pAd, &x);
 	LowerClock(pAd, &x);
-#ifdef RT30xx
     }
-#endif
 
     // output the read_opcode and register number in that order
     ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
@@ -222,7 +211,7 @@ USHORT RTMP_EEPROM_READ16(
 
     EEpromCleanup(pAd);
 
-#ifdef RT30xx
+#ifdef RT2870
 	// 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
@@ -231,7 +220,6 @@ USHORT RTMP_EEPROM_READ16(
 	    pAd->EepromAccess = FALSE;
 	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
     }
-}
 #endif
     return data;
 }	//ReadEEprom
@@ -243,14 +231,11 @@ VOID RTMP_EEPROM_WRITE16(
 {
     UINT32 x;
 
-#ifdef RT30xx
+#ifdef RT2870
 	if (pAd->NicConfig2.field.AntDiversity)
     {
     	pAd->EepromAccess = TRUE;
     }
-	//2008/09/11:KH add to support efuse<--
-//2008/09/11:KH add to support efuse-->
-	{
 #endif
 	Offset /= 2;
 
@@ -262,17 +247,13 @@ VOID RTMP_EEPROM_WRITE16(
     x |= EECS;
     RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
 
-#ifdef RT30xx
 	// patch can not access e-Fuse issue
     if (!IS_RT3090(pAd))
     {
-#endif
 	// kick a pulse
 	RaiseClock(pAd, &x);
 	LowerClock(pAd, &x);
-#ifdef RT30xx
     }
-#endif
 
     // output the read_opcode ,register number and data in that order
     ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
@@ -290,7 +271,7 @@ VOID RTMP_EEPROM_WRITE16(
 
     EEpromCleanup(pAd);
 
-#ifdef RT30xx
+#ifdef RT2870
 	// 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
@@ -299,12 +280,10 @@ VOID RTMP_EEPROM_WRITE16(
 	    pAd->EepromAccess = FALSE;
 	    AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
     }
-}
 #endif
 }
 
-//2008/09/11:KH add to support efuse<--
-#ifdef RT30xx
+#ifdef RT2870
 /*
 	========================================================================
 
@@ -1038,7 +1017,7 @@ INT	set_eFuseLoadFromBin_Proc(
 {
 	CHAR					*src;
 	struct file				*srcf;
-	INT 					retval, orgfsuid, orgfsgid;
+	INT 					retval;
    	mm_segment_t			orgfs;
 	UCHAR					*buffer;
 	UCHAR					BinFileSize=0;
@@ -1078,12 +1057,7 @@ INT	set_eFuseLoadFromBin_Proc(
 		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);
 
@@ -1146,10 +1120,7 @@ INT	set_eFuseLoadFromBin_Proc(
 		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]));
@@ -1505,6 +1476,4 @@ NTSTATUS eFuseWriteRegistersFromBin(
 
 	return TRUE;
 }
-
-#endif // RT30xx //
-//2008/09/11:KH add to support efuse-->
+#endif
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
index bb6fccb..61a2a4e 100644
--- a/drivers/staging/rt2860/common/mlme.c
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -43,7 +43,6 @@ 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};
@@ -338,9 +337,6 @@ UCHAR  WpaIe	 = IE_WPA;
 UCHAR  Wpa2Ie	 = IE_WPA2;
 UCHAR  IbssIe	 = IE_IBSS_PARM;
 UCHAR  Ccx2Ie	 = IE_CCX_V2;
-#ifdef RT2870
-UCHAR  WapiIe	 = IE_WAPI;
-#endif
 
 extern UCHAR	WPA_OUI[];
 
@@ -449,13 +445,7 @@ FREQUENCY_ITEM FreqItems3020[] =
 	{13,   247,	 2,  2},
 	{14,   248,	 2,  4},
 };
-#ifndef RT30xx
-#define	NUM_OF_3020_CHNL	(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
-#endif
-#ifdef RT30xx
-//2008/07/10:KH Modified to share this variable
 UCHAR	NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
-#endif
 
 /*
 	==========================================================================
@@ -1576,12 +1566,7 @@ VOID MlmeSelectTxRateTable(
 		}
 
 		//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)
-#ifndef RT30xx
-//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
-			)
+		if (pEntry->RateLen == 4)
 		{// B only AP
 			*ppTable = RateSwitchTable11B;
 			*pTableSize = RateSwitchTable11B[0];
@@ -2777,43 +2762,16 @@ VOID MlmeCheckPsmChange(
 		(pAd->StaCfg.Psm == PWR_ACTIVE) &&
 #ifdef RT2860
 		RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
-#endif
-#if !defined(RT2860) && !defined(RT30xx)
+#else
 		(pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
 #endif
-#ifndef RT30xx
-	{
-		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);
-		}
-	}
-#endif
-#ifdef RT30xx
-//		(! 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
@@ -2830,7 +2788,6 @@ VOID MlmeCheckPsmChange(
 			}
 		}
 	}
-#endif
 }
 
 // IRQL = PASSIVE_LEVEL
@@ -2845,9 +2802,8 @@ VOID MlmeSetPsmBit(
 	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);
-#ifndef RT30xx
+
 	DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
-#endif
 }
 
 // IRQL = DISPATCH_LEVEL
@@ -3877,18 +3833,14 @@ ULONG BssTableSetEntry(
 	}
 	else
 	{
-#ifdef RT30xx
 		/* 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)))
 		{
-#endif
 		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);
-#ifdef RT30xx
 		}
-#endif
 	}
 
 	return Idx;
@@ -3949,14 +3901,9 @@ VOID BssTableSsidSort(
 							continue;
 
 					// check group cipher
-#ifndef RT30xx
-					if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
-						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
-						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
-#endif
-#ifdef RT30xx
-					if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
-#endif
+					if (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled &&
+					    pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled &&
+					    pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
 						continue;
 
 					// check pairwise cipher, skip if none matched
@@ -3975,14 +3922,9 @@ VOID BssTableSsidSort(
 							continue;
 
 					// check group cipher
-#ifndef RT30xx
-					if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
-						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
-						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
-#endif
-#ifdef RT30xx
-					if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
-#endif
+					if (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled &&
+					    pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled &&
+					    pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
 						continue;
 
 					// check pairwise cipher, skip if none matched
@@ -4260,16 +4202,10 @@ VOID BssCipherParse(
 				switch (*pTmp)
 				{
 					case 1:
-#ifndef RT30xx
 						pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
 						break;
 					case 5:
 						pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
-#endif
-#ifdef RT30xx
-					case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
-						pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
-#endif
 						break;
 					case 2:
 						pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -4385,16 +4321,10 @@ VOID BssCipherParse(
 				switch (pCipher->Type)
 				{
 					case 1:
-#ifndef RT30xx
 						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
 						break;
 					case 5:
 						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
-#endif
-#ifdef RT30xx
-					case 5:	// Although WEP is not allowed in WPA related auth mode, we parse it anyway
-						pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
-#endif
 						break;
 					case 2:
 						pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -5635,119 +5565,7 @@ VOID 	AsicUpdateProtect(
 	}
 }
 
-#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
+#ifdef RT2870
 /*
 	==========================================================================
 	Description:
@@ -5902,8 +5720,7 @@ VOID RT30xxReverseRFSleepModeSetup(
 		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
 	}
 }
-// end johnli
-#endif // RT30xx //
+#endif
 
 /*
 	==========================================================================
@@ -5926,7 +5743,6 @@ VOID AsicSwitchChannel(
 	RTMP_RF_REGS *RFRegTable;
 
 	// Search Tx power value
-#ifdef RT30xx
 	// We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
 	// in ChannelList, so use TxPower array instead.
 	//
@@ -5939,38 +5755,15 @@ VOID AsicSwitchChannel(
 			break;
 		}
 	}
-#endif
-#ifndef RT30xx
-	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)
-	{
-#ifndef RT30xx
-		DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel));
-#endif
-#ifdef RT30xx
 		DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
-#endif
-	}
 
 #ifdef RT2870
 	// The RF programming sequence is difference between 3xxx and 2xxx
-#ifdef RT30xx
-	if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
-		(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
-#endif
-#ifndef RT30xx
-	if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
-#endif
+	if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && (
+	     (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3021) ||
+	     (pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
 	{
 		/* modify by WY for Read RF Reg. error */
 		UCHAR RFValue;
@@ -5983,22 +5776,6 @@ VOID AsicSwitchChannel(
 				RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
 				RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
 
-#ifndef RT30xx
-				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);
-				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
-				RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
-#endif
-#ifdef RT30xx
 				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
 				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
 				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
@@ -6032,7 +5809,6 @@ VOID AsicSwitchChannel(
 				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
 				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
 				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
-#endif
 
 				// Set BW
 				if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
@@ -6044,18 +5820,6 @@ VOID AsicSwitchChannel(
 				{
 					RFValue = pAd->Mlme.CaliBW20RfR24;
 				}
-#ifndef RT30xx
-				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;
-#endif
-#ifdef RT30xx
 				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
 				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
 
@@ -6076,13 +5840,10 @@ VOID AsicSwitchChannel(
 					FreqItems3020[index].N,
 					FreqItems3020[index].K,
 					FreqItems3020[index].R));
-#endif
-
 				break;
 			}
 		}
 
-#ifndef RT30xx
 		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,
@@ -6092,7 +5853,6 @@ VOID AsicSwitchChannel(
 			FreqItems3020[index].N,
 			FreqItems3020[index].K,
 			FreqItems3020[index].R));
-#endif
 	}
 	else
 #endif // RT2870 //
@@ -6336,98 +6096,6 @@ VOID AsicLockChannel(
 {
 }
 
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-VOID	AsicAntennaSelect(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UCHAR			Channel)
-{
-#ifdef RT30xx
-			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
-					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;
-					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);
-				}
-			}
-#endif /* RT30xx */
-}
-
-/*
-	========================================================================
-
-	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,
@@ -7150,13 +6818,13 @@ VOID AsicSetEdcaParm(
 				Ac2Cfg.field.AcTxop = 5;
 			}
 
-#ifdef RT30xx
+#ifdef RT2870
 			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
 		}
 
 		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
@@ -7237,11 +6905,10 @@ VOID AsicSetEdcaParm(
 		}
 
 		AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
-#ifdef RT30xx
+#ifdef RT2870
 		if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
 			AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
-#endif // RT30xx //
-
+#endif
 		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
 
 		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
@@ -7303,7 +6970,6 @@ VOID 	AsicSetSlotTime(
 	SlotTime = (bUseShortSlotTime)? 9 : 20;
 
 	{
-#ifndef RT30xx
 		// force using short SLOT time for FAE to demo performance when TxBurst is ON
 		if (((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))
@@ -7313,10 +6979,6 @@ VOID 	AsicSetSlotTime(
 			// And we will not set to short slot when bEnableTxBurst is TRUE.
 		}
 		else if (pAd->CommonCfg.bEnableTxBurst)
-#endif
-#ifdef RT30xx
-		if (pAd->CommonCfg.bEnableTxBurst)
-#endif
 			SlotTime = 9;
 	}
 
@@ -8331,7 +7993,7 @@ CHAR RTMPMaxRssi(
 	return larger;
 }
 
-#ifdef RT30xx
+#ifdef RT2870
 // 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
@@ -8340,7 +8002,6 @@ VOID AsicSetRxAnt(
 	IN PRTMP_ADAPTER	pAd,
 	IN UCHAR			Ant)
 {
-#ifdef RT30xx
 	UINT32	Value;
 	UINT32	x;
 
@@ -8379,9 +8040,8 @@ VOID AsicSetRxAnt(
 		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
 		DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
 	}
-#endif // RT30xx //
 }
-#endif /* RT30xx */
+#endif
 
 /*
     ========================================================================
@@ -8401,78 +8061,19 @@ VOID AsicEvaluateRxAnt(
 {
 	UCHAR	BBPR3 = 0;
 
-#ifndef RT30xx
-	{
-		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))
-			return;
-
-		if (pAd->StaCfg.Psm == PWR_SAVE)
-			return;
-	}
-
-	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 RT2860
-    	pAd->StaCfg.BBPR3 = BBPR3;
-#endif
+	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 RT2870
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-		)
-	{
-		ULONG	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-								pAd->RalinkCounters.OneSecTxRetryOkCount +
-								pAd->RalinkCounters.OneSecTxFailCount;
-
-		if (TxTotalCnt > 50)
-		{
-			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
-			pAd->Mlme.bLowThroughput = FALSE;
-		}
-		else
-		{
-			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
-			pAd->Mlme.bLowThroughput = TRUE;
-		}
-	}
+				|| (pAd->EepromAccess)
 #endif
-#endif /* RT30xx */
-#ifdef RT30xx
-	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;
-
-
-	{
-		//if (pAd->StaCfg.Psm == PWR_SAVE)
-		//	return;
-	}
+				)
+			return;
 
+#ifdef RT30xx
 	// 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
@@ -8495,6 +8096,7 @@ VOID AsicEvaluateRxAnt(
 			RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
 	}
 	else
+#endif
 	{
 		if (pAd->StaCfg.Psm == PWR_SAVE)
 			return;
@@ -8514,8 +8116,11 @@ VOID AsicEvaluateRxAnt(
 			BBPR3 |= (0x0);
 		}
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+
+#ifdef RT2860
+		pAd->StaCfg.BBPR3 = BBPR3;
+#endif
 	}
-#endif /* RT30xx */
 
 	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
 		)
@@ -8561,85 +8166,19 @@ VOID AsicRxAntEvalTimeout(
 	UCHAR			BBPR3 = 0;
 	CHAR			larger = -127, rssi0, rssi1, rssi2;
 
-#ifndef RT30xx
-	{
-		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)			||
-			RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-			return;
-
-		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);
-#ifdef RT2860
-		pAd->StaCfg.BBPR3 = BBPR3;
-#endif
-	}
-#endif /* RT30xx */
-#ifdef RT30xx
 	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
+							fRTMP_ADAPTER_NIC_NOT_EXIST)
+							|| OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT2870
 							|| (pAd->EepromAccess)
-#endif // RT30xx //
+#endif
 							)
 		return;
 
 	{
-		//if (pAd->StaCfg.Psm == PWR_SAVE)
-		//	return;
-
+#ifdef RT30xx
 		if (pAd->NicConfig2.field.AntDiversity)
 		{
 			if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
@@ -8671,6 +8210,7 @@ VOID AsicRxAntEvalTimeout(
 					pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
 		}
 		else
+#endif
 		{
 			if (pAd->StaCfg.Psm == PWR_SAVE)
 				return;
@@ -8721,13 +8261,13 @@ VOID AsicRxAntEvalTimeout(
 				BBPR3 |= (0x0);
 			}
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+#ifdef RT2860
+			pAd->StaCfg.BBPR3 = BBPR3;
+#endif
 		}
 	}
-#endif /* RT30xx */
 }
 
-
-
 VOID APSDPeriodicExec(
 	IN PVOID SystemSpecific1,
 	IN PVOID FunctionContext,
@@ -8942,38 +8482,19 @@ VOID AsicStaBbpTuning(
 #ifdef RT2870
 			// 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
-#ifndef RT30xx
-			if (IS_RT3070(pAd))
-#endif
-#ifdef RT30xx
 			if (IS_RT30xx(pAd))
-#endif
 			{
 				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
 				{
 					R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
 					if (OrigR66Value != R66)
-					{
-#ifndef RT30xx
-						RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
-#endif
-#ifdef RT30xx
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-#endif
-					}
 				}
 				else
 				{
 					R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
 					if (OrigR66Value != R66)
-					{
-#ifndef RT30xx
-						RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
-#endif
-#ifdef RT30xx
 						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-#endif
-					}
 				}
 			}
 			else
@@ -9182,15 +8703,13 @@ VOID AsicTurnOffRFClk(
 	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
+		return;
 	}
-	else
-	{
-#endif // RT30xx //
+
 	RFRegTable = RF2850RegTable;
 
 	switch (pAd->RfIcType)
@@ -9232,10 +8751,6 @@ VOID AsicTurnOffRFClk(
 		default:
 			break;
 	}
-#ifdef RT30xx
-	}
-#endif // RT30xx //
-
 }
 
 
@@ -9249,14 +8764,10 @@ VOID AsicTurnOnRFClk(
 	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 //
+		return;
+
 	RFRegTable = RF2850RegTable;
 
 	switch (pAd->RfIcType)
@@ -9303,14 +8814,9 @@ VOID AsicTurnOnRFClk(
 			break;
 	}
 
-#ifndef RT30xx
 	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
 		Channel,
 		pAd->RfIcType,
 		R2));
-#endif
-#ifdef RT30xx
-	}
-#endif // RT30xx //
 }
 
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
index 004f530..20c2ce2 100644
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -38,16 +38,12 @@
     Jan Lee  2006-09-15    RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
 */
 #include "../rt_config.h"
-#ifndef RT30xx
 #ifdef RT2860
 #include "firmware.h"
 #include <linux/bitrev.h>
 #endif
 #ifdef RT2870
-#include "../../rt2870/common/firmware.h"
-#endif
-#endif
-#ifdef RT30xx
+/* New firmware handles both RT2870 and RT3070. */
 #include "../../rt3070/firmware.h"
 #endif
 
@@ -63,59 +59,6 @@ ULONG    BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
 
 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])
-
-#ifdef RT2870
-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;
-}
-#endif
-
 //
 // BBP register initialization set
 //
@@ -147,12 +90,7 @@ REG_PAIR   RT30xx_RFRegTable[] = {
         {RF_R06,          0x02},
         {RF_R07,          0x70},
         {RF_R09,          0x0F},
-#ifndef RT30xx
-        {RF_R10,          0x71},
-#endif
-#ifdef RT30xx
         {RF_R10,          0x41},
-#endif
         {RF_R11,          0x21},
         {RF_R12,          0x7B},
         {RF_R14,          0x90},
@@ -165,9 +103,6 @@ REG_PAIR   RT30xx_RFRegTable[] = {
         {RF_R21,          0xDB},
         {RF_R24,          0x16},
         {RF_R25,          0x01},
-#ifndef RT30xx
-        {RF_R27,          0x03},
-#endif
         {RF_R29,          0x1F},
 };
 #define	NUM_RF_REG_PARMS	(sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
@@ -1099,145 +1034,6 @@ NDIS_STATUS	NICReadRegParameters(
 
 	========================================================================
 */
-#ifndef RT30xx
-VOID RTUSBFilterCalibration(
-	IN PRTMP_ADAPTER pAd)
-{
-	UCHAR	R55x = 0, value, FilterTarget = 0x1E, BBPValue;
-	UINT	loop = 0, count = 0, loopcnt = 0, ReTry = 0;
-	UCHAR	RF_R24_Value = 0;
-
-	// Give bbp filter initial value
-	pAd->Mlme.CaliBW20RfR24 = 0x16;
-	pAd->Mlme.CaliBW40RfR24 = 0x36;  //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);
-			FilterTarget = 0x19;
-
-			// when calibrate BW40, BBP mask must set to BW40.
-			RTUSBReadBBPRegister(pAd, BBP_R4, &BBPValue);
-			BBPValue&= (~0x18);
-			BBPValue|= (0x10);
-			RTUSBWriteBBPRegister(pAd, BBP_R4, BBPValue);
-		}
-		else			//BandWidth = 20 MHz
-		{
-			// Write 0x07 to RF_R24 to program filter
-			RF_R24_Value = 0x07;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			FilterTarget = 0x16;
-		}
-
-		// 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
-		RTUSBWriteBBPRegister(pAd, BBP_R24, 0);
-
-		do
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTUSBWriteBBPRegister(pAd, BBP_R25, 0x90);
-
-			RTMPusecDelay(1000);
-			// Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
-			RTUSBReadBBPRegister(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
-		RTUSBWriteBBPRegister(pAd, BBP_R24, 0x06);
-
-		while(TRUE)
-		{
-			// Write 0x90 to BBP_R25 to transmit test tone
-			RTUSBWriteBBPRegister(pAd, BBP_R25, 0x90);
-
-			//We need to wait for calibration
-			RTMPusecDelay(1000);
-			RTUSBReadBBPRegister(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, ("RTUSBFilterCalibration - 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
-	//
-	RTUSBWriteBBPRegister(pAd, BBP_R24, 0);
-
-	RT30xxReadRFRegister(pAd, RF_R22, &value);
-	value &= ~(0x01);
-	RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-	// set BBP back to BW20
-	RTUSBReadBBPRegister(pAd, BBP_R4, &BBPValue);
-	BBPValue&= (~0x18);
-	RTUSBWriteBBPRegister(pAd, BBP_R4, BBPValue);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTUSBFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
-}
-#endif /* RT30xx */
-#ifdef RT30xx
 VOID RTMPFilterCalibration(
 	IN PRTMP_ADAPTER pAd)
 {
@@ -1246,9 +1042,13 @@ VOID RTMPFilterCalibration(
 	UCHAR	RF_R24_Value = 0;
 
 	// Give bbp filter initial value
+#ifndef RT2870
+	pAd->Mlme.CaliBW20RfR24 = 0x16;
+	pAd->Mlme.CaliBW40RfR24 = 0x36;  //Bit[5] must be 1 for BW 40
+#else
 	pAd->Mlme.CaliBW20RfR24 = 0x1F;
 	pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
-
+#endif
 	do
 	{
 		if (loop == 1)	//BandWidth = 40 MHz
@@ -1266,11 +1066,12 @@ VOID RTMPFilterCalibration(
 			BBPValue&= (~0x18);
 			BBPValue|= (0x10);
 			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
+#ifdef RT2870
 			// set to BW40
 			RT30xxReadRFRegister(pAd, RF_R31, &value);
 			value |= 0x20;
 			RT30xxWriteRFRegister(pAd, RF_R31, value);
+#endif
 		}
 		else			//BandWidth = 20 MHz
 		{
@@ -1281,11 +1082,12 @@ VOID RTMPFilterCalibration(
 				FilterTarget = 0x13;
 			else
 				FilterTarget = 0x16;
-
+#ifdef RT2870
 			// set to BW20
 			RT30xxReadRFRegister(pAd, RF_R31, &value);
 			value &= (~0x20);
 			RT30xxWriteRFRegister(pAd, RF_R31, value);
+#endif
 		}
 
 		// Write 0x01 to RF_R22 to enable baseband loopback mode
@@ -1390,37 +1192,12 @@ VOID RTMPFilterCalibration(
 
 	DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
 }
-#endif /* RT30xx */
 
 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
-#ifndef RT30xx
-        if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) ||(pAd->RfIcType == RFIC_2020)))
-        {
-                // Init RF calibration
-                // Driver should toggle RF R30 bit7 before init RF registers
-                ULONG RfReg = 0;
-                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);
-                }
-
-                //For RF filter Calibration
-                RTUSBFilterCalibration(pAd);
-        }
-#endif
-#ifdef RT30xx
 	if (IS_RT3070(pAd) || IS_RT3071(pAd))
 	{
 		// Init RF calibration
@@ -1441,7 +1218,6 @@ VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
 			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
@@ -1498,7 +1274,6 @@ VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
 			RT30xxLoadRFNormalModeSetup(pAd);
 		}
 	}
-#endif
 }
 #endif // RT2870 //
 
@@ -1675,7 +1450,6 @@ VOID	NICReadEEPROMParameters(
 	Antenna.word = pAd->EEPROMDefaultValue[0];
 	if (Antenna.word == 0xFFFF)
 	{
-#ifdef RT30xx
 		if(IS_RT3090(pAd))
 		{
 			Antenna.word = 0;
@@ -1685,15 +1459,12 @@ VOID	NICReadEEPROMParameters(
 		}
 		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.
@@ -1722,9 +1493,6 @@ VOID	NICReadEEPROMParameters(
 	NicConfig2.word = pAd->EEPROMDefaultValue[1];
 
 	{
-#ifndef RT30xx
-		NicConfig2.word = 0;
-#endif
 		if ((NicConfig2.word & 0x00ff) == 0xff)
 		{
 			NicConfig2.word &= 0xff00;
@@ -1917,14 +1685,6 @@ VOID	NICReadEEPROMParameters(
 
 	RTMPReadTxPwrPerRate(pAd);
 
-#ifdef RT30xx
-	if (IS_RT30xx(pAd))
-	{
-		eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
-		pAd->EFuseTag = (value & 0xff);
-	}
-#endif // RT30xx //
-
 	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
 }
 
@@ -1969,10 +1729,9 @@ VOID	NICInitAsicFromEEPROM(
 		}
 	}
 
-#ifndef RT30xx
+#ifndef RT2870
 	Antenna.word = pAd->Antenna.word;
-#endif
-#ifdef RT30xx
+#else
 	Antenna.word = pAd->EEPROMDefaultValue[0];
 	if (Antenna.word == 0xFFFF)
 	{
@@ -1983,7 +1742,7 @@ VOID	NICInitAsicFromEEPROM(
 	pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
 	pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
 
-#ifdef RT30xx
+#ifdef RT2870
 	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
@@ -1991,7 +1750,7 @@ VOID	NICInitAsicFromEEPROM(
 #endif
 	NicConfig2.word = pAd->EEPROMDefaultValue[1];
 
-#ifdef RT30xx
+#ifdef RT2870
 	{
 		if ((NicConfig2.word & 0x00ff) == 0xff)
 		{
@@ -2007,7 +1766,7 @@ VOID	NICInitAsicFromEEPROM(
 	// Save the antenna for future use
 	pAd->NicConfig2.word = NicConfig2.word;
 
-#ifdef RT30xx
+#ifdef RT2870
 	// set default antenna as main
 	if (pAd->RfIcType == RFIC_3020)
 		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
@@ -2078,10 +1837,8 @@ VOID	NICInitAsicFromEEPROM(
 		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!!
-	//
+
+	/* BBP has been programmed so reset to UNKNOWN_BAND */
 	pAd->CommonCfg.BandState = UNKNOWN_BAND;
 
 	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
@@ -2351,10 +2108,8 @@ NDIS_STATUS	NICInitializeAsic(
 	UINT32			MacCsr0 = 0;
 	NTSTATUS		Status;
 	UCHAR			Value = 0xff;
-#endif // RT2870 //
-#ifdef RT30xx
 	UINT32			eFuseCtrl;
-#endif // RT30xx //
+#endif
 	USHORT			KeyIdx;
 	INT				i,apidx;
 
@@ -2418,21 +2173,8 @@ NDIS_STATUS	NICInitializeAsic(
 #endif // RT3070 //
 		RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
 	}
-
-#ifndef RT30xx
-	if(IS_RT3070(pAd))
-	{
-		// According to Frank Hsu (from Gary Tsao)
-		RTMP_IO_WRITE32(pAd, (USHORT)TX_SW_CFG0, 0x00000400);
-
-		// Initialize RT3070 serial MAC registers which is different from RT2870 serial
-		RTUSBWriteMACRegister(pAd, TX_SW_CFG1, 0);
-		RTUSBWriteMACRegister(pAd, TX_SW_CFG2, 0);
-	}
-#endif
 #endif // RT2870 //
 
-
 	{
 		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
 		{
@@ -2445,7 +2187,6 @@ NDIS_STATUS	NICInitializeAsic(
 		}
 	}
 
-#ifdef RT30xx
 	// Initialize RT3070 serial MAc registers which is different from RT2870 serial
 	if (IS_RT3090(pAd))
 	{
@@ -2468,6 +2209,7 @@ NDIS_STATUS	NICInitializeAsic(
 			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
 		}
 	}
+#ifdef RT2870
 	else if (IS_RT3070(pAd))
 	{
 		RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
@@ -2514,22 +2256,11 @@ NDIS_STATUS	NICInitializeAsic(
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
 	}
 
-#ifndef RT30xx
+#ifndef RT2870
 	// for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
 	if ((pAd->MACVersion&0xffff) != 0x0101)
 		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
-
-#ifdef RT2870
-	//write RT3070 BBP wchich different with 2870 after write RT2870 BBP
-	if (IS_RT3070(pAd))
-	{
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0a);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x99);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, 0x05);
-	}
-#endif // RT2870 //
-#endif
-#ifdef RT30xx
+#else
 	// 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)))
@@ -2666,8 +2397,7 @@ NDIS_STATUS	NICInitializeAsic(
 	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;
@@ -2678,9 +2408,8 @@ NDIS_STATUS	NICInitializeAsic(
 	else
 	{
 			DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
-
 	}
-#endif // RT30xx //
+#endif
 
 	{
 		// for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
@@ -3160,73 +2889,6 @@ VOID NICUpdateRawCounters(
 		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 < 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 //
 
 
 }
@@ -3652,7 +3314,7 @@ VOID	UserCfgInit(
 		}
 	}
 
-#ifdef RT30xx
+#ifdef RT2870
 	pAd->EepromAccess = FALSE;
 #endif
 	pAd->Antenna.word = 0;
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
index 101c292..c658bf3 100644
--- a/drivers/staging/rt2860/common/spectrum.c
+++ b/drivers/staging/rt2860/common/spectrum.c
@@ -1570,12 +1570,7 @@ static VOID PeerMeasureReportAction(
 
 	if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
 	{
-#ifndef RT30xx
 		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
-#endif
-#ifdef RT30xx
-		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
-#endif
 		return;
 	}
 
diff --git a/drivers/staging/rt2860/dfs.h b/drivers/staging/rt2860/dfs.h
index 752a635..f34f618 100644
--- a/drivers/staging/rt2860/dfs.h
+++ b/drivers/staging/rt2860/dfs.h
@@ -77,18 +77,6 @@ ULONG RTMPReadRadarDuration(
 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);
diff --git a/drivers/staging/rt2860/link_list.h b/drivers/staging/rt2860/link_list.h
deleted file mode 100644
index f652113..0000000
--- a/drivers/staging/rt2860/link_list.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *************************************************************************
- * 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/rt2860/md4.h b/drivers/staging/rt2860/md4.h
deleted file mode 100644
index f1e5b52..0000000
--- a/drivers/staging/rt2860/md4.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *************************************************************************
- * 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/rt2860/oid.h b/drivers/staging/rt2860/oid.h
index 8519afc..0227c4a 100644
--- a/drivers/staging/rt2860/oid.h
+++ b/drivers/staging/rt2860/oid.h
@@ -92,136 +92,31 @@
 //
 #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 OID_802_11_ADD_WEP			0x0112
+#define OID_802_11_DISASSOCIATE			0x0114
+#define OID_802_11_BSSID_LIST_SCAN		0x0508
+#define OID_802_11_SSID				0x0509
+#define OID_802_11_BSSID			0x050A
+#define OID_802_11_MIC_FAILURE_REPORT_FRAME	0x0528
 
 #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
 
 #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,
@@ -535,10 +430,8 @@ typedef enum _NDIS_802_11_WEP_STATUS
     Ndis802_11Encryption3KeyAbsent,
     Ndis802_11Encryption4Enabled,	// TKIP or AES mix
     Ndis802_11Encryption4KeyAbsent,
-#ifndef RT30xx
     Ndis802_11GroupWEP40Enabled,
 	Ndis802_11GroupWEP104Enabled,
-#endif
 } NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
   NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
 
@@ -626,27 +519,9 @@ typedef struct _NDIS_802_11_CAPABILITY
      NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
 } NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
 
-#if WIRELESS_EXT <= 11
-#ifndef SIOCDEVPRIVATE
-#define SIOCDEVPRIVATE                              0x8BE0
-#endif
-#define SIOCIWFIRSTPRIV								SIOCDEVPRIVATE
-#endif
-
-#ifdef RT30xx
 #define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
-#endif
 #define RTPRIV_IOCTL_SET							(SIOCIWFIRSTPRIV + 0x02)
 
-#ifdef DBG
-#define RTPRIV_IOCTL_BBP                            (SIOCIWFIRSTPRIV + 0x03)
-#define RTPRIV_IOCTL_MAC                            (SIOCIWFIRSTPRIV + 0x05)
-#ifdef RT30xx
-#define RTPRIV_IOCTL_RF                             (SIOCIWFIRSTPRIV + 0x13)
-#endif
-#define RTPRIV_IOCTL_E2P                            (SIOCIWFIRSTPRIV + 0x07)
-#endif
-
 #define RTPRIV_IOCTL_STATISTICS                     (SIOCIWFIRSTPRIV + 0x09)
 #define RTPRIV_IOCTL_ADD_PMKID_CACHE                (SIOCIWFIRSTPRIV + 0x0A)
 #define RTPRIV_IOCTL_RADIUS_DATA                    (SIOCIWFIRSTPRIV + 0x0C)
@@ -667,42 +542,11 @@ enum {
     RAIO_OFF = 10,
     RAIO_ON = 11,
 	SHOW_CFG_VALUE = 20,
-#if !defined(RT2860) && !defined(RT30xx)
+#if !defined(RT2860)
 	SHOW_ADHOC_ENTRY_INFO = 21,
 #endif
 };
 
-#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
-
-#ifdef RT30xx
-#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
-
-#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
-#endif
-
 #ifdef LLTD_SUPPORT
 // for consistency with RT61
 #define RT_OID_GET_PHY_MODE                         0x761
diff --git a/drivers/staging/rt2860/rt2860.h b/drivers/staging/rt2860/rt2860.h
index 4fbec90..ed28fe5 100644
--- a/drivers/staging/rt2860/rt2860.h
+++ b/drivers/staging/rt2860/rt2860.h
@@ -292,6 +292,8 @@ rt2860_interrupt(int irq, void *dev_instance);
 #define VEN_AWT_PCIe_DEVICE_ID	0x1059
 #define VEN_AWT_PCI_VENDOR_ID	0x1A3B
 
+#define EDIMAX_PCI_VENDOR_ID	0x1432
+
 // For RTMPPCIePowerLinkCtrlRestore () function
 #define RESTORE_HALT		    1
 #define RESTORE_WAKEUP		    2
diff --git a/drivers/staging/rt2860/rt28xx.h b/drivers/staging/rt2860/rt28xx.h
index 6e71acb..c085250 100644
--- a/drivers/staging/rt2860/rt28xx.h
+++ b/drivers/staging/rt2860/rt28xx.h
@@ -47,14 +47,9 @@
 #define PCI_EECTRL			0x0004
 #define PCI_MCUCTRL			0x0008
 
-#ifdef RT30xx
-#define	OPT_14			0x114
+typedef int NTSTATUS;
 
-typedef int				NTSTATUS;
-#define	RETRY_LIMIT             10
-#define STATUS_SUCCESS				0x00
-#define STATUS_UNSUCCESSFUL 		0x01
-#endif
+#define	OPT_14			0x114
 
 //
 // SCH/DMA registers - base address 0x0200
@@ -291,7 +286,6 @@ typedef	union	_USB_DMA_CFG_STRUC	{
 #define 	PBF_DBG 	 	 0x043c
 #define     PBF_CAP_CTRL     0x0440
 
-#ifdef RT30xx
 // eFuse registers
 #define EFUSE_CTRL              0x0580
 #define EFUSE_DATA0             0x0590
@@ -319,7 +313,6 @@ typedef	union	_EFUSE_CTRL_STRUC {
 
 #define LDO_CFG0 				0x05d4
 #define GPIO_SWITCH				0x05dc
-#endif /* RT30xx */
 
 //
 //  4  MAC  registers
@@ -1136,9 +1129,7 @@ typedef struct _HW_WCID_ENTRY {  // 8-byte per entry
 #define BBP_R22                     22
 #define BBP_R24                     24
 #define BBP_R25                     25
-#ifdef RT30xx
 #define BBP_R31                     31
-#endif
 #define BBP_R49                     49 //TSSI
 #define BBP_R50                     50
 #define BBP_R51                     51
@@ -1156,10 +1147,8 @@ typedef struct _HW_WCID_ENTRY {  // 8-byte per entry
 #define BBP_R73                     73
 #define BBP_R75						75
 #define BBP_R77                     77
-#ifdef RT30xx
 #define BBP_R79                     79
 #define BBP_R80                     80
-#endif
 #define BBP_R81                     81
 #define BBP_R82                     82
 #define BBP_R83                     83
@@ -1181,9 +1170,7 @@ typedef struct _HW_WCID_ENTRY {  // 8-byte per entry
 #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
@@ -1607,15 +1594,10 @@ typedef	union _EEPROM_NIC_CINFIG2_STRUC	{
 		USHORT		EnableWPSPBC:1;                 // WPS PBC Control bit
 		USHORT		BW40MAvailForG:1;			// 0:enable, 1:disable
 		USHORT		BW40MAvailForA:1;			// 0:enable, 1:disable
-#ifndef RT30xx
-		USHORT		Rsv2:6;                 // must be 0
-#endif
-#ifdef RT30xx
 		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
-#endif
 	}	field;
 	USHORT			word;
 }	EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
diff --git a/drivers/staging/rt2860/rt_config.h b/drivers/staging/rt2860/rt_config.h
index a19cbe1..2093a80 100644
--- a/drivers/staging/rt2860/rt_config.h
+++ b/drivers/staging/rt2860/rt_config.h
@@ -68,9 +68,5 @@
 #include "igmp_snoop.h"
 #endif // IGMP_SNOOP_SUPPORT //
 
-#ifdef IKANOS_VX_1X0
-#include	"vr_ikans.h"
-#endif // IKANOS_VX_1X0 //
-
 #endif	// __RT_CONFIG_H__
 
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index 80176b2..b396a9b 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -537,9 +537,9 @@ PNDIS_PACKET duplicate_pkt(
 	if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
 	{
 		skb_reserve(skb, 2);
-		NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
+		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
 		skb_put(skb, HdrLen);
-		NdisMoveMemory(skb->tail, pData, DataSize);
+		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
 		skb_put(skb, DataSize);
 		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
 		pPacket = OSPKT_TO_RTPKT(skb);
@@ -662,13 +662,9 @@ void announce_802_3_packet(
 	pRxPkt = RTPKT_TO_OSPKT(pPacket);
 
     /* 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);
 
 	netif_rx(pRxPkt);
-#endif // IKANOS_VX_1X0 //
 }
 
 
@@ -728,7 +724,6 @@ VOID RTMPSendWirelessEvent(
 	IN	UCHAR			BssIdx,
 	IN	CHAR			Rssi)
 {
-#if WIRELESS_EXT >= 15
 
 	union 	iwreq_data      wrqu;
 	PUCHAR 	pBuf = NULL, pBufPtr = NULL;
@@ -776,7 +771,7 @@ VOID RTMPSendWirelessEvent(
 		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);
+			pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
 		else
 			pBufPtr += sprintf(pBufPtr, "(RT2860) ");
 
@@ -805,9 +800,6 @@ VOID RTMPSendWirelessEvent(
 	}
 	else
 		DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
-#else
-	DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
-#endif  /* WIRELESS_EXT >= 15 */
 }
 
 void send_monitor_packets(
@@ -834,12 +826,7 @@ void send_monitor_packets(
 
     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
     {
-#ifndef RT30xx
         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
-#endif
-#ifdef RT30xx
-        DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
-#endif
 		goto err_free_sk_buff;
     }
 
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index 25b53ac..e8d64c3 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -63,10 +63,6 @@
 #include <linux/ctype.h>
 #include <linux/vmalloc.h>
 
-
-#ifdef RT30xx
-#include <linux/wireless.h>
-#endif
 #include <net/iw_handler.h>
 
 // load firmware
@@ -90,22 +86,23 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
 
 // add by kathy
 
-#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.1.1"
-#endif
-#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"
-#ifndef RT30xx
-#define STA_DRIVER_VERSION			"1.4.0.0"
-#endif
-#ifdef RT30xx
-#define STA_DRIVER_VERSION			"2.0.1.0"
-#endif
+/* order of "if defined()" is important, because for 3070 driver
+   both RT2870 and RT3070 are defined */
+#if defined(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.1.1"
+#elif defined(RT3070)
+ #define STA_PROFILE_PATH			"/etc/Wireless/RT3070STA/RT3070STA.dat"
+ #define STA_RT2870_IMAGE_FILE_NAME  "/etc/Wireless/RT3070STA/rt2870.bin"
+ #define STA_NIC_DEVICE_NAME			"RT3070STA"
+ #define STA_DRIVER_VERSION			"2.0.1.0"
+#elif defined(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			"1.4.0.0"
 #endif
 
 #ifdef RT2860
@@ -161,15 +158,6 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
 #define NDIS_PACKET_TYPE_BROADCAST		2
 #define NDIS_PACKET_TYPE_ALL_MULTICAST	3
 
-#ifndef RT30xx
-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)
-#endif
-
 struct os_lock  {
 	spinlock_t		lock;
 	unsigned long  	flags;
@@ -185,16 +173,9 @@ struct os_cookie {
 #ifdef RT2870
 	struct usb_device		*pUsb_Dev;
 
-#ifndef RT30xx
-	THREAD_PID				MLMEThr_pid;
-	THREAD_PID				RTUSBCmdThr_pid;
-	THREAD_PID				TimerQThr_pid;
-#endif
-#ifdef RT30xx
 	struct pid	*MLMEThr_pid;
 	struct pid	*RTUSBCmdThr_pid;
 	struct pid	*TimerQThr_pid;
-#endif
 #endif // RT2870 //
 
 	struct tasklet_struct 	rx_done_task;
@@ -219,12 +200,6 @@ struct os_cookie {
 	INT 					ioctl_if;
 };
 
-typedef struct _VIRTUAL_ADAPTER
-{
-	struct net_device		*RtmpDev;
-	struct net_device		*VirtualDev;
-} VIRTUAL_ADAPTER, PVIRTUAL_ADAPTER;
-
 #undef  ASSERT
 #define ASSERT(x)
 
@@ -444,51 +419,6 @@ extern ULONG    RTDebugLevel;
 }
 
 #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)									\
-{																	\
-    if ((_A)->bPCIclkOff == FALSE)                                      \
-    {                                                                   \
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-	(*_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)));		\
-	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));			\
-}
-#define RTMP_IO_WRITE32(_A, _R, _V)									\
-{																	\
-    if ((_A)->bPCIclkOff == FALSE)                                      \
-    {                                                                   \
-	UINT32	_Val;													\
-	_Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
-	_Val = SWAP32(_V);												\
-	writel(_Val, (void *)((_A)->CSRBaseAddress + (_R)));			\
-    }                                                                   \
-}
-#define RTMP_IO_WRITE8(_A, _R, _V)									\
-{																	\
-	UINT	Val;													\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
-	writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R)));			\
-}
-#define RTMP_IO_WRITE16(_A, _R, _V)									\
-{																	\
-	UINT	Val;													\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
-	writew(SWAP16((_V)), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
-}
-#else
 //Patch for ASIC turst read/write bug, needs to remove after metel fix
 #define RTMP_IO_READ32(_A, _R, _pV)								\
 {																\
@@ -519,32 +449,18 @@ extern ULONG    RTDebugLevel;
 	writel(_V, (void *)((_A)->CSRBaseAddress + (_R)));								\
     }                                                               \
 }
-#if defined(BRCM_6358)
-#define RTMP_IO_WRITE8(_A, _R, _V)            \
-{                    \
-	ULONG Val;                \
-	UCHAR _i;                \
-	_i = (_R & 0x3);             \
-	Val = readl((void *)((_A)->CSRBaseAddress + (_R - _i)));   \
-	Val = Val & (~(0x000000ff << ((_i)*8)));         \
-	Val = Val | ((ULONG)_V << ((_i)*8));         \
-	writel((Val), (void *)((_A)->CSRBaseAddress + (_R - _i)));    \
-}
-#else
 #define RTMP_IO_WRITE8(_A, _R, _V)												\
 {																				\
 	UINT	Val;																\
 	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
 	writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R)));		\
 }
-#endif
 #define RTMP_IO_WRITE16(_A, _R, _V)												\
 {																				\
 	UINT	Val;																\
 	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
 	writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
 }
-#endif
 #endif /* RT2860 */
 #ifdef RT2870
 //Patch for ASIC turst read/write bug, needs to remove after metel fix
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index f298b9b..22f37cf 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -74,11 +74,9 @@ static void CfgInitHook(PRTMP_ADAPTER pAd);
 
 extern	const struct iw_handler_def rt28xx_iw_handler_def;
 
-#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);
@@ -190,7 +188,7 @@ int rt28xx_close(IN PNET_DEV dev)
 	BOOLEAN 		Cancelled = FALSE;
 	UINT32			i = 0;
 #ifdef RT2870
-	DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
+	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
 	DECLARE_WAITQUEUE(wait, current);
 
 	//RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
@@ -517,9 +515,6 @@ static int rt28xx_init(IN struct net_device *net_dev)
 	NICInitRT30xxRFRegisters(pAd);
 #endif // RT2870 //
 
-#ifdef IKANOS_VX_1X0
-	VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
-#endif // IKANOS_VX_1X0 //
 
 		//
 	// Initialize RF register to default value
@@ -527,7 +522,7 @@ static int rt28xx_init(IN struct net_device *net_dev)
 	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
 	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
 
-#ifndef RT30xx
+#ifndef RT2870
 	// 8051 firmware require the signal during booting time.
 	AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
 #endif
@@ -675,16 +670,12 @@ err:
 static const struct net_device_ops rt2860_netdev_ops = {
 	.ndo_open		= MainVirtualIF_open,
 	.ndo_stop		= MainVirtualIF_close,
-	.ndo_do_ioctl		= rt28xx_ioctl,
+	.ndo_do_ioctl		= rt28xx_sta_ioctl,
 	.ndo_get_stats		= RT28xx_get_ether_stats,
 	.ndo_validate_addr	= NULL,
 	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_change_mtu		= eth_change_mtu,
-#ifdef IKANOS_VX_1X0
-	.ndo_start_xmit		= IKANOS_DataFramesTx,
-#else
 	.ndo_start_xmit		= rt28xx_send_packets,
-#endif
 };
 
 /* Must not be called for mdev and apdev */
@@ -695,22 +686,17 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 	CHAR    slot_name[IFNAMSIZ];
 	struct net_device   *device;
 
-#if WIRELESS_EXT >= 12
 	if (pAd->OpMode == OPMODE_STA)
 	{
 		dev->wireless_handlers = &rt28xx_iw_handler_def;
 	}
-#endif //WIRELESS_EXT >= 12
 
-#if WIRELESS_EXT < 21
-		dev->get_wireless_stats = rt28xx_get_wireless_stats;
-#endif
 	dev->priv_flags = INT_MAIN;
 	dev->netdev_ops = &rt2860_netdev_ops;
 	// find available device name
 	for (i = 0; i < 8; i++)
 	{
-		sprintf(slot_name, "ra%d", i);
+		sprintf(slot_name, "wlan%d", i);
 
 		device = dev_get_by_name(dev_net(dev), slot_name);
 		if (device != NULL)
@@ -727,7 +713,7 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
 	}
 	else
 	{
-		sprintf(dev->name, "ra%d", i);
+		sprintf(dev->name, "wlan%d", i);
 		Status = NDIS_STATUS_SUCCESS;
 	}
 
@@ -791,6 +777,8 @@ INT __devinit   rt28xx_probe(
 
 	// Allocate RTMP_ADAPTER miniport adapter structure
 	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+	if (handle == NULL)
+		goto err_out_free_netdev;;
 	RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
 
 	status = RTMPAllocAdapterBlock(handle, &pAd);
@@ -862,7 +850,7 @@ 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;
+	int status = NETDEV_TX_OK;
 	PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
 
 	{
@@ -892,7 +880,7 @@ int rt28xx_packet_xmit(struct sk_buff *skb)
 
 	STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
 
-	status = 0;
+	status = NETDEV_TX_OK;
 done:
 
 	return status;
@@ -923,7 +911,7 @@ INT rt28xx_send_packets(
 	if (!(net_dev->flags & IFF_UP))
 	{
 		RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
@@ -942,7 +930,6 @@ void CfgInitHook(PRTMP_ADAPTER pAd)
 } /* 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)
@@ -976,7 +963,6 @@ struct iw_statistics *rt28xx_get_wireless_stats(
 	DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
 	return &pAd->iw_stats;
 } /* End of rt28xx_get_wireless_stats */
-#endif // WIRELESS_EXT //
 
 
 
@@ -986,37 +972,6 @@ void tbtt_tasklet(unsigned long data)
 
 }
 
-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;
-	}
-
-	ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
-
-	return ret;
-}
-
 /*
     ========================================================================
 
diff --git a/drivers/staging/rt2860/rt_profile.c b/drivers/staging/rt2860/rt_profile.c
index d92b143..3bc41f8 100644
--- a/drivers/staging/rt2860/rt_profile.c
+++ b/drivers/staging/rt2860/rt_profile.c
@@ -710,7 +710,7 @@ static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  char *buffe
 				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"));
+			DBGPRINT(RT_DEBUG_TRACE, ("I/F(wlan%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
 			return 1;
 		}
 		else
@@ -731,12 +731,12 @@ static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  char *buffe
 				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"));
+			DBGPRINT(RT_DEBUG_TRACE, ("I/F(wlan%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));
+			DBGPRINT(RT_DEBUG_ERROR, ("I/F(wlan%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
 			return 0;
 		}
 	}
@@ -860,7 +860,7 @@ NDIS_STATUS	RTMPReadParametersHook(
 {
 	PUCHAR					src = NULL;
 	struct file				*srcf;
-	INT 					retval, orgfsuid, orgfsgid;
+	INT 					retval;
    	mm_segment_t			orgfs;
 	CHAR					*buffer;
 	CHAR					*tmpbuf;
@@ -884,15 +884,6 @@ NDIS_STATUS	RTMPReadParametersHook(
 
 	src = STA_PROFILE_PATH;
 
-	// Save uid and gid used for filesystem access.
-	// Set user and group to 0 (root)
-#ifndef RT30xx
-	orgfsuid = current_fsuid();
-	orgfsgid = current_fsgid();
-	/* Hm, can't really do this nicely anymore, so rely on these files
-	 * being set to the proper permission to read them... */
-	/* current->cred->fsuid = current->cred->fsgid = 0; */
-#endif
     orgfs = get_fs();
     set_fs(KERNEL_DS);
 
@@ -1230,14 +1221,10 @@ NDIS_STATUS	RTMPReadParametersHook(
 					//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))
@@ -1442,23 +1429,6 @@ NDIS_STATUS	RTMPReadParametersHook(
 								DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
 						}
 					}
-
-#ifdef RT30xx
-						{
-							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 // RT30xx //
 				}
 			}
 			else
@@ -1571,21 +1541,15 @@ static void	HTParametersHook(
         if (Value == 0)
         {
             pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-#ifdef RT30xx
 	    pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
-#endif
         }
         else
         {
             pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
-#ifdef RT30xx
 	    pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-#endif
         }
         pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
-#ifdef RT30xx
 	pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
-#endif
         DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
     }
 
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index 25c3199..3f498f6 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -40,13 +40,10 @@
 #ifndef __RTMP_H__
 #define __RTMP_H__
 
-#include "link_list.h"
 #include "spectrum_def.h"
 
 #include "aironet.h"
 
-//#define DBG_DIAGNOSE		1
-
 #define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
 #define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
 #define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
@@ -234,15 +231,9 @@ extern UCHAR  WpaIe;
 extern UCHAR  Wpa2Ie;
 extern UCHAR  IbssIe;
 extern UCHAR  Ccx2Ie;
-#ifdef RT30xx
-extern UCHAR  WapiIe;
-#endif
 
 extern UCHAR  WPA_OUI[];
 extern UCHAR  RSN_OUI[];
-#ifdef RT30xx
-extern UCHAR  WAPI_OUI[];
-#endif
 extern UCHAR  WME_INFO_ELEM[];
 extern UCHAR  WME_PARM_ELEM[];
 extern UCHAR  Ccx2QosInfo[];
@@ -400,15 +391,15 @@ typedef struct  _QUEUE_HEADER   {
     (_idx) = (_idx+1) % (_RingSize);       \
 }
 
-#ifdef RT30xx
+#ifdef RT2870
 // We will have a cost down version which mac version is 0x3090xxxx
 #define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
+#else
+#define IS_RT3090(_pAd)				0
 #endif
 #define IS_RT3070(_pAd)				(((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
-#ifdef RT30xx
+#ifdef RT2870
 #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)
 #endif
 
@@ -664,11 +655,6 @@ typedef struct  _QUEUE_HEADER   {
 #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)                                 \
                 {                                           \
@@ -935,7 +921,6 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
 }
 #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)					\
@@ -967,8 +952,6 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
 		_pAd->RxAnt.RcvPktNumWhenEvaluate++;								\
 	}																		\
 }
-#endif // RT30xx //
-
 
 #define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen)                    \
     NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
@@ -1312,7 +1295,7 @@ typedef struct _BBP_TUNING_STRUCT {
 
 typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
 	UCHAR     EvaluatePeriod;		 // 0:not evalute status, 1: evaluate status, 2: switching status
-#ifdef RT30xx
+#ifdef RT2870
 	UCHAR     EvaluateStableCnt;
 #endif
 	UCHAR     Pair1PrimaryRxAnt;     // 0:Ant-E1, 1:Ant-E2
@@ -1916,9 +1899,6 @@ typedef struct _COMMON_CONFIG {
 
 	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.
-#ifdef RT30xx
-	BOOLEAN				bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity.
-#endif
 
 	// IEEE802.11H--DFS.
 	RADAR_DETECT_STRUCT	RadarDetect;
@@ -2532,43 +2512,6 @@ typedef struct _INF_USB_CONFIG
 
 }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 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][24]; // 3*3	// TxDesc queue length in scale of 0~14, >=15
-	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][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][24]; // 3*3
-}RtmpDiagStruct;
-#endif // DBG_DIAGNOSE //
 
 
 //
@@ -2721,9 +2664,8 @@ typedef struct _RTMP_ADAPTER
 	ULONG                   EepromVersion;          // byte 0: version, byte 1: revision, byte 2~3: unused
 	UCHAR                   EEPROMAddressNum;       // 93c46=6  93c66=8
 	USHORT                  EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
-#ifdef RT30xx
+#ifdef RT2870
 	BOOLEAN                 EepromAccess;
-	UCHAR                   EFuseTag;
 #endif
 	ULONG                   FirmwareVersion;        // byte 0: Minor version, byte 1: Major version, otherwise unused.
 
@@ -2972,9 +2914,7 @@ typedef struct _RTMP_ADAPTER
 
 	ULONG					OneSecondnonBEpackets;		// record non BE packets per second
 
-#if WIRELESS_EXT >= 12
     struct iw_statistics    iw_stats;
-#endif
 
 	struct net_device_stats	stats;
 
@@ -2991,25 +2931,13 @@ typedef struct _RTMP_ADAPTER
 	UCHAR					flg_be_adjust;
 	ULONG					be_adjust_last_time;
 
-#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
+#ifdef RT2870
 	BOOLEAN		bUseEfuse;
-	BOOLEAN		bEEPROMFile;
-#endif // RT30xx //
-
+#endif
 } RTMP_ADAPTER, *PRTMP_ADAPTER;
 
 //
@@ -3235,14 +3163,6 @@ static inline VOID ConvertMulticastIP2MAC(
 }
 #endif /* RT2860 */
 
-BOOLEAN RTMPCheckForHang(
-	IN  NDIS_HANDLE MiniportAdapterContext
-	);
-
-VOID  RTMPHalt(
-	IN  NDIS_HANDLE MiniportAdapterContext
-	);
-
 //
 //  Private routines in rtmp_init.c
 //
@@ -3255,11 +3175,6 @@ 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
 	);
@@ -3306,13 +3221,6 @@ 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);
 
@@ -3366,26 +3274,6 @@ UCHAR BtoH(
 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,
@@ -3474,14 +3362,6 @@ VOID PeerPublicAction(
 	IN PRTMP_ADAPTER pAd,
 	IN MLME_QUEUE_ELEM *Elem);
 
-VOID StaPublicAction(
-	IN PRTMP_ADAPTER pAd,
-	IN UCHAR Bss2040Coexist);
-
-VOID PeerBSSTranAction(
-	IN PRTMP_ADAPTER pAd,
-	IN MLME_QUEUE_ELEM *Elem);
-
 VOID PeerHTAction(
 	IN PRTMP_ADAPTER pAd,
 	IN MLME_QUEUE_ELEM *Elem);
@@ -3523,39 +3403,18 @@ VOID InsertActField(
 	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);
-
 BOOLEAN CntlEnqueueForRecv(
     IN	PRTMP_ADAPTER	pAd,
 	IN ULONG Wcid,
     IN ULONG MsgLen,
 	IN PFRAME_BA_REQ pMsg);
 
-VOID BaAutoManSwitch(
-	IN	PRTMP_ADAPTER	pAd);
-
-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);
@@ -3697,13 +3556,7 @@ NDIS_STATUS MiniportMMRequest(
 	IN	UCHAR			QueIdx,
 	IN	PUCHAR			pData,
 	IN  UINT            Length);
-#ifdef RT2870
-NDIS_STATUS MiniportDataMMRequest(
-	 IN  PRTMP_ADAPTER   pAd,
-	 IN  UCHAR           QueIdx,
-	 IN  PUCHAR          pData,
-	 IN  UINT            Length);
-#endif
+
 VOID RTMPSendNullFrame(
 	IN  PRTMP_ADAPTER   pAd,
 	IN  UCHAR           TxRate,
@@ -3722,12 +3575,6 @@ VOID RTMPSendRTSFrame(
 	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);
@@ -3778,10 +3625,6 @@ BOOLEAN RTMPCheckEtherType(
 	IN	PNDIS_PACKET	pPacket);
 
 
-VOID RTMPCckBbpTuning(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	UINT			TxRate);
-
 //
 // Private routines in rtmp_wep.c
 //
@@ -3798,12 +3641,6 @@ VOID RTMPEncryptData(
 	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,
@@ -3870,14 +3707,6 @@ 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,
@@ -4051,23 +3880,6 @@ 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);
-
 VOID  BssEntrySet(
 	IN  PRTMP_ADAPTER   pAd,
 	OUT PBSS_ENTRY pBss,
@@ -4243,10 +4055,6 @@ VOID DisassocTimeout(
 	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);
@@ -4410,10 +4218,6 @@ VOID ScanTimeout(
 	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);
@@ -4426,10 +4230,6 @@ 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);
 
@@ -4727,13 +4527,6 @@ BOOLEAN PeerDisassocSanity(
 	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,
@@ -4803,12 +4596,6 @@ VOID LinkDownExec(
 	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);
 
@@ -4895,12 +4682,6 @@ VOID StaQuickResponeForRateUpExec(
 	IN PVOID SystemSpecific2,
 	IN PVOID SystemSpecific3);
 
-VOID AsicBbpTuning1(
-	IN PRTMP_ADAPTER pAd);
-
-VOID AsicBbpTuning2(
-	IN PRTMP_ADAPTER pAd);
-
 VOID RTMPUpdateMlmeRate(
 	IN PRTMP_ADAPTER	pAd);
 
@@ -4910,11 +4691,9 @@ CHAR RTMPMaxRssi(
 	IN CHAR				Rssi1,
 	IN CHAR				Rssi2);
 
-#ifdef RT30xx
 VOID AsicSetRxAnt(
 	IN PRTMP_ADAPTER	pAd,
 	IN UCHAR			Ant);
-#endif
 
 VOID AsicEvaluateRxAnt(
 	IN PRTMP_ADAPTER	pAd);
@@ -4972,31 +4751,6 @@ 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);
@@ -5122,12 +4876,6 @@ VOID RTMPIoctlGetMacTable(
 	IN PRTMP_ADAPTER pAd,
 	IN struct iwreq *wrq);
 
-VOID RTMPIndicateWPA2Status(
-	IN  PRTMP_ADAPTER  pAdapter);
-
-VOID	RTMPOPModeSwitching(
-	IN	PRTMP_ADAPTER	pAd);
-
 VOID    RTMPAddBSSIDCipher(
     IN  PRTMP_ADAPTER   pAd,
 	IN	UCHAR	Aid,
@@ -5149,11 +4897,6 @@ VOID RTMPSendWirelessEvent(
 	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
 //
@@ -5305,25 +5048,11 @@ VOID    AironetAddBeaconReport(
 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);
 
-VOID APAsicEvaluateRxAnt(
-	IN PRTMP_ADAPTER	pAd);
-
-
-VOID APAsicRxAntEvalTimeout(
-	IN PRTMP_ADAPTER	pAd);
-
 //
 // function prototype in cmm_wpa.c
 //
@@ -5340,64 +5069,6 @@ VOID AES_GTK_KEY_UNWRAP(
 	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,
@@ -5408,192 +5079,10 @@ VOID RTMPMakeRSNIE(
 // 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 //
-
 /* timeout -- ms */
 VOID RTMP_SetPeriodicTimer(
 	IN	NDIS_MINIPORT_TIMER *pTimer,
@@ -5728,23 +5217,6 @@ 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);
@@ -5763,27 +5235,6 @@ 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);
-
 void ba_flush_reordering_timeout_mpdus(
 	IN PRTMP_ADAPTER	pAd,
 	IN PBA_REC_ENTRY	pBAEntry,
@@ -5828,29 +5279,6 @@ VOID BARecSessionTearDown(
 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);
-
 BOOLEAN rtstrmactohex(
 	IN char *s1,
 	IN char *s2);
@@ -6049,16 +5477,6 @@ INT	Set_HtTxBASize_Proc(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	PUCHAR			arg);
 
-//Dls ,	kathy
-VOID RTMPSendDLSTearDownFrame(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PUCHAR			pDA);
-
-//Block ACK
-VOID QueryBATABLE(
-	IN  PRTMP_ADAPTER pAd,
-	OUT PQUERYBA_TABLE pBAT);
-
 INT	    WpaCheckEapCode(
 	IN  PRTMP_ADAPTER   	pAd,
 	IN  PUCHAR				pFrame,
@@ -6069,22 +5487,9 @@ VOID    WpaSendMicFailureToWpaSupplicant(
     IN  PRTMP_ADAPTER       pAd,
     IN  BOOLEAN             bUnicast);
 
-VOID    SendAssocIEsToWpaSupplicant(
-    IN  PRTMP_ADAPTER       pAd);
-
 int wext_notify_event_assoc(
 	IN  RTMP_ADAPTER *pAd);
 
-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);
-
-BOOLEAN APRxDoneInterruptHandle(
-	IN	PRTMP_ADAPTER	pAd);
-
 BOOLEAN STARxDoneInterruptHandle(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	BOOLEAN			argc);
@@ -6160,16 +5565,6 @@ UINT deaggregate_AMSDU_announce(
 		_pRxBlk->DataSize, _pRemovedLLCSNAP);                                   \
 }
 
-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,
@@ -6209,12 +5604,6 @@ VOID Update_Rssi_Sample(
 	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);
@@ -6323,11 +5712,9 @@ 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,
@@ -6404,22 +5791,11 @@ VOID RT28xx_UpdateBeaconToAsic(
 	IN ULONG BeaconLen,
 	IN ULONG UpdatePos);
 
-INT rt28xx_ioctl(
-	IN	struct net_device	*net_dev,
-	IN	OUT	struct ifreq	*rq,
-	IN	INT			cmd);
-
 INT rt28xx_sta_ioctl(
 	IN	struct net_device	*net_dev,
 	IN	OUT	struct ifreq	*rq,
 	IN	INT			cmd);
 
-BOOLEAN RT28XXSecurityKeyAdd(
-	IN		PRTMP_ADAPTER		pAd,
-	IN		ULONG				apidx,
-	IN		ULONG				KeyIdx,
-	IN		MAC_TABLE_ENTRY 	*pEntry);
-
 ////////////////////////////////////////
 PNDIS_PACKET GetPacketFromRxRing(
 	IN		PRTMP_ADAPTER	pAd,
@@ -6555,7 +5931,6 @@ VOID AsicTurnOnRFClk(
 	IN PRTMP_ADAPTER 	pAd,
 	IN	UCHAR			Channel);
 
-#ifdef RT30xx
 NTSTATUS RT30xxWriteRFRegister(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UCHAR			RegID,
@@ -6566,7 +5941,6 @@ NTSTATUS RT30xxReadRFRegister(
 	IN	UCHAR			RegID,
 	IN	PUCHAR			pValue);
 
-//2008/09/11:KH add to support efuse<--
 UCHAR eFuseReadRegisters(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	USHORT Offset,
@@ -6637,16 +6011,6 @@ VOID eFusePhysicalReadRegisters(
 	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);
 
@@ -6655,8 +6019,6 @@ VOID RT30xxLoadRFSleepModeSetup(
 
 VOID RT30xxReverseRFSleepModeSetup(
 	IN PRTMP_ADAPTER 	pAd);
-// end johnli
-#endif // RT30xx //
 
 #ifdef RT2870
 //
@@ -6675,10 +6037,6 @@ VOID	RTUSBInitHTTxDesc(
 	IN	ULONG			BulkOutSize,
 	IN	usb_complete_t	Func);
 
-VOID	RTUSBInitRxDesc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PRX_CONTEXT		pRxContext);
-
 VOID RTUSBCleanUpDataBulkOutQueue(
 	IN	PRTMP_ADAPTER	pAd);
 
@@ -6725,9 +6083,6 @@ VOID RTUSBInitRxDesc(
 	IN	PRTMP_ADAPTER	pAd,
 	IN  PRX_CONTEXT		pRxContext);
 
-VOID RTUSBBulkRxHandle(
-	IN unsigned long data);
-
 //
 // Function Prototype in rtusb_io.c
 //
@@ -6762,18 +6117,6 @@ NTSTATUS RTUSBWriteRFRegister(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UINT32			Value);
 
-#ifndef 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);
-#endif
-
 NTSTATUS RTUSB_VendorRequest(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UINT32			TransferFlags,
@@ -6887,14 +6230,6 @@ NTSTATUS	RTUSBFirmwareOpmode(
 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);
 
@@ -6917,31 +6252,12 @@ NDIS_STATUS RTMPWPAAddKeyProc(
 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);
 
@@ -7043,19 +6359,6 @@ 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,
@@ -7066,7 +6369,6 @@ PCHAR   RTMPGetRalinkAuthModeStr(
 
 PCHAR   RTMPGetRalinkEncryModeStr(
     IN  USHORT encryMode);
-//////////////////////////////////////
 
 VOID AsicStaBbpTuning(
 	IN PRTMP_ADAPTER pAd);
@@ -7109,9 +6411,6 @@ 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)
diff --git a/drivers/staging/rt2860/rtmp_ckipmic.h b/drivers/staging/rt2860/rtmp_ckipmic.h
index a3d949a..39955b9 100644
--- a/drivers/staging/rt2860/rtmp_ckipmic.h
+++ b/drivers/staging/rt2860/rtmp_ckipmic.h
@@ -46,24 +46,6 @@ typedef	struct	_MIC_CONTEXT	{
 	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,
@@ -93,21 +75,4 @@ 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/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h
index 5dde860..f5fee57 100644
--- a/drivers/staging/rt2860/rtmp_def.h
+++ b/drivers/staging/rt2860/rtmp_def.h
@@ -148,11 +148,7 @@
 #define MAX_PACKETS_IN_PS_QUEUE				128	//32
 #define WMM_NUM_OF_AC                       4  /* AC0, AC1, AC2, and AC3 */
 
-#ifdef RT30xx
-//2008/09/11:KH add to support efuse<--
 #define MAX_EEPROM_BIN_FILE_SIZE					1024
-//2008/09/11:KH add to support efuse-->
-#endif
 
 // RxFilter
 #define STANORMAL	 0x17f97
@@ -573,9 +569,6 @@
 // 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
-#ifdef RT2870
-#define IE_WAPI							68		// WAPI information element
-#endif
 #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
@@ -624,11 +617,6 @@
 #define AP_CNTL_STATE_MACHINE           15
 #define AP_WPA_STATE_MACHINE            16
 
-#ifdef RT30xx
-#define WSC_STATE_MACHINE            17
-#define WSC_UPNP_STATE_MACHINE		    18
-#endif
-
 //
 // STA's CONTROL/CONNECT state machine: states, events, total function #
 //
@@ -1215,10 +1203,8 @@
 #define RFIC_2750                   4       // 2.4G/5G 1T2R
 #define RFIC_3020                   5       // 2.4G 1T1R
 #define RFIC_2020                   6       // 2.4G B/G
-#ifdef RT30xx
 #define RFIC_3021                   7       // 2.4G 1T2R
 #define RFIC_3022                   8       // 2.4G 2T2R
-#endif
 
 // LED Status.
 #define LED_LINK_DOWN               0
diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c
index a0734c6..1a58715 100644
--- a/drivers/staging/rt2860/sta/assoc.c
+++ b/drivers/staging/rt2860/sta/assoc.c
@@ -454,11 +454,7 @@ VOID MlmeAssocReqAction(
 				RSNIe = IE_WPA2;
 			}
 
-#ifdef RT30xx
-#ifdef SIOCSIWGENIE
 			if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif // SIOCSIWGENIE //
-#endif
             RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
 
             // Check for WPA PMK cache list
@@ -485,8 +481,6 @@ VOID MlmeAssocReqAction(
 				}
 			}
 
-#ifdef RT30xx
-#ifdef SIOCSIWGENIE
 			if (pAd->StaCfg.WpaSupplicantUP == 1)
 			{
 				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
@@ -494,8 +488,6 @@ VOID MlmeAssocReqAction(
 		                        	END_OF_ARGS);
 			}
 			else
-#endif
-#endif
 			{
 				MakeOutgoingFrame(pOutBuffer + FrameLen,    		&tmp,
 				              		1,                              &RSNIe,
@@ -506,11 +498,7 @@ VOID MlmeAssocReqAction(
 
 			FrameLen += tmp;
 
-#ifdef RT30xx
-#ifdef SIOCSIWGENIE
 			if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif
-#endif
 			{
 	            // Append Variable IE
 	            NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
@@ -1503,7 +1491,6 @@ int wext_notify_event_assoc(
     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;
@@ -1512,19 +1499,6 @@ int wext_notify_event_assoc(
     }
     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 + strlen(custom), "%02x", 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;
 
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index ac71351..7bc75ab 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -1171,7 +1171,6 @@ VOID LinkUp(
 		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
 		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
 
-#ifdef RT30xx
 		if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
 			(pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
 		{
@@ -1183,7 +1182,6 @@ VOID LinkUp(
 		{
 			pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
 		}
-#endif
 #ifdef RT2870
 		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
 			AdhocTurnOnQos(pAd);
@@ -1585,9 +1583,7 @@ VOID LinkUp(
 		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;
-#ifdef RT30xx
 		pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
-#endif
 		pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
         NdisReleaseSpinLock(&pAd->MacTabLock);
 
@@ -1711,15 +1707,10 @@ VOID LinkUp(
 	// 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 RT30xx
-	if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
+	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))))
-#endif
-#ifndef RT30xx
-	if (((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)))
-#endif
 	{
 		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
 		Data  &= 0xFFFFFF00;
@@ -2101,7 +2092,6 @@ VOID LinkDown(
 		wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
 	}
 
-#ifdef RT30xx
 	if (IS_RT3090(pAd))
 	{
 		UINT32				macdata;
@@ -2115,7 +2105,6 @@ VOID LinkDown(
 		macdata &= ~(0x09);	//bit 0, 3
 		RTMP_IO_WRITE32(pAd, 0x1210, macdata);
 	}
-#endif // RT30xx //
 }
 
 /*
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
index b41ce23..f751ab6 100644
--- a/drivers/staging/rt2860/sta/rtmp_data.c
+++ b/drivers/staging/rt2860/sta/rtmp_data.c
@@ -575,21 +575,16 @@ VOID STAHandleRxMgmtFrame(
 	{
 
 		// We should collect RSSI not only U2M data but also my beacon
-#ifdef RT30xx
-		if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
-			&& (pAd->RxAnt.EvaluatePeriod == 0))
-#endif
-#ifndef RT30xx
-		if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)))
-#endif
-		{
+		if (pAd->RxAnt.EvaluatePeriod == 0 &&
+		    pHeader->FC.SubType == SUBTYPE_BEACON &&
+		    MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) {
 			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
 
 			pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
 			pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
 		}
 
-#ifdef RT30xx
+#ifdef RT2870
 		// collect rssi information for antenna diversity
 		if (pAd->NicConfig2.field.AntDiversity)
 		{
@@ -599,7 +594,7 @@ VOID STAHandleRxMgmtFrame(
 					pAd->StaCfg.NumOfAvgRssiSample ++;
 			}
 		}
-#endif // RT30xx //
+#endif
 
 		// First check the size, it MUST not exceed the mlme queue size
 		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c
index 87b5e49..a6e4362 100644
--- a/drivers/staging/rt2860/sta/sync.c
+++ b/drivers/staging/rt2860/sta/sync.c
@@ -1116,10 +1116,8 @@ VOID PeerBeacon(
 			// Add the safeguard against the mismatch of adhoc wep status
 			if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
 			{
-#ifdef RT30xx
 				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));
-#endif
 				return;
 			}
 
diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c
index 5827436..8c34e39 100644
--- a/drivers/staging/rt2860/sta/wpa.c
+++ b/drivers/staging/rt2860/sta/wpa.c
@@ -1384,12 +1384,10 @@ VOID	WpaGroupMsg1Action(
 			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;
-#ifndef RT30xx
 		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;
-#endif
 
     	//hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
 	}
@@ -1766,12 +1764,7 @@ BOOLEAN ParseKeyData(
 	// Get GTK length - refer to IEEE 802.11i-2004 p.82
 	GTKLEN = pKDE->Len -6;
 
-#ifdef RT30xx
 	if (GTKLEN < LEN_AES_KEY)
-#endif
-#ifndef RT30xx
-	if (GTKLEN < MIN_LEN_OF_GTK)
-#endif
 	{
 		DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
         return FALSE;
@@ -1797,12 +1790,10 @@ BOOLEAN ParseKeyData(
 		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;
-#ifndef RT30xx
 	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;
-#endif
 
 	return TRUE;
 
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index eb0109a..c0e0425 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -87,29 +87,8 @@ struct iw_priv_args privtab[] = {
 	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
 	{ SHOW_CFG_VALUE,
 	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
-#if !defined(RT2860) && !defined(RT30xx)
-	{ SHOW_ADHOC_ENTRY_INFO,
-	  0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
-#endif
 /* --- 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"},
@@ -173,29 +152,6 @@ INT Set_Wpa_Support(
     IN	PRTMP_ADAPTER	pAd,
 	IN	PUCHAR			arg);
 
-#ifdef DBG
-#if !defined(RT2860) && !defined(RT30xx)
-VOID RTMPIoctlBBP(
-	IN	PRTMP_ADAPTER	pAdapter,
-	IN	struct iwreq	*wrq);
-#endif
-
-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);
@@ -216,12 +172,6 @@ INT Set_ShortRetryLimit_Proc(
 	IN	PRTMP_ADAPTER	pAdapter,
 	IN	PUCHAR			arg);
 
-#if !defined(RT2860) && !defined(RT30xx)
-INT	Show_Adhoc_MacTable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PCHAR			extra);
-#endif
-
 static struct {
 	CHAR *name;
 	INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
@@ -279,13 +229,11 @@ static struct {
     {"ForceGF",		        		Set_ForceGF_Proc},
 	{"LongRetry",	        		Set_LongRetryLimit_Proc},
 	{"ShortRetry",	        		Set_ShortRetryLimit_Proc},
-//2008/09/11:KH add to support efuse<--
-#ifdef RT30xx
+#ifdef RT2870
 	{"efuseFreeNumber",				set_eFuseGetFreeBlockCount_Proc},
 	{"efuseDump",					set_eFusedump_Proc},
 	{"efuseLoadFromBin",				set_eFuseLoadFromBin_Proc},
-#endif // RT30xx //
-//2008/09/11:KH add to support efuse-->
+#endif
 	{NULL,}
 };
 
@@ -531,12 +479,7 @@ rt_ioctl_giwname(struct net_device *dev,
 		   char *name, char *extra)
 {
 //	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#ifdef RT2860
-    strncpy(name, "RT2860 Wireless", IFNAMSIZ);
-#endif
-#ifdef RT2870
-	strncpy(name, "RT2870 Wireless", IFNAMSIZ);
-#endif // RT2870 //
+	strncpy(name, RT28xx_CHIP_NAME " Wireless", IFNAMSIZ);
 	return 0;
 }
 
@@ -577,38 +520,10 @@ int rt_ioctl_giwfreq(struct net_device *dev,
 		   struct iw_request_info *info,
 		   struct iw_freq *freq, char *extra)
 {
-    VIRTUAL_ADAPTER *pVirtualAd = NULL;
-#ifndef RT30xx
-	PRTMP_ADAPTER pAdapter = NULL;
-#endif
-#ifdef RT30xx
-	PRTMP_ADAPTER pAdapter;
-#endif
-	UCHAR ch;
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	UCHAR ch = pAdapter->CommonCfg.Channel;
 	ULONG	m;
 
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-#ifndef RT30xx
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-#endif
-			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);
@@ -656,31 +571,7 @@ int rt_ioctl_giwmode(struct net_device *dev,
 		   struct iw_request_info *info,
 		   __u32 *mode, char *extra)
 {
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 
 	if (ADHOC_ON(pAdapter))
 		*mode = IW_MODE_ADHOC;
@@ -724,37 +615,11 @@ int rt_ioctl_giwrange(struct net_device *dev,
 		   struct iw_request_info *info,
 		   struct iw_point *data, char *extra)
 {
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-#endif
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 	struct iw_range *range = (struct iw_range *) extra;
 	u16 val;
 	int i;
 
-#ifndef RT30xx
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
-
 	DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
 	data->length = sizeof(struct iw_range);
 	memset(range, 0, sizeof(struct iw_range));
@@ -820,11 +685,9 @@ int rt_ioctl_giwrange(struct net_device *dev,
 	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;
 }
@@ -873,31 +736,7 @@ int rt_ioctl_giwap(struct net_device *dev,
 		      struct iw_request_info *info,
 		      struct sockaddr *ap_addr, char *extra)
 {
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 
 	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
 	{
@@ -994,7 +833,6 @@ int rt_ioctl_iwaplist(struct net_device *dev,
 	return 0;
 }
 
-#ifdef SIOCGIWSCAN
 int rt_ioctl_siwscan(struct net_device *dev,
 			struct iw_request_info *info,
 			struct iw_point *data, char *extra)
@@ -1091,9 +929,6 @@ int rt_ioctl_giwscan(struct net_device *dev,
 	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))
@@ -1115,25 +950,15 @@ int rt_ioctl_giwscan(struct net_device *dev,
 		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
-        }
+			return -E2BIG;
 
 		//MAC address
 		//================================
@@ -1144,13 +969,8 @@ int rt_ioctl_giwscan(struct net_device *dev,
 
         previous_ev = current_ev;
 		current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
-#ifdef RT30xx
         if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
+		return -E2BIG;
 
 		/*
 		Protocol:
@@ -1224,13 +1044,8 @@ int rt_ioctl_giwscan(struct net_device *dev,
 
 		previous_ev = current_ev;
 		current_ev	 = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
-#endif /* RT30xx */
         if (current_ev == previous_ev)
-#if WIRELESS_EXT >= 17
-            return -E2BIG;
-#else
-			break;
-#endif
+		return -E2BIG;
 
 		//ESSID
 		//================================
@@ -1242,11 +1057,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
         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
+		return -E2BIG;
 
 		//Network Type
 		//================================
@@ -1269,11 +1080,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
         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
+		return -E2BIG;
 
 		//Channel and Frequency
 		//================================
@@ -1289,11 +1096,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
 		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
+		return -E2BIG;
 
         //Add quality statistics
         //================================
@@ -1304,11 +1107,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
         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
+		return -E2BIG;
 
 		//Encyption key
 		//================================
@@ -1322,11 +1121,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
         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
+		return -E2BIG;
 
 		//Bit Rate
 		//================================
@@ -1355,14 +1150,9 @@ int rt_ioctl_giwscan(struct net_device *dev,
         	if((current_val-current_ev)>IW_EV_LCP_LEN)
             	current_ev = current_val;
         	else
-#if WIRELESS_EXT >= 17
-                return -E2BIG;
-#else
-			    break;
-#endif
+			return -E2BIG;
         }
 
-#ifdef IWEVGENIE
 		//WPA IE
 		if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
 		{
@@ -1374,11 +1164,7 @@ int rt_ioctl_giwscan(struct net_device *dev,
 			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
+				return -E2BIG;
 		}
 
 		//WPA2 IE
@@ -1392,54 +1178,8 @@ int rt_ioctl_giwscan(struct net_device *dev,
 			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 + strlen(custom), "%02x", 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 + strlen(custom), "%02x", 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
+				return -E2BIG;
         }
-#endif // IWEVGENIE //
 	}
 
 	data->length = current_ev - extra;
@@ -1447,7 +1187,6 @@ int rt_ioctl_giwscan(struct net_device *dev,
 	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,
@@ -1494,31 +1233,7 @@ int rt_ioctl_giwessid(struct net_device *dev,
 			 struct iw_request_info *info,
 			 struct iw_point *data, char *essid)
 {
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 
 	data->flags = 1;
     if (MONITOR_ON(pAdapter))
@@ -1578,31 +1293,7 @@ int rt_ioctl_giwnickn(struct net_device *dev,
 			 struct iw_request_info *info,
 			 struct iw_point *data, char *nickname)
 {
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 
 	if (data->length > strlen(pAdapter->nickname) + 1)
 		data->length = strlen(pAdapter->nickname) + 1;
@@ -1646,31 +1337,7 @@ int rt_ioctl_giwrts(struct net_device *dev,
 		       struct iw_request_info *info,
 		       struct iw_param *rts, char *extra)
 {
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 
 	//check if the interface is down
     	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
@@ -1702,8 +1369,8 @@ int rt_ioctl_siwfrag(struct net_device *dev,
 
 	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 >= 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
@@ -1717,31 +1384,7 @@ int rt_ioctl_giwfrag(struct net_device *dev,
 			struct iw_request_info *info,
 			struct iw_param *frag, char *extra)
 {
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 
 	//check if the interface is down
     	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
@@ -1781,15 +1424,8 @@ int rt_ioctl_siwencode(struct net_device *dev,
         pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
         pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
         goto done;
-	}
-#ifndef RT30xx
-	else if ((erq->length == 0) &&
-             (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN))
-#endif
-#ifdef RT30xx
-	else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)
-#endif
-	{
+	} else if (
+		 (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)) {
 		STA_PORT_SECURED(pAdapter);
 		pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
 		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
@@ -1799,9 +1435,6 @@ int rt_ioctl_siwencode(struct net_device *dev,
 			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
     	else
 			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-#ifndef RT30xx
-        goto done;
-#endif
 	}
 
     if (erq->length > 0)
@@ -1820,12 +1453,8 @@ int rt_ioctl_siwencode(struct net_device *dev,
             //Using default key
 			keyIdx = pAdapter->StaCfg.DefaultKeyId;
         }
-#ifdef RT30xx
 		else
-		{
 			pAdapter->StaCfg.DefaultKeyId=keyIdx;
-		}
-#endif
 
         NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
 
@@ -1877,32 +1506,8 @@ rt_ioctl_giwencode(struct net_device *dev,
 			  struct iw_request_info *info,
 			  struct iw_point *erq, char *key)
 {
-#ifdef RT30xx
 	PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#endif
 	int kid;
-#ifndef RT30xx
-	PRTMP_ADAPTER 	pAdapter = NULL;
-	VIRTUAL_ADAPTER *pVirtualAd = NULL;
-
-	if (dev->priv_flags == INT_MAIN)
-	{
-		pAdapter = dev->ml_priv;
-	}
-	else
-	{
-		pVirtualAd = dev->ml_priv;
-		if (pVirtualAd && pVirtualAd->RtmpDev)
-			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;
-	}
-#endif
 
 	//check if the interface is down
 	if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
@@ -1959,31 +1564,12 @@ 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;
+	PRTMP_ADAPTER pAdapter = dev->ml_priv;
+	POS_COOKIE pObj = (POS_COOKIE)pAdapter->OS_Cookie;
 	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;
@@ -2127,27 +1713,10 @@ 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;
+    PRTMP_ADAPTER pAd = dev->ml_priv;
+    POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
     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;
@@ -2265,12 +1834,6 @@ rt_private_show(struct net_device *dev, struct iw_request_info *info,
 					wrq->length = strlen(extra) + 1; // 1: size of '\0'
 			}
 			break;
-#if !defined(RT2860) && !defined(RT30xx)
-		case SHOW_ADHOC_ENTRY_INFO:
-			Show_Adhoc_MacTable_Proc(pAd, extra);
-			wrq->length = strlen(extra) + 1; // 1: size of '\0'
-			break;
-#endif
         default:
             DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd));
             break;
@@ -2279,7 +1842,6 @@ rt_private_show(struct net_device *dev, struct iw_request_info *info,
     return Status;
 }
 
-#ifdef SIOCSIWMLME
 int rt_ioctl_siwmlme(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu,
@@ -2335,9 +1897,7 @@ int rt_ioctl_siwmlme(struct net_device *dev,
 
 	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)
@@ -2626,7 +2186,6 @@ int rt_ioctl_siwencodeext(struct net_device *dev,
 
                 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,  16);
 			    NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
-#ifndef RT30xx
 				if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
 					pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
 				{
@@ -2641,7 +2200,6 @@ int rt_ioctl_siwencodeext(struct net_device *dev,
     				// Indicate Connected for GUI
     				pAdapter->IndicateMediaState = NdisMediaStateConnected;
 				}
-#endif
     			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));
@@ -2773,7 +2331,6 @@ rt_ioctl_giwencodeext(struct net_device *dev,
 	return 0;
 }
 
-#ifdef SIOCSIWGENIE
 int rt_ioctl_siwgenie(struct net_device *dev,
 			  struct iw_request_info *info,
 			  union iwreq_data *wrqu, char *extra)
@@ -2797,7 +2354,6 @@ int rt_ioctl_siwgenie(struct net_device *dev,
 
 	return 0;
 }
-#endif // SIOCSIWGENIE //
 
 int rt_ioctl_giwgenie(struct net_device *dev,
 			       struct iw_request_info *info,
@@ -2812,7 +2368,6 @@ int rt_ioctl_giwgenie(struct net_device *dev,
 		return 0;
 	}
 
-#ifdef SIOCSIWGENIE
 	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
 	{
 	if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
@@ -2822,7 +2377,6 @@ int rt_ioctl_giwgenie(struct net_device *dev,
 	memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
 	}
 	else
-#endif // SIOCSIWGENIE //
 	{
 		UCHAR RSNIe = IE_WPA;
 
@@ -2916,139 +2470,6 @@ int rt_ioctl_siwpmksa(struct net_device *dev,
 
 	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;
-	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 //
-				{
-					{
-					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 //
-				{
-					{
-					    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;
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
-#ifndef RT30xx
-			sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X    ", bbpId, bbpId*2, regBBP);
-			if (bbpId%5 == 4)
-				sprintf(extra+strlen(extra), "\n");
-#endif
-#ifdef RT30xx
-			sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP);  // edit by johnli, change display format
-#endif
-		}
-
-        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,
@@ -3184,19 +2605,10 @@ static const iw_handler rt_handler[] =
 	(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  */
@@ -3219,7 +2631,6 @@ static const iw_handler rt_handler[] =
 	(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   */
@@ -3227,18 +2638,13 @@ static const iw_handler rt_handler[] =
 	(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 */
 	(iw_handler) rt_ioctl_setparam, /* + 0x02 */
-#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 */
@@ -3274,1888 +2680,16 @@ const struct iw_handler_def rt28xx_iw_handler_def =
 #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;
-	OID_SET_HT_PHYMODE					HT_PhyMode;	//11n ,kathy
-    PNDIS_802_11_PMKID                  pPmkId = NULL;
-    BOOLEAN				                IEEE8021xState = FALSE;
-    BOOLEAN				                IEEE8021x_required_keys = FALSE;
-    UCHAR                               wpa_supplicant_enable = 0;
-
-	MaxPhyMode = PHY_11N_5G;
-
-	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);
-				SetCommonHT(pAdapter);
-				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:
-            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:
-            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);
-					SetCommonHT(pAdapter);
-				}
-                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
-#ifdef RT30xx
-                    pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
-#endif
-                    if (pAdapter->StaCfg.BssType == BSS_ADHOC)
-                    {
-#ifndef RT30xx
-						pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
-#endif
-                    	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;
-
-				if (Status == NDIS_STATUS_SUCCESS)
-					SetCommonHT(pAdapter);
-
-                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;
-		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;
-		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;
-
-		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:
-			//
-			// 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;
-		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;
-        // 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)
-                    {
-                        // 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;
-                        pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
-                    }
-#ifndef RT30xx
-#ifdef RT2860
-					if ((pAdapter->StaCfg.WpaSupplicantUP != 0) &&
-#endif
-#ifdef RT2870
-					if ((pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
-#endif
-						(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
-#ifdef RT30xx
-                    if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
-#endif
-                    {
-                        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;
-	    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;
-        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;
-
-    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;
-        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:
-            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;
-        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;
-        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;
-			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;
-
-		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);
-				DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
-				value = 0;
-				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;
-
-        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;
+	RTMP_ADAPTER *pAd = net_dev->ml_priv;
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
 	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))
@@ -5300,17 +2834,9 @@ INT rt28xx_sta_ioctl(
 		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:
-#ifdef RT30xx
-        case RT_PRIV_IOCTL_EXT:
-#endif
-			subcmd = wrq->u.data.flags;
-			if( subcmd & OID_GET_SET_TOGGLE)
-				Status = RTMPSetInformation(pAd, rq, subcmd);
-			else
-				Status = RTMPQueryInformation(pAd, rq, subcmd);
+		case RT_PRIV_IOCTL_EXT:
+			Status = -EOPNOTSUPP;
 			break;
 		case SIOCGIWPRIV:
 			if (wrq->u.data.pointer)
@@ -5330,19 +2856,6 @@ INT rt28xx_sta_ioctl(
 		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:
@@ -6241,592 +3754,6 @@ INT Set_Wpa_Support(
     return TRUE;
 }
 
-#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;
-#ifdef RT30xx
-	BOOLEAN				bIsPrintAllMAC = FALSE;
-#endif
-
-	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
-#ifndef RT30xx
-				{//Invalid parametes, so default printk all bbp
-#endif
-#ifdef RT30xx
-				{//Invalid parametes, so default printk all mac
-					bIsPrintAllMAC = TRUE;
-#endif
-					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);
-						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);
-			}
-		}
-	}
-#ifdef RT30xx
-	else
-		bIsPrintAllMAC = TRUE;
-#endif
-next:
-#ifdef RT30xx
-	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", __func__, -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);
-	}
-#endif /* RT30xx */
-	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;
-#ifdef RT30xx
-	BOOLEAN				bIsPrintAllE2P = FALSE;
-#endif
-
-	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
-#ifdef RT30xx
-					bIsPrintAllE2P = TRUE;
-#endif
-					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);
-		}
-	}
-#ifdef RT30xx
-	else
-		bIsPrintAllE2P = TRUE;
-#endif
-next:
-#ifdef RT30xx
-	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", __func__, -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);
-	}
-#endif /* RT30xx */
-	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.
-					// 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.
-						{
-							// 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++)
-		{
-			// 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", __func__));
-		}
-	}
-	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)
@@ -6867,48 +3794,3 @@ INT Set_ShortRetryLimit_Proc(
 	DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
 	return TRUE;
 }
-
-#if !defined(RT2860) && !defined(RT30xx)
-INT	Show_Adhoc_MacTable_Proc(
-	IN	PRTMP_ADAPTER	pAd,
-	IN	PCHAR			extra)
-{
-	INT i;
-
-	sprintf(extra, "\n");
-
-	sprintf(extra + strlen(extra), "HT Operating Mode : %d\n", pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
-
-	sprintf(extra + strlen(extra), "\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
-			"MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
-
-	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
-	{
-		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
-
-		if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
-		    break;
-		if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
-		{
-			sprintf(extra + strlen(extra), "%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(extra + strlen(extra), "%-4d", (int)pEntry->Aid);
-			sprintf(extra + strlen(extra), "%-4d", (int)pEntry->apidx);
-			sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi0);
-			sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi1);
-			sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi2);
-			sprintf(extra + strlen(extra), "%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
-			sprintf(extra + strlen(extra), "%-6s", GetBW(pEntry->HTPhyMode.field.BW));
-			sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.MCS);
-			sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.ShortGI);
-			sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.STBC);
-			sprintf(extra + strlen(extra), "%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
-						(pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
-			sprintf(extra, "%s\n", extra);
-		}
-	}
-
-	return TRUE;
-}
-#endif /* RT2870 */
diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h
index e671674..7006e38 100644
--- a/drivers/staging/rt2860/wpa.h
+++ b/drivers/staging/rt2860/wpa.h
@@ -90,9 +90,6 @@
 #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))
-#ifndef RT30xx
-#define MIN_LEN_OF_GTK				5
-#endif
 
 // 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 a4e8696..d0ed48b 100644
--- a/drivers/staging/rt2870/2870_main_dev.c
+++ b/drivers/staging/rt2870/2870_main_dev.c
@@ -45,11 +45,12 @@
 // *** 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");
+MODULE_DESCRIPTION(RT28xx_CHIP_NAME " Wireless LAN Linux Driver");
 MODULE_LICENSE("GPL");
 #ifdef MODULE_VERSION
 MODULE_VERSION(STA_DRIVER_VERSION);
 #endif
+MODULE_ALIAS("rt3070sta");
 
 /* Kernel thread and vars, which handles packets that are completed. Only
  * packets that have a "complete" function are sent here. This way, the
@@ -59,9 +60,91 @@ MODULE_VERSION(STA_DRIVER_VERSION);
 extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
 									IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
 
+struct usb_device_id rtusb_usb_id[] = {
+	{ USB_DEVICE(0x148F, 0x2770) }, /* Ralink */
+	{ USB_DEVICE(0x1737, 0x0071) }, /* Linksys WUSB600N */
+	{ USB_DEVICE(0x1737, 0x0070) }, /* Linksys */
+	{ 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(0x0DF6, 0x003F) }, /* Sitecom WL-608 */
+	{ USB_DEVICE(0x14B2, 0x3C06) }, /* Conceptronic */
+	{ USB_DEVICE(0x14B2, 0x3C28) }, /* Conceptronic */
+	{ USB_DEVICE(0x2019, 0xED06) }, /* Planex Communications, Inc. */
+	{ USB_DEVICE(0x2019, 0xED14) }, /* 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(0x050D, 0x815C) }, /* Belkin */
+	{ USB_DEVICE(0x050D, 0x825a) }, /* 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, 0x2870) }, /* AboCom */
+	{ USB_DEVICE(0x07B8, 0x2770) }, /* AboCom */
+	{ 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(0x7392, 0x7717) }, /* Edimax */
+	{ USB_DEVICE(0x1EDA, 0x2310) }, /* AirTies 3070 */
+	{ USB_DEVICE(0x1737, 0x0077) }, /* Linksys WUSB54GC-EU v3 */
+	{ } /* Terminating entry */
+};
 
-/* 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);
 
@@ -234,12 +317,7 @@ INT MlmeThread(
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
 
-#ifndef RT30xx
-	pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
-#endif
-#ifdef RT30xx
 	pObj->MLMEThr_pid = NULL;
-#endif
 
 	complete_and_exit (&pAd->mlmeComplete, 0);
 	return 0;
@@ -347,12 +425,7 @@ INT RTUSBCmdThread(
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
 
-#ifndef RT30xx
-	pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
-#endif
-#ifdef RT30xx
 	pObj->RTUSBCmdThr_pid = NULL;
-#endif
 
 	complete_and_exit (&pAd->CmdQComplete, 0);
 	return 0;
@@ -446,12 +519,8 @@ INT TimerQThread(
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
 
-#ifndef RT30xx
-	pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
-#endif
-#ifdef RT30xx
 	pObj->TimerQThr_pid = NULL;
-#endif
+
 	complete_and_exit(&pAd->TimerQComplete, 0);
 	return 0;
 
@@ -882,74 +951,29 @@ VOID RT28xxThreadTerminate(
 	RTUSBCancelPendingIRPs(pAd);
 
 	// Terminate Threads
-#ifndef RT30xx
-	CHECK_PID_LEGALITY(pObj->TimerQThr_pid)
+
+	if (pid_nr(pObj->TimerQThr_pid) > 0)
 	{
 		POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
 
-		printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj->TimerQThr_pid));
+		printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
 		mb();
 		pAd->TimerFunc_kill = 1;
 		mb();
-		ret = KILL_THREAD_PID(pObj->TimerQThr_pid, SIGTERM, 1);
+		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, GET_PID_NUMBER(pObj->TimerQThr_pid), ret);
+					pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
 		}
 		else
 		{
 			wait_for_completion(&pAd->TimerQComplete);
-			pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
-		}
-	}
-
-	CHECK_PID_LEGALITY(pObj->MLMEThr_pid)
-	{
-		printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj->MLMEThr_pid));
-		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;
+			pObj->TimerQThr_pid = NULL;
 		}
 	}
 
-	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
-	{
-		printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj->RTUSBCmdThr_pid));
-		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;
-		}
-	}
-#endif
-#ifdef RT30xx
-	if (pObj->MLMEThr_pid)
+	if (pid_nr(pObj->MLMEThr_pid) > 0)
 	{
 		printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
 		mb();
@@ -970,7 +994,7 @@ VOID RT28xxThreadTerminate(
 		}
 	}
 
-	if (pObj->RTUSBCmdThr_pid >= 0)
+	if (pid_nr(pObj->RTUSBCmdThr_pid) > 0)
 	{
 		printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
 		mb();
@@ -984,7 +1008,7 @@ VOID RT28xxThreadTerminate(
 		{
 			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);
@@ -992,27 +1016,6 @@ VOID RT28xxThreadTerminate(
 			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;
-		}
-	}
-#endif
 
 	// Kill tasklets
 	pAd->mlme_kill = 0;
@@ -1067,12 +1070,7 @@ BOOLEAN RT28XXChipsetCheck(
 		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
 			dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
 		{
-#ifndef RT30xx
-			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
-#endif
-#ifdef RT30xx
 			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
-#endif
 					dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
 			break;
 		}
@@ -1441,7 +1439,7 @@ VOID RT2870_BssBeaconStart(
 		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);
+		printk(RT28xx_CHIP_NAME "_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
 		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
 
 	}
diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig
index 8398d97..76841f6 100644
--- a/drivers/staging/rt2870/Kconfig
+++ b/drivers/staging/rt2870/Kconfig
@@ -1,6 +1,5 @@
 config RT2870
-	tristate "Ralink 2870 wireless support"
+	tristate "Ralink 2870/3070 wireless support"
 	depends on USB && X86 && WLAN_80211
 	---help---
-	  This is an experimental driver for the Ralink 2870 wireless chip.
-
+	  This is an experimental driver for the Ralink xx70 wireless chips.
diff --git a/drivers/staging/rt2870/Makefile b/drivers/staging/rt2870/Makefile
index 3c17921..306c331 100644
--- a/drivers/staging/rt2870/Makefile
+++ b/drivers/staging/rt2870/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_RT2870)	+= rt2870sta.o
 
 # TODO: all of these should be removed
 EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2870
+EXTRA_CFLAGS += -DRT2870 -DRT3070
 EXTRA_CFLAGS += -DDBG
 
 rt2870sta-objs :=		\
diff --git a/drivers/staging/rt2870/common/2870_rtmp_init.c b/drivers/staging/rt2870/common/2870_rtmp_init.c
index 80909e9..f517d9e 100644
--- a/drivers/staging/rt2870/common/2870_rtmp_init.c
+++ b/drivers/staging/rt2870/common/2870_rtmp_init.c
@@ -699,14 +699,9 @@ NDIS_STATUS AdapterBlockAllocateMemory(
 
 	usb_dev = pObj->pUsb_Dev;
 
-#ifndef RT30xx
-	pObj->MLMEThr_pid		= THREAD_PID_INIT_VALUE;
-	pObj->RTUSBCmdThr_pid	= THREAD_PID_INIT_VALUE;
-#endif
-#ifdef RT30xx
 	pObj->MLMEThr_pid	= NULL;
 	pObj->RTUSBCmdThr_pid	= NULL;
-#endif
+
 	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
 
 	if (*ppAd)
@@ -742,12 +737,7 @@ NDIS_STATUS	 CreateThreads(
 {
 	PRTMP_ADAPTER pAd = net_dev->ml_priv;
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
-#ifndef RT30xx
-	pid_t pid_number = -1;
-#endif
-#ifdef RT30xx
 	pid_t pid_number;
-#endif
 
 	//init_MUTEX(&(pAd->usbdev_semaphore));
 
@@ -761,75 +751,42 @@ NDIS_STATUS	 CreateThreads(
 	init_completion (&pAd->TimerQComplete);
 
 	// Creat MLME Thread
-#ifndef RT30xx
-	pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE;
-	pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-	{
-#endif
-#ifdef RT30xx
 	pObj->MLMEThr_pid = NULL;
 	pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
 	if (pid_number < 0)
 	{
-#endif
 		printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
 
-#ifndef RT30xx
-	pObj->MLMEThr_pid = GET_PID(pid_number);
-#endif
-#ifdef RT30xx
 	pObj->MLMEThr_pid = find_get_pid(pid_number);
-#endif
+
 	// Wait for the thread to start
 	wait_for_completion(&(pAd->mlmeComplete));
 
 	// Creat Command Thread
-#ifndef RT30xx
-	pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE;
-	pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-#endif
-#ifdef RT30xx
 	pObj->RTUSBCmdThr_pid = NULL;
 	pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
 	if (pid_number < 0)
-#endif
 	{
 		printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
 
-#ifndef RT30xx
-	pObj->RTUSBCmdThr_pid = GET_PID(pid_number);
-#endif
-#ifdef RT30xx
 	pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
-#endif
+
 	wait_for_completion(&(pAd->CmdQComplete));
 
-#ifndef RT30xx
-	pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE;
-	pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
-	if (pid_number < 0)
-#endif
-#ifdef RT30xx
 	pObj->TimerQThr_pid = NULL;
 	pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
 	if (pid_number < 0)
-#endif
 	{
 		printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
-#ifndef RT30xx
-	pObj->TimerQThr_pid = GET_PID(pid_number);
-#endif
-#ifdef RT30xx
+
 	pObj->TimerQThr_pid = find_get_pid(pid_number);
-#endif
+
 	// Wait for the thread to start
 	wait_for_completion(&(pAd->TimerQComplete));
 
@@ -1306,9 +1263,7 @@ static void rt2870_hcca_dma_done_tasklet(unsigned long data)
 	UCHAR				BulkOutPipeId = 4;
 	purbb_t				pUrb;
 
-#ifndef RT30xx
 	DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));
-#endif
 
 	pUrb			= (purbb_t)data;
 	pHTTXContext	= (PHT_TX_CONTEXT)pUrb->context;
@@ -1338,20 +1293,12 @@ static void rt2870_hcca_dma_done_tasklet(unsigned long data)
 				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
 			}
 
-#ifndef RT30xx
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
-#endif
-#ifdef RT30xx
 			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
-#endif
 			RTUSBKickBulkOut(pAd);
 		}
 	}
 
-#ifndef RT30xx
 	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));
-#endif
-		return;
 }
 
 
diff --git a/drivers/staging/rt2870/common/cmm_data_2870.c b/drivers/staging/rt2870/common/cmm_data_2870.c
index d6fc056..3b63a48 100644
--- a/drivers/staging/rt2870/common/cmm_data_2870.c
+++ b/drivers/staging/rt2870/common/cmm_data_2870.c
@@ -810,12 +810,7 @@ VOID RT28xxUsbStaAsicForceWakeup(
 	AutoWakeupCfg.word = 0;
 	RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
 
-#ifndef RT30xx
-	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x00);
-#endif
-#ifdef RT30xx
 	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-#endif
 
 	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
 }
@@ -852,12 +847,7 @@ VOID RT28xxUsbMlmeRadioOn(
 	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
 		return;
 
-#ifndef RT30xx
-    	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x00);
-#endif
-#ifdef RT30xx
     	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-#endif
 		RTMPusecDelay(10000);
 
 	NICResetFromError(pAd);
@@ -908,22 +898,6 @@ VOID RT28xxUsbMlmeRadioOFF(
 		BssTableInit(&pAd->ScanTab);
 	}
 
-#ifndef RT30xx
-	// 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);
-#endif
-
 	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
 	{
 		// Must using 40MHz.
@@ -935,13 +909,11 @@ VOID RT28xxUsbMlmeRadioOFF(
 		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
 	}
 
-#ifdef RT30xx
 	// 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
-#endif
 
 	// Waiting for DMA idle
 	i = 0;
@@ -954,12 +926,10 @@ VOID RT28xxUsbMlmeRadioOFF(
 		RTMPusecDelay(1000);
 	}while (i++ < 100);
 
-#ifdef RT30xx
 	// Disable MAC Tx/Rx
 	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
 	Value &= (0xfffffff3);
 	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-#endif
 
 	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
 }
diff --git a/drivers/staging/rt2870/common/firmware.h b/drivers/staging/rt2870/common/firmware.h
deleted file mode 100644
index a406698..0000000
--- a/drivers/staging/rt2870/common/firmware.h
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- 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, 0x79, 0x02,
-0x12, 0x7a, 0x02, 0x12, 0x99, 0x02, 0x12, 0x9e, 0x12, 0x12, 0x9a, 0x22, 0x02, 0x16, 0x36, 0x02,
-0x17, 0x0c, 0x02, 0x13, 0x89, 0x02, 0x12, 0x9f, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
-0xae, 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, 0x6e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
-0xb7, 0x31, 0x10, 0xe2, 0x50, 0x11, 0x08, 0x51, 0x11, 0x13, 0x52, 0x11, 0x13, 0x53, 0x11, 0x13,
-0x54, 0x11, 0x54, 0x55, 0x11, 0x79, 0x70, 0x11, 0xa4, 0x71, 0x11, 0xd2, 0x72, 0x12, 0x25, 0x73,
-0x12, 0x46, 0x80, 0x00, 0x00, 0x12, 0x6e, 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, 0x6e, 0x02, 0x12, 0x67, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x02,
-0x12, 0x6e, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x6e, 0x90,
-0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x6e, 0x75,
-0x4e, 0x03, 0x75, 0x4f, 0x20, 0x02, 0x12, 0x6e, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47,
-0x02, 0x12, 0x6e, 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,
-0x6e, 0x02, 0x12, 0x67, 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, 0xe4, 0xfd, 0xaf,
-0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x02, 0x12, 0x6e, 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,
-0x6e, 0x02, 0x12, 0x67, 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, 0x6e, 0x02,
-0x12, 0x67, 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, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x70, 0x40,
-0xe5, 0x3a, 0xf0, 0x80, 0x49, 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, 0x90, 0x70,
-0x42, 0xe5, 0x3a, 0xf0, 0xa3, 0x74, 0xab, 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, 0xc1, 0x00, 0x13, 0x54, 0x04, 0x13, 0x50,
-0x08, 0x13, 0x2b, 0x10, 0x12, 0xd5, 0x20, 0x12, 0xf5, 0x60, 0x13, 0x06, 0xa0, 0x00, 0x00, 0x13,
-0x56, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03,
-0x02, 0x13, 0x56, 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, 0x16, 0x12, 0x13, 0x9e, 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,
-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, 0x05, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07, 0x90, 0x02, 0x28,
-0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x05, 0x44, 0x01, 0xf0, 0x02, 0x16, 0x05,
-0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, 0x28, 0xe0, 0x54,
-0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x05, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08,
-0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x05, 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, 0x01, 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, 0x16, 0xf0, 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,
-0x2c, 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, 0x2c, 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, 0x7a, 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, 0x7a, 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, 0x7a, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x69, 0x77,
-0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x25, 0x02,
-0x12, 0x26, 0x02, 0x12, 0x39, 0x02, 0x12, 0x3e, 0x12, 0x12, 0x3a, 0x22, 0x02, 0x15, 0x72, 0x02,
-0x16, 0x48, 0x02, 0x13, 0x29, 0x02, 0x12, 0x3f, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x16,
-0xea, 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, 0x1a, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
-0xb4, 0x31, 0x10, 0xdf, 0x50, 0x11, 0x05, 0x51, 0x11, 0x10, 0x52, 0x11, 0x10, 0x53, 0x11, 0x10,
-0x54, 0x11, 0x51, 0x55, 0x11, 0x70, 0x70, 0x11, 0x9a, 0x71, 0x11, 0xc4, 0x72, 0x11, 0xf2, 0x80,
-0x00, 0x00, 0x12, 0x1a, 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, 0x1a, 0x02, 0x12, 0x13, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x02, 0x12, 0x1a, 0x90,
-0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x1a, 0x90, 0x70, 0x11, 0xe0,
-0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x1a, 0x75, 0x4e, 0x03, 0x75,
-0x4f, 0x20, 0x02, 0x12, 0x1a, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x02, 0x12, 0x1a,
-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, 0x1a, 0x02, 0x12,
-0x13, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x08, 0x08, 0x90, 0x70, 0x11, 0xe0,
-0x54, 0x07, 0xf5, 0x3a, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x02, 0x12, 0x1a,
-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, 0x1a, 0x80, 0x79, 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,
-0x60, 0x58, 0x80, 0x4f, 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, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x70, 0x40, 0xe5, 0x3a, 0xf0,
-0x80, 0x28, 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, 0x90, 0x70, 0x42, 0xe5, 0x3a, 0xf0,
-0xa3, 0x74, 0xab, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x0e, 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, 0x61, 0x00, 0x12, 0xf4, 0x04, 0x12, 0xf0,
-0x08, 0x12, 0xcb, 0x10, 0x12, 0x75, 0x20, 0x12, 0x95, 0x60, 0x12, 0xa6, 0xa0, 0x00, 0x00, 0x12,
-0xf6, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03,
-0x02, 0x12, 0xf6, 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, 0x15, 0x52, 0x12, 0x13, 0x3e, 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, 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, 0x15, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe3,
-0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x73,
-0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x15, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe3,
-0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x75,
-0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x15, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3,
-0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x71,
-0x92, 0x70, 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, 0x15, 0x41, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80,
-0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x15, 0x41, 0x44, 0x01,
-0xf0, 0x02, 0x15, 0x41, 0xe5, 0x46, 0x30, 0xe3, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90,
-0x02, 0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x15, 0x41, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x09,
-0xe5, 0x47, 0x64, 0x08, 0x60, 0x03, 0x02, 0x15, 0x41, 0xe4, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0,
-0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x26, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x36, 0x24, 0x03,
-0x70, 0x5f, 0xe5, 0x46, 0x13, 0x13, 0x13, 0x54, 0x1f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20,
-0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x02, 0xa2, 0x47,
-0x92, 0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x3f, 0xe5, 0x46, 0x30, 0xe3, 0x03, 0xd3, 0x80,
-0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe3, 0x0d, 0x54, 0x70, 0xc3, 0x94, 0x60, 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,
-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, 0x16, 0x2c, 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, 0x15, 0x68, 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, 0x15, 0x68, 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, 0x16, 0xb6, 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, 0x16, 0xb6, 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, 0x16, 0xb6, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe9, 0x00, } ;
diff --git a/drivers/staging/rt2870/common/rtusb_bulk.c b/drivers/staging/rt2870/common/rtusb_bulk.c
index 7ae3e95..a4244b5 100644
--- a/drivers/staging/rt2870/common/rtusb_bulk.c
+++ b/drivers/staging/rt2870/common/rtusb_bulk.c
@@ -976,7 +976,7 @@ VOID	RTUSBKickBulkOut(
 				RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
 			}
 		}
-#ifdef RT30xx
+
 		//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))
 		{
@@ -986,7 +986,6 @@ VOID	RTUSBKickBulkOut(
 			{
 			}
 		}
-#endif
 
 		// 7. Null frame is the last
 		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
index 704b5c2..1d69590 100644
--- a/drivers/staging/rt2870/common/rtusb_io.c
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -110,11 +110,9 @@ NTSTATUS RTUSBFirmwareWrite(
 	Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
 	Status = RTUSBFirmwareRun(pAd);
 
-#ifdef RT30xx
 	RTMPusecDelay(10000);
 	RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
 	AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
-#endif
 
 	return Status;
 }
@@ -671,11 +669,10 @@ NTSTATUS	RTUSBWriteRFRegister(
 	return STATUS_SUCCESS;
 }
 
-#ifndef RT30xx
 /*
 	========================================================================
 
-	Routine Description: Write RT3070 RF register through MAC
+	Routine Description: Write RT30xx RF register through MAC
 
 	Arguments:
 
@@ -687,7 +684,7 @@ NTSTATUS	RTUSBWriteRFRegister(
 
 	========================================================================
 */
-NTSTATUS	RT30xxWriteRFRegister(
+NTSTATUS RT30xxWriteRFRegister(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UCHAR			RegID,
 	IN	UCHAR			Value)
@@ -697,7 +694,7 @@ NTSTATUS	RT30xxWriteRFRegister(
 
 	do
 	{
-		RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
 
 		if (!rfcsr.field.RF_CSR_KICK)
 			break;
@@ -716,15 +713,16 @@ NTSTATUS	RT30xxWriteRFRegister(
 	rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
 	rfcsr.field.RF_CSR_DATA = Value;
 
-	RTUSBWriteMACRegister(pAd, RF_CSR_CFG, rfcsr.word);
+	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
 
 	return STATUS_SUCCESS;
 }
 
+
 /*
 	========================================================================
 
-	Routine Description: Read RT3070 RF register through MAC
+	Routine Description: Read RT30xx RF register through MAC
 
 	Arguments:
 
@@ -736,17 +734,17 @@ NTSTATUS	RT30xxWriteRFRegister(
 
 	========================================================================
 */
-NTSTATUS	RT30xxReadRFRegister(
+NTSTATUS RT30xxReadRFRegister(
 	IN	PRTMP_ADAPTER	pAd,
 	IN	UCHAR			RegID,
 	IN	PUCHAR			pValue)
 {
 	RF_CSR_CFG_STRUC	rfcsr;
-	UINT				i=0, k;
+	UINT				i=0, k=0;
 
 	for (i=0; i<MAX_BUSY_COUNT; i++)
 	{
-		RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
+		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
 
 		if (rfcsr.field.RF_CSR_KICK == BUSY)
 		{
@@ -756,10 +754,10 @@ NTSTATUS	RT30xxReadRFRegister(
 		rfcsr.field.RF_CSR_WR = 0;
 		rfcsr.field.RF_CSR_KICK = 1;
 		rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
-		RTUSBWriteMACRegister(pAd, RF_CSR_CFG, rfcsr.word);
+		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
 		for (k=0; k<MAX_BUSY_COUNT; k++)
 		{
-			RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
+			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
 
 			if (rfcsr.field.RF_CSR_KICK == IDLE)
 				break;
@@ -773,13 +771,12 @@ NTSTATUS	RT30xxReadRFRegister(
 	}
 	if (rfcsr.field.RF_CSR_KICK == BUSY)
 	{
-		DBGPRINT_ERR(("RF read R%d=0x%x fail\n", RegID, rfcsr.word));
+		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 */
 
 /*
 	========================================================================
@@ -804,13 +801,9 @@ NTSTATUS	RTUSBReadEEPROM(
 {
 	NTSTATUS	Status = STATUS_SUCCESS;
 
-#ifdef RT30xx
 	if(pAd->bUseEfuse)
-	{
 		Status =eFuseRead(pAd, Offset, pData, length);
-	}
 	else
-#endif // RT30xx //
 	{
 	Status = RTUSB_VendorRequest(
 		pAd,
@@ -849,13 +842,9 @@ NTSTATUS	RTUSBWriteEEPROM(
 {
 	NTSTATUS	Status = STATUS_SUCCESS;
 
-#ifdef RT30xx
 	if(pAd->bUseEfuse)
-	{
 		Status = eFuseWrite(pAd, Offset, pData, length);
-	}
 	else
-#endif // RT30xx //
 	{
 	Status = RTUSB_VendorRequest(
 		pAd,
@@ -983,12 +972,7 @@ NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
 	PCmdQElmt	cmdqelmt = NULL;
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
 
-#ifndef RT30xx
-	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
-#endif
-#ifdef RT30xx
-	if (pObj->RTUSBCmdThr_pid < 0)
-#endif
+	if (pid_nr(pObj->RTUSBCmdThr_pid) > 0)
 		return (NDIS_STATUS_RESOURCES);
 
 	status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
@@ -1738,39 +1722,6 @@ VOID CMDHandler(
 						}
 					}
 					break;
-
-#ifdef RT30xx
-//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);
-
-						RTMPAddWcidAttributeEntry(
-										  pAd,
-										  ApIdx,
-										  KeyIdx,
-										  CipherAlg,
-										  pEntry);
-					}
-						break;
-//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
-#endif
-
 				case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
 					{
 						MAC_TABLE_ENTRY *pEntry;
@@ -1816,17 +1767,11 @@ VOID CMDHandler(
 								pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
 					}
 					break;
-
-#ifdef RT30xx
-// 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
-#endif
-
 				case OID_802_11_ADD_WEP:
 					{
 						UINT	i;
diff --git a/drivers/staging/rt2870/link_list.h b/drivers/staging/rt2870/link_list.h
deleted file mode 100644
index 2589f34..0000000
--- a/drivers/staging/rt2870/link_list.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2860/link_list.h"
diff --git a/drivers/staging/rt2870/md4.h b/drivers/staging/rt2870/md4.h
deleted file mode 100644
index f1e5b52..0000000
--- a/drivers/staging/rt2870/md4.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *************************************************************************
- * 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/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
index 2b8872b..4c67baf 100644
--- a/drivers/staging/rt2870/rt2870.h
+++ b/drivers/staging/rt2870/rt2870.h
@@ -46,9 +46,7 @@
 #define MAX_TXBULK_SIZE         (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
 #define MAX_RXBULK_SIZE         (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
 #define MAX_MLME_HANDLER_MEMORY 20
-#ifndef RT30xx
 #define	RETRY_LIMIT             10
-#endif
 #define BUFFER_SIZE				2400	//2048
 #define	TX_RING					0xa
 #define	PRIO_RING				0xc
@@ -64,9 +62,7 @@
 #define	fRTUSB_BULK_OUT_DATA_NORMAL_2			0x00020000
 #define	fRTUSB_BULK_OUT_DATA_NORMAL_3			0x00040000
 #define	fRTUSB_BULK_OUT_DATA_NORMAL_4			0x00080000
-#ifdef RT30xx
 #define	fRTUSB_BULK_OUT_DATA_NORMAL_5			0x00100000
-#endif
 
 #define	fRTUSB_BULK_OUT_PSPOLL					0x00000020
 #define	fRTUSB_BULK_OUT_DATA_FRAG				0x00000040
@@ -74,155 +70,6 @@
 #define	fRTUSB_BULK_OUT_DATA_FRAG_3				0x00000100
 #define	fRTUSB_BULK_OUT_DATA_FRAG_4				0x00000200
 
-#ifndef RT30xx
-#define RT2870_USB_DEVICES	\
-{	\
-	{USB_DEVICE(0x148F,0x2770)}, /* Ralink */		\
-	{USB_DEVICE(0x1737,0x0071)}, /* Linksys WUSB600N */	\
-	{USB_DEVICE(0x1737,0x0070)}, /* Linksys */	\
-	{USB_DEVICE(0x148F,0x2870)}, /* Ralink */		\
-	{USB_DEVICE(0x148F,0x3070)}, /* Ralink */		\
-	{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,0x002D)}, /* Sitecom */		\
-	{USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */		\
-	{USB_DEVICE(0x0DF6,0x003F)}, /* Sitecom WL-608 */	\
-	{USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */		\
-	{USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */		\
-	{USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */		\
-	{USB_DEVICE(0x2019,0xED14)}, /* 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(0x14B2,0x3C07)}, /* AL */			\
-	{USB_DEVICE(0x14B2,0x3C12)}, /* AL */           \
-	{USB_DEVICE(0x050D,0x8053)}, /* Belkin */		\
-	{USB_DEVICE(0x050D,0x815C)}, /* 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 */		\
-	{USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */		\
-	{USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */		\
-	{USB_DEVICE(0x083A,0xB522)}, /* SMC */			\
-	{USB_DEVICE(0x083A,0xA618)}, /* SMC */			\
-	{USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */		\
-	{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(0x0471,0x200f)}, /* Philips */		\
-	{USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */		\
-	{USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */	\
-	{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 */		\
-	{USB_DEVICE(0x07B8,0x3071)}, /* AboCom */		\
-	{USB_DEVICE(0x07B8,0x2870)}, /* AboCom */		\
-	{USB_DEVICE(0x07B8,0x2770)}, /* AboCom */		\
-	{USB_DEVICE(0x7392,0x7711)}, /* Edimax */		\
-	{USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */		\
-	{USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */		\
-	{USB_DEVICE(0x0789,0x0162)}, /* Logitec */		\
-	{USB_DEVICE(0x0789,0x0163)}, /* Logitec */		\
-	{USB_DEVICE(0x0789,0x0164)}, /* Logitec */		\
-	{USB_DEVICE(0x7392,0x7717)}, /* Edimax */		\
-	{ }/* Terminating entry */                      \
-}
-#endif
-#ifdef RT30xx
-#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 */                      \
-}
-#endif
-
 #define	FREE_HTTX_RING(_p, _b, _t)			\
 {										\
 	if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition)				\
@@ -288,7 +135,6 @@ typedef	struct	_MGMT_STRUC	{
 
 
 /* ----------------- EEPROM Related MACRO ----------------- */
-#ifdef RT30xx
 #define RT28xx_EEPROM_READ16(pAd, offset, var)					\
 	do {														\
 		RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2);		\
@@ -303,21 +149,6 @@ typedef	struct	_MGMT_STRUC	{
 		_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;											\
-		_tmpVar = cpu2le16(var);								\
-		RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2);	\
-	}while(0)
-#endif // RT30xx //
 
 /* ----------------- TASK/THREAD Related MACRO ----------------- */
 #define RT28XX_TASK_THREAD_INIT(pAd, Status)		\
@@ -433,14 +264,6 @@ extern UCHAR EpToQueue[6];
 	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, 	\
 							pEntry, sizeof(MAC_TABLE_ENTRY));
 
-#ifdef RT30xx
-// 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
-#endif
-
 // remove Pair-wise key material from ASIC
 // yet implement
 #define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
@@ -526,12 +349,11 @@ extern UCHAR EpToQueue[6];
 	{	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);	\
 		RTUSBKickBulkOut(pAd); }
 
-#define RT28xx_CHIP_NAME            "RT2870"
+#define RT28xx_CHIP_NAME            "RTxx70"
+
 #define USB_CYC_CFG                 0x02a4
-#ifndef RT30xx
 #define STATUS_SUCCESS				0x00
 #define STATUS_UNSUCCESSFUL 		0x01
-#endif
 #define NT_SUCCESS(status)			(((status) > 0) ? (1):(0))
 #define InterlockedIncrement 	 	atomic_inc
 #define NdisInterlockedIncrement 	atomic_inc
@@ -556,9 +378,6 @@ extern UCHAR EpToQueue[6];
 //#undef MlmeAllocateMemory
 //#undef MlmeFreeMemory
 
-#ifndef RT30xx
-typedef int				NTSTATUS;
-#endif
 typedef struct usb_device	* PUSB_DEV;
 
 /* MACRO for linux usb */
@@ -586,36 +405,19 @@ 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);
 
-#ifndef RT30xx
 #define RTUSBMlmeUp(pAd)	        \
 {								    \
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	CHECK_PID_LEGALITY(pObj->MLMEThr_pid)		    \
+	if (pid_nr(pObj->MLMEThr_pid) > 0) \
         up(&(pAd->mlme_semaphore)); \
 }
 
 #define RTUSBCMDUp(pAd)	                \
 {									    \
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)	    \
+	if (pid_nr(pObj->RTUSBCmdThr_pid) > 0) \
 	    up(&(pAd->RTUSBCmd_semaphore)); \
 }
-#endif
-#ifdef RT30xx
-#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)); \
-}
-#endif
 
 static inline NDIS_STATUS RTMPAllocateMemory(
 	OUT PVOID *ptr,
@@ -657,9 +459,7 @@ 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
-#ifndef RT30xx
 	UCHAR Addr[MAC_ADDR_LEN];	// avoid in interrupt when write key
-#endif
 } RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID;
 
 typedef struct   _RT_SET_ASIC_WCID_ATTRI {
@@ -752,20 +552,13 @@ typedef	struct	_CMDHandler_TLV	{
 #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
-
-#ifdef RT30xx
-// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
 #define CMDTHREAD_UPDATE_PROTECT					0x0D790103	// cmd
-// end johnli
-#endif
 
 #define WPA1AKMBIT	    0x01
 #define WPA2AKMBIT	    0x02
diff --git a/drivers/staging/rt3070/2870_main_dev.c b/drivers/staging/rt3070/2870_main_dev.c
deleted file mode 100644
index 32427c0..0000000
--- a/drivers/staging/rt3070/2870_main_dev.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/2870_main_dev.c"
diff --git a/drivers/staging/rt3070/Kconfig b/drivers/staging/rt3070/Kconfig
deleted file mode 100644
index b37fb5d..0000000
--- a/drivers/staging/rt3070/Kconfig
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index df7ac19..0000000
--- a/drivers/staging/rt3070/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-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 += -DDBG
-
-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
deleted file mode 100644
index 345fa89..0000000
--- a/drivers/staging/rt3070/action.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/common/action.h"
diff --git a/drivers/staging/rt3070/aironet.h b/drivers/staging/rt3070/aironet.h
deleted file mode 100644
index 78088f2..0000000
--- a/drivers/staging/rt3070/aironet.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/aironet.h"
diff --git a/drivers/staging/rt3070/ap.h b/drivers/staging/rt3070/ap.h
deleted file mode 100644
index ab8de4b..0000000
--- a/drivers/staging/rt3070/ap.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/ap.h"
diff --git a/drivers/staging/rt3070/chlist.h b/drivers/staging/rt3070/chlist.h
deleted file mode 100644
index 8ee1ff5..0000000
--- a/drivers/staging/rt3070/chlist.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/chlist.h"
diff --git a/drivers/staging/rt3070/common/2870_rtmp_init.c b/drivers/staging/rt3070/common/2870_rtmp_init.c
deleted file mode 100644
index 5456454..0000000
--- a/drivers/staging/rt3070/common/2870_rtmp_init.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/2870_rtmp_init.c"
diff --git a/drivers/staging/rt3070/common/action.c b/drivers/staging/rt3070/common/action.c
deleted file mode 100644
index 035fd80..0000000
--- a/drivers/staging/rt3070/common/action.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/action.c"
diff --git a/drivers/staging/rt3070/common/ba_action.c b/drivers/staging/rt3070/common/ba_action.c
deleted file mode 100644
index 2d638ea..0000000
--- a/drivers/staging/rt3070/common/ba_action.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/ba_action.c"
diff --git a/drivers/staging/rt3070/common/cmm_data.c b/drivers/staging/rt3070/common/cmm_data.c
deleted file mode 100644
index 02e202d..0000000
--- a/drivers/staging/rt3070/common/cmm_data.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/cmm_data.c"
diff --git a/drivers/staging/rt3070/common/cmm_data_2870.c b/drivers/staging/rt3070/common/cmm_data_2870.c
deleted file mode 100644
index 0e51ee4..0000000
--- a/drivers/staging/rt3070/common/cmm_data_2870.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/cmm_data_2870.c"
diff --git a/drivers/staging/rt3070/common/cmm_info.c b/drivers/staging/rt3070/common/cmm_info.c
deleted file mode 100644
index 6e981e5..0000000
--- a/drivers/staging/rt3070/common/cmm_info.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/cmm_info.c"
diff --git a/drivers/staging/rt3070/common/cmm_sanity.c b/drivers/staging/rt3070/common/cmm_sanity.c
deleted file mode 100644
index 82ccf9e..0000000
--- a/drivers/staging/rt3070/common/cmm_sanity.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/cmm_sanity.c"
diff --git a/drivers/staging/rt3070/common/cmm_sync.c b/drivers/staging/rt3070/common/cmm_sync.c
deleted file mode 100644
index 3b51742..0000000
--- a/drivers/staging/rt3070/common/cmm_sync.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/cmm_sync.c"
diff --git a/drivers/staging/rt3070/common/cmm_wpa.c b/drivers/staging/rt3070/common/cmm_wpa.c
deleted file mode 100644
index 6483d32..0000000
--- a/drivers/staging/rt3070/common/cmm_wpa.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/cmm_wpa.c"
diff --git a/drivers/staging/rt3070/common/dfs.c b/drivers/staging/rt3070/common/dfs.c
deleted file mode 100644
index c584a69..0000000
--- a/drivers/staging/rt3070/common/dfs.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/dfs.c"
diff --git a/drivers/staging/rt3070/common/eeprom.c b/drivers/staging/rt3070/common/eeprom.c
deleted file mode 100644
index 0c567d3..0000000
--- a/drivers/staging/rt3070/common/eeprom.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/eeprom.c"
diff --git a/drivers/staging/rt3070/common/md5.c b/drivers/staging/rt3070/common/md5.c
deleted file mode 100644
index 0752884..0000000
--- a/drivers/staging/rt3070/common/md5.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/md5.c"
diff --git a/drivers/staging/rt3070/common/mlme.c b/drivers/staging/rt3070/common/mlme.c
deleted file mode 100644
index c2d0d4e..0000000
--- a/drivers/staging/rt3070/common/mlme.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/mlme.c"
diff --git a/drivers/staging/rt3070/common/rtmp_init.c b/drivers/staging/rt3070/common/rtmp_init.c
deleted file mode 100644
index 4709e5f..0000000
--- a/drivers/staging/rt3070/common/rtmp_init.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/rtmp_init.c"
diff --git a/drivers/staging/rt3070/common/rtmp_tkip.c b/drivers/staging/rt3070/common/rtmp_tkip.c
deleted file mode 100644
index 57a5ee9..0000000
--- a/drivers/staging/rt3070/common/rtmp_tkip.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/rtmp_tkip.c"
diff --git a/drivers/staging/rt3070/common/rtmp_wep.c b/drivers/staging/rt3070/common/rtmp_wep.c
deleted file mode 100644
index 7197985..0000000
--- a/drivers/staging/rt3070/common/rtmp_wep.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/rtmp_wep.c"
diff --git a/drivers/staging/rt3070/common/rtusb_bulk.c b/drivers/staging/rt3070/common/rtusb_bulk.c
deleted file mode 100644
index 762ecfe..0000000
--- a/drivers/staging/rt3070/common/rtusb_bulk.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/rtusb_bulk.c"
diff --git a/drivers/staging/rt3070/common/rtusb_data.c b/drivers/staging/rt3070/common/rtusb_data.c
deleted file mode 100644
index d05deb8..0000000
--- a/drivers/staging/rt3070/common/rtusb_data.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/rtusb_data.c"
diff --git a/drivers/staging/rt3070/common/rtusb_io.c b/drivers/staging/rt3070/common/rtusb_io.c
deleted file mode 100644
index 20a0b56..0000000
--- a/drivers/staging/rt3070/common/rtusb_io.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/rtusb_io.c"
diff --git a/drivers/staging/rt3070/common/spectrum.c b/drivers/staging/rt3070/common/spectrum.c
deleted file mode 100644
index de3b949..0000000
--- a/drivers/staging/rt3070/common/spectrum.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/common/spectrum.c"
diff --git a/drivers/staging/rt3070/dfs.h b/drivers/staging/rt3070/dfs.h
deleted file mode 100644
index b9c92e3..0000000
--- a/drivers/staging/rt3070/dfs.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/dfs.h"
diff --git a/drivers/staging/rt3070/link_list.h b/drivers/staging/rt3070/link_list.h
deleted file mode 100644
index 5550b2f..0000000
--- a/drivers/staging/rt3070/link_list.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/link_list.h"
diff --git a/drivers/staging/rt3070/md5.h b/drivers/staging/rt3070/md5.h
deleted file mode 100644
index 1042a99..0000000
--- a/drivers/staging/rt3070/md5.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/md5.h"
diff --git a/drivers/staging/rt3070/mlme.h b/drivers/staging/rt3070/mlme.h
deleted file mode 100644
index 773c0ed..0000000
--- a/drivers/staging/rt3070/mlme.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/mlme.h"
diff --git a/drivers/staging/rt3070/oid.h b/drivers/staging/rt3070/oid.h
deleted file mode 100644
index cbf16a8..0000000
--- a/drivers/staging/rt3070/oid.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/oid.h"
diff --git a/drivers/staging/rt3070/rt2870.h b/drivers/staging/rt3070/rt2870.h
deleted file mode 100644
index 16d8717..0000000
--- a/drivers/staging/rt3070/rt2870.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rt2870.h"
diff --git a/drivers/staging/rt3070/rt28xx.h b/drivers/staging/rt3070/rt28xx.h
deleted file mode 100644
index c47ddc8..0000000
--- a/drivers/staging/rt3070/rt28xx.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rt28xx.h"
diff --git a/drivers/staging/rt3070/rt_config.h b/drivers/staging/rt3070/rt_config.h
deleted file mode 100644
index 3e8fcbd..0000000
--- a/drivers/staging/rt3070/rt_config.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rt_config.h"
diff --git a/drivers/staging/rt3070/rt_linux.c b/drivers/staging/rt3070/rt_linux.c
deleted file mode 100644
index 6185f2e..0000000
--- a/drivers/staging/rt3070/rt_linux.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rt_linux.c"
diff --git a/drivers/staging/rt3070/rt_linux.h b/drivers/staging/rt3070/rt_linux.h
deleted file mode 100644
index 9f7efee..0000000
--- a/drivers/staging/rt3070/rt_linux.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/rt_linux.h"
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c
deleted file mode 100644
index c8bcd40..0000000
--- a/drivers/staging/rt3070/rt_main_dev.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rt_main_dev.c"
diff --git a/drivers/staging/rt3070/rt_profile.c b/drivers/staging/rt3070/rt_profile.c
deleted file mode 100644
index ab9eb1d..0000000
--- a/drivers/staging/rt3070/rt_profile.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rt_profile.c"
diff --git a/drivers/staging/rt3070/rtmp.h b/drivers/staging/rt3070/rtmp.h
deleted file mode 100644
index 5390ca3..0000000
--- a/drivers/staging/rt3070/rtmp.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rtmp.h"
diff --git a/drivers/staging/rt3070/rtmp_ckipmic.h b/drivers/staging/rt3070/rtmp_ckipmic.h
deleted file mode 100644
index 4956093..0000000
--- a/drivers/staging/rt3070/rtmp_ckipmic.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rtmp_ckipmic.h"
diff --git a/drivers/staging/rt3070/rtmp_def.h b/drivers/staging/rt3070/rtmp_def.h
deleted file mode 100644
index fa3b6b5..0000000
--- a/drivers/staging/rt3070/rtmp_def.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rtmp_def.h"
diff --git a/drivers/staging/rt3070/rtmp_type.h b/drivers/staging/rt3070/rtmp_type.h
deleted file mode 100644
index 42384e5..0000000
--- a/drivers/staging/rt3070/rtmp_type.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/rtmp_type.h"
diff --git a/drivers/staging/rt3070/spectrum.h b/drivers/staging/rt3070/spectrum.h
deleted file mode 100644
index 1ca9c25..0000000
--- a/drivers/staging/rt3070/spectrum.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/spectrum.h"
diff --git a/drivers/staging/rt3070/spectrum_def.h b/drivers/staging/rt3070/spectrum_def.h
deleted file mode 100644
index 892bc88..0000000
--- a/drivers/staging/rt3070/spectrum_def.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/spectrum_def.h"
diff --git a/drivers/staging/rt3070/sta/aironet.c b/drivers/staging/rt3070/sta/aironet.c
deleted file mode 100644
index 48fcc46..0000000
--- a/drivers/staging/rt3070/sta/aironet.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/aironet.c"
diff --git a/drivers/staging/rt3070/sta/assoc.c b/drivers/staging/rt3070/sta/assoc.c
deleted file mode 100644
index 1987a2a..0000000
--- a/drivers/staging/rt3070/sta/assoc.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/assoc.c"
diff --git a/drivers/staging/rt3070/sta/auth.c b/drivers/staging/rt3070/sta/auth.c
deleted file mode 100644
index d551982..0000000
--- a/drivers/staging/rt3070/sta/auth.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/auth.c"
diff --git a/drivers/staging/rt3070/sta/auth_rsp.c b/drivers/staging/rt3070/sta/auth_rsp.c
deleted file mode 100644
index c4ea2dc..0000000
--- a/drivers/staging/rt3070/sta/auth_rsp.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/auth_rsp.c"
diff --git a/drivers/staging/rt3070/sta/connect.c b/drivers/staging/rt3070/sta/connect.c
deleted file mode 100644
index d77802c..0000000
--- a/drivers/staging/rt3070/sta/connect.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "../../rt2870/sta/connect.c"
-
diff --git a/drivers/staging/rt3070/sta/rtmp_data.c b/drivers/staging/rt3070/sta/rtmp_data.c
deleted file mode 100644
index bf09120..0000000
--- a/drivers/staging/rt3070/sta/rtmp_data.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/rtmp_data.c"
diff --git a/drivers/staging/rt3070/sta/sanity.c b/drivers/staging/rt3070/sta/sanity.c
deleted file mode 100644
index b495477..0000000
--- a/drivers/staging/rt3070/sta/sanity.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/sanity.c"
diff --git a/drivers/staging/rt3070/sta/sync.c b/drivers/staging/rt3070/sta/sync.c
deleted file mode 100644
index b7b8eb4..0000000
--- a/drivers/staging/rt3070/sta/sync.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/sync.c"
diff --git a/drivers/staging/rt3070/sta/wpa.c b/drivers/staging/rt3070/sta/wpa.c
deleted file mode 100644
index 95543bb..0000000
--- a/drivers/staging/rt3070/sta/wpa.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../../rt2870/sta/wpa.c"
diff --git a/drivers/staging/rt3070/sta_ioctl.c b/drivers/staging/rt3070/sta_ioctl.c
deleted file mode 100644
index ac56507..0000000
--- a/drivers/staging/rt3070/sta_ioctl.c
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/sta_ioctl.c"
diff --git a/drivers/staging/rt3070/wpa.h b/drivers/staging/rt3070/wpa.h
deleted file mode 100644
index 94bb232..0000000
--- a/drivers/staging/rt3070/wpa.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../rt2870/wpa.h"
diff --git a/drivers/staging/rt3090/Kconfig b/drivers/staging/rt3090/Kconfig
new file mode 100644
index 0000000..255e8ea
--- /dev/null
+++ b/drivers/staging/rt3090/Kconfig
@@ -0,0 +1,5 @@
+config RT3090
+	tristate "Ralink 3090 wireless support"
+	depends on PCI && X86 && WLAN_80211
+	---help---
+	  This is an experimental driver for the Ralink 3090 wireless chip.
diff --git a/drivers/staging/rt3090/Makefile b/drivers/staging/rt3090/Makefile
new file mode 100644
index 0000000..995491c
--- /dev/null
+++ b/drivers/staging/rt3090/Makefile
@@ -0,0 +1,80 @@
+obj-$(CONFIG_RT3090)	+= rt3090sta.o
+
+include drivers/staging/rt3090/config.mk
+
+rt3090sta-objs := \
+	common/crypt_md5.o \
+	common/crypt_sha2.o \
+	common/crypt_hmac.o \
+	common/mlme.o \
+	common/cmm_wep.o \
+	common/action.o \
+	common/cmm_data.o \
+	common/rtmp_init.o \
+	common/cmm_tkip.o \
+	common/cmm_aes.o \
+	common/cmm_sync.o \
+	common/eeprom.o \
+	common/cmm_sanity.o \
+	common/cmm_info.o \
+	common/cmm_cfg.o \
+	common/cmm_wpa.o \
+	common/dfs.o \
+	common/spectrum.o \
+	common/rtmp_timer.o \
+	common/rt_channel.o \
+	common/cmm_profile.o \
+	common/cmm_asic.o \
+	sta/assoc.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
+
+#ifdef DOT11_N_SUPPORT
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+rt3090sta-objs += \
+	common/ba_action.o
+endif
+#endif // DOT11_N_SUPPORT //
+
+#ifdef ETH_CONVERT
+ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
+rt3090sta-objs += \
+	common/cmm_mat.o \
+	common/cmm_mat_iparp.o \
+	common/cmm_mat_pppoe.o \
+	common/cmm_mat_ipv6.o
+endif
+#endif // ETH_CONVERT //
+
+ifeq ($(HAS_BLOCK_NET_IF),y)
+rt3090sta-objs += common/netif_block.o
+endif
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+rt3090sta-objs += sta/dls.o
+endif
+
+rt3090sta-objs += \
+	pci_main_dev.o \
+	rt_pci_rbus.o \
+	common/cmm_mac_pci.o \
+	common/cmm_data_pci.o \
+	common/ee_prom.o \
+	common/ee_efuse.o \
+	common/rtmp_mcu.o \
+	chips/rt30xx.o \
+	common/rt_rf.o \
+	chips/rt3090.o
+
+ifeq ($(HAS_ATE),y)
+rt3090sta-objs += rt_ate.o
+endif
diff --git a/drivers/staging/rt3090/action.h b/drivers/staging/rt3090/action.h
new file mode 100644
index 0000000..ac0a0a3
--- /dev/null
+++ b/drivers/staging/rt3090/action.h
@@ -0,0 +1,66 @@
+/*
+ *************************************************************************
+ * 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/rt3090/ap.h b/drivers/staging/rt3090/ap.h
new file mode 100644
index 0000000..e894303
--- /dev/null
+++ b/drivers/staging/rt3090/ap.h
@@ -0,0 +1,512 @@
+/*
+ *************************************************************************
+ * 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__
+
+
+// =============================================================
+//      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);
+
+
+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 APCls2errAction(
+    IN PRTMP_ADAPTER pAd,
+	IN	ULONG Wcid,
+    IN	PHEADER_802_11	pHeader);
+
+// ap_connect.c
+
+
+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,
+	IN	PNDIS_802_11_SSID	pSsid,
+	IN	UCHAR				ScanType);
+
+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 WpaStateMachineInit(
+    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);
+
+
+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);
+
+// 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,
+    OUT 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);
+#if defined(RT30xx) || defined(RT305x)
+VOID EnableAPMIMOPS(
+    IN PRTMP_ADAPTER pAd);
+
+VOID DisableAPMIMOPS(
+    IN PRTMP_ADAPTER pAd);
+#endif
+#endif  // __AP_H__
diff --git a/drivers/staging/rt3090/ap_apcli.h b/drivers/staging/rt3090/ap_apcli.h
new file mode 100644
index 0000000..d363c36
--- /dev/null
+++ b/drivers/staging/rt3090/ap_apcli.h
@@ -0,0 +1,276 @@
+/*
+ *************************************************************************
+ * 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_apcli.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Shiang, Fonchi    02-13-2007      created
+*/
+
+#ifndef _AP_APCLI_H_
+#define _AP_APCLI_H_
+
+#ifdef APCLI_SUPPORT
+
+#include "rtmp.h"
+
+#define AUTH_TIMEOUT	300         // unit: msec
+#define ASSOC_TIMEOUT	300         // unit: msec
+//#define JOIN_TIMEOUT	2000        // unit: msec // not used in Ap-client mode, remove it
+#define PROBE_TIMEOUT	1000        // unit: msec
+
+#define APCLI_ROOT_BSSID_GET(pAd, wcid) ((pAd)->MacTab.Content[(wcid)].Addr)
+#define APCLI_IF_UP_CHECK(pAd, ifidx) ((pAd)->ApCfg.ApCliTab[(ifidx)].dev->flags & IFF_UP)
+
+/* sanity check for apidx */
+#define APCLI_MR_APIDX_SANITY_CHECK(idx) \
+{ \
+	if ((idx) >= MAX_APCLI_NUM) \
+	{ \
+		(idx) = 0; \
+		DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apcli-idx > MAX_APCLI_NUM!\n", __FUNCTION__)); \
+	} \
+}
+
+typedef struct _APCLI_MLME_JOIN_REQ_STRUCT {
+	UCHAR	Bssid[MAC_ADDR_LEN];
+	UCHAR	SsidLen;
+	UCHAR	Ssid[MAX_LEN_OF_SSID];
+} APCLI_MLME_JOIN_REQ_STRUCT;
+
+typedef struct _STA_CTRL_JOIN_REQ_STRUCT {
+	USHORT	Status;
+} APCLI_CTRL_MSG_STRUCT, *PSTA_CTRL_MSG_STRUCT;
+
+BOOLEAN isValidApCliIf(
+	SHORT ifIndex);
+
+//
+// Private routines in apcli_ctrl.c
+//
+VOID ApCliCtrlStateMachineInit(
+	IN PRTMP_ADAPTER pAd,
+	IN STATE_MACHINE_EX *Sm,
+	OUT STATE_MACHINE_FUNC_EX Trans[]);
+
+//
+// Private routines in apcli_sync.c
+//
+VOID ApCliSyncStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE_EX *Sm,
+    OUT STATE_MACHINE_FUNC_EX Trans[]);
+
+//
+// Private routines in apcli_auth.c
+//
+VOID ApCliAuthStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE_EX *Sm,
+    OUT STATE_MACHINE_FUNC_EX Trans[]);
+
+//
+// Private routines in apcli_assoc.c
+//
+VOID ApCliAssocStateMachineInit(
+    IN PRTMP_ADAPTER pAd,
+    IN STATE_MACHINE_EX *Sm,
+    OUT STATE_MACHINE_FUNC_EX Trans[]);
+
+MAC_TABLE_ENTRY *ApCliTableLookUpByWcid(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR wcid,
+	IN PUCHAR pAddrs);
+
+
+BOOLEAN ApCliAllowToSendPacket(
+	IN RTMP_ADAPTER *pAd,
+	IN PNDIS_PACKET pPacket,
+	OUT UCHAR		*pWcid);
+
+BOOLEAN		ApCliValidateRSNIE(
+	IN		PRTMP_ADAPTER	pAd,
+	IN		PEID_STRUCT	pEid_ptr,
+	IN		USHORT			eid_len,
+	IN		USHORT			idx);
+
+VOID RT28xx_ApCli_Init(
+	IN PRTMP_ADAPTER	pAd,
+	IN PNET_DEV			pPhyNetDev);
+
+VOID RT28xx_ApCli_Close(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RT28xx_ApCli_Remove(
+	IN PRTMP_ADAPTER	pAd);
+
+
+VOID RT28xx_ApCli_Remove(
+	IN PRTMP_ADAPTER ad_p);
+
+INT ApCliIfLookUp(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pAddr);
+
+INT ApCli_VirtualIF_Open(
+	IN	PNET_DEV	dev_p);
+
+INT ApCli_VirtualIF_Close(
+	IN	PNET_DEV	dev_p);
+
+INT ApCli_VirtualIF_PacketSend(
+	IN PNDIS_PACKET		skb_p,
+	IN PNET_DEV			dev_p);
+
+INT ApCli_VirtualIF_Ioctl(
+	IN PNET_DEV				dev_p,
+	IN OUT struct ifreq	*rq_p,
+	IN INT cmd);
+
+
+VOID ApCliMgtMacHeaderInit(
+    IN	PRTMP_ADAPTER	pAd,
+    IN OUT PHEADER_802_11 pHdr80211,
+    IN UCHAR SubType,
+    IN UCHAR ToDs,
+    IN PUCHAR pDA,
+    IN PUCHAR pBssid,
+    IN USHORT ifIndex);
+
+#ifdef DOT11_N_SUPPORT
+BOOLEAN ApCliCheckHt(
+	IN		PRTMP_ADAPTER		pAd,
+	IN		USHORT				IfIndex,
+	IN OUT	HT_CAPABILITY_IE	*pHtCapability,
+	IN OUT	ADD_HT_INFO_IE		*pAddHtInfo);
+#endif // DOT11_N_SUPPORT //
+
+BOOLEAN ApCliLinkUp(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR ifIndex);
+
+VOID ApCliLinkDown(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR ifIndex);
+
+VOID ApCliIfUp(
+	IN PRTMP_ADAPTER pAd);
+
+VOID ApCliIfDown(
+	IN PRTMP_ADAPTER pAd);
+
+VOID ApCliIfMonitor(
+	IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ApCliMsgTypeSubst(
+	IN PRTMP_ADAPTER  pAd,
+	IN PFRAME_802_11 pFrame,
+	OUT INT *Machine,
+	OUT INT *MsgType);
+
+BOOLEAN preCheckMsgTypeSubset(
+	IN PRTMP_ADAPTER  pAd,
+	IN PFRAME_802_11 pFrame,
+	OUT INT *Machine,
+	OUT INT *MsgType);
+
+BOOLEAN ApCliPeerAssocRspSanity(
+    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);
+
+VOID	ApCliPeerPairMsg1Action(
+	IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID	ApCliPeerPairMsg3Action(
+	IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+VOID	ApCliPeerGroupMsg1Action(
+	IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+BOOLEAN ApCliCheckRSNIE(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pData,
+	IN  UCHAR           DataLen,
+	IN  MAC_TABLE_ENTRY *pEntry,
+	OUT	UCHAR			*Offset);
+
+BOOLEAN ApCliParseKeyData(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pKeyData,
+	IN  UCHAR           KeyDataLen,
+	IN  MAC_TABLE_ENTRY *pEntry,
+	IN	UCHAR			IfIdx,
+	IN	UCHAR			bPairewise);
+
+BOOLEAN  ApCliHandleRxBroadcastFrame(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	RX_BLK			*pRxBlk,
+	IN  MAC_TABLE_ENTRY *pEntry,
+	IN	UCHAR			FromWhichBSSID);
+
+VOID APCliUpdatePairwiseKeyTable(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			*KeyRsc,
+	IN  MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN APCliUpdateSharedKeyTable(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR          pKey,
+	IN  UCHAR           KeyLen,
+	IN	UCHAR			DefaultKeyIdx,
+	IN  MAC_TABLE_ENTRY *pEntry);
+
+#endif // APCLI_SUPPORT //
+
+#endif /* _AP_APCLI_H_ */
diff --git a/drivers/staging/rt3090/ap_autoChSel.h b/drivers/staging/rt3090/ap_autoChSel.h
new file mode 100644
index 0000000..46881ff
--- /dev/null
+++ b/drivers/staging/rt3090/ap_autoChSel.h
@@ -0,0 +1,79 @@
+/*
+ *************************************************************************
+ * 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_autoChSel.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+
+#include "ap_autoChSel_cmm.h"
+
+#ifndef __AUTOCHSELECT_H__
+#define __AUTOCHSELECT_H__
+
+#ifdef AUTO_CH_SELECT_ENHANCE
+#define AP_AUTO_CH_SEL(__P, __O)	New_APAutoSelectChannel((__P), (__O))
+#else
+#define AP_AUTO_CH_SEL(__P, __O)	APAutoSelectChannel((__P), (__O))
+#endif
+
+
+ULONG AutoChBssInsertEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pBssid,
+	IN CHAR Ssid[],
+	IN UCHAR SsidLen,
+	IN UCHAR ChannelNo,
+	IN UCHAR ExtChOffset,
+	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,
+	IN BOOLEAN Optimal);
+
+UCHAR APAutoSelectChannel(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN Optimal);
+
+#endif // __AUTOCHSELECT_H__ //
diff --git a/drivers/staging/rt3090/ap_autoChSel_cmm.h b/drivers/staging/rt3090/ap_autoChSel_cmm.h
new file mode 100644
index 0000000..ad77ec1
--- /dev/null
+++ b/drivers/staging/rt3090/ap_autoChSel_cmm.h
@@ -0,0 +1,66 @@
+/*
+ *************************************************************************
+ * 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_autoChSel_cmm.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+
+
+#ifndef __AUTOCHSELECT_CMM_H__
+#define __AUTOCHSELECT_CMM_H__
+
+#define RSSI_TO_DBM_OFFSET 120 // RSSI-115 = dBm
+
+
+typedef struct {
+	ULONG dirtyness[MAX_NUM_OF_CHANNELS+1];
+	ULONG max_rssi[MAX_NUM_OF_CHANNELS+1];
+	ULONG total_rssi[MAX_NUM_OF_CHANNELS+1];
+	UINT32 FalseCCA[MAX_NUM_OF_CHANNELS+1];
+} CHANNELINFO, *PCHANNELINFO;
+
+typedef struct {
+	UCHAR Bssid[MAC_ADDR_LEN];
+	UCHAR SsidLen;
+	CHAR Ssid[MAX_LEN_OF_SSID];
+	UCHAR Channel;
+	UCHAR ExtChOffset;
+	UCHAR Rssi;
+} BSSENTRY, *PBSSENTRY;
+
+typedef struct {
+	UCHAR BssNr;
+	BSSENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
+} BSSINFO, *PBSSINFO;
+
+#endif // __AUTOCHSELECT_CMM_H__ //
diff --git a/drivers/staging/rt3090/ap_cfg.h b/drivers/staging/rt3090/ap_cfg.h
new file mode 100644
index 0000000..7c99423
--- /dev/null
+++ b/drivers/staging/rt3090/ap_cfg.h
@@ -0,0 +1,118 @@
+/*
+ *************************************************************************
+ * 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_cfg.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+#ifndef __AP_CFG_H__
+#define __AP_CFG_H__
+
+
+#include "rt_config.h"
+
+INT RTMPAPPrivIoctlSet(
+	IN RTMP_ADAPTER *pAd,
+	IN struct iwreq *pIoctlCmdStr);
+
+INT RTMPAPPrivIoctlShow(
+	IN RTMP_ADAPTER *pAd,
+	IN struct iwreq *pIoctlCmdStr);
+
+INT RTMPAPSetInformation(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	OUT	struct iwreq	*rq,
+	IN	INT				cmd);
+
+INT RTMPAPQueryInformation(
+	IN	PRTMP_ADAPTER       pAd,
+	IN	OUT	struct iwreq    *rq,
+	IN	INT                 cmd);
+
+VOID RTMPIoctlStatistics(
+	IN PRTMP_ADAPTER pAd,
+	IN struct iwreq *wrq);
+
+VOID RTMPIoctlGetMacTable(
+	IN PRTMP_ADAPTER pAd,
+	IN struct iwreq *wrq);
+
+#ifdef DBG
+VOID RTMPAPIoctlBBP(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  struct iwreq    *wrq);
+
+VOID RTMPAPIoctlMAC(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  struct iwreq    *wrq);
+
+VOID RTMPAPIoctlE2PROM(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  struct iwreq    *wrq);
+
+#ifdef RTMP_RF_RW_SUPPORT
+VOID RTMPAPIoctlRF(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq);
+#endif // RTMP_RF_RW_SUPPORT //
+
+#endif // DBG //
+
+VOID RT28XX_IOCTL_MaxRateGet(
+	IN	RTMP_ADAPTER			*pAd,
+	IN	PHTTRANSMIT_SETTING	pHtPhyMode,
+	OUT	UINT32					*pRate);
+
+
+#ifdef DOT11_N_SUPPORT
+VOID RTMPIoctlQueryBaTable(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	struct iwreq	*wrq);
+#endif // DOT11_N_SUPPORT //
+
+VOID RTMPIoctlStaticWepCopy(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	struct iwreq	*wrq);
+
+VOID RTMPIoctlRadiusData(
+	IN PRTMP_ADAPTER	pAd,
+	IN struct iwreq		*wrq);
+
+VOID RTMPIoctlAddWPAKey(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	struct iwreq	*wrq);
+
+VOID RTMPIoctlAddPMKIDCache(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	struct iwreq	*wrq);
+
+#endif // __AP_CFG_H__ //
diff --git a/drivers/staging/rt3090/ap_ids.h b/drivers/staging/rt3090/ap_ids.h
new file mode 100644
index 0000000..cf8797f
--- /dev/null
+++ b/drivers/staging/rt3090/ap_ids.h
@@ -0,0 +1,82 @@
+/*
+ *************************************************************************
+ * 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_ids.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+
+VOID RTMPIdsPeriodicExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+BOOLEAN RTMPSpoofedMgmtDetection(
+	IN PRTMP_ADAPTER	pAd,
+	IN PHEADER_802_11	pHeader,
+	IN CHAR				Rssi0,
+	IN CHAR				Rssi1,
+	IN CHAR				Rssi2);
+
+VOID RTMPConflictSsidDetection(
+	IN PRTMP_ADAPTER	pAd,
+	IN PUCHAR			pSsid,
+	IN UCHAR			SsidLen,
+	IN CHAR				Rssi0,
+	IN CHAR				Rssi1,
+	IN CHAR				Rssi2);
+
+BOOLEAN RTMPReplayAttackDetection(
+	IN PRTMP_ADAPTER	pAd,
+	IN PUCHAR			pAddr2,
+	IN CHAR				Rssi0,
+	IN CHAR				Rssi1,
+	IN CHAR				Rssi2);
+
+VOID RTMPUpdateStaMgmtCounter(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			type);
+
+VOID RTMPClearAllIdsCounter(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RTMPIdsStart(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RTMPIdsStop(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID rtmp_read_ids_from_file(
+			IN  PRTMP_ADAPTER pAd,
+			char *tmpbuf,
+			char *buffer);
diff --git a/drivers/staging/rt3090/ap_mbss.h b/drivers/staging/rt3090/ap_mbss.h
new file mode 100644
index 0000000..f78556c
--- /dev/null
+++ b/drivers/staging/rt3090/ap_mbss.h
@@ -0,0 +1,72 @@
+/*
+ *************************************************************************
+ * 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_mbss.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+
+#ifndef MODULE_MBSS
+
+#define MBSS_EXTERN    extern
+
+#else
+
+#define MBSS_EXTERN
+
+#endif // MODULE_MBSS //
+
+
+/* Public function list */
+MBSS_EXTERN VOID RT28xx_MBSS_Init(
+	IN PRTMP_ADAPTER ad_p,
+	IN PNET_DEV main_dev_p);
+
+MBSS_EXTERN VOID RT28xx_MBSS_Close(
+	IN PRTMP_ADAPTER ad_p);
+
+MBSS_EXTERN VOID RT28xx_MBSS_Remove(
+	IN PRTMP_ADAPTER ad_p);
+
+INT MBSS_VirtualIF_Open(
+	IN	PNET_DEV			dev_p);
+INT MBSS_VirtualIF_Close(
+	IN	PNET_DEV			dev_p);
+INT MBSS_VirtualIF_PacketSend(
+	IN PNDIS_PACKET			skb_p,
+	IN PNET_DEV				dev_p);
+INT MBSS_VirtualIF_Ioctl(
+	IN PNET_DEV				dev_p,
+	IN OUT struct ifreq	*rq_p,
+	IN INT cmd);
+
+/* End of ap_mbss.h */
diff --git a/drivers/staging/rt3090/ap_uapsd.h b/drivers/staging/rt3090/ap_uapsd.h
new file mode 100644
index 0000000..d49a9e7
--- /dev/null
+++ b/drivers/staging/rt3090/ap_uapsd.h
@@ -0,0 +1,636 @@
+/*
+ *************************************************************************
+ * 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_uapsd.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+
+/* only for UAPSD_TIMING_RECORD */
+
+//#define UAPSD_TIMING_RECORD_FUNC
+
+#define UAPSD_TIMING_RECORD_MAX				1000
+#define UAPSD_TIMING_RECORD_DISPLAY_TIMES	10
+
+#define UAPSD_TIMING_RECORD_ISR				1
+#define UAPSD_TIMING_RECORD_TASKLET			2
+#define UAPSD_TIMING_RECORD_TRG_RCV			3
+#define UAPSD_TIMING_RECORD_MOVE2TX			4
+#define UAPSD_TIMING_RECORD_TX2AIR			5
+
+#define UAPSD_TIMING_CTRL_STOP				0
+#define UAPSD_TIMING_CTRL_START				1
+#define UAPSD_TIMING_CTRL_SUSPEND			2
+
+#define UAPSD_TIMESTAMP_GET(__pAd, __TimeStamp)			\
+	{													\
+		UINT32 __CSR=0;	UINT64 __Value64;				\
+		RTMP_IO_READ32((__pAd), TSF_TIMER_DW0, &__CSR);	\
+		__TimeStamp = (UINT64)__CSR;					\
+		RTMP_IO_READ32((__pAd), TSF_TIMER_DW1, &__CSR);	\
+		__Value64 = (UINT64)__CSR;						\
+		__TimeStamp |= (__Value64 << 32);				\
+	}
+
+#ifdef LINUX
+#define UAPSD_TIME_GET(__pAd, __Time)					\
+		__Time = jiffies
+#endif // LINUX //
+
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+#define UAPSD_TIMING_RECORD_START()				\
+	UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_START);
+#define UAPSD_TIMING_RECORD_STOP()				\
+	UAPSD_TimingRecordCtrl(UAPSD_TIMING_CTRL_STOP);
+#define UAPSD_TIMING_RECORD(__pAd, __Type)		\
+	UAPSD_TimingRecord(__pAd, __Type);
+#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex)	\
+	UAPSD_TimeingRecordLoopIndex(__LoopIndex);
+#else
+
+#define UAPSD_TIMING_RECORD_START()
+#define UAPSD_TIMING_RECORD_STOP()
+#define UAPSD_TIMING_RECORD(__pAd, __type)
+#define UAPSD_TIMING_RECORD_INDEX(__LoopIndex)
+#endif // UAPSD_TIMING_RECORD_FUNC //
+
+
+#ifndef MODULE_WMM_UAPSD
+
+#define UAPSD_EXTERN			extern
+
+/* Public Marco list */
+
+/*
+	Init some parameters in packet structure for QoS Null frame;
+	purpose: is for management frame tx done use
+*/
+#define UAPSD_MR_QOS_NULL_HANDLE(__pAd, __pData, __pPacket)					\
+	{																		\
+		PHEADER_802_11 __pHeader = (PHEADER_802_11)(__pData);				\
+		MAC_TABLE_ENTRY *__pEntry;											\
+		if (__pHeader->FC.SubType == SUBTYPE_QOS_NULL)						\
+		{																	\
+			RTMP_SET_PACKET_QOS_NULL((__pPacket));							\
+			__pEntry = MacTableLookup((__pAd), __pHeader->Addr1);			\
+			if (__pEntry != NULL)											\
+			{																\
+				RTMP_SET_PACKET_WCID((__pPacket), __pEntry->Aid);			\
+			}																\
+		}																	\
+		else																\
+		{																	\
+			RTMP_SET_PACKET_NON_QOS_NULL((__pPacket));						\
+		}																	\
+	}
+
+/*
+	Init MAC entry UAPSD parameters;
+	purpose: initialize UAPSD PS queue and control parameters
+*/
+#define UAPSD_MR_ENTRY_INIT(__pEntry)										\
+	{																		\
+		UINT16	__IdAc;														\
+		for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++)						\
+			InitializeQueueHeader(&(__pEntry)->UAPSDQueue[__IdAc]);			\
+		(__pEntry)->UAPSDTxNum = 0;											\
+		(__pEntry)->pUAPSDEOSPFrame = NULL;									\
+		(__pEntry)->bAPSDFlagSPStart = 0;									\
+		(__pEntry)->bAPSDFlagEOSPOK = 0;									\
+		(__pEntry)->MaxSPLength = 0;										\
+	}
+
+/*
+	Reset MAC entry UAPSD parameters;
+   purpose: clean all UAPSD PS queue; release the EOSP frame if exists;
+			reset control parameters
+*/
+#define UAPSD_MR_ENTRY_RESET(__pAd, __pEntry)								\
+	{																		\
+		MAC_TABLE_ENTRY *__pSta;											\
+		UINT32 __IdAc;														\
+		__pSta = (__pEntry);												\
+		/* clear all U-APSD queues */										\
+		for(__IdAc=0; __IdAc<WMM_NUM_OF_AC; __IdAc++)						\
+			APCleanupPsQueue((__pAd), &__pSta->UAPSDQueue[__IdAc]);		\
+		/* clear EOSP frame */												\
+		__pSta->UAPSDTxNum = 0;												\
+		if (__pSta->pUAPSDEOSPFrame != NULL) {								\
+			RELEASE_NDIS_PACKET((__pAd),									\
+							QUEUE_ENTRY_TO_PACKET(__pSta->pUAPSDEOSPFrame),	\
+							NDIS_STATUS_FAILURE);							\
+			__pSta->pUAPSDEOSPFrame = NULL; }								\
+		__pSta->bAPSDFlagSPStart = 0;										\
+		__pSta->bAPSDFlagEOSPOK = 0; }
+
+/*
+	Enable or disable UAPSD flag in WMM element in beacon frame;
+	purpose: set UAPSD enable/disable bit
+*/
+#define UAPSD_MR_IE_FILL(__QosCtrlField, __pAd)								\
+		(__QosCtrlField) |= ((__pAd)->CommonCfg.bAPSDCapable) ? 0x80 : 0x00;
+
+/*
+	Check if we do NOT need to control TIM bit for the station;
+	note: we control TIM bit only when all AC are UAPSD AC
+*/
+#define UAPSD_MR_IS_NOT_TIM_BIT_NEEDED_HANDLED(__pMacEntry, __QueIdx)		\
+		(CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) && \
+			(!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VO] ||			\
+			!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_VI] ||			\
+			!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BE] ||			\
+			!(__pMacEntry)->bAPSDDeliverEnabledPerAC[QID_AC_BK]) &&			\
+		(__pMacEntry)->bAPSDDeliverEnabledPerAC[__QueIdx])
+
+/* check if the AC is UAPSD delivery-enabled AC */
+#define UAPSD_MR_IS_UAPSD_AC(__pMacEntry, __AcId)							\
+		(CLIENT_STATUS_TEST_FLAG((__pMacEntry), fCLIENT_STATUS_APSD_CAPABLE) &&	\
+			((0 <= (__AcId)) && ((__AcId) < WMM_NUM_OF_AC)) && /* 0 ~ 3 */	\
+			(__pMacEntry)->bAPSDDeliverEnabledPerAC[(__AcId)])
+
+/* check if all AC are UAPSD delivery-enabled AC */
+#define UAPSD_MR_IS_ALL_AC_UAPSD(__FlgIsActive, __pMacEntry)				\
+		(((__FlgIsActive) == FALSE) && ((__pMacEntry)->bAPSDAllAC == 1))
+
+/* suspend SP */
+#define UAPSD_MR_SP_SUSPEND(__pAd)											\
+		(__pAd)->bAPSDFlagSPSuspend = 1;
+
+/* resume SP */
+#define UAPSD_MR_SP_RESUME(__pAd)											\
+		(__pAd)->bAPSDFlagSPSuspend = 0;
+
+/* mark PS poll frame sent in mix mode */
+#ifdef RTMP_MAC_PCI
+/*
+	Note:
+	(1) When SP is not started, try to mark a flag to record if the legacy ps
+		packet is handled in statistics handler;
+	(2) When SP is started, increase the UAPSD count number for the legacy PS.
+*/
+#define UAPSD_MR_MIX_PS_POLL_RCV(__pAd, __pMacEntry)						\
+		if ((__pMacEntry)->bAPSDFlagSpRoughUse == 0)						\
+		{																	\
+			if ((__pMacEntry)->bAPSDFlagSPStart == 0)						\
+			{																\
+				if ((__pMacEntry)->bAPSDFlagLegacySent == 1)				\
+					NICUpdateFifoStaCounters((__pAd));						\
+				(__pMacEntry)->bAPSDFlagLegacySent = 1;						\
+			}																\
+			else															\
+			{																\
+				(__pMacEntry)->UAPSDTxNum ++;								\
+			}																\
+		}
+#endif // RTMP_MAC_PCI //
+
+
+#else
+
+#define UAPSD_EXTERN
+#define UAPSD_QOS_NULL_QUE_ID	0x7f
+
+#ifdef RTMP_MAC_PCI
+/*
+	In RT2870, FIFO counter is for all stations, not for per-entry,
+	so we can not use accurate method in RT2870
+*/
+
+/*
+	Note for SP ACCURATE Mechanism:
+	1. When traffic is busy for the PS station
+		Statistics FIFO counter maybe overflow before we read it, so UAPSD
+		counting mechanism will not accurately.
+
+		Solution:
+		We need to avoid the worse case so we suggest a maximum interval for
+		a SP that the interval between last frame from QAP and data frame from
+		QSTA is larger than UAPSD_EPT_SP_INT.
+
+	2. When traffic use CCK/1Mbps from QAP
+		Statistics FIFO will not count the packet. There are 2 cases:
+		(1) We force to downgrage ARP response & DHCP packet to 1Mbps;
+		(2) After rate switch mechanism, tx rate is fixed to 1Mbps.
+
+		Solution:
+		Use old DMA UAPSD mechanism.
+
+	3. When part of AC uses legacy PS mode
+		Statistics count will inclue packet statistics for legacy PS packets
+		so we can not know which one is UAPSD, which one is legacy.
+
+		Solution:
+		Cound the legacy PS packet.
+
+	4. Check FIFO statistics count in Rx Done function
+		We can not to check TX FIFO statistics count in Rx Done function or
+		the real packet tx/rx sequence will be disarranged.
+
+		Solution:
+		Suspend SP handle before rx done and resume SP handle after rx done.
+*/
+#define UAPSD_SP_ACCURATE		/* use more accurate method to send EOSP */
+#endif // RTMP_MAC_PCI //
+
+#define UAPSD_EPT_SP_INT		(100000/(1000000/OS_HZ)) /* 100ms */
+
+#endif // MODULE_WMM_UAPSD //
+
+
+/* max UAPSD buffer queue size */
+#define MAX_PACKETS_IN_UAPSD_QUEUE	16	/* for each AC = 16*4 = 64 */
+
+
+/* Public function list */
+/*
+========================================================================
+Routine Description:
+	UAPSD Module Init.
+
+Arguments:
+	pAd		Pointer to our adapter
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_Init(
+	IN	PRTMP_ADAPTER		pAd);
+
+
+/*
+========================================================================
+Routine Description:
+	UAPSD Module Release.
+
+Arguments:
+	pAd		Pointer to our adapter
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_Release(
+	IN	PRTMP_ADAPTER		pAd);
+
+
+/*
+========================================================================
+Routine Description:
+	Free all EOSP frames and close all SP.
+
+Arguments:
+	pAd		Pointer to our adapter
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_FreeAll(
+	IN	PRTMP_ADAPTER		pAd);
+
+
+/*
+========================================================================
+Routine Description:
+	Close current Service Period.
+
+Arguments:
+	pAd				Pointer to our adapter
+	pEntry			Close the SP of the entry
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_Close(
+    IN  PRTMP_ADAPTER       pAd,
+	IN	MAC_TABLE_ENTRY		*pEntry);
+
+
+/*
+========================================================================
+Routine Description:
+	Deliver all queued packets.
+
+Arguments:
+	pAd            Pointer to our adapter
+	*pEntry        STATION
+
+Return Value:
+	None
+
+Note:
+	SMP protection by caller for packet enqueue.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_AllPacketDeliver(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	MAC_TABLE_ENTRY		*pEntry);
+
+
+/*
+========================================================================
+Routine Description:
+	Parse the UAPSD field in WMM element in (re)association request frame.
+
+Arguments:
+	pAd				Pointer to our adapter
+	*pEntry			STATION
+	*pElm			QoS information field
+
+Return Value:
+	None
+
+Note:
+	No protection is needed.
+
+	1. Association -> TSPEC:
+		use static UAPSD settings in Association
+		update UAPSD settings in TSPEC
+
+	2. Association -> TSPEC(11r) -> Reassociation:
+		update UAPSD settings in TSPEC
+		backup static UAPSD settings in Reassociation
+
+	3. Association -> Reassociation:
+		update UAPSD settings in TSPEC
+		backup static UAPSD settings in Reassociation
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_AssocParse(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	MAC_TABLE_ENTRY		*pEntry,
+	IN	UCHAR				*pElm);
+
+
+/*
+========================================================================
+Routine Description:
+	Enqueue a UAPSD packet.
+
+Arguments:
+	pAd				Pointer to our adapter
+	*pEntry			STATION
+	pPacket			UAPSD dnlink packet
+	IdAc			UAPSD AC ID (0 ~ 3)
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_PacketEnqueue(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	MAC_TABLE_ENTRY		*pEntry,
+	IN	PNDIS_PACKET		pPacket,
+	IN	UINT32				IdAc);
+
+
+/*
+========================================================================
+Routine Description:
+	Handle QoS Null Frame Tx Done or Management Tx Done interrupt.
+
+Arguments:
+	pAd				Pointer to our adapter
+	pPacket			Completed TX packet
+	pDstMac			Destinated MAC address
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_QoSNullTxMgmtTxDoneHandle(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	PNDIS_PACKET		pPacket,
+	IN	UCHAR				*pDstMac);
+
+
+/*
+========================================================================
+Routine Description:
+	Maintenance our UAPSD PS queue.  Release all queued packet if timeout.
+
+Arguments:
+	pAd				Pointer to our adapter
+	*pEntry			STATION
+
+Return Value:
+	None
+
+Note:
+	If in RT2870, pEntry can not be removed during UAPSD_QueueMaintenance()
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_QueueMaintenance(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	MAC_TABLE_ENTRY		*pEntry);
+
+
+/*
+========================================================================
+Routine Description:
+	Close SP in Tx Done, not Tx DMA Done.
+
+Arguments:
+	pAd            Pointer to our adapter
+	pEntry			destination entry
+	FlgSuccess		0:tx success, 1:tx fail
+
+Return Value:
+    None
+
+Note:
+	For RT28xx series, for packetID=0 or multicast frame, no statistics
+	count can be got, ex: ARP response or DHCP packets, we will use
+	low rate to set (CCK, MCS=0=packetID).
+	So SP will not be close until UAPSD_EPT_SP_INT timeout.
+
+	So if the tx rate is 1Mbps for a entry, we will use DMA done, not
+	use UAPSD_SP_AUE_Handle().
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_AUE_Handle(
+	IN RTMP_ADAPTER		*pAd,
+    IN MAC_TABLE_ENTRY	*pEntry,
+	IN UCHAR			FlgSuccess);
+
+
+/*
+========================================================================
+Routine Description:
+	Close current Service Period.
+
+Arguments:
+	pAd				Pointer to our adapter
+
+Return Value:
+	None
+
+Note:
+	When we receive EOSP frame tx done interrupt and a uplink packet
+	from the station simultaneously, we will regard it as a new trigger
+	frame because the packet is received when EOSP frame tx done interrupt.
+
+	We can not sure the uplink packet is sent after old SP or in the old SP.
+	So we must close the old SP in receive done ISR to avoid the problem.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_CloseInRVDone(
+	IN	PRTMP_ADAPTER		pAd);
+
+
+/*
+========================================================================
+Routine Description:
+	Check if we need to close current SP.
+
+Arguments:
+	pAd				Pointer to our adapter
+	pPacket			Completed TX packet
+	pDstMac			Destinated MAC address
+
+Return Value:
+	None
+
+Note:
+	1. We need to call the function in TxDone ISR.
+	2. SMP protection by caller for packet enqueue.
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_SP_PacketCheck(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	PNDIS_PACKET		pPacket,
+	IN	UCHAR				*pDstMac);
+
+
+#ifdef UAPSD_TIMING_RECORD_FUNC
+/*
+========================================================================
+Routine Description:
+	Enable/Disable Timing Record Function.
+
+Arguments:
+	pAd				Pointer to our adapter
+	Flag			1 (Enable) or 0 (Disable)
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TimingRecordCtrl(
+	IN	UINT32				Flag);
+
+/*
+========================================================================
+Routine Description:
+	Record some timings.
+
+Arguments:
+	pAd				Pointer to our adapter
+	Type			The timing is for what type
+
+Return Value:
+	None
+
+Note:
+	UAPSD_TIMING_RECORD_ISR
+	UAPSD_TIMING_RECORD_TASKLET
+	UAPSD_TIMING_RECORD_TRG_RCV
+	UAPSD_TIMING_RECORD_MOVE2TX
+	UAPSD_TIMING_RECORD_TX2AIR
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TimingRecord(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	UINT32				Type);
+
+/*
+========================================================================
+Routine Description:
+	Record the loop index for received packet handle.
+
+Arguments:
+	pAd				Pointer to our adapter
+	LoopIndex		The RxProcessed in APRxDoneInterruptHandle()
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TimeingRecordLoopIndex(
+	IN	UINT32				LoopIndex);
+#endif // UAPSD_TIMING_RECORD_FUNC //
+
+
+/*
+========================================================================
+Routine Description:
+	Handle UAPSD Trigger Frame.
+
+Arguments:
+	pAd				Pointer to our adapter
+	*pEntry			the source STATION
+	UpOfFrame		the UP of the trigger frame
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+UAPSD_EXTERN VOID UAPSD_TriggerFrameHandle(
+	IN	PRTMP_ADAPTER		pAd,
+	IN	MAC_TABLE_ENTRY		*pEntry,
+	IN	UCHAR				UpOfFrame);
+
+
+
+/* End of ap_uapsd.h */
diff --git a/drivers/staging/rt3090/ap_wds.h b/drivers/staging/rt3090/ap_wds.h
new file mode 100644
index 0000000..efcb107
--- /dev/null
+++ b/drivers/staging/rt3090/ap_wds.h
@@ -0,0 +1,212 @@
+/*
+ *************************************************************************
+ * 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_cfg.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Fonchi    02-13-2007      created
+*/
+
+#ifndef _AP_WDS_H_
+#define _AP_WDS_H_
+
+#define WDS_ENTRY_RETRY_INTERVAL	(100 * OS_HZ / 1000)
+
+
+static inline BOOLEAN WDS_IF_UP_CHECK(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  ULONG ifidx)
+{
+	if ((pAd->flg_wds_init != TRUE) ||
+		(ifidx >= MAX_WDS_ENTRY))
+		return FALSE;
+
+//	if (pAd->WdsTab.WdsEntry[ifidx].dev->flags & IFF_UP)
+// Patch for wds ,when dirver call apmlmeperiod => APMlmeDynamicTxRateSwitching check if wds device ready
+if ((pAd->WdsTab.WdsEntry[ifidx].dev != NULL) && (pAd->WdsTab.WdsEntry[ifidx].dev->flags & IFF_UP))
+		return TRUE;
+
+	return FALSE;
+}
+
+LONG WdsEntryAlloc(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pAddr);
+
+VOID WdsEntryDel(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pAddr);
+
+MAC_TABLE_ENTRY *MacTableInsertWDSEntry(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PUCHAR pAddr,
+	UINT WdsTabIdx);
+
+BOOLEAN MacTableDeleteWDSEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT wcid,
+	IN PUCHAR pAddr);
+
+
+BOOLEAN ApWdsAllowToSendPacket(
+	IN RTMP_ADAPTER *pAd,
+	IN PNDIS_PACKET pPacket,
+	OUT	UCHAR		*pWcid);
+
+MAC_TABLE_ENTRY *WdsTableLookupByWcid(
+    IN  PRTMP_ADAPTER   pAd,
+	IN UCHAR wcid,
+	IN PUCHAR pAddr,
+	IN BOOLEAN bResetIdelCount);
+
+MAC_TABLE_ENTRY *WdsTableLookup(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PUCHAR          pAddr,
+	IN BOOLEAN bResetIdelCount);
+
+MAC_TABLE_ENTRY *FindWdsEntry(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Wcid,
+	IN PUCHAR			pAddr,
+	IN UINT32			PhyMode);
+
+VOID WdsTableMaintenance(
+    IN PRTMP_ADAPTER    pAd);
+
+VOID RT28xx_WDS_Init(
+	IN PRTMP_ADAPTER pAd,
+	IN PNET_DEV net_dev);
+
+VOID RT28xx_WDS_Close(
+	IN PRTMP_ADAPTER pAd);
+
+VOID RT28xx_WDS_Remove(
+	IN PRTMP_ADAPTER pAd);
+
+VOID WdsDown(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateWdsRxWCIDTable(
+	IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateWdsEncryption(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR wcid);
+
+VOID WdsPeerBeaconProc(
+	IN PRTMP_ADAPTER pAd,
+	IN PMAC_TABLE_ENTRY pEntry,
+	IN USHORT CapabilityInfo,
+	IN UCHAR MaxSupportedRateIn500Kbps,
+	IN UCHAR MaxSupportedRateLen,
+	IN BOOLEAN bWmmCapable,
+	IN ULONG ClientRalinkIe,
+	IN HT_CAPABILITY_IE *pHtCapability,
+	IN UCHAR HtCapabilityLen);
+
+VOID APWdsInitialize(
+	IN PRTMP_ADAPTER pAd);
+
+INT	Show_WdsTable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+VOID rtmp_read_wds_from_file(
+			IN  PRTMP_ADAPTER pAd,
+			PSTRING tmpbuf,
+			PSTRING buffer);
+
+VOID WdsPrepareWepKeyFromMainBss(
+	IN  PRTMP_ADAPTER pAd);
+
+INT WdsVirtualIFSendPackets(
+	IN PNDIS_PACKET pSkb,
+	IN PNET_DEV dev);
+
+INT WdsVirtualIF_open(
+	IN PNET_DEV dev);
+
+INT WdsVirtualIF_close(
+	IN PNET_DEV dev);
+
+INT WdsVirtualIF_ioctl(
+	IN PNET_DEV net_dev,
+	IN OUT struct ifreq *rq,
+	IN INT cmd);
+
+/*
+	==========================================================================
+	Description:
+		Check the WDS Entry is valid or not.
+	==========================================================================
+ */
+static inline BOOLEAN ValidWdsEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR WdsIndex)
+{
+	BOOLEAN result;
+	PMAC_TABLE_ENTRY pMacEntry;
+
+	do
+	{
+		if (WdsIndex >= MAX_WDS_ENTRY)
+		{
+			result = FALSE;
+			break;
+		}
+
+		if (pAd->WdsTab.WdsEntry[WdsIndex].Valid != TRUE)
+		{
+			result = FALSE;
+			break;
+		}
+
+		if ((pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID==0)
+			|| (pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID >= MAX_LEN_OF_MAC_TABLE))
+		{
+			result = FALSE;
+			break;
+		}
+
+		pMacEntry = &pAd->MacTab.Content[pAd->WdsTab.WdsEntry[WdsIndex].MacTabMatchWCID];
+		if (pMacEntry->ValidAsWDS != TRUE)
+		{
+			result = FALSE;
+			break;
+		}
+
+		result = TRUE;
+	} while(FALSE);
+
+	return result;
+}
+#endif // _AP_WDS_H_ //
diff --git a/drivers/staging/rt3090/chips/rt3090.c b/drivers/staging/rt3090/chips/rt3090.c
new file mode 100644
index 0000000..35c549d
--- /dev/null
+++ b/drivers/staging/rt3090/chips/rt3090.c
@@ -0,0 +1,123 @@
+/*
+ *************************************************************************
+ * 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:
+	rt3090.c
+
+	Abstract:
+	Specific funcitons and variables for RT3070
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifdef RT3090
+
+#include "../rt_config.h"
+
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif // RTMP_RF_RW_SUPPORT //
+
+
+VOID NICInitRT3090RFRegisters(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_RT3090(pAd))
+	{
+		// Init RF calibration
+		// Driver should toggle RF R30 bit7 before init RF registers
+		UINT32 RfReg = 0, 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);
+
+		// init R24, R31
+		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
+		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
+
+		// RT309x 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, &data);
+			data = ((data & 0xE0FFFFFF) | 0x0D000000);
+			RTMP_IO_WRITE32(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
+		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
+		data &= ~(0x20);
+		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
+
+		// 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);
+		}
+
+		// Driver should set RF R6 bit6 on before calibration
+		RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
+		RfReg |= 0x40;
+		RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
+
+		//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
+		RTMP_IO_READ32(pAd, OPT_14, &data);
+		data |= 0x01;
+		RTMP_IO_WRITE32(pAd, OPT_14, data);
+
+		// set default antenna as main
+		if (pAd->RfIcType == RFIC_3020)
+			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+
+		// add by johnli, RF power sequence setup, load RF normal operation-mode setup
+		RT30xxLoadRFNormalModeSetup(pAd);
+	}
+
+}
+
+#endif // RT3090 //
diff --git a/drivers/staging/rt3090/chips/rt30xx.c b/drivers/staging/rt3090/chips/rt30xx.c
new file mode 100644
index 0000000..9c8ae00
--- /dev/null
+++ b/drivers/staging/rt3090/chips/rt30xx.c
@@ -0,0 +1,525 @@
+/*
+ *************************************************************************
+ * 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:
+	rt30xx.c
+
+	Abstract:
+	Specific funcitons and variables for RT30xx.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+
+#ifdef RT30xx
+
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif // RTMP_RF_RW_SUPPORT //
+
+#include "../rt_config.h"
+
+
+//
+// RF register initialization set
+//
+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},
+};
+
+UCHAR NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR));
+
+
+
+// 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
+// The original name of this function is AsicSetRxAnt(), now change to
+//VOID AsicSetRxAnt(
+VOID RT30xxSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant)
+{
+	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
+#ifdef RTMP_MAC_PCI
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		x |= (EESK);
+		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+#else
+		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0);
+#endif // RTMP_MAC_PCI //
+
+		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
+#ifdef RTMP_MAC_PCI
+		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+		x &= ~(EESK);
+		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+#else
+		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0);
+#endif // RTMP_MAC_PCI //
+		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"));
+	}
+}
+
+
+/*
+	========================================================================
+
+	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) || IS_RT3572(pAd)|| IS_RT3390(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) || IS_RT3572(pAd)|| IS_RT3390(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));
+}
+
+
+// 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);
+
+	/* move to NICInitRT30xxRFRegisters
+	// 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;
+	}
+	// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
+	if (pAd->TxMixerGain24G >= 2)
+	{
+		RFValue &= (~0x7);  // clean bit [2:0]
+		RFValue |= pAd->TxMixerGain24G;
+	}
+	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);
+
+	/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
+	// LDORF_VC, RF R27 register Bit 2 to 0
+	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+	// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
+	// Raising RF voltage is no longer needed for RT3070(F)
+	if (IS_RT3090(pAd))	// RT309x and RT3071/72
+	{
+		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);
+	}
+
+	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
+		IS_RT3572(pAd) ||
+		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+	{
+		{
+			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);
+	}
+
+	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
+		IS_RT3572(pAd) ||
+		IS_RT3390(pAd) ||
+		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+	{
+		{
+			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);
+		}
+	}
+
+	if(IS_RT3572(pAd))
+		RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
+}
+// end johnli
+
+VOID RT30xxHaltAction(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT32		TxPinCfg = 0x00050F0F;
+
+	//
+	// Turn off LNA_PE or TRSW_POL
+	//
+	if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd))
+	{
+		if ((IS_RT3071(pAd) || IS_RT3572(pAd))
+#ifdef RTMP_EFUSE_SUPPORT
+			&& (pAd->bUseEfuse)
+#endif // RTMP_EFUSE_SUPPORT //
+			)
+		{
+			TxPinCfg &= 0xFFFBF0F0; // bit18 off
+		}
+		else
+		{
+			TxPinCfg &= 0xFFFFF0F0;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+}
+
+#endif // RT30xx //
diff --git a/drivers/staging/rt3090/chips/rt3370.c b/drivers/staging/rt3090/chips/rt3370.c
new file mode 100644
index 0000000..38ecb06
--- /dev/null
+++ b/drivers/staging/rt3090/chips/rt3370.c
@@ -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:
+	rt3370.c
+
+	Abstract:
+	Specific funcitons and variables for RT30xx.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifdef RT3370
+
+#include "../rt_config.h"
+
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif // RTMP_RF_RW_SUPPORT //
+
+
+VOID NICInitRT3370RFRegisters(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_RT3090(pAd)||IS_RT3390(pAd)||IS_RT3572(pAd))
+	{
+		// Init RF calibration
+		// Driver should toggle RF R30 bit7 before init RF registers
+		UINT32 RfReg = 0, 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);
+
+		// init R24, R31
+		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
+		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
+
+		if (IS_RT3390(pAd))
+		{
+			// patch LNA_PE_G1 failed issue
+			RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
+			data &= ~(0x20);
+			RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
+
+			// RF registers initialization
+			for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
+			{
+				RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
+			}
+		}
+
+		// patch LNA_PE_G1 failed issue
+		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
+		data &= ~(0x20);
+		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
+
+		// Initialize RF register to default value
+		for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
+		{
+			RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
+		}
+
+		// Driver should set RF R6 bit6 on before calibration
+		RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
+		RfReg |= 0x40;
+		RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
+
+		//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
+		RTMP_IO_READ32(pAd, OPT_14, &data);
+		data |= 0x01;
+		RTMP_IO_WRITE32(pAd, OPT_14, data);
+
+		// set default antenna as main
+		if (pAd->RfIcType == RFIC_3020)
+			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+
+		// add by johnli, RF power sequence setup, load RF normal operation-mode setup
+		RT30xxLoadRFNormalModeSetup(pAd);
+	}
+
+}
+#endif // RT3070 //
diff --git a/drivers/staging/rt3090/chips/rt3390.c b/drivers/staging/rt3090/chips/rt3390.c
new file mode 100644
index 0000000..afed9e7
--- /dev/null
+++ b/drivers/staging/rt3090/chips/rt3390.c
@@ -0,0 +1,122 @@
+/*
+ *************************************************************************
+ * 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:
+	rt3390.c
+
+	Abstract:
+	Specific funcitons and variables for RT30xx.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifdef RT3390
+
+#include "../rt_config.h"
+
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif // RTMP_RF_RW_SUPPORT //
+
+
+VOID NICInitRT3390RFRegisters(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_RT3090(pAd)||IS_RT3390(pAd)||IS_RT3572(pAd))
+	{
+		// Init RF calibration
+		// Driver should toggle RF R30 bit7 before init RF registers
+		UINT32 RfReg = 0, 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);
+
+		// init R24, R31
+		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
+		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
+
+		if (IS_RT3390(pAd))
+		{
+			// patch LNA_PE_G1 failed issue
+			RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
+			data &= ~(0x20);
+			RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
+
+			// RF registers initialization
+			for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
+			{
+				RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
+			}
+		}
+
+		// patch LNA_PE_G1 failed issue
+		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
+		data &= ~(0x20);
+		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
+
+		// Initialize RF register to default value
+		for (i = 0; i < NUM_RF_REG_PARMS_OVER_RT3390; i++)
+		{
+			RT30xxWriteRFRegister(pAd, RFRegTableOverRT3390[i].Register, RFRegTableOverRT3390[i].Value);
+		}
+
+		// Driver should set RF R6 bit6 on before calibration
+		RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
+		RfReg |= 0x40;
+		RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
+
+		//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
+		RTMP_IO_READ32(pAd, OPT_14, &data);
+		data |= 0x01;
+		RTMP_IO_WRITE32(pAd, OPT_14, data);
+
+		// set default antenna as main
+		if (pAd->RfIcType == RFIC_3020)
+			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+
+		// add by johnli, RF power sequence setup, load RF normal operation-mode setup
+		RT33xxLoadRFNormalModeSetup(pAd);
+	}
+
+}
+
+#endif // RT3390 //
diff --git a/drivers/staging/rt3090/chips/rt33xx.c b/drivers/staging/rt3090/chips/rt33xx.c
new file mode 100644
index 0000000..56f376c
--- /dev/null
+++ b/drivers/staging/rt3090/chips/rt33xx.c
@@ -0,0 +1,536 @@
+/*
+ *************************************************************************
+ * 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:
+	rt33xx.c
+
+	Abstract:
+	Specific funcitons and variables for RT30xx.
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+
+#ifdef RT33xx
+
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
+#endif // RTMP_RF_RW_SUPPORT //
+
+#include "../rt_config.h"
+
+
+//
+// RF register initialization set
+//
+REG_PAIR RFRegTableOverRT3390[] = {
+	{RF_R00,		0xA0},
+	{RF_R01,		0xE1},
+	{RF_R02,		0xF1},
+	{RF_R03,		0x62},
+	{RF_R04,		0x40},
+	{RF_R05,		0x8B},
+	{RF_R06,		0x42},
+	{RF_R07,		0x34},
+	{RF_R08,		0x00}, // Read only
+	{RF_R09,		0xC0},
+
+	{RF_R10,		0x61},
+	{RF_R11,		0x21},
+	{RF_R12,		0x3B},
+	{RF_R13,		0xE0},
+	{RF_R14,		0x90},
+	{RF_R15,		0x53},
+	{RF_R16,		0x0E},
+	{RF_R17,		0x94},
+	{RF_R18,		0x5C},
+	{RF_R19,		0x4A},
+
+	{RF_R20,		0xB2},
+	{RF_R21,		0xF6},
+	{RF_R22,		0x00},
+	{RF_R23,		0x14},
+	{RF_R24,		0x08},
+	{RF_R25,		0x3D},
+	{RF_R26,		0x85},
+	{RF_R27,		0x00},
+	{RF_R28,		0x41},
+	{RF_R29,		0x8F},
+	{RF_R30,		0x20},
+	{RF_R31,		0x0F},
+};
+
+UCHAR NUM_RF_REG_PARMS_OVER_RT3390=(sizeof(RFRegTableOverRT3390) / sizeof(REG_PAIR));
+
+
+
+// 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
+// The original name of this function is AsicSetRxAnt(), now change to
+//VOID AsicSetRxAnt(
+
+VOID RT33xxSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant)
+{
+	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"));
+	}
+}
+
+
+/*
+	========================================================================
+
+	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) || IS_RT3572(pAd)|| IS_RT3390(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) || IS_RT3572(pAd)|| IS_RT3390(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));
+}
+
+
+// add by johnli, RF power sequence setup
+/*
+	==========================================================================
+	Description:
+
+	Load RF normal operation-mode setup
+
+	==========================================================================
+ */
+VOID RT33xxLoadRFNormalModeSetup(
+	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);
+
+	/* move to NICInitRT30xxRFRegisters
+	// 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;
+	}
+	// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
+	if (pAd->TxMixerGain24G >= 2)
+	{
+		RFValue &= (~0x7);  // clean bit [2:0]
+		RFValue |= pAd->TxMixerGain24G;
+	}
+	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);
+
+	/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/
+	// LDORF_VC, RF R27 register Bit 2 to 0
+	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+	// TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F).
+	// Raising RF voltage is no longer needed for RT3070(F)
+	if (IS_RT3090(pAd))	// RT309x and RT3071/72
+	{
+		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 RT33xxLoadRFSleepModeSetup(
+	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);
+	}
+
+	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
+		IS_RT3572(pAd) ||
+		IS_RT3390(pAd) ||
+		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+	{
+		{
+			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 RT33xxReverseRFSleepModeSetup(
+	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);
+	}
+
+	if (IS_RT3090(pAd) ||	// IS_RT3090 including RT309x and RT3071/72
+		IS_RT3572(pAd) ||
+		IS_RT3390(pAd) ||
+		(IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
+	{
+		{
+			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);
+		}
+	}
+
+	if(IS_RT3572(pAd))
+		RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
+}
+// end johnli
+
+VOID RT33xxHaltAction(
+	IN PRTMP_ADAPTER	pAd)
+{
+	UINT32		TxPinCfg = 0x00050F0F;
+
+	//
+	// Turn off LNA_PE or TRSW_POL
+	//
+	if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3390(pAd)||IS_RT3572(pAd))
+	{
+	//KH? Both support 3390 usb and  PCI
+		if ((IS_RT3071(pAd) || IS_RT3572(pAd)||IS_RT3390(pAd))
+#ifdef RTMP_EFUSE_SUPPORT
+			&& (pAd->bUseEfuse)
+#endif // RTMP_EFUSE_SUPPORT //
+			)
+		{
+			TxPinCfg &= 0xFFFBF0F0; // bit18 off
+		}
+		else
+		{
+			TxPinCfg &= 0xFFFFF0F0;
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+}
+
+#endif // RT30xx //
diff --git a/drivers/staging/rt3090/chlist.h b/drivers/staging/rt3090/chlist.h
new file mode 100644
index 0000000..d03cb47
--- /dev/null
+++ b/drivers/staging/rt3090/chlist.h
@@ -0,0 +1,130 @@
+/*
+ *************************************************************************
+ * 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.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    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;
+
+extern CH_REGION ChRegion[];
+
+typedef struct _CH_FREQ_MAP_{
+	UINT16		channel;
+	UINT16		freqKHz;
+}CH_FREQ_MAP;
+
+extern CH_FREQ_MAP CH_HZ_ID_MAP[];
+extern int CH_HZ_ID_MAP_NUM;
+
+
+#define     MAP_CHANNEL_ID_TO_KHZ(_ch, _khz)					\
+		do{													\
+			int _chIdx;											\
+			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
+			{													\
+				if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel)			\
+				{												\
+					(_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;	\
+					break;										\
+				}												\
+			}													\
+			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
+				(_khz) = 2412000;									\
+            }while(0)
+
+#define     MAP_KHZ_TO_CHANNEL_ID(_khz, _ch)                 \
+		do{													\
+			int _chIdx;											\
+			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\
+			{													\
+				if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz)			\
+				{												\
+					(_ch) = CH_HZ_ID_MAP[_chIdx].channel;			\
+					break;										\
+				}												\
+			}													\
+			if (_chIdx == CH_HZ_ID_MAP_NUM)					\
+				(_ch) = 1;											\
+		}while(0)
+
+
+VOID BuildChannelListEx(
+	IN PRTMP_ADAPTER pAd);
+
+VOID BuildBeaconChList(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pBuf,
+	OUT	PULONG pBufLen);
+
+#ifdef DOT11_N_SUPPORT
+VOID N_ChannelCheck(
+	IN PRTMP_ADAPTER pAd);
+
+VOID N_SetCenCh(
+	IN PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+
+UINT8 GetCuntryMaxTxPwr(
+	IN PRTMP_ADAPTER pAd,
+	IN UINT8 channel);
+
+#endif // __CHLIST_H__
diff --git a/drivers/staging/rt3090/common/action.c b/drivers/staging/rt3090/common/action.c
new file mode 100644
index 0000000..8e3b0a0
--- /dev/null
+++ b/drivers/staging/rt3090/common/action.c
@@ -0,0 +1,1057 @@
+/*
+ *************************************************************************
+ * 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
+#ifdef QOS_DLS_SUPPORT
+			if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
+				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+			else
+#endif // QOS_DLS_SUPPORT //
+			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, (MGMT_USE_QUEUE_FLAG | 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
+#ifdef QOS_DLS_SUPPORT
+			if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
+				ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+			else
+#endif // QOS_DLS_SUPPORT //
+			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 DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+	UCHAR	Action = Elem->Msg[LENGTH_802_11+1];
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+		return;
+
+#ifdef DOT11_N_SUPPORT
+#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 //
+#endif // DOT11_N_SUPPORT //
+
+}
+
+
+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, (MGMT_USE_QUEUE_FLAG | 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/rt3090/common/ba_action.c b/drivers/staging/rt3090/common/ba_action.c
new file mode 100644
index 0000000..c732489
--- /dev/null
+++ b/drivers/staging/rt3090/common/ba_action.c
@@ -0,0 +1,1779 @@
+/*
+ *************************************************************************
+ * 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 * OS_HZ)/1000)	// system ticks -- 100 ms
+#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * OS_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)
+	   )
+		{
+//		DBGPRINT(RT_DEBUG_OFF, ("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;
+		}
+
+		DBGPRINT(RT_DEBUG_OFF, ("%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;
+//		DBGPRINT(RT_DEBUG_TRACE, ("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;
+
+	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;
+		pAd->BATable.numDoneOriginator ++;
+
+		// 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;
+
+		DBGPRINT(RT_DEBUG_OFF, ("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.
+		RTMP_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)
+	{
+		DBGPRINT(RT_DEBUG_OFF, ("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)
+		{
+			pAd->BATable.numDoneOriginator -= 1;
+			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);
+			if (Elem != NULL)
+			{
+				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;
+				Elem->MsgLen  = sizeof(DelbaReq);
+				NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+				MlmeDELBAAction(pAd, Elem);
+				kfree(Elem);
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __FUNCTION__));
+			}
+		}
+
+		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);
+		if (Elem != NULL)
+		{
+			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;
+			Elem->MsgLen  = sizeof(DelbaReq);
+			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+			MlmeDELBAAction(pAd, Elem);
+			kfree(Elem);
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__));
+			return;
+		}
+	}
+	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;
+		//ULONG   offset;
+		//UINT32  VALUE;
+
+		RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+
+		//
+		// 1. Send DELBA Action Frame
+		//
+		if (bPassive == FALSE)
+		{
+			MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+			if (Elem != NULL)
+			{
+				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;
+				Elem->MsgLen  = sizeof(DelbaReq);
+				NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+				MlmeDELBAAction(pAd, Elem);
+				kfree(Elem);
+			}
+			else
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__));
+				return;
+			}
+		}
+
+
+		//
+		// 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;
+
+		RTMP_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);
+		RTMP_MLME_HANDLER(pAd);
+		DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
+
+		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);
+			DBGPRINT(RT_DEBUG_OFF, ("%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]);
+			DBGPRINT(RT_DEBUG_OFF, ("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
+#ifdef QOS_DLS_SUPPORT
+		if (pAd->MacTab.Content[Elem->Wcid].ValidAsDls)
+			ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+		else
+#endif // QOS_DLS_SUPPORT //
+		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))
+	{
+		//DBGPRINT(RT_DEBUG_TRACE, ("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;
+
+	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_RT30xx(pAd)
+				&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
+			{
+				RTMP_ASIC_MMPS_DISABLE(pAd);
+			}
+#endif // RT30xx //
+			Frame.Psmp = 0;
+			break;
+		case MMPS_DYNAMIC:
+			Frame.Psmp = 3;
+			break;
+		case MMPS_STATIC:
+#ifdef RT30xx
+			if (IS_RT30xx(pAd)
+				&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
+			{
+				RTMP_ASIC_MMPS_ENABLE(pAd);
+			}
+#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);
+
+	SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID));
+	SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData);
+	SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize);
+	SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize);
+
+	//
+	// 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
+		}
+#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) &&
+		(!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP)))
+	{
+		// 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/rt3090/common/cmm_aes.c b/drivers/staging/rt3090/common/cmm_aes.c
new file mode 100644
index 0000000..4ccbbbf
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_aes.c
@@ -0,0 +1,1560 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_aes.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Paul Wu		02-25-02		Initial
+*/
+
+#include "../rt_config.h"
+
+
+typedef	struct
+{
+    UINT32 erk[64];     /* encryption round keys */
+    UINT32 drk[64];     /* decryption round keys */
+    int nr;             /* number of rounds */
+}
+aes_context;
+
+/*****************************/
+/******** 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)
+{
+	INT i;
+
+	for (i=0;i<4; i++)
+	{
+		out[i] = a[i] ^ b[i];
+	}
+}
+
+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];
+	}
+}
+
+UCHAR RTMPCkipSbox(
+	IN  UCHAR   a)
+{
+	return SboxTable[(int)a];
+}
+
+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 byte_sub(
+	IN  PUCHAR  in,
+	OUT PUCHAR  out)
+{
+	INT i;
+
+	for (i=0; i< 16; i++)
+	{
+		out[i] = RTMPCkipSbox(in[i]);
+	}
+}
+
+/************************************/
+/* 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 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);
+}
+
+
+/************************************************/
+/* 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);
+
+}
+
+/****************************************/
+/* aes128k128d()                        */
+/* Performs a 128 bit AES encrypt with  */
+/* 128 bit data.                        */
+/****************************************/
+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);
+
+}
+
+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;
+}
+
+/* =========================  AES En/Decryption ========================== */
+#ifndef	uint8
+#define	uint8  unsigned	char
+#endif
+
+#ifndef	uint32
+#define	uint32 unsigned	int
+#endif
+
+/* 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)	   );		\
+}
+
+
+int	rt_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 = (uint32 *) 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 = (uint32 *) 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 rt_aes_encrypt(aes_context *ctx, uint8 input[16],	uint8 output[16] )
+{
+	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
+
+	RK = (uint32 *) 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 rt_aes_decrypt( aes_context *ctx,	uint8 input[16], uint8 output[16] )
+{
+	uint32 *RK,	X0,	X1,	X2,	X3,	Y0,	Y1,	Y2,	Y3;
+
+	RK = (uint32 *) 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 );
+}
+
+/*
+    ==========================================================================
+    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 UINT32    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;
+
+    rt_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);
+            rt_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	UINT32   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];
+	}
+
+	rt_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);
+			rt_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);
+}
+
+
+/* =======  The related function of AES-128-CMAC  ======= */
+VOID leftshift_onebit(
+	IN  PUCHAR	input,
+	OUT PUCHAR	output)
+{
+	INT i;
+	UCHAR overflow = 0;
+
+	for (i=15; i>=0; i--)
+	{
+		output[i] = input[i] << 1;
+		output[i] |= overflow;
+		overflow = (input[i] & 0x80) ? 1 : 0;
+	}
+}
+
+VOID do_padding(
+	IN	PUCHAR	lastb,
+	OUT	PUCHAR	pad,
+	IN  INT		len)
+{
+	INT	j;
+
+	for (j=0; j<16; j++)
+	{
+		if (j < len)
+			pad[j] = lastb[j];
+		else if (j == len)
+			pad[j] = 0x80;
+		else
+			pad[j] = 0x00;
+	}
+
+
+}
+
+/*
+ *	The Subkey Generation Algorithm
+ */
+VOID generate_subkey(
+	IN	PUCHAR key,
+	OUT	PUCHAR K1,
+	OUT PUCHAR K2)
+{
+	aes_context aesctx;
+	UCHAR aes_128_key[16];
+	UCHAR const_Zero[16];
+	UCHAR tmp[16];
+	UCHAR const_Rb[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+					      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
+
+	// initial the key material
+	memset(const_Zero, 0, 16);
+	memset(aes_128_key, 0, 16);
+
+	// AES-128 with key is applied to an all-zero input block
+	rt_aes_set_key(&aesctx, key, 128);
+	rt_aes_encrypt(&aesctx, const_Zero, aes_128_key);
+
+	// derive K1(128-bit first subkey) and K2(128-bit second subkey), refer to rfc-4493 ch 2.3
+	if ((aes_128_key[0] & 0x80) == 0)
+	{
+		leftshift_onebit(aes_128_key, K1);
+	}
+	else
+	{
+		leftshift_onebit(aes_128_key, tmp);
+		xor_128(tmp, const_Rb, K1);
+	}
+
+	if ((K1[0] & 0x80) == 0)
+	{
+		leftshift_onebit(K1, K2);
+	}
+	else
+	{
+		leftshift_onebit(K1, tmp);
+		xor_128(tmp, const_Rb, K2);
+	}
+
+}
+
+/*
+ *	AES-CMAC Algorithm. (refer to rfc-4493 and SP800-38B)
+ *
+ *	Input : key		(128-bit key)
+ *			input		(message to be authenticated)
+ *			len			(length of the message in octets)
+ *
+ *	output: mac			(message authentication code)
+ */
+VOID AES_128_CMAC(
+	IN	PUCHAR	key,
+	IN	PUCHAR	input,
+	IN	INT		len,
+	OUT	PUCHAR	mac)
+{
+	UCHAR	X[16], Y[16], M_last[16], padded[16];
+	UCHAR	K1[16], K2[16];
+	aes_context aesctx;
+	INT		n, i, flag;
+
+	generate_subkey(key, K1, K2);
+
+	n = (len+15) / 16;		// n is number of rounds
+
+	if (n == 0)
+	{
+		n = 1;
+		flag = 0;
+	}
+	else
+	{
+		if ((len%16) == 0)
+			flag = 1;			// indicate that last block is a complete block
+		else
+			flag = 0;			// indicate that last block is not a complete block
+	}
+
+	if (flag)
+	{
+		xor_128(&input[16*(n-1)], K1, M_last);
+	}
+	else
+	{
+		do_padding(&input[16*(n-1)], padded, len%16);
+		xor_128(padded, K2, M_last);
+	}
+
+	memset(X, 0, 16);
+	for (i=0; i<n-1; i++)
+	{
+		xor_128(X, &input[16*i], Y);
+		rt_aes_set_key(&aesctx, key, 128);
+		rt_aes_encrypt(&aesctx, Y, X);
+	}
+
+	xor_128(X, M_last, Y);
+	rt_aes_set_key(&aesctx, key, 128);
+	rt_aes_encrypt(&aesctx, Y, X);
+
+	for (i=0; i<16; i++)
+	{
+		mac[i] = X[i];
+	}
+
+}
+/* =======  The related function of AES-128-CMAC  ======= */
diff --git a/drivers/staging/rt3090/common/cmm_asic.c b/drivers/staging/rt3090/common/cmm_asic.c
new file mode 100644
index 0000000..3d1c808
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_asic.c
@@ -0,0 +1,2753 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_asic.c
+
+	Abstract:
+	Functions used to communicate with ASIC
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+// 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},
+		{167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f},
+		{169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327},
+		{171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307},
+		{173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f},
+
+		// 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},
+};
+UCHAR	NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
+
+
+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.numDoneOriginator)
+	{
+		//
+		// 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;
+		pAd->FlgCtsEnabled = 0; /* CTS-self is not used */
+	}
+	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;
+		pAd->FlgCtsEnabled = 1; /* CTS-self is used */
+	}
+
+#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:
+				// Special on for Atheros problem n chip.
+				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]);
+	}
+}
+}
+
+
+/*
+	==========================================================================
+	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;
+	UCHAR	RFValue;
+
+	RFValue = 0;
+	// Search Tx power value
+	// 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;
+		}
+	}
+
+	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)||IS_RT3390(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 */
+
+		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;
+
+#ifdef DFS_DEBUG
+#ifdef DFS_FCC_BW40_FIX
+						if (pAd->infType == RTMP_DEV_INF_PCI) // RT2880 PCI
+						{
+							/* only for RT2880 */
+							// FCC DFS test
+							pAd->LatchRfRegs.R1 |= 0x100;
+							pAd->LatchRfRegs.R4 |= 0x00400000;
+						}
+#endif // DFS_FCC_BW40_FIX //
+#endif // DFS_DEBUG //
+
+						// 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;
+		}
+
+		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));
+	}
+
+	// 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);
+
+#if defined(RT3090) || defined(RT3390)
+		// PCIe PHY Transmit attenuation adjustment
+		if (IS_RT3090A(pAd) || IS_RT3390(pAd))
+		{
+			TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {0};
+
+			RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, &TxAttenuationCtrl.word);
+
+			if (Channel == 14) // Channel #14
+			{
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1; // Enable PCIe PHY Tx attenuation
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4; // 9/16 full drive level
+			}
+			else // Channel #1~#13
+			{
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0; // Disable PCIe PHY Tx attenuation
+				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0; // n/a
+			}
+
+			RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL, TxAttenuationCtrl.word);
+		}
+#endif
+	}
+	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);
+}
+
+/*
+	==========================================================================
+	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
+
+	==========================================================================
+ */
+#ifdef ANT_DIVERSITY_SUPPORT
+VOID	AsicAntennaSelect(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Channel)
+{
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
+#endif // CONFIG_STA_SUPPORT //
+	{
+		// 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;
+			realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
+#endif // CONFIG_STA_SUPPORT //
+
+			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)))
+				AsicEvaluateRxAnt(pAd);
+
+				pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
+		}
+		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);
+		}
+	}
+}
+#endif // ANT_DIVERSITY_SUPPORT //
+
+/*
+	========================================================================
+
+	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;
+#ifdef CONFIG_STA_SUPPORT
+	CHAR		Rssi = -127;
+#endif // CONFIG_STA_SUPPORT //
+#ifdef CARRIER_SENSE_NEW_ALGO
+	unsigned long flags; //KH Add to Fix PCIe Power-Saving bug
+#endif // CARRIER_SENSE_NEW_ALGO //
+
+
+#ifdef CARRIER_SENSE_NEW_ALGO
+	//KH Add to Fix PCIe Power-Saving bug<--
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	//KH Add to Fix PCIe Power-Saving bug-->
+#endif // CARRIER_SENSE_NEW_ALGO //
+
+#ifdef CONFIG_STA_SUPPORT
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+#ifdef RTMP_MAC_PCI
+		(pAd->bPCIclkOff == TRUE) ||
+#endif // RTMP_MAC_PCI //
+		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
+		RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+{
+
+#ifdef CARRIER_SENSE_NEW_ALGO
+	//KH Add to Fix PCIe Power-Saving bug<--
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+	//KH add to fix PCIe-Power Saving -->
+#endif // CARRIER_SENSE_NEW_ALGO //
+		return;
+}
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		Rssi = RTMPMaxRssi(pAd,
+						   pAd->StaCfg.RssiSample.AvgRssi0,
+						   pAd->StaCfg.RssiSample.AvgRssi1,
+						   pAd->StaCfg.RssiSample.AvgRssi2);
+#endif // CONFIG_STA_SUPPORT //
+
+	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
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			// to patch high power issue with some APs, like Belkin N1.
+			if (Rssi > -35)
+			{
+				BbpR1 |= 0x02;		// DeltaPwr -= 12;
+			}
+			else if (Rssi > -40)
+			{
+				BbpR1 |= 0x01;		// DeltaPwr -= 6;
+			}
+			else
+		;
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+	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 CARRIER_SENSE_NEW_ALGO
+	//KH Add to Fix PCIe Power-Saving bug<--
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+	//KH add to fix PCIe-Power Saving -->
+#endif // CARRIER_SENSE_NEW_ALGO //
+
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+VOID AsicResetBBPAgent(
+IN PRTMP_ADAPTER pAd)
+{
+	BBP_CSR_CFG_STRUC	BbpCsr;
+	DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit.!! \n"));
+	// Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first.
+	RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+	BbpCsr.field.Busy = 0;
+	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
+}
+/*
+	==========================================================================
+	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)
+{
+	RTMP_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_INFO, ("--> AsicForceWakeup \n"));
+    RTMP_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 RTMP_MAC_PCI
+	// 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
+	{
+		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
+		ptr += 4;
+	}
+
+	// start right after the 16-byte TXWI field
+	ptr = pAd->BeaconBuf;
+	for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
+	{
+		UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
+		ptr +=4;
+	}
+#endif // RTMP_MAC_PCI //
+
+
+	//
+	// 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;
+		if(pAd->Antenna.field.TxPath == 1)
+		{
+			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
+			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
+		}
+		else
+		{
+		Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
+		Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
+		}
+		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#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
+			// TODO: Shiang, this modification also suitable for RT3052/RT3050 ???
+			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_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+		return;
+	else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
+		return;
+
+	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->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
+#ifdef DOT11_N_SUPPORT
+			|| ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
+#endif // DOT11_N_SUPPORT //
+			)
+		{
+			// In this case, we will think it is doing Wi-Fi test
+			// And we will not set to short slot when bEnableTxBurst is TRUE.
+		}
+		else if (pAd->CommonCfg.bEnableTxBurst)
+		{
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+			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)
+		{
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+			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;
+#ifdef RTMP_MAC_PCI
+	INT   i;
+#endif // RTMP_MAC_PCI //
+
+	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 RTMP_MAC_PCI
+	offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
+	for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
+	{
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+
+	offset += MAX_LEN_OF_SHARE_KEY;
+	if (pTxMic)
+	{
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+		}
+	}
+
+	offset += 8;
+	if (pRxMic)
+	{
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
+		}
+	}
+#endif // RTMP_MAC_PCI //
+
+
+	//
+	// 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;
+#ifdef RTMP_MAC_PCI
+	UCHAR		i;
+#endif // RTMP_MAC_PCI //
+
+//	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 RTMP_MAC_PCI
+	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
+	{
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+	offset += MAX_LEN_OF_PEER_KEY;
+
+	//
+	// 3.) Set MIC key if available
+	//
+	if (pTxMic)
+	{
+		for (i = 0; i < 8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
+		}
+	}
+	offset += LEN_TKIP_TXMICK;
+
+	if (pRxMic)
+	{
+		for (i = 0; i < 8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
+		}
+	}
+#endif // RTMP_MAC_PCI //
+
+
+	//
+	// 4.) Modify IV/EIV if needs
+	//     This will force Asic to use this key ID by setting IV.
+	//
+	if (bTxKey)
+	{
+#ifdef RTMP_MAC_PCI
+		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+		//
+		// Write IV
+		//
+		RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
+		RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
+		RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
+
+		IV4 = (KeyIdx << 6);
+		if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
+			IV4 |= 0x20;  // turn on extension bit means EIV existence
+
+		RTMP_IO_WRITE8(pAd, offset + 3, IV4);
+
+		//
+		// Write EIV
+		//
+		offset += 4;
+		for (i = 0; i < 4; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
+		}
+#endif // RTMP_MAC_PCI //
+
+		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 RTMP_MAC_PCI
+	for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
+	{
+		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
+	}
+#endif // RTMP_MAC_PCI //
+	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 RTMP_MAC_PCI
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
+		}
+#endif // RTMP_MAC_PCI //
+	}
+	offset += 8;
+	if (pRxMic)
+	{
+#ifdef RTMP_MAC_PCI
+		for (i=0; i<8; i++)
+		{
+			RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
+		}
+#endif // RTMP_MAC_PCI //
+	}
+
+	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)
+{
+
+
+	if (pAd->chipOps.sendCommandToMcu)
+		pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
+
+	return TRUE;
+}
+
+
+VOID AsicSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant)
+{
+#ifdef RT33xx
+	RT33xxSetRxAnt(pAd, Ant);
+#else
+#ifdef RT30xx
+	/* RT3572 ATE need not to do this. */
+	RT30xxSetRxAnt(pAd, Ant);
+#endif // RT30xx //
+#endif // RT33xx //
+}
+
+
+VOID AsicTurnOffRFClk(
+	IN PRTMP_ADAPTER pAd,
+	IN	UCHAR		Channel)
+{
+	if (pAd->chipOps.AsicRfTurnOff)
+	{
+		pAd->chipOps.AsicRfTurnOff(pAd);
+	}
+	else
+	{
+		// RF R2 bit 18 = 0
+		UINT32			R1 = 0, R2 = 0, R3 = 0;
+		UCHAR			index;
+		RTMP_RF_REGS	*RFRegTable;
+
+		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;
+		}
+	}
+}
+
+
+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 PCIE_PS_SUPPORT
+	// The RF programming sequence is difference between 3xxx and 2xxx
+	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
+	{
+		return;
+	}
+#endif // PCIE_PS_SUPPORT //
+
+	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;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
+		Channel,
+		pAd->RfIcType,
+		R2));
+}
diff --git a/drivers/staging/rt3090/common/cmm_cfg.c b/drivers/staging/rt3090/common/cmm_cfg.c
new file mode 100644
index 0000000..d8be979
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_cfg.c
@@ -0,0 +1,295 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_cfg.c
+
+    Abstract:
+    Ralink WiFi Driver configuration related subroutines
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+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";
+	}
+}
+
+
+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";
+	}
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set Country Region to pAd->CommonCfg.CountryRegion.
+        This command will not work, if the field of CountryRegion in eeprom is programmed.
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT RT_CfgSetCountryRegion(
+	IN PRTMP_ADAPTER	pAd,
+	IN PSTRING			arg,
+	IN INT				band)
+{
+	LONG region, regionMax;
+	UCHAR *pCountryRegion;
+
+	region = simple_strtol(arg, 0, 10);
+
+	if (band == BAND_24G)
+	{
+		pCountryRegion = &pAd->CommonCfg.CountryRegion;
+		regionMax = REGION_MAXIMUM_BG_BAND;
+	}
+	else
+	{
+		pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
+		regionMax = REGION_MAXIMUM_A_BAND;
+	}
+
+	// TODO: Is it neccesay for following check???
+	// Country can be set only when EEPROM not programmed
+	if (*pCountryRegion & 0x80)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
+		return FALSE;
+	}
+
+	if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
+	{
+		*pCountryRegion= (UCHAR) region;
+	}
+	else if ((region == REGION_31_BG_BAND) && (band == BAND_24G))
+	{
+		*pCountryRegion = (UCHAR) region;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():region(%ld) out of range!\n", region));
+		return FALSE;
+	}
+
+	return TRUE;
+
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set Wireless Mode
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT RT_CfgSetWirelessMode(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	INT		MaxPhyMode = PHY_11G;
+	LONG	WirelessMode;
+
+#ifdef DOT11_N_SUPPORT
+	MaxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+	WirelessMode = simple_strtol(arg, 0, 10);
+	if (WirelessMode <= MaxPhyMode)
+	{
+		pAd->CommonCfg.PhyMode = WirelessMode;
+		pAd->CommonCfg.DesiredPhyMode = WirelessMode;
+		return TRUE;
+	}
+
+	return FALSE;
+
+}
+
+
+INT RT_CfgSetShortSlot(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	LONG 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
+
+	return TRUE;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set WEP KEY base on KeyIdx
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	RT_CfgSetWepKey(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			keyString,
+	IN	CIPHER_KEY		*pSharedKey,
+	IN	INT				keyIdx)
+{
+	INT				KeyLen;
+	INT				i;
+	UCHAR			CipherAlg = CIPHER_NONE;
+	BOOLEAN			bKeyIsHex = FALSE;
+
+	// TODO: Shall we do memset for the original key info??
+	memset(pSharedKey, 0, sizeof(CIPHER_KEY));
+	KeyLen = strlen(keyString);
+	switch (KeyLen)
+	{
+		case 5: //wep 40 Ascii type
+		case 13: //wep 104 Ascii type
+			bKeyIsHex = FALSE;
+			pSharedKey->KeyLen = KeyLen;
+			NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
+			break;
+
+		case 10: //wep 40 Hex type
+		case 26: //wep 104 Hex type
+			for(i=0; i < KeyLen; i++)
+			{
+				if( !isxdigit(*(keyString+i)) )
+					return FALSE;  //Not Hex value;
+			}
+			bKeyIsHex = TRUE;
+			pSharedKey->KeyLen = KeyLen/2 ;
+			AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
+			break;
+
+		default: //Invalid argument
+			DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", keyIdx, keyString));
+			return FALSE;
+	}
+
+	pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
+	DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n",
+						keyIdx, (bKeyIsHex == FALSE ? "Ascii" : "Hex"), CipherName[CipherAlg]));
+
+	return TRUE;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set WPA PSK key
+
+    Arguments:
+        pAdapter	Pointer to our adapter
+        keyString	WPA pre-shared key string
+        pHashStr	String used for password hash function
+        hashStrLen	Lenght of the hash string
+        pPMKBuf		Output buffer of WPAPSK key
+
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT RT_CfgSetWPAPSKKey(
+	IN RTMP_ADAPTER	*pAd,
+	IN PSTRING		keyString,
+	IN UCHAR		*pHashStr,
+	IN INT			hashStrLen,
+	OUT PUCHAR		pPMKBuf)
+{
+	int keyLen;
+	UCHAR keyMaterial[40];
+
+	keyLen = strlen(keyString);
+	if ((keyLen < 8) || (keyLen > 64))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
+									keyLen, keyString));
+		return FALSE;
+	}
+
+	memset(pPMKBuf, 0, 32);
+	if (keyLen == 64)
+	{
+	    AtoH(keyString, pPMKBuf, 32);
+	}
+	else
+	{
+	    PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
+	    NdisMoveMemory(pPMKBuf, keyMaterial, 32);
+	}
+
+	return TRUE;
+}
diff --git a/drivers/staging/rt3090/common/cmm_data.c b/drivers/staging/rt3090/common/cmm_data.c
new file mode 100644
index 0000000..6340071
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_data.c
@@ -0,0 +1,2763 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_data.c
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#include "../rt_config.h"
+
+
+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			rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+#ifdef RTMP_MAC_PCI
+	unsigned long	IrqFlags = 0;
+	UCHAR			IrqState;
+#endif // RTMP_MAC_PCI //
+	BOOLEAN			bUseDataQ = FALSE;
+	int			retryCnt = 0;
+
+	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+	if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG)
+	{
+		bUseDataQ = TRUE;
+		QueIdx &= (~MGMT_USE_QUEUE_FLAG);
+	}
+
+#ifdef RTMP_MAC_PCI
+	// 2860C use Tx Ring
+	IrqState = pAd->irq_disabled;
+	if (pAd->MACVersion == 0x28600100)
+	{
+		QueIdx = (bUseDataQ ==TRUE ? QueIdx : 3);
+		bUseDataQ = TRUE;
+	}
+	if (bUseDataQ && (!IrqState))
+		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+#endif // RTMP_MAC_PCI //
+
+	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.
+#ifdef RTMP_MAC_PCI
+		if (bUseDataQ)
+		{
+			retryCnt = MAX_DATAMM_RETRY;
+			// free Tx(QueIdx) resources
+			RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
+			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+		}
+		else
+#endif // RTMP_MAC_PCI //
+		{
+			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;
+
+
+#ifdef RTMP_MAC_PCI
+			if (bUseDataQ)
+			{
+				Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
+				retryCnt--;
+			}
+			else
+#endif // RTMP_MAC_PCI //
+				Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
+			if (Status == NDIS_STATUS_SUCCESS)
+				retryCnt = 0;
+			else
+				RTMPFreeNdisPacket(pAd, pPacket);
+		}
+		else
+		{
+			pAd->RalinkCounters.MgmtRingFullCount++;
+#ifdef RTMP_MAC_PCI
+			if (bUseDataQ)
+			{
+				retryCnt--;
+				DBGPRINT(RT_DEBUG_TRACE, ("retryCnt %d\n", retryCnt));
+				if (retryCnt == 0)
+				{
+					DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
+											QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+				}
+			}
+#endif // RTMP_MAC_PCI //
+			DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
+										QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+
+
+
+		}
+	} while (retryCnt > 0);
+
+
+#ifdef RTMP_MAC_PCI
+	if (bUseDataQ && (!IrqState))
+		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+#endif // RTMP_MAC_PCI //
+
+	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)
+{
+	PACKET_INFO	PacketInfo;
+	PUCHAR			pSrcBufVA;
+	UINT			SrcBufLen;
+	PHEADER_802_11	pHeader_802_11;
+
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#endif // CARRIER_DETECTION_SUPPORT //
+		)
+	{
+		return NDIS_STATUS_FAILURE;
+	}
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+	if (pSrcBufVA == NULL)
+		return NDIS_STATUS_FAILURE;
+
+	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
+
+
+#ifdef RTMP_MAC_PCI
+	if ( pAd->MACVersion == 0x28600100 )
+		return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
+	else
+#endif // RTMP_MAC_PCI //
+		return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+
+}
+
+
+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;
+	UCHAR			PID;
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+	// Make sure MGMT ring resource won't be used by other threads
+	RTMP_SEM_LOCK(&pAd->MgmtRingLock);
+	if (pSrcBufVA == NULL)
+	{
+		// The buffer shouldn't be NULL
+			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 = PWR_ACTIVE; // (pAd->StaCfg.Psm == PWR_SAVE);
+
+#ifdef CONFIG_STA_SUPPORT
+	//
+	// In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
+	// 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 ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
+			((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+			((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
+			(pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC))))
+		{
+			if (pAd->StaCfg.Psm == PWR_SAVE)
+				pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+			else
+				pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
+		}
+	}
+#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) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
+			{
+				bInsertTimestamp = TRUE;
+				bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Response
+			}
+			else if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) && (pHeader_802_11->FC.Type == BTYPE_MGMT))
+			{
+				bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Request
+			}
+		}
+	}
+
+	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 physical 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.
+	PID = PID_MGMT;
+
+
+	if (pMacEntry == NULL)
+	{
+		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
+		0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0,  (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+	}
+	else
+	{
+		/* dont use low rate to send QoS Null data frame */
+		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 ((pAd->OpMode == OPMODE_STA) &&
+			(ADHOC_ON(pAd)) &&
+			(RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS)))
+		{
+			if(pAd->CommonCfg.PSPXlink)
+				TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		{
+
+#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;
+}
+
+
+BOOLEAN CanDoAggregateTransmit(
+	IN RTMP_ADAPTER *pAd,
+	IN NDIS_PACKET *pPacket,
+	IN TX_BLK		*pTxBlk)
+{
+
+	//DBGPRINT(RT_DEBUG_TRACE, ("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;
+		eQIdx = 3;	// 4 ACs, start from 0.
+	}
+	else
+	{
+		sQIdx = eQIdx = QIdx;
+	}
+
+	for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
+	{
+		Count=0;
+
+		RTMP_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))))
+			{
+				RTMP_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;
+			}
+
+#ifdef RTMP_MAC_PCI
+			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
+
+#ifdef DBG_DIAGNOSE
+			if (firstRound == TRUE)
+			{
+				UCHAR	txDescNumLevel, txSwQNumLevel;
+
+				txDescNumLevel = (TX_RING_SIZE - FreeNumber[QueIdx]); // Number of occupied hw desc.
+				txDescNumLevel = ((txDescNumLevel <=15) ? txDescNumLevel : 15);
+				pDiagStruct->TxDescCnt[pDiagStruct->ArrayCurIdx][txDescNumLevel]++;
+
+				txSwQNumLevel = ((pAd->TxSwQueue[QueIdx].Number <=7) ? pAd->TxSwQueue[QueIdx].Number : 8);
+				pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][txSwQNumLevel]++;
+
+				firstRound = FALSE;
+			}
+#endif // DBG_DIAGNOSE //
+
+			if (FreeNumber[QueIdx] <= 5)
+			{
+				// free Tx(QueIdx) resources
+				RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
+				FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
+			}
+#endif // RTMP_MAC_PCI //
+
+			// 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_PACKET(pEntry);
+
+
+			// Early check to make sure we have enoguh Tx Resource.
+			hasTxDesc = RTMP_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_PACKET(pEntry);
+					FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
+					hasTxDesc = RTMP_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_PACKET(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;
+			}
+
+
+			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 //
+
+#ifdef RTMP_MAC_PCI
+			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 // RTMP_MAC_PCI //
+
+		}
+
+		RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+
+#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 (pAd->MACVersion == 0x28720200)
+	{
+		if( BASize >13 )
+			BASize =13;
+	}
+	else
+	{
+		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 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 //
+#endif // DOT11_N_SUPPORT //
+
+	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;
+
+}
+
+
+// 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;
+		}
+
+		//DBGPRINT(RT_DEBUG_TRACE,("%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);
+			if (Elem != NULL)
+			{
+				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);
+				REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, Elem->Msg, Elem->MsgLen, 0, 0, 0, 0);
+				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;
+#ifdef RTMP_MAC_PCI
+					AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
+#endif // RTMP_MAC_PCI //
+				}
+#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->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
+			pEntry->ContinueTxFailCnt = 0;
+#ifdef WDS_SUPPORT
+			pEntry->LockEntryTx = FALSE;
+			pEntry->TimeStamp_toTxRing = 0;
+#endif // WDS_SUPPORT //
+			InitializeQueueHeader(&pEntry->PsQueue);
+
+
+			pAd->MacTab.Size ++;
+			// Add this entry into ASIC RX WCID search table
+			RTMP_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
+			RTMP_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);
+
+			RTMP_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
+		{
+			DBGPRINT(RT_DEBUG_OFF, ("\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*/);
+		RTMP_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++)
+	{
+#ifdef RTMP_MAC_PCI
+		RTMP_STA_ENTRY_MAC_RESET(pAd, i);
+#endif // RTMP_MAC_PCI //
+		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;
+
+
+
+
+			//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((PNDIS_BUFFER)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((PNDIS_BUFFER)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(get_unaligned((PUINT16)(pSrcBuf)));
+					dstPort = OS_NTOHS(get_unaligned((PUINT16)(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);
+
+
+	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/rt3090/common/cmm_data_pci.c b/drivers/staging/rt3090/common/cmm_data_pci.c
new file mode 100644
index 0000000..084f819
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_data_pci.c
@@ -0,0 +1,1576 @@
+/*
+ *************************************************************************
+ * 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 PCI-depended, or you should out your function
+	in other files.
+
+*/
+#include "../rt_config.h"
+
+
+USHORT RtmpPCI_WriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHeaderLen;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+	if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+	{
+		//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
+		hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+	}
+	else
+	{
+		//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+		hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+	}
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	//
+	// build Tx Descriptor
+	//
+
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+	RetTxIdx = TxIdx;
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+}
+
+
+USHORT RtmpPCI_WriteSingleTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber)
+{
+
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHeaderLen;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	// copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+	//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	//
+	// build Tx Descriptor
+	//
+#ifndef RT_BIG_ENDIAN
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+#else
+	pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	TxD = *pDestTxD;
+	pTxD = &TxD;
+#endif
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
+	RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif // RT_BIG_ENDIAN //
+
+	RetTxIdx = TxIdx;
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+}
+
+
+USHORT RtmpPCI_WriteMultiTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			frameNum,
+	OUT	USHORT			*FreeNumber)
+{
+	BOOLEAN bIsLast;
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHdrLen;
+	UINT32			firstDMALen;
+
+	bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	if (frameNum == 0)
+	{
+		// 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;
+
+		firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+	}
+	else
+	{
+		firstDMALen = pTxBlk->MpduHeaderLen;
+	}
+
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
+
+	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+	//
+	// build Tx Descriptor
+	//
+#ifndef RT_BIG_ENDIAN
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+#else
+	pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	TxD = *pDestTxD;
+	pTxD = &TxD;
+#endif
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = firstDMALen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+#ifdef RT_BIG_ENDIAN
+	if (frameNum == 0)
+		RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+
+	if (frameNum != 0)
+		RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
+
+	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif // RT_BIG_ENDIAN //
+
+	RetTxIdx = TxIdx;
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+
+}
+
+
+VOID RtmpPCI_FinalWriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	USHORT			totalMPDUSize,
+	IN	USHORT			FirstTxIdx)
+{
+
+	PTXWI_STRUC		pTxWI;
+	PRTMP_TX_RING	pTxRing;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
+	pTxWI->MPDUtotalByteCount = totalMPDUSize;
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+}
+
+
+VOID RtmpPCIDataLastTxIdx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	USHORT			LastTxIdx)
+{
+	PTXD_STRUC		pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	PRTMP_TX_RING	pTxRing;
+
+	//
+	// get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[QueIdx];
+
+	//
+	// build Tx Descriptor
+	//
+#ifndef RT_BIG_ENDIAN
+	pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
+#else
+	pDestTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
+	TxD = *pDestTxD;
+	pTxD = &TxD;
+#endif
+
+	pTxD->LastSec1 = 1;
+
+#ifdef RT_BIG_ENDIAN
+	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+	WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif // RT_BIG_ENDIAN //
+
+}
+
+
+USHORT	RtmpPCI_WriteFragTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			fragNum,
+	OUT	USHORT			*FreeNumber)
+{
+	UCHAR			*pDMAHeaderBufVA;
+	USHORT			TxIdx, RetTxIdx;
+	PTXD_STRUC		pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	UINT32			BufBasePaLow;
+	PRTMP_TX_RING	pTxRing;
+	USHORT			hwHeaderLen;
+	UINT32			firstDMALen;
+
+	//
+	// Get Tx Ring Resource
+	//
+	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
+	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
+	pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+
+	//
+	// Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+	//
+	//hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+	firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
+	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
+
+
+	//
+	// Build Tx Descriptor
+	//
+#ifndef RT_BIG_ENDIAN
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+#else
+	pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+	TxD = *pDestTxD;
+	pTxD = &TxD;
+#endif
+	NdisZeroMemory(pTxD, TXD_SIZE);
+
+	if (fragNum == pTxBlk->TotalFragNum)
+	{
+		pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
+		pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+	}
+
+	pTxD->SDPtr0 = BufBasePaLow;
+	pTxD->SDLen0 = firstDMALen; // include padding
+	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
+	pTxD->SDLen1 = pTxBlk->SrcBufLen;
+	pTxD->LastSec0 = 0;
+	pTxD->LastSec1 = 1;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
+	RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif // RT_BIG_ENDIAN //
+
+	RetTxIdx = TxIdx;
+	pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+	//
+	// Update Tx index
+	//
+	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
+	pTxRing->TxCpuIdx = TxIdx;
+
+	*FreeNumber -= 1;
+
+	return RetTxIdx;
+
+}
+
+
+/*
+	Must be run in Interrupt context
+	This function handle PCI specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpPCIMgmtKickOut(
+	IN RTMP_ADAPTER		*pAd,
+	IN UCHAR			QueIdx,
+	IN PNDIS_PACKET		pPacket,
+	IN PUCHAR			pSrcBufVA,
+	IN UINT				SrcBufLen)
+{
+	PTXD_STRUC		pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	ULONG			SwIdx = pAd->MgmtRing.TxCpuIdx;
+
+#ifdef RT_BIG_ENDIAN
+    pDestTxD  = (PTXD_STRUC)pAd->MgmtRing.Cell[SwIdx].AllocVa;
+    TxD = *pDestTxD;
+    pTxD = &TxD;
+    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#else
+	pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
+#endif
+
+	pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
+	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
+
+	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
+	pTxD->LastSec0 = 1;
+	pTxD->LastSec1 = 1;
+	pTxD->DMADONE = 0;
+	pTxD->SDLen1 = 0;
+	pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
+	pTxD->SDLen0 = SrcBufLen;
+
+#ifdef RT_BIG_ENDIAN
+	RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif
+
+//==================================================================
+/*	DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
+	for (i = 0; i < (TXWI_SIZE+24); i++)
+	{
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
+		if ( i%4 == 3)
+			DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
+		if ( i%16 == 15)
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));
+	}
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*/
+//=======================================================================
+
+	pAd->RalinkCounters.KickTxCount++;
+	pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	// Increase TX_CTX_IDX, but write to register later.
+	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
+
+	return 0;
+}
+
+
+#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	pRxD)
+{
+	PCIPHER_KEY pWpaKey;
+	INT dBm;
+
+	// Phy errors & CRC errors
+	if (/*(pRxD->PhyErr) ||*/ (pRxD->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 += (pRxD->SDL0 + 14);
+
+	// Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
+	if (pHeader != NULL)
+	{
+		if (pHeader->FC.ToDs)
+		{
+			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 (pRxD->CipherErr)
+	{
+		if (pRxD->CipherErr == 2)
+			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));}
+		else if (pRxD->CipherErr == 1)
+			{DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));}
+		else if (pRxD->CipherErr == 3)
+			DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid "));
+
+        if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+            RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+		DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
+			pRxD->CipherErr,
+			pRxD->SDL0,
+			pRxD->Mcast | pRxD->Bcast,
+			pRxD->MyBss,
+			pRxWI->WirelessCliID,
+//			CipherName[pRxD->CipherAlg],
+			pRxWI->KeyIndex));
+
+		//
+		// MIC Error
+		//
+		if (pRxD->CipherErr == 2)
+		{
+			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+#ifdef WPA_SUPPLICANT_SUPPORT
+            if (pAd->StaCfg.WpaSupplicantUP)
+                WpaSendMicFailureToWpaSupplicant(pAd,
+                                   (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE);
+            else
+#endif // WPA_SUPPLICANT_SUPPORT //
+			    RTMPReportMicError(pAd, pWpaKey);
+
+            if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
+                RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
+		}
+
+		if (pHeader == NULL)
+			return(NDIS_STATUS_SUCCESS);
+		/*if ((pRxD->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);
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+BOOLEAN  RTMPFreeTXDUponTxDmaDone(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			QueIdx)
+{
+	PRTMP_TX_RING pTxRing;
+	PTXD_STRUC	  pTxD;
+#ifdef	RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+#endif
+	PNDIS_PACKET  pPacket;
+	UCHAR	FREE = 0;
+	TXD_STRUC	TxD, *pOriTxD;
+	//ULONG		IrqFlags;
+	BOOLEAN			bReschedule = FALSE;
+
+
+	ASSERT(QueIdx < NUM_OF_TX_RING);
+	pTxRing = &pAd->TxRing[QueIdx];
+
+	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
+	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
+	{
+//		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+		PHEADER_802_11	pHeader80211;
+
+		if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
+		{
+			if (pAd->ate.QID == QueIdx)
+			{
+				pAd->ate.TxDoneCount++;
+				pAd->RalinkCounters.KickTxCount++;
+
+				/* always use QID_AC_BE and FIFO_EDCA */
+				ASSERT(pAd->ate.QID == 0);
+				pAd->ate.TxAc0++;
+
+				FREE++;
+#ifndef RT_BIG_ENDIAN
+				pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
+				pOriTxD = pTxD;
+		        NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
+				pTxD = &TxD;
+#else
+		        pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
+		        pOriTxD = pDestTxD ;
+		        TxD = *pDestTxD;
+		        pTxD = &TxD;
+		        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+				pTxD->DMADONE = 0;
+
+				pHeader80211 = pTxRing->Cell[pTxRing->TxSwFreeIdx].DmaBuf.AllocVa + sizeof(TXWI_STRUC);
+#ifdef RT_BIG_ENDIAN
+				RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_READ, FALSE);
+#endif
+				pHeader80211->Sequence = ++pAd->ate.seq;
+#ifdef RT_BIG_ENDIAN
+				RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE);
+#endif
+
+				if  ((pAd->ate.bQATxStart == TRUE) && (pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.TxDoneCount < pAd->ate.TxCount))
+				{
+					pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
+					pAd->RalinkCounters.OneSecTransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
+					pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
+					INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
+
+					/* get TX_DTX_IDX again */
+					RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
+					goto kick_out;
+				}
+				else if ((pAd->ate.TxStatus == 1)/* or (pAd->ate.bQATxStart == TRUE) ??? */ && (pAd->ate.TxDoneCount == pAd->ate.TxCount))
+				{
+					DBGPRINT(RT_DEBUG_TRACE,("all Tx is done\n"));
+
+					// Tx status enters idle mode.
+					pAd->ate.TxStatus = 0;
+				}
+				else if (!(pAd->ate.Mode & ATE_TXFRAME))
+				{
+					/* not complete sending yet, but someone press the Stop TX botton */
+					DBGPRINT(RT_DEBUG_ERROR,("not complete sending yet, but someone pressed the Stop TX bottom\n"));
+					DBGPRINT(RT_DEBUG_ERROR,("pAd->ate.Mode = 0x%02x\n", pAd->ate.Mode));
+				}
+				else
+				{
+					DBGPRINT(RT_DEBUG_OFF,("pTxRing->TxSwFreeIdx = %d\n", pTxRing->TxSwFreeIdx));
+				}
+
+#ifndef RT_BIG_ENDIAN
+			NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
+#else
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+			*pDestTxD = TxD;
+#endif // RT_BIG_ENDIAN //
+
+				INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
+				continue;
+			}
+		}
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+		// static rate also need NICUpdateFifoStaCounters() function.
+		//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
+			NICUpdateFifoStaCounters(pAd);
+
+		/* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
+		FREE++;
+#ifndef RT_BIG_ENDIAN
+                pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
+		pOriTxD = pTxD;
+                NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
+		pTxD = &TxD;
+#else
+        pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
+        pOriTxD = pDestTxD ;
+        TxD = *pDestTxD;
+        pTxD = &TxD;
+        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+
+		pTxD->DMADONE = 0;
+
+
+#ifdef RALINK_ATE
+		/* Execution of this block is not allowed when ATE is running. */
+		if (!(ATE_ON(pAd)))
+#endif // RALINK_ATE //
+		{
+			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
+			if (pPacket)
+			{
+#ifdef CONFIG_5VT_ENHANCE
+				if (RTMP_GET_PACKET_5VT(pPacket))
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
+				else
+#endif // CONFIG_5VT_ENHANCE //
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNdisPacket as NULL after clear
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
+
+			ASSERT(pPacket == NULL);
+			if (pPacket)
+			{
+#ifdef CONFIG_5VT_ENHANCE
+				if (RTMP_GET_PACKET_5VT(pPacket))
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
+				else
+#endif // CONFIG_5VT_ENHANCE //
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNextNdisPacket as NULL after clear
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
+		}
+
+		pAd->RalinkCounters.TransmittedByteCount +=  (pTxD->SDLen1 + pTxD->SDLen0);
+		pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
+		INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
+		/* get tx_tdx_idx again */
+		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF ,  &pTxRing->TxDmaIdx);
+#ifdef RT_BIG_ENDIAN
+        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+        *pDestTxD = TxD;
+#else
+        NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
+#endif
+
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+kick_out:
+#endif // RALINK_28xx_QA //
+
+		/*
+			ATE_TXCONT mode also need to send some normal frames, so let it in.
+			ATE_STOP must be changed not to be 0xff
+			to prevent it from running into this block.
+		*/
+		if ((pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.QID == QueIdx))
+		{
+			// TxDoneCount++ has been done if QA is used.
+			if (pAd->ate.bQATxStart == FALSE)
+			{
+				pAd->ate.TxDoneCount++;
+			}
+			if (((pAd->ate.TxCount - pAd->ate.TxDoneCount + 1) >= TX_RING_SIZE))
+			{
+				/* Note : We increase TxCpuIdx here, not TxSwFreeIdx ! */
+				INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
+#ifndef RT_BIG_ENDIAN
+				pTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
+				pOriTxD = pTxD;
+		        NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
+				pTxD = &TxD;
+#else
+		        pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
+		        pOriTxD = pDestTxD ;
+		        TxD = *pDestTxD;
+		        pTxD = &TxD;
+		        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+				pTxD->DMADONE = 0;
+#ifndef RT_BIG_ENDIAN
+			NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
+#else
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+			*pDestTxD = TxD;
+#endif
+				// kick Tx-Ring
+				RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * RINGREG_DIFF, pAd->TxRing[QueIdx].TxCpuIdx);
+				pAd->RalinkCounters.KickTxCount++;
+			}
+		}
+#endif // RALINK_ATE //
+//         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+	}
+
+
+	return  bReschedule;
+
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process TX Rings DMA Done interrupt, running in DPC level
+
+	Arguments:
+		Adapter		Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+BOOLEAN	RTMPHandleTxRingDmaDoneInterrupt(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	INT_SOURCE_CSR_STRUC TxRingBitmap)
+{
+//	UCHAR			Count = 0;
+    unsigned long	IrqFlags;
+	BOOLEAN			bReschedule = FALSE;
+
+	// Make sure Tx ring resource won't be used by other threads
+	//NdisAcquireSpinLock(&pAd->TxRingLock);
+
+	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+
+	if (TxRingBitmap.field.Ac0DmaDone)
+		bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
+/*
+	if (TxRingBitmap.field.HccaDmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
+*/
+
+	if (TxRingBitmap.field.Ac3DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
+
+	if (TxRingBitmap.field.Ac2DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
+
+	if (TxRingBitmap.field.Ac1DmaDone)
+		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
+
+	// Make sure to release Tx ring resource
+	//NdisReleaseSpinLock(&pAd->TxRingLock);
+	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+	// Dequeue outgoing frames from TxSwQueue[] and process it
+	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+	return  bReschedule;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process MGMT ring DMA done interrupt, running in DPC level
+
+	Arguments:
+		pAd	Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+VOID	RTMPHandleMgmtRingDmaDoneInterrupt(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PTXD_STRUC	 pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	PNDIS_PACKET pPacket;
+//	int		 i;
+	UCHAR	FREE = 0;
+	PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
+
+	NdisAcquireSpinLock(&pAd->MgmtRingLock);
+
+	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
+	while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
+	{
+		FREE++;
+#ifdef RT_BIG_ENDIAN
+        pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
+        TxD = *pDestTxD;
+        pTxD = &TxD;
+		RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#else
+		pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
+#endif
+		pTxD->DMADONE = 0;
+		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
+
+
+		if (pPacket)
+		{
+			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+		}
+		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
+
+		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
+		if (pPacket)
+		{
+			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+		}
+		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
+		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
+
+#ifdef RT_BIG_ENDIAN
+        RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+        WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD);
+#endif
+	}
+	NdisReleaseSpinLock(&pAd->MgmtRingLock);
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+	Arguments:
+		Adapter		Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID	RTMPHandleTBTTInterrupt(
+	IN PRTMP_ADAPTER pAd)
+{
+	{
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		{
+		}
+	}
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+	Arguments:
+		pAd		Pointer to our adapter. Rewrite beacon content before next send-out.
+
+	IRQL = DISPATCH_LEVEL
+
+	========================================================================
+*/
+VOID	RTMPHandlePreTBTTInterrupt(
+	IN PRTMP_ADAPTER pAd)
+{
+	{
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
+		}
+	}
+
+
+}
+
+VOID	RTMPHandleRxCoherentInterrupt(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	WPDMA_GLO_CFG_STRUC	GloCfg;
+
+	if (pAd == NULL)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
+		return;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
+
+	GloCfg.field.EnTXWriteBackDDONE = 0;
+	GloCfg.field.EnableRxDMA = 0;
+	GloCfg.field.EnableTxDMA = 0;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+	RTMPRingCleanUp(pAd, QID_AC_BE);
+	RTMPRingCleanUp(pAd, QID_AC_BK);
+	RTMPRingCleanUp(pAd, QID_AC_VI);
+	RTMPRingCleanUp(pAd, QID_AC_VO);
+	/*RTMPRingCleanUp(pAd, QID_HCCA);*/
+	RTMPRingCleanUp(pAd, QID_MGMT);
+	RTMPRingCleanUp(pAd, QID_RX);
+
+	RTMPEnableRxTx(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
+}
+
+
+
+
+VOID DBGPRINT_TX_RING(
+	IN PRTMP_ADAPTER  pAd,
+	IN UCHAR          QueIdx)
+{
+	UINT32		Ac0Base;
+	UINT32		Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
+	int			i;
+//	PULONG		pTxD;
+	PULONG	ptemp;
+
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
+	switch (QueIdx)
+	{
+		case QID_AC_BE:
+			RTMP_IO_READ32(pAd, TX_BASE_PTR0, &Ac0Base);
+			RTMP_IO_READ32(pAd, TX_CTX_IDX0, &Ac0SwIdx);
+			RTMP_IO_READ32(pAd, TX_DTX_IDX0, &Ac0HwIdx);
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BE DESCRIPTOR  \n "  ));
+			for (i=0;i<TX_RING_SIZE;i++)
+			{
+				ptemp= (PULONG)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
+				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
+			}
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
+			break;
+		case QID_AC_BK:
+			RTMP_IO_READ32(pAd, TX_BASE_PTR1, &Ac0Base);
+			RTMP_IO_READ32(pAd, TX_CTX_IDX1, &Ac0SwIdx);
+			RTMP_IO_READ32(pAd, TX_DTX_IDX1, &Ac0HwIdx);
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BK DESCRIPTOR  \n "  ));
+			for (i=0;i<TX_RING_SIZE;i++)
+			{
+				ptemp= (PULONG)pAd->TxRing[QID_AC_BK].Cell[i].AllocVa;
+				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
+			}
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
+			break;
+		case QID_AC_VI:
+			RTMP_IO_READ32(pAd, TX_BASE_PTR2, &Ac0Base);
+			RTMP_IO_READ32(pAd, TX_CTX_IDX2, &Ac0SwIdx);
+			RTMP_IO_READ32(pAd, TX_DTX_IDX2, &Ac0HwIdx);
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VI DESCRIPTOR \n "  ));
+			for (i=0;i<TX_RING_SIZE;i++)
+			{
+				ptemp= (PULONG)pAd->TxRing[QID_AC_VI].Cell[i].AllocVa;
+				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
+			}
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
+			break;
+		case QID_AC_VO:
+			RTMP_IO_READ32(pAd, TX_BASE_PTR3, &Ac0Base);
+			RTMP_IO_READ32(pAd, TX_CTX_IDX3, &Ac0SwIdx);
+			RTMP_IO_READ32(pAd, TX_DTX_IDX3, &Ac0HwIdx);
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VO DESCRIPTOR \n "  ));
+			for (i=0;i<TX_RING_SIZE;i++)
+			{
+				ptemp= (PULONG)pAd->TxRing[QID_AC_VO].Cell[i].AllocVa;
+				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
+			}
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
+			break;
+		case QID_MGMT:
+			RTMP_IO_READ32(pAd, TX_BASE_PTR5, &Ac0Base);
+			RTMP_IO_READ32(pAd, TX_CTX_IDX5, &Ac0SwIdx);
+			RTMP_IO_READ32(pAd, TX_DTX_IDX5, &Ac0HwIdx);
+			DBGPRINT_RAW(RT_DEBUG_TRACE, (" All QID_MGMT  DESCRIPTOR \n "  ));
+			for (i=0;i<MGMT_RING_SIZE;i++)
+			{
+				ptemp= (PULONG)pAd->MgmtRing.Cell[i].AllocVa;
+				DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
+			}
+			DBGPRINT_RAW(RT_DEBUG_TRACE, ("  \n "  ));
+			break;
+
+		default:
+			DBGPRINT_ERR(("DBGPRINT_TX_RING(Ring %d) not supported\n", QueIdx));
+			break;
+	}
+	AC0freeIdx = pAd->TxRing[QueIdx].TxSwFreeIdx;
+
+	DBGPRINT(RT_DEBUG_TRACE,("TxRing%d, TX_DTX_IDX=%d, TX_CTX_IDX=%d\n", QueIdx, Ac0HwIdx, Ac0SwIdx));
+	DBGPRINT_RAW(RT_DEBUG_TRACE,("	TxSwFreeIdx[%d]", AC0freeIdx));
+	DBGPRINT_RAW(RT_DEBUG_TRACE,("	pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
+
+
+}
+
+
+VOID DBGPRINT_RX_RING(
+	IN PRTMP_ADAPTER  pAd)
+{
+	UINT32		Ac0Base;
+	UINT32		Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
+//	PULONG	 pTxD;
+	int			i;
+	UINT32	*ptemp;
+//	PRXD_STRUC		pRxD;
+
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n "  ));
+	RTMP_IO_READ32(pAd, RX_BASE_PTR, &Ac0Base);
+	RTMP_IO_READ32(pAd, RX_CRX_IDX, &Ac0SwIdx);
+	RTMP_IO_READ32(pAd, RX_DRX_IDX, &Ac0HwIdx);
+	AC0freeIdx = pAd->RxRing.RxSwReadIdx;
+
+	DBGPRINT_RAW(RT_DEBUG_TRACE, ("All RX DSP  \n "  ));
+	for (i=0;i<RX_RING_SIZE;i++)
+	{
+		ptemp = (UINT32 *)pAd->RxRing.Cell[i].AllocVa;
+		DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d]  %08x: %08x: %08x: %08x\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("RxRing, RX_DRX_IDX=%d, RX_CRX_IDX=%d \n", Ac0HwIdx, Ac0SwIdx));
+	DBGPRINT_RAW(RT_DEBUG_TRACE,("	RxSwReadIdx [%d]=", AC0freeIdx));
+	DBGPRINT_RAW(RT_DEBUG_TRACE,("	pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
+}
+
+
+PNDIS_PACKET GetPacketFromRxRing(
+	IN		PRTMP_ADAPTER	pAd,
+	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
+	OUT		BOOLEAN			*pbReschedule,
+	IN OUT	UINT32			*pRxPending)
+{
+	PRXD_STRUC				pRxD;
+#ifdef RT_BIG_ENDIAN
+	PRXD_STRUC				pDestRxD;
+	RXD_STRUC				RxD;
+#endif
+	PNDIS_PACKET			pRxPacket = NULL;
+	PNDIS_PACKET			pNewPacket;
+	PVOID					AllocVa;
+	NDIS_PHYSICAL_ADDRESS	AllocPa;
+	BOOLEAN					bReschedule = FALSE;
+
+	RTMP_SEM_LOCK(&pAd->RxRingLock);
+
+	if (*pRxPending == 0)
+	{
+		// Get how may packets had been received
+		RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
+
+		if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
+		{
+			// no more rx packets
+			bReschedule = FALSE;
+			goto done;
+		}
+
+		// get rx pending count
+		if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
+			*pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
+		else
+			*pRxPending	= pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
+
+	}
+
+#ifdef RT_BIG_ENDIAN
+	pDestRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
+	RxD = *pDestRxD;
+	pRxD = &RxD;
+	RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
+#else
+	// Point to Rx indexed rx ring descriptor
+	pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
+#endif
+
+	if (pRxD->DDONE == 0)
+	{
+		*pRxPending = 0;
+		// DMAIndx had done but DDONE bit not ready
+		bReschedule = TRUE;
+		goto done;
+	}
+
+
+	// return rx descriptor
+	NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
+
+	pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
+
+	if (pNewPacket)
+	{
+		// unmap the rx buffer
+		PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
+					 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
+		pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
+
+		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize	= RX_BUFFER_AGGRESIZE;
+		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket		= (PNDIS_PACKET) pNewPacket;
+		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa	= AllocVa;
+		pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa	= AllocPa;
+		/* update SDP0 to new buffer of rx packet */
+		pRxD->SDP0 = AllocPa;
+	}
+	else
+	{
+		//DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n"));
+		pRxPacket = NULL;
+		bReschedule = TRUE;
+	}
+
+	pRxD->DDONE = 0;
+
+	// had handled one rx packet
+	*pRxPending = *pRxPending - 1;
+
+	// update rx descriptor and kick rx
+#ifdef RT_BIG_ENDIAN
+	RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
+	WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, FALSE, TYPE_RXD);
+#endif
+	INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
+
+	pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
+	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+
+done:
+	RTMP_SEM_UNLOCK(&pAd->RxRingLock);
+	*pbReschedule = bReschedule;
+	return pRxPacket;
+}
+
+
+NDIS_STATUS MlmeHardTransmitTxRing(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket)
+{
+	PACKET_INFO	PacketInfo;
+	PUCHAR			pSrcBufVA;
+	UINT			SrcBufLen;
+	PTXD_STRUC		pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	PHEADER_802_11	pHeader_802_11;
+	BOOLEAN			bAckRequired, bInsertTimestamp;
+	ULONG			SrcBufPA;
+	//UCHAR			TxBufIdx;
+	UCHAR			MlmeRate;
+	ULONG			SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
+	PTXWI_STRUC	pFirstTxWI;
+	//ULONG	i;
+	//HTTRANSMIT_SETTING	MlmeTransmit;   //Rate for this MGMT frame.
+	ULONG	 FreeNum;
+	MAC_TABLE_ENTRY	*pMacEntry = NULL;
+
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+
+	if (pSrcBufVA == NULL)
+	{
+		// The buffer shouldn't be NULL
+		return NDIS_STATUS_FAILURE;
+	}
+
+	// Make sure MGMT ring resource won't be used by other threads
+	//NdisAcquireSpinLock(&pAd->TxRingLock);
+
+	FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+
+	if (FreeNum == 0)
+	{
+		//NdisReleaseSpinLock(&pAd->TxRingLock);
+		return NDIS_STATUS_FAILURE;
+	}
+
+	SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
+
+#ifndef RT_BIG_ENDIAN
+	pTxD  = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
+#else
+    pDestTxD  = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
+    TxD = *pDestTxD;
+    pTxD = &TxD;
+    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+
+	if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
+	{
+		DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
+		//NdisReleaseSpinLock(&pAd->TxRingLock);
+		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 (pAd->StaCfg.Psm == PWR_SAVE)
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+			AsicForceWakeup(pAd, TRUE);
+	}
+#endif // CONFIG_STA_SUPPORT //
+	pFirstTxWI	=(PTXWI_STRUC)pSrcBufVA;
+
+	pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
+	if (pHeader_802_11->Addr1[0] & 0x01)
+	{
+		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+	}
+	else
+	{
+		MlmeRate = pAd->CommonCfg.MlmeRate;
+	}
+
+	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+		(pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
+	{
+		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
+	}
+
+	// Verify Mlme rate for a / g bands.
+	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
+		MlmeRate = RATE_6;
+
+	//
+	// 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.
+	//
+	//
+	// 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)
+    {
+	if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
+	{
+		pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+	}
+	else
+	{
+		pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
+	}
+    }
+#endif // CONFIG_STA_SUPPORT //
+
+	bInsertTimestamp = FALSE;
+	if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
+	{
+		bAckRequired = FALSE;
+	}
+	else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
+	{
+		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"));
+		//NdisReleaseSpinLock(&pAd->TxRingLock);
+		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.
+	// Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
+	if (pMacEntry == NULL)
+	{
+	RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
+		0, RESERVED_WCID, (SrcBufLen - 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 - TXWI_SIZE),
+					pMacEntry->MaxHTPhyMode.field.MCS, 0,
+					(UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
+					IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+	}
+
+	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
+	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
+//	pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE;
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
+#endif
+	SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
+
+
+	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
+	pTxD->LastSec0 = 1;
+	pTxD->LastSec1 = 1;
+	pTxD->SDLen0 = SrcBufLen;
+	pTxD->SDLen1 = 0;
+	pTxD->SDPtr0 = SrcBufPA;
+	pTxD->DMADONE = 0;
+
+#ifdef RT_BIG_ENDIAN
+    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif
+
+	pAd->RalinkCounters.KickTxCount++;
+	pAd->RalinkCounters.OneSecTxDoneCount++;
+
+	// Increase TX_CTX_IDX, but write to register later.
+	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
+
+	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10,  pAd->TxRing[QueIdx].TxCpuIdx);
+
+	// Make sure to release MGMT ring resource
+//	NdisReleaseSpinLock(&pAd->TxRingLock);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+NDIS_STATUS MlmeDataHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket)
+{
+	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+		)
+	{
+		return NDIS_STATUS_FAILURE;
+	}
+
+	return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
+}
+
+
+/*
+	========================================================================
+
+	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);
+	//RT2860c??  fixed using EDCA queue for test...  We doubt Queue1 has problem.  2006-09-26 Jan
+	//pTxD->QSEL= FIFO_EDCA;
+	/*
+	if (pAd->bGenOneHCCA == TRUE)
+		pTxD->QSEL= FIFO_HCCA;
+	*/
+	pTxD->DMADONE = 0;
+}
diff --git a/drivers/staging/rt3090/common/cmm_info.c b/drivers/staging/rt3090/common/cmm_info.c
new file mode 100644
index 0000000..5be0714
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_info.c
@@ -0,0 +1,3717 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_info.c
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#include "../rt_config.h"
+
+
+INT	Show_SSID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_WirelessMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_TxBurst_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_TxPreamble_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_TxPower_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_Channel_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_BGProtection_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_RTSThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_FragThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+#ifdef DOT11_N_SUPPORT
+INT	Show_HtBw_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtMcs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtGi_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtOpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtExtcha_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtMpduDensity_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtBaWinSize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtRdg_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtAmsdu_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_HtAutoBa_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+#endif // DOT11_N_SUPPORT //
+
+INT	Show_CountryRegion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_CountryRegionABand_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_CountryCode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+#ifdef AGGREGATION_SUPPORT
+INT	Show_PktAggregate_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef WMM_SUPPORT
+INT	Show_WmmCapable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+#endif // WMM_SUPPORT //
+
+INT	Show_IEEE80211H_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+#ifdef CONFIG_STA_SUPPORT
+INT	Show_NetworkType_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+#endif // CONFIG_STA_SUPPORT //
+
+INT	Show_AuthMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_EncrypType_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_DefaultKeyID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_Key1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_Key2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_Key3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_Key4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+INT	Show_WPAPSK_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf);
+
+static struct {
+	PSTRING name;
+	INT (*show_proc)(PRTMP_ADAPTER pAdapter, PSTRING 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	PSTRING			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	PSTRING			arg)
+{
+	int retval;
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+	retval = RT_CfgSetCountryRegion(pAd, arg, BAND_24G);
+	if (retval == FALSE)
+		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	PSTRING			arg)
+{
+	int retval;
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+	retval = RT_CfgSetCountryRegion(pAd, arg, BAND_5G);
+	if (retval == FALSE)
+		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	PSTRING			arg)
+{
+	INT	success = TRUE;
+
+	success = RT_CfgSetWirelessMode(pAd, arg);
+	if (success)
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			LONG	WirelessMode = pAd->CommonCfg.PhyMode;
+
+			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
+			}
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+		// it is needed to set SSID to take effect
+#ifdef DOT11_N_SUPPORT
+		SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+		DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%d)\n", pAd->CommonCfg.PhyMode));
+	}
+	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	PSTRING			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	PSTRING			arg)
+{
+	int retval;
+
+	retval = RT_CfgSetShortSlot(pAd, arg);
+	if (retval == TRUE)
+		DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
+
+	return retval;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Set Tx power
+    Return:
+        TRUE if all parameters are OK, FALSE otherwise
+    ==========================================================================
+*/
+INT	Set_TxPower_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	LONG TxPower;
+	INT   success = FALSE;
+
+	TxPower = 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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			arg)
+{
+	LONG 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	PSTRING			arg)
+{
+	LONG 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
+
+
+#ifdef INF_AMAZON_PPA
+INT	Set_INF_AMAZON_SE_PPA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+	ULONG aggre;
+	UINT status;
+
+	aggre = simple_strtol(arg, 0, 10);
+
+	if (aggre == 1)
+	{
+		if(pAd->PPAEnable==TRUE)
+		{
+			printk("INF_AMAZON_SE_PPA already enabled \n");
+		}
+		else
+		{
+			if (ppa_hook_directpath_register_dev_fn)
+			{
+				UINT32 g_if_id;
+
+				if (pAd->pDirectpathCb == NULL)
+				{
+					 pAd->pDirectpathCb = (PPA_DIRECTPATH_CB *) kmalloc (sizeof(PPA_DIRECTPATH_CB), GFP_ATOMIC);
+				        printk("Realloc memory for  pDirectpathCb ??\n");
+				}
+
+				/* register callback */
+				pAd->pDirectpathCb->rx_fn = NULL;
+				pAd->pDirectpathCb->stop_tx_fn = NULL;
+				pAd->pDirectpathCb->start_tx_fn = NULL;
+
+				status = ppa_hook_directpath_register_dev_fn(&g_if_id, pAd->net_dev, pAd->pDirectpathCb, PPA_F_DIRECTPATH_ETH_IF);
+
+				if(status==1)
+				{
+					pAd->g_if_id=g_if_id;
+					printk("register INF_AMAZON_SE_PPA success :ret:%d id:%d:%d\n",status,pAd->g_if_id,g_if_id);
+					pAd->PPAEnable=TRUE;
+				}
+				else
+				{
+					printk("register INF_AMAZON_SE_PPA fail :ret:%d\n",status);
+				}
+
+			}
+			else
+			{
+				printk("INF_AMAZON_SE_PPA enable fail : there is no INF_AMAZON_SE_PPA module . \n");
+			}
+		}
+
+
+	}
+	else if (aggre == 0)
+	{
+		if(pAd->PPAEnable==FALSE)
+		{
+
+printk("INF_AMAZON_SE_PPA already disable \n");
+		}
+		else
+		{
+			if (ppa_hook_directpath_register_dev_fn)
+			{
+				UINT32 g_if_id;
+				g_if_id=pAd->g_if_id;
+				printk("g_if_id=%d \n",pAd->g_if_id);
+				status=ppa_hook_directpath_register_dev_fn(&g_if_id, pAd->net_dev, NULL, PPA_F_DIRECTPATH_DEREGISTER);
+
+				if(status==1)
+				{
+					pAd->g_if_id=0;
+					printk("unregister INF_AMAZON_SE_PPA success :ret:%d\n",status);
+					pAd->PPAEnable=FALSE;
+				}
+				else
+				{
+					printk("unregister INF_AMAZON_SE_PPA fail :ret:%d\n",status);
+				}
+
+			}
+			else
+			{
+				printk("INF_AMAZON_SE_PPA enable fail : there is no INF_AMAZON_SE_PPA module . \n");
+			}
+		}
+
+	}
+	else
+	{
+		printk("Invalid argument %d \n",aggre);
+		return FALSE;  //Invalid argument
+	}
+
+	return TRUE;
+
+}
+#endif // INF_AMAZON_PPA //
+
+
+/*
+    ==========================================================================
+    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	PSTRING			arg)
+{
+    LONG 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	PSTRING			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	PSTRING			arg)
+{
+#ifdef RTMP_MAC_PCI
+	INT i, QueIdx=0;
+//  ULONG	RegValue;
+        PRT28XX_RXD_STRUC pRxD;
+        PTXD_STRUC pTxD;
+	PRTMP_TX_RING	pTxRing = &pAd->TxRing[QueIdx];
+	PRTMP_MGMT_RING	pMgmtRing = &pAd->MgmtRing;
+	PRTMP_RX_RING	pRxRing = &pAd->RxRing;
+
+	for(i=0;i<TX_RING_SIZE;i++)
+	{
+	    pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
+	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
+	    hex_dump("Tx Descriptor", (PUCHAR)pTxD, 16);
+	    DBGPRINT(RT_DEBUG_OFF, ("pTxD->DMADONE = %x\n", pTxD->DMADONE));
+	}
+	DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
+	for(i=0;i<MGMT_RING_SIZE;i++)
+	{
+	    pTxD = (PTXD_STRUC) pMgmtRing->Cell[i].AllocVa;
+	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
+	    hex_dump("Mgmt Descriptor", (PUCHAR)pTxD, 16);
+	    DBGPRINT(RT_DEBUG_OFF, ("pMgmt->DMADONE = %x\n", pTxD->DMADONE));
+	}
+	DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n"));
+	for(i=0;i<RX_RING_SIZE;i++)
+	{
+	    pRxD = (PRT28XX_RXD_STRUC) pRxRing->Cell[i].AllocVa;
+	    DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i));
+	    hex_dump("Rx Descriptor", (PUCHAR)pRxD, 16);
+	    DBGPRINT(RT_DEBUG_OFF, ("pRxD->DDONE = %x\n", pRxD->DDONE));
+	}
+#endif // RTMP_MAC_PCI //
+
+	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	PSTRING			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));
+
+	// Reset HotSpot counter
+
+
+	return TRUE;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Add WPA key process.
+		In Adhoc WPANONE, bPairwise = 0;  KeyIdx = 0;
+
+	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:
+
+	========================================================================
+*/
+
+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));
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+	// 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);
+	}
+	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
+}
+#endif // 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
+
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+/*
+	========================================================================
+	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
+
+	// if no change, do nothing
+	/* bug fix
+	if (pAd->CommonCfg.PhyMode == phymode)
+		return;
+    */
+	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)
+				Wcid = pEntry->Aid;
+			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 RTMP_MAC_PCI
+	RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
+#endif // RTMP_MAC_PCI //
+
+	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:
+    ==========================================================================
+*/
+PSTRING 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";
+}
+
+PSTRING 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";
+}
+
+
+/*
+    ==========================================================================
+    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+23+9+7+3)	// Channel+SSID+Bssid+Security+Signal+WiressMode+NetworkType
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+VOID	RTMPCommSiteSurveyData(
+	IN  PSTRING		msg,
+	IN  PBSS_ENTRY	pBss)
+{
+	INT         Rssi = 0;
+	UINT        Rssi_Quality = 0;
+	NDIS_802_11_NETWORK_TYPE    wireless_mode;
+	CHAR		Ssid[MAX_LEN_OF_SSID +1];
+	STRING		SecurityStr[32] = {0};
+	NDIS_802_11_ENCRYPTION_STATUS	ap_cipher = Ndis802_11EncryptionDisabled;
+	NDIS_802_11_AUTHENTICATION_MODE	ap_auth_mode = Ndis802_11AuthModeOpen;
+
+	memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
+
+		//Channel
+		sprintf(msg+strlen(msg),"%-4d", pBss->Channel);
+		//SSID
+		memcpy(Ssid, pBss->Ssid, pBss->SsidLen);
+		Ssid[pBss->SsidLen] = '\0';
+		sprintf(msg+strlen(msg),"%-33s", Ssid);
+		//BSSID
+		sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x   ",
+			pBss->Bssid[0],
+			pBss->Bssid[1],
+			pBss->Bssid[2],
+			pBss->Bssid[3],
+			pBss->Bssid[4],
+			pBss->Bssid[5]);
+
+	//Security
+	if ((Ndis802_11AuthModeWPA <= pBss->AuthMode) &&
+		(pBss->AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+	{
+		if (pBss->AuthModeAux == Ndis802_11AuthModeWPANone)
+		{
+			ap_auth_mode = pBss->AuthMode;
+			if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+				ap_cipher = pBss->WPA.PairCipher;
+			else
+				ap_cipher = Ndis802_11Encryption4Enabled;
+		}
+		else if (pBss->AuthModeAux == Ndis802_11AuthModeOpen)
+		{
+			ap_auth_mode = pBss->AuthMode;
+			if ((ap_auth_mode == Ndis802_11AuthModeWPA) ||
+				(ap_auth_mode == Ndis802_11AuthModeWPAPSK))
+			{
+				if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+					ap_cipher = pBss->WPA.PairCipher;
+				else
+					ap_cipher = Ndis802_11Encryption4Enabled;
+			}
+			else if ((ap_auth_mode == Ndis802_11AuthModeWPA2) ||
+					 (ap_auth_mode == Ndis802_11AuthModeWPA2PSK))
+			{
+				if (pBss->WPA2.PairCipherAux == Ndis802_11WEPDisabled)
+					ap_cipher = pBss->WPA2.PairCipher;
+				else
+					ap_cipher = Ndis802_11Encryption4Enabled;
+			}
+		}
+		else if ((pBss->AuthMode == Ndis802_11AuthModeWPAPSK) ||
+				 (pBss->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		{
+			if ((pBss->AuthModeAux == Ndis802_11AuthModeWPAPSK) ||
+				(pBss->AuthModeAux == Ndis802_11AuthModeWPA2PSK))
+				ap_auth_mode = Ndis802_11AuthModeWPA1PSKWPA2PSK;
+			else
+				ap_auth_mode = pBss->AuthMode;
+
+			if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
+				ap_cipher = pBss->WPA.PairCipher;
+		}
+		else if ((pBss->AuthMode == Ndis802_11AuthModeWPA) ||
+				 (pBss->AuthMode == Ndis802_11AuthModeWPA2))
+		{
+			if ((pBss->AuthModeAux == Ndis802_11AuthModeWPA) ||
+				(pBss->AuthMode == Ndis802_11AuthModeWPA2))
+				ap_auth_mode = Ndis802_11AuthModeWPA1WPA2;
+			else
+				ap_auth_mode = pBss->AuthMode;
+
+			if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher)
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled))
+				ap_cipher = Ndis802_11Encryption4Enabled;
+			else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) &&
+					 (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) &&
+					 (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled))
+				ap_cipher = pBss->WPA.PairCipher;
+		}
+
+		sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
+	}
+	else
+	{
+		ap_auth_mode = pBss->AuthMode;
+		ap_cipher = pBss->WepStatus;
+		if (ap_cipher == Ndis802_11WEPDisabled)
+			sprintf(SecurityStr, "NONE");
+		else if (ap_cipher == Ndis802_11WEPEnabled)
+			sprintf(SecurityStr, "WEP");
+		else
+			sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher));
+	}
+
+	sprintf(msg+strlen(msg), "%-23s", SecurityStr);
+
+		// Rssi
+		Rssi = (INT)pBss->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(pBss);
+		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 (pBss->BssType == BSS_ADHOC)
+			sprintf(msg+strlen(msg),"%-3s", " Ad");
+		else
+			sprintf(msg+strlen(msg),"%-3s", " In");
+
+        sprintf(msg+strlen(msg),"\n");
+
+	return;
+}
+
+VOID RTMPIoctlGetSiteSurvey(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	PSTRING		msg;
+	INT		i=0;
+	INT			WaitCnt;
+	INT		Status=0;
+    INT         max_len = LINE_LEN;
+	PBSS_ENTRY	pBss;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	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 );
+	sprintf(msg,"%s","\n");
+	sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-23s%-9s%-7s%-3s\n",
+	    "Ch", "SSID", "BSSID", "Security", "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++)
+	{
+		pBss = &pAdapter->ScanTab.BssEntry[i];
+
+		if( pBss->Channel==0)
+			break;
+
+		if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
+			break;
+
+
+		RTMPCommSiteSurveyData(msg, pBss);
+
+#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 = kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
+	if (msg == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
+		return;
+	}
+	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);
+}
+
+
+#ifdef DOT11_N_SUPPORT
+INT	Set_BASetup_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+    UCHAR mac[6], tid;
+	PSTRING token;
+	STRING 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.
+*/
+	//DBGPRINT(RT_DEBUG_TRACE,("\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 = (UCHAR) 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, (&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+		DBGPRINT(RT_DEBUG_OFF, ("\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, (PUCHAR) mac);
+
+	if (pEntry) {
+		DBGPRINT(RT_DEBUG_OFF, ("\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	PSTRING			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	PSTRING			arg)
+{
+    UCHAR mac[6], tid;
+	PSTRING token;
+	STRING sepValue[] = ":", DASH = '-';
+	INT i;
+    MAC_TABLE_ENTRY *pEntry;
+
+    //DBGPRINT(RT_DEBUG_TRACE,("\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, (&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+	    DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
+								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
+
+	    pEntry = MacTableLookup(pAd, (PUCHAR) mac);
+
+	    if (pEntry) {
+	        DBGPRINT(RT_DEBUG_OFF, ("\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	PSTRING			arg)
+{
+    UCHAR mac[6], tid;
+	PSTRING token;
+	STRING sepValue[] = ":", DASH = '-';
+	INT i;
+    MAC_TABLE_ENTRY *pEntry;
+
+    //DBGPRINT(RT_DEBUG_TRACE,("\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, (&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+		DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x",
+								mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid));
+
+		pEntry = MacTableLookup(pAd, (PUCHAR) mac);
+
+		if (pEntry) {
+		    DBGPRINT(RT_DEBUG_OFF, ("\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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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_HtDisallowTKIP_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+	if (Value == 1)
+	{
+		pAd->CommonCfg.HT_DisallowTKIP = TRUE;
+	}
+	else
+	{
+		pAd->CommonCfg.HT_DisallowTKIP = FALSE;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Set_HtDisallowTKIP_Proc ::%s\n",
+				(pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "enabled" : "disabled"));
+
+	return TRUE;
+}
+
+INT	Set_HtOpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			arg)
+{
+    UCHAR mac[6], mode;
+	PSTRING token;
+	STRING sepValue[] = ":", DASH = '-';
+	INT i;
+    MAC_TABLE_ENTRY *pEntry;
+
+    //DBGPRINT(RT_DEBUG_TRACE,("\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, (&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+		DBGPRINT(RT_DEBUG_OFF, ("\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) {
+		    DBGPRINT(RT_DEBUG_OFF, ("\nSendPSMPAction MIPS mode = %d\n", mode));
+		    SendPSMPAction(pAd, pEntry->Aid, mode);
+		}
+
+		return TRUE;
+	}
+
+	return FALSE;
+
+
+}
+
+INT	Set_HtMIMOPSmode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			arg)
+{
+	ULONG Value;
+
+	Value = simple_strtol(arg, 0, 10);
+
+#ifdef RTMP_MAC_PCI
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+#endif // RTMP_MAC_PCI //
+	{
+		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 //
+
+
+
+INT Set_LongRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PSTRING			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	PSTRING			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;
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+PSTRING RTMPGetRalinkAuthModeStr(
+    IN  NDIS_802_11_AUTHENTICATION_MODE authMode)
+{
+	switch(authMode)
+	{
+		case Ndis802_11AuthModeOpen:
+			return "OPEN";
+		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";
+		case Ndis802_11AuthModeWPANone:
+			return "WPANONE";
+		default:
+			return "UNKNOW";
+	}
+}
+
+PSTRING RTMPGetRalinkEncryModeStr(
+    IN  USHORT encryMode)
+{
+	switch(encryMode)
+	{
+		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";
+		default:
+			return "UNKNOW";
+	}
+}
+
+INT RTMPShowCfgValue(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			pName,
+	IN	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
+	return 0;
+}
+
+INT	Show_TxPreamble_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			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	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
+	return 0;
+}
+
+INT	Show_Channel_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
+	return 0;
+}
+
+INT	Show_BGProtection_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			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	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
+	return 0;
+}
+
+INT	Show_FragThreshold_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
+	return 0;
+}
+
+#ifdef DOT11_N_SUPPORT
+INT	Show_HtBw_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
+	return 0;
+}
+
+INT	Show_HtBaWinSize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+	return 0;
+}
+
+INT	Show_HtRdg_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
+	return 0;
+}
+
+INT	Show_HtAmsdu_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
+	return 0;
+}
+
+INT	Show_HtAutoBa_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			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	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
+	return 0;
+}
+
+INT	Show_CountryRegionABand_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
+	return 0;
+}
+
+INT	Show_CountryCode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
+	return 0;
+}
+
+#ifdef AGGREGATION_SUPPORT
+INT	Show_PktAggregate_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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	PSTRING			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((PCHAR)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	PSTRING			pBuf)
+{
+	Show_WepKey_Proc(pAd, 0, pBuf);
+	return 0;
+}
+
+INT	Show_Key2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	Show_WepKey_Proc(pAd, 1, pBuf);
+	return 0;
+}
+
+INT	Show_Key3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	Show_WepKey_Proc(pAd, 2, pBuf);
+	return 0;
+}
+
+INT	Show_Key4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			pBuf)
+{
+	Show_WepKey_Proc(pAd, 3, pBuf);
+	return 0;
+}
+
+INT	Show_WPAPSK_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	OUT	PSTRING			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/rt3090/common/cmm_mac_pci.c b/drivers/staging/rt3090/common/cmm_mac_pci.c
new file mode 100644
index 0000000..8e16363
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_mac_pci.c
@@ -0,0 +1,1757 @@
+/*
+ *************************************************************************
+ * 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 RTMP_MAC_PCI
+
+#include "../rt_config.h"
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Allocate DMA memory blocks for send, receive
+
+	Arguments:
+		Adapter		Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS
+		NDIS_STATUS_FAILURE
+		NDIS_STATUS_RESOURCES
+
+	IRQL = PASSIVE_LEVEL
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS	RTMPAllocTxRxRingMemory(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	ULONG			RingBasePaHigh;
+	ULONG			RingBasePaLow;
+	PVOID			RingBaseVa;
+	INT				index, num;
+	PTXD_STRUC		pTxD;
+	PRXD_STRUC		pRxD;
+	ULONG			ErrorValue = 0;
+	PRTMP_TX_RING	pTxRing;
+	PRTMP_DMABUF	pDmaBuf;
+	PNDIS_PACKET	pPacket;
+//	PRTMP_REORDERBUF	pReorderBuf;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+	do
+	{
+		//
+		// Allocate all ring descriptors, include TxD, RxD, MgmtD.
+		// Although each size is different, to prevent cacheline and alignment
+		// issue, I intentional set them all to 64 bytes.
+		//
+		for (num=0; num<NUM_OF_TX_RING; num++)
+		{
+			ULONG  BufBasePaHigh;
+			ULONG  BufBasePaLow;
+			PVOID  BufBaseVa;
+
+			//
+			// Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
+			//
+			pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
+			RTMP_AllocateTxDescMemory(
+				pAd,
+				num,
+				pAd->TxDescRing[num].AllocSize,
+				FALSE,
+				&pAd->TxDescRing[num].AllocVa,
+				&pAd->TxDescRing[num].AllocPa);
+
+			if (pAd->TxDescRing[num].AllocVa == NULL)
+			{
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+
+			// Zero init this memory block
+			NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
+
+			// Save PA & VA for further operation
+			RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
+			RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
+			RingBaseVa     = pAd->TxDescRing[num].AllocVa;
+
+			//
+			// Allocate all 1st TXBuf's memory for this TxRing
+			//
+			pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
+			RTMP_AllocateFirstTxBuffer(
+				pAd,
+				num,
+				pAd->TxBufSpace[num].AllocSize,
+				FALSE,
+				&pAd->TxBufSpace[num].AllocVa,
+				&pAd->TxBufSpace[num].AllocPa);
+
+			if (pAd->TxBufSpace[num].AllocVa == NULL)
+			{
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+
+			// Zero init this memory block
+			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
+
+			// Save PA & VA for further operation
+			BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
+			BufBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
+			BufBaseVa     = pAd->TxBufSpace[num].AllocVa;
+
+			//
+			// Initialize Tx Ring Descriptor and associated buffer memory
+			//
+			pTxRing = &pAd->TxRing[num];
+			for (index = 0; index < TX_RING_SIZE; index++)
+			{
+				pTxRing->Cell[index].pNdisPacket = NULL;
+				pTxRing->Cell[index].pNextNdisPacket = NULL;
+				// Init Tx Ring Size, Va, Pa variables
+				pTxRing->Cell[index].AllocSize = TXD_SIZE;
+				pTxRing->Cell[index].AllocVa = RingBaseVa;
+				RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
+				RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
+
+				// Setup Tx Buffer size & address. only 802.11 header will store in this space
+				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
+				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
+				pDmaBuf->AllocVa = BufBaseVa;
+				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
+				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
+
+				// link the pre-allocated TxBuf to TXD
+				pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
+				pTxD->SDPtr0 = BufBasePaLow;
+				// advance to next ring descriptor address
+				pTxD->DMADONE = 1;
+#ifdef RT_BIG_ENDIAN
+				RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+				RingBasePaLow += TXD_SIZE;
+				RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
+
+				// advance to next TxBuf address
+				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
+				BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
+		}
+		if (Status == NDIS_STATUS_RESOURCES)
+			break;
+
+		//
+		// Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
+		//
+		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
+		RTMP_AllocateMgmtDescMemory(
+			pAd,
+			pAd->MgmtDescRing.AllocSize,
+			FALSE,
+			&pAd->MgmtDescRing.AllocVa,
+			&pAd->MgmtDescRing.AllocPa);
+
+		if (pAd->MgmtDescRing.AllocVa == NULL)
+		{
+			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			break;
+		}
+
+		// Zero init this memory block
+		NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+
+		// Save PA & VA for further operation
+		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
+		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
+		RingBaseVa     = pAd->MgmtDescRing.AllocVa;
+
+		//
+		// Initialize MGMT Ring and associated buffer memory
+		//
+		for (index = 0; index < MGMT_RING_SIZE; index++)
+		{
+			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
+			// Init MGMT Ring Size, Va, Pa variables
+			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
+			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
+			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
+			RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
+
+			// Offset to next ring descriptor address
+			RingBasePaLow += TXD_SIZE;
+			RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
+
+			// link the pre-allocated TxBuf to TXD
+			pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
+			pTxD->DMADONE = 1;
+
+#ifdef RT_BIG_ENDIAN
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+			// no pre-allocated buffer required in MgmtRing for scatter-gather case
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
+
+		//
+		// Allocate RX ring descriptor's memory except Tx ring which allocated eariler
+		//
+		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
+		RTMP_AllocateRxDescMemory(
+			pAd,
+			pAd->RxDescRing.AllocSize,
+			FALSE,
+			&pAd->RxDescRing.AllocVa,
+			&pAd->RxDescRing.AllocPa);
+
+		if (pAd->RxDescRing.AllocVa == NULL)
+		{
+			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+			DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
+			Status = NDIS_STATUS_RESOURCES;
+			break;
+		}
+
+		// Zero init this memory block
+		NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
+
+
+		DBGPRINT(RT_DEBUG_OFF,
+					("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize));
+
+		// Save PA & VA for further operation
+		RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
+		RingBasePaLow  = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
+		RingBaseVa     = pAd->RxDescRing.AllocVa;
+
+		//
+		// Initialize Rx Ring and associated buffer memory
+		//
+		for (index = 0; index < RX_RING_SIZE; index++)
+		{
+			// Init RX Ring Size, Va, Pa variables
+			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
+			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
+			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
+			RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
+
+			//NdisZeroMemory(RingBaseVa, RXD_SIZE);
+
+			// Offset to next ring descriptor address
+			RingBasePaLow += RXD_SIZE;
+			RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
+
+			// Setup Rx associated Buffer size & allocate share memory
+			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
+			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
+			pPacket = RTMP_AllocateRxPacketBuffer(
+				pAd,
+				pDmaBuf->AllocSize,
+				FALSE,
+				&pDmaBuf->AllocVa,
+				&pDmaBuf->AllocPa);
+
+			/* keep allocated rx packet */
+			pAd->RxRing.Cell[index].pNdisPacket = pPacket;
+
+			// Error handling
+			if (pDmaBuf->AllocVa == NULL)
+			{
+				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
+				DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
+				Status = NDIS_STATUS_RESOURCES;
+				break;
+			}
+
+			// Zero init this memory block
+			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
+
+			// Write RxD buffer address & allocated buffer length
+			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
+			pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
+			pRxD->DDONE = 0;
+
+#ifdef RT_BIG_ENDIAN
+			RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
+#endif
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
+
+	}	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;
+	}
+
+	if (Status != NDIS_STATUS_SUCCESS)
+	{
+		// Log error inforamtion
+		NdisWriteErrorLogEntry(
+			pAd->AdapterHandle,
+			NDIS_ERROR_CODE_OUT_OF_RESOURCES,
+			1,
+			ErrorValue);
+	}
+
+	// Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here.
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTxRxRingAndBacklogQueue\n"));
+
+/*
+		// Disable DMA.
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+		GloCfg.word &= 0xff0;
+		GloCfg.field.EnTXWriteBackDDONE =1;
+		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+*/
+
+		// Initialize all transmit related software queues
+		for(index = 0; index < NUM_OF_TX_RING; index++)
+		{
+			InitializeQueueHeader(&pAd->TxSwQueue[index]);
+			// Init TX rings index pointer
+			pAd->TxRing[index].TxSwFreeIdx = 0;
+			pAd->TxRing[index].TxCpuIdx = 0;
+			//RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TX_CTX_IDX);
+		}
+
+		// Init RX Ring index pointer
+		pAd->RxRing.RxSwReadIdx = 0;
+		pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
+		//RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0);
+
+
+		// init MGMT ring index pointer
+		pAd->MgmtRing.TxSwFreeIdx = 0;
+		pAd->MgmtRing.TxCpuIdx = 0;
+
+		pAd->PrivateInfo.TxRingFullCnt = 0;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTxRxRingAndBacklogQueue\n"));
+	}
+
+	DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+	return Status;
+}
+
+
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		None
+
+	IRQL = PASSIVE_LEVEL
+	IRQL = DISPATCH_LEVEL
+
+	Note:
+		Reset NIC to initial state AS IS system boot up time.
+
+	========================================================================
+*/
+VOID	RTMPRingCleanUp(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			RingType)
+{
+	PTXD_STRUC		pTxD;
+	PRXD_STRUC		pRxD;
+	PQUEUE_ENTRY	pEntry;
+	PNDIS_PACKET	pPacket;
+	int				i;
+	PRTMP_TX_RING	pTxRing;
+	unsigned long	IrqFlags;
+	//UINT32			RxSwReadIdx;
+
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
+	switch (RingType)
+	{
+		case QID_AC_BK:
+		case QID_AC_BE:
+		case QID_AC_VI:
+		case QID_AC_VO:
+		/*case QID_HCCA:*/
+
+			pTxRing = &pAd->TxRing[RingType];
+
+			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+			// We have to clean all descriptors in case some error happened with reset
+			for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
+			{
+				pTxD  = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
+
+				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
+				// release scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+					pTxRing->Cell[i].pNdisPacket = NULL;
+				}
+
+				pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
+				// release scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+					pTxRing->Cell[i].pNextNdisPacket = NULL;
+				}
+			}
+
+			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
+			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
+			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
+			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
+
+			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+			RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+			while (pAd->TxSwQueue[RingType].Head != NULL)
+			{
+				pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
+				pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+				DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
+			}
+			RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+			break;
+
+		case QID_MGMT:
+			// We have to clean all descriptors in case some error happened with reset
+			NdisAcquireSpinLock(&pAd->MgmtRingLock);
+
+			for (i=0; i<MGMT_RING_SIZE; i++)
+			{
+				pTxD  = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
+
+				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
+				// rlease scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+				}
+				pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+
+				pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
+				// release scatter-and-gather NDIS_PACKET
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+			}
+				pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
+
+			}
+
+			RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
+			pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
+			pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
+			RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
+
+			NdisReleaseSpinLock(&pAd->MgmtRingLock);
+			pAd->RalinkCounters.MgmtRingFullCount = 0;
+			break;
+
+		case QID_RX:
+			// We have to clean all descriptors in case some error happened with reset
+			NdisAcquireSpinLock(&pAd->RxRingLock);
+
+			for (i=0; i<RX_RING_SIZE; i++)
+			{
+				pRxD  = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
+                pRxD->DDONE = 0 ;
+			}
+
+			RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
+			pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
+			pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
+			RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+
+			NdisReleaseSpinLock(&pAd->RxRingLock);
+			break;
+
+		default:
+			break;
+	}
+}
+
+
+VOID RTMPFreeTxRxRingMemory(
+    IN  PRTMP_ADAPTER   pAd)
+{
+	int index, num , j;
+	PRTMP_TX_RING pTxRing;
+	PTXD_STRUC	  pTxD;
+	PNDIS_PACKET  pPacket;
+	unsigned int  IrqFlags;
+
+	//POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
+
+	// Free TxSwQueue Packet
+	for (index=0; index <NUM_OF_TX_RING; index++)
+	{
+		PQUEUE_ENTRY pEntry;
+		PNDIS_PACKET pPacket;
+		PQUEUE_HEADER   pQueue;
+
+		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+		pQueue = &pAd->TxSwQueue[index];
+		while (pQueue->Head)
+		{
+			pEntry = RemoveHeadQueue(pQueue);
+			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+		}
+		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+	}
+
+	// Free Tx Ring Packet
+	for (index=0;index< NUM_OF_TX_RING;index++)
+	{
+		pTxRing = &pAd->TxRing[index];
+
+		for (j=0; j< TX_RING_SIZE; j++)
+		{
+			pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
+			pPacket = pTxRing->Cell[j].pNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNdisPacket as NULL after clear
+			pTxRing->Cell[j].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[j].pNextNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+			//Always assign pNextNdisPacket as NULL after clear
+			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
+
+		}
+	}
+
+	for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
+	{
+		if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
+		{
+			PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
+			RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
+		}
+	}
+	NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
+
+	if (pAd->RxDescRing.AllocVa)
+    {
+		RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
+    }
+    NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
+
+	if (pAd->MgmtDescRing.AllocVa)
+	{
+		RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
+	}
+	NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
+
+	for (num = 0; num < NUM_OF_TX_RING; num++)
+	{
+	if (pAd->TxBufSpace[num].AllocVa)
+		{
+			RTMP_FreeFirstTxBuffer(pAd, pAd->TxBufSpace[num].AllocSize, FALSE, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
+	    }
+	    NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
+
+	if (pAd->TxDescRing[num].AllocVa)
+		{
+			RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
+	    }
+	    NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
+	}
+
+	if (pAd->FragFrame.pFragPacket)
+		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
+}
+
+
+/***************************************************************************
+  *
+  *	register related procedures.
+  *
+  **************************************************************************/
+/*
+========================================================================
+Routine Description:
+    Disable DMA.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+	None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMADisable(
+	IN RTMP_ADAPTER			*pAd)
+{
+	WPDMA_GLO_CFG_STRUC     GloCfg;
+
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+	GloCfg.word &= 0xff0;
+	GloCfg.field.EnTXWriteBackDDONE =1;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+}
+
+
+/*
+========================================================================
+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;
+	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.WPDMABurstSIZE = 2;
+	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);
+
+}
+
+
+BOOLEAN AsicCheckCommanOk(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command)
+{
+	UINT32	CmdStatus = 0, CID = 0, i;
+	UINT32	ThisCIDMask = 0;
+
+	i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
+		// Find where the command is. Because this is randomly specified by firmware.
+		if ((CID & CID0MASK) == Command)
+		{
+			ThisCIDMask = CID0MASK;
+			break;
+		}
+		else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
+		{
+			ThisCIDMask = CID1MASK;
+			break;
+		}
+		else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
+		{
+			ThisCIDMask = CID2MASK;
+			break;
+		}
+		else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
+		{
+			ThisCIDMask = CID3MASK;
+			break;
+		}
+
+		RTMPusecDelay(100);
+		i++;
+	}while (i < 200);
+
+	// Get CommandStatus Value
+	RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
+
+	// This command's status is at the same position as command. So AND command position's bitmask to read status.
+	if (i < 200)
+	{
+		// If Status is 1, the comamnd is success.
+		if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
+			|| ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
+			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+			return TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
+	}
+	// Clear Command and Status.
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+
+	return FALSE;
+}
+
+
+/*
+========================================================================
+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)
+{
+	ULONG				CapInfoPos = 0;
+	UCHAR			*ptr, *ptr_update, *ptr_capinfo;
+	UINT			i;
+	BOOLEAN			bBcnReq = FALSE;
+	UCHAR			bcn_idx = 0;
+
+
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __FUNCTION__));
+		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);
+	}
+	else
+	{
+		ptr = (PUCHAR)&pAd->BeaconTxWI;
+#ifdef RT_BIG_ENDIAN
+		RTMPWIEndianChange(ptr, TYPE_TXWI);
+#endif
+		for (i=0; i<TXWI_SIZE; i+=4)  // 16-byte TXWI field
+		{
+			UINT32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
+			ptr += 4;
+		}
+
+		// Update CapabilityInfo in Beacon
+		for (i = CapInfoPos; i < (CapInfoPos+2); i++)
+		{
+			RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
+			ptr_capinfo ++;
+		}
+
+		if (FrameLen > UpdatePos)
+		{
+			for (i= UpdatePos; i< (FrameLen); i++)
+			{
+				RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
+				ptr_update ++;
+			}
+		}
+
+	}
+
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RT28xxPciStaAsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN       bFromTx)
+{
+    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"));
+        return;
+    }
+
+    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_PCIE_DEVICE)
+		&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+    {
+        // Support PCIe Advance Power Save
+	if (bFromTx == TRUE
+			&&(pAd->Mlme.bPsPollTimerRunning == TRUE))
+	{
+            pAd->Mlme.bPsPollTimerRunning = FALSE;
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+		RTMPusecDelay(3000);
+            DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
+	}
+
+		AutoWakeupCfg.word = 0;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+        if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
+        {
+#ifdef PCIE_PS_SUPPORT
+			// add by johnli, RF power sequence setup, load RF normal operation-mode setup
+			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd))
+			{
+				RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
+				if (pChipOps->AsicReverseRfFromSleepMode)
+					pChipOps->AsicReverseRfFromSleepMode(pAd);
+			}
+			else
+#endif // PCIE_PS_SUPPORT //
+			{
+			// end johnli
+				// 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);
+				}
+			}
+        }
+#ifdef PCIE_PS_SUPPORT
+		// 3090 MCU Wakeup command needs more time to be stable.
+		// Before stable, don't issue other MCU command to prevent from firmware error.
+		if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+			&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+			{
+			DBGPRINT(RT_DEBUG_TRACE, ("<==RT28xxPciStaAsicForceWakeup::Release the MCU Lock(3090)\n"));
+			RTMP_SEM_LOCK(&pAd->McuCmdLock);
+			pAd->brt30xxBanMcuCmd = FALSE;
+			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+			}
+#endif // PCIE_PS_SUPPORT //
+    }
+    else
+    {
+        // PCI, 2860-PCIe
+         DBGPRINT(RT_DEBUG_TRACE, ("<==RT28xxPciStaAsicForceWakeup::Original PCI Power Saving\n"));
+        AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+        AutoWakeupCfg.word = 0;
+	    RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+    }
+
+    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+    OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+    DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
+}
+
+
+VOID RT28xxPciStaAsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp)
+{
+	BOOLEAN brc;
+
+	if (pAd->StaCfg.bRadio == FALSE)
+	{
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+		return;
+	}
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+		&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+	{
+		ULONG	Now = 0;
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+			return;
+		}
+
+		NdisGetSystemUpTime(&Now);
+		// If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM.
+		// Because Some AP can't queuing outgoing frames immediately.
+		if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu :  RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
+			return;
+		}
+		else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime,  pAd->RalinkCounters.RxCountSinceLastNULL));
+			return;
+		}
+
+		brc = RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp);
+		if (brc==TRUE)
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+	}
+	else
+	{
+		AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+		// we have decided to SLEEP, so at least do it for a BEACON period.
+		if (TbttNumToNextWakeUp == 0)
+			TbttNumToNextWakeUp = 1;
+
+		//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+
+		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, 0x00);   // send POWER-SAVE command to MCU. Timeout 40us.
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+		DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __FUNCTION__, TbttNumToNextWakeUp));
+	}
+
+}
+
+
+VOID PsPollWakeExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	unsigned long flags;
+
+    DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n"));
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+    if (pAd->Mlme.bPsPollTimerRunning)
+    {
+	    RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+    }
+    pAd->Mlme.bPsPollTimerRunning = FALSE;
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+#ifdef PCIE_PS_SUPPORT
+	// For rt30xx power solution 3, Use software timer to wake up in psm. So call
+	// AsicForceWakeup here instead of handling twakeup interrupt.
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd))
+	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("<--PsPollWakeExec::3090 calls AsicForceWakeup(pAd, DOT11POWERSAVE) in advance \n"));
+		AsicForceWakeup(pAd, DOT11POWERSAVE);
+	}
+
+#endif // PCIE_PS_SUPPORT //
+}
+
+VOID  RadioOnExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3)
+{
+	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+	RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+	WPDMA_GLO_CFG_STRUC	DmaCfg;
+	BOOLEAN				Cancelled;
+
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
+//KH Debug: Add the compile flag "RT2860 and condition
+#ifdef RTMP_PCI_SUPPORT
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+			&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+#endif // RTMP_PCI_SUPPORT //
+		return;
+	}
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
+
+
+#ifdef RTMP_PCI_SUPPORT
+if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+	&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+#endif // RTMP_PCI_SUPPORT //
+		return;
+	}
+//KH Debug: need to check. I add the compile flag "CONFIG_STA_SUPPORT" to enclose the following codes.
+#ifdef RTMP_PCI_SUPPORT
+if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+	&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+	{
+	pAd->Mlme.bPsPollTimerRunning = FALSE;
+	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+	}
+#endif // RTMP_PCI_SUPPORT //
+	if (pAd->StaCfg.bRadio == TRUE)
+	{
+		pAd->bPCIclkOff = FALSE;
+		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);
+
+		// 2. Send wake up command.
+		AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
+		// 2-1. wait command ok.
+		AsicCheckCommanOk(pAd, PowerWakeCID);
+
+		// When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt.
+		//RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
+		RTMP_ASIC_INTERRUPT_ENABLE(pAd);
+
+		// 3. Enable Tx DMA.
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
+		DmaCfg.field.EnableTxDMA = 1;
+		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+
+		// 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);
+		}
+//KH Debug:The following codes should be enclosed by RT3090 compile flag
+		if (pChipOps->AsicReverseRfFromSleepMode)
+			pChipOps->AsicReverseRfFromSleepMode(pAd);
+#ifdef PCIE_PS_SUPPORT
+#ifdef CONFIG_STA_SUPPORT
+// 3090 MCU Wakeup command needs more time to be stable.
+// Before stable, don't issue other MCU command to prevent from firmware error.
+if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
+	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+	{
+	RTMP_SEM_LOCK(&pAd->McuCmdLock);
+	pAd->brt30xxBanMcuCmd = FALSE;
+	RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+	}
+#endif // CONFIG_STA_SUPPORT //
+#endif // PCIE_PS_SUPPORT //
+		// Clear Radio off flag
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+		// Set LED
+		RTMPSetLED(pAd, LED_RADIO_ON);
+
+        if (pAd->StaCfg.Psm == PWR_ACTIVE)
+        {
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+        }
+	}
+	else
+	{
+		RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
+	}
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+/*
+	==========================================================================
+	Description:
+		This routine sends command to firmware and turn our chip to wake up mode from power save mode.
+		Both RadioOn and .11 power save function needs to call this routine.
+	Input:
+		Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On.  Need to restore PCI host value.
+		Level = other value : normal wake up function.
+
+	==========================================================================
+ */
+BOOLEAN RT28xxPciAsicRadioOn(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR     Level)
+{
+    //WPDMA_GLO_CFG_STRUC	DmaCfg;
+#ifdef CONFIG_STA_SUPPORT
+	BOOLEAN				Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+    //UINT32			    MACValue;
+
+	if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
+		return FALSE;
+
+#ifdef CONFIG_STA_SUPPORT
+	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+	{
+		if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+		{
+	    pAd->Mlme.bPsPollTimerRunning = FALSE;
+		RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+		}
+		if ((pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)&&
+		((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
+		||(RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)))
+		{
+			// Some chips don't need to delay 6ms, so copy RTMPPCIePowerLinkCtrlRestore
+			// return condition here.
+			/*
+			if (((pAd->MACVersion&0xffff0000) != 0x28600000)
+				&& ((pAd->DeviceID == NIC2860_PCIe_DEVICE_ID)
+				||(pAd->DeviceID == NIC2790_PCIe_DEVICE_ID)))
+			*/
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
+			// 1. Set PCI Link Control in Configuration Space.
+			RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+			RTMPusecDelay(6000);
+		}
+	}
+	}
+
+#ifdef PCIE_PS_SUPPORT
+if (!(((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
+	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))))
+#endif // PCIE_PS_SUPPORT //
+	{
+    pAd->bPCIclkOff = FALSE;
+		DBGPRINT(RT_DEBUG_TRACE, ("PSM :309xbPCIclkOff == %d\n", pAd->bPCIclkOff));
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+	// 2. Send wake up command.
+	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
+	pAd->bPCIclkOff = FALSE;
+	// 2-1. wait command ok.
+	AsicCheckCommanOk(pAd, PowerWakeCID);
+	RTMP_ASIC_INTERRUPT_ENABLE(pAd);
+
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+	if (Level == GUI_IDLE_POWER_SAVE)
+	{
+#ifdef  PCIE_PS_SUPPORT
+
+			// add by johnli, RF power sequence setup, load RF normal operation-mode setup
+			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
+			{
+				RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
+				if (pChipOps->AsicReverseRfFromSleepMode)
+					pChipOps->AsicReverseRfFromSleepMode(pAd);
+#ifdef CONFIG_STA_SUPPORT
+				// 3090 MCU Wakeup command needs more time to be stable.
+				// Before stable, don't issue other MCU command to prevent from firmware error.
+				if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
+					&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+					&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+					{
+						RTMP_SEM_LOCK(&pAd->McuCmdLock);
+						pAd->brt30xxBanMcuCmd = FALSE;
+						RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+					}
+#endif // CONFIG_STA_SUPPORT //
+			}
+			else
+			// end johnli
+#endif // PCIE_PS_SUPPORT //
+			{
+			// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+				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);
+				}
+				}
+#endif // CONFIG_STA_SUPPORT //
+			}
+	}
+        return TRUE;
+
+}
+
+
+/*
+	==========================================================================
+	Description:
+		This routine sends command to firmware and turn our chip to power save mode.
+		Both RadioOff and .11 power save function needs to call this routine.
+	Input:
+		Level = GUIRADIO_OFF  : GUI Radio Off mode
+		Level = DOT11POWERSAVE  : 802.11 power save mode
+		Level = RTMP_HALT  : When Disable device.
+
+	==========================================================================
+ */
+BOOLEAN RT28xxPciAsicRadioOff(
+	IN PRTMP_ADAPTER    pAd,
+	IN UCHAR            Level,
+	IN USHORT           TbttNumToNextWakeUp)
+{
+#ifdef CONFIG_STA_SUPPORT
+	WPDMA_GLO_CFG_STRUC	DmaCfg;
+	UCHAR		i, tempBBP_R3 = 0;
+#endif // CONFIG_STA_SUPPORT //
+	BOOLEAN		brc = FALSE, Cancelled;
+    UINT32		TbTTTime = 0;
+	UINT32		PsPollTime = 0/*, MACValue*/;
+    ULONG		BeaconPeriodTime;
+    UINT32		RxDmaIdx, RxCpuIdx;
+	DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", Level,pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
+
+	if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE)
+		return FALSE;
+
+    // Check Rx DMA busy status, if more than half is occupied, give up this radio off.
+	RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx);
+	RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx);
+	if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d ,  RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx));
+		return FALSE;
+	}
+	else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3))
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2.  RxCpuIdx = %d. RxDmaIdx = %d ,  \n", RxCpuIdx, RxDmaIdx));
+		return FALSE;
+	}
+
+    // 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_PCIE_DEVICE)
+		&& pAd->OpMode == OPMODE_STA
+#ifdef CONFIG_STA_SUPPORT
+		&&pAd->StaCfg.PSControl.field.EnableNewPS == TRUE
+#endif // CONFIG_STA_SUPPORT //
+		)
+	{
+
+	    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
+	    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+
+	    if (Level == DOT11POWERSAVE)
+		{
+			RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
+			TbTTTime &= 0x1ffff;
+			// 00. check if need to do sleep in this DTIM period.   If next beacon will arrive within 30ms , ...doesn't necessarily sleep.
+			// TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms
+	        if  (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0))
+			{
+				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 FALSE;
+			}
+			else
+			{
+				PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000;
+#ifdef PCIE_PS_SUPPORT
+#ifdef CONFIG_STA_SUPPORT
+				if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
+				&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+				&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+				{
+							PsPollTime -= 5;
+				}
+				else
+#endif // CONFIG_STA_SUPPORT //
+#endif // PCIE_PS_SUPPORT //
+				PsPollTime -= 3;
+
+	            BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100;
+				if (TbttNumToNextWakeUp > 0)
+					PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime);
+
+	            pAd->Mlme.bPsPollTimerRunning = TRUE;
+				RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime);
+			}
+		}
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOff::Level!=DOT11POWERSAVE \n"));
+	}
+
+	pAd->bPCIclkOffDisableTx = FALSE;
+    RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+    // Set to 1R.
+	if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA)
+	{
+    tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+	if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+		&& (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+	{
+		// Must using 40MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+	}
+	else
+	{
+		// Must using 20MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+	}
+
+	if (Level != RTMP_HALT)
+	{
+		// Change Interrupt bitmask.
+    // When PCI clock is off, don't want to service interrupt.
+	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+	}
+	else
+	{
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+	}
+
+
+	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+	//  2. Send Sleep command
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
+	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
+	// 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);
+
+	//  3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe.
+	// If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem.
+	if ((Level == DOT11POWERSAVE) && (brc == TRUE))
+	{
+		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
+		//  3-1. Wait command success
+		AsicCheckCommanOk(pAd, PowerRadioOffCID);
+	}
+	else if (brc == TRUE)
+	{
+		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00);	// lowbyte = 0 means to do power safe, NOT turn off radio.
+		//  3-1. Wait command success
+		AsicCheckCommanOk(pAd, PowerRadioOffCID);
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	// 1. Wait DMA not busy
+	i = 0;
+	do
+	{
+		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
+		if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
+			break;
+		RTMPusecDelay(20);
+		i++;
+	}while(i < 50);
+
+	/*
+	if (i >= 50)
+	{
+		pAd->CheckDmaBusyCount++;
+		DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount));
+	}
+	else
+	{
+		pAd->CheckDmaBusyCount = 0;
+	}
+	*/
+#endif // CONFIG_STA_SUPPORT //
+//KH Debug:My original codes have the follwoing codes, but currecnt codes do not have it.
+// Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment.
+RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280);
+//OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ);
+
+#ifdef PCIE_PS_SUPPORT
+#ifdef CONFIG_STA_SUPPORT
+if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
+	&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+	&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+	{
+	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOff::3090 return to skip the following TbttNumToNextWakeUp setting for 279x\n"));
+	pAd->bPCIclkOff = TRUE;
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
+	// For this case, doesn't need to below actions, so return here.
+	return brc;
+	}
+#endif // CONFIG_STA_SUPPORT //
+#endif // PCIE_PS_SUPPORT //
+	if (Level == DOT11POWERSAVE)
+	{
+		AUTO_WAKEUP_STRUC	AutoWakeupCfg;
+		//RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90);
+
+		// 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);
+
+		// 1. Set auto wake up timer.
+		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+		AutoWakeupCfg.field.EnableAutoWakeup = 1;
+		AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
+		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+	}
+
+#ifdef CONFIG_STA_SUPPORT
+	//  4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value.
+	if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA)
+	{
+		if ((brc == TRUE) && (i < 50))
+			RTMPPCIeLinkCtrlSetting(pAd, 1);
+	}
+	//  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function
+	else if (pAd->OpMode == OPMODE_STA)
+	{
+		if ((brc == TRUE) && (i < 50))
+			RTMPPCIeLinkCtrlSetting(pAd, 3);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	//pAd->bPCIclkOffDisableTx = FALSE;
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
+	return TRUE;
+}
+
+
+
+
+VOID RT28xxPciMlmeRadioOn(
+	IN PRTMP_ADAPTER pAd)
+{
+    if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+		return;
+
+    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
+
+    if ((pAd->OpMode == OPMODE_AP) ||
+        ((pAd->OpMode == OPMODE_STA)
+        && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+#ifdef CONFIG_STA_SUPPORT
+        ||pAd->StaCfg.PSControl.field.EnableNewPS == FALSE
+#endif // CONFIG_STA_SUPPORT //
+        )))
+    {
+	RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+	//NICResetFromError(pAd);
+
+	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);
+
+	// Enable Tx/Rx
+	RTMPEnableRxTx(pAd);
+
+	// Clear Radio off flag
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+	    // Set LED
+	    RTMPSetLED(pAd, LED_RADIO_ON);
+    }
+
+#ifdef CONFIG_STA_SUPPORT
+    if ((pAd->OpMode == OPMODE_STA) &&
+        (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+        &&(pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+    {
+        BOOLEAN		Cancelled;
+
+	RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
+
+        pAd->Mlme.bPsPollTimerRunning = FALSE;
+	RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+	RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
+	RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 40);
+    }
+#endif // CONFIG_STA_SUPPORT //
+}
+
+
+VOID RT28xxPciMlmeRadioOFF(
+	IN PRTMP_ADAPTER pAd)
+{
+	BOOLEAN brc=TRUE;
+
+    if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+	return;
+
+#ifdef CONFIG_STA_SUPPORT
+	// Link down first if any association exists
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+		{
+			MLME_DISASSOC_REQ_STRUCT DisReq;
+			MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+			if (pMsgElem)
+			{
+				COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid);
+				DisReq.Reason =  REASON_DISASSOC_STA_LEAVING;
+
+				pMsgElem->Machine = ASSOC_STATE_MACHINE;
+				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+				pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+				NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+				MlmeDisassocReqAction(pAd, pMsgElem);
+				kfree(pMsgElem);
+
+				RTMPusecDelay(1000);
+			}
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+    DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
+
+	// 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 (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+		{
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+	{
+			RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+	}
+			// If during power safe mode.
+			if (pAd->StaCfg.bRadio == TRUE)
+			{
+				DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
+				return;
+			}
+			// Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF).
+			if (IDLE_ON(pAd) &&
+				(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+			{
+				RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+			}
+		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+        {
+            BOOLEAN Cancelled;
+            pAd->Mlme.bPsPollTimerRunning = FALSE;
+            RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+	        RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,	&Cancelled);
+        }
+		}
+
+        // 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);
+
+        /*
+        if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+        {
+            RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+            return;
+        }
+        */
+    }
+#endif // CONFIG_STA_SUPPORT //
+	// Set LED.Move to here for fixing LED bug. This flag must be called after LinkDown
+	RTMPSetLED(pAd, LED_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+//KH Debug:All PCIe devices need to use timer to execute radio off function, or the PCIe&&EnableNewPS needs.
+//KH Ans:It is right, because only when the PCIe and EnableNewPs is true, we need to delay the RadioOffTimer
+//to avoid the deadlock with PCIe Power saving function.
+if (pAd->OpMode == OPMODE_STA&&
+	OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)&&
+	pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+	{
+	RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
+	}
+else
+#endif // CONFIG_STA_SUPPORT //
+{
+
+
+	brc=RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
+
+	if (brc==FALSE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __FUNCTION__));
+	}
+}
+/*
+	// Disable Tx/Rx DMA
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	   // disable DMA
+	GloCfg.field.EnableTxDMA = 0;
+	GloCfg.field.EnableRxDMA = 0;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);	   // abort all TX rings
+
+
+	// 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);
+
+	if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+	{
+		// Must using 40MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+	}
+	else
+	{
+		// Must using 20MHz.
+		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+	}
+
+	// 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);
+*/
+}
+
+#endif // RTMP_MAC_PCI //
diff --git a/drivers/staging/rt3090/common/cmm_profile.c b/drivers/staging/rt3090/common/cmm_profile.c
new file mode 100644
index 0000000..5803f42
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_profile.c
@@ -0,0 +1,2321 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_profile.c
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#include "../rt_config.h"
+
+
+#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(PSTRING s1, PSTRING s2)
+{
+	int i = 0;
+	PSTRING 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, (PUCHAR)&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(PSTRING s1, PSTRING s2)
+{
+	PSTRING 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.
+PSTRING rtstrstruncasecmp(PSTRING s1, PSTRING 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
+  */
+PSTRING rtstrstr(PSTRING s1,const PSTRING s2)
+{
+	INT l1, l2;
+
+	l2 = strlen(s2);
+	if (!l2)
+		return s1;
+
+	l1 = strlen(s1);
+
+	while (l1 >= l2)
+	{
+		l1--;
+		if (!memcmp(s1,s2,l2))
+			return 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.
+ */
+PSTRING __rstrtok;
+PSTRING rstrtok(PSTRING s,const PSTRING ct)
+{
+	PSTRING 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(PSTRING s,PSTRING ct)
+{
+	INT count = 0;
+	/* point to the beginning of the line */
+	PSTRING 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(PSTRING cp, unsigned int *addr)
+{
+	unsigned int	val;
+	int		base, n;
+	STRING		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
+    ========================================================================
+*/
+PSTRING RTMPFindSection(
+    IN  PSTRING   buffer)
+{
+    STRING temp_buf[32];
+    PSTRING  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
+	bTrimSpace	Set true if you want to strip the space character of the result pattern
+
+    Return Value:
+        TRUE                        Success
+        FALSE                       Fail
+
+    Note:
+	This routine get the value with the matched key (case case-sensitive)
+	For SSID and security key related parameters, we SHALL NOT trim the space(' ') character.
+    ========================================================================
+*/
+INT RTMPGetKeyParameter(
+    IN PSTRING key,
+    OUT PSTRING dest,
+    IN INT destsize,
+    IN PSTRING buffer,
+    IN BOOLEAN bTrimSpace)
+{
+	PSTRING pMemBuf, temp_buf1 = NULL, temp_buf2 = NULL;
+	PSTRING start_ptr, end_ptr;
+	PSTRING ptr;
+	PSTRING offset = NULL;
+	INT  len, keyLen;
+
+
+	keyLen = strlen(key);
+	os_alloc_mem(NULL, (PUCHAR *)&pMemBuf, MAX_PARAM_BUFFER_SIZE  * 2);
+	if (pMemBuf == NULL)
+		return (FALSE);
+
+	memset(pMemBuf, 0, MAX_PARAM_BUFFER_SIZE * 2);
+	temp_buf1 = pMemBuf;
+	temp_buf2 = (PSTRING)(pMemBuf + MAX_PARAM_BUFFER_SIZE);
+
+
+	//find section
+	if((offset = RTMPFindSection(buffer)) == NULL)
+	{
+		os_free_mem(NULL, (PUCHAR)pMemBuf);
+		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, (PUCHAR)pMemBuf);
+		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, (PUCHAR)pMemBuf);
+		return (FALSE);
+	}
+
+	NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+	temp_buf2[end_ptr-start_ptr]='\0';
+	if((start_ptr=rtstrstr(temp_buf2, "=")) == NULL)
+	{
+		os_free_mem(NULL, (PUCHAR)pMemBuf);
+		return (FALSE);
+	}
+	ptr = (start_ptr +1);
+	//trim special characters, i.e.,  TAB or space
+	while(*start_ptr != 0x00)
+	{
+		if( ((*ptr == ' ') && bTrimSpace) || (*ptr == '\t') )
+			ptr++;
+		else
+			break;
+	}
+	len = strlen(start_ptr);
+
+	memset(dest, 0x00, destsize);
+	strncpy(dest, ptr, ((len >= destsize) ? destsize: len));
+
+	os_free_mem(NULL, (PUCHAR)pMemBuf);
+
+	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  PSTRING   key,
+    OUT PSTRING   dest,
+    OUT	USHORT	*end_offset,
+    IN  INT     destsize,
+    IN  PSTRING   buffer,
+    IN	BOOLEAN	bTrimSpace)
+{
+    PSTRING temp_buf1 = NULL;
+    PSTRING temp_buf2 = NULL;
+    PSTRING start_ptr;
+    PSTRING end_ptr;
+    PSTRING ptr;
+    PSTRING offset = 0;
+    INT  len;
+
+	if (*end_offset >= MAX_INI_BUFFER_SIZE)
+		return (FALSE);
+
+	os_alloc_mem(NULL, (PUCHAR *)&temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+	if(temp_buf1 == NULL)
+        return (FALSE);
+
+	os_alloc_mem(NULL, (PUCHAR *)&temp_buf2, MAX_PARAM_BUFFER_SIZE);
+	if(temp_buf2 == NULL)
+	{
+		os_free_mem(NULL, (PUCHAR)temp_buf1);
+        return (FALSE);
+	}
+
+    //find section
+	if(*end_offset == 0)
+    {
+		if ((offset = RTMPFindSection(buffer)) == NULL)
+		{
+			os_free_mem(NULL, (PUCHAR)temp_buf1);
+		os_free_mem(NULL, (PUCHAR)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, (PUCHAR)temp_buf1);
+	os_free_mem(NULL, (PUCHAR)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, (PUCHAR)temp_buf1);
+	os_free_mem(NULL, (PUCHAR)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, (PUCHAR)temp_buf1);
+	os_free_mem(NULL, (PUCHAR)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, (PUCHAR)temp_buf1);
+    os_free_mem(NULL, (PUCHAR)temp_buf2);
+    return TRUE;
+}
+
+
+static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  PSTRING buffer,IN  ULONG KeyType,IN  INT BSSIdx,IN  INT KeyIdx)
+{
+	PSTRING		keybuff;
+	//INT			i = BSSIdx, idx = KeyIdx, retVal;
+	ULONG		KeyLen;
+	//UCHAR		CipherAlg = CIPHER_WEP64;
+	CIPHER_KEY	*pSharedKey;
+
+	keybuff = buffer;
+	KeyLen = strlen(keybuff);
+	pSharedKey = &pAd->SharedKey[BSSIdx][KeyIdx];
+
+	if(((KeyType != 0) && (KeyType != 1)) ||
+	    ((KeyType == 0) && (KeyLen != 10) && (KeyLen != 26)) ||
+	    ((KeyType== 1) && (KeyLen != 5) && (KeyLen != 13)))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length(%ld) or Type(%ld)\n",
+								KeyIdx+1, KeyLen, KeyType));
+		return FALSE;
+	}
+	else
+	{
+		return RT_CfgSetWepKey(pAd, buffer, pSharedKey, KeyIdx);
+	}
+
+}
+
+
+static void rtmp_read_key_parms_from_file(IN  PRTMP_ADAPTER pAd, PSTRING tmpbuf, PSTRING buffer)
+{
+	STRING		tok_str[16];
+	PSTRING		macptr;
+	INT			i = 0, idx;
+	ULONG		KeyType[MAX_MBSSID_NUM];
+	ULONG		KeyIdx;
+
+	NdisZeroMemory(KeyType, sizeof(KeyType));
+
+	//DefaultKeyID
+	if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer, TRUE))
+	{
+
+#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, TRUE))
+		{
+		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+		    {
+				/*
+					do sanity check for KeyType length;
+					or in station mode, the KeyType length > 1,
+					the code will overwrite the stack of caller
+					(RTMPSetProfileParameters) and cause srcbuf = NULL
+				*/
+				if (i < MAX_MBSSID_NUM)
+					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 (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE))
+				{
+					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)
+{
+	PSTRING					macptr;
+	INT						i=0;
+	BOOLEAN					bWmmEnable = FALSE;
+
+	//WmmCapable
+	if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+		{
+			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));
+		}
+
+		//MaxSPLength
+		if(RTMPGetKeyParameter("MaxSPLength", tmpbuf, 10, buffer, TRUE))
+		{
+			pAd->CommonCfg.MaxSPLength = simple_strtol(tmpbuf, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("MaxSPLength=%d\n", pAd->CommonCfg.MaxSPLength));
+		}
+
+		//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
+		if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer, TRUE))
+		{
+			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];
+
+			pAd->CommonCfg.bACMAPSDTr[0] = apsd_ac[0];
+			pAd->CommonCfg.bACMAPSDTr[1] = apsd_ac[1];
+			pAd->CommonCfg.bACMAPSDTr[2] = apsd_ac[2];
+			pAd->CommonCfg.bACMAPSDTr[3] = apsd_ac[3];
+		}
+	}
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+static void HTParametersHook(
+	IN	PRTMP_ADAPTER pAd,
+	IN	PSTRING		  pValueStr,
+	IN	PSTRING		  pInput)
+{
+
+	long Value;
+
+    if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput, TRUE))
+    {
+        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, TRUE))
+    {
+        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, TRUE))
+    {
+        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", (INT) Value));
+    }
+
+    if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput, TRUE))
+    {
+        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, TRUE))
+    {
+        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, TRUE))
+    {
+        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;
+        DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
+    }
+
+	// Tx_+HTC frame
+    if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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", (INT) 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, TRUE))
+	{
+		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", (INT) 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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+
+#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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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, TRUE))
+	{
+		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));
+	}
+	//2008/11/05: KH add to support Antenna power-saving of AP<--
+	//Green AP
+	if(RTMPGetKeyParameter("GreenAP", pValueStr, 10, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+		if (Value == 0)
+		{
+			pAd->CommonCfg.bGreenAPEnable = FALSE;
+		}
+		else
+		{
+			pAd->CommonCfg.bGreenAPEnable = TRUE;
+		}
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Green AP= %d\n", pAd->CommonCfg.bGreenAPEnable));
+	}
+
+	// HT_DisallowTKIP
+	if (RTMPGetKeyParameter("HT_DisallowTKIP", pValueStr, 25, pInput, TRUE))
+	{
+		Value = simple_strtol(pValueStr, 0, 10);
+
+		if (Value == 1)
+		{
+			pAd->CommonCfg.HT_DisallowTKIP = TRUE;
+		}
+		else
+		{
+			pAd->CommonCfg.HT_DisallowTKIP = FALSE;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("HT: Disallow TKIP mode = %s\n", (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "ON" : "OFF" ));
+	}
+
+
+	//2008/11/05:KH add to support Antenna power-saving of AP-->
+}
+#endif // DOT11_N_SUPPORT //
+
+
+NDIS_STATUS	RTMPSetProfileParameters(
+	IN RTMP_ADAPTER *pAd,
+	IN PSTRING	pBuffer)
+{
+	PSTRING					tmpbuf;
+	ULONG					RtsThresh;
+	ULONG					FragThresh;
+	PSTRING					macptr;
+	INT						i = 0, retval;
+	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if(tmpbuf == NULL)
+		return NDIS_STATUS_FAILURE;
+
+	do
+	{
+		// set file parameter to portcfg
+		//CountryRegion
+		if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, pBuffer, TRUE))
+		{
+			retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_24G);
+			DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
+		}
+		//CountryRegionABand
+		if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, pBuffer, TRUE))
+		{
+			retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_5G);
+			DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
+		}
+#ifdef RTMP_EFUSE_SUPPORT
+#ifdef RT30xx
+		//EfuseBufferMode
+		if(RTMPGetKeyParameter("EfuseBufferMode", tmpbuf, 25, pBuffer, TRUE))
+		{
+			pAd->bEEPROMFile = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+			DBGPRINT(RT_DEBUG_TRACE, ("EfuseBufferMode=%d\n", pAd->bUseEfuse));
+		}
+#endif // RT30xx //
+#endif // RTMP_EFUSE_SUPPORT //
+		//CountryCode
+		if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, pBuffer, TRUE))
+		{
+			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((PSTRING) pAd->CommonCfg.CountryCode) != 0)
+			{
+				pAd->CommonCfg.bCountryFlag = TRUE;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
+		}
+		//ChannelGeography
+		if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, pBuffer, TRUE))
+		{
+			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 (RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE))
+			{
+				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, pBuffer, TRUE))
+			{
+				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));
+			}
+		}
+#ifdef RTMP_MAC_PCI
+		//NewPCIePS
+		if(RTMPGetKeyParameter("NewPCIePS", tmpbuf, 10, pBuffer, TRUE))
+		{
+			UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+			if(temp_buffer>0)
+				pAd->StaCfg.PSControl.field.EnableNewPS=TRUE;
+				else
+					pAd->StaCfg.PSControl.field.EnableNewPS=FALSE;
+			DBGPRINT(RT_DEBUG_TRACE, ("NewPCIePS=%d\n", pAd->StaCfg.PSControl.field.EnableNewPS));
+		}
+#endif // RTMP_MAC_PCI //
+#ifdef RT3090
+		//PCIePowerLevel
+
+		if(RTMPGetKeyParameter("PCIePowerLevel", tmpbuf, 10, pBuffer, TRUE))
+		{
+			pAd->StaCfg.PSControl.field.rt30xxPowerMode = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+			DBGPRINT(RT_DEBUG_TRACE, ("PCIePowerLevel=%d\n", pAd->StaCfg.PSControl.field.rt30xxPowerMode));
+		}
+		//FollowHostASPM
+		if(RTMPGetKeyParameter("FollowHostASPM", tmpbuf, 10, pBuffer, TRUE))
+		{
+			UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+
+			if(temp_buffer>0)
+				pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=TRUE;
+				else
+					pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=FALSE;
+			DBGPRINT(RT_DEBUG_TRACE, ("rt30xxFollowHostASPM=%d\n", pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM));
+		}
+		//ForceTestASPM
+		if(RTMPGetKeyParameter("ForceTestASPM", tmpbuf, 10, pBuffer, TRUE))
+		{
+			UCHAR temp_buffer = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+
+			if(temp_buffer>0)
+				pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=TRUE;
+				else
+					pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=FALSE;
+			DBGPRINT(RT_DEBUG_TRACE, ("rt30xxForceASPM=%d\n", pAd->StaCfg.PSControl.field.rt30xxForceASPMTest));
+		}
+#endif // RT3090 //
+#endif // CONFIG_STA_SUPPORT //
+		//Channel
+		if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+			RT_CfgSetWirelessMode(pAd, tmpbuf);
+			DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
+		}
+	    //BasicRate
+		if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+	//#if 0	//#ifndef WIFI_TEST
+	//		pAd->CommonCfg.UseBGProtection = 2;// disable b/g protection for throughput test
+	//#else
+			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;
+			}
+	//#endif
+			DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
+		}
+		//OLBCDetection
+		if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+			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, pBuffer, TRUE))
+		{
+	//#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, pBuffer, TRUE))
+		{
+			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, pBuffer);
+#endif // CONFIG_STA_SUPPORT //
+
+		//ShortSlot
+		if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE))
+		{
+			RT_CfgSetShortSlot(pAd, tmpbuf);
+			DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
+		}
+		//IEEE80211H
+		if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, pBuffer, TRUE))
+		{
+		    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, pBuffer, TRUE))
+		{
+		    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));
+		}
+
+#ifdef MERGE_ARCH_TEAM
+		// DfsLowerLimit
+		if(RTMPGetKeyParameter("DfsLowerLimit", tmpbuf, 10, pBuffer, TRUE))
+		{
+			if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.RadarDetect.DfsLowerLimit = simple_strtol(tmpbuf, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("DfsLowerLimit=%ld\n", pAd->CommonCfg.RadarDetect.DfsLowerLimit));
+		}
+
+		// DfsUpperLimit
+		if(RTMPGetKeyParameter("DfsUpperLimit", tmpbuf, 10, pBuffer, TRUE))
+		{
+			if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.RadarDetect.DfsUpperLimit = simple_strtol(tmpbuf, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("DfsUpperLimit=%ld\n", pAd->CommonCfg.RadarDetect.DfsUpperLimit));
+		}
+
+		// FixDfsLimit
+		if(RTMPGetKeyParameter("FixDfsLimit", tmpbuf, 10, pBuffer, TRUE))
+		{
+		    if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.RadarDetect.FixDfsLimit = TRUE;
+			else
+				pAd->CommonCfg.RadarDetect.FixDfsLimit = FALSE;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("FixDfsLimit=%d\n", pAd->CommonCfg.RadarDetect.FixDfsLimit));
+		}
+
+		// LongPulseRadarTh
+		if(RTMPGetKeyParameter("LongPulseRadarTh", tmpbuf, 10, pBuffer, TRUE))
+		{
+		    if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.RadarDetect.LongPulseRadarTh = simple_strtol(tmpbuf, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("LongPulseRadarTh=%d\n", pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
+		}
+
+		// AvgRssiReq
+		if(RTMPGetKeyParameter("AvgRssiReq", tmpbuf, 10, pBuffer, TRUE))
+		{
+			if(simple_strtol(tmpbuf, 0, 10) != 0)
+				pAd->CommonCfg.RadarDetect.AvgRssiReq = simple_strtol(tmpbuf, 0, 10);
+
+			DBGPRINT(RT_DEBUG_TRACE, ("AvgRssiReq=%d\n", pAd->CommonCfg.RadarDetect.AvgRssiReq));
+		}
+
+#endif // MERGE_ARCH_TEAM //
+
+		//RDRegion
+		if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE))
+		{
+						RADAR_DETECT_STRUCT	*pRadarDetect = &pAd->CommonCfg.RadarDetect;
+			if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
+			{
+							pRadarDetect->RDDurRegion = JAP_W53;
+							pRadarDetect->DfsSessionTime = 15;
+			}
+			else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
+			{
+							pRadarDetect->RDDurRegion = JAP_W56;
+							pRadarDetect->DfsSessionTime = 13;
+			}
+			else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
+			{
+							pRadarDetect->RDDurRegion = JAP;
+							pRadarDetect->DfsSessionTime = 5;
+			}
+			else  if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
+			{
+							pRadarDetect->RDDurRegion = FCC;
+							pRadarDetect->DfsSessionTime = 5;
+#ifdef DFS_FCC_BW40_FIX
+							pRadarDetect->DfsSessionFccOff = 0;
+#endif // DFS_FCC_BW40_FIX //
+			}
+			else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
+			{
+							pRadarDetect->RDDurRegion = CE;
+							pRadarDetect->DfsSessionTime = 13;
+			}
+			else
+			{
+							pRadarDetect->RDDurRegion = CE;
+							pRadarDetect->DfsSessionTime = 13;
+			}
+
+						DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pRadarDetect->RDDurRegion));
+		}
+		else
+		{
+			pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+			pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+		}
+
+		//WirelessEvent
+		if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, pBuffer, TRUE))
+		{
+#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, pBuffer, TRUE))
+		{
+		    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, pBuffer, TRUE))
+		{
+#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, pBuffer, TRUE))
+		{
+
+#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(RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE))
+			{
+				int     ret = TRUE;
+
+				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)
+					)
+				{
+					ret = FALSE;
+				}
+				else
+				{
+					ret = RT_CfgSetWPAPSKKey(pAd, tmpbuf, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->StaCfg.PMK);
+				}
+
+				if (ret == TRUE)
+				{
+			RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
+			RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, tmpbuf, strlen(tmpbuf));
+					pAd->StaCfg.WpaPassPhraseLen= strlen(tmpbuf);
+
+					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)
+					{
+						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, pBuffer);
+
+
+		//HSCounter
+		/*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, pBuffer, TRUE))
+		{
+			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, pBuffer);
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef CARRIER_DETECTION_SUPPORT
+			//CarrierDetect
+			if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, pBuffer, TRUE))
+			{
+				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, pBuffer, TRUE))
+			{
+				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
+						RTMP_SET_PSM_BIT(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));
+				}
+			}
+			// AutoRoaming by RSSI
+			if (RTMPGetKeyParameter("AutoRoaming", tmpbuf, 32, pBuffer, TRUE))
+			{
+				if (simple_strtol(tmpbuf, 0, 10) == 0)
+					pAd->StaCfg.bAutoRoaming = FALSE;
+				else
+					pAd->StaCfg.bAutoRoaming = TRUE;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("AutoRoaming=%d\n", pAd->StaCfg.bAutoRoaming));
+			}
+			// RoamThreshold
+			if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, pBuffer, TRUE))
+			{
+				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, pBuffer, TRUE))
+			{
+				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));
+			}
+
+			// Beacon Lost Time
+			if (RTMPGetKeyParameter("BeaconLostTime", tmpbuf, 32, pBuffer, TRUE))
+			{
+				ULONG lInfo = (ULONG)simple_strtol(tmpbuf, 0, 10);
+
+				if ((lInfo != 0) && (lInfo <= 60))
+					pAd->StaCfg.BeaconLostTime = (lInfo * OS_HZ);
+				DBGPRINT(RT_DEBUG_TRACE, ("BeaconLostTime=%ld \n", pAd->StaCfg.BeaconLostTime));
+			}
+
+
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#ifdef RT30xx
+#ifdef ANT_DIVERSITY_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			if(RTMPGetKeyParameter("AntDiversity", tmpbuf, 10, pBuffer, TRUE))
+			{
+				for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+				{
+					UCHAR Ant = simple_strtol(tmpbuf, 0, 10);
+					if(Ant < 3)
+						pAd->CommonCfg.bRxAntDiversity = Ant;
+					else
+						pAd->CommonCfg.bRxAntDiversity = ANT_DIVERSITY_DISABLE;
+
+					DBGPRINT(RT_DEBUG_ERROR, ("AntDiversity=%d\n", pAd->CommonCfg.bRxAntDiversity));
+				}
+			}
+		}
+#endif // ANT_DIVERSITY_SUPPORT //
+#endif // RT30xx //
+
+	}while(0);
+
+
+	kfree(tmpbuf);
+
+	return NDIS_STATUS_SUCCESS;
+
+}
+
+
+#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];
+
+/*
+========================================================================
+Routine Description:
+    Get card profile path.
+
+Arguments:
+    pAd
+
+Return Value:
+    TRUE		- Find a card profile
+	FALSE		- use default profile
+
+Note:
+========================================================================
+*/
+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');		\
+		} }
+
+	RTMP_OS_FD srcf;
+	INT retval;
+	PSTRING buffer, tmpbuf;
+	STRING 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;
+	RTMP_OS_FS_INFO osFSInfo;
+
+	// 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;
+	}
+
+	// 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
+
+	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
+	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);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("mac addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", PRINT_MAC(mac)));
+
+	RtmpOSFSInfoChange(&osFSInfo, TRUE);
+	// open card information file
+	srcf = RtmpOSFileOpen(CARD_INFO_PATH, O_RDONLY, 0);
+	if (IS_FILE_OPEN_ERR(srcf))
+	{
+		/* card information file does not exist */
+			DBGPRINT(RT_DEBUG_TRACE,
+				("--> Error opening %s\n", CARD_INFO_PATH));
+		goto  free_resource;
+	}
+
+	/* card information file exists so reading the card information */
+	memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+	retval = RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE);
+	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, TRUE))
+		{
+			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 = (PUCHAR)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 = (PUCHAR)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 = (PUCHAR)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, TRUE))
+			{
+				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 = RtmpOSFileClose(srcf);
+
+free_resource:
+	RtmpOSFSInfoChange(&osFSInfo, FALSE);
+	kfree(buffer);
+	kfree(tmpbuf);
+
+	return flg_match_ok;
+}
+#endif // MULTIPLE_CARD_SUPPORT //
diff --git a/drivers/staging/rt3090/common/cmm_sanity.c b/drivers/staging/rt3090/common/cmm_sanity.c
new file mode 100644
index 0000000..de631c3
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_sanity.c
@@ -0,0 +1,1718 @@
+/*
+ *************************************************************************
+ * 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.
+#ifdef UNALIGNMENT_SUPPORT
+	{
+		BA_PARM		tmpBaParm;
+
+		NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM));
+		*(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm));
+		NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM));
+	}
+#else
+	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+#endif
+	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.
+#ifdef UNALIGNMENT_SUPPORT
+	{
+		BA_PARM		tmpBaParm;
+
+		NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM));
+		*(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm));
+		NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM));
+	}
+#else
+	*(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+#endif
+	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)
+{
+    UCHAR				*Ptr;
+#ifdef CONFIG_STA_SUPPORT
+	UCHAR				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));
+#ifdef UNALIGNMENT_SUPPORT
+				{
+					EXT_HT_CAP_INFO extHtCapInfo;
+					NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+					*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
+					NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+				}
+#else
+				*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+#endif // UNALIGNMENT_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+				IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				{
+					*pPreNHtCapabilityLen = 0;	// Now 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((PCHAR)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 //
+
+
+                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_LOUD, ("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 = (PCHAR) 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
+#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 == AUTH_MODE_OPEN)
+    {
+        if (*pSeq == 1 || *pSeq == 2)
+        {
+            return TRUE;
+        }
+        else
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
+            return FALSE;
+        }
+    }
+    else if (*pAlg == AUTH_MODE_KEY)
+    {
+        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 == AUTH_MODE_KEY) ||(*pAlg == AUTH_MODE_OPEN)
+	) &&
+        ((*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:
+        Check the validity of the received EAPoL frame
+    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 (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP)	// TKIP
+        {
+            HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic, MD5_DIGEST_SIZE);
+        }
+        else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)	// AES
+        {
+            HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, digest, SHA1_DIGEST_SIZE);
+            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;
+        }
+	}
+
+	// 1. Decrypt the Key Data field if GTK is included.
+	// 2. Extract the context of the Key Data field if it exist.
+	// The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear.
+	// The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
+	if (CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen) > 0)
+	{
+		// Decrypt this field
+		if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+		{
+			if(
+				(EapolKeyInfo.KeyDescVer == DESC_TYPE_AES))
+			{
+				// AES
+				AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA,
+									CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
+									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,
+								CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
+			}
+
+			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, CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen));
+		}
+		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,
+								  CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen),
+								  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 = (PCHAR)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));
+#ifdef UNALIGNMENT_SUPPORT
+					{
+						EXT_HT_CAP_INFO extHtCapInfo;
+
+						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
+						NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+					}
+#else
+					*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+#endif // UNALIGNMENT_SUPPORT //
+					*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 = (PCHAR)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));
+#ifdef UNALIGNMENT_SUPPORT
+					{
+						EXT_HT_CAP_INFO extHtCapInfo;
+
+						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
+						NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+					}
+#else
+					*(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+#endif // UNALIGNMENT_SUPPORT //
+					*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 = (PCHAR)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/rt3090/common/cmm_sync.c b/drivers/staging/rt3090/common/cmm_sync.c
new file mode 100644
index 0000000..6d7b974
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_sync.c
@@ -0,0 +1,734 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_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, 169, 173};
+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};
+UCHAR A_BAND_REGION_12_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_13_CHANNEL_LIST[]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161};
+UCHAR A_BAND_REGION_14_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_15_CHANNEL_LIST[]={149, 153, 157, 161, 165, 169, 173};
+
+
+//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;
+			case REGION_12_A_BAND:
+				num = sizeof(A_BAND_REGION_12_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
+				break;
+			case REGION_13_A_BAND:
+				num = sizeof(A_BAND_REGION_13_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
+				break;
+			case REGION_14_A_BAND:
+				num = sizeof(A_BAND_REGION_14_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
+				break;
+			case REGION_15_A_BAND:
+				num = sizeof(A_BAND_REGION_15_CHANNEL_LIST)/sizeof(UCHAR);
+				pChannelList = A_BAND_REGION_15_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);
+	}
+	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)
+				RTMP_SET_PSM_BIT(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);
+		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)
+			)
+		{
+			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;
+
+#ifdef CONFIG_STA_SUPPORT
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+				MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+#endif // CONFIG_STA_SUPPORT //
+
+
+			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));
+#ifdef UNALIGNMENT_SUPPORT
+					{
+						EXT_HT_CAP_INFO extHtCapInfo;
+
+						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
+						NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+					}
+#else
+					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+#endif // UNALIGNMENT_SUPPORT //
+
+					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));
+#ifdef UNALIGNMENT_SUPPORT
+					{
+						EXT_HT_CAP_INFO extHtCapInfo;
+
+						NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+						*(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo));
+						NdisMoveMemory((PUCHAR)(&HtCapabilityTmp.ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO));
+					}
+#else
+					*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = cpu2le16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+#endif // UNALIGNMENT_SUPPORT //
+
+					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/rt3090/common/cmm_tkip.c b/drivers/staging/rt3090/common/cmm_tkip.c
new file mode 100644
index 0000000..0b474f2
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_tkip.c
@@ -0,0 +1,966 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_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
+};
+
+//
+// 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;
+}
+
+
+//
+// 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;
+}
diff --git a/drivers/staging/rt3090/common/cmm_wep.c b/drivers/staging/rt3090/common/cmm_wep.c
new file mode 100644
index 0000000..d8ddfb2
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_wep.c
@@ -0,0 +1,500 @@
+/*
+ *************************************************************************
+ * 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.
+
+    {
+		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/rt3090/common/cmm_wpa.c b/drivers/staging/rt3090/common/cmm_wpa.c
new file mode 100644
index 0000000..bf68ad8
--- /dev/null
+++ b/drivers/staging/rt3090/common/cmm_wpa.c
@@ -0,0 +1,3149 @@
+/*
+ *************************************************************************
+ * 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_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
+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};
+UCHAR       OUI_WPA2_WEP104[4]   = {0x00, 0x0F, 0xAC, 0x05};
+
+
+
+static VOID	ConstructEapolKeyData(
+	IN	PMAC_TABLE_ENTRY	pEntry,
+	IN	UCHAR			GroupKeyWepStatus,
+	IN	UCHAR			keyDescVer,
+	IN	UCHAR			MsgType,
+	IN	UCHAR			DefaultKeyIdx,
+	IN	UCHAR			*GTK,
+	IN	UCHAR			*RSNIE,
+	IN	UCHAR			RSNIE_LEN,
+	OUT PEAPOL_PACKET   pMsg);
+
+static VOID	CalculateMIC(
+	IN	UCHAR			KeyDescVer,
+	IN	UCHAR			*PTK,
+	OUT PEAPOL_PACKET   pMsg);
+
+static VOID WpaEAPPacketAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+static VOID WpaEAPOLASFAlertAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+static VOID WpaEAPOLLogoffAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem);
+
+static VOID WpaEAPOLStartAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem);
+
+static VOID WpaEAPOLKeyAction(
+    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
+    ==========================================================================
+ */
+VOID WpaStateMachineInit(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  STATE_MACHINE *S,
+    OUT STATE_MACHINE_FUNC Trans[])
+{
+    StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_WPA_PTK_STATE, MAX_WPA_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PTK, WPA_MACHINE_BASE);
+
+    StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket, (STATE_MACHINE_FUNC)WpaEAPPacketAction);
+    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart, (STATE_MACHINE_FUNC)WpaEAPOLStartAction);
+    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff, (STATE_MACHINE_FUNC)WpaEAPOLLogoffAction);
+    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
+    StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert, (STATE_MACHINE_FUNC)WpaEAPOLASFAlertAction);
+}
+
+/*
+    ==========================================================================
+    Description:
+        this is state machine function.
+        When receiving EAP packets which is  for 802.1x authentication use.
+        Not use in PSK case
+    Return:
+    ==========================================================================
+*/
+VOID WpaEAPPacketAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID WpaEAPOLASFAlertAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID WpaEAPOLLogoffAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+/*
+    ==========================================================================
+    Description:
+       Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
+    Return:
+    ==========================================================================
+*/
+VOID WpaEAPOLStartAction(
+    IN PRTMP_ADAPTER    pAd,
+    IN MLME_QUEUE_ELEM  *Elem)
+{
+    MAC_TABLE_ENTRY     *pEntry;
+    PHEADER_802_11      pHeader;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
+
+    pHeader = (PHEADER_802_11)Elem->Msg;
+
+    //For normaol PSK, we enqueue an EAPOL-Start command to trigger the process.
+    if (Elem->MsgLen == 6)
+        pEntry = MacTableLookup(pAd, Elem->Msg);
+    else
+    {
+        pEntry = MacTableLookup(pAd, pHeader->Addr2);
+    }
+
+    if (pEntry)
+    {
+		DBGPRINT(RT_DEBUG_TRACE, (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n", pEntry->PortSecured, pEntry->WpaState, pEntry->AuthMode, pEntry->PMKID_CacheIdx));
+
+        if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+			&& (pEntry->WpaState < AS_PTKSTART)
+            && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND))))
+        {
+            pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+            pEntry->WpaState = AS_INITPSK;
+            pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+            NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
+            pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+
+            WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
+        }
+    }
+}
+
+/*
+    ==========================================================================
+    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)
+{
+    MAC_TABLE_ENTRY     *pEntry;
+    PHEADER_802_11      pHeader;
+    PEAPOL_PACKET       pEapol_packet;
+	KEY_INFO			peerKeyInfo;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
+
+    pHeader = (PHEADER_802_11)Elem->Msg;
+    pEapol_packet = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+	NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+	NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pEapol_packet->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+	hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet, (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
+
+	*((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
+
+    do
+    {
+        pEntry = MacTableLookup(pAd, pHeader->Addr2);
+
+		if (!pEntry || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+            break;
+
+		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
+				break;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n", PRINT_MAC(pEntry->Addr)));
+
+        if (((pEapol_packet->ProVer != EAPOL_VER) && (pEapol_packet->ProVer != EAPOL_VER2)) ||
+			((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC) && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC)))
+        {
+            DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
+            break;
+        }
+
+		// The value 1 shall be used for all EAPOL-Key frames to and from a STA when
+		// neither the group nor pairwise ciphers are CCMP for Key Descriptor 1.
+		if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP))
+        {
+	        DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(TKIP) \n"));
+	    break;
+	}
+		// The value 2 shall be used for all EAPOL-Key frames to and from a STA when
+		// either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2.
+	else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(AES) \n"));
+		break;
+	}
+
+		// Check if this STA is in class 3 state and the WPA state is started
+        if ((pEntry->Sst == SST_ASSOC) && (pEntry->WpaState >= AS_INITPSK))
+        {
+			// Check the Key Ack (bit 7) of the Key Information to determine the Authenticator
+			// or not.
+			// An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL-
+			// Key frame from the Authenticator must not have the Ack bit set.
+			if (peerKeyInfo.KeyAck == 1)
+			{
+				// The frame is snet by Authenticator.
+				// So the Supplicant side shall handle this.
+
+				if ((peerKeyInfo.Secure == 0) && (peerKeyInfo.Request == 0) &&
+					(peerKeyInfo.Error == 0) && (peerKeyInfo.KeyType == PAIRWISEKEY))
+				{
+					// Process 1. the message 1 of 4-way HS in WPA or WPA2
+					//			  EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1)
+					//		   2. the message 3 of 4-way HS in WPA
+					//			  EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)
+					if (peerKeyInfo.KeyMic == 0)
+			PeerPairMsg1Action(pAd, pEntry, Elem);
+	                else
+	                PeerPairMsg3Action(pAd, pEntry, Elem);
+				}
+				else if ((peerKeyInfo.Secure == 1) &&
+						 (peerKeyInfo.KeyMic == 1) &&
+						 (peerKeyInfo.Request == 0) &&
+						 (peerKeyInfo.Error == 0))
+				{
+					// Process 1. the message 3 of 4-way HS in WPA2
+					//			  EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3)
+					//		   2. the message 1 of group KS in WPA or WPA2
+					//			  EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N])
+					if (peerKeyInfo.KeyType == PAIRWISEKEY)
+						PeerPairMsg3Action(pAd, pEntry, Elem);
+					else
+						PeerGroupMsg1Action(pAd, pEntry, Elem);
+				}
+			}
+			else
+			{
+				// The frame is snet by Supplicant.
+				// So the Authenticator side shall handle this.
+				if ((peerKeyInfo.Request == 0) &&
+						 (peerKeyInfo.Error == 0) &&
+						 (peerKeyInfo.KeyMic == 1))
+				{
+					if (peerKeyInfo.Secure == 0 && peerKeyInfo.KeyType == PAIRWISEKEY)
+					{
+						// EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data)
+						// Process 1. message 2 of 4-way HS in WPA or WPA2
+						//		   2. message 4 of 4-way HS in WPA
+						if (CONV_ARRARY_TO_UINT16(pEapol_packet->KeyDesc.KeyDataLen) == 0)
+						{
+							PeerPairMsg4Action(pAd, pEntry, Elem);
+			}
+						else
+						{
+							PeerPairMsg2Action(pAd, pEntry, Elem);
+						}
+					}
+					else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == PAIRWISEKEY)
+					{
+						// EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0)
+						// Process message 4 of 4-way HS in WPA2
+						PeerPairMsg4Action(pAd, pEntry, Elem);
+					}
+					else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == GROUPKEY)
+					{
+						// EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0)
+						// Process message 2 of Group key HS in WPA or WPA2
+						PeerGroupMsg2Action(pAd, pEntry, &Elem->Msg[LENGTH_802_11], (Elem->MsgLen - LENGTH_802_11));
+					}
+				}
+			}
+        }
+    }while(FALSE);
+}
+
+/*
+	========================================================================
+
+	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  PMAC_TABLE_ENTRY	pEntry,
+    IN  PUCHAR			pHeader802_3,
+    IN  UINT			HdrLen,
+    IN  PUCHAR			pData,
+    IN  UINT			DataLen,
+    IN	BOOLEAN				bClearFrame)
+{
+    PNDIS_PACKET    pPacket;
+    NDIS_STATUS     Status;
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+		return;
+
+    do {
+		// build a NDIS packet
+		Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
+		if (Status != NDIS_STATUS_SUCCESS)
+		break;
+
+
+			if (bClearFrame)
+				RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
+			else
+				RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
+		{
+			RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+
+			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);	// set a default value
+			if(pEntry->apidx != 0)
+			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, pEntry->apidx);
+
+		RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
+			RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+		    // send out the packet
+	        Status = STASendPacket(pAd, pPacket);
+	    if (Status == NDIS_STATUS_SUCCESS)
+			{
+				UCHAR   Index;
+
+				// 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);
+				}
+			}
+		}
+#endif // CONFIG_STA_SUPPORT //
+
+    } while (FALSE);
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is a function to initilize 4-way handshake
+
+    Return:
+
+    ==========================================================================
+*/
+VOID WPAStart4WayHS(
+    IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN ULONG			TimeInterval)
+{
+    UCHAR           Header802_3[14];
+    EAPOL_PACKET	EAPOLPKT;
+	PUINT8			pBssid = NULL;
+	UCHAR			group_cipher = Ndis802_11WEPDisabled;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
+
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
+		return;
+	}
+
+
+	if (pBssid == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
+		return;
+    }
+
+	// Check the status
+    if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK))
+    {
+        DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
+        return;
+    }
+
+
+	// Increment replay counter by 1
+	ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+	// Randomly generate ANonce
+	GenRandom(pAd, (UCHAR *)pBssid, pEntry->ANonce);
+
+	// Construct EAPoL message - Pairwise Msg 1
+	// EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1)
+	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
+	ConstructEapolMsg(pEntry,
+					  group_cipher,
+					  EAPOL_PAIR_MSG_1,
+					  0,					// Default key index
+					  pEntry->ANonce,
+					  NULL,					// TxRSC
+					  NULL,					// GTK
+					  NULL,					// RSNIE
+					  0,					// RSNIE length
+					  &EAPOLPKT);
+
+
+	// Make outgoing frame
+    MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+    RTMPToWirelessSta(pAd, pEntry, Header802_3,
+					  LENGTH_802_3, (PUCHAR)&EAPOLPKT,
+					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4,
+					  (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
+
+	// Trigger Retry Timer
+    RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
+
+	// Update State
+    pEntry->WpaState = AS_PTKSTART;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
+
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
+
+	Arguments:
+		pAd			Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID PeerPairMsg1Action(
+	IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem)
+{
+	UCHAR				PTK[80];
+	UCHAR               Header802_3[14];
+	PEAPOL_PACKET		pMsg1;
+	UINT			MsgLen;
+	EAPOL_PACKET		EAPOLPKT;
+	PUINT8				pCurrentAddr = NULL;
+	PUINT8				pmk_ptr = NULL;
+	UCHAR				group_cipher = Ndis802_11WEPDisabled;
+	PUINT8				rsnie_ptr = NULL;
+	UCHAR				rsnie_len = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+		return;
+
+    if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
+        return;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		pCurrentAddr = pAd->CurrentAddress;
+		pmk_ptr = pAd->StaCfg.PMK;
+		group_cipher = pAd->StaCfg.GroupCipher;
+		rsnie_ptr = pAd->StaCfg.RSN_IE;
+		rsnie_len = pAd->StaCfg.RSNIE_Len;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// Store the received frame
+	pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	// Sanity Check peer Pairwise message 1 - Replay Counter
+	if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry) == FALSE)
+		return;
+
+	// Store Replay counter, it will use to verify message 3 and construct message 2
+	NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Store ANonce
+	NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+	// Generate random SNonce
+	GenRandom(pAd, (UCHAR *)pCurrentAddr, pEntry->SNonce);
+
+	{
+	    // Calculate PTK(ANonce, SNonce)
+	    WpaDerivePTK(pAd,
+				pmk_ptr,
+				pEntry->ANonce,
+					pEntry->Addr,
+					pEntry->SNonce,
+					pCurrentAddr,
+				    PTK,
+				    LEN_PTK);
+
+		// Save key to PTK entry
+		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
+	}
+
+	// Update WpaState
+	pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+
+	// Construct EAPoL message - Pairwise Msg 2
+	//  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2)
+	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
+	ConstructEapolMsg(pEntry,
+					  group_cipher,
+					  EAPOL_PAIR_MSG_2,
+					  0,				// DefaultKeyIdx
+					  pEntry->SNonce,
+					  NULL,				// TxRsc
+					  NULL,				// GTK
+					  (UCHAR *)rsnie_ptr,
+					  rsnie_len,
+					  &EAPOLPKT);
+
+	// Make outgoing frame
+	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+
+	RTMPToWirelessSta(pAd, pEntry,
+					  Header802_3, sizeof(Header802_3), (PUCHAR)&EAPOLPKT,
+					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the second packet of 4-way pairwisekey handshake.
+    Return:
+    ==========================================================================
+*/
+VOID PeerPairMsg2Action(
+    IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem)
+{
+	UCHAR				PTK[80];
+    BOOLEAN             Cancelled;
+    PHEADER_802_11      pHeader;
+	EAPOL_PACKET        EAPOLPKT;
+	PEAPOL_PACKET       pMsg2;
+	UINT			MsgLen;
+    UCHAR               Header802_3[LENGTH_802_3];
+	UCHAR				TxTsc[6];
+	PUINT8				pBssid = NULL;
+	PUINT8				pmk_ptr = NULL;
+	PUINT8				gtk_ptr = NULL;
+	UCHAR				default_key = 0;
+	UCHAR				group_cipher = Ndis802_11WEPDisabled;
+	PUINT8				rsnie_ptr = NULL;
+	UCHAR				rsnie_len = 0;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
+
+    if ((!pEntry) || (!pEntry->ValidAsCLI))
+        return;
+
+    if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
+        return;
+
+    // check Entry in valid State
+    if (pEntry->WpaState < AS_PTKSTART)
+        return;
+
+
+
+    // pointer to 802.11 header
+	pHeader = (PHEADER_802_11)Elem->Msg;
+
+	// skip 802.11_header(24-byte) and LLC_header(8)
+	pMsg2 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	// Store SNonce
+	NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+	{
+		// Derive PTK
+		WpaDerivePTK(pAd,
+					(UCHAR *)pmk_ptr,
+					pEntry->ANonce,			// ANONCE
+					(UCHAR *)pBssid,
+					pEntry->SNonce,			// SNONCE
+					pEntry->Addr,
+					PTK,
+					LEN_PTK);
+
+	NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
+	}
+
+	// Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE
+	if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry) == FALSE)
+		return;
+
+    do
+    {
+        // delete retry timer
+		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+		// Change state
+        pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+
+		// Increment replay counter by 1
+		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+		// Construct EAPoL message - Pairwise Msg 3
+		NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
+		ConstructEapolMsg(pEntry,
+						  group_cipher,
+						  EAPOL_PAIR_MSG_3,
+						  default_key,
+						  pEntry->ANonce,
+						  TxTsc,
+						  (UCHAR *)gtk_ptr,
+						  (UCHAR *)rsnie_ptr,
+						  rsnie_len,
+						  &EAPOLPKT);
+
+        // Make outgoing frame
+        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+        RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
+						  (PUCHAR)&EAPOLPKT,
+						  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4,
+						  (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
+
+        pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
+		RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
+
+		// Update State
+        pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
+    }while(FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID PeerPairMsg3Action(
+    IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem)
+{
+	PHEADER_802_11		pHeader;
+	UCHAR               Header802_3[14];
+	EAPOL_PACKET		EAPOLPKT;
+	PEAPOL_PACKET		pMsg3;
+	UINT			MsgLen;
+	PUINT8				pCurrentAddr = NULL;
+	UCHAR				group_cipher = Ndis802_11WEPDisabled;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+		return;
+
+    if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
+		return;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		pCurrentAddr = pAd->CurrentAddress;
+		group_cipher = pAd->StaCfg.GroupCipher;
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// 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];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	// Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE
+	if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry) == FALSE)
+		return;
+
+	// Save Replay counter, it will use construct message 4
+	NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Double check ANonce
+	if (!NdisEqualMemory(pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
+	{
+		return;
+	}
+
+	// Construct EAPoL message - Pairwise Msg 4
+	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
+	ConstructEapolMsg(pEntry,
+					  group_cipher,
+					  EAPOL_PAIR_MSG_4,
+					  0,					// group key index not used in message 4
+					  NULL,					// Nonce not used in message 4
+					  NULL,					// TxRSC not used in message 4
+					  NULL,					// GTK not used in message 4
+					  NULL,					// RSN IE not used in message 4
+					  0,
+					  &EAPOLPKT);
+
+	// Update WpaState
+	pEntry->WpaState = AS_PTKINITDONE;
+
+	// Update pairwise key
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		PCIPHER_KEY pSharedKey;
+
+		pSharedKey = &pAd->SharedKey[BSS0][0];
+
+		NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
+
+		// Prepare pair-wise key information into shared key table
+		NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
+		pSharedKey->KeyLen = LEN_TKIP_EK;
+	    NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+		// Decide its ChiperAlg
+		if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+			pSharedKey->CipherAlg = CIPHER_TKIP;
+		else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+			pSharedKey->CipherAlg = CIPHER_AES;
+		else
+			pSharedKey->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 = pSharedKey->CipherAlg;
+
+		// Update pairwise key information to ASIC Shared Key Table
+		AsicAddSharedKeyEntry(pAd,
+							  BSS0,
+							  0,
+							  pSharedKey->CipherAlg,
+							  pSharedKey->Key,
+							  pSharedKey->TxMic,
+							  pSharedKey->RxMic);
+
+		// Update ASIC WCID attribute table and IVEIV table
+		RTMPAddWcidAttributeEntry(pAd,
+								  BSS0,
+								  0,
+								  pSharedKey->CipherAlg,
+								  pEntry);
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// open 802.1x port control and privacy filter
+	if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
+		pEntry->AuthMode == Ndis802_11AuthModeWPA2)
+	{
+		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+
+#ifdef CONFIG_STA_SUPPORT
+		STA_PORT_SECURED(pAd);
+	    // Indicate Connected for GUI
+	    pAd->IndicateMediaState = NdisMediaStateConnected;
+#endif // CONFIG_STA_SUPPORT //
+		DBGPRINT(RT_DEBUG_TRACE, ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
+									GetAuthMode(pEntry->AuthMode),
+									GetEncryptType(pEntry->WepStatus),
+									GetEncryptType(group_cipher)));
+	}
+	else
+	{
+	}
+
+	// Init 802.3 header and send out
+	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+	RTMPToWirelessSta(pAd, pEntry,
+					  Header802_3, sizeof(Header802_3),
+					  (PUCHAR)&EAPOLPKT,
+					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the last packet of 4-way pairwisekey handshake.
+        Initilize 2-way groupkey handshake following.
+    Return:
+    ==========================================================================
+*/
+VOID PeerPairMsg4Action(
+    IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem)
+{
+	PEAPOL_PACKET		pMsg4;
+    PHEADER_802_11      pHeader;
+    UINT		MsgLen;
+    BOOLEAN             Cancelled;
+	UCHAR				group_cipher = Ndis802_11WEPDisabled;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
+
+    do
+    {
+        if ((!pEntry) || (!pEntry->ValidAsCLI))
+            break;
+
+        if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2 ) )
+            break;
+
+        if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
+            break;
+
+
+        // pointer to 802.11 header
+        pHeader = (PHEADER_802_11)Elem->Msg;
+
+		// skip 802.11_header(24-byte) and LLC_header(8)
+		pMsg4 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+		MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+        // Sanity Check peer Pairwise message 4 - Replay Counter, MIC
+		if (PeerWpaMessageSanity(pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
+			break;
+
+        // 3. uses the MLME.SETKEYS.request to configure PTK into MAC
+        NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY));
+
+		// reset IVEIV in Asic
+		AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
+
+        pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
+        NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32], LEN_TKIP_EK);
+        NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[TKIP_AP_RXMICK_OFFSET], LEN_TKIP_RXMICK);
+        NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[TKIP_AP_TXMICK_OFFSET], LEN_TKIP_TXMICK);
+
+		// Set pairwise key to Asic
+        {
+            pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+            if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
+                pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
+            else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+                pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
+
+			// 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,
+				pEntry->apidx,
+				0,
+				pEntry->PairwiseKey.CipherAlg,
+				pEntry);
+        }
+
+        // 4. upgrade state
+        pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+        pEntry->WpaState = AS_PTKINITDONE;
+		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+
+		if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
+			pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
+		{
+			pEntry->GTKState = REKEY_ESTABLISHED;
+			RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+
+			// send wireless event - for set key done WPA2
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+	        DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+									pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
+									pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
+									group_cipher,
+									GetEncryptType(group_cipher)));
+		}
+		else
+		{
+		// 5. init Group 2-way handshake if necessary.
+	        WPAStart2WayGroupHS(pAd, pEntry);
+
+		pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
+			RTMPModTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
+		}
+    }while(FALSE);
+
+}
+
+/*
+    ==========================================================================
+    Description:
+        This is a function to send the first packet of 2-way groupkey handshake
+    Return:
+
+    ==========================================================================
+*/
+VOID WPAStart2WayGroupHS(
+    IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry)
+{
+    UCHAR               Header802_3[14];
+	UCHAR				TxTsc[6];
+    EAPOL_PACKET	EAPOLPKT;
+	UCHAR				group_cipher = Ndis802_11WEPDisabled;
+	UCHAR				default_key = 0;
+	PUINT8				gnonce_ptr = NULL;
+	PUINT8				gtk_ptr = NULL;
+	PUINT8				pBssid = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
+
+    if ((!pEntry) || (!pEntry->ValidAsCLI))
+        return;
+
+
+    do
+    {
+        // Increment replay counter by 1
+		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
+
+		// Construct EAPoL message - Group Msg 1
+		NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
+		ConstructEapolMsg(pEntry,
+						  group_cipher,
+						  EAPOL_GROUP_MSG_1,
+						  default_key,
+						  (UCHAR *)gnonce_ptr,
+						  TxTsc,
+						  (UCHAR *)gtk_ptr,
+						  NULL,
+						  0,
+						  &EAPOLPKT);
+
+		// Make outgoing frame
+        MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
+        RTMPToWirelessSta(pAd, pEntry,
+						  Header802_3, LENGTH_802_3,
+						  (PUCHAR)&EAPOLPKT,
+						  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE);
+
+
+
+    }while (FALSE);
+
+    DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
+
+    return;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Process Group key 2-way handshaking
+
+	Arguments:
+		pAd	Pointer	to our adapter
+		Elem		Message body
+
+	Return Value:
+		None
+
+	Note:
+
+	========================================================================
+*/
+VOID	PeerGroupMsg1Action(
+	IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN MLME_QUEUE_ELEM  *Elem)
+{
+    UCHAR               Header802_3[14];
+	EAPOL_PACKET		EAPOLPKT;
+	PEAPOL_PACKET		pGroup;
+	UINT			MsgLen;
+	BOOLEAN             Cancelled;
+	UCHAR				default_key = 0;
+	UCHAR				group_cipher = Ndis802_11WEPDisabled;
+	PUINT8				pCurrentAddr = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
+
+	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
+        return;
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		pCurrentAddr = pAd->CurrentAddress;
+		group_cipher = pAd->StaCfg.GroupCipher;
+		default_key = pAd->StaCfg.DefaultKeyId;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	// 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];
+	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
+
+	// Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE
+	if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry) == FALSE)
+		return;
+
+	// delete retry timer
+	RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+
+	// Save Replay counter, it will use to construct message 2
+	NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+	// Construct EAPoL message - Group Msg 2
+	NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET));
+	ConstructEapolMsg(pEntry,
+					  group_cipher,
+					  EAPOL_GROUP_MSG_2,
+					  default_key,
+					  NULL,					// Nonce not used
+					  NULL,					// TxRSC not used
+					  NULL,					// GTK not used
+					  NULL,					// RSN IE not used
+					  0,
+					  &EAPOLPKT);
+
+    // open 802.1x port control and privacy filter
+	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+	pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+
+#ifdef CONFIG_STA_SUPPORT
+	STA_PORT_SECURED(pAd);
+    // Indicate Connected for GUI
+    pAd->IndicateMediaState = NdisMediaStateConnected;
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
+									GetAuthMode(pEntry->AuthMode),
+									GetEncryptType(pEntry->WepStatus),
+									GetEncryptType(group_cipher)));
+
+	// init header and Fill Packet and send Msg 2 to authenticator
+	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
+	RTMPToWirelessSta(pAd, pEntry,
+					  Header802_3, sizeof(Header802_3),
+					  (PUCHAR)&EAPOLPKT,
+					  CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerGroupMsg1Action: sned group message 2\n"));
+}
+
+/*
+    ==========================================================================
+    Description:
+        When receiving the last packet of 2-way groupkey handshake.
+    Return:
+    ==========================================================================
+*/
+VOID PeerGroupMsg2Action(
+    IN PRTMP_ADAPTER    pAd,
+    IN MAC_TABLE_ENTRY  *pEntry,
+    IN VOID             *Msg,
+    IN UINT             MsgLen)
+{
+    UINT		Len;
+    PUCHAR		pData;
+    BOOLEAN		Cancelled;
+	PEAPOL_PACKET       pMsg2;
+	UCHAR				group_cipher = Ndis802_11WEPDisabled;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
+
+    do
+    {
+        if ((!pEntry) || (!pEntry->ValidAsCLI))
+            break;
+
+        if (MsgLen < (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2))
+            break;
+
+        if (pEntry->WpaState != AS_PTKINITDONE)
+            break;
+
+
+        pData = (PUCHAR)Msg;
+		pMsg2 = (PEAPOL_PACKET) (pData + LENGTH_802_1_H);
+        Len = MsgLen - LENGTH_802_1_H;
+
+		// Sanity Check peer group message 2 - Replay Counter, MIC
+		if (PeerWpaMessageSanity(pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
+            break;
+
+        // 3.  upgrade state
+
+		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
+        pEntry->GTKState = REKEY_ESTABLISHED;
+
+		if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		{
+			// send wireless event - for set key done WPA2
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+			DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+										pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
+										pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
+										group_cipher, GetEncryptType(group_cipher)));
+		}
+		else
+		{
+			// send wireless event - for set key done WPA
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA1_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+		DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
+										pEntry->AuthMode, GetAuthMode(pEntry->AuthMode),
+										pEntry->WepStatus, GetEncryptType(pEntry->WepStatus),
+										group_cipher, GetEncryptType(group_cipher)));
+		}
+    }while(FALSE);
+}
+
+/*
+	========================================================================
+
+	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;
+}
+
+/*
+	========================================================================
+
+	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(key, key_len, input, total_len, &output[currentindex], SHA1_DIGEST_SIZE);
+		currentindex +=	20;
+
+		// update the last octet
+		input[total_len - 1]++;
+	}
+    os_free_mem(NULL, input);
+}
+
+/*
+* 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)
+*/
+
+static void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
+{
+    unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
+    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((unsigned char*) password, (int) strlen(password), digest, ssidlength+4, digest1, SHA1_DIGEST_SIZE); // for WPA update
+
+    /* output = U1 */
+    memcpy(output, digest1, SHA1_DIGEST_SIZE);
+
+    for (i = 1; i < iterations; i++)
+    {
+        /* Un = PRF(P, Un-1) */
+        HMAC_SHA1((unsigned char*) password, (int) strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); // for WPA update
+        memcpy(digest1, digest, SHA1_DIGEST_SIZE);
+
+        /* output = output xor Un */
+        for (j = 0; j < SHA1_DIGEST_SIZE; 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(PSTRING password, PUCHAR ssid, INT ssidlength, PUCHAR output)
+{
+    if ((strlen(password) > 63) || (ssidlength > 32))
+        return 0;
+
+    F(password, ssid, ssidlength, 4096, 1, output);
+    F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
+    return 1;
+}
+
+
+
+/*
+	========================================================================
+
+	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 WpaDerivePTK(
+	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 RTMPMakeRsnIeCipher(
+	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;
+        }
+
+#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);
+	}
+	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;
+        }
+
+#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);
+	}
+}
+
+/*
+	========================================================================
+
+	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 RTMPMakeRsnIeAKM(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			ElementID,
+	IN	UINT			AuthMode,
+	IN	UCHAR			apidx,
+	OUT	PUCHAR			pRsnIe,
+	OUT	UCHAR			*rsn_len)
+{
+	RSNIE_AUTH		*pRsnie_auth;
+	UCHAR			AkmCnt = 1;		// default as 1
+
+	pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
+
+	// decide WPA2 or WPA1
+	if (ElementID == Wpa2Ie)
+	{
+
+		switch (AuthMode)
+        {
+            case Ndis802_11AuthModeWPA2:
+            case Ndis802_11AuthModeWPA1WPA2:
+			NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
+                break;
+
+            case Ndis802_11AuthModeWPA2PSK:
+            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+			NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
+                break;
+			default:
+				AkmCnt = 0;
+				break;
+
+        }
+	}
+	else
+	{
+		switch (AuthMode)
+        {
+            case Ndis802_11AuthModeWPA:
+            case Ndis802_11AuthModeWPA1WPA2:
+                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
+                break;
+
+            case Ndis802_11AuthModeWPAPSK:
+            case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
+                break;
+
+			case Ndis802_11AuthModeWPANone:
+                NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
+                break;
+			default:
+				AkmCnt = 0;
+				break;
+        }
+	}
+
+	pRsnie_auth->acount = AkmCnt;
+	pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
+
+	// update current RSNIE length
+	(*rsn_len) += (sizeof(RSNIE_AUTH) + (4 * (AkmCnt - 1)));
+
+}
+
+/*
+	========================================================================
+
+	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 RTMPMakeRsnIeCap(
+	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 = WPA_TKIPAES_WPA2_TKIPAES;	// 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
+		RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
+
+		// 2. insert AKM
+		RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
+
+		// 3. insert capability
+		RTMPMakeRsnIeCap(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))
+//	if (*(UINT16 *)EAPOL == *(UINT16 *)pData)
+    {
+        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:
+		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
+
+    ==========================================================================
+*/
+PSTRING 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) &&
+				(pEid->Eid == pEntry->RSN_IE[0]) &&
+				((pEid->Len + 2) >= pEntry->RSNIE_Len) &&
+				(NdisEqualMemory(pEid->Octet, &pEntry->RSN_IE[2], pEntry->RSNIE_Len - 2)))
+			{
+
+					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)
+			{
+				WpaShowAllsuite(pMyKeyData, skip_offset);
+
+				// 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));
+	//hex_dump("remain data", pMyKeyData, 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
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		PCIPHER_KEY pSharedKey;
+
+		// set key material, TxMic and RxMic
+		NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
+		pAd->StaCfg.DefaultKeyId = DefaultIdx;
+
+		pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
+
+		// Prepare pair-wise key information into shared key table
+		NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
+		pSharedKey->KeyLen = LEN_TKIP_EK;
+		NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
+		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_RXMICK);
+		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_TXMICK);
+
+		// Update Shared Key CipherAlg
+		pSharedKey->CipherAlg = CIPHER_NONE;
+		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+			pSharedKey->CipherAlg = CIPHER_TKIP;
+		else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+			pSharedKey->CipherAlg = CIPHER_AES;
+		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+			pSharedKey->CipherAlg = CIPHER_WEP64;
+		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+			pSharedKey->CipherAlg = CIPHER_WEP128;
+
+
+		// Update group key information to ASIC Shared Key Table
+		AsicAddSharedKeyEntry(pAd,
+							  BSS0,
+							  pAd->StaCfg.DefaultKeyId,
+							  pSharedKey->CipherAlg,
+							  pSharedKey->Key,
+							  pSharedKey->TxMic,
+							  pSharedKey->RxMic);
+
+		// Update ASIC WCID attribute table and IVEIV table
+		RTMPAddWcidAttributeEntry(pAd,
+								  BSS0,
+								  pAd->StaCfg.DefaultKeyId,
+								  pSharedKey->CipherAlg,
+								  NULL);
+	}
+#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	PMAC_TABLE_ENTRY	pEntry,
+    IN	UCHAR				GroupKeyWepStatus,
+    IN	UCHAR				MsgType,
+    IN	UCHAR				DefaultKeyIdx,
+	IN	UCHAR				*KeyNonce,
+	IN	UCHAR				*TxRSC,
+	IN	UCHAR				*GTK,
+	IN	UCHAR				*RSNIE,
+	IN	UCHAR				RSNIE_Len,
+    OUT PEAPOL_PACKET       pMsg)
+{
+	BOOLEAN	bWPA2 = FALSE;
+	UCHAR	KeyDescVer;
+
+	// Choose WPA2 or not
+	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+		(pEntry->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
+	SET_UINT16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
+
+	// Fill in EAPoL descriptor
+	if (bWPA2)
+		pMsg->KeyDesc.Type = WPA2_KEY_DESC;
+	else
+		pMsg->KeyDesc.Type = WPA1_KEY_DESC;
+
+	// Key Descriptor Version (bits 0-2) specifies the key descriptor version type
+	{
+		// 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.
+		KeyDescVer = (((pEntry->WepStatus == Ndis802_11Encryption3Enabled) ||
+					(GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+	}
+
+	pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
+
+	// 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] = ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
+		}
+	}
+
+	// Fill in replay counter
+    NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, 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(pEntry,
+						  GroupKeyWepStatus,
+						  KeyDescVer,
+						  MsgType,
+						  DefaultKeyIdx,
+						  GTK,
+						  RSNIE,
+						  RSNIE_Len,
+						  pMsg);
+
+	// Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
+	if (MsgType != EAPOL_PAIR_MSG_1)
+	{
+		CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+	DBGPRINT(RT_DEBUG_TRACE, ("	     Body length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->Body_Len)));
+	DBGPRINT(RT_DEBUG_TRACE, ("	     Key length  = %d \n", CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyLength)));
+
+
+}
+
+/*
+	========================================================================
+
+	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	PMAC_TABLE_ENTRY	pEntry,
+	IN	UCHAR			GroupKeyWepStatus,
+	IN	UCHAR			keyDescVer,
+	IN	UCHAR			MsgType,
+	IN	UCHAR			DefaultKeyIdx,
+	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)];
+	ULONG		data_offset;
+	BOOLEAN		bWPA2Capable = FALSE;
+	PRTMP_ADAPTER	pAd = pEntry->pAd;
+	BOOLEAN		GTK_Included = FALSE;
+
+	// Choose WPA2 or not
+	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
+		(pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+		bWPA2Capable = TRUE;
+
+	if (MsgType == EAPOL_PAIR_MSG_1 ||
+		MsgType == EAPOL_PAIR_MSG_4 ||
+		MsgType == EAPOL_GROUP_MSG_2)
+		return;
+
+	// allocate memory pool
+	os_alloc_mem(NULL, (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);
+	SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
+	data_offset = 0;
+
+	// Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
+	if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
+	{
+		PUINT8	pmkid_ptr = NULL;
+		UINT8	pmkid_len = 0;
+
+
+		RTMPInsertRSNIE(&Key_Data[data_offset],
+						(PULONG)&data_offset,
+						RSNIE,
+						RSNIE_LEN,
+						pmkid_ptr,
+						pmkid_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
+	// 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;
+		}
+
+		GTK_Included = TRUE;
+	}
+
+
+	// This whole key-data field shall be encrypted if a GTK is included.
+	// Encrypt the data material in key data field with KEK
+	if (GTK_Included)
+	{
+		//hex_dump("GTK_Included", Key_Data, data_offset);
+
+		if (
+			(keyDescVer == DESC_TYPE_AES))
+		{
+			UCHAR	remainder = 0;
+			UCHAR	pad_len = 0;
+
+			// Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394,
+			// shall be used to encrypt the Key Data field using the KEK field from
+			// the derived PTK.
+
+			// If the Key Data field uses the NIST AES key wrap, then the Key Data field
+			// shall be padded before encrypting if the key data length is less than 16
+			// octets or if it is not a multiple of 8. The padding consists of appending
+			// a single octet 0xdd followed by zero or more 0x00 octets.
+			if ((remainder = data_offset & 0x07) != 0)
+			{
+				INT		i;
+
+				pad_len = (8 - remainder);
+				Key_Data[data_offset] = 0xDD;
+				for (i = 1; i < pad_len; i++)
+					Key_Data[data_offset + i] = 0;
+
+				data_offset += pad_len;
+			}
+
+			AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data, data_offset, Rc4GTK);
+            // AES wrap function will grow 8 bytes in length
+            data_offset += 8;
+		}
+		else
+		{
+			/*	Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
+				using the KEK field from the derived PTK. */
+
+			// 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], &pEntry->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);
+	}
+
+	// Update key data length field and total body length
+	SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
+	INC_UINT16_TO_ARRARY(pMsg->Body_Len, data_offset);
+
+	os_free_mem(NULL, 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:
+
+	========================================================================
+*/
+static VOID	CalculateMIC(
+	IN	UCHAR			KeyDescVer,
+	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(NULL, (PUCHAR *)&OutBuffer, 512);
+
+    if (OutBuffer == NULL)
+    {
+		DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
+		return;
+    }
+
+	// make a frame for calculating MIC.
+    MakeOutgoingFrame(OutBuffer,		&FrameLen,
+                      CONV_ARRARY_TO_UINT16(pMsg->Body_Len) + 4,	pMsg,
+                      END_OF_ARGS);
+
+	NdisZeroMemory(mic, sizeof(mic));
+
+	// Calculate MIC
+    if (KeyDescVer == DESC_TYPE_AES)
+	{
+		HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer,  FrameLen, digest, SHA1_DIGEST_SIZE);
+		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		HMAC_MD5(PTK,  LEN_EAP_MICK, OutBuffer, FrameLen, mic, MD5_DIGEST_SIZE);
+	}
+
+	// store the calculated MIC
+	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
+
+	os_free_mem(NULL, 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;
+
+}
+
+
+PUINT8	GetSuiteFromRSNIE(
+		IN	PUINT8	rsnie,
+		IN	UINT	rsnie_len,
+		IN	UINT8	type,
+		OUT	UINT8	*count)
+{
+	PEID_STRUCT pEid;
+	INT			len;
+	PUINT8		pBuf;
+	INT			offset = 0;
+	PRSNIE_AUTH	pAkm;
+	UINT16		acount;
+	BOOLEAN		isWPA2 = FALSE;
+
+	pEid = (PEID_STRUCT)rsnie;
+	len = rsnie_len - 2;	// exclude IE and length
+	pBuf = (PUINT8)&pEid->Octet[0];
+
+
+
+	// set default value
+	*count = 0;
+
+	// Check length
+	if ((len <= 0) || (pEid->Len != len))
+	{
+		DBGPRINT_ERR(("%s : The length is invalid\n", __FUNCTION__));
+		return NULL;
+	}
+
+	// Check WPA or WPA2
+	if (pEid->Eid == IE_WPA)
+	{
+		PRSNIE	pRsnie = (PRSNIE)pBuf;
+		UINT16 ucount;
+
+		if (len < sizeof(RSNIE))
+		{
+			DBGPRINT_ERR(("%s : The length is too short for WPA\n", __FUNCTION__));
+			return NULL;
+		}
+
+		// Get the count of pairwise cipher
+		ucount = cpu2le16(pRsnie->ucount);
+		if (ucount > 2)
+		{
+			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n",
+											__FUNCTION__, ucount));
+			return NULL;
+		}
+
+		// Get the group cipher
+		if (type == GROUP_SUITE)
+		{
+			*count = 1;
+			return pRsnie->mcast;
+		}
+		// Get the pairwise cipher suite
+		else if (type == PAIRWISE_SUITE)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
+										__FUNCTION__, ucount));
+			*count = ucount;
+			return pRsnie->ucast[0].oui;
+		}
+
+		offset = sizeof(RSNIE) + (4 * (ucount - 1));
+
+	}
+	else if (pEid->Eid == IE_RSN)
+	{
+		PRSNIE2	pRsnie = (PRSNIE2)pBuf;
+		UINT16 ucount;
+
+		isWPA2 = TRUE;
+
+		if (len < sizeof(RSNIE2))
+		{
+			DBGPRINT_ERR(("%s : The length is too short for WPA2\n", __FUNCTION__));
+			return NULL;
+		}
+
+		// Get the count of pairwise cipher
+		ucount = cpu2le16(pRsnie->ucount);
+		if (ucount > 2)
+		{
+			DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n",
+											__FUNCTION__, ucount));
+			return NULL;
+		}
+
+		// Get the group cipher
+		if (type == GROUP_SUITE)
+		{
+			*count = 1;
+			return pRsnie->mcast;
+		}
+		// Get the pairwise cipher suite
+		else if (type == PAIRWISE_SUITE)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n",
+										__FUNCTION__, ucount));
+			*count = ucount;
+			return pRsnie->ucast[0].oui;
+		}
+
+		offset = sizeof(RSNIE2) + (4 * (ucount - 1));
+
+	}
+	else
+	{
+		DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __FUNCTION__, pEid->Eid));
+		return NULL;
+	}
+
+	// skip group cipher and pairwise cipher suite
+	pBuf += offset;
+	len -= offset;
+
+	if (len < sizeof(RSNIE_AUTH))
+	{
+		DBGPRINT_ERR(("%s : The length of RSNIE is too short\n", __FUNCTION__));
+		return NULL;
+	}
+
+	// pointer to AKM count
+	pAkm = (PRSNIE_AUTH)pBuf;
+
+	// Get the count of pairwise cipher
+	acount = cpu2le16(pAkm->acount);
+	if (acount > 2)
+	{
+		DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n",
+										__FUNCTION__, acount));
+		return NULL;
+	}
+
+	// Get the AKM suite
+	if (type == AKM_SUITE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
+									__FUNCTION__, acount));
+		*count = acount;
+		return pAkm->auth[0].oui;
+	}
+	offset = sizeof(RSNIE_AUTH) + (4 * (acount - 1));
+
+	pBuf += offset;
+	len -= offset;
+
+	// The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~))
+	if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID))
+	{
+		// Skip RSN capability and PMKID-Count
+		pBuf += (sizeof(RSN_CAPABILITIES) + 2);
+		len -= (sizeof(RSN_CAPABILITIES) + 2);
+
+		// Get PMKID
+		if (type == PMKID_LIST)
+		{
+			*count = 1;
+			return pBuf;
+		}
+	}
+	else
+	{
+		DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __FUNCTION__));
+		return NULL;
+	}
+
+	*count = 0;
+	//DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __FUNCTION__, type));
+	return NULL;
+
+}
+
+VOID WpaShowAllsuite(
+	IN	PUINT8	rsnie,
+	IN	UINT	rsnie_len)
+{
+	PUINT8 pSuite = NULL;
+	UINT8 count;
+
+	hex_dump("RSNIE", rsnie, rsnie_len);
+
+	// group cipher
+	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count)) != NULL)
+	{
+		hex_dump("group cipher", pSuite, 4*count);
+	}
+
+	// pairwise cipher
+	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count)) != NULL)
+	{
+		hex_dump("pairwise cipher", pSuite, 4*count);
+	}
+
+	// AKM
+	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL)
+	{
+		hex_dump("AKM suite", pSuite, 4*count);
+	}
+
+	// PMKID
+	if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL)
+	{
+		hex_dump("PMKID", pSuite, LEN_PMKID);
+	}
+
+}
+
+VOID RTMPInsertRSNIE(
+	IN PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PUINT8 rsnie_ptr,
+	IN UINT8  rsnie_len,
+	IN PUINT8 pmkid_ptr,
+	IN UINT8  pmkid_len)
+{
+	PUCHAR	pTmpBuf;
+	ULONG	TempLen = 0;
+	UINT8	extra_len = 0;
+	UINT16	pmk_count = 0;
+	UCHAR	ie_num;
+	UINT8	total_len = 0;
+    UCHAR	WPA2_OUI[3]={0x00,0x0F,0xAC};
+
+	pTmpBuf = pFrameBuf;
+
+	/* PMKID-List Must larger than 0 and the multiple of 16. */
+	if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0))
+	{
+		extra_len = sizeof(UINT16) + pmkid_len;
+
+		pmk_count = (pmkid_len >> 4);
+		pmk_count = cpu2le16(pmk_count);
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_WARN, ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
+									__FUNCTION__, pmkid_len));
+	}
+
+	if (rsnie_len != 0)
+	{
+		ie_num = IE_WPA;
+		total_len = rsnie_len;
+
+		if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI)))
+		{
+			ie_num = IE_RSN;
+			total_len += extra_len;
+		}
+
+		/* construct RSNIE body */
+		MakeOutgoingFrame(pTmpBuf,			&TempLen,
+						  1,				&ie_num,
+						  1,				&total_len,
+						  rsnie_len,		rsnie_ptr,
+						  END_OF_ARGS);
+
+		pTmpBuf += TempLen;
+		*pFrameLen = *pFrameLen + TempLen;
+
+		if (ie_num == IE_RSN)
+		{
+			/* Insert PMKID-List field */
+			if (extra_len > 0)
+			{
+				MakeOutgoingFrame(pTmpBuf,					&TempLen,
+								  2,						&pmk_count,
+								  pmkid_len,				pmkid_ptr,
+								  END_OF_ARGS);
+
+				pTmpBuf += TempLen;
+				*pFrameLen = *pFrameLen + TempLen;
+			}
+		}
+	}
+
+	return;
+}
diff --git a/drivers/staging/rt3090/common/crypt_aes.c b/drivers/staging/rt3090/common/crypt_aes.c
new file mode 100644
index 0000000..f400f1e
--- /dev/null
+++ b/drivers/staging/rt3090/common/crypt_aes.c
@@ -0,0 +1,1007 @@
+/*
+ *************************************************************************
+ * 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:
+	crypt_aes.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+        Eddy        2009/01/19      Create AES-128, AES-192, AES-256, AES-CBC
+*/
+
+#include "crypt_aes.h"
+
+/* The value given by [x^(i-1),{00},{00},{00}], with x^(i-1) being powers of x in the field GF(2^8). */
+static const UINT32 aes_rcon[] = {
+	0x00000000, 0x01000000, 0x02000000, 0x04000000,
+    0x08000000, 0x10000000, 0x20000000, 0x40000000,
+    0x80000000, 0x1B000000, 0x36000000};
+
+static const UINT8 aes_sbox_enc[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7 ,0xab, 0x76, /* 0 */
+    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4 ,0x72, 0xc0, /* 1 */
+    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8 ,0x31, 0x15, /* 2 */
+    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27 ,0xb2, 0x75, /* 3 */
+    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3 ,0x2f, 0x84, /* 4 */
+    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c ,0x58, 0xcf, /* 5 */
+    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c ,0x9f, 0xa8, /* 6 */
+    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff ,0xf3, 0xd2, /* 7 */
+    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d ,0x19, 0x73, /* 8 */
+    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e ,0x0b, 0xdb, /* 9 */
+    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95 ,0xe4, 0x79, /* a */
+    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a ,0xae, 0x08, /* b */
+    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd ,0x8b, 0x8a, /* c */
+    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1 ,0x1d, 0x9e, /* d */
+    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55 ,0x28, 0xdf, /* e */
+    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54 ,0xbb, 0x16, /* f */
+};
+
+static const UINT8 aes_sbox_dec[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, /* 0 */
+    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, /* 1 */
+    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, /* 2 */
+    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, /* 3 */
+    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, /* 4 */
+    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, /* 5 */
+    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, /* 6 */
+    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, /* 7 */
+    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, /* 8 */
+    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, /* 9 */
+    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, /* a */
+    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, /* b */
+    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, /* c */
+    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, /* d */
+    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, /* e */
+    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, /* f */
+};
+
+/* ArrayIndex*{02} */
+static const UINT8 aes_mul_2[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, /* 0 */
+    0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, /* 1 */
+    0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, /* 2 */
+    0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, /* 3 */
+    0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, /* 4 */
+    0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 5 */
+    0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 6 */
+    0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, /* 7 */
+    0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, /* 8 */
+    0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, /* 9 */
+    0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, /* a */
+    0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, /* b */
+    0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, /* c */
+    0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, /* d */
+    0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, /* e */
+    0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, /* f */
+};
+
+/* ArrayIndex*{03} */
+static const UINT8 aes_mul_3[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, /* 0 */
+    0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, /* 1 */
+    0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, /* 2 */
+    0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, /* 3 */
+    0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, /* 4 */
+    0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, /* 5 */
+    0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, /* 6 */
+    0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, /* 7 */
+    0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, /* 8 */
+    0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, /* 9 */
+    0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, /* a */
+    0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, /* b */
+    0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, /* c */
+    0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, /* d */
+    0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, /* e */
+    0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, /* f */
+};
+
+/* ArrayIndex*{09} */
+static const UINT8 aes_mul_9[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, /* 0 */
+    0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, /* 1 */
+    0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, /* 2 */
+    0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, /* 3 */
+    0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, /* 4 */
+    0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, /* 5 */
+    0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, /* 6 */
+    0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, /* 7 */
+    0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, /* 8 */
+    0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, /* 9 */
+    0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, /* a */
+    0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, /* b */
+    0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, /* c */
+    0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, /* d */
+    0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, /* e */
+    0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, /* f */
+};
+
+/* ArrayIndex*{0b} */
+static const UINT8 aes_mul_b[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, /* 0 */
+    0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, /* 1 */
+    0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, /* 2 */
+    0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, /* 3 */
+    0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, /* 4 */
+    0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, /* 5 */
+    0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, /* 6 */
+    0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, /* 7 */
+    0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, /* 8 */
+    0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, /* 9 */
+    0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, /* a */
+    0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, /* b */
+    0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, /* c */
+    0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, /* d */
+    0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, /* e */
+    0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, /* f */
+};
+
+/* ArrayIndex*{0d} */
+static const UINT8 aes_mul_d[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, /* 0 */
+    0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, /* 1 */
+    0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, /* 2 */
+    0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, /* 3 */
+    0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, /* 4 */
+    0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, /* 5 */
+    0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, /* 6 */
+    0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, /* 7 */
+    0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, /* 8 */
+    0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, /* 9 */
+    0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, /* a */
+    0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, /* b */
+    0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, /* c */
+    0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, /* d */
+    0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, /* e */
+    0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, /* f */
+};
+
+/* ArrayIndex*{0e} */
+static const UINT8 aes_mul_e[] = {
+  /*  0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f    */
+    0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, /* 0 */
+    0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, /* 1 */
+    0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, /* 2 */
+    0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, /* 3 */
+    0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, /* 4 */
+    0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, /* 5 */
+    0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, /* 6 */
+    0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, /* 7 */
+    0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, /* 8 */
+    0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, /* 9 */
+    0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, /* a */
+    0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, /* b */
+    0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, /* c */
+    0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, /* d */
+    0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, /* e */
+    0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, /* f */
+};
+
+
+/* For AES_CMAC */
+#define AES_MAC_LENGTH 16 /* 128-bit string */
+static UINT8 Const_Zero[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static UINT8 Const_Rb[16] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
+
+
+/*
+========================================================================
+Routine Description:
+    AES key expansion (key schedule)
+
+Arguments:
+    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+    KeyLength        The length of cipher key in bytes
+    paes_ctx         Pointer to AES_CTX_STRUC
+
+Return Value:
+    paes_ctx         Retrun the KeyWordExpansion of AES_CTX_STRUC
+
+Note:
+    Pseudo code for key expansion
+    ------------------------------------------
+       Nk = (key length/4);
+
+       while (i < Nk)
+           KeyWordExpansion[i] = word(key[4*i], key[4*i + 1], key[4*i + 2], key[4*i + 3]);
+           i++;
+       end while
+
+       while (i < ((key length/4 + 6 + 1)*4) )
+           temp = KeyWordExpansion[i - 1];
+           if (i % Nk ==0)
+               temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk];
+           else if ((Nk > 6) && (i % 4 == 4))
+               temp = SubWord(temp);
+           end if
+
+           KeyWordExpansion[i] = KeyWordExpansion[i - Nk]^ temp;
+           i++;
+       end while
+========================================================================
+*/
+VOID AES_KeyExpansion (
+    IN UINT8 Key[],
+    IN UINT KeyLength,
+    INOUT AES_CTX_STRUC *paes_ctx)
+{
+    UINT KeyIndex = 0;
+    UINT NumberOfWordOfKey, NumberOfWordOfKeyExpansion;
+    UINT8  TempWord[AES_KEY_ROWS], Temp;
+    UINT32 Temprcon;
+
+    NumberOfWordOfKey = KeyLength >> 2;
+    while (KeyIndex < NumberOfWordOfKey)
+    {
+        paes_ctx->KeyWordExpansion[0][KeyIndex] = Key[4*KeyIndex];
+        paes_ctx->KeyWordExpansion[1][KeyIndex] = Key[4*KeyIndex + 1];
+        paes_ctx->KeyWordExpansion[2][KeyIndex] = Key[4*KeyIndex + 2];
+        paes_ctx->KeyWordExpansion[3][KeyIndex] = Key[4*KeyIndex + 3];
+        KeyIndex++;
+    } /* End of while */
+
+    NumberOfWordOfKeyExpansion = ((UINT) AES_KEY_ROWS) * ((KeyLength >> 2) + 6 + 1);
+    while (KeyIndex < NumberOfWordOfKeyExpansion)
+    {
+        TempWord[0] = paes_ctx->KeyWordExpansion[0][KeyIndex - 1];
+        TempWord[1] = paes_ctx->KeyWordExpansion[1][KeyIndex - 1];
+        TempWord[2] = paes_ctx->KeyWordExpansion[2][KeyIndex - 1];
+        TempWord[3] = paes_ctx->KeyWordExpansion[3][KeyIndex - 1];
+        if ((KeyIndex % NumberOfWordOfKey) == 0) {
+            Temprcon = aes_rcon[KeyIndex/NumberOfWordOfKey];
+            Temp = aes_sbox_enc[TempWord[1]]^((Temprcon >> 24) & 0xff);
+            TempWord[1] = aes_sbox_enc[TempWord[2]]^((Temprcon >> 16) & 0xff);
+            TempWord[2] = aes_sbox_enc[TempWord[3]]^((Temprcon >>  8) & 0xff);
+            TempWord[3] = aes_sbox_enc[TempWord[0]]^((Temprcon      ) & 0xff);
+            TempWord[0] = Temp;
+        } else if ((NumberOfWordOfKey > 6) && ((KeyIndex % NumberOfWordOfKey) == 4)) {
+            Temp = aes_sbox_enc[TempWord[0]];
+            TempWord[1] = aes_sbox_enc[TempWord[1]];
+            TempWord[2] = aes_sbox_enc[TempWord[2]];
+            TempWord[3] = aes_sbox_enc[TempWord[3]];
+            TempWord[0] = Temp;
+        }
+        paes_ctx->KeyWordExpansion[0][KeyIndex] = paes_ctx->KeyWordExpansion[0][KeyIndex - NumberOfWordOfKey]^TempWord[0];
+        paes_ctx->KeyWordExpansion[1][KeyIndex] = paes_ctx->KeyWordExpansion[1][KeyIndex - NumberOfWordOfKey]^TempWord[1];
+        paes_ctx->KeyWordExpansion[2][KeyIndex] = paes_ctx->KeyWordExpansion[2][KeyIndex - NumberOfWordOfKey]^TempWord[2];
+        paes_ctx->KeyWordExpansion[3][KeyIndex] = paes_ctx->KeyWordExpansion[3][KeyIndex - NumberOfWordOfKey]^TempWord[3];
+        KeyIndex++;
+    } /* End of while */
+} /* End of AES_KeyExpansion */
+
+
+/*
+========================================================================
+Routine Description:
+    AES encryption
+
+Arguments:
+    PlainBlock       The block of plain text, 16 bytes(128 bits) each block
+    PlainBlockSize   The length of block of plain text in bytes
+    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+    KeyLength        The length of cipher key in bytes
+    CipherBlockSize  The length of allocated cipher block in bytes
+
+Return Value:
+    CipherBlock      Return cipher text
+    CipherBlockSize  Return the length of real used cipher block in bytes
+
+Note:
+    Reference to FIPS-PUB 197
+    1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
+    2. Transfer the plain block to state block
+    3. Main encryption rounds
+    4. Transfer the state block to cipher block
+    ------------------------------------------
+       NumberOfRound = (key length / 4) + 6;
+       state block = plain block;
+
+       AddRoundKey(state block, key);
+       for round = 1 to NumberOfRound
+           SubBytes(state block)
+           ShiftRows(state block)
+           MixColumns(state block)
+           AddRoundKey(state block, key);
+       end for
+
+       SubBytes(state block)
+       ShiftRows(state block)
+       AddRoundKey(state block, key);
+
+       cipher block = state block;
+========================================================================
+*/
+VOID AES_Encrypt (
+    IN UINT8 PlainBlock[],
+    IN UINT PlainBlockSize,
+    IN UINT8 Key[],
+    IN UINT KeyLength,
+    OUT UINT8 CipherBlock[],
+    INOUT UINT *CipherBlockSize)
+{
+    AES_CTX_STRUC aes_ctx;
+    UINT RowIndex, ColumnIndex;
+    UINT RoundIndex, NumberOfRound = 0;
+    UINT8 Temp, Row0, Row1, Row2, Row3;
+
+    /*
+     * 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
+     */
+    if (PlainBlockSize != AES_BLOCK_SIZES) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
+            PlainBlockSize, AES_BLOCK_SIZES));
+        return;
+    } /* End of if */
+    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+        return;
+    } /* End of if */
+    if (*CipherBlockSize < AES_BLOCK_SIZES) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
+            *CipherBlockSize, AES_BLOCK_SIZES));
+        return;
+    } /* End of if */
+
+    /*
+     * 2. Transfer the plain block to state block
+     */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] = PlainBlock[RowIndex + 4*ColumnIndex];
+
+    /*
+     *  3. Main encryption rounds
+     */
+    AES_KeyExpansion(Key, KeyLength, &aes_ctx);
+    NumberOfRound = (KeyLength >> 2) + 6;
+
+    /* AES_AddRoundKey */
+    RoundIndex = 0;
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
+
+    for (RoundIndex = 1; RoundIndex < NumberOfRound;RoundIndex++)
+    {
+        /* AES_SubBytes */
+        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+                aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
+
+        /* AES_ShiftRows */
+        Temp = aes_ctx.State[1][0];
+        aes_ctx.State[1][0] = aes_ctx.State[1][1];
+        aes_ctx.State[1][1] = aes_ctx.State[1][2];
+        aes_ctx.State[1][2] = aes_ctx.State[1][3];
+        aes_ctx.State[1][3] = Temp;
+        Temp = aes_ctx.State[2][0];
+        aes_ctx.State[2][0] = aes_ctx.State[2][2];
+        aes_ctx.State[2][2] = Temp;
+        Temp = aes_ctx.State[2][1];
+        aes_ctx.State[2][1] = aes_ctx.State[2][3];
+        aes_ctx.State[2][3] = Temp;
+        Temp = aes_ctx.State[3][3];
+        aes_ctx.State[3][3] = aes_ctx.State[3][2];
+        aes_ctx.State[3][2] = aes_ctx.State[3][1];
+        aes_ctx.State[3][1] = aes_ctx.State[3][0];
+        aes_ctx.State[3][0] = Temp;
+
+        /* AES_MixColumns */
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+        {
+            Row0 = aes_ctx.State[0][ColumnIndex];
+            Row1 = aes_ctx.State[1][ColumnIndex];
+            Row2 = aes_ctx.State[2][ColumnIndex];
+            Row3 = aes_ctx.State[3][ColumnIndex];
+            aes_ctx.State[0][ColumnIndex] = aes_mul_2[Row0]^aes_mul_3[Row1]^Row2^Row3;
+            aes_ctx.State[1][ColumnIndex] = Row0^aes_mul_2[Row1]^aes_mul_3[Row2]^Row3;
+            aes_ctx.State[2][ColumnIndex] = Row0^Row1^aes_mul_2[Row2]^aes_mul_3[Row3];
+            aes_ctx.State[3][ColumnIndex] = aes_mul_3[Row0]^Row1^Row2^aes_mul_2[Row3];
+        }
+
+        /* AES_AddRoundKey */
+        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+                aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
+    } /* End of for */
+
+    /* AES_SubBytes */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
+    /* AES_ShiftRows */
+    Temp = aes_ctx.State[1][0];
+    aes_ctx.State[1][0] = aes_ctx.State[1][1];
+    aes_ctx.State[1][1] = aes_ctx.State[1][2];
+    aes_ctx.State[1][2] = aes_ctx.State[1][3];
+    aes_ctx.State[1][3] = Temp;
+    Temp = aes_ctx.State[2][0];
+    aes_ctx.State[2][0] = aes_ctx.State[2][2];
+    aes_ctx.State[2][2] = Temp;
+    Temp = aes_ctx.State[2][1];
+    aes_ctx.State[2][1] = aes_ctx.State[2][3];
+    aes_ctx.State[2][3] = Temp;
+    Temp = aes_ctx.State[3][3];
+    aes_ctx.State[3][3] = aes_ctx.State[3][2];
+    aes_ctx.State[3][2] = aes_ctx.State[3][1];
+    aes_ctx.State[3][1] = aes_ctx.State[3][0];
+    aes_ctx.State[3][0] = Temp;
+    /* AES_AddRoundKey */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
+
+    /*
+     * 4. Transfer the state block to cipher block
+     */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            CipherBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
+
+    *CipherBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
+} /* End of AES_Encrypt */
+
+
+/*
+========================================================================
+Routine Description:
+    AES decryption
+
+Arguments:
+    CipherBlock      The block of cipher text, 16 bytes(128 bits) each block
+    CipherBlockSize  The length of block of cipher text in bytes
+    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+    KeyLength        The length of cipher key in bytes
+    PlainBlockSize   The length of allocated plain block in bytes
+
+Return Value:
+    PlainBlock       Return plain text
+    PlainBlockSize  Return the length of real used plain block in bytes
+
+Note:
+    Reference to FIPS-PUB 197
+    1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
+    2. Transfer the cipher block to state block
+    3. Main decryption rounds
+    4. Transfer the state block to plain block
+    ------------------------------------------
+       NumberOfRound = (key length / 4) + 6;
+       state block = cipher block;
+
+       AddRoundKey(state block, key);
+       for round = NumberOfRound to 1
+           InvSubBytes(state block)
+           InvShiftRows(state block)
+           InvMixColumns(state block)
+           AddRoundKey(state block, key);
+       end for
+
+       InvSubBytes(state block)
+       InvShiftRows(state block)
+       AddRoundKey(state block, key);
+
+       plain block = state block;
+========================================================================
+*/
+VOID AES_Decrypt (
+    IN UINT8 CipherBlock[],
+    IN UINT CipherBlockSize,
+    IN UINT8 Key[],
+    IN UINT KeyLength,
+    OUT UINT8 PlainBlock[],
+    INOUT UINT *PlainBlockSize)
+{
+    AES_CTX_STRUC aes_ctx;
+    UINT RowIndex, ColumnIndex;
+    UINT RoundIndex, NumberOfRound = 0;
+    UINT8 Temp, Row0, Row1, Row2, Row3;
+
+    /*
+     * 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
+     */
+    if (*PlainBlockSize < AES_BLOCK_SIZES) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
+            *PlainBlockSize, AES_BLOCK_SIZES));
+        return;
+    } /* End of if */
+    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+        return;
+    } /* End of if */
+    if (CipherBlockSize != AES_BLOCK_SIZES) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
+            CipherBlockSize, AES_BLOCK_SIZES));
+        return;
+    } /* End of if */
+
+    /*
+     * 2. Transfer the cipher block to state block
+     */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] = CipherBlock[RowIndex + 4*ColumnIndex];
+
+    /*
+     *  3. Main decryption rounds
+     */
+    AES_KeyExpansion(Key, KeyLength, &aes_ctx);
+    NumberOfRound = (KeyLength >> 2) + 6;
+
+    /* AES_AddRoundKey */
+    RoundIndex = NumberOfRound;
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
+
+    for (RoundIndex = (NumberOfRound - 1); RoundIndex > 0 ;RoundIndex--)
+    {
+        /* AES_InvShiftRows */
+        Temp = aes_ctx.State[1][3];
+        aes_ctx.State[1][3] = aes_ctx.State[1][2];
+        aes_ctx.State[1][2] = aes_ctx.State[1][1];
+        aes_ctx.State[1][1] = aes_ctx.State[1][0];
+        aes_ctx.State[1][0] = Temp;
+        Temp = aes_ctx.State[2][0];
+        aes_ctx.State[2][0] = aes_ctx.State[2][2];
+        aes_ctx.State[2][2] = Temp;
+        Temp = aes_ctx.State[2][1];
+        aes_ctx.State[2][1] = aes_ctx.State[2][3];
+        aes_ctx.State[2][3] = Temp;
+        Temp = aes_ctx.State[3][0];
+        aes_ctx.State[3][0] = aes_ctx.State[3][1];
+        aes_ctx.State[3][1] = aes_ctx.State[3][2];
+        aes_ctx.State[3][2] = aes_ctx.State[3][3];
+        aes_ctx.State[3][3] = Temp;
+
+        /* AES_InvSubBytes */
+        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+                aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
+
+        /* AES_AddRoundKey */
+        for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+            for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+                aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
+
+        /* AES_InvMixColumns */
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+        {
+            Row0 = aes_ctx.State[0][ColumnIndex];
+            Row1 = aes_ctx.State[1][ColumnIndex];
+            Row2 = aes_ctx.State[2][ColumnIndex];
+            Row3 = aes_ctx.State[3][ColumnIndex];
+            aes_ctx.State[0][ColumnIndex] = aes_mul_e[Row0]^aes_mul_b[Row1]^aes_mul_d[Row2]^aes_mul_9[Row3];
+            aes_ctx.State[1][ColumnIndex] = aes_mul_9[Row0]^aes_mul_e[Row1]^aes_mul_b[Row2]^aes_mul_d[Row3];
+            aes_ctx.State[2][ColumnIndex] = aes_mul_d[Row0]^aes_mul_9[Row1]^aes_mul_e[Row2]^aes_mul_b[Row3];
+            aes_ctx.State[3][ColumnIndex] = aes_mul_b[Row0]^aes_mul_d[Row1]^aes_mul_9[Row2]^aes_mul_e[Row3];
+        }
+    } /* End of for */
+
+    /* AES_InvShiftRows */
+    Temp = aes_ctx.State[1][3];
+    aes_ctx.State[1][3] = aes_ctx.State[1][2];
+    aes_ctx.State[1][2] = aes_ctx.State[1][1];
+    aes_ctx.State[1][1] = aes_ctx.State[1][0];
+    aes_ctx.State[1][0] = Temp;
+    Temp = aes_ctx.State[2][0];
+    aes_ctx.State[2][0] = aes_ctx.State[2][2];
+    aes_ctx.State[2][2] = Temp;
+    Temp = aes_ctx.State[2][1];
+    aes_ctx.State[2][1] = aes_ctx.State[2][3];
+    aes_ctx.State[2][3] = Temp;
+    Temp = aes_ctx.State[3][0];
+    aes_ctx.State[3][0] = aes_ctx.State[3][1];
+    aes_ctx.State[3][1] = aes_ctx.State[3][2];
+    aes_ctx.State[3][2] = aes_ctx.State[3][3];
+    aes_ctx.State[3][3] = Temp;
+    /* AES_InvSubBytes */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
+    /* AES_AddRoundKey */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
+
+    /*
+     * 4. Transfer the state block to plain block
+     */
+    for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
+        for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
+            PlainBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
+
+    *PlainBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
+} /* End of AES_Decrypt */
+
+
+/*
+========================================================================
+Routine Description:
+    AES-CBC encryption
+
+Arguments:
+    PlainText        Plain text
+    PlainTextLength  The length of plain text in bytes
+    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+    KeyLength        The length of cipher key in bytes
+    IV               Initialization vector, it may be 16 bytes (128 bits)
+    IVLength         The length of initialization vector in bytes
+    CipherTextLength The length of allocated cipher text in bytes
+
+Return Value:
+    CipherText       Return cipher text
+    CipherTextLength Return the length of real used cipher text in bytes
+
+Note:
+    Reference to RFC 3602 and NIST 800-38A
+========================================================================
+*/
+VOID AES_CBC_Encrypt (
+    IN UINT8 PlainText[],
+    IN UINT PlainTextLength,
+    IN UINT8 Key[],
+    IN UINT KeyLength,
+    IN UINT8 IV[],
+    IN UINT IVLength,
+    OUT UINT8 CipherText[],
+    INOUT UINT *CipherTextLength)
+{
+    UINT PaddingSize, PlainBlockStart, CipherBlockStart, CipherBlockSize;
+    UINT Index;
+    UINT8 Block[AES_BLOCK_SIZES];
+
+    /*
+     * 1. Check the input parameters
+     *    - CipherTextLength > (PlainTextLength + Padding size), Padding size = block size - (PlainTextLength % block size)
+     *    - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
+     *    - IV length must be 16 bytes(128 bits)
+     */
+    PaddingSize = ((UINT) AES_BLOCK_SIZES) - (PlainTextLength % ((UINT)AES_BLOCK_SIZES));
+    if (*CipherTextLength < (PlainTextLength + PaddingSize)) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: cipher text length is %d bytes < (plain text length %d bytes + padding size %d bytes).\n",
+            *CipherTextLength, PlainTextLength, PaddingSize));
+        return;
+    } /* End of if */
+    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+        return;
+    } /* End of if */
+    if (IVLength != AES_CBC_IV_LENGTH) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
+            IVLength, AES_CBC_IV_LENGTH));
+        return;
+    } /* End of if */
+
+
+    /*
+     * 2. Main algorithm
+     *    - Plain text divide into serveral blocks (16 bytes/block)
+     *    - If plain text is divided with no remainder by block, add a new block and padding size = block(16 bytes)
+     *    - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
+     *    - Execute AES_Encrypt procedure.
+     *
+     *    - Padding method: The remainder bytes will be filled with padding size (1 byte)
+     */
+    PlainBlockStart = 0;
+    CipherBlockStart = 0;
+    while ((PlainTextLength - PlainBlockStart) >= AES_BLOCK_SIZES)
+    {
+        if (CipherBlockStart == 0) {
+            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+                Block[Index] = PlainText[PlainBlockStart + Index]^IV[Index];
+        } else {
+            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+                Block[Index] = PlainText[PlainBlockStart + Index]^CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
+        } /* End of if */
+
+        CipherBlockSize = *CipherTextLength - CipherBlockStart;
+        AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
+
+        PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
+        CipherBlockStart += CipherBlockSize;
+    } /* End of while */
+
+    NdisMoveMemory(Block, (&PlainText[0] + PlainBlockStart), (PlainTextLength - PlainBlockStart));
+    NdisFillMemory((Block + (((UINT) AES_BLOCK_SIZES) -PaddingSize)), PaddingSize, (UINT8) PaddingSize);
+    if (CipherBlockStart == 0) {
+       for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+           Block[Index] ^= IV[Index];
+    } else {
+       for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+           Block[Index] ^= CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
+    } /* End of if */
+    CipherBlockSize = *CipherTextLength - CipherBlockStart;
+    AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
+    CipherBlockStart += CipherBlockSize;
+    *CipherTextLength = CipherBlockStart;
+} /* End of AES_CBC_Encrypt */
+
+
+/*
+========================================================================
+Routine Description:
+    AES-CBC decryption
+
+Arguments:
+    CipherText       Cipher text
+    CipherTextLength The length of cipher text in bytes
+    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+    KeyLength        The length of cipher key in bytes
+    IV               Initialization vector, it may be 16 bytes (128 bits)
+    IVLength         The length of initialization vector in bytes
+    PlainTextLength  The length of allocated plain text in bytes
+
+Return Value:
+    PlainText        Return plain text
+    PlainTextLength  Return the length of real used plain text in bytes
+
+Note:
+    Reference to RFC 3602 and NIST 800-38A
+========================================================================
+*/
+VOID AES_CBC_Decrypt (
+    IN UINT8 CipherText[],
+    IN UINT CipherTextLength,
+    IN UINT8 Key[],
+    IN UINT KeyLength,
+    IN UINT8 IV[],
+    IN UINT IVLength,
+    OUT UINT8 PlainText[],
+    INOUT UINT *PlainTextLength)
+{
+    UINT PaddingSize, PlainBlockStart, CipherBlockStart, PlainBlockSize;
+    UINT Index;
+
+    /*
+     * 1. Check the input parameters
+     *    - CipherTextLength must be divided with no remainder by block
+     *    - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
+     *    - IV length must be 16 bytes(128 bits)
+     */
+    if ((CipherTextLength % AES_BLOCK_SIZES) != 0) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: cipher text length is %d bytes, it can't be divided with no remainder by block size(%d).\n",
+            CipherTextLength, AES_BLOCK_SIZES));
+        return;
+    } /* End of if */
+    if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
+            KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
+        return;
+    } /* End of if */
+    if (IVLength != AES_CBC_IV_LENGTH) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
+            IVLength, AES_CBC_IV_LENGTH));
+        return;
+    } /* End of if */
+
+
+    /*
+     * 2. Main algorithm
+     *    - Cypher text divide into serveral blocks (16 bytes/block)
+     *    - Execute AES_Decrypt procedure.
+     *    - Remove padding bytes, padding size is the last byte of plain text
+     */
+    CipherBlockStart = 0;
+    PlainBlockStart = 0;
+    while ((CipherTextLength - CipherBlockStart) >= AES_BLOCK_SIZES)
+    {
+        PlainBlockSize = *PlainTextLength - PlainBlockStart;
+        AES_Decrypt(CipherText + CipherBlockStart, AES_BLOCK_SIZES , Key, KeyLength, PlainText + PlainBlockStart, &PlainBlockSize);
+
+        if (PlainBlockStart == 0) {
+            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+                PlainText[PlainBlockStart + Index] ^= IV[Index];
+        } else {
+            for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+                PlainText[PlainBlockStart + Index] ^= CipherText[CipherBlockStart + Index - ((UINT) AES_BLOCK_SIZES)];
+        } /* End of if */
+
+        CipherBlockStart += AES_BLOCK_SIZES;
+        PlainBlockStart += PlainBlockSize;
+    } /* End of while */
+
+    PaddingSize = (UINT8) PlainText[PlainBlockStart -1];
+    *PlainTextLength = PlainBlockStart - PaddingSize;
+
+} /* End of AES_CBC_Encrypt */
+
+
+
+/*
+========================================================================
+Routine Description:
+    AES-CMAC generate subkey
+
+Arguments:
+    Key        Cipher key 128 bits
+    KeyLength  The length of Cipher key in bytes
+
+Return Value:
+    SubKey1    SubKey 1 128 bits
+    SubKey2    SubKey 2 128 bits
+
+Note:
+    Reference to RFC 4493
+
+    Step 1.  L := AES-128(K, const_Zero);
+    Step 2.  if MSB(L) is equal to 0
+                then    K1 := L << 1;
+                else    K1 := (L << 1) XOR const_Rb;
+    Step 3.  if MSB(K1) is equal to 0
+                then    K2 := K1 << 1;
+                else    K2 := (K1 << 1) XOR const_Rb;
+    Step 4.  return K1, K2;
+========================================================================
+*/
+VOID AES_CMAC_GenerateSubKey (
+    IN UINT8 Key[],
+    IN UINT KeyLength,
+    OUT UINT8 SubKey1[],
+    OUT UINT8 SubKey2[])
+{
+    UINT8 MSB_L = 0, MSB_K1 = 0, Top_Bit = 0;
+    UINT  SubKey1_Length = 0;
+    INT   Index = 0;
+
+    if (KeyLength != AES_KEY128_LENGTH) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC_GenerateSubKey: key length is %d bytes, it must be %d bytes(128 bits).\n",
+            KeyLength, AES_KEY128_LENGTH));
+        return;
+    } /* End of if */
+
+    /* Step 1: L := AES-128(K, const_Zero); */
+    SubKey1_Length = 16;
+    AES_Encrypt(Const_Zero, sizeof(Const_Zero), Key, KeyLength, SubKey1, &SubKey1_Length);
+
+    /*
+     * Step 2.  if MSB(L) is equal to 0
+     *           then    K1 := L << 1;
+     *           else    K1 := (L << 1) XOR const_Rb;
+     */
+    MSB_L = SubKey1[0] & 0x80;
+    for(Index = 0; Index < 15; Index++) {
+        Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
+        SubKey1[Index] <<= 1;
+        SubKey1[Index] |= Top_Bit;
+    }
+    SubKey1[15] <<= 1;
+    if (MSB_L > 0) {
+        for(Index = 0; Index < 16; Index++)
+            SubKey1[Index] ^= Const_Rb[Index];
+    } /* End of if */
+
+    /*
+     * Step 3.  if MSB(K1) is equal to 0
+     *           then    K2 := K1 << 1;
+     *           else    K2 := (K1 << 1) XOR const_Rb;
+     */
+    MSB_K1 = SubKey1[0] & 0x80;
+    for(Index = 0; Index < 15; Index++) {
+        Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
+        SubKey2[Index] = SubKey1[Index] << 1;
+        SubKey2[Index] |= Top_Bit;
+    }
+    SubKey2[15] = SubKey1[15] << 1;
+    if (MSB_K1 > 0) {
+        for(Index = 0; Index < 16; Index++)
+            SubKey2[Index] ^= Const_Rb[Index];
+    } /* End of if */
+} /* End of AES_CMAC_GenerateSubKey */
+
+
+/*
+========================================================================
+Routine Description:
+    AES-CMAC
+
+Arguments:
+    PlainText        Plain text
+    PlainTextLength  The length of plain text in bytes
+    Key              Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
+    KeyLength        The length of cipher key in bytes
+    MACTextLength    The length of allocated memory spaces in bytes
+
+Return Value:
+    MACText       Message authentication code (128-bit string)
+    MACTextLength Return the length of Message authentication code in bytes
+
+Note:
+    Reference to RFC 4493
+========================================================================
+*/
+VOID AES_CMAC (
+    IN UINT8 PlainText[],
+    IN UINT PlainTextLength,
+    IN UINT8 Key[],
+    IN UINT KeyLength,
+    OUT UINT8 MACText[],
+    INOUT UINT *MACTextLength)
+{
+    UINT  PlainBlockStart;
+    UINT8 X[AES_BLOCK_SIZES], Y[AES_BLOCK_SIZES];
+    UINT8 SubKey1[16];
+    UINT8 SubKey2[16];
+    INT X_Length, Index;
+
+    if (*MACTextLength < AES_MAC_LENGTH) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: MAC text length is less than %d bytes).\n",
+            AES_MAC_LENGTH));
+        return;
+    } /* End of if */
+    if (KeyLength != AES_KEY128_LENGTH) {
+	DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: key length is %d bytes, it must be %d bytes(128 bits).\n",
+            KeyLength, AES_KEY128_LENGTH));
+        return;
+    } /* End of if */
+
+    /* Step 1.  (K1,K2) := Generate_Subkey(K); */
+    NdisZeroMemory(SubKey1, 16);
+    NdisZeroMemory(SubKey2, 16);
+    AES_CMAC_GenerateSubKey(Key, KeyLength, SubKey1, SubKey2);
+
+    /*
+     * 2. Main algorithm
+     *    - Plain text divide into serveral blocks (16 bytes/block)
+     *    - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
+     *    - Execute AES_Encrypt procedure.
+     */
+    PlainBlockStart = 0;
+    NdisMoveMemory(X, Const_Zero, AES_BLOCK_SIZES);
+    while ((PlainTextLength - PlainBlockStart) > AES_BLOCK_SIZES)
+    {
+        for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+                Y[Index] = PlainText[PlainBlockStart + Index]^X[Index];
+
+        X_Length = sizeof(X);
+        AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, X, &X_Length);
+        PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
+    } /* End of while */
+    if ((PlainTextLength - PlainBlockStart) == AES_BLOCK_SIZES) {
+        for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+                Y[Index] = PlainText[PlainBlockStart + Index]^X[Index]^SubKey1[Index];
+    } else {
+        NdisZeroMemory(Y, AES_BLOCK_SIZES);
+        NdisMoveMemory(Y, &PlainText[PlainBlockStart], (PlainTextLength - PlainBlockStart));
+        Y[(PlainTextLength - PlainBlockStart)] = 0x80;
+        for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
+                Y[Index] = Y[Index]^X[Index]^SubKey2[Index];
+    } /* End of if */
+    AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, MACText, MACTextLength);
+} /* End of AES_CMAC */
diff --git a/drivers/staging/rt3090/common/crypt_biginteger.c b/drivers/staging/rt3090/common/crypt_biginteger.c
new file mode 100644
index 0000000..b346c5f
--- /dev/null
+++ b/drivers/staging/rt3090/common/crypt_biginteger.c
@@ -0,0 +1,1119 @@
+/*
+ *************************************************************************
+ * 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:
+	cmm_profile.c
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#include "crypt_biginteger.h"
+
+#ifdef __KERNEL__
+#define DEBUGPRINT(fmt, args...) printk(KERN_ERR fmt, ## args)
+#else
+#define DEBUGPRINT(fmt, args...) printf(fmt, ## args)
+#endif /* __KERNEL__ */
+
+#define UINT32_HBITS(value)	(((value) >> 0x10) & 0xffff)
+#define UINT32_LBITS(value)	((value) & 0xffff)
+#define UINT32_GETBYTE(value, index)	(((value) >> ((index)*8)) & 0xff)
+#define UINT64_HBITS(value)	(((value) >> 0x20) & 0xffffffff)
+#define UINT64_LBITS(value)	((value) & 0xffffffff)
+
+static UINT8 WPS_DH_P_VALUE[192] =
+{
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+    0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+    0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+    0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+    0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+    0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+    0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+    0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+    0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+    0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+    0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+    0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+    0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+    0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+    0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+static UINT8 WPS_DH_R_VALUE[193] =
+{
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00,
+};
+
+static UINT8 WPS_DH_X_VALUE[184] =
+{
+    0x36, 0xf0, 0x25, 0x5d, 0xde, 0x97, 0x3d, 0xcb,
+    0x3b, 0x39, 0x9d, 0x74, 0x7f, 0x23, 0xe3, 0x2e,
+    0xd6, 0xfd, 0xb1, 0xf7, 0x75, 0x98, 0x33, 0x8b,
+    0xfd, 0xf4, 0x41, 0x59, 0xc4, 0xec, 0x64, 0xdd,
+    0xae, 0xb5, 0xf7, 0x86, 0x71, 0xcb, 0xfb, 0x22,
+    0x10, 0x6a, 0xe6, 0x4c, 0x32, 0xc5, 0xbc, 0xe4,
+    0xcf, 0xd4, 0xf5, 0x92, 0x0d, 0xa0, 0xeb, 0xc8,
+    0xb0, 0x1e, 0xca, 0x92, 0x92, 0xae, 0x3d, 0xba,
+    0x1b, 0x7a, 0x4a, 0x89, 0x9d, 0xa1, 0x81, 0x39,
+    0x0b, 0xb3, 0xbd, 0x16, 0x59, 0xc8, 0x12, 0x94,
+    0xf4, 0x00, 0xa3, 0x49, 0x0b, 0xf9, 0x48, 0x12,
+    0x11, 0xc7, 0x94, 0x04, 0xa5, 0x76, 0x60, 0x5a,
+    0x51, 0x60, 0xdb, 0xee, 0x83, 0xb4, 0xe0, 0x19,
+    0xb6, 0xd7, 0x99, 0xae, 0x13, 0x1b, 0xa4, 0xc2,
+    0x3d, 0xff, 0x83, 0x47, 0x5e, 0x9c, 0x40, 0xfa,
+    0x67, 0x25, 0xb7, 0xc9, 0xe3, 0xaa, 0x2c, 0x65,
+    0x96, 0xe9, 0xc0, 0x57, 0x02, 0xdb, 0x30, 0xa0,
+    0x7c, 0x9a, 0xa2, 0xdc, 0x23, 0x5c, 0x52, 0x69,
+    0xe3, 0x9d, 0x0c, 0xa9, 0xdf, 0x7a, 0xad, 0x44,
+    0x61, 0x2a, 0xd6, 0xf8, 0x8f, 0x69, 0x69, 0x92,
+    0x98, 0xf3, 0xca, 0xb1, 0xb5, 0x43, 0x67, 0xfb,
+    0x0e, 0x8b, 0x93, 0xf7, 0x35, 0xdc, 0x8c, 0xd8,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+};
+
+static UINT8 WPS_DH_RRModP_VALUE[192] =
+{
+	0xe3, 0xb3, 0x3c, 0x72, 0x59, 0x54, 0x1c, 0x01,
+	0xee, 0x9c, 0x9a, 0x21, 0x6c, 0xc1, 0xeb, 0xd2,
+	0xae, 0x59, 0x41, 0x04, 0x79, 0x29, 0xa1, 0xc7,
+	0xe9, 0xc3, 0xfa, 0x02, 0xcc, 0x24, 0x56, 0xef,
+	0x10, 0x26, 0x30, 0xfa, 0x9a, 0x36, 0xa5, 0x1f,
+	0x57, 0xb5, 0x93, 0x48, 0x67, 0x98, 0x44, 0x60,
+	0x0b, 0xe4, 0x96, 0x47, 0xa8, 0x7c, 0x7b, 0x37,
+	0xf8, 0x05, 0x65, 0x64, 0x96, 0x9b, 0x7f, 0x02,
+	0xdc, 0x54, 0x1a, 0x4e, 0xd4, 0x05, 0x3f, 0x54,
+	0xd6, 0x2a, 0x0e, 0xea, 0xb2, 0x70, 0x52, 0x1b,
+	0x22, 0xc2, 0x96, 0xe9, 0xd4, 0x6f, 0xec, 0x23,
+	0x8e, 0x1a, 0xbd, 0x78, 0x02, 0x23, 0xb7, 0x6b,
+	0xb8, 0xfe, 0x61, 0x21, 0x19, 0x6b, 0x7e, 0x88,
+	0x1c, 0x72, 0x9c, 0x7e, 0x04, 0xb9, 0xf7, 0x96,
+	0x07, 0xcd, 0x0a, 0x62, 0x8e, 0x43, 0x41, 0x30,
+	0x04, 0xa5, 0x41, 0xff, 0x93, 0xae, 0x1c, 0xeb,
+	0xb0, 0x04, 0xa7, 0x50, 0xdb, 0x10, 0x2d, 0x39,
+	0xb9, 0x05, 0x2b, 0xb4, 0x7a, 0x58, 0xf1, 0x70,
+	0x7e, 0x8c, 0xd2, 0xac, 0x98, 0xb5, 0xfb, 0x62,
+	0x8f, 0x23, 0x31, 0xb1, 0x3b, 0x01, 0xe0, 0x18,
+	0xf4, 0x66, 0xee, 0x5f, 0xbc, 0xd4, 0x9d, 0x68,
+	0xd0, 0xab, 0x92, 0xe1, 0x83, 0x97, 0xf2, 0x45,
+	0x8e, 0x0e, 0x3e, 0x21, 0x67, 0x47, 0x8c, 0x73,
+	0xf1, 0x15, 0xd2, 0x7d, 0x32, 0xc6, 0x95, 0xe0,
+};
+
+static UINT8 Value_0[1] = {0x00};
+static UINT8 Value_1[1] = {0x01};
+static PBIG_INTEGER pBI_U = NULL, pBI_S = NULL, pBI_O = NULL;
+static UINT Bits_Of_R = 0;
+
+
+VOID BigInteger_Print (
+    IN PBIG_INTEGER pBI)
+{
+    int i = 0, j = 0;
+
+    if ((pBI == NULL) || (pBI->pIntegerArray == NULL))
+        return;
+
+    if (strlen(pBI->Name) != 0)
+        DEBUGPRINT("Name=%s\n", pBI->Name);
+    DEBUGPRINT("AllocSize=%d, ArrayLength=%d, IntegerLength=%d, Signed=%d\n", pBI->AllocSize, pBI->ArrayLength, pBI->IntegerLength, pBI->Signed);
+    for (i = (pBI->ArrayLength - 1), j = 0;i >=0;i--,j++) {
+        DEBUGPRINT("%08x, ", pBI->pIntegerArray[i]);
+        if ((j%8) == 7)
+            DEBUGPRINT("\n");
+    } /* End od for */
+    DEBUGPRINT("\n\n");
+} /* End of BigInteger_Print */
+
+
+VOID BigInteger_Init (
+    INOUT PBIG_INTEGER *pBI)
+{
+    if (*pBI != NULL)
+        BigInteger_Free(pBI);
+
+    if ((*pBI = (PBIG_INTEGER) kmalloc(sizeof(BIG_INTEGER), GFP_ATOMIC)) == NULL) {
+        DEBUGPRINT("BigInteger_Init: allocate %d bytes memory failure.\n", (sizeof(BIG_INTEGER)));
+        return;
+    } /* End of if */
+
+    NdisZeroMemory(*pBI, sizeof(BIG_INTEGER));
+    (*pBI)->pIntegerArray = NULL;
+    (*pBI)->Signed = 1;
+} /* End of BigInteger_Init */
+
+
+VOID BigInteger_Free_AllocSize (
+    IN PBIG_INTEGER *pBI)
+{
+    if ((*pBI != NULL) && ((*pBI)->pIntegerArray != NULL)) {
+        kfree((*pBI)->pIntegerArray);
+        NdisZeroMemory(*pBI, sizeof(BIG_INTEGER));
+        (*pBI)->pIntegerArray = NULL;
+        (*pBI)->Signed = 1;
+    } /* End of if */
+} /* End of BigInteger_Free_AllocSize */
+
+
+VOID BigInteger_Free (
+    IN PBIG_INTEGER *pBI)
+{
+    if (*pBI != NULL) {
+        BigInteger_Free_AllocSize(pBI);
+        kfree(*pBI);
+    } /* End of if */
+
+    *pBI = NULL;
+} /* End of BigInteger_Free */
+
+
+VOID BigInteger_AllocSize (
+    IN PBIG_INTEGER *pBI,
+    IN UINT Length)
+{
+    UINT ArrayLength = 0;
+
+    if (Length == 0)
+        return;
+
+    if (*pBI == NULL)
+        BigInteger_Init(pBI);
+
+    /* Caculate array size */
+    ArrayLength = Length >> 0x2;
+    if ((Length & 0x3) != 0)
+        ArrayLength++;
+
+    if (((*pBI)->pIntegerArray != NULL) && ((*pBI)->AllocSize < (sizeof(UINT32)*ArrayLength)))
+        BigInteger_Free_AllocSize(pBI);
+
+    if ((*pBI)->pIntegerArray == NULL) {
+        if (((*pBI)->pIntegerArray = (UINT32 *) kmalloc(sizeof(UINT32)*ArrayLength, GFP_ATOMIC)) == NULL) {
+            DEBUGPRINT("BigInteger_AllocSize: allocate %d bytes memory failure.\n", (sizeof(UINT32)*ArrayLength));
+            return;
+        } /* End of if */
+        (*pBI)->AllocSize = sizeof(UINT32)*ArrayLength;
+    } /* End of if */
+
+    NdisZeroMemory((*pBI)->pIntegerArray, (*pBI)->AllocSize);
+    (*pBI)->ArrayLength = ArrayLength;
+    (*pBI)->IntegerLength = Length;
+} /* End of BigInteger_AllocSize */
+
+
+VOID BigInteger_ClearHighBits (
+    IN PBIG_INTEGER pBI)
+{
+    INT BIArrayIndex, ShiftIndex = 0;
+    UINT8 value;
+
+    if ((pBI == NULL) || (pBI->pIntegerArray == NULL))
+        return;
+
+    BIArrayIndex = pBI->ArrayLength - 1;
+    while ((BIArrayIndex >= 0) && (pBI->pIntegerArray[BIArrayIndex] == 0))
+	BIArrayIndex--;
+
+    if (BIArrayIndex >= 0) {
+        value = 0;
+        ShiftIndex = 4;
+        while (value == 0) {
+            ShiftIndex--;
+            value = UINT32_GETBYTE(pBI->pIntegerArray[BIArrayIndex], ShiftIndex);
+	} /* End of while */
+    } /* End of if */
+
+    if ((BIArrayIndex == -1) && (ShiftIndex == -1)) {
+        pBI->IntegerLength = 1;
+        pBI->ArrayLength = 1;
+        pBI->Signed = 1;
+    } else {
+        pBI->IntegerLength = (BIArrayIndex*4) + ShiftIndex + 1;
+        pBI->ArrayLength = BIArrayIndex + 1;
+    } /* End of if */
+} /* End of BigInteger_ClearHighBits */
+
+
+VOID BigInteger_BI2Bin (
+    IN PBIG_INTEGER pBI,
+    OUT UINT8 *pValue,
+    OUT UINT *Length)
+{
+    INT  ValueIndex, BIArrayIndex, ShiftIndex;
+    UINT32  Number;
+
+    if (pBI == NULL) {
+        DEBUGPRINT("BigInteger_BI2Bin: pBI is NUll\n");
+        *Length = 0;
+        return;
+    } /* End of if */
+
+    if (*Length < (sizeof(UINT8) * pBI->IntegerLength)) {
+        DEBUGPRINT("BigInteger_BI2Bin: length(%d) is not enough.\n", *Length);
+        *Length = 0;
+        return;
+    } /* End of if */
+
+    if (pBI->pIntegerArray == NULL) {
+        *Length = 0;
+        return;
+    } /* End of if */
+
+    BigInteger_ClearHighBits(pBI);
+    if ((ShiftIndex = pBI->IntegerLength & 0x3) == 0)
+       ShiftIndex = 4;
+    BIArrayIndex = pBI->ArrayLength - 1;
+    ValueIndex = 0;
+
+    Number = pBI->pIntegerArray[BIArrayIndex];
+    while (ValueIndex < pBI->IntegerLength)
+    {
+        pValue[ValueIndex++] = (UINT8) UINT32_GETBYTE(Number, ShiftIndex - 1);
+        if ((--ShiftIndex) == 0) {
+            ShiftIndex = 4;
+            BIArrayIndex--;
+            Number = pBI->pIntegerArray[BIArrayIndex];
+        } /* End of if */
+    } /* End of while */
+    *Length = pBI->IntegerLength;
+} /* End of BigInteger_BI2Bin */
+
+
+VOID BigInteger_Bin2BI (
+    IN UINT8 *pValue,
+    IN UINT Length,
+    OUT PBIG_INTEGER *pBI)
+{
+    INT  ValueIndex, BIArrayIndex, ShiftIndex;
+    UINT32  Number;
+
+    BigInteger_AllocSize(pBI, Length);
+
+    if ((*pBI)->pIntegerArray != NULL) {
+        Number = 0;
+        if ((ShiftIndex = Length & 0x3) == 0)
+            ShiftIndex = 4;
+        BIArrayIndex = (*pBI)->ArrayLength - 1;
+        ValueIndex = 0;
+        while (ValueIndex < Length)
+        {
+            Number = (Number << 8) | (UINT8) pValue[ValueIndex++];
+            if ((--ShiftIndex) == 0) {
+                (*pBI)->pIntegerArray[BIArrayIndex] = Number;
+                ShiftIndex = 4;
+                BIArrayIndex--;
+                Number = 0;
+            } /* End of if */
+        } /* End of while */
+    } /* End of if */
+} /* End of BigInteger_Bin2BI */
+
+
+/* Calculate the bits of BigInteger, the highest bit is 1 */
+VOID BigInteger_BitsOfBI (
+    IN PBIG_INTEGER pBI,
+    OUT UINT *Bits_Of_P)
+{
+    UINT32 Number, Index;
+
+    Number = pBI->pIntegerArray[pBI->ArrayLength - 1];
+    Index = 0;
+    while ((!(Number & 0x80000000)) && (Index < 32)) {
+        Number <<= 1;
+        Index++;
+    } /* End of while */
+    *Bits_Of_P = (pBI->ArrayLength*sizeof(UINT32)) - Index;
+} /* End of BigInteger_BitsOfBN */
+
+
+INT BigInteger_GetBitValue (
+    IN PBIG_INTEGER pBI,
+    IN UINT Index)
+{
+    UINT Array = 0;
+    UINT Shift = 0;
+
+    if (Index > 0) {
+        Array = (Index - 1) >> 0x5;
+        Shift = (Index - 1) & 0x1F;
+    }
+    if (Array > pBI->ArrayLength)
+        return 0;
+
+    return ((pBI->pIntegerArray[Array] >> Shift) & 0x1);
+} /* End of BigInteger_GetBitValue */
+
+
+UINT8 BigInteger_GetByteValue (
+    IN PBIG_INTEGER pBI,
+    IN UINT Index)
+{
+    UINT Array = 0;
+    UINT Shift = 0;
+
+    if (Index > 0) {
+        Array = (Index - 1) >> 0x2;
+        Shift = (Index - 1) & 0x3;
+    }
+    if ((Array > pBI->ArrayLength) || (Index > pBI->IntegerLength))
+        return 0;
+
+
+    return (UINT8) UINT32_GETBYTE(pBI->pIntegerArray[Array], Shift - 1);
+} /* End of BigInteger_GetByteValue */
+
+
+VOID BigInteger_Copy (
+    IN PBIG_INTEGER pBI_Copied,
+    OUT PBIG_INTEGER *pBI_Result)
+{
+    BigInteger_AllocSize(pBI_Result, pBI_Copied->IntegerLength);
+    NdisCopyMemory((*pBI_Result)->pIntegerArray, pBI_Copied->pIntegerArray, (sizeof(UINT32)*(*pBI_Result)->ArrayLength));
+    (*pBI_Result)->ArrayLength = pBI_Copied->ArrayLength;
+    (*pBI_Result)->IntegerLength = pBI_Copied->IntegerLength;
+    (*pBI_Result)->Signed = pBI_Copied->Signed;
+} /* End of BigInteger_Copy */
+
+
+INT BigInteger_UnsignedCompare (
+    IN PBIG_INTEGER pFirstOperand,
+    IN PBIG_INTEGER pSecondOperand)
+{
+    INT BIArrayIndex;
+
+    if (pFirstOperand->IntegerLength > pSecondOperand->IntegerLength)
+        return 1;
+
+    if (pFirstOperand->IntegerLength < pSecondOperand->IntegerLength)
+        return -1;
+
+    if (pFirstOperand->IntegerLength == pSecondOperand->IntegerLength) {
+        for(BIArrayIndex = (pFirstOperand->ArrayLength - 1);BIArrayIndex >= 0 ; BIArrayIndex--)
+        {
+            if (pFirstOperand->pIntegerArray[BIArrayIndex] > pSecondOperand->pIntegerArray[BIArrayIndex])
+                return 1;
+            else if (pFirstOperand->pIntegerArray[BIArrayIndex] < pSecondOperand->pIntegerArray[BIArrayIndex])
+                return -1;
+        } /* End of for */
+    } /* End of if */
+
+    return 0;
+} /* End of BigInteger_Compare */
+
+
+VOID BigInteger_Add (
+    IN PBIG_INTEGER pFirstOperand,
+    IN PBIG_INTEGER pSecondOperand,
+    OUT PBIG_INTEGER *pBI_Result)
+{
+    INT CompareResult;
+    UINT32 BIArrayIndex;
+    UINT64 Sum, Carry;
+    PBIG_INTEGER pTempBI = NULL;
+
+    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+        DEBUGPRINT("BigInteger_Add: first or second operand is NULL.\n");
+        return;
+    } /* End of if */
+
+    if (*pBI_Result == NULL)
+        BigInteger_Init(pBI_Result);
+
+    CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
+    if ((CompareResult == 0) & ((pFirstOperand->Signed * pSecondOperand->Signed) < 0)) {
+        BigInteger_AllocSize(pBI_Result, 1);
+        return ;
+    } /* End of if */
+
+    /*
+     *  Singed table
+     *  A + B || A > B || A < B
+     *  ------------------------
+     *  +   + ||   +   ||   +
+     *  +   - ||   +   ||   -
+     *  -   + ||   -   ||   +
+     *  -   - ||   -   ||   -
+     */
+    if ((pFirstOperand->Signed * pSecondOperand->Signed) > 0) {
+        if (pFirstOperand->IntegerLength > pSecondOperand->IntegerLength) {
+                BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength + 1);
+        } else {
+                BigInteger_AllocSize(pBI_Result, pSecondOperand->IntegerLength + 1);
+        } /* End of if */
+
+        Carry = 0;
+        for (BIArrayIndex=0; BIArrayIndex < (*pBI_Result)->ArrayLength; BIArrayIndex++)
+        {
+
+            Sum = 0;
+            if (BIArrayIndex < pFirstOperand->ArrayLength)
+                Sum += (UINT64) pFirstOperand->pIntegerArray[BIArrayIndex];
+
+            if (BIArrayIndex < pSecondOperand->ArrayLength)
+                Sum += (UINT64) pSecondOperand->pIntegerArray[BIArrayIndex];
+
+            Sum += Carry;
+            Carry = Sum  >> 32;
+            (*pBI_Result)->pIntegerArray[BIArrayIndex] = (UINT32) (Sum & 0xffffffffUL);
+        } /* End of for */
+        (*pBI_Result)->Signed = pFirstOperand->Signed;
+        BigInteger_ClearHighBits(*pBI_Result);
+    } else {
+        if  ((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == -1)) {
+            BigInteger_Copy(pSecondOperand, &pTempBI);
+            pTempBI->Signed = 1;
+            BigInteger_Sub(pFirstOperand, pTempBI, pBI_Result);
+        } else if ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == 1)) {
+            BigInteger_Copy(pFirstOperand, &pTempBI);
+            pTempBI->Signed = 1;
+            BigInteger_Sub(pSecondOperand, pTempBI, pBI_Result);
+        } /* End of if */
+    } /* End of if */
+
+    BigInteger_Free(&pTempBI);
+} /* End of BigInteger_Add */
+
+
+VOID BigInteger_Sub (
+    IN PBIG_INTEGER pFirstOperand,
+    IN PBIG_INTEGER pSecondOperand,
+    OUT PBIG_INTEGER *pBI_Result)
+{
+    INT CompareResult;
+    UINT32 BIArrayIndex, Carry;
+    PBIG_INTEGER pTempBI = NULL, pTempBI2 = NULL;
+
+    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+        DEBUGPRINT("BigInteger_Sub: first or second operand is NULL.\n");
+        return;
+    } /* End of if */
+
+    if (*pBI_Result == NULL)
+        BigInteger_Init(pBI_Result);
+
+    CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
+    if ((CompareResult == 0) & ((pFirstOperand->Signed * pSecondOperand->Signed) > 0)) {
+        BigInteger_AllocSize(pBI_Result, 1);
+        return ;
+    } /* End of if */
+
+    BigInteger_Init(&pTempBI);
+    BigInteger_Init(&pTempBI2);
+
+    /*
+     *  Singed table
+     *  A - B || A > B || A < B
+     *  ------------------------
+     *  +   + ||   +   ||   -
+     *  +   - ||   +   ||   +
+     *  -   + ||   -   ||   -
+     *  -   - ||   -   ||   +
+     */
+    if ((pFirstOperand->Signed * pSecondOperand->Signed) > 0) {
+        if (CompareResult == 1) {
+            BigInteger_Copy(pFirstOperand, &pTempBI);
+            BigInteger_Copy(pSecondOperand, &pTempBI2);
+        } else if (CompareResult == -1) {
+            BigInteger_Copy(pSecondOperand, &pTempBI);
+            BigInteger_Copy(pFirstOperand, &pTempBI2);
+        } /* End of if */
+
+        BigInteger_Copy(pTempBI, pBI_Result);
+        Carry = 0;
+        for (BIArrayIndex=0; BIArrayIndex < (*pBI_Result)->ArrayLength; BIArrayIndex++)
+        {
+            if (BIArrayIndex < pTempBI2->ArrayLength) {
+                if ((*pBI_Result)->pIntegerArray[BIArrayIndex] >= (pTempBI2->pIntegerArray[BIArrayIndex] - Carry)) {
+                    (*pBI_Result)->pIntegerArray[BIArrayIndex] = (*pBI_Result)->pIntegerArray[BIArrayIndex] - pTempBI2->pIntegerArray[BIArrayIndex] - Carry;
+                    Carry = 0;
+                } else {
+                    (*pBI_Result)->pIntegerArray[BIArrayIndex] = 0xffffffffUL - pTempBI2->pIntegerArray[BIArrayIndex] - Carry + (*pBI_Result)->pIntegerArray[BIArrayIndex] + 1;
+                    Carry = 1;
+                } /* End of if */
+            } else {
+                if ((*pBI_Result)->pIntegerArray[BIArrayIndex] >= Carry) {
+                    (*pBI_Result)->pIntegerArray[BIArrayIndex] -= Carry;
+                    Carry = 0;
+                } else {
+                    (*pBI_Result)->pIntegerArray[BIArrayIndex] = 0xffffffffUL - Carry;
+                    Carry = 1;
+                } /* End of if */
+            } /* End of if */
+        } /* End of for */
+
+        if  (((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == 1) & (CompareResult == -1))
+          || ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == -1) & (CompareResult == 1)))
+            (*pBI_Result)->Signed = -1;
+
+        BigInteger_ClearHighBits(*pBI_Result);
+    } else {
+        if  ((pFirstOperand->Signed == 1) & (pSecondOperand->Signed == -1)) {
+            BigInteger_Copy(pSecondOperand, &pTempBI);
+            pTempBI->Signed = 1;
+            BigInteger_Add(pFirstOperand, pTempBI, pBI_Result);
+        } else if ((pFirstOperand->Signed == -1) & (pSecondOperand->Signed == 1)) {
+            BigInteger_Copy(pFirstOperand, &pTempBI);
+            pTempBI->Signed = 1;
+            BigInteger_Add(pTempBI, pSecondOperand, pBI_Result);
+            (*pBI_Result)->Signed = -1;
+        } /* End of if */
+    } /* End of if */
+
+    BigInteger_Free(&pTempBI);
+    BigInteger_Free(&pTempBI2);
+} /* End of BigInteger_Sub */
+
+
+VOID BigInteger_Mul (
+    IN PBIG_INTEGER pFirstOperand,
+    IN PBIG_INTEGER pSecondOperand,
+    OUT PBIG_INTEGER *pBI_Result)
+{
+
+    UINT32 BIFirstIndex, BISecondIndex;
+    UINT64 FirstValue, SecondValue, Sum, Carry;
+
+    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+        DEBUGPRINT("BigInteger_Mul: first or second operand is NULL.\n");
+        return;
+    } /* End of if */
+
+    /* The first or second operand is zero */
+    if  (((pFirstOperand->IntegerLength  == 1) && (pFirstOperand->pIntegerArray[0]  == 0))
+       ||((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 0))) {
+        BigInteger_AllocSize(pBI_Result, 1);
+        goto output;
+    } /* End of if */
+
+    /* The first or second operand is one */
+    if  ((pFirstOperand->IntegerLength  == 1) && (pFirstOperand->pIntegerArray[0]  == 1)) {
+        BigInteger_Copy(pSecondOperand, pBI_Result);
+        goto output;
+    } /* End of if */
+    if  ((pSecondOperand->IntegerLength  == 1) && (pSecondOperand->pIntegerArray[0]  == 1)) {
+        BigInteger_Copy(pFirstOperand, pBI_Result);
+        goto output;
+    } /* End of if */
+
+    BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength + pSecondOperand->IntegerLength);
+
+    for (BIFirstIndex=0; BIFirstIndex < pFirstOperand->ArrayLength; BIFirstIndex++)
+    {
+        Carry = 0;
+        FirstValue = (UINT64) pFirstOperand->pIntegerArray[BIFirstIndex];
+        if (FirstValue == 0) {
+            continue;
+        } else {
+            for (BISecondIndex=0; BISecondIndex < pSecondOperand->ArrayLength; BISecondIndex++)
+            {
+                SecondValue = ((UINT64) pSecondOperand->pIntegerArray[BISecondIndex])*FirstValue;
+                Sum = (UINT64) ((*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] + SecondValue + Carry);
+                Carry = Sum >> 32;
+                (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] = (UINT32) (Sum & 0xffffffffUL);
+            } /* End of for */
+            while (Carry != 0) {
+                Sum = (UINT64) (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex];
+                Sum += Carry;
+
+                Carry = Sum >> 32;
+                (*pBI_Result)->pIntegerArray[BIFirstIndex + BISecondIndex] = (UINT32) (Sum & 0xffffffffUL);
+                BISecondIndex++;
+            } /* End of while */
+        } /* End of if */
+    } /* End of for */
+
+output:
+    (*pBI_Result)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
+    BigInteger_ClearHighBits(*pBI_Result);
+} /* End of BigInteger_Mul */
+
+
+VOID BigInteger_Square (
+    IN PBIG_INTEGER pBI,
+    OUT PBIG_INTEGER *pBI_Result)
+{
+    INT BIFirstIndex, BISecondIndex;
+	UINT32 HBITS_Value, LBITS_Value, Temp1_Value, Temp2_Value, Carry32;
+	UINT32 *Point_Of_S, *Point_Of_Result, *Point_Of_BI;
+    UINT64 Result64_1, Result64_2, Carry64, TempValue64;
+
+    if ((pBI == NULL) || (pBI->pIntegerArray == NULL)) {
+        DEBUGPRINT("\tBigInteger_Square: the operand is NULL.\n");
+        return;
+    } /* End of if */
+
+    /* The operand is zero */
+    if  ((pBI->IntegerLength  == 1) && (pBI->pIntegerArray[0]  ==  0)) {
+        BigInteger_AllocSize(pBI_Result, 1);
+        goto output;
+    } /* End of if */
+
+    BigInteger_AllocSize(pBI_Result, (pBI->IntegerLength*2) + 20);
+    BigInteger_AllocSize(&pBI_S, (pBI->IntegerLength*2) + 20);
+    BigInteger_AllocSize(&pBI_O, (pBI->IntegerLength*2) + 20);
+
+    /*
+     * Input: pBI = {a_0, a_1, a_2, a_3, ..., a_n}
+     * Step1. calculate a_0^2, a_1^2, a_2^2, a_3^2 ... a_n^2
+     */
+	Point_Of_S = pBI_S->pIntegerArray;
+    for (BIFirstIndex=0; BIFirstIndex < pBI->ArrayLength; BIFirstIndex++)
+    {
+	HBITS_Value = UINT32_HBITS(pBI->pIntegerArray[BIFirstIndex]);
+		LBITS_Value = UINT32_LBITS(pBI->pIntegerArray[BIFirstIndex]);
+		Temp1_Value = HBITS_Value*LBITS_Value;
+		Temp2_Value = (Temp1_Value & 0x7fff) << 0x11;
+		Point_Of_S[0] = (LBITS_Value*LBITS_Value) + Temp2_Value;
+		Point_Of_S[1] = (HBITS_Value*HBITS_Value) + ((Temp1_Value >> 0xf) & 0x1ffff);
+		if (Point_Of_S[0] < Temp2_Value)
+			Point_Of_S[1] += 1;
+
+		Point_Of_S += 2;
+    } /* End of for */
+
+    /*
+     * Step2. calculate a_0*{a_1, a_2, a_3, a_4, ..., a_n}
+     */
+    Point_Of_BI = pBI->pIntegerArray;
+    Point_Of_Result = (*pBI_Result)->pIntegerArray;
+    Point_Of_Result[0] = 0;
+    TempValue64 = (UINT64) Point_Of_BI[0];
+    Point_Of_Result++;
+    Carry64 = 0;
+    for (BIFirstIndex=1; BIFirstIndex < pBI->ArrayLength; BIFirstIndex++)
+    {
+        Result64_1 =  (UINT64) Point_Of_BI[BIFirstIndex]*TempValue64;
+        Result64_1 += Carry64;
+        Carry64 = (Result64_1 >> 32);
+        Point_Of_Result[0] = (UINT32) (Result64_1 & 0xffffffffUL);
+        Point_Of_Result++;
+    } /* End of for */
+    if (Carry64 > 0)
+        Point_Of_Result[0] = (UINT32) (Carry64 & 0xffffffffUL);
+
+    /*
+     * Step3. calculate
+     *           a_1*{a_2, a_3, a_4, ..., a_n}
+     *           a_2*{a_3, a_4, a_5, ..., a_n}
+     *           a_3*{a_4, a_5, a_6, ..., a_n}
+     *           a_4*{a_5, a_6, a_7, ..., a_n}
+     *           ...
+     *           a_n-1*{a_n}
+     */
+    Point_Of_BI = pBI->pIntegerArray;
+    for (BIFirstIndex=1; BIFirstIndex < (pBI->ArrayLength - 1); BIFirstIndex++)
+    {
+        Point_Of_Result = (*pBI_Result)->pIntegerArray;
+        Point_Of_Result += (BIFirstIndex*2) + 1;
+        TempValue64 = (UINT64) Point_Of_BI[BIFirstIndex];
+        Carry64 = 0;
+        for (BISecondIndex=(BIFirstIndex + 1); BISecondIndex < pBI->ArrayLength; BISecondIndex++)
+        {
+            Result64_1 = ((UINT64) Point_Of_Result[0]) + Carry64;
+            Result64_2 = (UINT64) Point_Of_BI[BISecondIndex]*TempValue64;
+            Carry64 = (Result64_1 >> 32);
+            Result64_1 = (Result64_1 & 0xffffffffUL);
+            Result64_1 = Result64_1 + Result64_2;
+            Carry64 += (Result64_1 >> 32);
+            Point_Of_Result[0] = (UINT32) (Result64_1 & 0xffffffffUL);
+            Point_Of_Result++;
+        } /* End of for */
+        if (Carry64 > 0)
+            Point_Of_Result[0] += (UINT32) (Carry64 & 0xffffffffUL);
+    } /* End of for */
+
+    BigInteger_ClearHighBits(*pBI_Result);
+    BigInteger_Copy(*pBI_Result, &pBI_O);
+
+    Carry32 = 0;
+	for (BIFirstIndex=0; BIFirstIndex < pBI_O->ArrayLength; BIFirstIndex++) {
+        pBI_O->pIntegerArray[BIFirstIndex] = (pBI_O->pIntegerArray[BIFirstIndex] << 1) | Carry32;
+        if (pBI_O->pIntegerArray[BIFirstIndex] < (*pBI_Result)->pIntegerArray[BIFirstIndex])
+            Carry32 = 1;
+        else
+            Carry32 = 0;
+    } /* End of for */
+    pBI_O->pIntegerArray[BIFirstIndex] = Carry32;
+    pBI_O->IntegerLength++;
+    pBI_O->ArrayLength++;
+    BigInteger_ClearHighBits(pBI_O);
+
+    BigInteger_Add(pBI_O, pBI_S, pBI_Result);
+output:
+    (*pBI_Result)->Signed = 1;
+    BigInteger_ClearHighBits(*pBI_Result);
+} /* End of BigInteger_Square */
+
+
+VOID BigInteger_Div (
+    IN PBIG_INTEGER pFirstOperand,
+    IN PBIG_INTEGER pSecondOperand,
+    OUT PBIG_INTEGER *pBI_Result,
+    OUT PBIG_INTEGER *pBI_Remainder)
+{
+    INT CompareResult;
+    INT Index, MulIndex, ComputeSize;
+    UINT32 MulStart;
+    UINT AllocLength, ArrayIndex, ShiftIndex;
+    PBIG_INTEGER pTempBI = NULL, pTempBI2 = NULL, pMulBI = NULL;
+    UINT8 SecondHighByte;
+
+    if  ((pFirstOperand == NULL) || (pFirstOperand->pIntegerArray == NULL)
+      || (pSecondOperand == NULL) || (pSecondOperand->pIntegerArray == NULL)) {
+        DEBUGPRINT("BigInteger_Div: first or second operand is NULL.\n");
+        return;
+    } /* End of if */
+
+    /* The second operand is zero */
+    if ((pSecondOperand->IntegerLength == 1) && (pSecondOperand->pIntegerArray[0] == 0)) {
+        DEBUGPRINT("BigInteger_Div: second operand is zero.\n");
+        return;
+    } /* End of if */
+
+    if (*pBI_Result == NULL)
+        BigInteger_Init(pBI_Result);
+    if (*pBI_Remainder == NULL)
+        BigInteger_Init(pBI_Remainder);
+
+    /* The second operand is one */
+    if  ((pSecondOperand->IntegerLength  == 1) && (pSecondOperand->pIntegerArray[0]  == 1)) {
+        BigInteger_Copy(pFirstOperand, pBI_Result);
+        BigInteger_Bin2BI(Value_0, 1, pBI_Remainder);
+        goto output;
+    } /* End of if */
+
+    CompareResult = BigInteger_UnsignedCompare(pFirstOperand, pSecondOperand);
+    if (CompareResult == 0) {
+        BigInteger_Bin2BI(Value_1, 1, pBI_Result);
+        BigInteger_Bin2BI(Value_0, 1, pBI_Remainder);
+        goto output;
+    } else if (CompareResult == -1) {
+        BigInteger_Bin2BI(Value_0, 1, pBI_Result);
+        BigInteger_Copy(pFirstOperand, pBI_Remainder);
+        goto output;
+    } /* End of if */
+    BigInteger_AllocSize(pBI_Result, pFirstOperand->IntegerLength - pSecondOperand->IntegerLength + 1);
+    BigInteger_AllocSize(pBI_Remainder, pSecondOperand->IntegerLength);
+
+    AllocLength = (UINT) (pFirstOperand->IntegerLength << 1);
+    BigInteger_AllocSize(&pTempBI, AllocLength);
+    BigInteger_AllocSize(&pTempBI2, AllocLength);
+    BigInteger_AllocSize(&pMulBI, AllocLength);
+
+    BigInteger_Copy(pFirstOperand, pBI_Remainder);
+    SecondHighByte = BigInteger_GetByteValue(pSecondOperand, pSecondOperand->IntegerLength);
+    ComputeSize = (INT) pFirstOperand->IntegerLength - pSecondOperand->IntegerLength + 1;
+    for (Index = (INT) ComputeSize;Index >= 0;Index--) {
+        if (BigInteger_UnsignedCompare(*pBI_Remainder, pSecondOperand) == -1)
+            break;
+
+        if (((pSecondOperand->IntegerLength + Index) - (*pBI_Remainder)->IntegerLength) <= 1) {
+            BigInteger_AllocSize(&pMulBI, Index + 1);
+            ArrayIndex = 0;
+            if (Index > 0)
+                ArrayIndex = (UINT) (Index - 1) >> 2 ;
+            ShiftIndex = (Index & 0x03);
+            if (ShiftIndex == 0)
+                ShiftIndex = 4;
+            ShiftIndex--;
+            MulStart = 0;
+            MulStart = (BigInteger_GetByteValue((*pBI_Remainder), pFirstOperand->IntegerLength + Index - ComputeSize + 1) & 0xFF) << 8;
+            MulStart = MulStart | (BigInteger_GetByteValue((*pBI_Remainder), pFirstOperand->IntegerLength + Index - ComputeSize) & 0xFF);
+            if (MulStart < (UINT32) SecondHighByte)
+                continue;
+
+            MulStart = MulStart / (UINT32) SecondHighByte;
+
+            if (MulStart > 0xFF)
+                MulStart = 0x100;
+
+            for (MulIndex = (INT) MulStart;MulIndex <= 0x101;MulIndex++) { /* 0xFFFF / 0xFF = 0x101 */
+                if ((MulIndex > 0xFF) && (ShiftIndex == 3))
+                        pMulBI->pIntegerArray[ArrayIndex + 1] = 0x01;
+                pMulBI->pIntegerArray[ArrayIndex] = ((UINT) MulIndex << (8*ShiftIndex));
+                BigInteger_Mul(pSecondOperand, pMulBI , &pTempBI);
+                CompareResult = BigInteger_UnsignedCompare(*pBI_Remainder, pTempBI);
+                if (CompareResult < 1) {
+                    if (MulIndex > 1) {
+                        if (CompareResult != 0) {
+                            if ((MulIndex == 0x100) && (ShiftIndex == 3))
+                                   pMulBI->pIntegerArray[ArrayIndex + 1] = 0;
+                            pMulBI->pIntegerArray[ArrayIndex] = ((UINT) (MulIndex - 1) << (8*ShiftIndex));
+                        } /* End of if */
+
+                        BigInteger_Mul(pSecondOperand, pMulBI, &pTempBI);
+                        BigInteger_Sub(*pBI_Remainder, pTempBI, &pTempBI2);
+                        BigInteger_Copy(pTempBI2, pBI_Remainder);
+                        BigInteger_Add(*pBI_Result, pMulBI, &pTempBI2);
+                        BigInteger_Copy(pTempBI2, pBI_Result);
+                    } /* End of if */
+                    break;
+                } /* End of if */
+
+                if ((MulIndex >= 0x100) && (ShiftIndex == 3))
+                   pMulBI->pIntegerArray[ArrayIndex++] = 0;
+                pMulBI->pIntegerArray[ArrayIndex] = 0;
+            } /* End of for */
+        } /* End of if */
+    } /* End of for */
+
+    BigInteger_Free(&pTempBI);
+    BigInteger_Free(&pTempBI2);
+    BigInteger_Free(&pMulBI);
+output:
+    (*pBI_Result)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
+    (*pBI_Remainder)->Signed = pFirstOperand->Signed * pSecondOperand->Signed;
+    BigInteger_ClearHighBits(*pBI_Result);
+    BigInteger_ClearHighBits(*pBI_Remainder);
+} /* End of BigInteger_Div */
+
+
+VOID BigInteger_Montgomery_Reduction (
+    IN PBIG_INTEGER pBI_A,
+    IN PBIG_INTEGER pBI_P,
+     IN PBIG_INTEGER pBI_R,
+    OUT PBIG_INTEGER *pBI_Result)
+{
+    UINT32 *Point_P, *Point_Result;
+    UINT32 LoopCount;
+    UINT64 Result64_1, Result64_2, Carry64, TempValue64;
+    INT FirstLoop, SecondLoop;
+
+    BigInteger_AllocSize(pBI_Result, pBI_A->IntegerLength+ pBI_P->IntegerLength + 20);
+    BigInteger_Copy(pBI_A, pBI_Result);
+
+    Point_P = pBI_P->pIntegerArray;
+    Point_Result = (*pBI_Result)->pIntegerArray;
+
+    LoopCount = Bits_Of_R >> 0x5;
+    for (FirstLoop = 0;FirstLoop < LoopCount;FirstLoop++) {
+        Carry64 = 0;
+        TempValue64 = (UINT64) Point_Result[0];
+        for (SecondLoop = 0;SecondLoop < pBI_P->ArrayLength;SecondLoop++) {
+            Result64_1 = ((UINT64) Point_Result[SecondLoop]) + Carry64;
+            Result64_2 = (UINT64) Point_P[SecondLoop]*TempValue64;
+            Carry64 = (Result64_1 >> 32);
+            Result64_1 = (Result64_1 & 0xffffffffUL);
+            Result64_1 = Result64_1 + Result64_2;
+            Carry64 += (Result64_1 >> 32);
+            Point_Result[SecondLoop] = (UINT32) (Result64_1 & 0xffffffffUL);
+        } /* End of for */
+        while (Carry64 != 0) {
+          Result64_1 = ((UINT64) Point_Result[SecondLoop]) + Carry64;
+          Carry64 = Result64_1 >> 32;
+          Point_Result[SecondLoop] = (UINT32) (Result64_1 & 0xffffffffUL);
+          SecondLoop++;
+        } /* End of while */
+        Point_Result++;
+    } /* End of for */
+
+    for (FirstLoop = 0;FirstLoop <= LoopCount;FirstLoop++) {
+        (*pBI_Result)->pIntegerArray[FirstLoop] = (*pBI_Result)->pIntegerArray[FirstLoop + LoopCount];
+    } /* End of for */
+    if ((*pBI_Result)->pIntegerArray[LoopCount] != 0)
+        (*pBI_Result)->ArrayLength = LoopCount + 1;
+    else
+        (*pBI_Result)->ArrayLength = LoopCount;
+
+    (*pBI_Result)->IntegerLength = (*pBI_Result)->ArrayLength*4;
+    BigInteger_ClearHighBits(*pBI_Result);
+
+    if (BigInteger_UnsignedCompare(*pBI_Result, pBI_P) >= 0) {
+        BigInteger_Sub(*pBI_Result, pBI_P, &pBI_U);
+        BigInteger_Copy(pBI_U, pBI_Result);
+    } /* End of if */
+    BigInteger_ClearHighBits(*pBI_Result);
+} /* End of BigInteger_Montgomery_Reduction */
+
+
+VOID BigInteger_Montgomery_ExpMod (
+    IN PBIG_INTEGER pBI_G,
+    IN PBIG_INTEGER pBI_E,
+    IN PBIG_INTEGER pBI_P,
+    OUT PBIG_INTEGER *pBI_Result)
+{
+    UINT Bits_Of_P;
+    UINT32 Index, Index2, AllocLength;
+	UINT32 Sliding_Value , Sliding_HighValue, Sliding_LowValue;
+    PBIG_INTEGER pBI_Temp1 = NULL, pBI_Temp2 = NULL;
+    PBIG_INTEGER pBI_X = NULL, pBI_R = NULL, pBI_RR = NULL, pBI_1 = NULL;
+    BIG_INTEGER *pBI_A[SLIDING_WINDOW];
+    UINT8 *pRValue = NULL;
+
+    AllocLength = (pBI_G->IntegerLength + pBI_E->IntegerLength + pBI_P->IntegerLength + 300);
+    BigInteger_AllocSize(&pBI_Temp1, AllocLength);
+    BigInteger_AllocSize(&pBI_Temp2, AllocLength);
+
+    /* Calculate the bits of P and E, the highest bit is 1 */
+    BigInteger_BitsOfBI(pBI_P, &Bits_Of_P);
+
+    if ((pBI_E->IntegerLength == 1) && (pBI_E->pIntegerArray[0] == 1)) {
+        BigInteger_Div(pBI_G, pBI_P, &pBI_Temp1, pBI_Result);
+        goto memory_free;
+    } /* End of if */
+
+    if ((pBI_E->IntegerLength == 1) && (pBI_E->pIntegerArray[0] == 2)) {
+        BigInteger_Mul(pBI_G, pBI_G, &pBI_Temp1);
+        BigInteger_Div(pBI_Temp1, pBI_P, &pBI_Temp2, pBI_Result);
+        goto memory_free;
+    } /* End of if */
+
+    /*
+     * Main algorithm
+     */
+    BigInteger_Init(&pBI_R);
+    BigInteger_Init(&pBI_RR);
+    BigInteger_Bin2BI(Value_1, 1, &pBI_1);
+    BigInteger_AllocSize(&pBI_X, AllocLength);
+    BigInteger_AllocSize(&pBI_U, AllocLength); // for BigInteger_Montgomery_Reduction
+    BigInteger_AllocSize(&pBI_S, AllocLength); // for BigInteger_Square
+    BigInteger_AllocSize(&pBI_O, AllocLength); // for BigInteger_Square
+
+    for (Index = 0; Index < SLIDING_WINDOW; Index++) {
+        pBI_A[Index] = NULL;
+		BigInteger_AllocSize(&pBI_A[Index], 193);
+    } /* End of for */
+    BigInteger_Bin2BI(WPS_DH_P_VALUE, 192, &pBI_Temp1);
+    if (NdisCmpMemory(pBI_P->pIntegerArray, pBI_Temp1->pIntegerArray, pBI_P->IntegerLength) == 0) {
+        BigInteger_Bin2BI(WPS_DH_X_VALUE, 184, &pBI_X);
+        BigInteger_Bin2BI(WPS_DH_R_VALUE, 193, &pBI_R);
+        BigInteger_Bin2BI(WPS_DH_RRModP_VALUE, 192, &pBI_RR);
+        Bits_Of_R = 1537;
+    } else {
+        if ((Bits_Of_P % 8) == 0) {
+            AllocLength = pBI_P->IntegerLength + 1;
+        } else {
+            AllocLength = pBI_P->IntegerLength;
+        } /* End of if */
+        pRValue = (UINT8 *) kmalloc(sizeof(UINT8)*AllocLength, GFP_ATOMIC);
+	if (pRValue == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __FUNCTION__));
+		goto memory_free;
+	}
+        NdisZeroMemory(pRValue, sizeof(UINT8)*AllocLength);
+        pRValue[0] = (UINT8) (1 << (Bits_Of_P & 0x7));
+        BigInteger_Bin2BI(pRValue, AllocLength , &pBI_R);
+
+        BigInteger_Mul(pBI_R, pBI_R, &pBI_Temp1);
+        BigInteger_Div(pBI_Temp1, pBI_P, &pBI_A[1], &pBI_RR);
+
+        /* X = 1*R (mod P) */
+        BigInteger_Div(pBI_R, pBI_P, &pBI_Temp2, &pBI_X);
+    } /* End of if */
+
+    /* A = G*R (mod P) => A = MonMod(G, R^2 mod P) */
+    BigInteger_Mul(pBI_G, pBI_RR, &pBI_Temp1);
+    BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P , pBI_R, &pBI_A[1]);
+    for (Index = 2; Index < SLIDING_WINDOW; Index++) {
+        BigInteger_Mul(pBI_A[Index - 1], pBI_A[1], &pBI_Temp1);
+	    BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_A[Index]);
+    } /* End of for */
+
+    for (Index = pBI_E->IntegerLength ; Index > 0 ; Index--) {
+        for (Index2 = 0; Index2 < 4 ; Index2++) {
+            BigInteger_Square(pBI_X, &pBI_Temp1);
+			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+	    } /* End of for */
+
+		Sliding_Value = BigInteger_GetByteValue(pBI_E, Index);
+		Sliding_HighValue = (Sliding_Value >> 4);
+		if (Sliding_HighValue != 0) {
+            BigInteger_Mul(pBI_A[Sliding_HighValue], pBI_X, &pBI_Temp1);
+			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+		} /* End of if */
+
+        for (Index2 = 0; Index2 < 4 ; Index2++) {
+            BigInteger_Square(pBI_X, &pBI_Temp1);
+			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+	    } /* End of for */
+
+		Sliding_LowValue = Sliding_Value & 0x0f;
+		if (Sliding_LowValue != 0) {
+            BigInteger_Mul(pBI_A[Sliding_LowValue], pBI_X, &pBI_Temp1);
+			BigInteger_Montgomery_Reduction(pBI_Temp1, pBI_P, pBI_R, &pBI_X);
+		} /* End of if */
+    } /* End of for */
+    BigInteger_Montgomery_Reduction(pBI_X, pBI_P , pBI_R, pBI_Result);
+
+    BigInteger_Free(&pBI_X);
+    BigInteger_Free(&pBI_R);
+    BigInteger_Free(&pBI_RR);
+    BigInteger_Free(&pBI_1);
+    BigInteger_Free(&pBI_U);
+    BigInteger_Free(&pBI_S);
+    BigInteger_Free(&pBI_O);
+    for(Index = 0; Index < SLIDING_WINDOW; Index++)
+			BigInteger_Free(&pBI_A[Index]);
+    if (pRValue != NULL)
+        kfree(pRValue);
+
+memory_free:
+    BigInteger_Free(&pBI_Temp1);
+    BigInteger_Free(&pBI_Temp2);
+} /* End of BigInteger_Montgomery_ExpMod */
+
+/* End of crypt_biginteger.c */
diff --git a/drivers/staging/rt3090/common/crypt_dh.c b/drivers/staging/rt3090/common/crypt_dh.c
new file mode 100644
index 0000000..0f69f2a
--- /dev/null
+++ b/drivers/staging/rt3090/common/crypt_dh.c
@@ -0,0 +1,234 @@
+/*
+ *************************************************************************
+ * 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:
+	crypt_dh.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Eddy        2009/01/19      Create AES-128, AES-192, AES-256, AES-CBC
+*/
+
+#include "crypt_dh.h"
+#include "crypt_biginteger.h"
+
+/*
+========================================================================
+Routine Description:
+    Diffie-Hellman public key generation
+
+Arguments:
+    GValue           Array in UINT8
+    GValueLength     The length of G in bytes
+    PValue           Array in UINT8
+    PValueLength     The length of P in bytes
+    PrivateKey       Private key
+    PrivateKeyLength The length of Private key in bytes
+
+Return Value:
+    PublicKey       Public key
+    PublicKeyLength The length of public key in bytes
+
+Note:
+    Reference to RFC2631
+    PublicKey = G^PrivateKey (mod P)
+========================================================================
+*/
+void DH_PublicKey_Generate (
+    IN UINT8 GValue[],
+    IN UINT GValueLength,
+    IN UINT8 PValue[],
+    IN UINT PValueLength,
+    IN UINT8 PrivateKey[],
+    IN UINT PrivateKeyLength,
+    OUT UINT8 PublicKey[],
+    INOUT UINT *PublicKeyLength)
+{
+    PBIG_INTEGER pBI_G = NULL;
+    PBIG_INTEGER pBI_P = NULL;
+    PBIG_INTEGER pBI_PrivateKey = NULL;
+    PBIG_INTEGER pBI_PublicKey = NULL;
+
+    /*
+     * 1. Check the input parameters
+     *    - GValueLength, PValueLength and PrivateLength must be large than zero
+     *    - PublicKeyLength must be large or equal than PValueLength
+     *    - PValue must be odd
+     *
+     *    - PValue must be prime number (no implement)
+     *    - GValue must be greater than 0 but less than the PValue (no implement)
+     */
+    if (GValueLength == 0) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: G length is (%d)\n", GValueLength));
+        return;
+    } /* End of if */
+    if (PValueLength == 0) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P length is (%d)\n", PValueLength));
+        return;
+    } /* End of if */
+    if (PrivateKeyLength == 0) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: private key length is (%d)\n", PrivateKeyLength));
+        return;
+    } /* End of if */
+    if (*PublicKeyLength < PValueLength) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: public key length(%d) must be large or equal than P length(%d)\n",
+            *PublicKeyLength, PValueLength));
+        return;
+    } /* End of if */
+    if (!(PValue[PValueLength - 1] & 0x1)) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_PublicKey_Generate: P value must be odd\n"));
+        return;
+    } /* End of if */
+
+    /*
+     * 2. Transfer parameters to BigInteger structure
+     */
+    BigInteger_Init(&pBI_G);
+    BigInteger_Init(&pBI_P);
+    BigInteger_Init(&pBI_PrivateKey);
+    BigInteger_Init(&pBI_PublicKey);
+    BigInteger_Bin2BI(GValue, GValueLength, &pBI_G);
+    BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
+    BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
+
+    /*
+     * 3. Calculate PublicKey = G^PrivateKey (mod P)
+     *    - BigInteger Operation
+     *    - Montgomery reduction
+     */
+    BigInteger_Montgomery_ExpMod(pBI_G, pBI_PrivateKey, pBI_P, &pBI_PublicKey);
+
+    /*
+     * 4. Transfer BigInteger structure to char array
+     */
+    BigInteger_BI2Bin(pBI_PublicKey, PublicKey, PublicKeyLength);
+
+    BigInteger_Free(&pBI_G);
+    BigInteger_Free(&pBI_P);
+    BigInteger_Free(&pBI_PrivateKey);
+    BigInteger_Free(&pBI_PublicKey);
+} /* End of DH_PublicKey_Generate */
+
+
+/*
+========================================================================
+Routine Description:
+    Diffie-Hellman secret key generation
+
+Arguments:
+    PublicKey        Public key
+    PublicKeyLength  The length of Public key in bytes
+    PValue           Array in UINT8
+    PValueLength     The length of P in bytes
+    PrivateKey       Private key
+    PrivateKeyLength The length of Private key in bytes
+
+Return Value:
+    SecretKey        Secret key
+    SecretKeyLength  The length of secret key in bytes
+
+Note:
+    Reference to RFC2631
+    SecretKey = PublicKey^PrivateKey (mod P)
+========================================================================
+*/
+void DH_SecretKey_Generate (
+    IN UINT8 PublicKey[],
+    IN UINT PublicKeyLength,
+    IN UINT8 PValue[],
+    IN UINT PValueLength,
+    IN UINT8 PrivateKey[],
+    IN UINT PrivateKeyLength,
+    OUT UINT8 SecretKey[],
+    INOUT UINT *SecretKeyLength)
+{
+    PBIG_INTEGER pBI_P = NULL;
+    PBIG_INTEGER pBI_SecretKey = NULL;
+    PBIG_INTEGER pBI_PrivateKey = NULL;
+    PBIG_INTEGER pBI_PublicKey = NULL;
+
+    /*
+     * 1. Check the input parameters
+     *    - PublicKeyLength, PValueLength and PrivateLength must be large than zero
+     *    - SecretKeyLength must be large or equal than PValueLength
+     *    - PValue must be odd
+     *
+     *    - PValue must be prime number (no implement)
+     */
+    if (PublicKeyLength == 0) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: public key length is (%d)\n", PublicKeyLength));
+        return;
+    } /* End of if */
+    if (PValueLength == 0) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P length is (%d)\n", PValueLength));
+        return;
+    } /* End of if */
+    if (PrivateKeyLength == 0) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: private key length is (%d)\n", PrivateKeyLength));
+        return;
+    } /* End of if */
+    if (*SecretKeyLength < PValueLength) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: secret key length(%d) must be large or equal than P length(%d)\n",
+            *SecretKeyLength, PValueLength));
+        return;
+    } /* End of if */
+    if (!(PValue[PValueLength - 1] & 0x1)) {
+	DBGPRINT(RT_DEBUG_ERROR, ("DH_SecretKey_Generate: P value must be odd\n"));
+        return;
+    } /* End of if */
+
+    /*
+     * 2. Transfer parameters to BigInteger structure
+     */
+    BigInteger_Init(&pBI_P);
+    BigInteger_Init(&pBI_PrivateKey);
+    BigInteger_Init(&pBI_PublicKey);
+    BigInteger_Init(&pBI_SecretKey);
+
+    BigInteger_Bin2BI(PublicKey, PublicKeyLength, &pBI_PublicKey);
+    BigInteger_Bin2BI(PValue, PValueLength, &pBI_P);
+    BigInteger_Bin2BI(PrivateKey, PrivateKeyLength, &pBI_PrivateKey);
+
+    /*
+     * 3. Calculate SecretKey = PublicKey^PrivateKey (mod P)
+     *    - BigInteger Operation
+     *    - Montgomery reduction
+     */
+    BigInteger_Montgomery_ExpMod(pBI_PublicKey, pBI_PrivateKey, pBI_P, &pBI_SecretKey);
+
+    /*
+     * 4. Transfer BigInteger structure to char array
+     */
+    BigInteger_BI2Bin(pBI_SecretKey, SecretKey, SecretKeyLength);
+
+    BigInteger_Free(&pBI_P);
+    BigInteger_Free(&pBI_PrivateKey);
+    BigInteger_Free(&pBI_PublicKey);
+    BigInteger_Free(&pBI_SecretKey);
+} /* End of DH_SecretKey_Generate */
diff --git a/drivers/staging/rt3090/common/crypt_hmac.c b/drivers/staging/rt3090/common/crypt_hmac.c
new file mode 100644
index 0000000..e285408
--- /dev/null
+++ b/drivers/staging/rt3090/common/crypt_hmac.c
@@ -0,0 +1,279 @@
+/*
+ *************************************************************************
+ * 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 "../crypt_hmac.h"
+
+
+#ifdef HMAC_SHA1_SUPPORT
+/*
+========================================================================
+Routine Description:
+    HMAC using SHA1 hash function
+
+Arguments:
+    key             Secret key
+    key_len         The length of the key in bytes
+    message         Message context
+    message_len     The length of message in bytes
+    macLen          Request the length of message authentication code
+
+Return Value:
+    mac             Message authentication code
+
+Note:
+    None
+========================================================================
+*/
+VOID HMAC_SHA1 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen)
+{
+    SHA1_CTX_STRUC sha_ctx1;
+    SHA1_CTX_STRUC sha_ctx2;
+    UINT8 K0[SHA1_BLOCK_SIZE];
+    UINT8 Digest[SHA1_DIGEST_SIZE];
+    UINT index;
+
+    NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC));
+    NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC));
+    /*
+     * If the length of K = B(Block size): K0 = K.
+     * If the length of K > B: hash K to obtain an L byte string,
+     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+     */
+    NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
+    if (KeyLen <= SHA1_BLOCK_SIZE)
+        NdisMoveMemory(K0, Key, KeyLen);
+    else
+        RT_SHA1(Key, KeyLen, K0);
+    /* End of if */
+
+    /* Exclusive-Or K0 with ipad */
+    /* ipad: Inner pad; the byte xï¿½ï¿½36ï¿½ï¿½ repeated B times. */
+    for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36;
+        /* End of for */
+
+    SHA1_Init(&sha_ctx1);
+    /* H(K0^ipad) */
+    SHA1_Append(&sha_ctx1, K0, sizeof(K0));
+    /* H((K0^ipad)||text) */
+    SHA1_Append(&sha_ctx1, Message, MessageLen);
+    SHA1_End(&sha_ctx1, Digest);
+
+    /* Exclusive-Or K0 with opad and remove ipad */
+    /* opad: Outer pad; the byte xï¿½ï¿½5cï¿½ï¿½ repeated B times. */
+    for (index = 0; index < SHA1_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36^0x5c;
+        /* End of for */
+
+    SHA1_Init(&sha_ctx2);
+    /* H(K0^opad) */
+    SHA1_Append(&sha_ctx2, K0, sizeof(K0));
+    /* H( (K0^opad) || H((K0^ipad)||text) ) */
+    SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
+    SHA1_End(&sha_ctx2, Digest);
+
+    if (MACLen > SHA1_DIGEST_SIZE)
+        NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
+    else
+        NdisMoveMemory(MAC, Digest, MACLen);
+} /* End of HMAC_SHA1 */
+#endif /* HMAC_SHA1_SUPPORT */
+
+
+#ifdef HMAC_SHA256_SUPPORT
+/*
+========================================================================
+Routine Description:
+    HMAC using SHA256 hash function
+
+Arguments:
+    key             Secret key
+    key_len         The length of the key in bytes
+    message         Message context
+    message_len     The length of message in bytes
+    macLen          Request the length of message authentication code
+
+Return Value:
+    mac             Message authentication code
+
+Note:
+    None
+========================================================================
+*/
+VOID HMAC_SHA256 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen)
+{
+    SHA256_CTX_STRUC sha_ctx1;
+    SHA256_CTX_STRUC sha_ctx2;
+    UINT8 K0[SHA256_BLOCK_SIZE];
+    UINT8 Digest[SHA256_DIGEST_SIZE];
+    UINT index;
+
+    NdisZeroMemory(&sha_ctx1, sizeof(SHA256_CTX_STRUC));
+    NdisZeroMemory(&sha_ctx2, sizeof(SHA256_CTX_STRUC));
+    /*
+     * If the length of K = B(Block size): K0 = K.
+     * If the length of K > B: hash K to obtain an L byte string,
+     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+     */
+    NdisZeroMemory(K0, SHA256_BLOCK_SIZE);
+    if (KeyLen <= SHA256_BLOCK_SIZE) {
+        NdisMoveMemory(K0, Key, KeyLen);
+    } else {
+        RT_SHA256(Key, KeyLen, K0);
+    }
+
+    /* Exclusive-Or K0 with ipad */
+    /* ipad: Inner pad; the byte xï¿½ï¿½36ï¿½ï¿½ repeated B times. */
+    for (index = 0; index < SHA256_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36;
+        /* End of for */
+
+    SHA256_Init(&sha_ctx1);
+    /* H(K0^ipad) */
+    SHA256_Append(&sha_ctx1, K0, sizeof(K0));
+    /* H((K0^ipad)||text) */
+    SHA256_Append(&sha_ctx1, Message, MessageLen);
+    SHA256_End(&sha_ctx1, Digest);
+
+    /* Exclusive-Or K0 with opad and remove ipad */
+    /* opad: Outer pad; the byte xï¿½ï¿½5cï¿½ï¿½ repeated B times. */
+    for (index = 0; index < SHA256_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36^0x5c;
+        /* End of for */
+
+    SHA256_Init(&sha_ctx2);
+    /* H(K0^opad) */
+    SHA256_Append(&sha_ctx2, K0, sizeof(K0));
+    /* H( (K0^opad) || H((K0^ipad)||text) ) */
+    SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE);
+    SHA256_End(&sha_ctx2, Digest);
+
+    if (MACLen > SHA256_DIGEST_SIZE)
+        NdisMoveMemory(MAC, Digest,SHA256_DIGEST_SIZE);
+    else
+        NdisMoveMemory(MAC, Digest, MACLen);
+
+} /* End of HMAC_SHA256 */
+#endif /* HMAC_SHA256_SUPPORT */
+
+
+#ifdef HMAC_MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+    HMAC using MD5 hash function
+
+Arguments:
+    key             Secret key
+    key_len         The length of the key in bytes
+    message         Message context
+    message_len     The length of message in bytes
+    macLen          Request the length of message authentication code
+
+Return Value:
+    mac             Message authentication code
+
+Note:
+    None
+========================================================================
+*/
+VOID HMAC_MD5(
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen)
+{
+    MD5_CTX_STRUC md5_ctx1;
+    MD5_CTX_STRUC md5_ctx2;
+    UINT8 K0[MD5_BLOCK_SIZE];
+    UINT8 Digest[MD5_DIGEST_SIZE];
+    UINT index;
+
+    NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC));
+    NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC));
+    /*
+     * If the length of K = B(Block size): K0 = K.
+     * If the length of K > B: hash K to obtain an L byte string,
+     * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
+     * If the length of K < B: append zeros to the end of K to create a B-byte string K0
+     */
+    NdisZeroMemory(K0, MD5_BLOCK_SIZE);
+    if (KeyLen <= MD5_BLOCK_SIZE) {
+        NdisMoveMemory(K0, Key, KeyLen);
+    } else {
+        RT_MD5(Key, KeyLen, K0);
+    }
+
+    /* Exclusive-Or K0 with ipad */
+    /* ipad: Inner pad; the byte xï¿½ï¿½36ï¿½ï¿½ repeated B times. */
+    for (index = 0; index < MD5_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36;
+        /* End of for */
+
+    MD5_Init(&md5_ctx1);
+    /* H(K0^ipad) */
+    MD5_Append(&md5_ctx1, K0, sizeof(K0));
+    /* H((K0^ipad)||text) */
+    MD5_Append(&md5_ctx1, Message, MessageLen);
+    MD5_End(&md5_ctx1, Digest);
+
+    /* Exclusive-Or K0 with opad and remove ipad */
+    /* opad: Outer pad; the byte xï¿½ï¿½5cï¿½ï¿½ repeated B times. */
+    for (index = 0; index < MD5_BLOCK_SIZE; index++)
+        K0[index] ^= 0x36^0x5c;
+        /* End of for */
+
+    MD5_Init(&md5_ctx2);
+    /* H(K0^opad) */
+    MD5_Append(&md5_ctx2, K0, sizeof(K0));
+    /* H( (K0^opad) || H((K0^ipad)||text) ) */
+    MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
+    MD5_End(&md5_ctx2, Digest);
+
+    if (MACLen > MD5_DIGEST_SIZE)
+        NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
+    else
+        NdisMoveMemory(MAC, Digest, MACLen);
+} /* End of HMAC_SHA256 */
+#endif /* HMAC_MD5_SUPPORT */
+
+/* End of crypt_hmac.c */
diff --git a/drivers/staging/rt3090/common/crypt_md5.c b/drivers/staging/rt3090/common/crypt_md5.c
new file mode 100644
index 0000000..b093265
--- /dev/null
+++ b/drivers/staging/rt3090/common/crypt_md5.c
@@ -0,0 +1,353 @@
+/*
+ *************************************************************************
+ * 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 "../crypt_md5.h"
+
+
+#ifdef MD5_SUPPORT
+/*
+ * F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
+#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
+
+#define ROUND1(a, b, c, d, x, s, ac) {          \
+    (a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND2(a, b, c, d, x, s, ac) {          \
+    (a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND3(a, b, c, d, x, s, ac) {          \
+    (a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+#define ROUND4(a, b, c, d, x, s, ac) {          \
+    (a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \
+    (a)  = ROTL32((a),(s));                     \
+    (a) += (b);                                 \
+}
+static const UINT32 MD5_DefaultHashValue[4] = {
+    0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
+};
+#endif /* MD5_SUPPORT */
+
+
+#ifdef MD5_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Initial Md5_CTX_STRUC
+
+Arguments:
+    pMD5_CTX        Pointer to Md5_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID MD5_Init (
+    IN  MD5_CTX_STRUC *pMD5_CTX)
+{
+    NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
+        sizeof(MD5_DefaultHashValue));
+    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+    pMD5_CTX->BlockLen   = 0;
+    pMD5_CTX->MessageLen = 0;
+} /* End of MD5_Init */
+
+
+/*
+========================================================================
+Routine Description:
+    MD5 computation for one block (512 bits)
+
+Arguments:
+    pMD5_CTX        Pointer to Md5_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
+========================================================================
+*/
+VOID MD5_Hash (
+    IN  MD5_CTX_STRUC *pMD5_CTX)
+{
+    UINT32 X_i;
+    UINT32 X[16];
+    UINT32 a,b,c,d;
+
+    /* Prepare the message schedule, {X_i} */
+    NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
+    for (X_i = 0; X_i < 16; X_i++)
+        X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */
+        /* End of for */
+
+    /* MD5 hash computation */
+    /* Initialize the working variables */
+    a = pMD5_CTX->HashValue[0];
+    b = pMD5_CTX->HashValue[1];
+    c = pMD5_CTX->HashValue[2];
+    d = pMD5_CTX->HashValue[3];
+
+    /*
+     *  Round 1
+     *  Let [abcd k s i] denote the operation
+     *  a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND1(a, b, c, d, X[ 0],  7, 0xd76aa478); /* 1 */
+    ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */
+    ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */
+    ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */
+    ROUND1(a, b, c, d, X[ 4],  7, 0xf57c0faf); /* 5 */
+    ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */
+    ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */
+    ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */
+    ROUND1(a, b, c, d, X[ 8],  7, 0x698098d8); /* 9 */
+    ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */
+    ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */
+    ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */
+    ROUND1(a, b, c, d, X[12],  7, 0x6b901122); /* 13 */
+    ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */
+    ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */
+    ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */
+
+    /*
+     *  Round 2
+     *  Let [abcd k s i] denote the operation
+     *  a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND2(a, b, c, d, X[ 1],  5, 0xf61e2562); /* 17 */
+    ROUND2(d, a, b, c, X[ 6],  9, 0xc040b340); /* 18 */
+    ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */
+    ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */
+    ROUND2(a, b, c, d, X[ 5],  5, 0xd62f105d); /* 21 */
+    ROUND2(d, a, b, c, X[10],  9,  0x2441453); /* 22 */
+    ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */
+    ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */
+    ROUND2(a, b, c, d, X[ 9],  5, 0x21e1cde6); /* 25 */
+    ROUND2(d, a, b, c, X[14],  9, 0xc33707d6); /* 26 */
+    ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */
+    ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */
+    ROUND2(a, b, c, d, X[13],  5, 0xa9e3e905); /* 29 */
+    ROUND2(d, a, b, c, X[ 2],  9, 0xfcefa3f8); /* 30 */
+    ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */
+    ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */
+
+    /*
+     *  Round 3
+     *  Let [abcd k s t] denote the operation
+     *  a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND3(a, b, c, d, X[ 5],  4, 0xfffa3942); /* 33 */
+    ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */
+    ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */
+    ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */
+    ROUND3(a, b, c, d, X[ 1],  4, 0xa4beea44); /* 37 */
+    ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */
+    ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */
+    ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */
+    ROUND3(a, b, c, d, X[13],  4, 0x289b7ec6); /* 41 */
+    ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */
+    ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */
+    ROUND3(b, c, d, a, X[ 6], 23,  0x4881d05); /* 44 */
+    ROUND3(a, b, c, d, X[ 9],  4, 0xd9d4d039); /* 45 */
+    ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */
+    ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */
+    ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */
+
+    /*
+     *  Round 4
+     *  Let [abcd k s t] denote the operation
+     *  a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
+     */
+    ROUND4(a, b, c, d, X[ 0],  6, 0xf4292244); /* 49 */
+    ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */
+    ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */
+    ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */
+    ROUND4(a, b, c, d, X[12],  6, 0x655b59c3); /* 53 */
+    ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */
+    ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */
+    ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */
+    ROUND4(a, b, c, d, X[ 8],  6, 0x6fa87e4f); /* 57 */
+    ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */
+    ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */
+    ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */
+    ROUND4(a, b, c, d, X[ 4],  6, 0xf7537e82); /* 61 */
+    ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */
+    ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */
+    ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */
+
+    /* Compute the i^th intermediate hash value H^(i) */
+    pMD5_CTX->HashValue[0] += a;
+    pMD5_CTX->HashValue[1] += b;
+    pMD5_CTX->HashValue[2] += c;
+    pMD5_CTX->HashValue[3] += d;
+
+    NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
+    pMD5_CTX->BlockLen = 0;
+} /* End of MD5_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the MD5_Hash
+will be called.
+
+Arguments:
+    pMD5_CTX        Pointer to MD5_CTX_STRUC
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID MD5_Append (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen)
+{
+    UINT appendLen = 0;
+    UINT diffLen = 0;
+
+    while (appendLen != MessageLen) {
+        diffLen = MessageLen - appendLen;
+        if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
+            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+                Message + appendLen, diffLen);
+            pMD5_CTX->BlockLen += diffLen;
+            appendLen += diffLen;
+        }
+        else
+        {
+            NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
+                Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+            appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
+            pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
+            MD5_Hash(pMD5_CTX);
+        } /* End of if */
+    } /* End of while */
+    pMD5_CTX->MessageLen += MessageLen;
+} /* End of MD5_Append */
+
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pMD5_CTX        Pointer to MD5_CTX_STRUC
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID MD5_End (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    OUT UINT8 DigestMessage[])
+{
+    UINT index;
+    UINT64 message_length_bits;
+
+    /* append 1 bits to end of the message */
+    NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
+
+    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+    if (pMD5_CTX->BlockLen > 55)
+        MD5_Hash(pMD5_CTX);
+        /* End of if */
+
+    /* Append the length of message in rightmost 64 bits */
+    message_length_bits = pMD5_CTX->MessageLen*8;
+    message_length_bits = cpu2le64(message_length_bits);
+    NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
+    MD5_Hash(pMD5_CTX);
+
+    /* Return message digest, transform the UINT32 hash value to bytes */
+    for (index = 0; index < 4;index++)
+        pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]);
+        /* End of for */
+    NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
+} /* End of MD5_End */
+
+
+/*
+========================================================================
+Routine Description:
+    MD5 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID RT_MD5 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[])
+{
+    MD5_CTX_STRUC md5_ctx;
+
+    NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC));
+    MD5_Init(&md5_ctx);
+    MD5_Append(&md5_ctx, Message, MessageLen);
+    MD5_End(&md5_ctx, DigestMessage);
+} /* End of RT_MD5 */
+
+#endif /* MD5_SUPPORT */
+
+/* End of crypt_md5.c */
diff --git a/drivers/staging/rt3090/common/crypt_sha2.c b/drivers/staging/rt3090/common/crypt_sha2.c
new file mode 100644
index 0000000..c7490d0
--- /dev/null
+++ b/drivers/staging/rt3090/common/crypt_sha2.c
@@ -0,0 +1,536 @@
+/*
+ *************************************************************************
+ * 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 "../crypt_sha2.h"
+
+
+/* Basic operations */
+#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
+#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */
+#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */
+
+/* Basic functions */
+#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
+#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
+#define Parity(x,y,z) (x ^ y ^ z)
+
+#ifdef SHA1_SUPPORT
+/* SHA1 constants */
+#define SHA1_MASK 0x0000000f
+static const UINT32 SHA1_K[4] = {
+    0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
+};
+static const UINT32 SHA1_DefaultHashValue[5] = {
+    0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
+};
+#endif /* SHA1_SUPPORT */
+
+
+#ifdef SHA256_SUPPORT
+/* SHA256 functions */
+#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22))
+#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25))
+#define Sigma_256_0(x)  (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3))
+#define Sigma_256_1(x)  (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10))
+/* SHA256 constants */
+static const UINT32 SHA256_K[64] = {
+    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+    0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+    0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+    0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+    0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+    0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+    0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+    0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+    0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+    0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+    0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+    0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+    0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+static const UINT32 SHA256_DefaultHashValue[8] = {
+    0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL,
+    0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL
+};
+#endif /* SHA256_SUPPORT */
+
+
+#ifdef SHA1_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Initial SHA1_CTX_STRUC
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA1_Init (
+    IN  SHA1_CTX_STRUC *pSHA_CTX)
+{
+    NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
+        sizeof(SHA1_DefaultHashValue));
+    NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+    pSHA_CTX->MessageLen = 0;
+    pSHA_CTX->BlockLen   = 0;
+} /* End of SHA1_Init */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA1 computation for one block (512 bits)
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA1_Hash (
+    IN  SHA1_CTX_STRUC *pSHA_CTX)
+{
+    UINT32 W_i,t,s;
+    UINT32 W[16];
+    UINT32 a,b,c,d,e,T,f_t = 0;
+
+    /* Prepare the message schedule, {W_i}, 0 < t < 15 */
+    NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+    for (W_i = 0; W_i < 16; W_i++)
+        W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
+        /* End of for */
+
+    /* SHA256 hash computation */
+    /* Initialize the working variables */
+    a = pSHA_CTX->HashValue[0];
+    b = pSHA_CTX->HashValue[1];
+    c = pSHA_CTX->HashValue[2];
+    d = pSHA_CTX->HashValue[3];
+    e = pSHA_CTX->HashValue[4];
+
+    /* 80 rounds */
+    for (t = 0;t < 80;t++) {
+        s = t & SHA1_MASK;
+        if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */
+            W[s] = (W[(s+13) & SHA1_MASK]) ^ (W[(s+8) & SHA1_MASK]) ^ (W[(s+2) & SHA1_MASK]) ^ W[s];
+            W[s] = ROTL32(W[s],1);
+        } /* End of if */
+        switch (t / 20) {
+            case 0:
+                 f_t = Ch(b,c,d);
+                 break;
+            case 1:
+                 f_t = Parity(b,c,d);
+                 break;
+            case 2:
+                 f_t = Maj(b,c,d);
+                 break;
+            case 3:
+                 f_t = Parity(b,c,d);
+                 break;
+        } /* End of switch */
+        T = ROTL32(a,5) + f_t + e + SHA1_K[t / 20] + W[s];
+        e = d;
+        d = c;
+        c = ROTL32(b,30);
+        b = a;
+        a = T;
+     } /* End of for */
+
+     /* Compute the i^th intermediate hash value H^(i) */
+     pSHA_CTX->HashValue[0] += a;
+     pSHA_CTX->HashValue[1] += b;
+     pSHA_CTX->HashValue[2] += c;
+     pSHA_CTX->HashValue[3] += d;
+     pSHA_CTX->HashValue[4] += e;
+
+    NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
+    pSHA_CTX->BlockLen = 0;
+} /* End of SHA1_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the SHA1_Hash
+will be called.
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA1_Append (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen)
+{
+    UINT appendLen = 0;
+    UINT diffLen   = 0;
+
+    while (appendLen != MessageLen) {
+        diffLen = MessageLen - appendLen;
+        if ((pSHA_CTX->BlockLen + diffLen) <  SHA1_BLOCK_SIZE) {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, diffLen);
+            pSHA_CTX->BlockLen += diffLen;
+            appendLen += diffLen;
+        }
+        else
+        {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
+            SHA1_Hash(pSHA_CTX);
+        } /* End of if */
+    } /* End of while */
+    pSHA_CTX->MessageLen += MessageLen;
+} /* End of SHA1_Append */
+
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pSHA_CTX        Pointer to SHA1_CTX_STRUC
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA1_End (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[])
+{
+    UINT index;
+    UINT64 message_length_bits;
+
+    /* Append bit 1 to end of the message */
+    NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
+
+    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+    if (pSHA_CTX->BlockLen > 55)
+        SHA1_Hash(pSHA_CTX);
+        /* End of if */
+
+    /* Append the length of message in rightmost 64 bits */
+    message_length_bits = pSHA_CTX->MessageLen*8;
+    message_length_bits = cpu2be64(message_length_bits);
+    NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
+    SHA1_Hash(pSHA_CTX);
+
+    /* Return message digest, transform the UINT32 hash value to bytes */
+    for (index = 0; index < 5;index++)
+        pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
+        /* End of for */
+    NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
+} /* End of SHA1_End */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA1 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID RT_SHA1 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[])
+{
+
+    SHA1_CTX_STRUC sha_ctx;
+
+    NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC));
+    SHA1_Init(&sha_ctx);
+    SHA1_Append(&sha_ctx, Message, MessageLen);
+    SHA1_End(&sha_ctx, DigestMessage);
+} /* End of RT_SHA1 */
+#endif /* SHA1_SUPPORT */
+
+
+#ifdef SHA256_SUPPORT
+/*
+========================================================================
+Routine Description:
+    Initial SHA256_CTX_STRUC
+
+Arguments:
+    pSHA_CTX    Pointer to SHA256_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_Init (
+    IN  SHA256_CTX_STRUC *pSHA_CTX)
+{
+    NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue,
+        sizeof(SHA256_DefaultHashValue));
+    NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+    pSHA_CTX->MessageLen = 0;
+    pSHA_CTX->BlockLen   = 0;
+} /* End of SHA256_Init */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA256 computation for one block (512 bits)
+
+Arguments:
+    pSHA_CTX    Pointer to SHA256_CTX_STRUC
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_Hash (
+    IN  SHA256_CTX_STRUC *pSHA_CTX)
+{
+    UINT32 W_i,t;
+    UINT32 W[64];
+    UINT32 a,b,c,d,e,f,g,h,T1,T2;
+
+    /* Prepare the message schedule, {W_i}, 0 < t < 15 */
+    NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+    for (W_i = 0; W_i < 16; W_i++)
+        W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */
+        /* End of for */
+
+    /* SHA256 hash computation */
+    /* Initialize the working variables */
+    a = pSHA_CTX->HashValue[0];
+    b = pSHA_CTX->HashValue[1];
+    c = pSHA_CTX->HashValue[2];
+    d = pSHA_CTX->HashValue[3];
+    e = pSHA_CTX->HashValue[4];
+    f = pSHA_CTX->HashValue[5];
+    g = pSHA_CTX->HashValue[6];
+    h = pSHA_CTX->HashValue[7];
+
+    /* 64 rounds */
+    for (t = 0;t < 64;t++) {
+        if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */
+            W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16];
+            /* End of if */
+        T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t];
+        T2 = Zsigma_256_0(a) + Maj(a,b,c);
+        h = g;
+        g = f;
+        f = e;
+        e = d + T1;
+        d = c;
+        c = b;
+        b = a;
+        a = T1 + T2;
+     } /* End of for */
+
+     /* Compute the i^th intermediate hash value H^(i) */
+     pSHA_CTX->HashValue[0] += a;
+     pSHA_CTX->HashValue[1] += b;
+     pSHA_CTX->HashValue[2] += c;
+     pSHA_CTX->HashValue[3] += d;
+     pSHA_CTX->HashValue[4] += e;
+     pSHA_CTX->HashValue[5] += f;
+     pSHA_CTX->HashValue[6] += g;
+     pSHA_CTX->HashValue[7] += h;
+
+    NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE);
+    pSHA_CTX->BlockLen = 0;
+} /* End of SHA256_Hash */
+
+
+/*
+========================================================================
+Routine Description:
+    The message is appended to block. If block size > 64 bytes, the SHA256_Hash
+will be called.
+
+Arguments:
+    pSHA_CTX    Pointer to SHA256_CTX_STRUC
+    message     Message context
+    messageLen  The length of message in bytes
+
+Return Value:
+    None
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_Append (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen)
+{
+    UINT appendLen = 0;
+    UINT diffLen   = 0;
+
+    while (appendLen != MessageLen) {
+        diffLen = MessageLen - appendLen;
+        if ((pSHA_CTX->BlockLen + diffLen) <  SHA256_BLOCK_SIZE) {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, diffLen);
+            pSHA_CTX->BlockLen += diffLen;
+            appendLen += diffLen;
+        }
+        else
+        {
+            NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
+                Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen);
+            pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE;
+            SHA256_Hash(pSHA_CTX);
+        } /* End of if */
+    } /* End of while */
+    pSHA_CTX->MessageLen += MessageLen;
+} /* End of SHA256_Append */
+
+
+/*
+========================================================================
+Routine Description:
+    1. Append bit 1 to end of the message
+    2. Append the length of message in rightmost 64 bits
+    3. Transform the Hash Value to digest message
+
+Arguments:
+    pSHA_CTX        Pointer to SHA256_CTX_STRUC
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID SHA256_End (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[])
+{
+    UINT index;
+    UINT64 message_length_bits;
+
+    /* Append bit 1 to end of the message */
+    NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
+
+    /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
+    if (pSHA_CTX->BlockLen > 55)
+        SHA256_Hash(pSHA_CTX);
+        /* End of if */
+
+    /* Append the length of message in rightmost 64 bits */
+    message_length_bits = pSHA_CTX->MessageLen*8;
+    message_length_bits = cpu2be64(message_length_bits);
+    NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
+    SHA256_Hash(pSHA_CTX);
+
+    /* Return message digest, transform the UINT32 hash value to bytes */
+    for (index = 0; index < 8;index++)
+        pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]);
+        /* End of for */
+    NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE);
+} /* End of SHA256_End */
+
+
+/*
+========================================================================
+Routine Description:
+    SHA256 algorithm
+
+Arguments:
+    message         Message context
+    messageLen      The length of message in bytes
+
+Return Value:
+    digestMessage   Digest message
+
+Note:
+    None
+========================================================================
+*/
+VOID RT_SHA256 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[])
+{
+    SHA256_CTX_STRUC sha_ctx;
+
+    NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC));
+    SHA256_Init(&sha_ctx);
+    SHA256_Append(&sha_ctx, Message, MessageLen);
+    SHA256_End(&sha_ctx, DigestMessage);
+} /* End of RT_SHA256 */
+#endif /* SHA256_SUPPORT */
+
+/* End of crypt_sha2.c */
diff --git a/drivers/staging/rt3090/common/dfs.c b/drivers/staging/rt3090/common/dfs.c
new file mode 100644
index 0000000..c15704a
--- /dev/null
+++ b/drivers/staging/rt3090/common/dfs.c
@@ -0,0 +1,481 @@
+/*
+ *************************************************************************
+ * 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
+    --------  ----------      ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+typedef struct _RADAR_DURATION_TABLE
+{
+	ULONG RDDurRegion;
+	ULONG RadarSignalDuration;
+	ULONG Tolerance;
+} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
+
+
+
+UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
+{
+	{9, 250, 250, 250},		// CE
+#ifdef DFS_FCC_BW40_FIX
+	{1, 250, 250, 250},		// FCC
+#else
+	{4, 250, 250, 250},		// FCC
+#endif
+	{4, 250, 250, 250},		// JAP
+	{15, 250, 250, 250},	// JAP_W53
+	{4, 250, 250, 250}		// JAP_W56
+};
+
+#ifdef TONE_RADAR_DETECT_SUPPORT
+static void ToneRadarProgram(PRTMP_ADAPTER pAd);
+static void ToneRadarEnable(PRTMP_ADAPTER pAd);
+#endif // TONE_RADAR_DETECT_SUPPORT //
+
+#ifdef DFS_SUPPORT
+/*
+	========================================================================
+
+	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);
+
+#ifdef MERGE_ARCH_TEAM
+	if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56))
+	{
+		pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
+		pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd);
+		if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)
+		{
+			pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+		}
+		else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53)
+		{
+			pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
+		}
+#ifdef CARRIER_DETECTION_SUPPORT
+		pAd->CommonCfg.CarrierDetect.Enable = 1;
+#endif // CARRIER_DETECTION_SUPPORT //
+	}
+#endif // MERGE_ARCH_TEAM //
+
+	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;
+
+#ifdef MERGE_ARCH_TEAM
+
+
+#else // Original RT28xx source code.
+	RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
+	RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
+#endif // MERGE_ARCH_TEAM //
+
+	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 JAP:
+			{
+				UCHAR RDDurRegion;
+				RDDurRegion = JapRadarType(pAd);
+				if (RDDurRegion == JAP_W56)
+					CtsProtect = 0x03;
+				else
+					CtsProtect = 0x02;
+				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;
+}
+#endif // DFS_SUPPORT //
+
+
+/*
+	========================================================================
+
+	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)
+{
+	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;
+}
+
+#ifdef DFS_SUPPORT
+
+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;
+}
+#endif // DFS_SUPPORT //
+
+#ifdef DFS_SUPPORT
+/*
+    ==========================================================================
+    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 PSTRING arg)
+{
+	UINT8 Value;
+
+	Value = (UINT8) 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 PSTRING arg)
+{
+	UINT8 Value;
+
+	Value = (UINT8) 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;
+}
+#endif // DFS_SUPPORT //
diff --git a/drivers/staging/rt3090/common/ee_efuse.c b/drivers/staging/rt3090/common/ee_efuse.c
new file mode 100644
index 0000000..c51e305
--- /dev/null
+++ b/drivers/staging/rt3090/common/ee_efuse.c
@@ -0,0 +1,1548 @@
+/*
+ *************************************************************************
+ * 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:
+	ee_efuse.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+#define EFUSE_USAGE_MAP_START	0x2d0
+#define EFUSE_USAGE_MAP_END		0x2fc
+#define EFUSE_USAGE_MAP_SIZE	45
+
+
+
+#define EFUSE_EEPROM_DEFULT_FILE	"RT30xxEEPROM.bin"
+#define MAX_EEPROM_BIN_FILE_SIZE	1024
+
+
+
+#define EFUSE_TAG				0x2fe
+
+
+#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 //
+
+static UCHAR eFuseReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+static VOID eFuseReadPhysical(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUSHORT lpInBuffer,
+	IN	ULONG nInBufferSize,
+	OUT	PUSHORT lpOutBuffer,
+	IN	ULONG nOutBufferSize);
+
+static VOID eFusePhysicalWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+static NTSTATUS eFuseWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData);
+
+static VOID eFuseWritePhysical(
+	IN	PRTMP_ADAPTER	pAd,
+	PUSHORT lpInBuffer,
+	ULONG nInBufferSize,
+	PUCHAR lpOutBuffer,
+	ULONG nOutBufferSize);
+
+
+static NTSTATUS eFuseWriteRegistersFromBin(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData);
+
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	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, &eFuseCtrlStruc.word);
+
+	//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 < 500)
+	{
+		//rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		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 // RT_BIG_ENDIAN //
+
+		NdisMoveMemory(pData, &data, Length);
+	}
+
+	return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
+
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	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, &eFuseCtrlStruc.word);
+
+	//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 < 500)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		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 // RT_BIG_ENDIAN //
+
+	NdisMoveMemory(pData, &data, Length);
+
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static 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:
+
+	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:
+
+	Note:
+
+========================================================================
+*/
+static 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,  &eFuseCtrlStruc.word);
+
+	//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 < 500)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+		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.
+
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+	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 < 500)
+	{
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+
+		if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+			break;
+
+		RTMPusecDelay(2);
+		i++;
+	}
+}
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static NTSTATUS eFuseWriteRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	IN	USHORT* pData)
+{
+	USHORT	i,Loop=0;
+	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
+	{	Loop++;
+		//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&&Loop<2);
+	if(!bWriteSuccess)
+		DBGPRINT(RT_DEBUG_ERROR,("Efsue Write Failed!!\n"));
+	return TRUE;
+}
+
+
+/*
+========================================================================
+
+	Routine Description:
+
+	Arguments:
+
+	Return Value:
+
+	Note:
+
+========================================================================
+*/
+static 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 ...
+
+	DBGPRINT(RT_DEBUG_TRACE, ("eFuseWritePhysical Offset=0x%x, length=%d\n", Offset, Length));
+
+	{
+		// 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:
+
+	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:
+
+	Note:
+
+========================================================================
+*/
+INT set_eFuseGetFreeBlockCount_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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	PSTRING			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	PSTRING			arg)
+{
+	PSTRING					src;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osfsInfo;
+	INT						retval, memSize;
+	PSTRING					buffer, memPtr;
+	INT						i = 0,j=0,k=1;
+	USHORT					*PDATA;
+	USHORT					DATA;
+
+	memSize = 128 + MAX_EEPROM_BIN_FILE_SIZE + sizeof(USHORT) * 8;
+	memPtr = kmalloc(memSize, MEM_ALLOC_FLAG);
+	if (memPtr == NULL)
+		return FALSE;
+
+	NdisZeroMemory(memPtr, memSize);
+	src = memPtr; // kmalloc(128, MEM_ALLOC_FLAG);
+	buffer = src + 128;		// kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
+	PDATA = (USHORT*)(buffer + MAX_EEPROM_BIN_FILE_SIZE);	// kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
+
+	if(strlen(arg)>0)
+		NdisMoveMemory(src, arg, strlen(arg));
+	else
+		NdisMoveMemory(src, EFUSE_EEPROM_DEFULT_FILE, strlen(EFUSE_EEPROM_DEFULT_FILE));
+	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+
+	RtmpOSFSInfoChange(&osfsInfo, TRUE);
+
+	srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+	if (IS_FILE_OPEN_ERR(srcf))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening file %s\n", src));
+		retval = FALSE;
+		goto recoverFS;
+	}
+	else
+	{
+		// The object must have a read method
+		while(RtmpOSFileRead(srcf, &buffer[i], 1)==1)
+		{
+		i++;
+			if(i>MAX_EEPROM_BIN_FILE_SIZE)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("--> Error reading file %s, file size too large[>%d]\n", src, MAX_EEPROM_BIN_FILE_SIZE));
+				retval = FALSE;
+				goto closeFile;
+			}
+		}
+
+		retval = RtmpOSFileClose(srcf);
+		if (retval)
+			DBGPRINT(RT_DEBUG_TRACE, ("--> Error closing file %s\n", src));
+	}
+
+
+	RtmpOSFSInfoChange(&osfsInfo, FALSE);
+
+	for(j=0;j<i;j++)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]&0xff));
+		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);
+			}
+		}
+	}
+
+	return TRUE;
+
+closeFile:
+	if (srcf)
+		RtmpOSFileClose(srcf);
+
+recoverFS:
+	RtmpOSFSInfoChange(&osfsInfo, FALSE);
+
+
+	if (memPtr)
+		kfree(memPtr);
+
+	return retval;
+}
+
+
+static 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.
+		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
+		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, &eFuseCtrlStruc.word);
+
+		//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 < 500)
+		{
+			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;
+}
+
+
+int rtmp_ee_efuse_read16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	OUT USHORT *pValue)
+{
+	if(pAd->bFroceEEPROMBuffer || pAd->bEEPROMFile)
+	{
+	    DBGPRINT(RT_DEBUG_TRACE,  ("Read from EEPROM Buffer\n"));
+	    NdisMoveMemory(pValue, &(pAd->EEPROMImage[Offset]), 2);
+	}
+	else
+	    eFuseReadRegisters(pAd, Offset, 2, pValue);
+	return (*pValue);
+}
+
+
+int rtmp_ee_efuse_write16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	IN USHORT data)
+{
+    if(pAd->bFroceEEPROMBuffer||pAd->bEEPROMFile)
+    {
+        DBGPRINT(RT_DEBUG_TRACE,  ("Write to EEPROM Buffer\n"));
+        NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &data, 2);
+    }
+    else
+        eFuseWriteRegisters(pAd, Offset, 2, &data);
+	return 0;
+}
+
+
+int RtmpEfuseSupportCheck(
+	IN RTMP_ADAPTER *pAd)
+{
+	USHORT value;
+
+	if (IS_RT30xx(pAd))
+	{
+		eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
+		pAd->EFuseTag = (value & 0xff);
+	}
+	return 0;
+}
+
+INT set_eFuseBufferModeWriteBack_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UINT Enable;
+
+
+	if(strlen(arg)>0)
+	{
+		Enable= simple_strtol(arg, 0, 16);
+	}
+	else
+		return FALSE;
+	if(Enable==1)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("set_eFuseBufferMode_Proc:: Call WRITEEEPROMBUF"));
+		eFuseWriteEeeppromBuf(pAd);
+	}
+	else
+		return FALSE;
+	return TRUE;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		Load EEPROM from bin file for eFuse mode
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	Return Value:
+		NDIS_STATUS_SUCCESS         firmware image load ok
+		NDIS_STATUS_FAILURE         image not found
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+INT eFuseLoadEEPROM(
+	IN PRTMP_ADAPTER pAd)
+{
+	PSTRING					src = NULL;
+	INT						retval;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osFSInfo;
+
+
+	src=EFUSE_BUFFER_PATH;
+	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+
+
+	RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+	if (src && *src)
+	{
+		srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+		if (IS_FILE_OPEN_ERR(srcf))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+			return FALSE;
+		}
+		else
+		{
+
+				memset(pAd->EEPROMImage, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
+
+
+			retval =RtmpOSFileRead(srcf, (PSTRING)pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE);
+			if (retval > 0)
+							{
+				RTMPSetProfileParameters(pAd, (PSTRING)pAd->EEPROMImage);
+				retval = NDIS_STATUS_SUCCESS;
+			}
+			else
+				DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
+
+		}
+
+
+	}
+	else
+		{
+					DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
+					return FALSE;
+
+		}
+
+	retval=RtmpOSFileClose(srcf);
+
+	if (retval)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+	}
+
+
+	RtmpOSFSInfoChange(&osFSInfo, FALSE);
+
+	return TRUE;
+}
+
+INT eFuseWriteEeeppromBuf(
+	IN PRTMP_ADAPTER pAd)
+{
+
+	PSTRING					src = NULL;
+	INT						retval;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osFSInfo;
+
+
+	src=EFUSE_BUFFER_PATH;
+	DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+
+	RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+
+
+	if (src && *src)
+	{
+		srcf = RtmpOSFileOpen(src, O_WRONLY|O_CREAT, 0);
+
+		if (IS_FILE_OPEN_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->write)
+			{
+				// The object must have a read method
+                        srcf->f_op->write(srcf, pAd->EEPROMImage, 1024, &srcf->f_pos);
+
+			}
+			else
+			{
+						DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
+						return FALSE;
+			}
+*/
+
+			RtmpOSFileWrite(srcf, (PSTRING)pAd->EEPROMImage,MAX_EEPROM_BIN_FILE_SIZE);
+
+		}
+
+
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("--> Error src  or srcf is null\n"));
+		return FALSE;
+
+	}
+
+	retval=RtmpOSFileClose(srcf);
+
+	if (retval)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+	}
+
+	RtmpOSFSInfoChange(&osFSInfo, FALSE);
+	return TRUE;
+}
+
+
+VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd,
+	PUINT EfuseFreeBlock)
+{
+	USHORT i;
+	USHORT	LogicalAddress;
+	if(!pAd->bUseEfuse)
+		{
+		DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
+		return ;
+		}
+	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
+	{
+		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+		if( (LogicalAddress & 0xff) == 0)
+		{
+			*EfuseFreeBlock= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
+			break;
+		}
+		else if(( (LogicalAddress >> 8) & 0xff) == 0)
+		{
+			*EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END-i);
+			break;
+		}
+
+		if(i == EFUSE_USAGE_MAP_END)
+			*EfuseFreeBlock = 0;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is 0x%x\n",*EfuseFreeBlock));
+}
+
+INT eFuse_init(
+	IN PRTMP_ADAPTER pAd)
+{
+	UINT	EfuseFreeBlock=0;
+	DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and its size =%x[%x-%x] \n",EFUSE_USAGE_MAP_SIZE,EFUSE_USAGE_MAP_START,EFUSE_USAGE_MAP_END));
+	eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
+	//If the used block of efuse is less than 5. We assume the default value
+	// of this efuse is empty and change to the buffer mode in odrder to
+	//bring up interfaces successfully.
+	if(EfuseFreeBlock > (EFUSE_USAGE_MAP_END-5))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and the information is too less to bring up interface. Force to use EEPROM Buffer Mode\n"));
+		pAd->bFroceEEPROMBuffer = TRUE;
+		eFuseLoadEEPROM(pAd);
+	}
+	else
+		pAd->bFroceEEPROMBuffer = FALSE;
+	DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse and force to use EEPROM Buffer Mode=%x\n",pAd->bFroceEEPROMBuffer));
+
+	return 0;
+}
diff --git a/drivers/staging/rt3090/common/ee_prom.c b/drivers/staging/rt3090/common/ee_prom.c
new file mode 100644
index 0000000..051cfde
--- /dev/null
+++ b/drivers/staging/rt3090/common/ee_prom.c
@@ -0,0 +1,308 @@
+/*
+ *************************************************************************
+ * 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:
+	ee_prom.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+// IRQL = PASSIVE_LEVEL
+static inline 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
+static inline VOID LowerClock(
+    IN	PRTMP_ADAPTER	pAd,
+    IN  UINT32 *x)
+{
+	*x = *x & ~EESK;
+	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+	RTMPusecDelay(1);
+}
+
+// IRQL = PASSIVE_LEVEL
+static inline 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
+static inline 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
+static inline 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);
+}
+
+
+static inline 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);
+}
+
+
+static inline 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
+int rtmp_ee_prom_read16(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			Offset,
+	OUT USHORT			*pValue)
+{
+	UINT32		x;
+	USHORT		data;
+
+#ifdef RT30xx
+#ifdef ANT_DIVERSITY_SUPPORT
+	if (pAd->NicConfig2.field.AntDiversity)
+	{
+		pAd->EepromAccess = TRUE;
+	}
+#endif // ANT_DIVERSITY_SUPPORT //
+#endif // RT30xx //
+
+	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) || IS_RT3572(pAd) || IS_RT3390(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);
+
+#ifdef RT30xx
+#ifdef ANT_DIVERSITY_SUPPORT
+	// 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);
+	}
+#endif // ANT_DIVERSITY_SUPPORT //
+#endif // RT30xx //
+
+	*pValue = data;
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+int rtmp_ee_prom_write16(
+    IN  PRTMP_ADAPTER	pAd,
+    IN  USHORT Offset,
+    IN  USHORT Data)
+{
+	UINT32 x;
+
+#ifdef RT30xx
+#ifdef ANT_DIVERSITY_SUPPORT
+	if (pAd->NicConfig2.field.AntDiversity)
+	{
+		pAd->EepromAccess = TRUE;
+	}
+#endif // ANT_DIVERSITY_SUPPORT //
+#endif // RT30xx //
+
+	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) || IS_RT3572(pAd) || IS_RT3390(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);
+
+#ifdef RT30xx
+#ifdef ANT_DIVERSITY_SUPPORT
+	// 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);
+	}
+#endif // ANT_DIVERSITY_SUPPORT //
+#endif // RT30xx //
+
+	return NDIS_STATUS_SUCCESS;
+
+}
diff --git a/drivers/staging/rt3090/common/eeprom.c b/drivers/staging/rt3090/common/eeprom.c
new file mode 100644
index 0000000..2e83749
--- /dev/null
+++ b/drivers/staging/rt3090/common/eeprom.c
@@ -0,0 +1,98 @@
+/*
+ *************************************************************************
+ * 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"
+
+
+INT RtmpChipOpsEepromHook(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			infType)
+{
+	RTMP_CHIP_OP	*pChipOps = &pAd->chipOps;
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+	UINT32			eFuseCtrl, MacCsr0;
+	int index;
+
+	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);
+
+	pAd->bUseEfuse=FALSE;
+	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
+	pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
+	if(pAd->bUseEfuse)
+	{
+		pChipOps->eeinit = eFuse_init;
+		pChipOps->eeread = rtmp_ee_efuse_read16;
+		pChipOps->eewrite = rtmp_ee_efuse_write16;
+		return 0 ;
+	}
+	else
+	{
+		pAd->bFroceEEPROMBuffer = FALSE;
+		DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
+	}
+#endif // RTMP_EFUSE_SUPPORT //
+#endif // RT30xx //
+
+	switch(infType)
+	{
+#ifdef RTMP_PCI_SUPPORT
+		case RTMP_DEV_INF_PCI:
+			pChipOps->eeinit = NULL;
+			pChipOps->eeread = rtmp_ee_prom_read16;
+			pChipOps->eewrite = rtmp_ee_prom_write16;
+			break;
+#endif // RTMP_PCI_SUPPORT //
+
+
+		default:
+			DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
+			break;
+	}
+
+	return 0;
+}
diff --git a/drivers/staging/rt3090/common/igmp_snoop.c b/drivers/staging/rt3090/common/igmp_snoop.c
new file mode 100644
index 0000000..680658f
--- /dev/null
+++ b/drivers/staging/rt3090/common/igmp_snoop.c
@@ -0,0 +1,1365 @@
+/*
+ *************************************************************************
+ * 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 IGMP_SNOOP_SUPPORT
+
+#include "../rt_config.h"
+#include "../ipv6.h"
+#include "../igmp_snoop.h"
+
+
+static inline void initFreeEntryList(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PLIST_HEADER pList)
+{
+	int i;
+
+	for (i = 0; i < FREE_MEMBER_POOL_SIZE; i++)
+		insertTailList(pList, (PLIST_ENTRY)&(pMulticastFilterTable->freeMemberPool[i]));
+
+	return;
+}
+
+static inline PMEMBER_ENTRY AllocaGrpMemberEntry(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable)
+{
+	PMEMBER_ENTRY pMemberEntry;
+
+	RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+
+	pMemberEntry = (PMEMBER_ENTRY)removeHeadList(&pMulticastFilterTable->freeEntryList);
+
+	RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+
+	return (PMEMBER_ENTRY)pMemberEntry;
+}
+
+static inline VOID FreeGrpMemberEntry(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PMEMBER_ENTRY pEntry)
+{
+	RTMP_SEM_LOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+
+	insertTailList(&pMulticastFilterTable->freeEntryList, (PLIST_ENTRY)pEntry);
+
+	RTMP_SEM_UNLOCK(&pMulticastFilterTable->FreeMemberPoolTabLock);
+}
+
+static VOID IGMPTableDisplay(
+	IN PRTMP_ADAPTER pAd);
+
+static BOOLEAN isIgmpMacAddr(
+	IN PUCHAR pMacAddr);
+
+static VOID InsertIgmpMember(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PLIST_HEADER pList,
+	IN PUCHAR pMemberAddr);
+
+static VOID DeleteIgmpMember(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PLIST_HEADER pList,
+	IN PUCHAR pMemberAddr);
+
+static VOID DeleteIgmpMemberList(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PLIST_HEADER pList);
+
+
+/*
+    ==========================================================================
+    Description:
+        This routine init the entire IGMP table.
+    ==========================================================================
+ */
+VOID MulticastFilterTableInit(
+	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
+{
+	// Initialize MAC table and allocate spin lock
+	*ppMulticastFilterTable = kmalloc(sizeof(MULTICAST_FILTER_TABLE), MEM_ALLOC_FLAG);
+	if (*ppMulticastFilterTable == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for Multicase filter table, size=%d\n",
+			__FUNCTION__, sizeof(MULTICAST_FILTER_TABLE)));
+		return;
+	}
+
+	NdisZeroMemory(*ppMulticastFilterTable, sizeof(MULTICAST_FILTER_TABLE));
+	NdisAllocateSpinLock(&((*ppMulticastFilterTable)->MulticastFilterTabLock));
+
+	NdisAllocateSpinLock(&((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
+	initList(&((*ppMulticastFilterTable)->freeEntryList));
+	initFreeEntryList(*ppMulticastFilterTable, &((*ppMulticastFilterTable)->freeEntryList));
+	return;
+}
+
+/*
+    ==========================================================================
+    Description:
+        This routine reset the entire IGMP table.
+    ==========================================================================
+ */
+VOID MultiCastFilterTableReset(
+	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable)
+{
+	if(*ppMulticastFilterTable == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+		return;
+	}
+
+	NdisFreeSpinLock(&((*ppMulticastFilterTable)->FreeMemberPoolTabLock));
+	NdisFreeSpinLock(&((*ppMulticastFilterTable)->MulticastFilterTabLock));
+	kfree(*ppMulticastFilterTable);
+	*ppMulticastFilterTable = NULL;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Display all entrys in IGMP table
+    ==========================================================================
+ */
+static VOID IGMPTableDisplay(
+	IN PRTMP_ADAPTER pAd)
+{
+	int i;
+	MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
+	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+
+	if (pMulticastFilterTable == NULL)
+	{
+		DBGPRINT(RT_DEBUG_OFF, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+		return;
+	}
+
+	// if FULL, return
+	if (pMulticastFilterTable->Size == 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Table empty.\n"));
+		return;
+	}
+
+	// allocate one MAC entry
+	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+	for (i = 0; i< MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
+	{
+		// pick up the first available vacancy
+		if (pMulticastFilterTable->Content[i].Valid == TRUE)
+		{
+			PMEMBER_ENTRY pMemberEntry = NULL;
+			pEntry = &pMulticastFilterTable->Content[i];
+
+			DBGPRINT(RT_DEBUG_OFF, ("IF(%s) entry #%d, type=%s, GrpId=(%02x:%02x:%02x:%02x:%02x:%02x) memberCnt=%d\n",
+				RTMP_OS_NETDEV_GET_DEVNAME(pEntry->net_dev), i, (pEntry->type==0 ? "static":"dynamic"),
+				PRINT_MAC(pEntry->Addr), IgmpMemberCnt(&pEntry->MemberList)));
+
+			pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
+			while (pMemberEntry)
+			{
+				DBGPRINT(RT_DEBUG_OFF, ("member mac=(%02x:%02x:%02x:%02x:%02x:%02x)\n",
+										PRINT_MAC(pMemberEntry->Addr)));
+
+				pMemberEntry = pMemberEntry->pNext;
+			}
+		}
+	}
+
+	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+	return;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Add and new entry into MAC table
+    ==========================================================================
+ */
+BOOLEAN MulticastFilterTableInsertEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pGrpId,
+	IN PUCHAR pMemberAddr,
+	IN PNET_DEV dev,
+	IN MulticastFilterEntryType type)
+{
+	UCHAR HashIdx;
+	int i;
+	MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL, *pCurrEntry, *pPrevEntry;
+	PMEMBER_ENTRY pMemberEntry;
+	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+
+	if (pMulticastFilterTable == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+		return FALSE;
+	}
+
+	// if FULL, return
+	if (pMulticastFilterTable->Size >= MAX_LEN_OF_MULTICAST_FILTER_TABLE)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table full. max-entries = %d\n",
+			__FUNCTION__, MAX_LEN_OF_MULTICAST_FILTER_TABLE));
+		return FALSE;
+	}
+
+	// check the rule is in table already or not.
+	if ((pEntry = MulticastFilterTableLookup(pMulticastFilterTable, pGrpId, dev)))
+	{
+		// doesn't indicate member mac address.
+		if(pMemberAddr == NULL)
+		{
+			return FALSE;
+		}
+
+		pMemberEntry = (PMEMBER_ENTRY)pEntry->MemberList.pHead;
+
+		while (pMemberEntry)
+		{
+			if (MAC_ADDR_EQUAL(pMemberAddr, pMemberEntry->Addr))
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("%s: already in Members list.\n", __FUNCTION__));
+				return FALSE;
+			}
+
+			pMemberEntry = pMemberEntry->pNext;
+		}
+	}
+
+	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+	do
+	{
+		ULONG Now;
+		// the multicast entry already exist but doesn't include the member yet.
+		if (pEntry != NULL && pMemberAddr != NULL)
+		{
+			InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+			break;
+		}
+
+		// allocate one MAC entry
+		for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
+		{
+			// pick up the first available vacancy
+			pEntry = &pMulticastFilterTable->Content[i];
+			NdisGetSystemUpTime(&Now);
+			if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
+				&& ((Now - pEntry->lastTime) > IGMPMAC_TB_ENTRY_AGEOUT_TIME))
+			{
+				PMULTICAST_FILTER_TABLE_ENTRY pHashEntry;
+
+				HashIdx = MULTICAST_ADDR_HASH_INDEX(pEntry->Addr);
+				pHashEntry = pMulticastFilterTable->Hash[HashIdx];
+
+				if ((pEntry->net_dev == pHashEntry->net_dev)
+					&& MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
+				{
+					pMulticastFilterTable->Hash[HashIdx] = pHashEntry->pNext;
+					pMulticastFilterTable->Size --;
+					DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
+				} else
+				{
+					while (pHashEntry->pNext)
+					{
+						pPrevEntry = pHashEntry;
+						pHashEntry = pHashEntry->pNext;
+						if ((pEntry->net_dev == pHashEntry->net_dev)
+							&& MAC_ADDR_EQUAL(pEntry->Addr, pHashEntry->Addr))
+						{
+							pPrevEntry->pNext = pHashEntry->pNext;
+							pMulticastFilterTable->Size --;
+							DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+							break;
+						}
+					}
+				}
+				pEntry->Valid = FALSE;
+				DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+			}
+
+			if (pEntry->Valid == FALSE)
+			{
+				NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+				pEntry->Valid = TRUE;
+
+				COPY_MAC_ADDR(pEntry->Addr, pGrpId);
+				pEntry->net_dev = dev;
+				NdisGetSystemUpTime(&Now);
+				pEntry->lastTime = Now;
+				pEntry->type = type;
+				initList(&pEntry->MemberList);
+				if (pMemberAddr != NULL)
+					InsertIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+
+				pMulticastFilterTable->Size ++;
+
+				DBGPRINT(RT_DEBUG_TRACE, ("MulticastFilterTableInsertEntry -IF(%s) allocate entry #%d, Total= %d\n", RTMP_OS_NETDEV_GET_DEVNAME(dev), i, pMulticastFilterTable->Size));
+				break;
+			}
+		}
+
+		// add this MAC entry into HASH table
+		if (pEntry)
+		{
+			HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
+			if (pMulticastFilterTable->Hash[HashIdx] == NULL)
+			{
+				pMulticastFilterTable->Hash[HashIdx] = pEntry;
+			} else
+			{
+				pCurrEntry = pMulticastFilterTable->Hash[HashIdx];
+				while (pCurrEntry->pNext != NULL)
+					pCurrEntry = pCurrEntry->pNext;
+				pCurrEntry->pNext = pEntry;
+			}
+		}
+	}while(FALSE);
+
+	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Delete a specified client from MAC table
+    ==========================================================================
+ */
+BOOLEAN MulticastFilterTableDeleteEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pGrpId,
+	IN PUCHAR pMemberAddr,
+	IN PNET_DEV dev)
+{
+	USHORT HashIdx;
+	MULTICAST_FILTER_TABLE_ENTRY *pEntry, *pPrevEntry;
+	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+	USHORT Aid = MCAST_WCID;
+	SST	Sst = SST_ASSOC;
+	UCHAR PsMode = PWR_ACTIVE, Rate;
+
+	if (pMulticastFilterTable == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+		return FALSE;
+	}
+
+	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+	do
+	{
+		HashIdx = MULTICAST_ADDR_HASH_INDEX(pGrpId);
+		pPrevEntry = pEntry = pMulticastFilterTable->Hash[HashIdx];
+
+		while (pEntry && pEntry->Valid)
+		{
+			if ((pEntry->net_dev ==  dev)
+				&& MAC_ADDR_EQUAL(pEntry->Addr, pGrpId))
+				break;
+			else
+			{
+				pPrevEntry = pEntry;
+				pEntry = pEntry->pNext;
+			}
+		}
+
+		// check the rule is in table already or not.
+		if (pEntry && (pMemberAddr != NULL))
+		{
+			if(APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate))
+				DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+			if (IgmpMemberCnt(&pEntry->MemberList) > 0)
+				break;
+		}
+
+		if (pEntry)
+		{
+			if (pEntry == pMulticastFilterTable->Hash[HashIdx])
+			{
+				pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
+				DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+				NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+				pMulticastFilterTable->Size --;
+				DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 1 - Total= %d\n", pMulticastFilterTable->Size));
+			}
+			else
+			{
+				pPrevEntry->pNext = pEntry->pNext;
+				DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+				NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+				pMulticastFilterTable->Size --;
+				DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+			}
+		}
+		else
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: the Group doesn't exist.\n", __FUNCTION__));
+		}
+	} while(FALSE);
+
+	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        Look up the MAC address in the IGMP table. Return NULL if not found.
+    Return:
+        pEntry - pointer to the MAC entry; NULL is not found
+    ==========================================================================
+*/
+PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PUCHAR pAddr,
+	IN PNET_DEV dev)
+{
+	ULONG HashIdx, Now;
+	PMULTICAST_FILTER_TABLE_ENTRY pEntry = NULL, pPrev = NULL;
+
+	if (pMulticastFilterTable == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s Multicase filter table is not ready.\n", __FUNCTION__));
+		return NULL;
+	}
+
+	RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+	HashIdx = MULTICAST_ADDR_HASH_INDEX(pAddr);
+	pEntry = pPrev = pMulticastFilterTable->Hash[HashIdx];
+
+	while (pEntry && pEntry->Valid)
+	{
+		if ((pEntry->net_dev ==  dev)
+			&& MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+		{
+			NdisGetSystemUpTime(&Now);
+			pEntry->lastTime = Now;
+			break;
+		}
+		else
+		{
+			NdisGetSystemUpTime(&Now);
+			if ((pEntry->Valid == TRUE) && (pEntry->type == MCAT_FILTER_DYNAMIC)
+				&& RTMP_TIME_AFTER(Now, pEntry->lastTime+IGMPMAC_TB_ENTRY_AGEOUT_TIME))
+			{
+				// Remove the aged entry
+				if (pEntry == pMulticastFilterTable->Hash[HashIdx])
+				{
+					pMulticastFilterTable->Hash[HashIdx] = pEntry->pNext;
+					pPrev = pMulticastFilterTable->Hash[HashIdx];
+					DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+					NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+					pMulticastFilterTable->Size --;
+					pEntry = pPrev;
+					DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+				}
+				else
+				{
+					pPrev->pNext = pEntry->pNext;
+					DeleteIgmpMemberList(pMulticastFilterTable, &pEntry->MemberList);
+					NdisZeroMemory(pEntry, sizeof(MULTICAST_FILTER_TABLE_ENTRY));
+					pMulticastFilterTable->Size --;
+					pEntry = (pPrev == NULL ? NULL: pPrev->pNext);
+					DBGPRINT(RT_DEBUG_TRACE, ("MCastFilterTableDeleteEntry 2 - Total= %d\n", pMulticastFilterTable->Size));
+				}
+			}
+			else
+			{
+				pPrev = pEntry;
+				pEntry = pEntry->pNext;
+			}
+		}
+	}
+
+	RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+
+	return pEntry;
+}
+
+VOID IGMPSnooping(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pSrcMacAddr,
+	IN PUCHAR pIpHeader,
+	IN PNET_DEV pDev)
+{
+	INT i;
+	INT IpHeaderLen;
+	UCHAR GroupType;
+	UINT16 numOfGroup;
+	UCHAR IgmpVerType;
+	PUCHAR pIgmpHeader;
+	PUCHAR pGroup;
+	UCHAR AuxDataLen;
+	UINT16 numOfSources;
+	PUCHAR pGroupIpAddr;
+	UCHAR GroupMacAddr[6];
+	PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
+
+	if(isIgmpPkt(pDstMacAddr, pIpHeader))
+	{
+		IpHeaderLen = (*(pIpHeader + 2) & 0x0f) * 4;
+		pIgmpHeader = pIpHeader + 2 + IpHeaderLen;
+		IgmpVerType = (UCHAR)(*(pIgmpHeader));
+
+		DBGPRINT(RT_DEBUG_TRACE, ("IGMP type=%0x\n", IgmpVerType));
+
+		switch(IgmpVerType)
+		{
+		case IGMP_V1_MEMBERSHIP_REPORT: // IGMP version 1 membership report.
+		case IGMP_V2_MEMBERSHIP_REPORT: // IGMP version 2 membership report.
+			pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
+				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+			DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+				GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+			MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+			break;
+
+		case IGMP_LEAVE_GROUP: // IGMP version 1 and version 2 leave group.
+			pGroupIpAddr = (PUCHAR)(pIgmpHeader + 4);
+				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+			DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+				GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+			MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+			break;
+
+		case IGMP_V3_MEMBERSHIP_REPORT: // IGMP version 3 membership report.
+			numOfGroup = ntohs(*((UINT16 *)(pIgmpHeader + 6)));
+			pGroup = (PUCHAR)(pIgmpHeader + 8);
+			for (i=0; i < numOfGroup; i++)
+			{
+				GroupType = (UCHAR)(*pGroup);
+				AuxDataLen = (UCHAR)(*(pGroup + 1));
+				numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
+				pGroupIpAddr = (PUCHAR)(pGroup + 4);
+				DBGPRINT(RT_DEBUG_TRACE, ("IGMPv3 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources));
+					ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+				DBGPRINT(RT_DEBUG_TRACE, ("IGMP Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+					GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+
+				do
+				{
+					if((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES))
+					{
+						MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+						break;
+					}
+
+					if((GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES))
+					{
+						MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+						break;
+					}
+
+					if((GroupType == CHANGE_TO_INCLUDE_MODE))
+					{
+						if(numOfSources == 0)
+							MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+						else
+							MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+						break;
+					}
+				} while(FALSE);
+				pGroup += (8 + (numOfSources * 4) + AuxDataLen);
+			}
+			break;
+
+		default:
+			DBGPRINT(RT_DEBUG_TRACE, ("unknow IGMP Type=%d\n", IgmpVerType));
+			break;
+		}
+	}
+
+	return;
+}
+
+
+static BOOLEAN isIgmpMacAddr(
+	IN PUCHAR pMacAddr)
+{
+	if((pMacAddr[0] == 0x01)
+		&& (pMacAddr[1] == 0x00)
+		&& (pMacAddr[2] == 0x5e))
+		return TRUE;
+	return FALSE;
+}
+
+BOOLEAN isIgmpPkt(
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pIpHeader)
+{
+	UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
+	UCHAR IgmpProtocol;
+
+	if(!isIgmpMacAddr(pDstMacAddr))
+		return FALSE;
+
+	if(IpProtocol == ETH_P_IP)
+	{
+		IgmpProtocol = (UCHAR)*(pIpHeader + 11);
+		if(IgmpProtocol == IGMP_PROTOCOL_DESCRIPTOR)
+				return TRUE;
+	}
+
+	return FALSE;
+}
+
+static VOID InsertIgmpMember(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PLIST_HEADER pList,
+	IN PUCHAR pMemberAddr)
+{
+	PMEMBER_ENTRY pMemberEntry;
+
+	if(pList == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+		return;
+	}
+
+	if (pMemberAddr == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
+		return;
+	}
+
+	if((pMemberEntry = (PMEMBER_ENTRY)AllocaGrpMemberEntry(pMulticastFilterTable)) != NULL)
+	{
+		NdisZeroMemory(pMemberEntry, sizeof(MEMBER_ENTRY));
+		COPY_MAC_ADDR(pMemberEntry->Addr, pMemberAddr);
+		insertTailList(pList, (PLIST_ENTRY)pMemberEntry);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("%s Member Mac=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__,
+			pMemberEntry->Addr[0], pMemberEntry->Addr[1], pMemberEntry->Addr[2],
+			pMemberEntry->Addr[3], pMemberEntry->Addr[4], pMemberEntry->Addr[5]));
+	}
+	return;
+}
+
+static VOID DeleteIgmpMember(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PLIST_HEADER pList,
+	IN PUCHAR pMemberAddr)
+{
+	PMEMBER_ENTRY pCurEntry;
+
+	if((pList == NULL) || (pList->pHead == NULL))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+		return;
+	}
+
+	if (pMemberAddr == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: invalid member.\n", __FUNCTION__));
+		return;
+	}
+
+	pCurEntry = (PMEMBER_ENTRY)pList->pHead;
+	while (pCurEntry)
+	{
+		if(MAC_ADDR_EQUAL(pMemberAddr, pCurEntry->Addr))
+		{
+			delEntryList(pList, (PLIST_ENTRY)pCurEntry);
+			FreeGrpMemberEntry(pMulticastFilterTable, pCurEntry);
+			break;
+		}
+		pCurEntry = pCurEntry->pNext;
+	}
+
+	return;
+}
+
+static VOID DeleteIgmpMemberList(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PLIST_HEADER pList)
+{
+	PMEMBER_ENTRY pCurEntry, pPrvEntry;
+
+	if((pList == NULL) || (pList->pHead == NULL))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+		return;
+	}
+
+	pPrvEntry = pCurEntry = (PMEMBER_ENTRY)pList->pHead;
+	while (pCurEntry)
+	{
+		delEntryList(pList, (PLIST_ENTRY)pCurEntry);
+		pPrvEntry = pCurEntry;
+		pCurEntry = pCurEntry->pNext;
+		FreeGrpMemberEntry(pMulticastFilterTable, pPrvEntry);
+	}
+
+	initList(pList);
+	return;
+}
+
+
+UCHAR IgmpMemberCnt(
+	IN PLIST_HEADER pList)
+{
+	if(pList == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: membert list doesn't exist.\n", __FUNCTION__));
+		return 0;
+	}
+
+	return getListSize(pList);
+}
+
+VOID IgmpGroupDelMembers(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pMemberAddr,
+	IN PNET_DEV pDev)
+{
+	INT i;
+	MULTICAST_FILTER_TABLE_ENTRY *pEntry = NULL;
+	PMULTICAST_FILTER_TABLE pMulticastFilterTable = pAd->pMulticastFilterTable;
+
+	for (i = 0; i < MAX_LEN_OF_MULTICAST_FILTER_TABLE; i++)
+	{
+		// pick up the first available vacancy
+		pEntry = &pMulticastFilterTable->Content[i];
+		if (pEntry->Valid == TRUE)
+		{
+			if(pMemberAddr != NULL)
+			{
+				RTMP_SEM_LOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+				DeleteIgmpMember(pMulticastFilterTable, &pEntry->MemberList, pMemberAddr);
+				RTMP_SEM_UNLOCK(&pMulticastFilterTable->MulticastFilterTabLock);
+			}
+
+			if((pEntry->type == MCAT_FILTER_DYNAMIC)
+				&& (IgmpMemberCnt(&pEntry->MemberList) == 0))
+				MulticastFilterTableDeleteEntry(pAd, pEntry->Addr, pMemberAddr, pDev);
+		}
+	}
+}
+
+INT Set_IgmpSn_Enable_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg)
+{
+	UINT Enable;
+	POS_COOKIE pObj;
+	UCHAR ifIndex;
+	PNET_DEV pDev;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	ifIndex = pObj->ioctl_if;
+
+	pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
+	Enable = (UINT) simple_strtol(arg, 0, 10);
+
+	pAd->ApCfg.MBSSID[ifIndex].IgmpSnoopEnable = (BOOLEAN)(Enable == 0 ? 0 : 1);
+	DBGPRINT(RT_DEBUG_TRACE, ("%s::(%s) %s\n", __FUNCTION__, RTMP_OS_NETDEV_GET_DEVNAME(pDev), Enable == TRUE ? "Enable IGMP Snooping":"Disable IGMP Snooping"));
+
+	return TRUE;
+}
+
+INT Set_IgmpSn_AddEntry_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg)
+{
+	INT i;
+	BOOLEAN bGroupId = 1;
+	PSTRING value;
+	PSTRING thisChar;
+	UCHAR IpAddr[4];
+	UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+	UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
+	PUCHAR *pAddr = (PUCHAR *)&Addr;
+	PNET_DEV pDev;
+	POS_COOKIE pObj;
+	UCHAR ifIndex;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	ifIndex = pObj->ioctl_if;
+
+	pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
+
+	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+	{
+		// refuse the Member if it's not a MAC address.
+		if((bGroupId == 0) && (strlen(thisChar) != 17))
+			continue;
+
+		if(strlen(thisChar) == 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+		{
+			for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
+			{
+				if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+					return FALSE;  //Invalid
+
+				AtoH(value, &Addr[i++], 1);
+			}
+
+			if(i != 6)
+				return FALSE;  //Invalid
+		}
+		else
+		{
+			for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
+			{
+				if((strlen(value) > 0) && (strlen(value) <= 3))
+				{
+					int ii;
+					for(ii=0; ii<strlen(value); ii++)
+						if (!isxdigit(*(value + ii)))
+							return FALSE;
+				}
+				else
+					return FALSE;  //Invalid
+
+				IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
+				i++;
+			}
+
+			if(i != 4)
+				return FALSE;  //Invalid
+
+			ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
+		}
+
+		if(bGroupId == 1)
+			COPY_MAC_ADDR(GroupId, Addr);
+
+		// Group-Id must be a MCAST address.
+		if((bGroupId == 1) && IS_MULTICAST_MAC_ADDR(Addr))
+			MulticastFilterTableInsertEntry(pAd, GroupId, NULL, pDev, MCAT_FILTER_STATIC);
+		// Group-Member must be a UCAST address.
+		else if ((bGroupId == 0) && !IS_MULTICAST_MAC_ADDR(Addr))
+			MulticastFilterTableInsertEntry(pAd, GroupId, Addr, pDev, MCAT_FILTER_STATIC);
+		else
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X) is not a acceptable address.\n",
+				__FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
+			return FALSE;
+		}
+
+		bGroupId = 0;
+		DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
+			__FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
+
+	}
+
+	return TRUE;
+}
+
+INT Set_IgmpSn_DelEntry_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg)
+{
+	INT i, memberCnt = 0;
+	BOOLEAN bGroupId = 1;
+	PSTRING value;
+	PSTRING thisChar;
+	UCHAR IpAddr[4];
+	UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+	UCHAR GroupId[ETH_LENGTH_OF_ADDRESS];
+	PUCHAR *pAddr = (PUCHAR *)&Addr;
+	PNET_DEV pDev;
+	POS_COOKIE pObj;
+	UCHAR ifIndex;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	ifIndex = pObj->ioctl_if;
+
+	pDev = (ifIndex == MAIN_MBSSID) ? (pAd->net_dev) : (pAd->ApCfg.MBSSID[ifIndex].MSSIDDev);
+
+	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+	{
+		// refuse the Member if it's not a MAC address.
+		if((bGroupId == 0) && (strlen(thisChar) != 17))
+			continue;
+
+		if(strlen(thisChar) == 17)  //Mac address acceptable format 01:02:03:04:05:06 length 17
+		{
+			for (i=0, value = rstrtok(thisChar,":"); value; value = rstrtok(NULL,":"))
+			{
+				if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+					return FALSE;  //Invalid
+
+				AtoH(value, &Addr[i++], 1);
+			}
+
+			if(i != 6)
+				return FALSE;  //Invalid
+		}
+		else
+		{
+			for (i=0, value = rstrtok(thisChar,"."); value; value = rstrtok(NULL,"."))
+			{
+				if((strlen(value) > 0) && (strlen(value) <= 3))
+				{
+					int ii;
+					for(ii=0; ii<strlen(value); ii++)
+						if (!isxdigit(*(value + ii)))
+							return FALSE;
+				}
+				else
+					return FALSE;  //Invalid
+
+				IpAddr[i] = (UCHAR)simple_strtol(value, NULL, 10);
+				i++;
+			}
+
+			if(i != 4)
+				return FALSE;  //Invalid
+
+			ConvertMulticastIP2MAC(IpAddr, (PUCHAR *)&pAddr, ETH_P_IP);
+		}
+
+		if(bGroupId == 1)
+			COPY_MAC_ADDR(GroupId, Addr);
+		else
+			memberCnt++;
+
+		if (memberCnt > 0 )
+			MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, Addr, pDev);
+
+		bGroupId = 0;
+	}
+
+	if(memberCnt == 0)
+		MulticastFilterTableDeleteEntry(pAd, (PUCHAR)GroupId, NULL, pDev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s (%2X:%2X:%2X:%2X:%2X:%2X)\n",
+		__FUNCTION__, Addr[0], Addr[1], Addr[2], Addr[3], Addr[4], Addr[5]));
+
+	return TRUE;
+}
+
+INT Set_IgmpSn_TabDisplay_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg)
+{
+	IGMPTableDisplay(pAd);
+	return TRUE;
+}
+
+void rtmp_read_igmp_snoop_from_file(
+	IN  PRTMP_ADAPTER pAd,
+	PSTRING tmpbuf,
+	PSTRING buffer)
+{
+	PSTRING		macptr;
+	INT			i=0;
+
+	//IgmpSnEnable
+	if(RTMPGetKeyParameter("IgmpSnEnable", tmpbuf, 128, buffer, TRUE))
+	{
+		for (i = 0, macptr = rstrtok(tmpbuf,";"); (macptr && i < pAd->ApCfg.BssidNum); macptr = rstrtok(NULL,";"), i++)
+		{
+			if ((strncmp(macptr, "0", 1) == 0))
+				pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = FALSE;
+			else if ((strncmp(macptr, "1", 1) == 0))
+				pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = TRUE;
+	        else
+				pAd->ApCfg.MBSSID[i].IgmpSnoopEnable = FALSE;
+
+			DBGPRINT(RT_DEBUG_TRACE, ("MBSSID[%d].Enable=%d\n", i, pAd->ApCfg.MBSSID[i].IgmpSnoopEnable));
+	    }
+	}
+}
+
+NDIS_STATUS IgmpPktInfoQuery(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pSrcBufVA,
+	IN PNDIS_PACKET pPacket,
+	IN UCHAR apidx,
+	OUT BOOLEAN *pInIgmpGroup,
+	OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry)
+{
+	if(IS_MULTICAST_MAC_ADDR(pSrcBufVA))
+	{
+		BOOLEAN IgmpMldPkt = FALSE;
+		PUCHAR pIpHeader = pSrcBufVA + 12;
+
+		if(ntohs(*((UINT16 *)(pIpHeader))) == ETH_P_IPV6)
+			IgmpMldPkt = isMldPkt(pSrcBufVA, pIpHeader, NULL, NULL);
+		else
+			IgmpMldPkt = isIgmpPkt(pSrcBufVA, pIpHeader);
+
+		if (IgmpMldPkt)
+		{
+			*ppGroupEntry = NULL;
+		}
+		else if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pSrcBufVA,
+									pAd->ApCfg.MBSSID[apidx].MSSIDDev)) == NULL)
+		{
+			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+			return NDIS_STATUS_FAILURE;
+		}
+		*pInIgmpGroup = TRUE;
+	}
+	else if (IS_BROADCAST_MAC_ADDR(pSrcBufVA))
+	{
+		PUCHAR pDstIpAddr = pSrcBufVA + 30; // point to Destination of Ip address of IP header.
+		UCHAR GroupMacAddr[6];
+		PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
+
+		ConvertMulticastIP2MAC(pDstIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IP);
+		if ((*ppGroupEntry = MulticastFilterTableLookup(pAd->pMulticastFilterTable, pGroupMacAddr,
+								pAd->ApCfg.MBSSID[apidx].MSSIDDev)) != NULL)
+		{
+			*pInIgmpGroup = TRUE;
+		}
+	}
+	return NDIS_STATUS_SUCCESS;
+}
+
+NDIS_STATUS IgmpPktClone(
+	IN PRTMP_ADAPTER pAd,
+	IN PNDIS_PACKET pPacket,
+	IN UCHAR QueIdx,
+	IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry)
+{
+	PNDIS_PACKET pSkbClone = NULL;
+	PMEMBER_ENTRY pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead;
+	MAC_TABLE_ENTRY *pMacEntry = NULL;
+	USHORT Aid;
+	SST	Sst = SST_ASSOC;
+	UCHAR PsMode = PWR_ACTIVE;
+	UCHAR Rate;
+	unsigned long IrqFlags;
+
+	// check all members of the IGMP group.
+	while(pMemberEntry != NULL)
+	{
+		pMacEntry = APSsPsInquiry(pAd, pMemberEntry->Addr, &Sst, &Aid, &PsMode, &Rate);
+
+		if (pMacEntry && (Sst == SST_ASSOC) && (PsMode != PWR_SAVE))
+		{
+		pSkbClone = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
+		if(pSkbClone)
+		{
+				RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)Aid);
+				// Pkt type must set to PKTSRC_NDIS.
+				// It cause of the deason that APHardTransmit()
+				// doesn't handle PKTSRC_DRIVER pkt type in version 1.3.0.0.
+				RTMP_SET_PACKET_SOURCE(pSkbClone, PKTSRC_NDIS);
+			}
+			else
+			{
+				pMemberEntry = pMemberEntry->pNext;
+				continue;
+			}
+
+			// insert the pkt to TxSwQueue.
+			if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
+			{
+#ifdef BLOCK_NET_IF
+				StopNetIfQueue(pAd, QueIdx, pSkbClone);
+#endif // BLOCK_NET_IF //
+				RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE);
+				return NDIS_STATUS_FAILURE;
+			}
+			else
+			{
+				RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+				InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone));
+				RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+			}
+		}
+		pMemberEntry = pMemberEntry->pNext;
+	}
+	return NDIS_STATUS_SUCCESS;
+}
+
+static inline BOOLEAN isMldMacAddr(
+	IN PUCHAR pMacAddr)
+{
+	return ((pMacAddr[0] == 0x33) && (pMacAddr[1] == 0x33)) ? TRUE : FALSE;
+}
+
+static inline BOOLEAN IsSupportedMldMsg(
+	IN UINT8 MsgType)
+{
+	BOOLEAN result = FALSE;
+	switch(MsgType)
+	{
+		case MLD_V1_LISTENER_REPORT:
+		case MLD_V1_LISTENER_DONE:
+		case MLD_V2_LISTERNER_REPORT:
+			result = TRUE;
+			break;
+		default:
+			result = FALSE;
+			break;
+	}
+
+	return result;
+}
+
+BOOLEAN isMldPkt(
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pIpHeader,
+	OUT UINT8 *pProtoType,
+	OUT PUCHAR *pMldHeader)
+{
+	BOOLEAN result = FALSE;
+	UINT16 IpProtocol = ntohs(*((UINT16 *)(pIpHeader)));
+
+	if(!isMldMacAddr(pDstMacAddr))
+		return FALSE;
+
+	if(IpProtocol != ETH_P_IPV6)
+		return FALSE;
+
+	// skip protocol (2 Bytes).
+	pIpHeader += 2;
+	do
+	{
+		PRT_IPV6_HDR pIpv6Hdr = (PRT_IPV6_HDR)(pIpHeader);
+		UINT8 nextProtocol = pIpv6Hdr->nextHdr;
+		UINT32 offset = IPV6_HDR_LEN;
+
+		while(nextProtocol != IPV6_NEXT_HEADER_ICMPV6)
+		{
+			if(IPv6ExtHdrHandle((RT_IPV6_EXT_HDR *)(pIpHeader + offset), &nextProtocol, &offset) == FALSE)
+				break;
+		}
+
+		if(nextProtocol == IPV6_NEXT_HEADER_ICMPV6)
+		{
+			PRT_ICMPV6_HDR pICMPv6Hdr = (PRT_ICMPV6_HDR)(pIpHeader + offset);
+			if (IsSupportedMldMsg(pICMPv6Hdr->type) == TRUE)
+			{
+				if (pProtoType != NULL)
+					*pProtoType = pICMPv6Hdr->type;
+				if (pMldHeader != NULL)
+					*pMldHeader = (PUCHAR)pICMPv6Hdr;
+				result = TRUE;
+			}
+		}
+	}while(FALSE);
+
+	return result;
+}
+
+/*  MLD v1 messages have the following format:
+	0                   1                   2                   3
+	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|     Type      |     Code      |          Checksum             |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|     Maximum Response Delay    |          Reserved             |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                                                               |
+	+                                                               +
+	|                                                               |
+	+                       Multicast Address                       +
+	|                                                               |
+	+                                                               +
+	|                                                               |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+/*	Version 3 Membership Report Message
+	0                   1                   2                   3
+	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|  Type = 143   |    Reserved   |           Checksum            |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|           Reserved            |  Number of Group Records (M)  |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                                                               |
+	.                                                               .
+	.               Multicast Address Record [1]                    .
+	.                                                               .
+	|                                                               |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                                                               |
+	.                                                               .
+	.               Multicast Address Record [2]                    .
+	.                                                               .
+	|                                                               |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                               .                               |
+	.                               .                               .
+	|                               .                               |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|                                                               |
+	.                                                               .
+	.               Multicast Address Record [M]                    .
+	.                                                               .
+	|                                                               |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+	where each Group Record has the following internal format:
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	|  Record Type  |  Aux Data Len |     Number of Sources (N)     |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    *                                                               *
+    |                                                               |
+    *                       Multicast Address                       *
+    |                                                               |
+    *                                                               *
+    |                                                               |
+	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    *                                                               *
+    |                                                               |
+    *                       Source Address [1]                      *
+    |                                                               |
+    *                                                               *
+    |                                                               |
+    +-                                                             -+
+    |                                                               |
+    *                                                               *
+    |                                                               |
+    *                       Source Address [2]                      *
+    |                                                               |
+    *                                                               *
+    |                                                               |
+    +-                                                             -+
+    .                               .                               .
+    .                               .                               .
+    .                               .                               .
+    +-                                                             -+
+    |                                                               |
+    *                                                               *
+    |                                                               |
+    *                       Source Address [N]                      *
+    |                                                               |
+    *                                                               *
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    .                                                               .
+    .                         Auxiliary Data                        .
+    .                                                               .
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+
+VOID MLDSnooping(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pSrcMacAddr,
+	IN PUCHAR pIpHeader,
+	IN PNET_DEV pDev)
+{
+	INT i;
+	UCHAR GroupType;
+	UINT16 numOfGroup;
+	PUCHAR pGroup;
+	UCHAR AuxDataLen;
+	UINT16 numOfSources;
+	PUCHAR pGroupIpAddr;
+	UCHAR GroupMacAddr[6];
+	PUCHAR pGroupMacAddr = (PUCHAR)&GroupMacAddr;
+
+	UINT8 MldType;
+	PUCHAR pMldHeader;
+
+	if(isMldPkt(pDstMacAddr, pIpHeader, &MldType, &pMldHeader) == TRUE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("MLD type=%0x\n", MldType));
+
+		switch(MldType)
+		{
+			case MLD_V1_LISTENER_REPORT:
+				// skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes).
+				pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
+				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
+				DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
+						GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+				MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+				break;
+
+			case MLD_V1_LISTENER_DONE:
+				// skip Type(1 Byte), code(1 Byte), checksum(2 Bytes), Maximum Rsp Delay(2 Bytes), Reserve(2 Bytes).
+				pGroupIpAddr = (PUCHAR)(pMldHeader + 8);
+				ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
+				DBGPRINT(RT_DEBUG_TRACE, ("Group Id=%02x:%02x:%02x:%02x:%02x:%02x\n",
+						GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+				MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+				break;
+
+			case MLD_V2_LISTERNER_REPORT: // IGMP version 3 membership report.
+				numOfGroup = ntohs(*((UINT16 *)(pMldHeader + 6)));
+				pGroup = (PUCHAR)(pMldHeader + 8);
+				for (i=0; i < numOfGroup; i++)
+				{
+					GroupType = (UCHAR)(*pGroup);
+					AuxDataLen = (UCHAR)(*(pGroup + 1));
+					numOfSources = ntohs(*((UINT16 *)(pGroup + 2)));
+					pGroupIpAddr = (PUCHAR)(pGroup + 4);
+					DBGPRINT(RT_DEBUG_TRACE, ("MLDv2 Type=%d, ADL=%d, numOfSource=%d\n", GroupType, AuxDataLen, numOfSources));
+					ConvertMulticastIP2MAC(pGroupIpAddr, (PUCHAR *)&pGroupMacAddr, ETH_P_IPV6);
+					DBGPRINT(RT_DEBUG_TRACE, ("MLD Group=%02x:%02x:%02x:%02x:%02x:%02x\n",
+							GroupMacAddr[0], GroupMacAddr[1], GroupMacAddr[2], GroupMacAddr[3], GroupMacAddr[4], GroupMacAddr[5]));
+
+					do
+					{
+						if((GroupType == MODE_IS_EXCLUDE) || (GroupType == CHANGE_TO_EXCLUDE_MODE) || (GroupType == ALLOW_NEW_SOURCES))
+						{
+							MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+							break;
+						}
+
+						if((GroupType == MODE_IS_INCLUDE) || (GroupType == BLOCK_OLD_SOURCES))
+						{
+							MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+							break;
+						}
+
+						if((GroupType == CHANGE_TO_INCLUDE_MODE))
+						{
+							if(numOfSources == 0)
+								MulticastFilterTableDeleteEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev);
+							else
+								MulticastFilterTableInsertEntry(pAd, GroupMacAddr, pSrcMacAddr, pDev, MCAT_FILTER_DYNAMIC);
+							break;
+						}
+					} while(FALSE);
+					// skip 4 Bytes (Record Type, Aux Data Len, Number of Sources) + a IPv6 address.
+					pGroup += (4 + IPV6_ADDR_LEN + (numOfSources * 16) + AuxDataLen);
+				}
+				break;
+
+			default:
+				DBGPRINT(RT_DEBUG_TRACE, ("unknow MLD Type=%d\n", MldType));
+				break;
+		}
+	}
+
+	return;
+}
+
+
+#endif // IGMP_SNOOP_SUPPORT //
diff --git a/drivers/staging/rt3090/common/mlme.c b/drivers/staging/rt3090/common/mlme.c
new file mode 100644
index 0000000..1613c04
--- /dev/null
+++ b/drivers/staging/rt3090/common/mlme.c
@@ -0,0 +1,6550 @@
+/*
+ *************************************************************************
+ * 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)
+    0x0c, 0x0a,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 25, 45,
+    0x03, 0x21,  0, 20, 35,
+    0x04, 0x21,  1, 20, 35,
+    0x05, 0x21,  2, 20, 35,
+    0x06, 0x21,  3, 15, 35,
+    0x07, 0x21,  4, 15, 30,
+    0x08, 0x21,  5, 10, 25,
+    0x09, 0x21,  6,  8, 14,
+    0x0a, 0x21,  7,  8, 14,
+    0x0b, 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)
+    0x0e, 0x0c,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 25, 45,
+    0x03, 0x21,  0, 20, 35,
+    0x04, 0x21,  1, 20, 35,
+    0x05, 0x21,  2, 20, 35,
+    0x06, 0x21,  3, 15, 35,
+    0x07, 0x21,  4, 15, 30,
+    0x08, 0x20, 11, 15, 30,
+    0x09, 0x20, 12, 15, 30,
+    0x0a, 0x20, 13,  8, 20,
+    0x0b, 0x20, 14,  8, 20,
+    0x0c, 0x20, 15,  8, 25,
+    0x0d, 0x22, 15,  8, 15,
+};
+
+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)
+    0x0b, 0x00,  0,  0,  0,	// 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, 11, 15, 30,	// Required by System-Alan @ 20080812
+    0x06, 0x20, 12, 15, 30,	// 0x05, 0x20, 12, 15, 30,
+    0x07, 0x20, 13,  8, 20,	// 0x06, 0x20, 13,  8, 20,
+    0x08, 0x20, 14,  8, 20,	// 0x07, 0x20, 14,  8, 20,
+    0x09, 0x20, 15,  8, 25,	// 0x08, 0x20, 15,  8, 25,
+    0x0a, 0x22, 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)
+    0x0c, 0x0a,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 25, 45,
+    0x03, 0x21,  0, 20, 35,
+    0x04, 0x21,  1, 20, 35,
+    0x05, 0x21,  2, 20, 35,
+    0x06, 0x21,  3, 15, 35,
+    0x07, 0x21,  4, 15, 30,
+    0x08, 0x21,  5, 10, 25,
+    0x09, 0x21,  6,  8, 14,
+    0x0a, 0x21,  7,  8, 14,
+    0x0b, 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)
+    0x0e, 0x0c,  0,  0,  0,						// Initial used item after association
+    0x00, 0x00,  0, 40, 101,
+    0x01, 0x00,  1, 40, 50,
+    0x02, 0x00,  2, 25, 45,
+    0x03, 0x21,  0, 20, 35,
+    0x04, 0x21,  1, 20, 35,
+    0x05, 0x21,  2, 20, 35,
+    0x06, 0x21,  3, 15, 35,
+    0x07, 0x21,  4, 15, 30,
+    0x08, 0x20, 11, 15, 30,
+    0x09, 0x20, 12, 15, 30,
+    0x0a, 0x20, 13,  8, 20,
+    0x0b, 0x20, 14,  8, 20,
+    0x0c, 0x20, 15,  8, 25,
+    0x0d, 0x22, 15,  8, 15,
+};
+
+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,
+    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,
+};
+
+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 //
+
+
+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 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};
+
+
+/*
+	==========================================================================
+	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);
+
+#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 //
+
+
+		WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine, pAd->Mlme.WpaFunc);
+
+
+		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
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+#ifdef RTMP_PCI_SUPPORT
+			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+			{
+			    // only PCIe cards need these two timers
+				RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
+				RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
+			}
+#endif // RTMP_PCI_SUPPORT //
+
+			RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, GET_TIMER_FUNCTION(LinkDownExec), pAd, FALSE);
+
+		}
+#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;
+#ifdef APCLI_SUPPORT
+	SHORT apcliIfIndex;
+#endif // APCLI_SUPPORT //
+
+	// 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))
+		{
+
+			// 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 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;
+
+				case WPA_STATE_MACHINE:
+					StateMachinePerformAction(pAd, &pAd->Mlme.WpaMachine, 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;
+
+	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 RTMP_MAC_PCI
+	    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
+			&&(pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+	    {
+		    RTMPCancelTimer(&pAd->Mlme.PsPollTimer,		&Cancelled);
+		    RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,		&Cancelled);
+		}
+#endif // RTMP_MAC_PCI //
+
+#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 //
+		RTMPCancelTimer(&pAd->Mlme.LinkDownTimer,		&Cancelled);
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer,		&Cancelled);
+	RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer,		&Cancelled);
+
+
+
+	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+	{
+		RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
+		// Set LED
+		RTMPSetLED(pAd, LED_HALT);
+		RTMPSetSignalLED(pAd, -100);	// Force signal strength Led to be turned off, firmware is not done it.
+
+		if (pChipOps->AsicHaltAction)
+			pChipOps->AsicHaltAction(pAd);
+	}
+
+	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;
+	pAd->RalinkCounters.OneSecReceivedByteCount = 0;
+	pAd->RalinkCounters.OneSecTransmittedByteCount = 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;
+}
+
+
+/*
+	==========================================================================
+	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;
+	SHORT	realavgrssi;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef RTMP_MAC_PCI
+	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) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+			/*&&(pAd->bPCIclkOff == FALSE)*/)
+		{
+			UINT32				data = 0;
+
+			// Read GPIO pin2 as Hardware controlled radio state
+#ifndef RT3090
+			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+#endif // RT3090 //
+//KH(PCIE PS):Added based on Jane<--
+#ifdef RT3090
+// Read GPIO pin2 as Hardware controlled radio state
+// We need to Read GPIO if HW said so no mater what advance power saving
+if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
+	&& (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
+	&& (pAd->StaCfg.PSControl.field.EnablePSinIdle == TRUE))
+	{
+	// Want to make sure device goes to L0 state before reading register.
+	RTMPPCIeLinkCtrlValueRestore(pAd, 0);
+	RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
+	RTMPPCIeLinkCtrlSetting(pAd, 3);
+	}
+else
+	RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
+#endif // RT3090 //
+//KH(PCIE PS):Added based on Jane-->
+
+			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)
+				{
+					MlmeRadioOn(pAd);
+					// Update extra information
+					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+				}
+				else
+				{
+					MlmeRadioOff(pAd);
+					// Update extra information
+					pAd->ExtraInfo = HW_RADIO_OFF;
+				}
+			}
+		}
+	}
+#endif // RTMP_MAC_PCI //
+#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;
+
+	RTMP_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 ++;
+
+
+	// 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 //
+
+
+
+		//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 DOT11_N_SUPPORT
+		// Need statistics after read counter. So put after NICUpdateRawCounters
+		ORIBATimerTimeout(pAd);
+#endif // DOT11_N_SUPPORT //
+
+		// if MGMT RING is full more than twice within 1 second, we consider there's
+		// a hardware problem stucking the TX path. In this case, try a hardware reset
+		// to recover the system
+	//	if (pAd->RalinkCounters.MgmtRingFullCount >= 2)
+	//		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR);
+	//	else
+	//		pAd->RalinkCounters.MgmtRingFullCount = 0;
+
+		// The time period for checking antenna is according to traffic
+#ifdef ANT_DIVERSITY_SUPPORT
+		if ((pAd->NicConfig2.field.AntDiversity) &&
+			(pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_ENABLE) &&
+			(!pAd->EepromAccess))
+			AsicAntennaSelect(pAd, pAd->MlmeAux.Channel);
+		else if(pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT1 || pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT2)
+		{
+#ifdef CONFIG_STA_SUPPORT
+			realavgrssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
+#endif // CONFIG_STA_SUPPORT //
+			DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
+		}
+		else
+#endif // ANT_DIVERSITY_SUPPORT //
+		{
+			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)
+		{
+#ifdef RTMP_MAC_PCI
+			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
+#endif // RTMP_MAC_PCI //
+			{
+			// 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 //
+
+		RTMP_MLME_HANDLER(pAd);
+	}
+
+
+	pAd->bUpdateBcnCntDone = FALSE;
+}
+
+
+/*
+	==========================================================================
+	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) || (pAd->OpMode == OPMODE_STA)) && (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) || (pAd->OpMode == OPMODE_STA)) && (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 || pAd->CommonCfg.PhyMode==PHY_11B)
+#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
+VOID STAMlmePeriodicExec(
+	PRTMP_ADAPTER pAd)
+{
+	ULONG			    TxTotalCnt;
+	int	i;
+
+
+
+
+	/*
+		We return here in ATE mode, because the statistics
+		that ATE need are not collected via this routine.
+	*/
+#ifdef RALINK_ATE
+	if (ATE_ON(pAd))
+	return;
+#endif // RALINK_ATE //
+
+#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 PCIE_PS_SUPPORT
+// don't perform idle-power-save mechanism within 3 min after driver initialization.
+// This can make rebooter test more robust
+if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+	{
+	if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
+		&& (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
+		&& (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+		&& (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+		{
+		if (IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd))
+			{
+			if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+				{
+				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
+
+				RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
+				}
+			else
+				{
+				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
+				AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x2);
+				// Wait command success
+				AsicCheckCommanOk(pAd, PowerSafeCID);
+				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+				DBGPRINT(RT_DEBUG_TRACE, ("PSM - rt30xx Issue Sleep command)\n"));
+				}
+			}
+		else if (pAd->Mlme.OneSecPeriodicRound > 180)
+			{
+			if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+				{
+				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
+				RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
+				}
+			else
+				{
+				DBGPRINT(RT_DEBUG_TRACE, ("%s::%d\n",__FUNCTION__,__LINE__));
+				AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x02);
+				// Wait command success
+				AsicCheckCommanOk(pAd, PowerSafeCID);
+				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+				DBGPRINT(RT_DEBUG_TRACE, ("PSM -  rt28xx Issue Sleep command)\n"));
+				}
+			}
+		}
+	else
+		{
+		DBGPRINT(RT_DEBUG_TRACE,("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n",
+			pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid[0], pAd->CommonCfg.Ssid[1], pAd->CommonCfg.Ssid[2], pAd->CommonCfg.Ssid[3],
+			pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1], pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3]));
+		}
+	}
+#endif // PCIE_PS_SUPPORT //
+
+
+#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 &&
+			RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastMicErrorTime + (60*OS_HZ)))
+		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;
+	}
+
+
+
+
+	if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd))
+	{
+	}
+	else
+	{
+	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, NULL, 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 ((RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + (1*OS_HZ))) &&
+			(!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));
+
+			// Lost AP, send disconnect & link down event
+			LinkDown(pAd, FALSE);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+		//send disassociate event to wpa_supplicant
+		if (pAd->StaCfg.WpaSupplicantUP) {
+			RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
+		}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+		RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+#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);
+		}
+
+		if (pAd->StaCfg.bAutoRoaming)
+		{
+			BOOLEAN	rv = FALSE;
+			CHAR	dBmToRoam = pAd->StaCfg.dBmToRoam;
+			CHAR	MaxRssi = RTMPMaxRssi(pAd,
+										  pAd->StaCfg.RssiSample.LastRssi0,
+										  pAd->StaCfg.RssiSample.LastRssi1,
+										  pAd->StaCfg.RssiSample.LastRssi2);
+
+			// Scanning, ignore Roaming
+			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) &&
+				(pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
+				(MaxRssi <= dBmToRoam))
+			{
+				DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", MaxRssi, (CHAR)dBmToRoam));
+
+
+				// Add auto seamless roaming
+				if (rv == FALSE)
+					rv = MlmeCheckForFastRoaming(pAd);
+
+				if (rv == FALSE)
+				{
+					if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
+					{
+						DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
+						pAd->StaCfg.ScanCnt = 2;
+						pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+						MlmeAutoScan(pAd);
+					}
+				}
+			}
+		}
+	}
+	else if (ADHOC_ON(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 (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME) &&
+			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, (CHAR *)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 (RTMP_TIME_AFTER(pAd->Mlme.Now32, pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
+				MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+		}
+	}
+	else // no INFRA nor ADHOC connection
+	{
+
+		if (pAd->StaCfg.bScanReqIsFromWebUI &&
+			RTMP_TIME_BEFORE(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
+			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 (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (10 * OS_HZ)))
+				{
+					DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
+					ScanParmFill(pAd, &ScanReq, (PSTRING) 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;
+
+	if (pAd != NULL)
+	{
+		MLME_DISASSOC_REQ_STRUCT   DisassocReq;
+
+		if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
+			(INFRA_ON(pAd)))
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("LinkDownExec(): 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;
+
+			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,
+					pAd->MlmeAux.AutoReconnectSsidLen,
+					pAd->MlmeAux.AutoReconnectSsid);
+		RTMP_MLME_HANDLER(pAd);
+	}
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeAutoReconnectLastSSID(
+	IN PRTMP_ADAPTER pAd)
+{
+	if (pAd->StaCfg.bAutoConnectByBssid)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n",
+									pAd->MlmeAux.Bssid[0],
+									pAd->MlmeAux.Bssid[1],
+									pAd->MlmeAux.Bssid[2],
+									pAd->MlmeAux.Bssid[3],
+									pAd->MlmeAux.Bssid[4],
+									pAd->MlmeAux.Bssid[5]));
+
+		pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
+		MlmeEnqueue(pAd,
+			 MLME_CNTL_STATE_MACHINE,
+			 OID_802_11_BSSID,
+			 MAC_ADDR_LEN,
+			 pAd->MlmeAux.Bssid);
+
+		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+		RTMP_MLME_HANDLER(pAd);
+	}
+	// check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+	else 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);
+		RTMP_MLME_HANDLER(pAd);
+	}
+}
+
+
+/*
+	==========================================================================
+	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 + pAd->StaCfg.BeaconLostTime) < 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);
+			RTMP_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:
+	==========================================================================
+ */
+BOOLEAN MlmeCheckForFastRoaming(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	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;
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+	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);
+			RTMP_MLME_HANDLER(pAd);
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+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 = FALSE, 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;
+	RSSI_SAMPLE				*pRssi = &pAd->StaCfg.RssiSample;
+
+#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,
+							   pRssi->AvgRssi0,
+							   pRssi->AvgRssi1,
+							   pRssi->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,
+								   pRssi->AvgRssi0,
+								   pRssi->AvgRssi1,
+								   pRssi->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;
+		}
+
+		if (TxTotalCnt)
+		{
+			/*
+				Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
+				We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
+			*/
+			if (TxErrorRatio == 100)
+			{
+				TX_RTY_CFG_STRUC	TxRtyCfg,TxRtyCfgtmp;
+				ULONG	Index;
+				ULONG	MACValue;
+
+				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+				TxRtyCfgtmp.word = TxRtyCfg.word;
+				TxRtyCfg.field.LongRtyLimit = 0x0;
+				TxRtyCfg.field.ShortRtyLimit = 0x0;
+				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
+
+				RTMPusecDelay(1);
+
+				Index = 0;
+				MACValue = 0;
+				do
+				{
+					RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+					if ((MACValue & 0xffffff) == 0)
+						break;
+					Index++;
+					RTMPusecDelay(1000);
+				}while((Index < 330)&&(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)));
+
+				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
+				TxRtyCfg.field.LongRtyLimit = TxRtyCfgtmp.field.LongRtyLimit;
+				TxRtyCfg.field.ShortRtyLimit = TxRtyCfgtmp.field.ShortRtyLimit;
+				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
+			}
+		}
+
+		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,  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)*/)	//we hope to use ShortGI as initial rate
+				else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))	//we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI
+				{
+					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 = MCS23;
+				else if (MCS22 && (Rssi >= -72))
+					TxRateIdx = MCS22;
+		    else if (MCS21 && (Rssi >= -76))
+					TxRateIdx = MCS21;
+				else if (MCS20 && (Rssi >= -78))
+					TxRateIdx = MCS20;
+			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;
+
+		{
+			UCHAR tmpTxRate;
+
+			// to fix tcp ack issue
+			if (!bTxRateChanged && (pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5)))
+			{
+				tmpTxRate = DownRateIdx;
+				DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
+					pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount, pEntry->CurrTxRateIndex, tmpTxRate));
+			}
+			else
+			{
+				tmpTxRate = pEntry->CurrTxRateIndex;
+			}
+
+			pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*5];
+			if (bTxRateChanged && pNextTxRate)
+			{
+				MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+			}
+		}
+		// reset all OneSecTx counters
+		RESET_ONE_SEC_TX_CNT(pEntry);
+	}
+}
+
+/*
+	========================================================================
+	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
+	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)&&
+		RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
+		 /*&&
+		(pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+		(pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
+	{
+		NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
+		pAd->RalinkCounters.RxCountSinceLastNULL = 0;
+		RTMP_SET_PSM_BIT(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);
+	DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+	==========================================================================
+	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 PMAC_TABLE_ENTRY pMacEntry,
+	IN ULONG Now32)
+{
+	ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
+	ULONG RxCnt, RxPER;
+	UCHAR NorRssi;
+	CHAR  MaxRssi;
+	RSSI_SAMPLE *pRssiSample = NULL;
+	UINT32 OneSecTxNoRetryOkCount = 0;
+	UINT32 OneSecTxRetryOkCount = 0;
+	UINT32 OneSecTxFailCount = 0;
+	UINT32 OneSecRxOkCnt = 0;
+	UINT32 OneSecRxFcsErrCnt = 0;
+	ULONG ChannelQuality = 0;  // 0..100, Channel Quality Indication for Roaming
+#ifdef CONFIG_STA_SUPPORT
+	ULONG BeaconLostTime = pAd->StaCfg.BeaconLostTime;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+	// longer beacon lost time when carrier detection enabled
+	if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+	{
+		BeaconLostTime = pAd->StaCfg.BeaconLostTime + (pAd->StaCfg.BeaconLostTime/2);
+	}
+#endif // CARRIER_DETECTION_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+	if (pAd->OpMode == OPMODE_STA)
+	{
+		pRssiSample = &pAd->StaCfg.RssiSample;
+		OneSecTxNoRetryOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount;
+		OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
+		OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
+		OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
+		OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
+								pRssiSample->LastRssi1,
+								pRssiSample->LastRssi2);
+
+	//
+	// calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
+	//
+	TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
+	TxCnt = TxOkCnt + OneSecTxFailCount;
+	if (TxCnt < 5)
+	{
+		TxPER = 0;
+		TxPRR = 0;
+	}
+	else
+	{
+		TxPER = (OneSecTxFailCount * 100) / TxCnt;
+		TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
+	}
+
+	//
+	// calculate RX PER - don't take RxPER into consideration if too few sample
+	//
+	RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
+	if (RxCnt < 5)
+		RxPER = 0;
+	else
+		RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
+
+	//
+	// decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
+	//
+#ifdef CONFIG_STA_SUPPORT
+	if ((pAd->OpMode == OPMODE_STA) &&
+		INFRA_ON(pAd) &&
+		(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));
+		ChannelQuality = 0;
+	}
+	else
+#endif // CONFIG_STA_SUPPORT //
+	{
+		// 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)
+		ChannelQuality = (RSSI_WEIGHTING * NorRssi +
+								   TX_WEIGHTING * (100 - TxPRR) +
+								   RX_WEIGHTING* (100 - RxPER)) / 100;
+	}
+
+
+#ifdef CONFIG_STA_SUPPORT
+	if (pAd->OpMode == OPMODE_STA)
+		pAd->Mlme.ChannelQuality = (ChannelQuality > 100) ? 100 : ChannelQuality;
+#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 (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;
+	}
+
+#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);
+
+	// bug fix
+	// pAd->CommonCfg.BasicRateBitmap = 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);
+
+	if (pDesireHtPhy->MCSSet[4] != 0)
+	{
+		pMaxHtPhy->field.MCS = 32;
+	}
+
+	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"));
+}
+
+
+VOID BATableInit(
+	IN PRTMP_ADAPTER pAd,
+    IN BA_TABLE *Tab)
+{
+	int i;
+
+	Tab->numAsOriginator = 0;
+	Tab->numAsRecipient = 0;
+	Tab->numDoneOriginator = 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 //
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOff(
+	IN PRTMP_ADAPTER pAd)
+{
+	RTMP_MLME_RADIO_OFF(pAd);
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOn(
+	IN PRTMP_ADAPTER pAd)
+{
+	RTMP_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
+	}
+}
+
+
+/*! \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;
+}
+
+
+ULONG BssSsidTableSearchBySSID(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR	 pSsid,
+	IN UCHAR	 SsidLen)
+{
+	UCHAR i;
+
+	for (i = 0; i < Tab->BssNr; i++)
+	{
+		if (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, 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);
+	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,  (UCHAR *)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) &&
+						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+						(pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
+						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->WPA.GroupCipher) &&
+						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+						(pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
+						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:
+				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:
+						pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
+						break;
+					case 5:
+						pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
+						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-enterprise mode
+						if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+							pBss->AuthMode = Ndis802_11AuthModeWPA;
+						else
+							pBss->AuthModeAux = Ndis802_11AuthModeWPA;
+						break;
+					case 2:
+						// Set AP support WPA-PSK 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;
+					// Patched bugs for old driver
+					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:
+						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
+						break;
+					case 5:
+						pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
+						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
+				// Parsing all AKM ciphers
+				while (Count > 0)
+				{
+					pAKM = (PAKM_SUITE_STRUCT) pTmp;
+					if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+						break;
+
+					switch (pAKM->Type)
+					{
+						case 1:
+							// Set AP support WPA-enterprise mode
+							if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+								pBss->AuthMode = Ndis802_11AuthModeWPA2;
+							else
+								pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
+							break;
+						case 2:
+							// Set AP support WPA-PSK mode
+							if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+								pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
+							else
+								pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
+							break;
+						default:
+							if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+								pBss->AuthMode = Ndis802_11AuthModeMax;
+							else
+								pBss->AuthModeAux = Ndis802_11AuthModeMax;
+							break;
+					}
+					pTmp   += (Count * sizeof(AKM_SUITE_STRUCT));
+					Count--;
+				}
+
+				// 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;
+					// Patched bugs for old driver
+					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 UCHAR *Buffer,
+	OUT ULONG *FrameLen, ...)
+{
+	UCHAR   *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));
+
+	RTMP_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 RTMP_MAC_PCI
+	MLME_QUEUE_ELEM		*Elem = NULL;
+#endif // RTMP_MAC_PCI //
+#ifdef CONFIG_STA_SUPPORT
+	BOOLEAN				Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
+
+#ifdef RTMP_MAC_PCI
+	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+	if(pAd->Mlme.bRunning)
+	{
+		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+		return;
+	}
+	else
+	{
+		pAd->Mlme.bRunning = TRUE;
+	}
+	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+
+	// Remove all Mlme queues elements
+	while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
+	{
+		//From message type, determine which state machine I should drive
+		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
+		{
+			// free MLME element
+			Elem->Occupied = FALSE;
+			Elem->MsgLen = 0;
+
+		}
+		else {
+			DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
+		}
+	}
+#endif // RTMP_MAC_PCI //
+
+#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 //
+
+#ifdef RTMP_MAC_PCI
+	// Remove running state
+	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+	pAd->Mlme.bRunning = FALSE;
+	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+#endif // RTMP_MAC_PCI //
+}
+
+/*! \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, Alg;
+	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)
+	{
+		{
+	        *Machine = WPA_STATE_MACHINE;
+			EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+	        return (WpaMsgTypeSubst(EAPType, (INT *) 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));
+			NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT));
+			if (Seq == 1 || Seq == 3)
+			{
+				*Machine = AUTH_RSP_STATE_MACHINE;
+				*MsgType = MT2_PEER_AUTH_ODD;
+			}
+			else if (Seq == 2 || Seq == 4)
+			{
+				if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY)
+				{
+					*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;
+}
+
+
+/*
+	========================================================================
+
+	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;
+}
+
+
+/*
+    ========================================================================
+    Routine Description:
+        Periodic evaluate antenna link status
+
+    Arguments:
+        pAd         - Adapter pointer
+
+    Return Value:
+        None
+
+    ========================================================================
+*/
+VOID AsicEvaluateRxAnt(
+	IN PRTMP_ADAPTER	pAd)
+{
+#ifdef CONFIG_STA_SUPPORT
+	UCHAR	BBPR3 = 0;
+#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		|
+							fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
+							OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT3090
+							|| (pAd->bPCIclkOff == TRUE)
+#endif // RT3090 //
+#ifdef ANT_DIVERSITY_SUPPORT
+							|| (pAd->EepromAccess)
+#endif // ANT_DIVERSITY_SUPPORT //
+							)
+		return;
+
+#ifdef ANT_DIVERSITY_SUPPORT
+	if ((pAd->NicConfig2.field.AntDiversity) && (pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_ENABLE))
+	{
+		// 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
+			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
+#endif // ANT_DIVERSITY_SUPPORT //
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+
+			if (pAd->StaCfg.Psm == PWR_SAVE)
+				return;
+
+			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 RTMP_MAC_PCI
+			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			pAd->StaCfg.BBPR3 = BBPR3;
+#endif // RTMP_MAC_PCI //
+			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;
+				}
+			}
+		}
+#endif // CONFIG_STA_SUPPORT //
+	}
+}
+
+/*
+    ========================================================================
+    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;
+	BOOLEAN			bSwapAnt = FALSE;
+#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 RT3090
+							|| (pAd->bPCIclkOff == TRUE)
+#endif // RT3090 //
+#ifdef ANT_DIVERSITY_SUPPORT
+							|| (pAd->EepromAccess)
+#endif // ANT_DIVERSITY_SUPPORT //
+							)
+		return;
+
+#ifdef ANT_DIVERSITY_SUPPORT
+	if ((pAd->NicConfig2.field.AntDiversity) && (pAd->CommonCfg.bRxAntDiversity == ANT_DIVERSITY_ENABLE))
+	{
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+			if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
+				bSwapAnt = TRUE;
+#endif // CONFIG_STA_SUPPORT //
+		if (bSwapAnt == TRUE)
+			{
+				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;
+
+#ifdef CONFIG_STA_SUPPORT
+				pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
+#endif // CONFIG_STA_SUPPORT //
+//				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
+
+#ifdef CONFIG_STA_SUPPORT
+			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));
+#endif // CONFIG_STA_SUPPORT //
+		}
+		else
+#endif // ANT_DIVERSITY_SUPPORT //
+	{
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			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);
+#ifdef RTMP_MAC_PCI
+			pAd->StaCfg.BBPR3 = BBPR3;
+#endif // RTMP_MAC_PCI //
+		}
+#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;
+
+#ifdef QOS_DLS_SUPPORT
+		if (pEntry && (pEntry->ValidAsDls))
+			result = pAd->StaCfg.bAutoTxRateSwitch;
+#endif // QOS_DLS_SUPPORT //
+	}
+#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))
+#ifdef RTMP_MAC_PCI
+		&& (pAd->bPCIclkOff == FALSE)
+#endif // RTMP_MAC_PCI //
+		)
+	{
+		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_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(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
+#ifdef RT30xx
+		/* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
+
+		if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+		{
+			R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+		}
+		else
+#endif // RT30xx //
+		{
+			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 //
+		}
+	}
+
+}
diff --git a/drivers/staging/rt3090/common/mlme_ex.c b/drivers/staging/rt3090/common/mlme_ex.c
new file mode 100644
index 0000000..d7fb7f5
--- /dev/null
+++ b/drivers/staging/rt3090/common/mlme_ex.c
@@ -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:
+	mlme_ex.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+	Fonchi		2007-06-25		Extend original mlme APIs to support multi-entries
+*/
+
+#include "../rt_config.h"
+#include "../mlme_ex_def.h"
+//#include <stdarg.h>
+
+
+// ===========================================================================================
+// state_machine
+// ===========================================================================================
+
+/*! \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
+ */
+VOID StateMachineInitEx(
+	IN STATE_MACHINE_EX *S,
+	IN STATE_MACHINE_FUNC_EX Trans[],
+	IN ULONG StNr,
+	IN ULONG MsgNr,
+	IN STATE_MACHINE_FUNC_EX 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;
+
+	return;
+}
+
+/*! \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
+ */
+VOID StateMachineSetActionEx(
+	IN STATE_MACHINE_EX *S,
+	IN ULONG St,
+	IN ULONG Msg,
+	IN STATE_MACHINE_FUNC_EX 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;
+	}
+
+	return;
+}
+
+/*! \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
+ */
+VOID StateMachinePerformActionEx(
+	IN PRTMP_ADAPTER	pAd,
+	IN STATE_MACHINE_EX *S,
+	IN MLME_QUEUE_ELEM *Elem,
+	USHORT Idx,
+	PULONG pCurrState)
+{
+	if (S->TransFunc[(*pCurrState) * S->NrMsg + Elem->MsgType - S->Base])
+		(*(S->TransFunc[(*pCurrState) * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem, pCurrState, Idx);
+
+	return;
+}
+
+/*! \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
+ */
+BOOLEAN MlmeEnqueueEx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN ULONG Machine,
+	IN ULONG MsgType,
+	IN ULONG MsgLen,
+	IN VOID *Msg,
+	IN USHORT Idx)
+{
+	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))
+		return FALSE;
+
+
+	// First check the size, it MUST not exceed the mlme queue size
+	if (MsgLen > MAX_LEN_OF_MLME_BUFFER)
+	{
+		DBGPRINT_ERR(("MlmeEnqueueEx: msg too large, size = %ld \n", MsgLen));
+		return FALSE;
+	}
+
+	if (MlmeQueueFull(Queue))
+	{
+
+		return FALSE;
+	}
+
+	RTMP_SEM_LOCK(&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].Idx = Idx;
+	if (Msg != NULL)
+		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+
+	RTMP_SEM_UNLOCK(&Queue->Lock);
+
+	return TRUE;
+}
+
+/*
+    ==========================================================================
+    Description:
+        The drop function, when machine executes this, the message is simply
+        ignored. This function does nothing, the message is freed in
+        StateMachinePerformAction()
+    ==========================================================================
+ */
+VOID DropEx(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem,
+	PULONG pCurrState,
+	USHORT Idx)
+{
+	return;
+}
diff --git a/drivers/staging/rt3090/common/netif_block.c b/drivers/staging/rt3090/common/netif_block.c
new file mode 100644
index 0000000..2172957
--- /dev/null
+++ b/drivers/staging/rt3090/common/netif_block.c
@@ -0,0 +1,147 @@
+/*
+ *************************************************************************
+ * 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 BLOCK_NET_IF
+
+#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)
+	{
+		RTMP_OS_NETDEV_STOP_QUEUE(pNetDev);
+		pNetIfEntry->pNetDev = pNetDev;
+		insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
+
+		pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_STOP_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
+	}
+	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;
+		RTMP_OS_NETDEV_WAKE_QUEUE(pNetDev);
+		insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
+
+		DBGPRINT(RT_DEBUG_TRACE, ("RTMP_OS_NETDEV_WAKE_QUEUE(%s)\n", RTMP_OS_NETDEV_GET_DEVNAME(pNetDev)));
+	}
+	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 APCLI_SUPPORT
+	if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_APCLI)
+	{
+		IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_APCLI) % MAX_APCLI_NUM;
+		NetDev = pAd->ApCfg.ApCliTab[IfIdx].dev;
+	}
+	else
+#endif // APCLI_SUPPORT //
+#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;
+}
+
+#endif // BLOCK_NET_IF //
diff --git a/drivers/staging/rt3090/common/rt_channel.c b/drivers/staging/rt3090/common/rt_channel.c
new file mode 100644
index 0000000..da2391e
--- /dev/null
+++ b/drivers/staging/rt3090/common/rt_channel.c
@@ -0,0 +1,1287 @@
+/*
+ *************************************************************************
+ * 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"
+
+
+CH_FREQ_MAP CH_HZ_ID_MAP[]=
+		{
+			{1, 2412},
+			{2, 2417},
+			{3, 2422},
+			{4, 2427},
+			{5, 2432},
+			{6, 2437},
+			{7, 2442},
+			{8, 2447},
+			{9, 2452},
+			{10, 2457},
+			{11, 2462},
+			{12, 2467},
+			{13, 2472},
+			{14, 2484},
+
+			/*  UNII */
+			{36, 5180},
+			{40, 5200},
+			{44, 5220},
+			{48, 5240},
+			{52, 5260},
+			{56, 5280},
+			{60, 5300},
+			{64, 5320},
+			{149, 5745},
+			{153, 5765},
+			{157, 5785},
+			{161, 5805},
+			{165, 5825},
+			{167, 5835},
+			{169, 5845},
+			{171, 5855},
+			{173, 5865},
+
+			/* HiperLAN2 */
+			{100, 5500},
+			{104, 5520},
+			{108, 5540},
+			{112, 5560},
+			{116, 5580},
+			{120, 5600},
+			{124, 5620},
+			{128, 5640},
+			{132, 5660},
+			{136, 5680},
+			{140, 5700},
+
+			/* Japan MMAC */
+			{34, 5170},
+			{38, 5190},
+			{42, 5210},
+			{46, 5230},
+
+			/*  Japan */
+			{184, 4920},
+			{188, 4940},
+			{192, 4960},
+			{196, 4980},
+
+			{208, 5040},	/* Japan, means J08 */
+			{212, 5060},	/* Japan, means J12 */
+			{216, 5080},	/* Japan, means J16 */
+};
+
+INT	CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP)/sizeof(CH_FREQ_MAP));
+
+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
+				{ 36,	4,  23, IDOR, FALSE},	// 5G, ch 36~48
+				{ 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 PCH_REGION GetChRegion(
+	IN PUCHAR CntryCode)
+{
+	INT loop = 0;
+	PCH_REGION pChRegion = NULL;
+
+	while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0)
+	{
+		if (strncmp((PSTRING) ChRegion[loop].CountReg, (PSTRING) CntryCode, 2) == 0)
+		{
+			pChRegion = &ChRegion[loop];
+			break;
+		}
+		loop++;
+	}
+
+	if (pChRegion == NULL)
+		pChRegion = &ChRegion[loop];
+	return pChRegion;
+}
+
+static 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 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);
+        }
+	}
+}
+
+
+VOID BuildChannelListEx(
+	IN PRTMP_ADAPTER pAd)
+{
+	PCH_REGION pChReg;
+
+	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
+	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
+}
+
+
+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 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 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;
+}
+
+
+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()
+			}
+		}
+	}
+
+
+}
+
+
+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 //
+
+
+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;
+}
diff --git a/drivers/staging/rt3090/common/rt_rf.c b/drivers/staging/rt3090/common/rt_rf.c
new file mode 100644
index 0000000..9d638f7
--- /dev/null
+++ b/drivers/staging/rt3090/common/rt_rf.c
@@ -0,0 +1,201 @@
+/*
+ *************************************************************************
+ * 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_rf.c
+
+	Abstract:
+	Ralink Wireless driver RF related functions
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+#ifdef RTMP_RF_RW_SUPPORT
+/*
+	========================================================================
+
+	Routine Description: Write RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS 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 NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description: Read RT30xx RF register through MAC
+
+	Arguments:
+
+	Return Value:
+
+	IRQL =
+
+	Note:
+
+	========================================================================
+*/
+NDIS_STATUS 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;
+}
+
+
+VOID NICInitRFRegisters(
+	IN RTMP_ADAPTER *pAd)
+{
+	if (pAd->chipOps.AsicRfInit)
+		pAd->chipOps.AsicRfInit(pAd);
+}
+
+
+VOID RtmpChipOpsRFHook(
+	IN RTMP_ADAPTER *pAd)
+{
+	RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+
+	pChipOps->pRFRegTable = NULL;
+	pChipOps->AsicRfInit = NULL;
+	pChipOps->AsicRfTurnOn = NULL;
+	pChipOps->AsicRfTurnOff = NULL;
+	pChipOps->AsicReverseRfFromSleepMode = NULL;
+	pChipOps->AsicHaltAction = NULL;
+#ifdef RT33xx
+if (IS_RT3390(pAd) && (pAd->infType == RTMP_DEV_INF_PCI))
+		{
+			pChipOps->pRFRegTable = RFRegTableOverRT3390;
+			pChipOps->AsicHaltAction = RT33xxHaltAction;
+			pChipOps->AsicRfTurnOff = RT33xxLoadRFSleepModeSetup;
+			pChipOps->AsicRfInit = NICInitRT3390RFRegisters;
+			pChipOps->AsicReverseRfFromSleepMode = RT33xxReverseRFSleepModeSetup;
+		}
+#else // RT33xx //
+	/* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
+
+#ifdef RT30xx
+	if (IS_RT30xx(pAd))
+	{
+		pChipOps->pRFRegTable = RT30xx_RFRegTable;
+		pChipOps->AsicHaltAction = RT30xxHaltAction;
+#ifdef RT3090
+		if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI))
+		{
+			pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
+			pChipOps->AsicRfInit = NICInitRT3090RFRegisters;
+			pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup;
+		}
+#endif // RT3090 //
+	}
+#endif // RT30xx //
+#endif // RT33xx //
+}
+
+#endif // RTMP_RF_RW_SUPPORT //
diff --git a/drivers/staging/rt3090/common/rtmp_init.c b/drivers/staging/rt3090/common/rtmp_init.c
new file mode 100644
index 0000000..48b95b7
--- /dev/null
+++ b/drivers/staging/rt3090/common/rtmp_init.c
@@ -0,0 +1,3882 @@
+/*
+ *************************************************************************
+ * 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
+	--------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+
+
+UCHAR    BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+char*   CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
+
+//
+// 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.
+	{BBP_R106,		0x35},  // for ShortGI throughput
+};
+#define	NUM_BBP_REG_PARMS	(sizeof(BBPRegTable) / sizeof(REG_PAIR))
+
+
+//
+// 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,	0x00182090},	// CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT
+	{TX_TIMEOUT_CFG,	0x000a2090},	// CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01
+	{MAX_LEN_CFG,		MAX_AGGREGATION_SIZE | 0x00001000},	// 0x3018, MAX frame length. Max PSDU = 16kbytes.
+	{LED_CFG,		0x7f031e46}, // Gary, 2006-08-23
+
+//#ifdef CONFIG_AP_SUPPORT
+//	{WMM_AIFSN_CFG,		0x00001173},
+//	{WMM_CWMIN_CFG,		0x00002344},
+//	{WMM_CWMAX_CFG,		0x000034a6},
+//	{WMM_TXOP0_CFG,		0x00100020},
+//	{WMM_TXOP1_CFG,		0x002F0038},
+//#endif // CONFIG_AP_SUPPORT //
+
+//#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
+// WMM_ACM_SUPPORT
+//	{TX_RTY_CFG,			0x6bb80101},	// sample
+	{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.
+	{GF20_PROT_CFG,			0x01744004},    // set 19:18 --> Short NAV for MIMO PS
+	{GF40_PROT_CFG,			0x03F44084},
+	{MM20_PROT_CFG,			0x01744004},
+#ifdef RTMP_MAC_PCI
+	{MM40_PROT_CFG,			0x03F54084},
+#endif // RTMP_MAC_PCI //
+	{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 //
+//#ifdef CONFIG_AP_SUPPORT
+//	{TBTT_SYNC_CFG,			0x00422000},	// TBTT_ADJUST(7:0) == 0
+//	{TBTT_SYNC_CFG,			0x00012000},	// TBTT_ADJUST(7:0) == 0
+//#endif // CONFIG_AP_SUPPORT //
+	{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 //
+
+
+/*
+	========================================================================
+
+	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;
+		}
+		NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE);
+
+		Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
+		if (Status != NDIS_STATUS_SUCCESS)
+		{
+			DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
+			break;
+		}
+		pAd->BeaconBuf = pBeaconBuf;
+		DBGPRINT(RT_DEBUG_OFF, ("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER)));
+
+
+		// Init spin locks
+		NdisAllocateSpinLock(&pAd->MgmtRingLock);
+#ifdef RTMP_MAC_PCI
+		NdisAllocateSpinLock(&pAd->RxRingLock);
+#ifdef RT3090
+#ifdef CONFIG_STA_SUPPORT
+	NdisAllocateSpinLock(&pAd->McuCmdLock);
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT3090 //
+#endif // RTMP_MAC_PCI //
+
+		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		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);
+
+		/* For 20M/40M Power Delta issue */
+		pAd->Tx20MPwrCfgABand[i] = data;
+		pAd->Tx20MPwrCfgGBand[i] = data;
+		pAd->Tx40MPwrCfgABand[i] = Adata;
+		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));
+	}
+}
+
+
+/*
+	========================================================================
+
+	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++)
+	{
+		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++)
+	{
+		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++)
+	{
+		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, 167, 169; 171, 173 (including central frequency in BW 40MHz)
+	// 3.1 Fill up channel
+	choffset = 14 + 12 + 16;
+	/*for (i = 0; i < 2; i++)*/
+	for (i = 0; i < 3; 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 * 3 + choffset + 0].Channel		= 171;
+	pAd->TxPower[3 * 3 + choffset + 0].Power		= DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 3 + choffset + 0].Power2		= DEFAULT_RF_TX_POWER;
+
+	pAd->TxPower[3 * 3 + choffset + 1].Channel		= 173;
+	pAd->TxPower[3 * 3 + choffset + 1].Power		= DEFAULT_RF_TX_POWER;
+	pAd->TxPower[3 * 3 + choffset + 1].Power2		= DEFAULT_RF_TX_POWER;
+
+	// 3.2 Fill up power
+	/*for (i = 0; i < 4; i++)*/
+	for (i = 0; i < 6; i++)
+	{
+		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;*/
+	choffset = 14 + 12 + 16 + 11;
+
+
+}
+
+/*
+	========================================================================
+
+	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;
+}
+
+
+/*
+	========================================================================
+
+	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"));
+
+	if (pAd->chipOps.eeinit)
+		pAd->chipOps.eeinit(pAd);
+#ifdef RTMP_EFUSE_SUPPORT
+#ifdef RT30xx
+	if(!pAd->bFroceEEPROMBuffer && pAd->bEEPROMFile)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters::(Efuse)Load  to EEPROM Buffer Mode\n"));
+		eFuseLoadEEPROM(pAd);
+	}
+#endif // RT30xx //
+#endif // RTMP_EFUSE_SUPPORT //
+
+	// 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((PSTRING) 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;
+		PSTRING	macptr;
+
+		macptr = (PSTRING) 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",
+							PRINT_MAC(pAd->PermanentAddress)));
+		}
+	}
+
+	// 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)|| IS_RT3390(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));
+		}
+	}
+
+	// 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;
+
+	// Set the RfICType here, then we can initialize RFIC related operation callbacks
+	pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
+	pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
+
+#ifdef RTMP_RF_RW_SUPPORT
+	RtmpChipOpsRFHook(pAd);
+#endif // RTMP_RF_RW_SUPPORT //
+
+	//
+	// 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)
+		&& (Antenna.field.RfIcType != RFIC_3052))
+	{
+		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;
+
+#ifdef RT30xx
+	//
+	// Get TX mixer gain setting
+	// 0xff are invalid value
+	// Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero.
+	//       RT359X default value is 0x02
+	//
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
+	{
+		RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value);
+		pAd->TxMixerGain24G = 0;
+		value &= 0x00ff;
+		if (value != 0xff)
+		{
+			value &= 0x07;
+			pAd->TxMixerGain24G = (UCHAR)value;
+		}
+	}
+#endif // RT30xx //
+
+	//
+	// Get LED Setting.
+	//
+	RT28xx_EEPROM_READ16(pAd, 0x3a, value);
+	pAd->LedCntl.word = (value>>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
+	RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
+#endif // SINGLE_SKU //
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+	RtmpEfuseSupportCheck(pAd);
+#endif // RTMP_EFUSE_SUPPORT //
+#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);
+		}
+	}
+
+
+	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;
+
+#ifdef RT30xx
+	// set default antenna as main
+	if (pAd->RfIcType == RFIC_3020)
+		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+#endif // RT30xx //
+
+	//
+	// Send LED Setting to MCU.
+	//
+	if (pAd->LedCntl.word == 0xFF)
+	{
+		pAd->LedCntl.word = 0x01;
+		pAd->Led1 = 0x5555;
+		pAd->Led2 = 0x2221;
+
+#ifdef RTMP_MAC_PCI
+		pAd->Led3 = 0xA9F8;
+#endif // RTMP_MAC_PCI //
+	}
+
+	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));
+	AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity);
+
+	pAd->LedIndicatorStrength = 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);
+#ifdef RTMP_MAC_PCI
+#ifdef RT3090
+			AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff, 0x02);
+			AsicCheckCommanOk(pAd, PowerRadioOffCID);
+#endif // RT3090 //
+#ifndef RT3090
+			AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
+#endif // RT3090 //
+			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
+			// 2-1. wait command ok.
+			AsicCheckCommanOk(pAd, PowerWakeCID);
+#endif // RTMP_MAC_PCI //
+		}
+	}
+#ifdef RTMP_MAC_PCI
+#ifdef RT30xx
+		if (IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd))
+		{
+			RTMP_CHIP_OP *pChipOps = &pAd->chipOps;
+			if (pChipOps->AsicReverseRfFromSleepMode)
+				pChipOps->AsicReverseRfFromSleepMode(pAd);
+		}
+		// 3090 MCU Wakeup command needs more time to be stable.
+		// Before stable, don't issue other MCU command to prevent from firmware error.
+
+		if ((IS_RT3090(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)
+			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+			&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+		{
+			DBGPRINT(RT_DEBUG_TRACE,("%s::%d,release Mcu Lock\n",__FUNCTION__,__LINE__));
+			RTMP_SEM_LOCK(&pAd->McuCmdLock);
+			pAd->brt30xxBanMcuCmd = FALSE;
+			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+		}
+#endif // RT30xx //
+#endif // RTMP_MAC_PCI //
+#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;
+#ifdef RTMP_MAC_PCI
+	UINT32			Value;
+	DELAY_INT_CFG_STRUC	IntCfg;
+#endif // RTMP_MAC_PCI //
+//	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
+#ifdef RTMP_MAC_PCI
+	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 // RTMP_MAC_PCI //
+
+	// Initialze ASIC for TX & Rx operation
+	if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
+	{
+		if (j++ == 0)
+		{
+			NICLoadFirmware(pAd);
+			goto retry;
+		}
+		return NDIS_STATUS_FAILURE;
+	}
+
+
+#ifdef RTMP_MAC_PCI
+	// 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);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value));
+
+	// Write AC_BE base address register
+	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
+	RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value));
+
+	// Write AC_VI base address register
+	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
+	RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value));
+
+	// Write AC_VO base address register
+	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
+	RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value));
+
+	// Write HCCA base address register
+	/*
+	Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_HCCA].Cell[0].AllocPa);
+	RTMP_IO_WRITE32(pAd, TX_BASE_PTR4, Value);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR4 : 0x%x\n", Value));
+	*/
+
+	// Write MGMT_BASE_CSR register
+	Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa);
+	RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value));
+
+	// Write RX_BASE_CSR register
+	Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa);
+	RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value);
+	DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value));
+
+	// Init RX Ring index pointer
+	pAd->RxRing.RxSwReadIdx = 0;
+	pAd->RxRing.RxCpuIdx = RX_RING_SIZE-1;
+	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
+
+	// Init TX rings index pointer
+	{
+		for (i=0; i<NUM_OF_TX_RING; i++)
+		{
+			pAd->TxRing[i].TxSwFreeIdx = 0;
+			pAd->TxRing[i].TxCpuIdx = 0;
+			RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TxCpuIdx);
+		}
+	}
+
+	// init MGMT ring index pointer
+	pAd->MgmtRing.TxSwFreeIdx = 0;
+	pAd->MgmtRing.TxCpuIdx = 0;
+	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX,  pAd->MgmtRing.TxCpuIdx);
+
+	//
+	// set each Ring's SIZE  into ASIC. Descriptor Size is fixed by design.
+	//
+
+	// Write TX_RING_CSR0 register
+	Value = TX_RING_SIZE;
+	RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value);
+	RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value);
+	RTMP_IO_WRITE32(pAd, TX_MAX_CNT2, Value);
+	RTMP_IO_WRITE32(pAd, TX_MAX_CNT3, Value);
+	RTMP_IO_WRITE32(pAd, TX_MAX_CNT4, Value);
+	Value = MGMT_RING_SIZE;
+	RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value);
+
+	// Write RX_RING_CSR register
+	Value = RX_RING_SIZE;
+	RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
+#endif // RTMP_MAC_PCI //
+
+
+	// 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);
+
+
+#ifdef RTMP_MAC_PCI
+	// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
+	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);
+
+	GloCfg.word &= 0xff0;
+	GloCfg.field.EnTXWriteBackDDONE =1;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+	IntCfg.word = 0;
+	RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
+#endif // RTMP_MAC_PCI //
+
+
+	// 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 RT30xx
+	UCHAR			bbpreg=0;
+	UCHAR			RFValue=0;
+#endif // RT30xx //
+	USHORT			KeyIdx;
+	INT				i,apidx;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
+
+#ifdef RTMP_MAC_PCI
+	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3);	// To fix driver disable/enable hang issue when radio off
+	if (bHardReset == TRUE)
+	{
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
+	}
+	else
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+	// Initialize MAC register to default value
+	for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++)
+	{
+#ifdef RT30xx
+		if ((MACRegTable[Index].Register == TX_SW_CFG0) && ( IS_RT3090(pAd) ||  IS_RT3390(pAd)))
+		{
+			MACRegTable[Index].Value = 0x00000400;
+		}
+#endif // RT30xx //
+		RTMP_IO_WRITE32(pAd, 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, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
+		}
+	}
+#endif // CONFIG_STA_SUPPORT //
+#endif // RTMP_MAC_PCI //
+
+
+#ifdef RT30xx
+	// Initialize RT3070 serial MAC registers which is different from RT2870 serial
+	if (IS_RT3090(pAd) || IS_RT3572(pAd)||IS_RT3390(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, 0x2C);	// 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))
+	{
+		if (((pAd->MACVersion & 0xffff) < 0x0201))
+		{
+			RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C);	// To fix throughput drop drastically
+		}
+		else
+		{
+			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0);
+		}
+	}
+#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);
+#ifdef RT3090
+	//2008/11/28:KH add to fix the dead rf frequency offset bug<--
+	AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0);
+	//2008/11/28:KH add to fix the dead rf frequency offset bug-->
+#endif // RT3090 //
+	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);
+	}
+
+#ifdef RTMP_MAC_PCI
+	// TODO: shiang, check MACVersion, currently, rbus-based chip use this.
+	if (pAd->MACVersion == 0x28720200)
+	{
+		//UCHAR value;
+		ULONG value2;
+
+		//disable MLD by Bruce 20080704
+		//BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value);
+		//BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4);
+
+		//Maximum PSDU length from 16K to 32K bytes
+		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2);
+		value2 &= ~(0x3<<12);
+		value2 |= (0x2<<12);
+		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2);
+	}
+#endif // RTMP_MAC_PCI //
+
+	// 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.
+	//3070/71/72,3090,3090A( are included in RT30xx),3572,3390
+	if (((pAd->MACVersion & 0xffff) != 0x0101) && !(IS_RT30xx(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd)))
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
+
+#ifdef RT30xx
+// add by johnli, RF power sequence setup
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	{	//update for RT3070/71/72/90/91/92,3572,3390.
+		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)||IS_RT3390(pAd))	// RT309x, RT3071/72
+	{
+		// 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);
+		}
+	}
+	else if (IS_RT3070(pAd))
+	{
+		if ((pAd->MACVersion & 0xffff) >= 0x0201)
+		{
+			// enable DC filter
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
+
+			// improve power consumption in RT3070 Ver.F
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
+			bbpreg &= (~0x3);
+			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
+		}
+
+		// 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->NicConfig2.field.ExternalLNAForG == 0)
+		{
+			RFValue |= 0x20;
+		}
+		// set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
+		if (pAd->TxMixerGain24G >= 1)
+		{
+			RFValue &= (~0x7);  // clean bit [2:0]
+			RFValue |= pAd->TxMixerGain24G;
+		}
+		RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+	}
+// end johnli
+#endif // RT30xx //
+
+	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 CONFIG_STA_SUPPORT
+	// Add radio off control
+	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 shared 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 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 //
+
+#ifdef RT30xx
+#ifdef NEW_FW
+	if (IS_RT3070(pAd) ||  IS_RT3572(pAd)||IS_RT3390(pAd)||IS_RT3090(pAd))
+	{
+		// send 0x36 mcu command after 0x72 for RT3xxx to fix Radio-Off current leakage issue
+		RTMPusecDelay(200);
+		if (pAd->buseEfuse)
+			AsicSendCommandToMcu(pAd, 0x36, 0xff, 0xff, 0);
+		else
+			AsicSendCommandToMcu(pAd, 0x36, 0xff, 0xff, 0x04);
+		RTMPusecDelay(10);
+	}
+#endif // NEW_FW //
+#endif // RT30xx //
+
+	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++;
+
+#ifdef WDS_SUPPORT
+						// fix WDS Jam issue
+						if((pEntry->ValidAsWDS == TRUE)
+							&& (pEntry->LockEntryTx == FALSE)
+							&& (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck))
+						{
+							DBGPRINT(RT_DEBUG_TRACE, ("Entry %02x:%02x:%02x:%02x:%02x:%02x Blocked!! (Fail Cnt = %d)\n",
+								pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3],
+								pEntry->Addr[4],pEntry->Addr[5],pEntry->ContinueTxFailCnt ));
+
+							pEntry->LockEntryTx = TRUE;
+						}
+#endif // WDS_SUPPORT //
+					}
+					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;
+#ifdef WDS_SUPPORT
+				pEntry->LockEntryTx = FALSE;
+#endif // WDS_SUPPORT //
+			}
+
+			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 < (TX_RING_SIZE<<1) );
+
+}
+
+/*
+	========================================================================
+
+	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;
+	COUNTER_RALINK		*pRalinkCounters;
+
+
+	pRalinkCounters = &pAd->RalinkCounters;
+
+	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
+	pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
+	OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart;
+	pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
+	if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue)
+		pRalinkCounters->RealFcsErrCount.u.HighPart++;
+
+	// Update Duplicate Rcv check
+	pRalinkCounters->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;
+
+
+	//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);
+	pRalinkCounters->OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
+	pRalinkCounters->OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+	pRalinkCounters->OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+	pRalinkCounters->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);
+		pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount;
+		pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount;
+		pRalinkCounters->TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
+		pRalinkCounters->TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
+
+		pRalinkCounters->TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
+		pRalinkCounters->TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
+		pRalinkCounters->TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
+		pRalinkCounters->TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
+
+		pRalinkCounters->TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
+		pRalinkCounters->TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
+		pRalinkCounters->TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
+		pRalinkCounters->TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
+
+		pRalinkCounters->TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
+		pRalinkCounters->TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
+		pRalinkCounters->TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
+		pRalinkCounters->TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
+
+		pRalinkCounters->TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
+		pRalinkCounters->TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
+
+		// Calculate the transmitted A-MPDU count
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
+
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
+
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
+
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
+
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
+
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
+
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
+
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
+		pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
+	}
+
+#ifdef DBG_DIAGNOSE
+	{
+		RtmpDiagStruct	*pDiag;
+		UCHAR			ArrayCurIdx, i;
+
+		pDiag = &pAd->DiagStruct;
+		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);
+}
+
+
+NDIS_STATUS NICLoadFirmware(
+	IN PRTMP_ADAPTER pAd)
+{
+	NDIS_STATUS	 status = NDIS_STATUS_SUCCESS;
+	if (pAd->chipOps.loadFirmware)
+		status = pAd->chipOps.loadFirmware(pAd);
+
+	return status;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		erase 8051 firmware image in MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+VOID NICEraseFirmware(
+	IN PRTMP_ADAPTER pAd)
+{
+	if (pAd->chipOps.eraseFirmware)
+		pAd->chipOps.eraseFirmware(pAd);
+
+}/* End of NICEraseFirmware */
+
+
+/*
+	========================================================================
+
+	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:
+		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;
+	}
+}
+
+
+/*
+	========================================================================
+
+	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
+	//
+
+	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;
+		}
+	}
+
+	pAd->EepromAccess = FALSE;
+
+	pAd->Antenna.word = 0;
+	pAd->CommonCfg.BBPCurrentBW = BW_20;
+
+	pAd->LedCntl.word = 0;
+#ifdef RTMP_MAC_PCI
+	pAd->LedIndicatorStrength = 0;
+	pAd->RLnkCtrlOffset = 0;
+	pAd->HostLnkCtrlOffset = 0;
+#ifdef CONFIG_STA_SUPPORT
+	pAd->StaCfg.PSControl.field.EnableNewPS=TRUE;
+	pAd->CheckDmaBusyCount = 0;
+#endif // CONFIG_STA_SUPPORT //
+#endif // RTMP_MAC_PCI //
+
+	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;
+
+
+
+#ifdef TONE_RADAR_DETECT_SUPPORT
+#ifdef CARRIER_DETECTION_SUPPORT
+	pAd->CommonCfg.CarrierDetect.delta = CARRIER_DETECT_DELTA;
+	pAd->CommonCfg.CarrierDetect.div_flag = CARRIER_DETECT_DIV_FLAG;
+	pAd->CommonCfg.CarrierDetect.criteria = CARRIER_DETECT_CRITIRIA;
+#ifdef RT3090
+	if(IS_RT3090A(pAd))
+	pAd->CommonCfg.CarrierDetect.threshold = CARRIER_DETECT_THRESHOLD_3090A;
+	else
+#endif // RT3090 //
+	pAd->CommonCfg.CarrierDetect.threshold = CARRIER_DETECT_THRESHOLD;
+#endif // CARRIER_DETECTION_SUPPORT //
+#endif // TONE_RADAR_DETECT_SUPPORT //
+
+	pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
+#ifdef MERGE_ARCH_TEAM
+	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 2;
+	pAd->CommonCfg.RadarDetect.AvgRssiReq = -75;
+#else // original rt28xx source code
+	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
+#endif // MERGE_ARCH_TEAM //
+	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;
+	//2008/11/05:KH add to support Antenna power-saving of AP<--
+	pAd->CommonCfg.bGreenAPEnable=FALSE;
+	pAd->CommonCfg.bBlockAntDivforGreenAP=FALSE;
+	//2008/11/05:KH add to support Antenna power-saving of AP-->
+	pAd->CommonCfg.bBADecline = FALSE;
+	pAd->CommonCfg.bDisableReordering = FALSE;
+
+	if (pAd->MACVersion == 0x28720200)
+	{
+		pAd->CommonCfg.TxBASize = 13; //by Jerry recommend
+	}else{
+		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 //
+#ifdef PCIE_PS_SUPPORT
+pAd->brt30xxBanMcuCmd = FALSE;
+pAd->b3090ESpecialChip = FALSE;
+//KH Debug:the following must be removed
+pAd->StaCfg.PSControl.field.rt30xxPowerMode=3;
+pAd->StaCfg.PSControl.field.rt30xxForceASPMTest=0;
+pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM=1;
+#endif // PCIE_PS_SUPPORT //
+#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;
+
+		RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
+		pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+		// Patch for Ndtest
+		pAd->StaCfg.ScanCnt = 0;
+
+		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.
+		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
+		if (pAd->StaCfg.LastScanTime > 10 * OS_HZ)
+			pAd->StaCfg.LastScanTime -= (10 * OS_HZ);
+
+		NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
+#ifdef RTMP_MAC_PCI
+		sprintf((PSTRING) pAd->nickname, "RT2860STA");
+#endif // RTMP_MAC_PCI //
+		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;
+		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+
+
+		pAd->StaCfg.bAutoConnectByBssid = FALSE;
+		pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME;
+		NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
+		pAd->StaCfg.WpaPassPhraseLen = 0;
+		pAd->StaCfg.bAutoRoaming = FALSE;
+		pAd->StaCfg.bForceTxBurst = FALSE;
+	}
+#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.TxDoneCount = 0;
+	pAd->ate.RFFreqOffset = 0;
+	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 RTMP_MAC_PCI
+	pAd->ate.bFWLoading = FALSE;
+#endif // RTMP_MAC_PCI //
+
+
+#ifdef RALINK_28xx_QA
+	pAd->ate.TxStatus = 0;
+	pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+
+	pAd->CommonCfg.bWiFiTest = FALSE;
+#ifdef RTMP_MAC_PCI
+    pAd->bPCIclkOff = FALSE;
+#endif // RTMP_MAC_PCI //
+
+#ifdef CONFIG_STA_SUPPORT
+RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+#endif // CONFIG_STA_SUPPORT //
+#ifdef ANT_DIVERSITY_SUPPORT
+		if ( pAd->CommonCfg.bRxAntDiversity == ANT_FIX_ANT2)
+		{
+			pAd->RxAnt.Pair1PrimaryRxAnt = 1;
+			pAd->RxAnt.Pair1SecondaryRxAnt = 0;
+		}
+		else // Default
+		{
+			pAd->RxAnt.Pair1PrimaryRxAnt = 0;
+			pAd->RxAnt.Pair1SecondaryRxAnt = 1;
+		}
+		pAd->RxAnt.EvaluatePeriod = 0;
+		pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
+#ifdef CONFIG_STA_SUPPORT
+		pAd->RxAnt.Pair1AvgRssi[0] = pAd->RxAnt.Pair1AvgRssi[1] = 0;
+#endif // CONFIG_STA_SUPPORT //
+#endif // AP_ANTENNA_DIVERSITY_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
+}
+
+// IRQL = PASSIVE_LEVEL
+UCHAR BtoH(STRING 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(PSTRING src, PUCHAR dest, int destlen)
+{
+	PSTRING 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++;
+	}
+}
+
+
+//+++Mark by shiang, not use now, need to remove after confirm
+//---Mark by shiang, not use now, need to remove after confirm
+
+
+/*
+	========================================================================
+
+	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 RTMP_TIMER_TASK_SUPPORT
+	pTimer->pAd = pAd;
+#endif // RTMP_TIMER_TASK_SUPPORT //
+
+	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 RTMP_TIMER_TASK_SUPPORT
+		// We need to go-through the TimerQ to findout this timer handler and remove it if
+		//		it's still waiting for execution.
+		RtmpTimerQRemove(pTimer->pAd, pTimer);
+#endif // RTMP_TIMER_TASK_SUPPORT //
+	}
+	else
+	{
+		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;
+	BOOLEAN			bIgnored = FALSE;
+
+#ifdef RALINK_ATE
+	/*
+		In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
+		So LED mode is not supported when ATE is running.
+	*/
+	if (!IS_RT3572(pAd))
+	{
+		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->LedIndicatorStrength = 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;
+#ifdef RALINK_ATE
+#endif // RALINK_ATE //
+		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) && (bIgnored == FALSE))
+		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 (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH)
+	{
+		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->LedIndicatorStrength != nLed)
+		{
+			AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
+			pAd->LedIndicatorStrength = 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;
+	UINT32 rx_filter_flag;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
+
+	// Enable Rx DMA.
+	RT28XXDMAEnable(pAd);
+
+	// enable RX of MAC block
+	if (pAd->OpMode == OPMODE_AP)
+	{
+		rx_filter_flag = APNORMAL;
+
+
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);     // enable RX of DMA block
+	}
+	else
+	{
+		if (pAd->CommonCfg.PSPXlink)
+			rx_filter_flag = PSPXLINK;
+		else
+			rx_filter_flag = STANORMAL;     // Staion not drop control frame will fail WiFi Certification.
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);
+	}
+
+	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
+}
+
+
+//+++Add by shiang, move from os/linux/rt_main_dev.c
+void CfgInitHook(PRTMP_ADAPTER pAd)
+{
+	pAd->bBroadComHT = TRUE;
+}
+
+
+int rt28xx_init(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING pDefaultMac,
+	IN PSTRING pHostName)
+{
+	UINT					index;
+	UCHAR					TmpPhy;
+	NDIS_STATUS				Status;
+	UINT32					MacCsr0 = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef RTMP_MAC_PCI
+	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_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 // RTMP_MAC_PCI //
+#endif // CONFIG_STA_SUPPORT //
+
+
+	// reset Adapter flags
+	RTMP_CLEAR_FLAGS(pAd);
+
+	// Init BssTab & ChannelInfo tabbles for auto channel select.
+
+#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));
+
+#ifdef RTMP_MAC_PCI
+#ifdef PCIE_PS_SUPPORT
+	/*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register  at pcie L.1 level */
+	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))&&OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+	{
+		RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0);
+		MacCsr0 |= 0x402;
+		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0);
+		DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0));
+	}
+#endif // PCIE_PS_SUPPORT //
+
+	// To fix driver disable/enable hang issue when radio off
+	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2);
+#endif // RTMP_MAC_PCI //
+
+	// 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
+#ifdef RTMP_MAC_PCI
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
+	{
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+	}
+#endif // RTMP_MAC_PCI //
+
+	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 = RtmpMgmtTaskInit(pAd);
+	if (Status != NDIS_STATUS_SUCCESS)
+		goto err2;
+
+	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);
+	Status = RtmpNetTaskInit(pAd);
+	if (Status != NDIS_STATUS_SUCCESS)
+		goto err3;
+
+//	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);
+
+	DBGPRINT(RT_DEBUG_OFF, ("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 DOT11_N_SUPPORT
+	//Init Ba Capability parameters.
+//	RT28XX_BA_INIT(pAd);
+	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;
+
+	DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
+
+	// We should read EEPROM for all cases.  rt2860b
+	NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac);
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_OFF, ("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)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"));
+		goto err4;
+	}
+
+#ifdef DOT11_N_SUPPORT
+	DBGPRINT(RT_DEBUG_OFF, ("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 RTMP_RF_RW_SUPPORT
+	//Init RT30xx RFRegisters after read RFIC type from EEPROM
+	NICInitRFRegisters(pAd);
+#endif // RTMP_RF_RW_SUPPORT //
+
+
+
+//		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);
+
+	// 8051 firmware require the signal during booting time.
+	//2008/11/28:KH marked the following codes to patch Frequency offset bug
+	//AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
+
+	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"));
+
+
+	}// end of else
+
+
+	// Set up the Mac address
+	RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]);
+
+	// Various AP function init
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+		// send wireless event to wpa_supplicant for infroming interface up.
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_UP, NULL, NULL, 0);
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+	DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status));
+
+	return TRUE;
+
+
+err4:
+err3:
+	MlmeHalt(pAd);
+err2:
+	RTMPFreeTxRxRingMemory(pAd);
+err1:
+
+#ifdef DOT11_N_SUPPORT
+	os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
+#endif // DOT11_N_SUPPORT //
+
+	// shall not set priv to NULL here because the priv didn't been free yet.
+	//net_dev->priv = 0;
+#ifdef INF_AMAZON_SE
+err0:
+#endif // INF_AMAZON_SE //
+#ifdef ST
+err0:
+#endif // ST //
+
+	DBGPRINT(RT_DEBUG_ERROR, ("!!! rt28xx Initialized fail !!!\n"));
+	return FALSE;
+}
+//---Add by shiang, move from os/linux/rt_main_dev.c
+
+
+static INT RtmpChipOpsRegister(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			infType)
+{
+	RTMP_CHIP_OP	*pChipOps = &pAd->chipOps;
+	int status;
+
+	memset(pChipOps, 0, sizeof(RTMP_CHIP_OP));
+
+	/* set eeprom related hook functions */
+	status = RtmpChipOpsEepromHook(pAd, infType);
+
+	/* set mcu related hook functions */
+	switch(infType)
+	{
+#ifdef RTMP_PCI_SUPPORT
+		case RTMP_DEV_INF_PCI:
+			pChipOps->loadFirmware = RtmpAsicLoadFirmware;
+			pChipOps->eraseFirmware = RtmpAsicEraseFirmware;
+			pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
+			break;
+#endif // RTMP_PCI_SUPPORT //
+
+
+		default:
+			break;
+	}
+
+	return status;
+}
+
+
+INT RtmpRaDevCtrlInit(
+	IN RTMP_ADAPTER *pAd,
+	IN RTMP_INF_TYPE infType)
+{
+	//VOID	*handle;
+
+	// Assign the interface type. We need use it when do register/EEPROM access.
+	pAd->infType = infType;
+
+
+#ifdef CONFIG_STA_SUPPORT
+	pAd->OpMode = OPMODE_STA;
+	DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+	RtmpChipOpsRegister(pAd, infType);
+
+#ifdef MULTIPLE_CARD_SUPPORT
+{
+	extern BOOLEAN RTMP_CardInfoRead(PRTMP_ADAPTER pAd);
+
+	// 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 //
+
+	return 0;
+}
+
+
+BOOLEAN RtmpRaDevCtrlExit(IN RTMP_ADAPTER *pAd)
+{
+#ifdef MULTIPLE_CARD_SUPPORT
+extern UINT8  MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
+
+	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 //
+
+
+	RTMPFreeAdapter(pAd);
+
+	return TRUE;
+}
+
+
+// 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 */
+}
diff --git a/drivers/staging/rt3090/common/rtmp_mcu.c b/drivers/staging/rt3090/common/rtmp_mcu.c
new file mode 100644
index 0000000..23f785a
--- /dev/null
+++ b/drivers/staging/rt3090/common/rtmp_mcu.c
@@ -0,0 +1,560 @@
+/*
+ *************************************************************************
+ * 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_mcu.c
+
+	Abstract:
+	Miniport generic portion header file
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#include "../rt_config.h"
+#include "../firmware.h"
+
+//#define BIN_IN_FILE /* use *.bin firmware */
+
+
+// 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
+
+#ifdef RTMP_MAC_PCI
+#define FIRMWARE_MINOR_VERSION		2
+#endif // RTMP_MAC_PCI //
+
+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;
+}
+
+
+/*
+	========================================================================
+
+	Routine Description:
+		erase 8051 firmware image in MAC ASIC
+
+	Arguments:
+		Adapter						Pointer to our adapter
+
+	IRQL = PASSIVE_LEVEL
+
+	========================================================================
+*/
+INT RtmpAsicEraseFirmware(
+	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);
+
+	return 0;
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+		Load 8051 firmware 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 RtmpAsicLoadFirmware(
+	IN PRTMP_ADAPTER pAd)
+{
+#ifdef BIN_IN_FILE
+#define NICLF_DEFAULT_USE()	\
+	flg_default_firm_use = TRUE; \
+	DBGPRINT(RT_DEBUG_OFF, ("%s - Use default firmware!\n", __FUNCTION__));
+
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+	PUCHAR			src;
+	RTMP_OS_FD		srcf;
+	INT				retval, i;
+	PUCHAR			pFirmwareImage;
+	INT				FileLength = 0;
+	UINT32			MacReg;
+	ULONG			Index;
+	ULONG			firm;
+	BOOLEAN			flg_default_firm_use = FALSE;
+	RTMP_OS_FS_INFO	osFSInfo;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
+
+	/* init */
+	pFirmwareImage = NULL;
+	src = RTMP_FIRMWARE_FILE_NAME;
+
+	RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+	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 */
+		DBGPRINT(RT_DEBUG_ERROR, ("%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 = RtmpOSFileOpen(src, O_RDONLY, 0);
+
+			if (IS_FILE_OPEN_ERR(srcf))
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("%s - Error opening file %s\n", __FUNCTION__, src));
+				NICLF_DEFAULT_USE();
+				break;
+			}
+
+
+			/* read the firmware from the file *.bin */
+			FileLength = RtmpOSFileRead(srcf, pFirmwareImage, MAX_FIRMWARE_IMAGE_SIZE);
+			if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("%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 */
+					DBGPRINT(RT_DEBUG_ERROR, ("%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))
+					{
+						DBGPRINT(RT_DEBUG_ERROR, ("%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_FILE_OPEN_ERR(srcf))
+			;
+		else
+		{
+			retval = RtmpOSFileClose(srcf);
+			if (retval)
+			{
+				DBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
+			}
+		}
+	}
+
+
+	/* 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 */
+
+	RtmpOSFSInfoChange(&osFSInfo, FALSE);
+#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
+	//DBGPRINT(RT_DEBUG_TRACE, ("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 RTMP_MAC_PCI
+		if ((Version == 0x2860) || IS_RT3090(pAd)||IS_RT3390(pAd))
+		{
+			pFirmwareImage = FirmwareImage;
+			FileLength = FIRMWAREIMAGE_LENGTH;
+		}
+#endif // RTMP_MAC_PCI //
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+
+	RTMP_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)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+    DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __FUNCTION__, Status));
+
+    return Status;
+}
+
+
+INT RtmpAsicSendCommandToMcu(
+	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;
+#ifdef RTMP_MAC_PCI
+#ifdef RALINK_ATE
+	static UINT32 j = 0;
+#endif // RALINK_ATE //
+#endif // RTMP_MAC_PCI //
+#ifdef PCIE_PS_SUPPORT
+#ifdef CONFIG_STA_SUPPORT
+	// 3090F power solution 3 has hw limitation that needs to ban all mcu command
+	// when firmware is in radio state.  For other chip doesn't have this limitation.
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+		&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+		&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))
+	{
+		RTMP_SEM_LOCK(&pAd->McuCmdLock);
+		if ((pAd->brt30xxBanMcuCmd == TRUE)
+			&& (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD))
+		{
+			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+			DBGPRINT(RT_DEBUG_TRACE, (" Ban Mcu Cmd %x in sleep mode\n",  Command));
+			return FALSE;
+		}
+		else if ((Command == SLEEP_MCU_CMD)
+			||(Command == RFOFF_MCU_CMD))
+		{
+			pAd->brt30xxBanMcuCmd = TRUE;
+		}
+		else if (Command != WAKE_MCU_CMD)
+		{
+			pAd->brt30xxBanMcuCmd = FALSE;
+		}
+
+		RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
+
+	}
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+		&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+		&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+		&& (Command == WAKE_MCU_CMD))
+	{
+
+		do
+		{
+			RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
+			if (H2MMailbox.field.Owner == 0)
+				break;
+
+			RTMPusecDelay(2);
+			DBGPRINT(RT_DEBUG_INFO, ("AsicSendCommanToMcu::Mail box is busy\n"));
+		} 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_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+		H2MCmd.word			  = 0;
+		H2MCmd.field.HostCommand  = Command;
+		RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+
+
+	}
+	else
+#endif // CONFIG_STA_SUPPORT //
+#endif // PCIE_PS_SUPPORT //
+	{
+	do
+	{
+		RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
+		if (H2MMailbox.field.Owner == 0)
+			break;
+
+		RTMPusecDelay(2);
+	} while(i++ < 100);
+
+	if (i >= 100)
+	{
+#ifdef RTMP_MAC_PCI
+#ifdef RALINK_ATE
+		if (pAd->ate.bFWLoading == TRUE)
+		{
+			/* reloading firmware when received iwpriv cmd "ATE=ATESTOP" */
+			if (j > 0)
+			{
+				if (j % 64 != 0)
+				{
+					ATEDBGPRINT(RT_DEBUG_ERROR, ("#"));
+				}
+				else
+				{
+					ATEDBGPRINT(RT_DEBUG_ERROR, ("\n"));
+				}
+				++j;
+			}
+			else if (j == 0)
+			{
+				ATEDBGPRINT(RT_DEBUG_ERROR, ("Loading firmware. Please wait for a moment...\n"));
+				++j;
+			}
+		}
+		else
+#endif // RALINK_ATE //
+#endif // RTMP_MAC_PCI //
+		{
+		DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+		}
+		return FALSE;
+	}
+
+#ifdef RTMP_MAC_PCI
+#ifdef RALINK_ATE
+	else if (pAd->ate.bFWLoading == TRUE)
+	{
+		/* reloading of firmware is completed */
+		pAd->ate.bFWLoading = FALSE;
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("\n"));
+		j = 0;
+	}
+#endif // RALINK_ATE //
+#endif // RTMP_MAC_PCI //
+
+	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)
+	{
+	}
+}
+#ifdef PCIE_PS_SUPPORT
+#ifdef CONFIG_STA_SUPPORT
+	// 3090 MCU Wakeup command needs more time to be stable.
+	// Before stable, don't issue other MCU command to prevent from firmware error.
+	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
+		&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
+		&& (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
+		&& (Command == WAKE_MCU_CMD))
+	{
+		RTMPusecDelay(2000);
+		//Put this is after RF programming.
+		//NdisAcquireSpinLock(&pAd->McuCmdLock);
+		//pAd->brt30xxBanMcuCmd = FALSE;
+		//NdisReleaseSpinLock(&pAd->McuCmdLock);
+	}
+#endif // CONFIG_STA_SUPPORT //
+#endif // PCIE_PS_SUPPORT //
+
+	return TRUE;
+}
diff --git a/drivers/staging/rt3090/common/rtmp_timer.c b/drivers/staging/rt3090/common/rtmp_timer.c
new file mode 100644
index 0000000..5253e87
--- /dev/null
+++ b/drivers/staging/rt3090/common/rtmp_timer.c
@@ -0,0 +1,327 @@
+/*
+ *************************************************************************
+ * 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_timer.c
+
+    Abstract:
+    task for timer handling
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+    Name          Date            Modification logs
+    Shiang Tu	08-28-2008   init version
+
+*/
+
+#include "../rt_config.h"
+
+
+BUILD_TIMER_FUNCTION(MlmePeriodicExec);
+//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
+BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+BUILD_TIMER_FUNCTION(APSDPeriodicExec);
+BUILD_TIMER_FUNCTION(AsicRfTuningExec);
+
+
+#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);
+BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+#ifdef RTMP_MAC_PCI
+BUILD_TIMER_FUNCTION(PsPollWakeExec);
+BUILD_TIMER_FUNCTION(RadioOnExec);
+#endif // RTMP_MAC_PCI //
+#ifdef QOS_DLS_SUPPORT
+BUILD_TIMER_FUNCTION(DlsTimeoutAction);
+#endif // QOS_DLS_SUPPORT //
+
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#if defined(AP_LED) || defined(STA_LED)
+extern void LedCtrlMain(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+BUILD_TIMER_FUNCTION(LedCtrlMain);
+#endif
+
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+static void RtmpTimerQHandle(RTMP_ADAPTER *pAd)
+{
+#ifndef KTHREAD_SUPPORT
+	int status;
+#endif
+	RALINK_TIMER_STRUCT	*pTimer;
+	RTMP_TIMER_TASK_ENTRY	*pEntry;
+	unsigned long	irqFlag;
+	RTMP_OS_TASK *pTask;
+
+
+	pTask = &pAd->timerTask;
+	while(!pTask->task_killed)
+	{
+		pTimer = NULL;
+
+#ifdef KTHREAD_SUPPORT
+		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
+#else
+		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
+#endif
+
+		if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
+			break;
+
+		// event happened.
+		while(pAd->TimerQ.pQHead)
+		{
+			RTMP_INT_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_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
+
+			if (pTimer)
+			{
+				if ((pTimer->handle != NULL) && (!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);
+			}
+		}
+
+#ifndef KTHREAD_SUPPORT
+		if (status != 0)
+		{
+			pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			break;
+		}
+#endif
+	}
+}
+
+
+INT RtmpTimerQThread(
+	IN OUT PVOID Context)
+{
+	RTMP_OS_TASK	*pTask;
+	PRTMP_ADAPTER	pAd;
+
+
+	pTask = (RTMP_OS_TASK *)Context;
+	pAd = (PRTMP_ADAPTER)pTask->priv;
+
+	RtmpOSTaskCustomize(pTask);
+
+	RtmpTimerQHandle(pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+#ifndef KTHREAD_SUPPORT
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+#endif
+	/* 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().
+	 */
+	RtmpOSTaskNotifyToExit(pTask);
+
+	return 0;
+
+}
+
+
+RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer)
+{
+	RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail;
+	unsigned long irqFlags;
+	RTMP_OS_TASK	*pTask = &pAd->timerTask;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status & RTMP_TASK_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_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+	if (pQNode)
+	{
+#ifdef KTHREAD_SUPPORT
+		WAKE_UP(pTask);
+#else
+		RTMP_SEM_EVENT_UP(&pTask->taskSema);
+#endif
+	}
+
+	return pQNode;
+}
+
+
+BOOLEAN RtmpTimerQRemove(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer)
+{
+	RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL;
+	unsigned long irqFlags;
+
+	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+	if (pAd->TimerQ.status >= RTMP_TASK_STAT_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_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+	return TRUE;
+}
+
+
+void RtmpTimerQExit(RTMP_ADAPTER *pAd)
+{
+	RTMP_TIMER_TASK_ENTRY *pTimerQ;
+	unsigned long irqFlags;
+
+	RTMP_INT_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;
+#ifndef KTHREAD_SUPPORT
+	pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
+#endif
+	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+}
+
+
+void RtmpTimerQInit(RTMP_ADAPTER *pAd)
+{
+	int	i;
+	RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry;
+	unsigned long irqFlags;
+
+	NdisAllocateSpinLock(&pAd->TimerQLock);
+
+	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
+
+	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
+	if (pAd->TimerQ.pTimerQPoll)
+	{
+		pEntry = NULL;
+		pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll;
+		NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
+
+		RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
+		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 = RTMP_TASK_STAT_INITED;
+		RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
+	}
+}
+#endif // RTMP_TIMER_TASK_SUPPORT //
diff --git a/drivers/staging/rt3090/common/spectrum.c b/drivers/staging/rt3090/common/spectrum.c
new file mode 100644
index 0000000..12d2125
--- /dev/null
+++ b/drivers/staging/rt3090/common/spectrum.c
@@ -0,0 +1,2221 @@
+/*
+ *************************************************************************
+ * 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"
+
+
+/* The regulatory information in the USA (US) */
+DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] =
+{
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+    {0,	                {0,                   0,           {0}}}, // Invlid entry
+    {1,                 {4,                   16,           {36, 40, 44, 48}}},
+    {2,                 {4,                   23,           {52, 56, 60, 64}}},
+    {3,                 {4,                   29,           {149, 153, 157, 161}}},
+    {4,                 {11,                  23,           {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
+    {5,                 {5,                   30,           {149, 153, 157, 161, 165}}},
+    {6,                 {10,                  14,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
+    {7,                 {10,                  27,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}},
+    {8,                 {5,                   17,           {11, 13, 15, 17, 19}}},
+    {9,                 {5,                   30,           {11, 13, 15, 17, 19}}},
+    {10,                {2,                   20,           {21, 25}}},
+    {11,                {2,                   33,            {21, 25}}},
+    {12,                {11,                  30,            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}}
+};
+#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+/* The regulatory information in Europe */
+DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] =
+{
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+    {0,                 {0,                   0,           {0}}}, // Invalid entry
+    {1,                 {4,                   20,           {36, 40, 44, 48}}},
+    {2,                 {4,                   20,           {52, 56, 60, 64}}},
+    {3,                 {11,                  30,           {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}},
+    {4,                 {13,                  20,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}
+};
+#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+/* The regulatory information in Japan */
+DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] =
+{
+/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
+    {0,                 {0,                   0,           {0}}}, // Invalid entry
+    {1,                 {4,                   22,           {34, 38, 42, 46}}},
+    {2,                 {3,                   24,           {8, 12, 16}}},
+    {3,                 {3,                   24,           {8, 12, 16}}},
+    {4,                 {3,                   24,           {8, 12, 16}}},
+    {5,                 {3,                   24,           {8, 12, 16}}},
+    {6,                 {3,                   22,           {8, 12, 16}}},
+    {7,                 {4,                   24,           {184, 188, 192, 196}}},
+    {8,                 {4,                   24,           {184, 188, 192, 196}}},
+    {9,                 {4,                   24,           {184, 188, 192, 196}}},
+    {10,                {4,                   24,           {184, 188, 192, 196}}},
+    {11,                {4,                   22,           {184, 188, 192, 196}}},
+    {12,                {4,                   24,           {7, 8, 9, 11}}},
+    {13,                {4,                   24,           {7, 8, 9, 11}}},
+    {14,                {4,                   24,           {7, 8, 9, 11}}},
+    {15,                {4,                   24,           {7, 8, 9, 11}}},
+    {16,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {17,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {18,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {19,                {6,                   24,           {183, 184, 185, 187, 188, 189}}},
+    {20,                {6,                   17,           {183, 184, 185, 187, 188, 189}}},
+    {21,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {22,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {23,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {24,                {6,                   24,           {6, 7, 8, 9, 10, 11}}},
+    {25,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {26,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {27,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {28,                {8,                   24,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {29,                {8,                   17,           {182, 183, 184, 185, 186, 187, 188, 189}}},
+    {30,                {13,                  23,           {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}},
+    {31,                {1,                   23,           {14}}},
+    {32,                {4,                   22,           {52, 56, 60, 64}}}
+};
+#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION))
+
+
+CHAR RTMP_GetTxPwr(
+	IN PRTMP_ADAPTER pAd,
+	IN HTTRANSMIT_SETTING HTTxMode)
+{
+typedef struct __TX_PWR_CFG
+{
+	UINT8 Mode;
+	UINT8 MCS;
+	UINT16 req;
+	UINT8 shift;
+	UINT32 BitMask;
+} TX_PWR_CFG;
+
+	UINT32 Value;
+	INT Idx;
+	UINT8 PhyMode;
+	CHAR CurTxPwr;
+	UINT8 TxPwrRef = 0;
+	CHAR DaltaPwr;
+	ULONG TxPwr[5];
+
+
+	TX_PWR_CFG TxPwrCfg[] = {
+		{MODE_CCK, 0, 0, 4, 0x000000f0},
+		{MODE_CCK, 1, 0, 0, 0x0000000f},
+		{MODE_CCK, 2, 0, 12, 0x0000f000},
+		{MODE_CCK, 3, 0, 8, 0x00000f00},
+
+		{MODE_OFDM, 0, 0, 20, 0x00f00000},
+		{MODE_OFDM, 1, 0, 16, 0x000f0000},
+		{MODE_OFDM, 2, 0, 28, 0xf0000000},
+		{MODE_OFDM, 3, 0, 24, 0x0f000000},
+		{MODE_OFDM, 4, 1, 4, 0x000000f0},
+		{MODE_OFDM, 5, 1, 0, 0x0000000f},
+		{MODE_OFDM, 6, 1, 12, 0x0000f000},
+		{MODE_OFDM, 7, 1, 8, 0x00000f00}
+#ifdef DOT11_N_SUPPORT
+		,{MODE_HTMIX, 0, 1, 20, 0x00f00000},
+		{MODE_HTMIX, 1, 1, 16, 0x000f0000},
+		{MODE_HTMIX, 2, 1, 28, 0xf0000000},
+		{MODE_HTMIX, 3, 1, 24, 0x0f000000},
+		{MODE_HTMIX, 4, 2, 4, 0x000000f0},
+		{MODE_HTMIX, 5, 2, 0, 0x0000000f},
+		{MODE_HTMIX, 6, 2, 12, 0x0000f000},
+		{MODE_HTMIX, 7, 2, 8, 0x00000f00},
+		{MODE_HTMIX, 8, 2, 20, 0x00f00000},
+		{MODE_HTMIX, 9, 2, 16, 0x000f0000},
+		{MODE_HTMIX, 10, 2, 28, 0xf0000000},
+		{MODE_HTMIX, 11, 2, 24, 0x0f000000},
+		{MODE_HTMIX, 12, 3, 4, 0x000000f0},
+		{MODE_HTMIX, 13, 3, 0, 0x0000000f},
+		{MODE_HTMIX, 14, 3, 12, 0x0000f000},
+		{MODE_HTMIX, 15, 3, 8, 0x00000f00}
+#endif // DOT11_N_SUPPORT //
+	};
+#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG))
+
+#ifdef SINGLE_SKU
+	CurTxPwr = pAd->CommonCfg.DefineMaxTxPwr;
+#else
+	CurTxPwr = 19;
+#endif
+
+	/* check Tx Power setting from UI. */
+	if (pAd->CommonCfg.TxPowerPercentage > 90)
+		;
+	else if (pAd->CommonCfg.TxPowerPercentage > 60)  /* reduce Pwr for 1 dB. */
+		CurTxPwr -= 1;
+	else if (pAd->CommonCfg.TxPowerPercentage > 30)  /* reduce Pwr for 3 dB. */
+		CurTxPwr -= 3;
+	else if (pAd->CommonCfg.TxPowerPercentage > 15)  /* reduce Pwr for 6 dB. */
+		CurTxPwr -= 6;
+	else if (pAd->CommonCfg.TxPowerPercentage > 9)   /* reduce Pwr for 9 dB. */
+		CurTxPwr -= 9;
+	else                                           /* reduce Pwr for 12 dB. */
+		CurTxPwr -= 12;
+
+	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];
+		}
+	}
+
+
+	switch(HTTxMode.field.MODE)
+	{
+		case MODE_CCK:
+		case MODE_OFDM:
+			Value = TxPwr[1];
+			TxPwrRef = (Value & 0x00000f00) >> 8;
+
+			break;
+
+#ifdef DOT11_N_SUPPORT
+		case MODE_HTMIX:
+		case MODE_HTGREENFIELD:
+			if (pAd->CommonCfg.TxStream == 1)
+			{
+				Value = TxPwr[2];
+				TxPwrRef = (Value & 0x00000f00) >> 8;
+			}
+			else if (pAd->CommonCfg.TxStream == 2)
+			{
+				Value = TxPwr[3];
+				TxPwrRef = (Value & 0x00000f00) >> 8;
+			}
+			break;
+#endif // DOT11_N_SUPPORT //
+	}
+
+	PhyMode =
+#ifdef DOT11_N_SUPPORT
+				(HTTxMode.field.MODE == MODE_HTGREENFIELD)
+				? MODE_HTMIX :
+#endif // DOT11_N_SUPPORT //
+				HTTxMode.field.MODE;
+
+	for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++)
+	{
+		if ((TxPwrCfg[Idx].Mode == PhyMode)
+			&& (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS))
+		{
+			Value = TxPwr[TxPwrCfg[Idx].req];
+			DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask)
+											>> TxPwrCfg[Idx].shift);
+			CurTxPwr -= DaltaPwr;
+			break;
+		}
+	}
+
+	return CurTxPwr;
+}
+
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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:
+		Get Current Transmit Power.
+
+	Parametrs:
+
+	Return	: Current Time Stamp.
+	==========================================================================
+ */
+VOID InsertChannelRepIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PSTRING pCountry,
+	IN UINT8 RegulatoryClass)
+{
+	ULONG TempLen;
+	UINT8 Len;
+	UINT8 IEId = IE_AP_CHANNEL_REPORT;
+	PUCHAR pChListPtr = NULL;
+
+	Len = 1;
+	if (strncmp(pCountry, "US", 2) == 0)
+	{
+		if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE)
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n",
+						__FUNCTION__, RegulatoryClass));
+			return;
+		}
+
+		Len += USARegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
+		pChListPtr = USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
+	}
+	else if (strncmp(pCountry, "JP", 2) == 0)
+	{
+		if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE)
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n",
+						__FUNCTION__, RegulatoryClass));
+			return;
+		}
+
+		Len += JapanRegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels;
+		pChListPtr = JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
+					__FUNCTION__, pCountry));
+		return;
+	}
+
+	MakeOutgoingFrame(pFrameBuf,	&TempLen,
+					1,				&IEId,
+					1,				&Len,
+					1,				&RegulatoryClass,
+					Len -1,			pChListPtr,
+					END_OF_ARGS);
+
+	*pFrameLen = *pFrameLen + TempLen;
+
+	return;
+}
+
+/*
+	==========================================================================
+	Description:
+		Insert Dialog Token into frame.
+
+	Parametrs:
+		1. frame buffer pointer.
+		2. frame length.
+		3. Dialog token.
+
+	Return	: None.
+	==========================================================================
+ */
+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.
+	==========================================================================
+ */
+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 UINT8 Len,
+	IN PMEASURE_REQ_INFO pMeasureReqIE)
+{
+	ULONG TempLen;
+	UINT8 ElementID = IE_MEASUREMENT_REQUEST;
+
+	MakeOutgoingFrame(pFrameBuf,					&TempLen,
+						1,							&ElementID,
+						1,							&Len,
+						sizeof(MEASURE_REQ_INFO),	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 MakeMeasurementReqFrame(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pOutBuffer,
+	OUT PULONG pFrameLen,
+	IN UINT8 TotalLen,
+	IN UINT8 Category,
+	IN UINT8 Action,
+	IN UINT8 MeasureToken,
+	IN UINT8 MeasureReqMode,
+	IN UINT8 MeasureReqType,
+	IN UINT8 NumOfRepetitions)
+{
+	ULONG TempLen;
+	MEASURE_REQ_INFO MeasureReqIE;
+
+	InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action);
+
+	// fill Dialog Token
+	InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken);
+
+	/* fill Number of repetitions. */
+	if (Category == CATEGORY_RM)
+	{
+		MakeOutgoingFrame((pOutBuffer+*pFrameLen),	&TempLen,
+						2,							&NumOfRepetitions,
+						END_OF_ARGS);
+
+		*pFrameLen += TempLen;
+	}
+
+	// prepare Measurement IE.
+	NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
+	MeasureReqIE.Token = MeasureToken;
+	MeasureReqIE.ReqMode.word = MeasureReqMode;
+	MeasureReqIE.ReqType = MeasureReqType;
+	InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen,
+		TotalLen, &MeasureReqIE);
+
+	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 = 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,
+	OUT PMEASURE_REQ pMeasureReq)
+{
+	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 = (PUCHAR)(eid_ptr->Octet + 3);
+				NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
+				NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
+				pMeasureReq->MeasureStartTime = SWAP64(MeasureStartTime);
+				NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
+				pMeasureReq->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 = (PUCHAR)(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 = (PUCHAR)(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 = (PUCHAR)(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_REQ	MeasureReq;
+	MEASURE_REPORT_MODE ReportMode;
+
+	if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, &MeasureReq))
+	{
+		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	PSTRING			arg)
+{
+	UINT Aid = 1;
+	UINT ArgIdx;
+	PSTRING thisChar;
+
+	MEASURE_REQ_MODE MeasureReqMode;
+	UINT8 MeasureReqToken = RandomByte(pAd);
+	UINT8 MeasureReqType = RM_BASIC;
+	UINT8 MeasureCh = 1;
+	UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
+	MEASURE_REQ MeasureReq;
+	UINT8 TotalLen;
+
+	HEADER_802_11 ActHdr;
+	PUCHAR pOutBuffer = NULL;
+	NDIS_STATUS NStatus;
+	ULONG FrameLen;
+
+	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__));
+		goto END_OF_MEASURE_REQ;
+	}
+
+	ArgIdx = 1;
+	while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+	{
+		switch(ArgIdx)
+		{
+			case 1:	// Aid.
+				Aid = (UINT8) 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));
+					goto END_OF_MEASURE_REQ;
+				}
+				break;
+
+			case 3: // Measurement channel.
+				MeasureCh = (UINT8) 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));
+		goto END_OF_MEASURE_REQ;
+	}
+
+	MeasureReqMode.word = 0;
+	MeasureReqMode.field.Enable = 1;
+
+	MeasureReqInsert(pAd, MeasureReqToken);
+
+	// build action frame header.
+	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pAd->MacTab.Content[Aid].Addr,
+						pAd->CurrentAddress);
+
+	NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+	FrameLen = sizeof(HEADER_802_11);
+
+	TotalLen = sizeof(MEASURE_REQ_INFO) + sizeof(MEASURE_REQ);
+
+	MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
+		sizeof(MEASURE_REQ_INFO), CATEGORY_RM, RM_BASIC,
+		MeasureReqToken, MeasureReqMode.word,
+		MeasureReqType, 0);
+
+	MeasureReq.ChNum = MeasureCh;
+	MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
+	MeasureReq.MeasureDuration = cpu2le16(2000);
+
+	{
+		ULONG TempLen;
+		MakeOutgoingFrame(	pOutBuffer+FrameLen,	&TempLen,
+							sizeof(MEASURE_REQ),	&MeasureReq,
+							END_OF_ARGS);
+		FrameLen += TempLen;
+	}
+
+	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (UINT)FrameLen);
+
+END_OF_MEASURE_REQ:
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+	return TRUE;
+}
+
+INT Set_TpcReq_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UINT Aid;
+
+	UINT8 TpcReqToken = RandomByte(pAd);
+
+	Aid = (UINT) 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/rt3090/config.mk b/drivers/staging/rt3090/config.mk
new file mode 100644
index 0000000..4c90c40
--- /dev/null
+++ b/drivers/staging/rt3090/config.mk
@@ -0,0 +1,187 @@
+# Support ATE function
+HAS_ATE=y
+
+# Support 28xx QA ATE function
+HAS_28xx_QA=n
+
+
+HAS_NINTENDO=n
+
+# Support LLTD function
+HAS_LLTD=n
+
+# Support WDS function
+HAS_WDS=n
+
+# Support AP-Client function
+HAS_APCLI=n
+
+# Support Wpa_Supplicant
+HAS_WPA_SUPPLICANT=y
+
+# Support Native WpaSupplicant for Network Maganger
+HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y
+
+#Support Net interface block while Tx-Sw queue full
+HAS_BLOCK_NET_IF=n
+
+#Support IGMP-Snooping function.
+HAS_IGMP_SNOOP_SUPPORT=n
+
+#Support DFS function
+HAS_DFS_SUPPORT=n
+
+#Support Carrier-Sense function
+HAS_CS_SUPPORT=n
+
+# Support for STA Ethernet Converter
+HAS_ETH_CONVERT_SUPPORT=n
+
+# Support user specific transmit rate of Multicast packet.
+HAS_MCAST_RATE_SPECIFIC_SUPPORT=n
+
+# Support for Multiple Cards
+HAS_MC_SUPPORT=n
+
+#Support for PCI-MSI
+HAS_MSI_SUPPORT=n
+
+
+#Support for IEEE802.11e DLS
+HAS_QOS_DLS_SUPPORT=n
+
+#Support for EXT_CHANNEL
+HAS_EXT_BUILD_CHANNEL_LIST=n
+
+#Support for IDS
+HAS_IDS_SUPPORT=n
+
+
+#Support for Net-SNMP
+HAS_SNMP_SUPPORT=n
+
+#Support features of 802.11n Draft3
+HAS_DOT11N_DRAFT3_SUPPORT=n
+
+#Support features of Single SKU.
+HAS_SINGLE_SKU_SUPPORT=n
+
+#Support features of 802.11n
+HAS_DOT11_N_SUPPORT=y
+
+
+
+#Support for 2860/2880 co-exist
+HAS_RT2880_RT2860_COEXIST=n
+
+HAS_KTHREAD_SUPPORT=n
+
+
+#Support for Auto channel select enhance
+HAS_AUTO_CH_SELECT_ENHANCE=n
+
+#Support bypass bridge
+HAS_BG_FT_SUPPORT=n
+
+#Support Antenna Diversity
+HAS_ANTENNA_DIVERSITY_SUPPORT=y
+#################################################
+
+WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT  -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs -Wpointer-sign
+
+ifeq ($(HAS_KTHREAD_SUPPORT),y)
+WFLAGS += -DKTHREAD_SUPPORT
+endif
+
+
+#################################################
+
+# config for STA mode
+
+WFLAGS += -DCONFIG_STA_SUPPORT -DDBG
+
+ifeq ($(HAS_WPA_SUPPLICANT),y)
+WFLAGS += -DWPA_SUPPLICANT_SUPPORT
+ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
+WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
+endif
+endif
+
+
+ifeq ($(HAS_ETH_CONVERT_SUPPORT), y)
+WFLAGS += -DETH_CONVERT_SUPPORT  -DMAT_SUPPORT
+endif
+
+ifeq ($(HAS_ATE),y)
+WFLAGS += -DRALINK_ATE
+ifeq ($(HAS_28xx_QA),y)
+WFLAGS += -DRALINK_28xx_QA
+endif
+endif
+
+
+ifeq ($(HAS_SNMP_SUPPORT),y)
+WFLAGS += -DSNMP_SUPPORT
+endif
+
+ifeq ($(HAS_QOS_DLS_SUPPORT),y)
+WFLAGS += -DQOS_DLS_SUPPORT
+endif
+
+ifeq ($(HAS_DOT11_N_SUPPORT),y)
+WFLAGS += -DDOT11_N_SUPPORT
+endif
+
+ifeq ($(HAS_CS_SUPPORT),y)
+WFLAGS += -DCARRIER_DETECTION_SUPPORT
+endif
+
+ifeq ($(HAS_ANTENNA_DIVERSITY_SUPPORT),y)
+WFLAGS += -DANT_DIVERSITY_SUPPORT
+endif
+
+#################################################
+
+#################################################
+
+#
+# Common compiler flag
+#
+
+
+
+
+
+ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
+WFLAGS += -DEXT_BUILD_CHANNEL_LIST
+endif
+
+ifeq ($(HAS_IDS_SUPPORT),y)
+WFLAGS += -DIDS_SUPPORT
+endif
+
+
+#################################################
+# ChipSet specific definitions.
+#
+WFLAGS +=-DRTMP_MAC_PCI -DRT30xx -DRT3090  -DRTMP_PCI_SUPPORT -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT
+#################################################
+
+
+ifeq ($(HAS_BLOCK_NET_IF),y)
+WFLAGS += -DBLOCK_NET_IF
+endif
+
+ifeq ($(HAS_DFS_SUPPORT),y)
+WFLAGS += -DDFS_SUPPORT
+endif
+
+ifeq ($(HAS_MC_SUPPORT),y)
+WFLAGS += -DMULTIPLE_CARD_SUPPORT
+endif
+
+ifeq ($(HAS_LLTD),y)
+WFLAGS += -DLLTD_SUPPORT
+endif
+
+EXTRA_CFLAGS := $(WFLAGS)
diff --git a/drivers/staging/rt3090/crypt_hmac.h b/drivers/staging/rt3090/crypt_hmac.h
new file mode 100644
index 0000000..557ca73
--- /dev/null
+++ b/drivers/staging/rt3090/crypt_hmac.h
@@ -0,0 +1,81 @@
+/*
+ *************************************************************************
+ * 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:
+    crypt_hmac.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Eddy        2008/11/24      Create HMAC-SHA1, HMAC-SHA256
+*/
+
+#ifndef __CRYPT_HMAC_H__
+#define __CRYPT_HMAC_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+#ifdef SHA1_SUPPORT
+#define HMAC_SHA1_SUPPORT
+VOID HMAC_SHA1 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen);
+#endif /* SHA1_SUPPORT */
+
+#ifdef SHA256_SUPPORT
+#define HMAC_SHA256_SUPPORT
+VOID HMAC_SHA256 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen);
+#endif /* SHA256_SUPPORT */
+
+#ifdef MD5_SUPPORT
+#define HMAC_MD5_SUPPORT
+VOID HMAC_MD5 (
+    IN  const UINT8 Key[],
+    IN  UINT KeyLen,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 MAC[],
+    IN  UINT MACLen);
+#endif /* MD5_SUPPORT */
+
+#endif /* __CRYPT_HMAC_H__ */
diff --git a/drivers/staging/rt3090/crypt_md5.h b/drivers/staging/rt3090/crypt_md5.h
new file mode 100644
index 0000000..7ee3f42
--- /dev/null
+++ b/drivers/staging/rt3090/crypt_md5.h
@@ -0,0 +1,78 @@
+/*
+ *************************************************************************
+ * 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:
+    crypt_md5.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Eddy        2008/11/24      Create md5
+*/
+
+#ifndef __CRYPT_MD5_H__
+#define __CRYPT_MD5_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+/* Algorithm options */
+#define MD5_SUPPORT
+
+#ifdef MD5_SUPPORT
+#define MD5_BLOCK_SIZE    64 /* 512 bits = 64 bytes */
+#define MD5_DIGEST_SIZE   16 /* 128 bits = 16 bytes */
+typedef struct {
+    UINT32 HashValue[4];
+    UINT64 MessageLen;
+    UINT8  Block[MD5_BLOCK_SIZE];
+    UINT   BlockLen;
+} MD5_CTX_STRUC, *PMD5_CTX_STRUC;
+
+VOID MD5_Init (
+    IN  MD5_CTX_STRUC *pMD5_CTX);
+VOID MD5_Hash (
+    IN  MD5_CTX_STRUC *pMD5_CTX);
+VOID MD5_Append (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen);
+VOID MD5_End (
+    IN  MD5_CTX_STRUC *pMD5_CTX,
+    OUT UINT8 DigestMessage[]);
+VOID RT_MD5 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[]);
+#endif /* MD5_SUPPORT */
+
+#endif /* __CRYPT_MD5_H__ */
diff --git a/drivers/staging/rt3090/crypt_sha2.h b/drivers/staging/rt3090/crypt_sha2.h
new file mode 100644
index 0000000..85c0403
--- /dev/null
+++ b/drivers/staging/rt3090/crypt_sha2.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:
+    crypt_sha2.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+    Eddy        2008/11/24      Create SHA1
+    Eddy        2008/07/23      Create SHA256
+*/
+
+#ifndef __CRYPT_SHA2_H__
+#define __CRYPT_SHA2_H__
+
+#ifdef CRYPT_TESTPLAN
+#include "crypt_testplan.h"
+#else
+#include "rt_config.h"
+#endif /* CRYPT_TESTPLAN */
+
+/* Algorithm options */
+#define SHA1_SUPPORT
+#define SHA256_SUPPORT
+
+#ifdef SHA1_SUPPORT
+#define SHA1_BLOCK_SIZE    64 /* 512 bits = 64 bytes */
+#define SHA1_DIGEST_SIZE   20 /* 160 bits = 20 bytes */
+typedef struct _SHA1_CTX_STRUC {
+    UINT32 HashValue[5];  /* 5 = (SHA1_DIGEST_SIZE / 32) */
+    UINT64 MessageLen;    /* total size */
+    UINT8  Block[SHA1_BLOCK_SIZE];
+    UINT   BlockLen;
+} SHA1_CTX_STRUC, *PSHA1_CTX_STRUC;
+
+VOID SHA1_Init (
+    IN  SHA1_CTX_STRUC *pSHA_CTX);
+VOID SHA1_Hash (
+    IN  SHA1_CTX_STRUC *pSHA_CTX);
+VOID SHA1_Append (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen);
+VOID SHA1_End (
+    IN  SHA1_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[]);
+VOID RT_SHA1 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[]);
+#endif /* SHA1_SUPPORT */
+
+#ifdef SHA256_SUPPORT
+#define SHA256_BLOCK_SIZE   64 /* 512 bits = 64 bytes */
+#define SHA256_DIGEST_SIZE  32 /* 256 bits = 32 bytes */
+typedef struct _SHA256_CTX_STRUC {
+    UINT32 HashValue[8];  /* 8 = (SHA256_DIGEST_SIZE / 32) */
+    UINT64 MessageLen;    /* total size */
+    UINT8  Block[SHA256_BLOCK_SIZE];
+    UINT   BlockLen;
+} SHA256_CTX_STRUC, *PSHA256_CTX_STRUC;
+
+VOID SHA256_Init (
+    IN  SHA256_CTX_STRUC *pSHA_CTX);
+VOID SHA256_Hash (
+    IN  SHA256_CTX_STRUC *pSHA_CTX);
+VOID SHA256_Append (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen);
+VOID SHA256_End (
+    IN  SHA256_CTX_STRUC *pSHA_CTX,
+    OUT UINT8 DigestMessage[]);
+VOID RT_SHA256 (
+    IN  const UINT8 Message[],
+    IN  UINT MessageLen,
+    OUT UINT8 DigestMessage[]);
+#endif /* SHA256_SUPPORT */
+
+#endif /* __CRYPT_SHA2_H__ */
diff --git a/drivers/staging/rt3090/dfs.h b/drivers/staging/rt3090/dfs.h
new file mode 100644
index 0000000..506468e
--- /dev/null
+++ b/drivers/staging/rt3090/dfs.h
@@ -0,0 +1,137 @@
+/*
+ *************************************************************************
+ * 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:
+    Miniport generic portion header file
+
+    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
+
+
+
+/*************************************************************************
+  *
+  *	DFS Radar related definitions.
+  *
+  ************************************************************************/
+//#define CARRIER_DETECT_TASK_NUM	6
+//#define RADAR_DETECT_TASK_NUM	7
+
+// McuRadarState && McuCarrierState for 2880-SW-MCU
+#define FREE_FOR_TX				0
+#define WAIT_CTS_BEING_SENT		1
+#define DO_DETECTION			2
+
+// McuRadarEvent
+#define RADAR_EVENT_CTS_SENT			0x01 // Host signal MCU that CTS has been sent
+#define RADAR_EVENT_CTS_CARRIER_SENT	0x02 // Host signal MCU that CTS has been sent (Carrier)
+#define RADAR_EVENT_RADAR_DETECTING		0x04 // Radar detection is on going, carrier detection hold back
+#define RADAR_EVENT_CARRIER_DETECTING	0x08 // Carrier detection is on going, radar detection hold back
+#define RADAR_EVENT_WIDTH_RADAR			0x10 // BBP == 2 radar detected
+#define RADAR_EVENT_CTS_KICKED			0x20 // Radar detection need to sent double CTS, first CTS sent
+
+// McuRadarCmd
+#define DETECTION_STOP			0
+#define RADAR_DETECTION			1
+#define CARRIER_DETECTION		2
+
+
+
+#ifdef TONE_RADAR_DETECT_SUPPORT
+INT Set_CarrierCriteria_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+int Set_CarrierReCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+INT Set_CarrierStopCheck_Proc(IN PRTMP_ADAPTER pAd, IN PSTRING arg);
+void NewCarrierDetectionStart(PRTMP_ADAPTER pAd);
+void RTMPHandleRadarInterrupt(PRTMP_ADAPTER  pAd);
+VOID CSAsicDisableSync(IN PRTMP_ADAPTER pAd);
+#endif // TONE_RADAR_DETECT_SUPPORT //
+
+
+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 PSTRING arg);
+
+INT Set_LongPulseRadarTh_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg);
diff --git a/drivers/staging/rt3090/eeprom.h b/drivers/staging/rt3090/eeprom.h
new file mode 100644
index 0000000..ee0e807
--- /dev/null
+++ b/drivers/staging/rt3090/eeprom.h
@@ -0,0 +1,82 @@
+/*
+ *************************************************************************
+ * 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.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+#ifndef __EEPROM_H__
+#define __EEPROM_H__
+
+
+
+#ifdef RTMP_PCI_SUPPORT
+/*************************************************************************
+  *	Public function declarations for prom-based chipset
+  ************************************************************************/
+int rtmp_ee_prom_read16(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			Offset,
+	OUT USHORT			*pValue);
+
+int rtmp_ee_prom_write16(
+	IN PRTMP_ADAPTER	pAd,
+	IN USHORT			Offset,
+	IN USHORT			value);
+#endif // RTMP_PCI_SUPPORT //
+
+
+
+
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+int rtmp_ee_efuse_read16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	OUT USHORT *pValue);
+
+int rtmp_ee_efuse_write16(
+	IN RTMP_ADAPTER *pAd,
+	IN USHORT Offset,
+	IN USHORT data);
+#endif // RTMP_EFUSE_SUPPORT //
+#endif // RT30xx //
+
+/*************************************************************************
+  *	Public function declarations for prom operation callback functions setting
+  ************************************************************************/
+INT RtmpChipOpsEepromHook(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			infType);
+
+#endif // __EEPROM_H__ //
diff --git a/drivers/staging/rt3090/firmware.h b/drivers/staging/rt3090/firmware.h
new file mode 100644
index 0000000..f2836a2
--- /dev/null
+++ b/drivers/staging/rt3090/firmware.h
@@ -0,0 +1,517 @@
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+UCHAR FirmwareImage [] = {
+0x02, 0x02, 0xf3, 0x02, 0x02, 0xa1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x27, 0xff, 0xff,
+0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xd8, 0xc0, 0xe0,
+0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
+0x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
+0xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x36,
+0x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
+0x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
+0x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
+0x50, 0x85, 0x36, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
+0x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x36, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
+0x36, 0x12, 0x02, 0x7d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
+0xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
+0x36, 0x12, 0x02, 0x7d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
+0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82,
+0xc0, 0xd0, 0xe8, 0xc0, 0xe0, 0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0,
+0xe0, 0xed, 0xc0, 0xe0, 0xee, 0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12,
+0x10, 0x12, 0xd2, 0xaf, 0xd0, 0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc,
+0xd0, 0xe0, 0xfb, 0xd0, 0xe0, 0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82,
+0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0,
+0xd0, 0x75, 0xd0, 0x10, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5,
+0x54, 0x60, 0x04, 0x15, 0x54, 0x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04,
+0x15, 0x50, 0x80, 0x02, 0xc2, 0x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04,
+0x30, 0x45, 0x03, 0x12, 0x10, 0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83,
+0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x43, 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, 0x37, 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, 0xc2, 0x05, 0xd2, 0xaf, 0x22,
+0x12, 0x02, 0xc3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12,
+0x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b,
+0x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09,
+0x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12,
+0x03, 0x1c, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5,
+0x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18,
+0x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x1a, 0xc2, 0x18, 0xc2, 0x1b, 0x22,
+0xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16,
+0x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8,
+0xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12,
+0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
+0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60,
+0x1f, 0xe4, 0xfe, 0x12, 0x03, 0x5b, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x5b, 0xef, 0xf0, 0x74,
+0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3,
+0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
+0x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0,
+0xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x04, 0x12, 0x02, 0xdc, 0xe4, 0xf5,
+0x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x75, 0x89, 0x02, 0xe4,
+0xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75,
+0xa8, 0x05, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xc0, 0xff,
+0xc0, 0x26, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x0a, 0x22, 0xc0, 0x26,
+0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x18, 0x22, 0x30, 0x45, 0x03, 0x12,
+0x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
+0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x71, 0x1e, 0x80, 0xf5, 0x22, 0xc8,
+0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22, 0xc8, 0xef, 0xc8,
+0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x74, 0x14, 0x2e, 0xf5, 0x82,
+0xe4, 0x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x6f, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a,
+0x18, 0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x13, 0x68, 0x02,
+0x13, 0x69, 0x02, 0x14, 0x1e, 0x02, 0x14, 0x1f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x19, 0xa1, 0x02,
+0x1b, 0x31, 0x02, 0x14, 0xea, 0x02, 0x14, 0x20, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x01,
+0x75, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x1c, 0x4f, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
+0x20, 0xe7, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
+0x12, 0x02, 0x57, 0x11, 0x11, 0x30, 0x10, 0xe2, 0x31, 0x10, 0x90, 0x33, 0x10, 0xa0, 0x34, 0x10,
+0xbe, 0x35, 0x10, 0xac, 0x36, 0x11, 0x1f, 0x50, 0x11, 0x68, 0x51, 0x11, 0x71, 0x52, 0x11, 0x71,
+0x53, 0x11, 0x71, 0x54, 0x11, 0xb3, 0x55, 0x12, 0x16, 0x70, 0x12, 0x42, 0x71, 0x12, 0x71, 0x72,
+0x12, 0xda, 0x73, 0x12, 0xfe, 0x80, 0x13, 0x29, 0x83, 0x13, 0x47, 0x84, 0x00, 0x00, 0x13, 0x67,
+0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x2a, 0x75, 0x32, 0x0b, 0x75, 0x33, 0xb8, 0x02, 0x13, 0x62,
+0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0, 0x54, 0xfd, 0xf0, 0x02, 0x13, 0x62, 0x90, 0x70, 0x11, 0xe0,
+0xf5, 0x3c, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x22, 0xe5, 0x55,
+0xb4, 0x02, 0x0f, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x7d, 0x01,
+0x80, 0x02, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
+0x13, 0x62, 0x20, 0x02, 0x03, 0x30, 0x03, 0x10, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90,
+0x01, 0x0c, 0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x85, 0x56, 0x41, 0xd2, 0x02,
+0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4, 0x70, 0x03, 0x02, 0x13, 0x67, 0xe0, 0xf5, 0x30, 0x22, 0xe5,
+0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x67, 0x90, 0x70, 0x10,
+0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a, 0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e,
+0x01, 0x75, 0x4f, 0x84, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x13,
+0x67, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x13,
+0x67, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47,
+0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09, 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, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
+0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13,
+0x09, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x23, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x1d, 0xe5, 0x47, 0x64,
+0x09, 0x60, 0x17, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x0b, 0xe5,
+0x47, 0x64, 0x0d, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x0d, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f,
+0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5,
+0x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a, 0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56,
+0x12, 0x02, 0x7d, 0xd2, 0x04, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60,
+0x03, 0x02, 0x13, 0x09, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8,
+0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02,
+0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x09,
+0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0,
+0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13,
+0x62, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0x90, 0x10, 0x02, 0xe0, 0xf5, 0x58, 0xa3, 0xe0, 0xf5,
+0x59, 0xe5, 0x58, 0xb4, 0x70, 0x1e, 0xe5, 0x59, 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, 0xc2, 0x1a, 0xc2, 0x18,
+0xc2, 0x1b, 0xf5, 0x34, 0x90, 0x05, 0xa4, 0x74, 0x11, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0xa3, 0x74,
+0x03, 0xf0, 0xe4, 0xf5, 0x30, 0xc2, 0x19, 0x75, 0x3c, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
+0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x02, 0x13, 0x62, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40,
+0x06, 0xe5, 0x55, 0x60, 0x02, 0x80, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4,
+0xfd, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x64, 0xe5, 0x34,
+0xc3, 0x94, 0x03, 0x40, 0x0b, 0xe5, 0x55, 0x60, 0x07, 0x7d, 0x03, 0xaf, 0x56, 0x02, 0x02, 0x7d,
+0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02,
+0x7d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x39, 0xe4, 0xf5, 0x34, 0xf5, 0x30, 0x90, 0x70,
+0x10, 0xe0, 0xf4, 0x60, 0x03, 0xe0, 0xf5, 0x34, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0x80, 0x1b, 0xd2, 0x19, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x1a, 0x03,
+0xe4, 0xf5, 0x2f, 0xd2, 0x04, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x7d, 0x90, 0x04, 0x14, 0x74,
+0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0x22, 0x22, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x17,
+0xe5, 0x55, 0xb4, 0x02, 0x12, 0xe5, 0x30, 0x60, 0x0e, 0x30, 0x60, 0x0b, 0x74, 0xfd, 0x25, 0x46,
+0xf5, 0x46, 0xd2, 0x04, 0xe4, 0xf5, 0x53, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x14, 0x1d, 0x30, 0x60,
+0x21, 0xb2, 0x4d, 0x30, 0x4d, 0x1c, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x11, 0xe5, 0x55, 0xb4,
+0x02, 0x0c, 0xe5, 0x30, 0x60, 0x08, 0x74, 0x03, 0x25, 0x46, 0xf5, 0x46, 0x80, 0x02, 0x05, 0x46,
+0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e,
+0x30, 0x1a, 0x49, 0x7f, 0x32, 0x7d, 0xb8, 0x7c, 0x0b, 0x12, 0x02, 0x30, 0x50, 0x06, 0x90, 0x04,
+0x10, 0x74, 0x40, 0xf0, 0x7f, 0x35, 0x7d, 0x32, 0x12, 0x03, 0x3f, 0x50, 0x09, 0x90, 0x10, 0x04,
+0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5, 0x35, 0xd3, 0x94, 0x2d, 0x40, 0x30, 0x30, 0x1b, 0x2d,
+0xc2, 0x1b, 0xa2, 0x18, 0x92, 0x1a, 0x20, 0x1a, 0x24, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0,
+0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0, 0xc2, 0x61, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2,
+0x18, 0x92, 0x1a, 0x30, 0x1a, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22,
+0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x57, 0x14, 0x42, 0x00, 0x14, 0xd5, 0x04, 0x14,
+0xd1, 0x08, 0x14, 0xac, 0x10, 0x14, 0x56, 0x20, 0x14, 0x76, 0x60, 0x14, 0x87, 0xa0, 0x00, 0x00,
+0x14, 0xd7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60,
+0x03, 0x02, 0x14, 0xd7, 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, 0x2a, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff,
+0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x1a, 0x24, 0xc0,
+0x60, 0x0a, 0x24, 0x35, 0x70, 0x09, 0x12, 0x19, 0x5f, 0x12, 0x15, 0x09, 0x12, 0x19, 0x5f, 0x12,
+0x15, 0x09, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0x54,
+0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2,
+0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74, 0x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f,
+0xf5, 0x2d, 0xe5, 0x2a, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5, 0x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d,
+0x29, 0xe5, 0x5f, 0x54, 0x30, 0x64, 0x30, 0x70, 0x21, 0xe5, 0x2a, 0x70, 0x15, 0xe5, 0x34, 0xc3,
+0x94, 0x03, 0x40, 0x09, 0xe5, 0x30, 0x60, 0x05, 0x75, 0x2a, 0x05, 0x80, 0x07, 0x75, 0x2a, 0x0c,
+0x80, 0x02, 0x15, 0x2a, 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, 0x2a, 0x70, 0x03, 0x30, 0x4c, 0x11, 0xc2,
+0x4c, 0xe5, 0x2a, 0x70, 0x05, 0x75, 0x2a, 0x07, 0x80, 0x02, 0x15, 0x2a, 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, 0xe5, 0x47, 0xb4, 0x0a, 0x13, 0xe5, 0x3a,
+0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a, 0x70, 0x04, 0xd2, 0x6c, 0xc2,
+0x6d, 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, 0x75,
+0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x45, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
+0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
+0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 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, 0x45, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2,
+0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00,
+0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 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, 0x64, 0xe5, 0x47, 0x64, 0x0a, 0x70, 0x19, 0xe5,
+0x3a, 0xb4, 0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x53, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30,
+0xe5, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x80, 0x45, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80,
+0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5,
+0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 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, 0x2c, 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, 0x46, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60,
+0x14, 0x24, 0xfe, 0x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x19, 0x5e, 0x90, 0x02, 0x28, 0xe0,
+0x30, 0x47, 0x0d, 0x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22,
+0x44, 0x01, 0xf0, 0x22, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90,
+0x02, 0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47,
+0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x27, 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, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0c, 0x60, 0x09, 0xe5, 0x47, 0x64,
+0x0b, 0x60, 0x03, 0x02, 0x18, 0xc6, 0xe4, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd, 0xf0,
+0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24,
+0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03,
+0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35,
+0xa2, 0x47, 0x92, 0x39, 0x80, 0x47, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
+0x39, 0x80, 0x3a, 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, 0x39, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03,
+0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x05, 0xa2, 0x47, 0xb3, 0x92, 0x39, 0x90, 0x02, 0x28,
+0xe0, 0x54, 0xfd, 0x02, 0x19, 0x5b, 0xe5, 0x47, 0x64, 0x0d, 0x60, 0x03, 0x02, 0x19, 0x5e, 0xf5,
+0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xef, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2b, 0x14, 0x60, 0x2e,
+0x14, 0x60, 0x38, 0x24, 0xfc, 0x60, 0x5c, 0x24, 0xf9, 0x60, 0x1d, 0x24, 0x0e, 0x70, 0x61, 0xe5,
+0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x80, 0x35, 0xa2, 0x47, 0x92, 0x3c, 0x80, 0x47, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x3a, 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,
+0x3c, 0x80, 0x12, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x3c, 0x80, 0x05,
+0xa2, 0x47, 0xb3, 0x92, 0x3c, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xef, 0x45, 0x27, 0xf0, 0x22, 0xe5,
+0x47, 0x64, 0x0b, 0x70, 0x1c, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb, 0xf0, 0x30, 0x47, 0x04, 0xaf,
+0x45, 0x80, 0x05, 0xe5, 0x45, 0x64, 0x14, 0xff, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xeb, 0x4f, 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, 0x37, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a, 0x14, 0x60, 0x6b, 0x24, 0x02,
+0x60, 0x03, 0x02, 0x1b, 0x12, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20, 0x1a, 0x1c, 0x90, 0x02, 0x08,
+0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3,
+0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20, 0x12, 0x19, 0x97, 0x90, 0x10,
+0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x1b, 0x12, 0xe5, 0x50, 0x70, 0x06, 0x75,
+0x37, 0x03, 0x02, 0x1b, 0x12, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x15, 0x7f, 0x20, 0x12,
+0x19, 0x97, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb, 0xf0, 0x75, 0x51, 0x02, 0x02,
+0x1b, 0x12, 0xe5, 0x50, 0x70, 0x03, 0x02, 0x1b, 0x0d, 0x20, 0x1a, 0x15, 0x90, 0x02, 0x08, 0xe0,
+0x30, 0xe3, 0x03, 0x02, 0x1b, 0x09, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x1b,
+0x09, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x15, 0xe5, 0x59, 0xb4, 0x35,
+0x10, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03,
+0xf0, 0x7f, 0x01, 0x12, 0x03, 0x30, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54,
+0xf0, 0xf0, 0xe5, 0x59, 0xb4, 0x35, 0x14, 0xe5, 0x3c, 0xf4, 0x60, 0x06, 0xa3, 0xe0, 0x54, 0xf3,
+0x80, 0x14, 0x90, 0x13, 0x2a, 0xe0, 0x54, 0xfb, 0xf0, 0x80, 0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13,
+0x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80, 0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x20,
+0x1a, 0x07, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x10, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x09,
+0xe5, 0x30, 0x70, 0x05, 0x75, 0x8c, 0x40, 0x80, 0x03, 0x75, 0x8c, 0x80, 0x90, 0x04, 0x01, 0xe0,
+0x54, 0xfd, 0xf0, 0x20, 0x1a, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x59, 0xb4,
+0x28, 0x06, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x31, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x14, 0x90,
+0x01, 0x0d, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x59, 0x64, 0x35, 0x60, 0x07, 0x90, 0x12, 0x04, 0xe0,
+0x54, 0xfd, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x14, 0x20, 0x02, 0x11, 0x20, 0x03, 0x0e,
+0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x37,
+0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x37, 0x03,
+0xf5, 0x51, 0xe5, 0x37, 0x60, 0x18, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x1a, 0x0e,
+0xad, 0x37, 0xaf, 0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x37, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf,
+0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf,
+0x40, 0x12, 0x1c, 0x1b, 0xe5, 0x52, 0x14, 0x60, 0x5c, 0x14, 0x60, 0x3a, 0x24, 0x02, 0x60, 0x03,
+0x02, 0x1c, 0x18, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x0c, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x02,
+0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0xe5, 0x34, 0xc3, 0x94, 0x02, 0x40, 0x13, 0x90, 0x12, 0x04,
+0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x32, 0x12, 0x03, 0x30, 0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfe, 0xf0,
+0x75, 0x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x59, 0xb4, 0x28, 0x06, 0x90, 0x01, 0x0d, 0xe5, 0x31,
+0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x19, 0x9c, 0x75, 0x52, 0x01,
+0x75, 0x55, 0x03, 0x80, 0x73, 0xe5, 0x54, 0x70, 0x6f, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0,
+0x20, 0x1a, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0xf5, 0x8c, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f,
+0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03,
+0xf0, 0xe5, 0x58, 0xb4, 0x72, 0x16, 0xe5, 0x59, 0xb4, 0x35, 0x11, 0x90, 0x05, 0x00, 0x74, 0xe2,
+0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x03,
+0x30, 0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44,
+0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41,
+0x12, 0x1c, 0x1b, 0x30, 0x03, 0x02, 0xc2, 0x03, 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, 0x30,
+0x1a, 0x77, 0x90, 0x04, 0x37, 0xe0, 0x20, 0xe5, 0x6c, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x38, 0xa3,
+0xe0, 0xf5, 0x37, 0xf5, 0x39, 0xe4, 0xf5, 0x25, 0xe5, 0x39, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00,
+0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x37, 0x65, 0x39, 0x70, 0x05, 0xfc, 0x7d, 0x28, 0x80,
+0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee, 0x3c, 0xfe, 0x12, 0x1c, 0xca, 0x50, 0x07,
+0x90, 0x01, 0x14, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x39, 0x65, 0x38, 0x60, 0x10, 0xe4, 0x25, 0x39,
+0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x39, 0x80, 0xbb, 0x90, 0x04, 0x10,
+0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x38, 0xf0, 0xa3, 0xe5, 0x37, 0xf0, 0x90, 0x04, 0x11,
+0x74, 0x01, 0xf0, 0x80, 0x8d, 0xc2, 0x06, 0xd2, 0x1b, 0x22, 0xe5, 0x25, 0xc3, 0x94, 0x06, 0x50,
+0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xb4, 0xff, 0x07, 0x05, 0x25, 0xe4, 0xf5, 0x24, 0x80, 0x2e,
+0xe4, 0xf5, 0x25, 0x8f, 0x82, 0x8e, 0x83, 0xf0, 0x80, 0x24, 0xe5, 0x24, 0x75, 0xf0, 0x06, 0x84,
+0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e,
+0x83, 0xe0, 0x6d, 0x70, 0x06, 0x05, 0x25, 0x05, 0x24, 0x80, 0x03, 0xe4, 0xf5, 0x25, 0x0f, 0xbf,
+0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x07, 0xe5, 0x25, 0xc3, 0x94, 0x2a, 0x40, 0xab, 0xe5,
+0x25, 0xb4, 0x2a, 0x03, 0xd3, 0x80, 0x01, 0xc3, 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, 0x13, 0xe3, 0x34, } ;
diff --git a/drivers/staging/rt3090/igmp_snoop.h b/drivers/staging/rt3090/igmp_snoop.h
new file mode 100644
index 0000000..63f9692
--- /dev/null
+++ b/drivers/staging/rt3090/igmp_snoop.h
@@ -0,0 +1,152 @@
+/*
+ *************************************************************************
+ * 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:
+    igmp_snoop.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+
+
+#ifndef __RTMP_IGMP_SNOOP_H__
+#define __RTMP_IGMP_SNOOP_H__
+
+#include "link_list.h"
+
+#define IGMP_PROTOCOL_DESCRIPTOR	0x02
+#define IGMP_V1_MEMBERSHIP_REPORT	0x12
+#define IGMP_V2_MEMBERSHIP_REPORT	0x16
+#define IGMP_LEAVE_GROUP			0x17
+#define IGMP_V3_MEMBERSHIP_REPORT	0x22
+
+#define MLD_V1_LISTENER_REPORT		131
+#define MLD_V1_LISTENER_DONE		132
+#define MLD_V2_LISTERNER_REPORT		143
+
+#define IGMPMAC_TB_ENTRY_AGEOUT_TIME 120 * OS_HZ
+
+#define MULTICAST_ADDR_HASH_INDEX(Addr)      (MAC_ADDR_HASH(Addr) % (MAX_LEN_OF_MULTICAST_FILTER_HASH_TABLE))
+
+#define IS_MULTICAST_MAC_ADDR(Addr)			((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff))
+#define IS_BROADCAST_MAC_ADDR(Addr)			((((Addr[0]) & 0xff) == 0xff))
+
+VOID MulticastFilterTableInit(
+	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
+
+VOID MultiCastFilterTableReset(
+	IN PMULTICAST_FILTER_TABLE *ppMulticastFilterTable);
+
+BOOLEAN MulticastFilterTableInsertEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pGrpId,
+	IN PUCHAR pMemberAddr,
+	IN PNET_DEV dev,
+	IN MulticastFilterEntryType type);
+
+BOOLEAN MulticastFilterTableDeleteEntry(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pGrpId,
+	IN PUCHAR pMemberAddr,
+	IN PNET_DEV dev);
+
+PMULTICAST_FILTER_TABLE_ENTRY MulticastFilterTableLookup(
+	IN PMULTICAST_FILTER_TABLE pMulticastFilterTable,
+	IN PUCHAR pAddr,
+	IN PNET_DEV dev);
+
+BOOLEAN isIgmpPkt(
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pIpHeader);
+
+VOID IGMPSnooping(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pSrcMacAddr,
+	IN PUCHAR pIpHeader,
+	IN PNET_DEV pDev);
+
+BOOLEAN isMldPkt(
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pIpHeader,
+	OUT UINT8 *pProtoType,
+	OUT PUCHAR *pMldHeader);
+
+VOID MLDSnooping(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pDstMacAddr,
+	IN PUCHAR pSrcMacAddr,
+	IN PUCHAR pIpHeader,
+	IN PNET_DEV pDev);
+
+UCHAR IgmpMemberCnt(
+	IN PLIST_HEADER pList);
+
+VOID IgmpGroupDelMembers(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pMemberAddr,
+	IN PNET_DEV pDev);
+
+INT Set_IgmpSn_Enable_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg);
+
+INT Set_IgmpSn_AddEntry_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg);
+
+INT Set_IgmpSn_DelEntry_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg);
+
+INT Set_IgmpSn_TabDisplay_Proc(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING arg);
+
+void rtmp_read_igmp_snoop_from_file(
+	IN  PRTMP_ADAPTER pAd,
+	PSTRING tmpbuf,
+	PSTRING buffer);
+
+NDIS_STATUS IgmpPktInfoQuery(
+	IN PRTMP_ADAPTER pAd,
+	IN PUCHAR pSrcBufVA,
+	IN PNDIS_PACKET pPacket,
+	IN UCHAR apidx,
+	OUT BOOLEAN *pInIgmpGroup,
+	OUT PMULTICAST_FILTER_TABLE_ENTRY *ppGroupEntry);
+
+NDIS_STATUS IgmpPktClone(
+	IN PRTMP_ADAPTER pAd,
+	IN PNDIS_PACKET pPacket,
+	IN UCHAR QueIdx,
+	IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry);
+
+#endif /* __RTMP_IGMP_SNOOP_H__ */
diff --git a/drivers/staging/rt3090/ipv6.h b/drivers/staging/rt3090/ipv6.h
new file mode 100644
index 0000000..c34a5f2
--- /dev/null
+++ b/drivers/staging/rt3090/ipv6.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:
+    ipv6.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+*/
+
+#ifndef __IPV6_HDR_H_
+#define __IPV6_HDR_H_
+
+#define IPV6_ADDR_LEN 16
+#define IPV6_HDR_LEN  40
+
+// IPv6 address definition
+#define IPV6_LINK_LOCAL_ADDR_PREFIX		0xFE8
+#define IPV6_SITE_LOCAL_ADDR_PREFIX		0xFEC
+#define IPV6_LOCAL_ADDR_PREFIX			0xFE8
+#define IPV6_MULTICAST_ADDR_PREFIX		0xFF
+#define IPV6_LOOPBACK_ADDR				0x1
+#define IPV6_UNSPECIFIED_ADDR			0x0
+
+// defined as sequence in IPv6 header
+#define IPV6_NEXT_HEADER_HOP_BY_HOP		0x00	// 0
+#define IPV6_NEXT_HEADER_DESTINATION	0x3c	// 60
+#define IPV6_NEXT_HEADER_ROUTING		0x2b	// 43
+#define IPV6_NEXT_HEADER_FRAGMENT		0x2c	// 44
+#define IPV6_NEXT_HEADER_AUTHENTICATION	0x33	// 51
+#define IPV6_NEXT_HEADER_ENCAPSULATION	0x32	// 50, RFC-2406
+#define IPV6_NEXT_HEADER_NONE			0x3b	// 59
+
+#define IPV6_NEXT_HEADER_TCP			0x06
+#define IPV6_NEXT_HEADER_UDP			0x11
+#define IPV6_NEXT_HEADER_ICMPV6			0x3a
+
+// ICMPv6 msg type definition
+#define ICMPV6_MSG_TYPE_ROUTER_SOLICITATION			0x85 // 133
+#define ROUTER_SOLICITATION_FIXED_LEN				8
+
+#define ICMPV6_MSG_TYPE_ROUTER_ADVERTISEMENT		0x86 // 134
+#define ROUTER_ADVERTISEMENT_FIXED_LEN				16
+
+#define ICMPV6_MSG_TYPE_NEIGHBOR_SOLICITATION		0x87 // 135
+#define NEIGHBOR_SOLICITATION_FIXED_LEN				24
+
+#define ICMPV6_MSG_TYPE_NEIGHBOR_ADVERTISEMENT		0x88 // 136
+#define NEIGHBOR_ADVERTISEMENT_FIXED_LEN			24
+
+#define ICMPV6_MSG_TYPE_REDIRECT					0x89 // 137
+#define REDIRECT_FIXED_LEN							40
+
+/* IPv6 Address related structures */
+typedef struct rt_ipv6_addr_
+{
+	union
+	{
+		UCHAR	ipv6Addr8[16];
+		USHORT	ipv6Addr16[8];
+		UINT32	ipv6Addr32[4];
+	}addr;
+#define ipv6_addr			addr.ipv6Addr8
+#define ipv6_addr16			addr.ipv6Addr16
+#define ipv6_addr32			addr.ipv6Addr32
+}RT_IPV6_ADDR, *PRT_IPV6_ADDR;
+
+
+#define PRINT_IPV6_ADDR(ipv6Addr)	\
+	OS_NTOHS((ipv6Addr).ipv6_addr16[0]), \
+	OS_NTOHS((ipv6Addr).ipv6_addr16[1]), \
+	OS_NTOHS((ipv6Addr).ipv6_addr16[2]), \
+	OS_NTOHS((ipv6Addr).ipv6_addr16[3]), \
+	OS_NTOHS((ipv6Addr).ipv6_addr16[4]), \
+	OS_NTOHS((ipv6Addr).ipv6_addr16[5]), \
+	OS_NTOHS((ipv6Addr).ipv6_addr16[6]), \
+	OS_NTOHS((ipv6Addr).ipv6_addr16[7])
+
+
+/*IPv6 Header related structures */
+typedef struct PACKED _rt_ipv6_hdr_
+{
+	UINT32			ver:4,
+					trafficClass:8,
+				flowLabel:20;
+	USHORT			payload_len;
+	UCHAR			nextHdr;
+	UCHAR			hopLimit;
+	RT_IPV6_ADDR	srcAddr;
+	RT_IPV6_ADDR	dstAddr;
+}RT_IPV6_HDR, *PRT_IPV6_HDR;
+
+
+typedef struct PACKED _rt_ipv6_ext_hdr_
+{
+	UCHAR	nextProto; // Indicate the protocol type of next extension header.
+	UCHAR	extHdrLen; // optional field for msg length of this extension header which didn't include the first "nextProto" field.
+	UCHAR	octets[1]; // hook to extend header message body.
+}RT_IPV6_EXT_HDR, *PRT_IPV6_EXT_HDR;
+
+
+/* ICMPv6 related structures */
+typedef struct PACKED _rt_ipv6_icmpv6_hdr_
+{
+	UCHAR	type;
+	UCHAR	code;
+	USHORT	chksum;
+	UCHAR	octets[1]; //hook to extend header message body.
+}RT_ICMPV6_HDR, *PRT_ICMPV6_HDR;
+
+
+typedef struct PACKED _rt_icmp6_option_hdr_
+{
+	UCHAR type;
+	UCHAR len;
+	UCHAR octet[1];
+}RT_ICMPV6_OPTION_HDR, *PRT_ICMPV6_OPTION_HDR;
+
+typedef enum{
+// Defined ICMPv6 Option Types.
+	TYPE_SRC_LL_ADDR	= 1,
+	TYPE_TGT_LL_ADDR	= 2,
+	TYPE_PREFIX_INFO			= 3,
+	TYPE_REDIRECTED_HDR			= 4,
+	TYPE_MTU					= 5,
+}ICMPV6_OPTIONS_TYPE_DEF;
+
+
+static inline BOOLEAN IPv6ExtHdrHandle(
+	RT_IPV6_EXT_HDR		*pExtHdr,
+	UCHAR				*pProto,
+	UINT32				*pOffset)
+{
+	UCHAR nextProto = 0xff;
+	UINT32 extLen = 0;
+	BOOLEAN status = TRUE;
+
+	//printk("%s(): parsing the Extension Header with Protocol(0x%x):\n", __FUNCTION__, *pProto);
+	switch (*pProto)
+	{
+		case IPV6_NEXT_HEADER_HOP_BY_HOP:
+			// IPv6ExtHopByHopHandle();
+			nextProto = pExtHdr->nextProto;
+			extLen = (pExtHdr->extHdrLen + 1) * 8;
+			break;
+
+		case IPV6_NEXT_HEADER_DESTINATION:
+			// IPv6ExtDestHandle();
+			nextProto = pExtHdr->nextProto;
+			extLen = (pExtHdr->extHdrLen + 1) * 8;
+			break;
+
+		case IPV6_NEXT_HEADER_ROUTING:
+			// IPv6ExtRoutingHandle();
+			nextProto = pExtHdr->nextProto;
+			extLen = (pExtHdr->extHdrLen + 1) * 8;
+			break;
+
+		case IPV6_NEXT_HEADER_FRAGMENT:
+			// IPv6ExtFragmentHandle();
+			nextProto = pExtHdr->nextProto;
+			extLen = 8; // The Fragment header length is fixed to 8 bytes.
+			break;
+
+		case IPV6_NEXT_HEADER_AUTHENTICATION:
+		//   IPV6_NEXT_HEADER_ENCAPSULATION:
+			/*
+				TODO: Not support. For encryption issue.
+			*/
+			nextProto = 0xFF;
+			status = FALSE;
+			break;
+
+		default:
+			nextProto = 0xFF;
+			status = FALSE;
+			break;
+	}
+
+	*pProto = nextProto;
+	*pOffset += extLen;
+	//printk("%s(): nextProto = 0x%x!, offset=0x%x!\n", __FUNCTION__, nextProto, offset);
+
+	return status;
+
+}
+
+#endif // __IPV6_HDR_H_ //
diff --git a/drivers/staging/rt3090/link_list.h b/drivers/staging/rt3090/link_list.h
new file mode 100644
index 0000000..205b610
--- /dev/null
+++ b/drivers/staging/rt3090/link_list.h
@@ -0,0 +1,133 @@
+/*
+ *************************************************************************
+ * 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/rt3090/mac_pci.h b/drivers/staging/rt3090/mac_pci.h
new file mode 100644
index 0000000..bad04d4
--- /dev/null
+++ b/drivers/staging/rt3090/mac_pci.h
@@ -0,0 +1,454 @@
+/*
+ *************************************************************************
+ * 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:
+        mac_pci.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __MAC_PCI_H__
+#define __MAC_PCI_H__
+
+#include "rtmp_type.h"
+#include "rtmp_mac.h"
+#include "rtmp_phy.h"
+#include "rtmp_iface.h"
+#include "rtmp_dot11.h"
+
+
+//
+// Device ID & Vendor ID related definitions,
+// NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip.
+//
+#define NIC_PCI_VENDOR_ID		0x1814
+#define PCIBUS_INTEL_VENDOR	0x8086
+
+#if !defined(PCI_CAP_ID_EXP)
+#define PCI_CAP_ID_EXP			    0x10
+#endif
+#if !defined(PCI_EXP_LNKCTL)
+#define PCI_EXP_LNKCTL			    0x10
+#endif
+#if !defined(PCI_CLASS_BRIDGE_PCI)
+#define PCI_CLASS_BRIDGE_PCI		0x0604
+#endif
+
+
+
+
+
+#define TXINFO_SIZE						0
+#define RTMP_PKT_TAIL_PADDING			0
+#define fRTMP_ADAPTER_NEED_STOP_TX	0
+
+#define AUX_CTRL           0x10c
+
+//
+// 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
+
+
+//
+// Rx descriptor format, Rx Ring
+//
+#ifdef RT_BIG_ENDIAN
+typedef	struct	PACKED _RXD_STRUC{
+	// Word 0
+	UINT32		SDP0;
+	// Word 1
+	UINT32		DDONE:1;
+	UINT32		LS0:1;
+	UINT32		SDL0:14;
+	UINT32		Rsv:2;
+	UINT32		SDL1:14;
+	// Word 2
+	UINT32		SDP1;
+	// Word 3
+	UINT32		Rsv1:13;
+	UINT32		PlcpRssil:1;// To be moved
+	UINT32		PlcpSignal:1;		// To be moved
+	UINT32		Decrypted:1;	// this frame is being decrypted.
+	UINT32		AMPDU:1;
+	UINT32		L2PAD:1;
+	UINT32		RSSI:1;
+	UINT32		HTC:1;
+	UINT32		AMSDU:1;		// rx with 802.3 header, not 802.11 header. obsolete.
+	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;
+
+}	RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#else
+typedef	struct	PACKED _RXD_STRUC{
+	// Word	0
+	UINT32		SDP0;
+	// Word	1
+	UINT32		SDL1:14;
+	UINT32		Rsv:2;
+	UINT32		SDL0:14;
+	UINT32		LS0:1;
+	UINT32		DDONE:1;
+	// Word	2
+	UINT32		SDP1;
+	// Word	3
+	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;
+	UINT32		Decrypted:1;	// this frame is being decrypted.
+	UINT32		PlcpSignal:1;		// To be moved
+	UINT32		PlcpRssil:1;// To be moved
+	UINT32		Rsv1:13;
+}	RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#endif
+
+#ifdef BIG_ENDIAN
+typedef union _TX_ATTENUATION_CTRL_STRUC
+{
+	struct
+	{
+		ULONG	Reserve1:20;
+		ULONG	PCIE_PHY_TX_ATTEN_EN:1;
+		ULONG	PCIE_PHY_TX_ATTEN_VALUE:3;
+		ULONG	Reserve2:7;
+		ULONG	RF_ISOLATION_ENABLE:1;
+	} field;
+
+	ULONG	word;
+} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
+#else
+typedef union _TX_ATTENUATION_CTRL_STRUC {
+	struct
+	{
+		ULONG	RF_ISOLATION_ENABLE:1;
+		ULONG	Reserve2:7;
+		ULONG	PCIE_PHY_TX_ATTEN_VALUE:3;
+		ULONG	PCIE_PHY_TX_ATTEN_EN:1;
+		ULONG	Reserve1:20;
+	} field;
+
+	ULONG	word;
+} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
+#endif
+/* ----------------- EEPROM Related MACRO ----------------- */
+
+// 8051 firmware image for RT2860 - base address = 0x4000
+#define FIRMWARE_IMAGE_BASE     0x2000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x2000    // 8kbyte
+
+
+/* ----------------- Frimware Related MACRO ----------------- */
+#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)			\
+	do{								\
+		ULONG	_i, _firm;					\
+		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000);		\
+									\
+		for(_i=0; _i<_FwLen; _i+=4)				\
+		{							\
+			_firm = _pFwImage[_i] +				\
+			   (_pFwImage[_i+3] << 24) +			\
+			   (_pFwImage[_i+2] << 16) +			\
+			   (_pFwImage[_i+1] << 8);			\
+			RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm);	\
+		}							\
+		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);		\
+	}while(0)
+
+
+/* ----------------- TX Related MACRO ----------------- */
+#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
+#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)		do{}while(0)
+
+
+#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+		((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */
+#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)	\
+		do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
+		(((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
+		//(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/))
+
+
+#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)	\
+			RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
+		/* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)	\
+			RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+			RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)	\
+			RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)	\
+			RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
+
+#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
+			/*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/
+
+#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx)	\
+			RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
+/*			RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
+			MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define GET_TXRING_FREENO(_pAd, _QueIdx) \
+	(_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx)	? \
+			(_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
+			 :	\
+			(_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
+
+
+#define GET_MGMTRING_FREENO(_pAd) \
+	(_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx)	? \
+			(_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
+			 :	\
+			(_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
+
+
+/* ----------------- RX Related MACRO ----------------- */
+
+
+/* ----------------- ASIC Related MACRO ----------------- */
+// reset MAC of a station entry to 0x000000000000
+#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)	\
+	AsicDelWcidTab(pAd, Wcid);
+
+// add this entry into ASIC RX WCID search table
+#define RTMP_STA_ENTRY_ADD(pAd, pEntry)		\
+	AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+// Set MAC register value according operation mode
+#define RTMP_UPDATE_PROTECT(pAd)	\
+	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
+// end johnli
+
+// remove Pair-wise key material from ASIC
+#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)	\
+	AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid);
+
+// add Client security information into ASIC WCID table and IVEIV table
+#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)		\
+	RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,			\
+							pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
+
+#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry)		\
+	{	/* update pairwise key information to ASIC Shared Key Table */	\
+		AsicAddSharedKeyEntry(pAd, apidx, KeyID,					\
+						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
+						  pAd->SharedKey[apidx][KeyID].Key,				\
+						  pAd->SharedKey[apidx][KeyID].TxMic,			\
+						  pAd->SharedKey[apidx][KeyID].RxMic);			\
+		/* update ASIC WCID attribute table and IVEIV table */			\
+		RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,					\
+						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
+						  pEntry); }
+
+
+// Insert the BA bitmap to ASIC for the Wcid entry
+#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)	\
+		do{					\
+			UINT32	_Value = 0, _Offset;					\
+			_Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4;	\
+			RTMP_IO_READ32((_pAd), _Offset, &_Value);\
+			_Value |= (0x10000<<(_TID));	\
+			RTMP_IO_WRITE32((_pAd), _Offset, _Value);\
+		}while(0)
+
+
+// Remove the BA bitmap from ASIC for the Wcid entry
+//		bitmap field starts at 0x10000 in ASIC WCID table
+#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
+		do{								\
+			UINT32	_Value = 0, _Offset;				\
+			_Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4;	\
+			RTMP_IO_READ32((_pAd), _Offset, &_Value);			\
+			_Value &= (~(0x10000 << (_TID)));				\
+			RTMP_IO_WRITE32((_pAd), _Offset, _Value);			\
+		}while(0)
+
+
+/* ----------------- Interface Related MACRO ----------------- */
+
+//
+// Enable & Disable NIC interrupt via writing interrupt mask register
+// Since it use ADAPTER structure, it have to be put after structure definition.
+//
+#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd)		\
+	do{			\
+		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0);     /* 0: disable */	\
+		RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);		\
+	}while(0)
+
+#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\
+	do{				\
+		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/);     /* 1:enable */	\
+		RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);	\
+	}while(0)
+
+
+#define RTMP_IRQ_INIT(pAd)	\
+	{	pAd->int_enable_reg = ((DELAYINTMASK) |		\
+					(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);	\
+		pAd->int_disable_mask = 0;						\
+		pAd->int_pending = 0; }
+
+#define RTMP_IRQ_ENABLE(pAd)					\
+	{	/* clear garbage ints */			\
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\
+		RTMP_ASIC_INTERRUPT_ENABLE(pAd); }
+
+
+/* ----------------- MLME Related MACRO ----------------- */
+#define RTMP_MLME_HANDLER(pAd)			MlmeHandler(pAd)
+
+#define RTMP_MLME_PRE_SANITY_CHECK(pAd)
+
+#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
+		RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
+		MlmeRestartStateMachine(pAd)
+
+#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\
+		HandleCounterMeasure(_pAd, _pEntry)
+
+/* ----------------- Power Save Related MACRO ----------------- */
+#define RTMP_PS_POLL_ENQUEUE(pAd)				EnqueuePsPoll(pAd)
+
+
+// For RTMPPCIePowerLinkCtrlRestore () function
+#define RESTORE_HALT		1
+#define RESTORE_WAKEUP		2
+#define RESTORE_CLOSE           3
+
+#define PowerSafeCID		1
+#define PowerRadioOffCID	2
+#define PowerWakeCID		3
+#define CID0MASK		0x000000ff
+#define CID1MASK		0x0000ff00
+#define CID2MASK		0x00ff0000
+#define CID3MASK		0xff000000
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \
+    RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
+
+#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+    RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RTMP_SET_PSM_BIT(_pAd, _val) \
+	MlmeSetPsmBit(_pAd, _val);
+#endif // CONFIG_STA_SUPPORT //
+
+#define RTMP_MLME_RADIO_ON(pAd) \
+    RT28xxPciMlmeRadioOn(pAd);
+
+#define RTMP_MLME_RADIO_OFF(pAd) \
+    RT28xxPciMlmeRadioOFF(pAd);
+
+#endif //__MAC_PCI_H__ //
diff --git a/drivers/staging/rt3090/mlme.h b/drivers/staging/rt3090/mlme.h
new file mode 100644
index 0000000..2336743
--- /dev/null
+++ b/drivers/staging/rt3090/mlme.h
@@ -0,0 +1,1360 @@
+/*
+ *************************************************************************
+ * 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:
+    Miniport generic portion header file
+
+    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__
+
+#include "rtmp_dot11.h"
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+
+// 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
+
+#define BEACON_LOST_TIME            4 * OS_HZ    // 2048 msec = 2 sec
+
+#define DLS_TIMEOUT                 1200      // unit: msec
+#define AUTH_TIMEOUT                300       // unit: msec
+#define ASSOC_TIMEOUT               300       // unit: msec
+#define JOIN_TIMEOUT                2000        // 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
+#define LINK_DOWN_TIMEOUT           20000      // unit: msec
+#define AUTO_WAKEUP_TIMEOUT			70			//unit: msec
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define CW_MAX_IN_BITS              10        // actual CwMax = 2^CW_MAX_IN_BITS - 1
+#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 maximum
+																//	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];
+} 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;
+
+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;
+
+
+// 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;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+} 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;
+    UCHAR   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/rt3090/mlme_ex.h b/drivers/staging/rt3090/mlme_ex.h
new file mode 100644
index 0000000..b3e94dc
--- /dev/null
+++ b/drivers/staging/rt3090/mlme_ex.h
@@ -0,0 +1,83 @@
+/*
+ *************************************************************************
+ * 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_ex.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+	Fonchi		2007-06-25		Extend original mlme APIs to support multi-entries
+*/
+#ifndef __MLME_EX_H__
+#define __MLME_EX_H__
+
+#include "mlme_ex_def.h"
+
+
+VOID StateMachineInitEx(
+	IN STATE_MACHINE_EX *S,
+	IN STATE_MACHINE_FUNC_EX Trans[],
+	IN ULONG StNr,
+	IN ULONG MsgNr,
+	IN STATE_MACHINE_FUNC_EX DefFunc,
+	IN ULONG InitState,
+	IN ULONG Base);
+
+VOID StateMachineSetActionEx(
+	IN STATE_MACHINE_EX *S,
+	IN ULONG St,
+	IN ULONG Msg,
+	IN STATE_MACHINE_FUNC_EX Func);
+
+BOOLEAN isValidApCliIf(
+	SHORT Idx);
+
+VOID StateMachinePerformActionEx(
+	IN PRTMP_ADAPTER pAd,
+	IN STATE_MACHINE_EX *S,
+	IN MLME_QUEUE_ELEM *Elem,
+	USHORT Idx,
+	PULONG pCurrState);
+
+BOOLEAN MlmeEnqueueEx(
+	IN	PRTMP_ADAPTER pAd,
+	IN ULONG Machine,
+	IN ULONG MsgType,
+	IN ULONG MsgLen,
+	IN VOID *Msg,
+	IN USHORT Idx);
+
+VOID DropEx(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem,
+	PULONG pCurrState,
+	USHORT Idx);
+
+#endif /* __MLME_EX_H__ */
diff --git a/drivers/staging/rt3090/mlme_ex_def.h b/drivers/staging/rt3090/mlme_ex_def.h
new file mode 100644
index 0000000..ccd60b4
--- /dev/null
+++ b/drivers/staging/rt3090/mlme_ex_def.h
@@ -0,0 +1,53 @@
+/*
+ *************************************************************************
+ * 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_ex_def.h
+
+    Abstract:
+    Miniport generic portion header file
+
+    Revision History:
+    Who         When          What
+    --------    ----------    ----------------------------------------------
+	Fonchi		2007-06-25		Extend original mlme APIs to support multi-entries
+*/
+#ifndef __MLME_EX_DEF_H__
+#define __MLME_EX_DEF_H__
+
+
+typedef VOID (*STATE_MACHINE_FUNC_EX)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem, PULONG pCurrState, USHORT Idx);
+
+typedef struct _STA_STATE_MACHINE_EX
+{
+	ULONG					Base;
+	ULONG					NrState;
+	ULONG					NrMsg;
+	ULONG					CurrState;
+	STATE_MACHINE_FUNC_EX	*TransFunc;
+} STATE_MACHINE_EX, *PSTA_STATE_MACHINE_EX;
+
+#endif // __MLME_EX_DEF_H__ //
diff --git a/drivers/staging/rt3090/netif_block.h b/drivers/staging/rt3090/netif_block.h
new file mode 100644
index 0000000..9e75389
--- /dev/null
+++ b/drivers/staging/rt3090/netif_block.h
@@ -0,0 +1,56 @@
+/*
+ *************************************************************************
+ * 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 "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/rt3090/oid.h b/drivers/staging/rt3090/oid.h
new file mode 100644
index 0000000..29a4340
--- /dev/null
+++ b/drivers/staging/rt3090/oid.h
@@ -0,0 +1,1144 @@
+/*
+ *************************************************************************
+ * 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>
+
+#ifndef TRUE
+#define TRUE				1
+#endif
+#ifndef FALSE
+#define FALSE				0
+#endif
+//
+// 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_NUM_OF_CHS				54      // 14 channels @2.4G +  12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination
+#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
+
+
+#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
+#define RT_QUERY_EVENT_TABLE			0x0407
+//
+// IEEE 802.11 OIDs
+//
+#define	OID_GET_SET_TOGGLE			0x8000
+#define	OID_GET_SET_FROM_UI			0x4000
+
+#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
+#define OID_802_11_EAP_METHOD						0x0529
+
+// 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
+
+#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
+#define OID_802_11_SET_PSPXLINK_MODE				0x0648
+/*+++ add by woody +++*/
+#define OID_802_11_SET_PASSPHRASE				0x0649
+// 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)
+#define RT_OID_802_11_SET_PSPXLINK_MODE		  (OID_GET_SET_TOGGLE |	OID_802_11_SET_PSPXLINK_MODE)
+#define RT_OID_802_11_EAP_METHOD			  (OID_GET_SET_TOGGLE | OID_802_11_EAP_METHOD)
+#define RT_OID_802_11_SET_PASSPHRASE		  (OID_GET_SET_TOGGLE | OID_802_11_SET_PASSPHRASE)
+
+
+
+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_11OFDM24,
+	Ndis802_11Automode,
+    Ndis802_11OFDM5_N,
+    Ndis802_11OFDM24_N,
+    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[8][IFNAMSIZ];
+	UCHAR			EAPifname_len[8];
+	UCHAR			PreAuthifname[8][IFNAMSIZ];
+	UCHAR			PreAuthifname_len[8];
+	RADIUS_KEY_INFO	RadiusInfo[8];
+} 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;
+
+typedef struct _NDIS_802_11_PASSPHRASE
+{
+    UINT           KeyLength;          // length of key in bytes
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    UCHAR           KeyMaterial[1];     // variable length depending on above field
+} NDIS_802_11_PASSPHRASE, *PNDIS_802_11_PASSPHRASE;
+#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,
+    Ndis802_11GroupWEP40Enabled,
+	Ndis802_11GroupWEP104Enabled,
+} 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;
+
+#ifdef LINUX
+#if WIRELESS_EXT <= 11
+#ifndef SIOCDEVPRIVATE
+#define SIOCDEVPRIVATE                              0x8BE0
+#endif
+#define SIOCIWFIRSTPRIV								SIOCDEVPRIVATE
+#endif
+#endif // LINUX //
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define RT_PRIV_IOCTL							(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)
+
+#ifdef RTMP_RF_RW_SUPPORT
+// TODO: shiang, Need to reassign the oid number. ArchTeam use (SIOCIWFIRSTPRIV + 0x19) for this oid
+#define RTPRIV_IOCTL_RF                             (SIOCIWFIRSTPRIV + 0x13)  // edit by johnli, fix read rf register problem
+#endif // RTMP_RF_RW_SUPPORT //
+
+#define RTPRIV_IOCTL_E2P                            (SIOCIWFIRSTPRIV + 0x07)
+#endif // DBG //
+
+#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_EXT							(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,
+	RAIO_OFF = 10,
+	RAIO_ON = 11,
+#ifdef QOS_DLS_SUPPORT
+	SHOW_DLS_ENTRY_INFO = 19,
+#endif // QOS_DLS_SUPPORT //
+	SHOW_CFG_VALUE = 20,
+	SHOW_ADHOC_ENTRY_INFO = 21,
+};
+
+
+#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_WSC_CONFIG_STATUS					0x074F
+#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 //
+
+
+// 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;
+
+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;
+
+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;
+	UINT			ApplyProfileIdx;  // add by johnli, fix WPS test plan 5.1.1
+	WSC_CREDENTIAL	Profile[8];				// Support up to 8 profiles
+}	WSC_PROFILE, *PWSC_PROFILE;
+
+
+
+#endif // _OID_H_
diff --git a/drivers/staging/rt3090/pci_main_dev.c b/drivers/staging/rt3090/pci_main_dev.c
new file mode 100644
index 0000000..1410156
--- /dev/null
+++ b/drivers/staging/rt3090/pci_main_dev.c
@@ -0,0 +1,1195 @@
+/*
+ *************************************************************************
+ * 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:
+	pci_main_dev.c
+
+	Abstract:
+
+	Revision History:
+	Who			When			What
+	--------	----------		----------------------------------------------
+	Name		Date			Modification logs
+*/
+
+
+#include "rt_config.h"
+#include <linux/pci.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("Jett Chen <jett_chen@ralinktech.com>");
+MODULE_DESCRIPTION("RT3090 Wireless Lan Linux Driver");
+MODULE_LICENSE("GPL");
+
+//
+// Function declarations
+//
+extern int rt28xx_close(IN struct net_device *net_dev);
+extern int rt28xx_open(struct net_device *net_dev);
+
+static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
+static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id  *ent);
+static void __exit rt2860_cleanup_module(void);
+static int __init rt2860_init_module(void);
+
+
+ static VOID RTMPInitPCIeDevice(
+    IN  struct pci_dev   *pci_dev,
+    IN PRTMP_ADAPTER     pAd);
+
+
+#ifdef CONFIG_PM
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+#define pm_message_t u32
+#endif
+
+static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
+static int rt2860_resume(struct pci_dev *pci_dev);
+#endif
+#endif // CONFIG_PM //
+
+//
+// Ralink PCI device table, include all supported chipsets
+//
+static struct pci_device_id rt2860_pci_tbl[] __devinitdata =
+{
+#ifdef RT3090
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3090_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3091_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3092_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(0x1462, 0x891A)},
+#endif // RT3090 //
+#ifdef RT3390
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3390_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3391_PCIe_DEVICE_ID)},
+	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3392_PCIe_DEVICE_ID)},
+#endif // RT3390 //
+    {0,}		// terminate list
+};
+
+MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
+#ifdef CONFIG_STA_SUPPORT
+#ifdef MODULE_VERSION
+MODULE_VERSION(STA_DRIVER_VERSION);
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+
+//
+// Our PCI driver structure
+//
+static struct pci_driver rt2860_driver =
+{
+    name:       "rt3090",
+    id_table:   rt2860_pci_tbl,
+    probe:      rt2860_probe,
+#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
+};
+
+
+/***************************************************************************
+ *
+ *	PCI device initialization related procedures.
+ *
+ ***************************************************************************/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#ifdef CONFIG_PM
+
+VOID RT2860RejectPendingPackets(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	// clear PS packets
+	// clear TxSw packets
+}
+
+static int rt2860_suspend(
+	struct pci_dev *pci_dev,
+	pm_message_t state)
+{
+	struct net_device *net_dev = pci_get_drvdata(pci_dev);
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
+	INT32 retval = 0;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
+
+	if (net_dev == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
+	}
+	else
+	{
+		pAd = (PRTMP_ADAPTER)RTMP_OS_NETDEV_GET_PRIV(net_dev);
+
+		/* we can not use IFF_UP because ra0 down but ra1 up */
+		/* and 1 suspend/resume function for 1 module, not for each interface */
+		/* so Linux will call suspend/resume function once */
+		if (VIRTUAL_IF_NUM(pAd) > 0)
+		{
+			// avoid users do suspend after interface is down
+
+			// stop interface
+			netif_carrier_off(net_dev);
+			netif_stop_queue(net_dev);
+
+			// mark device as removed from system and therefore no longer available
+			netif_device_detach(net_dev);
+
+			// mark halt flag
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+			// take down the device
+			rt28xx_close((PNET_DEV)net_dev);
+
+			RT_MOD_DEC_USE_COUNT();
+		}
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
+	// reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html
+	// enable device to generate PME# when suspended
+	// pci_choose_state(): Choose the power state of a PCI device to be suspended
+	retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
+	// save the PCI configuration space of a device before suspending
+	pci_save_state(pci_dev);
+	// disable PCI device after use
+	pci_disable_device(pci_dev);
+
+	retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
+#endif
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
+	return retval;
+}
+
+static int rt2860_resume(
+	struct pci_dev *pci_dev)
+{
+	struct net_device *net_dev = pci_get_drvdata(pci_dev);
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
+	INT32 retval;
+
+
+	// set the power state of a PCI device
+	// PCI has 4 power states, DO (normal) ~ D3(less power)
+	// in include/linux/pci.h, you can find that
+	// #define PCI_D0          ((pci_power_t __force) 0)
+	// #define PCI_D1          ((pci_power_t __force) 1)
+	// #define PCI_D2          ((pci_power_t __force) 2)
+	// #define PCI_D3hot       ((pci_power_t __force) 3)
+	// #define PCI_D3cold      ((pci_power_t __force) 4)
+	// #define PCI_UNKNOWN     ((pci_power_t __force) 5)
+	// #define PCI_POWER_ERROR ((pci_power_t __force) -1)
+	retval = pci_set_power_state(pci_dev, PCI_D0);
+
+	// restore the saved state of a PCI device
+	pci_restore_state(pci_dev);
+
+	// initialize device before it's used by a driver
+	if (pci_enable_device(pci_dev))
+	{
+		printk("pci enable fail!\n");
+		return 0;
+	}
+#endif
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
+
+	if (net_dev == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
+	}
+	else
+		pAd = (PRTMP_ADAPTER)RTMP_OS_NETDEV_GET_PRIV(net_dev);
+
+	if (pAd != NULL)
+	{
+		/* we can not use IFF_UP because ra0 down but ra1 up */
+		/* and 1 suspend/resume function for 1 module, not for each interface */
+		/* so Linux will call suspend/resume function once */
+		if (VIRTUAL_IF_NUM(pAd) > 0)
+		{
+			// mark device as attached from system and restart if needed
+			netif_device_attach(net_dev);
+
+			if (rt28xx_open((PNET_DEV)net_dev) != 0)
+			{
+				// open fail
+				DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
+				return 0;
+			}
+
+			// increase MODULE use count
+			RT_MOD_INC_USE_COUNT();
+
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+			netif_start_queue(net_dev);
+			netif_carrier_on(net_dev);
+			netif_wake_queue(net_dev);
+		}
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
+	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
+}
+
+
+//
+// Driver module unload function
+//
+static VOID __exit rt2860_cleanup_module(VOID)
+{
+    pci_unregister_driver(&rt2860_driver);
+}
+
+module_init(rt2860_init_module);
+module_exit(rt2860_cleanup_module);
+
+
+//
+// PCI device probe & initialization function
+//
+static INT __devinit   rt2860_probe(
+    IN  struct pci_dev              *pci_dev,
+    IN  const struct pci_device_id  *pci_id)
+{
+	PRTMP_ADAPTER		pAd = (PRTMP_ADAPTER)NULL;
+	struct  net_device		*net_dev;
+	PVOID				handle;
+	PSTRING				print_name;
+	ULONG				csr_addr;
+	INT rv = 0;
+	RTMP_OS_NETDEV_OP_HOOK	netDevHook;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n"));
+
+//PCIDevInit==============================================
+	// wake up and enable device
+	if ((rv = pci_enable_device(pci_dev))!= 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Enable PCI device failed, errno=%d!\n", rv));
+		return rv;
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	print_name = pci_dev ? pci_name(pci_dev) : "rt3090";
+#else
+	print_name = pci_dev ? pci_dev->slot_name : "rt3090";
+#endif // LINUX_VERSION_CODE //
+
+	if ((rv = pci_request_regions(pci_dev, print_name)) != 0)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("Request PCI resource failed, errno=%d!\n", rv));
+		goto err_out;
+	}
+
+	// map physical address to virtual address for accessing register
+	csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
+	if (!csr_addr)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
+					print_name, (ULONG)pci_resource_len(pci_dev, 0), (ULONG)pci_resource_start(pci_dev, 0)));
+		goto err_out_free_res;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",  print_name,
+					(ULONG)pci_resource_start(pci_dev, 0), (ULONG)csr_addr, pci_dev->irq));
+	}
+
+	// Set DMA master
+	pci_set_master(pci_dev);
+
+
+//RtmpDevInit==============================================
+	// Allocate RTMP_ADAPTER adapter structure
+	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+	if (handle == NULL)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s(): Allocate memory for os handle failed!\n", __FUNCTION__));
+		goto err_out_iounmap;
+	}
+
+	((POS_COOKIE)handle)->pci_dev = pci_dev;
+
+	rv = RTMPAllocAdapterBlock(handle, &pAd);	//shiang: we may need the pci_dev for allocate structure of "RTMP_ADAPTER"
+	if (rv != NDIS_STATUS_SUCCESS)
+		goto err_out_iounmap;
+	// Here are the RTMP_ADAPTER structure with pci-bus specific parameters.
+	pAd->CSRBaseAddress = (PUCHAR)csr_addr;
+	DBGPRINT(RT_DEBUG_ERROR, ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n", (ULONG)pAd->CSRBaseAddress, csr_addr));
+	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI);
+
+
+//NetDevInit==============================================
+	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
+	if (net_dev == NULL)
+		goto err_out_free_radev;
+
+	// Here are the net_device structure with pci-bus specific parameters.
+	net_dev->irq = pci_dev->irq;		// Interrupt IRQ number
+	net_dev->base_addr = csr_addr;		// Save CSR virtual address and irq to device structure
+	pci_set_drvdata(pci_dev, net_dev);	// Set driver data
+
+#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, &(pci_dev->dev));
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+
+//All done, it's time to register the net device to linux kernel.
+	// Register this device
+	rv = RtmpOSNetDevAttach(net_dev, &netDevHook);
+	if (rv)
+		goto err_out_free_netdev;
+
+#ifdef CONFIG_STA_SUPPORT
+	pAd->StaCfg.OriDevType = net_dev->type;
+#endif // CONFIG_STA_SUPPORT //
+RTMPInitPCIeDevice(pci_dev, pAd);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n"));
+
+	return 0; // probe ok
+
+
+	/* --------------------------- ERROR HANDLE --------------------------- */
+err_out_free_netdev:
+	RtmpOSNetDevFree(net_dev);
+
+err_out_free_radev:
+	/* free RTMP_ADAPTER strcuture and os_cookie*/
+	RTMPFreeAdapter(pAd);
+
+err_out_iounmap:
+	iounmap((void *)(csr_addr));
+	release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
+
+err_out_free_res:
+	pci_release_regions(pci_dev);
+
+err_out:
+	pci_disable_device(pci_dev);
+
+	DBGPRINT(RT_DEBUG_ERROR, ("<=== rt2860_probe failed with rv = %d!\n", rv));
+
+	return -ENODEV; /* probe fail */
+}
+
+
+static VOID __devexit rt2860_remove_one(
+    IN  struct pci_dev  *pci_dev)
+{
+	PNET_DEV	net_dev = pci_get_drvdata(pci_dev);
+	RTMP_ADAPTER	*pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+	ULONG			csr_addr = net_dev->base_addr; // pAd->CSRBaseAddress;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
+
+	if (pAd != NULL)
+	{
+		// Unregister/Free all allocated net_device.
+		RtmpPhyNetDevExit(pAd, net_dev);
+
+		// Unmap CSR base address
+		iounmap((char *)(csr_addr));
+
+		// release memory region
+		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
+
+		// Free RTMP_ADAPTER related structures.
+		RtmpRaDevCtrlExit(pAd);
+
+	}
+	else
+	{
+		// Unregister network device
+		RtmpOSNetDevDetach(net_dev);
+
+		// Unmap CSR base address
+		iounmap((char *)(net_dev->base_addr));
+
+		// release memory region
+		release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
+	}
+
+	// Free the root net_device
+	RtmpOSNetDevFree(net_dev);
+
+}
+
+
+/*
+========================================================================
+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)
+{
+	/* always TRUE */
+	return TRUE;
+}
+
+
+
+/***************************************************************************
+ *
+ *	PCIe device initialization related procedures.
+ *
+ ***************************************************************************/
+ static VOID RTMPInitPCIeDevice(
+    IN  struct pci_dev   *pci_dev,
+    IN PRTMP_ADAPTER     pAd)
+{
+	USHORT  device_id;
+	POS_COOKIE pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id);
+	device_id = le2cpu16(device_id);
+	pObj->DeviceID = device_id;
+	if (
+#ifdef RT3090
+		(device_id == NIC3090_PCIe_DEVICE_ID) ||
+		(device_id == NIC3091_PCIe_DEVICE_ID) ||
+		(device_id == NIC3092_PCIe_DEVICE_ID) ||
+#endif // RT3090 //
+		 0)
+	{
+		UINT32 MacCsr0 = 0, Index= 0;
+		do
+		{
+			RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+
+			if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
+				break;
+
+			RTMPusecDelay(10);
+		} while (Index++ < 100);
+
+		// Support advanced power save after 2892/2790.
+		// MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO).
+		if ((MacCsr0&0xffff0000) != 0x28600000)
+		{
+			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
+		}
+	}
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPInitPCIeLinkCtrlValue(
+	IN	PRTMP_ADAPTER	pAd)
+{
+    INT     pos;
+    USHORT	reg16, data2, PCIePowerSaveLevel, Configuration;
+	UINT32 MacValue;
+    BOOLEAN	bFindIntel = FALSE;
+	POS_COOKIE pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __FUNCTION__));
+	// Init EEPROM, and save settings
+	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
+	{
+		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
+		pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff;
+		pAd->LnkCtrlBitMask = 0;
+		if ((PCIePowerSaveLevel&0xff) == 0xff)
+		{
+			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
+			DBGPRINT(RT_DEBUG_TRACE, ("====> PCIePowerSaveLevel = 0x%x.\n", PCIePowerSaveLevel));
+			return;
+		}
+	else
+	{
+		PCIePowerSaveLevel &= 0x3;
+		RT28xx_EEPROM_READ16(pAd, 0x24, data2);
+
+		if( !(((data2&0xff00) == 0x9200) && ((data2&0x80) !=0)) )
+		{
+			if (PCIePowerSaveLevel > 1 )
+				PCIePowerSaveLevel = 1;
+		}
+
+		DBGPRINT(RT_DEBUG_TRACE, ("====> Write 0x83 = 0x%x.\n", PCIePowerSaveLevel));
+		AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00);
+		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
+		PCIePowerSaveLevel &= 0xff;
+		PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
+		switch(PCIePowerSaveLevel)
+		{
+				case 0:	// Only support L0
+					pAd->LnkCtrlBitMask = 0;
+				break;
+				case 1:	// Only enable L0s
+					pAd->LnkCtrlBitMask = 1;
+				break;
+				case 2:	// enable L1, L0s
+					pAd->LnkCtrlBitMask = 3;
+				break;
+				case 3:	// sync with host clk and enable L1, L0s
+				pAd->LnkCtrlBitMask = 0x103;
+				break;
+		}
+			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
+			if ((PCIePowerSaveLevel&0xff) != 0xff)
+			{
+				PCIePowerSaveLevel &= 0x3;
+
+				if( !(((data2&0xff00) == 0x9200) && ((data2&0x80) !=0)) )
+				{
+					if (PCIePowerSaveLevel > 1 )
+						PCIePowerSaveLevel = 1;
+				}
+
+				DBGPRINT(RT_DEBUG_TRACE, ("====> rt28xx Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel));
+					       printk("\n\n\n%s:%d\n",__FUNCTION__,__LINE__);
+
+				AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00);
+			}
+		DBGPRINT(RT_DEBUG_TRACE, ("====> LnkCtrlBitMask = 0x%x.\n", pAd->LnkCtrlBitMask));
+	}
+	}
+	else if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
+	{
+		UCHAR	LinkCtrlSetting = 0;
+
+		// Check 3090E special setting chip.
+			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
+		if ((data2 == 0x9280) && ((pAd->MACVersion&0xffff) == 0x0211))
+		{
+			pAd->b3090ESpecialChip = TRUE;
+			DBGPRINT_RAW(RT_DEBUG_ERROR,("Special 3090E chip \n"));
+		}
+
+		RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
+		//enable WAKE_PCIE function, which forces to enable PCIE clock when mpu interrupt asserting.
+		//Force PCIE 125MHz CLK to toggle
+		MacValue |= 0x402;
+		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
+		DBGPRINT_RAW(RT_DEBUG_ERROR,(" AUX_CTRL = 0x%32x\n", MacValue));
+
+
+
+		// for RT30xx F and after, PCIe infterface, and for power solution 3
+		if ((IS_VERSION_AFTER_F(pAd))
+			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2)
+			&& (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3))
+		{
+			RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
+			DBGPRINT_RAW(RT_DEBUG_ERROR,(" Read AUX_CTRL = 0x%x\n", MacValue));
+			// turn on bit 12.
+			//enable 32KHz clock mode for power saving
+			MacValue |= 0x1000;
+			if (MacValue != 0xffffffff)
+			{
+				RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
+				DBGPRINT_RAW(RT_DEBUG_ERROR,(" Write AUX_CTRL = 0x%x\n", MacValue));
+				// 1. if use PCIePowerSetting is 2 or 3, need to program OSC_CTRL to 0x3ff11.
+				MacValue = 0x3ff11;
+				RTMP_IO_WRITE32(pAd, OSC_CTRL, MacValue);
+				DBGPRINT_RAW(RT_DEBUG_ERROR,(" OSC_CTRL = 0x%x\n", MacValue));
+				// 2. Write PCI register Clk ref bit
+				RTMPrt3xSetPCIePowerLinkCtrl(pAd);
+			}
+			else
+			{
+				// Error read Aux_Ctrl value.  Force to use solution 1
+				DBGPRINT(RT_DEBUG_ERROR,(" Error Value in AUX_CTRL = 0x%x\n", MacValue));
+				pAd->StaCfg.PSControl.field.rt30xxPowerMode = 1;
+				DBGPRINT(RT_DEBUG_ERROR,(" Force to use power solution1 \n"));
+			}
+		}
+		// 1. read setting from inf file.
+
+		PCIePowerSaveLevel = (USHORT)pAd->StaCfg.PSControl.field.rt30xxPowerMode;
+		DBGPRINT(RT_DEBUG_ERROR, ("====> rt30xx Read PowerLevelMode =  0x%x.\n", PCIePowerSaveLevel));
+		// 2. Check EnableNewPS.
+		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+			PCIePowerSaveLevel = 1;
+
+		if (IS_VERSION_BEFORE_F(pAd) && (pAd->b3090ESpecialChip == FALSE))
+		{
+			// Chip Version E only allow 1, So force set 1.
+			PCIePowerSaveLevel &= 0x1;
+			pAd->PCIePowerSaveLevel = (USHORT)PCIePowerSaveLevel;
+			DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx E Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel));
+
+			AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00);
+		}
+		else
+		{
+			// Chip Version F and after only allow 1 or 2 or 3. This might be modified after new chip version come out.
+			if (!((PCIePowerSaveLevel == 1) || (PCIePowerSaveLevel == 3)))
+				PCIePowerSaveLevel = 1;
+			DBGPRINT(RT_DEBUG_ERROR, ("====> rt30xx F Write 0x83 Command = 0x%x.\n", PCIePowerSaveLevel));
+			pAd->PCIePowerSaveLevel = (USHORT)PCIePowerSaveLevel;
+			// for 3090F , we need to add high-byte arg for 0x83 command to indicate the link control setting in
+			// PCI Configuration Space. Because firmware can't read PCI Configuration Space
+			if ((pAd->Rt3xxRalinkLinkCtrl & 0x2) && (pAd->Rt3xxHostLinkCtrl & 0x2))
+			{
+				LinkCtrlSetting = 1;
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xxF LinkCtrlSetting = 0x%x.\n", LinkCtrlSetting));
+			AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, LinkCtrlSetting);
+		}
+
+	}
+
+    // Find Ralink PCIe Device's Express Capability Offset
+	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
+
+    if (pos != 0)
+    {
+        // Ralink PCIe Device's Link Control Register Offset
+        pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+	pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
+        Configuration = le2cpu16(reg16);
+        DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
+                                    pAd->RLnkCtrlOffset, Configuration));
+        pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
+        Configuration &= 0xfefc;
+        Configuration |= (0x0);
+
+        RTMPFindHostPCIDev(pAd);
+        if (pObj->parent_pci_dev)
+        {
+		USHORT  vendor_id;
+
+		pci_read_config_word(pObj->parent_pci_dev, PCI_VENDOR_ID, &vendor_id);
+		vendor_id = le2cpu16(vendor_id);
+		if (vendor_id == PCIBUS_INTEL_VENDOR)
+                 {
+			bFindIntel = TRUE;
+                        RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1);
+                 }
+		/*
+		else if ((vendor_id == PCIBUS_AMD_VENDOR1)
+					&& (DeviceID == 0x96000000))
+				{
+					//Verified 2792 Aspire 8530 AMD NB (S3/S4/CBoot/WBoot/Chariot) by customer and ourselves.
+					// So use L1 Toggle method in this NB.
+			bFindIntel = TRUE;
+					RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1);
+					DBGPRINT(RT_DEBUG_TRACE, ("PSM : Aspire 8530 AMD NB. Use L1 Toggle. \n"));
+				}
+		*/
+		// Find PCI-to-PCI Bridge Express Capability Offset
+		pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
+
+		if (pos != 0)
+		{
+			BOOLEAN		bChange = FALSE;
+			// PCI-to-PCI Bridge Link Control Register Offset
+			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+			pci_read_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, &reg16);
+			Configuration = le2cpu16(reg16);
+			DBGPRINT(RT_DEBUG_TRACE, ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
+			                            pAd->HostLnkCtrlOffset, Configuration));
+			pAd->HostLnkCtrlConfiguration = (Configuration & 0x103);
+			Configuration &= 0xfefc;
+			Configuration |= (0x0);
+
+			switch (pObj->DeviceID)
+			{
+#ifdef RT3090
+				case NIC3090_PCIe_DEVICE_ID:
+				case NIC3091_PCIe_DEVICE_ID:
+				case NIC3092_PCIe_DEVICE_ID:
+					if (bFindIntel == FALSE)
+						bChange = TRUE;
+					break;
+#endif // RT3090 //
+				default:
+					break;
+			}
+
+			if (bChange)
+			{
+				reg16 = cpu2le16(Configuration);
+				pci_write_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, reg16);
+				DBGPRINT(RT_DEBUG_TRACE, ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
+						pAd->HostLnkCtrlOffset, Configuration));
+			}
+		}
+		else
+		{
+			pAd->HostLnkCtrlOffset = 0;
+			DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n", __FUNCTION__));
+		}
+        }
+    }
+    else
+    {
+        pAd->RLnkCtrlOffset = 0;
+        pAd->HostLnkCtrlOffset = 0;
+        DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n", __FUNCTION__));
+    }
+
+    if (bFindIntel == FALSE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Doesn't find Intel PCI host controller. \n"));
+		// Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff
+		pAd->PCIePowerSaveLevel = 0xff;
+		if ((pAd->RLnkCtrlOffset != 0)
+#ifdef RT3090
+			&& ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
+				||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
+				||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
+#endif // RT3090 //
+		)
+		{
+			pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
+			Configuration = le2cpu16(reg16);
+			DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n",
+			                        pAd->RLnkCtrlOffset, Configuration));
+			pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
+			Configuration &= 0xfefc;
+			Configuration |= (0x0);
+			reg16 = cpu2le16(Configuration);
+			pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16);
+			DBGPRINT(RT_DEBUG_TRACE, ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
+			                        pos + PCI_EXP_LNKCTL, Configuration));
+		}
+	}
+}
+
+VOID RTMPFindHostPCIDev(
+    IN	PRTMP_ADAPTER	pAd)
+{
+    USHORT  reg16;
+    UCHAR   reg8;
+	UINT	DevFn;
+    PPCI_DEV    pPci_dev;
+	POS_COOKIE	pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __FUNCTION__));
+
+    pObj->parent_pci_dev = NULL;
+    if (pObj->pci_dev->bus->parent)
+    {
+        for (DevFn = 0; DevFn < 255; DevFn++)
+        {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+            pPci_dev = pci_get_slot(pObj->pci_dev->bus->parent, DevFn);
+#else
+            pPci_dev = pci_find_slot(pObj->pci_dev->bus->parent->number, DevFn);
+#endif
+            if (pPci_dev)
+            {
+                pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE, &reg16);
+                reg16 = le2cpu16(reg16);
+                pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS, &reg8);
+                if ((reg16 == PCI_CLASS_BRIDGE_PCI) &&
+                    (reg8 == pObj->pci_dev->bus->number))
+                {
+                    pObj->parent_pci_dev = pPci_dev;
+                }
+            }
+        }
+    }
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+		Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
+		Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
+
+	========================================================================
+*/
+VOID RTMPPCIeLinkCtrlValueRestore(
+	IN	PRTMP_ADAPTER	pAd,
+	IN   UCHAR		Level)
+{
+	USHORT  PCIePowerSaveLevel, reg16;
+	USHORT	Configuration;
+	POS_COOKIE	pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+	// Check PSControl Configuration
+	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+		return TRUE;
+
+	//3090 will not execute the following codes.
+	// Check interface : If not PCIe interface, return.
+
+#ifdef RT3090
+	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
+		||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
+		||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
+		return;
+#endif // RT3090 //
+	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __FUNCTION__));
+	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
+	if ((PCIePowerSaveLevel&0xff) == 0xff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("return  \n"));
+		return;
+	}
+
+	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0))
+    {
+        PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
+        if ((Configuration != 0) &&
+            (Configuration != 0xFFFF))
+        {
+		Configuration &= 0xfefc;
+		// If call from interface down, restore to orginial setting.
+		if (Level == RESTORE_CLOSE)
+		{
+			Configuration |= pAd->HostLnkCtrlConfiguration;
+		}
+		else
+			Configuration |= 0x0;
+            PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
+		DBGPRINT(RT_DEBUG_TRACE, ("Restore PCI host : offset 0x%x = 0x%x\n", pAd->HostLnkCtrlOffset, Configuration));
+        }
+        else
+            DBGPRINT(RT_DEBUG_ERROR, ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration));
+    }
+
+    if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0))
+    {
+        PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+        if ((Configuration != 0) &&
+            (Configuration != 0xFFFF))
+        {
+		Configuration &= 0xfefc;
+			// If call from interface down, restore to orginial setting.
+			if (Level == RESTORE_CLOSE)
+		Configuration |= pAd->RLnkCtrlConfiguration;
+			else
+				Configuration |= 0x0;
+            PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+		DBGPRINT(RT_DEBUG_TRACE, ("Restore Ralink : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration));
+        }
+        else
+            DBGPRINT(RT_DEBUG_ERROR, ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("%s <===\n", __FUNCTION__));
+}
+
+/*
+	========================================================================
+
+	Routine Description:
+
+	Arguments:
+		Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
+		Because now frequently set our device to mode 1 or mode 3 will cause problem.
+
+	========================================================================
+*/
+VOID RTMPPCIeLinkCtrlSetting(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT		Max)
+{
+	USHORT  PCIePowerSaveLevel, reg16;
+	USHORT	Configuration;
+	POS_COOKIE	pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+		return;
+
+	// Check PSControl Configuration
+	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+		return TRUE;
+
+	// Check interface : If not PCIe interface, return.
+	//Block 3090 to enter the following function
+
+#ifdef RT3090
+	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
+		||(pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
+		||(pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
+		return;
+#endif // RT3090 //
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
+	{
+		DBGPRINT(RT_DEBUG_INFO, ("RTMPPCIePowerLinkCtrl return on fRTMP_PS_CAN_GO_SLEEP flag\n"));
+		return;
+	}
+	DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
+	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
+	if ((PCIePowerSaveLevel&0xff) == 0xff)
+	{
+		DBGPRINT(RT_DEBUG_TRACE,("return  \n"));
+		return;
+	}
+	PCIePowerSaveLevel = PCIePowerSaveLevel>>6;
+
+    // Skip non-exist deice right away
+	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0))
+	{
+        PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
+		switch (PCIePowerSaveLevel)
+		{
+			case 0:
+				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00
+				Configuration &= 0xfefc;
+				break;
+			case 1:
+				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01
+				Configuration &= 0xfefc;
+				Configuration |= 0x1;
+				break;
+			case 2:
+				//  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11
+				Configuration &= 0xfefc;
+				Configuration |= 0x3;
+				break;
+			case 3:
+				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1
+				Configuration &= 0xfefc;
+				Configuration |= 0x103;
+				break;
+		}
+        PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration);
+		DBGPRINT(RT_DEBUG_TRACE, ("Write PCI host offset 0x%x = 0x%x\n", pAd->HostLnkCtrlOffset, Configuration));
+	}
+
+	if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0))
+	{
+		// first 2892 chip not allow to frequently set mode 3. will cause hang problem.
+		if (PCIePowerSaveLevel > Max)
+			PCIePowerSaveLevel = Max;
+
+        PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+		switch (PCIePowerSaveLevel)
+		{
+			case 0:
+				// No PCI power safe
+				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 .
+				Configuration &= 0xfefc;
+				break;
+			case 1:
+				//  L0
+				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 .
+				Configuration &= 0xfefc;
+				Configuration |= 0x1;
+				break;
+			case 2:
+				// L0 and L1
+				//  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11
+				Configuration &= 0xfefc;
+				Configuration |= 0x3;
+				break;
+			case 3:
+				// L0 , L1 and clock management.
+				// Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1
+				Configuration &= 0xfefc;
+				Configuration |= 0x103;
+		              pAd->bPCIclkOff = TRUE;
+				break;
+		}
+        PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration);
+		DBGPRINT(RT_DEBUG_TRACE, ("Write Ralink device : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration));
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE,("RTMPPCIePowerLinkCtrl <==============\n"));
+}
+/*
+	========================================================================
+
+	Routine Description:
+		1. Write a PCI register for rt30xx power solution 3
+
+	========================================================================
+*/
+VOID RTMPrt3xSetPCIePowerLinkCtrl(
+	IN	PRTMP_ADAPTER	pAd)
+{
+
+	ULONG	HostConfiguration;
+	ULONG	Configuration;
+	ULONG	Vendor;
+	ULONG	offset;
+	POS_COOKIE	pObj;
+	INT     pos;
+	USHORT	reg16;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	DBGPRINT(RT_DEBUG_INFO, ("RTMPrt3xSetPCIePowerLinkCtrl.===> %x\n", pAd->StaCfg.PSControl.word));
+
+	// Check PSControl Configuration
+	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+		return;
+	RTMPFindHostPCIDev(pAd);
+        if (pObj->parent_pci_dev)
+        {
+		USHORT  vendor_id;
+		// Find PCI-to-PCI Bridge Express Capability Offset
+		pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
+
+		if (pos != 0)
+		{
+			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+		}
+	// If configurared to turn on L1.
+	HostConfiguration = 0;
+		if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1)
+		{
+						DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM \n"));
+
+			// Skip non-exist deice right away
+			if ((pAd->HostLnkCtrlOffset != 0))
+			{
+			 PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration);
+				// Prepare Configuration to write to Host
+				HostConfiguration |= 0x3;
+				PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration);
+				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
+				// Because in rt30xxForceASPMTest Mode, Force turn on L0s, L1.
+				// Fix HostConfiguration bit0:1 = 0x3 for later use.
+				HostConfiguration = 0x3;
+				DBGPRINT(RT_DEBUG_TRACE, ("PSM : Force ASPM : Host device L1/L0s Value =  0x%x\n", HostConfiguration));
+			}
+		}
+		else if (pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1)
+		{
+
+			// Skip non-exist deice right away
+			if ((pAd->HostLnkCtrlOffset != 0))
+			{
+			 PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, HostConfiguration);
+				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
+				HostConfiguration &= 0x3;
+				DBGPRINT(RT_DEBUG_TRACE, ("PSM : Follow Host ASPM : Host device L1/L0s Value =  0x%x\n", HostConfiguration));
+			}
+		}
+        }
+	// Prepare to write Ralink setting.
+	// Find Ralink PCIe Device's Express Capability Offset
+	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
+
+    if (pos != 0)
+    {
+        // Ralink PCIe Device's Link Control Register Offset
+       pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
+	pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, &reg16);
+        Configuration = le2cpu16(reg16);
+	DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
+			                                    pAd->RLnkCtrlOffset, Configuration));
+		Configuration |= 0x100;
+		if ((pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1)
+			|| (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1))
+		{
+			switch(HostConfiguration)
+			{
+				case 0:
+					Configuration &= 0xffffffc;
+					break;
+				case 1:
+					Configuration &= 0xffffffc;
+					Configuration |= 0x1;
+					break;
+				case 2:
+					Configuration &= 0xffffffc;
+					Configuration |= 0x2;
+					break;
+				case 3:
+					Configuration |= 0x3;
+					break;
+			}
+		}
+		reg16 = cpu2le16(Configuration);
+		pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16);
+		pAd->Rt3xxRalinkLinkCtrl = Configuration;
+		DBGPRINT(RT_DEBUG_TRACE, ("PSM :Write Ralink device L1/L0s Value =  0x%x\n", Configuration));
+	}
+	DBGPRINT(RT_DEBUG_INFO,("PSM :RTMPrt3xSetPCIePowerLinkCtrl <==============\n"));
+
+}
+
+#endif // CONFIG_STA_SUPPORT //
diff --git a/drivers/staging/rt3090/rt3090.h b/drivers/staging/rt3090/rt3090.h
new file mode 100644
index 0000000..d325cb0
--- /dev/null
+++ b/drivers/staging/rt3090/rt3090.h
@@ -0,0 +1,77 @@
+/*
+ *************************************************************************
+ * 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:
+	rt3090.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT3090_H__
+#define __RT3090_H__
+
+#ifdef RT3090
+
+#ifndef RTMP_PCI_SUPPORT
+#error "For RT3090, you should define the compile flag -DRTMP_PCI_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_PCI
+#error "For RT3090, you should define the compile flag -DRTMP_MAC_PCI"
+#endif
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "For RT3090, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
+#endif
+
+#ifndef RT30xx
+#error "For RT3090, you should define the compile flag -DRT30xx"
+#endif
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define TONE_RADAR_DETECT_SUPPORT
+#define CARRIER_SENSE_NEW_ALGO
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#define PCIE_PS_SUPPORT
+
+#include "mac_pci.h"
+#include "rt30xx.h"
+
+//
+// Device ID & Vendor ID, these values should match EEPROM value
+//
+#define NIC3090_PCIe_DEVICE_ID  0x3090		// 1T/1R miniCard
+#define NIC3091_PCIe_DEVICE_ID  0x3091		// 1T/2R miniCard
+#define NIC3092_PCIe_DEVICE_ID  0x3092		// 2T/2R miniCard
+
+#endif // RT3090 //
+
+#endif //__RT3090_H__ //
diff --git a/drivers/staging/rt3090/rt30xx.h b/drivers/staging/rt3090/rt30xx.h
new file mode 100644
index 0000000..70971a0
--- /dev/null
+++ b/drivers/staging/rt3090/rt30xx.h
@@ -0,0 +1,48 @@
+/*
+ *************************************************************************
+ * 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:
+	rt30xx.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT30XX_H__
+#define __RT30XX_H__
+
+#ifdef RT30xx
+
+
+extern REG_PAIR RT30xx_RFRegTable[];
+extern UCHAR NUM_RF_REG_PARMS;
+
+#endif // RT30xx //
+
+#endif //__RT30XX_H__ //
diff --git a/drivers/staging/rt3090/rt3370.h b/drivers/staging/rt3090/rt3370.h
new file mode 100644
index 0000000..bfa9006
--- /dev/null
+++ b/drivers/staging/rt3090/rt3370.h
@@ -0,0 +1,64 @@
+/*
+ *************************************************************************
+ * 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:
+    rt3370.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT3370_H__
+#define __RT3370_H__
+
+#ifdef RT3370
+
+
+#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT"
+
+#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB"
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
+#endif
+
+#ifndef RT33xx
+#error "For RT3070, you should define the compile flag -DRT30xx"
+#endif
+
+#include "mac_usb.h"
+#include "rt33xx.h"
+
+//
+// Device ID & Vendor ID, these values should match EEPROM value
+//
+
+#endif // RT3370 //
+
+#endif //__RT3370_H__ //
diff --git a/drivers/staging/rt3090/rt3390.h b/drivers/staging/rt3090/rt3390.h
new file mode 100644
index 0000000..412ab3d
--- /dev/null
+++ b/drivers/staging/rt3090/rt3390.h
@@ -0,0 +1,77 @@
+/*
+ *************************************************************************
+ * 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:
+    rt3390.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT3390_H__
+#define __RT3390_H__
+
+#ifdef RT3390
+
+#ifndef RTMP_PCI_SUPPORT
+#error "For RT3390, you should define the compile flag -DRTMP_PCI_SUPPORT"
+#endif
+
+#ifndef RTMP_MAC_PCI
+#error "For RT3390, you should define the compile flag -DRTMP_MAC_PCI"
+#endif
+
+#ifndef RTMP_RF_RW_SUPPORT
+#error "For RT3390, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
+#endif
+
+#ifndef RT30xx
+#error "For RT3390, you should define the compile flag -DRT30xx"
+#endif
+
+#ifdef CARRIER_DETECTION_SUPPORT
+#define TONE_RADAR_DETECT_SUPPORT
+#define CARRIER_SENSE_NEW_ALGO
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#define PCIE_PS_SUPPORT
+
+#include "mac_pci.h"
+#include "rt33xx.h"
+
+//
+// Device ID & Vendor ID, these values should match EEPROM value
+//
+#define NIC3390_PCIe_DEVICE_ID  0x3090		// 1T/1R miniCard
+#define NIC3391_PCIe_DEVICE_ID  0x3091		// 1T/2R miniCard
+#define NIC3392_PCIe_DEVICE_ID  0x3092		// 2T/2R miniCard
+
+#endif // RT3390 //
+
+#endif //__RT3390_H__ //
diff --git a/drivers/staging/rt3090/rt33xx.h b/drivers/staging/rt3090/rt33xx.h
new file mode 100644
index 0000000..6eb9388
--- /dev/null
+++ b/drivers/staging/rt3090/rt33xx.h
@@ -0,0 +1,48 @@
+/*
+ *************************************************************************
+ * 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:
+    rt33xx.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RT33XX_H__
+#define __RT33XX_H__
+
+#ifdef RT33xx
+
+
+extern REG_PAIR RFRegTableOverRT3390[];
+extern UCHAR NUM_RF_REG_PARMS_OVER_RT3390;
+
+#endif // RT33xx //
+
+#endif //__RT33XX_H__ //
diff --git a/drivers/staging/rt3090/rt_ate.c b/drivers/staging/rt3090/rt_ate.c
new file mode 100644
index 0000000..259aae4
--- /dev/null
+++ b/drivers/staging/rt3090/rt_ate.c
@@ -0,0 +1,6089 @@
+/*
+ *************************************************************************
+ * 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 RALINK_ATE
+
+#ifdef RT30xx
+#define ATE_BBP_REG_NUM	168
+UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
+#endif // RT30xx //
+
+// 802.11 MAC Header, Type:Data, Length:24bytes
+UCHAR TemplateFrame[24] = {0x08,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00};
+
+extern RTMP_RF_REGS RF2850RegTable[];
+extern UCHAR NUM_OF_2850_CHNL;
+
+extern FREQUENCY_ITEM FreqItems3020[];
+extern UCHAR NUM_OF_3020_CHNL;
+
+
+
+
+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	PSTRING			arg);
+
+#ifndef RT30xx
+static int CheckMCSValid(
+	IN UCHAR Mode,
+	IN UCHAR Mcs);
+#endif // RT30xx //
+
+#ifdef RT30xx
+static int CheckMCSValid(
+	IN UCHAR Mode,
+	IN UCHAR Mcs,
+	IN BOOLEAN bRT2070);
+#endif // RT30xx //
+
+#ifdef RTMP_MAC_PCI
+static VOID ATEWriteTxWI(
+	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);
+#endif // RTMP_MAC_PCI //
+
+
+static VOID SetJapanFilter(
+	IN	PRTMP_ADAPTER	pAd);
+
+
+#ifdef RALINK_28xx_QA
+static inline INT	DO_RACFG_CMD_ATE_START(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_STOP(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_RF_WRITE_ALL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_E2PROM_READ16(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_E2PROM_WRITE16(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_E2PROM_READ_ALL
+(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_E2PROM_WRITE_ALL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_IO_READ(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_IO_WRITE(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_IO_READ_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_BBP_READ8(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_BBP_WRITE8(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_BBP_READ_ALL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_GET_NOISE_LEVEL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_GET_COUNTER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_CLEAR_COUNTER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_TX_START(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_GET_TX_STATUS(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_TX_STOP(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_RX_START(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_RX_STOP(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_RX_STOP(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_START_TX_CARRIER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_START_TX_CONT(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_START_TX_FRAME(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_BW(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER0(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER1(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_FREQ_OFFSET(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_GET_STATISTICS(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_RESET_COUNTER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SEL_RX_ANTENNA(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_PREAMBLE(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_CHANNEL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_ADDR1(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_ADDR2(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_ADDR3(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_RATE(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_START_RX_FRAME(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_E2PROM_READ_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_IO_WRITE_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_BBP_READ_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+static inline INT DO_RACFG_CMD_ATE_BBP_WRITE_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN struct ate_racfghdr *pRaCfg
+);
+
+#endif // RALINK_28xx_QA //
+
+
+#ifdef RTMP_MAC_PCI
+static INT TxDmaBusy(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT result;
+	WPDMA_GLO_CFG_STRUC GloCfg;
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA
+	if (GloCfg.field.TxDMABusy)
+		result = 1;
+	else
+		result = 0;
+
+	return result;
+}
+
+
+static INT RxDmaBusy(
+	IN PRTMP_ADAPTER pAd)
+{
+	INT result;
+	WPDMA_GLO_CFG_STRUC GloCfg;
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA
+	if (GloCfg.field.RxDMABusy)
+		result = 1;
+	else
+		result = 0;
+
+	return result;
+}
+
+
+static VOID RtmpDmaEnable(
+	IN PRTMP_ADAPTER pAd,
+	IN INT Enable)
+{
+	BOOLEAN value;
+	ULONG WaitCnt;
+	WPDMA_GLO_CFG_STRUC GloCfg;
+
+	value = Enable > 0 ? 1 : 0;
+
+	// check DMA is in busy mode.
+	WaitCnt = 0;
+
+	while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
+	{
+		RTMPusecDelay(10);
+		if (WaitCnt++ > 100)
+			break;
+	}
+
+	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);	// disable DMA
+	GloCfg.field.EnableTxDMA = value;
+	GloCfg.field.EnableRxDMA = value;
+	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);	// abort all TX rings
+	RTMPusecDelay(5000);
+
+	return;
+}
+#endif // RTMP_MAC_PCI //
+
+
+
+
+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;
+}
+
+
+#ifdef RT30xx
+static int CheckMCSValid(
+	UCHAR Mode,
+	UCHAR Mcs,
+	BOOLEAN bRT2070)
+#endif // RT30xx //
+#ifndef RT30xx
+static int CheckMCSValid(
+	IN UCHAR Mode,
+	IN UCHAR Mcs)
+#endif // RT30xx //
+{
+	INT i;
+	PCHAR pRateTab;
+
+	switch (Mode)
+	{
+		case 0:
+			pRateTab = CCKRateTable;
+			break;
+		case 1:
+			pRateTab = OFDMRateTable;
+			break;
+		case 2:
+		case 3:
+#ifdef RT30xx
+			if (bRT2070)
+				pRateTab = OFDMRateTable;
+			else
+#endif // RT30xx //
+			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;
+}
+
+
+static INT ATETxPwrHandler(
+	IN PRTMP_ADAPTER pAd,
+	IN char index)
+{
+	ULONG R;
+	CHAR TxPower;
+	UCHAR Bbp94 = 0;
+	BOOLEAN bPowerReduce = FALSE;
+#ifdef RTMP_RF_RW_SUPPORT
+	UCHAR RFValue;
+#endif // RTMP_RF_RW_SUPPORT //
+#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.
+		*/
+		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 RTMP_RF_RW_SUPPORT
+		if (IS_RT30xx(pAd))
+		{
+			// Set Tx Power
+			ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)&RFValue);
+			RFValue = (RFValue & 0xE0) | TxPower;
+			ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)RFValue);
+			ATEDBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower=%d, RFValue=%x)\n", __FUNCTION__, TxPower, RFValue));
+		}
+		else
+#endif // RTMP_RF_RW_SUPPORT //
+		{
+		if (pAd->ate.Channel <= 14)
+		{
+			if (index == 0)
+			{
+				// shift TX power control to correct RF(R3) register bit position
+				R = R << 9;
+				R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+				pAd->LatchRfRegs.R3 = R;
+			}
+			else
+			{
+				// shift TX power control to correct RF(R4) register bit position
+				R = R << 6;
+				R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+				pAd->LatchRfRegs.R4 = R;
+			}
+		}
+		else /* 5.5GHz */
+		{
+			if (bPowerReduce == FALSE)
+			{
+				if (index == 0)
+				{
+					// shift TX power control to correct RF(R3) register bit position
+					R = (R << 10) | (1 << 9);
+					R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+					pAd->LatchRfRegs.R3 = R;
+				}
+				else
+				{
+					// shift TX power control to correct RF(R4) register bit position
+					R = (R << 7) | (1 << 6);
+					R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+					pAd->LatchRfRegs.R4 = R;
+				}
+			}
+			else
+			{
+				if (index == 0)
+				{
+					// shift TX power control to correct RF(R3) register bit position
+					R = (R << 10);
+					R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+
+					/* Clear bit 9 of R3 to reduce 7dB. */
+					pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
+				}
+				else
+				{
+					// shift TX power control to correct RF(R4) register bit position
+					R = (R << 7);
+					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;
+	}
+}
+
+
+/*
+==========================================================================
+    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
+==========================================================================
+*/
+#ifdef RTMP_MAC_PCI
+static INT	ATECmdHandler(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UINT32			Value = 0;
+	UCHAR			BbpData;
+	UINT32			MacData = 0;
+	PTXD_STRUC		pTxD;
+	INT				index;
+	UINT			i = 0, atemode = 0;
+	PRXD_STRUC		pRxD;
+	PRTMP_TX_RING	pTxRing = &pAd->TxRing[QID_AC_BE];
+	NDIS_STATUS		Status = NDIS_STATUS_SUCCESS;
+#ifdef	RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
+
+	ATEAsicSwitchChannel(pAd);
+
+	/* empty function */
+	AsicLockChannel(pAd, pAd->ate.Channel);
+
+	RTMPusecDelay(5000);
+
+	// read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
+	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+	// Default value in BBP R22 is 0x0.
+	BbpData = 0;
+
+	// clean bit4 to stop continuous Tx production test.
+	MacData &= 0xFFFFFFEF;
+
+	// Enter ATE mode and set Tx/Rx Idle
+	if (!strcmp(arg, "ATESTART"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
+
+#if defined(LINUX) || defined(VXWORKS)
+		// check if we have removed the firmware
+		if (!(ATE_ON(pAd)))
+		{
+			NICEraseFirmware(pAd);
+		}
+#endif // defined(LINUX) || defined(VXWORKS) //
+
+		atemode = pAd->ate.Mode;
+		pAd->ate.Mode = ATE_START;
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+		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);
+		}
+
+		/*
+			We should free some resource which was allocated
+			when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
+		*/
+		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+		{
+			PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
+
+			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);
+			}
+
+			// Abort Tx, Rx DMA.
+			RtmpDmaEnable(pAd, 0);
+			for (i=0; i<TX_RING_SIZE; i++)
+			{
+				PNDIS_PACKET  pPacket;
+
+#ifndef RT_BIG_ENDIAN
+			    pTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
+#else
+			pDestTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
+			TxD = *pDestTxD;
+			pTxD = &TxD;
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+				pTxD->DMADONE = 0;
+				pPacket = pTxRing->Cell[i].pNdisPacket;
+
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+				}
+
+				// Always assign pNdisPacket as NULL after clear
+				pTxRing->Cell[i].pNdisPacket = NULL;
+
+				pPacket = pTxRing->Cell[i].pNextNdisPacket;
+
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+				}
+
+				// Always assign pNextNdisPacket as NULL after clear
+				pTxRing->Cell[i].pNextNdisPacket = NULL;
+#ifdef RT_BIG_ENDIAN
+				RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+				WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif
+			}
+
+			// Start Tx, RX DMA
+			RtmpDmaEnable(pAd, 1);
+		}
+
+		// 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;
+		// TxStatus : 0 --> task is idle, 1 --> task is running
+		pAd->ate.TxStatus = 0;
+#endif // RALINK_28xx_QA //
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+		/* LinkDown() has "AsicDisableSync();" and "RTMP_BBP_IO_R/W8_BY_REG_ID();" inside. */
+//      LinkDown(pAd, FALSE);
+//		AsicEnableBssSync(pAd);
+
+#if defined(LINUX) || defined(VXWORKS)
+		RTMP_OS_NETDEV_STOP_QUEUE(pAd->net_dev);
+#endif // defined(LINUX) || defined(VXWORKS) //
+
+		/*
+			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 //
+
+		/* Disable 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);
+	}
+	else if (!strcmp(arg, "ATESTOP"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTOP\n"));
+
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+		// recover the MAC_SYS_CTRL register back
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+		// disable Tx, Rx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= (0xfffffff3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// abort Tx, RX DMA
+		RtmpDmaEnable(pAd, 0);
+
+#ifdef LINUX
+		pAd->ate.bFWLoading = TRUE;
+
+		Status = NICLoadFirmware(pAd);
+
+		if (Status != NDIS_STATUS_SUCCESS)
+		{
+			ATEDBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
+			return FALSE;
+		}
+#endif // LINUX //
+		pAd->ate.Mode = ATE_STOP;
+
+		/*
+			Even the firmware has been loaded,
+			we still could use ATE_BBP_IO_READ8_BY_REG_ID().
+			But this is not suggested.
+		*/
+		BbpSoftReset(pAd);
+
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+
+		NICInitializeAdapter(pAd, TRUE);
+
+		/*
+			Reinitialize Rx Ring before Rx DMA is enabled.
+			>>>RxCoherent<<< was gone !
+		*/
+		for (index = 0; index < RX_RING_SIZE; index++)
+		{
+			pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
+			pRxD->DDONE = 0;
+		}
+
+		// We should read EEPROM for all cases.
+		NICReadEEPROMParameters(pAd, NULL);
+		NICInitAsicFromEEPROM(pAd);
+
+		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+
+		/* empty function */
+		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+		/* clear garbage interrupts */
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);
+		/* Enable Interrupt */
+		RTMP_ASIC_INTERRUPT_ENABLE(pAd);
+
+		/* restore RX_FILTR_CFG */
+
+#ifdef CONFIG_STA_SUPPORT
+		/* restore RX_FILTR_CFG due to that QA maybe set it to 0x3 */
+		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
+#endif // CONFIG_STA_SUPPORT //
+
+		// Enable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// 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);
+
+
+#ifdef CONFIG_STA_SUPPORT
+		RTMPStationStart(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(LINUX) || defined(VXWORKS)
+		RTMP_OS_NETDEV_START_QUEUE(pAd->net_dev);
+#endif // defined(LINUX) || defined(VXWORKS) //
+	}
+	else if (!strcmp(arg, "TXCARR"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
+		pAd->ate.Mode = ATE_TXCARR;
+
+		// 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"))
+	{
+		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"));
+
+		// Step 1: send 50 packets first.
+		pAd->ate.Mode = ATE_TXCONT;
+		pAd->ate.TxCount = 50;
+
+		/* Do it after Tx/Rx DMA is aborted. */
+//		pAd->ate.TxDoneCount = 0;
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+
+		// Fix can't smooth kick
+		{
+			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10,  &pTxRing->TxDmaIdx);
+			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
+			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
+			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
+		}
+
+		pAd->ate.TxDoneCount = 0;
+
+		/* Only needed if we have to send some normal frames. */
+		SetJapanFilter(pAd);
+
+		for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
+		{
+			PNDIS_PACKET pPacket;
+			UINT32 TxIdx = pTxRing->TxCpuIdx;
+
+#ifndef RT_BIG_ENDIAN
+			pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
+#else
+			pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
+			TxD = *pDestTxD;
+			pTxD = &TxD;
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+			// Clean current cell.
+			pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+
+			// Always assign pNdisPacket as NULL after clear
+			pTxRing->Cell[TxIdx].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+
+			// Always assign pNextNdisPacket as NULL after clear
+			pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+#ifdef RT_BIG_ENDIAN
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+			WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif
+
+			if (ATESetUpFrame(pAd, TxIdx) != 0)
+				break;
+
+			INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
+		}
+
+		// Setup frame format.
+		ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
+
+		// Start Tx, RX DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		// 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);
+
+#ifdef RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			pAd->ate.TxStatus = 1;
+		}
+#endif // RALINK_28xx_QA //
+
+		// kick Tx-Ring
+		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
+
+		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;
+
+		// Fix can't smooth kick
+		{
+			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10,  &pTxRing->TxDmaIdx);
+			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
+			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
+			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
+		}
+
+		pAd->ate.TxDoneCount = 0;
+
+		SetJapanFilter(pAd);
+
+		for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
+		{
+			PNDIS_PACKET pPacket;
+			UINT32 TxIdx = pTxRing->TxCpuIdx;
+
+#ifndef RT_BIG_ENDIAN
+			pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
+#else
+			pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
+			TxD = *pDestTxD;
+			pTxD = &TxD;
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+			// clean current cell.
+			pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+
+			// Always assign pNdisPacket as NULL after clear
+			pTxRing->Cell[TxIdx].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+
+			// Always assign pNextNdisPacket as NULL after clear
+			pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+#ifdef RT_BIG_ENDIAN
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+			WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif
+
+			if (ATESetUpFrame(pAd, TxIdx) != 0)
+				break;
+
+			INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
+		}
+
+		ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
+
+		// Start Tx, RX DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		// 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);
+
+#ifdef RALINK_28xx_QA
+		if (pAd->ate.bQATxStart == TRUE)
+		{
+			pAd->ate.TxStatus = 1;
+		}
+#endif // RALINK_28xx_QA //
+
+		// kick Tx-Ring.
+		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
+
+		RTMPusecDelay(500);
+
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+		MacData |= 0x00000010;
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+	}
+	else if (!strcmp(arg, "TXFRAME"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=%d)\n", pAd->ate.TxCount));
+		pAd->ate.Mode |= ATE_TXFRAME;
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+		// Abort Tx, RX DMA.
+		RtmpDmaEnable(pAd, 0);
+
+		// Fix can't smooth kick
+		{
+			RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10,  &pTxRing->TxDmaIdx);
+			pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
+			pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
+			RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
+		}
+
+		pAd->ate.TxDoneCount = 0;
+
+		SetJapanFilter(pAd);
+
+		for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
+		{
+			PNDIS_PACKET pPacket;
+			UINT32 TxIdx = pTxRing->TxCpuIdx;
+
+#ifndef RT_BIG_ENDIAN
+			pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
+#else
+			pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
+			TxD = *pDestTxD;
+			pTxD = &TxD;
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+			// Clean current cell.
+			pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+
+			// Always assign pNdisPacket as NULL after clear
+			pTxRing->Cell[TxIdx].pNdisPacket = NULL;
+
+			pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
+
+			if (pPacket)
+			{
+				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+				RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+			}
+
+			// Always assign pNextNdisPacket as NULL after clear
+			pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
+
+#ifdef RT_BIG_ENDIAN
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+			WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif
+
+			if (ATESetUpFrame(pAd, TxIdx) != 0)
+				break;
+
+			INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
+
+		}
+
+		ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
+
+		// Start Tx, Rx DMA.
+		RtmpDmaEnable(pAd, 1);
+
+		// Enable Tx
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+#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;
+		}
+#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 //
+
+		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * RINGREG_DIFF, &pAd->TxRing[QID_AC_BE].TxDmaIdx);
+		// kick Tx-Ring.
+		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
+
+		pAd->RalinkCounters.KickTxCount++;
+	}
+#ifdef RALINK_28xx_QA
+	else if (!strcmp(arg, "TXSTOP"))
+	{
+		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);
+		}
+
+		/*
+			We should free some resource which was allocated
+			when ATE_TXFRAME, ATE_STOP, and ATE_TXCONT.
+		*/
+		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+		{
+			PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
+
+			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);
+			}
+
+			// Abort Tx, Rx DMA.
+			RtmpDmaEnable(pAd, 0);
+
+			for (i=0; i<TX_RING_SIZE; i++)
+			{
+				PNDIS_PACKET  pPacket;
+
+#ifndef RT_BIG_ENDIAN
+			    pTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
+#else
+			pDestTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
+			TxD = *pDestTxD;
+			pTxD = &TxD;
+			RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+#endif
+				pTxD->DMADONE = 0;
+				pPacket = pTxRing->Cell[i].pNdisPacket;
+
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+				}
+
+				// Always assign pNdisPacket as NULL after clear
+				pTxRing->Cell[i].pNdisPacket = NULL;
+
+				pPacket = pTxRing->Cell[i].pNextNdisPacket;
+
+				if (pPacket)
+				{
+					PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
+					RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+				}
+
+				// Always assign pNextNdisPacket as NULL after clear
+				pTxRing->Cell[i].pNextNdisPacket = NULL;
+#ifdef RT_BIG_ENDIAN
+				RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+				WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif
+			}
+			// Enable Tx, Rx DMA
+			RtmpDmaEnable(pAd, 1);
+
+		}
+
+		// TxStatus : 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, &Value);
+		Value &= ~(1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+	}
+	else if (!strcmp(arg, "RXSTOP"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
+		atemode = pAd->ate.Mode;
+		pAd->ate.Mode &= ATE_RXSTOP;
+		pAd->ate.bQARxStart = FALSE;
+//		pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+		if (atemode == ATE_TXCARR)
+		{
+			;
+		}
+		else if (atemode == ATE_TXCARRSUPP)
+		{
+			;
+		}
+
+		/*
+			We should free some resource which was allocated
+			when ATE_TXFRAME, ATE_STOP, and ATE_TXCONT.
+		*/
+		else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+		{
+			if (atemode == ATE_TXCONT)
+			{
+				;
+			}
+		}
+
+		// Soft reset BBP.
+		BbpSoftReset(pAd);
+
+		// 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 //
+	else if (!strcmp(arg, "RXFRAME"))
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
+
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+		pAd->ate.Mode |= ATE_RXFRAME;
+
+		// Disable Tx of MAC block.
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value &= ~(1 << 2);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+		// Enable Rx of MAC block.
+		RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+		Value |= (1 << 3);
+		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+	}
+	else
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
+		return FALSE;
+	}
+	RTMPusecDelay(5000);
+
+	ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
+
+	return TRUE;
+}
+/*=======================End of RTMP_MAC_PCI =======================*/
+#endif // RTMP_MAC_PCI //
+
+
+
+
+INT	Set_ATE_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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	PSTRING			arg)
+{
+	PSTRING				value;
+	INT					i;
+
+	// Mac address acceptable format 01:02:03:04:05:06 length 17
+	if (strlen(arg) != 17)
+		return FALSE;
+
+    for (i = 0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+	{
+		/* sanity check */
+		if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
+		{
+			return FALSE;
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		AtoH(value, &pAd->ate.Addr3[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	/* sanity check */
+	if (i != 6)
+	{
+		return FALSE;
+	}
+
+#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	PSTRING			arg)
+{
+	PSTRING				value;
+	INT					i;
+
+	// Mac address acceptable format 01:02:03:04:05:06 length 17
+	if (strlen(arg) != 17)
+		return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+	{
+		/* sanity check */
+		if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
+		{
+			return FALSE;
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		AtoH(value, &pAd->ate.Addr2[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	/* sanity check */
+	if (i != 6)
+	{
+		return FALSE;
+	}
+
+#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	PSTRING			arg)
+{
+	PSTRING				value;
+	INT					i;
+
+	// Mac address acceptable format 01:02:03:04:05:06 length 17
+	if (strlen(arg) != 17)
+		return FALSE;
+
+    for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+	{
+		/* sanity check */
+		if ((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))))
+		{
+			return FALSE;
+		}
+
+#ifdef CONFIG_STA_SUPPORT
+		AtoH(value, &pAd->ate.Addr1[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+	}
+
+	/* sanity check */
+	if(i != 6)
+	{
+		return FALSE;
+	}
+
+#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	PSTRING			arg)
+{
+	UCHAR channel;
+
+	channel = simple_strtol(arg, 0, 10);
+
+	// to allow A band channel : ((channel < 1) || (channel > 14))
+	if ((channel < 1) || (channel > 216))
+	{
+		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	PSTRING			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.5 GHz */
+	{
+		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	PSTRING			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	PSTRING			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"));
+
+	// calibration power unbalance issues, merged from Arch Team
+	ATEAsicSwitchChannel(pAd);
+
+
+	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	PSTRING			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"));
+
+	// calibration power unbalance issues, merged from Arch Team
+	ATEAsicSwitchChannel(pAd);
+
+
+	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	PSTRING			arg)
+{
+	UCHAR RFFreqOffset = 0;
+	ULONG R4 = 0;
+
+	RFFreqOffset = simple_strtol(arg, 0, 10);
+#ifndef RTMP_RF_RW_SUPPORT
+	if (RFFreqOffset >= 64)
+#endif // RTMP_RF_RW_SUPPORT //
+	/* RT35xx ATE will reuse this code segment. */
+#ifdef RTMP_RF_RW_SUPPORT
+//2008/08/06: KH modified the limit of offset value from 65 to 95(0x5F)
+	if (RFFreqOffset >= 95)
+#endif // RTMP_RF_RW_SUPPORT //
+	{
+		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 RTMP_RF_RW_SUPPORT
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
+	{
+		// Set RF offset
+		UCHAR RFValue;
+		ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R23, (PUCHAR)&RFValue);
+//2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+		RFValue = ((RFValue & 0x80) | pAd->ate.RFFreqOffset);
+		ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R23, (UCHAR)RFValue);
+	}
+	else
+#endif // RTMP_RF_RW_SUPPORT //
+	{
+		// RT28xx
+		// shift TX power control to correct RF register bit position
+		R4 = pAd->ate.RFFreqOffset << 15;
+		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	PSTRING			arg)
+{
+	INT i;
+	UCHAR value = 0;
+	UCHAR BBPCurrentBW;
+
+	BBPCurrentBW = simple_strtol(arg, 0, 10);
+
+	if ((BBPCurrentBW == 0)
+#ifdef RT30xx
+		|| IS_RT2070(pAd)
+#endif // RT30xx //
+		)
+	{
+		pAd->ate.TxWI.BW = BW_20;
+	}
+	else
+	{
+		pAd->ate.TxWI.BW = BW_40;
+	}
+
+	/* RT35xx ATE will reuse this code segment. */
+	// Fix the error spectrum of CCK-40MHZ
+	// Turn on BBP 20MHz mode by request here.
+	if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.TxWI.BW == BW_40))
+	{
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_BW_Proc!! Warning!! CCK only supports 20MHZ!!\nBandwidth switch to 20\n"));
+		pAd->ate.TxWI.BW = BW_20;
+	}
+
+	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
+			(to set 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);
+			}
+		}
+
+#ifdef RT30xx
+		// set BW = 20 MHz
+		if (IS_RT30xx(pAd))
+			ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24);
+		else
+#endif // RT30xx //
+		// set BW = 20 MHz
+		{
+			pAd->LatchRfRegs.R4 &= ~0x00200000;
+			RtmpRfIoWrite(pAd);
+		}
+
+	}
+	// If bandwidth = 40M, set RF Reg4 bit 21 = 0.
+	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 = 40 MHz
+		if(IS_RT30xx(pAd))
+			ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24);
+		else
+#endif // RT30xx //
+		// set BW = 40 MHz
+		{
+		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	PSTRING			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	PSTRING			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	PSTRING			arg)
+{
+	UCHAR MCS;
+	INT result;
+
+	MCS = simple_strtol(arg, 0, 10);
+#ifndef RT30xx
+	result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
+#endif // RT30xx //
+
+	/* RT35xx ATE will reuse this code segment. */
+#ifdef RT30xx
+	result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS, IS_RT2070(pAd));
+#endif // RT30xx //
+
+
+	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	PSTRING			arg)
+{
+	UCHAR BbpData = 0;
+
+	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.\nIt 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;
+	}
+
+	// Turn on BBP 20MHz mode by request here.
+	if (pAd->ate.TxWI.PHYMODE == MODE_CCK)
+	{
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
+		BbpData &= (~0x18);
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
+		pAd->ate.TxWI.BW = BW_20;
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::CCK Only support 20MHZ. Switch to 20MHZ.\n"));
+	}
+
+	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	PSTRING			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;
+}
+
+
+INT	Set_ATE_RX_FER_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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	PSTRING			arg)
+{
+#ifdef RTMP_RF_RW_SUPPORT
+//2008/07/10:KH add to support RT30xx ATE<--
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
+	{
+		/* modify by WY for Read RF Reg. error */
+		UCHAR RFValue;
+		INT index=0;
+
+		for (index = 0; index < 32; index++)
+		{
+			ATE_RF_IO_READ8_BY_REG_ID(pAd, index, (PUCHAR)&RFValue);
+			ate_print("R%d=%d\n",index,RFValue);
+		}
+	}
+	else
+//2008/07/10:KH add to support RT30xx ATE-->
+#endif // RTMP_RF_RW_SUPPORT //
+	{
+		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	PSTRING			arg)
+{
+	UINT32 value = (UINT32) simple_strtol(arg, 0, 16);
+
+#ifdef RTMP_RF_RW_SUPPORT
+//2008/07/10:KH add to support 3070 ATE<--
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
+	{
+		ate_print("Warning!! RT3xxx Don't Support !\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RTMP_RF_RW_SUPPORT //
+	{
+		pAd->LatchRfRegs.R1 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+}
+
+
+INT Set_ATE_Write_RF2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UINT32 value = (UINT32) simple_strtol(arg, 0, 16);
+
+#ifdef RTMP_RF_RW_SUPPORT
+//2008/07/10:KH add to support 3070 ATE<--
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
+	{
+		ate_print("Warning!! RT3xxx Don't Support !\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RTMP_RF_RW_SUPPORT //
+	{
+		pAd->LatchRfRegs.R2 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+}
+
+
+INT Set_ATE_Write_RF3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UINT32 value = simple_strtol(arg, 0, 16);
+
+#ifdef RTMP_RF_RW_SUPPORT
+//2008/07/10:KH add to support 3070 ATE<--
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
+	{
+		ate_print("Warning!! RT3xxx Don't Support !\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RTMP_RF_RW_SUPPORT //
+	{
+		pAd->LatchRfRegs.R3 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+}
+
+
+INT Set_ATE_Write_RF4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UINT32 value = (UINT32) simple_strtol(arg, 0, 16);
+
+#ifdef RTMP_RF_RW_SUPPORT
+//2008/07/10:KH add to support 3070 ATE<--
+	if (IS_RT30xx(pAd) || IS_RT3572(pAd))
+	{
+		ate_print("Warning!! RT3xxx Don't Support !\n");
+		return FALSE;
+
+	}
+	else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RTMP_RF_RW_SUPPORT //
+	{
+		pAd->LatchRfRegs.R4 = value;
+		RtmpRfIoWrite(pAd);
+	}
+	return TRUE;
+}
+
+
+/*
+==========================================================================
+    Description:
+        Load and Write EEPROM from a binary file prepared in advance.
+
+        Return:
+		TRUE if all parameters are OK, FALSE otherwise
+==========================================================================
+*/
+#if defined(LINUX) || defined(VXWORKS)
+INT Set_ATE_Load_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	BOOLEAN			ret = FALSE;
+	PSTRING			src = EEPROM_BIN_FILE_NAME;
+	RTMP_OS_FD		srcf;
+	INT32			retval;
+	USHORT			WriteEEPROM[(EEPROM_SIZE/2)];
+	INT				FileLength = 0;
+	UINT32			value = (UINT32) simple_strtol(arg, 0, 10);
+	RTMP_OS_FS_INFO	osFSInfo;
+
+	ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
+
+	if (value > 0)
+	{
+		/* zero the e2p buffer */
+		NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+		RtmpOSFSInfoChange(&osFSInfo, TRUE);
+
+		do
+		{
+			/* open the bin file */
+			srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+
+			if (IS_FILE_OPEN_ERR(srcf))
+			{
+				ate_print("%s - Error opening file %s\n", __FUNCTION__, src);
+				break;
+			}
+
+			/* read the firmware from the file *.bin */
+			FileLength = RtmpOSFileRead(srcf, (PSTRING)WriteEEPROM, EEPROM_SIZE);
+
+			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_FILE_OPEN_ERR(srcf))
+		{
+				;
+		}
+		else
+		{
+			retval = RtmpOSFileClose(srcf);
+
+			if (retval)
+			{
+				ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
+
+			}
+		}
+
+		/* restore */
+		RtmpOSFSInfoChange(&osFSInfo, FALSE);
+	}
+
+    ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
+
+    return ret;
+
+}
+#endif // defined(LINUX) || defined(VXWORKS) //
+
+
+
+
+INT Set_ATE_Read_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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	PSTRING			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	PSTRING			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 = 0, BbpValue = 0, R66 = 0x30;
+	RTMP_RF_REGS *RFRegTable;
+	UCHAR Channel = 0;
+
+	RFRegTable = NULL;
+
+#ifdef RALINK_28xx_QA
+	// for QA mode, TX power values are passed from UI
+	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 for RT3090
+	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 = 0;
+
+		for (index = 0; index < NUM_OF_3020_CHNL; index++)
+		{
+			if (Channel == FreqItems3020[index].Channel)
+			{
+				// Programming channel parameters.
+				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R02, FreqItems3020[index].N);
+				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R03, FreqItems3020[index].K);
+
+				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R06, (PUCHAR)&RFValue);
+				RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R06, (UCHAR)RFValue);
+
+				// Set Tx Power.
+				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R12, (PUCHAR)&RFValue);
+				RFValue = (RFValue & 0xE0) | TxPwer;
+				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R12, (UCHAR)RFValue);
+
+				// Set RF offset.
+				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R23, (PUCHAR)&RFValue);
+				//2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+				RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+				ATE_RF_IO_WRITE8_BY_REG_ID(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;
+				}
+				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R24, (UCHAR)RFValue);
+
+				// Enable RF tuning
+				ATE_RF_IO_READ8_BY_REG_ID(pAd, RF_R07, (PUCHAR)&RFValue);
+				RFValue = RFValue | 0x1;
+				ATE_RF_IO_WRITE8_BY_REG_ID(pAd, RF_R07, (UCHAR)RFValue);
+
+				// latch channel for future usage
+				pAd->LatchRfRegs.Channel = Channel;
+
+				break;
+			}
+		}
+
+		ATEDBGPRINT(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 //
+	{
+		/* RT28xx */
+		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 TX path is 1, bit 14 = 1;
+						if (pAd->Antenna.field.TxPath == 1)
+						{
+							R2 |= 0x4000;
+						}
+
+						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)
+						{
+							// write 1 to off RxPath
+							R2 |= 0x20040;
+						}
+
+						if (pAd->Antenna.field.TxPath == 2)
+						{
+							if (pAd->ate.TxAntennaSel == 1)
+							{
+								// If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
+								R2 |= 0x4000;
+								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)
+							{
+								// If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
+								R2 |= 0x8000;
+								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
+						{
+							// Set TX power0.
+							R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9);
+							// Set frequency offset and TX power1.
+							R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);
+						}
+
+						// 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)
+	{
+	    UINT32 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);// may be removed for RT35xx ++
+
+		ASSERT((BbpValue == 0x00));
+		if ((BbpValue != 0x00))
+		{
+			ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+		}// may be removed for RT35xx --
+
+		// 5.5 GHz 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;
+		}
+
+		// calibration power unbalance issues
+		if (pAd->Antenna.field.TxPath == 2)
+		{
+			if (pAd->ate.TxAntennaSel == 1)
+			{
+				TxPinCfg &= 0xFFFFFFF7;
+			}
+			else if (pAd->ate.TxAntennaSel == 2)
+			{
+				TxPinCfg &= 0xFFFFFFFD;
+			}
+		}
+
+		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+	}
+	else
+	{
+	    UINT32	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);// may be removed for RT35xx ++
+
+		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));// may be removed for RT35xx --
+
+		// 5.5 GHz 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);
+
+#ifndef RTMP_RF_RW_SUPPORT
+	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));
+    }
+#endif // RTMP_RF_RW_SUPPORT //
+}
+
+
+
+/* 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++)
+				{
+					// Found the range.
+					if (BbpR49 <= pTssiMinusBoundary[idx])
+						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++)
+				{
+					// Found the range.
+					if (BbpR49 >= pTssiPlusBoundary[idx])
+						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 RTMP_MAC_PCI
+static VOID ATEWriteTxWI(
+	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)
+{
+	TXWI_STRUC		TxWI;
+	PTXWI_STRUC	pTxWI;
+
+	//
+	// 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
+	if ( BASize >7 )
+		BASize =7;
+
+	pTxWI->BAWinSize = BASize;
+	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);
+	pTxWI->ShortGI = pTransmit->field.ShortGI;
+	pTxWI->STBC = pTransmit->field.STBC;
+
+	pTxWI->MCS = pTransmit->field.MCS;
+	pTxWI->PHYMODE = pTransmit->field.MODE;
+	pTxWI->CFACK = CfAck;
+	pTxWI->MIMOps = 0;
+	pTxWI->MpduDensity = 0;
+
+	pTxWI->PacketId = pTxWI->MCS;
+	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
+
+    return;
+}
+#endif // RTMP_MAC_PCI //
+
+
+
+
+/*
+========================================================================
+
+	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]);
+
+}
+
+
+
+
+/* There are two ways to convert Rssi */
+/* 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);
+}
+
+
+/*
+========================================================================
+
+	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. */
+//	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 ++;
+}
+
+
+#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"));
+
+#ifdef RTMP_MAC_PCI
+	pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+	/* We did not cancel this timer when entering ATE mode. */
+//	RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+#endif // RTMP_MAC_PCI //
+
+	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 RTMP_MAC_PCI
+static INT ATESetUpFrame(
+	IN PRTMP_ADAPTER pAd,
+	IN UINT32 TxIdx)
+{
+	UINT j;
+	PTXD_STRUC pTxD;
+#ifdef RT_BIG_ENDIAN
+    PTXD_STRUC      pDestTxD;
+    TXD_STRUC       TxD;
+#endif
+	PNDIS_PACKET pPacket;
+	PUCHAR pDest;
+	PVOID AllocVa;
+	NDIS_PHYSICAL_ADDRESS AllocPa;
+	HTTRANSMIT_SETTING	TxHTPhyMode;
+
+	PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
+	PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+	PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
+
+#ifdef RALINK_28xx_QA
+	PHEADER_802_11	pHeader80211;
+#endif // RALINK_28xx_QA //
+
+	if (pAd->ate.bQATxStart == TRUE)
+	{
+		// always use QID_AC_BE and FIFO_EDCA
+
+		// fill TxWI
+		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, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.CFACK,
+			pAd->ate.TxWI.TS,  pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
+			pAd->ate.TxWI.BAWinSize, 0, pAd->ate.TxWI.MPDUtotalByteCount, pAd->ate.TxWI.PacketId, 0, 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, FALSE, FALSE,
+			4, 0, pAd->ate.TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode);
+	}
+
+	// fill 802.11 header
+#ifdef RALINK_28xx_QA
+	if (pAd->ate.bQATxStart == TRUE)
+	{
+		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, pAd->ate.Header, pAd->ate.HLen);
+	}
+	else
+#endif // RALINK_28xx_QA //
+	{
+		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, TemplateFrame, LENGTH_802_11);
+		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+4, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
+		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+10, pAd->ate.Addr2, ETH_LENGTH_OF_ADDRESS);
+		NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+16, pAd->ate.Addr3, ETH_LENGTH_OF_ADDRESS);
+	}
+
+#ifdef RT_BIG_ENDIAN
+	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA)+TXWI_SIZE), DIR_READ, FALSE);
+#endif // RT_BIG_ENDIAN //
+
+	/* alloc buffer for payload */
+#ifdef RALINK_28xx_QA
+	if (pAd->ate.bQATxStart == TRUE)
+	{
+		pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.DLen + 0x100, FALSE, &AllocVa, &AllocPa);
+	}
+	else
+#endif // RALINK_28xx_QA //
+	{
+		pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.TxLength, FALSE, &AllocVa, &AllocPa);
+	}
+
+	if (pPacket == NULL)
+	{
+		pAd->ate.TxCount = 0;
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("%s fail to alloc packet space.\n", __FUNCTION__));
+		return -1;
+	}
+	pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket;
+
+	pDest = (PUCHAR) AllocVa;
+
+#ifdef RALINK_28xx_QA
+	if (pAd->ate.bQATxStart == TRUE)
+	{
+		RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.DLen;
+	}
+	else
+#endif // RALINK_28xx_QA //
+	{
+		RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.TxLength - LENGTH_802_11;
+	}
+
+	// prepare frame payload
+#ifdef RALINK_28xx_QA
+	if (pAd->ate.bQATxStart == TRUE)
+	{
+		// copy pattern
+		if ((pAd->ate.PLen != 0))
+		{
+			int j;
+
+			for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
+			{
+				memcpy(RTPKT_TO_OSPKT(pPacket)->data + j, pAd->ate.Pattern, pAd->ate.PLen);
+			}
+		}
+	}
+	else
+#endif // RALINK_28xx_QA //
+	{
+		for (j = 0; j < RTPKT_TO_OSPKT(pPacket)->len; j++)
+		{
+			pDest[j] = 0xA5;
+		}
+	}
+
+	/* build Tx Descriptor */
+#ifndef RT_BIG_ENDIAN
+	pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
+#else
+    pDestTxD  = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
+    TxD = *pDestTxD;
+    pTxD = &TxD;
+#endif // !RT_BIG_ENDIAN //
+
+#ifdef RALINK_28xx_QA
+	if (pAd->ate.bQATxStart == TRUE)
+	{
+		// prepare TxD
+		NdisZeroMemory(pTxD, TXD_SIZE);
+		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+		// build TX DESC
+		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+		pTxD->SDLen0 = TXWI_SIZE + pAd->ate.HLen;
+		pTxD->LastSec0 = 0;
+		pTxD->SDPtr1 = AllocPa;
+		pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;
+		pTxD->LastSec1 = 1;
+
+		pDest = (PUCHAR)pTxWI;
+		pDest += TXWI_SIZE;
+		pHeader80211 = (PHEADER_802_11)pDest;
+
+		// modify sequence number...
+		if (pAd->ate.TxDoneCount == 0)
+		{
+			pAd->ate.seq = pHeader80211->Sequence;
+		}
+		else
+			pHeader80211->Sequence = ++pAd->ate.seq;
+	}
+	else
+#endif // RALINK_28xx_QA //
+	{
+		NdisZeroMemory(pTxD, TXD_SIZE);
+		RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
+		// build TX DESC
+		pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
+		pTxD->SDLen0 = TXWI_SIZE + LENGTH_802_11;
+		pTxD->LastSec0 = 0;
+		pTxD->SDPtr1 = AllocPa;
+		pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;
+		pTxD->LastSec1 = 1;
+	}
+
+#ifdef RT_BIG_ENDIAN
+	RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+	RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA)+TXWI_SIZE), DIR_WRITE, FALSE);
+    RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
+    WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
+#endif // RT_BIG_ENDIAN //
+
+	return 0;
+}
+/*=======================End of RTMP_MAC_PCI =======================*/
+#endif // RTMP_MAC_PCI //
+
+
+
+
+VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+	USHORT i;
+	USHORT value;
+
+
+	for (i = 0 ; i < EEPROM_SIZE/2 ; )
+	{
+		/* "value" is especially 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 especially 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
+
+
+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);
+
+
+
+VOID RtmpDoAte(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq)
+{
+	USHORT Command_Id;
+	INT	Status = NDIS_STATUS_SUCCESS;
+	struct ate_racfghdr *pRaCfg;
+
+
+	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:
+			Status=DO_RACFG_CMD_ATE_START(pAdapter,wrq,pRaCfg);
+			break;
+
+		/* We will get this command either QA is closed or ated is killed by user. */
+		case RACFG_CMD_ATE_STOP:
+			Status=DO_RACFG_CMD_ATE_STOP(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_RF_WRITE_ALL:
+			Status=DO_RACFG_CMD_RF_WRITE_ALL(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_E2PROM_READ16:
+			Status=DO_RACFG_CMD_E2PROM_READ16(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_E2PROM_WRITE16:
+			Status=DO_RACFG_CMD_E2PROM_WRITE16(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_E2PROM_READ_ALL:
+			Status=DO_RACFG_CMD_E2PROM_READ_ALL(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_E2PROM_WRITE_ALL:
+			Status=DO_RACFG_CMD_E2PROM_WRITE_ALL(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_IO_READ:
+			Status=DO_RACFG_CMD_IO_READ(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_IO_WRITE:
+			Status=DO_RACFG_CMD_IO_WRITE(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_IO_READ_BULK:
+			Status=DO_RACFG_CMD_IO_READ_BULK(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_BBP_READ8:
+			Status=DO_RACFG_CMD_BBP_READ8(pAdapter,wrq,pRaCfg);
+			break;
+		case RACFG_CMD_BBP_WRITE8:
+			Status=DO_RACFG_CMD_BBP_WRITE8(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_BBP_READ_ALL:
+			Status=DO_RACFG_CMD_BBP_READ_ALL(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_E2PROM_READ_BULK:
+			Status=DO_RACFG_CMD_ATE_E2PROM_READ_BULK(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
+			Status=DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_IO_WRITE_BULK:
+			Status=DO_RACFG_CMD_ATE_IO_WRITE_BULK(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_BBP_READ_BULK:
+			Status=DO_RACFG_CMD_ATE_BBP_READ_BULK(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_BBP_WRITE_BULK:
+			Status=DO_RACFG_CMD_ATE_BBP_WRITE_BULK(pAdapter,wrq,pRaCfg);
+			break;
+
+
+		case RACFG_CMD_GET_NOISE_LEVEL:
+			Status=DO_RACFG_CMD_GET_NOISE_LEVEL(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_GET_COUNTER:
+			Status=DO_RACFG_CMD_GET_COUNTER(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_CLEAR_COUNTER:
+			Status=DO_RACFG_CMD_CLEAR_COUNTER(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_TX_START:
+			Status=DO_RACFG_CMD_TX_START(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_GET_TX_STATUS:
+			Status=DO_RACFG_CMD_GET_TX_STATUS(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_TX_STOP:
+			Status=DO_RACFG_CMD_TX_STOP(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_RX_START:
+			Status=DO_RACFG_CMD_RX_START(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_RX_STOP:
+			Status=DO_RACFG_CMD_RX_STOP(pAdapter,wrq,pRaCfg);
+			break;
+
+		/* The following cases are for new ATE GUI(not QA). */
+		/*==================================================*/
+		case RACFG_CMD_ATE_START_TX_CARRIER:
+			Status=DO_RACFG_CMD_ATE_START_TX_CARRIER(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_START_TX_CONT:
+			Status=DO_RACFG_CMD_ATE_START_TX_CONT(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_START_TX_FRAME:
+			Status=DO_RACFG_CMD_ATE_START_TX_FRAME(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_BW:
+			Status=DO_RACFG_CMD_ATE_SET_BW(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_POWER0:
+			Status=DO_RACFG_CMD_ATE_SET_TX_POWER0(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_POWER1:
+			Status=DO_RACFG_CMD_ATE_SET_TX_POWER1(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_FREQ_OFFSET:
+			Status=DO_RACFG_CMD_ATE_SET_TX_POWER1(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_GET_STATISTICS:
+			Status=DO_RACFG_CMD_ATE_GET_STATISTICS(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_RESET_COUNTER:
+			Status=DO_RACFG_CMD_ATE_RESET_COUNTER(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SEL_TX_ANTENNA:
+			Status=DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SEL_RX_ANTENNA:
+			Status=DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_PREAMBLE:
+			Status=DO_RACFG_CMD_ATE_SET_PREAMBLE(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_CHANNEL:
+			Status=DO_RACFG_CMD_ATE_SET_CHANNEL(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_ADDR1:
+			Status=DO_RACFG_CMD_ATE_SET_ADDR1(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_ADDR2:
+			Status=DO_RACFG_CMD_ATE_SET_ADDR2(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_ADDR3:
+			Status=DO_RACFG_CMD_ATE_SET_ADDR3(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_RATE:
+			Status=DO_RACFG_CMD_ATE_SET_RATE(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
+			Status=DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
+			Status=DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT(pAdapter,wrq,pRaCfg);
+			break;
+
+		case RACFG_CMD_ATE_START_RX_FRAME:
+			Status=DO_RACFG_CMD_ATE_START_RX_FRAME(pAdapter,wrq,pRaCfg);
+			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 synchronize 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 synchronize 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	PSTRING			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	PSTRING			arg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
+
+	if (Set_ATE_Proc(pAd, "RXSTOP"))
+	{
+		return TRUE;
+	}
+	else
+	{
+		return FALSE;
+	}
+}
+
+
+#ifdef DBG
+INT Set_EERead_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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(KERN_EMERG "%4.4x ", *p);
+		if (((i+1) % 16) == 0)
+			ate_print(KERN_EMERG "\n");
+		p++;
+	}
+
+	return TRUE;
+}
+
+
+INT Set_EEWrite_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	USHORT offset = 0, value;
+	PSTRING p2 = arg;
+
+	while ((*p2 != ':') && (*p2 != '\0'))
+	{
+		p2++;
+	}
+
+	if (*p2 == ':')
+	{
+		A2Hex(offset, arg);
+		A2Hex(value, p2 + 1);
+	}
+	else
+	{
+		A2Hex(value, arg);
+	}
+
+	if (offset >= EEPROM_SIZE)
+	{
+		ate_print(KERN_EMERG "Offset can not exceed EEPROM_SIZE( == 0x%04x)\n", EEPROM_SIZE);
+		return FALSE;
+	}
+
+	RT28xx_EEPROM_WRITE16(pAd, offset, value);
+
+	return TRUE;
+}
+
+
+INT Set_BBPRead_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	UCHAR value = 0, offset;
+
+	A2Hex(offset, arg);
+
+	if (ATE_ON(pAd))
+	{
+		ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset,  &value);
+	}
+	else
+	{
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset,  &value);
+	}
+
+	ate_print(KERN_EMERG "%x\n", value);
+
+	return TRUE;
+}
+
+
+INT Set_BBPWrite_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	USHORT offset = 0;
+	PSTRING p2 = arg;
+	UCHAR value;
+
+	while ((*p2 != ':') && (*p2 != '\0'))
+	{
+		p2++;
+	}
+
+	if (*p2 == ':')
+	{
+		A2Hex(offset, arg);
+		A2Hex(value, p2 + 1);
+	}
+	else
+	{
+		A2Hex(value, arg);
+	}
+
+	if (ATE_ON(pAd))
+	{
+		ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, offset,  value);
+	}
+	else
+	{
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, offset,  value);
+	}
+
+	return TRUE;
+}
+
+
+INT Set_RFWrite_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	PSTRING p2, p3, p4;
+	UINT32 R1, R2, R3, R4;
+
+	p2 = arg;
+
+	while ((*p2 != ':') && (*p2 != '\0'))
+	{
+		p2++;
+	}
+
+	if (*p2 != ':')
+		return FALSE;
+
+	p3 = p2 + 1;
+
+	while((*p3 != ':') && (*p3 != '\0'))
+	{
+		p3++;
+	}
+
+	if (*p3 != ':')
+		return FALSE;
+
+	p4 = p3 + 1;
+
+	while ((*p4 != ':') && (*p4 != '\0'))
+	{
+		p4++;
+	}
+
+	if (*p4 != ':')
+		return FALSE;
+
+
+	A2Hex(R1, arg);
+	A2Hex(R2, p2 + 1);
+	A2Hex(R3, p3 + 1);
+	A2Hex(R4, p4 + 1);
+
+	RTMP_RF_IO_WRITE32(pAd, R1);
+	RTMP_RF_IO_WRITE32(pAd, R2);
+	RTMP_RF_IO_WRITE32(pAd, R3);
+	RTMP_RF_IO_WRITE32(pAd, R4);
+
+	return TRUE;
+}
+#endif // DBG //
+#endif // RALINK_28xx_QA //
+
+
+
+
+#ifdef RALINK_28xx_QA
+#define	LEN_OF_ARG 16
+
+#define RESPONSE_TO_GUI(__pRaCfg, __pwrq, __Length, __Status)									\
+	(__pRaCfg)->length = htons((__Length));														\
+	(__pRaCfg)->status = htons((__Status));														\
+	(__pwrq)->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", (__pwrq)->u.data.length));		\
+	if (copy_to_user((__pwrq)->u.data.pointer, (UCHAR *)(__pRaCfg), (__pwrq)->u.data.length))	\
+	{																							\
+		ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in %s\n", __FUNCTION__));				\
+		return (-EFAULT);																		\
+	}																							\
+	else																						\
+	{																							\
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("%s is done !\n", __FUNCTION__));							\
+	}
+
+static inline INT	DO_RACFG_CMD_ATE_START(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
+
+	/* Prepare feedback as soon as we can to avoid QA timeout. */
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+	Set_ATE_Proc(pAdapter, "ATESTART");
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_STOP(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	INT32 ret;
+
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
+
+	/*
+		Distinguish this command came from QA(via ate agent)
+		or ate agent according to the existence of pid in payload.
+
+		No need to prepare feedback if this cmd came directly from ate agent,
+		not from QA.
+	*/
+	pRaCfg->length = ntohs(pRaCfg->length);
+
+	if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
+	{
+		/*
+			This command came from QA.
+			Get the pid of ATE agent.
+		*/
+		memcpy((UCHAR *)&pAdapter->ate.AtePid,
+						(&pRaCfg->data[0]) - 2/* == sizeof(pRaCfg->status) */,
+						sizeof(pAdapter->ate.AtePid));
+
+		/* Prepare feedback as soon as we can to avoid QA timeout. */
+		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+		/*
+			Kill ATE agent when leaving ATE mode.
+
+			We must kill ATE agent first before setting ATESTOP,
+			or Microsoft will report sth. wrong.
+		*/
+		ret = KILL_THREAD_PID(pAdapter->ate.AtePid, SIGTERM, 1);
+
+		if (ret)
+		{
+			ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to kill ate thread\n", pAdapter->net_dev->name));
+		}
+	}
+
+
+	/* AP/STA might have in ATE_STOP mode due to cmd from QA. */
+	if (ATE_ON(pAdapter))
+	{
+		/* Someone has killed ate agent while QA GUI is still open. */
+		Set_ATE_Proc(pAdapter, "ATESTOP");
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
+	}
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_RF_WRITE_ALL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return  NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_E2PROM_READ16(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	UINT16	offset=0, value=0;
+	USHORT  tmp=0;
+
+	offset = ntohs(pRaCfg->status);
+
+	/* "tmp" is especially 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));
+	memcpy(pRaCfg->data, &value, 2);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+2, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_E2PROM_WRITE16(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	USHORT	offset, value;
+
+	offset = ntohs(pRaCfg->status);
+	memcpy(&value, pRaCfg->data, 2);
+	value = ntohs(value);
+	RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_E2PROM_READ_ALL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	USHORT buffer[EEPROM_SIZE/2];
+
+	rt_ee_read_all(pAdapter,(USHORT *)buffer);
+	memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+EEPROM_SIZE, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_E2PROM_WRITE_ALL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_IO_READ(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+	memcpy(pRaCfg->data, &value, 4);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+4, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_IO_WRITE(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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 the offset out.
+	*/
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_IO_READ_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	UINT32	offset;
+	USHORT	len;
+
+	memcpy(&offset, &pRaCfg->status, 4);
+	offset = ntohl(offset);
+
+	/*
+		We do not need the base address.
+		So just extract the offset out.
+	*/
+	offset &= 0x0000FFFF;
+	memcpy(&len, pRaCfg->data+2, 2);
+	len = ntohs(len);
+
+	if (len > 371)
+	{
+		ATEDBGPRINT(RT_DEBUG_TRACE,("length requested is too large, make it smaller\n"));
+		pRaCfg->length = htons(2);
+		pRaCfg->status = htons(1);
+		return -EFAULT;
+	}
+
+	RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+(len*4), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_BBP_READ8(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+	}
+
+	pRaCfg->data[0] = value;
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+1, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_BBP_WRITE8(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+	}
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_BBP_READ_ALL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	USHORT bbp_reg_index;
+
+	for (bbp_reg_index = 0; bbp_reg_index < MAX_BBP_ID+1; bbp_reg_index++)
+	{
+		pRaCfg->data[bbp_reg_index] = 0;
+
+		if (ATE_ON(pAdapter))
+		{
+			ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbp_reg_index, &pRaCfg->data[bbp_reg_index]);
+		}
+		else
+		{
+			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbp_reg_index, &pRaCfg->data[bbp_reg_index]);
+		}
+	}
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+MAX_BBP_ID+1, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_GET_NOISE_LEVEL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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));
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+(sizeof(INT32)*3*10), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_GET_COUNTER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+60, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_CLEAR_COUNTER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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;
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_TX_START(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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.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 */
+
+		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]);
+
+		/* always use QID_AC_BE */
+		pAdapter->ate.QID = 0;
+
+		p = (USHORT *)(&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)
+				{
+#ifdef RTMP_MAC_PCI
+					pAdapter->ate.TxCount = 0xFFFFFFFF;
+#endif // RTMP_MAC_PCI //
+				}
+				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, BBP_R24, &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 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)
+	{
+		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+		return NDIS_STATUS_SUCCESS;
+	}
+
+TX_START_ERROR:
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), err);
+
+	return err;
+}
+
+
+static inline INT DO_RACFG_CMD_GET_TX_STATUS(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	UINT32 count=0;
+
+	count = htonl(pAdapter->ate.TxDoneCount);
+	NdisMoveMemory(pRaCfg->data, &count, 4);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+4, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_TX_STOP(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
+
+	Set_ATE_Proc(pAdapter, "TXSTOP");
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_RX_START(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+	pAdapter->ate.bQARxStart = TRUE;
+	Set_ATE_Proc(pAdapter, "RXFRAME");
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_RX_STOP(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
+
+	Set_ATE_Proc(pAdapter, "RXSTOP");
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_START_TX_CARRIER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
+
+	Set_ATE_Proc(pAdapter, "TXCARR");
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_START_TX_CONT(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
+
+	Set_ATE_Proc(pAdapter, "TXCONT");
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_START_TX_FRAME(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
+
+	Set_ATE_Proc(pAdapter, "TXFRAME");
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_BW(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+
+	Set_ATE_TX_BW_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER0(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_TX_POWER0_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_POWER1(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_TX_POWER1_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_FREQ_OFFSET(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_GET_STATISTICS(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+52, NDIS_STATUS_SUCCESS);
+	}
+	else
+	{
+		INT32 RSSI0 = 0;
+
+		RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+		memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+		RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+44, NDIS_STATUS_SUCCESS);
+	}
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_RESET_COUNTER(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 1;
+	STRING    str[LEN_OF_ARG];
+
+	NdisZeroMemory(str, LEN_OF_ARG);
+
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
+
+	sprintf((char *)str, "%d", value);
+	Set_ResetStatCounter_Proc(pAdapter, str);
+
+	pAdapter->ate.TxDoneCount = 0;
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SEL_TX_ANTENNA(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_TX_Antenna_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SEL_RX_ANTENNA(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_RX_Antenna_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_PREAMBLE(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_TX_MODE_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_CHANNEL(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_CHANNEL_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_ADDR1(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_ADDR2(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_ADDR3(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_RATE(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_TX_MCS_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_LEN(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	SHORT    value = 0;
+	STRING    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((char *)str, "%d", value);
+	Set_ATE_TX_LENGTH_Proc(pAdapter, str);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_SET_TX_FRAME_COUNT(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	USHORT    value = 0;
+	STRING    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);
+
+#ifdef RTMP_MAC_PCI
+	/* TX_FRAME_COUNT == 0 means tx infinitely */
+	if (value == 0)
+	{
+		/* Use TxCount = 0xFFFFFFFF to approximate the infinity. */
+		pAdapter->ate.TxCount = 0xFFFFFFFF;
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAdapter->ate.TxCount));
+		ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
+
+
+	}
+	else
+#endif // RTMP_MAC_PCI //
+	{
+		sprintf((char *)str, "%d", value);
+		Set_ATE_TX_COUNT_Proc(pAdapter, str);
+	}
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_START_RX_FRAME(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+	Set_ATE_Proc(pAdapter, "RXFRAME");
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_E2PROM_READ_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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"));
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+len, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_E2PROM_WRITE_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_IO_WRITE_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+		ATEDBGPRINT(RT_DEBUG_TRACE,("Write %x %x\n", offset + i, value));
+		RTMP_IO_WRITE32(pAdapter, ((offset+i) & (0xffff)), value);
+	}
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_BBP_READ_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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]);
+		}
+	}
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status)+len, NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+static inline INT DO_RACFG_CMD_ATE_BBP_WRITE_BULK(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq,
+	IN  struct ate_racfghdr *pRaCfg)
+{
+	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);
+		}
+	}
+
+	RESPONSE_TO_GUI(pRaCfg, wrq, sizeof(pRaCfg->status), NDIS_STATUS_SUCCESS);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+#endif // RALINK_28xx_QA //
+#endif	// RALINK_ATE //
diff --git a/drivers/staging/rt3090/rt_ate.h b/drivers/staging/rt3090/rt_ate.h
new file mode 100644
index 0000000..38d5961
--- /dev/null
+++ b/drivers/staging/rt3090/rt_ate.h
@@ -0,0 +1,314 @@
+/*
+ *************************************************************************
+ * 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__
+
+
+#ifdef LINUX
+#define ate_print printk
+#define ATEDBGPRINT DBGPRINT
+#ifdef RTMP_MAC_PCI
+#define EEPROM_SIZE								0x200
+#ifdef CONFIG_STA_SUPPORT
+#define EEPROM_BIN_FILE_NAME  "/etc/Wireless/RT2860STA/e2p.bin"
+#endif // CONFIG_STA_SUPPORT //
+#endif // RTMP_MAC_PCI //
+#endif // LINUX //
+
+
+#define ATE_ON(_p)              (((_p)->ate.Mode) != ATE_STOP)
+
+#ifdef RTMP_MAC_PCI
+#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)        \
+{                                                       \
+    BBP_CSR_CFG_STRUC  BbpCsr;                             \
+    int             j, k;                               \
+    for (j=0; j<MAX_BUSY_COUNT; j++)                    \
+    {                                                   \
+        RTMP_IO_READ32(_A, BBP_CSR_CFG, &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 = _I;                       \
+        RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word);     \
+        for (k=0; k<MAX_BUSY_COUNT; k++)                \
+        {                                               \
+            RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
+            if (BbpCsr.field.Busy == IDLE)              \
+                break;                                  \
+        }                                               \
+        if ((BbpCsr.field.Busy == IDLE) &&              \
+            (BbpCsr.field.RegNum == _I))                \
+        {                                               \
+            *(_pV) = (UCHAR)BbpCsr.field.Value;         \
+            break;                                      \
+        }                                               \
+    }                                                   \
+    if (BbpCsr.field.Busy == BUSY)                      \
+    {                                                   \
+        ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP read R%d fail\n", _I));      \
+        *(_pV) = (_A)->BbpWriteLatch[_I];               \
+    }                                                   \
+}
+
+#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)        \
+{                                                       \
+    BBP_CSR_CFG_STRUC  BbpCsr;                             \
+    int             BusyCnt;                            \
+    for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)  \
+    {                                                   \
+        RTMP_IO_READ32(_A, BBP_CSR_CFG, &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 = _V;                        \
+        BbpCsr.field.RegNum = _I;                       \
+        RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word);     \
+        (_A)->BbpWriteLatch[_I] = _V;                   \
+        break;                                          \
+    }                                                   \
+    if (BusyCnt == MAX_BUSY_COUNT)                      \
+    {                                                   \
+        ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP write R%d fail\n", _I));     \
+    }                                                   \
+}
+#endif // RTMP_MAC_PCI //
+
+
+#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	PSTRING			arg);
+
+INT	Set_ATE_DA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_SA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_BSSID_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_CHANNEL_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_POWER0_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_POWER1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_RX_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_FREQOFFSET_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_BW_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_LENGTH_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_COUNT_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_MCS_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_MODE_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_TX_GI_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+
+INT	Set_ATE_RX_FER_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ATE_Read_RF_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ATE_Write_RF1_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ATE_Write_RF2_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ATE_Write_RF3_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ATE_Write_RF4_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ATE_Load_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ATE_Read_E2P_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+
+INT	Set_ATE_Show_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ATE_Help_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+#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	PSTRING			arg);
+
+INT Set_RxStop_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+#ifdef DBG
+INT Set_EERead_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_EEWrite_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_BBPRead_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_BBPWrite_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_RFWrite_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+#endif // DBG //
+#endif // RALINK_28xx_QA //
+
+
+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/rt3090/rt_config.h b/drivers/staging/rt3090/rt_config.h
new file mode 100644
index 0000000..005142d
--- /dev/null
+++ b/drivers/staging/rt3090/rt_config.h
@@ -0,0 +1,126 @@
+/*
+ *************************************************************************
+ * 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"
+#include "rtmp_os.h"
+
+#include "rtmp_def.h"
+#include "rtmp_chip.h"
+#include "rtmp_timer.h"
+
+#include "oid.h"
+#include "mlme.h"
+#include "wpa.h"
+#include "crypt_md5.h"
+#include "crypt_sha2.h"
+#include "crypt_hmac.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 //
+
+#include "eeprom.h"
+#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
+#include "rtmp_mcu.h"
+#endif
+
+
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+
+#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 //
+
+#ifdef RALINK_28xx_QA
+#ifndef RALINK_ATE
+#error "For supporting QA GUI, please set HAS_ATE=y and HAS_28xx_QA=y."
+#endif // RALINK_ATE //
+#endif // RALINK_28xx_QA //
+
+
+
+
+#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/rt3090/rt_linux.c b/drivers/staging/rt3090/rt_linux.c
new file mode 100644
index 0000000..d2241ec
--- /dev/null
+++ b/drivers/staging/rt3090/rt_linux.c
@@ -0,0 +1,1623 @@
+/*
+ *************************************************************************
+ * 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;
+
+
+// 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*OS_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*OS_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*OS_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	RTMP_ADAPTER *pAd,
+	OUT	UCHAR **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	PVOID mem)
+{
+
+	ASSERT(mem);
+	kfree(mem);
+	return (NDIS_STATUS_SUCCESS);
+}
+
+
+
+
+PNDIS_PACKET RtmpOSNetPktAlloc(
+	IN RTMP_ADAPTER *pAd,
+	IN int size)
+{
+	struct sk_buff *skb;
+	/* Add 2 more bytes for ip header alignment*/
+	skb = dev_alloc_skb(size+2);
+
+	return ((PNDIS_PACKET)skb);
+}
+
+
+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;
+
+	if (pAd->BeaconBuf)
+		kfree(pAd->BeaconBuf);
+
+
+	NdisFreeSpinLock(&pAd->MgmtRingLock);
+
+#ifdef RTMP_MAC_PCI
+	NdisFreeSpinLock(&pAd->RxRingLock);
+#ifdef RT3090
+NdisFreeSpinLock(&pAd->McuCmdLock);
+#endif // RT3090 //
+#endif // RTMP_MAC_PCI //
+
+	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);
+	if (os_cookie)
+		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 + RTMP_PKT_TAIL_PADDING);
+	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 = (PNDIS_BUFFER)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 = (PNDIS_BUFFER)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;
+	}
+}
+
+
+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_pointer(skb), pHeader802_3, HdrLen);
+		skb_put(skb, HdrLen);
+		NdisMoveMemory(skb_tail_pointer(skb), 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;
+#ifdef INF_AMAZON_PPA
+        int             ret = 0;
+        unsigned int ppa_flags = 0; /* reserved for now */
+#endif // INF_AMAZON_PPA //
+
+	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
+#ifdef INF_AMAZON_SE
+#ifdef BG_FT_SUPPORT
+            BG_FTPH_PacketFromApHandle(pRxPkt);
+            return;
+#endif // BG_FT_SUPPORT //
+#endif // INF_AMAZON_SE //
+	pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
+
+#ifdef INF_AMAZON_PPA
+	if (ppa_hook_directpath_send_fn && pAd->PPAEnable==TRUE )
+	{
+		memset(pRxPkt->head,0,pRxPkt->data-pRxPkt->head-14);
+		DBGPRINT(RT_DEBUG_TRACE, ("ppa_hook_directpath_send_fn rx :ret:%d headroom:%d dev:%s pktlen:%d<===\n",ret,skb_headroom(pRxPkt)
+			,pRxPkt->dev->name,pRxPkt->len));
+		hex_dump("rx packet", pRxPkt->data, 32);
+		ret = ppa_hook_directpath_send_fn(pAd->g_if_id, pRxPkt, pRxPkt->len, ppa_flags);
+		pRxPkt=NULL;
+		return;
+
+	}
+#endif // INF_AMAZON_PPA //
+
+//#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;
+	PSTRING	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;
+
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL, (PUCHAR)pBuf, BufLen);
+		//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((PSTRING) ph->devname, (PSTRING) 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 //
+
+
+
+/*******************************************************************************
+
+	File open/close related functions.
+
+ *******************************************************************************/
+RTMP_OS_FD RtmpOSFileOpen(char *pPath,  int flag, int mode)
+{
+	struct file	*filePtr;
+
+	filePtr = filp_open(pPath, flag, 0);
+	if (IS_ERR(filePtr))
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("%s(): Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(filePtr), pPath));
+	}
+
+	return (RTMP_OS_FD)filePtr;
+}
+
+int RtmpOSFileClose(RTMP_OS_FD osfd)
+{
+	filp_close(osfd, NULL);
+	return 0;
+}
+
+
+void RtmpOSFileSeek(RTMP_OS_FD osfd, int offset)
+{
+	osfd->f_pos = offset;
+}
+
+
+int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen)
+{
+	// The object must have a read method
+	if (osfd->f_op && osfd->f_op->read)
+	{
+		return osfd->f_op->read(osfd,  pDataPtr, readLen, &osfd->f_pos);
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
+		return -1;
+	}
+}
+
+
+int RtmpOSFileWrite(RTMP_OS_FD osfd, char *pDataPtr, int writeLen)
+{
+	return osfd->f_op->write(osfd, pDataPtr, (size_t)writeLen, &osfd->f_pos);
+}
+
+
+void RtmpOSFSInfoChange(RTMP_OS_FS_INFO *pOSFSInfo, BOOLEAN bSet)
+{
+	if (bSet)
+	{
+		// Save uid and gid used for filesystem access.
+		// Set user and group to 0 (root)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+		pOSFSInfo->fsuid= current->fsuid;
+		pOSFSInfo->fsgid = current->fsgid;
+		current->fsuid = current->fsgid = 0;
+#else
+		pOSFSInfo->fsuid = current_fsuid();
+		pOSFSInfo->fsgid = current_fsgid();
+#endif
+		pOSFSInfo->fs = get_fs();
+		set_fs(KERNEL_DS);
+	}
+	else
+	{
+		set_fs(pOSFSInfo->fs);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+		current->fsuid = pOSFSInfo->fsuid;
+		current->fsgid = pOSFSInfo->fsgid;
+#endif
+	}
+}
+
+
+
+/*******************************************************************************
+
+	Task create/management/kill related functions.
+
+ *******************************************************************************/
+NDIS_STATUS RtmpOSTaskKill(
+	IN RTMP_OS_TASK *pTask)
+{
+	RTMP_ADAPTER *pAd;
+	int ret = NDIS_STATUS_FAILURE;
+
+	pAd = (RTMP_ADAPTER *)pTask->priv;
+
+#ifdef KTHREAD_SUPPORT
+	if (pTask->kthread_task)
+	{
+		kthread_stop(pTask->kthread_task);
+		ret = NDIS_STATUS_SUCCESS;
+	}
+#else
+	CHECK_PID_LEGALITY(pTask->taskPID)
+	{
+		printk("Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
+		mb();
+		pTask->task_killed = 1;
+		mb();
+		ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
+		if (ret)
+		{
+			printk(KERN_WARNING "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
+				pTask->taskName, GET_PID_NUMBER(pTask->taskPID), ret);
+		}
+		else
+		{
+			wait_for_completion(&pTask->taskComplete);
+			pTask->taskPID = THREAD_PID_INIT_VALUE;
+			pTask->task_killed = 0;
+			ret = NDIS_STATUS_SUCCESS;
+		}
+	}
+#endif
+
+	return ret;
+
+}
+
+
+INT RtmpOSTaskNotifyToExit(
+	IN RTMP_OS_TASK *pTask)
+{
+
+#ifndef KTHREAD_SUPPORT
+	complete_and_exit(&pTask->taskComplete, 0);
+#endif
+
+	return 0;
+}
+
+
+void RtmpOSTaskCustomize(
+	IN RTMP_OS_TASK *pTask)
+{
+
+#ifndef KTHREAD_SUPPORT
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	daemonize((PSTRING)&pTask->taskName[0]/*"%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, &pTask->taskName[0]);
+
+	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(&pTask->taskComplete);
+
+#endif
+}
+
+
+NDIS_STATUS RtmpOSTaskAttach(
+	IN RTMP_OS_TASK *pTask,
+	IN int (*fn)(void *),
+	IN void *arg)
+{
+	NDIS_STATUS status = NDIS_STATUS_SUCCESS;
+	pid_t pid_number = -1;
+
+#ifdef KTHREAD_SUPPORT
+	pTask->task_killed = 0;
+	pTask->kthread_task = NULL;
+	pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
+	if (IS_ERR(pTask->kthread_task))
+		status = NDIS_STATUS_FAILURE;
+#else
+	pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
+	if (pid_number < 0)
+	{
+		DBGPRINT (RT_DEBUG_ERROR, ("Attach task(%s) failed!\n", pTask->taskName));
+		status = NDIS_STATUS_FAILURE;
+	}
+	else
+	{
+		pTask->taskPID = GET_PID(pid_number);
+
+		// Wait for the thread to start
+		wait_for_completion(&pTask->taskComplete);
+		status = NDIS_STATUS_SUCCESS;
+	}
+#endif
+	return status;
+}
+
+
+NDIS_STATUS RtmpOSTaskInit(
+	IN RTMP_OS_TASK *pTask,
+	IN PSTRING		pTaskName,
+	IN VOID			*pPriv)
+{
+	int len;
+
+	ASSERT(pTask);
+
+#ifndef KTHREAD_SUPPORT
+	NdisZeroMemory((PUCHAR)(pTask), sizeof(RTMP_OS_TASK));
+#endif
+
+	len = strlen(pTaskName);
+	len = len > (RTMP_OS_TASK_NAME_LEN -1) ? (RTMP_OS_TASK_NAME_LEN-1) : len;
+	NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
+	pTask->priv = pPriv;
+
+#ifndef KTHREAD_SUPPORT
+	RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
+	pTask->taskPID = THREAD_PID_INIT_VALUE;
+
+	init_completion (&pTask->taskComplete);
+#endif
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+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);
+		}
+	}
+}
+
+
+#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->priv = (void *) (((long)(dev + 1) + 31) & ~31);
+
+    setup(dev);
+    strcpy(dev->name, mask);
+
+    return dev;
+}
+#endif // LINUX_VERSION_CODE //
+
+
+int RtmpOSWrielessEventSend(
+	IN RTMP_ADAPTER *pAd,
+	IN UINT32		eventType,
+	IN INT			flags,
+	IN PUCHAR		pSrcMac,
+	IN PUCHAR		pData,
+	IN UINT32		dataLen)
+{
+	union iwreq_data    wrqu;
+
+       memset(&wrqu, 0, sizeof(wrqu));
+
+	if (flags>-1)
+	       wrqu.data.flags = flags;
+
+	if (pSrcMac)
+		memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
+
+	if ((pData!= NULL) && (dataLen > 0))
+		wrqu.data.length = dataLen;
+
+       wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
+	return 0;
+}
+
+
+int RtmpOSNetDevAddrSet(
+	IN PNET_DEV pNetDev,
+	IN PUCHAR	pMacAddr)
+{
+	struct net_device *net_dev;
+	RTMP_ADAPTER *pAd;
+
+	net_dev = pNetDev;
+	//pAd = (RTMP_ADAPTER *)net_dev->priv;
+	pAd=RTMP_OS_NETDEV_GET_PRIV(pNetDev);
+
+#ifdef CONFIG_STA_SUPPORT
+	// work-around for the SuSE due to it has it's own interface name management system.
+	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 //
+
+	NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
+
+	return 0;
+}
+
+
+
+/*
+  *	Assign the network dev name for created Ralink WiFi interface.
+  */
+static int RtmpOSNetDevRequestName(
+	IN RTMP_ADAPTER *pAd,
+	IN PNET_DEV dev,
+	IN PSTRING pPrefixStr,
+	IN INT	devIdx)
+{
+	PNET_DEV		existNetDev;
+	STRING		suffixName[IFNAMSIZ];
+	STRING		desiredName[IFNAMSIZ];
+	int	ifNameIdx, prefixLen, slotNameLen;
+	int Status;
+
+
+	prefixLen = strlen(pPrefixStr);
+	ASSERT((prefixLen < IFNAMSIZ));
+
+	for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++)
+	{
+		memset(suffixName, 0, IFNAMSIZ);
+		memset(desiredName, 0, IFNAMSIZ);
+		strncpy(&desiredName[0], pPrefixStr, prefixLen);
+
+#ifdef MULTIPLE_CARD_SUPPORT
+		if (pAd->MC_RowID >= 0)
+			sprintf(suffixName, "%02d_%d", pAd->MC_RowID, ifNameIdx);
+		else
+#endif // MULTIPLE_CARD_SUPPORT //
+		sprintf(suffixName, "%d", ifNameIdx);
+
+		slotNameLen = strlen(suffixName);
+		ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
+		strcat(desiredName, suffixName);
+
+		existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
+		if (existNetDev == NULL)
+			break;
+		else
+			RtmpOSNetDeviceRefPut(existNetDev);
+	}
+
+	if(ifNameIdx < 32)
+	{
+		strcpy(&dev->name[0], &desiredName[0]);
+		Status = NDIS_STATUS_SUCCESS;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_ERROR,
+					("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr));
+		Status = NDIS_STATUS_FAILURE;
+	}
+
+	return Status;
+}
+
+
+void RtmpOSNetDevClose(
+	IN PNET_DEV pNetDev)
+{
+	dev_close(pNetDev);
+}
+
+
+void RtmpOSNetDevFree(PNET_DEV pNetDev)
+{
+	ASSERT(pNetDev);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	free_netdev(pNetDev);
+#else
+	kfree(pNetDev);
+#endif
+}
+
+
+INT RtmpOSNetDevAlloc(
+	IN PNET_DEV *new_dev_p,
+	IN UINT32	privDataSize)
+{
+	// assign it as null first.
+	*new_dev_p = NULL;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("Allocate a net device with private data size=%d!\n", privDataSize));
+#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
+	*new_dev_p = alloc_netdev(privDataSize, "eth%d", ether_setup);
+#else
+	*new_dev_p = alloc_etherdev(privDataSize);
+#endif // LINUX_VERSION_CODE //
+
+	if (*new_dev_p)
+		return NDIS_STATUS_SUCCESS;
+	else
+		return NDIS_STATUS_FAILURE;
+}
+
+
+PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, PSTRING pDevName)
+{
+	PNET_DEV	pTargetNetDev = NULL;
+
+
+#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)
+	pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
+#else
+	ASSERT(pNetDev);
+	pTargetNetDev = dev_get_by_name(pNetDev->nd_net, pDevName);
+#endif
+#else
+	pTargetNetDev = dev_get_by_name(pDevName);
+#endif // KERNEL_VERSION(2,6,24) //
+
+#else
+	int	devNameLen;
+
+	devNameLen = strlen(pDevName);
+	ASSERT((devNameLen <= IFNAMSIZ));
+
+	for(pTargetNetDev=dev_base; pTargetNetDev!=NULL; pTargetNetDev=pTargetNetDev->next)
+	{
+		if (strncmp(pTargetNetDev->name, pDevName, devNameLen) == 0)
+			break;
+	}
+#endif // KERNEL_VERSION(2,5,0) //
+
+	return pTargetNetDev;
+}
+
+
+void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	/*
+		every time dev_get_by_name is called, and it has returned a valid struct
+		net_device*, dev_put should be called afterwards, because otherwise the
+		machine hangs when the device is unregistered (since dev->refcnt > 1).
+	*/
+	if(pNetDev)
+		dev_put(pNetDev);
+#endif // LINUX_VERSION_CODE //
+}
+
+
+INT RtmpOSNetDevDestory(
+	IN RTMP_ADAPTER *pAd,
+	IN PNET_DEV		pNetDev)
+{
+
+	// TODO: Need to fix this
+	printk("WARNING: This function(%s) not implement yet!!!\n", __FUNCTION__);
+	return 0;
+}
+
+
+void RtmpOSNetDevDetach(PNET_DEV pNetDev)
+{
+	unregister_netdev(pNetDev);
+}
+
+
+int RtmpOSNetDevAttach(
+	IN PNET_DEV pNetDev,
+	IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook)
+{
+	int ret, rtnl_locked = FALSE;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
+	// If we need hook some callback function to the net device structrue, now do it.
+	if (pDevOpHook)
+	{
+		PRTMP_ADAPTER pAd = RTMP_OS_NETDEV_GET_PRIV(pNetDev);
+
+		pNetDev->netdev_ops = pDevOpHook->netdev_ops;
+
+		/* OS specific flags, here we used to indicate if we are virtual interface */
+		pNetDev->priv_flags = pDevOpHook->priv_flags;
+
+#if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12)
+		pNetDev->get_wireless_stats = rt28xx_get_wireless_stats;
+#endif
+
+#ifdef CONFIG_STA_SUPPORT
+#if WIRELESS_EXT >= 12
+		if (pAd->OpMode == OPMODE_STA)
+		{
+			pNetDev->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)
+		{
+			pNetDev->wireless_handlers = &rt28xx_ap_iw_handler_def;
+		}
+#endif //WIRELESS_EXT >= 12
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+		// copy the net device mac address to the net_device structure.
+		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN);
+
+		rtnl_locked = pDevOpHook->needProtcted;
+	}
+
+	if (rtnl_locked)
+		ret = register_netdevice(pNetDev);
+	else
+		ret = register_netdev(pNetDev);
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
+	if (ret == 0)
+		return NDIS_STATUS_SUCCESS;
+	else
+		return NDIS_STATUS_FAILURE;
+}
+
+
+PNET_DEV RtmpOSNetDevCreate(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			devType,
+	IN INT			devNum,
+	IN INT			privMemSize,
+	IN PSTRING		pNamePrefix)
+{
+	struct net_device *pNetDev = NULL;
+	int status;
+
+
+	/* allocate a new network device */
+	status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize*/);
+	if (status != NDIS_STATUS_SUCCESS)
+	{
+		/* allocation fail, exit */
+		DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (%s)...\n", pNamePrefix));
+		return NULL;
+	}
+
+
+	/* find a available interface name, max 32 interfaces */
+	status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
+	if (status != NDIS_STATUS_SUCCESS)
+	{
+		/* error! no any available ra name can be used! */
+		DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix));
+		RtmpOSNetDevFree(pNetDev);
+
+		return NULL;
+	}
+	else
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("The name of the new %s interface is %s...\n", pNamePrefix, pNetDev->name));
+	}
+
+	return pNetDev;
+}
diff --git a/drivers/staging/rt3090/rt_linux.h b/drivers/staging/rt3090/rt_linux.h
new file mode 100644
index 0000000..a970e78
--- /dev/null
+++ b/drivers/staging/rt3090/rt_linux.h
@@ -0,0 +1,1034 @@
+/*
+ *************************************************************************
+ * 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_linux.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+*/
+
+#ifndef __RT_LINUX_H__
+#define __RT_LINUX_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>
+
+#ifdef INF_AMAZON_PPA
+#include <asm/amazon_se/ifx_ppa_interface.h>
+#include <asm/amazon_se/ifx_ppa_hook.h>
+#endif // INF_AMAZON_PPA //
+
+// load firmware
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/unaligned.h>	// for get_unaligned()
+
+#ifdef KTHREAD_SUPPORT
+#include <linux/err.h>
+#include <linux/kthread.h>
+#endif // KTHREAD_SUPPORT //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef KTHREAD_SUPPORT
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)
+#error "This kerne version doesn't support kthread!!"
+#endif
+#endif // KTHREAD_SUPPORT //
+
+/***********************************************************************************
+ *	Profile related sections
+ ***********************************************************************************/
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef RTMP_MAC_PCI
+#define STA_PROFILE_PATH			"/etc/Wireless/RT2860STA/RT2860STA.dat"
+#define STA_DRIVER_VERSION			"2.1.0.0"
+#ifdef MULTIPLE_CARD_SUPPORT
+#define CARD_INFO_PATH			"/etc/Wireless/RT2860STA/RT2860STACard.dat"
+#endif // MULTIPLE_CARD_SUPPORT //
+#endif // RTMP_MAC_PCI //
+
+
+
+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 //
+
+/***********************************************************************************
+ *	Compiler related definitions
+ ***********************************************************************************/
+#undef __inline
+#define __inline		static inline
+#define IN
+#define OUT
+#define INOUT
+#define NDIS_STATUS		INT
+
+
+/***********************************************************************************
+ *	OS Specific definitions and data structures
+ ***********************************************************************************/
+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 void				* NDIS_HANDLE;
+typedef char				* PNDIS_BUFFER;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+typedef	struct pid *	RTMP_OS_PID;
+#else
+typedef pid_t				RTMP_OS_PID;
+#endif
+
+typedef struct semaphore	RTMP_OS_SEM;
+
+#ifdef RTMP_MAC_PCI
+#ifndef PCI_DEVICE
+#define PCI_DEVICE(vend,dev) \
+	.vendor = (vend), .device = (dev), \
+	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
+#endif // PCI_DEVICE //
+#endif // RTMP_MAC_PCI //
+
+#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 RTMP_INC_REF(_A)		0
+#define RTMP_DEC_REF(_A)		0
+#define RTMP_GET_REF(_A)		0
+
+
+#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
+
+
+/***********************************************************************************
+ *	Network related constant definitions
+ ***********************************************************************************/
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+#define ETH_LENGTH_OF_ADDRESS	6
+
+#define NDIS_STATUS_SUCCESS                     0x00
+#define NDIS_STATUS_FAILURE                     0x01
+#define NDIS_STATUS_INVALID_DATA				0x02
+#define NDIS_STATUS_RESOURCES                   0x03
+
+#define NDIS_SET_PACKET_STATUS(_p, _status)			do{} while(0)
+#define NdisWriteErrorLogEntry(_a, _b, _c, _d)		do{} while(0)
+
+/* 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)
+
+
+/***********************************************************************************
+ *	Ralink Specific network related constant definitions
+ ***********************************************************************************/
+#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 //
+#define NET_DEVICE_REAL_IDX_MASK		0x0f		// for each operation mode, we maximum support 15 entities.
+
+
+#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
+#define NDIS_PACKET_TYPE_PROMISCUOUS	4
+#endif // CONFIG_STA_SUPPORT //
+
+
+/***********************************************************************************
+ *	OS signaling related constant definitions
+ ***********************************************************************************/
+
+
+/***********************************************************************************
+ *	OS file operation related data structure definitions
+ ***********************************************************************************/
+typedef struct file* RTMP_OS_FD;
+
+typedef struct _RTMP_OS_FS_INFO_
+{
+	int				fsuid;
+	int				fsgid;
+	mm_segment_t	fs;
+}RTMP_OS_FS_INFO;
+
+#define IS_FILE_OPEN_ERR(_fd)	IS_ERR((_fd))
+
+
+/***********************************************************************************
+ *	OS semaphore related data structure and definitions
+ ***********************************************************************************/
+struct os_lock  {
+	spinlock_t		lock;
+	unsigned long	flags;
+};
+
+typedef spinlock_t			NDIS_SPIN_LOCK;
+
+//
+//  spin_lock enhanced for Nested spin lock
+//
+#define NdisAllocateSpinLock(__lock)      \
+{                                       \
+    spin_lock_init((spinlock_t *)(__lock));               \
+}
+
+#define NdisFreeSpinLock(lock)          \
+	do{}while(0)
+
+
+#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));	\
+}
+
+#define NdisAcquireSpinLock		RTMP_SEM_LOCK
+#define NdisReleaseSpinLock		RTMP_SEM_UNLOCK
+
+#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 RTMP_SEM_EVENT_INIT_LOCKED(_pSema)	sema_init((_pSema), 0)
+#define RTMP_SEM_EVENT_INIT(_pSema)			sema_init((_pSema), 1)
+#define RTMP_SEM_EVENT_WAIT(_pSema, _status)	((_status) = down_interruptible((_pSema)))
+#define RTMP_SEM_EVENT_UP(_pSema)			up(_pSema)
+
+#ifdef KTHREAD_SUPPORT
+#define RTMP_WAIT_EVENT_INTERRUPTIBLE(_pAd, _pTask) \
+{ \
+		wait_event_interruptible(_pTask->kthread_q, \
+								 _pTask->kthread_running || kthread_should_stop()); \
+		_pTask->kthread_running = FALSE; \
+		if (kthread_should_stop()) \
+		{ \
+			RTMP_SET_FLAG(_pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); \
+			break; \
+		} \
+}
+#endif
+
+#ifdef KTHREAD_SUPPORT
+#define WAKE_UP(_pTask) \
+	do{ \
+		if ((_pTask)->kthread_task) \
+        { \
+			(_pTask)->kthread_running = TRUE; \
+	        wake_up(&(_pTask)->kthread_q); \
+		} \
+	}while(0)
+#endif
+
+/***********************************************************************************
+ *	OS Memory Access related data structure and definitions
+ ***********************************************************************************/
+#define MEM_ALLOC_FLAG      (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC)
+
+#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
+#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length)
+#define NdisZeroMemory(Destination, Length)         memset(Destination, 0, Length)
+#define NdisFillMemory(Destination, Length, Fill)   memset(Destination, Fill, Length)
+#define NdisCmpMemory(Destination, Source, Length)  memcmp(Destination, Source, Length)
+#define NdisEqualMemory(Source1, Source2, Length)   (!memcmp(Source1, Source2, Length))
+#define RTMPEqualMemory(Source1, Source2, Length)	(!memcmp(Source1, Source2, Length))
+
+#define MlmeAllocateMemory(_pAd, _ppVA)		os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
+#define MlmeFreeMemory(_pAd, _pVA)			os_free_mem(_pAd, _pVA)
+
+#define COPY_MAC_ADDR(Addr1, Addr2)             memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
+
+
+/***********************************************************************************
+ *	OS task related data structure and definitions
+ ***********************************************************************************/
+#define RTMP_OS_MGMT_TASK_FLAGS	CLONE_VM
+
+#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
+
+typedef struct tasklet_struct  RTMP_NET_TASK_STRUCT;
+typedef struct tasklet_struct  *PRTMP_NET_TASK_STRUCT;
+
+
+/***********************************************************************************
+ * Timer related definitions and data structures.
+ **********************************************************************************/
+#define OS_HZ			HZ
+
+typedef struct timer_list	NDIS_MINIPORT_TIMER;
+typedef struct timer_list	RTMP_OS_TIMER;
+typedef void (*TIMER_FUNCTION)(unsigned long);
+
+
+#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); }
+
+#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 typecheck(type,x) \
+({      type __dummy; \
+        typeof(x) __dummy2; \
+        (void)(&__dummy == &__dummy2); \
+        1; \
+})
+#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)
+#define RTMP_TIME_AFTER(a,b) time_after(a, b)
+#endif
+
+#define ONE_TICK 1
+
+static inline void NdisGetSystemUpTime(ULONG *time)
+{
+	*time = jiffies;
+}
+
+
+/***********************************************************************************
+ *	OS specific cookie data structure binding to RTMP_ADAPTER
+ ***********************************************************************************/
+
+struct os_cookie {
+#ifdef RTMP_MAC_PCI
+	struct pci_dev			*pci_dev;
+	struct pci_dev			*parent_pci_dev;
+	USHORT                  DeviceID;
+	dma_addr_t				pAd_pa;
+#endif // RTMP_MAC_PCI //
+
+
+	RTMP_NET_TASK_STRUCT rx_done_task;
+	RTMP_NET_TASK_STRUCT mgmt_dma_done_task;
+	RTMP_NET_TASK_STRUCT ac0_dma_done_task;
+	RTMP_NET_TASK_STRUCT ac1_dma_done_task;
+	RTMP_NET_TASK_STRUCT ac2_dma_done_task;
+	RTMP_NET_TASK_STRUCT ac3_dma_done_task;
+	/*RTMP_NET_TASK_STRUCT hcca_dma_done_task;*/
+	RTMP_NET_TASK_STRUCT tbtt_task;
+#ifdef RTMP_MAC_PCI
+	RTMP_NET_TASK_STRUCT fifo_statistic_full_task;
+#endif // RTMP_MAC_PCI //
+
+
+
+	unsigned long			apd_pid; //802.1x daemon pid
+	INT						ioctl_if_type;
+	INT					ioctl_if;
+};
+
+typedef struct os_cookie	* POS_COOKIE;
+
+
+
+/***********************************************************************************
+ *	OS debugging and printing related definitions and data structure
+ ***********************************************************************************/
+#define PRINT_MAC(addr)	\
+	addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
+
+#ifdef DBG
+extern ULONG		RTDebugLevel;
+
+#define DBGPRINT_RAW(Level, Fmt)    \
+do{                                   \
+    if (Level <= RTDebugLevel)      \
+    {                               \
+        printk Fmt;               \
+    }                               \
+}while(0)
+
+#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
+
+#undef  ASSERT
+#define ASSERT(x)                                                               \
+{                                                                               \
+    if (!(x))                                                                   \
+    {                                                                           \
+        printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__);    \
+    }                                                                           \
+}
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
+
+
+/*********************************************************************************************************
+	The following code are not revised, temporary put it here.
+  *********************************************************************************************************/
+
+
+/***********************************************************************************
+ * Device DMA Access related definitions and data structures.
+ **********************************************************************************/
+#ifdef RTMP_MAC_PCI
+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);
+
+#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
+	linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
+
+#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \
+	linux_pci_unmap_single(_handle, _ptr, _size, _dir)
+
+#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \
+	pci_alloc_consistent(_pci_dev, _size, _ptr)
+
+#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \
+	pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr)
+
+#define DEV_ALLOC_SKB(_length) \
+	dev_alloc_skb(_length)
+#endif // RTMP_MAC_PCI //
+
+
+
+/*
+ * 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)
+
+#define NdisMIndicateStatus(_w, _x, _y, _z)
+
+
+
+/***********************************************************************************
+ * Device Register I/O Access related definitions and data structures.
+ **********************************************************************************/
+#ifdef RTMP_MAC_PCI
+#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)									\
+{																	\
+    if ((_A)->bPCIclkOff == FALSE)                                      \
+    {                                                                   \
+	(*_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)));		\
+	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));			\
+}
+
+#define RTMP_IO_WRITE32(_A, _R, _V)									\
+{																	\
+    if ((_A)->bPCIclkOff == FALSE)                                      \
+    {                                                                   \
+	UINT32	_Val;													\
+	_Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
+	_Val = SWAP32(_V);												\
+	writel(_Val, (void *)((_A)->CSRBaseAddress + (_R)));			\
+    }                                                                   \
+}
+
+#define RTMP_IO_WRITE8(_A, _R, _V)									\
+{																	\
+	UINT	Val;													\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
+	writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R)));			\
+}
+
+#define RTMP_IO_WRITE16(_A, _R, _V)									\
+{																	\
+	UINT	Val;													\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));		\
+	writew(SWAP16((_V)), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
+}
+#else
+//Patch for ASIC turst read/write bug, needs to remove after metel fix
+#define RTMP_IO_READ32(_A, _R, _pV)								\
+{																\
+    if ((_A)->bPCIclkOff == FALSE)                                  \
+    {                                                               \
+		(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
+		(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
+    }                                                               \
+    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)));			\
+	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));				\
+}
+
+#define RTMP_IO_WRITE32(_A, _R, _V)												\
+{																				\
+    if ((_A)->bPCIclkOff == FALSE)                                  \
+    {                                                               \
+	UINT	Val;																\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
+	writel((_V), (void *)((_A)->CSRBaseAddress + (_R)));								\
+    }                                                               \
+}
+
+#define RTMP_IO_FORCE_WRITE32(_A, _R, _V)												\
+{																				\
+	UINT	Val;																\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
+	writel(_V, (void *)((_A)->CSRBaseAddress + (_R)));								\
+}
+
+
+
+#if defined(BRCM_6358) || defined(RALINK_2880) || defined(RALINK_3052)
+#define RTMP_IO_WRITE8(_A, _R, _V)            \
+{                    \
+	ULONG Val;                \
+	UCHAR _i;                \
+	_i = ((_R) & 0x3);             \
+	Val = readl((void *)((_A)->CSRBaseAddress + ((_R) - _i)));   \
+	Val = Val & (~(0x000000ff << ((_i)*8)));         \
+	Val = Val | ((ULONG)(_V) << ((_i)*8));         \
+	writel((Val), (void *)((_A)->CSRBaseAddress + ((_R) - _i)));    \
+}
+#else
+#define RTMP_IO_WRITE8(_A, _R, _V)							\
+{															\
+	UINT	Val;												\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));	\
+	writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R)));		\
+}
+#endif // #if defined(BRCM_6358) || defined(RALINK_2880) //
+
+#define RTMP_IO_WRITE16(_A, _R, _V)							\
+{															\
+	UINT	Val;											\
+	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));	\
+	writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R)));	\
+}
+#endif // #if defined(INF_TWINPASS) || defined(INF_DANUBE) || defined(IKANOS_VX_1X0) //
+#endif // RTMP_MAC_PCI //
+
+
+
+/***********************************************************************************
+ *	Network Related data structure and marco definitions
+ ***********************************************************************************/
+#define PKTSRC_NDIS             0x7f
+#define PKTSRC_DRIVER           0x0f
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
+#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv)	((_pNetDev)->priv = (_pPriv))
+#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev)		((_pNetDev)->priv)
+#else
+#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv)	((_pNetDev)->ml_priv = (_pPriv))
+#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev)		((_pNetDev)->ml_priv)
+#endif
+#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev)	((_pNetDev)->name)
+#define RTMP_OS_NETDEV_GET_PHYADDR(_PNETDEV)	((_PNETDEV)->dev_addr)
+
+#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev)	netif_start_queue((_pNetDev))
+#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev)	netif_stop_queue((_pNetDev))
+#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev)	netif_wake_queue((_pNetDev))
+#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev)	netif_carrier_off((_pNetDev))
+
+#define QUEUE_ENTRY_TO_PACKET(pEntry) \
+	(PNDIS_PACKET)(pEntry)
+
+#define PACKET_TO_QUEUE_ENTRY(pPacket) \
+	(PQUEUE_ENTRY)(pPacket)
+
+#ifdef CONFIG_5VT_ENHANCE
+#define BRIDGE_TAG 0x35564252    // depends on 5VT define in br_input.c
+#endif
+
+#define GET_SG_LIST_FROM_PACKET(_p, _sc)	\
+    rt_get_sg_list_from_packet(_p, _sc)
+
+#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status)                    \
+{                                                                       \
+        RTMPFreeNdisPacket(_pAd, _pPacket);                             \
+}
+
+/*
+ * 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 SET_OS_PKT_DATAPTR(_pkt, _dataPtr)	\
+		(RTPKT_TO_OSPKT(_pkt)->data) = (_dataPtr)
+
+#define GET_OS_PKT_LEN(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->len)
+#define SET_OS_PKT_LEN(_pkt, _len)	\
+		(RTPKT_TO_OSPKT(_pkt)->len) = (_len)
+
+#define GET_OS_PKT_DATATAIL(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->tail)
+#define SET_OS_PKT_DATATAIL(_pkt, _start, _len)	\
+		((RTPKT_TO_OSPKT(_pkt))->tail) = (PUCHAR)((_start) + (_len))
+
+#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 SET_OS_PKT_NETDEV(_pkt, _pNetDev)	\
+		(RTPKT_TO_OSPKT(_pkt)->dev) = (_pNetDev)
+
+#define GET_OS_PKT_TYPE(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt))
+
+#define GET_OS_PKT_NEXT(_pkt) \
+		(RTPKT_TO_OSPKT(_pkt)->next)
+
+
+#define OS_PKT_CLONED(_pkt)		skb_cloned(RTPKT_TO_OSPKT(_pkt))
+
+#define OS_NTOHS(_Val) \
+		(ntohs(_Val))
+#define OS_HTONS(_Val) \
+		(htons(_Val))
+#define OS_NTOHL(_Val) \
+		(ntohl(_Val))
+#define OS_HTONL(_Val) \
+		(htonl(_Val))
+
+#define CB_OFF  10
+
+// 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])
+
+
+
+
+
+//
+//	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])
+
+
+
+/* use bit3 of cb[CB_OFF+16] */
+
+#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
+/* [CB_OFF+28], 1B, 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+28] = _morebit)
+#define RTMP_GET_PACKET_NOBULKOUT(_p)					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+28])
+#endif // INF_AMAZON_SE //
+/* Max skb->cb = 48B = [CB_OFF+38] */
+
+
+
+/***********************************************************************************
+ *	Other function prototypes definitions
+ ***********************************************************************************/
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
+int rt28xx_packet_xmit(struct sk_buff *skb);
+
+
+void FlashWrite(UCHAR * p, ULONG a, ULONG b);
+void FlashRead(UCHAR * p, ULONG a, ULONG b);
+
+#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 //
+
+
+#ifdef RTMP_MAC_PCI
+/* 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
+
+#endif // RTMP_MAC_PCI //
+
+INT rt28xx_ioctl(
+	IN	PNET_DEV		net_dev,
+	IN	OUT	struct ifreq	*rq,
+	IN	INT			cmd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+INT rt28xx_sta_ioctl(
+	IN	PNET_DEV		net_dev,
+	IN	OUT	struct ifreq	*rq,
+	IN	INT			cmd);
+#endif // CONFIG_STA_SUPPORT //
+
+extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char *buf);
+extern int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf);
+
+#endif // __RT_LINUX_H__ //
diff --git a/drivers/staging/rt3090/rt_main_dev.c b/drivers/staging/rt3090/rt_main_dev.c
new file mode 100644
index 0000000..3307a5f
--- /dev/null
+++ b/drivers/staging/rt3090/rt_main_dev.c
@@ -0,0 +1,897 @@
+/*
+ *************************************************************************
+ * 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
+    --------    ----------      ----------------------------------------------
+*/
+
+#include "rt_config.h"
+
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+UINT32 CW_MAX_IN_BITS;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+/*---------------------------------------------------------------------*/
+/* Private Variables Used                                              */
+/*---------------------------------------------------------------------*/
+
+PSTRING mac = "";		   // default 00:00:00:00:00:00
+PSTRING 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                                        */
+/*---------------------------------------------------------------------*/
+
+// public function prototype
+int rt28xx_close(IN struct net_device *net_dev);
+int rt28xx_open(struct net_device *net_dev);
+
+// private function prototype
+static INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
+
+
+static 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 = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+
+	// Sanity check for pAd
+	if (pAd == NULL)
+		return 0; // close ok
+
+	netif_carrier_off(pAd->net_dev);
+	netif_stop_queue(pAd->net_dev);
+
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		BOOLEAN			Cancelled;
+#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;
+				}
+			}
+			RTMP_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);
+
+			if (MsgElem)
+			{
+			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);
+		}
+
+		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
+		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+		// send wireless event to wpa_supplicant for infroming interface down.
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_INTERFACE_DOWN, NULL, NULL, 0);
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	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 = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+
+	// 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 = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+	BOOLEAN			Cancelled;
+	UINT32			i = 0;
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
+
+	Cancelled = FALSE;
+	// 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)
+	{
+#ifdef RTMP_MAC_PCI
+		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
+#endif // RTMP_MAC_PCI //
+
+		// 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);
+        }
+
+
+		MlmeRadioOff(pAd);
+#ifdef RTMP_MAC_PCI
+		pAd->bPCIclkOff = FALSE;
+#endif // RTMP_MAC_PCI //
+	}
+#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)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i));
+			RTMPusecDelay(1000);
+		}
+	}
+
+
+
+	// Stop Mlme state machine
+	MlmeHalt(pAd);
+
+	// Close net tasklets
+	RtmpNetTaskExit(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		MacTableReset(pAd);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+
+	MeasureReqTabExit(pAd);
+	TpcReqTabExit(pAd);
+
+
+	// Close kernel threads
+	RtmpMgmtTaskExit(pAd);
+
+#ifdef RTMP_MAC_PCI
+	{
+			BOOLEAN brc;
+			//	ULONG			Value;
+
+			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
+			{
+				RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+			}
+
+			// Receive packets to clear DMA index after disable interrupt.
+			//RTMPHandleRxDoneInterrupt(pAd);
+			// put to radio off to save power when driver unload.  After radiooff, can't write /read register.  So need to finish all
+			// register access before Radio off.
+
+
+			brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
+
+//In  solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff
+			pAd->bPCIclkOff = FALSE;
+
+			if (brc==FALSE)
+			{
+				DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __FUNCTION__));
+			}
+	}
+
+
+/*
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
+	{
+		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
+	}
+
+	// Disable Rx, register value supposed will remain after reset
+	NICIssueReset(pAd);
+*/
+#endif // RTMP_MAC_PCI //
+
+	// Free IRQ
+	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+	{
+#ifdef RTMP_MAC_PCI
+		// Deregister interrupt function
+		RTMP_IRQ_RELEASE(net_dev)
+#endif // RTMP_MAC_PCI //
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+	}
+
+	// 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 CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+/*+++Modify by woody to solve the bulk fail+++*/
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
+	return 0; // close ok
+} /* End of rt28xx_close */
+
+
+/*
+========================================================================
+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 = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+	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->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;
+	}
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#if WIRELESS_EXT >= 12
+	if (net_dev->priv_flags == INT_MAIN)
+	{
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+		if (pAd->OpMode == OPMODE_AP)
+			net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+#ifdef CONFIG_STA_SUPPORT
+		if (pAd->OpMode == OPMODE_STA)
+			net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
+#endif // CONFIG_STA_SUPPORT //
+	}
+#endif // WIRELESS_EXT >= 12 //
+
+	// Request interrupt service routine for PCI device
+	// register the interrupt routine with the os
+	RTMP_IRQ_REQUEST(net_dev);
+
+	// Init IRQ parameters stored in pAd
+	RTMP_IRQ_INIT(pAd);
+
+	// Chip & other init
+	if (rt28xx_init(pAd, mac, hostname) == FALSE)
+		goto err;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+	// Enable Interrupt
+	RTMP_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;
+//	UINT8  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
+#ifdef RTMP_MAC_PCI
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+        RTMPInitPCIeLinkCtrlValue(pAd);
+#endif // RTMP_MAC_PCI //
+#endif // CONFIG_STA_SUPPORT //
+
+	return (retval);
+
+err:
+//+++Add by shiang, move from rt28xx_init() to here.
+	RTMP_IRQ_RELEASE(net_dev);
+//---Add by shiang, move from rt28xx_init() to here.
+	return (-1);
+} /* End of rt28xx_open */
+
+static const struct net_device_ops rt3090_netdev_ops = {
+	.ndo_open		= MainVirtualIF_open,
+	.ndo_stop		= MainVirtualIF_close,
+	.ndo_do_ioctl		= rt28xx_ioctl,
+	.ndo_get_stats		= RT28xx_get_ether_stats,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_change_mtu		= eth_change_mtu,
+#ifdef IKANOS_VX_1X0
+	.ndo_start_xmit		= IKANOS_DataFramesTx,
+#else
+	.ndo_start_xmit		= rt28xx_send_packets,
+#endif
+};
+
+PNET_DEV RtmpPhyNetDevInit(
+	IN RTMP_ADAPTER *pAd,
+	IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook)
+{
+	struct net_device	*net_dev = NULL;
+//	NDIS_STATUS		Status;
+
+	net_dev = RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME);
+	if (net_dev == NULL)
+	{
+		printk("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
+		return NULL;
+	}
+
+	NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK));
+	pNetDevHook->netdev_ops = &rt3090_netdev_ops;
+	pNetDevHook->priv_flags = INT_MAIN;
+	pNetDevHook->needProtcted = FALSE;
+
+	RTMP_OS_NETDEV_SET_PRIV(net_dev, pAd);
+	//net_dev->priv = (PVOID)pAd;
+	pAd->net_dev = net_dev;
+
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+	SET_MODULE_OWNER(net_dev);
+#endif
+
+	netif_stop_queue(net_dev);
+
+	return net_dev;
+
+}
+
+
+/*
+========================================================================
+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 = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+	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:
+========================================================================
+*/
+static int rt28xx_send_packets(
+	IN struct sk_buff		*skb_p,
+	IN struct net_device	*net_dev)
+{
+	RTMP_ADAPTER *pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+
+	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);
+}
+
+
+#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 = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+
+
+
+	DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
+
+	pAd->iw_stats.status = 0; // Status - device dependent for now
+
+	// link quality
+#ifdef CONFIG_STA_SUPPORT
+	if (pAd->OpMode == OPMODE_STA)
+	pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
+#endif // CONFIG_STA_SUPPORT //
+
+	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;
+}
+#endif // WIRELESS_EXT //
+
+
+void tbtt_tasklet(unsigned long data)
+{
+//#define MAX_TX_IN_TBTT		(16)
+
+}
+
+INT rt28xx_ioctl(
+	IN	PNET_DEV	net_dev,
+	IN	OUT	struct ifreq	*rq,
+	IN	INT					cmd)
+{
+	RTMP_ADAPTER	*pAd = NULL;
+	INT				ret = 0;
+
+	pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+	if (pAd == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->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:
+
+    ========================================================================
+*/
+static struct net_device_stats *RT28xx_get_ether_stats(
+    IN  struct net_device *net_dev)
+{
+    RTMP_ADAPTER *pAd = NULL;
+
+	if (net_dev)
+		pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+
+	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;
+}
+
+
+BOOLEAN RtmpPhyNetDevExit(
+	IN RTMP_ADAPTER *pAd,
+	IN PNET_DEV net_dev)
+{
+
+
+
+#ifdef INF_AMAZON_PPA
+	if (ppa_hook_directpath_register_dev_fn && pAd->PPAEnable==TRUE)
+	{
+		UINT status;
+		status=ppa_hook_directpath_register_dev_fn(&pAd->g_if_id, pAd->net_dev, NULL, PPA_F_DIRECTPATH_DEREGISTER);
+		printk("unregister PPA:g_if_id=%d status=%d\n",pAd->g_if_id,status);
+	}
+	kfree(pAd->pDirectpathCb);
+#endif // INF_AMAZON_PPA //
+
+	// Unregister network device
+	if (net_dev != NULL)
+	{
+		printk("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n", net_dev->name);
+		RtmpOSNetDevDetach(net_dev);
+	}
+
+	return TRUE;
+
+}
+
+
+/*
+========================================================================
+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)
+{
+
+	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
+
+	if (*ppAd)
+	{
+		NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
+		((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
+		return (NDIS_STATUS_SUCCESS);
+	} else {
+		return (NDIS_STATUS_FAILURE);
+	}
+}
diff --git a/drivers/staging/rt3090/rt_pci_rbus.c b/drivers/staging/rt3090/rt_pci_rbus.c
new file mode 100644
index 0000000..2991319
--- /dev/null
+++ b/drivers/staging/rt3090/rt_pci_rbus.c
@@ -0,0 +1,989 @@
+/*
+ *************************************************************************
+ * 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_pci_rbus.c
+
+    Abstract:
+    Create and register network interface.
+
+    Revision History:
+    Who         When            What
+    --------    ----------      ----------------------------------------------
+*/
+
+#include "rt_config.h"
+#include <linux/pci.h>
+
+
+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
+
+
+static void rx_done_tasklet(unsigned long data);
+static void mgmt_dma_done_tasklet(unsigned long data);
+static void ac0_dma_done_tasklet(unsigned long data);
+static void ac1_dma_done_tasklet(unsigned long data);
+static void ac2_dma_done_tasklet(unsigned long data);
+static void ac3_dma_done_tasklet(unsigned long data);
+/*static void hcca_dma_done_tasklet(unsigned long data);*/
+static void fifo_statistic_full_tasklet(unsigned long data);
+
+
+
+/*---------------------------------------------------------------------*/
+/* Symbol & Macro Definitions                                          */
+/*---------------------------------------------------------------------*/
+#define RT2860_INT_RX_DLY				(1<<0)		// bit 0
+#define RT2860_INT_TX_DLY				(1<<1)		// bit 1
+#define RT2860_INT_RX_DONE				(1<<2)		// bit 2
+#define RT2860_INT_AC0_DMA_DONE			(1<<3)		// bit 3
+#define RT2860_INT_AC1_DMA_DONE			(1<<4)		// bit 4
+#define RT2860_INT_AC2_DMA_DONE			(1<<5)		// bit 5
+#define RT2860_INT_AC3_DMA_DONE			(1<<6)		// bit 6
+#define RT2860_INT_HCCA_DMA_DONE		(1<<7)		// bit 7
+#define RT2860_INT_MGMT_DONE			(1<<8)		// bit 8
+#ifdef TONE_RADAR_DETECT_SUPPORT
+#define RT2860_INT_TONE_RADAR			(1<<20)		// bit 20
+#endif // TONE_RADAR_DETECT_SUPPORT //
+
+#define INT_RX			RT2860_INT_RX_DONE
+
+#define INT_AC0_DLY		(RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)
+#define INT_AC1_DLY		(RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)
+#define INT_AC2_DLY		(RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)
+#define INT_AC3_DLY		(RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)
+#define INT_HCCA_DLY	(RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)
+#define INT_MGMT_DLY	RT2860_INT_MGMT_DONE
+#ifdef TONE_RADAR_DETECT_SUPPORT
+#define INT_TONE_RADAR	(RT2860_INT_TONE_RADAR)
+#endif // TONE_RADAR_DETECT_SUPPORT //
+
+
+/***************************************************************************
+  *
+  *	Interface-depended memory allocation/Free related procedures.
+  *		Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
+  *
+  **************************************************************************/
+// Function for TxDesc Memory allocation.
+void RTMP_AllocateTxDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	UINT	Index,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
+
+}
+
+
+// Function for MgmtDesc Memory allocation.
+void RTMP_AllocateMgmtDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
+
+}
+
+
+// Function for RxDesc Memory allocation.
+void RTMP_AllocateRxDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
+
+}
+
+
+// Function for free allocated Desc Memory.
+void RTMP_FreeDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	PVOID	VirtualAddress,
+	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
+}
+
+
+// Function for TxData DMA Memory allocation.
+void RTMP_AllocateFirstTxBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	UINT	Index,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
+}
+
+
+void RTMP_FreeFirstTxBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	IN	PVOID	VirtualAddress,
+	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
+}
+
+
+/*
+ * FUNCTION: Allocate a common buffer for DMA
+ * ARGUMENTS:
+ *     AdapterHandle:  AdapterHandle
+ *     Length:  Number of bytes to allocate
+ *     Cached:  Whether or not the memory can be cached
+ *     VirtualAddress:  Pointer to memory is returned here
+ *     PhysicalAddress:  Physical address corresponding to virtual address
+ */
+void RTMP_AllocateSharedMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	*VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
+}
+
+
+/*
+ * FUNCTION: Allocate a packet buffer for DMA
+ * ARGUMENTS:
+ *     AdapterHandle:  AdapterHandle
+ *     Length:  Number of bytes to allocate
+ *     Cached:  Whether or not the memory can be cached
+ *     VirtualAddress:  Pointer to memory is returned here
+ *     PhysicalAddress:  Physical address corresponding to virtual address
+ * Notes:
+ *     Cached is ignored: always cached memory
+ */
+PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	OUT	PVOID	*VirtualAddress,
+	OUT	PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
+{
+	struct sk_buff *pkt;
+
+	pkt = dev_alloc_skb(Length);
+
+	if (pkt == NULL) {
+		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
+	}
+
+	if (pkt) {
+		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+		*VirtualAddress = (PVOID) pkt->data;
+//#ifdef CONFIG_5VT_ENHANCE
+//		*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, 1600, PCI_DMA_FROMDEVICE);
+//#else
+		*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length,  -1, PCI_DMA_FROMDEVICE);
+//#endif
+	} else {
+		*VirtualAddress = (PVOID) NULL;
+		*PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
+	}
+
+	return (PNDIS_PACKET) pkt;
+}
+
+
+VOID Invalid_Remaining_Packet(
+	IN	PRTMP_ADAPTER pAd,
+	IN	 ULONG VirtualAddress)
+{
+	NDIS_PHYSICAL_ADDRESS PhysicalAddress;
+
+	PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
+}
+
+
+int RtmpOSIRQRequest(IN struct net_device *net_dev)
+{
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
+	int retval = 0;
+
+	ASSERT(pAd);
+
+	if (pAd->infType != RTMP_DEV_INF_RBUS)
+	{
+		POS_COOKIE _pObj = (POS_COOKIE)(pAd->OS_Cookie);
+		RTMP_MSI_ENABLE(pAd);
+		retval = request_irq(_pObj->pci_dev->irq,  rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev));
+		if (retval != 0)
+			printk("RT2860: request_irq  ERROR(%d)\n", retval);
+	}
+	else
+	{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+		if ((retval = request_irq(net_dev->irq, rt2860_interrupt, IRQF_SHARED, net_dev->name ,net_dev)))
+#else
+		if ((retval = request_irq(net_dev->irq,rt2860_interrupt, SA_INTERRUPT, net_dev->name ,net_dev)))
+#endif
+		{
+			printk("RT2860: request_irq  ERROR(%d)\n", retval);
+		}
+	}
+
+	return retval;
+
+}
+
+
+int RtmpOSIRQRelease(IN struct net_device *net_dev)
+{
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));
+
+	ASSERT(pAd);
+	if (pAd->infType != RTMP_DEV_INF_RBUS)
+	{
+		POS_COOKIE pObj = (POS_COOKIE)(pAd->OS_Cookie);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		synchronize_irq(pObj->pci_dev->irq);
+#endif
+		free_irq(pObj->pci_dev->irq, (net_dev));
+		RTMP_MSI_DISABLE(pAd);
+	}
+	else
+	{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		synchronize_irq(net_dev->irq);
+#endif
+		free_irq(net_dev->irq, (net_dev));
+	}
+
+	return 0;
+}
+
+
+NDIS_STATUS RtmpNetTaskInit(IN RTMP_ADAPTER *pAd)
+{
+	POS_COOKIE pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd);
+	/*tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd);*/
+	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+	tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+void RtmpNetTaskExit(IN RTMP_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);
+	tasklet_kill(&pObj->fifo_statistic_full_task);
+}
+
+
+NDIS_STATUS RtmpMgmtTaskInit(IN RTMP_ADAPTER *pAd)
+{
+
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+========================================================================
+Routine Description:
+    Close kernel threads.
+
+Arguments:
+	*pAd				the raxx interface data pointer
+
+Return Value:
+    NONE
+
+Note:
+========================================================================
+*/
+VOID RtmpMgmtTaskExit(
+	IN RTMP_ADAPTER *pAd)
+{
+
+
+	return;
+}
+
+
+static inline void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
+{
+	u32 regValue;
+
+	pAd->int_disable_mask &= ~(mode);
+	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
+	//if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+	{
+		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 1:enable
+	}
+	//else
+	//	DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n"));
+
+	if (regValue != 0)
+		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
+}
+
+
+static inline void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
+{
+	u32 regValue;
+
+	pAd->int_disable_mask |= mode;
+	regValue =	pAd->int_enable_reg & ~(pAd->int_disable_mask);
+	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);     // 0: disable
+
+	if (regValue == 0)
+	{
+		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
+	}
+}
+
+
+/***************************************************************************
+  *
+  *	tasklet related procedures.
+  *
+  **************************************************************************/
+static void mgmt_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
+    INT_SOURCE_CSR_STRUC	IntSource;
+	POS_COOKIE pObj;
+
+	// 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;
+
+    pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+//	printk("mgmt_dma_done_process\n");
+	IntSource.word = 0;
+	IntSource.field.MgmtDmaDone = 1;
+	pAd->int_pending &= ~INT_MGMT_DLY;
+
+	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
+
+	// if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
+	// bug report output
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if (pAd->int_pending & INT_MGMT_DLY)
+	{
+		tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_MGMT_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+
+static void rx_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
+	BOOLEAN	bReschedule = 0;
+	POS_COOKIE pObj;
+
+	// 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;
+
+#ifdef UAPSD_AP_SUPPORT
+	UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_TASKLET);
+#endif // UAPSD_AP_SUPPORT //
+
+    pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	pAd->int_pending &= ~(INT_RX);
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		bReschedule = STARxDoneInterruptHandle(pAd, 0);
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef UAPSD_AP_SUPPORT
+	UAPSD_TIMING_RECORD_STOP();
+#endif // UAPSD_AP_SUPPORT //
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid rotting packet
+	 */
+	if (pAd->int_pending & INT_RX || bReschedule)
+	{
+		tasklet_hi_schedule(&pObj->rx_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable RxINT again */
+	rt2860_int_enable(pAd, INT_RX);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+
+}
+
+
+void fifo_statistic_full_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
+	POS_COOKIE pObj;
+
+	// 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;
+
+    pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	pAd->int_pending &= ~(FifoStaFullInt);
+	NICUpdateFifoStaCounters(pAd);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid rotting packet
+	 */
+	if (pAd->int_pending & FifoStaFullInt)
+	{
+		tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable RxINT again */
+
+	rt2860_int_enable(pAd, FifoStaFullInt);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+
+}
+
+
+
+
+static void ac3_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
+    INT_SOURCE_CSR_STRUC	IntSource;
+	POS_COOKIE pObj;
+	BOOLEAN bReschedule = 0;
+
+	// 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;
+
+    pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+//	printk("ac0_dma_done_process\n");
+	IntSource.word = 0;
+	IntSource.field.Ac3DmaDone = 1;
+	pAd->int_pending &= ~INT_AC3_DLY;
+
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
+	{
+		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC3_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+
+static void ac2_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
+    INT_SOURCE_CSR_STRUC	IntSource;
+	POS_COOKIE pObj;
+	BOOLEAN bReschedule = 0;
+
+	// 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;
+
+    pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+	IntSource.word = 0;
+	IntSource.field.Ac2DmaDone = 1;
+	pAd->int_pending &= ~INT_AC2_DLY;
+
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
+	{
+		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC2_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+
+static void ac1_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
+    INT_SOURCE_CSR_STRUC	IntSource;
+	POS_COOKIE pObj;
+	BOOLEAN bReschedule = 0;
+
+	// 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;
+
+    pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+//	printk("ac0_dma_done_process\n");
+	IntSource.word = 0;
+	IntSource.field.Ac1DmaDone = 1;
+	pAd->int_pending &= ~INT_AC1_DLY;
+
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
+	{
+		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC1_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+
+static void ac0_dma_done_tasklet(unsigned long data)
+{
+	unsigned long flags;
+	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
+	INT_SOURCE_CSR_STRUC	IntSource;
+	POS_COOKIE pObj;
+	BOOLEAN bReschedule = 0;
+
+	// 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;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+//	printk("ac0_dma_done_process\n");
+	IntSource.word = 0;
+	IntSource.field.Ac0DmaDone = 1;
+	pAd->int_pending &= ~INT_AC0_DLY;
+
+//	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
+	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
+
+	RTMP_INT_LOCK(&pAd->irq_lock, flags);
+	/*
+	 * double check to avoid lose of interrupts
+	 */
+	if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
+	{
+		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+		return;
+	}
+
+	/* enable TxDataInt again */
+	rt2860_int_enable(pAd, INT_AC0_DLY);
+	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
+}
+
+
+
+
+/***************************************************************************
+  *
+  *	interrupt handler related procedures.
+  *
+  **************************************************************************/
+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 = (PRTMP_ADAPTER) RTMP_OS_NETDEV_GET_PRIV(net_dev);
+	INT_SOURCE_CSR_STRUC	IntSource;
+	POS_COOKIE pObj;
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+	/* Note 03312008: we can not return here before
+		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
+		Or kernel will panic after ifconfig ra0 down sometimes */
+
+
+	//
+	// Inital the Interrupt source.
+	//
+	IntSource.word = 0x00000000L;
+//	McuIntSource.word = 0x00000000L;
+
+	//
+	// Get the interrupt sources & saved to local variable
+	//
+	//RTMP_IO_READ32(pAd, where, &McuIntSource.word);
+	//RTMP_IO_WRITE32(pAd, , McuIntSource.word);
+
+	//
+	// Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp
+	// And at the same time, clock maybe turned off that say there is no DMA service.
+	// when ASIC get to sleep.
+	// To prevent system hang on power saving.
+	// We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up.
+	//
+	// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
+	// RT2860 => when ASIC is sleeping, MAC register can be read and written.
+//	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+	{
+		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
+		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
+	}
+//	else
+//		DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n"));
+
+//	RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear);
+//	RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear);
+//	DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n",
+//			IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear));
+
+	// Do nothing if Reset in progress
+	if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+	{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+        return  IRQ_HANDLED;
+#else
+        return;
+#endif
+	}
+
+	//
+	// Handle interrupt, walk through all bits
+	// Should start from highest priority interrupt
+	// The priority can be adjust by altering processing if statement
+	//
+
+#ifdef DBG
+
+#endif
+
+
+	pAd->bPCIclkOff = FALSE;
+
+	// If required spinlock, each interrupt service routine has to acquire
+	// and release itself.
+	//
+
+	// Do nothing if NIC doesn't exist
+	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
+	}
+
+	if (IntSource.word & TxCoherent)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
+		RTMPHandleRxCoherentInterrupt(pAd);
+	}
+
+	if (IntSource.word & RxCoherent)
+	{
+		DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
+		RTMPHandleRxCoherentInterrupt(pAd);
+	}
+
+	if (IntSource.word & FifoStaFullInt)
+	{
+		if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
+		{
+			/* mask FifoStaFullInt */
+			rt2860_int_disable(pAd, FifoStaFullInt);
+			tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
+		}
+		pAd->int_pending |= FifoStaFullInt;
+	}
+
+	if (IntSource.word & INT_MGMT_DLY)
+	{
+		if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
+		{
+			rt2860_int_disable(pAd, INT_MGMT_DLY);
+			tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
+		}
+		pAd->int_pending |= INT_MGMT_DLY ;
+	}
+
+	if (IntSource.word & INT_RX)
+	{
+		if ((pAd->int_disable_mask & INT_RX) == 0)
+		{
+
+			/* mask RxINT */
+			rt2860_int_disable(pAd, INT_RX);
+			tasklet_hi_schedule(&pObj->rx_done_task);
+		}
+		pAd->int_pending |= INT_RX;
+	}
+
+
+	if (IntSource.word & INT_AC3_DLY)
+	{
+
+		if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
+		{
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC3_DLY);
+			tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+		}
+		pAd->int_pending |= INT_AC3_DLY;
+	}
+
+	if (IntSource.word & INT_AC2_DLY)
+	{
+
+		if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
+		{
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC2_DLY);
+			tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+		}
+		pAd->int_pending |= INT_AC2_DLY;
+	}
+
+	if (IntSource.word & INT_AC1_DLY)
+	{
+
+		pAd->int_pending |= INT_AC1_DLY;
+
+		if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
+		{
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC1_DLY);
+			tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+		}
+
+	}
+
+	if (IntSource.word & INT_AC0_DLY)
+	{
+
+/*
+		if (IntSource.word & 0x2) {
+			u32 reg;
+			RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
+			printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
+		}
+*/
+		pAd->int_pending |= INT_AC0_DLY;
+
+		if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
+		{
+			/* mask TxDataInt */
+			rt2860_int_disable(pAd, INT_AC0_DLY);
+			tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+		}
+
+	}
+
+
+	if (IntSource.word & PreTBTTInt)
+	{
+		RTMPHandlePreTBTTInterrupt(pAd);
+	}
+
+	if (IntSource.word & TBTTInt)
+	{
+		RTMPHandleTBTTInterrupt(pAd);
+	}
+
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+	{
+		if (IntSource.word & AutoWakeupInt)
+			RTMPHandleTwakeupInterrupt(pAd);
+	}
+#endif // CONFIG_STA_SUPPORT //
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+	return  IRQ_HANDLED;
+#endif
+
+}
+
+/*
+ * invaild or writeback cache
+ * and convert virtual address to physical address
+ */
+dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
+{
+	PRTMP_ADAPTER pAd;
+	POS_COOKIE pObj;
+
+	/*
+		------ Porting Information ------
+		> For Tx Alloc:
+			mgmt packets => sd_idx = 0
+			SwIdx: pAd->MgmtRing.TxCpuIdx
+			pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
+
+			data packets => sd_idx = 1
+			TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
+			QueIdx: pTxBlk->QueIdx
+			pTxD  : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
+
+		> For Rx Alloc:
+			sd_idx = -1
+	*/
+
+	pAd = (PRTMP_ADAPTER)handle;
+	pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	if (sd_idx == 1)
+	{
+		PTX_BLK		pTxBlk;
+		pTxBlk = (PTX_BLK)ptr;
+		return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
+	}
+	else
+	{
+		return pci_map_single(pObj->pci_dev, ptr, size, direction);
+	}
+
+}
+
+void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
+{
+	PRTMP_ADAPTER pAd;
+	POS_COOKIE pObj;
+
+	pAd=(PRTMP_ADAPTER)handle;
+	pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+	pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
+
+}
diff --git a/drivers/staging/rt3090/rt_profile.c b/drivers/staging/rt3090/rt_profile.c
new file mode 100644
index 0000000..49a0590
--- /dev/null
+++ b/drivers/staging/rt3090/rt_profile.c
@@ -0,0 +1,101 @@
+/*
+ *************************************************************************
+ * 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_profile.c
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#include "rt_config.h"
+
+
+NDIS_STATUS	RTMPReadParametersHook(
+	IN	PRTMP_ADAPTER pAd)
+{
+	PSTRING					src = NULL;
+	RTMP_OS_FD				srcf;
+	RTMP_OS_FS_INFO			osFSInfo;
+	INT						retval = NDIS_STATUS_FAILURE;
+	PSTRING					buffer;
+
+	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+	if(buffer == NULL)
+		return NDIS_STATUS_FAILURE;
+	memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+
+	{
+
+#ifdef CONFIG_STA_SUPPORT
+		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+		{
+			src = STA_PROFILE_PATH;
+		}
+#endif // CONFIG_STA_SUPPORT //
+#ifdef MULTIPLE_CARD_SUPPORT
+		src = (PSTRING)pAd->MC_FileName;
+#endif // MULTIPLE_CARD_SUPPORT //
+	}
+
+	if (src && *src)
+	{
+		RtmpOSFSInfoChange(&osFSInfo, TRUE);
+		srcf = RtmpOSFileOpen(src, O_RDONLY, 0);
+		if (IS_FILE_OPEN_ERR(srcf))
+		{
+			DBGPRINT(RT_DEBUG_ERROR, ("Open file \"%s\" failed!\n", src));
+		}
+		else
+		{
+			retval =RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE);
+			if (retval > 0)
+			{
+				RTMPSetProfileParameters(pAd, buffer);
+				retval = NDIS_STATUS_SUCCESS;
+			}
+			else
+				DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
+
+			retval = RtmpOSFileClose(srcf);
+			if ( retval != 0)
+			{
+				retval = NDIS_STATUS_FAILURE;
+				DBGPRINT(RT_DEBUG_ERROR, ("Close file \"%s\" failed(errCode=%d)!\n", src, retval));
+			}
+		}
+
+		RtmpOSFSInfoChange(&osFSInfo, FALSE);
+	}
+
+	kfree(buffer);
+
+	return (retval);
+
+}
diff --git a/drivers/staging/rt3090/rtmp.h b/drivers/staging/rt3090/rtmp.h
new file mode 100644
index 0000000..8ef6d0b
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp.h
@@ -0,0 +1,6873 @@
+/*
+ *************************************************************************
+ * 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"
+
+#include "rtmp_dot11.h"
+
+#ifdef MLME_EX
+#include "mlme_ex_def.h"
+#endif // MLME_EX //
+
+#ifdef CONFIG_STA_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
+
+
+
+
+
+#include "rtmp_chip.h"
+
+
+
+typedef struct _RTMP_ADAPTER		RTMP_ADAPTER;
+typedef struct _RTMP_ADAPTER		*PRTMP_ADAPTER;
+
+typedef struct _RTMP_CHIP_OP_ RTMP_CHIP_OP;
+
+
+//#define DBG		1
+
+//#define DBG_DIAGNOSE		1
+
+
+//+++Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function
+#define MAX_DATAMM_RETRY	3
+#define MGMT_USE_QUEUE_FLAG	0x80
+//---Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function
+
+#define	MAXSEQ		(0xFFF)
+
+
+#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
+
+extern  unsigned char   SNAP_AIRONET[];
+extern  unsigned char   CISCO_OUI[];
+extern  UCHAR	BaSizeArray[4];
+
+extern UCHAR BROADCAST_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 //
+
+
+#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;		// Show Rx Frame Error Rate
+	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 RTMP_MAC_PCI
+	BOOLEAN	bFWLoading;	// Reload firmware when ATE is done.
+#endif // RTMP_MAC_PCI //
+	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
+	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;
+	RTMP_OS_PID	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;
+	// TxStatus : 0 --> task is idle, 1 --> task is running
+	UCHAR		TxStatus;
+#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 //
+
+
+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->Next = NULL;		\
+		(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++;                                    \
+}
+
+#define InsertTailQueueAc(pAd, pEntry, 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))
+// 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)
+
+#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);       \
+}
+
+
+#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)
+//
+
+
+//
+// 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);              \
+    }                                                                   \
+}
+
+
+// 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 RTMP_MAC_PCI
+#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
+{                                                                                       \
+    UINT32 High32TSF, Low32TSF;                                                          \
+    RTMP_IO_READ32(_pAd, TSF_TIMER_DW1, &High32TSF);                                       \
+    RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF);                                        \
+    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal);   \
+}
+#endif // RTMP_MAC_PCI //
+
+#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_EXTRA_SETTING(_pAd)
+
+#define STA_PORT_SECURED(_pAd) \
+{ \
+	BOOLEAN	Cancelled; \
+	(_pAd)->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
+	NdisAcquireSpinLock(&((_pAd)->MacTabLock)); \
+	(_pAd)->MacTab.Content[BSSID_WCID].PortSecured = (_pAd)->StaCfg.PortSecured; \
+	(_pAd)->MacTab.Content[BSSID_WCID].PrivacyFilter = Ndis802_11PrivFilterAcceptAll;\
+	NdisReleaseSpinLock(&(_pAd)->MacTabLock); \
+	RTMPCancelTimer(&((_pAd)->Mlme.LinkDownTimer), &Cancelled);\
+	STA_EXTRA_SETTING(_pAd); \
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+//
+//  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;
+
+
+//
+// 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_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          OneSecReceivedByteCount;
+	UINT32			OneSecFrameDuplicateCount;
+
+	UINT32          OneSecTransmittedByteCount;   // both successful and failure, used to calculate TX throughput
+	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 _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;
+
+
+
+
+/***************************************************************************
+  *	security key related data structure
+  **************************************************************************/
+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;
+
+
+// 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 {
+	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;
+
+//
+// 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;
+
+
+/*
+  *	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;
+
+
+//
+//  Arcfour Structure Added by PaulWu
+//
+typedef struct  _ARCFOUR
+{
+	UINT            X;
+	UINT            Y;
+	UCHAR           STATE[256];
+} ARCFOURCONTEXT, *PARCFOURCONTEXT;
+
+
+//
+// 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;
+
+
+/***************************************************************************
+  *	Channel and BBP related data structures
+  **************************************************************************/
+// 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 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
+#ifdef CONFIG_STA_SUPPORT
+	SHORT     Pair1AvgRssi[2];       // AvgRssi[0]:E1, AvgRssi[1]:E2
+	SHORT     Pair2AvgRssi[2];       // AvgRssi[0]:E3, AvgRssi[1]:E4
+#endif // CONFIG_STA_SUPPORT //
+	SHORT     Pair1LastAvgRssi;      //
+	SHORT     Pair2LastAvgRssi;      //
+	ULONG     RcvPktNumWhenEvaluate;
+	BOOLEAN   FirstPktArrivedWhenEvaluate;
+	RALINK_TIMER_STRUCT    RxAntDiversityTimer;
+} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
+
+
+/***************************************************************************
+  *	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;
+#ifdef DFS_FCC_BW40_FIX
+	CHAR		DfsSessionFccOff;
+#endif
+	BOOLEAN		bFastDfs;
+	UINT8		ChMovingTime;
+	UINT8		LongPulseRadarTh;
+#ifdef MERGE_ARCH_TEAM
+	CHAR		AvgRssiReq;
+	ULONG		DfsLowerLimit;
+	ULONG		DfsUpperLimit;
+	UINT8		FixDfsLimit;
+	ULONG		upperlimit;
+	ULONG		lowerlimit;
+#endif // MERGE_ARCH_TEAM //
+} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+typedef enum CD_STATE_n
+{
+	CD_NORMAL,
+	CD_SILENCE,
+	CD_MAX_STATE
+} CD_STATE;
+
+#ifdef TONE_RADAR_DETECT_SUPPORT
+#define CARRIER_DETECT_RECHECK_TIME			3
+
+
+#ifdef CARRIER_SENSE_NEW_ALGO
+#define CARRIER_DETECT_CRITIRIA				400
+#define CARRIER_DETECT_STOP_RATIO				0x11
+#define	CARRIER_DETECT_STOP_RATIO_OLD_3090			2
+#endif // CARRIER_SENSE_NEW_ALGO //
+
+
+#define CARRIER_DETECT_STOP_RECHECK_TIME		4
+#define CARRIER_DETECT_CRITIRIA_A				230
+#define CARRIER_DETECT_DELTA					7
+#define CARRIER_DETECT_DIV_FLAG				0
+#ifdef RT3090
+#define CARRIER_DETECT_THRESHOLD_3090A			0x1fffffff
+#endif // RT3090 //
+#ifdef RT3390
+#define CARRIER_DETECT_THRESHOLD			0x0fffffff
+#endif // RT3390 //
+#ifndef RT3390
+#define CARRIER_DETECT_THRESHOLD			0x0fffffff
+#endif // RT3390 //
+#endif // TONE_RADAR_DETECT_SUPPORT //
+
+typedef struct CARRIER_DETECTION_s
+{
+	BOOLEAN					Enable;
+	UINT8					CDSessionTime;
+	UINT8					CDPeriod;
+	CD_STATE				CD_State;
+#ifdef TONE_RADAR_DETECT_SUPPORT
+	UINT8					delta;
+	UINT8					div_flag;
+	UINT32					threshold;
+	UINT8					recheck;
+	UINT8					recheck1;
+	UINT8					recheck2;
+	UINT32					TimeStamp;
+	UINT32					criteria;
+	UINT32					CarrierDebug;
+	ULONG					idle_time;
+	ULONG					busy_time;
+	ULONG					Debug;
+#endif // TONE_RADAR_DETECT_SUPPORT //
+}CARRIER_DETECTION_STRUCT, *PCARRIER_DETECTION_STRUCT;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+
+#ifdef NEW_DFS
+typedef struct _NewDFSDebug
+{
+	UCHAR channel;
+	ULONG wait_time;
+	UCHAR delta_delay_range;
+	UCHAR delta_delay_step;
+	UCHAR EL_range;
+	UCHAR EL_step;
+	UCHAR EH_range;
+	UCHAR EH_step;
+	UCHAR WL_range;
+	UCHAR WL_step;
+	UCHAR WH_range;
+	UCHAR WH_step;
+	ULONG T_expected;
+	ULONG T_margin;
+	UCHAR start;
+	ULONG count;
+	ULONG idx;
+
+}NewDFSDebug, *pNewDFSDebug;
+
+#define NEW_DFS_FCC_5_ENT_NUM		5
+#define NEW_DFS_DBG_PORT_ENT_NUM_POWER	8
+#define NEW_DFS_DBG_PORT_ENT_NUM		(1 << NEW_DFS_DBG_PORT_ENT_NUM_POWER)  // CE Debug Port entry number, 256
+#define NEW_DFS_DBG_PORT_MASK	0xff
+
+// Matched Period definition
+#define NEW_DFS_MPERIOD_ENT_NUM_POWER		8
+#define NEW_DFS_MPERIOD_ENT_NUM		(1 << NEW_DFS_MPERIOD_ENT_NUM_POWER)	 // CE Period Table entry number, 512
+#define NEW_DFS_MAX_CHANNEL	4
+
+typedef struct _NewDFSDebugPort{
+	ULONG counter;
+	ULONG timestamp;
+	USHORT width;
+	USHORT start_idx; // start index to period table
+	USHORT end_idx; // end index to period table
+}NewDFSDebugPort, *pNewDFSDebugPort;
+
+// Matched Period Table
+typedef struct _NewDFSMPeriod{
+	USHORT	idx;
+	USHORT width;
+	USHORT	idx2;
+	USHORT width2;
+	ULONG period;
+}NewDFSMPeriod, *pNewDFSMPeriod;
+
+#endif // NEW_DFS //
+
+
+typedef enum _ABGBAND_STATE_ {
+	UNKNOWN_BAND,
+	BG_BAND,
+	A_BAND,
+} ABGBAND_STATE;
+
+#ifdef RTMP_MAC_PCI
+#ifdef CONFIG_STA_SUPPORT
+// Power save method control
+typedef	union	_PS_CONTROL	{
+	struct	{
+		ULONG		EnablePSinIdle:1;			// Enable radio off when not connect to AP. radio on only when sitesurvey,
+		ULONG		EnableNewPS:1;		// Enable new  Chip power save fucntion . New method can only be applied in chip version after 2872. and PCIe.
+		ULONG		rt30xxPowerMode:2;			// Power Level Mode for rt30xx chip
+		ULONG		rt30xxFollowHostASPM:1;			// Card Follows Host's setting for rt30xx chip.
+		ULONG		rt30xxForceASPMTest:1;			// Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode.
+		ULONG		rsv:26;			// Radio Measurement Enable
+	}	field;
+	ULONG			word;
+}	PS_CONTROL, *PPS_CONTROL;
+#endif // CONFIG_STA_SUPPORT //
+#endif // RTMP_MAC_PCI //
+/***************************************************************************
+  *	structure for MLME state machine
+  **************************************************************************/
+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_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];
+#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 //
+
+
+	// common WPA state machine
+	STATE_MACHINE           WpaMachine;
+	STATE_MACHINE_FUNC      WpaFunc[WPA_FUNC_SIZE];
+
+
+
+	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;
+#ifdef RTMP_MAC_PCI
+    UCHAR                   bPsPollTimerRunning;
+    RALINK_TIMER_STRUCT     PsPollTimer;
+	RALINK_TIMER_STRUCT     RadioOnOffTimer;
+#endif // RTMP_MAC_PCI //
+	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;
+
+
+#ifdef DOT11_N_SUPPORT
+/***************************************************************************
+  *	802.11 N related data structures
+  **************************************************************************/
+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;
+};
+
+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;
+
+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[]
+	ULONG		numDoneOriginator;	// count Done Originator sessions
+	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;
+
+
+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;
+
+
+#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 //
+
+#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 //
+
+
+//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;
+
+
+
+
+/***************************************************************************
+  *	Multiple SSID related data structures
+  **************************************************************************/
+#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]; }
+
+
+// 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
+	UCHAR       DesiredPhyMode;            // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
+	USHORT      Dsifs;              // in units of usec
+	ULONG       PacketFilter;       // Packet filter for receiving
+	UINT8		RegulatoryClass[MAX_NUM_OF_REGULATORY_CLASS];
+
+	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;
+
+	/* because TSPEC can modify the APSD flag, we need to keep the APSD flag
+		requested in association stage from the station;
+		we need to recover the APSD flag after the TSPEC is deleted. */
+	BOOLEAN		bACMAPSDBackup[4]; /* for delivery-enabled & trigger-enabled both */
+	BOOLEAN		bACMAPSDTr[4]; /* no use */
+
+	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
+	UINT8		PwrConstraint;
+
+#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 (when BA is established or AP is not a legacy WMM AP), 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.
+#ifdef ANT_DIVERSITY_SUPPORT
+	UCHAR				bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity.
+#endif // ANT_DIVERSITY_SUPPORT //
+
+	// IEEE802.11H--DFS.
+	RADAR_DETECT_STRUCT	RadarDetect;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+	CARRIER_DETECTION_STRUCT		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;
+//2008/11/05: KH add to support Antenna power-saving of AP<--
+	BOOLEAN					bGreenAPEnable;
+	BOOLEAN					bBlockAntDivforGreenAP;
+//2008/11/05: KH add to support Antenna power-saving of AP-->
+	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
+
+
+
+	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 //
+
+
+	BOOLEAN				PSPXlink;  // 0: Disable. 1: Enable
+
+
+#if defined(RT305x)||defined(RT30xx)
+	// request by Gary, for High Power issue
+	UCHAR	HighPowerPatchDisabled;
+#endif
+
+	BOOLEAN		HT_DisallowTKIP;		/* Restrict the encryption type in 11n HT mode */
+} 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		WpaPassPhrase[64];		// WPA PSK pass phrase
+	UINT		WpaPassPhraseLen;		// the length of WPA PSK pass phrase
+	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
+
+	// 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.
+
+	ULONG               CLBusyBytes;                // Save the total bytes received durning channel load scan time
+	USHORT              RPIDensity[8];              // Array for RPI density collection
+
+	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
+	// Hack for channel load and noise histogram parameters
+	UCHAR               NHFactor;                   // Parameter for Noise histogram
+	UCHAR               CLFactor;                   // Parameter for channel load
+
+	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		        bAutoRoaming;       // 0:disable auto roaming by RSSI, 1:enable auto roaming by RSSI
+	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;
+	BOOLEAN				bRSN_IE_FromWpaSupplicant;
+#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 RTMP_MAC_PCI
+    UCHAR       BBPR3;
+	// PS Control has 2 meanings for advanced power save function.
+	// 1. EnablePSinIdle : When no connection, always radio off except need to do site survey.
+	// 2. EnableNewPS  : will save more current in sleep or radio off mode.
+	PS_CONTROL				PSControl;
+#endif // RTMP_MAC_PCI //
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+	UCHAR				IEEE80211dClientMode;
+	UCHAR				StaOriCountryCode[3];
+	UCHAR				StaOriGeography;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+
+
+	BOOLEAN				bAutoConnectByBssid;
+	ULONG				BeaconLostTime;	// seconds
+	BOOLEAN			bForceTxBurst;          // 1: force enble TX PACKET BURST, 0: disable
+} 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 //
+
+
+
+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;	// Flag if this is Atheros chip that has IOT problem.  We need to turn on RTS/CTS protection.
+
+	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           SNonce[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;
+	NDIS_802_11_WEP_STATUS              GroupKeyWepStatus;
+	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
+// 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 WDS_SUPPORT
+	BOOLEAN		LockEntryTx; // TRUE = block to WDS Entry traffic, FALSE = not.
+	UINT32		TimeStamp_toTxRing;
+#endif // WDS_SUPPORT //
+
+//====================================================
+
+
+
+#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;
+
+	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 //
+
+
+
+	ULONG AssocDeadLine;
+
+
+
+	ULONG ChannelQuality;  // 0..100, Channel Quality Indication for Roaming
+
+} 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
+//2008/10/28: KH add to support Antenna power-saving of AP<--
+//2008/10/28: KH add to support Antenna power-saving of AP-->
+#endif // DOT11_N_SUPPORT //
+} MAC_TABLE, *PMAC_TABLE;
+
+
+
+
+#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 _RTMP_DEV_INFO_
+{
+	UCHAR			chipName[16];
+	RTMP_INF_TYPE	infType;
+}RTMP_DEV_INFO;
+
+
+#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 //
+
+
+struct _RTMP_CHIP_OP_
+{
+	/*  Calibration access related callback functions */
+	int (*eeinit)(RTMP_ADAPTER *pAd);										/* int (*eeinit)(RTMP_ADAPTER *pAd); */
+	int (*eeread)(RTMP_ADAPTER *pAd, USHORT offset, PUSHORT pValue);				/* int (*eeread)(RTMP_ADAPTER *pAd, int offset, PUSHORT pValue); */
+	int (*eewrite)(RTMP_ADAPTER *pAd, USHORT offset, USHORT value);;				/* int (*eewrite)(RTMP_ADAPTER *pAd, int offset, USHORT value); */
+
+	/* MCU related callback functions */
+	int (*loadFirmware)(RTMP_ADAPTER *pAd);								/* int (*loadFirmware)(RTMP_ADAPTER *pAd); */
+	int (*eraseFirmware)(RTMP_ADAPTER *pAd);								/* int (*eraseFirmware)(RTMP_ADAPTER *pAd); */
+	int (*sendCommandToMcu)(RTMP_ADAPTER *pAd, UCHAR cmd, UCHAR token, UCHAR arg0, UCHAR arg1);;	/* int (*sendCommandToMcu)(RTMP_ADAPTER *pAd, UCHAR cmd, UCHAR token, UCHAR arg0, UCHAR arg1); */
+
+	/* RF access related callback functions */
+	REG_PAIR *pRFRegTable;
+	void (*AsicRfInit)(RTMP_ADAPTER *pAd);
+	void (*AsicRfTurnOn)(RTMP_ADAPTER *pAd);
+	void (*AsicRfTurnOff)(RTMP_ADAPTER *pAd);
+	void (*AsicReverseRfFromSleepMode)(RTMP_ADAPTER *pAd);
+	void (*AsicHaltAction)(RTMP_ADAPTER *pAd);
+};
+
+
+//
+//  The miniport adapter structure
+//
+struct _RTMP_ADAPTER
+{
+	PVOID					OS_Cookie;	// save specific structure relative to OS
+	PNET_DEV				net_dev;
+	ULONG					VirtualIfCnt;
+
+	RTMP_CHIP_OP			chipOps;
+	USHORT					ThisTbttNumToNextWakeUp;
+
+#ifdef INF_AMAZON_PPA
+	UINT32  g_if_id;
+	BOOLEAN	PPAEnable;
+	PPA_DIRECTPATH_CB       *pDirectpathCb;
+#endif // INF_AMAZON_PPA //
+
+#ifdef RTMP_MAC_PCI
+/*****************************************************************************************/
+/*      PCI related parameters																  */
+/*****************************************************************************************/
+	PUCHAR                  CSRBaseAddress;     // PCI MMIO Base Address, all access will use
+	unsigned int			irq_num;
+
+	USHORT		            LnkCtrlBitMask;
+	USHORT		            RLnkCtrlConfiguration;
+	USHORT                  RLnkCtrlOffset;
+	USHORT		            HostLnkCtrlConfiguration;
+	USHORT                  HostLnkCtrlOffset;
+	USHORT		            PCIePowerSaveLevel;
+	ULONG				Rt3xxHostLinkCtrl;	// USed for 3090F chip
+	ULONG				Rt3xxRalinkLinkCtrl;	// USed for 3090F chip
+	USHORT				DeviceID;           // Read from PCI config
+	ULONG				AccessBBPFailCount;
+	BOOLEAN					bPCIclkOff;						// flag that indicate if the PICE power status in Configuration SPace..
+	BOOLEAN					bPCIclkOffDisableTx;			//
+
+	BOOLEAN					brt30xxBanMcuCmd;	//when = 0xff means all commands are ok to set .
+	BOOLEAN					b3090ESpecialChip;	//3090E special chip that write EEPROM 0x24=0x9280.
+	ULONG					CheckDmaBusyCount;  // Check Interrupt Status Register Count.
+
+	UINT					int_enable_reg;
+	UINT					int_disable_mask;
+	UINT					int_pending;
+
+
+	RTMP_DMABUF             TxBufSpace[NUM_OF_TX_RING]; // Shared memory of all 1st pre-allocated TxBuf associated with each TXD
+	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 // RTMP_MAC_PCI //
+
+
+	NDIS_SPIN_LOCK		irq_lock;
+	UCHAR				irq_disabled;
+
+
+/*****************************************************************************************/
+/*      RBUS related parameters																  */
+/*****************************************************************************************/
+
+
+/*****************************************************************************************/
+/*      Both PCI/USB related parameters														  */
+/*****************************************************************************************/
+	//RTMP_DEV_INFO			chipInfo;
+	RTMP_INF_TYPE			infType;
+
+/*****************************************************************************************/
+/*      Driver Mgmt related parameters														  */
+/*****************************************************************************************/
+	RTMP_OS_TASK			mlmeTask;
+#ifdef RTMP_TIMER_TASK_SUPPORT
+	// If you want use timer task to handle the timer related jobs, enable this.
+	RTMP_TIMER_TASK_QUEUE	TimerQ;
+	NDIS_SPIN_LOCK			TimerQLock;
+	RTMP_OS_TASK			timerTask;
+#endif // RTMP_TIMER_TASK_SUPPORT //
+
+
+/*****************************************************************************************/
+/*      Tx related parameters                                                           */
+/*****************************************************************************************/
+	BOOLEAN                 DeQueueRunning[NUM_OF_TX_RING];  // for ensuring RTUSBDeQueuePacket get call once
+	NDIS_SPIN_LOCK          DeQueueLock[NUM_OF_TX_RING];
+
+
+	// 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 RTMP_MAC_PCI
+	RTMP_RX_RING            RxRing;
+	NDIS_SPIN_LOCK          RxRingLock;                 // Rx Ring spinlock
+#ifdef RT3090
+	NDIS_SPIN_LOCK          McuCmdLock;              //MCU Command Queue spinlock
+#endif // RT3090 //
+#endif // RTMP_MAC_PCI //
+
+
+
+/*****************************************************************************************/
+/*      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
+	ULONG				FirmwareVersion;        // byte 0: Minor version, byte 1: Major version, otherwise unused.
+	USHORT				EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
+	UCHAR				EEPROMAddressNum;       // 93c46=6  93c66=8
+	BOOLEAN				EepromAccess;
+	UCHAR				EFuseTag;
+
+
+	// ---------------------------
+	// BBP Control
+	// ---------------------------
+#ifdef MERGE_ARCH_TEAM
+	UCHAR                   BbpWriteLatch[256];     // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
+#else
+	UCHAR                   BbpWriteLatch[140];     // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
+#endif // MERGE_ARCH_TEAM //
+	CHAR					BbpRssiToDbmDelta;		// change from UCHAR to CHAR for high power
+	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))
+
+	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
+
+	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
+#ifdef RT30xx
+	// for 3572
+	UCHAR		Bbp25;
+	UCHAR		Bbp26;
+
+	UCHAR		TxMixerGain24G;				// Tx mixer gain value from EEPROM to improve Tx EVM / Tx DAC, 2.4G
+	UCHAR		TxMixerGain5G;
+#endif // RT30xx //
+	// ----------------------------
+	// LED control
+	// ----------------------------
+	MCU_LEDCS_STRUC		LedCntl;
+	USHORT				Led1;	// read from EEPROM 0x3c
+	USHORT				Led2;	// EEPROM 0x3e
+	USHORT				Led3;	// EEPROM 0x40
+	UCHAR				LedIndicatorStrength;
+	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;
+
+
+
+
+//=========AP===========
+
+
+//=======STA===========
+#ifdef CONFIG_STA_SUPPORT
+	// -----------------------------------------------
+	// 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;
+	NDIS_SPIN_LOCK          BATabLock;
+	RALINK_TIMER_STRUCT RECBATimer;
+#endif // DOT11_N_SUPPORT //
+
+	// 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
+	ULONG                   PSFlags;                    // Power Save operation flag.
+
+	// current TX sequence #
+	USHORT                  Sequence;
+
+	// 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                                                     */
+	/*****************************************************************************************/
+
+	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;
+#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
+
+#ifdef LINUX
+#if WIRELESS_EXT >= 12
+    struct iw_statistics    iw_stats;
+#endif
+
+	struct net_device_stats	stats;
+#endif // LINUX //
+
+#ifdef BLOCK_NET_IF
+	BLOCK_QUEUE_ENTRY		blockQueueTab[NUM_OF_TX_RING];
+#endif // BLOCK_NET_IF //
+
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+	INT32					MC_RowID;
+	STRING					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					FlgCtsEnabled;
+	UINT8					PM_FlgSuspend;
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+	BOOLEAN		bUseEfuse;
+	BOOLEAN		bEEPROMFile;
+	BOOLEAN		bFroceEEPROMBuffer;
+	UCHAR		EEPROMImage[1024];
+#endif // RTMP_EFUSE_SUPPORT //
+#endif // RT30xx //
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+};
+
+
+
+#ifdef TONE_RADAR_DETECT_SUPPORT
+#define DELAYINTMASK		0x0013fffb
+#define INTMASK				0x0013fffb
+#define IndMask				0x0013fffc
+#define RadarInt			0x00100000
+#else
+#define DELAYINTMASK		0x0003fffb
+#define INTMASK				0x0003fffb
+#define IndMask				0x0003fffc
+#endif // TONE_RADAR_DETECT_SUPPORT //
+
+#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
+
+
+/***************************************************************************
+  *	Rx Path software control block related data structures
+  **************************************************************************/
+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
+
+
+/***************************************************************************
+  *	Tx Path software control block related data structures
+  **************************************************************************/
+#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[96];				// 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_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_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
+/***************************************************************************
+  *	Endian conversion related functions
+  **************************************************************************/
+/*
+	========================================================================
+
+	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));
+	}
+}
+
+
+#ifdef RTMP_MAC_PCI
+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
+}
+#endif // RTMP_MAC_PCI //
+
+
+/*
+	========================================================================
+
+	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 RTMP_MAC_PCI
+static inline VOID	RTMPDescriptorEndianChange(
+	IN	PUCHAR			pData,
+	IN	ULONG			DescriptorType)
+{
+	*((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));		// Byte 0~3
+	*((UINT32 *)(pData + 8)) = SWAP32(*((UINT32 *)(pData+8)));	// Byte 8~11
+	*((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 // RTMP_MAC_PCI //
+
+/*
+	========================================================================
+
+	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 //
+
+
+/***************************************************************************
+  *	Other static inline function definitions
+  **************************************************************************/
+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;
+}
+
+
+char *GetPhyMode(int Mode);
+char* GetBW(int BW);
+
+
+
+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);
+
+NDIS_STATUS	RTMPSetProfileParameters(
+	IN RTMP_ADAPTER *pAd,
+	IN PSTRING		pBuffer);
+
+INT RTMPGetKeyParameter(
+    IN PSTRING key,
+    OUT PSTRING dest,
+    IN INT destsize,
+    IN PSTRING buffer,
+    IN BOOLEAN bTrimSpace);
+
+VOID RTMPFreeAdapter(
+	IN  PRTMP_ADAPTER   pAd);
+
+NDIS_STATUS NICReadRegParameters(
+	IN  PRTMP_ADAPTER       pAd,
+	IN  NDIS_HANDLE         WrapperConfigurationContext);
+
+#ifdef RTMP_RF_RW_SUPPORT
+VOID NICInitRFRegisters(
+	IN PRTMP_ADAPTER pAd);
+
+VOID RtmpChipOpsRFHook(
+	IN RTMP_ADAPTER *pAd);
+
+NDIS_STATUS	RT30xxWriteRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			regID,
+	IN	UCHAR			value);
+
+NDIS_STATUS	RT30xxReadRFRegister(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			regID,
+	IN	PUCHAR			pValue);
+#endif // RTMP_RF_RW_SUPPORT //
+
+VOID NICReadEEPROMParameters(
+	IN  PRTMP_ADAPTER       pAd,
+	IN	PUCHAR				mac_addr);
+
+VOID NICInitAsicFromEEPROM(
+	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);
+
+NDIS_STATUS NICLoadFirmware(
+	IN  PRTMP_ADAPTER   pAd);
+
+VOID NICEraseFirmware(
+	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);
+
+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(
+	PSTRING	src,
+	PUCHAR 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);
+
+
+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);
+
+#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 //
+#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);
+
+#ifdef RTMP_MAC_PCI
+NDIS_STATUS MlmeHardTransmitTxRing(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UCHAR	QueIdx,
+	IN  PNDIS_PACKET    pPacket);
+
+NDIS_STATUS MlmeDataHardTransmit(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	QueIdx,
+	IN	PNDIS_PACKET	pPacket);
+
+VOID RTMPWriteTxDescriptor(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PTXD_STRUC		pTxD,
+	IN	BOOLEAN			bWIV,
+	IN	UCHAR			QSEL);
+#endif // RTMP_MAC_PCI //
+
+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 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);
+
+//+++mark by shiang, now this function merge to MiniportMMRequest()
+//---mark by shiang, now this function merge to MiniportMMRequest()
+
+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);
+
+VOID WpaStaPairwiseKeySetting(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID WpaStaGroupKeySetting(
+	IN	PRTMP_ADAPTER	pAd);
+
+#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 AsicResetBBPAgent(
+	IN PRTMP_ADAPTER pAd);
+
+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);
+
+
+#ifdef RTMP_MAC_PCI
+BOOLEAN AsicCheckCommanOk(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command);
+#endif // RTMP_MAC_PCI //
+
+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);
+
+ULONG BssSsidTableSearchBySSID(
+	IN BSS_TABLE *Tab,
+	IN PUCHAR	 pSsid,
+	IN UCHAR	 SsidLen);
+
+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  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);
+
+
+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	PSTRING			arg);
+
+INT	Set_DlsTearDownEntry_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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  STRING 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 UCHAR *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);
+
+BOOLEAN MlmeCheckForFastRoaming(
+	IN  PRTMP_ADAPTER   pAd);
+
+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 PMAC_TABLE_ENTRY pMacEntry,
+	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);
+
+#ifdef RT30xx
+VOID AsicSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant);
+
+VOID RTMPFilterCalibration(
+	IN PRTMP_ADAPTER pAd);
+
+#ifdef RTMP_EFUSE_SUPPORT
+//2008/09/11:KH add to support efuse<--
+INT set_eFuseGetFreeBlockCount_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT set_eFusedump_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT set_eFuseLoadFromBin_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+VOID eFusePhysicalReadRegisters(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT Offset,
+	IN	USHORT Length,
+	OUT	USHORT* pData);
+
+int RtmpEfuseSupportCheck(
+	IN RTMP_ADAPTER *pAd);
+
+INT set_eFuseBufferModeWriteBack_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT eFuseLoadEEPROM(
+	IN PRTMP_ADAPTER pAd);
+
+INT eFuseWriteEeeppromBuf(
+	IN PRTMP_ADAPTER pAd);
+
+VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd,
+	PUINT EfuseFreeBlock);
+
+INT eFuse_init(
+	IN PRTMP_ADAPTER pAd);
+
+NTSTATUS eFuseRead(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	OUT	PUCHAR			pData,
+	IN	USHORT			Length);
+
+NTSTATUS eFuseWrite(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT			Offset,
+	IN	PUCHAR			pData,
+	IN	USHORT			length);
+//2008/09/11:KH add to support efuse-->
+#endif // RTMP_EFUSE_SUPPORT //
+
+// 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
+
+
+#ifdef RT3090
+VOID NICInitRT3090RFRegisters(
+	IN RTMP_ADAPTER *pAd);
+#endif // RT3090 //
+
+VOID RT30xxHaltAction(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RT30xxSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant);
+#endif // RT30xx //
+#ifdef RT33xx
+VOID RT33xxLoadRFNormalModeSetup(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RT33xxLoadRFSleepModeSetup(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RT33xxReverseRFSleepModeSetup(
+	IN PRTMP_ADAPTER	pAd);
+
+#ifdef RT3370
+VOID NICInitRT3370RFRegisters(
+	IN RTMP_ADAPTER *pAd);
+#endif // RT3070 //
+
+#ifdef RT3390
+VOID NICInitRT3390RFRegisters(
+	IN RTMP_ADAPTER *pAd);
+#endif // RT3090 //
+
+VOID RT33xxHaltAction(
+	IN PRTMP_ADAPTER	pAd);
+
+VOID RT33xxSetRxAnt(
+	IN PRTMP_ADAPTER	pAd,
+	IN UCHAR			Ant);
+
+#endif // RT33xx //
+
+
+
+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);
+
+//
+// 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
+//
+INT RT_CfgSetCountryRegion(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg,
+	IN INT				band);
+
+INT RT_CfgSetWirelessMode(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT RT_CfgSetShortSlot(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	RT_CfgSetWepKey(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			keyString,
+	IN	CIPHER_KEY		*pSharedKey,
+	IN	INT				keyIdx);
+
+INT RT_CfgSetWPAPSKKey(
+	IN RTMP_ADAPTER	*pAd,
+	IN PSTRING		keyString,
+	IN UCHAR		*pHashStr,
+	IN INT			hashStrLen,
+	OUT PUCHAR		pPMKBuf);
+
+
+
+//
+// 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);
+
+PSTRING GetEncryptType(
+	CHAR enc);
+
+PSTRING GetAuthMode(
+	CHAR auth);
+
+
+VOID RTMPIndicateWPA2Status(
+	IN  PRTMP_ADAPTER  pAdapter);
+
+VOID	RTMPOPModeSwitching(
+	IN	PRTMP_ADAPTER	pAd);
+
+
+#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);
+
+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);
+
+#ifdef ANT_DIVERSITY_SUPPORT
+VOID	APAsicAntennaAvg(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR	              AntSelect,
+	IN	SHORT	              *RssiAvg);
+#endif // ANT_DIVERSITY_SUPPORT //
+
+VOID APAsicRxAntEvalTimeout(
+	IN PRTMP_ADAPTER	pAd);
+
+/*===================================
+	Function prototype in cmm_wpa.c
+  =================================== */
+VOID	RTMPToWirelessSta(
+    IN  PRTMP_ADAPTER		pAd,
+    IN  PMAC_TABLE_ENTRY	pEntry,
+    IN  PUCHAR			pHeader802_3,
+    IN  UINT			HdrLen,
+    IN  PUCHAR			pData,
+    IN  UINT			DataLen,
+    IN	BOOLEAN				bClearFrame);
+
+VOID WpaDerivePTK(
+	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);
+
+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	UINT32	c_len,
+	IN  UCHAR   *ciphertext);
+
+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	PMAC_TABLE_ENTRY	pEntry,
+    IN	UCHAR				GroupKeyWepStatus,
+    IN	UCHAR				MsgType,
+    IN	UCHAR				DefaultKeyIdx,
+	IN	UCHAR				*KeyNonce,
+	IN	UCHAR				*TxRSC,
+	IN	UCHAR				*GTK,
+	IN	UCHAR				*RSNIE,
+	IN	UCHAR				RSNIE_Len,
+    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 RTMPMakeRSNIE(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  UINT            AuthMode,
+	IN  UINT            WepStatus,
+	IN	UCHAR			apidx);
+
+//
+// function prototype in ap_wpa.c
+//
+VOID RTMPGetTxTscFromAsic(
+	IN  PRTMP_ADAPTER   pAd,
+	IN	UCHAR			apidx,
+	OUT	PUCHAR			pTxTsc);
+
+VOID APInstallPairwiseKey(
+	PRTMP_ADAPTER		pAd,
+	PMAC_TABLE_ENTRY	pEntry);
+
+MAC_TABLE_ENTRY *PACInquiry(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  ULONG           Wcid);
+
+UINT	APValidateRSNIE(
+	IN PRTMP_ADAPTER    pAd,
+	IN PMAC_TABLE_ENTRY pEntry,
+	IN PUCHAR			pRsnIe,
+	IN UCHAR			rsnie_len);
+
+VOID HandleCounterMeasure(
+	IN PRTMP_ADAPTER pAd,
+	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 PeerPairMsg1Action(
+	IN PRTMP_ADAPTER pAd,
+	IN MAC_TABLE_ENTRY  *pEntry,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg2Action(
+	IN PRTMP_ADAPTER pAd,
+	IN MAC_TABLE_ENTRY  *pEntry,
+	IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg3Action(
+	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 PeerGroupMsg1Action(
+	IN  PRTMP_ADAPTER    pAd,
+	IN  PMAC_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 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 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 WpaDeriveGTK(
+	IN  UCHAR   *PMK,
+	IN  UCHAR   *GNonce,
+	IN  UCHAR   *AA,
+	OUT UCHAR   *output,
+	IN  UINT    len);
+
+VOID AES_GTK_KEY_WRAP(
+	IN UCHAR *key,
+	IN UCHAR *plaintext,
+	IN UINT32 p_len,
+	OUT UCHAR *ciphertext);
+
+VOID AES_128_CMAC(
+	IN	PUCHAR	key,
+	IN	PUCHAR	input,
+	IN	INT		len,
+	OUT	PUCHAR	mac);
+
+VOID    WpaSend(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PUCHAR          pPacket,
+    IN  ULONG           Len);
+
+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);
+
+//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	RTMP_ADAPTER *pAd,
+	OUT	UCHAR **mem,
+	IN	ULONG  size);
+
+NDIS_STATUS os_free_mem(
+	IN	PRTMP_ADAPTER pAd,
+	IN	PVOID 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_FreeFirstTxBuffer(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	BOOLEAN	Cached,
+	IN	PVOID	VirtualAddress,
+	IN	NDIS_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);
+
+void RTMP_FreeDescMemory(
+	IN	PRTMP_ADAPTER pAd,
+	IN	ULONG	Length,
+	IN	PVOID	VirtualAddress,
+	IN	NDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+PNDIS_PACKET RtmpOSNetPktAlloc(
+	IN RTMP_ADAPTER *pAd,
+	IN int size);
+
+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);
+
+
+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);
+
+
+
+#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 PSTRING s1,
+	IN PSTRING s2);
+
+BOOLEAN rtstrcasecmp(
+	IN PSTRING s1,
+	IN PSTRING s2);
+
+PSTRING rtstrstruncasecmp(
+	IN PSTRING s1,
+	IN PSTRING s2);
+
+PSTRING rtstrstr(
+	IN	const PSTRING s1,
+	IN	const PSTRING s2);
+
+PSTRING rstrtok(
+	IN PSTRING s,
+	IN const PSTRING ct);
+
+int rtinet_aton(
+	const PSTRING cp,
+	unsigned int *addr);
+
+////////// common ioctl functions //////////
+INT Set_DriverVersion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_CountryRegion_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_CountryRegionABand_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_WirelessMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_Channel_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ShortSlot_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_TxPower_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_BGProtection_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PSTRING			arg);
+
+INT Set_TxPreamble_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PSTRING			arg);
+
+INT Set_RTSThreshold_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PSTRING			arg);
+
+INT Set_FragThreshold_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PSTRING			arg);
+
+INT Set_TxBurst_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PSTRING			arg);
+
+#ifdef AGGREGATION_SUPPORT
+INT	Set_PktAggregate_Proc(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PSTRING			arg);
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef INF_AMAZON_PPA
+INT	Set_INF_AMAZON_SE_PPA_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+
+#endif // INF_AMAZON_PPA //
+
+INT	Set_IEEE80211H_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+#ifdef DBG
+INT	Set_Debug_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+#endif
+
+INT	Show_DescInfo_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ResetStatCounter_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+#ifdef DOT11_N_SUPPORT
+INT	Set_BASetup_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_BADecline_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_BAOriTearDown_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_BARecTearDown_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtBw_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtMcs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtGi_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtOpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtStbc_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtHtc_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtExtcha_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtMpduDensity_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtBaWinSize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtRdg_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtLinkAdapt_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtAmsdu_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtAutoBa_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtProtect_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtMimoPs_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+
+INT	Set_ForceShortGI_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_ForceGF_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	SetCommonHT(
+	IN	PRTMP_ADAPTER	pAd);
+
+INT	Set_SendPSMPAction_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtMIMOPSmode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+
+INT	Set_HtTxBASize_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT	Set_HtDisallowTKIP_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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);
+
+////////////////////////////////////////
+
+VOID RTMPIoctlGetSiteSurvey(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq);
+
+
+
+
+
+#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);
+
+
+VOID    RTMPSetDesiredRates(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  LONG            Rates);
+#endif // CONFIG_STA_SUPPORT //
+
+INT	Set_FixedTxMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+INT	Set_OpMode_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+INT Set_LongRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PSTRING			arg);
+
+INT Set_ShortRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PSTRING			arg);
+
+BOOLEAN RT28XXChipsetCheck(
+	IN void *_dev_p);
+
+
+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_init(
+	IN PRTMP_ADAPTER pAd,
+	IN PSTRING pDefaultMac,
+	IN PSTRING pHostName);
+
+BOOLEAN RT28XXSecurityKeyAdd(
+	IN		PRTMP_ADAPTER		pAd,
+	IN		ULONG				apidx,
+	IN		ULONG				KeyIdx,
+	IN		MAC_TABLE_ENTRY		*pEntry);
+
+NDIS_STATUS RtmpNetTaskInit(
+	IN RTMP_ADAPTER *pAd);
+
+VOID RtmpNetTaskExit(
+	IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS RtmpMgmtTaskInit(
+	IN RTMP_ADAPTER *pAd);
+
+VOID RtmpMgmtTaskExit(
+	IN RTMP_ADAPTER *pAd);
+
+void tbtt_tasklet(unsigned long data);
+
+
+PNET_DEV RtmpPhyNetDevInit(
+	IN RTMP_ADAPTER *pAd,
+	IN RTMP_OS_NETDEV_OP_HOOK *pNetHook);
+
+BOOLEAN RtmpPhyNetDevExit(
+	IN RTMP_ADAPTER *pAd,
+	IN PNET_DEV net_dev);
+
+INT RtmpRaDevCtrlInit(
+	IN RTMP_ADAPTER *pAd,
+	IN RTMP_INF_TYPE infType);
+
+BOOLEAN RtmpRaDevCtrlExit(
+	IN RTMP_ADAPTER *pAd);
+
+
+#ifdef RTMP_MAC_PCI
+//
+// Function Prototype in cmm_data_pci.c
+//
+USHORT RtmpPCI_WriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber);
+
+USHORT RtmpPCI_WriteSingleTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber);
+
+USHORT RtmpPCI_WriteMultiTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			frameNum,
+	OUT	USHORT			*FreeNumber);
+
+USHORT	RtmpPCI_WriteFragTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			fragNum,
+	OUT	USHORT			*FreeNumber);
+
+USHORT RtmpPCI_WriteSubTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	BOOLEAN			bIsLast,
+	OUT	USHORT			*FreeNumber);
+
+VOID RtmpPCI_FinalWriteTxResource(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	USHORT			totalMPDUSize,
+	IN	USHORT			FirstTxIdx);
+
+VOID RtmpPCIDataLastTxIdx(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	UCHAR			QueIdx,
+	IN	USHORT			LastTxIdx);
+
+VOID RtmpPCIDataKickOut(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	TX_BLK			*pTxBlk,
+	IN	UCHAR			QueIdx);
+
+
+int RtmpPCIMgmtKickOut(
+	IN RTMP_ADAPTER		*pAd,
+	IN UCHAR			QueIdx,
+	IN PNDIS_PACKET		pPacket,
+	IN PUCHAR			pSrcBufVA,
+	IN UINT				SrcBufLen);
+
+
+NDIS_STATUS RTMPCheckRxError(
+	IN  PRTMP_ADAPTER   pAd,
+	IN  PHEADER_802_11  pHeader,
+	IN	PRXWI_STRUC	pRxWI,
+	IN  PRT28XX_RXD_STRUC      pRxD);
+
+BOOLEAN RT28xxPciAsicRadioOff(
+	IN PRTMP_ADAPTER    pAd,
+	IN UCHAR            Level,
+	IN USHORT           TbttNumToNextWakeUp);
+
+BOOLEAN RT28xxPciAsicRadioOn(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR     Level);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPInitPCIeLinkCtrlValue(
+	IN	PRTMP_ADAPTER	pAd);
+
+VOID RTMPFindHostPCIDev(
+    IN	PRTMP_ADAPTER	pAd);
+
+VOID RTMPPCIeLinkCtrlValueRestore(
+	IN	PRTMP_ADAPTER	pAd,
+	IN   UCHAR		Level);
+
+VOID RTMPPCIeLinkCtrlSetting(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	USHORT		Max);
+
+VOID RTMPrt3xSetPCIePowerLinkCtrl(
+	IN	PRTMP_ADAPTER	pAd);
+
+
+VOID RT28xxPciStaAsicForceWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN BOOLEAN       bFromTx);
+
+VOID RT28xxPciStaAsicSleepThenAutoWakeup(
+	IN PRTMP_ADAPTER pAd,
+	IN USHORT TbttNumToNextWakeUp);
+
+VOID PsPollWakeExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+
+VOID  RadioOnExec(
+	IN PVOID SystemSpecific1,
+	IN PVOID FunctionContext,
+	IN PVOID SystemSpecific2,
+	IN PVOID SystemSpecific3);
+#endif // CONFIG_STA_SUPPORT //
+
+VOID RT28xxPciMlmeRadioOn(
+	IN PRTMP_ADAPTER pAd);
+
+VOID RT28xxPciMlmeRadioOFF(
+	IN PRTMP_ADAPTER pAd);
+#endif // RTMP_MAC_PCI //
+
+VOID AsicTurnOffRFClk(
+	IN PRTMP_ADAPTER    pAd,
+	IN	UCHAR           Channel);
+
+VOID AsicTurnOnRFClk(
+	IN PRTMP_ADAPTER	pAd,
+	IN	UCHAR			Channel);
+
+
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+INT RtmpTimerQThread(
+	IN OUT PVOID Context);
+
+RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer);
+
+BOOLEAN RtmpTimerQRemove(
+	IN RTMP_ADAPTER *pAd,
+	IN RALINK_TIMER_STRUCT *pTimer);
+
+void RtmpTimerQExit(
+	IN RTMP_ADAPTER *pAd);
+
+void RtmpTimerQInit(
+	IN RTMP_ADAPTER *pAd);
+#endif // RTMP_TIMER_TASK_SUPPORT //
+
+
+
+////////////////////////////////////////
+
+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	PSTRING			pName,
+	IN	PSTRING			pBuf);
+
+PSTRING RTMPGetRalinkAuthModeStr(
+    IN  NDIS_802_11_AUTHENTICATION_MODE authMode);
+
+PSTRING 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  ADD_HT_INFO_IE		*pAddHtInfo,
+	IN  UCHAR				AddHtInfoLen,
+	IN  USHORT			CapabilityInfo);
+
+
+BOOLEAN	AUTH_ReqSend(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PMLME_QUEUE_ELEM	pElem,
+	IN  PRALINK_TIMER_STRUCT pAuthTimer,
+	IN  PSTRING				pSMName,
+	IN  USHORT				SeqNo,
+	IN  PUCHAR				pNewElement,
+	IN  ULONG				ElementLen);
+#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);
+
+
+#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
+#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
+#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
+
+
+#ifdef LINUX
+__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
+{
+	if (VIRTUAL_IF_NUM(pAd) == 0)
+	{
+		if (rt28xx_open(pAd->net_dev) != 0)
+		{
+			DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_open return fail!\n"));
+			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 // LINUX //
+
+
+
+
+/*
+	OS Related funciton prototype definitions.
+	TODO: Maybe we need to move these function prototypes to other proper place.
+*/
+int RtmpOSWrielessEventSend(
+	IN RTMP_ADAPTER *pAd,
+	IN UINT32		eventType,
+	IN INT			flags,
+	IN PUCHAR		pSrcMac,
+	IN PUCHAR		pData,
+	IN UINT32		dataLen);
+
+int RtmpOSNetDevAddrSet(
+	IN PNET_DEV pNetDev,
+	IN PUCHAR	pMacAddr);
+
+int RtmpOSNetDevAttach(
+	IN PNET_DEV pNetDev,
+	IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook);
+
+void RtmpOSNetDevClose(
+	IN PNET_DEV pNetDev);
+
+void RtmpOSNetDevDetach(
+	IN PNET_DEV pNetDev);
+
+INT RtmpOSNetDevAlloc(
+	IN PNET_DEV *pNewNetDev,
+	IN UINT32	privDataSize);
+
+void RtmpOSNetDevFree(
+	IN PNET_DEV pNetDev);
+
+PNET_DEV RtmpOSNetDevGetByName(
+	IN PNET_DEV pNetDev,
+	IN PSTRING	pDevName);
+
+void RtmpOSNetDeviceRefPut(
+	IN PNET_DEV pNetDev);
+
+PNET_DEV RtmpOSNetDevCreate(
+	IN RTMP_ADAPTER *pAd,
+	IN INT			devType,
+	IN INT			devNum,
+	IN INT			privMemSize,
+	IN PSTRING		pNamePrefix);
+
+/*
+	Task operation related function prototypes
+*/
+void RtmpOSTaskCustomize(
+	IN RTMP_OS_TASK *pTask);
+
+INT RtmpOSTaskNotifyToExit(
+	IN RTMP_OS_TASK *pTask);
+
+NDIS_STATUS RtmpOSTaskKill(
+	IN RTMP_OS_TASK *pTask);
+
+NDIS_STATUS RtmpOSTaskInit(
+	IN RTMP_OS_TASK *pTask,
+	PSTRING			 pTaskName,
+	VOID			 *pPriv);
+
+NDIS_STATUS RtmpOSTaskAttach(
+	IN RTMP_OS_TASK *pTask,
+	IN int (*fn)(void *),
+	IN void *arg);
+
+
+/*
+	File operation related function prototypes
+*/
+RTMP_OS_FD RtmpOSFileOpen(
+	IN char *pPath,
+	IN int flag,
+	IN int mode);
+
+int RtmpOSFileClose(
+	IN RTMP_OS_FD osfd);
+
+void RtmpOSFileSeek(
+	IN RTMP_OS_FD osfd,
+	IN int offset);
+
+int RtmpOSFileRead(
+	IN RTMP_OS_FD osfd,
+	IN char *pDataPtr,
+	IN int readLen);
+
+int RtmpOSFileWrite(
+	IN RTMP_OS_FD osfd,
+	IN char *pDataPtr,
+	IN int writeLen);
+
+void RtmpOSFSInfoChange(
+	IN RTMP_OS_FS_INFO *pOSFSInfo,
+	IN BOOLEAN bSet);
+
+
+#endif  // __RTMP_H__
diff --git a/drivers/staging/rt3090/rtmp_chip.h b/drivers/staging/rt3090/rtmp_chip.h
new file mode 100644
index 0000000..a0b4bf0
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_chip.h
@@ -0,0 +1,355 @@
+/*
+ *************************************************************************
+ * 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_chip.h
+
+	Abstract:
+	Ralink Wireless Chip related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef	__RTMP_CHIP_H__
+#define	__RTMP_CHIP_H__
+
+#include "rtmp_type.h"
+
+#ifdef RT3090
+#include "rt3090.h"
+#endif // RT3090 //
+
+#ifdef RT3370
+#include "rt3370.h"
+#endif // RT3370 //
+
+#ifdef RT3390
+#include "rt3390.h"
+#endif // RT3390 //
+
+// We will have a cost down version which mac version is 0x3090xxxx
+//
+// RT3090A facts
+//
+// a) 2.4 GHz
+// b) Replacement for RT3090
+// c) Internal LNA
+// d) Interference over channel #14
+// e) New BBP features (e.g., SIG re-modulation)
+//
+#define IS_RT3090A(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
+
+// We will have a cost down version which mac version is 0x3090xxxx
+#define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd)))
+
+#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||IS_RT3090A(_pAd))
+//#define IS_RT305X(_pAd)		((_pAd)->MACVersion == 0x28720200)
+
+/* RT3572, 3592, 3562, 3062 share the same MAC version */
+#define IS_RT3572(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x35720000)
+#define IS_VERSION_BEFORE_F(_pAd)			(((_pAd)->MACVersion&0xffff) <= 0x0211)
+// F version is 0x0212, E version is 0x0211. 309x can save more power after F version.
+#define IS_VERSION_AFTER_F(_pAd)			((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE)))
+//
+// RT3390 facts
+//
+// a) Base on RT3090 (RF IC: RT3020)
+// b) 2.4 GHz
+// c) 1x1
+// d) Single chip
+// e) Internal components: PA and LNA
+//
+//RT3390,RT3370
+#define IS_RT3390(_pAd)				(((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000)
+
+// ------------------------------------------------------
+// PCI registers - base address 0x0000
+// ------------------------------------------------------
+#define CHIP_PCI_CFG		0x0000
+#define CHIP_PCI_EECTRL		0x0004
+#define CHIP_PCI_MCUCTRL	0x0008
+
+#define OPT_14			0x114
+
+#define RETRY_LIMIT		10
+
+
+
+// ------------------------------------------------------
+// BBP & RF	definition
+// ------------------------------------------------------
+#define	BUSY		                1
+#define	IDLE		                0
+
+
+//-------------------------------------------------------------------------
+// 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_TXMIXER_GAIN_2_4G	0x48
+#define EEPROM_RSSI_A_OFFSET		0x4a
+#define EEPROM_TXMIXER_GAIN_5G		0x4c
+#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
+
+
+/*
+  *   EEPROM operation related marcos
+  */
+#define RT28xx_EEPROM_READ16(_pAd, _offset, _value)			\
+	(_pAd)->chipOps.eeread((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (PUSHORT)&(_value))
+
+#define RT28xx_EEPROM_WRITE16(_pAd, _offset, _value)		\
+	(_pAd)->chipOps.eewrite((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (USHORT)(_value))
+
+
+
+// -------------------------------------------------------------------
+//  E2PROM data layout
+// -------------------------------------------------------------------
+
+//
+// MCU_LEDCS: MCU LED Control Setting.
+//
+typedef union  _MCU_LEDCS_STRUC {
+	struct	{
+#ifdef RT_BIG_ENDIAN
+		UCHAR		Polarity:1;
+		UCHAR		LedMode:7;
+#else
+		UCHAR		LedMode:7;
+		UCHAR		Polarity:1;
+#endif // RT_BIG_ENDIAN //
+	} field;
+	UCHAR				word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+
+
+//
+// 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
+
+#endif	// __RTMP_CHIP_H__ //
diff --git a/drivers/staging/rt3090/rtmp_def.h b/drivers/staging/rt3090/rtmp_def.h
new file mode 100644
index 0000000..aeb739d
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_def.h
@@ -0,0 +1,1650 @@
+/*
+ *************************************************************************
+ * 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)
+
+#define MAX_RX_PKT_LEN	1520
+
+//
+// Entry number for each DMA descriptor ring
+//
+
+#ifdef RTMP_MAC_PCI
+#define TX_RING_SIZE            64 //64
+#define MGMT_RING_SIZE          128
+#define RX_RING_SIZE            128 //64
+#define MAX_TX_PROCESS          TX_RING_SIZE //8
+#define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
+#define MAX_TX_DONE_PROCESS     TX_RING_SIZE //8
+#define LOCAL_TXBUF_SIZE        2
+#endif // RTMP_MAC_PCI //
+
+#define PCI_VIRT_TO_PHYS(__Addr)	(((UINT32)(__Addr)) & 0x0FFFFFFF)
+
+
+#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)
+
+
+/*
+	WMM Note: If memory of your system is not much, please reduce the definition;
+	or when you do WMM test, the queue for low priority AC will be full, i.e.
+	TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in
+	WLAN, maybe no any packet buffer can be got in Ethernet driver.
+
+	Sometimes no packet buffer can be got in Ethernet driver, the system will
+	send flow control packet to the sender to slow down its sending rate.
+	So no WMM can be saw in the air.
+*/
+
+/*
+	Need to use 64 in vxworks for test case WMM A5-T07
+	Two dnlink (10Mbps) from a WMM station to a non-WMM station.
+	If use 256, queue is not enough.
+	And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to
+	clConfig.clNum = RX_RING_SIZE * 4;
+*/
+// TODO: For VxWorks the size is 256. Shall we cahnge the value as 256 for all OS?????
+#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 */
+
+
+#ifdef RTMP_EFUSE_SUPPORT
+//2008/09/11:KH add to support efuse<--
+#define MAX_EEPROM_BIN_FILE_SIZE				1024
+#define EFUSE_BUFFER_PATH						"/tmp/RT30xxEEPROM.bin"
+//2008/09/11:KH add to support efuse-->
+#endif // RTMP_EFUSE_SUPPORT //
+
+// RxFilter
+#define STANORMAL	 0x17f97
+#define APNORMAL	 0x15f97
+#define PSPXLINK	 0x17f93
+//
+//  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_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
+#define fRTMP_PS_TOGGLE_L1		0x00000010	// Use Toggle L1 mechanism for rt28xx PCIe
+#ifdef RT3090
+#define WAKE_MCU_CMD				0x31
+#define SLEEP_MCU_CMD					0x30
+#define RFOFF_MCU_CMD				0x35
+#endif // RT3090 //
+#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	// rt2860c has problem with atheros chip. we need to turn on RTS/CTS .
+#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
+#define fRX_FILTER_ACCEPT_PROMISCUOUS       NDIS_PACKET_TYPE_PROMISCUOUS
+
+//
+// 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
+#ifdef APCLI_SUPPORT
+#undef	MAX_APCLI_NUM
+#define MAX_APCLI_NUM				1
+#endif // APCLI_SUPPORT //
+
+#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) { \
+          DBGPRINT(RT_DEBUG_ERROR, ("%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_NUM_OF_REGULATORY_CLASS		16
+#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
+#define MAX_NUM_OF_BBP_LATCH             140
+//============================================================
+// 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_INVALID_GROUP_CIPHER	  41
+#define MLME_INVALID_PAIRWISE_CIPHER	  42
+#define MLME_INVALID_AKMP			  43
+#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_SYNC_STATE_MACHINE           14
+#define AP_CNTL_STATE_MACHINE           15
+#define WSC_STATE_MACHINE            17
+#define WSC_UPNP_STATE_MACHINE		    18
+
+
+#define WPA_STATE_MACHINE			23
+
+
+#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
+
+#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_FT_OTD_CONF					46
+#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
+/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */
+#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)
+
+//
+// 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 APMT2_PEER_DEAUTH				2
+#define APMT2_PEER_AUTH_REQ				3
+#define APMT2_PEER_AUTH_CONFIRM			4
+#define AP_MAX_AUTH_MSG                 5
+
+#define AP_AUTH_FUNC_SIZE               (AP_MAX_AUTH_STATE * AP_MAX_AUTH_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)
+
+//
+// Common WPA state machine: states, events, total function #
+//
+#define WPA_PTK                      0
+#define MAX_WPA_PTK_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_MSG                  5
+
+#define WPA_FUNC_SIZE                (MAX_WPA_PTK_STATE * MAX_WPA_MSG)
+
+#ifdef APCLI_SUPPORT
+//ApCli authentication state machine
+#define APCLI_AUTH_REQ_IDLE                0
+#define APCLI_AUTH_WAIT_SEQ2               1
+#define APCLI_AUTH_WAIT_SEQ4               2
+#define APCLI_MAX_AUTH_STATE               3
+
+#define APCLI_AUTH_MACHINE_BASE            0
+#define APCLI_MT2_MLME_AUTH_REQ            0
+#define APCLI_MT2_MLME_DEAUTH_REQ          1
+#define APCLI_MT2_PEER_AUTH_EVEN           2
+#define APCLI_MT2_PEER_DEAUTH              3
+#define APCLI_MT2_AUTH_TIMEOUT             4
+#define APCLI_MAX_AUTH_MSG                 5
+
+#define APCLI_AUTH_FUNC_SIZE               (APCLI_MAX_AUTH_STATE * APCLI_MAX_AUTH_MSG)
+
+//ApCli association state machine
+#define APCLI_ASSOC_IDLE                   0
+#define APCLI_ASSOC_WAIT_RSP               1
+#define APCLI_MAX_ASSOC_STATE              2
+
+#define APCLI_ASSOC_MACHINE_BASE           0
+#define APCLI_MT2_MLME_ASSOC_REQ           0
+#define APCLI_MT2_MLME_DISASSOC_REQ        1
+#define APCLI_MT2_PEER_DISASSOC_REQ        2
+#define APCLI_MT2_PEER_ASSOC_RSP           3
+#define APCLI_MT2_ASSOC_TIMEOUT            4
+#define APCLI_MAX_ASSOC_MSG                5
+
+#define APCLI_ASSOC_FUNC_SIZE              (APCLI_MAX_ASSOC_STATE * APCLI_MAX_ASSOC_MSG)
+
+//ApCli sync state machine
+#define APCLI_SYNC_IDLE                   0  // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
+#define APCLI_JOIN_WAIT_PROBE_RSP         1
+#define APCLI_MAX_SYNC_STATE              2
+
+#define APCLI_SYNC_MACHINE_BASE           0
+#define APCLI_MT2_MLME_PROBE_REQ          0
+#define APCLI_MT2_PEER_PROBE_RSP          1
+#define APCLI_MT2_PROBE_TIMEOUT           2
+#define APCLI_MAX_SYNC_MSG                3
+
+#define APCLI_SYNC_FUNC_SIZE              (APCLI_MAX_SYNC_STATE * APCLI_MAX_SYNC_MSG)
+
+//ApCli ctrl state machine
+#define APCLI_CTRL_DISCONNECTED           0  // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
+#define APCLI_CTRL_PROBE                  1
+#define APCLI_CTRL_AUTH                   2
+#define APCLI_CTRL_AUTH_2                 3
+#define APCLI_CTRL_ASSOC                  4
+#define APCLI_CTRL_DEASSOC                5
+#define APCLI_CTRL_CONNECTED              6
+#define APCLI_MAX_CTRL_STATE              7
+
+#define APCLI_CTRL_MACHINE_BASE           0
+#define APCLI_CTRL_JOIN_REQ               0
+#define APCLI_CTRL_PROBE_RSP              1
+#define APCLI_CTRL_AUTH_RSP               2
+#define APCLI_CTRL_DISCONNECT_REQ         3
+#define APCLI_CTRL_PEER_DISCONNECT_REQ    4
+#define APCLI_CTRL_ASSOC_RSP              5
+#define APCLI_CTRL_DEASSOC_RSP            6
+#define APCLI_CTRL_JOIN_REQ_TIMEOUT       7
+#define APCLI_CTRL_AUTH_REQ_TIMEOUT       8
+#define APCLI_CTRL_ASSOC_REQ_TIMEOUT      9
+#define APCLI_MAX_CTRL_MSG                10
+
+#define APCLI_CTRL_FUNC_SIZE              (APCLI_MAX_CTRL_STATE * APCLI_MAX_CTRL_MSG)
+
+
+#endif // APCLI_SUPPORT //
+
+
+// =============================================================================
+
+// 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, 169, 173
+#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_12_A_BAND                  12       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
+#define REGION_13_A_BAND                  13       // 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161
+#define REGION_14_A_BAND                  14       // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165
+#define REGION_15_A_BAND                  15       // 149, 153, 157, 161, 165, 169, 173
+#define REGION_MAXIMUM_A_BAND             15
+
+// 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
+
+
+// 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
+#define LED_MODE_SIGNAL_STREGTH		0x40 // EEPROM define = 64
+
+// 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
+
+#define INF_MAIN_DEV_NAME		"wlan"
+#define INF_MBSSID_DEV_NAME		"wlan"
+#define INF_WDS_DEV_NAME		"wds"
+#define INF_APCLI_DEV_NAME		"apcli"
+#define INF_MESH_DEV_NAME		"mesh"
+
+// 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, kathy
+#define MAX_TX_REORDERBUF		64
+#define MAX_RX_REORDERBUF		64
+#define DEFAULT_TX_TIMEOUT		30
+#define DEFAULT_RX_TIMEOUT		30
+#define MAX_BARECI_SESSION		8
+
+#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
+
+// definition for Antenna Diversity flag
+#ifdef ANT_DIVERSITY_SUPPORT
+enum ANT_DIVERSITY_TYPE {
+    ANT_DIVERSITY_DISABLE = 0,
+    ANT_DIVERSITY_ENABLE = 1,
+    ANT_FIX_ANT1 = 2,
+    ANT_FIX_ANT2 = 3
+};
+#endif // ANT_DIVERSITY_SUPPORT //
+
+// 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
+
+#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x))
+
+
+#define A2Dec(_X, _p)				\
+{									\
+	UCHAR *p;						\
+	_X = 0;							\
+	p = _p;							\
+	while (((*p >= '0') && (*p <= '9')))		\
+	{												\
+		if ((*p >= '0') && (*p <= '9'))		\
+			_X = _X * 10 + *p - 48;					\
+		p++;										\
+	}												\
+}
+
+
+#define A2Hex(_X, _p)				\
+do{									\
+	char *__p;						\
+	(_X) = 0;							\
+	__p = (char *)(_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++;										\
+	}												\
+}while(0)
+
+#endif  // __RTMP_DEF_H__
diff --git a/drivers/staging/rt3090/rtmp_dot11.h b/drivers/staging/rt3090/rtmp_dot11.h
new file mode 100644
index 0000000..a637825
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_dot11.h
@@ -0,0 +1,146 @@
+/*
+ *************************************************************************
+ * 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 __DOT11_BASE_H__
+#define __DOT11_BASE_H__
+
+#include "rtmp_type.h"
+
+
+// 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 _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;
+
+#endif // __DOT11_BASE_H__ //
diff --git a/drivers/staging/rt3090/rtmp_iface.h b/drivers/staging/rt3090/rtmp_iface.h
new file mode 100644
index 0000000..168d079
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_iface.h
@@ -0,0 +1,81 @@
+/*
+ *************************************************************************
+ * 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_iface.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+#ifndef __RTMP_IFACE_H__
+#define __RTMP_IFACE_H__
+
+#ifdef RTMP_PCI_SUPPORT
+#include "rtmp_pci.h"
+#endif // RTMP_PCI_SUPPORT //
+
+
+typedef struct _INF_PCI_CONFIG_
+{
+	unsigned long	CSRBaseAddress;     // PCI MMIO Base Address, all access will use
+	unsigned int	irq_num;
+}INF_PCI_CONFIG;
+
+
+typedef struct _INF_USB_CONFIG_
+{
+	UINT8                BulkInEpAddr;		// bulk-in endpoint address
+	UINT8                BulkOutEpAddr[6];	// bulk-out endpoint address
+}INF_USB_CONFIG;
+
+
+typedef struct _INF_RBUS_CONFIG_
+{
+	unsigned long		csr_addr;
+	unsigned int		irq;
+}INF_RBUS_CONFIG;
+
+
+typedef enum _RTMP_INF_TYPE_
+{
+	RTMP_DEV_INF_UNKNOWN = 0,
+	RTMP_DEV_INF_PCI = 1,
+	RTMP_DEV_INF_USB = 2,
+	RTMP_DEV_INF_RBUS = 4,
+}RTMP_INF_TYPE;
+
+
+typedef union _RTMP_INF_CONFIG_{
+	struct _INF_PCI_CONFIG_			pciConfig;
+	struct _INF_USB_CONFIG_			usbConfig;
+	struct _INF_RBUS_CONFIG_		rbusConfig;
+}RTMP_INF_CONFIG;
+
+#endif // __RTMP_IFACE_H__ //
diff --git a/drivers/staging/rt3090/rtmp_mac.h b/drivers/staging/rt3090/rtmp_mac.h
new file mode 100644
index 0000000..c57b295
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_mac.h
@@ -0,0 +1,2304 @@
+/*
+ *************************************************************************
+ * 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_mac.h
+
+	Abstract:
+	Ralink Wireless Chip MAC related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef __RTMP_MAC_H__
+#define __RTMP_MAC_H__
+
+
+
+// =================================================================================
+// 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
+
+
+//
+// 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
+	// ex: 00 03 00 40 means txop = 3, PHYMODE = 1
+	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;
+	// Word1
+	// ex:  1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38
+	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
+
+
+//
+// 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		rsv2:8;
+	UINT32		FOFFSET:8;	// RT35xx
+	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		FOFFSET:8;	// RT35xx
+	UINT32		rsv2:8;
+	/*UINT32		rsv2:16;*/
+}	RXWI_STRUC, *PRXWI_STRUC;
+#endif
+
+
+// =================================================================================
+// Register format
+// =================================================================================
+
+
+//
+// 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	{
+#ifdef TONE_RADAR_DETECT_SUPPORT
+		UINT32			:11;
+		UINT32			RadarINT:1;
+		UINT32		rsv:2;
+#else // original source code
+		UINT32		:14;
+#endif // TONE_RADAR_DETECT_SUPPORT //
+		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;
+#ifdef TONE_RADAR_DETECT_SUPPORT
+		UINT32		rsv:2;
+		UINT32			RadarINT:1;
+		UINT32			:11;
+#else
+		UINT32		:14;
+#endif // TONE_RADAR_DETECT_SUPPORT //
+	}	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;
+#ifdef TONE_RADAR_DETECT_SUPPORT
+		UINT32			:9;
+		UINT32			RadarINT:1;
+		UINT32		rsv:10;
+#else
+		UINT32		:20;
+#endif // TONE_RADAR_DETECT_SUPPORT //
+		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;
+#ifdef TONE_RADAR_DETECT_SUPPORT
+		UINT32		rsv:10;
+		UINT32			RadarINT:1;
+		UINT32			:9;
+#else
+		UINT32		:20;
+#endif // TONE_RADAR_DETECT_SUPPORT //
+		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
+
+#ifdef RT30xx
+#ifdef RTMP_EFUSE_SUPPORT
+// eFuse registers
+#define EFUSE_CTRL				0x0580
+#define EFUSE_DATA0				0x0590
+#define EFUSE_DATA1				0x0594
+#define EFUSE_DATA2				0x0598
+#define EFUSE_DATA3				0x059c
+#endif // RTMP_EFUSE_SUPPORT //
+#endif // RT30xx //
+
+#define OSC_CTRL		0x5a4
+#define PCIE_PHY_TX_ATTENUATION_CTRL	0x05C8
+#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;
+
+
+// =================================================================================
+// 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
+
+
+// =================================================================================
+// 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
+
+
+//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
+
+//
+// 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
+
+
+//
+// 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
+
+
+
+// ================================================================
+// 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 NUM_OF_TX_RING          4
+#define QID_MGMT                13
+#define QID_RX                  14
+#define QID_OTHER               15
+
+#endif // __RTMP_MAC_H__ //
diff --git a/drivers/staging/rt3090/rtmp_mcu.h b/drivers/staging/rt3090/rtmp_mcu.h
new file mode 100644
index 0000000..e1b2fee
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_mcu.h
@@ -0,0 +1,55 @@
+/*
+ *************************************************************************
+ * 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_mcu.h
+
+	Abstract:
+	Miniport header file for mcu related information
+
+	Revision History:
+	Who         When          What
+	--------    ----------    ----------------------------------------------
+*/
+
+#ifndef __RTMP_MCU_H__
+#define __RTMP_MCU_H__
+
+
+INT RtmpAsicEraseFirmware(
+	IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS RtmpAsicLoadFirmware(
+	IN PRTMP_ADAPTER pAd);
+
+INT RtmpAsicSendCommandToMcu(
+	IN PRTMP_ADAPTER pAd,
+	IN UCHAR		 Command,
+	IN UCHAR		 Token,
+	IN UCHAR		 Arg0,
+	IN UCHAR		 Arg1);
+
+#endif // __RTMP_MCU_H__ //
diff --git a/drivers/staging/rt3090/rtmp_os.h b/drivers/staging/rt3090/rtmp_os.h
new file mode 100644
index 0000000..5646b2d
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_os.h
@@ -0,0 +1,93 @@
+/*
+ *************************************************************************
+ * 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_os.h
+
+    Abstract:
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+ */
+
+
+#ifndef __RTMP_OS_H__
+#define __RTMP_OS_H__
+
+#ifdef LINUX
+#include "rt_linux.h"
+#endif // LINUX //
+
+
+/*
+	This data structure mainly strip some callback function defined in
+	"struct net_device" in kernel source "include/linux/netdevice.h".
+
+	The definition of this data structure may various depends on different
+	OS. Use it carefully.
+*/
+typedef struct _RTMP_OS_NETDEV_OP_HOOK_
+{
+	const struct net_device_ops *netdev_ops;
+	void			*priv;
+	int			priv_flags;
+	unsigned char devAddr[6];
+	unsigned char	devName[16];
+	unsigned char	needProtcted;
+}RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK;
+
+
+typedef enum _RTMP_TASK_STATUS_
+{
+	RTMP_TASK_STAT_UNKNOWN = 0,
+	RTMP_TASK_STAT_INITED = 1,
+	RTMP_TASK_STAT_RUNNING = 2,
+	RTMP_TASK_STAT_STOPED = 4,
+}RTMP_TASK_STATUS;
+#define RTMP_TASK_CAN_DO_INSERT		(RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING)
+
+#define RTMP_OS_TASK_NAME_LEN	16
+typedef struct _RTMP_OS_TASK_
+{
+	char					taskName[RTMP_OS_TASK_NAME_LEN];
+	void					*priv;
+	//unsigned long		taskFlags;
+	RTMP_TASK_STATUS	taskStatus;
+#ifndef KTHREAD_SUPPORT
+	RTMP_OS_SEM			taskSema;
+	RTMP_OS_PID			taskPID;
+	struct completion		taskComplete;
+#endif
+	unsigned char			task_killed;
+#ifdef KTHREAD_SUPPORT
+	struct task_struct	*kthread_task;
+	wait_queue_head_t		kthread_q;
+	BOOLEAN					kthread_running;
+#endif
+}RTMP_OS_TASK;
+
+#endif // __RMTP_OS_H__ //
diff --git a/drivers/staging/rt3090/rtmp_pci.h b/drivers/staging/rt3090/rtmp_pci.h
new file mode 100644
index 0000000..c2fed29
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_pci.h
@@ -0,0 +1,110 @@
+/*
+ *************************************************************************
+ * 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 __RTMP_PCI_H__
+#define __RTMP_PCI_H__
+
+#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)				\
+	((POS_COOKIE)handle)->pci_dev = dev_p;
+
+
+#ifdef LINUX
+// set driver data
+#define RT28XX_DRVDATA_SET(_a)			pci_set_drvdata(_a, net_dev);
+
+#define RT28XX_PUT_DEVICE(dev_p)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#define SA_SHIRQ IRQF_SHARED
+#endif
+
+#ifdef PCI_MSI_SUPPORT
+#define RTMP_MSI_ENABLE(_pAd) \
+{	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
+	(_pAd)->HaveMsi =	pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; }
+
+#define RTMP_MSI_DISABLE(_pAd) \
+{	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
+	if (_pAd->HaveMsi == TRUE) \
+		pci_disable_msi(_pObj->pci_dev); \
+	_pAd->HaveMsi = FALSE;	}
+#else
+#define RTMP_MSI_ENABLE(_pAd)
+#define RTMP_MSI_DISABLE(_pAd)
+#endif // PCI_MSI_SUPPORT //
+
+
+#define RTMP_PCI_DEV_UNMAP()										\
+{	if (net_dev->base_addr)	{								\
+		iounmap((void *)(net_dev->base_addr));				\
+		release_mem_region(pci_resource_start(dev_p, 0),	\
+							pci_resource_len(dev_p, 0)); }	\
+	if (net_dev->irq) pci_release_regions(dev_p); }
+
+
+#define RTMP_IRQ_REQUEST(net_dev)							\
+{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));	\
+	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);		\
+	RTMP_MSI_ENABLE(_pAd);									\
+	if ((retval = request_irq(_pObj->pci_dev->irq,		\
+							rt2860_interrupt, SA_SHIRQ,		\
+							(net_dev)->name, (net_dev)))) {	\
+		DBGPRINT(RT_DEBUG_ERROR, ("request_irq  error(%d)\n", retval));	\
+	return retval; } }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RTMP_IRQ_RELEASE(net_dev)								\
+{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));		\
+	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 RTMP_IRQ_RELEASE(net_dev)								\
+{	PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)(RTMP_OS_NETDEV_GET_PRIV(net_dev));		\
+	POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie);			\
+	free_irq(_pObj->pci_dev->irq, (net_dev));					\
+	RTMP_MSI_DISABLE(_pAd); }
+#endif
+
+#define PCI_REG_READ_WORD(pci_dev, offset, Configuration)   \
+    if (pci_read_config_word(pci_dev, offset, &reg16) == 0)     \
+        Configuration = le2cpu16(reg16);                        \
+    else                                                        \
+        Configuration = 0;
+
+#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration)  \
+    reg16 = cpu2le16(Configuration);                        \
+    pci_write_config_word(pci_dev, offset, reg16);          \
+
+#endif // LINUX //
+
+
+
+
+#endif // __RTMP_PCI_H__ //
diff --git a/drivers/staging/rt3090/rtmp_phy.h b/drivers/staging/rt3090/rtmp_phy.h
new file mode 100644
index 0000000..b9848ca
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_phy.h
@@ -0,0 +1,631 @@
+/*
+ *************************************************************************
+ * 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_phy.h
+
+	Abstract:
+	Ralink Wireless Chip PHY(BBP/RF) related definition & structures
+
+	Revision History:
+	Who			When		  What
+	--------	----------	  ----------------------------------------------
+*/
+
+#ifndef __RTMP_PHY_H__
+#define __RTMP_PHY_H__
+
+
+/*
+	RF sections
+*/
+#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
+
+
+// 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
+#define RFIC_3052                   9       // 2.4G/5G 2T2R
+
+/*
+	BBP sections
+*/
+#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_R26			26
+#define BBP_R27			27
+#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_R78			78
+#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_R106		106
+#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
+
+
+#ifdef MERGE_ARCH_TEAM
+	#define MAX_BBP_ID	200
+	#define MAX_BBP_MSG_SIZE	4096
+#else
+#ifdef RT30xx
+	// edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+	#define MAX_BBP_ID	138
+#endif // RT30xx //
+#ifndef RT30xx
+	#define MAX_BBP_ID	136
+#endif // RT30xx //
+	#define MAX_BBP_MSG_SIZE	2048
+#endif // MERGE_ARCH_TEAM //
+
+
+//
+// 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
+
+//#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
+
+/*****************************************************************************
+	RF register Read/Write marco definition
+ *****************************************************************************/
+#ifdef RTMP_MAC_PCI
+#define RTMP_RF_IO_WRITE32(_A, _V)                  \
+{											\
+	if ((_A)->bPCIclkOff == FALSE)	                \
+	{												\
+		PHY_CSR4_STRUC  _value;                          \
+		ULONG           _busyCnt = 0;                    \
+											\
+		do {                                            \
+			RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word);  \
+			if (_value.field.Busy == IDLE)               \
+				break;                                  \
+			_busyCnt++;                                  \
+		}while (_busyCnt < MAX_BUSY_COUNT);			\
+		if(_busyCnt < MAX_BUSY_COUNT)                   \
+		{                                               \
+			RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V));          \
+		}                                               \
+	}								\
+}
+#endif // RTMP_MAC_PCI //
+
+
+
+#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 //
+
+
+/*****************************************************************************
+	BBP register Read/Write marco definitions.
+	we read/write the bbp value by register's ID.
+	Generate PER to test BA
+ *****************************************************************************/
+#ifdef RTMP_MAC_PCI
+/*
+	basic marco for BBP read operation.
+	_pAd: the data structure pointer of RTMP_ADAPTER
+	_bbpID : the bbp register ID
+	_pV: data pointer used to save the value of queried bbp register.
+	_bViaMCU: if we need access the bbp via the MCU.
+*/
+#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU)			\
+	do{															\
+		BBP_CSR_CFG_STRUC  BbpCsr;								\
+		int   _busyCnt, _secCnt, _regID;						\
+																\
+		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
+		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)      \
+		{													\
+			RTMP_IO_READ32(_pAd, _regID, &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 = _bbpID;                       \
+			RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);     \
+			if ((_bViaMCU) == TRUE)							\
+			{													\
+				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
+				RTMPusecDelay(1000);	\
+			}							\
+			for (_secCnt=0; _secCnt<MAX_BUSY_COUNT; _secCnt++)       \
+			{                                               \
+				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
+				if (BbpCsr.field.Busy == IDLE)              \
+					break;                                  \
+			}                                               \
+			if ((BbpCsr.field.Busy == IDLE) &&              \
+				(BbpCsr.field.RegNum == _bbpID))                \
+			{                                               \
+				*(_pV) = (UCHAR)BbpCsr.field.Value;         \
+				break;                                      \
+			}                                               \
+		}                                                   \
+		if (BbpCsr.field.Busy == BUSY)                      \
+		{                                                   \
+			DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID));      \
+			*(_pV) = (_pAd)->BbpWriteLatch[_bbpID];               \
+			if ((_bViaMCU) == TRUE)				\
+			{									\
+				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);				\
+				BbpCsr.field.Busy = 0;                          \
+				RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);				\
+			}				\
+		}													\
+	}while(0)
+
+/*
+	This marco used for the BBP read operation which didn't need via MCU.
+*/
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
+	RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
+
+/*
+	This marco used for the BBP read operation which need via MCU.
+	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
+	will use this function too and didn't access the bbp register via the MCU.
+*/
+#ifndef CONFIG_STA_SUPPORT
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
+	do{														\
+		if ((_A)->bPCIclkOff == FALSE)							\
+		{													\
+			if ((_A)->infType == RTMP_DEV_INF_RBUS)			\
+				RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE);	\
+			else												\
+				RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE);	\
+		}													\
+	}while(0)
+#endif // CONFIG_STA_SUPPORT //
+#ifdef CONFIG_STA_SUPPORT
+// Read BBP register by register's ID. Generate PER to test BA
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)						\
+{																		\
+	BBP_CSR_CFG_STRUC	BbpCsr;											\
+	int					i, k;			\
+	BOOLEAN					brc;			\
+	BbpCsr.field.Busy = IDLE;			\
+	if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
+		&& ((_A)->bPCIclkOff == FALSE)	\
+		&& ((_A)->brt30xxBanMcuCmd == FALSE))	\
+	{																	\
+		for (i=0; i<MAX_BUSY_COUNT; i++)									\
+		{																	\
+			RTMP_IO_READ32(_A, 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 = _I;										\
+			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+			brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+			if (brc == TRUE)																\
+			{																\
+				for (k=0; k<MAX_BUSY_COUNT; k++)								\
+				{																\
+					RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);			\
+					if (BbpCsr.field.Busy == IDLE)								\
+						break;													\
+				}																\
+				if ((BbpCsr.field.Busy == IDLE) &&								\
+					(BbpCsr.field.RegNum == _I))								\
+				{																\
+					*(_pV) = (UCHAR)BbpCsr.field.Value;							\
+					break;														\
+				}																\
+			}																\
+			else																\
+			{																\
+				BbpCsr.field.Busy = 0;											\
+				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+			}																\
+		}																	\
+	}	\
+	else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
+		&& ((_A)->bPCIclkOff == FALSE))	\
+	{																	\
+		for (i=0; i<MAX_BUSY_COUNT; i++)									\
+		{																	\
+			RTMP_IO_READ32(_A, 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 = _I;										\
+			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+			AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+			for (k=0; k<MAX_BUSY_COUNT; k++)								\
+			{																\
+				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);			\
+				if (BbpCsr.field.Busy == IDLE)								\
+					break;													\
+			}																\
+			if ((BbpCsr.field.Busy == IDLE) &&								\
+				(BbpCsr.field.RegNum == _I))								\
+			{																\
+				*(_pV) = (UCHAR)BbpCsr.field.Value;							\
+				break;														\
+			}																\
+		}																	\
+	}																	\
+	else										\
+	{																	\
+		DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)));	\
+		*(_pV) = (_A)->BbpWriteLatch[_I];								\
+	}																	\
+	if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE))										\
+	{																	\
+		DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word));	\
+		*(_pV) = (_A)->BbpWriteLatch[_I];								\
+	}																	\
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+	basic marco for BBP write operation.
+	_pAd: the data structure pointer of RTMP_ADAPTER
+	_bbpID : the bbp register ID
+	_pV: data used to save the value of queried bbp register.
+	_bViaMCU: if we need access the bbp via the MCU.
+*/
+#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU)			\
+	do{															\
+		BBP_CSR_CFG_STRUC  BbpCsr;                             \
+		int             _busyCnt, _regID;							\
+																\
+		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
+		for (_busyCnt=0; _busyCnt<MAX_BUSY_COUNT; _busyCnt++)  \
+		{                                                   \
+			RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &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 = _pV;                        \
+			BbpCsr.field.RegNum = _bbpID;                       \
+			RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word);     \
+			if ((_bViaMCU) == TRUE)									\
+			{														\
+				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0);		\
+				if ((_pAd)->OpMode == OPMODE_AP)						\
+					RTMPusecDelay(1000);							\
+			}														\
+			(_pAd)->BbpWriteLatch[_bbpID] = _pV;					\
+			break;													\
+		}														\
+		if (_busyCnt == MAX_BUSY_COUNT)								\
+		{														\
+			DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID));				\
+			if((_bViaMCU) == TRUE)									\
+			{														\
+				RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word);	\
+				BbpCsr.field.Busy = 0;									\
+				RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word);	\
+			}														\
+		}														\
+	}while(0)
+
+
+/*
+	This marco used for the BBP write operation which didn't need via MCU.
+*/
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
+	RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
+
+/*
+	This marco used for the BBP write operation which need via MCU.
+	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
+	will use this function too and didn't access the bbp register via the MCU.
+*/
+#ifndef CONFIG_STA_SUPPORT
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
+	do{														\
+		if ((_A)->bPCIclkOff == FALSE)							\
+		{													\
+			if ((_A)->infType == RTMP_DEV_INF_RBUS)			\
+				RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE);	\
+			else												\
+				RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE);	\
+		}													\
+	}while(0)
+#endif // CONFIG_STA_SUPPORT //
+#ifdef CONFIG_STA_SUPPORT
+// Write BBP register by register's ID & value
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)						\
+{																		\
+	BBP_CSR_CFG_STRUC	BbpCsr;											\
+	INT					BusyCnt = 0;										\
+	BOOLEAN					brc;			\
+	if (_I < MAX_NUM_OF_BBP_LATCH)										\
+	{																	\
+		if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
+			&& ((_A)->bPCIclkOff == FALSE)	\
+			&& ((_A)->brt30xxBanMcuCmd == FALSE))	\
+		{																	\
+			if (_A->AccessBBPFailCount > 20)									\
+			{																	\
+				AsicResetBBPAgent(_A);				\
+				_A->AccessBBPFailCount = 0;											\
+			}																	\
+			for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)					\
+			{																	\
+				RTMP_IO_READ32(_A, 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 = _V;										\
+				BbpCsr.field.RegNum = _I;										\
+				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+				brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+				if (brc == TRUE)																\
+				{																\
+					(_A)->BbpWriteLatch[_I] = _V;									\
+				}																\
+				else																\
+				{																\
+					BbpCsr.field.Busy = 0;											\
+					RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+				}																\
+				break;															\
+			}																	\
+		}																	\
+		else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
+			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
+			&& ((_A)->bPCIclkOff == FALSE))	\
+		{																	\
+			if (_A->AccessBBPFailCount > 20)									\
+			{																	\
+				AsicResetBBPAgent(_A);				\
+				_A->AccessBBPFailCount = 0;											\
+			}																	\
+			for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)					\
+			{																	\
+				RTMP_IO_READ32(_A, 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 = _V;										\
+				BbpCsr.field.RegNum = _I;										\
+				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
+				AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
+				(_A)->BbpWriteLatch[_I] = _V;									\
+				break;															\
+			}																	\
+		}																	\
+		else										\
+		{																	\
+			DBGPRINT_ERR(("  brt30xxBanMcuCmd = %d. Write BBP %d \n",  (_A)->brt30xxBanMcuCmd, (_I)));	\
+		}																	\
+		if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE))			\
+		{																	\
+			if (BusyCnt == MAX_BUSY_COUNT)					\
+				(_A)->AccessBBPFailCount++;					\
+			DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff ));	\
+		}																	\
+	}																		\
+	else																		\
+	{																		\
+		DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n"));	\
+	}																		\
+}
+#endif // CONFIG_STA_SUPPORT //
+#endif // RTMP_MAC_PCI //
+
+
+
+#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++;								\
+	}																		\
+}
+
+#define RTMP_ASIC_MMPS_DISABLE(_pAd)							\
+	do{															\
+		UCHAR _bbpData;											\
+		UINT32 _macData;											\
+		/* 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);				\
+	}while(0)
+
+
+#define RTMP_ASIC_MMPS_ENABLE(_pAd)							\
+	do{															\
+		UCHAR _bbpData;											\
+		UINT32 _macData;											\
+		/* 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);				\
+	}while(0)
+
+#endif // RT30xx //
+
+#endif // __RTMP_PHY_H__ //
diff --git a/drivers/staging/rt3090/rtmp_timer.h b/drivers/staging/rt3090/rtmp_timer.h
new file mode 100644
index 0000000..dfac124
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_timer.h
@@ -0,0 +1,162 @@
+/*
+ *************************************************************************
+ * 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_timer.h
+
+    Abstract:
+	Ralink Wireless Driver timer related data structures and delcarations
+
+    Revision History:
+	Who           When                What
+	--------    ----------      ----------------------------------------------
+	Name          Date                 Modification logs
+	Shiang Tu    Aug-28-2008	init version
+
+*/
+
+#ifndef __RTMP_TIMER_H__
+#define  __RTMP_TIMER_H__
+
+#include "rtmp_os.h"
+
+
+#define DECLARE_TIMER_FUNCTION(_func)			\
+	void rtmp_timer_##_func(unsigned long data)
+
+#define GET_TIMER_FUNCTION(_func)				\
+	rtmp_timer_##_func
+
+
+/* ----------------- Timer Related MARCO ---------------*/
+// In some os or chipset, 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.
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+typedef VOID (*RTMP_TIMER_TASK_HANDLE)(
+	IN  PVOID   SystemSpecific1,
+	IN  PVOID   FunctionContext,
+	IN  PVOID   SystemSpecific2,
+	IN  PVOID   SystemSpecific3);
+#endif // RTMP_TIMER_TASK_SUPPORT //
+
+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 RTMP_TIMER_TASK_SUPPORT
+	RTMP_TIMER_TASK_HANDLE	handle;
+	void					*pAd;
+#endif // RTMP_TIMER_TASK_SUPPORT //
+}RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
+
+
+#ifdef RTMP_TIMER_TASK_SUPPORT
+typedef struct _RTMP_TIMER_TASK_ENTRY_
+{
+	RALINK_TIMER_STRUCT			*pRaTimer;
+	struct _RTMP_TIMER_TASK_ENTRY_	*pNext;
+}RTMP_TIMER_TASK_ENTRY;
+
+
+#define TIMER_QUEUE_SIZE_MAX	128
+typedef struct _RTMP_TIMER_TASK_QUEUE_
+{
+	unsigned int				status;
+	unsigned char				*pTimerQPoll;
+	RTMP_TIMER_TASK_ENTRY	*pQPollFreeList;
+	RTMP_TIMER_TASK_ENTRY	*pQHead;
+	RTMP_TIMER_TASK_ENTRY	*pQTail;
+}RTMP_TIMER_TASK_QUEUE;
+
+#define BUILD_TIMER_FUNCTION(_func)										\
+void rtmp_timer_##_func(unsigned long data)										\
+{																			\
+	PRALINK_TIMER_STRUCT	_pTimer = (PRALINK_TIMER_STRUCT)data;				\
+	RTMP_TIMER_TASK_ENTRY	*_pQNode;										\
+	RTMP_ADAPTER			*_pAd;											\
+																			\
+	_pTimer->handle = _func;													\
+	_pAd = (RTMP_ADAPTER *)_pTimer->pAd;										\
+	_pQNode = RtmpTimerQInsert(_pAd, _pTimer);								\
+	if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT))	\
+		RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ);							\
+}
+#else
+#define BUILD_TIMER_FUNCTION(_func)										\
+void rtmp_timer_##_func(unsigned long data)										\
+{																			\
+	PRALINK_TIMER_STRUCT	pTimer = (PRALINK_TIMER_STRUCT) data;				\
+																			\
+	_func(NULL, (PVOID) pTimer->cookie, NULL, pTimer);							\
+	if (pTimer->Repeat)														\
+		RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);			\
+}
+#endif // RTMP_TIMER_TASK_SUPPORT //
+
+
+DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
+DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
+DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
+DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
+
+
+#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);
+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 //
+
+
+
+
+#if defined(AP_LED) || defined(STA_LED)
+DECLARE_TIMER_FUNCTION(LedCtrlMain);
+#endif
+
+
+
+#endif // __RTMP_TIMER_H__ //
diff --git a/drivers/staging/rt3090/rtmp_type.h b/drivers/staging/rt3090/rtmp_type.h
new file mode 100644
index 0000000..d8b571e
--- /dev/null
+++ b/drivers/staging/rt3090/rtmp_type.h
@@ -0,0 +1,147 @@
+/*
+ *************************************************************************
+ * 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))
+
+#ifdef LINUX
+// 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;
+#endif // LINUX //
+
+typedef unsigned char *		PUINT8;
+typedef unsigned short *		PUINT16;
+typedef unsigned int *			PUINT32;
+typedef unsigned long long *	PUINT64;
+typedef int	*				PINT32;
+typedef long long *			PINT64;
+
+// modified for fixing compile warning on Sigma 8634 platform
+typedef char					STRING;
+typedef signed char			CHAR;
+
+typedef signed short			SHORT;
+typedef signed int				INT;
+typedef signed long			LONG;
+typedef signed long long		LONGLONG;
+
+
+#ifdef LINUX
+typedef unsigned char			UCHAR;
+typedef unsigned short			USHORT;
+typedef unsigned int			UINT;
+typedef unsigned long			ULONG;
+#endif // LINUX //
+typedef unsigned long long		ULONGLONG;
+
+typedef unsigned char			BOOLEAN;
+#ifdef LINUX
+typedef void					VOID;
+#endif // LINUX //
+
+typedef char *				PSTRING;
+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;
+
+
+//
+// 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;
+
+
+typedef int				NTSTATUS;
+
+
+#define STATUS_SUCCESS				0x00
+#define STATUS_UNSUCCESSFUL		0x01
+
+#endif  // __RTMP_TYPE_H__ //
diff --git a/drivers/staging/rt3090/spectrum.h b/drivers/staging/rt3090/spectrum.h
new file mode 100644
index 0000000..be9bae5
--- /dev/null
+++ b/drivers/staging/rt3090/spectrum.h
@@ -0,0 +1,234 @@
+/*
+ *************************************************************************
+ * 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"
+
+
+CHAR RTMP_GetTxPwr(
+	IN PRTMP_ADAPTER pAd,
+	IN HTTRANSMIT_SETTING HTTxMode);
+
+/*
+	==========================================================================
+	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 MakeMeasurementReqFrame(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pOutBuffer,
+	OUT PULONG pFrameLen,
+	IN UINT8 TotalLen,
+	IN UINT8 Category,
+	IN UINT8 Action,
+	IN UINT8 MeasureToken,
+	IN UINT8 MeasureReqMode,
+	IN UINT8 MeasureReqType,
+	IN UINT8 NumOfRepetitions);
+
+/*
+	==========================================================================
+	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	PSTRING			arg);
+
+INT Set_TpcReq_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_PwrConstraint(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+
+VOID MeasureReqTabInit(
+	IN PRTMP_ADAPTER pAd);
+
+VOID MeasureReqTabExit(
+	IN PRTMP_ADAPTER pAd);
+
+PMEASURE_REQ_ENTRY MeasureReqLookUp(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken);
+
+PMEASURE_REQ_ENTRY MeasureReqInsert(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken);
+
+VOID MeasureReqDelete(
+	IN PRTMP_ADAPTER	pAd,
+	IN UINT8			DialogToken);
+
+VOID InsertChannelRepIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PSTRING pCountry,
+	IN UINT8 RegulatoryClass);
+
+VOID InsertTpcReportIE(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 TxPwr,
+	IN UINT8 LinkMargin);
+
+VOID InsertDialogToken(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN UINT8 DialogToken);
+
+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);
+
+VOID RguClass_BuildBcnChList(
+	IN PRTMP_ADAPTER pAd,
+	OUT PUCHAR pBuf,
+	OUT	PULONG pBufLen);
+#endif // __SPECTRUM_H__ //
diff --git a/drivers/staging/rt3090/spectrum_def.h b/drivers/staging/rt3090/spectrum_def.h
new file mode 100644
index 0000000..0389b09
--- /dev/null
+++ b/drivers/staging/rt3090/spectrum_def.h
@@ -0,0 +1,257 @@
+/*
+ *************************************************************************
+ * 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		32
+#define MAX_HASH_MEASURE_REQ_TAB_SIZE	MAX_MEASURE_REQ_TAB_SIZE
+
+#define MAX_TPC_REQ_TAB_SIZE			32
+#define MAX_HASH_TPC_REQ_TAB_SIZE		MAX_TPC_REQ_TAB_SIZE
+
+#define MIN_RCV_PWR				100		/* Negative value ((dBm) */
+
+#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;
+
+
+/* The regulatory information */
+typedef struct _DOT11_CHANNEL_SET
+{
+	UCHAR NumberOfChannels;
+	UINT8 MaxTxPwr;
+	UCHAR ChannelList[16];
+} DOT11_CHANNEL_SET, *PDOT11_CHANNEL_SET;
+
+typedef struct _DOT11_REGULATORY_INFORMATION
+{
+	UCHAR RegulatoryClass;
+	DOT11_CHANNEL_SET ChannelSet;
+} DOT11_REGULATORY_INFORMATION, *PDOT11_REGULATORY_INFORMATION;
+
+
+
+#define RM_TPC_REQ				0
+#define RM_MEASURE_REQ			1
+
+#define RM_BASIC				0
+#define RM_CCA					1
+#define RM_RPI_HISTOGRAM		2
+#define RM_CH_LOAD				3
+#define RM_NOISE_HISTOGRAM		4
+
+
+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 :3;
+		UINT8 DurationMandatory:1;
+		UINT8 Report:1;
+		UINT8 Request:1;
+		UINT8 Enable:1;
+		UINT8 Parallel:1;
+	} field;
+#else
+	struct PACKED
+	{
+		UINT8 Parallel:1;
+		UINT8 Enable:1;
+		UINT8 Request:1;
+		UINT8 Report:1;
+		UINT8 DurationMandatory:1;
+		UINT8 :3;
+	} 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;
+	UINT8 Oct[0];
+} 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;
+	UINT8 ReportMode;
+	UINT8 ReportType;
+	UINT8 Octect[0];
+} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
+
+typedef struct PACKED _QUIET_INFO
+{
+	UINT8 QuietCnt;
+	UINT8 QuietPeriod;
+	UINT16 QuietDuration;
+	UINT16 QuietOffset;
+} QUIET_INFO, *PQUIET_INFO;
+
+#endif // __SPECTRUM_DEF_H__ //
diff --git a/drivers/staging/rt3090/sta/assoc.c b/drivers/staging/rt3090/sta/assoc.c
new file mode 100644
index 0000000..012ed2b
--- /dev/null
+++ b/drivers/staging/rt3090/sta/assoc.c
@@ -0,0 +1,1673 @@
+/*
+ *************************************************************************
+ * 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);
+	RTMP_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);
+	RTMP_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);
+	RTMP_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			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;
+	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 != WPA_SUPPLICANT_ENABLE) &&
+				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
+#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 == WPA_SUPPLICANT_ENABLE) &&
+				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == TRUE))
+			{
+				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 != WPA_SUPPLICANT_ENABLE) ||
+				(pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
+#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;
+		}
+
+
+		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			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;
+	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;
+		}
+
+		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 = 500;
+	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)
+	{
+		//send disassociate event to wpa_supplicant
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
+	}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+#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,
+									&AddHtInfo,
+									AddHtInfoLen,
+									CapabilityInfo);
+			}
+			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)
+			{
+				SendAssocIEsToWpaSupplicant(pAd);
+				RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_ASSOC_EVENT_FLAG, NULL, NULL, 0);
+			}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+                {
+                    wext_notify_event_assoc(pAd);
+                    RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0);
+                }
+#endif // NATIVE_WPA_SUPPLICANT_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;
+			//KH need to check again
+			// Don't allow to go to sleep mode if authmode is WPA-related.
+			//This can make Authentication process more smoothly.
+			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
+			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);
+			}
+
+
+			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)
+			{
+				//send disassociate event to wpa_supplicant
+				RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
+			}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+#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);
+}
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+VOID    SendAssocIEsToWpaSupplicant(
+    IN  PRTMP_ADAPTER pAd)
+{
+	STRING 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);
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_REQIE_EVENT_FLAG, NULL, (PUCHAR)custom, pAd->StaCfg.ReqVarIELen + 17);
+
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_ASSOCINFO_EVENT_FLAG, NULL, NULL, 0);
+	}
+	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)
+{
+	char custom[IW_CUSTOM_MAX] = {0};
+
+#if WIRELESS_EXT > 17
+	if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
+	{
+		NdisMoveMemory(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+		RtmpOSWrielessEventSend(pAd, IWEVASSOCREQIE, -1, NULL, custom, pAd->StaCfg.ReqVarIELen);
+	}
+	else
+	    DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
+#else
+	int len;
+
+	len = (pAd->StaCfg.ReqVarIELen*2) + 17;
+	if (len <= IW_CUSTOM_MAX)
+	{
+		UCHAR   idx;
+		sprintf(custom, "ASSOCINFO(ReqIEs=");
+		for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
+		        sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, custom, len);
+	}
+	else
+		DBGPRINT(RT_DEBUG_TRACE, ("len(%d) > MAX_CUSTOM_LEN\n", len));
+#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  ADD_HT_INFO_IE		*pAddHtInfo,
+	IN  UCHAR				AddHtInfoLen,
+	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
+	NdisZeroMemory(&pEntry->HTCapability, sizeof(pEntry->HTCapability));
+	// 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) &&
+			((pAd->StaCfg.BssType == BSS_INFRA) || ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAddHtInfo->AddHtInfo.ExtChanOffset == pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset))))
+		{
+			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);
+		NdisMoveMemory(&pEntry->HTCapability, pHtCapability, HtCapabilityLen);
+	}
+	else
+	{
+		pAd->MacTab.fAnyStationIsLegacy = TRUE;
+	}
+#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/rt3090/sta/auth.c b/drivers/staging/rt3090/sta/auth.c
new file mode 100644
index 0000000..157e299
--- /dev/null
+++ b/drivers/staging/rt3090/sta/auth.c
@@ -0,0 +1,491 @@
+/*
+ *************************************************************************
+ * 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);
+    RTMP_MLME_HANDLER(pAd);
+}
+
+
+/*
+    ==========================================================================
+    Description:
+
+	IRQL = DISPATCH_LEVEL
+
+    ==========================================================================
+ */
+VOID MlmeAuthReqAction(
+    IN PRTMP_ADAPTER pAd,
+    IN MLME_QUEUE_ELEM *Elem)
+{
+	if (AUTH_ReqSend(pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0))
+        pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
+    else
+    {
+		USHORT Status;
+
+        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, (PCHAR)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)
+                {
+                    pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+                    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
+            {
+                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);
+}
+
+BOOLEAN	AUTH_ReqSend(
+	IN  PRTMP_ADAPTER		pAd,
+	IN  PMLME_QUEUE_ELEM	pElem,
+	IN  PRALINK_TIMER_STRUCT pAuthTimer,
+	IN  PSTRING				pSMName,
+	IN  USHORT				SeqNo,
+	IN  PUCHAR				pNewElement,
+	IN  ULONG				ElementLen)
+{
+	USHORT             Alg, Seq, Status;
+	UCHAR              Addr[6];
+    ULONG              Timeout;
+    HEADER_802_11      AuthHdr;
+    BOOLEAN            TimerCancelled;
+    NDIS_STATUS        NStatus;
+    PUCHAR             pOutBuffer = NULL;
+    ULONG              FrameLen = 0, tmp = 0;
+
+	// Block all authentication request durning WPA block period
+	if (pAd->StaCfg.bBlockAssoc == TRUE)
+	{
+        DBGPRINT(RT_DEBUG_TRACE, ("%s - Block Auth request durning WPA block period!\n", pSMName));
+        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, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg))
+    {
+	/* reset timer */
+		RTMPCancelTimer(pAuthTimer, &TimerCancelled);
+
+        COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
+        pAd->MlmeAux.Alg  = Alg;
+        Seq = SeqNo;
+        Status = MLME_SUCCESS;
+
+        NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);  //Get an unused nonpaged memory
+        if(NStatus != NDIS_STATUS_SUCCESS)
+        {
+            DBGPRINT(RT_DEBUG_TRACE, ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", pSMName, 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 FALSE;
+        }
+
+        DBGPRINT(RT_DEBUG_TRACE, ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName, 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);
+
+		if (pNewElement && ElementLen)
+		{
+			MakeOutgoingFrame(pOutBuffer+FrameLen,	&tmp,
+							  ElementLen,			pNewElement,
+				  END_OF_ARGS);
+			FrameLen += tmp;
+		}
+
+        MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+	MlmeFreeMemory(pAd, pOutBuffer);
+
+		RTMPSetTimer(pAuthTimer, Timeout);
+		return TRUE;
+    }
+    else
+    {
+        DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n", pSMName));
+		return FALSE;
+    }
+
+	return TRUE;
+}
diff --git a/drivers/staging/rt3090/sta/auth_rsp.c b/drivers/staging/rt3090/sta/auth_rsp.c
new file mode 100644
index 0000000..207bfea
--- /dev/null
+++ b/drivers/staging/rt3090/sta/auth_rsp.c
@@ -0,0 +1,151 @@
+/*
+ *************************************************************************
+ * 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
+		RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+#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);
+        }
+    }
+    else
+    {
+        DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
+    }
+}
diff --git a/drivers/staging/rt3090/sta/connect.c b/drivers/staging/rt3090/sta/connect.c
new file mode 100644
index 0000000..4aa35ee
--- /dev/null
+++ b/drivers/staging/rt3090/sta/connect.c
@@ -0,0 +1,2759 @@
+/*
+ *************************************************************************
+ * 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)                                 \
+{                                                                                       \
+	NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID);							\
+	(_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);
+
+				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;
+		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:
+			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, (PUCHAR)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, (PSTRING) Elem->Msg, Elem->MsgLen, 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;
+
+	pAd->StaCfg.bAutoConnectByBssid = FALSE;
+
+	//
+	// 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, (PCHAR)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)
+			 ) &&
+			(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
+			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0);
+#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, (PSTRING) 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;
+
+	// find the desired BSS in the latest SCAN result table
+	BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
+	if (BssIdx == BSS_NOT_FOUND)
+	{
+		MLME_SCAN_REQ_STRUCT       ScanReq;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
+		//pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. start a new scan\n"));
+		ScanParmFill(pAd, &ScanReq, (PSTRING) 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
+		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
+		return;
+	}
+
+	//
+	// Update Reconnect Ssid, that user desired to connect.
+	//
+	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+	pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
+
+	// 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));
+
+	// 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);
+
+	{
+		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)
+{
+	UCHAR BBPValue = 0;
+
+	DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
+
+	{
+		//Let BBP register at 20MHz to do (fast) roaming.
+		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+		BBPValue &= (~0x18);
+		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+		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, (PCHAR)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
+			{
+				{
+					// 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, AUTH_MODE_KEY);
+					}
+					else
+					{
+						AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN);
+					}
+					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
+			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
+			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;
+				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);
+
+			{
+				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"));
+			{
+				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, AUTH_MODE_KEY);
+				}
+				else
+				{
+					AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN);
+				}
+				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
+		{
+			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)
+		{
+			if (pAd->CommonCfg.bWirelessEvent)
+			{
+				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+			}
+
+			LinkUp(pAd, BSS_INFRA);
+			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+		}
+		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)
+		{
+			// send wireless event - for association
+			if (pAd->CommonCfg.bWirelessEvent)
+				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+			//
+			// NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
+			//
+			LinkUp(pAd, BSS_INFRA);
+
+			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 = 0, HashIdx = 0;
+	MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry = NULL;
+
+	// Init ChannelQuality to prevent DEAD_CQI at initial LinkUp
+	pAd->Mlme.ChannelQuality = 50;
+
+	pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
+	if (pEntry)
+	{
+		MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+		pEntry = NULL;
+	}
+
+
+	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 //
+
+#ifdef RTMP_MAC_PCI
+	// 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);
+	if(pAd->Antenna.field.RxPath == 3)
+	{
+		Value |= (0x10);
+	}
+	else if(pAd->Antenna.field.RxPath == 2)
+	{
+		Value |= (0x8);
+	}
+	else if(pAd->Antenna.field.RxPath == 1)
+	{
+		Value |= (0x0);
+	}
+	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+	pAd->StaCfg.BBPR3 = Value;
+#endif // RTMP_MAC_PCI //
+
+	if (BssType == BSS_ADHOC)
+	{
+		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+
+#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);
+#ifdef RTMP_MAC_PCI
+            pAd->StaCfg.BBPR3 = Value;
+#endif // RTMP_MAC_PCI //
+
+		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);
+#ifdef RTMP_MAC_PCI
+            pAd->StaCfg.BBPR3 = Value;
+#endif // RTMP_MAC_PCI //
+
+		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);
+#ifdef RTMP_MAC_PCI
+            pAd->StaCfg.BBPR3 = Value;
+#endif // RTMP_MAC_PCI //
+
+			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
+			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+			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 = 1;
+			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
+		// 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);
+
+		// 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);
+
+						pEntry->Aid = BSSID_WCID;
+						// 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);
+		}
+		else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+				 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+		{
+#ifdef WPA_SUPPLICANT_SUPPORT
+			if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
+#endif // WPA_SUPPLICANT_SUPPORT //
+				RTMPSetTimer(&pAd->Mlme.LinkDownTimer, LINK_DOWN_TIMEOUT);
+		}
+        // --
+
+		// Add BSSID in my MAC Table.
+        NdisAcquireSpinLock(&pAd->MacTabLock);
+		// add this MAC entry into HASH table
+		if (pEntry)
+		{
+			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;
+			}
+		}
+		RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+		pEntry->Aid = BSSID_WCID;
+		pEntry->pAd = pAd;
+		pEntry->ValidAsCLI = TRUE;	//Although this is bssid..still set ValidAsCl
+		pAd->MacTab.Size = 1;	// infra mode always set MACtab size =1.
+		pEntry->Sst = SST_ASSOC;
+		pEntry->AuthState = SST_ASSOC;
+		pEntry->AuthMode = pAd->StaCfg.AuthMode;
+		pEntry->WepStatus = pAd->StaCfg.WepStatus;
+		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
+		{
+			pEntry->WpaState = AS_NOTUSE;
+			pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+		}
+		else
+		{
+			pEntry->WpaState = AS_PTKSTART;
+			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+		}
+		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 //
+
+
+		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);
+				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+				RTMPSetPiggyBack(pAd, TRUE);
+				DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
+			}
+			else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+			{
+				CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+				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 (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
+		(pAd->StaCfg.bForceTxBurst == FALSE) &&
+		(((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)
+	{
+#ifdef WPA_SUPPLICANT_SUPPORT
+		if (pAd->StaCfg.WpaSupplicantUP &&
+			(pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
+			(pAd->StaCfg.IEEE8021X == TRUE))
+			;
+		else
+#endif // WPA_SUPPLICANT_SUPPORT //
+		{
+			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);
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+
+#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;
+
+	BOOLEAN		Cancelled;
+
+	// 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 //
+	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+	//Comment the codes, beasue the line 2291 call the same function.
+	//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);
+	}
+
+	DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
+	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+
+#ifdef RTMP_MAC_PCI
+    if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+    {
+	    BOOLEAN Cancelled;
+        pAd->Mlme.bPsPollTimerRunning = FALSE;
+        RTMPCancelTimer(&pAd->Mlme.PsPollTimer,	&Cancelled);
+    }
+
+	pAd->bPCIclkOff = FALSE;
+#endif // RTMP_MAC_PCI //
+
+    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);
+        OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+    }
+#ifdef RTMP_MAC_PCI
+	pAd->bPCIclkOff = FALSE;
+#endif // RTMP_MAC_PCI //
+	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);
+
+#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);
+	}
+
+	AsicSetSlotTime(pAd, TRUE); //FALSE);
+	AsicSetEdcaParm(pAd, NULL);
+
+	// Set LED
+	RTMPSetLED(pAd, LED_LINK_DOWN);
+    pAd->LedIndicatorStrength = 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);
+	NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
+	pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
+	NdisReleaseSpinLock(&pAd->MacTabLock);
+
+	pAd->StaCfg.MicErrCnt = 0;
+
+    pAd->IndicateMediaState = NdisMediaStateDisconnected;
+	// Update extra information to link is up
+	pAd->ExtraInfo = GENERAL_LINK_DOWN;
+
+    pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+
+
+	// 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);
+// 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) {
+		//send disassociate event to wpa_supplicant
+		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, RT_DISASSOC_EVENT_FLAG, NULL, NULL, 0);
+	}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#ifdef RT30xx
+	if ((IS_RT30xx(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd))
+		&&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1))
+	{
+		RTMP_ASIC_MMPS_DISABLE(pAd);
+	}
+#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, (PCHAR)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
+	{
+
+#ifdef DOT11_N_SUPPORT
+#endif // DOT11_N_SUPPORT //
+		{
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+		}
+
+		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
+	{
+
+#ifdef DOT11_N_SUPPORT
+#endif // DOT11_N_SUPPORT //
+		{
+			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+		}
+
+		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 STRING 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 RTMP_MAC_PCI
+VOID ComposePsPoll(
+	IN PRTMP_ADAPTER pAd)
+{
+	NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+	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);
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID ComposeNullFrame(
+	IN PRTMP_ADAPTER pAd)
+{
+	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);
+}
+#endif // RTMP_MAC_PCI //
+
+
+
+
+/*
+	==========================================================================
+	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;
+	UCHAR         *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/rt3090/sta/dls.c b/drivers/staging/rt3090/sta/dls.c
new file mode 100644
index 0000000..306e16f
--- /dev/null
+++ b/drivers/staging/rt3090/sta/dls.c
@@ -0,0 +1,2207 @@
+/*
+ *************************************************************************
+ * 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;
+
+						DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
+									SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+
+						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)
+						{
+
+							DBGPRINT(RT_DEBUG_OFF, ("@@@ 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;
+
+					DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
+								SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+
+					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;
+
+						DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
+									SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+
+						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)
+						{
+							DBGPRINT(RT_DEBUG_OFF, ("@@@ 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 (Len < LENGTH_802_11 + 6 + 2) /* LENGTH_802_11 + LLC + EAPOL protocol type */
+		return bSTAKeyFrame;
+
+	pProto	= (PUCHAR)pHeader + LENGTH_802_11;
+
+	if ((pHeader->FC.SubType & 0x08))
+		pProto	+= 2;	/* QOS Control field */
+
+     /* Skip 4-bytes for HTC */
+     if (pHeader->FC.Order && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
+     {
+          pProto += 4;
+     }
+
+	/* L2PAD bit on will pad 2 bytes at LLC */
+	if (pRxD->L2PAD)
+	{
+		pProto += 2;
+	}
+
+	pProto	+= 6;	/* 0xAA 0xAA 0xAA 0x00 0x00 0x00 */
+
+	if ((!(pHeader->FC.SubType & 0x08)) && (!RTMPEqualMemory(EAPOL, pProto, 2)))
+		return bSTAKeyFrame;
+
+	pAddr	= pHeader->Addr2;
+
+	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);
+			WpaDerivePTK(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(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, digest, SHA1_DIGEST_SIZE);
+				NdisMoveMemory(Mic,	digest,	LEN_KEY_DESC_MIC);
+			}
+			else
+			{
+				HMAC_MD5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic, MD5_DIGEST_SIZE);
+			}
+
+			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 ((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 (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;
+				if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+					PairwiseKey.CipherAlg = CIPHER_TKIP;
+				else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+					PairwiseKey.CipherAlg = CIPHER_AES;
+
+				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 RTMP_MAC_PCI
+				AsicAddPairwiseKeyEntry(pAd,
+										pAd->StaCfg.DLSEntry[i].MacAddr,
+										(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
+										&PairwiseKey);
+
+				RTMPAddWcidAttributeEntry(pAd,
+										  BSS0,
+										  0,
+										  PairwiseKey.CipherAlg,
+										  pEntry);
+
+#endif // RTMP_MAC_PCI //
+				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;
+				if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+					PairwiseKey.CipherAlg = CIPHER_TKIP;
+				else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+					PairwiseKey.CipherAlg = CIPHER_AES;
+
+				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 RTMP_MAC_PCI
+		AsicAddPairwiseKeyEntry(pAd,
+										pAd->StaCfg.DLSEntry[i].MacAddr,
+										(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
+										&PairwiseKey);
+
+				RTMPAddWcidAttributeEntry(pAd,
+										  BSS0,
+										  0,
+										  PairwiseKey.CipherAlg,
+										  pEntry);
+#endif // RTMP_MAC_PCI //
+				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);
+	WpaDerivePTK(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(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
+		NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		NdisZeroMemory(Mic,	sizeof(Mic));
+		HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
+		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);
+	WpaDerivePTK(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(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
+		NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{
+		NdisZeroMemory(Mic,	sizeof(Mic));
+		HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
+		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);
+		RTMP_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;
+			pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+
+			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) && (pAd->StaCfg.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;
+
+	DBGPRINT(RT_DEBUG_OFF, ("\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))
+		{
+			PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
+
+			DBGPRINT(RT_DEBUG_OFF, ("%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]));
+			DBGPRINT(RT_DEBUG_OFF, ("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut));
+
+			DBGPRINT(RT_DEBUG_OFF, ("\n"));
+			DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2"));
+#ifdef DOT11_N_SUPPORT
+			DBGPRINT(RT_DEBUG_OFF, ("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC"));
+#endif // DOT11_N_SUPPORT //
+			DBGPRINT(RT_DEBUG_OFF, ("\n%02X:%02X:%02X:%02X:%02X:%02X  ",
+				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]));
+			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid));
+			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->apidx));
+			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode));
+			DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)));
+			DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi0));
+			DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi1));
+			DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi2));
+#ifdef DOT11_N_SUPPORT
+			DBGPRINT(RT_DEBUG_OFF, ("%-8d", (int)pEntry->MmpsMode));
+			DBGPRINT(RT_DEBUG_OFF, ("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE)));
+			DBGPRINT(RT_DEBUG_OFF, ("%-6s", GetBW(pEntry->HTPhyMode.field.BW)));
+			DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.MCS));
+			DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.ShortGI));
+			DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.STBC));
+#endif // DOT11_N_SUPPORT //
+			DBGPRINT(RT_DEBUG_OFF, ("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
+						(pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0));
+			DBGPRINT(RT_DEBUG_OFF, ("\n"));
+
+		}
+	}
+
+	return TRUE;
+}
+
+INT	Set_DlsAddEntry_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+    UCHAR	mac[MAC_ADDR_LEN];
+	USHORT	Timeout;
+	PSTRING token;
+	STRING 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 = (USHORT) 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, (&mac[i]), 1);
+		}
+		if(i != 6)
+			return FALSE;
+
+	    DBGPRINT(RT_DEBUG_OFF, ("\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	PSTRING			arg)
+{
+	UCHAR			macAddr[MAC_ADDR_LEN];
+	PSTRING			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);
+	}
+
+	DBGPRINT(RT_DEBUG_OFF, ("\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/rt3090/sta/rtmp_ckipmic.c b/drivers/staging/rt3090/sta/rtmp_ckipmic.c
new file mode 100644
index 0000000..5f6dbd7
--- /dev/null
+++ b/drivers/staging/rt3090/sta/rtmp_ckipmic.c
@@ -0,0 +1,579 @@
+/*
+ *************************************************************************
+ * 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.c
+
+	Abstract:
+	Data path subroutines
+
+	Revision History:
+	Who		When			What
+	--------	----------		----------------------------------------------
+*/
+
+#include "../rt_config.h"
+#include "../rtmp_ckipmic.h"
+
+
+#define MIC_ACCUM(v)            pContext->accum += (ULONGLONG)v * RTMPMicGetCoefficient(pContext)
+#define GB(p,i,s)               ( ((ULONG) *((UCHAR*)(p)+i) ) << (s) )
+#define GETBIG32(p)             GB(p,0,24)|GB(p,1,16)|GB(p,2,8)|GB(p,3,0)
+
+/*****************************/
+/******** 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
+};
+
+/*===========================================================================*/
+/*=================== CKIP KEY PERMUTATION ==================================*/
+/*===========================================================================*/
+
+/* 2-byte by 2-byte subset of the full AES table */
+static const USHORT Sbox[256] =
+{
+    0xC6A5,0xF884,0xEE99,0xF68D,0xFF0D,0xD6BD,0xDEB1,0x9154,
+    0x6050,0x0203,0xCEA9,0x567D,0xE719,0xB562,0x4DE6,0xEC9A,
+    0x8F45,0x1F9D,0x8940,0xFA87,0xEF15,0xB2EB,0x8EC9,0xFB0B,
+    0x41EC,0xB367,0x5FFD,0x45EA,0x23BF,0x53F7,0xE496,0x9B5B,
+    0x75C2,0xE11C,0x3DAE,0x4C6A,0x6C5A,0x7E41,0xF502,0x834F,
+    0x685C,0x51F4,0xD134,0xF908,0xE293,0xAB73,0x6253,0x2A3F,
+    0x080C,0x9552,0x4665,0x9D5E,0x3028,0x37A1,0x0A0F,0x2FB5,
+    0x0E09,0x2436,0x1B9B,0xDF3D,0xCD26,0x4E69,0x7FCD,0xEA9F,
+    0x121B,0x1D9E,0x5874,0x342E,0x362D,0xDCB2,0xB4EE,0x5BFB,
+    0xA4F6,0x764D,0xB761,0x7DCE,0x527B,0xDD3E,0x5E71,0x1397,
+    0xA6F5,0xB968,0x0000,0xC12C,0x4060,0xE31F,0x79C8,0xB6ED,
+    0xD4BE,0x8D46,0x67D9,0x724B,0x94DE,0x98D4,0xB0E8,0x854A,
+    0xBB6B,0xC52A,0x4FE5,0xED16,0x86C5,0x9AD7,0x6655,0x1194,
+    0x8ACF,0xE910,0x0406,0xFE81,0xA0F0,0x7844,0x25BA,0x4BE3,
+    0xA2F3,0x5DFE,0x80C0,0x058A,0x3FAD,0x21BC,0x7048,0xF104,
+    0x63DF,0x77C1,0xAF75,0x4263,0x2030,0xE51A,0xFD0E,0xBF6D,
+    0x814C,0x1814,0x2635,0xC32F,0xBEE1,0x35A2,0x88CC,0x2E39,
+    0x9357,0x55F2,0xFC82,0x7A47,0xC8AC,0xBAE7,0x322B,0xE695,
+    0xC0A0,0x1998,0x9ED1,0xA37F,0x4466,0x547E,0x3BAB,0x0B83,
+    0x8CCA,0xC729,0x6BD3,0x283C,0xA779,0xBCE2,0x161D,0xAD76,
+    0xDB3B,0x6456,0x744E,0x141E,0x92DB,0x0C0A,0x486C,0xB8E4,
+    0x9F5D,0xBD6E,0x43EF,0xC4A6,0x39A8,0x31A4,0xD337,0xF28B,
+    0xD532,0x8B43,0x6E59,0xDAB7,0x018C,0xB164,0x9CD2,0x49E0,
+    0xD8B4,0xACFA,0xF307,0xCF25,0xCAAF,0xF48E,0x47E9,0x1018,
+    0x6FD5,0xF088,0x4A6F,0x5C72,0x3824,0x57F1,0x73C7,0x9751,
+    0xCB23,0xA17C,0xE89C,0x3E21,0x96DD,0x61DC,0x0D86,0x0F85,
+    0xE090,0x7C42,0x71C4,0xCCAA,0x90D8,0x0605,0xF701,0x1C12,
+    0xC2A3,0x6A5F,0xAEF9,0x69D0,0x1791,0x9958,0x3A27,0x27B9,
+    0xD938,0xEB13,0x2BB3,0x2233,0xD2BB,0xA970,0x0789,0x33A7,
+    0x2DB6,0x3C22,0x1592,0xC920,0x8749,0xAAFF,0x5078,0xA57A,
+    0x038F,0x59F8,0x0980,0x1A17,0x65DA,0xD731,0x84C6,0xD0B8,
+    0x82C3,0x29B0,0x5A77,0x1E11,0x7BCB,0xA8FC,0x6DD6,0x2C3A
+    };
+
+#define Lo8(v16)     ((v16)       & 0xFF)
+#define Hi8(v16)    (((v16) >> 8) & 0xFF)
+#define u16Swap(i)  ( (((i) >> 8) & 0xFF) | (((i) << 8) & 0xFF00) )
+#define _S_(i)      (Sbox[Lo8(i)] ^ u16Swap(Sbox[Hi8(i)]))
+
+#define rotLeft_1(x) ((((x) << 1) | ((x) >> 15)) & 0xFFFF)
+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 */
+     )
+{
+    int i;
+    USHORT H[2], tmp;          /* H=32-bits of per-packet hash value */
+    USHORT L[8], R[8];         /* L=u16 array of CK, R=u16 array of PK */
+
+    /* build L from input key */
+    memset(L, 0, sizeof(L));
+    for (i=0; i<16; i++) {
+        L[i>>1] |= ( ((USHORT)(CK[i])) << ( i & 1 ? 8 : 0) );
+    }
+
+    H[0] = (((USHORT)piv[0]) << 8) + piv[1];
+    H[1] = ( ((USHORT)toDsFromDs) << 8) | piv[2];
+
+    for (i=0; i<8; i++) {
+        H[0] ^= L[i];           /* 16-bits of key material */
+        tmp   = _S_(H[0]);      /* 16x16 permutation */
+        H[0]  = tmp ^ H[1];     /* set up for next round */
+        H[1]  = tmp;
+        R[i]  = H[0];           /* store into key array  */
+    }
+
+    /* sweep in the other direction */
+    tmp=L[0];
+    for (i=7; i>0; i--) {
+        R[i] = tmp = rotLeft_1(tmp) + R[i];
+    }
+
+    /* IV of the permuted key is unchanged */
+    PK[0] = piv[0];
+    PK[1] = piv[1];
+    PK[2] = piv[2];
+
+    /* key portion of the permuted key is changed */
+    for (i=3; i<16; i++) {
+        PK[i] = (UCHAR) (R[i>>1] >> (i & 1 ? 8 : 0));
+    }
+}
+
+/* prepare for calculation of a new mic */
+VOID RTMPCkipMicInit(
+    IN  PMIC_CONTEXT        pContext,
+    IN  PUCHAR              CK)
+{
+    /* prepare for new mic calculation */
+    NdisMoveMemory(pContext->CK, CK, sizeof(pContext->CK));
+    pContext->accum = 0;
+    pContext->position = 0;
+}
+
+/* add some bytes to the mic calculation */
+VOID RTMPMicUpdate(
+    IN  PMIC_CONTEXT        pContext,
+    IN  PUCHAR              pOctets,
+    IN  INT                 len)
+{
+    INT     byte_position;
+    ULONG   val;
+
+    byte_position = (pContext->position & 3);
+    while (len > 0) {
+        /* build a 32-bit word for MIC multiply accumulate */
+        do {
+            if (len == 0) return;
+            pContext->part[byte_position++] = *pOctets++;
+            pContext->position++;
+            len--;
+        } while (byte_position < 4);
+        /* have a full 32-bit word to process */
+        val = GETBIG32(&pContext->part[0]);
+        MIC_ACCUM(val);
+        byte_position = 0;
+    }
+}
+
+ULONG RTMPMicGetCoefficient(
+    IN  PMIC_CONTEXT         pContext)
+{
+    UCHAR   aes_counter[16];
+    INT     coeff_position;
+    UCHAR   *p;
+
+    coeff_position = (pContext->position - 1) >> 2;
+    if ( (coeff_position & 3) == 0) {
+        /* fetching the first coefficient -- get new 16-byte aes counter output */
+        u32 counter = (coeff_position >> 2);
+
+        /* new counter value */
+        memset(&aes_counter[0], 0, sizeof(aes_counter));
+        aes_counter[15] = (UINT8)(counter >> 0);
+        aes_counter[14] = (UINT8)(counter >> 8);
+        aes_counter[13] = (UINT8)(counter >> 16);
+        aes_counter[12] = (UINT8)(counter >> 24);
+
+        RTMPAesEncrypt(&pContext->CK[0], &aes_counter[0], pContext->coefficient);
+    }
+    p = &(pContext->coefficient[ (coeff_position & 3) << 2 ]);
+    return GETBIG32(p);
+}
+
+/****************************************/
+/* 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];
+    }
+}
+
+UCHAR RTMPCkipSbox(
+    IN  UCHAR   a)
+{
+    return SboxTable[(int)a];
+}
+
+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 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 byte_sub(
+    IN  PUCHAR  in,
+    OUT PUCHAR  out)
+{
+    INT i;
+
+    for (i=0; i< 16; i++)
+    {
+        out[i] = RTMPCkipSbox(in[i]);
+    }
+}
+
+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);
+}
+
+VOID RTMPAesEncrypt(
+    IN  PUCHAR  key,
+    IN  PUCHAR  data,
+    IN  PUCHAR  ciphertext)
+{
+    INT             round;
+    INT             i;
+    UCHAR           intermediatea[16];
+    UCHAR           intermediateb[16];
+    UCHAR           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);
+        }
+    }
+
+}
+
+/* calculate the mic */
+VOID RTMPMicFinal(
+    IN  PMIC_CONTEXT    pContext,
+    OUT UCHAR           digest[4])
+{
+    INT             byte_position;
+    ULONG           val;
+    ULONGLONG       sum, utmp;
+    LONGLONG        stmp;
+
+    /* deal with partial 32-bit word left over from last update */
+    if ( (byte_position = (pContext->position & 3)) != 0) {
+        /* have a partial word in part to deal with -- zero unused bytes */
+        do {
+            pContext->part[byte_position++] = 0;
+            pContext->position++;
+        } while (byte_position < 4);
+        val = GETBIG32(&pContext->part[0]);
+        MIC_ACCUM(val);
+    }
+
+    /* reduce the accumulated u64 to a 32-bit MIC */
+    sum = pContext->accum;
+    stmp = (sum  & 0xffffffffL) - ((sum >> 32)  * 15);
+    utmp = (stmp & 0xffffffffL) - ((stmp >> 32) * 15);
+    sum = utmp & 0xffffffffL;
+    if (utmp > 0x10000000fL)
+        sum -= 15;
+
+    val = (ULONG)sum;
+    digest[0] = (UCHAR)((val>>24) & 0xFF);
+    digest[1] = (UCHAR) ((val>>16) & 0xFF);
+    digest[2] = (UCHAR) ((val>>8) & 0xFF);
+    digest[3] = (UCHAR)((val>>0) & 0xFF);
+}
+
+VOID RTMPCkipInsertCMIC(
+    IN  PRTMP_ADAPTER   pAd,
+    OUT PUCHAR          pMIC,
+    IN  PUCHAR          p80211hdr,
+    IN  PNDIS_PACKET    pPacket,
+    IN  PCIPHER_KEY     pKey,
+    IN  PUCHAR          mic_snap)
+{
+	PACKET_INFO		PacketInfo;
+	PUCHAR			pSrcBufVA;
+	ULONG			SrcBufLen;
+    PUCHAR          pDA, pSA, pProto;
+    UCHAR           bigethlen[2];
+	UCHAR			ckip_ck[16];
+    MIC_CONTEXT     mic_ctx;
+    USHORT          payloadlen;
+	UCHAR			i;
+
+	if (pKey == NULL)
+	{
+		DBGPRINT_ERR(("RTMPCkipInsertCMIC, Before to form the CKIP key (CK), pKey can't be NULL\n"));
+		return;
+	}
+
+    switch (*(p80211hdr+1) & 3)
+    {
+        case 0: /* FromDs=0, ToDs=0 */
+            pDA = p80211hdr+4;
+            pSA = p80211hdr+10;
+            break;
+        case 1: /* FromDs=0, ToDs=1 */
+            pDA = p80211hdr+16;
+            pSA = p80211hdr+10;
+            break;
+        case 2: /* FromDs=1, ToDs=0 */
+            pDA = p80211hdr+4;
+            pSA = p80211hdr+16;
+            break;
+        case 3: /* FromDs=1, ToDs=1 */
+            pDA = p80211hdr+16;
+            pSA = p80211hdr+24;
+            break;
+    }
+
+	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+    if (SrcBufLen < LENGTH_802_3)
+        return;
+
+    pProto = pSrcBufVA + 12;
+    payloadlen = PacketInfo.TotalPacketLength - LENGTH_802_3 + 18; // CKIP_LLC(8)+CMIC(4)+TxSEQ(4)+PROTO(2)=18
+
+    bigethlen[0] = (unsigned char)(payloadlen >> 8);
+    bigethlen[1] = (unsigned char)payloadlen;
+
+	//
+	// Encryption Key expansion to form the CKIP Key (CKIP_CK).
+	//
+	if (pKey->KeyLen < 16)
+	{
+		for(i = 0; i < (16 / pKey->KeyLen); i++)
+		{
+			NdisMoveMemory(ckip_ck + i * pKey->KeyLen,
+							pKey->Key,
+							pKey->KeyLen);
+		}
+		NdisMoveMemory(ckip_ck + i * pKey->KeyLen,
+						pKey->Key,
+						16 - (i * pKey->KeyLen));
+	}
+	else
+	{
+		NdisMoveMemory(ckip_ck, pKey->Key, pKey->KeyLen);
+	}
+    RTMPCkipMicInit(&mic_ctx, ckip_ck);
+    RTMPMicUpdate(&mic_ctx, pDA, MAC_ADDR_LEN);            // MIC <-- DA
+    RTMPMicUpdate(&mic_ctx, pSA, MAC_ADDR_LEN);            // MIC <-- SA
+    RTMPMicUpdate(&mic_ctx, bigethlen, 2);                 // MIC <-- payload length starting from CKIP SNAP
+    RTMPMicUpdate(&mic_ctx, mic_snap, 8);                  // MIC <-- snap header
+    RTMPMicUpdate(&mic_ctx, pAd->StaCfg.TxSEQ, 4);   // MIC <-- TxSEQ
+    RTMPMicUpdate(&mic_ctx, pProto, 2);                    // MIC <-- Protocol
+
+    pSrcBufVA += LENGTH_802_3;
+    SrcBufLen -= LENGTH_802_3;
+
+    // Mic <-- original payload. loop until all payload processed
+    do
+    {
+        if (SrcBufLen > 0)
+            RTMPMicUpdate(&mic_ctx, pSrcBufVA, SrcBufLen);
+
+		NdisGetNextBuffer(PacketInfo.pFirstBuffer, &PacketInfo.pFirstBuffer);
+        if (PacketInfo.pFirstBuffer)
+        {
+            NDIS_QUERY_BUFFER(PacketInfo.pFirstBuffer, &pSrcBufVA, &SrcBufLen);
+        }
+        else
+            break;
+    } while (TRUE);
+
+    RTMPMicFinal(&mic_ctx, pMIC);                          // update MIC
+}
diff --git a/drivers/staging/rt3090/sta/rtmp_data.c b/drivers/staging/rt3090/sta/rtmp_data.c
new file mode 100644
index 0000000..5591364
--- /dev/null
+++ b/drivers/staging/rt3090/sta/rtmp_data.c
@@ -0,0 +1,2661 @@
+/*
+ *************************************************************************
+ * 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
+	--------	----------		----------------------------------------------
+*/
+
+#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 RTMP_MAC_PCI
+						MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
+
+						// Set key material and cipherAlg to Asic
+						AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+
+						// Assign group key info
+						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+
+						// Assign pairwise key info
+						RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
+
+                        pAd->IndicateMediaState = NdisMediaStateConnected;
+                        pAd->ExtraInfo = GENERAL_LINK_UP;
+#endif // RTMP_MAC_PCI //
+						// 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_INFO,("bAPSDCapable\n"));
+
+			// Qos bit 4
+			pData = (PUCHAR)pHeader + LENGTH_802_11;
+			if ((*pData >> 4) & 0x01)
+			{
+				DBGPRINT(RT_DEBUG_INFO,("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;
+
+					RTMP_SET_PSM_BIT(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;
+
+	/* check if need to resend PS Poll when received packet with MoreData = 1 */
+	if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
+	{
+		if ((((UserPriority == 0) || (UserPriority == 3)) &&
+			pAd->CommonCfg.bAPSDAC_BE == 0) ||
+			(((UserPriority == 1) || (UserPriority == 2)) &&
+			pAd->CommonCfg.bAPSDAC_BK == 0) ||
+			(((UserPriority == 4) || (UserPriority == 5)) &&
+			pAd->CommonCfg.bAPSDAC_VI == 0) ||
+			(((UserPriority == 6) || (UserPriority == 7)) &&
+			pAd->CommonCfg.bAPSDAC_VO == 0))
+		{
+			/* non-UAPSD delivery-enabled AC */
+			RTMP_PS_POLL_ENQUEUE(pAd);
+		}
+	}
+
+	// 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 // AGGREGATION_SUPPORT //
+		{
+#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
+	{
+
+
+		/* check if need to resend PS Poll when received packet with MoreData = 1 */
+		if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1))
+		{
+			/* for UAPSD, all management frames will be VO priority */
+			if (pAd->CommonCfg.bAPSDAC_VO == 0)
+			{
+				/* non-UAPSD delivery-enabled AC */
+				RTMP_PS_POLL_ENQUEUE(pAd);
+			}
+		}
+
+		/* TODO: if MoreData == 0, station can go to sleep */
+
+
+		// 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
+#ifdef ANT_DIVERSITY_SUPPORT
+		// collect rssi information for antenna diversity
+		if ((pAd->NicConfig2.field.AntDiversity) &&
+			(pAd->CommonCfg.bRxAntDiversity != ANT_DIVERSITY_DISABLE))
+		{
+			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 // ANT_DIVERSITY_SUPPORT //
+#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;
+		}
+
+#ifdef RTMP_MAC_PCI
+		if (RxProcessed++ > MAX_RX_PROCESS_CNT)
+		{
+			// need to reschedule rx handle
+			bReschedule = TRUE;
+			break;
+		}
+#endif // RTMP_MAC_PCI //
+
+		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.OneSecReceivedByteCount +=  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;
+		}
+
+		/* STARxDoneInterruptHandle() is called 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 //
+		  )
+		  && ((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);
+	if (NumberOfFrag > 1)
+		RTSRequired = (pAd->CommonCfg.FragmentThreshold > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
+	else
+		RTSRequired = (PacketInfo.TotalPacketLength > pAd->CommonCfg.RtsThreshold) ? 1 : 0;
+
+	// Save RTS requirement to Ndis packet reserved field
+	RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
+	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
+			/*
+				Under WMM ACM control, we dont need to check the bit;
+				Or when a TSPEC is built for VO but we will change to issue
+				BA session for BE here, so we will not use BA to send VO packets.
+			*/
+			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
+	{
+		InsertTailQueueAc(pAd, pEntry, &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_11WEPEnabled && pEntry->WepStatus != Ndis802_11Encryption2Enabled))
+			)
+		{
+			BAOriSessionSetUp(pAd, pEntry, UserPriority, 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 RTMP_MAC_PCI
+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;
+
+	switch (QueIdx)
+	{
+		case QID_AC_BK:
+		case QID_AC_BE:
+		case QID_AC_VI:
+		case QID_AC_VO:
+		/*case QID_HCCA:*/
+			if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx)
+				FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1;
+			else
+				FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE - pAd->TxRing[QueIdx].TxCpuIdx - 1;
+
+			if (FreeNumber >= NumberRequired)
+				Status = NDIS_STATUS_SUCCESS;
+			break;
+
+		case QID_MGMT:
+			if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
+				FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1;
+			else
+				FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1;
+
+			if (FreeNumber >= NumberRequired)
+				Status = NDIS_STATUS_SUCCESS;
+			break;
+
+		default:
+			DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
+			break;
+	}
+	*FreeNumberIs = (UCHAR)FreeNumber;
+
+	return (Status);
+}
+#endif // RTMP_MAC_PCI //
+
+
+
+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)
+		{
+				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
+		{
+			{
+	    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 = (PUCHAR)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_PACKET(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 = (PUCHAR) 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 = (PUCHAR) 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
+		//
+                if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_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
+	//
+        if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_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) | (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx]<<5));
+		*(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 = (PUCHAR) 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
+	//
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_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
+	//
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_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;
+	HTTRANSMIT_SETTING	*pTransmit;
+
+
+	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 = (PUCHAR) 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)
+	{
+		RTMPCalculateMICValue(pAd, pTxBlk->pPacket, pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, 0);
+
+		// 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;
+
+	pTransmit = pTxBlk->pTransmit;
+	// Decide the TX rate
+	if (pTransmit->field.MODE == MODE_CCK)
+		pTxBlk->TxRate = pTransmit->field.MCS;
+	else if (pTransmit->field.MODE == MODE_OFDM)
+		pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
+	else
+		pTxBlk->TxRate = RATE_6_5;
+
+	// decide how much time an ACK/CTS frame will consume in the air
+	if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
+		AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
+	else
+		AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 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
+	//
+	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_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_INFO, ("AsicForceWakeup At HardTx\n"));
+#ifdef RTMP_MAC_PCI
+		AsicForceWakeup(pAd, TRUE);
+#endif // RTMP_MAC_PCI //
+	}
+
+	// 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))
+			RTMP_SET_PSM_BIT(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/rt3090/sta/sanity.c b/drivers/staging/rt3090/sta/sanity.c
new file mode 100644
index 0000000..aeda15b
--- /dev/null
+++ b/drivers/staging/rt3090/sta/sanity.c
@@ -0,0 +1,382 @@
+/*
+ *************************************************************************
+ * 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 = (PCHAR)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_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 = (PUCHAR)&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
+                    }
+                }
+                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);
+    }
+
+
+    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/rt3090/sta/sync.c b/drivers/staging/rt3090/sta/sync.c
new file mode 100644
index 0000000..2520e03
--- /dev/null
+++ b/drivers/staging/rt3090/sta/sync.c
@@ -0,0 +1,1840 @@
+/*
+ *************************************************************************
+ * 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);
+	RTMP_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))
+	{
+	RTMP_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++;
+
+#ifdef RTMP_MAC_PCI
+    if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
+        (IDLE_ON(pAd)) &&
+		(pAd->StaCfg.bRadio == TRUE) &&
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+	{
+	        if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
+		{
+			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
+			AsicCheckCommanOk(pAd, PowerWakeCID);
+			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
+			DBGPRINT(RT_DEBUG_TRACE, ("PSM - Issue Wake up command \n"));
+		}
+		else
+		{
+		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+	}
+	}
+#endif // RTMP_MAC_PCI //
+
+	// first check the parameter sanity
+	if (MlmeScanReqSanity(pAd,
+						  Elem->Msg,
+						  Elem->MsgLen,
+						  &BssType,
+						  (PCHAR)Ssid,
+						  &SsidLen,
+						  &ScanType))
+	{
+
+		// Check for channel load and noise hist request
+		// Suspend MSDU only at scan request, not the last two mentioned
+		// 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);
+
+		// 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));
+
+#ifdef RTMP_MAC_PCI
+    if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
+        (IDLE_ON(pAd)) &&
+		(pAd->StaCfg.bRadio == TRUE) &&
+		(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+	{
+		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+	}
+#endif // RTMP_MAC_PCI //
+
+	// 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)
+	{
+		RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+		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, (PCHAR)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;
+			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
+		}
+		// 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,
+								(PCHAR)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 //
+
+		Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (PCHAR)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;
+	BOOLEAN			bAllowNrate = FALSE;
+#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,
+								(PCHAR)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)
+				{
+					CHAR Rssi = 0;
+					Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+					Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod,
+										&Cf, 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->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);
+						CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
+					}
+				}
+				else
+				{
+					//
+					// 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
+			if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled))
+				|| (pAd->CommonCfg.HT_DisallowTKIP == FALSE))
+			{
+				bAllowNrate = TRUE;
+			}
+
+			pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+			pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
+
+			RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+			// filter out un-supported ht rates
+			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) &&
+				((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate)))
+			{
+				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;
+				pAd->MlmeAux.NewExtChannelOffset = 0xff;
+				RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+				pAd->MlmeAux.HtCapabilityLen = 0;
+				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));
+
+			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)
+			{
+				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,
+											&AddHtInfo,
+											AddHtInfoLen,
+											CapabilityInfo) == FALSE)
+					{
+						DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
+						return;
+					}
+
+					if (pEntry &&
+						(Elem->Wcid == RESERVED_WCID))
+				{
+						idx = pAd->StaCfg.DefaultKeyId;
+						RTMP_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)
+				{
+#ifdef RTMP_MAC_PCI
+					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+					{
+						// Restore to correct BBP R3 value
+						if (pAd->Antenna.field.RxPath > 1)
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+						// Turn clk to 80Mhz.
+					}
+#endif // RTMP_MAC_PCI //
+					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
+						RTMP_PS_POLL_ENQUEUE(pAd);
+				}
+				else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
+				{
+#ifdef RTMP_MAC_PCI
+					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+					{
+						if (pAd->Antenna.field.RxPath > 1)
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+					}
+#endif // RTMP_MAC_PCI //
+				}
+				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?
+#ifdef RTMP_MAC_PCI
+					if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
+					{
+						if (pAd->Antenna.field.RxPath > 1)
+						RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
+					}
+#endif // RTMP_MAC_PCI //
+				}
+				else
+				{
+					if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) ||
+						(pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) ||
+						(pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) ||
+						(pAd->CommonCfg.bACMAPSDTr[QID_AC_BE]))
+					{
+						/*
+							WMM Spec v1.0 3.6.2.4,
+							The WMM STA shall remain awake until it receives a
+							QoS Data or Null frame addressed to it, with the
+							EOSP subfield in QoS Control field set to 1.
+
+							So we can not sleep here or we will suffer a case:
+
+							PS Management Frame -->
+							Trigger frame -->
+							Beacon (TIM=0) (Beacon is closer to Trig frame) -->
+							Station goes to sleep -->
+							AP delivery queued UAPSD packets -->
+							Station can NOT receive the reply
+
+							Maybe we need a timeout timer to avoid that we do
+							NOT receive the EOSP frame.
+
+							We can not use More Data to check if SP is ended
+							due to MaxSPLength.
+						*/
+					}
+					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))
+						{
+							// Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
+							pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
+		                                        AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
+
+						}
+					}
+				}
+			}
+		}
+		// 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/rt3090/sta/wpa.c b/drivers/staging/rt3090/sta/wpa.c
new file mode 100644
index 0000000..2dbdba5
--- /dev/null
+++ b/drivers/staging/rt3090/sta/wpa.c
@@ -0,0 +1,396 @@
+/*
+ *************************************************************************
+ * 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"
+
+
+void inc_byte_array(UCHAR *counter, int len);
+
+/*
+	========================================================================
+
+	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
+	NdisGetSystemUpTime(&Now);
+	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)
+{
+	char custom[IW_CUSTOM_MAX] = {0};
+
+	sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
+	if(bUnicast)
+		sprintf(custom, "%s unicast", custom);
+
+	RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, (PUCHAR)custom, strlen(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
+	SET_UINT16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG)
+
+	// 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,
+		              CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 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(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE);
+		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+	}
+	else
+	{	// TKIP
+		HMAC_MD5(pAd->StaCfg.PTK,  LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE);
+	}
+	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+	// copy frame to Tx ring and send MIC failure report frame to authenticator
+	RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID],
+					  Header802_3, LENGTH_802_3,
+					  (PUCHAR)&Packet,
+					  CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 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;
+}
+
+VOID WpaStaPairwiseKeySetting(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PCIPHER_KEY pSharedKey;
+	PMAC_TABLE_ENTRY pEntry;
+
+	pEntry = &pAd->MacTab.Content[BSSID_WCID];
+
+	// Pairwise key shall use key#0
+	pSharedKey = &pAd->SharedKey[BSS0][0];
+
+	NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
+
+	// Prepare pair-wise key information into shared key table
+	NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
+	pSharedKey->KeyLen = LEN_TKIP_EK;
+    NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+	NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+	// Decide its ChiperAlg
+	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+		pSharedKey->CipherAlg = CIPHER_TKIP;
+	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+		pSharedKey->CipherAlg = CIPHER_AES;
+	else
+		pSharedKey->CipherAlg = CIPHER_NONE;
+
+	// Update these related information to MAC_TABLE_ENTRY
+	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 = pSharedKey->CipherAlg;
+
+	// Update pairwise key information to ASIC Shared Key Table
+	AsicAddSharedKeyEntry(pAd,
+						  BSS0,
+						  0,
+						  pSharedKey->CipherAlg,
+						  pSharedKey->Key,
+						  pSharedKey->TxMic,
+						  pSharedKey->RxMic);
+
+	// Update ASIC WCID attribute table and IVEIV table
+	RTMPAddWcidAttributeEntry(pAd,
+							  BSS0,
+							  0,
+							  pSharedKey->CipherAlg,
+							  pEntry);
+	STA_PORT_SECURED(pAd);
+	pAd->IndicateMediaState = NdisMediaStateConnected;
+
+	DBGPRINT(RT_DEBUG_TRACE, ("%s : AID(%d) port secured\n", __FUNCTION__, pEntry->Aid));
+
+}
+
+VOID WpaStaGroupKeySetting(
+	IN	PRTMP_ADAPTER	pAd)
+{
+	PCIPHER_KEY		pSharedKey;
+
+	pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
+
+	// Prepare pair-wise key information into shared key table
+	NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY));
+	pSharedKey->KeyLen = LEN_TKIP_EK;
+	NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
+	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_RXMICK);
+	NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_TXMICK);
+
+	// Update Shared Key CipherAlg
+	pSharedKey->CipherAlg = CIPHER_NONE;
+	if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+		pSharedKey->CipherAlg = CIPHER_TKIP;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+		pSharedKey->CipherAlg = CIPHER_AES;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+		pSharedKey->CipherAlg = CIPHER_WEP64;
+	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+		pSharedKey->CipherAlg = CIPHER_WEP128;
+
+	// Update group key information to ASIC Shared Key Table
+	AsicAddSharedKeyEntry(pAd,
+						  BSS0,
+						  pAd->StaCfg.DefaultKeyId,
+						  pSharedKey->CipherAlg,
+						  pSharedKey->Key,
+						  pSharedKey->TxMic,
+						  pSharedKey->RxMic);
+
+	// Update ASIC WCID attribute table and IVEIV table
+	RTMPAddWcidAttributeEntry(pAd,
+							  BSS0,
+							  pAd->StaCfg.DefaultKeyId,
+							  pSharedKey->CipherAlg,
+							  NULL);
+
+}
diff --git a/drivers/staging/rt3090/sta_ioctl.c b/drivers/staging/rt3090/sta_ioctl.c
new file mode 100644
index 0000000..b8ab84a
--- /dev/null
+++ b/drivers/staging/rt3090/sta_ioctl.c
@@ -0,0 +1,7557 @@
+/*
+ *************************************************************************
+ * 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
+
+#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[];
+
+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, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+  ""},
+/* --- sub-ioctls definitions --- */
+    { SHOW_CONN_STATUS,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
+	{ SHOW_DRVIER_VERION,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
+    { SHOW_BA_INFO,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
+	{ SHOW_DESC_INFO,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
+    { RAIO_OFF,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
+	{ RAIO_ON,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
+#ifdef QOS_DLS_SUPPORT
+	{ SHOW_DLS_ENTRY_INFO,
+	  IW_PRIV_TYPE_CHAR | 1024, 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" },
+	{ SHOW_ADHOC_ENTRY_INFO,
+	  IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
+/* --- 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 RTMP_RF_RW_SUPPORT
+{ RTPRIV_IOCTL_RF,
+  IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+  "rf"},
+#endif // RTMP_RF_RW_SUPPORT //
+{ 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"},
+
+
+};
+
+static __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};
+
+
+
+INT Set_SSID_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+#ifdef WMM_SUPPORT
+INT	Set_WmmCapable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+#endif
+
+INT Set_NetworkType_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_AuthMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_EncrypType_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_DefaultKeyID_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_Key1_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_Key2_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_Key3_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_Key4_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+INT Set_WPAPSK_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+
+INT Set_PSMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+#ifdef RT3090
+INT Set_PCIePSLevel_Proc(
+IN  PRTMP_ADAPTER   pAdapter,
+IN  PUCHAR          arg);
+#endif // RT3090 //
+#ifdef WPA_SUPPLICANT_SUPPORT
+INT Set_Wpa_Support(
+    IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			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);
+#endif // DBG //
+
+
+NDIS_STATUS RTMPWPANoneAddKeyProc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN	PVOID			pBuf);
+
+INT Set_FragTest_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+
+#ifdef DOT11_N_SUPPORT
+INT Set_TGnWifiTest_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING          arg);
+#endif // DOT11_N_SUPPORT //
+
+INT Set_LongRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PSTRING			arg);
+
+INT Set_ShortRetryLimit_Proc(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	PSTRING			arg);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          arg);
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef CARRIER_DETECTION_SUPPORT
+INT Set_CarrierDetect_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING          arg);
+#endif // CARRIER_DETECTION_SUPPORT //
+
+INT	Show_Adhoc_MacTable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			extra);
+
+#ifdef RTMP_RF_RW_SUPPORT
+VOID RTMPIoctlRF(
+	IN	PRTMP_ADAPTER	pAdapter,
+	IN	struct iwreq	*wrq);
+#endif // RTMP_RF_RW_SUPPORT //
+
+
+INT Set_BeaconLostTime_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING         arg);
+
+INT Set_AutoRoaming_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING         arg);
+
+INT Set_SiteSurvey_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg);
+
+INT Set_ForceTxBurst_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING         arg);
+
+#ifdef ANT_DIVERSITY_SUPPORT
+INT	Set_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg);
+#endif // ANT_DIVERSITY_SUPPORT //
+
+static struct {
+	PSTRING name;
+	INT (*set_proc)(PRTMP_ADAPTER pAdapter, PSTRING 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},
+	{"HtDisallowTKIP",				Set_HtDisallowTKIP_Proc},
+#endif // DOT11_N_SUPPORT //
+
+#ifdef AGGREGATION_SUPPORT
+	{"PktAggregate",				Set_PktAggregate_Proc},
+#endif // AGGREGATION_SUPPORT //
+
+#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 // DBG //
+
+#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
+#ifdef RTMP_EFUSE_SUPPORT
+	{"efuseFreeNumber",				set_eFuseGetFreeBlockCount_Proc},
+	{"efuseDump",					set_eFusedump_Proc},
+	{"efuseLoadFromBin",				set_eFuseLoadFromBin_Proc},
+	{"efuseBufferModeWriteBack",		set_eFuseBufferModeWriteBack_Proc},
+#endif // RTMP_EFUSE_SUPPORT //
+#ifdef ANT_DIVERSITY_SUPPORT
+	{"ant",					Set_Antenna_Proc},
+#endif // ANT_DIVERSITY_SUPPORT //
+#endif // RT30xx //
+//2008/09/11:KH add to support efuse-->
+
+	{"BeaconLostTime",				Set_BeaconLostTime_Proc},
+	{"AutoRoaming",					Set_AutoRoaming_Proc},
+	{"SiteSurvey",					Set_SiteSurvey_Proc},
+	{"ForceTxBurst",				Set_ForceTxBurst_Proc},
+
+	{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)
+{
+
+#ifdef RTMP_MAC_PCI
+    strncpy(name, "RT2860 Wireless", IFNAMSIZ);
+#endif // RTMP_MAC_PCI //
+	return 0;
+}
+
+int rt_ioctl_siwfreq(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_freq *freq, char *extra)
+{
+	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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)
+{
+	PRTMP_ADAPTER pAdapter = NULL;
+	UCHAR ch;
+	ULONG	m = 2412000;
+
+	pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	//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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	//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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	struct iw_range *range = (struct iw_range *) extra;
+	u16 val;
+	int i;
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	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 = 2412000;
+		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; /* OS_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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+    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)
+    {
+        RTMP_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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	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 NDIS_STATUS_SUCCESS;
+	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)
+		{
+			RTMP_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;
+		RTMP_MLME_HANDLER(pAdapter);
+	}while(0);
+	return NDIS_STATUS_SUCCESS;
+}
+
+int rt_ioctl_giwscan(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_point *data, char *extra)
+{
+
+	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
+	int i=0;
+	PSTRING current_ev = extra, previous_ev = extra;
+	PSTRING end_buf;
+	PSTRING current_val;
+	STRING custom[MAX_CUSTOM_LEN] = {0};
+#ifndef IWEVGENIE
+	unsigned 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, (PSTRING) 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;
+
+			if (tmpRate == 0x6c && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen > 0)
+			{
+				int rate_count = sizeof(ralinkrate)/sizeof(__s32);
+				HT_CAP_INFO capInfo = pAdapter->ScanTab.BssEntry[i].HtCapability.HtCapInfo;
+				int shortGI = capInfo.ChannelWidth ? capInfo.ShortGIfor40 : capInfo.ShortGIfor20;
+				int maxMCS = pAdapter->ScanTab.BssEntry[i].HtCapability.MCSSet[1] ?  15 : 7;
+				int rate_index = 12 + ((UCHAR)capInfo.ChannelWidth * 24) + ((UCHAR)shortGI *48) + ((UCHAR)maxMCS);
+				if (rate_index < 0)
+					rate_index = 0;
+				if (rate_index > rate_count)
+					rate_index = rate_count;
+				iwe.u.bitrate.value	=  ralinkrate[rate_index] * 500000;
+			}
+
+			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(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)
+        {
+		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(info, 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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	//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)
+	{
+		PSTRING	pSsidString = NULL;
+
+		// Includes null character.
+		if (data->length > (IW_ESSID_MAX_SIZE + 1))
+			return -E2BIG;
+
+		pSsidString = 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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	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);
+	}
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+    //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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	if (data->length > strlen((PSTRING) pAdapter->nickname) + 1)
+		data->length = strlen((PSTRING) 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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	//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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	//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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	//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)
+{
+	int kid;
+	PRTMP_ADAPTER pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	//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)
+{
+	PRTMP_ADAPTER pAdapter;
+	POS_COOKIE pObj;
+	PSTRING this_char = extra;
+	PSTRING value;
+	int  Status=0;
+
+	pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
+	if (pAdapter == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	pObj = (POS_COOKIE) pAdapter->OS_Cookie;
+	{
+		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 && (strcmp(this_char, "SiteSurvey") != 0))
+	    return -EINVAL;
+	else
+		goto SET_PROC;
+
+	// reject setting nothing besides ANY ssid(ssidLen=0)
+    if (!*value && (strcmp(this_char, "SSID") != 0))
+        return -EINVAL;
+
+SET_PROC:
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+    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	PSTRING			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, PSTRING extra)
+{
+	INT				Status = 0;
+	PRTMP_ADAPTER   pAd;
+	POS_COOKIE		pObj;
+	u32             subcmd = wrq->flags;
+
+	pAd = RTMP_OS_NETDEV_GET_PRIV(dev);
+	if (pAd == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+	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))
+            {
+                if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+		        {
+		            RTMP_MLME_RESET_STATE_MACHINE(pAd);
+		            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+		        }
+            }
+            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:
+            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, (PSTRING) wrq->pointer, extra);
+				if (Status == 0)
+					wrq->length = strlen(extra) + 1; // 1: size of '\0'
+			}
+			break;
+		case SHOW_ADHOC_ENTRY_INFO:
+			Show_Adhoc_MacTable_Proc(pAd, extra);
+			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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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);
+
+				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", __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);
+                            pAdapter->IndicateMediaState = NdisMediaStateConnected;
+                        }
+		}
+                    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);
+		        pAdapter->IndicateMediaState = NdisMediaStateConnected;
+                    }
+                }
+                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);
+			pAdapter->IndicateMediaState = NdisMediaStateConnected;
+                }
+                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);
+		        pAdapter->IndicateMediaState = NdisMediaStateConnected;
+                }
+                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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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 = (PCHAR)&(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 = (PCHAR)&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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwgenie\n"));
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+	pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+	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);
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE;
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+	}
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+	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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+	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)
+			{
+	PSTRING				this_char;
+	PSTRING				value = NULL;
+	UCHAR				regBBP = 0;
+//	CHAR				arg[255]={0};
+	UINT32				bbpId;
+	UINT32				bbpValue;
+	BOOLEAN				bIsPrintAllBBP = FALSE;
+	INT					Status = 0;
+    PRTMP_ADAPTER       pAdapter = RTMP_OS_NETDEV_GET_PRIV(dev);
+
+
+	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)
+			{
+				if (bbpId <= MAX_BBP_ID)
+				{
+#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, 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))
+			{
+				if (bbpId <= MAX_BBP_ID)
+				{
+#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, 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");
+		for (bbpId = 0; bbpId <= MAX_BBP_ID; bbpId++)
+		{
+		    if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 20))
+                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, regBBP);
+			if (bbpId%5 == 4)
+			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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+    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 = RTMP_OS_NETDEV_GET_PRIV(dev);
+    int rate_index = 0, rate_count = 0;
+    HTTRANSMIT_SETTING ht_setting;
+/* Remove to global variable
+    __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 */
+	(iw_handler) rt_ioctl_setparam, /* + 0x02 */
+#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, /* + 0x14 */
+	(iw_handler) NULL, /* + 0x15 */
+    (iw_handler) NULL, /* + 0x16 */
+	(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 pAd,
+    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;
+     PNDIS_802_11_PASSPHRASE                    ppassphrase = NULL;
+#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 (!(pAd->CommonCfg.CountryRegion & 0x80) && !(pAd->CommonCfg.CountryRegionForABand & 0x80))
+			{
+				ULONG   Country;
+				UCHAR	TmpPhy;
+
+				Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
+				pAd->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
+				pAd->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
+                TmpPhy = pAd->CommonCfg.PhyMode;
+				pAd->CommonCfg.PhyMode = 0xff;
+				// Build all corresponding channel information
+				RTMPSetPhyMode(pAd, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+				SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d  B/G:%d)\n", pAd->CommonCfg.CountryRegionForABand,
+				    pAd->CommonCfg.CountryRegion));
+            }
+            break;
+        case OID_802_11_BSSID_LIST_SCAN:
+            Now = jiffies;
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAd->RalinkCounters.LastOneSecTotalTxCount));
+
+            if (MONITOR_ON(pAd))
+            {
+                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(pAd, fRTMP_ADAPTER_RADIO_OFF))
+				break;
+
+			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+			{
+                DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
+				pAd->StaCfg.bScanReqIsFromWebUI = TRUE;
+				Status = NDIS_STATUS_SUCCESS;
+                break;
+            }
+
+			if (pAd->RalinkCounters.LastOneSecTotalTxCount > 100)
+            {
+                DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+				Status = NDIS_STATUS_SUCCESS;
+				pAd->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
+				break;
+            }
+
+            if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+				((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+				(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+				(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+				(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
+                (pAd->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;
+				pAd->StaCfg.ScanCnt = 99;		// Prevent auto scan triggered by this OID
+				break;
+            }
+
+
+            if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+            {
+                RTMP_MLME_RESET_STATE_MACHINE(pAd);
+                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.
+            pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
+            // Reset allowed scan retries
+            pAd->StaCfg.ScanCnt = 0;
+            pAd->StaCfg.LastScanTime = Now;
+
+			pAd->StaCfg.bScanReqIsFromWebUI = TRUE;
+            RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+            MlmeEnqueue(pAd,
+                        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
+            {
+		PSTRING 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(pAd, "");
+				}
+					else
+                    {
+				pSsidString = (PSTRING)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(pAd, pSsidString);
+							kfree(pSsidString);
+						}
+						else
+							Status = -ENOMEM;
+                    }
+                }
+            }
+            break;
+		case OID_802_11_SET_PASSPHRASE:
+	    ppassphrase= kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+	    if(ppassphrase== NULL)
+            {
+		Status = -ENOMEM;
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed!!\n"));
+		break;
+            }
+			else
+		{
+		Status = copy_from_user(ppassphrase, wrq->u.data.pointer, wrq->u.data.length);
+
+				if (Status)
+		{
+			Status  = -EINVAL;
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed (length mismatch)!!\n"));
+			}
+			else
+			{
+					if(ppassphrase->KeyLength < 8 || ppassphrase->KeyLength > 64)
+					{
+						Status  = -EINVAL;
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_PASSPHRASE, Failed (len less than 8 or greater than 64)!!\n"));
+					}
+					else
+					{
+						// set key passphrase and length
+						NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
+					NdisMoveMemory(pAd->StaCfg.WpaPassPhrase, &ppassphrase->KeyMaterial, ppassphrase->KeyLength);
+						pAd->StaCfg.WpaPassPhraseLen = ppassphrase->KeyLength;
+						hex_dump("pAd->StaCfg.WpaPassPhrase", pAd->StaCfg.WpaPassPhrase, 64);
+						printk("WpaPassPhrase=%s\n",pAd->StaCfg.WpaPassPhrase);
+					}
+                }
+            }
+		kfree(ppassphrase);
+			break;
+
+        case OID_802_11_BSSID:
+            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.
+                pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
+
+				// Prevent to connect AP again in STAMlmePeriodicExec
+				pAd->MlmeAux.AutoReconnectSsidLen= 32;
+
+                // Reset allowed scan retries
+				pAd->StaCfg.ScanCnt = 0;
+
+                if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+                {
+                    RTMP_MLME_RESET_STATE_MACHINE(pAd);
+                    DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+                }
+                MlmeEnqueue(pAd,
+                            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 (pAd->StaCfg.bSwRadio != RadioState)
+                {
+                    pAd->StaCfg.bSwRadio = RadioState;
+                    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;
+                        }
+                        else
+                        {
+				if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+				            {
+				                if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+						        {
+						            RTMP_MLME_RESET_STATE_MACHINE(pAd);
+						            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+						        }
+				            }
+
+                            MlmeRadioOff(pAd);
+                            // Update extra information
+							pAd->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(pAd, PhyMode);
+#ifdef DOT11_N_SUPPORT
+				SetCommonHT(pAd);
+#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
+            {
+		UINT32	Value;
+
+                Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
+                pAd->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
+                pAd->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
+                pAd->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
+                if ((pAd->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
+                    if (pAd->StaCfg.BssType == BSS_ADHOC)
+                    {
+			pAd->CommonCfg.PhyMode = StaConfig.AdhocMode;
+			RTMPSetPhyMode(pAd, PhyMode);
+                        MlmeUpdateTxRates(pAd, FALSE, 0);
+                        MakeIbssBeacon(pAd);           // re-build BEACON frame
+                        AsicEnableIbssSync(pAd);   // copy to on-chip memory
+                    }
+                }
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
+                                        pAd->CommonCfg.bEnableTxBurst,
+                                        pAd->CommonCfg.UseBGProtection,
+                                        pAd->CommonCfg.bUseShortSlotTime));
+
+				if (pAd->CommonCfg.PSPXlink)
+					Value = PSPXLINK;
+				else
+					Value = STANORMAL;
+				RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, Value);
+				Value = 0;
+				RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+				Value &= (~0x80);
+				RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+            }
+            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(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+                NdisMoveMemory(pAd->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",
+                    pAd->CommonCfg.DesireRate[0],pAd->CommonCfg.DesireRate[1],
+                    pAd->CommonCfg.DesireRate[2],pAd->CommonCfg.DesireRate[3],
+                    pAd->CommonCfg.DesireRate[4],pAd->CommonCfg.DesireRate[5],
+                    pAd->CommonCfg.DesireRate[6],pAd->CommonCfg.DesireRate[7] ));
+                // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
+                MlmeUpdateTxRates(pAd, 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)
+                {
+                    pAd->CommonCfg.TxPreamble = Preamble;
+                    MlmeSetTxPreamble(pAd, 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.
+                    pAd->CommonCfg.TxPreamble = Preamble;
+                    MlmeSetTxPreamble(pAd, 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 (pAd->StaCfg.WepStatus != WepStatus)
+                    {
+                        // Config has changed
+                        pAd->bConfigChanged = TRUE;
+                    }
+                    pAd->StaCfg.WepStatus     = WepStatus;
+                    pAd->StaCfg.OrigWepStatus = WepStatus;
+                    pAd->StaCfg.PairCipher    = WepStatus;
+			pAd->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 (pAd->StaCfg.AuthMode != AuthMode)
+                    {
+                        // Config has changed
+                        pAd->bConfigChanged = TRUE;
+                    }
+                    pAd->StaCfg.AuthMode = AuthMode;
+                }
+                pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAd->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(pAd, "Adhoc");
+				else if (BssType == Ndis802_11Infrastructure)
+					Set_NetworkType_Proc(pAd, "Infra");
+                else if (BssType == Ndis802_11Monitor)
+					Set_NetworkType_Proc(pAd, "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
+			{
+						pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+						pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+						AsicRemoveSharedKeyEntry(pAd, 0, (UCHAR)KeyIdx);
+			}
+		}
+            }
+            break;
+        case RT_OID_802_11_RESET_COUNTERS:
+            NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
+            NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
+            NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
+            pAd->Counters8023.RxNoBuffer   = 0;
+			pAd->Counters8023.GoodReceives = 0;
+			pAd->Counters8023.RxNoBuffer   = 0;
+            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
+                    pAd->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);
+                pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+                if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+                {
+                    if (FragThresh == 0)
+                    {
+                        pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+                        pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+                    }
+                    else
+                        Status  = -EINVAL;
+                }
+                else
+                    pAd->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(pAd, "CAM");
+                else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
+			Set_PSMode_Proc(pAd, "Max_PSP");
+                else if (PowerMode == Ndis802_11PowerModeFast_PSP)
+					Set_PSMode_Proc(pAd, "Fast_PSP");
+                else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
+					Set_PSMode_Proc(pAd, "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
+				pAd->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
+				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAd->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(pAd, PHY_11B);
+				else if (NetType == Ndis802_11OFDM24)
+					RTMPSetPhyMode(pAd, PHY_11BG_MIXED);
+				else if (NetType == Ndis802_11OFDM5)
+					RTMPSetPhyMode(pAd, PHY_11A);
+				else
+					Status = -EINVAL;
+#ifdef DOT11_N_SUPPORT
+				if (Status == NDIS_STATUS_SUCCESS)
+					SetCommonHT(pAd);
+#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 ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+				    (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+				    (pAd->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 ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+						 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+						 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) )     // Only for WPA PSK mode
+				{
+                    NdisMoveMemory(pAd->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
+                    // Use RaConfig as PSK agent.
+                    // Start STA supplicant state machine
+                    if (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+                        pAd->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
+                {
+                    pAd->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 (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+                {
+                    RTMPWPARemoveKeyProc(pAd, 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
+                        {
+                            pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+                            pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+                            AsicRemoveSharedKeyEntry(pAd, 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(pAd, 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))
+                     pAd->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
+
+                pAd->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
+                MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAd->CommonCfg.Channel);
+                //
+				// Save the channel on MlmeAux for CntlOidRTBssidProc used.
+				//
+				pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
+
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
+                    pConfig->BeaconPeriod, pConfig->ATIMWindow, pAd->CommonCfg.Channel));
+                // Config has changed
+                pAd->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 (pAd->CommonCfg.PhyMode	>= PHY_11ABGN_MIXED)
+					RTMPSetHT(pAd,	pHTPhyMode);
+			}
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
+				pAd->StaCfg.HTPhyMode.field.MCS, pAd->StaCfg.HTPhyMode.field.BW, pAd->StaCfg.HTPhyMode.field.ShortGI,
+				pAd->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	|
+				---------------------------------------------------------------------*/
+				pAd->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE :	FALSE;
+				pAd->CommonCfg.bAPSDAC_BE = ((apsd	& 0x00000002) >> 1)	? TRUE : FALSE;
+				pAd->CommonCfg.bAPSDAC_BK = ((apsd	& 0x00000004) >> 2)	? TRUE : FALSE;
+				pAd->CommonCfg.bAPSDAC_VI = ((apsd	& 0x00000008) >> 3)	? TRUE : FALSE;
+				pAd->CommonCfg.bAPSDAC_VO = ((apsd	& 0x00000010) >> 4)	? TRUE : FALSE;
+				pAd->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, pAd->CommonCfg.bAPSDCapable,
+					pAd->CommonCfg.bAPSDAC_BE,	pAd->CommonCfg.bAPSDAC_BK,	pAd->CommonCfg.bAPSDAC_VI,	pAd->CommonCfg.bAPSDAC_VO,	pAd->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(&pAd->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
+				if (pAd->CommonCfg.bAPSDForcePowerSave	!= pAd->StaCfg.Psm)
+				{
+					RTMP_SET_PSM_BIT(pAd,	pAd->CommonCfg.bAPSDForcePowerSave);
+					RTMPSendNullFrame(pAd,	pAd->CommonCfg.TxRate,	TRUE);
+				}
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n",	pAd->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 = pAd->CommonCfg.bDLSCapable;
+				Status = copy_from_user(&pAd->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
+				if (oldvalue &&	!pAd->CommonCfg.bDLSCapable)
+				{
+					int	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))
+						{
+							pAd->StaCfg.DLSEntry[i].Status	= DLS_NONE;
+							pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+							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;
+							pAd->StaCfg.DLSEntry[i].Valid	= FALSE;
+							RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+						}
+					}
+				}
+
+				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAd->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(pAd,
+							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(&pAd->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
+				DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d)	\n", pAd->CommonCfg.bWmmCapable));
+			}
+			break;
+
+		case OID_802_11_DISASSOCIATE:
+			//
+			// 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.
+			//
+			pAd->CommonCfg.NdisRadioStateOff =	TRUE;
+			// Set to immediately send the media disconnect	event
+			pAd->MlmeAux.CurrReqIsFromNdis	= TRUE;
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE	\n"));
+
+
+			if (INFRA_ON(pAd))
+			{
+				if (pAd->Mlme.CntlMachine.CurrState !=	CNTL_IDLE)
+				{
+					RTMP_MLME_RESET_STATE_MACHINE(pAd);
+					DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME	busy, reset	MLME state machine !!!\n"));
+				}
+
+				MlmeEnqueue(pAd,
+					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)
+					{
+						pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+						pAd->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+						pAd->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+						pAd->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+						pAd->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+						pAd->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
+						pAd->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+						// UPdata to HT IE
+						pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+						pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+						pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+					}
+					else
+					{
+                        pAd->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
+						pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
+						pAd->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+						pAd->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+						pAd->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+						pAd->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+						pAd->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
+						pAd->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+
+						// UPdata to HT IE
+						pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+						pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+						pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+
+						if (pAd->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
+							pAd->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
+
+					}
+
+					pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
+					DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAd->CommonCfg.BACapability.field.Policy,
+						pAd->CommonCfg.BACapability.field.RxBAWinLimit,pAd->CommonCfg.BACapability.field.TxBAWinLimit, pAd->CommonCfg.BACapability.field.AutoBA));
+					DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAd->CommonCfg.DesiredHtPhy.MimoPs, pAd->CommonCfg.DesiredHtPhy.AmsduEnable,
+						pAd->CommonCfg.DesiredHtPhy.AmsduSize, pAd->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(pAd, 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)
+							pAd->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
+
+						BAOriSessionSetUp(pAd, pEntry, index, 0, 100, TRUE);
+					}
+					else
+					{
+						//BATableInsertEntry(pAd, 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(pAd, pBA->MACAddr);
+						DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
+						if (pEntry)
+						{
+							DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
+							BAOriSessionTearDown(pAd, pEntry->Aid, pBA->TID, FALSE, TRUE);
+						}
+						else
+							DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
+					}
+					else
+					{
+						pEntry = MacTableLookup(pAd, pBA->MACAddr);
+						if (pEntry)
+						{
+							BARecSessionTearDown( pAd, (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(pAd->SharedKey[BSS0][KeyIdx].Key, 16);
+                    pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+                    NdisMoveMemory(pAd->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;
+                    }
+                    pAd->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(pAd->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
+                        pAd->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+                        NdisMoveMemory(pAd->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+                        pAd->StaCfg.DesireSharedKeyId = KeyIdx;
+                        pAd->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
+#endif // WPA_SUPPLICANT_SUPPORT //
+                        pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+                    }
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+					if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
+						(pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+					{
+						Key = pWepKey->KeyMaterial;
+
+						// 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);
+
+						STA_PORT_SECURED(pAd);
+
+					// Indicate Connected for GUI
+					pAd->IndicateMediaState = NdisMediaStateConnected;
+					}
+                    else if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
+#endif // WPA_SUPPLICANT_SUPPORT
+                    {
+                        Key = pAd->SharedKey[BSS0][KeyIdx].Key;
+
+                        // Set key material and cipherAlg to Asic
+					AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+                        if (pWepKey->KeyIndex & 0x80000000)
+                        {
+                            PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[BSSID_WCID];
+                            // Assign group key info
+						RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
+						// Assign pairwise key info
+						RTMPAddWcidAttributeEntry(pAd, 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, (pAd->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)
+                    pAd->StaCfg.bBlockAssoc = TRUE;
+                else
+                    // WPA MIC error should block association attempt for 60 seconds
+                    pAd->StaCfg.bBlockAssoc = FALSE;
+                DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAd->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);
+			pAd->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
+			DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAd->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);
+                if (MsgElem == NULL)
+                {
+			DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __FUNCTION__));
+                        return -EINVAL;
+                }
+
+                pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
+                Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
+                MlmeDeauthReqAction(pAd, MsgElem);
+				kfree(MsgElem);
+
+                if (INFRA_ON(pAd))
+                {
+                    LinkDown(pAd, FALSE);
+                    pAd->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)
+                    pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+                else
+                    pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+				NdisAcquireSpinLock(&pAd->MacTabLock);
+				pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
+				NdisReleaseSpinLock(&pAd->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);
+		        pAd->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);
+				pAd->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(pAd->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 < pAd->StaCfg.SavedPMKNum; CachedIdx++)
+			        {
+				        // compare the BSSID
+				        if (NdisEqualMemory(pBssIdInfo->BSSID, pAd->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(&pAd->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+				        pAd->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(&pAd->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(pAd, TX_RTY_CFG, &tx_rty_cfg.word);
+				tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+				RTMP_IO_WRITE32(pAd, 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(pAd, TX_RTY_CFG, &tx_rty_cfg.word);
+				tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+				RTMP_IO_WRITE32(pAd, 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
+			{
+				pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
+				NdisMoveMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
+				if (pKey->KeyIndex & 0x80000000)
+				{
+					// Default key for tx (shared key)
+					pAd->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(&pAd->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((PSTRING)&ctmp,"%d", ctmp);
+				Set_Channel_Proc(pAd, (PSTRING)&ctmp);
+			}
+			break;
+#endif
+
+
+
+		case RT_OID_802_11_SET_PSPXLINK_MODE:
+			if (wrq->u.data.length != sizeof(BOOLEAN))
+                Status  = -EINVAL;
+            else
+            {
+                Status = copy_from_user(&pAd->CommonCfg.PSPXlink, wrq->u.data.pointer, wrq->u.data.length);
+				/*if (pAd->CommonCfg.PSPXlink)
+					RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS)*/
+				DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_PSPXLINK_MODE(=%d) \n", pAd->CommonCfg.PSPXlink));
+            }
+			break;
+
+
+        default:
+            DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+            Status = -EOPNOTSUPP;
+            break;
+    }
+
+
+    return Status;
+}
+
+INT RTMPQueryInformation(
+    IN  PRTMP_ADAPTER pAd,
+    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;
+	STRING								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(pAd->nickname);
+            Status = copy_to_user(wrq->u.data.pointer, pAd->nickname, 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(CHAR);
+			sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
+			driverVersion[7] = '\0';
+			if (copy_to_user(wrq->u.data.pointer, &driverVersion[0], wrq->u.data.length))
+            {
+				Status = -EFAULT;
+            }
+            break;
+
+        case OID_802_11_BSSID_LIST:
+            if (RTMP_TEST_FLAG(pAd, 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",pAd->ScanTab.BssNr));
+			pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+            // Claculate total buffer size required
+            BssBufSize = sizeof(ULONG);
+
+            for (i = 0; i < pAd->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) + pAd->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 = pAd->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 < pAd->ScanTab.BssNr; i++)
+            {
+                pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
+                NdisMoveMemory(&pBss->MacAddress, &pAd->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
+                if ((pAd->ScanTab.BssEntry[i].Hidden == 1) && (pAd->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 ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
+					{
+						pBss->Ssid.SsidLength = pAd->ScanTab.BssEntry[i].SsidLen;
+						NdisMoveMemory(pBss->Ssid.Ssid, pAd->ScanTab.BssEntry[i].Ssid, pAd->ScanTab.BssEntry[i].SsidLen);
+					}
+					else
+			pBss->Ssid.SsidLength = 0;
+                }
+                else
+                {
+                    pBss->Ssid.SsidLength = pAd->ScanTab.BssEntry[i].SsidLen;
+                    NdisMoveMemory(pBss->Ssid.Ssid, pAd->ScanTab.BssEntry[i].Ssid, pAd->ScanTab.BssEntry[i].SsidLen);
+                }
+                pBss->Privacy = pAd->ScanTab.BssEntry[i].Privacy;
+                pBss->Rssi = pAd->ScanTab.BssEntry[i].Rssi - pAd->BbpRssiToDbmDelta;
+                pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAd->ScanTab.BssEntry[i]);
+                pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
+                pBss->Configuration.BeaconPeriod = pAd->ScanTab.BssEntry[i].BeaconPeriod;
+                pBss->Configuration.ATIMWindow = pAd->ScanTab.BssEntry[i].AtimWin;
+
+                MAP_CHANNEL_ID_TO_KHZ(pAd->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
+
+                if (pAd->ScanTab.BssEntry[i].BssType == BSS_INFRA)
+                    pBss->InfrastructureMode = Ndis802_11Infrastructure;
+                else
+                    pBss->InfrastructureMode = Ndis802_11IBSS;
+
+                NdisMoveMemory(pBss->SupportedRates, pAd->ScanTab.BssEntry[i].SupRate, pAd->ScanTab.BssEntry[i].SupRateLen);
+                NdisMoveMemory(pBss->SupportedRates + pAd->ScanTab.BssEntry[i].SupRateLen,
+                               pAd->ScanTab.BssEntry[i].ExtRate,
+                               pAd->ScanTab.BssEntry[i].ExtRateLen);
+
+                if (pAd->ScanTab.BssEntry[i].VarIELen == 0)
+                {
+                    pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
+                    NdisMoveMemory(pBss->IEs, &pAd->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) + pAd->ScanTab.BssEntry[i].VarIELen);
+                    pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
+                    NdisMoveMemory(pBss->IEs, &pAd->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
+                    NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAd->ScanTab.BssEntry[i].VarIEs, pAd->ScanTab.BssEntry[i].VarIELen);
+                    pPtr += pAd->ScanTab.BssEntry[i].VarIELen;
+                }
+                pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAd->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, &pAd->CurrentAddress, wrq->u.data.length);
+            break;
+        case OID_GEN_MEDIA_CONNECT_STATUS:
+            if (pAd->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:
+            if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+            {
+                Status = copy_to_user(wrq->u.data.pointer, &pAd->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 = pAd->CommonCfg.SsidLen;
+			memcpy(Ssid.Ssid, pAd->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[pAd->CommonCfg.TxRate];   // unit : 500 kbps
+                pLinkStatus->ChannelQuality = pAd->Mlme.ChannelQuality;
+                pLinkStatus->RxByteCount = pAd->RalinkCounters.ReceivedByteCount;
+                pLinkStatus->TxByteCount = pAd->RalinkCounters.TransmittedByteCount;
+			pLinkStatus->CentralChannel = pAd->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 = pAd->CommonCfg.BeaconPeriod;
+                pConfiguration->ATIMWindow = pAd->StaActive.AtimWin;
+                MAP_CHANNEL_ID_TO_KHZ(pAd->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, pAd->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 ((pAd->StaCfg.LastSNR0 > 0))
+			{
+				ulInfo = ((0xeb	- pAd->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 ((pAd->Antenna.field.RxPath	> 1) &&
+                (pAd->StaCfg.LastSNR1 > 0))
+			{
+				ulInfo = ((0xeb	- pAd->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(pAd->StaCfg.LastSNR1=%d)\n",pAd->StaCfg.LastSNR1));
+			break;
+        case OID_802_11_RSSI_TRIGGER:
+            ulInfo = pAd->StaCfg.RssiSample.LastRssi0 - pAd->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 = pAd->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 = pAd->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 = pAd->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(pAd);
+
+                // Sanity check for calculation of sucessful count
+                if (pAd->WlanCounters.TransmittedFragmentCount.QuadPart < pAd->WlanCounters.RetryCount.QuadPart)
+                    pAd->WlanCounters.TransmittedFragmentCount.QuadPart = pAd->WlanCounters.RetryCount.QuadPart;
+
+                pStatistics->TransmittedFragmentCount.QuadPart = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
+                pStatistics->MulticastTransmittedFrameCount.QuadPart = pAd->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
+                pStatistics->FailedCount.QuadPart = pAd->WlanCounters.FailedCount.QuadPart;
+                pStatistics->RetryCount.QuadPart = pAd->WlanCounters.RetryCount.QuadPart;
+                pStatistics->MultipleRetryCount.QuadPart = pAd->WlanCounters.MultipleRetryCount.QuadPart;
+                pStatistics->RTSSuccessCount.QuadPart = pAd->WlanCounters.RTSSuccessCount.QuadPart;
+                pStatistics->RTSFailureCount.QuadPart = pAd->WlanCounters.RTSFailureCount.QuadPart;
+                pStatistics->ACKFailureCount.QuadPart = pAd->WlanCounters.ACKFailureCount.QuadPart;
+                pStatistics->FrameDuplicateCount.QuadPart = pAd->WlanCounters.FrameDuplicateCount.QuadPart;
+                pStatistics->ReceivedFragmentCount.QuadPart = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
+                pStatistics->MulticastReceivedFrameCount.QuadPart = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;
+#ifdef DBG
+                pStatistics->FCSErrorCount = pAd->RalinkCounters.RealFcsErrCount;
+#else
+                pStatistics->FCSErrorCount.QuadPart = pAd->WlanCounters.FCSErrorCount.QuadPart;
+                pStatistics->FrameDuplicateCount.u.LowPart = pAd->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 = pAd->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 = pAd->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)pAd->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 = pAd->CommonCfg.bEnableTxBurst;
+                pStaConfig->EnableTurboRate = 0;
+                pStaConfig->UseBGProtection = pAd->CommonCfg.UseBGProtection;
+                pStaConfig->UseShortSlotTime = pAd->CommonCfg.bUseShortSlotTime;
+                //pStaConfig->AdhocMode = pAd->StaCfg.AdhocMode;
+                pStaConfig->HwRadioStatus = (pAd->StaCfg.bHwRadio == TRUE) ? 1 : 0;
+                pStaConfig->Rsv1 = 0;
+                pStaConfig->SystemErrorBitmap = pAd->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 = pAd->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 = pAd->CommonCfg.FragmentThreshold;
+            if (pAd->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 = pAd->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) pAd->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 (pAd->StaCfg.BssType == BSS_ADHOC)
+                BssType = Ndis802_11IBSS;
+            else if (pAd->StaCfg.BssType == BSS_INFRA)
+                BssType = Ndis802_11Infrastructure;
+            else if (pAd->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 = pAd->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 = pAd->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 = pAd->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, &pAd->CommonCfg.TxPower, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAd->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, &pAd->CommonCfg.TxPowerPercentage, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
+			break;
+        case OID_802_11_NETWORK_TYPES_SUPPORTED:
+			if ((pAd->RfIcType	== RFIC_2850) || (pAd->RfIcType ==	RFIC_2750) || (pAd->RfIcType == RFIC_3052))
+			{
+				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 (pAd->CommonCfg.PhyMode == PHY_11A)
+				ulInfo = Ndis802_11OFDM5;
+			else if ((pAd->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAd->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)pAd->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)pAd->LastTxRate;
+			ulInfo = (ULONG)pAd->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, &pAd->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, &pAd->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, &pAd->BbpWriteLatch[66], wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAd->BbpWriteLatch[66]));
+			break;
+	    case RT_OID_802_11_EXTRA_INFO:
+			wrq->u.data.length = sizeof(ULONG);
+			Status = copy_to_user(wrq->u.data.pointer, &pAd->ExtraInfo, wrq->u.data.length);
+	        DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAd->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 = (pAd->CommonCfg.bAPSDCapable | (pAd->CommonCfg.bAPSDAC_BE << 1) | (pAd->CommonCfg.bAPSDAC_BK << 2)
+				| (pAd->CommonCfg.bAPSDAC_VI << 3)	| (pAd->CommonCfg.bAPSDAC_VO << 4)	| (pAd->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,pAd->CommonCfg.bAPSDCapable,pAd->CommonCfg.bAPSDAC_BE,pAd->CommonCfg.bAPSDAC_BK,pAd->CommonCfg.bAPSDAC_VI,pAd->CommonCfg.bAPSDAC_VO,pAd->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, &pAd->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAd->CommonCfg.bAPSDForcePowerSave));
+			break;
+		case RT_OID_802_11_QUERY_WMM:
+			wrq->u.data.length = sizeof(BOOLEAN);
+			Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.bWmmCapable, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n",	pAd->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, &pAd->StaCfg.WpaSupplicantUP, wrq->u.data.length);
+            DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAd->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, pAd->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 = pAd->CommonCfg.PhyMode;
+			pHTPhyMode->HtMode = (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
+			pHTPhyMode->BW = (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
+			pHTPhyMode->MCS= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
+			pHTPhyMode->SHORTGI= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
+			pHTPhyMode->STBC= (UCHAR)pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
+
+			pHTPhyMode->ExtOffset = ((pAd->CommonCfg.CentralChannel < pAd->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", pAd->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 = pAd->CommonCfg.CountryRegionForABand;
+            ulInfo = (ulInfo << 8)|(pAd->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 = pAd->CommonCfg.PhyMode;
+			pHTPhyMode->HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
+			pHTPhyMode->BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
+			pHTPhyMode->MCS= (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+			pHTPhyMode->SHORTGI= (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
+			pHTPhyMode->STBC= (UCHAR)pAd->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", pAd->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, &pAd->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, &pAd->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 (pAd->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 = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen;
+			NdisMoveMemory(pKeyIdxValue->Value,
+						   &pAd->SharedKey[BSS0][pAd->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",
+										pAd->StaCfg.DefaultKeyId,
+										wrq->u.data.length,
+										pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
+										pAd->SharedKey[BSS0][0].Key[0],
+										pAd->SharedKey[BSS0][1].Key[0],
+										pAd->SharedKey[BSS0][2].Key[0],
+										pAd->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, &pAd->StaCfg.DefaultKeyId, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAd->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,
+									&pAd->SharedKey[BSS0][pAd->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(pAd, 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(pAd, 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 RTMP_MAC_PCI
+			{
+
+				USHORT  device_id;
+				if (((POS_COOKIE)pAd->OS_Cookie)->pci_dev != NULL)
+				pci_read_config_word(((POS_COOKIE)pAd->OS_Cookie)->pci_dev, PCI_DEVICE_ID, &device_id);
+				else
+					DBGPRINT(RT_DEBUG_TRACE, (" pci_dev = NULL\n"));
+				sprintf((PSTRING)tmp, "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id);
+			}
+#endif // RTMP_MAC_PCI //
+			wrq->u.data.length = strlen((PSTRING)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), pAd->CommonCfg.Channel));
+			Status = copy_to_user(wrq->u.data.pointer, &pAd->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 (pAd->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 = pAd->ChannelListNum;
+				for (i = 0; i < pChListBuf->ChannelListNum; i++)
+					pChListBuf->ChannelList[i] = pAd->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, &pAd->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, &pAd->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, &pAd->CommonCfg.bDLSCapable, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAd->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], &pAd->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 //
+
+		case OID_802_11_SET_PSPXLINK_MODE:
+			wrq->u.data.length = sizeof(BOOLEAN);
+            Status = copy_to_user(wrq->u.data.pointer, &pAd->CommonCfg.PSPXlink, wrq->u.data.length);
+			DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SET_PSPXLINK_MODE(=%d)\n", pAd->CommonCfg.PSPXlink));
+			break;
+
+
+        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;
+	RTMP_ADAPTER        *pAd = NULL;
+	struct iwreq        *wrq = (struct iwreq *) rq;
+	BOOLEAN				StateMachineTouched = FALSE;
+	INT					Status = NDIS_STATUS_SUCCESS;
+	USHORT				subcmd;
+
+
+	pAd = RTMP_OS_NETDEV_GET_PRIV(net_dev);
+	if (pAd == NULL)
+	{
+		/* if 1st open fail, pAd will be free;
+		   So the net_dev->priv will be NULL in 2rd open */
+		return -ENETDOWN;
+	}
+	pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+    //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	*erq = NULL;
+		erq = &wrq->u.data;
+            erq->length = strlen((PSTRING) pAd->nickname);
+            Status = copy_to_user(erq->pointer, pAd->nickname, erq->length);
+			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)
+			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)
+			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 RTMP_RF_RW_SUPPORT
+		case RTPRIV_IOCTL_RF:
+			RTMPIoctlRF(pAd, wrq);
+			break;
+#endif // RTMP_RF_RW_SUPPORT //
+#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
+	RTMP_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  PSTRING          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)
+        {
+            RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
+            DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+        }
+
+		if ((pAdapter->StaCfg.WpaPassPhraseLen >= 8) &&
+			(pAdapter->StaCfg.WpaPassPhraseLen <= 64))
+		{
+			STRING passphrase_str[65] = {0};
+			UCHAR keyMaterial[40];
+
+			RTMPMoveMemory(passphrase_str, pAdapter->StaCfg.WpaPassPhrase, pAdapter->StaCfg.WpaPassPhraseLen);
+			RTMPZeroMemory(pAdapter->StaCfg.PMK, 32);
+			if (pAdapter->StaCfg.WpaPassPhraseLen == 64)
+			{
+			    AtoH((PSTRING) pAdapter->StaCfg.WpaPassPhrase, pAdapter->StaCfg.PMK, 32);
+			}
+			else
+			{
+			    PasswordHash((PSTRING) pAdapter->StaCfg.WpaPassPhrase, Ssid.Ssid, Ssid.SsidLength, keyMaterial);
+			    NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
+			}
+		}
+
+        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
+	RTMP_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	PSTRING			arg)
+{
+	BOOLEAN	bWmmCapable;
+
+	bWmmCapable = simple_strtol(arg, 0, 10);
+
+	if ((bWmmCapable == 1)
+		)
+		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  PSTRING          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"));
+	}
+    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
+			RTMP_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  PSTRING          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  PSTRING          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  PSTRING          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  PSTRING          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  PSTRING          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  PSTRING          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  PSTRING          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   pAd,
+    IN  PSTRING          arg)
+{
+    int status;
+
+    if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+        (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+	    (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+		)
+        return TRUE;    // do nothing
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
+
+	status = RT_CfgSetWPAPSKKey(pAd, arg, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, pAd->StaCfg.PMK);
+	if (status == FALSE)
+	{
+		DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc(): Set key failed!\n"));
+		return FALSE;
+	}
+	NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
+    NdisMoveMemory(pAd->StaCfg.WpaPassPhrase, arg, strlen(arg));
+    pAd->StaCfg.WpaPassPhraseLen = (UINT)strlen(arg);
+
+
+
+    if(pAd->StaCfg.BssType == BSS_ADHOC &&
+       pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+    {
+        pAd->StaCfg.WpaState = SS_NOTUSE;
+    }
+    else
+    {
+        // Start STA supplicant state machine
+        pAd->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  PSTRING          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 MlmeCheckPsmChange()
+            // 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 MlmeCheckPsmChange()
+            // 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 MlmeCheckPsmChange()
+            // 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
+            RTMP_SET_PSM_BIT(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;
+}
+//Add to suport the function which clould dynamicallly enable/disable PCIe Power Saving
+
+#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	PSTRING			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)
+{
+	PSTRING				this_char;
+	PSTRING				value;
+	INT					j = 0, k = 0;
+	STRING				msg[1024];
+	STRING				arg[255];
+	ULONG				macAddr = 0;
+	UCHAR				temp[16];
+	STRING				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;
+		PSTRING			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)
+{
+	PSTRING				this_char;
+	PSTRING				value;
+	INT					j = 0, k = 0;
+	STRING				msg[1024];
+	STRING				arg[255];
+	USHORT				eepAddr = 0;
+	UCHAR				temp[16];
+	STRING				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;
+		PSTRING			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;
+	STRING				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((PSTRING) this_char, "%d", &(rfId)) == 1)
+			{
+				if (rfId <= 31)
+				{
+#ifdef RALINK_ATE
+					/*
+						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.
+					*/
+					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, 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((PSTRING) this_char, "%d", &(rfId)) == 1) && (sscanf((PSTRING) value, "%lx", &(rfValue)) == 1))
+			{
+				if (rfId <= 31)
+				{
+#ifdef RALINK_ATE
+						/*
+							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.
+						*/
+						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, 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, 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++)
+		{
+#ifdef RALINK_ATE
+			/*
+				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.
+			*/
+			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  PSTRING          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;
+}
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+    IN  PRTMP_ADAPTER   pAdapter,
+    IN  PSTRING          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  PSTRING         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 //
+
+
+INT	Show_Adhoc_MacTable_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			extra)
+{
+	INT i;
+
+	sprintf(extra, "\n");
+
+#ifdef DOT11_N_SUPPORT
+	sprintf(extra, "%sHT Operating Mode : %d\n", extra, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
+#endif // DOT11_N_SUPPORT //
+
+	sprintf(extra, "%s\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", extra,
+			"MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
+
+	for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+	{
+		PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+
+		if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
+		    break;
+		if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
+		{
+			sprintf(extra, "%s%02X:%02X:%02X:%02X:%02X:%02X  ", extra,
+				pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+				pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+			sprintf(extra, "%s%-4d", extra, (int)pEntry->Aid);
+			sprintf(extra, "%s%-4d", extra, (int)pEntry->apidx);
+			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi0);
+			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi1);
+			sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi2);
+			sprintf(extra, "%s%-10s", extra, GetPhyMode(pEntry->HTPhyMode.field.MODE));
+			sprintf(extra, "%s%-6s", extra, GetBW(pEntry->HTPhyMode.field.BW));
+			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.MCS);
+			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.ShortGI);
+			sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.STBC);
+			sprintf(extra, "%s%-10d, %d, %d%%\n", extra, pEntry->DebugFIFOCount, pEntry->DebugTxCount,
+						(pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
+			sprintf(extra, "%s\n", extra);
+		}
+	}
+
+	return TRUE;
+}
+
+
+INT Set_BeaconLostTime_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING         arg)
+{
+	ULONG ltmp = (ULONG)simple_strtol(arg, 0, 10);
+
+	if ((ltmp != 0) && (ltmp <= 60))
+		pAd->StaCfg.BeaconLostTime = (ltmp * OS_HZ);
+
+    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_BeaconLostTime_Proc::(BeaconLostTime=%ld)\n", pAd->StaCfg.BeaconLostTime));
+	return TRUE;
+}
+
+INT Set_AutoRoaming_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING         arg)
+{
+    if (simple_strtol(arg, 0, 10) == 0)
+        pAd->StaCfg.bAutoRoaming = FALSE;
+    else
+        pAd->StaCfg.bAutoRoaming = TRUE;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_AutoRoaming_Proc::(bAutoRoaming=%d)\n", pAd->StaCfg.bAutoRoaming));
+	return TRUE;
+}
+
+
+/*
+    ==========================================================================
+    Description:
+        Issue a site survey command to driver
+	Arguments:
+	    pAdapter                    Pointer to our adapter
+	    wrq                         Pointer to the ioctl argument
+
+    Return Value:
+        None
+
+    Note:
+        Usage:
+               1.) iwpriv ra0 set site_survey
+    ==========================================================================
+*/
+INT Set_SiteSurvey_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PSTRING			arg)
+{
+	NDIS_802_11_SSID Ssid;
+
+	//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 (MONITOR_ON(pAd))
+    {
+        DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
+        return -EINVAL;
+    }
+
+	RTMPZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+	Ssid.SsidLength = 0;
+	if ((arg != NULL) &&
+		(strlen(arg) <= MAX_LEN_OF_SSID))
+    {
+        RTMPMoveMemory(Ssid.Ssid, arg, strlen(arg));
+        Ssid.SsidLength = strlen(arg);
+	}
+
+	pAd->StaCfg.bScanReqIsFromWebUI = TRUE;
+
+	if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+	{
+		RTMP_MLME_RESET_STATE_MACHINE(pAd);
+		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.
+	pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
+	// Reset allowed scan retries
+	pAd->StaCfg.ScanCnt = 0;
+	NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
+
+	MlmeEnqueue(pAd,
+		MLME_CNTL_STATE_MACHINE,
+		OID_802_11_BSSID_LIST_SCAN,
+		Ssid.SsidLength,
+		Ssid.Ssid);
+
+	RTMP_MLME_HANDLER(pAd);
+
+    DBGPRINT(RT_DEBUG_TRACE, ("Set_SiteSurvey_Proc\n"));
+
+    return TRUE;
+}
+
+INT Set_ForceTxBurst_Proc(
+    IN  PRTMP_ADAPTER   pAd,
+    IN  PSTRING         arg)
+{
+    if (simple_strtol(arg, 0, 10) == 0)
+        pAd->StaCfg.bForceTxBurst = FALSE;
+    else
+        pAd->StaCfg.bForceTxBurst = TRUE;
+
+    DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ForceTxBurst_Proc::(bForceTxBurst=%d)\n", pAd->StaCfg.bForceTxBurst));
+	return TRUE;
+}
+
+#ifdef ANT_DIVERSITY_SUPPORT
+INT	Set_Antenna_Proc(
+	IN	PRTMP_ADAPTER	pAd,
+	IN	PUCHAR			arg)
+{
+    UCHAR UsedAnt;
+	DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Antenna_Proc *******************\n"));
+
+    if(simple_strtol(arg, 0, 10) <= 3)
+        UsedAnt = simple_strtol(arg, 0, 10);
+
+    pAd->CommonCfg.bRxAntDiversity = UsedAnt; // Auto switch
+    if (UsedAnt == ANT_DIVERSITY_ENABLE)
+    {
+            pAd->RxAnt.EvaluateStableCnt = 0;
+            DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Antenna_Proc(Auto Switch Mode), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+    }
+    /* 2: Fix in the PHY Antenna CON1*/
+    if (UsedAnt == ANT_FIX_ANT1)
+    {
+            AsicSetRxAnt(pAd, 0);
+            DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Antenna_Proc(Fix in Ant CON1), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+    }
+    /* 3: Fix in the PHY Antenna CON2*/
+    if (UsedAnt == ANT_FIX_ANT2)
+    {
+            AsicSetRxAnt(pAd, 1);
+            DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Antenna_Proc(Fix in Ant CON2), (%d,%d)\n", pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+    }
+
+	return TRUE;
+}
+#endif // ANT_DIVERSITY_SUPPORT //
\ No newline at end of file
diff --git a/drivers/staging/rt3090/vr_ikans.h b/drivers/staging/rt3090/vr_ikans.h
new file mode 100644
index 0000000..16bff3b
--- /dev/null
+++ b/drivers/staging/rt3090/vr_ikans.h
@@ -0,0 +1,71 @@
+/*
+ *************************************************************************
+ * 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:
+	vr_ikans.h
+
+    Abstract:
+    Handle association related requests either from WSTA or from local MLME
+
+    Revision History:
+    Who          When          What
+    ---------    ----------    ----------------------------------------------
+    Sample Lin	01-28-2008    Created
+ */
+
+#ifndef __VR_IKANS_H__
+#define __VR_IKANS_H__
+
+#ifndef MODULE_IKANOS
+#define IKANOS_EXTERN	extern
+#else
+#define IKANOS_EXTERN
+#endif // MODULE_IKANOS //
+
+#ifdef IKANOS_VX_1X0
+	typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
+
+	struct IKANOS_TX_INFO
+	{
+		struct net_device *netdev;
+		IkanosWlanTxCbFuncP *fp;
+	};
+#endif // IKANOS_VX_1X0 //
+
+
+IKANOS_EXTERN void VR_IKANOS_FP_Init(UINT8 BssNum, UINT8 *pApMac);
+
+IKANOS_EXTERN INT32 IKANOS_DataFramesTx(struct sk_buff *pSkb,
+										struct net_device *pNetDev);
+
+IKANOS_EXTERN void IKANOS_DataFrameRx(PRTMP_ADAPTER pAd,
+										void *pRxParam,
+										struct sk_buff *pSkb,
+										UINT32 Length);
+
+#endif // __VR_IKANS_H__ //
+
+/* End of vr_ikans.h */
diff --git a/drivers/staging/rt3090/wpa.h b/drivers/staging/rt3090/wpa.h
new file mode 100644
index 0000000..8baa287
--- /dev/null
+++ b/drivers/staging/rt3090/wpa.h
@@ -0,0 +1,447 @@
+/*
+ *************************************************************************
+ * 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 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))
+#define MIN_LEN_OF_GTK				5
+#define LEN_PMK						32
+#define LEN_PMK_NAME				16
+#define LEN_NONCE					32
+
+// RSN IE Length definition
+#define MAX_LEN_OF_RSNIE		255
+#define MIN_LEN_OF_RSNIE		8
+
+#define KEY_LIFETIME				3600
+
+//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
+
+// WPA mechanism retry timer interval
+#define PEER_MSG1_RETRY_EXEC_INTV           1000			// 1 sec
+#define PEER_MSG3_RETRY_EXEC_INTV           3000			// 3 sec
+#define GROUP_KEY_UPDATE_EXEC_INTV          1000				// 1 sec
+#define PEER_GROUP_KEY_UPDATE_INIV			2000				// 2 sec
+
+#define ENQUEUE_EAPOL_START_TIMER			200					// 200 ms
+
+// group rekey interval
+#define TIME_REKEY                          0
+#define PKT_REKEY                           1
+#define DISABLE_REKEY                       2
+#define MAX_REKEY                           2
+
+#define MAX_REKEY_INTER                     0x3ffffff
+
+#define GROUP_SUITE					0
+#define PAIRWISE_SUITE				1
+#define AKM_SUITE					2
+#define PMKID_LIST					3
+
+
+#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)
+
+#ifndef ROUND_UP
+#define ROUND_UP(__x, __y) \
+	(((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
+#endif
+
+#define	SET_UINT16_TO_ARRARY(_V, _LEN)		\
+{											\
+	_V[0] = (_LEN & 0xFF00) >> 8;			\
+	_V[1] = (_LEN & 0xFF);					\
+}
+
+#define	INC_UINT16_TO_ARRARY(_V, _LEN)			\
+{												\
+	UINT16	var_len;							\
+												\
+	var_len = (_V[0]<<8) | (_V[1]);				\
+	var_len += _LEN;							\
+												\
+	_V[0] = (var_len & 0xFF00) >> 8;			\
+	_V[1] = (var_len & 0xFF);					\
+}
+
+#define	CONV_ARRARY_TO_UINT16(_V)	((_V[0]<<8) | (_V[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;
+
+
+/*========================================
+	The prototype is defined in cmm_wpa.c
+  ========================================*/
+BOOLEAN WpaMsgTypeSubst(
+	IN  UCHAR   EAPType,
+	OUT INT		*MsgType);
+
+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 PasswordHash(
+	char *password,
+	unsigned char *ssid,
+	int ssidlength,
+	unsigned char *output);
+
+PUINT8	GetSuiteFromRSNIE(
+		IN	PUINT8	rsnie,
+		IN	UINT	rsnie_len,
+		IN	UINT8	type,
+		OUT	UINT8	*count);
+
+VOID WpaShowAllsuite(
+	IN	PUINT8	rsnie,
+	IN	UINT	rsnie_len);
+
+VOID RTMPInsertRSNIE(
+	IN PUCHAR pFrameBuf,
+	OUT PULONG pFrameLen,
+	IN PUINT8 rsnie_ptr,
+	IN UINT8  rsnie_len,
+	IN PUINT8 pmkid_ptr,
+	IN UINT8  pmkid_len);
+
+
+#endif
diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile
index 6bc7e29..ac35cff 100644
--- a/drivers/staging/rtl8187se/Makefile
+++ b/drivers/staging/rtl8187se/Makefile
@@ -1,24 +1,14 @@
 
 #EXTRA_CFLAGS += -DCONFIG_IEEE80211_NOWEP=y
-#EXTRA_CFLAGS += -DCONFIG_RTL8180_IOMAP
 #EXTRA_CFLAGS += -std=gnu89
 #EXTRA_CFLAGS += -O2
 #CC            = gcc
-EXTRA_CFLAGS += -DTHOMAS_TURBO
-#CFLAGS += -DCONFIG_RTL8185B
-#CFLAGS += -DCONFIG_RTL818x_S
 
-#added for EeePC testing
-EXTRA_CFLAGS += -DENABLE_IPS
 EXTRA_CFLAGS += -DSW_ANTE
 EXTRA_CFLAGS += -DTX_TRACK
 EXTRA_CFLAGS += -DHIGH_POWER
 EXTRA_CFLAGS += -DSW_DIG
 EXTRA_CFLAGS += -DRATE_ADAPT
-EXTRA_CFLAGS += -DCONFIG_RTL8180_PM
-
-#+YJ,080626
-EXTRA_CFLAGS += -DENABLE_DOT11D
 
 #enable it for legacy power save, disable it for leisure  power save
 EXTRA_CFLAGS += -DENABLE_LPS
@@ -28,17 +18,11 @@ EXTRA_CFLAGS += -DENABLE_LPS
 
 rtl8187se-objs :=			\
 		r8180_core.o		\
-		r8180_sa2400.o		\
 		r8180_93cx6.o		\
 		r8180_wx.o		\
-		r8180_max2820.o		\
-		r8180_gct.o		\
-		r8180_rtl8225.o		\
-		r8180_rtl8255.o		\
 		r8180_rtl8225z2.o	\
 		r8185b_init.o		\
 		r8180_dm.o		\
-		r8180_pm.o		\
 		ieee80211/dot11d.o			\
 		ieee80211/ieee80211_softmac.o		\
 		ieee80211/ieee80211_rx.o		\
diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO
new file mode 100644
index 0000000..c09a916
--- /dev/null
+++ b/drivers/staging/rtl8187se/TODO
@@ -0,0 +1,15 @@
+TODO:
+- prepare private ieee80211 stack for merge with rtl8192su's version:
+  - add hwsec_active flag to struct ieee80211_device
+  - add bHwSec flag to cb_desc structure
+- switch to use shared "librtl" instead of private ieee80211 stack
+- switch to use LIB80211
+- switch to use MAC80211
+- switch to use EEPROM_93CX6
+- use kernel coding style
+- checkpatch.pl fixes
+- sparse fixes
+- integrate with drivers/net/wireless/rtl818x
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
+Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
diff --git a/drivers/staging/rtl8187se/dot11d.h b/drivers/staging/rtl8187se/dot11d.h
deleted file mode 100644
index 2417da9..0000000
--- a/drivers/staging/rtl8187se/dot11d.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#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.h b/drivers/staging/rtl8187se/ieee80211.h
deleted file mode 100644
index 5833608..0000000
--- a/drivers/staging/rtl8187se/ieee80211.h
+++ /dev/null
@@ -1,1755 +0,0 @@
-/*
- * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andreamrl@tiscali.it>
- *
- * 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. See README and COPYING for
- * more details.
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h>   /* ARRAY_SIZE */
-#include <linux/version.h>
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
-#include <linux/wireless.h>
-#endif
-
-/*
-#ifndef bool
-#define bool int
-#endif
-
-#ifndef true
-#define true   1
-#endif
-
-#ifndef false
-#define false  0
-#endif
-*/
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-#ifndef bool
-typedef enum{false = 0, true} bool;
-#endif
-#endif
-//#ifdef JOHN_HWSEC
-#define KEY_TYPE_NA		0x0
-#define KEY_TYPE_WEP40 		0x1
-#define KEY_TYPE_TKIP		0x2
-#define KEY_TYPE_CCMP		0x4
-#define KEY_TYPE_WEP104		0x5
-//#endif
-
-
-#define aSifsTime					10
-
-#define MGMT_QUEUE_NUM 5
-
-
-#define IEEE_CMD_SET_WPA_PARAM			1
-#define	IEEE_CMD_SET_WPA_IE			2
-#define IEEE_CMD_SET_ENCRYPTION			3
-#define IEEE_CMD_MLME				4
-
-#define IEEE_PARAM_WPA_ENABLED			1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES		2
-#define IEEE_PARAM_DROP_UNENCRYPTED		3
-#define IEEE_PARAM_PRIVACY_INVOKED		4
-#define IEEE_PARAM_AUTH_ALGS			5
-#define IEEE_PARAM_IEEE_802_1X			6
-//It should consistent with the driver_XXX.c
-//   David, 2006.9.26
-#define IEEE_PARAM_WPAX_SELECT			7
-//Added for notify the encryption type selection
-//   David, 2006.9.26
-#define IEEE_PROTO_WPA				1
-#define IEEE_PROTO_RSN				2
-//Added for notify the encryption type selection
-//   David, 2006.9.26
-#define IEEE_WPAX_USEGROUP			0
-#define IEEE_WPAX_WEP40				1
-#define IEEE_WPAX_TKIP				2
-#define IEEE_WPAX_WRAP   			3
-#define IEEE_WPAX_CCMP				4
-#define IEEE_WPAX_WEP104			5
-
-#define IEEE_KEY_MGMT_IEEE8021X			1
-#define IEEE_KEY_MGMT_PSK			2
-
-
-
-#define IEEE_MLME_STA_DEAUTH			1
-#define IEEE_MLME_STA_DISASSOC			2
-
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG		2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR		3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED		4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED		5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED		6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED		7
-
-
-#define	IEEE_CRYPT_ALG_NAME_LEN			16
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
-#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
-#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
-#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
-////////////////////////////////
-// added for kernel conflict under FC5
-#define ieee80211_wx_get_name   ieee80211_wx_get_name_rtl
-#define free_ieee80211          free_ieee80211_rtl
-#define alloc_ieee80211        alloc_ieee80211_rtl
-///////////////////////////////
-#endif
-//error in ubuntu2.6.22,so add these
-#define ieee80211_wake_queue ieee80211_wake_queue_rtl
-#define ieee80211_stop_queue ieee80211_stop_queue_rtl
-
-#define ieee80211_rx ieee80211_rx_rtl
-
-#define ieee80211_register_crypto_ops	ieee80211_register_crypto_ops_rtl
-#define ieee80211_unregister_crypto_ops	ieee80211_unregister_crypto_ops_rtl
-#define ieee80211_get_crypto_ops	ieee80211_get_crypto_ops_rtl
-#define ieee80211_crypt_deinit_entries	ieee80211_crypt_deinit_entries_rtl
-#define ieee80211_crypt_deinit_handler	ieee80211_crypt_deinit_handler_rtl
-#define ieee80211_crypt_delayed_deinit	ieee80211_crypt_delayed_deinit_rtl
-
-#define ieee80211_txb_free	ieee80211_txb_free_rtl
-#define ieee80211_wx_get_essid	ieee80211_wx_get_essid_rtl
-#define ieee80211_wx_set_essid	ieee80211_wx_set_essid_rtl
-#define ieee80211_wx_set_rate	ieee80211_wx_set_rate_rtl
-#define ieee80211_wx_get_rate	ieee80211_wx_get_rate_rtl
-#define ieee80211_wx_set_wap	ieee80211_wx_set_wap_rtl
-#define ieee80211_wx_get_wap	ieee80211_wx_get_wap_rtl
-#define ieee80211_wx_set_mode	ieee80211_wx_set_mode_rtl
-#define ieee80211_wx_get_mode	ieee80211_wx_get_mode_rtl
-#define ieee80211_wx_set_scan	ieee80211_wx_set_scan_rtl
-#define ieee80211_wx_get_freq	ieee80211_wx_get_freq_rtl
-#define ieee80211_wx_set_freq	ieee80211_wx_set_freq_rtl
-#define ieee80211_wx_set_rawtx	ieee80211_wx_set_rawtx_rtl
-#define ieee80211_wx_set_power	ieee80211_wx_set_power_rtl
-#define ieee80211_wx_get_power	ieee80211_wx_get_power_rtl
-#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rtl
-#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rtl
-#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rtl
-#define	ieee80211_start_protocol	ieee80211_start_protocol_rtl
-#define	ieee80211_stop_protocol		ieee80211_stop_protocol_rtl
-#define	ieee80211_rx_mgt		ieee80211_rx_mgt_rtl
-
-#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
-//by amy for ps
-#define notify_wx_assoc_event  notify_wx_assoc_event_rtl
-#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rtl
-#define ieee80211_disassociate ieee80211_disassociate_rtl
-#define ieee80211_start_scan ieee80211_start_scan_rtl
-//by amy for ps
-typedef struct ieee_param {
-	u32 cmd;
-	u8 sta_addr[ETH_ALEN];
-        union {
-		struct {
-			u8 name;
-			u32 value;
-		} wpa_param;
-		struct {
-			u32 len;
-			u8 reserved[32];
-			u8 data[0];
-		} wpa_ie;
-	        struct{
-			int command;
-    			int reason_code;
-		} mlme;
-		struct {
-			u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
-			u8 set_tx;
-			u32 err;
-			u8 idx;
-			u8 seq[8]; /* sequence counter (set: RX, get: TX) */
-			u16 key_len;
-			u8 key[0];
-		} crypt;
-
-	} u;
-}ieee_param;
-
-
-#if WIRELESS_EXT < 17
-#define IW_QUAL_QUAL_INVALID   0x10
-#define IW_QUAL_LEVEL_INVALID  0x20
-#define IW_QUAL_NOISE_INVALID  0x40
-#define IW_QUAL_QUAL_UPDATED   0x1
-#define IW_QUAL_LEVEL_UPDATED  0x2
-#define IW_QUAL_NOISE_UPDATED  0x4
-#endif
-
-// linux under 2.6.9 release may not support it, so modify it for common use
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
-#define MSECS(t)	(1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
-static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_UNINTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-         return timeout;
-}
-#else
-#define MSECS(t) msecs_to_jiffies(t)
-#define msleep_interruptible_rtl  msleep_interruptible
-#endif
-
-#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_HLEN			30
-#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK		0x0c
-#define IEEE80211_FC0_TYPE_DATA		0x08
-#define IEEE80211_FC0_SUBTYPE_MASK	0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS	0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
-	(((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
-	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
-	u8 mac[ETH_ALEN];
-	u16 seq_num[17];
-	u16 frag_num[17];
-	unsigned long packet_time[17];
-	struct list_head list;
-};
-
-struct ieee80211_hdr {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_QOS {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-	u16 QOS_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr_QOS {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u16 QOS_ctl;
-} __attribute__ ((packed));
-
-enum eap_type {
-	EAP_PACKET = 0,
-	EAPOL_START,
-	EAPOL_LOGOFF,
-	EAPOL_KEY,
-	EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
-	[EAP_PACKET]		= "EAP-Packet",
-	[EAPOL_START]		= "EAPOL-Start",
-	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
-	[EAPOL_KEY]		= "EAPOL-Key",
-	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
-	return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-
-struct eapol {
-	u8 snap[6];
-	u16 ethertype;
-	u8 version;
-	u8 type;
-	u16 length;
-} __attribute__ ((packed));
-
-#define IEEE80211_3ADDR_LEN 24
-#define IEEE80211_4ADDR_LEN 30
-#define IEEE80211_FCS_LEN    4
-
-#define MIN_FRAG_THRESHOLD     256U
-#define	MAX_FRAG_THRESHOLD     2346U
-
-/* Frame control field constants */
-#define IEEE80211_FCTL_VERS		0x0002
-#define IEEE80211_FCTL_FTYPE		0x000c
-#define IEEE80211_FCTL_STYPE		0x00f0
-#define IEEE80211_FCTL_TODS		0x0100
-#define IEEE80211_FCTL_FROMDS		0x0200
-#define IEEE80211_FCTL_DSTODS		0x0300 //added by david
-#define IEEE80211_FCTL_MOREFRAGS	0x0400
-#define IEEE80211_FCTL_RETRY		0x0800
-#define IEEE80211_FCTL_PM		0x1000
-#define IEEE80211_FCTL_MOREDATA	0x2000
-#define IEEE80211_FCTL_WEP		0x4000
-#define IEEE80211_FCTL_ORDER		0x8000
-
-#define IEEE80211_FTYPE_MGMT		0x0000
-#define IEEE80211_FTYPE_CTL		0x0004
-#define IEEE80211_FTYPE_DATA		0x0008
-
-/* management */
-#define IEEE80211_STYPE_ASSOC_REQ	0x0000
-#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
-#define IEEE80211_STYPE_REASSOC_REQ	0x0020
-#define IEEE80211_STYPE_REASSOC_RESP	0x0030
-#define IEEE80211_STYPE_PROBE_REQ	0x0040
-#define IEEE80211_STYPE_PROBE_RESP	0x0050
-#define IEEE80211_STYPE_BEACON		0x0080
-#define IEEE80211_STYPE_ATIM		0x0090
-#define IEEE80211_STYPE_DISASSOC	0x00A0
-#define IEEE80211_STYPE_AUTH		0x00B0
-#define IEEE80211_STYPE_DEAUTH		0x00C0
-#define IEEE80211_STYPE_MANAGE_ACT	0x00D0
-
-/* control */
-#define IEEE80211_STYPE_PSPOLL		0x00A0
-#define IEEE80211_STYPE_RTS		0x00B0
-#define IEEE80211_STYPE_CTS		0x00C0
-#define IEEE80211_STYPE_ACK		0x00D0
-#define IEEE80211_STYPE_CFEND		0x00E0
-#define IEEE80211_STYPE_CFENDACK	0x00F0
-
-/* data */
-#define IEEE80211_STYPE_DATA		0x0000
-#define IEEE80211_STYPE_DATA_CFACK	0x0010
-#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
-#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
-#define IEEE80211_STYPE_NULLFUNC	0x0040
-#define IEEE80211_STYPE_CFACK		0x0050
-#define IEEE80211_STYPE_CFPOLL		0x0060
-#define IEEE80211_STYPE_CFACKPOLL	0x0070
-#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
-#define IEEE80211_STYPE_QOS_NULL	0x00C0
-
-
-#define IEEE80211_SCTL_FRAG		0x000F
-#define IEEE80211_SCTL_SEQ		0xFFF0
-
-
-/* debug macros */
-
-#ifdef CONFIG_IEEE80211_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
-  printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
-         in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#endif	/* CONFIG_IEEE80211_DEBUG */
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IEEE80211_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/ipw/debug_level
- *
- * you simply need to add your entry to the ipw_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
- *
- */
-
-#define IEEE80211_DL_INFO          (1<<0)
-#define IEEE80211_DL_WX            (1<<1)
-#define IEEE80211_DL_SCAN          (1<<2)
-#define IEEE80211_DL_STATE         (1<<3)
-#define IEEE80211_DL_MGMT          (1<<4)
-#define IEEE80211_DL_FRAG          (1<<5)
-#define IEEE80211_DL_EAP           (1<<6)
-#define IEEE80211_DL_DROP          (1<<7)
-
-#define IEEE80211_DL_TX            (1<<8)
-#define IEEE80211_DL_RX            (1<<9)
-
-#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
-#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
-#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
-
-#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
-#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
-//#define IEEE_DEBUG_SCAN  IEEE80211_WARNING
-#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
-#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
-#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
-#define IEEE80211_DEBUG_EAP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
-#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
-#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
-#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY		// enable iwspy support
-#endif
-#include <net/iw_handler.h>	// new driver API
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
-
-        u8    dsap;   /* always 0xAA */
-        u8    ssap;   /* always 0xAA */
-        u8    ctrl;   /* always 0x03 */
-        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
-
-} __attribute__ ((packed));
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
-
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq)  ((seq) & IEEE80211_SCTL_SEQ)
-
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_IBSS (1<<1)
-#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
-#define WLAN_CAPABILITY_PRIVACY (1<<4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
-#define WLAN_CAPABILITY_PBCC (1<<6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-
-/* Status codes */
-#define WLAN_STATUS_SUCCESS 0
-#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
-#define WLAN_STATUS_CAPS_UNSUPPORTED 10
-#define WLAN_STATUS_REASSOC_NO_ASSOC 11
-#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
-#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
-#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
-#define WLAN_STATUS_CHALLENGE_FAIL 15
-#define WLAN_STATUS_AUTH_TIMEOUT 16
-#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
-#define WLAN_STATUS_ASSOC_DENIED_RATES 18
-/* 802.11b */
-#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
-#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
-#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
-
-/* Reason codes */
-#define WLAN_REASON_UNSPECIFIED 1
-#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
-#define WLAN_REASON_DEAUTH_LEAVING 3
-#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
-#define WLAN_REASON_DISASSOC_AP_BUSY 5
-#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
-#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
-#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
-#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
-
-
-/* Information Element IDs */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARAMS 2
-#define WLAN_EID_DS_PARAMS 3
-#define WLAN_EID_CF_PARAMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARAMS 6
-#define WLAN_EID_CHALLENGE 16
-#define WLAN_EID_RSN 48
-#define WLAN_EID_GENERIC 221
-
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-
-#define IEEE80211_CCK_MODULATION    (1<<0)
-#define IEEE80211_OFDM_MODULATION   (1<<1)
-
-#define IEEE80211_24GHZ_BAND     (1<<0)
-#define IEEE80211_52GHZ_BAND     (1<<1)
-
-#define IEEE80211_CCK_RATE_LEN  		4
-#define IEEE80211_CCK_RATE_1MB		        0x02
-#define IEEE80211_CCK_RATE_2MB		        0x04
-#define IEEE80211_CCK_RATE_5MB		        0x0B
-#define IEEE80211_CCK_RATE_11MB		        0x16
-#define IEEE80211_OFDM_RATE_LEN 		8
-#define IEEE80211_OFDM_RATE_6MB		        0x0C
-#define IEEE80211_OFDM_RATE_9MB		        0x12
-#define IEEE80211_OFDM_RATE_12MB		0x18
-#define IEEE80211_OFDM_RATE_18MB		0x24
-#define IEEE80211_OFDM_RATE_24MB		0x30
-#define IEEE80211_OFDM_RATE_36MB		0x48
-#define IEEE80211_OFDM_RATE_48MB		0x60
-#define IEEE80211_OFDM_RATE_54MB		0x6C
-#define IEEE80211_BASIC_RATE_MASK		0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
-
-#define IEEE80211_CCK_RATES_MASK	        0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
-	IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
-        IEEE80211_CCK_RATE_5MB_MASK | \
-        IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
-	IEEE80211_OFDM_RATE_12MB_MASK | \
-	IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
-	IEEE80211_OFDM_RATE_9MB_MASK  | \
-	IEEE80211_OFDM_RATE_18MB_MASK | \
-	IEEE80211_OFDM_RATE_36MB_MASK | \
-	IEEE80211_OFDM_RATE_48MB_MASK | \
-	IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
-                                IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES	    8
-#define IEEE80211_NUM_CCK_RATES	            4
-#define IEEE80211_OFDM_SHIFT_MASK_A         4
-
-
-
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- *       information for frames received.  Not setting these will not cause
- *       any adverse affects. */
-struct ieee80211_rx_stats {
-	u32 mac_time[2];
-	u8 signalstrength;
-	s8 rssi;
-	u8 signal;
-	u8 noise;
-	u16 rate; /* in 100 kbps */
-	u8 received_channel;
-	u8 control;
-	u8 mask;
-	u8 freq;
-	u16 len;
-	u8 nic_type;
-};
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
-#define IEEE80211_FRAG_CACHE_LEN 4
-
-struct ieee80211_frag_entry {
-	unsigned long first_frag_time;
-	unsigned int seq;
-	unsigned int last_frag;
-	struct sk_buff *skb;
-	u8 src_addr[ETH_ALEN];
-	u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
-	unsigned int tx_unicast_frames;
-	unsigned int tx_multicast_frames;
-	unsigned int tx_fragments;
-	unsigned int tx_unicast_octets;
-	unsigned int tx_multicast_octets;
-	unsigned int tx_deferred_transmissions;
-	unsigned int tx_single_retry_frames;
-	unsigned int tx_multiple_retry_frames;
-	unsigned int tx_retry_limit_exceeded;
-	unsigned int tx_discards;
-	unsigned int rx_unicast_frames;
-	unsigned int rx_multicast_frames;
-	unsigned int rx_fragments;
-	unsigned int rx_unicast_octets;
-	unsigned int rx_multicast_octets;
-	unsigned int rx_fcs_errors;
-	unsigned int rx_discards_no_buffer;
-	unsigned int tx_discards_wrong_sa;
-	unsigned int rx_discards_undecryptable;
-	unsigned int rx_message_in_msg_fragments;
-	unsigned int rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_softmac_stats{
-	unsigned int rx_ass_ok;
-	unsigned int rx_ass_err;
-	unsigned int rx_probe_rq;
-	unsigned int tx_probe_rs;
-	unsigned int tx_beacons;
-	unsigned int rx_auth_rq;
-	unsigned int rx_auth_rs_ok;
-	unsigned int rx_auth_rs_err;
-	unsigned int tx_auth_rq;
-	unsigned int no_auth_rs;
-	unsigned int no_ass_rs;
-	unsigned int tx_ass_rq;
-	unsigned int rx_ass_rq;
-	unsigned int tx_probe_rq;
-	unsigned int reassoc;
-	unsigned int swtxstop;
-	unsigned int swtxawake;
-};
-
-struct ieee80211_device;
-
-#include "ieee80211_crypt.h"
-
-#define SEC_KEY_1         (1<<0)
-#define SEC_KEY_2         (1<<1)
-#define SEC_KEY_3         (1<<2)
-#define SEC_KEY_4         (1<<3)
-#define SEC_ACTIVE_KEY    (1<<4)
-#define SEC_AUTH_MODE     (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL         (1<<7)
-#define SEC_ENABLED       (1<<8)
-
-#define SEC_LEVEL_0      0 /* None */
-#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
-
-#define WEP_KEY_LEN_MODIF 32
-
-struct ieee80211_security {
-	u16 active_key:2,
-            enabled:1,
-	    auth_mode:2,
-            auth_algo:4,
-            unicast_uses_group:1;
-	u8 key_sizes[WEP_KEYS];
-	u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
-	u8 level;
-	u16 flags;
-} __attribute__ ((packed));
-
-
-/*
-
- 802.11 data frame from AP
-
-      ,-------------------------------------------------------------------.
-Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
-      |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
-      |      | tion | (BSSID) |         |         | ence |  data   |      |
-      `-------------------------------------------------------------------'
-
-Total: 28-2340 bytes
-
-*/
-
-struct ieee80211_header_data {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[6];
-	u8 addr2[6];
-	u8 addr3[6];
-	u16 seq_ctrl;
-};
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-/* Management Frame Information Element Types */
-#define MFIE_TYPE_SSID       0
-#define MFIE_TYPE_RATES      1
-#define MFIE_TYPE_FH_SET     2
-#define MFIE_TYPE_DS_SET     3
-#define MFIE_TYPE_CF_SET     4
-#define MFIE_TYPE_TIM        5
-#define MFIE_TYPE_IBSS_SET   6
-#define MFIE_TYPE_COUNTRY  7 //+YJ,080625
-#define MFIE_TYPE_CHALLENGE  16
-#define MFIE_TYPE_ERP        42
-#define MFIE_TYPE_RSN	     48
-#define MFIE_TYPE_RATES_EX   50
-#define MFIE_TYPE_GENERIC    221
-
-#ifdef ENABLE_DOT11D
-typedef enum
-{
-	COUNTRY_CODE_FCC = 0,
-	COUNTRY_CODE_IC = 1,
-	COUNTRY_CODE_ETSI = 2,
-	COUNTRY_CODE_SPAIN = 3,
-	COUNTRY_CODE_FRANCE = 4,
-	COUNTRY_CODE_MKK = 5,
-	COUNTRY_CODE_MKK1 = 6,
-	COUNTRY_CODE_ISRAEL = 7,
-	COUNTRY_CODE_TELEC = 8,
-	COUNTRY_CODE_GLOBAL_DOMAIN = 9,
-	COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
-}country_code_type_t;
-#endif
-
-struct ieee80211_info_element_hdr {
-	u8 id;
-	u8 len;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
-	u8 id;
-	u8 len;
-	u8 data[0];
-} __attribute__ ((packed));
-
-/*
- * These are the data types that can make up management packets
- *
-	u16 auth_algorithm;
-	u16 auth_sequence;
-	u16 beacon_interval;
-	u16 capability;
-	u8 current_ap[ETH_ALEN];
-	u16 listen_interval;
-	struct {
-		u16 association_id:14, reserved:2;
-	} __attribute__ ((packed));
-	u32 time_stamp[2];
-	u16 reason;
-	u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 10
-
-struct ieee80211_authentication {
-	struct ieee80211_header_data header;
-	u16 algorithm;
-	u16 transaction;
-	u16 status;
-	//struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-
-struct ieee80211_probe_response {
-	struct ieee80211_header_data header;
-	u32 time_stamp[2];
-	u16 beacon_interval;
-	u16 capability;
-	struct ieee80211_info_element info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_probe_request {
-	struct ieee80211_header_data header;
-	/*struct ieee80211_info_element info_element;*/
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_request_frame {
-	struct ieee80211_hdr_3addr header;
-	u16 capability;
-	u16 listen_interval;
-	//u8 current_ap[ETH_ALEN];
-	struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_response_frame {
-	struct ieee80211_hdr_3addr header;
-	u16 capability;
-	u16 status;
-	u16 aid;
-	struct ieee80211_info_element info_element; /* supported rates */
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc_frame{
-        struct ieee80211_hdr_3addr header;
-        u16    reasoncode;
-}__attribute__ ((packed));
-
-struct ieee80211_txb {
-	u8 nr_frags;
-	u8 encrypted;
-	u16 reserved;
-	u16 frag_size;
-	u16 payload_size;
-	struct sk_buff *fragments[0];
-};
-
-struct ieee80211_wmm_ac_param {
-	u8 ac_aci_acm_aifsn;
-	u8 ac_ecwmin_ecwmax;
-	u16 ac_txop_limit;
-};
-
-struct ieee80211_wmm_ts_info {
-	u8 ac_dir_tid;
-	u8 ac_up_psb;
-	u8 reserved;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_tspec_elem {
-	struct ieee80211_wmm_ts_info ts_info;
-	u16 norm_msdu_size;
-	u16 max_msdu_size;
-	u32 min_serv_inter;
-	u32 max_serv_inter;
-	u32 inact_inter;
-	u32 suspen_inter;
-	u32 serv_start_time;
-	u32 min_data_rate;
-	u32 mean_data_rate;
-	u32 peak_data_rate;
-	u32 max_burst_size;
-	u32 delay_bound;
-	u32 min_phy_rate;
-	u16 surp_band_allow;
-	u16 medium_time;
-}__attribute__((packed));
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len  (WMM_all_frame << 4)
-#define IEEE80211_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-/* SWEEP TABLE ENTRIES NUMBER*/
-#define MAX_SWEEP_TAB_ENTRIES		  42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
-/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates.  Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH                  ((u8)12)
-#define MAX_RATES_EX_LENGTH               ((u8)16)
-#define MAX_NETWORK_COUNT                  128
-//#define MAX_CHANNEL_NUMBER                 161
-#define MAX_CHANNEL_NUMBER                 165 //YJ,modified,080625
-#define MAX_IE_LEN						0xFF //+YJ,080625
-
-typedef struct _CHANNEL_LIST{
-	u8	Channel[MAX_CHANNEL_NUMBER + 1];
-	u8	Len;
-}CHANNEL_LIST, *PCHANNEL_LIST;
-
-#define IEEE80211_SOFTMAC_SCAN_TIME	  100//400
-//(HZ / 2)
-//by amy for ps
-#define IEEE80211_WATCH_DOG_TIME    2000
-//by amy for ps
-//by amy for antenna
-#define ANTENNA_DIVERSITY_TIMER_PERIOD		1000 // 1000 m
-//by amy for antenna
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH                 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM    (1<<1)
-#define NETWORK_HAS_CCK     (1<<2)
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-#define IEEE80211_PS_ENABLE   IEEE80211_DTIM_VALID
-//added by David for QoS 2006/6/30
-//#define WMM_Hang_8187
-#ifdef WMM_Hang_8187
-#undef WMM_Hang_8187
-#endif
-
-#define WME_AC_BE   0x00
-#define WME_AC_BK   0x01
-#define WME_AC_VI   0x02
-#define WME_AC_VO   0x03
-#define WME_ACI_MASK 0x03
-#define WME_AIFSN_MASK 0x03
-#define WME_AC_PRAM_LEN 16
-
-//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
-//#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1))
-#define UP2AC(up) (		   \
-	((up) < 1) ? WME_AC_BE : \
-	((up) < 3) ? WME_AC_BK : \
-	((up) < 4) ? WME_AC_BE : \
-	((up) < 6) ? WME_AC_VI : \
-	WME_AC_VO)
-//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
-#define AC2UP(_ac)	(       \
-	((_ac) == WME_AC_VO) ? 6 : \
-	((_ac) == WME_AC_VI) ? 5 : \
-	((_ac) == WME_AC_BK) ? 1 : \
-	0)
-
-#define	ETHER_ADDR_LEN		6	/* length of an Ethernet address */
-struct	ether_header {
-	u8 ether_dhost[ETHER_ADDR_LEN];
-	u8 ether_shost[ETHER_ADDR_LEN];
-	u16 ether_type;
-} __attribute__((packed));
-
-#ifndef ETHERTYPE_PAE
-#define	ETHERTYPE_PAE	0x888e		/* EAPOL PAE/802.1x */
-#endif
-#ifndef ETHERTYPE_IP
-#define	ETHERTYPE_IP	0x0800		/* IP protocol */
-#endif
-
-struct ieee80211_network {
-	/* These entries are used to identify a unique network */
-	u8 bssid[ETH_ALEN];
-	u8 channel;
-	/* Ensure null-terminated for any debug msgs */
-	u8 ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 ssid_len;
-
-	/* These are network statistics */
-	struct ieee80211_rx_stats stats;
-	u16 capability;
-	u8 rates[MAX_RATES_LENGTH];
-	u8 rates_len;
-	u8 rates_ex[MAX_RATES_EX_LENGTH];
-	u8 rates_ex_len;
-	unsigned long last_scanned;
-	u8 mode;
-	u8 flags;
-	u32 last_associate;
-	u32 time_stamp[2];
-	u16 beacon_interval;
-	u16 listen_interval;
-	u16 atim_window;
-	u8 wpa_ie[MAX_WPA_IE_LEN];
-	size_t wpa_ie_len;
-	u8 rsn_ie[MAX_WPA_IE_LEN];
-	size_t rsn_ie_len;
-	u8 dtim_period;
-	u8 dtim_data;
-	u32 last_dtim_sta_time[2];
-	struct list_head list;
-	//appeded for QoS
-	u8 wmm_info;
-	struct ieee80211_wmm_ac_param wmm_param[4];
-	u8 QoS_Enable;
-	u8 SignalStrength;
-//by amy 080312
-	u8 HighestOperaRate;
-//by amy 080312
-#ifdef THOMAS_TURBO
-	u8 Turbo_Enable;//enable turbo mode, added by thomas
-#endif
-#ifdef ENABLE_DOT11D
-	u16 CountryIeLen;
-	u8 CountryIeBuf[MAX_IE_LEN];
-#endif
-};
-
-enum ieee80211_state {
-
-	/* the card is not linked at all */
-	IEEE80211_NOLINK = 0,
-
-	/* IEEE80211_ASSOCIATING* are for BSS client mode
-	 * the driver shall not perform RX filtering unless
-	 * the state is LINKED.
-	 * The driver shall just check for the state LINKED and
-	 * defaults to NOLINK for ALL the other states (including
-	 * LINKED_SCANNING)
-	 */
-
-	/* the association procedure will start (wq scheduling)*/
-	IEEE80211_ASSOCIATING,
-	IEEE80211_ASSOCIATING_RETRY,
-
-	/* the association procedure is sending AUTH request*/
-	IEEE80211_ASSOCIATING_AUTHENTICATING,
-
-	/* the association procedure has successfully authentcated
-	 * and is sending association request
-	 */
-	IEEE80211_ASSOCIATING_AUTHENTICATED,
-
-	/* the link is ok. the card associated to a BSS or linked
-	 * to a ibss cell or acting as an AP and creating the bss
-	 */
-	IEEE80211_LINKED,
-
-	/* same as LINKED, but the driver shall apply RX filter
-	 * rules as we are in NO_LINK mode. As the card is still
-	 * logically linked, but it is doing a syncro site survey
-	 * then it will be back to LINKED state.
-	 */
-	IEEE80211_LINKED_SCANNING,
-
-};
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
-extern inline int is_multicast_ether_addr(const u8 *addr)
-{
-        return ((addr[0] != 0xff) && (0x01 & addr[0]));
-}
-#endif
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
-extern inline int is_broadcast_ether_addr(const u8 *addr)
-{
-	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
-		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
-}
-#endif
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-
-typedef struct tx_pending_t{
-	int frag;
-	struct ieee80211_txb *txb;
-}tx_pending_t;
-
-
-struct ieee80211_device {
-	struct net_device *dev;
-
-	/* Bookkeeping structures */
-	struct net_device_stats stats;
-	struct ieee80211_stats ieee_stats;
-	struct ieee80211_softmac_stats softmac_stats;
-
-	/* Probe / Beacon management */
-	struct list_head network_free_list;
-	struct list_head network_list;
-	struct ieee80211_network *networks;
-	int scans;
-	int scan_age;
-
-	int iw_mode; /* operating mode (IW_MODE_*) */
-
-	spinlock_t lock;
-	spinlock_t wpax_suitlist_lock;
-
-	int tx_headroom; /* Set to size of any additional room needed at front
-			  * of allocated Tx SKBs */
-	u32 config;
-
-	/* WEP and other encryption related settings at the device level */
-	int open_wep; /* Set to 1 to allow unencrypted frames */
-
-	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
-				 * WEP key changes */
-
-	/* If the host performs {en,de}cryption, then set to 1 */
-	int host_encrypt;
-	int host_decrypt;
-	int ieee802_1x; /* is IEEE 802.1X used */
-
-	/* WPA data */
-	int wpa_enabled;
-	int drop_unencrypted;
-	int tkip_countermeasures;
-	int privacy_invoked;
-	size_t wpa_ie_len;
-	u8 *wpa_ie;
-
-	u8 ap_mac_addr[6];
-	u16 pairwise_key_type;
-	u16 broadcast_key_type;
-
-	struct list_head crypt_deinit_list;
-	struct ieee80211_crypt_data *crypt[WEP_KEYS];
-	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
-	struct timer_list crypt_deinit_timer;
-
-	int bcrx_sta_key; /* use individual keys to override default keys even
-			   * with RX of broad/multicast frames */
-
-	/* Fragmentation structures */
-	// each streaming contain a entry
-	struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
-	unsigned int frag_next_idx[17];
-	u16 fts; /* Fragmentation Threshold */
-
-	/* This stores infos for the current network.
-	 * Either the network we are associated in INFRASTRUCTURE
-	 * or the network that we are creating in MASTER mode.
-	 * ad-hoc is a mixture ;-).
-	 * Note that in infrastructure mode, even when not associated,
-	 * fields bssid and essid may be valid (if wpa_set and essid_set
-	 * are true) as thy carry the value set by the user via iwconfig
-	 */
-	struct ieee80211_network current_network;
-
-
-	enum ieee80211_state state;
-
-	int short_slot;
-	int mode;       /* A, B, G */
-	int modulation; /* CCK, OFDM */
-	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
-	int abg_true;   /* ABG flag              */
-
-	/* used for forcing the ibss workqueue to terminate
-	 * without wait for the syncro scan to terminate
-	 */
-	short sync_scan_hurryup;
-
-#ifdef ENABLE_DOT11D
-	void * pDot11dInfo;
-	bool bGlobalDomain;
-
-	// For Liteon Ch12~13 passive scan
-	u8	MinPassiveChnlNum;
-	u8	IbssStartChnl;
-#else
-	/* map of allowed channels. 0 is dummy */
-	// FIXME: remeber to default to a basic channel plan depending of the PHY type
-	int channel_map[MAX_CHANNEL_NUMBER+1];
-#endif
-
-	int rate;       /* current rate */
-	int basic_rate;
-	//FIXME: pleace callback, see if redundant with softmac_features
-	short active_scan;
-
-	/* this contains flags for selectively enable softmac support */
-	u16 softmac_features;
-
-	/* if the sequence control field is not filled by HW */
-	u16 seq_ctrl[5];
-
-	/* association procedure transaction sequence number */
-	u16 associate_seq;
-
-	/* AID for RTXed association responses */
-	u16 assoc_id;
-
-	/* power save mode related*/
-	short ps;
-	short sta_sleep;
-	int ps_timeout;
-	struct tasklet_struct ps_task;
-	u32 ps_th;
-	u32 ps_tl;
-
-	short raw_tx;
-	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
-	short queue_stop;
-	short scanning;
-	short proto_started;
-
-	struct semaphore wx_sem;
-	struct semaphore scan_sem;
-
-	spinlock_t mgmt_tx_lock;
-	spinlock_t beacon_lock;
-
-	short beacon_txing;
-
-	short wap_set;
-	short ssid_set;
-
-	u8  wpax_type_set;    //{added by David, 2006.9.28}
-	u32 wpax_type_notify; //{added by David, 2006.9.26}
-
-	/* QoS related flag */
-	char init_wmmparam_flag;
-
-	/* for discarding duplicated packets in IBSS */
-	struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
-	/* for discarding duplicated packets in BSS */
-	u16 last_rxseq_num[17]; /* rx seq previous per-tid */
-	u16 last_rxfrag_num[17];/* tx frag previous per-tid */
-	unsigned long last_packet_time[17];
-
-	/* for PS mode */
-	unsigned long last_rx_ps_time;
-
-	/* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
-	struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
-	int mgmt_queue_head;
-	int mgmt_queue_tail;
-
-
-	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
-	struct  tx_pending_t tx_pending;
-
-	/* used if IEEE_SOFTMAC_ASSOCIATE is set */
-	struct timer_list associate_timer;
-
-	/* used if IEEE_SOFTMAC_BEACONS is set */
-	struct timer_list beacon_timer;
-
-	struct work_struct associate_complete_wq;
-//	struct work_struct associate_retry_wq;
-	struct work_struct associate_procedure_wq;
-//	struct work_struct softmac_scan_wq;
-	struct work_struct wx_sync_scan_wq;
-	struct work_struct wmm_param_update_wq;
-	struct work_struct ps_request_tx_ack_wq;//for ps
-//	struct work_struct hw_wakeup_wq;
-//	struct work_struct hw_sleep_wq;
-//	struct work_struct watch_dog_wq;
-	bool bInactivePs;
-	bool actscanning;
-	bool beinretry;
-	u16 ListenInterval;
-	unsigned long NumRxDataInPeriod; //YJ,add,080828
-	unsigned long NumRxBcnInPeriod;  //YJ,add,080828
-	unsigned long NumRxOkTotal;
-	unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
-	bool bHwRadioOff;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-        struct delayed_work softmac_scan_wq;
-        struct delayed_work associate_retry_wq;
-	struct delayed_work hw_wakeup_wq;
-	struct delayed_work hw_sleep_wq;//+by amy 080324
-	struct delayed_work watch_dog_wq;
-	struct delayed_work sw_antenna_wq;
-	struct delayed_work  start_ibss_wq;
-//by amy for rate adaptive 080312
-    struct delayed_work rate_adapter_wq;
-//by amy for rate adaptive
-	struct delayed_work hw_dig_wq;
-	struct delayed_work tx_pw_wq;
-
-//Added for RF power on power off by lizhaoming 080512
-	struct delayed_work GPIOChangeRFWorkItem;
-#else
-
-	struct work_struct start_ibss_wq;
-        struct work_struct softmac_scan_wq;
-        struct work_struct associate_retry_wq;
-	struct work_struct hw_wakeup_wq;
-	struct work_struct hw_sleep_wq;
-	struct work_struct watch_dog_wq;
-	struct work_struct sw_antenna_wq;
-//by amy for rate adaptive 080312
-    struct work_struct rate_adapter_wq;
-//by amy for rate adaptive
-	struct work_struct hw_dig_wq;
-	struct work_struct tx_pw_wq;
-
-//Added for RF power on power off by lizhaoming 080512
-	struct work_struct GPIOChangeRFWorkItem;
-#endif
-	struct workqueue_struct *wq;
-
-	/* Callback functions */
-	void (*set_security)(struct net_device *dev,
-			     struct ieee80211_security *sec);
-
-	/* Used to TX data frame by using txb structs.
-	 * this is not used if in the softmac_features
-	 * is set the flag IEEE_SOFTMAC_TX_QUEUE
-	 */
-	int (*hard_start_xmit)(struct ieee80211_txb *txb,
-			       struct net_device *dev);
-
-	int (*reset_port)(struct net_device *dev);
-
-	/* Softmac-generated frames (mamagement) are TXed via this
-	 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
-	 * not set. As some cards may have different HW queues that
-	 * one might want to use for data and management frames
-	 * the option to have two callbacks might be useful.
-	 * This fucntion can't sleep.
-	 */
-	int (*softmac_hard_start_xmit)(struct sk_buff *skb,
-			       struct net_device *dev);
-
-	/* used instead of hard_start_xmit (not softmac_hard_start_xmit)
-	 * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
-	 * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
-	 * then also management frames are sent via this callback.
-	 * This function can't sleep.
-	 */
-	void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
-			       struct net_device *dev,int rate);
-
-	/* stops the HW queue for DATA frames. Useful to avoid
-	 * waste time to TX data frame when we are reassociating
-	 * This function can sleep.
-	 */
-	void (*data_hard_stop)(struct net_device *dev);
-
-	/* OK this is complementar to data_poll_hard_stop */
-	void (*data_hard_resume)(struct net_device *dev);
-
-	/* ask to the driver to retune the radio .
-	 * This function can sleep. the driver should ensure
-	 * the radio has been swithced before return.
-	 */
-	void (*set_chan)(struct net_device *dev,short ch);
-
-	/* These are not used if the ieee stack takes care of
-	 * scanning (IEEE_SOFTMAC_SCAN feature set).
-	 * In this case only the set_chan is used.
-	 *
-	 * The syncro version is similar to the start_scan but
-	 * does not return until all channels has been scanned.
-	 * this is called in user context and should sleep,
-	 * it is called in a work_queue when swithcing to ad-hoc mode
-	 * or in behalf of iwlist scan when the card is associated
-	 * and root user ask for a scan.
-	 * the fucntion stop_scan should stop both the syncro and
-	 * background scanning and can sleep.
-	 * The fucntion start_scan should initiate the background
-	 * scanning and can't sleep.
-	 */
-	void (*scan_syncro)(struct net_device *dev);
-	void (*start_scan)(struct net_device *dev);
-	void (*stop_scan)(struct net_device *dev);
-
-	/* indicate the driver that the link state is changed
-	 * for example it may indicate the card is associated now.
-	 * Driver might be interested in this to apply RX filter
-	 * rules or simply light the LINK led
-	 */
-	void (*link_change)(struct net_device *dev);
-
-	/* these two function indicates to the HW when to start
-	 * and stop to send beacons. This is used when the
-	 * IEEE_SOFTMAC_BEACONS is not set. For now the
-	 * stop_send_bacons is NOT guaranteed to be called only
-	 * after start_send_beacons.
-	 */
-	void (*start_send_beacons) (struct net_device *dev);
-	void (*stop_send_beacons) (struct net_device *dev);
-
-	/* power save mode related */
-	void (*sta_wake_up) (struct net_device *dev);
-	void (*ps_request_tx_ack) (struct net_device *dev);
-	void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
-	short (*ps_is_queue_empty) (struct net_device *dev);
-
-	/* QoS related */
-	//void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
-	//void (*wmm_param_update) (struct ieee80211_device *ieee);
-
-	/* This must be the last item so that it points to the data
-	 * allocated beyond this structure by alloc_ieee80211 */
-	u8 priv[0];
-};
-
-#define IEEE_A            (1<<0)
-#define IEEE_B            (1<<1)
-#define IEEE_G            (1<<2)
-#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1<<2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1<<4)
-
-/* Generate respones to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1<<5)
-
-/* The ieee802.11 stack will manages the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details. */
-#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
-
-/* Generate beacons.  The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1<<6)
-
-
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
-	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-}
-
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
-{
-	/* Single white space is for Linksys APs */
-	if (essid_len == 1 && essid[0] == ' ')
-		return 1;
-
-	/* Otherwise, if the entire essid is 0, we assume it is hidden */
-	while (essid_len) {
-		essid_len--;
-		if (essid[essid_len] != '\0')
-			return 0;
-	}
-
-	return 1;
-}
-
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
-{
-	/*
-	 * It is possible for both access points and our device to support
-	 * combinations of modes, so as long as there is one valid combination
-	 * of ap/device supported modes, then return success
-	 *
-	 */
-	if ((mode & IEEE_A) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_G) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_B) &&
-	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	return 0;
-}
-
-extern inline int ieee80211_get_hdrlen(u16 fc)
-{
-	int hdrlen = 24;
-
-	switch (WLAN_FC_GET_TYPE(fc)) {
-	case IEEE80211_FTYPE_DATA:
-		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-			hdrlen = 30; /* Addr4 */
-		if(IEEE80211_QOS_HAS_SEQ(fc))
-			hdrlen += 2; /* QOS ctrl*/
-		break;
-	case IEEE80211_FTYPE_CTL:
-		switch (WLAN_FC_GET_STYPE(fc)) {
-		case IEEE80211_STYPE_CTS:
-		case IEEE80211_STYPE_ACK:
-			hdrlen = 10;
-			break;
-		default:
-			hdrlen = 16;
-			break;
-		}
-		break;
-	}
-
-	return hdrlen;
-}
-
-
-
-/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
-
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-
-extern int ieee80211_encrypt_fragment(
-	struct ieee80211_device *ieee,
-	struct sk_buff *frag,
-	int hdr_len);
-
-extern int ieee80211_xmit(struct sk_buff *skb,
-			  struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-
-/* ieee80211_rx.c */
-extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-			struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-			     struct ieee80211_hdr *header,
-			     struct ieee80211_rx_stats *stats);
-
-/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data* wrqu, char *extra);
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
-                               struct iw_request_info *info,
-                               struct iw_param *data, char *extra);
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra);
-
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
-/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(struct ieee80211_network net);
-extern short ieee80211_is_shortslot(struct ieee80211_network net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
-			struct ieee80211_rx_stats *rx_stats, u16 type,
-			u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
-
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
-extern void ieee80211_start_scan(struct ieee80211_device *ieee);
-
-//Add for RF power on power off by lizhaoming 080512
-extern void SendDisassociation(struct ieee80211_device *ieee,
-       			 u8*                     asSta,
-        		 u8                      asRsn);
-
-/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
-/* ieee80211_softmac_wx.c */
-
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *ext);
-
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
-			 struct iw_request_info *info,
-			 union iwreq_data *awrq,
-			 char *extra);
-
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
-
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
-			      struct iw_request_info *a,
-			      union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-#else
- extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#endif
-//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra);
-
-extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
-
-extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
-
-extern const long ieee80211_wlan_frequencies[];
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
-	ieee->scans++;
-}
-
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
-	return ieee->scans;
-}
-
-static inline const char *escape_essid(const char *essid, u8 essid_len) {
-	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-	const char *s = essid;
-	char *d = escaped;
-
-	if (ieee80211_is_empty_essid(essid, essid_len)) {
-		memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-		return escaped;
-	}
-
-	essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
-	while (essid_len--) {
-		if (*s == '\0') {
-			*d++ = '\\';
-			*d++ = '0';
-			s++;
-		} else {
-			*d++ = *s++;
-		}
-	}
-	*d = '\0';
-	return escaped;
-}
-#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c
index 54bcdcf..309bb8b 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.c
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c
@@ -1,4 +1,3 @@
-#ifdef ENABLE_DOT11D
 //-----------------------------------------------------------------------------
 //	File:
 //		Dot11d.c
@@ -130,16 +129,6 @@ Dot11d_UpdateCountryIe(
 	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,
@@ -233,14 +222,3 @@ int ToLegalChannel(
 
 	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 82576b5..029c2ca 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.h
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h
@@ -97,6 +97,4 @@ 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.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
index 5833608..3222c22 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -29,37 +29,14 @@
 #include <linux/jiffies.h>
 #include <linux/timer.h>
 #include <linux/sched.h>
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
 #include <linux/wireless.h>
-#endif
-
-/*
-#ifndef bool
-#define bool int
-#endif
-
-#ifndef true
-#define true   1
-#endif
+#include <linux/ieee80211.h>
 
-#ifndef false
-#define false  0
-#endif
-*/
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-#ifndef bool
-typedef enum{false = 0, true} bool;
-#endif
-#endif
-//#ifdef JOHN_HWSEC
 #define KEY_TYPE_NA		0x0
 #define KEY_TYPE_WEP40 		0x1
 #define KEY_TYPE_TKIP		0x2
 #define KEY_TYPE_CCMP		0x4
 #define KEY_TYPE_WEP104		0x5
-//#endif
-
 
 #define aSifsTime					10
 
@@ -112,58 +89,6 @@ typedef enum{false = 0, true} bool;
 
 #define	IEEE_CRYPT_ALG_NAME_LEN			16
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
-#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
-#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
-#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
-////////////////////////////////
-// added for kernel conflict under FC5
-#define ieee80211_wx_get_name   ieee80211_wx_get_name_rtl
-#define free_ieee80211          free_ieee80211_rtl
-#define alloc_ieee80211        alloc_ieee80211_rtl
-///////////////////////////////
-#endif
-//error in ubuntu2.6.22,so add these
-#define ieee80211_wake_queue ieee80211_wake_queue_rtl
-#define ieee80211_stop_queue ieee80211_stop_queue_rtl
-
-#define ieee80211_rx ieee80211_rx_rtl
-
-#define ieee80211_register_crypto_ops	ieee80211_register_crypto_ops_rtl
-#define ieee80211_unregister_crypto_ops	ieee80211_unregister_crypto_ops_rtl
-#define ieee80211_get_crypto_ops	ieee80211_get_crypto_ops_rtl
-#define ieee80211_crypt_deinit_entries	ieee80211_crypt_deinit_entries_rtl
-#define ieee80211_crypt_deinit_handler	ieee80211_crypt_deinit_handler_rtl
-#define ieee80211_crypt_delayed_deinit	ieee80211_crypt_delayed_deinit_rtl
-
-#define ieee80211_txb_free	ieee80211_txb_free_rtl
-#define ieee80211_wx_get_essid	ieee80211_wx_get_essid_rtl
-#define ieee80211_wx_set_essid	ieee80211_wx_set_essid_rtl
-#define ieee80211_wx_set_rate	ieee80211_wx_set_rate_rtl
-#define ieee80211_wx_get_rate	ieee80211_wx_get_rate_rtl
-#define ieee80211_wx_set_wap	ieee80211_wx_set_wap_rtl
-#define ieee80211_wx_get_wap	ieee80211_wx_get_wap_rtl
-#define ieee80211_wx_set_mode	ieee80211_wx_set_mode_rtl
-#define ieee80211_wx_get_mode	ieee80211_wx_get_mode_rtl
-#define ieee80211_wx_set_scan	ieee80211_wx_set_scan_rtl
-#define ieee80211_wx_get_freq	ieee80211_wx_get_freq_rtl
-#define ieee80211_wx_set_freq	ieee80211_wx_set_freq_rtl
-#define ieee80211_wx_set_rawtx	ieee80211_wx_set_rawtx_rtl
-#define ieee80211_wx_set_power	ieee80211_wx_set_power_rtl
-#define ieee80211_wx_get_power	ieee80211_wx_get_power_rtl
-#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rtl
-#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rtl
-#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rtl
-#define	ieee80211_start_protocol	ieee80211_start_protocol_rtl
-#define	ieee80211_stop_protocol		ieee80211_stop_protocol_rtl
-#define	ieee80211_rx_mgt		ieee80211_rx_mgt_rtl
-
-#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
-//by amy for ps
-#define notify_wx_assoc_event  notify_wx_assoc_event_rtl
-#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rtl
-#define ieee80211_disassociate ieee80211_disassociate_rtl
-#define ieee80211_start_scan ieee80211_start_scan_rtl
 //by amy for ps
 typedef struct ieee_param {
 	u32 cmd;
@@ -196,32 +121,8 @@ typedef struct ieee_param {
 }ieee_param;
 
 
-#if WIRELESS_EXT < 17
-#define IW_QUAL_QUAL_INVALID   0x10
-#define IW_QUAL_LEVEL_INVALID  0x20
-#define IW_QUAL_NOISE_INVALID  0x40
-#define IW_QUAL_QUAL_UPDATED   0x1
-#define IW_QUAL_LEVEL_UPDATED  0x2
-#define IW_QUAL_NOISE_UPDATED  0x4
-#endif
-
-// linux under 2.6.9 release may not support it, so modify it for common use
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
-#define MSECS(t)	(1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
-static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_UNINTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-         return timeout;
-}
-#else
 #define MSECS(t) msecs_to_jiffies(t)
 #define msleep_interruptible_rtl  msleep_interruptible
-#endif
 
 #define IEEE80211_DATA_LEN		2304
 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
@@ -232,162 +133,21 @@ static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
    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_HLEN			30
-#define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK		0x0c
-#define IEEE80211_FC0_TYPE_DATA		0x08
-#define IEEE80211_FC0_SUBTYPE_MASK	0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS	0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
-	(((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
-	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
-	u8 mac[ETH_ALEN];
-	u16 seq_num[17];
-	u16 frag_num[17];
-	unsigned long packet_time[17];
-	struct list_head list;
-};
-
-struct ieee80211_hdr {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_QOS {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-	u16 QOS_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addr_QOS {
-	u16 frame_ctl;
-	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
-	u16 QOS_ctl;
-} __attribute__ ((packed));
-
-enum eap_type {
-	EAP_PACKET = 0,
-	EAPOL_START,
-	EAPOL_LOGOFF,
-	EAPOL_KEY,
-	EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
-	[EAP_PACKET]		= "EAP-Packet",
-	[EAPOL_START]		= "EAPOL-Start",
-	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
-	[EAPOL_KEY]		= "EAPOL-Key",
-	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
-	return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-
-struct eapol {
-	u8 snap[6];
-	u16 ethertype;
-	u8 version;
-	u8 type;
-	u16 length;
-} __attribute__ ((packed));
-
 #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 IEEE80211_MGMT_HDR_LEN 24
+#define IEEE80211_DATA_HDR3_LEN 24
+#define IEEE80211_DATA_HDR4_LEN 30
 
 #define MIN_FRAG_THRESHOLD     256U
 #define	MAX_FRAG_THRESHOLD     2346U
 
 /* Frame control field constants */
-#define IEEE80211_FCTL_VERS		0x0002
-#define IEEE80211_FCTL_FTYPE		0x000c
-#define IEEE80211_FCTL_STYPE		0x00f0
-#define IEEE80211_FCTL_TODS		0x0100
-#define IEEE80211_FCTL_FROMDS		0x0200
 #define IEEE80211_FCTL_DSTODS		0x0300 //added by david
-#define IEEE80211_FCTL_MOREFRAGS	0x0400
-#define IEEE80211_FCTL_RETRY		0x0800
-#define IEEE80211_FCTL_PM		0x1000
-#define IEEE80211_FCTL_MOREDATA	0x2000
 #define IEEE80211_FCTL_WEP		0x4000
-#define IEEE80211_FCTL_ORDER		0x8000
-
-#define IEEE80211_FTYPE_MGMT		0x0000
-#define IEEE80211_FTYPE_CTL		0x0004
-#define IEEE80211_FTYPE_DATA		0x0008
-
-/* management */
-#define IEEE80211_STYPE_ASSOC_REQ	0x0000
-#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
-#define IEEE80211_STYPE_REASSOC_REQ	0x0020
-#define IEEE80211_STYPE_REASSOC_RESP	0x0030
-#define IEEE80211_STYPE_PROBE_REQ	0x0040
-#define IEEE80211_STYPE_PROBE_RESP	0x0050
-#define IEEE80211_STYPE_BEACON		0x0080
-#define IEEE80211_STYPE_ATIM		0x0090
-#define IEEE80211_STYPE_DISASSOC	0x00A0
-#define IEEE80211_STYPE_AUTH		0x00B0
-#define IEEE80211_STYPE_DEAUTH		0x00C0
-#define IEEE80211_STYPE_MANAGE_ACT	0x00D0
-
-/* control */
-#define IEEE80211_STYPE_PSPOLL		0x00A0
-#define IEEE80211_STYPE_RTS		0x00B0
-#define IEEE80211_STYPE_CTS		0x00C0
-#define IEEE80211_STYPE_ACK		0x00D0
-#define IEEE80211_STYPE_CFEND		0x00E0
-#define IEEE80211_STYPE_CFENDACK	0x00F0
-
-/* data */
-#define IEEE80211_STYPE_DATA		0x0000
-#define IEEE80211_STYPE_DATA_CFACK	0x0010
-#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
-#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
-#define IEEE80211_STYPE_NULLFUNC	0x0040
-#define IEEE80211_STYPE_CFACK		0x0050
-#define IEEE80211_STYPE_CFPOLL		0x0060
-#define IEEE80211_STYPE_CFACKPOLL	0x0070
-#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
-#define IEEE80211_STYPE_QOS_NULL	0x00C0
-
-
-#define IEEE80211_SCTL_FRAG		0x000F
-#define IEEE80211_SCTL_SEQ		0xFFF0
-
 
 /* debug macros */
 
@@ -401,6 +161,10 @@ do { if (ieee80211_debug_level & (level)) \
 #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
 #endif	/* CONFIG_IEEE80211_DEBUG */
 
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
+		   ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
+
 /*
  * To use the debug system;
  *
@@ -493,68 +257,9 @@ struct ieee80211_snap_hdr {
 #define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
 #define WLAN_GET_SEQ_SEQ(seq)  ((seq) & IEEE80211_SCTL_SEQ)
 
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
-
 #define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_IBSS (1<<1)
-#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
-#define WLAN_CAPABILITY_PRIVACY (1<<4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
-#define WLAN_CAPABILITY_PBCC (1<<6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
 #define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
 
-/* Status codes */
-#define WLAN_STATUS_SUCCESS 0
-#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
-#define WLAN_STATUS_CAPS_UNSUPPORTED 10
-#define WLAN_STATUS_REASSOC_NO_ASSOC 11
-#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
-#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
-#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
-#define WLAN_STATUS_CHALLENGE_FAIL 15
-#define WLAN_STATUS_AUTH_TIMEOUT 16
-#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
-#define WLAN_STATUS_ASSOC_DENIED_RATES 18
-/* 802.11b */
-#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
-#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
-#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
-
-/* Reason codes */
-#define WLAN_REASON_UNSPECIFIED 1
-#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
-#define WLAN_REASON_DEAUTH_LEAVING 3
-#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
-#define WLAN_REASON_DISASSOC_AP_BUSY 5
-#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
-#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
-#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
-#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
-
-
-/* Information Element IDs */
-#define WLAN_EID_SSID 0
-#define WLAN_EID_SUPP_RATES 1
-#define WLAN_EID_FH_PARAMS 2
-#define WLAN_EID_DS_PARAMS 3
-#define WLAN_EID_CF_PARAMS 4
-#define WLAN_EID_TIM 5
-#define WLAN_EID_IBSS_PARAMS 6
-#define WLAN_EID_CHALLENGE 16
-#define WLAN_EID_RSN 48
-#define WLAN_EID_GENERIC 221
-
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-
 #define IEEE80211_STATMASK_SIGNAL (1<<0)
 #define IEEE80211_STATMASK_RSSI (1<<1)
 #define IEEE80211_STATMASK_NOISE (1<<2)
@@ -621,8 +326,25 @@ struct ieee80211_snap_hdr {
 #define IEEE80211_NUM_CCK_RATES	            4
 #define IEEE80211_OFDM_SHIFT_MASK_A         4
 
+/* this is stolen and modified from the madwifi driver*/
+#define IEEE80211_FC0_TYPE_MASK		0x0c
+#define IEEE80211_FC0_TYPE_DATA		0x08
+#define IEEE80211_FC0_SUBTYPE_MASK	0xB0
+#define IEEE80211_FC0_SUBTYPE_QOS	0x80
 
+#define IEEE80211_QOS_HAS_SEQ(fc) \
+	(((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
+	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
 
+/* this is stolen from ipw2200 driver */
+#define IEEE_IBSS_MAC_HASH_SIZE 31
+struct ieee_ibss_seq {
+	u8 mac[ETH_ALEN];
+	u16 seq_num[17];
+	u16 frag_num[17];
+	unsigned long packet_time[17];
+	struct list_head list;
+};
 
 /* NOTE: This data is for statistical purposes; not all hardware provides this
  *       information for frames received.  Not setting these will not cause
@@ -681,26 +403,6 @@ struct ieee80211_stats {
 	unsigned int rx_message_in_bad_msg_fragments;
 };
 
-struct ieee80211_softmac_stats{
-	unsigned int rx_ass_ok;
-	unsigned int rx_ass_err;
-	unsigned int rx_probe_rq;
-	unsigned int tx_probe_rs;
-	unsigned int tx_beacons;
-	unsigned int rx_auth_rq;
-	unsigned int rx_auth_rs_ok;
-	unsigned int rx_auth_rs_err;
-	unsigned int tx_auth_rq;
-	unsigned int no_auth_rs;
-	unsigned int no_ass_rs;
-	unsigned int tx_ass_rq;
-	unsigned int rx_ass_rq;
-	unsigned int tx_probe_rq;
-	unsigned int reassoc;
-	unsigned int swtxstop;
-	unsigned int swtxawake;
-};
-
 struct ieee80211_device;
 
 #include "ieee80211_crypt.h"
@@ -754,6 +456,23 @@ Total: 28-2340 bytes
 
 */
 
+/* Management Frame Information Element Types */
+enum {
+	MFIE_TYPE_SSID = 0,
+	MFIE_TYPE_RATES = 1,
+	MFIE_TYPE_FH_SET = 2,
+	MFIE_TYPE_DS_SET = 3,
+	MFIE_TYPE_CF_SET = 4,
+	MFIE_TYPE_TIM = 5,
+	MFIE_TYPE_IBSS_SET = 6,
+	MFIE_TYPE_COUNTRY = 7,
+	MFIE_TYPE_CHALLENGE = 16,
+	MFIE_TYPE_ERP = 42,
+	MFIE_TYPE_RSN = 48,
+	MFIE_TYPE_RATES_EX = 50,
+	MFIE_TYPE_GENERIC = 221,
+};
+
 struct ieee80211_header_data {
 	u16 frame_ctl;
 	u16 duration_id;
@@ -763,39 +482,45 @@ struct ieee80211_header_data {
 	u16 seq_ctrl;
 };
 
-#define BEACON_PROBE_SSID_ID_POSITION 12
+struct ieee80211_hdr_3addr {
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+} __attribute__ ((packed));
 
-/* Management Frame Information Element Types */
-#define MFIE_TYPE_SSID       0
-#define MFIE_TYPE_RATES      1
-#define MFIE_TYPE_FH_SET     2
-#define MFIE_TYPE_DS_SET     3
-#define MFIE_TYPE_CF_SET     4
-#define MFIE_TYPE_TIM        5
-#define MFIE_TYPE_IBSS_SET   6
-#define MFIE_TYPE_COUNTRY  7 //+YJ,080625
-#define MFIE_TYPE_CHALLENGE  16
-#define MFIE_TYPE_ERP        42
-#define MFIE_TYPE_RSN	     48
-#define MFIE_TYPE_RATES_EX   50
-#define MFIE_TYPE_GENERIC    221
-
-#ifdef ENABLE_DOT11D
-typedef enum
-{
-	COUNTRY_CODE_FCC = 0,
-	COUNTRY_CODE_IC = 1,
-	COUNTRY_CODE_ETSI = 2,
-	COUNTRY_CODE_SPAIN = 3,
-	COUNTRY_CODE_FRANCE = 4,
-	COUNTRY_CODE_MKK = 5,
-	COUNTRY_CODE_MKK1 = 6,
-	COUNTRY_CODE_ISRAEL = 7,
-	COUNTRY_CODE_TELEC = 8,
-	COUNTRY_CODE_GLOBAL_DOMAIN = 9,
-	COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
-}country_code_type_t;
-#endif
+struct ieee80211_hdr_4addr {
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+	u16 frame_ctl;
+	u16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	u16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+	u16 qos_ctl;
+} __attribute__ ((packed));
 
 struct ieee80211_info_element_hdr {
 	u8 id;
@@ -808,26 +533,6 @@ struct ieee80211_info_element {
 	u8 data[0];
 } __attribute__ ((packed));
 
-/*
- * These are the data types that can make up management packets
- *
-	u16 auth_algorithm;
-	u16 auth_sequence;
-	u16 beacon_interval;
-	u16 capability;
-	u8 current_ap[ETH_ALEN];
-	u16 listen_interval;
-	struct {
-		u16 association_id:14, reserved:2;
-	} __attribute__ ((packed));
-	u32 time_stamp[2];
-	u16 reason;
-	u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 10
-
 struct ieee80211_authentication {
 	struct ieee80211_header_data header;
 	u16 algorithm;
@@ -836,6 +541,15 @@ struct ieee80211_authentication {
 	//struct ieee80211_info_element_hdr info_element;
 } __attribute__ ((packed));
 
+struct ieee80211_disassoc_frame {
+	struct ieee80211_hdr_3addr header;
+	u16    reasoncode;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+	struct ieee80211_header_data header;
+	/* struct ieee80211_info_element info_element; */
+} __attribute__ ((packed));
 
 struct ieee80211_probe_response {
 	struct ieee80211_header_data header;
@@ -845,11 +559,6 @@ struct ieee80211_probe_response {
 	struct ieee80211_info_element info_element;
 } __attribute__ ((packed));
 
-struct ieee80211_probe_request {
-	struct ieee80211_header_data header;
-	/*struct ieee80211_info_element info_element;*/
-} __attribute__ ((packed));
-
 struct ieee80211_assoc_request_frame {
 	struct ieee80211_hdr_3addr header;
 	u16 capability;
@@ -866,11 +575,6 @@ struct ieee80211_assoc_response_frame {
 	struct ieee80211_info_element info_element; /* supported rates */
 } __attribute__ ((packed));
 
-struct ieee80211_disassoc_frame{
-        struct ieee80211_hdr_3addr header;
-        u16    reasoncode;
-}__attribute__ ((packed));
-
 struct ieee80211_txb {
 	u8 nr_frags;
 	u8 encrypted;
@@ -880,6 +584,32 @@ struct ieee80211_txb {
 	struct sk_buff *fragments[0];
 };
 
+/* SWEEP TABLE ENTRIES NUMBER */
+#define MAX_SWEEP_TAB_ENTRIES			42
+#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET	7
+
+/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
+ * only use 8, and then use extended rates for the remaining supported
+ * rates.  Other APs, however, stick all of their supported rates on the
+ * main rates information element... */
+#define MAX_RATES_LENGTH			((u8)12)
+#define MAX_RATES_EX_LENGTH			((u8)16)
+
+#define MAX_NETWORK_COUNT			128
+
+#define MAX_CHANNEL_NUMBER			165
+
+#define IEEE80211_SOFTMAC_SCAN_TIME		100 /* (HZ / 2) */
+#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME	(HZ * 2)
+
+#define CRC_LENGTH	4U
+
+#define MAX_WPA_IE_LEN	64
+
+#define NETWORK_EMPTY_ESSID	(1 << 0)
+#define NETWORK_HAS_OFDM	(1 << 1)
+#define NETWORK_HAS_CCK		(1 << 2)
+
 struct ieee80211_wmm_ac_param {
 	u8 ac_aci_acm_aifsn;
 	u8 ac_ecwmin_ecwmax;
@@ -911,23 +641,82 @@ struct ieee80211_wmm_tspec_elem {
 	u16 medium_time;
 }__attribute__((packed));
 
+enum eap_type {
+	EAP_PACKET = 0,
+	EAPOL_START,
+	EAPOL_LOGOFF,
+	EAPOL_KEY,
+	EAPOL_ENCAP_ASF_ALERT
+};
+
+static const char *eap_types[] = {
+	[EAP_PACKET]		= "EAP-Packet",
+	[EAPOL_START]		= "EAPOL-Start",
+	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
+	[EAPOL_KEY]		= "EAPOL-Key",
+	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
+};
+
+static inline const char *eap_get_type(int type)
+{
+	return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+
+struct eapol {
+	u8 snap[6];
+	u16 ethertype;
+	u8 version;
+	u8 type;
+	u16 length;
+} __attribute__ ((packed));
+
+struct ieee80211_softmac_stats {
+	unsigned int rx_ass_ok;
+	unsigned int rx_ass_err;
+	unsigned int rx_probe_rq;
+	unsigned int tx_probe_rs;
+	unsigned int tx_beacons;
+	unsigned int rx_auth_rq;
+	unsigned int rx_auth_rs_ok;
+	unsigned int rx_auth_rs_err;
+	unsigned int tx_auth_rq;
+	unsigned int no_auth_rs;
+	unsigned int no_ass_rs;
+	unsigned int tx_ass_rq;
+	unsigned int rx_ass_rq;
+	unsigned int tx_probe_rq;
+	unsigned int reassoc;
+	unsigned int swtxstop;
+	unsigned int swtxawake;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+/*
+ * These are the data types that can make up management packets
+ *
+	u16 auth_algorithm;
+	u16 auth_sequence;
+	u16 beacon_interval;
+	u16 capability;
+	u8 current_ap[ETH_ALEN];
+	u16 listen_interval;
+	struct {
+		u16 association_id:14, reserved:2;
+	} __attribute__ ((packed));
+	u32 time_stamp[2];
+	u16 reason;
+	u16 status;
+*/
+
+#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
+#define IEEE80211_DEFAULT_BASIC_RATE 10
+
 enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
 #define MAX_SP_Len  (WMM_all_frame << 4)
 #define IEEE80211_QOS_TID 0x0f
 #define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
 
-/* SWEEP TABLE ENTRIES NUMBER*/
-#define MAX_SWEEP_TAB_ENTRIES		  42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
-/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates.  Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH                  ((u8)12)
-#define MAX_RATES_EX_LENGTH               ((u8)16)
-#define MAX_NETWORK_COUNT                  128
-//#define MAX_CHANNEL_NUMBER                 161
-#define MAX_CHANNEL_NUMBER                 165 //YJ,modified,080625
 #define MAX_IE_LEN						0xFF //+YJ,080625
 
 typedef struct _CHANNEL_LIST{
@@ -935,23 +724,12 @@ typedef struct _CHANNEL_LIST{
 	u8	Len;
 }CHANNEL_LIST, *PCHANNEL_LIST;
 
-#define IEEE80211_SOFTMAC_SCAN_TIME	  100//400
-//(HZ / 2)
 //by amy for ps
 #define IEEE80211_WATCH_DOG_TIME    2000
 //by amy for ps
 //by amy for antenna
 #define ANTENNA_DIVERSITY_TIMER_PERIOD		1000 // 1000 m
 //by amy for antenna
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH                 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM    (1<<1)
-#define NETWORK_HAS_CCK     (1<<2)
 
 #define IEEE80211_DTIM_MBCAST 4
 #define IEEE80211_DTIM_UCAST 2
@@ -1044,13 +822,9 @@ struct ieee80211_network {
 //by amy 080312
 	u8 HighestOperaRate;
 //by amy 080312
-#ifdef THOMAS_TURBO
 	u8 Turbo_Enable;//enable turbo mode, added by thomas
-#endif
-#ifdef ENABLE_DOT11D
 	u16 CountryIeLen;
 	u8 CountryIeBuf[MAX_IE_LEN];
-#endif
 };
 
 enum ieee80211_state {
@@ -1094,24 +868,6 @@ enum ieee80211_state {
 
 #define DEFAULT_MAX_SCAN_AGE (15 * HZ)
 #define DEFAULT_FTS 2346
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
-extern inline int is_multicast_ether_addr(const u8 *addr)
-{
-        return ((addr[0] != 0xff) && (0x01 & addr[0]));
-}
-#endif
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
-extern inline int is_broadcast_ether_addr(const u8 *addr)
-{
-	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
-		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
-}
-#endif
 
 #define CFG_IEEE80211_RESERVE_FCS (1<<0)
 #define CFG_IEEE80211_COMPUTE_FCS (1<<1)
@@ -1121,6 +877,19 @@ typedef struct tx_pending_t{
 	struct ieee80211_txb *txb;
 }tx_pending_t;
 
+enum {
+	COUNTRY_CODE_FCC = 0,
+	COUNTRY_CODE_IC = 1,
+	COUNTRY_CODE_ETSI = 2,
+	COUNTRY_CODE_SPAIN = 3,
+	COUNTRY_CODE_FRANCE = 4,
+	COUNTRY_CODE_MKK = 5,
+	COUNTRY_CODE_MKK1 = 6,
+	COUNTRY_CODE_ISRAEL = 7,
+	COUNTRY_CODE_TELEC = 8,
+	COUNTRY_CODE_GLOBAL_DOMAIN = 9,
+	COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
+};
 
 struct ieee80211_device {
 	struct net_device *dev;
@@ -1207,18 +976,12 @@ struct ieee80211_device {
 	 */
 	short sync_scan_hurryup;
 
-#ifdef ENABLE_DOT11D
 	void * pDot11dInfo;
 	bool bGlobalDomain;
 
 	// For Liteon Ch12~13 passive scan
 	u8	MinPassiveChnlNum;
 	u8	IbssStartChnl;
-#else
-	/* map of allowed channels. 0 is dummy */
-	// FIXME: remeber to default to a basic channel plan depending of the PHY type
-	int channel_map[MAX_CHANNEL_NUMBER+1];
-#endif
 
 	int rate;       /* current rate */
 	int basic_rate;
@@ -1313,7 +1076,6 @@ struct ieee80211_device {
 	unsigned long NumRxOkTotal;
 	unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
 	bool bHwRadioOff;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
         struct delayed_work softmac_scan_wq;
         struct delayed_work associate_retry_wq;
 	struct delayed_work hw_wakeup_wq;
@@ -1329,24 +1091,7 @@ struct ieee80211_device {
 
 //Added for RF power on power off by lizhaoming 080512
 	struct delayed_work GPIOChangeRFWorkItem;
-#else
-
-	struct work_struct start_ibss_wq;
-        struct work_struct softmac_scan_wq;
-        struct work_struct associate_retry_wq;
-	struct work_struct hw_wakeup_wq;
-	struct work_struct hw_sleep_wq;
-	struct work_struct watch_dog_wq;
-	struct work_struct sw_antenna_wq;
-//by amy for rate adaptive 080312
-    struct work_struct rate_adapter_wq;
-//by amy for rate adaptive
-	struct work_struct hw_dig_wq;
-	struct work_struct tx_pw_wq;
 
-//Added for RF power on power off by lizhaoming 080512
-	struct work_struct GPIOChangeRFWorkItem;
-#endif
 	struct workqueue_struct *wq;
 
 	/* Callback functions */
@@ -1582,7 +1327,7 @@ extern void ieee80211_txb_free(struct ieee80211_txb *);
 extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 			struct ieee80211_rx_stats *rx_stats);
 extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-			     struct ieee80211_hdr *header,
+			     struct ieee80211_hdr_4addr *header,
 			     struct ieee80211_rx_stats *stats);
 
 /* ieee80211_wx.c */
@@ -1690,12 +1435,8 @@ extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_reques
 
 extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-#else
- extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#endif
-//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
 
 extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
 			       struct iw_request_info *info,
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
index 7370296..013c3e1 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
@@ -19,10 +19,6 @@
 #include <asm/string.h>
 #include <asm/errno.h>
 
-#if (LINUX_VERSION_CODE<KERNEL_VERSION(2,6,18))
-#include<linux/config.h>
-#endif
-
 #include "ieee80211.h"
 
 MODULE_AUTHOR("Jouni Malinen");
@@ -251,16 +247,3 @@ void ieee80211_crypto_deinit(void)
 	}
 	kfree(hcrypt);
 }
-
-#if 0
-EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
-EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
-EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
-
-EXPORT_SYMBOL(ieee80211_register_crypto_ops);
-EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
-EXPORT_SYMBOL(ieee80211_get_crypto_ops);
-#endif
-
-//module_init(ieee80211_crypto_init);
-//module_exit(ieee80211_crypto_deinit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
index 08add38..172e8f3 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
@@ -24,28 +24,13 @@
 
 #include "ieee80211.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
-    #include <linux/scatterlist.h>
-#endif
-
-//#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: CCMP");
 MODULE_LICENSE("GPL");
 
-#ifdef OPENSUSE_SLED
-#ifndef IN_OPENSUSE_SLED
-#define IN_OPENSUSE_SLED 1
-#endif
-#endif
 
 #define AES_BLOCK_LEN 16
 #define CCMP_HDR_LEN 8
@@ -77,21 +62,7 @@ struct ieee80211_ccmp_data {
 void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
 			     const u8 pt[16], u8 ct[16])
 {
-      	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
 	crypto_cipher_encrypt_one((void *)tfm, ct, pt);
-	#else
-	struct scatterlist src, dst;
-
-	src.page = virt_to_page(pt);
-	src.offset = offset_in_page(pt);
-	src.length = AES_BLOCK_LEN;
-
-	dst.page = virt_to_page(ct);
-	dst.offset = offset_in_page(ct);
-	dst.length = AES_BLOCK_LEN;
-
-	crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
-	#endif
 }
 
 static void * ieee80211_ccmp_init(int key_idx)
@@ -104,33 +75,20 @@ static void * ieee80211_ccmp_init(int key_idx)
 	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = key_idx;
 
-       #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
-	priv->tfm = crypto_alloc_tfm("aes", 0);
-	if (priv->tfm == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
-		       "crypto API aes\n");
-		goto fail;
-	}
-       #else
-       priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+	priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(priv->tfm)) {
 		printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
 		       "crypto API aes\n");
 		priv->tfm = NULL;
 		goto fail;
 	}
-	#endif
+
 	return priv;
 
 fail:
 	if (priv) {
 		if (priv->tfm)
-			//#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-       			#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
-			crypto_free_tfm(priv->tfm);
-                    #else
 			crypto_free_cipher((void *)priv->tfm);
-		      #endif
 		kfree(priv);
 	}
 
@@ -141,13 +99,9 @@ fail:
 static void ieee80211_ccmp_deinit(void *priv)
 {
 	struct ieee80211_ccmp_data *_priv = priv;
+
 	if (_priv && _priv->tfm)
-		//#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-       		#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
-		crypto_free_tfm(_priv->tfm);
-             #else
 		crypto_free_cipher((void *)_priv->tfm);
-		#endif
 	kfree(priv);
 }
 
@@ -159,9 +113,8 @@ static inline void xor_block(u8 *b, u8 *a, size_t len)
 		b[i] ^= a[i];
 }
 
-#ifndef JOHN_CCMP
 static void ccmp_init_blocks(struct crypto_tfm *tfm,
-			     struct ieee80211_hdr *hdr,
+			     struct ieee80211_hdr_4addr *hdr,
 			     u8 *pn, size_t dlen, u8 *b0, u8 *auth,
 			     u8 *s0)
 {
@@ -237,22 +190,20 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm,
 	b0[14] = b0[15] = 0;
 	ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
 }
-#endif
 
 static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
 	struct ieee80211_ccmp_data *key = priv;
 	int data_len, i;
 	u8 *pos;
-	struct ieee80211_hdr *hdr;
-#ifndef JOHN_CCMP
+	struct ieee80211_hdr_4addr *hdr;
 	int blocks, last, len;
 	u8 *mic;
 	u8 *b0 = key->tx_b0;
 	u8 *b = key->tx_b;
 	u8 *e = key->tx_e;
 	u8 *s0 = key->tx_s0;
-#endif
+
 	if (skb_headroom(skb) < CCMP_HDR_LEN ||
 	    skb_tailroom(skb) < CCMP_MIC_LEN ||
 	    skb->len < hdr_len)
@@ -281,8 +232,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	*pos++ = key->tx_pn[1];
 	*pos++ = key->tx_pn[0];
 
-	hdr = (struct ieee80211_hdr *) skb->data;
-#ifndef JOHN_CCMP
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	//mic is moved to here by john
 	mic = skb_put(skb, CCMP_MIC_LEN);
 
@@ -306,7 +256,7 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 	for (i = 0; i < CCMP_MIC_LEN; i++)
 		mic[i] = b[i] ^ s0[i];
-#endif
+
 	return 0;
 }
 
@@ -315,22 +265,21 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
 	struct ieee80211_ccmp_data *key = priv;
 	u8 keyidx, *pos;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u8 pn[6];
-#ifndef JOHN_CCMP
 	size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
 	u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
 	u8 *b0 = key->rx_b0;
 	u8 *b = key->rx_b;
 	u8 *a = key->rx_a;
 	int i, blocks, last, len;
-#endif
+
 	if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
 		key->dot11RSNAStatsCCMPFormatErrors++;
 		return -1;
 	}
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	pos = skb->data + hdr_len;
 	keyidx = pos[3];
 	if (!(keyidx & (1 << 5))) {
@@ -376,7 +325,6 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 		return -4;
 	}
 
-#ifndef JOHN_CCMP
 	ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
 	xor_block(mic, b, CCMP_MIC_LEN);
 
@@ -407,7 +355,6 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 	memcpy(key->rx_pn, pn, CCMP_PN_LEN);
 
-#endif
 	/* Remove hdr and MIC */
 	memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
 	skb_pull(skb, CCMP_HDR_LEN);
@@ -520,14 +467,3 @@ void ieee80211_crypto_ccmp_exit(void)
 {
 	ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
 }
-
-#if 0
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_ccmp_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
-#endif
-#endif
-
-//module_init(ieee80211_crypto_ccmp_init);
-//module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
index de97bbe..e6d8385 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
@@ -23,29 +23,14 @@
 
 #include "ieee80211.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
-//#include <asm/scatterlist.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-    #include <asm/scatterlist.h>
-#else
-    #include <linux/scatterlist.h>
-#endif
-
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: TKIP");
 MODULE_LICENSE("GPL");
 
-#ifdef OPENSUSE_SLED
-#ifndef IN_OPENSUSE_SLED
-#define IN_OPENSUSE_SLED 1
-#endif
-#endif
 
 struct ieee80211_tkip_data {
 #define TKIP_KEY_LEN 32
@@ -70,13 +55,10 @@ struct ieee80211_tkip_data {
 
 	int key_idx;
 
-       #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
-	   	struct crypto_blkcipher *rx_tfm_arc4;
-	       struct crypto_hash *rx_tfm_michael;
-	       struct crypto_blkcipher *tx_tfm_arc4;
-	       struct crypto_hash *tx_tfm_michael;
-       #endif
-
+	struct crypto_blkcipher *rx_tfm_arc4;
+	struct crypto_hash *rx_tfm_michael;
+	struct crypto_blkcipher *tx_tfm_arc4;
+	struct crypto_hash *tx_tfm_michael;
 	struct crypto_tfm *tfm_arc4;
 	struct crypto_tfm *tfm_michael;
 
@@ -94,22 +76,6 @@ static void * ieee80211_tkip_init(int key_idx)
 	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = key_idx;
 
-      #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
-	if (priv->tfm_arc4 == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-		       "crypto API arc4\n");
-		goto fail;
-	}
-
-	priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
-	if (priv->tfm_michael == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-		       "crypto API michael_mic\n");
-		goto fail;
-	}
-
-	#else
 	priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
 						CRYPTO_ALG_ASYNC);
 	if (IS_ERR(priv->tx_tfm_arc4)) {
@@ -145,17 +111,11 @@ static void * ieee80211_tkip_init(int key_idx)
 		priv->rx_tfm_michael = NULL;
 		goto fail;
 	}
-       #endif
+
 	return priv;
 
 fail:
 	if (priv) {
-		#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-		if (priv->tfm_michael)
-			crypto_free_tfm(priv->tfm_michael);
-		if (priv->tfm_arc4)
-			crypto_free_tfm(priv->tfm_arc4);
-             #else
 		if (priv->tx_tfm_michael)
 			crypto_free_hash(priv->tx_tfm_michael);
 		if (priv->tx_tfm_arc4)
@@ -164,7 +124,6 @@ fail:
 			crypto_free_hash(priv->rx_tfm_michael);
 		if (priv->rx_tfm_arc4)
 			crypto_free_blkcipher(priv->rx_tfm_arc4);
-		#endif
 		kfree(priv);
 	}
 
@@ -175,12 +134,7 @@ fail:
 static void ieee80211_tkip_deinit(void *priv)
 {
 	struct ieee80211_tkip_data *_priv = priv;
-	#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	if (_priv && _priv->tfm_michael)
-		crypto_free_tfm(_priv->tfm_michael);
-	if (_priv && _priv->tfm_arc4)
-		crypto_free_tfm(_priv->tfm_arc4);
-	#else
+
 	if (_priv) {
 		if (_priv->tx_tfm_michael)
 			crypto_free_hash(_priv->tx_tfm_michael);
@@ -191,7 +145,6 @@ static void ieee80211_tkip_deinit(void *priv)
 		if (_priv->rx_tfm_arc4)
 			crypto_free_blkcipher(_priv->rx_tfm_arc4);
 	}
-	#endif
 	kfree(priv);
 }
 
@@ -281,7 +234,6 @@ static inline u16 _S_(u16 v)
 	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
 }
 
-#ifndef JOHN_TKIP
 #define PHASE1_LOOP_COUNT 8
 
 static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
@@ -351,21 +303,17 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
 	}
 #endif
 }
-#endif
+
 static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
         struct ieee80211_tkip_data *tkey = priv;
-        #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
         struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
-        #endif
 	int len;
 	u8  *pos;
-	struct ieee80211_hdr *hdr;
-#ifndef JOHN_TKIP
+	struct ieee80211_hdr_4addr *hdr;
 	u8 rc4key[16],*icv;
 	u32 crc;
 	struct scatterlist sg;
-#endif
 	int ret;
 
 	ret = 0;
@@ -373,20 +321,8 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	    skb->len < hdr_len)
 		return -1;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
-#if 0
-printk("@@ tkey\n");
-printk("%x|", ((u32*)tkey->key)[0]);
-printk("%x|", ((u32*)tkey->key)[1]);
-printk("%x|", ((u32*)tkey->key)[2]);
-printk("%x|", ((u32*)tkey->key)[3]);
-printk("%x|", ((u32*)tkey->key)[4]);
-printk("%x|", ((u32*)tkey->key)[5]);
-printk("%x|", ((u32*)tkey->key)[6]);
-printk("%x\n", ((u32*)tkey->key)[7]);
-#endif
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 
-#ifndef JOHN_TKIP
 	if (!tkey->tx_phase1_done) {
 		tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
 				   tkey->tx_iv32);
@@ -394,95 +330,56 @@ printk("%x\n", ((u32*)tkey->key)[7]);
 	}
 	tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
 
-#else
-	tkey->tx_phase1_done = 1;
-#endif  /*JOHN_TKIP*/
-
 	len = skb->len - hdr_len;
 	pos = skb_push(skb, 8);
 	memmove(pos, pos + 8, hdr_len);
 	pos += hdr_len;
 
-#ifdef JOHN_TKIP
-	*pos++ = Hi8(tkey->tx_iv16);
-	*pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
-	*pos++ = Lo8(tkey->tx_iv16);
-#else
 	*pos++ = rc4key[0];
 	*pos++ = rc4key[1];
 	*pos++ = rc4key[2];
-#endif
 	*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
 	*pos++ = tkey->tx_iv32 & 0xff;
 	*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
 	*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
 	*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
-#ifndef JOHN_TKIP
+
 	icv = skb_put(skb, 4);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 	crc = ~crc32_le(~0, pos, len);
-#else
-	crc = ~ether_crc_le(len, pos);
-#endif
 	icv[0] = crc;
 	icv[1] = crc >> 8;
 	icv[2] = crc >> 16;
 	icv[3] = crc >> 24;
-      #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
-	crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
-      #else
 	crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-        #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-          sg.page = virt_to_page(pos);
-          sg.offset = offset_in_page(pos);
-          sg.length = len + 4;
-        #else
-          sg_init_one(&sg, pos, len+4);
-        #endif
+	sg_init_one(&sg, pos, len + 4);
 	ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-      #endif
-#endif
+
 	tkey->tx_iv16++;
 	if (tkey->tx_iv16 == 0) {
 		tkey->tx_phase1_done = 0;
 		tkey->tx_iv32++;
 	}
-#ifndef JOHN_TKIP
-      #if((LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	   return 0;
-      #else
 	   return ret;
-      #endif
-#else
-	return 0;
-#endif
 }
 
 static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
-        struct ieee80211_tkip_data *tkey = priv;
-        #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) ||(IN_OPENSUSE_SLED))
-        struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
-        #endif
+	struct ieee80211_tkip_data *tkey = priv;
+	struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
 	u8 keyidx, *pos;
 	u32 iv32;
 	u16 iv16;
-	struct ieee80211_hdr *hdr;
-#ifndef JOHN_TKIP
+	struct ieee80211_hdr_4addr *hdr;
 	u8 icv[4];
 	u32 crc;
 	struct scatterlist sg;
 	u8 rc4key[16];
 	int plen;
-#endif
+
 	if (skb->len < hdr_len + 8 + 4)
 		return -1;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	pos = skb->data + hdr_len;
 	keyidx = pos[3];
 	if (!(keyidx & (1 << 5))) {
@@ -509,7 +406,6 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	iv16 = (pos[0] << 8) | pos[2];
 	iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
 	pos += 8;
-#ifndef JOHN_TKIP
 
 	if (iv32 < tkey->rx_iv32 ||
 	    (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
@@ -530,21 +426,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
 
 	plen = skb->len - hdr_len - 12;
-       #if((LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
-	crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
-	#else
 	crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-        #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,24))
-          sg.page = virt_to_page(pos);
-          sg.offset = offset_in_page(pos);
-          sg.length = plen + 4;
-        #else
-          sg_init_one(&sg, pos, plen+4);
-        #endif
+	sg_init_one(&sg, pos, plen + 4);
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -553,13 +436,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 		}
 		return -7;
 	}
-	#endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 	crc = ~crc32_le(~0, pos, plen);
-#else
-	crc = ~ether_crc_le(plen, pos);
-#endif
 	icv[0] = crc;
 	icv[1] = crc >> 8;
 	icv[2] = crc >> 16;
@@ -578,8 +456,6 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 		return -5;
 	}
 
-#endif 	/* JOHN_TKIP */
-
 	/* Update real counters only after Michael MIC verification has
 	 * completed */
 	tkey->rx_iv32_new = iv32;
@@ -590,67 +466,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	skb_pull(skb, 8);
 	skb_trim(skb, skb->len - 4);
 
-//john's test
-#ifdef JOHN_DUMP
-if( ((u16*)skb->data)[0] & 0x4000){
-        printk("@@ rx decrypted skb->data");
-        int i;
-        for(i=0;i<skb->len;i++){
-                if( (i%24)==0 ) printk("\n");
-                printk("%2x ", ((u8*)skb->data)[i]);
-        }
-        printk("\n");
-}
-#endif /*JOHN_DUMP*/
 	return keyidx;
 }
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
-static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
-		       u8 *data, size_t data_len, u8 *mic)
-{
-	struct scatterlist sg[2];
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-	struct hash_desc desc;
-	int ret=0;
-#endif
-	if (tkey->tfm_michael == NULL) {
-		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
-		return -1;
-	}
-	sg[0].page = virt_to_page(hdr);
-	sg[0].offset = offset_in_page(hdr);
-	sg[0].length = 16;
-
-	sg[1].page = virt_to_page(data);
-	sg[1].offset = offset_in_page(data);
-	sg[1].length = data_len;
-
-	//crypto_digest_init(tkey->tfm_michael);
-	//crypto_digest_setkey(tkey->tfm_michael, key, 8);
-	//crypto_digest_update(tkey->tfm_michael, sg, 2);
-	//crypto_digest_final(tkey->tfm_michael, mic);
-
-	//return 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	crypto_digest_init(tkey->tfm_michael);
-	crypto_digest_setkey(tkey->tfm_michael, key, 8);
-	crypto_digest_update(tkey->tfm_michael, sg, 2);
-	crypto_digest_final(tkey->tfm_michael, mic);
-
-	return 0;
-#else
-if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
-		return -1;
-
-//	return 0;
-	desc.tfm = tkey->tfm_michael;
-	desc.flags = 0;
-	ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
-	return ret;
-#endif
-}
-#else
 static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                        u8 * data, size_t data_len, u8 * mic)
 {
@@ -661,18 +479,10 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
                 return -1;
         }
-        #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-          sg[0].page = virt_to_page(hdr);
-          sg[0].offset = offset_in_page(hdr);
-          sg[0].length = 16;
-          sg[1].page = virt_to_page(data);
-          sg[1].offset = offset_in_page(data);
-          sg[1].length = data_len;
-        #else
-          sg_init_table(sg, 2);
-          sg_set_buf(&sg[0], hdr, 16);
-          sg_set_buf(&sg[1], data, data_len);
-        #endif
+
+	sg_init_table(sg, 2);
+	sg_set_buf(&sg[0], hdr, 16);
+	sg_set_buf(&sg[1], data, data_len);
 
         if (crypto_hash_setkey(tfm_michael, key, 8))
                 return -1;
@@ -681,15 +491,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
         desc.flags = 0;
         return crypto_hash_digest(&desc, sg, data_len + 16, mic);
 }
-#endif
-
-
 
 static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
 {
-	struct ieee80211_hdr *hdr11;
+	struct ieee80211_hdr_4addr *hdr11;
 
-	hdr11 = (struct ieee80211_hdr *) skb->data;
+	hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
 	switch (le16_to_cpu(hdr11->frame_ctl) &
 		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 	case IEEE80211_FCTL_TODS:
@@ -720,9 +527,9 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
 {
 	struct ieee80211_tkip_data *tkey = priv;
 	u8 *pos;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 
 	if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
 		printk(KERN_DEBUG "Invalid packet for Michael MIC add "
@@ -740,22 +547,16 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
 	}
 	// }
 	pos = skb_put(skb, 8);
-        #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
+
+	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
 			skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
-        #else
-        if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
-                        skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
-        #endif
 		return -1;
 
 	return 0;
 }
 
-
-#if WIRELESS_EXT >= 18
 static void ieee80211_michael_mic_failure(struct net_device *dev,
-				       struct ieee80211_hdr *hdr,
+				       struct ieee80211_hdr_4addr *hdr,
 				       int keyidx)
 {
 	union iwreq_data wrqu;
@@ -774,39 +575,15 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
 	wrqu.data.length = sizeof(ev);
 	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
 }
-#elif WIRELESS_EXT >= 15
-static void ieee80211_michael_mic_failure(struct net_device *dev,
-				       struct ieee80211_hdr *hdr,
-				       int keyidx)
-{
-	union iwreq_data wrqu;
-	char buf[128];
-
-	/* TODO: needed parameters: count, keyid, key type, TSC */
-	sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
-		MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
-		MAC_ARG(hdr->addr2));
-	memset(&wrqu, 0, sizeof(wrqu));
-	wrqu.data.length = strlen(buf);
-	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
-}
-#else /* WIRELESS_EXT >= 15 */
-static inline void ieee80211_michael_mic_failure(struct net_device *dev,
-					      struct ieee80211_hdr *hdr,
-					      int keyidx)
-{
-}
-#endif /* WIRELESS_EXT >= 15 */
-
 
 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
 				     int hdr_len, void *priv)
 {
 	struct ieee80211_tkip_data *tkey = priv;
 	u8 mic[8];
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 
 	if (!tkey->key_set)
 		return -1;
@@ -818,17 +595,14 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
 		tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
 	}
 	// }
-        #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
-			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
-        #else
+
 	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
-                        skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
-        #endif
-            	return -1;
+			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
+		return -1;
+
 	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
-		struct ieee80211_hdr *hdr;
-		hdr = (struct ieee80211_hdr *) skb->data;
+		struct ieee80211_hdr_4addr *hdr;
+		hdr = (struct ieee80211_hdr_4addr *)skb->data;
 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
 		       "MSDU from " MAC_FMT " keyidx=%d\n",
 		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
@@ -854,29 +628,19 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
 {
 	struct ieee80211_tkip_data *tkey = priv;
 	int keyidx;
-	#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	struct crypto_tfm *tfm = tkey->tfm_michael;
-	struct crypto_tfm *tfm2 = tkey->tfm_arc4;
-	#else
 	struct crypto_hash *tfm = tkey->tx_tfm_michael;
 	struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
 	struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
 	struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-	#endif
 
 	keyidx = tkey->key_idx;
 	memset(tkey, 0, sizeof(*tkey));
 	tkey->key_idx = keyidx;
 
-	#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	tkey->tfm_michael = tfm;
-	tkey->tfm_arc4 = tfm2;
-       #else
 	tkey->tx_tfm_michael = tfm;
 	tkey->tx_tfm_arc4 = tfm2;
 	tkey->rx_tfm_michael = tfm3;
 	tkey->rx_tfm_arc4 = tfm4;
-	#endif
 
 	if (len == TKIP_KEY_LEN) {
 		memcpy(tkey->key, key, TKIP_KEY_LEN);
@@ -987,15 +751,3 @@ void ieee80211_tkip_null(void)
 //    printk("============>%s()\n", __func__);
         return;
 }
-
-#if 0
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_tkip_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
-#endif
-#endif
-
-
-//module_init(ieee80211_crypto_tkip_init);
-//module_exit(ieee80211_crypto_tkip_exit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
index 68a22b3..c6c3bc3 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
@@ -20,29 +20,14 @@
 
 #include "ieee80211.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
-    #include <linux/scatterlist.h>
-#endif
-//#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: WEP");
 MODULE_LICENSE("GPL");
 
-#ifdef OPENSUSE_SLED
-#ifndef IN_OPENSUSE_SLED
-#define IN_OPENSUSE_SLED 1
-#endif
-#endif
 
 
 struct prism2_wep_data {
@@ -51,12 +36,8 @@ struct prism2_wep_data {
 	u8 key[WEP_KEY_LEN + 1];
 	u8 key_len;
 	u8 key_idx;
-	#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	struct crypto_tfm *tfm;
-	#else
 	struct crypto_blkcipher *tx_tfm;
 	struct crypto_blkcipher *rx_tfm;
-	#endif
 };
 
 
@@ -69,14 +50,6 @@ static void * prism2_wep_init(int keyidx)
 		goto fail;
 	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = keyidx;
-	#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	priv->tfm = crypto_alloc_tfm("arc4", 0);
-     	if (priv->tfm == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
-		       "crypto API arc4\n");
-		goto fail;
-	}
-	#else
 	priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(priv->tx_tfm)) {
 		printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
@@ -91,7 +64,6 @@ static void * prism2_wep_init(int keyidx)
 		priv->rx_tfm = NULL;
 		goto fail;
 	}
-	#endif
 
 	/* start WEP IV from a random value */
 	get_random_bytes(&priv->iv, 4);
@@ -99,14 +71,6 @@ static void * prism2_wep_init(int keyidx)
 	return priv;
 
 fail:
-	//#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-	#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	if (priv) {
-		if (priv->tfm)
-			crypto_free_tfm(priv->tfm);
-		kfree(priv);
-	}
-       #else
 	if (priv) {
 		if (priv->tx_tfm)
 			crypto_free_blkcipher(priv->tx_tfm);
@@ -114,7 +78,7 @@ fail:
 			crypto_free_blkcipher(priv->rx_tfm);
 		kfree(priv);
 	}
-	#endif
+
 	return NULL;
 }
 
@@ -122,18 +86,14 @@ fail:
 static void prism2_wep_deinit(void *priv)
 {
 	struct prism2_wep_data *_priv = priv;
-	//#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-	#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	if (_priv && _priv->tfm)
-		crypto_free_tfm(_priv->tfm);
-	#else
+
 	if (_priv) {
 		if (_priv->tx_tfm)
 			crypto_free_blkcipher(_priv->tx_tfm);
 		if (_priv->rx_tfm)
 			crypto_free_blkcipher(_priv->rx_tfm);
 	}
-        #endif
+
 	kfree(priv);
 }
 
@@ -147,18 +107,14 @@ static void prism2_wep_deinit(void *priv)
 static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
 	struct prism2_wep_data *wep = priv;
-//#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
-        struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
-#endif
+	struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
 	u32 klen, len;
 	u8 key[WEP_KEY_LEN + 3];
 	u8 *pos;
-#ifndef JOHN_HWSEC
 	u32 crc;
 	u8 *icv;
 	struct scatterlist sg;
-#endif
+
 	if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
 	    skb->len < hdr_len)
 		return -1;
@@ -190,41 +146,18 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	/* Copy rest of the WEP key (the secret part) */
 	memcpy(key + 3, wep->key, wep->key_len);
 
-#ifndef JOHN_HWSEC
 	/* Append little-endian CRC32 and encrypt it to produce ICV */
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 	crc = ~crc32_le(~0, pos, len);
-#else
-	crc = ~ether_crc_le(len, pos);
-#endif
 	icv = skb_put(skb, 4);
 	icv[0] = crc;
 	icv[1] = crc >> 8;
 	icv[2] = crc >> 16;
 	icv[3] = crc >> 24;
 
-        //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-	#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	crypto_cipher_setkey(wep->tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = len + 4;
-	crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
-
-	return 0;
-	#else
 	crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-        #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-          sg.page = virt_to_page(pos);
-          sg.offset = offset_in_page(pos);
-          sg.length = len + 4;
-        #else
-          sg_init_one(&sg, pos, len+4);
-        #endif
+	sg_init_one(&sg, pos, len + 4);
+
 	return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-	#endif
-#endif /* JOHN_HWSEC */
-	return 0;
 }
 
 
@@ -238,18 +171,14 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 {
 	struct prism2_wep_data *wep = priv;
-        //#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
-	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
-        struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
-        #endif
+	struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
 	u32 klen, plen;
 	u8 key[WEP_KEY_LEN + 3];
 	u8 keyidx, *pos;
-#ifndef JOHN_HWSEC
 	u32 crc;
 	u8 icv[4];
 	struct scatterlist sg;
-#endif
+
 	if (skb->len < hdr_len + 8)
 		return -1;
 
@@ -268,32 +197,14 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 	/* Apply RC4 to data and compute CRC32 over decrypted data */
 	plen = skb->len - hdr_len - 8;
-#ifndef JOHN_HWSEC
-//#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
-	crypto_cipher_setkey(wep->tfm, key, klen);
-	sg.page = virt_to_page(pos);
-	sg.offset = offset_in_page(pos);
-	sg.length = plen + 4;
-	crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
-#else
+
 	crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-        #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-          sg.page = virt_to_page(pos);
-          sg.offset = offset_in_page(pos);
-          sg.length = plen + 4;
-        #else
-          sg_init_one(&sg, pos, plen+4);
-        #endif
+	sg_init_one(&sg, pos, plen + 4);
+
 	if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 		return -7;
-#endif
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 	crc = ~crc32_le(~0, pos, plen);
-#else
-	crc = ~ether_crc_le(plen, pos);
-#endif
 	icv[0] = crc;
 	icv[1] = crc >> 8;
 	icv[2] = crc >> 16;
@@ -303,7 +214,6 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 		/* ICV mismatch - drop frame */
 		return -2;
 	}
-#endif 	/* JOHN_HWSEC */
 
 	/* Remove IV and ICV */
 	memmove(skb->data + 4, skb->data, hdr_len);
@@ -383,12 +293,3 @@ void ieee80211_wep_null(void)
 //	printk("============>%s()\n", __func__);
         return;
 }
-#if 0
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_wep_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
-#endif
-#endif
-//module_init(ieee80211_crypto_wep_init);
-//module_exit(ieee80211_crypto_wep_exit);
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
index c2b61e6..6fbe489 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
@@ -210,91 +210,3 @@ void free_ieee80211(struct net_device *dev)
 
 	free_netdev(dev);
 }
-
-//#ifdef CONFIG_IEEE80211_DEBUG
-#if 0
-
-static int debug = 0;
-u32 ieee80211_debug_level = 0;
-struct proc_dir_entry *ieee80211_proc = NULL;
-
-static int show_debug_level(char *page, char **start, off_t offset,
-			    int count, int *eof, void *data)
-{
-	return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
-}
-
-static int store_debug_level(struct file *file, const char *buffer,
-			     unsigned long count, void *data)
-{
-	char buf[] = "0x00000000";
-	unsigned long len = min(sizeof(buf) - 1, (u32)count);
-	char *p = (char *)buf;
-	unsigned long val;
-
-	if (copy_from_user(buf, buffer, len))
-		return count;
-	buf[len] = 0;
-	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
-		p++;
-		if (p[0] == 'x' || p[0] == 'X')
-			p++;
-		val = simple_strtoul(p, &p, 16);
-	} else
-		val = simple_strtoul(p, &p, 10);
-	if (p == buf)
-		printk(KERN_INFO DRV_NAME
-		       ": %s is not in hex or decimal form.\n", buf);
-	else
-		ieee80211_debug_level = val;
-
-	return strnlen(buf, count);
-}
-
-static int __init ieee80211_init(void)
-{
-	struct proc_dir_entry *e;
-
-	ieee80211_debug_level = debug;
-	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
-	if (ieee80211_proc == NULL) {
-		IEEE80211_ERROR("Unable to create " DRV_NAME
-				" proc directory\n");
-		return -EIO;
-	}
-	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
-			      ieee80211_proc);
-	if (!e) {
-		remove_proc_entry(DRV_NAME, proc_net);
-		ieee80211_proc = NULL;
-		return -EIO;
-	}
-	e->read_proc = show_debug_level;
-	e->write_proc = store_debug_level;
-	e->data = NULL;
-
-	return 0;
-}
-
-static void __exit ieee80211_exit(void)
-{
-	if (ieee80211_proc) {
-		remove_proc_entry("debug_level", ieee80211_proc);
-		remove_proc_entry(DRV_NAME, proc_net);
-		ieee80211_proc = NULL;
-	}
-}
-
-#include <linux/moduleparam.h>
-module_param(debug, int, 0444);
-MODULE_PARM_DESC(debug, "debug output mask");
-
-
-module_exit(ieee80211_exit);
-module_init(ieee80211_init);
-#endif
-
-#if 0
-EXPORT_SYMBOL(alloc_ieee80211);
-EXPORT_SYMBOL(free_ieee80211);
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
index 4d4ee56..5e2e79b 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
@@ -44,22 +44,17 @@
 #include <linux/ctype.h>
 
 #include "ieee80211.h"
-#ifdef ENABLE_DOT11D
 #include "dot11d.h"
-#endif
 static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
 					struct sk_buff *skb,
 					struct ieee80211_rx_stats *rx_stats)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_hdr_4addr *hdr =
+		(struct ieee80211_hdr_4addr *)skb->data;
 	u16 fc = le16_to_cpu(hdr->frame_ctl);
 
 	skb->dev = ieee->dev;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-        skb_reset_mac_header(skb);
-#else
-        skb->mac.raw = skb->data;
-#endif
+	skb_reset_mac_header(skb);
 	skb_pull(skb, ieee80211_get_hdrlen(fc));
 	skb->pkt_type = PACKET_OTHERHOST;
 	skb->protocol = __constant_htons(ETH_P_80211_RAW);
@@ -101,7 +96,7 @@ ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
 /* Called only as a tasklet (software IRQ) */
 static struct sk_buff *
 ieee80211_frag_cache_get(struct ieee80211_device *ieee,
-			 struct ieee80211_hdr *hdr)
+			 struct ieee80211_hdr_4addr *hdr)
 {
 	struct sk_buff *skb = NULL;
 	u16 fc = le16_to_cpu(hdr->frame_ctl);
@@ -109,25 +104,18 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 	unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
 	unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
 	struct ieee80211_frag_entry *entry;
-	struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
-	struct ieee80211_hdr_QOS *hdr_4addr_QoS;
+	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
 	u8 tid;
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->iw_mode == ieee->iw_ext_mode)
-	{
-		tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
-	}
-	else
-#endif
 	if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
-	  hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
-	  tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
 	  tid = UP2AC(tid);
 	  tid ++;
 	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
-	  hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
-	  tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
 	  tid = UP2AC(tid);
 	  tid ++;
 	} else {
@@ -137,7 +125,7 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 	if (frag == 0) {
 		/* Reserve enough space to fit maximum frame length */
 		skb = dev_alloc_skb(ieee->dev->mtu +
-				    sizeof(struct ieee80211_hdr) +
+				    sizeof(struct ieee80211_hdr_4addr) +
 				    8 /* LLC */ +
 				    2 /* alignment */ +
 				    8 /* WEP */ +
@@ -177,31 +165,24 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee,
 
 /* Called only as a tasklet (software IRQ) */
 static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
-					   struct ieee80211_hdr *hdr)
+					   struct ieee80211_hdr_4addr *hdr)
 {
 	u16 fc = le16_to_cpu(hdr->frame_ctl);
 	u16 sc = le16_to_cpu(hdr->seq_ctl);
 	unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
 	struct ieee80211_frag_entry *entry;
-	struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
-	struct ieee80211_hdr_QOS *hdr_4addr_QoS;
+	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
 	u8 tid;
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->iw_mode == ieee->iw_ext_mode)
-	{
-		tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
-	}
-	else
-#endif
 	if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
-	  hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
-	  tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
 	  tid = UP2AC(tid);
 	  tid ++;
 	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
-	  hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
-	  tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
 	  tid = UP2AC(tid);
 	  tid ++;
 	} else {
@@ -234,17 +215,18 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 			struct ieee80211_rx_stats *rx_stats, u16 type,
 			u16 stype)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	// cheat the the hdr type
-	hdr = (struct ieee80211_hdr *)skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 
 	/* On the struct stats definition there is written that
 	 * this is not mandatory.... but seems that the probe
 	 * response parser uses it
 	 */
 	rx_stats->len = skb->len;
-	ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
+	ieee80211_rx_mgt(ieee, (struct ieee80211_hdr_4addr *)skb->data,
+			 rx_stats);
 
 	if((ieee->state == IEEE80211_LINKED)&&(memcmp(hdr->addr3,ieee->current_network.bssid,ETH_ALEN))) {
 		dev_kfree_skb_any(skb);
@@ -257,51 +239,6 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 	return 0;
 
-	#ifdef NOT_YET
-	if (ieee->iw_mode == IW_MODE_MASTER) {
-		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
-		       ieee->dev->name);
-		return 0;
-/*
-  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
-  skb->data);*/
-	}
-
-	if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
-		if (stype == WLAN_FC_STYPE_BEACON &&
-		    ieee->iw_mode == IW_MODE_MASTER) {
-			struct sk_buff *skb2;
-			/* Process beacon frames also in kernel driver to
-			 * update STA(AP) table statistics */
-			skb2 = skb_clone(skb, GFP_ATOMIC);
-			if (skb2)
-				hostap_rx(skb2->dev, skb2, rx_stats);
-		}
-
-		/* send management frames to the user space daemon for
-		 * processing */
-		ieee->apdevstats.rx_packets++;
-		ieee->apdevstats.rx_bytes += skb->len;
-		prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
-		return 0;
-	}
-
-	    if (ieee->iw_mode == IW_MODE_MASTER) {
-		if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
-			printk(KERN_DEBUG "%s: unknown management frame "
-			       "(type=0x%02x, stype=0x%02x) dropped\n",
-			       skb->dev->name, type, stype);
-			return -1;
-		}
-
-		hostap_rx(skb->dev, skb, rx_stats);
-		return 0;
-	}
-
-	printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
-	       "received in non-Host AP mode\n", skb->dev->name);
-	return -1;
-	#endif
 }
 
 
@@ -321,13 +258,13 @@ static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
 {
 	struct net_device *dev = ieee->dev;
 	u16 fc, ethertype;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u8 *pos;
 
 	if (skb->len < 24)
 		return 0;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	/* check that the frame is unicast frame to us */
@@ -361,20 +298,13 @@ static inline int
 ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
 			   struct ieee80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
-	{
-		hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
-	}
-	else
-#endif
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
@@ -413,20 +343,13 @@ static inline int
 ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
 			     int keyidx, struct ieee80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
-	{
-		hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
-	}
-	else
-#endif
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
 	atomic_inc(&crypt->refcnt);
@@ -446,7 +369,7 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *s
 /* this function is stolen from ipw2200 driver*/
 #define IEEE_PACKET_RETRY_TIME (5*HZ)
 static int is_duplicate_packet(struct ieee80211_device *ieee,
-				      struct ieee80211_hdr *header)
+				      struct ieee80211_hdr_4addr *header)
 {
 	u16 fc = le16_to_cpu(header->frame_ctl);
 	u16 sc = le16_to_cpu(header->seq_ctl);
@@ -454,26 +377,19 @@ static int is_duplicate_packet(struct ieee80211_device *ieee,
 	u16 frag = WLAN_GET_SEQ_FRAG(sc);
 	u16 *last_seq, *last_frag;
 	unsigned long *last_time;
-	struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
-	struct ieee80211_hdr_QOS *hdr_4addr_QoS;
+	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
 	u8 tid;
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->iw_mode == ieee->iw_ext_mode)
-	{
-		tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
-	}
-	else
-#endif
 	//TO2DS and QoS
 	if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
-	  hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
-	  tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
 	  tid = UP2AC(tid);
 	  tid ++;
 	} else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
-	  hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
-	  tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
 	  tid = UP2AC(tid);
 	  tid ++;
 	} else { // no QoS
@@ -519,16 +435,6 @@ static int is_duplicate_packet(struct ieee80211_device *ieee,
 
 		break;
 	default:
-#ifdef _RTL8187_EXT_PATCH_
-		if(ieee->iw_mode == ieee->iw_ext_mode)
-		{
-			last_seq = &ieee->last_rxseq_num[tid];
-			last_frag = &ieee->last_rxfrag_num[tid];
-			last_time = &ieee->last_packet_time[tid];
-			break;
-		}
-		else
-#endif
 		return 0;
 	}
 
@@ -569,8 +475,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 {
 	struct net_device *dev = ieee->dev;
 	//struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct ieee80211_hdr *hdr;
-	//struct ieee80211_hdr_3addr_QOS *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	size_t hdrlen;
 	u16 fc, type, stype, sc;
@@ -578,28 +483,14 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	unsigned int frag;
 	u8 *payload;
 	u16 ethertype;
-#ifdef NOT_YET
-	struct net_device *wds = NULL;
-	struct sk_buff *skb2 = NULL;
-	struct net_device *wds = NULL;
-	int frame_authorized = 0;
-	int from_assoc_ap = 0;
-	void *sta = NULL;
-#endif
-//	u16 QOS_ctl = 0;
 	u8 dst[ETH_ALEN];
 	u8 src[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
 	struct ieee80211_crypt_data *crypt = NULL;
 	int keyidx = 0;
 
-	//Added for mesh by Lawrence.
-#ifdef _RTL8187_EXT_PATCH_
-	u8 status;
-	u32 flags;
-#endif
 	// cheat the the hdr type
-	hdr = (struct ieee80211_hdr *)skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	stats = &ieee->stats;
 
 	if (skb->len < 10) {
@@ -632,63 +523,21 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	}
 //YJ,add,080828,for keep alive,end
 
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
-	{
-		hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
-		if(skb->len < hdrlen)
-			goto rx_dropped;
-	}
-	else
-#endif
 	hdrlen = ieee80211_get_hdrlen(fc);
 
-#ifdef NOT_YET
-#if WIRELESS_EXT > 15
-	/* Put this code here so that we avoid duplicating it in all
-	 * Rx paths. - Jean II */
-#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
-	/* If spy monitoring on */
-	if (iface->spy_data.spy_number > 0) {
-		struct iw_quality wstats;
-		wstats.level = rx_stats->signal;
-		wstats.noise = rx_stats->noise;
-		wstats.updated = 6;	/* No qual value */
-		/* Update spy records */
-		wireless_spy_update(dev, hdr->addr2, &wstats);
-	}
-#endif /* IW_WIRELESS_SPY */
-#endif /* WIRELESS_EXT > 15 */
-	hostap_update_rx_stats(local->ap, hdr, rx_stats);
-#endif
 
-#if WIRELESS_EXT > 15
 	if (ieee->iw_mode == IW_MODE_MONITOR) {
 		ieee80211_monitor_rx(ieee, skb, rx_stats);
 		stats->rx_packets++;
 		stats->rx_bytes += skb->len;
 		return 1;
 	}
-#endif
+
 	if (ieee->host_decrypt) {
 		int idx = 0;
 		if (skb->len >= hdrlen + 3)
 			idx = skb->data[hdrlen + 3] >> 6;
 		crypt = ieee->crypt[idx];
-#ifdef NOT_YET
-		sta = NULL;
-
-		/* Use station specific key to override default keys if the
-		 * receiver address is a unicast address ("individual RA"). If
-		 * bcrx_sta_key parameter is set, station specific key is used
-		 * even with broad/multicast targets (this is against IEEE
-		 * 802.11, but makes it easier to use different keys with
-		 * stations that do not support WEP key mapping). */
-
-		if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
-			(void) hostap_handle_sta_crypto(local, hdr, &crypt,
-							&sta);
-#endif
 
 		/* allow NULL decrypt to indicate an station specific override
 		 * for default encryption */
@@ -712,47 +561,17 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	if (skb->len < IEEE80211_DATA_HDR3_LEN)
 		goto rx_dropped;
 
-#ifdef _RTL8187_EXT_PATCH_
-	if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire )
-		ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb );
-#endif
-
 	// if QoS enabled, should check the sequence for each of the AC
 	if (is_duplicate_packet(ieee, hdr))
 		goto rx_dropped;
 
 
 	if (type == IEEE80211_FTYPE_MGMT) {
-
-	#if 0
-		if ( stype == IEEE80211_STYPE_AUTH &&
-		    fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
-		    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
-		{
-			printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
-			       "from " MAC_FMT "\n", dev->name,
-			       MAC_ARG(hdr->addr2));
-			/* TODO: could inform hostapd about this so that it
-			 * could send auth failure report */
-			goto rx_dropped;
-		}
-	#endif
-
-
 		if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
 			goto rx_dropped;
 		else
 			goto rx_exit;
 	}
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
-	{
-		if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
-		{
-			goto rx_exit;
-		}
-	}
-#endif
 
 	/* Data frame - extract src/dst addresses */
 	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
@@ -780,55 +599,10 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		break;
 	}
 
-#ifdef NOT_YET
-	if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
-		goto rx_dropped;
-	if (wds) {
-		skb->dev = dev = wds;
-		stats = hostap_get_stats(dev);
-	}
-
-	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
-	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
-	    ieee->stadev &&
-	    memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
-		/* Frame from BSSID of the AP for which we are a client */
-		skb->dev = dev = ieee->stadev;
-		stats = hostap_get_stats(dev);
-		from_assoc_ap = 1;
-	}
-#endif
 
 	dev->last_rx = jiffies;
 
-#ifdef NOT_YET
-	if ((ieee->iw_mode == IW_MODE_MASTER ||
-	     ieee->iw_mode == IW_MODE_REPEAT) &&
-	    !from_assoc_ap) {
-		switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
-					     wds != NULL)) {
-		case AP_RX_CONTINUE_NOT_AUTHORIZED:
-			frame_authorized = 0;
-			break;
-		case AP_RX_CONTINUE:
-			frame_authorized = 1;
-			break;
-		case AP_RX_DROP:
-			goto rx_dropped;
-		case AP_RX_EXIT:
-			goto rx_exit;
-		}
-	}
-#endif
 
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
-	{
-		if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
-			goto rx_dropped;
-	}
-	else
-#endif
 	/* Nullfunc frames may have PS-bit set, so they must be passed to
 	 * hostap_handle_sta_rx() before being dropped here. */
 	if (stype != IEEE80211_STYPE_DATA &&
@@ -857,7 +631,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
 		goto rx_dropped;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 
 	/* skb: hdr + (possibly fragmented) plaintext payload */
 	// PR: FIXME: hostap has additional conditions in the "if" below:
@@ -910,7 +684,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		/* this was the last fragment and the frame will be
 		 * delivered, so remove skb from fragment cache */
 		skb = frag_skb;
-		hdr = (struct ieee80211_hdr *) skb->data;
+		hdr = (struct ieee80211_hdr_4addr *)skb->data;
 		ieee80211_frag_cache_invalidate(ieee, hdr);
 	}
 
@@ -920,7 +694,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	    ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
 		goto rx_dropped;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
 	if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
 		if (/*ieee->ieee802_1x &&*/
 		    ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
@@ -970,47 +744,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	payload = skb->data + hdrlen;
 	ethertype = (payload[6] << 8) | payload[7];
 
-#ifdef NOT_YET
-	/* If IEEE 802.1X is used, check whether the port is authorized to send
-	 * the received frame. */
-	if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
-		if (ethertype == ETH_P_PAE) {
-			printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
-			       dev->name);
-			if (ieee->hostapd && ieee->apdev) {
-				/* Send IEEE 802.1X frames to the user
-				 * space daemon for processing */
-				prism2_rx_80211(ieee->apdev, skb, rx_stats,
-						PRISM2_RX_MGMT);
-				ieee->apdevstats.rx_packets++;
-				ieee->apdevstats.rx_bytes += skb->len;
-				goto rx_exit;
-			}
-		} else if (!frame_authorized) {
-			printk(KERN_DEBUG "%s: dropped frame from "
-			       "unauthorized port (IEEE 802.1X): "
-			       "ethertype=0x%04x\n",
-			       dev->name, ethertype);
-			goto rx_dropped;
-		}
-	}
-#endif
-
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
-	{
-	//Added for mesh rx interrupt.
-		//spin_lock_irqsave(&ieee->lock,flags);
-		status = ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats);
-		//spin_unlock_irqrestore(&ieee->lock,flags);
-
-		if(status)
-//	if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
-			goto rx_exit;
-		else
-			goto rx_dropped;
-	}
-#endif
 
 	/* convert hdr + possible LLC headers into Ethernet header */
 	if (skb->len - hdrlen >= 8 &&
@@ -1032,51 +765,10 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
 	}
 
-#ifdef NOT_YET
-	if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
-		    IEEE80211_FCTL_TODS) &&
-	    skb->len >= ETH_HLEN + ETH_ALEN) {
-		/* Non-standard frame: get addr4 from its bogus location after
-		 * the payload */
-		memcpy(skb->data + ETH_ALEN,
-		       skb->data + skb->len - ETH_ALEN, ETH_ALEN);
-		skb_trim(skb, skb->len - ETH_ALEN);
-	}
-#endif
 
 	stats->rx_packets++;
 	stats->rx_bytes += skb->len;
 
-#ifdef NOT_YET
-	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
-	    ieee->ap->bridge_packets) {
-		if (dst[0] & 0x01) {
-			/* copy multicast frame both to the higher layers and
-			 * to the wireless media */
-			ieee->ap->bridged_multicast++;
-			skb2 = skb_clone(skb, GFP_ATOMIC);
-			if (skb2 == NULL)
-				printk(KERN_DEBUG "%s: skb_clone failed for "
-				       "multicast frame\n", dev->name);
-		} else if (hostap_is_sta_assoc(ieee->ap, dst)) {
-			/* send frame directly to the associated STA using
-			 * wireless media and not passing to higher layers */
-			ieee->ap->bridged_unicast++;
-			skb2 = skb;
-			skb = NULL;
-		}
-	}
-
-	if (skb2 != NULL) {
-		/* send to wireless media */
-		skb2->protocol = __constant_htons(ETH_P_802_3);
-		skb2->mac.raw = skb2->nh.raw = skb2->data;
-		/* skb2->nh.raw = skb2->data + ETH_HLEN; */
-		skb2->dev = dev;
-		dev_queue_xmit(skb2);
-	}
-
-#endif
 	if (skb) {
 		skb->protocol = eth_type_trans(skb, dev);
 		memset(skb->cb, 0, sizeof(skb->cb));
@@ -1087,10 +779,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	}
 
  rx_exit:
-#ifdef NOT_YET
-	if (sta)
-		hostap_handle_sta_release(sta);
-#endif
 	return 1;
 
  rx_dropped:
@@ -1102,41 +790,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	return 0;
 }
 
-#ifdef _RTL8187_EXT_PATCH_
-int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
-{
-	u8 *payload;
-	u16 ethertype;
-
-	/* skb: hdr + (possible reassembled) full plaintext payload */
-	payload = skb->data + hdrlen;
-	ethertype = (payload[6] << 8) | payload[7];
-
-	/* convert hdr + possible LLC headers into Ethernet header */
-	if (skb->len - hdrlen >= 8 &&
-	    ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
-	      ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-	     memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
-		/* remove RFC1042 or Bridge-Tunnel encapsulation and
-		 * replace EtherType */
-		skb_pull(skb, hdrlen + SNAP_SIZE);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	} else {
-		u16 len;
-		/* Leave Ethernet header part of hdr and full payload */
-		skb_pull(skb, hdrlen);
-		len = htons(skb->len);
-		memcpy(skb_push(skb, 2), &len, 2);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	}
-
-	return 1;
-}
-#endif // _RTL8187_EXT_PATCH_
-
-
 #define MGMT_FRAME_FIXED_PART_LENGTH		0x24
 
 static inline int ieee80211_is_ofdm_rate(u8 rate)
@@ -1211,7 +864,6 @@ static inline int ieee80211_SignalStrengthTranslate(
 	return RetSS;
 }
 
-#ifdef ENABLE_DOT11D
 static inline void ieee80211_extract_country_ie(
 	struct ieee80211_device *ieee,
 	struct ieee80211_info_element *info_element,
@@ -1219,15 +871,6 @@ static inline void ieee80211_extract_country_ie(
 	u8 * addr2
 )
 {
-#if 0
-	u32 i = 0;
-	u8 * p = (u8*)info_element->data;
-	printk("-----------------------\n");
-	printk("%s Country IE:", network->ssid);
-	for(i=0; i<info_element->len; i++)
-		printk("\t%2.2x", *(p+i));
-	printk("\n-----------------------\n");
-#endif
 	if(IS_DOT11D_ENABLE(ieee))
 	{
 		if(info_element->len!= 0)
@@ -1253,7 +896,6 @@ static inline void ieee80211_extract_country_ie(
 	}
 
 }
-#endif
 
 int
 ieee80211_TranslateToDbm(
@@ -1302,13 +944,9 @@ inline int ieee80211_network_init(
 //by amy 080312
 	network->HighestOperaRate = 0;
 //by amy 080312
-#ifdef THOMAS_TURBO
 	network->Turbo_Enable = 0;
-#endif
-#ifdef ENABLE_DOT11D
 	network->CountryIeLen = 0;
 	memset(network->CountryIeBuf, 0, MAX_IE_LEN);
-#endif
 
 	if (stats->freq == IEEE80211_52GHZ_BAND) {
 		/* for A band (No DS info) */
@@ -1424,11 +1062,8 @@ inline int ieee80211_network_init(
 
 			if(ieee->state != IEEE80211_LINKED)
 				break;
-#if 0
-			network->last_dtim_sta_time[0] = stats->mac_time[0];
-#else
+
 			network->last_dtim_sta_time[0] = jiffies;
-#endif
 			network->last_dtim_sta_time[1] = stats->mac_time[1];
 
 			network->dtim_data = IEEE80211_DTIM_VALID;
@@ -1483,7 +1118,6 @@ inline int ieee80211_network_init(
 				       network->wpa_ie_len);
 			}
 
-#ifdef THOMAS_TURBO
 			if (info_element->len == 7 &&
 			    info_element->data[0] == 0x00 &&
 			    info_element->data[1] == 0xe0 &&
@@ -1492,7 +1126,6 @@ inline int ieee80211_network_init(
 			    info_element->data[4] == 0x02) {
 				network->Turbo_Enable = 1;
 			}
-#endif
 			if (1 == stats->nic_type) {//nic 87
 				break;
 			}
@@ -1533,14 +1166,12 @@ inline int ieee80211_network_init(
 			memcpy(network->rsn_ie, info_element,
 			       network->rsn_ie_len);
 			break;
-#ifdef ENABLE_DOT11D
 		case MFIE_TYPE_COUNTRY:
 			IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
 					     info_element->len);
 //			printk("=====>Receive <%s> Country IE\n",network->ssid);
 			ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
 			break;
-#endif
 		default:
 			IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
 					     info_element->id);
@@ -1576,9 +1207,7 @@ inline int ieee80211_network_init(
 
 	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
 		network->flags |= NETWORK_EMPTY_ESSID;
-#if 0
-	stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
-#endif
+
 	stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
 	//stats->noise = stats->signal - stats->noise;
 	stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
@@ -1688,13 +1317,9 @@ inline void update_network(struct ieee80211_network *dst,
 	dst->QoS_Enable = 1;//for Rtl8187 simulation
 #endif
 	dst->SignalStrength = src->SignalStrength;
-#ifdef THOMAS_TURBO
 	dst->Turbo_Enable = src->Turbo_Enable;
-#endif
-#ifdef ENABLE_DOT11D
 	dst->CountryIeLen = src->CountryIeLen;
 	memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
-#endif
 }
 
 
@@ -1715,13 +1340,6 @@ inline void ieee80211_process_probe_response(
 	u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0;  //YJ,add,080819,for hidden ap
 
 	memset(&network, 0, sizeof(struct ieee80211_network));
-//rz
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) {
-		ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats);
-		return;
-	}
-#endif
 
 	IEEE80211_DEBUG_SCAN(
 		"'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
@@ -1743,21 +1361,7 @@ inline void ieee80211_process_probe_response(
 		(beacon->capability & (1<<0x2)) ? '1' : '0',
 		(beacon->capability & (1<<0x1)) ? '1' : '0',
 		(beacon->capability & (1<<0x0)) ? '1' : '0');
-#if 0
-	if(strcmp(escape_essid(beacon->info_element.data, beacon->info_element.len), "rtl_softap") == 0)
-	{
-		if(WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)
-		{
-			u32 i = 0, len = stats->len;
-			u8 * p = (u8*)beacon;
-			printk("-----------------------\n");
-			printk("rtl_softap Beacon:");
-			for(i=0; i<len; i++)
-				printk("\t%2.2x", *(p+i));
-			printk("\n-----------------------\n");
-		}
-	}
-#endif
+
 	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
 		IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
 				     escape_essid(info_element->data,
@@ -1769,7 +1373,6 @@ inline void ieee80211_process_probe_response(
 		return;
 	}
 
-#ifdef ENABLE_DOT11D
 	// For Asus EeePc request,
 	// (1) if wireless adapter receive get any 802.11d country code in AP beacon,
 	//	   wireless adapter should follow the country code.
@@ -1823,7 +1426,6 @@ inline void ieee80211_process_probe_response(
 			}
 		}
 	}
-#endif
 	/* The network parsed correctly -- so now we scan our known networks
 	 * to see if we can find it in our list.
 	 *
@@ -1886,9 +1488,6 @@ inline void ieee80211_process_probe_response(
 				     "PROBE RESPONSE" : "BEACON");
 #endif
 
-#ifdef _RTL8187_EXT_PATCH_
-	network.ext_entry = target->ext_entry;
-#endif
 		memcpy(target, &network, sizeof(*target));
 		list_add_tail(&target->list, &ieee->network_list);
 		if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
@@ -1926,7 +1525,7 @@ inline void ieee80211_process_probe_response(
 }
 
 void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-		      struct ieee80211_hdr *header,
+		      struct ieee80211_hdr_4addr *header,
 		      struct ieee80211_rx_stats *stats)
 {
 	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
@@ -1946,26 +1545,5 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
 		ieee80211_process_probe_response(
 			ieee, (struct ieee80211_probe_response *)header, stats);
 		break;
-//rz
-#ifdef _RTL8187_EXT_PATCH_
-	case IEEE80211_STYPE_PROBE_REQ:
-		IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n",
-				     WLAN_FC_GET_STYPE(header->frame_ctl));
-		IEEE80211_DEBUG_SCAN("Probe request\n");
-		///
-		if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req )
-			ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats);
-		break;
-#endif // _RTL8187_EXT_PATCH_
-
 	}
 }
-
-#if 0
-EXPORT_SYMBOL(ieee80211_rx_mgt);
-EXPORT_SYMBOL(ieee80211_rx);
-EXPORT_SYMBOL(ieee80211_network_init);
-#ifdef _RTL8187_EXT_PATCH_
-EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether);
-#endif
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index 80f9cc7..59b2ab4 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -21,9 +21,7 @@
 #include <linux/version.h>
 #include <asm/uaccess.h>
 
-#ifdef ENABLE_DOT11D
 #include "dot11d.h"
-#endif
 u8 rsn_authen_cipher_suite[16][4] = {
 	{0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
 	{0x00,0x0F,0xAC,0x01}, //WEP-40         //RSNA default
@@ -129,7 +127,6 @@ void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
 	*tag_p = tag;
 }
 
-#ifdef THOMAS_TURBO
 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
 	u8 *tag = *tag_p;
 
@@ -146,7 +143,6 @@ void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
 	*tag_p = tag;
 	printk(KERN_ALERT "This is enable turbo mode IE process\n");
 }
-#endif
 
 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
@@ -325,27 +321,12 @@ inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
 	struct sk_buff *skb;
 	struct ieee80211_probe_request *req;
 
-#ifdef _RTL8187_EXT_PATCH_
-	short extMore = 0;
-	if(ieee->ext_patch_ieee80211_probe_req_1)
-		extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
-#endif
-
 	len = ieee->current_network.ssid_len;
 
 	rate_len = ieee80211_MFIE_rate_len(ieee);
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(!extMore)
-#endif
 	skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
 			    2 + len + rate_len);
-#ifdef _RTL8187_EXT_PATCH_
-	else
-		skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
-			    2 + len + rate_len+128); // MESHID + CAP
-#endif
-
 	if (!skb)
 		return NULL;
 
@@ -366,24 +347,13 @@ inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
 	ieee80211_MFIE_Brate(ieee,&tag);
 	ieee80211_MFIE_Grate(ieee,&tag);
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(extMore)
-		ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
-#endif
 	return skb;
 }
 
 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
 
-//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-//void ext_ieee80211_send_beacon_wq(struct work_struct *work)
-//{
-//	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
-//#else
 void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
 {
-//#endif
-
 	struct sk_buff *skb;
 
 	//unsigned long flags;
@@ -443,79 +413,10 @@ void ieee80211_send_beacon_cb(unsigned long _ieee)
 	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
 }
 
-#ifdef _RTL8187_EXT_PATCH_
-
-inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
-{
-	unsigned int len,rate_len;
-	u8 *tag;
-	struct sk_buff *skb;
-	struct ieee80211_probe_request *req;
-
-#ifdef _RTL8187_EXT_PATCH_
-	short extMore = 0;
-	if(ieee->ext_patch_ieee80211_probe_req_1)
-		extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
-#endif
-
-	len = len_ssid;
-
-	rate_len = ieee80211_MFIE_rate_len(ieee);
-
-#ifdef _RTL8187_EXT_PATCH_
-	if(!extMore)
-#endif
-	skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
-			    2 + len + rate_len);
-#ifdef _RTL8187_EXT_PATCH_
-	else
-		skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
-			    2 + len + rate_len+128); // MESHID + CAP
-#endif
-
-	if (!skb)
-		return NULL;
-
-	req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
-	req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-	req->header.duration_id = 0; //FIXME: is this OK ?
-
-	memset(req->header.addr1, 0xff, ETH_ALEN);
-	memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memset(req->header.addr3, 0xff, ETH_ALEN);
-
-	tag = (u8 *) skb_put(skb,len+2+rate_len);
-
-	*tag++ = MFIE_TYPE_SSID;
-	*tag++ = len;
-	if(len)
-	{
-		memcpy(tag, ssid, len);
-		tag += len;
-	}
-
-	ieee80211_MFIE_Brate(ieee,&tag);
-	ieee80211_MFIE_Grate(ieee,&tag);
-
-#ifdef _RTL8187_EXT_PATCH_
-	if(extMore)
-		ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
-#endif
-	return skb;
-}
-
-#endif // _RTL8187_EXT_PATCH_
-
-
 void ieee80211_send_probe(struct ieee80211_device *ieee)
 {
 	struct sk_buff *skb;
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->iw_mode == ieee->iw_ext_mode)
-		skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
-	else
-#endif
 	skb = ieee80211_probe_req(ieee);
 	if (skb){
 		softmac_mgmt_xmit(skb, ieee);
@@ -538,13 +439,10 @@ void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 {
 	short ch = 0;
-#ifdef ENABLE_DOT11D
 	u8 channel_map[MAX_CHANNEL_NUMBER+1];
 	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-#endif
 	down(&ieee->scan_sem);
 //	printk("==================> Sync scan\n");
-//	dump_chnl_map(channel_map);
 
 	while(1)
 	{
@@ -554,11 +452,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 			if (ch > MAX_CHANNEL_NUMBER)
 				goto out; /* scan completed */
 
-#ifdef ENABLE_DOT11D
 		}while(!channel_map[ch]);
-#else
-		}while(!ieee->channel_map[ch]);
-#endif
 		/* this fuction can be called in two situations
 		 * 1- We have switched to ad-hoc mode and we are
 		 *    performing a complete syncro scan before conclude
@@ -583,9 +477,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 
 		ieee->set_chan(ieee->dev, ch);
 //		printk("=====>channel=%d   ",ch);
-#ifdef ENABLE_DOT11D
 		if(channel_map[ch] == 1)
-#endif
 		{
 //			printk("====send probe request\n");
 			ieee80211_send_probe_requests(ieee);
@@ -603,20 +495,16 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 out:
 	ieee->sync_scan_hurryup = 0;
 	up(&ieee->scan_sem);
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee))
 		DOT11D_ScanComplete(ieee);
-#endif
 }
 
 void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
 {
 	int ch;
         unsigned int watch_dog = 0;
-#ifdef ENABLE_DOT11D
 	u8 channel_map[MAX_CHANNEL_NUMBER+1];
 	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-#endif
         down(&ieee->scan_sem);
 	ch = ieee->current_network.channel;
 //      	if(ieee->sync_scan_hurryup)
@@ -650,16 +538,12 @@ void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
 		{
 			goto out;
 		}
-#ifdef ENABLE_DOT11D
 		if(channel_map[ieee->current_network.channel] > 0)
-#endif
 		{
 			ieee->set_chan(ieee->dev, ieee->current_network.channel);
 //			printk("======>channel=%d  ",ieee->current_network.channel);
 		}
-#ifdef ENABLE_DOT11D
 		if(channel_map[ieee->current_network.channel] == 1)
-#endif
 		{
 //			printk("====send probe request\n");
 			ieee80211_send_probe_requests(ieee);
@@ -678,11 +562,7 @@ void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
 				goto out; /* scan completed */
 
 			ieee->current_network.channel = (ieee->current_network.channel + 1)%MAX_CHANNEL_NUMBER;
-#ifdef ENABLE_DOT11D
 		}while(!channel_map[ieee->current_network.channel]);
-#else
-		}while(!ieee->channel_map[ieee->current_network.channel]);
-#endif
         }
 out:
 	//ieee->sync_scan_hurryup = 0;
@@ -690,46 +570,17 @@ out:
    	//ieee->current_network.channel = ch;
 	ieee->actscanning = false;
 	up(&ieee->scan_sem);
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee))
 		DOT11D_ScanComplete(ieee);
-#endif
 }
 
-
-#if 0
-/* called both by wq with ieee->lock held */
-void ieee80211_softmac_scan(struct ieee80211_device *ieee)
-{
-	short watchdog = 0;
-
-	do{
-		ieee->current_network.channel =
-			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
-		if (watchdog++ > MAX_CHANNEL_NUMBER)
-				return; /* no good chans */
-
-	}while(!ieee->channel_map[ieee->current_network.channel]);
-
-
-	schedule_work(&ieee->softmac_scan_wq);
-}
-#endif
-#ifdef ENABLE_IPS
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_softmac_scan_wq(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
-#else
-void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
 	static short watchdog = 0;
-#ifdef ENABLE_DOT11D
 	u8 channel_map[MAX_CHANNEL_NUMBER+1];
 	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-#endif
 //	printk("ieee80211_softmac_scan_wq ENABLE_IPS\n");
 //	printk("in %s\n",__func__);
 	down(&ieee->scan_sem);
@@ -740,11 +591,7 @@ void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
 		if (watchdog++ > MAX_CHANNEL_NUMBER)
 				goto out; /* no good chans */
 
-#ifdef ENABLE_DOT11D
  	}while(!channel_map[ieee->current_network.channel]);
-#else
- 	}while(!ieee->channel_map[ieee->current_network.channel]);
-#endif
 
 	//printk("current_network.channel:%d\n", ieee->current_network.channel);
 	if (ieee->scanning == 0 )
@@ -753,9 +600,7 @@ void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
 		goto out;
 	}
 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-#ifdef ENABLE_DOT11D
 	if(channel_map[ieee->current_network.channel] == 1)
-#endif
 		ieee80211_send_probe_requests(ieee);
 
 	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
@@ -767,77 +612,10 @@ out:
 	ieee->scanning = 0;
 	up(&ieee->scan_sem);
 
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee))
 		DOT11D_ScanComplete(ieee);
-#endif
 	return;
 }
-#else
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void ieee80211_softmac_scan_wq(struct work_struct *work)
-{
-	struct delayed_work *dwork = to_delayed_work(work);
-        struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, softmac_scan_wq);
-#else
-void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
-
-        short watchdog = 0;
-#ifdef ENABLE_DOT11D
-	u8 channel_map[MAX_CHANNEL_NUMBER+1];
-	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-#endif
-//      printk("enter scan wq,watchdog is %d\n",watchdog);
-        down(&ieee->scan_sem);
-
-        do{
-                ieee->current_network.channel =
-                        (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
-                if (watchdog++ > MAX_CHANNEL_NUMBER)
-                                goto out; /* no good chans */
-
-#ifdef ENABLE_DOT11D
-        }while(!channel_map[ieee->current_network.channel]);
-#else
-        }while(!ieee->channel_map[ieee->current_network.channel]);
-#endif
-
-//      printk("current_network.channel:%d\n", ieee->current_network.channel);
-        if (ieee->scanning == 0 )
-        {
-                printk("error out, scanning = 0\n");
-                goto out;
-        }
-        ieee->set_chan(ieee->dev, ieee->current_network.channel);
-#ifdef ENABLE_DOT11D
-	if(channel_map[ieee->current_network.channel] == 1)
-#endif
-		ieee80211_send_probe_requests(ieee);
-
-	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
-out:
-	up(&ieee->scan_sem);
-#ifdef ENABLE_DOT11D
-	if(IS_DOT11D_ENABLE(ieee))
-		DOT11D_ScanComplete(ieee);
-#endif
-}
-
-#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-void ieee80211_softmac_scan_cb(unsigned long _dev)
-{
-	unsigned long flags;
-	struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	ieee80211_softmac_scan(ieee);
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-#endif
-
 
 void ieee80211_beacons_start(struct ieee80211_device *ieee)
 {
@@ -913,7 +691,6 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
 /* called with ieee->lock held */
 void ieee80211_start_scan(struct ieee80211_device *ieee)
 {
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee) )
 	{
 		if(IS_COUNTRY_IE_VALID(ieee))
@@ -921,7 +698,6 @@ void ieee80211_start_scan(struct ieee80211_device *ieee)
 			RESET_CIE_WATCHDOG(ieee);
 		}
 	}
-#endif
 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
 		if (ieee->scanning == 0)
 		{
@@ -941,7 +717,6 @@ void ieee80211_start_scan(struct ieee80211_device *ieee)
 /* called with wx_sem held */
 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
 {
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee) )
 	{
 		if(IS_COUNTRY_IE_VALID(ieee))
@@ -949,7 +724,6 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
 			RESET_CIE_WATCHDOG(ieee);
 		}
 	}
-#endif
 	ieee->sync_scan_hurryup = 0;
 
 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
@@ -1110,138 +884,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
 	skb->dev = ieee->dev;
 	return skb;
 }
-#ifdef _RTL8187_EXT_PATCH_
-struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net)
-{
-	u8 *tag;
-	int beacon_size;
-	struct ieee80211_probe_response *beacon_buf;
-	struct sk_buff *skb;
-	int encrypt;
-	int atim_len,erp_len;
-	struct ieee80211_crypt_data* crypt;
-	u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
-	int wpa_ie_len = ieee->wpa_ie_len;
-	char *ssid = net->ssid;
-	int ssid_len = net->ssid_len;
-
-	int rate_len = ieee->current_network.rates_len+2;
-	int rate_ex_len = ieee->current_network.rates_ex_len;
-	if(rate_ex_len > 0) rate_ex_len+=2;
-
-	if( ieee->meshScanMode&4)
-		ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
-	if( ieee->meshScanMode&6)
-	{
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-		queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
-#else
-		schedule_task(&ieee->ext_stop_scan_wq);
-#endif
-	}
-	if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
-		atim_len = 4;
-	else
-		atim_len = 0;
-
-	if(ieee80211_is_54g(*net))
-		erp_len = 3;
-	else
-		erp_len = 0;
-
-	beacon_size = sizeof(struct ieee80211_probe_response)+
-		ssid_len
-		+3 //channel
-		+rate_len
-		+rate_ex_len
-		+atim_len
-		+erp_len;
-//b
-	skb = dev_alloc_skb(beacon_size+196);
-
-	if (!skb)
- 		return NULL;
-
-	beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
-
-	memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
-	memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
-
-	beacon_buf->header.duration_id = 0; //FIXME
-
-	beacon_buf->beacon_interval =
-		cpu_to_le16(ieee->current_network.beacon_interval);  // use current_network here
-	beacon_buf->capability =
-		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
-
-	if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
-		cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
-
-	crypt = ieee->crypt[ieee->tx_keyidx];
-
-	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
-		((0 == strcmp(crypt->ops->name, "WEP"))||wpa_ie_len);
-
-	if (encrypt)
-		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
-
-	beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
-
-	beacon_buf->info_element.id = MFIE_TYPE_SSID;
-	beacon_buf->info_element.len = ssid_len;
-
-	tag = (u8*) beacon_buf->info_element.data;
-
-	// brocad cast / probe rsp
-	if(memcmp(dest, broadcast_addr, ETH_ALEN ))
-		memcpy(tag, ssid, ssid_len);
-	else
-		ssid_len=0;
-
-	tag += ssid_len;
-
-//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
-//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
-
-	*(tag++) = MFIE_TYPE_RATES;
-	*(tag++) = rate_len-2;
-	memcpy(tag,ieee->current_network.rates,rate_len-2);
-	tag+=rate_len-2;
-
-	*(tag++) = MFIE_TYPE_DS_SET;
-	*(tag++) = 1;
-	*(tag++) = ieee->current_network.channel;  // use current_network here
-
-
-	if(atim_len){
-		*(tag++) = MFIE_TYPE_IBSS_SET;
-		*(tag++) = 2;
-		*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
-		tag+=2;
-	}
-
-	if(erp_len){
-		*(tag++) = MFIE_TYPE_ERP;
-		*(tag++) = 1;
-		*(tag++) = 0;
-	}
-
-	if(rate_ex_len){
-		*(tag++) = MFIE_TYPE_RATES_EX;
-		*(tag++) = rate_ex_len-2;
-		memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
-		tag+=rate_ex_len-2;
-	}
-	if (wpa_ie_len)
-		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
-
-	skb->dev = ieee->dev;
-	return skb;
-}
-#endif // _RTL8187_EXT_PATCH_
 
 struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
 {
@@ -1314,12 +956,7 @@ struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8
 	auth->transaction = cpu_to_le16(2);
 	auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->iw_mode == ieee->iw_ext_mode)
-		memcpy(auth->header.addr3, dest, ETH_ALEN);
-#else
 	memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
-#endif
 	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
 	memcpy(auth->header.addr1, dest, ETH_ALEN);
 	auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
@@ -1412,9 +1049,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 #endif
 	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
 	unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
-#ifdef THOMAS_TURBO
 	unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
-#endif
 
 	u8  encry_proto = ieee->wpax_type_notify & 0xff;
 	//u8  pairwise_type = (ieee->wpax_type_notify >> 8) & 0xff;
@@ -1432,7 +1067,6 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 			wpa_len = 0;
 		}
 	}
-#ifdef THOMAS_TURBO
 	len = sizeof(struct ieee80211_assoc_request_frame)+
 		+ beacon->ssid_len//essid tagged val
 		+ rate_len//rates tagged val
@@ -1440,20 +1074,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 		+ rsn_len
 		+ wmm_info_len
 		+ turbo_info_len;
-#else
-	len = sizeof(struct ieee80211_assoc_request_frame)+
-		+ beacon->ssid_len//essid tagged val
-		+ rate_len//rates tagged val
-		+ wpa_len
-		+ rsn_len
-		+ wmm_info_len;
-#endif
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->iw_mode == ieee->iw_ext_mode)
-		skb = dev_alloc_skb(len+256); // stanley
-	else
-#endif
 	skb = dev_alloc_skb(len);
 
 	if (!skb)
@@ -1479,11 +1100,6 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 	if(ieee->short_slot)
 		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
 
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1)
-		ieee->ext_patch_ieee80211_association_req_1(hdr);
-#endif
-
 	hdr->listen_interval = 0xa; //FIXME
 
 	hdr->info_element.id = MFIE_TYPE_SSID;
@@ -1499,221 +1115,18 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 
 	//add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
 	//choose AES encryption as default algorithm while using mixed mode
-#if 0
-	if(rsn_len == 0){
-
-		tag = skb_put(skb,wpa_len);
-
-		if(wpa_len) {
 
-
-		  //{add by david. 2006.8.31
-		  //fix linksys compatibility bug
-		  //}
-		  if(wpa_len > 24) {//22+2, mean include the capability
-			beacon->wpa_ie[wpa_len - 2] = 0;
-		  }
-		//multicast cipher OUI
-                  if(  beacon->wpa_ie[11]==0x2      ){ //0x0050f202 is the oui of tkip
-                  ieee->broadcast_key_type = KEY_TYPE_TKIP;
-                }
-                  else if(  beacon->wpa_ie[11]==0x4      ){//0x0050f204 is the oui of ccmp
-                  ieee->broadcast_key_type = KEY_TYPE_CCMP;
-                }
- 		//unicast cipher OUI
-		  if(	beacon->wpa_ie[14]==0
-			&& beacon->wpa_ie[15]==0x50
-                        && beacon->wpa_ie[16]==0xf2
-                        && beacon->wpa_ie[17]==0x2  	){ //0x0050f202 is the oui of tkip
-                  ieee->pairwise_key_type = KEY_TYPE_TKIP;
-		}
-
-                  else if(   beacon->wpa_ie[14]==0
-                        && beacon->wpa_ie[15]==0x50
-                        && beacon->wpa_ie[16]==0xf2
-                        && beacon->wpa_ie[17]==0x4      ){//0x0050f204 is the oui of ccmp
-                  ieee->pairwise_key_type = KEY_TYPE_CCMP;
-		}
-		//indicate the wpa_ie content to WPA_SUPPLICANT
-		buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
-		memset(buff, 0, IW_CUSTOM_MAX);
-		p=buff;
-		p += sprintf(p, "ASSOCINFO(ReqIEs=");
-		for(i=0;i<wpa_len;i++){
-			p += sprintf(p, "%02x", beacon->wpa_ie[i]);
-		}
-		p += sprintf(p, ")");
-		memset(&wrqu, 0, sizeof(wrqu) );
-		wrqu.data.length = p - buff;
-
-		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
-		  memcpy(tag,beacon->wpa_ie,wpa_len);
-		}
-
-	}
-
-	if(rsn_len > 22) {
-
-	  					if(     beacon->rsn_ie[4]==0x0 &&
-                                beacon->rsn_ie[5]==0xf &&
-                                beacon->rsn_ie[6]==0xac){
-
-                                switch(beacon->rsn_ie[7]){
-                                        case 0x1:
-                                                ieee->broadcast_key_type = KEY_TYPE_WEP40;
-                                                break;
-                                        case 0x2:
-                                                ieee->broadcast_key_type = KEY_TYPE_TKIP;
-                                                break;
-                                        case 0x4:
-                                                ieee->broadcast_key_type = KEY_TYPE_CCMP;
-                                                break;
-                                        case 0x5:
-                                                ieee->broadcast_key_type = KEY_TYPE_WEP104;
-                                                break;
-                                        default:
-                                                printk("fault suite type in RSN broadcast key\n");
-                                                break;
-                                }
-                        }
-
-                        if(     beacon->rsn_ie[10]==0x0 &&
-                                beacon->rsn_ie[11]==0xf &&
-                                beacon->rsn_ie[12]==0xac){
-				if(beacon->rsn_ie[8]==1){//not mixed mode
-	                                switch(beacon->rsn_ie[13]){
-        	                                case 0x2:
-                	                                ieee->pairwise_key_type = KEY_TYPE_TKIP;
-                        	                        break;
-                                	        case 0x4:
-                                        	        ieee->pairwise_key_type = KEY_TYPE_CCMP;
-                                                	break;
-        	                                default:
-	                                                printk("fault suite type in RSN pairwise key\n");
-                	                                break;
-                                	}
-				}
-				else if(beacon->rsn_ie[8]==2){//mixed mode
-					ieee->pairwise_key_type = KEY_TYPE_CCMP;
-				}
-                        }
-
-
-
-		tag = skb_put(skb,22);
-		memcpy(tag,(beacon->rsn_ie + info_addr),8);
-		tag[1] =  20;
-		tag += 8;
-		info_addr += 8;
-
-		spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
-		for (i = 0; i < 2; i++) {
-			tag[0] = 1;
-			tag[1] = 0;
-			tag += 2;
-			suite_count = beacon->rsn_ie[info_addr] + \
-				      (beacon->rsn_ie[info_addr + 1] << 8);
-			info_addr += 2;
-			if(1 == suite_count) {
-				memcpy(tag,(beacon->rsn_ie + info_addr),4);
-				info_addr += 4;
-			} else {
-				// if the wpax_type_notify has been set by the application,
-				// just use it, otherwise just use the default one.
-				if(ieee->wpax_type_set) {
-					suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ;
-					memcpy(tag,rsn_authen_cipher_suite[suit_select],4);
-				} else {
-					//default set as ccmp, or none authentication
-					if(i == 0) {
-						memcpy(tag,rsn_authen_cipher_suite[4],4);
-					} else {
-						memcpy(tag,rsn_authen_cipher_suite[2],4);
-					}
-
-				}
-
-				info_addr += (suite_count * 4);
-			}
-			tag += 4;
-		}
-		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
-
-		tag[0] = 0;
-		tag[1] = beacon->rsn_ie[info_addr+1];
-
-	} else {
-		tag = skb_put(skb,rsn_len);
-		if(rsn_len) {
-
-
-			if( 	beacon->rsn_ie[4]==0x0 &&
-				beacon->rsn_ie[5]==0xf &&
-				beacon->rsn_ie[6]==0xac){
-				switch(beacon->rsn_ie[7]){
-					case 0x1:
-						ieee->broadcast_key_type = KEY_TYPE_WEP40;
-                                                break;
-					case 0x2:
-						ieee->broadcast_key_type = KEY_TYPE_TKIP;
-						break;
-					case 0x4:
-   	                                        ieee->broadcast_key_type = KEY_TYPE_CCMP;
-                                                break;
-                                        case 0x5:
-                                                ieee->broadcast_key_type = KEY_TYPE_WEP104;
-                                                break;
-					default:
-						printk("fault suite type in RSN broadcast key\n");
-						break;
-				}
-			}
-                        if(     beacon->rsn_ie[10]==0x0 &&
-                                beacon->rsn_ie[11]==0xf &&
-                                beacon->rsn_ie[12]==0xac){
-                                if(beacon->rsn_ie[8]==1){//not mixed mode
-                                        switch(beacon->rsn_ie[13]){
-                                                case 0x2:
-                                                        ieee->pairwise_key_type = KEY_TYPE_TKIP;
-                                                        break;
-                                                case 0x4:
-                                                        ieee->pairwise_key_type = KEY_TYPE_CCMP;
-                                                        break;
-                                                default:
-                                                        printk("fault suite type in RSN pairwise key\n");
-                                                        break;
-                                	}
-
-				}
-                                else if(beacon->rsn_ie[8]==2){//mixed mode
-                                        ieee->pairwise_key_type = KEY_TYPE_CCMP;
-                                }
-                        }
-
-
-			beacon->rsn_ie[rsn_len - 2] = 0;
-			memcpy(tag,beacon->rsn_ie,rsn_len);
-		}
-	}
-#else
 	tag = skb_put(skb,ieee->wpa_ie_len);
 	memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
-#endif
+
 	tag = skb_put(skb,wmm_info_len);
 	if(wmm_info_len) {
 	  ieee80211_WMM_Info(ieee, &tag);
 	}
-#ifdef THOMAS_TURBO
 	tag = skb_put(skb,turbo_info_len);
         if(turbo_info_len) {
                 ieee80211_TURBO_Info(ieee, &tag);
         }
-#endif
-
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2)
-		ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb);
-#endif
 
 	return skb;
 }
@@ -1761,13 +1174,6 @@ void ieee80211_associate_step1(struct ieee80211_device *ieee)
 	IEEE80211_DEBUG_MGMT("Stopping scan\n");
 	ieee->softmac_stats.tx_auth_rq++;
 	skb=ieee80211_authentication_req(beacon, ieee, 0);
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->iw_mode == ieee->iw_ext_mode )	{
-		if(skb)
-			softmac_mgmt_xmit(skb, ieee);
-		return;
-	}else
-#endif
 	if (!skb){
 
 		ieee80211_associate_abort(ieee);
@@ -1824,105 +1230,6 @@ void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int
 	kfree(challenge);
 }
 
-#ifdef _RTL8187_EXT_PATCH_
-
-// based on ieee80211_assoc_resp
-struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
-{
-	struct sk_buff *skb;
-	u8* tag;
-
-	struct ieee80211_crypt_data* crypt;
-	struct ieee80211_assoc_response_frame *assoc;
-	short encrypt;
-
-	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
-	int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
-
-	if(ieee->iw_mode == ieee->iw_ext_mode)
-		skb = dev_alloc_skb(len+256); // stanley
-	else
-		skb = dev_alloc_skb(len);
-
-	if (!skb)
-		return NULL;
-
-	assoc = (struct ieee80211_assoc_response_frame *)
-		skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
-
-	assoc->header.frame_ctl = cpu_to_le16(pkt_type);
-
-	memcpy(assoc->header.addr1, dest,ETH_ALEN);
-	memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
-	memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
-	assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
-		WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
-
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1)
-		ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc);
-
-	if(ieee->short_slot)
-		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
-	if (ieee->host_encrypt)
-		crypt = ieee->crypt[ieee->tx_keyidx];
-	else crypt = NULL;
-
-	encrypt = ( crypt && crypt->ops);
-
-	if (encrypt)
-		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
-	assoc->status = 0;
-	assoc->aid = cpu_to_le16(ieee->assoc_id);
-	if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
-	else ieee->assoc_id++;
-
-	assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
-	assoc->info_element.len = 0;
-
-	tag = (u8*) skb_put(skb, rate_len);
-
-	ieee80211_MFIE_Brate(ieee, &tag);
-	ieee80211_MFIE_Grate(ieee, &tag);
-
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2)
-		ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb);
-
-	return skb;
-}
-
-// based on ieee80211_resp_to_assoc_rq
-void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
-{
-	struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
-
-	if (buf)
-		softmac_mgmt_xmit(buf, ieee);
-}
-
-// based on ieee80211_associate_step2
-void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
-{
-
-	struct sk_buff* skb;
-
-	// printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
-
-	ieee->softmac_stats.tx_ass_rq++;
-	skb=ieee80211_association_req(pstat, ieee);
-	if (skb)
-		softmac_mgmt_xmit(skb, ieee);
-}
-
-void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
-{
-	// do nothing
-	// printk("@@@@@ ieee80211_ext_issue_disassoc\n");
-	return;
-}
-#endif // _RTL8187_EXT_PATCH_
-
 void ieee80211_associate_step2(struct ieee80211_device *ieee)
 {
 	struct sk_buff* skb;
@@ -1945,14 +1252,10 @@ void ieee80211_associate_step2(struct ieee80211_device *ieee)
 	}
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_associate_complete_wq(struct work_struct *work)
 {
 	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
-#else
-void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
-{
-#endif
+
 	printk(KERN_INFO "Associated successfully\n");
 	if(ieee80211_is_54g(ieee->current_network) &&
 		(ieee->modulation & IEEE80211_OFDM_MODULATION)){
@@ -1984,14 +1287,10 @@ void ieee80211_associate_complete(struct ieee80211_device *ieee)
 	queue_work(ieee->wq, &ieee->associate_complete_wq);
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_associate_procedure_wq(struct work_struct *work)
 {
 	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
-#else
-void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
-{
-#endif
+
 	ieee->sync_scan_hurryup = 1;
 	down(&ieee->wx_sem);
 
@@ -2006,55 +1305,6 @@ void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
 
 	up(&ieee->wx_sem);
 }
-#ifdef _RTL8187_EXT_PATCH_
-// based on ieee80211_associate_procedure_wq
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-void ieee80211_ext_stop_scan_wq(struct work_struct *work)
-{
-	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
-#else
-void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
-	  if (ieee->scanning == 0)
-	{
-		if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
-				&& ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) )
-		return;
-	}
-
-	ieee->sync_scan_hurryup = 1;
-
-	down(&ieee->wx_sem);
-
-	// printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
-	if (ieee->data_hard_stop)
-		ieee->data_hard_stop(ieee->dev);
-
-	ieee80211_stop_scan(ieee);
-
-	// set channel
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel)
-		ieee->set_chan(ieee->dev, ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee));
-	else
-		ieee->set_chan(ieee->dev, ieee->current_network.channel);
-	//
-	up(&ieee->wx_sem);
-}
-
-
-void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
-{
-	#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-		queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
-	#else
-		schedule_task(&ieee->ext_send_beacon_wq);
-	#endif
-
-}
-
-#endif // _RTL8187_EXT_PATCH_
 
 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
 {
@@ -2324,12 +1574,6 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
 	}
 
 	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
-	//FIXME
-	#if 0
-	spin_lock_irqsave(&ieee->lock,flags);
-	add_associate(ieee,dest);
-	spin_unlock_irqrestore(&ieee->lock,flags);
-	#endif
 }
 
 
@@ -2347,11 +1591,8 @@ void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
 
 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
 {
-#if 0
-        int timeout = ieee->ps_timeout;
-#else
         int timeout = 0;
-#endif
+
 	u8 dtim;
 	/*if(ieee->ps == IEEE80211_PS_DISABLED ||
 		ieee->iw_mode != IW_MODE_INFRA ||
@@ -2382,13 +1623,7 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti
 	if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
 		(ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
 		return 0;
-#if 0
-	if(time_l){
-		*time_l = ieee->current_network.last_dtim_sta_time[0]
-			+ (ieee->current_network.beacon_interval
-			* ieee->current_network.dtim_period) * 1000;
-	}
-#else
+
 	if(time_l){
 		*time_l = ieee->current_network.last_dtim_sta_time[0]
 			+ MSECS((ieee->current_network.beacon_interval));
@@ -2396,7 +1631,6 @@ short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *ti
 			//printk("beacon_interval:%x, dtim_period:%x, totol to Msecs:%x, HZ:%x\n", ieee->current_network.beacon_interval, ieee->current_network.dtim_period, MSECS(((ieee->current_network.beacon_interval * ieee->current_network.dtim_period))), HZ);
 	}
 
-#endif
 	if(time_h){
 		*time_h = ieee->current_network.last_dtim_sta_time[1];
 		if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
@@ -2638,12 +1872,6 @@ associate_complete:
 					ieee80211_associate_abort(ieee);
 				}
 			}
-#ifdef _RTL8187_EXT_PATCH_
-			else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp)
-			{
-					ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
-			}
-#endif
 			break;
 
 		case IEEE80211_STYPE_ASSOC_REQ:
@@ -2653,21 +1881,10 @@ associate_complete:
 				ieee->iw_mode == IW_MODE_MASTER)
 
 				ieee80211_rx_assoc_rq(ieee, skb);
-#ifdef _RTL8187_EXT_PATCH_
-			else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req)
-			{
-					ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
-			}
-#endif
 			break;
 
 		case IEEE80211_STYPE_AUTH:
 
-#ifdef _RTL8187_EXT_PATCH_
-printk("IEEE80211_STYPE_AUTH\n");
-			if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth)
-			if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) );
-#endif
 			if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
 				if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
 				ieee->iw_mode == IW_MODE_INFRA){
@@ -2707,11 +1924,6 @@ printk("IEEE80211_STYPE_AUTH\n");
 
 		case IEEE80211_STYPE_DISASSOC:
 		case IEEE80211_STYPE_DEAUTH:
-#ifdef _RTL8187_EXT_PATCH_
-printk("IEEE80211_STYPE_DEAUTH\n");
-		if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth)
-		if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) )	;
-#endif
 			/* FIXME for now repeat all the association procedure
 			* both for disassociation and deauthentication
 			*/
@@ -2764,41 +1976,9 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
 
 	unsigned long flags;
 	int  i;
-#ifdef _RTL8187_EXT_PATCH_
-	int rate = ieee->rate;
-#endif
 
 	spin_lock_irqsave(&ieee->lock,flags);
-	#if 0
-	if(ieee->queue_stop){
-		IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
-		netif_stop_queue(ieee->dev);
-		ieee->ieee_stats.swtxstop++;
-		//dev_kfree_skb_any(skb);
-		err = 1;
-		goto exit;
-	}
-
-	ieee->stats.tx_bytes+=skb->len;
-
-
-	txb=ieee80211_skb_to_txb(ieee,skb);
-
-
-	if(txb==NULL){
-		IEEE80211DMESG("WW: IEEE stack failed to provide txb");
-		//dev_kfree_skb_any(skb);
-		err = 1;
-		goto exit;
-	}
-	#endif
 
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags)
-	{
-		rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
-	}
-#endif
 	/* called with 2nd parm 0, no tx mgmt lock required */
 	ieee80211_sta_wakeup(ieee,0);
 
@@ -2811,11 +1991,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
 		}else{
 			ieee->softmac_data_hard_start_xmit(
 				txb->fragments[i],
-#ifdef _RTL8187_EXT_PATCH_
-				ieee->dev, rate);
-#else
 				ieee->dev,ieee->rate);
-#endif
 				//(i+1)<txb->nr_frags);
 			ieee->stats.tx_packets++;
 			ieee->stats.tx_bytes += txb->fragments[i]->len;
@@ -2977,15 +2153,11 @@ void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
 		netif_carrier_on(ieee->dev);
 	}
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 void ieee80211_start_ibss_wq(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
-#else
-void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
-{
-#endif
 
 	/* iwconfig mode ad-hoc will schedule this and return
 	 * on the other hand this will block further iwconfig SET
@@ -3007,10 +2179,8 @@ void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
 	/* check if we have this cell in our network list */
 	ieee80211_softmac_check_all_nets(ieee);
 
-#ifdef ENABLE_DOT11D
 	if(ieee->state == IEEE80211_NOLINK)
 		ieee->current_network.channel = 10;
-#endif
 	/* if not then the state is not linked. Maybe the user swithced to
 	 * ad-hoc mode just after being in monitor mode, or just after
 	 * being very few time in managed mode (so the card have had no
@@ -3099,7 +2269,6 @@ inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
 void ieee80211_start_bss(struct ieee80211_device *ieee)
 {
 	unsigned long flags;
-#ifdef ENABLE_DOT11D
 	//
 	// Ref: 802.11d 11.1.3.3
 	// STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
@@ -3111,7 +2280,6 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
 			return;
 		}
 	}
-#endif
 	/* check if we have already found the net we
 	 * are interested in (if any).
 	 * if not (we are disassociated and we are not
@@ -3150,24 +2318,17 @@ void ieee80211_disassociate(struct ieee80211_device *ieee)
 	if (ieee->data_hard_stop)
 			ieee->data_hard_stop(ieee->dev);
 
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee))
 		Dot11d_Reset(ieee);
-#endif
 	ieee->state = IEEE80211_NOLINK;
 	ieee->link_change(ieee->dev);
 	notify_wx_assoc_event(ieee);
 
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_associate_retry_wq(struct work_struct *work)
 {
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
-#else
-void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
-{
-#endif
 	unsigned long flags;
 	down(&ieee->wx_sem);
 	if(!ieee->proto_started)
@@ -3217,16 +2378,7 @@ struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
 	struct sk_buff *skb = NULL;
 	struct ieee80211_probe_response *b;
 
-//rz
-#ifdef _RTL8187_EXT_PATCH_
-	if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp )
-		skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network));
-	else
-		skb = ieee80211_probe_resp(ieee, broadcast_addr);
-#else
 	skb = ieee80211_probe_resp(ieee, broadcast_addr);
-#endif
-//
 	if (!skb)
 		return NULL;
 
@@ -3273,17 +2425,6 @@ void ieee80211_stop_protocol(struct ieee80211_device *ieee)
 
 	ieee->proto_started = 0;
 
-#ifdef _RTL8187_EXT_PATCH_
-	if(ieee->ext_patch_ieee80211_stop_protocol)
-		ieee->ext_patch_ieee80211_stop_protocol(ieee);
-//if call queue_delayed_work,can call this,or do nothing..
-//edit by lawrence,20071118
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-//	cancel_delayed_work(&ieee->ext_stop_scan_wq);
-//	cancel_delayed_work(&ieee->ext_send_beacon_wq);
-#endif
-#endif // _RTL8187_EXT_PATCH_
-
 	ieee80211_stop_send_beacons(ieee);
 	if((ieee->iw_mode == IW_MODE_INFRA)&&(ieee->state == IEEE80211_LINKED)) {
 		SendDisassociation(ieee,NULL,WLAN_REASON_DISASSOC_STA_HAS_LEFT);
@@ -3320,11 +2461,7 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee)
 			if (ch > MAX_CHANNEL_NUMBER)
 				return; /* no channel found */
 
-#ifdef ENABLE_DOT11D
 		}while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
-#else
-		}while(!ieee->channel_map[ch]);
-#endif
 
 		ieee->current_network.channel = ch;
 	}
@@ -3368,92 +2505,8 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee)
 			break;
 
 		default:
-#ifdef _RTL8187_EXT_PATCH_
-			if((ieee->iw_mode == ieee->iw_ext_mode) &&\
-			    ieee->ext_patch_ieee80211_start_protocol &&\
-                            ieee->ext_patch_ieee80211_start_protocol(ieee)) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-				queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
-#endif
-				// By default, WMM function will be disabled in
-				// EXTENSION mode
-				ieee->current_network.QoS_Enable = 0;
-
-				if(ieee->modulation & IEEE80211_CCK_MODULATION){
-					ieee->current_network.rates_len = 4;
-					ieee->current_network.rates[0] = \
-                                              IEEE80211_BASIC_RATE_MASK | \
-					      IEEE80211_CCK_RATE_1MB;
-					ieee->current_network.rates[1] = \
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_CCK_RATE_2MB;
-					ieee->current_network.rates[2] = \
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_CCK_RATE_5MB;
-					ieee->current_network.rates[3] = \
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_CCK_RATE_11MB;
-				}else
-					ieee->current_network.rates_len = 0;
-
-				if(ieee->modulation & IEEE80211_OFDM_MODULATION){
-					ieee->current_network.rates_ex_len = 8;
-					ieee->current_network.rates_ex[0] = \
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_OFDM_RATE_6MB;
-					ieee->current_network.rates_ex[1] = \
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_OFDM_RATE_9MB;
-					ieee->current_network.rates_ex[2] = \
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_OFDM_RATE_12MB;
-					ieee->current_network.rates_ex[3] = \
-                                              IEEE80211_BASIC_RATE_MASK | \
-                                              IEEE80211_OFDM_RATE_18MB;
-					ieee->current_network.rates_ex[4] =\
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_OFDM_RATE_24MB;
-					ieee->current_network.rates_ex[5] =\
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_OFDM_RATE_36MB;
-					ieee->current_network.rates_ex[6] = \
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_OFDM_RATE_48MB;
-					ieee->current_network.rates_ex[7] =\
-                                              IEEE80211_BASIC_RATE_MASK |\
-                                              IEEE80211_OFDM_RATE_54MB;
-					ieee->rate = 540;
-				}else{
-					ieee->current_network.rates_ex_len = 0;
-					ieee->rate = 110;
-				}
-
-				/*
-				   spin_lock_irqsave(&ieee->lock, flags);
-				   if (ieee->state == IEEE80211_NOLINK)
-				   ieee80211_start_scan(ieee);
-				// ieee->set_chan(ieee->dev, 8);
-
-				spin_unlock_irqrestore(&ieee->lock, flags);
-				*/
-				memcpy(ieee->current_network.bssid, ieee->dev->dev_addr,\
-				      	 ETH_ALEN);
-				ieee->link_change(ieee->dev);
-				notify_wx_assoc_event(ieee);
-
-				if (ieee->data_hard_resume)
-					ieee->data_hard_resume(ieee->dev);
-
-				netif_carrier_on(ieee->dev);
-			} else {
-				ieee->iw_mode = IW_MODE_INFRA;
-				ieee80211_start_bss(ieee);
-			}
-#else
 			ieee->iw_mode = IW_MODE_INFRA;
 			ieee80211_start_bss(ieee);
-
-#endif
 			break;
 	}
 }
@@ -3497,16 +2550,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 	ieee->beinretry = false;
 	ieee->bHwRadioOff = false;
 //by amy
-#ifdef _RTL8187_EXT_PATCH_
-	ieee->iw_ext_mode = 999;
-#endif
 
 	init_mgmt_queue(ieee);
-#if 0
-	init_timer(&ieee->scan_timer);
-	ieee->scan_timer.data = (unsigned long)ieee;
-	ieee->scan_timer.function = ieee80211_softmac_scan_cb;
-#endif
+
 	ieee->tx_pending.txb = NULL;
 
 	init_timer(&ieee->associate_timer);
@@ -3522,7 +2568,6 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 #else
 	ieee->wq = create_workqueue(DRV_NAME);
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
 	INIT_DELAYED_WORK(&ieee->start_ibss_wq,(void*) ieee80211_start_ibss_wq);
 	INIT_WORK(&ieee->associate_complete_wq,(void*) ieee80211_associate_complete_wq);
 	INIT_WORK(&ieee->associate_procedure_wq,(void*) ieee80211_associate_procedure_wq);
@@ -3530,26 +2575,7 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 	INIT_DELAYED_WORK(&ieee->associate_retry_wq,(void*) ieee80211_associate_retry_wq);
 	INIT_WORK(&ieee->wx_sync_scan_wq,(void*) ieee80211_wx_sync_scan_wq);
 //	INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq);
-//added by lawrence,20071118
-#ifdef _RTL8187_EXT_PATCH_
-	INIT_WORK(&ieee->ext_stop_scan_wq,(void*) ieee80211_ext_stop_scan_wq);
-	//INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
-	INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ext_ieee80211_send_beacon_wq);
-#endif //_RTL8187_EXT_PATCH_
-#else
-	INIT_WORK(&ieee->start_ibss_wq,(void*) ieee80211_start_ibss_wq,ieee);
-	INIT_WORK(&ieee->associate_retry_wq,(void*) ieee80211_associate_retry_wq,ieee);
-	INIT_WORK(&ieee->associate_complete_wq,(void*) ieee80211_associate_complete_wq,ieee);
-	INIT_WORK(&ieee->associate_procedure_wq,(void*) ieee80211_associate_procedure_wq,ieee);
-	INIT_WORK(&ieee->softmac_scan_wq,(void*) ieee80211_softmac_scan_wq,ieee);
-	INIT_WORK(&ieee->wx_sync_scan_wq,(void*) ieee80211_wx_sync_scan_wq,ieee);
-//	INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq,ieee);
-#ifdef _RTL8187_EXT_PATCH_
-	INIT_WORK(&ieee->ext_stop_scan_wq,(void*) ieee80211_ext_stop_scan_wq,ieee);
-	//INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
-	INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ext_ieee80211_send_beacon_wq,ieee);
-#endif
-#endif
+
 	sema_init(&ieee->wx_sem, 1);
 	sema_init(&ieee->scan_sem, 1);
 
@@ -3559,9 +2585,7 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 	tasklet_init(&ieee->ps_task,
 	     (void(*)(unsigned long)) ieee80211_sta_ps,
 	     (unsigned long)ieee);
-#ifdef ENABLE_DOT11D
 	ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
-#endif
 }
 
 void ieee80211_softmac_free(struct ieee80211_device *ieee)
@@ -3575,15 +2599,9 @@ void ieee80211_softmac_free(struct ieee80211_device *ieee)
 	//add for RF power on power of by lizhaoming 080512
 	cancel_delayed_work(&ieee->GPIOChangeRFWorkItem);
 
-#ifdef _RTL8187_EXT_PATCH_
-	cancel_delayed_work(&ieee->ext_stop_scan_wq);
-	cancel_delayed_work(&ieee->ext_send_beacon_wq);
-#endif
 	destroy_workqueue(ieee->wq);
-#ifdef ENABLE_DOT11D
 	if(NULL != ieee->pDot11dInfo)
 		kfree(ieee->pDot11dInfo);
-#endif
 	up(&ieee->wx_sem);
 }
 
@@ -3992,38 +3010,3 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee)
 		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
 	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
 }
-
-
-#if 0
-EXPORT_SYMBOL(ieee80211_get_beacon);
-EXPORT_SYMBOL(ieee80211_wake_queue);
-EXPORT_SYMBOL(ieee80211_stop_queue);
-EXPORT_SYMBOL(ieee80211_reset_queue);
-EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
-EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
-EXPORT_SYMBOL(ieee80211_is_shortslot);
-EXPORT_SYMBOL(ieee80211_is_54g);
-EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
-EXPORT_SYMBOL(ieee80211_ps_tx_ack);
-EXPORT_SYMBOL(ieee80211_start_protocol);
-EXPORT_SYMBOL(ieee80211_stop_protocol);
-EXPORT_SYMBOL(notify_wx_assoc_event);
-EXPORT_SYMBOL(ieee80211_stop_send_beacons);
-EXPORT_SYMBOL(SendDisassociation);
-EXPORT_SYMBOL(ieee80211_disassociate);
-EXPORT_SYMBOL(ieee80211_start_scan);
-EXPORT_SYMBOL(ieee80211_softmac_ips_scan_syncro);
-#ifdef _RTL8187_EXT_PATCH_
-EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req);
-EXPORT_SYMBOL(ieee80211_ext_issue_disassoc);
-EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp);
-EXPORT_SYMBOL(softmac_mgmt_xmit);
-EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net);
-EXPORT_SYMBOL(ieee80211_start_scan);
-EXPORT_SYMBOL(ieee80211_stop_scan);
-EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon);
-EXPORT_SYMBOL(ieee80211_rx_auth_rq);
-EXPORT_SYMBOL(ieee80211_associate_step1);
-#endif // _RTL8187_EXT_PATCH_
-EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
index 54b4b71..f1d6cb4 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
@@ -270,16 +270,9 @@ out:
 }
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 void ieee80211_wx_sync_scan_wq(struct work_struct *work)
 {
 	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
-#else
-void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
-//void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
-//{
 	short chan;
 
 	chan = ieee->current_network.channel;
@@ -379,11 +372,7 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
 
 	if (wrqu->essid.flags && wrqu->essid.length) {
 //YJ,modified,080819
-#if LINUX_VERSION_CODE <  KERNEL_VERSION(2,6,20)
-		len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
-#else
 		len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE;
-#endif
 		memset(ieee->current_network.ssid, 0, ieee->current_network.ssid_len); //YJ,add,080819
 		strncpy(ieee->current_network.ssid, extra, len);
 		ieee->current_network.ssid_len = len;
@@ -581,22 +570,3 @@ exit:
 	return ret;
 
 }
-
-#if 0
-EXPORT_SYMBOL(ieee80211_wx_get_essid);
-EXPORT_SYMBOL(ieee80211_wx_set_essid);
-EXPORT_SYMBOL(ieee80211_wx_set_rate);
-EXPORT_SYMBOL(ieee80211_wx_get_rate);
-EXPORT_SYMBOL(ieee80211_wx_set_wap);
-EXPORT_SYMBOL(ieee80211_wx_get_wap);
-EXPORT_SYMBOL(ieee80211_wx_set_mode);
-EXPORT_SYMBOL(ieee80211_wx_get_mode);
-EXPORT_SYMBOL(ieee80211_wx_set_scan);
-EXPORT_SYMBOL(ieee80211_wx_get_freq);
-EXPORT_SYMBOL(ieee80211_wx_set_freq);
-EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
-EXPORT_SYMBOL(ieee80211_wx_get_name);
-EXPORT_SYMBOL(ieee80211_wx_set_power);
-EXPORT_SYMBOL(ieee80211_wx_get_power);
-EXPORT_SYMBOL(ieee80211_wlan_frequencies);
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
index 1294e05..e2945db 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
@@ -192,11 +192,11 @@ int ieee80211_encrypt_fragment(
         return -1;
 
 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
-	struct ieee80211_hdr *header;
+	struct ieee80211_hdr_4addr *header;
 
 	if (ieee->tkip_countermeasures &&
 	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
-		header = (struct ieee80211_hdr *) frag->data;
+		header = (struct ieee80211_hdr_4addr *)frag->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 			       "TX packet to " MAC_FMT "\n",
@@ -304,245 +304,23 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
   return(wme_UP);
 }
 
-#ifdef _RTL8187_EXT_PATCH_
-// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
-struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
-	struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
-	struct ieee80211_txb *txb = NULL;
-	struct ieee80211_hdr_3addr *frag_hdr;
-	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
-	int ether_type;
-	int bytes, QOS_ctl;
-	struct sk_buff *skb_frag;
-
-	ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
-
-	/* Advance the SKB to the start of the payload */
-	skb_pull(skb, sizeof(struct ethhdr));
-
-	/* Determine total amount of storage required for TXB packets */
-	bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
-	/* Determine fragmentation size based on destination (multicast
-	 * and broadcast are not fragmented) */
-	// if (is_multicast_ether_addr(dest) ||
-	// is_broadcast_ether_addr(dest)) {
-	if (is_multicast_ether_addr(header->addr1) ||
-			is_broadcast_ether_addr(header->addr1)) {
-		frag_size = MAX_FRAG_THRESHOLD;
-		QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
-	}
-	else {
-		//printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
-		frag_size = ieee->fts;//default:392
-		QOS_ctl = 0;
-	}
-
-	if(isQoS) {
-		QOS_ctl |= skb->priority; //set in the ieee80211_classify
-		*pQOS_ctl = cpu_to_le16(QOS_ctl);
-	}
-	//printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
-	/* Determine amount of payload per fragment.  Regardless of if
-	 * this stack is providing the full 802.11 header, one will
-	 * eventually be affixed to this fragment -- so we must account for
-	 * it when determining the amount of payload space. */
-	//bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
-	bytes_per_frag = frag_size - hdr_len;
-	if (ieee->config &
-			(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
-		bytes_per_frag -= IEEE80211_FCS_LEN;
-
-	/* Each fragment may need to have room for encryptiong pre/postfix */
-	if (isEncrypt)
-		bytes_per_frag -= crypt->ops->extra_prefix_len +
-			crypt->ops->extra_postfix_len;
-
-	/* Number of fragments is the total bytes_per_frag /
-	 * payload_per_fragment */
-	nr_frags = bytes / bytes_per_frag;
-	bytes_last_frag = bytes % bytes_per_frag;
-	if (bytes_last_frag)
-		nr_frags++;
-	else
-		bytes_last_frag = bytes_per_frag;
-
-	/* When we allocate the TXB we allocate enough space for the reserve
-	 * and full fragment bytes (bytes_per_frag doesn't include prefix,
-	 * postfix, header, FCS, etc.) */
-	txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
-	if (unlikely(!txb)) {
-		printk(KERN_WARNING "%s: Could not allocate TXB\n",
-			ieee->dev->name);
-		return NULL;
-	}
-	txb->encrypted = isEncrypt;
-	txb->payload_size = bytes;
-
-	for (i = 0; i < nr_frags; i++) {
-		skb_frag = txb->fragments[i];
-		skb_frag->priority = UP2AC(skb->priority);
-		if (isEncrypt)
-			skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
-
-		frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
-		memcpy(frag_hdr, (void *)header, hdr_len);
-
-		/* If this is not the last fragment, then add the MOREFRAGS
-		 * bit to the frame control */
-		if (i != nr_frags - 1) {
-			frag_hdr->frame_ctl = cpu_to_le16(
-					header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
-			bytes = bytes_per_frag;
-
-		} else {
-			/* The last fragment takes the remaining length */
-			bytes = bytes_last_frag;
-		}
-
-		frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
-		//frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
-		//
-
-		/* Put a SNAP header on the first fragment */
-		if (i == 0) {
-			ieee80211_put_snap(
-				skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
-			bytes -= SNAP_SIZE + sizeof(u16);
-		}
-
-		memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
-
-		/* Advance the SKB... */
-		skb_pull(skb, bytes);
-
-		/* Encryption routine will move the header forward in order
-		 * to insert the IV between the header and the payload */
-		if (isEncrypt)
-			ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
-		if (ieee->config &
-				(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
-			skb_put(skb_frag, 4);
-	}
-	// Advance sequence number in data frame.
-	//printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
-	if (ieee->seq_ctrl[0] == 0xFFF)
-		ieee->seq_ctrl[0] = 0;
-	else
-		ieee->seq_ctrl[0]++;
-	// stanley, just for debug
-/*
-{
-	int j=0;
-	for(j=0;j<nr_frags;j++)
-	{
-			int i;
-		struct sk_buff *skb = txb->fragments[j];
-			printk("send(%d): ", j);
-			for (i=0;i<skb->len;i++)
-				printk("%02X ", skb->data[i]&0xff);
-			printk("\n");
-	}
-}
-*/
-
-	return txb;
-}
-
-
-// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
-// Assume no encryption, no FCS computing
-struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
-	struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
-	struct ieee80211_txb *txb = NULL;
-	struct ieee80211_hdr_3addr *frag_hdr;
-	int ether_type;
-	int bytes, QOS_ctl;
-
-	ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
-
-	/* Advance the SKB to the start of the payload */
-	skb_pull(skb, sizeof(struct ethhdr));
-
-	/* Determine total amount of storage required for TXB packets */
-	bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
-	if (is_multicast_ether_addr(header->addr1) ||
-			is_broadcast_ether_addr(header->addr1)) {
-		QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
-	}
-	else {
-		QOS_ctl = 0;
-	}
-
-	if(isQoS) {
-		QOS_ctl |= skb->priority; //set in the ieee80211_classify
-		*pQOS_ctl = cpu_to_le16(QOS_ctl);
-	}
-
-	txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
-	if (unlikely(!txb)) {
-		printk(KERN_WARNING "%s: Could not allocate TXB\n",
-			ieee->dev->name);
-		return NULL;
-	}
-
-	txb->nr_frags = 1;
-	txb->frag_size = bytes;
-	txb->encrypted = isEncrypt;
-	txb->payload_size = bytes;
-
-	txb->fragments[0] = skb;
-	ieee80211_put_snap(
-			skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
-	frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
-	memcpy(frag_hdr, (void *)header, hdr_len);
-	frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
-	skb->priority = UP2AC(skb->priority);
-
-	// Advance sequence number in data frame.
-	//printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
-	if (ieee->seq_ctrl[0] == 0xFFF)
-		ieee->seq_ctrl[0] = 0;
-	else
-		ieee->seq_ctrl[0]++;
-
-	return txb;
-}
-
-#endif // _RTL8187_EXT_PATCH_
-
 /* SKBs are added to the ieee->tx_queue. */
 int ieee80211_xmit(struct sk_buff *skb,
 		   struct net_device *dev)
 {
 	struct ieee80211_device *ieee = netdev_priv(dev);
 	struct ieee80211_txb *txb = NULL;
-	struct ieee80211_hdr_3addr_QOS *frag_hdr;
+	struct ieee80211_hdr_3addrqos *frag_hdr;
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
 	unsigned long flags;
 	struct net_device_stats *stats = &ieee->stats;
 	int ether_type, encrypt;
-	int bytes, fc, QOS_ctl, hdr_len;
+	int bytes, fc, qos_ctl, hdr_len;
 	struct sk_buff *skb_frag;
-	//struct ieee80211_hdr header = { /* Ensure zero initialized */
-	//	.duration_id = 0,
-	//	.seq_ctl = 0
-	//};
-	struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
+	struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
 		.duration_id = 0,
 		.seq_ctl = 0,
-		.QOS_ctl = 0
+		.qos_ctl = 0
 	};
 	u8 dest[ETH_ALEN], src[ETH_ALEN];
 
@@ -569,16 +347,6 @@ int ieee80211_xmit(struct sk_buff *skb,
 			goto success;
 		}
 
-
-#ifdef _RTL8187_EXT_PATCH_
-		// note, skb->priority which was set by ieee80211_classify, and used by physical tx
-		if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
-		{
-			txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
-			goto success;
-		}
-#endif
-
 		ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
 
 		crypt = ieee->crypt[ieee->tx_keyidx];
@@ -651,22 +419,23 @@ int ieee80211_xmit(struct sk_buff *skb,
 		if (is_multicast_ether_addr(header.addr1) ||
 		is_broadcast_ether_addr(header.addr1)) {
 			frag_size = MAX_FRAG_THRESHOLD;
-			QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
+			qos_ctl = QOS_CTL_NOTCONTAIN_ACK;
 		}
 		else {
 			//printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
 			frag_size = ieee->fts;//default:392
-			QOS_ctl = 0;
+			qos_ctl = 0;
 		}
 
 		if (ieee->current_network.QoS_Enable)	{
 			hdr_len = IEEE80211_3ADDR_LEN + 2;
-			QOS_ctl |= skb->priority; //set in the ieee80211_classify
-			header.QOS_ctl = cpu_to_le16(QOS_ctl);
+			/* skb->priority is set in the ieee80211_classify() */
+			qos_ctl |= skb->priority;
+			header.qos_ctl = cpu_to_le16(qos_ctl);
 		} else {
 			hdr_len = IEEE80211_3ADDR_LEN;
 		}
-		//printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
+
 		/* Determine amount of payload per fragment.  Regardless of if
 		* this stack is providing the full 802.11 header, one will
 		* eventually be affixed to this fragment -- so we must account for
@@ -709,7 +478,7 @@ int ieee80211_xmit(struct sk_buff *skb,
 			if (encrypt)
 				skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
 
-			frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
+			frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
 			memcpy(frag_hdr, &header, hdr_len);
 
 			/* If this is not the last fragment, then add the MOREFRAGS
@@ -790,10 +559,6 @@ int ieee80211_xmit(struct sk_buff *skb,
 
  success:
 	spin_unlock_irqrestore(&ieee->lock, flags);
-#ifdef _RTL8187_EXT_PATCH_
-	// Sometimes, extension mode can reuse skb (by txb->fragments[0])
-	if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
-#endif
 		dev_kfree_skb_any(skb);
 	if (txb) {
 		if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
@@ -802,13 +567,13 @@ int ieee80211_xmit(struct sk_buff *skb,
 			if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
 				stats->tx_packets++;
 				stats->tx_bytes += txb->payload_size;
-				return 0;
+				return NETDEV_TX_OK;
 			}
 			ieee80211_txb_free(txb);
 		}
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 
  failed:
 	spin_unlock_irqrestore(&ieee->lock, flags);
@@ -817,12 +582,3 @@ int ieee80211_xmit(struct sk_buff *skb,
 	return NETDEV_TX_BUSY;
 
 }
-
-#if 0
-EXPORT_SYMBOL(ieee80211_txb_free);
-#ifdef _RTL8187_EXT_PATCH_
-EXPORT_SYMBOL(ieee80211_alloc_txb);
-EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
-EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
-#endif // _RTL8187_EXT_PATCH_
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index d1295e5..8d8bdd0 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -39,12 +39,6 @@ static const char *ieee80211_modes[] = {
 	"?", "a", "b", "ab", "g", "ag", "bg", "abg"
 };
 
-#ifdef FEDORACORE_9
-#define IN_FEDORACORE_9 1
-#else
-#define IN_FEDORACORE_9 0
-#endif
-
 #define MAX_CUSTOM_LEN 64
 static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 		                           char *start, char *stop,
@@ -61,11 +55,7 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 	iwe.cmd = SIOCGIWAP;
 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 	memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-#else
-	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
-#endif
 
 	/* Remaining entries will be displayed in the order we provide them */
 
@@ -77,28 +67,16 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 	if (network->ssid_len == 0) {
 	//YJ,modified,080903,end
 		iwe.u.data.length = sizeof("<hidden>");
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 		start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
-#else
-		start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
-#endif
 	} else {
 		iwe.u.data.length = min(network->ssid_len, (u8)32);
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 		start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-#else
-		start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
-#endif
 	}
 	//printk("ESSID: %s\n",network->ssid);
 	/* Add the protocol name */
 	iwe.cmd = SIOCGIWNAME;
 	snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
-#else
-	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
-#endif
 
         /* Add mode */
         iwe.cmd = SIOCGIWMODE;
@@ -109,11 +87,7 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 		else
 			iwe.u.mode = IW_MODE_ADHOC;
 
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 		start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
-#else
-		start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
-#endif
 	}
 
         /* Add frequency/channel */
@@ -123,11 +97,7 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 	iwe.u.freq.m = network->channel;
 	iwe.u.freq.e = 0;
 	iwe.u.freq.i = 0;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-#else
-	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
-#endif
 
 	/* Add encryption capability */
 	iwe.cmd = SIOCGIWENCODE;
@@ -136,11 +106,7 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 	else
 		iwe.u.data.flags = IW_ENCODE_DISABLED;
 	iwe.u.data.length = 0;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 	start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-#else
-	start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
-#endif
 
 	/* Add basic and extended rates */
 	max_rate = 0;
@@ -169,20 +135,12 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 	iwe.cmd = SIOCGIWRATE;
 	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
 	iwe.u.bitrate.value = max_rate * 500000;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
-#else
-	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
-#endif
 
 	iwe.cmd = IWEVCUSTOM;
 	iwe.u.data.length = p - custom;
 	if (iwe.u.data.length)
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 		start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-		start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
 
 	/* Add quality statistics */
 	/* TODO: Fix these values... */
@@ -201,92 +159,35 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 	if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
 		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
 	iwe.u.qual.updated = 7;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 	start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-#else
-	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
-#endif
 
 	iwe.cmd = IWEVCUSTOM;
 	p = custom;
 
 	iwe.u.data.length = p - custom;
 	if (iwe.u.data.length)
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 		start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-		start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
-
-#if 0
-	if (ieee->wpa_enabled && network->wpa_ie_len){
-		char buf[MAX_WPA_IE_LEN * 2 + 30];
-	//	printk("WPA IE\n");
-		u8 *p = buf;
-		p += sprintf(p, "wpa_ie=");
-		for (i = 0; i < network->wpa_ie_len; i++) {
-			p += sprintf(p, "%02x", network->wpa_ie[i]);
-		}
 
 		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = IWEVCUSTOM;
-		iwe.u.data.length = strlen(buf);
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
-		start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-		start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
-	}
-
-	if (ieee->wpa_enabled && network->rsn_ie_len){
-		char buf[MAX_WPA_IE_LEN * 2 + 30];
-
-		u8 *p = buf;
-		p += sprintf(p, "rsn_ie=");
-		for (i = 0; i < network->rsn_ie_len; i++) {
-			p += sprintf(p, "%02x", network->rsn_ie[i]);
-		}
-
-
-#else
-		memset(&iwe, 0, sizeof(iwe));
         if (network->wpa_ie_len) {
 	//	printk("wpa_ie_len:%d\n", network->wpa_ie_len);
                 char buf[MAX_WPA_IE_LEN];
                 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
                 iwe.cmd = IWEVGENIE;
                 iwe.u.data.length = network->wpa_ie_len;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
         }
 
         memset(&iwe, 0, sizeof(iwe));
         if (network->rsn_ie_len) {
 	//	printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
-		#if 0
-		{
-			int i;
-			for (i=0; i<network->rsn_ie_len; i++);
-			printk("%2x ", network->rsn_ie[i]);
-			printk("\n");
-		}
-		#endif
                 char buf[MAX_WPA_IE_LEN];
                 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
                 iwe.cmd = IWEVGENIE;
                 iwe.u.data.length = network->rsn_ie_len;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 		start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-		start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
 	}
 
-#endif
-
 	/* Add EXTRA: Age to display seconds since last beacon/probe response
 	 * for given network. */
 	iwe.cmd = IWEVCUSTOM;
@@ -295,11 +196,7 @@ static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
 		      " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
 	iwe.u.data.length = p - custom;
 	if (iwe.u.data.length)
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
 		start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-		start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
 
 	return start;
 }
@@ -638,12 +535,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
 
 	sec.enabled = 1;
     //    sec.encrypt = 1;
-#if 0
-        if (group_key ? !ieee->host_mc_decrypt :
-            !(ieee->host_encrypt || ieee->host_decrypt ||
-              ieee->host_encrypt_msdu))
-                goto skip_host_crypt;
-#endif
+
         switch (ext->alg) {
         case IW_ENCODE_ALG_WEP:
                 alg = "WEP";
@@ -829,15 +721,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
 #if 1
 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
 {
-#if 0
-	printk("====>%s()\n", __func__);
-	{
-		int i;
-		for (i=0; i<len; i++)
-		printk("%2x ", ie[i]&0xff);
-		printk("\n");
-	}
-#endif
 	u8 *buf = NULL;
 
 	if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
@@ -872,13 +755,3 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
 
 }
 #endif
-
-#if 0
-EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
-EXPORT_SYMBOL(ieee80211_wx_set_mlme);
-EXPORT_SYMBOL(ieee80211_wx_set_auth);
-EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
-EXPORT_SYMBOL(ieee80211_wx_get_scan);
-EXPORT_SYMBOL(ieee80211_wx_set_encode);
-EXPORT_SYMBOL(ieee80211_wx_get_encode);
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/internal.h b/drivers/staging/rtl8187se/ieee80211/internal.h
deleted file mode 100644
index ddc2235..0000000
--- a/drivers/staging/rtl8187se/ieee80211/internal.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 _CRYPTO_INTERNAL_H
-#define _CRYPTO_INTERNAL_H
-
-
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/init.h>
-#include <asm/hardirq.h>
-#include <asm/softirq.h>
-#include <asm/kmap_types.h>
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
-#define list_for_each_entry(pos, head, member)				\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head); 					\
-	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next))
-
-static inline void cond_resched(void)
-{
-	if (need_resched()) {
-		set_current_state(TASK_RUNNING);
-		schedule();
-	}
-}
-#endif
-
-extern enum km_type crypto_km_types[];
-
-static inline enum km_type crypto_kmap_type(int out)
-{
-	return crypto_km_types[(in_softirq() ? 2 : 0) + out];
-}
-
-static inline void *crypto_kmap(struct page *page, int out)
-{
-	return kmap_atomic(page, crypto_kmap_type(out));
-}
-
-static inline void crypto_kunmap(void *vaddr, int out)
-{
-	kunmap_atomic(vaddr, crypto_kmap_type(out));
-}
-
-static inline void crypto_yield(struct crypto_tfm *tfm)
-{
-	if (!in_softirq())
-		cond_resched();
-}
-
-static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
-{
-	return (void *)&tfm[1];
-}
-
-struct crypto_alg *crypto_alg_lookup(const char *name);
-
-#ifdef CONFIG_KMOD
-void crypto_alg_autoload(const char *name);
-struct crypto_alg *crypto_alg_mod_lookup(const char *name);
-#else
-static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
-{
-	return crypto_alg_lookup(name);
-}
-#endif
-
-#ifdef CONFIG_CRYPTO_HMAC
-int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
-void crypto_free_hmac_block(struct crypto_tfm *tfm);
-#else
-static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
-{
-	return 0;
-}
-
-static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
-{ }
-#endif
-
-#ifdef CONFIG_PROC_FS
-void __init crypto_init_proc(void);
-#else
-static inline void crypto_init_proc(void)
-{ }
-#endif
-
-int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
-int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
-int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
-
-int crypto_init_digest_ops(struct crypto_tfm *tfm);
-int crypto_init_cipher_ops(struct crypto_tfm *tfm);
-int crypto_init_compress_ops(struct crypto_tfm *tfm);
-
-void crypto_exit_digest_ops(struct crypto_tfm *tfm);
-void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
-void crypto_exit_compress_ops(struct crypto_tfm *tfm);
-
-#endif	/* _CRYPTO_INTERNAL_H */
-
diff --git a/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h b/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h
deleted file mode 100644
index 9ed0ca4..0000000
--- a/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Scatterlist Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- * Copyright (c) 2002 David S. Miller (davem@redhat.com)
- *
- * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Mé°ˆler.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 _LINUX_CRYPTO_H
-#define _LINUX_CRYPTO_H
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/string.h>
-#include <asm/page.h>
-#include <asm/errno.h>
-
-#define crypto_register_alg crypto_register_alg_rtl
-#define crypto_unregister_alg crypto_unregister_alg_rtl
-#define crypto_alloc_tfm crypto_alloc_tfm_rtl
-#define crypto_free_tfm crypto_free_tfm_rtl
-#define crypto_alg_available crypto_alg_available_rtl
-
-/*
- * Algorithm masks and types.
- */
-#define CRYPTO_ALG_TYPE_MASK		0x000000ff
-#define CRYPTO_ALG_TYPE_CIPHER		0x00000001
-#define CRYPTO_ALG_TYPE_DIGEST		0x00000002
-#define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
-
-/*
- * Transform masks and values (for crt_flags).
- */
-#define CRYPTO_TFM_MODE_MASK		0x000000ff
-#define CRYPTO_TFM_REQ_MASK		0x000fff00
-#define CRYPTO_TFM_RES_MASK		0xfff00000
-
-#define CRYPTO_TFM_MODE_ECB		0x00000001
-#define CRYPTO_TFM_MODE_CBC		0x00000002
-#define CRYPTO_TFM_MODE_CFB		0x00000004
-#define CRYPTO_TFM_MODE_CTR		0x00000008
-
-#define CRYPTO_TFM_REQ_WEAK_KEY		0x00000100
-#define CRYPTO_TFM_RES_WEAK_KEY		0x00100000
-#define CRYPTO_TFM_RES_BAD_KEY_LEN   	0x00200000
-#define CRYPTO_TFM_RES_BAD_KEY_SCHED 	0x00400000
-#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 	0x00800000
-#define CRYPTO_TFM_RES_BAD_FLAGS 	0x01000000
-
-/*
- * Miscellaneous stuff.
- */
-#define CRYPTO_UNSPEC			0
-#define CRYPTO_MAX_ALG_NAME		64
-
-struct scatterlist;
-
-/*
- * Algorithms: modular crypto algorithm implementations, managed
- * via crypto_register_alg() and crypto_unregister_alg().
- */
-struct cipher_alg {
-	unsigned int cia_min_keysize;
-	unsigned int cia_max_keysize;
-	int (*cia_setkey)(void *ctx, const u8 *key,
-	                  unsigned int keylen, u32 *flags);
-	void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
-	void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
-};
-
-struct digest_alg {
-	unsigned int dia_digestsize;
-	void (*dia_init)(void *ctx);
-	void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
-	void (*dia_final)(void *ctx, u8 *out);
-	int (*dia_setkey)(void *ctx, const u8 *key,
-	                  unsigned int keylen, u32 *flags);
-};
-
-struct compress_alg {
-	int (*coa_init)(void *ctx);
-	void (*coa_exit)(void *ctx);
-	int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
-	                    u8 *dst, unsigned int *dlen);
-	int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
-	                      u8 *dst, unsigned int *dlen);
-};
-
-#define cra_cipher	cra_u.cipher
-#define cra_digest	cra_u.digest
-#define cra_compress	cra_u.compress
-
-struct crypto_alg {
-	struct list_head cra_list;
-	u32 cra_flags;
-	unsigned int cra_blocksize;
-	unsigned int cra_ctxsize;
-	const char cra_name[CRYPTO_MAX_ALG_NAME];
-
-	union {
-		struct cipher_alg cipher;
-		struct digest_alg digest;
-		struct compress_alg compress;
-	} cra_u;
-
-	struct module *cra_module;
-};
-
-/*
- * Algorithm registration interface.
- */
-int crypto_register_alg(struct crypto_alg *alg);
-int crypto_unregister_alg(struct crypto_alg *alg);
-
-/*
- * Algorithm query interface.
- */
-int crypto_alg_available(const char *name, u32 flags);
-
-/*
- * Transforms: user-instantiated objects which encapsulate algorithms
- * and core processing logic.  Managed via crypto_alloc_tfm() and
- * crypto_free_tfm(), as well as the various helpers below.
- */
-struct crypto_tfm;
-
-struct cipher_tfm {
-	void *cit_iv;
-	unsigned int cit_ivsize;
-	u32 cit_mode;
-	int (*cit_setkey)(struct crypto_tfm *tfm,
-	                  const u8 *key, unsigned int keylen);
-	int (*cit_encrypt)(struct crypto_tfm *tfm,
-			   struct scatterlist *dst,
-			   struct scatterlist *src,
-			   unsigned int nbytes);
-	int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
-	                      struct scatterlist *dst,
-	                      struct scatterlist *src,
-	                      unsigned int nbytes, u8 *iv);
-	int (*cit_decrypt)(struct crypto_tfm *tfm,
-			   struct scatterlist *dst,
-			   struct scatterlist *src,
-			   unsigned int nbytes);
-	int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
-			   struct scatterlist *dst,
-			   struct scatterlist *src,
-			   unsigned int nbytes, u8 *iv);
-	void (*cit_xor_block)(u8 *dst, const u8 *src);
-};
-
-struct digest_tfm {
-	void (*dit_init)(struct crypto_tfm *tfm);
-	void (*dit_update)(struct crypto_tfm *tfm,
-	                   struct scatterlist *sg, unsigned int nsg);
-	void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
-	void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
-	                   unsigned int nsg, u8 *out);
-	int (*dit_setkey)(struct crypto_tfm *tfm,
-	                  const u8 *key, unsigned int keylen);
-#ifdef CONFIG_CRYPTO_HMAC
-	void *dit_hmac_block;
-#endif
-};
-
-struct compress_tfm {
-	int (*cot_compress)(struct crypto_tfm *tfm,
-	                    const u8 *src, unsigned int slen,
-	                    u8 *dst, unsigned int *dlen);
-	int (*cot_decompress)(struct crypto_tfm *tfm,
-	                      const u8 *src, unsigned int slen,
-	                      u8 *dst, unsigned int *dlen);
-};
-
-#define crt_cipher	crt_u.cipher
-#define crt_digest	crt_u.digest
-#define crt_compress	crt_u.compress
-
-struct crypto_tfm {
-
-	u32 crt_flags;
-
-	union {
-		struct cipher_tfm cipher;
-		struct digest_tfm digest;
-		struct compress_tfm compress;
-	} crt_u;
-
-	struct crypto_alg *__crt_alg;
-};
-
-/*
- * Transform user interface.
- */
-
-/*
- * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
- * If that fails and the kernel supports dynamically loadable modules, it
- * will then attempt to load a module of the same name or alias.  A refcount
- * is grabbed on the algorithm which is then associated with the new transform.
- *
- * crypto_free_tfm() frees up the transform and any associated resources,
- * then drops the refcount on the associated algorithm.
- */
-struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
-void crypto_free_tfm(struct crypto_tfm *tfm);
-
-/*
- * Transform helpers which query the underlying algorithm.
- */
-static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
-{
-	return tfm->__crt_alg->cra_name;
-}
-
-static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
-{
-	struct crypto_alg *alg = tfm->__crt_alg;
-
-	if (alg->cra_module)
-		return alg->cra_module->name;
-	else
-		return NULL;
-}
-
-static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
-{
-	return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
-}
-
-static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->__crt_alg->cra_cipher.cia_min_keysize;
-}
-
-static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->__crt_alg->cra_cipher.cia_max_keysize;
-}
-
-static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_ivsize;
-}
-
-static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
-{
-	return tfm->__crt_alg->cra_blocksize;
-}
-
-static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	return tfm->__crt_alg->cra_digest.dia_digestsize;
-}
-
-/*
- * API wrappers.
- */
-static inline void crypto_digest_init(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_init(tfm);
-}
-
-static inline void crypto_digest_update(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_update(tfm, sg, nsg);
-}
-
-static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_final(tfm, out);
-}
-
-static inline void crypto_digest_digest(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg, u8 *out)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
-}
-
-static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
-                                       const u8 *key, unsigned int keylen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	if (tfm->crt_digest.dit_setkey == NULL)
-		return -ENOSYS;
-	return tfm->crt_digest.dit_setkey(tfm, key, keylen);
-}
-
-static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
-                                       const u8 *key, unsigned int keylen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
-}
-
-static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *dst,
-                                        struct scatterlist *src,
-                                        unsigned int nbytes)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
-}
-
-static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
-                                           struct scatterlist *dst,
-                                           struct scatterlist *src,
-                                           unsigned int nbytes, u8 *iv)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
-	return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
-}
-
-static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *dst,
-                                        struct scatterlist *src,
-                                        unsigned int nbytes)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
-}
-
-static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
-                                           struct scatterlist *dst,
-                                           struct scatterlist *src,
-                                           unsigned int nbytes, u8 *iv)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
-	return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
-}
-
-static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
-                                        const u8 *src, unsigned int len)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	memcpy(tfm->crt_cipher.cit_iv, src, len);
-}
-
-static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
-                                        u8 *dst, unsigned int len)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	memcpy(dst, tfm->crt_cipher.cit_iv, len);
-}
-
-static inline int crypto_comp_compress(struct crypto_tfm *tfm,
-                                       const u8 *src, unsigned int slen,
-                                       u8 *dst, unsigned int *dlen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
-	return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
-}
-
-static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
-                                         const u8 *src, unsigned int slen,
-                                         u8 *dst, unsigned int *dlen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
-	return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
-}
-
-/*
- * HMAC support.
- */
-#ifdef CONFIG_CRYPTO_HMAC
-void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
-void crypto_hmac_update(struct crypto_tfm *tfm,
-                        struct scatterlist *sg, unsigned int nsg);
-void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
-                       unsigned int *keylen, u8 *out);
-void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
-                 struct scatterlist *sg, unsigned int nsg, u8 *out);
-#endif	/* CONFIG_CRYPTO_HMAC */
-
-#endif	/* _LINUX_CRYPTO_H */
-
diff --git a/drivers/staging/rtl8187se/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211_crypt.h
deleted file mode 100644
index b58a3bc..0000000
--- a/drivers/staging/rtl8187se/ieee80211_crypt.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
-	const char *name;
-
-	/* init new crypto context (e.g., allocate private data space,
-	 * select IV, etc.); returns NULL on failure or pointer to allocated
-	 * private data on success */
-	void * (*init)(int keyidx);
-
-	/* deinitialize crypto context and free allocated private data */
-	void (*deinit)(void *priv);
-
-	/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
-	 * value from decrypt_mpdu is passed as the keyidx value for
-	 * decrypt_msdu. skb must have enough head and tail room for the
-	 * encryption; if not, error will be returned; these functions are
-	 * called for all MPDUs (i.e., fragments).
-	 */
-	int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
-	/* These functions are called for full MSDUs, i.e. full frames.
-	 * These can be NULL if full MSDU operations are not needed. */
-	int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-			    void *priv);
-
-	int (*set_key)(void *key, int len, u8 *seq, void *priv);
-	int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
-	/* procfs handler for printing out key information and possible
-	 * statistics */
-	char * (*print_stats)(char *p, void *priv);
-
-	/* maximum number of bytes added by encryption; encrypt buf is
-	 * allocated with extra_prefix_len bytes, copy of in_buf, and
-	 * extra_postfix_len; encrypt need not use all this space, but
-	 * the result must start at the beginning of the buffer and correct
-	 * length must be returned */
-	int extra_prefix_len, extra_postfix_len;
-
-	struct module *owner;
-};
-
-struct ieee80211_crypt_data {
-	struct list_head list; /* delayed deletion list */
-	struct ieee80211_crypto_ops *ops;
-	void *priv;
-	atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
-				    struct ieee80211_crypt_data **crypt);
-
-#endif
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
index db446b7..8216d7e 100644
--- a/drivers/staging/rtl8187se/r8180.h
+++ b/drivers/staging/rtl8187se/r8180.h
@@ -41,7 +41,7 @@
 #include <linux/timer.h>
 #include <linux/proc_fs.h>	// Necessary because we use the proc fs
 #include <linux/if_arp.h>
-#include "ieee80211.h"
+#include "ieee80211/ieee80211.h"
 #include <asm/io.h>
 //#include <asm/semaphore.h>
 
@@ -52,31 +52,16 @@
 
 #define DEFAULT_FRAG_THRESHOLD 2342U
 #define MIN_FRAG_THRESHOLD     256U
-//#define	MAX_FRAG_THRESHOLD     2342U
 #define DEFAULT_RTS_THRESHOLD 2342U
 #define MIN_RTS_THRESHOLD 0U
 #define MAX_RTS_THRESHOLD 2342U
 #define DEFAULT_BEACONINTERVAL 0x64U
-#define DEFAULT_BEACON_ESSID "Rtl8180"
 
-#define DEFAULT_SSID ""
 #define DEFAULT_RETRY_RTS 7
 #define DEFAULT_RETRY_DATA 7
-#define PRISM_HDR_SIZE 64
 
-#ifdef CONFIG_RTL8185B
-
-#define MGNT_QUEUE						0
-#define BK_QUEUE						1
-#define BE_QUEUE						2
-#define VI_QUEUE						3
-#define VO_QUEUE						4
-#define HIGH_QUEUE						5
 #define BEACON_QUEUE					6
 
-#define LOW_QUEUE						BE_QUEUE
-#define NORMAL_QUEUE					MGNT_QUEUE
-
 #define aSifsTime 	10
 
 #define sCrcLng         4
@@ -199,7 +184,6 @@ typedef	union _ThreeWire{
 	u16			longData;
 }ThreeWireReg;
 
-#endif
 
 typedef struct buffer
 {
@@ -659,7 +643,6 @@ typedef struct r8180_priv
 	short ack_tx_to_ieee;
 
 	u8 PowerProfile;
-#ifdef CONFIG_RTL8185B
 	u32 CSMethod;
 	u8 cck_txpwr_base;
 	u8 ofdm_txpwr_base;
@@ -675,7 +658,6 @@ typedef struct r8180_priv
 	u32 IntrMask;
 
 	struct 	ChnlAccessSetting  ChannelAccessSetting;
-#endif
 }r8180_priv;
 
 #define MANAGE_PRIORITY 0
@@ -750,11 +732,7 @@ void rtl8185b_irq_enable(struct net_device *dev);
 void fix_rx_fifo(struct net_device *dev);
 void fix_tx_fifo(struct net_device *dev);
 void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
-#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
 //#endif
 bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource);
 
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h
index a028a51..36ae100 100644
--- a/drivers/staging/rtl8187se/r8180_93cx6.h
+++ b/drivers/staging/rtl8187se/r8180_93cx6.h
@@ -28,11 +28,9 @@
 #define	RFCHIPID_MAXIM 4
 #define	RFCHIPID_GCT 5
 #define RFCHIPID_RTL8225 9
-#ifdef CONFIG_RTL8185B
 #define RF_ZEBRA2 11
 #define EPROM_TXPW_BASE 0x05
 #define RF_ZEBRA4 12
-#endif
 #define RFCHIPID_RTL8255 0xa
 #define RF_PARAM 0x19
 #define RF_PARAM_DIGPHY_SHIFT 0
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 7e2feca..53e654d 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -22,69 +22,24 @@
 
    A big big thanks goes also to Realtek corp. for their help in my attempt to
    add RTL8185 and RTL8225 support, and to David Young also.
-*/
-
-#if 0
-double __floatsidf (int i) { return i; }
-unsigned int __fixunsdfsi (double d) { return d; }
-double __adddf3(double a, double b) { return a+b; }
-double __addsf3(float a, float b) { return a+b; }
-double __subdf3(double a, double b) { return a-b; }
-double __extendsfdf2(float a) {return a;}
-#endif
 
+   Power management interface routines.
+   Written by Mariusz Matuszek.
+*/
 
-#undef DEBUG_TX_DESC2
 #undef RX_DONT_PASS_UL
-#undef DEBUG_EPROM
-#undef DEBUG_RX_VERBOSE
 #undef DUMMY_RX
-#undef DEBUG_ZERO_RX
-#undef DEBUG_RX_SKB
-#undef DEBUG_TX_FRAG
-#undef DEBUG_RX_FRAG
-#undef DEBUG_TX_FILLDESC
-#undef DEBUG_TX
-#undef DEBUG_IRQ
-#undef DEBUG_RX
-#undef DEBUG_RXALLOC
-#undef DEBUG_REGISTERS
-#undef DEBUG_RING
-#undef DEBUG_IRQ_TASKLET
-#undef DEBUG_TX_ALLOC
-#undef DEBUG_TX_DESC
-
-//#define DEBUG_TX
-//#define DEBUG_TX_DESC2
-//#define DEBUG_RX
-//#define DEBUG_RX_SKB
-
-//#define CONFIG_RTL8180_IO_MAP
+
 #include <linux/syscalls.h>
-//#include <linux/fcntl.h>
-//#include <asm/uaccess.h>
+
 #include "r8180_hw.h"
 #include "r8180.h"
-#include "r8180_sa2400.h"  /* PHILIPS Radio frontend */
-#include "r8180_max2820.h" /* MAXIM Radio frontend */
-#include "r8180_gct.h"     /* GCT Radio frontend */
 #include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_rtl8255.h" /* RTL8255 Radio frontend */
 #include "r8180_93cx6.h"   /* Card EEPROM */
 #include "r8180_wx.h"
 #include "r8180_dm.h"
 
-#ifdef CONFIG_RTL8180_PM
-#include "r8180_pm.h"
-#endif
-
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
-
-#ifdef CONFIG_RTL8185B
-//#define CONFIG_RTL8180_IO_MAP
-#endif
+#include "ieee80211/dot11d.h"
 
 #ifndef PCI_VENDOR_ID_BELKIN
 	#define PCI_VENDOR_ID_BELKIN 0x1799
@@ -96,42 +51,11 @@ double __extendsfdf2(float a) {return a;}
 static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
         {
                 .vendor = PCI_VENDOR_ID_REALTEK,
-//                .device = 0x8180,
                 .device = 0x8199,
                 .subvendor = PCI_ANY_ID,
                 .subdevice = PCI_ANY_ID,
                 .driver_data = 0,
         },
-#if 0
-        {
-                .vendor = PCI_VENDOR_ID_BELKIN,
-                .device = 0x6001,
-                .subvendor = PCI_ANY_ID,
-                .subdevice = PCI_ANY_ID,
-                .driver_data = 1,
-        },
-        {       /* Belkin F5D6020 v3 */
-	        .vendor = PCI_VENDOR_ID_BELKIN,
-                .device = 0x6020,
-                .subvendor = PCI_ANY_ID,
-                .subdevice = PCI_ANY_ID,
-                .driver_data = 2,
-        },
-        {       /* D-Link DWL-610 */
-                .vendor = PCI_VENDOR_ID_DLINK,
-                .device = 0x3300,
-                .subvendor = PCI_ANY_ID,
-                .subdevice = PCI_ANY_ID,
-                .driver_data = 3,
-        },
-	{
-		.vendor = PCI_VENDOR_ID_REALTEK,
-		.device = 0x8185,
-		.subvendor = PCI_ANY_ID,
-		.subdevice = PCI_ANY_ID,
-		.driver_data = 4,
-	},
-#endif
         {
                 .vendor = 0,
                 .device = 0,
@@ -144,7 +68,6 @@ static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
 
 static char* ifname = "wlan%d";
 static int hwseqnum = 0;
-//static char* ifname = "ath%d";
 static int hwwep = 0;
 static int channels = 0x3fff;
 
@@ -156,35 +79,12 @@ MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
 MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards");
 
 
-
-/*
-MODULE_PARM(ifname, "s");
-MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
-
-MODULE_PARM(hwseqnum,"i");
-MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
-
-MODULE_PARM(hwwep,"i");
-MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
-
-MODULE_PARM(channels,"i");
-MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
-*/
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
 module_param(ifname, charp, S_IRUGO|S_IWUSR );
 module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
 module_param(hwwep,int, S_IRUGO|S_IWUSR);
 module_param(channels,int, S_IRUGO|S_IWUSR);
-#else
-MODULE_PARM(ifname, "s");
-MODULE_PARM(hwseqnum,"i");
-MODULE_PARM(hwwep,"i");
-MODULE_PARM(channels,"i");
-#endif
 
 MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
-//MODULE_PARM_DESC(devname," Net interface name, ath%d=default");
 MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
 MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
@@ -203,56 +103,73 @@ static void rtl8180_shutdown (struct pci_dev *pdev)
 	pci_disable_device(pdev);
 }
 
-static struct pci_driver rtl8180_pci_driver = {
-	.name		= RTL8180_MODULE_NAME,	          /* Driver name   */
-	.id_table	= rtl8180_pci_id_tbl,	          /* PCI_ID table  */
-	.probe		= rtl8180_pci_probe,	          /* probe fn      */
-	.remove		= __devexit_p(rtl8180_pci_remove),/* remove fn     */
-#ifdef CONFIG_RTL8180_PM
-	.suspend	= rtl8180_suspend,	          /* PM suspend fn */
-	.resume		= rtl8180_resume,                 /* PM resume fn  */
-#else
-	.suspend	= NULL,			          /* PM suspend fn */
-	.resume      	= NULL,			          /* PM resume fn  */
-#endif
-	.shutdown	= rtl8180_shutdown,
-};
+static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
 
+	if (!netif_running(dev))
+		goto out_pci_suspend;
 
+	if (dev->netdev_ops->ndo_stop)
+		dev->netdev_ops->ndo_stop(dev);
 
-#ifdef CONFIG_RTL8180_IO_MAP
+	netif_device_detach(dev);
 
-u8 read_nic_byte(struct net_device *dev, int x)
-{
-        return 0xff&inb(dev->base_addr +x);
+out_pci_suspend:
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+	return 0;
 }
 
-u32 read_nic_dword(struct net_device *dev, int x)
+static int rtl8180_resume(struct pci_dev *pdev)
 {
-        return inl(dev->base_addr +x);
-}
+	struct net_device *dev = pci_get_drvdata(pdev);
+	int err;
+	u32 val;
 
-u16 read_nic_word(struct net_device *dev, int x)
-{
-        return inw(dev->base_addr +x);
-}
+	pci_set_power_state(pdev, PCI_D0);
 
-void write_nic_byte(struct net_device *dev, int x,u8 y)
-{
-        outb(y&0xff,dev->base_addr +x);
-}
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
+				dev->name);
 
-void write_nic_word(struct net_device *dev, int x,u16 y)
-{
-        outw(y,dev->base_addr +x);
-}
+		return err;
+	}
 
-void write_nic_dword(struct net_device *dev, int x,u32 y)
-{
-        outl(y,dev->base_addr +x);
+	pci_restore_state(pdev);
+
+	/*
+	 * Suspend/Resume resets the PCI configuration space, so we have to
+	 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
+	 * from interfering with C3 CPU state. pci_restore_state won't help
+	 * here since it only restores the first 64 bytes pci config header.
+	 */
+	pci_read_config_dword(pdev, 0x40, &val);
+	if ((val & 0x0000ff00) != 0)
+		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+
+	if (!netif_running(dev))
+		goto out;
+
+	if (dev->netdev_ops->ndo_open)
+		dev->netdev_ops->ndo_open(dev);
+
+	netif_device_attach(dev);
+out:
+	return 0;
 }
 
-#else /* RTL_IO_MAP */
+static struct pci_driver rtl8180_pci_driver = {
+	.name		= RTL8180_MODULE_NAME,
+	.id_table	= rtl8180_pci_id_tbl,
+	.probe		= rtl8180_pci_probe,
+	.remove		= __devexit_p(rtl8180_pci_remove),
+	.suspend	= rtl8180_suspend,
+	.resume		= rtl8180_resume,
+	.shutdown	= rtl8180_shutdown,
+};
 
 u8 read_nic_byte(struct net_device *dev, int x)
 {
@@ -287,21 +204,12 @@ void write_nic_word(struct net_device *dev, int x,u16 y)
 	udelay(20);
 }
 
-#endif /* RTL_IO_MAP */
-
-
-
-
-
 inline void force_pci_posting(struct net_device *dev)
 {
 	read_nic_byte(dev,EPROM_CMD);
-#ifndef CONFIG_RTL8180_IO_MAP
 	mb();
-#endif
 }
 
-
 irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs);
 void set_nic_rxring(struct net_device *dev);
 void set_nic_txring(struct net_device *dev);
@@ -309,10 +217,6 @@ static struct net_device_stats *rtl8180_stats(struct net_device *dev);
 void rtl8180_commit(struct net_device *dev);
 void rtl8180_start_tx_beacon(struct net_device *dev);
 
-/****************************************************************************
-   -----------------------------PROCFS STUFF-------------------------
-*****************************************************************************/
-
 static struct proc_dir_entry *rtl8180_proc = NULL;
 
 static int proc_get_registers(char *page, char **start,
@@ -320,33 +224,22 @@ static int proc_get_registers(char *page, char **start,
 			  int *eof, void *data)
 {
 	struct net_device *dev = data;
-//	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
 	int len = 0;
 	int i,n;
-
-	int max=0xff;
+	int max = 0xff;
 
 	/* This dump the current register page */
-	for(n=0;n<=max;)
-	{
-		//printk( "\nD: %2x> ", n);
-		len += snprintf(page + len, count - len,
-			"\nD:  %2x > ",n);
+	for (n = 0; n <= max;) {
+		len += snprintf(page + len, count - len, "\nD:  %2x > ", n);
 
-		for(i=0;i<16 && n<=max;i++,n++)
-		len += snprintf(page + len, count - len,
-			"%2x ",read_nic_byte(dev,n));
-
-		//	printk("%2x ",read_nic_byte(dev,n));
+		for (i = 0; i < 16 && n <= max; i++, n++)
+			len += snprintf(page + len, count - len, "%2x ",
+					read_nic_byte(dev, n));
 	}
 	len += snprintf(page + len, count - len,"\n");
 
-
-
 	*eof = 1;
 	return len;
-
 }
 
 int get_curr_tx_free_desc(struct net_device *dev, int priority);
@@ -355,56 +248,12 @@ static int proc_get_stats_hw(char *page, char **start,
 			  off_t offset, int count,
 			  int *eof, void *data)
 {
-	//struct net_device *dev = data;
-	//struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
 	int len = 0;
-#ifdef 	CONFIG_RTL8185B
 
-#else
-	len += snprintf(page + len, count - len,
-		"NIC int: %lu\n"
-		"Total int: %lu\n"
-		"--------------------\n"
-		"LP avail desc %d\n"
-		"NP avail desc %d\n"
-		"--------------------\n"
-		"LP phys dma addr %x\n"
-		"LP NIC ptr %x\n"
-		"LP virt 32base %x\n"
-		"LP virt 32tail %x\n"
-		"--------------------\n"
-		"NP phys dma addr %x\n"
-		"NP NIC ptr %x\n"
-		"NP virt 32base %x\n"
-		"NP virt 32tail %x\n"
-		"--------------------\n"
-		"BP phys dma addr %x\n"
-		"BP NIC ptr %x\n"
-		"BP virt 32base %x\n"
-		"BP virt 32tail %x\n",
-		priv->stats.ints,
-		priv->stats.shints,
-		get_curr_tx_free_desc(dev,LOW_PRIORITY),
-		get_curr_tx_free_desc(dev,NORM_PRIORITY),
-		(u32)priv->txvipringdma,
-		read_nic_dword(dev,TLPDA),
-		(u32)priv->txvipring,
-		(u32)priv->txvipringtail,
-		(u32)priv->txvopringdma,
-		read_nic_dword(dev,TNPDA),
-		(u32)priv->txvopring,
-		(u32)priv->txvopringtail,
-		(u32)priv->txbeaconringdma,
-		read_nic_dword(dev,TBDA),
-		(u32)priv->txbeaconring,
-		(u32)priv->txbeaconringtail);
-#endif
 	*eof = 1;
 	return len;
 }
 
-
 static int proc_get_stats_rx(char *page, char **start,
 			  off_t offset, int count,
 			  int *eof, void *data)
@@ -415,30 +264,6 @@ static int proc_get_stats_rx(char *page, char **start,
 	int len = 0;
 
 	len += snprintf(page + len, count - len,
-	/*	"RX descriptor not available: %lu\n"
-		"RX incomplete (missing last descriptor): %lu\n"
-		"RX not data: %lu\n"
-		//"RX descriptor pointer reset: %lu\n"
-		"RX descriptor pointer lost: %lu\n"
-		//"RX pointer workaround: %lu\n"
-		"RX error int: %lu\n"
-		"RX fifo overflow: %lu\n"
-		"RX int: %lu\n"
-		"RX packet: %lu\n"
-		"RX bytes: %lu\n"
-		"RX DMA fail: %lu\n",
-		priv->stats.rxrdu,
-		priv->stats.rxnolast,
-		priv->stats.rxnodata,
-		//priv->stats.rxreset,
-		priv->stats.rxnopointer,
-		//priv->stats.rxwrkaround,
-		priv->stats.rxerr,
-		priv->stats.rxoverflow,
-		priv->stats.rxint,
-		priv->ieee80211->stats.rx_packets,
-		priv->ieee80211->stats.rx_bytes,
-		priv->stats.rxdmafail  */
 		"RX OK: %lu\n"
 		"RX Retry: %lu\n"
 		"RX CRC Error(0-500): %lu\n"
@@ -457,82 +282,6 @@ static int proc_get_stats_rx(char *page, char **start,
 	return len;
 }
 
-#if 0
-static int proc_get_stats_ieee(char *page, char **start,
-			  off_t offset, int count,
-			  int *eof, void *data)
-{
-	struct net_device *dev = data;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	int len = 0;
-
-	len += snprintf(page + len, count - len,
-		"TXed association requests: %u\n"
-		"TXed authentication requests: %u\n"
-		"RXed successful association response: %u\n"
-		"RXed failed association response: %u\n"
-		"RXed successful authentication response: %u\n"
-		"RXed failed authentication response: %u\n"
-		"Association requests without response: %u\n"
-		"Authentication requests without response: %u\n"
-		"TX probe response: %u\n"
-		"RX probe request: %u\n"
-		"TX probe request: %lu\n"
-		"RX authentication requests: %lu\n"
-		"RX association requests: %lu\n"
-		"Reassociations: %lu\n",
-		priv->ieee80211->ieee_stats.tx_ass,
-		priv->ieee80211->ieee_stats.tx_aut,
-		priv->ieee80211->ieee_stats.rx_ass_ok,
-		priv->ieee80211->ieee_stats.rx_ass_err,
-		priv->ieee80211->ieee_stats.rx_aut_ok,
-		priv->ieee80211->ieee_stats.rx_aut_err,
-		priv->ieee80211->ieee_stats.ass_noresp,
-		priv->ieee80211->ieee_stats.aut_noresp,
-		priv->ieee80211->ieee_stats.tx_probe,
-		priv->ieee80211->ieee_stats.rx_probe,
-		priv->ieee80211->ieee_stats.tx_probe_rq,
-		priv->ieee80211->ieee_stats.rx_auth_rq,
-		priv->ieee80211->ieee_stats.rx_assoc_rq,
-		priv->ieee80211->ieee_stats.reassoc);
-
-	*eof = 1;
-	return len;
-}
-#endif
-#if 0
-static int proc_get_stats_ap(char *page, char **start,
-			  off_t offset, int count,
-			  int *eof, void *data)
-{
-	struct net_device *dev = data;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct mac_htable_t *list;
-	int i;
-	int len = 0;
-
-	if(priv->ieee80211->iw_mode != IW_MODE_MASTER){
-		len += snprintf(page + len, count - len,
-		"Card is not acting as AP...\n"
-		);
-	}else{
-		len += snprintf(page + len, count - len,
-		"List of associated STA:\n"
-		);
-
-		for(i=0;i<MAC_HTABLE_ENTRY;i++)
-			for (list = priv->ieee80211->assoc_htable[i]; list!=NULL; list = list->next){
-				len += snprintf(page + len, count - len,
-					MACSTR"\n",MAC2STR(list->adr));
-			}
-
-	}
-	*eof = 1;
-	return len;
-}
-#endif
-
 static int proc_get_stats_tx(char *page, char **start,
 			  off_t offset, int count,
 			  int *eof, void *data)
@@ -545,36 +294,6 @@ static int proc_get_stats_tx(char *page, char **start,
 
 	totalOK=priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint;
 	len += snprintf(page + len, count - len,
-	/*	"TX normal priority ok int: %lu\n"
-		"TX normal priority error int: %lu\n"
-		"TX high priority ok int: %lu\n"
-		"TX high priority failed error int: %lu\n"
-		"TX low priority ok int: %lu\n"
-		"TX low priority failed error int: %lu\n"
-		"TX bytes: %lu\n"
-		"TX packets: %lu\n"
-		"TX queue resume: %lu\n"
-		"TX queue stopped?: %d\n"
-		"TX fifo overflow: %lu\n"
-		//"SW TX stop: %lu\n"
-		//"SW TX wake: %lu\n"
-		"TX beacon: %lu\n"
-		"TX beacon aborted: %lu\n",
-		priv->stats.txnpokint,
-		priv->stats.txnperr,
-		priv->stats.txhpokint,
-		priv->stats.txhperr,
-		priv->stats.txlpokint,
-		priv->stats.txlperr,
-		priv->ieee80211->stats.tx_bytes,
-		priv->ieee80211->stats.tx_packets,
-		priv->stats.txresumed,
-		netif_queue_stopped(dev),
-		priv->stats.txoverflow,
-		//priv->ieee80211->ieee_stats.swtxstop,
-		//priv->ieee80211->ieee_stats.swtxawake,
-		priv->stats.txbeacon,
-		priv->stats.txbeaconerr  */
 		"TX OK: %lu\n"
 		"TX Error: %lu\n"
 		"TX Retry: %lu\n"
@@ -591,36 +310,17 @@ static int proc_get_stats_tx(char *page, char **start,
 	return len;
 }
 
-
-#if WIRELESS_EXT < 17
-static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
-{
-       struct r8180_priv *priv = ieee80211_priv(dev);
-
-       return &priv->wstats;
-}
-#endif
 void rtl8180_proc_module_init(void)
 {
 	DMESG("Initializing proc filesystem");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-        rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, proc_net);
-#else
         rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, init_net.proc_net);
-#endif
 }
 
-
 void rtl8180_proc_module_remove(void)
 {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-        remove_proc_entry(RTL8180_MODULE_NAME, proc_net);
-#else
         remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
-#endif
 }
 
-
 void rtl8180_proc_remove_one(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
@@ -628,19 +328,17 @@ void rtl8180_proc_remove_one(struct net_device *dev)
 		remove_proc_entry("stats-hw", priv->dir_dev);
 		remove_proc_entry("stats-tx", priv->dir_dev);
 		remove_proc_entry("stats-rx", priv->dir_dev);
-//		remove_proc_entry("stats-ieee", priv->dir_dev);
-//		remove_proc_entry("stats-ap", priv->dir_dev);
 		remove_proc_entry("registers", priv->dir_dev);
 		remove_proc_entry(dev->name, rtl8180_proc);
 		priv->dir_dev = NULL;
 	}
 }
 
-
 void rtl8180_proc_init_one(struct net_device *dev)
 {
 	struct proc_dir_entry *e;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
 	priv->dir_dev = rtl8180_proc;
 	if (!priv->dir_dev) {
 		DMESGE("Unable to initialize /proc/net/r8180/%s\n",
@@ -650,7 +348,6 @@ void rtl8180_proc_init_one(struct net_device *dev)
 
 	e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_hw, dev);
-
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/r8180/%s/stats-hw\n",
@@ -659,7 +356,6 @@ void rtl8180_proc_init_one(struct net_device *dev)
 
 	e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_rx, dev);
-
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/r8180/%s/stats-rx\n",
@@ -669,45 +365,21 @@ void rtl8180_proc_init_one(struct net_device *dev)
 
 	e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_tx, dev);
-
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/r8180/%s/stats-tx\n",
 		      dev->name);
 	}
-	#if 0
-	e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
-				   priv->dir_dev, proc_get_stats_ieee, dev);
-
-	if (!e) {
-		DMESGE("Unable to initialize "
-		      "/proc/net/rtl8180/%s/stats-ieee\n",
-		      dev->name);
-	}
-	#endif
-	#if 0
-	e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
-				   priv->dir_dev, proc_get_stats_ap, dev);
-
-	if (!e) {
-		DMESGE("Unable to initialize "
-		      "/proc/net/rtl8180/%s/stats-ap\n",
-		      dev->name);
-	}
-	#endif
 
 	e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_registers, dev);
-
 	if (!e) {
 		DMESGE("Unable to initialize "
 		      "/proc/net/r8180/%s/registers\n",
 		      dev->name);
 	}
 }
-/****************************************************************************
-   -----------------------------MISC STUFF-------------------------
-*****************************************************************************/
+
 /*
   FIXME: check if we can use some standard already-existent
   data type+functions in kernel
@@ -716,10 +388,6 @@ void rtl8180_proc_init_one(struct net_device *dev)
 short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
 		struct buffer **bufferhead)
 {
-#ifdef DEBUG_RING
-	DMESG("adding buffer to TX/RX struct");
-#endif
-
         struct buffer *tmp;
 
 	if(! *buffer){
@@ -751,7 +419,6 @@ short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
 	return 0;
 }
 
-
 void buffer_free(struct net_device *dev,struct buffer **buffer,int len,short
 consistent)
 {
@@ -759,14 +426,12 @@ consistent)
 	struct buffer *tmp,*next;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct pci_dev *pdev=priv->pdev;
-	//int i;
 
-	if(! *buffer) return;
+	if (!*buffer)
+		return;
 
-	/*for(tmp=*buffer; tmp->next != *buffer; tmp=tmp->next)
+	tmp = *buffer;
 
-	*/
-	tmp=*buffer;
 	do{
 		next=tmp->next;
 		if(consistent){
@@ -785,7 +450,6 @@ consistent)
 	*buffer=NULL;
 }
 
-
 void print_buffer(u32 *buffer, int len)
 {
 	int i;
@@ -804,7 +468,6 @@ void print_buffer(u32 *buffer, int len)
 	printk("\n");
 }
 
-
 int get_curr_tx_free_desc(struct net_device *dev, int priority)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -841,39 +504,33 @@ int get_curr_tx_free_desc(struct net_device *dev, int priority)
 			return -1;
 	}
 
-	//DMESG("%x %x", head, tail);
-
-	/* FIXME FIXME FIXME FIXME */
-
-#if 0
-	if( head <= tail ) return priv->txringcount-1 - (tail - head)/8;
-	return (head - tail)/8/4;
-#else
-	if( head <= tail )
+	if (head <= tail)
 		ret = priv->txringcount - (tail - head)/8;
 	else
 		ret = (head - tail)/8;
 
-	if(ret > priv->txringcount ) DMESG("BUG");
+	if (ret > priv->txringcount)
+		DMESG("BUG");
+
 	return ret;
-#endif
 }
 
-
 short check_nic_enought_desc(struct net_device *dev, int priority)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device *ieee = netdev_priv(dev);
-
 	int requiredbyte, required;
+
 	requiredbyte = priv->ieee80211->fts + sizeof(struct ieee80211_header_data);
 
-	if(ieee->current_network.QoS_Enable) {
+	if (ieee->current_network.QoS_Enable)
 		requiredbyte += 2;
-	};
 
 	required = requiredbyte / (priv->txbuffsize-4);
-	if (requiredbyte % priv->txbuffsize) required++;
+
+	if (requiredbyte % priv->txbuffsize)
+		required++;
+
 	/* for now we keep two free descriptor as a safety boundary
 	 * between the tail and the head
 	 */
@@ -881,172 +538,12 @@ short check_nic_enought_desc(struct net_device *dev, int priority)
 	return (required+2 < get_curr_tx_free_desc(dev,priority));
 }
 
-
-/* This function is only for debuging purpose */
-void check_tx_ring(struct net_device *dev, int pri)
-{
-	static int maxlog =3;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u32* tmp;
-	struct buffer *buf;
-	int i;
-	int nic;
-	u32* tail;
-	u32* head;
-	u32* begin;
-	u32 nicbegin;
-	struct buffer* buffer;
-
-	maxlog --;
-	if (maxlog <0 ) return;
-
-	switch(pri) {
-	case MANAGE_PRIORITY:
-		tail = priv->txmapringtail;
-		begin = priv->txmapring;
-		head = priv->txmapringhead;
-		nic = read_nic_dword(dev,TX_MANAGEPRIORITY_RING_ADDR);
-		buffer = priv->txmapbufs;
-		nicbegin = priv->txmapringdma;
-		break;
-
-
-	case BK_PRIORITY:
-		tail = priv->txbkpringtail;
-		begin = priv->txbkpring;
-		head = priv->txbkpringhead;
-		nic = read_nic_dword(dev,TX_BKPRIORITY_RING_ADDR);
-		buffer = priv->txbkpbufs;
-		nicbegin = priv->txbkpringdma;
-		break;
-
-	case BE_PRIORITY:
-		tail = priv->txbepringtail;
-		begin = priv->txbepring;
-		head = priv->txbepringhead;
-		nic = read_nic_dword(dev,TX_BEPRIORITY_RING_ADDR);
-		buffer = priv->txbepbufs;
-		nicbegin = priv->txbepringdma;
-		break;
-
-	case VI_PRIORITY:
-		tail = priv->txvipringtail;
-		begin = priv->txvipring;
-		head = priv->txvipringhead;
-		nic = read_nic_dword(dev,TX_VIPRIORITY_RING_ADDR);
-		buffer = priv->txvipbufs;
-		nicbegin = priv->txvipringdma;
-		break;
-
-
-	case VO_PRIORITY:
-		tail = priv->txvopringtail;
-		begin = priv->txvopring;
-		head = priv->txvopringhead;
-		nic = read_nic_dword(dev,TX_VOPRIORITY_RING_ADDR);
-		buffer = priv->txvopbufs;
-		nicbegin = priv->txvopringdma;
-		break;
-
-	case HI_PRIORITY:
-		tail = priv->txhpringtail;
-		begin = priv->txhpring;
-		head = priv->txhpringhead;
-		nic = read_nic_dword(dev,TX_HIGHPRIORITY_RING_ADDR);
-		buffer = priv->txhpbufs;
-		nicbegin = priv->txhpringdma;
-		break;
-
-	default:
-		return ;
-		break;
-	}
-
-	if(!priv->txvopbufs)
-		DMESGE ("NIC TX ack, but TX queue corrupted!");
-	else{
-
-		for(i=0,buf=buffer, tmp=begin;
-			tmp<begin+(priv->txringcount)*8;
-			tmp+=8,buf=buf->next,i++)
-
-			DMESG("BUF%d %s %x %s. Next : %x",i,
-			      *tmp & (1<<31) ? "filled" : "empty",
-			      *(buf->buf),
-			      *tmp & (1<<15)? "ok": "err", *(tmp+4));
-	}
-
-	return;
-}
-
-
-
-/* this function is only for debugging purpose */
-void check_rxbuf(struct net_device *dev)
-{
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u32* tmp;
-	struct buffer *buf;
-	u8 rx_desc_size;
-
-#ifdef CONFIG_RTL8185B
-	rx_desc_size = 8;
-#else
-	rx_desc_size = 4;
-#endif
-
-	if(!priv->rxbuffer)
-		DMESGE ("NIC RX ack, but RX queue corrupted!");
-
-	else{
-
-		for(buf=priv->rxbuffer, tmp=priv->rxring;
-		    tmp < priv->rxring+(priv->rxringcount)*rx_desc_size;
-		    tmp+=rx_desc_size, buf=buf->next)
-
-			DMESG("BUF %s %x",
-			      *tmp & (1<<31) ? "empty" : "filled",
-			      *(buf->buf));
-	}
-
-	return;
-}
-
-
-void dump_eprom(struct net_device *dev)
-{
-	int i;
-	for(i=0; i<63; i++)
-		DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
-}
-
-
-void rtl8180_dump_reg(struct net_device *dev)
-{
-	int i;
-	int n;
-	int max=0xff;
-
-	DMESG("Dumping NIC register map");
-
-	for(n=0;n<=max;)
-	{
-		printk( "\nD: %2x> ", n);
-		for(i=0;i<16 && n<=max;i++,n++)
-			printk("%2x ",read_nic_byte(dev,n));
-	}
-	printk("\n");
-}
-
-
 void fix_tx_fifo(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	u32 *tmp;
 	int i;
-#ifdef DEBUG_TX_ALLOC
-	DMESG("FIXING TX FIFOs");
-#endif
+
 	for (tmp=priv->txmapring, i=0;
 	     i < priv->txringcount;
 	     tmp+=8, i++){
@@ -1087,9 +584,7 @@ void fix_tx_fifo(struct net_device *dev)
 	     tmp+=8, i++){
 		*tmp = *tmp &~ (1<<31);
 	}
-#ifdef DEBUG_TX_ALLOC
-	DMESG("TX FIFOs FIXED");
-#endif
+
 	priv->txmapringtail = priv->txmapring;
 	priv->txmapringhead = priv->txmapring;
 	priv->txmapbufstail = priv->txmapbufs;
@@ -1122,7 +617,6 @@ void fix_tx_fifo(struct net_device *dev)
 	priv->ack_tx_to_ieee = 0;
 }
 
-
 void fix_rx_fifo(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
@@ -1130,16 +624,7 @@ void fix_rx_fifo(struct net_device *dev)
 	struct buffer *rxbuf;
 	u8 rx_desc_size;
 
-#ifdef CONFIG_RTL8185B
 	rx_desc_size = 8; // 4*8 = 32 bytes
-#else
-	rx_desc_size = 4;
-#endif
-
-#ifdef DEBUG_RXALLOC
-	DMESG("FIXING RX FIFO");
-	check_rxbuf(dev);
-#endif
 
 	for (tmp=priv->rxring, rxbuf=priv->rxbufferhead;
 	     (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size);
@@ -1150,50 +635,40 @@ void fix_rx_fifo(struct net_device *dev)
 		*tmp |= (1<<31);
 	}
 
-#ifdef DEBUG_RXALLOC
-	DMESG("RX FIFO FIXED");
-	check_rxbuf(dev);
-#endif
-
 	priv->rxringtail=priv->rxring;
 	priv->rxbuffer=priv->rxbufferhead;
 	priv->rx_skb_complete=1;
 	set_nic_rxring(dev);
 }
 
-
-/****************************************************************************
-      ------------------------------HW STUFF---------------------------
-*****************************************************************************/
-
 unsigned char QUALITY_MAP[] = {
-  0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61,
-  0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c,
-  0x5b, 0x5a, 0x59, 0x57, 0x56, 0x54, 0x52, 0x4f,
-  0x4c, 0x49, 0x45, 0x41, 0x3c, 0x37, 0x31, 0x29,
-  0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-  0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-  0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e,
-  0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 0x19, 0x19,
-  0x18, 0x17, 0x16, 0x15, 0x14, 0x12, 0x11, 0x0f,
-  0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x01, 0x00
+	0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61,
+	0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c,
+	0x5b, 0x5a, 0x59, 0x57, 0x56, 0x54, 0x52, 0x4f,
+	0x4c, 0x49, 0x45, 0x41, 0x3c, 0x37, 0x31, 0x29,
+	0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+	0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
+	0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e,
+	0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 0x19, 0x19,
+	0x18, 0x17, 0x16, 0x15, 0x14, 0x12, 0x11, 0x0f,
+	0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x01, 0x00
 };
 
 unsigned char STRENGTH_MAP[] = {
-  0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
-  0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
-  0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
-  0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
-  0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
-  0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
-  0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
-  0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
-  0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
-  0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00
+	0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
+	0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
+	0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
+	0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
+	0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
+	0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
+	0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
+	0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
+	0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
+	0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00
 };
 
-void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual){
-	//void Mlme_UpdateRssiSQ(struct net_device *dev, u8 *rssi, u8 *qual){
+void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual)
+{
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	u32 temp;
 	u32 temp2;
@@ -1289,8 +764,6 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual){
 			}
 		}
 		break;
-
-	/* case 4 */
 	case RFCHIPID_MAXIM:
 		lsb = temp2 & 1;
 		temp2 &= 0x7e;
@@ -1315,38 +788,27 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual){
 	return;
 }
 
-
 void rtl8180_irq_enable(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
 	priv->irq_enabled = 1;
-/*
-	write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
-	INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
-	INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
-	INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
-*/
 	write_nic_word(dev,INTA_MASK, priv->irq_mask);
 }
 
-
 void rtl8180_irq_disable(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
-#ifdef CONFIG_RTL8185B
 	write_nic_dword(dev,IMR,0);
-#else
-	write_nic_word(dev,INTA_MASK,0);
-#endif
 	force_pci_posting(dev);
 	priv->irq_enabled = 0;
 }
 
-
 void rtl8180_set_mode(struct net_device *dev,int mode)
 {
 	u8 ecmd;
+
 	ecmd=read_nic_byte(dev, EPROM_CMD);
 	ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
 	ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
@@ -1388,28 +850,21 @@ void rtl8180_update_msr(struct net_device *dev)
 
 	write_nic_byte(dev, MSR, msr);
 	write_nic_dword(dev, RX_CONF, rxconf);
-
 }
 
-
-
 void rtl8180_set_chan(struct net_device *dev,short ch)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
-	if((ch > 14) || (ch < 1))
-	{
+	if ((ch > 14) || (ch < 1)) {
 		printk("In %s: Invalid chnanel %d\n", __func__, ch);
 		return;
 	}
 
 	priv->chan=ch;
-	//printk("in %s:channel is %d\n",__func__,ch);
 	priv->rf_set_chan(dev,priv->chan);
-
 }
 
-
 void rtl8180_rx_enable(struct net_device *dev)
 {
 	u8 cmd;
@@ -1423,8 +878,8 @@ void rtl8180_rx_enable(struct net_device *dev)
 	rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
 	rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
 	rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
-//	rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
-	if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
+	if (dev->flags & IFF_PROMISC)
+		DMESG("NIC in promisc mode");
 
 	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
 	   dev->flags & IFF_PROMISC){
@@ -1435,11 +890,6 @@ void rtl8180_rx_enable(struct net_device *dev)
 			rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
 	}
 
-	/*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
-		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
-		rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
-	}*/
-
 	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
 		rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
 		rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
@@ -1449,84 +899,61 @@ void rtl8180_rx_enable(struct net_device *dev)
 	if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
 		rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
 
-	//if(!priv->card_8185){
-		rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
-		rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
-	//}
+	rxconf = rxconf & ~RX_FIFO_THRESHOLD_MASK;
+	rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE << RX_FIFO_THRESHOLD_SHIFT);
 
 	rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
 	rxconf = rxconf &~ MAX_RX_DMA_MASK;
 	rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
 
-	//if(!priv->card_8185)
-		rxconf = rxconf | RCR_ONLYERLPKT;
+	rxconf = rxconf | RCR_ONLYERLPKT;
 
 	rxconf = rxconf &~ RCR_CS_MASK;
-	if(!priv->card_8185)
+
+	if (!priv->card_8185)
 		rxconf |= (priv->rcr_csense<<RCR_CS_SHIFT);
-//	rxconf &=~ 0xfff00000;
-//	rxconf |= 0x90100000;//9014f76f;
+
 	write_nic_dword(dev, RX_CONF, rxconf);
 
 	fix_rx_fifo(dev);
 
-#ifdef DEBUG_RX
-	DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
-#endif
 	cmd=read_nic_byte(dev,CMD);
 	write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
-
-	/* In rtl8139 driver seems that DMA threshold has to be written
-	 *  after enabling RX, so we rewrite RX_CONFIG register
-	 */
-	//mdelay(100);
-//	write_nic_dword(dev, RX_CONF, rxconf);
-
 }
 
-
 void set_nic_txring(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-//		DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
 
 	write_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR, priv->txmapringdma);
-//		DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
 	write_nic_dword(dev, TX_BKPRIORITY_RING_ADDR, priv->txbkpringdma);
-//		DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
 	write_nic_dword(dev, TX_BEPRIORITY_RING_ADDR, priv->txbepringdma);
-//		DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
 	write_nic_dword(dev, TX_VIPRIORITY_RING_ADDR, priv->txvipringdma);
-//		DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
 	write_nic_dword(dev, TX_VOPRIORITY_RING_ADDR, priv->txvopringdma);
-//		DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
 	write_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR, priv->txhpringdma);
-//		DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
-
 	write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
 }
 
-
 void rtl8180_conttx_enable(struct net_device *dev)
 {
 	u32 txconf;
+
 	txconf = read_nic_dword(dev,TX_CONF);
 	txconf = txconf &~ TX_LOOPBACK_MASK;
 	txconf = txconf | (TX_LOOPBACK_CONTINUE <<TX_LOOPBACK_SHIFT);
 	write_nic_dword(dev,TX_CONF,txconf);
 }
 
-
 void rtl8180_conttx_disable(struct net_device *dev)
 {
 	u32 txconf;
+
 	txconf = read_nic_dword(dev,TX_CONF);
 	txconf = txconf &~ TX_LOOPBACK_MASK;
 	txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
 	write_nic_dword(dev,TX_CONF,txconf);
 }
 
-
 void rtl8180_tx_enable(struct net_device *dev)
 {
 	u8 cmd;
@@ -1534,12 +961,10 @@ void rtl8180_tx_enable(struct net_device *dev)
 	u8 byte;
 	u32 txconf;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	txconf= read_nic_dword(dev,TX_CONF);
-
-
-	if(priv->card_8185){
 
+	txconf = read_nic_dword(dev, TX_CONF);
 
+	if (priv->card_8185) {
 		byte = read_nic_byte(dev,CW_CONF);
 		byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
 		byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
@@ -1550,26 +975,12 @@ void rtl8180_tx_enable(struct net_device *dev)
 		tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
 		tx_agc_ctl |=(1<<TX_AGC_CTL_FEEDBACK_ANT);
 		write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
-		/*
-		write_nic_word(dev, 0x5e, 0x01);
-		force_pci_posting(dev);
-		mdelay(1);
-		write_nic_word(dev, 0xfe, 0x10);
-		force_pci_posting(dev);
-		mdelay(1);
-		write_nic_word(dev, 0x5e, 0x00);
-		force_pci_posting(dev);
-		mdelay(1);
-		*/
 		write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
 	}
 
-	if(priv->card_8185){
-
+	if (priv->card_8185)
 		txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
-
-	}else{
-
+	else {
 		if(hwseqnum)
 			txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
 		else
@@ -1584,80 +995,52 @@ void rtl8180_tx_enable(struct net_device *dev)
 	txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
 	txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
 
-	if(priv->card_8185){
-		if(priv->hw_plcp_len)
+	if (priv->card_8185) {
+		if (priv->hw_plcp_len)
 			txconf = txconf &~ TCR_PLCP_LEN;
 		else
 			txconf = txconf | TCR_PLCP_LEN;
-	}else{
+	} else
 		txconf = txconf &~ TCR_SAT;
-	}
+
 	txconf = txconf &~ TCR_MXDMA_MASK;
 	txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
 	txconf = txconf | TCR_CWMIN;
 	txconf = txconf | TCR_DISCW;
 
-//	if(priv->ieee80211->hw_wep)
-//		txconf=txconf &~ (1<<TX_NOICV_SHIFT);
-//	else
-		txconf=txconf | (1<<TX_NOICV_SHIFT);
+	txconf = txconf | (1 << TX_NOICV_SHIFT);
 
 	write_nic_dword(dev,TX_CONF,txconf);
 
-
 	fix_tx_fifo(dev);
 
-#ifdef DEBUG_TX
-	DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
-#endif
-
 	cmd=read_nic_byte(dev,CMD);
 	write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
 
-//	mdelay(100);
 	write_nic_dword(dev,TX_CONF,txconf);
-//	#endif
-/*
-	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
-	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
-	*/
 }
 
-
 void rtl8180_beacon_tx_enable(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-#ifdef CONFIG_RTL8185B
 	priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);
 	write_nic_byte(dev,TPPollStop, priv->dma_poll_mask);
-#else
-	priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-#endif
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 }
 
-
 void rtl8180_beacon_tx_disable(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-#ifdef CONFIG_RTL8185B
 	priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ;
 	write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
-#else
-	priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-#endif
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 
 }
 
-
 void rtl8180_rtx_disable(struct net_device *dev)
 {
 	u8 cmd;
@@ -1668,42 +1051,11 @@ void rtl8180_rtx_disable(struct net_device *dev)
 		       ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
 	force_pci_posting(dev);
 	mdelay(10);
-	/*while (read_nic_byte(dev,CMD) & (1<<CMD_RX_ENABLE_SHIFT))
-	  udelay(10);
-	*/
 
 	if(!priv->rx_skb_complete)
 		dev_kfree_skb_any(priv->rx_skb);
 }
 
-#if 0
-int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
-{
-	int i;
-	u32 *tmp;
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-	priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
-					  sizeof(u32)*8*count,
-					  &priv->txbeaconringdma);
-	if (!priv->txbeaconring) return -1;
-	for (tmp=priv->txbeaconring,i=0;i<count;i++){
-		*tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
-		/*
-		*(tmp+2) = (u32)dma_tmp;
-		*(tmp+3) = bufsize;
-		*/
-		if(i+1<count)
-			*(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
-		else
-			*(tmp+4) = (u32)priv->txbeaconringdma;
-
-		tmp=tmp+8;
-	}
-	return 0;
-}
-#endif
-
 short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
 			 int addr)
 {
@@ -1721,51 +1073,30 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
 	}
 	desc = (u32*)pci_alloc_consistent(pdev,
 					  sizeof(u32)*8*count+256, &dma_desc);
-	if(desc==NULL) return -1;
-	if(dma_desc & 0xff){
+	if (desc == NULL)
+		return -1;
 
+	if (dma_desc & 0xff)
 		/*
 		 * descriptor's buffer must be 256 byte aligned
 		 * we shouldn't be here, since we set DMA mask !
 		 */
 		WARN(1, "DMA buffer is not aligned\n");
-	}
-	tmp=desc;
-	for (i=0;i<count;i++)
-	{
-		buf = (void*)pci_alloc_consistent(pdev,bufsize,&dma_tmp);
-		if (buf == NULL) return -ENOMEM;
 
-		switch(addr) {
-#if 0
-		case TX_NORMPRIORITY_RING_ADDR:
-			if(-1 == buffer_add(&(priv->txnpbufs),buf,dma_tmp,NULL)){
-				DMESGE("Unable to allocate mem for buffer NP");
-				return -ENOMEM;
-			}
-			break;
+	tmp = desc;
 
-		case TX_LOWPRIORITY_RING_ADDR:
-			if(-1 == buffer_add(&(priv->txlpbufs),buf,dma_tmp,NULL)){
-				DMESGE("Unable to allocate mem for buffer LP");
-				return -ENOMEM;
-			}
-			break;
+	for (i = 0; i < count; i++) {
+		buf = (void *)pci_alloc_consistent(pdev, bufsize, &dma_tmp);
+		if (buf == NULL)
+			return -ENOMEM;
 
-		case TX_HIGHPRIORITY_RING_ADDR:
-			if(-1 == buffer_add(&(priv->txhpbufs),buf,dma_tmp,NULL)){
-				DMESGE("Unable to allocate mem for buffer HP");
-				return -ENOMEM;
-			}
-			break;
-#else
+		switch(addr) {
 		case TX_MANAGEPRIORITY_RING_ADDR:
 			if(-1 == buffer_add(&(priv->txmapbufs),buf,dma_tmp,NULL)){
 				DMESGE("Unable to allocate mem for buffer NP");
 				return -ENOMEM;
 			}
 			break;
-
 		case TX_BKPRIORITY_RING_ADDR:
 			if(-1 == buffer_add(&(priv->txbkpbufs),buf,dma_tmp,NULL)){
 				DMESGE("Unable to allocate mem for buffer LP");
@@ -1778,7 +1109,6 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
 				return -ENOMEM;
 			}
 			break;
-
 		case TX_VIPRIORITY_RING_ADDR:
 			if(-1 == buffer_add(&(priv->txvipbufs),buf,dma_tmp,NULL)){
 				DMESGE("Unable to allocate mem for buffer LP");
@@ -1791,7 +1121,6 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
 				return -ENOMEM;
 			}
 			break;
-#endif
 		case TX_HIGHPRIORITY_RING_ADDR:
 			if(-1 == buffer_add(&(priv->txhpbufs),buf,dma_tmp,NULL)){
 				DMESGE("Unable to allocate mem for buffer HP");
@@ -1822,32 +1151,26 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
 		priv->txmapringdma=dma_desc;
 		priv->txmapring=desc;
 		break;
-
 	case TX_BKPRIORITY_RING_ADDR:
 		priv->txbkpringdma=dma_desc;
 		priv->txbkpring=desc;
 		break;
-
 	case TX_BEPRIORITY_RING_ADDR:
 		priv->txbepringdma=dma_desc;
 		priv->txbepring=desc;
 		break;
-
 	case TX_VIPRIORITY_RING_ADDR:
 		priv->txvipringdma=dma_desc;
 		priv->txvipring=desc;
 		break;
-
 	case TX_VOPRIORITY_RING_ADDR:
 		priv->txvopringdma=dma_desc;
 		priv->txvopring=desc;
 		break;
-
 	case TX_HIGHPRIORITY_RING_ADDR:
 		priv->txhpringdma=dma_desc;
 		priv->txhpring=desc;
 		break;
-
 	case TX_BEACON_RING_ADDR:
 		priv->txbeaconringdma=dma_desc;
 		priv->txbeaconring=desc;
@@ -1855,17 +1178,11 @@ short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
 
 	}
 
-#ifdef DEBUG_TX
-	DMESG("Tx dma physical address: %x",dma_desc);
-#endif
-
 	return 0;
 }
 
-
 void free_tx_desc_rings(struct net_device *dev)
 {
-
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct pci_dev *pdev=priv->pdev;
 	int count = priv->txringcount;
@@ -1900,41 +1217,18 @@ void free_tx_desc_rings(struct net_device *dev)
 	buffer_free(dev,&(priv->txbeaconbufs),priv->txbuffsize,1);
 }
 
-#if 0
-void free_beacon_desc_ring(struct net_device *dev,int count)
-{
-
-	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	struct pci_dev *pdev=priv->pdev;
-
-	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
-			    priv->txbeaconring, priv->txbeaconringdma);
-
-	if (priv->beacon_buf)
-		pci_free_consistent(priv->pdev,
-			priv->master_beaconsize,priv->beacon_buf,priv->beacondmabuf);
-
-}
-#endif
 void free_rx_desc_ring(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct pci_dev *pdev = priv->pdev;
-
 	int count = priv->rxringcount;
 
-#ifdef CONFIG_RTL8185B
 	pci_free_consistent(pdev, sizeof(u32)*8*count+256,
 			    priv->rxring, priv->rxringdma);
-#else
-	pci_free_consistent(pdev, sizeof(u32)*4*count+256,
-			    priv->rxring, priv->rxringdma);
-#endif
 
 	buffer_free(dev,&(priv->rxbuffer),priv->rxbuffersize,0);
 }
 
-
 short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
 {
 	int i;
@@ -1946,11 +1240,7 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
 	void *buf;
 	u8 rx_desc_size;
 
-#ifdef CONFIG_RTL8185B
 	rx_desc_size = 8; // 4*8 = 32 bytes
-#else
-	rx_desc_size = 4;
-#endif
 
 	if((bufsize & 0xfff) != bufsize){
 		DMESGE ("RX buffer allocation too large");
@@ -1960,21 +1250,18 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
 	desc = (u32*)pci_alloc_consistent(pdev,sizeof(u32)*rx_desc_size*count+256,
 					  &dma_desc);
 
-	if(dma_desc & 0xff){
-
+	if (dma_desc & 0xff)
 		/*
 		 * descriptor's buffer must be 256 byte aligned
 		 * should never happen since we specify the DMA mask
 		 */
 		WARN(1, "DMA buffer is not aligned\n");
-	}
 
 	priv->rxring=desc;
 	priv->rxringdma=dma_desc;
 	tmp=desc;
 
-	for (i=0;i<count;i++){
-
+	for (i = 0; i < count; i++) {
 		if ((buf= kmalloc(bufsize * sizeof(u8),GFP_ATOMIC)) == NULL){
 			DMESGE("Failed to kmalloc RX buffer");
 			return -1;
@@ -1983,12 +1270,6 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
 		dma_tmp = pci_map_single(pdev,buf,bufsize * sizeof(u8),
 					 PCI_DMA_FROMDEVICE);
 
-#ifdef DEBUG_ZERO_RX
-		int j;
-		for(j=0;j<bufsize;j++) ((u8*)buf)[i] = 0;
-#endif
-
-		//buf = (void*)pci_alloc_consistent(pdev,bufsize,&dma_tmp);
 		if(-1 == buffer_add(&(priv->rxbuffer), buf,dma_tmp,
 			   &(priv->rxbufferhead))){
 			   DMESGE("Unable to allocate mem RX buf");
@@ -1999,21 +1280,11 @@ short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
 		*(tmp+2) = (u32)dma_tmp;
 		*tmp = *tmp |(1<<31); // descriptor void, owned by the NIC
 
-#ifdef DEBUG_RXALLOC
-		DMESG("Alloc %x size buffer, DMA mem @ %x, virtual mem @ %x",
-		      (u32)(bufsize&0xfff), (u32)dma_tmp, (u32)buf);
-#endif
-
 		tmp=tmp+rx_desc_size;
 	}
 
 	*(tmp-rx_desc_size) = *(tmp-rx_desc_size) | (1<<30); // this is the last descriptor
 
-
-#ifdef DEBUG_RXALLOC
-	DMESG("RX DMA physical address: %x",dma_desc);
-#endif
-
 	return 0;
 }
 
@@ -2023,24 +1294,16 @@ void set_nic_rxring(struct net_device *dev)
 	u8 pgreg;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
-	//rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
 	pgreg=read_nic_byte(dev, PGSELECT);
 	write_nic_byte(dev, PGSELECT, pgreg &~ (1<<PGSELECT_PG_SHIFT));
 
-	//rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
 	write_nic_dword(dev, RXRING_ADDR,priv->rxringdma);
 }
 
-
 void rtl8180_reset(struct net_device *dev)
 {
-	//u32 txconf = 0x80e00707; //FIXME: Make me understandable
 	u8 cr;
 
-	//write_nic_dword(dev,TX_CONF,txconf);
-
 	rtl8180_irq_disable(dev);
 
 	cr=read_nic_byte(dev,CMD);
@@ -2057,83 +1320,80 @@ void rtl8180_reset(struct net_device *dev)
 	else
 		DMESG("Card successfully reset");
 
-//#ifndef CONFIG_RTL8185B
 	rtl8180_set_mode(dev,EPROM_CMD_LOAD);
 	force_pci_posting(dev);
 	mdelay(200);
-//#endif
 }
 
 inline u16 ieeerate2rtlrate(int rate)
 {
 	switch(rate){
 	case 10:
-	return 0;
+		return 0;
 	case 20:
-	return 1;
+		return 1;
 	case 55:
-	return 2;
+		return 2;
 	case 110:
-	return 3;
+		return 3;
 	case 60:
-	return 4;
+		return 4;
 	case 90:
-	return 5;
+		return 5;
 	case 120:
-	return 6;
+		return 6;
 	case 180:
-	return 7;
+		return 7;
 	case 240:
-	return 8;
+		return 8;
 	case 360:
-	return 9;
+		return 9;
 	case 480:
-	return 10;
+		return 10;
 	case 540:
-	return 11;
+		return 11;
 	default:
-	return 3;
-
+		return 3;
 	}
 }
 
 static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720};
+
 inline u16 rtl8180_rate2rate(short rate)
 {
-	if (rate >12) return 10;
+	if (rate > 12)
+		return 10;
 	return rtl_rate[rate];
 }
+
 inline u8 rtl8180_IsWirelessBMode(u16 rate)
 {
 	if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
 		return 1;
-	else return 0;
+	else
+		return 0;
 }
+
 u16 N_DBPSOfRate(u16 DataRate);
-u16 ComputeTxTime(
-	u16		FrameLength,
-	u16		DataRate,
-	u8		bManagementFrame,
-	u8		bShortPreamble
-)
+
+u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame,
+		  u8 bShortPreamble)
 {
 	u16	FrameTime;
 	u16	N_DBPS;
 	u16	Ceiling;
 
-	if( rtl8180_IsWirelessBMode(DataRate) )
-	{
-		if( bManagementFrame || !bShortPreamble || DataRate == 10 )
-		{	// long preamble
+	if (rtl8180_IsWirelessBMode(DataRate)) {
+		if (bManagementFrame || !bShortPreamble || DataRate == 10)
+			/* long preamble */
 			FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
-		}
 		else
-		{	// Short preamble
+			/* short preamble */
 			FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
-		}
-		if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
-				FrameTime ++;
-	} else {	//802.11g DSSS-OFDM PLCP length field calculation.
+
+		if ((FrameLength*8 % (DataRate/10)) != 0) /* get the ceilling */
+			FrameTime++;
+	} else {	/* 802.11g DSSS-OFDM PLCP length field calculation. */
 		N_DBPS = N_DBPSOfRate(DataRate);
 		Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
 				+ (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
@@ -2141,49 +1401,41 @@ u16 ComputeTxTime(
 	}
 	return FrameTime;
 }
+
 u16 N_DBPSOfRate(u16 DataRate)
 {
 	 u16 N_DBPS = 24;
 
-	 switch(DataRate)
-	 {
-	 case 60:
-	  N_DBPS = 24;
-	  break;
-
-	 case 90:
-	  N_DBPS = 36;
-	  break;
-
-	 case 120:
-	  N_DBPS = 48;
-	  break;
-
-	 case 180:
-	  N_DBPS = 72;
-	  break;
-
-	 case 240:
-	  N_DBPS = 96;
-	  break;
-
-	 case 360:
-	  N_DBPS = 144;
-	  break;
-
-	 case 480:
-	  N_DBPS = 192;
-	  break;
-
-	 case 540:
-	  N_DBPS = 216;
-	  break;
-
-	 default:
-	  break;
-	 }
+	switch (DataRate) {
+	case 60:
+		N_DBPS = 24;
+		break;
+	case 90:
+		N_DBPS = 36;
+		break;
+	case 120:
+		N_DBPS = 48;
+		break;
+	case 180:
+		N_DBPS = 72;
+		break;
+	case 240:
+		N_DBPS = 96;
+		break;
+	case 360:
+		N_DBPS = 144;
+		break;
+	case 480:
+		N_DBPS = 192;
+		break;
+	case 540:
+		N_DBPS = 216;
+		break;
+	default:
+		break;
+	}
 
-	 return N_DBPS;
+	return N_DBPS;
 }
 
 //{by amy 080312
@@ -2192,76 +1444,46 @@ u16 N_DBPSOfRate(u16 DataRate)
 // 	For Netgear case, they want good-looking singal strength.
 //		2004.12.05, by rcnjko.
 //
-long
-NetgearSignalStrengthTranslate(
-	long LastSS,
-	long CurrSS
-	)
+long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
 {
 	long RetSS;
 
 	// Step 1. Scale mapping.
-	if(CurrSS >= 71 && CurrSS <= 100)
-	{
+	if (CurrSS >= 71 && CurrSS <= 100)
 		RetSS = 90 + ((CurrSS - 70) / 3);
-	}
-	else if(CurrSS >= 41 && CurrSS <= 70)
-	{
+	else if (CurrSS >= 41 && CurrSS <= 70)
 		RetSS = 78 + ((CurrSS - 40) / 3);
-	}
-	else if(CurrSS >= 31 && CurrSS <= 40)
-	{
+	else if (CurrSS >= 31 && CurrSS <= 40)
 		RetSS = 66 + (CurrSS - 30);
-	}
-	else if(CurrSS >= 21 && CurrSS <= 30)
-	{
+	else if (CurrSS >= 21 && CurrSS <= 30)
 		RetSS = 54 + (CurrSS - 20);
-	}
-	else if(CurrSS >= 5 && CurrSS <= 20)
-	{
+	else if (CurrSS >= 5 && CurrSS <= 20)
 		RetSS = 42 + (((CurrSS - 5) * 2) / 3);
-	}
-	else if(CurrSS == 4)
-	{
+	else if (CurrSS == 4)
 		RetSS = 36;
-	}
-	else if(CurrSS == 3)
-	{
+	else if (CurrSS == 3)
 		RetSS = 27;
-	}
-	else if(CurrSS == 2)
-	{
+	else if (CurrSS == 2)
 		RetSS = 18;
-	}
-	else if(CurrSS == 1)
-	{
+	else if (CurrSS == 1)
 		RetSS = 9;
-	}
 	else
-	{
 		RetSS = CurrSS;
-	}
-	//RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
 
 	// Step 2. Smoothing.
 	if(LastSS > 0)
-	{
 		RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
-	}
-	//RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
 
 	return RetSS;
 }
+
 //
 //	Description:
 //		Translate 0-100 signal strength index into dBm.
 //
-long
-TranslateToDbm8185(
-	u8 SignalStrengthIndex	// 0-100 index.
-	)
+long TranslateToDbm8185(u8 SignalStrengthIndex)
 {
-	long	SignalPower; // in dBm.
+	long SignalPower;
 
 	// Translate to dBm (x=0.5y-95).
 	SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
@@ -2269,6 +1491,7 @@ TranslateToDbm8185(
 
 	return SignalPower;
 }
+
 //
 //	Description:
 //		Perform signal smoothing for dynamic mechanism.
@@ -2277,53 +1500,23 @@ TranslateToDbm8185(
 //		of correctness. Ported from 8187B.
 //	2007-02-26, by Bruce.
 //
-void
-PerformUndecoratedSignalSmoothing8185(
-	struct r8180_priv *priv,
-	bool    bCckRate
-	)
+void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
+					   bool bCckRate)
 {
-
-
 	// Determin the current packet is CCK rate.
 	priv->bCurCCKPkt = bCckRate;
 
-	if(priv->UndecoratedSmoothedSS >= 0)
-	{
+	if (priv->UndecoratedSmoothedSS >= 0)
 		priv->UndecoratedSmoothedSS = ( (priv->UndecoratedSmoothedSS * 5) + (priv->SignalStrength * 10) ) / 6;
-	}
 	else
-	{
 		priv->UndecoratedSmoothedSS = priv->SignalStrength * 10;
-	}
 
 	priv->UndercorateSmoothedRxPower = ( (priv->UndercorateSmoothedRxPower * 50) + (priv->RxPower* 11)) / 60;
 
-//	printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", priv->SignalStrength, priv->UndecoratedSmoothedSS);
-//	printk("Sommthing RxPower (%d) => UndecoratedRxPower (%d)\n", priv->RxPower, priv->UndercorateSmoothedRxPower);
-
-	//if(priv->CurCCKRSSI >= 0 && bCckRate)
-	if(bCckRate)
-	{
+	if (bCckRate)
 		priv->CurCCKRSSI = priv->RSSI;
-	}
 	else
-	{
 		priv->CurCCKRSSI = 0;
-	}
-
-	// Boundary checking.
-	// TODO: The overflow condition does happen, if we want to fix,
-	// we shall recalculate thresholds first.
-	if(priv->UndecoratedSmoothedSS > 100)
-	{
-//		printk("UndecoratedSmoothedSS(%d) overflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
-	}
-	if(priv->UndecoratedSmoothedSS < 0)
-	{
-//		printk("UndecoratedSmoothedSS(%d) underflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
-	}
-
 }
 
 //by amy 080312}
@@ -2333,108 +1526,47 @@ void rtl8180_rx(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	struct sk_buff *tmp_skb;
-
-	//struct sk_buff *skb;
 	short first,last;
 	u32 len;
 	int lastlen;
 	unsigned char quality, signal;
 	u8 rate;
-	//u32 *prism_hdr;
 	u32 *tmp,*tmp2;
 	u8 rx_desc_size;
 	u8 padding;
-	//u32 count=0;
 	char rxpower = 0;
 	u32 RXAGC = 0;
 	long RxAGC_dBm = 0;
 	u8	LNA=0, BB=0;
 	u8 	LNA_gain[4]={02, 17, 29, 39};
 	u8  Antenna = 0;
-	struct ieee80211_hdr *hdr;//by amy
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc,type;
 	u8 bHwError = 0,bCRC = 0,bICV = 0;
-	//bHwError = 0;
-	//bCRC = 0;
-	//bICV = 0;
 	bool	bCckRate = false;
 	u8     RSSI = 0;
-	long	SignalStrengthIndex = 0;//+by amy 080312
-//	u8 SignalStrength = 0;
+	long	SignalStrengthIndex = 0;
 	struct ieee80211_rx_stats stats = {
 		.signal = 0,
 		.noise = -98,
 		.rate = 0,
-	//	.mac_time = jiffies,
 		.freq = IEEE80211_24GHZ_BAND,
 	};
 
-#ifdef CONFIG_RTL8185B
 	stats.nic_type = NIC_8185B;
 	rx_desc_size = 8;
 
-#else
-	stats.nic_type = NIC_8185;
-	rx_desc_size = 4;
-#endif
-	//printk("receive frame!%d\n",count++);
-	//if (!priv->rxbuffer) DMESG ("EE: NIC RX ack, but RX queue corrupted!");
-	//else {
-
 	if ((*(priv->rxringtail)) & (1<<31)) {
-
 		/* we have got an RX int, but the descriptor
 		 * we are pointing is empty*/
 
 		priv->stats.rxnodata++;
 		priv->ieee80211->stats.rx_errors++;
 
-	/*	if (! *(priv->rxring) & (1<<31)) {
-
-			priv->stats.rxreset++;
-			priv->rxringtail=priv->rxring;
-			priv->rxbuffer=priv->rxbufferhead;
-
-		}else{*/
-
-		#if 0
-		/* Maybe it is possible that the NIC has skipped some descriptors or
-		 * it has reset its internal pointer to the beginning of the ring
-		 * we search for the first filled descriptor in the ring, or we break
-		 * putting again the pointer in the old location if we do not found any.
-		 * This is quite dangerous, what does happen if the nic writes
-		 * two descriptor (say A and B) when we have just checked the descriptor
-		 * A and we are going to check the descriptor B..This might happen if the
-		 * interrupt was dummy, there was not really filled descriptors and
-		 * the NIC didn't lose pointer
-		 */
-
-		//priv->stats.rxwrkaround++;
-
-		tmp = priv->rxringtail;
-		while (*(priv->rxringtail) & (1<<31)){
-
-			priv->rxringtail+=4;
-
-			if(priv->rxringtail >=
-				(priv->rxring)+(priv->rxringcount )*4)
-				priv->rxringtail=priv->rxring;
-
-			priv->rxbuffer=(priv->rxbuffer->next);
-
-			if(priv->rxringtail == tmp ){
-				//DMESG("EE: Could not find RX pointer");
-				priv->stats.rxnopointer++;
-				break;
-			}
-		}
-		#else
-
 		tmp2 = NULL;
 		tmp = priv->rxringtail;
 		do{
 			if(tmp == priv->rxring)
-				//tmp  = priv->rxring + (priv->rxringcount )*rx_desc_size; xiong-2006-11-15
 				tmp  = priv->rxring + (priv->rxringcount - 1)*rx_desc_size;
 			else
 				tmp -= rx_desc_size;
@@ -2444,8 +1576,6 @@ void rtl8180_rx(struct net_device *dev)
 		}while(tmp != priv->rxring);
 
 		if(tmp2) priv->rxringtail = tmp2;
-		#endif
-		//}
 	}
 
 	/* while there are filled descriptors */
@@ -2487,7 +1617,6 @@ void rtl8180_rx(struct net_device *dev)
 				len=lastlen-priv->rx_prevlen;
 
 			if(*(priv->rxringtail) & (1<<13)) {
-//lastlen=((*priv->rxringtail) &0xfff);
 				if ((*(priv->rxringtail) & 0xfff) <500)
 					priv->stats.rxcrcerrmin++;
 				else if ((*(priv->rxringtail) & 0x0fff) >1000)
@@ -2501,7 +1630,6 @@ void rtl8180_rx(struct net_device *dev)
 			len = priv->rxbuffersize;
 		}
 
-#ifdef CONFIG_RTL8185B
 		if(first && last) {
 			padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
 		}else if(first) {
@@ -2512,10 +1640,7 @@ void rtl8180_rx(struct net_device *dev)
 		}else {
 			padding = 0;
 		}
-#ifdef CONFIG_RTL818X_S
                padding = 0;
-#endif
-#endif
 		priv->rx_prevlen+=len;
 
 		if(priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100){
@@ -2529,17 +1654,6 @@ void rtl8180_rx(struct net_device *dev)
 			priv->rx_skb_complete = 1;
 		}
 
-#ifdef DEBUG_RX_FRAG
-		DMESG("Iteration.. len %x",len);
-		if(first) DMESG ("First descriptor");
-		if(last) DMESG("Last descriptor");
-
-#endif
-#ifdef DEBUG_RX_VERBOSE
-		print_buffer( priv->rxbuffer->buf, len);
-#endif
-
-#ifdef CONFIG_RTL8185B
 		signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16);
 		signal=(signal&0xfe)>>1;	// Modify by hikaru 6.6
 
@@ -2550,22 +1664,11 @@ void rtl8180_rx(struct net_device *dev)
 		rxpower =((char)(((*(priv->rxringtail+4))& (0x00ff0000))>>16))/2 - 42;
 		RSSI = ((u8)(((*(priv->rxringtail+3)) & (0x0000ff00))>> 8)) & (0x7f);
 
-#else
-		signal=((*(priv->rxringtail+1))& (0xff0000))>>16;
-		signal=(signal&0xfe)>>1;	// Modify by hikaru 6.6
-
-		quality=((*(priv->rxringtail+1)) & (0xff));
-
-		stats.mac_time[0] = *(priv->rxringtail+2);
-		stats.mac_time[1] = *(priv->rxringtail+3);
-#endif
 		rate=((*(priv->rxringtail)) &
 			((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
 
 		stats.rate = rtl8180_rate2rate(rate);
-		//DMESG("%d",rate);
 		Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ;
-//		printk("in rtl8180_rx():Antenna is %d\n",Antenna);
 //by amy for antenna
 		if(!rtl8180_IsWirelessBMode(stats.rate))
 		{ // OFDM rate.
@@ -2633,7 +1736,7 @@ void rtl8180_rx(struct net_device *dev)
 			| (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 );
 		bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
 		bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12;
-            hdr = (struct ieee80211_hdr *)priv->rxbuffer->buf;
+		hdr = (struct ieee80211_hdr_4addr *)priv->rxbuffer->buf;
 		    fc = le16_to_cpu(hdr->frame_ctl);
 	        type = WLAN_FC_GET_TYPE(fc);
 
@@ -2670,59 +1773,20 @@ void rtl8180_rx(struct net_device *dev)
 			}
 
 //by amy for antenna
-
-
-
-
-
-
 #ifndef DUMMY_RX
 		if(first){
 			if(!priv->rx_skb_complete){
 				/* seems that HW sometimes fails to reiceve and
 				   doesn't provide the last descriptor */
-#ifdef DEBUG_RX_SKB
-				DMESG("going to free incomplete skb");
-#endif
 				dev_kfree_skb_any(priv->rx_skb);
 				priv->stats.rxnolast++;
-#ifdef DEBUG_RX_SKB
-				DMESG("free incomplete skb OK");
-#endif
 			}
 			/* support for prism header has been originally added by Christian */
 			if(priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR){
 
-#if 0
-				priv->rx_skb = dev_alloc_skb(len+2+PRISM_HDR_SIZE);
-				if(! priv->rx_skb) goto drop;
-
-				prism_hdr = (u32*) skb_put(priv->rx_skb,PRISM_HDR_SIZE);
-				prism_hdr[0]=htonl(0x80211001);        //version
-				prism_hdr[1]=htonl(0x40);              //length
-				prism_hdr[2]=htonl(stats.mac_time[1]);    //mactime (HIGH)
-				prism_hdr[3]=htonl(stats.mac_time[0]);    //mactime (LOW)
-				rdtsc(prism_hdr[5], prism_hdr[4]);         //hostime (LOW+HIGH)
-				prism_hdr[4]=htonl(prism_hdr[4]);          //Byte-Order aendern
-				prism_hdr[5]=htonl(prism_hdr[5]);          //Byte-Order aendern
-				prism_hdr[6]=0x00;                     //phytype
-				prism_hdr[7]=htonl(priv->chan);        //channel
-				prism_hdr[8]=htonl(stats.rate);        //datarate
-				prism_hdr[9]=0x00;                     //antenna
-				prism_hdr[10]=0x00;                    //priority
-				prism_hdr[11]=0x00;                    //ssi_type
-				prism_hdr[12]=htonl(stats.signal);     //ssi_signal
-				prism_hdr[13]=htonl(stats.noise);      //ssi_noise
-				prism_hdr[14]=0x00;                    //preamble
-				prism_hdr[15]=0x00;                    //encoding
-
-#endif
 			}else{
 				priv->rx_skb = dev_alloc_skb(len+2);
 				if( !priv->rx_skb) goto drop;
-#ifdef DEBUG_RX_SKB
-				DMESG("Alloc initial skb %x",len+2);
-#endif
 			}
 
 			priv->rx_skb_complete=0;
@@ -2741,91 +1805,50 @@ void rtl8180_rx(struct net_device *dev)
 				if(!tmp_skb) goto drop;
 
 				tmp_skb->dev=dev;
-#ifdef DEBUG_RX_SKB
-				DMESG("Realloc skb %x",len+2);
-#endif
 
-#ifdef DEBUG_RX_SKB
-				DMESG("going copy prev frag %x",priv->rx_skb->len);
-#endif
 				memcpy(skb_put(tmp_skb,priv->rx_skb->len),
 					priv->rx_skb->data,
 					priv->rx_skb->len);
-#ifdef DEBUG_RX_SKB
-				DMESG("skb copy prev frag complete");
-#endif
 
 				dev_kfree_skb_any(priv->rx_skb);
-#ifdef DEBUG_RX_SKB
-				DMESG("prev skb free ok");
-#endif
 
 				priv->rx_skb=tmp_skb;
 			}
 		}
-#ifdef DEBUG_RX_SKB
-		DMESG("going to copy current payload %x",len);
-#endif
+
 		if(!priv->rx_skb_complete) {
-#ifdef CONFIG_RTL8185B
 			if(padding) {
 				memcpy(skb_put(priv->rx_skb,len),
 					(((unsigned char *)priv->rxbuffer->buf) + 2),len);
 			} else {
-#endif
 				memcpy(skb_put(priv->rx_skb,len),
 					priv->rxbuffer->buf,len);
-#ifdef CONFIG_RTL8185B
 			}
-#endif
 		}
-#ifdef DEBUG_RX_SKB
-		DMESG("current fragment skb copy complete");
-#endif
 
 		if(last && !priv->rx_skb_complete){
-
-#ifdef DEBUG_RX_SKB
-			DMESG("Got last fragment");
-#endif
-
 			if(priv->rx_skb->len > 4)
 				skb_trim(priv->rx_skb,priv->rx_skb->len-4);
-#ifdef DEBUG_RX_SKB
-			DMESG("yanked out crc, passing to the upper layer");
-#endif
-
 #ifndef RX_DONT_PASS_UL
 			if(!ieee80211_rx(priv->ieee80211,
 					 priv->rx_skb, &stats)){
-#ifdef DEBUG_RX
-				DMESGW("Packet not consumed");
-#endif
 #endif // RX_DONT_PASS_UL
 
 				dev_kfree_skb_any(priv->rx_skb);
 #ifndef RX_DONT_PASS_UL
 			}
 #endif
-#ifdef DEBUG_RX
-			else{
-					DMESG("Rcv frag");
-			}
-#endif
 			priv->rx_skb_complete=1;
 		}
 
 #endif //DUMMY_RX
-
 		pci_dma_sync_single_for_device(priv->pdev,
 				    priv->rxbuffer->dma,
 				    priv->rxbuffersize * \
 				    sizeof(u8),
 				    PCI_DMA_FROMDEVICE);
 
-
 drop: // this is used when we have not enought mem
-
 		/* restore the descriptor */
 		*(priv->rxringtail+2)=priv->rxbuffer->dma;
 		*(priv->rxringtail)=*(priv->rxringtail) &~ 0xfff;
@@ -2834,35 +1857,14 @@ drop: // this is used when we have not enought mem
 
 		*(priv->rxringtail)=
 			*(priv->rxringtail) | (1<<31);
-			//^empty descriptor
-
-			//wmb();
-
-#ifdef DEBUG_RX
-		DMESG("Current descriptor: %x",(u32)priv->rxringtail);
-#endif
-		//unsigned long flags;
-		//spin_lock_irqsave(&priv->irq_lock,flags);
 
 		priv->rxringtail+=rx_desc_size;
 		if(priv->rxringtail >=
 		   (priv->rxring)+(priv->rxringcount )*rx_desc_size)
 			priv->rxringtail=priv->rxring;
 
-		//spin_unlock_irqrestore(&priv->irq_lock,flags);
-
-
 		priv->rxbuffer=(priv->rxbuffer->next);
-
 	}
-
-
-
-//	if(get_curr_tx_free_desc(dev,priority))
-//	ieee80211_sta_ps_sleep(priv->ieee80211, &tmp, &tmp2);
-
-
-
 }
 
 
@@ -2871,33 +1873,6 @@ void rtl8180_dma_kick(struct net_device *dev, int priority)
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-/*
-
-	switch(priority){
-
-		case LOW_PRIORITY:
-
-		write_nic_byte(dev,TX_DMA_POLLING,
-		       (1<< TX_DMA_POLLING_LOWPRIORITY_SHIFT) |
-			        priv->dma_poll_mask);
-		break;
-
-		case NORM_PRIORITY:
-
-		write_nic_byte(dev,TX_DMA_POLLING,
-		       (1<< TX_DMA_POLLING_NORMPRIORITY_SHIFT) |
-			        priv->dma_poll_mask);
-		break;
-
-		case HI_PRIORITY:
-
-		write_nic_byte(dev,TX_DMA_POLLING,
-		       (1<< TX_DMA_POLLING_HIPRIORITY_SHIFT) |
-			        priv->dma_poll_mask);
-		break;
-
-	}
-*/
 	write_nic_byte(dev, TX_DMA_POLLING,
 			(1 << (priority + 1)) | priv->dma_poll_mask);
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
@@ -2905,53 +1880,26 @@ void rtl8180_dma_kick(struct net_device *dev, int priority)
 	force_pci_posting(dev);
 }
 
-#if 0
-void rtl8180_tx_queues_stop(struct net_device *dev)
-{
-	//struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-	u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
-	dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
-	dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
-	dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
-
-	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
-	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
-}
-#endif
-
 void rtl8180_data_hard_stop(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-#ifdef CONFIG_RTL8185B
 	priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ;
 	write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
-#else
-	priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-#endif
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 }
 
-
 void rtl8180_data_hard_resume(struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-#ifdef  CONFIG_RTL8185B
 	priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ);
 	write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
-#else
-	priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-#endif
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 }
 
-
 /* this function TX data frames when the ieee80211 stack requires this.
  * It checks also if we need to stop the ieee tx queue, eventually do it
  */
@@ -2964,7 +1912,6 @@ rate)
 	short morefrag = (h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS;
 	unsigned long flags;
 	int priority;
-	//static int count = 0;
 
 	mode = priv->ieee80211->iw_mode;
 
@@ -2976,11 +1923,7 @@ rate)
 	* the ieee stack, or from the try_wake_queue (again trought
 	* the ieee stack.
 	*/
-#ifdef CONFIG_RTL8185B
 	priority = AC2Q(skb->priority);
-#else
-	priority = LOW_PRIORITY;
-#endif
 	spin_lock_irqsave(&priv->tx_lock,flags);
 
 	if(priv->ieee80211->bHwRadioOff)
@@ -2990,22 +1933,16 @@ rate)
 		return;
 	}
 
-	//printk(KERN_WARNING "priority = %d@%d\n", priority, count++);
 	if (!check_nic_enought_desc(dev, priority)){
-		//DMESG("Error: no descriptor left by previous TX (avail %d) ",
-		//	get_curr_tx_free_desc(dev, priority));
 		DMESGW("Error: no descriptor left by previous TX (avail %d) ",
 			get_curr_tx_free_desc(dev, priority));
-	//printk(KERN_WARNING "==============================================================> \n");
 		ieee80211_stop_queue(priv->ieee80211);
 	}
 	rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate);
 	if (!check_nic_enought_desc(dev, priority))
 		ieee80211_stop_queue(priv->ieee80211);
 
-	//dev_kfree_skb_any(skb);
 	spin_unlock_irqrestore(&priv->tx_lock,flags);
-
 }
 
 /* This is a rough attempt to TX a frame
@@ -3022,25 +1959,17 @@ rate)
 int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
 	unsigned long flags;
-
 	int priority;
 
-#ifdef CONFIG_RTL8185B
 	priority = MANAGE_PRIORITY;
-#else
-	priority = NORM_PRIORITY;
-#endif
 
 	spin_lock_irqsave(&priv->tx_lock,flags);
 
-	if(priv->ieee80211->bHwRadioOff)
-	{
+	if (priv->ieee80211->bHwRadioOff) {
 		spin_unlock_irqrestore(&priv->tx_lock,flags);
-
 		dev_kfree_skb_any(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	rtl8180_tx(dev, skb->data, skb->len, priority,
@@ -3051,7 +1980,7 @@ int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
 	spin_unlock_irqrestore(&priv->tx_lock,flags);
 
 	dev_kfree_skb_any(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 // longpre 144+48 shortpre 72+24
@@ -3069,7 +1998,6 @@ u16 rtl8180_len2duration(u32 len, short rate,short* ext)
 		if(drift ==0 ) break;
 		duration++;
 		break;
-
 	case 1://2mbps
 		*ext=0;
 		duration = ((len+4)<<4) /0x4;
@@ -3077,7 +2005,6 @@ u16 rtl8180_len2duration(u32 len, short rate,short* ext)
 		if(drift ==0 ) break;
 		duration++;
 		break;
-
 	case 2: //5.5mbps
 		*ext=0;
 		duration = ((len+4)<<4) /0xb;
@@ -3086,7 +2013,6 @@ u16 rtl8180_len2duration(u32 len, short rate,short* ext)
 			break;
 		duration++;
 		break;
-
 	default:
 	case 3://11mbps
 		*ext=0;
@@ -3104,12 +2030,9 @@ u16 rtl8180_len2duration(u32 len, short rate,short* ext)
 	return duration;
 }
 
-
 void rtl8180_prepare_beacon(struct net_device *dev)
 {
-
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
 	struct sk_buff *skb;
 
 	u16 word  = read_nic_word(dev, BcnItv);
@@ -3117,46 +2040,12 @@ void rtl8180_prepare_beacon(struct net_device *dev)
 	word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval);//0x64;
 	write_nic_word(dev, BcnItv, word);
 
-
 	skb = ieee80211_get_beacon(priv->ieee80211);
 	if(skb){
 		rtl8180_tx(dev,skb->data,skb->len,BEACON_PRIORITY,
 			0,0,ieeerate2rtlrate(priv->ieee80211->basic_rate));
 		dev_kfree_skb_any(skb);
 	}
-	#if 0
-	//DMESG("size %x",len);
-	if(*tail & (1<<31)){
-
-		//DMESG("No more beacon TX desc");
-		return ;
-
-	}
-	//while(! (*tail & (1<<31))){
-		*tail= 0; // zeroes header
-
-		*tail = *tail| (1<<29) ; //fist segment of the packet
-		*tail = (*tail) | (1<<28); // last segment
-	//	*tail = *tail | (1<<18); // this is  a beacon frame
-		*(tail+3)=*(tail+3) &~ 0xfff;
-		*(tail+3)=*(tail+3) | len; // buffer lenght
-		*tail = *tail |len;
-		// zeroes the second 32-bits dword of the descriptor
-		*(tail+1)= 0;
-		*tail = *tail | (rate << 24);
-
-			duration = rtl8180_len2duration(len,rate,&ext);
-
-		*(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
-
-		*tail = *tail | (1<<31);
-		//^ descriptor ready to be txed
-		if((tail - begin)/8 == priv->txbeaconcount-1)
-			tail=begin;
-		else
-			tail=tail+8;
-	//}
-#endif
 }
 
 /* This function do the real dirty work: it enqueues a TX command
@@ -3174,26 +2063,19 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 	int remain;
 	int buflen;
 	int count;
-	//u16	AckCtsTime;
-	//u16	FrameTime;
 	u16 duration;
 	short ext;
 	struct buffer* buflist;
-	//unsigned long flags;
-#ifdef CONFIG_RTL8185B
 	struct ieee80211_hdr_3addr *frag_hdr = (struct ieee80211_hdr_3addr *)txbuf;
 	u8 dest[ETH_ALEN];
 	u8			bUseShortPreamble = 0;
 	u8			bCTSEnable = 0;
 	u8			bRTSEnable = 0;
-	//u16			RTSRate = 22;
-	//u8			RetryLimit = 0;
 	u16 			Duration = 0;
 	u16			RtsDur = 0;
 	u16			ThisFrameTime = 0;
 	u16			TxDescDuration = 0;
 	u8 			ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14
-#endif
 
 	switch(priority) {
 	case MANAGE_PRIORITY:
@@ -3202,56 +2084,47 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 		buflist = priv->txmapbufstail;
 		count = priv->txringcount;
 		break;
-
 	case BK_PRIORITY:
 		tail=priv->txbkpringtail;
 		begin=priv->txbkpring;
 		buflist = priv->txbkpbufstail;
 		count = priv->txringcount;
 		break;
-
 	case BE_PRIORITY:
 		tail=priv->txbepringtail;
 		begin=priv->txbepring;
 		buflist = priv->txbepbufstail;
 		count = priv->txringcount;
 		break;
-
 	case VI_PRIORITY:
 		tail=priv->txvipringtail;
 		begin=priv->txvipring;
 		buflist = priv->txvipbufstail;
 		count = priv->txringcount;
 		break;
-
 	case VO_PRIORITY:
 		tail=priv->txvopringtail;
 		begin=priv->txvopring;
 		buflist = priv->txvopbufstail;
 		count = priv->txringcount;
 		break;
-
 	case HI_PRIORITY:
 		tail=priv->txhpringtail;
 		begin=priv->txhpring;
 		buflist = priv->txhpbufstail;
 		count = priv->txringcount;
 		break;
-
 	case BEACON_PRIORITY:
 		tail=priv->txbeaconringtail;
 		begin=priv->txbeaconring;
 		buflist = priv->txbeaconbufstail;
 		count = priv->txbeaconcount;
 		break;
-
 	default:
 		return -1;
 		break;
  	}
 
-	//printk("in rtl8180_tx(): rate is %d\n",priv->ieee80211->rate);
-#if 1
 		memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
 		if (is_multicast_ether_addr(dest) ||
 				is_broadcast_ether_addr(dest))
@@ -3264,20 +2137,13 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 			ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble);
 			TxDescDuration = ThisFrameTime;
 		} else {// Unicast packet
-			//u8 AckRate;
 			u16 AckTime;
 
 			//YJ,add,080828,for Keep alive
 			priv->NumTxUnicast++;
 
 			// Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
-			//AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) );
-			// Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko.
-			//AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE);
-			//For simplicity, just use the 1M basic rate
-			//AckTime = ComputeTxTime(14, 540,0, 0);	// AckCTSLng = 14 use 1M bps send
 			AckTime = ComputeTxTime(14, 10,0, 0);	// AckCTSLng = 14 use 1M bps send
-			//AckTime = ComputeTxTime(14, 2,false, false);	// AckCTSLng = 14 use 1M bps send
 
 			if ( ((len + sCrcLng) > priv->rts) && priv->rts )
 			{ // RTS/CTS.
@@ -3328,41 +2194,24 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 		} // End of Unicast packet
 
 		frag_hdr->duration_id = Duration;
-#endif
 
 	buflen=priv->txbuffsize;
 	remain=len;
 	temp_tail = tail;
-//printk("================================>buflen = %d, remain = %d!\n", buflen,remain);
+
 	while(remain!=0){
-#ifdef DEBUG_TX_FRAG
-		DMESG("TX iteration");
-#endif
-#ifdef DEBUG_TX
-		DMESG("TX: filling descriptor %x",(u32)tail);
-#endif
 		mb();
 		if(!buflist){
 			DMESGE("TX buffer error, cannot TX frames. pri %d.", priority);
-			//spin_unlock_irqrestore(&priv->tx_lock,flags);
 			return -1;
 		}
 		buf=buflist->buf;
 
-		if( (*tail & (1<<31)) && (priority != BEACON_PRIORITY)){
-
-				DMESGW("No more TX desc, returning %x of %x",
-				remain,len);
-				priv->stats.txrdu++;
-#ifdef DEBUG_TX_DESC
-				check_tx_ring(dev,priority);
-			//	netif_stop_queue(dev);
-			//	netif_carrier_off(dev);
-#endif
-			//	spin_unlock_irqrestore(&priv->tx_lock,flags);
-
+		if ((*tail & (1 << 31)) && (priority != BEACON_PRIORITY)) {
+			DMESGW("No more TX desc, returning %x of %x",
+			       remain, len);
+			priv->stats.txrdu++;
 			return remain;
-
 		}
 
 		*tail= 0; // zeroes header
@@ -3375,14 +2224,10 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 		if(priv->card_8185){
 			//FIXME: this should be triggered by HW encryption parameters.
 			*tail |= (1<<15); //no encrypt
-//			*tail |= (1<<30); //raise int when completed
 		}
-	//	*tail = *tail | (1<<16);
+
 		if(remain==len && !descfrag) {
 			ownbit_flag = false;	//added by david woo,2007.12.14
-#ifdef DEBUG_TX_FRAG
-			DMESG("First descriptor");
-#endif
 			*tail = *tail| (1<<29) ; //fist segment of the packet
 			*tail = *tail |(len);
 		} else {
@@ -3401,9 +2246,8 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 		// Use short preamble or not
 		if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE)
 			if (priv->plcp_preamble_mode==1 && rate!=0)	//  short mode now, not long!
-			//	*tail |= (1<<16);				// enable short preamble mode.
+			;//	*tail |= (1<<16);				// enable short preamble mode.
 
-#ifdef CONFIG_RTL8185B
 		if(bCTSEnable) {
 			*tail |= (1<<18);
 		}
@@ -3417,60 +2261,13 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 		*(tail+3) |= ((TxDescDuration&0xffff)<<16); //DURATION
 //	        *(tail+3) |= (0xe6<<16);
         	*(tail+5) |= (11<<8);//(priv->retry_data<<8); //retry lim ;
-#else
-		//Use RTS or not
-#ifdef CONFIG_RTL8187B
-		if ( (len>priv->rts) && priv->rts && priority!=MANAGE_PRIORITY){
-#else
-		if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
-#endif
-			*tail |= (1<<23);	//enalbe RTS function
-			*tail |= (0<<19);	//use 1M bps send RTS packet
-			AckCtsTime = ComputeTxTime(14, 10,0, 0);	// AckCTSLng = 14 use 1M bps send
-			FrameTime = ComputeTxTime(len + 4, rtl8180_rate2rate(rate), 0, *tail&(1<<16));
-			// RTS/CTS time is calculate as follow
-			duration = FrameTime + 3*10 + 2*AckCtsTime;	//10us is the SifsTime;
-			*(tail+1) |= duration; 	//Need to edit here!  ----hikaru
-		}else{
-			*(tail+1)= 0; // zeroes the second 32-bits dword of the descriptor
-		}
-#endif
 
 		*tail = *tail | ((rate&0xf) << 24);
-		//DMESG("rate %d",rate);
-
-		if(priv->card_8185){
-
-			#if 0
-			*(tail+5)&= ~(1<<24); /* tx ant 0 */
-
-			*(tail+5) &= ~(1<<23); /* random tx agc 23-16 */
-			*(tail+5) |= (1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16);
-
-			*(tail+5) &=
-~((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8));
-			*(tail+5) |= (7<<8); // Max retry limit
-
-			*(tail+5) &= ~((1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0));
-			*(tail+5) |= (8<<4); // Max contention window
-			*(tail+6) |= 4; // Min contention window
-			#endif
-           //    	*(tail+5) = 0;
-		}
 
 		/* hw_plcp_len is not used for rtl8180 chip */
 		/* FIXME */
 		if(priv->card_8185 == 0 || !priv->hw_plcp_len){
-
-			duration = rtl8180_len2duration(len,
-				rate,&ext);
-
-
-#ifdef DEBUG_TX
-			DMESG("PLCP duration %d",duration );
-			//DMESG("drift %d",drift);
-			DMESG("extension %s", (ext==1) ? "on":"off");
-#endif
+			duration = rtl8180_len2duration(len, rate, &ext);
 			*(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
 			if(ext) *(tail+1) = *(tail+1) |(1<<31); //plcp length extension
 		}
@@ -3478,10 +2275,6 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 		if(morefrag) *tail = (*tail) | (1<<17); // more fragment
 		if(!remain) *tail = (*tail) | (1<<28); // last segment of frame
 
-#ifdef DEBUG_TX_FRAG
-		if(!remain)DMESG("Last descriptor");
-		if(morefrag)DMESG("More frag");
-#endif
                *(tail+5) = *(tail+5)|(2<<27);
                 *(tail+7) = *(tail+7)|(1<<4);
 
@@ -3491,15 +2284,8 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 			*tail = *tail | (1<<31); // descriptor ready to be txed
 		}
 
-#ifdef DEBUG_TX_DESC2
-                printk("tx desc is:\n");
-		DMESG("%8x %8x %8x %8x %8x %8x %8x %8x", tail[0], tail[1], tail[2], tail[3],
-			tail[4], tail[5], tail[6], tail[7]);
-#endif
-
 		if((tail - begin)/8 == count-1)
 			tail=begin;
-
 		else
 			tail=tail+8;
 
@@ -3512,75 +2298,56 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
 				priv->txmapringtail=tail;
 				priv->txmapbufstail=buflist;
 				break;
-
 			case BK_PRIORITY:
 				priv->txbkpringtail=tail;
 				priv->txbkpbufstail=buflist;
 				break;
-
 			case BE_PRIORITY:
 				priv->txbepringtail=tail;
 				priv->txbepbufstail=buflist;
 				break;
-
 			case VI_PRIORITY:
 				priv->txvipringtail=tail;
 				priv->txvipbufstail=buflist;
 				break;
-
 			case VO_PRIORITY:
 				priv->txvopringtail=tail;
 				priv->txvopbufstail=buflist;
 				break;
-
 			case HI_PRIORITY:
 				priv->txhpringtail=tail;
 				priv->txhpbufstail = buflist;
 				break;
-
 			case BEACON_PRIORITY:
 				/* the HW seems to be happy with the 1st
 				 * descriptor filled and the 2nd empty...
 				 * So always update descriptor 1 and never
 				 * touch 2nd
 				 */
-			//	priv->txbeaconringtail=tail;
-			//	priv->txbeaconbufstail=buflist;
-
 				break;
-
 		}
-
-		//rtl8180_dma_kick(dev,priority);
 	}
 	*temp_tail = *temp_tail | (1<<31); // descriptor ready to be txed
 	rtl8180_dma_kick(dev,priority);
-	//spin_unlock_irqrestore(&priv->tx_lock,flags);
 
 	return 0;
-
 }
 
-
 void rtl8180_irq_rx_tasklet(struct r8180_priv * priv);
 
-
 void rtl8180_link_change(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	u16 beacon_interval;
-
 	struct ieee80211_network *net = &priv->ieee80211->current_network;
-//	rtl8180_adapter_start(dev);
-	rtl8180_update_msr(dev);
 
+	rtl8180_update_msr(dev);
 
 	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
 
 	write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
 	write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
 
-
 	beacon_interval  = read_nic_dword(dev,BEACON_INTERVAL);
 	beacon_interval &= ~ BEACON_INTERVAL_MASK;
 	beacon_interval |= net->beacon_interval;
@@ -3588,46 +2355,14 @@ void rtl8180_link_change(struct net_device *dev)
 
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 
-
-	/*
-	u16 atim = read_nic_dword(dev,ATIM);
-	u16 = u16 &~ ATIM_MASK;
-	u16 = u16 | beacon->atim;
-	*/
-#if 0
-	if (net->capability & WLAN_CAPABILITY_PRIVACY) {
-		if (priv->hw_wep) {
-			DMESG("Enabling hardware WEP support");
-			rtl8180_set_hw_wep(dev);
-			priv->ieee80211->host_encrypt=0;
-			priv->ieee80211->host_decrypt=0;
-		}
-#ifndef CONFIG_IEEE80211_NOWEP
-		else {
-			priv->ieee80211->host_encrypt=1;
-			priv->ieee80211->host_decrypt=1;
-		}
-#endif
-	}
-#ifndef CONFIG_IEEE80211_NOWEP
-	else{
-		priv->ieee80211->host_encrypt=0;
-		priv->ieee80211->host_decrypt=0;
-	}
-#endif
-#endif
-
-
 	if(priv->card_8185)
 		rtl8180_set_chan(dev, priv->chan);
-
-
 }
 
 void rtl8180_rq_tx_ack(struct net_device *dev){
 
 	struct r8180_priv *priv = ieee80211_priv(dev);
-//	printk("====================>%s\n",__func__);
+
 	write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)|CONFIG4_PWRMGT);
 	priv->ack_tx_to_ieee = 1;
 }
@@ -3668,39 +2403,29 @@ short rtl8180_is_tx_queue_empty(struct net_device *dev){
 void rtl8180_hw_wakeup(struct net_device *dev)
 {
 	unsigned long flags;
-
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
 	spin_lock_irqsave(&priv->ps_lock,flags);
-	//DMESG("Waken up!");
 	write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)&~CONFIG4_PWRMGT);
-
-	if(priv->rf_wakeup)
+	if (priv->rf_wakeup)
 		priv->rf_wakeup(dev);
-//	mdelay(HW_WAKE_DELAY);
 	spin_unlock_irqrestore(&priv->ps_lock,flags);
 }
 
 void rtl8180_hw_sleep_down(struct net_device *dev)
 {
         unsigned long flags;
-
         struct r8180_priv *priv = ieee80211_priv(dev);
 
         spin_lock_irqsave(&priv->ps_lock,flags);
-       //DMESG("Sleep!");
-
         if(priv->rf_sleep)
                 priv->rf_sleep(dev);
         spin_unlock_irqrestore(&priv->ps_lock,flags);
 }
 
-
 void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
 {
-
 	struct r8180_priv *priv = ieee80211_priv(dev);
-
 	u32 rb = jiffies;
 	unsigned long flags;
 
@@ -3711,14 +2436,6 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
 	 */
 	tl -= MSECS(4+16+7);
 
-	//if(tl == 0) tl = 1;
-
-	/* FIXME HACK FIXME HACK */
-//	force_pci_posting(dev);
-	//mdelay(1);
-
-//	rb = read_nic_dword(dev, TSFTR);
-
 	/* If the interval in witch we are requested to sleep is too
 	 * short then give up and remain awake
 	 */
@@ -3729,13 +2446,9 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
 		return;
 	}
 
-//	write_nic_dword(dev, TimerInt, tl);
-//	rb = read_nic_dword(dev, TSFTR);
 	{
 		u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
-	//	if (tl<rb)
 
-		//lzm,add,080828
 		priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp);
 
 		queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
@@ -3743,34 +2456,21 @@ void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
 	/* if we suspect the TimerInt is gone beyond tl
 	 * while setting it, then give up
 	 */
-#if 1
+
 	if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
 		((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
 		spin_unlock_irqrestore(&priv->ps_lock,flags);
 		return;
 	}
-#endif
-//	if(priv->rf_sleep)
-//		priv->rf_sleep(dev);
 
 	queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq);
 	spin_unlock_irqrestore(&priv->ps_lock,flags);
 }
 
-
-//void rtl8180_wmm_param_update(struct net_device *dev,u8 *ac_param)
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
 void rtl8180_wmm_param_update(struct work_struct * work)
 {
 	struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq);
-	//struct r8180_priv *priv = (struct r8180_priv*)(ieee->priv);
 	struct net_device *dev = ieee->dev;
-#else
-void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
-{
-	struct net_device *dev = ieee->dev;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
 	u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
 	u8 mode = ieee->current_network.mode;
 	AC_CODING	eACI;
@@ -3778,10 +2478,6 @@ void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
 	PAC_PARAM	pAcParam;
 	u8 i;
 
-#ifndef CONFIG_RTL8185B
-        //for legacy 8185 keep the PARAM unchange.
-	return;
-#else
 	if(!ieee->current_network.QoS_Enable){
 		//legacy ac_xx_param update
 		AcParam.longData = 0;
@@ -3806,19 +2502,15 @@ void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
 					case AC1_BK:
 						write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
 						break;
-
 					case AC0_BE:
 						write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
 						break;
-
 					case AC2_VI:
 						write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
 						break;
-
 					case AC3_VO:
 						write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
 						break;
-
 					default:
 						printk(KERN_WARNING "SetHwReg8185():invalid ACI: %d!\n", eACI);
 						break;
@@ -3849,19 +2541,15 @@ void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
 				case AC1_BK:
 					write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
 					break;
-
 				case AC0_BE:
 					write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
 					break;
-
 				case AC2_VI:
 					write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
 					break;
-
 				case AC3_VO:
 					write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
 					break;
-
 				default:
 					printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
 					break;
@@ -3869,63 +2557,26 @@ void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
 		}
 		ac_param += (sizeof(AC_PARAM));
 	}
-#endif
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_tx_irq_wq(struct work_struct *work);
-#else
-void rtl8180_tx_irq_wq(struct net_device *dev);
-#endif
-
-
-
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_restart_wq(struct work_struct *work);
 //void rtl8180_rq_tx_ack(struct work_struct *work);
-#else
- void rtl8180_restart_wq(struct net_device *dev);
-//void rtl8180_rq_tx_ack(struct net_device *dev);
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_watch_dog_wq(struct work_struct *work);
-#else
-void rtl8180_watch_dog_wq(struct net_device *dev);
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_hw_wakeup_wq(struct work_struct *work);
-#else
-void rtl8180_hw_wakeup_wq(struct net_device *dev);
-#endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_hw_sleep_wq(struct work_struct *work);
-#else
-void rtl8180_hw_sleep_wq(struct net_device *dev);
-#endif
-
-
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_sw_antenna_wq(struct work_struct *work);
-#else
-void rtl8180_sw_antenna_wq(struct net_device *dev);
-#endif
- void rtl8180_watch_dog(struct net_device *dev);
+void rtl8180_watch_dog(struct net_device *dev);
+
 void watch_dog_adaptive(unsigned long data)
 {
-    struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
-//	DMESG("---->watch_dog_adaptive()\n");
-	if(!priv->up)
-	{
+	struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
+
+	if (!priv->up) {
 		DMESG("<----watch_dog_adaptive():driver is not up!\n");
 		return;
 	}
 
-  //      queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
-//{by amy 080312
-#if 1
 	// Tx High Power Mechanism.
 #ifdef HIGH_POWER
 	if(CheckHighPower((struct net_device *)data))
@@ -3934,14 +2585,12 @@ void watch_dog_adaptive(unsigned long data)
 	}
 #endif
 
-#ifdef CONFIG_RTL818X_S
 	// Tx Power Tracking on 87SE.
 #ifdef TX_TRACK
 	//if( priv->bTxPowerTrack )	//lzm mod 080826
 	if( CheckTxPwrTracking((struct net_device *)data));
 		TxPwrTracking87SE((struct net_device *)data);
 #endif
-#endif
 
 	// Perform DIG immediately.
 #ifdef SW_DIG
@@ -3950,20 +2599,14 @@ void watch_dog_adaptive(unsigned long data)
 		queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
 	}
 #endif
-#endif
-//by amy 080312}
    	rtl8180_watch_dog((struct net_device *)data);
 
-
 	queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
 
    	priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME);
 	add_timer(&priv->watch_dog_timer);
-//        DMESG("<----watch_dog_adaptive()\n");
 }
 
-#ifdef ENABLE_DOT11D
-
 static CHANNEL_LIST ChannelPlan[] = {
 	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19},  		//FCC
 	{{1,2,3,4,5,6,7,8,9,10,11},11},                    				//IC
@@ -4038,20 +2681,15 @@ static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ie
 		}
 	}
 }
-#endif
 
-//Add for RF power on power off by lizhaoming 080512
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void GPIOChangeRFWorkItemCallBack(struct work_struct *work);
-#else
-void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee);
-#endif
 
 //YJ,add,080828
 static void rtl8180_statistics_init(struct Stats *pstats)
 {
 	memset(pstats, 0, sizeof(struct Stats));
 }
+
 static void rtl8180_link_detect_init(plink_detect_t plink_detect)
 {
 	memset(plink_detect, 0, sizeof(link_detect_t));
@@ -4070,40 +2708,14 @@ short rtl8180_init(struct net_device *dev)
 	u16 tmpu16;
 	int i, j;
 
-#ifdef ENABLE_DOT11D
-#if 0
-	for(i=0;i<0xFF;i++) {
-		if(i%16 == 0)
-			printk("\n[%x]: ", i/16);
-		printk("\t%4.4x", eprom_read(dev,i));
-	}
-#endif
 	priv->channel_plan = eprom_read(dev, EEPROM_COUNTRY_CODE>>1) & 0xFF;
 	if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
 		printk("rtl8180_init:Error channel plan! Set to default.\n");
 		priv->channel_plan = 0;
 	}
-	//priv->channel_plan = 9;  //Global Domain
 
 	DMESG("Channel plan is %d\n",priv->channel_plan);
 	rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
-#else
-	int ch;
-	//Set Default Channel Plan
-	if(!channels){
-		DMESG("No channels, aborting");
-		return -1;
-	}
-	ch=channels;
-	priv->channel_plan = 0;//hikaru
-	 // set channels 1..14 allowed in given locale
-	for (i=1; i<=14; i++) {
-		(priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
-		ch >>= 1;
-	}
-#endif
-
-	//memcpy(priv->stats,0,sizeof(struct Stats));
 
 	//FIXME: these constants are placed in a bad pleace.
 	priv->txbuffsize = 2048;//1024;
@@ -4112,20 +2724,9 @@ short rtl8180_init(struct net_device *dev)
 	priv->rxringcount = 64;//32;
 	priv->txbeaconcount = 2;
 	priv->rx_skb_complete = 1;
-	//priv->txnp_pending.ispending=0;
-	/* ^^ the SKB does not containt a partial RXed
-	 * packet (is empty)
-	 */
 
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
 	priv->RegThreeWireMode = HW_THREE_WIRE_SI;
-#else
-        priv->RegThreeWireMode = SW_THREE_WIRE;
-#endif
-#endif
 
-//Add for RF power on power off by lizhaoming 080512
 	priv->RFChangeInProgress = false;
 	priv->SetRFPowerStateInProgress = false;
 	priv->RFProgType = 0;
@@ -4133,42 +2734,8 @@ short rtl8180_init(struct net_device *dev)
 
 	priv->irq_enabled=0;
 
-//YJ,modified,080828
-#if 0
-	priv->stats.rxdmafail=0;
-	priv->stats.txrdu=0;
-	priv->stats.rxrdu=0;
-	priv->stats.rxnolast=0;
-	priv->stats.rxnodata=0;
-	//priv->stats.rxreset=0;
-	//priv->stats.rxwrkaround=0;
-	priv->stats.rxnopointer=0;
-	priv->stats.txnperr=0;
-	priv->stats.txresumed=0;
-	priv->stats.rxerr=0;
-	priv->stats.rxoverflow=0;
-	priv->stats.rxint=0;
-	priv->stats.txnpokint=0;
-	priv->stats.txhpokint=0;
-	priv->stats.txhperr=0;
-	priv->stats.ints=0;
-	priv->stats.shints=0;
-	priv->stats.txoverflow=0;
-	priv->stats.txbeacon=0;
-	priv->stats.txbeaconerr=0;
-	priv->stats.txlperr=0;
-	priv->stats.txlpokint=0;
-	priv->stats.txretry=0;//tony 20060601
-	priv->stats.rxcrcerrmin=0;
-	priv->stats.rxcrcerrmid=0;
-	priv->stats.rxcrcerrmax=0;
-	priv->stats.rxicverr=0;
-#else
 	rtl8180_statistics_init(&priv->stats);
 	rtl8180_link_detect_init(&priv->link_detect);
-#endif
-//YJ,modified,080828,end
-
 
 	priv->ack_tx_to_ieee = 0;
 	priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
@@ -4201,8 +2768,6 @@ short rtl8180_init(struct net_device *dev)
 	priv->eRFPowerState = eRfOff;
 	priv->RfOffReason = 0;
 	priv->LedStrategy = SW_LED_MODE0;
-	//priv->NumRxOkInPeriod = 0;  //YJ,del,080828
-	//priv->NumTxOkInPeriod = 0;  //YJ,del,080828
 	priv->TxPollingTimes = 0;//lzm add 080826
 	priv->bLeisurePs = true;
 	priv->dot11PowerSaveMode = eActive;
@@ -4258,13 +2823,10 @@ short rtl8180_init(struct net_device *dev)
 	priv->CurCCKRSSI = 0;
 	priv->RxPower = 0;
 	priv->RSSI = 0;
-	//YJ,add,080828
 	priv->NumTxOkTotal = 0;
 	priv->NumTxUnicast = 0;
 	priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
 	priv->PowerProfile = POWER_PROFILE_AC;
-	//YJ,add,080828,end
-//by amy for rate adaptive
     priv->CurrRetryCnt=0;
     priv->LastRetryCnt=0;
     priv->LastTxokCnt=0;
@@ -4285,8 +2847,6 @@ short rtl8180_init(struct net_device *dev)
 	priv->ForcedDataRate = 0;
 	priv->RegBModeGainStage = 1;
 
-//by amy for rate adaptive
-//by amy 080312}
 	priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
 	spin_lock_init(&priv->irq_lock);
 	spin_lock_init(&priv->irq_th_lock);
@@ -4295,59 +2855,30 @@ short rtl8180_init(struct net_device *dev)
 	spin_lock_init(&priv->rf_ps_lock);
 	sema_init(&priv->wx_sem,1);
 	sema_init(&priv->rf_state,1);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 	INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq);
 	INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq);
 	INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq);
 	INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq);
-	//INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*) rtl8180_watch_dog_wq);
-	//INIT_DELAYED_WORK(&priv->ieee80211->sw_antenna_wq,(void*) rtl8180_sw_antenna_wq);
 	INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update);
 	INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);//+by amy 080312
 	INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);//+by amy 080312
 	INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);//+by amy 080312
 
-	//add for RF power on power off by lizhaoming 080512
 	INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack);
-#else
-	INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq,dev);
-	INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq,dev);
-	//INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*) rtl8180_watch_dog_wq,dev);
-	INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq,dev);
-	INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq,dev);
-	//INIT_WORK(&priv->ieee80211->sw_antenna_wq,(void*) rtl8180_sw_antenna_wq,dev);
-	INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update,priv->ieee80211);
-    INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev);//+by amy 080312
-	INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev);//+by amy 080312
-	INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev);//+by amy 080312
-
-	//add for RF power on power off by lizhaoming 080512
-	INIT_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack, priv->ieee80211);
-#endif
-	//INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq,dev);
 
 	tasklet_init(&priv->irq_rx_tasklet,
 		     (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
 		     (unsigned long)priv);
-//by amy
+
     init_timer(&priv->watch_dog_timer);
 	priv->watch_dog_timer.data = (unsigned long)dev;
 	priv->watch_dog_timer.function = watch_dog_adaptive;
-//by amy
 
-//{by amy 080312
-//by amy for rate adaptive
     init_timer(&priv->rateadapter_timer);
         priv->rateadapter_timer.data = (unsigned long)dev;
         priv->rateadapter_timer.function = timer_rate_adaptive;
 		priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
 		priv->bEnhanceTxPwr=false;
-//by amy for rate adaptive
-//by amy 080312}
-	//priv->ieee80211->func =
-	//	kmalloc(sizeof(struct ieee80211_helper_functions),GFP_KERNEL);
-	//memset(priv->ieee80211->func, 0,
-	  //     sizeof(struct ieee80211_helper_functions));
 
 	priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
 	priv->ieee80211->set_chan = rtl8180_set_chan;
@@ -4362,7 +2893,6 @@ short rtl8180_init(struct net_device *dev)
 	priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable;
 	priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
 
-#ifdef CONFIG_RTL8185B
 	priv->MWIEnable = 0;
 
 	priv->ShortRetryLimit = 7;
@@ -4379,15 +2909,9 @@ short rtl8180_init(struct net_device *dev)
 									(0 ? TCR_SAT : 0);	// FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
 
 	priv->ReceiveConfig	=
-#ifdef CONFIG_RTL818X_S
-#else
-                                                        priv->CSMethod |
-#endif
-//								RCR_ENMARP |
 								RCR_AMF | RCR_ADF |				//accept management/data
 								RCR_ACF |						//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
 								RCR_AB | RCR_AM | RCR_APM |		//accept BC/MC/UC
-								//RCR_AICV | RCR_ACRC32 | 		//accept ICV/CRC error packet
 								(7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
 								(priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
 								(priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
@@ -4403,49 +2927,35 @@ short rtl8180_init(struct net_device *dev)
 								IMR_RQoSOK; // <NOTE> ROK and RQoSOK are mutually exclusive, so, we must handle RQoSOK interrupt to receive QoS frames, 2005.12.09, by rcnjko.
 
 	priv->InitialGain = 6;
-#endif
 
 	hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
 
 	switch (hw_version){
-#ifdef CONFIG_RTL8185B
 		case HW_VERID_R8185B_B:
-#ifdef CONFIG_RTL818X_S
                         priv->card_8185 = VERSION_8187S_C;
 		        DMESG("MAC controller is a RTL8187SE b/g");
 			priv->phy_ver = 2;
 			break;
-#else
-			DMESG("MAC controller is a RTL8185B b/g");
-			priv->card_8185 = 3;
-			priv->phy_ver = 2;
-			break;
-#endif
-#endif
 		case HW_VERID_R8185_ABC:
 			DMESG("MAC controller is a RTL8185 b/g");
 			priv->card_8185 = 1;
 			/* you should not find a card with 8225 PHY ver < C*/
 			priv->phy_ver = 2;
 			break;
-
 		case HW_VERID_R8185_D:
 			DMESG("MAC controller is a RTL8185 b/g (V. D)");
 			priv->card_8185 = 2;
 			/* you should not find a card with 8225 PHY ver < C*/
 			priv->phy_ver = 2;
 			break;
-
 		case HW_VERID_R8180_ABCD:
 			DMESG("MAC controller is a RTL8180");
 			priv->card_8185 = 0;
 			break;
-
 		case HW_VERID_R8180_F:
 			DMESG("MAC controller is a RTL8180 (v. F)");
 			priv->card_8185 = 0;
 			break;
-
 		default:
 			DMESGW("MAC chip not recognized: version %x. Assuming RTL8180",hw_version);
 			priv->card_8185 = 0;
@@ -4459,98 +2969,50 @@ short rtl8180_init(struct net_device *dev)
 	/* you should not found any 8185 Ver B Card */
 	priv->card_8185_Bversion = 0;
 
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
 	// just for sync 85
 	priv->card_type = PCI;
         DMESG("This is a PCI NIC");
-#else
-	config3 = read_nic_byte(dev, CONFIG3);
-	if(config3 & 0x8){
-		priv->card_type = CARDBUS;
-		DMESG("This is a CARDBUS NIC");
-	}
-	else if( config3 & 0x4){
-		priv->card_type = MINIPCI;
-		DMESG("This is a MINI-PCI NIC");
-	}else{
-		priv->card_type = PCI;
-		DMESG("This is a PCI NIC");
-	}
-#endif
-#endif
 	priv->enable_gpio0 = 0;
 
-//by amy for antenna
-#ifdef CONFIG_RTL8185B
 	usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET);
 	DMESG("usValue is 0x%x\n",usValue);
-#ifdef CONFIG_RTL818X_S
 	//3Read AntennaDiversity
+
 	// SW Antenna Diversity.
-	if(	(usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE )
-	{
+	if ((usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE)
 		priv->EEPROMSwAntennaDiversity = false;
-		//printk("EEPROM Disable SW Antenna Diversity\n");
-	}
 	else
-	{
 		priv->EEPROMSwAntennaDiversity = true;
-		//printk("EEPROM Enable SW Antenna Diversity\n");
-	}
+
 	// Default Antenna to use.
-	if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 )
-	{
+	if ((usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1)
 		priv->EEPROMDefaultAntenna1 = false;
-		//printk("EEPROM Default Antenna 0\n");
-	}
 	else
-	{
 		priv->EEPROMDefaultAntenna1 = true;
-		//printk("EEPROM Default Antenna 1\n");
-	}
 
-	//
-	// Antenna diversity mechanism. Added by Roger, 2007.11.05.
-	//
 	if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto
-	{// 0: default from EEPROM.
+		/* 0: default from EEPROM. */
 		priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
-	}
 	else
-	{// 1:disable antenna diversity, 2: enable antenna diversity.
+		/* 1:disable antenna diversity, 2: enable antenna diversity. */
 		priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
-	}
-	//printk("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
-
 
-	//
-	// Default antenna settings. Added by Roger, 2007.11.05.
-	//
-	if( priv->RegDefaultAntenna == 0)
-	{// 0: default from EEPROM.
+	if (priv->RegDefaultAntenna == 0)
+		/* 0: default from EEPROM. */
 		priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
-	}
 	else
-	{// 1: main, 2: aux.
+		/* 1: main, 2: aux. */
 		priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
-	}
-	//printk("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
-#endif
-#endif
-//by amy for antenna
+
 	/* rtl8185 can calc plcp len in HW.*/
 	priv->hw_plcp_len = 1;
 
 	priv->plcp_preamble_mode = 2;
 	/*the eeprom type is stored in RCR register bit #6 */
-	if (RCR_9356SEL & read_nic_dword(dev, RCR)){
+	if (RCR_9356SEL & read_nic_dword(dev, RCR))
 		priv->epromtype=EPROM_93c56;
-		//DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
-	}else{
+	else
 		priv->epromtype=EPROM_93c46;
-		//DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
-	}
 
 	dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
 	dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
@@ -4558,42 +3020,26 @@ short rtl8180_init(struct net_device *dev)
 	dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
 	dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
 	dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8;
-	//DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
-
 
 	for(i=1,j=0; i<14; i+=2,j++){
-
 		word = eprom_read(dev,EPROM_TXPW_CH1_2 + j);
 		priv->chtxpwr[i]=word & 0xff;
 		priv->chtxpwr[i+1]=(word & 0xff00)>>8;
-#ifdef DEBUG_EPROM
-		DMESG("tx word %x:%x",j,word);
-		DMESG("ch %d pwr %x",i,priv->chtxpwr[i]);
-		DMESG("ch %d pwr %x",i+1,priv->chtxpwr[i+1]);
-#endif
 	}
 	if(priv->card_8185){
 		for(i=1,j=0; i<14; i+=2,j++){
-
 			word = eprom_read(dev,EPROM_TXPW_OFDM_CH1_2 + j);
 			priv->chtxpwr_ofdm[i]=word & 0xff;
 			priv->chtxpwr_ofdm[i+1]=(word & 0xff00)>>8;
-#ifdef DEBUG_EPROM
-			DMESG("ofdm tx word %x:%x",j,word);
-			DMESG("ofdm ch %d pwr %x",i,priv->chtxpwr_ofdm[i]);
-			DMESG("ofdm ch %d pwr %x",i+1,priv->chtxpwr_ofdm[i+1]);
-#endif
 		}
 	}
-//{by amy 080312
+
 	//3Read crystal calibtration and thermal meter indication on 87SE.
 
 	// By SD3 SY's request. Added by Roger, 2007.12.11.
 
 	tmpu16 = eprom_read(dev, EEPROM_RSV>>1);
 
-	//printk("ReadAdapterInfo8185(): EEPROM_RSV(%04x)\n", tmpu16);
-
 		// Crystal calibration for Xin and Xout resp.
 		priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; // 0~7.5pF
 		priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK)>>4; // 0~7.5pF
@@ -4605,12 +3051,9 @@ short rtl8180_init(struct net_device *dev)
 		if((tmpu16 & EEPROM_THERMAL_METER_ENABLE)>>13)
 			priv->bTxPowerTrack = true;
 
-//by amy 080312}
-#ifdef CONFIG_RTL8185B
 	word = eprom_read(dev,EPROM_TXPW_BASE);
 	priv->cck_txpwr_base = word & 0xf;
 	priv->ofdm_txpwr_base = (word>>4) & 0xf;
-#endif
 
 	version = eprom_read(dev,EPROM_VERSION);
 	DMESG("EEPROM version %x",version);
@@ -4646,142 +3089,15 @@ DMESG output to andreamrl@tiscali.it THANKS");
 		priv->rf_chip = 0xff & eprom_read(dev,RFCHIPID);
 	}
 
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
 	priv->rf_chip = RF_ZEBRA4;
 	priv->rf_sleep = rtl8225z4_rf_sleep;
 	priv->rf_wakeup = rtl8225z4_rf_wakeup;
-#else
-        priv->rf_chip = RF_ZEBRA2;
-#endif
-	//DMESG("Card reports RF frontend Realtek 8225z2");
-	//DMESGW("This driver has EXPERIMENTAL support for this chipset.");
-	//DMESGW("use it with care and at your own risk and");
 	DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
 
 	priv->rf_close = rtl8225z2_rf_close;
 	priv->rf_init = rtl8225z2_rf_init;
 	priv->rf_set_chan = rtl8225z2_rf_set_chan;
 	priv->rf_set_sens = NULL;
-	//priv->rf_sleep = rtl8225_rf_sleep;
-	//priv->rf_wakeup = rtl8225_rf_wakeup;
-
-#else
-	/* check RF frontend chipset */
-	switch (priv->rf_chip) {
-
-		case RFCHIPID_RTL8225:
-
-		if(priv->card_8185){
-			DMESG("Card reports RF frontend Realtek 8225");
-			DMESGW("This driver has EXPERIMENTAL support for this chipset.");
-			DMESGW("use it with care and at your own risk and");
-			DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
-
-			priv->rf_close = rtl8225_rf_close;
-			priv->rf_init = rtl8225_rf_init;
-			priv->rf_set_chan = rtl8225_rf_set_chan;
-			priv->rf_set_sens = NULL;
-			priv->rf_sleep = rtl8225_rf_sleep;
-			priv->rf_wakeup = rtl8225_rf_wakeup;
-
-		}else{
-			DMESGW("Detected RTL8225 radio on a card recognized as RTL8180");
-			DMESGW("This could not be... something went wrong....");
-			return -ENODEV;
-		}
-			break;
-
-		case RFCHIPID_RTL8255:
-		if(priv->card_8185){
-			DMESG("Card reports RF frontend Realtek 8255");
-			DMESGW("This driver has EXPERIMENTAL support for this chipset.");
-			DMESGW("use it with care and at your own risk and");
-			DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
-
-			priv->rf_close = rtl8255_rf_close;
-			priv->rf_init = rtl8255_rf_init;
-			priv->rf_set_chan = rtl8255_rf_set_chan;
-			priv->rf_set_sens = NULL;
-			priv->rf_sleep = NULL;
-			priv->rf_wakeup = NULL;
-
-		}else{
-			DMESGW("Detected RTL8255 radio on a card recognized as RTL8180");
-			DMESGW("This could not be... something went wrong....");
-			return -ENODEV;
-		}
-			break;
-
-
-		case RFCHIPID_INTERSIL:
-			DMESGW("Card reports RF frontend by Intersil.");
-			DMESGW("This driver has NO support for this chipset.");
-			return -ENODEV;
-			break;
-
-		case RFCHIPID_RFMD:
-			DMESGW("Card reports RF frontend by RFMD.");
-			DMESGW("This driver has NO support for this chipset.");
-			return -ENODEV;
-			break;
-
-		case RFCHIPID_GCT:
-			DMESGW("Card reports RF frontend by GCT.");
-			DMESGW("This driver has EXPERIMENTAL support for this chipset.");
-			DMESGW("use it with care and at your own risk and");
-			DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
-			priv->rf_close = gct_rf_close;
-			priv->rf_init = gct_rf_init;
-			priv->rf_set_chan = gct_rf_set_chan;
-			priv->rf_set_sens = NULL;
-			priv->rf_sleep = NULL;
-			priv->rf_wakeup = NULL;
-			break;
-
-		case RFCHIPID_MAXIM:
-			DMESGW("Card reports RF frontend by MAXIM.");
-			DMESGW("This driver has EXPERIMENTAL support for this chipset.");
-			DMESGW("use it with care and at your own risk and");
-			DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
-			priv->rf_close = maxim_rf_close;
-			priv->rf_init = maxim_rf_init;
-			priv->rf_set_chan = maxim_rf_set_chan;
-			priv->rf_set_sens = NULL;
-			priv->rf_sleep = NULL;
-			priv->rf_wakeup = NULL;
-			break;
-
-		case RFCHIPID_PHILIPS:
-			DMESG("Card reports RF frontend by Philips.");
-			DMESG("OK! Philips SA2400 radio chipset is supported.");
-			priv->rf_close = sa2400_rf_close;
-			priv->rf_init = sa2400_rf_init;
-			priv->rf_set_chan = sa2400_rf_set_chan;
-			priv->rf_set_sens = sa2400_rf_set_sens;
-			priv->sens = SA2400_RF_DEF_SENS; /* default sensitivity */
-			priv->max_sens = SA2400_RF_MAX_SENS; /* maximum sensitivity */
-			priv->rf_sleep = NULL;
-			priv->rf_wakeup = NULL;
-
-			if(priv->digphy){
-				DMESGW("Digital PHY found");
-				DMESGW("Philips DIGITAL PHY is untested! *Please*\
-	report success/failure to <andreamrl@tiscali.it>");
-			}else{
-				DMESG ("Analog PHY found");
-			}
-
-			break;
-
-		default:
-			DMESGW("Unknown RF module %x",priv->rf_chip);
-			DMESGW("Exiting...");
-			return -1;
-
-	}
-#endif
-
 
 	if(!priv->card_8185){
 		if(priv->antb)
@@ -4828,11 +3144,7 @@ DMESG output to andreamrl@tiscali.it THANKS");
 				  TX_BEACON_RING_ADDR))
 		return -ENOMEM;
 
-
-	//priv->beacon_buf=NULL;
-
 	if(!priv->card_8185){
-
 		if(read_nic_byte(dev, CONFIG0) & (1<<CONFIG0_WEP40_SHIFT))
 			DMESG ("40-bit WEP is supported in hardware");
 		else
@@ -4855,21 +3167,14 @@ DMESG output to andreamrl@tiscali.it THANKS");
 		DMESG("IRQ %d",dev->irq);
 	}
 
-#ifdef DEBUG_EPROM
-	dump_eprom(dev);
-#endif
-
 	return 0;
-
 }
 
-
 void rtl8180_no_hw_wep(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
-	if(!priv->card_8185)
-	{
+	if (!priv->card_8185) {
 		u8 security;
 
 		security  = read_nic_byte(dev, SECURITY);
@@ -4877,19 +3182,9 @@ void rtl8180_no_hw_wep(struct net_device *dev)
 		security &=~(1<<SECURITY_WEP_RX_ENABLE_SHIFT);
 
 		write_nic_byte(dev, SECURITY, security);
-
-	}else{
-
-		//FIXME!!!
 	}
-	/*
-	  write_nic_dword(dev,TX_CONF,read_nic_dword(dev,TX_CONF) |
-	  (1<<TX_NOICV_SHIFT) );
-	*/
-//	priv->ieee80211->hw_wep=0;
 }
 
-
 void rtl8180_set_hw_wep(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -4908,10 +3203,6 @@ void rtl8180_set_hw_wep(struct net_device *dev)
 	write_nic_dword(dev,KEY0+4+4,(priv->key0[2]));
 	write_nic_dword(dev,KEY0+4+4+4,(key0_word4));
 
-	/*
-	  TX_CONF,read_nic_dword(dev,TX_CONF) &~(1<<TX_NOICV_SHIFT));
-	*/
-
 	security  = read_nic_byte(dev,SECURITY);
 	security |= (1<<SECURITY_WEP_TX_ENABLE_SHIFT);
 	security |= (1<<SECURITY_WEP_RX_ENABLE_SHIFT);
@@ -4923,8 +3214,6 @@ void rtl8180_set_hw_wep(struct net_device *dev)
 	DMESG("key %x %x %x %x",read_nic_dword(dev,KEY0+4+4+4),
 	      read_nic_dword(dev,KEY0+4+4),read_nic_dword(dev,KEY0+4),
 	      read_nic_dword(dev,KEY0));
-
-	//priv->ieee80211->hw_wep=1;
 }
 
 
@@ -4933,10 +3222,8 @@ void rtl8185_rf_pins_enable(struct net_device *dev)
 //	u16 tmp;
 //	tmp = read_nic_word(dev, RFPinsEnable);
 	write_nic_word(dev, RFPinsEnable, 0x1fff);// | tmp);
-//	write_nic_word(dev, RFPinsEnable,7 | tmp);
 }
 
-
 void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
 {
 	u8 conf3;
@@ -4950,10 +3237,8 @@ void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
 	conf3 = read_nic_byte(dev, CONFIG3);
 	write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
 }
 
-
 void rtl8180_set_anaparam(struct net_device *dev, u32 a)
 {
 	u8 conf3;
@@ -4969,7 +3254,6 @@ void rtl8180_set_anaparam(struct net_device *dev, u32 a)
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 }
 
-
 void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
 {
 	write_nic_byte(dev, TX_ANTENNA, ant);
@@ -4977,55 +3261,38 @@ void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
 	mdelay(1);
 }
 
-
 void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
 {
-	//u8 phyr;
 	u32 phyw;
-	//int i;
 
 	adr |= 0x80;
 
 	phyw= ((data<<8) | adr);
-#if 0
-
-	write_nic_dword(dev, PHY_ADR, phyw);
 
-	//read_nic_dword(dev, PHY_ADR);
-	for(i=0;i<10;i++){
-		write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
-		phyr = read_nic_byte(dev, PHY_READ);
-		if(phyr == (data&0xff)) break;
-
-	}
-#else
 	// Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
 	write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
 	write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
 	write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
 	write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
-#endif
+
 	/* this is ok to fail when we write AGC table. check for AGC table might be
 	 * done by masking with 0x7f instead of 0xff
 	 */
 	//if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data,adr);
 }
 
-
 inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
 {
 	data = data & 0xff;
 	rtl8185_write_phy(dev, adr, data);
 }
 
-
 void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
 {
 	data = data & 0xff;
 	rtl8185_write_phy(dev, adr, data | 0x10000);
 }
 
-
 /* 70*3 = 210 ms
  * I hope this is enougth
  */
@@ -5054,9 +3321,6 @@ void write_phy(struct net_device *dev, u8 adr, u8 data)
 		if(phy == data){ //SUCCESS!
 			force_pci_posting(dev);
 			mdelay(3); //random value
-#ifdef DEBUG_BB
-			DMESG("Phy wr %x,%x",adr,data);
-#endif
 			return;
 		}else{
 			force_pci_posting(dev);
@@ -5072,55 +3336,32 @@ void rtl8185_set_rate(struct net_device *dev)
 	u16 word;
 	int basic_rate,min_rr_rate,max_rr_rate;
 
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	//if (ieee80211_is_54g(priv->ieee80211->current_network) &&
-//		priv->ieee80211->state == IEEE80211_LINKED){
 	basic_rate = ieeerate2rtlrate(240);
 	min_rr_rate = ieeerate2rtlrate(60);
 	max_rr_rate = ieeerate2rtlrate(240);
 
-//
-//	}else{
-//		basic_rate = ieeerate2rtlrate(20);
-//		min_rr_rate = ieeerate2rtlrate(10);
-//		max_rr_rate = ieeerate2rtlrate(110);
-//	}
-
 	write_nic_byte(dev, RESP_RATE,
 			max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
 
 	word  = read_nic_word(dev, BRSR);
 	word &= ~BRSR_MBR_8185;
 
-
 	for(i=0;i<=basic_rate;i++)
 		word |= (1<<i);
 
 	write_nic_word(dev, BRSR, word);
-	//DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE),read_nic_word(dev,BRSR));
 }
 
-
-
 void rtl8180_adapter_start(struct net_device *dev)
 {
         struct r8180_priv *priv = ieee80211_priv(dev);
 	u32 anaparam;
 	u16 word;
 	u8 config3;
-//	int i;
 
 	rtl8180_rtx_disable(dev);
 	rtl8180_reset(dev);
 
-	/* seems that 0xffff or 0xafff will cause
-	 * HW interrupt line crash
-	 */
-
-	//priv->irq_mask = 0xafff;
-//	priv->irq_mask = 0x4fcf;
-
 	/* enable beacon timeout, beacon TX ok and err
 	 * LP tx ok and err, HP TX ok and err, NP TX ok and err,
 	 * RX ok and ERR, and GP timer */
@@ -5152,8 +3393,6 @@ void rtl8180_adapter_start(struct net_device *dev)
 	/* These might be unnecessary since we do in rx_enable / tx_enable */
 	fix_rx_fifo(dev);
 	fix_tx_fifo(dev);
-	/*set_nic_rxring(dev);
-	  set_nic_txring(dev);*/
 
 	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
 
@@ -5174,9 +3413,6 @@ void rtl8180_adapter_start(struct net_device *dev)
 	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
 
 	write_nic_dword(dev,INT_TIMEOUT,0);
-#ifdef DEBUG_REGISTERS
-	rtl8180_dump_reg(dev);
-#endif
 
 	if(!priv->card_8185)
 	{
@@ -5191,7 +3427,6 @@ void rtl8180_adapter_start(struct net_device *dev)
 		write_nic_byte(dev, CONFIG5,
 			read_nic_byte(dev, CONFIG5) &~ (1<<AGCRESET_SHIFT));
 	}else{
-
 		write_nic_byte(dev, WPA_CONFIG, 0);
 		//write_nic_byte(dev, TESTR, 0xd);
 	}
@@ -5201,28 +3436,23 @@ void rtl8180_adapter_start(struct net_device *dev)
 	if(priv->card_8185){
 		rtl8185_set_rate(dev);
 		write_nic_byte(dev, RATE_FALLBACK, 0x81);
-	//	write_nic_byte(dev, 0xdf, 0x15);
 	}else{
 		word  = read_nic_word(dev, BRSR);
 		word &= ~BRSR_MBR;
 		word &= ~BRSR_BPLCP;
 		word |= ieeerate2rtlrate(priv->ieee80211->basic_rate);
-//by amy
-              word |= 0x0f;
-//by amy
+		word |= 0x0f;
 		write_nic_word(dev, BRSR, word);
 	}
 
-
 	if(priv->card_8185){
 		write_nic_byte(dev, GP_ENABLE,read_nic_byte(dev, GP_ENABLE) & ~(1<<6));
 
 		//FIXME cfg 3 ClkRun enable - isn't it ReadOnly ?
 		rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
 		write_nic_byte(dev,CONFIG3, read_nic_byte(dev, CONFIG3)
-|(1<<CONFIG3_CLKRUN_SHIFT));
+			       | (1 << CONFIG3_CLKRUN_SHIFT));
 		rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
 	}
 
 	priv->rf_init(dev);
@@ -5232,51 +3462,23 @@ void rtl8180_adapter_start(struct net_device *dev)
 	rtl8180_irq_enable(dev);
 
 	netif_start_queue(dev);
-	/*DMESG ("lfree %d",get_curr_tx_free_desc(dev,LOW_PRIORITY));
-
-	DMESG ("nfree %d",get_curr_tx_free_desc(dev,NORM_PRIORITY));
-
-	DMESG ("hfree %d",get_curr_tx_free_desc(dev,HI_PRIORITY));
-	if(check_nic_enought_desc(dev,NORM_PRIORITY)) DMESG("NORM OK");
-	if(check_nic_enought_desc(dev,HI_PRIORITY)) DMESG("HI OK");
-	if(check_nic_enought_desc(dev,LOW_PRIORITY)) DMESG("LOW OK");*/
 }
 
-
-
 /* this configures registers for beacon tx and enables it via
  * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
  * be used to stop beacon transmission
  */
 void rtl8180_start_tx_beacon(struct net_device *dev)
 {
-//	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 	u16 word;
-//	DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
 
 	DMESG("Enabling beacon TX");
-	//write_nic_byte(dev, 0x42,0xe6);// TCR
-//	set_nic_txring(dev);
-//	fix_tx_fifo(dev);
 	rtl8180_prepare_beacon(dev);
 	rtl8180_irq_disable(dev);
 	rtl8180_beacon_tx_enable(dev);
-#if 0
-	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-	//write_nic_byte(dev,0x9d,0x20); //DMA Poll
-	//write_nic_word(dev,0x7a,0);
-	//write_nic_word(dev,0x7a,0x8000);
 
-#if 0
-	word  = read_nic_word(dev, BcnItv);
-	word &= ~BcnItv_BcnItv; // clear Bcn_Itv
-	word |= priv->ieee80211->current_network.beacon_interval;//0x64;
-	write_nic_word(dev, BcnItv, word);
-#endif
-#endif
 	word = read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd;
 	write_nic_word(dev, AtimWnd,word);// word |=
-//priv->ieee80211->current_network.atim_window);
 
 	word  = read_nic_word(dev, BintrItv);
 	word &= ~BintrItv_BintrItv;
@@ -5286,30 +3488,11 @@ void rtl8180_start_tx_beacon(struct net_device *dev)
 	*/
 	write_nic_word(dev, BintrItv, word);
 
-
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
 
-//	rtl8180_beacon_tx_enable(dev);
-#ifdef CONFIG_RTL8185B
         rtl8185b_irq_enable(dev);
-#else
-	rtl8180_irq_enable(dev);
-#endif
-	/* VV !!!!!!!!!! VV*/
-	/*
-	rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,0x9d,0x00);
-	rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
-*/
-//	DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
-
 }
 
-
-
-/***************************************************************************
-    -------------------------------NET STUFF---------------------------
-***************************************************************************/
 static struct net_device_stats *rtl8180_stats(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -5326,121 +3509,49 @@ MgntActSet_802_11_PowerSaveMode(
 	RT_PS_MODE		rtPsMode
 )
 {
-
 	// Currently, we do not change power save mode on IBSS mode.
 	if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
-	{
 		return false;
-	}
 
-	//
-	// <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
-	// some AP will not response to our mgnt frames with PwrMgt bit set,
-	// e.g. cannot associate the AP.
-	// So I commented out it. 2005.02.16, by rcnjko.
-	//
-//	// Change device's power save mode.
-//	Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
-
-	// Update power save mode configured.
-//	priv->dot11PowerSaveMode = rtPsMode;
 	priv->ieee80211->ps = rtPsMode;
-	// Determine ListenInterval.
-#if 0
-	if(priv->dot11PowerSaveMode == eMaxPs)
-	{
-		priv->ieee80211->ListenInterval = 10;
-	}
-	else
-	{
-		priv->ieee80211->ListenInterval = 2;
-	}
-#endif
+
 	return true;
 }
 
-//================================================================================
-// Leisure Power Save in linked state.
-//================================================================================
-
-//
-//	Description:
-//		Enter the leisure power save mode.
-//
-void
-LeisurePSEnter(
-	struct r8180_priv *priv
-	)
+void LeisurePSEnter(struct r8180_priv *priv)
 {
-	if (priv->bLeisurePs)
-	{
+	if (priv->bLeisurePs) {
 		if (priv->ieee80211->ps == IEEE80211_PS_DISABLED)
-		{
-			//printk("----Enter PS\n");
 			MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);//IEEE80211_PS_ENABLE
-		}
 	}
 }
 
-
-//
-//	Description:
-//		Leave the leisure power save mode.
-//
-void
-LeisurePSLeave(
-	struct r8180_priv *priv
-	)
+void LeisurePSLeave(struct r8180_priv *priv)
 {
-	if (priv->bLeisurePs)
-	{
+	if (priv->bLeisurePs) {
 		if (priv->ieee80211->ps != IEEE80211_PS_DISABLED)
-		{
-			//printk("----Leave PS\n");
 			MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_DISABLED);
-		}
 	}
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 void rtl8180_hw_wakeup_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 = to_delayed_work(work);
 	struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
 	struct net_device *dev = ieee->dev;
-#else
-void rtl8180_hw_wakeup_wq(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
 
-//	printk("dev is %d\n",dev);
-//	printk("&*&(^*(&(&=========>%s()\n", __func__);
 	rtl8180_hw_wakeup(dev);
-
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_hw_sleep_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 = to_delayed_work(work);
         struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
         struct net_device *dev = ieee->dev;
-#else
-void rtl8180_hw_sleep_wq(struct net_device *dev)
-{
-        struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
 
         rtl8180_hw_sleep_down(dev);
 }
 
-//YJ,add,080828,for KeepAlive
 static void MgntLinkKeepAlive(struct r8180_priv *priv )
 {
 	if (priv->keepAliveLevel == 0)
@@ -5451,7 +3562,6 @@ static void MgntLinkKeepAlive(struct r8180_priv *priv )
 		//
 		// Keep-Alive.
 		//
-		//printk("LastTx:%d Tx:%d LastRx:%d Rx:%ld Idle:%d\n",priv->link_detect.LastNumTxUnicast,priv->NumTxUnicast, priv->link_detect.LastNumRxUnicast, priv->ieee80211->NumRxUnicast, priv->link_detect.IdleCount);
 
 		if ( (priv->keepAliveLevel== 2) ||
 			(priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
@@ -5477,9 +3587,9 @@ static void MgntLinkKeepAlive(struct r8180_priv *priv )
 		priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
 	}
 }
-//YJ,add,080828,for KeepAlive,end
 
 static u8 read_acadapter_file(char *filename);
+
 void rtl8180_watch_dog(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -5488,20 +3598,18 @@ void rtl8180_watch_dog(struct net_device *dev)
 	u32 TotalRxNum = 0;
 	u16 SlotIndex = 0;
 	u16 i = 0;
-#ifdef ENABLE_IPS
 	if(priv->ieee80211->actscanning == false){
 		if((priv->ieee80211->iw_mode != IW_MODE_ADHOC) && (priv->ieee80211->state == IEEE80211_NOLINK) && (priv->ieee80211->beinretry == false) && (priv->eRFPowerState == eRfOn)){
 			IPSEnter(dev);
 		}
 	}
-#endif
 	//YJ,add,080828,for link state check
 	if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){
 		SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum;
 		priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod;
 		for( i=0; i<priv->link_detect.SlotNum; i++ )
 			TotalRxNum+= priv->link_detect.RxFrameNum[i];
-		//printk("&&&&&=== TotalRxNum = %d\n", TotalRxNum);
+
 		if(TotalRxNum == 0){
 			priv->ieee80211->state = IEEE80211_ASSOCIATING;
 			queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
@@ -5513,47 +3621,13 @@ void rtl8180_watch_dog(struct net_device *dev)
 
 	//YJ,add,080828,for LPS
 #ifdef ENABLE_LPS
-	if(priv->PowerProfile == POWER_PROFILE_BATTERY )
-	{
-		//Turn on LeisurePS on battery power
-		//printk("!!!!!On battery power\n");
+	if (priv->PowerProfile == POWER_PROFILE_BATTERY)
 		priv->bLeisurePs = true;
-	}
-	else if(priv->PowerProfile == POWER_PROFILE_AC )
-	{
-		// Turn off LeisurePS on AC power
-		//printk("----On AC power\n");
+	else if (priv->PowerProfile == POWER_PROFILE_AC) {
 		LeisurePSLeave(priv);
 		priv->bLeisurePs= false;
 	}
-#endif
 
-#if 0
-#ifndef ENABLE_LPS
-	if(priv->ieee80211->state == IEEE80211_LINKED){
-		if(	priv->NumRxOkInPeriod> 666 ||
-			priv->NumTxOkInPeriod > 666 ) {
-			bBusyTraffic = true;
-		}
-		if((priv->ieee80211->NumRxData + priv->NumTxOkInPeriod)<8) {
-			bEnterPS= true;
-		}
-		if(bEnterPS) {
-			LeisurePSEnter(priv);
-		}
-		else {
-			LeisurePSLeave(priv);
-		}
-	}
-	else	{
-		LeisurePSLeave(priv);
-	}
-#endif
-	priv->NumRxOkInPeriod = 0;
-	priv->NumTxOkInPeriod = 0;
-	priv->ieee80211->NumRxData = 0;
-#else
-#ifdef ENABLE_LPS
 	if(priv->ieee80211->state == IEEE80211_LINKED){
 		priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod;
 		//printk("TxOk=%d RxOk=%d\n", priv->link_detect.NumTxOkInPeriod, priv->link_detect.NumRxOkInPeriod);
@@ -5564,74 +3638,50 @@ void rtl8180_watch_dog(struct net_device *dev)
 		if(((priv->link_detect.NumRxOkInPeriod + priv->link_detect.NumTxOkInPeriod) > 8)
 			|| (priv->link_detect.NumRxOkInPeriod > 2)) {
 			bEnterPS= false;
-		}
-		else {
+		} else
 			bEnterPS= true;
-		}
 
-		if(bEnterPS) {
+		if (bEnterPS)
 			LeisurePSEnter(priv);
-		}
-		else {
+		else
 			LeisurePSLeave(priv);
-		}
-	}
-	else{
+	} else
 		LeisurePSLeave(priv);
-	}
 #endif
 	priv->link_detect.bBusyTraffic = bBusyTraffic;
 	priv->link_detect.NumRxOkInPeriod = 0;
 	priv->link_detect.NumTxOkInPeriod = 0;
 	priv->ieee80211->NumRxDataInPeriod = 0;
 	priv->ieee80211->NumRxBcnInPeriod = 0;
-#endif
 }
+
 int _rtl8180_up(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	//int i;
 
 	priv->up=1;
 
 	DMESG("Bringing up iface");
-#ifdef CONFIG_RTL8185B
 	rtl8185b_adapter_start(dev);
 	rtl8185b_rx_enable(dev);
 	rtl8185b_tx_enable(dev);
-#else
-	rtl8180_adapter_start(dev);
-	rtl8180_rx_enable(dev);
-	rtl8180_tx_enable(dev);
-#endif
-#ifdef ENABLE_IPS
 	if(priv->bInactivePs){
 		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
 			IPSLeave(dev);
 	}
-#endif
-//by amy 080312
 #ifdef RATE_ADAPT
        timer_rate_adaptive((unsigned long)dev);
 #endif
-//by amy 080312
 	watch_dog_adaptive((unsigned long)dev);
 #ifdef SW_ANTE
         if(priv->bSwAntennaDiverity)
 			SwAntennaDiversityTimerCallback(dev);
 #endif
-//	IPSEnter(dev);
 	ieee80211_softmac_start_protocol(priv->ieee80211);
 
-//Add for RF power on power off by lizhaoming 080512
-//	priv->eRFPowerState = eRfOn;
-//	printk("\n--------Start queue_work:GPIOChangeRFWorkItem");
-//	queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->GPIOChangeRFWorkItem,1000);
-
 	return 0;
 }
 
-
 int rtl8180_open(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -5641,10 +3691,8 @@ int rtl8180_open(struct net_device *dev)
 	ret = rtl8180_up(dev);
 	up(&priv->wx_sem);
 	return ret;
-
 }
 
-
 int rtl8180_up(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -5654,7 +3702,6 @@ int rtl8180_up(struct net_device *dev)
 	return _rtl8180_up(dev);
 }
 
-
 int rtl8180_close(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -5665,14 +3712,14 @@ int rtl8180_close(struct net_device *dev)
 	up(&priv->wx_sem);
 
 	return ret;
-
 }
 
 int rtl8180_down(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
-	if (priv->up == 0) return -1;
+	if (priv->up == 0)
+		return -1;
 
 	priv->up=0;
 
@@ -5683,33 +3730,24 @@ int rtl8180_down(struct net_device *dev)
 	rtl8180_rtx_disable(dev);
 	rtl8180_irq_disable(dev);
 	del_timer_sync(&priv->watch_dog_timer);
-	//cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
-//{by amy 080312
-    del_timer_sync(&priv->rateadapter_timer);
-    cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
-//by amy 080312}
+	del_timer_sync(&priv->rateadapter_timer);
+	cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
 	cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
 	cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
 	cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
 	cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
 	del_timer_sync(&priv->SwAntennaDiversityTimer);
 	SetZebraRFPowerState8185(dev,eRfOff);
-	//ieee80211_softmac_stop_protocol(priv->ieee80211);
 	memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network));
 	priv->ieee80211->state = IEEE80211_NOLINK;
 	return 0;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_restart_wq(struct work_struct *work)
 {
 	struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
 	struct net_device *dev = priv->dev;
-#else
-void rtl8180_restart_wq(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
+
 	down(&priv->wx_sem);
 
 	rtl8180_commit(dev);
@@ -5720,26 +3758,20 @@ void rtl8180_restart_wq(struct net_device *dev)
 void rtl8180_restart(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
-	//rtl8180_commit(dev);
+
 	schedule_work(&priv->reset_wq);
-	//DMESG("TXTIMEOUT");
 }
 
-
 void rtl8180_commit(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
-	if (priv->up == 0) return ;
-//+by amy 080312
+	if (priv->up == 0)
+		return ;
+
 	del_timer_sync(&priv->watch_dog_timer);
-	//cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
-//{by amy 080312
-//by amy for rate adaptive
-    del_timer_sync(&priv->rateadapter_timer);
-    cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
-//by amy for rate adaptive
-//by amy 080312}
+	del_timer_sync(&priv->rateadapter_timer);
+	cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
 	cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
 	cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
 	cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
@@ -5751,39 +3783,19 @@ void rtl8180_commit(struct net_device *dev)
 	_rtl8180_up(dev);
 }
 
-
 static void r8180_set_multicast(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	short promisc;
 
-	//down(&priv->wx_sem);
-
 	promisc = (dev->flags & IFF_PROMISC) ? 1:0;
 
 	if (promisc != priv->promisc)
 		rtl8180_restart(dev);
 
 	priv->promisc = promisc;
-
-	//up(&priv->wx_sem);
 }
 
-#if 0
-/* this is called by the kernel when it needs to TX a 802.3 encapsulated frame*/
-int rtl8180_8023_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&priv->tx_lock,flags);
-	ret = ieee80211_r8180_8023_hardstartxmit(skb,priv->ieee80211);
-	spin_unlock_irqrestore(&priv->tx_lock,flags);
-	return ret;
-}
-#endif
-
 int r8180_set_mac_adr(struct net_device *dev, void *mac)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -5810,27 +3822,20 @@ int r8180_set_mac_adr(struct net_device *dev, void *mac)
 int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
 	struct iwreq *wrq = (struct iwreq *) rq;
 	int ret=-1;
+
 	switch (cmd) {
-	    case RTL_IOCTL_WPA_SUPPLICANT:
+	case RTL_IOCTL_WPA_SUPPLICANT:
 		ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
 		return ret;
-
-	    default:
+	default:
 		return -EOPNOTSUPP;
 	}
 
 	return -EOPNOTSUPP;
 }
 
-
-
-/****************************************************************************
-     -----------------------------PCI STUFF---------------------------
-*****************************************************************************/
-
 static const struct net_device_ops rtl8180_netdev_ops = {
 	.ndo_open		= rtl8180_open,
 	.ndo_stop		= rtl8180_close,
@@ -5850,14 +3855,9 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
 	unsigned long ioaddr = 0;
 	struct net_device *dev = NULL;
 	struct r8180_priv *priv= NULL;
-	//u8 *ptr;
 	u8 unit = 0;
 
-#ifdef CONFIG_RTL8180_IO_MAP
-	unsigned long pio_start, pio_len, pio_flags;
-#else
 	unsigned long pmem_start, pmem_len, pmem_flags;
-#endif //end #ifdef RTL_IO_MAP
 
 	DMESG("Configuring chip resources");
 
@@ -5867,7 +3867,6 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
 	}
 
 	pci_set_master(pdev);
-	//pci_set_wmi(pdev);
 	pci_set_dma_mask(pdev, 0xffffff00ULL);
 	pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
 	dev = alloc_ieee80211(sizeof(struct r8180_priv));
@@ -5876,38 +3875,11 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
 	priv = ieee80211_priv(dev);
 	priv->ieee80211 = netdev_priv(dev);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-        SET_MODULE_OWNER(dev);
-#endif
 	pci_set_drvdata(pdev, dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	priv = ieee80211_priv(dev);
-//	memset(priv,0,sizeof(struct r8180_priv));
-	priv->pdev=pdev;
-
-
-#ifdef CONFIG_RTL8180_IO_MAP
-
-	pio_start = (unsigned long)pci_resource_start (pdev, 0);
-	pio_len = (unsigned long)pci_resource_len (pdev, 0);
-	pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
-
-      	if (!(pio_flags & IORESOURCE_IO)) {
-		DMESG("region #0 not a PIO resource, aborting");
-		goto fail;
-	}
-
-	//DMESG("IO space @ 0x%08lx", pio_start );
-	if( ! request_region( pio_start, pio_len, RTL8180_MODULE_NAME ) ){
-		DMESG("request_region failed!");
-		goto fail;
-	}
-
-	ioaddr = pio_start;
-	dev->base_addr = ioaddr; // device I/O address
-
-#else
+	priv->pdev = pdev;
 
 	pmem_start = pci_resource_start(pdev, 1);
 	pmem_len = pci_resource_len(pdev, 1);
@@ -5918,31 +3890,22 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
 		goto fail;
 	}
 
-	//DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
 	if( ! request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) {
 		DMESG("request_mem_region failed!");
 		goto fail;
 	}
 
-
 	ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
 	if( ioaddr == (unsigned long)NULL ){
 		DMESG("ioremap failed!");
-	       // release_mem_region( pmem_start, pmem_len );
 		goto fail1;
 	}
 
 	dev->mem_start = ioaddr; // shared mem start
 	dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
 
-#endif //end #ifdef RTL_IO_MAP
-
-#ifdef CONFIG_RTL8185B
-	//pci_read_config_byte(pdev, 0x05, ptr);
-	//pci_write_config_byte(pdev, 0x05, (*ptr) & (~0x04));
 	pci_read_config_byte(pdev, 0x05, &unit);
 	pci_write_config_byte(pdev, 0x05, unit & (~0x04));
-#endif
 
 	dev->irq = pdev->irq;
 	priv->irq = 0;
@@ -5950,24 +3913,15 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
 	dev->netdev_ops = &rtl8180_netdev_ops;
 	dev->wireless_handlers = &r8180_wx_handlers_def;
 
-#if WIRELESS_EXT >= 12
-#if WIRELESS_EXT < 17
-	dev->get_wireless_stats = r8180_get_wireless_stats;
-#endif
-	dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
-#endif
-
 	dev->type=ARPHRD_ETHER;
 	dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13
 
 	if (dev_alloc_name(dev, ifname) < 0){
                 DMESG("Oops: devname already taken! Trying wlan%%d...\n");
 		ifname = "wlan%d";
-	//	ifname = "ath%d";
 		dev_alloc_name(dev, ifname);
         }
 
-
 	if(rtl8180_init(dev)!=0){
 		DMESG("Initialization failed");
 		goto fail1;
@@ -5981,28 +3935,14 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
 
 	DMESG("Driver probe completed\n");
 	return 0;
-
 fail1:
-
-#ifdef CONFIG_RTL8180_IO_MAP
-
-	if( dev->base_addr != 0 ){
-
-		release_region(dev->base_addr,
-	       pci_resource_len(pdev, 0) );
-	}
-#else
 	if( dev->mem_start != (unsigned long)NULL ){
 		iounmap( (void *)dev->mem_start );
 		release_mem_region( pci_resource_start(pdev, 1),
 				    pci_resource_len(pdev, 1) );
 	}
-#endif //end #ifdef RTL_IO_MAP
-
-
 fail:
 	if(dev){
-
 		if (priv->irq) {
 			free_irq(dev->irq, dev);
 			dev->irq=0;
@@ -6015,57 +3955,38 @@ fail:
 	DMESG("wlan driver load failed\n");
 	pci_set_drvdata(pdev, NULL);
 	return -ENODEV;
-
 }
 
-
 static void __devexit rtl8180_pci_remove(struct pci_dev *pdev)
 {
 	struct r8180_priv *priv;
 	struct net_device *dev = pci_get_drvdata(pdev);
- 	if(dev){
 
+	if (dev) {
 		unregister_netdev(dev);
 
-		priv=ieee80211_priv(dev);
+		priv = ieee80211_priv(dev);
 
 		rtl8180_proc_remove_one(dev);
 		rtl8180_down(dev);
 		priv->rf_close(dev);
 		rtl8180_reset(dev);
-		//rtl8180_rtx_disable(dev);
-		//rtl8180_irq_disable(dev);
 		mdelay(10);
-		//write_nic_word(dev,INTA,read_nic_word(dev,INTA));
-		//force_pci_posting(dev);
-		//mdelay(10);
 
 		if(priv->irq){
-
 			DMESG("Freeing irq %d",dev->irq);
 			free_irq(dev->irq, dev);
 			priv->irq=0;
-
 		}
 
 		free_rx_desc_ring(dev);
 		free_tx_desc_rings(dev);
-	//	free_beacon_desc_ring(dev,priv->txbeaconcount);
-
-#ifdef CONFIG_RTL8180_IO_MAP
 
-		if( dev->base_addr != 0 ){
-
-			release_region(dev->base_addr,
-				       pci_resource_len(pdev, 0) );
-		}
-#else
 		if( dev->mem_start != (unsigned long)NULL ){
 			iounmap( (void *)dev->mem_start );
 			release_mem_region( pci_resource_start(pdev, 1),
 					    pci_resource_len(pdev, 1) );
 		}
-#endif /*end #ifdef RTL_IO_MAP*/
 
 		free_ieee80211(dev);
 	}
@@ -6074,7 +3995,6 @@ static void __devexit rtl8180_pci_remove(struct pci_dev *pdev)
 	DMESG("wlan driver removed\n");
 }
 
-
 /* fun with the built-in ieee80211 stack... */
 extern int ieee80211_crypto_init(void);
 extern void ieee80211_crypto_deinit(void);
@@ -6117,21 +4037,13 @@ static int __init rtl8180_pci_module_init(void)
 	DMESG("Wireless extensions version %d", WIRELESS_EXT);
 	rtl8180_proc_module_init();
 
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
-      if(0!=pci_module_init(&rtl8180_pci_driver))
-#else
-      if(0!=pci_register_driver(&rtl8180_pci_driver))
-#endif
-	//if(0!=pci_module_init(&rtl8180_pci_driver))
-	{
+      if (pci_register_driver(&rtl8180_pci_driver)) {
 		DMESG("No device found");
-		/*pci_unregister_driver (&rtl8180_pci_driver);*/
 		return -ENODEV;
 	}
 	return 0;
 }
 
-
 static void __exit rtl8180_pci_module_exit(void)
 {
 	pci_unregister_driver (&rtl8180_pci_driver);
@@ -6143,7 +4055,6 @@ static void __exit rtl8180_pci_module_exit(void)
 	DMESG("Exiting");
 }
 
-
 void rtl8180_try_wake_queue(struct net_device *dev, int pri)
 {
 	unsigned long flags;
@@ -6158,25 +4069,17 @@ void rtl8180_try_wake_queue(struct net_device *dev, int pri)
 		ieee80211_wake_queue(priv->ieee80211);
 }
 
-/*****************************************************************************
-      -----------------------------IRQ STUFF---------------------------
-******************************************************************************/
-
 void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
 {
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
 	u32 *tail; //tail virtual addr
 	u32 *head; //head virtual addr
 	u32 *begin;//start of ring virtual addr
 	u32 *nicv; //nic pointer virtual addr
-//	u32 *txdv; //packet just TXed
 	u32 nic; //nic pointer physical addr
 	u32 nicbegin;// start of ring physical addr
-//	short txed;
 	unsigned long flag;
 	/* physical addr are ok on 32 bits since we set DMA mask*/
-
 	int offs;
 	int j,i;
 	int hd;
@@ -6190,7 +4093,6 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
 		nic = read_nic_dword(dev,TX_MANAGEPRIORITY_RING_ADDR);
 		nicbegin = priv->txmapringdma;
 		break;
-
 	case BK_PRIORITY:
 		tail = priv->txbkpringtail;
 		begin = priv->txbkpring;
@@ -6198,7 +4100,6 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
 		nic = read_nic_dword(dev,TX_BKPRIORITY_RING_ADDR);
 		nicbegin = priv->txbkpringdma;
 		break;
-
 	case BE_PRIORITY:
 		tail = priv->txbepringtail;
 		begin = priv->txbepring;
@@ -6206,7 +4107,6 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
 		nic = read_nic_dword(dev,TX_BEPRIORITY_RING_ADDR);
 		nicbegin = priv->txbepringdma;
 		break;
-
 	case VI_PRIORITY:
 		tail = priv->txvipringtail;
 		begin = priv->txvipring;
@@ -6214,7 +4114,6 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
 		nic = read_nic_dword(dev,TX_VIPRIORITY_RING_ADDR);
 		nicbegin = priv->txvipringdma;
 		break;
-
 	case VO_PRIORITY:
 		tail = priv->txvopringtail;
 		begin = priv->txvopring;
@@ -6222,7 +4121,6 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
 		nic = read_nic_dword(dev,TX_VOPRIORITY_RING_ADDR);
 		nicbegin = priv->txvopringdma;
 		break;
-
 	case HI_PRIORITY:
 		tail = priv->txhpringtail;
 		begin = priv->txhpring;
@@ -6235,21 +4133,11 @@ void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
 		spin_unlock_irqrestore(&priv->tx_lock,flag);
 		return ;
 	}
-/*	DMESG("%x %s %x %x",((int)nic & 0xfff)/8/4,
-	*(priv->txnpring + ((int)nic&0xfff)/4/8) & (1<<31) ? "filled" : "empty",
-	(priv->txnpringtail - priv->txnpring)/8,(priv->txnpringhead -
-priv->txnpring)/8);
-*/
-	//nicv = (u32*) ((nic - nicbegin) + (int)begin);
+
 	nicv = (u32*) ((nic - nicbegin) + (u8*)begin);
 	if((head <= tail && (nicv > tail || nicv < head)) ||
 		(head > tail && (nicv > tail && nicv < head))){
-
 			DMESGW("nic has lost pointer");
-#ifdef DEBUG_TX_DESC
-			//check_tx_ring(dev,NORM_PRIORITY);
-			check_tx_ring(dev,pri);
-#endif
 			spin_unlock_irqrestore(&priv->tx_lock,flag);
 			rtl8180_restart(dev);
 			return;
@@ -6259,69 +4147,39 @@ priv->txnpring)/8);
 	 * but not the currenly pointed by the nic (the next to be txed)
 	 * and the previous of the pointed (might be in process ??)
 	*/
-	//if (head == nic) return;
-	//DMESG("%x %x",head,nic);
 	offs = (nic - nicbegin);
-	//DMESG("%x %x %x",nic ,(u32)nicbegin, (int)nic -nicbegin);
-
 	offs = offs / 8 /4;
-
 	hd = (head - begin) /8;
 
 	if(offs >= hd)
 		j = offs - hd;
 	else
 		j = offs + (priv->txringcount -1 -hd);
-	//	j= priv->txringcount -1- (hd - offs);
 
 	j-=2;
 	if(j<0) j=0;
 
-
 	for(i=0;i<j;i++)
 	{
-//		printk("+++++++++++++check status desc\n");
 		if((*head) & (1<<31))
 			break;
 		if(((*head)&(0x10000000)) != 0){
-//			printk("++++++++++++++last desc,retry count is %d\n",((*head) & (0x000000ff)));
 			priv->CurrRetryCnt += (u16)((*head) & (0x000000ff));
-#if 1
-			if(!error)
-			{
+			if (!error)
 				priv->NumTxOkTotal++;
-//				printk("NumTxOkTotal is %d\n",priv->NumTxOkTotal++);
-			}
-#endif
-			//	printk("in function %s:curr_retry_count is %d\n",__func__,((*head) & (0x000000ff)));
 		}
-		if(!error){
+
+		if (!error)
 			priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff);
-		}
-//		printk("in function %s:curr_txokbyte_count is %d\n",__func__,(*(head+3)) & (0x00000fff));
+
 		*head = *head &~ (1<<31);
 
 		if((head - begin)/8 == priv->txringcount-1)
 			head=begin;
-
 		else
 			head+=8;
 	}
-#if 0
-	if(nicv == begin)
-		txdv = begin + (priv->txringcount -1)*8;
-	else
-		txdv = nicv - 8;
-
-	txed = !(txdv[0] &(1<<31));
 
-	if(txed){
-		if(!(txdv[0] & (1<<15))) error = 1;
-		//if(!(txdv[0] & (1<<30))) error = 1;
-		if(error)DMESG("%x",txdv[0]);
- 	}
-#endif
-	//DMESG("%x",txdv[0]);
 	/* the head has been moved to the last certainly TXed
 	 * (or at least processed by the nic) packet.
 	 * The driver take forcefully owning of all these packets
@@ -6334,63 +4192,41 @@ priv->txnpring)/8);
 	switch(pri) {
 	case MANAGE_PRIORITY:
 		priv->txmapringhead = head;
-			//printk("1==========================================> priority check!\n");
+
 		if(priv->ack_tx_to_ieee){
-				// try to implement power-save mode 2008.1.22
-		//	printk("2==========================================> priority check!\n");
-#if 1
 			if(rtl8180_is_tx_queue_empty(dev)){
-			//	printk("tx queue empty, after send null sleep packet, try to sleep !\n");
 				priv->ack_tx_to_ieee = 0;
 				ieee80211_ps_tx_ack(priv->ieee80211,!error);
 			}
-#endif
 		}
 		break;
-
 	case BK_PRIORITY:
 		priv->txbkpringhead = head;
 		break;
-
 	case BE_PRIORITY:
 		priv->txbepringhead = head;
 		break;
-
 	case VI_PRIORITY:
 		priv->txvipringhead = head;
 		break;
-
 	case VO_PRIORITY:
 		priv->txvopringhead = head;
 		break;
-
 	case HI_PRIORITY:
 		priv->txhpringhead = head;
 		break;
 	}
 
-	/*DMESG("%x %x %x", (priv->txnpringhead - priv->txnpring) /8 ,
-		(priv->txnpringtail - priv->txnpring) /8,
-		offs );
-	*/
-
 	spin_unlock_irqrestore(&priv->tx_lock,flag);
-
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8180_tx_irq_wq(struct work_struct *work)
 {
-	//struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
 	struct delayed_work *dwork = to_delayed_work(work);
 	struct ieee80211_device * ieee = (struct ieee80211_device*)
 	                                       container_of(dwork, struct ieee80211_device, watch_dog_wq);
 	struct net_device *dev = ieee->dev;
-#else
-void rtl8180_tx_irq_wq(struct net_device *dev)
-{
-	//struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
+
 	rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
 }
 irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
@@ -6405,19 +4241,12 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
 
 	spin_lock_irqsave(&priv->irq_th_lock,flags);
 
-#ifdef CONFIG_RTL8185B
 	//ISR: 4bytes
 	inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
 	write_nic_dword(dev,ISR,inta); // reset int situation
-#else
-	inta = read_nic_word(dev,INTA) & priv->irq_mask;
-	write_nic_word(dev,INTA,inta); // reset int situation
-#endif
 
 	priv->stats.shints++;
 
-	//DMESG("Enter interrupt, ISR value = 0x%08x", inta);
-
 	if(!inta){
 		spin_unlock_irqrestore(&priv->irq_th_lock,flags);
 		return IRQ_HANDLED;
@@ -6427,60 +4256,38 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
 	*/
 	}
 
-	if(inta == 0xffff){
-			/* HW disappared */
-			spin_unlock_irqrestore(&priv->irq_th_lock,flags);
-			return IRQ_HANDLED;
+	if (inta == 0xffff) {
+		/* HW disappared */
+		spin_unlock_irqrestore(&priv->irq_th_lock, flags);
+		return IRQ_HANDLED;
 	}
 
 	priv->stats.ints++;
-#ifdef DEBUG_IRQ
-	DMESG("NIC irq %x",inta);
-#endif
-	//priv->irqpending = inta;
-
 
 	if(!netif_running(dev)) {
 		spin_unlock_irqrestore(&priv->irq_th_lock,flags);
 		return IRQ_HANDLED;
 	}
 
-	if(inta & ISR_TimeOut){
+	if (inta & ISR_TimeOut)
 		write_nic_dword(dev, TimerInt, 0);
-		//DMESG("=================>waking up");
-//		rtl8180_hw_wakeup(dev);
-	}
 
-	if(inta & ISR_TBDOK){
+	if (inta & ISR_TBDOK)
 		priv->stats.txbeacon++;
-	}
 
-	if(inta & ISR_TBDER){
+	if (inta & ISR_TBDER)
 		priv->stats.txbeaconerr++;
-	}
 
-	if(inta  & IMR_TMGDOK ) {
-//		priv->NumTxOkTotal++;
+	if (inta & IMR_TMGDOK)
 		rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
-//			schedule_work(&priv->tx_irq_wq);
-
-	}
 
 	if(inta & ISR_THPDER){
-#ifdef DEBUG_TX
-		DMESG ("TX high priority ERR");
-#endif
 		priv->stats.txhperr++;
 		rtl8180_tx_isr(dev,HI_PRIORITY,1);
 		priv->ieee80211->stats.tx_errors++;
 	}
 
 	if(inta & ISR_THPDOK){ //High priority tx ok
-#ifdef DEBUG_TX
-		DMESG ("TX high priority OK");
-#endif
-//		priv->NumTxOkTotal++;
-		//priv->NumTxOkInPeriod++;  //YJ,del,080828
 		priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
 		priv->stats.txhpokint++;
 		rtl8180_tx_isr(dev,HI_PRIORITY,0);
@@ -6488,18 +4295,10 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
 
 	if(inta & ISR_RER) {
 		priv->stats.rxerr++;
-#ifdef DEBUG_RX
-		DMESGW("RX error int");
-#endif
 	}
-#ifdef CONFIG_RTL8185B
 	if(inta & ISR_TBKDER){ //corresponding to BK_PRIORITY
 		priv->stats.txbkperr++;
 		priv->ieee80211->stats.tx_errors++;
-#ifdef DEBUG_TX
-		DMESGW("TX bkp error int");
-#endif
-		//tasklet_schedule(&priv->irq_tx_tasklet);
 		rtl8180_tx_isr(dev,BK_PRIORITY,1);
 		rtl8180_try_wake_queue(dev, BE_PRIORITY);
 	}
@@ -6507,113 +4306,65 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
 	if(inta & ISR_TBEDER){ //corresponding to BE_PRIORITY
 		priv->stats.txbeperr++;
 		priv->ieee80211->stats.tx_errors++;
-#ifdef DEBUG_TX
-		DMESGW("TX bep error int");
-#endif
 		rtl8180_tx_isr(dev,BE_PRIORITY,1);
-		//tasklet_schedule(&priv->irq_tx_tasklet);
 		rtl8180_try_wake_queue(dev, BE_PRIORITY);
 	}
-#endif
 	if(inta & ISR_TNPDER){ //corresponding to VO_PRIORITY
 		priv->stats.txnperr++;
 		priv->ieee80211->stats.tx_errors++;
-#ifdef DEBUG_TX
-		DMESGW("TX np error int");
-#endif
-		//tasklet_schedule(&priv->irq_tx_tasklet);
 		rtl8180_tx_isr(dev,NORM_PRIORITY,1);
-#ifdef CONFIG_RTL8185B
 		rtl8180_try_wake_queue(dev, NORM_PRIORITY);
-#endif
 	}
 
 	if(inta & ISR_TLPDER){ //corresponding to VI_PRIORITY
 		priv->stats.txlperr++;
 		priv->ieee80211->stats.tx_errors++;
-#ifdef DEBUG_TX
-		DMESGW("TX lp error int");
-#endif
 		rtl8180_tx_isr(dev,LOW_PRIORITY,1);
-		//tasklet_schedule(&priv->irq_tx_tasklet);
 		rtl8180_try_wake_queue(dev, LOW_PRIORITY);
 	}
 
 	if(inta & ISR_ROK){
-#ifdef DEBUG_RX
-		DMESG("Frame arrived !");
-#endif
-		//priv->NumRxOkInPeriod++;  //YJ,del,080828
 		priv->stats.rxint++;
 		tasklet_schedule(&priv->irq_rx_tasklet);
 	}
 
 	if(inta & ISR_RQoSOK ){
-#ifdef DEBUG_RX
-		DMESG("QoS Frame arrived !");
-#endif
-		//priv->NumRxOkInPeriod++;  //YJ,del,080828
 		priv->stats.rxint++;
 		tasklet_schedule(&priv->irq_rx_tasklet);
 	}
 	if(inta & ISR_BcnInt) {
-		//DMESG("Preparing Beacons");
 		rtl8180_prepare_beacon(dev);
 	}
 
 	if(inta & ISR_RDU){
-//#ifdef DEBUG_RX
 		DMESGW("No RX descriptor available");
 		priv->stats.rxrdu++;
-//#endif
 		tasklet_schedule(&priv->irq_rx_tasklet);
-		/*queue_work(priv->workqueue ,&priv->restart_work);*/
-
 	}
+
 	if(inta & ISR_RXFOVW){
-#ifdef DEBUG_RX
-		DMESGW("RX fifo overflow");
-#endif
 		priv->stats.rxoverflow++;
 		tasklet_schedule(&priv->irq_rx_tasklet);
-		//queue_work(priv->workqueue ,&priv->restart_work);
 	}
 
-	if(inta & ISR_TXFOVW) priv->stats.txoverflow++;
+	if (inta & ISR_TXFOVW)
+		priv->stats.txoverflow++;
 
 	if(inta & ISR_TNPDOK){ //Normal priority tx ok
-#ifdef DEBUG_TX
-		DMESG ("TX normal priority OK");
-#endif
-//		priv->NumTxOkTotal++;
-		//priv->NumTxOkInPeriod++;  //YJ,del,080828
 		priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
-		//	priv->ieee80211->stats.tx_packets++;
 		priv->stats.txnpokint++;
 		rtl8180_tx_isr(dev,NORM_PRIORITY,0);
 	}
 
 	if(inta & ISR_TLPDOK){ //Low priority tx ok
-#ifdef DEBUG_TX
-		DMESG ("TX low priority OK");
-#endif
-//		priv->NumTxOkTotal++;
-		//priv->NumTxOkInPeriod++;  //YJ,del,080828
 		priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
-		//	priv->ieee80211->stats.tx_packets++;
 		priv->stats.txlpokint++;
 		rtl8180_tx_isr(dev,LOW_PRIORITY,0);
 		rtl8180_try_wake_queue(dev, LOW_PRIORITY);
 	}
 
-#ifdef CONFIG_RTL8185B
 	if(inta & ISR_TBKDOK){ //corresponding to BK_PRIORITY
 		priv->stats.txbkpokint++;
-#ifdef DEBUG_TX
-		DMESGW("TX bk priority ok");
-#endif
-//		priv->NumTxOkTotal++;
-		//priv->NumTxOkInPeriod++;  //YJ,del,080828
 		priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
 		rtl8180_tx_isr(dev,BK_PRIORITY,0);
 		rtl8180_try_wake_queue(dev, BE_PRIORITY);
@@ -6621,63 +4372,26 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
 
 	if(inta & ISR_TBEDOK){ //corresponding to BE_PRIORITY
 		priv->stats.txbeperr++;
-#ifdef DEBUG_TX
-		DMESGW("TX be priority ok");
-#endif
-//		priv->NumTxOkTotal++;
-		//priv->NumTxOkInPeriod++;  //YJ,del,080828
 		priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
 		rtl8180_tx_isr(dev,BE_PRIORITY,0);
 		rtl8180_try_wake_queue(dev, BE_PRIORITY);
 	}
-#endif
 	force_pci_posting(dev);
 	spin_unlock_irqrestore(&priv->irq_th_lock,flags);
 
 	return IRQ_HANDLED;
 }
 
-
 void rtl8180_irq_rx_tasklet(struct r8180_priv* priv)
 {
-//	unsigned long flags;
-
-/*	spin_lock_irqsave(&priv->irq_lock, flags);
-	priv->irq_mask &=~IMR_ROK;
-	priv->irq_mask &=~IMR_RDU;
-
-	rtl8180_irq_enable(priv->dev);
-	spin_unlock_irqrestore(&priv->irq_lock, flags);
-*/
 	rtl8180_rx(priv->dev);
-
-/*	spin_lock_irqsave(&priv->irq_lock, flags);
-	priv->irq_mask |= IMR_ROK;
-	priv->irq_mask |= IMR_RDU;
-	rtl8180_irq_enable(priv->dev);
-	spin_unlock_irqrestore(&priv->irq_lock, flags);
-*/
 }
 
-/****************************************************************************
-lizhaoming--------------------------- RF power on/power off -----------------
-*****************************************************************************/
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
 {
-	//struct delayed_work *dwork = to_delayed_work(work);
 	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, GPIOChangeRFWorkItem.work);
 	struct net_device *dev = ieee->dev;
 	struct r8180_priv *priv = ieee80211_priv(dev);
-#else
-void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee)
-{
-	struct net_device *dev = ieee->dev;
-	struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
-
-	//u16 tmp2byte;
 	u8 btPSR;
 	u8 btConfig0;
 	RT_RF_POWER_STATE	eRfPowerStateToSet;
@@ -6687,7 +4401,6 @@ void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee)
         static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
         static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
 	static int readf_count = 0;
-	//printk("============>%s in \n", __func__);
 
 #ifdef ENABLE_LPS
 	if(readf_count % 10 == 0)
@@ -6695,14 +4408,6 @@ void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee)
 
 	readf_count = (readf_count+1)%0xffff;
 #endif
-#if 0
-	if(priv->up == 0)//driver stopped
-		{
-			printk("\nDo nothing...");
-			goto out;
-		}
-	else
-#endif
 		{
 			// We should turn off LED before polling FF51[4].
 
@@ -6750,54 +4455,13 @@ void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee)
 
                                 call_usermodehelper(RadioPowerPath,argv,envp,1);
 			}
-
 		}
-
 }
 
 static u8 read_acadapter_file(char *filename)
 {
-//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
-#if 0
-	int fd;
-	char buf[1];
-	char ret[50];
-	int i = 0;
-	int n = 0;
-	mm_segment_t old_fs = get_fs();
-	set_fs(KERNEL_DS);
-
-	fd = sys_open(filename, O_RDONLY, 0);
-	if (fd >= 0) {
-		while (sys_read(fd, buf, 1) == 1)
-		{
-			i++;
-			if(i>10)
-			{
-				if(buf[0]!=' ')
-				{
-					ret[n]=buf[0];
-					n++;
-				}
-			}
-		}
-		sys_close(fd);
-	}
-	ret[n]='\0';
-//	printk("%s \n", ret);
-	set_fs(old_fs);
-
-	if(strncmp(ret, "off-line",8) == 0)
-	{
-		return 1;
-	}
-#endif
 	return 0;
 }
 
-/***************************************************************************
-     ------------------- module init / exit stubs ----------------
-****************************************************************************/
 module_init(rtl8180_pci_module_init);
 module_exit(rtl8180_pci_module_exit);
-
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
index e772f0f..b6eeeec 100644
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -126,7 +126,6 @@ DoTxHighPower(
 //		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);
@@ -135,11 +134,6 @@ void rtl8180_tx_pw_wq (struct work_struct *work)
 	struct delayed_work *dwork = to_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");
 
@@ -308,7 +302,6 @@ DynamicInitGain(
 	}
 }
 
-#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);
@@ -317,11 +310,6 @@ void rtl8180_hw_dig_wq (struct work_struct *work)
 	struct delayed_work *dwork = to_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.
@@ -529,7 +517,6 @@ MgntIsCckRate(
 
         return bReturn;
 }
-#ifdef CONFIG_RTL818X_S
 //
 //	Description:
 //		Tx Power tracking mechanism routine on 87SE.
@@ -1246,18 +1233,11 @@ SetInitialGain:
 	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 = to_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);
@@ -1277,10 +1257,8 @@ void timer_rate_adaptive(unsigned long data)
 			(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);
@@ -1337,22 +1315,12 @@ SetAntenna8185(
 		{
 		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;
@@ -1368,21 +1336,11 @@ SetAntenna8185(
 		{
 		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;
@@ -1422,14 +1380,6 @@ SwitchAntenna(
 
 	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");
@@ -1437,14 +1387,6 @@ SwitchAntenna(
 	}
 	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");
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
index b2736c8..84f4672 100644
--- a/drivers/staging/rtl8187se/r8180_dm.h
+++ b/drivers/staging/rtl8187se/r8180_dm.h
@@ -11,30 +11,12 @@ 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);
 
 
diff --git a/drivers/staging/rtl8187se/r8180_gct.c b/drivers/staging/rtl8187se/r8180_gct.c
deleted file mode 100644
index 86cb427..0000000
--- a/drivers/staging/rtl8187se/r8180_gct.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
-   This files contains GCT radio frontend programming routines.
-
-   This is part of rtl8180 OpenSource driver
-   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-   Released under the terms of GPL (General Public Licence)
-
-   Parts of this driver are based on the GPL part of the
-   official realtek driver
-
-   Parts of this driver are based on the rtl8180 driver skeleton
-   from Patric Schenke & Andres Salomon
-
-   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
-   Code from Rtw8180 NetBSD driver by David Young has been really useful to
-   understand some things and gets some ideas
-
-   Code from rtl8181 project has been useful to me to understand some things.
-
-   Some code from 'Deuce' work
-
-   We want to tanks the Authors of such projects and the Ndiswrapper
-   project Authors.
-*/
-
-
-#include "r8180.h"
-#include "r8180_hw.h"
-#include "r8180_gct.h"
-
-
-//#define DEBUG_GCT
-
-/* the following experiment are just experiments.
- * this means if you enable them you can have every kind
- * of result, included damage the RF chip, so don't
- * touch them if you don't know what you are doing.
- * In any case, if you do it, do at your own risk
- */
-
-//#define GCT_EXPERIMENT1  //improve RX sensivity
-
-//#define GCT_EXPERIMENT2
-
-//#define GCT_EXPERIMENT3  //iprove a bit RX signal quality ?
-
-//#define GCT_EXPERIMENT4 //maybe solve some brokeness with experiment1 ?
-
-//#define GCT_EXPERIMENT5
-
-//#define GCT_EXPERIMENT6  //not good
-
-
-u32 gct_chan[] = {
-	0x0,	//dummy channel 0
-	0x0, //1
-	0x1, //2
-	0x2, //3
-	0x3, //4
-	0x4, //5
-	0x5, //6
-	0x6, //7
-	0x7, //8
-	0x8, //9
-	0x9, //10
-	0xa, //11
-	0xb, //12
-	0xc, //13
-	0xd, //14
-};
-
-int gct_encode[16] = {
-	0, 8, 4, 0xC,
-	2, 0xA, 6, 0xE,
-	1, 9, 5, 0xD,
-	3, 0xB, 7, 0xF
-};
-
-void gct_rf_stabilize(struct net_device *dev)
-{
-	force_pci_posting(dev);
-	mdelay(3); //for now use a great value.. we may optimize in future
-}
-
-
-void write_gct(struct net_device *dev, u8 adr, u32 data)
-{
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 phy_config;
-
-	phy_config =  gct_encode[(data & 0xf00) >> 8];
-	phy_config |= gct_encode[(data & 0xf0) >> 4 ] << 4;
-	phy_config |= gct_encode[(data & 0xf)       ] << 8;
-	phy_config |= gct_encode[(adr >> 1) & 0xf   ] << 12;
-	phy_config |=            (adr & 1 )           << 16;
-	phy_config |= gct_encode[(data & 0xf000)>>12] << 24;
-
-	phy_config |= 0x90000000; // MAC will bang bits to the chip
-
-
-	write_nic_dword(dev,PHY_CONFIG,phy_config);
-#ifdef DEBUG_GCT
-	DMESG("Writing GCT: %x (adr %x)",phy_config,adr);
-#endif
-	gct_rf_stabilize(dev);
-}
-
-
-
-void gct_write_phy_antenna(struct net_device *dev,short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 ant;
-
-	ant = GCT_ANTENNA;
-	if(priv->antb) /*default antenna is antenna B */
-		ant |= BB_ANTENNA_B;
-	if(ch == 14)
-		ant |= BB_ANTATTEN_CHAN14;
-	write_phy(dev,0x10,ant);
-	//DMESG("BB antenna %x ",ant);
-}
-
-
-void gct_rf_set_chan(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 txpw = 0xff & priv->chtxpwr[ch];
-	u32 chan = gct_chan[ch];
-
-	//write_phy(dev,3,txpw);
-#ifdef DEBUG_GCT
-	DMESG("Gct set channel");
-#endif
-	/* set TX power */
-	write_gct(dev,0x15,0);
- 	write_gct(dev,6, txpw);
-	write_gct(dev,0x15, 0x10);
-	write_gct(dev,0x15,0);
-
-	/*set frequency*/
-	write_gct(dev,7, 0);
-      	write_gct(dev,0xB, chan);
-      	write_gct(dev,7, 0x1000);
-
-#ifdef DEBUG_GCT
-	DMESG("Gct set channel > write phy antenna");
-#endif
-
-
-	gct_write_phy_antenna(dev,ch);
-
-}
-
-
-void gct_rf_close(struct net_device *dev)
-{
-	u32 anaparam;
-
-	anaparam = read_nic_dword(dev,ANAPARAM);
-	anaparam &= 0x000fffff;
-	anaparam |= 0x3f900000;
-	rtl8180_set_anaparam(dev, anaparam);
-
-	write_gct(dev, 0x7, 0);
-	write_gct(dev, 0x1f, 0x45);
-	write_gct(dev, 0x1f, 0x5);
-	write_gct(dev, 0x0, 0x8e4);
-}
-
-
-void gct_rf_init(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	//u32 anaparam;
-
-
-	write_nic_byte(dev,PHY_DELAY,0x6);	//this is general
-	write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
-
-	//DMESG("%x", read_nic_dword(dev,ANAPARAM));
-	/* we should set anaparm here*/
-	//rtl8180_set_anaparam(dev,anaparam);
-
-	write_gct(dev,0x1f,0);
-	write_gct(dev,0x1f,0);
-	write_gct(dev,0x1f,0x40);
-	write_gct(dev,0x1f,0x60);
-	write_gct(dev,0x1f,0x61);
-	write_gct(dev,0x1f,0x61);
-	write_gct(dev,0x0,0xae4);
-	write_gct(dev,0x1f,0x1);
-	write_gct(dev,0x1f,0x41);
-	write_gct(dev,0x1f,0x61);
-	write_gct(dev,0x1,0x1a23);
-	write_gct(dev,0x2,0x4971);
-	write_gct(dev,0x3,0x41de);
-	write_gct(dev,0x4,0x2d80);
-#ifdef GCT_EXPERIMENT1
-	//write_gct(dev,0x5,0x6810);  // from zydas driver. sens+ but quite slow
-	//write_gct(dev,0x5,0x681f);  //good+ (somewhat stable, better sens, performance decent)
-	write_gct(dev,0x5,0x685f);  //good performances, not sure sens is really so beeter
-	//write_gct(dev,0x5,0x687f);  //good performances, maybe sens is not improved
-	//write_gct(dev,0x5,0x689f);  //like above
-	//write_gct(dev,0x5,0x685e);  //bad
-	//write_gct(dev,0x5,0x68ff);  //good+ (somewhat stable, better sens(?), performance decent)
-	//write_gct(dev,0x5,0x68f0);  //bad
-	//write_gct(dev,0x5,0x6cff);  //sens+ but not so good
-	//write_gct(dev,0x5,0x6dff);  //sens+,apparentely very good but broken
-	//write_gct(dev,0x5,0x65ff);  //sens+,good
-	//write_gct(dev,0x5,0x78ff);  //sens + but almost broken
-	//write_gct(dev,0x5,0x7810);  //- //snes + but broken
-	//write_gct(dev,0x5,0x781f);  //-- //sens +
-	//write_gct(dev,0x5,0x78f0);  //low sens
-#else
-	write_gct(dev,0x5,0x61ff);   //best performance but weak sensitivity
-#endif
-#ifdef GCT_EXPERIMENT2
-	write_gct(dev,0x6,0xe);
-#else
-	write_gct(dev,0x6,0x0);
-#endif
-	write_gct(dev,0x7,0x0);
-	write_gct(dev,0x8,0x7533);
-	write_gct(dev,0x9,0xc401);
-	write_gct(dev,0xa,0x0);
-	write_gct(dev,0xc,0x1c7);
-	write_gct(dev,0xd,0x29d3);
-	write_gct(dev,0xe,0x2e8);
-	write_gct(dev,0x10,0x192);
-#ifdef GCT_EXPERIMENT3
-	write_gct(dev,0x11,0x246);
-#else
-	write_gct(dev,0x11,0x248);
-#endif
-	write_gct(dev,0x12,0x0);
-	write_gct(dev,0x13,0x20c4);
-#ifdef GCT_EXPERIMENT4
-	write_gct(dev,0x14,0xf488);
-#else
-	write_gct(dev,0x14,0xf4fc);
-#endif
-#ifdef GCT_EXPERIMENT5
-	write_gct(dev,0x15,0xb152);
-#else
-	write_gct(dev,0x15,0x0);
-#endif
-#ifdef GCT_EXPERIMENT6
-	write_gct(dev,0x1e,0x1);
-#endif
-	write_gct(dev,0x16,0x1500);
-
-	write_gct(dev,0x7,0x1000);
-	/*write_gct(dev,0x15,0x0);
-	write_gct(dev,0x6,0x15);
-	write_gct(dev,0x15,0x8);
-	write_gct(dev,0x15,0x0);
-*/
-	write_phy(dev,0,0xa8);
-
-/*	write_gct(dev,0x15,0x0);
-	write_gct(dev,0x6,0x12);
-	write_gct(dev,0x15,0x8);
-	write_gct(dev,0x15,0x0);
-*/
-	write_phy(dev,3,0x0);
-	write_phy(dev,4,0xc0); /* lna det*/
-	write_phy(dev,5,0x90);
-	write_phy(dev,6,0x1e);
-	write_phy(dev,7,0x64);
-
-#ifdef DEBUG_GCT
-	DMESG("Gct init> write phy antenna");
-#endif
-
-	gct_write_phy_antenna(dev,priv->chan);
-
-	write_phy(dev,0x11,0x88);
-	if(!priv->diversity)
-		write_phy(dev,0x12,0xc0);
-	else
-		write_phy(dev,0x12,0x40);
-
-	write_phy(dev,0x13,0x90 | priv->cs_treshold );
-
-	write_phy(dev,0x19,0x0);
-	write_phy(dev,0x1a,0xa0);
-	write_phy(dev,0x1b,0x44);
-
-#ifdef DEBUG_GCT
-	DMESG("Gct init > set channel2");
-#endif
-
-	gct_rf_set_chan(dev,priv->chan);
-}
diff --git a/drivers/staging/rtl8187se/r8180_gct.h b/drivers/staging/rtl8187se/r8180_gct.h
deleted file mode 100644
index fe965ca..0000000
--- a/drivers/staging/rtl8187se/r8180_gct.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-	This is part of rtl8180 OpenSource driver - v 0.20
-	Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the official realtek driver
-	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
-	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
-	We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-#define GCT_ANTENNA 0xA3
-
-
-// we use the untouched eeprom value- cross your finger ;-)
-#define GCT_ANAPARAM_PWR1_ON ??
-#define GCT_ANAPARAM_PWR0_ON ??
-
-
-
-void gct_rf_init(struct net_device *dev);
-void gct_rf_set_chan(struct net_device *dev,short ch);
-
-void gct_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_hw.h b/drivers/staging/rtl8187se/r8180_hw.h
index bf38934..db29691 100644
--- a/drivers/staging/rtl8187se/r8180_hw.h
+++ b/drivers/staging/rtl8187se/r8180_hw.h
@@ -20,8 +20,6 @@
 #ifndef R8180_HW
 #define R8180_HW
 
-#define CONFIG_RTL8185B  //support for rtl8185B, xiong-2006-11-15
-#define CONFIG_RTL818X_S
 
 #define BIT0	0x00000001
 #define BIT1	0x00000002
@@ -31,18 +29,10 @@
 #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
@@ -59,29 +49,14 @@
 #define MAX_SLEEP_TIME (10000)
 #define MIN_SLEEP_TIME (50)
 
-#define BB_ANTATTEN_CHAN14	0x0c
-#define BB_ANTENNA_B 0x40
-
-#define BB_HOST_BANG (1<<30)
 #define BB_HOST_BANG_EN (1<<2)
 #define BB_HOST_BANG_CLK (1<<1)
-#define BB_HOST_BANG_DATA	 1
-
-#define ANAPARAM_TXDACOFF_SHIFT 27
-#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28))
-#define ANAPARAM_PWR0_SHIFT 28
-#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20))
-#define ANAPARAM_PWR1_SHIFT 20
 
 #define MAC0 0
-#define MAC1 1
-#define MAC2 2
-#define MAC3 3
 #define MAC4 4
-#define MAC5 5
+
 #define CMD 0x37
 #define CMD_RST_SHIFT 4
-#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
 #define CMD_RX_ENABLE_SHIFT 3
 #define CMD_TX_ENABLE_SHIFT 2
 
@@ -98,13 +73,9 @@
 #define EPROM_W_SHIFT 1
 #define EPROM_R_SHIFT 0
 #define CONFIG2_DMA_POLLING_MODE_SHIFT 3
-#define INTA 0x3e
+
 #define INTA_TXOVERFLOW (1<<15)
 #define INTA_TIMEOUT (1<<14)
-#define INTA_BEACONTIMEOUT (1<<13)
-#define INTA_ATIM (1<<12)
-#define INTA_BEACONDESCERR (1<<11)
-#define INTA_BEACONDESCOK (1<<10)
 #define INTA_HIPRIORITYDESCERR (1<<9)
 #define INTA_HIPRIORITYDESCOK (1<<8)
 #define INTA_NORMPRIORITYDESCERR (1<<7)
@@ -113,9 +84,9 @@
 #define INTA_RXDESCERR (1<<4)
 #define INTA_LOWPRIORITYDESCERR (1<<3)
 #define INTA_LOWPRIORITYDESCOK (1<<2)
-#define INTA_RXCRCERR (1<<1)
 #define INTA_RXOK (1)
 #define INTA_MASK 0x3c
+
 #define RXRING_ADDR 0xe4 // page 0
 #define PGSELECT 0x5e
 #define PGSELECT_PG_SHIFT 0
@@ -133,20 +104,15 @@
 #define ACCEPT_MCAST_FRAME_SHIFT 2
 #define ACCEPT_ALLMAC_FRAME_SHIFT 0
 #define ACCEPT_NICMAC_FRAME_SHIFT 1
+
 #define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
 #define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_128 3
-#define RX_FIFO_THRESHOLD_256 4
-#define RX_FIFO_THRESHOLD_512 5
-#define RX_FIFO_THRESHOLD_1024 6
 #define RX_FIFO_THRESHOLD_NONE 7
 #define RX_AUTORESETPHY_SHIFT 28
-#define EPROM_TYPE_SHIFT 6
+
 #define TX_CONF 0x40
 #define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
 #define TX_LOOPBACK_SHIFT 17
-#define TX_LOOPBACK_MAC 1
-#define TX_LOOPBACK_BASEBAND 2
 #define TX_LOOPBACK_NONE 0
 #define TX_LOOPBACK_CONTINUE 3
 #define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
@@ -160,21 +126,12 @@
 #define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
 #define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
 #define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
-#define TX_DMA_STOP_BEACON_SHIFT 3
-#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
-#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
-#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
 #define TX_MANAGEPRIORITY_RING_ADDR 0x0C
 #define TX_BKPRIORITY_RING_ADDR 0x10
 #define TX_BEPRIORITY_RING_ADDR 0x14
 #define TX_VIPRIORITY_RING_ADDR 0x20
 #define TX_VOPRIORITY_RING_ADDR 0x24
 #define TX_HIGHPRIORITY_RING_ADDR 0x28
-//AC_VI and Low priority share the sane queue
-#define TX_LOWPRIORITY_RING_ADDR TX_VIPRIORITY_RING_ADDR
-//AC_VO and Norm priority share the same queue
-#define TX_NORMPRIORITY_RING_ADDR TX_VOPRIORITY_RING_ADDR
-
 #define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
 #define MAX_RX_DMA_2048 7
 #define MAX_RX_DMA_1024	6
@@ -191,11 +148,7 @@
 #define ATIM 0x72
 #define EPROM_CS_SHIFT 3
 #define EPROM_CK_SHIFT 2
-#define PHY_DELAY 0x78
-#define PHY_CONFIG 0x80
 #define PHY_ADR 0x7c
-#define PHY_READ 0x7e
-#define CARRIER_SENSE_COUNTER 0x79 //byte
 #define SECURITY 0x5f //1209 this is sth wrong
 #define SECURITY_WEP_TX_ENABLE_SHIFT 1
 #define SECURITY_WEP_RX_ENABLE_SHIFT 0
@@ -216,91 +169,38 @@
  * RealTek names are used.
  */
 
-#define IDR0 0x0000
-#define IDR1 0x0001
-#define IDR2 0x0002
-#define IDR3 0x0003
-#define IDR4 0x0004
-#define IDR5 0x0005
-
-/* 0x0006 - 0x0007 - reserved */
-
-#define MAR0 0x0008
-#define MAR1 0x0009
-#define MAR2 0x000A
-#define MAR3 0x000B
-#define MAR4 0x000C
-#define MAR5 0x000D
-#define MAR6 0x000E
-#define MAR7 0x000F
-
-/* 0x0010 - 0x0017 - reserved */
-
 #define TSFTR 0x0018
-#define TSFTR_END 0x001F
 
 #define TLPDA 0x0020
-#define TLPDA_END 0x0023
-#define TNPDA 0x0024
-#define TNPDA_END 0x0027
-#define THPDA 0x0028
-#define THPDA_END 0x002B
 
 #define BSSID 0x002E
-#define BSSID_END 0x0033
 
 #define CR 0x0037
 
-#ifdef CONFIG_RTL8185B
 #define RF_SW_CONFIG	        0x8			// store data which is transmitted to RF for driver
 #define RF_SW_CFG_SI		BIT1
-#define PIFS			0x2C			// PCF InterFrame Spacing Timer Setting.
 #define EIFS			0x2D			// Extended InterFrame Space Timer, in unit of 4 us.
 
 #define BRSR			0x34			// Basic rate set
 
 #define IMR 0x006C
 #define ISR 0x003C
-#else
-#define BRSR 0x002C
-#define BRSR_END 0x002D
-
-/* 0x0034 - 0x0034 - reserved */
-#define EIFS 0x0035
-
-#define IMR 0x003C
-#define IMR_END 0x003D
-#define ISR 0x003E
-#define ISR_END 0x003F
-#endif
 
 #define TCR 0x0040
-#define TCR_END 0x0043
 
 #define RCR 0x0044
-#define RCR_END 0x0047
 
 #define TimerInt 0x0048
-#define TimerInt_END 0x004B
-
-#define TBDA 0x004C
-#define TBDA_END 0x004F
 
 #define CR9346 0x0050
 
 #define CONFIG0 0x0051
-#define CONFIG1 0x0052
 #define CONFIG2 0x0053
 
-#define ANA_PARM 0x0054
-#define ANA_PARM_END 0x0x0057
-
 #define MSR 0x0058
 
 #define CONFIG3 0x0059
 #define CONFIG4 0x005A
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
 	// SD3 szuyitasi: Mac0x57= CC -> B0 Mac0x60= D1 -> C6
 	// Mac0x60 = 0x000004C6 power save parameters
 	#define ANAPARM_ASIC_ON    0xB0054D00
@@ -308,49 +208,20 @@
 
 	#define ANAPARM_ON ANAPARM_ASIC_ON
 	#define ANAPARM2_ON ANAPARM2_ASIC_ON
-#else
-	// SD3 CMLin:
-	#define ANAPARM_ASIC_ON    0x45090658
-	#define ANAPARM2_ASIC_ON  0x727f3f52
-
-	#define ANAPARM_ON ANAPARM_ASIC_ON
-	#define ANAPARM2_ON ANAPARM2_ASIC_ON
-#endif
-#endif
 
 #define TESTR 0x005B
 
-/* 0x005C - 0x005D - reserved */
-
 #define PSR 0x005E
 
-/* 0x0060 - 0x006F - reserved */
-
 #define BcnItv 0x0070
-#define BcnItv_END 0x0071
 
 #define AtimWnd 0x0072
-#define AtimWnd_END 0x0073
 
 #define BintrItv 0x0074
-#define BintrItv_END 0x0075
-
-#define AtimtrItv 0x0076
-#define AtimtrItv_END 0x0077
-
-#define PhyDelay 0x0078
-
-#define CRCount 0x0079
-
-/* 0x007A - 0x007B - reserved */
 
 #define PhyAddr 0x007C
-#define PhyDataW 0x007D
 #define PhyDataR 0x007E
 
-#define PhyCFG 0x0080
-#define PhyCFG_END 0x0083
-
 /* following are for rtl8185 */
 #define RFPinsOutput 0x80
 #define RFPinsEnable 0x82
@@ -382,108 +253,12 @@
 #define MAX_RESP_RATE_SHIFT 4
 #define MIN_RESP_RATE_SHIFT 0
 #define RATE_FALLBACK 0xbe
-/*
- *  0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
- *  is set to 1
- */
-
-#define Wakeup0 0x0084
-#define Wakeup0_END 0x008B
-
-#define Wakeup1 0x008C
-#define Wakeup1_END 0x0093
-
-#define Wakeup2LD 0x0094
-#define Wakeup2LD_END 0x009B
-#define Wakeup2HD 0x009C
-#define Wakeup2HD_END 0x00A3
-
-#define Wakeup3LD 0x00A4
-#define Wakeup3LD_END 0x00AB
-#define Wakeup3HD 0x00AC
-#define Wakeup3HD_END 0x00B3
-
-#define Wakeup4LD 0x00B4
-#define Wakeup4LD_END 0x00BB
-#define Wakeup4HD 0x00BC
-#define Wakeup4HD_END 0x00C3
-
-#define CRC0 0x00C4
-#define CRC0_END 0x00C5
-#define CRC1 0x00C6
-#define CRC1_END 0x00C7
-#define CRC2 0x00C8
-#define CRC2_END 0x00C9
-#define CRC3 0x00CA
-#define CRC3_END 0x00CB
-#define CRC4 0x00CC
-#define CRC4_END 0x00CD
-
-/* 0x00CE - 0x00D3 - reserved */
-
-
-
-/*
- *  0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
- *  is set to 0
- */
-
-/* 0x0084 - 0x008F - reserved */
-
-#define DK0 0x0090
-#define DK0_END 0x009F
-#define DK1 0x00A0
-#define DK1_END 0x00AF
-#define DK2 0x00B0
-#define DK2_END 0x00BF
-#define DK3 0x00C0
-#define DK3_END 0x00CF
-
-/* 0x00D0 - 0x00D3 - reserved */
-
-
-
-
-
-/* 0x00D4 - 0x00D7 - reserved */
 
 #define CONFIG5 0x00D8
 
-#define TPPoll 0x00D9
-
-/* 0x00DA - 0x00DB - reserved */
-
-#ifdef CONFIG_RTL818X_S
 #define PHYPR			0xDA			//0xDA - 0x0B PHY Parameter Register.
-#endif
-
-#define CWR 0x00DC
-#define CWR_END 0x00DD
-
-#define RetryCTR 0x00DE
-
-/* 0x00DF - 0x00E3 - reserved */
-
-#define RDSAR 0x00E4
-#define RDSAR_END 0x00E7
 
-/* 0x00E8 - 0x00EF - reserved */
-#ifdef CONFIG_RTL818X_S
-#define LED_CONTROL		0xED
-#endif
-
-#define FER 0x00F0
-#define FER_END 0x00F3
-
-#ifdef CONFIG_RTL8185B
 #define FEMR			0x1D4	// Function Event Mask register
-#else
-#define FEMR 0x00F4
-#define FEMR_END 0x00F7
-#endif
-
-#define FPSR 0x00F8
-#define FPSR_END 0x00FB
 
 #define FFER 0x00FC
 #define FFER_END 0x00FF
@@ -510,7 +285,6 @@
 #define CR_TE       ((1<< 2))
 #define CR_MulRW    ((1<< 0))
 
-#ifdef CONFIG_RTL8185B
 #define IMR_Dot11hInt	((1<< 25))			// 802.11h Measurement Interrupt
 #define IMR_BcnDmaInt	((1<< 24))			// Beacon DMA Interrupt // What differenct between BcnDmaInt and BcnInt???
 #define IMR_WakeInt		((1<< 23))			// Wake Up Interrupt
@@ -573,49 +347,12 @@
 #define ISR_TimeOut ISR_TimeOut1
 #define ISR_RXFOVW ISR_FOVW
 
-#else
-#define IMR_TXFOVW  ((1<<15))
-#define IMR_TimeOut ((1<<14))
-#define IMR_BcnInt  ((1<<13))
-#define IMR_ATIMInt ((1<<12))
-#define IMR_TBDER   ((1<<11))
-#define IMR_TBDOK   ((1<<10))
-#define IMR_THPDER  ((1<< 9))
-#define IMR_THPDOK  ((1<< 8))
-#define IMR_TNPDER  ((1<< 7))
-#define IMR_TNPDOK  ((1<< 6))
-#define IMR_RXFOVW  ((1<< 5))
-#define IMR_RDU     ((1<< 4))
-#define IMR_TLPDER  ((1<< 3))
-#define IMR_TLPDOK  ((1<< 2))
-#define IMR_RER     ((1<< 1))
-#define IMR_ROK     ((1<< 0))
-
-#define ISR_TXFOVW  ((1<<15))
-#define ISR_TimeOut ((1<<14))
-#define ISR_BcnInt  ((1<<13))
-#define ISR_ATIMInt ((1<<12))
-#define ISR_TBDER   ((1<<11))
-#define ISR_TBDOK   ((1<<10))
-#define ISR_THPDER  ((1<< 9))
-#define ISR_THPDOK  ((1<< 8))
-#define ISR_TNPDER  ((1<< 7))
-#define ISR_TNPDOK  ((1<< 6))
-#define ISR_RXFOVW  ((1<< 5))
-#define ISR_RDU     ((1<< 4))
-#define ISR_TLPDER  ((1<< 3))
-#define ISR_TLPDOK  ((1<< 2))
-#define ISR_RER     ((1<< 1))
-#define ISR_ROK     ((1<< 0))
-#endif
 
 #define HW_VERID_R8180_F 3
 #define HW_VERID_R8180_ABCD 2
 #define HW_VERID_R8185_ABC 4
 #define HW_VERID_R8185_D 5
-#ifdef CONFIG_RTL8185B
 #define HW_VERID_R8185B_B 6
-#endif
 
 #define TCR_CWMIN   ((1<<31))
 #define TCR_SWSEQ   ((1<<30))
@@ -671,53 +408,10 @@
 #define CR9346_EED1    ((1<<1))
 #define CR9346_EED0    ((1<<0))
 
-#define CONFIG0_WEP104     ((1<<6))
-#define CONFIG0_LEDGPO_En  ((1<<4))
-#define CONFIG0_Aux_Status ((1<<3))
-#define CONFIG0_GL         ((1<<1)|(1<<0))
-#define CONFIG0_GL1        ((1<<1))
-#define CONFIG0_GL0        ((1<<0))
-
-#define CONFIG1_LEDS       ((1<<7)|(1<<6))
-#define CONFIG1_LEDS1      ((1<<7))
-#define CONFIG1_LEDS0      ((1<<6))
-#define CONFIG1_LWACT      ((1<<4))
-#define CONFIG1_MEMMAP     ((1<<3))
-#define CONFIG1_IOMAP      ((1<<2))
-#define CONFIG1_VPD        ((1<<1))
-#define CONFIG1_PMEn       ((1<<0))
-
-#define CONFIG2_LCK        ((1<<7))
-#define CONFIG2_ANT        ((1<<6))
-#define CONFIG2_DPS        ((1<<3))
-#define CONFIG2_PAPE_sign  ((1<<2))
-#define CONFIG2_PAPE_time  ((1<<1)|(1<<0))
-#define CONFIG2_PAPE_time1 ((1<<1))
-#define CONFIG2_PAPE_time0 ((1<<0))
-
-#define CONFIG3_GNTSel     ((1<<7))
 #define CONFIG3_PARM_En    ((1<<6))
-#define CONFIG3_Magic      ((1<<5))
-#define CONFIG3_CardB_En   ((1<<3))
-#define CONFIG3_CLKRUN_En  ((1<<2))
 #define CONFIG3_FuncRegEn  ((1<<1))
-#define CONFIG3_FBtbEn     ((1<<0))
 
-#define CONFIG4_VCOPDN     ((1<<7))
-#define CONFIG4_PWROFF     ((1<<6))
 #define CONFIG4_PWRMGT     ((1<<5))
-#define CONFIG4_LWPME      ((1<<4))
-#define CONFIG4_LWPTN      ((1<<2))
-#define CONFIG4_RFTYPE     ((1<<1)|(1<<0))
-#define CONFIG4_RFTYPE1    ((1<<1))
-#define CONFIG4_RFTYPE0    ((1<<0))
-
-#define CONFIG5_TX_FIFO_OK ((1<<7))
-#define CONFIG5_RX_FIFO_OK ((1<<6))
-#define CONFIG5_CALON      ((1<<5))
-#define CONFIG5_EACPI      ((1<<2))
-#define CONFIG5_LANWake    ((1<<1))
-#define CONFIG5_PME_STS    ((1<<0))
 
 #define MSR_LINK_MASK      ((1<<2)|(1<<3))
 #define MSR_LINK_MANAGED   2
@@ -726,54 +420,19 @@
 #define MSR_LINK_ADHOC     1
 #define MSR_LINK_MASTER    3
 
-#define PSR_GPO            ((1<<7))
-#define PSR_GPI            ((1<<6))
-#define PSR_LEDGPO1        ((1<<5))
-#define PSR_LEDGPO0        ((1<<4))
-#define PSR_UWF            ((1<<1))
-#define PSR_PSEn           ((1<<0))
-
-#define SCR_KM             ((1<<5)|(1<<4))
-#define SCR_KM1            ((1<<5))
-#define SCR_KM0            ((1<<4))
-#define SCR_TXSECON        ((1<<1))
-#define SCR_RXSECON        ((1<<0))
-
 #define BcnItv_BcnItv      (0x01FF)
 
 #define AtimWnd_AtimWnd    (0x01FF)
 
 #define BintrItv_BintrItv  (0x01FF)
 
-#define AtimtrItv_AtimtrItv (0x01FF)
-
-#define PhyDelay_PhyDelay  ((1<<2)|(1<<1)|(1<<0))
-
-#define TPPoll_BQ    ((1<<7))
-#define TPPoll_HPQ   ((1<<6))
-#define TPPoll_NPQ   ((1<<5))
-#define TPPoll_LPQ   ((1<<4))
-#define TPPoll_SBQ   ((1<<3))
-#define TPPoll_SHPQ  ((1<<2))
-#define TPPoll_SNPQ  ((1<<1))
-#define TPPoll_SLPQ  ((1<<0))
-
-#define CWR_CW       (0x01FF)
-
-#define FER_INTR     ((1<<15))
-#define FER_GWAKE    ((1<< 4))
-
 #define FEMR_INTR    ((1<<15))
 #define FEMR_WKUP    ((1<<14))
 #define FEMR_GWAKE   ((1<< 4))
 
-#define FPSR_INTR    ((1<<15))
-#define FPSR_GWAKE   ((1<< 4))
-
 #define FFER_INTR    ((1<<15))
 #define FFER_GWAKE   ((1<< 4))
 
-#ifdef CONFIG_RTL8185B
 // Three wire mode.
 #define SW_THREE_WIRE			0
 #define HW_THREE_WIRE			2
@@ -790,17 +449,6 @@
 #define RCR_MXDMA_OFFSET				8
 #define RCR_FIFO_OFFSET					13
 
-#define TMGDS			0x0C			// Tx Management Descriptor Address
-#define TBKDS			0x10			// Tx AC_BK Descriptor Address
-#define TBEDS			0x14			// Tx AC_BE Descriptor Address
-#define TLPDS			0x20			// Tx AC_VI Descriptor Address
-#define TNPDS			0x24			// Tx AC_VO Descriptor Address
-#define THPDS			0x28			// Tx Hign Priority Descriptor Address
-
-#define TBDS			0x4c			// Beacon descriptor queue start address
-
-#define RDSA			0xE4			// Receive descriptor queue start address
-
 #define AckTimeOutReg	0x79		// ACK timeout register, in unit of 4 us.
 
 #define RFTiming			0x8C
@@ -814,8 +462,6 @@
 
 #define ACM_CONTROL             0x00BF      // ACM Control Registe
 
-#define RTL8185B_VER_REG    0xE1
-
 #define	IntMig			0xE2			// Interrupt Migration (0xE2 ~ 0xE3)
 
 #define TID_AC_MAP		0xE8			// TID to AC Mapping Register
@@ -827,11 +473,7 @@
 #define AC_BE_PARAM		0xF8			// AC_BE Parameters Record
 #define AC_BK_PARAM		0xFC			// AC_BK Parameters Record
 
-#ifdef CONFIG_RTL818X_S
-#define BcnTimingAdjust	0x16A			// Beacon Timing Adjust Register.
 #define GPIOCtrl			0x16B			// GPIO Control Register.
-#define PSByGC			0x180			// 0x180 - 0x183 Power Saving by Gated Clock.
-#endif
 #define ARFR			0x1E0	// Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
 
 #define RFSW_CTRL			0x272	// 0x272-0x273.
@@ -840,33 +482,14 @@
 #define SW_3W_CMD0			0x27C	// Software 3-wire Control/Status Register.
 #define SW_3W_CMD1			0x27D	// Software 3-wire Control/Status Register.
 
-#ifdef CONFIG_RTL818X_S
 #define PI_DATA_READ		0X360	// 0x360 - 0x361  Parallel Interface Data Register.
 #define SI_DATA_READ		0x362	// 0x362 - 0x363  Serial Interface Data Register.
-#endif
-
-//----------------------------------------------------------------------------
-//       8185B TPPoll bits 				(offset 0xd9, 1 byte)
-//----------------------------------------------------------------------------
-#define TPPOLL_BQ			(0x01 << 7)
-#define TPPOLL_HPQ			(0x01 << 6)
-#define TPPOLL_AC_VOQ		(0x01 << 5)
-#define TPPOLL_AC_VIQ		(0x01 << 4)
-#define TPPOLL_AC_BEQ		(0x01 << 3)
-#define TPPOLL_AC_BKQ		(0x01 << 2)
-#define TPPOLL_AC_MGQ		(0x01 << 1)
 
 //----------------------------------------------------------------------------
 //       8185B TPPollStop bits 				(offset 0x93, 1 byte)
 //----------------------------------------------------------------------------
 #define TPPOLLSTOP_BQ			(0x01 << 7)
-#define TPPOLLSTOP_HPQ			(0x01 << 6)
-#define TPPOLLSTOP_AC_VOQ		(0x01 << 5)
 #define TPPOLLSTOP_AC_VIQ		(0x01 << 4)
-#define TPPOLLSTOP_AC_BEQ		(0x01 << 3)
-#define TPPOLLSTOP_AC_BKQ		(0x01 << 2)
-#define TPPOLLSTOP_AC_MGQ		(0x01 << 1)
-
 
 #define MSR_LINK_ENEDCA	   (1<<4)
 
@@ -885,7 +508,6 @@
 #define VIQ_ACM_EN				(0x01 << 6) //BIT6
 #define BEQ_ACM_EN				(0x01 << 5) //BIT5
 #define ACM_HW_EN				(0x01 << 4) //BIT4
-#define TXOPSEL					(0x01 << 3) //BIT3
 #define VOQ_ACM_CTL				(0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
 #define VIQ_ACM_CTL				(0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
 #define BEQ_ACM_CTL				(0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
@@ -916,7 +538,6 @@
 #define RTL8225z2_ANAPARAM_OFF	0x55480658
 #define RTL8225z2_ANAPARAM2_OFF	0x72003f70
 //by amy for power save
-#define RF_CHANGE_BY_SW BIT31
 #define RF_CHANGE_BY_HW BIT30
 #define RF_CHANGE_BY_PS BIT29
 #define RF_CHANGE_BY_IPS BIT28
@@ -934,23 +555,19 @@
 //{by amy 080312
 //0x7C, 0x7D Crystal calibration and Tx Power tracking mechanism. Added by Roger. 2007.12.10.
 #define EEPROM_RSV						0x7C
-#define EEPROM_XTAL_CAL_MASK			0x00FF	// 0x7C[7:0], Crystal calibration mask.
 #define EEPROM_XTAL_CAL_XOUT_MASK	0x0F	// 0x7C[3:0], Crystal calibration for Xout.
 #define EEPROM_XTAL_CAL_XIN_MASK		0xF0	// 0x7C[7:4], Crystal calibration for Xin.
 #define EEPROM_THERMAL_METER_MASK	0x0F00	// 0x7D[3:0], Thermal meter reference level.
 #define EEPROM_XTAL_CAL_ENABLE		0x1000	// 0x7D[4], Crystal calibration enabled/disabled BIT.
 #define EEPROM_THERMAL_METER_ENABLE	0x2000	// 0x7D[5], Thermal meter enabled/disabled BIT.
-#define EEPROM_CID_RSVD1				0x3F
 #define EN_LPF_CAL			0x238	// Enable LPF Calibration.
 #define PWR_METER_EN		BIT1
 // <RJ_TODO_8185B> where are false alarm counters in 8185B?
 #define CCK_FALSE_ALARM		0xD0
-#define OFDM_FALSE_ALARM	0xD2
 //by amy 080312}
 
 //YJ,add for Country IE, 080630
 #define EEPROM_COUNTRY_CODE  0x2E
 //YJ,add,080630,end
-#endif
 
 #endif
diff --git a/drivers/staging/rtl8187se/r8180_max2820.c b/drivers/staging/rtl8187se/r8180_max2820.c
deleted file mode 100644
index cea0846..0000000
--- a/drivers/staging/rtl8187se/r8180_max2820.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
-   This files contains MAXIM MAX2820 radio frontend programming routines.
-
-   This is part of rtl8180 OpenSource driver
-   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-   Released under the terms of GPL (General Public Licence)
-
-   Parts of this driver are based on the GPL part of the
-   official realtek driver
-
-   Parts of this driver are based on the rtl8180 driver skeleton
-   from Patric Schenke & Andres Salomon
-
-   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
-   NetBSD rtl8180 driver from Dave Young has been really useful to
-   understand how to program the MAXIM radio. Thanks a lot!!!
-
-   'The Deuce' tested this and fixed some bugs.
-
-   Code from rtl8181 project has been useful to me to understand some things.
-
-   We want to tanks the Authors of such projects and the Ndiswrapper
-   project Authors.
-*/
-
-
-#include "r8180.h"
-#include "r8180_hw.h"
-#include "r8180_max2820.h"
-
-
-//#define DEBUG_MAXIM
-
-u32 maxim_chan[] = {
-	0,	//dummy channel 0
-	12, //1
-	17, //2
-	22, //3
-	27, //4
-	32, //5
-	37, //6
-	42, //7
-	47, //8
-	52, //9
-	57, //10
-	62, //11
-	67, //12
-	72, //13
-	84, //14
-};
-
-#if 0
-/* maxim expects 4 bit address MSF, then 12 bit data MSF*/
-void write_maxim(struct net_device *dev,u8 adr, u32 data)
-{
-
-	int shift;
-	short bit;
-	u16 word;
-
-	adr = adr &0xf;
-	word = (u16)data & 0xfff;
-	word |= (adr<<12);
-	/*write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN);
-	read_nic_dword(dev,PHY_CONFIG);
-	mdelay(1);
-
-	write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
-	read_nic_dword(dev,PHY_CONFIG);
-	mdelay(1);
-	*/
-
-	/* MAX2820 will sample data on rising edge of clock */
-	for(shift = 15;shift >=0; shift--){
-		bit = word>>shift & 1;
-
-		write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA));
-
-		read_nic_dword(dev,PHY_CONFIG);
-		mdelay(2);
-
-		write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
-		(bit<<BB_HOST_BANG_DATA) | BB_HOST_BANG_CLK); /* sample data */
-
-		read_nic_dword(dev,PHY_CONFIG);
-		mdelay(1);
-
-		write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
-		(bit<<BB_HOST_BANG_DATA));
-
-		read_nic_dword(dev,PHY_CONFIG);
-		mdelay(2);
-
-	}
-	write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
-					BB_HOST_BANG_EN);
-	read_nic_dword(dev,PHY_CONFIG);
-	mdelay(2);
-
-	/* The shift register fill flush to the requested register the
-	 * last 12 bits data shifted in
-	 */
-	write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
-					BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
-	read_nic_dword(dev,PHY_CONFIG);
-	mdelay(2);
-
-	write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
-					BB_HOST_BANG_EN);
-	read_nic_dword(dev,PHY_CONFIG);
-	mdelay(2);
-
-
-#ifdef DEBUG_MAXIM
-	DMESG("Writing maxim: %x (adr %x)",phy_config,adr);
-#endif
-
-}
-#endif
-
-void write_maxim(struct net_device *dev,u8 adr, u32 data) {
-	u32 temp;
-	temp =  0x90 + (data & 0xf);
-	temp <<= 16;
-	temp += adr;
-	temp <<= 8;
-	temp += (data >> 4) & 0xff;
-#ifdef DEBUG_MAXIM
-	DMESG("write_maxim: %08x", temp);
-#endif
-	write_nic_dword(dev, PHY_CONFIG, temp);
-	force_pci_posting(dev);
-	mdelay(1);
-}
-
-
-void maxim_write_phy_antenna(struct net_device *dev,short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 ant;
-
-	ant = MAXIM_ANTENNA;
-	if(priv->antb) /*default antenna is antenna B */
-		ant |= BB_ANTENNA_B;
-	if(ch == 14)
-		ant |= BB_ANTATTEN_CHAN14;
-	write_phy(dev,0x10,ant);
-	//DMESG("BB antenna %x ",ant);
-}
-
-
-void maxim_rf_set_chan(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 txpw = 0xff & priv->chtxpwr[ch];
-	u32 chan = maxim_chan[ch];
-
-	/*While philips SA2400 drive the PA bias
-	 *seems that for MAXIM we delegate this
-	 *to the BB
-	 */
-
-	//write_maxim(dev,5,txpw);
-	write_phy(dev,3,txpw);
-
-	maxim_write_phy_antenna(dev,ch);
-	write_maxim(dev,3,chan);
-}
-
-
-void maxim_rf_close(struct net_device *dev)
-{
-	write_phy(dev, 3, 0x8);
-	write_maxim(dev, 1, 0);
-}
-
-
-void maxim_rf_init(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 anaparam;
-
-	write_nic_byte(dev,PHY_DELAY,0x6);	//this is general
-	write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
-
-	/*these are maxim specific*/
-	anaparam = read_nic_dword(dev,ANAPARAM);
-	anaparam = anaparam &~ (ANAPARAM_TXDACOFF_SHIFT);
-	anaparam = anaparam &~ANAPARAM_PWR1_MASK;
-	anaparam = anaparam &~ANAPARAM_PWR0_MASK;
-	anaparam |= (MAXIM_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
-	anaparam |= (MAXIM_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
-
-	//rtl8180_set_anaparam(dev,anaparam);
-
-	/* MAXIM from netbsd driver */
-
-	write_maxim(dev,0, 7); /* test mode as indicated in datasheet*/
-	write_maxim(dev,1, 0x1e); /* enable register*/
-	write_maxim(dev,2, 1); /* synt register */
-
-
-	maxim_rf_set_chan(dev,priv->chan);
-
-	write_maxim(dev,4, 0x313); /* rx register*/
-
-	/* PA is driven directly by the BB, we keep the MAXIM bias
-	 * at the highest value in the boubt tha pleacing it to lower
-	 * values may introduce some further attenuation somewhere..
-	 */
-
-	write_maxim(dev,5, 0xf);
-
-
-	/*baseband configuration*/
-	write_phy(dev,0,0x88); //sys1
-	write_phy(dev,3,0x8); //txagc
-	write_phy(dev,4,0xf8); // lnadet
-	write_phy(dev,5,0x90); // ifagcinit
-	write_phy(dev,6,0x1a); // ifagclimit
-	write_phy(dev,7,0x64); // ifagcdet
-
-	/*Should be done something more here??*/
-
-	maxim_write_phy_antenna(dev,priv->chan);
-
-	write_phy(dev,0x11,0x88); //trl
-	if(priv->diversity)
-		write_phy(dev,0x12,0xc7);
-	else
-		write_phy(dev,0x12,0x47);
-
-	write_phy(dev,0x13,0x9b);
-
-	write_phy(dev,0x19,0x0); //CHESTLIM
-	write_phy(dev,0x1a,0x9f); //CHSQLIM
-
-	maxim_rf_set_chan(dev,priv->chan);
-}
diff --git a/drivers/staging/rtl8187se/r8180_max2820.h b/drivers/staging/rtl8187se/r8180_max2820.h
deleted file mode 100644
index 5d4fb55..0000000
--- a/drivers/staging/rtl8187se/r8180_max2820.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-	This is part of rtl8180 OpenSource driver
-	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the official realtek driver
-	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
-	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
-	We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-#define MAXIM_ANTENNA 0xb3
-#define MAXIM_ANAPARAM_PWR1_ON 0x8
-#define MAXIM_ANAPARAM_PWR0_ON 0x0
-
-
-void maxim_rf_init(struct net_device *dev);
-void maxim_rf_set_chan(struct net_device *dev,short ch);
-
-void maxim_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_pm.c b/drivers/staging/rtl8187se/r8180_pm.c
deleted file mode 100644
index 2b3d642..0000000
--- a/drivers/staging/rtl8187se/r8180_pm.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-   Power management interface routines.
-   Written by Mariusz Matuszek.
-   This code is currently just a placeholder for later work and
-   does not do anything useful.
-
-   This is part of rtl8180 OpenSource driver.
-   Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
-   Released under the terms of GPL (General Public Licence)
-*/
-
-#ifdef CONFIG_RTL8180_PM
-
-
-#include "r8180_hw.h"
-#include "r8180_pm.h"
-#include "r8180.h"
-
-int rtl8180_save_state (struct pci_dev *dev, u32 state)
-{
-        printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
-	return(-EAGAIN);
-}
-
-int rtl8180_suspend (struct pci_dev *pdev, pm_message_t state)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	if (!netif_running(dev))
-		goto out_pci_suspend;
-
-	if (dev->netdev_ops->ndo_stop)
-		dev->netdev_ops->ndo_stop(dev);
-
-	netif_device_detach(dev);
-
-out_pci_suspend:
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
-	pci_set_power_state(pdev,pci_choose_state(pdev,state));
-	return 0;
-}
-
-int rtl8180_resume (struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-	int err;
-	u32 val;
-
-	pci_set_power_state(pdev, PCI_D0);
-
-	err = pci_enable_device(pdev);
-	if(err) {
-		printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
-				dev->name);
-
-		return err;
-	}
-	pci_restore_state(pdev);
-	/*
-	 * Suspend/Resume resets the PCI configuration space, so we have to
-	 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
-	 * from interfering with C3 CPU state. pci_restore_state won't help
-	 * here since it only restores the first 64 bytes pci config header.
-	 */
-	pci_read_config_dword(pdev, 0x40, &val);
-	if ((val & 0x0000ff00) != 0)
-		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
-	if(!netif_running(dev))
-		goto out;
-
-	if (dev->netdev_ops->ndo_open)
-		dev->netdev_ops->ndo_open(dev);
-	netif_device_attach(dev);
-out:
-	return 0;
-}
-
-
-int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
-{
-        printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
-	       state, enable);
-	return(-EAGAIN);
-}
-
-
-
-#endif //CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8187se/r8180_pm.h b/drivers/staging/rtl8187se/r8180_pm.h
deleted file mode 100644
index 7958b3a..0000000
--- a/drivers/staging/rtl8187se/r8180_pm.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-        Power management interface routines.
-	Written by Mariusz Matuszek.
-	This code is currently just a placeholder for later work and
-	does not do anything useful.
-
-	This is part of rtl8180 OpenSource driver.
-	Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
-	Released under the terms of GPL (General Public Licence)
-
-*/
-
-#ifdef CONFIG_RTL8180_PM
-
-#ifndef R8180_PM_H
-#define R8180_PM_H
-
-#include <linux/types.h>
-#include <linux/pci.h>
-
-int rtl8180_save_state (struct pci_dev *dev, u32 state);
-int rtl8180_suspend (struct pci_dev *pdev, pm_message_t state);
-int rtl8180_resume (struct pci_dev *pdev);
-int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
-
-#endif //R8180_PM_H
-
-#endif // CONFIG_RTL8180_PM
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.c b/drivers/staging/rtl8187se/r8180_rtl8225.c
deleted file mode 100644
index 96ed029..0000000
--- a/drivers/staging/rtl8187se/r8180_rtl8225.c
+++ /dev/null
@@ -1,933 +0,0 @@
-/*
-  This is part of the rtl8180-sa2400 driver
-  released under the GPL (See file COPYING for details).
-  Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
-
-  This files contains programming code for the rtl8225
-  radio frontend.
-
-  *Many* thanks to Realtek Corp. for their great support!
-
-*/
-
-
-
-#include "r8180_hw.h"
-#include "r8180_rtl8225.h"
-
-
-u8 rtl8225_gain[]={
-	0x23,0x88,0x7c,0xa5,// -82dbm
-	0x23,0x88,0x7c,0xb5,// -82dbm
-	0x23,0x88,0x7c,0xc5,// -82dbm
-	0x33,0x80,0x79,0xc5,// -78dbm
-	0x43,0x78,0x76,0xc5,// -74dbm
-	0x53,0x60,0x73,0xc5,// -70dbm
-	0x63,0x58,0x70,0xc5,// -66dbm
-};
-
-#if 0
-u8 rtl8225_init_gain[]={
-	//0x00,0x00,0x00,0x00,//0x00,0x00,0x00,0x00,
-	0x33,0x80,0x6c,0xc5,//0x00,0x49,0x06,0xb5,//Gain = 0 ~ -78dbm
-	0x43,0x78,0x69,0xc5,//0x00,0x45,0x06,0xb1,//Gain = 1 ~ -74dbm
-	0x53,0x60,0x66,0xc5,//0x00,0x41,0x06,0xab,//Gain = 2 ~ -70dbm
-	0x63,0x58,0x63,0xc5,//0x00,0x3d,0x06,0xa5,//Gain = 3 ~ -66dbm
-	0x73,0x50,0x62,0xc5,//0x00,0x39,0x06,0xa1,//Gain = 4 ~ -62dbm
-	0x83,0x43,0x61,0xc5,//0x00,0x35,0x06,0x9b,//Gain = 5 ~ -58dbm
-	0x93,0x38,0x5a,0xc5,//0x00,0x31,0x06,0x99,//Gain = 6 ~ -54dbm
-};
-#endif
-#ifdef CONFIG_RTL818X_S
-u32 rtl8225_chan[] ={
-              0,
-		0x0080, //ch1
-		0x0100, //ch2
-		0x0180, //ch3
-		0x0200, //ch4
-		0x0280,
-		0x0300,
-		0x0380,
-		0x0400,
-		0x0480,
-		0x0500,
-		0x0580,
-		0x0600,
-		0x0680,
-		0x074A, //ch14
-};
-#else
-u32 rtl8225_chan[] = {
-	0,	//dummy channel 0
-	0x085c, //1
-	0x08dc, //2
-	0x095c, //3
-	0x09dc, //4
-	0x0a5c, //5
-	0x0adc, //6
-	0x0b5c, //7
-	0x0bdc, //8
-	0x0c5c, //9
-	0x0cdc, //10
-	0x0d5c, //11
-	0x0ddc, //12
-	0x0e5c, //13
-	//0x0f5c, //14
-	0x0f72, // 14
-};
-#endif
-
-u16 rtl8225bcd_rxgain[]={
-	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
-	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
-	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
-	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
-	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
-	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
-	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
-	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
-	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
-	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
-	0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
-	0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
-
-};
-
-
-#if 0
-u16 rtl8225bc_rxgain[]={
-	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
-	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
-	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
-	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
-	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
-	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
-	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
-	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
-	0x0794, 0x0795, 0x0798, 0x0799, 0x039a, 0x039b, 0x039c, 0x039d,
-	0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
-	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
-	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
-
-};
-
-
-u16 rtl8225a_rxgain[]={
-	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
-	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
-	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
-	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
-	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
-	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
-	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
-	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
-	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
-	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
-	0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad,
-	0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad
-};
-#endif
-
-u8 rtl8225_agc[]={
-	0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
-	0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
-	0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
-	0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
-	0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
-	0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
-	0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-	0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-};
-
-
-u8 rtl8225_tx_gain_cck_ofdm[]={
-	0x02,0x06,0x0e,0x1e,0x3e,0x7e
-};
-
-
-u8 rtl8225_tx_power_ofdm[]={
-	0x80,0x90,0xa2,0xb5,0xcb,0xe4
-};
-
-
-u8 rtl8225_tx_power_cck_ch14[]={
-	0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
-	0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
-	0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
-	0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
-	0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
-	0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00
-};
-
-
-u8 rtl8225_tx_power_cck[]={
-	0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,
-	0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,
-	0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,
-	0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,
-	0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,
-	0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03
-};
-
-
-void rtl8225_set_gain(struct net_device *dev, short gain)
-{
-	write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
-	write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
-	write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
-	write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
-}
-#if 0
-
-void rtl8225_set_gain(struct net_device *dev, short gain)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-
-	if(priv->card_8185 == 2)
-		write_phy_ofdm(dev, 0x21, 0x27);
-	else
-		write_phy_ofdm(dev, 0x21, 0x37);
-
-	write_phy_ofdm(dev, 0x25, 0x20);
-	write_phy_ofdm(dev, 0x11, 0x6);
-
-	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-		write_phy_ofdm(dev, 0x27, 0x8);
-	else
-		write_phy_ofdm(dev, 0x27, 0x88);
-
-	write_phy_ofdm(dev, 0x14, 0);
-	write_phy_ofdm(dev, 0x16, 0);
-	write_phy_ofdm(dev, 0x15, 0x40);
-	write_phy_ofdm(dev, 0x17, 0x40);
-
-	write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
-	write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
-	write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
-	write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
-	//rtl8225_set_gain_usb(dev, gain);
-}
-#endif
-
-
-void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
-{
-	int i;
-	u16 out,select;
-	u8 bit;
-	u32 bangdata = (data << 4) | (adr & 0xf);
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
-
-	write_nic_word(dev,RFPinsEnable,
-		(read_nic_word(dev,RFPinsEnable) | 0x7));
-
-	select = read_nic_word(dev, RFPinsSelect);
-
-	write_nic_word(dev, RFPinsSelect, select | 0x7 |
-		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
-
-	force_pci_posting(dev);
-	udelay(2);
-
-	write_nic_word(dev, RFPinsOutput, out);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-
-	for(i=15; i>=0;i--){
-
-		bit = (bangdata & (1<<i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out);
-
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
-		i--;
-		bit = (bangdata & (1<<i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
-		write_nic_word(dev, RFPinsOutput, bit | out);
-
-	}
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out |
-		((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
-
-	write_nic_word(dev, RFPinsSelect, select |
-		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
-
-	if(priv->card_type == USB)
-		mdelay(2);
-	else
-		rtl8185_rf_pins_enable(dev);
-}
-
-void rtl8225_rf_close(struct net_device *dev)
-{
-	write_rtl8225(dev, 0x4, 0x1f);
-
-	force_pci_posting(dev);
-	mdelay(1);
-
-	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
-	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
-}
-
-void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	int GainIdx;
-	int GainSetting;
-	int i;
-	u8 power;
-	u8 *cck_power_table;
-	u8 max_cck_power_level;
-	u8 max_ofdm_power_level;
-	u8 min_ofdm_power_level;
-	u8 cck_power_level = 0xff & priv->chtxpwr[ch];
-	u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
-
-	if(priv->card_type == USB){
-		max_cck_power_level = 11;
-		max_ofdm_power_level = 25; //  12 -> 25
-		min_ofdm_power_level = 10;
-	}else{
-		max_cck_power_level = 35;
-		max_ofdm_power_level = 35;
-		min_ofdm_power_level = 0;
-	}
-	/* CCK power setting */
-	if(cck_power_level > max_cck_power_level)
-		cck_power_level = max_cck_power_level;
-	GainIdx=cck_power_level % 6;
-	GainSetting=cck_power_level / 6;
-
-	if(ch == 14)
-		cck_power_table = rtl8225_tx_power_cck_ch14;
-	else
-		cck_power_table = rtl8225_tx_power_cck;
-
-//	if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
-		/*Ver B*/
-//		write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
-//	}else{
-		/*Ver C - D */
-	write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
-//	}
-
-	for(i=0;i<8;i++){
-
-		power = cck_power_table[GainIdx * 8 + i];
-		write_phy_cck(dev, 0x44 + i, power);
-	}
-
-	/* FIXME Is this delay really needeed ? */
-	force_pci_posting(dev);
-	mdelay(1);
-
-	/* OFDM power setting */
-//  Old:
-//	if(ofdm_power_level > max_ofdm_power_level)
-//		ofdm_power_level = 35;
-//	ofdm_power_level += min_ofdm_power_level;
-//  Latest:
-	if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
-		ofdm_power_level = max_ofdm_power_level;
-	else
-		ofdm_power_level += min_ofdm_power_level;
-	if(ofdm_power_level > 35)
-		ofdm_power_level = 35;
-//
-
-	GainIdx=ofdm_power_level % 6;
-	GainSetting=ofdm_power_level / 6;
-#if 1
-//	if(priv->card_type == USB){
-		rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
-
-		write_phy_ofdm(dev,2,0x42);
-		write_phy_ofdm(dev,6,0);
-		write_phy_ofdm(dev,8,0);
-//	}
-#endif
-//	if(priv->card_8185 == 1 && priv->card_8185_Bversion){
-//		/*Ver B*/
-//		write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
-//	}else{
-		/*Ver C - D */
-	write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
-//	}
-
-
-	power = rtl8225_tx_power_ofdm[GainIdx];
-
-	write_phy_ofdm(dev, 0x5, power);
-	write_phy_ofdm(dev, 0x7, power);
-
-	force_pci_posting(dev);
-	mdelay(1);
-	//write_nic_byte(dev, TX_AGC_CONTROL,4);
-}
-#if 0
-/* switch between mode B and G */
-void rtl8225_set_mode(struct net_device *dev, short modeb)
-{
-	write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
-	write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
-}
-#endif
-void rtl8225_rf_set_chan(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
-		ieee80211_is_54g(priv->ieee80211->current_network)) ||
-		priv->ieee80211->iw_mode == IW_MODE_MONITOR;
-
-	rtl8225_SetTXPowerLevel(dev, ch);
-
-	write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
-
-	force_pci_posting(dev);
-	mdelay(10);
-
-	// A mode sifs 0x44, difs 34-14, slot 9, eifs 23, cwm 3, cwM 7, ctstoself 0x10
-	if(gset){
-		write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
-		write_nic_byte(dev,DIFS,0x14); //DIFS: 20
-		//write_nic_byte(dev,DIFS,20); //DIFS: 20
-	}else{
-		write_nic_byte(dev,SIFS,0x44);// SIFS: 0x22
-		write_nic_byte(dev,DIFS,50 - 14); //DIFS: 36
-	}
-	if(priv->ieee80211->state == IEEE80211_LINKED &&
-		ieee80211_is_shortslot(priv->ieee80211->current_network))
-		write_nic_byte(dev,SLOT,0x9); //SLOT: 9
-
-	else
-		write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
-
-
-	if(gset){
-		write_nic_byte(dev,EIFS,81);//91 - 20); // EIFS: 91 (0x5B)
-		write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
-		//DMESG("using G net params");
-	}else{
-		write_nic_byte(dev,EIFS,81); // EIFS: 91 (0x5B)
-		write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
-		//DMESG("using B net params");
-	}
-
-
-}
-
-void rtl8225_host_pci_init(struct net_device *dev)
-{
-	write_nic_word(dev, RFPinsOutput, 0x480);
-
-	rtl8185_rf_pins_enable(dev);
-
-	//if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
-	//write_nic_word(dev, RFPinsSelect, 0x88);
-	//else
-	write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
-
-	write_nic_byte(dev, GP_ENABLE, 0);
-
-	force_pci_posting(dev);
-	mdelay(200);
-
-	write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
-
-
-}
-
-void rtl8225_host_usb_init(struct net_device *dev)
-{
-	#if 0
-	write_nic_byte(dev,RFPinsSelect+1,0);
-
-	write_nic_byte(dev,GPIO,0);
-
-	write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
-
-	write_nic_byte(dev,RFPinsSelect+1,4);
-
-	write_nic_byte(dev,GPIO,0x20);
-
-	write_nic_byte(dev,GP_ENABLE,0);
-
-
-	/* Config BB & RF */
-	write_nic_word(dev, RFPinsOutput, 0x80);
-
-	write_nic_word(dev, RFPinsSelect, 0x80);
-
-	write_nic_word(dev, RFPinsEnable, 0x80);
-
-
-	mdelay(100);
-
-	mdelay(1000);
-#endif
-
-}
-
-void rtl8225_rf_sleep(struct net_device *dev)
-{
-	write_rtl8225(dev,0x4,0xdff);
-	force_pci_posting(dev);
-	mdelay(1);
-	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_SLEEP);
-	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_SLEEP);
-	force_pci_posting(dev);
-}
-
-void rtl8225_rf_wakeup(struct net_device *dev)
-{
-	write_rtl8225(dev,0x4,0x9ff);
-	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-	force_pci_posting(dev);
-}
-
-void rtl8225_rf_init(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int i;
-	short channel = 1;
-	u16 brsr;
-
-	priv->chan = channel;
-
-	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-
-
-	if(priv->card_type == USB)
-		rtl8225_host_usb_init(dev);
-	else
-		rtl8225_host_pci_init(dev);
-
-	write_nic_dword(dev, RF_TIMING, 0x000a8008);
-
-	brsr = read_nic_word(dev, BRSR);
-
-	write_nic_word(dev, BRSR, 0xffff);
-
-	#if 0
-	if(priv->card_8185 == 1){/* version C or B */
-		if(priv->card_8185_Bversion)  /* version B*/
-			write_nic_dword(dev, RF_PARA, 0x44);
-		else    /* version C */
-			write_nic_dword(dev, RF_PARA, 0x100044);
-	}else{ /* version D */
-		if(priv->enable_gpio0)
-			write_nic_dword(dev, RF_PARA, 0x20100044);
-		else /* also USB */
-			write_nic_dword(dev, RF_PARA, 0x100044);
-	}
-	#endif
-
-	write_nic_dword(dev, RF_PARA, 0x100044);
-
-	#if 1  //0->1
-	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-	write_nic_byte(dev, CONFIG3, 0x44);
-	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-	#endif
-
-	if(priv->card_type == USB){
-		rtl8185_rf_pins_enable(dev);
-
-		mdelay(1000);
-	}
-
-	write_rtl8225(dev, 0x0, 0x67); mdelay(1);
-
-
-	write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
-
-	write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
-
-	write_rtl8225(dev, 0x3, 0x441); mdelay(1);
-
-	if(priv->card_type == USB)
-		write_rtl8225(dev, 0x4, 0x486);
-	else
-		write_rtl8225(dev, 0x4, 0x8be);
-
-	mdelay(1);
-
-
-	#if 0
-	}else if(priv->phy_ver == 1){
-		/* version A */
-		write_rtl8225(dev, 0x5, 0xbc0 + 2);
-	}else{
-	#endif
-	/* version B & C */
-
-	if(priv->card_type == USB)
-		write_rtl8225(dev, 0x5, 0xbc0);
-	else if(priv->card_type == MINIPCI)
-		write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3));
-	else
-		write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
-
-	 mdelay(1);
-//	}
-
-	write_rtl8225(dev, 0x6, 0xae6);  mdelay(1);
-
-	write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel]));  mdelay(1);
-
-	write_rtl8225(dev, 0x8, 0x1f);  mdelay(1);
-
-	write_rtl8225(dev, 0x9, 0x334);  mdelay(1);
-
-	write_rtl8225(dev, 0xa, 0xfd4);  mdelay(1);
-
-	write_rtl8225(dev, 0xb, 0x391);  mdelay(1);
-
-	write_rtl8225(dev, 0xc, 0x50);  mdelay(1);
-
-
-	write_rtl8225(dev, 0xd, 0x6db);   mdelay(1);
-
-	write_rtl8225(dev, 0xe, 0x29);  mdelay(1);
-
-	write_rtl8225(dev, 0xf, 0x914);
-
-	if(priv->card_type == USB){
-		//force_pci_posting(dev);
-		mdelay(100);
-	}
-
-	write_rtl8225(dev, 0x2, 0xc4d);
-
-	if(priv->card_type == USB){
-	//	force_pci_posting(dev);
-		mdelay(200);
-
-		write_rtl8225(dev, 0x2, 0x44d);
-
-	//	force_pci_posting(dev);
-		mdelay(100);
-
-	}//End of if(priv->card_type == USB)
-	/* FIXME!! rtl8187 we have to check if calibrarion
-	 * is successful and eventually cal. again (repeat
-	 * the two write on reg 2)
-	*/
-	force_pci_posting(dev);
-
-	mdelay(100); //200 for 8187
-
-	//if(priv->card_type != USB) /* maybe not needed even for 8185 */
-//	write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
-
-	write_rtl8225(dev, 0x0, 0x127);
-
-	for(i=0;i<95;i++){
-		write_rtl8225(dev, 0x1, (u8)(i+1));
-
-		#if 0
-		if(priv->phy_ver == 1)
-			/* version A */
-			write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
-		else
-		#endif
-		/* version B & C & D*/
-
-		write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
-	}
-
-	write_rtl8225(dev, 0x0, 0x27);
-
-
-//	//if(priv->card_type != USB){
-//		write_rtl8225(dev, 0x2, 0x44d);
-//		write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
-//		write_rtl8225(dev, 0x2, 0x47d);
-//
-//		force_pci_posting(dev);
-//		mdelay(100);
-//
-//		write_rtl8225(dev, 0x2, 0x44d);
-//	//}
-
-	write_rtl8225(dev, 0x0, 0x22f);
-
-	if(priv->card_type != USB)
-		rtl8185_rf_pins_enable(dev);
-
-	for(i=0;i<128;i++){
-		write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
-
-		mdelay(1);
-		write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
-
-		mdelay(1);
-	}
-
-	force_pci_posting(dev);
-	mdelay(1);
-
-	write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
-	write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
-	write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
-	write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
-
-	#if 0
-	if(priv->card_type == USB){
-		write_phy_ofdm(dev, 0xa, 0x9);
-	}else{
-		if(priv->card_8185 == 1 && priv->card_8185_Bversion){
-			/* Ver B
-			* maybe later version can accept this also?
-			*/
-			write_phy_ofdm(dev, 0xa, 0x6);
-			write_phy_ofdm(dev, 0x18, 0x6f);
-		}else{
-	#endif
-			/* ver C & D */
-	write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
-
-	//write_phy_ofdm(dev, 0x18, 0xef);
-	//	}
-	//}
-	write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
-
-	write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
-
-
-	//if(priv->card_type != USB)
-	//write_phy_ofdm(dev, 0xd, 0x33); // <>
-
-	write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
-
-
-	#if 0
-	if(priv->card_8185 == 1){
-		if(priv->card_8185_Bversion)
-			write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
-		else
-			write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
-	}else{
-	#endif
-	write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
-/*ver D & 8187*/
-//	}
-
-//	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-//		write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
-//	else
-	write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
-/*ver C & D & 8187*/
-
-	write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
-/*agc resp time 700*/
-
-
-//	if(priv->card_8185 == 2){
-	/* Ver D & 8187*/
-	write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
-
-	write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
-
-#if 0
-	}else{
-		/* Ver B & C*/
-		write_phy_ofdm(dev, 0x12, 0x0);
-		write_phy_ofdm(dev, 0x13, 0x0);
-	}
-#endif
-	write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
-
-//	if (priv->card_type == USB)
-//		write_phy_ofdm(dev, 0x18, 0xef);
-
-	write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
-
-
-	write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
-	write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
-
-//	if (priv->card_type != USB){
-//		if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-//			write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */
-//		else
-	write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
- /* Ver C & D */ //FIXME:MAYBE not needed
-//	}
-
-	write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
-
-#if 0
-	if(priv->card_8185 == 1){
-		if(priv->card_8185_Bversion){
-			/*ver B*/
-			write_phy_ofdm(dev, 0x1e, 0x95);
-			write_phy_ofdm(dev, 0x1f, 0x55);
-		}else{
-			/*ver C*/
-			write_phy_ofdm(dev, 0x1e, 0x90);
-			write_phy_ofdm(dev, 0x1f, 0x34);
-
-		}
-	}else{
-#endif
-		/*ver D & 8187*/
-	write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
-
-	write_phy_ofdm(dev, 0x1f, 0x75);	mdelay(1);
-
-//	}
-
-	write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
-
-	write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
-
-	write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
-
-//	if(priv->card_type != USB)
-	//write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
-
-	write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
-	write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
-	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
-#if 0
-	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-		write_phy_ofdm(dev, 0x27, 0x08); /* Ver B. might work also fo ver C&D ?*/
-	else
-#endif
-	write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
-/* Ver C & D & 8187*/
-
-	// <> Set init. gain to m74dBm.
-	write_phy_ofdm(dev, 0x0d, 0x43);	 mdelay(1);
-	write_phy_ofdm(dev, 0x1b, 0x76);	 mdelay(1);
-	write_phy_ofdm(dev, 0x1d, 0xc5);	 mdelay(1);
-	write_phy_ofdm(dev, 0x23, 0x78);	 mdelay(1);
-
-	//if(priv->card_type == USB);
-	//	rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
-
-	write_phy_cck(dev, 0x0, 0x98); mdelay(1);
-	write_phy_cck(dev, 0x3, 0x20); mdelay(1);
-	write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
-	write_phy_cck(dev, 0x5, 0x12); mdelay(1);
-	write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
-#if 0
-	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-		write_phy_cck(dev, 0x7, 0xd8); /* Ver B */
-	else
-#endif
-	write_phy_cck(dev, 0x7, 0x78);mdelay(1);
- /* Ver C & D & 8187*/
-
-	write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
-
-	write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
-	write_phy_cck(dev, 0x11, 0x88); mdelay(1);
-	write_phy_cck(dev, 0x12, 0x47); mdelay(1);
-#if 0
-	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-		write_phy_cck(dev, 0x13, 0x98); /* Ver B */
-	else
-#endif
-	write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
-
-	write_phy_cck(dev, 0x19, 0x0);
-	write_phy_cck(dev, 0x1a, 0xa0);
-	write_phy_cck(dev, 0x1b, 0x8);
-	write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
-
-	write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
-
-
-	write_phy_cck(dev, 0x42, 0x15); mdelay(1);
-	write_phy_cck(dev, 0x43, 0x18); mdelay(1);
-	write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
-	write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
-	write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
-	write_phy_cck(dev, 0x47, 0x15); mdelay(1);
-	write_phy_cck(dev, 0x48, 0x10); mdelay(1);
-	write_phy_cck(dev, 0x49, 0xa); mdelay(1);
-	write_phy_cck(dev, 0x4a, 0x5); mdelay(1);
-	write_phy_cck(dev, 0x4b, 0x2); mdelay(1);
-	write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
-
-
-	write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
-
-
-
-// <>
-//	// TESTR 0xb 8187
-//	write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
-//
-//	//if(priv->card_type != USB){
-//		write_phy_ofdm(dev, 0x2, 0x62);
-//		write_phy_ofdm(dev, 0x6, 0x0);
-//		write_phy_ofdm(dev, 0x8, 0x0);
-//	//}
-
-	rtl8225_SetTXPowerLevel(dev, channel);
-
-	write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
-	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
-
-	rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
-
-	/* switch to high-speed 3-wire
-	 * last digit. 2 for both cck and ofdm
-	 */
-	if(priv->card_type == USB)
-		write_nic_dword(dev, 0x94, 0x3dc00002);
-	else{
-		write_nic_dword(dev, 0x94, 0x15c00002);
-		rtl8185_rf_pins_enable(dev);
-	}
-
-//	if(priv->card_type != USB)
-//	rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
-//	 rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
-//
-//	/* make sure is waken up! */
-//	write_rtl8225(dev,0x4, 0x9ff);
-//	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-//	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-
-	rtl8225_rf_set_chan(dev, priv->chan);
-
-	write_nic_word(dev,BRSR,brsr);
-
-}
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h
index 458de66..ed35db5 100644
--- a/drivers/staging/rtl8187se/r8180_rtl8225.h
+++ b/drivers/staging/rtl8187se/r8180_rtl8225.h
@@ -19,23 +19,13 @@
 #define RTL8225_ANAPARAM_SLEEP 0xa00bab59
 #define RTL8225_ANAPARAM2_SLEEP 0x840dec11
 
-#ifdef CONFIG_RTL8185B
 void rtl8225z2_rf_init(struct net_device *dev);
 void rtl8225z2_rf_set_chan(struct net_device *dev,short ch);
 void rtl8225z2_rf_close(struct net_device *dev);
 
-void rtl8225_host_pci_init(struct net_device *dev);
-void rtl8225_host_usb_init(struct net_device *dev);
-
-void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
 void RF_WriteReg(struct net_device *dev, u8 offset, u32	data);
 u32 RF_ReadReg(struct net_device *dev, u8 offset);
-#endif
-void rtl8225_rf_init(struct net_device *dev);
-void rtl8225_rf_set_chan(struct net_device *dev,short ch);
-void rtl8225_rf_close(struct net_device *dev);
-void rtl8225_rf_sleep(struct net_device *dev);
-void rtl8225_rf_wakeup(struct net_device *dev);
+
 void rtl8180_set_mode(struct net_device *dev,int mode);
 void rtl8180_set_mode(struct net_device *dev,int mode);
 bool SetZebraRFPowerState8185(struct net_device *dev,RT_RF_POWER_STATE  eRFPowerState);
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
index 4136b94..b648751 100644
--- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c
+++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
@@ -14,64 +14,76 @@
 #include "r8180_rtl8225.h"
 #include "r8180_93cx6.h"
 
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
+#include "ieee80211/dot11d.h"
 
-#ifdef CONFIG_RTL8185B
 
-extern u8 rtl8225_agc[];
+static void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
+{
+	int i;
+	u16 out, select;
+	u8 bit;
+	u32 bangdata = (data << 4) | (adr & 0xf);
+	struct r8180_priv *priv = ieee80211_priv(dev);
 
-extern u32 rtl8225_chan[];
+	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
 
-//2005.11.16
-u8 rtl8225z2_threshold[]={
-        0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
-};
+	write_nic_word(dev, RFPinsEnable,
+		(read_nic_word(dev, RFPinsEnable) | 0x7));
 
-//      0xd 0x19 0x1b 0x21
-u8 rtl8225z2_gain_bg[]={
-	0x23, 0x15, 0xa5, // -82-1dbm
-        0x23, 0x15, 0xb5, // -82-2dbm
-        0x23, 0x15, 0xc5, // -82-3dbm
-        0x33, 0x15, 0xc5, // -78dbm
-        0x43, 0x15, 0xc5, // -74dbm
-        0x53, 0x15, 0xc5, // -70dbm
-        0x63, 0x15, 0xc5, // -66dbm
-};
+	select = read_nic_word(dev, RFPinsSelect);
 
-u8 rtl8225z2_gain_a[]={
-	0x13,0x27,0x5a,//,0x37,// -82dbm
-	0x23,0x23,0x58,//,0x37,// -82dbm
-	0x33,0x1f,0x56,//,0x37,// -82dbm
-	0x43,0x1b,0x54,//,0x37,// -78dbm
-	0x53,0x17,0x51,//,0x37,// -74dbm
-	0x63,0x24,0x4f,//,0x37,// -70dbm
-	0x73,0x0f,0x4c,//,0x37,// -66dbm
-};
-#if 0
-u32 rtl8225_chan[] = {
-	0,	//dummy channel 0
-	0x085c, //1
-	0x08dc, //2
-	0x095c, //3
-	0x09dc, //4
-	0x0a5c, //5
-	0x0adc, //6
-	0x0b5c, //7
-	0x0bdc, //8
-	0x0c5c, //9
-	0x0cdc, //10
-	0x0d5c, //11
-	0x0ddc, //12
-	0x0e5c, //13
-	//0x0f5c, //14
-	0x0f72, // 14
-};
-#endif
+	write_nic_word(dev, RFPinsSelect, select | 0x7 |
+		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
+
+	force_pci_posting(dev);
+	udelay(10);
+
+	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
+
+	force_pci_posting(dev);
+	udelay(2);
+
+	write_nic_word(dev, RFPinsOutput, out);
+
+	force_pci_posting(dev);
+	udelay(10);
+
+	for (i = 15; i >= 0; i--) {
+		bit = (bangdata & (1 << i)) >> i;
+
+		write_nic_word(dev, RFPinsOutput, bit | out);
 
-//-
-u16 rtl8225z2_rxgain[]={
+		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
+		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
+
+		i--;
+		bit = (bangdata & (1 << i)) >> i;
+
+		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
+		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
+
+		write_nic_word(dev, RFPinsOutput, bit | out);
+
+	}
+
+	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
+
+	force_pci_posting(dev);
+	udelay(10);
+
+	write_nic_word(dev, RFPinsOutput, out |
+		((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
+
+	write_nic_word(dev, RFPinsSelect, select |
+		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
+
+	if (priv->card_type == USB)
+		mdelay(2);
+	else
+		rtl8185_rf_pins_enable(dev);
+}
+
+static const u16 rtl8225bcd_rxgain[] = {
 	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
 	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
 	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
@@ -82,127 +94,234 @@ u16 rtl8225z2_rxgain[]={
 	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
 	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
 	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
-	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
-	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
+	0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
+	0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
 
 };
 
-//2005.11.16,
-u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={
-        0x00,0x01,0x02,0x03,0x04,0x05,
-        0x06,0x07,0x08,0x09,0x0a,0x0b,
-        0x0c,0x0d,0x0e,0x0f,0x10,0x11,
-        0x12,0x13,0x14,0x15,0x16,0x17,
-        0x18,0x19,0x1a,0x1b,0x1c,0x1d,
-        0x1e,0x1f,0x20,0x21,0x22,0x23,
+static const u8 rtl8225_agc[] = {
+	0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+	0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
+	0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
+	0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
+	0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
+	0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
+	0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
+	0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
+	0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
+	0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
+	0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
+	0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
+	0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 };
 
-#if 0
-//-
-u8 rtl8225_agc[]={
-	0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
-	0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
-	0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
-	0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
-	0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
-	0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
-	0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-	0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-};
-#endif
-/*
- from 0 to 0x23
-u8 rtl8225_tx_gain_cck_ofdm[]={
-	0x02,0x06,0x0e,0x1e,0x3e,0x7e
+static const u8 rtl8225_gain[] = {
+	0x23, 0x88, 0x7c, 0xa5,	/* -82dBm */
+	0x23, 0x88, 0x7c, 0xb5,	/* -82dBm */
+	0x23, 0x88, 0x7c, 0xc5,	/* -82dBm */
+	0x33, 0x80, 0x79, 0xc5,	/* -78dBm */
+	0x43, 0x78, 0x76, 0xc5,	/* -74dBm */
+	0x53, 0x60, 0x73, 0xc5,	/* -70dBm */
+	0x63, 0x58, 0x70, 0xc5,	/* -66dBm */
 };
-*/
 
-//-
-u8 rtl8225z2_tx_power_ofdm[]={
-	0x42,0x00,0x40,0x00,0x40
+static const u8 rtl8225_tx_gain_cck_ofdm[] = {
+	0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
 };
 
-
-//-
-u8 rtl8225z2_tx_power_cck_ch14[]={
-	0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00
+static const u8 rtl8225_tx_power_cck[] = {
+	0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
+	0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
+	0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
+	0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
+	0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
+	0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
 };
 
+static const u8 rtl8225_tx_power_cck_ch14[] = {
+	0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
+	0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
+	0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
+	0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
+	0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
+	0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
+};
 
-//-
-u8 rtl8225z2_tx_power_cck[]={
-	0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04
+static const u8 rtl8225_tx_power_ofdm[] = {
+	0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
 };
 
+static const u32 rtl8225_chan[] = {
+	0,
+	0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
+	0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A,
+};
 
-void rtl8225z2_set_gain(struct net_device *dev, short gain)
+static void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
 {
-	u8* rtl8225_gain;
 	struct r8180_priv *priv = ieee80211_priv(dev);
+	int GainIdx;
+	int GainSetting;
+	int i;
+	u8 power;
+	const u8 *cck_power_table;
+	u8 max_cck_power_level;
+	u8 max_ofdm_power_level;
+	u8 min_ofdm_power_level;
+	u8 cck_power_level = 0xff & priv->chtxpwr[ch];
+	u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
+
+	if (priv->card_type == USB) {
+		max_cck_power_level = 11;
+		max_ofdm_power_level = 25;
+		min_ofdm_power_level = 10;
+	} else {
+		max_cck_power_level = 35;
+		max_ofdm_power_level = 35;
+		min_ofdm_power_level = 0;
+	}
 
-	u8 mode = priv->ieee80211->mode;
+	if (cck_power_level > max_cck_power_level)
+		cck_power_level = max_cck_power_level;
 
-	if(mode == IEEE_B || mode == IEEE_G)
-		rtl8225_gain = rtl8225z2_gain_bg;
+	GainIdx = cck_power_level % 6;
+	GainSetting = cck_power_level / 6;
+
+	if (ch == 14)
+		cck_power_table = rtl8225_tx_power_cck_ch14;
 	else
-		rtl8225_gain = rtl8225z2_gain_a;
+		cck_power_table = rtl8225_tx_power_cck;
 
-	//write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]);
-	//write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]);
-	//write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]);
-        //2005.11.17, by ch-hsu
-        write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
-        write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
-        write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
-	write_phy_ofdm(dev, 0x21, 0x37);
+	write_nic_byte(dev, TX_GAIN_CCK,
+		       rtl8225_tx_gain_cck_ofdm[GainSetting] >> 1);
+
+	for (i = 0; i < 8; i++) {
+		power = cck_power_table[GainIdx * 8 + i];
+		write_phy_cck(dev, 0x44 + i, power);
+	}
+
+	/* FIXME Is this delay really needeed ? */
+	force_pci_posting(dev);
+	mdelay(1);
+
+	if (ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
+		ofdm_power_level = max_ofdm_power_level;
+	else
+		ofdm_power_level += min_ofdm_power_level;
 
+	if (ofdm_power_level > 35)
+		ofdm_power_level = 35;
+
+	GainIdx = ofdm_power_level % 6;
+	GainSetting = ofdm_power_level / 6;
+
+	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
+
+	write_phy_ofdm(dev, 2, 0x42);
+	write_phy_ofdm(dev, 6, 0x00);
+	write_phy_ofdm(dev, 8, 0x00);
+
+	write_nic_byte(dev, TX_GAIN_OFDM,
+		       rtl8225_tx_gain_cck_ofdm[GainSetting] >> 1);
+
+	power = rtl8225_tx_power_ofdm[GainIdx];
+
+	write_phy_ofdm(dev, 5, power);
+	write_phy_ofdm(dev, 7, power);
+
+	force_pci_posting(dev);
+	mdelay(1);
 }
 
-#if 0
+static const u8 rtl8225z2_threshold[] = {
+        0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
+};
 
-void rtl8225_set_gain(struct net_device *dev, short gain)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
+static const u8 rtl8225z2_gain_bg[] = {
+	0x23, 0x15, 0xa5, /* -82-1dBm */
+	0x23, 0x15, 0xb5, /* -82-2dBm */
+	0x23, 0x15, 0xc5, /* -82-3dBm */
+	0x33, 0x15, 0xc5, /* -78dBm */
+	0x43, 0x15, 0xc5, /* -74dBm */
+	0x53, 0x15, 0xc5, /* -70dBm */
+	0x63, 0x15, 0xc5, /* -66dBm */
+};
 
-	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
+static const u8 rtl8225z2_gain_a[] = {
+	0x13, 0x27, 0x5a, /* -82dBm */
+	0x23, 0x23, 0x58, /* -82dBm */
+	0x33, 0x1f, 0x56, /* -82dBm */
+	0x43, 0x1b, 0x54, /* -78dBm */
+	0x53, 0x17, 0x51, /* -74dBm */
+	0x63, 0x24, 0x4f, /* -70dBm */
+	0x73, 0x0f, 0x4c, /* -66dBm */
+};
 
-	if(priv->card_8185 == 2)
-		write_phy_ofdm(dev, 0x21, 0x27);
-	else
-		write_phy_ofdm(dev, 0x21, 0x37);
+static const u16 rtl8225z2_rxgain[] = {
+	0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+	0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+	0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+	0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+	0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+	0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+	0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+	0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+	0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+	0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+	0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
+	0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
 
-	write_phy_ofdm(dev, 0x25, 0x20);
-	write_phy_ofdm(dev, 0x11, 0x6);
+};
+
+static const u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[] = {
+	0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+	0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+	0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+	0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+	0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
+};
+
+static const u8 rtl8225z2_tx_power_ofdm[] = {
+	0x42, 0x00, 0x40, 0x00, 0x40
+};
+
+static const u8 rtl8225z2_tx_power_cck_ch14[] = {
+	0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+};
 
-	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-		write_phy_ofdm(dev, 0x27, 0x8);
+static const u8 rtl8225z2_tx_power_cck[] = {
+	0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+};
+
+void rtl8225z2_set_gain(struct net_device *dev, short gain)
+{
+	const u8 *rtl8225_gain;
+	struct r8180_priv *priv = ieee80211_priv(dev);
+	u8 mode = priv->ieee80211->mode;
+
+	if (mode == IEEE_B || mode == IEEE_G)
+		rtl8225_gain = rtl8225z2_gain_bg;
 	else
-		write_phy_ofdm(dev, 0x27, 0x88);
-
-	write_phy_ofdm(dev, 0x14, 0);
-	write_phy_ofdm(dev, 0x16, 0);
-	write_phy_ofdm(dev, 0x15, 0x40);
-	write_phy_ofdm(dev, 0x17, 0x40);
-
-	write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
-	write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
-	write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
-	write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
-	//rtl8225_set_gain_usb(dev, gain);
+		rtl8225_gain = rtl8225z2_gain_a;
+
+	write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
+	write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
+	write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
+	write_phy_ofdm(dev, 0x21, 0x37);
 }
-#endif
 
-u32 read_rtl8225(struct net_device *dev, u8 adr)
+static u32 read_rtl8225(struct net_device *dev, u8 adr)
 {
 	u32 data2Write = ((u32)(adr & 0x1f)) << 27;
 	u32 dataRead;
 	u32 mask;
 	u16 oval,oval2,oval3,tmp;
-//	ThreeWireReg twreg;
-//	ThreeWireReg tdata;
 	int i;
 	short bit, rw;
-
 	u8 wLength = 6;
 	u8 rLength = 12;
 	u8 low2high = 0;
@@ -225,8 +344,8 @@ u32 read_rtl8225(struct net_device *dev, u8 adr)
 	rw = 0;
 
 	mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
-	for(i = 0; i < wLength/2; i++)
-	{
+
+	for (i = 0; i < wLength/2; i++) {
 		bit = ((data2Write&mask) != 0) ? 1 : 0;
 		write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
 
@@ -235,8 +354,7 @@ u32 read_rtl8225(struct net_device *dev, u8 adr)
 
 		mask = (low2high) ? (mask<<1): (mask>>1);
 
-		if(i == 2)
-		{
+		if (i == 2) {
 			rw = BB_HOST_BANG_RW;
 			write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
 			write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2);
@@ -253,17 +371,16 @@ u32 read_rtl8225(struct net_device *dev, u8 adr)
 		mask = (low2high) ? (mask<<1) : (mask>>1);
 	}
 
-	//twreg.struc.clk = 0;
-	//twreg.struc.data = 0;
 	write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2);
 	mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
 
-	// We must set data pin to HW controled, otherwise RF can't driver it and
-	// value RF register won't be able to read back properly. 2006.06.13, by rcnjko.
+	/*
+	 * We must set data pin to HW controled, otherwise RF can't driver it
+	 * and value RF register won't be able to read back properly.
+	 */
 	write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01)));
 
-	for(i = 0; i < rLength; i++)
-	{
+	for (i = 0; i < rLength; i++) {
 		write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
 
 		write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
@@ -281,144 +398,27 @@ u32 read_rtl8225(struct net_device *dev, u8 adr)
 	write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
 
 	write_nic_word(dev, RFPinsEnable, oval2);
-	write_nic_word(dev, RFPinsSelect, oval3);   // Set To SW Switch
+	write_nic_word(dev, RFPinsSelect, oval3); /* Set To SW Switch */
 	write_nic_word(dev, RFPinsOutput, 0x3a0);
 
 	return dataRead;
-
-}
-#if 0
-void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
-{
-	int i;
-	u16 out,select;
-	u8 bit;
-	u32 bangdata = (data << 4) | (adr & 0xf);
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
-
-	write_nic_word(dev,RFPinsEnable,
-		(read_nic_word(dev,RFPinsEnable) | 0x7));
-
-	select = read_nic_word(dev, RFPinsSelect);
-
-	write_nic_word(dev, RFPinsSelect, select | 0x7 |
-		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
-
-	force_pci_posting(dev);
-	udelay(2);
-
-	write_nic_word(dev, RFPinsOutput, out);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-
-	for(i=15; i>=0;i--){
-
-		bit = (bangdata & (1<<i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out);
-
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
-		i--;
-		bit = (bangdata & (1<<i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
-		write_nic_word(dev, RFPinsOutput, bit | out);
-
-	}
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out |
-		((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
-
-	write_nic_word(dev, RFPinsSelect, select |
-		((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
-
-	if(priv->card_type == USB)
-		mdelay(2);
-	else
-		rtl8185_rf_pins_enable(dev);
 }
 
-#endif
 short rtl8225_is_V_z2(struct net_device *dev)
 {
 	short vz2 = 1;
-	//int i;
-	/* sw to reg pg 1 */
-	//write_rtl8225(dev, 0, 0x1b7);
-	//write_rtl8225(dev, 0, 0x0b7);
-
-	/* reg 8 pg 1 = 23*/
-	//printk(KERN_WARNING "RF Rigisters:\n");
-#if 0
-	for(i = 0; i <= 0xf; i++)
-		printk(KERN_WARNING "%08x,", read_rtl8225(dev, i));
-	//printk(KERN_WARNING "reg[9]@pg1 = 0x%x\n", read_rtl8225(dev, 0x0F));
-
-//	printk(KERN_WARNING "RF:\n");
-#endif
-	if( read_rtl8225(dev, 8) != 0x588)
-		vz2 = 0;
 
+	if (read_rtl8225(dev, 8) != 0x588)
+		vz2 = 0;
 	else	/* reg 9 pg 1 = 24 */
-		if( read_rtl8225(dev, 9) != 0x700)
+		if (read_rtl8225(dev, 9) != 0x700)
 			vz2 = 0;
 
 	/* sw back to pg 0 */
 	write_rtl8225(dev, 0, 0xb7);
 
 	return vz2;
-
-}
-
-#if 0
-void rtl8225_rf_close(struct net_device *dev)
-{
-	write_rtl8225(dev, 0x4, 0x1f);
-
-	force_pci_posting(dev);
-	mdelay(1);
-
-	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
-	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
 }
-#endif
-#if 0
-short rtl8225_rf_set_sens(struct net_device *dev, short sens)
-{
-	if (sens <0 || sens > 6) return -1;
-
-	if(sens > 4)
-		write_rtl8225(dev, 0x0c, 0x850);
-	else
-		write_rtl8225(dev, 0x0c, 0x50);
-
-	sens= 6-sens;
-	rtl8225_set_gain(dev, sens);
-
-	write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
-	return 0;
-
-}
-#endif
-
 
 void rtl8225z2_rf_close(struct net_device *dev)
 {
@@ -431,70 +431,55 @@ void rtl8225z2_rf_close(struct net_device *dev)
 	rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF);
 }
 
-#ifdef ENABLE_DOT11D
-//
-//	Description:
-//		Map dBm into Tx power index according to
-//		current HW model, for example, RF and PA, and
-//		current wireless mode.
-//
-s8
-DbmToTxPwrIdx(
-	struct r8180_priv *priv,
-	WIRELESS_MODE	WirelessMode,
-	s32			PowerInDbm
-	)
+/*
+ * Map dBm into Tx power index according to current HW model, for example,
+ * RF and PA, and current wireless mode.
+ */
+s8 DbmToTxPwrIdx(struct r8180_priv *priv, WIRELESS_MODE WirelessMode,
+		 s32 PowerInDbm)
 {
  	bool bUseDefault = true;
 	s8 TxPwrIdx = 0;
 
-#ifdef CONFIG_RTL818X_S
-	//
-	// 071011, SD3 SY:
-	// OFDM Power in dBm = Index * 0.5 + 0
-	// CCK Power in dBm = Index * 0.25 + 13
-	//
-	if(priv->card_8185 >= VERSION_8187S_B)
-	{
+	/*
+	 * OFDM Power in dBm = Index * 0.5 + 0
+	 * CCK Power in dBm = Index * 0.25 + 13
+	 */
+	if (priv->card_8185 >= VERSION_8187S_B) {
 		s32 tmp = 0;
 
-		if(WirelessMode == WIRELESS_MODE_G)
-		{
+		if (WirelessMode == WIRELESS_MODE_G) {
 			bUseDefault = false;
 			tmp = (2 * PowerInDbm);
 
-			if(tmp < 0)
+			if (tmp < 0)
 				TxPwrIdx = 0;
-			else if(tmp > 40) // 40 means 20 dBm.
+			else if (tmp > 40) /* 40 means 20 dBm. */
 				TxPwrIdx = 40;
 			else
 				TxPwrIdx = (s8)tmp;
-		}
-		else if(WirelessMode == WIRELESS_MODE_B)
-		{
+		} else if (WirelessMode == WIRELESS_MODE_B) {
 			bUseDefault = false;
 			tmp = (4 * PowerInDbm) - 52;
 
 			if(tmp < 0)
 				TxPwrIdx = 0;
-			else if(tmp > 28) // 28 means 20 dBm.
+			else if (tmp > 28) /* 28 means 20 dBm. */
 				TxPwrIdx = 28;
 			else
 				TxPwrIdx = (s8)tmp;
 		}
 	}
-#endif
-
-	//
-	// TRUE if we want to use a default implementation.
-	// We shall set it to FALSE when we have exact translation formular
-	// for target IC. 070622, by rcnjko.
-	//
-	if(bUseDefault)
-	{
-		if(PowerInDbm < 0)
+
+	/*
+	 * TRUE if we want to use a default implementation.
+	 * We shall set it to FALSE when we have exact translation formular
+	 * for target IC. 070622, by rcnjko.
+	 */
+	if (bUseDefault) {
+		if (PowerInDbm < 0)
 			TxPwrIdx = 0;
-		else if(PowerInDbm > 35)
+		else if (PowerInDbm > 35)
 			TxPwrIdx = 35;
 		else
 			TxPwrIdx = (u8)PowerInDbm;
@@ -502,302 +487,140 @@ DbmToTxPwrIdx(
 
 	return TxPwrIdx;
 }
-#endif
 
 void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
-
-//	int GainIdx;
-//	int GainSetting;
-	//int i;
-	//u8 power;
-	//u8 *cck_power_table;
 	u8 max_cck_power_level;
-	//u8 min_cck_power_level;
 	u8 max_ofdm_power_level;
 	u8 min_ofdm_power_level;
-//	u8 cck_power_level = 0xff & priv->chtxpwr[ch];//-by amy 080312
-//	u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];//-by amy 080312
-	char cck_power_level = (char)(0xff & priv->chtxpwr[ch]);//+by amy 080312
-	char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]);//+by amy 080312
-#if 0
-	//
-	// CCX 2 S31, AP control of client transmit power:
-	// 1. We shall not exceed Cell Power Limit as possible as we can.
-	// 2. Tolerance is +/- 5dB.
-	// 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit.
-	//
-	// TODO:
-	// 1. 802.11h power contraint
-	//
-	// 071011, by rcnjko.
-	//
-	if(	priv->OpMode == RT_OP_MODE_INFRASTRUCTURE &&
-		priv->bWithCcxCellPwr &&
-		ch == priv->dot11CurrentChannelNumber)
-	{
-		u8 CckCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_B, pMgntInfo->CcxCellPwr);
-		u8 OfdmCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_G, pMgntInfo->CcxCellPwr);
-
-		printk("CCX Cell Limit: %d dBm => CCK Tx power index : %d, OFDM Tx power index: %d\n",
-			priv->CcxCellPwr, CckCellPwrIdx, OfdmCellPwrIdx);
-		printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
-			channel, CckTxPwrIdx, OfdmTxPwrIdx);
-
-		if(cck_power_level > CckCellPwrIdx)
-			cck_power_level = CckCellPwrIdx;
-		if(ofdm_power_level > OfdmCellPwrIdx)
-			ofdm_power_level = OfdmCellPwrIdx;
-
-		printk("Altered CCK Tx power index : %d, OFDM Tx power index: %d\n",
-			CckTxPwrIdx, OfdmTxPwrIdx);
-	}
-#endif
-#ifdef ENABLE_DOT11D
-	if(IS_DOT11D_ENABLE(priv->ieee80211) &&
-		IS_DOT11D_STATE_DONE(priv->ieee80211) )
-	{
-		//PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
+	char cck_power_level = (char)(0xff & priv->chtxpwr[ch]);
+	char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]);
+
+	if (IS_DOT11D_ENABLE(priv->ieee80211) &&
+	    IS_DOT11D_STATE_DONE(priv->ieee80211)) {
 		u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
 		u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
 		u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
 
-		//printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
-
-		//printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
-		//	ch, cck_power_level, ofdm_power_level);
-
-		if(cck_power_level > CckMaxPwrIdx)
+		if (cck_power_level > CckMaxPwrIdx)
 			cck_power_level = CckMaxPwrIdx;
-		if(ofdm_power_level > OfdmMaxPwrIdx)
+		if (ofdm_power_level > OfdmMaxPwrIdx)
 			ofdm_power_level = OfdmMaxPwrIdx;
 	}
 
-	//priv->CurrentCckTxPwrIdx = cck_power_level;
-	//priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
-#endif
-
 	max_cck_power_level = 15;
-	max_ofdm_power_level = 25; //  12 -> 25
+	max_ofdm_power_level = 25;
 	min_ofdm_power_level = 10;
 
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
-
-	if(cck_power_level > 35)
-	{
+	if (cck_power_level > 35)
 		cck_power_level = 35;
-	}
-	//
-	// Set up CCK TXAGC. suggested by SD3 SY.
-	//
-       write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]) );
-       //printk("CCK TX power is %x\n", (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]));
-       force_pci_posting(dev);
-	mdelay(1);
-#else
-
-	/* CCK power setting */
-	if(cck_power_level > max_cck_power_level)
-		cck_power_level = max_cck_power_level;
-
-	cck_power_level += priv->cck_txpwr_base;
-
-	if(cck_power_level > 35)
-		cck_power_level = 35;
-
-	if(ch == 14)
-		cck_power_table = rtl8225z2_tx_power_cck_ch14;
-	else
-		cck_power_table = rtl8225z2_tx_power_cck;
-
-
-	for(i=0;i<8;i++){
-
-		power = cck_power_table[i];
-		write_phy_cck(dev, 0x44 + i, power);
-	}
-
-	//write_nic_byte(dev, TX_GAIN_CCK, power);
-	//2005.11.17,
-	write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]);
 
+	write_nic_byte(dev, CCK_TXAGC,
+		       (ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]));
 	force_pci_posting(dev);
 	mdelay(1);
-#endif
-#endif
-	/* OFDM power setting */
-//  Old:
-//	if(ofdm_power_level > max_ofdm_power_level)
-//		ofdm_power_level = 35;
-//	ofdm_power_level += min_ofdm_power_level;
-//  Latest:
-/*	if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
-		ofdm_power_level = max_ofdm_power_level;
-	else
-		ofdm_power_level += min_ofdm_power_level;
 
-	ofdm_power_level += priv->ofdm_txpwr_base;
-*/
-	if(ofdm_power_level > 35)
+	if (ofdm_power_level > 35)
 		ofdm_power_level = 35;
 
-//	rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
-
-	//rtl8185_set_anaparam2(dev, ANAPARM2_ASIC_ON);
-
 	if (priv->up == 0) {
-		//must add these for rtl8185B down, xiong-2006-11-21
-		write_phy_ofdm(dev,2,0x42);
-		write_phy_ofdm(dev,5,0);
-		write_phy_ofdm(dev,6,0x40);
-		write_phy_ofdm(dev,7,0);
-		write_phy_ofdm(dev,8,0x40);
+		write_phy_ofdm(dev, 2, 0x42);
+		write_phy_ofdm(dev, 5, 0x00);
+		write_phy_ofdm(dev, 6, 0x40);
+		write_phy_ofdm(dev, 7, 0x00);
+		write_phy_ofdm(dev, 8, 0x40);
 	}
 
-	//write_nic_byte(dev, TX_GAIN_OFDM, ofdm_power_level);
-	//2005.11.17,
-#ifdef CONFIG_RTL818X_S
-        write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]);
-#else
-        write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]*2);
-#endif
-        if(ofdm_power_level<=11)
-        {
-//            write_nic_dword(dev,PHY_ADR,0x00005c87);
-//            write_nic_dword(dev,PHY_ADR,0x00005c89);
-		write_phy_ofdm(dev,0x07,0x5c);
-		write_phy_ofdm(dev,0x09,0x5c);
-        }
-	if(ofdm_power_level<=17)
-        {
-//             write_nic_dword(dev,PHY_ADR,0x00005487);
-//             write_nic_dword(dev,PHY_ADR,0x00005489);
-		write_phy_ofdm(dev,0x07,0x54);
-		write_phy_ofdm(dev,0x09,0x54);
-        }
-        else
-        {
-//             write_nic_dword(dev,PHY_ADR,0x00005087);
-//             write_nic_dword(dev,PHY_ADR,0x00005089);
-		write_phy_ofdm(dev,0x07,0x50);
-		write_phy_ofdm(dev,0x09,0x50);
+	write_nic_byte(dev, OFDM_TXAGC,
+		       ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]);
+
+	if (ofdm_power_level <= 11) {
+		write_phy_ofdm(dev, 0x07, 0x5c);
+		write_phy_ofdm(dev, 0x09, 0x5c);
         }
+
+	if (ofdm_power_level <= 17) {
+		write_phy_ofdm(dev, 0x07, 0x54);
+		write_phy_ofdm(dev, 0x09, 0x54);
+	} else {
+		write_phy_ofdm(dev, 0x07, 0x50);
+		write_phy_ofdm(dev, 0x09, 0x50);
+	}
+
 	force_pci_posting(dev);
 	mdelay(1);
-
-}
-#if 0
-/* switch between mode B and G */
-void rtl8225_set_mode(struct net_device *dev, short modeb)
-{
-	write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
-	write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
 }
-#endif
 
 void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
 {
-/*
-	short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
-		ieee80211_is_54g(priv->ieee80211->current_network)) ||
-		priv->ieee80211->iw_mode == IW_MODE_MONITOR;
-*/
 	rtl8225z2_SetTXPowerLevel(dev, ch);
 
 	RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
 
-	//YJ,add,080828, if set channel failed, write again
-	if((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
-	{
+	if ((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
 		RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
-	}
 
 	mdelay(1);
 
 	force_pci_posting(dev);
 	mdelay(10);
-//deleted by David : 2006/8/9
-#if 0
-	write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
-
-	if(gset)
-		write_nic_byte(dev,DIFS,20); //DIFS: 20
-	else
-		write_nic_byte(dev,DIFS,0x24); //DIFS: 36
-
-	if(priv->ieee80211->state == IEEE80211_LINKED &&
-		ieee80211_is_shortslot(priv->ieee80211->current_network))
-		write_nic_byte(dev,SLOT,0x9); //SLOT: 9
-
-	else
-		write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
-
-
-	if(gset){
-		write_nic_byte(dev,EIFS,91 - 20); // EIFS: 91 (0x5B)
-		write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
-		//DMESG("using G net params");
-	}else{
-		write_nic_byte(dev,EIFS,91 - 0x24); // EIFS: 91 (0x5B)
-		write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
-		//DMESG("using B net params");
-	}
-#endif
-
 }
-#if 0
-void rtl8225_host_pci_init(struct net_device *dev)
+
+static void rtl8225_host_pci_init(struct net_device *dev)
 {
 	write_nic_word(dev, RFPinsOutput, 0x480);
 
 	rtl8185_rf_pins_enable(dev);
 
-	//if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
-	//write_nic_word(dev, RFPinsSelect, 0x88);
-	//else
-	write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
+	write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO);
 
 	write_nic_byte(dev, GP_ENABLE, 0);
 
 	force_pci_posting(dev);
 	mdelay(200);
 
-	write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
-
-
+	/* bit 6 is for RF on/off detection */
+	write_nic_word(dev, GP_ENABLE, 0xff & (~(1 << 6)));
 }
 
-void rtl8225_host_usb_init(struct net_device *dev)
+static void rtl8225_rf_set_chan(struct net_device *dev, short ch)
 {
-	write_nic_byte(dev,RFPinsSelect+1,0);
-
-	write_nic_byte(dev,GPIO,0);
-
-	write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
-
-	write_nic_byte(dev,RFPinsSelect+1,4);
-
-	write_nic_byte(dev,GPIO,0x20);
-
-	write_nic_byte(dev,GP_ENABLE,0);
-
-
-	/* Config BB & RF */
-	write_nic_word(dev, RFPinsOutput, 0x80);
-
-	write_nic_word(dev, RFPinsSelect, 0x80);
+	struct r8180_priv *priv = ieee80211_priv(dev);
+	short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
+		ieee80211_is_54g(priv->ieee80211->current_network)) ||
+		priv->ieee80211->iw_mode == IW_MODE_MONITOR;
 
-	write_nic_word(dev, RFPinsEnable, 0x80);
+	rtl8225_SetTXPowerLevel(dev, ch);
 
+	write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
 
-	mdelay(100);
+	force_pci_posting(dev);
+	mdelay(10);
 
-	mdelay(1000);
+	if (gset) {
+		write_nic_byte(dev, SIFS, 0x22);
+		write_nic_byte(dev, DIFS, 0x14);
+	} else {
+		write_nic_byte(dev, SIFS, 0x44);
+		write_nic_byte(dev, DIFS, 0x24);
+	}
 
+	if (priv->ieee80211->state == IEEE80211_LINKED &&
+	    ieee80211_is_shortslot(priv->ieee80211->current_network))
+		write_nic_byte(dev, SLOT, 0x9);
+	else
+		write_nic_byte(dev, SLOT, 0x14);
+
+	if (gset) {
+		write_nic_byte(dev, EIFS, 81);
+		write_nic_byte(dev, CW_VAL, 0x73);
+	} else {
+		write_nic_byte(dev, EIFS, 81);
+		write_nic_byte(dev, CW_VAL, 0xa5);
+	}
 }
-#endif
+
 void rtl8225z2_rf_init(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
@@ -808,12 +631,7 @@ void rtl8225z2_rf_init(struct net_device *dev)
 
 	priv->chan = channel;
 
-//	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-
-
-	if(priv->card_type == USB)
-		rtl8225_host_usb_init(dev);
-	else
+	if (priv->card_type != USB)
 		rtl8225_host_pci_init(dev);
 
 	write_nic_dword(dev, RF_TIMING, 0x000a8008);
@@ -822,80 +640,40 @@ void rtl8225z2_rf_init(struct net_device *dev)
 
 	write_nic_word(dev, BRSR, 0xffff);
 
-
 	write_nic_dword(dev, RF_PARA, 0x100044);
 
-	#if 1  //0->1
 	rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
 	write_nic_byte(dev, CONFIG3, 0x44);
 	rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-	#endif
-
 
 	rtl8185_rf_pins_enable(dev);
 
-//		mdelay(1000);
-
 	write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
-
-
 	write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
-
 	write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
-
 	write_rtl8225(dev, 0x3, 0x441); mdelay(1);
-
-
-	write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
-
-
-
-	write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
-//	}
-
+	write_rtl8225(dev, 0x4, 0x8c3); mdelay(1);
+	write_rtl8225(dev, 0x5, 0xc72); mdelay(1);
 	write_rtl8225(dev, 0x6, 0xe6);  mdelay(1);
-
 	write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel]));  mdelay(1);
-
 	write_rtl8225(dev, 0x8, 0x3f);  mdelay(1);
-
-	write_rtl8225(dev, 0x9, 0x335);  mdelay(1);
-
-	write_rtl8225(dev, 0xa, 0x9d4);  mdelay(1);
-
-	write_rtl8225(dev, 0xb, 0x7bb);  mdelay(1);
-
-	write_rtl8225(dev, 0xc, 0x850);  mdelay(1);
-
-
-	write_rtl8225(dev, 0xd, 0xcdf);   mdelay(1);
-
+	write_rtl8225(dev, 0x9, 0x335); mdelay(1);
+	write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
+	write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
+	write_rtl8225(dev, 0xc, 0x850); mdelay(1);
+	write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
 	write_rtl8225(dev, 0xe, 0x2b);  mdelay(1);
-
 	write_rtl8225(dev, 0xf, 0x114);
 
-
 	mdelay(100);
 
-
-	//if(priv->card_type != USB) /* maybe not needed even for 8185 */
-//	write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
-
 	write_rtl8225(dev, 0x0, 0x1b7);
 
-	for(i=0;i<95;i++){
-		write_rtl8225(dev, 0x1, (u8)(i+1));
-
-		#if 0
-		if(priv->phy_ver == 1)
-			/* version A */
-			write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
-		else
-		#endif
-		/* version B & C & D*/
-
+	for (i = 0; i < 95; i++) {
+		write_rtl8225(dev, 0x1, (u8)(i + 1));
 		write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
 	}
+
 	write_rtl8225(dev, 0x3, 0x80);
 	write_rtl8225(dev, 0x5, 0x4);
 
@@ -903,185 +681,90 @@ void rtl8225z2_rf_init(struct net_device *dev)
 
 	write_rtl8225(dev, 0x2, 0xc4d);
 
-	if(priv->card_type == USB){
-	//	force_pci_posting(dev);
+	if (priv->card_type == USB) {
 		mdelay(200);
 
 		write_rtl8225(dev, 0x2, 0x44d);
-
-	//	force_pci_posting(dev);
 		mdelay(100);
+	}
 
-	}//End of if(priv->card_type == USB)
 	/* FIXME!! rtl8187 we have to check if calibrarion
 	 * is successful and eventually cal. again (repeat
 	 * the two write on reg 2)
-	*/
-	// Check for calibration status, 2005.11.17,
-        data = read_rtl8225(dev, 6);
-        if (!(data&0x00000080))
-        {
-                write_rtl8225(dev, 0x02, 0x0c4d);
-                force_pci_posting(dev); mdelay(200);
-                write_rtl8225(dev, 0x02, 0x044d);
-                force_pci_posting(dev); mdelay(100);
-                data = read_rtl8225(dev, 6);
-                if (!(data&0x00000080))
-                        {
-                                DMESGW("RF Calibration Failed!!!!\n");
-                        }
-        }
-	//force_pci_posting(dev);
-
-	mdelay(200); //200 for 8187
-
+	 */
+	data = read_rtl8225(dev, 6);
+	if (!(data & 0x00000080)) {
+		write_rtl8225(dev, 0x02, 0x0c4d);
+		force_pci_posting(dev); mdelay(200);
+		write_rtl8225(dev, 0x02, 0x044d);
+		force_pci_posting(dev); mdelay(100);
+		data = read_rtl8225(dev, 6);
+		if (!(data & 0x00000080))
+			DMESGW("RF Calibration Failed!!!!\n");
+	}
 
-//	//if(priv->card_type != USB){
-//		write_rtl8225(dev, 0x2, 0x44d);
-//		write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
-//		write_rtl8225(dev, 0x2, 0x47d);
-//
-//		force_pci_posting(dev);
-//		mdelay(100);
-//
-//		write_rtl8225(dev, 0x2, 0x44d);
-//	//}
+	mdelay(200);
 
 	write_rtl8225(dev, 0x0, 0x2bf);
 
-	if(priv->card_type != USB)
+	if (priv->card_type != USB)
 		rtl8185_rf_pins_enable(dev);
-	//set up ZEBRA AGC table, 2005.11.17,
-        for(i=0;i<128;i++){
-                data = rtl8225_agc[i];
-
-                addr = i + 0x80; //enable writing AGC table
-                write_phy_ofdm(dev, 0xb, data);
 
-                mdelay(1);
-                write_phy_ofdm(dev, 0xa, addr);
-
-                mdelay(1);
-        }
-#if 0
-	for(i=0;i<128;i++){
-		write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
+	for (i = 0; i < 128; i++) {
+		data = rtl8225_agc[i];
 
+		addr = i + 0x80; /* enable writing AGC table */
+		write_phy_ofdm(dev, 0xb, data);
 		mdelay(1);
-		write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
 
+		write_phy_ofdm(dev, 0xa, addr);
 		mdelay(1);
 	}
-#endif
 
 	force_pci_posting(dev);
 	mdelay(1);
 
-	write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
-	write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
-	write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
-	write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
-	write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
-
-	write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
-
-	//write_phy_ofdm(dev, 0x18, 0xef);
-	//	}
-	//}
-	write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
-
-	write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
-
-
-	//if(priv->card_type != USB)
-	write_phy_ofdm(dev, 0xd, 0x43);
-
-	write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
-
-
-	#if 0
-	if(priv->card_8185 == 1){
-		if(priv->card_8185_Bversion)
-			write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
-		else
-			write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
-	}else{
-	#endif
-	write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
-/*ver D & 8187*/
-//	}
-
-//	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-//		write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
-//	else
-	write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
-/*ver C & D & 8187*/
-
-	write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
-/*agc resp time 700*/
-
-
-//	if(priv->card_8185 == 2){
-	/* Ver D & 8187*/
-	write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
-
-	write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
-
-#if 0
-	}else{
-		/* Ver B & C*/
-		write_phy_ofdm(dev, 0x12, 0x0);
-		write_phy_ofdm(dev, 0x13, 0x0);
-	}
-#endif
-	write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
+	write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
+	write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
+	write_phy_ofdm(dev, 0x02, ((priv->card_type == USB) ? 0x42 : 0x62)); mdelay(1);
+	write_phy_ofdm(dev, 0x03, 0x00); mdelay(1);
+	write_phy_ofdm(dev, 0x04, 0x00); mdelay(1);
+	write_phy_ofdm(dev, 0x05, 0x00); mdelay(1);
+	write_phy_ofdm(dev, 0x06, 0x40); mdelay(1);
+	write_phy_ofdm(dev, 0x07, 0x00); mdelay(1);
+	write_phy_ofdm(dev, 0x08, 0x40); mdelay(1);
+	write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1);
+	write_phy_ofdm(dev, 0x0a, 0x08); mdelay(1);
+	write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1);
+	write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1);
+	write_phy_ofdm(dev, 0x0d, 0x43);
+	write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1);
+	write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1);
+	write_phy_ofdm(dev, 0x10, 0x84); mdelay(1);
+	write_phy_ofdm(dev, 0x11, 0x07); mdelay(1);
+	write_phy_ofdm(dev, 0x12, 0x20); mdelay(1);
+	write_phy_ofdm(dev, 0x13, 0x20); mdelay(1);
+	write_phy_ofdm(dev, 0x14, 0x00); mdelay(1);
 	write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
-	write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
+	write_phy_ofdm(dev, 0x16, 0x00); mdelay(1);
 	write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
-
-//	if (priv->card_type == USB)
-//		write_phy_ofdm(dev, 0x18, 0xef);
-
-	write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
-
-
+	write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
 	write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
 	write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
-	write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1);
-
-	write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
-
-	write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
-
-	write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
-
-	write_phy_ofdm(dev, 0x1f, 0x75);	mdelay(1);
-
-//	}
-
-	write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
-
-	write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
-
-	write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
-
-//	if(priv->card_type != USB)
-	write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
-
+	write_phy_ofdm(dev, 0x1b, 0x15); mdelay(1);
+	write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1);
+	write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
+	write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1);
+	write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
+	write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1);
+	write_phy_ofdm(dev, 0x21, 0x17); mdelay(1);
+	write_phy_ofdm(dev, 0x22, 0x16); mdelay(1);
+	write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME maybe not needed */
 	write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
 	write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
 	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
-
 	write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
 
-
-	// <> Set init. gain to m74dBm.
-
 	rtl8225z2_set_gain(dev,4);
 
 	write_phy_cck(dev, 0x0, 0x98); mdelay(1);
@@ -1089,101 +772,57 @@ void rtl8225z2_rf_init(struct net_device *dev)
 	write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
 	write_phy_cck(dev, 0x5, 0x12); mdelay(1);
 	write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
-
-	write_phy_cck(dev, 0x7, 0x78);mdelay(1);
- /* Ver C & D & 8187*/
-
-	write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
-
+	write_phy_cck(dev, 0x7, 0x78); mdelay(1);
+	write_phy_cck(dev, 0x8, 0x2e); mdelay(1);
 	write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
 	write_phy_cck(dev, 0x11, 0x88); mdelay(1);
 	write_phy_cck(dev, 0x12, 0x47); mdelay(1);
-#if 0
-	if(priv->card_8185 == 1 && priv->card_8185_Bversion)
-		write_phy_cck(dev, 0x13, 0x98); /* Ver B */
-	else
-#endif
-	write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
-
-	write_phy_cck(dev, 0x19, 0x0);
+	write_phy_cck(dev, 0x13, 0xd0);
+	write_phy_cck(dev, 0x19, 0x00);
 	write_phy_cck(dev, 0x1a, 0xa0);
-	write_phy_cck(dev, 0x1b, 0x8);
+	write_phy_cck(dev, 0x1b, 0x08);
 	write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
-
-	write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
-
-
+	write_phy_cck(dev, 0x41, 0x8d); mdelay(1);
 	write_phy_cck(dev, 0x42, 0x15); mdelay(1);
 	write_phy_cck(dev, 0x43, 0x18); mdelay(1);
-
-
 	write_phy_cck(dev, 0x44, 0x36); mdelay(1);
 	write_phy_cck(dev, 0x45, 0x35); mdelay(1);
 	write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
 	write_phy_cck(dev, 0x47, 0x25); mdelay(1);
 	write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
 	write_phy_cck(dev, 0x49, 0x12); mdelay(1);
-	write_phy_cck(dev, 0x4a, 0x9); mdelay(1);
-	write_phy_cck(dev, 0x4b, 0x4); mdelay(1);
-	write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
-
+	write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
+	write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
+	write_phy_cck(dev, 0x4c, 0x05); mdelay(1);
 
 	write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
 
-
-
-// <>
-//	// TESTR 0xb 8187
-//	write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
-//
-//	//if(priv->card_type != USB){
-//		write_phy_ofdm(dev, 0x2, 0x62);
-//		write_phy_ofdm(dev, 0x6, 0x0);
-//		write_phy_ofdm(dev, 0x8, 0x0);
-//	//}
-
 	rtl8225z2_SetTXPowerLevel(dev, channel);
-#ifdef CONFIG_RTL818X_S
-        write_phy_cck(dev, 0x11, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
-#else
-	write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
-#endif
-	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
 
-	rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
+	/* RX antenna default to A */
+	write_phy_cck(dev, 0x11, 0x9b); mdelay(1);		/* B: 0xDB */
+	write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);		/* B: 0x10 */
+
+	rtl8185_tx_antenna(dev, 0x03);				/* B: 0x00 */
 
 	/* switch to high-speed 3-wire
 	 * last digit. 2 for both cck and ofdm
 	 */
-	if(priv->card_type == USB)
+	if (priv->card_type == USB)
 		write_nic_dword(dev, 0x94, 0x3dc00002);
-	else{
+	else {
 		write_nic_dword(dev, 0x94, 0x15c00002);
 		rtl8185_rf_pins_enable(dev);
 	}
 
-//	if(priv->card_type != USB)
-//	rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
-//	 rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
-//
-//	/* make sure is waken up! */
-//	write_rtl8225(dev,0x4, 0x9ff);
-//	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-//	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-
 	rtl8225_rf_set_chan(dev, priv->chan);
-
-	//write_nic_word(dev,BRSR,brsr);
-
-	//rtl8225z2_rf_set_mode(dev);
 }
 
 void rtl8225z2_rf_set_mode(struct net_device *dev)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 
-	if(priv->ieee80211->mode == IEEE_A)
-	{
+	if (priv->ieee80211->mode == IEEE_A) {
 		write_rtl8225(dev, 0x5, 0x1865);
 		write_nic_dword(dev, RF_PARA, 0x10084);
 		write_nic_dword(dev, RF_TIMING, 0xa8008);
@@ -1199,8 +838,7 @@ void rtl8225z2_rf_set_mode(struct net_device *dev)
 		write_phy_ofdm(dev,0x17, 0x40);
 
 		write_nic_dword(dev, 0x94,0x10000000);
-	}else{
-
+	} else {
 		write_rtl8225(dev, 0x5, 0x1864);
 		write_nic_dword(dev, RF_PARA, 0x10044);
 		write_nic_dword(dev, RF_TIMING, 0xa8008);
@@ -1219,46 +857,35 @@ void rtl8225z2_rf_set_mode(struct net_device *dev)
 	}
 }
 
-//lzm mod 080826
-//#define MAX_DOZE_WAITING_TIMES_85B 64
-//#define MAX_POLLING_24F_TIMES_87SE 	5
 #define MAX_DOZE_WAITING_TIMES_85B 		20
-#define MAX_POLLING_24F_TIMES_87SE 			10
+#define MAX_POLLING_24F_TIMES_87SE 		10
 #define LPS_MAX_SLEEP_WAITING_TIMES_87SE 	5
 
-bool
-SetZebraRFPowerState8185(
-	struct net_device *dev,
-	RT_RF_POWER_STATE	eRFPowerState
-	)
+bool SetZebraRFPowerState8185(struct net_device *dev,
+			      RT_RF_POWER_STATE eRFPowerState)
 {
 	struct r8180_priv *priv = ieee80211_priv(dev);
 	u8			btCR9346, btConfig3;
-	bool bActionAllowed= true, bTurnOffBB = true;//lzm mod 080826
-	//u32			DWordContent;
+	bool bActionAllowed = true, bTurnOffBB = true;
 	u8			u1bTmp;
 	int			i;
-	//u16			u2bTFPC = 0;
 	bool		bResult = true;
 	u8			QueueID;
 
-	if(priv->SetRFPowerStateInProgress == true)
+	if (priv->SetRFPowerStateInProgress == true)
 		return false;
 
 	priv->SetRFPowerStateInProgress = true;
 
-	// enable EEM0 and EEM1 in 9346CR
 	btCR9346 = read_nic_byte(dev, CR9346);
-	write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
-	// enable PARM_En in Config3
+	write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
+
 	btConfig3 = read_nic_byte(dev, CONFIG3);
-	write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
+	write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En));
 
-	switch( priv->rf_chip )
-	{
+	switch (priv->rf_chip) {
 	case RF_ZEBRA2:
-		switch( eRFPowerState )
-		{
+		switch (eRFPowerState) {
 		case eRfOn:
 			RF_WriteReg(dev,0x4,0x9FF);
 
@@ -1267,247 +894,168 @@ SetZebraRFPowerState8185(
 
 			write_nic_byte(dev, CONFIG4, priv->RFProgType);
 
-			//Follow 87B, Isaiah 2007-04-27
+			/* turn on CCK and OFDM */
 			u1bTmp = read_nic_byte(dev, 0x24E);
-			write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
+			write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
 			break;
-
 		case eRfSleep:
 			break;
-
 		case eRfOff:
 			break;
-
 		default:
 			bResult = false;
 			break;
 		}
 		break;
-
 	case RF_ZEBRA4:
-		switch( eRFPowerState )
-		{
+		switch (eRFPowerState) {
 		case eRfOn:
-			//printk("===================================power on@jiffies:%d\n",jiffies);
 			write_nic_word(dev, 0x37C, 0x00EC);
 
-			//turn on AFE
+			/* turn on AFE */
 			write_nic_byte(dev, 0x54, 0x00);
 			write_nic_byte(dev, 0x62, 0x00);
 
-			//lzm mod 080826
-			//turn on RF
-			//RF_WriteReg(dev, 0x0, 0x009f); //mdelay(1);
-			//RF_WriteReg(dev, 0x4, 0x0972); //mdelay(1);
+			/* turn on RF */
 			RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
 			RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-			//turn on RF again, suggested by SD3 stevenl.
+
+			/* turn on RF again */
 			RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
 			RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
 
-			//turn on BB
-//			write_nic_dword(dev, PhyAddr, 0x4090); //ofdm 10=00
-//			write_nic_dword(dev, PhyAddr, 0x4092); //ofdm 12=00
+			/* turn on BB */
 			write_phy_ofdm(dev,0x10,0x40);
 			write_phy_ofdm(dev,0x12,0x40);
-			//Avoid power down at init time.
+
+			/* Avoid power down at init time. */
 			write_nic_byte(dev, CONFIG4, priv->RFProgType);
 
 			u1bTmp = read_nic_byte(dev, 0x24E);
-			write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );
-
+			write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
 			break;
-
 		case eRfSleep:
-			// Make sure BusyQueue is empty befor turn off RFE pwoer.
-			//printk("===================================power sleep@jiffies:%d\n",jiffies);
-
-			for(QueueID = 0, i = 0; QueueID < 6; )
-			{
-				if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
-				{
+			for (QueueID = 0, i = 0; QueueID < 6;) {
+				if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
 					QueueID++;
 					continue;
-				}
-#if 0		//reserved amy
-				else if(priv->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
-				{
-					RT_TRACE(COMP_POWER, DBG_LOUD, ("eRfSleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", (pMgntInfo->TxPollingTimes+1), QueueID));
-					break;
-				}
-#endif
-				else//lzm mod 080826
-				{
+				} else {
 					priv->TxPollingTimes ++;
-					if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
-						{
-							//RT_TRACE(COMP_POWER, DBG_WARNING, ("\n\n\n SetZebraRFPowerState8185B():eRfSleep:  %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", LPS_MAX_SLEEP_WAITING_TIMES_87SE, QueueID));
-							bActionAllowed=false;
-							break;
-						}
-						else
-						{
-							udelay(10);  // Windows may delay 3~16ms actually.
-							//RT_TRACE(COMP_POWER, DBG_LOUD, ("eRfSleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (pMgntInfo->TxPollingTimes), QueueID));
-						}
+					if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
+						bActionAllowed = false;
+						break;
+					} else
+						udelay(10);
 				}
-
-				//lzm del 080826
-				//if(i >= MAX_DOZE_WAITING_TIMES_85B)
-				//{
-					//printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
-					//break;
-				//}
 			}
 
-			if(bActionAllowed)//lzm add 080826
-			{
-				//turn off BB RXIQ matrix to cut off rx signal
-//				write_nic_dword(dev, PhyAddr, 0x0090); //ofdm 10=00
-//				write_nic_dword(dev, PhyAddr, 0x0092); //ofdm 12=00
-				write_phy_ofdm(dev,0x10,0x00);
-				write_phy_ofdm(dev,0x12,0x00);
-				//turn off RF
-				RF_WriteReg(dev, 0x4, 0x0000); //mdelay(1);
-				RF_WriteReg(dev, 0x0, 0x0000); //mdelay(1);
-				//turn off AFE except PLL
+			if (bActionAllowed) {
+				/* turn off BB RXIQ matrix to cut off rx signal */
+				write_phy_ofdm(dev, 0x10, 0x00);
+				write_phy_ofdm(dev, 0x12, 0x00);
+
+				/* turn off RF */
+				RF_WriteReg(dev, 0x4, 0x0000);
+				RF_WriteReg(dev, 0x0, 0x0000);
+
+				/* turn off AFE except PLL */
 				write_nic_byte(dev, 0x62, 0xff);
 				write_nic_byte(dev, 0x54, 0xec);
-//				mdelay(10);
 
-#if 1
 				mdelay(1);
+
 				{
 					int i = 0;
-					while (true)
-					{
+					while (true) {
 						u8 tmp24F = read_nic_byte(dev, 0x24f);
-						if ((tmp24F == 0x01) || (tmp24F == 0x09))
-						{
+
+						if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
 							bTurnOffBB = true;
 							break;
-						}
-						else//lzm mod 080826
-						{
+						} else {
 							udelay(10);
 							i++;
 							priv->TxPollingTimes++;
 
-							if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
-							{
-								//RT_TRACE(COMP_POWER, DBG_WARNING, ("\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times Rx Mac0x24F=0x%x !!!\n\n\n", i, u1bTmp24F));
-								bTurnOffBB=false;
+							if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
+								bTurnOffBB = false;
 								break;
-							}
-							else
-							{
-								udelay(10);// Windows may delay 3~16ms actually.
-								//RT_TRACE(COMP_POWER, DBG_LOUD,("(%d)eRfSleep- u1bTmp24F= 0x%X\n", i, u1bTmp24F));
-
-							}
+							} else
+								udelay(10);
 						}
-
-						//lzm del 080826
-						//if (i > MAX_POLLING_24F_TIMES_87SE)
-						//	break;
 					}
 				}
-#endif
-				if (bTurnOffBB)//lzm mod 080826
-				{
-				//turn off BB
-				u1bTmp = read_nic_byte(dev, 0x24E);
-				write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));
 
-				//turn off AFE PLL
-				//write_nic_byte(dev, 0x54, 0xec);
-				//write_nic_word(dev, 0x37C, 0x00ec);
-				write_nic_byte(dev, 0x54, 0xFC);  //[ECS] FC-> EC->FC, asked by SD3 Stevenl
-				write_nic_word(dev, 0x37C, 0x00FC);//[ECS] FC-> EC->FC, asked by SD3 Stevenl
+				if (bTurnOffBB) {
+					/* turn off BB */
+					u1bTmp = read_nic_byte(dev, 0x24E);
+					write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
+
+					/* turn off AFE PLL */
+					write_nic_byte(dev, 0x54, 0xFC);
+					write_nic_word(dev, 0x37C, 0x00FC);
 				}
 			}
 			break;
-
 		case eRfOff:
-			// Make sure BusyQueue is empty befor turn off RFE pwoer.
-			//printk("===================================power off@jiffies:%d\n",jiffies);
-			for(QueueID = 0, i = 0; QueueID < 6; )
-			{
-				if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
-				{
+			for (QueueID = 0, i = 0; QueueID < 6;) {
+				if (get_curr_tx_free_desc(dev, QueueID) == priv->txringcount) {
 					QueueID++;
 					continue;
-				}
-#if 0
-				else if(Adapter->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
-				{
-					RT_TRACE(COMP_POWER, DBG_LOUD, ("%d times TcbBusyQueue[%d] !=0 but lower power state!\n", (i+1), QueueID));
-					break;
-				}
-#endif
-				else
-				{
+				} else {
 					udelay(10);
 					i++;
 				}
 
-				if(i >= MAX_DOZE_WAITING_TIMES_85B)
-				{
-					//printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
+				if (i >= MAX_DOZE_WAITING_TIMES_85B)
 					break;
-				}
 			}
 
-			//turn off BB RXIQ matrix to cut off rx signal
-//			write_nic_dword(dev, PhyAddr, 0x0090); //ofdm 10=00
-//			write_nic_dword(dev, PhyAddr, 0x0092); //ofdm 12=00
-			write_phy_ofdm(dev,0x10,0x00);
-			write_phy_ofdm(dev,0x12,0x00);
-			//turn off RF
-			RF_WriteReg(dev, 0x4, 0x0000); //mdelay(1);
-			RF_WriteReg(dev, 0x0, 0x0000); //mdelay(1);
-			//turn off AFE except PLL
+			/* turn off BB RXIQ matrix to cut off rx signal */
+			write_phy_ofdm(dev, 0x10, 0x00);
+			write_phy_ofdm(dev, 0x12, 0x00);
+
+			/* turn off RF */
+			RF_WriteReg(dev, 0x4, 0x0000);
+			RF_WriteReg(dev, 0x0, 0x0000);
+
+			/* turn off AFE except PLL */
 			write_nic_byte(dev, 0x62, 0xff);
 			write_nic_byte(dev, 0x54, 0xec);
-//			mdelay(10);
-#if 1
+
 			mdelay(1);
+
 			{
 				int i = 0;
+
 				while (true)
 				{
 					u8 tmp24F = read_nic_byte(dev, 0x24f);
-					if ((tmp24F == 0x01) || (tmp24F == 0x09))
-					{
+
+					if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
 						bTurnOffBB = true;
 						break;
-					}
-					else
-					{
+					} else {
 						bTurnOffBB = false;
 						udelay(10);
 						i++;
 					}
+
 					if (i > MAX_POLLING_24F_TIMES_87SE)
 						break;
 				}
 			}
-#endif
-			if (bTurnOffBB)//lzm mod 080826
-			{
 
-			//turn off BB
-			u1bTmp = read_nic_byte(dev, 0x24E);
-			write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));
-			//turn off AFE PLL (80M)
-			//write_nic_byte(dev, 0x54, 0xec);
-			//write_nic_word(dev, 0x37C, 0x00ec);
-			write_nic_byte(dev, 0x54, 0xFC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
-			write_nic_word(dev, 0x37C, 0x00FC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
-			}
+			if (bTurnOffBB) {
+				/* turn off BB */
+				u1bTmp = read_nic_byte(dev, 0x24E);
+				write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
 
+				/* turn off AFE PLL (80M) */
+				write_nic_byte(dev, 0x54, 0xFC);
+				write_nic_word(dev, 0x37C, 0x00FC);
+			}
 			break;
-
 		default:
 			bResult = false;
 			printk("SetZebraRFPowerState8185(): unknow state to set: 0x%X!!!\n", eRFPowerState);
@@ -1516,72 +1064,26 @@ SetZebraRFPowerState8185(
 		break;
 	}
 
-	// disable PARM_En in Config3
 	btConfig3 &= ~(CONFIG3_PARM_En);
 	write_nic_byte(dev, CONFIG3, btConfig3);
-	// disable EEM0 and EEM1 in 9346CR
+
 	btCR9346 &= ~(0xC0);
 	write_nic_byte(dev, CR9346, btCR9346);
 
-	if(bResult && bActionAllowed)//lzm mod 080826
-	{
-		// Update current RF state variable.
+	if (bResult && bActionAllowed)
 		priv->eRFPowerState = eRFPowerState;
-#if 0
-		switch(priv->eRFPowerState)
-		{
-		case eRfOff:
-			//
-			//If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
-			//
-			if(priv->RfOffReason==RF_CHANGE_BY_IPS )
-			{
-				Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
-			}
-			else
-			{
-				// Turn off LED if RF is not ON.
-				Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
-			}
-			break;
-
-		case eRfOn:
-			// Turn on RF we are still linked, which might happen when
-			// we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
-			if( pMgntInfo->bMediaConnect == TRUE )
-			{
-				Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
-			}
-			break;
-
-		default:
-			// do nothing.
-			break;
-		}
-#endif
-
-	}
 
 	priv->SetRFPowerStateInProgress = false;
 
-	return (bResult && bActionAllowed) ;
+	return bResult && bActionAllowed;
 }
+
 void rtl8225z4_rf_sleep(struct net_device *dev)
 {
-	//
-	// Turn off RF power.
-	//
-	//printk("=========>%s()\n", __func__);
 	MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
-	//mdelay(2);	//FIXME
 }
+
 void rtl8225z4_rf_wakeup(struct net_device *dev)
 {
-	//
-	// Turn on RF power.
-	//
-	//printk("=========>%s()\n", __func__);
 	MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
 }
-#endif
-
diff --git a/drivers/staging/rtl8187se/r8180_rtl8255.c b/drivers/staging/rtl8187se/r8180_rtl8255.c
deleted file mode 100644
index 1a62444..0000000
--- a/drivers/staging/rtl8187se/r8180_rtl8255.c
+++ /dev/null
@@ -1,1838 +0,0 @@
-/*
-  This is part of the rtl8180-sa2400 driver
-  released under the GPL (See file COPYING for details).
-  Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
-
-  This files contains programming code for the rtl8255
-  radio frontend.
-
-  *Many* thanks to Realtek Corp. for their great support!
-
-*/
-
-#define BAND_A 1
-#define BAND_BG 2
-
-#include "r8180.h"
-#include "r8180_hw.h"
-#include "r8180_rtl8255.h"
-
-u32 rtl8255_chan[] = {
-	0,	//dummy channel 0
-	0x13, //1
-	0x115, //2
-	0x217, //3
-	0x219, //4
-	0x31b, //5
-	0x41d, //6
-	0x41f, //7
-	0x621, //8
-	0x623, //9
-	0x625, //10
-	0x627, //11
-	0x829, //12
-	0x82b, //13
-	0x92f, // 14
-};
-
-static short rtl8255_gain_2G[]={
-	0x33, 0x17, 0x7c, 0xc5,//-78
-	0x43, 0x17, 0x7a, 0xc5,//-74
-	0x53, 0x17, 0x78, 0xc5,//-70
-	0x63, 0x17, 0x76, 0xc5,//-66
-};
-
-
-static short rtl8255_agc[]={
-	0x1, 0x1, 0x1, 0x1, 0x1,         0x1, 0x1, 0x1, 0x1, 0x1,
-
-	0x1, 0x1, 0x2, 0x2, 0x3,         0x3, 0x4, 0x4, 0x5, 0x5,
-	0x6, 0x6, 0x7, 0x7, 0x8,         0x8, 0x9, 0x9, 0xa, 0xa,
-	0xb, 0xb, 0xc, 0xc, 0xd,         0xd, 0xe, 0xe, 0xf, 0xf,
-
-	0x10, 0x10, 0x11, 0x11, 0x12,    0x12, 0x13, 0x13, 0x14, 0x14,
-	0x15, 0x15, 0x16, 0x16, 0x17,    0x17, 0x18, 0x18, 0x19, 0x19,
-	0x1a, 0x1a, 0x1b, 0x1b, 0x1c,    0x1c, 0x1d, 0x1d, 0x1e, 0x1e,
-	0x1f, 0x1f,
-
-	0x20, 0x20, 0x21, 0x21, 0x22,    0x22, 0x23, 0x23, 0x24, 0x24,
-	0x25, 0x25, 0x26, 0x26, 0x27,    0x27, 0x28, 0x28, 0x29, 0x29,
-	0x2a, 0x2a,
-
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a,    0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a,    0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a, 0x2a,    0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-	0x2a, 0x2a, 0x2a, 0x2a
-
-};
-
-void rtl8255_set_gain(struct net_device *dev, short gain)
-{
-
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	write_phy_ofdm(dev, 0x0d, rtl8255_gain_2G[gain * 4]);
-	write_phy_ofdm(dev, 0x23, rtl8255_gain_2G[gain * 4 + 1]);
-	write_phy_ofdm(dev, 0x1b, rtl8255_gain_2G[gain * 4 + 2]);
-	write_phy_ofdm(dev, 0x1d, rtl8255_gain_2G[gain * 4 + 3]);
-	//rtl8225_set_gain_usb(dev, gain);
-}
-
-void write_rtl8255_reg0c(struct net_device *dev, u32 d1, u32 d2, u32 d3, u32 d4,
-u32 d5, u32 d6, u32 d7, u32 d8, u32 d9, u32 d10)
-{
-	int i,j;
-	u16 out,select;
-	u8 bit;
-	u32 bangdata;
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	write_nic_word(dev,RFPinsEnable,
-		(read_nic_word(dev,RFPinsEnable) | 0x7));
-
-	select = read_nic_word(dev, RFPinsSelect);
-
-	write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
-
-	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
-
-	force_pci_posting(dev);
-	udelay(2);
-
-	write_nic_word(dev, RFPinsOutput, out);
-
-	force_pci_posting(dev);
-	udelay(2);
-
-	for(j=0;j<10;j++)
-	{
-		switch(j)
-		{
-			case 9:
-			bangdata = d10 | 0x0c;
-			break;
-			case 8:
-			bangdata = d9;
-			break;
-			case 7:
-			bangdata = d8;
-			break;
-			case 6:
-			bangdata = d7;
-			break;
-			case 5:
-			bangdata = d6;
-			break;
-			case 4:
-			bangdata = d5;
-			break;
-			case 3:
-			bangdata = d4;
-			break;
-			case 2:
-			bangdata = d3;
-			break;
-			case 1:
-			bangdata = d2;
-			break;
-			case 0:
-			bangdata = d1;
-			break;
-			default:
-			bangdata=0xbadc0de; /* avoid gcc complaints */
-			break;
-		}
-
-		for(i=31; i>=0;i--){
-
-			bit = (bangdata & (1<<i)) >> i;
-
-			write_nic_word(dev, RFPinsOutput, bit | out);
-			force_pci_posting(dev);
-			udelay(1);
-			write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-			force_pci_posting(dev);
-			udelay(1);
-		//	write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-			i--;
-			bit = (bangdata & (1<<i)) >> i;
-
-			write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-			force_pci_posting(dev);
-			udelay(1);
-		//	write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-			write_nic_word(dev, RFPinsOutput, bit | out);
-			force_pci_posting(dev);
-			udelay(1);
-		}
-	}
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-	force_pci_posting(dev);
-	udelay(10);
-
-//	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-	write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
-//	rtl8185_rf_pins_enable(dev);
-
-}
-
-void write_rtl8255(struct net_device *dev, u8 adr, u16 data)
-{
-	int i;
-	u16 out,select;
-	u8 bit;
-	u32 bangdata = (data << 4) | (adr & 0xf);
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
-
-	write_nic_word(dev,RFPinsEnable,
-		(read_nic_word(dev,RFPinsEnable) | 0x7));
-
-	select = read_nic_word(dev, RFPinsSelect);
-
-	write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
-
-	force_pci_posting(dev);
-	udelay(2);
-
-	write_nic_word(dev, RFPinsOutput, out);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-
-	for(i=15; i>=0;i--){
-
-		bit = (bangdata & (1<<i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		i--;
-		bit = (bangdata & (1<<i)) >> i;
-
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-		write_nic_word(dev, RFPinsOutput, bit | out);
-	}
-
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
-	force_pci_posting(dev);
-	udelay(10);
-
-	write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-	write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
-
-	rtl8185_rf_pins_enable(dev);
-}
-
-void rtl8255_rf_close(struct net_device *dev)
-{
-
-//	rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
-//	rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
-}
-
-void rtl8255_SetTXPowerLevel(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-
-	u8 cck_power_level = 0xff & priv->chtxpwr[ch];
-	u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
-	write_nic_byte(dev, TX_GAIN_OFDM, ofdm_power_level);
-	write_nic_byte(dev, TX_GAIN_CCK, cck_power_level);
-	force_pci_posting(dev);
-	mdelay(1);
-	//write_nic_byte(dev, TX_AGC_CONTROL,4);
-}
-#if 0
-/* switch between mode B and G */
-void rtl8255_set_mode(struct net_device *dev, short modeb)
-{
-	write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
-	write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
-}
-#endif
-
-void rtl8255_rf_set_chan(struct net_device *dev, short ch)
-{
-	//write_rtl8225(dev, 0x7, rtl8225_chan[1]);
-	write_rtl8255(dev, 0x5, 0x65);
-	write_rtl8255(dev, 0x6, rtl8255_chan[ch]);
-	write_rtl8255(dev, 0x7, 0x7c);
-	write_rtl8255(dev, 0x8, 0x6);
-
-
-	force_pci_posting(dev);
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(HZ);
-//	rtl8225_set_mode_B(dev);
-
-	rtl8255_SetTXPowerLevel(dev, ch);
-	/* FIXME FIXME FIXME */
-
-	#if 0
-	write_nic_byte(dev,DIFS,0xe); //DIFS
-	write_nic_byte(dev,SLOT,0x14); //SLOT
-	write_nic_byte(dev,EIFS,0x5b); // EIFS
-	//write_nic_byte(dev,0xbc,0); //CW CONFIG
-	write_nic_byte(dev,0xbd,0xa4); //CW VALUE
-	//write_nic_byte(dev,TX_AGC_CONTROL,4);
-	//write_nic_byte(dev, 0x9d,7);
-//Apr 20 13:25:03 localhost kernel: w8. 409d<-7  // CCK AGC
-	/*write_nic_word(dev,0x84,0x488);
-	write_nic_byte(dev,0x91,0x3e);
-	write_nic_byte(dev,0x90,0x30);
-	write_nic_word(dev,0x84,0x488);
-	write_nic_byte(dev,0x91,0x3e);
-	write_nic_byte(dev,0x90,0x20);
-	*/
-	//mdelay(100);
-	#endif
-}
-
-void rtl8255_init_BGband(struct net_device *dev)
-{
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804187cf, 0x40000027,
-		0x92402ac0, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc00);
-	write_rtl8255(dev, 0x4, 0xe00);
-	write_rtl8255(dev, 0x4, 0xc00);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x800);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa00);
-	write_rtl8255(dev, 0x4, 0x800);
-	write_rtl8255(dev, 0x4, 0x400);
-	write_rtl8255(dev, 0x3, 0x26);
-	write_rtl8255(dev, 0x2, 0x27);
-	write_rtl8255(dev, 0x4, 0x600);
-	write_rtl8255(dev, 0x4, 0x400);
-	write_rtl8255(dev, 0x4, 0x400);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x600);
-	write_rtl8255(dev, 0x4, 0x400);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804187ce, 0x80000027,
-		0x92402ac0, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc01);
-	write_rtl8255(dev, 0x4, 0xe01);
-	write_rtl8255(dev, 0x4, 0xc01);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x801);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa01);
-	write_rtl8255(dev, 0x4, 0x801);
-	write_rtl8255(dev, 0x4, 0x401);
-	write_rtl8255(dev, 0x3, 0x26);
-	write_rtl8255(dev, 0x2, 0x27);
-	write_rtl8255(dev, 0x4, 0x601);
-	write_rtl8255(dev, 0x4, 0x401);
-	write_rtl8255(dev, 0x4, 0x401);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x601);
-	write_rtl8255(dev, 0x4, 0x401);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418bdf, 0x40000027,
-		0x92402ac4, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc02);
-	write_rtl8255(dev, 0x4, 0xe02);
-	write_rtl8255(dev, 0x4, 0xc02);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x802);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa02);
-	write_rtl8255(dev, 0x4, 0x802);
-	write_rtl8255(dev, 0x4, 0x402);
-	write_rtl8255(dev, 0x3, 0x26);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x602);
-	write_rtl8255(dev, 0x4, 0x402);
-	write_rtl8255(dev, 0x4, 0x402);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x602);
-	write_rtl8255(dev, 0x4, 0x402);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418bbf, 0x40000027,
-		0x92402ac4, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc03);
-	write_rtl8255(dev, 0x4, 0xe03);
-	write_rtl8255(dev, 0x4, 0xc03);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x803);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa03);
-	write_rtl8255(dev, 0x4, 0x803);
-	write_rtl8255(dev, 0x4, 0x403);
-	write_rtl8255(dev, 0x3, 0x26);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x603);
-	write_rtl8255(dev, 0x4, 0x403);
-	write_rtl8255(dev, 0x4, 0x403);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x603);
-	write_rtl8255(dev, 0x4, 0x403);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418b9f, 0x40000027,
-		0x92402ac8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc04);
-	write_rtl8255(dev, 0x4, 0xe04);
-	write_rtl8255(dev, 0x4, 0xc04);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x804);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa04);
-	write_rtl8255(dev, 0x4, 0x804);
-	write_rtl8255(dev, 0x4, 0x404);
-	write_rtl8255(dev, 0x3, 0x26);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x604);
-	write_rtl8255(dev, 0x4, 0x404);
-	write_rtl8255(dev, 0x4, 0x404);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x604);
-	write_rtl8255(dev, 0x4, 0x404);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183df, 0x40000027,
-		0x92402ac8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc05);
-	write_rtl8255(dev, 0x4, 0xe05);
-	write_rtl8255(dev, 0x4, 0xc05);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x805);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa05);
-	write_rtl8255(dev, 0x4, 0x805);
-	write_rtl8255(dev, 0x4, 0x405);
-	write_rtl8255(dev, 0x3, 0x26);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x605);
-	write_rtl8255(dev, 0x4, 0x405);
-	write_rtl8255(dev, 0x4, 0x405);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x605);
-	write_rtl8255(dev, 0x4, 0x405);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183cf, 0x27,
-		0x92402acc, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc06);
-	write_rtl8255(dev, 0x4, 0xe06);
-	write_rtl8255(dev, 0x4, 0xc06);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x806);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa06);
-	write_rtl8255(dev, 0x4, 0x806);
-	write_rtl8255(dev, 0x4, 0x406);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x606);
-	write_rtl8255(dev, 0x4, 0x406);
-	write_rtl8255(dev, 0x4, 0x406);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x606);
-	write_rtl8255(dev, 0x4, 0x406);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183af, 0x27,
-		0x92402acc, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc07);
-	write_rtl8255(dev, 0x4, 0xe07);
-	write_rtl8255(dev, 0x4, 0xc07);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x807);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa07);
-	write_rtl8255(dev, 0x4, 0x807);
-	write_rtl8255(dev, 0x4, 0x407);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x607);
-	write_rtl8255(dev, 0x4, 0x407);
-	write_rtl8255(dev, 0x4, 0x407);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x607);
-	write_rtl8255(dev, 0x4, 0x407);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804083d7, 0x40000027,
-		0x92402ad0, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc08);
-	write_rtl8255(dev, 0x4, 0xe08);
-	write_rtl8255(dev, 0x4, 0xc08);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x808);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa08);
-	write_rtl8255(dev, 0x4, 0x808);
-	write_rtl8255(dev, 0x4, 0x408);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x608);
-	write_rtl8255(dev, 0x4, 0x408);
-	write_rtl8255(dev, 0x4, 0x408);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x608);
-	write_rtl8255(dev, 0x4, 0x408);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804083c7, 0x27,
-		0x92402ad0, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc09);
-	write_rtl8255(dev, 0x4, 0xe09);
-	write_rtl8255(dev, 0x4, 0xc09);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x809);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa09);
-	write_rtl8255(dev, 0x4, 0x809);
-	write_rtl8255(dev, 0x4, 0x409);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x609);
-	write_rtl8255(dev, 0x4, 0x409);
-	write_rtl8255(dev, 0x4, 0x409);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x609);
-	write_rtl8255(dev, 0x4, 0x409);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043d7, 0x40000027,
-		0x92402ad4, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc0a);
-	write_rtl8255(dev, 0x4, 0xe0a);
-	write_rtl8255(dev, 0x4, 0xc0a);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x80a);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa0a);
-	write_rtl8255(dev, 0x4, 0x80a);
-	write_rtl8255(dev, 0x4, 0x40a);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x60a);
-	write_rtl8255(dev, 0x4, 0x40a);
-	write_rtl8255(dev, 0x4, 0x40a);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x60a);
-	write_rtl8255(dev, 0x4, 0x40a);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043d7, 0x40000027,
-		0x92402ad4, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc0b);
-	write_rtl8255(dev, 0x4, 0xe0b);
-	write_rtl8255(dev, 0x4, 0xc0b);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x80b);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa0b);
-	write_rtl8255(dev, 0x4, 0x80b);
-	write_rtl8255(dev, 0x4, 0x40b);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x60b);
-	write_rtl8255(dev, 0x4, 0x40b);
-	write_rtl8255(dev, 0x4, 0x40b);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x60b);
-	write_rtl8255(dev, 0x4, 0x40b);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043c7, 0x27,
-		0x92402ad8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc0c);
-	write_rtl8255(dev, 0x4, 0xe0c);
-	write_rtl8255(dev, 0x4, 0xc0c);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x80c);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa0c);
-	write_rtl8255(dev, 0x4, 0x80c);
-	write_rtl8255(dev, 0x4, 0x40c);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x60c);
-	write_rtl8255(dev, 0x4, 0x40c);
-	write_rtl8255(dev, 0x4, 0x40c);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x60c);
-	write_rtl8255(dev, 0x4, 0x40c);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043a7, 0x27,
-		0x92402ad8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc0d);
-	write_rtl8255(dev, 0x4, 0xe0d);
-	write_rtl8255(dev, 0x4, 0xc0d);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x80d);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa0d);
-	write_rtl8255(dev, 0x4, 0x80d);
-	write_rtl8255(dev, 0x4, 0x40d);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x60d);
-	write_rtl8255(dev, 0x4, 0x40d);
-	write_rtl8255(dev, 0x4, 0x40d);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x60d);
-	write_rtl8255(dev, 0x4, 0x40d);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404387, 0x27,
-		0x92402aa8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc0e);
-	write_rtl8255(dev, 0x4, 0xe0e);
-	write_rtl8255(dev, 0x4, 0xc0e);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x80e);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa0e);
-	write_rtl8255(dev, 0x4, 0x80e);
-	write_rtl8255(dev, 0x4, 0x40e);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x60e);
-	write_rtl8255(dev, 0x4, 0x40e);
-	write_rtl8255(dev, 0x4, 0x40e);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x60e);
-	write_rtl8255(dev, 0x4, 0x40e);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804041c7, 0x27,
-		0x92402aa8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc0f);
-	write_rtl8255(dev, 0x4, 0xe0f);
-	write_rtl8255(dev, 0x4, 0xc0f);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x80f);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa0f);
-	write_rtl8255(dev, 0x4, 0x80f);
-	write_rtl8255(dev, 0x4, 0x40f);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x60f);
-	write_rtl8255(dev, 0x4, 0x40f);
-	write_rtl8255(dev, 0x4, 0x40f);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x60f);
-	write_rtl8255(dev, 0x4, 0x40f);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804041a7, 0x27,
-		0x92402aac, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc10);
-	write_rtl8255(dev, 0x4, 0xe10);
-	write_rtl8255(dev, 0x4, 0xc10);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x810);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa10);
-	write_rtl8255(dev, 0x4, 0x810);
-	write_rtl8255(dev, 0x4, 0x410);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x610);
-	write_rtl8255(dev, 0x4, 0x410);
-	write_rtl8255(dev, 0x4, 0x410);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x610);
-	write_rtl8255(dev, 0x4, 0x410);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404187, 0x27,
-		0x92402aac, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc11);
-	write_rtl8255(dev, 0x4, 0xe11);
-	write_rtl8255(dev, 0x4, 0xc11);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x811);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa11);
-	write_rtl8255(dev, 0x4, 0x811);
-	write_rtl8255(dev, 0x4, 0x411);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x611);
-	write_rtl8255(dev, 0x4, 0x411);
-	write_rtl8255(dev, 0x4, 0x411);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x611);
-	write_rtl8255(dev, 0x4, 0x411);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404186, 0x80000027,
-		0x92402ab0, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc12);
-	write_rtl8255(dev, 0x4, 0xe12);
-	write_rtl8255(dev, 0x4, 0xc12);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x812);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa12);
-	write_rtl8255(dev, 0x4, 0x812);
-	write_rtl8255(dev, 0x4, 0x412);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x612);
-	write_rtl8255(dev, 0x4, 0x412);
-	write_rtl8255(dev, 0x4, 0x412);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x612);
-	write_rtl8255(dev, 0x4, 0x412);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404186, 0x27,
-		0x92402ab0, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc13);
-	write_rtl8255(dev, 0x4, 0xe13);
-	write_rtl8255(dev, 0x4, 0xc13);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x813);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa13);
-	write_rtl8255(dev, 0x4, 0x813);
-	write_rtl8255(dev, 0x4, 0x413);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x613);
-	write_rtl8255(dev, 0x4, 0x413);
-	write_rtl8255(dev, 0x4, 0x413);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x613);
-	write_rtl8255(dev, 0x4, 0x413);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404146, 0x27,
-		0x92402ab4, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc14);
-	write_rtl8255(dev, 0x4, 0xe14);
-	write_rtl8255(dev, 0x4, 0xc14);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x814);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa14);
-	write_rtl8255(dev, 0x4, 0x814);
-	write_rtl8255(dev, 0x4, 0x414);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x614);
-	write_rtl8255(dev, 0x4, 0x414);
-	write_rtl8255(dev, 0x4, 0x414);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x614);
-	write_rtl8255(dev, 0x4, 0x414);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404126, 0x27,
-		0x92402ab4, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc15);
-	write_rtl8255(dev, 0x4, 0xe15);
-	write_rtl8255(dev, 0x4, 0xc15);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x815);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa15);
-	write_rtl8255(dev, 0x4, 0x815);
-	write_rtl8255(dev, 0x4, 0x415);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x615);
-	write_rtl8255(dev, 0x4, 0x415);
-	write_rtl8255(dev, 0x4, 0x415);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x615);
-	write_rtl8255(dev, 0x4, 0x415);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404106, 0x27,
-		0x92402ab8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc16);
-	write_rtl8255(dev, 0x4, 0xe16);
-	write_rtl8255(dev, 0x4, 0xc16);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x816);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa16);
-	write_rtl8255(dev, 0x4, 0x816);
-	write_rtl8255(dev, 0x4, 0x416);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x616);
-	write_rtl8255(dev, 0x4, 0x416);
-	write_rtl8255(dev, 0x4, 0x416);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x616);
-	write_rtl8255(dev, 0x4, 0x416);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404105, 0x27,
-		0x92402ab8, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc17);
-	write_rtl8255(dev, 0x4, 0xe17);
-	write_rtl8255(dev, 0x4, 0xc17);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x817);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa17);
-	write_rtl8255(dev, 0x4, 0x817);
-	write_rtl8255(dev, 0x4, 0x417);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x617);
-	write_rtl8255(dev, 0x4, 0x417);
-	write_rtl8255(dev, 0x4, 0x417);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x617);
-	write_rtl8255(dev, 0x4, 0x417);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404104, 0x80000027,
-		0x92402a88, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc18);
-	write_rtl8255(dev, 0x4, 0xe18);
-	write_rtl8255(dev, 0x4, 0xc18);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x818);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa18);
-	write_rtl8255(dev, 0x4, 0x818);
-	write_rtl8255(dev, 0x4, 0x418);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x618);
-	write_rtl8255(dev, 0x4, 0x418);
-	write_rtl8255(dev, 0x4, 0x418);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x618);
-	write_rtl8255(dev, 0x4, 0x418);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404104, 0x27,
-		0x92402a88, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc19);
-	write_rtl8255(dev, 0x4, 0xe19);
-	write_rtl8255(dev, 0x4, 0xc19);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x819);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa19);
-	write_rtl8255(dev, 0x4, 0x819);
-	write_rtl8255(dev, 0x4, 0x419);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x619);
-	write_rtl8255(dev, 0x4, 0x419);
-	write_rtl8255(dev, 0x4, 0x419);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x619);
-	write_rtl8255(dev, 0x4, 0x419);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404044, 0x27,
-		0x92402a8c, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc1a);
-	write_rtl8255(dev, 0x4, 0xe1a);
-	write_rtl8255(dev, 0x4, 0xc1a);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x81a);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa1a);
-	write_rtl8255(dev, 0x4, 0x81a);
-	write_rtl8255(dev, 0x4, 0x41a);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x61a);
-	write_rtl8255(dev, 0x4, 0x41a);
-	write_rtl8255(dev, 0x4, 0x41a);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x61a);
-	write_rtl8255(dev, 0x4, 0x41a);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404024, 0x27,
-		0x92402a8c, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc1b);
-	write_rtl8255(dev, 0x4, 0xe1b);
-	write_rtl8255(dev, 0x4, 0xc1b);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x81b);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa1b);
-	write_rtl8255(dev, 0x4, 0x81b);
-	write_rtl8255(dev, 0x4, 0x41b);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x61b);
-	write_rtl8255(dev, 0x4, 0x41b);
-	write_rtl8255(dev, 0x4, 0x41b);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x61b);
-	write_rtl8255(dev, 0x4, 0x41b);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404004, 0x27,
-		0x92402a90, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc1c);
-	write_rtl8255(dev, 0x4, 0xe1c);
-	write_rtl8255(dev, 0x4, 0xc1c);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x81c);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa1c);
-	write_rtl8255(dev, 0x4, 0x81c);
-	write_rtl8255(dev, 0x4, 0x41c);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x61c);
-	write_rtl8255(dev, 0x4, 0x41c);
-	write_rtl8255(dev, 0x4, 0x41c);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x61c);
-	write_rtl8255(dev, 0x4, 0x41c);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404001, 0x27,
-		0x92402a90, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc1d);
-	write_rtl8255(dev, 0x4, 0xe1d);
-	write_rtl8255(dev, 0x4, 0xc1d);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x81d);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa1d);
-	write_rtl8255(dev, 0x4, 0x81d);
-	write_rtl8255(dev, 0x4, 0x41d);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x61d);
-	write_rtl8255(dev, 0x4, 0x41d);
-	write_rtl8255(dev, 0x4, 0x41d);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x61d);
-	write_rtl8255(dev, 0x4, 0x41d);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a94, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc1e);
-	write_rtl8255(dev, 0x4, 0xe1e);
-	write_rtl8255(dev, 0x4, 0xc1e);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x81e);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa1e);
-	write_rtl8255(dev, 0x4, 0x81e);
-	write_rtl8255(dev, 0x4, 0x41e);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x61e);
-	write_rtl8255(dev, 0x4, 0x41e);
-	write_rtl8255(dev, 0x4, 0x41e);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x61e);
-	write_rtl8255(dev, 0x4, 0x41e);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x27,
-		0x92402a94, 0xf0009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc1f);
-	write_rtl8255(dev, 0x4, 0xe1f);
-	write_rtl8255(dev, 0x4, 0xc1f);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x81f);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa1f);
-	write_rtl8255(dev, 0x4, 0x81f);
-	write_rtl8255(dev, 0x4, 0x41f);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x61f);
-	write_rtl8255(dev, 0x4, 0x41f);
-	write_rtl8255(dev, 0x4, 0x41f);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x61f);
-	write_rtl8255(dev, 0x4, 0x41f);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404020, 0x80000027,
-		0x92402a98, 0xf8009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc20);
-	write_rtl8255(dev, 0x4, 0xe20);
-	write_rtl8255(dev, 0x4, 0xc20);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x820);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa20);
-	write_rtl8255(dev, 0x4, 0x820);
-	write_rtl8255(dev, 0x4, 0x420);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x620);
-	write_rtl8255(dev, 0x4, 0x420);
-	write_rtl8255(dev, 0x4, 0x420);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x620);
-	write_rtl8255(dev, 0x4, 0x420);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404020, 0x27,
-		0x92402a98, 0xf8009, 0x28000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc21);
-	write_rtl8255(dev, 0x4, 0xe21);
-	write_rtl8255(dev, 0x4, 0xc21);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x821);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa21);
-	write_rtl8255(dev, 0x4, 0x821);
-	write_rtl8255(dev, 0x4, 0x421);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x621);
-	write_rtl8255(dev, 0x4, 0x421);
-	write_rtl8255(dev, 0x4, 0x421);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x621);
-	write_rtl8255(dev, 0x4, 0x421);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a68, 0xf0009, 0x10028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc22);
-	write_rtl8255(dev, 0x4, 0xe22);
-	write_rtl8255(dev, 0x4, 0xc22);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x822);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa22);
-	write_rtl8255(dev, 0x4, 0x822);
-	write_rtl8255(dev, 0x4, 0x422);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x622);
-	write_rtl8255(dev, 0x4, 0x422);
-	write_rtl8255(dev, 0x4, 0x422);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x622);
-	write_rtl8255(dev, 0x4, 0x422);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
-		0x92402a68, 0xf0009, 0x20028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc23);
-	write_rtl8255(dev, 0x4, 0xe23);
-	write_rtl8255(dev, 0x4, 0xc23);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x823);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa23);
-	write_rtl8255(dev, 0x4, 0x823);
-	write_rtl8255(dev, 0x4, 0x423);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x623);
-	write_rtl8255(dev, 0x4, 0x423);
-	write_rtl8255(dev, 0x4, 0x423);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x623);
-	write_rtl8255(dev, 0x4, 0x423);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
-		0x92402a6c, 0xf0009, 0x30028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc24);
-	write_rtl8255(dev, 0x4, 0xe24);
-	write_rtl8255(dev, 0x4, 0xc24);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x824);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa24);
-	write_rtl8255(dev, 0x4, 0x824);
-	write_rtl8255(dev, 0x4, 0x424);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x624);
-	write_rtl8255(dev, 0x4, 0x424);
-	write_rtl8255(dev, 0x4, 0x424);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x624);
-	write_rtl8255(dev, 0x4, 0x424);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
-		0x92402a6c, 0xf0009, 0x40028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc25);
-	write_rtl8255(dev, 0x4, 0xe25);
-	write_rtl8255(dev, 0x4, 0xc25);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x825);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa25);
-	write_rtl8255(dev, 0x4, 0x825);
-	write_rtl8255(dev, 0x4, 0x425);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x625);
-	write_rtl8255(dev, 0x4, 0x425);
-	write_rtl8255(dev, 0x4, 0x425);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x625);
-	write_rtl8255(dev, 0x4, 0x425);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a70, 0xf0009, 0x60028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc26);
-	write_rtl8255(dev, 0x4, 0xe26);
-	write_rtl8255(dev, 0x4, 0xc26);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x826);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa26);
-	write_rtl8255(dev, 0x4, 0x826);
-	write_rtl8255(dev, 0x4, 0x426);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x626);
-	write_rtl8255(dev, 0x4, 0x426);
-	write_rtl8255(dev, 0x4, 0x426);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x626);
-	write_rtl8255(dev, 0x4, 0x426);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404031, 0x40000027,
-		0x92402a70, 0xf0011, 0x60028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc27);
-	write_rtl8255(dev, 0x4, 0xe27);
-	write_rtl8255(dev, 0x4, 0xc27);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x827);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa27);
-	write_rtl8255(dev, 0x4, 0x827);
-	write_rtl8255(dev, 0x4, 0x427);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x627);
-	write_rtl8255(dev, 0x4, 0x427);
-	write_rtl8255(dev, 0x4, 0x427);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x627);
-	write_rtl8255(dev, 0x4, 0x427);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404011, 0x40000027,
-		0x92402a74, 0xf0011, 0x60028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc28);
-	write_rtl8255(dev, 0x4, 0xe28);
-	write_rtl8255(dev, 0x4, 0xc28);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x828);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa28);
-	write_rtl8255(dev, 0x4, 0x828);
-	write_rtl8255(dev, 0x4, 0x428);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x628);
-	write_rtl8255(dev, 0x4, 0x428);
-	write_rtl8255(dev, 0x4, 0x428);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x628);
-	write_rtl8255(dev, 0x4, 0x428);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0xc0000027,
-		0x92402a74, 0xf0011, 0x60028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc29);
-	write_rtl8255(dev, 0x4, 0xe29);
-	write_rtl8255(dev, 0x4, 0xc29);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x829);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa29);
-	write_rtl8255(dev, 0x4, 0x829);
-	write_rtl8255(dev, 0x4, 0x429);
-	write_rtl8255(dev, 0x3, 0x25);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x629);
-	write_rtl8255(dev, 0x4, 0x429);
-	write_rtl8255(dev, 0x4, 0x429);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x629);
-	write_rtl8255(dev, 0x4, 0x429);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a78, 0xf0011, 0x60028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc2a);
-	write_rtl8255(dev, 0x4, 0xe2a);
-	write_rtl8255(dev, 0x4, 0xc2a);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x82a);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa2a);
-	write_rtl8255(dev, 0x4, 0x82a);
-	write_rtl8255(dev, 0x4, 0x42a);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x62a);
-	write_rtl8255(dev, 0x4, 0x42a);
-	write_rtl8255(dev, 0x4, 0x42a);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x62a);
-	write_rtl8255(dev, 0x4, 0x42a);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a78, 0xf0011, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc2b);
-	write_rtl8255(dev, 0x4, 0xe2b);
-	write_rtl8255(dev, 0x4, 0xc2b);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x82b);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa2b);
-	write_rtl8255(dev, 0x4, 0x82b);
-	write_rtl8255(dev, 0x4, 0x42b);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x62b);
-	write_rtl8255(dev, 0x4, 0x42b);
-	write_rtl8255(dev, 0x4, 0x42b);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x62b);
-	write_rtl8255(dev, 0x4, 0x42b);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a48, 0xf0019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc2c);
-	write_rtl8255(dev, 0x4, 0xe2c);
-	write_rtl8255(dev, 0x4, 0xc2c);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x82c);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa2c);
-	write_rtl8255(dev, 0x4, 0x82c);
-	write_rtl8255(dev, 0x4, 0x42c);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x62c);
-	write_rtl8255(dev, 0x4, 0x42c);
-	write_rtl8255(dev, 0x4, 0x42c);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x62c);
-	write_rtl8255(dev, 0x4, 0x42c);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a48, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc2d);
-	write_rtl8255(dev, 0x4, 0xe2d);
-	write_rtl8255(dev, 0x4, 0xc2d);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x82d);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa2d);
-	write_rtl8255(dev, 0x4, 0x82d);
-	write_rtl8255(dev, 0x4, 0x42d);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x62d);
-	write_rtl8255(dev, 0x4, 0x42d);
-	write_rtl8255(dev, 0x4, 0x42d);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x62d);
-	write_rtl8255(dev, 0x4, 0x42d);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a4c, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc2e);
-	write_rtl8255(dev, 0x4, 0xe2e);
-	write_rtl8255(dev, 0x4, 0xc2e);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x82e);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa2e);
-	write_rtl8255(dev, 0x4, 0x82e);
-	write_rtl8255(dev, 0x4, 0x42e);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x62e);
-	write_rtl8255(dev, 0x4, 0x42e);
-	write_rtl8255(dev, 0x4, 0x42e);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x62e);
-	write_rtl8255(dev, 0x4, 0x42e);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a4c, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc2f);
-	write_rtl8255(dev, 0x4, 0xe2f);
-	write_rtl8255(dev, 0x4, 0xc2f);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x82f);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa2f);
-	write_rtl8255(dev, 0x4, 0x82f);
-	write_rtl8255(dev, 0x4, 0x42f);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x62f);
-	write_rtl8255(dev, 0x4, 0x42f);
-	write_rtl8255(dev, 0x4, 0x42f);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x62f);
-	write_rtl8255(dev, 0x4, 0x42f);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a50, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc30);
-	write_rtl8255(dev, 0x4, 0xe30);
-	write_rtl8255(dev, 0x4, 0xc30);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x830);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa30);
-	write_rtl8255(dev, 0x4, 0x830);
-	write_rtl8255(dev, 0x4, 0x430);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x630);
-	write_rtl8255(dev, 0x4, 0x430);
-	write_rtl8255(dev, 0x4, 0x430);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x630);
-	write_rtl8255(dev, 0x4, 0x430);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a50, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc31);
-	write_rtl8255(dev, 0x4, 0xe31);
-	write_rtl8255(dev, 0x4, 0xc31);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x831);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa31);
-	write_rtl8255(dev, 0x4, 0x831);
-	write_rtl8255(dev, 0x4, 0x431);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x631);
-	write_rtl8255(dev, 0x4, 0x431);
-	write_rtl8255(dev, 0x4, 0x431);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x631);
-	write_rtl8255(dev, 0x4, 0x431);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a54, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc32);
-	write_rtl8255(dev, 0x4, 0xe32);
-	write_rtl8255(dev, 0x4, 0xc32);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x832);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa32);
-	write_rtl8255(dev, 0x4, 0x832);
-	write_rtl8255(dev, 0x4, 0x432);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x632);
-	write_rtl8255(dev, 0x4, 0x432);
-	write_rtl8255(dev, 0x4, 0x432);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x632);
-	write_rtl8255(dev, 0x4, 0x432);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a54, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc33);
-	write_rtl8255(dev, 0x4, 0xe33);
-	write_rtl8255(dev, 0x4, 0xc33);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x833);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa33);
-	write_rtl8255(dev, 0x4, 0x833);
-	write_rtl8255(dev, 0x4, 0x433);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x633);
-	write_rtl8255(dev, 0x4, 0x433);
-	write_rtl8255(dev, 0x4, 0x433);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x633);
-	write_rtl8255(dev, 0x4, 0x433);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a58, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc34);
-	write_rtl8255(dev, 0x4, 0xe34);
-	write_rtl8255(dev, 0x4, 0xc34);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x834);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa34);
-	write_rtl8255(dev, 0x4, 0x834);
-	write_rtl8255(dev, 0x4, 0x434);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x634);
-	write_rtl8255(dev, 0x4, 0x434);
-	write_rtl8255(dev, 0x4, 0x434);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x634);
-	write_rtl8255(dev, 0x4, 0x434);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a58, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc35);
-	write_rtl8255(dev, 0x4, 0xe35);
-	write_rtl8255(dev, 0x4, 0xc35);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x835);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa35);
-	write_rtl8255(dev, 0x4, 0x835);
-	write_rtl8255(dev, 0x4, 0x435);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x4, 0x635);
-	write_rtl8255(dev, 0x4, 0x435);
-	write_rtl8255(dev, 0x4, 0x435);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x635);
-	write_rtl8255(dev, 0x4, 0x435);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a24, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc36);
-	write_rtl8255(dev, 0x4, 0xe36);
-	write_rtl8255(dev, 0x4, 0xc36);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x836);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa36);
-	write_rtl8255(dev, 0x4, 0x836);
-	write_rtl8255(dev, 0x4, 0x436);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x25);
-	write_rtl8255(dev, 0x4, 0x636);
-	write_rtl8255(dev, 0x4, 0x436);
-	write_rtl8255(dev, 0x4, 0x436);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x636);
-	write_rtl8255(dev, 0x4, 0x436);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a24, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc37);
-	write_rtl8255(dev, 0x4, 0xe37);
-	write_rtl8255(dev, 0x4, 0xc37);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x837);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa37);
-	write_rtl8255(dev, 0x4, 0x837);
-	write_rtl8255(dev, 0x4, 0x437);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x25);
-	write_rtl8255(dev, 0x4, 0x637);
-	write_rtl8255(dev, 0x4, 0x437);
-	write_rtl8255(dev, 0x4, 0x437);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x637);
-	write_rtl8255(dev, 0x4, 0x437);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a28, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc38);
-	write_rtl8255(dev, 0x4, 0xe38);
-	write_rtl8255(dev, 0x4, 0xc38);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x838);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa38);
-	write_rtl8255(dev, 0x4, 0x838);
-	write_rtl8255(dev, 0x4, 0x438);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x25);
-	write_rtl8255(dev, 0x4, 0x638);
-	write_rtl8255(dev, 0x4, 0x438);
-	write_rtl8255(dev, 0x4, 0x438);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x638);
-	write_rtl8255(dev, 0x4, 0x438);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a28, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc39);
-	write_rtl8255(dev, 0x4, 0xe39);
-	write_rtl8255(dev, 0x4, 0xc39);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x839);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa39);
-	write_rtl8255(dev, 0x4, 0x839);
-	write_rtl8255(dev, 0x4, 0x439);
-	write_rtl8255(dev, 0x3, 0x24);
-	write_rtl8255(dev, 0x2, 0x25);
-	write_rtl8255(dev, 0x4, 0x639);
-	write_rtl8255(dev, 0x4, 0x439);
-	write_rtl8255(dev, 0x4, 0x439);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x639);
-	write_rtl8255(dev, 0x4, 0x439);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc3a);
-	write_rtl8255(dev, 0x4, 0xe3a);
-	write_rtl8255(dev, 0x4, 0xc3a);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x83a);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa3a);
-	write_rtl8255(dev, 0x4, 0x83a);
-	write_rtl8255(dev, 0x4, 0x43a);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0x63a);
-	write_rtl8255(dev, 0x4, 0x43a);
-	write_rtl8255(dev, 0x4, 0x43a);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x63a);
-	write_rtl8255(dev, 0x4, 0x43a);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc3b);
-	write_rtl8255(dev, 0x4, 0xe3b);
-	write_rtl8255(dev, 0x4, 0xc3b);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x83b);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa3b);
-	write_rtl8255(dev, 0x4, 0x83b);
-	write_rtl8255(dev, 0x4, 0x43b);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0x63b);
-	write_rtl8255(dev, 0x4, 0x43b);
-	write_rtl8255(dev, 0x4, 0x43b);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x63b);
-	write_rtl8255(dev, 0x4, 0x43b);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc3c);
-	write_rtl8255(dev, 0x4, 0xe3c);
-	write_rtl8255(dev, 0x4, 0xc3c);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x83c);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa3c);
-	write_rtl8255(dev, 0x4, 0x83c);
-	write_rtl8255(dev, 0x4, 0x43c);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0x63c);
-	write_rtl8255(dev, 0x4, 0x43c);
-	write_rtl8255(dev, 0x4, 0x43c);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x63c);
-	write_rtl8255(dev, 0x4, 0x43c);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc3d);
-	write_rtl8255(dev, 0x4, 0xe3d);
-	write_rtl8255(dev, 0x4, 0xc3d);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x83d);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa3d);
-	write_rtl8255(dev, 0x4, 0x83d);
-	write_rtl8255(dev, 0x4, 0x43d);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0x63d);
-	write_rtl8255(dev, 0x4, 0x43d);
-	write_rtl8255(dev, 0x4, 0x43d);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x63d);
-	write_rtl8255(dev, 0x4, 0x43d);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc3e);
-	write_rtl8255(dev, 0x4, 0xe3e);
-	write_rtl8255(dev, 0x4, 0xc3e);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x83e);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa3e);
-	write_rtl8255(dev, 0x4, 0x83e);
-	write_rtl8255(dev, 0x4, 0x43e);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0x63e);
-	write_rtl8255(dev, 0x4, 0x43e);
-	write_rtl8255(dev, 0x4, 0x43e);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x63e);
-	write_rtl8255(dev, 0x4, 0x43e);
-	write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
-		0x92402a00, 0xf8011, 0x70028000, 0xc00, 0x0);
-	write_rtl8255(dev, 0x1, 0x807);
-	write_rtl8255(dev, 0x4, 0xc3f);
-	write_rtl8255(dev, 0x4, 0xe3f);
-	write_rtl8255(dev, 0x4, 0xc3f);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255(dev, 0x4, 0x83f);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0xa3f);
-	write_rtl8255(dev, 0x4, 0x83f);
-	write_rtl8255(dev, 0x4, 0x43f);
-	write_rtl8255(dev, 0x3, 0x0);
-	write_rtl8255(dev, 0x2, 0x0);
-	write_rtl8255(dev, 0x4, 0x63f);
-	write_rtl8255(dev, 0x4, 0x43f);
-	write_rtl8255(dev, 0x4, 0x43f);
-	write_rtl8255(dev, 0x3, 0x100);
-	write_rtl8255(dev, 0x4, 0x63f);
-	write_rtl8255(dev, 0x4, 0x43f);
-	write_rtl8255(dev, 0x4, 0x0);
-	write_rtl8255(dev, 0x1, 0x0);
-	write_rtl8255_reg0c(dev, 0x3539, 0x70000c03, 0xfef46178, 0x408000, 0x403307,
-		0x924f80c0, 0xf955c, 0x8400, 0x429200, 0x1ce20);
-	write_rtl8255(dev, 0x1, 0x1c7);
-	write_rtl8255(dev, 0x2, 0x26);
-	write_rtl8255(dev, 0x3, 0x27);
-	write_rtl8255(dev, 0x1, 0x47);
-	write_rtl8255(dev, 0x4, 0x98c);
-	write_rtl8255(dev, 0x5, 0x65);
-	write_rtl8255(dev, 0x6, 0x13);
-	write_rtl8255(dev, 0x7, 0x7c);
-	write_rtl8255(dev, 0x8, 0x6);
-	write_rtl8255(dev, 0x8, 0x7);
-	write_rtl8255(dev, 0x8, 0x6);
-	write_rtl8255(dev, 0x9, 0xce2);
-	write_rtl8255(dev, 0xb, 0x1c5);
-	write_rtl8255(dev, 0xd, 0xd7f);
-	write_rtl8255(dev, 0xe, 0x369);
-	write_rtl8255(dev, 0xa, 0xd56);
-	write_rtl8255(dev, 0xa, 0xd57);
-	mdelay(20);
-	write_rtl8255(dev, 0xd, 0xd7e);
-
-}
-
-
-void rtl8255_set_band_param(struct net_device *dev, short band)
-{
-	if(band != BAND_A){
-		write_nic_dword(dev, 0x94, 0x3dc00002);
-		write_nic_dword(dev, 0x88, 0x00100040);
-
-		write_phy_cck(dev, 0x13, 0xd0);
-
-		write_phy_cck(dev, 0x41, 0x9d);
-		write_nic_dword(dev, 0x8c, 0x00082205);
-		write_nic_byte(dev, 0xb4, 0x66);
-	}
-}
-
-void rtl8255_rf_init(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	int i;
-	u16 brsr;
-//	short channel /*= priv->chan*/ = 1;
-	priv->chan = 1;
-
-	write_nic_word(dev, RFPinsOutput, 0x80);
-	write_nic_word(dev, RFPinsSelect, 0x80 | SW_CONTROL_GPIO);
-	write_nic_word(dev, RFPinsEnable, 0x80);
-	write_nic_word(dev, RFPinsSelect, SW_CONTROL_GPIO);
-
-	write_nic_dword(dev, RF_TIMING, 0x000f800f);
-
-	brsr = read_nic_word(dev, BRSR);
-
-	write_nic_word(dev, 0x2c, 0xffff);
-
-
-	rtl8180_set_anaparam(dev, RTL8255_ANAPARAM_ON);
-	rtl8185_set_anaparam2(dev, RTL8255_ANAPARAM2_ON);
-
-	write_nic_dword(dev, 0x94, 0x11c00002);
-
-	write_nic_dword(dev, RF_PARA, 0x100040);
-
-	rtl8185_rf_pins_enable(dev);
-
-	rtl8255_init_BGband(dev);
-	rtl8255_set_band_param(dev,BAND_BG);
-
-	write_phy_cck(dev, 0x0, 0x98);
-	write_phy_cck(dev, 0x3, 0x20);
-	write_phy_cck(dev, 0x4, 0x2e);
-	write_phy_cck(dev, 0x5, 0x12);
-	write_phy_cck(dev, 0x6, 0xfc);
-	write_phy_cck(dev, 0x7, 0xd8);
-	write_phy_cck(dev, 0x8, 0x2e);
-	write_phy_cck(dev, 0x10, 0xd3);
-	write_phy_cck(dev, 0x11, 0x88);
-	write_phy_cck(dev, 0x12, 0x47);
-	write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
-
-	write_phy_cck(dev, 0x19, 0x0);
-	write_phy_cck(dev, 0x1a, 0xa0);
-	write_phy_cck(dev, 0x1b, 0x8);
-	write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
-	write_phy_cck(dev, 0x41, 0x9d); /* Energy Threshold */
-	//write_phy_cck(dev, 0x42, 0x0);
-	write_phy_cck(dev, 0x43, 0x8);
-
-	write_nic_byte(dev, TESTR,0x8);
-
-	for(i=0;i<128;i++){
-		write_phy_ofdm(dev, 0x4b, rtl8255_agc[i]);
-		write_phy_ofdm(dev, 0x4a, (u8)i+ 0x80);
-	}
-
-
-	write_phy_ofdm(dev, 0x0, 0x1);
-	write_phy_ofdm(dev, 0x1, 0x2);
-	write_phy_ofdm(dev, 0x2, 0x43);
-	write_phy_ofdm(dev, 0x3, 0x0);
-	write_phy_ofdm(dev, 0x4, 0x0);
-	write_phy_ofdm(dev, 0x5, 0x0);
-	write_phy_ofdm(dev, 0x6, 0x40);
-	write_phy_ofdm(dev, 0x7, 0x0);
-	write_phy_ofdm(dev, 0x8, 0x40);
-	write_phy_ofdm(dev, 0x9, 0xfe);
-	write_phy_ofdm(dev, 0xa, 0x9);
-	write_phy_ofdm(dev, 0xb, 0x80);
-	write_phy_ofdm(dev, 0xc, 0x1);
-	write_phy_ofdm(dev, 0xd, 0x43);
-	write_phy_ofdm(dev, 0xe, 0xd3);
-	write_phy_ofdm(dev, 0xf, 0x38);
-	write_phy_ofdm(dev, 0x10, 0x4);
-	write_phy_ofdm(dev, 0x11, 0x06);/*agc resp time 700*/
-	write_phy_ofdm(dev, 0x12, 0x20);
-	write_phy_ofdm(dev, 0x13, 0x20);
-	write_phy_ofdm(dev, 0x14, 0x0);
-	write_phy_ofdm(dev, 0x15, 0x40);
-	write_phy_ofdm(dev, 0x16, 0x0);
-	write_phy_ofdm(dev, 0x17, 0x40);
-	write_phy_ofdm(dev, 0x18, 0xef);
-	write_phy_ofdm(dev, 0x19, 0x25);
-	write_phy_ofdm(dev, 0x1a, 0x20);
-	write_phy_ofdm(dev, 0x1b, 0x7a);
-	write_phy_ofdm(dev, 0x1c, 0x84);
-	write_phy_ofdm(dev, 0x1e, 0x95);
-	write_phy_ofdm(dev, 0x1f, 0x75);
-	write_phy_ofdm(dev, 0x20, 0x1f);
-	write_phy_ofdm(dev, 0x21, 0x17);
-	write_phy_ofdm(dev, 0x22, 0x16);
-	write_phy_ofdm(dev, 0x23, 0x70); //FIXME maybe not needed
-	write_phy_ofdm(dev, 0x24, 0x70);
-	write_phy_ofdm(dev, 0x25, 0x0);
-	write_phy_ofdm(dev, 0x26, 0x10);
-	write_phy_ofdm(dev, 0x27, 0x88);
-
-
-	write_nic_dword(dev, 0x94, 0x3dc00002); //BAND DEPEND.
-//	write_nic_dword(dev, 0x94, 0x15c00002); //BAND DEPEND.
-
-	write_phy_cck(dev, 0x4, 0x18);
-	write_phy_cck(dev, 0x43, 0x18);
-	write_phy_cck(dev, 0x6, 0xdc);
-	write_phy_cck(dev, 0x44, 0x2b);
-	write_phy_cck(dev, 0x45, 0x2b);
-	write_phy_cck(dev, 0x46, 0x25);
-	write_phy_cck(dev, 0x47, 0x15);
-	write_phy_cck(dev, 0x48, 0x0);
-	write_phy_cck(dev, 0x49, 0x0);
-	write_phy_cck(dev, 0x4a, 0x0);
-	write_phy_cck(dev, 0x4b, 0x0);
-//	write_phy_cck(dev, 0x4c, 0x5);
-#if 0
-	write_phy_cck(dev, 0x41, 0x9d); /* Energy Threshold */
-	// TESTR 0xb 8187
-	write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
-#endif
-	//rtl8255_set_gain(dev, 1); /* FIXME this '1' is random */
-
-	rtl8255_SetTXPowerLevel(dev, priv->chan);
-
-	write_phy_cck(dev, 0x10, 0x93 |0x4); /* Rx ant B, 0xd3 for A */
-	write_phy_ofdm(dev, 0x26, 0x90); /* Rx ant B, 0x10 for A */
-
-	rtl8185_tx_antenna(dev, 0x3); /* TX ant B, 0x0 for A*/
-	/* make sure is waken up! */
-	rtl8180_set_anaparam(dev, RTL8255_ANAPARAM_ON);
-	rtl8185_set_anaparam2(dev, RTL8255_ANAPARAM2_ON);
-
-	rtl8255_set_band_param(dev,BAND_BG);
-
-	write_phy_cck(dev, 0x41, 0x9d);
-
-	rtl8255_set_gain(dev, 4);
-	//rtl8255_set_energy_threshold(dev);
-	write_phy_cck(dev, 0x41, 0x9d);
-	rtl8255_rf_set_chan(dev, priv->chan);
-
-	write_nic_word(dev, BRSR, brsr);
-}
-
diff --git a/drivers/staging/rtl8187se/r8180_rtl8255.h b/drivers/staging/rtl8187se/r8180_rtl8255.h
deleted file mode 100644
index be44ca6..0000000
--- a/drivers/staging/rtl8187se/r8180_rtl8255.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-  This is part of the rtl8180-sa2400 driver
-  released under the GPL (See file COPYING for details).
-  Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
-
-  This files contains programming code for the rtl8255
-  radio frontend.
-
-  *Many* thanks to Realtek Corp. for their great support!
-
-*/
-
-#define RTL8255_ANAPARAM_ON 0xa0000b59
-#define RTL8255_ANAPARAM2_ON 0x840cf311
-
-
-void rtl8255_rf_init(struct net_device *dev);
-void rtl8255_rf_set_chan(struct net_device *dev,short ch);
-void rtl8255_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_sa2400.c b/drivers/staging/rtl8187se/r8180_sa2400.c
deleted file mode 100644
index d649560..0000000
--- a/drivers/staging/rtl8187se/r8180_sa2400.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
-   This files contains PHILIPS SA2400 radio frontend programming routines.
-
-   This is part of rtl8180 OpenSource driver
-   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-   Released under the terms of GPL (General Public Licence)
-
-   Parts of this driver are based on the GPL part of the
-   official realtek driver
-
-   Parts of this driver are based on the rtl8180 driver skeleton
-   from Patric Schenke & Andres Salomon
-
-   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
-
-   Code at http://che.ojctech.com/~dyoung/rtw/ has been useful to me to
-   understand some things.
-
-   Code from rtl8181 project has been useful to me to understand some things.
-
-   We want to tanks the Authors of such projects and the Ndiswrapper
-   project Authors.
-*/
-
-
-#include "r8180.h"
-#include "r8180_hw.h"
-#include "r8180_sa2400.h"
-
-
-//#define DEBUG_SA2400
-
-u32 sa2400_chan[] = {
-	0x0,	//dummy channel 0
-	0x00096c, //1
-	0x080970, //2
-	0x100974, //3
-	0x180978, //4
-	0x000980, //5
-	0x080984, //6
-	0x100988, //7
-	0x18098c, //8
-	0x000994, //9
-	0x080998, //10
-	0x10099c, //11
-	0x1809a0, //12
-	0x0009a8, //13
-	0x0009b4, //14
-};
-
-
-void rf_stabilize(struct net_device *dev)
-{
-	force_pci_posting(dev);
-	mdelay(3); //for now use a great value.. we may optimize in future
-}
-
-
-void write_sa2400(struct net_device *dev,u8 adr, u32 data)
-{
-//	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 phy_config;
-
-        // philips sa2400 expects 24 bits data
-
-	/*if(adr == 4 && priv->digphy){
-		phy_config=0x60000000;
-	}else{
-		phy_config=0xb0000000;
-	}*/
-
-	phy_config = 0xb0000000; // MAC will bang bits to the sa2400
-
-	phy_config |= (((u32)(adr&0xf))<< 24);
-	phy_config |= (data & 0xffffff);
-	write_nic_dword(dev,PHY_CONFIG,phy_config);
-#ifdef DEBUG_SA2400
-	DMESG("Writing sa2400: %x (adr %x)",phy_config,adr);
-#endif
-	rf_stabilize(dev);
-}
-
-
-
-void sa2400_write_phy_antenna(struct net_device *dev,short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u8 ant;
-
-	ant = SA2400_ANTENNA;
-	if(priv->antb) /*default antenna is antenna B */
-		ant |= BB_ANTENNA_B;
-	if(ch == 14)
-		ant |= BB_ANTATTEN_CHAN14;
-	write_phy(dev,0x10,ant);
-	//DMESG("BB antenna %x ",ant);
-}
-
-
-/* from the rtl8181 embedded driver */
-short sa2400_rf_set_sens(struct net_device *dev, short sens)
-{
-	u8 finetune = 0;
-	if ((sens > 85) || (sens < 54)) return -1;
-
-	write_sa2400(dev,5,0x1dfb | (sens-54) << 15 |(finetune<<20));  // AGC	0xc9dfb
-
-	return 0;
-}
-
-
-void sa2400_rf_set_chan(struct net_device *dev, short ch)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 txpw = 0xff & priv->chtxpwr[ch];
-	u32 chan = sa2400_chan[ch];
-
-	write_sa2400(dev,7,txpw);
-	//write_phy(dev,0x10,0xd1);
-	sa2400_write_phy_antenna(dev,ch);
-	write_sa2400(dev,0,chan);
-	write_sa2400(dev,1,0xbb50);
-	write_sa2400(dev,2,0x80);
-	write_sa2400(dev,3,0);
-}
-
-
-void sa2400_rf_close(struct net_device *dev)
-{
-	write_sa2400(dev, 4, 0);
-}
-
-
-void sa2400_rf_init(struct net_device *dev)
-{
-	struct r8180_priv *priv = ieee80211_priv(dev);
-	u32 anaparam;
-	u8 firdac;
-
-	write_nic_byte(dev,PHY_DELAY,0x6);	//this is general
-	write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
-
-	/*these are philips sa2400 specific*/
-	anaparam = read_nic_dword(dev,ANAPARAM);
-	anaparam = anaparam &~ (1<<ANAPARAM_TXDACOFF_SHIFT);
-
-	anaparam = anaparam &~ANAPARAM_PWR1_MASK;
-	anaparam = anaparam &~ANAPARAM_PWR0_MASK;
-	if(priv->digphy){
-		anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
-		anaparam |= (SA2400_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
-	}else{
-		anaparam |= (SA2400_ANA_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
-	}
-
-	rtl8180_set_anaparam(dev,anaparam);
-
-	firdac = (priv->digphy) ? (1<<SA2400_REG4_FIRDAC_SHIFT) : 0;
-	write_sa2400(dev,0,sa2400_chan[priv->chan]);
-	write_sa2400(dev,1,0xbb50);
-	write_sa2400(dev,2,0x80);
-	write_sa2400(dev,3,0);
-	write_sa2400(dev,4,0x19340 | firdac);
-	write_sa2400(dev,5,0xc9dfb);  // AGC
-	write_sa2400(dev,4,0x19348 | firdac);  //calibrates VCO
-
-	if(priv->digphy)
-		write_sa2400(dev,4,0x1938c); /*???*/
-
-	write_sa2400(dev,4,0x19340 | firdac);
-
-	write_sa2400(dev,0,sa2400_chan[priv->chan]);
-	write_sa2400(dev,1,0xbb50);
-	write_sa2400(dev,2,0x80);
-	write_sa2400(dev,3,0);
-	write_sa2400(dev,4,0x19344 | firdac); //calibrates filter
-
-	/* new from rtl8180 embedded driver (rtl8181 project) */
-	write_sa2400(dev,6,0x13ff | (1<<23)); // MANRX
-	write_sa2400(dev,8,0); //VCO
-
-	if(!priv->digphy)
-	{
-		rtl8180_set_anaparam(dev, anaparam | \
-				     (1<<ANAPARAM_TXDACOFF_SHIFT));
-
-		rtl8180_conttx_enable(dev);
-
-		write_sa2400(dev, 4, 0x19341); // calibrates DC
-
-		/* a 5us sleep is required here,
-		   we rely on the 3ms delay introduced in write_sa2400
-		*/
-		write_sa2400(dev, 4, 0x19345);
-		/* a 20us sleep is required here,
-		   we rely on the 3ms delay introduced in write_sa2400
-		*/
-		rtl8180_conttx_disable(dev);
-
-		rtl8180_set_anaparam(dev, anaparam);
-	}
-	/* end new */
-
-	write_sa2400(dev,4,0x19341 | firdac ); //RTX MODE
-
-	// Set tx power level !?
-
-
-	/*baseband configuration*/
-	write_phy(dev,0,0x98);
-	write_phy(dev,3,0x38);
-	write_phy(dev,4,0xe0);
-	write_phy(dev,5,0x90);
-	write_phy(dev,6,0x1a);
-	write_phy(dev,7,0x64);
-
-	/*Should be done something more here??*/
-
-	sa2400_write_phy_antenna(dev,priv->chan);
-
-	write_phy(dev,0x11,0x80);
-	if(priv->diversity)
-		write_phy(dev,0x12,0xc7);
-	else
-		write_phy(dev,0x12,0x47);
-
-	write_phy(dev,0x13,0x90 | priv->cs_treshold );
-
-	write_phy(dev,0x19,0x0);
-	write_phy(dev,0x1a,0xa0);
-
-	sa2400_rf_set_chan(dev,priv->chan);
-}
diff --git a/drivers/staging/rtl8187se/r8180_sa2400.h b/drivers/staging/rtl8187se/r8180_sa2400.h
deleted file mode 100644
index 683a69b..0000000
--- a/drivers/staging/rtl8187se/r8180_sa2400.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-	This is part of rtl8180 OpenSource driver - v 0.7
-	Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the official realtek driver
-	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
-	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
-
-	We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-#define SA2400_ANTENNA 0x91
-#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
-#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
-#define SA2400_ANAPARAM_PWR0_ON 0x3
-
-#define SA2400_RF_MAX_SENS 85
-#define SA2400_RF_DEF_SENS 80
-
-#define SA2400_REG4_FIRDAC_SHIFT 7
-
-void sa2400_rf_init(struct net_device *dev);
-void sa2400_rf_set_chan(struct net_device *dev,short ch);
-short sa2400_rf_set_sens(struct net_device *dev,short sens);
-void sa2400_rf_close(struct net_device *dev);
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
index 979ba0b..766892e 100644
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -20,17 +20,14 @@
 
 #include "r8180.h"
 #include "r8180_hw.h"
-#include "r8180_sa2400.h"
 
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
+#include "ieee80211/dot11d.h"
 
 //#define RATE_COUNT 4
 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
 	6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
 
-#define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
+#define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
 
 static CHANNEL_LIST DefaultChannelPlan[] = {
 //	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14},			//Default channel plan
@@ -197,13 +194,11 @@ static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
 		return 0;
 
 	down(&priv->wx_sem);
-#ifdef ENABLE_IPS
 //	printk("set mode ENABLE_IPS\n");
 	if(priv->bInactivePs){
 		if(wrqu->mode == IW_MODE_ADHOC)
 			IPSLeave(dev);
 	}
-#endif
 	ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
 
 	//rtl8180_commit(dev);
@@ -313,11 +308,7 @@ static int rtl8180_wx_get_range(struct net_device *dev,
 	for (i = 0, val = 0; i < 14; i++) {
 
 		// Include only legal frequencies for some countries
-#ifdef ENABLE_DOT11D
 		if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
-#else
-		if ((priv->ieee80211->channel_map)[i+1]) {
-#endif
 		        range->freq[val].i = i + 1;
 			range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
 			range->freq[val].e = 1;
@@ -370,7 +361,6 @@ static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
 
 	down(&priv->wx_sem);
 	if(priv->up){
-#ifdef ENABLE_IPS
 //		printk("set scan ENABLE_IPS\n");
 		priv->ieee80211->actscanning = true;
 		if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
@@ -393,7 +383,6 @@ static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
 			ret = 0;
 		}
 		else
-#endif
 		{
 			//YJ,add,080828, prevent scan in BusyTraffic
 			//FIXME: Need to consider last scan time
@@ -446,11 +435,9 @@ static int r8180_wx_set_essid(struct net_device *dev,
 		return 0;
 
 	down(&priv->wx_sem);
-#ifdef ENABLE_IPS
 	//printk("set essid ENABLE_IPS\n");
 	if(priv->bInactivePs)
 		IPSLeave(dev);
-#endif
 //	printk("haha:set essid %s essid_len = %d essid_flgs = %d\n",b,  wrqu->essid.length, wrqu->essid.flags);
 
 	ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
@@ -1189,20 +1176,12 @@ static int r8180_wx_set_channelplan(struct net_device *dev,
 		// Clear old channel map
 		for (i=1;i<=MAX_CHANNEL_NUMBER;i++)
 		{
-#ifdef ENABLE_DOT11D
 			GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
-#else
-			priv->ieee80211->channel_map[i] = 0;
-#endif
 		}
 		// Set new channel map
 		for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
 		{
-#ifdef ENABLE_DOT11D
 			GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
-#else
-			priv->ieee80211->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
-#endif
 		}
 	}
 	up(&priv->wx_sem);
@@ -1543,7 +1522,6 @@ static iw_handler r8180_private_handler[] = {
 	r8180_wx_set_forcerate,
 };
 
-#if WIRELESS_EXT >= 17
 static inline int is_same_network(struct ieee80211_network *src,
                                   struct ieee80211_network *dst,
 				  struct ieee80211_device *ieee)
@@ -1584,36 +1562,7 @@ static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
 		wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
 		return wstats;
 	}
-#if 0
-	spin_lock_irqsave(&ieee->lock, flag);
-	list_for_each_entry(target, &ieee->network_list, list)
-	{
-		if (is_same_network(target, &ieee->current_network, ieee))
-		{
-			printk("it's same network:%s\n", target->ssid);
-#if 0
-			if (!tmp_level)
-			{
-				tmp_level = target->stats.signalstrength;
-				tmp_qual = target->stats.signal;
-			}
-			else
-			{
 
-				tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
-				tmp_qual = (15*tmp_qual + target->stats.signal)/16;
-			}
-#else
-			tmp_level = target->stats.signal;
-			tmp_qual = target->stats.signalstrength;
-			tmp_noise = target->stats.noise;
-			printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
-#endif
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&ieee->lock, flag);
-#endif
 	tmp_level = (&ieee->current_network)->stats.signal;
 	tmp_qual = (&ieee->current_network)->stats.signalstrength;
 	tmp_noise = (&ieee->current_network)->stats.noise;
@@ -1626,18 +1575,14 @@ static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
 	wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
 	return wstats;
 }
-#endif
-
 
 struct iw_handler_def  r8180_wx_handlers_def={
 	.standard = r8180_wx_handlers,
-	.num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
+	.num_standard = ARRAY_SIZE(r8180_wx_handlers),
 	.private = r8180_private_handler,
-	.num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
+	.num_private = ARRAY_SIZE(r8180_private_handler),
  	.num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
-#if WIRELESS_EXT >= 17
 	.get_wireless_stats = r8180_get_wireless_stats,
-#endif
 	.private_args = (struct iw_priv_args *)r8180_private_args,
 };
 
diff --git a/drivers/staging/rtl8187se/r8180_wx.h b/drivers/staging/rtl8187se/r8180_wx.h
index b20a67d..735d03d 100644
--- a/drivers/staging/rtl8187se/r8180_wx.h
+++ b/drivers/staging/rtl8187se/r8180_wx.h
@@ -15,7 +15,7 @@
 #ifndef R8180_WX_H
 #define R8180_WX_H
 #include <linux/wireless.h>
-#include "ieee80211.h"
+#include "ieee80211/ieee80211.h"
 extern struct iw_handler_def r8180_wx_handlers_def;
 
 #endif
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
index 4b885a2..cd07059 100644
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ b/drivers/staging/rtl8187se/r8185b_init.c
@@ -22,28 +22,16 @@ Notes:
 #include <linux/spinlock.h>
 #include "r8180_hw.h"
 #include "r8180.h"
-#include "r8180_sa2400.h"  /* PHILIPS Radio frontend */
-#include "r8180_max2820.h" /* MAXIM Radio frontend */
-#include "r8180_gct.h"     /* GCT Radio frontend */
 #include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_rtl8255.h" /* RTL8255 Radio frontend */
 #include "r8180_93cx6.h"   /* Card EEPROM */
 #include "r8180_wx.h"
 
-#ifdef CONFIG_RTL8180_PM
-#include "r8180_pm.h"
-#endif
-
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
+#include "ieee80211/dot11d.h"
 
-#ifdef CONFIG_RTL8185B
 
 //#define CONFIG_RTL8180_IO_MAP
 
 #define TC_3W_POLL_MAX_TRY_CNT 5
-#ifdef CONFIG_RTL818X_S
 static u8 MAC_REG_TABLE[][2]={
                         //PAGA 0:
                         // 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185()
@@ -124,97 +112,6 @@ static u8 OFDM_CONFIG[]={
 			0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
 			0xD8, 0x3C, 0x7B, 0x10, 0x10
 		};
-#else
- static u8 MAC_REG_TABLE[][2]={
-			//PAGA 0:
-			{0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
-			{0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
-			{0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
-			{0xff, 0x00},
-
-			//PAGE 1:
-			{0x5e, 0x01},
-			{0x58, 0x4b}, {0x59, 0x00}, {0x5a, 0x4b}, {0x5b, 0x00}, {0x60, 0x4b},
-			{0x61, 0x09}, {0x62, 0x4b}, {0x63, 0x09}, {0xce, 0x0f}, {0xcf, 0x00},
-			{0xe0, 0xff}, {0xe1, 0x0f}, {0xe2, 0x00}, {0xf0, 0x4e}, {0xf1, 0x01},
-			{0xf2, 0x02}, {0xf3, 0x03}, {0xf4, 0x04}, {0xf5, 0x05}, {0xf6, 0x06},
-			{0xf7, 0x07}, {0xf8, 0x08},
-
-
-			//PAGE 2:
-			{0x5e, 0x02},
-			{0x0c, 0x04}, {0x21, 0x61}, {0x22, 0x68}, {0x23, 0x6f}, {0x24, 0x76},
-			{0x25, 0x7d}, {0x26, 0x84}, {0x27, 0x8d}, {0x4d, 0x08}, {0x4e, 0x00},
-			{0x50, 0x05}, {0x51, 0xf5}, {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0x1f},
-			{0x55, 0x23}, {0x56, 0x45}, {0x57, 0x67}, {0x58, 0x08}, {0x59, 0x08},
-			{0x5a, 0x08}, {0x5b, 0x08}, {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08},
-			{0x63, 0x08}, {0x64, 0xcf}, {0x72, 0x56}, {0x73, 0x9a},
-
-			//PAGA 0:
-			{0x5e, 0x00},
-			{0x34, 0xff}, {0x35, 0x0f}, {0x5b, 0x40}, {0x84, 0x88}, {0x85, 0x24},
-			{0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x07}, {0x8d, 0x00}, {0x94, 0x1b},
-			{0x95, 0x12}, {0x96, 0x00}, {0x97, 0x06}, {0x9d, 0x1a}, {0x9f, 0x10},
-			{0xb4, 0x22}, {0xbe, 0x80}, {0xdb, 0x00}, {0xee, 0x00}, {0x5b, 0x42},
-			{0x91, 0x03},
-
-			//PAGE 2:
-			{0x5e, 0x02},
-			{0x4c, 0x03},
-
-			//PAGE 0:
-			{0x5e, 0x00},
-
-			//PAGE 3:
-			{0x5e, 0x03},
-			{0x9f, 0x00},
-
-			//PAGE 0:
-			{0x5e, 0x00},
-			{0x8c, 0x01}, {0x8d, 0x10},{0x8e, 0x08}, {0x8f, 0x00}
-		};
-
-
-static u8  ZEBRA_AGC[]={
-	0,
-	0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,
-	0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,
-	0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,
-	0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-	0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x19,0x1e,0x1f,0x20,0x21,0x21,0x22,
-	0x23,0x24,0x24,0x25,0x25,0x26,0x26,0x27,0x27,0x28,0x28,0x28,0x29,0x2a,0x2a,0x2b,
-	0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2f,0x30,0x31,0x31,0x31,0x31,
-	0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31
-	};
-
-static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
-	0,
-	0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409,
-	0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541,
-	0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583,
-	0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644,
-	0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688,
-	0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745,
-	0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789,
-	0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793,
-	0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,
-	0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9,
-	0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3,
-	0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb
-};
-
-// 2006.07.13, SD3 szuyitasi:
-//	OFDM.0x03=0x0C (original is 0x0F)
-// Use the new SD3 given param, by shien chang, 2006.07.14
-static u8 OFDM_CONFIG[]={
-	0x10, 0x0d, 0x01, 0x0C, 0x14, 0xfb, 0x0f, 0x60, 0x00, 0x60,
-	0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
-	0x00, 0x00, 0xa8, 0x46, 0xb2, 0x33, 0x07, 0xa5, 0x6f, 0x55,
-	0xc8, 0xb3, 0x0a, 0xe1, 0x1c, 0x8a, 0xb6, 0x83, 0x34, 0x0f,
-	0x4f, 0x23, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, 0xc0, 0xc1,
-	0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, 0x6d, 0x3c, 0xff, 0x07
-};
-#endif
 
 /*---------------------------------------------------------------
   * Hardware IO
@@ -228,37 +125,9 @@ PlatformIOWrite1Byte(
 	u8		data
 	)
 {
-#ifndef CONFIG_RTL8180_IO_MAP
 	write_nic_byte(dev, offset, data);
 	read_nic_byte(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
 
-#else // Port IO
-	u32 Page = (offset >> 8);
-
-	switch(Page)
-	{
-	case 0: // Page 0
-		write_nic_byte(dev, offset, data);
-		break;
-
-	case 1: // Page 1
-	case 2: // Page 2
-	case 3: // Page 3
-		{
-			u8 psr = read_nic_byte(dev, PSR);
-
-			write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
-			write_nic_byte(dev, (offset & 0xff), data);
-			write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
-		}
-		break;
-
-	default:
-		// Illegal page number.
-		DMESGE("PlatformIOWrite1Byte(): illegal page number: %d, offset: %#X", Page, offset);
-		break;
-	}
-#endif
 }
 
 void
@@ -268,38 +137,10 @@ PlatformIOWrite2Byte(
 	u16		data
 	)
 {
-#ifndef CONFIG_RTL8180_IO_MAP
 	write_nic_word(dev, offset, data);
 	read_nic_word(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
 
 
-#else // Port IO
-	u32 Page = (offset >> 8);
-
-	switch(Page)
-	{
-	case 0: // Page 0
-		write_nic_word(dev, offset, data);
-		break;
-
-	case 1: // Page 1
-	case 2: // Page 2
-	case 3: // Page 3
-		{
-			u8 psr = read_nic_byte(dev, PSR);
-
-			write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
-			write_nic_word(dev, (offset & 0xff), data);
-			write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
-		}
-		break;
-
-	default:
-		// Illegal page number.
-		DMESGE("PlatformIOWrite2Byte(): illegal page number: %d, offset: %#X", Page, offset);
-		break;
-	}
-#endif
 }
 u8 PlatformIORead1Byte(struct net_device *dev, u32 offset);
 
@@ -310,7 +151,6 @@ PlatformIOWrite4Byte(
 	u32		data
 	)
 {
-#ifndef CONFIG_RTL8180_IO_MAP
 //{by amy 080312
 if (offset == PhyAddr)
 	{//For Base Band configuration.
@@ -354,33 +194,6 @@ if (offset == PhyAddr)
 		write_nic_dword(dev, offset, data);
 		read_nic_dword(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
 	}
-#else // Port IO
-	u32 Page = (offset >> 8);
-
-	switch(Page)
-	{
-	case 0: // Page 0
-		write_nic_word(dev, offset, data);
-		break;
-
-	case 1: // Page 1
-	case 2: // Page 2
-	case 3: // Page 3
-		{
-			u8 psr = read_nic_byte(dev, PSR);
-
-			write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
-			write_nic_dword(dev, (offset & 0xff), data);
-			write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
-		}
-		break;
-
-	default:
-		// Illegal page number.
-		DMESGE("PlatformIOWrite4Byte(): illegal page number: %d, offset: %#X", Page, offset);
-		break;
-	}
-#endif
 }
 
 u8
@@ -391,36 +204,8 @@ PlatformIORead1Byte(
 {
 	u8	data = 0;
 
-#ifndef CONFIG_RTL8180_IO_MAP
 	data = read_nic_byte(dev, offset);
 
-#else // Port IO
-	u32 Page = (offset >> 8);
-
-	switch(Page)
-	{
-	case 0: // Page 0
-		data = read_nic_byte(dev, offset);
-		break;
-
-	case 1: // Page 1
-	case 2: // Page 2
-	case 3: // Page 3
-		{
-			u8 psr = read_nic_byte(dev, PSR);
-
-			write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
-			data = read_nic_byte(dev, (offset & 0xff));
-			write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
-		}
-		break;
-
-	default:
-		// Illegal page number.
-		DMESGE("PlatformIORead1Byte(): illegal page number: %d, offset: %#X", Page, offset);
-		break;
-	}
-#endif
 
 	return data;
 }
@@ -433,36 +218,8 @@ PlatformIORead2Byte(
 {
 	u16	data = 0;
 
-#ifndef CONFIG_RTL8180_IO_MAP
 	data = read_nic_word(dev, offset);
 
-#else // Port IO
-	u32 Page = (offset >> 8);
-
-	switch(Page)
-	{
-	case 0: // Page 0
-		data = read_nic_word(dev, offset);
-		break;
-
-	case 1: // Page 1
-	case 2: // Page 2
-	case 3: // Page 3
-		{
-			u8 psr = read_nic_byte(dev, PSR);
-
-			write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
-			data = read_nic_word(dev, (offset & 0xff));
-			write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
-		}
-		break;
-
-	default:
-		// Illegal page number.
-		DMESGE("PlatformIORead2Byte(): illegal page number: %d, offset: %#X", Page, offset);
-		break;
-	}
-#endif
 
 	return data;
 }
@@ -475,36 +232,8 @@ PlatformIORead4Byte(
 {
 	u32	data = 0;
 
-#ifndef CONFIG_RTL8180_IO_MAP
 	data = read_nic_dword(dev, offset);
 
-#else // Port IO
-	u32 Page = (offset >> 8);
-
-	switch(Page)
-	{
-	case 0: // Page 0
-		data = read_nic_dword(dev, offset);
-		break;
-
-	case 1: // Page 1
-	case 2: // Page 2
-	case 3: // Page 3
-		{
-			u8 psr = read_nic_byte(dev, PSR);
-
-			write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
-			data = read_nic_dword(dev, (offset & 0xff));
-			write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
-		}
-		break;
-
-	default:
-		// Illegal page number.
-		DMESGE("PlatformIORead4Byte(): illegal page number: %d, offset: %#X\n", Page, offset);
-		break;
-	}
-#endif
 
 	return data;
 }
@@ -542,12 +271,10 @@ ZEBRA_RFSerialWrite(
 	u16				UshortBuffer;
 
 	u8			u1bTmp;
-#ifdef CONFIG_RTL818X_S
 	// RTL8187S HSSI Read/Write Function
 	u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
 	u1bTmp |=   RF_SW_CFG_SI;   //reg08[1]=1 Serial Interface(SI)
 	write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
-#endif
 	UshortBuffer = read_nic_word(dev, RFPinsOutput);
 	oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko.
 
@@ -918,7 +645,6 @@ RF_WriteReg(
 					1);					// bWrite
          		}
 			break;
-  #ifdef CONFIG_RTL818X_S
 			case HW_THREE_WIRE_PI: //Parallel Interface
 			{ // Pure HW 3-wire.
 				data2Write = (data << 4) | (u32)(offset & 0x0f);
@@ -952,7 +678,6 @@ RF_WriteReg(
 //                                 printk(" exit ZEBRA_RFSerialWrite\n ");
 			}
 			break;
-  #endif
 
 
 		default:
@@ -985,13 +710,11 @@ ZEBRA_RFSerialRead(
 	u8			u1bTmp;
 	ThreeWireReg	tdata;
 	//PHAL_DATA_8187	pHalData = GetHalData8187(pAdapter);
-#ifdef CONFIG_RTL818X_S
 	{ // RTL8187S HSSI Read/Write Function
 		u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
 		u1bTmp |=   RF_SW_CFG_SI;   //reg08[1]=1 Serial Interface(SI)
 		write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
 	}
-#endif
 
 	wReg80 = oval = read_nic_word(dev, RFPinsOutput);
 	oval2 = read_nic_word(dev, RFPinsEnable);
@@ -1115,7 +838,6 @@ RF_ReadReg(
 	case RF_ZEBRA4:
 		switch(priv->RegThreeWireMode)
 		{
-#ifdef CONFIG_RTL818X_S
 			case HW_THREE_WIRE_PI: // For 87S  Parallel Interface.
 			{
 				data2Write = ((u32)(offset&0x0f));
@@ -1145,7 +867,6 @@ RF_ReadReg(
 			}
 			break;
 
-#endif
 			// Perform SW 3-wire programming by driver.
 			default:
 			{
@@ -1204,7 +925,6 @@ ReadBBPortUchar(
 	return RegisterContent;
 }
 //{by amy 080312
-#ifdef CONFIG_RTL818X_S
 //
 //	Description:
 //		Perform Antenna settings with antenna diversity on 87SE.
@@ -1286,7 +1006,6 @@ SetAntennaConfig87SE(
 	priv->CurrAntennaIndex = DefaultAnt; // Update default settings.
 	return	bAntennaSwitched;
 }
-#endif
 //by amy 080312
 /*---------------------------------------------------------------
   * Hardware Initialization.
@@ -1305,7 +1024,6 @@ ZEBRA_Config_85BASIC_HardCode(
 	u32	u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
        u8			u1b24E;
 
-#ifdef CONFIG_RTL818X_S
 
 	//=============================================================================
 	// 87S_PCIE :: RADIOCFG.TXT
@@ -1470,11 +1188,6 @@ ZEBRA_Config_85BASIC_HardCode(
 	RF_WriteReg(dev, 0x05, 0x05ab);			mdelay(1); // Rx mode//+edward
 	RF_WriteReg(dev, 0x00, 0x009f);			mdelay(1); // Rx mode//+edward
 
-#if 0//-edward
-	RF_WriteReg(dev, 0x00, 0x0197);			mdelay(1);
-	RF_WriteReg(dev, 0x05, 0x05ab);			mdelay(1);
-	RF_WriteReg(dev, 0x00, 0x009F);			mdelay(1);
-#endif
 	RF_WriteReg(dev, 0x01, 0x0000);			mdelay(1); // Rx mode//+edward
 	RF_WriteReg(dev, 0x02, 0x0000);			mdelay(1); // Rx mode//+edward
 	//power save parameters.
@@ -1494,14 +1207,7 @@ ZEBRA_Config_85BASIC_HardCode(
 		CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
 		CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
 	*/
-#if 0
-	write_nic_dword(dev, PHY_ADR, 0x0100c880);
-	write_nic_dword(dev, PHY_ADR, 0x01001c86);
-	write_nic_dword(dev, PHY_ADR, 0x01007890);
-	write_nic_dword(dev, PHY_ADR, 0x0100d0ae);
-	write_nic_dword(dev, PHY_ADR, 0x010006af);
-	write_nic_dword(dev, PHY_ADR, 0x01004681);
-#endif
+
 	write_phy_cck(dev,0x00,0xc8);
 	write_phy_cck(dev,0x06,0x1c);
 	write_phy_cck(dev,0x10,0x78);
@@ -1513,72 +1219,6 @@ ZEBRA_Config_85BASIC_HardCode(
 	write_nic_byte(dev, CCK_TXAGC, 0x10);
 	write_nic_byte(dev, OFDM_TXAGC, 0x1B);
 	write_nic_byte(dev, ANTSEL, 0x03);
-#else
-	//=============================================================================
-	// RADIOCFG.TXT
-	//=============================================================================
-
-	RF_WriteReg(dev, 0x00, 0x00b7);			mdelay(1);
-	RF_WriteReg(dev, 0x01, 0x0ee0);			mdelay(1);
-	RF_WriteReg(dev, 0x02, 0x044d);			mdelay(1);
-	RF_WriteReg(dev, 0x03, 0x0441);			mdelay(1);
-	RF_WriteReg(dev, 0x04, 0x08c3);			mdelay(1);
-	RF_WriteReg(dev, 0x05, 0x0c72);			mdelay(1);
-	RF_WriteReg(dev, 0x06, 0x00e6);			mdelay(1);
-	RF_WriteReg(dev, 0x07, 0x082a);			mdelay(1);
-	RF_WriteReg(dev, 0x08, 0x003f);			mdelay(1);
-	RF_WriteReg(dev, 0x09, 0x0335);			mdelay(1);
-	RF_WriteReg(dev, 0x0a, 0x09d4);			mdelay(1);
-	RF_WriteReg(dev, 0x0b, 0x07bb);			mdelay(1);
-	RF_WriteReg(dev, 0x0c, 0x0850);			mdelay(1);
-	RF_WriteReg(dev, 0x0d, 0x0cdf);			mdelay(1);
-	RF_WriteReg(dev, 0x0e, 0x002b);			mdelay(1);
-	RF_WriteReg(dev, 0x0f, 0x0114);			mdelay(1);
-
-	RF_WriteReg(dev, 0x00, 0x01b7);			mdelay(1);
-
-
-	for(i=1;i<=95;i++)
-	{
-		RF_WriteReg(dev, 0x01, i);	mdelay(1);
-		RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
-		//DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
-	}
-
-	RF_WriteReg(dev, 0x03, 0x0080);			mdelay(1); 	// write reg 18
-	RF_WriteReg(dev, 0x05, 0x0004);			mdelay(1);	// write reg 20
-	RF_WriteReg(dev, 0x00, 0x00b7);			mdelay(1);	// switch to reg0-reg15
-	//0xfd
-	//0xfd
-	//0xfd
-	RF_WriteReg(dev, 0x02, 0x0c4d);			mdelay(1);
-	mdelay(100);	// Deay 100 ms. //0xfe
-	mdelay(100);	// Deay 100 ms. //0xfe
-	RF_WriteReg(dev, 0x02, 0x044d);			mdelay(1);
-	RF_WriteReg(dev, 0x00, 0x02bf);			mdelay(1);	//0x002f disable 6us corner change,  06f--> enable
-
-	//=============================================================================
-
-	//=============================================================================
-	// CCKCONF.TXT
-	//=============================================================================
-
-	//=============================================================================
-
-	//=============================================================================
-	// Follow WMAC RTL8225_Config()
-	//=============================================================================
-
-	// power control
-	write_nic_byte(dev, CCK_TXAGC, 0x03);
-	write_nic_byte(dev, OFDM_TXAGC, 0x07);
-	write_nic_byte(dev, ANTSEL, 0x03);
-
-	//=============================================================================
-
-	// OFDM BBP setup
-//	SetOutputEnableOfRfPins(dev);//by amy
-#endif
 
 
 
@@ -1633,69 +1273,9 @@ ZEBRA_Config_85BASIC_HardCode(
 //by amy for antenna
 	//=============================================================================
 //{by amy 080312
-#ifdef CONFIG_RTL818X_S
 	// Config Sw/Hw  Combinational Antenna Diversity. Added by Roger, 2008.02.26.
 	SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity);
-#endif
 //by amy 080312}
-#if 0
-	// Config Sw/Hw  Antenna Diversity
-	if( priv->bSwAntennaDiverity )  //  Use SW+Hw Antenna Diversity
-	{
-		if( priv->bDefaultAntenna1 == true )  // aux antenna
-		{
-			// Mac register, aux antenna
-			write_nic_byte(dev, ANTSEL, 0x00);
-			// Config CCK RX antenna.
-			write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
-			write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
-			write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
-			// Config OFDM RX antenna.
-			write_phy_ofdm(dev, 0x0d, 0x54);   // Reg0d : 54
-			write_phy_ofdm(dev, 0x18, 0xb2);  // Reg18 : b2
-		}
-		else //  main antenna
-		{
-			// Mac register, main antenna
-			write_nic_byte(dev, ANTSEL, 0x03);
-			//base band
-			// Config CCK RX antenna.
-			write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
-			write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
-			write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
-			// Config OFDM RX antenna.
-			write_phy_ofdm(dev, 0x0d, 0x5c);   // Reg0d : 5c
-			write_phy_ofdm(dev, 0x18, 0xb2);  // Reg18 : b2
-		}
-	}
-	else   // Disable Antenna Diversity
-	{
-		if( priv->bDefaultAntenna1 == true ) // aux Antenna
-		{
-			// Mac register, aux antenna
-			write_nic_byte(dev, ANTSEL, 0x00);
-			// Config CCK RX antenna.
-			write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
-			write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
-			write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
-			// Config OFDM RX antenna.
-			write_phy_ofdm(dev, 0x0d, 0x54);   // Reg0d : 54
-			write_phy_ofdm(dev, 0x18, 0x32);  // Reg18 : 32
-		}
-		else // main Antenna
-		{
-			// Mac register, main antenna
-			write_nic_byte(dev, ANTSEL, 0x03);
-			// Config CCK RX antenna.
-			write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
-			write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
-			write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
-			// Config OFDM RX antenna.
-			write_phy_ofdm(dev, 0x0d, 0x5c);   // Reg0d : 5c
-			write_phy_ofdm(dev, 0x18, 0x32);  // Reg18 : 32
-		}
-	}
-#endif
 //by amy for antenna
 }
 
@@ -1722,69 +1302,6 @@ UpdateInitialGain(
 
 	switch(priv->rf_chip)
 	{
-#if 0
-	case RF_ZEBRA2:
-		// Dynamic set initial gain, by shien chang, 2006.07.14
-		switch(priv->InitialGain)
-		{
-			case 1: //m861dBm
-				DMESG("RTL8185B + 8225 Initial Gain State 1: -82 dBm \n");
-				write_nic_dword(dev, PhyAddr, 0x2697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0x86a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfa85);	mdelay(1);
-				break;
-
-			case 2: //m862dBm
-				DMESG("RTL8185B + 8225 Initial Gain State 2: -82 dBm \n");
-				write_nic_dword(dev, PhyAddr, 0x2697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0x86a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfb85);	mdelay(1);
-				break;
-
-			case 3: //m863dBm
-				DMESG("RTL8185B + 8225 Initial Gain State 3: -82 dBm \n");
-				write_nic_dword(dev, PhyAddr, 0x2697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0x96a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfb85);	mdelay(1);
-				break;
-
-			case 4: //m864dBm
-				DMESG("RTL8185B + 8225 Initial Gain State 4: -78 dBm \n");
-				write_nic_dword(dev, PhyAddr, 0x2697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xa6a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfb85);	mdelay(1);
-				break;
-
-			case 5: //m82dBm
-				DMESG("RTL8185B + 8225 Initial Gain State 5: -74 dBm \n");
-				write_nic_dword(dev, PhyAddr, 0x3697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xa6a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfb85);	mdelay(1);
-				break;
-
-			case 6: //m78dBm
-				DMESG("RTL8185B + 8225 Initial Gain State 6: -70 dBm \n");
-				write_nic_dword(dev, PhyAddr, 0x4697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xa6a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfb85);	mdelay(1);
-				break;
-
-			case 7: //m74dBm
-				DMESG("RTL8185B + 8225 Initial Gain State 7: -66 dBm \n");
-				write_nic_dword(dev, PhyAddr, 0x5697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xa6a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfb85);	mdelay(1);
-				break;
-
-			default:	//MP
-				DMESG("RTL8185B + 8225 Initial Gain State 1: -82 dBm (default)\n");
-				write_nic_dword(dev, PhyAddr, 0x2697);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0x86a4);	mdelay(1);
-				write_nic_dword(dev, PhyAddr, 0xfa85);	mdelay(1);
-				break;
-		}
-		break;
-#endif
 	case RF_ZEBRA4:
 		// Dynamic set initial gain, follow 87B
 		switch(priv->InitialGain)
@@ -1861,7 +1378,6 @@ UpdateInitialGain(
 		break;
 	}
 }
-#ifdef CONFIG_RTL818X_S
 //
 //	Description:
 //		Tx Power tracking mechanism routine on 87SE.
@@ -1882,7 +1398,6 @@ InitTxPwrTracking87SE(
 	RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN);			mdelay(1);
 }
 
-#endif
 void
 PhyConfig8185(
 	struct net_device *dev
@@ -1900,7 +1415,6 @@ PhyConfig8185(
 		break;
 	}
 //{by amy 080312
-#ifdef CONFIG_RTL818X_S
 	// Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06.
 	if(priv->bDigMechanism)
 	{
@@ -1917,7 +1431,6 @@ PhyConfig8185(
 	if(priv->bTxPowerTrack)
 		InitTxPwrTracking87SE(dev);
 
-#endif
 //by amy 080312}
 	priv->InitialGainBackUp= priv->InitialGain;
 	UpdateInitialGain(dev);
@@ -2005,16 +1518,8 @@ HwConfigureRTL8185(
 		// <RJ_TODO_8185B> We shall set up the ARFR according to user's setting.
 		//write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
 //by amy
-#if 0
-		PlatformIOWrite2Byte(dev, ARFR, 0x0fff); 	// set 1M ~ 54M
-#endif
-#ifdef CONFIG_RTL818X_S
 	        // Aadded by Roger, 2007.11.15.
 	        PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps.
-#else
-		PlatformIOWrite2Byte(dev, ARFR, 0x0c00); //set 48Mbps, 54Mbps.
-                // By SD3 szuyi's request. by Roger, 2007.03.26.
-#endif
 //by amy
 	}
 	else
@@ -2084,10 +1589,6 @@ MacConfig_85BASIC(
 	// Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
 	//PlatformIOWrite4Byte(dev, RFTiming, 0x00004001);
 //by amy
-#if 0
-	write_nic_dword(dev, RFTiming, 0x00004001);
-#endif
-#ifdef CONFIG_RTL818X_S
 	// power save parameter based on "87SE power save parameters 20071127.doc", as follow.
 
 	//Enable DA10 TX power saving
@@ -2108,9 +1609,6 @@ MacConfig_85BASIC(
 	write_nic_word(dev, 0x37C, 0x00EC);
 //	write_nic_word(dev, 0x37E, 0x00FE);//-edward
 	write_nic_word(dev, 0x37E, 0x00EC);//+edward
-#else
-       write_nic_dword(dev, RFTiming, 0x00004003);
-#endif
        write_nic_byte(dev, 0x24E,0x01);
 //by amy
 
@@ -2231,11 +1729,9 @@ ActUpdateChannelAccessSetting(
 
 		//lzm reserved 080826
 #if 1
-#ifdef THOMAS_TURBO
 		// For turbo mode setting. port from 87B by Isaiah 2008-08-01
 		if( ieee->current_network.Turbo_Enable == 1 )
 			AcParam.f.TXOPLimit = 0x01FF;
-#endif
 		// For 87SE with Intel 4965  Ad-Hoc mode have poor throughput (19MB)
 		if (ieee->iw_mode == IW_MODE_ADHOC)
 			AcParam.f.TXOPLimit = 0x0020;
@@ -2477,16 +1973,6 @@ MgntDisconnectIBSS(
 	notify_wx_assoc_event(priv->ieee80211);
 
 	// Stop SW Beacon.Use hw beacon so do not need to do so.by amy
-#if 0
-	if(pMgntInfo->bEnableSwBeaconTimer)
-	{
-		// SwBeaconTimer will stop if pMgntInfo->mIbss==FALSE, see SwBeaconCallback() for details.
-// comment out by haich, 2007.10.01
-//#if DEV_BUS_TYPE==USB_INTERFACE
-		PlatformCancelTimer( Adapter, &pMgntInfo->SwBeaconTimer);
-//#endif
-	}
-#endif
 
 //		MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
 
@@ -2576,10 +2062,8 @@ MgntDisconnect(
 
 	// Indication of disassociation event.
 	//DrvIFIndicateDisassociation(Adapter, asRsn);
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(priv->ieee80211))
 		Dot11d_Reset(priv->ieee80211);
-#endif
 	// In adhoc mode, update beacon frame.
 	if( priv->ieee80211->state == IEEE80211_LINKED )
 	{
@@ -2844,19 +2328,7 @@ InactivePowerSave(
 	//
 	// To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
 	//
-#if 0
-	while( index < 4 )
-	{
-		if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
-			(pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
-		{
-			if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
-			pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
 
-		}
-		index++;
-	}
-#endif
 	priv->bSwRfProcessing = false;
 }
 
@@ -2981,22 +2453,14 @@ void rtl8185b_adapter_start(struct net_device *dev)
 	write_nic_byte(dev, CR9346, 0xc0);	// enable config register write
 //by amy
 	tmpu8 = read_nic_byte(dev, CONFIG3);
-#ifdef CONFIG_RTL818X_S
 	write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) );
-#else
-	write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En | CONFIG3_CLKRUN_En) );
-#endif
 //by amy
 	// Turn on Analog power.
 	// Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
 	write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
 	write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
 //by amy
-#ifdef CONFIG_RTL818X_S
 	write_nic_word(dev, ANAPARAM3, 0x0010);
-#else
-      write_nic_byte(dev, ANAPARAM3, 0x00);
-#endif
 //by amy
 
 	write_nic_byte(dev, CONFIG3, tmpu8);
@@ -3082,7 +2546,6 @@ void rtl8185b_adapter_start(struct net_device *dev)
 		InitWirelessMode = ieee->mode;
 	}
 //by amy for power save
-#ifdef ENABLE_IPS
 //	printk("initialize ENABLE_IPS\n");
 	priv->eRFPowerState = eRfOff;
 	priv->RfOffReason = 0;
@@ -3107,7 +2570,6 @@ void rtl8185b_adapter_start(struct net_device *dev)
 	//	printk("rf off cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
 
 	}
-#endif
 //	IPSEnter(dev);
 //by amy for power save
 #ifdef TODO
@@ -3151,58 +2613,6 @@ void rtl8185b_rx_enable(struct net_device *dev)
 	//u32 rxconf;
 	/* for now we accept data, management & ctl frame*/
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-#if 0
-	rxconf=read_nic_dword(dev,RX_CONF);
-	rxconf = rxconf &~ MAC_FILTER_MASK;
-	rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
-	rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
-	rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
-	rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
-//	rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
-	if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
-
-	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
-	   dev->flags & IFF_PROMISC){
-		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
-	}else{
-		rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
-		if(priv->card_8185 == 0)
-			rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
-	}
-
-	/*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
-		rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
-		rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
-	}*/
-
-	if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
-		rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
-		rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
-		rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
-	}
-
-	if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
-		rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
-
-	//if(!priv->card_8185){
-		rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
-		rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
-	//}
-
-	rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
-	rxconf = rxconf &~ MAX_RX_DMA_MASK;
-	rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
-
-	//if(!priv->card_8185)
-		rxconf = rxconf | RCR_ONLYERLPKT;
-
-	rxconf = rxconf &~ RCR_CS_MASK;
-	if(!priv->card_8185)
-		rxconf |= (priv->rcr_csense<<RCR_CS_SHIFT);
-//	rxconf &=~ 0xfff00000;
-//	rxconf |= 0x90100000;//9014f76f;
-	write_nic_dword(dev, RX_CONF, rxconf);
-#endif
 
 	if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
 
@@ -3244,76 +2654,6 @@ void rtl8185b_tx_enable(struct net_device *dev)
 	//u32 txconf;
 	struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
 
-#if 0
-	txconf= read_nic_dword(dev,TX_CONF);
-	if(priv->card_8185){
-
-
-		byte = read_nic_byte(dev,CW_CONF);
-		byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
-		byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
-		write_nic_byte(dev, CW_CONF, byte);
-
-		tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
-		tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
-		tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
-		tx_agc_ctl |=(1<<TX_AGC_CTL_FEEDBACK_ANT);
-		write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
-		/*
-		write_nic_word(dev, 0x5e, 0x01);
-		force_pci_posting(dev);
-		mdelay(1);
-		write_nic_word(dev, 0xfe, 0x10);
-		force_pci_posting(dev);
-		mdelay(1);
-		write_nic_word(dev, 0x5e, 0x00);
-		force_pci_posting(dev);
-		mdelay(1);
-		*/
-		write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
-	}
-
-	if(priv->card_8185){
-
-		txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
-
-	}else{
-
-		if(hwseqnum)
-			txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
-		else
-			txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
-	}
-
-	txconf = txconf &~ TX_LOOPBACK_MASK;
-	txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
-	txconf = txconf &~ TCR_DPRETRY_MASK;
-	txconf = txconf &~ TCR_RTSRETRY_MASK;
-	txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT);
-	txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
-	txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
-
-	if(priv->card_8185){
-		if(priv->hw_plcp_len)
-			txconf = txconf &~ TCR_PLCP_LEN;
-		else
-			txconf = txconf | TCR_PLCP_LEN;
-	}else{
-		txconf = txconf &~ TCR_SAT;
-	}
-	txconf = txconf &~ TCR_MXDMA_MASK;
-	txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
-	txconf = txconf | TCR_CWMIN;
-	txconf = txconf | TCR_DISCW;
-
-//	if(priv->ieee80211->hw_wep)
-//		txconf=txconf &~ (1<<TX_NOICV_SHIFT);
-//	else
-		txconf=txconf | (1<<TX_NOICV_SHIFT);
-
-	write_nic_dword(dev,TX_CONF,txconf);
-#endif
-
 	write_nic_dword(dev, TCR, priv->TransmitConfig);
 	byte = read_nic_byte(dev, MSR);
 	byte |= MSR_LINK_ENEDCA;
@@ -3339,4 +2679,3 @@ void rtl8185b_tx_enable(struct net_device *dev)
 }
 
 
-#endif
diff --git a/drivers/staging/rtl8192e/Kconfig b/drivers/staging/rtl8192e/Kconfig
new file mode 100644
index 0000000..3100aa5
--- /dev/null
+++ b/drivers/staging/rtl8192e/Kconfig
@@ -0,0 +1,6 @@
+config RTL8192E
+	tristate "RealTek RTL8192E Wireless LAN NIC driver"
+	depends on PCI
+	depends on WIRELESS_EXT
+	default N
+	---help---
diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile
new file mode 100644
index 0000000..5e4aa95
--- /dev/null
+++ b/drivers/staging/rtl8192e/Makefile
@@ -0,0 +1,34 @@
+NIC_SELECT = RTL8192E
+
+
+EXTRA_CFLAGS += -DRTL8192E
+EXTRA_CFLAGS += -std=gnu89
+EXTRA_CFLAGS += -O2
+EXTRA_CFLAGS += -DTHOMAS_TURBO
+EXTRA_CFLAGS += -DENABLE_DOT11D
+
+r8192_pci-objs :=		\
+	r8192E_core.o		\
+	r8180_93cx6.o		\
+	r8192E_wx.o		\
+	r8190_rtl8256.o		\
+	r819xE_phy.o		\
+	r819xE_firmware.o	\
+	r819xE_cmdpkt.o		\
+	r8192E_dm.o		\
+	ieee80211/ieee80211_rx.o		\
+	ieee80211/ieee80211_softmac.o		\
+	ieee80211/ieee80211_tx.o		\
+	ieee80211/ieee80211_wx.o		\
+	ieee80211/ieee80211_module.o		\
+	ieee80211/ieee80211_softmac_wx.o	\
+	ieee80211/rtl819x_HTProc.o		\
+	ieee80211/rtl819x_TSProc.o		\
+	ieee80211/rtl819x_BAProc.o		\
+	ieee80211/dot11d.o			\
+	ieee80211/ieee80211_crypt.o		\
+	ieee80211/ieee80211_crypt_tkip.o	\
+	ieee80211/ieee80211_crypt_ccmp.o	\
+	ieee80211/ieee80211_crypt_wep.o
+
+obj-$(CONFIG_RTL8192E) += r8192_pci.o
diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h
new file mode 100644
index 0000000..15b7a4b
--- /dev/null
+++ b/drivers/staging/rtl8192e/dot11d.h
@@ -0,0 +1,102 @@
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#ifdef ENABLE_DOT11D
+#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 //ENABLE_DOT11D
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192e/ieee80211.h b/drivers/staging/rtl8192e/ieee80211.h
new file mode 100644
index 0000000..97137dd
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211.h
@@ -0,0 +1,2687 @@
+/*
+ * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
+ * remains copyright by the original authors
+ *
+ * Portions of the merged code are based on Host AP (software wireless
+ * LAN access point) driver for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * Modified for Realtek's wi-fi cards by Andrea Merello
+ * <andreamrl@tiscali.it>
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+#ifndef IEEE80211_H
+#define IEEE80211_H
+#include <linux/if_ether.h> /* ETH_ALEN */
+#include <linux/kernel.h>   /* ARRAY_SIZE */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+
+#include <linux/delay.h>
+#include <linux/wireless.h>
+
+#include "ieee80211/rtl819x_HT.h"
+#include "ieee80211/rtl819x_BA.h"
+#include "ieee80211/rtl819x_TS.h"
+
+#ifndef IW_MODE_MONITOR
+#define IW_MODE_MONITOR 6
+#endif
+
+#ifndef IWEVCUSTOM
+#define IWEVCUSTOM 0x8c02
+#endif
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define KEY_TYPE_NA		0x0
+#define KEY_TYPE_WEP40 		0x1
+#define KEY_TYPE_TKIP		0x2
+#define KEY_TYPE_CCMP		0x4
+#define KEY_TYPE_WEP104		0x5
+
+/* added for rtl819x tx procedure */
+#define MAX_QUEUE_SIZE		0x10
+
+//
+// 8190 queue mapping
+//
+#define BK_QUEUE                               0
+#define BE_QUEUE                               1
+#define VI_QUEUE                               2
+#define VO_QUEUE                               3
+#define HCCA_QUEUE                             4
+#define TXCMD_QUEUE                            5
+#define MGNT_QUEUE                             6
+#define HIGH_QUEUE                             7
+#define BEACON_QUEUE                           8
+
+#define LOW_QUEUE                              BE_QUEUE
+#define NORMAL_QUEUE                           MGNT_QUEUE
+
+//added by amy for ps
+#define SWRF_TIMEOUT				50
+
+//added by amy for LEAP related
+#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
+#define SUPPORT_CKIP_MIC			0x08	// bit3
+#define SUPPORT_CKIP_PK			0x10	// bit4
+/* defined for skb cb field */
+/* At most 28 byte */
+typedef struct cb_desc {
+        /* Tx Desc Related flags (8-9) */
+	u8 bLastIniPkt:1;
+	u8 bCmdOrInit:1;
+        u8 bFirstSeg:1;
+        u8 bLastSeg:1;
+        u8 bEncrypt:1;
+        u8 bTxDisableRateFallBack:1;
+        u8 bTxUseDriverAssingedRate:1;
+        u8 bHwSec:1; //indicate whether use Hw security. WB
+
+        u8 reserved1;
+
+        /* Tx Firmware Relaged flags (10-11)*/
+        u8 bCTSEnable:1;
+        u8 bRTSEnable:1;
+        u8 bUseShortGI:1;
+        u8 bUseShortPreamble:1;
+        u8 bTxEnableFwCalcDur:1;
+        u8 bAMPDUEnable:1;
+        u8 bRTSSTBC:1;
+        u8 RTSSC:1;
+
+        u8 bRTSBW:1;
+        u8 bPacketBW:1;
+	u8 bRTSUseShortPreamble:1;
+	u8 bRTSUseShortGI:1;
+	u8 bMulticast:1;
+	u8 bBroadcast:1;
+        //u8 reserved2:2;
+        u8 drv_agg_enable:1;
+        u8 reserved2:1;
+
+        /* Tx Desc related element(12-19) */
+        u8 rata_index;
+        u8 queue_index;
+        //u8 reserved3;
+        //u8 reserved4;
+        u16 txbuf_size;
+        //u8 reserved5;
+	u8 RATRIndex;
+        u8 reserved6;
+        u8 reserved7;
+        u8 reserved8;
+
+        /* Tx firmware related element(20-27) */
+        u8 data_rate;
+        u8 rts_rate;
+        u8 ampdu_factor;
+        u8 ampdu_density;
+        //u8 reserved9;
+        //u8 reserved10;
+        //u8 reserved11;
+        u8 DrvAggrNum;
+	u16 pkt_size;
+        u8 reserved12;
+}cb_desc, *pcb_desc;
+
+/*--------------------------Define -------------------------------------------*/
+#define MGN_1M                  0x02
+#define MGN_2M                  0x04
+#define MGN_5_5M                0x0b
+#define MGN_11M                 0x16
+
+#define MGN_6M                  0x0c
+#define MGN_9M                  0x12
+#define MGN_12M                 0x18
+#define MGN_18M                 0x24
+#define MGN_24M                 0x30
+#define MGN_36M                 0x48
+#define MGN_48M                 0x60
+#define MGN_54M                 0x6c
+
+#define MGN_MCS0                0x80
+#define MGN_MCS1                0x81
+#define MGN_MCS2                0x82
+#define MGN_MCS3                0x83
+#define MGN_MCS4                0x84
+#define MGN_MCS5                0x85
+#define MGN_MCS6                0x86
+#define MGN_MCS7                0x87
+#define MGN_MCS8                0x88
+#define MGN_MCS9                0x89
+#define MGN_MCS10               0x8a
+#define MGN_MCS11               0x8b
+#define MGN_MCS12               0x8c
+#define MGN_MCS13               0x8d
+#define MGN_MCS14               0x8e
+#define MGN_MCS15               0x8f
+
+//----------------------------------------------------------------------------
+//		802.11 Management frame Reason Code field
+//----------------------------------------------------------------------------
+enum	_ReasonCode{
+	unspec_reason	= 0x1,
+	auth_not_valid	= 0x2,
+	deauth_lv_ss	= 0x3,
+	inactivity		= 0x4,
+	ap_overload 	= 0x5,
+	class2_err		= 0x6,
+	class3_err		= 0x7,
+	disas_lv_ss 	= 0x8,
+	asoc_not_auth	= 0x9,
+
+	//----MIC_CHECK
+	mic_failure 	= 0xe,
+	//----END MIC_CHECK
+
+	// Reason code defined in 802.11i D10.0 p.28.
+	invalid_IE		= 0x0d,
+	four_way_tmout	= 0x0f,
+	two_way_tmout	= 0x10,
+	IE_dismatch 	= 0x11,
+	invalid_Gcipher = 0x12,
+	invalid_Pcipher = 0x13,
+	invalid_AKMP	= 0x14,
+	unsup_RSNIEver = 0x15,
+	invalid_RSNIE	= 0x16,
+	auth_802_1x_fail= 0x17,
+	ciper_reject		= 0x18,
+
+	// Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
+	QoS_unspec		= 0x20, // 32
+	QAP_bandwidth	= 0x21, // 33
+	poor_condition	= 0x22, // 34
+	no_facility 	= 0x23, // 35
+							// Where is 36???
+	req_declined	= 0x25, // 37
+	invalid_param	= 0x26, // 38
+	req_not_honored= 0x27,	// 39
+	TS_not_created	= 0x2F, // 47
+	DL_not_allowed	= 0x30, // 48
+	dest_not_exist	= 0x31, // 49
+	dest_not_QSTA	= 0x32, // 50
+};
+
+
+
+#define aSifsTime	 (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10)
+
+#define MGMT_QUEUE_NUM 5
+
+#define IEEE_CMD_SET_WPA_PARAM			1
+#define	IEEE_CMD_SET_WPA_IE			2
+#define IEEE_CMD_SET_ENCRYPTION			3
+#define IEEE_CMD_MLME				4
+
+#define IEEE_PARAM_WPA_ENABLED			1
+#define IEEE_PARAM_TKIP_COUNTERMEASURES		2
+#define IEEE_PARAM_DROP_UNENCRYPTED		3
+#define IEEE_PARAM_PRIVACY_INVOKED		4
+#define IEEE_PARAM_AUTH_ALGS			5
+#define IEEE_PARAM_IEEE_802_1X			6
+//It should consistent with the driver_XXX.c
+//   David, 2006.9.26
+#define IEEE_PARAM_WPAX_SELECT			7
+//Added for notify the encryption type selection
+//   David, 2006.9.26
+#define IEEE_PROTO_WPA				1
+#define IEEE_PROTO_RSN				2
+//Added for notify the encryption type selection
+//   David, 2006.9.26
+#define IEEE_WPAX_USEGROUP			0
+#define IEEE_WPAX_WEP40				1
+#define IEEE_WPAX_TKIP				2
+#define IEEE_WPAX_WRAP   			3
+#define IEEE_WPAX_CCMP				4
+#define IEEE_WPAX_WEP104			5
+
+#define IEEE_KEY_MGMT_IEEE8021X			1
+#define IEEE_KEY_MGMT_PSK			2
+
+#define IEEE_MLME_STA_DEAUTH			1
+#define IEEE_MLME_STA_DISASSOC			2
+
+
+#define IEEE_CRYPT_ERR_UNKNOWN_ALG		2
+#define IEEE_CRYPT_ERR_UNKNOWN_ADDR		3
+#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED	4
+#define IEEE_CRYPT_ERR_KEY_SET_FAILED		5
+#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED	6
+#define IEEE_CRYPT_ERR_CARD_CONF_FAILED		7
+
+
+#define	IEEE_CRYPT_ALG_NAME_LEN			16
+
+#define MAX_IE_LEN  0xff
+
+// added for kernel conflict
+#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
+#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
+#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
+#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
+#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
+#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
+
+#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
+
+#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
+
+#define ieee80211_wep_null		ieee80211_wep_null_rsl
+
+#define free_ieee80211          	free_ieee80211_rsl
+#define alloc_ieee80211        		alloc_ieee80211_rsl
+
+#define ieee80211_rx 			ieee80211_rx_rsl
+#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
+
+#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
+#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
+#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
+#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
+#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
+#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
+#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
+#define ieee80211_is_54g		ieee80211_is_54g_rsl
+#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
+#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
+#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
+#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
+#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
+#define SendDisassociation		SendDisassociation_rsl
+#define ieee80211_disassociate		ieee80211_disassociate_rsl
+#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
+#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
+#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
+#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
+#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
+
+#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
+#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
+#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
+#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
+#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
+#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
+#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl
+#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
+#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
+#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
+#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
+#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
+#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
+#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
+#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
+#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
+#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
+#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
+
+#define ieee80211_txb_free		ieee80211_txb_free_rsl
+
+#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
+#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
+#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
+#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
+#if WIRELESS_EXT >= 18
+#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
+#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
+#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
+#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
+#endif
+
+
+typedef struct ieee_param {
+	u32 cmd;
+	u8 sta_addr[ETH_ALEN];
+        union {
+		struct {
+			u8 name;
+			u32 value;
+		} wpa_param;
+		struct {
+			u32 len;
+			u8 reserved[32];
+			u8 data[0];
+		} wpa_ie;
+	        struct{
+			int command;
+    			int reason_code;
+		} mlme;
+		struct {
+			u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
+			u8 set_tx;
+			u32 err;
+			u8 idx;
+			u8 seq[8]; /* sequence counter (set: RX, get: TX) */
+			u16 key_len;
+			u8 key[0];
+		} crypt;
+	} u;
+}ieee_param;
+
+
+#if WIRELESS_EXT < 17
+#define IW_QUAL_QUAL_INVALID   0x10
+#define IW_QUAL_LEVEL_INVALID  0x20
+#define IW_QUAL_NOISE_INVALID  0x40
+#define IW_QUAL_QUAL_UPDATED   0x1
+#define IW_QUAL_LEVEL_UPDATED  0x2
+#define IW_QUAL_NOISE_UPDATED  0x4
+#endif
+
+#define MSECS(t) msecs_to_jiffies(t)
+#define msleep_interruptible_rsl  msleep_interruptible
+
+#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 IEEE80211_MGMT_HDR_LEN 24
+#define IEEE80211_DATA_HDR3_LEN 24
+#define IEEE80211_DATA_HDR4_LEN 30
+
+#define MIN_FRAG_THRESHOLD     256U
+#define MAX_FRAG_THRESHOLD     2346U
+
+
+/* Frame control field constants */
+#define IEEE80211_FCTL_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_FRAMETYPE	0x00fc
+#define IEEE80211_FCTL_TODS		0x0100
+#define IEEE80211_FCTL_FROMDS		0x0200
+#define IEEE80211_FCTL_DSTODS		0x0300 //added by david
+#define IEEE80211_FCTL_MOREFRAGS	0x0400
+#define IEEE80211_FCTL_RETRY		0x0800
+#define IEEE80211_FCTL_PM		0x1000
+#define IEEE80211_FCTL_MOREDATA		0x2000
+#define IEEE80211_FCTL_WEP		0x4000
+#define IEEE80211_FCTL_ORDER		0x8000
+
+#define IEEE80211_FTYPE_MGMT		0x0000
+#define IEEE80211_FTYPE_CTL		0x0004
+#define IEEE80211_FTYPE_DATA		0x0008
+
+/* management */
+#define IEEE80211_STYPE_ASSOC_REQ	0x0000
+#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
+#define IEEE80211_STYPE_REASSOC_REQ	0x0020
+#define IEEE80211_STYPE_REASSOC_RESP	0x0030
+#define IEEE80211_STYPE_PROBE_REQ	0x0040
+#define IEEE80211_STYPE_PROBE_RESP	0x0050
+#define IEEE80211_STYPE_BEACON		0x0080
+#define IEEE80211_STYPE_ATIM		0x0090
+#define IEEE80211_STYPE_DISASSOC	0x00A0
+#define IEEE80211_STYPE_AUTH		0x00B0
+#define IEEE80211_STYPE_DEAUTH		0x00C0
+#define IEEE80211_STYPE_MANAGE_ACT	0x00D0
+
+/* control */
+#define IEEE80211_STYPE_PSPOLL		0x00A0
+#define IEEE80211_STYPE_RTS		0x00B0
+#define IEEE80211_STYPE_CTS		0x00C0
+#define IEEE80211_STYPE_ACK		0x00D0
+#define IEEE80211_STYPE_CFEND		0x00E0
+#define IEEE80211_STYPE_CFENDACK	0x00F0
+#define IEEE80211_STYPE_BLOCKACK   0x0094
+
+/* data */
+#define IEEE80211_STYPE_DATA		0x0000
+#define IEEE80211_STYPE_DATA_CFACK	0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
+#define IEEE80211_STYPE_NULLFUNC	0x0040
+#define IEEE80211_STYPE_CFACK		0x0050
+#define IEEE80211_STYPE_CFPOLL		0x0060
+#define IEEE80211_STYPE_CFACKPOLL	0x0070
+#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
+#define IEEE80211_STYPE_QOS_NULL	0x00C0
+
+#define IEEE80211_SCTL_FRAG		0x000F
+#define IEEE80211_SCTL_SEQ		0xFFF0
+
+/* QOS control */
+#define IEEE80211_QCTL_TID              0x000F
+
+#define	FC_QOS_BIT					BIT7
+#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
+#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )
+//added by wb. Is this right?
+#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
+#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+#define SN_EQUAL(a, b)	(a == b)
+#define MAX_DEV_ADDR_SIZE 8
+typedef enum _ACT_CATEGORY{
+        ACT_CAT_QOS = 1,
+        ACT_CAT_DLS = 2,
+        ACT_CAT_BA  = 3,
+        ACT_CAT_HT  = 7,
+        ACT_CAT_WMM = 17,
+} ACT_CATEGORY, *PACT_CATEGORY;
+
+typedef enum _TS_ACTION{
+        ACT_ADDTSREQ = 0,
+        ACT_ADDTSRSP = 1,
+        ACT_DELTS    = 2,
+        ACT_SCHEDULE = 3,
+} TS_ACTION, *PTS_ACTION;
+
+typedef enum _BA_ACTION{
+        ACT_ADDBAREQ = 0,
+        ACT_ADDBARSP = 1,
+        ACT_DELBA    = 2,
+} BA_ACTION, *PBA_ACTION;
+
+typedef enum _InitialGainOpType{
+	IG_Backup=0,
+	IG_Restore,
+	IG_Max
+}InitialGainOpType;
+
+/* debug macros */
+#define CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_IEEE80211_DEBUG
+extern u32 ieee80211_debug_level;
+#define IEEE80211_DEBUG(level, fmt, args...) \
+do { if (ieee80211_debug_level & (level)) \
+  printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0)
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
+	do{ if ((ieee80211_debug_level & (level)) == (level))	\
+		{ 	\
+			int i;					\
+			u8* pdata = (u8*) data;			\
+			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
+			for(i=0; i<(int)(datalen); i++)			\
+			{						\
+				printk("%2x ", pdata[i]);		\
+				if ((i+1)%16 == 0) printk("\n");	\
+			}				\
+			printk("\n");			\
+		}					\
+	} while (0)
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif	/* CONFIG_IEEE80211_DEBUG */
+
+/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
+
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
+
+/*
+ * To use the debug system;
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IEEE80211_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry.  xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
+ * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/ipw/debug_level
+ *
+ * you simply need to add your entry to the ipw_debug_levels array.
+ *
+ * If you do not see debug_level in /proc/net/ipw then you do not have
+ * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IEEE80211_DL_INFO          (1<<0)
+#define IEEE80211_DL_WX            (1<<1)
+#define IEEE80211_DL_SCAN          (1<<2)
+#define IEEE80211_DL_STATE         (1<<3)
+#define IEEE80211_DL_MGMT          (1<<4)
+#define IEEE80211_DL_FRAG          (1<<5)
+#define IEEE80211_DL_EAP           (1<<6)
+#define IEEE80211_DL_DROP          (1<<7)
+
+#define IEEE80211_DL_TX            (1<<8)
+#define IEEE80211_DL_RX            (1<<9)
+
+#define IEEE80211_DL_HT		   (1<<10)  //HT
+#define IEEE80211_DL_BA		   (1<<11)  //ba
+#define IEEE80211_DL_TS		   (1<<12)  //TS
+#define IEEE80211_DL_QOS           (1<<13)
+#define IEEE80211_DL_REORDER	   (1<<14)
+#define IEEE80211_DL_IOT	   (1<<15)
+#define IEEE80211_DL_IPS	   (1<<16)
+#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
+#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
+#define IEEE80211_DL_ERR	   (1<<31)   //always open
+#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
+#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
+#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
+
+#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
+#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
+#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
+#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
+#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
+#define IEEE80211_DEBUG_EAP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
+#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
+#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
+#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+
+#ifdef CONFIG_IEEE80211_DEBUG
+/* Added by Annie, 2005-11-22. */
+#define MAX_STR_LEN     64
+/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
+#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
+                        if((_Comp) & level)   							\
+                        {                                                                       \
+                                int             __i;                                            \
+                                u8  buffer[MAX_STR_LEN];                                    	\
+                                int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
+                                memset(buffer, 0, MAX_STR_LEN);                      		\
+                                memcpy(buffer, (u8 *)_Ptr, length );            		\
+                                for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
+                                {                                                               \
+                                     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
+                                }                                                               \
+                                buffer[length] = '\0';                                          \
+                                printk("Rtl819x: ");                                         	\
+                                printk(_TitleString);                                         \
+                                printk(": %d, <%s>\n", _Len, buffer);                         \
+                        }
+#else
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
+#endif
+
+#include <linux/netdevice.h>
+#include <linux/if_arp.h> /* ARPHRD_ETHER */
+
+#ifndef WIRELESS_SPY
+#define WIRELESS_SPY		// enable iwspy support
+#endif
+#include <net/iw_handler.h>	// new driver API
+
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
+
+#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#endif
+
+/* IEEE 802.11 defines */
+
+#define P80211_OUI_LEN 3
+
+struct ieee80211_snap_hdr {
+
+        u8    dsap;   /* always 0xAA */
+        u8    ssap;   /* always 0xAA */
+        u8    ctrl;   /* always 0x03 */
+        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
+
+} __attribute__ ((packed));
+
+#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
+
+#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_LEAP 2
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#define WLAN_CAPABILITY_BSS (1<<0)
+#define WLAN_CAPABILITY_IBSS (1<<1)
+#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
+#define WLAN_CAPABILITY_PRIVACY (1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
+#define WLAN_CAPABILITY_PBCC (1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+
+/* 802.11g ERP information element */
+#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
+#define WLAN_ERP_USE_PROTECTION (1<<1)
+#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
+
+/* Status codes */
+enum ieee80211_statuscode {
+        WLAN_STATUS_SUCCESS = 0,
+        WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+        WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+        WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+        WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+        WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+        WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+        WLAN_STATUS_CHALLENGE_FAIL = 15,
+        WLAN_STATUS_AUTH_TIMEOUT = 16,
+        WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+        WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+        /* 802.11b */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+        WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+        WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+        /* 802.11h */
+        WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+        /* 802.11g */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+        WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+        /* 802.11i */
+        WLAN_STATUS_INVALID_IE = 40,
+        WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+        WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+        WLAN_STATUS_INVALID_AKMP = 43,
+        WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+        WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+        WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+};
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+        WLAN_REASON_UNSPECIFIED = 1,
+        WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+        WLAN_REASON_DEAUTH_LEAVING = 3,
+        WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+        WLAN_REASON_DISASSOC_AP_BUSY = 5,
+        WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+        WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+        WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+        WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+        /* 802.11h */
+        WLAN_REASON_DISASSOC_BAD_POWER = 10,
+        WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+        /* 802.11i */
+        WLAN_REASON_INVALID_IE = 13,
+        WLAN_REASON_MIC_FAILURE = 14,
+        WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+        WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+        WLAN_REASON_IE_DIFFERENT = 17,
+        WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+        WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+        WLAN_REASON_INVALID_AKMP = 20,
+        WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+        WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+        WLAN_REASON_IEEE8021X_FAILED = 23,
+        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+};
+
+#define IEEE80211_STATMASK_SIGNAL (1<<0)
+#define IEEE80211_STATMASK_RSSI (1<<1)
+#define IEEE80211_STATMASK_NOISE (1<<2)
+#define IEEE80211_STATMASK_RATE (1<<3)
+#define IEEE80211_STATMASK_WEMASK 0x7
+
+#define IEEE80211_CCK_MODULATION    (1<<0)
+#define IEEE80211_OFDM_MODULATION   (1<<1)
+
+#define IEEE80211_24GHZ_BAND     (1<<0)
+#define IEEE80211_52GHZ_BAND     (1<<1)
+
+#define IEEE80211_CCK_RATE_LEN  		4
+#define IEEE80211_CCK_RATE_1MB		        0x02
+#define IEEE80211_CCK_RATE_2MB		        0x04
+#define IEEE80211_CCK_RATE_5MB		        0x0B
+#define IEEE80211_CCK_RATE_11MB		        0x16
+#define IEEE80211_OFDM_RATE_LEN 		8
+#define IEEE80211_OFDM_RATE_6MB		        0x0C
+#define IEEE80211_OFDM_RATE_9MB		        0x12
+#define IEEE80211_OFDM_RATE_12MB		0x18
+#define IEEE80211_OFDM_RATE_18MB		0x24
+#define IEEE80211_OFDM_RATE_24MB		0x30
+#define IEEE80211_OFDM_RATE_36MB		0x48
+#define IEEE80211_OFDM_RATE_48MB		0x60
+#define IEEE80211_OFDM_RATE_54MB		0x6C
+#define IEEE80211_BASIC_RATE_MASK		0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
+
+#define IEEE80211_CCK_RATES_MASK	        0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
+	IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
+        IEEE80211_CCK_RATE_5MB_MASK | \
+        IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
+	IEEE80211_OFDM_RATE_12MB_MASK | \
+	IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
+	IEEE80211_OFDM_RATE_9MB_MASK  | \
+	IEEE80211_OFDM_RATE_18MB_MASK | \
+	IEEE80211_OFDM_RATE_36MB_MASK | \
+	IEEE80211_OFDM_RATE_48MB_MASK | \
+	IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+                                IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+#define IEEE80211_NUM_OFDM_RATES	    8
+#define IEEE80211_NUM_CCK_RATES	            4
+#define IEEE80211_OFDM_SHIFT_MASK_A         4
+
+
+/* this is stolen and modified from the madwifi driver*/
+#define IEEE80211_FC0_TYPE_MASK		0x0c
+#define IEEE80211_FC0_TYPE_DATA		0x08
+#define IEEE80211_FC0_SUBTYPE_MASK	0xB0
+#define IEEE80211_FC0_SUBTYPE_QOS	0x80
+
+#define IEEE80211_QOS_HAS_SEQ(fc) \
+	(((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
+	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
+
+/* this is stolen from ipw2200 driver */
+#define IEEE_IBSS_MAC_HASH_SIZE 31
+struct ieee_ibss_seq {
+	u8 mac[ETH_ALEN];
+	u16 seq_num[17];
+	u16 frag_num[17];
+	unsigned long packet_time[17];
+	struct list_head list;
+};
+
+/* NOTE: This data is for statistical purposes; not all hardware provides this
+ *       information for frames received.  Not setting these will not cause
+ *       any adverse affects. */
+struct ieee80211_rx_stats {
+#if 1
+	u32 mac_time[2];
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate; /* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+	u8 nic_type;
+	u16       Length;
+	//      u8        DataRate;      // In 0.5 Mbps
+	u8        SignalQuality; // in 0-100 index.
+	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
+	s8        RxPower; // in dBm Translate from PWdB
+	u8        SignalStrength; // in 0-100 index.
+	u16       bHwError:1;
+	u16       bCRC:1;
+	u16       bICV:1;
+	u16       bShortPreamble:1;
+	u16       Antenna:1;      //for rtl8185
+	u16       Decrypted:1;    //for rtl8185, rtl8187
+	u16       Wakeup:1;       //for rtl8185
+	u16       Reserved0:1;    //for rtl8185
+	u8        AGC;
+	u32       TimeStampLow;
+	u32       TimeStampHigh;
+	bool      bShift;
+	bool      bIsQosData;             // Added by Annie, 2005-12-22.
+	u8        UserPriority;
+
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+	u8        RxDrvInfoSize;
+	u8        RxBufShift;
+	bool      bIsAMPDU;
+	bool      bFirstMPDU;
+	bool      bContainHTC;
+	bool      RxIs40MHzPacket;
+	u32       RxPWDBAll;
+	u8        RxMIMOSignalStrength[4];        // in 0~100 index
+	s8        RxMIMOSignalQuality[2];
+	bool      bPacketMatchBSSID;
+	bool      bIsCCK;
+	bool      bPacketToSelf;
+	//added by amy
+	u8*       virtual_address;
+	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
+	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
+	u16          fragoffset;                        // Data offset for this fragment
+	u16          ntotalfrag;
+	bool      	  bisrxaggrsubframe;
+	bool		  bPacketBeacon;	//cosa add for rssi
+	bool		  bToSelfBA;		//cosa add for rssi
+	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
+	u16		  Seq_Num;
+#endif
+
+};
+
+/* IEEE 802.11 requires that STA supports concurrent reception of at least
+ * three fragmented frames. This define can be increased to support more
+ * concurrent frames, but it should be noted that each entry can consume about
+ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
+#define IEEE80211_FRAG_CACHE_LEN 4
+
+struct ieee80211_frag_entry {
+	unsigned long first_frag_time;
+	unsigned int seq;
+	unsigned int last_frag;
+	struct sk_buff *skb;
+	u8 src_addr[ETH_ALEN];
+	u8 dst_addr[ETH_ALEN];
+};
+
+struct ieee80211_stats {
+	unsigned int tx_unicast_frames;
+	unsigned int tx_multicast_frames;
+	unsigned int tx_fragments;
+	unsigned int tx_unicast_octets;
+	unsigned int tx_multicast_octets;
+	unsigned int tx_deferred_transmissions;
+	unsigned int tx_single_retry_frames;
+	unsigned int tx_multiple_retry_frames;
+	unsigned int tx_retry_limit_exceeded;
+	unsigned int tx_discards;
+	unsigned int rx_unicast_frames;
+	unsigned int rx_multicast_frames;
+	unsigned int rx_fragments;
+	unsigned int rx_unicast_octets;
+	unsigned int rx_multicast_octets;
+	unsigned int rx_fcs_errors;
+	unsigned int rx_discards_no_buffer;
+	unsigned int tx_discards_wrong_sa;
+	unsigned int rx_discards_undecryptable;
+	unsigned int rx_message_in_msg_fragments;
+	unsigned int rx_message_in_bad_msg_fragments;
+};
+
+struct ieee80211_device;
+
+#include "ieee80211_crypt.h"
+
+#define SEC_KEY_1         (1<<0)
+#define SEC_KEY_2         (1<<1)
+#define SEC_KEY_3         (1<<2)
+#define SEC_KEY_4         (1<<3)
+#define SEC_ACTIVE_KEY    (1<<4)
+#define SEC_AUTH_MODE     (1<<5)
+#define SEC_UNICAST_GROUP (1<<6)
+#define SEC_LEVEL         (1<<7)
+#define SEC_ENABLED       (1<<8)
+#define SEC_ENCRYPT       (1<<9)
+
+#define SEC_LEVEL_0      0 /* None */
+#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
+#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
+#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
+
+#define SEC_ALG_NONE            0
+#define SEC_ALG_WEP             1
+#define SEC_ALG_TKIP            2
+#define SEC_ALG_CCMP            3
+
+#define WEP_KEYS 		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN             32
+#define SCM_TEMPORAL_KEY_LENGTH 16
+
+struct ieee80211_security {
+	u16 active_key:2,
+            enabled:1,
+	    auth_mode:2,
+            auth_algo:4,
+            unicast_uses_group:1,
+	    encrypt:1;
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+	u8 level;
+	u16 flags;
+} __attribute__ ((packed));
+
+
+/*
+ 802.11 data frame from AP
+      ,-------------------------------------------------------------------.
+Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
+      |------|------|---------|---------|---------|------|---------|------|
+Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
+      |      | tion | (BSSID) |         |         | ence |  data   |      |
+      `-------------------------------------------------------------------'
+Total: 28-2340 bytes
+*/
+
+/* Management Frame Information Element Types */
+enum ieee80211_mfie {
+        MFIE_TYPE_SSID = 0,
+        MFIE_TYPE_RATES = 1,
+        MFIE_TYPE_FH_SET = 2,
+        MFIE_TYPE_DS_SET = 3,
+        MFIE_TYPE_CF_SET = 4,
+        MFIE_TYPE_TIM = 5,
+        MFIE_TYPE_IBSS_SET = 6,
+        MFIE_TYPE_COUNTRY = 7,
+        MFIE_TYPE_HOP_PARAMS = 8,
+        MFIE_TYPE_HOP_TABLE = 9,
+        MFIE_TYPE_REQUEST = 10,
+        MFIE_TYPE_CHALLENGE = 16,
+        MFIE_TYPE_POWER_CONSTRAINT = 32,
+        MFIE_TYPE_POWER_CAPABILITY = 33,
+        MFIE_TYPE_TPC_REQUEST = 34,
+        MFIE_TYPE_TPC_REPORT = 35,
+        MFIE_TYPE_SUPP_CHANNELS = 36,
+        MFIE_TYPE_CSA = 37,
+        MFIE_TYPE_MEASURE_REQUEST = 38,
+        MFIE_TYPE_MEASURE_REPORT = 39,
+        MFIE_TYPE_QUIET = 40,
+        MFIE_TYPE_IBSS_DFS = 41,
+        MFIE_TYPE_ERP = 42,
+        MFIE_TYPE_RSN = 48,
+        MFIE_TYPE_RATES_EX = 50,
+        MFIE_TYPE_HT_CAP= 45,
+	 MFIE_TYPE_HT_INFO= 61,
+	 MFIE_TYPE_AIRONET=133,
+        MFIE_TYPE_GENERIC = 221,
+        MFIE_TYPE_QOS_PARAMETER = 222,
+};
+
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 addr2[ETH_ALEN];
+        u8 payload[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_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_authentication {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/*challenge*/
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+        struct ieee80211_hdr_3addr header;
+        __le16 reason;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+	struct ieee80211_hdr_3addr header;
+	/* SSID, supported rates */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	u32 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_request_frame {
+	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_reassoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	/* SSID, supported rates, RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	struct ieee80211_info_element info_element[0]; /* supported rates */
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 queue_index;
+	u8 rts_included;
+	u16 reserved;
+	__le16 frag_size;
+	__le16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+#define MAX_TX_AGG_COUNT		  16
+struct ieee80211_drv_agg_txb {
+	u8 nr_drv_agg_frames;
+	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
+}__attribute__((packed));
+
+#define MAX_SUBFRAME_COUNT 		  64
+struct ieee80211_rxb {
+	u8 nr_subframes;
+	struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+}__attribute__((packed));
+
+typedef union _frameqos {
+	u16 shortdata;
+	u8  chardata[2];
+	struct {
+		u16 tid:4;
+		u16 eosp:1;
+		u16 ack_policy:2;
+		u16 reserved:1;
+		u16 txop:8;
+	}field;
+}frameqos,*pframeqos;
+
+/* SWEEP TABLE ENTRIES NUMBER*/
+#define MAX_SWEEP_TAB_ENTRIES		  42
+#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
+/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
+ * only use 8, and then use extended rates for the remaining supported
+ * rates.  Other APs, however, stick all of their supported rates on the
+ * main rates information element... */
+#define MAX_RATES_LENGTH                  ((u8)12)
+#define MAX_RATES_EX_LENGTH               ((u8)16)
+#define MAX_NETWORK_COUNT                  128
+
+#define MAX_CHANNEL_NUMBER                 161
+#define IEEE80211_SOFTMAC_SCAN_TIME	   100
+//(HZ / 2)
+#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
+
+#define CRC_LENGTH                 4U
+
+#define MAX_WPA_IE_LEN 64
+
+#define NETWORK_EMPTY_ESSID (1<<0)
+#define NETWORK_HAS_OFDM    (1<<1)
+#define NETWORK_HAS_CCK     (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+                                         NETWORK_HAS_QOS_INFORMATION)
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+#if 1
+struct ieee80211_qos_information_element {
+        u8 elementID;
+        u8 length;
+        u8 qui[QOS_OUI_LEN];
+        u8 qui_type;
+        u8 qui_subtype;
+        u8 version;
+        u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+        u8 aci_aifsn;
+        u8 ecw_min_max;
+        __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+        struct ieee80211_qos_information_element info_element;
+        u8 reserved;
+        struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+        __le16 cw_min[QOS_QUEUE_NUM];
+        __le16 cw_max[QOS_QUEUE_NUM];
+        u8 aifs[QOS_QUEUE_NUM];
+        u8 flag[QOS_QUEUE_NUM];
+        __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+        struct ieee80211_qos_parameters parameters;
+        int active;
+        int supported;
+        u8 param_count;
+        u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+        u8 tim_count;
+        u8 tim_period;
+} __attribute__ ((packed));
+
+//#else
+struct ieee80211_wmm_ac_param {
+	u8 ac_aci_acm_aifsn;
+	u8 ac_ecwmin_ecwmax;
+	u16 ac_txop_limit;
+};
+
+struct ieee80211_wmm_ts_info {
+	u8 ac_dir_tid;
+	u8 ac_up_psb;
+	u8 reserved;
+} __attribute__ ((packed));
+
+struct ieee80211_wmm_tspec_elem {
+	struct ieee80211_wmm_ts_info ts_info;
+	u16 norm_msdu_size;
+	u16 max_msdu_size;
+	u32 min_serv_inter;
+	u32 max_serv_inter;
+	u32 inact_inter;
+	u32 suspen_inter;
+	u32 serv_start_time;
+	u32 min_data_rate;
+	u32 mean_data_rate;
+	u32 peak_data_rate;
+	u32 max_burst_size;
+	u32 delay_bound;
+	u32 min_phy_rate;
+	u16 surp_band_allow;
+	u16 medium_time;
+}__attribute__((packed));
+#endif
+enum eap_type {
+	EAP_PACKET = 0,
+	EAPOL_START,
+	EAPOL_LOGOFF,
+	EAPOL_KEY,
+	EAPOL_ENCAP_ASF_ALERT
+};
+
+static const char *eap_types[] = {
+	[EAP_PACKET]		= "EAP-Packet",
+	[EAPOL_START]		= "EAPOL-Start",
+	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
+	[EAPOL_KEY]		= "EAPOL-Key",
+	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
+};
+
+static inline const char *eap_get_type(int type)
+{
+	return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+//added by amy for reorder
+static inline u8 Frame_QoSTID(u8* buf)
+{
+	struct ieee80211_hdr_3addr *hdr;
+	u16 fc;
+	hdr = (struct ieee80211_hdr_3addr *)buf;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
+}
+
+//added by amy for reorder
+
+struct eapol {
+	u8 snap[6];
+	u16 ethertype;
+	u8 version;
+	u8 type;
+	u16 length;
+} __attribute__ ((packed));
+
+struct ieee80211_softmac_stats{
+	unsigned int rx_ass_ok;
+	unsigned int rx_ass_err;
+	unsigned int rx_probe_rq;
+	unsigned int tx_probe_rs;
+	unsigned int tx_beacons;
+	unsigned int rx_auth_rq;
+	unsigned int rx_auth_rs_ok;
+	unsigned int rx_auth_rs_err;
+	unsigned int tx_auth_rq;
+	unsigned int no_auth_rs;
+	unsigned int no_ass_rs;
+	unsigned int tx_ass_rq;
+	unsigned int rx_ass_rq;
+	unsigned int tx_probe_rq;
+	unsigned int reassoc;
+	unsigned int swtxstop;
+	unsigned int swtxawake;
+	unsigned char CurrentShowTxate;
+	unsigned char last_packet_rate;
+	unsigned int txretrycount;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_info_element_hdr {
+	u8 id;
+	u8 len;
+} __attribute__ ((packed));
+
+/*
+ * These are the data types that can make up management packets
+ *
+	u16 auth_algorithm;
+	u16 auth_sequence;
+	u16 beacon_interval;
+	u16 capability;
+	u8 current_ap[ETH_ALEN];
+	u16 listen_interval;
+	struct {
+		u16 association_id:14, reserved:2;
+	} __attribute__ ((packed));
+	u32 time_stamp[2];
+	u16 reason;
+	u16 status;
+*/
+
+#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
+#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps
+
+enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
+#define MAX_SP_Len  (WMM_all_frame << 4)
+#define IEEE80211_QOS_TID 0x0f
+#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
+
+#define IEEE80211_DTIM_MBCAST 4
+#define IEEE80211_DTIM_UCAST 2
+#define IEEE80211_DTIM_VALID 1
+#define IEEE80211_DTIM_INVALID 0
+
+#define IEEE80211_PS_DISABLED 0
+#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
+#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
+
+//added by David for QoS 2006/6/30
+//#define WMM_Hang_8187
+#ifdef WMM_Hang_8187
+#undef WMM_Hang_8187
+#endif
+
+#define WME_AC_BK   0x00
+#define WME_AC_BE   0x01
+#define WME_AC_VI   0x02
+#define WME_AC_VO   0x03
+#define WME_ACI_MASK 0x03
+#define WME_AIFSN_MASK 0x03
+#define WME_AC_PRAM_LEN 16
+
+#define MAX_RECEIVE_BUFFER_SIZE 9100
+
+//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
+//#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1))
+#if 1
+#define UP2AC(up) (		   \
+	((up) < 1) ? WME_AC_BE : \
+	((up) < 3) ? WME_AC_BK : \
+	((up) < 4) ? WME_AC_BE : \
+	((up) < 6) ? WME_AC_VI : \
+	WME_AC_VO)
+#endif
+//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
+#define AC2UP(_ac)	(       \
+	((_ac) == WME_AC_VO) ? 6 : \
+	((_ac) == WME_AC_VI) ? 5 : \
+	((_ac) == WME_AC_BK) ? 1 : \
+	0)
+
+#define	ETHER_ADDR_LEN		6	/* length of an Ethernet address */
+#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
+
+struct	ether_header {
+	u8 ether_dhost[ETHER_ADDR_LEN];
+	u8 ether_shost[ETHER_ADDR_LEN];
+	u16 ether_type;
+} __attribute__((packed));
+
+#ifndef ETHERTYPE_PAE
+#define	ETHERTYPE_PAE	0x888e		/* EAPOL PAE/802.1x */
+#endif
+#ifndef ETHERTYPE_IP
+#define	ETHERTYPE_IP	0x0800		/* IP protocol */
+#endif
+
+typedef struct _bss_ht{
+
+	bool				support_ht;
+
+	// HT related elements
+	u8					ht_cap_buf[32];
+	u16					ht_cap_len;
+	u8					ht_info_buf[32];
+	u16					ht_info_len;
+
+	HT_SPEC_VER			ht_spec_ver;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	bool				aggregation;
+	bool				long_slot_time;
+}bss_ht, *pbss_ht;
+
+typedef enum _erp_t{
+	ERP_NonERPpresent	= 0x01,
+	ERP_UseProtection	= 0x02,
+	ERP_BarkerPreambleMode = 0x04,
+} erp_t;
+
+
+struct ieee80211_network {
+	/* These entries are used to identify a unique network */
+	u8 bssid[ETH_ALEN];
+	u8 channel;
+	/* Ensure null-terminated for any debug msgs */
+	u8 ssid[IW_ESSID_MAX_SIZE + 1];
+	u8 ssid_len;
+#if 1
+        struct ieee80211_qos_data qos_data;
+#else
+       // Qos related. Added by Annie, 2005-11-01.
+        BSS_QOS   BssQos;
+#endif
+
+	//added by amy for LEAP
+	bool	bWithAironetIE;
+	bool	bCkipSupported;
+	bool	bCcxRmEnable;
+	u16 	CcxRmState[2];
+	// CCXv4 S59, MBSSID.
+	bool	bMBssidValid;
+	u8	MBssidMask;
+	u8	MBssid[6];
+	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
+	bool	bWithCcxVerNum;
+	u8	BssCcxVerNumber;
+	/* These are network statistics */
+	struct ieee80211_rx_stats stats;
+	u16 capability;
+	u8  rates[MAX_RATES_LENGTH];
+	u8  rates_len;
+	u8  rates_ex[MAX_RATES_EX_LENGTH];
+	u8  rates_ex_len;
+	unsigned long last_scanned;
+	u8  mode;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8  erp_value;
+	u8  wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8  rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+
+        struct ieee80211_tim_parameters tim;
+	u8  dtim_period;
+	u8  dtim_data;
+	u32 last_dtim_sta_time[2];
+
+        //appeded for QoS
+        u8 wmm_info;
+        struct ieee80211_wmm_ac_param wmm_param[4];
+        u8 QoS_Enable;
+#ifdef THOMAS_TURBO
+	u8 Turbo_Enable;//enable turbo mode, added by thomas
+#endif
+#ifdef ENABLE_DOT11D
+	u16 CountryIeLen;
+	u8 CountryIeBuf[MAX_IE_LEN];
+#endif
+        // HT Related, by amy, 2008.04.29
+	BSS_HT	bssht;
+	// Add to handle broadcom AP management frame CCK rate.
+	bool broadcom_cap_exist;
+	bool ralink_cap_exist;
+	bool atheros_cap_exist;
+        bool cisco_cap_exist;
+        bool unknown_cap_exist;
+//	u8	berp_info;
+	bool	berp_info_valid;
+	bool buseprotection;
+	//put at the end of the structure.
+	struct list_head list;
+};
+
+#if 1
+enum ieee80211_state {
+
+	/* the card is not linked at all */
+	IEEE80211_NOLINK = 0,
+
+	/* IEEE80211_ASSOCIATING* are for BSS client mode
+	 * the driver shall not perform RX filtering unless
+	 * the state is LINKED.
+	 * The driver shall just check for the state LINKED and
+	 * defaults to NOLINK for ALL the other states (including
+	 * LINKED_SCANNING)
+	 */
+
+	/* the association procedure will start (wq scheduling)*/
+	IEEE80211_ASSOCIATING,
+	IEEE80211_ASSOCIATING_RETRY,
+
+	/* the association procedure is sending AUTH request*/
+	IEEE80211_ASSOCIATING_AUTHENTICATING,
+
+	/* the association procedure has successfully authentcated
+	 * and is sending association request
+	 */
+	IEEE80211_ASSOCIATING_AUTHENTICATED,
+
+	/* the link is ok. the card associated to a BSS or linked
+	 * to a ibss cell or acting as an AP and creating the bss
+	 */
+	IEEE80211_LINKED,
+
+	/* same as LINKED, but the driver shall apply RX filter
+	 * rules as we are in NO_LINK mode. As the card is still
+	 * logically linked, but it is doing a syncro site survey
+	 * then it will be back to LINKED state.
+	 */
+	IEEE80211_LINKED_SCANNING,
+
+};
+#else
+enum ieee80211_state {
+        IEEE80211_UNINITIALIZED = 0,
+        IEEE80211_INITIALIZED,
+        IEEE80211_ASSOCIATING,
+        IEEE80211_ASSOCIATED,
+        IEEE80211_AUTHENTICATING,
+        IEEE80211_AUTHENTICATED,
+        IEEE80211_SHUTDOWN
+};
+#endif
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+
+#define CFG_IEEE80211_RESERVE_FCS (1<<0)
+#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+                                  IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+                                  IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+typedef struct tx_pending_t{
+	int frag;
+	struct ieee80211_txb *txb;
+}tx_pending_t;
+
+typedef struct _bandwidth_autoswitch
+{
+	long threshold_20Mhzto40Mhz;
+	long	threshold_40Mhzto20Mhz;
+	bool bforced_tx20Mhz;
+	bool bautoswitch_enable;
+}bandwidth_autoswitch,*pbandwidth_autoswitch;
+
+
+//added by amy for order
+
+#define REORDER_WIN_SIZE	128
+#define REORDER_ENTRY_NUM	128
+typedef struct _RX_REORDER_ENTRY
+{
+	struct list_head	List;
+	u16			SeqNum;
+	struct ieee80211_rxb* prxb;
+} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
+//added by amy for order
+typedef enum _Fsync_State{
+	Default_Fsync,
+	HW_Fsync,
+	SW_Fsync
+}Fsync_State;
+
+// Power save mode configured.
+typedef	enum _RT_PS_MODE
+{
+	eActive,	// Active/Continuous access.
+	eMaxPs,		// Max power save mode.
+	eFastPs		// Fast power save mode.
+}RT_PS_MODE;
+
+typedef enum _IPS_CALLBACK_FUNCION
+{
+	IPS_CALLBACK_NONE = 0,
+	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
+	IPS_CALLBACK_JOIN_REQUEST = 2,
+}IPS_CALLBACK_FUNCION;
+
+typedef enum _RT_JOIN_ACTION{
+	RT_JOIN_INFRA   = 1,
+	RT_JOIN_IBSS  = 2,
+	RT_START_IBSS = 3,
+	RT_NO_ACTION  = 4,
+}RT_JOIN_ACTION;
+
+typedef struct _IbssParms{
+	u16   atimWin;
+}IbssParms, *PIbssParms;
+#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
+
+// RF state.
+typedef	enum _RT_RF_POWER_STATE
+{
+	eRfOn,
+	eRfSleep,
+	eRfOff
+}RT_RF_POWER_STATE;
+
+typedef struct _RT_POWER_SAVE_CONTROL
+{
+
+	//
+	// Inactive Power Save(IPS) : Disable RF when disconnected
+	//
+	bool				bInactivePs;
+	bool				bIPSModeBackup;
+	bool				bSwRfProcessing;
+	RT_RF_POWER_STATE	eInactivePowerState;
+	struct work_struct 	InactivePsWorkItem;
+	struct timer_list	InactivePsTimer;
+
+	// Return point for join action
+	IPS_CALLBACK_FUNCION	ReturnPoint;
+
+	// Recored Parameters for rescheduled JoinRequest
+	bool				bTmpBssDesc;
+	RT_JOIN_ACTION		tmpJoinAction;
+	struct ieee80211_network tmpBssDesc;
+
+	// Recored Parameters for rescheduled MgntLinkRequest
+	bool				bTmpScanOnly;
+	bool				bTmpActiveScan;
+	bool				bTmpFilterHiddenAP;
+	bool				bTmpUpdateParms;
+	u8					tmpSsidBuf[33];
+	OCTET_STRING			tmpSsid2Scan;
+	bool				bTmpSsid2Scan;
+	u8					tmpNetworkType;
+	u8					tmpChannelNumber;
+	u16					tmpBcnPeriod;
+	u8					tmpDtimPeriod;
+	u16					tmpmCap;
+	OCTET_STRING			tmpSuppRateSet;
+	u8					tmpSuppRateBuf[MAX_NUM_RATES];
+	bool				bTmpSuppRate;
+	IbssParms				tmpIbpm;
+	bool				bTmpIbpm;
+
+	//
+	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
+	//
+	bool				bLeisurePs;
+
+}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
+
+typedef u32 RT_RF_CHANGE_SOURCE;
+#define RF_CHANGE_BY_SW BIT31
+#define RF_CHANGE_BY_HW BIT30
+#define RF_CHANGE_BY_PS BIT29
+#define RF_CHANGE_BY_IPS BIT28
+#define RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
+
+#ifdef ENABLE_DOT11D
+typedef enum
+{
+	COUNTRY_CODE_FCC = 0,
+	COUNTRY_CODE_IC = 1,
+	COUNTRY_CODE_ETSI = 2,
+	COUNTRY_CODE_SPAIN = 3,
+	COUNTRY_CODE_FRANCE = 4,
+	COUNTRY_CODE_MKK = 5,
+	COUNTRY_CODE_MKK1 = 6,
+	COUNTRY_CODE_ISRAEL = 7,
+	COUNTRY_CODE_TELEC,
+	COUNTRY_CODE_MIC,
+	COUNTRY_CODE_GLOBAL_DOMAIN
+}country_code_type_t;
+#endif
+
+#define RT_MAX_LD_SLOT_NUM	10
+typedef struct _RT_LINK_DETECT_T{
+
+	u32				NumRecvBcnInPeriod;
+	u32				NumRecvDataInPeriod;
+
+	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
+	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
+	u16				SlotNum;	// number of CheckForHang period to determine link status
+	u16				SlotIndex;
+
+	u32				NumTxOkInPeriod;
+	u32				NumRxOkInPeriod;
+	bool				bBusyTraffic;
+}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+
+
+struct ieee80211_device {
+	struct net_device *dev;
+        struct ieee80211_security sec;
+
+	//hw security related
+//	u8 hwsec_support; //support?
+	u8 hwsec_active;  //hw security active.
+	bool is_silent_reset;
+	bool is_roaming;
+	bool ieee_up;
+	//added by amy
+	bool bSupportRemoteWakeUp;
+	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
+	bool actscanning;
+	bool beinretry;
+	RT_RF_POWER_STATE		eRFPowerState;
+	RT_RF_CHANGE_SOURCE	RfOffReason;
+	bool is_set_key;
+	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
+
+	//11n HT below
+	PRT_HIGH_THROUGHPUT	pHTInfo;
+	//struct timer_list		SwBwTimer;
+//	spinlock_t chnlop_spinlock;
+	spinlock_t bw_spinlock;
+
+	spinlock_t reorder_spinlock;
+	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
+	//the way fill this is the same as in the IE
+	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
+	u8	dot11HTOperationalRateSet[16];		//use RATR format
+	u8	RegHTSuppRateSet[16];
+	u8				HTCurrentOperaRate;
+	u8				HTHighestOperaRate;
+	//wb added for rate operation mode to firmware
+	u8	bTxDisableRateFallBack;
+	u8 	bTxUseDriverAssingedRate;
+	atomic_t	atm_chnlop;
+	atomic_t	atm_swbw;
+//	u8	HTHighestOperaRate;
+//	u8 	HTCurrentOperaRate;
+
+	// 802.11e and WMM Traffic Stream Info (TX)
+	struct list_head		Tx_TS_Admit_List;
+	struct list_head		Tx_TS_Pending_List;
+	struct list_head		Tx_TS_Unused_List;
+	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
+	// 802.11e and WMM Traffic Stream Info (RX)
+	struct list_head		Rx_TS_Admit_List;
+	struct list_head		Rx_TS_Pending_List;
+	struct list_head		Rx_TS_Unused_List;
+	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
+//#ifdef TO_DO_LIST
+	RX_REORDER_ENTRY	RxReorderEntry[128];
+	struct list_head		RxReorder_Unused_List;
+//#endif
+	// Qos related. Added by Annie, 2005-11-01.
+//	PSTA_QOS			pStaQos;
+	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
+
+
+	/* Bookkeeping structures */
+	struct net_device_stats stats;
+	struct ieee80211_stats ieee_stats;
+	struct ieee80211_softmac_stats softmac_stats;
+
+	/* Probe / Beacon management */
+	struct list_head network_free_list;
+	struct list_head network_list;
+	struct ieee80211_network *networks;
+	int scans;
+	int scan_age;
+
+	int iw_mode; /* operating mode (IW_MODE_*) */
+	struct iw_spy_data spy_data;
+
+	spinlock_t lock;
+	spinlock_t wpax_suitlist_lock;
+
+	int tx_headroom; /* Set to size of any additional room needed at front
+			  * of allocated Tx SKBs */
+	u32 config;
+
+	/* WEP and other encryption related settings at the device level */
+	int open_wep; /* Set to 1 to allow unencrypted frames */
+	int auth_mode;
+	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+				 * WEP key changes */
+
+	/* If the host performs {en,de}cryption, then set to 1 */
+	int host_encrypt;
+	int host_encrypt_msdu;
+	int host_decrypt;
+        /* host performs multicast decryption */
+        int host_mc_decrypt;
+
+        /* host should strip IV and ICV from protected frames */
+        /* meaningful only when hardware decryption is being used */
+        int host_strip_iv_icv;
+
+        int host_open_frag;
+        int host_build_iv;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	bool bHalfWirelessN24GMode;
+	int wpa_enabled;
+	int drop_unencrypted;
+	int tkip_countermeasures;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+	u8 ap_mac_addr[6];
+	u16 pairwise_key_type;
+	u16 group_key_type;
+	struct list_head crypt_deinit_list;
+	struct ieee80211_crypt_data *crypt[WEP_KEYS];
+	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+	struct timer_list crypt_deinit_timer;
+        int crypt_quiesced;
+
+	int bcrx_sta_key; /* use individual keys to override default keys even
+			   * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	// each streaming contain a entry
+	struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx[17];
+	u16 fts; /* Fragmentation Threshold */
+#define DEFAULT_RTS_THRESHOLD 2346U
+#define MIN_RTS_THRESHOLD 1
+#define MAX_RTS_THRESHOLD 2346U
+        u16 rts; /* RTS threshold */
+
+        /* Association info */
+        u8 bssid[ETH_ALEN];
+
+	/* This stores infos for the current network.
+	 * Either the network we are associated in INFRASTRUCTURE
+	 * or the network that we are creating in MASTER mode.
+	 * ad-hoc is a mixture ;-).
+	 * Note that in infrastructure mode, even when not associated,
+	 * fields bssid and essid may be valid (if wpa_set and essid_set
+	 * are true) as thy carry the value set by the user via iwconfig
+	 */
+	struct ieee80211_network current_network;
+
+	enum ieee80211_state state;
+
+	int short_slot;
+	int reg_mode;
+	int mode;       /* A, B, G */
+	int modulation; /* CCK, OFDM */
+	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
+	int abg_true;   /* ABG flag              */
+
+	/* used for forcing the ibss workqueue to terminate
+	 * without wait for the syncro scan to terminate
+	 */
+	short sync_scan_hurryup;
+
+        int perfect_rssi;
+        int worst_rssi;
+
+        u16 prev_seq_ctl;       /* used to drop duplicate frames */
+
+	/* map of allowed channels. 0 is dummy */
+	// FIXME: remeber to default to a basic channel plan depending of the PHY type
+#ifdef ENABLE_DOT11D
+	void* pDot11dInfo;
+	bool bGlobalDomain;
+#else
+	int channel_map[MAX_CHANNEL_NUMBER+1];
+#endif
+	int rate;       /* current rate */
+	int basic_rate;
+	//FIXME: pleace callback, see if redundant with softmac_features
+	short active_scan;
+
+	/* this contains flags for selectively enable softmac support */
+	u16 softmac_features;
+
+	/* if the sequence control field is not filled by HW */
+	u16 seq_ctrl[5];
+
+	/* association procedure transaction sequence number */
+	u16 associate_seq;
+
+	/* AID for RTXed association responses */
+	u16 assoc_id;
+
+	/* power save mode related*/
+	u8 ack_tx_to_ieee;
+	short ps;
+	short sta_sleep;
+	int ps_timeout;
+	int ps_period;
+	struct tasklet_struct ps_task;
+	u32 ps_th;
+	u32 ps_tl;
+
+	short raw_tx;
+	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
+	short queue_stop;
+	short scanning;
+	short proto_started;
+
+	struct semaphore wx_sem;
+	struct semaphore scan_sem;
+
+	spinlock_t mgmt_tx_lock;
+	spinlock_t beacon_lock;
+
+	short beacon_txing;
+
+	short wap_set;
+	short ssid_set;
+
+	u8  wpax_type_set;    //{added by David, 2006.9.28}
+	u32 wpax_type_notify; //{added by David, 2006.9.26}
+
+	/* QoS related flag */
+	char init_wmmparam_flag;
+	/* set on initialization */
+	u8  qos_support;
+
+	/* for discarding duplicated packets in IBSS */
+	struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
+
+	/* for discarding duplicated packets in BSS */
+	u16 last_rxseq_num[17]; /* rx seq previous per-tid */
+	u16 last_rxfrag_num[17];/* tx frag previous per-tid */
+	unsigned long last_packet_time[17];
+
+	/* for PS mode */
+	unsigned long last_rx_ps_time;
+
+	/* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
+	struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
+	int mgmt_queue_head;
+	int mgmt_queue_tail;
+//{ added for rtl819x
+#define IEEE80211_QUEUE_LIMIT 128
+	u8 AsocRetryCount;
+	unsigned int hw_header;
+	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE];
+	u32	sta_edca_param[4];
+	bool aggregation;
+	// Enable/Disable Rx immediate BA capability.
+	bool enable_rx_imm_BA;
+	bool bibsscoordinator;
+
+	//+by amy for DM ,080515
+	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
+	bool	bdynamic_txpower_enable;
+
+	bool bCTSToSelfEnable;
+	u8 	CTSToSelfTH;
+
+	u32 	fsync_time_interval;
+	u32	fsync_rate_bitmap;
+	u8	fsync_rssi_threshold;
+	bool	bfsync_enable;
+
+	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval
+	u32	fsync_firstdiff_ratethreshold;		// low threshold
+	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
+	Fsync_State			fsync_state;
+	bool		bis_any_nonbepkts;
+	//20Mhz 40Mhz AutoSwitch Threshold
+	bandwidth_autoswitch bandwidth_auto_switch;
+	//for txpower tracking
+	bool FwRWRF;
+
+	//added by amy for AP roaming
+	RT_LINK_DETECT_T	LinkDetectInfo;
+        //added by amy for ps
+	RT_POWER_SAVE_CONTROL	PowerSaveControl;
+//}
+	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
+	struct  tx_pending_t tx_pending;
+
+	/* used if IEEE_SOFTMAC_ASSOCIATE is set */
+	struct timer_list associate_timer;
+
+	/* used if IEEE_SOFTMAC_BEACONS is set */
+	struct timer_list beacon_timer;
+
+        struct work_struct associate_complete_wq;
+        struct work_struct associate_procedure_wq;
+        struct delayed_work softmac_scan_wq;
+        struct delayed_work associate_retry_wq;
+	 struct delayed_work start_ibss_wq;
+	 struct delayed_work hw_wakeup_wq;
+	struct delayed_work hw_sleep_wq;
+        struct work_struct wx_sync_scan_wq;
+        struct workqueue_struct *wq;
+        // Qos related. Added by Annie, 2005-11-01.
+        //STA_QOS  StaQos;
+
+        //u32 STA_EDCA_PARAM[4];
+	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
+
+
+	/* Callback functions */
+	void (*set_security)(struct net_device *dev,
+			     struct ieee80211_security *sec);
+
+	/* Used to TX data frame by using txb structs.
+	 * this is not used if in the softmac_features
+	 * is set the flag IEEE_SOFTMAC_TX_QUEUE
+	 */
+	int (*hard_start_xmit)(struct ieee80211_txb *txb,
+			       struct net_device *dev);
+
+	int (*reset_port)(struct net_device *dev);
+        int (*is_queue_full) (struct net_device * dev, int pri);
+
+        int (*handle_management) (struct net_device * dev,
+                                  struct ieee80211_network * network, u16 type);
+        int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* Softmac-generated frames (mamagement) are TXed via this
+	 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
+	 * not set. As some cards may have different HW queues that
+	 * one might want to use for data and management frames
+	 * the option to have two callbacks might be useful.
+	 * This fucntion can't sleep.
+	 */
+	int (*softmac_hard_start_xmit)(struct sk_buff *skb,
+			       struct net_device *dev);
+
+	/* used instead of hard_start_xmit (not softmac_hard_start_xmit)
+	 * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
+	 * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
+	 * then also management frames are sent via this callback.
+	 * This function can't sleep.
+	 */
+	void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
+			       struct net_device *dev,int rate);
+
+	/* stops the HW queue for DATA frames. Useful to avoid
+	 * waste time to TX data frame when we are reassociating
+	 * This function can sleep.
+	 */
+	void (*data_hard_stop)(struct net_device *dev);
+
+	/* OK this is complementar to data_poll_hard_stop */
+	void (*data_hard_resume)(struct net_device *dev);
+
+	/* ask to the driver to retune the radio .
+	 * This function can sleep. the driver should ensure
+	 * the radio has been swithced before return.
+	 */
+	void (*set_chan)(struct net_device *dev,short ch);
+
+	/* These are not used if the ieee stack takes care of
+	 * scanning (IEEE_SOFTMAC_SCAN feature set).
+	 * In this case only the set_chan is used.
+	 *
+	 * The syncro version is similar to the start_scan but
+	 * does not return until all channels has been scanned.
+	 * this is called in user context and should sleep,
+	 * it is called in a work_queue when swithcing to ad-hoc mode
+	 * or in behalf of iwlist scan when the card is associated
+	 * and root user ask for a scan.
+	 * the fucntion stop_scan should stop both the syncro and
+	 * background scanning and can sleep.
+	 * The fucntion start_scan should initiate the background
+	 * scanning and can't sleep.
+	 */
+	void (*scan_syncro)(struct net_device *dev);
+	void (*start_scan)(struct net_device *dev);
+	void (*stop_scan)(struct net_device *dev);
+
+	/* indicate the driver that the link state is changed
+	 * for example it may indicate the card is associated now.
+	 * Driver might be interested in this to apply RX filter
+	 * rules or simply light the LINK led
+	 */
+	void (*link_change)(struct net_device *dev);
+
+	/* these two function indicates to the HW when to start
+	 * and stop to send beacons. This is used when the
+	 * IEEE_SOFTMAC_BEACONS is not set. For now the
+	 * stop_send_bacons is NOT guaranteed to be called only
+	 * after start_send_beacons.
+	 */
+	void (*start_send_beacons) (struct net_device *dev);
+	void (*stop_send_beacons) (struct net_device *dev);
+
+	/* power save mode related */
+	void (*sta_wake_up) (struct net_device *dev);
+//	void (*ps_request_tx_ack) (struct net_device *dev);
+	void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
+	short (*ps_is_queue_empty) (struct net_device *dev);
+#if 0
+	/* Typical STA methods */
+        int (*handle_auth) (struct net_device * dev,
+                            struct ieee80211_auth * auth);
+        int (*handle_deauth) (struct net_device * dev,
+                              struct ieee80211_deauth * auth);
+        int (*handle_action) (struct net_device * dev,
+                              struct ieee80211_action * action,
+                              struct ieee80211_rx_stats * stats);
+        int (*handle_disassoc) (struct net_device * dev,
+                                struct ieee80211_disassoc * assoc);
+#endif
+        int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
+#if 0
+        int (*handle_probe_response) (struct net_device * dev,
+                                      struct ieee80211_probe_response * resp,
+                                      struct ieee80211_network * network);
+        int (*handle_probe_request) (struct net_device * dev,
+                                     struct ieee80211_probe_request * req,
+                                     struct ieee80211_rx_stats * stats);
+#endif
+        int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
+
+#if 0
+        /* Typical AP methods */
+        int (*handle_assoc_request) (struct net_device * dev);
+        int (*handle_reassoc_request) (struct net_device * dev,
+                                       struct ieee80211_reassoc_request * req);
+#endif
+
+	/* check whether Tx hw resouce available */
+	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
+	//added by wb for HT related
+//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
+	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
+	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
+	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
+	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev);
+	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
+
+	/* This must be the last item so that it points to the data
+	 * allocated beyond this structure by alloc_ieee80211 */
+	u8 priv[0];
+};
+
+#define IEEE_A            (1<<0)
+#define IEEE_B            (1<<1)
+#define IEEE_G            (1<<2)
+#define IEEE_N_24G 		  (1<<4)
+#define	IEEE_N_5G		  (1<<5)
+#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
+
+/* Generate a 802.11 header */
+
+/* Uses the channel change callback directly
+ * instead of [start/stop] scan callbacks
+ */
+#define IEEE_SOFTMAC_SCAN (1<<2)
+
+/* Perform authentication and association handshake */
+#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
+
+/* Generate probe requests */
+#define IEEE_SOFTMAC_PROBERQ (1<<4)
+
+/* Generate respones to probe requests */
+#define IEEE_SOFTMAC_PROBERS (1<<5)
+
+/* The ieee802.11 stack will manages the netif queue
+ * wake/stop for the driver, taking care of 802.11
+ * fragmentation. See softmac.c for details. */
+#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
+
+/* Uses only the softmac_data_hard_start_xmit
+ * even for TX management frames.
+ */
+#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
+
+/* Generate beacons.  The stack will enqueue beacons
+ * to the card
+ */
+#define IEEE_SOFTMAC_BEACONS (1<<6)
+
+static inline void *ieee80211_priv(struct net_device *dev)
+{
+	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+}
+
+extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+{
+	/* Single white space is for Linksys APs */
+	if (essid_len == 1 && essid[0] == ' ')
+		return 1;
+
+	/* Otherwise, if the entire essid is 0, we assume it is hidden */
+	while (essid_len) {
+		essid_len--;
+		if (essid[essid_len] != '\0')
+			return 0;
+	}
+
+	return 1;
+}
+
+extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+{
+	/*
+	 * It is possible for both access points and our device to support
+	 * combinations of modes, so as long as there is one valid combination
+	 * of ap/device supported modes, then return success
+	 *
+	 */
+	if ((mode & IEEE_A) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_G) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_B) &&
+	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	return 0;
+}
+
+extern inline int ieee80211_get_hdrlen(u16 fc)
+{
+	int hdrlen = IEEE80211_3ADDR_LEN;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */
+		if(IEEE80211_QOS_HAS_SEQ(fc))
+			hdrlen += 2; /* QOS ctrl*/
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (WLAN_FC_GET_STYPE(fc)) {
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+        switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+        case IEEE80211_1ADDR_LEN:
+                return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+        case IEEE80211_2ADDR_LEN:
+                return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+        case IEEE80211_3ADDR_LEN:
+                return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+        case IEEE80211_4ADDR_LEN:
+                return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+        }
+        return NULL;
+}
+
+static inline int ieee80211_is_ofdm_rate(u8 rate)
+{
+        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+        case IEEE80211_OFDM_RATE_6MB:
+        case IEEE80211_OFDM_RATE_9MB:
+        case IEEE80211_OFDM_RATE_12MB:
+        case IEEE80211_OFDM_RATE_18MB:
+        case IEEE80211_OFDM_RATE_24MB:
+        case IEEE80211_OFDM_RATE_36MB:
+        case IEEE80211_OFDM_RATE_48MB:
+        case IEEE80211_OFDM_RATE_54MB:
+                return 1;
+        }
+        return 0;
+}
+
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+        case IEEE80211_CCK_RATE_1MB:
+        case IEEE80211_CCK_RATE_2MB:
+        case IEEE80211_CCK_RATE_5MB:
+        case IEEE80211_CCK_RATE_11MB:
+                return 1;
+        }
+        return 0;
+}
+
+
+/* ieee80211.c */
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
+
+extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+
+/* ieee80211_tx.c */
+
+extern int ieee80211_encrypt_fragment(
+	struct ieee80211_device *ieee,
+	struct sk_buff *frag,
+	int hdr_len);
+
+extern int ieee80211_xmit(struct sk_buff *skb,
+			  struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+
+/* ieee80211_rx.c */
+extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats);
+extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+			     struct ieee80211_hdr_4addr *header,
+			     struct ieee80211_rx_stats *stats);
+
+/* ieee80211_wx.c */
+extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+#if WIRELESS_EXT >= 18
+extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               struct iw_param *data, char *extra);
+extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra);
+#endif
+extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
+
+/* ieee80211_softmac.c */
+extern short ieee80211_is_54g(struct ieee80211_network net);
+extern short ieee80211_is_shortslot(struct ieee80211_network net);
+extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats, u16 type,
+			u16 stype);
+extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
+
+void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
+extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
+extern void ieee80211_start_bss(struct ieee80211_device *ieee);
+extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
+extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
+extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
+extern void ieee80211_disassociate(struct ieee80211_device *ieee);
+extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
+extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
+extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
+extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
+extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
+extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
+extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
+extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
+extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
+extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
+
+extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
+
+/* ieee80211_crypt_ccmp&tkip&wep.c */
+extern void ieee80211_tkip_null(void);
+extern void ieee80211_wep_null(void);
+extern void ieee80211_ccmp_null(void);
+
+/* ieee80211_softmac_wx.c */
+
+extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *ext);
+
+extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
+			 struct iw_request_info *info,
+			 union iwreq_data *awrq,
+			 char *extra);
+
+extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
+
+extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
+			      struct iw_request_info *a,
+			      union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
+extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
+
+
+extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+//HT
+#define MAX_RECEIVE_BUFFER_SIZE 9100  //
+extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
+extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
+
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
+extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
+extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
+extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
+extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
+extern void HTOnAssocRsp(struct ieee80211_device *ieee);
+extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
+extern void HTInitializeBssDesc(PBSS_HT pBssHT);
+extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
+extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
+extern u8 MCS_FILTER_ALL[];
+extern u16 MCS_DATA_RATE[2][2][77] ;
+extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
+//extern void HTSetConnectBwModeCallback(unsigned long data);
+extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
+extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
+extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
+extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
+extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
+//function in BAPROC.c
+extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
+extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
+extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+extern void BaSetupTimeOut(unsigned long data);
+extern void TxBaInactTimeout(unsigned long data);
+extern void RxBaInactTimeout(unsigned long data);
+extern void ResetBaEntry( PBA_RECORD pBA);
+//function in TS.c
+extern bool GetTs(
+        struct ieee80211_device*        ieee,
+        PTS_COMMON_INFO                 *ppTS,
+        u8*                             Addr,
+        u8                              TID,
+        TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
+        bool                            bAddNewTs
+        );
+extern void TSInitialize(struct ieee80211_device *ieee);
+extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);
+extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
+extern void RemoveAllTS(struct ieee80211_device* ieee);
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
+
+extern const long ieee80211_wlan_frequencies[];
+
+extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+{
+	ieee->scans++;
+}
+
+extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+{
+	return ieee->scans;
+}
+
+static inline const char *escape_essid(const char *essid, u8 essid_len) {
+	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+	const char *s = essid;
+	char *d = escaped;
+
+	if (ieee80211_is_empty_essid(essid, essid_len)) {
+		memcpy(escaped, "<hidden>", sizeof("<hidden>"));
+		return escaped;
+	}
+
+	essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
+	while (essid_len--) {
+		if (*s == '\0') {
+			*d++ = '\\';
+			*d++ = '0';
+			s++;
+		} else {
+			*d++ = *s++;
+		}
+	}
+	*d = '\0';
+	return escaped;
+}
+
+/* For the function is more related to hardware setting, it's better to use the
+ * ieee handler to refer to it.
+ */
+extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
+extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element,
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats);
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+#define RT_ASOC_RETRY_LIMIT	5
+#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192e/ieee80211/dot11d.c b/drivers/staging/rtl8192e/ieee80211/dot11d.c
new file mode 100644
index 0000000..908f605
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/dot11d.c
@@ -0,0 +1,239 @@
+#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);
+#if 0
+	if(!pDot11dInfo->bEnabled)
+		return;
+#endif
+	// 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;
+
+	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");
+			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");
+			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;
+}
+
+
+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 (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,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);
+#else
+EXPORT_SYMBOL_NOVERS(Dot11d_Init);
+EXPORT_SYMBOL_NOVERS(Dot11d_Reset);
+EXPORT_SYMBOL_NOVERS(Dot11d_UpdateCountryIe);
+EXPORT_SYMBOL_NOVERS(DOT11D_GetMaxTxPwrInDbm);
+EXPORT_SYMBOL_NOVERS(DOT11D_ScanComplete);
+EXPORT_SYMBOL_NOVERS(IsLegalChannel);
+EXPORT_SYMBOL_NOVERS(ToLegalChannel);
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/dot11d.h b/drivers/staging/rtl8192e/ieee80211/dot11d.h
new file mode 100644
index 0000000..15b7a4b
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/dot11d.h
@@ -0,0 +1,102 @@
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#ifdef ENABLE_DOT11D
+#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 //ENABLE_DOT11D
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
new file mode 100644
index 0000000..83c8452
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211.h
@@ -0,0 +1,2802 @@
+/*
+ * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
+ * remains copyright by the original authors
+ *
+ * Portions of the merged code are based on Host AP (software wireless
+ * LAN access point) driver for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * Modified for Realtek's wi-fi cards by Andrea Merello
+ * <andreamrl@tiscali.it>
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+#ifndef IEEE80211_H
+#define IEEE80211_H
+#include <linux/if_ether.h> /* ETH_ALEN */
+#include <linux/kernel.h>   /* ARRAY_SIZE */
+#include <linux/version.h>
+#include <linux/module.h>
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#include <linux/jiffies.h>
+#else
+#include <linux/jffs.h>
+#include <linux/tqueue.h>
+#endif
+#include <linux/timer.h>
+#include <linux/sched.h>
+
+#include <linux/delay.h>
+#include <linux/wireless.h>
+
+#include "rtl819x_HT.h"
+#include "rtl819x_BA.h"
+#include "rtl819x_TS.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
+#ifndef bool
+typedef enum{false = 0, true} bool;
+#endif
+#endif
+
+#ifndef IW_MODE_MONITOR
+#define IW_MODE_MONITOR 6
+#endif
+
+#ifndef IWEVCUSTOM
+#define IWEVCUSTOM 0x8c02
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#ifndef __bitwise
+#define __bitwise __attribute__((bitwise))
+#endif
+typedef __u16  __le16;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27))
+struct iw_spy_data{
+	/* --- Standard spy support --- */
+	int 			spy_number;
+	u_char 			spy_address[IW_MAX_SPY][ETH_ALEN];
+	struct iw_quality	spy_stat[IW_MAX_SPY];
+	/* --- Enhanced spy support (event) */
+	struct iw_quality	spy_thr_low; /* Low threshold */
+	struct iw_quality	spy_thr_high; /* High threshold */
+	u_char			spy_thr_under[IW_MAX_SPY];
+};
+#endif
+#endif
+
+#ifndef container_of
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr:        the pointer to the member.
+ * @type:       the type of the container struct this is embedded in.
+ * @member:     the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({                      \
+        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+        (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#define KEY_TYPE_NA		0x0
+#define KEY_TYPE_WEP40 		0x1
+#define KEY_TYPE_TKIP		0x2
+#define KEY_TYPE_CCMP		0x4
+#define KEY_TYPE_WEP104		0x5
+
+/* added for rtl819x tx procedure */
+#define MAX_QUEUE_SIZE		0x10
+
+//
+// 8190 queue mapping
+//
+#define BK_QUEUE                               0
+#define BE_QUEUE                               1
+#define VI_QUEUE                               2
+#define VO_QUEUE                               3
+#define HCCA_QUEUE                             4
+#define TXCMD_QUEUE                            5
+#define MGNT_QUEUE                             6
+#define HIGH_QUEUE                             7
+#define BEACON_QUEUE                           8
+
+#define LOW_QUEUE                              BE_QUEUE
+#define NORMAL_QUEUE                           MGNT_QUEUE
+
+//added by amy for ps
+#define SWRF_TIMEOUT				50
+
+//added by amy for LEAP related
+#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
+#define SUPPORT_CKIP_MIC			0x08	// bit3
+#define SUPPORT_CKIP_PK			0x10	// bit4
+/* defined for skb cb field */
+/* At most 28 byte */
+typedef struct cb_desc {
+        /* Tx Desc Related flags (8-9) */
+	u8 bLastIniPkt:1;
+	u8 bCmdOrInit:1;
+        u8 bFirstSeg:1;
+        u8 bLastSeg:1;
+        u8 bEncrypt:1;
+        u8 bTxDisableRateFallBack:1;
+        u8 bTxUseDriverAssingedRate:1;
+        u8 bHwSec:1; //indicate whether use Hw security. WB
+
+        u8 reserved1;
+
+        /* Tx Firmware Relaged flags (10-11)*/
+        u8 bCTSEnable:1;
+        u8 bRTSEnable:1;
+        u8 bUseShortGI:1;
+        u8 bUseShortPreamble:1;
+        u8 bTxEnableFwCalcDur:1;
+        u8 bAMPDUEnable:1;
+        u8 bRTSSTBC:1;
+        u8 RTSSC:1;
+
+        u8 bRTSBW:1;
+        u8 bPacketBW:1;
+	u8 bRTSUseShortPreamble:1;
+	u8 bRTSUseShortGI:1;
+	u8 bMulticast:1;
+	u8 bBroadcast:1;
+        //u8 reserved2:2;
+        u8 drv_agg_enable:1;
+        u8 reserved2:1;
+
+        /* Tx Desc related element(12-19) */
+        u8 rata_index;
+        u8 queue_index;
+        //u8 reserved3;
+        //u8 reserved4;
+        u16 txbuf_size;
+        //u8 reserved5;
+	u8 RATRIndex;
+        u8 reserved6;
+        u8 reserved7;
+        u8 reserved8;
+
+        /* Tx firmware related element(20-27) */
+        u8 data_rate;
+        u8 rts_rate;
+        u8 ampdu_factor;
+        u8 ampdu_density;
+        //u8 reserved9;
+        //u8 reserved10;
+        //u8 reserved11;
+        u8 DrvAggrNum;
+	u16 pkt_size;
+        u8 reserved12;
+}cb_desc, *pcb_desc;
+
+/*--------------------------Define -------------------------------------------*/
+#define MGN_1M                  0x02
+#define MGN_2M                  0x04
+#define MGN_5_5M                0x0b
+#define MGN_11M                 0x16
+
+#define MGN_6M                  0x0c
+#define MGN_9M                  0x12
+#define MGN_12M                 0x18
+#define MGN_18M                 0x24
+#define MGN_24M                 0x30
+#define MGN_36M                 0x48
+#define MGN_48M                 0x60
+#define MGN_54M                 0x6c
+
+#define MGN_MCS0                0x80
+#define MGN_MCS1                0x81
+#define MGN_MCS2                0x82
+#define MGN_MCS3                0x83
+#define MGN_MCS4                0x84
+#define MGN_MCS5                0x85
+#define MGN_MCS6                0x86
+#define MGN_MCS7                0x87
+#define MGN_MCS8                0x88
+#define MGN_MCS9                0x89
+#define MGN_MCS10               0x8a
+#define MGN_MCS11               0x8b
+#define MGN_MCS12               0x8c
+#define MGN_MCS13               0x8d
+#define MGN_MCS14               0x8e
+#define MGN_MCS15               0x8f
+
+//----------------------------------------------------------------------------
+//		802.11 Management frame Reason Code field
+//----------------------------------------------------------------------------
+enum	_ReasonCode{
+	unspec_reason	= 0x1,
+	auth_not_valid	= 0x2,
+	deauth_lv_ss	= 0x3,
+	inactivity		= 0x4,
+	ap_overload 	= 0x5,
+	class2_err		= 0x6,
+	class3_err		= 0x7,
+	disas_lv_ss 	= 0x8,
+	asoc_not_auth	= 0x9,
+
+	//----MIC_CHECK
+	mic_failure 	= 0xe,
+	//----END MIC_CHECK
+
+	// Reason code defined in 802.11i D10.0 p.28.
+	invalid_IE		= 0x0d,
+	four_way_tmout	= 0x0f,
+	two_way_tmout	= 0x10,
+	IE_dismatch 	= 0x11,
+	invalid_Gcipher = 0x12,
+	invalid_Pcipher = 0x13,
+	invalid_AKMP	= 0x14,
+	unsup_RSNIEver = 0x15,
+	invalid_RSNIE	= 0x16,
+	auth_802_1x_fail= 0x17,
+	ciper_reject		= 0x18,
+
+	// Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
+	QoS_unspec		= 0x20, // 32
+	QAP_bandwidth	= 0x21, // 33
+	poor_condition	= 0x22, // 34
+	no_facility 	= 0x23, // 35
+							// Where is 36???
+	req_declined	= 0x25, // 37
+	invalid_param	= 0x26, // 38
+	req_not_honored= 0x27,	// 39
+	TS_not_created	= 0x2F, // 47
+	DL_not_allowed	= 0x30, // 48
+	dest_not_exist	= 0x31, // 49
+	dest_not_QSTA	= 0x32, // 50
+};
+
+
+
+#define aSifsTime	 (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10)
+
+#define MGMT_QUEUE_NUM 5
+
+#define IEEE_CMD_SET_WPA_PARAM			1
+#define	IEEE_CMD_SET_WPA_IE			2
+#define IEEE_CMD_SET_ENCRYPTION			3
+#define IEEE_CMD_MLME				4
+
+#define IEEE_PARAM_WPA_ENABLED			1
+#define IEEE_PARAM_TKIP_COUNTERMEASURES		2
+#define IEEE_PARAM_DROP_UNENCRYPTED		3
+#define IEEE_PARAM_PRIVACY_INVOKED		4
+#define IEEE_PARAM_AUTH_ALGS			5
+#define IEEE_PARAM_IEEE_802_1X			6
+//It should consistent with the driver_XXX.c
+//   David, 2006.9.26
+#define IEEE_PARAM_WPAX_SELECT			7
+//Added for notify the encryption type selection
+//   David, 2006.9.26
+#define IEEE_PROTO_WPA				1
+#define IEEE_PROTO_RSN				2
+//Added for notify the encryption type selection
+//   David, 2006.9.26
+#define IEEE_WPAX_USEGROUP			0
+#define IEEE_WPAX_WEP40				1
+#define IEEE_WPAX_TKIP				2
+#define IEEE_WPAX_WRAP   			3
+#define IEEE_WPAX_CCMP				4
+#define IEEE_WPAX_WEP104			5
+
+#define IEEE_KEY_MGMT_IEEE8021X			1
+#define IEEE_KEY_MGMT_PSK			2
+
+#define IEEE_MLME_STA_DEAUTH			1
+#define IEEE_MLME_STA_DISASSOC			2
+
+
+#define IEEE_CRYPT_ERR_UNKNOWN_ALG		2
+#define IEEE_CRYPT_ERR_UNKNOWN_ADDR		3
+#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED	4
+#define IEEE_CRYPT_ERR_KEY_SET_FAILED		5
+#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED	6
+#define IEEE_CRYPT_ERR_CARD_CONF_FAILED		7
+
+
+#define	IEEE_CRYPT_ALG_NAME_LEN			16
+
+#define MAX_IE_LEN  0xff
+
+// added for kernel conflict
+#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
+#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
+#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
+#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
+#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
+#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
+
+#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
+
+#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
+
+#define ieee80211_wep_null		ieee80211_wep_null_rsl
+
+#define free_ieee80211          	free_ieee80211_rsl
+#define alloc_ieee80211        		alloc_ieee80211_rsl
+
+#define ieee80211_rx 			ieee80211_rx_rsl
+#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
+
+#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
+#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
+#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
+#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
+#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
+#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
+#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
+#define ieee80211_is_54g		ieee80211_is_54g_rsl
+#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
+#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
+#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
+#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
+#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
+#define SendDisassociation		SendDisassociation_rsl
+#define ieee80211_disassociate		ieee80211_disassociate_rsl
+#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
+#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
+#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
+#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
+#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
+
+#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
+#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
+#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
+#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
+#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
+#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
+#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl
+#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
+#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
+#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
+#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
+#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
+#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
+#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
+#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
+#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
+#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
+#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
+
+#define ieee80211_txb_free		ieee80211_txb_free_rsl
+
+#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
+#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
+#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
+#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
+#if WIRELESS_EXT >= 18
+#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
+#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
+#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
+#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
+#endif
+
+
+typedef struct ieee_param {
+	u32 cmd;
+	u8 sta_addr[ETH_ALEN];
+        union {
+		struct {
+			u8 name;
+			u32 value;
+		} wpa_param;
+		struct {
+			u32 len;
+			u8 reserved[32];
+			u8 data[0];
+		} wpa_ie;
+	        struct{
+			int command;
+    			int reason_code;
+		} mlme;
+		struct {
+			u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
+			u8 set_tx;
+			u32 err;
+			u8 idx;
+			u8 seq[8]; /* sequence counter (set: RX, get: TX) */
+			u16 key_len;
+			u8 key[0];
+		} crypt;
+	} u;
+}ieee_param;
+
+
+#if WIRELESS_EXT < 17
+#define IW_QUAL_QUAL_INVALID   0x10
+#define IW_QUAL_LEVEL_INVALID  0x20
+#define IW_QUAL_NOISE_INVALID  0x40
+#define IW_QUAL_QUAL_UPDATED   0x1
+#define IW_QUAL_LEVEL_UPDATED  0x2
+#define IW_QUAL_NOISE_UPDATED  0x4
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
+{
+	task->routine = func;
+	task->data 	= data;
+	//task->next = NULL;
+	INIT_LIST_HEAD(&task->list);
+	task->sync = 0;
+}
+#endif
+
+// linux under 2.6.9 release may not support it, so modify it for common use
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+//#define MSECS(t)	(1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
+#define MSECS(t)	(HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
+static inline unsigned long msleep_interruptible_rsl(unsigned int msecs)
+{
+         unsigned long timeout = MSECS(msecs) + 1;
+
+         while (timeout) {
+                 set_current_state(TASK_INTERRUPTIBLE);
+                 timeout = schedule_timeout(timeout);
+         }
+         return timeout;
+}
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
+static inline void msleep(unsigned int msecs)
+{
+         unsigned long timeout = MSECS(msecs) + 1;
+
+         while (timeout) {
+                 set_current_state(TASK_UNINTERRUPTIBLE);
+                 timeout = schedule_timeout(timeout);
+         }
+}
+#endif
+#else
+#define MSECS(t) msecs_to_jiffies(t)
+#define msleep_interruptible_rsl  msleep_interruptible
+#endif
+
+#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 IEEE80211_MGMT_HDR_LEN 24
+#define IEEE80211_DATA_HDR3_LEN 24
+#define IEEE80211_DATA_HDR4_LEN 30
+
+#define MIN_FRAG_THRESHOLD     256U
+#define MAX_FRAG_THRESHOLD     2346U
+
+
+/* Frame control field constants */
+#define IEEE80211_FCTL_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_FRAMETYPE	0x00fc
+#define IEEE80211_FCTL_TODS		0x0100
+#define IEEE80211_FCTL_FROMDS		0x0200
+#define IEEE80211_FCTL_DSTODS		0x0300 //added by david
+#define IEEE80211_FCTL_MOREFRAGS	0x0400
+#define IEEE80211_FCTL_RETRY		0x0800
+#define IEEE80211_FCTL_PM		0x1000
+#define IEEE80211_FCTL_MOREDATA		0x2000
+#define IEEE80211_FCTL_WEP		0x4000
+#define IEEE80211_FCTL_ORDER		0x8000
+
+#define IEEE80211_FTYPE_MGMT		0x0000
+#define IEEE80211_FTYPE_CTL		0x0004
+#define IEEE80211_FTYPE_DATA		0x0008
+
+/* management */
+#define IEEE80211_STYPE_ASSOC_REQ	0x0000
+#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
+#define IEEE80211_STYPE_REASSOC_REQ	0x0020
+#define IEEE80211_STYPE_REASSOC_RESP	0x0030
+#define IEEE80211_STYPE_PROBE_REQ	0x0040
+#define IEEE80211_STYPE_PROBE_RESP	0x0050
+#define IEEE80211_STYPE_BEACON		0x0080
+#define IEEE80211_STYPE_ATIM		0x0090
+#define IEEE80211_STYPE_DISASSOC	0x00A0
+#define IEEE80211_STYPE_AUTH		0x00B0
+#define IEEE80211_STYPE_DEAUTH		0x00C0
+#define IEEE80211_STYPE_MANAGE_ACT	0x00D0
+
+/* control */
+#define IEEE80211_STYPE_PSPOLL		0x00A0
+#define IEEE80211_STYPE_RTS		0x00B0
+#define IEEE80211_STYPE_CTS		0x00C0
+#define IEEE80211_STYPE_ACK		0x00D0
+#define IEEE80211_STYPE_CFEND		0x00E0
+#define IEEE80211_STYPE_CFENDACK	0x00F0
+#define IEEE80211_STYPE_BLOCKACK   0x0094
+
+/* data */
+#define IEEE80211_STYPE_DATA		0x0000
+#define IEEE80211_STYPE_DATA_CFACK	0x0010
+#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
+#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
+#define IEEE80211_STYPE_NULLFUNC	0x0040
+#define IEEE80211_STYPE_CFACK		0x0050
+#define IEEE80211_STYPE_CFPOLL		0x0060
+#define IEEE80211_STYPE_CFACKPOLL	0x0070
+#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
+#define IEEE80211_STYPE_QOS_NULL	0x00C0
+
+#define IEEE80211_SCTL_FRAG		0x000F
+#define IEEE80211_SCTL_SEQ		0xFFF0
+
+/* QOS control */
+#define IEEE80211_QCTL_TID              0x000F
+
+#define	FC_QOS_BIT					BIT7
+#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
+#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )
+//added by wb. Is this right?
+#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
+#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+#define SN_EQUAL(a, b)	(a == b)
+#define MAX_DEV_ADDR_SIZE 8
+typedef enum _ACT_CATEGORY{
+        ACT_CAT_QOS = 1,
+        ACT_CAT_DLS = 2,
+        ACT_CAT_BA  = 3,
+        ACT_CAT_HT  = 7,
+        ACT_CAT_WMM = 17,
+} ACT_CATEGORY, *PACT_CATEGORY;
+
+typedef enum _TS_ACTION{
+        ACT_ADDTSREQ = 0,
+        ACT_ADDTSRSP = 1,
+        ACT_DELTS    = 2,
+        ACT_SCHEDULE = 3,
+} TS_ACTION, *PTS_ACTION;
+
+typedef enum _BA_ACTION{
+        ACT_ADDBAREQ = 0,
+        ACT_ADDBARSP = 1,
+        ACT_DELBA    = 2,
+} BA_ACTION, *PBA_ACTION;
+
+typedef enum _InitialGainOpType{
+	IG_Backup=0,
+	IG_Restore,
+	IG_Max
+}InitialGainOpType;
+
+/* debug macros */
+#define CONFIG_IEEE80211_DEBUG
+#ifdef CONFIG_IEEE80211_DEBUG
+extern u32 ieee80211_debug_level;
+#define IEEE80211_DEBUG(level, fmt, args...) \
+do { if (ieee80211_debug_level & (level)) \
+  printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0)
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
+	do{ if ((ieee80211_debug_level & (level)) == (level))	\
+		{ 	\
+			int i;					\
+			u8* pdata = (u8*) data;			\
+			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
+			for(i=0; i<(int)(datalen); i++)			\
+			{						\
+				printk("%2x ", pdata[i]);		\
+				if ((i+1)%16 == 0) printk("\n");	\
+			}				\
+			printk("\n");			\
+		}					\
+	} while (0)
+#else
+#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
+#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif	/* CONFIG_IEEE80211_DEBUG */
+
+/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
+
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
+
+/*
+ * To use the debug system;
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IEEE80211_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry.  xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
+ * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/ipw/debug_level
+ *
+ * you simply need to add your entry to the ipw_debug_levels array.
+ *
+ * If you do not see debug_level in /proc/net/ipw then you do not have
+ * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IEEE80211_DL_INFO          (1<<0)
+#define IEEE80211_DL_WX            (1<<1)
+#define IEEE80211_DL_SCAN          (1<<2)
+#define IEEE80211_DL_STATE         (1<<3)
+#define IEEE80211_DL_MGMT          (1<<4)
+#define IEEE80211_DL_FRAG          (1<<5)
+#define IEEE80211_DL_EAP           (1<<6)
+#define IEEE80211_DL_DROP          (1<<7)
+
+#define IEEE80211_DL_TX            (1<<8)
+#define IEEE80211_DL_RX            (1<<9)
+
+#define IEEE80211_DL_HT		   (1<<10)  //HT
+#define IEEE80211_DL_BA		   (1<<11)  //ba
+#define IEEE80211_DL_TS		   (1<<12)  //TS
+#define IEEE80211_DL_QOS           (1<<13)
+#define IEEE80211_DL_REORDER	   (1<<14)
+#define IEEE80211_DL_IOT	   (1<<15)
+#define IEEE80211_DL_IPS	   (1<<16)
+#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
+#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
+#define IEEE80211_DL_ERR	   (1<<31)   //always open
+#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
+#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
+#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
+
+#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
+#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
+#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
+#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
+#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
+#define IEEE80211_DEBUG_EAP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
+#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
+#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
+#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
+#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
+
+#ifdef CONFIG_IEEE80211_DEBUG
+/* Added by Annie, 2005-11-22. */
+#define MAX_STR_LEN     64
+/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
+#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
+                        if((_Comp) & level)   							\
+                        {                                                                       \
+                                int             __i;                                            \
+                                u8  buffer[MAX_STR_LEN];                                    	\
+                                int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
+                                memset(buffer, 0, MAX_STR_LEN);                      		\
+                                memcpy(buffer, (u8 *)_Ptr, length );            		\
+                                for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
+                                {                                                               \
+                                     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
+                                }                                                               \
+                                buffer[length] = '\0';                                          \
+                                printk("Rtl819x: ");                                         	\
+                                printk(_TitleString);                                         \
+                                printk(": %d, <%s>\n", _Len, buffer);                         \
+                        }
+#else
+#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
+#endif
+
+#include <linux/netdevice.h>
+#include <linux/if_arp.h> /* ARPHRD_ETHER */
+
+#ifndef WIRELESS_SPY
+#define WIRELESS_SPY		// enable iwspy support
+#endif
+#include <net/iw_handler.h>	// new driver API
+
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
+
+#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
+
+#ifndef ETH_P_80211_RAW
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#endif
+
+/* IEEE 802.11 defines */
+
+#define P80211_OUI_LEN 3
+
+struct ieee80211_snap_hdr {
+
+        u8    dsap;   /* always 0xAA */
+        u8    ssap;   /* always 0xAA */
+        u8    ctrl;   /* always 0x03 */
+        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
+
+} __attribute__ ((packed));
+
+#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
+
+#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
+#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
+#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
+
+#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
+#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
+#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+
+/* Authentication algorithms */
+#define WLAN_AUTH_OPEN 0
+#define WLAN_AUTH_SHARED_KEY 1
+#define WLAN_AUTH_LEAP 2
+
+#define WLAN_AUTH_CHALLENGE_LEN 128
+
+#define WLAN_CAPABILITY_BSS (1<<0)
+#define WLAN_CAPABILITY_IBSS (1<<1)
+#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
+#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
+#define WLAN_CAPABILITY_PRIVACY (1<<4)
+#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
+#define WLAN_CAPABILITY_PBCC (1<<6)
+#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
+#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
+#define WLAN_CAPABILITY_QOS (1<<9)
+#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
+#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
+
+/* 802.11g ERP information element */
+#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
+#define WLAN_ERP_USE_PROTECTION (1<<1)
+#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
+
+/* Status codes */
+enum ieee80211_statuscode {
+        WLAN_STATUS_SUCCESS = 0,
+        WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
+        WLAN_STATUS_CAPS_UNSUPPORTED = 10,
+        WLAN_STATUS_REASSOC_NO_ASSOC = 11,
+        WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
+        WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
+        WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
+        WLAN_STATUS_CHALLENGE_FAIL = 15,
+        WLAN_STATUS_AUTH_TIMEOUT = 16,
+        WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
+        WLAN_STATUS_ASSOC_DENIED_RATES = 18,
+        /* 802.11b */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
+        WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
+        WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
+        /* 802.11h */
+        WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
+        WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
+        /* 802.11g */
+        WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
+        WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
+        /* 802.11i */
+        WLAN_STATUS_INVALID_IE = 40,
+        WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
+        WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
+        WLAN_STATUS_INVALID_AKMP = 43,
+        WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
+        WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
+        WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+};
+
+/* Reason codes */
+enum ieee80211_reasoncode {
+        WLAN_REASON_UNSPECIFIED = 1,
+        WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
+        WLAN_REASON_DEAUTH_LEAVING = 3,
+        WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
+        WLAN_REASON_DISASSOC_AP_BUSY = 5,
+        WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+        WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+        WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
+        WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+        /* 802.11h */
+        WLAN_REASON_DISASSOC_BAD_POWER = 10,
+        WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
+        /* 802.11i */
+        WLAN_REASON_INVALID_IE = 13,
+        WLAN_REASON_MIC_FAILURE = 14,
+        WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
+        WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
+        WLAN_REASON_IE_DIFFERENT = 17,
+        WLAN_REASON_INVALID_GROUP_CIPHER = 18,
+        WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
+        WLAN_REASON_INVALID_AKMP = 20,
+        WLAN_REASON_UNSUPP_RSN_VERSION = 21,
+        WLAN_REASON_INVALID_RSN_IE_CAP = 22,
+        WLAN_REASON_IEEE8021X_FAILED = 23,
+        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+};
+
+#define IEEE80211_STATMASK_SIGNAL (1<<0)
+#define IEEE80211_STATMASK_RSSI (1<<1)
+#define IEEE80211_STATMASK_NOISE (1<<2)
+#define IEEE80211_STATMASK_RATE (1<<3)
+#define IEEE80211_STATMASK_WEMASK 0x7
+
+#define IEEE80211_CCK_MODULATION    (1<<0)
+#define IEEE80211_OFDM_MODULATION   (1<<1)
+
+#define IEEE80211_24GHZ_BAND     (1<<0)
+#define IEEE80211_52GHZ_BAND     (1<<1)
+
+#define IEEE80211_CCK_RATE_LEN  		4
+#define IEEE80211_CCK_RATE_1MB		        0x02
+#define IEEE80211_CCK_RATE_2MB		        0x04
+#define IEEE80211_CCK_RATE_5MB		        0x0B
+#define IEEE80211_CCK_RATE_11MB		        0x16
+#define IEEE80211_OFDM_RATE_LEN 		8
+#define IEEE80211_OFDM_RATE_6MB		        0x0C
+#define IEEE80211_OFDM_RATE_9MB		        0x12
+#define IEEE80211_OFDM_RATE_12MB		0x18
+#define IEEE80211_OFDM_RATE_18MB		0x24
+#define IEEE80211_OFDM_RATE_24MB		0x30
+#define IEEE80211_OFDM_RATE_36MB		0x48
+#define IEEE80211_OFDM_RATE_48MB		0x60
+#define IEEE80211_OFDM_RATE_54MB		0x6C
+#define IEEE80211_BASIC_RATE_MASK		0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
+
+#define IEEE80211_CCK_RATES_MASK	        0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
+	IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
+        IEEE80211_CCK_RATE_5MB_MASK | \
+        IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
+	IEEE80211_OFDM_RATE_12MB_MASK | \
+	IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
+	IEEE80211_OFDM_RATE_9MB_MASK  | \
+	IEEE80211_OFDM_RATE_18MB_MASK | \
+	IEEE80211_OFDM_RATE_36MB_MASK | \
+	IEEE80211_OFDM_RATE_48MB_MASK | \
+	IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+                                IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+#define IEEE80211_NUM_OFDM_RATES	    8
+#define IEEE80211_NUM_CCK_RATES	            4
+#define IEEE80211_OFDM_SHIFT_MASK_A         4
+
+
+/* this is stolen and modified from the madwifi driver*/
+#define IEEE80211_FC0_TYPE_MASK		0x0c
+#define IEEE80211_FC0_TYPE_DATA		0x08
+#define IEEE80211_FC0_SUBTYPE_MASK	0xB0
+#define IEEE80211_FC0_SUBTYPE_QOS	0x80
+
+#define IEEE80211_QOS_HAS_SEQ(fc) \
+	(((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
+	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
+
+/* this is stolen from ipw2200 driver */
+#define IEEE_IBSS_MAC_HASH_SIZE 31
+struct ieee_ibss_seq {
+	u8 mac[ETH_ALEN];
+	u16 seq_num[17];
+	u16 frag_num[17];
+	unsigned long packet_time[17];
+	struct list_head list;
+};
+
+/* NOTE: This data is for statistical purposes; not all hardware provides this
+ *       information for frames received.  Not setting these will not cause
+ *       any adverse affects. */
+struct ieee80211_rx_stats {
+#if 1
+	u32 mac_time[2];
+	s8 rssi;
+	u8 signal;
+	u8 noise;
+	u16 rate; /* in 100 kbps */
+	u8 received_channel;
+	u8 control;
+	u8 mask;
+	u8 freq;
+	u16 len;
+	u64 tsf;
+	u32 beacon_time;
+	u8 nic_type;
+	u16       Length;
+	//      u8        DataRate;      // In 0.5 Mbps
+	u8        SignalQuality; // in 0-100 index.
+	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
+	s8        RxPower; // in dBm Translate from PWdB
+	u8        SignalStrength; // in 0-100 index.
+	u16       bHwError:1;
+	u16       bCRC:1;
+	u16       bICV:1;
+	u16       bShortPreamble:1;
+	u16       Antenna:1;      //for rtl8185
+	u16       Decrypted:1;    //for rtl8185, rtl8187
+	u16       Wakeup:1;       //for rtl8185
+	u16       Reserved0:1;    //for rtl8185
+	u8        AGC;
+	u32       TimeStampLow;
+	u32       TimeStampHigh;
+	bool      bShift;
+	bool      bIsQosData;             // Added by Annie, 2005-12-22.
+	u8        UserPriority;
+
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+	u8        RxDrvInfoSize;
+	u8        RxBufShift;
+	bool      bIsAMPDU;
+	bool      bFirstMPDU;
+	bool      bContainHTC;
+	bool      RxIs40MHzPacket;
+	u32       RxPWDBAll;
+	u8        RxMIMOSignalStrength[4];        // in 0~100 index
+	s8        RxMIMOSignalQuality[2];
+	bool      bPacketMatchBSSID;
+	bool      bIsCCK;
+	bool      bPacketToSelf;
+	//added by amy
+	u8*       virtual_address;
+	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
+	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
+	u16          fragoffset;                        // Data offset for this fragment
+	u16          ntotalfrag;
+	bool      	  bisrxaggrsubframe;
+	bool		  bPacketBeacon;	//cosa add for rssi
+	bool		  bToSelfBA;		//cosa add for rssi
+	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
+	u16		  Seq_Num;
+#endif
+
+};
+
+/* IEEE 802.11 requires that STA supports concurrent reception of at least
+ * three fragmented frames. This define can be increased to support more
+ * concurrent frames, but it should be noted that each entry can consume about
+ * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
+#define IEEE80211_FRAG_CACHE_LEN 4
+
+struct ieee80211_frag_entry {
+	unsigned long first_frag_time;
+	unsigned int seq;
+	unsigned int last_frag;
+	struct sk_buff *skb;
+	u8 src_addr[ETH_ALEN];
+	u8 dst_addr[ETH_ALEN];
+};
+
+struct ieee80211_stats {
+	unsigned int tx_unicast_frames;
+	unsigned int tx_multicast_frames;
+	unsigned int tx_fragments;
+	unsigned int tx_unicast_octets;
+	unsigned int tx_multicast_octets;
+	unsigned int tx_deferred_transmissions;
+	unsigned int tx_single_retry_frames;
+	unsigned int tx_multiple_retry_frames;
+	unsigned int tx_retry_limit_exceeded;
+	unsigned int tx_discards;
+	unsigned int rx_unicast_frames;
+	unsigned int rx_multicast_frames;
+	unsigned int rx_fragments;
+	unsigned int rx_unicast_octets;
+	unsigned int rx_multicast_octets;
+	unsigned int rx_fcs_errors;
+	unsigned int rx_discards_no_buffer;
+	unsigned int tx_discards_wrong_sa;
+	unsigned int rx_discards_undecryptable;
+	unsigned int rx_message_in_msg_fragments;
+	unsigned int rx_message_in_bad_msg_fragments;
+};
+
+struct ieee80211_device;
+
+#include "ieee80211_crypt.h"
+
+#define SEC_KEY_1         (1<<0)
+#define SEC_KEY_2         (1<<1)
+#define SEC_KEY_3         (1<<2)
+#define SEC_KEY_4         (1<<3)
+#define SEC_ACTIVE_KEY    (1<<4)
+#define SEC_AUTH_MODE     (1<<5)
+#define SEC_UNICAST_GROUP (1<<6)
+#define SEC_LEVEL         (1<<7)
+#define SEC_ENABLED       (1<<8)
+#define SEC_ENCRYPT       (1<<9)
+
+#define SEC_LEVEL_0      0 /* None */
+#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
+#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
+#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
+#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
+
+#define SEC_ALG_NONE            0
+#define SEC_ALG_WEP             1
+#define SEC_ALG_TKIP            2
+#define SEC_ALG_CCMP            3
+
+#define WEP_KEYS 		4
+#define WEP_KEY_LEN		13
+#define SCM_KEY_LEN             32
+#define SCM_TEMPORAL_KEY_LENGTH 16
+
+struct ieee80211_security {
+	u16 active_key:2,
+            enabled:1,
+	    auth_mode:2,
+            auth_algo:4,
+            unicast_uses_group:1,
+	    encrypt:1;
+	u8 key_sizes[WEP_KEYS];
+	u8 keys[WEP_KEYS][SCM_KEY_LEN];
+	u8 level;
+	u16 flags;
+} __attribute__ ((packed));
+
+
+/*
+ 802.11 data frame from AP
+      ,-------------------------------------------------------------------.
+Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
+      |------|------|---------|---------|---------|------|---------|------|
+Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
+      |      | tion | (BSSID) |         |         | ence |  data   |      |
+      `-------------------------------------------------------------------'
+Total: 28-2340 bytes
+*/
+
+/* Management Frame Information Element Types */
+enum ieee80211_mfie {
+        MFIE_TYPE_SSID = 0,
+        MFIE_TYPE_RATES = 1,
+        MFIE_TYPE_FH_SET = 2,
+        MFIE_TYPE_DS_SET = 3,
+        MFIE_TYPE_CF_SET = 4,
+        MFIE_TYPE_TIM = 5,
+        MFIE_TYPE_IBSS_SET = 6,
+        MFIE_TYPE_COUNTRY = 7,
+        MFIE_TYPE_HOP_PARAMS = 8,
+        MFIE_TYPE_HOP_TABLE = 9,
+        MFIE_TYPE_REQUEST = 10,
+        MFIE_TYPE_CHALLENGE = 16,
+        MFIE_TYPE_POWER_CONSTRAINT = 32,
+        MFIE_TYPE_POWER_CAPABILITY = 33,
+        MFIE_TYPE_TPC_REQUEST = 34,
+        MFIE_TYPE_TPC_REPORT = 35,
+        MFIE_TYPE_SUPP_CHANNELS = 36,
+        MFIE_TYPE_CSA = 37,
+        MFIE_TYPE_MEASURE_REQUEST = 38,
+        MFIE_TYPE_MEASURE_REPORT = 39,
+        MFIE_TYPE_QUIET = 40,
+        MFIE_TYPE_IBSS_DFS = 41,
+        MFIE_TYPE_ERP = 42,
+        MFIE_TYPE_RSN = 48,
+        MFIE_TYPE_RATES_EX = 50,
+        MFIE_TYPE_HT_CAP= 45,
+	 MFIE_TYPE_HT_INFO= 61,
+	 MFIE_TYPE_AIRONET=133,
+        MFIE_TYPE_GENERIC = 221,
+        MFIE_TYPE_QOS_PARAMETER = 222,
+};
+
+/* Minimal header; can be used for passing 802.11 frames with sufficient
+ * information to determine what type of underlying data type is actually
+ * stored in the data. */
+struct ieee80211_hdr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_1addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_2addr {
+        __le16 frame_ctl;
+        __le16 duration_id;
+        u8 addr1[ETH_ALEN];
+        u8 addr2[ETH_ALEN];
+        u8 payload[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_hdr_4addr {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_4addrqos {
+	__le16 frame_ctl;
+	__le16 duration_id;
+	u8 addr1[ETH_ALEN];
+	u8 addr2[ETH_ALEN];
+	u8 addr3[ETH_ALEN];
+	__le16 seq_ctl;
+	u8 addr4[ETH_ALEN];
+        u8 payload[0];
+	__le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct ieee80211_info_element {
+	u8 id;
+	u8 len;
+	u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_authentication {
+	struct ieee80211_hdr_3addr header;
+	__le16 algorithm;
+	__le16 transaction;
+	__le16 status;
+	/*challenge*/
+	struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+        struct ieee80211_hdr_3addr header;
+        __le16 reason;
+} __attribute__ ((packed));
+
+struct ieee80211_probe_request {
+	struct ieee80211_hdr_3addr header;
+	/* SSID, supported rates */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+	struct ieee80211_hdr_3addr header;
+	u32 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_request_frame {
+	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_reassoc_request_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 listen_interval;
+	u8 current_ap[ETH_ALEN];
+	/* SSID, supported rates, RSN */
+        struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_response_frame {
+	struct ieee80211_hdr_3addr header;
+	__le16 capability;
+	__le16 status;
+	__le16 aid;
+	struct ieee80211_info_element info_element[0]; /* supported rates */
+} __attribute__ ((packed));
+
+struct ieee80211_txb {
+	u8 nr_frags;
+	u8 encrypted;
+	u8 queue_index;
+	u8 rts_included;
+	u16 reserved;
+	__le16 frag_size;
+	__le16 payload_size;
+	struct sk_buff *fragments[0];
+};
+
+#define MAX_TX_AGG_COUNT		  16
+struct ieee80211_drv_agg_txb {
+	u8 nr_drv_agg_frames;
+	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
+}__attribute__((packed));
+
+#define MAX_SUBFRAME_COUNT 		  64
+struct ieee80211_rxb {
+	u8 nr_subframes;
+	struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+}__attribute__((packed));
+
+typedef union _frameqos {
+	u16 shortdata;
+	u8  chardata[2];
+	struct {
+		u16 tid:4;
+		u16 eosp:1;
+		u16 ack_policy:2;
+		u16 reserved:1;
+		u16 txop:8;
+	}field;
+}frameqos,*pframeqos;
+
+/* SWEEP TABLE ENTRIES NUMBER*/
+#define MAX_SWEEP_TAB_ENTRIES		  42
+#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
+/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
+ * only use 8, and then use extended rates for the remaining supported
+ * rates.  Other APs, however, stick all of their supported rates on the
+ * main rates information element... */
+#define MAX_RATES_LENGTH                  ((u8)12)
+#define MAX_RATES_EX_LENGTH               ((u8)16)
+#define MAX_NETWORK_COUNT                  128
+
+#define MAX_CHANNEL_NUMBER                 161
+#define IEEE80211_SOFTMAC_SCAN_TIME	   100
+//(HZ / 2)
+#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
+
+#define CRC_LENGTH                 4U
+
+#define MAX_WPA_IE_LEN 64
+
+#define NETWORK_EMPTY_ESSID (1<<0)
+#define NETWORK_HAS_OFDM    (1<<1)
+#define NETWORK_HAS_CCK     (1<<2)
+
+/* QoS structure */
+#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
+#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
+#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
+                                         NETWORK_HAS_QOS_INFORMATION)
+/* 802.11h */
+#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
+#define NETWORK_HAS_CSA                 (1<<6)
+#define NETWORK_HAS_QUIET               (1<<7)
+#define NETWORK_HAS_IBSS_DFS            (1<<8)
+#define NETWORK_HAS_TPC_REPORT          (1<<9)
+
+#define NETWORK_HAS_ERP_VALUE           (1<<10)
+
+#define QOS_QUEUE_NUM                   4
+#define QOS_OUI_LEN                     3
+#define QOS_OUI_TYPE                    2
+#define QOS_ELEMENT_ID                  221
+#define QOS_OUI_INFO_SUB_TYPE           0
+#define QOS_OUI_PARAM_SUB_TYPE          1
+#define QOS_VERSION_1                   1
+#define QOS_AIFSN_MIN_VALUE             2
+#if 1
+struct ieee80211_qos_information_element {
+        u8 elementID;
+        u8 length;
+        u8 qui[QOS_OUI_LEN];
+        u8 qui_type;
+        u8 qui_subtype;
+        u8 version;
+        u8 ac_info;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_ac_parameter {
+        u8 aci_aifsn;
+        u8 ecw_min_max;
+        __le16 tx_op_limit;
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameter_info {
+        struct ieee80211_qos_information_element info_element;
+        u8 reserved;
+        struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_parameters {
+        __le16 cw_min[QOS_QUEUE_NUM];
+        __le16 cw_max[QOS_QUEUE_NUM];
+        u8 aifs[QOS_QUEUE_NUM];
+        u8 flag[QOS_QUEUE_NUM];
+        __le16 tx_op_limit[QOS_QUEUE_NUM];
+} __attribute__ ((packed));
+
+struct ieee80211_qos_data {
+        struct ieee80211_qos_parameters parameters;
+        int active;
+        int supported;
+        u8 param_count;
+        u8 old_param_count;
+};
+
+struct ieee80211_tim_parameters {
+        u8 tim_count;
+        u8 tim_period;
+} __attribute__ ((packed));
+
+//#else
+struct ieee80211_wmm_ac_param {
+	u8 ac_aci_acm_aifsn;
+	u8 ac_ecwmin_ecwmax;
+	u16 ac_txop_limit;
+};
+
+struct ieee80211_wmm_ts_info {
+	u8 ac_dir_tid;
+	u8 ac_up_psb;
+	u8 reserved;
+} __attribute__ ((packed));
+
+struct ieee80211_wmm_tspec_elem {
+	struct ieee80211_wmm_ts_info ts_info;
+	u16 norm_msdu_size;
+	u16 max_msdu_size;
+	u32 min_serv_inter;
+	u32 max_serv_inter;
+	u32 inact_inter;
+	u32 suspen_inter;
+	u32 serv_start_time;
+	u32 min_data_rate;
+	u32 mean_data_rate;
+	u32 peak_data_rate;
+	u32 max_burst_size;
+	u32 delay_bound;
+	u32 min_phy_rate;
+	u16 surp_band_allow;
+	u16 medium_time;
+}__attribute__((packed));
+#endif
+enum eap_type {
+	EAP_PACKET = 0,
+	EAPOL_START,
+	EAPOL_LOGOFF,
+	EAPOL_KEY,
+	EAPOL_ENCAP_ASF_ALERT
+};
+
+static const char *eap_types[] = {
+	[EAP_PACKET]		= "EAP-Packet",
+	[EAPOL_START]		= "EAPOL-Start",
+	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
+	[EAPOL_KEY]		= "EAPOL-Key",
+	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
+};
+
+static inline const char *eap_get_type(int type)
+{
+	return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
+}
+//added by amy for reorder
+static inline u8 Frame_QoSTID(u8* buf)
+{
+	struct ieee80211_hdr_3addr *hdr;
+	u16 fc;
+	hdr = (struct ieee80211_hdr_3addr *)buf;
+	fc = le16_to_cpu(hdr->frame_ctl);
+	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
+}
+
+//added by amy for reorder
+
+struct eapol {
+	u8 snap[6];
+	u16 ethertype;
+	u8 version;
+	u8 type;
+	u16 length;
+} __attribute__ ((packed));
+
+struct ieee80211_softmac_stats{
+	unsigned int rx_ass_ok;
+	unsigned int rx_ass_err;
+	unsigned int rx_probe_rq;
+	unsigned int tx_probe_rs;
+	unsigned int tx_beacons;
+	unsigned int rx_auth_rq;
+	unsigned int rx_auth_rs_ok;
+	unsigned int rx_auth_rs_err;
+	unsigned int tx_auth_rq;
+	unsigned int no_auth_rs;
+	unsigned int no_ass_rs;
+	unsigned int tx_ass_rq;
+	unsigned int rx_ass_rq;
+	unsigned int tx_probe_rq;
+	unsigned int reassoc;
+	unsigned int swtxstop;
+	unsigned int swtxawake;
+	unsigned char CurrentShowTxate;
+	unsigned char last_packet_rate;
+	unsigned int txretrycount;
+};
+
+#define BEACON_PROBE_SSID_ID_POSITION 12
+
+struct ieee80211_info_element_hdr {
+	u8 id;
+	u8 len;
+} __attribute__ ((packed));
+
+/*
+ * These are the data types that can make up management packets
+ *
+	u16 auth_algorithm;
+	u16 auth_sequence;
+	u16 beacon_interval;
+	u16 capability;
+	u8 current_ap[ETH_ALEN];
+	u16 listen_interval;
+	struct {
+		u16 association_id:14, reserved:2;
+	} __attribute__ ((packed));
+	u32 time_stamp[2];
+	u16 reason;
+	u16 status;
+*/
+
+#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
+#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps
+
+enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
+#define MAX_SP_Len  (WMM_all_frame << 4)
+#define IEEE80211_QOS_TID 0x0f
+#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
+
+#define IEEE80211_DTIM_MBCAST 4
+#define IEEE80211_DTIM_UCAST 2
+#define IEEE80211_DTIM_VALID 1
+#define IEEE80211_DTIM_INVALID 0
+
+#define IEEE80211_PS_DISABLED 0
+#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
+#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
+
+//added by David for QoS 2006/6/30
+//#define WMM_Hang_8187
+#ifdef WMM_Hang_8187
+#undef WMM_Hang_8187
+#endif
+
+#define WME_AC_BK   0x00
+#define WME_AC_BE   0x01
+#define WME_AC_VI   0x02
+#define WME_AC_VO   0x03
+#define WME_ACI_MASK 0x03
+#define WME_AIFSN_MASK 0x03
+#define WME_AC_PRAM_LEN 16
+
+#define MAX_RECEIVE_BUFFER_SIZE 9100
+
+//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
+//#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1))
+#if 1
+#define UP2AC(up) (		   \
+	((up) < 1) ? WME_AC_BE : \
+	((up) < 3) ? WME_AC_BK : \
+	((up) < 4) ? WME_AC_BE : \
+	((up) < 6) ? WME_AC_VI : \
+	WME_AC_VO)
+#endif
+//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
+#define AC2UP(_ac)	(       \
+	((_ac) == WME_AC_VO) ? 6 : \
+	((_ac) == WME_AC_VI) ? 5 : \
+	((_ac) == WME_AC_BK) ? 1 : \
+	0)
+
+#define	ETHER_ADDR_LEN		6	/* length of an Ethernet address */
+#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
+
+struct	ether_header {
+	u8 ether_dhost[ETHER_ADDR_LEN];
+	u8 ether_shost[ETHER_ADDR_LEN];
+	u16 ether_type;
+} __attribute__((packed));
+
+#ifndef ETHERTYPE_PAE
+#define	ETHERTYPE_PAE	0x888e		/* EAPOL PAE/802.1x */
+#endif
+#ifndef ETHERTYPE_IP
+#define	ETHERTYPE_IP	0x0800		/* IP protocol */
+#endif
+
+typedef struct _bss_ht{
+
+	bool				support_ht;
+
+	// HT related elements
+	u8					ht_cap_buf[32];
+	u16					ht_cap_len;
+	u8					ht_info_buf[32];
+	u16					ht_info_len;
+
+	HT_SPEC_VER			ht_spec_ver;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	bool				aggregation;
+	bool				long_slot_time;
+}bss_ht, *pbss_ht;
+
+typedef enum _erp_t{
+	ERP_NonERPpresent	= 0x01,
+	ERP_UseProtection	= 0x02,
+	ERP_BarkerPreambleMode = 0x04,
+} erp_t;
+
+
+struct ieee80211_network {
+	/* These entries are used to identify a unique network */
+	u8 bssid[ETH_ALEN];
+	u8 channel;
+	/* Ensure null-terminated for any debug msgs */
+	u8 ssid[IW_ESSID_MAX_SIZE + 1];
+	u8 ssid_len;
+#if 1
+        struct ieee80211_qos_data qos_data;
+#else
+       // Qos related. Added by Annie, 2005-11-01.
+        BSS_QOS   BssQos;
+#endif
+
+	//added by amy for LEAP
+	bool	bWithAironetIE;
+	bool	bCkipSupported;
+	bool	bCcxRmEnable;
+	u16 	CcxRmState[2];
+	// CCXv4 S59, MBSSID.
+	bool	bMBssidValid;
+	u8	MBssidMask;
+	u8	MBssid[6];
+	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
+	bool	bWithCcxVerNum;
+	u8	BssCcxVerNumber;
+	/* These are network statistics */
+	struct ieee80211_rx_stats stats;
+	u16 capability;
+	u8  rates[MAX_RATES_LENGTH];
+	u8  rates_len;
+	u8  rates_ex[MAX_RATES_EX_LENGTH];
+	u8  rates_ex_len;
+	unsigned long last_scanned;
+	u8  mode;
+	u32 flags;
+	u32 last_associate;
+	u32 time_stamp[2];
+	u16 beacon_interval;
+	u16 listen_interval;
+	u16 atim_window;
+	u8  erp_value;
+	u8  wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8  rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
+
+        struct ieee80211_tim_parameters tim;
+	u8  dtim_period;
+	u8  dtim_data;
+	u32 last_dtim_sta_time[2];
+
+        //appeded for QoS
+        u8 wmm_info;
+        struct ieee80211_wmm_ac_param wmm_param[4];
+        u8 QoS_Enable;
+#ifdef THOMAS_TURBO
+	u8 Turbo_Enable;//enable turbo mode, added by thomas
+#endif
+#ifdef ENABLE_DOT11D
+	u16 CountryIeLen;
+	u8 CountryIeBuf[MAX_IE_LEN];
+#endif
+        // HT Related, by amy, 2008.04.29
+	BSS_HT	bssht;
+	// Add to handle broadcom AP management frame CCK rate.
+	bool broadcom_cap_exist;
+	bool ralink_cap_exist;
+	bool atheros_cap_exist;
+	bool cisco_cap_exist;
+	bool unknown_cap_exist;
+//	u8	berp_info;
+	bool	berp_info_valid;
+	bool buseprotection;
+	//put at the end of the structure.
+	struct list_head list;
+};
+
+#if 1
+enum ieee80211_state {
+
+	/* the card is not linked at all */
+	IEEE80211_NOLINK = 0,
+
+	/* IEEE80211_ASSOCIATING* are for BSS client mode
+	 * the driver shall not perform RX filtering unless
+	 * the state is LINKED.
+	 * The driver shall just check for the state LINKED and
+	 * defaults to NOLINK for ALL the other states (including
+	 * LINKED_SCANNING)
+	 */
+
+	/* the association procedure will start (wq scheduling)*/
+	IEEE80211_ASSOCIATING,
+	IEEE80211_ASSOCIATING_RETRY,
+
+	/* the association procedure is sending AUTH request*/
+	IEEE80211_ASSOCIATING_AUTHENTICATING,
+
+	/* the association procedure has successfully authentcated
+	 * and is sending association request
+	 */
+	IEEE80211_ASSOCIATING_AUTHENTICATED,
+
+	/* the link is ok. the card associated to a BSS or linked
+	 * to a ibss cell or acting as an AP and creating the bss
+	 */
+	IEEE80211_LINKED,
+
+	/* same as LINKED, but the driver shall apply RX filter
+	 * rules as we are in NO_LINK mode. As the card is still
+	 * logically linked, but it is doing a syncro site survey
+	 * then it will be back to LINKED state.
+	 */
+	IEEE80211_LINKED_SCANNING,
+
+};
+#else
+enum ieee80211_state {
+        IEEE80211_UNINITIALIZED = 0,
+        IEEE80211_INITIALIZED,
+        IEEE80211_ASSOCIATING,
+        IEEE80211_ASSOCIATED,
+        IEEE80211_AUTHENTICATING,
+        IEEE80211_AUTHENTICATED,
+        IEEE80211_SHUTDOWN
+};
+#endif
+
+#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
+#define DEFAULT_FTS 2346
+
+#define CFG_IEEE80211_RESERVE_FCS (1<<0)
+#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
+#define CFG_IEEE80211_RTS (1<<2)
+
+#define IEEE80211_24GHZ_MIN_CHANNEL 1
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
+#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
+                                  IEEE80211_24GHZ_MIN_CHANNEL + 1)
+
+#define IEEE80211_52GHZ_MIN_CHANNEL 34
+#define IEEE80211_52GHZ_MAX_CHANNEL 165
+#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
+                                  IEEE80211_52GHZ_MIN_CHANNEL + 1)
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
+extern inline int is_multicast_ether_addr(const u8 *addr)
+{
+        return ((addr[0] != 0xff) && (0x01 & addr[0]));
+}
+#endif
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
+extern inline int is_broadcast_ether_addr(const u8 *addr)
+{
+	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
+		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
+}
+#endif
+
+typedef struct tx_pending_t{
+	int frag;
+	struct ieee80211_txb *txb;
+}tx_pending_t;
+
+typedef struct _bandwidth_autoswitch
+{
+	long threshold_20Mhzto40Mhz;
+	long	threshold_40Mhzto20Mhz;
+	bool bforced_tx20Mhz;
+	bool bautoswitch_enable;
+}bandwidth_autoswitch,*pbandwidth_autoswitch;
+
+
+//added by amy for order
+
+#define REORDER_WIN_SIZE	128
+#define REORDER_ENTRY_NUM	128
+typedef struct _RX_REORDER_ENTRY
+{
+	struct list_head	List;
+	u16			SeqNum;
+	struct ieee80211_rxb* prxb;
+} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
+//added by amy for order
+typedef enum _Fsync_State{
+	Default_Fsync,
+	HW_Fsync,
+	SW_Fsync
+}Fsync_State;
+
+// Power save mode configured.
+typedef	enum _RT_PS_MODE
+{
+	eActive,	// Active/Continuous access.
+	eMaxPs,		// Max power save mode.
+	eFastPs		// Fast power save mode.
+}RT_PS_MODE;
+
+typedef enum _IPS_CALLBACK_FUNCION
+{
+	IPS_CALLBACK_NONE = 0,
+	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
+	IPS_CALLBACK_JOIN_REQUEST = 2,
+}IPS_CALLBACK_FUNCION;
+
+typedef enum _RT_JOIN_ACTION{
+	RT_JOIN_INFRA   = 1,
+	RT_JOIN_IBSS  = 2,
+	RT_START_IBSS = 3,
+	RT_NO_ACTION  = 4,
+}RT_JOIN_ACTION;
+
+typedef struct _IbssParms{
+	u16   atimWin;
+}IbssParms, *PIbssParms;
+#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
+
+// RF state.
+typedef	enum _RT_RF_POWER_STATE
+{
+	eRfOn,
+	eRfSleep,
+	eRfOff
+}RT_RF_POWER_STATE;
+
+typedef struct _RT_POWER_SAVE_CONTROL
+{
+
+	//
+	// Inactive Power Save(IPS) : Disable RF when disconnected
+	//
+	bool				bInactivePs;
+	bool				bIPSModeBackup;
+	bool				bSwRfProcessing;
+	RT_RF_POWER_STATE	eInactivePowerState;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	struct work_struct 	InactivePsWorkItem;
+#else
+	struct tq_struct	InactivePsWorkItem;
+#endif
+	struct timer_list	InactivePsTimer;
+
+	// Return point for join action
+	IPS_CALLBACK_FUNCION	ReturnPoint;
+
+	// Recored Parameters for rescheduled JoinRequest
+	bool				bTmpBssDesc;
+	RT_JOIN_ACTION		tmpJoinAction;
+	struct ieee80211_network tmpBssDesc;
+
+	// Recored Parameters for rescheduled MgntLinkRequest
+	bool				bTmpScanOnly;
+	bool				bTmpActiveScan;
+	bool				bTmpFilterHiddenAP;
+	bool				bTmpUpdateParms;
+	u8					tmpSsidBuf[33];
+	OCTET_STRING			tmpSsid2Scan;
+	bool				bTmpSsid2Scan;
+	u8					tmpNetworkType;
+	u8					tmpChannelNumber;
+	u16					tmpBcnPeriod;
+	u8					tmpDtimPeriod;
+	u16					tmpmCap;
+	OCTET_STRING			tmpSuppRateSet;
+	u8					tmpSuppRateBuf[MAX_NUM_RATES];
+	bool				bTmpSuppRate;
+	IbssParms				tmpIbpm;
+	bool				bTmpIbpm;
+
+	//
+	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
+	//
+	bool				bLeisurePs;
+
+}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
+
+typedef u32 RT_RF_CHANGE_SOURCE;
+#define RF_CHANGE_BY_SW BIT31
+#define RF_CHANGE_BY_HW BIT30
+#define RF_CHANGE_BY_PS BIT29
+#define RF_CHANGE_BY_IPS BIT28
+#define RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
+
+#ifdef ENABLE_DOT11D
+typedef enum
+{
+	COUNTRY_CODE_FCC = 0,
+	COUNTRY_CODE_IC = 1,
+	COUNTRY_CODE_ETSI = 2,
+	COUNTRY_CODE_SPAIN = 3,
+	COUNTRY_CODE_FRANCE = 4,
+	COUNTRY_CODE_MKK = 5,
+	COUNTRY_CODE_MKK1 = 6,
+	COUNTRY_CODE_ISRAEL = 7,
+	COUNTRY_CODE_TELEC,
+	COUNTRY_CODE_MIC,
+	COUNTRY_CODE_GLOBAL_DOMAIN
+}country_code_type_t;
+#endif
+
+#define RT_MAX_LD_SLOT_NUM	10
+typedef struct _RT_LINK_DETECT_T{
+
+	u32				NumRecvBcnInPeriod;
+	u32				NumRecvDataInPeriod;
+
+	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
+	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
+	u16				SlotNum;	// number of CheckForHang period to determine link status
+	u16				SlotIndex;
+
+	u32				NumTxOkInPeriod;
+	u32				NumRxOkInPeriod;
+	bool				bBusyTraffic;
+}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+
+
+struct ieee80211_device {
+	struct net_device *dev;
+        struct ieee80211_security sec;
+
+	//hw security related
+//	u8 hwsec_support; //support?
+	u8 hwsec_active;  //hw security active.
+	bool is_silent_reset;
+	bool is_roaming;
+	bool ieee_up;
+	//added by amy
+	bool bSupportRemoteWakeUp;
+	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
+	bool actscanning;
+	bool beinretry;
+	RT_RF_POWER_STATE		eRFPowerState;
+	RT_RF_CHANGE_SOURCE	RfOffReason;
+	bool is_set_key;
+	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
+
+	//11n HT below
+	PRT_HIGH_THROUGHPUT	pHTInfo;
+	//struct timer_list		SwBwTimer;
+//	spinlock_t chnlop_spinlock;
+	spinlock_t bw_spinlock;
+
+	spinlock_t reorder_spinlock;
+	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
+	//the way fill this is the same as in the IE
+	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
+	u8	dot11HTOperationalRateSet[16];		//use RATR format
+	u8	RegHTSuppRateSet[16];
+	u8				HTCurrentOperaRate;
+	u8				HTHighestOperaRate;
+	//wb added for rate operation mode to firmware
+	u8	bTxDisableRateFallBack;
+	u8 	bTxUseDriverAssingedRate;
+	atomic_t	atm_chnlop;
+	atomic_t	atm_swbw;
+//	u8	HTHighestOperaRate;
+//	u8 	HTCurrentOperaRate;
+
+	// 802.11e and WMM Traffic Stream Info (TX)
+	struct list_head		Tx_TS_Admit_List;
+	struct list_head		Tx_TS_Pending_List;
+	struct list_head		Tx_TS_Unused_List;
+	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
+	// 802.11e and WMM Traffic Stream Info (RX)
+	struct list_head		Rx_TS_Admit_List;
+	struct list_head		Rx_TS_Pending_List;
+	struct list_head		Rx_TS_Unused_List;
+	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
+//#ifdef TO_DO_LIST
+	RX_REORDER_ENTRY	RxReorderEntry[128];
+	struct list_head		RxReorder_Unused_List;
+//#endif
+	// Qos related. Added by Annie, 2005-11-01.
+//	PSTA_QOS			pStaQos;
+	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
+
+
+	/* Bookkeeping structures */
+	struct net_device_stats stats;
+	struct ieee80211_stats ieee_stats;
+	struct ieee80211_softmac_stats softmac_stats;
+
+	/* Probe / Beacon management */
+	struct list_head network_free_list;
+	struct list_head network_list;
+	struct ieee80211_network *networks;
+	int scans;
+	int scan_age;
+
+	int iw_mode; /* operating mode (IW_MODE_*) */
+	struct iw_spy_data spy_data;
+
+	spinlock_t lock;
+	spinlock_t wpax_suitlist_lock;
+
+	int tx_headroom; /* Set to size of any additional room needed at front
+			  * of allocated Tx SKBs */
+	u32 config;
+
+	/* WEP and other encryption related settings at the device level */
+	int open_wep; /* Set to 1 to allow unencrypted frames */
+	int auth_mode;
+	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
+				 * WEP key changes */
+
+	/* If the host performs {en,de}cryption, then set to 1 */
+	int host_encrypt;
+	int host_encrypt_msdu;
+	int host_decrypt;
+        /* host performs multicast decryption */
+        int host_mc_decrypt;
+
+        /* host should strip IV and ICV from protected frames */
+        /* meaningful only when hardware decryption is being used */
+        int host_strip_iv_icv;
+
+        int host_open_frag;
+        int host_build_iv;
+	int ieee802_1x; /* is IEEE 802.1X used */
+
+	/* WPA data */
+	bool bHalfWirelessN24GMode;
+	int wpa_enabled;
+	int drop_unencrypted;
+	int tkip_countermeasures;
+	int privacy_invoked;
+	size_t wpa_ie_len;
+	u8 *wpa_ie;
+	u8 ap_mac_addr[6];
+	u16 pairwise_key_type;
+	u16 group_key_type;
+	struct list_head crypt_deinit_list;
+	struct ieee80211_crypt_data *crypt[WEP_KEYS];
+	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
+	struct timer_list crypt_deinit_timer;
+        int crypt_quiesced;
+
+	int bcrx_sta_key; /* use individual keys to override default keys even
+			   * with RX of broad/multicast frames */
+
+	/* Fragmentation structures */
+	// each streaming contain a entry
+	struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
+	unsigned int frag_next_idx[17];
+	u16 fts; /* Fragmentation Threshold */
+#define DEFAULT_RTS_THRESHOLD 2346U
+#define MIN_RTS_THRESHOLD 1
+#define MAX_RTS_THRESHOLD 2346U
+        u16 rts; /* RTS threshold */
+
+        /* Association info */
+        u8 bssid[ETH_ALEN];
+
+	/* This stores infos for the current network.
+	 * Either the network we are associated in INFRASTRUCTURE
+	 * or the network that we are creating in MASTER mode.
+	 * ad-hoc is a mixture ;-).
+	 * Note that in infrastructure mode, even when not associated,
+	 * fields bssid and essid may be valid (if wpa_set and essid_set
+	 * are true) as thy carry the value set by the user via iwconfig
+	 */
+	struct ieee80211_network current_network;
+
+	enum ieee80211_state state;
+
+	int short_slot;
+	int reg_mode;
+	int mode;       /* A, B, G */
+	int modulation; /* CCK, OFDM */
+	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
+	int abg_true;   /* ABG flag              */
+
+	/* used for forcing the ibss workqueue to terminate
+	 * without wait for the syncro scan to terminate
+	 */
+	short sync_scan_hurryup;
+
+        int perfect_rssi;
+        int worst_rssi;
+
+        u16 prev_seq_ctl;       /* used to drop duplicate frames */
+
+	/* map of allowed channels. 0 is dummy */
+	// FIXME: remeber to default to a basic channel plan depending of the PHY type
+#ifdef ENABLE_DOT11D
+	void* pDot11dInfo;
+	bool bGlobalDomain;
+#else
+	int channel_map[MAX_CHANNEL_NUMBER+1];
+#endif
+	int rate;       /* current rate */
+	int basic_rate;
+	//FIXME: pleace callback, see if redundant with softmac_features
+	short active_scan;
+
+	/* this contains flags for selectively enable softmac support */
+	u16 softmac_features;
+
+	/* if the sequence control field is not filled by HW */
+	u16 seq_ctrl[5];
+
+	/* association procedure transaction sequence number */
+	u16 associate_seq;
+
+	/* AID for RTXed association responses */
+	u16 assoc_id;
+
+	/* power save mode related*/
+	u8 ack_tx_to_ieee;
+	short ps;
+	short sta_sleep;
+	int ps_timeout;
+	int ps_period;
+	struct tasklet_struct ps_task;
+	u32 ps_th;
+	u32 ps_tl;
+
+	short raw_tx;
+	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
+	short queue_stop;
+	short scanning;
+	short proto_started;
+
+	struct semaphore wx_sem;
+	struct semaphore scan_sem;
+
+	spinlock_t mgmt_tx_lock;
+	spinlock_t beacon_lock;
+
+	short beacon_txing;
+
+	short wap_set;
+	short ssid_set;
+
+	u8  wpax_type_set;    //{added by David, 2006.9.28}
+	u32 wpax_type_notify; //{added by David, 2006.9.26}
+
+	/* QoS related flag */
+	char init_wmmparam_flag;
+	/* set on initialization */
+	u8  qos_support;
+
+	/* for discarding duplicated packets in IBSS */
+	struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
+
+	/* for discarding duplicated packets in BSS */
+	u16 last_rxseq_num[17]; /* rx seq previous per-tid */
+	u16 last_rxfrag_num[17];/* tx frag previous per-tid */
+	unsigned long last_packet_time[17];
+
+	/* for PS mode */
+	unsigned long last_rx_ps_time;
+
+	/* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
+	struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
+	int mgmt_queue_head;
+	int mgmt_queue_tail;
+//{ added for rtl819x
+#define IEEE80211_QUEUE_LIMIT 128
+	u8 AsocRetryCount;
+	unsigned int hw_header;
+	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE];
+	u32	sta_edca_param[4];
+	bool aggregation;
+	// Enable/Disable Rx immediate BA capability.
+	bool enable_rx_imm_BA;
+	bool bibsscoordinator;
+
+	//+by amy for DM ,080515
+	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
+	bool	bdynamic_txpower_enable;
+
+	bool bCTSToSelfEnable;
+	u8 	CTSToSelfTH;
+
+	u32 	fsync_time_interval;
+	u32	fsync_rate_bitmap;
+	u8	fsync_rssi_threshold;
+	bool	bfsync_enable;
+
+	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval
+	u32	fsync_firstdiff_ratethreshold;		// low threshold
+	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
+	Fsync_State			fsync_state;
+	bool		bis_any_nonbepkts;
+	//20Mhz 40Mhz AutoSwitch Threshold
+	bandwidth_autoswitch bandwidth_auto_switch;
+	//for txpower tracking
+	bool FwRWRF;
+
+	//added by amy for AP roaming
+	RT_LINK_DETECT_T	LinkDetectInfo;
+        //added by amy for ps
+	RT_POWER_SAVE_CONTROL	PowerSaveControl;
+//}
+	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
+	struct  tx_pending_t tx_pending;
+
+	/* used if IEEE_SOFTMAC_ASSOCIATE is set */
+	struct timer_list associate_timer;
+
+	/* used if IEEE_SOFTMAC_BEACONS is set */
+	struct timer_list beacon_timer;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+        struct work_struct associate_complete_wq;
+        struct work_struct associate_procedure_wq;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+        struct delayed_work softmac_scan_wq;
+        struct delayed_work associate_retry_wq;
+	 struct delayed_work start_ibss_wq;
+	 struct delayed_work hw_wakeup_wq;
+	struct delayed_work hw_sleep_wq;
+#else
+        struct work_struct softmac_scan_wq;
+        struct work_struct associate_retry_wq;
+	struct work_struct start_ibss_wq;
+	struct work_struct hw_wakeup_wq;
+	struct work_struct hw_sleep_wq;
+#endif
+        struct work_struct wx_sync_scan_wq;
+        struct workqueue_struct *wq;
+#else
+	/* used for periodly scan */
+	struct timer_list scan_timer;
+
+	struct tq_struct associate_complete_wq;
+	struct tq_struct associate_retry_wq;
+	struct tq_struct start_ibss_wq;
+	struct tq_struct associate_procedure_wq;
+	struct tq_struct softmac_scan_wq;
+	struct tq_struct wx_sync_scan_wq;
+
+#endif
+        // Qos related. Added by Annie, 2005-11-01.
+        //STA_QOS  StaQos;
+
+        //u32 STA_EDCA_PARAM[4];
+	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
+
+
+	/* Callback functions */
+	void (*set_security)(struct net_device *dev,
+			     struct ieee80211_security *sec);
+
+	/* Used to TX data frame by using txb structs.
+	 * this is not used if in the softmac_features
+	 * is set the flag IEEE_SOFTMAC_TX_QUEUE
+	 */
+	int (*hard_start_xmit)(struct ieee80211_txb *txb,
+			       struct net_device *dev);
+
+	int (*reset_port)(struct net_device *dev);
+        int (*is_queue_full) (struct net_device * dev, int pri);
+
+        int (*handle_management) (struct net_device * dev,
+                                  struct ieee80211_network * network, u16 type);
+        int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+
+	/* Softmac-generated frames (mamagement) are TXed via this
+	 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
+	 * not set. As some cards may have different HW queues that
+	 * one might want to use for data and management frames
+	 * the option to have two callbacks might be useful.
+	 * This fucntion can't sleep.
+	 */
+	int (*softmac_hard_start_xmit)(struct sk_buff *skb,
+			       struct net_device *dev);
+
+	/* used instead of hard_start_xmit (not softmac_hard_start_xmit)
+	 * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
+	 * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
+	 * then also management frames are sent via this callback.
+	 * This function can't sleep.
+	 */
+	void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
+			       struct net_device *dev,int rate);
+
+	/* stops the HW queue for DATA frames. Useful to avoid
+	 * waste time to TX data frame when we are reassociating
+	 * This function can sleep.
+	 */
+	void (*data_hard_stop)(struct net_device *dev);
+
+	/* OK this is complementar to data_poll_hard_stop */
+	void (*data_hard_resume)(struct net_device *dev);
+
+	/* ask to the driver to retune the radio .
+	 * This function can sleep. the driver should ensure
+	 * the radio has been swithced before return.
+	 */
+	void (*set_chan)(struct net_device *dev,short ch);
+
+	/* These are not used if the ieee stack takes care of
+	 * scanning (IEEE_SOFTMAC_SCAN feature set).
+	 * In this case only the set_chan is used.
+	 *
+	 * The syncro version is similar to the start_scan but
+	 * does not return until all channels has been scanned.
+	 * this is called in user context and should sleep,
+	 * it is called in a work_queue when swithcing to ad-hoc mode
+	 * or in behalf of iwlist scan when the card is associated
+	 * and root user ask for a scan.
+	 * the fucntion stop_scan should stop both the syncro and
+	 * background scanning and can sleep.
+	 * The fucntion start_scan should initiate the background
+	 * scanning and can't sleep.
+	 */
+	void (*scan_syncro)(struct net_device *dev);
+	void (*start_scan)(struct net_device *dev);
+	void (*stop_scan)(struct net_device *dev);
+
+	/* indicate the driver that the link state is changed
+	 * for example it may indicate the card is associated now.
+	 * Driver might be interested in this to apply RX filter
+	 * rules or simply light the LINK led
+	 */
+	void (*link_change)(struct net_device *dev);
+
+	/* these two function indicates to the HW when to start
+	 * and stop to send beacons. This is used when the
+	 * IEEE_SOFTMAC_BEACONS is not set. For now the
+	 * stop_send_bacons is NOT guaranteed to be called only
+	 * after start_send_beacons.
+	 */
+	void (*start_send_beacons) (struct net_device *dev,u16 tx_rate);
+	void (*stop_send_beacons) (struct net_device *dev);
+
+	/* power save mode related */
+	void (*sta_wake_up) (struct net_device *dev);
+//	void (*ps_request_tx_ack) (struct net_device *dev);
+	void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
+	short (*ps_is_queue_empty) (struct net_device *dev);
+#if 0
+	/* Typical STA methods */
+        int (*handle_auth) (struct net_device * dev,
+                            struct ieee80211_auth * auth);
+        int (*handle_deauth) (struct net_device * dev,
+                              struct ieee80211_deauth * auth);
+        int (*handle_action) (struct net_device * dev,
+                              struct ieee80211_action * action,
+                              struct ieee80211_rx_stats * stats);
+        int (*handle_disassoc) (struct net_device * dev,
+                                struct ieee80211_disassoc * assoc);
+#endif
+        int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
+#if 0
+        int (*handle_probe_response) (struct net_device * dev,
+                                      struct ieee80211_probe_response * resp,
+                                      struct ieee80211_network * network);
+        int (*handle_probe_request) (struct net_device * dev,
+                                     struct ieee80211_probe_request * req,
+                                     struct ieee80211_rx_stats * stats);
+#endif
+        int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
+
+#if 0
+        /* Typical AP methods */
+        int (*handle_assoc_request) (struct net_device * dev);
+        int (*handle_reassoc_request) (struct net_device * dev,
+                                       struct ieee80211_reassoc_request * req);
+#endif
+
+	/* check whether Tx hw resouce available */
+	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
+	//added by wb for HT related
+//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
+	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
+//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
+	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
+	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
+	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev);
+	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
+
+	/* This must be the last item so that it points to the data
+	 * allocated beyond this structure by alloc_ieee80211 */
+	u8 priv[0];
+};
+
+#define IEEE_A            (1<<0)
+#define IEEE_B            (1<<1)
+#define IEEE_G            (1<<2)
+#define IEEE_N_24G 		  (1<<4)
+#define	IEEE_N_5G		  (1<<5)
+#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
+
+/* Generate a 802.11 header */
+
+/* Uses the channel change callback directly
+ * instead of [start/stop] scan callbacks
+ */
+#define IEEE_SOFTMAC_SCAN (1<<2)
+
+/* Perform authentication and association handshake */
+#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
+
+/* Generate probe requests */
+#define IEEE_SOFTMAC_PROBERQ (1<<4)
+
+/* Generate respones to probe requests */
+#define IEEE_SOFTMAC_PROBERS (1<<5)
+
+/* The ieee802.11 stack will manages the netif queue
+ * wake/stop for the driver, taking care of 802.11
+ * fragmentation. See softmac.c for details. */
+#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
+
+/* Uses only the softmac_data_hard_start_xmit
+ * even for TX management frames.
+ */
+#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
+
+/* Generate beacons.  The stack will enqueue beacons
+ * to the card
+ */
+#define IEEE_SOFTMAC_BEACONS (1<<6)
+
+static inline void *ieee80211_priv(struct net_device *dev)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
+#else
+	return ((struct ieee80211_device *)dev->priv)->priv;
+#endif
+}
+
+extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
+{
+	/* Single white space is for Linksys APs */
+	if (essid_len == 1 && essid[0] == ' ')
+		return 1;
+
+	/* Otherwise, if the entire essid is 0, we assume it is hidden */
+	while (essid_len) {
+		essid_len--;
+		if (essid[essid_len] != '\0')
+			return 0;
+	}
+
+	return 1;
+}
+
+extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
+{
+	/*
+	 * It is possible for both access points and our device to support
+	 * combinations of modes, so as long as there is one valid combination
+	 * of ap/device supported modes, then return success
+	 *
+	 */
+	if ((mode & IEEE_A) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_G) &&
+	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	if ((mode & IEEE_B) &&
+	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
+	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
+		return 1;
+
+	return 0;
+}
+
+extern inline int ieee80211_get_hdrlen(u16 fc)
+{
+	int hdrlen = IEEE80211_3ADDR_LEN;
+
+	switch (WLAN_FC_GET_TYPE(fc)) {
+	case IEEE80211_FTYPE_DATA:
+		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
+			hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */
+		if(IEEE80211_QOS_HAS_SEQ(fc))
+			hdrlen += 2; /* QOS ctrl*/
+		break;
+	case IEEE80211_FTYPE_CTL:
+		switch (WLAN_FC_GET_STYPE(fc)) {
+		case IEEE80211_STYPE_CTS:
+		case IEEE80211_STYPE_ACK:
+			hdrlen = IEEE80211_1ADDR_LEN;
+			break;
+		default:
+			hdrlen = IEEE80211_2ADDR_LEN;
+			break;
+		}
+		break;
+	}
+
+	return hdrlen;
+}
+
+static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+{
+        switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
+        case IEEE80211_1ADDR_LEN:
+                return ((struct ieee80211_hdr_1addr *)hdr)->payload;
+        case IEEE80211_2ADDR_LEN:
+                return ((struct ieee80211_hdr_2addr *)hdr)->payload;
+        case IEEE80211_3ADDR_LEN:
+                return ((struct ieee80211_hdr_3addr *)hdr)->payload;
+        case IEEE80211_4ADDR_LEN:
+                return ((struct ieee80211_hdr_4addr *)hdr)->payload;
+        }
+        return NULL;
+}
+
+static inline int ieee80211_is_ofdm_rate(u8 rate)
+{
+        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+        case IEEE80211_OFDM_RATE_6MB:
+        case IEEE80211_OFDM_RATE_9MB:
+        case IEEE80211_OFDM_RATE_12MB:
+        case IEEE80211_OFDM_RATE_18MB:
+        case IEEE80211_OFDM_RATE_24MB:
+        case IEEE80211_OFDM_RATE_36MB:
+        case IEEE80211_OFDM_RATE_48MB:
+        case IEEE80211_OFDM_RATE_54MB:
+                return 1;
+        }
+        return 0;
+}
+
+static inline int ieee80211_is_cck_rate(u8 rate)
+{
+        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
+        case IEEE80211_CCK_RATE_1MB:
+        case IEEE80211_CCK_RATE_2MB:
+        case IEEE80211_CCK_RATE_5MB:
+        case IEEE80211_CCK_RATE_11MB:
+                return 1;
+        }
+        return 0;
+}
+
+
+/* ieee80211.c */
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
+
+extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
+
+/* ieee80211_tx.c */
+
+extern int ieee80211_encrypt_fragment(
+	struct ieee80211_device *ieee,
+	struct sk_buff *frag,
+	int hdr_len);
+
+extern int ieee80211_xmit(struct sk_buff *skb,
+			  struct net_device *dev);
+extern void ieee80211_txb_free(struct ieee80211_txb *);
+
+
+/* ieee80211_rx.c */
+extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats);
+extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+			     struct ieee80211_hdr_4addr *header,
+			     struct ieee80211_rx_stats *stats);
+
+/* ieee80211_wx.c */
+extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+				   struct iw_request_info *info,
+				   union iwreq_data *wrqu, char *key);
+#if WIRELESS_EXT >= 18
+extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+                            struct iw_request_info *info,
+                            union iwreq_data* wrqu, char *extra);
+extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               struct iw_param *data, char *extra);
+extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra);
+#endif
+extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
+
+/* ieee80211_softmac.c */
+extern short ieee80211_is_54g(struct ieee80211_network net);
+extern short ieee80211_is_shortslot(struct ieee80211_network net);
+extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats, u16 type,
+			u16 stype);
+extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
+
+void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
+extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
+
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
+extern void ieee80211_start_bss(struct ieee80211_device *ieee);
+extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
+extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
+extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
+extern void ieee80211_disassociate(struct ieee80211_device *ieee);
+extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
+extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
+extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
+extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
+extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
+extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
+extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
+extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
+extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
+extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
+extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
+extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
+extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
+
+extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
+
+/* ieee80211_crypt_ccmp&tkip&wep.c */
+extern void ieee80211_tkip_null(void);
+extern void ieee80211_wep_null(void);
+extern void ieee80211_ccmp_null(void);
+
+/* ieee80211_softmac_wx.c */
+
+extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *ext);
+
+extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
+			 struct iw_request_info *info,
+			 union iwreq_data *awrq,
+			 char *extra);
+
+extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
+
+extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
+			      struct iw_request_info *a,
+			      union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b);
+
+//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
+#else
+ extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
+#endif
+
+
+extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+
+extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra);
+//HT
+#define MAX_RECEIVE_BUFFER_SIZE 9100  //
+extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
+extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
+
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
+extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
+extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
+extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
+extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
+extern void HTOnAssocRsp(struct ieee80211_device *ieee);
+extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
+extern void HTInitializeBssDesc(PBSS_HT pBssHT);
+extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
+extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
+extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
+extern u8 MCS_FILTER_ALL[];
+extern u16 MCS_DATA_RATE[2][2][77] ;
+extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
+//extern void HTSetConnectBwModeCallback(unsigned long data);
+extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
+extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
+extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
+extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
+extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
+//function in BAPROC.c
+extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
+extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
+extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
+extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+extern void BaSetupTimeOut(unsigned long data);
+extern void TxBaInactTimeout(unsigned long data);
+extern void RxBaInactTimeout(unsigned long data);
+extern void ResetBaEntry( PBA_RECORD pBA);
+//function in TS.c
+extern bool GetTs(
+        struct ieee80211_device*        ieee,
+        PTS_COMMON_INFO                 *ppTS,
+        u8*                             Addr,
+        u8                              TID,
+        TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
+        bool                            bAddNewTs
+        );
+extern void TSInitialize(struct ieee80211_device *ieee);
+extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);
+extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
+extern void RemoveAllTS(struct ieee80211_device* ieee);
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
+
+extern const long ieee80211_wlan_frequencies[];
+
+extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
+{
+	ieee->scans++;
+}
+
+extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
+{
+	return ieee->scans;
+}
+
+static inline const char *escape_essid(const char *essid, u8 essid_len) {
+	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+	const char *s = essid;
+	char *d = escaped;
+
+	if (ieee80211_is_empty_essid(essid, essid_len)) {
+		memcpy(escaped, "<hidden>", sizeof("<hidden>"));
+		return escaped;
+	}
+
+	essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
+	while (essid_len--) {
+		if (*s == '\0') {
+			*d++ = '\\';
+			*d++ = '0';
+			s++;
+		} else {
+			*d++ = *s++;
+		}
+	}
+	*d = '\0';
+	return escaped;
+}
+
+/* For the function is more related to hardware setting, it's better to use the
+ * ieee handler to refer to it.
+ */
+extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
+extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
+extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element,
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats);
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+#define RT_ASOC_RETRY_LIMIT	5
+#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
new file mode 100644
index 0000000..1a8ea8a
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c
@@ -0,0 +1,273 @@
+/*
+ * Host AP crypto routines
+ *
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.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. See README and COPYING for
+ * more details.
+ *
+ */
+
+//#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/string.h>
+#include <asm/errno.h>
+
+#include "ieee80211.h"
+
+//MODULE_AUTHOR("Jouni Malinen");
+//MODULE_DESCRIPTION("HostAP crypto");
+//MODULE_LICENSE("GPL");
+
+struct ieee80211_crypto_alg {
+	struct list_head list;
+	struct ieee80211_crypto_ops *ops;
+};
+
+
+struct ieee80211_crypto {
+	struct list_head algs;
+	spinlock_t lock;
+};
+
+static struct ieee80211_crypto *hcrypt;
+
+void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
+					   int force)
+{
+	struct list_head *ptr, *n;
+	struct ieee80211_crypt_data *entry;
+
+	for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
+	     ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
+		entry = list_entry(ptr, struct ieee80211_crypt_data, list);
+
+		if (atomic_read(&entry->refcnt) != 0 && !force)
+			continue;
+
+		list_del(ptr);
+
+		if (entry->ops) {
+			entry->ops->deinit(entry->priv);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+			module_put(entry->ops->owner);
+#else
+			__MOD_DEC_USE_COUNT(entry->ops->owner);
+#endif
+		}
+		kfree(entry);
+	}
+}
+
+void ieee80211_crypt_deinit_handler(unsigned long data)
+{
+	struct ieee80211_device *ieee = (struct ieee80211_device *)data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+	ieee80211_crypt_deinit_entries(ieee, 0);
+	if (!list_empty(&ieee->crypt_deinit_list)) {
+		printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
+		       "deletion list\n", ieee->dev->name);
+		ieee->crypt_deinit_timer.expires = jiffies + HZ;
+		add_timer(&ieee->crypt_deinit_timer);
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+}
+
+void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
+				    struct ieee80211_crypt_data **crypt)
+{
+	struct ieee80211_crypt_data *tmp;
+	unsigned long flags;
+
+	if (*crypt == NULL)
+		return;
+
+	tmp = *crypt;
+	*crypt = NULL;
+
+	/* must not run ops->deinit() while there may be pending encrypt or
+	 * decrypt operations. Use a list of delayed deinits to avoid needing
+	 * locking. */
+
+	spin_lock_irqsave(&ieee->lock, flags);
+	list_add(&tmp->list, &ieee->crypt_deinit_list);
+	if (!timer_pending(&ieee->crypt_deinit_timer)) {
+		ieee->crypt_deinit_timer.expires = jiffies + HZ;
+		add_timer(&ieee->crypt_deinit_timer);
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+}
+
+int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
+{
+	unsigned long flags;
+	struct ieee80211_crypto_alg *alg;
+
+	if (hcrypt == NULL)
+		return -1;
+
+	alg = kmalloc(sizeof(*alg), GFP_KERNEL);
+	if (alg == NULL)
+		return -ENOMEM;
+
+	memset(alg, 0, sizeof(*alg));
+	alg->ops = ops;
+
+	spin_lock_irqsave(&hcrypt->lock, flags);
+	list_add(&alg->list, &hcrypt->algs);
+	spin_unlock_irqrestore(&hcrypt->lock, flags);
+
+	printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
+	       ops->name);
+
+	return 0;
+}
+
+int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
+{
+	unsigned long flags;
+	struct list_head *ptr;
+	struct ieee80211_crypto_alg *del_alg = NULL;
+
+	if (hcrypt == NULL)
+		return -1;
+
+	spin_lock_irqsave(&hcrypt->lock, flags);
+	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
+		struct ieee80211_crypto_alg *alg =
+			(struct ieee80211_crypto_alg *) ptr;
+		if (alg->ops == ops) {
+			list_del(&alg->list);
+			del_alg = alg;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&hcrypt->lock, flags);
+
+	if (del_alg) {
+		printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
+		       "'%s'\n", ops->name);
+		kfree(del_alg);
+	}
+
+	return del_alg ? 0 : -1;
+}
+
+
+struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
+{
+	unsigned long flags;
+	struct list_head *ptr;
+	struct ieee80211_crypto_alg *found_alg = NULL;
+
+	if (hcrypt == NULL)
+		return NULL;
+
+	spin_lock_irqsave(&hcrypt->lock, flags);
+	for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
+		struct ieee80211_crypto_alg *alg =
+			(struct ieee80211_crypto_alg *) ptr;
+		if (strcmp(alg->ops->name, name) == 0) {
+			found_alg = alg;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&hcrypt->lock, flags);
+
+	if (found_alg)
+		return found_alg->ops;
+	else
+		return NULL;
+}
+
+
+static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
+static void ieee80211_crypt_null_deinit(void *priv) {}
+
+static struct ieee80211_crypto_ops ieee80211_crypt_null = {
+	.name			= "NULL",
+	.init			= ieee80211_crypt_null_init,
+	.deinit			= ieee80211_crypt_null_deinit,
+	.encrypt_mpdu		= NULL,
+	.decrypt_mpdu		= NULL,
+	.encrypt_msdu		= NULL,
+	.decrypt_msdu		= NULL,
+	.set_key		= NULL,
+	.get_key		= NULL,
+	.extra_prefix_len	= 0,
+	.extra_postfix_len	= 0,
+	.owner			= THIS_MODULE,
+};
+
+
+int __init ieee80211_crypto_init(void)
+{
+	int ret = -ENOMEM;
+
+	hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
+	if (!hcrypt)
+		goto out;
+
+	memset(hcrypt, 0, sizeof(*hcrypt));
+	INIT_LIST_HEAD(&hcrypt->algs);
+	spin_lock_init(&hcrypt->lock);
+
+	ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
+	if (ret < 0) {
+		kfree(hcrypt);
+		hcrypt = NULL;
+	}
+out:
+	return ret;
+}
+
+
+void __exit ieee80211_crypto_deinit(void)
+{
+	struct list_head *ptr, *n;
+
+	if (hcrypt == NULL)
+		return;
+
+	for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
+	     ptr = n, n = ptr->next) {
+		struct ieee80211_crypto_alg *alg =
+			(struct ieee80211_crypto_alg *) ptr;
+		list_del(ptr);
+		printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
+		       "'%s' (deinit)\n", alg->ops->name);
+		kfree(alg);
+	}
+
+	kfree(hcrypt);
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
+//EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
+//EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
+
+//EXPORT_SYMBOL(ieee80211_register_crypto_ops);
+//EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
+//EXPORT_SYMBOL(ieee80211_get_crypto_ops);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries);
+EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler);
+EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit);
+
+EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops);
+EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops);
+EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops);
+#endif
+
+//module_init(ieee80211_crypto_init);
+//module_exit(ieee80211_crypto_deinit);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h
new file mode 100644
index 0000000..a84df4b
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h
@@ -0,0 +1,93 @@
+/*
+ * Original code based on Host AP (software wireless LAN access point) driver
+ * for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ *
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. See README and COPYING for
+ * more details.
+ */
+
+/*
+ * This file defines the interface to the ieee80211 crypto module.
+ */
+#ifndef IEEE80211_CRYPT_H
+#define IEEE80211_CRYPT_H
+
+#include <linux/skbuff.h>
+
+struct ieee80211_crypto_ops {
+	const char *name;
+
+	/* init new crypto context (e.g., allocate private data space,
+	 * select IV, etc.); returns NULL on failure or pointer to allocated
+	 * private data on success */
+	void * (*init)(int keyidx);
+
+	/* deinitialize crypto context and free allocated private data */
+	void (*deinit)(void *priv);
+
+	/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
+	 * value from decrypt_mpdu is passed as the keyidx value for
+	 * decrypt_msdu. skb must have enough head and tail room for the
+	 * encryption; if not, error will be returned; these functions are
+	 * called for all MPDUs (i.e., fragments).
+	 */
+	int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+	int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+
+	/* These functions are called for full MSDUs, i.e. full frames.
+	 * These can be NULL if full MSDU operations are not needed. */
+	int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
+	int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
+			    void *priv);
+
+	int (*set_key)(void *key, int len, u8 *seq, void *priv);
+	int (*get_key)(void *key, int len, u8 *seq, void *priv);
+
+	/* procfs handler for printing out key information and possible
+	 * statistics */
+	char * (*print_stats)(char *p, void *priv);
+
+	/* maximum number of bytes added by encryption; encrypt buf is
+	 * allocated with extra_prefix_len bytes, copy of in_buf, and
+	 * extra_postfix_len; encrypt need not use all this space, but
+	 * the result must start at the beginning of the buffer and correct
+	 * length must be returned */
+	int extra_prefix_len, extra_postfix_len;
+
+	struct module *owner;
+};
+
+struct ieee80211_crypt_data {
+	struct list_head list; /* delayed deletion list */
+	struct ieee80211_crypto_ops *ops;
+	void *priv;
+	atomic_t refcnt;
+};
+
+int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
+int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
+struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
+void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
+void ieee80211_crypt_deinit_handler(unsigned long);
+void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
+				    struct ieee80211_crypt_data **crypt);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
+#endif
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
+#define crypto_alloc_tfm crypto_alloc_tfm_rsl
+#define crypto_free_tfm crypto_free_tfm_rsl
+#endif
+
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
new file mode 100644
index 0000000..ab871b3
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c
@@ -0,0 +1,534 @@
+/*
+ * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
+ *
+ * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+
+//#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <asm/string.h>
+#include <linux/wireless.h>
+
+#include "ieee80211.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include "rtl_crypto.h"
+#else
+#include <linux/crypto.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+    #include <asm/scatterlist.h>
+#else
+    #include <linux/scatterlist.h>
+#endif
+//#include <asm/scatterlist.h>
+
+MODULE_AUTHOR("Jouni Malinen");
+MODULE_DESCRIPTION("Host AP crypt: CCMP");
+MODULE_LICENSE("GPL");
+
+#ifndef OPENSUSE_SLED
+#define OPENSUSE_SLED 0
+#endif
+
+#define AES_BLOCK_LEN 16
+#define CCMP_HDR_LEN 8
+#define CCMP_MIC_LEN 8
+#define CCMP_TK_LEN 16
+#define CCMP_PN_LEN 6
+
+struct ieee80211_ccmp_data {
+	u8 key[CCMP_TK_LEN];
+	int key_set;
+
+	u8 tx_pn[CCMP_PN_LEN];
+	u8 rx_pn[CCMP_PN_LEN];
+
+	u32 dot11RSNAStatsCCMPFormatErrors;
+	u32 dot11RSNAStatsCCMPReplays;
+	u32 dot11RSNAStatsCCMPDecryptErrors;
+
+	int key_idx;
+
+	struct crypto_tfm *tfm;
+
+	/* scratch buffers for virt_to_page() (crypto API) */
+	u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
+		tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
+	u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
+};
+
+void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
+			     const u8 pt[16], u8 ct[16])
+{
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	struct scatterlist src, dst;
+
+	src.page = virt_to_page(pt);
+	src.offset = offset_in_page(pt);
+	src.length = AES_BLOCK_LEN;
+
+	dst.page = virt_to_page(ct);
+	dst.offset = offset_in_page(ct);
+	dst.length = AES_BLOCK_LEN;
+
+	crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
+#else
+	crypto_cipher_encrypt_one((void*)tfm, ct, pt);
+#endif
+}
+
+static void * ieee80211_ccmp_init(int key_idx)
+{
+	struct ieee80211_ccmp_data *priv;
+
+	priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	if (priv == NULL)
+		goto fail;
+	memset(priv, 0, sizeof(*priv));
+	priv->key_idx = key_idx;
+
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	priv->tfm = crypto_alloc_tfm("aes", 0);
+	if (priv->tfm == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
+		       "crypto API aes\n");
+		goto fail;
+	}
+       #else
+       priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+	if (IS_ERR(priv->tfm)) {
+		printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
+		       "crypto API aes\n");
+		priv->tfm = NULL;
+		goto fail;
+	}
+	#endif
+	return priv;
+
+fail:
+	if (priv) {
+		if (priv->tfm)
+			#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
+			crypto_free_tfm(priv->tfm);
+                    #else
+			crypto_free_cipher((void*)priv->tfm);
+		      #endif
+		kfree(priv);
+	}
+
+	return NULL;
+}
+
+
+static void ieee80211_ccmp_deinit(void *priv)
+{
+	struct ieee80211_ccmp_data *_priv = priv;
+	if (_priv && _priv->tfm)
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
+		crypto_free_tfm(_priv->tfm);
+#else
+		crypto_free_cipher((void*)_priv->tfm);
+#endif
+	kfree(priv);
+}
+
+
+static inline void xor_block(u8 *b, u8 *a, size_t len)
+{
+	int i;
+	for (i = 0; i < len; i++)
+		b[i] ^= a[i];
+}
+
+
+
+static void ccmp_init_blocks(struct crypto_tfm *tfm,
+			     struct ieee80211_hdr_4addr *hdr,
+			     u8 *pn, size_t dlen, u8 *b0, u8 *auth,
+			     u8 *s0)
+{
+	u8 *pos, qc = 0;
+	size_t aad_len;
+	u16 fc;
+	int a4_included, qc_included;
+	u8 aad[2 * AES_BLOCK_LEN];
+
+	fc = le16_to_cpu(hdr->frame_ctl);
+	a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
+		       (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
+	/*
+	qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
+		       (WLAN_FC_GET_STYPE(fc) & 0x08));
+        */
+	// fixed by David :2006.9.6
+	qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
+		       (WLAN_FC_GET_STYPE(fc) & 0x80));
+	aad_len = 22;
+	if (a4_included)
+		aad_len += 6;
+	if (qc_included) {
+		pos = (u8 *) &hdr->addr4;
+		if (a4_included)
+			pos += 6;
+		qc = *pos & 0x0f;
+		aad_len += 2;
+	}
+	/* CCM Initial Block:
+	 * Flag (Include authentication header, M=3 (8-octet MIC),
+	 *       L=1 (2-octet Dlen))
+	 * Nonce: 0x00 | A2 | PN
+	 * Dlen */
+	b0[0] = 0x59;
+	b0[1] = qc;
+	memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
+	memcpy(b0 + 8, pn, CCMP_PN_LEN);
+	b0[14] = (dlen >> 8) & 0xff;
+	b0[15] = dlen & 0xff;
+
+	/* AAD:
+	 * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
+	 * A1 | A2 | A3
+	 * SC with bits 4..15 (seq#) masked to zero
+	 * A4 (if present)
+	 * QC (if present)
+	 */
+	pos = (u8 *) hdr;
+	aad[0] = 0; /* aad_len >> 8 */
+	aad[1] = aad_len & 0xff;
+	aad[2] = pos[0] & 0x8f;
+	aad[3] = pos[1] & 0xc7;
+	memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
+	pos = (u8 *) &hdr->seq_ctl;
+	aad[22] = pos[0] & 0x0f;
+	aad[23] = 0; /* all bits masked */
+	memset(aad + 24, 0, 8);
+	if (a4_included)
+		memcpy(aad + 24, hdr->addr4, ETH_ALEN);
+	if (qc_included) {
+		aad[a4_included ? 30 : 24] = qc;
+		/* rest of QC masked */
+	}
+
+	/* Start with the first block and AAD */
+	ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
+	xor_block(auth, aad, AES_BLOCK_LEN);
+	ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
+	xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
+	ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
+	b0[0] &= 0x07;
+	b0[14] = b0[15] = 0;
+	ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
+}
+
+
+
+static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_ccmp_data *key = priv;
+	int data_len, i;
+	u8 *pos;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+
+	if (skb_headroom(skb) < CCMP_HDR_LEN ||
+	    skb_tailroom(skb) < CCMP_MIC_LEN ||
+	    skb->len < hdr_len)
+		return -1;
+
+	data_len = skb->len - hdr_len;
+	pos = skb_push(skb, CCMP_HDR_LEN);
+	memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
+	pos += hdr_len;
+//	mic = skb_put(skb, CCMP_MIC_LEN);
+
+	i = CCMP_PN_LEN - 1;
+	while (i >= 0) {
+		key->tx_pn[i]++;
+		if (key->tx_pn[i] != 0)
+			break;
+		i--;
+	}
+
+	*pos++ = key->tx_pn[5];
+	*pos++ = key->tx_pn[4];
+	*pos++ = 0;
+	*pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
+	*pos++ = key->tx_pn[3];
+	*pos++ = key->tx_pn[2];
+	*pos++ = key->tx_pn[1];
+	*pos++ = key->tx_pn[0];
+
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	if (!tcb_desc->bHwSec)
+	{
+		int blocks, last, len;
+		u8 *mic;
+		u8 *b0 = key->tx_b0;
+		u8 *b = key->tx_b;
+		u8 *e = key->tx_e;
+		u8 *s0 = key->tx_s0;
+
+		//mic is moved to here by john
+		mic = skb_put(skb, CCMP_MIC_LEN);
+
+		ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
+
+		blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
+		last = data_len % AES_BLOCK_LEN;
+
+		for (i = 1; i <= blocks; i++) {
+			len = (i == blocks && last) ? last : AES_BLOCK_LEN;
+			/* Authentication */
+			xor_block(b, pos, len);
+			ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
+			/* Encryption, with counter */
+			b0[14] = (i >> 8) & 0xff;
+			b0[15] = i & 0xff;
+			ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
+			xor_block(pos, e, len);
+			pos += len;
+		}
+
+		for (i = 0; i < CCMP_MIC_LEN; i++)
+			mic[i] = b[i] ^ s0[i];
+	}
+	return 0;
+}
+
+
+static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_ccmp_data *key = priv;
+	u8 keyidx, *pos;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 pn[6];
+
+	if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
+		key->dot11RSNAStatsCCMPFormatErrors++;
+		return -1;
+	}
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	pos = skb->data + hdr_len;
+	keyidx = pos[3];
+	if (!(keyidx & (1 << 5))) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "CCMP: received packet without ExtIV"
+			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+		}
+		key->dot11RSNAStatsCCMPFormatErrors++;
+		return -2;
+	}
+	keyidx >>= 6;
+	if (key->key_idx != keyidx) {
+		printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
+		       "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
+		return -6;
+	}
+	if (!key->key_set) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
+			       " with keyid=%d that does not have a configured"
+			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+		}
+		return -3;
+	}
+
+	pn[0] = pos[7];
+	pn[1] = pos[6];
+	pn[2] = pos[5];
+	pn[3] = pos[4];
+	pn[4] = pos[1];
+	pn[5] = pos[0];
+	pos += 8;
+
+	if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
+			       " previous PN %02x%02x%02x%02x%02x%02x "
+			       "received PN %02x%02x%02x%02x%02x%02x\n",
+			       MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
+			       MAC_ARG(pn));
+		}
+		key->dot11RSNAStatsCCMPReplays++;
+		return -4;
+	}
+	if (!tcb_desc->bHwSec)
+	{
+		size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
+		u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
+		u8 *b0 = key->rx_b0;
+		u8 *b = key->rx_b;
+		u8 *a = key->rx_a;
+		int i, blocks, last, len;
+
+
+		ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
+		xor_block(mic, b, CCMP_MIC_LEN);
+
+		blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
+		last = data_len % AES_BLOCK_LEN;
+
+		for (i = 1; i <= blocks; i++) {
+			len = (i == blocks && last) ? last : AES_BLOCK_LEN;
+			/* Decrypt, with counter */
+			b0[14] = (i >> 8) & 0xff;
+			b0[15] = i & 0xff;
+			ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
+			xor_block(pos, b, len);
+			/* Authentication */
+			xor_block(a, pos, len);
+			ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
+			pos += len;
+		}
+
+		if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
+			if (net_ratelimit()) {
+				printk(KERN_DEBUG "CCMP: decrypt failed: STA="
+				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			}
+			key->dot11RSNAStatsCCMPDecryptErrors++;
+			return -5;
+		}
+
+		memcpy(key->rx_pn, pn, CCMP_PN_LEN);
+	}
+	/* Remove hdr and MIC */
+	memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
+	skb_pull(skb, CCMP_HDR_LEN);
+	skb_trim(skb, skb->len - CCMP_MIC_LEN);
+
+	return keyidx;
+}
+
+
+static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
+{
+	struct ieee80211_ccmp_data *data = priv;
+	int keyidx;
+	struct crypto_tfm *tfm = data->tfm;
+
+	keyidx = data->key_idx;
+	memset(data, 0, sizeof(*data));
+	data->key_idx = keyidx;
+	data->tfm = tfm;
+	if (len == CCMP_TK_LEN) {
+		memcpy(data->key, key, CCMP_TK_LEN);
+		data->key_set = 1;
+		if (seq) {
+			data->rx_pn[0] = seq[5];
+			data->rx_pn[1] = seq[4];
+			data->rx_pn[2] = seq[3];
+			data->rx_pn[3] = seq[2];
+			data->rx_pn[4] = seq[1];
+			data->rx_pn[5] = seq[0];
+		}
+		crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN);
+	} else if (len == 0)
+		data->key_set = 0;
+	else
+		return -1;
+
+	return 0;
+}
+
+
+static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
+{
+	struct ieee80211_ccmp_data *data = priv;
+
+	if (len < CCMP_TK_LEN)
+		return -1;
+
+	if (!data->key_set)
+		return 0;
+	memcpy(key, data->key, CCMP_TK_LEN);
+
+	if (seq) {
+		seq[0] = data->tx_pn[5];
+		seq[1] = data->tx_pn[4];
+		seq[2] = data->tx_pn[3];
+		seq[3] = data->tx_pn[2];
+		seq[4] = data->tx_pn[1];
+		seq[5] = data->tx_pn[0];
+	}
+
+	return CCMP_TK_LEN;
+}
+
+
+static char * ieee80211_ccmp_print_stats(char *p, void *priv)
+{
+	struct ieee80211_ccmp_data *ccmp = priv;
+	p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
+		     "tx_pn=%02x%02x%02x%02x%02x%02x "
+		     "rx_pn=%02x%02x%02x%02x%02x%02x "
+		     "format_errors=%d replays=%d decrypt_errors=%d\n",
+		     ccmp->key_idx, ccmp->key_set,
+		     MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
+		     ccmp->dot11RSNAStatsCCMPFormatErrors,
+		     ccmp->dot11RSNAStatsCCMPReplays,
+		     ccmp->dot11RSNAStatsCCMPDecryptErrors);
+
+	return p;
+}
+
+void ieee80211_ccmp_null(void)
+{
+//    printk("============>%s()\n", __FUNCTION__);
+	return;
+}
+
+static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
+	.name			= "CCMP",
+	.init			= ieee80211_ccmp_init,
+	.deinit			= ieee80211_ccmp_deinit,
+	.encrypt_mpdu		= ieee80211_ccmp_encrypt,
+	.decrypt_mpdu		= ieee80211_ccmp_decrypt,
+	.encrypt_msdu		= NULL,
+	.decrypt_msdu		= NULL,
+	.set_key		= ieee80211_ccmp_set_key,
+	.get_key		= ieee80211_ccmp_get_key,
+	.print_stats		= ieee80211_ccmp_print_stats,
+	.extra_prefix_len	= CCMP_HDR_LEN,
+	.extra_postfix_len	= CCMP_MIC_LEN,
+	.owner			= THIS_MODULE,
+};
+
+
+int __init ieee80211_crypto_ccmp_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
+}
+
+
+void __exit ieee80211_crypto_ccmp_exit(void)
+{
+	ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_ccmp_null);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
+#endif
+
+//module_init(ieee80211_crypto_ccmp_init);
+//module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
new file mode 100644
index 0000000..7a1797e
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c
@@ -0,0 +1,1031 @@
+/*
+ * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
+ *
+ * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+
+//#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <asm/string.h>
+
+#include "ieee80211.h"
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include "rtl_crypto.h"
+#else
+#include <linux/crypto.h>
+#endif
+//#include <asm/scatterlist.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+    #include <asm/scatterlist.h>
+#else
+        #include <linux/scatterlist.h>
+#endif
+
+#include <linux/crc32.h>
+
+MODULE_AUTHOR("Jouni Malinen");
+MODULE_DESCRIPTION("Host AP crypt: TKIP");
+MODULE_LICENSE("GPL");
+
+#ifndef OPENSUSE_SLED
+#define OPENSUSE_SLED 0
+#endif
+
+struct ieee80211_tkip_data {
+#define TKIP_KEY_LEN 32
+	u8 key[TKIP_KEY_LEN];
+	int key_set;
+
+	u32 tx_iv32;
+	u16 tx_iv16;
+	u16 tx_ttak[5];
+	int tx_phase1_done;
+
+	u32 rx_iv32;
+	u16 rx_iv16;
+	u16 rx_ttak[5];
+	int rx_phase1_done;
+	u32 rx_iv32_new;
+	u16 rx_iv16_new;
+
+	u32 dot11RSNAStatsTKIPReplays;
+	u32 dot11RSNAStatsTKIPICVErrors;
+	u32 dot11RSNAStatsTKIPLocalMICFailures;
+
+	int key_idx;
+#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct crypto_blkcipher *rx_tfm_arc4;
+	struct crypto_hash *rx_tfm_michael;
+	struct crypto_blkcipher *tx_tfm_arc4;
+	struct crypto_hash *tx_tfm_michael;
+#else
+	struct crypto_tfm *tx_tfm_arc4;
+	struct crypto_tfm *tx_tfm_michael;
+	struct crypto_tfm *rx_tfm_arc4;
+	struct crypto_tfm *rx_tfm_michael;
+#endif
+	/* scratch buffers for virt_to_page() (crypto API) */
+	u8 rx_hdr[16], tx_hdr[16];
+};
+
+static void * ieee80211_tkip_init(int key_idx)
+{
+	struct ieee80211_tkip_data *priv;
+
+	priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	if (priv == NULL)
+		goto fail;
+	memset(priv, 0, sizeof(*priv));
+	priv->key_idx = key_idx;
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
+	if (priv->tx_tfm_arc4 == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API arc4\n");
+		goto fail;
+	}
+
+	priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
+	if (priv->tx_tfm_michael == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API michael_mic\n");
+		goto fail;
+	}
+
+	priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
+	if (priv->rx_tfm_arc4 == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API arc4\n");
+		goto fail;
+	}
+
+	priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
+	if (priv->rx_tfm_michael == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API michael_mic\n");
+		goto fail;
+	}
+#else
+	priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
+			CRYPTO_ALG_ASYNC);
+	if (IS_ERR(priv->tx_tfm_arc4)) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API arc4\n");
+		priv->tx_tfm_arc4 = NULL;
+		goto fail;
+	}
+
+	priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
+			CRYPTO_ALG_ASYNC);
+	if (IS_ERR(priv->tx_tfm_michael)) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API michael_mic\n");
+		priv->tx_tfm_michael = NULL;
+		goto fail;
+	}
+
+	priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
+			CRYPTO_ALG_ASYNC);
+	if (IS_ERR(priv->rx_tfm_arc4)) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API arc4\n");
+		priv->rx_tfm_arc4 = NULL;
+		goto fail;
+	}
+
+	priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
+			CRYPTO_ALG_ASYNC);
+	if (IS_ERR(priv->rx_tfm_michael)) {
+		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
+				"crypto API michael_mic\n");
+		priv->rx_tfm_michael = NULL;
+		goto fail;
+	}
+#endif
+	return priv;
+
+fail:
+	if (priv) {
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		if (priv->tx_tfm_michael)
+			crypto_free_tfm(priv->tx_tfm_michael);
+		if (priv->tx_tfm_arc4)
+			crypto_free_tfm(priv->tx_tfm_arc4);
+		if (priv->rx_tfm_michael)
+			crypto_free_tfm(priv->rx_tfm_michael);
+		if (priv->rx_tfm_arc4)
+			crypto_free_tfm(priv->rx_tfm_arc4);
+
+#else
+		if (priv->tx_tfm_michael)
+			crypto_free_hash(priv->tx_tfm_michael);
+		if (priv->tx_tfm_arc4)
+			crypto_free_blkcipher(priv->tx_tfm_arc4);
+		if (priv->rx_tfm_michael)
+			crypto_free_hash(priv->rx_tfm_michael);
+		if (priv->rx_tfm_arc4)
+			crypto_free_blkcipher(priv->rx_tfm_arc4);
+#endif
+		kfree(priv);
+	}
+
+	return NULL;
+}
+
+
+static void ieee80211_tkip_deinit(void *priv)
+{
+	struct ieee80211_tkip_data *_priv = priv;
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	if (_priv->tx_tfm_michael)
+		crypto_free_tfm(_priv->tx_tfm_michael);
+	if (_priv->tx_tfm_arc4)
+		crypto_free_tfm(_priv->tx_tfm_arc4);
+	if (_priv->rx_tfm_michael)
+		crypto_free_tfm(_priv->rx_tfm_michael);
+	if (_priv->rx_tfm_arc4)
+		crypto_free_tfm(_priv->rx_tfm_arc4);
+#else
+	if (_priv) {
+		if (_priv->tx_tfm_michael)
+			crypto_free_hash(_priv->tx_tfm_michael);
+		if (_priv->tx_tfm_arc4)
+			crypto_free_blkcipher(_priv->tx_tfm_arc4);
+		if (_priv->rx_tfm_michael)
+			crypto_free_hash(_priv->rx_tfm_michael);
+		if (_priv->rx_tfm_arc4)
+			crypto_free_blkcipher(_priv->rx_tfm_arc4);
+	}
+#endif
+	kfree(priv);
+}
+
+
+static inline u16 RotR1(u16 val)
+{
+	return (val >> 1) | (val << 15);
+}
+
+
+static inline u8 Lo8(u16 val)
+{
+	return val & 0xff;
+}
+
+
+static inline u8 Hi8(u16 val)
+{
+	return val >> 8;
+}
+
+
+static inline u16 Lo16(u32 val)
+{
+	return val & 0xffff;
+}
+
+
+static inline u16 Hi16(u32 val)
+{
+	return val >> 16;
+}
+
+
+static inline u16 Mk16(u8 hi, u8 lo)
+{
+	return lo | (((u16) hi) << 8);
+}
+
+
+static inline u16 Mk16_le(u16 *v)
+{
+	return le16_to_cpu(*v);
+}
+
+
+static const u16 Sbox[256] =
+{
+	0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
+	0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
+	0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
+	0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
+	0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
+	0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
+	0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
+	0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
+	0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
+	0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
+	0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
+	0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
+	0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
+	0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
+	0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
+	0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
+	0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
+	0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
+	0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
+	0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
+	0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
+	0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
+	0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
+	0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
+	0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
+	0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
+	0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
+	0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
+	0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
+	0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
+	0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
+	0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
+};
+
+
+static inline u16 _S_(u16 v)
+{
+	u16 t = Sbox[Hi8(v)];
+	return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
+}
+
+
+#define PHASE1_LOOP_COUNT 8
+
+
+static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
+{
+	int i, j;
+
+	/* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
+	TTAK[0] = Lo16(IV32);
+	TTAK[1] = Hi16(IV32);
+	TTAK[2] = Mk16(TA[1], TA[0]);
+	TTAK[3] = Mk16(TA[3], TA[2]);
+	TTAK[4] = Mk16(TA[5], TA[4]);
+
+	for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
+		j = 2 * (i & 1);
+		TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
+		TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
+		TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
+		TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
+		TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
+	}
+}
+
+
+static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
+			       u16 IV16)
+{
+	/* Make temporary area overlap WEP seed so that the final copy can be
+	 * avoided on little endian hosts. */
+	u16 *PPK = (u16 *) &WEPSeed[4];
+
+	/* Step 1 - make copy of TTAK and bring in TSC */
+	PPK[0] = TTAK[0];
+	PPK[1] = TTAK[1];
+	PPK[2] = TTAK[2];
+	PPK[3] = TTAK[3];
+	PPK[4] = TTAK[4];
+	PPK[5] = TTAK[4] + IV16;
+
+	/* Step 2 - 96-bit bijective mixing using S-box */
+	PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
+	PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
+	PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
+	PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
+	PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
+	PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
+
+	PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
+	PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
+	PPK[2] += RotR1(PPK[1]);
+	PPK[3] += RotR1(PPK[2]);
+	PPK[4] += RotR1(PPK[3]);
+	PPK[5] += RotR1(PPK[4]);
+
+	/* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
+	 * WEPSeed[0..2] is transmitted as WEP IV */
+	WEPSeed[0] = Hi8(IV16);
+	WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
+	WEPSeed[2] = Lo8(IV16);
+	WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
+
+#ifdef __BIG_ENDIAN
+	{
+		int i;
+		for (i = 0; i < 6; i++)
+			PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
+	}
+#endif
+}
+
+
+static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+		int len;
+	u8 *pos;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
+	int ret = 0;
+	#endif
+	u8 rc4key[16],  *icv;
+	u32 crc;
+	struct scatterlist sg;
+
+	if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
+	    skb->len < hdr_len)
+		return -1;
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+
+#if 0
+printk("@@ tkey\n");
+printk("%x|", ((u32*)tkey->key)[0]);
+printk("%x|", ((u32*)tkey->key)[1]);
+printk("%x|", ((u32*)tkey->key)[2]);
+printk("%x|", ((u32*)tkey->key)[3]);
+printk("%x|", ((u32*)tkey->key)[4]);
+printk("%x|", ((u32*)tkey->key)[5]);
+printk("%x|", ((u32*)tkey->key)[6]);
+printk("%x\n", ((u32*)tkey->key)[7]);
+#endif
+
+	if (!tcb_desc->bHwSec)
+	{
+		if (!tkey->tx_phase1_done) {
+			tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
+					tkey->tx_iv32);
+			tkey->tx_phase1_done = 1;
+		}
+		tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
+	}
+	else
+	tkey->tx_phase1_done = 1;
+
+
+	len = skb->len - hdr_len;
+	pos = skb_push(skb, 8);
+	memmove(pos, pos + 8, hdr_len);
+	pos += hdr_len;
+
+	if (tcb_desc->bHwSec)
+	{
+		*pos++ = Hi8(tkey->tx_iv16);
+		*pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
+		*pos++ = Lo8(tkey->tx_iv16);
+	}
+	else
+	{
+		*pos++ = rc4key[0];
+		*pos++ = rc4key[1];
+		*pos++ = rc4key[2];
+	}
+
+	*pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
+	*pos++ = tkey->tx_iv32 & 0xff;
+	*pos++ = (tkey->tx_iv32 >> 8) & 0xff;
+	*pos++ = (tkey->tx_iv32 >> 16) & 0xff;
+	*pos++ = (tkey->tx_iv32 >> 24) & 0xff;
+
+	if (!tcb_desc->bHwSec)
+	{
+		icv = skb_put(skb, 4);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+		crc = ~crc32_le(~0, pos, len);
+#else
+		crc = ~ether_crc_le(len, pos);
+#endif
+		icv[0] = crc;
+		icv[1] = crc >> 8;
+		icv[2] = crc >> 16;
+		icv[3] = crc >> 24;
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = len + 4;
+		crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
+#else
+		crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = len + 4;
+#else
+		sg_init_one(&sg, pos, len+4);
+#endif
+		ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
+#endif
+
+	}
+
+	tkey->tx_iv16++;
+	if (tkey->tx_iv16 == 0) {
+		tkey->tx_phase1_done = 0;
+		tkey->tx_iv32++;
+	}
+
+	if (!tcb_desc->bHwSec)
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		return 0;
+	#else
+		return ret;
+	#endif
+	else
+        	return 0;
+
+
+}
+
+static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+	u8 keyidx, *pos;
+	u32 iv32;
+	u16 iv16;
+	struct ieee80211_hdr_4addr *hdr;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
+	#endif
+	u8 rc4key[16];
+	u8 icv[4];
+	u32 crc;
+	struct scatterlist sg;
+	int plen;
+	if (skb->len < hdr_len + 8 + 4)
+		return -1;
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	pos = skb->data + hdr_len;
+	keyidx = pos[3];
+	if (!(keyidx & (1 << 5))) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "TKIP: received packet without ExtIV"
+			       " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
+		}
+		return -2;
+	}
+	keyidx >>= 6;
+	if (tkey->key_idx != keyidx) {
+		printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
+		       "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
+		return -6;
+	}
+	if (!tkey->key_set) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
+			       " with keyid=%d that does not have a configured"
+			       " key\n", MAC_ARG(hdr->addr2), keyidx);
+		}
+		return -3;
+	}
+	iv16 = (pos[0] << 8) | pos[2];
+	iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
+	pos += 8;
+
+	if (!tcb_desc->bHwSec)
+	{
+		if (iv32 < tkey->rx_iv32 ||
+		(iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
+			if (net_ratelimit()) {
+				printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
+				" previous TSC %08x%04x received TSC "
+				"%08x%04x\n", MAC_ARG(hdr->addr2),
+				tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
+			}
+			tkey->dot11RSNAStatsTKIPReplays++;
+			return -4;
+		}
+
+		if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
+			tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
+			tkey->rx_phase1_done = 1;
+		}
+		tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
+
+		plen = skb->len - hdr_len - 12;
+
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = plen + 4;
+		crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
+#else
+		crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = plen + 4;
+#else
+		sg_init_one(&sg, pos, plen+4);
+#endif
+		if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
+			if (net_ratelimit()) {
+				printk(KERN_DEBUG ": TKIP: failed to decrypt "
+						"received packet from " MAC_FMT "\n",
+						MAC_ARG(hdr->addr2));
+			}
+			return -7;
+		}
+#endif
+
+	#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+		crc = ~crc32_le(~0, pos, plen);
+	#else
+		crc = ~ether_crc_le(plen, pos);
+	#endif
+		icv[0] = crc;
+		icv[1] = crc >> 8;
+		icv[2] = crc >> 16;
+		icv[3] = crc >> 24;
+
+		if (memcmp(icv, pos + plen, 4) != 0) {
+			if (iv32 != tkey->rx_iv32) {
+				/* Previously cached Phase1 result was already lost, so
+				* it needs to be recalculated for the next packet. */
+				tkey->rx_phase1_done = 0;
+			}
+			if (net_ratelimit()) {
+				printk(KERN_DEBUG "TKIP: ICV error detected: STA="
+				MAC_FMT "\n", MAC_ARG(hdr->addr2));
+			}
+			tkey->dot11RSNAStatsTKIPICVErrors++;
+			return -5;
+		}
+
+	}
+
+	/* Update real counters only after Michael MIC verification has
+	 * completed */
+	tkey->rx_iv32_new = iv32;
+	tkey->rx_iv16_new = iv16;
+
+	/* Remove IV and ICV */
+	memmove(skb->data + 8, skb->data, hdr_len);
+	skb_pull(skb, 8);
+	skb_trim(skb, skb->len - 4);
+
+//john's test
+#ifdef JOHN_DUMP
+if( ((u16*)skb->data)[0] & 0x4000){
+        printk("@@ rx decrypted skb->data");
+        int i;
+        for(i=0;i<skb->len;i++){
+                if( (i%24)==0 ) printk("\n");
+                printk("%2x ", ((u8*)skb->data)[i]);
+        }
+        printk("\n");
+}
+#endif /*JOHN_DUMP*/
+	return keyidx;
+}
+
+
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr,
+		       u8 *data, size_t data_len, u8 *mic)
+{
+	struct scatterlist sg[2];
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+        struct hash_desc desc;
+        int ret = 0;
+#endif
+
+	if (tfm_michael == NULL){
+		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
+		return -1;
+	}
+	sg[0].page = virt_to_page(hdr);
+	sg[0].offset = offset_in_page(hdr);
+	sg[0].length = 16;
+
+	sg[1].page = virt_to_page(data);
+	sg[1].offset = offset_in_page(data);
+	sg[1].length = data_len;
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+	crypto_digest_init(tfm_michael);
+        crypto_digest_setkey(tfm_michael, key, 8);
+        crypto_digest_update(tfm_michael, sg, 2);
+        crypto_digest_final(tfm_michael, mic);
+        return 0;
+#else
+if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
+                return -1;
+
+//      return 0;
+              desc.tfm = tkey->tfm_michael;
+              desc.flags = 0;
+              ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
+              return ret;
+#endif
+}
+#else
+static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
+                       u8 * data, size_t data_len, u8 * mic)
+{
+        struct hash_desc desc;
+        struct scatterlist sg[2];
+
+        if (tfm_michael == NULL) {
+                printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
+                return -1;
+        }
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+        sg[0].page = virt_to_page(hdr);
+        sg[0].offset = offset_in_page(hdr);
+        sg[0].length = 16;
+
+        sg[1].page = virt_to_page(data);
+        sg[1].offset = offset_in_page(data);
+        sg[1].length = data_len;
+#else
+        sg_init_table(sg, 2);
+        sg_set_buf(&sg[0], hdr, 16);
+        sg_set_buf(&sg[1], data, data_len);
+#endif
+
+        if (crypto_hash_setkey(tfm_michael, key, 8))
+                return -1;
+
+        desc.tfm = tfm_michael;
+        desc.flags = 0;
+        return crypto_hash_digest(&desc, sg, data_len + 16, mic);
+}
+#endif
+
+
+
+static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
+{
+	struct ieee80211_hdr_4addr *hdr11;
+
+	hdr11 = (struct ieee80211_hdr_4addr *) skb->data;
+	switch (le16_to_cpu(hdr11->frame_ctl) &
+		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
+	case IEEE80211_FCTL_TODS:
+		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
+		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+		break;
+	case IEEE80211_FCTL_FROMDS:
+		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
+		memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
+		break;
+	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
+		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
+		memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
+		break;
+	case 0:
+		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
+		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+		break;
+	}
+
+	hdr[12] = 0; /* priority */
+
+	hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
+}
+
+
+static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+	u8 *pos;
+	struct ieee80211_hdr_4addr *hdr;
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+
+	if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
+		printk(KERN_DEBUG "Invalid packet for Michael MIC add "
+		       "(tailroom=%d hdr_len=%d skb->len=%d)\n",
+		       skb_tailroom(skb), hdr_len, skb->len);
+		return -1;
+	}
+
+	michael_mic_hdr(skb, tkey->tx_hdr);
+
+	// { david, 2006.9.1
+	// fix the wpa process with wmm enabled.
+	if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
+		tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
+	}
+	// }
+	pos = skb_put(skb, 8);
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
+				skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
+#else
+	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
+				skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
+#endif
+		return -1;
+
+	return 0;
+}
+
+
+#if WIRELESS_EXT >= 18
+static void ieee80211_michael_mic_failure(struct net_device *dev,
+				       struct ieee80211_hdr_4addr *hdr,
+				       int keyidx)
+{
+	union iwreq_data wrqu;
+	struct iw_michaelmicfailure ev;
+
+	/* TODO: needed parameters: count, keyid, key type, TSC */
+	memset(&ev, 0, sizeof(ev));
+	ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
+	if (hdr->addr1[0] & 0x01)
+		ev.flags |= IW_MICFAILURE_GROUP;
+	else
+		ev.flags |= IW_MICFAILURE_PAIRWISE;
+	ev.src_addr.sa_family = ARPHRD_ETHER;
+	memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.data.length = sizeof(ev);
+	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
+}
+#elif WIRELESS_EXT >= 15
+static void ieee80211_michael_mic_failure(struct net_device *dev,
+				       struct ieee80211_hdr_4addr *hdr,
+				       int keyidx)
+{
+	union iwreq_data wrqu;
+	char buf[128];
+
+	/* TODO: needed parameters: count, keyid, key type, TSC */
+	sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
+		MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
+		MAC_ARG(hdr->addr2));
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.data.length = strlen(buf);
+	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
+}
+#else /* WIRELESS_EXT >= 15 */
+static inline void ieee80211_michael_mic_failure(struct net_device *dev,
+					      struct ieee80211_hdr_4addr *hdr,
+					      int keyidx)
+{
+}
+#endif /* WIRELESS_EXT >= 15 */
+
+static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
+				     int hdr_len, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+	u8 mic[8];
+	struct ieee80211_hdr_4addr *hdr;
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+
+	if (!tkey->key_set)
+		return -1;
+
+	michael_mic_hdr(skb, tkey->rx_hdr);
+	// { david, 2006.9.1
+	// fix the wpa process with wmm enabled.
+	if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
+		tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
+	}
+	// }
+
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
+				skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
+#else
+	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
+				skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
+#endif
+            	return -1;
+	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
+		struct ieee80211_hdr_4addr *hdr;
+		hdr = (struct ieee80211_hdr_4addr *) skb->data;
+		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
+		       "MSDU from " MAC_FMT " keyidx=%d\n",
+		       skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
+		       keyidx);
+		if (skb->dev)
+			ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
+		tkey->dot11RSNAStatsTKIPLocalMICFailures++;
+		return -1;
+	}
+
+	/* Update TSC counters for RX now that the packet verification has
+	 * completed. */
+	tkey->rx_iv32 = tkey->rx_iv32_new;
+	tkey->rx_iv16 = tkey->rx_iv16_new;
+
+	skb_trim(skb, skb->len - 8);
+
+	return 0;
+}
+
+
+static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+	int keyidx;
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	struct crypto_tfm *tfm = tkey->tx_tfm_michael;
+	struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
+	struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
+	struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
+#else
+	struct crypto_hash *tfm = tkey->tx_tfm_michael;
+	struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
+	struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
+	struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
+#endif
+
+	keyidx = tkey->key_idx;
+	memset(tkey, 0, sizeof(*tkey));
+	tkey->key_idx = keyidx;
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	tkey->tx_tfm_michael = tfm;
+	tkey->tx_tfm_arc4 = tfm2;
+	tkey->rx_tfm_michael = tfm3;
+	tkey->rx_tfm_arc4 = tfm4;
+#else
+	tkey->tx_tfm_michael = tfm;
+	tkey->tx_tfm_arc4 = tfm2;
+	tkey->rx_tfm_michael = tfm3;
+	tkey->rx_tfm_arc4 = tfm4;
+#endif
+
+	if (len == TKIP_KEY_LEN) {
+		memcpy(tkey->key, key, TKIP_KEY_LEN);
+		tkey->key_set = 1;
+		tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
+		if (seq) {
+			tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
+				(seq[3] << 8) | seq[2];
+			tkey->rx_iv16 = (seq[1] << 8) | seq[0];
+		}
+	} else if (len == 0)
+		tkey->key_set = 0;
+	else
+		return -1;
+
+	return 0;
+}
+
+
+static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
+{
+	struct ieee80211_tkip_data *tkey = priv;
+
+	if (len < TKIP_KEY_LEN)
+		return -1;
+
+	if (!tkey->key_set)
+		return 0;
+	memcpy(key, tkey->key, TKIP_KEY_LEN);
+
+	if (seq) {
+		/* Return the sequence number of the last transmitted frame. */
+		u16 iv16 = tkey->tx_iv16;
+		u32 iv32 = tkey->tx_iv32;
+		if (iv16 == 0)
+			iv32--;
+		iv16--;
+		seq[0] = tkey->tx_iv16;
+		seq[1] = tkey->tx_iv16 >> 8;
+		seq[2] = tkey->tx_iv32;
+		seq[3] = tkey->tx_iv32 >> 8;
+		seq[4] = tkey->tx_iv32 >> 16;
+		seq[5] = tkey->tx_iv32 >> 24;
+	}
+
+	return TKIP_KEY_LEN;
+}
+
+
+static char * ieee80211_tkip_print_stats(char *p, void *priv)
+{
+	struct ieee80211_tkip_data *tkip = priv;
+	p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
+		     "tx_pn=%02x%02x%02x%02x%02x%02x "
+		     "rx_pn=%02x%02x%02x%02x%02x%02x "
+		     "replays=%d icv_errors=%d local_mic_failures=%d\n",
+		     tkip->key_idx, tkip->key_set,
+		     (tkip->tx_iv32 >> 24) & 0xff,
+		     (tkip->tx_iv32 >> 16) & 0xff,
+		     (tkip->tx_iv32 >> 8) & 0xff,
+		     tkip->tx_iv32 & 0xff,
+		     (tkip->tx_iv16 >> 8) & 0xff,
+		     tkip->tx_iv16 & 0xff,
+		     (tkip->rx_iv32 >> 24) & 0xff,
+		     (tkip->rx_iv32 >> 16) & 0xff,
+		     (tkip->rx_iv32 >> 8) & 0xff,
+		     tkip->rx_iv32 & 0xff,
+		     (tkip->rx_iv16 >> 8) & 0xff,
+		     tkip->rx_iv16 & 0xff,
+		     tkip->dot11RSNAStatsTKIPReplays,
+		     tkip->dot11RSNAStatsTKIPICVErrors,
+		     tkip->dot11RSNAStatsTKIPLocalMICFailures);
+	return p;
+}
+
+
+static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
+	.name			= "TKIP",
+	.init			= ieee80211_tkip_init,
+	.deinit			= ieee80211_tkip_deinit,
+	.encrypt_mpdu		= ieee80211_tkip_encrypt,
+	.decrypt_mpdu		= ieee80211_tkip_decrypt,
+	.encrypt_msdu		= ieee80211_michael_mic_add,
+	.decrypt_msdu		= ieee80211_michael_mic_verify,
+	.set_key		= ieee80211_tkip_set_key,
+	.get_key		= ieee80211_tkip_get_key,
+	.print_stats		= ieee80211_tkip_print_stats,
+	.extra_prefix_len	= 4 + 4, /* IV + ExtIV */
+	.extra_postfix_len	= 8 + 4, /* MIC + ICV */
+	.owner		        = THIS_MODULE,
+};
+
+
+int __init ieee80211_crypto_tkip_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
+}
+
+
+void __exit ieee80211_crypto_tkip_exit(void)
+{
+	ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
+}
+
+void ieee80211_tkip_null(void)
+{
+//    printk("============>%s()\n", __FUNCTION__);
+        return;
+}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_tkip_null);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
+#endif
+
+//module_init(ieee80211_crypto_tkip_init);
+//module_exit(ieee80211_crypto_tkip_exit);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c
new file mode 100644
index 0000000..5678313
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c
@@ -0,0 +1,393 @@
+/*
+ * Host AP crypt: host-based WEP encryption implementation for Host AP driver
+ *
+ * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * 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. See README and COPYING for
+ * more details.
+ */
+
+//#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/skbuff.h>
+#include <asm/string.h>
+
+#include "ieee80211.h"
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include "rtl_crypto.h"
+#else
+#include <linux/crypto.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+    #include <asm/scatterlist.h>
+#else
+    #include <linux/scatterlist.h>
+#endif
+//#include <asm/scatterlist.h>
+#include <linux/crc32.h>
+//
+/*
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include "rtl_crypto.h"
+#else
+#include <linux/crypto.h>
+#endif
+
+#include <asm/scatterlist.h>
+#include <linux/crc32.h>
+*/
+MODULE_AUTHOR("Jouni Malinen");
+MODULE_DESCRIPTION("Host AP crypt: WEP");
+MODULE_LICENSE("GPL");
+#ifndef OPENSUSE_SLED
+#define OPENSUSE_SLED 0
+#endif
+
+struct prism2_wep_data {
+	u32 iv;
+#define WEP_KEY_LEN 13
+	u8 key[WEP_KEY_LEN + 1];
+	u8 key_len;
+	u8 key_idx;
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	struct crypto_tfm *tfm;
+	#else
+        struct crypto_blkcipher *tx_tfm;
+        struct crypto_blkcipher *rx_tfm;
+        #endif
+};
+
+
+static void * prism2_wep_init(int keyidx)
+{
+	struct prism2_wep_data *priv;
+
+	priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
+	if (priv == NULL)
+		goto fail;
+	memset(priv, 0, sizeof(*priv));
+	priv->key_idx = keyidx;
+
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	priv->tfm = crypto_alloc_tfm("arc4", 0);
+	if (priv->tfm == NULL) {
+		printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
+		       "crypto API arc4\n");
+		goto fail;
+	}
+	#else
+	priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
+        if (IS_ERR(priv->tx_tfm)) {
+                printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
+                       "crypto API arc4\n");
+                priv->tx_tfm = NULL;
+                goto fail;
+        }
+        priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
+        if (IS_ERR(priv->rx_tfm)) {
+                printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
+                       "crypto API arc4\n");
+                priv->rx_tfm = NULL;
+                goto fail;
+        }
+        #endif
+
+	/* start WEP IV from a random value */
+	get_random_bytes(&priv->iv, 4);
+
+	return priv;
+
+fail:
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	if (priv) {
+		if (priv->tfm)
+			crypto_free_tfm(priv->tfm);
+		kfree(priv);
+	}
+	#else
+	if (priv) {
+                if (priv->tx_tfm)
+                        crypto_free_blkcipher(priv->tx_tfm);
+                if (priv->rx_tfm)
+                        crypto_free_blkcipher(priv->rx_tfm);
+                kfree(priv);
+        }
+        #endif
+	return NULL;
+}
+
+
+static void prism2_wep_deinit(void *priv)
+{
+	struct prism2_wep_data *_priv = priv;
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+	if (_priv && _priv->tfm)
+		crypto_free_tfm(_priv->tfm);
+	#else
+	if (_priv) {
+                if (_priv->tx_tfm)
+                        crypto_free_blkcipher(_priv->tx_tfm);
+                if (_priv->rx_tfm)
+                        crypto_free_blkcipher(_priv->rx_tfm);
+        }
+        #endif
+	kfree(priv);
+}
+
+/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
+ * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
+ * so the payload length increases with 8 bytes.
+ *
+ * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
+ */
+static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct prism2_wep_data *wep = priv;
+	u32 klen, len;
+	u8 key[WEP_KEY_LEN + 3];
+	u8 *pos;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
+	#endif
+	u32 crc;
+	u8 *icv;
+	struct scatterlist sg;
+	if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
+	    skb->len < hdr_len)
+		return -1;
+
+	len = skb->len - hdr_len;
+	pos = skb_push(skb, 4);
+	memmove(pos, pos + 4, hdr_len);
+	pos += hdr_len;
+
+	klen = 3 + wep->key_len;
+
+	wep->iv++;
+
+	/* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
+	 * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
+	 * can be used to speedup attacks, so avoid using them. */
+	if ((wep->iv & 0xff00) == 0xff00) {
+		u8 B = (wep->iv >> 16) & 0xff;
+		if (B >= 3 && B < klen)
+			wep->iv += 0x0100;
+	}
+
+	/* Prepend 24-bit IV to RC4 key and TX frame */
+	*pos++ = key[0] = (wep->iv >> 16) & 0xff;
+	*pos++ = key[1] = (wep->iv >> 8) & 0xff;
+	*pos++ = key[2] = wep->iv & 0xff;
+	*pos++ = wep->key_idx << 6;
+
+	/* Copy rest of the WEP key (the secret part) */
+	memcpy(key + 3, wep->key, wep->key_len);
+
+	if (!tcb_desc->bHwSec)
+	{
+
+		/* Append little-endian CRC32 and encrypt it to produce ICV */
+	#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+		crc = ~crc32_le(~0, pos, len);
+	#else
+		crc = ~ether_crc_le(len, pos);
+	#endif
+		icv = skb_put(skb, 4);
+		icv[0] = crc;
+		icv[1] = crc >> 8;
+		icv[2] = crc >> 16;
+		icv[3] = crc >> 24;
+
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		crypto_cipher_setkey(wep->tfm, key, klen);
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = len + 4;
+		crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
+		return 0;
+	#else
+		crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
+	#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = len + 4;
+	#else
+		sg_init_one(&sg, pos, len+4);
+	#endif
+		return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
+	#endif
+	}
+
+	return 0;
+}
+
+
+/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
+ * the frame: IV (4 bytes), encrypted payload (including SNAP header),
+ * ICV (4 bytes). len includes both IV and ICV.
+ *
+ * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
+ * failure. If frame is OK, IV and ICV will be removed.
+ */
+static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+	struct prism2_wep_data *wep = priv;
+	u32  klen, plen;
+	u8 key[WEP_KEY_LEN + 3];
+	u8 keyidx, *pos;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+	struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
+	#endif
+	u32 crc;
+	u8 icv[4];
+	struct scatterlist sg;
+	if (skb->len < hdr_len + 8)
+		return -1;
+
+	pos = skb->data + hdr_len;
+	key[0] = *pos++;
+	key[1] = *pos++;
+	key[2] = *pos++;
+	keyidx = *pos++ >> 6;
+	if (keyidx != wep->key_idx)
+		return -1;
+
+	klen = 3 + wep->key_len;
+
+	/* Copy rest of the WEP key (the secret part) */
+	memcpy(key + 3, wep->key, wep->key_len);
+
+	/* Apply RC4 to data and compute CRC32 over decrypted data */
+	plen = skb->len - hdr_len - 8;
+
+	if (!tcb_desc->bHwSec)
+	{
+#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
+		crypto_cipher_setkey(wep->tfm, key, klen);
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = plen + 4;
+		crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
+	#else
+		crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
+	#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		sg.page = virt_to_page(pos);
+		sg.offset = offset_in_page(pos);
+		sg.length = plen + 4;
+	#else
+		sg_init_one(&sg, pos, plen+4);
+	#endif
+		if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
+			return -7;
+	#endif
+	#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+		crc = ~crc32_le(~0, pos, plen);
+	#else
+		crc = ~ether_crc_le(plen, pos);
+	#endif
+		icv[0] = crc;
+		icv[1] = crc >> 8;
+		icv[2] = crc >> 16;
+		icv[3] = crc >> 24;
+		if (memcmp(icv, pos + plen, 4) != 0) {
+			/* ICV mismatch - drop frame */
+			return -2;
+		}
+	}
+	/* Remove IV and ICV */
+	memmove(skb->data + 4, skb->data, hdr_len);
+	skb_pull(skb, 4);
+	skb_trim(skb, skb->len - 4);
+
+	return 0;
+}
+
+
+static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
+{
+	struct prism2_wep_data *wep = priv;
+
+	if (len < 0 || len > WEP_KEY_LEN)
+		return -1;
+
+	memcpy(wep->key, key, len);
+	wep->key_len = len;
+
+	return 0;
+}
+
+
+static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
+{
+	struct prism2_wep_data *wep = priv;
+
+	if (len < wep->key_len)
+		return -1;
+
+	memcpy(key, wep->key, wep->key_len);
+
+	return wep->key_len;
+}
+
+
+static char * prism2_wep_print_stats(char *p, void *priv)
+{
+	struct prism2_wep_data *wep = priv;
+	p += sprintf(p, "key[%d] alg=WEP len=%d\n",
+		     wep->key_idx, wep->key_len);
+	return p;
+}
+
+
+static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
+	.name			= "WEP",
+	.init			= prism2_wep_init,
+	.deinit			= prism2_wep_deinit,
+	.encrypt_mpdu		= prism2_wep_encrypt,
+	.decrypt_mpdu		= prism2_wep_decrypt,
+	.encrypt_msdu		= NULL,
+	.decrypt_msdu		= NULL,
+	.set_key		= prism2_wep_set_key,
+	.get_key		= prism2_wep_get_key,
+	.print_stats		= prism2_wep_print_stats,
+	.extra_prefix_len	= 4, /* IV */
+	.extra_postfix_len	= 4, /* ICV */
+	.owner			= THIS_MODULE,
+};
+
+
+int __init ieee80211_crypto_wep_init(void)
+{
+	return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
+}
+
+
+void __exit ieee80211_crypto_wep_exit(void)
+{
+	ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
+}
+
+void ieee80211_wep_null(void)
+{
+//	printk("============>%s()\n", __FUNCTION__);
+        return;
+}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_wep_null);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
+#endif
+
+//module_init(ieee80211_crypto_wep_init);
+//module_exit(ieee80211_crypto_wep_exit);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
new file mode 100644
index 0000000..16256a3
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c
@@ -0,0 +1,432 @@
+/*******************************************************************************
+
+  Copyright(c) 2004 Intel Corporation. All rights reserved.
+
+  Portions of this file are based on the WEP enablement code provided by the
+  Host AP project hostap-drivers v0.1.3
+  Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+  <jkmaline@cc.hut.fi>
+  Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 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.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+
+  Contact Information:
+  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#include <linux/compiler.h>
+//#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+#include <net/arp.h>
+
+#include "ieee80211.h"
+
+MODULE_DESCRIPTION("802.11 data/management/control stack");
+MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
+MODULE_LICENSE("GPL");
+
+#define DRV_NAME "ieee80211"
+
+static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
+{
+	if (ieee->networks)
+		return 0;
+
+	ieee->networks = kmalloc(
+		MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
+		GFP_KERNEL);
+	if (!ieee->networks) {
+		printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
+		       ieee->dev->name);
+		return -ENOMEM;
+	}
+
+	memset(ieee->networks, 0,
+	       MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
+
+	return 0;
+}
+
+static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
+{
+	if (!ieee->networks)
+		return;
+	kfree(ieee->networks);
+	ieee->networks = NULL;
+}
+
+static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
+{
+	int i;
+
+	INIT_LIST_HEAD(&ieee->network_free_list);
+	INIT_LIST_HEAD(&ieee->network_list);
+	for (i = 0; i < MAX_NETWORK_COUNT; i++)
+		list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
+}
+
+
+struct net_device *alloc_ieee80211(int sizeof_priv)
+{
+	struct ieee80211_device *ieee;
+	struct net_device *dev;
+	int i,err;
+
+	IEEE80211_DEBUG_INFO("Initializing...\n");
+
+	dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
+	if (!dev) {
+		IEEE80211_ERROR("Unable to network device.\n");
+		goto failed;
+	}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+	ieee = netdev_priv(dev);
+#else
+	ieee = (struct ieee80211_device *)dev->priv;
+#endif
+#if 0
+	dev->hard_start_xmit = ieee80211_xmit;
+#endif
+
+	memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
+	ieee->dev = dev;
+
+	err = ieee80211_networks_allocate(ieee);
+	if (err) {
+		IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
+				err);
+		goto failed;
+	}
+	ieee80211_networks_initialize(ieee);
+
+
+	/* Default fragmentation threshold is maximum payload size */
+	ieee->fts = DEFAULT_FTS;
+	ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
+	ieee->open_wep = 1;
+
+	/* Default to enabling full open WEP with host based encrypt/decrypt */
+	ieee->host_encrypt = 1;
+	ieee->host_decrypt = 1;
+	ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
+
+	INIT_LIST_HEAD(&ieee->crypt_deinit_list);
+	init_timer(&ieee->crypt_deinit_timer);
+	ieee->crypt_deinit_timer.data = (unsigned long)ieee;
+	ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
+
+	spin_lock_init(&ieee->lock);
+	spin_lock_init(&ieee->wpax_suitlist_lock);
+	spin_lock_init(&ieee->bw_spinlock);
+	spin_lock_init(&ieee->reorder_spinlock);
+	//added by WB
+	atomic_set(&(ieee->atm_chnlop), 0);
+	atomic_set(&(ieee->atm_swbw), 0);
+
+	ieee->wpax_type_set = 0;
+ 	ieee->wpa_enabled = 0;
+ 	ieee->tkip_countermeasures = 0;
+ 	ieee->drop_unencrypted = 0;
+ 	ieee->privacy_invoked = 0;
+ 	ieee->ieee802_1x = 1;
+	ieee->raw_tx = 0;
+	//ieee->hwsec_support = 1; //defalt support hw security. //use module_param instead.
+	ieee->hwsec_active = 0; //disable hwsec, switch it on when necessary.
+
+	ieee80211_softmac_init(ieee);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
+	ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
+#else
+	ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kmalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
+	memset(ieee->pHTInfo,0,sizeof(RT_HIGH_THROUGHPUT));
+#endif
+	if (ieee->pHTInfo == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
+		return NULL;
+	}
+	HTUpdateDefaultSetting(ieee);
+	HTInitializeHTInfo(ieee); //may move to other place.
+	TSInitialize(ieee);
+#if 0
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+ 	INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq);
+#else
+	INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq, ieee);
+#endif
+#endif
+	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
+
+	for (i = 0; i < 17; i++) {
+	  ieee->last_rxseq_num[i] = -1;
+	  ieee->last_rxfrag_num[i] = -1;
+	  ieee->last_packet_time[i] = 0;
+	}
+
+//These function were added to load crypte module autoly
+	ieee80211_tkip_null();
+	ieee80211_wep_null();
+	ieee80211_ccmp_null();
+
+	return dev;
+
+ failed:
+	if (dev)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+		free_netdev(dev);
+#else
+		kfree(dev);
+#endif
+	return NULL;
+}
+
+
+void free_ieee80211(struct net_device *dev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+	struct ieee80211_device *ieee = netdev_priv(dev);
+#else
+	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
+#endif
+	int i;
+	//struct list_head *p, *q;
+//	del_timer_sync(&ieee->SwBwTimer);
+#if 1
+	if (ieee->pHTInfo != NULL)
+	{
+		kfree(ieee->pHTInfo);
+		ieee->pHTInfo = NULL;
+	}
+#endif
+	RemoveAllTS(ieee);
+	ieee80211_softmac_free(ieee);
+	del_timer_sync(&ieee->crypt_deinit_timer);
+	ieee80211_crypt_deinit_entries(ieee, 1);
+
+	for (i = 0; i < WEP_KEYS; i++) {
+		struct ieee80211_crypt_data *crypt = ieee->crypt[i];
+		if (crypt) {
+			if (crypt->ops) {
+				crypt->ops->deinit(crypt->priv);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+				module_put(crypt->ops->owner);
+#else
+				__MOD_DEC_USE_COUNT(crypt->ops->owner);
+#endif
+			}
+			kfree(crypt);
+			ieee->crypt[i] = NULL;
+		}
+	}
+
+	ieee80211_networks_free(ieee);
+#if 0
+	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
+		list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
+			kfree(list_entry(p, struct ieee_ibss_seq, list));
+			list_del(p);
+		}
+	}
+
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+	free_netdev(dev);
+#else
+	kfree(dev);
+#endif
+}
+
+#ifdef CONFIG_IEEE80211_DEBUG
+
+u32 ieee80211_debug_level = 0;
+static int debug = \
+	//		    IEEE80211_DL_INFO	|
+	//		    IEEE80211_DL_WX	|
+	//		    IEEE80211_DL_SCAN	|
+	//		    IEEE80211_DL_STATE	|
+	//		    IEEE80211_DL_MGMT	|
+	//		    IEEE80211_DL_FRAG	|
+	//		    IEEE80211_DL_EAP	|
+	//		    IEEE80211_DL_DROP	|
+	//		    IEEE80211_DL_TX	|
+	//		    IEEE80211_DL_RX	|
+			    //IEEE80211_DL_QOS    |
+	//		    IEEE80211_DL_HT 	|
+	//		    IEEE80211_DL_TS	|
+//			    IEEE80211_DL_BA 	|
+	//		    IEEE80211_DL_REORDER|
+//			    IEEE80211_DL_TRACE  |
+			    //IEEE80211_DL_DATA	|
+			    IEEE80211_DL_ERR	  //awayls open this flags to show error out
+			    ;
+struct proc_dir_entry *ieee80211_proc = NULL;
+
+static int show_debug_level(char *page, char **start, off_t offset,
+			    int count, int *eof, void *data)
+{
+	return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
+}
+
+static int store_debug_level(struct file *file, const char *buffer,
+			     unsigned long count, void *data)
+{
+	char buf[] = "0x00000000";
+	unsigned long len = min(sizeof(buf) - 1, (u32)count);
+	char *p = (char *)buf;
+	unsigned long val;
+
+	if (copy_from_user(buf, buffer, len))
+		return count;
+	buf[len] = 0;
+	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+		p++;
+		if (p[0] == 'x' || p[0] == 'X')
+			p++;
+		val = simple_strtoul(p, &p, 16);
+	} else
+		val = simple_strtoul(p, &p, 10);
+	if (p == buf)
+		printk(KERN_INFO DRV_NAME
+		       ": %s is not in hex or decimal form.\n", buf);
+	else
+		ieee80211_debug_level = val;
+
+	return strnlen(buf, count);
+}
+
+extern int ieee80211_crypto_init(void);
+extern void ieee80211_crypto_deinit(void);
+extern int ieee80211_crypto_tkip_init(void);
+extern void ieee80211_crypto_tkip_exit(void);
+extern int ieee80211_crypto_ccmp_init(void);
+extern void ieee80211_crypto_ccmp_exit(void);
+extern int ieee80211_crypto_wep_init(void);
+extern void ieee80211_crypto_wep_exit(void);
+
+int __init ieee80211_init(void)
+{
+	struct proc_dir_entry *e;
+	int retval;
+
+	retval = ieee80211_crypto_init();
+	if (retval)
+		return retval;
+	retval = ieee80211_crypto_tkip_init();
+	if (retval) {
+		ieee80211_crypto_deinit();
+		return retval;
+	}
+	retval = ieee80211_crypto_ccmp_init();
+	if (retval) {
+		ieee80211_crypto_tkip_exit();
+		ieee80211_crypto_deinit();
+		return retval;
+	}
+	retval = ieee80211_crypto_wep_init();
+	if (retval) {
+		ieee80211_crypto_ccmp_exit();
+		ieee80211_crypto_tkip_exit();
+		ieee80211_crypto_deinit();
+		return retval;
+	}
+
+	ieee80211_debug_level = debug;
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
+#else
+	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
+#endif
+	if (ieee80211_proc == NULL) {
+		IEEE80211_ERROR("Unable to create " DRV_NAME
+				" proc directory\n");
+		return -EIO;
+	}
+	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
+			      ieee80211_proc);
+	if (!e) {
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		remove_proc_entry(DRV_NAME, proc_net);
+#else
+		remove_proc_entry(DRV_NAME, init_net.proc_net);
+#endif
+		ieee80211_proc = NULL;
+		return -EIO;
+	}
+	e->read_proc = show_debug_level;
+	e->write_proc = store_debug_level;
+	e->data = NULL;
+
+	return 0;
+}
+
+void __exit ieee80211_exit(void)
+{
+	if (ieee80211_proc) {
+		remove_proc_entry("debug_level", ieee80211_proc);
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+		remove_proc_entry(DRV_NAME, proc_net);
+#else
+		remove_proc_entry(DRV_NAME, init_net.proc_net);
+#endif
+		ieee80211_proc = NULL;
+	}
+	ieee80211_crypto_wep_exit();
+	ieee80211_crypto_ccmp_exit();
+	ieee80211_crypto_tkip_exit();
+	ieee80211_crypto_deinit();
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+#include <linux/moduleparam.h>
+module_param(debug, int, 0444);
+MODULE_PARM_DESC(debug, "debug output mask");
+
+
+//module_exit(ieee80211_exit);
+//module_init(ieee80211_init);
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(alloc_ieee80211);
+//EXPORT_SYMBOL(free_ieee80211);
+#else
+EXPORT_SYMBOL_NOVERS(alloc_ieee80211);
+EXPORT_SYMBOL_NOVERS(free_ieee80211);
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
new file mode 100644
index 0000000..5dc478b
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c
@@ -0,0 +1,2802 @@
+/*
+ * Original code based Host AP (software wireless LAN access point) driver
+ * for Intersil Prism2/2.5/3 - hostap.o module, common routines
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. See README and COPYING for
+ * more details.
+ ******************************************************************************
+
+  Few modifications for Realtek's Wi-Fi drivers by
+  Andrea Merello <andreamrl@tiscali.it>
+
+  A special thanks goes to Realtek for their support !
+
+******************************************************************************/
+
+
+#include <linux/compiler.h>
+//#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+#include <linux/ctype.h>
+
+#include "ieee80211.h"
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
+					struct sk_buff *skb,
+					struct ieee80211_rx_stats *rx_stats)
+{
+	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	u16 fc = le16_to_cpu(hdr->frame_ctl);
+
+	skb->dev = ieee->dev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+        skb_reset_mac_header(skb);
+#else
+        skb->mac.raw = skb->data;
+#endif
+
+	skb_pull(skb, ieee80211_get_hdrlen(fc));
+	skb->pkt_type = PACKET_OTHERHOST;
+	skb->protocol = __constant_htons(ETH_P_80211_RAW);
+	memset(skb->cb, 0, sizeof(skb->cb));
+	netif_rx(skb);
+}
+
+
+/* Called only as a tasklet (software IRQ) */
+static struct ieee80211_frag_entry *
+ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
+			  unsigned int frag, u8 tid,u8 *src, u8 *dst)
+{
+	struct ieee80211_frag_entry *entry;
+	int i;
+
+	for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
+		entry = &ieee->frag_cache[tid][i];
+		if (entry->skb != NULL &&
+		    time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
+			IEEE80211_DEBUG_FRAG(
+				"expiring fragment cache entry "
+				"seq=%u last_frag=%u\n",
+				entry->seq, entry->last_frag);
+			dev_kfree_skb_any(entry->skb);
+			entry->skb = NULL;
+		}
+
+		if (entry->skb != NULL && entry->seq == seq &&
+		    (entry->last_frag + 1 == frag || frag == -1) &&
+		    memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
+		    memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
+			return entry;
+	}
+
+	return NULL;
+}
+
+/* Called only as a tasklet (software IRQ) */
+static struct sk_buff *
+ieee80211_frag_cache_get(struct ieee80211_device *ieee,
+			 struct ieee80211_hdr_4addr *hdr)
+{
+	struct sk_buff *skb = NULL;
+	u16 fc = le16_to_cpu(hdr->frame_ctl);
+	u16 sc = le16_to_cpu(hdr->seq_ctl);
+	unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
+	unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
+	struct ieee80211_frag_entry *entry;
+	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
+	u8 tid;
+
+	if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else {
+	  tid = 0;
+	}
+
+	if (frag == 0) {
+		/* Reserve enough space to fit maximum frame length */
+		skb = dev_alloc_skb(ieee->dev->mtu +
+				    sizeof(struct ieee80211_hdr_4addr) +
+				    8 /* LLC */ +
+				    2 /* alignment */ +
+				    8 /* WEP */ +
+				    ETH_ALEN /* WDS */ +
+				    (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
+		if (skb == NULL)
+			return NULL;
+
+		entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
+		ieee->frag_next_idx[tid]++;
+		if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
+			ieee->frag_next_idx[tid] = 0;
+
+		if (entry->skb != NULL)
+			dev_kfree_skb_any(entry->skb);
+
+		entry->first_frag_time = jiffies;
+		entry->seq = seq;
+		entry->last_frag = frag;
+		entry->skb = skb;
+		memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
+		memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
+	} else {
+		/* received a fragment of a frame for which the head fragment
+		 * should have already been received */
+		entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
+						  hdr->addr1);
+		if (entry != NULL) {
+			entry->last_frag = frag;
+			skb = entry->skb;
+		}
+	}
+
+	return skb;
+}
+
+
+/* Called only as a tasklet (software IRQ) */
+static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
+					   struct ieee80211_hdr_4addr *hdr)
+{
+	u16 fc = le16_to_cpu(hdr->frame_ctl);
+	u16 sc = le16_to_cpu(hdr->seq_ctl);
+	unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
+	struct ieee80211_frag_entry *entry;
+	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
+	u8 tid;
+
+	if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else if (IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else {
+	  tid = 0;
+	}
+
+	entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
+					  hdr->addr1);
+
+	if (entry == NULL) {
+		IEEE80211_DEBUG_FRAG(
+			"could not invalidate fragment cache "
+			"entry (seq=%u)\n", seq);
+		return -1;
+	}
+
+	entry->skb = NULL;
+	return 0;
+}
+
+
+
+/* ieee80211_rx_frame_mgtmt
+ *
+ * Responsible for handling management control frames
+ *
+ * Called by ieee80211_rx */
+static inline int
+ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats, u16 type,
+			u16 stype)
+{
+	/* On the struct stats definition there is written that
+	 * this is not mandatory.... but seems that the probe
+	 * response parser uses it
+	 */
+        struct ieee80211_hdr_3addr * hdr = (struct ieee80211_hdr_3addr *)skb->data;
+
+	rx_stats->len = skb->len;
+	ieee80211_rx_mgt(ieee,(struct ieee80211_hdr_4addr *)skb->data,rx_stats);
+        //if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN)))
+        if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames
+        {
+                dev_kfree_skb_any(skb);
+                return 0;
+        }
+
+	ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
+
+	dev_kfree_skb_any(skb);
+
+	return 0;
+
+	#ifdef NOT_YET
+	if (ieee->iw_mode == IW_MODE_MASTER) {
+		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
+		       ieee->dev->name);
+		return 0;
+/*
+  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
+  skb->data);*/
+	}
+
+	if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
+		if (stype == WLAN_FC_STYPE_BEACON &&
+		    ieee->iw_mode == IW_MODE_MASTER) {
+			struct sk_buff *skb2;
+			/* Process beacon frames also in kernel driver to
+			 * update STA(AP) table statistics */
+			skb2 = skb_clone(skb, GFP_ATOMIC);
+			if (skb2)
+				hostap_rx(skb2->dev, skb2, rx_stats);
+		}
+
+		/* send management frames to the user space daemon for
+		 * processing */
+		ieee->apdevstats.rx_packets++;
+		ieee->apdevstats.rx_bytes += skb->len;
+		prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
+		return 0;
+	}
+
+	    if (ieee->iw_mode == IW_MODE_MASTER) {
+		if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
+			printk(KERN_DEBUG "%s: unknown management frame "
+			       "(type=0x%02x, stype=0x%02x) dropped\n",
+			       skb->dev->name, type, stype);
+			return -1;
+		}
+
+		hostap_rx(skb->dev, skb, rx_stats);
+		return 0;
+	}
+
+	printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
+	       "received in non-Host AP mode\n", skb->dev->name);
+	return -1;
+	#endif
+}
+
+
+
+/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
+/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
+static unsigned char rfc1042_header[] =
+{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
+static unsigned char bridge_tunnel_header[] =
+{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
+/* No encapsulation header if EtherType < 0x600 (=length) */
+
+/* Called by ieee80211_rx_frame_decrypt */
+static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
+				    struct sk_buff *skb, size_t hdrlen)
+{
+	struct net_device *dev = ieee->dev;
+	u16 fc, ethertype;
+	struct ieee80211_hdr_4addr *hdr;
+	u8 *pos;
+
+	if (skb->len < 24)
+		return 0;
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	fc = le16_to_cpu(hdr->frame_ctl);
+
+	/* check that the frame is unicast frame to us */
+	if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
+	    IEEE80211_FCTL_TODS &&
+	    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
+	    memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
+		/* ToDS frame with own addr BSSID and DA */
+	} else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
+		   IEEE80211_FCTL_FROMDS &&
+		   memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
+		/* FromDS frame with own addr as DA */
+	} else
+		return 0;
+
+	if (skb->len < 24 + 8)
+		return 0;
+
+	/* check for port access entity Ethernet type */
+//	pos = skb->data + 24;
+	pos = skb->data + hdrlen;
+	ethertype = (pos[6] << 8) | pos[7];
+	if (ethertype == ETH_P_PAE)
+		return 1;
+
+	return 0;
+}
+
+/* Called only as a tasklet (software IRQ), by ieee80211_rx */
+static inline int
+ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
+			   struct ieee80211_crypt_data *crypt)
+{
+	struct ieee80211_hdr_4addr *hdr;
+	int res, hdrlen;
+
+	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
+		return 0;
+#if 1
+	if (ieee->hwsec_active)
+	{
+		cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+		tcb_desc->bHwSec = 1;
+	}
+#endif
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+
+#ifdef CONFIG_IEEE80211_CRYPT_TKIP
+	if (ieee->tkip_countermeasures &&
+	    strcmp(crypt->ops->name, "TKIP") == 0) {
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+			       "received packet from " MAC_FMT "\n",
+			       ieee->dev->name, MAC_ARG(hdr->addr2));
+		}
+		return -1;
+	}
+#endif
+
+	atomic_inc(&crypt->refcnt);
+	res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
+	atomic_dec(&crypt->refcnt);
+	if (res < 0) {
+		IEEE80211_DEBUG_DROP(
+			"decryption failed (SA=" MAC_FMT
+			") res=%d\n", MAC_ARG(hdr->addr2), res);
+		if (res == -2)
+			IEEE80211_DEBUG_DROP("Decryption failed ICV "
+					     "mismatch (key %d)\n",
+					     skb->data[hdrlen + 3] >> 6);
+		ieee->ieee_stats.rx_discards_undecryptable++;
+		return -1;
+	}
+
+	return res;
+}
+
+
+/* Called only as a tasklet (software IRQ), by ieee80211_rx */
+static inline int
+ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
+			     int keyidx, struct ieee80211_crypt_data *crypt)
+{
+	struct ieee80211_hdr_4addr *hdr;
+	int res, hdrlen;
+
+	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
+		return 0;
+	if (ieee->hwsec_active)
+	{
+		cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE);
+		tcb_desc->bHwSec = 1;
+	}
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+
+	atomic_inc(&crypt->refcnt);
+	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
+	atomic_dec(&crypt->refcnt);
+	if (res < 0) {
+		printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
+		       " (SA=" MAC_FMT " keyidx=%d)\n",
+		       ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/* this function is stolen from ipw2200 driver*/
+#define IEEE_PACKET_RETRY_TIME (5*HZ)
+static int is_duplicate_packet(struct ieee80211_device *ieee,
+				      struct ieee80211_hdr_4addr *header)
+{
+	u16 fc = le16_to_cpu(header->frame_ctl);
+	u16 sc = le16_to_cpu(header->seq_ctl);
+	u16 seq = WLAN_GET_SEQ_SEQ(sc);
+	u16 frag = WLAN_GET_SEQ_FRAG(sc);
+	u16 *last_seq, *last_frag;
+	unsigned long *last_time;
+	struct ieee80211_hdr_3addrqos *hdr_3addrqos;
+	struct ieee80211_hdr_4addrqos *hdr_4addrqos;
+	u8 tid;
+
+
+	//TO2DS and QoS
+	if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
+	  hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
+	  tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
+	  hdr_3addrqos = (struct ieee80211_hdr_3addrqos*)header;
+	  tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID;
+	  tid = UP2AC(tid);
+	  tid ++;
+	} else { // no QoS
+	  tid = 0;
+	}
+
+	switch (ieee->iw_mode) {
+	case IW_MODE_ADHOC:
+	{
+		struct list_head *p;
+		struct ieee_ibss_seq *entry = NULL;
+		u8 *mac = header->addr2;
+		int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
+		//for (pos = (head)->next; pos != (head); pos = pos->next)
+		//__list_for_each(p, &ieee->ibss_mac_hash[index]) {
+		list_for_each(p, &ieee->ibss_mac_hash[index]) {
+			entry = list_entry(p, struct ieee_ibss_seq, list);
+			if (!memcmp(entry->mac, mac, ETH_ALEN))
+				break;
+		}
+	//	if (memcmp(entry->mac, mac, ETH_ALEN)){
+		if (p == &ieee->ibss_mac_hash[index]) {
+			entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
+			if (!entry) {
+				printk(KERN_WARNING "Cannot malloc new mac entry\n");
+				return 0;
+			}
+			memcpy(entry->mac, mac, ETH_ALEN);
+			entry->seq_num[tid] = seq;
+			entry->frag_num[tid] = frag;
+			entry->packet_time[tid] = jiffies;
+			list_add(&entry->list, &ieee->ibss_mac_hash[index]);
+			return 0;
+		}
+		last_seq = &entry->seq_num[tid];
+		last_frag = &entry->frag_num[tid];
+		last_time = &entry->packet_time[tid];
+		break;
+	}
+
+	case IW_MODE_INFRA:
+		last_seq = &ieee->last_rxseq_num[tid];
+		last_frag = &ieee->last_rxfrag_num[tid];
+		last_time = &ieee->last_packet_time[tid];
+
+		break;
+	default:
+		return 0;
+	}
+
+//	if(tid != 0) {
+//		printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
+//	}
+	if ((*last_seq == seq) &&
+	    time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
+		if (*last_frag == frag){
+			//printk(KERN_WARNING "[1] go drop!\n");
+			goto drop;
+
+		}
+		if (*last_frag + 1 != frag)
+			/* out-of-order fragment */
+			//printk(KERN_WARNING "[2] go drop!\n");
+			goto drop;
+	} else
+		*last_seq = seq;
+
+	*last_frag = frag;
+	*last_time = jiffies;
+	return 0;
+
+drop:
+//	BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
+//	printk("DUP\n");
+
+	return 1;
+}
+bool
+AddReorderEntry(
+	PRX_TS_RECORD			pTS,
+	PRX_REORDER_ENTRY		pReorderEntry
+	)
+{
+	struct list_head *pList = &pTS->RxPendingPktList;
+#if  1
+	while(pList->next != &pTS->RxPendingPktList)
+	{
+		if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
+		{
+			pList = pList->next;
+		}
+		else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) )
+		{
+			return false;
+		}
+		else
+		{
+			break;
+		}
+	}
+#endif
+	pReorderEntry->List.next = pList->next;
+	pReorderEntry->List.next->prev = &pReorderEntry->List;
+	pReorderEntry->List.prev = pList;
+	pList->next = &pReorderEntry->List;
+
+	return true;
+}
+
+void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index)
+{
+	u8 i = 0 , j=0;
+	u16 ethertype;
+//	if(index > 1)
+//		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): hahahahhhh, We indicate packet from reorder list, index is %u\n",__FUNCTION__,index);
+	for(j = 0; j<index; j++)
+	{
+//added by amy for reorder
+		struct ieee80211_rxb* prxb = prxbIndicateArray[j];
+		for(i = 0; i<prxb->nr_subframes; i++) {
+			struct sk_buff *sub_skb = prxb->subframes[i];
+
+		/* convert hdr + possible LLC headers into Ethernet header */
+			ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
+			if (sub_skb->len >= 8 &&
+				((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
+				  ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
+				 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
+			/* remove RFC1042 or Bridge-Tunnel encapsulation and
+			 * replace EtherType */
+				skb_pull(sub_skb, SNAP_SIZE);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
+			} else {
+				u16 len;
+			/* Leave Ethernet header part of hdr and full payload */
+				len = htons(sub_skb->len);
+				memcpy(skb_push(sub_skb, 2), &len, 2);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN);
+				memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN);
+			}
+			//stats->rx_packets++;
+			//stats->rx_bytes += sub_skb->len;
+
+		/* Indicat the packets to upper layer */
+			if (sub_skb) {
+				//printk("0skb_len(%d)\n", skb->len);
+				sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev);
+				memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
+				sub_skb->dev = ieee->dev;
+				sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
+				//skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
+				ieee->last_rx_ps_time = jiffies;
+				//printk("1skb_len(%d)\n", skb->len);
+				netif_rx(sub_skb);
+			}
+		}
+		kfree(prxb);
+		prxb = NULL;
+	}
+}
+
+
+void RxReorderIndicatePacket( struct ieee80211_device *ieee,
+		struct ieee80211_rxb* prxb,
+		PRX_TS_RECORD		pTS,
+		u16			SeqNum)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PRX_REORDER_ENTRY 	pReorderEntry = NULL;
+	struct ieee80211_rxb* prxbIndicateArray[REORDER_WIN_SIZE];
+	u8			WinSize = pHTInfo->RxReorderWinSize;
+	u16			WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096;
+	u8			index = 0;
+	bool			bMatchWinStart = false, bPktInBuf = false;
+	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize);
+#if 0
+	if(!list_empty(&ieee->RxReorder_Unused_List))
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): ieee->RxReorder_Unused_List is nut NULL\n");
+#endif
+	/* Rx Reorder initialize condition.*/
+	if(pTS->RxIndicateSeq == 0xffff) {
+		pTS->RxIndicateSeq = SeqNum;
+	}
+
+	/* Drop out the packet which SeqNum is smaller than WinStart */
+	if(SN_LESS(SeqNum, pTS->RxIndicateSeq)) {
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n",
+				 pTS->RxIndicateSeq, SeqNum);
+		pHTInfo->RxReorderDropCounter++;
+		{
+			int i;
+			for(i =0; i < prxb->nr_subframes; i++) {
+				dev_kfree_skb(prxb->subframes[i]);
+			}
+			kfree(prxb);
+			prxb = NULL;
+		}
+		return;
+	}
+
+	/*
+	 * Sliding window manipulation. Conditions includes:
+	 * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
+	 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
+	 */
+	if(SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) {
+		pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
+		bMatchWinStart = true;
+	} else if(SN_LESS(WinEnd, SeqNum)) {
+		if(SeqNum >= (WinSize - 1)) {
+			pTS->RxIndicateSeq = SeqNum + 1 -WinSize;
+		} else {
+			pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1;
+		}
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+	}
+
+	/*
+	 * Indication process.
+	 * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
+	 * with the SeqNum smaller than latest WinStart and buffer other packets.
+	 */
+	/* For Rx Reorder condition:
+	 * 1. All packets with SeqNum smaller than WinStart => Indicate
+	 * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
+	 */
+	if(bMatchWinStart) {
+		/* Current packet is going to be indicated.*/
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\
+				pTS->RxIndicateSeq, SeqNum);
+		prxbIndicateArray[0] = prxb;
+//		printk("========================>%s(): SeqNum is %d\n",__FUNCTION__,SeqNum);
+		index = 1;
+	} else {
+		/* Current packet is going to be inserted into pending list.*/
+		//IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): We RX no ordered packed, insert to orderd list\n",__FUNCTION__);
+		if(!list_empty(&ieee->RxReorder_Unused_List)) {
+			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List);
+			list_del_init(&pReorderEntry->List);
+
+			/* Make a reorder entry and insert into a the packet list.*/
+			pReorderEntry->SeqNum = SeqNum;
+			pReorderEntry->prxb = prxb;
+	//		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pREorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
+
+#if 1
+			if(!AddReorderEntry(pTS, pReorderEntry)) {
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n",
+					__FUNCTION__, pTS->RxIndicateSeq, SeqNum);
+				list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
+				{
+					int i;
+					for(i =0; i < prxb->nr_subframes; i++) {
+						dev_kfree_skb(prxb->subframes[i]);
+					}
+					kfree(prxb);
+					prxb = NULL;
+				}
+			} else {
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER,
+					 "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+			}
+#endif
+		}
+		else {
+			/*
+			 * Packets are dropped if there is not enough reorder entries.
+			 * This part shall be modified!! We can just indicate all the
+			 * packets in buffer and get reorder entries.
+			 */
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n");
+			{
+				int i;
+				for(i =0; i < prxb->nr_subframes; i++) {
+					dev_kfree_skb(prxb->subframes[i]);
+				}
+				kfree(prxb);
+				prxb = NULL;
+			}
+		}
+	}
+
+	/* Check if there is any packet need indicate.*/
+	while(!list_empty(&pTS->RxPendingPktList)) {
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__FUNCTION__);
+#if 1
+		pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+		if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) ||
+				SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
+		{
+			/* This protect buffer from overflow. */
+			if(index >= REORDER_WIN_SIZE) {
+				IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n");
+				bPktInBuf = true;
+				break;
+			}
+
+			list_del_init(&pReorderEntry->List);
+
+			if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq))
+				pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096;
+
+			IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum);
+			prxbIndicateArray[index] = pReorderEntry->prxb;
+		//	printk("========================>%s(): pReorderEntry->SeqNum is %d\n",__FUNCTION__,pReorderEntry->SeqNum);
+			index++;
+
+			list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List);
+		} else {
+			bPktInBuf = true;
+			break;
+		}
+#endif
+	}
+
+	/* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/
+	if(index>0) {
+		// Cancel previous pending timer.
+		if (timer_pending(&pTS->RxPktPendingTimer))
+			del_timer_sync(&pTS->RxPktPendingTimer);
+		pTS->RxTimeoutIndicateSeq = 0xffff;
+
+		// Indicate packets
+		if(index>REORDER_WIN_SIZE){
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
+			return;
+		}
+		ieee80211_indicate_packets(ieee, prxbIndicateArray, index);
+		bPktInBuf = false;
+	}
+
+#if 1
+	if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) {
+		// Set new pending timer.
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__);
+		pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
+#if 0
+		if(timer_pending(&pTS->RxPktPendingTimer))
+			del_timer_sync(&pTS->RxPktPendingTimer);
+		pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime);
+		add_timer(&pTS->RxPktPendingTimer);
+#else
+		mod_timer(&pTS->RxPktPendingTimer,  jiffies + MSECS(pHTInfo->RxReorderPendingTime));
+#endif
+	}
+#endif
+}
+
+u8 parse_subframe(struct sk_buff *skb,
+                  struct ieee80211_rx_stats *rx_stats,
+		  struct ieee80211_rxb *rxb,u8* src,u8* dst)
+{
+	struct ieee80211_hdr_3addr  *hdr = (struct ieee80211_hdr_3addr* )skb->data;
+	u16		fc = le16_to_cpu(hdr->frame_ctl);
+
+	u16		LLCOffset= sizeof(struct ieee80211_hdr_3addr);
+	u16		ChkLength;
+	bool		bIsAggregateFrame = false;
+	u16		nSubframe_Length;
+	u8		nPadding_Length = 0;
+	u16		SeqNum=0;
+
+	struct sk_buff *sub_skb;
+	u8             *data_ptr;
+	/* just for debug purpose */
+	SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl));
+
+	if((IEEE80211_QOS_HAS_SEQ(fc))&&\
+			(((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) {
+		bIsAggregateFrame = true;
+	}
+
+	if(IEEE80211_QOS_HAS_SEQ(fc)) {
+		LLCOffset += 2;
+	}
+
+	if(rx_stats->bContainHTC) {
+		LLCOffset += sHTCLng;
+	}
+	//printk("ChkLength = %d\n", LLCOffset);
+	// Null packet, don't indicate it to upper layer
+	ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/
+
+	if( skb->len <= ChkLength ) {
+		return 0;
+	}
+
+	skb_pull(skb, LLCOffset);
+
+	if(!bIsAggregateFrame) {
+		rxb->nr_subframes = 1;
+#ifdef JOHN_NOCPY
+		rxb->subframes[0] = skb;
+#else
+		rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC);
+#endif
+
+		memcpy(rxb->src,src,ETH_ALEN);
+		memcpy(rxb->dst,dst,ETH_ALEN);
+		//IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len);
+		return 1;
+	} else {
+		rxb->nr_subframes = 0;
+		memcpy(rxb->src,src,ETH_ALEN);
+		memcpy(rxb->dst,dst,ETH_ALEN);
+		while(skb->len > ETHERNET_HEADER_SIZE) {
+			/* Offset 12 denote 2 mac address */
+			nSubframe_Length = *((u16*)(skb->data + 12));
+			//==m==>change the length order
+			nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
+
+			if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
+#if 0//cosa
+				RT_ASSERT(
+						(nRemain_Length>=(ETHERNET_HEADER_SIZE + nSubframe_Length)),
+						("ParseSubframe(): A-MSDU subframe parse error!! Subframe Length: %d\n", nSubframe_Length) );
+#endif
+				printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
+						__FUNCTION__,rxb->nr_subframes);
+				printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length);
+				printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length);
+				printk("The Packet SeqNum is %d\n",SeqNum);
+				return 0;
+			}
+
+			/* move the data point to data content */
+			skb_pull(skb, ETHERNET_HEADER_SIZE);
+
+#ifdef JOHN_NOCPY
+			sub_skb = skb_clone(skb, GFP_ATOMIC);
+			sub_skb->len = nSubframe_Length;
+			sub_skb->tail = sub_skb->data + nSubframe_Length;
+#else
+			/* Allocate new skb for releasing to upper layer */
+			sub_skb = dev_alloc_skb(nSubframe_Length + 12);
+			skb_reserve(sub_skb, 12);
+			data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
+			memcpy(data_ptr,skb->data,nSubframe_Length);
+#endif
+			rxb->subframes[rxb->nr_subframes++] = sub_skb;
+			if(rxb->nr_subframes >= MAX_SUBFRAME_COUNT) {
+				IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n");
+				break;
+			}
+			skb_pull(skb,nSubframe_Length);
+
+			if(skb->len != 0) {
+				nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4);
+				if(nPadding_Length == 4) {
+					nPadding_Length = 0;
+				}
+
+				if(skb->len < nPadding_Length) {
+					return 0;
+				}
+
+				skb_pull(skb,nPadding_Length);
+			}
+		}
+#ifdef JOHN_NOCPY
+		dev_kfree_skb(skb);
+#endif
+		//{just for debug added by david
+		//printk("AMSDU::rxb->nr_subframes = %d\n",rxb->nr_subframes);
+		//}
+		return rxb->nr_subframes;
+	}
+}
+
+/* All received frames are sent to this function. @skb contains the frame in
+ * IEEE 802.11 format, i.e., in the format it was sent over air.
+ * This function is called only as a tasklet (software IRQ). */
+int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
+		 struct ieee80211_rx_stats *rx_stats)
+{
+	struct net_device *dev = ieee->dev;
+	struct ieee80211_hdr_4addr *hdr;
+	//struct ieee80211_hdr_3addrqos *hdr;
+
+	size_t hdrlen;
+	u16 fc, type, stype, sc;
+	struct net_device_stats *stats;
+	unsigned int frag;
+	u8 *payload;
+	u16 ethertype;
+	//added by amy for reorder
+	u8	TID = 0;
+	u16	SeqNum = 0;
+	PRX_TS_RECORD pTS = NULL;
+	//bool bIsAggregateFrame = false;
+	//added by amy for reorder
+#ifdef NOT_YET
+	struct net_device *wds = NULL;
+	struct sk_buff *skb2 = NULL;
+	struct net_device *wds = NULL;
+	int frame_authorized = 0;
+	int from_assoc_ap = 0;
+	void *sta = NULL;
+#endif
+//	u16 qos_ctl = 0;
+	u8 dst[ETH_ALEN];
+	u8 src[ETH_ALEN];
+	u8 bssid[ETH_ALEN];
+	struct ieee80211_crypt_data *crypt = NULL;
+	int keyidx = 0;
+
+	int i;
+	struct ieee80211_rxb* rxb = NULL;
+	// cheat the the hdr type
+	hdr = (struct ieee80211_hdr_4addr *)skb->data;
+	stats = &ieee->stats;
+
+	if (skb->len < 10) {
+		printk(KERN_INFO "%s: SKB length < 10\n",
+		       dev->name);
+		goto rx_dropped;
+	}
+
+	fc = le16_to_cpu(hdr->frame_ctl);
+	type = WLAN_FC_GET_TYPE(fc);
+	stype = WLAN_FC_GET_STYPE(fc);
+	sc = le16_to_cpu(hdr->seq_ctl);
+
+	frag = WLAN_GET_SEQ_FRAG(sc);
+	hdrlen = ieee80211_get_hdrlen(fc);
+
+	if(HTCCheck(ieee, skb->data))
+	{
+		if(net_ratelimit())
+		printk("find HTCControl\n");
+		hdrlen += 4;
+		rx_stats->bContainHTC = 1;
+	}
+
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+#ifdef NOT_YET
+#if WIRELESS_EXT > 15
+	/* Put this code here so that we avoid duplicating it in all
+	 * Rx paths. - Jean II */
+#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
+	/* If spy monitoring on */
+	if (iface->spy_data.spy_number > 0) {
+		struct iw_quality wstats;
+		wstats.level = rx_stats->rssi;
+		wstats.noise = rx_stats->noise;
+		wstats.updated = 6;	/* No qual value */
+		/* Update spy records */
+		wireless_spy_update(dev, hdr->addr2, &wstats);
+	}
+#endif /* IW_WIRELESS_SPY */
+#endif /* WIRELESS_EXT > 15 */
+	hostap_update_rx_stats(local->ap, hdr, rx_stats);
+#endif
+
+#if WIRELESS_EXT > 15
+	if (ieee->iw_mode == IW_MODE_MONITOR) {
+		ieee80211_monitor_rx(ieee, skb, rx_stats);
+		stats->rx_packets++;
+		stats->rx_bytes += skb->len;
+		return 1;
+	}
+#endif
+	if (ieee->host_decrypt) {
+		int idx = 0;
+		if (skb->len >= hdrlen + 3)
+			idx = skb->data[hdrlen + 3] >> 6;
+		crypt = ieee->crypt[idx];
+#ifdef NOT_YET
+		sta = NULL;
+
+		/* Use station specific key to override default keys if the
+		 * receiver address is a unicast address ("individual RA"). If
+		 * bcrx_sta_key parameter is set, station specific key is used
+		 * even with broad/multicast targets (this is against IEEE
+		 * 802.11, but makes it easier to use different keys with
+		 * stations that do not support WEP key mapping). */
+
+		if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
+			(void) hostap_handle_sta_crypto(local, hdr, &crypt,
+							&sta);
+#endif
+
+		/* allow NULL decrypt to indicate an station specific override
+		 * for default encryption */
+		if (crypt && (crypt->ops == NULL ||
+			      crypt->ops->decrypt_mpdu == NULL))
+			crypt = NULL;
+
+		if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
+			/* This seems to be triggered by some (multicast?)
+			 * frames from other than current BSS, so just drop the
+			 * frames silently instead of filling system log with
+			 * these reports. */
+			IEEE80211_DEBUG_DROP("Decryption failed (not set)"
+					     " (SA=" MAC_FMT ")\n",
+					     MAC_ARG(hdr->addr2));
+			ieee->ieee_stats.rx_discards_undecryptable++;
+			goto rx_dropped;
+		}
+	}
+
+	if (skb->len < IEEE80211_DATA_HDR3_LEN)
+		goto rx_dropped;
+
+	// if QoS enabled, should check the sequence for each of the AC
+	if( (ieee->pHTInfo->bCurRxReorderEnable == false) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)){
+		if (is_duplicate_packet(ieee, hdr))
+		goto rx_dropped;
+
+	}
+	else
+	{
+		PRX_TS_RECORD pRxTS = NULL;
+	#if 0
+		struct ieee80211_hdr_3addr *hdr;
+		u16 fc;
+		hdr = (struct ieee80211_hdr_3addr *)skb->data;
+		fc = le16_to_cpu(hdr->frame_ctl);
+		u8 tmp = (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS);
+
+		u8 tid = (*((u8*)skb->data + (((fc& IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))?30:24)))&0xf;
+		printk("====================>fc:%x, tid:%d, tmp:%d\n", fc, tid, tmp);
+		//u8 tid =  (u8)((frameqos*)(buf + ((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24))->field.tid;
+	#endif
+			//IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__FUNCTION__, tid);
+#if 1
+		if(GetTs(
+				ieee,
+				(PTS_COMMON_INFO*) &pRxTS,
+				hdr->addr2,
+				(u8)Frame_QoSTID((u8*)(skb->data)),
+				RX_DIR,
+				true))
+		{
+
+		//	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): pRxTS->RxLastFragNum is %d,frag is %d,pRxTS->RxLastSeqNum is %d,seq is %d\n",__FUNCTION__,pRxTS->RxLastFragNum,frag,pRxTS->RxLastSeqNum,WLAN_GET_SEQ_SEQ(sc));
+			if( 	(fc & (1<<11))  &&
+					(frag == pRxTS->RxLastFragNum) &&
+					(WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)	)
+			{
+				goto rx_dropped;
+			}
+			else
+			{
+				pRxTS->RxLastFragNum = frag;
+				pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc);
+			}
+		}
+		else
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__FUNCTION__);
+			goto rx_dropped;
+		}
+	}
+#endif
+	if (type == IEEE80211_FTYPE_MGMT) {
+
+	#if 0
+		if ( stype == IEEE80211_STYPE_AUTH &&
+		    fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
+		    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
+		{
+			printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
+			       "from " MAC_FMT "\n", dev->name,
+			       MAC_ARG(hdr->addr2));
+			/* TODO: could inform hostapd about this so that it
+			 * could send auth failure report */
+			goto rx_dropped;
+		}
+	#endif
+
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+		if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
+			goto rx_dropped;
+		else
+			goto rx_exit;
+	}
+
+	/* Data frame - extract src/dst addresses */
+	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
+	case IEEE80211_FCTL_FROMDS:
+		memcpy(dst, hdr->addr1, ETH_ALEN);
+		memcpy(src, hdr->addr3, ETH_ALEN);
+		memcpy(bssid, hdr->addr2, ETH_ALEN);
+		break;
+	case IEEE80211_FCTL_TODS:
+		memcpy(dst, hdr->addr3, ETH_ALEN);
+		memcpy(src, hdr->addr2, ETH_ALEN);
+		memcpy(bssid, hdr->addr1, ETH_ALEN);
+		break;
+	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
+		if (skb->len < IEEE80211_DATA_HDR4_LEN)
+			goto rx_dropped;
+		memcpy(dst, hdr->addr3, ETH_ALEN);
+		memcpy(src, hdr->addr4, ETH_ALEN);
+		memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
+		break;
+	case 0:
+		memcpy(dst, hdr->addr1, ETH_ALEN);
+		memcpy(src, hdr->addr2, ETH_ALEN);
+		memcpy(bssid, hdr->addr3, ETH_ALEN);
+		break;
+	}
+
+#ifdef NOT_YET
+	if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
+		goto rx_dropped;
+	if (wds) {
+		skb->dev = dev = wds;
+		stats = hostap_get_stats(dev);
+	}
+
+	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
+	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
+	    ieee->stadev &&
+	    memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
+		/* Frame from BSSID of the AP for which we are a client */
+		skb->dev = dev = ieee->stadev;
+		stats = hostap_get_stats(dev);
+		from_assoc_ap = 1;
+	}
+#endif
+
+	dev->last_rx = jiffies;
+
+#ifdef NOT_YET
+	if ((ieee->iw_mode == IW_MODE_MASTER ||
+	     ieee->iw_mode == IW_MODE_REPEAT) &&
+	    !from_assoc_ap) {
+		switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
+					     wds != NULL)) {
+		case AP_RX_CONTINUE_NOT_AUTHORIZED:
+			frame_authorized = 0;
+			break;
+		case AP_RX_CONTINUE:
+			frame_authorized = 1;
+			break;
+		case AP_RX_DROP:
+			goto rx_dropped;
+		case AP_RX_EXIT:
+			goto rx_exit;
+		}
+	}
+#endif
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+	/* Nullfunc frames may have PS-bit set, so they must be passed to
+	 * hostap_handle_sta_rx() before being dropped here. */
+	if (stype != IEEE80211_STYPE_DATA &&
+	    stype != IEEE80211_STYPE_DATA_CFACK &&
+	    stype != IEEE80211_STYPE_DATA_CFPOLL &&
+	    stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
+	    stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
+	    ) {
+		if (stype != IEEE80211_STYPE_NULLFUNC)
+			IEEE80211_DEBUG_DROP(
+				"RX: dropped data frame "
+				"with no data (type=0x%02x, "
+				"subtype=0x%02x, len=%d)\n",
+				type, stype, skb->len);
+		goto rx_dropped;
+	}
+        if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
+                goto rx_dropped;
+
+	/* skb: hdr + (possibly fragmented, possibly encrypted) payload */
+
+	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
+	    (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
+	{
+		printk("decrypt frame error\n");
+		goto rx_dropped;
+	}
+
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+
+	/* skb: hdr + (possibly fragmented) plaintext payload */
+	// PR: FIXME: hostap has additional conditions in the "if" below:
+	// ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
+	if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
+		int flen;
+		struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
+		IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
+
+		if (!frag_skb) {
+			IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
+					"Rx cannot get skb from fragment "
+					"cache (morefrag=%d seq=%u frag=%u)\n",
+					(fc & IEEE80211_FCTL_MOREFRAGS) != 0,
+					WLAN_GET_SEQ_SEQ(sc), frag);
+			goto rx_dropped;
+		}
+		flen = skb->len;
+		if (frag != 0)
+			flen -= hdrlen;
+
+		if (frag_skb->tail + flen > frag_skb->end) {
+			printk(KERN_WARNING "%s: host decrypted and "
+			       "reassembled frame did not fit skb\n",
+			       dev->name);
+			ieee80211_frag_cache_invalidate(ieee, hdr);
+			goto rx_dropped;
+		}
+
+		if (frag == 0) {
+			/* copy first fragment (including full headers) into
+			 * beginning of the fragment cache skb */
+			memcpy(skb_put(frag_skb, flen), skb->data, flen);
+		} else {
+			/* append frame payload to the end of the fragment
+			 * cache skb */
+			memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
+			       flen);
+		}
+		dev_kfree_skb_any(skb);
+		skb = NULL;
+
+		if (fc & IEEE80211_FCTL_MOREFRAGS) {
+			/* more fragments expected - leave the skb in fragment
+			 * cache for now; it will be delivered to upper layers
+			 * after all fragments have been received */
+			goto rx_exit;
+		}
+
+		/* this was the last fragment and the frame will be
+		 * delivered, so remove skb from fragment cache */
+		skb = frag_skb;
+		hdr = (struct ieee80211_hdr_4addr *) skb->data;
+		ieee80211_frag_cache_invalidate(ieee, hdr);
+	}
+
+	/* skb: hdr + (possible reassembled) full MSDU payload; possibly still
+	 * encrypted/authenticated */
+	if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
+	    ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
+	{
+		printk("==>decrypt msdu error\n");
+		goto rx_dropped;
+	}
+
+	//added by amy for AP roaming
+	ieee->LinkDetectInfo.NumRecvDataInPeriod++;
+	ieee->LinkDetectInfo.NumRxOkInPeriod++;
+
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
+	if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
+		if (/*ieee->ieee802_1x &&*/
+		    ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
+
+#ifdef CONFIG_IEEE80211_DEBUG
+			/* pass unencrypted EAPOL frames even if encryption is
+			 * configured */
+			struct eapol *eap = (struct eapol *)(skb->data +
+				24);
+			IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
+						eap_get_type(eap->type));
+#endif
+		} else {
+			IEEE80211_DEBUG_DROP(
+				"encryption configured, but RX "
+				"frame not encrypted (SA=" MAC_FMT ")\n",
+				MAC_ARG(hdr->addr2));
+			goto rx_dropped;
+		}
+	}
+
+#ifdef CONFIG_IEEE80211_DEBUG
+	if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
+	    ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
+			struct eapol *eap = (struct eapol *)(skb->data +
+				24);
+			IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
+						eap_get_type(eap->type));
+	}
+#endif
+
+	if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
+	    !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
+		IEEE80211_DEBUG_DROP(
+			"dropped unencrypted RX data "
+			"frame from " MAC_FMT
+			" (drop_unencrypted=1)\n",
+			MAC_ARG(hdr->addr2));
+		goto rx_dropped;
+	}
+/*
+	if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
+		printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
+	}
+*/
+//added by amy for reorder
+#if 1
+	if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data)
+		&& !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1))
+	{
+		TID = Frame_QoSTID(skb->data);
+		SeqNum = WLAN_GET_SEQ_SEQ(sc);
+		GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true);
+		if(TID !=0 && TID !=3)
+		{
+			ieee->bis_any_nonbepkts = true;
+		}
+	}
+#endif
+//added by amy for reorder
+	/* skb: hdr + (possible reassembled) full plaintext payload */
+	payload = skb->data + hdrlen;
+	//ethertype = (payload[6] << 8) | payload[7];
+	rxb = (struct ieee80211_rxb*)kmalloc(sizeof(struct ieee80211_rxb),GFP_ATOMIC);
+	if(rxb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__);
+		goto rx_dropped;
+	}
+	/* to parse amsdu packets */
+	/* qos data packets & reserved bit is 1 */
+	if(parse_subframe(skb,rx_stats,rxb,src,dst) == 0) {
+		/* only to free rxb, and not submit the packets to upper layer */
+		for(i =0; i < rxb->nr_subframes; i++) {
+			dev_kfree_skb(rxb->subframes[i]);
+		}
+		kfree(rxb);
+		rxb = NULL;
+		goto rx_dropped;
+	}
+
+	ieee->last_rx_ps_time = jiffies;
+//added by amy for reorder
+	if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){
+//added by amy for reorder
+		for(i = 0; i<rxb->nr_subframes; i++) {
+			struct sk_buff *sub_skb = rxb->subframes[i];
+
+			if (sub_skb) {
+				/* convert hdr + possible LLC headers into Ethernet header */
+				ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7];
+				if (sub_skb->len >= 8 &&
+						((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 &&
+						  ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
+						 memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) {
+					/* remove RFC1042 or Bridge-Tunnel encapsulation and
+					 * replace EtherType */
+					skb_pull(sub_skb, SNAP_SIZE);
+					memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
+					memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
+				} else {
+					u16 len;
+					/* Leave Ethernet header part of hdr and full payload */
+					len = htons(sub_skb->len);
+					memcpy(skb_push(sub_skb, 2), &len, 2);
+					memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN);
+					memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN);
+				}
+
+				stats->rx_packets++;
+				stats->rx_bytes += sub_skb->len;
+				if(is_multicast_ether_addr(dst)) {
+					stats->multicast++;
+				}
+
+				/* Indicat the packets to upper layer */
+				//printk("0skb_len(%d)\n", skb->len);
+				sub_skb->protocol = eth_type_trans(sub_skb, dev);
+				memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
+				sub_skb->dev = dev;
+				sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
+				//skb->ip_summed = CHECKSUM_UNNECESSARY; /* 802.11 crc not sufficient */
+				//printk("1skb_len(%d)\n", skb->len);
+				netif_rx(sub_skb);
+			}
+		}
+		kfree(rxb);
+		rxb = NULL;
+
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__FUNCTION__);
+		RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum);
+	}
+#ifndef JOHN_NOCPY
+	dev_kfree_skb(skb);
+#endif
+
+ rx_exit:
+#ifdef NOT_YET
+	if (sta)
+		hostap_handle_sta_release(sta);
+#endif
+	return 1;
+
+ rx_dropped:
+	if (rxb != NULL)
+	{
+		kfree(rxb);
+		rxb = NULL;
+	}
+	stats->rx_dropped++;
+
+	/* Returning 0 indicates to caller that we have not handled the SKB--
+	 * so it is still allocated and can be used again by underlying
+	 * hardware as a DMA target */
+	return 0;
+}
+
+#define MGMT_FRAME_FIXED_PART_LENGTH            0x24
+
+static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+/*
+* Make ther structure we read from the beacon packet has
+* the right values
+*/
+static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element
+                                     *info_element, int sub_type)
+{
+
+        if (info_element->qui_subtype != sub_type)
+                return -1;
+        if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN))
+                return -1;
+        if (info_element->qui_type != QOS_OUI_TYPE)
+                return -1;
+        if (info_element->version != QOS_VERSION_1)
+                return -1;
+
+        return 0;
+}
+
+
+/*
+ * Parse a QoS parameter element
+ */
+static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info
+                                            *element_param, struct ieee80211_info_element
+                                            *info_element)
+{
+        int ret = 0;
+        u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2;
+
+        if ((info_element == NULL) || (element_param == NULL))
+                return -1;
+
+        if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) {
+                memcpy(element_param->info_element.qui, info_element->data,
+                       info_element->len);
+                element_param->info_element.elementID = info_element->id;
+                element_param->info_element.length = info_element->len;
+        } else
+                ret = -1;
+        if (ret == 0)
+                ret = ieee80211_verify_qos_info(&element_param->info_element,
+                                                QOS_OUI_PARAM_SUB_TYPE);
+        return ret;
+}
+
+/*
+ * Parse a QoS information element
+ */
+static int ieee80211_read_qos_info_element(struct
+                                           ieee80211_qos_information_element
+                                           *element_info, struct ieee80211_info_element
+                                           *info_element)
+{
+        int ret = 0;
+        u16 size = sizeof(struct ieee80211_qos_information_element) - 2;
+
+        if (element_info == NULL)
+                return -1;
+        if (info_element == NULL)
+                return -1;
+
+        if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) {
+                memcpy(element_info->qui, info_element->data,
+                       info_element->len);
+                element_info->elementID = info_element->id;
+                element_info->length = info_element->len;
+        } else
+                ret = -1;
+
+        if (ret == 0)
+                ret = ieee80211_verify_qos_info(element_info,
+                                                QOS_OUI_INFO_SUB_TYPE);
+        return ret;
+}
+
+
+/*
+ * Write QoS parameters from the ac parameters.
+ */
+static int ieee80211_qos_convert_ac_to_parameters(struct
+                                                  ieee80211_qos_parameter_info
+                                                  *param_elm, struct
+                                                  ieee80211_qos_parameters
+                                                  *qos_param)
+{
+        int rc = 0;
+        int i;
+        struct ieee80211_qos_ac_parameter *ac_params;
+	u8 aci;
+        //u8 cw_min;
+        //u8 cw_max;
+
+        for (i = 0; i < QOS_QUEUE_NUM; i++) {
+                ac_params = &(param_elm->ac_params_record[i]);
+
+		aci = (ac_params->aci_aifsn & 0x60) >> 5;
+
+		if(aci >= QOS_QUEUE_NUM)
+			continue;
+                qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f;
+
+		/* WMM spec P.11: The minimum value for AIFSN shall be 2 */
+                qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci];
+
+                qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F;
+
+                qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4;
+
+                qos_param->flag[aci] =
+                    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
+                qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit);
+        }
+        return rc;
+}
+
+/*
+ * we have a generic data element which it may contain QoS information or
+ * parameters element. check the information element length to decide
+ * which type to read
+ */
+static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
+                                             *info_element,
+                                             struct ieee80211_network *network)
+{
+        int rc = 0;
+        struct ieee80211_qos_parameters *qos_param = NULL;
+        struct ieee80211_qos_information_element qos_info_element;
+
+        rc = ieee80211_read_qos_info_element(&qos_info_element, info_element);
+
+        if (rc == 0) {
+                network->qos_data.param_count = qos_info_element.ac_info & 0x0F;
+                network->flags |= NETWORK_HAS_QOS_INFORMATION;
+        } else {
+                struct ieee80211_qos_parameter_info param_element;
+
+                rc = ieee80211_read_qos_param_element(&param_element,
+                                                      info_element);
+                if (rc == 0) {
+                        qos_param = &(network->qos_data.parameters);
+                        ieee80211_qos_convert_ac_to_parameters(&param_element,
+                                                               qos_param);
+                        network->flags |= NETWORK_HAS_QOS_PARAMETERS;
+                        network->qos_data.param_count =
+                            param_element.info_element.ac_info & 0x0F;
+                }
+        }
+
+        if (rc == 0) {
+                IEEE80211_DEBUG_QOS("QoS is supported\n");
+                network->qos_data.supported = 1;
+        }
+        return rc;
+}
+
+#ifdef CONFIG_IEEE80211_DEBUG
+#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
+
+static const char *get_info_element_string(u16 id)
+{
+        switch (id) {
+                MFIE_STRING(SSID);
+                MFIE_STRING(RATES);
+                MFIE_STRING(FH_SET);
+                MFIE_STRING(DS_SET);
+                MFIE_STRING(CF_SET);
+                MFIE_STRING(TIM);
+                MFIE_STRING(IBSS_SET);
+                MFIE_STRING(COUNTRY);
+                MFIE_STRING(HOP_PARAMS);
+                MFIE_STRING(HOP_TABLE);
+                MFIE_STRING(REQUEST);
+                MFIE_STRING(CHALLENGE);
+                MFIE_STRING(POWER_CONSTRAINT);
+                MFIE_STRING(POWER_CAPABILITY);
+                MFIE_STRING(TPC_REQUEST);
+                MFIE_STRING(TPC_REPORT);
+                MFIE_STRING(SUPP_CHANNELS);
+                MFIE_STRING(CSA);
+                MFIE_STRING(MEASURE_REQUEST);
+                MFIE_STRING(MEASURE_REPORT);
+                MFIE_STRING(QUIET);
+                MFIE_STRING(IBSS_DFS);
+               // MFIE_STRING(ERP_INFO);
+                MFIE_STRING(RSN);
+                MFIE_STRING(RATES_EX);
+                MFIE_STRING(GENERIC);
+                MFIE_STRING(QOS_PARAMETER);
+        default:
+                return "UNKNOWN";
+        }
+}
+#endif
+
+#ifdef ENABLE_DOT11D
+static inline void ieee80211_extract_country_ie(
+	struct ieee80211_device *ieee,
+	struct ieee80211_info_element *info_element,
+	struct ieee80211_network *network,
+	u8 * addr2
+)
+{
+	if(IS_DOT11D_ENABLE(ieee))
+	{
+		if(info_element->len!= 0)
+		{
+			memcpy(network->CountryIeBuf, info_element->data, info_element->len);
+			network->CountryIeLen = info_element->len;
+
+			if(!IS_COUNTRY_IE_VALID(ieee))
+			{
+				Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
+			}
+		}
+
+		//
+		// 070305, rcnjko: I update country IE watch dog here because
+		// some AP (e.g. Cisco 1242) don't include country IE in their
+		// probe response frame.
+		//
+		if(IS_EQUAL_CIE_SRC(ieee, addr2) )
+		{
+			UPDATE_CIE_WATCHDOG(ieee);
+		}
+	}
+
+}
+#endif
+
+int ieee80211_parse_info_param(struct ieee80211_device *ieee,
+		struct ieee80211_info_element *info_element,
+		u16 length,
+		struct ieee80211_network *network,
+		struct ieee80211_rx_stats *stats)
+{
+	u8 i;
+	short offset;
+        u16	tmp_htcap_len=0;
+	u16	tmp_htinfo_len=0;
+	u16 ht_realtek_agg_len=0;
+	u8  ht_realtek_agg_buf[MAX_IE_LEN];
+//	u16 broadcom_len = 0;
+#ifdef CONFIG_IEEE80211_DEBUG
+	char rates_str[64];
+	char *p;
+#endif
+
+	while (length >= sizeof(*info_element)) {
+		if (sizeof(*info_element) + info_element->len > length) {
+			IEEE80211_DEBUG_MGMT("Info elem: parse failed: "
+					     "info_element->len + 2 > left : "
+					     "info_element->len+2=%zd left=%d, id=%d.\n",
+					     info_element->len +
+					     sizeof(*info_element),
+					     length, info_element->id);
+			/* We stop processing but don't return an error here
+			 * because some misbehaviour APs break this rule. ie.
+			 * Orinoco AP1000. */
+			break;
+		}
+
+		switch (info_element->id) {
+		case MFIE_TYPE_SSID:
+			if (ieee80211_is_empty_essid(info_element->data,
+						     info_element->len)) {
+				network->flags |= NETWORK_EMPTY_ESSID;
+				break;
+			}
+
+			network->ssid_len = min(info_element->len,
+						(u8) IW_ESSID_MAX_SIZE);
+			memcpy(network->ssid, info_element->data, network->ssid_len);
+			if (network->ssid_len < IW_ESSID_MAX_SIZE)
+				memset(network->ssid + network->ssid_len, 0,
+				       IW_ESSID_MAX_SIZE - network->ssid_len);
+
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n",
+					     network->ssid, network->ssid_len);
+			break;
+
+		case MFIE_TYPE_RATES:
+#ifdef CONFIG_IEEE80211_DEBUG
+			p = rates_str;
+#endif
+			network->rates_len = min(info_element->len,
+						 MAX_RATES_LENGTH);
+			for (i = 0; i < network->rates_len; i++) {
+				network->rates[i] = info_element->data[i];
+#ifdef CONFIG_IEEE80211_DEBUG
+				p += snprintf(p, sizeof(rates_str) -
+					      (p - rates_str), "%02X ",
+					      network->rates[i]);
+#endif
+				if (ieee80211_is_ofdm_rate
+				    (info_element->data[i])) {
+					network->flags |= NETWORK_HAS_OFDM;
+					if (info_element->data[i] &
+					    IEEE80211_BASIC_RATE_MASK)
+						network->flags &=
+						    ~NETWORK_HAS_CCK;
+				}
+			}
+
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n",
+					     rates_str, network->rates_len);
+			break;
+
+		case MFIE_TYPE_RATES_EX:
+#ifdef CONFIG_IEEE80211_DEBUG
+			p = rates_str;
+#endif
+			network->rates_ex_len = min(info_element->len,
+						    MAX_RATES_EX_LENGTH);
+			for (i = 0; i < network->rates_ex_len; i++) {
+				network->rates_ex[i] = info_element->data[i];
+#ifdef CONFIG_IEEE80211_DEBUG
+				p += snprintf(p, sizeof(rates_str) -
+					      (p - rates_str), "%02X ",
+					      network->rates[i]);
+#endif
+				if (ieee80211_is_ofdm_rate
+				    (info_element->data[i])) {
+					network->flags |= NETWORK_HAS_OFDM;
+					if (info_element->data[i] &
+					    IEEE80211_BASIC_RATE_MASK)
+						network->flags &=
+						    ~NETWORK_HAS_CCK;
+				}
+			}
+
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
+					     rates_str, network->rates_ex_len);
+			break;
+
+		case MFIE_TYPE_DS_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n",
+					     info_element->data[0]);
+			network->channel = info_element->data[0];
+			break;
+
+		case MFIE_TYPE_FH_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n");
+			break;
+
+		case MFIE_TYPE_CF_SET:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n");
+			break;
+
+		case MFIE_TYPE_TIM:
+			if(info_element->len < 4)
+				break;
+
+			network->tim.tim_count = info_element->data[0];
+			network->tim.tim_period = info_element->data[1];
+
+                        network->dtim_period = info_element->data[1];
+                        if(ieee->state != IEEE80211_LINKED)
+                                break;
+#if 0
+                        network->last_dtim_sta_time[0] = stats->mac_time[0];
+#else
+			//we use jiffies for legacy Power save
+			network->last_dtim_sta_time[0] = jiffies;
+#endif
+                        network->last_dtim_sta_time[1] = stats->mac_time[1];
+
+                        network->dtim_data = IEEE80211_DTIM_VALID;
+
+                        if(info_element->data[0] != 0)
+                                break;
+
+                        if(info_element->data[2] & 1)
+                                network->dtim_data |= IEEE80211_DTIM_MBCAST;
+
+                        offset = (info_element->data[2] >> 1)*2;
+
+                        //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
+
+                        if(ieee->assoc_id < 8*offset ||
+                                ieee->assoc_id > 8*(offset + info_element->len -3))
+
+                                break;
+
+                        offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ;
+
+                        if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
+                                network->dtim_data |= IEEE80211_DTIM_UCAST;
+
+			//IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
+			break;
+
+		case MFIE_TYPE_ERP:
+			network->erp_value = info_element->data[0];
+			network->flags |= NETWORK_HAS_ERP_VALUE;
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
+					     network->erp_value);
+			break;
+		case MFIE_TYPE_IBSS_SET:
+			network->atim_window = info_element->data[0];
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n",
+					     network->atim_window);
+			break;
+
+		case MFIE_TYPE_CHALLENGE:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n");
+			break;
+
+		case MFIE_TYPE_GENERIC:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n",
+					     info_element->len);
+			if (!ieee80211_parse_qos_info_param_IE(info_element,
+							       network))
+				break;
+
+			if (info_element->len >= 4 &&
+			    info_element->data[0] == 0x00 &&
+			    info_element->data[1] == 0x50 &&
+			    info_element->data[2] == 0xf2 &&
+			    info_element->data[3] == 0x01) {
+				network->wpa_ie_len = min(info_element->len + 2,
+							  MAX_WPA_IE_LEN);
+				memcpy(network->wpa_ie, info_element,
+				       network->wpa_ie_len);
+				break;
+			}
+
+#ifdef THOMAS_TURBO
+                        if (info_element->len == 7 &&
+                            info_element->data[0] == 0x00 &&
+                            info_element->data[1] == 0xe0 &&
+                            info_element->data[2] == 0x4c &&
+                            info_element->data[3] == 0x01 &&
+                            info_element->data[4] == 0x02) {
+                                network->Turbo_Enable = 1;
+                        }
+#endif
+
+                        //for HTcap and HTinfo parameters
+			if(tmp_htcap_len == 0){
+				if(info_element->len >= 4 &&
+				   info_element->data[0] == 0x00 &&
+				   info_element->data[1] == 0x90 &&
+				   info_element->data[2] == 0x4c &&
+				   info_element->data[3] == 0x033){
+
+						tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
+				   		if(tmp_htcap_len != 0){
+				   			network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+							network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
+								sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
+							memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
+				   		}
+				}
+				if(tmp_htcap_len != 0)
+					network->bssht.bdSupportHT = true;
+				else
+					network->bssht.bdSupportHT = false;
+			}
+
+
+			if(tmp_htinfo_len == 0){
+				if(info_element->len >= 4 &&
+					info_element->data[0] == 0x00 &&
+				   	info_element->data[1] == 0x90 &&
+				   	info_element->data[2] == 0x4c &&
+				   	info_element->data[3] == 0x034){
+
+						tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
+						if(tmp_htinfo_len != 0){
+							network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+							if(tmp_htinfo_len){
+								network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
+									sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
+								memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
+							}
+
+						}
+
+				}
+			}
+
+			if(ieee->aggregation){
+				if(network->bssht.bdSupportHT){
+					if(info_element->len >= 4 &&
+						info_element->data[0] == 0x00 &&
+						info_element->data[1] == 0xe0 &&
+						info_element->data[2] == 0x4c &&
+						info_element->data[3] == 0x02){
+
+						ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN);
+						memcpy(ht_realtek_agg_buf,info_element->data,info_element->len);
+
+					}
+					if(ht_realtek_agg_len >= 5){
+						network->bssht.bdRT2RTAggregation = true;
+
+						if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02))
+						network->bssht.bdRT2RTLongSlotTime = true;
+					}
+				}
+
+			}
+
+			//if(tmp_htcap_len !=0  ||  tmp_htinfo_len != 0)
+			{
+				if((info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x05 &&
+					 info_element->data[2] == 0xb5) ||
+					 (info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x0a &&
+					 info_element->data[2] == 0xf7) ||
+					 (info_element->len >= 3 &&
+					 info_element->data[0] == 0x00 &&
+					 info_element->data[1] == 0x10 &&
+					 info_element->data[2] == 0x18)){
+
+						network->broadcom_cap_exist = true;
+
+				}
+			}
+#if 0
+			if (tmp_htcap_len !=0)
+				{
+					u16 cap_ext = ((PHT_CAPABILITY_ELE)&info_element->data[0])->ExtHTCapInfo;
+					if ((cap_ext & 0x0c00) == 0x0c00)
+						{
+							network->ralink_cap_exist = true;
+						}
+				}
+#endif
+			if(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x0c &&
+				info_element->data[2] == 0x43)
+			{
+				network->ralink_cap_exist = true;
+			}
+			else
+				network->ralink_cap_exist = false;
+			//added by amy for atheros AP
+			if((info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x03 &&
+				info_element->data[2] == 0x7f) ||
+				(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x13 &&
+				info_element->data[2] == 0x74))
+			{
+				printk("========>%s(): athros AP is exist\n",__FUNCTION__);
+				network->atheros_cap_exist = true;
+			}
+			else
+				network->atheros_cap_exist = false;
+
+			if(info_element->len >= 3 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96)
+			{
+				network->cisco_cap_exist = true;
+			}
+			else
+				network->cisco_cap_exist = false;
+			//added by amy for LEAP of cisco
+			if(info_element->len > 4 &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96 &&
+				info_element->data[3] == 0x01)
+			{
+				if(info_element->len == 6)
+				{
+					memcpy(network->CcxRmState, &info_element[4], 2);
+					if(network->CcxRmState[0] != 0)
+					{
+						network->bCcxRmEnable = true;
+					}
+					else
+						network->bCcxRmEnable = false;
+					//
+					// CCXv4 Table 59-1 MBSSID Masks.
+					//
+					network->MBssidMask = network->CcxRmState[1] & 0x07;
+					if(network->MBssidMask != 0)
+					{
+						network->bMBssidValid = true;
+						network->MBssidMask = 0xff << (network->MBssidMask);
+						cpMacAddr(network->MBssid, network->bssid);
+						network->MBssid[5] &= network->MBssidMask;
+					}
+					else
+					{
+						network->bMBssidValid = false;
+					}
+				}
+				else
+				{
+					network->bCcxRmEnable = false;
+				}
+			}
+			if(info_element->len > 4  &&
+				info_element->data[0] == 0x00 &&
+				info_element->data[1] == 0x40 &&
+				info_element->data[2] == 0x96 &&
+				info_element->data[3] == 0x03)
+			{
+				if(info_element->len == 5)
+				{
+					network->bWithCcxVerNum = true;
+					network->BssCcxVerNumber = info_element->data[4];
+				}
+				else
+				{
+					network->bWithCcxVerNum = false;
+					network->BssCcxVerNumber = 0;
+				}
+			}
+			break;
+
+		case MFIE_TYPE_RSN:
+			IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n",
+					     info_element->len);
+			network->rsn_ie_len = min(info_element->len + 2,
+						  MAX_WPA_IE_LEN);
+			memcpy(network->rsn_ie, info_element,
+			       network->rsn_ie_len);
+			break;
+
+                        //HT related element.
+		case MFIE_TYPE_HT_CAP:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n",
+					     info_element->len);
+			tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN);
+			if(tmp_htcap_len != 0){
+				network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC;
+				network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\
+					sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len;
+				memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen);
+
+				//If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
+				// windows driver will update WMM parameters each beacon received once connected
+                                // Linux driver is a bit different.
+				network->bssht.bdSupportHT = true;
+			}
+			else
+				network->bssht.bdSupportHT = false;
+			break;
+
+
+		case MFIE_TYPE_HT_INFO:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n",
+					     info_element->len);
+			tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN);
+			if(tmp_htinfo_len){
+				network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE;
+				network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\
+					sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len;
+				memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen);
+			}
+			break;
+
+		case MFIE_TYPE_AIRONET:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n",
+					     info_element->len);
+			if(info_element->len >IE_CISCO_FLAG_POSITION)
+			{
+				network->bWithAironetIE = true;
+
+				// CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23):
+				// "A Cisco access point advertises support for CKIP in beacon and probe response packets,
+				//  by adding an Aironet element and setting one or both of the CKIP negotiation bits."
+				if(	(info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC)	||
+					(info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK)	)
+				{
+		 			network->bCkipSupported = true;
+				}
+				else
+				{
+					network->bCkipSupported = false;
+				}
+			}
+			else
+			{
+				network->bWithAironetIE = false;
+		 		network->bCkipSupported = false;
+			}
+			break;
+		case MFIE_TYPE_QOS_PARAMETER:
+			printk(KERN_ERR
+			       "QoS Error need to parse QOS_PARAMETER IE\n");
+			break;
+
+#ifdef ENABLE_DOT11D
+		case MFIE_TYPE_COUNTRY:
+			IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
+					     info_element->len);
+			//printk("=====>Receive <%s> Country IE\n",network->ssid);
+			ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP
+			break;
+#endif
+/* TODO */
+#if 0
+			/* 802.11h */
+		case MFIE_TYPE_POWER_CONSTRAINT:
+			network->power_constraint = info_element->data[0];
+			network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
+			break;
+
+		case MFIE_TYPE_CSA:
+			network->power_constraint = info_element->data[0];
+			network->flags |= NETWORK_HAS_CSA;
+			break;
+
+		case MFIE_TYPE_QUIET:
+			network->quiet.count = info_element->data[0];
+			network->quiet.period = info_element->data[1];
+			network->quiet.duration = info_element->data[2];
+			network->quiet.offset = info_element->data[3];
+			network->flags |= NETWORK_HAS_QUIET;
+			break;
+
+		case MFIE_TYPE_IBSS_DFS:
+			if (network->ibss_dfs)
+				break;
+			network->ibss_dfs = kmemdup(info_element->data,
+						    info_element->len,
+						    GFP_ATOMIC);
+			if (!network->ibss_dfs)
+				return 1;
+			network->flags |= NETWORK_HAS_IBSS_DFS;
+			break;
+
+		case MFIE_TYPE_TPC_REPORT:
+			network->tpc_report.transmit_power =
+			    info_element->data[0];
+			network->tpc_report.link_margin = info_element->data[1];
+			network->flags |= NETWORK_HAS_TPC_REPORT;
+			break;
+#endif
+		default:
+			IEEE80211_DEBUG_MGMT
+			    ("Unsupported info element: %s (%d)\n",
+			     get_info_element_string(info_element->id),
+			     info_element->id);
+			break;
+		}
+
+		length -= sizeof(*info_element) + info_element->len;
+		info_element =
+		    (struct ieee80211_info_element *)&info_element->
+		    data[info_element->len];
+	}
+
+	if(!network->atheros_cap_exist && !network->broadcom_cap_exist &&
+		!network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation)
+	{
+		network->unknown_cap_exist = true;
+	}
+	else
+	{
+		network->unknown_cap_exist = false;
+	}
+	return 0;
+}
+
+static inline u8 ieee80211_SignalStrengthTranslate(
+	u8  CurrSS
+	)
+{
+	u8 RetSS;
+
+	// Step 1. Scale mapping.
+	if(CurrSS >= 71 && CurrSS <= 100)
+	{
+		RetSS = 90 + ((CurrSS - 70) / 3);
+	}
+	else if(CurrSS >= 41 && CurrSS <= 70)
+	{
+		RetSS = 78 + ((CurrSS - 40) / 3);
+	}
+	else if(CurrSS >= 31 && CurrSS <= 40)
+	{
+		RetSS = 66 + (CurrSS - 30);
+	}
+	else if(CurrSS >= 21 && CurrSS <= 30)
+	{
+		RetSS = 54 + (CurrSS - 20);
+	}
+	else if(CurrSS >= 5 && CurrSS <= 20)
+	{
+		RetSS = 42 + (((CurrSS - 5) * 2) / 3);
+	}
+	else if(CurrSS == 4)
+	{
+		RetSS = 36;
+	}
+	else if(CurrSS == 3)
+	{
+		RetSS = 27;
+	}
+	else if(CurrSS == 2)
+	{
+		RetSS = 18;
+	}
+	else if(CurrSS == 1)
+	{
+		RetSS = 9;
+	}
+	else
+	{
+		RetSS = CurrSS;
+	}
+	//RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
+
+	// Step 2. Smoothing.
+
+	//RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing:  LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
+
+	return RetSS;
+}
+
+long ieee80211_translate_todbm(u8 signal_strength_index	)// 0-100 index.
+{
+	long	signal_power; // in dBm.
+
+	// Translate to dBm (x=0.5y-95).
+	signal_power = (long)((signal_strength_index + 1) >> 1);
+	signal_power -= 95;
+
+	return signal_power;
+}
+
+static inline int ieee80211_network_init(
+	struct ieee80211_device *ieee,
+	struct ieee80211_probe_response *beacon,
+	struct ieee80211_network *network,
+	struct ieee80211_rx_stats *stats)
+{
+#ifdef CONFIG_IEEE80211_DEBUG
+	//char rates_str[64];
+	//char *p;
+#endif
+
+        network->qos_data.active = 0;
+        network->qos_data.supported = 0;
+        network->qos_data.param_count = 0;
+        network->qos_data.old_param_count = 0;
+
+	/* Pull out fixed field data */
+	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+	network->capability = le16_to_cpu(beacon->capability);
+	network->last_scanned = jiffies;
+	network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]);
+	network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]);
+	network->beacon_interval = le32_to_cpu(beacon->beacon_interval);
+	/* Where to pull this? beacon->listen_interval;*/
+	network->listen_interval = 0x0A;
+	network->rates_len = network->rates_ex_len = 0;
+	network->last_associate = 0;
+	network->ssid_len = 0;
+	network->flags = 0;
+	network->atim_window = 0;
+	network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ?
+            0x3 : 0x0;
+	network->berp_info_valid = false;
+        network->broadcom_cap_exist = false;
+	network->ralink_cap_exist = false;
+	network->atheros_cap_exist = false;
+	network->cisco_cap_exist = false;
+	network->unknown_cap_exist = false;
+#ifdef THOMAS_TURBO
+	network->Turbo_Enable = 0;
+#endif
+#ifdef ENABLE_DOT11D
+	network->CountryIeLen = 0;
+	memset(network->CountryIeBuf, 0, MAX_IE_LEN);
+#endif
+//Initialize HT parameters
+	//ieee80211_ht_initialize(&network->bssht);
+	HTInitializeBssDesc(&network->bssht);
+	if (stats->freq == IEEE80211_52GHZ_BAND) {
+		/* for A band (No DS info) */
+		network->channel = stats->received_channel;
+	} else
+		network->flags |= NETWORK_HAS_CCK;
+
+ 	network->wpa_ie_len = 0;
+ 	network->rsn_ie_len = 0;
+
+        if (ieee80211_parse_info_param
+            (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats))
+                return 1;
+
+	network->mode = 0;
+	if (stats->freq == IEEE80211_52GHZ_BAND)
+		network->mode = IEEE_A;
+	else {
+		if (network->flags & NETWORK_HAS_OFDM)
+			network->mode |= IEEE_G;
+		if (network->flags & NETWORK_HAS_CCK)
+			network->mode |= IEEE_B;
+	}
+
+	if (network->mode == 0) {
+		IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+				     "network.\n",
+				     escape_essid(network->ssid,
+						  network->ssid_len),
+				     MAC_ARG(network->bssid));
+		return 1;
+	}
+
+	if(network->bssht.bdSupportHT){
+		if(network->mode == IEEE_A)
+			network->mode = IEEE_N_5G;
+		else if(network->mode & (IEEE_G | IEEE_B))
+			network->mode = IEEE_N_24G;
+	}
+	if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
+		network->flags |= NETWORK_EMPTY_ESSID;
+
+#if 1
+	stats->signal = 30 + (stats->SignalStrength * 70) / 100;
+	//stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
+	stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25;
+#endif
+
+	memcpy(&network->stats, stats, sizeof(network->stats));
+
+	return 0;
+}
+
+static inline int is_same_network(struct ieee80211_network *src,
+				  struct ieee80211_network *dst, struct ieee80211_device* ieee)
+{
+	/* A network is only a duplicate if the channel, BSSID, ESSID
+	 * and the capability field (in particular IBSS and BSS) all match.
+	 * We treat all <hidden> with the same BSSID and channel
+	 * as one network */
+	return //((src->ssid_len == dst->ssid_len) &&
+		(((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
+		(src->channel == dst->channel) &&
+		!memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
+		//!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
+		(!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) &&
+		((src->capability & WLAN_CAPABILITY_IBSS) ==
+		(dst->capability & WLAN_CAPABILITY_IBSS)) &&
+		((src->capability & WLAN_CAPABILITY_BSS) ==
+		(dst->capability & WLAN_CAPABILITY_BSS)));
+}
+
+static inline void update_network(struct ieee80211_network *dst,
+				  struct ieee80211_network *src)
+{
+	int qos_active;
+	u8 old_param;
+
+	memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
+	dst->capability = src->capability;
+	memcpy(dst->rates, src->rates, src->rates_len);
+	dst->rates_len = src->rates_len;
+	memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
+	dst->rates_ex_len = src->rates_ex_len;
+	if(src->ssid_len > 0)
+	{
+		memset(dst->ssid, 0, dst->ssid_len);
+		dst->ssid_len = src->ssid_len;
+		memcpy(dst->ssid, src->ssid, src->ssid_len);
+	}
+	dst->mode = src->mode;
+	dst->flags = src->flags;
+	dst->time_stamp[0] = src->time_stamp[0];
+	dst->time_stamp[1] = src->time_stamp[1];
+	if (src->flags & NETWORK_HAS_ERP_VALUE)
+	{
+		dst->erp_value = src->erp_value;
+		dst->berp_info_valid = src->berp_info_valid = true;
+	}
+	dst->beacon_interval = src->beacon_interval;
+	dst->listen_interval = src->listen_interval;
+	dst->atim_window = src->atim_window;
+	dst->dtim_period = src->dtim_period;
+	dst->dtim_data = src->dtim_data;
+	dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
+	dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
+	memcpy(&dst->tim, &src->tim, sizeof(struct ieee80211_tim_parameters));
+
+        dst->bssht.bdSupportHT = src->bssht.bdSupportHT;
+	dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation;
+	dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen;
+	memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen);
+	dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen;
+	memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen);
+	dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer;
+	dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime;
+	dst->broadcom_cap_exist = src->broadcom_cap_exist;
+	dst->ralink_cap_exist = src->ralink_cap_exist;
+	dst->atheros_cap_exist = src->atheros_cap_exist;
+	dst->cisco_cap_exist = src->cisco_cap_exist;
+	dst->unknown_cap_exist = src->unknown_cap_exist;
+	memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
+	dst->wpa_ie_len = src->wpa_ie_len;
+	memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
+	dst->rsn_ie_len = src->rsn_ie_len;
+
+	dst->last_scanned = jiffies;
+	/* qos related parameters */
+	//qos_active = src->qos_data.active;
+	qos_active = dst->qos_data.active;
+	//old_param = dst->qos_data.old_param_count;
+	old_param = dst->qos_data.param_count;
+	if(dst->flags & NETWORK_HAS_QOS_MASK){
+        //not update QOS paramter in beacon, as most AP will set all these parameter to 0.//WB
+	//	printk("====>%s(), aifs:%x, %x\n", __FUNCTION__, dst->qos_data.parameters.aifs[0], src->qos_data.parameters.aifs[0]);
+	//	memcpy(&dst->qos_data, &src->qos_data,
+	//		sizeof(struct ieee80211_qos_data));
+	}
+	else {
+		dst->qos_data.supported = src->qos_data.supported;
+		dst->qos_data.param_count = src->qos_data.param_count;
+	}
+
+	if(dst->qos_data.supported == 1) {
+		dst->QoS_Enable = 1;
+		if(dst->ssid_len)
+			IEEE80211_DEBUG_QOS
+				("QoS the network %s is QoS supported\n",
+				dst->ssid);
+		else
+			IEEE80211_DEBUG_QOS
+				("QoS the network is QoS supported\n");
+	}
+	dst->qos_data.active = qos_active;
+	dst->qos_data.old_param_count = old_param;
+
+	/* dst->last_associate is not overwritten */
+#if 1
+	dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
+	if(src->wmm_param[0].ac_aci_acm_aifsn|| \
+	   src->wmm_param[1].ac_aci_acm_aifsn|| \
+	   src->wmm_param[2].ac_aci_acm_aifsn|| \
+	   src->wmm_param[1].ac_aci_acm_aifsn) {
+	  memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
+	}
+	//dst->QoS_Enable = src->QoS_Enable;
+#else
+	dst->QoS_Enable = 1;//for Rtl8187 simulation
+#endif
+#ifdef THOMAS_TURBO
+	dst->Turbo_Enable = src->Turbo_Enable;
+#endif
+
+#ifdef ENABLE_DOT11D
+	dst->CountryIeLen = src->CountryIeLen;
+	memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
+#endif
+
+	//added by amy for LEAP
+	dst->bWithAironetIE = src->bWithAironetIE;
+	dst->bCkipSupported = src->bCkipSupported;
+	memcpy(dst->CcxRmState,src->CcxRmState,2);
+	dst->bCcxRmEnable = src->bCcxRmEnable;
+	dst->MBssidMask = src->MBssidMask;
+	dst->bMBssidValid = src->bMBssidValid;
+	memcpy(dst->MBssid,src->MBssid,6);
+	dst->bWithCcxVerNum = src->bWithCcxVerNum;
+	dst->BssCcxVerNumber = src->BssCcxVerNumber;
+
+}
+
+static inline int is_beacon(__le16 fc)
+{
+	return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
+}
+
+static inline void ieee80211_process_probe_response(
+	struct ieee80211_device *ieee,
+	struct ieee80211_probe_response *beacon,
+	struct ieee80211_rx_stats *stats)
+{
+	struct ieee80211_network network;
+	struct ieee80211_network *target;
+	struct ieee80211_network *oldest = NULL;
+#ifdef CONFIG_IEEE80211_DEBUG
+	struct ieee80211_info_element *info_element = &beacon->info_element[0];
+#endif
+	unsigned long flags;
+	short renew;
+	//u8 wmm_info;
+
+	memset(&network, 0, sizeof(struct ieee80211_network));
+	IEEE80211_DEBUG_SCAN(
+		"'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+		escape_essid(info_element->data, info_element->len),
+		MAC_ARG(beacon->header.addr3),
+		(beacon->capability & (1<<0xf)) ? '1' : '0',
+		(beacon->capability & (1<<0xe)) ? '1' : '0',
+		(beacon->capability & (1<<0xd)) ? '1' : '0',
+		(beacon->capability & (1<<0xc)) ? '1' : '0',
+		(beacon->capability & (1<<0xb)) ? '1' : '0',
+		(beacon->capability & (1<<0xa)) ? '1' : '0',
+		(beacon->capability & (1<<0x9)) ? '1' : '0',
+		(beacon->capability & (1<<0x8)) ? '1' : '0',
+		(beacon->capability & (1<<0x7)) ? '1' : '0',
+		(beacon->capability & (1<<0x6)) ? '1' : '0',
+		(beacon->capability & (1<<0x5)) ? '1' : '0',
+		(beacon->capability & (1<<0x4)) ? '1' : '0',
+		(beacon->capability & (1<<0x3)) ? '1' : '0',
+		(beacon->capability & (1<<0x2)) ? '1' : '0',
+		(beacon->capability & (1<<0x1)) ? '1' : '0',
+		(beacon->capability & (1<<0x0)) ? '1' : '0');
+
+	if (ieee80211_network_init(ieee, beacon, &network, stats)) {
+		IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+				     escape_essid(info_element->data,
+						  info_element->len),
+				     MAC_ARG(beacon->header.addr3),
+				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+				     IEEE80211_STYPE_PROBE_RESP ?
+				     "PROBE RESPONSE" : "BEACON");
+		return;
+	}
+
+#ifdef ENABLE_DOT11D
+	// For Asus EeePc request,
+	// (1) if wireless adapter receive get any 802.11d country code in AP beacon,
+	//	   wireless adapter should follow the country code.
+	// (2)  If there is no any country code in beacon,
+	//       then wireless adapter should do active scan from ch1~11 and
+	//       passive scan from ch12~14
+
+	if( !IsLegalChannel(ieee, network.channel) )
+		return;
+	if(ieee->bGlobalDomain)
+	{
+		if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
+		{
+			// Case 1: Country code
+			if(IS_COUNTRY_IE_VALID(ieee) )
+			{
+				if( !IsLegalChannel(ieee, network.channel) )
+				{
+					printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
+					return;
+				}
+			}
+			// Case 2: No any country code.
+			else
+			{
+				// Filter over channel ch12~14
+				if(network.channel > 11)
+				{
+					printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
+					return;
+				}
+			}
+		}
+		else
+		{
+			// Case 1: Country code
+			if(IS_COUNTRY_IE_VALID(ieee) )
+			{
+				if( !IsLegalChannel(ieee, network.channel) )
+				{
+					printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
+					return;
+				}
+			}
+			// Case 2: No any country code.
+			else
+			{
+				// Filter over channel ch12~14
+				if(network.channel > 14)
+				{
+					printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
+					return;
+				}
+			}
+		}
+	}
+#endif
+
+	/* The network parsed correctly -- so now we scan our known networks
+	 * to see if we can find it in our list.
+	 *
+	 * NOTE:  This search is definitely not optimized.  Once its doing
+	 *        the "right thing" we'll optimize it for efficiency if
+	 *        necessary */
+
+	/* Search for this entry in the list and update it if it is
+	 * already there. */
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if(is_same_network(&ieee->current_network, &network, ieee)) {
+		update_network(&ieee->current_network, &network);
+		if((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G)
+		&& ieee->current_network.berp_info_valid){
+		if(ieee->current_network.erp_value& ERP_UseProtection)
+			ieee->current_network.buseprotection = true;
+		else
+			ieee->current_network.buseprotection = false;
+		}
+		if(is_beacon(beacon->header.frame_ctl))
+		{
+			if(ieee->state == IEEE80211_LINKED)
+				ieee->LinkDetectInfo.NumRecvBcnInPeriod++;
+		}
+		else //hidden AP
+			network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
+	}
+
+	list_for_each_entry(target, &ieee->network_list, list) {
+		if (is_same_network(target, &network, ieee))
+			break;
+		if ((oldest == NULL) ||
+		    (target->last_scanned < oldest->last_scanned))
+			oldest = target;
+	}
+
+	/* If we didn't find a match, then get a new network slot to initialize
+	 * with this beacon's information */
+	if (&target->list == &ieee->network_list) {
+		if (list_empty(&ieee->network_free_list)) {
+			/* If there are no more slots, expire the oldest */
+			list_del(&oldest->list);
+			target = oldest;
+			IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+					     "network list.\n",
+					     escape_essid(target->ssid,
+							  target->ssid_len),
+					     MAC_ARG(target->bssid));
+		} else {
+			/* Otherwise just pull from the free list */
+			target = list_entry(ieee->network_free_list.next,
+					    struct ieee80211_network, list);
+			list_del(ieee->network_free_list.next);
+		}
+
+
+#ifdef CONFIG_IEEE80211_DEBUG
+		IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+				     escape_essid(network.ssid,
+						  network.ssid_len),
+				     MAC_ARG(network.bssid),
+				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+				     IEEE80211_STYPE_PROBE_RESP ?
+				     "PROBE RESPONSE" : "BEACON");
+#endif
+		memcpy(target, &network, sizeof(*target));
+		list_add_tail(&target->list, &ieee->network_list);
+		if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
+			ieee80211_softmac_new_net(ieee,&network);
+	} else {
+		IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+				     escape_essid(target->ssid,
+						  target->ssid_len),
+				     MAC_ARG(target->bssid),
+				     WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
+				     IEEE80211_STYPE_PROBE_RESP ?
+				     "PROBE RESPONSE" : "BEACON");
+
+		/* we have an entry and we are going to update it. But this entry may
+		 * be already expired. In this case we do the same as we found a new
+		 * net and call the new_net handler
+		 */
+		renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
+		//YJ,add,080819,for hidden ap
+		if(is_beacon(beacon->header.frame_ctl) == 0)
+			network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
+		//if(strncmp(network.ssid, "linksys-c",9) == 0)
+		//	printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
+		if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
+		    && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
+		    ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
+			renew = 1;
+		//YJ,add,080819,for hidden ap,end
+
+		update_network(target, &network);
+		if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
+			ieee80211_softmac_new_net(ieee,&network);
+	}
+
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\
+		(ieee->state == IEEE80211_LINKED)) {
+		if(ieee->handle_beacon != NULL) {
+			ieee->handle_beacon(ieee->dev,beacon,&ieee->current_network);
+		}
+	}
+}
+
+void ieee80211_rx_mgt(struct ieee80211_device *ieee,
+		      struct ieee80211_hdr_4addr *header,
+		      struct ieee80211_rx_stats *stats)
+{
+	if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
+				ieee->iw_mode == IW_MODE_INFRA &&
+				ieee->state == IEEE80211_LINKED))
+	{
+		tasklet_schedule(&ieee->ps_task);
+	}
+
+	if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
+		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
+		ieee->last_rx_ps_time = jiffies;
+
+	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+
+	case IEEE80211_STYPE_BEACON:
+		IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
+				     WLAN_FC_GET_STYPE(header->frame_ctl));
+		IEEE80211_DEBUG_SCAN("Beacon\n");
+		ieee80211_process_probe_response(
+			ieee, (struct ieee80211_probe_response *)header, stats);
+		break;
+
+	case IEEE80211_STYPE_PROBE_RESP:
+		IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
+				     WLAN_FC_GET_STYPE(header->frame_ctl));
+		IEEE80211_DEBUG_SCAN("Probe response\n");
+		ieee80211_process_probe_response(
+			ieee, (struct ieee80211_probe_response *)header, stats);
+		break;
+
+	}
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_rx_mgt);
+//EXPORT_SYMBOL(ieee80211_rx);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
+EXPORT_SYMBOL_NOVERS(ieee80211_rx);
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
new file mode 100644
index 0000000..2fc04df
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c
@@ -0,0 +1,3548 @@
+/* IEEE 802.11 SoftMAC layer
+ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Mostly extracted from the rtl8180-sa2400 driver for the
+ * in-kernel generic ieee802.11 stack.
+ *
+ * Few lines might be stolen from other part of the ieee80211
+ * stack. Copyright who own it's copyright
+ *
+ * WPA code stolen from the ipw2200 driver.
+ * Copyright who own it's copyright.
+ *
+ * released under the GPL
+ */
+
+
+#include "ieee80211.h"
+
+#include <linux/random.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+
+u8 rsn_authen_cipher_suite[16][4] = {
+	{0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
+	{0x00,0x0F,0xAC,0x01}, //WEP-40         //RSNA default
+	{0x00,0x0F,0xAC,0x02}, //TKIP           //NONE		//{used just as default}
+	{0x00,0x0F,0xAC,0x03}, //WRAP-historical
+	{0x00,0x0F,0xAC,0x04}, //CCMP
+	{0x00,0x0F,0xAC,0x05}, //WEP-104
+};
+
+short ieee80211_is_54g(struct ieee80211_network net)
+{
+	return ((net.rates_ex_len > 0) || (net.rates_len > 4));
+}
+
+short ieee80211_is_shortslot(struct ieee80211_network net)
+{
+	return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
+}
+
+/* returns the total length needed for pleacing the RATE MFIE
+ * tag and the EXTENDED RATE MFIE tag if needed.
+ * It encludes two bytes per tag for the tag itself and its len
+ */
+unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
+{
+	unsigned int rate_len = 0;
+
+	if (ieee->modulation & IEEE80211_CCK_MODULATION)
+		rate_len = IEEE80211_CCK_RATE_LEN + 2;
+
+	if (ieee->modulation & IEEE80211_OFDM_MODULATION)
+
+		rate_len += IEEE80211_OFDM_RATE_LEN + 2;
+
+	return rate_len;
+}
+
+/* pleace the MFIE rate, tag to the memory (double) poined.
+ * Then it updates the pointer so that
+ * it points after the new MFIE tag added.
+ */
+void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
+{
+	u8 *tag = *tag_p;
+
+	if (ieee->modulation & IEEE80211_CCK_MODULATION){
+		*tag++ = MFIE_TYPE_RATES;
+		*tag++ = 4;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+	}
+
+	/* We may add an option for custom rates that specific HW might support */
+	*tag_p = tag;
+}
+
+void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
+{
+	u8 *tag = *tag_p;
+
+		if (ieee->modulation & IEEE80211_OFDM_MODULATION){
+
+		*tag++ = MFIE_TYPE_RATES_EX;
+		*tag++ = 8;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
+		*tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
+
+	}
+
+	/* We may add an option for custom rates that specific HW might support */
+	*tag_p = tag;
+}
+
+
+void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
+	u8 *tag = *tag_p;
+
+	*tag++ = MFIE_TYPE_GENERIC; //0
+	*tag++ = 7;
+	*tag++ = 0x00;
+	*tag++ = 0x50;
+	*tag++ = 0xf2;
+	*tag++ = 0x02;//5
+	*tag++ = 0x00;
+	*tag++ = 0x01;
+#ifdef SUPPORT_USPD
+	if(ieee->current_network.wmm_info & 0x80) {
+		*tag++ = 0x0f|MAX_SP_Len;
+	} else {
+		*tag++ = MAX_SP_Len;
+	}
+#else
+	*tag++ = MAX_SP_Len;
+#endif
+	*tag_p = tag;
+}
+
+#ifdef THOMAS_TURBO
+void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
+	u8 *tag = *tag_p;
+
+        *tag++ = MFIE_TYPE_GENERIC; //0
+        *tag++ = 7;
+        *tag++ = 0x00;
+        *tag++ = 0xe0;
+        *tag++ = 0x4c;
+        *tag++ = 0x01;//5
+        *tag++ = 0x02;
+        *tag++ = 0x11;
+	*tag++ = 0x00;
+
+	*tag_p = tag;
+	printk(KERN_ALERT "This is enable turbo mode IE process\n");
+}
+#endif
+
+void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+	int nh;
+	nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
+
+/*
+ * if the queue is full but we have newer frames then
+ * just overwrites the oldest.
+ *
+ * if (nh == ieee->mgmt_queue_tail)
+ *		return -1;
+ */
+	ieee->mgmt_queue_head = nh;
+	ieee->mgmt_queue_ring[nh] = skb;
+
+	//return 0;
+}
+
+struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
+{
+	struct sk_buff *ret;
+
+	if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
+		return NULL;
+
+	ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
+
+	ieee->mgmt_queue_tail =
+		(ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
+
+	return ret;
+}
+
+void init_mgmt_queue(struct ieee80211_device *ieee)
+{
+	ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
+}
+
+u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
+{
+	PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
+	u8 rate;
+
+	// 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
+	if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
+		rate = 0x0c;
+	else
+		rate = ieee->basic_rate & 0x7f;
+
+	if(rate == 0){
+		// 2005.01.26, by rcnjko.
+		if(ieee->mode == IEEE_A||
+		   ieee->mode== IEEE_N_5G||
+		   (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
+			rate = 0x0c;
+		else
+			rate = 0x02;
+	}
+
+	/*
+	// Data rate of ProbeReq is already decided. Annie, 2005-03-31
+	if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
+	{
+	if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
+	rate = 0x0c;
+	else
+	rate = 0x02;
+	}
+	 */
+	return rate;
+}
+
+
+void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
+
+inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
+	struct ieee80211_hdr_3addr  *header=
+		(struct ieee80211_hdr_3addr  *) skb->data;
+
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	/* called with 2nd param 0, no mgmt lock required */
+	ieee80211_sta_wakeup(ieee,0);
+
+	tcb_desc->queue_index = MGNT_QUEUE;
+	tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
+        tcb_desc->RATRIndex = 7;
+        tcb_desc->bTxDisableRateFallBack = 1;
+        tcb_desc->bTxUseDriverAssingedRate = 1;
+
+	if(single){
+		if(ieee->queue_stop){
+			enqueue_mgmt(ieee,skb);
+		}else{
+			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
+
+			if (ieee->seq_ctrl[0] == 0xFFF)
+				ieee->seq_ctrl[0] = 0;
+			else
+				ieee->seq_ctrl[0]++;
+
+			/* avoid watchdog triggers */
+	//		ieee->dev->trans_start = jiffies;
+			ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
+			//dev_kfree_skb_any(skb);//edit by thomas
+		}
+
+		spin_unlock_irqrestore(&ieee->lock, flags);
+	}else{
+		spin_unlock_irqrestore(&ieee->lock, flags);
+		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
+
+		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+
+		if (ieee->seq_ctrl[0] == 0xFFF)
+			ieee->seq_ctrl[0] = 0;
+		else
+			ieee->seq_ctrl[0]++;
+
+		/* check wether the managed packet queued greater than 5 */
+		if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
+				(skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
+				(ieee->queue_stop) ) {
+			/* insert the skb packet to the management queue */
+			/* as for the completion function, it does not need
+			 * to check it any more.
+			 * */
+			//printk("%s():insert to waitqueue!\n",__FUNCTION__);
+			skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
+		} else {
+			//printk("TX packet!\n");
+			ieee->softmac_hard_start_xmit(skb,ieee->dev);
+			//dev_kfree_skb_any(skb);//edit by thomas
+		}
+		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
+	}
+}
+
+inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
+{
+
+	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
+	struct ieee80211_hdr_3addr  *header =
+		(struct ieee80211_hdr_3addr  *) skb->data;
+        cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
+
+	tcb_desc->queue_index = MGNT_QUEUE;
+	tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
+	tcb_desc->RATRIndex = 7;
+	tcb_desc->bTxDisableRateFallBack = 1;
+	tcb_desc->bTxUseDriverAssingedRate = 1;
+	//printk("=============>%s()\n", __FUNCTION__);
+	if(single){
+
+		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+
+		if (ieee->seq_ctrl[0] == 0xFFF)
+			ieee->seq_ctrl[0] = 0;
+		else
+			ieee->seq_ctrl[0]++;
+
+		/* avoid watchdog triggers */
+	//	ieee->dev->trans_start = jiffies;
+		ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
+
+	}else{
+
+		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+
+		if (ieee->seq_ctrl[0] == 0xFFF)
+			ieee->seq_ctrl[0] = 0;
+		else
+			ieee->seq_ctrl[0]++;
+
+		ieee->softmac_hard_start_xmit(skb,ieee->dev);
+
+	}
+	//dev_kfree_skb_any(skb);//edit by thomas
+}
+
+inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
+{
+	unsigned int len,rate_len;
+	u8 *tag;
+	struct sk_buff *skb;
+	struct ieee80211_probe_request *req;
+
+	len = ieee->current_network.ssid_len;
+
+	rate_len = ieee80211_MFIE_rate_len(ieee);
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
+			    2 + len + rate_len + ieee->tx_headroom);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+
+	req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
+	req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+	req->header.duration_id = 0; //FIXME: is this OK ?
+
+	memset(req->header.addr1, 0xff, ETH_ALEN);
+	memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memset(req->header.addr3, 0xff, ETH_ALEN);
+
+	tag = (u8 *) skb_put(skb,len+2+rate_len);
+
+	*tag++ = MFIE_TYPE_SSID;
+	*tag++ = len;
+	memcpy(tag, ieee->current_network.ssid, len);
+	tag += len;
+
+	ieee80211_MFIE_Brate(ieee,&tag);
+	ieee80211_MFIE_Grate(ieee,&tag);
+	return skb;
+}
+
+struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
+void ieee80211_send_beacon(struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	if(!ieee->ieee_up)
+		return;
+	//unsigned long flags;
+	skb = ieee80211_get_beacon_(ieee);
+
+	if (skb){
+		softmac_mgmt_xmit(skb, ieee);
+		ieee->softmac_stats.tx_beacons++;
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+//	ieee->beacon_timer.expires = jiffies +
+//		(MSECS( ieee->current_network.beacon_interval -5));
+
+	//spin_lock_irqsave(&ieee->beacon_lock,flags);
+	if(ieee->beacon_txing && ieee->ieee_up){
+//		if(!timer_pending(&ieee->beacon_timer))
+//			add_timer(&ieee->beacon_timer);
+		mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
+	}
+	//spin_unlock_irqrestore(&ieee->beacon_lock,flags);
+}
+
+
+void ieee80211_send_beacon_cb(unsigned long _ieee)
+{
+	struct ieee80211_device *ieee =
+		(struct ieee80211_device *) _ieee;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ieee->beacon_lock, flags);
+	ieee80211_send_beacon(ieee);
+	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
+}
+
+
+void ieee80211_send_probe(struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+
+	skb = ieee80211_probe_req(ieee);
+	if (skb){
+		softmac_mgmt_xmit(skb, ieee);
+		ieee->softmac_stats.tx_probe_rq++;
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+}
+
+void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
+{
+	if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
+		ieee80211_send_probe(ieee);
+		ieee80211_send_probe(ieee);
+	}
+}
+
+/* this performs syncro scan blocking the caller until all channels
+ * in the allowed channel map has been checked.
+ */
+void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
+{
+	short ch = 0;
+#ifdef ENABLE_DOT11D
+	u8 channel_map[MAX_CHANNEL_NUMBER+1];
+	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
+#endif
+	down(&ieee->scan_sem);
+
+	while(1)
+	{
+
+		do{
+			ch++;
+			if (ch > MAX_CHANNEL_NUMBER)
+				goto out; /* scan completed */
+#ifdef ENABLE_DOT11D
+		}while(!channel_map[ch]);
+#else
+		}while(!ieee->channel_map[ch]);
+#endif
+
+		/* this fuction can be called in two situations
+		 * 1- We have switched to ad-hoc mode and we are
+		 *    performing a complete syncro scan before conclude
+		 *    there are no interesting cell and to create a
+		 *    new one. In this case the link state is
+		 *    IEEE80211_NOLINK until we found an interesting cell.
+		 *    If so the ieee8021_new_net, called by the RX path
+		 *    will set the state to IEEE80211_LINKED, so we stop
+		 *    scanning
+		 * 2- We are linked and the root uses run iwlist scan.
+		 *    So we switch to IEEE80211_LINKED_SCANNING to remember
+		 *    that we are still logically linked (not interested in
+		 *    new network events, despite for updating the net list,
+		 *    but we are temporarly 'unlinked' as the driver shall
+		 *    not filter RX frames and the channel is changing.
+		 * So the only situation in witch are interested is to check
+		 * if the state become LINKED because of the #1 situation
+		 */
+
+		if (ieee->state == IEEE80211_LINKED)
+			goto out;
+		ieee->set_chan(ieee->dev, ch);
+#ifdef ENABLE_DOT11D
+		if(channel_map[ch] == 1)
+#endif
+		ieee80211_send_probe_requests(ieee);
+
+		/* this prevent excessive time wait when we
+		 * need to wait for a syncro scan to end..
+		 */
+		if(ieee->state < IEEE80211_LINKED)
+			;
+		else
+		if (ieee->sync_scan_hurryup)
+			goto out;
+
+
+		msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
+
+	}
+out:
+	if(ieee->state < IEEE80211_LINKED){
+		ieee->actscanning = false;
+		up(&ieee->scan_sem);
+	}
+	else{
+	ieee->sync_scan_hurryup = 0;
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		DOT11D_ScanComplete(ieee);
+#endif
+	up(&ieee->scan_sem);
+}
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+/* called both by wq with ieee->lock held */
+void ieee80211_softmac_scan(struct ieee80211_device *ieee)
+{
+#if 0
+	short watchdog = 0;
+	do{
+		ieee->current_network.channel =
+			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
+		if (watchdog++ > MAX_CHANNEL_NUMBER)
+				return; /* no good chans */
+
+	}while(!ieee->channel_map[ieee->current_network.channel]);
+#endif
+
+	schedule_task(&ieee->softmac_scan_wq);
+}
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_softmac_scan_wq(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, softmac_scan_wq);
+#else
+void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
+{
+#endif
+	static short watchdog = 0;
+	u8 last_channel = ieee->current_network.channel;
+#ifdef ENABLE_DOT11D
+	u8 channel_map[MAX_CHANNEL_NUMBER+1];
+	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
+#endif
+	if(!ieee->ieee_up)
+		return;
+	down(&ieee->scan_sem);
+	do{
+		ieee->current_network.channel =
+			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
+		if (watchdog++ > MAX_CHANNEL_NUMBER)
+		{
+		//if current channel is not in channel map, set to default channel.
+		#ifdef ENABLE_DOT11D
+      			if (!channel_map[ieee->current_network.channel]);
+		#else
+			if (!ieee->channel_map[ieee->current_network.channel]);
+		#endif
+				ieee->current_network.channel = 6;
+				goto out; /* no good chans */
+		}
+#ifdef ENABLE_DOT11D
+        }while(!channel_map[ieee->current_network.channel]);
+#else
+	}while(!ieee->channel_map[ieee->current_network.channel]);
+#endif
+	if (ieee->scanning == 0 )
+		goto out;
+	ieee->set_chan(ieee->dev, ieee->current_network.channel);
+#ifdef ENABLE_DOT11D
+	if(channel_map[ieee->current_network.channel] == 1)
+#endif
+	ieee80211_send_probe_requests(ieee);
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
+#else
+	//ieee->scan_timer.expires = jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME);
+	if (ieee->scanning == 1)
+		mod_timer(&ieee->scan_timer,(jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME)));
+#endif
+
+	up(&ieee->scan_sem);
+	return;
+out:
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		DOT11D_ScanComplete(ieee);
+#endif
+	ieee->current_network.channel = last_channel;
+        ieee->actscanning = false;
+	watchdog = 0;
+	ieee->scanning = 0;
+	up(&ieee->scan_sem);
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+void ieee80211_softmac_scan_cb(unsigned long _dev)
+{
+	unsigned long flags;
+	struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+	ieee80211_softmac_scan(ieee);
+	spin_unlock_irqrestore(&ieee->lock, flags);
+}
+#endif
+
+
+void ieee80211_beacons_start(struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&ieee->beacon_lock,flags);
+
+	ieee->beacon_txing = 1;
+	ieee80211_send_beacon(ieee);
+
+	spin_unlock_irqrestore(&ieee->beacon_lock,flags);
+}
+
+void ieee80211_beacons_stop(struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ieee->beacon_lock,flags);
+
+	ieee->beacon_txing = 0;
+ 	del_timer_sync(&ieee->beacon_timer);
+
+	spin_unlock_irqrestore(&ieee->beacon_lock,flags);
+
+}
+
+
+void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
+{
+	if(ieee->stop_send_beacons)
+		ieee->stop_send_beacons(ieee->dev);
+	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
+		ieee80211_beacons_stop(ieee);
+}
+
+
+void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
+{
+	if(ieee->start_send_beacons)
+		ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
+	if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
+		ieee80211_beacons_start(ieee);
+}
+
+
+void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
+{
+//	unsigned long flags;
+
+	//ieee->sync_scan_hurryup = 1;
+
+	down(&ieee->scan_sem);
+//	spin_lock_irqsave(&ieee->lock, flags);
+
+	if (ieee->scanning == 1){
+		ieee->scanning = 0;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+		cancel_delayed_work(&ieee->softmac_scan_wq);
+#else
+		del_timer_sync(&ieee->scan_timer);
+#endif
+	}
+
+//	spin_unlock_irqrestore(&ieee->lock, flags);
+	up(&ieee->scan_sem);
+}
+
+void ieee80211_stop_scan(struct ieee80211_device *ieee)
+{
+	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
+		ieee80211_softmac_stop_scan(ieee);
+	else
+		ieee->stop_scan(ieee->dev);
+}
+
+/* called with ieee->lock held */
+void ieee80211_start_scan(struct ieee80211_device *ieee)
+{
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee) )
+	{
+		if(IS_COUNTRY_IE_VALID(ieee))
+		{
+			RESET_CIE_WATCHDOG(ieee);
+		}
+	}
+#endif
+	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
+		if (ieee->scanning == 0){
+			ieee->scanning = 1;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+			queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
+#else
+
+			queue_work(ieee->wq, &ieee->softmac_scan_wq);
+#endif
+#else
+			ieee80211_softmac_scan(ieee);
+#endif
+		}
+	}else
+		ieee->start_scan(ieee->dev);
+
+}
+
+/* called with wx_sem held */
+void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
+{
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee) )
+	{
+		if(IS_COUNTRY_IE_VALID(ieee))
+		{
+			RESET_CIE_WATCHDOG(ieee);
+		}
+	}
+#endif
+	ieee->sync_scan_hurryup = 0;
+	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
+		ieee80211_softmac_scan_syncro(ieee);
+	else
+		ieee->scan_syncro(ieee->dev);
+
+}
+
+inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
+	struct ieee80211_device *ieee, int challengelen)
+{
+	struct sk_buff *skb;
+	struct ieee80211_authentication *auth;
+	int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
+
+
+	skb = dev_alloc_skb(len);
+	if (!skb) return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+	auth = (struct ieee80211_authentication *)
+		skb_put(skb, sizeof(struct ieee80211_authentication));
+
+	auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
+	if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
+
+	auth->header.duration_id = 0x013a; //FIXME
+
+	memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
+	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
+
+	//auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
+	if(ieee->auth_mode == 0)
+		auth->algorithm = WLAN_AUTH_OPEN;
+	else if(ieee->auth_mode == 1)
+		auth->algorithm = WLAN_AUTH_SHARED_KEY;
+	else if(ieee->auth_mode == 2)
+		auth->algorithm = WLAN_AUTH_OPEN;//0x80;
+	printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
+	auth->transaction = cpu_to_le16(ieee->associate_seq);
+	ieee->associate_seq++;
+
+	auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
+
+	return skb;
+
+}
+
+
+static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
+{
+	u8 *tag;
+	int beacon_size;
+	struct ieee80211_probe_response *beacon_buf;
+	struct sk_buff *skb = NULL;
+	int encrypt;
+	int atim_len,erp_len;
+	struct ieee80211_crypt_data* crypt;
+
+	char *ssid = ieee->current_network.ssid;
+	int ssid_len = ieee->current_network.ssid_len;
+	int rate_len = ieee->current_network.rates_len+2;
+	int rate_ex_len = ieee->current_network.rates_ex_len;
+	int wpa_ie_len = ieee->wpa_ie_len;
+	u8 erpinfo_content = 0;
+
+	u8* tmp_ht_cap_buf;
+	u8 tmp_ht_cap_len=0;
+	u8* tmp_ht_info_buf;
+	u8 tmp_ht_info_len=0;
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u8* tmp_generic_ie_buf=NULL;
+	u8 tmp_generic_ie_len=0;
+
+	if(rate_ex_len > 0) rate_ex_len+=2;
+
+	if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
+		atim_len = 4;
+	else
+		atim_len = 0;
+
+#if 1
+	if(ieee80211_is_54g(ieee->current_network))
+		erp_len = 3;
+	else
+		erp_len = 0;
+#else
+      if((ieee->current_network.mode == IEEE_G)
+	  	||( ieee->current_network.mode == IEEE_N_24G && ieee->pHTInfo->bCurSuppCCK)) {
+	  	erp_len = 3;
+		erpinfo_content = 0;
+		if(ieee->current_network.buseprotection)
+			erpinfo_content |= ERP_UseProtection;
+      	}
+	else
+		erp_len = 0;
+#endif
+
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+
+
+	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
+		((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
+	//HT ralated element
+#if 1
+	tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
+	tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
+	tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
+	tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
+	HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
+	HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
+
+
+        if(pHTInfo->bRegRT2RTAggregation)
+        {
+        	tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
+		tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
+		HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
+        }
+//	printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len);
+#endif
+	beacon_size = sizeof(struct ieee80211_probe_response)+2+
+		ssid_len
+		+3 //channel
+		+rate_len
+		+rate_ex_len
+		+atim_len
+		+erp_len
+                +wpa_ie_len
+	//	+tmp_ht_cap_len
+	//	+tmp_ht_info_len
+	//	+tmp_generic_ie_len
+//		+wmm_len+2
+		+ieee->tx_headroom;
+	skb = dev_alloc_skb(beacon_size);
+	if (!skb)
+		return NULL;
+	skb_reserve(skb, ieee->tx_headroom);
+	beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
+	memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
+	memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
+
+	beacon_buf->header.duration_id = 0; //FIXME
+	beacon_buf->beacon_interval =
+		cpu_to_le16(ieee->current_network.beacon_interval);
+	beacon_buf->capability =
+		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
+	beacon_buf->capability |=
+		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
+
+	if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
+		cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+#if 0
+	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
+		(0 == strcmp(crypt->ops->name, "WEP"));
+#endif
+	if (encrypt)
+		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
+
+
+	beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
+	beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
+	beacon_buf->info_element[0].len = ssid_len;
+
+	tag = (u8*) beacon_buf->info_element[0].data;
+
+	memcpy(tag, ssid, ssid_len);
+
+	tag += ssid_len;
+
+	*(tag++) = MFIE_TYPE_RATES;
+	*(tag++) = rate_len-2;
+	memcpy(tag,ieee->current_network.rates,rate_len-2);
+	tag+=rate_len-2;
+
+	*(tag++) = MFIE_TYPE_DS_SET;
+	*(tag++) = 1;
+	*(tag++) = ieee->current_network.channel;
+
+	if(atim_len){
+	u16 val16;
+		*(tag++) = MFIE_TYPE_IBSS_SET;
+		*(tag++) = 2;
+		//*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
+		 val16 = cpu_to_le16(ieee->current_network.atim_window);
+		memcpy((u8 *)tag, (u8 *)&val16, 2);
+		tag+=2;
+	}
+
+	if(erp_len){
+		*(tag++) = MFIE_TYPE_ERP;
+		*(tag++) = 1;
+		*(tag++) = erpinfo_content;
+	}
+#if 0
+	//Include High Throuput capability
+
+	*(tag++) = MFIE_TYPE_HT_CAP;
+	*(tag++) = tmp_ht_cap_len - 2;
+	memcpy(tag, tmp_ht_cap_buf, tmp_ht_cap_len - 2);
+	tag += tmp_ht_cap_len - 2;
+#endif
+	if(rate_ex_len){
+		*(tag++) = MFIE_TYPE_RATES_EX;
+		*(tag++) = rate_ex_len-2;
+		memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
+		tag+=rate_ex_len-2;
+	}
+
+#if 0
+	//Include High Throuput info
+
+	*(tag++) = MFIE_TYPE_HT_INFO;
+	*(tag++) = tmp_ht_info_len - 2;
+	memcpy(tag, tmp_ht_info_buf, tmp_ht_info_len -2);
+	tag += tmp_ht_info_len - 2;
+#endif
+	if (wpa_ie_len)
+	{
+		if (ieee->iw_mode == IW_MODE_ADHOC)
+		{//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
+			memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
+		}
+		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
+		tag += wpa_ie_len;
+	}
+
+#if 0
+	//
+	// Construct Realtek Proprietary Aggregation mode (Set AMPDU Factor to 2, 32k)
+	//
+	if(pHTInfo->bRegRT2RTAggregation)
+	{
+		(*tag++) = 0xdd;
+		(*tag++) = tmp_generic_ie_len - 2;
+		memcpy(tag,tmp_generic_ie_buf,tmp_generic_ie_len -2);
+		tag += tmp_generic_ie_len -2;
+
+	}
+#endif
+#if 0
+	if(ieee->qos_support)
+	{
+		(*tag++) = 0xdd;
+		(*tag++) = wmm_len;
+		memcpy(tag,QosOui,wmm_len);
+		tag += wmm_len;
+	}
+#endif
+	//skb->dev = ieee->dev;
+	return skb;
+}
+
+
+struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
+{
+	struct sk_buff *skb;
+	u8* tag;
+
+	struct ieee80211_crypt_data* crypt;
+	struct ieee80211_assoc_response_frame *assoc;
+	short encrypt;
+
+	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
+	int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
+
+	skb = dev_alloc_skb(len);
+
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+
+	assoc = (struct ieee80211_assoc_response_frame *)
+		skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
+
+	assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
+	memcpy(assoc->header.addr1, dest,ETH_ALEN);
+	memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
+		WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
+
+
+	if(ieee->short_slot)
+		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
+
+	if (ieee->host_encrypt)
+		crypt = ieee->crypt[ieee->tx_keyidx];
+	else crypt = NULL;
+
+	encrypt = ( crypt && crypt->ops);
+
+	if (encrypt)
+		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
+
+	assoc->status = 0;
+	assoc->aid = cpu_to_le16(ieee->assoc_id);
+	if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
+	else ieee->assoc_id++;
+
+	tag = (u8*) skb_put(skb, rate_len);
+
+	ieee80211_MFIE_Brate(ieee, &tag);
+	ieee80211_MFIE_Grate(ieee, &tag);
+
+	return skb;
+}
+
+struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
+{
+	struct sk_buff *skb;
+	struct ieee80211_authentication *auth;
+	int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
+
+	skb = dev_alloc_skb(len);
+
+	if (!skb)
+		return NULL;
+
+	skb->len = sizeof(struct ieee80211_authentication);
+
+	auth = (struct ieee80211_authentication *)skb->data;
+
+	auth->status = cpu_to_le16(status);
+	auth->transaction = cpu_to_le16(2);
+	auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
+
+	memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(auth->header.addr1, dest, ETH_ALEN);
+	auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
+	return skb;
+
+
+}
+
+struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
+{
+	struct sk_buff *skb;
+	struct ieee80211_hdr_3addr* hdr;
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
+
+	if (!skb)
+		return NULL;
+
+	hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
+
+	memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
+	memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
+
+	hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
+		(pwr ? IEEE80211_FCTL_PM:0));
+
+	return skb;
+
+
+}
+
+
+void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
+{
+	struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
+
+	if (buf)
+		softmac_mgmt_xmit(buf, ieee);
+}
+
+
+void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
+{
+	struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
+
+	if (buf)
+		softmac_mgmt_xmit(buf, ieee);
+}
+
+
+void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
+{
+
+
+	struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
+	if (buf)
+		softmac_mgmt_xmit(buf, ieee);
+}
+
+
+inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	//unsigned long flags;
+
+	struct ieee80211_assoc_request_frame *hdr;
+	u8 *tag;//,*rsn_ie;
+	//short info_addr = 0;
+	//int i;
+	//u16 suite_count = 0;
+	//u8 suit_select = 0;
+	//unsigned int wpa_len = beacon->wpa_ie_len;
+	//for HT
+	u8* ht_cap_buf = NULL;
+	u8 ht_cap_len=0;
+	u8* realtek_ie_buf=NULL;
+	u8 realtek_ie_len=0;
+	int wpa_ie_len= ieee->wpa_ie_len;
+	unsigned int ckip_ie_len=0;
+	unsigned int ccxrm_ie_len=0;
+	unsigned int cxvernum_ie_len=0;
+	struct ieee80211_crypt_data* crypt;
+	int encrypt;
+
+	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
+	unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
+#ifdef THOMAS_TURBO
+	unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
+#endif
+
+	int len = 0;
+
+	crypt = ieee->crypt[ieee->tx_keyidx];
+	encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
+
+	//Include High Throuput capability && Realtek proprietary
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
+	{
+		ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
+		ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
+		HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
+		if(ieee->pHTInfo->bCurrentRT2RTAggregation)
+		{
+			realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
+			realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
+			HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
+
+		}
+	}
+	if(ieee->qos_support){
+		wmm_info_len = beacon->qos_data.supported?9:0;
+	}
+
+
+	if(beacon->bCkipSupported)
+	{
+		ckip_ie_len = 30+2;
+	}
+	if(beacon->bCcxRmEnable)
+	{
+		ccxrm_ie_len = 6+2;
+	}
+	if( beacon->BssCcxVerNumber >= 2 )
+	{
+		cxvernum_ie_len = 5+2;
+	}
+#ifdef THOMAS_TURBO
+	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
+		+ beacon->ssid_len//essid tagged val
+		+ rate_len//rates tagged val
+		+ wpa_ie_len
+		+ wmm_info_len
+		+ turbo_info_len
+                + ht_cap_len
+		+ realtek_ie_len
+		+ ckip_ie_len
+		+ ccxrm_ie_len
+		+ cxvernum_ie_len
+		+ ieee->tx_headroom;
+#else
+	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
+		+ beacon->ssid_len//essid tagged val
+		+ rate_len//rates tagged val
+		+ wpa_ie_len
+		+ wmm_info_len
+                + ht_cap_len
+		+ realtek_ie_len
+		+ ckip_ie_len
+		+ ccxrm_ie_len
+		+ cxvernum_ie_len
+		+ ieee->tx_headroom;
+#endif
+
+	skb = dev_alloc_skb(len);
+
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, ieee->tx_headroom);
+
+	hdr = (struct ieee80211_assoc_request_frame *)
+		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
+
+
+	hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
+	hdr->header.duration_id= 37; //FIXME
+	memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
+	memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
+
+	memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
+
+	hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
+	if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
+		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
+
+	if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
+
+	if(ieee->short_slot)
+		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
+ 	if (wmm_info_len) //QOS
+	hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
+
+	hdr->listen_interval = 0xa; //FIXME
+
+	hdr->info_element[0].id = MFIE_TYPE_SSID;
+
+	hdr->info_element[0].len = beacon->ssid_len;
+	tag = skb_put(skb, beacon->ssid_len);
+	memcpy(tag, beacon->ssid, beacon->ssid_len);
+
+	tag = skb_put(skb, rate_len);
+
+	ieee80211_MFIE_Brate(ieee, &tag);
+	ieee80211_MFIE_Grate(ieee, &tag);
+	// For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
+	if( beacon->bCkipSupported )
+	{
+		static u8	AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
+		u8	CcxAironetBuf[30];
+		OCTET_STRING	osCcxAironetIE;
+
+		memset(CcxAironetBuf, 0,30);
+		osCcxAironetIE.Octet = CcxAironetBuf;
+		osCcxAironetIE.Length = sizeof(CcxAironetBuf);
+		//
+		// Ref. CCX test plan v3.61, 3.2.3.1 step 13.
+		// We want to make the device type as "4500-client". 060926, by CCW.
+		//
+		memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
+
+		// CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
+		// "The CKIP negotiation is started with the associate request from the client to the access point,
+		//  containing an Aironet element with both the MIC and KP bits set."
+		osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |=  (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
+		tag = skb_put(skb, ckip_ie_len);
+		*tag++ = MFIE_TYPE_AIRONET;
+		*tag++ = osCcxAironetIE.Length;
+		memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
+		tag += osCcxAironetIE.Length;
+	}
+
+	if(beacon->bCcxRmEnable)
+	{
+		static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
+		OCTET_STRING osCcxRmCap;
+
+		osCcxRmCap.Octet = CcxRmCapBuf;
+		osCcxRmCap.Length = sizeof(CcxRmCapBuf);
+		tag = skb_put(skb,ccxrm_ie_len);
+		*tag++ = MFIE_TYPE_GENERIC;
+		*tag++ = osCcxRmCap.Length;
+		memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
+		tag += osCcxRmCap.Length;
+	}
+
+	if( beacon->BssCcxVerNumber >= 2 )
+	{
+		u8			CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
+		OCTET_STRING	osCcxVerNum;
+		CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
+		osCcxVerNum.Octet = CcxVerNumBuf;
+		osCcxVerNum.Length = sizeof(CcxVerNumBuf);
+		tag = skb_put(skb,cxvernum_ie_len);
+		*tag++ = MFIE_TYPE_GENERIC;
+		*tag++ = osCcxVerNum.Length;
+		memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
+		tag += osCcxVerNum.Length;
+	}
+        //HT cap element
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
+		if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
+		{
+			tag = skb_put(skb, ht_cap_len);
+			*tag++ = MFIE_TYPE_HT_CAP;
+			*tag++ = ht_cap_len - 2;
+			memcpy(tag, ht_cap_buf,ht_cap_len -2);
+			tag += ht_cap_len -2;
+		}
+	}
+
+
+	//choose what wpa_supplicant gives to associate.
+	tag = skb_put(skb, wpa_ie_len);
+	if (wpa_ie_len){
+		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
+	}
+
+	tag = skb_put(skb,wmm_info_len);
+	if(wmm_info_len) {
+	  ieee80211_WMM_Info(ieee, &tag);
+	}
+#ifdef THOMAS_TURBO
+	tag = skb_put(skb,turbo_info_len);
+        if(turbo_info_len) {
+                ieee80211_TURBO_Info(ieee, &tag);
+        }
+#endif
+
+	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
+		if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+		{
+			tag = skb_put(skb, ht_cap_len);
+			*tag++ = MFIE_TYPE_GENERIC;
+			*tag++ = ht_cap_len - 2;
+			memcpy(tag, ht_cap_buf,ht_cap_len - 2);
+			tag += ht_cap_len -2;
+		}
+
+		if(ieee->pHTInfo->bCurrentRT2RTAggregation){
+			tag = skb_put(skb, realtek_ie_len);
+			*tag++ = MFIE_TYPE_GENERIC;
+			*tag++ = realtek_ie_len - 2;
+			memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
+		}
+	}
+//	printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+	return skb;
+}
+
+void ieee80211_associate_abort(struct ieee80211_device *ieee)
+{
+
+	unsigned long flags;
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	ieee->associate_seq++;
+
+	/* don't scan, and avoid to have the RX path possibily
+	 * try again to associate. Even do not react to AUTH or
+	 * ASSOC response. Just wait for the retry wq to be scheduled.
+	 * Here we will check if there are good nets to associate
+	 * with, so we retry or just get back to NO_LINK and scanning
+	 */
+	if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
+		IEEE80211_DEBUG_MGMT("Authentication failed\n");
+		ieee->softmac_stats.no_auth_rs++;
+	}else{
+		IEEE80211_DEBUG_MGMT("Association failed\n");
+		ieee->softmac_stats.no_ass_rs++;
+	}
+
+	ieee->state = IEEE80211_ASSOCIATING_RETRY;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
+                           IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
+#else
+	schedule_task(&ieee->associate_retry_wq);
+#endif
+
+	spin_unlock_irqrestore(&ieee->lock, flags);
+}
+
+void ieee80211_associate_abort_cb(unsigned long dev)
+{
+	ieee80211_associate_abort((struct ieee80211_device *) dev);
+}
+
+
+void ieee80211_associate_step1(struct ieee80211_device *ieee)
+{
+	struct ieee80211_network *beacon = &ieee->current_network;
+	struct sk_buff *skb;
+
+	IEEE80211_DEBUG_MGMT("Stopping scan\n");
+
+	ieee->softmac_stats.tx_auth_rq++;
+	skb=ieee80211_authentication_req(beacon, ieee, 0);
+
+	if (!skb)
+		ieee80211_associate_abort(ieee);
+	else{
+		ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
+		IEEE80211_DEBUG_MGMT("Sending authentication request\n");
+		//printk(KERN_WARNING "Sending authentication request\n");
+		softmac_mgmt_xmit(skb, ieee);
+		//BUGON when you try to add_timer twice, using mod_timer may be better, john0709
+		if(!timer_pending(&ieee->associate_timer)){
+			ieee->associate_timer.expires = jiffies + (HZ / 2);
+			add_timer(&ieee->associate_timer);
+		}
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+}
+
+void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
+{
+	u8 *c;
+	struct sk_buff *skb;
+	struct ieee80211_network *beacon = &ieee->current_network;
+//	int hlen = sizeof(struct ieee80211_authentication);
+
+	ieee->associate_seq++;
+	ieee->softmac_stats.tx_auth_rq++;
+
+	skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
+	if (!skb)
+		ieee80211_associate_abort(ieee);
+	else{
+		c = skb_put(skb, chlen+2);
+		*(c++) = MFIE_TYPE_CHALLENGE;
+		*(c++) = chlen;
+		memcpy(c, challenge, chlen);
+
+		IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
+
+		ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr  ));
+
+		softmac_mgmt_xmit(skb, ieee);
+		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
+#if 0
+		ieee->associate_timer.expires = jiffies + (HZ / 2);
+		add_timer(&ieee->associate_timer);
+#endif
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+	kfree(challenge);
+}
+
+void ieee80211_associate_step2(struct ieee80211_device *ieee)
+{
+	struct sk_buff* skb;
+	struct ieee80211_network *beacon = &ieee->current_network;
+
+	del_timer_sync(&ieee->associate_timer);
+
+	IEEE80211_DEBUG_MGMT("Sending association request\n");
+
+	ieee->softmac_stats.tx_ass_rq++;
+	skb=ieee80211_association_req(beacon, ieee);
+	if (!skb)
+		ieee80211_associate_abort(ieee);
+	else{
+		softmac_mgmt_xmit(skb, ieee);
+		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
+#if 0
+		ieee->associate_timer.expires = jiffies + (HZ / 2);
+		add_timer(&ieee->associate_timer);
+#endif
+		//dev_kfree_skb_any(skb);//edit by thomas
+	}
+}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_associate_complete_wq(struct work_struct *work)
+{
+        struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
+#else
+void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
+{
+#endif
+	printk(KERN_INFO "Associated successfully\n");
+	ieee->is_roaming = false;
+	if(ieee80211_is_54g(ieee->current_network) &&
+		(ieee->modulation & IEEE80211_OFDM_MODULATION)){
+
+		ieee->rate = 108;
+		printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
+	}else{
+		ieee->rate = 22;
+		printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
+	}
+	if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
+	{
+		printk("Successfully associated, ht enabled\n");
+		HTOnAssocRsp(ieee);
+	}
+	else
+	{
+		printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
+		memset(ieee->dot11HTOperationalRateSet, 0, 16);
+		//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+	ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
+	// To prevent the immediately calling watch_dog after association.
+	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
+	{
+		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
+		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
+	}
+	ieee->link_change(ieee->dev);
+	if(ieee->is_silent_reset == 0){
+		printk("============>normal associate\n");
+	notify_wx_assoc_event(ieee);
+	}
+	else if(ieee->is_silent_reset == 1)
+	{
+		printk("==================>silent reset associate\n");
+		ieee->is_silent_reset = 0;
+	}
+
+	if (ieee->data_hard_resume)
+		ieee->data_hard_resume(ieee->dev);
+	netif_carrier_on(ieee->dev);
+}
+
+void ieee80211_associate_complete(struct ieee80211_device *ieee)
+{
+//	int i;
+//	struct net_device* dev = ieee->dev;
+	del_timer_sync(&ieee->associate_timer);
+
+#if 0
+	for(i = 0; i < 6; i++) {
+	  ieee->seq_ctrl[i] = 0;
+	}
+#endif
+	ieee->state = IEEE80211_LINKED;
+#if 0
+	if (ieee->pHTInfo->bCurrentHTSupport)
+	{
+		printk("Successfully associated, ht enabled\n");
+		queue_work(ieee->wq, &ieee->ht_onAssRsp);
+	}
+	else
+	{
+		printk("Successfully associated, ht not enabled\n");
+		memset(ieee->dot11HTOperationalRateSet, 0, 16);
+		HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+#endif
+	//ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	queue_work(ieee->wq, &ieee->associate_complete_wq);
+#else
+	schedule_task(&ieee->associate_complete_wq);
+#endif
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_associate_procedure_wq(struct work_struct *work)
+{
+        struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
+#else
+void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
+{
+#endif
+	ieee->sync_scan_hurryup = 1;
+	down(&ieee->wx_sem);
+
+	if (ieee->data_hard_stop)
+		ieee->data_hard_stop(ieee->dev);
+
+	ieee80211_stop_scan(ieee);
+	printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
+	//ieee->set_chan(ieee->dev, ieee->current_network.channel);
+	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+
+	ieee->associate_seq = 1;
+	ieee80211_associate_step1(ieee);
+
+	up(&ieee->wx_sem);
+}
+
+inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
+{
+	u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
+	int tmp_ssid_len = 0;
+
+	short apset,ssidset,ssidbroad,apmatch,ssidmatch;
+
+	/* we are interested in new new only if we are not associated
+	 * and we are not associating / authenticating
+	 */
+	if (ieee->state != IEEE80211_NOLINK)
+		return;
+
+	if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
+		return;
+
+	if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
+		return;
+
+
+	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
+		/* if the user specified the AP MAC, we need also the essid
+		 * This could be obtained by beacons or, if the network does not
+		 * broadcast it, it can be put manually.
+		 */
+		apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
+		ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
+		ssidbroad =  !(net->ssid_len == 0 || net->ssid[0]== '\0');
+		apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
+		ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
+				(!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
+
+
+		if (	/* if the user set the AP check if match.
+		         * if the network does not broadcast essid we check the user supplyed ANY essid
+			 * if the network does broadcast and the user does not set essid it is OK
+			 * if the network does broadcast and the user did set essid chech if essid match
+			 */
+			( apset && apmatch &&
+				((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
+			/* if the ap is not set, check that the user set the bssid
+			 * and the network does bradcast and that those two bssid matches
+			 */
+			(!apset && ssidset && ssidbroad && ssidmatch)
+			){
+				/* if the essid is hidden replace it with the
+				* essid provided by the user.
+				*/
+				if (!ssidbroad){
+					strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
+					tmp_ssid_len = ieee->current_network.ssid_len;
+				}
+				memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
+
+				if (!ssidbroad){
+					strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
+					ieee->current_network.ssid_len = tmp_ssid_len;
+				}
+				printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT);
+
+				//ieee->pHTInfo->IOTAction = 0;
+				HTResetIOTSetting(ieee->pHTInfo);
+				if (ieee->iw_mode == IW_MODE_INFRA){
+					/* Join the network for the first time */
+					ieee->AsocRetryCount = 0;
+					//for HT by amy 080514
+					if((ieee->current_network.qos_data.supported == 1) &&
+					  // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
+					   ieee->current_network.bssht.bdSupportHT)
+/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
+					{
+					//	ieee->pHTInfo->bCurrentHTSupport = true;
+						HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
+					}
+					else
+					{
+						ieee->pHTInfo->bCurrentHTSupport = false;
+					}
+
+					ieee->state = IEEE80211_ASSOCIATING;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+					queue_work(ieee->wq, &ieee->associate_procedure_wq);
+#else
+					schedule_task(&ieee->associate_procedure_wq);
+#endif
+				}else{
+					if(ieee80211_is_54g(ieee->current_network) &&
+						(ieee->modulation & IEEE80211_OFDM_MODULATION)){
+						ieee->rate = 108;
+						ieee->SetWirelessMode(ieee->dev, IEEE_G);
+						printk(KERN_INFO"Using G rates\n");
+					}else{
+						ieee->rate = 22;
+						ieee->SetWirelessMode(ieee->dev, IEEE_B);
+						printk(KERN_INFO"Using B rates\n");
+					}
+					memset(ieee->dot11HTOperationalRateSet, 0, 16);
+					//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+					ieee->state = IEEE80211_LINKED;
+				}
+
+		}
+	}
+
+}
+
+void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+	struct ieee80211_network *target;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	list_for_each_entry(target, &ieee->network_list, list) {
+
+		/* if the state become different that NOLINK means
+		 * we had found what we are searching for
+		 */
+
+		if (ieee->state != IEEE80211_NOLINK)
+			break;
+
+		if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
+		ieee80211_softmac_new_net(ieee, target);
+	}
+
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+}
+
+
+static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
+{
+	struct ieee80211_authentication *a;
+	u8 *t;
+	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
+		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
+		return 0xcafe;
+	}
+	*challenge = NULL;
+	a = (struct ieee80211_authentication*) skb->data;
+	if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
+		t = skb->data + sizeof(struct ieee80211_authentication);
+
+		if(*(t++) == MFIE_TYPE_CHALLENGE){
+			*chlen = *(t++);
+			*challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
+			memcpy(*challenge, t, *chlen);
+		}
+	}
+
+	return cpu_to_le16(a->status);
+
+}
+
+
+int auth_rq_parse(struct sk_buff *skb,u8* dest)
+{
+	struct ieee80211_authentication *a;
+
+	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
+		IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
+		return -1;
+	}
+	a = (struct ieee80211_authentication*) skb->data;
+
+	memcpy(dest,a->header.addr2, ETH_ALEN);
+
+	if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
+		return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
+
+	return WLAN_STATUS_SUCCESS;
+}
+
+static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
+{
+	u8 *tag;
+	u8 *skbend;
+	u8 *ssid=NULL;
+	u8 ssidlen = 0;
+
+	struct ieee80211_hdr_3addr   *header =
+		(struct ieee80211_hdr_3addr   *) skb->data;
+
+	if (skb->len < sizeof (struct ieee80211_hdr_3addr  ))
+		return -1; /* corrupted */
+
+	memcpy(src,header->addr2, ETH_ALEN);
+
+	skbend = (u8*)skb->data + skb->len;
+
+	tag = skb->data + sizeof (struct ieee80211_hdr_3addr  );
+
+	while (tag+1 < skbend){
+		if (*tag == 0){
+			ssid = tag+2;
+			ssidlen = *(tag+1);
+			break;
+		}
+		tag++; /* point to the len field */
+		tag = tag + *(tag); /* point to the last data byte of the tag */
+		tag++; /* point to the next tag */
+	}
+
+	//IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
+	if (ssidlen == 0) return 1;
+
+	if (!ssid) return 1; /* ssid not found in tagged param */
+	return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
+
+}
+
+int assoc_rq_parse(struct sk_buff *skb,u8* dest)
+{
+	struct ieee80211_assoc_request_frame *a;
+
+	if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
+		sizeof(struct ieee80211_info_element))) {
+
+		IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
+		return -1;
+	}
+
+	a = (struct ieee80211_assoc_request_frame*) skb->data;
+
+	memcpy(dest,a->header.addr2,ETH_ALEN);
+
+	return 0;
+}
+
+static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
+{
+	struct ieee80211_assoc_response_frame *response_head;
+	u16 status_code;
+
+	if (skb->len <  sizeof(struct ieee80211_assoc_response_frame)){
+		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
+		return 0xcafe;
+	}
+
+	response_head = (struct ieee80211_assoc_response_frame*) skb->data;
+	*aid = le16_to_cpu(response_head->aid) & 0x3fff;
+
+	status_code = le16_to_cpu(response_head->status);
+	if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
+	   status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
+	   ((ieee->mode == IEEE_G) &&
+	    (ieee->current_network.mode == IEEE_N_24G) &&
+            (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
+                 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
+	}else {
+		 ieee->AsocRetryCount = 0;
+	}
+
+	return le16_to_cpu(response_head->status);
+}
+
+static inline void
+ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+	u8 dest[ETH_ALEN];
+
+	//IEEE80211DMESG("Rx probe");
+	ieee->softmac_stats.rx_probe_rq++;
+	//DMESG("Dest is "MACSTR, MAC2STR(dest));
+	if (probe_rq_parse(ieee, skb, dest)){
+		//IEEE80211DMESG("Was for me!");
+		ieee->softmac_stats.tx_probe_rs++;
+		ieee80211_resp_to_probe(ieee, dest);
+	}
+}
+
+static inline void
+ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+	u8 dest[ETH_ALEN];
+	int status;
+	//IEEE80211DMESG("Rx probe");
+	ieee->softmac_stats.rx_auth_rq++;
+
+	if ((status = auth_rq_parse(skb, dest))!= -1){
+		ieee80211_resp_to_auth(ieee, status, dest);
+	}
+	//DMESG("Dest is "MACSTR, MAC2STR(dest));
+
+}
+
+static inline void
+ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
+{
+
+	u8 dest[ETH_ALEN];
+	//unsigned long flags;
+
+	ieee->softmac_stats.rx_ass_rq++;
+	if (assoc_rq_parse(skb,dest) != -1){
+		ieee80211_resp_to_assoc_rq(ieee, dest);
+	}
+
+	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
+	//FIXME
+	#if 0
+	spin_lock_irqsave(&ieee->lock,flags);
+	add_associate(ieee,dest);
+	spin_unlock_irqrestore(&ieee->lock,flags);
+	#endif
+}
+
+
+
+void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
+{
+
+	struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
+
+	if (buf)
+		softmac_ps_mgmt_xmit(buf, ieee);
+
+}
+
+
+short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
+{
+	int timeout = ieee->ps_timeout;
+	u8 dtim;
+	/*if(ieee->ps == IEEE80211_PS_DISABLED ||
+		ieee->iw_mode != IW_MODE_INFRA ||
+		ieee->state != IEEE80211_LINKED)
+
+		return 0;
+	*/
+	dtim = ieee->current_network.dtim_data;
+	//printk("DTIM\n");
+	if(!(dtim & IEEE80211_DTIM_VALID))
+		return 0;
+	timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
+	//printk("VALID\n");
+	ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
+
+	if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
+		return 2;
+
+	if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
+		return 0;
+
+	if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
+		return 0;
+
+	if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
+		(ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
+		return 0;
+
+	if(time_l){
+		*time_l = ieee->current_network.last_dtim_sta_time[0]
+			+ (ieee->current_network.beacon_interval);
+		//	* ieee->current_network.dtim_period) * 1000;
+	}
+
+	if(time_h){
+		*time_h = ieee->current_network.last_dtim_sta_time[1];
+		if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
+			*time_h += 1;
+	}
+
+	return 1;
+
+
+}
+
+inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
+{
+
+	u32 th,tl;
+	short sleep;
+
+	unsigned long flags,flags2;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if((ieee->ps == IEEE80211_PS_DISABLED ||
+		ieee->iw_mode != IW_MODE_INFRA ||
+		ieee->state != IEEE80211_LINKED)){
+
+	//	#warning CHECK_LOCK_HERE
+		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
+
+		ieee80211_sta_wakeup(ieee, 1);
+
+		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
+	}
+
+	sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
+	/* 2 wake, 1 sleep, 0 do nothing */
+	if(sleep == 0)
+		goto out;
+
+	if(sleep == 1){
+
+		if(ieee->sta_sleep == 1)
+			ieee->enter_sleep_state(ieee->dev,th,tl);
+
+		else if(ieee->sta_sleep == 0){
+		//	printk("send null 1\n");
+			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
+
+			if(ieee->ps_is_queue_empty(ieee->dev)){
+
+
+				ieee->sta_sleep = 2;
+
+				ieee->ack_tx_to_ieee = 1;
+
+				ieee80211_sta_ps_send_null_frame(ieee,1);
+
+				ieee->ps_th = th;
+				ieee->ps_tl = tl;
+			}
+			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
+
+		}
+
+
+	}else if(sleep == 2){
+//#warning CHECK_LOCK_HERE
+		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
+
+		ieee80211_sta_wakeup(ieee,1);
+
+		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
+	}
+
+out:
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+}
+
+void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
+{
+	if(ieee->sta_sleep == 0){
+		if(nl){
+			printk("Warning: driver is probably failing to report TX ps error\n");
+			ieee->ack_tx_to_ieee = 1;
+			ieee80211_sta_ps_send_null_frame(ieee, 0);
+		}
+		return;
+
+	}
+
+	if(ieee->sta_sleep == 1)
+		ieee->sta_wake_up(ieee->dev);
+
+	ieee->sta_sleep = 0;
+
+	if(nl){
+		ieee->ack_tx_to_ieee = 1;
+		ieee80211_sta_ps_send_null_frame(ieee, 0);
+	}
+}
+
+void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
+{
+	unsigned long flags,flags2;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if(ieee->sta_sleep == 2){
+		/* Null frame with PS bit set */
+		if(success){
+			ieee->sta_sleep = 1;
+			ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
+		}
+		/* if the card report not success we can't be sure the AP
+		 * has not RXed so we can't assume the AP believe us awake
+		 */
+	}
+	/* 21112005 - tx again null without PS bit if lost */
+	else {
+
+		if((ieee->sta_sleep == 0) && !success){
+			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
+			ieee80211_sta_ps_send_null_frame(ieee, 0);
+			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
+		}
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+}
+void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
+{
+	struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
+	u8* act = ieee80211_get_payload(header);
+	u8 tmp = 0;
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	if (act == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
+		return;
+	}
+	tmp = *act;
+	act ++;
+	switch (tmp)
+	{
+		case ACT_CAT_BA:
+			if (*act == ACT_ADDBAREQ)
+			ieee80211_rx_ADDBAReq(ieee, skb);
+			else if (*act == ACT_ADDBARSP)
+			ieee80211_rx_ADDBARsp(ieee, skb);
+			else if (*act == ACT_DELBA)
+			ieee80211_rx_DELBA(ieee, skb);
+			break;
+		default:
+//			if (net_ratelimit())
+//			IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
+			break;
+	}
+	return;
+
+}
+inline int
+ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
+			struct ieee80211_rx_stats *rx_stats, u16 type,
+			u16 stype)
+{
+	struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
+	u16 errcode;
+	u8* challenge;
+	int chlen=0;
+	int aid;
+	struct ieee80211_assoc_response_frame *assoc_resp;
+//	struct ieee80211_info_element *info_element;
+	bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
+
+	if(!ieee->proto_started)
+		return 0;
+#if 0
+	printk("%d, %d, %d, %d\n", ieee->sta_sleep, ieee->ps, ieee->iw_mode, ieee->state);
+	if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
+		ieee->iw_mode == IW_MODE_INFRA &&
+		ieee->state == IEEE80211_LINKED))
+
+		tasklet_schedule(&ieee->ps_task);
+
+	if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
+		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
+		ieee->last_rx_ps_time = jiffies;
+#endif
+
+	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
+
+		case IEEE80211_STYPE_ASSOC_RESP:
+		case IEEE80211_STYPE_REASSOC_RESP:
+
+			IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
+					WLAN_FC_GET_STYPE(header->frame_ctl));
+			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
+				ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
+				ieee->iw_mode == IW_MODE_INFRA){
+				struct ieee80211_network network_resp;
+				struct ieee80211_network *network = &network_resp;
+
+				if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
+					ieee->state=IEEE80211_LINKED;
+					ieee->assoc_id = aid;
+					ieee->softmac_stats.rx_ass_ok++;
+					/* station support qos */
+					/* Let the register setting defaultly with Legacy station */
+					if(ieee->qos_support) {
+						assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
+						memset(network, 0, sizeof(*network));
+						if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
+									rx_stats->len - sizeof(*assoc_resp),\
+									network,rx_stats)){
+							return 1;
+						}
+						else
+						{	//filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
+							memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
+							memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
+						}
+						if (ieee->handle_assoc_response != NULL)
+							ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
+					}
+					ieee80211_associate_complete(ieee);
+				} else {
+					/* aid could not been allocated */
+					ieee->softmac_stats.rx_ass_err++;
+					printk(
+						"Association response status code 0x%x\n",
+						errcode);
+					IEEE80211_DEBUG_MGMT(
+						"Association response status code 0x%x\n",
+						errcode);
+					if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+						queue_work(ieee->wq, &ieee->associate_procedure_wq);
+#else
+						schedule_task(&ieee->associate_procedure_wq);
+#endif
+					} else {
+						ieee80211_associate_abort(ieee);
+					}
+				}
+			}
+			break;
+
+		case IEEE80211_STYPE_ASSOC_REQ:
+		case IEEE80211_STYPE_REASSOC_REQ:
+
+			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
+				ieee->iw_mode == IW_MODE_MASTER)
+
+				ieee80211_rx_assoc_rq(ieee, skb);
+			break;
+
+		case IEEE80211_STYPE_AUTH:
+
+			if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
+				if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
+				ieee->iw_mode == IW_MODE_INFRA){
+
+						IEEE80211_DEBUG_MGMT("Received authentication response");
+
+						if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
+							if(ieee->open_wep || !challenge){
+								ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
+								ieee->softmac_stats.rx_auth_rs_ok++;
+								if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
+								{
+									if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
+									{
+												// WEP or TKIP encryption
+										if(IsHTHalfNmodeAPs(ieee))
+										{
+											bSupportNmode = true;
+											bHalfSupportNmode = true;
+										}
+										else
+										{
+											bSupportNmode = false;
+											bHalfSupportNmode = false;
+										}
+									printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
+									}
+								}
+								/* Dummy wirless mode setting to avoid encryption issue */
+								if(bSupportNmode) {
+									//N mode setting
+									ieee->SetWirelessMode(ieee->dev, \
+											ieee->current_network.mode);
+								}else{
+									//b/g mode setting
+									/*TODO*/
+									ieee->SetWirelessMode(ieee->dev, IEEE_G);
+								}
+
+								if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
+								{
+									printk("===============>entern half N mode\n");
+									ieee->bHalfWirelessN24GMode = true;
+								}
+								else
+									ieee->bHalfWirelessN24GMode = false;
+
+								ieee80211_associate_step2(ieee);
+							}else{
+								ieee80211_auth_challenge(ieee, challenge, chlen);
+							}
+						}else{
+							ieee->softmac_stats.rx_auth_rs_err++;
+							IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
+
+							printk("Authentication respose status code 0x%x",errcode);
+							ieee80211_associate_abort(ieee);
+						}
+
+					}else if (ieee->iw_mode == IW_MODE_MASTER){
+						ieee80211_rx_auth_rq(ieee, skb);
+					}
+				}
+			break;
+
+		case IEEE80211_STYPE_PROBE_REQ:
+
+			if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
+				((ieee->iw_mode == IW_MODE_ADHOC ||
+				ieee->iw_mode == IW_MODE_MASTER) &&
+				ieee->state == IEEE80211_LINKED)){
+				ieee80211_rx_probe_rq(ieee, skb);
+			}
+			break;
+
+		case IEEE80211_STYPE_DISASSOC:
+		case IEEE80211_STYPE_DEAUTH:
+			/* FIXME for now repeat all the association procedure
+			* both for disassociation and deauthentication
+			*/
+			if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
+				ieee->state == IEEE80211_LINKED &&
+				ieee->iw_mode == IW_MODE_INFRA){
+
+				ieee->state = IEEE80211_ASSOCIATING;
+				ieee->softmac_stats.reassoc++;
+				ieee->is_roaming = true;
+				ieee80211_disassociate(ieee);
+			//	notify_wx_assoc_event(ieee);
+				//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+				RemovePeerTS(ieee, header->addr2);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+				queue_work(ieee->wq, &ieee->associate_procedure_wq);
+#else
+				schedule_task(&ieee->associate_procedure_wq);
+#endif
+			}
+			break;
+		case IEEE80211_STYPE_MANAGE_ACT:
+			ieee80211_process_action(ieee,skb);
+			break;
+		default:
+			return -1;
+			break;
+	}
+
+	//dev_kfree_skb_any(skb);
+	return 0;
+}
+
+/* following are for a simplier TX queue management.
+ * Instead of using netif_[stop/wake]_queue the driver
+ * will uses these two function (plus a reset one), that
+ * will internally uses the kernel netif_* and takes
+ * care of the ieee802.11 fragmentation.
+ * So the driver receives a fragment per time and might
+ * call the stop function when it want without take care
+ * to have enought room to TX an entire packet.
+ * This might be useful if each fragment need it's own
+ * descriptor, thus just keep a total free memory > than
+ * the max fragmentation treshold is not enought.. If the
+ * ieee802.11 stack passed a TXB struct then you needed
+ * to keep N free descriptors where
+ * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
+ * In this way you need just one and the 802.11 stack
+ * will take care of buffering fragments and pass them to
+ * to the driver later, when it wakes the queue.
+ */
+void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
+{
+
+	unsigned int queue_index = txb->queue_index;
+	unsigned long flags;
+	int  i;
+	cb_desc *tcb_desc = NULL;
+
+	spin_lock_irqsave(&ieee->lock,flags);
+
+	/* called with 2nd parm 0, no tx mgmt lock required */
+	ieee80211_sta_wakeup(ieee,0);
+
+	/* update the tx status */
+//	ieee->stats.tx_bytes += txb->payload_size;
+//	ieee->stats.tx_packets++;
+	tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
+	if(tcb_desc->bMulticast) {
+		ieee->stats.multicast++;
+	}
+#if 1
+	/* if xmit available, just xmit it immediately, else just insert it to the wait queue */
+	for(i = 0; i < txb->nr_frags; i++) {
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+		if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
+#else
+		if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
+#endif
+		(!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
+		     (ieee->queue_stop)) {
+			/* insert the skb packet to the wait queue */
+			/* as for the completion function, it does not need
+			 * to check it any more.
+			 * */
+			//printk("error:no descriptor left@queue_index %d\n", queue_index);
+			//ieee80211_stop_queue(ieee);
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+			skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
+#else
+			skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
+#endif
+		}else{
+			ieee->softmac_data_hard_start_xmit(
+					txb->fragments[i],
+					ieee->dev,ieee->rate);
+			//ieee->stats.tx_packets++;
+			//ieee->stats.tx_bytes += txb->fragments[i]->len;
+			//ieee->dev->trans_start = jiffies;
+		}
+	}
+#endif
+	ieee80211_txb_free(txb);
+
+//exit:
+	spin_unlock_irqrestore(&ieee->lock,flags);
+
+}
+
+/* called with ieee->lock acquired */
+void ieee80211_resume_tx(struct ieee80211_device *ieee)
+{
+	int i;
+	for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
+
+		if (ieee->queue_stop){
+			ieee->tx_pending.frag = i;
+			return;
+		}else{
+
+			ieee->softmac_data_hard_start_xmit(
+				ieee->tx_pending.txb->fragments[i],
+				ieee->dev,ieee->rate);
+				//(i+1)<ieee->tx_pending.txb->nr_frags);
+			ieee->stats.tx_packets++;
+		//	ieee->dev->trans_start = jiffies;
+		}
+	}
+
+
+	ieee80211_txb_free(ieee->tx_pending.txb);
+	ieee->tx_pending.txb = NULL;
+}
+
+
+void ieee80211_reset_queue(struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ieee->lock,flags);
+	init_mgmt_queue(ieee);
+	if (ieee->tx_pending.txb){
+		ieee80211_txb_free(ieee->tx_pending.txb);
+		ieee->tx_pending.txb = NULL;
+	}
+	ieee->queue_stop = 0;
+	spin_unlock_irqrestore(&ieee->lock,flags);
+
+}
+
+void ieee80211_wake_queue(struct ieee80211_device *ieee)
+{
+
+	unsigned long flags;
+	struct sk_buff *skb;
+	struct ieee80211_hdr_3addr  *header;
+
+	spin_lock_irqsave(&ieee->lock,flags);
+	if (! ieee->queue_stop) goto exit;
+
+	ieee->queue_stop = 0;
+
+	if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
+		while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
+
+			header = (struct ieee80211_hdr_3addr  *) skb->data;
+
+			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+
+			if (ieee->seq_ctrl[0] == 0xFFF)
+				ieee->seq_ctrl[0] = 0;
+			else
+				ieee->seq_ctrl[0]++;
+
+			ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
+			//dev_kfree_skb_any(skb);//edit by thomas
+		}
+	}
+	if (!ieee->queue_stop && ieee->tx_pending.txb)
+		ieee80211_resume_tx(ieee);
+
+	if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
+		ieee->softmac_stats.swtxawake++;
+		netif_wake_queue(ieee->dev);
+	}
+
+exit :
+	spin_unlock_irqrestore(&ieee->lock,flags);
+}
+
+
+void ieee80211_stop_queue(struct ieee80211_device *ieee)
+{
+	//unsigned long flags;
+	//spin_lock_irqsave(&ieee->lock,flags);
+
+	if (! netif_queue_stopped(ieee->dev)){
+		netif_stop_queue(ieee->dev);
+		ieee->softmac_stats.swtxstop++;
+	}
+	ieee->queue_stop = 1;
+	//spin_unlock_irqrestore(&ieee->lock,flags);
+
+}
+
+
+inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
+{
+
+	get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
+
+	/* an IBSS cell address must have the two less significant
+	 * bits of the first byte = 2
+	 */
+	ieee->current_network.bssid[0] &= ~0x01;
+	ieee->current_network.bssid[0] |= 0x02;
+}
+
+/* called in user context only */
+void ieee80211_start_master_bss(struct ieee80211_device *ieee)
+{
+	ieee->assoc_id = 1;
+
+	if (ieee->current_network.ssid_len == 0){
+		strncpy(ieee->current_network.ssid,
+			IEEE80211_DEFAULT_TX_ESSID,
+			IW_ESSID_MAX_SIZE);
+
+		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
+		ieee->ssid_set = 1;
+	}
+
+	memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
+
+	ieee->set_chan(ieee->dev, ieee->current_network.channel);
+	ieee->state = IEEE80211_LINKED;
+	ieee->link_change(ieee->dev);
+	notify_wx_assoc_event(ieee);
+
+	if (ieee->data_hard_resume)
+		ieee->data_hard_resume(ieee->dev);
+
+	netif_carrier_on(ieee->dev);
+}
+
+void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
+{
+	if(ieee->raw_tx){
+
+		if (ieee->data_hard_resume)
+			ieee->data_hard_resume(ieee->dev);
+
+		netif_carrier_on(ieee->dev);
+	}
+}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_start_ibss_wq(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, start_ibss_wq);
+#else
+void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
+{
+#endif
+	/* iwconfig mode ad-hoc will schedule this and return
+	 * on the other hand this will block further iwconfig SET
+	 * operations because of the wx_sem hold.
+	 * Anyway some most set operations set a flag to speed-up
+	 * (abort) this wq (when syncro scanning) before sleeping
+	 * on the semaphore
+	 */
+	if(!ieee->proto_started){
+		printk("==========oh driver down return\n");
+		return;
+	}
+	down(&ieee->wx_sem);
+
+	if (ieee->current_network.ssid_len == 0){
+		strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
+		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
+		ieee->ssid_set = 1;
+	}
+
+	/* check if we have this cell in our network list */
+	ieee80211_softmac_check_all_nets(ieee);
+
+
+#ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d.
+//	if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
+	if (ieee->state == IEEE80211_NOLINK)
+		ieee->current_network.channel = 6;
+#endif
+	/* if not then the state is not linked. Maybe the user swithced to
+	 * ad-hoc mode just after being in monitor mode, or just after
+	 * being very few time in managed mode (so the card have had no
+	 * time to scan all the chans..) or we have just run up the iface
+	 * after setting ad-hoc mode. So we have to give another try..
+	 * Here, in ibss mode, should be safe to do this without extra care
+	 * (in bss mode we had to make sure no-one tryed to associate when
+	 * we had just checked the ieee->state and we was going to start the
+	 * scan) beacause in ibss mode the ieee80211_new_net function, when
+	 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
+	 * so, at worst, we waste a bit of time to initiate an unneeded syncro
+	 * scan, that will stop at the first round because it sees the state
+	 * associated.
+	 */
+	if (ieee->state == IEEE80211_NOLINK)
+		ieee80211_start_scan_syncro(ieee);
+
+	/* the network definitively is not here.. create a new cell */
+	if (ieee->state == IEEE80211_NOLINK){
+		printk("creating new IBSS cell\n");
+		if(!ieee->wap_set)
+			ieee80211_randomize_cell(ieee);
+
+		if(ieee->modulation & IEEE80211_CCK_MODULATION){
+
+			ieee->current_network.rates_len = 4;
+
+			ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+			ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+			ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+			ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+
+		}else
+			ieee->current_network.rates_len = 0;
+
+		if(ieee->modulation & IEEE80211_OFDM_MODULATION){
+			ieee->current_network.rates_ex_len = 8;
+
+			ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
+			ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
+			ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
+			ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
+			ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
+			ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
+			ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
+			ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
+
+			ieee->rate = 108;
+		}else{
+			ieee->current_network.rates_ex_len = 0;
+			ieee->rate = 22;
+		}
+
+		// By default, WMM function will be disabled in IBSS mode
+		ieee->current_network.QoS_Enable = 0;
+		ieee->SetWirelessMode(ieee->dev, IEEE_G);
+		ieee->current_network.atim_window = 0;
+		ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
+		if(ieee->short_slot)
+			ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
+
+	}
+
+	ieee->state = IEEE80211_LINKED;
+
+	ieee->set_chan(ieee->dev, ieee->current_network.channel);
+	ieee->link_change(ieee->dev);
+
+	notify_wx_assoc_event(ieee);
+
+	ieee80211_start_send_beacons(ieee);
+
+	if (ieee->data_hard_resume)
+		ieee->data_hard_resume(ieee->dev);
+	netif_carrier_on(ieee->dev);
+
+	up(&ieee->wx_sem);
+}
+
+inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
+#else
+	schedule_task(&ieee->start_ibss_wq);
+#endif
+}
+
+/* this is called only in user context, with wx_sem held */
+void ieee80211_start_bss(struct ieee80211_device *ieee)
+{
+	unsigned long flags;
+#ifdef ENABLE_DOT11D
+	//
+	// Ref: 802.11d 11.1.3.3
+	// STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
+	//
+	if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
+	{
+		if(! ieee->bGlobalDomain)
+		{
+			return;
+		}
+	}
+#endif
+	/* check if we have already found the net we
+	 * are interested in (if any).
+	 * if not (we are disassociated and we are not
+	 * in associating / authenticating phase) start the background scanning.
+	 */
+	ieee80211_softmac_check_all_nets(ieee);
+
+	/* ensure no-one start an associating process (thus setting
+	 * the ieee->state to ieee80211_ASSOCIATING) while we
+	 * have just cheked it and we are going to enable scan.
+	 * The ieee80211_new_net function is always called with
+	 * lock held (from both ieee80211_softmac_check_all_nets and
+	 * the rx path), so we cannot be in the middle of such function
+	 */
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if (ieee->state == IEEE80211_NOLINK){
+		ieee->actscanning = true;
+		ieee80211_start_scan(ieee);
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+}
+
+/* called only in userspace context */
+void ieee80211_disassociate(struct ieee80211_device *ieee)
+{
+
+
+	netif_carrier_off(ieee->dev);
+	if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
+			ieee80211_reset_queue(ieee);
+
+	if (ieee->data_hard_stop)
+			ieee->data_hard_stop(ieee->dev);
+#ifdef ENABLE_DOT11D
+	if(IS_DOT11D_ENABLE(ieee))
+		Dot11d_Reset(ieee);
+#endif
+	ieee->state = IEEE80211_NOLINK;
+	ieee->is_set_key = false;
+	ieee->link_change(ieee->dev);
+	//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	notify_wx_assoc_event(ieee);
+
+}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void ieee80211_associate_retry_wq(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, associate_retry_wq);
+#else
+void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
+{
+#endif
+	unsigned long flags;
+
+	down(&ieee->wx_sem);
+	if(!ieee->proto_started)
+		goto exit;
+
+	if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
+		goto exit;
+
+	/* until we do not set the state to IEEE80211_NOLINK
+	* there are no possibility to have someone else trying
+	* to start an association procdure (we get here with
+	* ieee->state = IEEE80211_ASSOCIATING).
+	* When we set the state to IEEE80211_NOLINK it is possible
+	* that the RX path run an attempt to associate, but
+	* both ieee80211_softmac_check_all_nets and the
+	* RX path works with ieee->lock held so there are no
+	* problems. If we are still disassociated then start a scan.
+	* the lock here is necessary to ensure no one try to start
+	* an association procedure when we have just checked the
+	* state and we are going to start the scan.
+	*/
+	ieee->beinretry = true;
+	ieee->state = IEEE80211_NOLINK;
+
+	ieee80211_softmac_check_all_nets(ieee);
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if(ieee->state == IEEE80211_NOLINK)
+	{
+		ieee->is_roaming= false;
+		ieee->actscanning = true;
+		ieee80211_start_scan(ieee);
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+	ieee->beinretry = false;
+exit:
+	up(&ieee->wx_sem);
+}
+
+struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
+{
+	u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
+
+	struct sk_buff *skb;
+	struct ieee80211_probe_response *b;
+
+	skb = ieee80211_probe_resp(ieee, broadcast_addr);
+
+	if (!skb)
+		return NULL;
+
+	b = (struct ieee80211_probe_response *) skb->data;
+	b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
+
+	return skb;
+
+}
+
+struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
+{
+	struct sk_buff *skb;
+	struct ieee80211_probe_response *b;
+
+	skb = ieee80211_get_beacon_(ieee);
+	if(!skb)
+		return NULL;
+
+	b = (struct ieee80211_probe_response *) skb->data;
+	b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
+
+	if (ieee->seq_ctrl[0] == 0xFFF)
+		ieee->seq_ctrl[0] = 0;
+	else
+		ieee->seq_ctrl[0]++;
+
+	return skb;
+}
+
+void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
+{
+	ieee->sync_scan_hurryup = 1;
+	down(&ieee->wx_sem);
+	ieee80211_stop_protocol(ieee);
+	up(&ieee->wx_sem);
+}
+
+
+void ieee80211_stop_protocol(struct ieee80211_device *ieee)
+{
+	if (!ieee->proto_started)
+		return;
+
+	ieee->proto_started = 0;
+
+	ieee80211_stop_send_beacons(ieee);
+	del_timer_sync(&ieee->associate_timer);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	cancel_delayed_work(&ieee->associate_retry_wq);
+	cancel_delayed_work(&ieee->start_ibss_wq);
+#endif
+	ieee80211_stop_scan(ieee);
+
+	ieee80211_disassociate(ieee);
+	RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
+}
+
+void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
+{
+	ieee->sync_scan_hurryup = 0;
+	down(&ieee->wx_sem);
+	ieee80211_start_protocol(ieee);
+	up(&ieee->wx_sem);
+}
+
+void ieee80211_start_protocol(struct ieee80211_device *ieee)
+{
+	short ch = 0;
+ 	int i = 0;
+	if (ieee->proto_started)
+		return;
+
+	ieee->proto_started = 1;
+
+	if (ieee->current_network.channel == 0){
+		do{
+			ch++;
+			if (ch > MAX_CHANNEL_NUMBER)
+				return; /* no channel found */
+#ifdef ENABLE_DOT11D
+		}while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
+#else
+		}while(!ieee->channel_map[ch]);
+#endif
+		ieee->current_network.channel = ch;
+	}
+
+	if (ieee->current_network.beacon_interval == 0)
+		ieee->current_network.beacon_interval = 100;
+//	printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
+//	ieee->set_chan(ieee->dev,ieee->current_network.channel);
+
+       	for(i = 0; i < 17; i++) {
+	  ieee->last_rxseq_num[i] = -1;
+	  ieee->last_rxfrag_num[i] = -1;
+	  ieee->last_packet_time[i] = 0;
+	}
+
+	ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
+
+
+	/* if the user set the MAC of the ad-hoc cell and then
+	 * switch to managed mode, shall we  make sure that association
+	 * attempts does not fail just because the user provide the essid
+	 * and the nic is still checking for the AP MAC ??
+	 */
+	if (ieee->iw_mode == IW_MODE_INFRA)
+		ieee80211_start_bss(ieee);
+
+	else if (ieee->iw_mode == IW_MODE_ADHOC)
+		ieee80211_start_ibss(ieee);
+
+	else if (ieee->iw_mode == IW_MODE_MASTER)
+		ieee80211_start_master_bss(ieee);
+
+	else if(ieee->iw_mode == IW_MODE_MONITOR)
+		ieee80211_start_monitor_mode(ieee);
+}
+
+
+#define DRV_NAME  "Ieee80211"
+void ieee80211_softmac_init(struct ieee80211_device *ieee)
+{
+	int i;
+	memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
+
+	ieee->state = IEEE80211_NOLINK;
+	ieee->sync_scan_hurryup = 0;
+	for(i = 0; i < 5; i++) {
+	  ieee->seq_ctrl[i] = 0;
+	}
+#ifdef ENABLE_DOT11D
+	ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
+	if (!ieee->pDot11dInfo)
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
+	memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO));
+#endif
+	//added for  AP roaming
+	ieee->LinkDetectInfo.SlotNum = 2;
+	ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
+        ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
+
+	ieee->assoc_id = 0;
+	ieee->queue_stop = 0;
+	ieee->scanning = 0;
+	ieee->softmac_features = 0; //so IEEE2100-like driver are happy
+	ieee->wap_set = 0;
+	ieee->ssid_set = 0;
+	ieee->proto_started = 0;
+	ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
+	ieee->rate = 22;
+	ieee->ps = IEEE80211_PS_DISABLED;
+	ieee->sta_sleep = 0;
+	ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
+	ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
+	ieee->Regdot11HTOperationalRateSet[4]= 0x01;
+	//added by amy
+	ieee->actscanning = false;
+	ieee->beinretry = false;
+	ieee->is_set_key = false;
+	init_mgmt_queue(ieee);
+
+	ieee->sta_edca_param[0] = 0x0000A403;
+	ieee->sta_edca_param[1] = 0x0000A427;
+	ieee->sta_edca_param[2] = 0x005E4342;
+	ieee->sta_edca_param[3] = 0x002F3262;
+	ieee->aggregation = true;
+	ieee->enable_rx_imm_BA = 1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	init_timer(&ieee->scan_timer);
+	ieee->scan_timer.data = (unsigned long)ieee;
+	ieee->scan_timer.function = ieee80211_softmac_scan_cb;
+#endif
+	ieee->tx_pending.txb = NULL;
+
+	init_timer(&ieee->associate_timer);
+	ieee->associate_timer.data = (unsigned long)ieee;
+	ieee->associate_timer.function = ieee80211_associate_abort_cb;
+
+	init_timer(&ieee->beacon_timer);
+	ieee->beacon_timer.data = (unsigned long) ieee;
+	ieee->beacon_timer.function = ieee80211_send_beacon_cb;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+#ifdef PF_SYNCTHREAD
+	ieee->wq = create_workqueue(DRV_NAME,0);
+#else
+	ieee->wq = create_workqueue(DRV_NAME);
+#endif
+#endif
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+        INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
+        INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
+        INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
+        INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
+        INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
+        INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
+
+#else
+	INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
+	INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
+	INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
+	INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
+	INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
+	INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
+#endif
+
+#else
+	tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
+	tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
+	tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
+	tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
+	tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
+	tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
+#endif
+	sema_init(&ieee->wx_sem, 1);
+	sema_init(&ieee->scan_sem, 1);
+
+	spin_lock_init(&ieee->mgmt_tx_lock);
+	spin_lock_init(&ieee->beacon_lock);
+
+	tasklet_init(&ieee->ps_task,
+	     (void(*)(unsigned long)) ieee80211_sta_ps,
+	     (unsigned long)ieee);
+
+}
+
+void ieee80211_softmac_free(struct ieee80211_device *ieee)
+{
+	down(&ieee->wx_sem);
+#ifdef ENABLE_DOT11D
+	if(NULL != ieee->pDot11dInfo)
+	{
+		kfree(ieee->pDot11dInfo);
+		ieee->pDot11dInfo = NULL;
+	}
+#endif
+	del_timer_sync(&ieee->associate_timer);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	cancel_delayed_work(&ieee->associate_retry_wq);
+	destroy_workqueue(ieee->wq);
+#endif
+
+	up(&ieee->wx_sem);
+}
+
+/********************************************************
+ * Start of WPA code.                                   *
+ * this is stolen from the ipw2200 driver               *
+ ********************************************************/
+
+
+static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
+{
+	/* This is called when wpa_supplicant loads and closes the driver
+	 * interface. */
+	printk("%s WPA\n",value ? "enabling" : "disabling");
+	ieee->wpa_enabled = value;
+	return 0;
+}
+
+
+void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
+{
+	/* make sure WPA is enabled */
+	ieee80211_wpa_enable(ieee, 1);
+
+	ieee80211_disassociate(ieee);
+}
+
+
+static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
+{
+
+	int ret = 0;
+
+	switch (command) {
+	case IEEE_MLME_STA_DEAUTH:
+		// silently ignore
+		break;
+
+	case IEEE_MLME_STA_DISASSOC:
+		ieee80211_disassociate(ieee);
+		break;
+
+	default:
+		printk("Unknown MLME request: %d\n", command);
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+
+static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
+			      struct ieee_param *param, int plen)
+{
+	u8 *buf;
+
+	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
+	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
+		return -EINVAL;
+
+	if (param->u.wpa_ie.len) {
+		buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+
+		memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = buf;
+		ieee->wpa_ie_len = param->u.wpa_ie.len;
+	} else {
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = NULL;
+		ieee->wpa_ie_len = 0;
+	}
+
+	ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
+	return 0;
+}
+
+#define AUTH_ALG_OPEN_SYSTEM			0x1
+#define AUTH_ALG_SHARED_KEY			0x2
+
+static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
+{
+
+	struct ieee80211_security sec = {
+		.flags = SEC_AUTH_MODE,
+	};
+	int ret = 0;
+
+	if (value & AUTH_ALG_SHARED_KEY) {
+		sec.auth_mode = WLAN_AUTH_SHARED_KEY;
+		ieee->open_wep = 0;
+		ieee->auth_mode = 1;
+	} else if (value & AUTH_ALG_OPEN_SYSTEM){
+		sec.auth_mode = WLAN_AUTH_OPEN;
+		ieee->open_wep = 1;
+		ieee->auth_mode = 0;
+	}
+	else if (value & IW_AUTH_ALG_LEAP){
+		sec.auth_mode = WLAN_AUTH_LEAP;
+		ieee->open_wep = 1;
+		ieee->auth_mode = 2;
+	}
+
+
+	if (ieee->set_security)
+		ieee->set_security(ieee->dev, &sec);
+	//else
+	//	ret = -EOPNOTSUPP;
+
+	return ret;
+}
+
+static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
+{
+	int ret=0;
+	unsigned long flags;
+
+	switch (name) {
+	case IEEE_PARAM_WPA_ENABLED:
+		ret = ieee80211_wpa_enable(ieee, value);
+		break;
+
+	case IEEE_PARAM_TKIP_COUNTERMEASURES:
+		ieee->tkip_countermeasures=value;
+		break;
+
+	case IEEE_PARAM_DROP_UNENCRYPTED: {
+		/* HACK:
+		 *
+		 * wpa_supplicant calls set_wpa_enabled when the driver
+		 * is loaded and unloaded, regardless of if WPA is being
+		 * used.  No other calls are made which can be used to
+		 * determine if encryption will be used or not prior to
+		 * association being expected.  If encryption is not being
+		 * used, drop_unencrypted is set to false, else true -- we
+		 * can use this to determine if the CAP_PRIVACY_ON bit should
+		 * be set.
+		 */
+		struct ieee80211_security sec = {
+			.flags = SEC_ENABLED,
+			.enabled = value,
+		};
+ 		ieee->drop_unencrypted = value;
+		/* We only change SEC_LEVEL for open mode. Others
+		 * are set by ipw_wpa_set_encryption.
+		 */
+		if (!value) {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_0;
+		}
+		else {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_1;
+		}
+		if (ieee->set_security)
+			ieee->set_security(ieee->dev, &sec);
+		break;
+	}
+
+	case IEEE_PARAM_PRIVACY_INVOKED:
+		ieee->privacy_invoked=value;
+		break;
+
+	case IEEE_PARAM_AUTH_ALGS:
+		ret = ieee80211_wpa_set_auth_algs(ieee, value);
+		break;
+
+	case IEEE_PARAM_IEEE_802_1X:
+		ieee->ieee802_1x=value;
+		break;
+	case IEEE_PARAM_WPAX_SELECT:
+		// added for WPA2 mixed mode
+		spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
+		ieee->wpax_type_set = 1;
+		ieee->wpax_type_notify = value;
+		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
+		break;
+
+	default:
+		printk("Unknown WPA param: %d\n",name);
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+/* implementation borrowed from hostap driver */
+
+static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
+				  struct ieee_param *param, int param_len)
+{
+	int ret = 0;
+
+	struct ieee80211_crypto_ops *ops;
+	struct ieee80211_crypt_data **crypt;
+
+	struct ieee80211_security sec = {
+		.flags = 0,
+	};
+
+	param->u.crypt.err = 0;
+	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
+
+	if (param_len !=
+	    (int) ((char *) param->u.crypt.key - (char *) param) +
+	    param->u.crypt.key_len) {
+		printk("Len mismatch %d, %d\n", param_len,
+			       param->u.crypt.key_len);
+		return -EINVAL;
+	}
+	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+		if (param->u.crypt.idx >= WEP_KEYS)
+			return -EINVAL;
+		crypt = &ieee->crypt[param->u.crypt.idx];
+	} else {
+		return -EINVAL;
+	}
+
+	if (strcmp(param->u.crypt.alg, "none") == 0) {
+		if (crypt) {
+			sec.enabled = 0;
+			// FIXME FIXME
+			//sec.encrypt = 0;
+			sec.level = SEC_LEVEL_0;
+			sec.flags |= SEC_ENABLED | SEC_LEVEL;
+			ieee80211_crypt_delayed_deinit(ieee, crypt);
+		}
+		goto done;
+	}
+	sec.enabled = 1;
+// FIXME FIXME
+//	sec.encrypt = 1;
+	sec.flags |= SEC_ENABLED;
+
+	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
+	if (!(ieee->host_encrypt || ieee->host_decrypt) &&
+	    strcmp(param->u.crypt.alg, "TKIP"))
+		goto skip_host_crypt;
+
+	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
+		request_module("ieee80211_crypt_wep");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+		//set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
+		request_module("ieee80211_crypt_tkip");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
+		request_module("ieee80211_crypt_ccmp");
+		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
+	}
+	if (ops == NULL) {
+		printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
+		param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
+		ret = -EINVAL;
+		goto done;
+	}
+
+	if (*crypt == NULL || (*crypt)->ops != ops) {
+		struct ieee80211_crypt_data *new_crypt;
+
+		ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+		new_crypt = (struct ieee80211_crypt_data *)
+			kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+		if (new_crypt == NULL) {
+			ret = -ENOMEM;
+			goto done;
+		}
+		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
+		new_crypt->ops = ops;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+#else
+		if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
+#endif
+			new_crypt->priv =
+				new_crypt->ops->init(param->u.crypt.idx);
+
+		if (new_crypt->priv == NULL) {
+			kfree(new_crypt);
+			param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
+			ret = -EINVAL;
+			goto done;
+		}
+
+		*crypt = new_crypt;
+	}
+
+	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
+	    (*crypt)->ops->set_key(param->u.crypt.key,
+				   param->u.crypt.key_len, param->u.crypt.seq,
+				   (*crypt)->priv) < 0) {
+		printk("key setting failed\n");
+		param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
+		ret = -EINVAL;
+		goto done;
+	}
+
+ skip_host_crypt:
+	if (param->u.crypt.set_tx) {
+		ieee->tx_keyidx = param->u.crypt.idx;
+		sec.active_key = param->u.crypt.idx;
+		sec.flags |= SEC_ACTIVE_KEY;
+	} else
+		sec.flags &= ~SEC_ACTIVE_KEY;
+
+	if (param->u.crypt.alg != NULL) {
+		memcpy(sec.keys[param->u.crypt.idx],
+		       param->u.crypt.key,
+		       param->u.crypt.key_len);
+		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
+		sec.flags |= (1 << param->u.crypt.idx);
+
+		if (strcmp(param->u.crypt.alg, "WEP") == 0) {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_1;
+		} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_2;
+		} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
+			sec.flags |= SEC_LEVEL;
+			sec.level = SEC_LEVEL_3;
+		}
+	}
+ done:
+	if (ieee->set_security)
+		ieee->set_security(ieee->dev, &sec);
+
+	/* Do not reset port if card is in Managed mode since resetting will
+	 * generate new IEEE 802.11 authentication which may end up in looping
+	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
+	 * configuration (for example... Prism2), implement the reset_port in
+	 * the callbacks structures used to initialize the 802.11 stack. */
+	if (ieee->reset_on_keychange &&
+	    ieee->iw_mode != IW_MODE_INFRA &&
+	    ieee->reset_port &&
+	    ieee->reset_port(ieee->dev)) {
+		printk("reset_port failed\n");
+		param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+inline struct sk_buff *ieee80211_disassociate_skb(
+							struct ieee80211_network *beacon,
+							struct ieee80211_device *ieee,
+							u8	asRsn)
+{
+	struct sk_buff *skb;
+	struct ieee80211_disassoc *disass;
+
+	skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
+	if (!skb)
+		return NULL;
+
+	disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
+	disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
+	disass->header.duration_id = 0;
+
+	memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
+	memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
+
+	disass->reason = asRsn;
+	return skb;
+}
+
+
+void
+SendDisassociation(
+		struct ieee80211_device *ieee,
+		u8* 					asSta,
+		u8						asRsn
+)
+{
+		struct ieee80211_network *beacon = &ieee->current_network;
+		struct sk_buff *skb;
+		skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
+		if (skb){
+				softmac_mgmt_xmit(skb, ieee);
+				//dev_kfree_skb_any(skb);//edit by thomas
+		}
+}
+
+int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
+{
+	struct ieee_param *param;
+	int ret=0;
+
+	down(&ieee->wx_sem);
+	//IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
+
+	if (p->length < sizeof(struct ieee_param) || !p->pointer){
+		ret = -EINVAL;
+		goto out;
+	}
+
+	param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
+	if (param == NULL){
+		ret = -ENOMEM;
+		goto out;
+	}
+	if (copy_from_user(param, p->pointer, p->length)) {
+		kfree(param);
+		ret = -EFAULT;
+		goto out;
+	}
+
+	switch (param->cmd) {
+
+	case IEEE_CMD_SET_WPA_PARAM:
+		ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
+					param->u.wpa_param.value);
+		break;
+
+	case IEEE_CMD_SET_WPA_IE:
+		ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
+		break;
+
+	case IEEE_CMD_SET_ENCRYPTION:
+		ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
+		break;
+
+	case IEEE_CMD_MLME:
+		ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
+				   param->u.mlme.reason_code);
+		break;
+
+	default:
+		printk("Unknown WPA supplicant request: %d\n",param->cmd);
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
+		ret = -EFAULT;
+
+	kfree(param);
+out:
+	up(&ieee->wx_sem);
+
+	return ret;
+}
+
+void notify_wx_assoc_event(struct ieee80211_device *ieee)
+{
+	union iwreq_data wrqu;
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	if (ieee->state == IEEE80211_LINKED)
+		memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
+	else
+		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_get_beacon);
+//EXPORT_SYMBOL(ieee80211_wake_queue);
+//EXPORT_SYMBOL(ieee80211_stop_queue);
+//EXPORT_SYMBOL(ieee80211_reset_queue);
+//EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
+//EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
+//EXPORT_SYMBOL(ieee80211_is_shortslot);
+//EXPORT_SYMBOL(ieee80211_is_54g);
+//EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
+//EXPORT_SYMBOL(ieee80211_ps_tx_ack);
+//EXPORT_SYMBOL(ieee80211_softmac_xmit);
+//EXPORT_SYMBOL(ieee80211_stop_send_beacons);
+//EXPORT_SYMBOL(notify_wx_assoc_event);
+//EXPORT_SYMBOL(SendDisassociation);
+//EXPORT_SYMBOL(ieee80211_disassociate);
+//EXPORT_SYMBOL(ieee80211_start_send_beacons);
+//EXPORT_SYMBOL(ieee80211_stop_scan);
+//EXPORT_SYMBOL(ieee80211_send_probe_requests);
+//EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
+//EXPORT_SYMBOL(ieee80211_start_scan_syncro);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
+EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue);
+EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue);
+EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
+EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
+EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
+EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot);
+EXPORT_SYMBOL_NOVERS(ieee80211_is_54g);
+EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl);
+EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack);
+EXPORT_SYMBOL_NOVERS(ieee80211_softmac_xmit);
+EXPORT_SYMBOL_NOVERS(ieee80211_stop_send_beacons);
+EXPORT_SYMBOL_NOVERS(notify_wx_assoc_event);
+EXPORT_SYMBOL_NOVERS(SendDisassociation);
+EXPORT_SYMBOL_NOVERS(ieee80211_disassociate);
+EXPORT_SYMBOL_NOVERS(ieee80211_start_send_beacons);
+EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
+EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests);
+EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro);
+EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro);
+#endif
+//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
new file mode 100644
index 0000000..7c21aaa
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c
@@ -0,0 +1,682 @@
+/* IEEE 802.11 SoftMAC layer
+ * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Mostly extracted from the rtl8180-sa2400 driver for the
+ * in-kernel generic ieee802.11 stack.
+ *
+ * Some pieces of code might be stolen from ipw2100 driver
+ * copyright of who own it's copyright ;-)
+ *
+ * PS wx handler mostly stolen from hostap, copyright who
+ * own it's copyright ;-)
+ *
+ * released under the GPL
+ */
+
+
+#include "ieee80211.h"
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+/* FIXME: add A freqs */
+
+const long ieee80211_wlan_frequencies[] = {
+	2412, 2417, 2422, 2427,
+	2432, 2437, 2442, 2447,
+	2452, 2457, 2462, 2467,
+	2472, 2484
+};
+
+
+int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	int ret;
+	struct iw_freq *fwrq = & wrqu->freq;
+
+	down(&ieee->wx_sem);
+
+	if(ieee->iw_mode == IW_MODE_INFRA){
+		ret = -EOPNOTSUPP;
+		goto out;
+	}
+
+	/* if setting by freq convert to channel */
+	if (fwrq->e == 1) {
+		if ((fwrq->m >= (int) 2.412e8 &&
+		     fwrq->m <= (int) 2.487e8)) {
+			int f = fwrq->m / 100000;
+			int c = 0;
+
+			while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
+				c++;
+
+			/* hack to fall through */
+			fwrq->e = 0;
+			fwrq->m = c + 1;
+		}
+	}
+
+	if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
+		ret = -EOPNOTSUPP;
+		goto out;
+
+	}else { /* Set the channel */
+
+#ifdef ENABLE_DOT11D
+		if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
+			ret = -EINVAL;
+			goto out;
+		}
+#endif
+		ieee->current_network.channel = fwrq->m;
+		ieee->set_chan(ieee->dev, ieee->current_network.channel);
+
+		if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
+			if(ieee->state == IEEE80211_LINKED){
+
+			ieee80211_stop_send_beacons(ieee);
+			ieee80211_start_send_beacons(ieee);
+			}
+	}
+
+	ret = 0;
+out:
+	up(&ieee->wx_sem);
+	return ret;
+}
+
+
+int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
+			     struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct iw_freq *fwrq = & wrqu->freq;
+
+	if (ieee->current_network.channel == 0)
+		return -1;
+	//NM 0.7.0 will not accept channel any more.
+	fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000;
+	fwrq->e = 1;
+//	fwrq->m = ieee->current_network.channel;
+//	fwrq->e = 0;
+
+	return 0;
+}
+
+int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	unsigned long flags;
+	wrqu->ap_addr.sa_family = ARPHRD_ETHER;
+
+	if (ieee->iw_mode == IW_MODE_MONITOR)
+		return -1;
+
+	/* We want avoid to give to the user inconsistent infos*/
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if (ieee->state != IEEE80211_LINKED &&
+		ieee->state != IEEE80211_LINKED_SCANNING &&
+		ieee->wap_set == 0)
+
+		memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
+	else
+		memcpy(wrqu->ap_addr.sa_data,
+		       ieee->current_network.bssid, ETH_ALEN);
+
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+	return 0;
+}
+
+
+int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
+			 struct iw_request_info *info,
+			 union iwreq_data *awrq,
+			 char *extra)
+{
+
+	int ret = 0;
+	u8 zero[] = {0,0,0,0,0,0};
+	unsigned long flags;
+
+	short ifup = ieee->proto_started;//dev->flags & IFF_UP;
+	struct sockaddr *temp = (struct sockaddr *)awrq;
+
+	ieee->sync_scan_hurryup = 1;
+
+	down(&ieee->wx_sem);
+	/* use ifconfig hw ether */
+	if (ieee->iw_mode == IW_MODE_MASTER){
+		ret = -1;
+		goto out;
+	}
+
+	if (temp->sa_family != ARPHRD_ETHER){
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (ifup)
+		ieee80211_stop_protocol(ieee);
+
+	/* just to avoid to give inconsistent infos in the
+	 * get wx method. not really needed otherwise
+	 */
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
+	ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
+
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+	if (ifup)
+		ieee80211_start_protocol(ieee);
+out:
+	up(&ieee->wx_sem);
+	return ret;
+}
+
+ int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
+{
+	int len,ret = 0;
+	unsigned long flags;
+
+	if (ieee->iw_mode == IW_MODE_MONITOR)
+		return -1;
+
+	/* We want avoid to give to the user inconsistent infos*/
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if (ieee->current_network.ssid[0] == '\0' ||
+		ieee->current_network.ssid_len == 0){
+		ret = -1;
+		goto out;
+	}
+
+	if (ieee->state != IEEE80211_LINKED &&
+		ieee->state != IEEE80211_LINKED_SCANNING &&
+		ieee->ssid_set == 0){
+		ret = -1;
+		goto out;
+	}
+	len = ieee->current_network.ssid_len;
+	wrqu->essid.length = len;
+	strncpy(b,ieee->current_network.ssid,len);
+	wrqu->essid.flags = 1;
+
+out:
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+	return ret;
+
+}
+
+int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+
+	u32 target_rate = wrqu->bitrate.value;
+
+	ieee->rate = target_rate/100000;
+	//FIXME: we might want to limit rate also in management protocols.
+	return 0;
+}
+
+
+
+int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	u32 tmp_rate;
+#if 0
+	printk("===>mode:%d, halfNmode:%d\n", ieee->mode, ieee->bHalfWirelessN24GMode);
+	if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G))
+		tmp_rate = ieee->rate;
+	else if (ieee->mode & IEEE_N_5G)
+		tmp_rate = 580;
+	else if (ieee->mode & IEEE_N_24G)
+	{
+		if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+			tmp_rate = HTHalfMcsToDataRate(ieee, 15);
+		else
+			tmp_rate = HTMcsToDataRate(ieee, 15);
+	}
+#else
+	tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate);
+
+#endif
+	wrqu->bitrate.value = tmp_rate * 500000;
+
+	return 0;
+}
+
+
+int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	if (wrqu->rts.disabled || !wrqu->rts.fixed)
+		ieee->rts = DEFAULT_RTS_THRESHOLD;
+	else
+	{
+		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
+				wrqu->rts.value > MAX_RTS_THRESHOLD)
+			return -EINVAL;
+		ieee->rts = wrqu->rts.value;
+	}
+	return 0;
+}
+
+int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	wrqu->rts.value = ieee->rts;
+	wrqu->rts.fixed = 0;	/* no auto select */
+	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
+	return 0;
+}
+int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+
+	ieee->sync_scan_hurryup = 1;
+
+	down(&ieee->wx_sem);
+
+	if (wrqu->mode == ieee->iw_mode)
+		goto out;
+
+	if (wrqu->mode == IW_MODE_MONITOR){
+
+		ieee->dev->type = ARPHRD_IEEE80211;
+	}else{
+		ieee->dev->type = ARPHRD_ETHER;
+	}
+
+	if (!ieee->proto_started){
+		ieee->iw_mode = wrqu->mode;
+	}else{
+		ieee80211_stop_protocol(ieee);
+		ieee->iw_mode = wrqu->mode;
+		ieee80211_start_protocol(ieee);
+	}
+
+out:
+	up(&ieee->wx_sem);
+	return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+void ieee80211_wx_sync_scan_wq(struct work_struct *work)
+{
+        struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
+#else
+void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
+{
+#endif
+	short chan;
+	HT_EXTCHNL_OFFSET chan_offset=0;
+	HT_CHANNEL_WIDTH bandwidth=0;
+	int b40M = 0;
+	static int count = 0;
+	chan = ieee->current_network.channel;
+	netif_carrier_off(ieee->dev);
+
+	if (ieee->data_hard_stop)
+		ieee->data_hard_stop(ieee->dev);
+
+	ieee80211_stop_send_beacons(ieee);
+
+	ieee->state = IEEE80211_LINKED_SCANNING;
+	ieee->link_change(ieee->dev);
+	ieee->InitialGainHandler(ieee->dev,IG_Backup);
+	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
+		b40M = 1;
+		chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
+		bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz;
+		printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth);
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+		}
+	ieee80211_start_scan_syncro(ieee);
+	if (b40M) {
+		printk("Scan in 20M, back to 40M\n");
+		if (chan_offset == HT_EXTCHNL_OFFSET_UPPER)
+			ieee->set_chan(ieee->dev, chan + 2);
+		else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER)
+			ieee->set_chan(ieee->dev, chan - 2);
+		else
+			ieee->set_chan(ieee->dev, chan);
+		ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset);
+	} else {
+		ieee->set_chan(ieee->dev, chan);
+	}
+
+	ieee->InitialGainHandler(ieee->dev,IG_Restore);
+	ieee->state = IEEE80211_LINKED;
+	ieee->link_change(ieee->dev);
+	// To prevent the immediately calling watch_dog after scan.
+	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
+	{
+		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
+		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
+	}
+	if (ieee->data_hard_resume)
+		ieee->data_hard_resume(ieee->dev);
+
+	if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
+		ieee80211_start_send_beacons(ieee);
+
+	netif_carrier_on(ieee->dev);
+	count = 0;
+	up(&ieee->wx_sem);
+
+}
+
+int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	int ret = 0;
+
+	down(&ieee->wx_sem);
+
+	if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
+		ret = -1;
+		goto out;
+	}
+
+	if ( ieee->state == IEEE80211_LINKED){
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+		queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
+#else
+		schedule_task(&ieee->wx_sync_scan_wq);
+#endif
+		/* intentionally forget to up sem */
+		return 0;
+	}
+
+out:
+	up(&ieee->wx_sem);
+	return ret;
+}
+
+int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
+			      struct iw_request_info *a,
+			      union iwreq_data *wrqu, char *extra)
+{
+
+	int ret=0,len;
+	short proto_started;
+	unsigned long flags;
+
+	ieee->sync_scan_hurryup = 1;
+	down(&ieee->wx_sem);
+
+	proto_started = ieee->proto_started;
+
+	if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
+		ret= -E2BIG;
+		goto out;
+	}
+
+	if (ieee->iw_mode == IW_MODE_MONITOR){
+		ret= -1;
+		goto out;
+	}
+
+	if(proto_started)
+		ieee80211_stop_protocol(ieee);
+
+
+	/* this is just to be sure that the GET wx callback
+	 * has consisten infos. not needed otherwise
+	 */
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	if (wrqu->essid.flags && wrqu->essid.length) {
+		//first flush current network.ssid
+		len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
+#if LINUX_VERSION_CODE <  KERNEL_VERSION(2,6,20)
+		strncpy(ieee->current_network.ssid, extra, len);
+		ieee->current_network.ssid_len = len;
+#if 0
+		{
+			int i;
+			for (i=0; i<len; i++)
+				printk("%c ", extra[i]);
+			printk("\n");
+		}
+#endif
+#else
+		strncpy(ieee->current_network.ssid, extra, len+1);
+		ieee->current_network.ssid_len = len+1;
+#if 0
+		{
+			int i;
+			for (i=0; i<len + 1; i++)
+				printk("%c ", extra[i]);
+			printk("\n");
+		}
+#endif
+#endif
+		ieee->ssid_set = 1;
+	}
+	else{
+		ieee->ssid_set = 0;
+		ieee->current_network.ssid[0] = '\0';
+		ieee->current_network.ssid_len = 0;
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+
+	if (proto_started)
+		ieee80211_start_protocol(ieee);
+out:
+	up(&ieee->wx_sem);
+	return ret;
+}
+
+ int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+
+	wrqu->mode = ieee->iw_mode;
+	return 0;
+}
+
+ int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+
+	int *parms = (int *)extra;
+	int enable = (parms[0] > 0);
+	short prev = ieee->raw_tx;
+
+	down(&ieee->wx_sem);
+
+	if(enable)
+		ieee->raw_tx = 1;
+	else
+		ieee->raw_tx = 0;
+
+	printk(KERN_INFO"raw TX is %s\n",
+	      ieee->raw_tx ? "enabled" : "disabled");
+
+	if(ieee->iw_mode == IW_MODE_MONITOR)
+	{
+		if(prev == 0 && ieee->raw_tx){
+			if (ieee->data_hard_resume)
+				ieee->data_hard_resume(ieee->dev);
+
+			netif_carrier_on(ieee->dev);
+		}
+
+		if(prev && ieee->raw_tx == 1)
+			netif_carrier_off(ieee->dev);
+	}
+
+	up(&ieee->wx_sem);
+
+	return 0;
+}
+
+int ieee80211_wx_get_name(struct ieee80211_device *ieee,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	strcpy(wrqu->name, "802.11");
+	if(ieee->modulation & IEEE80211_CCK_MODULATION)
+		strcat(wrqu->name, "b");
+	if(ieee->modulation & IEEE80211_OFDM_MODULATION)
+		strcat(wrqu->name, "g");
+	if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
+		strcat(wrqu->name, "n");
+	return 0;
+}
+
+
+/* this is mostly stolen from hostap */
+int ieee80211_wx_set_power(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra)
+{
+	int ret = 0;
+#if 1
+	if(
+		(!ieee->sta_wake_up) ||
+	//	(!ieee->ps_request_tx_ack) ||
+		(!ieee->enter_sleep_state) ||
+		(!ieee->ps_is_queue_empty)){
+
+	//	printk("ERROR. PS mode is tryied to be use but driver missed a callback\n\n");
+
+		return -1;
+	}
+#endif
+	down(&ieee->wx_sem);
+
+	if (wrqu->power.disabled){
+		ieee->ps = IEEE80211_PS_DISABLED;
+		goto exit;
+	}
+	if (wrqu->power.flags & IW_POWER_TIMEOUT) {
+		//ieee->ps_period = wrqu->power.value / 1000;
+		ieee->ps_timeout = wrqu->power.value / 1000;
+	}
+
+	if (wrqu->power.flags & IW_POWER_PERIOD) {
+
+		//ieee->ps_timeout = wrqu->power.value / 1000;
+		ieee->ps_period = wrqu->power.value / 1000;
+		//wrq->value / 1024;
+
+	}
+	switch (wrqu->power.flags & IW_POWER_MODE) {
+	case IW_POWER_UNICAST_R:
+		ieee->ps = IEEE80211_PS_UNICAST;
+		break;
+	case IW_POWER_MULTICAST_R:
+		ieee->ps = IEEE80211_PS_MBCAST;
+		break;
+	case IW_POWER_ALL_R:
+		ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
+		break;
+
+	case IW_POWER_ON:
+	//	ieee->ps = IEEE80211_PS_DISABLED;
+		break;
+
+	default:
+		ret = -EINVAL;
+		goto exit;
+
+	}
+exit:
+	up(&ieee->wx_sem);
+	return ret;
+
+}
+
+/* this is stolen from hostap */
+int ieee80211_wx_get_power(struct ieee80211_device *ieee,
+				 struct iw_request_info *info,
+				 union iwreq_data *wrqu, char *extra)
+{
+	int ret =0;
+
+	down(&ieee->wx_sem);
+
+	if(ieee->ps == IEEE80211_PS_DISABLED){
+		wrqu->power.disabled = 1;
+		goto exit;
+	}
+
+	wrqu->power.disabled = 0;
+
+	if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+		wrqu->power.flags = IW_POWER_TIMEOUT;
+		wrqu->power.value = ieee->ps_timeout * 1000;
+	} else {
+//		ret = -EOPNOTSUPP;
+//		goto exit;
+		wrqu->power.flags = IW_POWER_PERIOD;
+		wrqu->power.value = ieee->ps_period * 1000;
+//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024;
+	}
+
+       if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST))
+	   	wrqu->power.flags |= IW_POWER_ALL_R;
+	else if (ieee->ps & IEEE80211_PS_MBCAST)
+		wrqu->power.flags |= IW_POWER_MULTICAST_R;
+	else
+		wrqu->power.flags |= IW_POWER_UNICAST_R;
+
+exit:
+	up(&ieee->wx_sem);
+	return ret;
+
+}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_wx_get_essid);
+//EXPORT_SYMBOL(ieee80211_wx_set_essid);
+//EXPORT_SYMBOL(ieee80211_wx_set_rate);
+//EXPORT_SYMBOL(ieee80211_wx_get_rate);
+//EXPORT_SYMBOL(ieee80211_wx_set_wap);
+//EXPORT_SYMBOL(ieee80211_wx_get_wap);
+//EXPORT_SYMBOL(ieee80211_wx_set_mode);
+//EXPORT_SYMBOL(ieee80211_wx_get_mode);
+//EXPORT_SYMBOL(ieee80211_wx_set_scan);
+//EXPORT_SYMBOL(ieee80211_wx_get_freq);
+//EXPORT_SYMBOL(ieee80211_wx_set_freq);
+//EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
+//EXPORT_SYMBOL(ieee80211_wx_get_name);
+//EXPORT_SYMBOL(ieee80211_wx_set_power);
+//EXPORT_SYMBOL(ieee80211_wx_get_power);
+//EXPORT_SYMBOL(ieee80211_wlan_frequencies);
+//EXPORT_SYMBOL(ieee80211_wx_set_rts);
+//EXPORT_SYMBOL(ieee80211_wx_get_rts);
+#else
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power);
+EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rts);
+EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rts);
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
new file mode 100644
index 0000000..103b33c
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c
@@ -0,0 +1,933 @@
+/******************************************************************************
+
+  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 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.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+
+  Contact Information:
+  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+******************************************************************************
+
+  Few modifications for Realtek's Wi-Fi drivers by
+  Andrea Merello <andreamrl@tiscali.it>
+
+  A special thanks goes to Realtek for their support !
+
+******************************************************************************/
+
+#include <linux/compiler.h>
+//#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/if_arp.h>
+#include <linux/in6.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <asm/uaccess.h>
+#include <linux/if_vlan.h>
+
+#include "ieee80211.h"
+
+
+/*
+
+
+802.11 Data Frame
+
+
+802.11 frame_contorl for data frames - 2 bytes
+     ,-----------------------------------------------------------------------------------------.
+bits | 0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  a  |  b  |  c  |  d  |  e   |
+     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
+val  | 0  |  0  |  0  |  1  |  x  |  0  |  0  |  0  |  1  |  0  |  x  |  x  |  x  |  x  |  x   |
+     |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
+desc | ^-ver-^  |  ^type-^  |  ^-----subtype-----^  | to  |from |more |retry| pwr |more |wep   |
+     |          |           | x=0 data,x=1 data+ack | DS  | DS  |frag |     | mgm |data |      |
+     '-----------------------------------------------------------------------------------------'
+		                                    /\
+                                                    |
+802.11 Data Frame                                   |
+           ,--------- 'ctrl' expands to >-----------'
+          |
+      ,--'---,-------------------------------------------------------------.
+Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
+      |------|------|---------|---------|---------|------|---------|------|
+Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  Frame  |  fcs |
+      |      | tion | (BSSID) |         |         | ence |  data   |      |
+      `--------------------------------------------------|         |------'
+Total: 28 non-data bytes                                 `----.----'
+                                                              |
+       .- 'Frame data' expands to <---------------------------'
+       |
+       V
+      ,---------------------------------------------------.
+Bytes |  1   |  1   |    1    |    3     |  2   |  0-2304 |
+      |------|------|---------|----------|------|---------|
+Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP      |
+      | DSAP | SSAP |         |          |      | Packet  |
+      | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8|      |         |
+      `-----------------------------------------|         |
+Total: 8 non-data bytes                         `----.----'
+                                                     |
+       .- 'IP Packet' expands, if WEP enabled, to <--'
+       |
+       V
+      ,-----------------------.
+Bytes |  4  |   0-2296  |  4  |
+      |-----|-----------|-----|
+Desc. | IV  | Encrypted | ICV |
+      |     | IP Packet |     |
+      `-----------------------'
+Total: 8 non-data bytes
+
+
+802.3 Ethernet Data Frame
+
+      ,-----------------------------------------.
+Bytes |   6   |   6   |  2   |  Variable |   4  |
+      |-------|-------|------|-----------|------|
+Desc. | Dest. | Source| Type | IP Packet |  fcs |
+      |  MAC  |  MAC  |      |           |      |
+      `-----------------------------------------'
+Total: 18 non-data bytes
+
+In the event that fragmentation is required, the incoming payload is split into
+N parts of size ieee->fts.  The first fragment contains the SNAP header and the
+remaining packets are just data.
+
+If encryption is enabled, each fragment payload size is reduced by enough space
+to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
+So if you have 1500 bytes of payload with ieee->fts set to 500 without
+encryption it will take 3 frames.  With WEP it will take 4 frames as the
+payload of each frame is reduced to 492 bytes.
+
+* SKB visualization
+*
+*  ,- skb->data
+* |
+* |    ETHERNET HEADER        ,-<-- PAYLOAD
+* |                           |     14 bytes from skb->data
+* |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
+* |                       | | |
+* |,-Dest.--. ,--Src.---. | | |
+* |  6 bytes| | 6 bytes | | | |
+* v         | |         | | | |
+* 0         | v       1 | v | v           2
+* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+*     ^     | ^         | ^ |
+*     |     | |         | | |
+*     |     | |         | `T' <---- 2 bytes for Type
+*     |     | |         |
+*     |     | '---SNAP--' <-------- 6 bytes for SNAP
+*     |     |
+*     `-IV--' <-------------------- 4 bytes for IV (WEP)
+*
+*      SNAP HEADER
+*
+*/
+
+static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
+static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
+
+static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
+{
+	struct ieee80211_snap_hdr *snap;
+	u8 *oui;
+
+	snap = (struct ieee80211_snap_hdr *)data;
+	snap->dsap = 0xaa;
+	snap->ssap = 0xaa;
+	snap->ctrl = 0x03;
+
+	if (h_proto == 0x8137 || h_proto == 0x80f3)
+		oui = P802_1H_OUI;
+	else
+		oui = RFC1042_OUI;
+	snap->oui[0] = oui[0];
+	snap->oui[1] = oui[1];
+	snap->oui[2] = oui[2];
+
+	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
+
+	return SNAP_SIZE + sizeof(u16);
+}
+
+int ieee80211_encrypt_fragment(
+	struct ieee80211_device *ieee,
+	struct sk_buff *frag,
+	int hdr_len)
+{
+	struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
+	int res;
+
+	if (!(crypt && crypt->ops))
+	{
+		printk("=========>%s(), crypt is null\n", __FUNCTION__);
+		return -1;
+	}
+#ifdef CONFIG_IEEE80211_CRYPT_TKIP
+	struct ieee80211_hdr *header;
+
+	if (ieee->tkip_countermeasures &&
+	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
+		header = (struct ieee80211_hdr *) frag->data;
+		if (net_ratelimit()) {
+			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
+			       "TX packet to " MAC_FMT "\n",
+			       ieee->dev->name, MAC_ARG(header->addr1));
+		}
+		return -1;
+	}
+#endif
+	/* To encrypt, frame format is:
+	 * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
+
+	// PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
+	/* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
+	 * call both MSDU and MPDU encryption functions from here. */
+	atomic_inc(&crypt->refcnt);
+	res = 0;
+	if (crypt->ops->encrypt_msdu)
+		res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
+	if (res == 0 && crypt->ops->encrypt_mpdu)
+		res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
+
+	atomic_dec(&crypt->refcnt);
+	if (res < 0) {
+		printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
+		       ieee->dev->name, frag->len);
+		ieee->ieee_stats.tx_discards++;
+		return -1;
+	}
+
+	return 0;
+}
+
+
+void ieee80211_txb_free(struct ieee80211_txb *txb) {
+	//int i;
+	if (unlikely(!txb))
+		return;
+#if 0
+	for (i = 0; i < txb->nr_frags; i++)
+		if (txb->fragments[i])
+			dev_kfree_skb_any(txb->fragments[i]);
+#endif
+	kfree(txb);
+}
+
+struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
+					  int gfp_mask)
+{
+	struct ieee80211_txb *txb;
+	int i;
+	txb = kmalloc(
+		sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
+		gfp_mask);
+	if (!txb)
+		return NULL;
+
+	memset(txb, 0, sizeof(struct ieee80211_txb));
+	txb->nr_frags = nr_frags;
+	txb->frag_size = txb_size;
+
+	for (i = 0; i < nr_frags; i++) {
+		txb->fragments[i] = dev_alloc_skb(txb_size);
+		if (unlikely(!txb->fragments[i])) {
+			i--;
+			break;
+		}
+		memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb));
+	}
+	if (unlikely(i != nr_frags)) {
+		while (i >= 0)
+			dev_kfree_skb_any(txb->fragments[i--]);
+		kfree(txb);
+		return NULL;
+	}
+	return txb;
+}
+
+// Classify the to-be send data packet
+// Need to acquire the sent queue index.
+static int
+ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
+{
+	struct ethhdr *eth;
+	struct iphdr *ip;
+	eth = (struct ethhdr *)skb->data;
+	if (eth->h_proto != htons(ETH_P_IP))
+		return 0;
+
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+	ip = ip_hdr(skb);
+#else
+	ip = (struct iphdr*)(skb->data + sizeof(struct ether_header));
+#endif
+	switch (ip->tos & 0xfc) {
+		case 0x20:
+			return 2;
+		case 0x40:
+			return 1;
+		case 0x60:
+			return 3;
+		case 0x80:
+			return 4;
+		case 0xa0:
+			return 5;
+		case 0xc0:
+			return 6;
+		case 0xe0:
+			return 7;
+		default:
+			return 0;
+	}
+}
+
+#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
+void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PTX_TS_RECORD			pTxTs = NULL;
+	struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data;
+
+	if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+	if (!IsQoSDataFrame(skb->data))
+		return;
+
+	if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1))
+		return;
+	//check packet and mode later
+#ifdef TO_DO_LIST
+	if(pTcb->PacketLength >= 4096)
+		return;
+	// For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation.
+	if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter))
+		return;
+#endif
+#if 1
+	if(!ieee->GetNmodeSupportBySecCfg(ieee->dev))
+	{
+		return;
+	}
+#endif
+	if(pHTInfo->bCurrentAMPDUEnable)
+	{
+		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true))
+		{
+			printk("===>can't get TS\n");
+			return;
+		}
+		if (pTxTs->TxAdmittedBARecord.bValid == false)
+		{
+			//as some AP will refuse our action frame until key handshake has been finished. WB
+			if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA))
+			;
+			else
+			TsStartAddBaProcess(ieee, pTxTs);
+			goto FORCED_AGG_SETTING;
+		}
+		else if (pTxTs->bUsingBa == false)
+		{
+			if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096))
+				pTxTs->bUsingBa = true;
+			else
+				goto FORCED_AGG_SETTING;
+		}
+
+		if (ieee->iw_mode == IW_MODE_INFRA)
+		{
+			tcb_desc->bAMPDUEnable = true;
+			tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor;
+			tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity;
+		}
+	}
+FORCED_AGG_SETTING:
+	switch(pHTInfo->ForcedAMPDUMode )
+	{
+		case HT_AGG_AUTO:
+			break;
+
+		case HT_AGG_FORCE_ENABLE:
+			tcb_desc->bAMPDUEnable = true;
+			tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity;
+			tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor;
+			break;
+
+		case HT_AGG_FORCE_DISABLE:
+			tcb_desc->bAMPDUEnable = false;
+			tcb_desc->ampdu_density = 0;
+			tcb_desc->ampdu_factor = 0;
+			break;
+
+	}
+		return;
+}
+
+extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
+{
+	tcb_desc->bUseShortPreamble = false;
+	if (tcb_desc->data_rate == 2)
+	{//// 1M can only use Long Preamble. 11B spec
+		return;
+	}
+	else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+	{
+		tcb_desc->bUseShortPreamble = true;
+	}
+	return;
+}
+extern	void
+ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
+
+	tcb_desc->bUseShortGI 		= false;
+
+	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+
+	if(pHTInfo->bForcedShortGI)
+	{
+		tcb_desc->bUseShortGI = true;
+		return;
+	}
+
+	if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz)
+		tcb_desc->bUseShortGI = true;
+	else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz)
+		tcb_desc->bUseShortGI = true;
+}
+
+void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+
+	tcb_desc->bPacketBW = false;
+
+	if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT)
+		return;
+
+	if(tcb_desc->bMulticast || tcb_desc->bBroadcast)
+		return;
+
+	if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel.
+		return;
+	//BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance
+	if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz)
+		tcb_desc->bPacketBW = true;
+	return;
+}
+
+void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb)
+{
+	// Common Settings
+	tcb_desc->bRTSSTBC			= false;
+	tcb_desc->bRTSUseShortGI		= false; // Since protection frames are always sent by legacy rate, ShortGI will never be used.
+	tcb_desc->bCTSEnable			= false; // Most of protection using RTS/CTS
+	tcb_desc->RTSSC				= 0;		// 20MHz: Don't care;  40MHz: Duplicate.
+	tcb_desc->bRTSBW			= false; // RTS frame bandwidth is always 20MHz
+
+	if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts
+		return;
+
+	if (is_broadcast_ether_addr(skb->data+16))  //check addr3 as infrastructure add3 is DA.
+		return;
+
+	if (ieee->mode < IEEE_N_24G) //b, g mode
+	{
+			// (1) RTS_Threshold is compared to the MPDU, not MSDU.
+			// (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame.
+			//		Other fragments are protected by previous fragment.
+			//		So we only need to check the length of first fragment.
+		if (skb->len > ieee->rts)
+		{
+			tcb_desc->bRTSEnable = true;
+			tcb_desc->rts_rate = MGN_24M;
+		}
+		else if (ieee->current_network.buseprotection)
+		{
+			// Use CTS-to-SELF in protection mode.
+			tcb_desc->bRTSEnable = true;
+			tcb_desc->bCTSEnable = true;
+			tcb_desc->rts_rate = MGN_24M;
+		}
+		//otherwise return;
+		return;
+	}
+	else
+	{// 11n High throughput case.
+		PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+		while (true)
+		{
+			//check ERP protection
+			if (ieee->current_network.buseprotection)
+			{// CTS-to-SELF
+				tcb_desc->bRTSEnable = true;
+				tcb_desc->bCTSEnable = true;
+				tcb_desc->rts_rate = MGN_24M;
+				break;
+			}
+			//check HT op mode
+			if(pHTInfo->bCurrentHTSupport  && pHTInfo->bEnableHT)
+			{
+				u8 HTOpMode = pHTInfo->CurrentOpMode;
+				if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) ||
+							(!pHTInfo->bCurBW40MHz && HTOpMode == 3) )
+				{
+					tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+					tcb_desc->bRTSEnable = true;
+					break;
+				}
+			}
+			//check rts
+			if (skb->len > ieee->rts)
+			{
+				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+				tcb_desc->bRTSEnable = true;
+				break;
+			}
+			//to do list: check MIMO power save condition.
+			//check AMPDU aggregation for TXOP
+			if(tcb_desc->bAMPDUEnable)
+			{
+				tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps.
+				// According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads
+				// throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily
+				tcb_desc->bRTSEnable = false;
+				break;
+			}
+			//check IOT action
+			if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF)
+			{
+				tcb_desc->bCTSEnable	= true;
+				tcb_desc->rts_rate  = 	MGN_24M;
+				tcb_desc->bRTSEnable = true;
+				break;
+			}
+			// Totally no protection case!!
+			goto NO_PROTECTION;
+		}
+		}
+	// For test , CTS replace with RTS
+	if( 0 )
+	{
+		tcb_desc->bCTSEnable	= true;
+		tcb_desc->rts_rate = MGN_24M;
+		tcb_desc->bRTSEnable 	= true;
+	}
+	if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+		tcb_desc->bUseShortPreamble = true;
+	if (ieee->mode == IW_MODE_MASTER)
+			goto NO_PROTECTION;
+	return;
+NO_PROTECTION:
+	tcb_desc->bRTSEnable	= false;
+	tcb_desc->bCTSEnable	= false;
+	tcb_desc->rts_rate		= 0;
+	tcb_desc->RTSSC		= 0;
+	tcb_desc->bRTSBW		= false;
+}
+
+
+void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc)
+{
+#ifdef TO_DO_LIST
+	if(!IsDataFrame(pFrame))
+	{
+		pTcb->bTxDisableRateFallBack = TRUE;
+		pTcb->bTxUseDriverAssingedRate = TRUE;
+		pTcb->RATRIndex = 7;
+		return;
+	}
+
+	if(pMgntInfo->ForcedDataRate!= 0)
+	{
+		pTcb->bTxDisableRateFallBack = TRUE;
+		pTcb->bTxUseDriverAssingedRate = TRUE;
+		return;
+	}
+#endif
+	if(ieee->bTxDisableRateFallBack)
+		tcb_desc->bTxDisableRateFallBack = true;
+
+	if(ieee->bTxUseDriverAssingedRate)
+		tcb_desc->bTxUseDriverAssingedRate = true;
+	if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate)
+	{
+		if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
+			tcb_desc->RATRIndex = 0;
+	}
+}
+
+void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst)
+{
+	if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst))
+		return;
+	if (IsQoSDataFrame(skb->data)) //we deal qos data only
+	{
+		PTX_TS_RECORD pTS = NULL;
+		if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true))
+		{
+			return;
+		}
+		pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096;
+	}
+}
+
+int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+	struct ieee80211_device *ieee = netdev_priv(dev);
+#else
+	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
+#endif
+	struct ieee80211_txb *txb = NULL;
+	struct ieee80211_hdr_3addrqos *frag_hdr;
+	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
+	unsigned long flags;
+	struct net_device_stats *stats = &ieee->stats;
+	int ether_type = 0, encrypt;
+	int bytes, fc, qos_ctl = 0, hdr_len;
+	struct sk_buff *skb_frag;
+	struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
+		.duration_id = 0,
+		.seq_ctl = 0,
+		.qos_ctl = 0
+	};
+	u8 dest[ETH_ALEN], src[ETH_ALEN];
+	int qos_actived = ieee->current_network.qos_data.active;
+
+	struct ieee80211_crypt_data* crypt;
+
+	cb_desc *tcb_desc;
+
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	/* If there is no driver handler to take the TXB, dont' bother
+	 * creating it... */
+	if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
+	   ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
+		printk(KERN_WARNING "%s: No xmit handler.\n",
+		       ieee->dev->name);
+		goto success;
+	}
+
+
+	if(likely(ieee->raw_tx == 0)){
+		if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
+			printk(KERN_WARNING "%s: skb too small (%d).\n",
+			ieee->dev->name, skb->len);
+			goto success;
+		}
+
+		memset(skb->cb, 0, sizeof(skb->cb));
+		ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
+
+		crypt = ieee->crypt[ieee->tx_keyidx];
+
+		encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
+			ieee->host_encrypt && crypt && crypt->ops;
+
+		if (!encrypt && ieee->ieee802_1x &&
+		ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
+			stats->tx_dropped++;
+			goto success;
+		}
+	#ifdef CONFIG_IEEE80211_DEBUG
+		if (crypt && !encrypt && ether_type == ETH_P_PAE) {
+			struct eapol *eap = (struct eapol *)(skb->data +
+				sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
+			IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
+				eap_get_type(eap->type));
+		}
+	#endif
+
+		/* Save source and destination addresses */
+		memcpy(&dest, skb->data, ETH_ALEN);
+		memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
+
+                /* Advance the SKB to the start of the payload */
+                skb_pull(skb, sizeof(struct ethhdr));
+
+                /* Determine total amount of storage required for TXB packets */
+                bytes = skb->len + SNAP_SIZE + sizeof(u16);
+
+		if (encrypt)
+			fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP;
+		else
+
+                        fc = IEEE80211_FTYPE_DATA;
+
+		//if(ieee->current_network.QoS_Enable)
+		if(qos_actived)
+			fc |= IEEE80211_STYPE_QOS_DATA;
+		else
+			fc |= IEEE80211_STYPE_DATA;
+
+		if (ieee->iw_mode == IW_MODE_INFRA) {
+			fc |= IEEE80211_FCTL_TODS;
+			/* To DS: Addr1 = BSSID, Addr2 = SA,
+			Addr3 = DA */
+			memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
+			memcpy(&header.addr2, &src, ETH_ALEN);
+			memcpy(&header.addr3, &dest, ETH_ALEN);
+		} else if (ieee->iw_mode == IW_MODE_ADHOC) {
+			/* not From/To DS: Addr1 = DA, Addr2 = SA,
+			Addr3 = BSSID */
+			memcpy(&header.addr1, dest, ETH_ALEN);
+			memcpy(&header.addr2, src, ETH_ALEN);
+			memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
+		}
+
+                header.frame_ctl = cpu_to_le16(fc);
+
+		/* Determine fragmentation size based on destination (multicast
+		* and broadcast are not fragmented) */
+		if (is_multicast_ether_addr(header.addr1) ||
+		is_broadcast_ether_addr(header.addr1)) {
+			frag_size = MAX_FRAG_THRESHOLD;
+			qos_ctl |= QOS_CTL_NOTCONTAIN_ACK;
+		}
+		else {
+			frag_size = ieee->fts;//default:392
+			qos_ctl = 0;
+		}
+
+		//if (ieee->current_network.QoS_Enable)
+		if(qos_actived)
+		{
+			hdr_len = IEEE80211_3ADDR_LEN + 2;
+
+			skb->priority = ieee80211_classify(skb, &ieee->current_network);
+			qos_ctl |= skb->priority; //set in the ieee80211_classify
+			header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID);
+		} else {
+			hdr_len = IEEE80211_3ADDR_LEN;
+		}
+		/* Determine amount of payload per fragment.  Regardless of if
+		* this stack is providing the full 802.11 header, one will
+		* eventually be affixed to this fragment -- so we must account for
+		* it when determining the amount of payload space. */
+		bytes_per_frag = frag_size - hdr_len;
+		if (ieee->config &
+		(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+			bytes_per_frag -= IEEE80211_FCS_LEN;
+
+		/* Each fragment may need to have room for encryptiong pre/postfix */
+		if (encrypt)
+			bytes_per_frag -= crypt->ops->extra_prefix_len +
+				crypt->ops->extra_postfix_len;
+
+		/* Number of fragments is the total bytes_per_frag /
+		* payload_per_fragment */
+		nr_frags = bytes / bytes_per_frag;
+		bytes_last_frag = bytes % bytes_per_frag;
+		if (bytes_last_frag)
+			nr_frags++;
+		else
+			bytes_last_frag = bytes_per_frag;
+
+		/* When we allocate the TXB we allocate enough space for the reserve
+		* and full fragment bytes (bytes_per_frag doesn't include prefix,
+		* postfix, header, FCS, etc.) */
+		txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC);
+		if (unlikely(!txb)) {
+			printk(KERN_WARNING "%s: Could not allocate TXB\n",
+			ieee->dev->name);
+			goto failed;
+		}
+		txb->encrypted = encrypt;
+		txb->payload_size = bytes;
+
+		//if (ieee->current_network.QoS_Enable)
+		if(qos_actived)
+		{
+			txb->queue_index = UP2AC(skb->priority);
+		} else {
+			txb->queue_index = WME_AC_BK;;
+		}
+
+
+
+		for (i = 0; i < nr_frags; i++) {
+			skb_frag = txb->fragments[i];
+			tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE);
+			if(qos_actived){
+				skb_frag->priority = skb->priority;//UP2AC(skb->priority);
+				tcb_desc->queue_index =  UP2AC(skb->priority);
+			} else {
+				skb_frag->priority = WME_AC_BK;
+				tcb_desc->queue_index = WME_AC_BK;
+			}
+			skb_reserve(skb_frag, ieee->tx_headroom);
+
+			if (encrypt){
+				if (ieee->hwsec_active)
+					tcb_desc->bHwSec = 1;
+				else
+					tcb_desc->bHwSec = 0;
+				skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
+			}
+			else
+			{
+				tcb_desc->bHwSec = 0;
+			}
+			frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len);
+			memcpy(frag_hdr, &header, hdr_len);
+
+			/* If this is not the last fragment, then add the MOREFRAGS
+			* bit to the frame control */
+			if (i != nr_frags - 1) {
+				frag_hdr->frame_ctl = cpu_to_le16(
+					fc | IEEE80211_FCTL_MOREFRAGS);
+				bytes = bytes_per_frag;
+
+			} else {
+				/* The last fragment takes the remaining length */
+				bytes = bytes_last_frag;
+			}
+			//if(ieee->current_network.QoS_Enable)
+			if(qos_actived)
+			{
+				// add 1 only indicate to corresponding seq number control 2006/7/12
+				frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
+			} else {
+				frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
+			}
+
+			/* Put a SNAP header on the first fragment */
+			if (i == 0) {
+				ieee80211_put_snap(
+					skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
+					ether_type);
+				bytes -= SNAP_SIZE + sizeof(u16);
+			}
+
+			memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
+
+			/* Advance the SKB... */
+			skb_pull(skb, bytes);
+
+			/* Encryption routine will move the header forward in order
+			* to insert the IV between the header and the payload */
+			if (encrypt)
+				ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
+			if (ieee->config &
+			(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
+				skb_put(skb_frag, 4);
+		}
+
+		if(qos_actived)
+		{
+		  if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
+			ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
+		  else
+			ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
+		} else {
+  		  if (ieee->seq_ctrl[0] == 0xFFF)
+			ieee->seq_ctrl[0] = 0;
+		  else
+			ieee->seq_ctrl[0]++;
+		}
+	}else{
+		if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
+			printk(KERN_WARNING "%s: skb too small (%d).\n",
+			ieee->dev->name, skb->len);
+			goto success;
+		}
+
+		txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
+		if(!txb){
+			printk(KERN_WARNING "%s: Could not allocate TXB\n",
+			ieee->dev->name);
+			goto failed;
+		}
+
+		txb->encrypted = 0;
+		txb->payload_size = skb->len;
+		memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
+	}
+
+ success:
+//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place.
+	if (txb)
+	{
+#if 1
+		cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
+		tcb_desc->bTxEnableFwCalcDur = 1;
+		if (is_multicast_ether_addr(header.addr1))
+			tcb_desc->bMulticast = 1;
+		if (is_broadcast_ether_addr(header.addr1))
+			tcb_desc->bBroadcast = 1;
+		ieee80211_txrate_selectmode(ieee, tcb_desc);
+		if ( tcb_desc->bMulticast ||  tcb_desc->bBroadcast)
+			tcb_desc->data_rate = ieee->basic_rate;
+		else
+			//tcb_desc->data_rate = CURRENT_RATE(ieee->current_network.mode, ieee->rate, ieee->HTCurrentOperaRate);
+			tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate);
+		ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc);
+		ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc);
+		ieee80211_query_HTCapShortGI(ieee, tcb_desc);
+		ieee80211_query_BandwidthMode(ieee, tcb_desc);
+		ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]);
+		ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1);
+//		IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, txb->fragments[0]->data, txb->fragments[0]->len);
+		//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, tcb_desc, sizeof(cb_desc));
+#endif
+	}
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	dev_kfree_skb_any(skb);
+	if (txb) {
+		if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
+			ieee80211_softmac_xmit(txb, ieee);
+		}else{
+			if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
+				stats->tx_packets++;
+				stats->tx_bytes += txb->payload_size;
+				return 0;
+			}
+			ieee80211_txb_free(txb);
+		}
+	}
+
+	return 0;
+
+ failed:
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	netif_stop_queue(dev);
+	stats->tx_errors++;
+	return 1;
+
+}
+
+//EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
new file mode 100644
index 0000000..2234831
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c
@@ -0,0 +1,1032 @@
+/******************************************************************************
+
+  Copyright(c) 2004 Intel Corporation. All rights reserved.
+
+  Portions of this file are based on the WEP enablement code provided by the
+  Host AP project hostap-drivers v0.1.3
+  Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+  <jkmaline@cc.hut.fi>
+  Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful, but WITHOUT
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 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.
+
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+
+  Contact Information:
+  James P. Ketrenos <ipw2100-admin@linux.intel.com>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+******************************************************************************/
+#include <linux/wireless.h>
+#include <linux/version.h>
+#include <linux/kmod.h>
+#include <linux/module.h>
+
+#include "ieee80211.h"
+#if 0
+static const char *ieee80211_modes[] = {
+	"?", "a", "b", "ab", "g", "ag", "bg", "abg"
+};
+#endif
+struct modes_unit {
+	char *mode_string;
+	int mode_size;
+};
+struct modes_unit ieee80211_modes[] = {
+	{"a",1},
+	{"b",1},
+	{"g",1},
+	{"?",1},
+	{"N-24G",5},
+	{"N-5G",4},
+};
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static inline char *
+iwe_stream_add_event_rsl(char *     stream,         /* Stream of events */
+                     char *     ends,           /* End of stream */
+                     struct iw_event *iwe,      /* Payload */
+                     int        event_len)      /* Real size of payload */
+{
+        /* Check if it's possible */
+        if((stream + event_len) < ends) {
+                iwe->len = event_len;
+		ndelay(1);   //new
+                memcpy(stream, (char *) iwe, event_len);
+                stream += event_len;
+        }
+        return stream;
+}
+#else
+#define iwe_stream_add_event_rsl iwe_stream_add_event
+#endif
+
+#define MAX_CUSTOM_LEN 64
+static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
+ 					   char *start, char *stop,
+					   struct ieee80211_network *network,
+                                           struct iw_request_info *info)
+{
+	char custom[MAX_CUSTOM_LEN];
+	char proto_name[IFNAMSIZ];
+	char *pname = proto_name;
+	char *p;
+	struct iw_event iwe;
+	int i, j;
+	u16 max_rate, rate;
+	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};
+
+	/* 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, network->bssid, ETH_ALEN);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+	start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
+#else
+	start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_ADDR_LEN);
+#endif
+	/* Remaining entries will be displayed in the order we provide them */
+
+	/* Add the ESSID */
+	iwe.cmd = SIOCGIWESSID;
+	iwe.u.data.flags = 1;
+//	if (network->flags & NETWORK_EMPTY_ESSID) {
+	if (network->ssid_len == 0) {
+		iwe.u.data.length = sizeof("<hidden>");
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
+#endif
+        } else {
+		iwe.u.data.length = min(network->ssid_len, (u8)32);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+#endif
+        }
+	/* Add the protocol name */
+	iwe.cmd = SIOCGIWNAME;
+	for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) {
+		if(network->mode&(1<<i)) {
+			sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
+			pname +=ieee80211_modes[i].mode_size;
+		}
+	}
+	*pname = '\0';
+	snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
+#else
+        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_CHAR_LEN);
+#endif
+        /* Add mode */
+        iwe.cmd = SIOCGIWMODE;
+        if (network->capability &
+	    (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
+		if (network->capability & WLAN_CAPABILITY_BSS)
+			iwe.u.mode = IW_MODE_MASTER;
+		else
+			iwe.u.mode = IW_MODE_ADHOC;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
+#else
+                start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_UINT_LEN);
+#endif
+        }
+
+        /* Add frequency/channel */
+	iwe.cmd = SIOCGIWFREQ;
+/*	iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
+	iwe.u.freq.e = 3; */
+	iwe.u.freq.m = network->channel;
+	iwe.u.freq.e = 0;
+	iwe.u.freq.i = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
+#else
+        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_FREQ_LEN);
+#endif
+	/* Add encryption capability */
+	iwe.cmd = SIOCGIWENCODE;
+	if (network->capability & WLAN_CAPABILITY_PRIVACY)
+		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+	else
+		iwe.u.data.flags = IW_ENCODE_DISABLED;
+	iwe.u.data.length = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
+#else
+        start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+#endif
+	/* Add basic and extended rates */
+	max_rate = 0;
+	p = custom;
+	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
+	for (i = 0, j = 0; i < network->rates_len; ) {
+		if (j < network->rates_ex_len &&
+		    ((network->rates_ex[j] & 0x7F) <
+		     (network->rates[i] & 0x7F)))
+			rate = network->rates_ex[j++] & 0x7F;
+		else
+			rate = network->rates[i++] & 0x7F;
+		if (rate > max_rate)
+			max_rate = rate;
+		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
+			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
+	}
+	for (; j < network->rates_ex_len; j++) {
+		rate = network->rates_ex[j] & 0x7F;
+		p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
+			      "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
+		if (rate > max_rate)
+			max_rate = rate;
+	}
+
+	if (network->mode >= IEEE_N_24G)//add N rate here;
+	{
+		PHT_CAPABILITY_ELE ht_cap = NULL;
+		bool is40M = false, isShortGI = false;
+		u8 max_mcs = 0;
+		if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4))
+			ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4];
+		else
+			ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0];
+		is40M = (ht_cap->ChlWidth)?1:0;
+		isShortGI = (ht_cap->ChlWidth)?
+						((ht_cap->ShortGI40Mhz)?1:0):
+						((ht_cap->ShortGI20Mhz)?1:0);
+
+		max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL);
+		rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f];
+		if (rate > max_rate)
+			max_rate = rate;
+	}
+#if 0
+	printk("max rate:%d ===basic rate:\n", max_rate);
+	for (i=0;i<network->rates_len;i++)
+		printk(" %x", network->rates[i]);
+	printk("\n=======extend rate\n");
+	for (i=0; i<network->rates_ex_len; i++)
+		printk(" %x", network->rates_ex[i]);
+	printk("\n");
+#endif
+	iwe.cmd = SIOCGIWRATE;
+	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+	iwe.u.bitrate.value = max_rate * 500000;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
+				     IW_EV_PARAM_LEN);
+#else
+        start = iwe_stream_add_event_rsl(start, stop, &iwe,
+				     IW_EV_PARAM_LEN);
+#endif
+	iwe.cmd = IWEVCUSTOM;
+	iwe.u.data.length = p - custom;
+	if (iwe.u.data.length)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_point(info, start, stop, &iwe, custom);
+#else
+        start = iwe_stream_add_point(start, stop, &iwe, custom);
+#endif
+	/* Add quality statistics */
+	/* TODO: Fix these values... */
+	iwe.cmd = IWEVQUAL;
+	iwe.u.qual.qual = network->stats.signal;
+	iwe.u.qual.level = network->stats.rssi;
+	iwe.u.qual.noise = network->stats.noise;
+	iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
+	if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
+		iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
+	if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
+		iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
+	if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
+		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
+	iwe.u.qual.updated = 7;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+        start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
+#else
+        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_QUAL_LEN);
+#endif
+	iwe.cmd = IWEVCUSTOM;
+	p = custom;
+
+	iwe.u.data.length = p - custom;
+	if (iwe.u.data.length)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+            start = iwe_stream_add_point(info, start, stop, &iwe, custom);
+#else
+            start = iwe_stream_add_point(start, stop, &iwe, custom);
+#endif
+#if (WIRELESS_EXT < 18)
+	if (ieee->wpa_enabled && network->wpa_ie_len){
+		char buf[MAX_WPA_IE_LEN * 2 + 30];
+	//	printk("WPA IE\n");
+		u8 *p = buf;
+		p += sprintf(p, "wpa_ie=");
+		for (i = 0; i < network->wpa_ie_len; i++) {
+			p += sprintf(p, "%02x", network->wpa_ie[i]);
+		}
+
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVCUSTOM;
+		iwe.u.data.length = strlen(buf);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, buf);
+#endif
+        }
+
+	if (ieee->wpa_enabled && network->rsn_ie_len){
+		char buf[MAX_WPA_IE_LEN * 2 + 30];
+
+		u8 *p = buf;
+		p += sprintf(p, "rsn_ie=");
+		for (i = 0; i < network->rsn_ie_len; i++) {
+			p += sprintf(p, "%02x", network->rsn_ie[i]);
+		}
+
+		memset(&iwe, 0, sizeof(iwe));
+		iwe.cmd = IWEVCUSTOM;
+		iwe.u.data.length = strlen(buf);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, buf);
+#endif
+        }
+#else
+	memset(&iwe, 0, sizeof(iwe));
+	if (network->wpa_ie_len)
+	{
+		char buf[MAX_WPA_IE_LEN];
+		memcpy(buf, network->wpa_ie, network->wpa_ie_len);
+		iwe.cmd = IWEVGENIE;
+		iwe.u.data.length = network->wpa_ie_len;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, buf);
+#endif
+        }
+	memset(&iwe, 0, sizeof(iwe));
+	if (network->rsn_ie_len)
+	{
+		char buf[MAX_WPA_IE_LEN];
+		memcpy(buf, network->rsn_ie, network->rsn_ie_len);
+		iwe.cmd = IWEVGENIE;
+		iwe.u.data.length = network->rsn_ie_len;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
+#else
+                start = iwe_stream_add_point(start, stop, &iwe, buf);
+#endif
+        }
+#endif
+
+
+	/* Add EXTRA: Age to display seconds since last beacon/probe response
+	 * for given network. */
+	iwe.cmd = IWEVCUSTOM;
+	p = custom;
+	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
+		      " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
+	iwe.u.data.length = p - custom;
+	if (iwe.u.data.length)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+            start = iwe_stream_add_point(info, start, stop, &iwe, custom);
+#else
+            start = iwe_stream_add_point(start, stop, &iwe, custom);
+#endif
+
+	return start;
+}
+
+int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
+			  struct iw_request_info *info,
+			  union iwreq_data *wrqu, char *extra)
+{
+	struct ieee80211_network *network;
+	unsigned long flags;
+
+	char *ev = extra;
+//	char *stop = ev + IW_SCAN_MAX_DATA;
+	char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
+	//char *stop = ev + IW_SCAN_MAX_DATA;
+	int i = 0;
+	int err = 0;
+	IEEE80211_DEBUG_WX("Getting scan\n");
+	down(&ieee->wx_sem);
+	spin_lock_irqsave(&ieee->lock, flags);
+
+	list_for_each_entry(network, &ieee->network_list, list) {
+		i++;
+		if((stop-ev)<200)
+		{
+			err = -E2BIG;
+			break;
+												}
+		if (ieee->scan_age == 0 ||
+		    time_after(network->last_scanned + ieee->scan_age, jiffies))
+			ev = rtl819x_translate_scan(ieee, ev, stop, network, info);
+		else
+			IEEE80211_DEBUG_SCAN(
+				"Not showing network '%s ("
+				MAC_FMT ")' due to age (%lums).\n",
+				escape_essid(network->ssid,
+					     network->ssid_len),
+				MAC_ARG(network->bssid),
+				(jiffies - network->last_scanned) / (HZ / 100));
+	}
+
+	spin_unlock_irqrestore(&ieee->lock, flags);
+	up(&ieee->wx_sem);
+	wrqu->data.length = ev -  extra;
+	wrqu->data.flags = 0;
+
+	IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
+
+	return err;
+}
+
+int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *keybuf)
+{
+	struct iw_point *erq = &(wrqu->encoding);
+	struct net_device *dev = ieee->dev;
+	struct ieee80211_security sec = {
+		.flags = 0
+	};
+	int i, key, key_provided, len;
+	struct ieee80211_crypt_data **crypt;
+
+	IEEE80211_DEBUG_WX("SET_ENCODE\n");
+
+	key = erq->flags & IW_ENCODE_INDEX;
+	if (key) {
+		if (key > WEP_KEYS)
+			return -EINVAL;
+		key--;
+		key_provided = 1;
+	} else {
+		key_provided = 0;
+		key = ieee->tx_keyidx;
+	}
+
+	IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
+			   "provided" : "default");
+	crypt = &ieee->crypt[key];
+
+	if (erq->flags & IW_ENCODE_DISABLED) {
+		if (key_provided && *crypt) {
+			IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
+					   key);
+			ieee80211_crypt_delayed_deinit(ieee, crypt);
+		} else
+			IEEE80211_DEBUG_WX("Disabling encryption.\n");
+
+		/* Check all the keys to see if any are still configured,
+		 * and if no key index was provided, de-init them all */
+		for (i = 0; i < WEP_KEYS; i++) {
+			if (ieee->crypt[i] != NULL) {
+				if (key_provided)
+					break;
+				ieee80211_crypt_delayed_deinit(
+					ieee, &ieee->crypt[i]);
+			}
+		}
+
+		if (i == WEP_KEYS) {
+			sec.enabled = 0;
+			sec.level = SEC_LEVEL_0;
+			sec.flags |= SEC_ENABLED | SEC_LEVEL;
+		}
+
+		goto done;
+	}
+
+
+
+	sec.enabled = 1;
+	sec.flags |= SEC_ENABLED;
+
+	if (*crypt != NULL && (*crypt)->ops != NULL &&
+	    strcmp((*crypt)->ops->name, "WEP") != 0) {
+		/* changing to use WEP; deinit previously used algorithm
+		 * on this key */
+		ieee80211_crypt_delayed_deinit(ieee, crypt);
+	}
+
+	if (*crypt == NULL) {
+		struct ieee80211_crypt_data *new_crypt;
+
+		/* take WEP into use */
+		new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
+				    GFP_KERNEL);
+		if (new_crypt == NULL)
+			return -ENOMEM;
+		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
+		new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+		if (!new_crypt->ops) {
+			request_module("ieee80211_crypt_wep");
+			new_crypt->ops = ieee80211_get_crypto_ops("WEP");
+		}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+#else
+		if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
+#endif
+			new_crypt->priv = new_crypt->ops->init(key);
+
+		if (!new_crypt->ops || !new_crypt->priv) {
+			kfree(new_crypt);
+			new_crypt = NULL;
+
+			printk(KERN_WARNING "%s: could not initialize WEP: "
+			       "load module ieee80211_crypt_wep\n",
+			       dev->name);
+			return -EOPNOTSUPP;
+		}
+		*crypt = new_crypt;
+	}
+
+	/* If a new key was provided, set it up */
+	if (erq->length > 0) {
+		len = erq->length <= 5 ? 5 : 13;
+		memcpy(sec.keys[key], keybuf, erq->length);
+		if (len > erq->length)
+			memset(sec.keys[key] + erq->length, 0,
+			       len - erq->length);
+		IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
+				   key, escape_essid(sec.keys[key], len),
+				   erq->length, len);
+		sec.key_sizes[key] = len;
+ 		(*crypt)->ops->set_key(sec.keys[key], len, NULL,
+				       (*crypt)->priv);
+		sec.flags |= (1 << key);
+		/* This ensures a key will be activated if no key is
+		 * explicitely set */
+		if (key == sec.active_key)
+			sec.flags |= SEC_ACTIVE_KEY;
+		ieee->tx_keyidx = key;
+
+	} else {
+		len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
+					     NULL, (*crypt)->priv);
+		if (len == 0) {
+			/* Set a default key of all 0 */
+			printk("Setting key %d to all zero.\n",
+					   key);
+
+			IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
+					   key);
+			memset(sec.keys[key], 0, 13);
+			(*crypt)->ops->set_key(sec.keys[key], 13, NULL,
+					       (*crypt)->priv);
+			sec.key_sizes[key] = 13;
+			sec.flags |= (1 << key);
+		}
+
+		/* No key data - just set the default TX key index */
+		if (key_provided) {
+			IEEE80211_DEBUG_WX(
+				"Setting key %d to default Tx key.\n", key);
+			ieee->tx_keyidx = key;
+			sec.active_key = key;
+			sec.flags |= SEC_ACTIVE_KEY;
+		}
+	}
+
+ done:
+	ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
+	ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
+	sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
+	sec.flags |= SEC_AUTH_MODE;
+	IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
+			   "OPEN" : "SHARED KEY");
+
+	/* For now we just support WEP, so only set that security level...
+	 * TODO: When WPA is added this is one place that needs to change */
+	sec.flags |= SEC_LEVEL;
+	sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
+
+	if (ieee->set_security)
+		ieee->set_security(dev, &sec);
+
+	/* Do not reset port if card is in Managed mode since resetting will
+	 * generate new IEEE 802.11 authentication which may end up in looping
+	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
+	 * configuration (for example... Prism2), implement the reset_port in
+	 * the callbacks structures used to initialize the 802.11 stack. */
+	if (ieee->reset_on_keychange &&
+	    ieee->iw_mode != IW_MODE_INFRA &&
+	    ieee->reset_port && ieee->reset_port(dev)) {
+		printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *keybuf)
+{
+	struct iw_point *erq = &(wrqu->encoding);
+	int len, key;
+	struct ieee80211_crypt_data *crypt;
+
+	IEEE80211_DEBUG_WX("GET_ENCODE\n");
+
+	if(ieee->iw_mode == IW_MODE_MONITOR)
+		return -1;
+
+	key = erq->flags & IW_ENCODE_INDEX;
+	if (key) {
+		if (key > WEP_KEYS)
+			return -EINVAL;
+		key--;
+	} else
+		key = ieee->tx_keyidx;
+
+	crypt = ieee->crypt[key];
+	erq->flags = key + 1;
+
+	if (crypt == NULL || crypt->ops == NULL) {
+		erq->length = 0;
+		erq->flags |= IW_ENCODE_DISABLED;
+		return 0;
+	}
+#if 0
+	if (strcmp(crypt->ops->name, "WEP") != 0) {
+		/* only WEP is supported with wireless extensions, so just
+		 * report that encryption is used */
+		erq->length = 0;
+		erq->flags |= IW_ENCODE_ENABLED;
+		return 0;
+	}
+#endif
+	len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
+	erq->length = (len >= 0 ? len : 0);
+
+	erq->flags |= IW_ENCODE_ENABLED;
+
+	if (ieee->open_wep)
+		erq->flags |= IW_ENCODE_OPEN;
+	else
+		erq->flags |= IW_ENCODE_RESTRICTED;
+
+	return 0;
+}
+#if (WIRELESS_EXT >= 18)
+int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+	int ret = 0;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	struct net_device *dev = ieee->dev;
+        struct iw_point *encoding = &wrqu->encoding;
+        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+        int i, idx;
+        int group_key = 0;
+        const char *alg, *module;
+        struct ieee80211_crypto_ops *ops;
+        struct ieee80211_crypt_data **crypt;
+
+        struct ieee80211_security sec = {
+                .flags = 0,
+        };
+	//printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
+        idx = encoding->flags & IW_ENCODE_INDEX;
+        if (idx) {
+                if (idx < 1 || idx > WEP_KEYS)
+                        return -EINVAL;
+                idx--;
+        } else
+                idx = ieee->tx_keyidx;
+
+        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+
+                crypt = &ieee->crypt[idx];
+
+                group_key = 1;
+        } else {
+                /* some Cisco APs use idx>0 for unicast in dynamic WEP */
+		//printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
+                if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
+                        return -EINVAL;
+                if (ieee->iw_mode == IW_MODE_INFRA)
+
+                        crypt = &ieee->crypt[idx];
+
+                else
+                        return -EINVAL;
+        }
+
+        sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
+        if ((encoding->flags & IW_ENCODE_DISABLED) ||
+            ext->alg == IW_ENCODE_ALG_NONE) {
+                if (*crypt)
+                        ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+                for (i = 0; i < WEP_KEYS; i++)
+
+			if (ieee->crypt[i] != NULL)
+
+                                break;
+
+                if (i == WEP_KEYS) {
+                        sec.enabled = 0;
+                      //  sec.encrypt = 0;
+                        sec.level = SEC_LEVEL_0;
+                        sec.flags |= SEC_LEVEL;
+                }
+		//printk("disabled: flag:%x\n", encoding->flags);
+                goto done;
+        }
+
+	sec.enabled = 1;
+    //    sec.encrypt = 1;
+#if 0
+        if (group_key ? !ieee->host_mc_decrypt :
+            !(ieee->host_encrypt || ieee->host_decrypt ||
+              ieee->host_encrypt_msdu))
+                goto skip_host_crypt;
+#endif
+        switch (ext->alg) {
+        case IW_ENCODE_ALG_WEP:
+                alg = "WEP";
+                module = "ieee80211_crypt_wep";
+                break;
+        case IW_ENCODE_ALG_TKIP:
+                alg = "TKIP";
+                module = "ieee80211_crypt_tkip";
+                break;
+        case IW_ENCODE_ALG_CCMP:
+                alg = "CCMP";
+                module = "ieee80211_crypt_ccmp";
+                break;
+        default:
+                IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+                                   dev->name, ext->alg);
+                ret = -EINVAL;
+                goto done;
+        }
+	printk("alg name:%s\n",alg);
+
+	 ops = ieee80211_get_crypto_ops(alg);
+        if (ops == NULL) {
+                request_module(module);
+                ops = ieee80211_get_crypto_ops(alg);
+        }
+        if (ops == NULL) {
+                IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
+                                   dev->name, ext->alg);
+		printk("========>unknown crypto alg %d\n", ext->alg);
+                ret = -EINVAL;
+                goto done;
+        }
+
+        if (*crypt == NULL || (*crypt)->ops != ops) {
+                struct ieee80211_crypt_data *new_crypt;
+
+                ieee80211_crypt_delayed_deinit(ieee, crypt);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
+                new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
+#else
+                new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
+		memset(new_crypt,0,sizeof(*new_crypt));
+#endif
+                if (new_crypt == NULL) {
+                        ret = -ENOMEM;
+                        goto done;
+                }
+                new_crypt->ops = ops;
+                if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
+                        new_crypt->priv = new_crypt->ops->init(idx);
+                if (new_crypt->priv == NULL) {
+                        kfree(new_crypt);
+                        ret = -EINVAL;
+                        goto done;
+                }
+                *crypt = new_crypt;
+
+ 	}
+
+        if (ext->key_len > 0 && (*crypt)->ops->set_key &&
+            (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
+                                   (*crypt)->priv) < 0) {
+                IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
+		printk("key setting failed\n");
+                ret = -EINVAL;
+                goto done;
+        }
+#if 1
+ //skip_host_crypt:
+	//printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
+        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+                ieee->tx_keyidx = idx;
+                sec.active_key = idx;
+                sec.flags |= SEC_ACTIVE_KEY;
+        }
+
+        if (ext->alg != IW_ENCODE_ALG_NONE) {
+                //memcpy(sec.keys[idx], ext->key, ext->key_len);
+                sec.key_sizes[idx] = ext->key_len;
+                sec.flags |= (1 << idx);
+                if (ext->alg == IW_ENCODE_ALG_WEP) {
+                      //  sec.encode_alg[idx] = SEC_ALG_WEP;
+                        sec.flags |= SEC_LEVEL;
+                        sec.level = SEC_LEVEL_1;
+                } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
+                      //  sec.encode_alg[idx] = SEC_ALG_TKIP;
+                        sec.flags |= SEC_LEVEL;
+                        sec.level = SEC_LEVEL_2;
+                } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
+                       // sec.encode_alg[idx] = SEC_ALG_CCMP;
+                        sec.flags |= SEC_LEVEL;
+                        sec.level = SEC_LEVEL_3;
+                }
+                /* Don't set sec level for group keys. */
+                if (group_key)
+                        sec.flags &= ~SEC_LEVEL;
+        }
+#endif
+done:
+        if (ieee->set_security)
+                ieee->set_security(ieee->dev, &sec);
+
+	 if (ieee->reset_on_keychange &&
+            ieee->iw_mode != IW_MODE_INFRA &&
+            ieee->reset_port && ieee->reset_port(dev)) {
+                IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
+                return -EINVAL;
+        }
+#endif
+        return ret;
+}
+
+int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct iw_point *encoding = &wrqu->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	struct ieee80211_crypt_data *crypt;
+	int idx, max_key_len;
+
+	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 > WEP_KEYS)
+			return -EINVAL;
+		idx--;
+	} else
+		idx = ieee->tx_keyidx;
+
+	if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
+	    ext->alg != IW_ENCODE_ALG_WEP)
+		if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
+			return -EINVAL;
+
+	crypt = ieee->crypt[idx];
+	encoding->flags = idx + 1;
+	memset(ext, 0, sizeof(*ext));
+
+	if (crypt == NULL || crypt->ops == NULL ) {
+		ext->alg = IW_ENCODE_ALG_NONE;
+		ext->key_len = 0;
+		encoding->flags |= IW_ENCODE_DISABLED;
+	} else {
+		if (strcmp(crypt->ops->name, "WEP") == 0 )
+			ext->alg = IW_ENCODE_ALG_WEP;
+		else if (strcmp(crypt->ops->name, "TKIP"))
+			ext->alg = IW_ENCODE_ALG_TKIP;
+		else if (strcmp(crypt->ops->name, "CCMP"))
+			ext->alg = IW_ENCODE_ALG_CCMP;
+		else
+			return -EINVAL;
+		ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
+		encoding->flags |= IW_ENCODE_ENABLED;
+		if (ext->key_len &&
+		    (ext->alg == IW_ENCODE_ALG_TKIP ||
+		     ext->alg == IW_ENCODE_ALG_CCMP))
+			ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
+
+	}
+
+	return 0;
+}
+
+int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	struct iw_mlme *mlme = (struct iw_mlme *) extra;
+	switch (mlme->cmd) {
+        case IW_MLME_DEAUTH:
+	case IW_MLME_DISASSOC:
+		ieee80211_disassociate(ieee);
+		break;
+	 default:
+                return -EOPNOTSUPP;
+        }
+#endif
+	return 0;
+}
+
+int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
+                               struct iw_request_info *info,
+                               struct iw_param *data, char *extra)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+	switch (data->flags & IW_AUTH_INDEX) {
+        case IW_AUTH_WPA_VERSION:
+	     /*need to support wpa2 here*/
+		//printk("wpa version:%x\n", data->value);
+		break;
+        case IW_AUTH_CIPHER_PAIRWISE:
+        case IW_AUTH_CIPHER_GROUP:
+        case IW_AUTH_KEY_MGMT:
+                /*
+ *                  * Host AP driver does not use these parameters and allows
+ *                                   * wpa_supplicant to control them internally.
+ *                                                    */
+                break;
+        case IW_AUTH_TKIP_COUNTERMEASURES:
+                ieee->tkip_countermeasures = data->value;
+                break;
+        case IW_AUTH_DROP_UNENCRYPTED:
+                ieee->drop_unencrypted = data->value;
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		//printk("======>%s():data->value is %d\n",__FUNCTION__,data->value);
+	//	ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
+		if(data->value & IW_AUTH_ALG_SHARED_KEY){
+			ieee->open_wep = 0;
+			ieee->auth_mode = 1;
+		}
+		else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){
+			ieee->open_wep = 1;
+			ieee->auth_mode = 0;
+		}
+		else if(data->value & IW_AUTH_ALG_LEAP){
+			ieee->open_wep = 1;
+			ieee->auth_mode = 2;
+			//printk("hahahaa:LEAP\n");
+		}
+		else
+			return -EINVAL;
+		//printk("open_wep:%d\n", ieee->open_wep);
+		break;
+
+#if 1
+	case IW_AUTH_WPA_ENABLED:
+		ieee->wpa_enabled = (data->value)?1:0;
+		//printk("enalbe wpa:%d\n", ieee->wpa_enabled);
+		break;
+
+#endif
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+                ieee->ieee802_1x = data->value;
+		break;
+	case IW_AUTH_PRIVACY_INVOKED:
+		ieee->privacy_invoked = data->value;
+		break;
+	default:
+                return -EOPNOTSUPP;
+	}
+#endif
+	return 0;
+}
+#endif
+#if 1
+int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+#if 0
+	printk("====>%s()\n", __FUNCTION__);
+	{
+		int i;
+		for (i=0; i<len; i++)
+		printk("%2x ", ie[i]&0xff);
+		printk("\n");
+	}
+#endif
+	u8 *buf;
+
+	if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
+	{
+	//	printk("return error out, len:%d\n", len);
+	return -EINVAL;
+	}
+
+
+	if (len)
+	{
+		if (len != ie[1]+2)
+		{
+			printk("len:%d, ie:%d\n", len, ie[1]);
+			return -EINVAL;
+		}
+		buf = kmalloc(len, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+		memcpy(buf, ie, len);
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = buf;
+		ieee->wpa_ie_len = len;
+	}
+	else{
+		if (ieee->wpa_ie)
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = NULL;
+		ieee->wpa_ie_len = 0;
+	}
+#endif
+	return 0;
+
+}
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+//EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
+#if (WIRELESS_EXT >= 18)
+//EXPORT_SYMBOL(ieee80211_wx_set_mlme);
+//EXPORT_SYMBOL(ieee80211_wx_set_auth);
+//EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
+//EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
+#endif
+//EXPORT_SYMBOL(ieee80211_wx_get_scan);
+//EXPORT_SYMBOL(ieee80211_wx_set_encode);
+//EXPORT_SYMBOL(ieee80211_wx_get_encode);
+#else
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_gen_ie);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mlme);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_auth);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode_ext);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode);
+//EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode);
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h
new file mode 100644
index 0000000..8ddc8bf
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h
@@ -0,0 +1,69 @@
+#ifndef _BATYPE_H_
+#define _BATYPE_H_
+
+#define 	TOTAL_TXBA_NUM	16
+#define	TOTAL_RXBA_NUM	16
+
+#define	BA_SETUP_TIMEOUT	200
+#define	BA_INACT_TIMEOUT	60000
+
+#define	BA_POLICY_DELAYED		0
+#define	BA_POLICY_IMMEDIATE	1
+
+#define	ADDBA_STATUS_SUCCESS			0
+#define	ADDBA_STATUS_REFUSED		37
+#define	ADDBA_STATUS_INVALID_PARAM	38
+
+#define	DELBA_REASON_QSTA_LEAVING	36
+#define	DELBA_REASON_END_BA			37
+#define	DELBA_REASON_UNKNOWN_BA	38
+#define	DELBA_REASON_TIMEOUT			39
+/*  whether need define BA Action frames here?
+struct ieee80211_ADDBA_Req{
+	struct ieee80211_header_data header;
+	u8	category;
+	u8
+} __attribute__ ((packed));
+*/
+//Is this need?I put here just to make it easier to define structure BA_RECORD //WB
+typedef union _SEQUENCE_CONTROL{
+	u16 ShortData;
+	struct
+	{
+		u16	FragNum:4;
+		u16	SeqNum:12;
+	}field;
+}SEQUENCE_CONTROL, *PSEQUENCE_CONTROL;
+
+typedef union _BA_PARAM_SET {
+	u8 charData[2];
+	u16 shortData;
+	struct {
+		u16 AMSDU_Support:1;
+		u16 BAPolicy:1;
+		u16 TID:4;
+		u16 BufferSize:10;
+	} field;
+} BA_PARAM_SET, *PBA_PARAM_SET;
+
+typedef union _DELBA_PARAM_SET {
+	u8 charData[2];
+	u16 shortData;
+	struct {
+		u16 Reserved:11;
+		u16 Initiator:1;
+		u16 TID:4;
+	} field;
+} DELBA_PARAM_SET, *PDELBA_PARAM_SET;
+
+typedef struct _BA_RECORD {
+	struct timer_list		Timer;
+	u8				bValid;
+	u8				DialogToken;
+	BA_PARAM_SET		BaParamSet;
+	u16				BaTimeoutValue;
+	SEQUENCE_CONTROL	BaStartSeqCtrl;
+} BA_RECORD, *PBA_RECORD;
+
+#endif //end _BATYPE_H_
+
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
new file mode 100644
index 0000000..98b3bb6
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c
@@ -0,0 +1,779 @@
+/********************************************************************************************************************************
+ * This file is created to process BA Action Frame. According to 802.11 spec, there are 3 BA action types at all. And as BA is
+ * related to TS, this part need some struture defined in QOS side code. Also TX RX is going to be resturctured, so how to send
+ * ADDBAREQ ADDBARSP and DELBA packet is still on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue.
+ * WB 2008-05-27
+ * *****************************************************************************************************************************/
+#include "ieee80211.h"
+#include "rtl819x_BA.h"
+
+/********************************************************************************************************************
+ *function:  Activate BA entry. And if Time is nozero, start timer.
+ *   input:  PBA_RECORD 		pBA  //BA entry to be enabled
+ *   	     u16 			Time //indicate time delay.
+ *  output:  none
+********************************************************************************************************************/
+void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time)
+{
+	pBA->bValid = true;
+	if(Time != 0)
+		mod_timer(&pBA->Timer, jiffies + MSECS(Time));
+}
+
+/********************************************************************************************************************
+ *function:  deactivate BA entry, including its timer.
+ *   input:  PBA_RECORD 		pBA  //BA entry to be disabled
+ *  output:  none
+********************************************************************************************************************/
+void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA)
+{
+	pBA->bValid = false;
+	del_timer_sync(&pBA->Timer);
+}
+/********************************************************************************************************************
+ *function: deactivete BA entry in Tx Ts, and send DELBA.
+ *   input:
+ *   	     PTX_TS_RECORD		pTxTs //Tx Ts which is to deactivate BA entry.
+ *  output:  none
+ *  notice:  As PTX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME
+********************************************************************************************************************/
+u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD	pTxTs)
+{
+	PBA_RECORD		pAdmittedBa = &pTxTs->TxAdmittedBARecord;  //These two BA entries must exist in TS structure
+	PBA_RECORD		pPendingBa = &pTxTs->TxPendingBARecord;
+	u8			bSendDELBA = false;
+
+	// Delete pending BA
+	if(pPendingBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pPendingBa);
+		bSendDELBA = true;
+	}
+
+	// Delete admitted BA
+	if(pAdmittedBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pAdmittedBa);
+		bSendDELBA = true;
+	}
+
+	return bSendDELBA;
+}
+
+/********************************************************************************************************************
+ *function: deactivete BA entry in Tx Ts, and send DELBA.
+ *   input:
+ *   	     PRX_TS_RECORD		pRxTs //Rx Ts which is to deactivate BA entry.
+ *  output:  none
+ *  notice:  As PRX_TS_RECORD structure will be defined in QOS, so wait to be merged. //FIXME, same with above
+********************************************************************************************************************/
+u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD	pRxTs)
+{
+	PBA_RECORD		pBa = &pRxTs->RxAdmittedBARecord;
+	u8			bSendDELBA = false;
+
+	if(pBa->bValid)
+	{
+		DeActivateBAEntry(ieee, pBa);
+		bSendDELBA = true;
+	}
+
+	return bSendDELBA;
+}
+
+/********************************************************************************************************************
+ *function: reset BA entry
+ *   input:
+ *   	     PBA_RECORD		pBA //entry to be reset
+ *  output:  none
+********************************************************************************************************************/
+void ResetBaEntry( PBA_RECORD pBA)
+{
+	pBA->bValid			= false;
+	pBA->BaParamSet.shortData	= 0;
+	pBA->BaTimeoutValue		= 0;
+	pBA->DialogToken		= 0;
+	pBA->BaStartSeqCtrl.ShortData	= 0;
+}
+//These functions need porting here or not?
+/*******************************************************************************************************************************
+ *function:  construct ADDBAREQ and ADDBARSP frame here together.
+ *   input:  u8* 		Dst 	//ADDBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA.
+ *   	     u16 		StatusCode  //status code in RSP and I will use it to indicate whether it's RSP or REQ(will I?)
+ *   	     u8			type	//indicate whether it's RSP(ACT_ADDBARSP) ow REQ(ACT_ADDBAREQ)
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit
+*******************************************************************************************************************************/
+static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type)
+{
+	struct sk_buff *skb = NULL;
+	 struct ieee80211_hdr_3addr* BAReq = NULL;
+	u8* tag = NULL;
+	u16 tmp = 0;
+	u16 len = ieee->tx_headroom + 9;
+	//category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) +  BA Timeout Value(2) +  BA Start SeqCtrl(2)(or StatusCode(2))
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:"MAC_FMT", ieee->dev:%p\n", __FUNCTION__, type, MAC_ARG(Dst), ieee->dev);
+	if (pBA == NULL||ieee == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee);
+		return NULL;
+	}
+	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
+	if (skb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
+		return NULL;
+	}
+
+	memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr));  	//I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb.
+	skb_reserve(skb, ieee->tx_headroom);
+
+	BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
+
+	memcpy(BAReq->addr1, Dst, ETH_ALEN);
+	memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN);
+
+	memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN);
+
+	BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+
+	//tag += sizeof( struct ieee80211_hdr_3addr); //move to action field
+	tag = (u8*)skb_put(skb, 9);
+	*tag ++= ACT_CAT_BA;
+	*tag ++= type;
+	// Dialog Token
+	*tag ++= pBA->DialogToken;
+
+	if (ACT_ADDBARSP == type)
+	{
+		// Status Code
+		printk("=====>to send ADDBARSP\n");
+		tmp = cpu_to_le16(StatusCode);
+		memcpy(tag, (u8*)&tmp, 2);
+		tag += 2;
+	}
+	// BA Parameter Set
+	tmp = cpu_to_le16(pBA->BaParamSet.shortData);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+	// BA Timeout Value
+	tmp = cpu_to_le16(pBA->BaTimeoutValue);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+
+	if (ACT_ADDBAREQ == type)
+	{
+	// BA Start SeqCtrl
+		memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2);
+		tag += 2;
+	}
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	return skb;
+	//return NULL;
+}
+
+#if 0 //I try to merge ADDBA_REQ and ADDBA_RSP frames together..
+/********************************************************************************************************************
+ *function:  construct ADDBAREQ frame
+ *   input:  u8* 		dst 	//ADDBARsp frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA_RSP.
+ *   	     u16 		StatusCode  //status code.
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit
+********************************************************************************************************************/
+static struct sk_buff* ieee80211_ADDBA_Rsp( IN	struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
+{
+	OCTET_STRING	osADDBAFrame, tmp;
+
+	FillOctetString(osADDBAFrame, Buffer, 0);
+	*pLength = 0;
+
+	ConstructMaFrameHdr(
+					Adapter,
+					Addr,
+					ACT_CAT_BA,
+					ACT_ADDBARSP,
+					&osADDBAFrame	);
+
+	// Dialog Token
+	FillOctetString(tmp, &pBA->DialogToken, 1);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	// Status Code
+	FillOctetString(tmp, &StatusCode, 2);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	// BA Parameter Set
+	FillOctetString(tmp, &pBA->BaParamSet, 2);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	// BA Timeout Value
+	FillOctetString(tmp, &pBA->BaTimeoutValue, 2);
+	PacketAppendData(&osADDBAFrame, tmp);
+
+	*pLength = osADDBAFrame.Length;
+}
+#endif
+
+/********************************************************************************************************************
+ *function:  construct DELBA frame
+ *   input:  u8* 		dst 	//DELBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *   	     TR_SELECT	        TxRxSelect  //TX RX direction
+ *   	     u16 		ReasonCode  //status code.
+ *  output:  none
+ *  return:  sk_buff* 		skb     //return constructed skb to xmit
+********************************************************************************************************************/
+static struct sk_buff* ieee80211_DELBA(
+	struct ieee80211_device* ieee,
+	u8*		         dst,
+	PBA_RECORD		 pBA,
+	TR_SELECT		 TxRxSelect,
+	u16			 ReasonCode
+	)
+{
+	DELBA_PARAM_SET	DelbaParamSet;
+	struct sk_buff *skb = NULL;
+	 struct ieee80211_hdr_3addr* Delba = NULL;
+	u8* tag = NULL;
+	u16 tmp = 0;
+	//len = head len + DELBA Parameter Set(2) + Reason Code(2)
+	u16 len = 6 + ieee->tx_headroom;
+
+	if (net_ratelimit())
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:"MAC_FMT"\n", __FUNCTION__, ReasonCode, MAC_ARG(dst));
+
+	memset(&DelbaParamSet, 0, 2);
+
+	DelbaParamSet.field.Initiator	= (TxRxSelect==TX_DIR)?1:0;
+	DelbaParamSet.field.TID	= pBA->BaParamSet.field.TID;
+
+	skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME
+	if (skb == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n");
+		return NULL;
+	}
+//	memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr));
+	skb_reserve(skb, ieee->tx_headroom);
+
+	Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr));
+
+	memcpy(Delba->addr1, dst, ETH_ALEN);
+	memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN);
+	memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN);
+	Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame
+
+	tag = (u8*)skb_put(skb, 6);
+
+	*tag ++= ACT_CAT_BA;
+	*tag ++= ACT_DELBA;
+
+	// DELBA Parameter Set
+	tmp = cpu_to_le16(DelbaParamSet.shortData);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+	// Reason Code
+	tmp = cpu_to_le16(ReasonCode);
+	memcpy(tag, (u8*)&tmp, 2);
+	tag += 2;
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	if (net_ratelimit())
+	IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__);
+	return skb;
+}
+
+/********************************************************************************************************************
+ *function: send ADDBAReq frame out
+ *   input:  u8* 		dst 	//ADDBAReq frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8*	dst, PBA_RECORD	pBA)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero.
+
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//add statistic needed here.
+		//and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit()
+		//WB
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+	return;
+}
+
+/********************************************************************************************************************
+ *function: send ADDBARSP frame out
+ *   input:  u8* 		dst 	//DELBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *   	     u16		StatusCode //RSP StatusCode
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//same above
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+
+	return;
+
+}
+/********************************************************************************************************************
+ *function: send ADDBARSP frame out
+ *   input:  u8* 		dst 	//DELBA frame's destination
+ *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA
+ *   	     TR_SELECT          TxRxSelect //TX or RX
+ *   	     u16		ReasonCode //DEL ReasonCode
+ *  output:  none
+ *  notice: If any possible, please hide pBA in ieee. And temporarily use Manage Queue as softmac_mgmt_xmit() usually does
+********************************************************************************************************************/
+
+void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode)
+{
+	struct sk_buff *skb = NULL;
+	skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames
+	if (skb)
+	{
+		softmac_mgmt_xmit(skb, ieee);
+		//same above
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__);
+	}
+	return ;
+}
+
+/********************************************************************************************************************
+ *function: RX ADDBAReq
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* req = NULL;
+	u16 rc = 0;
+	u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL;
+	PBA_RECORD pBA = NULL;
+	PBA_PARAM_SET	pBaParamSet = NULL;
+	u16* pBaTimeoutVal = NULL;
+	PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL;
+	PRX_TS_RECORD	pTS = NULL;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		return -1;
+	}
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+
+	req = ( struct ieee80211_hdr_3addr*) skb->data;
+	tag = (u8*)req;
+	dst = (u8*)(&req->addr2[0]);
+	tag += sizeof( struct ieee80211_hdr_3addr);
+	pDialogToken = tag + 2;  //category+action
+	pBaParamSet = (PBA_PARAM_SET)(tag + 3);   //+DialogToken
+	pBaTimeoutVal = (u16*)(tag + 5);
+	pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7);
+
+	printk("====================>rx ADDBAREQ from :"MAC_FMT"\n", MAC_ARG(dst));
+//some other capability is not ready now.
+	if(	(ieee->current_network.qos_data.active == 0) ||
+		(ieee->pHTInfo->bCurrentHTSupport == false)) //||
+	//	(ieee->pStaQos->bEnableRxImmBA == false)	)
+	{
+		rc = ADDBA_STATUS_REFUSED;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
+		goto OnADDBAReq_Fail;
+	}
+	// Search for related traffic stream.
+	// If there is no matched TS, reject the ADDBA request.
+	if(	!GetTs(
+			ieee,
+			(PTS_COMMON_INFO*)(&pTS),
+			dst,
+			(u8)(pBaParamSet->field.TID),
+			RX_DIR,
+			true)	)
+	{
+		rc = ADDBA_STATUS_REFUSED;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
+		goto OnADDBAReq_Fail;
+	}
+	pBA = &pTS->RxAdmittedBARecord;
+	// To Determine the ADDBA Req content
+	// We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl...
+	// I want to check StartSeqCtrl to make sure when we start aggregation!!!
+	//
+	if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
+	{
+		rc = ADDBA_STATUS_INVALID_PARAM;
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__);
+		goto OnADDBAReq_Fail;
+	}
+		// Admit the ADDBA Request
+	//
+	DeActivateBAEntry(ieee, pBA);
+	pBA->DialogToken = *pDialogToken;
+	pBA->BaParamSet = *pBaParamSet;
+	pBA->BaTimeoutValue = *pBaTimeoutVal;
+	pBA->BaStartSeqCtrl = *pBaStartSeqCtrl;
+	//for half N mode we only aggregate 1 frame
+	if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	pBA->BaParamSet.field.BufferSize = 1;
+	else
+	pBA->BaParamSet.field.BufferSize = 32;
+	ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue);
+	ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS);
+
+	// End of procedure.
+	return 0;
+
+OnADDBAReq_Fail:
+	{
+		BA_RECORD	BA;
+		BA.BaParamSet = *pBaParamSet;
+		BA.BaTimeoutValue = *pBaTimeoutVal;
+		BA.DialogToken = *pDialogToken;
+		BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE;
+		ieee80211_send_ADDBARsp(ieee, dst, &BA, rc);
+		return 0; //we send RSP out.
+	}
+
+}
+
+/********************************************************************************************************************
+ *function: RX ADDBARSP
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* rsp = NULL;
+	PBA_RECORD		pPendingBA, pAdmittedBA;
+	PTX_TS_RECORD		pTS = NULL;
+	u8* dst = NULL, *pDialogToken = NULL, *tag = NULL;
+	u16* pStatusCode = NULL, *pBaTimeoutVal = NULL;
+	PBA_PARAM_SET		pBaParamSet = NULL;
+	u16			ReasonCode;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		return -1;
+	}
+	rsp = ( struct ieee80211_hdr_3addr*)skb->data;
+	tag = (u8*)rsp;
+	dst = (u8*)(&rsp->addr2[0]);
+	tag += sizeof( struct ieee80211_hdr_3addr);
+	pDialogToken = tag + 2;
+	pStatusCode = (u16*)(tag + 3);
+	pBaParamSet = (PBA_PARAM_SET)(tag + 5);
+	pBaTimeoutVal = (u16*)(tag + 7);
+
+	// Check the capability
+	// Since we can always receive A-MPDU, we just check if it is under HT mode.
+	if(     ieee->current_network.qos_data.active == 0  ||
+		ieee->pHTInfo->bCurrentHTSupport == false ||
+		ieee->pHTInfo->bCurrentAMPDUEnable == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable);
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+
+
+	//
+	// Search for related TS.
+	// If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame.
+	//
+	if (!GetTs(
+			ieee,
+			(PTS_COMMON_INFO*)(&pTS),
+			dst,
+			(u8)(pBaParamSet->field.TID),
+			TX_DIR,
+			false)	)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__);
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+
+	pTS->bAddBaReqInProgress = false;
+	pPendingBA = &pTS->TxPendingBARecord;
+	pAdmittedBA = &pTS->TxAdmittedBARecord;
+
+
+	//
+	// Check if related BA is waiting for setup.
+	// If not, reject by sending DELBA frame.
+	//
+	if((pAdmittedBA->bValid==true))
+	{
+		// Since BA is already setup, we ignore all other ADDBA Response.
+		IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n");
+		return -1;
+	}
+	else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR,  "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n");
+		ReasonCode = DELBA_REASON_UNKNOWN_BA;
+		goto OnADDBARsp_Reject;
+	}
+	else
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode);
+		DeActivateBAEntry(ieee, pPendingBA);
+	}
+
+
+	if(*pStatusCode == ADDBA_STATUS_SUCCESS)
+	{
+		//
+		// Determine ADDBA Rsp content here.
+		// We can compare the value of BA parameter set that Peer returned and Self sent.
+		// If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism.
+		//
+		if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED)
+		{
+			// Since this is a kind of ADDBA failed, we delay next ADDBA process.
+			pTS->bAddBaReqDelayed = true;
+			DeActivateBAEntry(ieee, pAdmittedBA);
+			ReasonCode = DELBA_REASON_END_BA;
+			goto OnADDBARsp_Reject;
+		}
+
+
+		//
+		// Admitted condition
+		//
+		pAdmittedBA->DialogToken = *pDialogToken;
+		pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal;
+		pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl;
+		pAdmittedBA->BaParamSet = *pBaParamSet;
+		DeActivateBAEntry(ieee, pAdmittedBA);
+		ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal);
+	}
+	else
+	{
+		// Delay next ADDBA process.
+		pTS->bAddBaReqDelayed = true;
+	}
+
+	// End of procedure
+	return 0;
+
+OnADDBARsp_Reject:
+	{
+		BA_RECORD	BA;
+		BA.BaParamSet = *pBaParamSet;
+		ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode);
+		return 0;
+	}
+
+}
+
+/********************************************************************************************************************
+ *function: RX DELBA
+ *   input:  struct sk_buff *   skb	//incoming ADDBAReq skb.
+ *  return:  0(pass), other(fail)
+ *  notice:  As this function need support of QOS, I comment some code out. And when qos is ready, this code need to be support.
+********************************************************************************************************************/
+int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
+{
+	 struct ieee80211_hdr_3addr* delba = NULL;
+	PDELBA_PARAM_SET	pDelBaParamSet = NULL;
+	u16*			pReasonCode = NULL;
+	u8*			dst = NULL;
+
+	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 6));
+		return -1;
+	}
+
+	if(ieee->current_network.qos_data.active == 0 ||
+		ieee->pHTInfo->bCurrentHTSupport == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport);
+		return -1;
+	}
+
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
+	delba = ( struct ieee80211_hdr_3addr*)skb->data;
+	dst = (u8*)(&delba->addr2[0]);
+	delba += sizeof( struct ieee80211_hdr_3addr);
+	pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2);
+	pReasonCode = (u16*)(delba+4);
+
+	if(pDelBaParamSet->field.Initiator == 1)
+	{
+		PRX_TS_RECORD 	pRxTs;
+
+		if( !GetTs(
+				ieee,
+				(PTS_COMMON_INFO*)&pRxTs,
+				dst,
+				(u8)pDelBaParamSet->field.TID,
+				RX_DIR,
+				false)	)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for RXTS in %s()\n", __FUNCTION__);
+			return -1;
+		}
+
+		RxTsDeleteBA(ieee, pRxTs);
+	}
+	else
+	{
+		PTX_TS_RECORD	pTxTs;
+
+		if(!GetTs(
+			ieee,
+			(PTS_COMMON_INFO*)&pTxTs,
+			dst,
+			(u8)pDelBaParamSet->field.TID,
+			TX_DIR,
+			false)	)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR,  "can't get TS for TXTS in %s()\n", __FUNCTION__);
+			return -1;
+		}
+
+		pTxTs->bUsingBa = false;
+		pTxTs->bAddBaReqInProgress = false;
+		pTxTs->bAddBaReqDelayed = false;
+		del_timer_sync(&pTxTs->TsAddBaTimer);
+		//PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer);
+		TxTsDeleteBA(ieee, pTxTs);
+	}
+	return 0;
+}
+
+//
+// ADDBA initiate. This can only be called by TX side.
+//
+void
+TsInitAddBA(
+	struct ieee80211_device* ieee,
+	PTX_TS_RECORD	pTS,
+	u8		Policy,
+	u8		bOverwritePending
+	)
+{
+	PBA_RECORD			pBA = &pTS->TxPendingBARecord;
+
+	if(pBA->bValid==true && bOverwritePending==false)
+		return;
+
+	// Set parameters to "Pending" variable set
+	DeActivateBAEntry(ieee, pBA);
+
+	pBA->DialogToken++;						// DialogToken: Only keep the latest dialog token
+	pBA->BaParamSet.field.AMSDU_Support = 0;	// Do not support A-MSDU with A-MPDU now!!
+	pBA->BaParamSet.field.BAPolicy = Policy;	// Policy: Delayed or Immediate
+	pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID;	// TID
+	// BufferSize: This need to be set according to A-MPDU vector
+	pBA->BaParamSet.field.BufferSize = 32;		// BufferSize: This need to be set according to A-MPDU vector
+	pBA->BaTimeoutValue = 0;					// Timeout value: Set 0 to disable Timer
+	pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; 	// Block Ack will start after 3 packets later.
+
+	ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT);
+
+	ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA);
+}
+
+void
+TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect)
+{
+
+	if(TxRxSelect == TX_DIR)
+	{
+		PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)pTsCommonInfo;
+
+		if(TxTsDeleteBA(ieee, pTxTs))
+			ieee80211_send_DELBA(
+				ieee,
+				pTsCommonInfo->Addr,
+				(pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord),
+				TxRxSelect,
+				DELBA_REASON_END_BA);
+	}
+	else if(TxRxSelect == RX_DIR)
+	{
+		PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)pTsCommonInfo;
+		if(RxTsDeleteBA(ieee, pRxTs))
+			ieee80211_send_DELBA(
+				ieee,
+				pTsCommonInfo->Addr,
+				&pRxTs->RxAdmittedBARecord,
+				TxRxSelect,
+				DELBA_REASON_END_BA	);
+	}
+}
+/********************************************************************************************************************
+ *function:  BA setup timer
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:
+********************************************************************************************************************/
+void BaSetupTimeOut(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+
+	pTxTs->bAddBaReqInProgress = false;
+	pTxTs->bAddBaReqDelayed = true;
+	pTxTs->TxPendingBARecord.bValid = false;
+}
+
+void TxBaInactTimeout(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]);
+	TxTsDeleteBA(ieee, pTxTs);
+	ieee80211_send_DELBA(
+		ieee,
+		pTxTs->TsCommonInfo.Addr,
+		&pTxTs->TxAdmittedBARecord,
+		TX_DIR,
+		DELBA_REASON_TIMEOUT);
+}
+
+void RxBaInactTimeout(unsigned long data)
+{
+	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
+
+	RxTsDeleteBA(ieee, pRxTs);
+	ieee80211_send_DELBA(
+		ieee,
+		pRxTs->TsCommonInfo.Addr,
+		&pRxTs->RxAdmittedBARecord,
+		RX_DIR,
+		DELBA_REASON_TIMEOUT);
+	return ;
+}
+
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
new file mode 100644
index 0000000..992b718
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h
@@ -0,0 +1,481 @@
+#ifndef _RTL819XU_HTTYPE_H_
+#define _RTL819XU_HTTYPE_H_
+
+//------------------------------------------------------------
+// The HT Capability element is present in beacons, association request,
+//	reassociation request and probe response frames
+//------------------------------------------------------------
+
+//
+// Operation mode value
+//
+#define HT_OPMODE_NO_PROTECT		0
+#define HT_OPMODE_OPTIONAL		1
+#define HT_OPMODE_40MHZ_PROTECT	2
+#define HT_OPMODE_MIXED			3
+
+//
+// MIMO Power Save Setings
+//
+#define MIMO_PS_STATIC				0
+#define MIMO_PS_DYNAMIC			1
+#define MIMO_PS_NOLIMIT			3
+
+
+//
+//	There should be 128 bits to cover all of the MCS rates. However, since
+//	8190 does not support too much rates, one integer is quite enough.
+//
+
+#define sHTCLng	4
+
+
+#define HT_SUPPORTED_MCS_1SS_BITMAP					0x000000ff
+#define HT_SUPPORTED_MCS_2SS_BITMAP					0x0000ff00
+#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP			HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP
+
+
+typedef enum _HT_MCS_RATE{
+	HT_MCS0   = 0x00000001,
+	HT_MCS1   = 0x00000002,
+	HT_MCS2   = 0x00000004,
+	HT_MCS3   = 0x00000008,
+	HT_MCS4   = 0x00000010,
+	HT_MCS5   = 0x00000020,
+	HT_MCS6   = 0x00000040,
+	HT_MCS7   = 0x00000080,
+	HT_MCS8   = 0x00000100,
+	HT_MCS9   = 0x00000200,
+	HT_MCS10 = 0x00000400,
+	HT_MCS11 = 0x00000800,
+	HT_MCS12 = 0x00001000,
+	HT_MCS13 = 0x00002000,
+	HT_MCS14 = 0x00004000,
+	HT_MCS15 = 0x00008000,
+	// Do not define MCS32 here although 8190 support MCS32
+}HT_MCS_RATE,*PHT_MCS_RATE;
+
+//
+// Represent Channel Width in HT Capabilities
+//
+typedef enum _HT_CHANNEL_WIDTH{
+	HT_CHANNEL_WIDTH_20 = 0,
+	HT_CHANNEL_WIDTH_20_40 = 1,
+}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH;
+
+//
+// Represent Extention Channel Offset in HT Capabilities
+// This is available only in 40Mhz mode.
+//
+typedef enum _HT_EXTCHNL_OFFSET{
+	HT_EXTCHNL_OFFSET_NO_EXT = 0,
+	HT_EXTCHNL_OFFSET_UPPER = 1,
+	HT_EXTCHNL_OFFSET_NO_DEF = 2,
+	HT_EXTCHNL_OFFSET_LOWER = 3,
+}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET;
+
+typedef enum _CHNLOP{
+	CHNLOP_NONE = 0, // No Action now
+	CHNLOP_SCAN = 1, // Scan in progress
+	CHNLOP_SWBW = 2, // Bandwidth switching in progress
+	CHNLOP_SWCHNL = 3, // Software Channel switching in progress
+} CHNLOP, *PCHNLOP;
+
+// Determine if the Channel Operation is in progress
+#define CHHLOP_IN_PROGRESS(_pHTInfo)	\
+		((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE
+
+/*
+typedef	union _HT_CAPABILITY{
+	u16	ShortData;
+	u8	CharData[2];
+	struct
+	{
+		u16	AdvCoding:1;
+		u16	ChlWidth:1;
+		u16	MimoPwrSave:2;
+		u16	GreenField:1;
+		u16	ShortGI20Mhz:1;
+		u16	ShortGI40Mhz:1;
+		u16	STBC:1;
+		u16	BeamForm:1;
+		u16	DelayBA:1;
+		u16	MaxAMSDUSize:1;
+		u16	DssCCk:1;
+		u16	PSMP:1;
+		u16	Rsvd:3;
+	}Field;
+}HT_CAPABILITY, *PHT_CAPABILITY;
+
+typedef	union _HT_CAPABILITY_MACPARA{
+	u8	ShortData;
+	u8	CharData[1];
+	struct
+	{
+		u8	MaxRxAMPDU:2;
+		u8	MPDUDensity:2;
+		u8	Rsvd:4;
+	}Field;
+}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA;
+*/
+
+typedef enum _HT_ACTION{
+	ACT_RECOMMAND_WIDTH		= 0,
+	ACT_MIMO_PWR_SAVE 		= 1,
+	ACT_PSMP					= 2,
+	ACT_SET_PCO_PHASE		= 3,
+	ACT_MIMO_CHL_MEASURE	= 4,
+	ACT_RECIPROCITY_CORRECT	= 5,
+	ACT_MIMO_CSI_MATRICS		= 6,
+	ACT_MIMO_NOCOMPR_STEER	= 7,
+	ACT_MIMO_COMPR_STEER		= 8,
+	ACT_ANTENNA_SELECT		= 9,
+} HT_ACTION, *PHT_ACTION;
+
+
+/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */
+typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{
+	SC_MODE_DUPLICATE = 0,
+	SC_MODE_LOWER = 1,
+	SC_MODE_UPPER = 2,
+	SC_MODE_FULL40MHZ = 3,
+}HT_BW40_SC_E;
+
+typedef	struct _HT_CAPABILITY_ELE{
+
+	//HT capability info
+	u8	AdvCoding:1;
+	u8	ChlWidth:1;
+	u8	MimoPwrSave:2;
+	u8	GreenField:1;
+	u8	ShortGI20Mhz:1;
+	u8	ShortGI40Mhz:1;
+	u8	TxSTBC:1;
+	u8	RxSTBC:2;
+	u8	DelayBA:1;
+	u8	MaxAMSDUSize:1;
+	u8	DssCCk:1;
+	u8	PSMP:1;
+	u8	Rsvd1:1;
+	u8	LSigTxopProtect:1;
+
+	//MAC HT parameters info
+	u8	MaxRxAMPDUFactor:2;
+	u8	MPDUDensity:3;
+	u8	Rsvd2:3;
+
+	//Supported MCS set
+	u8	MCS[16];
+
+
+	//Extended HT Capability Info
+	u16	ExtHTCapInfo;
+
+	//TXBF Capabilities
+	u8	TxBFCap[4];
+
+	//Antenna Selection Capabilities
+	u8	ASCap;
+
+} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE;
+
+//------------------------------------------------------------
+// The HT Information element is present in beacons
+// Only AP is required to include this element
+//------------------------------------------------------------
+
+typedef struct _HT_INFORMATION_ELE{
+	u8	ControlChl;
+
+	u8	ExtChlOffset:2;
+	u8	RecommemdedTxWidth:1;
+	u8	RIFS:1;
+	u8	PSMPAccessOnly:1;
+	u8	SrvIntGranularity:3;
+
+	u8	OptMode:2;
+	u8	NonGFDevPresent:1;
+	u8	Revd1:5;
+	u8	Revd2:8;
+
+	u8	Rsvd3:6;
+	u8	DualBeacon:1;
+	u8	DualCTSProtect:1;
+
+	u8	SecondaryBeacon:1;
+	u8	LSigTxopProtectFull:1;
+	u8	PcoActive:1;
+	u8	PcoPhase:1;
+	u8	Rsvd4:4;
+
+	u8	BasicMSC[16];
+} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE;
+
+//
+// MIMO Power Save control field.
+// This is appear in MIMO Power Save Action Frame
+//
+typedef struct _MIMOPS_CTRL{
+	u8	MimoPsEnable:1;
+	u8	MimoPsMode:1;
+	u8	Reserved:6;
+} MIMOPS_CTRL, *PMIMOPS_CTRL;
+
+typedef enum _HT_SPEC_VER{
+	HT_SPEC_VER_IEEE = 0,
+	HT_SPEC_VER_EWC = 1,
+}HT_SPEC_VER, *PHT_SPEC_VER;
+
+typedef enum _HT_AGGRE_MODE_E{
+	HT_AGG_AUTO = 0,
+	HT_AGG_FORCE_ENABLE = 1,
+	HT_AGG_FORCE_DISABLE = 2,
+}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E;
+
+//------------------------------------------------------------
+//  The Data structure is used to keep HT related variables when card is
+//  configured as non-AP STA mode.  **Note**  Current_xxx should be set
+//	to default value in HTInitializeHTInfo()
+//------------------------------------------------------------
+
+typedef struct _RT_HIGH_THROUGHPUT{
+	u8				bEnableHT;
+	u8				bCurrentHTSupport;
+
+	u8				bRegBW40MHz;				// Tx 40MHz channel capablity
+	u8				bCurBW40MHz;				// Tx 40MHz channel capability
+
+	u8				bRegShortGI40MHz;			// Tx Short GI for 40Mhz
+	u8				bCurShortGI40MHz;			// Tx Short GI for 40MHz
+
+	u8				bRegShortGI20MHz;			// Tx Short GI for 20MHz
+	u8				bCurShortGI20MHz;			// Tx Short GI for 20MHz
+
+	u8				bRegSuppCCK;				// Tx CCK rate capability
+	u8				bCurSuppCCK;				// Tx CCK rate capability
+
+	// 802.11n spec version for "peer"
+	HT_SPEC_VER			ePeerHTSpecVer;
+
+
+	// HT related information for "Self"
+	HT_CAPABILITY_ELE	SelfHTCap;		// This is HT cap element sent to peer STA, which also indicate HT Rx capabilities.
+	HT_INFORMATION_ELE	SelfHTInfo;		// This is HT info element sent to peer STA, which also indicate HT Rx capabilities.
+
+	// HT related information for "Peer"
+	u8				PeerHTCapBuf[32];
+	u8				PeerHTInfoBuf[32];
+
+
+	// A-MSDU related
+	u8				bAMSDU_Support;			// This indicates Tx A-MSDU capability
+	u16				nAMSDU_MaxSize;			// This indicates Tx A-MSDU capability
+	u8				bCurrent_AMSDU_Support;	// This indicates Tx A-MSDU capability
+	u16				nCurrent_AMSDU_MaxSize;	// This indicates Tx A-MSDU capability
+
+
+	// AMPDU  related <2006.08.10 Emily>
+	u8				bAMPDUEnable;				// This indicate Tx A-MPDU capability
+	u8				bCurrentAMPDUEnable;		// This indicate Tx A-MPDU capability
+	u8				AMPDU_Factor;				// This indicate Tx A-MPDU capability
+	u8				CurrentAMPDUFactor;		// This indicate Tx A-MPDU capability
+	u8				MPDU_Density;				// This indicate Tx A-MPDU capability
+	u8				CurrentMPDUDensity;			// This indicate Tx A-MPDU capability
+
+	// Forced A-MPDU enable
+	HT_AGGRE_MODE_E	ForcedAMPDUMode;
+	u8				ForcedAMPDUFactor;
+	u8				ForcedMPDUDensity;
+
+	// Forced A-MSDU enable
+	HT_AGGRE_MODE_E	ForcedAMSDUMode;
+	u16				ForcedAMSDUMaxSize;
+
+	u8				bForcedShortGI;
+
+	u8				CurrentOpMode;
+
+	// MIMO PS related
+	u8				SelfMimoPs;
+	u8				PeerMimoPs;
+
+	// 40MHz Channel Offset settings.
+	HT_EXTCHNL_OFFSET	CurSTAExtChnlOffset;
+	u8				bCurTxBW40MHz;	// If we use 40 MHz to Tx
+	u8				PeerBandwidth;
+
+	// For Bandwidth Switching
+	u8				bSwBwInProgress;
+	CHNLOP				ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15.
+	u8				SwBwStep;
+	//struct timer_list		SwBwTimer;  //moved to ieee80211_device. as timer_list need include some header file here.
+
+	// For Realtek proprietary A-MPDU factor for aggregation
+	u8				bRegRT2RTAggregation;
+	u8				bCurrentRT2RTAggregation;
+	u8				bCurrentRT2RTLongSlotTime;
+	u8				szRT2RTAggBuffer[10];
+
+	// Rx Reorder control
+	u8				bRegRxReorderEnable;
+	u8				bCurRxReorderEnable;
+	u8				RxReorderWinSize;
+	u8				RxReorderPendingTime;
+	u16				RxReorderDropCounter;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	u8				UsbTxAggrNum;
+#endif
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	u8				UsbRxFwAggrEn;
+	u8				UsbRxFwAggrPageNum;
+	u8				UsbRxFwAggrPacketNum;
+	u8				UsbRxFwAggrTimeout;
+#endif
+
+	// Add for Broadcom(Linksys) IOT. Joseph
+	u8				bIsPeerBcm;
+
+	// For IOT issue.
+	u8				IOTPeer;
+	u32				IOTAction;
+} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT;
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each Sta"
+// when card is configured as "AP mode"
+//------------------------------------------------------------
+
+typedef struct _RT_HTINFO_STA_ENTRY{
+	u8			bEnableHT;
+
+	u8			bSupportCck;
+
+	u16			AMSDU_MaxSize;
+
+	u8			AMPDU_Factor;
+	u8			MPDU_Density;
+
+	u8			HTHighestOperaRate;
+
+	u8			bBw40MHz;
+
+	u8			MimoPs;
+
+	u8			McsRateSet[16];
+
+
+}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY;
+
+
+
+
+
+//------------------------------------------------------------
+// The Data structure is used to keep HT related variable for "each AP"
+// when card is configured as "STA mode"
+//------------------------------------------------------------
+
+typedef struct _BSS_HT{
+
+	u8				bdSupportHT;
+
+	// HT related elements
+	u8					bdHTCapBuf[32];
+	u16					bdHTCapLen;
+	u8					bdHTInfoBuf[32];
+	u16					bdHTInfoLen;
+
+	HT_SPEC_VER				bdHTSpecVer;
+	//HT_CAPABILITY_ELE			bdHTCapEle;
+	//HT_INFORMATION_ELE		bdHTInfoEle;
+
+	u8					bdRT2RTAggregation;
+	u8					bdRT2RTLongSlotTime;
+} __attribute__ ((packed)) BSS_HT, *PBSS_HT;
+
+typedef struct _MIMO_RSSI{
+	u32	EnableAntenna;
+	u32	AntennaA;
+	u32 	AntennaB;
+	u32 	AntennaC;
+	u32 	AntennaD;
+	u32	Average;
+}MIMO_RSSI, *PMIMO_RSSI;
+
+typedef struct _MIMO_EVM{
+	u32	EVM1;
+	u32    EVM2;
+}MIMO_EVM, *PMIMO_EVM;
+
+typedef struct _FALSE_ALARM_STATISTICS{
+	u32	Cnt_Parity_Fail;
+	u32    Cnt_Rate_Illegal;
+	u32	Cnt_Crc8_fail;
+	u32	Cnt_all;
+}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS;
+
+
+extern u8 MCS_FILTER_ALL[16];
+extern u8 MCS_FILTER_1SS[16];
+
+/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set
+   STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have
+   to add a macro to judge wireless mode. */
+#define PICK_RATE(_nLegacyRate, _nMcsRate)	\
+		(_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate)
+/* 2007/07/12 MH We only define legacy and HT wireless mode now. */
+#define	LEGACY_WIRELESS_MODE	IEEE_MODE_MASK
+
+#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate)	\
+					((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\
+						(LegacyRate):\
+						(PICK_RATE(LegacyRate, HTRate))
+
+
+
+// MCS Bw 40 {1~7, 12~15,32}
+#define	RATE_ADPT_1SS_MASK 		0xFF
+#define	RATE_ADPT_2SS_MASK	   	0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily
+#define	RATE_ADPT_MCS32_MASK		0x01
+
+#define 	IS_11N_MCS_RATE(rate)		(rate&0x80)
+
+typedef enum _HT_AGGRE_SIZE{
+	HT_AGG_SIZE_8K = 0,
+	HT_AGG_SIZE_16K = 1,
+	HT_AGG_SIZE_32K = 2,
+	HT_AGG_SIZE_64K = 3,
+}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E;
+
+/* Indicate different AP vendor for IOT issue */
+typedef enum _HT_IOT_PEER
+{
+	HT_IOT_PEER_UNKNOWN = 0,
+	HT_IOT_PEER_REALTEK = 1,
+	HT_IOT_PEER_BROADCOM = 2,
+	HT_IOT_PEER_RALINK = 3,
+	HT_IOT_PEER_ATHEROS = 4,
+	HT_IOT_PEER_CISCO= 5,
+	HT_IOT_PEER_MAX = 6
+}HT_IOT_PEER_E, *PHTIOT_PEER_E;
+
+//
+// IOT Action for different AP
+//
+typedef enum _HT_IOT_ACTION{
+	HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001,
+	HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002,
+	HT_IOT_ACT_DISABLE_MCS14 = 0x00000004,
+	HT_IOT_ACT_DISABLE_MCS15 = 0x00000008,
+	HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010,
+	HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020,
+	HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040,
+	HT_IOT_ACT_CDD_FSYNC = 0x00000080,
+	HT_IOT_ACT_PURE_N_MODE = 0x00000100,
+	HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200,
+}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E;
+
+#endif //_RTL819XU_HTTYPE_H_
+
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
new file mode 100644
index 0000000..1e39214
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c
@@ -0,0 +1,1719 @@
+
+//As this function is mainly ported from Windows driver, so leave the name little changed. If any confusion caused, tell me. Created by WB. 2008.05.08
+#include "ieee80211.h"
+#include "rtl819x_HT.h"
+u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+u16 MCS_DATA_RATE[2][2][77] =
+	{	{	{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260,
+			39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520,
+			0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195,
+			195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260,
+			286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429},			// Long GI, 20MHz
+			{14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289,
+			43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578,
+			0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217,
+			217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289,
+			318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477}	},		// Short GI, 20MHz
+		{	{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,
+			81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080,
+			12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405,
+			405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540,
+			594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891}, 	// Long GI, 40MHz
+			{30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,
+			90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200,
+			13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450,
+			450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600,
+			660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990}	}	// Short GI, 40MHz
+	};
+
+static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf};
+static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70};
+static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e};
+static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f};
+static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f};	//cosa 03202008
+static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf};
+static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc};
+static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e};
+static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02};
+static u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0};
+static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94};
+
+// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Shoud we put the
+// code in other place??
+//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96};
+/********************************************************************************************************************
+ *function:  This function update default settings in pHTInfo structure
+ *   input:  PRT_HIGH_THROUGHPUT	pHTInfo
+ *  output:  none
+ *  return:  none
+ *  notice:  These value need be modified if any changes.
+ * *****************************************************************************************************************/
+void HTUpdateDefaultSetting(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	//const typeof( ((struct ieee80211_device *)0)->pHTInfo ) *__mptr = &pHTInfo;
+
+	//printk("pHTinfo:%p, &pHTinfo:%p, mptr:%p,  offsetof:%x\n", pHTInfo, &pHTInfo, __mptr, offsetof(struct ieee80211_device, pHTInfo));
+	//printk("===>ieee:%p,\n", ieee);
+	// ShortGI support
+	pHTInfo->bRegShortGI20MHz= 1;
+	pHTInfo->bRegShortGI40MHz= 1;
+
+	// 40MHz channel support
+	pHTInfo->bRegBW40MHz = 1;
+
+	// CCK rate support in 40MHz channel
+	if(pHTInfo->bRegBW40MHz)
+		pHTInfo->bRegSuppCCK = 1;
+	else
+		pHTInfo->bRegSuppCCK = true;
+
+	// AMSDU related
+	pHTInfo->nAMSDU_MaxSize = 7935UL;
+	pHTInfo->bAMSDU_Support = 0;
+
+	// AMPDU related
+	pHTInfo->bAMPDUEnable = 1;
+	pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k)
+	pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec
+
+	// MIMO Power Save
+	pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.)
+	if(pHTInfo->SelfMimoPs == 2)
+		pHTInfo->SelfMimoPs = 3;
+	// 8190 only. Assign rate operation mode to firmware
+	ieee->bTxDisableRateFallBack = 0;
+	ieee->bTxUseDriverAssingedRate = 0;
+
+#ifdef 	TO_DO_LIST
+	// 8190 only. Assign duration operation mode to firmware
+	pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur;
+#endif
+	// 8190 only, Realtek proprietary aggregation mode
+	// Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
+	pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2,   1: Set MPDUDensity=2(32k)  for Realtek AP and set MPDUDensity=0(8k) for others
+
+	// For Rx Reorder Control
+	pHTInfo->bRegRxReorderEnable = 1;
+	pHTInfo->RxReorderWinSize = 64;
+	pHTInfo->RxReorderPendingTime = 30;
+
+#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
+	pHTInfo->UsbTxAggrNum = 4;
+#endif
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	pHTInfo->UsbRxFwAggrEn = 1;
+	pHTInfo->UsbRxFwAggrPageNum = 24;
+	pHTInfo->UsbRxFwAggrPacketNum = 8;
+	pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us
+#endif
+
+
+}
+/********************************************************************************************************************
+ *function:  This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq)
+ *   input:  u8*	CapIE       //Capability IE to be printed out
+ *   	     u8* 	TitleString //mainly print out caller function
+ *  output:  none
+ *  return:  none
+ *  notice:  Driver should not print out this message by default.
+ * *****************************************************************************************************************/
+void HTDebugHTCapability(u8* CapIE, u8* TitleString )
+{
+
+	static u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
+	PHT_CAPABILITY_ELE 		pCapELE;
+
+	if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap)))
+	{
+		//EWC IE
+		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
+		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]);
+	}else
+		pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]);
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString );
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO");
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor);
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMPDU Density = %d\n", pCapELE->MPDUDensity);
+	IEEE80211_DEBUG(IEEE80211_DL_HT,  "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\
+				pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]);
+	return;
+
+}
+/********************************************************************************************************************
+ *function:  This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp)
+ *   input:  u8*	InfoIE       //Capability IE to be printed out
+ *   	     u8* 	TitleString //mainly print out caller function
+ *  output:  none
+ *  return:  none
+ *  notice:  Driver should not print out this message by default.
+ * *****************************************************************************************************************/
+void HTDebugHTInfo(u8*	InfoIE, u8* TitleString)
+{
+
+	static u8	EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
+	PHT_INFORMATION_ELE		pHTInfoEle;
+
+	if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
+	{
+		// Not EWC IE
+		IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__);
+		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]);
+	}else
+		pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]);
+
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString);
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl);
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel =");
+	switch(pHTInfoEle->ExtChlOffset)
+	{
+		case 0:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n");
+			break;
+		case 1:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n");
+			break;
+		case 2:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n");
+			break;
+		case 3:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n");
+			break;
+	}
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz");
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = ");
+	switch(pHTInfoEle->OptMode)
+	{
+		case 0:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n");
+			break;
+		case 1:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n");
+			break;
+		case 2:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n");
+			break;
+		case 3:
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n");
+			break;
+	}
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\
+				pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]);
+	return;
+}
+
+/*
+*	Return:     	true if station in half n mode and AP supports 40 bw
+*/
+bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee)
+{
+	bool			retValue = false;
+	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
+
+	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
+		retValue = false;
+	else if(pHTInfo->bRegBW40MHz == false)	// station supports 40 bw
+		retValue = false;
+	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
+		retValue = false;
+	else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw
+		retValue = true;
+	else
+		retValue = false;
+
+	return retValue;
+}
+
+bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz)
+{
+	bool			retValue = false;
+	PRT_HIGH_THROUGHPUT	 pHTInfo = ieee->pHTInfo;
+
+	if(pHTInfo->bCurrentHTSupport == false )	// wireless is n mode
+		retValue = false;
+	else if(!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) 	// station in half n mode
+		retValue = false;
+	else if(is40MHz) // ap support 40 bw
+	{
+		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI
+			retValue = true;
+		else
+			retValue = false;
+	}
+	else
+	{
+		if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI
+			retValue = true;
+		else
+			retValue = false;
+	}
+
+	return retValue;
+}
+
+u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, 	u8	nMcsRate)
+{
+
+	u8	is40MHz;
+	u8	isShortGI;
+
+	is40MHz  =  (IsHTHalfNmode40Bandwidth(ieee))?1:0;
+	isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0;
+
+	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
+}
+
+
+u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+
+	u8	is40MHz = (pHTInfo->bCurBW40MHz)?1:0;
+	u8	isShortGI = (pHTInfo->bCurBW40MHz)?
+						((pHTInfo->bCurShortGI40MHz)?1:0):
+						((pHTInfo->bCurShortGI20MHz)?1:0);
+	return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)];
+}
+
+/********************************************************************************************************************
+ *function:  This function returns current datarate.
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8 			nDataRate
+ *  output:  none
+ *  return:  tx rate
+ *  notice:  quite unsure about how to use this function //wb
+ * *****************************************************************************************************************/
+u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate)
+{
+	//PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	u16		CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c};
+	u8	is40MHz = 0;
+	u8	isShortGI = 0;
+
+	if(nDataRate < 12)
+	{
+		return CCKOFDMRate[nDataRate];
+	}
+	else
+	{
+		if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 )
+		{
+			is40MHz = 0;
+			isShortGI = 0;
+
+		      // nDataRate = nDataRate - 12;
+		}
+		else if(nDataRate >=0x20  && nDataRate <= 0x2f ) //(27, 44)
+		{
+			is40MHz = 1;
+			isShortGI = 0;
+
+			//nDataRate = nDataRate - 28;
+		}
+		else if(nDataRate >= 0x30  && nDataRate <= 0x3f )  //(43, 60)
+		{
+			is40MHz = 0;
+			isShortGI = 1;
+
+			//nDataRate = nDataRate - 44;
+		}
+		else if(nDataRate >= 0x40  && nDataRate <= 0x4f ) //(59, 76)
+		{
+			is40MHz = 1;
+			isShortGI = 1;
+
+			//nDataRate = nDataRate - 60;
+		}
+		return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf];
+	}
+}
+
+
+
+bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
+{
+	bool			retValue = false;
+	struct ieee80211_network* net = &ieee->current_network;
+#if 0
+	if(pMgntInfo->bHalfNMode == false)
+		retValue = false;
+	else
+#endif
+	if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
+		     (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
+		     (net->ralink_cap_exist))
+		retValue = true;
+	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
+    		    (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+    		    (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+    		    (memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ||
+    		    (net->broadcom_cap_exist))
+    		  retValue = true;
+	else if(net->bssht.bdRT2RTAggregation)
+		retValue = true;
+	else
+		retValue = false;
+
+	return retValue;
+}
+
+/********************************************************************************************************************
+ *function:  This function returns peer IOT.
+ *   input:  struct ieee80211_device* 	ieee
+ *  output:  none
+ *  return:
+ *  notice:
+ * *****************************************************************************************************************/
+void HTIOTPeerDetermine(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	struct ieee80211_network* net = &ieee->current_network;
+	if(net->bssht.bdRT2RTAggregation)
+		pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK;
+	else if(net->broadcom_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) ||
+			(memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+			(memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+			(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) )
+		pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM;
+	else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
+			(memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
+			(memcmp(net->bssid, PCI_RALINK, 3)==0) ||
+			(memcmp(net->bssid, EDIMAX_RALINK, 3)==0) ||
+			(memcmp(net->bssid, AIRLINK_RALINK, 3)==0) ||
+			 net->ralink_cap_exist)
+		pHTInfo->IOTPeer = HT_IOT_PEER_RALINK;
+	else if((net->atheros_cap_exist )|| (memcmp(net->bssid, DLINK_ATHEROS, 3) == 0))
+		pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS;
+	else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0)
+		pHTInfo->IOTPeer = HT_IOT_PEER_CISCO;
+	else
+		pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
+
+	IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer);
+}
+/********************************************************************************************************************
+ *function:  Check whether driver should declare received rate up to MCS13 only since some chipset is not good
+ *	     at receiving MCS14~15 frame from some AP.
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8 *			PeerMacAddr
+ *  output:  none
+ *  return:  return 1 if driver should declare MCS13 only(otherwise return 0)
+  * *****************************************************************************************************************/
+u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
+{
+	u8 ret = 0;
+#if 0
+	// Apply for 819u only
+#if (HAL_CODE_BASE==RTL8192 && DEV_BUS_TYPE==USB_INTERFACE)
+	if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
+    		(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)
+	    )
+	{
+		ret = 1;
+	}
+
+
+	if(pHTInfo->bCurrentRT2RTAggregation)
+	{
+		// The parameter of pHTInfo->bCurrentRT2RTAggregation must be decided previously
+		ret = 1;
+	}
+#endif
+#endif
+	return ret;
+ }
+
+
+/**
+* Function:	HTIOTActIsDisableMCS15
+*
+* Overview:	Check whether driver should declare capability of receving MCS15
+*
+* Input:
+*			PADAPTER		Adapter,
+*
+* Output:		None
+* Return:     	true if driver should disable MCS15
+* 2008.04.15	Emily
+*/
+bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee)
+{
+	bool retValue = false;
+
+#ifdef TODO
+	// Apply for 819u only
+#if (HAL_CODE_BASE==RTL8192)
+
+#if (DEV_BUS_TYPE == USB_INTERFACE)
+	// Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15
+	retValue = true;
+#elif (DEV_BUS_TYPE == PCI_INTERFACE)
+	// Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12
+//	if(pBssDesc->bCiscoCapExist)
+//		retValue = false;
+//	else
+		retValue = false;
+#endif
+#endif
+#endif
+	// Jerry Chang suggest that 8190 1x2 does not need to disable MCS15
+
+	return retValue;
+}
+
+/**
+* Function:	HTIOTActIsDisableMCSTwoSpatialStream
+*
+* Overview:	Check whether driver should declare capability of receving All 2 ss packets
+*
+* Input:
+*			PADAPTER		Adapter,
+*
+* Output:		None
+* Return:     	true if driver should disable all two spatial stream packet
+* 2008.04.21	Emily
+*/
+bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee, u8 *PeerMacAddr)
+{
+	bool retValue = false;
+
+#ifdef TODO
+	// Apply for 819u only
+//#if (HAL_CODE_BASE==RTL8192)
+
+	//This rule only apply to Belkin(Ralink) AP
+	if(IS_UNDER_11N_AES_MODE(Adapter))
+	{
+		if((PlatformCompareMemory(PeerMacAddr, BELKINF5D8233V1_RALINK, 3)==0) ||
+				(PlatformCompareMemory(PeerMacAddr, PCI_RALINK, 3)==0) ||
+				(PlatformCompareMemory(PeerMacAddr, EDIMAX_RALINK, 3)==0))
+		{
+			//Set True to disable this function. Disable by default, Emily, 2008.04.23
+			retValue = false;
+		}
+	}
+
+//#endif
+#endif
+	return retValue;
+}
+
+/********************************************************************************************************************
+ *function:  Check whether driver should disable EDCA turbo mode
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			PeerMacAddr
+ *  output:  none
+ *  return:  return 1 if driver should disable EDCA turbo mode(otherwise return 0)
+  * *****************************************************************************************************************/
+u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* 	ieee, u8* PeerMacAddr)
+{
+	u8	retValue = false;	// default enable EDCA Turbo mode.
+	// Set specific EDCA parameter for different AP in DM handler.
+
+	return retValue;
+#if 0
+	if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0)||
+		(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
+		(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
+		(memcmp(PeerMacAddr, NETGEAR834Bv2_BROADCOM, 3)==0))
+
+	{
+		retValue = 1;	//Linksys disable EDCA turbo mode
+	}
+
+	return retValue;
+#endif
+}
+
+/********************************************************************************************************************
+ *function:  Check whether we need to use OFDM to sned MGNT frame for broadcom AP
+ *   input:  struct ieee80211_network *network   //current network we live
+ *  output:  none
+ *  return:  return 1 if true
+  * *****************************************************************************************************************/
+u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network)
+{
+	u8	retValue = 0;
+
+	// 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP.
+	// 2008/01/28 MH We must prevent that we select null bssid to link.
+
+	if(network->broadcom_cap_exist)
+	{
+		retValue = 1;
+	}
+
+	return retValue;
+}
+
+u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
+{
+	u8	retValue = 0;
+	if(	(memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
+	    	(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) ||
+	    	(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0))
+	{
+		retValue = 1;
+	}
+
+	return retValue;
+}
+
+void HTResetIOTSetting(
+	PRT_HIGH_THROUGHPUT		pHTInfo
+)
+{
+	pHTInfo->IOTAction = 0;
+	pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN;
+}
+
+
+/********************************************************************************************************************
+ *function:  Construct Capablility Element in Beacon... if HTEnable is turned on
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			posHTCap //pointer to store Capability Ele
+ *   	     u8*			len //store length of CE
+ *   	     u8				IsEncrypt //whether encrypt, needed further
+ *  output:  none
+ *  return:  none
+ *  notice:  posHTCap can't be null and should be initialized before.
+  * *****************************************************************************************************************/
+void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 IsEncrypt)
+{
+	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;
+	PHT_CAPABILITY_ELE 	pCapELE = NULL;
+	//u8 bIsDeclareMCS13;
+
+	if ((posHTCap == NULL) || (pHT == NULL))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n");
+		return;
+	}
+	memset(posHTCap, 0, *len);
+	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+	{
+		u8	EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};	// For 11n EWC definition, 2007.07.17, by Emily
+		memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap));
+		pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]);
+	}else
+	{
+		pCapELE = (PHT_CAPABILITY_ELE)posHTCap;
+	}
+
+
+	//HT capability info
+	pCapELE->AdvCoding 		= 0; // This feature is not supported now!!
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	{
+		pCapELE->ChlWidth = 0;
+	}
+	else
+	{
+		pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0);
+	}
+
+//	pCapELE->ChlWidth 		= (pHT->bRegBW40MHz?1:0);
+	pCapELE->MimoPwrSave 		= pHT->SelfMimoPs;
+	pCapELE->GreenField		= 0; // This feature is not supported now!!
+	pCapELE->ShortGI20Mhz		= 1; // We can receive Short GI!!
+	pCapELE->ShortGI40Mhz		= 1; // We can receive Short GI!!
+	//DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r",
+		//pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz);
+	pCapELE->TxSTBC 		= 1;
+	pCapELE->RxSTBC 		= 0;
+	pCapELE->DelayBA		= 0;	// Do not support now!!
+	pCapELE->MaxAMSDUSize	= (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0;
+	pCapELE->DssCCk 		= ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0);
+	pCapELE->PSMP			= 0; // Do not support now!!
+	pCapELE->LSigTxopProtect	= 0; // Do not support now!!
+
+
+	//MAC HT parameters info
+        // TODO: Nedd to take care of this part
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk);
+
+	if( IsEncrypt)
+	{
+		pCapELE->MPDUDensity 	= 7; // 8us
+		pCapELE->MaxRxAMPDUFactor 	= 2; // 2 is for 32 K and 3 is 64K
+	}
+	else
+	{
+		pCapELE->MaxRxAMPDUFactor 	= 3; // 2 is for 32 K and 3 is 64K
+		pCapELE->MPDUDensity 	= 0; // no density
+	}
+
+	//Supported MCS set
+	memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16);
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15)
+		pCapELE->MCS[1] &= 0x7f;
+
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14)
+		pCapELE->MCS[1] &= 0xbf;
+
+	if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS)
+		pCapELE->MCS[1] &= 0x00;
+
+	// 2008.06.12
+	// For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7.
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+	{
+		int i;
+		for(i = 1; i< 16; i++)
+			pCapELE->MCS[i] = 0;
+	}
+
+	//Extended HT Capability Info
+	memset(&pCapELE->ExtHTCapInfo, 0, 2);
+
+
+	//TXBF Capabilities
+	memset(pCapELE->TxBFCap, 0, 4);
+
+	//Antenna Selection Capabilities
+	pCapELE->ASCap = 0;
+//add 2 to give space for element ID and len when construct frames
+	if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)
+		*len = 30 + 2;
+	else
+		*len = 26 + 2;
+
+
+
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTCap, *len -2);
+
+	//Print each field in detail. Driver should not print out this message by default
+//	HTDebugHTCapability(posHTCap, (u8*)"HTConstructCapability()");
+	return;
+
+}
+/********************************************************************************************************************
+ *function:  Construct  Information Element in Beacon... if HTEnable is turned on
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			posHTCap //pointer to store Information Ele
+ *   	     u8*			len   //store len of
+ *   	     u8				IsEncrypt //whether encrypt, needed further
+ *  output:  none
+ *  return:  none
+ *  notice:  posHTCap can't be null and be initialized before. only AP and IBSS sta should do this
+  * *****************************************************************************************************************/
+void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 IsEncrypt)
+{
+	PRT_HIGH_THROUGHPUT	pHT = ieee->pHTInfo;
+	PHT_INFORMATION_ELE		pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo;
+	if ((posHTInfo == NULL) || (pHTInfoEle == NULL))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n");
+		return;
+	}
+
+	memset(posHTInfo, 0, *len);
+	if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported
+	{
+		pHTInfoEle->ControlChl 			= ieee->current_network.channel;
+		pHTInfoEle->ExtChlOffset 			= ((pHT->bRegBW40MHz == false)?HT_EXTCHNL_OFFSET_NO_EXT:
+											(ieee->current_network.channel<=6)?
+												HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER);
+		pHTInfoEle->RecommemdedTxWidth	= pHT->bRegBW40MHz;
+		pHTInfoEle->RIFS 					= 0;
+		pHTInfoEle->PSMPAccessOnly		= 0;
+		pHTInfoEle->SrvIntGranularity		= 0;
+		pHTInfoEle->OptMode				= pHT->CurrentOpMode;
+		pHTInfoEle->NonGFDevPresent		= 0;
+		pHTInfoEle->DualBeacon			= 0;
+		pHTInfoEle->SecondaryBeacon		= 0;
+		pHTInfoEle->LSigTxopProtectFull		= 0;
+		pHTInfoEle->PcoActive				= 0;
+		pHTInfoEle->PcoPhase				= 0;
+
+		memset(pHTInfoEle->BasicMSC, 0, 16);
+
+
+		*len = 22 + 2; //same above
+
+	}
+	else
+	{
+		//STA should not generate High Throughput Information Element
+		*len = 0;
+	}
+	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA | IEEE80211_DL_HT, posHTInfo, *len - 2);
+	//HTDebugHTInfo(posHTInfo, "HTConstructInforElement");
+	return;
+}
+
+/*
+  *  According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance
+  *  if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2
+  *  (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set
+  *  limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP
+  *  will be much less than the traffic stream from AP to STA if both of the stream runs concurrently
+  *  at the same time.
+  *
+  *  Frame Format
+  *  Element ID		Length		OUI			Type1		Reserved
+  *  1 byte			1 byte		3 bytes		1 byte		1 byte
+  *
+  *  OUI 		= 0x00, 0xe0, 0x4c,
+  *  Type 	= 0x02
+  *  Reserved 	= 0x00
+  *
+  *  2007.8.21 by Emily
+*/
+/********************************************************************************************************************
+ *function:  Construct  Information Element in Beacon... in RT2RT condition
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			posRT2RTAgg //pointer to store Information Ele
+ *   	     u8*			len   //store len
+ *  output:  none
+ *  return:  none
+ *  notice:
+  * *****************************************************************************************************************/
+void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len)
+{
+	if (posRT2RTAgg == NULL) {
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n");
+		return;
+	}
+	memset(posRT2RTAgg, 0, *len);
+	*posRT2RTAgg++ = 0x00;
+	*posRT2RTAgg++ = 0xe0;
+	*posRT2RTAgg++ = 0x4c;
+	*posRT2RTAgg++ = 0x02;
+	*posRT2RTAgg++ = 0x01;
+	*posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02;
+
+	if(ieee->bSupportRemoteWakeUp) {
+		*posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW;
+	}
+
+	*len = 6 + 2;
+	return;
+#ifdef TODO
+#if(HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE)
+	/*
+	//Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this
+	   section of code.
+	if(IS_UNDER_11N_AES_MODE(Adapter))
+	{
+		posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU;
+	}else
+	{
+		posRT2RTAgg->Octet[5] &= 0xfb;
+	}
+	*/
+
+#else
+	// Do Nothing
+#endif
+
+	posRT2RTAgg->Length = 6;
+#endif
+
+
+
+
+}
+
+
+/********************************************************************************************************************
+ *function:  Pick the right Rate Adaptive table to use
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			pOperateMCS //A pointer to MCS rate bitmap
+ *  return:  always we return true
+ *  notice:
+  * *****************************************************************************************************************/
+u8 HT_PickMCSRate(struct ieee80211_device* ieee, u8* pOperateMCS)
+{
+	u8					i;
+	if (pOperateMCS == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n");
+		return false;
+	}
+
+	switch(ieee->mode)
+	{
+	case IEEE_A:
+	case IEEE_B:
+	case IEEE_G:
+			//legacy rate routine handled at selectedrate
+
+			//no MCS rate
+			for(i=0;i<=15;i++){
+				pOperateMCS[i] = 0;
+			}
+			break;
+
+	case IEEE_N_24G:	//assume CCK rate ok
+	case IEEE_N_5G:
+			// Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G.
+			// Legacy part shall be handled at SelectRateSet().
+
+			//HT part
+			// TODO: may be different if we have different number of antenna
+			pOperateMCS[0] &=RATE_ADPT_1SS_MASK;	//support MCS 0~7
+			pOperateMCS[1] &=RATE_ADPT_2SS_MASK;
+			pOperateMCS[3] &=RATE_ADPT_MCS32_MASK;
+			break;
+
+	//should never reach here
+	default:
+
+			break;
+
+	}
+
+	return true;
+}
+
+/*
+*	Description:
+*		This function will get the highest speed rate in input MCS set.
+*
+*	/param 	Adapter			Pionter to Adapter entity
+*			pMCSRateSet		Pointer to MCS rate bitmap
+*			pMCSFilter		Pointer to MCS rate filter
+*
+*	/return	Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter.
+*
+*/
+/********************************************************************************************************************
+ *function:  This function will get the highest speed rate in input MCS set.
+ *   input:  struct ieee80211_device* 	ieee
+ *   	     u8* 			pMCSRateSet //Pointer to MCS rate bitmap
+ *   	     u8*			pMCSFilter //Pointer to MCS rate filter
+ *  return:  Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter
+ *  notice:
+  * *****************************************************************************************************************/
+u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter)
+{
+	u8		i, j;
+	u8		bitMap;
+	u8		mcsRate = 0;
+	u8		availableMcsRate[16];
+	if (pMCSRateSet == NULL || pMCSFilter == NULL)
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n");
+		return false;
+	}
+	for(i=0; i<16; i++)
+		availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i];
+
+	for(i = 0; i < 16; i++)
+	{
+		if(availableMcsRate[i] != 0)
+			break;
+	}
+	if(i == 16)
+		return false;
+
+	for(i = 0; i < 16; i++)
+	{
+		if(availableMcsRate[i] != 0)
+		{
+			bitMap = availableMcsRate[i];
+			for(j = 0; j < 8; j++)
+			{
+				if((bitMap%2) != 0)
+				{
+					if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate))
+						mcsRate = (8*i+j);
+				}
+				bitMap = bitMap>>1;
+			}
+		}
+	}
+	return (mcsRate|0x80);
+}
+
+
+
+/*
+**
+**1.Filter our operation rate set with AP's rate set
+**2.shall reference channel bandwidth, STBC, Antenna number
+**3.generate rate adative table for firmware
+**David 20060906
+**
+** \pHTSupportedCap: the connected STA's supported rate Capability element
+*/
+u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperateMCS)
+{
+
+	u8 i=0;
+
+	// filter out operational rate set not supported by AP, the lenth of it is 16
+	for(i=0;i<=15;i++){
+		pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i];
+	}
+
+
+	// TODO: adjust our operational rate set  according to our channel bandwidth, STBC and Antenna number
+
+	// TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet
+	// we also shall suggested the first start rate set according to our singal strength
+	HT_PickMCSRate(ieee, pOperateMCS);
+
+	// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
+	if(ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev))
+		pOperateMCS[1] = 0;
+
+	//
+	// For RTL819X, we support only MCS0~15.
+	// And also, we do not know how to use MCS32 now.
+	//
+	for(i=2; i<=15; i++)
+		pOperateMCS[i] = 0;
+
+	return true;
+}
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset);
+#if 0
+//I need move this function to other places, such as rx?
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void HTOnAssocRsp_wq(struct work_struct *work)
+{
+	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ht_onAssRsp);
+#else
+void HTOnAssocRsp_wq(struct ieee80211_device *ieee)
+{
+#endif
+#endif
+void HTOnAssocRsp(struct ieee80211_device *ieee)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+	PHT_CAPABILITY_ELE		pPeerHTCap = NULL;
+	PHT_INFORMATION_ELE		pPeerHTInfo = NULL;
+	u16	nMaxAMSDUSize = 0;
+	u8*	pMcsFilter = NULL;
+
+	static u8				EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33};		// For 11n EWC definition, 2007.07.17, by Emily
+	static u8				EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34};	// For 11n EWC definition, 2007.07.17, by Emily
+
+	if( pHTInfo->bCurrentHTSupport == false )
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n");
+		return;
+	}
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n");
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE));
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE));
+
+//	HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq");
+//	HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq");
+	//
+	if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap)))
+		pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]);
+	else
+		pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf);
+
+	if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo)))
+		pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]);
+	else
+		pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf);
+
+
+	////////////////////////////////////////////////////////
+	// Configurations:
+	////////////////////////////////////////////////////////
+	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE));
+//	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE));
+	// Config Supported Channel Width setting
+	//
+	HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset));
+
+//	if(pHTInfo->bCurBW40MHz == true)
+		pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false);
+
+	//
+	// Update short GI/ long GI setting
+	//
+	// TODO:
+	pHTInfo->bCurShortGI20MHz=
+		((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false);
+	pHTInfo->bCurShortGI40MHz=
+		((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false);
+
+	//
+	// Config TX STBC setting
+	//
+	// TODO:
+
+	//
+	// Config DSSS/CCK  mode in 40MHz mode
+	//
+	// TODO:
+	pHTInfo->bCurSuppCCK =
+		((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false);
+
+
+	//
+	// Config and configure A-MSDU setting
+	//
+	pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+
+	nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935;
+
+	if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize )
+		pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize;
+	else
+		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+
+	//
+	// Config A-MPDU setting
+	//
+	pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
+
+	// <1> Decide AMPDU Factor
+
+	// By Emily
+	if(!pHTInfo->bRegRT2RTAggregation)
+	{
+		// Decide AMPDU Factor according to protocol handshake
+		if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor)
+			pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+		else
+			pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+	}else
+	{
+		// Set MPDU density to 2 to Realtek AP, and set it to 0 for others
+		// Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily
+#if 0
+		osTmp= PacketGetElement( asocpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE);
+		if(osTmp.Length >= 5)	//00:e0:4c:02:00
+#endif
+		if (ieee->current_network.bssht.bdRT2RTAggregation)
+		{
+			if( ieee->pairwise_key_type != KEY_TYPE_NA)
+				// Realtek may set 32k in security mode and 64k for others
+				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+			else
+				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K;
+		}else
+		{
+			if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K)
+				pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor;
+			else
+				pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K;
+		}
+	}
+
+	// <2> Set AMPDU Minimum MPDU Start Spacing
+	// 802.11n 3.0 section 9.7d.3
+#if 1
+	if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
+		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	else
+		pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
+	if(ieee->pairwise_key_type != KEY_TYPE_NA )
+		pHTInfo->CurrentMPDUDensity 	= 7; // 8us
+#else
+	if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity)
+		pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	else
+		pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity;
+#endif
+	// Force TX AMSDU
+
+	// Lanhsin: mark for tmp to avoid deauth by ap from  s3
+	//if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0)
+	if(0)
+		{
+
+			pHTInfo->bCurrentAMPDUEnable = false;
+			pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE;
+			pHTInfo->ForcedAMSDUMaxSize = 7935;
+
+		pHTInfo->IOTAction |=  HT_IOT_ACT_TX_USE_AMSDU_8K;
+	}
+
+	// Rx Reorder Setting
+	pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable;
+
+	//
+	// Filter out unsupported HT rate for this AP
+	// Update RATR table
+	// This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism.
+	//
+
+	// Handle Ralink AP bad MCS rate set condition. Joseph.
+	// This fix the bug of Ralink AP. This may be removed in the future.
+	if(pPeerHTCap->MCS[0] == 0)
+		pPeerHTCap->MCS[0] = 0xff;
+
+	HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet);
+
+	//
+	// Config MIMO Power Save setting
+	//
+	pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave;
+	if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC)
+		pMcsFilter = MCS_FILTER_1SS;
+	else
+		pMcsFilter = MCS_FILTER_ALL;
+	//WB add for MCS8 bug
+//	pMcsFilter = MCS_FILTER_1SS;
+	ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter);
+	ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
+
+	//
+	// Config current operation mode.
+	//
+	pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
+
+
+
+}
+
+void HTSetConnectBwModeCallback(struct ieee80211_device* ieee);
+/********************************************************************************************************************
+ *function:  initialize HT info(struct PRT_HIGH_THROUGHPUT)
+ *   input:  struct ieee80211_device* 	ieee
+ *  output:  none
+ *  return:  none
+ *  notice: This function is called when *  (1) MPInitialization Phase *  (2) Receiving of Deauthentication from AP
+********************************************************************************************************************/
+// TODO: Should this funciton be called when receiving of Disassociation?
+void HTInitializeHTInfo(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+
+	//
+	// These parameters will be reset when receiving deauthentication packet
+	//
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __FUNCTION__);
+	pHTInfo->bCurrentHTSupport = false;
+
+	// 40MHz channel support
+	pHTInfo->bCurBW40MHz = false;
+	pHTInfo->bCurTxBW40MHz = false;
+
+	// Short GI support
+	pHTInfo->bCurShortGI20MHz = false;
+	pHTInfo->bCurShortGI40MHz = false;
+	pHTInfo->bForcedShortGI = false;
+
+	// CCK rate support
+	// This flag is set to true to support CCK rate by default.
+	// It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to
+	// 11N BSS.
+	pHTInfo->bCurSuppCCK = true;
+
+	// AMSDU related
+	pHTInfo->bCurrent_AMSDU_Support = false;
+	pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+	// AMPUD related
+	pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density;
+	pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+
+
+	// Initialize all of the parameters related to 11n
+	memset((void*)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap));
+	memset((void*)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo));
+	memset((void*)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf));
+	memset((void*)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf));
+
+	pHTInfo->bSwBwInProgress = false;
+	pHTInfo->ChnlOp = CHNLOP_NONE;
+
+	// Set default IEEE spec for Draft N
+	pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE;
+
+	// Realtek proprietary aggregation mode
+	pHTInfo->bCurrentRT2RTAggregation = false;
+	pHTInfo->bCurrentRT2RTLongSlotTime = false;
+	pHTInfo->IOTPeer = 0;
+	pHTInfo->IOTAction = 0;
+
+	//MCS rate initialized here
+	{
+		u8* RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]);
+		RegHTSuppRateSets[0] = 0xFF;	//support MCS 0~7
+		RegHTSuppRateSets[1] = 0xFF;	//support MCS 8~15
+		RegHTSuppRateSets[4] = 0x01;	//support MCS 32
+	}
+}
+/********************************************************************************************************************
+ *function:  initialize Bss HT structure(struct PBSS_HT)
+ *   input:  PBSS_HT pBssHT //to be initialized
+ *  output:  none
+ *  return:  none
+ *  notice: This function is called when initialize network structure
+********************************************************************************************************************/
+void HTInitializeBssDesc(PBSS_HT pBssHT)
+{
+
+	pBssHT->bdSupportHT = false;
+	memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf));
+	pBssHT->bdHTCapLen = 0;
+	memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf));
+	pBssHT->bdHTInfoLen = 0;
+
+	pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE;
+
+	pBssHT->bdRT2RTAggregation = false;
+	pBssHT->bdRT2RTLongSlotTime = false;
+}
+#if 0
+//below function has merged into ieee80211_network_init() in ieee80211_rx.c
+void
+HTParsingHTCapElement(
+	IN	PADAPTER		Adapter,
+	IN	OCTET_STRING	HTCapIE,
+	OUT	PRT_WLAN_BSS	pBssDesc
+)
+{
+	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
+
+	if( HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf) )
+	{
+		RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTCapElement(): HT Capability Element length is too long!\n") );
+		return;
+	}
+
+	// TODO: Check the correctness of HT Cap
+	//Print each field in detail. Driver should not print out this message by default
+	if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc)
+		HTDebugHTCapability(DBG_TRACE, Adapter, &HTCapIE, (pu8)"HTParsingHTCapElement()");
+
+	HTCapIE.Length = HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf)?\
+		sizeof(pBssDesc->BssHT.bdHTCapBuf):HTCapIE.Length;	//prevent from overflow
+
+	CopyMem(pBssDesc->BssHT.bdHTCapBuf, HTCapIE.Octet, HTCapIE.Length);
+	pBssDesc->BssHT.bdHTCapLen = HTCapIE.Length;
+
+}
+
+
+void
+HTParsingHTInfoElement(
+	PADAPTER		Adapter,
+	OCTET_STRING	HTInfoIE,
+	PRT_WLAN_BSS	pBssDesc
+)
+{
+	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
+
+	if( HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf))
+	{
+		RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTInfoElement(): HT Information Element length is too long!\n") );
+		return;
+	}
+
+	// TODO: Check the correctness of HT Info
+	//Print each field in detail. Driver should not print out this message by default
+	if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc)
+		HTDebugHTInfo(DBG_TRACE, Adapter, &HTInfoIE, (pu8)"HTParsingHTInfoElement()");
+
+	HTInfoIE.Length = HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)?\
+		sizeof(pBssDesc->BssHT.bdHTInfoBuf):HTInfoIE.Length;	//prevent from overflow
+
+	CopyMem( pBssDesc->BssHT.bdHTInfoBuf, HTInfoIE.Octet, HTInfoIE.Length);
+	pBssDesc->BssHT.bdHTInfoLen = HTInfoIE.Length;
+}
+
+/*
+  * Get HT related information from beacon and save it in BssDesc
+  *
+  * (1) Parse HTCap, and HTInfo, and record whether it is 11n AP
+  * (2) If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
+  * (3) Check whether peer is Realtek AP (for Realtek proprietary aggregation mode).
+  * Input:
+  * 		PADAPTER	Adapter
+  *
+  * Output:
+  *		PRT_TCB		BssDesc
+  *
+*/
+void HTGetValueFromBeaconOrProbeRsp(
+	PADAPTER			Adapter,
+	POCTET_STRING		pSRCmmpdu,
+	PRT_WLAN_BSS		bssDesc
+)
+{
+	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
+	PRT_HIGH_THROUGHPUT		pHTInfo = GET_HT_INFO(pMgntInfo);
+	OCTET_STRING				HTCapIE, HTInfoIE, HTRealtekAgg, mmpdu;
+	OCTET_STRING				BroadcomElement, CiscoElement;
+
+	mmpdu.Octet = pSRCmmpdu->Octet;
+	mmpdu.Length = pSRCmmpdu->Length;
+
+	//2Note:
+	//   Mark for IOT testing using  Linksys WRT350N, This AP does not contain WMM IE  when
+	//   it is configured at pure-N mode.
+	//	if(bssDesc->BssQos.bdQoSMode & QOS_WMM)
+	//
+
+	HTInitializeBssDesc (&bssDesc->BssHT);
+
+	//2<1> Parse HTCap, and HTInfo
+	// Get HT Capability IE: (1) Get IEEE Draft N IE or (2) Get EWC IE
+	HTCapIE = PacketGetElement(mmpdu, EID_HTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE);
+	if(HTCapIE.Length == 0)
+	{
+		HTCapIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_CAP, OUI_SUBTYPE_DONT_CARE);
+		if(HTCapIE.Length != 0)
+			bssDesc->BssHT.bdHTSpecVer= HT_SPEC_VER_EWC;
+	}
+	if(HTCapIE.Length != 0)
+		HTParsingHTCapElement(Adapter, HTCapIE, bssDesc);
+
+	// Get HT Information IE: (1) Get IEEE Draft N IE or (2) Get EWC IE
+	HTInfoIE = PacketGetElement(mmpdu, EID_HTInfo, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE);
+	if(HTInfoIE.Length == 0)
+	{
+		HTInfoIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_INFO, OUI_SUBTYPE_DONT_CARE);
+		if(HTInfoIE.Length != 0)
+				bssDesc->BssHT.bdHTSpecVer  = HT_SPEC_VER_EWC;
+	}
+	if(HTInfoIE.Length != 0)
+		HTParsingHTInfoElement(Adapter, HTInfoIE, bssDesc);
+
+	//2<2>If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
+	if(HTCapIE.Length != 0)
+	{
+		bssDesc->BssHT.bdSupportHT = true;
+		if(bssDesc->BssQos.bdQoSMode == QOS_DISABLE)
+			QosSetLegacyWMMParamWithHT(Adapter, bssDesc);
+	}
+	else
+	{
+		bssDesc->BssHT.bdSupportHT = false;
+	}
+
+	//2<3>Check whether the peer is Realtek AP/STA
+	if(pHTInfo->bRegRT2RTAggregation)
+	{
+		if(bssDesc->BssHT.bdSupportHT)
+		{
+			HTRealtekAgg = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE);
+			if(HTRealtekAgg.Length >=5 )
+			{
+				bssDesc->BssHT.bdRT2RTAggregation = true;
+
+				if((HTRealtekAgg.Octet[4]==1) && (HTRealtekAgg.Octet[5] & 0x02))
+					bssDesc->BssHT.bdRT2RTLongSlotTime = true;
+			}
+		}
+	}
+
+	//
+	// 2008/01/25 MH Get Broadcom AP IE for manamgent frame CCK rate problem.
+	// AP can not receive CCK managemtn from from 92E.
+	//
+
+	// Initialize every new bss broadcom cap exist as false..
+	bssDesc->bBroadcomCapExist= false;
+
+	if(HTCapIE.Length != 0 || HTInfoIE.Length != 0)
+	{
+		u4Byte	Length = 0;
+
+		FillOctetString(BroadcomElement, NULL, 0);
+
+		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_1, OUI_SUBTYPE_DONT_CARE);
+		Length += BroadcomElement.Length;
+		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_2, OUI_SUBTYPE_DONT_CARE);
+		Length += BroadcomElement.Length;
+		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_3, OUI_SUBTYPE_DONT_CARE);
+		Length += BroadcomElement.Length;
+
+		if(Length > 0)
+			bssDesc->bBroadcomCapExist = true;
+	}
+
+
+	// For Cisco IOT issue
+	CiscoElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_CISCO_IE, OUI_SUBTYPE_DONT_CARE);
+	if(CiscoElement.Length != 0){ // 3: 0x00, 0x40, 0x96 ....
+		bssDesc->bCiscoCapExist = true;
+	}else{
+		bssDesc->bCiscoCapExist = false;
+	}
+}
+
+
+#endif
+/********************************************************************************************************************
+ *function:  initialize Bss HT structure(struct PBSS_HT)
+ *   input:  struct ieee80211_device 	*ieee
+ *   	     struct ieee80211_network 	*pNetwork //usually current network we are live in
+ *  output:  none
+ *  return:  none
+ *  notice: This function should ONLY be called before association
+********************************************************************************************************************/
+void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
+{
+	PRT_HIGH_THROUGHPUT		pHTInfo = ieee->pHTInfo;
+//	u16						nMaxAMSDUSize;
+//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+//	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
+//	u8*	pMcsFilter;
+	u8	bIOTAction = 0;
+
+	//
+	//  Save Peer Setting before Association
+	//
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __FUNCTION__);
+	/*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/
+//	if( pHTInfo->bEnableHT &&  pNetwork->bssht.bdSupportHT)
+	if (pNetwork->bssht.bdSupportHT)
+	{
+		pHTInfo->bCurrentHTSupport = true;
+		pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer;
+
+		// Save HTCap and HTInfo information Element
+		if(pNetwork->bssht.bdHTCapLen > 0 && 	pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf))
+			memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen);
+
+		if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf))
+			memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen);
+
+		// Check whether RT to RT aggregation mode is enabled
+		if(pHTInfo->bRegRT2RTAggregation)
+		{
+			pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation;
+			pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime;
+		}
+		else
+		{
+			pHTInfo->bCurrentRT2RTAggregation = false;
+			pHTInfo->bCurrentRT2RTLongSlotTime = false;
+		}
+
+		// Determine the IOT Peer Vendor.
+		HTIOTPeerDetermine(ieee);
+
+		// Decide IOT Action
+		// Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided
+		pHTInfo->IOTAction = 0;
+		bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14;
+
+		bIOTAction = HTIOTActIsDisableMCS15(ieee);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15;
+
+		bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS;
+
+
+		bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO;
+
+		bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M;
+
+		bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid);
+		if(bIOTAction)
+			pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC;
+
+
+	}
+	else
+	{
+		pHTInfo->bCurrentHTSupport = false;
+		pHTInfo->bCurrentRT2RTAggregation = false;
+		pHTInfo->bCurrentRT2RTLongSlotTime = false;
+
+		pHTInfo->IOTAction = 0;
+	}
+
+}
+
+void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, 	struct ieee80211_network * pNetwork)
+{
+	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
+//	PHT_CAPABILITY_ELE		pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf;
+	PHT_INFORMATION_ELE		pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf;
+
+	if(pHTInfo->bCurrentHTSupport)
+	{
+		//
+		// Config current operation mode.
+		//
+		if(pNetwork->bssht.bdHTInfoLen != 0)
+			pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode;
+
+		//
+		// <TODO: Config according to OBSS non-HT STA present!!>
+		//
+	}
+}
+
+void HTUseDefaultSetting(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+//	u8	regBwOpMode;
+
+	if(pHTInfo->bEnableHT)
+	{
+		pHTInfo->bCurrentHTSupport = true;
+
+		pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK;
+
+		pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz;
+
+		pHTInfo->bCurShortGI20MHz= pHTInfo->bRegShortGI20MHz;
+
+		pHTInfo->bCurShortGI40MHz= pHTInfo->bRegShortGI40MHz;
+
+		pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support;
+
+		pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize;
+
+		pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable;
+
+		pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor;
+
+		pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity;
+
+		// Set BWOpMode register
+
+		//update RATR index0
+		HTFilterMCSRate(ieee, ieee->Regdot11HTOperationalRateSet, ieee->dot11HTOperationalRateSet);
+	//function below is not implemented at all. WB
+#ifdef TODO
+		Adapter->HalFunc.InitHalRATRTableHandler( Adapter, &pMgntInfo->dot11OperationalRateSet, pMgntInfo->dot11HTOperationalRateSet);
+#endif
+		ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, MCS_FILTER_ALL);
+		ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate;
+
+	}
+	else
+	{
+		pHTInfo->bCurrentHTSupport = false;
+	}
+	return;
+}
+/********************************************************************************************************************
+ *function:  check whether HT control field exists
+ *   input:  struct ieee80211_device 	*ieee
+ *   	     u8*			pFrame //coming skb->data
+ *  output:  none
+ *  return:  return true if HT control field exists(false otherwise)
+ *  notice:
+********************************************************************************************************************/
+u8 HTCCheck(struct ieee80211_device* ieee, u8*	pFrame)
+{
+	if(ieee->pHTInfo->bCurrentHTSupport)
+	{
+		if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n");
+			return true;
+		}
+	}
+	return false;
+}
+
+//
+// This function set bandwidth mode in protocol layer.
+//
+void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+//	u32 flags = 0;
+
+	if(pHTInfo->bRegBW40MHz == false)
+		return;
+
+
+
+	// To reduce dummy operation
+//	if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) ||
+//	   (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset))
+//		return;
+
+//	spin_lock_irqsave(&(ieee->bw_spinlock), flags);
+	if(pHTInfo->bSwBwInProgress) {
+//		spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
+		return;
+	}
+	//if in half N mode, set to 20M bandwidth please 09.08.2008 WB.
+	if(Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)))
+	 {
+	 		// Handle Illegal extention channel offset!!
+		if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER)
+			Offset = HT_EXTCHNL_OFFSET_NO_EXT;
+		if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) {
+			pHTInfo->bCurBW40MHz = true;
+			pHTInfo->CurSTAExtChnlOffset = Offset;
+		} else {
+			pHTInfo->bCurBW40MHz = false;
+			pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
+		}
+	} else {
+		pHTInfo->bCurBW40MHz = false;
+		pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT;
+	}
+
+	pHTInfo->bSwBwInProgress = true;
+
+	// TODO: 2007.7.13 by Emily Wait 2000ms  in order to garantee that switching
+	//   bandwidth is executed after scan is finished. It is a temporal solution
+	//   because software should ganrantee the last operation of switching bandwidth
+	//   is executed properlly.
+	HTSetConnectBwModeCallback(ieee);
+
+//	spin_unlock_irqrestore(&(ieee->bw_spinlock), flags);
+}
+
+void HTSetConnectBwModeCallback(struct ieee80211_device* ieee)
+{
+	PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
+
+	IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __FUNCTION__);
+
+	if(pHTInfo->bCurBW40MHz)
+	{
+		if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER)
+			ieee->set_chan(ieee->dev, ieee->current_network.channel+2);
+		else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER)
+			ieee->set_chan(ieee->dev, ieee->current_network.channel-2);
+		else
+			ieee->set_chan(ieee->dev, ieee->current_network.channel);
+
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset);
+	} else {
+		ieee->set_chan(ieee->dev, ieee->current_network.channel);
+		ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
+	}
+
+	pHTInfo->bSwBwInProgress = false;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+//EXPORT_SYMBOL_NOVERS(HTUpdateSelfAndPeerSetting);
+#else
+//EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting);
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h
new file mode 100644
index 0000000..a50ee0e
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h
@@ -0,0 +1,748 @@
+#ifndef __INC_QOS_TYPE_H
+#define __INC_QOS_TYPE_H
+
+#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
+
+#define	MAX_WMMELE_LENGTH	64
+
+//
+// QoS mode.
+// enum 0, 1, 2, 4: since we can use the OR(|) operation.
+//
+// QOS_MODE is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
+//typedef	enum _QOS_MODE{
+//	QOS_DISABLE		= 0,
+//	QOS_WMM			= 1,
+//	QOS_EDCA			= 2,
+//	QOS_HCCA			= 4,
+//}QOS_MODE,*PQOS_MODE;
+//
+typedef u32 QOS_MODE, *PQOS_MODE;
+#define QOS_DISABLE		0
+#define QOS_WMM			1
+#define QOS_WMMSA		2
+#define QOS_EDCA		4
+#define QOS_HCCA		8
+#define QOS_WMM_UAPSD		16   //WMM Power Save, 2006-06-14 Isaiah
+
+#define AC_PARAM_SIZE	4
+#define WMM_PARAM_ELE_BODY_LEN	18
+
+//
+// QoS ACK Policy Field Values
+// Ref: WMM spec 2.1.6: QoS Control Field, p.10.
+//
+typedef	enum _ACK_POLICY{
+	eAckPlc0_ACK		= 0x00,
+	eAckPlc1_NoACK		= 0x01,
+}ACK_POLICY,*PACK_POLICY;
+
+#define WMM_PARAM_ELEMENT_SIZE	(8+(4*AC_PARAM_SIZE))
+#if 0
+#define GET_QOS_CTRL(_pStart)	ReadEF2Byte((u8 *)(_pStart) + 24)
+#define SET_QOS_CTRL(_pStart, _value)	WriteEF2Byte((u8 *)(_pStart) + 24, _value)
+
+// WMM control field.
+#define GET_QOS_CTRL_WMM_UP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 3))
+#define SET_QOS_CTRL_WMM_UP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 3, (u8)(_value))
+
+#define GET_QOS_CTRL_WMM_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_WMM_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_WMM_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_WMM_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+// 802.11e control field (by STA, data)
+#define GET_QOS_CTRL_STA_DATA_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
+#define SET_QOS_CTRL_STA_DATA_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_TXOP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
+#define SET_QOS_CTRL_STA_DATA_TXOP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
+
+#define GET_QOS_CTRL_STA_DATA_QSIZE(_pStart)	GET_QOS_CTRL_STA_DATA_TXOP(_pStart)
+#define SET_QOS_CTRL_STA_DATA_QSIZE(_pStart, _value)	SET_QOS_CTRL_STA_DATA_TXOP(_pStart)
+
+// 802.11e control field (by HC, data)
+#define GET_QOS_CTRL_HC_DATA_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
+#define SET_QOS_CTRL_HC_DATA_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_DATA_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_HC_DATA_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
+#define SET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
+
+// 802.11e control field (by HC, CFP)
+#define GET_QOS_CTRL_HC_CFP_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
+#define SET_QOS_CTRL_HC_CFP_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_CFP_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
+#define SET_QOS_CTRL_HC_CFP_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
+#define SET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
+
+#define GET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
+#define SET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
+
+#define SET_WMM_QOS_INFO_FIELD(_pStart, _val)	WriteEF1Byte(_pStart, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart)	LE_BITS_TO_1BYTE(_pStart, 0, 4)
+#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 7, 1)
+#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 0, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 1, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 2, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 3, 1)
+#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val)
+
+#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart)	LE_BITS_TO_1BYTE(_pStart, 5, 2)
+#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val)
+
+
+#define WMM_INFO_ELEMENT_SIZE	7
+
+#define GET_WMM_INFO_ELE_OUI(_pStart)	((u8 *)(_pStart))
+#define SET_WMM_INFO_ELE_OUI(_pStart, _pVal)	PlatformMoveMemory(_pStart, _pVal, 3);
+
+#define GET_WMM_INFO_ELE_OUI_TYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+3) ) )
+#define SET_WMM_INFO_ELE_OUI_TYPE(_pStart, _val)	( *((u8 *)(_pStart)+3) = EF1Byte(_val) )
+
+#define GET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+4) ) )
+#define SET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart, _val)	( *((u8 *)(_pStart)+4) = EF1Byte(_val) )
+
+#define GET_WMM_INFO_ELE_VERSION(_pStart)	( EF1Byte( *((u8 *)(_pStart)+5) ) )
+#define SET_WMM_INFO_ELE_VERSION(_pStart, _val)	( *((u8 *)(_pStart)+5) = EF1Byte(_val) )
+
+#define GET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart)	( EF1Byte( *((u8 *)(_pStart)+6) ) )
+#define SET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart, _val)	( *((u8 *)(_pStart)+6) = EF1Byte(_val) )
+
+
+
+#define GET_WMM_AC_PARAM_AIFSN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 4) )
+#define SET_WMM_AC_PARAM_AIFSN(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 0, 4, _val)
+
+#define GET_WMM_AC_PARAM_ACM(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 4, 1) )
+#define SET_WMM_AC_PARAM_ACM(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 4, 1, _val)
+
+#define GET_WMM_AC_PARAM_ACI(_pStart)		( (u8)LE_BITS_TO_4BYTE(_pStart, 5, 2) )
+#define SET_WMM_AC_PARAM_ACI(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 5, 2, _val)
+
+#define GET_WMM_AC_PARAM_ACI_AIFSN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 8) )
+#define SET_WMM_AC_PARAM_ACI_AIFSN(_pStart, _val)	SET_BTIS_TO_LE_4BYTE(_pStart, 0, 8, _val)
+
+#define GET_WMM_AC_PARAM_ECWMIN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 8, 4) )
+#define SET_WMM_AC_PARAM_ECWMIN(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 8, 4, _val)
+
+#define GET_WMM_AC_PARAM_ECWMAX(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 12, 4) )
+#define SET_WMM_AC_PARAM_ECWMAX(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 12, 4, _val)
+
+#define GET_WMM_AC_PARAM_TXOP_LIMIT(_pStart)		( (u16)LE_BITS_TO_4BYTE(_pStart, 16, 16) )
+#define SET_WMM_AC_PARAM_TXOP_LIMIT(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 16, 16, _val)
+
+
+
+
+#define GET_WMM_PARAM_ELE_OUI(_pStart)	((u8 *)(_pStart))
+#define SET_WMM_PARAM_ELE_OUI(_pStart, _pVal)	PlatformMoveMemory(_pStart, _pVal, 3)
+
+#define GET_WMM_PARAM_ELE_OUI_TYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+3) ) )
+#define SET_WMM_PARAM_ELE_OUI_TYPE(_pStart, _val)	( *((u8 *)(_pStart)+3) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+4) ) )
+#define SET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart, _val)	( *((u8 *)(_pStart)+4) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_VERSION(_pStart)	( EF1Byte( *((u8 *)(_pStart)+5) ) )
+#define SET_WMM_PARAM_ELE_VERSION(_pStart, _val)	( *((u8 *)(_pStart)+5) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart)	( EF1Byte( *((u8 *)(_pStart)+6) ) )
+#define SET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart, _val)	( *((u8 *)(_pStart)+6) = EF1Byte(_val) )
+
+#define GET_WMM_PARAM_ELE_AC_PARAM(_pStart)	( (u8 *)(_pStart)+8 )
+#define SET_WMM_PARAM_ELE_AC_PARAM(_pStart, _pVal) PlatformMoveMemory((_pStart)+8, _pVal, 16)
+#endif
+
+//
+// QoS Control Field
+// Ref:
+//	1. WMM spec 2.1.6: QoS Control Field, p.9.
+//	2. 802.11e/D13.0 7.1.3.5, p.26.
+//
+typedef	union _QOS_CTRL_FIELD{
+	u8	charData[2];
+	u16	shortData;
+
+	// WMM spec
+	struct
+	{
+		u8		UP:3;
+		u8		usRsvd1:1;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd2:1;
+		u8		ucRsvdByte;
+	}WMM;
+
+	// 802.11e: QoS data type frame sent by non-AP QSTAs.
+	struct
+	{
+		u8		TID:4;
+		u8		bIsQsize:1;// 0: BIT[8:15] is TXOP Duration Requested, 1: BIT[8:15] is Queue Size.
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		TxopOrQsize;	// (BIT4=0)TXOP Duration Requested or (BIT4=1)Queue Size.
+	}BySta;
+
+	// 802.11e: QoS data, QoS Null, and QoS Data+CF-Ack frames sent by HC.
+	struct
+	{
+		u8		TID:4;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		PSBufState;		// QAP PS Buffer State.
+	}ByHc_Data;
+
+	// 802.11e: QoS (+) CF-Poll frames sent by HC.
+	struct
+	{
+		u8		TID:4;
+		u8		EOSP:1;
+		u8		AckPolicy:2;
+		u8		usRsvd:1;
+		u8		TxopLimit;		// TXOP Limit.
+	}ByHc_CFP;
+
+}QOS_CTRL_FIELD, *PQOS_CTRL_FIELD;
+
+
+//
+// QoS Info Field
+// Ref:
+//	1. WMM spec 2.2.1: WME Information Element, p.11.
+//	2. 8185 QoS code: QOS_INFO [def. in QoS_mp.h]
+//
+typedef	union _QOS_INFO_FIELD{
+	u8	charData;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucReserved:4;
+	}WMM;
+
+	struct
+	{
+		//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
+		u8		ucAC_VO_UAPSD:1;
+		u8		ucAC_VI_UAPSD:1;
+		u8		ucAC_BE_UAPSD:1;
+		u8		ucAC_BK_UAPSD:1;
+		u8		ucReserved1:1;
+		u8		ucMaxSPLen:2;
+		u8		ucReserved2:1;
+
+	}ByWmmPsSta;
+
+	struct
+	{
+		//Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah
+		u8		ucParameterSetCount:4;
+		u8		ucReserved:3;
+		u8		ucApUapsd:1;
+	}ByWmmPsAp;
+
+	struct
+	{
+		u8		ucAC3_UAPSD:1;
+		u8		ucAC2_UAPSD:1;
+		u8		ucAC1_UAPSD:1;
+		u8		ucAC0_UAPSD:1;
+		u8		ucQAck:1;
+		u8		ucMaxSPLen:2;
+		u8		ucMoreDataAck:1;
+	} By11eSta;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucReserved:1;
+	} By11eAp;
+
+	struct
+	{
+		u8		ucReserved1:4;
+		u8		ucQAck:1;
+		u8		ucReserved2:2;
+		u8		ucMoreDataAck:1;
+	} ByWmmsaSta;
+
+	struct
+	{
+		u8		ucReserved1:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucReserved2:1;
+	} ByWmmsaAp;
+
+	struct
+	{
+		u8		ucAC3_UAPSD:1;
+		u8		ucAC2_UAPSD:1;
+		u8		ucAC1_UAPSD:1;
+		u8		ucAC0_UAPSD:1;
+		u8		ucQAck:1;
+		u8		ucMaxSPLen:2;
+		u8		ucMoreDataAck:1;
+	} ByAllSta;
+
+	struct
+	{
+		u8		ucParameterSetCount:4;
+		u8		ucQAck:1;
+		u8		ucQueueReq:1;
+		u8		ucTXOPReq:1;
+		u8		ucApUapsd:1;
+	} ByAllAp;
+
+}QOS_INFO_FIELD, *PQOS_INFO_FIELD;
+
+#if 0
+//
+// WMM Information Element
+// Ref: WMM spec 2.2.1: WME Information Element, p.10.
+//
+typedef struct _WMM_INFO_ELEMENT{
+//	u8			ElementID;
+//	u8			Length;
+	u8			OUI[3];
+	u8			OUI_Type;
+	u8			OUI_SubType;
+	u8			Version;
+	QOS_INFO_FIELD	QosInfo;
+}WMM_INFO_ELEMENT, *PWMM_INFO_ELEMENT;
+#endif
+
+//
+// ACI to AC coding.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
+//
+// AC_CODING is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko.
+//typedef	enum _AC_CODING{
+//	AC0_BE	= 0,		// ACI: 0x00	// Best Effort
+//	AC1_BK	= 1,		// ACI: 0x01	// Background
+//	AC2_VI	= 2,		// ACI: 0x10	// Video
+//	AC3_VO	= 3,		// ACI: 0x11	// Voice
+//	AC_MAX = 4,		// Max: define total number; Should not to be used as a real enum.
+//}AC_CODING,*PAC_CODING;
+//
+typedef u32 AC_CODING;
+#define AC0_BE	0		// ACI: 0x00	// Best Effort
+#define AC1_BK	1		// ACI: 0x01	// Background
+#define AC2_VI	2		// ACI: 0x10	// Video
+#define AC3_VO	3		// ACI: 0x11	// Voice
+#define AC_MAX	4		// Max: define total number; Should not to be used as a real enum.
+
+//
+// ACI/AIFSN Field.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
+//
+typedef	union _ACI_AIFSN{
+	u8	charData;
+
+	struct
+	{
+		u8	AIFSN:4;
+		u8	ACM:1;
+		u8	ACI:2;
+		u8	Reserved:1;
+	}f;	// Field
+}ACI_AIFSN, *PACI_AIFSN;
+
+//
+// ECWmin/ECWmax field.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
+//
+typedef	union _ECW{
+	u8	charData;
+	struct
+	{
+		u8	ECWmin:4;
+		u8	ECWmax:4;
+	}f;	// Field
+}ECW, *PECW;
+
+//
+// AC Parameters Record Format.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
+//
+typedef	union _AC_PARAM{
+	u32	longData;
+	u8	charData[4];
+
+	struct
+	{
+		ACI_AIFSN	AciAifsn;
+		ECW		Ecw;
+		u16		TXOPLimit;
+	}f;	// Field
+}AC_PARAM, *PAC_PARAM;
+
+
+
+//
+// QoS element subtype
+//
+typedef	enum _QOS_ELE_SUBTYPE{
+	QOSELE_TYPE_INFO	= 0x00,		// 0x00: Information element
+	QOSELE_TYPE_PARAM	= 0x01,		// 0x01: parameter element
+}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE;
+
+
+//
+// Direction Field Values.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.18.
+//
+typedef	enum _DIRECTION_VALUE{
+	DIR_UP			= 0,		// 0x00	// UpLink
+	DIR_DOWN		= 1,		// 0x01	// DownLink
+	DIR_DIRECT		= 2,		// 0x10	// DirectLink
+	DIR_BI_DIR		= 3,		// 0x11	// Bi-Direction
+}DIRECTION_VALUE,*PDIRECTION_VALUE;
+
+
+//
+// TS Info field in WMM TSPEC Element.
+// Ref:
+//	1. WMM spec 2.2.11: WME TSPEC Element, p.18.
+//	2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h]
+//
+typedef union _QOS_TSINFO{
+	u8		charData[3];
+	struct {
+		u8		ucTrafficType:1;			//WMM is reserved
+		u8		ucTSID:4;
+		u8		ucDirection:2;
+		u8		ucAccessPolicy:2;	//WMM: bit8=0, bit7=1
+		u8		ucAggregation:1;		//WMM is reserved
+		u8		ucPSB:1;				//WMMSA is APSD
+		u8		ucUP:3;
+		u8		ucTSInfoAckPolicy:2;		//WMM is reserved
+		u8		ucSchedule:1;			//WMM is reserved
+		u8		ucReserved:7;
+	}field;
+}QOS_TSINFO, *PQOS_TSINFO;
+
+//
+// WMM TSPEC Body.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
+//
+typedef union _TSPEC_BODY{
+	u8		charData[55];
+
+	struct
+	{
+		QOS_TSINFO	TSInfo;	//u8	TSInfo[3];
+		u16	NominalMSDUsize;
+		u16	MaxMSDUsize;
+		u32	MinServiceItv;
+		u32	MaxServiceItv;
+		u32	InactivityItv;
+		u32	SuspenItv;
+		u32	ServiceStartTime;
+		u32	MinDataRate;
+		u32	MeanDataRate;
+		u32	PeakDataRate;
+		u32	MaxBurstSize;
+		u32	DelayBound;
+		u32	MinPhyRate;
+		u16	SurplusBandwidthAllowance;
+		u16	MediumTime;
+	} f;	// Field
+}TSPEC_BODY, *PTSPEC_BODY;
+
+
+//
+// WMM TSPEC Element.
+// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16.
+//
+typedef struct _WMM_TSPEC{
+	u8		ID;
+	u8		Length;
+	u8		OUI[3];
+	u8		OUI_Type;
+	u8		OUI_SubType;
+	u8		Version;
+	TSPEC_BODY	Body;
+} WMM_TSPEC, *PWMM_TSPEC;
+
+//
+// ACM implementation method.
+// Annie, 2005-12-13.
+//
+typedef	enum _ACM_METHOD{
+	eAcmWay0_SwAndHw		= 0,		// By SW and HW.
+	eAcmWay1_HW			= 1,		// By HW.
+	eAcmWay2_SW			= 2,		// By SW.
+}ACM_METHOD,*PACM_METHOD;
+
+
+typedef struct _ACM{
+//	u8		RegEnableACM;
+	u64		UsedTime;
+	u64		MediumTime;
+	u8		HwAcmCtl;	// TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B).
+}ACM, *PACM;
+
+typedef	u8		AC_UAPSD, *PAC_UAPSD;
+
+#define	GET_VO_UAPSD(_apsd) ((_apsd) & BIT0)
+#define	SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0)
+
+#define	GET_VI_UAPSD(_apsd) ((_apsd) & BIT1)
+#define	SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1)
+
+#define	GET_BK_UAPSD(_apsd) ((_apsd) & BIT2)
+#define	SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2)
+
+#define	GET_BE_UAPSD(_apsd) ((_apsd) & BIT3)
+#define	SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3)
+
+
+//typedef struct _TCLASS{
+// TODO
+//} TCLASS, *PTCLASS;
+typedef union _QOS_TCLAS{
+
+	struct _TYPE_GENERAL{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+	} TYPE_GENERAL;
+
+	struct _TYPE0_ETH{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8		SrcAddr[6];
+		u8		DstAddr[6];
+		u16		Type;
+	} TYPE0_ETH;
+
+	struct _TYPE1_IPV4{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8 		Version;
+		u8		SrcIP[4];
+		u8		DstIP[4];
+		u16		SrcPort;
+		u16		DstPort;
+		u8		DSCP;
+		u8		Protocol;
+		u8		Reserved;
+	} TYPE1_IPV4;
+
+	struct _TYPE1_IPV6{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u8 		Version;
+		u8		SrcIP[16];
+		u8		DstIP[16];
+		u16		SrcPort;
+		u16		DstPort;
+		u8		FlowLabel[3];
+	} TYPE1_IPV6;
+
+	struct _TYPE2_8021Q{
+		u8		Priority;
+		u8 		ClassifierType;
+		u8 		Mask;
+		u16		TagType;
+	} TYPE2_8021Q;
+} QOS_TCLAS, *PQOS_TCLAS;
+
+//typedef struct _WMM_TSTREAM{
+//
+//- TSPEC
+//- AC (which to mapping)
+//} WMM_TSTREAM, *PWMM_TSTREAM;
+typedef struct _QOS_TSTREAM{
+	u8			AC;
+	WMM_TSPEC		TSpec;
+	QOS_TCLAS		TClass;
+} QOS_TSTREAM, *PQOS_TSTREAM;
+
+//typedef struct _U_APSD{
+//- TriggerEnable [4]
+//- MaxSPLength
+//- HighestAcBuffered
+//} U_APSD, *PU_APSD;
+
+//joseph TODO:
+//	UAPSD function should be implemented by 2 data structure
+//	"Qos control field" and "Qos info field"
+//typedef struct _QOS_UAPSD{
+//	u8			bTriggerEnable[4];
+//	u8 			MaxSPLength;
+//	u8			HighestBufAC;
+//} QOS_UAPSD, *PQOS_APSD;
+
+//----------------------------------------------------------------------------
+//      802.11 Management frame Status Code field
+//----------------------------------------------------------------------------
+typedef struct _OCTET_STRING{
+        u8        	*Octet;
+        u16             Length;
+}OCTET_STRING, *POCTET_STRING;
+#if 0
+#define FillOctetString(_os,_octet,_len)             \
+        (_os).Octet=(u8 *)(_octet);                  \
+        (_os).Length=(_len);
+
+#define WMM_ELEM_HDR_LEN        		     6
+#define WMMElemSkipHdr(_osWMMElem)                   \
+        (_osWMMElem).Octet += WMM_ELEM_HDR_LEN;      \
+        (_osWMMElem).Length -= WMM_ELEM_HDR_LEN;
+#endif
+//
+// STA QoS data.
+// Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h]
+//
+typedef struct _STA_QOS{
+	//DECLARE_RT_OBJECT(STA_QOS);
+	u8				WMMIEBuf[MAX_WMMELE_LENGTH];
+	u8*				WMMIE;
+
+	// Part 1. Self QoS Mode.
+	QOS_MODE			QosCapability; //QoS Capability, 2006-06-14 Isaiah
+	QOS_MODE			CurrentQosMode;
+
+	// For WMM Power Save Mode :
+	// ACs are trigger/delivery enabled or legacy power save enabled. 2006-06-13 Isaiah
+	AC_UAPSD			b4ac_Uapsd;  //VoUapsd(bit0), ViUapsd(bit1),  BkUapsd(bit2), BeUapsd(bit3),
+	AC_UAPSD			Curr4acUapsd;
+	u8				bInServicePeriod;
+	u8				MaxSPLength;
+	int 				NumBcnBeforeTrigger;
+
+	// Part 2. EDCA Parameter (perAC)
+	u8 *				pWMMInfoEle;
+	u8				WMMParamEle[WMM_PARAM_ELEMENT_SIZE];
+	u8				WMMPELength;
+
+	// <Bruce_Note>
+	//2 ToDo: remove the Qos Info Field and replace it by the above WMM Info element.
+	// By Bruce, 2008-01-30.
+	// Part 2. EDCA Parameter (perAC)
+	QOS_INFO_FIELD			QosInfoField_STA; 	// Maintained by STA
+	QOS_INFO_FIELD			QosInfoField_AP;	// Retrieved from AP
+
+	AC_PARAM			CurAcParameters[4];
+
+	// Part 3. ACM
+	ACM				acm[4];
+	ACM_METHOD			AcmMethod;
+
+	// Part 4. Per TID (Part 5: TCLASS will be described by TStream)
+	QOS_TSTREAM			TStream[16];
+	WMM_TSPEC			TSpec;
+
+	u32				QBssWirelessMode;
+
+	// No Ack Setting
+	u8				bNoAck;
+
+	// Enable/Disable Rx immediate BA capability.
+	u8				bEnableRxImmBA;
+
+}STA_QOS, *PSTA_QOS;
+
+//
+// BSS QOS data.
+// Ref: BssDscr in 8185 code. [def. in BssDscr.h]
+//
+typedef struct _BSS_QOS{
+	QOS_MODE		bdQoSMode;
+
+	u8			bdWMMIEBuf[MAX_WMMELE_LENGTH];
+	u8*		bdWMMIE;
+
+	QOS_ELE_SUBTYPE		EleSubType;
+
+	u8 *			pWMMInfoEle;
+	u8 *			pWMMParamEle;
+
+	QOS_INFO_FIELD		QosInfoField;
+	AC_PARAM		AcParameter[4];
+}BSS_QOS, *PBSS_QOS;
+
+
+//
+// Ref: sQoSCtlLng and QoSCtl definition in 8185 QoS code.
+//#define QoSCtl   ((	(Adapter->bRegQoS) && (Adapter->dot11QoS.QoSMode &(QOS_EDCA|QOS_HCCA))	  )  ?sQoSCtlLng:0)
+//
+#define sQoSCtlLng			2
+#define	QOS_CTRL_LEN(_QosMode)		((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0)
+
+
+//Added by joseph
+//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
+//#define UP2AC(up)			((up<3)?((up==0)?1:0):(up>>1))
+#define IsACValid(ac)			((ac<=7 )?true:false )
+
+#endif // #ifndef __INC_QOS_TYPE_H
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h
new file mode 100644
index 0000000..baaac21
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h
@@ -0,0 +1,56 @@
+#ifndef _TSTYPE_H_
+#define _TSTYPE_H_
+#include "rtl819x_Qos.h"
+#define TS_SETUP_TIMEOUT	60  // In millisecond
+#define TS_INACT_TIMEOUT	60
+#define TS_ADDBA_DELAY		60
+
+#define TOTAL_TS_NUM		16
+#define TCLAS_NUM		4
+
+// This define the Tx/Rx directions
+typedef enum _TR_SELECT {
+	TX_DIR = 0,
+	RX_DIR = 1,
+} TR_SELECT, *PTR_SELECT;
+
+typedef struct _TS_COMMON_INFO{
+	struct list_head		List;
+	struct timer_list		SetupTimer;
+	struct timer_list		InactTimer;
+	u8				Addr[6];
+	TSPEC_BODY			TSpec;
+	QOS_TCLAS			TClass[TCLAS_NUM];
+	u8				TClasProc;
+	u8				TClasNum;
+} TS_COMMON_INFO, *PTS_COMMON_INFO;
+
+typedef struct _TX_TS_RECORD{
+	TS_COMMON_INFO		TsCommonInfo;
+	u16				TxCurSeq;
+	BA_RECORD			TxPendingBARecord;  	// For BA Originator
+	BA_RECORD			TxAdmittedBARecord;	// For BA Originator
+//	QOS_DL_RECORD		DLRecord;
+	u8				bAddBaReqInProgress;
+	u8				bAddBaReqDelayed;
+	u8				bUsingBa;
+	struct timer_list		TsAddBaTimer;
+	u8				num;
+} TX_TS_RECORD, *PTX_TS_RECORD;
+
+typedef struct _RX_TS_RECORD {
+	TS_COMMON_INFO		TsCommonInfo;
+	u16				RxIndicateSeq;
+	u16				RxTimeoutIndicateSeq;
+	struct list_head		RxPendingPktList;
+	struct timer_list		RxPktPendingTimer;
+	BA_RECORD			RxAdmittedBARecord;	 // For BA Recepient
+	u16				RxLastSeqNum;
+	u8				RxLastFragNum;
+	u8				num;
+//	QOS_DL_RECORD		DLRecord;
+} RX_TS_RECORD, *PRX_TS_RECORD;
+
+
+#endif
+
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
new file mode 100644
index 0000000..2816b60
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c
@@ -0,0 +1,659 @@
+#include "ieee80211.h"
+#include <linux/etherdevice.h>
+#include "rtl819x_TS.h"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define list_for_each_entry_safe(pos, n, head, member) \
+	for (pos = list_entry((head)->next, typeof(*pos), member), \
+		n = list_entry(pos->member.next, typeof(*pos), member); \
+		&pos->member != (head); \
+		pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif
+void TsSetupTimeOut(unsigned long data)
+{
+	// Not implement yet
+	// This is used for WMMSA and ACM , that would send ADDTSReq frame.
+}
+
+void TsInactTimeout(unsigned long data)
+{
+	// Not implement yet
+	// This is used for WMMSA and ACM.
+	// This function would be call when TS is no Tx/Rx for some period of time.
+}
+
+/********************************************************************************************************************
+ *function:  I still not understand this function, so wait for further implementation
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:
+********************************************************************************************************************/
+#if 1
+void RxPktPendingTimeout(unsigned long data)
+{
+	PRX_TS_RECORD	pRxTs = (PRX_TS_RECORD)data;
+	struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]);
+
+	PRX_REORDER_ENTRY 	pReorderEntry = NULL;
+
+	//u32 flags = 0;
+	unsigned long flags = 0;
+	struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE];
+	u8 index = 0;
+	bool bPktInBuf = false;
+
+
+	spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
+	//PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__);
+	if(pRxTs->RxTimeoutIndicateSeq != 0xffff)
+	{
+		// Indicate the pending packets sequentially according to SeqNum until meet the gap.
+		while(!list_empty(&pRxTs->RxPendingPktList))
+		{
+			pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+			if(index == 0)
+				pRxTs->RxIndicateSeq = pReorderEntry->SeqNum;
+
+			if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ||
+				SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)	)
+			{
+				list_del_init(&pReorderEntry->List);
+
+				if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq))
+					pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096;
+
+				IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum);
+				stats_IndicateArray[index] = pReorderEntry->prxb;
+				index++;
+
+				list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List);
+			}
+			else
+			{
+				bPktInBuf = true;
+				break;
+			}
+		}
+	}
+
+	if(index>0)
+	{
+		// Set RxTimeoutIndicateSeq to 0xffff to indicate no pending packets in buffer now.
+		pRxTs->RxTimeoutIndicateSeq = 0xffff;
+
+		// Indicate packets
+		if(index > REORDER_WIN_SIZE){
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n");
+			spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+			return;
+		}
+		ieee80211_indicate_packets(ieee, stats_IndicateArray, index);
+		bPktInBuf = false;
+	}
+
+	if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
+	{
+		pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
+#if 0
+		if(timer_pending(&pRxTs->RxPktPendingTimer))
+			del_timer_sync(&pRxTs->RxPktPendingTimer);
+		pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime;
+		add_timer(&pRxTs->RxPktPendingTimer);
+#else
+		mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime));
+#endif
+	}
+	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+	//PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+}
+#endif
+
+/********************************************************************************************************************
+ *function:  Add BA timer function
+ *   input:  unsigned long	 data		//acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer
+ *  return:  NULL
+ *  notice:
+********************************************************************************************************************/
+void TsAddBaProcess(unsigned long data)
+{
+	PTX_TS_RECORD	pTxTs = (PTX_TS_RECORD)data;
+	u8 num = pTxTs->num;
+	struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]);
+
+	TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false);
+	IEEE80211_DEBUG(IEEE80211_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n");
+}
+
+
+void ResetTsCommonInfo(PTS_COMMON_INFO	pTsCommonInfo)
+{
+	memset(pTsCommonInfo->Addr, 0, 6);
+	memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY));
+	memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM);
+	pTsCommonInfo->TClasProc = 0;
+	pTsCommonInfo->TClasNum = 0;
+}
+
+void ResetTxTsEntry(PTX_TS_RECORD pTS)
+{
+	ResetTsCommonInfo(&pTS->TsCommonInfo);
+	pTS->TxCurSeq = 0;
+	pTS->bAddBaReqInProgress = false;
+	pTS->bAddBaReqDelayed = false;
+	pTS->bUsingBa = false;
+	ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator
+	ResetBaEntry(&pTS->TxPendingBARecord);
+}
+
+void ResetRxTsEntry(PRX_TS_RECORD pTS)
+{
+	ResetTsCommonInfo(&pTS->TsCommonInfo);
+	pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!!
+	pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!!
+	ResetBaEntry(&pTS->RxAdmittedBARecord);	  // For BA Recepient
+}
+
+void TSInitialize(struct ieee80211_device *ieee)
+{
+	PTX_TS_RECORD		pTxTS  = ieee->TxTsRecord;
+	PRX_TS_RECORD		pRxTS  = ieee->RxTsRecord;
+	PRX_REORDER_ENTRY	pRxReorderEntry = ieee->RxReorderEntry;
+	u8				count = 0;
+	IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __FUNCTION__);
+	// Initialize Tx TS related info.
+	INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List);
+	INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List);
+	INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List);
+
+	for(count = 0; count < TOTAL_TS_NUM; count++)
+	{
+		//
+		pTxTS->num = count;
+		// The timers for the operation of Traffic Stream and Block Ack.
+		// DLS related timer will be add here in the future!!
+		init_timer(&pTxTS->TsCommonInfo.SetupTimer);
+		pTxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
+
+		init_timer(&pTxTS->TsCommonInfo.InactTimer);
+		pTxTS->TsCommonInfo.InactTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
+
+		init_timer(&pTxTS->TsAddBaTimer);
+		pTxTS->TsAddBaTimer.data = (unsigned long)pTxTS;
+		pTxTS->TsAddBaTimer.function = TsAddBaProcess;
+
+		init_timer(&pTxTS->TxPendingBARecord.Timer);
+		pTxTS->TxPendingBARecord.Timer.data = (unsigned long)pTxTS;
+		pTxTS->TxPendingBARecord.Timer.function = BaSetupTimeOut;
+
+		init_timer(&pTxTS->TxAdmittedBARecord.Timer);
+		pTxTS->TxAdmittedBARecord.Timer.data = (unsigned long)pTxTS;
+		pTxTS->TxAdmittedBARecord.Timer.function = TxBaInactTimeout;
+
+		ResetTxTsEntry(pTxTS);
+		list_add_tail(&pTxTS->TsCommonInfo.List, &ieee->Tx_TS_Unused_List);
+		pTxTS++;
+	}
+
+	// Initialize Rx TS related info.
+	INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List);
+	INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List);
+	INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List);
+	for(count = 0; count < TOTAL_TS_NUM; count++)
+	{
+		pRxTS->num = count;
+		INIT_LIST_HEAD(&pRxTS->RxPendingPktList);
+
+		init_timer(&pRxTS->TsCommonInfo.SetupTimer);
+		pRxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pRxTS;
+		pRxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut;
+
+		init_timer(&pRxTS->TsCommonInfo.InactTimer);
+		pRxTS->TsCommonInfo.InactTimer.data = (unsigned long)pRxTS;
+		pRxTS->TsCommonInfo.InactTimer.function = TsInactTimeout;
+
+		init_timer(&pRxTS->RxAdmittedBARecord.Timer);
+		pRxTS->RxAdmittedBARecord.Timer.data = (unsigned long)pRxTS;
+		pRxTS->RxAdmittedBARecord.Timer.function = RxBaInactTimeout;
+
+		init_timer(&pRxTS->RxPktPendingTimer);
+		pRxTS->RxPktPendingTimer.data = (unsigned long)pRxTS;
+		pRxTS->RxPktPendingTimer.function = RxPktPendingTimeout;
+
+		ResetRxTsEntry(pRxTS);
+		list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List);
+		pRxTS++;
+	}
+	// Initialize unused Rx Reorder List.
+	INIT_LIST_HEAD(&ieee->RxReorder_Unused_List);
+//#ifdef TO_DO_LIST
+	for(count = 0; count < REORDER_ENTRY_NUM; count++)
+	{
+		list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
+		if(count == (REORDER_ENTRY_NUM-1))
+			break;
+		pRxReorderEntry = &ieee->RxReorderEntry[count+1];
+	}
+//#endif
+
+}
+
+void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime)
+{
+	del_timer_sync(&pTsCommonInfo->SetupTimer);
+	del_timer_sync(&pTsCommonInfo->InactTimer);
+
+	if(InactTime!=0)
+		mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime));
+}
+
+
+PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8*	Addr, u8 TID, TR_SELECT	TxRxSelect)
+{
+	//DIRECTION_VALUE 	dir;
+	u8 	dir;
+	bool				search_dir[4] = {0, 0, 0, 0};
+	struct list_head*		psearch_list; //FIXME
+	PTS_COMMON_INFO	pRet = NULL;
+	if(ieee->iw_mode == IW_MODE_MASTER) //ap mode
+	{
+		if(TxRxSelect == TX_DIR)
+		{
+			search_dir[DIR_DOWN] = true;
+			search_dir[DIR_BI_DIR]= true;
+		}
+		else
+		{
+			search_dir[DIR_UP] 	= true;
+			search_dir[DIR_BI_DIR]= true;
+		}
+	}
+	else if(ieee->iw_mode == IW_MODE_ADHOC)
+	{
+		if(TxRxSelect == TX_DIR)
+			search_dir[DIR_UP] 	= true;
+		else
+			search_dir[DIR_DOWN] = true;
+	}
+	else
+	{
+		if(TxRxSelect == TX_DIR)
+		{
+			search_dir[DIR_UP] 	= true;
+			search_dir[DIR_BI_DIR]= true;
+			search_dir[DIR_DIRECT]= true;
+		}
+		else
+		{
+			search_dir[DIR_DOWN] = true;
+			search_dir[DIR_BI_DIR]= true;
+			search_dir[DIR_DIRECT]= true;
+		}
+	}
+
+	if(TxRxSelect == TX_DIR)
+		psearch_list = &ieee->Tx_TS_Admit_List;
+	else
+		psearch_list = &ieee->Rx_TS_Admit_List;
+
+	//for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++)
+	for(dir = 0; dir <= DIR_BI_DIR; dir++)
+	{
+		if(search_dir[dir] ==false )
+			continue;
+		list_for_each_entry(pRet, psearch_list, List){
+	//		IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:"MAC_FMT", TID:%d, dir:%d\n", MAC_ARG(pRet->Addr), pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection);
+			if (memcmp(pRet->Addr, Addr, 6) == 0)
+				if (pRet->TSpec.f.TSInfo.field.ucTSID == TID)
+					if(pRet->TSpec.f.TSInfo.field.ucDirection == dir)
+					{
+	//					printk("Bingo! got it\n");
+						break;
+					}
+
+		}
+		if(&pRet->List  != psearch_list)
+			break;
+	}
+
+	if(&pRet->List  != psearch_list){
+		return pRet ;
+	}
+	else
+		return NULL;
+}
+
+void MakeTSEntry(
+		PTS_COMMON_INFO	pTsCommonInfo,
+		u8*		Addr,
+		PTSPEC_BODY	pTSPEC,
+		PQOS_TCLAS	pTCLAS,
+		u8		TCLAS_Num,
+		u8		TCLAS_Proc
+	)
+{
+	u8	count;
+
+	if(pTsCommonInfo == NULL)
+		return;
+
+	memcpy(pTsCommonInfo->Addr, Addr, 6);
+
+	if(pTSPEC != NULL)
+		memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY));
+
+	for(count = 0; count < TCLAS_Num; count++)
+		memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS));
+
+	pTsCommonInfo->TClasProc = TCLAS_Proc;
+	pTsCommonInfo->TClasNum = TCLAS_Num;
+}
+
+
+bool GetTs(
+	struct ieee80211_device*	ieee,
+	PTS_COMMON_INFO			*ppTS,
+	u8*				Addr,
+	u8				TID,
+	TR_SELECT			TxRxSelect,  //Rx:1, Tx:0
+	bool				bAddNewTs
+	)
+{
+	u8	UP = 0;
+	//
+	// We do not build any TS for Broadcast or Multicast stream.
+	// So reject these kinds of search here.
+	//
+	if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr))
+	{
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n");
+		return false;
+	}
+#if 0
+	if(ieee->pStaQos->CurrentQosMode == QOS_DISABLE)
+	{	UP = 0; } //only use one TS
+	else if(ieee->pStaQos->CurrentQosMode & QOS_WMM)
+	{
+#else
+	if (ieee->current_network.qos_data.supported == 0)
+		UP = 0;
+	else
+	{
+#endif
+		// In WMM case: we use 4 TID only
+		if (!IsACValid(TID))
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __FUNCTION__, TID);
+			return false;
+		}
+
+		switch(TID)
+		{
+		case 0:
+		case 3:
+			UP = 0;
+			break;
+
+		case 1:
+		case 2:
+			UP = 2;
+			break;
+
+		case 4:
+		case 5:
+			UP = 5;
+			break;
+
+		case 6:
+		case 7:
+			UP = 7;
+			break;
+		}
+	}
+
+	*ppTS = SearchAdmitTRStream(
+			ieee,
+			Addr,
+			UP,
+			TxRxSelect);
+	if(*ppTS != NULL)
+	{
+		return true;
+	}
+	else
+	{
+		if(bAddNewTs == false)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP);
+			return false;
+		}
+		else
+		{
+			//
+			// Create a new Traffic stream for current Tx/Rx
+			// This is for EDCA and WMM to add a new TS.
+			// For HCCA or WMMSA, TS cannot be addmit without negotiation.
+			//
+			TSPEC_BODY	TSpec;
+			PQOS_TSINFO		pTSInfo = &TSpec.f.TSInfo;
+			struct list_head*	pUnusedList =
+								(TxRxSelect == TX_DIR)?
+								(&ieee->Tx_TS_Unused_List):
+								(&ieee->Rx_TS_Unused_List);
+
+			struct list_head*	pAddmitList =
+								(TxRxSelect == TX_DIR)?
+								(&ieee->Tx_TS_Admit_List):
+								(&ieee->Rx_TS_Admit_List);
+
+			DIRECTION_VALUE		Dir =		(ieee->iw_mode == IW_MODE_MASTER)?
+								((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP):
+								((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN);
+			IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n");
+			if(!list_empty(pUnusedList))
+			{
+				(*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List);
+				list_del_init(&(*ppTS)->List);
+				if(TxRxSelect==TX_DIR)
+				{
+					PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo);
+					ResetTxTsEntry(tmp);
+				}
+				else{
+					PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo);
+					ResetRxTsEntry(tmp);
+				}
+
+				IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:"MAC_FMT"\n", UP, Dir, MAC_ARG(Addr));
+				// Prepare TS Info releated field
+				pTSInfo->field.ucTrafficType = 0;			// Traffic type: WMM is reserved in this field
+				pTSInfo->field.ucTSID = UP;			// TSID
+				pTSInfo->field.ucDirection = Dir;			// Direction: if there is DirectLink, this need additional consideration.
+				pTSInfo->field.ucAccessPolicy = 1;		// Access policy
+				pTSInfo->field.ucAggregation = 0; 		// Aggregation
+				pTSInfo->field.ucPSB = 0; 				// Aggregation
+				pTSInfo->field.ucUP = UP;				// User priority
+				pTSInfo->field.ucTSInfoAckPolicy = 0;		// Ack policy
+				pTSInfo->field.ucSchedule = 0;			// Schedule
+
+				MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0);
+				AdmitTS(ieee, *ppTS, 0);
+				list_add_tail(&((*ppTS)->List), pAddmitList);
+				// if there is DirectLink, we need to do additional operation here!!
+
+				return true;
+			}
+			else
+			{
+				IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __FUNCTION__);
+				return false;
+			}
+		}
+	}
+}
+
+void RemoveTsEntry(
+	struct ieee80211_device*	ieee,
+	PTS_COMMON_INFO			pTs,
+	TR_SELECT			TxRxSelect
+	)
+{
+	//u32 flags = 0;
+	unsigned long flags = 0;
+	del_timer_sync(&pTs->SetupTimer);
+	del_timer_sync(&pTs->InactTimer);
+	TsInitDelBA(ieee, pTs, TxRxSelect);
+
+	if(TxRxSelect == RX_DIR)
+	{
+//#ifdef TO_DO_LIST
+		PRX_REORDER_ENTRY	pRxReorderEntry;
+		PRX_TS_RECORD 		pRxTS = (PRX_TS_RECORD)pTs;
+		if(timer_pending(&pRxTS->RxPktPendingTimer))
+			del_timer_sync(&pRxTS->RxPktPendingTimer);
+
+                while(!list_empty(&pRxTS->RxPendingPktList))
+                {
+                //      PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
+                        spin_lock_irqsave(&(ieee->reorder_spinlock), flags);
+                        //pRxReorderEntry = list_entry(&pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+			pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List);
+                        list_del_init(&pRxReorderEntry->List);
+                        {
+                                int i = 0;
+                                struct ieee80211_rxb * prxb = pRxReorderEntry->prxb;
+				if (unlikely(!prxb))
+				{
+					spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+					return;
+				}
+                                for(i =0; i < prxb->nr_subframes; i++) {
+                                        dev_kfree_skb(prxb->subframes[i]);
+                                }
+                                kfree(prxb);
+                                prxb = NULL;
+                        }
+                        list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List);
+                        //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
+                        spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
+                }
+
+//#endif
+	}
+	else
+	{
+		PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs;
+		del_timer_sync(&pTxTS->TsAddBaTimer);
+	}
+}
+
+void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr)
+{
+	PTS_COMMON_INFO	pTS, pTmpTS;
+	printk("===========>RemovePeerTS,"MAC_FMT"\n", MAC_ARG(Addr));
+#if 1
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, TX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+		}
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			printk("====>remove Tx_TS_admin_list\n");
+			RemoveTsEntry(ieee, pTS, TX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+		}
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, RX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+		}
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
+	{
+		if (memcmp(pTS->Addr, Addr, 6) == 0)
+		{
+			RemoveTsEntry(ieee, pTS, RX_DIR);
+			list_del_init(&pTS->List);
+			list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+		}
+	}
+#endif
+}
+
+void RemoveAllTS(struct ieee80211_device* ieee)
+{
+	PTS_COMMON_INFO pTS, pTmpTS;
+#if 1
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, TX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, TX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List);
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, RX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+	}
+
+	list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List)
+	{
+		RemoveTsEntry(ieee, pTS, RX_DIR);
+		list_del_init(&pTS->List);
+		list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List);
+	}
+#endif
+}
+
+void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD	pTxTS)
+{
+	if(pTxTS->bAddBaReqInProgress == false)
+	{
+		pTxTS->bAddBaReqInProgress = true;
+#if 1
+		if(pTxTS->bAddBaReqDelayed)
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n");
+			mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY));
+		}
+		else
+		{
+			IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n");
+			mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks
+		}
+#endif
+	}
+	else
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__);
+}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+EXPORT_SYMBOL_NOVERS(RemovePeerTS);
+#else
+//EXPORT_SYMBOL(RemovePeerTS);
+#endif
diff --git a/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h b/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h
new file mode 100644
index 0000000..ccf6ae7
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h
@@ -0,0 +1,399 @@
+/*
+ * Scatterlist Cryptographic API.
+ *
+ * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
+ * Copyright (c) 2002 David S. Miller (davem@redhat.com)
+ *
+ * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
+ * and Nettle, by Niels Mé°ˆler.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the 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 _LINUX_CRYPTO_H
+#define _LINUX_CRYPTO_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include <asm/page.h>
+#include <asm/errno.h>
+
+#define crypto_register_alg crypto_register_alg_rsl
+#define crypto_unregister_alg crypto_unregister_alg_rsl
+#define crypto_alloc_tfm crypto_alloc_tfm_rsl
+#define crypto_free_tfm crypto_free_tfm_rsl
+#define crypto_alg_available crypto_alg_available_rsl
+
+/*
+ * Algorithm masks and types.
+ */
+#define CRYPTO_ALG_TYPE_MASK		0x000000ff
+#define CRYPTO_ALG_TYPE_CIPHER		0x00000001
+#define CRYPTO_ALG_TYPE_DIGEST		0x00000002
+#define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
+
+/*
+ * Transform masks and values (for crt_flags).
+ */
+#define CRYPTO_TFM_MODE_MASK		0x000000ff
+#define CRYPTO_TFM_REQ_MASK		0x000fff00
+#define CRYPTO_TFM_RES_MASK		0xfff00000
+
+#define CRYPTO_TFM_MODE_ECB		0x00000001
+#define CRYPTO_TFM_MODE_CBC		0x00000002
+#define CRYPTO_TFM_MODE_CFB		0x00000004
+#define CRYPTO_TFM_MODE_CTR		0x00000008
+
+#define CRYPTO_TFM_REQ_WEAK_KEY		0x00000100
+#define CRYPTO_TFM_RES_WEAK_KEY		0x00100000
+#define CRYPTO_TFM_RES_BAD_KEY_LEN   	0x00200000
+#define CRYPTO_TFM_RES_BAD_KEY_SCHED 	0x00400000
+#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 	0x00800000
+#define CRYPTO_TFM_RES_BAD_FLAGS 	0x01000000
+
+/*
+ * Miscellaneous stuff.
+ */
+#define CRYPTO_UNSPEC			0
+#define CRYPTO_MAX_ALG_NAME		64
+
+struct scatterlist;
+
+/*
+ * Algorithms: modular crypto algorithm implementations, managed
+ * via crypto_register_alg() and crypto_unregister_alg().
+ */
+struct cipher_alg {
+	unsigned int cia_min_keysize;
+	unsigned int cia_max_keysize;
+	int (*cia_setkey)(void *ctx, const u8 *key,
+	                  unsigned int keylen, u32 *flags);
+	void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
+	void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
+};
+
+struct digest_alg {
+	unsigned int dia_digestsize;
+	void (*dia_init)(void *ctx);
+	void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
+	void (*dia_final)(void *ctx, u8 *out);
+	int (*dia_setkey)(void *ctx, const u8 *key,
+	                  unsigned int keylen, u32 *flags);
+};
+
+struct compress_alg {
+	int (*coa_init)(void *ctx);
+	void (*coa_exit)(void *ctx);
+	int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
+	                    u8 *dst, unsigned int *dlen);
+	int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
+	                      u8 *dst, unsigned int *dlen);
+};
+
+#define cra_cipher	cra_u.cipher
+#define cra_digest	cra_u.digest
+#define cra_compress	cra_u.compress
+
+struct crypto_alg {
+	struct list_head cra_list;
+	u32 cra_flags;
+	unsigned int cra_blocksize;
+	unsigned int cra_ctxsize;
+	const char cra_name[CRYPTO_MAX_ALG_NAME];
+
+	union {
+		struct cipher_alg cipher;
+		struct digest_alg digest;
+		struct compress_alg compress;
+	} cra_u;
+
+	struct module *cra_module;
+};
+
+/*
+ * Algorithm registration interface.
+ */
+int crypto_register_alg(struct crypto_alg *alg);
+int crypto_unregister_alg(struct crypto_alg *alg);
+
+/*
+ * Algorithm query interface.
+ */
+int crypto_alg_available(const char *name, u32 flags);
+
+/*
+ * Transforms: user-instantiated objects which encapsulate algorithms
+ * and core processing logic.  Managed via crypto_alloc_tfm() and
+ * crypto_free_tfm(), as well as the various helpers below.
+ */
+struct crypto_tfm;
+
+struct cipher_tfm {
+	void *cit_iv;
+	unsigned int cit_ivsize;
+	u32 cit_mode;
+	int (*cit_setkey)(struct crypto_tfm *tfm,
+	                  const u8 *key, unsigned int keylen);
+	int (*cit_encrypt)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
+	int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
+	                      struct scatterlist *dst,
+	                      struct scatterlist *src,
+	                      unsigned int nbytes, u8 *iv);
+	int (*cit_decrypt)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes);
+	int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
+			   struct scatterlist *dst,
+			   struct scatterlist *src,
+			   unsigned int nbytes, u8 *iv);
+	void (*cit_xor_block)(u8 *dst, const u8 *src);
+};
+
+struct digest_tfm {
+	void (*dit_init)(struct crypto_tfm *tfm);
+	void (*dit_update)(struct crypto_tfm *tfm,
+	                   struct scatterlist *sg, unsigned int nsg);
+	void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
+	void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
+	                   unsigned int nsg, u8 *out);
+	int (*dit_setkey)(struct crypto_tfm *tfm,
+	                  const u8 *key, unsigned int keylen);
+#ifdef CONFIG_CRYPTO_HMAC
+	void *dit_hmac_block;
+#endif
+};
+
+struct compress_tfm {
+	int (*cot_compress)(struct crypto_tfm *tfm,
+	                    const u8 *src, unsigned int slen,
+	                    u8 *dst, unsigned int *dlen);
+	int (*cot_decompress)(struct crypto_tfm *tfm,
+	                      const u8 *src, unsigned int slen,
+	                      u8 *dst, unsigned int *dlen);
+};
+
+#define crt_cipher	crt_u.cipher
+#define crt_digest	crt_u.digest
+#define crt_compress	crt_u.compress
+
+struct crypto_tfm {
+
+	u32 crt_flags;
+
+	union {
+		struct cipher_tfm cipher;
+		struct digest_tfm digest;
+		struct compress_tfm compress;
+	} crt_u;
+
+	struct crypto_alg *__crt_alg;
+};
+
+/*
+ * Transform user interface.
+ */
+
+/*
+ * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
+ * If that fails and the kernel supports dynamically loadable modules, it
+ * will then attempt to load a module of the same name or alias.  A refcount
+ * is grabbed on the algorithm which is then associated with the new transform.
+ *
+ * crypto_free_tfm() frees up the transform and any associated resources,
+ * then drops the refcount on the associated algorithm.
+ */
+struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
+void crypto_free_tfm(struct crypto_tfm *tfm);
+
+/*
+ * Transform helpers which query the underlying algorithm.
+ */
+static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_name;
+}
+
+static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+
+	if (alg->cra_module)
+		return alg->cra_module->name;
+	else
+		return NULL;
+}
+
+static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
+}
+
+static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->__crt_alg->cra_cipher.cia_min_keysize;
+}
+
+static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->__crt_alg->cra_cipher.cia_max_keysize;
+}
+
+static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_ivsize;
+}
+
+static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
+{
+	return tfm->__crt_alg->cra_blocksize;
+}
+
+static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	return tfm->__crt_alg->cra_digest.dia_digestsize;
+}
+
+/*
+ * API wrappers.
+ */
+static inline void crypto_digest_init(struct crypto_tfm *tfm)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_init(tfm);
+}
+
+static inline void crypto_digest_update(struct crypto_tfm *tfm,
+                                        struct scatterlist *sg,
+                                        unsigned int nsg)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_update(tfm, sg, nsg);
+}
+
+static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_final(tfm, out);
+}
+
+static inline void crypto_digest_digest(struct crypto_tfm *tfm,
+                                        struct scatterlist *sg,
+                                        unsigned int nsg, u8 *out)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
+}
+
+static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
+                                       const u8 *key, unsigned int keylen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
+	if (tfm->crt_digest.dit_setkey == NULL)
+		return -ENOSYS;
+	return tfm->crt_digest.dit_setkey(tfm, key, keylen);
+}
+
+static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
+                                       const u8 *key, unsigned int keylen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
+}
+
+static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
+}
+
+static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
+                                           struct scatterlist *dst,
+                                           struct scatterlist *src,
+                                           unsigned int nbytes, u8 *iv)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
+	return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
+}
+
+static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
+                                        struct scatterlist *dst,
+                                        struct scatterlist *src,
+                                        unsigned int nbytes)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
+}
+
+static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
+                                           struct scatterlist *dst,
+                                           struct scatterlist *src,
+                                           unsigned int nbytes, u8 *iv)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
+	return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
+}
+
+static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
+                                        const u8 *src, unsigned int len)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	memcpy(tfm->crt_cipher.cit_iv, src, len);
+}
+
+static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
+                                        u8 *dst, unsigned int len)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
+	memcpy(dst, tfm->crt_cipher.cit_iv, len);
+}
+
+static inline int crypto_comp_compress(struct crypto_tfm *tfm,
+                                       const u8 *src, unsigned int slen,
+                                       u8 *dst, unsigned int *dlen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
+	return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
+}
+
+static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
+                                         const u8 *src, unsigned int slen,
+                                         u8 *dst, unsigned int *dlen)
+{
+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
+	return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
+}
+
+/*
+ * HMAC support.
+ */
+#ifdef CONFIG_CRYPTO_HMAC
+void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
+void crypto_hmac_update(struct crypto_tfm *tfm,
+                        struct scatterlist *sg, unsigned int nsg);
+void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
+                       unsigned int *keylen, u8 *out);
+void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
+                 struct scatterlist *sg, unsigned int nsg, u8 *out);
+#endif	/* CONFIG_CRYPTO_HMAC */
+
+#endif	/* _LINUX_CRYPTO_H */
+
diff --git a/drivers/staging/rtl8192e/ieee80211_crypt.h b/drivers/staging/rtl8192e/ieee80211_crypt.h
new file mode 100644
index 0000000..b58a3bc
--- /dev/null
+++ b/drivers/staging/rtl8192e/ieee80211_crypt.h
@@ -0,0 +1,86 @@
+/*
+ * Original code based on Host AP (software wireless LAN access point) driver
+ * for Intersil Prism2/2.5/3.
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ *
+ * Adaption to a generic IEEE 802.11 stack by James Ketrenos
+ * <jketreno@linux.intel.com>
+ *
+ * Copyright (c) 2004, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation. See README and COPYING for
+ * more details.
+ */
+
+/*
+ * This file defines the interface to the ieee80211 crypto module.
+ */
+#ifndef IEEE80211_CRYPT_H
+#define IEEE80211_CRYPT_H
+
+#include <linux/skbuff.h>
+
+struct ieee80211_crypto_ops {
+	const char *name;
+
+	/* init new crypto context (e.g., allocate private data space,
+	 * select IV, etc.); returns NULL on failure or pointer to allocated
+	 * private data on success */
+	void * (*init)(int keyidx);
+
+	/* deinitialize crypto context and free allocated private data */
+	void (*deinit)(void *priv);
+
+	/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
+	 * value from decrypt_mpdu is passed as the keyidx value for
+	 * decrypt_msdu. skb must have enough head and tail room for the
+	 * encryption; if not, error will be returned; these functions are
+	 * called for all MPDUs (i.e., fragments).
+	 */
+	int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+	int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
+
+	/* These functions are called for full MSDUs, i.e. full frames.
+	 * These can be NULL if full MSDU operations are not needed. */
+	int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
+	int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
+			    void *priv);
+
+	int (*set_key)(void *key, int len, u8 *seq, void *priv);
+	int (*get_key)(void *key, int len, u8 *seq, void *priv);
+
+	/* procfs handler for printing out key information and possible
+	 * statistics */
+	char * (*print_stats)(char *p, void *priv);
+
+	/* maximum number of bytes added by encryption; encrypt buf is
+	 * allocated with extra_prefix_len bytes, copy of in_buf, and
+	 * extra_postfix_len; encrypt need not use all this space, but
+	 * the result must start at the beginning of the buffer and correct
+	 * length must be returned */
+	int extra_prefix_len, extra_postfix_len;
+
+	struct module *owner;
+};
+
+struct ieee80211_crypt_data {
+	struct list_head list; /* delayed deletion list */
+	struct ieee80211_crypto_ops *ops;
+	void *priv;
+	atomic_t refcnt;
+};
+
+int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
+int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
+struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
+void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
+void ieee80211_crypt_deinit_handler(unsigned long);
+void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
+				    struct ieee80211_crypt_data **crypt);
+
+#endif
diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c
new file mode 100644
index 0000000..79f7a0f
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8180_93cx6.c
@@ -0,0 +1,146 @@
+/*
+   This files contains card eeprom (93c46 or 93c56) programming routines,
+   memory is addressed by 16 bits words.
+
+   This is part of rtl8180 OpenSource driver.
+   Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+   Released under the terms of GPL (General Public Licence)
+
+   Parts of this driver are based on the GPL part of the
+   official realtek driver.
+
+   Parts of this driver are based on the rtl8180 driver skeleton
+   from Patric Schenke & Andres Salomon.
+
+   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
+
+   We want to tanks the Authors of those projects and the Ndiswrapper
+   project Authors.
+*/
+
+#include "r8180_93cx6.h"
+
+static void eprom_cs(struct net_device *dev, short bit)
+{
+	if(bit)
+		write_nic_byte(dev, EPROM_CMD,
+			       (1<<EPROM_CS_SHIFT) | \
+			       read_nic_byte(dev, EPROM_CMD)); //enable EPROM
+	else
+		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
+			       &~(1<<EPROM_CS_SHIFT)); //disable EPROM
+
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+}
+
+
+static void eprom_ck_cycle(struct net_device *dev)
+{
+	write_nic_byte(dev, EPROM_CMD,
+		       (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+	write_nic_byte(dev, EPROM_CMD,
+		       read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+}
+
+
+static void eprom_w(struct net_device *dev,short bit)
+{
+	if(bit)
+		write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
+			       read_nic_byte(dev,EPROM_CMD));
+	else
+		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
+			       &~(1<<EPROM_W_SHIFT));
+
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+}
+
+
+static short eprom_r(struct net_device *dev)
+{
+	short bit;
+
+	bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
+	udelay(EPROM_DELAY);
+
+	if(bit) return 1;
+	return 0;
+}
+
+
+static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
+{
+	int i;
+
+	for(i=0; i<len; i++){
+		eprom_w(dev, b[i]);
+		eprom_ck_cycle(dev);
+	}
+}
+
+
+u32 eprom_read(struct net_device *dev, u32 addr)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	short read_cmd[]={1,1,0};
+	short addr_str[8];
+	int i;
+	int addr_len;
+	u32 ret;
+
+	ret=0;
+        //enable EPROM programming
+	write_nic_byte(dev, EPROM_CMD,
+		       (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
+	force_pci_posting(dev);
+	udelay(EPROM_DELAY);
+
+	if (priv->epromtype==EPROM_93c56){
+		addr_str[7]=addr & 1;
+		addr_str[6]=addr & (1<<1);
+		addr_str[5]=addr & (1<<2);
+		addr_str[4]=addr & (1<<3);
+		addr_str[3]=addr & (1<<4);
+		addr_str[2]=addr & (1<<5);
+		addr_str[1]=addr & (1<<6);
+		addr_str[0]=addr & (1<<7);
+		addr_len=8;
+	}else{
+		addr_str[5]=addr & 1;
+		addr_str[4]=addr & (1<<1);
+		addr_str[3]=addr & (1<<2);
+		addr_str[2]=addr & (1<<3);
+		addr_str[1]=addr & (1<<4);
+		addr_str[0]=addr & (1<<5);
+		addr_len=6;
+	}
+	eprom_cs(dev, 1);
+	eprom_ck_cycle(dev);
+	eprom_send_bits_string(dev, read_cmd, 3);
+	eprom_send_bits_string(dev, addr_str, addr_len);
+
+	//keep chip pin D to low state while reading.
+	//I'm unsure if it is necessary, but anyway shouldn't hurt
+	eprom_w(dev, 0);
+
+	for(i=0;i<16;i++){
+		//eeprom needs a clk cycle between writing opcode&adr
+		//and reading data. (eeprom outs a dummy 0)
+		eprom_ck_cycle(dev);
+		ret |= (eprom_r(dev)<<(15-i));
+	}
+
+	eprom_cs(dev, 0);
+	eprom_ck_cycle(dev);
+
+	//disable EPROM programming
+	write_nic_byte(dev, EPROM_CMD,
+		       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
+	return ret;
+}
diff --git a/drivers/staging/rtl8192e/r8180_93cx6.h b/drivers/staging/rtl8192e/r8180_93cx6.h
new file mode 100644
index 0000000..62e14c7
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8180_93cx6.h
@@ -0,0 +1,40 @@
+/*
+	This is part of rtl8187 OpenSource driver
+	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+	Released under the terms of GPL (General Public Licence)
+
+	Parts of this driver are based on the GPL part of the official realtek driver
+	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
+	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
+
+	We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
+*/
+
+/*This files contains card eeprom (93c46 or 93c56) programming routines*/
+/*memory is addressed by WORDS*/
+
+#include "r8192E.h"
+#include "r8192E_hw.h"
+
+#define EPROM_DELAY 10
+
+#define EPROM_ANAPARAM_ADDRLWORD 0xd
+#define EPROM_ANAPARAM_ADDRHWORD 0xe
+
+#define EPROM_RFCHIPID 0x6
+#define EPROM_TXPW_BASE 0x05
+#define EPROM_RFCHIPID_RTL8225U 5
+#define EPROM_RF_PARAM 0x4
+#define EPROM_CONFIG2 0xc
+
+#define EPROM_VERSION 0x1E
+#define MAC_ADR 0x7
+
+#define CIS 0x18
+
+#define EPROM_TXPW0 0x16
+#define EPROM_TXPW2 0x1b
+#define EPROM_TXPW1 0x3d
+
+
+u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c
new file mode 100644
index 0000000..0eaee3a
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.c
@@ -0,0 +1,1161 @@
+/*
+  This is part of the rtl8192 driver
+  released under the GPL (See file COPYING for details).
+
+  This files contains programming code for the rtl8256
+  radio frontend.
+
+  *Many* thanks to Realtek Corp. for their great support!
+
+*/
+
+#include "r8192E.h"
+#include "r8192E_hw.h"
+#include "r819xE_phyreg.h"
+#include "r819xE_phy.h"
+#include "r8190_rtl8256.h"
+
+/*--------------------------------------------------------------------------
+ * Overview:   	set RF band width (20M or 40M)
+ * Input:       struct net_device*	dev
+ * 		WIRELESS_BANDWIDTH_E	Bandwidth	//20M or 40M
+ * Output:      NONE
+ * Return:      NONE
+ * Note:	8226 support both 20M  and 40 MHz
+ *---------------------------------------------------------------------------*/
+void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth)	//20M or 40M
+{
+	u8	eRFPath;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+	for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
+	{
+		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+				continue;
+
+		switch(Bandwidth)
+		{
+			case HT_CHANNEL_WIDTH_20:
+				if(priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later!
+				{
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
+
+					//cosa add for sd3's request 01/23/2008
+					//rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
+				}
+				else
+				{
+					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+				}
+
+				break;
+			case HT_CHANNEL_WIDTH_20_40:
+				if(priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later!
+				{
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff);
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1);
+
+					//cosa add for sd3's request 01/23/2008
+					#if 0
+					if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes
+						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b);
+					else
+						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
+					#endif
+				}
+				else
+				{
+					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
+				}
+
+
+				break;
+			default:
+				RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
+				break;
+
+		}
+	}
+	return;
+}
+/*--------------------------------------------------------------------------
+ * Overview:    Interface to config 8256
+ * Input:       struct net_device*	dev
+ * Output:      NONE
+ * Return:      NONE
+ *---------------------------------------------------------------------------*/
+RT_STATUS PHY_RF8256_Config(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	// Initialize general global value
+	//
+	RT_STATUS rtStatus = RT_STATUS_SUCCESS;
+	// TODO: Extend RF_PATH_C and RF_PATH_D in the future
+	priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
+	// Config BB and RF
+	rtStatus = phy_RF8256_Config_ParaFile(dev);
+
+	return rtStatus;
+}
+/*--------------------------------------------------------------------------
+ * Overview:    Interface to config 8256
+ * Input:       struct net_device*	dev
+ * Output:      NONE
+ * Return:      NONE
+ *---------------------------------------------------------------------------*/
+RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev)
+{
+	u32 	u4RegValue = 0;
+	u8 	eRFPath;
+	RT_STATUS				rtStatus = RT_STATUS_SUCCESS;
+	BB_REGISTER_DEFINITION_T	*pPhyReg;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32	RegOffSetToBeCheck = 0x3;
+	u32 	RegValueToBeCheck = 0x7f1;
+	u32	RF3_Final_Value = 0;
+	u8	ConstRetryTimes = 5, RetryTimes = 5;
+	u8 ret = 0;
+	//3//-----------------------------------------------------------------
+	//3// <2> Initialize RF
+	//3//-----------------------------------------------------------------
+	for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
+	{
+		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+				continue;
+
+		pPhyReg = &priv->PHYRegDef[eRFPath];
+
+		// Joseph test for shorten RF config
+	//	pHalData->RfReg0Value[eRFPath] =  rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord);
+
+		/*----Store original RFENV control type----*/
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
+			break;
+		case RF90_PATH_B :
+		case RF90_PATH_D:
+			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
+			break;
+		}
+
+		/*----Set RF_ENV enable----*/
+		rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
+
+		/*----Set RF_ENV output high----*/
+		rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
+
+		/* Set bit number of Address and Data for RF register */
+		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); 	// Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258
+		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);	// Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ???
+
+		rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
+
+		/*----Check RF block (for FPGA platform only)----*/
+		// TODO: this function should be removed on ASIC , Emily 2007.2.2
+		rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath);
+		if(rtStatus!= RT_STATUS_SUCCESS)
+		{
+			RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
+			goto phy_RF8256_Config_ParaFile_Fail;
+		}
+
+		RetryTimes = ConstRetryTimes;
+		RF3_Final_Value = 0;
+		/*----Initialize RF fom connfiguration file----*/
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		case RF90_PATH_B:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		case RF90_PATH_C:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		case RF90_PATH_D:
+			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
+			{
+				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
+				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
+				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
+				RetryTimes--;
+			}
+			break;
+		}
+
+		/*----Restore RFENV control type----*/;
+		switch(eRFPath)
+		{
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
+			break;
+		case RF90_PATH_B :
+		case RF90_PATH_D:
+			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
+			break;
+		}
+
+		if(ret){
+			RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
+			goto phy_RF8256_Config_ParaFile_Fail;
+		}
+
+	}
+
+	RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
+	return RT_STATUS_SUCCESS;
+
+phy_RF8256_Config_ParaFile_Fail:
+	RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
+	return RT_STATUS_FAILURE;
+}
+
+
+void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel)
+{
+	u32	TxAGC=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef RTL8190P
+	u8				byte0, byte1;
+
+	TxAGC |= ((powerlevel<<8)|powerlevel);
+	TxAGC += priv->CCKTxPowerLevelOriginalOffset;
+
+	if(priv->bDynamicTxLowPower == true  //cosa 04282008 for cck long range
+		/*pMgntInfo->bScanInProgress == TRUE*/ ) //cosa 05/22/2008 for scan
+	{
+		if(priv->CustomerID == RT_CID_819x_Netcore)
+			TxAGC = 0x2222;
+		else
+		TxAGC += ((priv->CckPwEnl<<8)|priv->CckPwEnl);
+	}
+
+	byte0 = (u8)(TxAGC & 0xff);
+	byte1 = (u8)((TxAGC & 0xff00)>>8);
+	if(byte0 > 0x24)
+		byte0 = 0x24;
+	if(byte1 > 0x24)
+		byte1 = 0x24;
+	if(priv->rf_type == RF_2T4R)	//Only 2T4R you have to care the Antenna Tx Power offset
+	{	// check antenna C over the max index 0x24
+			if(priv->RF_C_TxPwDiff > 0)
+			{
+				if( (byte0 + (u8)priv->RF_C_TxPwDiff) > 0x24)
+					byte0 = 0x24 - priv->RF_C_TxPwDiff;
+				if( (byte1 + (u8)priv->RF_C_TxPwDiff) > 0x24)
+					byte1 = 0x24 - priv->RF_C_TxPwDiff;
+			}
+		}
+	TxAGC = (byte1<<8) |byte0;
+	write_nic_dword(dev, CCK_TXAGC, TxAGC);
+#else
+	#ifdef RTL8192E
+
+	TxAGC = powerlevel;
+	if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range
+	{
+		if(priv->CustomerID == RT_CID_819x_Netcore)
+		TxAGC = 0x22;
+	else
+		TxAGC += priv->CckPwEnl;
+	}
+	if(TxAGC > 0x24)
+		TxAGC = 0x24;
+	rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
+	#endif
+#endif
+}
+
+
+void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//Joseph TxPower for 8192 testing
+#ifdef RTL8190P
+	u32				TxAGC1=0, TxAGC2=0, TxAGC2_tmp = 0;
+	u8				i, byteVal1[4], byteVal2[4], byteVal3[4];
+
+	if(priv->bDynamicTxHighPower == true)     //Add by Jacken 2008/03/06
+	{
+		TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel);
+		//for tx power track
+		TxAGC2_tmp = TxAGC1;
+
+		TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0];
+		TxAGC2 =0x03030303;
+
+		//for tx power track
+		TxAGC2_tmp += priv->MCSTxPowerLevelOriginalOffset[1];
+	}
+	else
+	{
+		TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel);
+		TxAGC2 = TxAGC1;
+
+		TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0];
+		TxAGC2 += priv->MCSTxPowerLevelOriginalOffset[1];
+
+		TxAGC2_tmp = TxAGC2;
+
+	}
+	for(i=0; i<4; i++)
+	{
+		byteVal1[i] = (u8)(  (TxAGC1 & (0xff<<(i*8))) >>(i*8) );
+		if(byteVal1[i] > 0x24)
+			byteVal1[i] = 0x24;
+		byteVal2[i] = (u8)(  (TxAGC2 & (0xff<<(i*8))) >>(i*8) );
+		if(byteVal2[i] > 0x24)
+			byteVal2[i] = 0x24;
+
+		//for tx power track
+		byteVal3[i] = (u8)(  (TxAGC2_tmp & (0xff<<(i*8))) >>(i*8) );
+		if(byteVal3[i] > 0x24)
+			byteVal3[i] = 0x24;
+	}
+
+	if(priv->rf_type == RF_2T4R)	//Only 2T4R you have to care the Antenna Tx Power offset
+	{	// check antenna C over the max index 0x24
+		if(priv->RF_C_TxPwDiff > 0)
+		{
+			for(i=0; i<4; i++)
+			{
+				if( (byteVal1[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
+					byteVal1[i] = 0x24 - priv->RF_C_TxPwDiff;
+				if( (byteVal2[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
+					byteVal2[i] = 0x24 - priv->RF_C_TxPwDiff;
+				if( (byteVal3[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
+					byteVal3[i] = 0x24 - priv->RF_C_TxPwDiff;
+			}
+		}
+	}
+
+	TxAGC1 = (byteVal1[3]<<24) | (byteVal1[2]<<16) |(byteVal1[1]<<8) |byteVal1[0];
+	TxAGC2 = (byteVal2[3]<<24) | (byteVal2[2]<<16) |(byteVal2[1]<<8) |byteVal2[0];
+
+	//for tx power track
+	TxAGC2_tmp = (byteVal3[3]<<24) | (byteVal3[2]<<16) |(byteVal3[1]<<8) |byteVal3[0];
+	priv->Pwr_Track = TxAGC2_tmp;
+	//DbgPrint("TxAGC2_tmp = 0x%x\n", TxAGC2_tmp);
+
+	//DbgPrint("TxAGC1/TxAGC2 = 0x%x/0x%x\n", TxAGC1, TxAGC2);
+	write_nic_dword(dev, MCS_TXAGC, TxAGC1);
+	write_nic_dword(dev, MCS_TXAGC+4, TxAGC2);
+#else
+#ifdef RTL8192E
+	u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
+	u8 index = 0;
+	u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
+	u8 byte0, byte1, byte2, byte3;
+
+	powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff;	//OFDM rates
+	powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
+	powerBase1 = powerlevel;							//MCS rates
+	powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
+
+	for(index=0; index<6; index++)
+	{
+		writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
+		byte0 = (u8)(writeVal & 0x7f);
+		byte1 = (u8)((writeVal & 0x7f00)>>8);
+		byte2 = (u8)((writeVal & 0x7f0000)>>16);
+		byte3 = (u8)((writeVal & 0x7f000000)>>24);
+		if(byte0 > 0x24)	// Max power index = 0x24
+			byte0 = 0x24;
+		if(byte1 > 0x24)
+			byte1 = 0x24;
+		if(byte2 > 0x24)
+			byte2 = 0x24;
+		if(byte3 > 0x24)
+			byte3 = 0x24;
+
+		if(index == 3)
+		{
+			writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
+			priv->Pwr_Track = writeVal_tmp;
+		}
+
+		if(priv->bDynamicTxHighPower == true)     //Add by Jacken 2008/03/06  //when DM implement, add this
+		{
+			writeVal = 0x03030303;
+		}
+		else
+		{
+			writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
+		}
+		rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
+	}
+
+#endif
+#endif
+	return;
+}
+
+#define MAX_DOZE_WAITING_TIMES_9x 64
+static bool
+SetRFPowerState8190(
+	struct net_device* dev,
+	RT_RF_POWER_STATE	eRFPowerState
+	)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_POWER_SAVE_CONTROL	pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+	bool bResult = true;
+	//u8 eRFPath;
+	u8	i = 0, QueueID = 0;
+	ptx_ring	head=NULL,tail=NULL;
+
+	if(priv->SetRFPowerStateInProgress == true)
+		return false;
+	RT_TRACE(COMP_POWER, "===========> SetRFPowerState8190()!\n");
+	priv->SetRFPowerStateInProgress = true;
+
+	switch(priv->rf_chip)
+	{
+		case RF_8256:
+		switch( eRFPowerState )
+		{
+			case eRfOn:
+				RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOn !\n");
+						//RXTX enable control: On
+					//for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+					//	PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
+				#ifdef RTL8190P
+				if(priv->rf_type == RF_2T4R)
+				{
+					//enable RF-Chip A/B
+					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
+					//enable RF-Chip C/D
+					rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4]
+					//analog to digital on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8]
+					//digital to analog on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0xf); // 0x880[8:5]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0xf);// 0xc04[3:0]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0xf);// 0xd04[3:0]
+					//analog to digital part2 on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0xf); // 0x880[12:9]
+				}
+				else if(priv->rf_type == RF_1T2R)	//RF-C, RF-D
+				{
+					//enable RF-Chip C/D
+					rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4]
+					//analog to digital on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10]
+					//digital to analog on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x180, 0x3); // 0x880[8:7]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xc, 0x3);// 0xc04[3:2]
+					//rx antenna on
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xc, 0x3);// 0xd04[3:2]
+					//analog to digital part2 on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11]
+				}
+				#else
+				write_nic_byte(dev, ANAPAR, 0x37);//160MHz
+				write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403
+				mdelay(1);
+				//enable clock 80/88 MHz
+
+				priv->bHwRfOffAction = 0;
+				//}
+
+				// Baseband reset 2008.09.30 add
+				write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0));
+
+				//2 AFE
+				// 2008.09.30 add
+				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884
+				//analog to digital part2 on
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3);		// 0x880[6:5]
+				//digital to analog on
+				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3]
+				//analog to digital on
+				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8]
+				//rx antenna on
+				//PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
+				//rx antenna on 2008.09.30 mark
+				//PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
+
+				//2 RF
+				//enable RF-Chip A/B
+					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1);		// 0x860[4]
+				rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1);		// 0x864[4]
+				#endif
+						break;
+
+				//
+				// In current solution, RFSleep=RFOff in order to save power under 802.11 power save.
+				// By Bruce, 2008-01-16.
+				//
+			case eRfSleep:
+			case eRfOff:
+				RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOff/Sleep !\n");
+				if (pPSC->bLeisurePs)
+				{
+					for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
+					{
+						switch(QueueID) {
+							case MGNT_QUEUE:
+								tail=priv->txmapringtail;
+								head=priv->txmapringhead;
+								break;
+
+							case BK_QUEUE:
+								tail=priv->txbkpringtail;
+								head=priv->txbkpringhead;
+								break;
+
+							case BE_QUEUE:
+								tail=priv->txbepringtail;
+								head=priv->txbepringhead;
+								break;
+
+							case VI_QUEUE:
+								tail=priv->txvipringtail;
+								head=priv->txvipringhead;
+								break;
+
+							case VO_QUEUE:
+								tail=priv->txvopringtail;
+								head=priv->txvopringhead;
+								break;
+
+							default:
+								tail=head=NULL;
+								break;
+						}
+						if(tail == head)
+						{
+							//DbgPrint("QueueID = %d", QueueID);
+							QueueID++;
+							continue;
+						}
+						else
+						{
+							RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times BusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
+							udelay(10);
+							i++;
+						}
+
+						if(i >= MAX_DOZE_WAITING_TIMES_9x)
+						{
+							RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
+							break;
+						}
+					}
+				}
+				#ifdef RTL8190P
+				if(priv->rf_type == RF_2T4R)
+				{
+					//disable RF-Chip A/B
+					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);		// 0x860[4]
+				}
+				//disable RF-Chip C/D
+				rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x0); // 0x868[4]
+				//analog to digital off, for power save
+				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
+				//digital to analog off, for power save
+				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0x0); // 0x880[8:5]
+				//rx antenna off
+				rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
+				//rx antenna off
+				rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
+				//analog to digital part2 off, for power save
+				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0x0); // 0x880[12:9]
+#else //8192E
+					//2 RF
+				//disable RF-Chip A/B
+				rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);		// 0x860[4]
+					rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x0);		// 0x864[4]
+					//2 AFE
+				//analog to digital off, for power save
+					//PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0x0); //  2008.09.30 Modify
+				//digital to analog off, for power save
+					//PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x0); // 0x880 2008.09.30 Modify
+					//rx antenna off  2008.09.30 mark
+					//PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
+					//rx antenna off  2008.09.30 mark
+					//PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
+				//analog to digital part2 off, for power save
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);		// 0x880[6:5]
+					// 2008.09.30 add
+					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x0); // 0x884
+
+
+					//disable clock 80/88 MHz 2008.09.30 mark
+					//PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x4, 0x0); // 0x880[2]
+					//2 BB
+					// Baseband reset 2008.09.30 add
+					write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); // 0x101
+					//MAC: off
+					write_nic_byte(dev, MacBlkCtrl, 0x0); // 0x403
+					//slow down cpu/lbus clock from 160MHz to Lower
+					write_nic_byte(dev, ANAPAR, 0x07); // 0x 17 40MHz
+				priv->bHwRfOffAction = 0;
+				//}
+				#endif
+					break;
+
+			default:
+					bResult = false;
+					RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
+					break;
+		}
+
+		break;
+
+		default:
+			RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n");
+			break;
+	}
+
+	if(bResult)
+	{
+		// Update current RF state variable.
+		priv->ieee80211->eRFPowerState = eRFPowerState;
+
+		switch(priv->rf_chip )
+		{
+			case RF_8256:
+			switch(priv->ieee80211->eRFPowerState)
+			{
+				case eRfOff:
+				//
+				//If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
+				//
+					if(priv->ieee80211->RfOffReason==RF_CHANGE_BY_IPS )
+					{
+						#ifdef TO_DO
+						Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
+						#endif
+					}
+					else
+					{
+					// Turn off LED if RF is not ON.
+						#ifdef TO_DO
+						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
+						#endif
+					}
+					break;
+
+				case eRfOn:
+				// Turn on RF we are still linked, which might happen when
+				// we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
+					if( priv->ieee80211->state == IEEE80211_LINKED)
+					{
+						#ifdef TO_DO
+						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
+						#endif
+					}
+					else
+					{
+					// Turn off LED if RF is not ON.
+						#ifdef TO_DO
+						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
+						#endif
+					}
+					break;
+
+				default:
+			// do nothing.
+					break;
+			}// Switch RF state
+
+			break;
+
+			default:
+				RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n");
+				break;
+		}// Switch RFChipID
+	}
+
+	priv->SetRFPowerStateInProgress = false;
+	RT_TRACE(COMP_POWER, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult);
+	return bResult;
+}
+
+
+
+//
+//	Description:
+//		Change RF power state.
+//
+//	Assumption:
+//		This function must be executed in re-schdulable context,
+//		ie. PASSIVE_LEVEL.
+//
+//	050823, by rcnjko.
+//
+static bool
+SetRFPowerState(
+	struct net_device* dev,
+	RT_RF_POWER_STATE	eRFPowerState
+	)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	bool bResult = false;
+
+	RT_TRACE(COMP_RF,"---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
+#ifdef RTL8192E
+	if(eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0)
+#else
+	if(eRFPowerState == priv->ieee80211->eRFPowerState)
+#endif
+	{
+		RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
+		return bResult;
+	}
+
+	bResult = SetRFPowerState8190(dev, eRFPowerState);
+
+	RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): bResult(%d)\n", bResult);
+
+	return bResult;
+}
+
+static void
+MgntDisconnectIBSS(
+	struct net_device* dev
+)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//RT_OP_MODE	OpMode;
+	u8			i;
+	bool	bFilterOutNonAssociatedBSSID = false;
+
+	//IEEE80211_DEBUG(IEEE80211_DL_TRACE, "XXXXXXXXXX MgntDisconnect IBSS\n");
+
+	priv->ieee80211->state = IEEE80211_NOLINK;
+
+//	PlatformZeroMemory( pMgntInfo->Bssid, 6 );
+	for(i=0;i<6;i++)  priv->ieee80211->current_network.bssid[i]= 0x55;
+	priv->OpMode = RT_OP_MODE_NO_LINK;
+	write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
+	write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
+	{
+			RT_OP_MODE	OpMode = priv->OpMode;
+			//LED_CTL_MODE	LedAction = LED_CTL_NO_LINK;
+			u8	btMsr = read_nic_byte(dev, MSR);
+
+			btMsr &= 0xfc;
+
+			switch(OpMode)
+			{
+			case RT_OP_MODE_INFRASTRUCTURE:
+				btMsr |= MSR_LINK_MANAGED;
+				//LedAction = LED_CTL_LINK;
+				break;
+
+			case RT_OP_MODE_IBSS:
+				btMsr |= MSR_LINK_ADHOC;
+				// led link set seperate
+				break;
+
+			case RT_OP_MODE_AP:
+				btMsr |= MSR_LINK_MASTER;
+				//LedAction = LED_CTL_LINK;
+				break;
+
+			default:
+				btMsr |= MSR_LINK_NONE;
+				break;
+			}
+
+			write_nic_byte(dev, MSR, btMsr);
+
+			// LED control
+			//Adapter->HalFunc.LedControlHandler(Adapter, LedAction);
+	}
+	ieee80211_stop_send_beacons(priv->ieee80211);
+
+	// If disconnect, clear RCR CBSSID bit
+	bFilterOutNonAssociatedBSSID = false;
+	{
+			u32 RegRCR, Type;
+			Type = bFilterOutNonAssociatedBSSID;
+			RegRCR = read_nic_dword(dev,RCR);
+			priv->ReceiveConfig = RegRCR;
+			if (Type == true)
+				RegRCR |= (RCR_CBSSID);
+			else if (Type == false)
+				RegRCR &= (~RCR_CBSSID);
+
+			{
+				write_nic_dword(dev, RCR,RegRCR);
+				priv->ReceiveConfig = RegRCR;
+			}
+
+		}
+	//MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
+	notify_wx_assoc_event(priv->ieee80211);
+
+}
+
+static void
+MlmeDisassociateRequest(
+	struct net_device* dev,
+	u8* 		asSta,
+	u8			asRsn
+	)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 i;
+
+	RemovePeerTS(priv->ieee80211, asSta);
+
+	SendDisassociation( priv->ieee80211, asSta, asRsn );
+
+	if(memcpy(priv->ieee80211->current_network.bssid,asSta,6) == NULL)
+	{
+		//ShuChen TODO: change media status.
+		//ShuChen TODO: What to do when disassociate.
+		priv->ieee80211->state = IEEE80211_NOLINK;
+		//pMgntInfo->AsocTimestamp = 0;
+		for(i=0;i<6;i++)  priv->ieee80211->current_network.bssid[i] = 0x22;
+//		pMgntInfo->mBrates.Length = 0;
+//		Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
+		priv->OpMode = RT_OP_MODE_NO_LINK;
+		{
+			RT_OP_MODE	OpMode = priv->OpMode;
+			//LED_CTL_MODE	LedAction = LED_CTL_NO_LINK;
+			u8 btMsr = read_nic_byte(dev, MSR);
+
+			btMsr &= 0xfc;
+
+			switch(OpMode)
+			{
+			case RT_OP_MODE_INFRASTRUCTURE:
+				btMsr |= MSR_LINK_MANAGED;
+				//LedAction = LED_CTL_LINK;
+				break;
+
+			case RT_OP_MODE_IBSS:
+				btMsr |= MSR_LINK_ADHOC;
+				// led link set seperate
+				break;
+
+			case RT_OP_MODE_AP:
+				btMsr |= MSR_LINK_MASTER;
+				//LedAction = LED_CTL_LINK;
+				break;
+
+			default:
+				btMsr |= MSR_LINK_NONE;
+				break;
+			}
+
+			write_nic_byte(dev, MSR, btMsr);
+
+			// LED control
+			//Adapter->HalFunc.LedControlHandler(Adapter, LedAction);
+		}
+		ieee80211_disassociate(priv->ieee80211);
+
+		write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
+		write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
+
+	}
+
+}
+
+
+static void
+MgntDisconnectAP(
+	struct net_device* dev,
+	u8 asRsn
+)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool bFilterOutNonAssociatedBSSID = false;
+
+//
+// Commented out by rcnjko, 2005.01.27:
+// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
+//
+//	//2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
+//	SecClearAllKeys(Adapter);
+
+	// In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
+#ifdef TO_DO
+	if(   pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
+		(pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) )	// In CCKM mode will Clear key
+	{
+		SecClearAllKeys(Adapter);
+		RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
+	}
+#endif
+	// If disconnect, clear RCR CBSSID bit
+	bFilterOutNonAssociatedBSSID = false;
+	{
+			u32 RegRCR, Type;
+
+			Type = bFilterOutNonAssociatedBSSID;
+			//Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RCR, (pu1Byte)(&RegRCR));
+			RegRCR = read_nic_dword(dev,RCR);
+			priv->ReceiveConfig = RegRCR;
+
+			if (Type == true)
+				RegRCR |= (RCR_CBSSID);
+			else if (Type == false)
+				RegRCR &= (~RCR_CBSSID);
+
+			write_nic_dword(dev, RCR,RegRCR);
+			priv->ReceiveConfig = RegRCR;
+
+
+	}
+	// 2004.10.11, by rcnjko.
+	//MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
+	MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
+
+	priv->ieee80211->state = IEEE80211_NOLINK;
+	//pMgntInfo->AsocTimestamp = 0;
+}
+
+
+static bool
+MgntDisconnect(
+	struct net_device* dev,
+	u8 asRsn
+)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//
+	// Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
+	//
+#ifdef TO_DO
+	if(pMgntInfo->mPss != eAwake)
+	{
+		//
+		// Using AwkaeTimer to prevent mismatch ps state.
+		// In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
+		//
+		// PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
+		PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
+	}
+#endif
+	// Follow 8180 AP mode, 2005.05.30, by rcnjko.
+#ifdef TO_DO
+	if(pMgntInfo->mActingAsAp)
+	{
+		RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> AP_DisassociateAllStation\n"));
+		AP_DisassociateAllStation(Adapter, unspec_reason);
+		return TRUE;
+	}
+#endif
+	// Indication of disassociation event.
+	//DrvIFIndicateDisassociation(Adapter, asRsn);
+
+	// In adhoc mode, update beacon frame.
+	if( priv->ieee80211->state == IEEE80211_LINKED )
+	{
+		if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
+		{
+			//RT_TRACE(COMP_MLME, "MgntDisconnect() ===> MgntDisconnectIBSS\n");
+			MgntDisconnectIBSS(dev);
+		}
+		if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
+		{
+			// We clear key here instead of MgntDisconnectAP() because that
+			// MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
+			// e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
+			// used to handle disassociation related things to AP, e.g. send Disassoc
+			// frame to AP.  2005.01.27, by rcnjko.
+			//IEEE80211_DEBUG(IEEE80211_DL_TRACE,"MgntDisconnect() ===> MgntDisconnectAP\n");
+			MgntDisconnectAP(dev, asRsn);
+		}
+
+		// Inidicate Disconnect, 2005.02.23, by rcnjko.
+		//MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
+	}
+
+	return true;
+}
+
+//
+//	Description:
+//		Chang RF Power State.
+//		Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
+//
+//	Assumption:
+//		PASSIVE LEVEL.
+//
+bool
+MgntActSet_RF_State(
+	struct net_device* dev,
+	RT_RF_POWER_STATE	StateToSet,
+	RT_RF_CHANGE_SOURCE ChangeSource
+	)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool 			bActionAllowed = false;
+	bool 			bConnectBySSID = false;
+	RT_RF_POWER_STATE	rtState;
+	u16					RFWaitCounter = 0;
+	unsigned long flag;
+	RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet);
+
+	//1//
+	//1//<1>Prevent the race condition of RF state change.
+	//1//
+	// Only one thread can change the RF state at one time, and others should wait to be executed. By Bruce, 2007-11-28.
+
+	while(true)
+	{
+		spin_lock_irqsave(&priv->rf_ps_lock,flag);
+		if(priv->RFChangeInProgress)
+		{
+			spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
+			RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet);
+
+			// Set RF after the previous action is done.
+			while(priv->RFChangeInProgress)
+			{
+				RFWaitCounter ++;
+				RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter);
+				udelay(1000); // 1 ms
+
+				// Wait too long, return FALSE to avoid to be stuck here.
+				if(RFWaitCounter > 100)
+				{
+					RT_TRACE(COMP_ERR, "MgntActSet_RF_State(): Wait too logn to set RF\n");
+					// TODO: Reset RF state?
+					return false;
+				}
+			}
+		}
+		else
+		{
+			priv->RFChangeInProgress = true;
+			spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
+			break;
+		}
+	}
+
+	rtState = priv->ieee80211->eRFPowerState;
+
+	switch(StateToSet)
+	{
+	case eRfOn:
+		//
+		// Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
+		// the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
+		//
+
+		priv->ieee80211->RfOffReason &= (~ChangeSource);
+
+		if(! priv->ieee80211->RfOffReason)
+		{
+			priv->ieee80211->RfOffReason = 0;
+			bActionAllowed = true;
+
+
+			if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW )
+			{
+				bConnectBySSID = true;
+			}
+		}
+		else
+			RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->ieee80211->RfOffReason, ChangeSource);
+
+		break;
+
+	case eRfOff:
+
+			if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
+			{
+				//
+				// 060808, Annie:
+				// Disconnect to current BSS when radio off. Asked by QuanTa.
+				//
+				// Set all link status falg, by Bruce, 2007-06-26.
+				//MgntActSet_802_11_DISASSOCIATE( Adapter, disas_lv_ss );
+				MgntDisconnect(dev, disas_lv_ss);
+
+				// Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
+				// 2007.05.28, by shien chang.
+
+			}
+
+
+		priv->ieee80211->RfOffReason |= ChangeSource;
+		bActionAllowed = true;
+		break;
+
+	case eRfSleep:
+		priv->ieee80211->RfOffReason |= ChangeSource;
+		bActionAllowed = true;
+		break;
+
+	default:
+		break;
+	}
+
+	if(bActionAllowed)
+	{
+		RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason);
+				// Config HW to the specified mode.
+		SetRFPowerState(dev, StateToSet);
+		// Turn on RF.
+		if(StateToSet == eRfOn)
+		{
+			//Adapter->HalFunc.HalEnableRxHandler(Adapter);
+			if(bConnectBySSID)
+			{
+				//MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
+			}
+		}
+		// Turn off RF.
+		else if(StateToSet == eRfOff)
+		{
+			//Adapter->HalFunc.HalDisableRxHandler(Adapter);
+		}
+	}
+	else
+	{
+		RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->ieee80211->RfOffReason);
+	}
+
+	// Release RF spinlock
+	spin_lock_irqsave(&priv->rf_ps_lock,flag);
+	priv->RFChangeInProgress = false;
+	spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
+
+	RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n");
+	return bActionAllowed;
+}
+
+
diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h
new file mode 100644
index 0000000..7d9095a
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8190_rtl8256.h
@@ -0,0 +1,28 @@
+/*
+  This is part of the rtl8180-sa2400 driver
+  released under the GPL (See file COPYING for details).
+  Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
+
+  This files contains programming code for the rtl8256
+  radio frontend.
+
+  *Many* thanks to Realtek Corp. for their great support!
+
+*/
+
+#ifndef RTL8225H
+#define RTL8225H
+
+#ifdef RTL8190P
+#define RTL819X_TOTAL_RF_PATH	4
+#else
+#define RTL819X_TOTAL_RF_PATH 2 //for 8192E
+#endif
+extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
+extern RT_STATUS PHY_RF8256_Config(struct net_device* dev);
+extern RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev);
+extern void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel);
+extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
+extern bool MgntActSet_RF_State(struct net_device* dev, RT_RF_POWER_STATE StateToSet, RT_RF_CHANGE_SOURCE ChangeSource);
+
+#endif
diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h
new file mode 100644
index 0000000..61b6f25
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192E.h
@@ -0,0 +1,1516 @@
+/*
+   This is part of rtl8187 OpenSource driver.
+   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+   Released under the terms of GPL (General Public Licence)
+
+   Parts of this driver are based on the GPL part of the
+   official realtek driver
+
+   Parts of this driver are based on the rtl8192 driver skeleton
+   from Patric Schenke & Andres Salomon
+
+   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
+
+   We want to tanks the Authors of those projects and the Ndiswrapper
+   project Authors.
+*/
+
+#ifndef R819xU_H
+#define R819xU_H
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+//#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+//#include <linux/usb.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/rtnetlink.h>	//for rtnl_lock()
+#include <linux/wireless.h>
+#include <linux/timer.h>
+#include <linux/proc_fs.h>	// Necessary because we use the proc fs
+#include <linux/if_arp.h>
+#include <linux/random.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include "ieee80211.h"
+
+
+
+
+#define RTL819xE_MODULE_NAME "rtl819xE"
+//added for HW security, john.0629
+#define FALSE 0
+#define TRUE 1
+#define MAX_KEY_LEN     61
+#define KEY_BUF_SIZE    5
+
+#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
+// Rx smooth factor
+#define	Rx_Smooth_Factor		20
+/* 2007/06/04 MH Define sliding window for RSSI history. */
+#define		PHY_RSSI_SLID_WIN_MAX				100
+#define		PHY_Beacon_RSSI_SLID_WIN_MAX		10
+
+#define IC_VersionCut_D	0x3
+#define IC_VersionCut_E	0x4
+
+#if 0 //we need to use RT_TRACE instead DMESG as RT_TRACE will clearly show debug level wb.
+#define DMESG(x,a...) printk(KERN_INFO RTL819xE_MODULE_NAME ": " x "\n", ## a)
+#define DMESGW(x,a...) printk(KERN_WARNING RTL819xE_MODULE_NAME ": WW:" x "\n", ## a)
+#define DMESGE(x,a...) printk(KERN_WARNING RTL819xE_MODULE_NAME ": EE:" x "\n", ## a)
+#else
+#define DMESG(x,a...)
+#define DMESGW(x,a...)
+#define DMESGE(x,a...)
+extern u32 rt_global_debug_component;
+#define RT_TRACE(component, x, args...) \
+do { if(rt_global_debug_component & component) \
+	printk(KERN_DEBUG RTL819xE_MODULE_NAME ":" x "\n" , \
+	       ##args);\
+}while(0);
+
+#define COMP_TRACE				BIT0		// For function call tracing.
+#define COMP_DBG				BIT1		// Only for temporary debug message.
+#define COMP_INIT				BIT2		// during driver initialization / halt / reset.
+
+
+#define COMP_RECV				BIT3		// Reveive part data path.
+#define COMP_SEND				BIT4		// Send part path.
+#define COMP_IO					BIT5		// I/O Related. Added by Annie, 2006-03-02.
+#define COMP_POWER				BIT6		// 802.11 Power Save mode or System/Device Power state related.
+#define COMP_EPROM				BIT7		// 802.11 link related: join/start BSS, leave BSS.
+#define COMP_SWBW				BIT8	// For bandwidth switch.
+#define COMP_SEC				BIT9// For Security.
+
+
+#define COMP_TURBO				BIT10	// For Turbo Mode related. By Annie, 2005-10-21.
+#define COMP_QOS				BIT11	// For QoS.
+
+#define COMP_RATE				BIT12	// For Rate Adaptive mechanism, 2006.07.02, by rcnjko. #define COMP_EVENTS				0x00000080	// Event handling
+#define COMP_RXDESC			        BIT13	// Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15.
+#define COMP_PHY				BIT14
+#define COMP_DIG				BIT15	// For DIG, 2006.09.25, by rcnjko.
+#define COMP_TXAGC				BIT16	// For Tx power, 060928, by rcnjko.
+#define COMP_HALDM				BIT17	// For HW Dynamic Mechanism, 061010, by rcnjko.
+#define COMP_POWER_TRACKING	                BIT18	//FOR 8190 TX POWER TRACKING
+#define COMP_EVENTS			        BIT19	// Event handling
+
+#define COMP_RF					BIT20	// For RF.
+//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//1//1Attention Please!!!<11n or 8190 specific code should be put below this line>
+//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+#define COMP_FIRMWARE			        BIT21	//for firmware downloading
+#define COMP_HT					BIT22	// For 802.11n HT related information. by Emily 2006-8-11
+
+#define COMP_RESET				BIT23
+#define COMP_CMDPKT			        BIT24
+#define COMP_SCAN				BIT25
+#define COMP_IPS				BIT26
+#define COMP_DOWN				BIT27  // for rm driver module
+#define COMP_INTR 				BIT28  // for interrupt
+#define COMP_ERR				BIT31  // for error out, always on
+#endif
+
+#define RTL819x_DEBUG
+#ifdef RTL819x_DEBUG
+#define assert(expr) \
+        if (!(expr)) {                                  \
+                printk( "Assertion failed! %s,%s,%s,line=%d\n", \
+                #expr,__FILE__,__FUNCTION__,__LINE__);          \
+        }
+//wb added to debug out data buf
+//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
+#define RT_DEBUG_DATA(level, data, datalen)      \
+        do{ if ((rt_global_debug_component & (level)) == (level))   \
+                {       \
+                        int i;                                  \
+                        u8* pdata = (u8*) data;                 \
+                        printk(KERN_DEBUG RTL819xE_MODULE_NAME ": %s()\n", __FUNCTION__);   \
+                        for(i=0; i<(int)(datalen); i++)                 \
+                        {                                               \
+                                printk("%2x ", pdata[i]);               \
+                                if ((i+1)%16 == 0) printk("\n");        \
+                        }                               \
+                        printk("\n");                   \
+                }                                       \
+        } while (0)
+#else
+#define assert(expr) do {} while (0)
+#define RT_DEBUG_DATA(level, data, datalen) do {} while(0)
+#endif /* RTL8169_DEBUG */
+
+
+//
+// Queue Select Value in TxDesc
+//
+#define QSLT_BK                                 0x1
+#define QSLT_BE                                 0x0
+#define QSLT_VI                                 0x4
+#define QSLT_VO                                 0x6
+#define QSLT_BEACON                             0x10
+#define QSLT_HIGH                               0x11
+#define QSLT_MGNT                               0x12
+#define QSLT_CMD                                0x13
+
+#define DESC90_RATE1M                           0x00
+#define DESC90_RATE2M                           0x01
+#define DESC90_RATE5_5M                         0x02
+#define DESC90_RATE11M                          0x03
+#define DESC90_RATE6M                           0x04
+#define DESC90_RATE9M                           0x05
+#define DESC90_RATE12M                          0x06
+#define DESC90_RATE18M                          0x07
+#define DESC90_RATE24M                          0x08
+#define DESC90_RATE36M                          0x09
+#define DESC90_RATE48M                          0x0a
+#define DESC90_RATE54M                          0x0b
+#define DESC90_RATEMCS0                         0x00
+#define DESC90_RATEMCS1                         0x01
+#define DESC90_RATEMCS2                         0x02
+#define DESC90_RATEMCS3                         0x03
+#define DESC90_RATEMCS4                         0x04
+#define DESC90_RATEMCS5                         0x05
+#define DESC90_RATEMCS6                         0x06
+#define DESC90_RATEMCS7                         0x07
+#define DESC90_RATEMCS8                         0x08
+#define DESC90_RATEMCS9                         0x09
+#define DESC90_RATEMCS10                        0x0a
+#define DESC90_RATEMCS11                        0x0b
+#define DESC90_RATEMCS12                        0x0c
+#define DESC90_RATEMCS13                        0x0d
+#define DESC90_RATEMCS14                        0x0e
+#define DESC90_RATEMCS15                        0x0f
+#define DESC90_RATEMCS32                        0x20
+
+#define RTL819X_DEFAULT_RF_TYPE RF_1T2R
+#define EEPROM_Default_LegacyHTTxPowerDiff	0x4
+#define IEEE80211_WATCH_DOG_TIME    2000
+
+/* For rtl819x */
+typedef struct _tx_desc_819x_pci {
+        //DWORD 0
+        u16	PktSize;
+        u8	Offset;
+        u8	Reserved1:3;
+        u8	CmdInit:1;
+        u8	LastSeg:1;
+        u8	FirstSeg:1;
+        u8	LINIP:1;
+        u8	OWN:1;
+
+        //DWORD 1
+        u8	TxFWInfoSize;
+        u8	RATid:3;
+        u8	DISFB:1;
+        u8	USERATE:1;
+        u8	MOREFRAG:1;
+        u8	NoEnc:1;
+        u8	PIFS:1;
+        u8	QueueSelect:5;
+        u8	NoACM:1;
+        u8	Resv:2;
+        u8	SecCAMID:5;
+        u8	SecDescAssign:1;
+        u8	SecType:2;
+
+        //DWORD 2
+        u16	TxBufferSize;
+        u8	PktId:7;
+        u8	Resv1:1;
+        u8	Reserved2;
+
+        //DWORD 3
+	u32 	TxBuffAddr;
+
+	//DWORD 4
+	u32	NextDescAddress;
+
+	//DWORD 5,6,7
+        u32	Reserved5;
+        u32	Reserved6;
+        u32	Reserved7;
+}tx_desc_819x_pci, *ptx_desc_819x_pci;
+
+
+typedef struct _tx_desc_cmd_819x_pci {
+        //DWORD 0
+	u16	PktSize;
+	u8	Reserved1;
+	u8	CmdType:3;
+	u8	CmdInit:1;
+	u8	LastSeg:1;
+	u8	FirstSeg:1;
+	u8	LINIP:1;
+	u8	OWN:1;
+
+        //DOWRD 1
+	u16	ElementReport;
+	u16	Reserved2;
+
+        //DOWRD 2
+	u16 	TxBufferSize;
+	u16	Reserved3;
+
+       //DWORD 3,4,5
+	u32	TxBufferAddr;
+	u32	NextDescAddress;
+	u32	Reserved4;
+	u32	Reserved5;
+	u32	Reserved6;
+}tx_desc_cmd_819x_pci, *ptx_desc_cmd_819x_pci;
+
+
+typedef struct _tx_fwinfo_819x_pci {
+        //DOWRD 0
+        u8		TxRate:7;
+        u8		CtsEnable:1;
+        u8		RtsRate:7;
+        u8		RtsEnable:1;
+        u8		TxHT:1;
+        u8		Short:1;                //Short PLCP for CCK, or short GI for 11n MCS
+        u8		TxBandwidth:1;          // This is used for HT MCS rate only.
+        u8		TxSubCarrier:2;         // This is used for legacy OFDM rate only.
+        u8		STBC:2;
+        u8		AllowAggregation:1;
+        u8		RtsHT:1;                //Interpre RtsRate field as high throughput data rate
+        u8		RtsShort:1;             //Short PLCP for CCK, or short GI for 11n MCS
+        u8		RtsBandwidth:1;         // This is used for HT MCS rate only.
+        u8		RtsSubcarrier:2;        // This is used for legacy OFDM rate only.
+        u8		RtsSTBC:2;
+        u8		EnableCPUDur:1;         //Enable firmware to recalculate and assign packet duration
+
+        //DWORD 1
+        u8		RxMF:2;
+        u8		RxAMD:3;
+        u8		Reserved1:3;
+        u8		Reserved2;
+        u8		Reserved3;
+        u8		Reserved4;
+
+        //u32                Reserved;
+}tx_fwinfo_819x_pci, *ptx_fwinfo_819x_pci;
+
+typedef struct rtl8192_rx_info {
+	struct urb *urb;
+	struct net_device *dev;
+	u8 out_pipe;
+}rtl8192_rx_info ;
+typedef struct _rx_desc_819x_pci{
+	//DOWRD 0
+	u16			Length:14;
+	u16			CRC32:1;
+	u16			ICV:1;
+	u8			RxDrvInfoSize;
+	u8			Shift:2;
+	u8			PHYStatus:1;
+	u8			SWDec:1;
+	u8					LastSeg:1;
+	u8					FirstSeg:1;
+	u8					EOR:1;
+	u8					OWN:1;
+
+	//DWORD 1
+	u32			Reserved2;
+
+	//DWORD 2
+	u32			Reserved3;
+
+	//DWORD 3
+	u32	BufferAddress;
+
+}rx_desc_819x_pci, *prx_desc_819x_pci;
+
+typedef struct _rx_fwinfo_819x_pci{
+	//DWORD 0
+	u16			Reserved1:12;
+	u16			PartAggr:1;
+	u16			FirstAGGR:1;
+	u16			Reserved2:2;
+
+	u8			RxRate:7;
+	u8			RxHT:1;
+
+	u8			BW:1;
+	u8			SPLCP:1;
+	u8			Reserved3:2;
+	u8			PAM:1;
+	u8			Mcast:1;
+	u8			Bcast:1;
+	u8			Reserved4:1;
+
+	//DWORD 1
+	u32			TSFL;
+
+}rx_fwinfo_819x_pci, *prx_fwinfo_819x_pci;
+
+#define MAX_DEV_ADDR_SIZE		8  /* support till 64 bit bus width OS */
+#define MAX_FIRMWARE_INFORMATION_SIZE   32 /*2006/04/30 by Emily forRTL8190*/
+#define MAX_802_11_HEADER_LENGTH        (40 + MAX_FIRMWARE_INFORMATION_SIZE)
+#define ENCRYPTION_MAX_OVERHEAD		128
+//#define	USB_HWDESC_HEADER_LEN		sizeof(tx_desc_819x_usb)
+//#define TX_PACKET_SHIFT_BYTES 	  	(USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb))
+#define MAX_FRAGMENT_COUNT		8
+#define MAX_TRANSMIT_BUFFER_SIZE  	(1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT)
+
+#define scrclng					4		// octets for crc32 (FCS, ICV)
+/* 8190 Loopback Mode definition */
+typedef enum _rtl819x_loopback{
+	RTL819X_NO_LOOPBACK = 0,
+	RTL819X_MAC_LOOPBACK = 1,
+	RTL819X_DMA_LOOPBACK = 2,
+	RTL819X_CCK_LOOPBACK = 3,
+}rtl819x_loopback_e;
+
+/* due to rtl8192 firmware */
+typedef enum _desc_packet_type_e{
+	DESC_PACKET_TYPE_INIT = 0,
+	DESC_PACKET_TYPE_NORMAL = 1,
+}desc_packet_type_e;
+
+typedef enum _firmware_source{
+	FW_SOURCE_IMG_FILE = 0,
+	FW_SOURCE_HEADER_FILE = 1,		//from header file
+}firmware_source_e, *pfirmware_source_e;
+
+typedef enum _firmware_status{
+	FW_STATUS_0_INIT = 0,
+	FW_STATUS_1_MOVE_BOOT_CODE = 1,
+	FW_STATUS_2_MOVE_MAIN_CODE = 2,
+	FW_STATUS_3_TURNON_CPU = 3,
+	FW_STATUS_4_MOVE_DATA_CODE = 4,
+	FW_STATUS_5_READY = 5,
+}firmware_status_e;
+
+typedef struct _rt_firmare_seg_container {
+	u16	seg_size;
+	u8	*seg_ptr;
+}fw_seg_container, *pfw_seg_container;
+
+typedef struct _rt_firmware{
+	firmware_status_e firmware_status;
+	u16		  cmdpacket_frag_thresold;
+#define RTL8190_MAX_FIRMWARE_CODE_SIZE	64000	//64k
+#define MAX_FW_INIT_STEP		3
+	u8		  firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE];
+	u16		  firmware_buf_size[MAX_FW_INIT_STEP];
+}rt_firmware, *prt_firmware;
+//+by amy 080507
+#define MAX_RECEIVE_BUFFER_SIZE	9100	// Add this to 9100 bytes to receive A-MSDU from RT-AP
+
+/* Firmware Queue Layout */
+#define NUM_OF_FIRMWARE_QUEUE		10
+#define NUM_OF_PAGES_IN_FW		0x100
+#define NUM_OF_PAGE_IN_FW_QUEUE_BE	0x0aa
+#define NUM_OF_PAGE_IN_FW_QUEUE_BK	0x007
+#define NUM_OF_PAGE_IN_FW_QUEUE_VI	0x024
+#define NUM_OF_PAGE_IN_FW_QUEUE_VO	0x007
+#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_CMD	0x2
+#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT	0x10
+#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH	0
+#define NUM_OF_PAGE_IN_FW_QUEUE_BCN	0x4
+#define NUM_OF_PAGE_IN_FW_QUEUE_PUB	0xd
+#define APPLIED_RESERVED_QUEUE_IN_FW	0x80000000
+#define RSVD_FW_QUEUE_PAGE_BK_SHIFT	0x00
+#define RSVD_FW_QUEUE_PAGE_BE_SHIFT	0x08
+#define RSVD_FW_QUEUE_PAGE_VI_SHIFT	0x10
+#define RSVD_FW_QUEUE_PAGE_VO_SHIFT	0x18
+#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT	0x10
+#define RSVD_FW_QUEUE_PAGE_CMD_SHIFT	0x08
+#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT	0x00
+#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT	0x08
+
+//8187B Security
+//#define RWCAM                   0xA0                    // Software read/write CAM config
+//#define WCAMI                   0xA4                    // Software write CAM input content
+//#define RCAMO                   0xA8                    // Output value from CAM according to 0xa0 setting
+#define DCAM                    0xAC                    // Debug CAM Interface
+#define AESMSK_FC               0xB2    // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06.
+
+
+#define CAM_CONTENT_COUNT       8
+//#define CFG_DEFAULT_KEY         BIT5
+#define CFG_VALID               BIT15
+#if 0
+//----------------------------------------------------------------------------
+//       8187B WPA Config Register (offset 0xb0, 1 byte)
+//----------------------------------------------------------------------------
+#define SCR_UseDK                       0x01
+#define SCR_TxSecEnable                 0x02
+#define SCR_RxSecEnable                 0x04
+
+//----------------------------------------------------------------------------
+//       8187B CAM Config Setting (offset 0xb0, 1 byte)
+//----------------------------------------------------------------------------
+#define CAM_VALID                               0x8000
+#define CAM_NOTVALID                    0x0000
+#define CAM_USEDK                               0x0020
+
+
+#define CAM_NONE                                0x0
+#define CAM_WEP40                               0x01
+#define CAM_TKIP                                0x02
+#define CAM_AES                                 0x04
+#define CAM_WEP104                              0x05
+
+//#define CAM_SIZE                              16
+#define TOTAL_CAM_ENTRY         16
+#define CAM_ENTRY_LEN_IN_DW     6       // 6, unit: in u4byte. Added by Annie, 2006-05-25.
+#define CAM_ENTRY_LEN_IN_BYTE   (CAM_ENTRY_LEN_IN_DW*sizeof(u32))    // 24, unit: in u1byte. Added by Annie, 2006-05-25.
+
+#define CAM_CONFIG_USEDK                1
+#define CAM_CONFIG_NO_USEDK             0
+
+#define CAM_WRITE                               0x00010000
+#define CAM_READ                                0x00000000
+#define CAM_POLLINIG                    0x80000000
+
+//=================================================================
+//=================================================================
+
+#endif
+#define EPROM_93c46 0
+#define EPROM_93c56 1
+
+#define DEFAULT_FRAG_THRESHOLD 2342U
+#define MIN_FRAG_THRESHOLD     256U
+#define DEFAULT_BEACONINTERVAL 0x64U
+#define DEFAULT_BEACON_ESSID "Rtl819xU"
+
+#define DEFAULT_SSID ""
+#define DEFAULT_RETRY_RTS 7
+#define DEFAULT_RETRY_DATA 7
+#define PRISM_HDR_SIZE 64
+
+#define		PHY_RSSI_SLID_WIN_MAX				100
+
+
+typedef enum _WIRELESS_MODE {
+	WIRELESS_MODE_UNKNOWN = 0x00,
+	WIRELESS_MODE_A = 0x01,
+	WIRELESS_MODE_B = 0x02,
+	WIRELESS_MODE_G = 0x04,
+	WIRELESS_MODE_AUTO = 0x08,
+	WIRELESS_MODE_N_24G = 0x10,
+	WIRELESS_MODE_N_5G = 0x20
+} WIRELESS_MODE;
+
+#define RTL_IOCTL_WPA_SUPPLICANT		SIOCIWFIRSTPRIV+30
+
+typedef struct buffer
+{
+	struct buffer *next;
+	u32 *buf;
+	dma_addr_t dma;
+
+} buffer;
+
+typedef struct rtl_reg_debug{
+        unsigned int  cmd;
+        struct {
+                unsigned char type;
+                unsigned char addr;
+                unsigned char page;
+                unsigned char length;
+        } head;
+        unsigned char buf[0xff];
+}rtl_reg_debug;
+
+#if 0
+
+typedef struct tx_pendingbuf
+{
+	struct ieee80211_txb *txb;
+	short ispending;
+	short descfrag;
+} tx_pendigbuf;
+
+#endif
+
+typedef struct _rt_9x_tx_rate_history {
+	u32             cck[4];
+	u32             ofdm[8];
+	// HT_MCS[0][]: BW=0 SG=0
+	// HT_MCS[1][]: BW=1 SG=0
+	// HT_MCS[2][]: BW=0 SG=1
+	// HT_MCS[3][]: BW=1 SG=1
+	u32             ht_mcs[4][16];
+}rt_tx_rahis_t, *prt_tx_rahis_t;
+
+typedef	struct _RT_SMOOTH_DATA_4RF {
+	char	elements[4][100];//array to store values
+	u32	index;			//index to current array to store
+	u32	TotalNum;		//num of valid elements
+	u32	TotalVal[4];		//sum of valid elements
+}RT_SMOOTH_DATA_4RF, *PRT_SMOOTH_DATA_4RF;
+
+typedef enum _tag_TxCmd_Config_Index{
+	TXCMD_TXRA_HISTORY_CTRL				= 0xFF900000,
+	TXCMD_RESET_TX_PKT_BUFF				= 0xFF900001,
+	TXCMD_RESET_RX_PKT_BUFF				= 0xFF900002,
+	TXCMD_SET_TX_DURATION				= 0xFF900003,
+	TXCMD_SET_RX_RSSI						= 0xFF900004,
+	TXCMD_SET_TX_PWR_TRACKING			= 0xFF900005,
+	TXCMD_XXXX_CTRL,
+}DCMD_TXCMD_OP;
+
+typedef struct Stats
+{
+	unsigned long txrdu;
+	unsigned long rxrdu;
+	//unsigned long rxnolast;
+	//unsigned long rxnodata;
+//	unsigned long rxreset;
+//	unsigned long rxnopointer;
+	unsigned long rxok;
+	unsigned long rxframgment;
+	unsigned long rxcmdpkt[4];		//08/05/08 amy rx cmd element txfeedback/bcn report/cfg set/query
+	unsigned long rxurberr;
+	unsigned long rxstaterr;
+	unsigned long rxcrcerrmin;//crc error (0-500)
+	unsigned long rxcrcerrmid;//crc error (500-1000)
+	unsigned long rxcrcerrmax;//crc error (>1000)
+	unsigned long received_rate_histogram[4][32];	//0: Total, 1:OK, 2:CRC, 3:ICV, 2007 07 03 cosa
+	unsigned long received_preamble_GI[2][32];		//0: Long preamble/GI, 1:Short preamble/GI
+	unsigned long	rx_AMPDUsize_histogram[5]; // level: (<4K), (4K~8K), (8K~16K), (16K~32K), (32K~64K)
+	unsigned long rx_AMPDUnum_histogram[5]; // level: (<5), (5~10), (10~20), (20~40), (>40)
+	unsigned long numpacket_matchbssid;	// debug use only.
+	unsigned long numpacket_toself;		// debug use only.
+	unsigned long num_process_phyinfo;		// debug use only.
+	unsigned long numqry_phystatus;
+	unsigned long numqry_phystatusCCK;
+	unsigned long numqry_phystatusHT;
+	unsigned long received_bwtype[5];              //0: 20M, 1: funn40M, 2: upper20M, 3: lower20M, 4: duplicate
+	unsigned long txnperr;
+	unsigned long txnpdrop;
+	unsigned long txresumed;
+//	unsigned long rxerr;
+	unsigned long rxoverflow;
+	unsigned long rxint;
+	unsigned long txnpokint;
+//	unsigned long txhpokint;
+//	unsigned long txhperr;
+	unsigned long ints;
+	unsigned long shints;
+	unsigned long txoverflow;
+//	unsigned long rxdmafail;
+//	unsigned long txbeacon;
+//	unsigned long txbeaconerr;
+	unsigned long txlpokint;
+	unsigned long txlpdrop;
+	unsigned long txlperr;
+	unsigned long txbeokint;
+	unsigned long txbedrop;
+	unsigned long txbeerr;
+	unsigned long txbkokint;
+	unsigned long txbkdrop;
+	unsigned long txbkerr;
+	unsigned long txviokint;
+	unsigned long txvidrop;
+	unsigned long txvierr;
+	unsigned long txvookint;
+	unsigned long txvodrop;
+	unsigned long txvoerr;
+	unsigned long txbeaconokint;
+	unsigned long txbeacondrop;
+	unsigned long txbeaconerr;
+	unsigned long txmanageokint;
+	unsigned long txmanagedrop;
+	unsigned long txmanageerr;
+	unsigned long txcmdpktokint;
+	unsigned long txdatapkt;
+	unsigned long txfeedback;
+	unsigned long txfeedbackok;
+	unsigned long txoktotal;
+	unsigned long txokbytestotal;
+	unsigned long txokinperiod;
+	unsigned long txmulticast;
+	unsigned long txbytesmulticast;
+	unsigned long txbroadcast;
+	unsigned long txbytesbroadcast;
+	unsigned long txunicast;
+	unsigned long txbytesunicast;
+	unsigned long rxbytesunicast;
+	unsigned long txfeedbackfail;
+	unsigned long txerrtotal;
+	unsigned long txerrbytestotal;
+	unsigned long txerrmulticast;
+	unsigned long txerrbroadcast;
+	unsigned long txerrunicast;
+	unsigned long txretrycount;
+	unsigned long txfeedbackretry;
+	u8			last_packet_rate;
+	unsigned long slide_signal_strength[100];
+	unsigned long slide_evm[100];
+	unsigned long	slide_rssi_total;	// For recording sliding window's RSSI value
+	unsigned long slide_evm_total;	// For recording sliding window's EVM value
+	long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct.
+	long signal_quality;
+	long last_signal_strength_inpercent;
+	long	recv_signal_power;	// Correct smoothed ss in Dbm, only used in driver to report real power now.
+	u8 rx_rssi_percentage[4];
+	u8 rx_evm_percentage[2];
+	long rxSNRdB[4];
+	rt_tx_rahis_t txrate;
+	u32 Slide_Beacon_pwdb[100];	//cosa add for beacon rssi
+	u32 Slide_Beacon_Total;		//cosa add for beacon rssi
+	RT_SMOOTH_DATA_4RF		cck_adc_pwdb;
+	u32	CurrentShowTxate;
+
+
+} Stats;
+
+
+// Bandwidth Offset
+#define HAL_PRIME_CHNL_OFFSET_DONT_CARE		0
+#define HAL_PRIME_CHNL_OFFSET_LOWER			1
+#define HAL_PRIME_CHNL_OFFSET_UPPER			2
+
+//+by amy 080507
+
+typedef struct 	ChnlAccessSetting {
+	u16 SIFS_Timer;
+	u16 DIFS_Timer;
+	u16 SlotTimeTimer;
+	u16 EIFS_Timer;
+	u16 CWminIndex;
+	u16 CWmaxIndex;
+}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
+
+typedef struct _BB_REGISTER_DEFINITION{
+	u32 rfintfs; 			// set software control: //		0x870~0x877[8 bytes]
+	u32 rfintfi; 			// readback data: //		0x8e0~0x8e7[8 bytes]
+	u32 rfintfo; 			// output data: //		0x860~0x86f [16 bytes]
+	u32 rfintfe; 			// output enable: //		0x860~0x86f [16 bytes]
+	u32 rf3wireOffset; 		// LSSI data: //		0x840~0x84f [16 bytes]
+	u32 rfLSSI_Select; 		// BB Band Select: //		0x878~0x87f [8 bytes]
+	u32 rfTxGainStage;		// Tx gain stage: //		0x80c~0x80f [4 bytes]
+	u32 rfHSSIPara1; 		// wire parameter control1 : //		0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes]
+	u32 rfHSSIPara2; 		// wire parameter control2 : //		0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes]
+	u32 rfSwitchControl; 	//Tx Rx antenna control : //		0x858~0x85f [16 bytes]
+	u32 rfAGCControl1; 	//AGC parameter control1 : //		0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes]
+	u32 rfAGCControl2; 	//AGC parameter control2 : //		0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes]
+	u32 rfRxIQImbalance; 	//OFDM Rx IQ imbalance matrix : //		0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes]
+	u32 rfRxAFE;  			//Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : //		0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes]
+	u32 rfTxIQImbalance; 	//OFDM Tx IQ imbalance matrix //		0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes]
+	u32 rfTxAFE; 			//Tx IQ DC Offset and Tx DFIR type //		0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes]
+	u32 rfLSSIReadBack; 	//LSSI RF readback data //		0x8a0~0x8af [16 bytes]
+}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T;
+
+typedef enum _RT_RF_TYPE_819xU{
+        RF_TYPE_MIN = 0,
+        RF_8225,
+        RF_8256,
+        RF_8258,
+        RF_PSEUDO_11N = 4,
+}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
+
+
+typedef struct _rate_adaptive
+{
+	u8				rate_adaptive_disabled;
+	u8				ratr_state;
+	u16				reserve;
+
+	u32				high_rssi_thresh_for_ra;
+	u32				high2low_rssi_thresh_for_ra;
+	u8				low2high_rssi_thresh_for_ra40M;
+	u32				low_rssi_thresh_for_ra40M;
+	u8				low2high_rssi_thresh_for_ra20M;
+	u32				low_rssi_thresh_for_ra20M;
+	u32				upper_rssi_threshold_ratr;
+	u32				middle_rssi_threshold_ratr;
+	u32				low_rssi_threshold_ratr;
+	u32				low_rssi_threshold_ratr_40M;
+	u32				low_rssi_threshold_ratr_20M;
+	u8				ping_rssi_enable;	//cosa add for test
+	u32				ping_rssi_ratr;	//cosa add for test
+	u32				ping_rssi_thresh_for_ra;//cosa add for test
+	u32				last_ratr;
+
+} rate_adaptive, *prate_adaptive;
+#define TxBBGainTableLength 37
+#define	CCKTxBBGainTableLength 23
+typedef struct _txbbgain_struct
+{
+	long	txbb_iq_amplifygain;
+	u32	txbbgain_value;
+} txbbgain_struct, *ptxbbgain_struct;
+
+typedef struct _ccktxbbgain_struct
+{
+	//The Value is from a22 to a29 one Byte one time is much Safer
+	u8	ccktxbb_valuearray[8];
+} ccktxbbgain_struct,*pccktxbbgain_struct;
+
+
+typedef struct _init_gain
+{
+	u8				xaagccore1;
+	u8				xbagccore1;
+	u8				xcagccore1;
+	u8				xdagccore1;
+	u8				cca;
+
+} init_gain, *pinit_gain;
+
+/* 2007/11/02 MH Define RF mode temporarily for test. */
+typedef enum tag_Rf_Operatetion_State
+{
+    RF_STEP_INIT = 0,
+    RF_STEP_NORMAL,
+    RF_STEP_MAX
+}RF_STEP_E;
+
+typedef enum _RT_STATUS{
+	RT_STATUS_SUCCESS,
+	RT_STATUS_FAILURE,
+	RT_STATUS_PENDING,
+	RT_STATUS_RESOURCE
+}RT_STATUS,*PRT_STATUS;
+
+typedef enum _RT_CUSTOMER_ID
+{
+	RT_CID_DEFAULT = 0,
+	RT_CID_8187_ALPHA0 = 1,
+	RT_CID_8187_SERCOMM_PS = 2,
+	RT_CID_8187_HW_LED = 3,
+	RT_CID_8187_NETGEAR = 4,
+	RT_CID_WHQL = 5,
+	RT_CID_819x_CAMEO  = 6,
+	RT_CID_819x_RUNTOP = 7,
+	RT_CID_819x_Senao = 8,
+	RT_CID_TOSHIBA = 9,	// Merge by Jacken, 2008/01/31.
+	RT_CID_819x_Netcore = 10,
+	RT_CID_Nettronix = 11,
+	RT_CID_DLINK = 12,
+	RT_CID_PRONET = 13,
+	RT_CID_COREGA = 14,
+}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID;
+
+//================================================================================
+// LED customization.
+//================================================================================
+
+typedef	enum _LED_STRATEGY_8190{
+	SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option.
+	SW_LED_MODE1, // SW control for PCI Express
+	SW_LED_MODE2, // SW control for Cameo.
+	SW_LED_MODE3, // SW contorl for RunTop.
+	SW_LED_MODE4, // SW control for Netcore
+	SW_LED_MODE5, //added by vivi, for led new mode, DLINK
+	SW_LED_MODE6, //added by vivi, for led new mode, PRONET
+	HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes)
+}LED_STRATEGY_8190, *PLED_STRATEGY_8190;
+
+#define CHANNEL_PLAN_LEN				10
+
+#define sCrcLng 		4
+
+typedef struct _TX_FWINFO_STRUCUTRE{
+	//DOWRD 0
+	u8			TxRate:7;
+	u8			CtsEnable:1;
+	u8			RtsRate:7;
+	u8			RtsEnable:1;
+	u8			TxHT:1;
+	u8			Short:1;
+	u8			TxBandwidth:1;
+	u8			TxSubCarrier:2;
+	u8			STBC:2;
+	u8			AllowAggregation:1;
+	u8			RtsHT:1;
+	u8			RtsShort:1;
+	u8			RtsBandwidth:1;
+	u8			RtsSubcarrier:2;
+	u8			RtsSTBC:2;
+	u8			EnableCPUDur:1;
+
+	//DWORD 1
+	u32			RxMF:2;
+	u32			RxAMD:3;
+	u32			Reserved1:3;
+	u32			TxAGCOffset:4;
+	u32			TxAGCSign:1;
+	u32			Tx_INFO_RSVD:6;
+	u32			PacketID:13;
+}TX_FWINFO_T;
+
+
+typedef struct _TX_FWINFO_8190PCI{
+	//DOWRD 0
+	u8			TxRate:7;
+	u8			CtsEnable:1;
+	u8			RtsRate:7;
+	u8			RtsEnable:1;
+	u8			TxHT:1;
+	u8			Short:1;						//Short PLCP for CCK, or short GI for 11n MCS
+	u8			TxBandwidth:1;				// This is used for HT MCS rate only.
+	u8			TxSubCarrier:2; 			// This is used for legacy OFDM rate only.
+	u8			STBC:2;
+	u8			AllowAggregation:1;
+	u8			RtsHT:1;						//Interpre RtsRate field as high throughput data rate
+	u8			RtsShort:1; 				//Short PLCP for CCK, or short GI for 11n MCS
+	u8			RtsBandwidth:1; 			// This is used for HT MCS rate only.
+	u8			RtsSubcarrier:2;				// This is used for legacy OFDM rate only.
+	u8			RtsSTBC:2;
+	u8			EnableCPUDur:1; 			//Enable firmware to recalculate and assign packet duration
+
+	//DWORD 1
+	u32			RxMF:2;
+	u32			RxAMD:3;
+	u32			TxPerPktInfoFeedback:1; 	// 1: indicate that the transimission info of this packet should be gathered by Firmware and retured by Rx Cmd.
+	u32			Reserved1:2;
+	u32			TxAGCOffset:4;		// Only 90 support
+	u32			TxAGCSign:1;		// Only 90 support
+	u32			RAW_TXD:1;			// MAC will send data in txpktbuffer without any processing,such as CRC check
+	u32			Retry_Limit:4;		// CCX Support relative retry limit FW page only support 4 bits now.
+	u32			Reserved2:1;
+	u32			PacketID:13;
+
+	// DW 2
+
+}TX_FWINFO_8190PCI, *PTX_FWINFO_8190PCI;
+
+typedef struct _phy_ofdm_rx_status_report_819xpci
+{
+	u8	trsw_gain_X[4];
+	u8	pwdb_all;
+	u8	cfosho_X[4];
+	u8	cfotail_X[4];
+	u8	rxevm_X[2];
+	u8	rxsnr_X[4];
+	u8	pdsnr_X[2];
+	u8	csi_current_X[2];
+	u8	csi_target_X[2];
+	u8	sigevm;
+	u8	max_ex_pwr;
+	u8	sgi_en;
+	u8	rxsc_sgien_exflg;
+}phy_sts_ofdm_819xpci_t;
+
+typedef struct _phy_cck_rx_status_report_819xpci
+{
+	/* For CCK rate descriptor. This is a unsigned 8:1 variable. LSB bit presend
+	   0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */
+	u8	adc_pwdb_X[4];
+	u8	sq_rpt;
+	u8	cck_agc_rpt;
+}phy_sts_cck_819xpci_t;
+
+typedef struct _phy_ofdm_rx_status_rxsc_sgien_exintfflag{
+	u8			reserved:4;
+	u8			rxsc:2;
+	u8			sgi_en:1;
+	u8			ex_intf_flag:1;
+}phy_ofdm_rx_status_rxsc_sgien_exintfflag;
+
+typedef enum _RT_OP_MODE{
+	RT_OP_MODE_AP,
+	RT_OP_MODE_INFRASTRUCTURE,
+	RT_OP_MODE_IBSS,
+	RT_OP_MODE_NO_LINK,
+}RT_OP_MODE, *PRT_OP_MODE;
+
+
+/* 2007/11/02 MH Define RF mode temporarily for test. */
+typedef enum tag_Rf_OpType
+{
+    RF_OP_By_SW_3wire = 0,
+    RF_OP_By_FW,
+    RF_OP_MAX
+}RF_OpType_E;
+
+typedef enum _RESET_TYPE {
+	RESET_TYPE_NORESET = 0x00,
+	RESET_TYPE_NORMAL = 0x01,
+	RESET_TYPE_SILENT = 0x02
+} RESET_TYPE;
+
+typedef struct _tx_ring{
+	u32 * desc;
+	u8 nStuckCount;
+	struct _tx_ring * next;
+}__attribute__ ((packed)) tx_ring, * ptx_ring;
+
+struct rtl8192_tx_ring {
+    tx_desc_819x_pci *desc;
+    dma_addr_t dma;
+    unsigned int idx;
+    unsigned int entries;
+    struct sk_buff_head queue;
+};
+
+#define NIC_SEND_HANG_THRESHOLD_NORMAL		4
+#define NIC_SEND_HANG_THRESHOLD_POWERSAVE 	8
+#define MAX_TX_QUEUE				9	// BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON.
+
+#define MAX_RX_COUNT                            64
+#define MAX_TX_QUEUE_COUNT                      9
+
+typedef struct r8192_priv
+{
+	struct pci_dev *pdev;
+	//added for maintain info from eeprom
+	short epromtype;
+	u16 eeprom_vid;
+	u16 eeprom_did;
+	u8  eeprom_CustomerID;
+	u16  eeprom_ChannelPlan;
+	RT_CUSTOMER_ID CustomerID;
+	LED_STRATEGY_8190	LedStrategy;
+	//bool bDcut;
+	u8	IC_Cut;
+	int irq;
+	short irq_enabled;
+	struct ieee80211_device *ieee80211;
+	bool being_init_adapter;
+	u8 Rf_Mode;
+	short card_8192; /* O: rtl8192, 1:rtl8185 V B/C, 2:rtl8185 V D */
+	u8 card_8192_version; /* if TCR reports card V B/C this discriminates */
+//	short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
+	short enable_gpio0;
+	enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
+	short hw_plcp_len;
+	short plcp_preamble_mode;
+	u8 ScanDelay;
+	spinlock_t irq_lock;
+	spinlock_t irq_th_lock;
+	spinlock_t tx_lock;
+	spinlock_t rf_ps_lock;
+        struct mutex mutex;
+	spinlock_t rf_lock; //used to lock rf write operation added by wb
+	spinlock_t ps_lock;
+
+	u32 irq_mask;
+//	short irq_enabled;
+//	struct net_device *dev; //comment this out.
+	short chan;
+	short sens;
+	short max_sens;
+	u32 rx_prevlen;
+/*RX stuff*/
+        rx_desc_819x_pci *rx_ring;
+        dma_addr_t rx_ring_dma;
+        unsigned int rx_idx;
+        struct sk_buff *rx_buf[MAX_RX_COUNT];
+	int rxringcount;
+	u16 rxbuffersize;
+
+
+	struct sk_buff *rx_skb;
+	u32 *rxring;
+	u32 *rxringtail;
+	dma_addr_t rxringdma;
+	struct buffer *rxbuffer;
+	struct buffer *rxbufferhead;
+	short rx_skb_complete;
+/*TX stuff*/
+        struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT];
+	int txringcount;
+//{
+	int txbuffsize;
+	int txfwbuffersize;
+	//struct tx_pendingbuf txnp_pending;
+	//struct tasklet_struct irq_tx_tasklet;
+	struct tasklet_struct irq_rx_tasklet;
+	struct tasklet_struct irq_tx_tasklet;
+        struct tasklet_struct irq_prepare_beacon_tasklet;
+	struct buffer *txmapbufs;
+	struct buffer *txbkpbufs;
+	struct buffer *txbepbufs;
+	struct buffer *txvipbufs;
+	struct buffer *txvopbufs;
+	struct buffer *txcmdbufs;
+	struct buffer *txmapbufstail;
+	struct buffer *txbkpbufstail;
+	struct buffer *txbepbufstail;
+	struct buffer *txvipbufstail;
+	struct buffer *txvopbufstail;
+	struct buffer *txcmdbufstail;
+	/* adhoc/master mode stuff */
+	ptx_ring txbeaconringtail;
+	dma_addr_t txbeaconringdma;
+	ptx_ring txbeaconring;
+	int txbeaconcount;
+	struct buffer *txbeaconbufs;
+	struct buffer *txbeaconbufstail;
+	ptx_ring txmapring;
+	ptx_ring txbkpring;
+	ptx_ring txbepring;
+	ptx_ring txvipring;
+	ptx_ring txvopring;
+	ptx_ring txcmdring;
+	ptx_ring txmapringtail;
+	ptx_ring txbkpringtail;
+	ptx_ring txbepringtail;
+	ptx_ring txvipringtail;
+	ptx_ring txvopringtail;
+	ptx_ring txcmdringtail;
+	ptx_ring txmapringhead;
+	ptx_ring txbkpringhead;
+	ptx_ring txbepringhead;
+	ptx_ring txvipringhead;
+	ptx_ring txvopringhead;
+	ptx_ring txcmdringhead;
+	dma_addr_t txmapringdma;
+	dma_addr_t txbkpringdma;
+	dma_addr_t txbepringdma;
+	dma_addr_t txvipringdma;
+	dma_addr_t txvopringdma;
+	dma_addr_t txcmdringdma;
+	//	u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
+//	u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
+//	u8 cck_txpwr_base;
+//	u8 ofdm_txpwr_base;
+//	u8 challow[15]; //channels from 1 to 14, 0 not used
+	short up;
+	short crcmon; //if 1 allow bad crc frame reception in monitor mode
+//	short prism_hdr;
+
+//	struct timer_list scan_timer;
+	/*short scanpending;
+	short stopscan;*/
+//	spinlock_t scan_lock;
+//	u8 active_probe;
+	//u8 active_scan_num;
+	struct semaphore wx_sem;
+	struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david
+//	short hw_wep;
+
+//	short digphy;
+//	short antb;
+//	short diversity;
+//	u8 cs_treshold;
+//	short rcr_csense;
+	u8 rf_type; //0 means 1T2R, 1 means 2T4R
+	RT_RF_TYPE_819xU rf_chip;
+
+//	u32 key0[4];
+	short (*rf_set_sens)(struct net_device *dev,short sens);
+	u8 (*rf_set_chan)(struct net_device *dev,u8 ch);
+	void (*rf_close)(struct net_device *dev);
+	void (*rf_init)(struct net_device *dev);
+	//short rate;
+	short promisc;
+	/*stats*/
+	struct Stats stats;
+	struct iw_statistics wstats;
+	struct proc_dir_entry *dir_dev;
+
+	/*RX stuff*/
+//	u32 *rxring;
+//	u32 *rxringtail;
+//	dma_addr_t rxringdma;
+
+#ifdef THOMAS_BEACON
+	u32 *oldaddr;
+#endif
+#ifdef THOMAS_TASKLET
+	atomic_t irt_counter;//count for irq_rx_tasklet
+#endif
+#ifdef JACKSON_NEW_RX
+        struct sk_buff **pp_rxskb;
+        int     rx_inx;
+#endif
+
+/* modified by davad for Rx process */
+       struct sk_buff_head rx_queue;
+       struct sk_buff_head skb_queue;
+       struct work_struct qos_activate;
+	short  tx_urb_index;
+	atomic_t tx_pending[0x10];//UART_PRIORITY+1
+
+	struct urb *rxurb_task;
+
+	//2 Tx Related variables
+	u16	ShortRetryLimit;
+	u16	LongRetryLimit;
+	u32	TransmitConfig;
+	u8	RegCWinMin;		// For turbo mode CW adaptive. Added by Annie, 2005-10-27.
+
+	u32     LastRxDescTSFHigh;
+	u32     LastRxDescTSFLow;
+
+
+	//2 Rx Related variables
+	u16	EarlyRxThreshold;
+	u32	ReceiveConfig;
+	u8	AcmControl;
+
+	u8	RFProgType;
+
+	u8 retry_data;
+	u8 retry_rts;
+	u16 rts;
+
+	struct 	ChnlAccessSetting  ChannelAccessSetting;
+
+	struct work_struct reset_wq;
+
+/**********************************************************/
+//for rtl819xPci
+	// Data Rate Config. Added by Annie, 2006-04-13.
+	u16	basic_rate;
+	u8	short_preamble;
+	u8 	slot_time;
+	u16 SifsTime;
+/* WirelessMode*/
+	u8 RegWirelessMode;
+/*Firmware*/
+	prt_firmware		pFirmware;
+	rtl819x_loopback_e	LoopbackMode;
+	firmware_source_e	firmware_source;
+	bool AutoloadFailFlag;
+	u16 EEPROMTxPowerDiff;
+	u16 EEPROMAntPwDiff;		// Antenna gain offset from B/C/D to A
+	u8 EEPROMThermalMeter;
+	u8 EEPROMPwDiff;
+	u8 EEPROMCrystalCap;
+	u8 EEPROM_Def_Ver;
+	u8 EEPROMTxPowerLevelCCK[14];// CCK channel 1~14
+	// The following definition is for eeprom 93c56
+	u8 EEPROMRfACCKChnl1TxPwLevel[3];	//RF-A CCK Tx Power Level at channel 7
+	u8 EEPROMRfAOfdmChnlTxPwLevel[3];//RF-A CCK Tx Power Level at [0],[1],[2] = channel 1,7,13
+	u8 EEPROMRfCCCKChnl1TxPwLevel[3];	//RF-C CCK Tx Power Level at channel 7
+	u8 EEPROMRfCOfdmChnlTxPwLevel[3];//RF-C CCK Tx Power Level at [0],[1],[2] = channel 1,7,13
+	u8 EEPROMTxPowerLevelCCK_V1[3];
+	u8 EEPROMTxPowerLevelOFDM24G[14]; // OFDM 2.4G channel 1~14
+	u8 EEPROMTxPowerLevelOFDM5G[24];	// OFDM 5G
+	u8 EEPROMLegacyHTTxPowerDiff;	// Legacy to HT rate power diff
+	bool bTXPowerDataReadFromEEPORM;
+/*channel plan*/
+	u16 RegChannelPlan; // Channel Plan specifed by user, 15: following setting of EEPROM, 0-14: default channel plan index specified by user.
+	u16 ChannelPlan;
+/*PS related*/
+	bool RegRfOff;
+	// Rf off action for power save
+	u8	bHwRfOffAction;	//0:No action, 1:By GPIO, 2:By Disable
+/*PHY related*/
+	BB_REGISTER_DEFINITION_T	PHYRegDef[4];	//Radio A/B/C/D
+	// Read/write are allow for following hardware information variables
+	u32	MCSTxPowerLevelOriginalOffset[6];
+	u32	CCKTxPowerLevelOriginalOffset;
+	u8	TxPowerLevelCCK[14];			// CCK channel 1~14
+	u8	TxPowerLevelCCK_A[14];			// RF-A, CCK channel 1~14
+	u8 	TxPowerLevelCCK_C[14];
+	u8	TxPowerLevelOFDM24G[14];		// OFDM 2.4G channel 1~14
+	u8	TxPowerLevelOFDM5G[14];			// OFDM 5G
+	u8	TxPowerLevelOFDM24G_A[14];	// RF-A, OFDM 2.4G channel 1~14
+	u8	TxPowerLevelOFDM24G_C[14];	// RF-C, OFDM 2.4G channel 1~14
+	u8	LegacyHTTxPowerDiff;			// Legacy to HT rate power diff
+	u8	TxPowerDiff;
+	char	RF_C_TxPwDiff;					// Antenna gain offset, rf-c to rf-a
+	u8	AntennaTxPwDiff[3];				// Antenna gain offset, index 0 for B, 1 for C, and 2 for D
+	u8	CrystalCap;						// CrystalCap.
+	u8	ThermalMeter[2];				// ThermalMeter, index 0 for RFIC0, and 1 for RFIC1
+	//05/27/2008 cck power enlarge
+	u8	CckPwEnl;
+	u16	TSSI_13dBm;
+	u32 	Pwr_Track;
+	u8				CCKPresentAttentuation_20Mdefault;
+	u8				CCKPresentAttentuation_40Mdefault;
+	char				CCKPresentAttentuation_difference;
+	char				CCKPresentAttentuation;
+	// Use to calculate PWBD.
+	u8	bCckHighPower;
+	long	undecorated_smoothed_pwdb;
+	long	undecorated_smoothed_cck_adc_pwdb[4];
+	//for set channel
+	u8	SwChnlInProgress;
+	u8 	SwChnlStage;
+	u8	SwChnlStep;
+	u8	SetBWModeInProgress;
+	HT_CHANNEL_WIDTH		CurrentChannelBW;
+
+	// 8190 40MHz mode
+	//
+	u8	nCur40MhzPrimeSC;	// Control channel sub-carrier
+	// Joseph test for shorten RF configuration time.
+	// We save RF reg0 in this variable to reduce RF reading.
+	//
+	u32					RfReg0Value[4];
+	u8 					NumTotalRFPath;
+	bool 				brfpath_rxenable[4];
+//+by amy 080507
+	struct timer_list watch_dog_timer;
+
+//+by amy 080515 for dynamic mechenism
+	//Add by amy Tx Power Control for Near/Far Range 2008/05/15
+	bool	bdynamic_txpower;  //bDynamicTxPower
+	bool	bDynamicTxHighPower;  // Tx high power state
+	bool	bDynamicTxLowPower;  // Tx low power state
+	bool	bLastDTPFlag_High;
+	bool	bLastDTPFlag_Low;
+
+	bool	bstore_last_dtpflag;
+	bool	bstart_txctrl_bydtp;   //Define to discriminate on High power State or on sitesuvey to change Tx gain index
+	//Add by amy for Rate Adaptive
+	rate_adaptive rate_adaptive;
+	//Add by amy for TX power tracking
+	//2008/05/15  Mars OPEN/CLOSE TX POWER TRACKING
+       txbbgain_struct txbbgain_table[TxBBGainTableLength];
+	u8			   txpower_count;//For 6 sec do tracking again
+	bool			   btxpower_trackingInit;
+	u8			   OFDM_index;
+	u8			   CCK_index;
+	u8			   Record_CCK_20Mindex;
+	u8			   Record_CCK_40Mindex;
+	//2007/09/10 Mars Add CCK TX Power Tracking
+	ccktxbbgain_struct	cck_txbbgain_table[CCKTxBBGainTableLength];
+	ccktxbbgain_struct	cck_txbbgain_ch14_table[CCKTxBBGainTableLength];
+	u8 rfa_txpowertrackingindex;
+	u8 rfa_txpowertrackingindex_real;
+	u8 rfa_txpowertracking_default;
+	u8 rfc_txpowertrackingindex;
+	u8 rfc_txpowertrackingindex_real;
+	u8 rfc_txpowertracking_default;
+	bool btxpower_tracking;
+	bool bcck_in_ch14;
+
+	//For Backup Initial Gain
+	init_gain initgain_backup;
+	u8 		DefaultInitialGain[4];
+	// For EDCA Turbo mode, Added by amy 080515.
+	bool		bis_any_nonbepkts;
+	bool		bcurrent_turbo_EDCA;
+
+	bool		bis_cur_rdlstate;
+	struct timer_list fsync_timer;
+	bool bfsync_processing;	// 500ms Fsync timer is active or not
+	u32 	rate_record;
+	u32 	rateCountDiffRecord;
+	u32	ContiuneDiffCount;
+	bool bswitch_fsync;
+
+	u8	framesync;
+	u32 	framesyncC34;
+	u8   	framesyncMonitor;
+        	//Added by amy 080516  for RX related
+	u16 	nrxAMPDU_size;
+	u8 	nrxAMPDU_aggr_num;
+
+	/*Last RxDesc TSF value*/
+	u32 last_rxdesc_tsf_high;
+	u32 last_rxdesc_tsf_low;
+
+	//by amy for gpio
+	bool bHwRadioOff;
+	//by amy for ps
+	bool RFChangeInProgress; // RF Chnage in progress, by Bruce, 2007-10-30
+	bool SetRFPowerStateInProgress;
+	RT_OP_MODE OpMode;
+	//by amy for reset_count
+	u32 reset_count;
+	bool bpbc_pressed;
+	//by amy for debug
+	u32 txpower_checkcnt;
+	u32 txpower_tracking_callback_cnt;
+	u8 thermal_read_val[40];
+	u8 thermal_readback_index;
+	u32 ccktxpower_adjustcnt_not_ch14;
+	u32 ccktxpower_adjustcnt_ch14;
+	u8 tx_fwinfo_force_subcarriermode;
+	u8 tx_fwinfo_force_subcarrierval;
+
+	//by amy for silent reset
+	RESET_TYPE	ResetProgress;
+	bool		bForcedSilentReset;
+	bool		bDisableNormalResetCheck;
+	u16		TxCounter;
+	u16		RxCounter;
+	int		IrpPendingCount;
+	bool		bResetInProgress;
+	bool		force_reset;
+	u8		InitialGainOperateType;
+
+	//define work item by amy 080526
+	struct delayed_work update_beacon_wq;
+	struct delayed_work watch_dog_wq;
+	struct delayed_work txpower_tracking_wq;
+	struct delayed_work rfpath_check_wq;
+	struct delayed_work gpio_change_rf_wq;
+	struct delayed_work initialgain_operate_wq;
+	struct workqueue_struct *priv_wq;
+}r8192_priv;
+
+// for rtl8187
+// now mirging to rtl8187B
+/*
+typedef enum{
+	LOW_PRIORITY = 0x02,
+	NORM_PRIORITY
+	} priority_t;
+*/
+//for rtl8187B
+#if 0
+typedef enum{
+	BULK_PRIORITY = 0x01,
+	//RSVD0,
+	//RSVD1,
+	LOW_PRIORITY,
+	NORM_PRIORITY,
+	VO_PRIORITY,
+	VI_PRIORITY, //0x05
+	BE_PRIORITY,
+	BK_PRIORITY,
+	CMD_PRIORITY,//0x8
+	RSVD3,
+	BEACON_PRIORITY, //0x0A
+	HIGH_PRIORITY,
+	MANAGE_PRIORITY,
+	RSVD4,
+	RSVD5,
+	UART_PRIORITY //0x0F
+} priority_t;
+#endif
+typedef enum{
+	NIC_8192E = 1,
+	} nic_t;
+
+
+#if 0 //defined in Qos.h
+//typedef u32 AC_CODING;
+#define AC0_BE	0		// ACI: 0x00	// Best Effort
+#define AC1_BK	1		// ACI: 0x01	// Background
+#define AC2_VI	2		// ACI: 0x10	// Video
+#define AC3_VO	3		// ACI: 0x11	// Voice
+#define AC_MAX	4		// Max: define total number; Should not to be used as a real enum.
+
+//
+// ECWmin/ECWmax field.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
+//
+typedef	union _ECW{
+	u8	charData;
+	struct
+	{
+		u8	ECWmin:4;
+		u8	ECWmax:4;
+	}f;	// Field
+}ECW, *PECW;
+
+//
+// ACI/AIFSN Field.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
+//
+typedef	union _ACI_AIFSN{
+	u8	charData;
+
+	struct
+	{
+		u8	AIFSN:4;
+		u8	ACM:1;
+		u8	ACI:2;
+		u8	Reserved:1;
+	}f;	// Field
+}ACI_AIFSN, *PACI_AIFSN;
+
+//
+// AC Parameters Record Format.
+// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
+//
+typedef	union _AC_PARAM{
+	u32	longData;
+	u8	charData[4];
+
+	struct
+	{
+		ACI_AIFSN	AciAifsn;
+		ECW		Ecw;
+		u16		TXOPLimit;
+	}f;	// Field
+}AC_PARAM, *PAC_PARAM;
+
+#endif
+bool init_firmware(struct net_device *dev);
+void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb);
+short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
+u32 read_cam(struct net_device *dev, u8 addr);
+void write_cam(struct net_device *dev, u8 addr, u32 data);
+u8 read_nic_byte(struct net_device *dev, int x);
+u8 read_nic_byte_E(struct net_device *dev, int x);
+u32 read_nic_dword(struct net_device *dev, int x);
+u16 read_nic_word(struct net_device *dev, int x) ;
+void write_nic_byte(struct net_device *dev, int x,u8 y);
+void write_nic_byte_E(struct net_device *dev, int x,u8 y);
+void write_nic_word(struct net_device *dev, int x,u16 y);
+void write_nic_dword(struct net_device *dev, int x,u32 y);
+void force_pci_posting(struct net_device *dev);
+
+void rtl8192_rtx_disable(struct net_device *);
+void rtl8192_rx_enable(struct net_device *);
+void rtl8192_tx_enable(struct net_device *);
+
+void rtl8192_disassociate(struct net_device *dev);
+//void fix_rx_fifo(struct net_device *dev);
+void rtl8185_set_rf_pins_enable(struct net_device *dev,u32 a);
+
+void rtl8192_set_anaparam(struct net_device *dev,u32 a);
+void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
+void rtl8192_update_msr(struct net_device *dev);
+int rtl8192_down(struct net_device *dev);
+int rtl8192_up(struct net_device *dev);
+void rtl8192_commit(struct net_device *dev);
+void rtl8192_set_chan(struct net_device *dev,short ch);
+void write_phy(struct net_device *dev, u8 adr, u8 data);
+void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
+void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
+void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
+void rtl8187_set_rxconf(struct net_device *dev);
+//short check_nic_enough_desc(struct net_device *dev, priority_t priority);
+void rtl8192_start_beacon(struct net_device *dev);
+void CamResetAllEntry(struct net_device* dev);
+void EnableHWSecurityConfig8192(struct net_device *dev);
+void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, u8 *MacAddr, u8 DefaultKey, u32 *KeyContent );
+void CamPrintDbgReg(struct net_device* dev);
+extern	void	dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
+extern void firmware_init_param(struct net_device *dev);
+extern RT_STATUS cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len);
+void rtl8192_hw_wakeup_wq (struct work_struct *work);
+
+short rtl8192_is_tx_queue_empty(struct net_device *dev);
+#ifdef ENABLE_IPS
+void IPSEnter(struct net_device *dev);
+void IPSLeave(struct net_device *dev);
+#endif
+#endif
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
new file mode 100644
index 0000000..d4fa654
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -0,0 +1,6462 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ * Linux device driver for RTL8190P / RTL8192E
+ *
+ * Based on the r8180 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ * Jerry chuang <wlanfae@realtek.com>
+ */
+
+
+#undef LOOP_TEST
+#undef RX_DONT_PASS_UL
+#undef DEBUG_EPROM
+#undef DEBUG_RX_VERBOSE
+#undef DUMMY_RX
+#undef DEBUG_ZERO_RX
+#undef DEBUG_RX_SKB
+#undef DEBUG_TX_FRAG
+#undef DEBUG_RX_FRAG
+#undef DEBUG_TX_FILLDESC
+#undef DEBUG_TX
+#undef DEBUG_IRQ
+#undef DEBUG_RX
+#undef DEBUG_RXALLOC
+#undef DEBUG_REGISTERS
+#undef DEBUG_RING
+#undef DEBUG_IRQ_TASKLET
+#undef DEBUG_TX_ALLOC
+#undef DEBUG_TX_DESC
+
+//#define CONFIG_RTL8192_IO_MAP
+#include <asm/uaccess.h>
+#include "r8192E_hw.h"
+#include "r8192E.h"
+#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
+#include "r8180_93cx6.h"   /* Card EEPROM */
+#include "r8192E_wx.h"
+#include "r819xE_phy.h" //added by WB 4.30.2008
+#include "r819xE_phyreg.h"
+#include "r819xE_cmdpkt.h"
+#include "r8192E_dm.h"
+//#include "r8192xU_phyreg.h"
+//#include <linux/usb.h>
+// FIXME: check if 2.6.7 is ok
+
+#ifdef CONFIG_PM_RTL
+#include "r8192_pm.h"
+#endif
+
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+
+//set here to open your trace code. //WB
+u32 rt_global_debug_component = \
+		//		COMP_INIT    	|
+			//	COMP_EPROM   	|
+		//		COMP_PHY	|
+		//		COMP_RF		|
+				COMP_FIRMWARE	|
+			//	COMP_TRACE	|
+		//		COMP_DOWN	|
+		//		COMP_SWBW	|
+		//		COMP_SEC	|
+//				COMP_QOS	|
+//				COMP_RATE	|
+		//		COMP_RECV	|
+		//		COMP_SEND	|
+		//		COMP_POWER	|
+			//	COMP_EVENTS	|
+			//	COMP_RESET	|
+			//	COMP_CMDPKT	|
+			//	COMP_POWER_TRACKING	|
+                        // 	COMP_INTR       |
+				COMP_ERR ; //always open err flags on
+#ifndef PCI_DEVICE
+#define PCI_DEVICE(vend,dev)\
+	.vendor=(vend),.device=(dev),\
+	.subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID
+#endif
+static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
+#ifdef RTL8190P
+	/* Realtek */
+	/* Dlink */
+	{ PCI_DEVICE(0x10ec, 0x8190) },
+	/* Corega */
+	{ PCI_DEVICE(0x07aa, 0x0045) },
+	{ PCI_DEVICE(0x07aa, 0x0046) },
+#else
+	/* Realtek */
+	{ PCI_DEVICE(0x10ec, 0x8192) },
+
+	/* Corega */
+	{ PCI_DEVICE(0x07aa, 0x0044) },
+	{ PCI_DEVICE(0x07aa, 0x0047) },
+#endif
+	{}
+};
+
+static char* ifname = "wlan%d";
+static int hwwep = 1; //default use hw. set 0 to use software security
+static int channels = 0x3fff;
+
+MODULE_LICENSE("GPL");
+MODULE_VERSION("V 1.1");
+MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
+//MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
+MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
+
+
+module_param(ifname, charp, S_IRUGO|S_IWUSR );
+//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
+module_param(hwwep,int, S_IRUGO|S_IWUSR);
+module_param(channels,int, S_IRUGO|S_IWUSR);
+
+MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
+//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
+MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
+MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
+
+static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
+			 const struct pci_device_id *id);
+static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
+
+static struct pci_driver rtl8192_pci_driver = {
+	.name		= RTL819xE_MODULE_NAME,	          /* Driver name   */
+	.id_table	= rtl8192_pci_id_tbl,	          /* PCI_ID table  */
+	.probe		= rtl8192_pci_probe,	          /* probe fn      */
+	.remove		= __devexit_p(rtl8192_pci_disconnect),	  /* remove fn     */
+#ifdef CONFIG_PM_RTL
+	.suspend	= rtl8192E_suspend,	          /* PM suspend fn */
+	.resume		= rtl8192E_resume,                 /* PM resume fn  */
+#else
+	.suspend	= NULL,			          /* PM suspend fn */
+	.resume      	= NULL,			          /* PM resume fn  */
+#endif
+};
+
+#ifdef ENABLE_DOT11D
+
+typedef struct _CHANNEL_LIST
+{
+	u8	Channel[32];
+	u8	Len;
+}CHANNEL_LIST, *PCHANNEL_LIST;
+
+static CHANNEL_LIST ChannelPlan[] = {
+	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24},  		//FCC
+	{{1,2,3,4,5,6,7,8,9,10,11},11},                    				//IC
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},  	//ETSI
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},    //Spain. Change to ETSI.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},  	//France. Change to ETSI.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},	//MKK					//MKK
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},	//Israel.
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},			// For 11a , TELEC
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22},    //MIC
+	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}					//For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
+};
+
+static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
+{
+	int i, max_chan=-1, min_chan=-1;
+	struct ieee80211_device* ieee = priv->ieee80211;
+	switch (channel_plan)
+	{
+		case COUNTRY_CODE_FCC:
+		case COUNTRY_CODE_IC:
+		case COUNTRY_CODE_ETSI:
+		case COUNTRY_CODE_SPAIN:
+		case COUNTRY_CODE_FRANCE:
+		case COUNTRY_CODE_MKK:
+		case COUNTRY_CODE_MKK1:
+		case COUNTRY_CODE_ISRAEL:
+		case COUNTRY_CODE_TELEC:
+		case COUNTRY_CODE_MIC:
+		{
+			Dot11d_Init(ieee);
+			ieee->bGlobalDomain = false;
+                        //acturally 8225 & 8256 rf chip only support B,G,24N mode
+                        if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
+			{
+				min_chan = 1;
+				max_chan = 14;
+			}
+			else
+			{
+				RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
+			}
+			if (ChannelPlan[channel_plan].Len != 0){
+				// Clear old channel map
+				memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
+				// Set new channel map
+				for (i=0;i<ChannelPlan[channel_plan].Len;i++)
+				{
+	                                if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
+					    break;
+					GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
+				}
+			}
+			break;
+		}
+		case COUNTRY_CODE_GLOBAL_DOMAIN:
+		{
+			GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
+			Dot11d_Reset(ieee);
+			ieee->bGlobalDomain = true;
+			break;
+		}
+		default:
+			break;
+	}
+}
+#endif
+
+
+#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 )
+/* 2007/07/25 MH Defien temp tx fw info. */
+static TX_FWINFO_T Tmp_TxFwInfo;
+
+
+#define 	rx_hal_is_cck_rate(_pdrvinfo)\
+			(_pdrvinfo->RxRate == DESC90_RATE1M ||\
+			_pdrvinfo->RxRate == DESC90_RATE2M ||\
+			_pdrvinfo->RxRate == DESC90_RATE5_5M ||\
+			_pdrvinfo->RxRate == DESC90_RATE11M) &&\
+			!_pdrvinfo->RxHT\
+
+
+void CamResetAllEntry(struct net_device *dev)
+{
+	//u8 ucIndex;
+	u32 ulcommand = 0;
+
+#if 1
+	ulcommand |= BIT31|BIT30;
+	write_nic_dword(dev, RWCAM, ulcommand);
+#else
+        for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
+                CAM_mark_invalid(dev, ucIndex);
+        for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
+                CAM_empty_entry(dev, ucIndex);
+#endif
+}
+
+
+void write_cam(struct net_device *dev, u8 addr, u32 data)
+{
+        write_nic_dword(dev, WCAMI, data);
+        write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
+}
+u32 read_cam(struct net_device *dev, u8 addr)
+{
+        write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
+        return read_nic_dword(dev, 0xa8);
+}
+
+////////////////////////////////////////////////////////////
+#ifdef CONFIG_RTL8180_IO_MAP
+
+u8 read_nic_byte(struct net_device *dev, int x)
+{
+        return 0xff&inb(dev->base_addr +x);
+}
+
+u32 read_nic_dword(struct net_device *dev, int x)
+{
+        return inl(dev->base_addr +x);
+}
+
+u16 read_nic_word(struct net_device *dev, int x)
+{
+        return inw(dev->base_addr +x);
+}
+
+void write_nic_byte(struct net_device *dev, int x,u8 y)
+{
+        outb(y&0xff,dev->base_addr +x);
+}
+
+void write_nic_word(struct net_device *dev, int x,u16 y)
+{
+        outw(y,dev->base_addr +x);
+}
+
+void write_nic_dword(struct net_device *dev, int x,u32 y)
+{
+        outl(y,dev->base_addr +x);
+}
+
+#else /* RTL_IO_MAP */
+
+u8 read_nic_byte(struct net_device *dev, int x)
+{
+        return 0xff&readb((u8*)dev->mem_start +x);
+}
+
+u32 read_nic_dword(struct net_device *dev, int x)
+{
+        return readl((u8*)dev->mem_start +x);
+}
+
+u16 read_nic_word(struct net_device *dev, int x)
+{
+        return readw((u8*)dev->mem_start +x);
+}
+
+void write_nic_byte(struct net_device *dev, int x,u8 y)
+{
+        writeb(y,(u8*)dev->mem_start +x);
+	udelay(20);
+}
+
+void write_nic_dword(struct net_device *dev, int x,u32 y)
+{
+        writel(y,(u8*)dev->mem_start +x);
+	udelay(20);
+}
+
+void write_nic_word(struct net_device *dev, int x,u16 y)
+{
+        writew(y,(u8*)dev->mem_start +x);
+	udelay(20);
+}
+
+#endif /* RTL_IO_MAP */
+
+
+///////////////////////////////////////////////////////////
+
+//u8 read_phy_cck(struct net_device *dev, u8 adr);
+//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
+/* this might still called in what was the PHY rtl8185/rtl8192 common code
+ * plans are to possibilty turn it again in one common code...
+ */
+inline void force_pci_posting(struct net_device *dev)
+{
+}
+
+
+//warning message WB
+irqreturn_t rtl8192_interrupt(int irq, void *netdev);
+//static struct net_device_stats *rtl8192_stats(struct net_device *dev);
+void rtl8192_commit(struct net_device *dev);
+//void rtl8192_restart(struct net_device *dev);
+void rtl8192_restart(struct work_struct *work);
+//void rtl8192_rq_tx_ack(struct work_struct *work);
+
+void watch_dog_timer_callback(unsigned long data);
+#ifdef ENABLE_IPS
+void IPSEnter(struct net_device *dev);
+void IPSLeave(struct net_device *dev);
+void InactivePsWorkItemCallback(struct net_device *dev);
+#endif
+/****************************************************************************
+   -----------------------------PROCFS STUFF-------------------------
+*****************************************************************************/
+
+static struct proc_dir_entry *rtl8192_proc = NULL;
+
+
+
+static int proc_get_stats_ap(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+	struct ieee80211_network *target;
+
+	int len = 0;
+
+        list_for_each_entry(target, &ieee->network_list, list) {
+
+		len += snprintf(page + len, count - len,
+                "%s ", target->ssid);
+
+		if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
+	                len += snprintf(page + len, count - len,
+        	        "WPA\n");
+		}
+		else{
+                        len += snprintf(page + len, count - len,
+                        "non_WPA\n");
+                }
+
+        }
+
+	*eof = 1;
+	return len;
+}
+
+static int proc_get_registers(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	int len = 0;
+	int i,n;
+
+	int max=0xff;
+
+	/* This dump the current register page */
+	len += snprintf(page + len, count - len,
+                        "\n####################page 0##################\n ");
+
+	for(n=0;n<=max;)
+	{
+		//printk( "\nD: %2x> ", n);
+		len += snprintf(page + len, count - len,
+			"\nD:  %2x > ",n);
+
+		for(i=0;i<16 && n<=max;i++,n++)
+		len += snprintf(page + len, count - len,
+			"%2x ",read_nic_byte(dev,n));
+
+		//	printk("%2x ",read_nic_byte(dev,n));
+	}
+	len += snprintf(page + len, count - len,"\n");
+	len += snprintf(page + len, count - len,
+                        "\n####################page 1##################\n ");
+        for(n=0;n<=max;)
+        {
+                //printk( "\nD: %2x> ", n);
+                len += snprintf(page + len, count - len,
+                        "\nD:  %2x > ",n);
+
+                for(i=0;i<16 && n<=max;i++,n++)
+                len += snprintf(page + len, count - len,
+                        "%2x ",read_nic_byte(dev,0x100|n));
+
+                //      printk("%2x ",read_nic_byte(dev,n));
+        }
+
+	len += snprintf(page + len, count - len,
+                        "\n####################page 3##################\n ");
+        for(n=0;n<=max;)
+        {
+                //printk( "\nD: %2x> ", n);
+                len += snprintf(page + len, count - len,
+                        "\nD:  %2x > ",n);
+
+                for(i=0;i<16 && n<=max;i++,n++)
+                len += snprintf(page + len, count - len,
+                        "%2x ",read_nic_byte(dev,0x300|n));
+
+                //      printk("%2x ",read_nic_byte(dev,n));
+        }
+
+
+	*eof = 1;
+	return len;
+
+}
+
+
+
+static int proc_get_stats_tx(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	int len = 0;
+
+	len += snprintf(page + len, count - len,
+		"TX VI priority ok int: %lu\n"
+//		"TX VI priority error int: %lu\n"
+		"TX VO priority ok int: %lu\n"
+//		"TX VO priority error int: %lu\n"
+		"TX BE priority ok int: %lu\n"
+//		"TX BE priority error int: %lu\n"
+		"TX BK priority ok int: %lu\n"
+//		"TX BK priority error int: %lu\n"
+		"TX MANAGE priority ok int: %lu\n"
+//		"TX MANAGE priority error int: %lu\n"
+		"TX BEACON priority ok int: %lu\n"
+		"TX BEACON priority error int: %lu\n"
+		"TX CMDPKT priority ok int: %lu\n"
+//		"TX high priority ok int: %lu\n"
+//		"TX high priority failed error int: %lu\n"
+//		"TX queue resume: %lu\n"
+		"TX queue stopped?: %d\n"
+		"TX fifo overflow: %lu\n"
+//		"TX beacon: %lu\n"
+//		"TX VI queue: %d\n"
+//		"TX VO queue: %d\n"
+//		"TX BE queue: %d\n"
+//		"TX BK queue: %d\n"
+//		"TX HW queue: %d\n"
+//		"TX VI dropped: %lu\n"
+//		"TX VO dropped: %lu\n"
+//		"TX BE dropped: %lu\n"
+//		"TX BK dropped: %lu\n"
+		"TX total data packets %lu\n"
+		"TX total data bytes :%lu\n",
+//		"TX beacon aborted: %lu\n",
+		priv->stats.txviokint,
+//		priv->stats.txvierr,
+		priv->stats.txvookint,
+//		priv->stats.txvoerr,
+		priv->stats.txbeokint,
+//		priv->stats.txbeerr,
+		priv->stats.txbkokint,
+//		priv->stats.txbkerr,
+		priv->stats.txmanageokint,
+//		priv->stats.txmanageerr,
+		priv->stats.txbeaconokint,
+		priv->stats.txbeaconerr,
+		priv->stats.txcmdpktokint,
+//		priv->stats.txhpokint,
+//		priv->stats.txhperr,
+//		priv->stats.txresumed,
+		netif_queue_stopped(dev),
+		priv->stats.txoverflow,
+//		priv->stats.txbeacon,
+//		atomic_read(&(priv->tx_pending[VI_QUEUE])),
+//		atomic_read(&(priv->tx_pending[VO_QUEUE])),
+//		atomic_read(&(priv->tx_pending[BE_QUEUE])),
+//		atomic_read(&(priv->tx_pending[BK_QUEUE])),
+//		read_nic_byte(dev, TXFIFOCOUNT),
+//		priv->stats.txvidrop,
+//		priv->stats.txvodrop,
+		priv->ieee80211->stats.tx_packets,
+		priv->ieee80211->stats.tx_bytes
+
+
+//		priv->stats.txbedrop,
+//		priv->stats.txbkdrop
+			//	priv->stats.txdatapkt
+//		priv->stats.txbeaconerr
+		);
+
+	*eof = 1;
+	return len;
+}
+
+
+
+static int proc_get_stats_rx(char *page, char **start,
+			  off_t offset, int count,
+			  int *eof, void *data)
+{
+	struct net_device *dev = data;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	int len = 0;
+
+	len += snprintf(page + len, count - len,
+		"RX packets: %lu\n"
+		"RX desc err: %lu\n"
+		"RX rx overflow error: %lu\n"
+		"RX invalid urb error: %lu\n",
+		priv->stats.rxint,
+		priv->stats.rxrdu,
+		priv->stats.rxoverflow,
+		priv->stats.rxurberr);
+
+	*eof = 1;
+	return len;
+}
+
+static void rtl8192_proc_module_init(void)
+{
+	RT_TRACE(COMP_INIT, "Initializing proc filesystem");
+	rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
+}
+
+
+static void rtl8192_proc_module_remove(void)
+{
+	remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
+}
+
+
+static void rtl8192_proc_remove_one(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	printk("dev name=======> %s\n",dev->name);
+
+	if (priv->dir_dev) {
+	//	remove_proc_entry("stats-hw", priv->dir_dev);
+		remove_proc_entry("stats-tx", priv->dir_dev);
+		remove_proc_entry("stats-rx", priv->dir_dev);
+	//	remove_proc_entry("stats-ieee", priv->dir_dev);
+		remove_proc_entry("stats-ap", priv->dir_dev);
+		remove_proc_entry("registers", priv->dir_dev);
+	//	remove_proc_entry("cck-registers",priv->dir_dev);
+	//	remove_proc_entry("ofdm-registers",priv->dir_dev);
+		//remove_proc_entry(dev->name, rtl8192_proc);
+		remove_proc_entry("wlan0", rtl8192_proc);
+		priv->dir_dev = NULL;
+	}
+}
+
+
+static void rtl8192_proc_init_one(struct net_device *dev)
+{
+	struct proc_dir_entry *e;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dir_dev = create_proc_entry(dev->name,
+					  S_IFDIR | S_IRUGO | S_IXUGO,
+					  rtl8192_proc);
+	if (!priv->dir_dev) {
+		RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
+		      dev->name);
+		return;
+	}
+	e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_stats_rx, dev);
+
+	if (!e) {
+		RT_TRACE(COMP_ERR,"Unable to initialize "
+		      "/proc/net/rtl8192/%s/stats-rx\n",
+		      dev->name);
+	}
+
+
+	e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_stats_tx, dev);
+
+	if (!e) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/stats-tx\n",
+		      dev->name);
+	}
+
+	e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_stats_ap, dev);
+
+	if (!e) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/stats-ap\n",
+		      dev->name);
+	}
+
+	e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
+				   priv->dir_dev, proc_get_registers, dev);
+	if (!e) {
+		RT_TRACE(COMP_ERR, "Unable to initialize "
+		      "/proc/net/rtl8192/%s/registers\n",
+		      dev->name);
+	}
+}
+/****************************************************************************
+   -----------------------------MISC STUFF-------------------------
+*****************************************************************************/
+
+short check_nic_enough_desc(struct net_device *dev, int prio)
+{
+    struct r8192_priv *priv = ieee80211_priv(dev);
+    struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
+
+    /* for now we reserve two free descriptor as a safety boundary
+     * between the tail and the head
+     */
+    if (ring->entries - skb_queue_len(&ring->queue) >= 2) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static void tx_timeout(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//rtl8192_commit(dev);
+
+	schedule_work(&priv->reset_wq);
+	printk("TXTIMEOUT");
+}
+
+
+/****************************************************************************
+      ------------------------------HW STUFF---------------------------
+*****************************************************************************/
+
+
+static void rtl8192_irq_enable(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->irq_enabled = 1;
+	write_nic_dword(dev,INTA_MASK, priv->irq_mask);
+}
+
+
+static void rtl8192_irq_disable(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	write_nic_dword(dev,INTA_MASK,0);
+	force_pci_posting(dev);
+	priv->irq_enabled = 0;
+}
+
+
+static void rtl8192_set_mode(struct net_device *dev,int mode)
+{
+	u8 ecmd;
+	ecmd=read_nic_byte(dev, EPROM_CMD);
+	ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
+	ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
+	ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
+	ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
+	write_nic_byte(dev, EPROM_CMD, ecmd);
+}
+
+
+void rtl8192_update_msr(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 msr;
+
+	msr  = read_nic_byte(dev, MSR);
+	msr &= ~ MSR_LINK_MASK;
+
+	/* do not change in link_state != WLAN_LINK_ASSOCIATED.
+	 * msr must be updated if the state is ASSOCIATING.
+	 * this is intentional and make sense for ad-hoc and
+	 * master (see the create BSS/IBSS func)
+	 */
+	if (priv->ieee80211->state == IEEE80211_LINKED){
+
+		if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
+			msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
+		else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+			msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
+		else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
+			msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
+
+	}else
+		msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
+
+	write_nic_byte(dev, MSR, msr);
+}
+
+void rtl8192_set_chan(struct net_device *dev,short ch)
+{
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+    RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
+    priv->chan=ch;
+#if 0
+    if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
+            priv->ieee80211->iw_mode == IW_MODE_MASTER){
+
+        priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
+        priv->ieee80211->master_chan = ch;
+        rtl8192_update_beacon_ch(dev);
+    }
+#endif
+
+    /* this hack should avoid frame TX during channel setting*/
+
+
+    //	tx = read_nic_dword(dev,TX_CONF);
+    //	tx &= ~TX_LOOPBACK_MASK;
+
+#ifndef LOOP_TEST
+    //TODO
+    //	write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
+
+    //need to implement rf set channel here WB
+
+    if (priv->rf_set_chan)
+        priv->rf_set_chan(dev,priv->chan);
+    //	mdelay(10);
+    //	write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
+#endif
+}
+
+void rtl8192_rx_enable(struct net_device *dev)
+{
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+    write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
+}
+
+/* the TX_DESC_BASE setting is according to the following queue index
+ *  BK_QUEUE       ===>                        0
+ *  BE_QUEUE       ===>                        1
+ *  VI_QUEUE       ===>                        2
+ *  VO_QUEUE       ===>                        3
+ *  HCCA_QUEUE     ===>                        4
+ *  TXCMD_QUEUE    ===>                        5
+ *  MGNT_QUEUE     ===>                        6
+ *  HIGH_QUEUE     ===>                        7
+ *  BEACON_QUEUE   ===>                        8
+ *  */
+static u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
+void rtl8192_tx_enable(struct net_device *dev)
+{
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+    u32 i;
+    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
+        write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
+
+    ieee80211_reset_queue(priv->ieee80211);
+}
+
+
+static void rtl8192_free_rx_ring(struct net_device *dev)
+{
+    struct r8192_priv *priv = ieee80211_priv(dev);
+    int i;
+
+    for (i = 0; i < priv->rxringcount; i++) {
+        struct sk_buff *skb = priv->rx_buf[i];
+        if (!skb)
+            continue;
+
+        pci_unmap_single(priv->pdev,
+                *((dma_addr_t *)skb->cb),
+                priv->rxbuffersize, PCI_DMA_FROMDEVICE);
+        kfree_skb(skb);
+    }
+
+    pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
+            priv->rx_ring, priv->rx_ring_dma);
+    priv->rx_ring = NULL;
+}
+
+static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
+{
+    struct r8192_priv *priv = ieee80211_priv(dev);
+    struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
+
+    while (skb_queue_len(&ring->queue)) {
+        tx_desc_819x_pci *entry = &ring->desc[ring->idx];
+        struct sk_buff *skb = __skb_dequeue(&ring->queue);
+
+        pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
+                skb->len, PCI_DMA_TODEVICE);
+        kfree_skb(skb);
+        ring->idx = (ring->idx + 1) % ring->entries;
+    }
+
+    pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
+            ring->desc, ring->dma);
+    ring->desc = NULL;
+}
+
+
+static void rtl8192_beacon_disable(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	u32 reg;
+
+	reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
+
+	/* disable Beacon realted interrupt signal */
+	reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
+	write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
+}
+
+void rtl8192_rtx_disable(struct net_device *dev)
+{
+	u8 cmd;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+        int i;
+
+	cmd=read_nic_byte(dev,CMDR);
+//	if(!priv->ieee80211->bSupportRemoteWakeUp) {
+		write_nic_byte(dev, CMDR, cmd &~ \
+				(CR_TE|CR_RE));
+//	}
+	force_pci_posting(dev);
+	mdelay(30);
+
+        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+                skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
+        }
+        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+                skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
+        }
+
+
+	skb_queue_purge(&priv->skb_queue);
+	return;
+}
+
+static void rtl8192_reset(struct net_device *dev)
+{
+    rtl8192_irq_disable(dev);
+    printk("This is RTL819xP Reset procedure\n");
+}
+
+static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
+inline u16 rtl8192_rate2rate(short rate)
+{
+	if (rate >11) return 0;
+	return rtl_rate[rate];
+}
+
+
+
+
+static void rtl8192_data_hard_stop(struct net_device *dev)
+{
+	//FIXME !!
+	#if 0
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
+	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
+	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
+	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
+	#endif
+}
+
+
+static void rtl8192_data_hard_resume(struct net_device *dev)
+{
+	// FIXME !!
+	#if 0
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
+	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
+	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
+	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
+	#endif
+}
+
+/* this function TX data frames when the ieee80211 stack requires this.
+ * It checks also if we need to stop the ieee tx queue, eventually do it
+ */
+static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	int ret;
+	//unsigned long flags;
+	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+	u8 queue_index = tcb_desc->queue_index;
+	/* shall not be referred by command packet */
+	assert(queue_index != TXCMD_QUEUE);
+
+	//spin_lock_irqsave(&priv->tx_lock,flags);
+
+        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+#if 0
+	tcb_desc->RATRIndex = 7;
+	tcb_desc->bTxDisableRateFallBack = 1;
+	tcb_desc->bTxUseDriverAssingedRate = 1;
+	tcb_desc->bTxEnableFwCalcDur = 1;
+#endif
+	skb_push(skb, priv->ieee80211->tx_headroom);
+	ret = rtl8192_tx(dev, skb);
+	if(ret != 0) {
+		kfree_skb(skb);
+	};
+
+//
+	if(queue_index!=MGNT_QUEUE) {
+	priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
+	priv->ieee80211->stats.tx_packets++;
+	}
+
+	//spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+//	return ret;
+	return;
+}
+
+/* This is a rough attempt to TX a frame
+ * This is called by the ieee 80211 stack to TX management frames.
+ * If the ring is full packet are dropped (for data frame the queue
+ * is stopped before this can happen).
+ */
+static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+
+	int ret;
+	//unsigned long flags;
+        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+        u8 queue_index = tcb_desc->queue_index;
+
+
+	//spin_lock_irqsave(&priv->tx_lock,flags);
+
+        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+	if(queue_index == TXCMD_QUEUE) {
+	//	skb_push(skb, USB_HWDESC_HEADER_LEN);
+		rtl819xE_tx_cmd(dev, skb);
+		ret = 0;
+	        //spin_unlock_irqrestore(&priv->tx_lock,flags);
+		return ret;
+	} else {
+	//	RT_TRACE(COMP_SEND, "To send management packet\n");
+		tcb_desc->RATRIndex = 7;
+		tcb_desc->bTxDisableRateFallBack = 1;
+		tcb_desc->bTxUseDriverAssingedRate = 1;
+		tcb_desc->bTxEnableFwCalcDur = 1;
+		skb_push(skb, priv->ieee80211->tx_headroom);
+		ret = rtl8192_tx(dev, skb);
+		if(ret != 0) {
+			kfree_skb(skb);
+		};
+	}
+
+//	priv->ieee80211->stats.tx_bytes+=skb->len;
+//	priv->ieee80211->stats.tx_packets++;
+
+	//spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+	return ret;
+
+}
+
+
+void rtl8192_try_wake_queue(struct net_device *dev, int pri);
+
+static void rtl8192_tx_isr(struct net_device *dev, int prio)
+{
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+    struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
+
+    while (skb_queue_len(&ring->queue)) {
+        tx_desc_819x_pci *entry = &ring->desc[ring->idx];
+        struct sk_buff *skb;
+
+        /* beacon packet will only use the first descriptor defautly,
+         * and the OWN may not be cleared by the hardware
+         * */
+        if(prio != BEACON_QUEUE) {
+            if(entry->OWN)
+                return;
+            ring->idx = (ring->idx + 1) % ring->entries;
+        }
+
+        skb = __skb_dequeue(&ring->queue);
+        pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
+                skb->len, PCI_DMA_TODEVICE);
+
+        kfree_skb(skb);
+    }
+    if (prio == MGNT_QUEUE){
+        if (priv->ieee80211->ack_tx_to_ieee){
+            if (rtl8192_is_tx_queue_empty(dev)){
+                priv->ieee80211->ack_tx_to_ieee = 0;
+                ieee80211_ps_tx_ack(priv->ieee80211, 1);
+            }
+        }
+    }
+
+    if(prio != BEACON_QUEUE) {
+        /* try to deal with the pending packets  */
+        tasklet_schedule(&priv->irq_tx_tasklet);
+    }
+
+}
+
+static void rtl8192_stop_beacon(struct net_device *dev)
+{
+	//rtl8192_beacon_disable(dev);
+}
+
+static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
+{
+	 struct r8192_priv *priv = ieee80211_priv(dev);
+	 struct ieee80211_network *net;
+	 u8 i=0, basic_rate = 0;
+	 net = & priv->ieee80211->current_network;
+
+	 for (i=0; i<net->rates_len; i++)
+	 {
+		 basic_rate = net->rates[i]&0x7f;
+		 switch(basic_rate)
+		 {
+			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
+			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
+			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
+			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
+			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
+			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
+			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
+			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
+			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
+			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
+			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
+			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
+		 }
+	 }
+	 for (i=0; i<net->rates_ex_len; i++)
+	 {
+		 basic_rate = net->rates_ex[i]&0x7f;
+		 switch(basic_rate)
+		 {
+			 case MGN_1M:	*rate_config |= RRSR_1M;	break;
+			 case MGN_2M:	*rate_config |= RRSR_2M;	break;
+			 case MGN_5_5M:	*rate_config |= RRSR_5_5M;	break;
+			 case MGN_11M:	*rate_config |= RRSR_11M;	break;
+			 case MGN_6M:	*rate_config |= RRSR_6M;	break;
+			 case MGN_9M:	*rate_config |= RRSR_9M;	break;
+			 case MGN_12M:	*rate_config |= RRSR_12M;	break;
+			 case MGN_18M:	*rate_config |= RRSR_18M;	break;
+			 case MGN_24M:	*rate_config |= RRSR_24M;	break;
+			 case MGN_36M:	*rate_config |= RRSR_36M;	break;
+			 case MGN_48M:	*rate_config |= RRSR_48M;	break;
+			 case MGN_54M:	*rate_config |= RRSR_54M;	break;
+		 }
+	 }
+}
+
+
+#define SHORT_SLOT_TIME 9
+#define NON_SHORT_SLOT_TIME 20
+
+static void rtl8192_update_cap(struct net_device* dev, u16 cap)
+{
+	u32 tmp = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_network *net = &priv->ieee80211->current_network;
+	priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
+	tmp = priv->basic_rate;
+	if (priv->short_preamble)
+		tmp |= BRSR_AckShortPmb;
+	write_nic_dword(dev, RRSR, tmp);
+
+	if (net->mode & (IEEE_G|IEEE_N_24G))
+	{
+		u8 slot_time = 0;
+		if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
+		{//short slot time
+			slot_time = SHORT_SLOT_TIME;
+		}
+		else //long slot time
+			slot_time = NON_SHORT_SLOT_TIME;
+		priv->slot_time = slot_time;
+		write_nic_byte(dev, SLOT_TIME, slot_time);
+	}
+
+}
+
+static void rtl8192_net_update(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_network *net;
+	u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
+	u16 rate_config = 0;
+	net = &priv->ieee80211->current_network;
+	//update Basic rate: RR, BRSR
+	rtl8192_config_rate(dev, &rate_config);
+	// 2007.01.16, by Emily
+	// Select RRSR (in Legacy-OFDM and CCK)
+	// For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
+	// We do not use other rates.
+	 priv->basic_rate = rate_config &= 0x15f;
+	//BSSID
+	write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
+	write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
+#if 0
+	//MSR
+	rtl8192_update_msr(dev);
+#endif
+
+
+//	rtl8192_update_cap(dev, net->capability);
+	if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+	{
+		write_nic_word(dev, ATIMWND, 2);
+		write_nic_word(dev, BCN_DMATIME, 256);
+		write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
+	//	write_nic_word(dev, BcnIntTime, 100);
+	//BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
+		write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
+		write_nic_byte(dev, BCN_ERR_THRESH, 100);
+
+		BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
+	// TODO: BcnIFS may required to be changed on ASIC
+	 	BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
+
+		write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
+	}
+
+
+}
+
+void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
+{
+    struct r8192_priv *priv = ieee80211_priv(dev);
+    struct rtl8192_tx_ring *ring;
+    tx_desc_819x_pci *entry;
+    unsigned int idx;
+    dma_addr_t mapping;
+    cb_desc *tcb_desc;
+    unsigned long flags;
+
+    ring = &priv->tx_ring[TXCMD_QUEUE];
+    mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+
+    spin_lock_irqsave(&priv->irq_th_lock,flags);
+    idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
+    entry = &ring->desc[idx];
+
+    tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+    memset(entry,0,12);
+    entry->LINIP = tcb_desc->bLastIniPkt;
+    entry->FirstSeg = 1;//first segment
+    entry->LastSeg = 1; //last segment
+    if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
+        entry->CmdInit = DESC_PACKET_TYPE_INIT;
+    } else {
+        entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
+        entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
+        entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
+        entry->QueueSelect = QSLT_CMD;
+        entry->TxFWInfoSize = 0x08;
+        entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
+    }
+    entry->TxBufferSize = skb->len;
+    entry->TxBuffAddr = cpu_to_le32(mapping);
+    entry->OWN = 1;
+
+#ifdef JOHN_DUMP_TXDESC
+    {       int i;
+        tx_desc_819x_pci *entry1 =  &ring->desc[0];
+        unsigned int *ptr= (unsigned int *)entry1;
+        printk("<Tx descriptor>:\n");
+        for (i = 0; i < 8; i++)
+            printk("%8x ", ptr[i]);
+        printk("\n");
+    }
+#endif
+    __skb_queue_tail(&ring->queue, skb);
+    spin_unlock_irqrestore(&priv->irq_th_lock,flags);
+
+    write_nic_byte(dev, TPPoll, TPPoll_CQ);
+
+    return;
+}
+
+/*
+ * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
+ * in TxFwInfo data structure
+ * 2006.10.30 by Emily
+ *
+ * \param QUEUEID       Software Queue
+*/
+static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
+{
+	u8 QueueSelect = 0x0;       //defualt set to
+
+	switch(QueueID) {
+		case BE_QUEUE:
+			QueueSelect = QSLT_BE;  //or QSelect = pTcb->priority;
+			break;
+
+		case BK_QUEUE:
+			QueueSelect = QSLT_BK;  //or QSelect = pTcb->priority;
+			break;
+
+		case VO_QUEUE:
+			QueueSelect = QSLT_VO;  //or QSelect = pTcb->priority;
+			break;
+
+		case VI_QUEUE:
+			QueueSelect = QSLT_VI;  //or QSelect = pTcb->priority;
+			break;
+		case MGNT_QUEUE:
+			QueueSelect = QSLT_MGNT;
+			break;
+
+		case BEACON_QUEUE:
+			QueueSelect = QSLT_BEACON;
+			break;
+
+			// TODO: 2006.10.30 mark other queue selection until we verify it is OK
+			// TODO: Remove Assertions
+//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
+		case TXCMD_QUEUE:
+			QueueSelect = QSLT_CMD;
+			break;
+//#endif
+		case HIGH_QUEUE:
+			//QueueSelect = QSLT_HIGH;
+			//break;
+
+		default:
+			RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
+			break;
+	}
+	return QueueSelect;
+}
+
+static u8 MRateToHwRate8190Pci(u8 rate)
+{
+	u8  ret = DESC90_RATE1M;
+
+	switch(rate) {
+		case MGN_1M:	ret = DESC90_RATE1M;		break;
+		case MGN_2M:	ret = DESC90_RATE2M;		break;
+		case MGN_5_5M:	ret = DESC90_RATE5_5M;	break;
+		case MGN_11M:	ret = DESC90_RATE11M;	break;
+		case MGN_6M:	ret = DESC90_RATE6M;		break;
+		case MGN_9M:	ret = DESC90_RATE9M;		break;
+		case MGN_12M:	ret = DESC90_RATE12M;	break;
+		case MGN_18M:	ret = DESC90_RATE18M;	break;
+		case MGN_24M:	ret = DESC90_RATE24M;	break;
+		case MGN_36M:	ret = DESC90_RATE36M;	break;
+		case MGN_48M:	ret = DESC90_RATE48M;	break;
+		case MGN_54M:	ret = DESC90_RATE54M;	break;
+
+		// HT rate since here
+		case MGN_MCS0:	ret = DESC90_RATEMCS0;	break;
+		case MGN_MCS1:	ret = DESC90_RATEMCS1;	break;
+		case MGN_MCS2:	ret = DESC90_RATEMCS2;	break;
+		case MGN_MCS3:	ret = DESC90_RATEMCS3;	break;
+		case MGN_MCS4:	ret = DESC90_RATEMCS4;	break;
+		case MGN_MCS5:	ret = DESC90_RATEMCS5;	break;
+		case MGN_MCS6:	ret = DESC90_RATEMCS6;	break;
+		case MGN_MCS7:	ret = DESC90_RATEMCS7;	break;
+		case MGN_MCS8:	ret = DESC90_RATEMCS8;	break;
+		case MGN_MCS9:	ret = DESC90_RATEMCS9;	break;
+		case MGN_MCS10:	ret = DESC90_RATEMCS10;	break;
+		case MGN_MCS11:	ret = DESC90_RATEMCS11;	break;
+		case MGN_MCS12:	ret = DESC90_RATEMCS12;	break;
+		case MGN_MCS13:	ret = DESC90_RATEMCS13;	break;
+		case MGN_MCS14:	ret = DESC90_RATEMCS14;	break;
+		case MGN_MCS15:	ret = DESC90_RATEMCS15;	break;
+		case (0x80|0x20): ret = DESC90_RATEMCS32; break;
+
+		default:       break;
+	}
+	return ret;
+}
+
+
+static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
+{
+	u8   tmp_Short;
+
+	tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
+
+	if(TxHT==1 && TxRate != DESC90_RATEMCS15)
+		tmp_Short = 0;
+
+	return tmp_Short;
+}
+
+/*
+ * The tx procedure is just as following,
+ * skb->cb will contain all the following information,
+ * priority, morefrag, rate, &dev.
+ * */
+short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
+{
+    struct r8192_priv *priv = ieee80211_priv(dev);
+    struct rtl8192_tx_ring  *ring;
+    unsigned long flags;
+    cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+    tx_desc_819x_pci *pdesc = NULL;
+    TX_FWINFO_8190PCI *pTxFwInfo = NULL;
+    dma_addr_t mapping;
+    bool  multi_addr=false,broad_addr=false,uni_addr=false;
+    u8*   pda_addr = NULL;
+    int   idx;
+
+    mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+    /* collect the tx packets statitcs */
+    pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
+    if(is_multicast_ether_addr(pda_addr))
+        multi_addr = true;
+    else if(is_broadcast_ether_addr(pda_addr))
+        broad_addr = true;
+    else
+        uni_addr = true;
+
+    if(uni_addr)
+        priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
+    else if(multi_addr)
+        priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
+    else
+        priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
+
+    /* fill tx firmware */
+    pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
+    memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
+    pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
+    pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
+    pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
+    pTxFwInfo->Short	= QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
+
+    /* Aggregation related */
+    if(tcb_desc->bAMPDUEnable) {
+        pTxFwInfo->AllowAggregation = 1;
+        pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
+        pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
+    } else {
+        pTxFwInfo->AllowAggregation = 0;
+        pTxFwInfo->RxMF = 0;
+        pTxFwInfo->RxAMD = 0;
+    }
+
+    //
+    // Protection mode related
+    //
+    pTxFwInfo->RtsEnable =	(tcb_desc->bRTSEnable)?1:0;
+    pTxFwInfo->CtsEnable =	(tcb_desc->bCTSEnable)?1:0;
+    pTxFwInfo->RtsSTBC =	(tcb_desc->bRTSSTBC)?1:0;
+    pTxFwInfo->RtsHT=		(tcb_desc->rts_rate&0x80)?1:0;
+    pTxFwInfo->RtsRate =		MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
+    pTxFwInfo->RtsBandwidth = 0;
+    pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
+    pTxFwInfo->RtsShort =	(pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
+    //
+    // Set Bandwidth and sub-channel settings.
+    //
+    if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
+    {
+        if(tcb_desc->bPacketBW)
+        {
+            pTxFwInfo->TxBandwidth = 1;
+#ifdef RTL8190P
+            pTxFwInfo->TxSubCarrier = 3;
+#else
+            pTxFwInfo->TxSubCarrier = 0;	//By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
+#endif
+        }
+        else
+        {
+            pTxFwInfo->TxBandwidth = 0;
+            pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
+        }
+    } else {
+        pTxFwInfo->TxBandwidth = 0;
+        pTxFwInfo->TxSubCarrier = 0;
+    }
+
+    if (0)
+    {
+	    /* 2007/07/25 MH  Copy current TX FW info.*/
+	    memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
+	    printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
+	    printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
+	    printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
+	    printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
+	    printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
+	    printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
+	    printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
+	    printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
+	    printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
+	    printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
+	    printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
+
+        printk("<=====**********************out of print\n");
+
+    }
+    spin_lock_irqsave(&priv->irq_th_lock,flags);
+    ring = &priv->tx_ring[tcb_desc->queue_index];
+    if (tcb_desc->queue_index != BEACON_QUEUE) {
+        idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
+    } else {
+        idx = 0;
+    }
+
+    pdesc = &ring->desc[idx];
+    if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
+	    RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
+			    tcb_desc->queue_index,ring->idx, idx,skb->len);
+	    return skb->len;
+    }
+
+    /* fill tx descriptor */
+    memset((u8*)pdesc,0,12);
+    /*DWORD 0*/
+    pdesc->LINIP = 0;
+    pdesc->CmdInit = 1;
+    pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
+    pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
+
+    /*DWORD 1*/
+    pdesc->SecCAMID= 0;
+    pdesc->RATid = tcb_desc->RATRIndex;
+
+
+    pdesc->NoEnc = 1;
+    pdesc->SecType = 0x0;
+    if (tcb_desc->bHwSec) {
+        static u8 tmp =0;
+        if (!tmp) {
+            printk("==>================hw sec\n");
+            tmp = 1;
+        }
+        switch (priv->ieee80211->pairwise_key_type) {
+            case KEY_TYPE_WEP40:
+            case KEY_TYPE_WEP104:
+                pdesc->SecType = 0x1;
+                pdesc->NoEnc = 0;
+                break;
+            case KEY_TYPE_TKIP:
+                pdesc->SecType = 0x2;
+                pdesc->NoEnc = 0;
+                break;
+            case KEY_TYPE_CCMP:
+                pdesc->SecType = 0x3;
+                pdesc->NoEnc = 0;
+                break;
+            case KEY_TYPE_NA:
+                pdesc->SecType = 0x0;
+                pdesc->NoEnc = 1;
+                break;
+        }
+    }
+
+    //
+    // Set Packet ID
+    //
+    pdesc->PktId = 0x0;
+
+    pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
+    pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
+
+    pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
+    pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
+
+    pdesc->FirstSeg =1;
+    pdesc->LastSeg = 1;
+    pdesc->TxBufferSize = skb->len;
+
+    pdesc->TxBuffAddr = cpu_to_le32(mapping);
+    __skb_queue_tail(&ring->queue, skb);
+    pdesc->OWN = 1;
+    spin_unlock_irqrestore(&priv->irq_th_lock,flags);
+    dev->trans_start = jiffies;
+    write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
+    return 0;
+}
+
+static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
+{
+    struct r8192_priv *priv = ieee80211_priv(dev);
+    rx_desc_819x_pci *entry = NULL;
+    int i;
+
+    priv->rx_ring = pci_alloc_consistent(priv->pdev,
+            sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
+
+    if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
+        RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
+        return -ENOMEM;
+    }
+
+    memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
+    priv->rx_idx = 0;
+
+    for (i = 0; i < priv->rxringcount; i++) {
+        struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
+        dma_addr_t *mapping;
+        entry = &priv->rx_ring[i];
+        if (!skb)
+            return 0;
+        priv->rx_buf[i] = skb;
+        mapping = (dma_addr_t *)skb->cb;
+        *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
+                priv->rxbuffersize, PCI_DMA_FROMDEVICE);
+
+        entry->BufferAddress = cpu_to_le32(*mapping);
+
+        entry->Length = priv->rxbuffersize;
+        entry->OWN = 1;
+    }
+
+    entry->EOR = 1;
+    return 0;
+}
+
+static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
+        unsigned int prio, unsigned int entries)
+{
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+    tx_desc_819x_pci *ring;
+    dma_addr_t dma;
+    int i;
+
+    ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
+    if (!ring || (unsigned long)ring & 0xFF) {
+        RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
+        return -ENOMEM;
+    }
+
+    memset(ring, 0, sizeof(*ring)*entries);
+    priv->tx_ring[prio].desc = ring;
+    priv->tx_ring[prio].dma = dma;
+    priv->tx_ring[prio].idx = 0;
+    priv->tx_ring[prio].entries = entries;
+    skb_queue_head_init(&priv->tx_ring[prio].queue);
+
+    for (i = 0; i < entries; i++)
+        ring[i].NextDescAddress =
+            cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
+
+    return 0;
+}
+
+
+static short rtl8192_pci_initdescring(struct net_device *dev)
+{
+    u32 ret;
+    int i;
+    struct r8192_priv *priv = ieee80211_priv(dev);
+
+    ret = rtl8192_alloc_rx_desc_ring(dev);
+    if (ret) {
+        return ret;
+    }
+
+
+    /* general process for other queue */
+    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
+        if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount)))
+            goto err_free_rings;
+    }
+
+#if 0
+    /* specific process for hardware beacon process */
+    if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2)))
+        goto err_free_rings;
+#endif
+
+    return 0;
+
+err_free_rings:
+    rtl8192_free_rx_ring(dev);
+    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
+        if (priv->tx_ring[i].desc)
+            rtl8192_free_tx_ring(dev, i);
+    return 1;
+}
+
+static void rtl8192_pci_resetdescring(struct net_device *dev)
+{
+    struct r8192_priv *priv = ieee80211_priv(dev);
+    int i;
+
+    /* force the rx_idx to the first one */
+    if(priv->rx_ring) {
+        rx_desc_819x_pci *entry = NULL;
+        for (i = 0; i < priv->rxringcount; i++) {
+            entry = &priv->rx_ring[i];
+            entry->OWN = 1;
+        }
+        priv->rx_idx = 0;
+    }
+
+    /* after reset, release previous pending packet, and force the
+     * tx idx to the first one */
+    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
+        if (priv->tx_ring[i].desc) {
+            struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
+
+            while (skb_queue_len(&ring->queue)) {
+                tx_desc_819x_pci *entry = &ring->desc[ring->idx];
+                struct sk_buff *skb = __skb_dequeue(&ring->queue);
+
+                pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
+                        skb->len, PCI_DMA_TODEVICE);
+                kfree_skb(skb);
+                ring->idx = (ring->idx + 1) % ring->entries;
+            }
+            ring->idx = 0;
+        }
+    }
+}
+
+#if 1
+extern void rtl8192_update_ratr_table(struct net_device* dev);
+static void rtl8192_link_change(struct net_device *dev)
+{
+//	int i;
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
+	if (ieee->state == IEEE80211_LINKED)
+	{
+		rtl8192_net_update(dev);
+		rtl8192_update_ratr_table(dev);
+#if 1
+		//add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
+		if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
+		EnableHWSecurityConfig8192(dev);
+#endif
+	}
+	else
+	{
+		write_nic_byte(dev, 0x173, 0);
+	}
+	/*update timing params*/
+	//rtl8192_set_chan(dev, priv->chan);
+	//MSR
+	rtl8192_update_msr(dev);
+
+	// 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
+	//	// To set CBSSID bit when link with any AP or STA.
+	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
+	{
+		u32 reg = 0;
+		reg = read_nic_dword(dev, RCR);
+		if (priv->ieee80211->state == IEEE80211_LINKED)
+			priv->ReceiveConfig = reg |= RCR_CBSSID;
+		else
+			priv->ReceiveConfig = reg &= ~RCR_CBSSID;
+		write_nic_dword(dev, RCR, reg);
+	}
+}
+#endif
+
+
+static struct ieee80211_qos_parameters def_qos_parameters = {
+        {3,3,3,3},/* cw_min */
+        {7,7,7,7},/* cw_max */
+        {2,2,2,2},/* aifs */
+        {0,0,0,0},/* flags */
+        {0,0,0,0} /* tx_op_limit */
+};
+
+static void rtl8192_update_beacon(struct work_struct * work)
+{
+        struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
+        struct net_device *dev = priv->ieee80211->dev;
+ 	struct ieee80211_device* ieee = priv->ieee80211;
+	struct ieee80211_network* net = &ieee->current_network;
+
+	if (ieee->pHTInfo->bCurrentHTSupport)
+		HTUpdateSelfAndPeerSetting(ieee, net);
+	ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
+	rtl8192_update_cap(dev, net->capability);
+}
+/*
+* background support to run QoS activate functionality
+*/
+static int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
+static void rtl8192_qos_activate(struct work_struct * work)
+{
+        struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
+        struct net_device *dev = priv->ieee80211->dev;
+        struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
+        u8 mode = priv->ieee80211->current_network.mode;
+//        u32 size = sizeof(struct ieee80211_qos_parameters);
+	u8  u1bAIFS;
+	u32 u4bAcParam;
+        int i;
+
+        mutex_lock(&priv->mutex);
+        if(priv->ieee80211->state != IEEE80211_LINKED)
+		goto success;
+	RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
+	/* It better set slot time at first */
+	/* For we just support b/g mode at present, let the slot time at 9/20 selection */
+	/* update the ac parameter to related registers */
+	for(i = 0; i <  QOS_QUEUE_NUM; i++) {
+		//Mode G/A: slotTimeTimer = 9; Mode B: 20
+		u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
+		u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
+				(((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
+				(((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
+				((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
+		printk("===>u4bAcParam:%x, ", u4bAcParam);
+		write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
+		//write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
+	}
+
+success:
+        mutex_unlock(&priv->mutex);
+}
+
+static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
+		int active_network,
+		struct ieee80211_network *network)
+{
+	int ret = 0;
+	u32 size = sizeof(struct ieee80211_qos_parameters);
+
+	if(priv->ieee80211->state !=IEEE80211_LINKED)
+                return ret;
+
+        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+                return ret;
+
+	if (network->flags & NETWORK_HAS_QOS_MASK) {
+		if (active_network &&
+				(network->flags & NETWORK_HAS_QOS_PARAMETERS))
+			network->qos_data.active = network->qos_data.supported;
+
+		if ((network->qos_data.active == 1) && (active_network == 1) &&
+				(network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
+				(network->qos_data.old_param_count !=
+				 network->qos_data.param_count)) {
+			network->qos_data.old_param_count =
+				network->qos_data.param_count;
+			queue_work(priv->priv_wq, &priv->qos_activate);
+			RT_TRACE (COMP_QOS, "QoS parameters change call "
+					"qos_activate\n");
+		}
+	} else {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+		       &def_qos_parameters, size);
+
+		if ((network->qos_data.active == 1) && (active_network == 1)) {
+			queue_work(priv->priv_wq, &priv->qos_activate);
+			RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
+		}
+		network->qos_data.active = 0;
+		network->qos_data.supported = 0;
+	}
+
+	return 0;
+}
+
+/* handle manage frame frame beacon and probe response */
+static int rtl8192_handle_beacon(struct net_device * dev,
+                              struct ieee80211_beacon * beacon,
+                              struct ieee80211_network * network)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	rtl8192_qos_handle_probe_response(priv,1,network);
+
+	queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
+	return 0;
+
+}
+
+/*
+* handling the beaconing responses. if we get different QoS setting
+* off the network from the associated setting, adjust the QoS
+* setting
+*/
+static int rtl8192_qos_association_resp(struct r8192_priv *priv,
+                                    struct ieee80211_network *network)
+{
+        int ret = 0;
+        unsigned long flags;
+        u32 size = sizeof(struct ieee80211_qos_parameters);
+        int set_qos_param = 0;
+
+        if ((priv == NULL) || (network == NULL))
+                return ret;
+
+	if(priv->ieee80211->state !=IEEE80211_LINKED)
+                return ret;
+
+        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
+                return ret;
+
+        spin_lock_irqsave(&priv->ieee80211->lock, flags);
+	if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+			 &network->qos_data.parameters,\
+			sizeof(struct ieee80211_qos_parameters));
+		priv->ieee80211->current_network.qos_data.active = 1;
+#if 0
+		if((priv->ieee80211->current_network.qos_data.param_count != \
+					network->qos_data.param_count))
+#endif
+		 {
+                        set_qos_param = 1;
+			/* update qos parameter for current network */
+			priv->ieee80211->current_network.qos_data.old_param_count = \
+				 priv->ieee80211->current_network.qos_data.param_count;
+			priv->ieee80211->current_network.qos_data.param_count = \
+			     	 network->qos_data.param_count;
+		}
+        } else {
+		memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
+		       &def_qos_parameters, size);
+		priv->ieee80211->current_network.qos_data.active = 0;
+		priv->ieee80211->current_network.qos_data.supported = 0;
+                set_qos_param = 1;
+        }
+
+        spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
+
+	RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
+	if (set_qos_param == 1)
+		queue_work(priv->priv_wq, &priv->qos_activate);
+
+        return ret;
+}
+
+
+static int rtl8192_handle_assoc_response(struct net_device *dev,
+                                     struct ieee80211_assoc_response_frame *resp,
+                                     struct ieee80211_network *network)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        rtl8192_qos_association_resp(priv, network);
+        return 0;
+}
+
+
+//updateRATRTabel for MCS only. Basic rate is not implement.
+void rtl8192_update_ratr_table(struct net_device* dev)
+	//	POCTET_STRING	posLegacyRate,
+	//	u8*			pMcsRate)
+	//	PRT_WLAN_STA	pEntry)
+{
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	u8* pMcsRate = ieee->dot11HTOperationalRateSet;
+	//struct ieee80211_network *net = &ieee->current_network;
+	u32 ratr_value = 0;
+	u8 rate_index = 0;
+
+	rtl8192_config_rate(dev, (u16*)(&ratr_value));
+	ratr_value |= (*(u16*)(pMcsRate)) << 12;
+//	switch (net->mode)
+	switch (ieee->mode)
+	{
+		case IEEE_A:
+			ratr_value &= 0x00000FF0;
+			break;
+		case IEEE_B:
+			ratr_value &= 0x0000000F;
+			break;
+		case IEEE_G:
+			ratr_value &= 0x00000FF7;
+			break;
+		case IEEE_N_24G:
+		case IEEE_N_5G:
+			if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
+				ratr_value &= 0x0007F007;
+			else{
+				if (priv->rf_type == RF_1T2R)
+					ratr_value &= 0x000FF007;
+				else
+					ratr_value &= 0x0F81F007;
+			}
+			break;
+		default:
+			break;
+	}
+	ratr_value &= 0x0FFFFFFF;
+	if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
+		ratr_value |= 0x80000000;
+	}else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
+		ratr_value |= 0x80000000;
+	}
+	write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
+	write_nic_byte(dev, UFWP, 1);
+}
+
+static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
+static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
+static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
+{
+#if 1
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+        int wpa_ie_len= ieee->wpa_ie_len;
+        struct ieee80211_crypt_data* crypt;
+        int encrypt;
+
+        crypt = ieee->crypt[ieee->tx_keyidx];
+        encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
+
+	/* simply judge  */
+	if(encrypt && (wpa_ie_len == 0)) {
+		/* wep encryption, no N mode setting */
+		return false;
+//	} else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
+	} else if((wpa_ie_len != 0)) {
+		/* parse pairwise key type */
+		//if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
+		if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
+			return true;
+		else
+			return false;
+	} else {
+		//RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
+		return true;
+	}
+
+#if 0
+        //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
+        //We can't force in G mode if Pairwie key is AES and group key is TKIP
+        if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption)  ||
+           (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
+           (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
+        {
+                return  false;
+        }
+        else
+                return true;
+#endif
+	return true;
+#endif
+}
+
+static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
+{
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//we donot consider set support rate for ABG mode, only HT MCS rate is set here.
+	if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
+	{
+		memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
+		//RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
+		//RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
+	}
+	else
+		memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
+	return;
+}
+
+static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 ret = 0;
+	switch(priv->rf_chip)
+	{
+		case RF_8225:
+		case RF_8256:
+		case RF_PSEUDO_11N:
+			ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
+			break;
+		case RF_8258:
+			ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
+			break;
+		default:
+			ret = WIRELESS_MODE_B;
+			break;
+	}
+	return ret;
+}
+
+static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
+
+#if 1
+	if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
+	{
+		if(bSupportMode & WIRELESS_MODE_N_24G)
+		{
+			wireless_mode = WIRELESS_MODE_N_24G;
+		}
+		else if(bSupportMode & WIRELESS_MODE_N_5G)
+		{
+			wireless_mode = WIRELESS_MODE_N_5G;
+		}
+		else if((bSupportMode & WIRELESS_MODE_A))
+		{
+			wireless_mode = WIRELESS_MODE_A;
+		}
+		else if((bSupportMode & WIRELESS_MODE_G))
+		{
+			wireless_mode = WIRELESS_MODE_G;
+		}
+		else if((bSupportMode & WIRELESS_MODE_B))
+		{
+			wireless_mode = WIRELESS_MODE_B;
+		}
+		else{
+			RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
+			wireless_mode = WIRELESS_MODE_B;
+		}
+	}
+#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
+	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
+#endif
+	priv->ieee80211->mode = wireless_mode;
+
+	if ((wireless_mode == WIRELESS_MODE_N_24G) ||  (wireless_mode == WIRELESS_MODE_N_5G))
+		priv->ieee80211->pHTInfo->bEnableHT = 1;
+	else
+		priv->ieee80211->pHTInfo->bEnableHT = 0;
+	RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
+	rtl8192_refresh_supportrate(priv);
+#endif
+
+}
+//init priv variables here
+
+static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
+{
+	bool			Reval;
+	struct r8192_priv* priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+
+	if(ieee->bHalfWirelessN24GMode == true)
+		Reval = true;
+	else
+		Reval =  false;
+
+	return Reval;
+}
+
+short rtl8192_is_tx_queue_empty(struct net_device *dev)
+{
+	int i=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	for (i=0; i<=MGNT_QUEUE; i++)
+	{
+		if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
+			continue;
+		if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
+			printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
+			return 0;
+		}
+	}
+	return 1;
+}
+static void rtl8192_hw_sleep_down(struct net_device *dev)
+{
+	RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
+	MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
+}
+static void rtl8192_hw_sleep_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_sleep_wq);
+        struct net_device *dev = ieee->dev;
+	//printk("=========>%s()\n", __FUNCTION__);
+        rtl8192_hw_sleep_down(dev);
+}
+//	printk("dev is %d\n",dev);
+//	printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
+static void rtl8192_hw_wakeup(struct net_device* dev)
+{
+//	u32 flags = 0;
+
+//	spin_lock_irqsave(&priv->ps_lock,flags);
+	RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
+	MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
+	//FIXME: will we send package stored while nic is sleep?
+//	spin_unlock_irqrestore(&priv->ps_lock,flags);
+}
+void rtl8192_hw_wakeup_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_wakeup_wq);
+	struct net_device *dev = ieee->dev;
+	rtl8192_hw_wakeup(dev);
+
+}
+
+#define MIN_SLEEP_TIME 50
+#define MAX_SLEEP_TIME 10000
+static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	u32 rb = jiffies;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->ps_lock,flags);
+
+	/* Writing HW register with 0 equals to disable
+	 * the timer, that is not really what we want
+	 */
+	tl -= MSECS(4+16+7);
+
+	//if(tl == 0) tl = 1;
+
+	/* FIXME HACK FIXME HACK */
+//	force_pci_posting(dev);
+	//mdelay(1);
+
+//	rb = read_nic_dword(dev, TSFTR);
+
+	/* If the interval in witch we are requested to sleep is too
+	 * short then give up and remain awake
+	 */
+	if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
+		||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
+		spin_unlock_irqrestore(&priv->ps_lock,flags);
+		printk("too short to sleep\n");
+		return;
+	}
+
+//	write_nic_dword(dev, TimerInt, tl);
+//	rb = read_nic_dword(dev, TSFTR);
+	{
+		u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
+	//	if (tl<rb)
+		queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
+	}
+	/* if we suspect the TimerInt is gone beyond tl
+	 * while setting it, then give up
+	 */
+#if 1
+	if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
+		((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
+		printk("========>too long to sleep:%x, %x, %lx\n", tl, rb,  MSECS(MAX_SLEEP_TIME));
+		spin_unlock_irqrestore(&priv->ps_lock,flags);
+		return;
+	}
+#endif
+//	if(priv->rf_sleep)
+//		priv->rf_sleep(dev);
+
+	//printk("<=========%s()\n", __FUNCTION__);
+	queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
+	spin_unlock_irqrestore(&priv->ps_lock,flags);
+}
+static void rtl8192_init_priv_variable(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 i;
+	priv->being_init_adapter = false;
+	priv->txbuffsize = 1600;//1024;
+	priv->txfwbuffersize = 4096;
+	priv->txringcount = 64;//32;
+	//priv->txbeaconcount = priv->txringcount;
+	priv->txbeaconcount = 2;
+	priv->rxbuffersize = 9100;//2048;//1024;
+	priv->rxringcount = MAX_RX_COUNT;//64;
+	priv->irq_enabled=0;
+	priv->card_8192 = NIC_8192E;
+	priv->rx_skb_complete = 1;
+	priv->chan = 1; //set to channel 1
+	priv->RegWirelessMode = WIRELESS_MODE_AUTO;
+	priv->RegChannelPlan = 0xf;
+	priv->nrxAMPDU_size = 0;
+	priv->nrxAMPDU_aggr_num = 0;
+	priv->last_rxdesc_tsf_high = 0;
+	priv->last_rxdesc_tsf_low = 0;
+	priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
+	priv->ieee80211->iw_mode = IW_MODE_INFRA;
+	priv->ieee80211->ieee_up=0;
+	priv->retry_rts = DEFAULT_RETRY_RTS;
+	priv->retry_data = DEFAULT_RETRY_DATA;
+	priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
+	priv->ieee80211->rate = 110; //11 mbps
+	priv->ieee80211->short_slot = 1;
+	priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
+	priv->bcck_in_ch14 = false;
+	priv->bfsync_processing  = false;
+	priv->CCKPresentAttentuation = 0;
+	priv->rfa_txpowertrackingindex = 0;
+	priv->rfc_txpowertrackingindex = 0;
+	priv->CckPwEnl = 6;
+	priv->ScanDelay = 50;//for Scan TODO
+	//added by amy for silent reset
+	priv->ResetProgress = RESET_TYPE_NORESET;
+	priv->bForcedSilentReset = 0;
+	priv->bDisableNormalResetCheck = false;
+	priv->force_reset = false;
+	//added by amy for power save
+	priv->RegRfOff = 0;
+	priv->ieee80211->RfOffReason = 0;
+	priv->RFChangeInProgress = false;
+	priv->bHwRfOffAction = 0;
+	priv->SetRFPowerStateInProgress = false;
+	priv->ieee80211->PowerSaveControl.bInactivePs = true;
+	priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
+	//just for debug
+	priv->txpower_checkcnt = 0;
+	priv->thermal_readback_index =0;
+	priv->txpower_tracking_callback_cnt = 0;
+	priv->ccktxpower_adjustcnt_ch14 = 0;
+	priv->ccktxpower_adjustcnt_not_ch14 = 0;
+
+	priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
+	priv->ieee80211->iw_mode = IW_MODE_INFRA;
+	priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN |
+		IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
+		IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
+		IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //|  //IEEE_SOFTMAC_SINGLE_QUEUE;
+
+	priv->ieee80211->active_scan = 1;
+	priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
+	priv->ieee80211->host_encrypt = 1;
+	priv->ieee80211->host_decrypt = 1;
+	//priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
+	//priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
+	priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
+	priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
+	priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
+	priv->ieee80211->set_chan = rtl8192_set_chan;
+	priv->ieee80211->link_change = rtl8192_link_change;
+	priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
+	priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
+	priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
+	priv->ieee80211->init_wmmparam_flag = 0;
+	priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
+	priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
+	priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
+	priv->ieee80211->qos_support = 1;
+	priv->ieee80211->dot11PowerSaveMode = 0;
+	//added by WB
+//	priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
+	priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
+	priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
+	priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
+
+	priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
+//	priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
+	priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
+	priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
+	//added by david
+	priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
+	priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
+	priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
+
+	//added by amy
+	priv->ieee80211->InitialGainHandler = InitialGain819xPci;
+
+	priv->card_type = USB;
+	{
+		priv->ShortRetryLimit = 0x30;
+		priv->LongRetryLimit = 0x30;
+	}
+	priv->EarlyRxThreshold = 7;
+	priv->enable_gpio0 = 0;
+
+	priv->TransmitConfig = 0;
+
+	priv->ReceiveConfig = RCR_ADD3	|
+		RCR_AMF | RCR_ADF |		//accept management/data
+		RCR_AICV |			//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
+		RCR_AB | RCR_AM | RCR_APM |	//accept BC/MC/UC
+		RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
+		((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
+
+	priv->irq_mask = 	(u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
+				IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
+				IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW	|\
+				IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
+
+	priv->AcmControl = 0;
+	priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
+	if (priv->pFirmware)
+	memset(priv->pFirmware, 0, sizeof(rt_firmware));
+
+	/* rx related queue */
+        skb_queue_head_init(&priv->rx_queue);
+	skb_queue_head_init(&priv->skb_queue);
+
+	/* Tx related queue */
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
+	}
+	for(i = 0; i < MAX_QUEUE_SIZE; i++) {
+		skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
+	}
+	priv->rf_set_chan = rtl8192_phy_SwChnl;
+}
+
+//init lock here
+static void rtl8192_init_priv_lock(struct r8192_priv* priv)
+{
+	spin_lock_init(&priv->tx_lock);
+	spin_lock_init(&priv->irq_lock);//added by thomas
+	spin_lock_init(&priv->irq_th_lock);
+	spin_lock_init(&priv->rf_ps_lock);
+	spin_lock_init(&priv->ps_lock);
+	//spin_lock_init(&priv->rf_lock);
+	sema_init(&priv->wx_sem,1);
+	sema_init(&priv->rf_sem,1);
+	mutex_init(&priv->mutex);
+}
+
+extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
+
+void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
+void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
+void rtl8192_prepare_beacon(struct r8192_priv *priv);
+//init tasklet and wait_queue here. only 2.6 above kernel is considered
+#define DRV_NAME "wlan0"
+static void rtl8192_init_priv_task(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+#ifdef PF_SYNCTHREAD
+	priv->priv_wq = create_workqueue(DRV_NAME,0);
+#else
+	priv->priv_wq = create_workqueue(DRV_NAME);
+#endif
+
+//	INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
+	INIT_WORK(&priv->reset_wq,  rtl8192_restart);
+//	INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
+	INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
+	INIT_DELAYED_WORK(&priv->txpower_tracking_wq,  dm_txpower_trackingcallback);
+	INIT_DELAYED_WORK(&priv->rfpath_check_wq,  dm_rf_pathcheck_workitemcallback);
+	INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
+	//INIT_WORK(&priv->SwChnlWorkItem,  rtl8192_SwChnl_WorkItem);
+	//INIT_WORK(&priv->SetBWModeWorkItem,  rtl8192_SetBWModeWorkItem);
+	INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
+	INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
+	INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
+
+	tasklet_init(&priv->irq_rx_tasklet,
+	     (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
+	     (unsigned long)priv);
+	tasklet_init(&priv->irq_tx_tasklet,
+	     (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
+	     (unsigned long)priv);
+        tasklet_init(&priv->irq_prepare_beacon_tasklet,
+                (void(*)(unsigned long))rtl8192_prepare_beacon,
+                (unsigned long)priv);
+}
+
+static void rtl8192_get_eeprom_size(struct net_device* dev)
+{
+	u16 curCR = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
+	curCR = read_nic_dword(dev, EPROM_CMD);
+	RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
+	//whether need I consider BIT5?
+	priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
+	RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
+}
+
+//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
+static inline u16 endian_swap(u16* data)
+{
+	u16 tmp = *data;
+	*data = (tmp >> 8) | (tmp << 8);
+	return *data;
+}
+
+/*
+ *	Note:	Adapter->EEPROMAddressSize should be set before this function call.
+ * 			EEPROM address size can be got through GetEEPROMSize8185()
+*/
+static void rtl8192_read_eeprom_info(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	u8			tempval;
+#ifdef RTL8192E
+	u8			ICVer8192, ICVer8256;
+#endif
+	u16			i,usValue, IC_Version;
+	u16			EEPROMId;
+#ifdef RTL8190P
+   	u8			offset;//, tmpAFR;
+    	u8      		EepromTxPower[100];
+#endif
+	u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
+	RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
+
+
+	// TODO: I don't know if we need to apply EF function to EEPROM read function
+
+	//2 Read EEPROM ID to make sure autoload is success
+	EEPROMId = eprom_read(dev, 0);
+	if( EEPROMId != RTL8190_EEPROM_ID )
+	{
+		RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
+		priv->AutoloadFailFlag=true;
+	}
+	else
+	{
+		priv->AutoloadFailFlag=false;
+	}
+
+	//
+	// Assign Chip Version ID
+	//
+	// Read IC Version && Channel Plan
+	if(!priv->AutoloadFailFlag)
+	{
+		// VID, PID
+		priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
+		priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
+
+		usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
+		priv->eeprom_CustomerID = (u8)( usValue & 0xff);
+		usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
+		priv->eeprom_ChannelPlan = usValue&0xff;
+		IC_Version = ((usValue&0xff00)>>8);
+
+#ifdef RTL8190P
+		priv->card_8192_version = (VERSION_8190)(IC_Version);
+#else
+	#ifdef RTL8192E
+		ICVer8192 = (IC_Version&0xf);		//bit0~3; 1:A cut, 2:B cut, 3:C cut...
+		ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
+		RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
+		RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
+		if(ICVer8192 == 0x2)	//B-cut
+		{
+			if(ICVer8256 == 0x5) //E-cut
+				priv->card_8192_version= VERSION_8190_BE;
+		}
+	#endif
+#endif
+		switch(priv->card_8192_version)
+		{
+			case VERSION_8190_BD:
+			case VERSION_8190_BE:
+				break;
+			default:
+				priv->card_8192_version = VERSION_8190_BD;
+				break;
+		}
+		RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
+	}
+	else
+	{
+		priv->card_8192_version = VERSION_8190_BD;
+		priv->eeprom_vid = 0;
+		priv->eeprom_did = 0;
+		priv->eeprom_CustomerID = 0;
+		priv->eeprom_ChannelPlan = 0;
+		RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
+	}
+
+	RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
+	RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
+	RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
+
+	//2 Read Permanent MAC address
+	if(!priv->AutoloadFailFlag)
+	{
+		for(i = 0; i < 6; i += 2)
+		{
+			usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
+			*(u16*)(&dev->dev_addr[i]) = usValue;
+		}
+	} else {
+		// when auto load failed,  the last address byte set to be a random one.
+		// added by david woo.2007/11/7
+		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
+	}
+
+	RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
+			dev->dev_addr[0], dev->dev_addr[1],
+			dev->dev_addr[2], dev->dev_addr[3],
+			dev->dev_addr[4], dev->dev_addr[5]);
+
+		//2 TX Power Check EEPROM Fail or not
+	if(priv->card_8192_version > VERSION_8190_BD) {
+		priv->bTXPowerDataReadFromEEPORM = true;
+	} else {
+		priv->bTXPowerDataReadFromEEPORM = false;
+	}
+
+	// 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
+	priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
+
+	if(priv->card_8192_version > VERSION_8190_BD)
+	{
+		// Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
+		if(!priv->AutoloadFailFlag)
+		{
+			tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
+			priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf;	// bit[3:0]
+
+			if (tempval&0x80)	//RF-indication, bit[7]
+				priv->rf_type = RF_1T2R;
+			else
+				priv->rf_type = RF_2T4R;
+		}
+		else
+		{
+			priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
+		}
+		RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
+			priv->EEPROMLegacyHTTxPowerDiff);
+
+		// Read ThermalMeter from EEPROM
+		if(!priv->AutoloadFailFlag)
+		{
+			priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
+		}
+		else
+		{
+			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
+		}
+		RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
+		//vivi, for tx power track
+		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
+
+		if(priv->epromtype == EPROM_93c46)
+		{
+		// Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
+		if(!priv->AutoloadFailFlag)
+		{
+				usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
+				priv->EEPROMAntPwDiff = (usValue&0x0fff);
+				priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
+		}
+		else
+		{
+				priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
+				priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
+		}
+			RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
+			RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
+
+		//
+		// Get per-channel Tx Power Level
+		//
+		for(i=0; i<14; i+=2)
+		{
+			if(!priv->AutoloadFailFlag)
+			{
+				usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
+			}
+			else
+			{
+				usValue = EEPROM_Default_TxPower;
+			}
+			*((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
+			RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
+			RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
+		}
+		for(i=0; i<14; i+=2)
+		{
+			if(!priv->AutoloadFailFlag)
+			{
+				usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
+			}
+			else
+			{
+				usValue = EEPROM_Default_TxPower;
+			}
+			*((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
+			RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
+			RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
+		}
+		}
+		else if(priv->epromtype== EPROM_93c56)
+		{
+		#ifdef RTL8190P
+			// Read CrystalCap from EEPROM
+			if(!priv->AutoloadFailFlag)
+			{
+				priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
+				priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
+			}
+			else
+			{
+				priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
+				priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
+			}
+			RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
+			RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
+
+			// Get Tx Power Level by Channel
+			if(!priv->AutoloadFailFlag)
+			{
+				    // Read Tx power of Channel 1 ~ 14 from EEPROM.
+			       for(i = 0; i < 12; i+=2)
+				{
+					if (i <6)
+						offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
+					else
+						offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
+					usValue = eprom_read(dev, (offset>>1));
+				       *((u16*)(&EepromTxPower[i])) = usValue;
+				}
+
+			       for(i = 0; i < 12; i++)
+			       	{
+			       		if (i <= 2)
+						priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
+					else if ((i >=3 )&&(i <= 5))
+						priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
+					else if ((i >=6 )&&(i <= 8))
+						priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
+					else
+						priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
+				}
+			}
+			else
+			{
+				priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
+
+				priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
+
+				priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
+
+				priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
+				priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
+			}
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
+			RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
+#endif
+
+		}
+		//
+		// Update HAL variables.
+		//
+		if(priv->epromtype == EPROM_93c46)
+		{
+			for(i=0; i<14; i++)
+			{
+				priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
+				priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
+			}
+			priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
+		// Antenna B gain offset to antenna A, bit0~3
+			priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
+		// Antenna C gain offset to antenna A, bit4~7
+			priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
+		// Antenna D gain offset to antenna A, bit8~11
+			priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
+		// CrystalCap, bit12~15
+			priv->CrystalCap = priv->EEPROMCrystalCap;
+		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
+			priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
+			priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
+		}
+		else if(priv->epromtype == EPROM_93c56)
+		{
+			//char	cck_pwr_diff_a=0, cck_pwr_diff_c=0;
+
+			//cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
+			//cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
+			for(i=0; i<3; i++)	// channel 1~3 use the same Tx Power Level.
+			{
+				priv->TxPowerLevelCCK_A[i]  = priv->EEPROMRfACCKChnl1TxPwLevel[0];
+				priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
+				priv->TxPowerLevelCCK_C[i] =  priv->EEPROMRfCCCKChnl1TxPwLevel[0];
+				priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
+			}
+			for(i=3; i<9; i++)	// channel 4~9 use the same Tx Power Level
+			{
+				priv->TxPowerLevelCCK_A[i]  = priv->EEPROMRfACCKChnl1TxPwLevel[1];
+				priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
+				priv->TxPowerLevelCCK_C[i] =  priv->EEPROMRfCCCKChnl1TxPwLevel[1];
+				priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
+			}
+			for(i=9; i<14; i++)	// channel 10~14 use the same Tx Power Level
+			{
+				priv->TxPowerLevelCCK_A[i]  = priv->EEPROMRfACCKChnl1TxPwLevel[2];
+				priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
+				priv->TxPowerLevelCCK_C[i] =  priv->EEPROMRfCCCKChnl1TxPwLevel[2];
+				priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
+			}
+			for(i=0; i<14; i++)
+				RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
+			for(i=0; i<14; i++)
+				RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
+			for(i=0; i<14; i++)
+				RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
+			for(i=0; i<14; i++)
+				RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
+			priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
+			priv->AntennaTxPwDiff[0] = 0;
+			priv->AntennaTxPwDiff[1] = 0;
+			priv->AntennaTxPwDiff[2] = 0;
+			priv->CrystalCap = priv->EEPROMCrystalCap;
+			// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
+			priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
+			priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
+		}
+	}
+
+	if(priv->rf_type == RF_1T2R)
+	{
+		RT_TRACE(COMP_INIT, "\n1T2R config\n");
+	}
+	else if (priv->rf_type == RF_2T4R)
+	{
+		RT_TRACE(COMP_INIT, "\n2T4R config\n");
+	}
+
+	// 2008/01/16 MH We can only know RF type in the function. So we have to init
+	// DIG RATR table again.
+	init_rate_adaptive(dev);
+
+	//1 Make a copy for following variables and we can change them if we want
+
+	priv->rf_chip= RF_8256;
+
+	if(priv->RegChannelPlan == 0xf)
+	{
+		priv->ChannelPlan = priv->eeprom_ChannelPlan;
+	}
+	else
+	{
+		priv->ChannelPlan = priv->RegChannelPlan;
+	}
+
+	//
+	//  Used PID and DID to Set CustomerID
+	//
+	if( priv->eeprom_vid == 0x1186 &&  priv->eeprom_did == 0x3304 )
+	{
+		priv->CustomerID =  RT_CID_DLINK;
+	}
+
+	switch(priv->eeprom_CustomerID)
+	{
+		case EEPROM_CID_DEFAULT:
+			priv->CustomerID = RT_CID_DEFAULT;
+			break;
+		case EEPROM_CID_CAMEO:
+			priv->CustomerID = RT_CID_819x_CAMEO;
+			break;
+		case  EEPROM_CID_RUNTOP:
+			priv->CustomerID = RT_CID_819x_RUNTOP;
+			break;
+		case EEPROM_CID_NetCore:
+			priv->CustomerID = RT_CID_819x_Netcore;
+			break;
+		case EEPROM_CID_TOSHIBA:        // Merge by Jacken, 2008/01/31
+			priv->CustomerID = RT_CID_TOSHIBA;
+			if(priv->eeprom_ChannelPlan&0x80)
+				priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
+			else
+				priv->ChannelPlan = 0x0;
+			RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
+				priv->ChannelPlan);
+			break;
+		case EEPROM_CID_Nettronix:
+			priv->ScanDelay = 100;	//cosa add for scan
+			priv->CustomerID = RT_CID_Nettronix;
+			break;
+		case EEPROM_CID_Pronet:
+			priv->CustomerID = RT_CID_PRONET;
+			break;
+		case EEPROM_CID_DLINK:
+			priv->CustomerID = RT_CID_DLINK;
+			break;
+
+		case EEPROM_CID_WHQL:
+			//Adapter->bInHctTest = TRUE;//do not supported
+
+			//priv->bSupportTurboMode = FALSE;
+			//priv->bAutoTurboBy8186 = FALSE;
+
+			//pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
+			//pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
+			//pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
+
+			break;
+		default:
+			// value from RegCustomerID
+			break;
+	}
+
+	//Avoid the channel plan array overflow, by Bruce, 2007-08-27.
+	if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
+		priv->ChannelPlan = 0; //FCC
+
+	switch(priv->CustomerID)
+	{
+		case RT_CID_DEFAULT:
+		#ifdef RTL8190P
+			priv->LedStrategy = HW_LED;
+		#else
+			#ifdef RTL8192E
+			priv->LedStrategy = SW_LED_MODE1;
+			#endif
+		#endif
+			break;
+
+		case RT_CID_819x_CAMEO:
+			priv->LedStrategy = SW_LED_MODE2;
+			break;
+
+		case RT_CID_819x_RUNTOP:
+			priv->LedStrategy = SW_LED_MODE3;
+			break;
+
+		case RT_CID_819x_Netcore:
+			priv->LedStrategy = SW_LED_MODE4;
+			break;
+
+		case RT_CID_Nettronix:
+			priv->LedStrategy = SW_LED_MODE5;
+			break;
+
+		case RT_CID_PRONET:
+			priv->LedStrategy = SW_LED_MODE6;
+			break;
+
+		case RT_CID_TOSHIBA:   //Modify by Jacken 2008/01/31
+			// Do nothing.
+			//break;
+
+		default:
+		#ifdef RTL8190P
+			priv->LedStrategy = HW_LED;
+		#else
+			#ifdef RTL8192E
+			priv->LedStrategy = SW_LED_MODE1;
+			#endif
+		#endif
+			break;
+	}
+/*
+	//2008.06.03, for WOL
+	if( priv->eeprom_vid == 0x1186 &&  priv->eeprom_did == 0x3304)
+		priv->ieee80211->bSupportRemoteWakeUp = TRUE;
+	else
+		priv->ieee80211->bSupportRemoteWakeUp = FALSE;
+*/
+	RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
+	RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
+	RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
+	RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
+
+	return ;
+}
+
+
+static short rtl8192_get_channel_map(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef ENABLE_DOT11D
+	if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
+		printk("rtl8180_init:Error channel plan! Set to default.\n");
+		priv->ChannelPlan= 0;
+	}
+	RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
+
+	rtl819x_set_channel_map(priv->ChannelPlan, priv);
+#else
+	int ch,i;
+	//Set Default Channel Plan
+	if(!channels){
+		DMESG("No channels, aborting");
+		return -1;
+	}
+	ch=channels;
+	priv->ChannelPlan= 0;//hikaru
+	 // set channels 1..14 allowed in given locale
+	for (i=1; i<=14; i++) {
+		(priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
+		ch >>= 1;
+	}
+#endif
+	return 0;
+}
+
+static short rtl8192_init(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	memset(&(priv->stats),0,sizeof(struct Stats));
+	rtl8192_init_priv_variable(dev);
+	rtl8192_init_priv_lock(priv);
+	rtl8192_init_priv_task(dev);
+	rtl8192_get_eeprom_size(dev);
+	rtl8192_read_eeprom_info(dev);
+	rtl8192_get_channel_map(dev);
+	init_hal_dm(dev);
+	init_timer(&priv->watch_dog_timer);
+	priv->watch_dog_timer.data = (unsigned long)dev;
+	priv->watch_dog_timer.function = watch_dog_timer_callback;
+#if defined(IRQF_SHARED)
+        if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
+#else
+        if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
+#endif
+		printk("Error allocating IRQ %d",dev->irq);
+		return -1;
+	}else{
+		priv->irq=dev->irq;
+		printk("IRQ %d",dev->irq);
+	}
+	if(rtl8192_pci_initdescring(dev)!=0){
+		printk("Endopoints initialization failed");
+		return -1;
+	}
+
+	//rtl8192_rx_enable(dev);
+	//rtl8192_adapter_start(dev);
+	return 0;
+}
+
+/******************************************************************************
+ *function:  This function actually only set RRSR, RATR and BW_OPMODE registers
+ *	     not to do all the hw config as its name says
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  This part need to modified according to the rate set we filtered
+ * ****************************************************************************/
+static void rtl8192_hwconfig(struct net_device* dev)
+{
+	u32 regRATR = 0, regRRSR = 0;
+	u8 regBwOpMode = 0, regTmp = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+// Set RRSR, RATR, and BW_OPMODE registers
+	//
+	switch(priv->ieee80211->mode)
+	{
+	case WIRELESS_MODE_B:
+		regBwOpMode = BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_CCK;
+		regRRSR = RATE_ALL_CCK;
+		break;
+	case WIRELESS_MODE_A:
+		regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_OFDM_AG;
+		regRRSR = RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_G:
+		regBwOpMode = BW_OPMODE_20MHZ;
+		regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_AUTO:
+	case WIRELESS_MODE_N_24G:
+		// It support CCK rate by default.
+		// CCK rate will be filtered out only when associated AP does not support it.
+		regBwOpMode = BW_OPMODE_20MHZ;
+			regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+			regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+		break;
+	case WIRELESS_MODE_N_5G:
+		regBwOpMode = BW_OPMODE_5G;
+		regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
+		regRRSR = RATE_ALL_OFDM_AG;
+		break;
+	}
+
+	write_nic_byte(dev, BW_OPMODE, regBwOpMode);
+	{
+		u32 ratr_value = 0;
+		ratr_value = regRATR;
+		if (priv->rf_type == RF_1T2R)
+		{
+			ratr_value &= ~(RATE_ALL_OFDM_2SS);
+		}
+		write_nic_dword(dev, RATR0, ratr_value);
+		write_nic_byte(dev, UFWP, 1);
+	}
+	regTmp = read_nic_byte(dev, 0x313);
+	regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
+	write_nic_dword(dev, RRSR, regRRSR);
+
+	//
+	// Set Retry Limit here
+	//
+	write_nic_word(dev, RETRY_LIMIT,
+			priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
+			priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
+	// Set Contention Window here
+
+	// Set Tx AGC
+
+	// Set Tx Antenna including Feedback control
+
+	// Set Auto Rate fallback control
+
+
+}
+
+
+static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+//	struct ieee80211_device *ieee = priv->ieee80211;
+	u32 ulRegRead;
+	RT_STATUS rtStatus = RT_STATUS_SUCCESS;
+//	static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
+//	static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
+	//u8 eRFPath;
+	u8 tmpvalue;
+#ifdef RTL8192E
+	u8 ICVersion,SwitchingRegulatorOutput;
+#endif
+	bool bfirmwareok = true;
+#ifdef RTL8190P
+	u8 ucRegRead;
+#endif
+	u32	tmpRegA, tmpRegC, TempCCk;
+	int	i =0;
+//	u32 dwRegRead = 0;
+
+	RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
+	priv->being_init_adapter = true;
+        rtl8192_pci_resetdescring(dev);
+	// 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
+	priv->Rf_Mode = RF_OP_By_SW_3wire;
+#ifdef RTL8192E
+        //dPLL on
+        if(priv->ResetProgress == RESET_TYPE_NORESET)
+        {
+            write_nic_byte(dev, ANAPAR, 0x37);
+            // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
+            // Joseph increae the time to prevent firmware download fail
+            mdelay(500);
+        }
+#endif
+	//PlatformSleepUs(10000);
+	// For any kind of InitializeAdapter process, we shall use system now!!
+	priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
+
+	// Set to eRfoff in order not to count receive count.
+	if(priv->RegRfOff == TRUE)
+		priv->ieee80211->eRFPowerState = eRfOff;
+
+	//
+	//3 //Config CPUReset Register
+	//3//
+	//3 Firmware Reset Or Not
+	ulRegRead = read_nic_dword(dev, CPU_GEN);
+	if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
+	{	//called from MPInitialized. do nothing
+		ulRegRead |= CPU_GEN_SYSTEM_RESET;
+	}else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
+		ulRegRead |= CPU_GEN_FIRMWARE_RESET;	// Called from MPReset
+	else
+		RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__,   priv->pFirmware->firmware_status);
+
+#ifdef RTL8190P
+	//2008.06.03, for WOL 90 hw bug
+	ulRegRead &= (~(CPU_GEN_GPIO_UART));
+#endif
+
+	write_nic_dword(dev, CPU_GEN, ulRegRead);
+	//mdelay(100);
+
+#ifdef RTL8192E
+
+	//3//
+	//3 //Fix the issue of E-cut high temperature issue
+	//3//
+	// TODO: E cut only
+	ICVersion = read_nic_byte(dev, IC_VERRSION);
+	if(ICVersion >= 0x4) //E-cut only
+	{
+		// HW SD suggest that we should not wirte this register too often, so driver
+		// should readback this register. This register will be modified only when
+		// power on reset
+		SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
+		if(SwitchingRegulatorOutput  != 0xb8)
+		{
+			write_nic_byte(dev, SWREGULATOR, 0xa8);
+			mdelay(1);
+			write_nic_byte(dev, SWREGULATOR, 0xb8);
+		}
+	}
+#endif
+
+
+	//3//
+	//3// Initialize BB before MAC
+	//3//
+	RT_TRACE(COMP_INIT, "BB Config Start!\n");
+	rtStatus = rtl8192_BBConfig(dev);
+	if(rtStatus != RT_STATUS_SUCCESS)
+	{
+		RT_TRACE(COMP_ERR, "BB Config failed\n");
+		return rtStatus;
+	}
+	RT_TRACE(COMP_INIT,"BB Config Finished!\n");
+
+	//3//Set Loopback mode or Normal mode
+	//3//
+	//2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
+	//	because setting of System_Reset bit reset MAC to default transmission mode.
+		//Loopback mode or not
+	priv->LoopbackMode = RTL819X_NO_LOOPBACK;
+	//priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	{
+	ulRegRead = read_nic_dword(dev, CPU_GEN);
+	if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
+	{
+		ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
+	}
+	else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
+	{
+		ulRegRead |= CPU_CCK_LOOPBACK;
+	}
+	else
+	{
+		RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
+	}
+
+	//2008.06.03, for WOL
+	//ulRegRead &= (~(CPU_GEN_GPIO_UART));
+	write_nic_dword(dev, CPU_GEN, ulRegRead);
+
+	// 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
+	udelay(500);
+	}
+	//3Set Hardware(Do nothing now)
+	rtl8192_hwconfig(dev);
+	//2=======================================================
+	// Common Setting for all of the FPGA platform. (part 1)
+	//2=======================================================
+	// If there is changes, please make sure it applies to all of the FPGA version
+	//3 Turn on Tx/Rx
+	write_nic_byte(dev, CMDR, CR_RE|CR_TE);
+
+	//2Set Tx dma burst
+#ifdef RTL8190P
+	write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | \
+											(MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) | \
+											(1<<MULRW_SHIFT)));
+#else
+	#ifdef RTL8192E
+	write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |\
+				   (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
+	#endif
+#endif
+	//set IDR0 here
+	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
+	write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
+	//set RCR
+	write_nic_dword(dev, RCR, priv->ReceiveConfig);
+
+	//3 Initialize Number of Reserved Pages in Firmware Queue
+	#ifdef TO_DO_LIST
+	if(priv->bInHctTest)
+	{
+		PlatformEFIOWrite4Byte(Adapter, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
+                                       	NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
+					NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
+					NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
+		PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
+		PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
+					NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
+					NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
+	}
+	else
+	#endif
+	{
+		write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
+					NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
+					NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
+					NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
+		write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
+		write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
+					NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
+					NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
+	}
+
+	rtl8192_tx_enable(dev);
+	rtl8192_rx_enable(dev);
+	//3Set Response Rate Setting Register
+	// CCK rate is supported by default.
+	// CCK rate will be filtered out only when associated AP does not support it.
+	ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR))  | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
+	write_nic_dword(dev, RRSR, ulRegRead);
+	write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
+
+	//2Set AckTimeout
+	// TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
+	write_nic_byte(dev, ACK_TIMEOUT, 0x30);
+
+	//rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
+	//-----------------------------------------------------------------------------
+	// Set up security related. 070106, by rcnjko:
+	// 1. Clear all H/W keys.
+	// 2. Enable H/W encryption/decryption.
+	//-----------------------------------------------------------------------------
+	CamResetAllEntry(dev);
+	{
+		u8 SECR_value = 0x0;
+		SECR_value |= SCR_TxEncEnable;
+		SECR_value |= SCR_RxDecEnable;
+		SECR_value |= SCR_NoSKMC;
+		write_nic_byte(dev, SECR, SECR_value);
+	}
+	//3Beacon related
+	write_nic_word(dev, ATIMWND, 2);
+	write_nic_word(dev, BCN_INTERVAL, 100);
+	for (i=0; i<QOS_QUEUE_NUM; i++)
+		write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
+	//
+	// Switching regulator controller: This is set temporarily.
+	// It's not sure if this can be removed in the future.
+	// PJ advised to leave it by default.
+	//
+	write_nic_byte(dev, 0xbe, 0xc0);
+
+	//2=======================================================
+	// Set PHY related configuration defined in MAC register bank
+	//2=======================================================
+	rtl8192_phy_configmac(dev);
+
+	if (priv->card_8192_version > (u8) VERSION_8190_BD) {
+		rtl8192_phy_getTxPower(dev);
+		rtl8192_phy_setTxPower(dev, priv->chan);
+	}
+
+	//if D or C cut
+		tmpvalue = read_nic_byte(dev, IC_VERRSION);
+		priv->IC_Cut = tmpvalue;
+		RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
+		if(priv->IC_Cut >= IC_VersionCut_D)
+		{
+			//pHalData->bDcut = TRUE;
+			if(priv->IC_Cut == IC_VersionCut_D)
+				RT_TRACE(COMP_INIT, "D-cut\n");
+			if(priv->IC_Cut == IC_VersionCut_E)
+			{
+				RT_TRACE(COMP_INIT, "E-cut\n");
+				// HW SD suggest that we should not wirte this register too often, so driver
+				// should readback this register. This register will be modified only when
+				// power on reset
+			}
+		}
+		else
+		{
+			//pHalData->bDcut = FALSE;
+			RT_TRACE(COMP_INIT, "Before C-cut\n");
+		}
+
+#if 1
+	//Firmware download
+	RT_TRACE(COMP_INIT, "Load Firmware!\n");
+	bfirmwareok = init_firmware(dev);
+	if(bfirmwareok != true) {
+		rtStatus = RT_STATUS_FAILURE;
+		return rtStatus;
+	}
+	RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
+#endif
+	//RF config
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	{
+	RT_TRACE(COMP_INIT, "RF Config Started!\n");
+	rtStatus = rtl8192_phy_RFConfig(dev);
+	if(rtStatus != RT_STATUS_SUCCESS)
+	{
+		RT_TRACE(COMP_ERR, "RF Config failed\n");
+			return rtStatus;
+	}
+	RT_TRACE(COMP_INIT, "RF Config Finished!\n");
+	}
+	rtl8192_phy_updateInitGain(dev);
+
+	/*---- Set CCK and OFDM Block "ON"----*/
+	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
+	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
+
+#ifdef RTL8192E
+	//Enable Led
+	write_nic_byte(dev, 0x87, 0x0);
+#endif
+#ifdef RTL8190P
+	//2008.06.03, for WOL
+	ucRegRead = read_nic_byte(dev, GPE);
+	ucRegRead |= BIT0;
+	write_nic_byte(dev, GPE, ucRegRead);
+
+	ucRegRead = read_nic_byte(dev, GPO);
+	ucRegRead &= ~BIT0;
+	write_nic_byte(dev, GPO, ucRegRead);
+#endif
+
+	//2=======================================================
+	// RF Power Save
+	//2=======================================================
+#ifdef ENABLE_IPS
+
+{
+	if(priv->RegRfOff == TRUE)
+	{ // User disable RF via registry.
+		RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
+		MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
+#if 0//cosa, ask SD3 willis and he doesn't know what is this for
+		// Those action will be discard in MgntActSet_RF_State because off the same state
+	for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+		PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
+#endif
+	}
+	else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
+	{ // H/W or S/W RF OFF before sleep.
+		RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
+		MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
+	}
+	else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
+	{ // H/W or S/W RF OFF before sleep.
+		RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
+		MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
+	}
+	else
+	{
+		RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
+		priv->ieee80211->eRFPowerState = eRfOn;
+		priv->ieee80211->RfOffReason = 0;
+		//DrvIFIndicateCurrentPhyStatus(Adapter);
+	// LED control
+	//Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
+
+	//
+	// If inactive power mode is enabled, disable rf while in disconnected state.
+	// But we should still tell upper layer we are in rf on state.
+	// 2007.07.16, by shien chang.
+	//
+		//if(!Adapter->bInHctTest)
+	//IPSEnter(Adapter);
+
+	}
+}
+#endif
+	if(1){
+#ifdef RTL8192E
+			// We can force firmware to do RF-R/W
+			if(priv->ieee80211->FwRWRF)
+				priv->Rf_Mode = RF_OP_By_FW;
+			else
+				priv->Rf_Mode = RF_OP_By_SW_3wire;
+#else
+			priv->Rf_Mode = RF_OP_By_SW_3wire;
+#endif
+	}
+#ifdef RTL8190P
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	{
+		dm_initialize_txpower_tracking(dev);
+
+		tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
+		tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
+
+		if(priv->rf_type == RF_2T4R){
+		for(i = 0; i<TxBBGainTableLength; i++)
+		{
+			if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
+			{
+				priv->rfa_txpowertrackingindex= (u8)i;
+				priv->rfa_txpowertrackingindex_real= (u8)i;
+				priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
+				break;
+			}
+		}
+		}
+		for(i = 0; i<TxBBGainTableLength; i++)
+		{
+			if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
+			{
+				priv->rfc_txpowertrackingindex= (u8)i;
+				priv->rfc_txpowertrackingindex_real= (u8)i;
+				priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
+				break;
+			}
+		}
+		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
+
+		for(i=0 ; i<CCKTxBBGainTableLength ; i++)
+		{
+			if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
+			{
+				priv->CCKPresentAttentuation_20Mdefault =(u8) i;
+				break;
+			}
+		}
+		priv->CCKPresentAttentuation_40Mdefault = 0;
+		priv->CCKPresentAttentuation_difference = 0;
+		priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
+	}
+#else
+	#ifdef RTL8192E
+	if(priv->ResetProgress == RESET_TYPE_NORESET)
+	{
+		dm_initialize_txpower_tracking(dev);
+
+		if(priv->IC_Cut >= IC_VersionCut_D)
+		{
+			tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
+			tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
+			for(i = 0; i<TxBBGainTableLength; i++)
+			{
+				if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
+				{
+					priv->rfa_txpowertrackingindex= (u8)i;
+					priv->rfa_txpowertrackingindex_real= (u8)i;
+					priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
+					break;
+				}
+			}
+
+		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
+
+		for(i=0 ; i<CCKTxBBGainTableLength ; i++)
+		{
+			if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
+			{
+				priv->CCKPresentAttentuation_20Mdefault =(u8) i;
+				break;
+			}
+		}
+		priv->CCKPresentAttentuation_40Mdefault = 0;
+		priv->CCKPresentAttentuation_difference = 0;
+		priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
+			priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
+		}
+	}
+	#endif
+#endif
+	rtl8192_irq_enable(dev);
+	priv->being_init_adapter = false;
+	return rtStatus;
+
+}
+
+void rtl8192_prepare_beacon(struct r8192_priv *priv)
+{
+	struct sk_buff *skb;
+	//unsigned long flags;
+	cb_desc *tcb_desc;
+
+	skb = ieee80211_get_beacon(priv->ieee80211);
+	tcb_desc = (cb_desc *)(skb->cb + 8);
+        //printk("===========> %s\n", __FUNCTION__);
+	//spin_lock_irqsave(&priv->tx_lock,flags);
+	/* prepare misc info for the beacon xmit */
+	tcb_desc->queue_index = BEACON_QUEUE;
+	/* IBSS does not support HT yet, use 1M defautly */
+	tcb_desc->data_rate = 2;
+	tcb_desc->RATRIndex = 7;
+	tcb_desc->bTxDisableRateFallBack = 1;
+	tcb_desc->bTxUseDriverAssingedRate = 1;
+
+	skb_push(skb, priv->ieee80211->tx_headroom);
+	if(skb){
+		rtl8192_tx(priv->ieee80211->dev,skb);
+	}
+	//spin_unlock_irqrestore (&priv->tx_lock, flags);
+}
+
+
+/* this configures registers for beacon tx and enables it via
+ * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
+ * be used to stop beacon transmission
+ */
+void rtl8192_start_beacon(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct ieee80211_network *net = &priv->ieee80211->current_network;
+	u16 BcnTimeCfg = 0;
+        u16 BcnCW = 6;
+        u16 BcnIFS = 0xf;
+
+	DMESG("Enabling beacon TX");
+	//rtl8192_prepare_beacon(dev);
+	rtl8192_irq_disable(dev);
+	//rtl8192_beacon_tx_enable(dev);
+
+	/* ATIM window */
+	write_nic_word(dev, ATIMWND, 2);
+
+	/* Beacon interval (in unit of TU) */
+	write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
+
+	/*
+	 * DrvErlyInt (in unit of TU).
+	 * (Time to send interrupt to notify driver to c
+	 * hange beacon content)
+	 * */
+	write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
+
+	/*
+	 * BcnDMATIM(in unit of us).
+	 * Indicates the time before TBTT to perform beacon queue DMA
+	 * */
+	write_nic_word(dev, BCN_DMATIME, 256);
+
+	/*
+	 * Force beacon frame transmission even after receiving
+	 * beacon frame from other ad hoc STA
+	 * */
+	write_nic_byte(dev, BCN_ERR_THRESH, 100);
+
+	/* Set CW and IFS */
+	BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
+	BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
+	write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
+
+
+	/* enable the interrupt for ad-hoc process */
+	rtl8192_irq_enable(dev);
+}
+/***************************************************************************
+    -------------------------------NET STUFF---------------------------
+***************************************************************************/
+
+
+
+static bool HalTxCheckStuck8190Pci(struct net_device *dev)
+{
+	u16 				RegTxCounter = read_nic_word(dev, 0x128);
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool				bStuck = FALSE;
+	RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
+	if(priv->TxCounter==RegTxCounter)
+		bStuck = TRUE;
+
+	priv->TxCounter = RegTxCounter;
+
+	return bStuck;
+}
+
+/*
+*	<Assumption: RT_TX_SPINLOCK is acquired.>
+*	First added: 2006.11.19 by emily
+*/
+static RESET_TYPE
+TxCheckStuck(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8			QueueID;
+	ptx_ring		head=NULL,tail=NULL,txring = NULL;
+	u8			ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
+	bool			bCheckFwTxCnt = false;
+	//unsigned long flags;
+
+	//
+	// Decide Stuch threshold according to current power save mode
+	//
+	//printk("++++++++++++>%s()\n",__FUNCTION__);
+	switch (priv->ieee80211->dot11PowerSaveMode)
+	{
+		// The threshold value  may required to be adjusted .
+		case eActive:		// Active/Continuous access.
+			ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
+			break;
+		case eMaxPs:		// Max power save mode.
+			ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
+			break;
+		case eFastPs:	// Fast power save mode.
+			ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
+			break;
+	}
+
+	//
+	// Check whether specific tcb has been queued for a specific time
+	//
+	for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
+	{
+
+
+		if(QueueID == TXCMD_QUEUE)
+			continue;
+
+		switch(QueueID) {
+		case MGNT_QUEUE:
+			tail=priv->txmapringtail;
+			head=priv->txmapringhead;
+			break;
+
+		case BK_QUEUE:
+			tail=priv->txbkpringtail;
+			head=priv->txbkpringhead;
+			break;
+
+		case BE_QUEUE:
+			tail=priv->txbepringtail;
+			head=priv->txbepringhead;
+			break;
+
+		case VI_QUEUE:
+			tail=priv->txvipringtail;
+			head=priv->txvipringhead;
+			break;
+
+		case VO_QUEUE:
+			tail=priv->txvopringtail;
+			head=priv->txvopringhead;
+			break;
+
+		default:
+			tail=head=NULL;
+			break;
+		}
+
+		if(tail == head)
+			continue;
+		else
+		{
+			txring = head;
+			if(txring == NULL)
+			{
+				RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
+				continue;
+			}
+			txring->nStuckCount++;
+			bCheckFwTxCnt = TRUE;
+		}
+	}
+#if 1
+	if(bCheckFwTxCnt)
+	{
+		if(HalTxCheckStuck8190Pci(dev))
+		{
+			RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
+			return RESET_TYPE_SILENT;
+		}
+	}
+#endif
+	return RESET_TYPE_NORESET;
+}
+
+
+static bool HalRxCheckStuck8190Pci(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u16 				RegRxCounter = read_nic_word(dev, 0x130);
+	bool				bStuck = FALSE;
+	static u8			rx_chk_cnt = 0;
+	RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
+	// If rssi is small, we should check rx for long time because of bad rx.
+	// or maybe it will continuous silent reset every 2 seconds.
+	rx_chk_cnt++;
+	if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
+	{
+		rx_chk_cnt = 0;	//high rssi, check rx stuck right now.
+	}
+	else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
+		((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
+		(priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
+
+	{
+		if(rx_chk_cnt < 2)
+		{
+			return bStuck;
+		}
+		else
+		{
+			rx_chk_cnt = 0;
+		}
+	}
+	else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
+		(priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
+		priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
+	{
+		if(rx_chk_cnt < 4)
+		{
+			//DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
+			return bStuck;
+		}
+		else
+		{
+			rx_chk_cnt = 0;
+			//DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
+		}
+	}
+	else
+	{
+		if(rx_chk_cnt < 8)
+		{
+			//DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
+			return bStuck;
+		}
+		else
+		{
+			rx_chk_cnt = 0;
+			//DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
+		}
+	}
+	if(priv->RxCounter==RegRxCounter)
+		bStuck = TRUE;
+
+	priv->RxCounter = RegRxCounter;
+
+	return bStuck;
+}
+
+static RESET_TYPE RxCheckStuck(struct net_device *dev)
+{
+
+	if(HalRxCheckStuck8190Pci(dev))
+	{
+		RT_TRACE(COMP_RESET, "RxStuck Condition\n");
+		return RESET_TYPE_SILENT;
+	}
+
+	return RESET_TYPE_NORESET;
+}
+
+static RESET_TYPE
+rtl819x_ifcheck_resetornot(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RESET_TYPE	TxResetType = RESET_TYPE_NORESET;
+	RESET_TYPE	RxResetType = RESET_TYPE_NORESET;
+	RT_RF_POWER_STATE 	rfState;
+
+	rfState = priv->ieee80211->eRFPowerState;
+
+	TxResetType = TxCheckStuck(dev);
+#if 1
+	if( rfState != eRfOff &&
+		/*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
+		(priv->ieee80211->iw_mode != IW_MODE_ADHOC))
+	{
+		// If driver is in the status of firmware download failure , driver skips RF initialization and RF is
+		// in turned off state. Driver should check whether Rx stuck and do silent reset. And
+		// if driver is in firmware download failure status, driver should initialize RF in the following
+		// silent reset procedure Emily, 2008.01.21
+
+		// Driver should not check RX stuck in IBSS mode because it is required to
+		// set Check BSSID in order to send beacon, however, if check BSSID is
+		// set, STA cannot hear any packet a all. Emily, 2008.04.12
+		RxResetType = RxCheckStuck(dev);
+	}
+#endif
+
+	RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
+	if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
+		return RESET_TYPE_NORMAL;
+	else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
+		return RESET_TYPE_SILENT;
+	else
+		return RESET_TYPE_NORESET;
+
+}
+
+
+static void CamRestoreAllEntry(struct net_device *dev)
+{
+	u8 EntryId = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8*	MacAddr = priv->ieee80211->current_network.bssid;
+
+	static u8	CAM_CONST_ADDR[4][6] = {
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
+	static u8	CAM_CONST_BROAD[] =
+		{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+	RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
+
+
+	if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
+	    (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
+	{
+
+		for(EntryId=0; EntryId<4; EntryId++)
+		{
+			{
+				MacAddr = CAM_CONST_ADDR[EntryId];
+				setKey(dev,
+						EntryId ,
+						EntryId,
+						priv->ieee80211->pairwise_key_type,
+						MacAddr,
+						0,
+						NULL);
+			}
+		}
+
+	}
+	else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
+	{
+
+		{
+			if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						(u8*)dev->dev_addr,
+						0,
+						NULL);
+			else
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						MacAddr,
+						0,
+						NULL);
+		}
+	}
+	else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
+	{
+
+		{
+			if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						(u8*)dev->dev_addr,
+						0,
+						NULL);
+			else
+				setKey(dev,
+						4,
+						0,
+						priv->ieee80211->pairwise_key_type,
+						MacAddr,
+						0,
+						NULL);
+		}
+	}
+
+
+
+	if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
+	{
+		MacAddr = CAM_CONST_BROAD;
+		for(EntryId=1 ; EntryId<4 ; EntryId++)
+		{
+			{
+				setKey(dev,
+						EntryId,
+						EntryId,
+						priv->ieee80211->group_key_type,
+						MacAddr,
+						0,
+						NULL);
+			}
+		}
+		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						0,
+						0,
+						priv->ieee80211->group_key_type,
+						CAM_CONST_ADDR[0],
+						0,
+						NULL);
+	}
+	else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
+	{
+		MacAddr = CAM_CONST_BROAD;
+		for(EntryId=1; EntryId<4 ; EntryId++)
+		{
+			{
+				setKey(dev,
+						EntryId ,
+						EntryId,
+						priv->ieee80211->group_key_type,
+						MacAddr,
+						0,
+						NULL);
+			}
+		}
+
+		if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+				setKey(dev,
+						0 ,
+						0,
+						priv->ieee80211->group_key_type,
+						CAM_CONST_ADDR[0],
+						0,
+						NULL);
+	}
+}
+
+void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
+int _rtl8192_up(struct net_device *dev);
+
+/*
+ * This function is used to fix Tx/Rx stop bug temporarily.
+ * This function will do "system reset" to NIC when Tx or Rx is stuck.
+ * The method checking Tx/Rx stuck of this function is supported by FW,
+ * which reports Tx and Rx counter to register 0x128 and 0x130.
+ * */
+static void rtl819x_ifsilentreset(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8	reset_times = 0;
+	int reset_status = 0;
+	struct ieee80211_device *ieee = priv->ieee80211;
+
+
+	// 2007.07.20. If we need to check CCK stop, please uncomment this line.
+	//bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
+
+	if(priv->ResetProgress==RESET_TYPE_NORESET)
+	{
+RESET_START:
+
+		RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
+
+		// Set the variable for reset.
+		priv->ResetProgress = RESET_TYPE_SILENT;
+//		rtl8192_close(dev);
+#if 1
+		down(&priv->wx_sem);
+		if(priv->up == 0)
+		{
+			RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
+			up(&priv->wx_sem);
+			return ;
+		}
+		priv->up = 0;
+		RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
+		if(!netif_queue_stopped(dev))
+			netif_stop_queue(dev);
+
+		dm_backup_dynamic_mechanism_state(dev);
+
+		rtl8192_irq_disable(dev);
+		rtl8192_cancel_deferred_work(priv);
+		deinit_hal_dm(dev);
+		del_timer_sync(&priv->watch_dog_timer);
+		ieee->sync_scan_hurryup = 1;
+		if(ieee->state == IEEE80211_LINKED)
+		{
+			down(&ieee->wx_sem);
+			printk("ieee->state is IEEE80211_LINKED\n");
+			ieee80211_stop_send_beacons(priv->ieee80211);
+			del_timer_sync(&ieee->associate_timer);
+                        cancel_delayed_work(&ieee->associate_retry_wq);
+			ieee80211_stop_scan(ieee);
+			netif_carrier_off(dev);
+			up(&ieee->wx_sem);
+		}
+		else{
+			printk("ieee->state is NOT LINKED\n");
+			ieee80211_softmac_stop_protocol(priv->ieee80211);
+		}
+		rtl8192_rtx_disable(dev);
+		up(&priv->wx_sem);
+		RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
+		RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
+		reset_status = _rtl8192_up(dev);
+
+		RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
+		if(reset_status == -1)
+		{
+			if(reset_times < 3)
+			{
+				reset_times++;
+				goto RESET_START;
+			}
+			else
+			{
+				RT_TRACE(COMP_ERR," ERR!!! %s():  Reset Failed!!\n",__FUNCTION__);
+			}
+		}
+#endif
+		ieee->is_silent_reset = 1;
+#if 1
+		EnableHWSecurityConfig8192(dev);
+#if 1
+		if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
+		{
+			ieee->set_chan(ieee->dev, ieee->current_network.channel);
+
+#if 1
+			queue_work(ieee->wq, &ieee->associate_complete_wq);
+#endif
+
+		}
+		else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
+		{
+			ieee->set_chan(ieee->dev, ieee->current_network.channel);
+			ieee->link_change(ieee->dev);
+
+		//	notify_wx_assoc_event(ieee);
+
+			ieee80211_start_send_beacons(ieee);
+
+			if (ieee->data_hard_resume)
+				ieee->data_hard_resume(ieee->dev);
+			netif_carrier_on(ieee->dev);
+		}
+#endif
+
+		CamRestoreAllEntry(dev);
+
+		// Restore the previous setting for all dynamic mechanism
+		dm_restore_dynamic_mechanism_state(dev);
+
+		priv->ResetProgress = RESET_TYPE_NORESET;
+		priv->reset_count++;
+
+		priv->bForcedSilentReset =false;
+		priv->bResetInProgress = false;
+
+		// For test --> force write UFWP.
+		write_nic_byte(dev, UFWP, 1);
+		RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
+#endif
+	}
+}
+
+#ifdef ENABLE_IPS
+void InactivePsWorkItemCallback(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_POWER_SAVE_CONTROL	pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+	//u8							index = 0;
+
+	RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
+	//
+	// This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
+	// is really scheduled.
+	// The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
+	// previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
+	// blocks the IPS procedure of switching RF.
+	// By Bruce, 2007-12-25.
+	//
+	pPSC->bSwRfProcessing = TRUE;
+
+	RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
+			pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
+
+
+	MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
+
+	//
+	// To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
+	//
+	pPSC->bSwRfProcessing = FALSE;
+	RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
+}
+
+//
+//	Description:
+//		Enter the inactive power save mode. RF will be off
+//	2007.08.17, by shien chang.
+//
+void
+IPSEnter(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_POWER_SAVE_CONTROL		pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+	RT_RF_POWER_STATE 			rtState;
+
+	if (pPSC->bInactivePs)
+	{
+		rtState = priv->ieee80211->eRFPowerState;
+		//
+		// Added by Bruce, 2007-12-25.
+		// Do not enter IPS in the following conditions:
+		// (1) RF is already OFF or Sleep
+		// (2) bSwRfProcessing (indicates the IPS is still under going)
+		// (3) Connectted (only disconnected can trigger IPS)
+		// (4) IBSS (send Beacon)
+		// (5) AP mode (send Beacon)
+		//
+		if (rtState == eRfOn && !pPSC->bSwRfProcessing
+			&& (priv->ieee80211->state != IEEE80211_LINKED) )
+		{
+			RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
+			pPSC->eInactivePowerState = eRfOff;
+//			queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
+			InactivePsWorkItemCallback(dev);
+		}
+	}
+}
+
+//
+//	Description:
+//		Leave the inactive power save mode, RF will be on.
+//	2007.08.17, by shien chang.
+//
+void
+IPSLeave(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_POWER_SAVE_CONTROL	pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
+	RT_RF_POWER_STATE 	rtState;
+
+	if (pPSC->bInactivePs)
+	{
+		rtState = priv->ieee80211->eRFPowerState;
+		if (rtState != eRfOn  && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
+		{
+			RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
+			pPSC->eInactivePowerState = eRfOn;
+//			queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
+			InactivePsWorkItemCallback(dev);
+		}
+	}
+}
+#endif
+
+static void rtl819x_update_rxcounts(
+	struct r8192_priv *priv,
+	u32* TotalRxBcnNum,
+	u32* TotalRxDataNum
+)
+{
+	u16 			SlotIndex;
+	u8			i;
+
+	*TotalRxBcnNum = 0;
+	*TotalRxDataNum = 0;
+
+	SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
+	priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
+	priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
+	for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
+		*TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
+		*TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
+	}
+}
+
+
+void rtl819x_watchdog_wqcallback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
+       struct net_device *dev = priv->ieee80211->dev;
+	struct ieee80211_device* ieee = priv->ieee80211;
+	RESET_TYPE	ResetType = RESET_TYPE_NORESET;
+      	static u8	check_reset_cnt=0;
+	unsigned long flags;
+	bool bBusyTraffic = false;
+	static u8 last_time = 0;
+	if(!priv->up)
+		return;
+	hal_dm_watchdog(dev);
+#ifdef ENABLE_IPS
+//	printk("watch_dog ENABLE_IPS\n");
+	if(ieee->actscanning == false){
+		if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
+			if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
+				printk("====================>haha:IPSEnter()\n");
+				IPSEnter(dev);
+				//ieee80211_stop_scan(priv->ieee80211);
+			}
+		}
+	}
+#endif
+	{//to get busy traffic condition
+		if(ieee->state == IEEE80211_LINKED)
+		{
+			if(	ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
+				ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
+				bBusyTraffic = true;
+			}
+
+		}
+	        ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
+	        ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
+		ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
+	}
+
+
+	//added by amy for AP roaming
+	if (1)
+	{
+		if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
+		{
+			u32	TotalRxBcnNum = 0;
+			u32	TotalRxDataNum = 0;
+
+			rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
+			if((TotalRxBcnNum+TotalRxDataNum) == 0)
+			{
+				if( ieee->eRFPowerState == eRfOff)
+					RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
+				printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
+		//		Dot11d_Reset(dev);
+				ieee->state = IEEE80211_ASSOCIATING;
+				notify_wx_assoc_event(priv->ieee80211);
+                                RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
+				ieee->is_roaming = true;
+				ieee->is_set_key = false;
+                             ieee->link_change(dev);
+                                queue_work(ieee->wq, &ieee->associate_procedure_wq);
+			}
+		}
+	      ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
+              ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
+
+	}
+	//check if reset the driver
+	spin_lock_irqsave(&priv->tx_lock,flags);
+	if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
+	{
+    		ResetType = rtl819x_ifcheck_resetornot(dev);
+		check_reset_cnt = 3;
+		//DbgPrint("Start to check silent reset\n");
+	}
+	spin_unlock_irqrestore(&priv->tx_lock,flags);
+	if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
+	{
+		priv->ResetProgress = RESET_TYPE_NORMAL;
+		RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
+		return;
+	}
+	/* disable silent reset temply 2008.9.11*/
+#if 1
+	if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
+	{
+		last_time = 1;
+		rtl819x_ifsilentreset(dev);
+	}
+	else
+		last_time = 0;
+#endif
+	priv->force_reset = false;
+	priv->bForcedSilentReset = false;
+	priv->bResetInProgress = false;
+	RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
+
+}
+
+void watch_dog_timer_callback(unsigned long data)
+{
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
+	queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
+	mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
+
+}
+int _rtl8192_up(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//int i;
+	RT_STATUS init_status = RT_STATUS_SUCCESS;
+	priv->up=1;
+	priv->ieee80211->ieee_up=1;
+	RT_TRACE(COMP_INIT, "Bringing up iface");
+
+	init_status = rtl8192_adapter_start(dev);
+	if(init_status != RT_STATUS_SUCCESS)
+	{
+		RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
+		return -1;
+	}
+	RT_TRACE(COMP_INIT, "start adapter finished\n");
+#ifdef RTL8192E
+	if(priv->ieee80211->eRFPowerState!=eRfOn)
+		MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
+#endif
+	if(priv->ieee80211->state != IEEE80211_LINKED)
+	ieee80211_softmac_start_protocol(priv->ieee80211);
+	ieee80211_reset_queue(priv->ieee80211);
+	watch_dog_timer_callback((unsigned long) dev);
+	if(!netif_queue_stopped(dev))
+		netif_start_queue(dev);
+	else
+		netif_wake_queue(dev);
+
+	return 0;
+}
+
+
+static int rtl8192_open(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+
+	down(&priv->wx_sem);
+	ret = rtl8192_up(dev);
+	up(&priv->wx_sem);
+	return ret;
+
+}
+
+
+int rtl8192_up(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if (priv->up == 1) return -1;
+
+	return _rtl8192_up(dev);
+}
+
+
+static int rtl8192_close(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+
+	down(&priv->wx_sem);
+
+	ret = rtl8192_down(dev);
+
+	up(&priv->wx_sem);
+
+	return ret;
+
+}
+
+int rtl8192_down(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+//	int i;
+#if 0
+	u8	ucRegRead;
+	u32	ulRegRead;
+#endif
+	if (priv->up == 0) return -1;
+
+	priv->up=0;
+	priv->ieee80211->ieee_up = 0;
+	RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
+/* FIXME */
+	if (!netif_queue_stopped(dev))
+		netif_stop_queue(dev);
+
+	rtl8192_irq_disable(dev);
+#if 0
+	if(!priv->ieee80211->bSupportRemoteWakeUp) {
+		MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
+		// 2006.11.30. System reset bit
+		ulRegRead = read_nic_dword(dev, CPU_GEN);
+		ulRegRead|=CPU_GEN_SYSTEM_RESET;
+		write_nic_dword(dev, CPU_GEN, ulRegRead);
+	} else {
+		//2008.06.03 for WOL
+		write_nic_dword(dev, WFCRC0, 0xffffffff);
+		write_nic_dword(dev, WFCRC1, 0xffffffff);
+		write_nic_dword(dev, WFCRC2, 0xffffffff);
+#ifdef RTL8190P
+		//GPIO 0 = TRUE
+		ucRegRead = read_nic_byte(dev, GPO);
+		ucRegRead |= BIT0;
+		write_nic_byte(dev, GPO, ucRegRead);
+#endif
+		//Write PMR register
+		write_nic_byte(dev, PMR, 0x5);
+		//Disable tx, enanble rx
+		write_nic_byte(dev, MacBlkCtrl, 0xa);
+	}
+#endif
+//	flush_scheduled_work();
+	rtl8192_cancel_deferred_work(priv);
+	deinit_hal_dm(dev);
+	del_timer_sync(&priv->watch_dog_timer);
+
+	ieee80211_softmac_stop_protocol(priv->ieee80211);
+#ifdef ENABLE_IPS
+	MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
+#endif
+	rtl8192_rtx_disable(dev);
+	memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
+
+	RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
+
+		return 0;
+}
+
+
+void rtl8192_commit(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if (priv->up == 0) return ;
+
+
+	ieee80211_softmac_stop_protocol(priv->ieee80211);
+
+	rtl8192_irq_disable(dev);
+	rtl8192_rtx_disable(dev);
+	_rtl8192_up(dev);
+}
+
+void rtl8192_restart(struct work_struct *work)
+{
+        struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
+        struct net_device *dev = priv->ieee80211->dev;
+
+	down(&priv->wx_sem);
+
+	rtl8192_commit(dev);
+
+	up(&priv->wx_sem);
+}
+
+static void r8192_set_multicast(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	short promisc;
+
+	//down(&priv->wx_sem);
+
+	/* FIXME FIXME */
+
+	promisc = (dev->flags & IFF_PROMISC) ? 1:0;
+
+	if (promisc != priv->promisc) {
+		;
+	//	rtl8192_commit(dev);
+	}
+
+	priv->promisc = promisc;
+
+	//schedule_work(&priv->reset_wq);
+	//up(&priv->wx_sem);
+}
+
+
+static int r8192_set_mac_adr(struct net_device *dev, void *mac)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct sockaddr *addr = mac;
+
+	down(&priv->wx_sem);
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+
+	schedule_work(&priv->reset_wq);
+	up(&priv->wx_sem);
+
+	return 0;
+}
+
+/* based on ipw2200 driver */
+static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct iwreq *wrq = (struct iwreq *)rq;
+	int ret=-1;
+	struct ieee80211_device *ieee = priv->ieee80211;
+	u32 key[4];
+	u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+	struct iw_point *p = &wrq->u.data;
+	struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
+
+	down(&priv->wx_sem);
+
+
+     if (p->length < sizeof(struct ieee_param) || !p->pointer){
+             ret = -EINVAL;
+             goto out;
+     }
+
+     ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
+     if (ipw == NULL){
+             ret = -ENOMEM;
+             goto out;
+     }
+     if (copy_from_user(ipw, p->pointer, p->length)) {
+            kfree(ipw);
+            ret = -EFAULT;
+            goto out;
+     }
+
+	switch (cmd) {
+	    case RTL_IOCTL_WPA_SUPPLICANT:
+		//parse here for HW security
+			if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
+			{
+				if (ipw->u.crypt.set_tx)
+				{
+					if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
+						ieee->pairwise_key_type = KEY_TYPE_CCMP;
+					else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
+						ieee->pairwise_key_type = KEY_TYPE_TKIP;
+					else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
+					{
+						if (ipw->u.crypt.key_len == 13)
+							ieee->pairwise_key_type = KEY_TYPE_WEP104;
+						else if (ipw->u.crypt.key_len == 5)
+							ieee->pairwise_key_type = KEY_TYPE_WEP40;
+					}
+					else
+						ieee->pairwise_key_type = KEY_TYPE_NA;
+
+					if (ieee->pairwise_key_type)
+					{
+						memcpy((u8*)key, ipw->u.crypt.key, 16);
+						EnableHWSecurityConfig8192(dev);
+					//we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching!
+					//added by WB.
+						setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
+						if (ieee->auth_mode != 2)  //LEAP WEP will never set this.
+						setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
+					}
+					if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
+							write_nic_byte(dev, 0x173, 1); //fix aes bug
+						}
+
+				}
+				else //if (ipw->u.crypt.idx) //group key use idx > 0
+				{
+					memcpy((u8*)key, ipw->u.crypt.key, 16);
+					if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
+						ieee->group_key_type= KEY_TYPE_CCMP;
+					else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
+						ieee->group_key_type = KEY_TYPE_TKIP;
+					else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
+					{
+						if (ipw->u.crypt.key_len == 13)
+							ieee->group_key_type = KEY_TYPE_WEP104;
+						else if (ipw->u.crypt.key_len == 5)
+							ieee->group_key_type = KEY_TYPE_WEP40;
+					}
+					else
+						ieee->group_key_type = KEY_TYPE_NA;
+
+					if (ieee->group_key_type)
+					{
+							setKey(	dev,
+								ipw->u.crypt.idx,
+								ipw->u.crypt.idx,		//KeyIndex
+						     		ieee->group_key_type,	//KeyType
+						            	broadcast_addr,	//MacAddr
+								0,		//DefaultKey
+							      	key);		//KeyContent
+					}
+				}
+			}
+#ifdef JOHN_DEBUG
+		//john's test 0711
+	{
+		int i;
+		printk("@@ wrq->u pointer = ");
+		for(i=0;i<wrq->u.data.length;i++){
+			if(i%10==0) printk("\n");
+			printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
+		}
+		printk("\n");
+	}
+#endif /*JOHN_DEBUG*/
+		ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
+		break;
+
+	    default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	kfree(ipw);
+out:
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+static u8 HwRateToMRate90(bool bIsHT, u8 rate)
+{
+	u8  ret_rate = 0x02;
+
+	if(!bIsHT) {
+		switch(rate) {
+			case DESC90_RATE1M:   ret_rate = MGN_1M;         break;
+			case DESC90_RATE2M:   ret_rate = MGN_2M;         break;
+			case DESC90_RATE5_5M: ret_rate = MGN_5_5M;       break;
+			case DESC90_RATE11M:  ret_rate = MGN_11M;        break;
+			case DESC90_RATE6M:   ret_rate = MGN_6M;         break;
+			case DESC90_RATE9M:   ret_rate = MGN_9M;         break;
+			case DESC90_RATE12M:  ret_rate = MGN_12M;        break;
+			case DESC90_RATE18M:  ret_rate = MGN_18M;        break;
+			case DESC90_RATE24M:  ret_rate = MGN_24M;        break;
+			case DESC90_RATE36M:  ret_rate = MGN_36M;        break;
+			case DESC90_RATE48M:  ret_rate = MGN_48M;        break;
+			case DESC90_RATE54M:  ret_rate = MGN_54M;        break;
+
+			default:
+					      RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
+					      break;
+		}
+
+	} else {
+		switch(rate) {
+			case DESC90_RATEMCS0:   ret_rate = MGN_MCS0;    break;
+			case DESC90_RATEMCS1:   ret_rate = MGN_MCS1;    break;
+			case DESC90_RATEMCS2:   ret_rate = MGN_MCS2;    break;
+			case DESC90_RATEMCS3:   ret_rate = MGN_MCS3;    break;
+			case DESC90_RATEMCS4:   ret_rate = MGN_MCS4;    break;
+			case DESC90_RATEMCS5:   ret_rate = MGN_MCS5;    break;
+			case DESC90_RATEMCS6:   ret_rate = MGN_MCS6;    break;
+			case DESC90_RATEMCS7:   ret_rate = MGN_MCS7;    break;
+			case DESC90_RATEMCS8:   ret_rate = MGN_MCS8;    break;
+			case DESC90_RATEMCS9:   ret_rate = MGN_MCS9;    break;
+			case DESC90_RATEMCS10:  ret_rate = MGN_MCS10;   break;
+			case DESC90_RATEMCS11:  ret_rate = MGN_MCS11;   break;
+			case DESC90_RATEMCS12:  ret_rate = MGN_MCS12;   break;
+			case DESC90_RATEMCS13:  ret_rate = MGN_MCS13;   break;
+			case DESC90_RATEMCS14:  ret_rate = MGN_MCS14;   break;
+			case DESC90_RATEMCS15:  ret_rate = MGN_MCS15;   break;
+			case DESC90_RATEMCS32:  ret_rate = (0x80|0x20); break;
+
+			default:
+						RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
+						break;
+		}
+	}
+
+	return ret_rate;
+}
+
+/**
+ * Function:     UpdateRxPktTimeStamp
+ * Overview:     Recored down the TSF time stamp when receiving a packet
+ *
+ * Input:
+ *       PADAPTER        Adapter
+ *       PRT_RFD         pRfd,
+ *
+ * Output:
+ *       PRT_RFD         pRfd
+ *                               (pRfd->Status.TimeStampHigh is updated)
+ *                               (pRfd->Status.TimeStampLow is updated)
+ * Return:
+ *               None
+ */
+static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	if(stats->bIsAMPDU && !stats->bFirstMPDU) {
+		stats->mac_time[0] = priv->LastRxDescTSFLow;
+		stats->mac_time[1] = priv->LastRxDescTSFHigh;
+	} else {
+		priv->LastRxDescTSFLow = stats->mac_time[0];
+		priv->LastRxDescTSFHigh = stats->mac_time[1];
+	}
+}
+
+static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
+{
+	long	signal_power; // in dBm.
+
+	// Translate to dBm (x=0.5y-95).
+	signal_power = (long)((signal_strength_index + 1) >> 1);
+	signal_power -= 95;
+
+	return signal_power;
+}
+
+//
+//	Description:
+//		Update Rx signal related information in the packet reeived
+//		to RxStats. User application can query RxStats to realize
+//		current Rx signal status.
+//
+//	Assumption:
+//		In normal operation, user only care about the information of the BSS
+//		and we shall invoke this function if the packet received is from the BSS.
+//
+static void
+rtl819x_update_rxsignalstatistics8190pci(
+	struct r8192_priv * priv,
+	struct ieee80211_rx_stats * pprevious_stats
+	)
+{
+	int weighting = 0;
+
+	//2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
+
+	// Initila state
+	if(priv->stats.recv_signal_power == 0)
+		priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
+
+	// To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
+	// reaction of smoothed Signal Power.
+	if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
+		weighting = 5;
+	else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
+		weighting = (-5);
+	//
+	// We need more correct power of received packets and the  "SignalStrength" of RxStats have been beautified or translated,
+	// so we record the correct power in Dbm here. By Bruce, 2008-03-07.
+	//
+	priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
+}
+
+static void
+rtl8190_process_cck_rxpathsel(
+	struct r8192_priv * priv,
+	struct ieee80211_rx_stats * pprevious_stats
+	)
+{
+#ifdef RTL8190P	//Only 90P 2T4R need to check
+	char				last_cck_adc_pwdb[4]={0,0,0,0};
+	u8				i;
+//cosa add for Rx path selection
+		if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
+		{
+			if(pprevious_stats->bIsCCK &&
+				(pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
+			{
+				/* record the cck adc_pwdb to the sliding window. */
+				if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
+				{
+					priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
+					for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
+					{
+						last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
+						priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
+					}
+				}
+				for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
+				{
+					priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
+					priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
+				}
+				priv->stats.cck_adc_pwdb.index++;
+				if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
+					priv->stats.cck_adc_pwdb.index = 0;
+
+				for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
+				{
+					DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
+				}
+
+				for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
+				{
+					if(pprevious_stats->cck_adc_pwdb[i]  > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
+					{
+						priv->undecorated_smoothed_cck_adc_pwdb[i] =
+							( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
+							(pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
+						priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
+					}
+					else
+					{
+						priv->undecorated_smoothed_cck_adc_pwdb[i] =
+							( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
+							(pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
+					}
+				}
+			}
+		}
+#endif
+}
+
+
+/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
+	be a local static. Otherwise, it may increase when we return from S3/S4. The
+	value will be kept in memory or disk. We must delcare the value in adapter
+	and it will be reinitialized when return from S3/S4. */
+static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
+{
+	bool bcheck = false;
+	u8	rfpath;
+	u32 nspatial_stream, tmp_val;
+	//u8	i;
+	static u32 slide_rssi_index=0, slide_rssi_statistics=0;
+	static u32 slide_evm_index=0, slide_evm_statistics=0;
+	static u32 last_rssi=0, last_evm=0;
+	//cosa add for rx path selection
+//	static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
+//	static char last_cck_adc_pwdb[4]={0,0,0,0};
+	//cosa add for beacon rssi smoothing
+	static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
+	static u32 last_beacon_adc_pwdb=0;
+
+	struct ieee80211_hdr_3addr *hdr;
+	u16 sc ;
+	unsigned int frag,seq;
+	hdr = (struct ieee80211_hdr_3addr *)buffer;
+	sc = le16_to_cpu(hdr->seq_ctl);
+	frag = WLAN_GET_SEQ_FRAG(sc);
+	seq = WLAN_GET_SEQ_SEQ(sc);
+	//cosa add 04292008 to record the sequence number
+	pcurrent_stats->Seq_Num = seq;
+	//
+	// Check whether we should take the previous packet into accounting
+	//
+	if(!pprevious_stats->bIsAMPDU)
+	{
+		// if previous packet is not aggregated packet
+		bcheck = true;
+	}else
+	{
+//remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
+#if 0
+		// if previous packet is aggregated packet, and current packet
+		//	(1) is not AMPDU
+		//	(2) is the first packet of one AMPDU
+		// that means the previous packet is the last one aggregated packet
+		if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
+			bcheck = true;
+#endif
+	}
+
+	if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
+	{
+		slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
+		last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
+		priv->stats.slide_rssi_total -= last_rssi;
+	}
+	priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
+
+	priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
+	if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
+		slide_rssi_index = 0;
+
+	// <1> Showed on UI for user, in dbm
+	tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
+	priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
+	pcurrent_stats->rssi = priv->stats.signal_strength;
+	//
+	// If the previous packet does not match the criteria, neglect it
+	//
+	if(!pprevious_stats->bPacketMatchBSSID)
+	{
+		if(!pprevious_stats->bToSelfBA)
+			return;
+	}
+
+	if(!bcheck)
+		return;
+
+	rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
+
+	//
+	// Check RSSI
+	//
+	priv->stats.num_process_phyinfo++;
+#if 0
+	/* record the general signal strength to the sliding window. */
+	if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
+	{
+		slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
+		last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
+		priv->stats.slide_rssi_total -= last_rssi;
+	}
+	priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
+
+	priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
+	if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
+		slide_rssi_index = 0;
+
+	// <1> Showed on UI for user, in dbm
+	tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
+	priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
+
+#endif
+	// <2> Showed on UI for engineering
+	// hardware does not provide rssi information for each rf path in CCK
+	if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
+	{
+		for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
+		{
+			if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
+				continue;
+			RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath]  = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
+			//Fixed by Jacken 2008-03-20
+			if(priv->stats.rx_rssi_percentage[rfpath] == 0)
+			{
+				priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
+				//DbgPrint("MIMO RSSI initialize \n");
+			}
+			if(pprevious_stats->RxMIMOSignalStrength[rfpath]  > priv->stats.rx_rssi_percentage[rfpath])
+			{
+				priv->stats.rx_rssi_percentage[rfpath] =
+					( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
+				priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath]  + 1;
+			}
+			else
+			{
+				priv->stats.rx_rssi_percentage[rfpath] =
+					( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
+			}
+			RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath]  = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
+		}
+	}
+
+
+	//
+	// Check PWDB.
+	//
+	//cosa add for beacon rssi smoothing by average.
+	if(pprevious_stats->bPacketBeacon)
+	{
+		/* record the beacon pwdb to the sliding window. */
+		if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
+		{
+			slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
+			last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
+			priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
+			//DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
+			//	slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
+		}
+		priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
+		priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
+		//DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
+		slide_beacon_adc_pwdb_index++;
+		if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
+			slide_beacon_adc_pwdb_index = 0;
+		pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
+		if(pprevious_stats->RxPWDBAll >= 3)
+			pprevious_stats->RxPWDBAll -= 3;
+	}
+
+	RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
+				pprevious_stats->bIsCCK? "CCK": "OFDM",
+				pprevious_stats->RxPWDBAll);
+
+	if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
+	{
+		if(priv->undecorated_smoothed_pwdb < 0)	// initialize
+		{
+			priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
+			//DbgPrint("First pwdb initialize \n");
+		}
+#if 1
+		if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
+		{
+			priv->undecorated_smoothed_pwdb =
+					( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
+			priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
+		}
+		else
+		{
+			priv->undecorated_smoothed_pwdb =
+					( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
+					(pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
+		}
+#else
+		//Fixed by Jacken 2008-03-20
+		if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
+		{
+			pHalData->UndecoratedSmoothedPWDB =
+					( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
+			pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
+		}
+		else
+		{
+			pHalData->UndecoratedSmoothedPWDB =
+					( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
+		}
+#endif
+		rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
+	}
+
+	//
+	// Check EVM
+	//
+	/* record the general EVM to the sliding window. */
+	if(pprevious_stats->SignalQuality == 0)
+	{
+	}
+	else
+	{
+		if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
+			if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
+				slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
+				last_evm = priv->stats.slide_evm[slide_evm_index];
+				priv->stats.slide_evm_total -= last_evm;
+			}
+
+			priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
+
+			priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
+			if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
+				slide_evm_index = 0;
+
+			// <1> Showed on UI for user, in percentage.
+			tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
+			priv->stats.signal_quality = tmp_val;
+			//cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
+			priv->stats.last_signal_strength_inpercent = tmp_val;
+		}
+
+		// <2> Showed on UI for engineering
+		if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
+		{
+			for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
+			{
+				if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
+				{
+					if(priv->stats.rx_evm_percentage[nspatial_stream] == 0)	// initialize
+					{
+						priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
+					}
+					priv->stats.rx_evm_percentage[nspatial_stream] =
+						( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
+						(pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
+				}
+			}
+		}
+	}
+
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:	rtl819x_query_rxpwrpercentage()
+ *
+ * Overview:
+ *
+ * Input:		char		antpower
+ *
+ * Output:		NONE
+ *
+ * Return:		0-100 percentage
+ *
+ * Revised History:
+ *	When		Who 	Remark
+ *	05/26/2008	amy 	Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static u8 rtl819x_query_rxpwrpercentage(
+	char		antpower
+	)
+{
+	if ((antpower <= -100) || (antpower >= 20))
+	{
+		return	0;
+	}
+	else if (antpower >= 0)
+	{
+		return	100;
+	}
+	else
+	{
+		return	(100+antpower);
+	}
+
+}	/* QueryRxPwrPercentage */
+
+static u8
+rtl819x_evm_dbtopercentage(
+	char value
+	)
+{
+	char ret_val;
+
+	ret_val = value;
+
+	if(ret_val >= 0)
+		ret_val = 0;
+	if(ret_val <= -33)
+		ret_val = -33;
+	ret_val = 0 - ret_val;
+	ret_val*=3;
+	if(ret_val == 99)
+		ret_val = 100;
+	return(ret_val);
+}
+
+//
+//	Description:
+//	We want good-looking for signal strength/quality
+//	2007/7/19 01:09, by cosa.
+//
+static long rtl819x_signal_scale_mapping(long currsig)
+{
+	long retsig;
+
+	// Step 1. Scale mapping.
+	if(currsig >= 61 && currsig <= 100)
+	{
+		retsig = 90 + ((currsig - 60) / 4);
+	}
+	else if(currsig >= 41 && currsig <= 60)
+	{
+		retsig = 78 + ((currsig - 40) / 2);
+	}
+	else if(currsig >= 31 && currsig <= 40)
+	{
+		retsig = 66 + (currsig - 30);
+	}
+	else if(currsig >= 21 && currsig <= 30)
+	{
+		retsig = 54 + (currsig - 20);
+	}
+	else if(currsig >= 5 && currsig <= 20)
+	{
+		retsig = 42 + (((currsig - 5) * 2) / 3);
+	}
+	else if(currsig == 4)
+	{
+		retsig = 36;
+	}
+	else if(currsig == 3)
+	{
+		retsig = 27;
+	}
+	else if(currsig == 2)
+	{
+		retsig = 18;
+	}
+	else if(currsig == 1)
+	{
+		retsig = 9;
+	}
+	else
+	{
+		retsig = currsig;
+	}
+
+	return retsig;
+}
+
+static void rtl8192_query_rxphystatus(
+	struct r8192_priv * priv,
+	struct ieee80211_rx_stats * pstats,
+	prx_desc_819x_pci  pdesc,
+	prx_fwinfo_819x_pci   pdrvinfo,
+	struct ieee80211_rx_stats * precord_stats,
+	bool bpacket_match_bssid,
+	bool bpacket_toself,
+	bool bPacketBeacon,
+	bool bToSelfBA
+	)
+{
+	//PRT_RFD_STATUS		pRtRfdStatus = &(pRfd->Status);
+	phy_sts_ofdm_819xpci_t* pofdm_buf;
+	phy_sts_cck_819xpci_t	*	pcck_buf;
+	phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
+	u8				*prxpkt;
+	u8				i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
+	char				rx_pwr[4], rx_pwr_all=0;
+	//long				rx_avg_pwr = 0;
+	char				rx_snrX, rx_evmX;
+	u8				evm, pwdb_all;
+	u32 			RSSI, total_rssi=0;//, total_evm=0;
+//	long				signal_strength_index = 0;
+	u8				is_cck_rate=0;
+	u8				rf_rx_num = 0;
+
+	/* 2007/07/04 MH For OFDM RSSI. For high power or not. */
+	static	u8		check_reg824 = 0;
+	static	u32		reg824_bit9 = 0;
+
+	priv->stats.numqry_phystatus++;
+
+	is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
+
+	// Record it for next packet processing
+	memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
+	pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
+	pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
+	pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
+	pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
+	pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
+	/*2007.08.30 requested by SD3 Jerry */
+	if(check_reg824 == 0)
+	{
+		reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
+		check_reg824 = 1;
+	}
+
+
+	prxpkt = (u8*)pdrvinfo;
+
+	/* Move pointer to the 16th bytes. Phy status start address. */
+	prxpkt += sizeof(rx_fwinfo_819x_pci);
+
+	/* Initial the cck and ofdm buffer pointer */
+	pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
+	pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
+
+	pstats->RxMIMOSignalQuality[0] = -1;
+	pstats->RxMIMOSignalQuality[1] = -1;
+	precord_stats->RxMIMOSignalQuality[0] = -1;
+	precord_stats->RxMIMOSignalQuality[1] = -1;
+
+	if(is_cck_rate)
+	{
+		//
+		// (1)Hardware does not provide RSSI for CCK
+		//
+
+		//
+		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
+		//
+		u8 report;//, cck_agc_rpt;
+#ifdef RTL8190P
+		u8 tmp_pwdb;
+		char cck_adc_pwdb[4];
+#endif
+		priv->stats.numqry_phystatusCCK++;
+
+#ifdef RTL8190P	//Only 90P 2T4R need to check
+		if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
+		{
+			for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
+			{
+				tmp_pwdb = pcck_buf->adc_pwdb_X[i];
+				cck_adc_pwdb[i] = (char)tmp_pwdb;
+				cck_adc_pwdb[i] /= 2;
+				pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
+				//DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
+			}
+		}
+#endif
+
+		if(!reg824_bit9)
+		{
+			report = pcck_buf->cck_agc_rpt & 0xc0;
+			report = report>>6;
+			switch(report)
+			{
+				//Fixed by Jacken from Bryant 2008-03-20
+				//Original value is -38 , -26 , -14 , -2
+				//Fixed value is -35 , -23 , -11 , 6
+				case 0x3:
+					rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+				case 0x2:
+					rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+				case 0x1:
+					rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+				case 0x0:
+					rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
+					break;
+			}
+		}
+		else
+		{
+			report = pcck_buf->cck_agc_rpt & 0x60;
+			report = report>>5;
+			switch(report)
+			{
+				case 0x3:
+					rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
+					break;
+				case 0x2:
+					rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
+					break;
+				case 0x1:
+					rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
+					break;
+				case 0x0:
+					rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
+					break;
+			}
+		}
+
+		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
+		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
+		pstats->RecvSignalPower = rx_pwr_all;
+
+		//
+		// (3) Get Signal Quality (EVM)
+		//
+		if(bpacket_match_bssid)
+		{
+			u8	sq;
+
+			if(pstats->RxPWDBAll > 40)
+			{
+				sq = 100;
+			}else
+			{
+				sq = pcck_buf->sq_rpt;
+
+				if(pcck_buf->sq_rpt > 64)
+					sq = 0;
+				else if (pcck_buf->sq_rpt < 20)
+					sq = 100;
+				else
+					sq = ((64-sq) * 100) / 44;
+			}
+			pstats->SignalQuality = precord_stats->SignalQuality = sq;
+			pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
+			pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
+		}
+	}
+	else
+	{
+		priv->stats.numqry_phystatusHT++;
+		//
+		// (1)Get RSSI for HT rate
+		//
+		for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
+		{
+			// 2008/01/30 MH we will judge RF RX path now.
+			if (priv->brfpath_rxenable[i])
+				rf_rx_num++;
+			//else
+				//continue;
+
+			//Fixed by Jacken from Bryant 2008-03-20
+			//Original value is 106
+#ifdef RTL8190P	   //Modify by Jacken 2008/03/31
+			rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
+#else
+			rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
+#endif
+
+			//Get Rx snr value in DB
+			tmp_rxsnr = pofdm_buf->rxsnr_X[i];
+			rx_snrX = (char)(tmp_rxsnr);
+			rx_snrX /= 2;
+			priv->stats.rxSNRdB[i] = (long)rx_snrX;
+
+			/* Translate DBM to percentage. */
+			RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
+			if (priv->brfpath_rxenable[i])
+				total_rssi += RSSI;
+
+			/* Record Signal Strength for next packet */
+			if(bpacket_match_bssid)
+			{
+				pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
+				precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
+			}
+		}
+
+
+		//
+		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
+		//
+		//Fixed by Jacken from Bryant 2008-03-20
+		//Original value is 106
+		rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
+		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
+
+		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
+		pstats->RxPower = precord_stats->RxPower =	rx_pwr_all;
+		pstats->RecvSignalPower = rx_pwr_all;
+		//
+		// (3)EVM of HT rate
+		//
+		if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
+			pdrvinfo->RxRate<=DESC90_RATEMCS15)
+			max_spatial_stream = 2; //both spatial stream make sense
+		else
+			max_spatial_stream = 1; //only spatial stream 1 makes sense
+
+		for(i=0; i<max_spatial_stream; i++)
+		{
+			tmp_rxevm = pofdm_buf->rxevm_X[i];
+			rx_evmX = (char)(tmp_rxevm);
+
+			// Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
+			// fill most significant bit to "zero" when doing shifting operation which may change a negative
+			// value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore.
+			rx_evmX /= 2;	//dbm
+
+			evm = rtl819x_evm_dbtopercentage(rx_evmX);
+#if 0
+			EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
+#endif
+			if(bpacket_match_bssid)
+			{
+				if(i==0) // Fill value in RFD, Get the first spatial stream only
+					pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
+				pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
+			}
+		}
+
+
+		/* record rx statistics for debug */
+		rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
+		prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
+		if(pdrvinfo->BW)	//40M channel
+			priv->stats.received_bwtype[1+prxsc->rxsc]++;
+		else				//20M channel
+			priv->stats.received_bwtype[0]++;
+	}
+
+	//UI BSS List signal strength(in percentage), make it good looking, from 0~100.
+	//It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
+	if(is_cck_rate)
+	{
+		pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
+
+	}
+	else
+	{
+		//pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
+		// We can judge RX path number now.
+		if (rf_rx_num != 0)
+			pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
+	}
+}	/* QueryRxPhyStatus8190Pci */
+
+static void
+rtl8192_record_rxdesc_forlateruse(
+	struct ieee80211_rx_stats * psrc_stats,
+	struct ieee80211_rx_stats * ptarget_stats
+)
+{
+	ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
+	ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
+	//ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
+}
+
+
+
+static void TranslateRxSignalStuff819xpci(struct net_device *dev,
+        struct sk_buff *skb,
+        struct ieee80211_rx_stats * pstats,
+        prx_desc_819x_pci pdesc,
+        prx_fwinfo_819x_pci pdrvinfo)
+{
+    // TODO: We must only check packet for current MAC address. Not finish
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+    bool bpacket_match_bssid, bpacket_toself;
+    bool bPacketBeacon=false, bToSelfBA=false;
+    static struct ieee80211_rx_stats  previous_stats;
+    struct ieee80211_hdr_3addr *hdr;
+    u16 fc,type;
+
+    // Get Signal Quality for only RX data queue (but not command queue)
+
+    u8* tmp_buf;
+    u8	*praddr;
+
+    /* Get MAC frame start address. */
+    tmp_buf = skb->data;
+
+    hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
+    fc = le16_to_cpu(hdr->frame_ctl);
+    type = WLAN_FC_GET_TYPE(fc);
+    praddr = hdr->addr1;
+
+    /* Check if the received packet is acceptabe. */
+    bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
+            (eqMacAddr(priv->ieee80211->current_network.bssid,	(fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
+            && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
+    bpacket_toself =  bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
+#if 1//cosa
+    if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
+    {
+        bPacketBeacon = true;
+        //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
+    }
+    if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
+    {
+        if((eqMacAddr(praddr,dev->dev_addr)))
+            bToSelfBA = true;
+        //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
+    }
+
+#endif
+    if(bpacket_match_bssid)
+    {
+        priv->stats.numpacket_matchbssid++;
+    }
+    if(bpacket_toself){
+        priv->stats.numpacket_toself++;
+    }
+    //
+    // Process PHY information for previous packet (RSSI/PWDB/EVM)
+    //
+    // Because phy information is contained in the last packet of AMPDU only, so driver
+    // should process phy information of previous packet
+    rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
+    rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
+            bpacket_toself ,bPacketBeacon, bToSelfBA);
+    rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
+
+}
+
+
+static void rtl8192_tx_resume(struct net_device *dev)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee80211;
+	struct sk_buff *skb;
+	int queue_index;
+
+	for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
+		while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
+				(priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
+			/* 1. dequeue the packet from the wait queue */
+			skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
+			/* 2. tx the packet directly */
+			ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
+			#if 0
+			if(queue_index!=MGNT_QUEUE) {
+				ieee->stats.tx_packets++;
+				ieee->stats.tx_bytes += skb->len;
+			}
+			#endif
+		}
+	}
+}
+
+void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
+{
+       rtl8192_tx_resume(priv->ieee80211->dev);
+}
+
+/**
+* Function:	UpdateReceivedRateHistogramStatistics
+* Overview:	Recored down the received data rate
+*
+* Input:
+* 	PADAPTER	Adapter
+*	PRT_RFD		pRfd,
+*
+* Output:
+*	PRT_TCB		Adapter
+*				(Adapter->RxStats.ReceivedRateHistogram[] is updated)
+* Return:
+*		None
+*/
+static void UpdateReceivedRateHistogramStatistics8190(
+	struct net_device *dev,
+	struct ieee80211_rx_stats* pstats
+	)
+{
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	u32 rcvType=1;   //0: Total, 1:OK, 2:CRC, 3:ICV
+	u32 rateIndex;
+	u32 preamble_guardinterval;  //1: short preamble/GI, 0: long preamble/GI
+
+	/* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
+	#if 0
+	if (pRfd->queue_id == CMPK_RX_QUEUE_ID)
+		return;
+	#endif
+	if(pstats->bCRC)
+		rcvType = 2;
+	else if(pstats->bICV)
+		rcvType = 3;
+
+	if(pstats->bShortPreamble)
+		preamble_guardinterval = 1;// short
+	else
+		preamble_guardinterval = 0;// long
+
+	switch(pstats->rate)
+	{
+		//
+		// CCK rate
+		//
+		case MGN_1M:    rateIndex = 0;  break;
+	    	case MGN_2M:    rateIndex = 1;  break;
+	    	case MGN_5_5M:  rateIndex = 2;  break;
+	    	case MGN_11M:   rateIndex = 3;  break;
+		//
+		// Legacy OFDM rate
+		//
+	    	case MGN_6M:    rateIndex = 4;  break;
+	    	case MGN_9M:    rateIndex = 5;  break;
+	    	case MGN_12M:   rateIndex = 6;  break;
+	    	case MGN_18M:   rateIndex = 7;  break;
+	    	case MGN_24M:   rateIndex = 8;  break;
+	    	case MGN_36M:   rateIndex = 9;  break;
+	    	case MGN_48M:   rateIndex = 10; break;
+	    	case MGN_54M:   rateIndex = 11; break;
+		//
+		// 11n High throughput rate
+		//
+	    	case MGN_MCS0:  rateIndex = 12; break;
+	    	case MGN_MCS1:  rateIndex = 13; break;
+	    	case MGN_MCS2:  rateIndex = 14; break;
+	    	case MGN_MCS3:  rateIndex = 15; break;
+	    	case MGN_MCS4:  rateIndex = 16; break;
+	    	case MGN_MCS5:  rateIndex = 17; break;
+	    	case MGN_MCS6:  rateIndex = 18; break;
+	    	case MGN_MCS7:  rateIndex = 19; break;
+	    	case MGN_MCS8:  rateIndex = 20; break;
+	    	case MGN_MCS9:  rateIndex = 21; break;
+	    	case MGN_MCS10: rateIndex = 22; break;
+	    	case MGN_MCS11: rateIndex = 23; break;
+	    	case MGN_MCS12: rateIndex = 24; break;
+	    	case MGN_MCS13: rateIndex = 25; break;
+	    	case MGN_MCS14: rateIndex = 26; break;
+	    	case MGN_MCS15: rateIndex = 27; break;
+		default:        rateIndex = 28; break;
+	}
+	priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
+	priv->stats.received_rate_histogram[0][rateIndex]++; //total
+	priv->stats.received_rate_histogram[rcvType][rateIndex]++;
+}
+
+static void rtl8192_rx(struct net_device *dev)
+{
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+    struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
+    bool unicast_packet = false;
+    struct ieee80211_rx_stats stats = {
+        .signal = 0,
+        .noise = -98,
+        .rate = 0,
+        .freq = IEEE80211_24GHZ_BAND,
+    };
+    unsigned int count = priv->rxringcount;
+
+    stats.nic_type = NIC_8192E;
+
+    while (count--) {
+        rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
+        struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
+
+        if (pdesc->OWN){
+            /* wait data to be filled by hardware */
+            return;
+        } else {
+            stats.bICV = pdesc->ICV;
+            stats.bCRC = pdesc->CRC32;
+            stats.bHwError = pdesc->CRC32 | pdesc->ICV;
+
+            stats.Length = pdesc->Length;
+            if(stats.Length < 24)
+                stats.bHwError |= 1;
+
+            if(stats.bHwError) {
+                stats.bShift = false;
+
+                if(pdesc->CRC32) {
+                    if (pdesc->Length <500)
+                        priv->stats.rxcrcerrmin++;
+                    else if (pdesc->Length >1000)
+                        priv->stats.rxcrcerrmax++;
+                    else
+                        priv->stats.rxcrcerrmid++;
+                }
+                goto done;
+            } else {
+                prx_fwinfo_819x_pci pDrvInfo = NULL;
+                struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
+
+                if (unlikely(!new_skb)) {
+                    goto done;
+                }
+
+                stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
+                stats.RxBufShift = ((pdesc->Shift)&0x03);
+                stats.Decrypted = !pdesc->SWDec;
+
+                pci_dma_sync_single_for_cpu(priv->pdev,
+                     *((dma_addr_t *)skb->cb),
+                     priv->rxbuffersize,
+                     PCI_DMA_FROMDEVICE);
+                skb_put(skb, pdesc->Length);
+                pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
+                skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
+
+                stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
+                stats.bShortPreamble = pDrvInfo->SPLCP;
+
+                /* it is debug only. It should be disabled in released driver.
+                 * 2007.1.11 by Emily
+                 * */
+                UpdateReceivedRateHistogramStatistics8190(dev, &stats);
+
+                stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
+                stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
+
+                stats.TimeStampLow = pDrvInfo->TSFL;
+                stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
+
+                UpdateRxPktTimeStamp8190(dev, &stats);
+
+                //
+                // Get Total offset of MPDU Frame Body
+                //
+                if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
+                    stats.bShift = 1;
+
+                stats.RxIs40MHzPacket = pDrvInfo->BW;
+
+                /* ???? */
+                TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
+
+                /* Rx A-MPDU */
+                if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
+                    RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
+                            pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
+		   skb_trim(skb, skb->len - 4/*sCrcLng*/);
+                /* rx packets statistics */
+                ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
+                unicast_packet = false;
+
+                if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
+                    //TODO
+                }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
+                    //TODO
+                }else {
+                    /* unicast packet */
+                    unicast_packet = true;
+                }
+
+                stats.packetlength = stats.Length-4;
+                stats.fraglength = stats.packetlength;
+                stats.fragoffset = 0;
+                stats.ntotalfrag = 1;
+
+                if(!ieee80211_rx(priv->ieee80211, skb, &stats)){
+                    dev_kfree_skb_any(skb);
+                } else {
+                    priv->stats.rxok++;
+                    if(unicast_packet) {
+                        priv->stats.rxbytesunicast += skb->len;
+                    }
+                }
+
+                skb = new_skb;
+                priv->rx_buf[priv->rx_idx] = skb;
+                *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
+//                *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
+            }
+
+        }
+done:
+        pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
+        pdesc->OWN = 1;
+        pdesc->Length = priv->rxbuffersize;
+        if (priv->rx_idx == priv->rxringcount-1)
+            pdesc->EOR = 1;
+        priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
+    }
+
+}
+
+void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
+{
+       rtl8192_rx(priv->ieee80211->dev);
+	/* unmask RDU */
+       write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
+}
+
+static const struct net_device_ops rtl8192_netdev_ops = {
+	.ndo_open =			rtl8192_open,
+	.ndo_stop =			rtl8192_close,
+/*	.ndo_get_stats =		rtl8192_stats, */
+	.ndo_tx_timeout =		tx_timeout,
+	.ndo_do_ioctl =			rtl8192_ioctl,
+	.ndo_set_multicast_list =	r8192_set_multicast,
+	.ndo_set_mac_address =		r8192_set_mac_adr,
+	.ndo_start_xmit = 		ieee80211_xmit,
+};
+
+/****************************************************************************
+     ---------------------------- PCI_STUFF---------------------------
+*****************************************************************************/
+
+static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
+			 const struct pci_device_id *id)
+{
+	unsigned long ioaddr = 0;
+	struct net_device *dev = NULL;
+	struct r8192_priv *priv= NULL;
+	u8 unit = 0;
+
+#ifdef CONFIG_RTL8192_IO_MAP
+	unsigned long pio_start, pio_len, pio_flags;
+#else
+	unsigned long pmem_start, pmem_len, pmem_flags;
+#endif //end #ifdef RTL_IO_MAP
+
+	RT_TRACE(COMP_INIT,"Configuring chip resources");
+
+	if( pci_enable_device (pdev) ){
+		RT_TRACE(COMP_ERR,"Failed to enable PCI device");
+		return -EIO;
+	}
+
+	pci_set_master(pdev);
+	//pci_set_wmi(pdev);
+	pci_set_dma_mask(pdev, 0xffffff00ULL);
+	pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
+	dev = alloc_ieee80211(sizeof(struct r8192_priv));
+	if (!dev)
+		return -ENOMEM;
+
+	pci_set_drvdata(pdev, dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	priv = ieee80211_priv(dev);
+	priv->ieee80211 = netdev_priv(dev);
+	priv->pdev=pdev;
+	if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
+		priv->ieee80211->bSupportRemoteWakeUp = 1;
+	} else
+	{
+		priv->ieee80211->bSupportRemoteWakeUp = 0;
+	}
+
+#ifdef CONFIG_RTL8192_IO_MAP
+
+	pio_start = (unsigned long)pci_resource_start (pdev, 0);
+	pio_len = (unsigned long)pci_resource_len (pdev, 0);
+	pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
+
+      	if (!(pio_flags & IORESOURCE_IO)) {
+		RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
+		goto fail;
+	}
+
+	//DMESG("IO space @ 0x%08lx", pio_start );
+	if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
+		RT_TRACE(COMP_ERR,"request_region failed!");
+		goto fail;
+	}
+
+	ioaddr = pio_start;
+	dev->base_addr = ioaddr; // device I/O address
+
+#else
+
+	pmem_start = pci_resource_start(pdev, 1);
+	pmem_len = pci_resource_len(pdev, 1);
+	pmem_flags = pci_resource_flags (pdev, 1);
+
+	if (!(pmem_flags & IORESOURCE_MEM)) {
+		RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
+		goto fail;
+	}
+
+	//DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
+	if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
+		RT_TRACE(COMP_ERR,"request_mem_region failed!");
+		goto fail;
+	}
+
+
+	ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
+	if( ioaddr == (unsigned long)NULL ){
+		RT_TRACE(COMP_ERR,"ioremap failed!");
+	       // release_mem_region( pmem_start, pmem_len );
+		goto fail1;
+	}
+
+	dev->mem_start = ioaddr; // shared mem start
+	dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
+
+#endif //end #ifdef RTL_IO_MAP
+
+        /* We disable the RETRY_TIMEOUT register (0x41) to keep
+         * PCI Tx retries from interfering with C3 CPU state */
+         pci_write_config_byte(pdev, 0x41, 0x00);
+
+
+	pci_read_config_byte(pdev, 0x05, &unit);
+	pci_write_config_byte(pdev, 0x05, unit & (~0x04));
+
+	dev->irq = pdev->irq;
+	priv->irq = 0;
+
+	dev->netdev_ops = &rtl8192_netdev_ops;
+#if 0
+	dev->open = rtl8192_open;
+	dev->stop = rtl8192_close;
+	//dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
+	dev->tx_timeout = tx_timeout;
+	//dev->wireless_handlers = &r8192_wx_handlers_def;
+	dev->do_ioctl = rtl8192_ioctl;
+	dev->set_multicast_list = r8192_set_multicast;
+	dev->set_mac_address = r8192_set_mac_adr;
+#endif
+
+         //DMESG("Oops: i'm coming\n");
+#if WIRELESS_EXT >= 12
+#if WIRELESS_EXT < 17
+        dev->get_wireless_stats = r8192_get_wireless_stats;
+#endif
+        dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
+#endif
+       //dev->get_wireless_stats = r8192_get_wireless_stats;
+	dev->type=ARPHRD_ETHER;
+
+	dev->watchdog_timeo = HZ*3;	//modified by john, 0805
+
+	if (dev_alloc_name(dev, ifname) < 0){
+                RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
+		ifname = "wlan%d";
+		dev_alloc_name(dev, ifname);
+        }
+
+	RT_TRACE(COMP_INIT, "Driver probe completed1\n");
+	if(rtl8192_init(dev)!=0){
+		RT_TRACE(COMP_ERR, "Initialization failed");
+		goto fail;
+	}
+
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
+	register_netdev(dev);
+	RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
+	rtl8192_proc_init_one(dev);
+
+
+	RT_TRACE(COMP_INIT, "Driver probe completed\n");
+	return 0;
+
+fail1:
+
+#ifdef CONFIG_RTL8180_IO_MAP
+
+	if( dev->base_addr != 0 ){
+
+		release_region(dev->base_addr,
+	       pci_resource_len(pdev, 0) );
+	}
+#else
+	if( dev->mem_start != (unsigned long)NULL ){
+		iounmap( (void *)dev->mem_start );
+		release_mem_region( pci_resource_start(pdev, 1),
+				    pci_resource_len(pdev, 1) );
+	}
+#endif //end #ifdef RTL_IO_MAP
+
+fail:
+	if(dev){
+
+		if (priv->irq) {
+			free_irq(dev->irq, dev);
+			dev->irq=0;
+		}
+		free_ieee80211(dev);
+	}
+
+	pci_disable_device(pdev);
+
+	DMESG("wlan driver load failed\n");
+	pci_set_drvdata(pdev, NULL);
+	return -ENODEV;
+
+}
+
+/* detach all the work and timer structure declared or inititialized
+ * in r8192_init function.
+ * */
+void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
+{
+	/* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
+         * is  or is newer than 2.6.20 and work structure is defined to be struct work_struct.
+         * Otherwise call cancel_delayed_work is enough.
+         * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
+         * */
+	cancel_delayed_work(&priv->watch_dog_wq);
+	cancel_delayed_work(&priv->update_beacon_wq);
+	cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
+	cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
+#ifdef RTL8192E
+	cancel_delayed_work(&priv->gpio_change_rf_wq);
+#endif
+	cancel_work_sync(&priv->reset_wq);
+	cancel_work_sync(&priv->qos_activate);
+	//cancel_work_sync(&priv->SetBWModeWorkItem);
+	//cancel_work_sync(&priv->SwChnlWorkItem);
+
+}
+
+
+static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct r8192_priv *priv ;
+
+ 	if(dev){
+
+		unregister_netdev(dev);
+
+		priv=ieee80211_priv(dev);
+
+		rtl8192_proc_remove_one(dev);
+
+		rtl8192_down(dev);
+		if (priv->pFirmware)
+		{
+			vfree(priv->pFirmware);
+			priv->pFirmware = NULL;
+		}
+	//	priv->rf_close(dev);
+	//	rtl8192_usb_deleteendpoints(dev);
+		destroy_workqueue(priv->priv_wq);
+                /* redundant with rtl8192_down */
+               // rtl8192_irq_disable(dev);
+               // rtl8192_reset(dev);
+               // mdelay(10);
+                {
+                    u32 i;
+                    /* free tx/rx rings */
+                    rtl8192_free_rx_ring(dev);
+                    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
+                        rtl8192_free_tx_ring(dev, i);
+                    }
+                }
+		if(priv->irq){
+
+			printk("Freeing irq %d\n",dev->irq);
+			free_irq(dev->irq, dev);
+			priv->irq=0;
+
+		}
+
+
+
+	//	free_beacon_desc_ring(dev,priv->txbeaconcount);
+
+#ifdef CONFIG_RTL8180_IO_MAP
+
+		if( dev->base_addr != 0 ){
+
+			release_region(dev->base_addr,
+				       pci_resource_len(pdev, 0) );
+		}
+#else
+		if( dev->mem_start != (unsigned long)NULL ){
+			iounmap( (void *)dev->mem_start );
+			release_mem_region( pci_resource_start(pdev, 1),
+					    pci_resource_len(pdev, 1) );
+		}
+#endif /*end #ifdef RTL_IO_MAP*/
+		free_ieee80211(dev);
+
+	}
+
+	pci_disable_device(pdev);
+	RT_TRACE(COMP_DOWN, "wlan driver removed\n");
+}
+
+extern int ieee80211_init(void);
+extern void ieee80211_exit(void);
+
+static int __init rtl8192_pci_module_init(void)
+{
+	int retval;
+
+	retval = ieee80211_init();
+	if (retval)
+		return retval;
+
+	printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
+	printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
+	RT_TRACE(COMP_INIT, "Initializing module");
+	RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
+	rtl8192_proc_module_init();
+      if(0!=pci_register_driver(&rtl8192_pci_driver))
+	{
+		DMESG("No device found");
+		/*pci_unregister_driver (&rtl8192_pci_driver);*/
+		return -ENODEV;
+	}
+	return 0;
+}
+
+
+static void __exit rtl8192_pci_module_exit(void)
+{
+	pci_unregister_driver(&rtl8192_pci_driver);
+
+	RT_TRACE(COMP_DOWN, "Exiting");
+	rtl8192_proc_module_remove();
+	ieee80211_exit();
+}
+
+//warning message WB
+irqreturn_t rtl8192_interrupt(int irq, void *netdev)
+{
+    struct net_device *dev = (struct net_device *) netdev;
+    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+    unsigned long flags;
+    u32 inta;
+    /* We should return IRQ_NONE, but for now let me keep this */
+    if(priv->irq_enabled == 0){
+        return IRQ_HANDLED;
+    }
+
+    spin_lock_irqsave(&priv->irq_th_lock,flags);
+
+    //ISR: 4bytes
+
+    inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
+    write_nic_dword(dev,ISR,inta); // reset int situation
+
+    priv->stats.shints++;
+    //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
+    if(!inta){
+        spin_unlock_irqrestore(&priv->irq_th_lock,flags);
+        return IRQ_HANDLED;
+        /*
+           most probably we can safely return IRQ_NONE,
+           but for now is better to avoid problems
+           */
+    }
+
+    if(inta == 0xffff){
+        /* HW disappared */
+        spin_unlock_irqrestore(&priv->irq_th_lock,flags);
+        return IRQ_HANDLED;
+    }
+
+    priv->stats.ints++;
+#ifdef DEBUG_IRQ
+    DMESG("NIC irq %x",inta);
+#endif
+    //priv->irqpending = inta;
+
+
+    if(!netif_running(dev)) {
+        spin_unlock_irqrestore(&priv->irq_th_lock,flags);
+        return IRQ_HANDLED;
+    }
+
+    if(inta & IMR_TIMEOUT0){
+        //		write_nic_dword(dev, TimerInt, 0);
+        //DMESG("=================>waking up");
+        //		rtl8180_hw_wakeup(dev);
+    }
+
+    if(inta & IMR_TBDOK){
+        RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
+        rtl8192_tx_isr(dev, BEACON_QUEUE);
+        priv->stats.txbeaconokint++;
+    }
+
+    if(inta & IMR_TBDER){
+        RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
+        rtl8192_tx_isr(dev, BEACON_QUEUE);
+        priv->stats.txbeaconerr++;
+    }
+
+    if(inta  & IMR_MGNTDOK ) {
+        RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
+        priv->stats.txmanageokint++;
+        rtl8192_tx_isr(dev,MGNT_QUEUE);
+
+    }
+
+    if(inta & IMR_COMDOK)
+    {
+        priv->stats.txcmdpktokint++;
+        rtl8192_tx_isr(dev,TXCMD_QUEUE);
+    }
+
+    if(inta & IMR_ROK){
+#ifdef DEBUG_RX
+        DMESG("Frame arrived !");
+#endif
+        priv->stats.rxint++;
+        tasklet_schedule(&priv->irq_rx_tasklet);
+    }
+
+    if(inta & IMR_BcnInt) {
+        RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
+        tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
+    }
+
+    if(inta & IMR_RDU){
+        RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
+        priv->stats.rxrdu++;
+        /* reset int situation */
+        write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
+        tasklet_schedule(&priv->irq_rx_tasklet);
+    }
+
+    if(inta & IMR_RXFOVW){
+        RT_TRACE(COMP_INTR, "rx overflow !\n");
+        priv->stats.rxoverflow++;
+        tasklet_schedule(&priv->irq_rx_tasklet);
+    }
+
+    if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
+
+    if(inta & IMR_BKDOK){
+        RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
+        priv->stats.txbkokint++;
+        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
+        rtl8192_tx_isr(dev,BK_QUEUE);
+        rtl8192_try_wake_queue(dev, BK_QUEUE);
+    }
+
+    if(inta & IMR_BEDOK){
+        RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
+        priv->stats.txbeokint++;
+        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
+        rtl8192_tx_isr(dev,BE_QUEUE);
+        rtl8192_try_wake_queue(dev, BE_QUEUE);
+    }
+
+    if(inta & IMR_VIDOK){
+        RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
+        priv->stats.txviokint++;
+        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
+        rtl8192_tx_isr(dev,VI_QUEUE);
+        rtl8192_try_wake_queue(dev, VI_QUEUE);
+    }
+
+    if(inta & IMR_VODOK){
+        priv->stats.txvookint++;
+        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
+        rtl8192_tx_isr(dev,VO_QUEUE);
+        rtl8192_try_wake_queue(dev, VO_QUEUE);
+    }
+
+    force_pci_posting(dev);
+    spin_unlock_irqrestore(&priv->irq_th_lock,flags);
+
+    return IRQ_HANDLED;
+}
+
+void rtl8192_try_wake_queue(struct net_device *dev, int pri)
+{
+#if 0
+	unsigned long flags;
+	short enough_desc;
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+
+	spin_lock_irqsave(&priv->tx_lock,flags);
+	enough_desc = check_nic_enough_desc(dev,pri);
+        spin_unlock_irqrestore(&priv->tx_lock,flags);
+
+	if(enough_desc)
+		ieee80211_wake_queue(priv->ieee80211);
+#endif
+}
+
+
+void EnableHWSecurityConfig8192(struct net_device *dev)
+{
+        u8 SECR_value = 0x0;
+	// struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
+	 //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	 struct ieee80211_device* ieee = priv->ieee80211;
+	 //printk("==>ieee:%p, dev:%p\n", ieee, dev);
+	SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
+#if 1
+	if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
+	{
+		SECR_value |= SCR_RxUseDK;
+		SECR_value |= SCR_TxUseDK;
+	}
+	else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
+	{
+		SECR_value |= SCR_RxUseDK;
+		SECR_value |= SCR_TxUseDK;
+	}
+
+#endif
+
+        //add HWSec active enable here.
+//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4
+	ieee->hwsec_active = 1;
+
+	if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off
+	{
+		ieee->hwsec_active = 0;
+		SECR_value &= ~SCR_RxDecEnable;
+	}
+
+	RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
+			ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
+	{
+                write_nic_byte(dev, SECR,  SECR_value);//SECR_value |  SCR_UseDK );
+        }
+
+}
+#define TOTAL_CAM_ENTRY 32
+//#define CAM_CONTENT_COUNT 8
+void setKey(	struct net_device *dev,
+		u8 EntryNo,
+		u8 KeyIndex,
+		u16 KeyType,
+		u8 *MacAddr,
+		u8 DefaultKey,
+		u32 *KeyContent )
+{
+	u32 TargetCommand = 0;
+	u32 TargetContent = 0;
+	u16 usConfig = 0;
+	u8 i;
+#ifdef ENABLE_IPS
+	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
+	RT_RF_POWER_STATE	rtState;
+	rtState = priv->ieee80211->eRFPowerState;
+	if(priv->ieee80211->PowerSaveControl.bInactivePs){
+		if(rtState == eRfOff){
+			if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
+			{
+				RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
+				up(&priv->wx_sem);
+				return ;
+			}
+			else{
+				IPSLeave(dev);
+			}
+		}
+	}
+	priv->ieee80211->is_set_key = true;
+#endif
+	if (EntryNo >= TOTAL_CAM_ENTRY)
+		RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
+
+	RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
+
+	if (DefaultKey)
+		usConfig |= BIT15 | (KeyType<<2);
+	else
+		usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
+//	usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
+
+
+	for(i=0 ; i<CAM_CONTENT_COUNT; i++){
+		TargetCommand  = i+CAM_CONTENT_COUNT*EntryNo;
+		TargetCommand |= BIT31|BIT16;
+
+		if(i==0){//MAC|Config
+			TargetContent = (u32)(*(MacAddr+0)) << 16|
+					(u32)(*(MacAddr+1)) << 24|
+					(u32)usConfig;
+
+			write_nic_dword(dev, WCAMI, TargetContent);
+			write_nic_dword(dev, RWCAM, TargetCommand);
+	//		printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
+		}
+		else if(i==1){//MAC
+                        TargetContent = (u32)(*(MacAddr+2)) 	 |
+                                        (u32)(*(MacAddr+3)) <<  8|
+                                        (u32)(*(MacAddr+4)) << 16|
+                                        (u32)(*(MacAddr+5)) << 24;
+			write_nic_dword(dev, WCAMI, TargetContent);
+			write_nic_dword(dev, RWCAM, TargetCommand);
+		}
+		else {	//Key Material
+			if(KeyContent != NULL)
+			{
+			write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
+			write_nic_dword(dev, RWCAM, TargetCommand);
+		}
+	}
+	}
+	RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
+}
+// This function seems not ready! WB
+void CamPrintDbgReg(struct net_device* dev)
+{
+	unsigned long rvalue;
+	unsigned char ucValue;
+	write_nic_dword(dev, DCAM, 0x80000000);
+	msleep(40);
+	rvalue = read_nic_dword(dev, DCAM);	//delay_ms(40);
+	RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
+	if((rvalue & 0x40000000) != 0x4000000)
+		RT_TRACE(COMP_SEC, "-->TX Key Not Found      ");
+	msleep(20);
+	write_nic_dword(dev, DCAM, 0x00000000);	//delay_ms(40);
+	rvalue = read_nic_dword(dev, DCAM);	//delay_ms(40);
+	RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
+	if((rvalue & 0x40000000) != 0x4000000)
+		RT_TRACE(COMP_SEC, "-->CAM Key Not Found   ");
+	ucValue = read_nic_byte(dev, SECR);
+	RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
+}
+
+
+/***************************************************************************
+     ------------------- module init / exit stubs ----------------
+****************************************************************************/
+module_init(rtl8192_pci_module_init);
+module_exit(rtl8192_pci_module_exit);
diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c
new file mode 100644
index 0000000..bf87632
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192E_dm.c
@@ -0,0 +1,3880 @@
+/*++
+Copyright-c Realtek Semiconductor Corp. All rights reserved.
+
+Module Name:
+	r8192U_dm.c
+
+Abstract:
+	HW dynamic mechanism.
+
+Major Change History:
+	When      	Who				What
+	----------	--------------- -------------------------------
+	2008-05-14	amy                     create version 0 porting from windows code.
+
+--*/
+#include "r8192E.h"
+#include "r8192E_dm.h"
+#include "r8192E_hw.h"
+#include "r819xE_phy.h"
+#include "r819xE_phyreg.h"
+#include "r8190_rtl8256.h"
+/*---------------------------Define Local Constant---------------------------*/
+//
+// Indicate different AP vendor for IOT issue.
+//
+#ifdef  RTL8190P
+static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+{ 0x5e4322, 	0x5e4322, 	0x5e4322,  	0x604322, 	0xa44f, 	0x5e4322};
+static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+{ 0x5e4322, 	0xa44f, 	0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322};
+#else
+#ifdef RTL8192E
+static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5e4322};
+static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+{ 0x5e4322, 	0xa44f,		0x5e4322,  	0x604322, 	0x5e4322, 	0x5e4322};
+#else
+static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
+{ 0x5e4322, 	0x5e4322, 	0x5e4322, 	0x604322, 	0xa44f, 	0x5ea44f};
+static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
+{ 0x5e4322, 	0xa44f, 	0x5e4322, 	0x604322, 	0x5ea44f, 	0x5ea44f};
+#endif
+#endif
+
+#define RTK_UL_EDCA 0xa44f
+#define RTK_DL_EDCA 0x5e4322
+/*---------------------------Define Local Constant---------------------------*/
+
+
+/*------------------------Define global variable-----------------------------*/
+// Debug variable ?
+dig_t	dm_digtable;
+// Store current shoftware write register content for MAC PHY.
+u8		dm_shadow[16][256] = {{0}};
+// For Dynamic Rx Path Selection by Signal Strength
+DRxPathSel	DM_RxPathSelTable;
+/*------------------------Define global variable-----------------------------*/
+
+
+/*------------------------Define local variable------------------------------*/
+/*------------------------Define local variable------------------------------*/
+
+
+/*--------------------Define export function prototype-----------------------*/
+extern	void	init_hal_dm(struct net_device *dev);
+extern	void deinit_hal_dm(struct net_device *dev);
+
+extern void hal_dm_watchdog(struct net_device *dev);
+
+
+extern	void	init_rate_adaptive(struct net_device *dev);
+extern	void	dm_txpower_trackingcallback(struct work_struct *work);
+
+extern	void	dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
+extern	void	dm_restore_dynamic_mechanism_state(struct net_device *dev);
+extern	void	dm_backup_dynamic_mechanism_state(struct net_device *dev);
+extern	void	dm_change_dynamic_initgain_thresh(struct net_device *dev,
+								u32		dm_type,
+								u32		dm_value);
+extern	void	DM_ChangeFsyncSetting(struct net_device *dev,
+												s32		DM_Type,
+												s32		DM_Value);
+extern	void dm_force_tx_fw_info(struct net_device *dev,
+										u32		force_type,
+										u32		force_value);
+extern	void	dm_init_edca_turbo(struct net_device *dev);
+extern	void	dm_rf_operation_test_callback(unsigned long data);
+extern	void	dm_rf_pathcheck_workitemcallback(struct work_struct *work);
+extern	void dm_fsync_timer_callback(unsigned long data);
+extern	void dm_check_fsync(struct net_device *dev);
+extern	void	dm_shadow_init(struct net_device *dev);
+extern	void dm_initialize_txpower_tracking(struct net_device *dev);
+
+#ifdef RTL8192E
+extern  void    dm_gpio_change_rf_callback(struct work_struct *work);
+#endif
+
+
+
+/*--------------------Define export function prototype-----------------------*/
+
+
+/*---------------------Define local function prototype-----------------------*/
+// DM --> Rate Adaptive
+static	void	dm_check_rate_adaptive(struct net_device *dev);
+
+// DM --> Bandwidth switch
+static	void	dm_init_bandwidth_autoswitch(struct net_device *dev);
+static	void	dm_bandwidth_autoswitch(	struct net_device *dev);
+
+// DM --> TX power control
+//static	void	dm_initialize_txpower_tracking(struct net_device *dev);
+
+static	void	dm_check_txpower_tracking(struct net_device *dev);
+
+
+
+//static	void	dm_txpower_reset_recovery(struct net_device *dev);
+
+
+// DM --> BB init gain restore
+#ifndef RTL8192U
+static	void	dm_bb_initialgain_restore(struct net_device *dev);
+
+
+// DM --> BB init gain backup
+static	void	dm_bb_initialgain_backup(struct net_device *dev);
+#endif
+
+// DM --> Dynamic Init Gain by RSSI
+static	void	dm_dig_init(struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi(struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi_by_driverrssi(	struct net_device *dev);
+static	void	dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
+static	void	dm_initial_gain(struct net_device *dev);
+static	void	dm_pd_th(struct net_device *dev);
+static	void	dm_cs_ratio(struct net_device *dev);
+
+static	void dm_init_ctstoself(struct net_device *dev);
+// DM --> EDCA turboe mode control
+static	void	dm_check_edca_turbo(struct net_device *dev);
+
+// DM --> HW RF control
+static	void	dm_check_rfctrl_gpio(struct net_device *dev);
+
+#ifndef RTL8190P
+//static	void	dm_gpio_change_rf(struct net_device *dev);
+#endif
+// DM --> Check PBC
+static	void dm_check_pbc_gpio(struct net_device *dev);
+
+
+// DM --> Check current RX RF path state
+static	void	dm_check_rx_path_selection(struct net_device *dev);
+static 	void dm_init_rxpath_selection(struct net_device *dev);
+static	void dm_rxpath_sel_byrssi(struct net_device *dev);
+
+
+// DM --> Fsync for broadcom ap
+static void dm_init_fsync(struct net_device *dev);
+static void dm_deInit_fsync(struct net_device *dev);
+
+//Added by vivi, 20080522
+static	void	dm_check_txrateandretrycount(struct net_device *dev);
+
+/*---------------------Define local function prototype-----------------------*/
+
+/*---------------------Define of Tx Power Control For Near/Far Range --------*/   //Add by Jacken 2008/02/18
+static	void	dm_init_dynamic_txpower(struct net_device *dev);
+static	void	dm_dynamic_txpower(struct net_device *dev);
+
+
+// DM --> For rate adaptive and DIG, we must send RSSI to firmware
+static	void dm_send_rssi_tofw(struct net_device *dev);
+static	void	dm_ctstoself(struct net_device *dev);
+/*---------------------------Define function prototype------------------------*/
+//================================================================================
+//	HW Dynamic mechanism interface.
+//================================================================================
+
+//
+//	Description:
+//		Prepare SW resource for HW dynamic mechanism.
+//
+//	Assumption:
+//		This function is only invoked at driver intialization once.
+//
+//
+void init_hal_dm(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
+	priv->undecorated_smoothed_pwdb = -1;
+
+	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
+	dm_init_dynamic_txpower(dev);
+	init_rate_adaptive(dev);
+	//dm_initialize_txpower_tracking(dev);
+	dm_dig_init(dev);
+	dm_init_edca_turbo(dev);
+	dm_init_bandwidth_autoswitch(dev);
+	dm_init_fsync(dev);
+	dm_init_rxpath_selection(dev);
+	dm_init_ctstoself(dev);
+#ifdef RTL8192E
+	INIT_DELAYED_WORK(&priv->gpio_change_rf_wq,  dm_gpio_change_rf_callback);
+#endif
+
+}	// InitHalDm
+
+void deinit_hal_dm(struct net_device *dev)
+{
+
+	dm_deInit_fsync(dev);
+
+}
+
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+void dm_CheckRxAggregation(struct net_device *dev) {
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	static unsigned long	lastTxOkCnt = 0;
+	static unsigned long	lastRxOkCnt = 0;
+	unsigned long		curTxOkCnt = 0;
+	unsigned long		curRxOkCnt = 0;
+
+/*
+	if (pHalData->bForcedUsbRxAggr) {
+		if (pHalData->ForcedUsbRxAggrInfo == 0) {
+			if (pHalData->bCurrentRxAggrEnable) {
+				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
+			}
+		} else {
+			if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) {
+				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE);
+			}
+		}
+		return;
+	}
+
+*/
+	curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
+	curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
+
+	if((curTxOkCnt + curRxOkCnt) < 15000000) {
+		return;
+	}
+
+	if(curTxOkCnt > 4*curRxOkCnt) {
+		if (priv->bCurrentRxAggrEnable) {
+			write_nic_dword(dev, 0x1a8, 0);
+			priv->bCurrentRxAggrEnable = false;
+		}
+	}else{
+		if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
+			u32 ulValue;
+			ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
+				(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
+			/*
+			 * If usb rx firmware aggregation is enabled,
+			 * when anyone of three threshold conditions above is reached,
+			 * firmware will send aggregated packet to driver.
+			 */
+			write_nic_dword(dev, 0x1a8, ulValue);
+			priv->bCurrentRxAggrEnable = true;
+		}
+	}
+
+	lastTxOkCnt = priv->stats.txbytesunicast;
+	lastRxOkCnt = priv->stats.rxbytesunicast;
+}	// dm_CheckEdcaTurbo
+#endif
+
+
+
+void hal_dm_watchdog(struct net_device *dev)
+{
+        //struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//static u8 	previous_bssid[6] ={0};
+
+	/*Add by amy 2008/05/15 ,porting from windows code.*/
+	dm_check_rate_adaptive(dev);
+	dm_dynamic_txpower(dev);
+	dm_check_txrateandretrycount(dev);
+
+	dm_check_txpower_tracking(dev);
+
+	dm_ctrl_initgain_byrssi(dev);
+	dm_check_edca_turbo(dev);
+	dm_bandwidth_autoswitch(dev);
+
+	dm_check_rfctrl_gpio(dev);
+	dm_check_rx_path_selection(dev);
+	dm_check_fsync(dev);
+
+	// Add by amy 2008-05-15 porting from windows code.
+	dm_check_pbc_gpio(dev);
+	dm_send_rssi_tofw(dev);
+	dm_ctstoself(dev);
+
+#ifdef USB_RX_AGGREGATION_SUPPORT
+	dm_CheckRxAggregation(dev);
+#endif
+}	//HalDmWatchDog
+
+
+/*
+  * Decide Rate Adaptive Set according to distance (signal strength)
+  *	01/11/2008	MHC		Modify input arguments and RATR table level.
+  *	01/16/2008	MHC		RF_Type is assigned in ReadAdapterInfo(). We must call
+  *						the function after making sure RF_Type.
+  */
+void init_rate_adaptive(struct net_device * dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	prate_adaptive			pra = (prate_adaptive)&priv->rate_adaptive;
+
+	pra->ratr_state = DM_RATR_STA_MAX;
+	pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
+	pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
+	pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
+
+	pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
+	pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
+	pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
+
+	if(priv->CustomerID == RT_CID_819x_Netcore)
+		pra->ping_rssi_enable = 1;
+	else
+		pra->ping_rssi_enable = 0;
+	pra->ping_rssi_thresh_for_ra = 15;
+
+
+	if (priv->rf_type == RF_2T4R)
+	{
+		// 07/10/08 MH Modify for RA smooth scheme.
+		/* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
+		pra->upper_rssi_threshold_ratr		= 	0x8f0f0000;
+		pra->middle_rssi_threshold_ratr		= 	0x8f0ff000;
+		pra->low_rssi_threshold_ratr		= 	0x8f0ff001;
+		pra->low_rssi_threshold_ratr_40M	= 	0x8f0ff005;
+		pra->low_rssi_threshold_ratr_20M	= 	0x8f0ff001;
+		pra->ping_rssi_ratr	= 	0x0000000d;//cosa add for test
+	}
+	else if (priv->rf_type == RF_1T2R)
+	{
+		pra->upper_rssi_threshold_ratr		= 	0x000f0000;
+		pra->middle_rssi_threshold_ratr		= 	0x000ff000;
+		pra->low_rssi_threshold_ratr		= 	0x000ff001;
+		pra->low_rssi_threshold_ratr_40M	= 	0x000ff005;
+		pra->low_rssi_threshold_ratr_20M	= 	0x000ff001;
+		pra->ping_rssi_ratr	= 	0x0000000d;//cosa add for test
+	}
+
+}	// InitRateAdaptive
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_rate_adaptive()
+ *
+ * Overview:
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/26/08	amy 	Create version 0 proting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_check_rate_adaptive(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	prate_adaptive			pra = (prate_adaptive)&priv->rate_adaptive;
+	u32						currentRATR, targetRATR = 0;
+	u32						LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
+	bool						bshort_gi_enabled = false;
+	static u8					ping_rssi_state=0;
+
+
+	if(!priv->up)
+	{
+		RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
+		return;
+	}
+
+	if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
+		return;
+
+	// TODO: Only 11n mode is implemented currently,
+	if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
+		 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
+		 return;
+
+	if( priv->ieee80211->state == IEEE80211_LINKED )
+	{
+	//	RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
+
+		//
+		// Check whether Short GI is enabled
+		//
+		bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
+			(!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
+
+
+		pra->upper_rssi_threshold_ratr =
+				(pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+
+		pra->middle_rssi_threshold_ratr =
+				(pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			pra->low_rssi_threshold_ratr =
+				(pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+		}
+		else
+		{
+			pra->low_rssi_threshold_ratr =
+			(pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+		}
+		//cosa add for test
+		pra->ping_rssi_ratr =
+				(pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
+
+		/* 2007/10/08 MH We support RA smooth scheme now. When it is the first
+		   time to link with AP. We will not change upper/lower threshold. If
+		   STA stay in high or low level, we must change two different threshold
+		   to prevent jumping frequently. */
+		if (pra->ratr_state == DM_RATR_STA_HIGH)
+		{
+			HighRSSIThreshForRA 	= pra->high2low_rssi_thresh_for_ra;
+			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
+		}
+		else if (pra->ratr_state == DM_RATR_STA_LOW)
+		{
+			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
+			LowRSSIThreshForRA 	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+					(pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
+		}
+		else
+		{
+			HighRSSIThreshForRA	= pra->high_rssi_thresh_for_ra;
+			LowRSSIThreshForRA	= (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
+					(pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
+		}
+
+		//DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
+		if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
+		{
+			//DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
+			pra->ratr_state = DM_RATR_STA_HIGH;
+			targetRATR = pra->upper_rssi_threshold_ratr;
+		}else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
+		{
+			//DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);
+			pra->ratr_state = DM_RATR_STA_MIDDLE;
+			targetRATR = pra->middle_rssi_threshold_ratr;
+		}else
+		{
+			//DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);
+			pra->ratr_state = DM_RATR_STA_LOW;
+			targetRATR = pra->low_rssi_threshold_ratr;
+		}
+
+			//cosa add for test
+		if(pra->ping_rssi_enable)
+		{
+			//pHalData->UndecoratedSmoothedPWDB = 19;
+			if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
+			{
+				if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
+					ping_rssi_state )
+				{
+					//DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);
+					pra->ratr_state = DM_RATR_STA_LOW;
+					targetRATR = pra->ping_rssi_ratr;
+					ping_rssi_state = 1;
+				}
+				//else
+				//	DbgPrint("TestRSSI is between the range. \n");
+			}
+			else
+			{
+				//DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR);
+				ping_rssi_state = 0;
+			}
+		}
+
+		// 2008.04.01
+#if 1
+		// For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
+		if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
+			targetRATR &=  0xf00fffff;
+#endif
+
+		//
+		// Check whether updating of RATR0 is required
+		//
+		currentRATR = read_nic_dword(dev, RATR0);
+		if( targetRATR !=  currentRATR )
+		{
+			u32 ratr_value;
+			ratr_value = targetRATR;
+			RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
+			if(priv->rf_type == RF_1T2R)
+			{
+				ratr_value &= ~(RATE_ALL_OFDM_2SS);
+			}
+			write_nic_dword(dev, RATR0, ratr_value);
+			write_nic_byte(dev, UFWP, 1);
+
+			pra->last_ratr = targetRATR;
+		}
+
+	}
+	else
+	{
+		pra->ratr_state = DM_RATR_STA_MAX;
+	}
+
+}	// dm_CheckRateAdaptive
+
+
+static void dm_init_bandwidth_autoswitch(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
+	priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
+	priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
+	priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
+
+}	// dm_init_bandwidth_autoswitch
+
+
+static void dm_bandwidth_autoswitch(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
+		return;
+	}else{
+		if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
+			if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
+				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
+		}else{//in force send packets in 20 Mhz in 20/40
+			if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
+				priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
+
+		}
+	}
+}	// dm_BandwidthAutoSwitch
+
+//OFDM default at 0db, index=6.
+#ifndef RTL8190P
+static u32 OFDMSwingTable[OFDM_Table_Length] = {
+	0x7f8001fe,	// 0, +6db
+	0x71c001c7,	// 1, +5db
+	0x65400195,	// 2, +4db
+	0x5a400169,	// 3, +3db
+	0x50800142,	// 4, +2db
+	0x47c0011f,	// 5, +1db
+	0x40000100,	// 6, +0db ===> default, upper for higher temprature, lower for low temprature
+	0x390000e4,	// 7, -1db
+	0x32c000cb,	// 8, -2db
+	0x2d4000b5,	// 9, -3db
+	0x288000a2,	// 10, -4db
+	0x24000090,	// 11, -5db
+	0x20000080,	// 12, -6db
+	0x1c800072,	// 13, -7db
+	0x19800066,	// 14, -8db
+	0x26c0005b,	// 15, -9db
+	0x24400051,	// 16, -10db
+	0x12000048,	// 17, -11db
+	0x10000040	// 18, -12db
+};
+static u8	CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
+	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},	// 0, +0db ===> CCK40M default
+	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},	// 1, -1db
+	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},	// 2, -2db
+	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},	// 3, -3db
+	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},	// 4, -4db
+	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},	// 5, -5db
+	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},	// 6, -6db ===> CCK20M default
+	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},	// 7, -7db
+	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},	// 8, -8db
+	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},	// 9, -9db
+	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},	// 10, -10db
+	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}	// 11, -11db
+};
+
+static u8	CCKSwingTable_Ch14[CCK_Table_length][8] = {
+	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},	// 0, +0db  ===> CCK40M default
+	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},	// 1, -1db
+	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},	// 2, -2db
+	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},	// 3, -3db
+	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},	// 4, -4db
+	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},	// 5, -5db
+	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},	// 6, -6db  ===> CCK20M default
+	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},	// 7, -7db
+	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},	// 8, -8db
+	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},	// 9, -9db
+	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},	// 10, -10db
+	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}	// 11, -11db
+};
+#endif
+#define		Pw_Track_Flag				0x11d
+#define		Tssi_Mea_Value				0x13c
+#define		Tssi_Report_Value1			0x134
+#define		Tssi_Report_Value2			0x13e
+#define		FW_Busy_Flag				0x13f
+static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev)
+	{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	bool						bHighpowerstate, viviflag = FALSE;
+	DCMD_TXCMD_T			tx_cmd;
+	u8					powerlevelOFDM24G;
+	int	    				i =0, j = 0, k = 0;
+	u8						RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
+	u32						Value;
+	u8						Pwr_Flag;
+	u16					Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
+#ifdef RTL8192U
+	RT_STATUS 				rtStatus = RT_STATUS_SUCCESS;
+#endif
+//	bool rtStatus = true;
+	u32						delta=0;
+	RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
+//	write_nic_byte(dev, 0x1ba, 0);
+	write_nic_byte(dev, Pw_Track_Flag, 0);
+	write_nic_byte(dev, FW_Busy_Flag, 0);
+	priv->ieee80211->bdynamic_txpower_enable = false;
+	bHighpowerstate = priv->bDynamicTxHighPower;
+
+	powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
+	RF_Type = priv->rf_type;
+	Value = (RF_Type<<8) | powerlevelOFDM24G;
+
+	RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
+
+	for(j = 0; j<=30; j++)
+{	//fill tx_cmd
+
+	tx_cmd.Op		= TXCMD_SET_TX_PWR_TRACKING;
+	tx_cmd.Length	= 4;
+	tx_cmd.Value		= Value;
+#ifdef RTL8192U
+	rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
+	if (rtStatus == RT_STATUS_FAILURE)
+	{
+		RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
+	}
+#else
+	cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
+#endif
+	mdelay(1);
+	//DbgPrint("hi, vivi, strange\n");
+	for(i = 0;i <= 30; i++)
+	{
+		Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag);
+
+		if (Pwr_Flag == 0)
+		{
+			mdelay(1);
+			continue;
+		}
+
+		Avg_TSSI_Meas = read_nic_word(dev, Tssi_Mea_Value);
+
+		if(Avg_TSSI_Meas == 0)
+		{
+			write_nic_byte(dev, Pw_Track_Flag, 0);
+			write_nic_byte(dev, FW_Busy_Flag, 0);
+			return;
+		}
+
+		for(k = 0;k < 5; k++)
+		{
+			if(k !=4)
+				tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value1+k);
+			else
+				tmp_report[k] = read_nic_byte(dev, Tssi_Report_Value2);
+
+			RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
+		}
+
+		//check if the report value is right
+		for(k = 0;k < 5; k++)
+		{
+			if(tmp_report[k] <= 20)
+			{
+				viviflag =TRUE;
+				break;
+			}
+		}
+		if(viviflag ==TRUE)
+		{
+			write_nic_byte(dev, Pw_Track_Flag, 0);
+			viviflag = FALSE;
+			RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
+			for(k = 0;k < 5; k++)
+				tmp_report[k] = 0;
+			break;
+		}
+
+		for(k = 0;k < 5; k++)
+		{
+			Avg_TSSI_Meas_from_driver += tmp_report[k];
+		}
+
+		Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
+		RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
+		TSSI_13dBm = priv->TSSI_13dBm;
+		RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
+
+		//if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
+		// For MacOS-compatible
+		if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
+			delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
+		else
+			delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
+
+		if(delta <= E_FOR_TX_POWER_TRACK)
+		{
+			priv->ieee80211->bdynamic_txpower_enable = TRUE;
+			write_nic_byte(dev, Pw_Track_Flag, 0);
+			write_nic_byte(dev, FW_Busy_Flag, 0);
+			RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
+#ifdef RTL8190P
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
+#endif
+			RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
+			RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
+			return;
+		}
+		else
+		{
+			if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
+			{
+				if (RF_Type == RF_2T4R)
+				{
+
+						if((priv->rfa_txpowertrackingindex > 0) &&(priv->rfc_txpowertrackingindex > 0))
+				{
+					priv->rfa_txpowertrackingindex--;
+					if(priv->rfa_txpowertrackingindex_real > 4)
+					{
+						priv->rfa_txpowertrackingindex_real--;
+						rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
+					}
+
+					priv->rfc_txpowertrackingindex--;
+					if(priv->rfc_txpowertrackingindex_real > 4)
+					{
+						priv->rfc_txpowertrackingindex_real--;
+						rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
+					}
+						}
+						else
+						{
+								rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
+								rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
+				}
+			}
+			else
+			{
+						if(priv->rfc_txpowertrackingindex > 0)
+						{
+							priv->rfc_txpowertrackingindex--;
+							if(priv->rfc_txpowertrackingindex_real > 4)
+							{
+								priv->rfc_txpowertrackingindex_real--;
+								rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
+							}
+						}
+						else
+							rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
+				}
+			}
+			else
+			{
+				if (RF_Type == RF_2T4R)
+				{
+					if((priv->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&(priv->rfc_txpowertrackingindex < TxBBGainTableLength - 1))
+				{
+					priv->rfa_txpowertrackingindex++;
+					priv->rfa_txpowertrackingindex_real++;
+					rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
+					priv->rfc_txpowertrackingindex++;
+					priv->rfc_txpowertrackingindex_real++;
+					rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
+				}
+					else
+					{
+						rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
+						rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
+			}
+				}
+				else
+				{
+					if(priv->rfc_txpowertrackingindex < (TxBBGainTableLength - 1))
+					{
+							priv->rfc_txpowertrackingindex++;
+							priv->rfc_txpowertrackingindex_real++;
+							rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
+					}
+					else
+							rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
+				}
+			}
+			if (RF_Type == RF_2T4R)
+			priv->CCKPresentAttentuation_difference
+				= priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
+			else
+				priv->CCKPresentAttentuation_difference
+					= priv->rfc_txpowertrackingindex - priv->rfc_txpowertracking_default;
+
+			if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
+				priv->CCKPresentAttentuation
+				= priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference;
+			else
+				priv->CCKPresentAttentuation
+				= priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference;
+
+			if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
+					priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
+			if(priv->CCKPresentAttentuation < 0)
+					priv->CCKPresentAttentuation = 0;
+
+			if(1)
+			{
+				if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
+				{
+					priv->bcck_in_ch14 = TRUE;
+					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+				}
+				else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
+				{
+					priv->bcck_in_ch14 = FALSE;
+					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+				}
+				else
+					dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
+#ifdef RTL8190P
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
+#endif
+		RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
+		RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
+
+		if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24)
+		{
+			priv->ieee80211->bdynamic_txpower_enable = TRUE;
+			write_nic_byte(dev, Pw_Track_Flag, 0);
+			write_nic_byte(dev, FW_Busy_Flag, 0);
+			RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
+			return;
+		}
+
+
+	}
+		write_nic_byte(dev, Pw_Track_Flag, 0);
+		Avg_TSSI_Meas_from_driver = 0;
+		for(k = 0;k < 5; k++)
+			tmp_report[k] = 0;
+		break;
+	}
+	write_nic_byte(dev, FW_Busy_Flag, 0);
+}
+		priv->ieee80211->bdynamic_txpower_enable = TRUE;
+		write_nic_byte(dev, Pw_Track_Flag, 0);
+}
+#ifndef RTL8190P
+static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
+{
+#define ThermalMeterVal	9
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 tmpRegA, TempCCk;
+	u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
+	int i =0, CCKSwingNeedUpdate=0;
+
+	if(!priv->btxpower_trackingInit)
+	{
+		//Query OFDM default setting
+		tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
+		for(i=0; i<OFDM_Table_Length; i++)	//find the index
+		{
+			if(tmpRegA == OFDMSwingTable[i])
+			{
+				priv->OFDM_index= (u8)i;
+				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
+					rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
+			}
+		}
+
+		//Query CCK default setting From 0xa22
+		TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
+		for(i=0 ; i<CCK_Table_length ; i++)
+		{
+			if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
+			{
+				priv->CCK_index =(u8) i;
+				RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
+					rCCK0_TxFilter1, TempCCk, priv->CCK_index);
+		break;
+	}
+}
+		priv->btxpower_trackingInit = TRUE;
+		//pHalData->TXPowercount = 0;
+		return;
+	}
+
+	// read and filter out unreasonable value
+	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);	// 0x12: RF Reg[10:7]
+	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
+	if(tmpRegA < 3 || tmpRegA > 13)
+		return;
+	if(tmpRegA >= 12)	// if over 12, TP will be bad when high temprature
+		tmpRegA = 12;
+	RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
+	priv->ThermalMeter[0] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
+	priv->ThermalMeter[1] = ThermalMeterVal;	//We use fixed value by Bryant's suggestion
+
+	//Get current RF-A temprature index
+	if(priv->ThermalMeter[0] >= (u8)tmpRegA)	//lower temprature
+	{
+		tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
+		tmpCCK40Mindex = tmpCCK20Mindex - 6;
+		if(tmpOFDMindex >= OFDM_Table_Length)
+			tmpOFDMindex = OFDM_Table_Length-1;
+		if(tmpCCK20Mindex >= CCK_Table_length)
+			tmpCCK20Mindex = CCK_Table_length-1;
+		if(tmpCCK40Mindex >= CCK_Table_length)
+			tmpCCK40Mindex = CCK_Table_length-1;
+	}
+	else
+	{
+		tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
+		if(tmpval >= 6)								// higher temprature
+			tmpOFDMindex = tmpCCK20Mindex = 0;		// max to +6dB
+		else
+			tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
+		tmpCCK40Mindex = 0;
+	}
+	//DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
+		//((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
+		//tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);
+	if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)	//40M
+		tmpCCKindex = tmpCCK40Mindex;
+	else
+		tmpCCKindex = tmpCCK20Mindex;
+
+	//record for bandwidth swith
+	priv->Record_CCK_20Mindex = tmpCCK20Mindex;
+	priv->Record_CCK_40Mindex = tmpCCK40Mindex;
+	RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
+		priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
+
+	if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
+	{
+		priv->bcck_in_ch14 = TRUE;
+		CCKSwingNeedUpdate = 1;
+	}
+	else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
+	{
+		priv->bcck_in_ch14 = FALSE;
+		CCKSwingNeedUpdate = 1;
+	}
+
+	if(priv->CCK_index != tmpCCKindex)
+{
+		priv->CCK_index = tmpCCKindex;
+		CCKSwingNeedUpdate = 1;
+	}
+
+	if(CCKSwingNeedUpdate)
+	{
+		//DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);
+		dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
+	}
+	if(priv->OFDM_index != tmpOFDMindex)
+	{
+		priv->OFDM_index = tmpOFDMindex;
+		rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
+		RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
+			priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
+	}
+	priv->txpower_count = 0;
+}
+#endif
+void dm_txpower_trackingcallback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
+       struct net_device *dev = priv->ieee80211->dev;
+
+#ifdef RTL8190P
+	dm_TXPowerTrackingCallback_TSSI(dev);
+#else
+	//if(priv->bDcut == TRUE)
+	if(priv->IC_Cut >= IC_VersionCut_D)
+		dm_TXPowerTrackingCallback_TSSI(dev);
+	else
+		dm_TXPowerTrackingCallback_ThermalMeter(dev);
+#endif
+}
+
+
+static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//Initial the Tx BB index and mapping value
+	priv->txbbgain_table[0].txbb_iq_amplifygain = 	 		12;
+	priv->txbbgain_table[0].txbbgain_value=0x7f8001fe;
+	priv->txbbgain_table[1].txbb_iq_amplifygain = 	 		11;
+	priv->txbbgain_table[1].txbbgain_value=0x788001e2;
+	priv->txbbgain_table[2].txbb_iq_amplifygain = 	 		10;
+	priv->txbbgain_table[2].txbbgain_value=0x71c001c7;
+	priv->txbbgain_table[3].txbb_iq_amplifygain = 	 		9;
+	priv->txbbgain_table[3].txbbgain_value=0x6b8001ae;
+	priv->txbbgain_table[4].txbb_iq_amplifygain = 		       8;
+	priv->txbbgain_table[4].txbbgain_value=0x65400195;
+	priv->txbbgain_table[5].txbb_iq_amplifygain = 		       7;
+	priv->txbbgain_table[5].txbbgain_value=0x5fc0017f;
+	priv->txbbgain_table[6].txbb_iq_amplifygain = 		       6;
+	priv->txbbgain_table[6].txbbgain_value=0x5a400169;
+	priv->txbbgain_table[7].txbb_iq_amplifygain = 		       5;
+	priv->txbbgain_table[7].txbbgain_value=0x55400155;
+	priv->txbbgain_table[8].txbb_iq_amplifygain = 		       4;
+	priv->txbbgain_table[8].txbbgain_value=0x50800142;
+	priv->txbbgain_table[9].txbb_iq_amplifygain = 		       3;
+	priv->txbbgain_table[9].txbbgain_value=0x4c000130;
+	priv->txbbgain_table[10].txbb_iq_amplifygain = 		       2;
+	priv->txbbgain_table[10].txbbgain_value=0x47c0011f;
+	priv->txbbgain_table[11].txbb_iq_amplifygain = 		       1;
+	priv->txbbgain_table[11].txbbgain_value=0x43c0010f;
+	priv->txbbgain_table[12].txbb_iq_amplifygain = 		       0;
+	priv->txbbgain_table[12].txbbgain_value=0x40000100;
+	priv->txbbgain_table[13].txbb_iq_amplifygain = 		       -1;
+	priv->txbbgain_table[13].txbbgain_value=0x3c8000f2;
+	priv->txbbgain_table[14].txbb_iq_amplifygain = 		     -2;
+	priv->txbbgain_table[14].txbbgain_value=0x390000e4;
+	priv->txbbgain_table[15].txbb_iq_amplifygain = 		     -3;
+	priv->txbbgain_table[15].txbbgain_value=0x35c000d7;
+	priv->txbbgain_table[16].txbb_iq_amplifygain = 		     -4;
+	priv->txbbgain_table[16].txbbgain_value=0x32c000cb;
+	priv->txbbgain_table[17].txbb_iq_amplifygain = 		     -5;
+	priv->txbbgain_table[17].txbbgain_value=0x300000c0;
+	priv->txbbgain_table[18].txbb_iq_amplifygain = 		 	    -6;
+	priv->txbbgain_table[18].txbbgain_value=0x2d4000b5;
+	priv->txbbgain_table[19].txbb_iq_amplifygain = 		     -7;
+	priv->txbbgain_table[19].txbbgain_value=0x2ac000ab;
+	priv->txbbgain_table[20].txbb_iq_amplifygain = 		     -8;
+	priv->txbbgain_table[20].txbbgain_value=0x288000a2;
+	priv->txbbgain_table[21].txbb_iq_amplifygain = 		     -9;
+	priv->txbbgain_table[21].txbbgain_value=0x26000098;
+	priv->txbbgain_table[22].txbb_iq_amplifygain = 		     -10;
+	priv->txbbgain_table[22].txbbgain_value=0x24000090;
+	priv->txbbgain_table[23].txbb_iq_amplifygain = 		     -11;
+	priv->txbbgain_table[23].txbbgain_value=0x22000088;
+	priv->txbbgain_table[24].txbb_iq_amplifygain = 		     -12;
+	priv->txbbgain_table[24].txbbgain_value=0x20000080;
+	priv->txbbgain_table[25].txbb_iq_amplifygain = 		     -13;
+	priv->txbbgain_table[25].txbbgain_value=0x1a00006c;
+	priv->txbbgain_table[26].txbb_iq_amplifygain = 		     -14;
+	priv->txbbgain_table[26].txbbgain_value=0x1c800072;
+	priv->txbbgain_table[27].txbb_iq_amplifygain = 		     -15;
+	priv->txbbgain_table[27].txbbgain_value=0x18000060;
+	priv->txbbgain_table[28].txbb_iq_amplifygain = 		     -16;
+	priv->txbbgain_table[28].txbbgain_value=0x19800066;
+	priv->txbbgain_table[29].txbb_iq_amplifygain = 		     -17;
+	priv->txbbgain_table[29].txbbgain_value=0x15800056;
+	priv->txbbgain_table[30].txbb_iq_amplifygain = 		     -18;
+	priv->txbbgain_table[30].txbbgain_value=0x26c0005b;
+	priv->txbbgain_table[31].txbb_iq_amplifygain = 		     -19;
+	priv->txbbgain_table[31].txbbgain_value=0x14400051;
+	priv->txbbgain_table[32].txbb_iq_amplifygain = 		     -20;
+	priv->txbbgain_table[32].txbbgain_value=0x24400051;
+	priv->txbbgain_table[33].txbb_iq_amplifygain = 		     -21;
+	priv->txbbgain_table[33].txbbgain_value=0x1300004c;
+	priv->txbbgain_table[34].txbb_iq_amplifygain = 		     -22;
+	priv->txbbgain_table[34].txbbgain_value=0x12000048;
+	priv->txbbgain_table[35].txbb_iq_amplifygain = 		     -23;
+	priv->txbbgain_table[35].txbbgain_value=0x11000044;
+	priv->txbbgain_table[36].txbb_iq_amplifygain = 		     -24;
+	priv->txbbgain_table[36].txbbgain_value=0x10000040;
+
+	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
+	//This Table is for CH1~CH13
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
+	priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
+
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
+	priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
+
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
+	priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
+	priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
+	priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
+	priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
+	priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
+	priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
+
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
+	priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
+	priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
+	priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
+	priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
+	priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
+
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
+
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
+	priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
+
+	//ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
+	//This Table is for CH14
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
+
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
+	priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
+
+	priv->btxpower_tracking = TRUE;
+	priv->txpower_count       = 0;
+	priv->btxpower_trackingInit = FALSE;
+
+}
+#ifndef RTL8190P
+static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism
+	// can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
+	// 3-wire by driver cause RF goes into wrong state.
+	if(priv->ieee80211->FwRWRF)
+		priv->btxpower_tracking = TRUE;
+	else
+		priv->btxpower_tracking = FALSE;
+	priv->txpower_count       = 0;
+	priv->btxpower_trackingInit = FALSE;
+}
+#endif
+
+void dm_initialize_txpower_tracking(struct net_device *dev)
+{
+#ifndef RTL8190P
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#endif
+#ifdef RTL8190P
+	dm_InitializeTXPowerTracking_TSSI(dev);
+#else
+	//if(priv->bDcut == TRUE)
+	if(priv->IC_Cut >= IC_VersionCut_D)
+		dm_InitializeTXPowerTracking_TSSI(dev);
+	else
+		dm_InitializeTXPowerTracking_ThermalMeter(dev);
+#endif
+}	// dm_InitializeTXPowerTracking
+
+
+static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u32 tx_power_track_counter = 0;
+	RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
+	if(read_nic_byte(dev, 0x11e) ==1)
+		return;
+	if(!priv->btxpower_tracking)
+		return;
+	tx_power_track_counter++;
+
+
+	 if(tx_power_track_counter > 90)
+	 	{
+				queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
+		tx_power_track_counter =0;
+	 	}
+
+}
+
+#ifndef RTL8190P
+static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u8 	TM_Trigger=0;
+
+	//DbgPrint("dm_CheckTXPowerTracking() \n");
+	if(!priv->btxpower_tracking)
+		return;
+	else
+	{
+		if(priv->txpower_count  <= 2)
+		{
+			priv->txpower_count++;
+			return;
+		}
+	}
+
+	if(!TM_Trigger)
+	{
+		//Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
+		//actually write reg0x02 bit1=0, then bit1=1.
+		//DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
+		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
+		TM_Trigger = 1;
+		return;
+	}
+	else
+		{
+		//DbgPrint("Schedule TxPowerTrackingWorkItem\n");
+			queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
+		TM_Trigger = 0;
+		}
+}
+#endif
+
+static void dm_check_txpower_tracking(struct net_device *dev)
+{
+#ifndef RTL8190P
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//static u32 tx_power_track_counter = 0;
+#endif
+#ifdef  RTL8190P
+	dm_CheckTXPowerTracking_TSSI(dev);
+#else
+	//if(priv->bDcut == TRUE)
+	if(priv->IC_Cut >= IC_VersionCut_D)
+		dm_CheckTXPowerTracking_TSSI(dev);
+	else
+		dm_CheckTXPowerTracking_ThermalMeter(dev);
+#endif
+
+}	// dm_CheckTXPowerTracking
+
+
+static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
+{
+	u32 TempVal;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//Write 0xa22 0xa23
+	TempVal = 0;
+	if(!bInCH14){
+		//Write 0xa22 0xa23
+		TempVal = 	(u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
+					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
+
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	(u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
+					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
+					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
+					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	(u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
+					(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
+	}
+	else
+	{
+		TempVal = 	(u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
+					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
+
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	(u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
+					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
+					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
+					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	(u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
+					(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
+	}
+
+
+}
+#ifndef RTL8190P
+static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,	bool  bInCH14)
+{
+	u32 TempVal;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	TempVal = 0;
+	if(!bInCH14)
+	{
+		//Write 0xa22 0xa23
+		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter1, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter2, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
+					(CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_DebugPort, TempVal);
+	}
+	else
+	{
+//		priv->CCKTxPowerAdjustCntNotCh14++;	//cosa add for debug.
+		//Write 0xa22 0xa23
+		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][0] +
+					(CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter1, TempVal);
+		//Write 0xa24 ~ 0xa27
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][2] +
+					(CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
+					(CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
+					(CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
+		rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_TxFilter2, TempVal);
+		//Write 0xa28  0xa29
+		TempVal = 0;
+		TempVal = 	CCKSwingTable_Ch14[priv->CCK_index][6] +
+					(CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
+
+		rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
+		RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
+			rCCK0_DebugPort, TempVal);
+	}
+	}
+#endif
+
+
+void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
+{	// dm_CCKTxPowerAdjust
+#ifndef RTL8190P
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#endif
+#ifdef RTL8190P
+	dm_CCKTxPowerAdjust_TSSI(dev, binch14);
+#else
+	//if(priv->bDcut == TRUE)
+	if(priv->IC_Cut >= IC_VersionCut_D)
+		dm_CCKTxPowerAdjust_TSSI(dev, binch14);
+	else
+		dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
+#endif
+}
+
+
+#ifndef  RTL8192U
+static void dm_txpower_reset_recovery(
+	struct net_device *dev
+)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
+	rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->CCKPresentAttentuation);
+	dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+
+	rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex);
+	RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
+
+}	// dm_TXPowerResetRecovery
+
+void dm_restore_dynamic_mechanism_state(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 	reg_ratr = priv->rate_adaptive.last_ratr;
+
+	if(!priv->up)
+	{
+		RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
+		return;
+	}
+
+	//
+	// Restore previous state for rate adaptive
+	//
+	if(priv->rate_adaptive.rate_adaptive_disabled)
+		return;
+	// TODO: Only 11n mode is implemented currently,
+	if( !(priv->ieee80211->mode==WIRELESS_MODE_N_24G ||
+		 priv->ieee80211->mode==WIRELESS_MODE_N_5G))
+		 return;
+	{
+			/* 2007/11/15 MH Copy from 8190PCI. */
+			u32 ratr_value;
+			ratr_value = reg_ratr;
+			if(priv->rf_type == RF_1T2R)	// 1T2R, Spatial Stream 2 should be disabled
+			{
+				ratr_value &=~ (RATE_ALL_OFDM_2SS);
+				//DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);
+			}
+			//DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);
+			//cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);
+			write_nic_dword(dev, RATR0, ratr_value);
+			write_nic_byte(dev, UFWP, 1);
+	}
+	//Resore TX Power Tracking Index
+	if(priv->btxpower_trackingInit && priv->btxpower_tracking){
+		dm_txpower_reset_recovery(dev);
+	}
+
+	//
+	//Restore BB Initial Gain
+	//
+	dm_bb_initialgain_restore(dev);
+
+}	// DM_RestoreDynamicMechanismState
+
+static void dm_bb_initialgain_restore(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 bit_mask = 0x7f; //Bit0~ Bit6
+
+	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+		return;
+
+	//Disable Initial Gain
+	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+	rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
+	rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
+	rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
+	rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
+	bit_mask  = bMaskByte2;
+	rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
+
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+	RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
+	//Enable Initial Gain
+	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+
+}	// dm_BBInitialGainRestore
+
+
+void dm_backup_dynamic_mechanism_state(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// Fsync to avoid reset
+	priv->bswitch_fsync  = false;
+	priv->bfsync_processing = false;
+	//Backup BB InitialGain
+	dm_bb_initialgain_backup(dev);
+
+}	// DM_BackupDynamicMechanismState
+
+
+static void dm_bb_initialgain_backup(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 bit_mask = bMaskByte0; //Bit0~ Bit6
+
+	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+		return;
+
+	//PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
+	rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+	priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
+	priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
+	priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
+	priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
+	bit_mask  = bMaskByte2;
+	priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
+
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+	RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
+
+}   // dm_BBInitialGainBakcup
+
+#endif
+/*-----------------------------------------------------------------------------
+ * Function:	dm_change_dynamic_initgain_thresh()
+ *
+ * Overview:
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/29/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type, u32	dm_value)
+{
+	if (dm_type == DIG_TYPE_THRESH_HIGH)
+	{
+		dm_digtable.rssi_high_thresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_THRESH_LOW)
+	{
+		dm_digtable.rssi_low_thresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
+	{
+		dm_digtable.rssi_high_power_highthresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
+	{
+		dm_digtable.rssi_high_power_highthresh = dm_value;
+	}
+	else if (dm_type == DIG_TYPE_ENABLE)
+	{
+		dm_digtable.dig_state		= DM_STA_DIG_MAX;
+		dm_digtable.dig_enable_flag	= true;
+	}
+	else if (dm_type == DIG_TYPE_DISABLE)
+	{
+		dm_digtable.dig_state		= DM_STA_DIG_MAX;
+		dm_digtable.dig_enable_flag	= false;
+	}
+	else if (dm_type == DIG_TYPE_DBG_MODE)
+	{
+		if(dm_value >= DM_DBG_MAX)
+			dm_value = DM_DBG_OFF;
+		dm_digtable.dbg_mode		= (u8)dm_value;
+	}
+	else if (dm_type == DIG_TYPE_RSSI)
+	{
+		if(dm_value > 100)
+			dm_value = 30;
+		dm_digtable.rssi_val			= (long)dm_value;
+	}
+	else if (dm_type == DIG_TYPE_ALGORITHM)
+	{
+		if (dm_value >= DIG_ALGO_MAX)
+			dm_value = DIG_ALGO_BY_FALSE_ALARM;
+		if(dm_digtable.dig_algorithm != (u8)dm_value)
+			dm_digtable.dig_algorithm_switch = 1;
+		dm_digtable.dig_algorithm	= (u8)dm_value;
+	}
+	else if (dm_type == DIG_TYPE_BACKOFF)
+	{
+		if(dm_value > 30)
+			dm_value = 30;
+		dm_digtable.backoff_val		= (u8)dm_value;
+	}
+	else if(dm_type == DIG_TYPE_RX_GAIN_MIN)
+	{
+		if(dm_value == 0)
+			dm_value = 0x1;
+		dm_digtable.rx_gain_range_min = (u8)dm_value;
+	}
+	else if(dm_type == DIG_TYPE_RX_GAIN_MAX)
+	{
+		if(dm_value > 0x50)
+			dm_value = 0x50;
+		dm_digtable.rx_gain_range_max = (u8)dm_value;
+	}
+}	/* DM_ChangeDynamicInitGainThresh */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_dig_init()
+ *
+ * Overview:	Set DIG scheme init value.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/15/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_dig_init(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	/* 2007/10/05 MH Disable DIG scheme now. Not tested. */
+	dm_digtable.dig_enable_flag	= true;
+	dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
+	dm_digtable.dbg_mode = DM_DBG_OFF;	//off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
+	dm_digtable.dig_algorithm_switch = 0;
+
+	/* 2007/10/04 MH Define init gain threshol. */
+	dm_digtable.dig_state		= DM_STA_DIG_MAX;
+	dm_digtable.dig_highpwr_state	= DM_STA_DIG_MAX;
+	dm_digtable.initialgain_lowerbound_state = false;
+
+	dm_digtable.rssi_low_thresh 	= DM_DIG_THRESH_LOW;
+	dm_digtable.rssi_high_thresh 	= DM_DIG_THRESH_HIGH;
+
+	dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
+	dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
+
+	dm_digtable.rssi_val = 50;	//for new dig debug rssi value
+	dm_digtable.backoff_val = DM_DIG_BACKOFF;
+	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
+	if(priv->CustomerID == RT_CID_819x_Netcore)
+		dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
+	else
+		dm_digtable.rx_gain_range_min = DM_DIG_MIN;
+
+}	/* dm_dig_init */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_ctrl_initgain_byrssi()
+ *
+ * Overview:	Driver must monitor RSSI and notify firmware to change initial
+ *				gain according to different threshold. BB team provide the
+ *				suggested solution.
+ *
+ * Input:			struct net_device *dev
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/27/2008	amy		Create Version 0 porting from windows code.
+ *---------------------------------------------------------------------------*/
+static void dm_ctrl_initgain_byrssi(struct net_device *dev)
+{
+
+	if (dm_digtable.dig_enable_flag == false)
+		return;
+
+	if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+		dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
+	else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
+		dm_ctrl_initgain_byrssi_by_driverrssi(dev);
+	else
+		return;
+}
+
+
+static void dm_ctrl_initgain_byrssi_by_driverrssi(
+	struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 i;
+	static u8 	fw_dig=0;
+
+	if (dm_digtable.dig_enable_flag == false)
+		return;
+
+	//DbgPrint("Dig by Sw Rssi \n");
+	if(dm_digtable.dig_algorithm_switch)	// if swithed algorithm, we have to disable FW Dig.
+		fw_dig = 0;
+	if(fw_dig <= 3)	// execute several times to make sure the FW Dig is disabled
+	{// FW DIG Off
+		for(i=0; i<3; i++)
+			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+		fw_dig++;
+		dm_digtable.dig_state = DM_STA_DIG_OFF;	//fw dig off.
+	}
+
+	if(priv->ieee80211->state == IEEE80211_LINKED)
+		dm_digtable.cur_connect_state = DIG_CONNECT;
+	else
+		dm_digtable.cur_connect_state = DIG_DISCONNECT;
+
+	//DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n",
+		//DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);
+
+	if(dm_digtable.dbg_mode == DM_DBG_OFF)
+		dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
+	//DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val);
+	dm_initial_gain(dev);
+	dm_pd_th(dev);
+	dm_cs_ratio(dev);
+	if(dm_digtable.dig_algorithm_switch)
+		dm_digtable.dig_algorithm_switch = 0;
+	dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
+
+}	/* dm_CtrlInitGainByRssi */
+
+static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
+	struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u32 reset_cnt = 0;
+	u8 i;
+
+	if (dm_digtable.dig_enable_flag == false)
+		return;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		dm_digtable.dig_state = DM_STA_DIG_MAX;
+		// Fw DIG On.
+		for(i=0; i<3; i++)
+			rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+		dm_digtable.dig_algorithm_switch = 0;
+	}
+
+	if (priv->ieee80211->state != IEEE80211_LINKED)
+		return;
+
+	// For smooth, we can not change DIG state.
+	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
+		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
+	{
+		return;
+	}
+	//DbgPrint("Dig by Fw False Alarm\n");
+	//if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)
+	/*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
+	pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
+	DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
+	/* 1. When RSSI decrease, We have to judge if it is smaller than a treshold
+		  and then execute below step. */
+	if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
+	{
+		/* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
+		   will be reset to init value. We must prevent the condition. */
+		if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
+			(priv->reset_count == reset_cnt))
+		{
+			return;
+		}
+		else
+		{
+			reset_cnt = priv->reset_count;
+		}
+
+		// If DIG is off, DIG high power state must reset.
+		dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
+		dm_digtable.dig_state = DM_STA_DIG_OFF;
+
+		// 1.1 DIG Off.
+		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// Only clear byte 1 and rewrite.
+
+		// 1.2 Set initial gain.
+		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
+		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
+		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
+		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
+
+		// 1.3 Lower PD_TH for OFDM.
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+			#ifdef RTL8190P
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
+			#else
+				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
+				#endif
+			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+				write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
+			*/
+			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+
+
+			//else
+				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
+		}
+		else
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+
+		// 1.4 Lower CS ratio for CCK.
+		write_nic_byte(dev, 0xa0a, 0x08);
+
+		// 1.5 Higher EDCCA.
+		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
+		return;
+
+	}
+
+	/* 2. When RSSI increase, We have to judge if it is larger than a treshold
+		  and then execute below step.  */
+	if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
+	{
+		u8 reset_flag = 0;
+
+		if (dm_digtable.dig_state == DM_STA_DIG_ON &&
+			(priv->reset_count == reset_cnt))
+		{
+			dm_ctrl_initgain_byrssi_highpwr(dev);
+			return;
+		}
+		else
+		{
+			if (priv->reset_count != reset_cnt)
+				reset_flag = 1;
+
+			reset_cnt = priv->reset_count;
+		}
+
+		dm_digtable.dig_state = DM_STA_DIG_ON;
+		//DbgPrint("DIG ON\n\r");
+
+		// 2.1 Set initial gain.
+		// 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
+		if (reset_flag == 1)
+		{
+			write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
+			write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
+			write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
+			write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
+		}
+		else
+		{
+		write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
+		write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
+		write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
+		write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
+		}
+
+		// 2.2 Higher PD_TH for OFDM.
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+			#ifdef RTL8190P
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+			#else
+				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
+				#endif
+			/*
+			else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+			*/
+			//else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
+
+			//else
+				//PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
+		}
+		else
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
+
+		// 2.3 Higher CS ratio for CCK.
+		write_nic_byte(dev, 0xa0a, 0xcd);
+
+		// 2.4 Lower EDCCA.
+		/* 2008/01/11 MH 90/92 series are the same. */
+		//PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
+
+		// 2.5 DIG On.
+		rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// Only clear byte 1 and rewrite.
+
+	}
+
+	dm_ctrl_initgain_byrssi_highpwr(dev);
+
+}	/* dm_CtrlInitGainByRssi */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_ctrl_initgain_byrssi_highpwr()
+ *
+ * Overview:
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_ctrl_initgain_byrssi_highpwr(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u32 reset_cnt_highpwr = 0;
+
+	// For smooth, we can not change high power DIG state in the range.
+	if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
+		(priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
+	{
+		return;
+	}
+
+	/* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
+		  it is larger than a treshold and then execute below step.  */
+	// 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
+	if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
+	{
+		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
+			(priv->reset_count == reset_cnt_highpwr))
+			return;
+		else
+			dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
+
+		// 3.1 Higher PD_TH for OFDM for high power state.
+		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+		{
+			#ifdef RTL8190P
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+			#else
+				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
+				#endif
+
+			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+			*/
+
+		}
+		else
+			write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
+	}
+	else
+	{
+		if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
+			(priv->reset_count == reset_cnt_highpwr))
+			return;
+		else
+			dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
+
+		if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
+			 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
+		{
+			// 3.2 Recover PD_TH for OFDM for normal power region.
+			if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+			{
+				#ifdef RTL8190P
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+				#else
+					write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
+					#endif
+				/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+				*/
+
+			}
+			else
+				write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
+		}
+	}
+
+	reset_cnt_highpwr = priv->reset_count;
+
+}	/* dm_CtrlInitGainByRssiHighPwr */
+
+
+static void dm_initial_gain(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8					initial_gain=0;
+	static u8				initialized=0, force_write=0;
+	static u32			reset_cnt=0;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		initialized = 0;
+		reset_cnt = 0;
+	}
+
+	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
+	{
+		if(dm_digtable.cur_connect_state == DIG_CONNECT)
+		{
+			if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
+				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
+			else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
+				dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
+			else
+				dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
+		}
+		else		//current state is disconnected
+		{
+			if(dm_digtable.cur_ig_value == 0)
+				dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
+			else
+				dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
+		}
+	}
+	else	// disconnected -> connected or connected -> disconnected
+	{
+		dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
+		dm_digtable.pre_ig_value = 0;
+	}
+	//DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);
+
+	// if silent reset happened, we should rewrite the values back
+	if(priv->reset_count != reset_cnt)
+	{
+		force_write = 1;
+		reset_cnt = priv->reset_count;
+	}
+
+	if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
+		force_write = 1;
+
+	{
+		if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
+			|| !initialized || force_write)
+		{
+			initial_gain = (u8)dm_digtable.cur_ig_value;
+			//DbgPrint("Write initial gain = 0x%x\n", initial_gain);
+			// Set initial gain.
+			write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
+			write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
+			dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
+			initialized = 1;
+			force_write = 0;
+		}
+	}
+}
+
+static void dm_pd_th(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u8				initialized=0, force_write=0;
+	static u32			reset_cnt = 0;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		initialized = 0;
+		reset_cnt = 0;
+	}
+
+	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
+	{
+		if(dm_digtable.cur_connect_state == DIG_CONNECT)
+		{
+			if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
+				dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
+			else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
+				dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
+			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
+					(dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
+				dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
+			else
+				dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
+		}
+		else
+		{
+			dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
+		}
+	}
+	else	// disconnected -> connected or connected -> disconnected
+	{
+		dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
+	}
+
+	// if silent reset happened, we should rewrite the values back
+	if(priv->reset_count != reset_cnt)
+	{
+		force_write = 1;
+		reset_cnt = priv->reset_count;
+	}
+
+	{
+		if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
+			(initialized<=3) || force_write)
+		{
+			//DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);
+			if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
+			{
+				// Lower PD_TH for OFDM.
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+				{
+					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+					#ifdef RTL8190P
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
+					#else
+						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
+						#endif
+					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
+					*/
+				}
+				else
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+			}
+			else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
+			{
+				// Higher PD_TH for OFDM.
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+				{
+					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
+					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
+					#ifdef RTL8190P
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+					#else
+						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
+						#endif
+					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
+					*/
+				}
+				else
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
+			}
+			else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
+			{
+				// Higher PD_TH for OFDM for high power state.
+				if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
+				{
+					#ifdef RTL8190P
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+					#else
+						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
+						#endif
+					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
+						write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
+					*/
+				}
+				else
+					write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
+			}
+			dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
+			if(initialized <= 3)
+				initialized++;
+			force_write = 0;
+		}
+	}
+}
+
+static	void dm_cs_ratio(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	static u8				initialized=0,force_write=0;
+	static u32			reset_cnt = 0;
+
+	if(dm_digtable.dig_algorithm_switch)
+	{
+		initialized = 0;
+		reset_cnt = 0;
+	}
+
+	if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
+	{
+		if(dm_digtable.cur_connect_state == DIG_CONNECT)
+		{
+			if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
+				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
+			else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
+				dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
+			else
+				dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
+		}
+		else
+		{
+			dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
+		}
+	}
+	else	// disconnected -> connected or connected -> disconnected
+	{
+		dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
+	}
+
+	// if silent reset happened, we should rewrite the values back
+	if(priv->reset_count != reset_cnt)
+	{
+		force_write = 1;
+		reset_cnt = priv->reset_count;
+	}
+
+
+	{
+		if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
+			!initialized || force_write)
+		{
+			//DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
+			if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
+			{
+				// Lower CS ratio for CCK.
+				write_nic_byte(dev, 0xa0a, 0x08);
+			}
+			else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
+			{
+				// Higher CS ratio for CCK.
+				write_nic_byte(dev, 0xa0a, 0xcd);
+			}
+			dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
+			initialized = 1;
+			force_write = 0;
+		}
+	}
+}
+
+void dm_init_edca_turbo(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->bcurrent_turbo_EDCA = false;
+	priv->ieee80211->bis_any_nonbepkts = false;
+	priv->bis_cur_rdlstate = false;
+}	// dm_init_edca_turbo
+
+#if 1
+static void dm_check_edca_turbo(
+	struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	//PSTA_QOS			pStaQos = pMgntInfo->pStaQos;
+
+	// Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
+	static unsigned long			lastTxOkCnt = 0;
+	static unsigned long			lastRxOkCnt = 0;
+	unsigned long				curTxOkCnt = 0;
+	unsigned long				curRxOkCnt = 0;
+
+	//
+	// Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
+	// should follow the settings from QAP. By Bruce, 2007-12-07.
+	//
+	#if 1
+	if(priv->ieee80211->state != IEEE80211_LINKED)
+		goto dm_CheckEdcaTurbo_EXIT;
+	#endif
+	// We do not turn on EDCA turbo mode for some AP that has IOT issue
+	if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
+		goto dm_CheckEdcaTurbo_EXIT;
+
+//	printk("========>%s():bis_any_nonbepkts is %d\n",__FUNCTION__,priv->bis_any_nonbepkts);
+	// Check the status for current condition.
+	if(!priv->ieee80211->bis_any_nonbepkts)
+	{
+		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
+		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
+		// For RT-AP, we needs to turn it on when Rx>Tx
+		if(curRxOkCnt > 4*curTxOkCnt)
+		{
+			//printk("%s():curRxOkCnt > 4*curTxOkCnt\n");
+			if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
+			{
+				write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
+				priv->bis_cur_rdlstate = true;
+			}
+		}
+		else
+		{
+
+			//printk("%s():curRxOkCnt < 4*curTxOkCnt\n");
+			if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
+			{
+				write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
+				priv->bis_cur_rdlstate = false;
+			}
+
+		}
+
+		priv->bcurrent_turbo_EDCA = true;
+	}
+	else
+	{
+		//
+		// Turn Off EDCA turbo here.
+		// Restore original EDCA according to the declaration of AP.
+		//
+		 if(priv->bcurrent_turbo_EDCA)
+		{
+
+			{
+				u8		u1bAIFS;
+				u32		u4bAcParam;
+				struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
+				u8 mode = priv->ieee80211->mode;
+
+			// For Each time updating EDCA parameter, reset EDCA turbo mode status.
+				dm_init_edca_turbo(dev);
+				u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
+				u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
+					(((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
+					(((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
+					((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
+				printk("===>u4bAcParam:%x, ", u4bAcParam);
+			//write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
+				write_nic_dword(dev, EDCAPARA_BE,  u4bAcParam);
+
+			// Check ACM bit.
+			// If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
+				{
+			// TODO:  Modified this part and try to set acm control in only 1 IO processing!!
+
+					PACI_AIFSN	pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
+					u8		AcmCtrl = read_nic_byte( dev, AcmHwCtrl );
+					if( pAciAifsn->f.ACM )
+					{ // ACM bit is 1.
+						AcmCtrl |= AcmHw_BeqEn;
+					}
+					else
+					{ // ACM bit is 0.
+						AcmCtrl &= (~AcmHw_BeqEn);
+					}
+
+					RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
+					write_nic_byte(dev, AcmHwCtrl, AcmCtrl );
+				}
+			}
+			priv->bcurrent_turbo_EDCA = false;
+		}
+	}
+
+
+dm_CheckEdcaTurbo_EXIT:
+	// Set variables for next time.
+	priv->ieee80211->bis_any_nonbepkts = false;
+	lastTxOkCnt = priv->stats.txbytesunicast;
+	lastRxOkCnt = priv->stats.rxbytesunicast;
+}	// dm_CheckEdcaTurbo
+#endif
+
+static void dm_init_ctstoself(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+
+	priv->ieee80211->bCTSToSelfEnable = TRUE;
+	priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
+}
+
+static void dm_ctstoself(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
+	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
+	static unsigned long				lastTxOkCnt = 0;
+	static unsigned long				lastRxOkCnt = 0;
+	unsigned long						curTxOkCnt = 0;
+	unsigned long						curRxOkCnt = 0;
+
+	if(priv->ieee80211->bCTSToSelfEnable != TRUE)
+	{
+		pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
+		return;
+	}
+	/*
+	1. Uplink
+	2. Linksys350/Linksys300N
+	3. <50 disable, >55 enable
+	*/
+
+	if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
+	{
+		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
+		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
+		if(curRxOkCnt > 4*curTxOkCnt)	//downlink, disable CTS to self
+		{
+			pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
+			//DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");
+		}
+		else	//uplink
+		{
+		#if 1
+			pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
+		#else
+			if(priv->undecorated_smoothed_pwdb < priv->ieee80211->CTSToSelfTH)	// disable CTS to self
+			{
+				pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
+				//DbgPrint("dm_CTSToSelf() ==> CTS to self disabled\n");
+			}
+			else if(priv->undecorated_smoothed_pwdb >= (priv->ieee80211->CTSToSelfTH+5))	// enable CTS to self
+			{
+				pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
+				//DbgPrint("dm_CTSToSelf() ==> CTS to self enabled\n");
+			}
+		#endif
+		}
+
+		lastTxOkCnt = priv->stats.txbytesunicast;
+		lastRxOkCnt = priv->stats.rxbytesunicast;
+	}
+}
+
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_rfctrl_gpio()
+ *
+ * Overview:	Copy 8187B template for 9xseries.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+#if 1
+static void dm_check_rfctrl_gpio(struct net_device * dev)
+{
+#ifdef RTL8192E
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#endif
+
+	// Walk around for DTM test, we will not enable HW - radio on/off because r/w
+	// page 1 register before Lextra bus is enabled cause system fails when resuming
+	// from S4. 20080218, Emily
+
+	// Stop to execute workitem to prevent S3/S4 bug.
+#ifdef RTL8190P
+	return;
+#endif
+#ifdef RTL8192U
+	return;
+#endif
+#ifdef RTL8192E
+		queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
+#endif
+
+}	/* dm_CheckRfCtrlGPIO */
+
+#endif
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_pbc_gpio()
+ *
+ * Overview:	Check if PBC button is pressed.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy 	Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void	dm_check_pbc_gpio(struct net_device *dev)
+{
+#ifdef RTL8192U
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 tmp1byte;
+
+
+	tmp1byte = read_nic_byte(dev,GPI);
+	if(tmp1byte == 0xff)
+	return;
+
+	if (tmp1byte&BIT6 || tmp1byte&BIT0)
+	{
+		// Here we only set bPbcPressed to TRUE
+		// After trigger PBC, the variable will be set to FALSE
+		RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
+		priv->bpbc_pressed = true;
+	}
+#endif
+
+}
+
+#ifdef RTL8192E
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_GPIOChangeRF
+ * Overview:	PCI will not support workitem call back HW radio on-off control.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	02/21/2008	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+void dm_gpio_change_rf_callback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
+       struct net_device *dev = priv->ieee80211->dev;
+	u8 tmp1byte;
+	RT_RF_POWER_STATE	eRfPowerStateToSet;
+	bool bActuallySet = false;
+
+		bActuallySet=false;
+
+		if(!priv->up)
+		{
+		RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
+		}
+		else
+		{
+			// 0x108 GPIO input register is read only
+			//set 0x108 B1= 1: RF-ON; 0: RF-OFF.
+			tmp1byte = read_nic_byte(dev,GPI);
+
+			eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
+
+			if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
+			{
+			RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
+
+				priv->bHwRadioOff = false;
+				bActuallySet = true;
+			}
+			else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
+			{
+			RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
+				priv->bHwRadioOff = true;
+				bActuallySet = true;
+			}
+
+			if(bActuallySet)
+			{
+			priv->bHwRfOffAction = 1;
+				MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
+				//DrvIFIndicateCurrentPhyStatus(pAdapter);
+
+		}
+		else
+		{
+			msleep(2000);
+			}
+
+		}
+
+}	/* dm_GPIOChangeRF */
+
+#endif
+/*-----------------------------------------------------------------------------
+ * Function:	DM_RFPathCheckWorkItemCallBack()
+ *
+ * Overview:	Check if Current RF RX path is enabled
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	01/30/2008	MHC		Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
+{
+	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
+       struct net_device *dev =priv->ieee80211->dev;
+	//bool bactually_set = false;
+	u8 rfpath = 0, i;
+
+
+	/* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
+	   always be the same. We only read 0xc04 now. */
+	rfpath = read_nic_byte(dev, 0xc04);
+
+	// Check Bit 0-3, it means if RF A-D is enabled.
+	for (i = 0; i < RF90_PATH_MAX; i++)
+	{
+		if (rfpath & (0x01<<i))
+			priv->brfpath_rxenable[i] = 1;
+		else
+			priv->brfpath_rxenable[i] = 0;
+	}
+	if(!DM_RxPathSelTable.Enable)
+		return;
+
+	dm_rxpath_sel_byrssi(dev);
+}	/* DM_RFPathCheckWorkItemCallBack */
+
+static void dm_init_rxpath_selection(struct net_device * dev)
+{
+	u8 i;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	DM_RxPathSelTable.Enable = 1;	//default enabled
+	DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
+	DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
+	if(priv->CustomerID == RT_CID_819x_Netcore)
+		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
+	else
+		DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
+	DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
+	DM_RxPathSelTable.disabledRF = 0;
+	for(i=0; i<4; i++)
+	{
+		DM_RxPathSelTable.rf_rssi[i] = 50;
+		DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
+		DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
+	}
+}
+
+static void dm_rxpath_sel_byrssi(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8				i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
+	u8				tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
+	u8				cck_default_Rx=0x2;	//RF-C
+	u8				cck_optional_Rx=0x3;//RF-D
+	long				tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
+	u8				cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
+	u8				cur_rf_rssi;
+	long				cur_cck_pwdb;
+	static u8			disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
+	u8				update_cck_rx_path;
+
+	if(priv->rf_type != RF_2T4R)
+		return;
+
+	if(!cck_Rx_Path_initialized)
+	{
+		DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
+		cck_Rx_Path_initialized = 1;
+	}
+
+	DM_RxPathSelTable.disabledRF = 0xf;
+	DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04));
+
+	if(priv->ieee80211->mode == WIRELESS_MODE_B)
+	{
+		DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;	//pure B mode, fixed cck version2
+		//DbgPrint("Pure B mode, use cck rx version2 \n");
+	}
+
+	//decide max/sec/min rssi index
+	for (i=0; i<RF90_PATH_MAX; i++)
+	{
+		if(!DM_RxPathSelTable.DbgMode)
+			DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
+
+		if(priv->brfpath_rxenable[i])
+		{
+			rf_num++;
+			cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
+
+			if(rf_num == 1)	// find first enabled rf path and the rssi values
+			{	//initialize, set all rssi index to the same one
+				max_rssi_index = min_rssi_index = sec_rssi_index = i;
+				tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
+			}
+			else if(rf_num == 2)
+			{	// we pick up the max index first, and let sec and min to be the same one
+				if(cur_rf_rssi >= tmp_max_rssi)
+				{
+					tmp_max_rssi = cur_rf_rssi;
+					max_rssi_index = i;
+				}
+				else
+				{
+					tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
+					sec_rssi_index = min_rssi_index = i;
+				}
+			}
+			else
+			{
+				if(cur_rf_rssi > tmp_max_rssi)
+				{
+					tmp_sec_rssi = tmp_max_rssi;
+					sec_rssi_index = max_rssi_index;
+					tmp_max_rssi = cur_rf_rssi;
+					max_rssi_index = i;
+				}
+				else if(cur_rf_rssi == tmp_max_rssi)
+				{	// let sec and min point to the different index
+					tmp_sec_rssi = cur_rf_rssi;
+					sec_rssi_index = i;
+				}
+				else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
+				{
+					tmp_sec_rssi = cur_rf_rssi;
+					sec_rssi_index = i;
+				}
+				else if(cur_rf_rssi == tmp_sec_rssi)
+				{
+					if(tmp_sec_rssi == tmp_min_rssi)
+					{	// let sec and min point to the different index
+						tmp_sec_rssi = cur_rf_rssi;
+						sec_rssi_index = i;
+					}
+					else
+					{
+						// This case we don't need to set any index
+					}
+				}
+				else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
+				{
+					// This case we don't need to set any index
+				}
+				else if(cur_rf_rssi == tmp_min_rssi)
+				{
+					if(tmp_sec_rssi == tmp_min_rssi)
+					{	// let sec and min point to the different index
+						tmp_min_rssi = cur_rf_rssi;
+						min_rssi_index = i;
+					}
+					else
+					{
+						// This case we don't need to set any index
+					}
+				}
+				else if(cur_rf_rssi < tmp_min_rssi)
+				{
+					tmp_min_rssi = cur_rf_rssi;
+					min_rssi_index = i;
+				}
+			}
+		}
+	}
+
+	rf_num = 0;
+	// decide max/sec/min cck pwdb index
+	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
+	{
+		for (i=0; i<RF90_PATH_MAX; i++)
+		{
+			if(priv->brfpath_rxenable[i])
+			{
+				rf_num++;
+				cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
+
+				if(rf_num == 1)	// find first enabled rf path and the rssi values
+				{	//initialize, set all rssi index to the same one
+					cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
+					tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
+				}
+				else if(rf_num == 2)
+				{	// we pick up the max index first, and let sec and min to be the same one
+					if(cur_cck_pwdb >= tmp_cck_max_pwdb)
+					{
+						tmp_cck_max_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_max_index = i;
+					}
+					else
+					{
+						tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
+					}
+				}
+				else
+				{
+					if(cur_cck_pwdb > tmp_cck_max_pwdb)
+					{
+						tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
+						cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
+						tmp_cck_max_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_max_index = i;
+					}
+					else if(cur_cck_pwdb == tmp_cck_max_pwdb)
+					{	// let sec and min point to the different index
+						tmp_cck_sec_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_sec_index = i;
+					}
+					else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
+					{
+						tmp_cck_sec_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_sec_index = i;
+					}
+					else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
+					{
+						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
+						{	// let sec and min point to the different index
+							tmp_cck_sec_pwdb = cur_cck_pwdb;
+							cck_rx_ver2_sec_index = i;
+						}
+						else
+						{
+							// This case we don't need to set any index
+						}
+					}
+					else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
+					{
+						// This case we don't need to set any index
+					}
+					else if(cur_cck_pwdb == tmp_cck_min_pwdb)
+					{
+						if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
+						{	// let sec and min point to the different index
+							tmp_cck_min_pwdb = cur_cck_pwdb;
+							cck_rx_ver2_min_index = i;
+						}
+						else
+						{
+							// This case we don't need to set any index
+						}
+					}
+					else if(cur_cck_pwdb < tmp_cck_min_pwdb)
+					{
+						tmp_cck_min_pwdb = cur_cck_pwdb;
+						cck_rx_ver2_min_index = i;
+					}
+				}
+
+			}
+		}
+	}
+
+
+	// Set CCK Rx path
+	// reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
+	update_cck_rx_path = 0;
+	if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
+	{
+		cck_default_Rx = cck_rx_ver2_max_index;
+		cck_optional_Rx = cck_rx_ver2_sec_index;
+		if(tmp_cck_max_pwdb != -64)
+			update_cck_rx_path = 1;
+	}
+
+	if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
+	{
+		if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
+		{
+			//record the enabled rssi threshold
+			DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
+			//disable the BB Rx path, OFDM
+			rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xc04[3:0]
+			rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);	// 0xd04[3:0]
+			disabled_rf_cnt++;
+		}
+		if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
+		{
+			cck_default_Rx = max_rssi_index;
+			cck_optional_Rx = sec_rssi_index;
+			if(tmp_max_rssi)
+				update_cck_rx_path = 1;
+		}
+	}
+
+	if(update_cck_rx_path)
+	{
+		DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
+		rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
+	}
+
+	if(DM_RxPathSelTable.disabledRF)
+	{
+		for(i=0; i<4; i++)
+		{
+			if((DM_RxPathSelTable.disabledRF>>i) & 0x1)	//disabled rf
+			{
+				if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
+				{
+					//enable the BB Rx path
+					//DbgPrint("RF-%d is enabled. \n", 0x1<<i);
+					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);	// 0xc04[3:0]
+					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);	// 0xd04[3:0]
+					DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
+					disabled_rf_cnt--;
+				}
+			}
+		}
+	}
+}
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_check_rx_path_selection()
+ *
+ * Overview:	Call a workitem to check current RXRF path and Rx Path selection by RSSI.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/28/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void	dm_check_rx_path_selection(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
+}	/* dm_CheckRxRFPath */
+
+
+static void dm_init_fsync (struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	priv->ieee80211->fsync_time_interval = 500;
+	priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
+	priv->ieee80211->fsync_rssi_threshold = 30;
+#ifdef RTL8190P
+	priv->ieee80211->bfsync_enable = true;
+#else
+	priv->ieee80211->bfsync_enable = false;
+#endif
+	priv->ieee80211->fsync_multiple_timeinterval = 3;
+	priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
+	priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
+	priv->ieee80211->fsync_state = Default_Fsync;
+	priv->framesyncMonitor = 1;	// current default 0xc38 monitor on
+
+	init_timer(&priv->fsync_timer);
+	priv->fsync_timer.data = (unsigned long)dev;
+	priv->fsync_timer.function = dm_fsync_timer_callback;
+}
+
+
+static void dm_deInit_fsync(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	del_timer_sync(&priv->fsync_timer);
+}
+
+void dm_fsync_timer_callback(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
+	u32 rate_index, rate_count = 0, rate_count_diff=0;
+	bool		bSwitchFromCountDiff = false;
+	bool		bDoubleTimeInterval = false;
+
+	if(	priv->ieee80211->state == IEEE80211_LINKED &&
+		priv->ieee80211->bfsync_enable &&
+		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
+	{
+		 // Count rate 54, MCS [7], [12, 13, 14, 15]
+		u32 rate_bitmap;
+		for(rate_index = 0; rate_index <= 27; rate_index++)
+		{
+			rate_bitmap  = 1 << rate_index;
+			if(priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
+		 		rate_count+= priv->stats.received_rate_histogram[1][rate_index];
+		}
+
+		if(rate_count < priv->rate_record)
+			rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
+		else
+			rate_count_diff = rate_count - priv->rate_record;
+		if(rate_count_diff < priv->rateCountDiffRecord)
+		{
+
+			u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
+			// Contiune count
+			if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
+				priv->ContiuneDiffCount++;
+			else
+				priv->ContiuneDiffCount = 0;
+
+			// Contiune count over
+			if(priv->ContiuneDiffCount >=2)
+			{
+				bSwitchFromCountDiff = true;
+				priv->ContiuneDiffCount = 0;
+			}
+		}
+		else
+		{
+			// Stop contiune count
+			priv->ContiuneDiffCount = 0;
+		}
+
+		//If Count diff <= FsyncRateCountThreshold
+		if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
+		{
+			bSwitchFromCountDiff = true;
+			priv->ContiuneDiffCount = 0;
+		}
+		priv->rate_record = rate_count;
+		priv->rateCountDiffRecord = rate_count_diff;
+		RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
+		// if we never receive those mcs rate and rssi > 30 % then switch fsyn
+		if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
+		{
+			bDoubleTimeInterval = true;
+			priv->bswitch_fsync = !priv->bswitch_fsync;
+			if(priv->bswitch_fsync)
+			{
+			#ifdef RTL8190P
+				write_nic_byte(dev,0xC36, 0x00);
+			#else
+				write_nic_byte(dev,0xC36, 0x1c);
+			#endif
+				write_nic_byte(dev, 0xC3e, 0x90);
+			}
+			else
+			{
+			#ifdef RTL8190P
+				write_nic_byte(dev, 0xC36, 0x40);
+			#else
+				write_nic_byte(dev, 0xC36, 0x5c);
+			#endif
+				write_nic_byte(dev, 0xC3e, 0x96);
+			}
+		}
+		else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
+		{
+			if(priv->bswitch_fsync)
+			{
+				priv->bswitch_fsync  = false;
+			#ifdef RTL8190P
+				write_nic_byte(dev, 0xC36, 0x40);
+			#else
+				write_nic_byte(dev, 0xC36, 0x5c);
+			#endif
+				write_nic_byte(dev, 0xC3e, 0x96);
+			}
+		}
+		if(bDoubleTimeInterval){
+			if(timer_pending(&priv->fsync_timer))
+				del_timer_sync(&priv->fsync_timer);
+			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
+			add_timer(&priv->fsync_timer);
+		}
+		else{
+			if(timer_pending(&priv->fsync_timer))
+				del_timer_sync(&priv->fsync_timer);
+			priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
+			add_timer(&priv->fsync_timer);
+		}
+	}
+	else
+	{
+		// Let Register return to default value;
+		if(priv->bswitch_fsync)
+		{
+			priv->bswitch_fsync  = false;
+		#ifdef RTL8190P
+			write_nic_byte(dev, 0xC36, 0x40);
+		#else
+			write_nic_byte(dev, 0xC36, 0x5c);
+		#endif
+			write_nic_byte(dev, 0xC3e, 0x96);
+		}
+		priv->ContiuneDiffCount = 0;
+	#ifdef RTL8190P
+		write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd);
+	#else
+		write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
+	#endif
+	}
+	RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
+	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
+}
+
+static void dm_StartHWFsync(struct net_device *dev)
+{
+	RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
+	write_nic_byte(dev, 0xc3b, 0x41);
+}
+
+static void dm_EndSWFsync(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
+	del_timer_sync(&(priv->fsync_timer));
+
+	// Let Register return to default value;
+	if(priv->bswitch_fsync)
+	{
+		priv->bswitch_fsync  = false;
+
+		#ifdef RTL8190P
+			write_nic_byte(dev, 0xC36, 0x40);
+		#else
+		write_nic_byte(dev, 0xC36, 0x5c);
+#endif
+
+		write_nic_byte(dev, 0xC3e, 0x96);
+	}
+
+	priv->ContiuneDiffCount = 0;
+#ifndef RTL8190P
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
+#endif
+
+}
+
+static void dm_StartSWFsync(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 			rateIndex;
+	u32 			rateBitmap;
+
+	RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
+	// Initial rate record to zero, start to record.
+	priv->rate_record = 0;
+	// Initial contiune diff count to zero, start to record.
+	priv->ContiuneDiffCount = 0;
+	priv->rateCountDiffRecord = 0;
+	priv->bswitch_fsync  = false;
+
+	if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
+	{
+		priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
+		priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
+	}
+	else
+	{
+		priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
+		priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
+	}
+	for(rateIndex = 0; rateIndex <= 27; rateIndex++)
+	{
+		rateBitmap  = 1 << rateIndex;
+		if(priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
+			priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
+	}
+	if(timer_pending(&priv->fsync_timer))
+		del_timer_sync(&priv->fsync_timer);
+	priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
+	add_timer(&priv->fsync_timer);
+
+#ifndef RTL8190P
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
+#endif
+
+}
+
+static void dm_EndHWFsync(struct net_device *dev)
+{
+	RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
+	write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
+	write_nic_byte(dev, 0xc3b, 0x49);
+
+}
+
+void dm_check_fsync(struct net_device *dev)
+{
+#define	RegC38_Default				0
+#define	RegC38_NonFsync_Other_AP	1
+#define	RegC38_Fsync_AP_BCM		2
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	//u32 			framesyncC34;
+	static u8		reg_c38_State=RegC38_Default;
+	static u32	reset_cnt=0;
+
+	RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
+	RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
+
+	if(	priv->ieee80211->state == IEEE80211_LINKED &&
+		(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
+	{
+		if(priv->ieee80211->bfsync_enable == 0)
+		{
+			switch(priv->ieee80211->fsync_state)
+			{
+				case Default_Fsync:
+					dm_StartHWFsync(dev);
+					priv->ieee80211->fsync_state = HW_Fsync;
+					break;
+				case SW_Fsync:
+					dm_EndSWFsync(dev);
+					dm_StartHWFsync(dev);
+					priv->ieee80211->fsync_state = HW_Fsync;
+					break;
+				case HW_Fsync:
+				default:
+					break;
+			}
+		}
+		else
+		{
+			switch(priv->ieee80211->fsync_state)
+			{
+				case Default_Fsync:
+					dm_StartSWFsync(dev);
+					priv->ieee80211->fsync_state = SW_Fsync;
+					break;
+				case HW_Fsync:
+					dm_EndHWFsync(dev);
+					dm_StartSWFsync(dev);
+					priv->ieee80211->fsync_state = SW_Fsync;
+					break;
+				case SW_Fsync:
+				default:
+					break;
+
+			}
+		}
+		if(priv->framesyncMonitor)
+		{
+			if(reg_c38_State != RegC38_Fsync_AP_BCM)
+			{	//For broadcom AP we write different default value
+				#ifdef RTL8190P
+					write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
+				#else
+					write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
+				#endif
+
+				reg_c38_State = RegC38_Fsync_AP_BCM;
+			}
+		}
+	}
+	else
+	{
+		switch(priv->ieee80211->fsync_state)
+		{
+			case HW_Fsync:
+				dm_EndHWFsync(dev);
+				priv->ieee80211->fsync_state = Default_Fsync;
+				break;
+			case SW_Fsync:
+				dm_EndSWFsync(dev);
+				priv->ieee80211->fsync_state = Default_Fsync;
+				break;
+			case Default_Fsync:
+			default:
+				break;
+		}
+
+		if(priv->framesyncMonitor)
+		{
+			if(priv->ieee80211->state == IEEE80211_LINKED)
+			{
+				if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
+				{
+					if(reg_c38_State != RegC38_NonFsync_Other_AP)
+					{
+						#ifdef RTL8190P
+							write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
+						#else
+							write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
+						#endif
+
+						reg_c38_State = RegC38_NonFsync_Other_AP;
+					#if 0//cosa
+						if (Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
+							DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x10);
+						else
+							DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x90);
+					#endif
+					}
+				}
+				else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
+				{
+					if(reg_c38_State)
+					{
+						write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+						reg_c38_State = RegC38_Default;
+						//DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync);
+					}
+				}
+			}
+			else
+			{
+				if(reg_c38_State)
+				{
+					write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+					reg_c38_State = RegC38_Default;
+					//DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync);
+				}
+			}
+		}
+	}
+	if(priv->framesyncMonitor)
+	{
+		if(priv->reset_count != reset_cnt)
+		{	//After silent reset, the reg_c38_State will be returned to default value
+			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+			reg_c38_State = RegC38_Default;
+			reset_cnt = priv->reset_count;
+			//DbgPrint("reg_c38_State = 0 for silent reset. \n");
+		}
+	}
+	else
+	{
+		if(reg_c38_State)
+		{
+			write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
+			reg_c38_State = RegC38_Default;
+			//DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync);
+		}
+	}
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	dm_shadow_init()
+ *
+ * Overview:	Store all NIC MAC/BB register content.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/29/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+void dm_shadow_init(struct net_device *dev)
+{
+	u8	page;
+	u16	offset;
+
+	for (page = 0; page < 5; page++)
+		for (offset = 0; offset < 256; offset++)
+		{
+			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
+			//DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
+		}
+
+	for (page = 8; page < 11; page++)
+		for (offset = 0; offset < 256; offset++)
+			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
+
+	for (page = 12; page < 15; page++)
+		for (offset = 0; offset < 256; offset++)
+			dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
+
+}   /* dm_shadow_init */
+
+/*---------------------------Define function prototype------------------------*/
+/*-----------------------------------------------------------------------------
+ * Function:	DM_DynamicTxPower()
+ *
+ * Overview:	Detect Signal strength to control TX Registry
+ 			Tx Power Control For Near/Far Range
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	03/06/2008	Jacken	Create Version 0.
+ *
+ *---------------------------------------------------------------------------*/
+static void dm_init_dynamic_txpower(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
+	priv->ieee80211->bdynamic_txpower_enable = true;    //Default to enable Tx Power Control
+	priv->bLastDTPFlag_High = false;
+	priv->bLastDTPFlag_Low = false;
+	priv->bDynamicTxHighPower = false;
+	priv->bDynamicTxLowPower = false;
+}
+
+static void dm_dynamic_txpower(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	unsigned int txhipower_threshhold=0;
+        unsigned int txlowpower_threshold=0;
+	if(priv->ieee80211->bdynamic_txpower_enable != true)
+	{
+		priv->bDynamicTxHighPower = false;
+		priv->bDynamicTxLowPower = false;
+		return;
+	}
+	//printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist);
+        if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
+		txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
+		txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
+	}
+	else
+	{
+		txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
+		txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
+	}
+
+//	printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold);
+
+	RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
+
+	if(priv->ieee80211->state == IEEE80211_LINKED)
+	{
+		if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
+		{
+			priv->bDynamicTxHighPower = true;
+			priv->bDynamicTxLowPower = false;
+		}
+		else
+		{
+			// high power state check
+			if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
+			{
+				priv->bDynamicTxHighPower = false;
+			}
+			// low power state check
+			if(priv->undecorated_smoothed_pwdb < 35)
+			{
+				priv->bDynamicTxLowPower = true;
+			}
+			else if(priv->undecorated_smoothed_pwdb >= 40)
+			{
+				priv->bDynamicTxLowPower = false;
+			}
+		}
+	}
+	else
+	{
+		//pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
+		priv->bDynamicTxHighPower = false;
+		priv->bDynamicTxLowPower = false;
+	}
+
+	if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
+		(priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
+	{
+		RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190()  channel = %d \n" , priv->ieee80211->current_network.channel);
+
+
+		rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
+
+	}
+	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
+	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
+
+}	/* dm_dynamic_txpower */
+
+//added by vivi, for read tx rate and retrycount
+static void dm_check_txrateandretrycount(struct net_device * dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	//for 11n tx rate
+//	priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
+	ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
+	//printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
+	//for initial tx rate
+//	priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
+	ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg);
+	//for tx tx retry count
+//	priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
+	ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
+}
+
+static void dm_send_rssi_tofw(struct net_device *dev)
+{
+	DCMD_TXCMD_T			tx_cmd;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	// If we test chariot, we should stop the TX command ?
+	// Because 92E will always silent reset when we send tx command. We use register
+	// 0x1e0(byte) to botify driver.
+	write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
+	return;
+#if 1
+	tx_cmd.Op		= TXCMD_SET_RX_RSSI;
+	tx_cmd.Length	= 4;
+	tx_cmd.Value		= priv->undecorated_smoothed_pwdb;
+
+	cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
+								DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
+#endif
+}
+
+/*---------------------------Define function prototype------------------------*/
+
diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h
new file mode 100644
index 0000000..f74a880
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192E_dm.h
@@ -0,0 +1,312 @@
+/*****************************************************************************
+ *	Copyright(c) 2007,  RealTEK Technology Inc. All Right Reserved.
+ *
+ * Module:		Hal819xUsbDM.h	(RTL8192  Header H File)
+ *
+ *
+ * Note:		For dynamic control definition constant structure.
+ *
+ *
+ * Export:
+ *
+ * Abbrev:
+ *
+ * History:
+ *	Data		Who		Remark
+ *	10/04/2007  MHC    	Create initial version.
+ *
+ *****************************************************************************/
+ /* Check to see if the file has been included already.  */
+#ifndef	__R8192UDM_H__
+#define __R8192UDM_H__
+
+
+/*--------------------------Define Parameters-------------------------------*/
+#define 		OFDM_Table_Length	19
+#define		CCK_Table_length	12
+
+#define		DM_DIG_THRESH_HIGH					40
+#define		DM_DIG_THRESH_LOW					35
+
+#define		DM_DIG_HIGH_PWR_THRESH_HIGH		75
+#define		DM_DIG_HIGH_PWR_THRESH_LOW		70
+
+#define		BW_AUTO_SWITCH_HIGH_LOW			25
+#define		BW_AUTO_SWITCH_LOW_HIGH			30
+
+#define		DM_check_fsync_time_interval				500
+
+
+#define		DM_DIG_BACKOFF				12
+#define		DM_DIG_MAX					0x36
+#define		DM_DIG_MIN					0x1c
+#define		DM_DIG_MIN_Netcore			0x12
+
+#define		RxPathSelection_SS_TH_low		30
+#define		RxPathSelection_diff_TH			18
+
+#define		RateAdaptiveTH_High			50
+#define		RateAdaptiveTH_Low_20M		30
+#define		RateAdaptiveTH_Low_40M		10
+#define		VeryLowRSSI					15
+#define		CTSToSelfTHVal					35
+
+//defined by vivi, for tx power track
+#define		E_FOR_TX_POWER_TRACK               300
+//Dynamic Tx Power Control Threshold
+#define		TX_POWER_NEAR_FIELD_THRESH_HIGH		68
+#define		TX_POWER_NEAR_FIELD_THRESH_LOW		62
+//added by amy for atheros AP
+#define         TX_POWER_ATHEROAP_THRESH_HIGH           78
+#define 	TX_POWER_ATHEROAP_THRESH_LOW		72
+
+//defined by vivi, for showing on UI. Newer firmware has changed to 0x1e0
+#define 		Current_Tx_Rate_Reg         0x1e0//0x1b8
+#define 		Initial_Tx_Rate_Reg         0x1e1 //0x1b9
+#define 		Tx_Retry_Count_Reg         0x1ac
+#define		RegC38_TH				 20
+#if 0
+//----------------------------------------------------------------------------
+//       8190 Rate Adaptive Table Register	(offset 0x320, 4 byte)
+//----------------------------------------------------------------------------
+
+//CCK
+#define	RATR_1M					0x00000001
+#define	RATR_2M					0x00000002
+#define	RATR_55M					0x00000004
+#define	RATR_11M					0x00000008
+//OFDM
+#define	RATR_6M					0x00000010
+#define	RATR_9M					0x00000020
+#define	RATR_12M					0x00000040
+#define	RATR_18M					0x00000080
+#define	RATR_24M					0x00000100
+#define	RATR_36M					0x00000200
+#define	RATR_48M					0x00000400
+#define	RATR_54M					0x00000800
+//MCS 1 Spatial Stream
+#define	RATR_MCS0					0x00001000
+#define	RATR_MCS1					0x00002000
+#define	RATR_MCS2					0x00004000
+#define	RATR_MCS3					0x00008000
+#define	RATR_MCS4					0x00010000
+#define	RATR_MCS5					0x00020000
+#define	RATR_MCS6					0x00040000
+#define	RATR_MCS7					0x00080000
+//MCS 2 Spatial Stream
+#define	RATR_MCS8					0x00100000
+#define	RATR_MCS9					0x00200000
+#define	RATR_MCS10					0x00400000
+#define	RATR_MCS11					0x00800000
+#define	RATR_MCS12					0x01000000
+#define	RATR_MCS13					0x02000000
+#define	RATR_MCS14					0x04000000
+#define	RATR_MCS15					0x08000000
+// ALL CCK Rate
+#define RATE_ALL_CCK				RATR_1M|RATR_2M|RATR_55M|RATR_11M
+#define RATE_ALL_OFDM_AG			RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M\
+									|RATR_36M|RATR_48M|RATR_54M
+#define RATE_ALL_OFDM_2SS			RATR_MCS8|RATR_MCS9	|RATR_MCS10|RATR_MCS11| \
+									RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
+#endif
+/*--------------------------Define Parameters-------------------------------*/
+
+
+/*------------------------------Define structure----------------------------*/
+/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */
+typedef struct _dynamic_initial_gain_threshold_
+{
+	u8		dig_enable_flag;
+	u8		dig_algorithm;
+	u8		dbg_mode;
+	u8		dig_algorithm_switch;
+
+	long		rssi_low_thresh;
+	long		rssi_high_thresh;
+
+	long		rssi_high_power_lowthresh;
+	long		rssi_high_power_highthresh;
+
+	u8		dig_state;
+	u8		dig_highpwr_state;
+	u8		cur_connect_state;
+	u8		pre_connect_state;
+
+	u8		curpd_thstate;
+	u8		prepd_thstate;
+	u8		curcs_ratio_state;
+	u8		precs_ratio_state;
+
+	u32		pre_ig_value;
+	u32		cur_ig_value;
+
+	u8		backoff_val;
+	u8		rx_gain_range_max;
+	u8		rx_gain_range_min;
+	bool		initialgain_lowerbound_state;
+
+	long		rssi_val;
+}dig_t;
+
+typedef enum tag_dynamic_init_gain_state_definition
+{
+	DM_STA_DIG_OFF = 0,
+	DM_STA_DIG_ON,
+	DM_STA_DIG_MAX
+}dm_dig_sta_e;
+
+
+/* 2007/10/08 MH Define RATR state. */
+typedef enum tag_dynamic_ratr_state_definition
+{
+	DM_RATR_STA_HIGH = 0,
+	DM_RATR_STA_MIDDLE = 1,
+	DM_RATR_STA_LOW = 2,
+	DM_RATR_STA_MAX
+}dm_ratr_sta_e;
+
+/* 2007/10/11 MH Define DIG operation type. */
+typedef enum tag_dynamic_init_gain_operation_type_definition
+{
+	DIG_TYPE_THRESH_HIGH	= 0,
+	DIG_TYPE_THRESH_LOW	= 1,
+	DIG_TYPE_THRESH_HIGHPWR_HIGH	= 2,
+	DIG_TYPE_THRESH_HIGHPWR_LOW	= 3,
+	DIG_TYPE_DBG_MODE				= 4,
+	DIG_TYPE_RSSI						= 5,
+	DIG_TYPE_ALGORITHM				= 6,
+	DIG_TYPE_BACKOFF					= 7,
+	DIG_TYPE_PWDB_FACTOR			= 8,
+	DIG_TYPE_RX_GAIN_MIN				= 9,
+	DIG_TYPE_RX_GAIN_MAX				= 10,
+	DIG_TYPE_ENABLE 		= 20,
+	DIG_TYPE_DISABLE 		= 30,
+	DIG_OP_TYPE_MAX
+}dm_dig_op_e;
+
+typedef enum tag_dig_algorithm_definition
+{
+	DIG_ALGO_BY_FALSE_ALARM = 0,
+	DIG_ALGO_BY_RSSI	= 1,
+	DIG_ALGO_MAX
+}dm_dig_alg_e;
+
+typedef enum tag_dig_dbgmode_definition
+{
+	DIG_DBG_OFF = 0,
+	DIG_DBG_ON = 1,
+	DIG_DBG_MAX
+}dm_dig_dbg_e;
+
+typedef enum tag_dig_connect_definition
+{
+	DIG_DISCONNECT = 0,
+	DIG_CONNECT = 1,
+	DIG_CONNECT_MAX
+}dm_dig_connect_e;
+
+typedef enum tag_dig_packetdetection_threshold_definition
+{
+	DIG_PD_AT_LOW_POWER = 0,
+	DIG_PD_AT_NORMAL_POWER = 1,
+	DIG_PD_AT_HIGH_POWER = 2,
+	DIG_PD_MAX
+}dm_dig_pd_th_e;
+
+typedef enum tag_dig_cck_cs_ratio_state_definition
+{
+	DIG_CS_RATIO_LOWER = 0,
+	DIG_CS_RATIO_HIGHER = 1,
+	DIG_CS_MAX
+}dm_dig_cs_ratio_e;
+typedef struct _Dynamic_Rx_Path_Selection_
+{
+	u8		Enable;
+	u8		DbgMode;
+	u8		cck_method;
+	u8		cck_Rx_path;
+
+	u8		SS_TH_low;
+	u8		diff_TH;
+	u8		disabledRF;
+	u8		reserved;
+
+	u8		rf_rssi[4];
+	u8		rf_enable_rssi_th[4];
+	long		cck_pwdb_sta[4];
+}DRxPathSel;
+
+typedef enum tag_CCK_Rx_Path_Method_Definition
+{
+	CCK_Rx_Version_1 = 0,
+	CCK_Rx_Version_2= 1,
+	CCK_Rx_Version_MAX
+}DM_CCK_Rx_Path_Method;
+
+typedef enum tag_DM_DbgMode_Definition
+{
+	DM_DBG_OFF = 0,
+	DM_DBG_ON = 1,
+	DM_DBG_MAX
+}DM_DBG_E;
+
+typedef struct tag_Tx_Config_Cmd_Format
+{
+	u32	Op;										/* Command packet type. */
+	u32	Length;									/* Command packet length. */
+	u32	Value;
+}DCMD_TXCMD_T, *PDCMD_TXCMD_T;
+/*------------------------------Define structure----------------------------*/
+
+
+/*------------------------Export global variable----------------------------*/
+extern	dig_t	dm_digtable;
+extern	u8		dm_shadow[16][256];
+extern DRxPathSel      DM_RxPathSelTable;
+/*------------------------Export global variable----------------------------*/
+
+
+/*------------------------Export Marco Definition---------------------------*/
+
+/*------------------------Export Marco Definition---------------------------*/
+
+
+/*--------------------------Exported Function prototype---------------------*/
+/*--------------------------Exported Function prototype---------------------*/
+extern  void    init_hal_dm(struct net_device *dev);
+extern  void deinit_hal_dm(struct net_device *dev);
+
+extern void hal_dm_watchdog(struct net_device *dev);
+
+
+extern  void    init_rate_adaptive(struct net_device *dev);
+extern  void    dm_txpower_trackingcallback(struct work_struct *work);
+
+extern  void    dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
+extern  void    dm_restore_dynamic_mechanism_state(struct net_device *dev);
+extern  void    dm_backup_dynamic_mechanism_state(struct net_device *dev);
+extern  void    dm_change_dynamic_initgain_thresh(struct net_device *dev,
+                                                                u32             dm_type,
+                                                                u32             dm_value);
+extern  void    DM_ChangeFsyncSetting(struct net_device *dev,
+                                                                                                s32             DM_Type,
+                                                                                                s32             DM_Value);
+extern  void dm_force_tx_fw_info(struct net_device *dev,
+                                                                                u32             force_type,
+                                                                                u32             force_value);
+extern  void    dm_init_edca_turbo(struct net_device *dev);
+extern  void    dm_rf_operation_test_callback(unsigned long data);
+extern  void    dm_rf_pathcheck_workitemcallback(struct work_struct *work);
+extern  void dm_fsync_timer_callback(unsigned long data);
+#if 0
+extern  bool    dm_check_lbus_status(struct net_device *dev);
+#endif
+extern  void dm_check_fsync(struct net_device *dev);
+extern  void    dm_shadow_init(struct net_device *dev);
+extern  void dm_initialize_txpower_tracking(struct net_device *dev);
+
+
+#endif	/*__R8192UDM_H__ */
+
+
+/* End of r8192U_dm.h */
diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h
new file mode 100644
index 0000000..388908f
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192E_hw.h
@@ -0,0 +1,811 @@
+/*
+	This is part of rtl8187 OpenSource driver.
+	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+	Released under the terms of GPL (General Public Licence)
+
+	Parts of this driver are based on the GPL part of the
+	official Realtek driver.
+	Parts of this driver are based on the rtl8180 driver skeleton
+	from Patric Schenke & Andres Salomon.
+	Parts of this driver are based on the Intel Pro Wireless
+	2100 GPL driver.
+
+	We want to tanks the Authors of those projects
+	and the Ndiswrapper project Authors.
+*/
+
+/* Mariusz Matuszek added full registers definition with Realtek's name */
+
+/* this file contains register definitions for the rtl8187 MAC controller */
+#ifndef R8180_HW
+#define R8180_HW
+
+typedef enum _VERSION_8190{
+	// RTL8190
+	VERSION_8190_BD=0x3,
+	VERSION_8190_BE
+}VERSION_8190,*PVERSION_8190;
+//added for different RF type
+typedef enum _RT_RF_TYPE_DEF
+{
+	RF_1T2R = 0,
+	RF_2T4R,
+
+	RF_819X_MAX_TYPE
+}RT_RF_TYPE_DEF;
+
+typedef enum _BaseBand_Config_Type{
+	BaseBand_Config_PHY_REG = 0,			//Radio Path A
+	BaseBand_Config_AGC_TAB = 1,			//Radio Path B
+}BaseBand_Config_Type, *PBaseBand_Config_Type;
+#if 0
+typedef enum _RT_RF_TYPE_819xU{
+	RF_TYPE_MIN = 0,
+	RF_8225,
+	RF_8256,
+	RF_8258,
+	RF_PSEUDO_11N = 4,
+}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
+#endif
+#define	RTL8187_REQT_READ	0xc0
+#define	RTL8187_REQT_WRITE	0x40
+#define	RTL8187_REQ_GET_REGS	0x05
+#define	RTL8187_REQ_SET_REGS	0x05
+
+#define R8180_MAX_RETRY 255
+#define MAX_TX_URB 5
+#define MAX_RX_URB 16
+//#define MAX_RX_NORMAL_URB 3
+//#define MAX_RX_COMMAND_URB 2
+#define RX_URB_SIZE 9100
+
+#define BB_ANTATTEN_CHAN14	0x0c
+#define BB_ANTENNA_B 0x40
+
+#define BB_HOST_BANG (1<<30)
+#define BB_HOST_BANG_EN (1<<2)
+#define BB_HOST_BANG_CLK (1<<1)
+#define BB_HOST_BANG_RW (1<<3)
+#define BB_HOST_BANG_DATA	 1
+
+//#if (RTL819X_FPGA_VER & RTL819X_FPGA_VIVI_070920)
+#define RTL8190_EEPROM_ID	0x8129
+#define EEPROM_VID		0x02
+#define EEPROM_DID		0x04
+#define EEPROM_NODE_ADDRESS_BYTE_0	0x0C
+
+#define EEPROM_TxPowerDiff	0x1F
+
+
+#define EEPROM_PwDiff		0x21	//0x21
+#define EEPROM_CrystalCap	0x22	//0x22
+
+
+
+#define EEPROM_TxPwIndex_CCK_V1		0x29	//0x29~0x2B
+#define EEPROM_TxPwIndex_OFDM_24G_V1	0x2C	//0x2C~0x2E
+#define EEPROM_TxPwIndex_Ver		0x27	//0x27
+
+#define EEPROM_Default_TxPowerDiff		0x0
+#define EEPROM_Default_ThermalMeter		0x77
+#define EEPROM_Default_AntTxPowerDiff		0x0
+#define EEPROM_Default_TxPwDiff_CrystalCap	0x5
+#define EEPROM_Default_PwDiff			0x4
+#define EEPROM_Default_CrystalCap		0x5
+#define EEPROM_Default_TxPower			0x1010
+#define EEPROM_ICVersion_ChannelPlan	0x7C	//0x7C:ChannelPlan, 0x7D:IC_Version
+#define EEPROM_Customer_ID			0x7B	//0x7B:CustomerID
+#ifdef RTL8190P
+#define EEPROM_RFInd_PowerDiff			0x14
+#define EEPROM_ThermalMeter			0x15
+#define EEPROM_TxPwDiff_CrystalCap		0x16
+#define EEPROM_TxPwIndex_CCK			0x18	//0x18~0x25
+#define EEPROM_TxPwIndex_OFDM_24G	0x26	//0x26~0x33
+#define EEPROM_TxPwIndex_OFDM_5G		0x34	//0x34~0x7B
+#define EEPROM_C56_CrystalCap			0x17	//0x17
+#define EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex	0x80	//0x80
+#define EEPROM_C56_RfA_HT_OFDM_TxPwIndex	0x81	//0x81~0x83
+#define EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex	0xbc	//0xb8
+#define EEPROM_C56_RfC_HT_OFDM_TxPwIndex	0xb9	//0xb9~0xbb
+#else
+#ifdef RTL8192E
+#define EEPROM_RFInd_PowerDiff			0x28
+#define EEPROM_ThermalMeter			0x29
+#define EEPROM_TxPwDiff_CrystalCap		0x2A	//0x2A~0x2B
+#define EEPROM_TxPwIndex_CCK			0x2C	//0x23
+#define EEPROM_TxPwIndex_OFDM_24G	0x3A	//0x24~0x26
+#endif
+#endif
+#define EEPROM_Default_TxPowerLevel		0x10
+//#define EEPROM_ChannelPlan			0x7c	//0x7C
+#define EEPROM_IC_VER				0x7d	//0x7D
+#define EEPROM_CRC				0x7e	//0x7E~0x7F
+
+#define EEPROM_CID_DEFAULT			0x0
+#define EEPROM_CID_CAMEO				0x1
+#define EEPROM_CID_RUNTOP				0x2
+#define EEPROM_CID_Senao				0x3
+#define EEPROM_CID_TOSHIBA				0x4	// Toshiba setting, Merge by Jacken, 2008/01/31
+#define EEPROM_CID_NetCore				0x5
+#define EEPROM_CID_Nettronix			0x6
+#define EEPROM_CID_Pronet				0x7
+#define EEPROM_CID_DLINK				0x8
+#define EEPROM_CID_WHQL 				0xFE  //added by sherry for dtm, 20080728
+//#endif
+enum _RTL8192Pci_HW {
+	MAC0 			= 0x000,
+	MAC1 			= 0x001,
+	MAC2 			= 0x002,
+	MAC3 			= 0x003,
+	MAC4 			= 0x004,
+	MAC5 			= 0x005,
+	PCIF			= 0x009, // PCI Function Register 0x0009h~0x000bh
+//----------------------------------------------------------------------------
+//       8190 PCIF bits							(Offset 0x009-000b, 24bit)
+//----------------------------------------------------------------------------
+#define MXDMA2_16bytes		0x000
+#define MXDMA2_32bytes		0x001
+#define MXDMA2_64bytes		0x010
+#define MXDMA2_128bytes		0x011
+#define MXDMA2_256bytes		0x100
+#define MXDMA2_512bytes		0x101
+#define MXDMA2_1024bytes	0x110
+#define MXDMA2_NoLimit		0x7
+
+#define	MULRW_SHIFT		3
+#define	MXDMA2_RX_SHIFT		4
+#define	MXDMA2_TX_SHIFT		0
+        PMR                     = 0x00c, // Power management register
+	EPROM_CMD 		= 0x00e,
+#define EPROM_CMD_RESERVED_MASK BIT5
+#define EPROM_CMD_9356SEL	BIT4
+#define EPROM_CMD_OPERATING_MODE_SHIFT 6
+#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
+#define EPROM_CMD_CONFIG 0x3
+#define EPROM_CMD_NORMAL 0
+#define EPROM_CMD_LOAD 1
+#define EPROM_CMD_PROGRAM 2
+#define EPROM_CS_SHIFT 3
+#define EPROM_CK_SHIFT 2
+#define EPROM_W_SHIFT 1
+#define EPROM_R_SHIFT 0
+
+	AFR			 = 0x010,
+#define AFR_CardBEn		(1<<0)
+#define AFR_CLKRUN_SEL		(1<<1)
+#define AFR_FuncRegEn		(1<<2)
+
+	ANAPAR			= 0x17,
+#define	BB_GLOBAL_RESET_BIT	0x1
+	BB_GLOBAL_RESET		= 0x020, // BasebandGlobal Reset Register
+	BSSIDR			= 0x02E, // BSSID Register
+	CMDR			= 0x037, // Command register
+#define 	CR_RST					0x10
+#define 	CR_RE					0x08
+#define 	CR_TE					0x04
+#define 	CR_MulRW				0x01
+	SIFS		= 0x03E,	// SIFS register
+	TCR			= 0x040, // Transmit Configuration Register
+	RCR			= 0x044, // Receive Configuration Register
+//----------------------------------------------------------------------------
+////       8190 (RCR) Receive Configuration Register	(Offset 0x44~47, 32 bit)
+////----------------------------------------------------------------------------
+#define RCR_FILTER_MASK (BIT0|BIT1|BIT2|BIT3|BIT5|BIT12|BIT18|BIT19|BIT20|BIT21|BIT22|BIT23)
+#define RCR_ONLYERLPKT		BIT31			// Early Receiving based on Packet Size.
+#define RCR_ENCS2		BIT30				// Enable Carrier Sense Detection Method 2
+#define RCR_ENCS1		BIT29				// Enable Carrier Sense Detection Method 1
+#define RCR_ENMBID		BIT27				// Enable Multiple BssId.
+#define RCR_ACKTXBW		(BIT24|BIT25)		// TXBW Setting of ACK frames
+#define RCR_CBSSID		BIT23				// Accept BSSID match packet
+#define RCR_APWRMGT		BIT22				// Accept power management packet
+#define	RCR_ADD3		BIT21			// Accept address 3 match packet
+#define RCR_AMF			BIT20				// Accept management type frame
+#define RCR_ACF			BIT19				// Accept control type frame
+#define RCR_ADF			BIT18				// Accept data type frame
+#define RCR_RXFTH		BIT13	// Rx FIFO Threshold
+#define RCR_AICV		BIT12				// Accept ICV error packet
+#define	RCR_ACRC32		BIT5			// Accept CRC32 error packet
+#define	RCR_AB			BIT3			// Accept broadcast packet
+#define	RCR_AM			BIT2			// Accept multicast packet
+#define	RCR_APM			BIT1			// Accept physical match packet
+#define	RCR_AAP			BIT0			// Accept all unicast packet
+#define RCR_MXDMA_OFFSET	8
+#define RCR_FIFO_OFFSET		13
+	SLOT_TIME		= 0x049, // Slot Time Register
+	ACK_TIMEOUT		= 0x04c, // Ack Timeout Register
+	PIFS_TIME		= 0x04d, // PIFS time
+	USTIME			= 0x04e, // Microsecond Tuning Register, Sets the microsecond time unit used by MAC clock.
+	EDCAPARA_BE		= 0x050, // EDCA Parameter of AC BE
+	EDCAPARA_BK		= 0x054, // EDCA Parameter of AC BK
+	EDCAPARA_VO		= 0x058, // EDCA Parameter of AC VO
+	EDCAPARA_VI		= 0x05C, // EDCA Parameter of AC VI
+#define	AC_PARAM_TXOP_LIMIT_OFFSET		16
+#define	AC_PARAM_ECW_MAX_OFFSET		12
+#define	AC_PARAM_ECW_MIN_OFFSET			8
+#define	AC_PARAM_AIFS_OFFSET				0
+	RFPC			= 0x05F, // Rx FIFO Packet Count
+	CWRR			= 0x060, // Contention Window Report Register
+	BCN_TCFG		= 0x062, // Beacon Time Configuration
+#define BCN_TCFG_CW_SHIFT		8
+#define BCN_TCFG_IFS			0
+	BCN_INTERVAL		= 0x070, // Beacon Interval (TU)
+	ATIMWND			= 0x072, // ATIM Window Size (TU)
+	BCN_DRV_EARLY_INT	= 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT
+#define	BCN_DRV_EARLY_INT_SWBCN_SHIFT	8
+#define	BCN_DRV_EARLY_INT_TIME_SHIFT	0
+	BCN_DMATIME		= 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA
+	BCN_ERR_THRESH		= 0x078, // Beacon Error Threshold
+	RWCAM			= 0x0A0, //IN 8190 Data Sheet is called CAMcmd
+	//----------------------------------------------------------------------------
+	////       8190 CAM Command Register     		(offset 0xA0, 4 byte)
+	////----------------------------------------------------------------------------
+#define   CAM_CM_SecCAMPolling		BIT31		//Security CAM Polling
+#define   CAM_CM_SecCAMClr			BIT30		//Clear all bits in CAM
+#define   CAM_CM_SecCAMWE			BIT16		//Security CAM enable
+#define   CAM_VALID			       BIT15
+#define   CAM_NOTVALID			0x0000
+#define   CAM_USEDK				BIT5
+
+#define   CAM_NONE				0x0
+#define   CAM_WEP40				0x01
+#define   CAM_TKIP				0x02
+#define   CAM_AES				0x04
+#define   CAM_WEP104			0x05
+
+#define   TOTAL_CAM_ENTRY				32
+
+#define   CAM_CONFIG_USEDK	true
+#define   CAM_CONFIG_NO_USEDK	false
+#define   CAM_WRITE		BIT16
+#define   CAM_READ		0x00000000
+#define   CAM_POLLINIG		BIT31
+#define   SCR_UseDK		0x01
+	WCAMI			= 0x0A4, // Software write CAM input content
+	RCAMO			= 0x0A8, // Software read/write CAM config
+	SECR			= 0x0B0, //Security Configuration Register
+#define	SCR_TxUseDK			BIT0			//Force Tx Use Default Key
+#define   SCR_RxUseDK			BIT1			//Force Rx Use Default Key
+#define   SCR_TxEncEnable		BIT2			//Enable Tx Encryption
+#define   SCR_RxDecEnable		BIT3			//Enable Rx Decryption
+#define   SCR_SKByA2				BIT4			//Search kEY BY A2
+#define   SCR_NoSKMC				BIT5			//No Key Search for Multicast
+	SWREGULATOR	= 0x0BD,	// Switching Regulator
+	INTA_MASK 		= 0x0f4,
+//----------------------------------------------------------------------------
+//       8190 IMR/ISR bits						(offset 0xfd,  8bits)
+//----------------------------------------------------------------------------
+#define IMR8190_DISABLED		0x0
+#define IMR_ATIMEND			BIT28			// ATIM Window End Interrupt
+#define IMR_TBDOK			BIT27			// Transmit Beacon OK Interrupt
+#define IMR_TBDER			BIT26			// Transmit Beacon Error Interrupt
+#define IMR_TXFOVW			BIT15			// Transmit FIFO Overflow
+#define IMR_TIMEOUT0			BIT14			// TimeOut0
+#define IMR_BcnInt			BIT13			// Beacon DMA Interrupt 0
+#define	IMR_RXFOVW			BIT12			// Receive FIFO Overflow
+#define IMR_RDU				BIT11			// Receive Descriptor Unavailable
+#define IMR_RXCMDOK			BIT10			// Receive Command Packet OK
+#define IMR_BDOK			BIT9			// Beacon Queue DMA OK Interrup
+#define IMR_HIGHDOK			BIT8			// High Queue DMA OK Interrupt
+#define	IMR_COMDOK			BIT7			// Command Queue DMA OK Interrupt
+#define IMR_MGNTDOK			BIT6			// Management Queue DMA OK Interrupt
+#define IMR_HCCADOK			BIT5			// HCCA Queue DMA OK Interrupt
+#define	IMR_BKDOK			BIT4			// AC_BK DMA OK Interrupt
+#define	IMR_BEDOK			BIT3			// AC_BE DMA OK Interrupt
+#define	IMR_VIDOK			BIT2			// AC_VI DMA OK Interrupt
+#define	IMR_VODOK			BIT1			// AC_VO DMA Interrupt
+#define	IMR_ROK				BIT0			// Receive DMA OK Interrupt
+	ISR			= 0x0f8, // Interrupt Status Register
+	TPPoll			= 0x0fd, // Transmit priority polling register
+#define TPPoll_BKQ		BIT0				// BK queue polling
+#define TPPoll_BEQ		BIT1				// BE queue polling
+#define TPPoll_VIQ		BIT2				// VI queue polling
+#define TPPoll_VOQ		BIT3				// VO queue polling
+#define TPPoll_BQ		BIT4				// Beacon queue polling
+#define TPPoll_CQ		BIT5				// Command queue polling
+#define TPPoll_MQ		BIT6				// Management queue polling
+#define TPPoll_HQ		BIT7				// High queue polling
+#define TPPoll_HCCAQ		BIT8				// HCCA queue polling
+#define TPPoll_StopBK	BIT9				// Stop BK queue
+#define TPPoll_StopBE	BIT10			// Stop BE queue
+#define TPPoll_StopVI		BIT11			// Stop VI queue
+#define TPPoll_StopVO	BIT12			// Stop VO queue
+#define TPPoll_StopMgt	BIT13			// Stop Mgnt queue
+#define TPPoll_StopHigh	BIT14			// Stop High queue
+#define TPPoll_StopHCCA	BIT15			// Stop HCCA queue
+#define TPPoll_SHIFT		8				// Queue ID mapping
+
+	PSR			= 0x0ff, // Page Select Register
+#define PSR_GEN			0x0				// Page 0 register general MAC Control
+#define PSR_CPU			0x1				// Page 1 register for CPU
+	CPU_GEN			= 0x100, // CPU Reset Register
+	BB_RESET			= 0x101, // Baseband Reset
+//----------------------------------------------------------------------------
+//       8190 CPU General Register		(offset 0x100, 4 byte)
+//----------------------------------------------------------------------------
+#define	CPU_CCK_LOOPBACK	0x00030000
+#define	CPU_GEN_SYSTEM_RESET	0x00000001
+#define	CPU_GEN_FIRMWARE_RESET	0x00000008
+#define	CPU_GEN_BOOT_RDY	0x00000010
+#define	CPU_GEN_FIRM_RDY	0x00000020
+#define	CPU_GEN_PUT_CODE_OK	0x00000080
+#define	CPU_GEN_BB_RST		0x00000100
+#define	CPU_GEN_PWR_STB_CPU	0x00000004
+#define CPU_GEN_NO_LOOPBACK_MSK	0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19
+#define CPU_GEN_NO_LOOPBACK_SET	0x00080000 // Set BIT19 to 1
+#define	CPU_GEN_GPIO_UART		0x00007000
+
+	LED1Cfg			= 0x154,// LED1 Configuration Register
+ 	LED0Cfg			= 0x155,// LED0 Configuration Register
+
+	AcmAvg			= 0x170, // ACM Average Period Register
+	AcmHwCtrl		= 0x171, // ACM Hardware Control Register
+//----------------------------------------------------------------------------
+//
+//       8190 AcmHwCtrl bits 					(offset 0x171, 1 byte)
+//----------------------------------------------------------------------------
+#define	AcmHw_HwEn		BIT0
+#define	AcmHw_BeqEn		BIT1
+#define	AcmHw_ViqEn		BIT2
+#define	AcmHw_VoqEn		BIT3
+#define	AcmHw_BeqStatus		BIT4
+#define	AcmHw_ViqStatus		BIT5
+#define	AcmHw_VoqStatus		BIT6
+	AcmFwCtrl		= 0x172, // ACM Firmware Control Register
+#define	AcmFw_BeqStatus		BIT0
+#define	AcmFw_ViqStatus		BIT1
+#define	AcmFw_VoqStatus		BIT2
+	VOAdmTime		= 0x174, // VO Queue Admitted Time Register
+	VIAdmTime		= 0x178, // VI Queue Admitted Time Register
+	BEAdmTime		= 0x17C, // BE Queue Admitted Time Register
+	RQPN1			= 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk
+	RQPN2			= 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High
+	RQPN3			= 0x188, // Reserved Queue Page Number, Bcn, Public,
+	QPRR			= 0x1E0, // Queue Page Report per TID
+	QPNR			= 0x1F0, // Queue Packet Number report per TID
+/* there's 9 tx descriptor base address available */
+	BQDA			= 0x200, // Beacon Queue Descriptor Address
+	HQDA			= 0x204, // High Priority Queue Descriptor Address
+	CQDA			= 0x208, // Command Queue Descriptor Address
+	MQDA			= 0x20C, // Management Queue Descriptor Address
+	HCCAQDA			= 0x210, // HCCA Queue Descriptor Address
+	VOQDA			= 0x214, // VO Queue Descriptor Address
+	VIQDA			= 0x218, // VI Queue Descriptor Address
+	BEQDA			= 0x21C, // BE Queue Descriptor Address
+	BKQDA			= 0x220, // BK Queue Descriptor Address
+/* there's 2 rx descriptor base address availalbe */
+	RCQDA			= 0x224, // Receive command Queue Descriptor Address
+	RDQDA			= 0x228, // Receive Queue Descriptor Start Address
+
+	MAR0			= 0x240, // Multicast filter.
+	MAR4			= 0x244,
+
+	CCX_PERIOD		= 0x250, // CCX Measurement Period Register, in unit of TU.
+	CLM_RESULT		= 0x251, // CCA Busy fraction register.
+	NHM_PERIOD		= 0x252, // NHM Measurement Period register, in unit of TU.
+
+	NHM_THRESHOLD0		= 0x253, // Noise Histogram Meashorement0.
+	NHM_THRESHOLD1		= 0x254, // Noise Histogram Meashorement1.
+	NHM_THRESHOLD2		= 0x255, // Noise Histogram Meashorement2.
+	NHM_THRESHOLD3		= 0x256, // Noise Histogram Meashorement3.
+	NHM_THRESHOLD4		= 0x257, // Noise Histogram Meashorement4.
+	NHM_THRESHOLD5		= 0x258, // Noise Histogram Meashorement5.
+	NHM_THRESHOLD6		= 0x259, // Noise Histogram Meashorement6
+
+	MCTRL			= 0x25A, // Measurement Control
+
+	NHM_RPI_COUNTER0	= 0x264, // Noise Histogram RPI counter0, the fraction of signal strength < NHM_THRESHOLD0.
+	NHM_RPI_COUNTER1	= 0x265, // Noise Histogram RPI counter1, the fraction of signal strength in (NHM_THRESHOLD0, NHM_THRESHOLD1].
+	NHM_RPI_COUNTER2	= 0x266, // Noise Histogram RPI counter2, the fraction of signal strength in (NHM_THRESHOLD1, NHM_THRESHOLD2].
+	NHM_RPI_COUNTER3	= 0x267, // Noise Histogram RPI counter3, the fraction of signal strength in (NHM_THRESHOLD2, NHM_THRESHOLD3].
+	NHM_RPI_COUNTER4	= 0x268, // Noise Histogram RPI counter4, the fraction of signal strength in (NHM_THRESHOLD3, NHM_THRESHOLD4].
+	NHM_RPI_COUNTER5	= 0x269, // Noise Histogram RPI counter5, the fraction of signal strength in (NHM_THRESHOLD4, NHM_THRESHOLD5].
+	NHM_RPI_COUNTER6	= 0x26A, // Noise Histogram RPI counter6, the fraction of signal strength in (NHM_THRESHOLD5, NHM_THRESHOLD6].
+	NHM_RPI_COUNTER7	= 0x26B, // Noise Histogram RPI counter7, the fraction of signal strength in (NHM_THRESHOLD6, NHM_THRESHOLD7].
+        WFCRC0                  = 0x2f0,
+        WFCRC1                  = 0x2f4,
+        WFCRC2                  = 0x2f8,
+
+	BW_OPMODE		= 0x300, // Bandwidth operation mode
+#define	BW_OPMODE_11J			BIT0
+#define	BW_OPMODE_5G			BIT1
+#define	BW_OPMODE_20MHZ			BIT2
+	IC_VERRSION		= 0x301,	//IC_VERSION
+	MSR			= 0x303, // Media Status register
+#define MSR_LINK_MASK      ((1<<0)|(1<<1))
+#define MSR_LINK_MANAGED   2
+#define MSR_LINK_NONE      0
+#define MSR_LINK_SHIFT     0
+#define MSR_LINK_ADHOC     1
+#define MSR_LINK_MASTER    3
+#define MSR_LINK_ENEDCA	   (1<<4)
+	RETRY_LIMIT		= 0x304, // Retry Limit [15:8]-short, [7:0]-long
+#define RETRY_LIMIT_SHORT_SHIFT 8
+#define RETRY_LIMIT_LONG_SHIFT 0
+	TSFR			= 0x308,
+	RRSR			= 0x310, // Response Rate Set
+#define RRSR_RSC_OFFSET			21
+#define RRSR_SHORT_OFFSET			23
+#define RRSR_RSC_DUPLICATE			0x600000
+#define RRSR_RSC_UPSUBCHNL			0x400000
+#define RRSR_RSC_LOWSUBCHNL		0x200000
+#define RRSR_SHORT					0x800000
+#define RRSR_1M						BIT0
+#define RRSR_2M						BIT1
+#define RRSR_5_5M					BIT2
+#define RRSR_11M					BIT3
+#define RRSR_6M						BIT4
+#define RRSR_9M						BIT5
+#define RRSR_12M					BIT6
+#define RRSR_18M					BIT7
+#define RRSR_24M					BIT8
+#define RRSR_36M					BIT9
+#define RRSR_48M					BIT10
+#define RRSR_54M					BIT11
+#define RRSR_MCS0					BIT12
+#define RRSR_MCS1					BIT13
+#define RRSR_MCS2					BIT14
+#define RRSR_MCS3					BIT15
+#define RRSR_MCS4					BIT16
+#define RRSR_MCS5					BIT17
+#define RRSR_MCS6					BIT18
+#define RRSR_MCS7					BIT19
+#define BRSR_AckShortPmb			BIT23		// CCK ACK: use Short Preamble or not
+	UFWP			= 0x318,
+	RATR0			= 0x320, // Rate Adaptive Table register1
+//----------------------------------------------------------------------------
+//       8190 Rate Adaptive Table Register	(offset 0x320, 4 byte)
+//----------------------------------------------------------------------------
+//CCK
+#define	RATR_1M			0x00000001
+#define	RATR_2M			0x00000002
+#define	RATR_55M		0x00000004
+#define	RATR_11M		0x00000008
+//OFDM
+#define	RATR_6M			0x00000010
+#define	RATR_9M			0x00000020
+#define	RATR_12M		0x00000040
+#define	RATR_18M		0x00000080
+#define	RATR_24M		0x00000100
+#define	RATR_36M		0x00000200
+#define	RATR_48M		0x00000400
+#define	RATR_54M		0x00000800
+//MCS 1 Spatial Stream
+#define	RATR_MCS0		0x00001000
+#define	RATR_MCS1		0x00002000
+#define	RATR_MCS2		0x00004000
+#define	RATR_MCS3		0x00008000
+#define	RATR_MCS4		0x00010000
+#define	RATR_MCS5		0x00020000
+#define	RATR_MCS6		0x00040000
+#define	RATR_MCS7		0x00080000
+//MCS 2 Spatial Stream
+#define	RATR_MCS8		0x00100000
+#define	RATR_MCS9		0x00200000
+#define	RATR_MCS10		0x00400000
+#define	RATR_MCS11		0x00800000
+#define	RATR_MCS12		0x01000000
+#define	RATR_MCS13		0x02000000
+#define	RATR_MCS14		0x04000000
+#define	RATR_MCS15		0x08000000
+// ALL CCK Rate
+#define RATE_ALL_CCK		RATR_1M|RATR_2M|RATR_55M|RATR_11M
+#define RATE_ALL_OFDM_AG	RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|RATR_36M|RATR_48M|RATR_54M
+#define RATE_ALL_OFDM_1SS	RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 | \
+									RATR_MCS4|RATR_MCS5|RATR_MCS6	|RATR_MCS7
+#define RATE_ALL_OFDM_2SS	RATR_MCS8|RATR_MCS9	|RATR_MCS10|RATR_MCS11| \
+									RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
+
+
+	DRIVER_RSSI		= 0x32c,	// Driver tell Firmware current RSSI
+	MCS_TXAGC		= 0x340, // MCS AGC
+	CCK_TXAGC		= 0x348, // CCK AGC
+//	IMR			= 0x354, // Interrupt Mask Register
+//	IMR_POLL		= 0x360,
+	MacBlkCtrl		= 0x403, // Mac block on/off control register
+
+	//Cmd9346CR		= 0x00e,
+//#define Cmd9346CR_9356SEL	(1<<4)
+#if 0
+/* 0x0006 - 0x0007 - reserved */
+	RXFIFOCOUNT 		= 0x010,
+	TXFIFOCOUNT 		= 0x012,
+	BQREQ 			= 0x013,
+/* 0x0010 - 0x0017 - reserved */
+	TSFTR 			= 0x018,
+	TLPDA 			= 0x020,
+	TNPDA 			= 0x024,
+	THPDA 			= 0x028,
+	BSSID 			= 0x02E,
+	RESP_RATE 		= 0x034,
+	CMD 			= 0x037,
+#define CMD_RST_SHIFT 4
+#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
+#define CMD_RX_ENABLE_SHIFT 3
+#define CMD_TX_ENABLE_SHIFT 2
+#define CR_RST      ((1<< 4))
+#define CR_RE       ((1<< 3))
+#define CR_TE       ((1<< 2))
+#define CR_MulRW    ((1<< 0))
+
+	INTA 			= 0x03e,
+#endif
+
+///////////////////
+//////////////////
+#if 0
+	TX_CONF 		= 0x040,
+#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
+#define TX_LOOPBACK_SHIFT 17
+#define TX_LOOPBACK_MAC 1
+#define TX_LOOPBACK_BASEBAND 2
+#define TX_LOOPBACK_NONE 0
+#define TX_LOOPBACK_CONTINUE 3
+#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
+#define TX_LRLRETRY_SHIFT 0
+#define TX_SRLRETRY_SHIFT 8
+#define TX_NOICV_SHIFT 19
+#define TX_NOCRC_SHIFT 16
+#define TCR_DurProcMode  ((1<<30))
+#define TCR_DISReqQsize  ((1<<28))
+#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
+#define TCR_HWVERID_SHIFT 25
+#define TCR_SWPLCPLEN     ((1<<24))
+#define TCR_PLCP_LEN TCR_SAT // rtl8180
+#define TCR_MXDMA_MASK   ((1<<23)|(1<<22)|(1<<21))
+#define TCR_MXDMA_1024 6
+#define TCR_MXDMA_2048 7
+#define TCR_MXDMA_SHIFT  21
+#define TCR_DISCW   ((1<<20))
+#define TCR_ICV     ((1<<19))
+#define TCR_LBK     ((1<<18)|(1<<17))
+#define TCR_LBK1    ((1<<18))
+#define TCR_LBK0    ((1<<17))
+#define TCR_CRC     ((1<<16))
+#define TCR_SRL_MASK   ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
+#define TCR_LRL_MASK   ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
+#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
+
+	RX_CONF 		= 0x044,
+#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
+(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
+#define RX_CHECK_BSSID_SHIFT 23
+#define ACCEPT_PWR_FRAME_SHIFT 22
+#define ACCEPT_MNG_FRAME_SHIFT 20
+#define ACCEPT_CTL_FRAME_SHIFT 19
+#define ACCEPT_DATA_FRAME_SHIFT 18
+#define ACCEPT_ICVERR_FRAME_SHIFT 12
+#define ACCEPT_CRCERR_FRAME_SHIFT 5
+#define ACCEPT_BCAST_FRAME_SHIFT 3
+#define ACCEPT_MCAST_FRAME_SHIFT 2
+#define ACCEPT_ALLMAC_FRAME_SHIFT 0
+#define ACCEPT_NICMAC_FRAME_SHIFT 1
+#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
+#define RX_FIFO_THRESHOLD_SHIFT 13
+#define RX_FIFO_THRESHOLD_128 3
+#define RX_FIFO_THRESHOLD_256 4
+#define RX_FIFO_THRESHOLD_512 5
+#define RX_FIFO_THRESHOLD_1024 6
+#define RX_FIFO_THRESHOLD_NONE 7
+#define RX_AUTORESETPHY_SHIFT 28
+#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
+#define MAX_RX_DMA_2048 7
+#define MAX_RX_DMA_1024	6
+#define MAX_RX_DMA_SHIFT 10
+#define RCR_ONLYERLPKT ((1<<31))
+#define RCR_CS_SHIFT   29
+#define RCR_CS_MASK    ((1<<30) | (1<<29))
+#define RCR_ENMARP     ((1<<28))
+#define RCR_CBSSID     ((1<<23))
+#define RCR_APWRMGT    ((1<<22))
+#define RCR_ADD3       ((1<<21))
+#define RCR_AMF        ((1<<20))
+#define RCR_ACF        ((1<<19))
+#define RCR_ADF        ((1<<18))
+#define RCR_RXFTH      ((1<<15)|(1<<14)|(1<<13))
+#define RCR_RXFTH2     ((1<<15))
+#define RCR_RXFTH1     ((1<<14))
+#define RCR_RXFTH0     ((1<<13))
+#define RCR_AICV       ((1<<12))
+#define RCR_MXDMA      ((1<<10)|(1<< 9)|(1<< 8))
+#define RCR_MXDMA2     ((1<<10))
+#define RCR_MXDMA1     ((1<< 9))
+#define RCR_MXDMA0     ((1<< 8))
+#define RCR_9356SEL    ((1<< 6))
+#define RCR_ACRC32     ((1<< 5))
+#define RCR_AB         ((1<< 3))
+#define RCR_AM         ((1<< 2))
+#define RCR_APM        ((1<< 1))
+#define RCR_AAP        ((1<< 0))
+
+	INT_TIMEOUT 		= 0x048,
+
+	TX_BEACON_RING_ADDR 	= 0x04c,
+
+#endif
+#if 0
+	CONFIG0 		= 0x051,
+#define CONFIG0_WEP104     ((1<<6))
+#define CONFIG0_LEDGPO_En  ((1<<4))
+#define CONFIG0_Aux_Status ((1<<3))
+#define CONFIG0_GL         ((1<<1)|(1<<0))
+#define CONFIG0_GL1        ((1<<1))
+#define CONFIG0_GL0        ((1<<0))
+	CONFIG1 		= 0x052,
+#define CONFIG1_LEDS       ((1<<7)|(1<<6))
+#define CONFIG1_LEDS1      ((1<<7))
+#define CONFIG1_LEDS0      ((1<<6))
+#define CONFIG1_LWACT      ((1<<4))
+#define CONFIG1_MEMMAP     ((1<<3))
+#define CONFIG1_IOMAP      ((1<<2))
+#define CONFIG1_VPD        ((1<<1))
+#define CONFIG1_PMEn       ((1<<0))
+	CONFIG2 		= 0x053,
+#define CONFIG2_LCK        ((1<<7))
+#define CONFIG2_ANT        ((1<<6))
+#define CONFIG2_DPS        ((1<<3))
+#define CONFIG2_PAPE_sign  ((1<<2))
+#define CONFIG2_PAPE_time  ((1<<1)|(1<<0))
+#define CONFIG2_PAPE_time1 ((1<<1))
+#define CONFIG2_PAPE_time0 ((1<<0))
+	ANA_PARAM 		= 0x054,
+	CONFIG3 		= 0x059,
+#define CONFIG3_GNTSel     ((1<<7))
+#define CONFIG3_PARM_En    ((1<<6))
+#define CONFIG3_Magic      ((1<<5))
+#define CONFIG3_CardB_En   ((1<<3))
+#define CONFIG3_CLKRUN_En  ((1<<2))
+#define CONFIG3_FuncRegEn  ((1<<1))
+#define CONFIG3_FBtbEn     ((1<<0))
+#define CONFIG3_CLKRUN_SHIFT 2
+#define CONFIG3_ANAPARAM_W_SHIFT 6
+	CONFIG4 		= 0x05a,
+#define CONFIG4_VCOPDN     ((1<<7))
+#define CONFIG4_PWROFF     ((1<<6))
+#define CONFIG4_PWRMGT     ((1<<5))
+#define CONFIG4_LWPME      ((1<<4))
+#define CONFIG4_LWPTN      ((1<<2))
+#define CONFIG4_RFTYPE     ((1<<1)|(1<<0))
+#define CONFIG4_RFTYPE1    ((1<<1))
+#define CONFIG4_RFTYPE0    ((1<<0))
+	TESTR 			= 0x05b,
+#define TFPC_AC  0x05C
+
+#define SCR 0x05F
+	PGSELECT 		= 0x05e,
+#define PGSELECT_PG_SHIFT 0
+	SECURITY 		= 0x05f,
+#define SECURITY_WEP_TX_ENABLE_SHIFT 1
+#define SECURITY_WEP_RX_ENABLE_SHIFT 0
+#define SECURITY_ENCRYP_104 1
+#define SECURITY_ENCRYP_SHIFT 4
+#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
+
+	ANA_PARAM2 		= 0x060,
+	BEACON_INTERVAL 	= 0x070,
+#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
+(1<<6)|(1<<7)|(1<<8)|(1<<9))
+
+	ATIM_WND 		= 0x072,
+#define ATIM_WND_MASK      (0x01FF)
+
+	BCN_INTR_ITV 		= 0x074,
+#define BCN_INTR_ITV_MASK  (0x01FF)
+
+	ATIM_INTR_ITV		= 0x076,
+#define ATIM_INTR_ITV_MASK  (0x01FF)
+
+	AckTimeOutReg      	= 0x079, //ACK timeout register, in unit of 4 us.
+	PHY_ADR 		= 0x07c,
+	PHY_READ 		= 0x07e,
+	RFPinsOutput 		= 0x080,
+	RFPinsEnable 		= 0x082,
+//Page 0
+	RFPinsSelect 		= 0x084,
+#define SW_CONTROL_GPIO 0x400
+	RFPinsInput 		= 0x086,
+	RF_PARA 		= 0x088,
+	RF_TIMING 		= 0x08c,
+	GP_ENABLE 		= 0x090,
+	GPIO 			= 0x091,
+	TX_AGC_CTL 		= 0x09c,
+#define TX_AGC_CTL_PER_PACKET_TXAGC	0x01
+#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
+#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
+#define TX_AGC_CTL_FEEDBACK_ANT 2
+#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02
+	OFDM_TXAGC 		= 0x09e,
+	ANTSEL 			= 0x09f,
+
+
+
+	SIFS 			= 0x0b4,
+	DIFS 			= 0x0b5,
+	SLOT 			= 0x0b6,
+	CW_CONF 		= 0x0bc,
+#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02
+#define CW_CONF_PERPACKET_CW 0x01
+#define CW_CONF_PERPACKET_RETRY_SHIFT 1
+#define CW_CONF_PERPACKET_CW_SHIFT 0
+	CW_VAL 			= 0x0bd,
+	RATE_FALLBACK 		= 0x0be,
+#define MAX_RESP_RATE_SHIFT 4
+#define MIN_RESP_RATE_SHIFT 0
+#define RATE_FALLBACK_CTL_ENABLE  0x80
+#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
+	ACM_CONTROL             = 0x0BF,      // ACM Control Registe
+//----------------------------------------------------------------------------
+//       8187B ACM_CONTROL bits						(Offset 0xBF, 1 Byte)
+//----------------------------------------------------------------------------
+#define VOQ_ACM_EN				(0x01 << 7) //BIT7
+#define VIQ_ACM_EN				(0x01 << 6) //BIT6
+#define BEQ_ACM_EN				(0x01 << 5) //BIT5
+#define ACM_HW_EN				(0x01 << 4) //BIT4
+#define TXOPSEL					(0x01 << 3) //BIT3
+#define VOQ_ACM_CTL				(0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
+#define VIQ_ACM_CTL				(0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
+#define BEQ_ACM_CTL				(0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
+	CONFIG5 		= 0x0D8,
+#define CONFIG5_TX_FIFO_OK ((1<<7))
+#define CONFIG5_RX_FIFO_OK ((1<<6))
+#define CONFIG5_CALON      ((1<<5))
+#define CONFIG5_EACPI      ((1<<2))
+#define CONFIG5_LANWake    ((1<<1))
+#define CONFIG5_PME_STS    ((1<<0))
+	TX_DMA_POLLING 		= 0x0fd,
+#define TX_DMA_POLLING_BEACON_SHIFT 7
+#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
+#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
+#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
+#define TX_DMA_STOP_BEACON_SHIFT 3
+#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
+#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
+#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
+	CWR 			= 0x0DC,
+	RetryCTR 		= 0x0DE,
+	INT_MIG                 = 0x0E2,      // Interrupt Migration (0xE2 ~ 0xE3)
+	TID_AC_MAP         	= 0x0E8,     // TID to AC Mapping Register
+	ANA_PARAM3 		= 0x0EE,
+
+
+//page 1
+	Wakeup0 		= 0x084,
+	Wakeup1 		= 0x08C,
+	Wakeup2LD 		= 0x094,
+	Wakeup2HD 		= 0x09C,
+	Wakeup3LD 		= 0x0A4,
+	Wakeup3HD 		= 0x0AC,
+	Wakeup4LD 		= 0x0B4,
+	Wakeup4HD 		= 0x0BC,
+	CRC0 			= 0x0C4,
+	CRC1 			= 0x0C6,
+	CRC2 			= 0x0C8,
+	CRC3 			= 0x0CA,
+	CRC4 			= 0x0CC,
+/* 0x00CE - 0x00D3 - reserved */
+
+	RFSW_CTRL               = 0x272,   // 0x272-0x273.
+
+/**************************************************************************/
+	FER 			= 0x0F0,
+	FEMR 			= 0x0F4,
+	FPSR 			= 0x0F8,
+	FFER 			= 0x0FC,
+
+	AC_VO_PARAM             = 0x0F0,      // AC_VO Parameters Record
+	AC_VI_PARAM             = 0x0F4,      // AC_VI Parameters Record
+	AC_BE_PARAM             = 0x0F8,      // AC_BE Parameters Record
+	AC_BK_PARAM             = 0x0FC,      // AC_BK Parameters Record
+	TALLY_SEL 		= 0x0fc,
+#endif
+}
+;
+//----------------------------------------------------------------------------
+//       818xB AnaParm & AnaParm2 Register
+//----------------------------------------------------------------------------
+//#define ANAPARM_ASIC_ON    0x45090658
+//#define ANAPARM2_ASIC_ON   0x727f3f52
+
+#define GPI 0x108
+#define GPO 0x109
+#define GPE 0x10a
+#endif
diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c
new file mode 100644
index 0000000..e9e799c
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192E_wx.c
@@ -0,0 +1,1344 @@
+/*
+   This file contains wireless extension handlers.
+
+   This is part of rtl8180 OpenSource driver.
+   Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
+   Released under the terms of GPL (General Public Licence)
+
+   Parts of this driver are based on the GPL part
+   of the official realtek driver.
+
+   Parts of this driver are based on the rtl8180 driver skeleton
+   from Patric Schenke & Andres Salomon.
+
+   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
+
+   We want to tanks the Authors of those projects and the Ndiswrapper
+   project Authors.
+*/
+
+#include <linux/string.h>
+#include "r8192E.h"
+#include "r8192E_hw.h"
+#include "r8192E_wx.h"
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+
+#define RATE_COUNT 12
+static u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
+	6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
+
+
+#ifndef ENETDOWN
+#define ENETDOWN 1
+#endif
+static int r8192_wx_get_freq(struct net_device *dev,
+			     struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
+}
+
+
+static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv=ieee80211_priv(dev);
+
+	return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
+}
+
+
+
+static int r8192_wx_get_rate(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
+}
+
+
+
+static int r8192_wx_set_rate(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+
+static int r8192_wx_set_rts(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+static int r8192_wx_get_rts(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra);
+}
+
+static int r8192_wx_set_power(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+static int r8192_wx_get_power(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra);
+}
+
+#ifdef JOHN_IOCTL
+u16 read_rtl8225(struct net_device *dev, u8 addr);
+void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
+u32 john_read_rtl8225(struct net_device *dev, u8 adr);
+void _write_rtl8225(struct net_device *dev, u8 adr, u16 data);
+
+static int r8192_wx_read_regs(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 addr;
+	u16 data1;
+
+	down(&priv->wx_sem);
+
+
+	get_user(addr,(u8*)wrqu->data.pointer);
+	data1 = read_rtl8225(dev, addr);
+	wrqu->data.length = data1;
+
+	up(&priv->wx_sem);
+	return 0;
+
+}
+
+static int r8192_wx_write_regs(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        u8 addr;
+
+        down(&priv->wx_sem);
+
+        get_user(addr, (u8*)wrqu->data.pointer);
+	write_rtl8225(dev, addr, wrqu->data.length);
+
+        up(&priv->wx_sem);
+	return 0;
+
+}
+
+void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
+u8 rtl8187_read_phy(struct net_device *dev,u8 adr, u32 data);
+
+static int r8192_wx_read_bb(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 databb;
+#if 0
+	int i;
+	for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
+#endif
+
+        down(&priv->wx_sem);
+
+	databb = rtl8187_read_phy(dev, (u8)wrqu->data.length, 0x00000000);
+	wrqu->data.length = databb;
+
+	up(&priv->wx_sem);
+	return 0;
+}
+
+void rtl8187_write_phy(struct net_device *dev, u8 adr, u32 data);
+static int r8192_wx_write_bb(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        u8 databb;
+
+        down(&priv->wx_sem);
+
+        get_user(databb, (u8*)wrqu->data.pointer);
+        rtl8187_write_phy(dev, wrqu->data.length, databb);
+
+        up(&priv->wx_sem);
+        return 0;
+
+}
+
+
+static int r8192_wx_write_nicb(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        u32 addr;
+
+        down(&priv->wx_sem);
+
+        get_user(addr, (u32*)wrqu->data.pointer);
+        write_nic_byte(dev, addr, wrqu->data.length);
+
+        up(&priv->wx_sem);
+        return 0;
+
+}
+static int r8192_wx_read_nicb(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        u32 addr;
+        u16 data1;
+
+        down(&priv->wx_sem);
+
+        get_user(addr,(u32*)wrqu->data.pointer);
+        data1 = read_nic_byte(dev, addr);
+        wrqu->data.length = data1;
+
+        up(&priv->wx_sem);
+        return 0;
+}
+
+static int r8192_wx_get_ap_status(struct net_device *dev,
+                               struct iw_request_info *info,
+                               union iwreq_data *wrqu, char *extra)
+{
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        struct ieee80211_device *ieee = priv->ieee80211;
+        struct ieee80211_network *target;
+	int name_len;
+
+        down(&priv->wx_sem);
+
+	//count the length of input ssid
+	for(name_len=0 ; ((char*)wrqu->data.pointer)[name_len]!='\0' ; name_len++);
+
+	//search for the correspoding info which is received
+        list_for_each_entry(target, &ieee->network_list, list) {
+                if ( (target->ssid_len == name_len) &&
+		     (strncmp(target->ssid, (char*)wrqu->data.pointer, name_len)==0)){
+			if(target->wpa_ie_len>0 || target->rsn_ie_len>0 )
+				//set flags=1 to indicate this ap is WPA
+				wrqu->data.flags = 1;
+			else wrqu->data.flags = 0;
+
+
+		break;
+                }
+        }
+
+        up(&priv->wx_sem);
+        return 0;
+}
+
+
+
+#endif
+
+static int r8192_wx_set_rawtx(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+
+}
+
+static int r8192_wx_force_reset(struct net_device *dev,
+		struct iw_request_info *info,
+		union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra);
+	priv->force_reset = *extra;
+	up(&priv->wx_sem);
+	return 0;
+
+}
+
+
+static int r8192_wx_set_crcmon(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int *parms = (int *)extra;
+	int enable = (parms[0] > 0);
+	short prev = priv->crcmon;
+
+	down(&priv->wx_sem);
+
+	if(enable)
+		priv->crcmon=1;
+	else
+		priv->crcmon=0;
+
+	DMESG("bad CRC in monitor mode are %s",
+	      priv->crcmon ? "accepted" : "rejected");
+
+	if(prev != priv->crcmon && priv->up){
+		//rtl8180_down(dev);
+		//rtl8180_up(dev);
+	}
+
+	up(&priv->wx_sem);
+
+	return 0;
+}
+
+static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_RF_POWER_STATE	rtState;
+	int ret;
+
+	rtState = priv->ieee80211->eRFPowerState;
+	down(&priv->wx_sem);
+#ifdef ENABLE_IPS
+	if(wrqu->mode == IW_MODE_ADHOC){
+
+		if(priv->ieee80211->PowerSaveControl.bInactivePs){
+			if(rtState == eRfOff){
+				if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
+				{
+					RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
+					up(&priv->wx_sem);
+					return -1;
+				}
+				else{
+				printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+					IPSLeave(dev);
+				}
+			}
+		}
+	}
+#endif
+	ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
+
+	//rtl8187_set_rxconf(dev);
+
+	up(&priv->wx_sem);
+	return ret;
+}
+
+struct  iw_range_with_scan_capa
+{
+        /* Informative stuff (to choose between different interface) */
+        __u32           throughput;     /* To give an idea... */
+        /* In theory this value should be the maximum benchmarked
+         * TCP/IP throughput, because with most of these devices the
+         * bit rate is meaningless (overhead an co) to estimate how
+         * fast the connection will go and pick the fastest one.
+         * I suggest people to play with Netperf or any benchmark...
+         */
+
+        /* NWID (or domain id) */
+        __u32           min_nwid;       /* Minimal NWID we are able to set */
+        __u32           max_nwid;       /* Maximal NWID we are able to set */
+
+        /* Old Frequency (backward compat - moved lower ) */
+        __u16           old_num_channels;
+        __u8            old_num_frequency;
+
+        /* Scan capabilities */
+        __u8            scan_capa;
+};
+static int rtl8180_wx_get_range(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct iw_range *range = (struct iw_range *)extra;
+	struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u16 val;
+	int i;
+
+	wrqu->data.length = sizeof(*range);
+	memset(range, 0, sizeof(*range));
+
+	/* Let's try to keep this struct in the same order as in
+	 * linux/include/wireless.h
+	 */
+
+	/* TODO: See what values we can set, and remove the ones we can't
+	 * set, or fill them with some default data.
+	 */
+
+	/* ~5 Mb/s real (802.11b) */
+	range->throughput = 5 * 1000 * 1000;
+
+	// TODO: Not used in 802.11b?
+//	range->min_nwid;	/* Minimal NWID we are able to set */
+	// TODO: Not used in 802.11b?
+//	range->max_nwid;	/* Maximal NWID we are able to set */
+
+        /* Old Frequency (backward compat - moved lower ) */
+//	range->old_num_channels;
+//	range->old_num_frequency;
+//	range->old_freq[6]; /* Filler to keep "version" at the same offset */
+	if(priv->rf_set_sens != NULL)
+		range->sensitivity = priv->max_sens;	/* signal level threshold range */
+
+	range->max_qual.qual = 100;
+	/* TODO: Find real max RSSI and stick here */
+	range->max_qual.level = 0;
+	range->max_qual.noise = -98;
+	range->max_qual.updated = 7; /* Updated all three */
+
+	range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
+	/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
+	range->avg_qual.level = 20 + -98;
+	range->avg_qual.noise = 0;
+	range->avg_qual.updated = 7; /* Updated all three */
+
+	range->num_bitrates = RATE_COUNT;
+
+	for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
+		range->bitrate[i] = rtl8180_rates[i];
+	}
+
+	range->min_frag = MIN_FRAG_THRESHOLD;
+	range->max_frag = MAX_FRAG_THRESHOLD;
+
+	range->min_pmp=0;
+	range->max_pmp = 5000000;
+	range->min_pmt = 0;
+	range->max_pmt = 65535*1000;
+	range->pmp_flags = IW_POWER_PERIOD;
+	range->pmt_flags = IW_POWER_TIMEOUT;
+	range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 16;
+
+//	range->retry_capa;	/* What retry options are supported */
+//	range->retry_flags;	/* How to decode max/min retry limit */
+//	range->r_time_flags;	/* How to decode max/min retry life */
+//	range->min_retry;	/* Minimal number of retries */
+//	range->max_retry;	/* Maximal number of retries */
+//	range->min_r_time;	/* Minimal retry lifetime */
+//	range->max_r_time;	/* Maximal retry lifetime */
+
+
+	for (i = 0, val = 0; i < 14; i++) {
+
+		// Include only legal frequencies for some countries
+#ifdef ENABLE_DOT11D
+		if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
+#else
+		if ((priv->ieee80211->channel_map)[i+1]) {
+#endif
+		        range->freq[val].i = i + 1;
+			range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
+			range->freq[val].e = 1;
+			val++;
+		} else {
+			// FIXME: do we need to set anything for channels
+			// we don't use ?
+		}
+
+		if (val == IW_MAX_FREQUENCIES)
+		break;
+	}
+	range->num_frequency = val;
+	range->num_channels = val;
+#if WIRELESS_EXT > 17
+	range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
+			  IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+	tmp->scan_capa = 0x01;
+	return 0;
+}
+
+
+static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	RT_RF_POWER_STATE	rtState;
+	int ret;
+	rtState = priv->ieee80211->eRFPowerState;
+	if(!priv->up) return -ENETDOWN;
+	if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
+		return -EAGAIN;
+
+	if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
+	{
+		struct iw_scan_req* req = (struct iw_scan_req*)b;
+		if (req->essid_len)
+		{
+			//printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
+			ieee->current_network.ssid_len = req->essid_len;
+			memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
+			//printk("=====>network ssid:%s\n", ieee->current_network.ssid);
+		}
+	}
+
+	down(&priv->wx_sem);
+#ifdef ENABLE_IPS
+	priv->ieee80211->actscanning = true;
+	if(priv->ieee80211->state != IEEE80211_LINKED){
+		if(priv->ieee80211->PowerSaveControl.bInactivePs){
+			if(rtState == eRfOff){
+				if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
+				{
+					RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
+					up(&priv->wx_sem);
+					return -1;
+				}
+				else{
+					printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+					IPSLeave(dev);
+				}
+			}
+		}
+		priv->ieee80211->scanning = 0;
+		ieee80211_softmac_scan_syncro(priv->ieee80211);
+		ret = 0;
+	}
+	else
+#else
+
+	if(priv->ieee80211->state != IEEE80211_LINKED){
+		priv->ieee80211->scanning = 0;
+		ieee80211_softmac_scan_syncro(priv->ieee80211);
+		ret = 0;
+	}
+	else
+#endif
+	ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
+
+	up(&priv->wx_sem);
+	return ret;
+}
+
+
+static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(!priv->up) return -ENETDOWN;
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+static int r8192_wx_set_essid(struct net_device *dev,
+			      struct iw_request_info *a,
+			      union iwreq_data *wrqu, char *b)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_RF_POWER_STATE	rtState;
+	int ret;
+
+	rtState = priv->ieee80211->eRFPowerState;
+	down(&priv->wx_sem);
+#ifdef ENABLE_IPS
+	if(priv->ieee80211->PowerSaveControl.bInactivePs){
+		if(rtState == eRfOff){
+			if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
+			{
+				RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
+				up(&priv->wx_sem);
+				return -1;
+			}
+			else{
+				printk("=========>%s(): IPSLeave\n",__FUNCTION__);
+				IPSLeave(dev);
+			}
+		}
+	}
+#endif
+	ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+
+
+
+static int r8192_wx_get_essid(struct net_device *dev,
+			      struct iw_request_info *a,
+			      union iwreq_data *wrqu, char *b)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
+
+	up(&priv->wx_sem);
+
+	return ret;
+}
+
+
+static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
+			     union iwreq_data *wrqu, char *b)
+{
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
+
+	up(&priv->wx_sem);
+	return ret;
+}
+
+static int r8192_wx_get_name(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
+}
+
+
+static int r8192_wx_set_frag(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if (wrqu->frag.disabled)
+		priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
+	else {
+		if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
+		    wrqu->frag.value > MAX_FRAG_THRESHOLD)
+			return -EINVAL;
+
+		priv->ieee80211->fts = wrqu->frag.value & ~0x1;
+	}
+
+	return 0;
+}
+
+
+static int r8192_wx_get_frag(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	wrqu->frag.value = priv->ieee80211->fts;
+	wrqu->frag.fixed = 0;	/* no auto select */
+	wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
+
+	return 0;
+}
+
+
+static int r8192_wx_set_wap(struct net_device *dev,
+			 struct iw_request_info *info,
+			 union iwreq_data *awrq,
+			 char *extra)
+{
+
+	int ret;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+//        struct sockaddr *temp = (struct sockaddr *)awrq;
+
+	down(&priv->wx_sem);
+
+	ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
+
+	up(&priv->wx_sem);
+
+	return ret;
+
+}
+
+
+static int r8192_wx_get_wap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
+}
+
+
+static int r8192_wx_get_enc(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *key)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
+}
+
+static int r8192_wx_set_enc(struct net_device *dev,
+			    struct iw_request_info *info,
+			    union iwreq_data *wrqu, char *key)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int ret;
+
+	struct ieee80211_device *ieee = priv->ieee80211;
+	//u32 TargetContent;
+	u32 hwkey[4]={0,0,0,0};
+	u8 mask=0xff;
+	u32 key_idx=0;
+	u8 zero_addr[4][6] ={	{0x00,0x00,0x00,0x00,0x00,0x00},
+				{0x00,0x00,0x00,0x00,0x00,0x01},
+				{0x00,0x00,0x00,0x00,0x00,0x02},
+				{0x00,0x00,0x00,0x00,0x00,0x03} };
+	int i;
+
+       if(!priv->up) return -ENETDOWN;
+
+	down(&priv->wx_sem);
+
+	RT_TRACE(COMP_SEC, "Setting SW wep key");
+	ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
+
+	up(&priv->wx_sem);
+
+
+	//sometimes, the length is zero while we do not type key value
+	if(wrqu->encoding.length!=0){
+
+		for(i=0 ; i<4 ; i++){
+			hwkey[i] |=  key[4*i+0]&mask;
+			if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00;
+			if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00;
+			hwkey[i] |= (key[4*i+1]&mask)<<8;
+			hwkey[i] |= (key[4*i+2]&mask)<<16;
+			hwkey[i] |= (key[4*i+3]&mask)<<24;
+		}
+
+		#define CONF_WEP40  0x4
+		#define CONF_WEP104 0x14
+
+		switch(wrqu->encoding.flags & IW_ENCODE_INDEX){
+			case 0: key_idx = ieee->tx_keyidx; break;
+			case 1:	key_idx = 0; break;
+			case 2:	key_idx = 1; break;
+			case 3:	key_idx = 2; break;
+			case 4:	key_idx	= 3; break;
+			default: break;
+		}
+
+		//printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags);
+		if(wrqu->encoding.length==0x5){
+		ieee->pairwise_key_type = KEY_TYPE_WEP40;
+			EnableHWSecurityConfig8192(dev);
+			setKey( dev,
+				key_idx,                //EntryNo
+				key_idx,                //KeyIndex
+				KEY_TYPE_WEP40,         //KeyType
+				zero_addr[key_idx],
+				0,                      //DefaultKey
+				hwkey);                 //KeyContent
+
+#if 0
+			if(key_idx == 0){
+
+				//write_nic_byte(dev, SECR, 7);
+				setKey( dev,
+					4,                      //EntryNo
+					key_idx,                      //KeyIndex
+					KEY_TYPE_WEP40,        //KeyType
+					broadcast_addr,         //addr
+					0,                      //DefaultKey
+					hwkey);                 //KeyContent
+			}
+#endif
+		}
+
+		else if(wrqu->encoding.length==0xd){
+			ieee->pairwise_key_type = KEY_TYPE_WEP104;
+				EnableHWSecurityConfig8192(dev);
+			setKey( dev,
+				key_idx,                //EntryNo
+				key_idx,                //KeyIndex
+				KEY_TYPE_WEP104,        //KeyType
+				zero_addr[key_idx],
+				0,                      //DefaultKey
+				hwkey);                 //KeyContent
+#if 0
+			if(key_idx == 0){
+
+				//write_nic_byte(dev, SECR, 7);
+				setKey( dev,
+					4,                      //EntryNo
+					key_idx,                      //KeyIndex
+					KEY_TYPE_WEP104,        //KeyType
+					broadcast_addr,         //addr
+					0,                      //DefaultKey
+					hwkey);                 //KeyContent
+			}
+#endif
+		}
+		else printk("wrong type in WEP, not WEP40 and WEP104\n");
+
+
+	}
+
+#if 0
+	//consider the setting different key index situation
+	//wrqu->encoding.flags = 801 means that we set key with index "1"
+	if(wrqu->encoding.length==0 && (wrqu->encoding.flags >>8) == 0x8 ){
+		printk("===>1\n");
+		//write_nic_byte(dev, SECR, 7);
+		EnableHWSecurityConfig8192(dev);
+		//copy wpa config from default key(key0~key3) to broadcast key(key5)
+		//
+		key_idx = (wrqu->encoding.flags & 0xf)-1 ;
+		write_cam(dev, (4*6),   0xffff0000|read_cam(dev, key_idx*6) );
+		write_cam(dev, (4*6)+1, 0xffffffff);
+		write_cam(dev, (4*6)+2, read_cam(dev, (key_idx*6)+2) );
+		write_cam(dev, (4*6)+3, read_cam(dev, (key_idx*6)+3) );
+		write_cam(dev, (4*6)+4, read_cam(dev, (key_idx*6)+4) );
+		write_cam(dev, (4*6)+5, read_cam(dev, (key_idx*6)+5) );
+	}
+#endif
+
+	return ret;
+}
+
+
+static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
+ iwreq_data *wrqu, char *p){
+
+ 	struct r8192_priv *priv = ieee80211_priv(dev);
+	int *parms=(int*)p;
+	int mode=parms[0];
+
+	priv->ieee80211->active_scan = mode;
+
+	return 1;
+}
+
+
+
+static int r8192_wx_set_retry(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int err = 0;
+
+	down(&priv->wx_sem);
+
+	if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
+	    wrqu->retry.disabled){
+		err = -EINVAL;
+		goto exit;
+	}
+	if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
+		err = -EINVAL;
+		goto exit;
+	}
+
+	if(wrqu->retry.value > R8180_MAX_RETRY){
+		err= -EINVAL;
+		goto exit;
+	}
+	if (wrqu->retry.flags & IW_RETRY_MAX) {
+		priv->retry_rts = wrqu->retry.value;
+		DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
+
+	}else {
+		priv->retry_data = wrqu->retry.value;
+		DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
+	}
+
+	/* FIXME !
+	 * We might try to write directly the TX config register
+	 * or to restart just the (R)TX process.
+	 * I'm unsure if whole reset is really needed
+	 */
+
+ 	rtl8192_commit(dev);
+	/*
+	if(priv->up){
+		rtl8180_rtx_disable(dev);
+		rtl8180_rx_enable(dev);
+		rtl8180_tx_enable(dev);
+
+	}
+	*/
+exit:
+	up(&priv->wx_sem);
+
+	return err;
+}
+
+static int r8192_wx_get_retry(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+
+	wrqu->retry.disabled = 0; /* can't be disabled */
+
+	if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
+	    IW_RETRY_LIFETIME)
+		return -EINVAL;
+
+	if (wrqu->retry.flags & IW_RETRY_MAX) {
+		wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
+		wrqu->retry.value = priv->retry_rts;
+	} else {
+		wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
+		wrqu->retry.value = priv->retry_data;
+	}
+	//DMESG("returning %d",wrqu->retry.value);
+
+
+	return 0;
+}
+
+static int r8192_wx_get_sens(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	if(priv->rf_set_sens == NULL)
+		return -1; /* we have not this support for this radio */
+	wrqu->sens.value = priv->sens;
+	return 0;
+}
+
+
+static int r8192_wx_set_sens(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	short err = 0;
+	down(&priv->wx_sem);
+	//DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
+	if(priv->rf_set_sens == NULL) {
+		err= -1; /* we have not this support for this radio */
+		goto exit;
+	}
+	if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
+		priv->sens = wrqu->sens.value;
+	else
+		err= -EINVAL;
+
+exit:
+	up(&priv->wx_sem);
+
+	return err;
+}
+
+#if (WIRELESS_EXT >= 18)
+static int r8192_wx_set_enc_ext(struct net_device *dev,
+                                        struct iw_request_info *info,
+                                        union iwreq_data *wrqu, char *extra)
+{
+	int ret=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+
+	down(&priv->wx_sem);
+	ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra);
+
+	{
+		u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
+		u8 zero[6] = {0};
+		u32 key[4] = {0};
+		struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+		struct iw_point *encoding = &wrqu->encoding;
+#if 0
+		static u8 CAM_CONST_ADDR[4][6] = {
+			{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+			{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+			{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+			{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
+#endif
+		u8 idx = 0, alg = 0, group = 0;
+		if ((encoding->flags & IW_ENCODE_DISABLED) ||
+		ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
+		{
+			ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA;
+			CamResetAllEntry(dev);
+			goto end_hw_sec;
+		}
+		alg =  (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4;
+		idx = encoding->flags & IW_ENCODE_INDEX;
+		if (idx)
+			idx --;
+		group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY;
+
+		if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg ==  KEY_TYPE_WEP40))
+		{
+			if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) )
+				alg = KEY_TYPE_WEP104;
+			ieee->pairwise_key_type = alg;
+			EnableHWSecurityConfig8192(dev);
+		}
+		memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1
+
+		if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) )
+		{
+			if (ext->key_len == 13)
+				ieee->pairwise_key_type = alg = KEY_TYPE_WEP104;
+			setKey( dev,
+					idx,//EntryNo
+					idx, //KeyIndex
+					alg,  //KeyType
+					zero, //MacAddr
+					0,              //DefaultKey
+					key);           //KeyContent
+		}
+		else if (group)
+		{
+			ieee->group_key_type = alg;
+			setKey( dev,
+					idx,//EntryNo
+					idx, //KeyIndex
+					alg,  //KeyType
+					broadcast_addr, //MacAddr
+					0,              //DefaultKey
+					key);           //KeyContent
+		}
+		else //pairwise key
+		{
+			if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
+							write_nic_byte(dev, 0x173, 1); //fix aes bug
+			}
+			setKey( dev,
+					4,//EntryNo
+					idx, //KeyIndex
+					alg,  //KeyType
+					(u8*)ieee->ap_mac_addr, //MacAddr
+					0,              //DefaultKey
+					key);           //KeyContent
+		}
+
+
+	}
+
+end_hw_sec:
+	up(&priv->wx_sem);
+	return ret;
+
+}
+static int r8192_wx_set_auth(struct net_device *dev,
+                                        struct iw_request_info *info,
+                                        union iwreq_data *data, char *extra)
+{
+	int ret=0;
+	//printk("====>%s()\n", __FUNCTION__);
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	down(&priv->wx_sem);
+	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
+	up(&priv->wx_sem);
+	return ret;
+}
+
+static int r8192_wx_set_mlme(struct net_device *dev,
+                                        struct iw_request_info *info,
+                                        union iwreq_data *wrqu, char *extra)
+{
+	//printk("====>%s()\n", __FUNCTION__);
+
+	int ret=0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	down(&priv->wx_sem);
+	ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
+	up(&priv->wx_sem);
+	return ret;
+}
+#endif
+static int r8192_wx_set_gen_ie(struct net_device *dev,
+                                        struct iw_request_info *info,
+                                        union iwreq_data *data, char *extra)
+{
+	   //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
+	int ret=0;
+        struct r8192_priv *priv = ieee80211_priv(dev);
+        down(&priv->wx_sem);
+        ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length);
+        up(&priv->wx_sem);
+	//printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
+        return ret;
+}
+
+static int dummy(struct net_device *dev, struct iw_request_info *a,
+		 union iwreq_data *wrqu,char *b)
+{
+	return -1;
+}
+
+
+static iw_handler r8192_wx_handlers[] =
+{
+        NULL,                     /* SIOCSIWCOMMIT */
+        r8192_wx_get_name,   	  /* SIOCGIWNAME */
+        dummy,                    /* SIOCSIWNWID */
+        dummy,                    /* SIOCGIWNWID */
+        r8192_wx_set_freq,        /* SIOCSIWFREQ */
+        r8192_wx_get_freq,        /* SIOCGIWFREQ */
+        r8192_wx_set_mode,        /* SIOCSIWMODE */
+        r8192_wx_get_mode,        /* SIOCGIWMODE */
+        r8192_wx_set_sens,        /* SIOCSIWSENS */
+        r8192_wx_get_sens,        /* SIOCGIWSENS */
+        NULL,                     /* SIOCSIWRANGE */
+        rtl8180_wx_get_range,	  /* SIOCGIWRANGE */
+        NULL,                     /* SIOCSIWPRIV */
+        NULL,                     /* SIOCGIWPRIV */
+        NULL,                     /* SIOCSIWSTATS */
+        NULL,                     /* SIOCGIWSTATS */
+        dummy,                    /* SIOCSIWSPY */
+        dummy,                    /* SIOCGIWSPY */
+        NULL,                     /* SIOCGIWTHRSPY */
+        NULL,                     /* SIOCWIWTHRSPY */
+        r8192_wx_set_wap,      	  /* SIOCSIWAP */
+        r8192_wx_get_wap,         /* SIOCGIWAP */
+#if (WIRELESS_EXT >= 18)
+        r8192_wx_set_mlme,                     /* MLME-- */
+#else
+	 NULL,
+#endif
+        dummy,                     /* SIOCGIWAPLIST -- depricated */
+        r8192_wx_set_scan,        /* SIOCSIWSCAN */
+        r8192_wx_get_scan,        /* SIOCGIWSCAN */
+        r8192_wx_set_essid,       /* SIOCSIWESSID */
+        r8192_wx_get_essid,       /* SIOCGIWESSID */
+        dummy,                    /* SIOCSIWNICKN */
+        dummy,                    /* SIOCGIWNICKN */
+        NULL,                     /* -- hole -- */
+        NULL,                     /* -- hole -- */
+        r8192_wx_set_rate,        /* SIOCSIWRATE */
+        r8192_wx_get_rate,        /* SIOCGIWRATE */
+        r8192_wx_set_rts,                    /* SIOCSIWRTS */
+        r8192_wx_get_rts,                    /* SIOCGIWRTS */
+        r8192_wx_set_frag,        /* SIOCSIWFRAG */
+        r8192_wx_get_frag,        /* SIOCGIWFRAG */
+        dummy,                    /* SIOCSIWTXPOW */
+        dummy,                    /* SIOCGIWTXPOW */
+        r8192_wx_set_retry,       /* SIOCSIWRETRY */
+        r8192_wx_get_retry,       /* SIOCGIWRETRY */
+        r8192_wx_set_enc,         /* SIOCSIWENCODE */
+        r8192_wx_get_enc,         /* SIOCGIWENCODE */
+        r8192_wx_set_power,                    /* SIOCSIWPOWER */
+        r8192_wx_get_power,                    /* SIOCGIWPOWER */
+	NULL,			/*---hole---*/
+	NULL, 			/*---hole---*/
+	r8192_wx_set_gen_ie,//NULL, 			/* SIOCSIWGENIE */
+	NULL, 			/* SIOCSIWGENIE */
+#if (WIRELESS_EXT >= 18)
+	r8192_wx_set_auth,//NULL, 			/* SIOCSIWAUTH */
+	NULL,//r8192_wx_get_auth,//NULL, 			/* SIOCSIWAUTH */
+	r8192_wx_set_enc_ext, 			/* SIOCSIWENCODEEXT */
+#else
+	NULL,
+	NULL,
+	NULL,
+#endif
+	NULL,//r8192_wx_get_enc_ext,//NULL, 			/* SIOCSIWENCODEEXT */
+	NULL, 			/* SIOCSIWPMKSA */
+	NULL, 			 /*---hole---*/
+
+};
+
+
+static const struct iw_priv_args r8192_private_args[] = {
+
+	{
+		SIOCIWFIRSTPRIV + 0x0,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
+	},
+
+	{
+		SIOCIWFIRSTPRIV + 0x1,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
+
+	},
+	{
+		SIOCIWFIRSTPRIV + 0x2,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
+	}
+#ifdef JOHN_IOCTL
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x3,
+                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readRF"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x4,
+                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeRF"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x5,
+                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readBB"
+	}
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x6,
+                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writeBB"
+	}
+        ,
+        {
+                SIOCIWFIRSTPRIV + 0x7,
+                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "readnicb"
+        }
+        ,
+        {
+                SIOCIWFIRSTPRIV + 0x8,
+                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "writenicb"
+        }
+        ,
+        {
+                SIOCIWFIRSTPRIV + 0x9,
+                IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
+        }
+
+#endif
+	,
+	{
+		SIOCIWFIRSTPRIV + 0x3,
+		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
+
+	}
+
+};
+
+
+static iw_handler r8192_private_handler[] = {
+//	r8192_wx_set_monitor,  /* SIOCIWFIRSTPRIV */
+	r8192_wx_set_crcmon,   /*SIOCIWSECONDPRIV*/
+//	r8192_wx_set_forceassociate,
+//	r8192_wx_set_beaconinterval,
+//	r8192_wx_set_monitor_type,
+	r8192_wx_set_scan_type,
+	r8192_wx_set_rawtx,
+#ifdef JOHN_IOCTL
+	r8192_wx_read_regs,
+	r8192_wx_write_regs,
+	r8192_wx_read_bb,
+	r8192_wx_write_bb,
+        r8192_wx_read_nicb,
+        r8192_wx_write_nicb,
+	r8192_wx_get_ap_status
+#endif
+	r8192_wx_force_reset,
+};
+
+//#if WIRELESS_EXT >= 17
+struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
+{
+       struct r8192_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device* ieee = priv->ieee80211;
+	struct iw_statistics* wstats = &priv->wstats;
+	int tmp_level = 0;
+	int tmp_qual = 0;
+	int tmp_noise = 0;
+	if(ieee->state < IEEE80211_LINKED)
+	{
+		wstats->qual.qual = 0;
+		wstats->qual.level = 0;
+		wstats->qual.noise = 0;
+		wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+		return wstats;
+	}
+
+       tmp_level = (&ieee->current_network)->stats.rssi;
+	tmp_qual = (&ieee->current_network)->stats.signal;
+	tmp_noise = (&ieee->current_network)->stats.noise;
+	//printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
+
+	wstats->qual.level = tmp_level;
+	wstats->qual.qual = tmp_qual;
+	wstats->qual.noise = tmp_noise;
+	wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+	return wstats;
+}
+//#endif
+
+
+struct iw_handler_def  r8192_wx_handlers_def={
+	.standard = r8192_wx_handlers,
+	.num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
+	.private = r8192_private_handler,
+	.num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
+ 	.num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
+#if WIRELESS_EXT >= 17
+	.get_wireless_stats = r8192_get_wireless_stats,
+#endif
+	.private_args = (struct iw_priv_args *)r8192_private_args,
+};
diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h
new file mode 100644
index 0000000..79ebdb6
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192E_wx.h
@@ -0,0 +1,22 @@
+/*
+	This is part of rtl8180 OpenSource driver - v 0.3
+	Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+	Released under the terms of GPL (General Public Licence)
+
+	Parts of this driver are based on the GPL part of the official realtek driver
+	Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
+	Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
+
+	We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
+*/
+
+/* this file (will) contains wireless extension handlers*/
+
+#ifndef R8180_WX_H
+#define R8180_WX_H
+//#include <linux/wireless.h>
+//#include "ieee80211.h"
+extern struct iw_handler_def r8192_wx_handlers_def;
+/* Enable  the rtl819x_core.c to share this function, david 2008.9.22 */
+extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
+#endif
diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c
new file mode 100644
index 0000000..feef29b
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192_pm.c
@@ -0,0 +1,172 @@
+/*
+   Power management interface routines.
+   Written by Mariusz Matuszek.
+   This code is currently just a placeholder for later work and
+   does not do anything useful.
+
+   This is part of rtl8180 OpenSource driver.
+   Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+   Released under the terms of GPL (General Public Licence)
+*/
+
+#ifdef CONFIG_PM_RTL
+
+#include "r8192E.h"
+#include "r8192E_hw.h"
+#include "r8192_pm.h"
+#include "r8190_rtl8256.h"
+
+int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state)
+{
+        printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event);
+	return(-EAGAIN);
+}
+
+
+int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8	ucRegRead;
+	u32	ulRegRead;
+
+        RT_TRACE(COMP_POWER, "============> r8192E suspend call.\n");
+	if (!netif_running(dev))
+		goto out_pci_suspend;
+
+	if (dev->netdev_ops->ndo_stop)
+		dev->netdev_ops->ndo_stop(dev);
+//	dev->stop(dev);
+#if 0
+
+	netif_carrier_off(dev);
+
+	ieee80211_softmac_stop_protocol(priv->ieee80211);
+
+	write_nic_byte(dev,MSR,(read_nic_byte(dev,MSR)&0xfc)|MSR_LINK_NONE);
+	if(!priv->ieee80211->bSupportRemoteWakeUp) {
+		/* disable tx/rx. In 8185 we write 0x10 (Reset bit),
+		 * but here we make reference to WMAC and wirte 0x0.
+		 * 2006.11.21 Emily
+		 */
+		write_nic_byte(dev, CMDR, 0);
+	}
+	//disable interrupt
+	write_nic_dword(dev,INTA_MASK,0);
+	priv->irq_enabled = 0;
+        write_nic_dword(dev,ISR,read_nic_dword(dev, ISR));
+
+	/* need to  free DM related functions */
+	cancel_work_sync(&priv->reset_wq);
+	del_timer_sync(&priv->fsync_timer);
+	del_timer_sync(&priv->watch_dog_timer);
+	cancel_delayed_work(&priv->watch_dog_wq);
+	cancel_delayed_work(&priv->update_beacon_wq);
+	cancel_work_sync(&priv->qos_activate);
+
+	/* TODO
+#if ((DEV_BUS_TYPE == PCI_INTERFACE) && (HAL_CODE_BASE == RTL8192))
+pHalData->bHwRfOffAction = 2;
+#endif
+*/
+#endif
+	// Call MgntActSet_RF_State instead to prevent RF config race condition.
+	// By Bruce, 2008-01-17.
+	//
+	if(!priv->ieee80211->bSupportRemoteWakeUp) {
+		MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
+		// 2006.11.30. System reset bit
+		ulRegRead = read_nic_dword(dev, CPU_GEN);
+		ulRegRead|=CPU_GEN_SYSTEM_RESET;
+		write_nic_dword(dev, CPU_GEN, ulRegRead);
+	} else {
+		//2008.06.03 for WOL
+		write_nic_dword(dev, WFCRC0, 0xffffffff);
+		write_nic_dword(dev, WFCRC1, 0xffffffff);
+		write_nic_dword(dev, WFCRC2, 0xffffffff);
+#ifdef RTL8190P
+		//GPIO 0 = TRUE
+		ucRegRead = read_nic_byte(dev, GPO);
+		ucRegRead |= BIT0;
+		write_nic_byte(dev, GPO, ucRegRead);
+#endif
+		//Write PMR register
+		write_nic_byte(dev, PMR, 0x5);
+		//Disable tx, enanble rx
+		write_nic_byte(dev, MacBlkCtrl, 0xa);
+	}
+
+out_pci_suspend:
+	RT_TRACE(COMP_POWER, "r8192E support WOL call??????????????????????\n");
+	if(priv->ieee80211->bSupportRemoteWakeUp) {
+		RT_TRACE(COMP_POWER, "r8192E support WOL call!!!!!!!!!!!!!!!!!!.\n");
+	}
+	netif_device_detach(dev);
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_enable_wake(pdev, pci_choose_state(pdev,state),\
+			priv->ieee80211->bSupportRemoteWakeUp?1:0);
+	pci_set_power_state(pdev,pci_choose_state(pdev,state));
+
+	return 0;
+}
+
+int rtl8192E_resume (struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	//struct r8192_priv *priv = ieee80211_priv(dev);
+	//union iwreq_data wrqu;
+	int err;
+	u32 val;
+
+        RT_TRACE(COMP_POWER, "================>r8192E resume call.");
+
+	pci_set_power_state(pdev, PCI_D0);
+
+	err = pci_enable_device(pdev);
+	if(err) {
+		printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
+				dev->name);
+		return err;
+	}
+
+	pci_restore_state(pdev);
+
+	/*
+	 * Suspend/Resume resets the PCI configuration space, so we have to
+	 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
+	 * from interfering with C3 CPU state. pci_restore_state won't help
+	 * here since it only restores the first 64 bytes pci config header.
+	 */
+	pci_read_config_dword(pdev, 0x40, &val);
+	if ((val & 0x0000ff00) != 0) {
+		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+	}
+
+
+
+	pci_enable_wake(pdev, PCI_D0, 0);
+
+	if(!netif_running(dev))
+		goto out;
+
+	netif_device_attach(dev);
+
+	if (dev->netdev_ops->ndo_open)
+		dev->netdev_ops->ndo_open(dev);
+
+//	dev->open(dev);
+out:
+        RT_TRACE(COMP_POWER, "<================r8192E resume call.\n");
+	return 0;
+}
+
+
+int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable)
+{
+        printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n",
+	       state.event, enable);
+	return(-EAGAIN);
+}
+
+#endif //CONFIG_PM_RTL
diff --git a/drivers/staging/rtl8192e/r8192_pm.h b/drivers/staging/rtl8192e/r8192_pm.h
new file mode 100644
index 0000000..68d292b
--- /dev/null
+++ b/drivers/staging/rtl8192e/r8192_pm.h
@@ -0,0 +1,28 @@
+/*
+        Power management interface routines.
+	Written by Mariusz Matuszek.
+	This code is currently just a placeholder for later work and
+	does not do anything useful.
+
+	This is part of rtl8180 OpenSource driver.
+	Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
+	Released under the terms of GPL (General Public Licence)
+
+*/
+
+#ifdef CONFIG_PM_RTL
+
+#ifndef R8192E_PM_H
+#define R8192E_PM_H
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state);
+int rtl8192E_suspend (struct pci_dev *dev, pm_message_t state);
+int rtl8192E_resume (struct pci_dev *dev);
+int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable);
+
+#endif //R8192E_PM_H
+
+#endif // CONFIG_PM_RTL
diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
new file mode 100644
index 0000000..d6b7d2f
--- /dev/null
+++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.c
@@ -0,0 +1,804 @@
+/******************************************************************************
+
+     (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
+
+ Module:	r819xusb_cmdpkt.c	(RTL8190 TX/RX command packet handler Source C File)
+
+ Note:      The module is responsible for handling TX and RX command packet.
+ 			1. TX : Send set and query configuration command packet.
+ 			2. RX : Receive tx feedback, beacon state, query configuration
+ 			        command packet.
+
+ Function:
+
+ Export:
+
+ Abbrev:
+
+ History:
+	Data		Who		Remark
+
+	05/06/2008  amy    	Create initial version porting from windows driver.
+
+******************************************************************************/
+#include "r8192E.h"
+#include "r8192E_hw.h"
+#include "r819xE_cmdpkt.h"
+/*---------------------------Define Local Constant---------------------------*/
+/* Debug constant*/
+#define		CMPK_DEBOUNCE_CNT			1
+/* 2007/10/24 MH Add for printing a range of data. */
+#define		CMPK_PRINT(Address)\
+{\
+	unsigned char	i;\
+	u32	temp[10];\
+	\
+	memcpy(temp, Address, 40);\
+	for (i = 0; i <40; i+=4)\
+		printk("\r\n %08x", temp[i]);\
+}\
+
+/*---------------------------Define functions---------------------------------*/
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_message_handle_tx()
+ *
+ * Overview:	Driver internal module can call the API to send message to
+ *				firmware side. For example, you can send a debug command packet.
+ *				Or you can send a request for FW to modify RLX4181 LBUS HW bank.
+ *				Otherwise, you can change MAC/PHT/RF register by firmware at
+ *				run time. We do not support message more than one segment now.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/06/2008	amy		porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+RT_STATUS cmpk_message_handle_tx(
+	struct net_device *dev,
+	u8*	code_virtual_address,
+	u32	packettype,
+	u32	buffer_len)
+{
+
+	RT_STATUS 	    rt_status = RT_STATUS_SUCCESS;
+#ifdef RTL8192U
+	return rt_status;
+#else
+	struct r8192_priv   *priv = ieee80211_priv(dev);
+	u16		    frag_threshold;
+	u16		    frag_length = 0, frag_offset = 0;
+	rt_firmware	    *pfirmware = priv->pFirmware;
+	struct sk_buff	    *skb;
+	unsigned char	    *seg_ptr;
+	cb_desc		    *tcb_desc;
+	u8                  bLastIniPkt;
+
+	PTX_FWINFO_8190PCI      pTxFwInfo = NULL;
+        int i;
+
+	//spin_lock_irqsave(&priv->tx_lock,flags);
+	RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
+	firmware_init_param(dev);
+	//Fragmentation might be required
+	frag_threshold = pfirmware->cmdpacket_frag_thresold;
+        do {
+            if((buffer_len - frag_offset) > frag_threshold) {
+                frag_length = frag_threshold ;
+                bLastIniPkt = 0;
+
+            } else {
+                frag_length =(u16)(buffer_len - frag_offset);
+                bLastIniPkt = 1;
+
+            }
+
+            /* Allocate skb buffer to contain firmware info and tx descriptor info
+             * add 4 to avoid packet appending overflow.
+             * */
+#ifdef RTL8192U
+            skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
+#else
+            skb  = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4);
+#endif
+            if(skb == NULL) {
+                rt_status = RT_STATUS_FAILURE;
+                goto Failed;
+            }
+
+            memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
+            tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
+            tcb_desc->queue_index = TXCMD_QUEUE;
+            tcb_desc->bCmdOrInit = packettype;
+            tcb_desc->bLastIniPkt = bLastIniPkt;
+            tcb_desc->pkt_size = frag_length;
+
+#ifdef RTL8192U
+            skb_reserve(skb, USB_HWDESC_HEADER_LEN);
+#endif
+
+            //seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom);
+            seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom);
+
+            pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr;
+            memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
+            memset(pTxFwInfo,0x12,8);
+
+            seg_ptr +=sizeof(TX_FWINFO_8190PCI);
+
+            /*
+             * Transform from little endian to big endian
+             * and pending  zero
+             */
+            seg_ptr = skb->tail;
+            for(i=0 ; i < frag_length; i+=4) {
+                *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
+                *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
+                *seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
+                *seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
+            }
+            skb_put(skb, i);
+            priv->ieee80211->softmac_hard_start_xmit(skb,dev);
+
+            code_virtual_address += frag_length;
+            frag_offset += frag_length;
+
+        }while(frag_offset < buffer_len);
+
+Failed:
+	//spin_unlock_irqrestore(&priv->tx_lock,flags);
+	return rt_status;
+
+
+#endif
+}	/* CMPK_Message_Handle_Tx */
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_counttxstatistic()
+ *
+ * Overview:
+ *
+ * Input:       PADAPTER 	pAdapter		-	.
+ *				CMPK_TXFB_T *psTx_FB	-	.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/12/2008	amy 	Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_count_txstatistic(
+	struct net_device *dev,
+	cmpk_txfb_t	*pstx_fb)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef ENABLE_PS
+	RT_RF_POWER_STATE	rtState;
+
+	pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
+
+	// When RF is off, we should not count the packet for hw/sw synchronize
+	// reason, ie. there may be a duration while sw switch is changed and hw
+	// switch is being changed. 2006.12.04, by shien chang.
+	if (rtState == eRfOff)
+	{
+		return;
+	}
+#endif
+
+#ifdef TODO
+	if(pAdapter->bInHctTest)
+		return;
+#endif
+	/* We can not know the packet length and transmit type: broadcast or uni
+	   or multicast. So the relative statistics must be collected in tx
+	   feedback info. */
+	if (pstx_fb->tok)
+	{
+		priv->stats.txfeedbackok++;
+		priv->stats.txoktotal++;
+		priv->stats.txokbytestotal += pstx_fb->pkt_length;
+		priv->stats.txokinperiod++;
+
+		/* We can not make sure broadcast/multicast or unicast mode. */
+		if (pstx_fb->pkt_type == PACKET_MULTICAST)
+		{
+			priv->stats.txmulticast++;
+			priv->stats.txbytesmulticast += pstx_fb->pkt_length;
+		}
+		else if (pstx_fb->pkt_type == PACKET_BROADCAST)
+		{
+			priv->stats.txbroadcast++;
+			priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
+		}
+		else
+		{
+			priv->stats.txunicast++;
+			priv->stats.txbytesunicast += pstx_fb->pkt_length;
+		}
+	}
+	else
+	{
+		priv->stats.txfeedbackfail++;
+		priv->stats.txerrtotal++;
+		priv->stats.txerrbytestotal += pstx_fb->pkt_length;
+
+		/* We can not make sure broadcast/multicast or unicast mode. */
+		if (pstx_fb->pkt_type == PACKET_MULTICAST)
+		{
+			priv->stats.txerrmulticast++;
+		}
+		else if (pstx_fb->pkt_type == PACKET_BROADCAST)
+		{
+			priv->stats.txerrbroadcast++;
+		}
+		else
+		{
+			priv->stats.txerrunicast++;
+		}
+	}
+
+	priv->stats.txretrycount += pstx_fb->retry_cnt;
+	priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
+
+}	/* cmpk_CountTxStatistic */
+
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_handle_tx_feedback()
+ *
+ * Overview:	The function is responsible for extract the message inside TX
+ *				feedbck message from firmware. It will contain dedicated info in
+ *				ws-06-0063-rtl8190-command-packet-specification. Please
+ *				refer to chapter "TX Feedback Element". We have to read 20 bytes
+ *				in the command packet.
+ *
+ * Input:       struct net_device *    dev
+ *				u8 	*	pmsg		-	Msg Ptr of the command packet.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/08/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_tx_feedback(
+	struct net_device *dev,
+	u8	*	pmsg)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	cmpk_txfb_t		rx_tx_fb;	/* */
+
+	priv->stats.txfeedback++;
+
+	/* 0. Display received message. */
+	//cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg);
+
+	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
+	/* It seems that FW use big endian(MIPS) and DRV use little endian in
+	   windows OS. So we have to read the content byte by byte or transfer
+	   endian type before copy the message copy. */
+#if 0		// The TX FEEDBACK packet element address
+	//rx_tx_fb.Element_ID 	= pMsg[0];
+	//rx_tx_fb.Length 		= pMsg[1];
+	rx_tx_fb.TOK 			= pMsg[2]>>7;
+	rx_tx_fb.Fail_Reason 	= (pMsg[2] & 0x70) >> 4;
+	rx_tx_fb.TID 			= (pMsg[2] & 0x0F);
+	rx_tx_fb.Qos_Pkt 		= pMsg[3] >> 7;
+	rx_tx_fb.Bandwidth 		= (pMsg[3] & 0x40) >> 6;
+	rx_tx_fb.Retry_Cnt 		= pMsg[5];
+	rx_tx_fb.Pkt_ID 		= (pMsg[6] << 8) | pMsg[7];
+	rx_tx_fb.Seq_Num 		= (pMsg[8] << 8) | pMsg[9];
+	rx_tx_fb.S_Rate 		= pMsg[10];
+	rx_tx_fb.F_Rate 		= pMsg[11];
+	rx_tx_fb.S_RTS_Rate 	= pMsg[12];
+	rx_tx_fb.F_RTS_Rate 	= pMsg[13];
+	rx_tx_fb.pkt_length	= (pMsg[14] << 8) | pMsg[15];
+#endif
+	/* 2007/07/05 MH Use pointer to transfer structure memory. */
+	//memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
+	memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
+	/* 2. Use tx feedback info to count TX statistics. */
+	cmpk_count_txstatistic(dev, &rx_tx_fb);
+#if 0
+	/* 2007/07/11 MH Assign current operate rate.  */
+	if (pAdapter->RegWirelessMode == WIRELESS_MODE_A ||
+		pAdapter->RegWirelessMode == WIRELESS_MODE_B ||
+		pAdapter->RegWirelessMode == WIRELESS_MODE_G)
+	{
+		pMgntInfo->CurrentOperaRate = (rx_tx_fb.F_Rate & 0x7F);
+	}
+	else if (pAdapter->RegWirelessMode == WIRELESS_MODE_N_24G ||
+		 	 pAdapter->RegWirelessMode == WIRELESS_MODE_N_5G)
+	{
+		pMgntInfo->HTCurrentOperaRate = (rx_tx_fb.F_Rate & 0x8F);
+	}
+#endif
+	/* 2007/01/17 MH Comment previous method for TX statistic function. */
+	/* Collect info TX feedback packet to fill TCB. */
+	/* We can not know the packet length and transmit type: broadcast or uni
+	   or multicast. */
+	//CountTxStatistics( pAdapter, &tcb );
+
+}	/* cmpk_Handle_Tx_Feedback */
+
+static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u16 tx_rate;
+	{
+		//
+		// 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn.
+		//
+		if((priv->ieee80211->current_network.mode == IEEE_A)  ||
+			(priv->ieee80211->current_network.mode == IEEE_N_5G) ||
+			((priv->ieee80211->current_network.mode == IEEE_N_24G)  && (!priv->ieee80211->pHTInfo->bCurSuppCCK)))
+		{
+			tx_rate = 60;
+			DMESG("send beacon frame  tx rate is 6Mbpm\n");
+		}
+		else
+		{
+			tx_rate =10;
+			DMESG("send beacon frame  tx rate is 1Mbpm\n");
+		}
+
+		//rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon
+
+	}
+
+}
+
+
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_handle_interrupt_status()
+ *
+ * Overview:    The function is responsible for extract the message from
+ *				firmware. It will contain dedicated info in
+ *				ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
+ * 				Please refer to chapter "Interrupt Status Element".
+ *
+ * Input:       struct net_device *dev,
+ *			u8*	pmsg		-	Message Pointer of the command packet.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When			Who			Remark
+ *  05/12/2008	amy		Add this for rtl8192 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_interrupt_status(
+	struct net_device *dev,
+	u8*	pmsg)
+{
+	cmpk_intr_sta_t		rx_intr_status;	/* */
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	DMESG("---> cmpk_Handle_Interrupt_Status()\n");
+
+	/* 0. Display received message. */
+	//cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
+
+	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
+	/* It seems that FW use big endian(MIPS) and DRV use little endian in
+	   windows OS. So we have to read the content byte by byte or transfer
+	   endian type before copy the message copy. */
+	//rx_bcn_state.Element_ID 	= pMsg[0];
+	//rx_bcn_state.Length 		= pMsg[1];
+	rx_intr_status.length = pmsg[1];
+	if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2))
+	{
+		DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
+		return;
+	}
+
+
+	// Statistics of beacon for ad-hoc mode.
+	if(	priv->ieee80211->iw_mode == IW_MODE_ADHOC)
+	{
+		//2 maybe need endian transform?
+		rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
+		//rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4)));
+
+		DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
+
+		if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
+		{
+			priv->ieee80211->bibsscoordinator = true;
+			priv->stats.txbeaconokint++;
+		}
+		else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
+		{
+			priv->ieee80211->bibsscoordinator = false;
+			priv->stats.txbeaconerr++;
+		}
+
+		if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
+		{
+			cmdpkt_beacontimerinterrupt_819xusb(dev);
+		}
+
+	}
+
+	 // Other informations in interrupt status we need?
+
+
+	DMESG("<---- cmpk_handle_interrupt_status()\n");
+
+}	/* cmpk_handle_interrupt_status */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_handle_query_config_rx()
+ *
+ * Overview:    The function is responsible for extract the message from
+ *				firmware. It will contain dedicated info in
+ *				ws-06-0063-rtl8190-command-packet-specification. Please
+ *				refer to chapter "Beacon State Element".
+ *
+ * Input:       u8 *  pmsg	-	Message Pointer of the command packet.
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_query_config_rx(
+	struct net_device *dev,
+	u8*	   pmsg)
+{
+	cmpk_query_cfg_t	rx_query_cfg;	/* */
+
+	/* 0. Display received message. */
+	//cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
+
+	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
+	/* It seems that FW use big endian(MIPS) and DRV use little endian in
+	   windows OS. So we have to read the content byte by byte or transfer
+	   endian type before copy the message copy. */
+	//rx_query_cfg.Element_ID 	= pMsg[0];
+	//rx_query_cfg.Length 		= pMsg[1];
+	rx_query_cfg.cfg_action 	= (pmsg[4] & 0x80000000)>>31;
+	rx_query_cfg.cfg_type 		= (pmsg[4] & 0x60) >> 5;
+	rx_query_cfg.cfg_size 		= (pmsg[4] & 0x18) >> 3;
+	rx_query_cfg.cfg_page 		= (pmsg[6] & 0x0F) >> 0;
+	rx_query_cfg.cfg_offset 		= pmsg[7];
+	rx_query_cfg.value 			= (pmsg[8] << 24) | (pmsg[9] << 16) |
+								  (pmsg[10] << 8) | (pmsg[11] << 0);
+	rx_query_cfg.mask 			= (pmsg[12] << 24) | (pmsg[13] << 16) |
+								  (pmsg[14] << 8) | (pmsg[15] << 0);
+
+}	/* cmpk_Handle_Query_Config_Rx */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_count_tx_status()
+ *
+ * Overview:	Count aggregated tx status from firmwar of one type rx command
+ *				packet element id = RX_TX_STATUS.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void	cmpk_count_tx_status(	struct net_device *dev,
+									cmpk_tx_status_t 	*pstx_status)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+#ifdef ENABLE_PS
+
+	RT_RF_POWER_STATE	rtstate;
+
+	pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
+
+	// When RF is off, we should not count the packet for hw/sw synchronize
+	// reason, ie. there may be a duration while sw switch is changed and hw
+	// switch is being changed. 2006.12.04, by shien chang.
+	if (rtState == eRfOff)
+	{
+		return;
+	}
+#endif
+
+	priv->stats.txfeedbackok	+= pstx_status->txok;
+	priv->stats.txoktotal		+= pstx_status->txok;
+
+	priv->stats.txfeedbackfail	+= pstx_status->txfail;
+	priv->stats.txerrtotal		+= pstx_status->txfail;
+
+	priv->stats.txretrycount		+= pstx_status->txretry;
+	priv->stats.txfeedbackretry	+= pstx_status->txretry;
+
+	//pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length;
+	//pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length;
+	//pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++;
+
+	priv->stats.txmulticast	+= pstx_status->txmcok;
+	priv->stats.txbroadcast	+= pstx_status->txbcok;
+	priv->stats.txunicast		+= pstx_status->txucok;
+
+	priv->stats.txerrmulticast	+= pstx_status->txmcfail;
+	priv->stats.txerrbroadcast	+= pstx_status->txbcfail;
+	priv->stats.txerrunicast	+= pstx_status->txucfail;
+
+	priv->stats.txbytesmulticast	+= pstx_status->txmclength;
+	priv->stats.txbytesbroadcast	+= pstx_status->txbclength;
+	priv->stats.txbytesunicast		+= pstx_status->txuclength;
+
+	priv->stats.last_packet_rate		= pstx_status->rate;
+}	/* cmpk_CountTxStatus */
+
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_handle_tx_status()
+ *
+ * Overview:	Firmware add a new tx feedback status to reduce rx command
+ *				packet buffer operation load.
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_tx_status(
+	struct net_device *dev,
+	u8*	   pmsg)
+{
+	cmpk_tx_status_t	rx_tx_sts;	/* */
+
+	memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
+	/* 2. Use tx feedback info to count TX statistics. */
+	cmpk_count_tx_status(dev, &rx_tx_sts);
+
+}	/* cmpk_Handle_Tx_Status */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:	cmpk_handle_tx_rate_history()
+ *
+ * Overview:	Firmware add a new tx rate history
+ *
+ * Input:		NONE
+ *
+ * Output:		NONE
+ *
+ * Return:		NONE
+ *
+ * Revised History:
+ *	When		Who		Remark
+ *	05/12/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+static	void
+cmpk_handle_tx_rate_history(
+	struct net_device *dev,
+	u8*	   pmsg)
+{
+	cmpk_tx_rahis_t	*ptxrate;
+//	RT_RF_POWER_STATE	rtState;
+	u8				i, j;
+	u16				length = sizeof(cmpk_tx_rahis_t);
+	u32				*ptemp;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+
+#ifdef ENABLE_PS
+	pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
+
+	// When RF is off, we should not count the packet for hw/sw synchronize
+	// reason, ie. there may be a duration while sw switch is changed and hw
+	// switch is being changed. 2006.12.04, by shien chang.
+	if (rtState == eRfOff)
+	{
+		return;
+	}
+#endif
+
+	ptemp = (u32 *)pmsg;
+
+	//
+	// Do endian transfer to word alignment(16 bits) for windows system.
+	// You must do different endian transfer for linux and MAC OS
+	//
+	for (i = 0; i < (length/4); i++)
+	{
+		u16	 temp1, temp2;
+
+		temp1 = ptemp[i]&0x0000FFFF;
+		temp2 = ptemp[i]>>16;
+		ptemp[i] = (temp1<<16)|temp2;
+	}
+
+	ptxrate = (cmpk_tx_rahis_t *)pmsg;
+
+	if (ptxrate == NULL )
+	{
+		return;
+	}
+
+	for (i = 0; i < 16; i++)
+	{
+		// Collect CCK rate packet num
+		if (i < 4)
+			priv->stats.txrate.cck[i] += ptxrate->cck[i];
+
+		// Collect OFDM rate packet num
+		if (i< 8)
+			priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
+
+		for (j = 0; j < 4; j++)
+			priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
+	}
+
+}	/* cmpk_Handle_Tx_Rate_History */
+
+
+/*-----------------------------------------------------------------------------
+ * Function:    cmpk_message_handle_rx()
+ *
+ * Overview:    In the function, we will capture different RX command packet
+ *				info. Every RX command packet element has different message
+ *				length and meaning in content. We only support three type of RX
+ *				command packet now. Please refer to document
+ *				ws-06-0063-rtl8190-command-packet-specification.
+ *
+ * Input:       NONE
+ *
+ * Output:      NONE
+ *
+ * Return:      NONE
+ *
+ * Revised History:
+ *  When		Who		Remark
+ *  05/06/2008	amy		Create Version 0 porting from windows code.
+ *
+ *---------------------------------------------------------------------------*/
+u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats)
+{
+//	u32			debug_level = DBG_LOUD;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	int			total_length;
+	u8			cmd_length, exe_cnt = 0;
+	u8			element_id;
+	u8			*pcmd_buff;
+
+        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx()\n");
+
+	/* 0. Check inpt arguments. If is is a command queue message or pointer is
+	      null. */
+	if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL))
+	{
+		/* Print error message. */
+		/*RT_TRACE(COMP_SEND, DebugLevel,
+				("\n\r[CMPK]-->Err queue id or pointer"));*/
+		return 0;	/* This is not a command packet. */
+	}
+
+	/* 1. Read received command packet message length from RFD. */
+	total_length = pstats->Length;
+
+	/* 2. Read virtual address from RFD. */
+	pcmd_buff = pstats->virtual_address;
+
+	/* 3. Read command pakcet element id and length. */
+	element_id = pcmd_buff[0];
+	/*RT_TRACE(COMP_SEND, DebugLevel,
+			("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/
+
+	/* 4. Check every received command packet conent according to different
+	      element type. Because FW may aggregate RX command packet to minimize
+	      transmit time between DRV and FW.*/
+	// Add a counter to prevent to locked in the loop too long
+	while (total_length > 0 || exe_cnt++ >100)
+	{
+		/* 2007/01/17 MH We support aggregation of different cmd in the same packet. */
+		element_id = pcmd_buff[0];
+
+		switch(element_id)
+		{
+			case RX_TX_FEEDBACK:
+
+        			RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n");
+				cmpk_handle_tx_feedback (dev, pcmd_buff);
+				cmd_length = CMPK_RX_TX_FB_SIZE;
+				break;
+
+			case RX_INTERRUPT_STATUS:
+
+			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n");
+				cmpk_handle_interrupt_status(dev, pcmd_buff);
+				cmd_length = sizeof(cmpk_intr_sta_t);
+				break;
+
+			case BOTH_QUERY_CONFIG:
+
+			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n");
+				cmpk_handle_query_config_rx(dev, pcmd_buff);
+				cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
+				break;
+
+			case RX_TX_STATUS:
+
+			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_STATUS\n");
+				cmpk_handle_tx_status(dev, pcmd_buff);
+				cmd_length = CMPK_RX_TX_STS_SIZE;
+				break;
+
+			case RX_TX_PER_PKT_FEEDBACK:
+				// You must at lease add a switch case element here,
+				// Otherwise, we will jump to default case.
+				//DbgPrint("CCX Test\r\n");
+			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n");
+				cmd_length = CMPK_RX_TX_FB_SIZE;
+				break;
+
+			case RX_TX_RATE_HISTORY:
+				//DbgPrint(" rx tx rate history\r\n");
+
+			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n");
+				cmpk_handle_tx_rate_history(dev, pcmd_buff);
+				cmd_length = CMPK_TX_RAHIS_SIZE;
+				break;
+
+			default:
+
+			        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknow CMD Element\n");
+				return 1;	/* This is a command packet. */
+		}
+		// 2007/01/22 MH Display received rx command packet info.
+		//cmpk_Display_Message(cmd_length, pcmd_buff);
+
+		// 2007/01/22 MH Add to display tx statistic.
+		//cmpk_DisplayTxStatistic(pAdapter);
+
+		/* 2007/03/09 MH Collect sidderent cmd element pkt num. */
+		priv->stats.rxcmdpkt[element_id]++;
+
+		total_length -= cmd_length;
+		pcmd_buff    += cmd_length;
+	}	/* while (total_length > 0) */
+	return	1;	/* This is a command packet. */
+
+	RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n");
+}	/* CMPK_Message_Handle_Rx */
diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.h b/drivers/staging/rtl8192e/r819xE_cmdpkt.h
new file mode 100644
index 0000000..8fe2b9e
--- /dev/null
+++ b/drivers/staging/rtl8192e/r819xE_cmdpkt.h
@@ -0,0 +1,207 @@
+#ifndef R819XUSB_CMDPKT_H
+#define R819XUSB_CMDPKT_H
+/* Different command packet have dedicated message length and definition. */
+#define		CMPK_RX_TX_FB_SIZE					sizeof(cmpk_txfb_t)		//20
+#define		CMPK_TX_SET_CONFIG_SIZE				sizeof(cmpk_set_cfg_t)	//16
+#define		CMPK_BOTH_QUERY_CONFIG_SIZE			sizeof(cmpk_set_cfg_t)	//16
+#define		CMPK_RX_TX_STS_SIZE					sizeof(cmpk_tx_status_t)//
+#define		CMPK_RX_DBG_MSG_SIZE			sizeof(cmpk_rx_dbginfo_t)//
+#define		CMPK_TX_RAHIS_SIZE			sizeof(cmpk_tx_rahis_t)
+
+/* 2008/05/08 amy For USB constant. */
+#define ISR_TxBcnOk					BIT27			// Transmit Beacon OK
+#define ISR_TxBcnErr				BIT26			// Transmit Beacon Error
+#define ISR_BcnTimerIntr			BIT13			// Beacon Timer Interrupt
+
+#if 0
+/* Define packet type. */
+typedef enum tag_packet_type
+{
+    PACKET_BROADCAST,
+    PACKET_MULTICAST,
+    PACKET_UNICAST,
+    PACKET_TYPE_MAX
+}cmpk_pkt_type_e;
+#endif
+
+/* Define element ID of command packet. */
+
+/*------------------------------Define structure----------------------------*/
+/* Define different command packet structure. */
+/* 1. RX side: TX feedback packet. */
+typedef struct tag_cmd_pkt_tx_feedback
+{
+	// DWORD 0
+	u8	element_id;			/* Command packet type. */
+	u8	length;				/* Command packet length. */
+	/* 2007/07/05 MH Change tx feedback info field. */
+	/*------TX Feedback Info Field */
+	u8	TID:4;				/* */
+	u8	fail_reason:3;		/* */
+	u8	tok:1;				/* Transmit ok. */
+	u8	reserve1:4;			/* */
+	u8	pkt_type:2;		/* */
+	u8	bandwidth:1;		/* */
+	u8	qos_pkt:1;			/* */
+
+	// DWORD 1
+	u8	reserve2;			/* */
+	/*------TX Feedback Info Field */
+	u8	retry_cnt;			/* */
+	u16	pkt_id;				/* */
+
+	// DWORD 3
+	u16	seq_num;			/* */
+	u8	s_rate;				/* Start rate. */
+	u8	f_rate;				/* Final rate. */
+
+	// DWORD 4
+	u8	s_rts_rate;			/* */
+	u8	f_rts_rate;			/* */
+	u16	pkt_length;			/* */
+
+	// DWORD 5
+	u16	reserve3;			/* */
+	u16	duration;			/* */
+}cmpk_txfb_t;
+
+/* 2. RX side: Interrupt status packet. It includes Beacon State,
+	  Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */
+typedef struct tag_cmd_pkt_interrupt_status
+{
+	u8	element_id;			/* Command packet type. */
+	u8	length;				/* Command packet length. */
+	u16	reserve;
+	u32	interrupt_status;				/* Interrupt Status. */
+}cmpk_intr_sta_t;
+
+
+/* 3. TX side: Set configuration packet. */
+typedef struct tag_cmd_pkt_set_configuration
+{
+	u8	element_id;			/* Command packet type. */
+	u8	length;				/* Command packet length. */
+	u16	reserve1;			/* */
+	u8 	cfg_reserve1:3;
+	u8	cfg_size:2;			/* Configuration info. */
+	u8	cfg_type:2;			/* Configuration info. */
+	u8	cfg_action:1;		/* Configuration info. */
+	u8	cfg_reserve2;		/* Configuration info. */
+	u8	cfg_page:4;			/* Configuration info. */
+	u8	cfg_reserve3:4;		/* Configuration info. */
+	u8	cfg_offset;			/* Configuration info. */
+	u32	value;				/* */
+	u32	mask;				/* */
+}cmpk_set_cfg_t;
+
+/* 4. Both side : TX/RX query configuraton packet. The query structure is the
+      same as set configuration. */
+#define		cmpk_query_cfg_t	cmpk_set_cfg_t
+
+/* 5. Multi packet feedback status. */
+typedef struct tag_tx_stats_feedback // PJ quick rxcmd 09042007
+{
+	// For endian transfer --> Driver will not the same as firmware structure.
+	// DW 0
+	u16	reserve1;
+	u8 	length;				// Command packet length
+	u8 	element_id;			// Command packet type
+
+	// DW 1
+	u16	txfail;				// Tx Fail count
+	u16 	txok;				// Tx ok count
+
+	// DW 2
+	u16	txmcok;  			// tx multicast
+	u16 	txretry;			// Tx Retry count
+
+	// DW 3
+	u16  txucok;				// tx unicast
+	u16	txbcok;  			// tx broadcast
+
+	// DW 4
+	u16	txbcfail;			//
+	u16	txmcfail;			//
+
+	// DW 5
+	u16	reserve2;			//
+	u16	txucfail;			//
+
+	// DW 6-8
+	u32	txmclength;
+	u32	txbclength;
+	u32	txuclength;
+
+	// DW 9
+	u16	reserve3_23;
+	u8	reserve3_1;
+	u8	rate;
+}__attribute__((packed)) cmpk_tx_status_t;
+
+/* 6. Debug feedback message. */
+/* 2007/10/23 MH Define RX debug message  */
+typedef struct tag_rx_debug_message_feedback
+{
+	// For endian transfer --> for driver
+	// DW 0
+	u16	reserve1;
+	u8 	length;				// Command packet length
+	u8 	element_id;			// Command packet type
+
+	// DW 1-??
+	// Variable debug message.
+
+}cmpk_rx_dbginfo_t;
+
+/* 2008/03/20 MH Define transmit rate history. For big endian format. */
+typedef struct tag_tx_rate_history
+{
+	// For endian transfer --> for driver
+	// DW 0
+	u8 	element_id;			// Command packet type
+	u8 	length;				// Command packet length
+	u16	reserved1;
+
+	// DW 1-2	CCK rate counter
+	u16 	cck[4];
+
+	// DW 3-6
+	u16 	ofdm[8];
+
+	// DW 7-14
+	//UINT16	MCS_BW0_SG0[16];
+
+	// DW 15-22
+	//UINT16	MCS_BW1_SG0[16];
+
+	// DW 23-30
+	//UINT16	MCS_BW0_SG1[16];
+
+	// DW 31-38
+	//UINT16	MCS_BW1_SG1[16];
+
+	// DW 7-14	BW=0 SG=0
+	// DW 15-22	BW=1 SG=0
+	// DW 23-30	BW=0 SG=1
+	// DW 31-38	BW=1 SG=1
+	u16	ht_mcs[4][16];
+
+}__attribute__((packed)) cmpk_tx_rahis_t;
+
+typedef enum tag_command_packet_directories
+{
+    RX_TX_FEEDBACK = 0,
+    RX_INTERRUPT_STATUS		= 1,
+    TX_SET_CONFIG				= 2,
+    BOTH_QUERY_CONFIG			= 3,
+    RX_TX_STATUS				= 4,
+    RX_DBGINFO_FEEDBACK		= 5,
+    RX_TX_PER_PKT_FEEDBACK		= 6,
+    RX_TX_RATE_HISTORY		= 7,
+    RX_CMD_ELE_MAX
+}cmpk_element_e;
+
+extern  u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats);
+
+
+#endif
diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c
new file mode 100644
index 0000000..1f9e413
--- /dev/null
+++ b/drivers/staging/rtl8192e/r819xE_firmware.c
@@ -0,0 +1,352 @@
+/*
+ * Procedure:    Init boot code/firmware code/data session
+ *
+ * Description: This routine will intialize firmware. If any error occurs
+ *		during the initialization process, the routine shall terminate
+ *		immediately and return fail.  NIC driver should call
+ *		NdisOpenFile only from MiniportInitialize.
+ *
+ * Arguments:   The pointer of the adapter
+
+ * Returns:
+ *		NDIS_STATUS_FAILURE - the following initialization process
+ *				      should be terminated
+ *		NDIS_STATUS_SUCCESS - if firmware initialization process
+ *				      success
+ */
+#include "r8192E.h"
+#include "r8192E_hw.h"
+#include <linux/firmware.h>
+
+/* It should be double word alignment */
+#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	(4 * (v / 4) - 8)
+
+enum firmware_init_step {
+	FW_INIT_STEP0_BOOT = 0,
+	FW_INIT_STEP1_MAIN = 1,
+	FW_INIT_STEP2_DATA = 2,
+};
+
+enum opt_rst_type {
+	OPT_SYSTEM_RESET = 0,
+	OPT_FIRMWARE_RESET = 1,
+};
+
+void firmware_init_param(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	rt_firmware *pfirmware = priv->pFirmware;
+
+	pfirmware->cmdpacket_frag_thresold =
+		GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE);
+}
+
+/*
+ * segment the img and use the ptr and length to remember info on each segment
+ */
+static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
+			     u32 buffer_len)
+{
+	struct r8192_priv   *priv = ieee80211_priv(dev);
+	bool 		    rt_status = true;
+	u16		    frag_threshold;
+	u16		    frag_length, frag_offset = 0;
+	int		    i;
+
+	rt_firmware	    *pfirmware = priv->pFirmware;
+	struct sk_buff	    *skb;
+	unsigned char	    *seg_ptr;
+	cb_desc		    *tcb_desc;
+	u8                  bLastIniPkt;
+
+	firmware_init_param(dev);
+
+	/* Fragmentation might be required */
+	frag_threshold = pfirmware->cmdpacket_frag_thresold;
+	do {
+		if ((buffer_len - frag_offset) > frag_threshold) {
+			frag_length = frag_threshold ;
+			bLastIniPkt = 0;
+		} else {
+			frag_length = buffer_len - frag_offset;
+			bLastIniPkt = 1;
+		}
+
+		/*
+		 * Allocate skb buffer to contain firmware info and tx
+		 * descriptor info add 4 to avoid packet appending overflow.
+		 */
+		skb  = dev_alloc_skb(frag_length + 4);
+		memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
+		tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
+		tcb_desc->queue_index = TXCMD_QUEUE;
+		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
+		tcb_desc->bLastIniPkt = bLastIniPkt;
+
+		seg_ptr = skb->data;
+
+		/*
+		 * Transform from little endian to big endian and pending zero
+		 */
+		for (i = 0; i < frag_length; i += 4) {
+			*seg_ptr++ = ((i+0) < frag_length) ? code_virtual_address[i+3] : 0;
+			*seg_ptr++ = ((i+1) < frag_length) ? code_virtual_address[i+2] : 0;
+			*seg_ptr++ = ((i+2) < frag_length) ? code_virtual_address[i+1] : 0;
+			*seg_ptr++ = ((i+3) < frag_length) ? code_virtual_address[i+0] : 0;
+		}
+		tcb_desc->txbuf_size = (u16)i;
+		skb_put(skb, i);
+		priv->ieee80211->softmac_hard_start_xmit(skb, dev);
+
+		code_virtual_address += frag_length;
+		frag_offset += frag_length;
+
+	} while (frag_offset < buffer_len);
+
+	return rt_status;
+}
+
+/*
+ * Procedure:    Check whether main code is download OK. If OK, turn on CPU
+ *
+ * Description:   CPU register locates in different page against general
+ *		  register.  Switch to CPU register in the begin and switch
+ *		  back before return
+ *
+ * Arguments:   The pointer of the adapter
+ *
+ * Returns:
+ *	NDIS_STATUS_FAILURE - the following initialization process should be
+ *			      terminated
+ *	NDIS_STATUS_SUCCESS - if firmware initialization process success
+ */
+static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
+{
+	unsigned long timeout;
+	bool rt_status = true;
+	u32 CPU_status = 0;
+
+	/* Check whether put code OK */
+	timeout = jiffies + msecs_to_jiffies(20);
+	while (time_before(jiffies, timeout)) {
+		CPU_status = read_nic_dword(dev, CPU_GEN);
+
+		if (CPU_status & CPU_GEN_PUT_CODE_OK)
+			break;
+		msleep(2);
+	}
+
+	if (!(CPU_status & CPU_GEN_PUT_CODE_OK)) {
+		RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
+		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
+	} else {
+		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
+	}
+
+	/* Turn On CPU */
+	CPU_status = read_nic_dword(dev, CPU_GEN);
+	write_nic_byte(dev, CPU_GEN,
+		       (u8)((CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff));
+	mdelay(1);
+
+	/* Check whether CPU boot OK */
+	timeout = jiffies + msecs_to_jiffies(20);
+	while (time_before(jiffies, timeout)) {
+		CPU_status = read_nic_dword(dev, CPU_GEN);
+
+		if (CPU_status & CPU_GEN_BOOT_RDY)
+			break;
+		msleep(2);
+	}
+
+	if (!(CPU_status & CPU_GEN_BOOT_RDY))
+		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
+	else
+		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
+
+	return rt_status;
+
+CPUCheckMainCodeOKAndTurnOnCPU_Fail:
+	RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
+	rt_status = FALSE;
+	return rt_status;
+}
+
+static bool CPUcheck_firmware_ready(struct net_device *dev)
+{
+	unsigned long timeout;
+	bool rt_status = true;
+	u32 CPU_status = 0;
+
+	/* Check Firmware Ready */
+	timeout = jiffies + msecs_to_jiffies(20);
+	while (time_before(jiffies, timeout)) {
+		CPU_status = read_nic_dword(dev, CPU_GEN);
+
+		if (CPU_status & CPU_GEN_FIRM_RDY)
+			break;
+		msleep(2);
+	}
+
+	if (!(CPU_status & CPU_GEN_FIRM_RDY))
+		goto CPUCheckFirmwareReady_Fail;
+	else
+		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
+
+	return rt_status;
+
+CPUCheckFirmwareReady_Fail:
+	RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
+	rt_status = false;
+	return rt_status;
+
+}
+
+bool init_firmware(struct net_device *dev)
+{
+	struct r8192_priv 	*priv = ieee80211_priv(dev);
+	bool			rt_status = TRUE;
+	u32			file_length = 0;
+	u8			*mapped_file = NULL;
+	u32			init_step = 0;
+	enum opt_rst_type	rst_opt = OPT_SYSTEM_RESET;
+	enum firmware_init_step	starting_state = FW_INIT_STEP0_BOOT;
+
+	rt_firmware		*pfirmware = priv->pFirmware;
+	const struct firmware 	*fw_entry;
+	const char *fw_name[3] = { "RTL8192E/boot.img",
+				   "RTL8192E/main.img",
+				   "RTL8192E/data.img"};
+	int rc;
+
+	RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
+
+	if (pfirmware->firmware_status == FW_STATUS_0_INIT) {
+		/* it is called by reset */
+		rst_opt = OPT_SYSTEM_RESET;
+		starting_state = FW_INIT_STEP0_BOOT;
+		/* TODO: system reset */
+
+	} else if (pfirmware->firmware_status == FW_STATUS_5_READY) {
+		/* it is called by Initialize */
+		rst_opt = OPT_FIRMWARE_RESET;
+		starting_state = FW_INIT_STEP2_DATA;
+	} else {
+		RT_TRACE(COMP_FIRMWARE,
+			"PlatformInitFirmware: undefined firmware state\n");
+	}
+
+	/*
+	 * Download boot, main, and data image for System reset.
+	 * Download data image for firmware reseta
+	 */
+	for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
+		/*
+		 * Open Image file, and map file to contineous memory if open file success.
+		 * or read image file from array. Default load from IMG file
+		 */
+		if (rst_opt == OPT_SYSTEM_RESET) {
+			if (pfirmware->firmware_buf_size[init_step] == 0) {
+				rc = request_firmware(&fw_entry, fw_name[init_step], &priv->pdev->dev);
+				if (rc < 0) {
+					RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n");
+					goto download_firmware_fail;
+				}
+
+				if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) {
+					RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!\n");
+					goto download_firmware_fail;
+				}
+
+				if (init_step != FW_INIT_STEP1_MAIN) {
+					memcpy(pfirmware->firmware_buf[init_step], fw_entry->data, fw_entry->size);
+					pfirmware->firmware_buf_size[init_step] = fw_entry->size;
+
+				} else {
+					memset(pfirmware->firmware_buf[init_step], 0, 128);
+					memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data, fw_entry->size);
+					pfirmware->firmware_buf_size[init_step] = fw_entry->size+128;
+				}
+
+				if (rst_opt == OPT_SYSTEM_RESET)
+					release_firmware(fw_entry);
+			}
+			mapped_file = pfirmware->firmware_buf[init_step];
+			file_length = pfirmware->firmware_buf_size[init_step];
+		} else if (rst_opt == OPT_FIRMWARE_RESET) {
+			/* we only need to download data.img here */
+			mapped_file = pfirmware->firmware_buf[init_step];
+			file_length = pfirmware->firmware_buf_size[init_step];
+		}
+
+		/* Download image file */
+		/* The firmware download process is just as following,
+		 * 1. that is each packet will be segmented and inserted to the
+		 *    wait queue.
+		 * 2. each packet segment will be put in the skb_buff packet.
+		 * 3. each skb_buff packet data content will already include
+		 *    the firmware info and Tx descriptor info
+		 */
+		rt_status = fw_download_code(dev, mapped_file, file_length);
+		if (rt_status != TRUE)
+			goto download_firmware_fail;
+
+		switch (init_step) {
+		case FW_INIT_STEP0_BOOT:
+			/* Download boot
+			 * initialize command descriptor.
+			 * will set polling bit when firmware code is also
+			 * configured
+			 */
+			pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
+			/* mdelay(1000); */
+			/*
+			 * To initialize IMEM, CPU move code  from 0x80000080,
+			 * hence, we send 0x80 byte packet
+			 */
+			break;
+
+		case FW_INIT_STEP1_MAIN:
+			/* Download firmware code.
+			 * Wait until Boot Ready and Turn on CPU */
+			pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
+
+			/* Check Put Code OK and Turn On CPU */
+			rt_status = CPUcheck_maincodeok_turnonCPU(dev);
+			if (rt_status != TRUE) {
+				RT_TRACE(COMP_FIRMWARE,
+					"CPUcheck_maincodeok_turnonCPU fail!\n");
+				goto download_firmware_fail;
+			}
+
+			pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
+			break;
+
+		case FW_INIT_STEP2_DATA:
+			/* download initial data code */
+			pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
+			mdelay(1);
+
+			rt_status = CPUcheck_firmware_ready(dev);
+			if (rt_status != TRUE) {
+				RT_TRACE(COMP_FIRMWARE,
+					"CPUcheck_firmware_ready fail(%d)!\n",
+					rt_status);
+				goto download_firmware_fail;
+			}
+
+			/* wait until data code is initialized ready.*/
+			pfirmware->firmware_status = FW_STATUS_5_READY;
+			break;
+		}
+	}
+
+	RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
+	return rt_status;
+
+download_firmware_fail:
+	RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__);
+	rt_status = FALSE;
+	return rt_status;
+
+}
diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c
new file mode 100644
index 0000000..c44059a
--- /dev/null
+++ b/drivers/staging/rtl8192e/r819xE_phy.c
@@ -0,0 +1,3352 @@
+#include "r8192E.h"
+#include "r8192E_hw.h"
+#include "r819xE_phyreg.h"
+#include "r8190_rtl8256.h"
+#include "r819xE_phy.h"
+#include "r8192E_dm.h"
+#ifdef ENABLE_DOT11D
+#include "dot11d.h"
+#endif
+static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
+	0,
+	0x085c, //2412 1
+	0x08dc, //2417 2
+	0x095c, //2422 3
+	0x09dc, //2427 4
+	0x0a5c, //2432 5
+	0x0adc, //2437 6
+	0x0b5c, //2442 7
+	0x0bdc, //2447 8
+	0x0c5c, //2452 9
+	0x0cdc, //2457 10
+	0x0d5c, //2462 11
+	0x0ddc, //2467 12
+	0x0e5c, //2472 13
+	0x0f72, //2484
+};
+#ifdef RTL8190P
+u32 Rtl8190PciMACPHY_Array[] = {
+0x03c,0xffff0000,0x00000f0f,
+0x340,0xffffffff,0x161a1a1a,
+0x344,0xffffffff,0x12121416,
+0x348,0x0000ffff,0x00001818,
+0x12c,0xffffffff,0x04000802,
+0x318,0x00000fff,0x00000800,
+};
+u32 Rtl8190PciMACPHY_Array_PG[] = {
+0x03c,0xffff0000,0x00000f0f,
+0x340,0xffffffff,0x0a0c0d0f,
+0x344,0xffffffff,0x06070809,
+0x344,0xffffffff,0x06070809,
+0x348,0x0000ffff,0x00000000,
+0x12c,0xffffffff,0x04000802,
+0x318,0x00000fff,0x00000800,
+};
+
+u32 Rtl8190PciAGCTAB_Array[AGCTAB_ArrayLength] = {
+0xc78,0x7d000001,
+0xc78,0x7d010001,
+0xc78,0x7d020001,
+0xc78,0x7d030001,
+0xc78,0x7c040001,
+0xc78,0x7b050001,
+0xc78,0x7a060001,
+0xc78,0x79070001,
+0xc78,0x78080001,
+0xc78,0x77090001,
+0xc78,0x760a0001,
+0xc78,0x750b0001,
+0xc78,0x740c0001,
+0xc78,0x730d0001,
+0xc78,0x720e0001,
+0xc78,0x710f0001,
+0xc78,0x70100001,
+0xc78,0x6f110001,
+0xc78,0x6e120001,
+0xc78,0x6d130001,
+0xc78,0x6c140001,
+0xc78,0x6b150001,
+0xc78,0x6a160001,
+0xc78,0x69170001,
+0xc78,0x68180001,
+0xc78,0x67190001,
+0xc78,0x661a0001,
+0xc78,0x651b0001,
+0xc78,0x641c0001,
+0xc78,0x491d0001,
+0xc78,0x481e0001,
+0xc78,0x471f0001,
+0xc78,0x46200001,
+0xc78,0x45210001,
+0xc78,0x44220001,
+0xc78,0x43230001,
+0xc78,0x28240001,
+0xc78,0x27250001,
+0xc78,0x26260001,
+0xc78,0x25270001,
+0xc78,0x24280001,
+0xc78,0x23290001,
+0xc78,0x222a0001,
+0xc78,0x212b0001,
+0xc78,0x202c0001,
+0xc78,0x0a2d0001,
+0xc78,0x082e0001,
+0xc78,0x062f0001,
+0xc78,0x05300001,
+0xc78,0x04310001,
+0xc78,0x03320001,
+0xc78,0x02330001,
+0xc78,0x01340001,
+0xc78,0x00350001,
+0xc78,0x00360001,
+0xc78,0x00370001,
+0xc78,0x00380001,
+0xc78,0x00390001,
+0xc78,0x003a0001,
+0xc78,0x003b0001,
+0xc78,0x003c0001,
+0xc78,0x003d0001,
+0xc78,0x003e0001,
+0xc78,0x003f0001,
+0xc78,0x7d400001,
+0xc78,0x7d410001,
+0xc78,0x7d420001,
+0xc78,0x7d430001,
+0xc78,0x7c440001,
+0xc78,0x7b450001,
+0xc78,0x7a460001,
+0xc78,0x79470001,
+0xc78,0x78480001,
+0xc78,0x77490001,
+0xc78,0x764a0001,
+0xc78,0x754b0001,
+0xc78,0x744c0001,
+0xc78,0x734d0001,
+0xc78,0x724e0001,
+0xc78,0x714f0001,
+0xc78,0x70500001,
+0xc78,0x6f510001,
+0xc78,0x6e520001,
+0xc78,0x6d530001,
+0xc78,0x6c540001,
+0xc78,0x6b550001,
+0xc78,0x6a560001,
+0xc78,0x69570001,
+0xc78,0x68580001,
+0xc78,0x67590001,
+0xc78,0x665a0001,
+0xc78,0x655b0001,
+0xc78,0x645c0001,
+0xc78,0x495d0001,
+0xc78,0x485e0001,
+0xc78,0x475f0001,
+0xc78,0x46600001,
+0xc78,0x45610001,
+0xc78,0x44620001,
+0xc78,0x43630001,
+0xc78,0x28640001,
+0xc78,0x27650001,
+0xc78,0x26660001,
+0xc78,0x25670001,
+0xc78,0x24680001,
+0xc78,0x23690001,
+0xc78,0x226a0001,
+0xc78,0x216b0001,
+0xc78,0x206c0001,
+0xc78,0x0a6d0001,
+0xc78,0x086e0001,
+0xc78,0x066f0001,
+0xc78,0x05700001,
+0xc78,0x04710001,
+0xc78,0x03720001,
+0xc78,0x02730001,
+0xc78,0x01740001,
+0xc78,0x00750001,
+0xc78,0x00760001,
+0xc78,0x00770001,
+0xc78,0x00780001,
+0xc78,0x00790001,
+0xc78,0x007a0001,
+0xc78,0x007b0001,
+0xc78,0x007c0001,
+0xc78,0x007d0001,
+0xc78,0x007e0001,
+0xc78,0x007f0001,
+0xc78,0x3600001e,
+0xc78,0x3601001e,
+0xc78,0x3602001e,
+0xc78,0x3603001e,
+0xc78,0x3604001e,
+0xc78,0x3605001e,
+0xc78,0x3a06001e,
+0xc78,0x3c07001e,
+0xc78,0x3e08001e,
+0xc78,0x4209001e,
+0xc78,0x430a001e,
+0xc78,0x450b001e,
+0xc78,0x470c001e,
+0xc78,0x480d001e,
+0xc78,0x490e001e,
+0xc78,0x4b0f001e,
+0xc78,0x4c10001e,
+0xc78,0x4d11001e,
+0xc78,0x4d12001e,
+0xc78,0x4e13001e,
+0xc78,0x4f14001e,
+0xc78,0x5015001e,
+0xc78,0x5116001e,
+0xc78,0x5117001e,
+0xc78,0x5218001e,
+0xc78,0x5219001e,
+0xc78,0x531a001e,
+0xc78,0x541b001e,
+0xc78,0x541c001e,
+0xc78,0x551d001e,
+0xc78,0x561e001e,
+0xc78,0x561f001e,
+0xc78,0x5720001e,
+0xc78,0x5821001e,
+0xc78,0x5822001e,
+0xc78,0x5923001e,
+0xc78,0x5924001e,
+0xc78,0x5a25001e,
+0xc78,0x5b26001e,
+0xc78,0x5b27001e,
+0xc78,0x5c28001e,
+0xc78,0x5c29001e,
+0xc78,0x5d2a001e,
+0xc78,0x5d2b001e,
+0xc78,0x5e2c001e,
+0xc78,0x5e2d001e,
+0xc78,0x5f2e001e,
+0xc78,0x602f001e,
+0xc78,0x6030001e,
+0xc78,0x6131001e,
+0xc78,0x6132001e,
+0xc78,0x6233001e,
+0xc78,0x6234001e,
+0xc78,0x6335001e,
+0xc78,0x6336001e,
+0xc78,0x6437001e,
+0xc78,0x6538001e,
+0xc78,0x6639001e,
+0xc78,0x663a001e,
+0xc78,0x673b001e,
+0xc78,0x683c001e,
+0xc78,0x693d001e,
+0xc78,0x6a3e001e,
+0xc78,0x6b3f001e,
+};
+
+u32 Rtl8190PciPHY_REGArray[PHY_REGArrayLength] = {
+0x800,0x00050060,
+0x804,0x00000005,
+0x808,0x0000fc00,
+0x80c,0x0000001c,
+0x810,0x801010aa,
+0x814,0x000908c0,
+0x818,0x00000000,
+0x81c,0x00000000,
+0x820,0x00000004,
+0x824,0x00690000,
+0x828,0x00000004,
+0x82c,0x00e90000,
+0x830,0x00000004,
+0x834,0x00690000,
+0x838,0x00000004,
+0x83c,0x00e90000,
+0x840,0x00000000,
+0x844,0x00000000,
+0x848,0x00000000,
+0x84c,0x00000000,
+0x850,0x00000000,
+0x854,0x00000000,
+0x858,0x65a965a9,
+0x85c,0x65a965a9,
+0x860,0x001f0010,
+0x864,0x007f0010,
+0x868,0x001f0010,
+0x86c,0x007f0010,
+0x870,0x0f100f70,
+0x874,0x0f100f70,
+0x878,0x00000000,
+0x87c,0x00000000,
+0x880,0x5c385eb8,
+0x884,0x6357060d,
+0x888,0x0460c341,
+0x88c,0x0000ff00,
+0x890,0x00000000,
+0x894,0xfffffffe,
+0x898,0x4c42382f,
+0x89c,0x00656056,
+0x8b0,0x00000000,
+0x8e0,0x00000000,
+0x8e4,0x00000000,
+0x900,0x00000000,
+0x904,0x00000023,
+0x908,0x00000000,
+0x90c,0x35541545,
+0xa00,0x00d0c7d8,
+0xa04,0xab1f0008,
+0xa08,0x80cd8300,
+0xa0c,0x2e62740f,
+0xa10,0x95009b78,
+0xa14,0x11145008,
+0xa18,0x00881117,
+0xa1c,0x89140fa0,
+0xa20,0x1a1b0000,
+0xa24,0x090e1317,
+0xa28,0x00000204,
+0xa2c,0x00000000,
+0xc00,0x00000040,
+0xc04,0x0000500f,
+0xc08,0x000000e4,
+0xc0c,0x6c6c6c6c,
+0xc10,0x08000000,
+0xc14,0x40000100,
+0xc18,0x08000000,
+0xc1c,0x40000100,
+0xc20,0x08000000,
+0xc24,0x40000100,
+0xc28,0x08000000,
+0xc2c,0x40000100,
+0xc30,0x6de9ac44,
+0xc34,0x164052cd,
+0xc38,0x00070a14,
+0xc3c,0x0a969764,
+0xc40,0x1f7c403f,
+0xc44,0x000100b7,
+0xc48,0xec020000,
+0xc4c,0x00000300,
+0xc50,0x69543420,
+0xc54,0x433c0094,
+0xc58,0x69543420,
+0xc5c,0x433c0094,
+0xc60,0x69543420,
+0xc64,0x433c0094,
+0xc68,0x69543420,
+0xc6c,0x433c0094,
+0xc70,0x2c7f000d,
+0xc74,0x0186175b,
+0xc78,0x0000001f,
+0xc7c,0x00b91612,
+0xc80,0x40000100,
+0xc84,0x00000000,
+0xc88,0x40000100,
+0xc8c,0x08000000,
+0xc90,0x40000100,
+0xc94,0x00000000,
+0xc98,0x40000100,
+0xc9c,0x00000000,
+0xca0,0x00492492,
+0xca4,0x00000000,
+0xca8,0x00000000,
+0xcac,0x00000000,
+0xcb0,0x00000000,
+0xcb4,0x00000000,
+0xcb8,0x00000000,
+0xcbc,0x00492492,
+0xcc0,0x00000000,
+0xcc4,0x00000000,
+0xcc8,0x00000000,
+0xccc,0x00000000,
+0xcd0,0x00000000,
+0xcd4,0x00000000,
+0xcd8,0x64b22427,
+0xcdc,0x00766932,
+0xce0,0x00222222,
+0xd00,0x00000740,
+0xd04,0x0000040f,
+0xd08,0x0000803f,
+0xd0c,0x00000001,
+0xd10,0xa0633333,
+0xd14,0x33333c63,
+0xd18,0x6a8f5b6b,
+0xd1c,0x00000000,
+0xd20,0x00000000,
+0xd24,0x00000000,
+0xd28,0x00000000,
+0xd2c,0xcc979975,
+0xd30,0x00000000,
+0xd34,0x00000000,
+0xd38,0x00000000,
+0xd3c,0x00027293,
+0xd40,0x00000000,
+0xd44,0x00000000,
+0xd48,0x00000000,
+0xd4c,0x00000000,
+0xd50,0x6437140a,
+0xd54,0x024dbd02,
+0xd58,0x00000000,
+0xd5c,0x14032064,
+};
+u32 Rtl8190PciPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = {
+0x800,0x00050060,
+0x804,0x00000004,
+0x808,0x0000fc00,
+0x80c,0x0000001c,
+0x810,0x801010aa,
+0x814,0x000908c0,
+0x818,0x00000000,
+0x81c,0x00000000,
+0x820,0x00000004,
+0x824,0x00690000,
+0x828,0x00000004,
+0x82c,0x00e90000,
+0x830,0x00000004,
+0x834,0x00690000,
+0x838,0x00000004,
+0x83c,0x00e90000,
+0x840,0x00000000,
+0x844,0x00000000,
+0x848,0x00000000,
+0x84c,0x00000000,
+0x850,0x00000000,
+0x854,0x00000000,
+0x858,0x65a965a9,
+0x85c,0x65a965a9,
+0x860,0x001f0000,
+0x864,0x007f0000,
+0x868,0x001f0010,
+0x86c,0x007f0010,
+0x870,0x0f100f70,
+0x874,0x0f100f70,
+0x878,0x00000000,
+0x87c,0x00000000,
+0x880,0x5c385898,
+0x884,0x6357060d,
+0x888,0x0460c341,
+0x88c,0x0000fc00,
+0x890,0x00000000,
+0x894,0xfffffffe,
+0x898,0x4c42382f,
+0x89c,0x00656056,
+0x8b0,0x00000000,
+0x8e0,0x00000000,
+0x8e4,0x00000000,
+0x900,0x00000000,
+0x904,0x00000023,
+0x908,0x00000000,
+0x90c,0x34441444,
+0xa00,0x00d0c7d8,
+0xa04,0x2b1f0008,
+0xa08,0x80cd8300,
+0xa0c,0x2e62740f,
+0xa10,0x95009b78,
+0xa14,0x11145008,
+0xa18,0x00881117,
+0xa1c,0x89140fa0,
+0xa20,0x1a1b0000,
+0xa24,0x090e1317,
+0xa28,0x00000204,
+0xa2c,0x00000000,
+0xc00,0x00000040,
+0xc04,0x0000500c,
+0xc08,0x000000e4,
+0xc0c,0x6c6c6c6c,
+0xc10,0x08000000,
+0xc14,0x40000100,
+0xc18,0x08000000,
+0xc1c,0x40000100,
+0xc20,0x08000000,
+0xc24,0x40000100,
+0xc28,0x08000000,
+0xc2c,0x40000100,
+0xc30,0x6de9ac44,
+0xc34,0x164052cd,
+0xc38,0x00070a14,
+0xc3c,0x0a969764,
+0xc40,0x1f7c403f,
+0xc44,0x000100b7,
+0xc48,0xec020000,
+0xc4c,0x00000300,
+0xc50,0x69543420,
+0xc54,0x433c0094,
+0xc58,0x69543420,
+0xc5c,0x433c0094,
+0xc60,0x69543420,
+0xc64,0x433c0094,
+0xc68,0x69543420,
+0xc6c,0x433c0094,
+0xc70,0x2c7f000d,
+0xc74,0x0186175b,
+0xc78,0x0000001f,
+0xc7c,0x00b91612,
+0xc80,0x40000100,
+0xc84,0x00000000,
+0xc88,0x40000100,
+0xc8c,0x08000000,
+0xc90,0x40000100,
+0xc94,0x00000000,
+0xc98,0x40000100,
+0xc9c,0x00000000,
+0xca0,0x00492492,
+0xca4,0x00000000,
+0xca8,0x00000000,
+0xcac,0x00000000,
+0xcb0,0x00000000,
+0xcb4,0x00000000,
+0xcb8,0x00000000,
+0xcbc,0x00492492,
+0xcc0,0x00000000,
+0xcc4,0x00000000,
+0xcc8,0x00000000,
+0xccc,0x00000000,
+0xcd0,0x00000000,
+0xcd4,0x00000000,
+0xcd8,0x64b22427,
+0xcdc,0x00766932,
+0xce0,0x00222222,
+0xd00,0x00000740,
+0xd04,0x0000040c,
+0xd08,0x0000803f,
+0xd0c,0x00000001,
+0xd10,0xa0633333,
+0xd14,0x33333c63,
+0xd18,0x6a8f5b6b,
+0xd1c,0x00000000,
+0xd20,0x00000000,
+0xd24,0x00000000,
+0xd28,0x00000000,
+0xd2c,0xcc979975,
+0xd30,0x00000000,
+0xd34,0x00000000,
+0xd38,0x00000000,
+0xd3c,0x00027293,
+0xd40,0x00000000,
+0xd44,0x00000000,
+0xd48,0x00000000,
+0xd4c,0x00000000,
+0xd50,0x6437140a,
+0xd54,0x024dbd02,
+0xd58,0x00000000,
+0xd5c,0x14032064,
+};
+
+u32 Rtl8190PciRadioA_Array[RadioA_ArrayLength] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x00000ee0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x009,0x000007f0,
+0x00a,0x000009d0,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x00f,0x00000990,
+0x012,0x00000806,
+0x014,0x000005ab,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000f80,
+0x01b,0x00000f5e,
+0x01c,0x00000008,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x01f,0x00000000,
+0x020,0x000001a5,
+0x01f,0x00000001,
+0x020,0x00000165,
+0x01f,0x00000002,
+0x020,0x000000c6,
+0x01f,0x00000003,
+0x020,0x00000086,
+0x01f,0x00000004,
+0x020,0x00000046,
+0x01f,0x00000005,
+0x020,0x000001e6,
+0x01f,0x00000006,
+0x020,0x000001a6,
+0x01f,0x00000007,
+0x020,0x00000166,
+0x01f,0x00000008,
+0x020,0x000000c7,
+0x01f,0x00000009,
+0x020,0x00000087,
+0x01f,0x0000000a,
+0x020,0x000000f7,
+0x01f,0x0000000b,
+0x020,0x000000d7,
+0x01f,0x0000000c,
+0x020,0x000000b7,
+0x01f,0x0000000d,
+0x020,0x00000097,
+0x01f,0x0000000e,
+0x020,0x00000077,
+0x01f,0x0000000f,
+0x020,0x00000057,
+0x01f,0x00000010,
+0x020,0x00000037,
+0x01f,0x00000011,
+0x020,0x000000fb,
+0x01f,0x00000012,
+0x020,0x000000db,
+0x01f,0x00000013,
+0x020,0x000000bb,
+0x01f,0x00000014,
+0x020,0x000000ff,
+0x01f,0x00000015,
+0x020,0x000000e3,
+0x01f,0x00000016,
+0x020,0x000000c3,
+0x01f,0x00000017,
+0x020,0x000000a3,
+0x01f,0x00000018,
+0x020,0x00000083,
+0x01f,0x00000019,
+0x020,0x00000063,
+0x01f,0x0000001a,
+0x020,0x00000043,
+0x01f,0x0000001b,
+0x020,0x00000023,
+0x01f,0x0000001c,
+0x020,0x00000003,
+0x01f,0x0000001d,
+0x020,0x000001e3,
+0x01f,0x0000001e,
+0x020,0x000001c3,
+0x01f,0x0000001f,
+0x020,0x000001a3,
+0x01f,0x00000020,
+0x020,0x00000183,
+0x01f,0x00000021,
+0x020,0x00000163,
+0x01f,0x00000022,
+0x020,0x00000143,
+0x01f,0x00000023,
+0x020,0x00000123,
+0x01f,0x00000024,
+0x020,0x00000103,
+0x023,0x00000203,
+0x024,0x00000200,
+0x00b,0x000001ba,
+0x02c,0x000003d7,
+0x02d,0x00000ff0,
+0x000,0x00000037,
+0x004,0x00000160,
+0x007,0x00000080,
+0x002,0x0000088d,
+0x0fe,0x00000000,
+0x0fe,0x00000000,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x000,0x000000bf,
+0x00d,0x0000001f,
+0x00d,0x00000c9f,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+u32 Rtl8190PciRadioB_Array[RadioB_ArrayLength] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x000006e0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x000,0x000000b7,
+0x00a,0x00000850,
+0x000,0x000000bf,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000e00,
+0x01b,0x00000f5e,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x00b,0x000001ba,
+0x023,0x00000203,
+0x024,0x00000200,
+0x000,0x00000037,
+0x004,0x00000160,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x00d,0x00000ccc,
+0x000,0x000000bf,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+u32 Rtl8190PciRadioC_Array[RadioC_ArrayLength] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x00000ee0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x009,0x000007f0,
+0x00a,0x000009d0,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x00f,0x00000990,
+0x012,0x00000806,
+0x014,0x000005ab,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000f80,
+0x01b,0x00000f5e,
+0x01c,0x00000008,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x01f,0x00000000,
+0x020,0x000001a5,
+0x01f,0x00000001,
+0x020,0x00000165,
+0x01f,0x00000002,
+0x020,0x000000c6,
+0x01f,0x00000003,
+0x020,0x00000086,
+0x01f,0x00000004,
+0x020,0x00000046,
+0x01f,0x00000005,
+0x020,0x000001e6,
+0x01f,0x00000006,
+0x020,0x000001a6,
+0x01f,0x00000007,
+0x020,0x00000166,
+0x01f,0x00000008,
+0x020,0x000000c7,
+0x01f,0x00000009,
+0x020,0x00000087,
+0x01f,0x0000000a,
+0x020,0x000000f7,
+0x01f,0x0000000b,
+0x020,0x000000d7,
+0x01f,0x0000000c,
+0x020,0x000000b7,
+0x01f,0x0000000d,
+0x020,0x00000097,
+0x01f,0x0000000e,
+0x020,0x00000077,
+0x01f,0x0000000f,
+0x020,0x00000057,
+0x01f,0x00000010,
+0x020,0x00000037,
+0x01f,0x00000011,
+0x020,0x000000fb,
+0x01f,0x00000012,
+0x020,0x000000db,
+0x01f,0x00000013,
+0x020,0x000000bb,
+0x01f,0x00000014,
+0x020,0x000000ff,
+0x01f,0x00000015,
+0x020,0x000000e3,
+0x01f,0x00000016,
+0x020,0x000000c3,
+0x01f,0x00000017,
+0x020,0x000000a3,
+0x01f,0x00000018,
+0x020,0x00000083,
+0x01f,0x00000019,
+0x020,0x00000063,
+0x01f,0x0000001a,
+0x020,0x00000043,
+0x01f,0x0000001b,
+0x020,0x00000023,
+0x01f,0x0000001c,
+0x020,0x00000003,
+0x01f,0x0000001d,
+0x020,0x000001e3,
+0x01f,0x0000001e,
+0x020,0x000001c3,
+0x01f,0x0000001f,
+0x020,0x000001a3,
+0x01f,0x00000020,
+0x020,0x00000183,
+0x01f,0x00000021,
+0x020,0x00000163,
+0x01f,0x00000022,
+0x020,0x00000143,
+0x01f,0x00000023,
+0x020,0x00000123,
+0x01f,0x00000024,
+0x020,0x00000103,
+0x023,0x00000203,
+0x024,0x00000200,
+0x00b,0x000001ba,
+0x02c,0x000003d7,
+0x02d,0x00000ff0,
+0x000,0x00000037,
+0x004,0x00000160,
+0x007,0x00000080,
+0x002,0x0000088d,
+0x0fe,0x00000000,
+0x0fe,0x00000000,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x000,0x000000bf,
+0x00d,0x0000001f,
+0x00d,0x00000c9f,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+u32 Rtl8190PciRadioD_Array[RadioD_ArrayLength] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x000006e0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x000,0x000000b7,
+0x00a,0x00000850,
+0x000,0x000000bf,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000e00,
+0x01b,0x00000f5e,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x00b,0x000001ba,
+0x023,0x00000203,
+0x024,0x00000200,
+0x000,0x00000037,
+0x004,0x00000160,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x00d,0x00000ccc,
+0x000,0x000000bf,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+#endif
+#ifdef RTL8192E
+static u32 Rtl8192PciEMACPHY_Array[] = {
+0x03c,0xffff0000,0x00000f0f,
+0x340,0xffffffff,0x161a1a1a,
+0x344,0xffffffff,0x12121416,
+0x348,0x0000ffff,0x00001818,
+0x12c,0xffffffff,0x04000802,
+0x318,0x00000fff,0x00000100,
+};
+static u32 Rtl8192PciEMACPHY_Array_PG[] = {
+0x03c,0xffff0000,0x00000f0f,
+0xe00,0xffffffff,0x06090909,
+0xe04,0xffffffff,0x00030306,
+0xe08,0x0000ff00,0x00000000,
+0xe10,0xffffffff,0x0a0c0d0f,
+0xe14,0xffffffff,0x06070809,
+0xe18,0xffffffff,0x0a0c0d0f,
+0xe1c,0xffffffff,0x06070809,
+0x12c,0xffffffff,0x04000802,
+0x318,0x00000fff,0x00000800,
+};
+static u32 Rtl8192PciEAGCTAB_Array[AGCTAB_ArrayLength] = {
+0xc78,0x7d000001,
+0xc78,0x7d010001,
+0xc78,0x7d020001,
+0xc78,0x7d030001,
+0xc78,0x7d040001,
+0xc78,0x7d050001,
+0xc78,0x7c060001,
+0xc78,0x7b070001,
+0xc78,0x7a080001,
+0xc78,0x79090001,
+0xc78,0x780a0001,
+0xc78,0x770b0001,
+0xc78,0x760c0001,
+0xc78,0x750d0001,
+0xc78,0x740e0001,
+0xc78,0x730f0001,
+0xc78,0x72100001,
+0xc78,0x71110001,
+0xc78,0x70120001,
+0xc78,0x6f130001,
+0xc78,0x6e140001,
+0xc78,0x6d150001,
+0xc78,0x6c160001,
+0xc78,0x6b170001,
+0xc78,0x6a180001,
+0xc78,0x69190001,
+0xc78,0x681a0001,
+0xc78,0x671b0001,
+0xc78,0x661c0001,
+0xc78,0x651d0001,
+0xc78,0x641e0001,
+0xc78,0x491f0001,
+0xc78,0x48200001,
+0xc78,0x47210001,
+0xc78,0x46220001,
+0xc78,0x45230001,
+0xc78,0x44240001,
+0xc78,0x43250001,
+0xc78,0x28260001,
+0xc78,0x27270001,
+0xc78,0x26280001,
+0xc78,0x25290001,
+0xc78,0x242a0001,
+0xc78,0x232b0001,
+0xc78,0x222c0001,
+0xc78,0x212d0001,
+0xc78,0x202e0001,
+0xc78,0x0a2f0001,
+0xc78,0x08300001,
+0xc78,0x06310001,
+0xc78,0x05320001,
+0xc78,0x04330001,
+0xc78,0x03340001,
+0xc78,0x02350001,
+0xc78,0x01360001,
+0xc78,0x00370001,
+0xc78,0x00380001,
+0xc78,0x00390001,
+0xc78,0x003a0001,
+0xc78,0x003b0001,
+0xc78,0x003c0001,
+0xc78,0x003d0001,
+0xc78,0x003e0001,
+0xc78,0x003f0001,
+0xc78,0x7d400001,
+0xc78,0x7d410001,
+0xc78,0x7d420001,
+0xc78,0x7d430001,
+0xc78,0x7d440001,
+0xc78,0x7d450001,
+0xc78,0x7c460001,
+0xc78,0x7b470001,
+0xc78,0x7a480001,
+0xc78,0x79490001,
+0xc78,0x784a0001,
+0xc78,0x774b0001,
+0xc78,0x764c0001,
+0xc78,0x754d0001,
+0xc78,0x744e0001,
+0xc78,0x734f0001,
+0xc78,0x72500001,
+0xc78,0x71510001,
+0xc78,0x70520001,
+0xc78,0x6f530001,
+0xc78,0x6e540001,
+0xc78,0x6d550001,
+0xc78,0x6c560001,
+0xc78,0x6b570001,
+0xc78,0x6a580001,
+0xc78,0x69590001,
+0xc78,0x685a0001,
+0xc78,0x675b0001,
+0xc78,0x665c0001,
+0xc78,0x655d0001,
+0xc78,0x645e0001,
+0xc78,0x495f0001,
+0xc78,0x48600001,
+0xc78,0x47610001,
+0xc78,0x46620001,
+0xc78,0x45630001,
+0xc78,0x44640001,
+0xc78,0x43650001,
+0xc78,0x28660001,
+0xc78,0x27670001,
+0xc78,0x26680001,
+0xc78,0x25690001,
+0xc78,0x246a0001,
+0xc78,0x236b0001,
+0xc78,0x226c0001,
+0xc78,0x216d0001,
+0xc78,0x206e0001,
+0xc78,0x0a6f0001,
+0xc78,0x08700001,
+0xc78,0x06710001,
+0xc78,0x05720001,
+0xc78,0x04730001,
+0xc78,0x03740001,
+0xc78,0x02750001,
+0xc78,0x01760001,
+0xc78,0x00770001,
+0xc78,0x00780001,
+0xc78,0x00790001,
+0xc78,0x007a0001,
+0xc78,0x007b0001,
+0xc78,0x007c0001,
+0xc78,0x007d0001,
+0xc78,0x007e0001,
+0xc78,0x007f0001,
+0xc78,0x2e00001e,
+0xc78,0x2e01001e,
+0xc78,0x2e02001e,
+0xc78,0x2e03001e,
+0xc78,0x2e04001e,
+0xc78,0x2e05001e,
+0xc78,0x3006001e,
+0xc78,0x3407001e,
+0xc78,0x3908001e,
+0xc78,0x3c09001e,
+0xc78,0x3f0a001e,
+0xc78,0x420b001e,
+0xc78,0x440c001e,
+0xc78,0x450d001e,
+0xc78,0x460e001e,
+0xc78,0x460f001e,
+0xc78,0x4710001e,
+0xc78,0x4811001e,
+0xc78,0x4912001e,
+0xc78,0x4a13001e,
+0xc78,0x4b14001e,
+0xc78,0x4b15001e,
+0xc78,0x4c16001e,
+0xc78,0x4d17001e,
+0xc78,0x4e18001e,
+0xc78,0x4f19001e,
+0xc78,0x4f1a001e,
+0xc78,0x501b001e,
+0xc78,0x511c001e,
+0xc78,0x521d001e,
+0xc78,0x521e001e,
+0xc78,0x531f001e,
+0xc78,0x5320001e,
+0xc78,0x5421001e,
+0xc78,0x5522001e,
+0xc78,0x5523001e,
+0xc78,0x5624001e,
+0xc78,0x5725001e,
+0xc78,0x5726001e,
+0xc78,0x5827001e,
+0xc78,0x5828001e,
+0xc78,0x5929001e,
+0xc78,0x592a001e,
+0xc78,0x5a2b001e,
+0xc78,0x5b2c001e,
+0xc78,0x5c2d001e,
+0xc78,0x5c2e001e,
+0xc78,0x5d2f001e,
+0xc78,0x5e30001e,
+0xc78,0x5f31001e,
+0xc78,0x6032001e,
+0xc78,0x6033001e,
+0xc78,0x6134001e,
+0xc78,0x6235001e,
+0xc78,0x6336001e,
+0xc78,0x6437001e,
+0xc78,0x6438001e,
+0xc78,0x6539001e,
+0xc78,0x663a001e,
+0xc78,0x673b001e,
+0xc78,0x673c001e,
+0xc78,0x683d001e,
+0xc78,0x693e001e,
+0xc78,0x6a3f001e,
+};
+static u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLength] = {
+0x0, };
+static u32 Rtl8192PciEPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = {
+0x800,0x00000000,
+0x804,0x00000001,
+0x808,0x0000fc00,
+0x80c,0x0000001c,
+0x810,0x801010aa,
+0x814,0x008514d0,
+0x818,0x00000040,
+0x81c,0x00000000,
+0x820,0x00000004,
+0x824,0x00690000,
+0x828,0x00000004,
+0x82c,0x00e90000,
+0x830,0x00000004,
+0x834,0x00690000,
+0x838,0x00000004,
+0x83c,0x00e90000,
+0x840,0x00000000,
+0x844,0x00000000,
+0x848,0x00000000,
+0x84c,0x00000000,
+0x850,0x00000000,
+0x854,0x00000000,
+0x858,0x65a965a9,
+0x85c,0x65a965a9,
+0x860,0x001f0010,
+0x864,0x007f0010,
+0x868,0x001f0010,
+0x86c,0x007f0010,
+0x870,0x0f100f70,
+0x874,0x0f100f70,
+0x878,0x00000000,
+0x87c,0x00000000,
+0x880,0x6870e36c,
+0x884,0xe3573600,
+0x888,0x4260c340,
+0x88c,0x0000ff00,
+0x890,0x00000000,
+0x894,0xfffffffe,
+0x898,0x4c42382f,
+0x89c,0x00656056,
+0x8b0,0x00000000,
+0x8e0,0x00000000,
+0x8e4,0x00000000,
+0x900,0x00000000,
+0x904,0x00000023,
+0x908,0x00000000,
+0x90c,0x31121311,
+0xa00,0x00d0c7d8,
+0xa04,0x811f0008,
+0xa08,0x80cd8300,
+0xa0c,0x2e62740f,
+0xa10,0x95009b78,
+0xa14,0x11145008,
+0xa18,0x00881117,
+0xa1c,0x89140fa0,
+0xa20,0x1a1b0000,
+0xa24,0x090e1317,
+0xa28,0x00000204,
+0xa2c,0x00000000,
+0xc00,0x00000040,
+0xc04,0x00005433,
+0xc08,0x000000e4,
+0xc0c,0x6c6c6c6c,
+0xc10,0x08800000,
+0xc14,0x40000100,
+0xc18,0x08000000,
+0xc1c,0x40000100,
+0xc20,0x08000000,
+0xc24,0x40000100,
+0xc28,0x08000000,
+0xc2c,0x40000100,
+0xc30,0x6de9ac44,
+0xc34,0x465c52cd,
+0xc38,0x497f5994,
+0xc3c,0x0a969764,
+0xc40,0x1f7c403f,
+0xc44,0x000100b7,
+0xc48,0xec020000,
+0xc4c,0x00000300,
+0xc50,0x69543420,
+0xc54,0x433c0094,
+0xc58,0x69543420,
+0xc5c,0x433c0094,
+0xc60,0x69543420,
+0xc64,0x433c0094,
+0xc68,0x69543420,
+0xc6c,0x433c0094,
+0xc70,0x2c7f000d,
+0xc74,0x0186175b,
+0xc78,0x0000001f,
+0xc7c,0x00b91612,
+0xc80,0x40000100,
+0xc84,0x20000000,
+0xc88,0x40000100,
+0xc8c,0x20200000,
+0xc90,0x40000100,
+0xc94,0x00000000,
+0xc98,0x40000100,
+0xc9c,0x00000000,
+0xca0,0x00492492,
+0xca4,0x00000000,
+0xca8,0x00000000,
+0xcac,0x00000000,
+0xcb0,0x00000000,
+0xcb4,0x00000000,
+0xcb8,0x00000000,
+0xcbc,0x00492492,
+0xcc0,0x00000000,
+0xcc4,0x00000000,
+0xcc8,0x00000000,
+0xccc,0x00000000,
+0xcd0,0x00000000,
+0xcd4,0x00000000,
+0xcd8,0x64b22427,
+0xcdc,0x00766932,
+0xce0,0x00222222,
+0xd00,0x00000750,
+0xd04,0x00000403,
+0xd08,0x0000907f,
+0xd0c,0x00000001,
+0xd10,0xa0633333,
+0xd14,0x33333c63,
+0xd18,0x6a8f5b6b,
+0xd1c,0x00000000,
+0xd20,0x00000000,
+0xd24,0x00000000,
+0xd28,0x00000000,
+0xd2c,0xcc979975,
+0xd30,0x00000000,
+0xd34,0x00000000,
+0xd38,0x00000000,
+0xd3c,0x00027293,
+0xd40,0x00000000,
+0xd44,0x00000000,
+0xd48,0x00000000,
+0xd4c,0x00000000,
+0xd50,0x6437140a,
+0xd54,0x024dbd02,
+0xd58,0x00000000,
+0xd5c,0x04032064,
+0xe00,0x161a1a1a,
+0xe04,0x12121416,
+0xe08,0x00001800,
+0xe0c,0x00000000,
+0xe10,0x161a1a1a,
+0xe14,0x12121416,
+0xe18,0x161a1a1a,
+0xe1c,0x12121416,
+};
+static u32 Rtl8192PciERadioA_Array[RadioA_ArrayLength] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x00000ee0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x009,0x000007f0,
+0x00a,0x000009d0,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x00f,0x00000990,
+0x012,0x00000806,
+0x014,0x000005ab,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000f80,
+0x01b,0x00000f5e,
+0x01c,0x00000008,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x01f,0x00000000,
+0x020,0x000001a5,
+0x01f,0x00000001,
+0x020,0x00000165,
+0x01f,0x00000002,
+0x020,0x000000c6,
+0x01f,0x00000003,
+0x020,0x00000086,
+0x01f,0x00000004,
+0x020,0x00000046,
+0x01f,0x00000005,
+0x020,0x000001e6,
+0x01f,0x00000006,
+0x020,0x000001a6,
+0x01f,0x00000007,
+0x020,0x00000166,
+0x01f,0x00000008,
+0x020,0x000000c7,
+0x01f,0x00000009,
+0x020,0x00000087,
+0x01f,0x0000000a,
+0x020,0x000000f7,
+0x01f,0x0000000b,
+0x020,0x000000d7,
+0x01f,0x0000000c,
+0x020,0x000000b7,
+0x01f,0x0000000d,
+0x020,0x00000097,
+0x01f,0x0000000e,
+0x020,0x00000077,
+0x01f,0x0000000f,
+0x020,0x00000057,
+0x01f,0x00000010,
+0x020,0x00000037,
+0x01f,0x00000011,
+0x020,0x000000fb,
+0x01f,0x00000012,
+0x020,0x000000db,
+0x01f,0x00000013,
+0x020,0x000000bb,
+0x01f,0x00000014,
+0x020,0x000000ff,
+0x01f,0x00000015,
+0x020,0x000000e3,
+0x01f,0x00000016,
+0x020,0x000000c3,
+0x01f,0x00000017,
+0x020,0x000000a3,
+0x01f,0x00000018,
+0x020,0x00000083,
+0x01f,0x00000019,
+0x020,0x00000063,
+0x01f,0x0000001a,
+0x020,0x00000043,
+0x01f,0x0000001b,
+0x020,0x00000023,
+0x01f,0x0000001c,
+0x020,0x00000003,
+0x01f,0x0000001d,
+0x020,0x000001e3,
+0x01f,0x0000001e,
+0x020,0x000001c3,
+0x01f,0x0000001f,
+0x020,0x000001a3,
+0x01f,0x00000020,
+0x020,0x00000183,
+0x01f,0x00000021,
+0x020,0x00000163,
+0x01f,0x00000022,
+0x020,0x00000143,
+0x01f,0x00000023,
+0x020,0x00000123,
+0x01f,0x00000024,
+0x020,0x00000103,
+0x023,0x00000203,
+0x024,0x00000100,
+0x00b,0x000001ba,
+0x02c,0x000003d7,
+0x02d,0x00000ff0,
+0x000,0x00000037,
+0x004,0x00000160,
+0x007,0x00000080,
+0x002,0x0000088d,
+0x0fe,0x00000000,
+0x0fe,0x00000000,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x000,0x000000bf,
+0x00d,0x0000001f,
+0x00d,0x00000c9f,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+static u32 Rtl8192PciERadioB_Array[RadioB_ArrayLength] = {
+0x019,0x00000003,
+0x000,0x000000bf,
+0x001,0x000006e0,
+0x002,0x0000004c,
+0x003,0x000007f1,
+0x004,0x00000975,
+0x005,0x00000c58,
+0x006,0x00000ae6,
+0x007,0x000000ca,
+0x008,0x00000e1c,
+0x000,0x000000b7,
+0x00a,0x00000850,
+0x000,0x000000bf,
+0x00b,0x000001ba,
+0x00c,0x00000240,
+0x00e,0x00000020,
+0x015,0x00000f80,
+0x016,0x00000020,
+0x017,0x00000597,
+0x018,0x0000050a,
+0x01a,0x00000e00,
+0x01b,0x00000f5e,
+0x01d,0x00000607,
+0x01e,0x000006cc,
+0x00b,0x000001ba,
+0x023,0x00000203,
+0x024,0x00000100,
+0x000,0x00000037,
+0x004,0x00000160,
+0x016,0x00000200,
+0x016,0x00000380,
+0x016,0x00000020,
+0x016,0x000001a0,
+0x00d,0x00000ccc,
+0x000,0x000000bf,
+0x002,0x0000004d,
+0x000,0x00000cbf,
+0x004,0x00000975,
+0x007,0x00000700,
+};
+static u32 Rtl8192PciERadioC_Array[RadioC_ArrayLength] = {
+0x0,  };
+static u32 Rtl8192PciERadioD_Array[RadioD_ArrayLength] = {
+0x0, };
+#endif
+
+/*************************Define local function prototype**********************/
+
+static u32 phy_FwRFSerialRead(struct net_device* dev,RF90_RADIO_PATH_E	eRFPath,u32 Offset);
+static void phy_FwRFSerialWrite(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset,u32	Data);
+/*************************Define local function prototype**********************/
+/******************************************************************************
+ *function:  This function read BB parameters from Header file we gen,
+ *	     and do register read/write
+ *   input:  u32	dwBitMask  //taget bit pos in the addr to be modified
+ *  output:  none
+ *  return:  u32	return the shift bit bit position of the mask
+ * ****************************************************************************/
+static u32 rtl8192_CalculateBitShift(u32 dwBitMask)
+{
+	u32 i;
+	for (i=0; i<=31; i++)
+	{
+		if (((dwBitMask>>i)&0x1) == 1)
+			break;
+	}
+	return i;
+}
+/******************************************************************************
+ *function:  This function check different RF type to execute legal judgement. If RF Path is illegal, we will return false.
+ *   input:  none
+ *  output:  none
+ *  return:  0(illegal, false), 1(legal,true)
+ * ***************************************************************************/
+u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
+{
+	u8 ret = 1;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef RTL8190P
+	if(priv->rf_type == RF_2T4R)
+	{
+		ret= 1;
+	}
+	else if (priv->rf_type == RF_1T2R)
+	{
+		if(eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B)
+			ret = 0;
+		else if(eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D)
+			ret =  1;
+	}
+#else
+	#ifdef RTL8192E
+	if (priv->rf_type == RF_2T4R)
+		ret = 0;
+	else if (priv->rf_type == RF_1T2R)
+	{
+		if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B)
+			ret = 1;
+		else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D)
+			ret = 0;
+	}
+	#endif
+#endif
+	return ret;
+}
+/******************************************************************************
+ *function:  This function set specific bits to BB register
+ *   input:  net_device dev
+ *           u32	dwRegAddr  //target addr to be modified
+ *           u32	dwBitMask  //taget bit pos in the addr to be modified
+ *           u32	dwData     //value to be write
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ****************************************************************************/
+void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData)
+{
+
+	u32 OriginalValue, BitShift, NewValue;
+
+	if(dwBitMask!= bMaskDWord)
+	{//if not "double word" write
+		OriginalValue = read_nic_dword(dev, dwRegAddr);
+		BitShift = rtl8192_CalculateBitShift(dwBitMask);
+            	NewValue = (((OriginalValue) & (~dwBitMask)) | (dwData << BitShift));
+		write_nic_dword(dev, dwRegAddr, NewValue);
+	}else
+		write_nic_dword(dev, dwRegAddr, dwData);
+	return;
+}
+/******************************************************************************
+ *function:  This function reads specific bits from BB register
+ *   input:  net_device dev
+ *           u32	dwRegAddr  //target addr to be readback
+ *           u32	dwBitMask  //taget bit pos in the addr to be readback
+ *  output:  none
+ *  return:  u32	Data	//the readback register value
+ *  notice:
+ * ****************************************************************************/
+u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask)
+{
+	u32 Ret = 0, OriginalValue, BitShift;
+
+	OriginalValue = read_nic_dword(dev, dwRegAddr);
+	BitShift = rtl8192_CalculateBitShift(dwBitMask);
+	Ret = (OriginalValue & dwBitMask) >> BitShift;
+
+	return (Ret);
+}
+/******************************************************************************
+ *function:  This function read register from RF chip
+ *   input:  net_device dev
+ *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
+ *           u32	Offset     //target address to be read
+ *  output:  none
+ *  return:  u32 	readback value
+ *  notice:  There are three types of serial operations:(1) Software serial write.(2)Hardware LSSI-Low Speed Serial Interface.(3)Hardware HSSI-High speed serial write. Driver here need to implement (1) and (2)---need more spec for this information.
+ * ****************************************************************************/
+static u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 ret = 0;
+	u32 NewOffset = 0;
+	BB_REGISTER_DEFINITION_T* pPhyReg = &priv->PHYRegDef[eRFPath];
+	//rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0);
+	//make sure RF register offset is correct
+	Offset &= 0x3f;
+
+	//switch page for 8256 RF IC
+	if (priv->rf_chip == RF_8256)
+	{
+#ifdef RTL8190P
+		//analog to digital off, for protection
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
+#else
+	#ifdef RTL8192E
+		//analog to digital off, for protection
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
+	#endif
+#endif
+		if (Offset >= 31)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x140;
+			//Switch to Reg_Mode2 for Reg 31-45
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) );
+			//modify offset
+			NewOffset = Offset -30;
+		}
+		else if (Offset >= 16)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x100;
+			priv->RfReg0Value[eRFPath] &= (~0x40);
+			//Switch to Reg_Mode 1 for Reg16-30
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) );
+
+			NewOffset = Offset - 15;
+		}
+		else
+			NewOffset = Offset;
+	}
+	else
+	{
+		RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
+		NewOffset = Offset;
+	}
+	//put desired read addr to LSSI control Register
+	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset);
+	//Issue a posedge trigger
+	//
+	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x0);
+	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x1);
+
+
+	// TODO: we should not delay such a  long time. Ask help from SD3
+	msleep(1);
+
+	ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
+
+
+	// Switch back to Reg_Mode0;
+	if(priv->rf_chip == RF_8256)
+	{
+		priv->RfReg0Value[eRFPath] &= 0xebf;
+
+		rtl8192_setBBreg(
+			dev,
+			pPhyReg->rf3wireOffset,
+			bMaskDWord,
+			(priv->RfReg0Value[eRFPath] << 16));
+
+#ifdef RTL8190P
+		if(priv->rf_type == RF_2T4R)
+		{
+			//analog to digital on
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8]
+		}
+		else if(priv->rf_type == RF_1T2R)
+		{
+			//analog to digital on
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10]
+		}
+#else
+	#ifdef RTL8192E
+		//analog to digital on
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
+	#endif
+#endif
+	}
+
+
+	return ret;
+
+}
+
+/******************************************************************************
+ *function:  This function write data to RF register
+ *   input:  net_device dev
+ *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
+ *           u32	Offset     //target address to be written
+ *           u32	Data	//The new register data to be written
+ *  output:  none
+ *  return:  none
+ *  notice:  For RF8256 only.
+  ===========================================================
+ *Reg Mode	RegCTL[1]	RegCTL[0]		Note
+ *		(Reg00[12])	(Reg00[10])
+ *===========================================================
+ *Reg_Mode0	0		x			Reg 0 ~15(0x0 ~ 0xf)
+ *------------------------------------------------------------------
+ *Reg_Mode1	1		0			Reg 16 ~30(0x1 ~ 0xf)
+ *------------------------------------------------------------------
+ * Reg_Mode2	1		1			Reg 31 ~ 45(0x1 ~ 0xf)
+ *------------------------------------------------------------------
+ * ****************************************************************************/
+static void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 DataAndAddr = 0, NewOffset = 0;
+	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];
+
+	Offset &= 0x3f;
+	if (priv->rf_chip == RF_8256)
+	{
+
+#ifdef RTL8190P
+		//analog to digital off, for protection
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
+#else
+	#ifdef RTL8192E
+		//analog to digital off, for protection
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
+	#endif
+#endif
+
+		if (Offset >= 31)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x140;
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16));
+			NewOffset = Offset - 30;
+		}
+		else if (Offset >= 16)
+		{
+			priv->RfReg0Value[eRFPath] |= 0x100;
+			priv->RfReg0Value[eRFPath] &= (~0x40);
+			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
+			NewOffset = Offset - 15;
+		}
+		else
+			NewOffset = Offset;
+	}
+	else
+	{
+		RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
+		NewOffset = Offset;
+	}
+
+	// Put write addr in [5:0]  and write data in [31:16]
+	DataAndAddr = (Data<<16) | (NewOffset&0x3f);
+
+	// Write Operation
+	rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
+
+
+	if(Offset==0x0)
+		priv->RfReg0Value[eRFPath] = Data;
+
+	// Switch back to Reg_Mode0;
+ 	if(priv->rf_chip == RF_8256)
+	{
+		if(Offset != 0)
+		{
+			priv->RfReg0Value[eRFPath] &= 0xebf;
+			rtl8192_setBBreg(
+				dev,
+				pPhyReg->rf3wireOffset,
+				bMaskDWord,
+				(priv->RfReg0Value[eRFPath] << 16));
+		}
+#ifdef RTL8190P
+		if(priv->rf_type == RF_2T4R)
+		{
+			//analog to digital on
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8]
+		}
+		else if(priv->rf_type == RF_1T2R)
+		{
+			//analog to digital on
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10]
+		}
+#else
+	#ifdef RTL8192E
+		//analog to digital on
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
+	#endif
+#endif
+	}
+
+	return;
+}
+
+/******************************************************************************
+ *function:  This function set specific bits to RF register
+ *   input:  net_device dev
+ *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
+ *           u32	RegAddr  //target addr to be modified
+ *           u32	BitMask  //taget bit pos in the addr to be modified
+ *           u32	Data     //value to be write
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ****************************************************************************/
+void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32 Original_Value, BitShift, New_Value;
+//	u8	time = 0;
+
+	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+		return;
+#ifdef RTL8192E
+	if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter)
+		return;
+#endif
+	//spin_lock_irqsave(&priv->rf_lock, flags);
+	//down(&priv->rf_sem);
+
+	RT_TRACE(COMP_PHY, "FW RF CTRL is not ready now\n");
+	if (priv->Rf_Mode == RF_OP_By_FW)
+	{
+		if (BitMask != bMask12Bits) // RF data is 12 bits only
+		{
+			Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
+			BitShift =  rtl8192_CalculateBitShift(BitMask);
+			New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift));
+
+			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value);
+		}else
+			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data);
+		udelay(200);
+
+	}
+	else
+	{
+		if (BitMask != bMask12Bits) // RF data is 12 bits only
+   	        {
+			Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
+      			BitShift =  rtl8192_CalculateBitShift(BitMask);
+      			New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift));
+
+			rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, New_Value);
+	        }else
+			rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data);
+	}
+	//spin_unlock_irqrestore(&priv->rf_lock, flags);
+	//up(&priv->rf_sem);
+	return;
+}
+
+/******************************************************************************
+ *function:  This function reads specific bits from RF register
+ *   input:  net_device dev
+ *           u32	RegAddr  //target addr to be readback
+ *           u32	BitMask  //taget bit pos in the addr to be readback
+ *  output:  none
+ *  return:  u32	Data	//the readback register value
+ *  notice:
+ * ****************************************************************************/
+u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask)
+{
+	u32 Original_Value, Readback_Value, BitShift;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+		return 0;
+#ifdef RTL8192E
+	if(priv->ieee80211->eRFPowerState != eRfOn && !priv->being_init_adapter)
+		return	0;
+#endif
+	down(&priv->rf_sem);
+	if (priv->Rf_Mode == RF_OP_By_FW)
+	{
+		Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
+		udelay(200);
+	}
+	else
+	{
+		Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
+
+	}
+	BitShift =  rtl8192_CalculateBitShift(BitMask);
+   	Readback_Value = (Original_Value & BitMask) >> BitShift;
+	up(&priv->rf_sem);
+//	udelay(200);
+	return (Readback_Value);
+}
+
+/******************************************************************************
+ *function:  We support firmware to execute RF-R/W.
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ***************************************************************************/
+static u32 phy_FwRFSerialRead(
+	struct net_device* dev,
+	RF90_RADIO_PATH_E	eRFPath,
+	u32				Offset	)
+{
+	u32		retValue = 0;
+	u32		Data = 0;
+	u8		time = 0;
+	//DbgPrint("FW RF CTRL\n\r");
+	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
+	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
+	   much time. This is only for site survey. */
+	// 1. Read operation need not insert data. bit 0-11
+	//Data &= bMask12Bits;
+	// 2. Write RF register address. Bit 12-19
+	Data |= ((Offset&0xFF)<<12);
+	// 3. Write RF path.  bit 20-21
+	Data |= ((eRFPath&0x3)<<20);
+	// 4. Set RF read indicator. bit 22=0
+	//Data |= 0x00000;
+	// 5. Trigger Fw to operate the command. bit 31
+	Data |= 0x80000000;
+	// 6. We can not execute read operation if bit 31 is 1.
+	while (read_nic_dword(dev, QPNR)&0x80000000)
+	{
+		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
+		if (time++ < 100)
+		{
+			//DbgPrint("FW not finish RF-R Time=%d\n\r", time);
+			udelay(10);
+		}
+		else
+			break;
+	}
+	// 7. Execute read operation.
+	write_nic_dword(dev, QPNR, Data);
+	// 8. Check if firmawre send back RF content.
+	while (read_nic_dword(dev, QPNR)&0x80000000)
+	{
+		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
+		if (time++ < 100)
+		{
+			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
+			udelay(10);
+		}
+		else
+			return	(0);
+	}
+	retValue = read_nic_dword(dev, RF_DATA);
+
+	return	(retValue);
+
+}	/* phy_FwRFSerialRead */
+
+/******************************************************************************
+ *function:  We support firmware to execute RF-R/W.
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:
+ * ***************************************************************************/
+static void
+phy_FwRFSerialWrite(
+		struct net_device* dev,
+		RF90_RADIO_PATH_E	eRFPath,
+		u32				Offset,
+		u32				Data	)
+{
+	u8	time = 0;
+
+	//DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data);
+	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
+	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
+	   much time. This is only for site survey. */
+
+	// 1. Set driver write bit and 12 bit data. bit 0-11
+	//Data &= bMask12Bits;	// Done by uper layer.
+	// 2. Write RF register address. bit 12-19
+	Data |= ((Offset&0xFF)<<12);
+	// 3. Write RF path.  bit 20-21
+	Data |= ((eRFPath&0x3)<<20);
+	// 4. Set RF write indicator. bit 22=1
+	Data |= 0x400000;
+	// 5. Trigger Fw to operate the command. bit 31=1
+	Data |= 0x80000000;
+
+	// 6. Write operation. We can not write if bit 31 is 1.
+	while (read_nic_dword(dev, QPNR)&0x80000000)
+	{
+		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
+		if (time++ < 100)
+		{
+			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
+			udelay(10);
+		}
+		else
+			break;
+	}
+	// 7. No matter check bit. We always force the write. Because FW will
+	//    not accept the command.
+	write_nic_dword(dev, QPNR, Data);
+	/* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware
+	   to finish RF write operation. */
+	/* 2008/01/17 MH We support delay in firmware side now. */
+	//delay_us(20);
+
+}	/* phy_FwRFSerialWrite */
+
+
+/******************************************************************************
+ *function:  This function read BB parameters from Header file we gen,
+ *	     and do register read/write
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:  BB parameters may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+void rtl8192_phy_configmac(struct net_device* dev)
+{
+	u32 dwArrayLen = 0, i = 0;
+	u32* pdwArray = NULL;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef TO_DO_LIST
+if(Adapter->bInHctTest)
+	{
+		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_ArrayDTM\n");
+		dwArrayLen = MACPHY_ArrayLengthDTM;
+		pdwArray = Rtl819XMACPHY_ArrayDTM;
+	}
+	else if(priv->bTXPowerDataReadFromEEPORM)
+#endif
+	 if(priv->bTXPowerDataReadFromEEPORM)
+	{
+		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n");
+		dwArrayLen = MACPHY_Array_PGLength;
+		pdwArray = Rtl819XMACPHY_Array_PG;
+
+	}
+	else
+	{
+		RT_TRACE(COMP_PHY,"Read rtl819XMACPHY_Array\n");
+		dwArrayLen = MACPHY_ArrayLength;
+		pdwArray = Rtl819XMACPHY_Array;
+	}
+	for(i = 0; i<dwArrayLen; i=i+3){
+		RT_TRACE(COMP_DBG, "The Rtl8190MACPHY_Array[0] is %x Rtl8190MACPHY_Array[1] is %x Rtl8190MACPHY_Array[2] is %x\n",
+				pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
+		if(pdwArray[i] == 0x318)
+		{
+			pdwArray[i+2] = 0x00000800;
+			//DbgPrint("ptrArray[i], ptrArray[i+1], ptrArray[i+2] = %x, %x, %x\n",
+			//	ptrArray[i], ptrArray[i+1], ptrArray[i+2]);
+		}
+		rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
+	}
+	return;
+
+}
+
+/******************************************************************************
+ *function:  This function do dirty work
+ *   input:  dev
+ *  output:  none
+ *  return:  none
+ *  notice:  BB parameters may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+
+void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType)
+{
+	int i;
+	//u8 ArrayLength;
+	u32*	Rtl819XPHY_REGArray_Table = NULL;
+	u32*	Rtl819XAGCTAB_Array_Table = NULL;
+	u16	AGCTAB_ArrayLen, PHY_REGArrayLen = 0;
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef TO_DO_LIST
+	u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL;
+	if(Adapter->bInHctTest)
+	{
+		AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM;
+		Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
+
+		if(priv->RF_Type == RF_2T4R)
+		{
+			PHY_REGArrayLen = PHY_REGArrayLengthDTM;
+			Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArrayDTM;
+		}
+		else if (priv->RF_Type == RF_1T2R)
+		{
+			PHY_REGArrayLen = PHY_REG_1T2RArrayLengthDTM;
+			Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArrayDTM;
+		}
+	}
+	else
+#endif
+	{
+		AGCTAB_ArrayLen = AGCTAB_ArrayLength;
+		Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_Array;
+		if(priv->rf_type == RF_2T4R)
+		{
+			PHY_REGArrayLen = PHY_REGArrayLength;
+			Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArray;
+		}
+		else if (priv->rf_type == RF_1T2R)
+		{
+			PHY_REGArrayLen = PHY_REG_1T2RArrayLength;
+			Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArray;
+		}
+	}
+
+	if (ConfigType == BaseBand_Config_PHY_REG)
+	{
+		for (i=0; i<PHY_REGArrayLen; i+=2)
+		{
+			rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table[i], bMaskDWord, Rtl819XPHY_REGArray_Table[i+1]);
+			RT_TRACE(COMP_DBG, "i: %x, The Rtl819xUsbPHY_REGArray[0] is %x Rtl819xUsbPHY_REGArray[1] is %x \n",i, Rtl819XPHY_REGArray_Table[i], Rtl819XPHY_REGArray_Table[i+1]);
+		}
+	}
+	else if (ConfigType == BaseBand_Config_AGC_TAB)
+	{
+		for (i=0; i<AGCTAB_ArrayLen; i+=2)
+		{
+			rtl8192_setBBreg(dev, Rtl819XAGCTAB_Array_Table[i], bMaskDWord, Rtl819XAGCTAB_Array_Table[i+1]);
+			RT_TRACE(COMP_DBG, "i:%x, The rtl819XAGCTAB_Array[0] is %x rtl819XAGCTAB_Array[1] is %x \n",i, Rtl819XAGCTAB_Array_Table[i], Rtl819XAGCTAB_Array_Table[i+1]);
+		}
+	}
+	return;
+
+
+}
+/******************************************************************************
+ *function:  This function initialize Register definition offset for Radio Path
+ *	     A/B/C/D
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  Initialization value here is constant and it should never be changed
+ * ***************************************************************************/
+static void rtl8192_InitBBRFRegDef(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+// RF Interface Sowrtware Control
+	priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
+	priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
+	priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874
+	priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876)
+
+	// RF Interface Readback Value
+	priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0
+	priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2)
+	priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4
+	priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6)
+
+	// RF Interface Output (and Enable)
+	priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
+	priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
+	priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868
+	priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C
+
+	// RF Interface (Output and)  Enable
+	priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
+	priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
+	priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A)
+	priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E)
+
+	//Addr of LSSI. Wirte RF register by driver
+	priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
+	priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
+	priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
+	priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
+
+	// RF parameter
+	priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;  //BB Band Select
+	priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
+	priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
+	priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
+
+	// Tx AGC Gain Stage (same for all path. Should we remove this?)
+	priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+	priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+	priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+	priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
+
+	// Tranceiver A~D HSSI Parameter-1
+	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;  //wire control parameter1
+	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;  //wire control parameter1
+	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1;  //wire control parameter1
+	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1;  //wire control parameter1
+
+	// Tranceiver A~D HSSI Parameter-2
+	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  //wire control parameter2
+	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;  //wire control parameter2
+	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2;  //wire control parameter2
+	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2;  //wire control parameter1
+
+	// RF switch Control
+	priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control
+	priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
+	priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
+	priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
+
+	// AGC control 1
+	priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
+	priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
+	priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
+	priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
+
+	// AGC control 2
+	priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
+	priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
+	priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
+	priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
+
+	// RX AFE control 1
+	priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
+
+	// RX AFE control 1
+	priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
+	priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
+	priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
+	priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
+
+	// Tx AFE control 1
+	priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
+	priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
+
+	// Tx AFE control 2
+	priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
+	priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
+	priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
+	priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
+
+	// Tranceiver LSSI Readback
+	priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
+	priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
+	priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
+	priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
+
+}
+/******************************************************************************
+ *function:  This function is to write register and then readback to make sure whether BB and RF is OK
+ *   input:  net_device dev
+ *   	     HW90_BLOCK_E CheckBlock
+ *   	     RF90_RADIO_PATH_E eRFPath  //only used when checkblock is HW90_BLOCK_RF
+ *  output:  none
+ *  return:  return whether BB and RF is ok(0:OK; 1:Fail)
+ *  notice:  This function may be removed in the ASIC
+ * ***************************************************************************/
+RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath)
+{
+	//struct r8192_priv *priv = ieee80211_priv(dev);
+//	BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
+	RT_STATUS ret = RT_STATUS_SUCCESS;
+	u32 i, CheckTimes = 4, dwRegRead = 0;
+	u32 WriteAddr[4];
+	u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
+	// Initialize register address offset to be checked
+	WriteAddr[HW90_BLOCK_MAC] = 0x100;
+	WriteAddr[HW90_BLOCK_PHY0] = 0x900;
+	WriteAddr[HW90_BLOCK_PHY1] = 0x800;
+	WriteAddr[HW90_BLOCK_RF] = 0x3;
+	RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __FUNCTION__, CheckBlock);
+	for(i=0 ; i < CheckTimes ; i++)
+	{
+
+		//
+		// Write Data to register and readback
+		//
+		switch(CheckBlock)
+		{
+		case HW90_BLOCK_MAC:
+			RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write 0x100 here!");
+			break;
+
+		case HW90_BLOCK_PHY0:
+		case HW90_BLOCK_PHY1:
+			write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]);
+			dwRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]);
+			break;
+
+		case HW90_BLOCK_RF:
+			WriteData[i] &= 0xfff;
+			rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]);
+			// TODO: we should not delay for such a long time. Ask SD3
+			mdelay(10);
+			dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord);
+			mdelay(10);
+			break;
+
+		default:
+			ret = RT_STATUS_FAILURE;
+			break;
+		}
+
+
+		//
+		// Check whether readback data is correct
+		//
+		if(dwRegRead != WriteData[i])
+		{
+			RT_TRACE(COMP_ERR, "====>error=====dwRegRead: %x, WriteData: %x \n", dwRegRead, WriteData[i]);
+			ret = RT_STATUS_FAILURE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+
+/******************************************************************************
+ *function:  This function initialize BB&RF
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  Initialization value may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+static RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_STATUS rtStatus = RT_STATUS_SUCCESS;
+	u8 bRegValue = 0, eCheckItem = 0;
+	u32 dwRegValue = 0;
+	/**************************************
+	//<1>Initialize BaseBand
+	**************************************/
+
+	/*--set BB Global Reset--*/
+	bRegValue = read_nic_byte(dev, BB_GLOBAL_RESET);
+	write_nic_byte(dev, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT));
+
+	/*---set BB reset Active---*/
+	dwRegValue = read_nic_dword(dev, CPU_GEN);
+	write_nic_dword(dev, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST)));
+
+	/*----Ckeck FPGAPHY0 and PHY1 board is OK----*/
+	// TODO: this function should be removed on ASIC , Emily 2007.2.2
+	for(eCheckItem=(HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem<=HW90_BLOCK_PHY1; eCheckItem++)
+	{
+		rtStatus  = rtl8192_phy_checkBBAndRF(dev, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path
+		if(rtStatus != RT_STATUS_SUCCESS)
+		{
+			RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1);
+			return rtStatus;
+		}
+	}
+	/*---- Set CCK and OFDM Block "OFF"----*/
+	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
+	/*----BB Register Initilazation----*/
+	//==m==>Set PHY REG From Header<==m==
+	rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG);
+
+	/*----Set BB reset de-Active----*/
+	dwRegValue = read_nic_dword(dev, CPU_GEN);
+	write_nic_dword(dev, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST));
+
+ 	/*----BB AGC table Initialization----*/
+	//==m==>Set PHY REG From Header<==m==
+	rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB);
+
+	if (priv->card_8192_version  > VERSION_8190_BD)
+	{
+		if(priv->rf_type == RF_2T4R)
+		{
+		// Antenna gain offset from B/C/D to A
+		dwRegValue = (  priv->AntennaTxPwDiff[2]<<8 |
+						priv->AntennaTxPwDiff[1]<<4 |
+						priv->AntennaTxPwDiff[0]);
+		}
+		else
+			dwRegValue = 0x0;	//Antenna gain offset doesn't make sense in RF 1T2R.
+		rtl8192_setBBreg(dev, rFPGA0_TxGainStage,
+			(bXBTxAGC|bXCTxAGC|bXDTxAGC), dwRegValue);
+
+
+		//XSTALLCap
+#ifdef RTL8190P
+	dwRegValue = priv->CrystalCap & 0x3;	// bit0~1 of crystal cap
+	rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap01, dwRegValue);
+	dwRegValue = ((priv->CrystalCap & 0xc)>>2);	// bit2~3 of crystal cap
+	rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, bXtalCap23, dwRegValue);
+#else
+	#ifdef RTL8192E
+		dwRegValue = priv->CrystalCap;
+		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, dwRegValue);
+	#endif
+#endif
+
+	}
+
+	// Check if the CCK HighPower is turned ON.
+	// This is used to calculate PWDB.
+//	priv->bCckHighPower = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
+	return rtStatus;
+}
+/******************************************************************************
+ *function:  This function initialize BB&RF
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ *  notice:  Initialization value may change all the time, so please make
+ *           sure it has been synced with the newest.
+ * ***************************************************************************/
+RT_STATUS rtl8192_BBConfig(struct net_device* dev)
+{
+	RT_STATUS	rtStatus = RT_STATUS_SUCCESS;
+	rtl8192_InitBBRFRegDef(dev);
+	//config BB&RF. As hardCode based initialization has not been well
+	//implemented, so use file first.FIXME:should implement it for hardcode?
+	rtStatus = rtl8192_BB_Config_ParaFile(dev);
+	return rtStatus;
+}
+
+/******************************************************************************
+ *function:  This function obtains the initialization value of Tx power Level offset
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ * ***************************************************************************/
+void rtl8192_phy_getTxPower(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#ifdef RTL8190P
+	priv->MCSTxPowerLevelOriginalOffset[0] =
+		read_nic_dword(dev, MCS_TXAGC);
+	priv->MCSTxPowerLevelOriginalOffset[1] =
+		read_nic_dword(dev, (MCS_TXAGC+4));
+	priv->CCKTxPowerLevelOriginalOffset =
+		read_nic_dword(dev, CCK_TXAGC);
+#else
+	#ifdef RTL8192E
+	priv->MCSTxPowerLevelOriginalOffset[0] =
+		read_nic_dword(dev, rTxAGC_Rate18_06);
+	priv->MCSTxPowerLevelOriginalOffset[1] =
+		read_nic_dword(dev, rTxAGC_Rate54_24);
+	priv->MCSTxPowerLevelOriginalOffset[2] =
+		read_nic_dword(dev, rTxAGC_Mcs03_Mcs00);
+	priv->MCSTxPowerLevelOriginalOffset[3] =
+		read_nic_dword(dev, rTxAGC_Mcs07_Mcs04);
+	priv->MCSTxPowerLevelOriginalOffset[4] =
+		read_nic_dword(dev, rTxAGC_Mcs11_Mcs08);
+	priv->MCSTxPowerLevelOriginalOffset[5] =
+		read_nic_dword(dev, rTxAGC_Mcs15_Mcs12);
+	#endif
+#endif
+
+	// read rx initial gain
+	priv->DefaultInitialGain[0] = read_nic_byte(dev, rOFDM0_XAAGCCore1);
+	priv->DefaultInitialGain[1] = read_nic_byte(dev, rOFDM0_XBAGCCore1);
+	priv->DefaultInitialGain[2] = read_nic_byte(dev, rOFDM0_XCAGCCore1);
+	priv->DefaultInitialGain[3] = read_nic_byte(dev, rOFDM0_XDAGCCore1);
+	RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n",
+		priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
+		priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
+
+	// read framesync
+	priv->framesync = read_nic_byte(dev, rOFDM0_RxDetector3);
+	priv->framesyncC34 = read_nic_dword(dev, rOFDM0_RxDetector2);
+	RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n",
+		rOFDM0_RxDetector3, priv->framesync);
+	// read SIFS (save the value read fome MACPHY_REG.txt)
+	priv->SifsTime = read_nic_word(dev, SIFS);
+	return;
+}
+
+/******************************************************************************
+ *function:  This function obtains the initialization value of Tx power Level offset
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  none
+ * ***************************************************************************/
+void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8	powerlevel = 0,powerlevelOFDM24G = 0;
+	char ant_pwr_diff;
+	u32	u4RegValue;
+
+	if(priv->epromtype == EPROM_93c46)
+	{
+		powerlevel = priv->TxPowerLevelCCK[channel-1];
+		powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
+	}
+	else if(priv->epromtype == EPROM_93c56)
+	{
+		if(priv->rf_type == RF_1T2R)
+		{
+			powerlevel = priv->TxPowerLevelCCK_C[channel-1];
+			powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_C[channel-1];
+		}
+		else if(priv->rf_type == RF_2T4R)
+		{
+			// Mainly we use RF-A Tx Power to write the Tx Power registers, but the RF-C Tx
+			// Power must be calculated by the antenna diff.
+			// So we have to rewrite Antenna gain offset register here.
+			powerlevel = priv->TxPowerLevelCCK_A[channel-1];
+			powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_A[channel-1];
+
+			ant_pwr_diff = priv->TxPowerLevelOFDM24G_C[channel-1]
+						-priv->TxPowerLevelOFDM24G_A[channel-1];
+			ant_pwr_diff &= 0xf;
+			//DbgPrint(" ant_pwr_diff = 0x%x", (u8)(ant_pwr_diff));
+			priv->RF_C_TxPwDiff = ant_pwr_diff;
+
+			priv->AntennaTxPwDiff[2] = 0;// RF-D, don't care
+			priv->AntennaTxPwDiff[1] = (u8)(ant_pwr_diff);// RF-C
+			priv->AntennaTxPwDiff[0] = 0;// RF-B, don't care
+
+			// Antenna gain offset from B/C/D to A
+			u4RegValue = (  priv->AntennaTxPwDiff[2]<<8 |
+						priv->AntennaTxPwDiff[1]<<4 |
+						priv->AntennaTxPwDiff[0]);
+
+			rtl8192_setBBreg(dev, rFPGA0_TxGainStage,
+			(bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue);
+		}
+	}
+#ifdef TODO
+	//
+	// CCX 2 S31, AP control of client transmit power:
+	// 1. We shall not exceed Cell Power Limit as possible as we can.
+	// 2. Tolerance is +/- 5dB.
+	// 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit.
+	//
+	// TODO:
+	// 1. 802.11h power contraint
+	//
+	// 071011, by rcnjko.
+	//
+	if(	pMgntInfo->OpMode == RT_OP_MODE_INFRASTRUCTURE &&
+		pMgntInfo->bWithCcxCellPwr &&
+		channel == pMgntInfo->dot11CurrentChannelNumber)
+	{
+		u8	CckCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_B, pMgntInfo->CcxCellPwr);
+		u8	LegacyOfdmCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_G, pMgntInfo->CcxCellPwr);
+		u8	OfdmCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_N_24G, pMgntInfo->CcxCellPwr);
+
+		RT_TRACE(COMP_TXAGC, DBG_LOUD,
+			("CCX Cell Limit: %d dbm => CCK Tx power index : %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n",
+			pMgntInfo->CcxCellPwr, CckCellPwrIdx, LegacyOfdmCellPwrIdx, OfdmCellPwrIdx));
+		RT_TRACE(COMP_TXAGC, DBG_LOUD,
+			("EEPROM channel(%d) => CCK Tx power index: %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n",
+			channel, powerlevel, powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff, powerlevelOFDM24G));
+
+		// CCK
+		if(powerlevel > CckCellPwrIdx)
+			powerlevel = CckCellPwrIdx;
+		// Legacy OFDM, HT OFDM
+		if(powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff > OfdmCellPwrIdx)
+		{
+			if((OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff) > 0)
+			{
+				powerlevelOFDM24G = OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff;
+			}
+			else
+			{
+				LegacyOfdmCellPwrIdx = 0;
+			}
+		}
+
+		RT_TRACE(COMP_TXAGC, DBG_LOUD,
+			("Altered CCK Tx power index : %d, Legacy OFDM Tx power index: %d, OFDM Tx power index: %d\n",
+			powerlevel, powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff, powerlevelOFDM24G));
+	}
+
+	pHalData->CurrentCckTxPwrIdx = powerlevel;
+	pHalData->CurrentOfdm24GTxPwrIdx = powerlevelOFDM24G;
+#endif
+	switch(priv->rf_chip)
+	{
+	case RF_8225:
+	//	PHY_SetRF8225CckTxPower(Adapter, powerlevel);
+	//	PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G);
+		break;
+	case RF_8256:
+		PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement
+		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
+		break;
+	case RF_8258:
+		break;
+	default:
+		RT_TRACE(COMP_ERR, "unknown rf chip in funtion %s()\n", __FUNCTION__);
+		break;
+	}
+	return;
+}
+
+/******************************************************************************
+ *function:  This function check Rf chip to do RF config
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  only 8256 is supported
+ * ***************************************************************************/
+RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_STATUS rtStatus = RT_STATUS_SUCCESS;
+	switch(priv->rf_chip)
+	{
+		case RF_8225:
+//			rtStatus = PHY_RF8225_Config(Adapter);
+			break;
+		case RF_8256:
+			rtStatus = PHY_RF8256_Config(dev);
+			break;
+
+		case RF_8258:
+			break;
+		case RF_PSEUDO_11N:
+		//rtStatus = PHY_RF8225_Config(Adapter);
+		break;
+
+		default:
+			RT_TRACE(COMP_ERR, "error chip id\n");
+			break;
+	}
+	return rtStatus;
+}
+
+/******************************************************************************
+ *function:  This function update Initial gain
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  As Windows has not implemented this, wait for complement
+ * ***************************************************************************/
+void rtl8192_phy_updateInitGain(struct net_device* dev)
+{
+	return;
+}
+
+/******************************************************************************
+ *function:  This function read RF parameters from general head file, and do RF 3-wire
+ *   input:  net_device dev
+ *  output:  none
+ *  return:  return code show if RF configuration is successful(0:pass, 1:fail)
+ *    Note:  Delay may be required for RF configuration
+ * ***************************************************************************/
+u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E	eRFPath)
+{
+
+	int i;
+	//u32* pRFArray;
+	u8 ret = 0;
+
+	switch(eRFPath){
+		case RF90_PATH_A:
+			for(i = 0;i<RadioA_ArrayLength; i=i+2){
+
+				if(Rtl819XRadioA_Array[i] == 0xfe){
+						msleep(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioA_Array[i], bMask12Bits, Rtl819XRadioA_Array[i+1]);
+				//msleep(1);
+
+			}
+			break;
+		case RF90_PATH_B:
+			for(i = 0;i<RadioB_ArrayLength; i=i+2){
+
+				if(Rtl819XRadioB_Array[i] == 0xfe){
+						msleep(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioB_Array[i], bMask12Bits, Rtl819XRadioB_Array[i+1]);
+				//msleep(1);
+
+			}
+			break;
+		case RF90_PATH_C:
+			for(i = 0;i<RadioC_ArrayLength; i=i+2){
+
+				if(Rtl819XRadioC_Array[i] == 0xfe){
+						msleep(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioC_Array[i], bMask12Bits, Rtl819XRadioC_Array[i+1]);
+				//msleep(1);
+
+			}
+			break;
+		case RF90_PATH_D:
+			for(i = 0;i<RadioD_ArrayLength; i=i+2){
+
+				if(Rtl819XRadioD_Array[i] == 0xfe){
+						msleep(100);
+						continue;
+				}
+				rtl8192_phy_SetRFReg(dev, eRFPath, Rtl819XRadioD_Array[i], bMask12Bits, Rtl819XRadioD_Array[i+1]);
+				//msleep(1);
+
+			}
+			break;
+		default:
+			break;
+	}
+
+	return ret;;
+
+}
+/******************************************************************************
+ *function:  This function set Tx Power of the channel
+ *   input:  struct net_device *dev
+ *   	     u8 		channel
+ *  output:  none
+ *  return:  none
+ *    Note:
+ * ***************************************************************************/
+static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8	powerlevel = priv->TxPowerLevelCCK[channel-1];
+	u8	powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
+
+	switch(priv->rf_chip)
+	{
+	case RF_8225:
+#ifdef TO_DO_LIST
+		PHY_SetRF8225CckTxPower(Adapter, powerlevel);
+		PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G);
+#endif
+		break;
+
+	case RF_8256:
+		PHY_SetRF8256CCKTxPower(dev, powerlevel);
+		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
+		break;
+
+	case RF_8258:
+		break;
+	default:
+		RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n");
+		break;
+	}
+	return;
+}
+/****************************************************************************************
+ *function:  This function set command table variable(struct SwChnlCmd).
+ *   input:  SwChnlCmd*		CmdTable 	//table to be set.
+ *   	     u32		CmdTableIdx 	//variable index in table to be set
+ *   	     u32		CmdTableSz	//table size.
+ *   	     SwChnlCmdID	CmdID		//command ID to set.
+ *	     u32		Para1
+ *	     u32		Para2
+ *	     u32		msDelay
+ *  output:
+ *  return:  true if finished, false otherwise
+ *    Note:
+ * ************************************************************************************/
+static u8 rtl8192_phy_SetSwChnlCmdArray(
+	SwChnlCmd*		CmdTable,
+	u32			CmdTableIdx,
+	u32			CmdTableSz,
+	SwChnlCmdID		CmdID,
+	u32			Para1,
+	u32			Para2,
+	u32			msDelay
+	)
+{
+	SwChnlCmd* pCmd;
+
+	if(CmdTable == NULL)
+	{
+		RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n");
+		return false;
+	}
+	if(CmdTableIdx >= CmdTableSz)
+	{
+		RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
+				CmdTableIdx, CmdTableSz);
+		return false;
+	}
+
+	pCmd = CmdTable + CmdTableIdx;
+	pCmd->CmdID = CmdID;
+	pCmd->Para1 = Para1;
+	pCmd->Para2 = Para2;
+	pCmd->msDelay = msDelay;
+
+	return true;
+}
+/******************************************************************************
+ *function:  This function set channel step by step
+ *   input:  struct net_device *dev
+ *   	     u8 		channel
+ *   	     u8* 		stage //3 stages
+ *   	     u8* 		step  //
+ *   	     u32* 		delay //whether need to delay
+ *  output:  store new stage, step and delay for next step(combine with function above)
+ *  return:  true if finished, false otherwise
+ *    Note:  Wait for simpler function to replace it //wb
+ * ***************************************************************************/
+static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u8* step, u32* delay)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+//	PCHANNEL_ACCESS_SETTING	pChnlAccessSetting;
+	SwChnlCmd				PreCommonCmd[MAX_PRECMD_CNT];
+	u32					PreCommonCmdCnt;
+	SwChnlCmd				PostCommonCmd[MAX_POSTCMD_CNT];
+	u32					PostCommonCmdCnt;
+	SwChnlCmd				RfDependCmd[MAX_RFDEPENDCMD_CNT];
+	u32					RfDependCmdCnt;
+	SwChnlCmd				*CurrentCmd = NULL;
+	//RF90_RADIO_PATH_E		eRFPath;
+	u8		eRFPath;
+//	u32		RfRetVal;
+//	u8		RetryCnt;
+
+	RT_TRACE(COMP_TRACE, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel);
+//	RT_ASSERT(IsLegalChannel(Adapter, channel), ("illegal channel: %d\n", channel));
+
+#ifdef ENABLE_DOT11D
+	if (!IsLegalChannel(priv->ieee80211, channel))
+	{
+		RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
+		return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
+	}
+#endif
+
+	//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
+	//for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
+	{
+		//if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
+		//	return false;
+		// <1> Fill up pre common command.
+		PreCommonCmdCnt = 0;
+		rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
+					CmdID_SetTxPowerLevel, 0, 0, 0);
+		rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
+					CmdID_End, 0, 0, 0);
+
+		// <2> Fill up post common command.
+		PostCommonCmdCnt = 0;
+
+		rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT,
+					CmdID_End, 0, 0, 0);
+
+		// <3> Fill up RF dependent command.
+		RfDependCmdCnt = 0;
+		switch( priv->rf_chip )
+		{
+		case RF_8225:
+			if (!(channel >= 1 && channel <= 14))
+			{
+				RT_TRACE(COMP_ERR, "illegal channel for Zebra 8225: %d\n", channel);
+				return false;
+			}
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+				CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10);
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+				CmdID_End, 0, 0, 0);
+			break;
+
+		case RF_8256:
+			// TEST!! This is not the table for 8256!!
+			if (!(channel >= 1 && channel <= 14))
+			{
+				RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel);
+				return false;
+			}
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+				CmdID_RF_WriteReg, rZebra1_Channel, channel, 10);
+			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
+			CmdID_End, 0, 0, 0);
+			break;
+
+		case RF_8258:
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
+			return false;
+			break;
+		}
+
+
+		do{
+			switch(*stage)
+			{
+			case 0:
+				CurrentCmd=&PreCommonCmd[*step];
+				break;
+			case 1:
+				CurrentCmd=&RfDependCmd[*step];
+				break;
+			case 2:
+				CurrentCmd=&PostCommonCmd[*step];
+				break;
+			}
+
+			if(CurrentCmd->CmdID==CmdID_End)
+			{
+				if((*stage)==2)
+				{
+					return true;
+				}
+				else
+				{
+					(*stage)++;
+					(*step)=0;
+					continue;
+				}
+			}
+
+			switch(CurrentCmd->CmdID)
+			{
+			case CmdID_SetTxPowerLevel:
+				if(priv->card_8192_version > (u8)VERSION_8190_BD) //xiong: consider it later!
+					rtl8192_SetTxPowerLevel(dev,channel);
+				break;
+			case CmdID_WritePortUlong:
+				write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2);
+				break;
+			case CmdID_WritePortUshort:
+				write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2);
+				break;
+			case CmdID_WritePortUchar:
+				write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2);
+				break;
+			case CmdID_RF_WriteReg:
+				for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
+					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bMask12Bits, CurrentCmd->Para2<<7);
+				break;
+			default:
+				break;
+			}
+
+			break;
+		}while(true);
+	}/*for(Number of RF paths)*/
+
+	(*delay)=CurrentCmd->msDelay;
+	(*step)++;
+	return false;
+}
+
+/******************************************************************************
+ *function:  This function does acturally set channel work
+ *   input:  struct net_device *dev
+ *   	     u8 		channel
+ *  output:  none
+ *  return:  noin
+ *    Note:  We should not call this function directly
+ * ***************************************************************************/
+static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32	delay = 0;
+
+	while(!rtl8192_phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay))
+	{
+		if(delay>0)
+			msleep(delay);//or mdelay? need further consideration
+                if(!priv->up)
+		        break;
+	}
+}
+/******************************************************************************
+ *function:  Callback routine of the work item for switch channel.
+ *   input:
+ *
+ *  output:  none
+ *  return:  noin
+ * ***************************************************************************/
+void rtl8192_SwChnl_WorkItem(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	RT_TRACE(COMP_TRACE, "==> SwChnlCallback819xUsbWorkItem()\n");
+
+	RT_TRACE(COMP_TRACE, "=====>--%s(), set chan:%d, priv:%p\n", __FUNCTION__, priv->chan, priv);
+
+	rtl8192_phy_FinishSwChnlNow(dev , priv->chan);
+
+	RT_TRACE(COMP_TRACE, "<== SwChnlCallback819xUsbWorkItem()\n");
+}
+
+/******************************************************************************
+ *function:  This function scheduled actural workitem to set channel
+ *   input:  net_device dev
+ *   	     u8		channel //channel to set
+ *  output:  none
+ *  return:  return code show if workitem is scheduled(1:pass, 0:fail)
+ *    Note:  Delay may be required for RF configuration
+ * ***************************************************************************/
+u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	RT_TRACE(COMP_PHY, "=====>%s()\n", __FUNCTION__);
+        if(!priv->up)
+		return false;
+	if(priv->SwChnlInProgress)
+		return false;
+
+//	if(pHalData->SetBWModeInProgress)
+//		return;
+
+	//--------------------------------------------
+	switch(priv->ieee80211->mode)
+	{
+	case WIRELESS_MODE_A:
+	case WIRELESS_MODE_N_5G:
+		if (channel<=14){
+			RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14");
+			return false;
+		}
+		break;
+	case WIRELESS_MODE_B:
+		if (channel>14){
+			RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14");
+			return false;
+		}
+		break;
+	case WIRELESS_MODE_G:
+	case WIRELESS_MODE_N_24G:
+		if (channel>14){
+			RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14");
+			return false;
+		}
+		break;
+	}
+	//--------------------------------------------
+
+	priv->SwChnlInProgress = true;
+	if(channel == 0)
+		channel = 1;
+
+	priv->chan=channel;
+
+	priv->SwChnlStage=0;
+	priv->SwChnlStep=0;
+//	schedule_work(&(priv->SwChnlWorkItem));
+//	rtl8192_SwChnl_WorkItem(dev);
+	if(priv->up) {
+//		queue_work(priv->priv_wq,&(priv->SwChnlWorkItem));
+	rtl8192_SwChnl_WorkItem(dev);
+	}
+        priv->SwChnlInProgress = false;
+	return true;
+}
+
+static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct net_device *dev	)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	switch(priv->CurrentChannelBW)
+	{
+		/* 20 MHz channel*/
+		case HT_CHANNEL_WIDTH_20:
+	//added by vivi, cck,tx power track, 20080703
+			priv->CCKPresentAttentuation =
+				priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference;
+
+			if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
+				priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
+			if(priv->CCKPresentAttentuation < 0)
+				priv->CCKPresentAttentuation = 0;
+
+			RT_TRACE(COMP_POWER_TRACKING, "20M, priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
+
+			if(priv->ieee80211->current_network.channel== 14 && !priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = TRUE;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = FALSE;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+		break;
+
+		/* 40 MHz channel*/
+		case HT_CHANNEL_WIDTH_20_40:
+			//added by vivi, cck,tx power track, 20080703
+			priv->CCKPresentAttentuation =
+				priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference;
+
+			RT_TRACE(COMP_POWER_TRACKING, "40M, priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
+			if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
+				priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
+			if(priv->CCKPresentAttentuation < 0)
+				priv->CCKPresentAttentuation = 0;
+
+			if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = TRUE;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
+			{
+				priv->bcck_in_ch14 = FALSE;
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+			}
+			else
+				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
+		break;
+	}
+}
+
+#ifndef RTL8190P
+static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct net_device *dev)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+	if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
+		priv->bcck_in_ch14 = TRUE;
+	else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
+		priv->bcck_in_ch14 = FALSE;
+
+	//write to default index and tx power track will be done in dm.
+	switch(priv->CurrentChannelBW)
+	{
+		/* 20 MHz channel*/
+		case HT_CHANNEL_WIDTH_20:
+			if(priv->Record_CCK_20Mindex == 0)
+				priv->Record_CCK_20Mindex = 6;	//set default value.
+			priv->CCK_index = priv->Record_CCK_20Mindex;//6;
+			RT_TRACE(COMP_POWER_TRACKING, "20MHz, CCK_Tx_Power_Track_BW_Switch_ThermalMeter(),CCK_index = %d\n", priv->CCK_index);
+		break;
+
+		/* 40 MHz channel*/
+		case HT_CHANNEL_WIDTH_20_40:
+			priv->CCK_index = priv->Record_CCK_40Mindex;//0;
+			RT_TRACE(COMP_POWER_TRACKING, "40MHz, CCK_Tx_Power_Track_BW_Switch_ThermalMeter(), CCK_index = %d\n", priv->CCK_index);
+		break;
+	}
+	dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
+}
+#endif
+
+static void CCK_Tx_Power_Track_BW_Switch(struct net_device *dev)
+{
+#ifdef RTL8192E
+	struct r8192_priv *priv = ieee80211_priv(dev);
+#endif
+
+#ifdef RTL8190P
+	CCK_Tx_Power_Track_BW_Switch_TSSI(dev);
+#else
+	//if(pHalData->bDcut == TRUE)
+	if(priv->IC_Cut >= IC_VersionCut_D)
+		CCK_Tx_Power_Track_BW_Switch_TSSI(dev);
+	else
+		CCK_Tx_Power_Track_BW_Switch_ThermalMeter(dev);
+#endif
+}
+
+
+//
+/******************************************************************************
+ *function:  Callback routine of the work item for set bandwidth mode.
+ *   input:  struct net_device *dev
+ *   	     HT_CHANNEL_WIDTH	Bandwidth  //20M or 40M
+ *   	     HT_EXTCHNL_OFFSET Offset 	   //Upper, Lower, or Don't care
+ *  output:  none
+ *  return:  none
+ *    Note:  I doubt whether SetBWModeInProgress flag is necessary as we can
+ *    	     test whether current work in the queue or not.//do I?
+ * ***************************************************************************/
+void rtl8192_SetBWModeWorkItem(struct net_device *dev)
+{
+
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u8 regBwOpMode;
+
+	RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem()  Switch to %s bandwidth\n", \
+					priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz")
+
+
+	if(priv->rf_chip== RF_PSEUDO_11N)
+	{
+		priv->SetBWModeInProgress= false;
+		return;
+	}
+	if(!priv->up)
+	{
+		priv->SetBWModeInProgress= false;
+		return;
+	}
+	//<1>Set MAC register
+	regBwOpMode = read_nic_byte(dev, BW_OPMODE);
+
+	switch(priv->CurrentChannelBW)
+	{
+		case HT_CHANNEL_WIDTH_20:
+			regBwOpMode |= BW_OPMODE_20MHZ;
+		       // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
+			write_nic_byte(dev, BW_OPMODE, regBwOpMode);
+			break;
+
+		case HT_CHANNEL_WIDTH_20_40:
+			regBwOpMode &= ~BW_OPMODE_20MHZ;
+        		// 2007/02/07 Mark by Emily becasue we have not verify whether this register works
+			write_nic_byte(dev, BW_OPMODE, regBwOpMode);
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
+			break;
+	}
+
+	//<2>Set PHY related register
+	switch(priv->CurrentChannelBW)
+	{
+		case HT_CHANNEL_WIDTH_20:
+			// Add by Vivi 20071119
+			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
+			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
+//			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
+
+			// Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207
+//			write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000);
+//			write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317);
+//			write_nic_dword(dev, rCCK0_DebugPort, 0x00000204);
+			if(!priv->btxpower_tracking)
+			{
+				write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000);
+				write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317);
+				write_nic_dword(dev, rCCK0_DebugPort, 0x00000204);
+			}
+			else
+				CCK_Tx_Power_Track_BW_Switch(dev);
+
+#ifdef RTL8190P
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 1);
+			rtl8192_setBBreg(dev, rOFDM0_RxDetector1, bMaskByte0, 0x44); 	// 0xc30 is for 8190 only, Emily
+#else
+	#ifdef RTL8192E
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
+	#endif
+#endif
+
+			break;
+		case HT_CHANNEL_WIDTH_20_40:
+			// Add by Vivi 20071119
+			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
+			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
+			//rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
+                    //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
+			//rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
+
+			// Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207
+			//write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000);
+			//write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e);
+			//write_nic_dword(dev, rCCK0_DebugPort, 0x00000409);
+			if(!priv->btxpower_tracking)
+			{
+				write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000);
+				write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e);
+				write_nic_dword(dev, rCCK0_DebugPort, 0x00000409);
+			}
+			else
+				CCK_Tx_Power_Track_BW_Switch(dev);
+
+			// Set Control channel to upper or lower. These settings are required only for 40MHz
+			rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
+			rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
+
+
+#ifdef RTL8190P
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 0);
+			rtl8192_setBBreg(dev, rOFDM0_RxDetector1, bMaskByte0, 0x42);	// 0xc30 is for 8190 only, Emily
+
+			// Set whether CCK should be sent in upper or lower channel. Suggest by YN. 20071207
+			// It is set in Tx descriptor for 8192x series
+			if(priv->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
+			{
+				rtl8192_setBBreg(dev, rFPGA0_RFMOD, (BIT6|BIT5), 0x01);
+			}else if(priv->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
+			{
+				rtl8192_setBBreg(dev, rFPGA0_RFMOD, (BIT6|BIT5), 0x02);
+			}
+
+#else
+	#ifdef RTL8192E
+			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
+	#endif
+#endif
+			break;
+		default:
+			RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW);
+			break;
+
+	}
+	//Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
+
+#if 1
+	//<3>Set RF related register
+	switch( priv->rf_chip )
+	{
+		case RF_8225:
+#ifdef TO_DO_LIST
+			PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW);
+#endif
+			break;
+
+		case RF_8256:
+			PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
+			break;
+
+		case RF_8258:
+			// PHY_SetRF8258Bandwidth();
+			break;
+
+		case RF_PSEUDO_11N:
+			// Do Nothing
+			break;
+
+		default:
+			RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
+			break;
+	}
+#endif
+	atomic_dec(&(priv->ieee80211->atm_swbw));
+	priv->SetBWModeInProgress= false;
+
+	RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb()");
+}
+
+/******************************************************************************
+ *function:  This function schedules bandwith switch work.
+ *   input:  struct net_device *dev
+ *   	     HT_CHANNEL_WIDTH	Bandwidth  //20M or 40M
+ *   	     HT_EXTCHNL_OFFSET Offset 	   //Upper, Lower, or Don't care
+ *  output:  none
+ *  return:  none
+ *    Note:  I doubt whether SetBWModeInProgress flag is necessary as we can
+ *    	     test whether current work in the queue or not.//do I?
+ * ***************************************************************************/
+void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET Offset)
+{
+	struct r8192_priv *priv = ieee80211_priv(dev);
+
+
+	if(priv->SetBWModeInProgress)
+		return;
+
+	 atomic_inc(&(priv->ieee80211->atm_swbw));
+	priv->SetBWModeInProgress= true;
+
+	priv->CurrentChannelBW = Bandwidth;
+
+	if(Offset==HT_EXTCHNL_OFFSET_LOWER)
+		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
+	else if(Offset==HT_EXTCHNL_OFFSET_UPPER)
+		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
+	else
+		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+
+	//queue_work(priv->priv_wq, &(priv->SetBWModeWorkItem));
+	//	schedule_work(&(priv->SetBWModeWorkItem));
+	rtl8192_SetBWModeWorkItem(dev);
+
+}
+
+
+void InitialGain819xPci(struct net_device *dev, u8 Operation)
+{
+#define SCAN_RX_INITIAL_GAIN	0x17
+#define POWER_DETECTION_TH	0x08
+	struct r8192_priv *priv = ieee80211_priv(dev);
+	u32					BitMask;
+	u8					initial_gain;
+
+	if(priv->up)
+	{
+		switch(Operation)
+		{
+			case IG_Backup:
+			RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
+				initial_gain = SCAN_RX_INITIAL_GAIN;//pHalData->DefaultInitialGain[0];//
+				BitMask = bMaskByte0;
+				if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+					rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
+				priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask);
+				priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask);
+				priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask);
+				priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask);
+				BitMask  = bMaskByte2;
+				priv->initgain_backup.cca		= (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask);
+
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
+
+			RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain);
+				write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
+				write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
+				write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
+				write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
+				RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH);
+				write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
+				break;
+			case IG_Restore:
+			RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
+				BitMask = 0x7f; //Bit0~ Bit6
+				if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+					rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
+
+				rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1);
+				rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1);
+				rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1);
+				rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1);
+				BitMask  = bMaskByte2;
+				rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca);
+
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
+			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
+
+				rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
+
+
+				if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
+					rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// FW DIG ON
+				break;
+			default:
+			RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n");
+				break;
+		}
+	}
+}
+
diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h
new file mode 100644
index 0000000..fa77abe
--- /dev/null
+++ b/drivers/staging/rtl8192e/r819xE_phy.h
@@ -0,0 +1,125 @@
+#ifndef _R819XU_PHY_H
+#define _R819XU_PHY_H
+/* Channel switch:The size of command tables for switch channel*/
+#define MAX_PRECMD_CNT 16
+#define MAX_RFDEPENDCMD_CNT 16
+#define MAX_POSTCMD_CNT 16
+
+#ifdef RTL8190P
+#define MACPHY_Array_PGLength 21
+#define Rtl819XMACPHY_Array_PG			Rtl8190PciMACPHY_Array_PG
+#define Rtl819XMACPHY_Array				Rtl8190PciMACPHY_Array
+#define RadioC_ArrayLength 246
+#define RadioD_ArrayLength 78
+#define Rtl819XRadioA_Array					Rtl8190PciRadioA_Array
+#define Rtl819XRadioB_Array					Rtl8190PciRadioB_Array
+#define Rtl819XRadioC_Array					Rtl8190PciRadioC_Array
+#define Rtl819XRadioD_Array					Rtl8190PciRadioD_Array
+#define Rtl819XAGCTAB_Array				Rtl8190PciAGCTAB_Array
+#define PHY_REGArrayLength 				280
+#define Rtl819XPHY_REGArray				Rtl8190PciPHY_REGArray
+#define PHY_REG_1T2RArrayLength 		280
+#define Rtl819XPHY_REG_1T2RArray		Rtl8190PciPHY_REG_1T2RArray
+#endif
+
+	#ifdef RTL8192E
+	#define MACPHY_Array_PGLength 30
+	#define Rtl819XMACPHY_Array_PG			Rtl8192PciEMACPHY_Array_PG
+	#define Rtl819XMACPHY_Array				Rtl8192PciEMACPHY_Array
+	#define RadioC_ArrayLength 1
+	#define RadioD_ArrayLength 1
+	#define Rtl819XRadioA_Array					Rtl8192PciERadioA_Array
+	#define Rtl819XRadioB_Array					Rtl8192PciERadioB_Array
+	#define Rtl819XRadioC_Array					Rtl8192PciERadioC_Array
+	#define Rtl819XRadioD_Array					Rtl8192PciERadioD_Array
+	#define Rtl819XAGCTAB_Array				Rtl8192PciEAGCTAB_Array
+	#define PHY_REGArrayLength 				1
+	#define Rtl819XPHY_REGArray				Rtl8192PciEPHY_REGArray
+	#define PHY_REG_1T2RArrayLength 		296
+	#define Rtl819XPHY_REG_1T2RArray		Rtl8192PciEPHY_REG_1T2RArray
+	#endif
+#define AGCTAB_ArrayLength 384
+#define MACPHY_ArrayLength 18
+
+#define RadioA_ArrayLength 246
+#define RadioB_ArrayLength 78
+
+
+typedef enum _SwChnlCmdID{
+	CmdID_End,
+	CmdID_SetTxPowerLevel,
+	CmdID_BBRegWrite10,
+	CmdID_WritePortUlong,
+	CmdID_WritePortUshort,
+	CmdID_WritePortUchar,
+	CmdID_RF_WriteReg,
+}SwChnlCmdID;
+
+/*--------------------------------Define structure--------------------------------*/
+/* 1. Switch channel related */
+typedef struct _SwChnlCmd{
+	SwChnlCmdID	CmdID;
+	u32			Para1;
+	u32			Para2;
+	u32			msDelay;
+}__attribute__ ((packed)) SwChnlCmd;
+
+extern u32 rtl819XMACPHY_Array_PG[];
+extern u32 rtl819XPHY_REG_1T2RArray[];
+extern u32 rtl819XAGCTAB_Array[];
+extern u32 rtl819XRadioA_Array[];
+extern u32 rtl819XRadioB_Array[];
+extern u32 rtl819XRadioC_Array[];
+extern u32 rtl819XRadioD_Array[];
+
+typedef enum _HW90_BLOCK{
+	HW90_BLOCK_MAC = 0,
+	HW90_BLOCK_PHY0 = 1,
+	HW90_BLOCK_PHY1 = 2,
+	HW90_BLOCK_RF = 3,
+	HW90_BLOCK_MAXIMUM = 4, // Never use this
+}HW90_BLOCK_E, *PHW90_BLOCK_E;
+
+typedef enum _RF90_RADIO_PATH{
+	RF90_PATH_A = 0,			//Radio Path A
+	RF90_PATH_B = 1,			//Radio Path B
+	RF90_PATH_C = 2,			//Radio Path C
+	RF90_PATH_D = 3,			//Radio Path D
+	RF90_PATH_MAX				//Max RF number 92 support
+}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
+
+#define bMaskByte0                0xff
+#define bMaskByte1                0xff00
+#define bMaskByte2                0xff0000
+#define bMaskByte3                0xff000000
+#define bMaskHWord                0xffff0000
+#define bMaskLWord                0x0000ffff
+#define bMaskDWord                0xffffffff
+
+//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
+extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath);
+extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData);
+extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask);
+//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset);
+//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
+extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data);
+extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
+extern void rtl8192_phy_configmac(struct net_device* dev);
+extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType);
+//extern void rtl8192_InitBBRFRegDef(struct net_device* dev);
+extern RT_STATUS rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
+//extern RT_STATUS rtl8192_BB_Config_ParaFile(struct net_device* dev);
+extern RT_STATUS rtl8192_BBConfig(struct net_device* dev);
+extern void rtl8192_phy_getTxPower(struct net_device* dev);
+extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel);
+extern RT_STATUS rtl8192_phy_RFConfig(struct net_device* dev);
+extern void rtl8192_phy_updateInitGain(struct net_device* dev);
+extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E	eRFPath);
+
+extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel);
+extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET Offset);
+extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
+extern void rtl8192_SetBWModeWorkItem(struct net_device *dev);
+extern void InitialGain819xPci(struct net_device *dev, u8 Operation);
+
+#endif
diff --git a/drivers/staging/rtl8192e/r819xE_phyreg.h b/drivers/staging/rtl8192e/r819xE_phyreg.h
new file mode 100644
index 0000000..d4a4392
--- /dev/null
+++ b/drivers/staging/rtl8192e/r819xE_phyreg.h
@@ -0,0 +1,878 @@
+#ifndef _R819XU_PHYREG_H
+#define _R819XU_PHYREG_H
+
+
+#define   RF_DATA				0x1d4					// FW will write RF data in the register.
+
+//Register   //duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF
+//page 1
+#define rPMAC_Reset               		0x100
+#define rPMAC_TxStart             		0x104
+#define rPMAC_TxLegacySIG         		0x108
+#define rPMAC_TxHTSIG1            		0x10c
+#define rPMAC_TxHTSIG2            		0x110
+#define rPMAC_PHYDebug            		0x114
+#define rPMAC_TxPacketNum         		0x118
+#define rPMAC_TxIdle              		0x11c
+#define rPMAC_TxMACHeader0       	0x120
+#define rPMAC_TxMACHeader1       	0x124
+#define rPMAC_TxMACHeader2       	0x128
+#define rPMAC_TxMACHeader3       	0x12c
+#define rPMAC_TxMACHeader4       	0x130
+#define rPMAC_TxMACHeader5       	0x134
+#define rPMAC_TxDataType          		0x138
+#define rPMAC_TxRandomSeed      		0x13c
+#define rPMAC_CCKPLCPPreamble  		0x140
+#define rPMAC_CCKPLCPHeader     		0x144
+#define rPMAC_CCKCRC16            		0x148
+#define rPMAC_OFDMRxCRC32OK  		0x170
+#define rPMAC_OFDMRxCRC32Er   		0x174
+#define rPMAC_OFDMRxParityEr    		0x178
+#define rPMAC_OFDMRxCRC8Er     		0x17c
+#define rPMAC_CCKCRxRC16Er       		0x180
+#define rPMAC_CCKCRxRC32Er       		0x184
+#define rPMAC_CCKCRxRC32OK      		0x188
+#define rPMAC_TxStatus            		0x18c
+
+//90P
+#define	MCS_TXAGC				0x340	// MCS AGC
+#define	CCK_TXAGC				0x348	// CCK AGC
+
+//page8
+#define rFPGA0_RFMOD              		0x800  //RF mode & CCK TxSC
+#define rFPGA0_TxInfo             		0x804
+#define rFPGA0_PSDFunction        		0x808
+#define rFPGA0_TxGainStage        		0x80c
+#define rFPGA0_RFTiming1          		0x810
+#define rFPGA0_RFTiming2          		0x814
+//#define rFPGA0_XC_RFTiming        		0x818
+//#define rFPGA0_XD_RFTiming        		0x81c
+#define rFPGA0_XA_HSSIParameter1  	0x820
+#define rFPGA0_XA_HSSIParameter2  	0x824
+#define rFPGA0_XB_HSSIParameter1  	0x828
+#define rFPGA0_XB_HSSIParameter2  	0x82c
+#define rFPGA0_XC_HSSIParameter1  	0x830
+#define rFPGA0_XC_HSSIParameter2  	0x834
+#define rFPGA0_XD_HSSIParameter1  	0x838
+#define rFPGA0_XD_HSSIParameter2  	0x83c
+#define rFPGA0_XA_LSSIParameter   	0x840
+#define rFPGA0_XB_LSSIParameter   	0x844
+#define rFPGA0_XC_LSSIParameter   	0x848
+#define rFPGA0_XD_LSSIParameter   	0x84c
+#define rFPGA0_RFWakeUpParameter  	0x850
+#define rFPGA0_RFSleepUpParameter 	0x854
+#define rFPGA0_XAB_SwitchControl  	0x858
+#define rFPGA0_XCD_SwitchControl  	0x85c
+#define rFPGA0_XA_RFInterfaceOE   	0x860
+#define rFPGA0_XB_RFInterfaceOE   	0x864
+#define rFPGA0_XC_RFInterfaceOE   	0x868
+#define rFPGA0_XD_RFInterfaceOE   	0x86c
+#define rFPGA0_XAB_RFInterfaceSW  	0x870
+#define rFPGA0_XCD_RFInterfaceSW  	0x874
+#define rFPGA0_XAB_RFParameter    	0x878
+#define rFPGA0_XCD_RFParameter    	0x87c
+#define rFPGA0_AnalogParameter1   	0x880
+#define rFPGA0_AnalogParameter2   	0x884
+#define rFPGA0_AnalogParameter3   	0x888
+#define rFPGA0_AnalogParameter4   	0x88c
+#define rFPGA0_XA_LSSIReadBack    	0x8a0
+#define rFPGA0_XB_LSSIReadBack    	0x8a4
+#define rFPGA0_XC_LSSIReadBack    	0x8a8
+#define rFPGA0_XD_LSSIReadBack    	0x8ac
+#define rFPGA0_PSDReport          		0x8b4
+#define rFPGA0_XAB_RFInterfaceRB  	0x8e0
+#define rFPGA0_XCD_RFInterfaceRB  	0x8e4
+
+//page 9
+#define rFPGA1_RFMOD              		0x900  //RF mode & OFDM TxSC
+#define rFPGA1_TxBlock            		0x904
+#define rFPGA1_DebugSelect        		0x908
+#define rFPGA1_TxInfo             		0x90c
+
+//page a
+#define rCCK0_System              		0xa00
+#define rCCK0_AFESetting          		0xa04
+#define rCCK0_CCA                 			0xa08
+#define rCCK0_RxAGC1              		0xa0c  //AGC default value, saturation level
+#define rCCK0_RxAGC2              		0xa10  //AGC & DAGC
+#define rCCK0_RxHP                		0xa14
+#define rCCK0_DSPParameter1       	0xa18  //Timing recovery & Channel estimation threshold
+#define rCCK0_DSPParameter2       	0xa1c  //SQ threshold
+#define rCCK0_TxFilter1           		0xa20
+#define rCCK0_TxFilter2           		0xa24
+#define rCCK0_DebugPort           		0xa28  //debug port and Tx filter3
+#define rCCK0_FalseAlarmReport    	0xa2c  //0xa2d
+#define rCCK0_TRSSIReport         		0xa50
+#define rCCK0_RxReport            		0xa54  //0xa57
+#define rCCK0_FACounterLower      	0xa5c  //0xa5b
+#define rCCK0_FACounterUpper      	0xa58  //0xa5c
+
+//page c
+#define rOFDM0_LSTF               		0xc00
+#define rOFDM0_TRxPathEnable      	0xc04
+#define rOFDM0_TRMuxPar           		0xc08
+#define rOFDM0_TRSWIsolation      		0xc0c
+#define rOFDM0_XARxAFE            		0xc10  //RxIQ DC offset, Rx digital filter, DC notch filter
+#define rOFDM0_XARxIQImbalance    	0xc14  //RxIQ imblance matrix
+#define rOFDM0_XBRxAFE            		0xc18
+#define rOFDM0_XBRxIQImbalance    	0xc1c
+#define rOFDM0_XCRxAFE            		0xc20
+#define rOFDM0_XCRxIQImbalance    	0xc24
+#define rOFDM0_XDRxAFE            		0xc28
+#define rOFDM0_XDRxIQImbalance    	0xc2c
+#define rOFDM0_RxDetector1        		0xc30  //PD,BW & SBD
+#define rOFDM0_RxDetector2        		0xc34  //SBD & Fame Sync.
+#define rOFDM0_RxDetector3        		0xc38  //Frame Sync.
+#define rOFDM0_RxDetector4        		0xc3c  //PD, SBD, Frame Sync & Short-GI
+#define rOFDM0_RxDSP              		0xc40  //Rx Sync Path
+#define rOFDM0_CFOandDAGC         	0xc44  //CFO & DAGC
+#define rOFDM0_CCADropThreshold   	0xc48 //CCA Drop threshold
+#define rOFDM0_ECCAThreshold      	0xc4c // energy CCA
+#define rOFDM0_XAAGCCore1         	0xc50
+#define rOFDM0_XAAGCCore2         	0xc54
+#define rOFDM0_XBAGCCore1         	0xc58
+#define rOFDM0_XBAGCCore2         	0xc5c
+#define rOFDM0_XCAGCCore1         	0xc60
+#define rOFDM0_XCAGCCore2         	0xc64
+#define rOFDM0_XDAGCCore1         	0xc68
+#define rOFDM0_XDAGCCore2         	0xc6c
+#define rOFDM0_AGCParameter1      	0xc70
+#define rOFDM0_AGCParameter2      	0xc74
+#define rOFDM0_AGCRSSITable       	0xc78
+#define rOFDM0_HTSTFAGC           		0xc7c
+#define rOFDM0_XATxIQImbalance   	0xc80
+#define rOFDM0_XATxAFE            		0xc84
+#define rOFDM0_XBTxIQImbalance    	0xc88
+#define rOFDM0_XBTxAFE            		0xc8c
+#define rOFDM0_XCTxIQImbalance    	0xc90
+#define rOFDM0_XCTxAFE            		0xc94
+#define rOFDM0_XDTxIQImbalance    	0xc98
+#define rOFDM0_XDTxAFE            		0xc9c
+#define rOFDM0_RxHPParameter      	0xce0
+#define rOFDM0_TxPseudoNoiseWgt   	0xce4
+#define rOFDM0_FrameSync          		0xcf0
+#define rOFDM0_DFSReport          		0xcf4
+#define rOFDM0_TxCoeff1           		0xca4
+#define rOFDM0_TxCoeff2           		0xca8
+#define rOFDM0_TxCoeff3           		0xcac
+#define rOFDM0_TxCoeff4           		0xcb0
+#define rOFDM0_TxCoeff5           		0xcb4
+#define rOFDM0_TxCoeff6           		0xcb8
+
+
+//page d
+#define rOFDM1_LSTF               		0xd00
+#define rOFDM1_TRxPathEnable      	0xd04
+#define rOFDM1_CFO                		0xd08
+#define rOFDM1_CSI1               		0xd10
+#define rOFDM1_SBD                		0xd14
+#define rOFDM1_CSI2               		0xd18
+#define rOFDM1_CFOTracking        		0xd2c
+#define rOFDM1_TRxMesaure1        	0xd34
+#define rOFDM1_IntfDet            		0xd3c
+#define rOFDM1_PseudoNoiseStateAB 0xd50
+#define rOFDM1_PseudoNoiseStateCD 0xd54
+#define rOFDM1_RxPseudoNoiseWgt   0xd58
+#define rOFDM_PHYCounter1         		0xda0  //cca, parity fail
+#define rOFDM_PHYCounter2         		0xda4  //rate illegal, crc8 fail
+#define rOFDM_PHYCounter3         		0xda8  //MCS not support
+#define rOFDM_ShortCFOAB          		0xdac
+#define rOFDM_ShortCFOCD          		0xdb0
+#define rOFDM_LongCFOAB           		0xdb4
+#define rOFDM_LongCFOCD           		0xdb8
+#define rOFDM_TailCFOAB           		0xdbc
+#define rOFDM_TailCFOCD           		0xdc0
+#define rOFDM_PWMeasure1          	0xdc4
+#define rOFDM_PWMeasure2          	0xdc8
+#define rOFDM_BWReport            		0xdcc
+#define rOFDM_AGCReport           		0xdd0
+#define rOFDM_RxSNR               		0xdd4
+#define rOFDM_RxEVMCSI            		0xdd8
+#define rOFDM_SIGReport           		0xddc
+
+//page e
+#define rTxAGC_Rate18_06			0xe00
+#define rTxAGC_Rate54_24			0xe04
+#define rTxAGC_CCK_Mcs32			0xe08
+#define rTxAGC_Mcs03_Mcs00			0xe10
+#define rTxAGC_Mcs07_Mcs04			0xe14
+#define rTxAGC_Mcs11_Mcs08			0xe18
+#define rTxAGC_Mcs15_Mcs12			0xe1c
+
+
+//RF
+//Zebra1
+#define rZebra1_HSSIEnable            	0x0
+#define rZebra1_TRxEnable1            	0x1
+#define rZebra1_TRxEnable2           	0x2
+#define rZebra1_AGC                   		0x4
+#define rZebra1_ChargePump            	0x5
+#define rZebra1_Channel               		0x7
+#define rZebra1_TxGain               	 	0x8
+#define rZebra1_TxLPF                 		0x9
+#define rZebra1_RxLPF                 		0xb
+#define rZebra1_RxHPFCorner           	0xc
+
+//Zebra4
+#define rGlobalCtrl                   		0
+#define rRTL8256_TxLPF                		19
+#define rRTL8256_RxLPF                		11
+
+//RTL8258
+#define rRTL8258_TxLPF                		0x11
+#define rRTL8258_RxLPF                		0x13
+#define rRTL8258_RSSILPF              	0xa
+
+//Bit Mask
+//page-1
+#define bBBResetB                 			0x100
+#define bGlobalResetB             		0x200
+#define bOFDMTxStart              		0x4
+#define bCCKTxStart               			0x8
+#define bCRC32Debug               		0x100
+#define bPMACLoopback             		0x10
+#define bTxLSIG                   			0xffffff
+#define bOFDMTxRate               		0xf
+#define bOFDMTxReserved           		0x10
+#define bOFDMTxLength             		0x1ffe0
+#define bOFDMTxParity             		0x20000
+#define bTxHTSIG1                 			0xffffff
+#define bTxHTMCSRate              		0x7f
+#define bTxHTBW                   			0x80
+#define bTxHTLength               		0xffff00
+#define bTxHTSIG2                 			0xffffff
+#define bTxHTSmoothing            		0x1
+#define bTxHTSounding             		0x2
+#define bTxHTReserved             		0x4
+#define bTxHTAggreation           		0x8
+#define bTxHTSTBC                 			0x30
+#define bTxHTAdvanceCoding        		0x40
+#define bTxHTShortGI              		0x80
+#define bTxHTNumberHT_LTF         		0x300
+#define bTxHTCRC8                 			0x3fc00
+#define bCounterReset             		0x10000
+#define bNumOfOFDMTx              		0xffff
+#define bNumOfCCKTx               		0xffff0000
+#define bTxIdleInterval           			0xffff
+#define bOFDMService              		0xffff0000
+#define bTxMACHeader              		0xffffffff
+#define bTxDataInit               			0xff
+#define bTxHTMode                 		0x100
+#define bTxDataType               		0x30000
+#define bTxRandomSeed             		0xffffffff
+#define bCCKTxPreamble           		0x1
+#define bCCKTxSFD                 			0xffff0000
+#define bCCKTxSIG                 			0xff
+#define bCCKTxService             		0xff00
+#define bCCKLengthExt             		0x8000
+#define bCCKTxLength              		0xffff0000
+#define bCCKTxCRC16               		0xffff
+#define bCCKTxStatus              		0x1
+#define bOFDMTxStatus             		0x2
+
+//page-8
+#define bRFMOD                    			0x1
+#define bJapanMode                		0x2
+#define bCCKTxSC                  			0x30
+#define bCCKEn                    			0x1000000
+#define bOFDMEn                   			0x2000000
+#define bOFDMRxADCPhase           		0x10000
+#define bOFDMTxDACPhase           		0x40000
+#define bXATxAGC                  			0x3f
+#define bXBTxAGC                  			0xf00
+#define bXCTxAGC                  			0xf000
+#define bXDTxAGC                  			0xf0000
+#define bPAStart                  			0xf0000000
+#define bTRStart                  			0x00f00000
+#define bRFStart                  			0x0000f000
+#define bBBStart                  			0x000000f0
+#define bBBCCKStart               		0x0000000f
+#define bPAEnd                    			0xf          //Reg0x814
+#define bTREnd                    			0x0f000000
+#define bRFEnd                    			0x000f0000
+#define bCCAMask                  			0x000000f0   //T2R
+#define bR2RCCAMask               		0x00000f00
+#define bHSSI_R2TDelay            		0xf8000000
+#define bHSSI_T2RDelay            		0xf80000
+#define bContTxHSSI               		0x400     //chane gain at continue Tx
+#define bIGFromCCK                		0x200
+#define bAGCAddress               		0x3f
+#define bRxHPTx                   			0x7000
+#define bRxHPT2R                  			0x38000
+#define bRxHPCCKIni               		0xc0000
+#define bAGCTxCode                		0xc00000
+#define bAGCRxCode                		0x300000
+#define b3WireDataLength          		0x800
+#define b3WireAddressLength       		0x400
+#define b3WireRFPowerDown         		0x1
+//#define bHWSISelect               		0x8
+#define b5GPAPEPolarity           		0x40000000
+#define b2GPAPEPolarity           		0x80000000
+#define bRFSW_TxDefaultAnt        		0x3
+#define bRFSW_TxOptionAnt         		0x30
+#define bRFSW_RxDefaultAnt        		0x300
+#define bRFSW_RxOptionAnt         		0x3000
+#define bRFSI_3WireData           		0x1
+#define bRFSI_3WireClock          		0x2
+#define bRFSI_3WireLoad           		0x4
+#define bRFSI_3WireRW             		0x8
+#define bRFSI_3Wire               			0xf  //3-wire total control
+#define bRFSI_RFENV               		0x10
+#define bRFSI_TRSW                		0x20
+#define bRFSI_TRSWB               		0x40
+#define bRFSI_ANTSW               		0x100
+#define bRFSI_ANTSWB              		0x200
+#define bRFSI_PAPE                			0x400
+#define bRFSI_PAPE5G              		0x800
+#define bBandSelect               			0x1
+#define bHTSIG2_GI                			0x80
+#define bHTSIG2_Smoothing         		0x01
+#define bHTSIG2_Sounding          		0x02
+#define bHTSIG2_Aggreaton         		0x08
+#define bHTSIG2_STBC              		0x30
+#define bHTSIG2_AdvCoding         		0x40
+#define bHTSIG2_NumOfHTLTF        	0x300
+#define bHTSIG2_CRC8              		0x3fc
+#define bHTSIG1_MCS               		0x7f
+#define bHTSIG1_BandWidth         		0x80
+#define bHTSIG1_HTLength          		0xffff
+#define bLSIG_Rate                			0xf
+#define bLSIG_Reserved            		0x10
+#define bLSIG_Length              		0x1fffe
+#define bLSIG_Parity              			0x20
+#define bCCKRxPhase               		0x4
+#define bLSSIReadAddress          		0x3f000000   //LSSI "Read" Address
+#define bLSSIReadEdge             		0x80000000   //LSSI "Read" edge signal
+#define bLSSIReadBackData         		0xfff
+#define bLSSIReadOKFlag           		0x1000
+#define bCCKSampleRate            		0x8       //0: 44MHz, 1:88MHz
+
+#define bRegulator0Standby        		0x1
+#define bRegulatorPLLStandby      		0x2
+#define bRegulator1Standby        		0x4
+#define bPLLPowerUp               		0x8
+#define bDPLLPowerUp              		0x10
+#define bDA10PowerUp              		0x20
+#define bAD7PowerUp               		0x200
+#define bDA6PowerUp               		0x2000
+#define bXtalPowerUp              		0x4000
+#define b40MDClkPowerUP           		0x8000
+#define bDA6DebugMode             		0x20000
+#define bDA6Swing                 			0x380000
+#define bADClkPhase               		0x4000000
+#define b80MClkDelay              		0x18000000
+#define bAFEWatchDogEnable        		0x20000000
+#define bXtalCap                			0x0f000000
+#define bXtalCap01                			0xc0000000
+#define bXtalCap23                			0x3
+#define bXtalCap92x					0x0f000000
+#define bIntDifClkEnable          		0x400
+#define bExtSigClkEnable         	 	0x800
+#define bBandgapMbiasPowerUp      	0x10000
+#define bAD11SHGain               		0xc0000
+#define bAD11InputRange           		0x700000
+#define bAD11OPCurrent            		0x3800000
+#define bIPathLoopback            		0x4000000
+#define bQPathLoopback            		0x8000000
+#define bAFELoopback              		0x10000000
+#define bDA10Swing                		0x7e0
+#define bDA10Reverse              		0x800
+#define bDAClkSource              		0x1000
+#define bAD7InputRange            		0x6000
+#define bAD7Gain                  			0x38000
+#define bAD7OutputCMMode          		0x40000
+#define bAD7InputCMMode           		0x380000
+#define bAD7Current               			0xc00000
+#define bRegulatorAdjust          		0x7000000
+#define bAD11PowerUpAtTx          		0x1
+#define bDA10PSAtTx               		0x10
+#define bAD11PowerUpAtRx          		0x100
+#define bDA10PSAtRx               		0x1000
+
+#define bCCKRxAGCFormat           		0x200
+
+#define bPSDFFTSamplepPoint       		0xc000
+#define bPSDAverageNum            		0x3000
+#define bIQPathControl            		0xc00
+#define bPSDFreq                  			0x3ff
+#define bPSDAntennaPath           		0x30
+#define bPSDIQSwitch              		0x40
+#define bPSDRxTrigger             		0x400000
+#define bPSDTxTrigger             		0x80000000
+#define bPSDSineToneScale        		0x7f000000
+#define bPSDReport                			0xffff
+
+//page-9
+#define bOFDMTxSC                 		0x30000000
+#define bCCKTxOn                  			0x1
+#define bOFDMTxOn                 		0x2
+#define bDebugPage                		0xfff  //reset debug page and also HWord, LWord
+#define bDebugItem                		0xff   //reset debug page and LWord
+#define bAntL              	       		0x10
+#define bAntNonHT           	      			0x100
+#define bAntHT1               			0x1000
+#define bAntHT2                   			0x10000
+#define bAntHT1S1                 			0x100000
+#define bAntNonHTS1               		0x1000000
+
+//page-a
+#define bCCKBBMode                		0x3
+#define bCCKTxPowerSaving         		0x80
+#define bCCKRxPowerSaving         		0x40
+#define bCCKSideBand              		0x10
+#define bCCKScramble              		0x8
+#define bCCKAntDiversity    		      	0x8000
+#define bCCKCarrierRecovery   	    	0x4000
+#define bCCKTxRate           		     	0x3000
+#define bCCKDCCancel             	 	0x0800
+#define bCCKISICancel             		0x0400
+#define bCCKMatchFilter           		0x0200
+#define bCCKEqualizer             		0x0100
+#define bCCKPreambleDetect       	 	0x800000
+#define bCCKFastFalseCCA          		0x400000
+#define bCCKChEstStart            		0x300000
+#define bCCKCCACount              		0x080000
+#define bCCKcs_lim                			0x070000
+#define bCCKBistMode              		0x80000000
+#define bCCKCCAMask             	  	0x40000000
+#define bCCKTxDACPhase         	   	0x4
+#define bCCKRxADCPhase         	   	0x20000000   //r_rx_clk
+#define bCCKr_cp_mode0         	   	0x0100
+#define bCCKTxDCOffset           	 	0xf0
+#define bCCKRxDCOffset           	 	0xf
+#define bCCKCCAMode              	 	0xc000
+#define bCCKFalseCS_lim           		0x3f00
+#define bCCKCS_ratio              		0xc00000
+#define bCCKCorgBit_sel           		0x300000
+#define bCCKPD_lim                			0x0f0000
+#define bCCKNewCCA                		0x80000000
+#define bCCKRxHPofIG              		0x8000
+#define bCCKRxIG                  			0x7f00
+#define bCCKLNAPolarity           		0x800000
+#define bCCKRx1stGain             		0x7f0000
+#define bCCKRFExtend              		0x20000000 //CCK Rx Iinital gain polarity
+#define bCCKRxAGCSatLevel        	 	0x1f000000
+#define bCCKRxAGCSatCount       	  	0xe0
+#define bCCKRxRFSettle            		0x1f       //AGCsamp_dly
+#define bCCKFixedRxAGC           	 	0x8000
+//#define bCCKRxAGCFormat         	 	0x4000   //remove to HSSI register 0x824
+#define bCCKAntennaPolarity      	 	0x2000
+#define bCCKTxFilterType          		0x0c00
+#define bCCKRxAGCReportType   	   	0x0300
+#define bCCKRxDAGCEn              		0x80000000
+#define bCCKRxDAGCPeriod        	  	0x20000000
+#define bCCKRxDAGCSatLevel     	   	0x1f000000
+#define bCCKTimingRecovery       	 	0x800000
+#define bCCKTxC0                  			0x3f0000
+#define bCCKTxC1                  			0x3f000000
+#define bCCKTxC2                  			0x3f
+#define bCCKTxC3                  			0x3f00
+#define bCCKTxC4                  			0x3f0000
+#define bCCKTxC5                  			0x3f000000
+#define bCCKTxC6                  			0x3f
+#define bCCKTxC7                  			0x3f00
+#define bCCKDebugPort             		0xff0000
+#define bCCKDACDebug              		0x0f000000
+#define bCCKFalseAlarmEnable      		0x8000
+#define bCCKFalseAlarmRead        		0x4000
+#define bCCKTRSSI                 			0x7f
+#define bCCKRxAGCReport           		0xfe
+#define bCCKRxReport_AntSel       		0x80000000
+#define bCCKRxReport_MFOff        		0x40000000
+#define bCCKRxRxReport_SQLoss     	0x20000000
+#define bCCKRxReport_Pktloss      		0x10000000
+#define bCCKRxReport_Lockedbit    	0x08000000
+#define bCCKRxReport_RateError    	0x04000000
+#define bCCKRxReport_RxRate       		0x03000000
+#define bCCKRxFACounterLower      	0xff
+#define bCCKRxFACounterUpper      	0xff000000
+#define bCCKRxHPAGCStart          		0xe000
+#define bCCKRxHPAGCFinal          		0x1c00
+
+#define bCCKRxFalseAlarmEnable    	0x8000
+#define bCCKFACounterFreeze       		0x4000
+
+#define bCCKTxPathSel             		0x10000000
+#define bCCKDefaultRxPath         		0xc000000
+#define bCCKOptionRxPath          		0x3000000
+
+//page c
+#define bNumOfSTF                			0x3
+#define bShift_L                 			0xc0
+#define bGI_TH                   			0xc
+#define bRxPathA                 			0x1
+#define bRxPathB                 			0x2
+#define bRxPathC                 			0x4
+#define bRxPathD                 			0x8
+#define bTxPathA                 			0x1
+#define bTxPathB                 			0x2
+#define bTxPathC                 			0x4
+#define bTxPathD                 			0x8
+#define bTRSSIFreq               			0x200
+#define bADCBackoff              			0x3000
+#define bDFIRBackoff             			0xc000
+#define bTRSSILatchPhase         		0x10000
+#define bRxIDCOffset             			0xff
+#define bRxQDCOffset             			0xff00
+#define bRxDFIRMode              		0x1800000
+#define bRxDCNFType              		0xe000000
+#define bRXIQImb_A               			0x3ff
+#define bRXIQImb_B               			0xfc00
+#define bRXIQImb_C               			0x3f0000
+#define bRXIQImb_D               			0xffc00000
+#define bDC_dc_Notch             		0x60000
+#define bRxNBINotch              			0x1f000000
+#define bPD_TH                   			0xf
+#define bPD_TH_Opt2              		0xc000
+#define bPWED_TH                 			0x700
+#define bIfMF_Win_L              			0x800
+#define bPD_Option               			0x1000
+#define bMF_Win_L                			0xe000
+#define bBW_Search_L             		0x30000
+#define bwin_enh_L               			0xc0000
+#define bBW_TH                   			0x700000
+#define bED_TH2                  			0x3800000
+#define bBW_option               			0x4000000
+#define bRatio_TH                			0x18000000
+#define bWindow_L                			0xe0000000
+#define bSBD_Option              			0x1
+#define bFrame_TH                			0x1c
+#define bFS_Option               			0x60
+#define bDC_Slope_check          		0x80
+#define bFGuard_Counter_DC_L     		0xe00
+#define bFrame_Weight_Short      		0x7000
+#define bSub_Tune                			0xe00000
+#define bFrame_DC_Length         		0xe000000
+#define bSBD_start_offset        		0x30000000
+#define bFrame_TH_2              		0x7
+#define bFrame_GI2_TH            		0x38
+#define bGI2_Sync_en             		0x40
+#define bSarch_Short_Early       		0x300
+#define bSarch_Short_Late        		0xc00
+#define bSarch_GI2_Late          		0x70000
+#define bCFOAntSum               		0x1
+#define bCFOAcc                  			0x2
+#define bCFOStartOffset          		0xc
+#define bCFOLookBack             		0x70
+#define bCFOSumWeight            		0x80
+#define bDAGCEnable              			0x10000
+#define bTXIQImb_A               			0x3ff
+#define bTXIQImb_B               			0xfc00
+#define bTXIQImb_C               			0x3f0000
+#define bTXIQImb_D               			0xffc00000
+#define bTxIDCOffset             			0xff
+#define bTxQDCOffset             			0xff00
+#define bTxDFIRMode              		0x10000
+#define bTxPesudoNoiseOn         		0x4000000
+#define bTxPesudoNoise_A         		0xff
+#define bTxPesudoNoise_B         		0xff00
+#define bTxPesudoNoise_C         		0xff0000
+#define bTxPesudoNoise_D         		0xff000000
+#define bCCADropOption           		0x20000
+#define bCCADropThres            		0xfff00000
+#define bEDCCA_H                 			0xf
+#define bEDCCA_L                 			0xf0
+#define bLambda_ED               0x300
+#define bRxInitialGain           0x7f
+#define bRxAntDivEn              0x80
+#define bRxAGCAddressForLNA      0x7f00
+#define bRxHighPowerFlow         0x8000
+#define bRxAGCFreezeThres        0xc0000
+#define bRxFreezeStep_AGC1       0x300000
+#define bRxFreezeStep_AGC2       0xc00000
+#define bRxFreezeStep_AGC3       0x3000000
+#define bRxFreezeStep_AGC0       0xc000000
+#define bRxRssi_Cmp_En           0x10000000
+#define bRxQuickAGCEn            0x20000000
+#define bRxAGCFreezeThresMode    0x40000000
+#define bRxOverFlowCheckType     0x80000000
+#define bRxAGCShift              0x7f
+#define bTRSW_Tri_Only           0x80
+#define bPowerThres              0x300
+#define bRxAGCEn                 0x1
+#define bRxAGCTogetherEn         0x2
+#define bRxAGCMin                0x4
+#define bRxHP_Ini                0x7
+#define bRxHP_TRLNA              0x70
+#define bRxHP_RSSI               0x700
+#define bRxHP_BBP1               0x7000
+#define bRxHP_BBP2               0x70000
+#define bRxHP_BBP3               0x700000
+#define bRSSI_H                  0x7f0000     //the threshold for high power
+#define bRSSI_Gen                0x7f000000   //the threshold for ant diversity
+#define bRxSettle_TRSW           0x7
+#define bRxSettle_LNA            0x38
+#define bRxSettle_RSSI           0x1c0
+#define bRxSettle_BBP            0xe00
+#define bRxSettle_RxHP           0x7000
+#define bRxSettle_AntSW_RSSI     0x38000
+#define bRxSettle_AntSW          0xc0000
+#define bRxProcessTime_DAGC      0x300000
+#define bRxSettle_HSSI           0x400000
+#define bRxProcessTime_BBPPW     0x800000
+#define bRxAntennaPowerShift     0x3000000
+#define bRSSITableSelect         0xc000000
+#define bRxHP_Final              0x7000000
+#define bRxHTSettle_BBP          0x7
+#define bRxHTSettle_HSSI         0x8
+#define bRxHTSettle_RxHP         0x70
+#define bRxHTSettle_BBPPW        0x80
+#define bRxHTSettle_Idle         0x300
+#define bRxHTSettle_Reserved     0x1c00
+#define bRxHTRxHPEn              0x8000
+#define bRxHTAGCFreezeThres      0x30000
+#define bRxHTAGCTogetherEn       0x40000
+#define bRxHTAGCMin              0x80000
+#define bRxHTAGCEn               0x100000
+#define bRxHTDAGCEn              0x200000
+#define bRxHTRxHP_BBP            0x1c00000
+#define bRxHTRxHP_Final          0xe0000000
+#define bRxPWRatioTH             0x3
+#define bRxPWRatioEn             0x4
+#define bRxMFHold                0x3800
+#define bRxPD_Delay_TH1          0x38
+#define bRxPD_Delay_TH2          0x1c0
+#define bRxPD_DC_COUNT_MAX       0x600
+//#define bRxMF_Hold               0x3800
+#define bRxPD_Delay_TH           0x8000
+#define bRxProcess_Delay         0xf0000
+#define bRxSearchrange_GI2_Early 0x700000
+#define bRxFrame_Guard_Counter_L 0x3800000
+#define bRxSGI_Guard_L           0xc000000
+#define bRxSGI_Search_L          0x30000000
+#define bRxSGI_TH                0xc0000000
+#define bDFSCnt0                 0xff
+#define bDFSCnt1                 0xff00
+#define bDFSFlag                 0xf0000
+
+#define bMFWeightSum             0x300000
+#define bMinIdxTH                0x7f000000
+
+#define bDAFormat                0x40000
+
+#define bTxChEmuEnable           0x01000000
+
+#define bTRSWIsolation_A         0x7f
+#define bTRSWIsolation_B         0x7f00
+#define bTRSWIsolation_C         0x7f0000
+#define bTRSWIsolation_D         0x7f000000
+
+#define bExtLNAGain              0x7c00
+
+//page d
+#define bSTBCEn                  0x4
+#define bAntennaMapping          0x10
+#define bNss                     0x20
+#define bCFOAntSumD              0x200
+#define bPHYCounterReset         0x8000000
+#define bCFOReportGet            0x4000000
+#define bOFDMContinueTx          0x10000000
+#define bOFDMSingleCarrier       0x20000000
+#define bOFDMSingleTone          0x40000000
+//#define bRxPath1                 0x01
+//#define bRxPath2                 0x02
+//#define bRxPath3                 0x04
+//#define bRxPath4                 0x08
+//#define bTxPath1                 0x10
+//#define bTxPath2                 0x20
+#define bHTDetect                0x100
+#define bCFOEn                   0x10000
+#define bCFOValue                0xfff00000
+#define bSigTone_Re              0x3f
+#define bSigTone_Im              0x7f00
+#define bCounter_CCA             0xffff
+#define bCounter_ParityFail      0xffff0000
+#define bCounter_RateIllegal     0xffff
+#define bCounter_CRC8Fail        0xffff0000
+#define bCounter_MCSNoSupport    0xffff
+#define bCounter_FastSync        0xffff
+#define bShortCFO                0xfff
+#define bShortCFOTLength         12   //total
+#define bShortCFOFLength         11   //fraction
+#define bLongCFO                 0x7ff
+#define bLongCFOTLength          11
+#define bLongCFOFLength          11
+#define bTailCFO                 0x1fff
+#define bTailCFOTLength          13
+#define bTailCFOFLength          12
+
+#define bmax_en_pwdB             0xffff
+#define bCC_power_dB             0xffff0000
+#define bnoise_pwdB              0xffff
+#define bPowerMeasTLength        10
+#define bPowerMeasFLength        3
+#define bRx_HT_BW                0x1
+#define bRxSC                    0x6
+#define bRx_HT                   0x8
+
+#define bNB_intf_det_on          0x1
+#define bIntf_win_len_cfg        0x30
+#define bNB_Intf_TH_cfg          0x1c0
+
+#define bRFGain                  0x3f
+#define bTableSel                0x40
+#define bTRSW                    0x80
+
+#define bRxSNR_A                 0xff
+#define bRxSNR_B                 0xff00
+#define bRxSNR_C                 0xff0000
+#define bRxSNR_D                 0xff000000
+#define bSNREVMTLength           8
+#define bSNREVMFLength           1
+
+#define bCSI1st                  0xff
+#define bCSI2nd                  0xff00
+#define bRxEVM1st                0xff0000
+#define bRxEVM2nd                0xff000000
+
+#define bSIGEVM                  0xff
+#define bPWDB                    0xff00
+#define bSGIEN                   0x10000
+
+#define bSFactorQAM1             0xf
+#define bSFactorQAM2             0xf0
+#define bSFactorQAM3             0xf00
+#define bSFactorQAM4             0xf000
+#define bSFactorQAM5             0xf0000
+#define bSFactorQAM6             0xf0000
+#define bSFactorQAM7             0xf00000
+#define bSFactorQAM8             0xf000000
+#define bSFactorQAM9             0xf0000000
+#define bCSIScheme               0x100000
+
+#define bNoiseLvlTopSet          0x3
+#define bChSmooth                0x4
+#define bChSmoothCfg1            0x38
+#define bChSmoothCfg2            0x1c0
+#define bChSmoothCfg3            0xe00
+#define bChSmoothCfg4            0x7000
+#define bMRCMode                 0x800000
+#define bTHEVMCfg                0x7000000
+
+#define bLoopFitType             0x1
+#define bUpdCFO                  0x40
+#define bUpdCFOOffData           0x80
+#define bAdvUpdCFO               0x100
+#define bAdvTimeCtrl             0x800
+#define bUpdClko                 0x1000
+#define bFC                      0x6000
+#define bTrackingMode            0x8000
+#define bPhCmpEnable             0x10000
+#define bUpdClkoLTF              0x20000
+#define bComChCFO                0x40000
+#define bCSIEstiMode             0x80000
+#define bAdvUpdEqz               0x100000
+#define bUChCfg                  0x7000000
+#define bUpdEqz                  0x8000000
+
+//page e
+#define bTxAGCRate18_06			0x7f7f7f7f
+#define bTxAGCRate54_24			0x7f7f7f7f
+#define bTxAGCRateMCS32		0x7f
+#define bTxAGCRateCCK			0x7f00
+#define bTxAGCRateMCS3_MCS0	0x7f7f7f7f
+#define bTxAGCRateMCS7_MCS4	0x7f7f7f7f
+#define bTxAGCRateMCS11_MCS8	0x7f7f7f7f
+#define bTxAGCRateMCS15_MCS12	0x7f7f7f7f
+
+
+//Rx Pseduo noise
+#define bRxPesudoNoiseOn         0x20000000
+#define bRxPesudoNoise_A         0xff
+#define bRxPesudoNoise_B         0xff00
+#define bRxPesudoNoise_C         0xff0000
+#define bRxPesudoNoise_D         0xff000000
+#define bPesudoNoiseState_A      0xffff
+#define bPesudoNoiseState_B      0xffff0000
+#define bPesudoNoiseState_C      0xffff
+#define bPesudoNoiseState_D      0xffff0000
+
+//RF
+//Zebra1
+#define bZebra1_HSSIEnable        0x8
+#define bZebra1_TRxControl        0xc00
+#define bZebra1_TRxGainSetting    0x07f
+#define bZebra1_RxCorner          0xc00
+#define bZebra1_TxChargePump      0x38
+#define bZebra1_RxChargePump      0x7
+#define bZebra1_ChannelNum        0xf80
+#define bZebra1_TxLPFBW           0x400
+#define bZebra1_RxLPFBW           0x600
+
+//Zebra4
+#define bRTL8256RegModeCtrl1      0x100
+#define bRTL8256RegModeCtrl0      0x40
+#define bRTL8256_TxLPFBW          0x18
+#define bRTL8256_RxLPFBW          0x600
+
+//RTL8258
+#define bRTL8258_TxLPFBW          0xc
+#define bRTL8258_RxLPFBW          0xc00
+#define bRTL8258_RSSILPFBW        0xc0
+
+//byte endable for sb_write
+#define bByte0                    0x1
+#define bByte1                    0x2
+#define bByte2                    0x4
+#define bByte3                    0x8
+#define bWord0                    0x3
+#define bWord1                    0xc
+#define bDWord                    0xf
+
+//for PutRegsetting & GetRegSetting BitMask
+#define bMaskByte0                0xff
+#define bMaskByte1                0xff00
+#define bMaskByte2                0xff0000
+#define bMaskByte3                0xff000000
+#define bMaskHWord                0xffff0000
+#define bMaskLWord                0x0000ffff
+#define bMaskDWord                0xffffffff
+
+//for PutRFRegsetting & GetRFRegSetting BitMask
+#define bMask12Bits               0xfff
+
+#define bEnable                   0x1
+#define bDisable                  0x0
+
+#define LeftAntenna               0x0
+#define RightAntenna              0x1
+
+#define tCheckTxStatus            500   //500ms
+#define tUpdateRxCounter          100   //100ms
+
+#define rateCCK     0
+#define rateOFDM    1
+#define rateHT      2
+
+//define Register-End
+#define bPMAC_End                 0x1ff
+#define bFPGAPHY0_End             0x8ff
+#define bFPGAPHY1_End             0x9ff
+#define bCCKPHY0_End              0xaff
+#define bOFDMPHY0_End             0xcff
+#define bOFDMPHY1_End             0xdff
+
+//define max debug item in each debug page
+//#define bMaxItem_FPGA_PHY0        0x9
+//#define bMaxItem_FPGA_PHY1        0x3
+//#define bMaxItem_PHY_11B          0x16
+//#define bMaxItem_OFDM_PHY0        0x29
+//#define bMaxItem_OFDM_PHY1        0x0
+
+#define bPMACControl              0x0
+#define bWMACControl              0x1
+#define bWNICControl              0x2
+
+#define PathA                     0x0
+#define PathB                     0x1
+#define PathC                     0x2
+#define PathD                     0x3
+
+#define	rRTL8256RxMixerPole		0xb
+#define 	bZebraRxMixerPole		0x6
+#define 	rRTL8256TxBBOPBias        0x9
+#define 	bRTL8256TxBBOPBias       0x400
+#define 	rRTL8256TxBBBW             19
+#define 	bRTL8256TxBBBW            	0x18
+
+#endif	//__INC_HAL8190PCIPHYREG_H
diff --git a/drivers/staging/rtl8192su/Makefile b/drivers/staging/rtl8192su/Makefile
index f010ab5..c8b4332 100644
--- a/drivers/staging/rtl8192su/Makefile
+++ b/drivers/staging/rtl8192su/Makefile
@@ -2,33 +2,11 @@ NIC_SELECT = RTL8192SU
 
 EXTRA_CFLAGS += -std=gnu89
 EXTRA_CFLAGS += -O2
-EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
 
 EXTRA_CFLAGS += -DJACKSON_NEW_RX
-EXTRA_CFLAGS += -DTHOMAS_BEACON -DTHOMAS_TURBO
-#EXTRA_CFLAGS += -DUSE_ONE_PIPE
-EXTRA_CFLAGS += -DENABLE_DOT11D
-
-EXTRA_CFLAGS += -DRTL8192SU
-EXTRA_CFLAGS += -DRTL8190_Download_Firmware_From_Header=1
-EXTRA_CFLAGS += -DRTL8192S_PREPARE_FOR_NORMAL_RELEASE
-EXTRA_CFLAGS += -DRTL8192SU_DISABLE_IQK=1
-
-#EXTRA_CFLAGS += -DEEPROM_OLD_FORMAT_SUPPORT
-
-#EXTRA_CFLAGS += -DUSB_RX_AGGREGATION_SUPPORT=0
-#EXTRA_CFLAGS += -DUSB_TX_DRIVER_AGGREGATION_ENABLE=0
-#EXTRA_CFLAGS += -DRTL8192SU_DISABLE_CCK_RATE=0
-EXTRA_CFLAGS += -DRTL8192S_DISABLE_FW_DM=0
-EXTRA_CFLAGS += -DDISABLE_BB_RF=0
-EXTRA_CFLAGS += -DRTL8192SU_USE_PARAM_TXPWR=0
-EXTRA_CFLAGS += -DRTL8192SU_FPGA_UNSPECIFIED_NETWORK=0
-#EXTRA_CFLAGS += -DRTL8192SU_FPGA_2MAC_VERIFICATION #=0
-EXTRA_CFLAGS += -DRTL8192SU_ASIC_VERIFICATION
-EXTRA_CFLAGS += -DRTL8192SU_USB_PHY_TEST=0
+EXTRA_CFLAGS += -DTHOMAS_BEACON
 
 #EXTRA_CFLAGS += -DMUTIPLE_BULK_OUT
-EXTRA_CFLAGS += -DCONFIG_RTL8192_PM
 
 r8192s_usb-objs :=		\
 	r8180_93cx6.o		\
@@ -42,9 +20,11 @@ r8192s_usb-objs :=		\
 	r8192S_firmware.o	\
 	r8192S_Efuse.o		\
 	r8192U_core.o		\
-	r8192U_pm.o
-
-ieee80211-rsl-objs :=			\
+	r8192U_pm.o		\
+	ieee80211/ieee80211_crypt.o		\
+	ieee80211/ieee80211_crypt_tkip.o	\
+	ieee80211/ieee80211_crypt_ccmp.o	\
+	ieee80211/ieee80211_crypt_wep.o		\
 	ieee80211/ieee80211_rx.o	\
 	ieee80211/ieee80211_softmac.o	\
 	ieee80211/ieee80211_tx.o	\
@@ -57,10 +37,3 @@ ieee80211-rsl-objs :=			\
 	ieee80211/dot11d.o
 
 obj-$(CONFIG_RTL8192SU) += r8192s_usb.o
-obj-$(CONFIG_RTL8192SU) += ieee80211-rsl.o
-obj-$(CONFIG_RTL8192SU) += ieee80211/ieee80211_crypt.o
-obj-$(CONFIG_RTL8192SU) += ieee80211/ieee80211_crypt_tkip.o
-obj-$(CONFIG_RTL8192SU) += ieee80211/ieee80211_crypt_ccmp.o
-obj-$(CONFIG_RTL8192SU) += ieee80211/ieee80211_crypt_wep.o
-
-
diff --git a/drivers/staging/rtl8192su/TODO b/drivers/staging/rtl8192su/TODO
new file mode 100644
index 0000000..b13be9e
--- /dev/null
+++ b/drivers/staging/rtl8192su/TODO
@@ -0,0 +1,18 @@
+TODO:
+- prepare private ieee80211 stack for merge with rtl8187se's version:
+  - remove rtl8192su's specific dead code
+  - cleanup ieee80211.h
+  - move rtl8192su's specific code out from ieee80211.h
+  - abstract rtl819su's specific code
+  - use list_for_each_safe() in ieee80211_crypto_deinit
+- switch to use shared "librtl" instead of private ieee80211 stack
+- switch to use LIB80211
+- switch to use MAC80211
+- switch to use EEPROM_93CX6
+- use kernel coding style
+- checkpatch.pl fixes
+- sparse fixes
+- integrate with drivers/net/wireless/rtl818x
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
+Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
diff --git a/drivers/staging/rtl8192su/dot11d.h b/drivers/staging/rtl8192su/dot11d.h
deleted file mode 100644
index 15b7a4b..0000000
--- a/drivers/staging/rtl8192su/dot11d.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#ifdef ENABLE_DOT11D
-#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 //ENABLE_DOT11D
-#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192su/ieee80211.h b/drivers/staging/rtl8192su/ieee80211.h
deleted file mode 100644
index ea97393..0000000
--- a/drivers/staging/rtl8192su/ieee80211.h
+++ /dev/null
@@ -1,2901 +0,0 @@
-/*
- * Merged with mainline ieee80211.h in Aug 2004.  Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andreamrl@tiscali.it>
- *
- * 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. See README and COPYING for
- * more details.
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h>   /* ARRAY_SIZE */
-#include <linux/version.h>
-#include <linux/module.h>
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-#include <linux/jiffies.h>
-#else
-#include <linux/jffs.h>
-#include <linux/tqueue.h>
-#endif
-#include <linux/timer.h>
-#include <linux/sched.h>
-
-#include <linux/delay.h>
-#include <linux/wireless.h>
-
-#include "ieee80211/rtl819x_HT.h"
-#include "ieee80211/rtl819x_BA.h"
-#include "ieee80211/rtl819x_TS.h"
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-#ifndef bool
-typedef enum{false = 0, true} bool;
-#endif
-#endif
-
-#ifndef IW_MODE_MONITOR
-#define IW_MODE_MONITOR 6
-#endif
-
-#ifndef IWEVCUSTOM
-#define IWEVCUSTOM 0x8c02
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#ifndef __bitwise
-#define __bitwise __attribute__((bitwise))
-#endif
-typedef __u16  __le16;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27))
-struct iw_spy_data{
-	/* --- Standard spy support --- */
-	int 			spy_number;
-	u_char 			spy_address[IW_MAX_SPY][ETH_ALEN];
-	struct iw_quality	spy_stat[IW_MAX_SPY];
-	/* --- Enhanced spy support (event) */
-	struct iw_quality	spy_thr_low; /* Low threshold */
-	struct iw_quality	spy_thr_high; /* High threshold */
-	u_char			spy_thr_under[IW_MAX_SPY];
-};
-#endif
-#endif
-
-#ifndef container_of
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr:        the pointer to the member.
- * @type:       the type of the container struct this is embedded in.
- * @member:     the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({                      \
-        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
-        (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
-#define KEY_TYPE_NA		0x0
-#define KEY_TYPE_WEP40 		0x1
-#define KEY_TYPE_TKIP		0x2
-#define KEY_TYPE_CCMP		0x4
-#define KEY_TYPE_WEP104		0x5
-
-/* added for rtl819x tx procedure */
-#define MAX_QUEUE_SIZE		0x10
-
-//
-// 8190 queue mapping
-//
-#define BK_QUEUE                               0
-#define BE_QUEUE                               1
-#define VI_QUEUE                               2
-#define VO_QUEUE                               3
-#define HCCA_QUEUE                             4
-#define TXCMD_QUEUE                            5
-#define MGNT_QUEUE                             6
-#define HIGH_QUEUE                             7
-#define BEACON_QUEUE                           8
-
-#define LOW_QUEUE                              BE_QUEUE
-#define NORMAL_QUEUE                           MGNT_QUEUE
-
-//added by amy for ps
-#define SWRF_TIMEOUT				50
-
-//added by amy for LEAP related
-#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
-#define SUPPORT_CKIP_MIC			0x08	// bit3
-#define SUPPORT_CKIP_PK			0x10	// bit4
-//added by amy for ps
-// RF Off Level for IPS or HW/SW radio off
-#define	RT_RF_OFF_LEVL_ASPM			BIT0	// PCI ASPM
-#define	RT_RF_OFF_LEVL_CLK_REQ		BIT1	// PCI clock request
-#define	RT_RF_OFF_LEVL_PCI_D3			BIT2	// PCI D3 mode
-#define	RT_RF_OFF_LEVL_HALT_NIC		BIT3	// NIC halt, re-initialize hw parameters
-#define	RT_RF_OFF_LEVL_FREE_FW		BIT4	// FW free, re-download the FW
-#define	RT_RF_OFF_LEVL_FW_32K		BIT5	// FW in 32k
-#define	RT_RF_PS_LEVEL_ALWAYS_ASPM	BIT6	// Always enable ASPM and Clock Req in initialization.
-#define	RT_RF_LPS_DISALBE_2R			BIT30	// When LPS is on, disable 2R if no packet is received or transmittd.
-#define	RT_RF_LPS_LEVEL_ASPM			BIT31	// LPS with ASPM
-#define	RT_IN_PS_LEVEL(pPSC, _PS_FLAG)	((pPSC->CurPsLevel & _PS_FLAG) ? true : false)
-#define	RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG)	(pPSC->CurPsLevel &= (~(_PS_FLAG)))
-#define	RT_SET_PS_LEVEL(pPSC, _PS_FLAG)	(pPSC->CurPsLevel->CurPsLevel |= _PS_FLAG)
-/* defined for skb cb field */
-/* At most 28 byte */
-typedef struct cb_desc {
-        /* Tx Desc Related flags (8-9) */
-	u8 bLastIniPkt:1;
-	u8 bCmdOrInit:1;
-        u8 bFirstSeg:1;
-        u8 bLastSeg:1;
-        u8 bEncrypt:1;
-        u8 bTxDisableRateFallBack:1;
-        u8 bTxUseDriverAssingedRate:1;
-        u8 bHwSec:1; //indicate whether use Hw security. WB
-
-        u8 reserved1;
-
-        /* Tx Firmware Relaged flags (10-11)*/
-        u8 bCTSEnable:1;
-        u8 bRTSEnable:1;
-        u8 bUseShortGI:1;
-        u8 bUseShortPreamble:1;
-        u8 bTxEnableFwCalcDur:1;
-        u8 bAMPDUEnable:1;
-        u8 bRTSSTBC:1;
-        u8 RTSSC:1;
-
-        u8 bRTSBW:1;
-        u8 bPacketBW:1;
-	u8 bRTSUseShortPreamble:1;
-	u8 bRTSUseShortGI:1;
-	u8 bMulticast:1;
-	u8 bBroadcast:1;
-        //u8 reserved2:2;
-        u8 drv_agg_enable:1;
-        u8 reserved2:1;
-
-        /* Tx Desc related element(12-19) */
-        u8 rata_index;
-        u8 queue_index;
-        //u8 reserved3;
-        //u8 reserved4;
-        u16 txbuf_size;
-        //u8 reserved5;
-	u8 RATRIndex;
-        u8 reserved6;
-        u8 reserved7;
-        u8 reserved8;
-
-        /* Tx firmware related element(20-27) */
-        u8 data_rate;
-        u8 rts_rate;
-        u8 ampdu_factor;
-        u8 ampdu_density;
-        //u8 reserved9;
-        //u8 reserved10;
-        //u8 reserved11;
-        u8 DrvAggrNum;
-	u16 pkt_size;
-        u8 reserved12;
-}cb_desc, *pcb_desc;
-
-/*--------------------------Define -------------------------------------------*/
-#define MGN_1M                  0x02
-#define MGN_2M                  0x04
-#define MGN_5_5M                0x0b
-#define MGN_11M                 0x16
-
-#define MGN_6M                  0x0c
-#define MGN_9M                  0x12
-#define MGN_12M                 0x18
-#define MGN_18M                 0x24
-#define MGN_24M                 0x30
-#define MGN_36M                 0x48
-#define MGN_48M                 0x60
-#define MGN_54M                 0x6c
-
-#define MGN_MCS0                0x80
-#define MGN_MCS1                0x81
-#define MGN_MCS2                0x82
-#define MGN_MCS3                0x83
-#define MGN_MCS4                0x84
-#define MGN_MCS5                0x85
-#define MGN_MCS6                0x86
-#define MGN_MCS7                0x87
-#define MGN_MCS8                0x88
-#define MGN_MCS9                0x89
-#define MGN_MCS10               0x8a
-#define MGN_MCS11               0x8b
-#define MGN_MCS12               0x8c
-#define MGN_MCS13               0x8d
-#define MGN_MCS14               0x8e
-#define MGN_MCS15               0x8f
-#define	MGN_MCS0_SG			0x90
-#define	MGN_MCS1_SG			0x91
-#define	MGN_MCS2_SG			0x92
-#define	MGN_MCS3_SG			0x93
-#define	MGN_MCS4_SG			0x94
-#define	MGN_MCS5_SG			0x95
-#define	MGN_MCS6_SG			0x96
-#define	MGN_MCS7_SG			0x97
-#define	MGN_MCS8_SG			0x98
-#define	MGN_MCS9_SG			0x99
-#define	MGN_MCS10_SG		0x9a
-#define	MGN_MCS11_SG		0x9b
-#define	MGN_MCS12_SG		0x9c
-#define	MGN_MCS13_SG		0x9d
-#define	MGN_MCS14_SG		0x9e
-#define	MGN_MCS15_SG		0x9f
-
-
-//----------------------------------------------------------------------------
-//		802.11 Management frame Reason Code field
-//----------------------------------------------------------------------------
-enum	_ReasonCode{
-	unspec_reason	= 0x1,
-	auth_not_valid	= 0x2,
-	deauth_lv_ss	= 0x3,
-	inactivity		= 0x4,
-	ap_overload 	= 0x5,
-	class2_err		= 0x6,
-	class3_err		= 0x7,
-	disas_lv_ss 	= 0x8,
-	asoc_not_auth	= 0x9,
-
-	//----MIC_CHECK
-	mic_failure 	= 0xe,
-	//----END MIC_CHECK
-
-	// Reason code defined in 802.11i D10.0 p.28.
-	invalid_IE		= 0x0d,
-	four_way_tmout	= 0x0f,
-	two_way_tmout	= 0x10,
-	IE_dismatch 	= 0x11,
-	invalid_Gcipher = 0x12,
-	invalid_Pcipher = 0x13,
-	invalid_AKMP	= 0x14,
-	unsup_RSNIEver = 0x15,
-	invalid_RSNIE	= 0x16,
-	auth_802_1x_fail= 0x17,
-	ciper_reject		= 0x18,
-
-	// Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
-	QoS_unspec		= 0x20, // 32
-	QAP_bandwidth	= 0x21, // 33
-	poor_condition	= 0x22, // 34
-	no_facility 	= 0x23, // 35
-							// Where is 36???
-	req_declined	= 0x25, // 37
-	invalid_param	= 0x26, // 38
-	req_not_honored= 0x27,	// 39
-	TS_not_created	= 0x2F, // 47
-	DL_not_allowed	= 0x30, // 48
-	dest_not_exist	= 0x31, // 49
-	dest_not_QSTA	= 0x32, // 50
-};
-
-
-
-#define aSifsTime	 (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10)
-
-#define MGMT_QUEUE_NUM 5
-
-#define IEEE_CMD_SET_WPA_PARAM			1
-#define	IEEE_CMD_SET_WPA_IE			2
-#define IEEE_CMD_SET_ENCRYPTION			3
-#define IEEE_CMD_MLME				4
-
-#define IEEE_PARAM_WPA_ENABLED			1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES		2
-#define IEEE_PARAM_DROP_UNENCRYPTED		3
-#define IEEE_PARAM_PRIVACY_INVOKED		4
-#define IEEE_PARAM_AUTH_ALGS			5
-#define IEEE_PARAM_IEEE_802_1X			6
-//It should consistent with the driver_XXX.c
-//   David, 2006.9.26
-#define IEEE_PARAM_WPAX_SELECT			7
-//Added for notify the encryption type selection
-//   David, 2006.9.26
-#define IEEE_PROTO_WPA				1
-#define IEEE_PROTO_RSN				2
-//Added for notify the encryption type selection
-//   David, 2006.9.26
-#define IEEE_WPAX_USEGROUP			0
-#define IEEE_WPAX_WEP40				1
-#define IEEE_WPAX_TKIP				2
-#define IEEE_WPAX_WRAP   			3
-#define IEEE_WPAX_CCMP				4
-#define IEEE_WPAX_WEP104			5
-
-#define IEEE_KEY_MGMT_IEEE8021X			1
-#define IEEE_KEY_MGMT_PSK			2
-
-#define IEEE_MLME_STA_DEAUTH			1
-#define IEEE_MLME_STA_DISASSOC			2
-
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG		2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR		3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED	4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED		5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED	6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED		7
-
-
-#define	IEEE_CRYPT_ALG_NAME_LEN			16
-
-#define MAX_IE_LEN  0xff
-
-// added for kernel conflict
-#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
-#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
-#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
-#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
-#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
-#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
-
-#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
-
-#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
-
-#define ieee80211_wep_null		ieee80211_wep_null_rsl
-
-#define free_ieee80211          	free_ieee80211_rsl
-#define alloc_ieee80211        		alloc_ieee80211_rsl
-
-#define ieee80211_rx 			ieee80211_rx_rsl
-#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
-
-#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
-#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
-#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
-#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
-#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
-#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
-#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
-#define ieee80211_is_54g		ieee80211_is_54g_rsl
-#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
-#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
-#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
-#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
-#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
-#define SendDisassociation		SendDisassociation_rsl
-#define ieee80211_disassociate		ieee80211_disassociate_rsl
-#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
-#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
-#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
-#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
-#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
-
-#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
-#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
-#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
-#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
-#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
-#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
-#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl
-#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
-#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
-#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
-#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
-#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
-#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
-#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
-#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
-#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
-#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
-#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
-
-#define ieee80211_txb_free		ieee80211_txb_free_rsl
-
-#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
-#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
-#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
-#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
-#if WIRELESS_EXT >= 18
-#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
-#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
-#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
-#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
-#endif
-
-
-typedef struct ieee_param {
-	u32 cmd;
-	u8 sta_addr[ETH_ALEN];
-        union {
-		struct {
-			u8 name;
-			u32 value;
-		} wpa_param;
-		struct {
-			u32 len;
-			u8 reserved[32];
-			u8 data[0];
-		} wpa_ie;
-	        struct{
-			int command;
-    			int reason_code;
-		} mlme;
-		struct {
-			u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
-			u8 set_tx;
-			u32 err;
-			u8 idx;
-			u8 seq[8]; /* sequence counter (set: RX, get: TX) */
-			u16 key_len;
-			u8 key[0];
-		} crypt;
-	} u;
-}ieee_param;
-
-
-#if WIRELESS_EXT < 17
-#define IW_QUAL_QUAL_INVALID   0x10
-#define IW_QUAL_LEVEL_INVALID  0x20
-#define IW_QUAL_NOISE_INVALID  0x40
-#define IW_QUAL_QUAL_UPDATED   0x1
-#define IW_QUAL_LEVEL_UPDATED  0x2
-#define IW_QUAL_NOISE_UPDATED  0x4
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
-{
-	task->routine = func;
-	task->data 	= data;
-	//task->next = NULL;
-	INIT_LIST_HEAD(&task->list);
-	task->sync = 0;
-}
-#endif
-
-// linux under 2.6.9 release may not support it, so modify it for common use
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
-//#define MSECS(t)	(1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
-#define MSECS(t)	(HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
-static inline unsigned long msleep_interruptible_rsl(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_INTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-         return timeout;
-}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
-static inline void msleep(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_UNINTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-}
-#endif
-#else
-#define MSECS(t) msecs_to_jiffies(t)
-#define msleep_interruptible_rsl  msleep_interruptible
-#endif
-
-#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 IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-#define MIN_FRAG_THRESHOLD     256U
-#define MAX_FRAG_THRESHOLD     2346U
-
-
-/* Frame control field constants */
-#define IEEE80211_FCTL_VERS		0x0003
-#define IEEE80211_FCTL_FTYPE		0x000c
-#define IEEE80211_FCTL_STYPE		0x00f0
-#define IEEE80211_FCTL_FRAMETYPE	0x00fc
-#define IEEE80211_FCTL_TODS		0x0100
-#define IEEE80211_FCTL_FROMDS		0x0200
-#define IEEE80211_FCTL_DSTODS		0x0300 //added by david
-#define IEEE80211_FCTL_MOREFRAGS	0x0400
-#define IEEE80211_FCTL_RETRY		0x0800
-#define IEEE80211_FCTL_PM		0x1000
-#define IEEE80211_FCTL_MOREDATA		0x2000
-#define IEEE80211_FCTL_WEP		0x4000
-#define IEEE80211_FCTL_ORDER		0x8000
-
-#define IEEE80211_FTYPE_MGMT		0x0000
-#define IEEE80211_FTYPE_CTL		0x0004
-#define IEEE80211_FTYPE_DATA		0x0008
-
-/* management */
-#define IEEE80211_STYPE_ASSOC_REQ	0x0000
-#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
-#define IEEE80211_STYPE_REASSOC_REQ	0x0020
-#define IEEE80211_STYPE_REASSOC_RESP	0x0030
-#define IEEE80211_STYPE_PROBE_REQ	0x0040
-#define IEEE80211_STYPE_PROBE_RESP	0x0050
-#define IEEE80211_STYPE_BEACON		0x0080
-#define IEEE80211_STYPE_ATIM		0x0090
-#define IEEE80211_STYPE_DISASSOC	0x00A0
-#define IEEE80211_STYPE_AUTH		0x00B0
-#define IEEE80211_STYPE_DEAUTH		0x00C0
-#define IEEE80211_STYPE_MANAGE_ACT	0x00D0
-
-/* control */
-#define IEEE80211_STYPE_PSPOLL		0x00A0
-#define IEEE80211_STYPE_RTS		0x00B0
-#define IEEE80211_STYPE_CTS		0x00C0
-#define IEEE80211_STYPE_ACK		0x00D0
-#define IEEE80211_STYPE_CFEND		0x00E0
-#define IEEE80211_STYPE_CFENDACK	0x00F0
-#define IEEE80211_STYPE_BLOCKACK   0x0094
-
-/* data */
-#define IEEE80211_STYPE_DATA		0x0000
-#define IEEE80211_STYPE_DATA_CFACK	0x0010
-#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
-#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
-#define IEEE80211_STYPE_NULLFUNC	0x0040
-#define IEEE80211_STYPE_CFACK		0x0050
-#define IEEE80211_STYPE_CFPOLL		0x0060
-#define IEEE80211_STYPE_CFACKPOLL	0x0070
-#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
-#define IEEE80211_STYPE_QOS_NULL	0x00C0
-
-#define IEEE80211_SCTL_FRAG		0x000F
-#define IEEE80211_SCTL_SEQ		0xFFF0
-
-/* QOS control */
-#define IEEE80211_QCTL_TID              0x000F
-
-#define	FC_QOS_BIT					BIT7
-#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
-#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )
-//added by wb. Is this right?
-#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
-#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
-#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
-#define SN_EQUAL(a, b)	(a == b)
-#define MAX_DEV_ADDR_SIZE 8
-typedef enum _ACT_CATEGORY{
-        ACT_CAT_QOS = 1,
-        ACT_CAT_DLS = 2,
-        ACT_CAT_BA  = 3,
-        ACT_CAT_HT  = 7,
-        ACT_CAT_WMM = 17,
-} ACT_CATEGORY, *PACT_CATEGORY;
-
-typedef enum _TS_ACTION{
-        ACT_ADDTSREQ = 0,
-        ACT_ADDTSRSP = 1,
-        ACT_DELTS    = 2,
-        ACT_SCHEDULE = 3,
-} TS_ACTION, *PTS_ACTION;
-
-typedef enum _BA_ACTION{
-        ACT_ADDBAREQ = 0,
-        ACT_ADDBARSP = 1,
-        ACT_DELBA    = 2,
-} BA_ACTION, *PBA_ACTION;
-
-typedef enum _InitialGainOpType{
-	IG_Backup=0,
-	IG_Restore,
-	IG_Max
-}InitialGainOpType;
-//added by amy for LED 090319
-//================================================================================
-// LED customization.
-//================================================================================
-typedef enum _LED_CTL_MODE{
-        LED_CTL_POWER_ON = 1,
-        LED_CTL_LINK = 2,
-        LED_CTL_NO_LINK = 3,
-        LED_CTL_TX = 4,
-        LED_CTL_RX = 5,
-        LED_CTL_SITE_SURVEY = 6,
-        LED_CTL_POWER_OFF = 7,
-        LED_CTL_START_TO_LINK = 8,
-        LED_CTL_START_WPS = 9,
-        LED_CTL_STOP_WPS = 10,
-        LED_CTL_START_WPS_BOTTON = 11, //added for runtop
-}LED_CTL_MODE;
-
-/* debug macros */
-#define CONFIG_IEEE80211_DEBUG
-#ifdef CONFIG_IEEE80211_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
-  printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0)
-//wb added to debug out data buf
-//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
-#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
-	do{ if ((ieee80211_debug_level & (level)) == (level))	\
-		{ 	\
-			int i;					\
-			u8* pdata = (u8*) data;			\
-			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
-			for(i=0; i<(int)(datalen); i++)			\
-			{						\
-				printk("%2x ", pdata[i]);		\
-				if ((i+1)%16 == 0) printk("\n");	\
-			}				\
-			printk("\n");			\
-		}					\
-	} while (0)
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
-#endif	/* CONFIG_IEEE80211_DEBUG */
-
-/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
-
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IEEE80211_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/ipw/debug_level
- *
- * you simply need to add your entry to the ipw_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
- *
- */
-
-#define IEEE80211_DL_INFO          (1<<0)
-#define IEEE80211_DL_WX            (1<<1)
-#define IEEE80211_DL_SCAN          (1<<2)
-#define IEEE80211_DL_STATE         (1<<3)
-#define IEEE80211_DL_MGMT          (1<<4)
-#define IEEE80211_DL_FRAG          (1<<5)
-#define IEEE80211_DL_EAP           (1<<6)
-#define IEEE80211_DL_DROP          (1<<7)
-
-#define IEEE80211_DL_TX            (1<<8)
-#define IEEE80211_DL_RX            (1<<9)
-
-#define IEEE80211_DL_HT		   (1<<10)  //HT
-#define IEEE80211_DL_BA		   (1<<11)  //ba
-#define IEEE80211_DL_TS		   (1<<12)  //TS
-#define IEEE80211_DL_QOS           (1<<13)
-#define IEEE80211_DL_REORDER	   (1<<14)
-#define IEEE80211_DL_IOT	   (1<<15)
-#define IEEE80211_DL_IPS	   (1<<16)
-#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
-#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
-#define IEEE80211_DL_ERR	   (1<<31)   //always open
-#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
-#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
-#define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
-
-#define IEEE80211_DEBUG_WX(f, a...)     IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
-#define IEEE80211_DEBUG_SCAN(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
-#define IEEE80211_DEBUG_STATE(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
-#define IEEE80211_DEBUG_MGMT(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
-#define IEEE80211_DEBUG_FRAG(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
-#define IEEE80211_DEBUG_EAP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
-#define IEEE80211_DEBUG_DROP(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
-#define IEEE80211_DEBUG_TX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
-#define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
-#define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
-
-#ifdef CONFIG_IEEE80211_DEBUG
-/* Added by Annie, 2005-11-22. */
-#define MAX_STR_LEN     64
-/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
-#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')
-#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
-                        if((_Comp) & level)   							\
-                        {                                                                       \
-                                int             __i;                                            \
-                                u8  buffer[MAX_STR_LEN];                                    	\
-                                int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
-                                memset(buffer, 0, MAX_STR_LEN);                      		\
-                                memcpy(buffer, (u8 *)_Ptr, length );            		\
-                                for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
-                                {                                                               \
-                                     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
-                                }                                                               \
-                                buffer[length] = '\0';                                          \
-                                printk("Rtl819x: ");                                         	\
-                                printk(_TitleString);                                         \
-                                printk(": %d, <%s>\n", _Len, buffer);                         \
-                        }
-#else
-#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
-#endif
-
-#include <linux/netdevice.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY		// enable iwspy support
-#endif
-#include <net/iw_handler.h>	// new driver API
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
-
-        u8    dsap;   /* always 0xAA */
-        u8    ssap;   /* always 0xAA */
-        u8    ctrl;   /* always 0x03 */
-        u8    oui[P80211_OUI_LEN];    /* organizational universal id */
-
-} __attribute__ ((packed));
-
-#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
-
-#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS)
-#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
-#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
-
-#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE)
-#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_LEAP 2
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_IBSS (1<<1)
-#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
-#define WLAN_CAPABILITY_PRIVACY (1<<4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
-#define WLAN_CAPABILITY_PBCC (1<<6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
-#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
-#define WLAN_CAPABILITY_QOS (1<<9)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
-
-/* 802.11g ERP information element */
-#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
-#define WLAN_ERP_USE_PROTECTION (1<<1)
-#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
-
-/* Status codes */
-enum ieee80211_statuscode {
-        WLAN_STATUS_SUCCESS = 0,
-        WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
-        WLAN_STATUS_CAPS_UNSUPPORTED = 10,
-        WLAN_STATUS_REASSOC_NO_ASSOC = 11,
-        WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
-        WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
-        WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
-        WLAN_STATUS_CHALLENGE_FAIL = 15,
-        WLAN_STATUS_AUTH_TIMEOUT = 16,
-        WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
-        WLAN_STATUS_ASSOC_DENIED_RATES = 18,
-        /* 802.11b */
-        WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
-        WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
-        WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
-        /* 802.11h */
-        WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
-        WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
-        WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
-        /* 802.11g */
-        WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
-        WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
-        /* 802.11i */
-        WLAN_STATUS_INVALID_IE = 40,
-        WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
-        WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
-        WLAN_STATUS_INVALID_AKMP = 43,
-        WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
-        WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
-        WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
-};
-
-/* Reason codes */
-enum ieee80211_reasoncode {
-        WLAN_REASON_UNSPECIFIED = 1,
-        WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
-        WLAN_REASON_DEAUTH_LEAVING = 3,
-        WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
-        WLAN_REASON_DISASSOC_AP_BUSY = 5,
-        WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
-        WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
-        WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
-        WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
-        /* 802.11h */
-        WLAN_REASON_DISASSOC_BAD_POWER = 10,
-        WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
-        /* 802.11i */
-        WLAN_REASON_INVALID_IE = 13,
-        WLAN_REASON_MIC_FAILURE = 14,
-        WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
-        WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
-        WLAN_REASON_IE_DIFFERENT = 17,
-        WLAN_REASON_INVALID_GROUP_CIPHER = 18,
-        WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
-        WLAN_REASON_INVALID_AKMP = 20,
-        WLAN_REASON_UNSUPP_RSN_VERSION = 21,
-        WLAN_REASON_INVALID_RSN_IE_CAP = 22,
-        WLAN_REASON_IEEE8021X_FAILED = 23,
-        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
-};
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-#define IEEE80211_CCK_MODULATION    (1<<0)
-#define IEEE80211_OFDM_MODULATION   (1<<1)
-
-#define IEEE80211_24GHZ_BAND     (1<<0)
-#define IEEE80211_52GHZ_BAND     (1<<1)
-
-#define IEEE80211_CCK_RATE_LEN  		4
-#define IEEE80211_CCK_RATE_1MB		        0x02
-#define IEEE80211_CCK_RATE_2MB		        0x04
-#define IEEE80211_CCK_RATE_5MB		        0x0B
-#define IEEE80211_CCK_RATE_11MB		        0x16
-#define IEEE80211_OFDM_RATE_LEN 		8
-#define IEEE80211_OFDM_RATE_6MB		        0x0C
-#define IEEE80211_OFDM_RATE_9MB		        0x12
-#define IEEE80211_OFDM_RATE_12MB		0x18
-#define IEEE80211_OFDM_RATE_18MB		0x24
-#define IEEE80211_OFDM_RATE_24MB		0x30
-#define IEEE80211_OFDM_RATE_36MB		0x48
-#define IEEE80211_OFDM_RATE_48MB		0x60
-#define IEEE80211_OFDM_RATE_54MB		0x6C
-#define IEEE80211_BASIC_RATE_MASK		0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK		(1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK		(1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK		(1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK		(1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK		(1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK		(1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK		(1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK		(1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK		(1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK		(1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK		(1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK		(1<<11)
-
-#define IEEE80211_CCK_RATES_MASK	        0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK	(IEEE80211_CCK_RATE_1MB_MASK | \
-	IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK	(IEEE80211_CCK_BASIC_RATES_MASK | \
-        IEEE80211_CCK_RATE_5MB_MASK | \
-        IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK		0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK	(IEEE80211_OFDM_RATE_6MB_MASK | \
-	IEEE80211_OFDM_RATE_12MB_MASK | \
-	IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK	(IEEE80211_OFDM_BASIC_RATES_MASK | \
-	IEEE80211_OFDM_RATE_9MB_MASK  | \
-	IEEE80211_OFDM_RATE_18MB_MASK | \
-	IEEE80211_OFDM_RATE_36MB_MASK | \
-	IEEE80211_OFDM_RATE_48MB_MASK | \
-	IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
-                                IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES	    8
-#define IEEE80211_NUM_CCK_RATES	            4
-#define IEEE80211_OFDM_SHIFT_MASK_A         4
-
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK		0x0c
-#define IEEE80211_FC0_TYPE_DATA		0x08
-#define IEEE80211_FC0_SUBTYPE_MASK	0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS	0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
-	(((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
-	 (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
-	u8 mac[ETH_ALEN];
-	u16 seq_num[17];
-	u16 frag_num[17];
-	unsigned long packet_time[17];
-	struct list_head list;
-};
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- *       information for frames received.  Not setting these will not cause
- *       any adverse affects. */
-struct ieee80211_rx_stats {
-#if 1
-	u32 mac_time[2];
-	s8 rssi;
-	u8 signal;
-	u8 noise;
-	u16 rate; /* in 100 kbps */
-	u8 received_channel;
-	u8 control;
-	u8 mask;
-	u8 freq;
-	u16 len;
-	u64 tsf;
-	u32 beacon_time;
-	u8 nic_type;
-	u16       Length;
-	//      u8        DataRate;      // In 0.5 Mbps
-	u8        SignalQuality; // in 0-100 index.
-	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
-	s8        RxPower; // in dBm Translate from PWdB
-	u8        SignalStrength; // in 0-100 index.
-	u16       bHwError:1;
-	u16       bCRC:1;
-	u16       bICV:1;
-	u16       bShortPreamble:1;
-	u16       Antenna:1;      //for rtl8185
-	u16       Decrypted:1;    //for rtl8185, rtl8187
-	u16       Wakeup:1;       //for rtl8185
-	u16       Reserved0:1;    //for rtl8185
-	u8        AGC;
-	u32       TimeStampLow;
-	u32       TimeStampHigh;
-	bool      bShift;
-	bool      bIsQosData;             // Added by Annie, 2005-12-22.
-	u8        UserPriority;
-
-	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
-	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
-	u8        RxDrvInfoSize;
-	u8        RxBufShift;
-	bool      bIsAMPDU;
-	bool      bFirstMPDU;
-	bool      bContainHTC;
-	bool      RxIs40MHzPacket;
-	u32       RxPWDBAll;
-	u8        RxMIMOSignalStrength[4];        // in 0~100 index
-	s8        RxMIMOSignalQuality[2];
-	bool      bPacketMatchBSSID;
-	bool      bIsCCK;
-	bool      bPacketToSelf;
-	//added by amy
-	u8*       virtual_address;
-	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
-	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
-	u16          fragoffset;                        // Data offset for this fragment
-	u16          ntotalfrag;
-	bool      	  bisrxaggrsubframe;
-	bool		  bPacketBeacon;	//cosa add for rssi
-	bool		  bToSelfBA;		//cosa add for rssi
-	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
-	u16		  Seq_Num;
-	u8		nTotalAggPkt;		// Number of aggregated packets.
-#endif
-
-};
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
-#define IEEE80211_FRAG_CACHE_LEN 4
-
-struct ieee80211_frag_entry {
-	unsigned long first_frag_time;
-	unsigned int seq;
-	unsigned int last_frag;
-	struct sk_buff *skb;
-	u8 src_addr[ETH_ALEN];
-	u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
-	unsigned int tx_unicast_frames;
-	unsigned int tx_multicast_frames;
-	unsigned int tx_fragments;
-	unsigned int tx_unicast_octets;
-	unsigned int tx_multicast_octets;
-	unsigned int tx_deferred_transmissions;
-	unsigned int tx_single_retry_frames;
-	unsigned int tx_multiple_retry_frames;
-	unsigned int tx_retry_limit_exceeded;
-	unsigned int tx_discards;
-	unsigned int rx_unicast_frames;
-	unsigned int rx_multicast_frames;
-	unsigned int rx_fragments;
-	unsigned int rx_unicast_octets;
-	unsigned int rx_multicast_octets;
-	unsigned int rx_fcs_errors;
-	unsigned int rx_discards_no_buffer;
-	unsigned int tx_discards_wrong_sa;
-	unsigned int rx_discards_undecryptable;
-	unsigned int rx_message_in_msg_fragments;
-	unsigned int rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_device;
-
-#include "ieee80211_crypt.h"
-
-#define SEC_KEY_1         (1<<0)
-#define SEC_KEY_2         (1<<1)
-#define SEC_KEY_3         (1<<2)
-#define SEC_KEY_4         (1<<3)
-#define SEC_ACTIVE_KEY    (1<<4)
-#define SEC_AUTH_MODE     (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL         (1<<7)
-#define SEC_ENABLED       (1<<8)
-#define SEC_ENCRYPT       (1<<9)
-
-#define SEC_LEVEL_0      0 /* None */
-#define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2      2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3      4 /* Level 2 + CCMP */
-
-#define SEC_ALG_NONE            0
-#define SEC_ALG_WEP             1
-#define SEC_ALG_TKIP            2
-#define SEC_ALG_CCMP            3
-
-#define WEP_KEYS 		4
-#define WEP_KEY_LEN		13
-#define SCM_KEY_LEN             32
-#define SCM_TEMPORAL_KEY_LENGTH 16
-
-struct ieee80211_security {
-	u16 active_key:2,
-            enabled:1,
-	    auth_mode:2,
-            auth_algo:4,
-            unicast_uses_group:1,
-	    encrypt:1;
-	u8 key_sizes[WEP_KEYS];
-	u8 keys[WEP_KEYS][SCM_KEY_LEN];
-	u8 level;
-	u16 flags;
-} __attribute__ ((packed));
-
-
-/*
- 802.11 data frame from AP
-      ,-------------------------------------------------------------------.
-Bytes |  2   |  2   |    6    |    6    |    6    |  2   | 0..2312 |   4  |
-      |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura |  DA/RA  |   TA    |    SA   | Sequ |  frame  |  fcs |
-      |      | tion | (BSSID) |         |         | ence |  data   |      |
-      `-------------------------------------------------------------------'
-Total: 28-2340 bytes
-*/
-
-/* Management Frame Information Element Types */
-enum ieee80211_mfie {
-        MFIE_TYPE_SSID = 0,
-        MFIE_TYPE_RATES = 1,
-        MFIE_TYPE_FH_SET = 2,
-        MFIE_TYPE_DS_SET = 3,
-        MFIE_TYPE_CF_SET = 4,
-        MFIE_TYPE_TIM = 5,
-        MFIE_TYPE_IBSS_SET = 6,
-        MFIE_TYPE_COUNTRY = 7,
-        MFIE_TYPE_HOP_PARAMS = 8,
-        MFIE_TYPE_HOP_TABLE = 9,
-        MFIE_TYPE_REQUEST = 10,
-        MFIE_TYPE_CHALLENGE = 16,
-        MFIE_TYPE_POWER_CONSTRAINT = 32,
-        MFIE_TYPE_POWER_CAPABILITY = 33,
-        MFIE_TYPE_TPC_REQUEST = 34,
-        MFIE_TYPE_TPC_REPORT = 35,
-        MFIE_TYPE_SUPP_CHANNELS = 36,
-        MFIE_TYPE_CSA = 37,
-        MFIE_TYPE_MEASURE_REQUEST = 38,
-        MFIE_TYPE_MEASURE_REPORT = 39,
-        MFIE_TYPE_QUIET = 40,
-        MFIE_TYPE_IBSS_DFS = 41,
-        MFIE_TYPE_ERP = 42,
-        MFIE_TYPE_RSN = 48,
-        MFIE_TYPE_RATES_EX = 50,
-        MFIE_TYPE_HT_CAP= 45,
-	 MFIE_TYPE_HT_INFO= 61,
-	 MFIE_TYPE_AIRONET=133,
-        MFIE_TYPE_GENERIC = 221,
-        MFIE_TYPE_QOS_PARAMETER = 222,
-};
-
-/* Minimal header; can be used for passing 802.11 frames with sufficient
- * information to determine what type of underlying data type is actually
- * stored in the data. */
-struct ieee80211_hdr {
-        __le16 frame_ctl;
-        __le16 duration_id;
-        u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_1addr {
-        __le16 frame_ctl;
-        __le16 duration_id;
-        u8 addr1[ETH_ALEN];
-        u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_2addr {
-        __le16 frame_ctl;
-        __le16 duration_id;
-        u8 addr1[ETH_ALEN];
-        u8 addr2[ETH_ALEN];
-        u8 payload[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_hdr_4addr {
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	__le16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-        u8 payload[0];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addrqos {
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	__le16 seq_ctl;
-        u8 payload[0];
-	__le16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_4addrqos {
-	__le16 frame_ctl;
-	__le16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
-	__le16 seq_ctl;
-	u8 addr4[ETH_ALEN];
-        u8 payload[0];
-	__le16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
-	u8 id;
-	u8 len;
-	u8 data[0];
-} __attribute__ ((packed));
-
-struct ieee80211_authentication {
-	struct ieee80211_hdr_3addr header;
-	__le16 algorithm;
-	__le16 transaction;
-	__le16 status;
-	/*challenge*/
-	struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc {
-        struct ieee80211_hdr_3addr header;
-        __le16 reason;
-} __attribute__ ((packed));
-
-struct ieee80211_probe_request {
-	struct ieee80211_hdr_3addr header;
-	/* SSID, supported rates */
-        struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_probe_response {
-	struct ieee80211_hdr_3addr header;
-	u32 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_request_frame {
-	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_reassoc_request_frame {
-	struct ieee80211_hdr_3addr header;
-	__le16 capability;
-	__le16 listen_interval;
-	u8 current_ap[ETH_ALEN];
-	/* SSID, supported rates, RSN */
-        struct ieee80211_info_element info_element[0];
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_response_frame {
-	struct ieee80211_hdr_3addr header;
-	__le16 capability;
-	__le16 status;
-	__le16 aid;
-	struct ieee80211_info_element info_element[0]; /* supported rates */
-} __attribute__ ((packed));
-
-struct ieee80211_txb {
-	u8 nr_frags;
-	u8 encrypted;
-	u8 queue_index;
-	u8 rts_included;
-	u16 reserved;
-	__le16 frag_size;
-	__le16 payload_size;
-	struct sk_buff *fragments[0];
-};
-
-#define MAX_TX_AGG_COUNT		  16
-struct ieee80211_drv_agg_txb {
-	u8 nr_drv_agg_frames;
-	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
-}__attribute__((packed));
-
-#define MAX_SUBFRAME_COUNT 		  64
-struct ieee80211_rxb {
-	u8 nr_subframes;
-	struct sk_buff *subframes[MAX_SUBFRAME_COUNT];
-	u8 dst[ETH_ALEN];
-	u8 src[ETH_ALEN];
-}__attribute__((packed));
-
-typedef union _frameqos {
-	u16 shortdata;
-	u8  chardata[2];
-	struct {
-		u16 tid:4;
-		u16 eosp:1;
-		u16 ack_policy:2;
-		u16 reserved:1;
-		u16 txop:8;
-	}field;
-}frameqos,*pframeqos;
-
-/* SWEEP TABLE ENTRIES NUMBER*/
-#define MAX_SWEEP_TAB_ENTRIES		  42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
-/* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates.  Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH                  ((u8)12)
-#define MAX_RATES_EX_LENGTH               ((u8)16)
-#define MAX_NETWORK_COUNT                  128
-
-#define MAX_CHANNEL_NUMBER                 161
-#define IEEE80211_SOFTMAC_SCAN_TIME	   100
-//(HZ / 2)
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH                 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM    (1<<1)
-#define NETWORK_HAS_CCK     (1<<2)
-
-/* QoS structure */
-#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
-#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
-#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
-                                         NETWORK_HAS_QOS_INFORMATION)
-/* 802.11h */
-#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
-#define NETWORK_HAS_CSA                 (1<<6)
-#define NETWORK_HAS_QUIET               (1<<7)
-#define NETWORK_HAS_IBSS_DFS            (1<<8)
-#define NETWORK_HAS_TPC_REPORT          (1<<9)
-
-#define NETWORK_HAS_ERP_VALUE           (1<<10)
-
-#define QOS_QUEUE_NUM                   4
-#define QOS_OUI_LEN                     3
-#define QOS_OUI_TYPE                    2
-#define QOS_ELEMENT_ID                  221
-#define QOS_OUI_INFO_SUB_TYPE           0
-#define QOS_OUI_PARAM_SUB_TYPE          1
-#define QOS_VERSION_1                   1
-#define QOS_AIFSN_MIN_VALUE             2
-#if 1
-struct ieee80211_qos_information_element {
-        u8 elementID;
-        u8 length;
-        u8 qui[QOS_OUI_LEN];
-        u8 qui_type;
-        u8 qui_subtype;
-        u8 version;
-        u8 ac_info;
-} __attribute__ ((packed));
-
-struct ieee80211_qos_ac_parameter {
-        u8 aci_aifsn;
-        u8 ecw_min_max;
-        __le16 tx_op_limit;
-} __attribute__ ((packed));
-
-struct ieee80211_qos_parameter_info {
-        struct ieee80211_qos_information_element info_element;
-        u8 reserved;
-        struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM];
-} __attribute__ ((packed));
-
-struct ieee80211_qos_parameters {
-        __le16 cw_min[QOS_QUEUE_NUM];
-        __le16 cw_max[QOS_QUEUE_NUM];
-        u8 aifs[QOS_QUEUE_NUM];
-        u8 flag[QOS_QUEUE_NUM];
-        __le16 tx_op_limit[QOS_QUEUE_NUM];
-} __attribute__ ((packed));
-
-struct ieee80211_qos_data {
-        struct ieee80211_qos_parameters parameters;
-        int active;
-        int supported;
-        u8 param_count;
-        u8 old_param_count;
-};
-
-struct ieee80211_tim_parameters {
-        u8 tim_count;
-        u8 tim_period;
-} __attribute__ ((packed));
-
-//#else
-struct ieee80211_wmm_ac_param {
-	u8 ac_aci_acm_aifsn;
-	u8 ac_ecwmin_ecwmax;
-	u16 ac_txop_limit;
-};
-
-struct ieee80211_wmm_ts_info {
-	u8 ac_dir_tid;
-	u8 ac_up_psb;
-	u8 reserved;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_tspec_elem {
-	struct ieee80211_wmm_ts_info ts_info;
-	u16 norm_msdu_size;
-	u16 max_msdu_size;
-	u32 min_serv_inter;
-	u32 max_serv_inter;
-	u32 inact_inter;
-	u32 suspen_inter;
-	u32 serv_start_time;
-	u32 min_data_rate;
-	u32 mean_data_rate;
-	u32 peak_data_rate;
-	u32 max_burst_size;
-	u32 delay_bound;
-	u32 min_phy_rate;
-	u16 surp_band_allow;
-	u16 medium_time;
-}__attribute__((packed));
-#endif
-enum eap_type {
-	EAP_PACKET = 0,
-	EAPOL_START,
-	EAPOL_LOGOFF,
-	EAPOL_KEY,
-	EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
-	[EAP_PACKET]		= "EAP-Packet",
-	[EAPOL_START]		= "EAPOL-Start",
-	[EAPOL_LOGOFF]		= "EAPOL-Logoff",
-	[EAPOL_KEY]		= "EAPOL-Key",
-	[EAPOL_ENCAP_ASF_ALERT]	= "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
-	return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-//added by amy for reorder
-static inline u8 Frame_QoSTID(u8* buf)
-{
-	struct ieee80211_hdr_3addr *hdr;
-	u16 fc;
-	hdr = (struct ieee80211_hdr_3addr *)buf;
-	fc = le16_to_cpu(hdr->frame_ctl);
-	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
-}
-
-//added by amy for reorder
-
-struct eapol {
-	u8 snap[6];
-	u16 ethertype;
-	u8 version;
-	u8 type;
-	u16 length;
-} __attribute__ ((packed));
-
-struct ieee80211_softmac_stats{
-	unsigned int rx_ass_ok;
-	unsigned int rx_ass_err;
-	unsigned int rx_probe_rq;
-	unsigned int tx_probe_rs;
-	unsigned int tx_beacons;
-	unsigned int rx_auth_rq;
-	unsigned int rx_auth_rs_ok;
-	unsigned int rx_auth_rs_err;
-	unsigned int tx_auth_rq;
-	unsigned int no_auth_rs;
-	unsigned int no_ass_rs;
-	unsigned int tx_ass_rq;
-	unsigned int rx_ass_rq;
-	unsigned int tx_probe_rq;
-	unsigned int reassoc;
-	unsigned int swtxstop;
-	unsigned int swtxawake;
-	unsigned char CurrentShowTxate;
-	unsigned char last_packet_rate;
-	unsigned int txretrycount;
-};
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-struct ieee80211_info_element_hdr {
-	u8 id;
-	u8 len;
-} __attribute__ ((packed));
-
-/*
- * These are the data types that can make up management packets
- *
-	u16 auth_algorithm;
-	u16 auth_sequence;
-	u16 beacon_interval;
-	u16 capability;
-	u8 current_ap[ETH_ALEN];
-	u16 listen_interval;
-	struct {
-		u16 association_id:14, reserved:2;
-	} __attribute__ ((packed));
-	u32 time_stamp[2];
-	u16 reason;
-	u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len  (WMM_all_frame << 4)
-#define IEEE80211_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-
-//added by David for QoS 2006/6/30
-//#define WMM_Hang_8187
-#ifdef WMM_Hang_8187
-#undef WMM_Hang_8187
-#endif
-
-#define WME_AC_BK   0x00
-#define WME_AC_BE   0x01
-#define WME_AC_VI   0x02
-#define WME_AC_VO   0x03
-#define WME_ACI_MASK 0x03
-#define WME_AIFSN_MASK 0x03
-#define WME_AC_PRAM_LEN 16
-
-#define MAX_RECEIVE_BUFFER_SIZE 9100
-
-//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
-//#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1))
-#if 1
-#define UP2AC(up) (		   \
-	((up) < 1) ? WME_AC_BE : \
-	((up) < 3) ? WME_AC_BK : \
-	((up) < 4) ? WME_AC_BE : \
-	((up) < 6) ? WME_AC_VI : \
-	WME_AC_VO)
-#endif
-//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
-#define AC2UP(_ac)	(       \
-	((_ac) == WME_AC_VO) ? 6 : \
-	((_ac) == WME_AC_VI) ? 5 : \
-	((_ac) == WME_AC_BK) ? 1 : \
-	0)
-
-#define	ETHER_ADDR_LEN		6	/* length of an Ethernet address */
-#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
-
-struct	ether_header {
-	u8 ether_dhost[ETHER_ADDR_LEN];
-	u8 ether_shost[ETHER_ADDR_LEN];
-	u16 ether_type;
-} __attribute__((packed));
-
-#ifndef ETHERTYPE_PAE
-#define	ETHERTYPE_PAE	0x888e		/* EAPOL PAE/802.1x */
-#endif
-#ifndef ETHERTYPE_IP
-#define	ETHERTYPE_IP	0x0800		/* IP protocol */
-#endif
-
-typedef struct _bss_ht{
-
-	bool				support_ht;
-
-	// HT related elements
-	u8					ht_cap_buf[32];
-	u16					ht_cap_len;
-	u8					ht_info_buf[32];
-	u16					ht_info_len;
-
-	HT_SPEC_VER			ht_spec_ver;
-	//HT_CAPABILITY_ELE			bdHTCapEle;
-	//HT_INFORMATION_ELE		bdHTInfoEle;
-
-	bool				aggregation;
-	bool				long_slot_time;
-}bss_ht, *pbss_ht;
-
-typedef enum _erp_t{
-	ERP_NonERPpresent	= 0x01,
-	ERP_UseProtection	= 0x02,
-	ERP_BarkerPreambleMode = 0x04,
-} erp_t;
-
-
-struct ieee80211_network {
-	/* These entries are used to identify a unique network */
-	u8 bssid[ETH_ALEN];
-	u8 channel;
-	/* Ensure null-terminated for any debug msgs */
-	u8 ssid[IW_ESSID_MAX_SIZE + 1];
-	u8 ssid_len;
-#if 1
-        struct ieee80211_qos_data qos_data;
-#else
-       // Qos related. Added by Annie, 2005-11-01.
-        BSS_QOS   BssQos;
-#endif
-
-	//added by amy for LEAP
-	bool	bWithAironetIE;
-	bool	bCkipSupported;
-	bool	bCcxRmEnable;
-	u16 	CcxRmState[2];
-	// CCXv4 S59, MBSSID.
-	bool	bMBssidValid;
-	u8	MBssidMask;
-	u8	MBssid[6];
-	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
-	bool	bWithCcxVerNum;
-	u8	BssCcxVerNumber;
-	/* These are network statistics */
-	struct ieee80211_rx_stats stats;
-	u16 capability;
-	u8  rates[MAX_RATES_LENGTH];
-	u8  rates_len;
-	u8  rates_ex[MAX_RATES_EX_LENGTH];
-	u8  rates_ex_len;
-	unsigned long last_scanned;
-	u8  mode;
-	u32 flags;
-	u32 last_associate;
-	u32 time_stamp[2];
-	u16 beacon_interval;
-	u16 listen_interval;
-	u16 atim_window;
-	u8  erp_value;
-	u8  wpa_ie[MAX_WPA_IE_LEN];
-	size_t wpa_ie_len;
-	u8  rsn_ie[MAX_WPA_IE_LEN];
-	size_t rsn_ie_len;
-
-        struct ieee80211_tim_parameters tim;
-	u8  dtim_period;
-	u8  dtim_data;
-	u32 last_dtim_sta_time[2];
-
-        //appeded for QoS
-        u8 wmm_info;
-        struct ieee80211_wmm_ac_param wmm_param[4];
-        u8 QoS_Enable;
-#ifdef THOMAS_TURBO
-	u8 Turbo_Enable;//enable turbo mode, added by thomas
-#endif
-#ifdef ENABLE_DOT11D
-	u16 CountryIeLen;
-	u8 CountryIeBuf[MAX_IE_LEN];
-#endif
-        // HT Related, by amy, 2008.04.29
-	BSS_HT	bssht;
-	// Add to handle broadcom AP management frame CCK rate.
-	bool broadcom_cap_exist;
-	bool realtek_cap_exit;
-	bool marvell_cap_exist;
-	bool ralink_cap_exist;
-	bool atheros_cap_exist;
-	bool cisco_cap_exist;
-	bool unknown_cap_exist;
-//	u8	berp_info;
-	bool	berp_info_valid;
-	bool buseprotection;
-	//put at the end of the structure.
-	struct list_head list;
-};
-
-#if 1
-enum ieee80211_state {
-
-	/* the card is not linked at all */
-	IEEE80211_NOLINK = 0,
-
-	/* IEEE80211_ASSOCIATING* are for BSS client mode
-	 * the driver shall not perform RX filtering unless
-	 * the state is LINKED.
-	 * The driver shall just check for the state LINKED and
-	 * defaults to NOLINK for ALL the other states (including
-	 * LINKED_SCANNING)
-	 */
-
-	/* the association procedure will start (wq scheduling)*/
-	IEEE80211_ASSOCIATING,
-	IEEE80211_ASSOCIATING_RETRY,
-
-	/* the association procedure is sending AUTH request*/
-	IEEE80211_ASSOCIATING_AUTHENTICATING,
-
-	/* the association procedure has successfully authentcated
-	 * and is sending association request
-	 */
-	IEEE80211_ASSOCIATING_AUTHENTICATED,
-
-	/* the link is ok. the card associated to a BSS or linked
-	 * to a ibss cell or acting as an AP and creating the bss
-	 */
-	IEEE80211_LINKED,
-
-	/* same as LINKED, but the driver shall apply RX filter
-	 * rules as we are in NO_LINK mode. As the card is still
-	 * logically linked, but it is doing a syncro site survey
-	 * then it will be back to LINKED state.
-	 */
-	IEEE80211_LINKED_SCANNING,
-
-};
-#else
-enum ieee80211_state {
-        IEEE80211_UNINITIALIZED = 0,
-        IEEE80211_INITIALIZED,
-        IEEE80211_ASSOCIATING,
-        IEEE80211_ASSOCIATED,
-        IEEE80211_AUTHENTICATING,
-        IEEE80211_AUTHENTICATED,
-        IEEE80211_SHUTDOWN
-};
-#endif
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-#define CFG_IEEE80211_RTS (1<<2)
-
-#define IEEE80211_24GHZ_MIN_CHANNEL 1
-#define IEEE80211_24GHZ_MAX_CHANNEL 14
-#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
-                                  IEEE80211_24GHZ_MIN_CHANNEL + 1)
-
-#define IEEE80211_52GHZ_MIN_CHANNEL 34
-#define IEEE80211_52GHZ_MAX_CHANNEL 165
-#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
-                                  IEEE80211_52GHZ_MIN_CHANNEL + 1)
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
-extern inline int is_multicast_ether_addr(const u8 *addr)
-{
-        return ((addr[0] != 0xff) && (0x01 & addr[0]));
-}
-#endif
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
-extern inline int is_broadcast_ether_addr(const u8 *addr)
-{
-	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
-		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
-}
-#endif
-
-typedef struct tx_pending_t{
-	int frag;
-	struct ieee80211_txb *txb;
-}tx_pending_t;
-
-typedef struct _bandwidth_autoswitch
-{
-	long threshold_20Mhzto40Mhz;
-	long	threshold_40Mhzto20Mhz;
-	bool bforced_tx20Mhz;
-	bool bautoswitch_enable;
-}bandwidth_autoswitch,*pbandwidth_autoswitch;
-
-
-//added by amy for order
-
-#define REORDER_WIN_SIZE	128
-#define REORDER_ENTRY_NUM	128
-typedef struct _RX_REORDER_ENTRY
-{
-	struct list_head	List;
-	u16			SeqNum;
-	struct ieee80211_rxb* prxb;
-} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
-//added by amy for order
-typedef enum _Fsync_State{
-	Default_Fsync,
-	HW_Fsync,
-	SW_Fsync
-}Fsync_State;
-
-// Power save mode configured.
-typedef	enum _RT_PS_MODE
-{
-	eActive,	// Active/Continuous access.
-	eMaxPs,		// Max power save mode.
-	eFastPs		// Fast power save mode.
-}RT_PS_MODE;
-
-typedef enum _IPS_CALLBACK_FUNCION
-{
-	IPS_CALLBACK_NONE = 0,
-	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
-	IPS_CALLBACK_JOIN_REQUEST = 2,
-}IPS_CALLBACK_FUNCION;
-
-typedef enum _RT_JOIN_ACTION{
-	RT_JOIN_INFRA   = 1,
-	RT_JOIN_IBSS  = 2,
-	RT_START_IBSS = 3,
-	RT_NO_ACTION  = 4,
-}RT_JOIN_ACTION;
-
-typedef struct _IbssParms{
-	u16   atimWin;
-}IbssParms, *PIbssParms;
-#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
-
-// RF state.
-typedef	enum _RT_RF_POWER_STATE
-{
-	eRfOn,
-	eRfSleep,
-	eRfOff
-}RT_RF_POWER_STATE;
-
-typedef struct _RT_POWER_SAVE_CONTROL
-{
-
-	//
-	// Inactive Power Save(IPS) : Disable RF when disconnected
-	//
-	bool				bInactivePs;
-	bool				bIPSModeBackup;
-	bool				bHaltAdapterClkRQ;
-	bool				bSwRfProcessing;
-	RT_RF_POWER_STATE	eInactivePowerState;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	struct work_struct 	InactivePsWorkItem;
-#else
-	struct tq_struct	InactivePsWorkItem;
-#endif
-	struct timer_list	InactivePsTimer;
-
-	// Return point for join action
-	IPS_CALLBACK_FUNCION	ReturnPoint;
-
-	// Recored Parameters for rescheduled JoinRequest
-	bool				bTmpBssDesc;
-	RT_JOIN_ACTION		tmpJoinAction;
-	struct ieee80211_network tmpBssDesc;
-
-	// Recored Parameters for rescheduled MgntLinkRequest
-	bool				bTmpScanOnly;
-	bool				bTmpActiveScan;
-	bool				bTmpFilterHiddenAP;
-	bool				bTmpUpdateParms;
-	u8					tmpSsidBuf[33];
-	OCTET_STRING			tmpSsid2Scan;
-	bool				bTmpSsid2Scan;
-	u8					tmpNetworkType;
-	u8					tmpChannelNumber;
-	u16					tmpBcnPeriod;
-	u8					tmpDtimPeriod;
-	u16					tmpmCap;
-	OCTET_STRING			tmpSuppRateSet;
-	u8					tmpSuppRateBuf[MAX_NUM_RATES];
-	bool				bTmpSuppRate;
-	IbssParms				tmpIbpm;
-	bool				bTmpIbpm;
-
-	//
-	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
-	//
-	bool				bLeisurePs;
-	u32				PowerProfile;
-	u8				LpsIdleCount;
-	u8				RegMaxLPSAwakeIntvl;
-	u8				LPSAwakeIntvl;
-
-	//RF OFF Level
-	u32				CurPsLevel;
-	u32				RegRfPsLevel;
-
-	//Fw Control LPS
-	bool				bFwCtrlLPS;
-	u8				FWCtrlPSMode;
-
-	//2009.01.01 added by tynli
-	// Record if there is a link request in IPS RF off progress.
-	bool				LinkReqInIPSRFOffPgs;
-	// To make sure that connect info should be executed, so we set the bit to filter the link info which comes after the connect info.
-	bool				BufConnectinfoBefore;
-
-}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
-
-typedef u32 RT_RF_CHANGE_SOURCE;
-#define RF_CHANGE_BY_SW BIT31
-#define RF_CHANGE_BY_HW BIT30
-#define RF_CHANGE_BY_PS BIT29
-#define RF_CHANGE_BY_IPS BIT28
-#define RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
-
-#ifdef ENABLE_DOT11D
-typedef enum
-{
-	COUNTRY_CODE_FCC = 0,
-	COUNTRY_CODE_IC = 1,
-	COUNTRY_CODE_ETSI = 2,
-	COUNTRY_CODE_SPAIN = 3,
-	COUNTRY_CODE_FRANCE = 4,
-	COUNTRY_CODE_MKK = 5,
-	COUNTRY_CODE_MKK1 = 6,
-	COUNTRY_CODE_ISRAEL = 7,
-	COUNTRY_CODE_TELEC,
-	COUNTRY_CODE_MIC,
-	COUNTRY_CODE_GLOBAL_DOMAIN
-}country_code_type_t;
-#endif
-	// Firmware realted CMD IO.
-typedef	enum _FW_CMD_IO_TYPE{
-	FW_CMD_DIG_ENABLE = 0, // For DIG DM
-	FW_CMD_DIG_DISABLE = 1,
-	FW_CMD_DIG_HALT = 2,
-	FW_CMD_DIG_RESUME = 3,
-	FW_CMD_HIGH_PWR_ENABLE = 4, // For High Power DM
-	FW_CMD_HIGH_PWR_DISABLE = 5,
-	FW_CMD_RA_RESET = 6, // For Rate adaptive DM
-	FW_CMD_RA_ACTIVE= 7,
-	FW_CMD_RA_REFRESH_N= 8,
-	FW_CMD_RA_REFRESH_BG= 9,
-	FW_CMD_IQK_ENABLE = 10, // For FW supported IQK
-	FW_CMD_TXPWR_TRACK_ENABLE = 11,	// Tx power tracking switch
-	FW_CMD_TXPWR_TRACK_DISABLE = 12,	// Tx power tracking switch
-	FW_CMD_PAUSE_DM_BY_SCAN = 13,
-	FW_CMD_RESUME_DM_BY_SCAN = 14,
-	FW_CMD_MID_HIGH_PWR_ENABLE = 15,
-	FW_CMD_LPS_ENTER = 16,			// Indifate firmware that driver enters LPS, For PS-Poll hardware bug
-	FW_CMD_LPS_LEAVE = 17,			// Indicate firmware that driver leave LPS, 2009/1/4, by Emily
-}FW_CMD_IO_TYPE,*PFW_CMD_IO_TYPE;
-#define RT_MAX_LD_SLOT_NUM	10
-typedef struct _RT_LINK_DETECT_T{
-
-	u32				NumRecvBcnInPeriod;
-	u32				NumRecvDataInPeriod;
-
-	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
-	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
-	u16				SlotNum;	// number of CheckForHang period to determine link status
-	u16				SlotIndex;
-
-	u32				NumTxOkInPeriod;
-	u32				NumRxOkInPeriod;
-	bool				bBusyTraffic;
-}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
-
-
-struct ieee80211_device {
-	struct net_device *dev;
-        struct ieee80211_security sec;
-
-	//hw security related
-//	u8 hwsec_support; //support?
-	u8 hwsec_active;  //hw security active.
-	bool is_silent_reset;
-	bool is_roaming;
-	bool ieee_up;
-	//added by amy
-	bool bSupportRemoteWakeUp;
-	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
-	bool actscanning;
-	//added by amy 090313
-	bool be_scan_inprogress;
-	bool beinretry;
-	RT_RF_POWER_STATE		eRFPowerState;
-	RT_RF_CHANGE_SOURCE	RfOffReason;
-	bool is_set_key;
-	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
-
-	//11n HT below
-	PRT_HIGH_THROUGHPUT	pHTInfo;
-	//struct timer_list		SwBwTimer;
-//	spinlock_t chnlop_spinlock;
-	spinlock_t bw_spinlock;
-
-	spinlock_t reorder_spinlock;
-	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
-	//the way fill this is the same as in the IE
-	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
-	u8	dot11HTOperationalRateSet[16];		//use RATR format
-	u8	RegHTSuppRateSet[16];
-	u8				HTCurrentOperaRate;
-	u8				HTHighestOperaRate;
-	//wb added for rate operation mode to firmware
-	u8	bTxDisableRateFallBack;
-	u8 	bTxUseDriverAssingedRate;
-	atomic_t	atm_chnlop;
-	atomic_t	atm_swbw;
-//	u8	HTHighestOperaRate;
-//	u8 	HTCurrentOperaRate;
-
-	// 802.11e and WMM Traffic Stream Info (TX)
-	struct list_head		Tx_TS_Admit_List;
-	struct list_head		Tx_TS_Pending_List;
-	struct list_head		Tx_TS_Unused_List;
-	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
-	// 802.11e and WMM Traffic Stream Info (RX)
-	struct list_head		Rx_TS_Admit_List;
-	struct list_head		Rx_TS_Pending_List;
-	struct list_head		Rx_TS_Unused_List;
-	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
-//#ifdef TO_DO_LIST
-	RX_REORDER_ENTRY	RxReorderEntry[128];
-	struct list_head		RxReorder_Unused_List;
-//#endif
-	// Qos related. Added by Annie, 2005-11-01.
-//	PSTA_QOS			pStaQos;
-	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
-
-
-	/* Bookkeeping structures */
-	struct net_device_stats stats;
-	struct ieee80211_stats ieee_stats;
-	struct ieee80211_softmac_stats softmac_stats;
-
-	/* Probe / Beacon management */
-	struct list_head network_free_list;
-	struct list_head network_list;
-	struct ieee80211_network *networks;
-	int scans;
-	int scan_age;
-
-	int iw_mode; /* operating mode (IW_MODE_*) */
-	struct iw_spy_data spy_data;
-
-	spinlock_t lock;
-	spinlock_t wpax_suitlist_lock;
-
-	int tx_headroom; /* Set to size of any additional room needed at front
-			  * of allocated Tx SKBs */
-	u32 config;
-
-	/* WEP and other encryption related settings at the device level */
-	int open_wep; /* Set to 1 to allow unencrypted frames */
-	int auth_mode;
-	int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
-				 * WEP key changes */
-
-	/* If the host performs {en,de}cryption, then set to 1 */
-	int host_encrypt;
-	int host_encrypt_msdu;
-	int host_decrypt;
-        /* host performs multicast decryption */
-        int host_mc_decrypt;
-
-        /* host should strip IV and ICV from protected frames */
-        /* meaningful only when hardware decryption is being used */
-        int host_strip_iv_icv;
-
-        int host_open_frag;
-        int host_build_iv;
-	int ieee802_1x; /* is IEEE 802.1X used */
-
-	/* WPA data */
-	bool bHalfWirelessN24GMode;
-	int wpa_enabled;
-	int drop_unencrypted;
-	int tkip_countermeasures;
-	int privacy_invoked;
-	size_t wpa_ie_len;
-	u8 *wpa_ie;
-	u8 ap_mac_addr[6];
-	u16 pairwise_key_type;
-	u16 group_key_type;
-	struct list_head crypt_deinit_list;
-	struct ieee80211_crypt_data *crypt[WEP_KEYS];
-	int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
-	struct timer_list crypt_deinit_timer;
-        int crypt_quiesced;
-
-	int bcrx_sta_key; /* use individual keys to override default keys even
-			   * with RX of broad/multicast frames */
-
-	/* Fragmentation structures */
-	// each streaming contain a entry
-	struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
-	unsigned int frag_next_idx[17];
-	u16 fts; /* Fragmentation Threshold */
-#define DEFAULT_RTS_THRESHOLD 2346U
-#define MIN_RTS_THRESHOLD 1
-#define MAX_RTS_THRESHOLD 2346U
-        u16 rts; /* RTS threshold */
-
-        /* Association info */
-        u8 bssid[ETH_ALEN];
-
-	/* This stores infos for the current network.
-	 * Either the network we are associated in INFRASTRUCTURE
-	 * or the network that we are creating in MASTER mode.
-	 * ad-hoc is a mixture ;-).
-	 * Note that in infrastructure mode, even when not associated,
-	 * fields bssid and essid may be valid (if wpa_set and essid_set
-	 * are true) as thy carry the value set by the user via iwconfig
-	 */
-	struct ieee80211_network current_network;
-
-	enum ieee80211_state state;
-
-	int short_slot;
-	int reg_mode;
-	int mode;       /* A, B, G */
-	int modulation; /* CCK, OFDM */
-	int freq_band;  /* 2.4Ghz, 5.2Ghz, Mixed */
-	int abg_true;   /* ABG flag              */
-
-	/* used for forcing the ibss workqueue to terminate
-	 * without wait for the syncro scan to terminate
-	 */
-	short sync_scan_hurryup;
-	u16 scan_watch_dog;
-        int perfect_rssi;
-        int worst_rssi;
-
-        u16 prev_seq_ctl;       /* used to drop duplicate frames */
-
-	/* map of allowed channels. 0 is dummy */
-	// FIXME: remeber to default to a basic channel plan depending of the PHY type
-#ifdef ENABLE_DOT11D
-	void* pDot11dInfo;
-	bool bGlobalDomain;
-#else
-	int channel_map[MAX_CHANNEL_NUMBER+1];
-#endif
-	int rate;       /* current rate */
-	int basic_rate;
-	//FIXME: pleace callback, see if redundant with softmac_features
-	short active_scan;
-
-	/* this contains flags for selectively enable softmac support */
-	u16 softmac_features;
-
-	/* if the sequence control field is not filled by HW */
-	u16 seq_ctrl[5];
-
-	/* association procedure transaction sequence number */
-	u16 associate_seq;
-
-	/* AID for RTXed association responses */
-	u16 assoc_id;
-
-	/* power save mode related*/
-	u8 ack_tx_to_ieee;
-	short ps;
-	short sta_sleep;
-	int ps_timeout;
-	int ps_period;
-	struct tasklet_struct ps_task;
-	u32 ps_th;
-	u32 ps_tl;
-
-	short raw_tx;
-	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
-	short queue_stop;
-	short scanning;
-	short proto_started;
-
-	struct semaphore wx_sem;
-	struct semaphore scan_sem;
-
-	spinlock_t mgmt_tx_lock;
-	spinlock_t beacon_lock;
-
-	short beacon_txing;
-
-	short wap_set;
-	short ssid_set;
-
-	u8  wpax_type_set;    //{added by David, 2006.9.28}
-	u32 wpax_type_notify; //{added by David, 2006.9.26}
-
-	/* QoS related flag */
-	char init_wmmparam_flag;
-	/* set on initialization */
-	u8  qos_support;
-
-	/* for discarding duplicated packets in IBSS */
-	struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
-	/* for discarding duplicated packets in BSS */
-	u16 last_rxseq_num[17]; /* rx seq previous per-tid */
-	u16 last_rxfrag_num[17];/* tx frag previous per-tid */
-	unsigned long last_packet_time[17];
-
-	/* for PS mode */
-	unsigned long last_rx_ps_time;
-
-	/* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
-	struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
-	int mgmt_queue_head;
-	int mgmt_queue_tail;
-//{ added for rtl819x
-#define IEEE80211_QUEUE_LIMIT 128
-	u8 AsocRetryCount;
-	unsigned int hw_header;
-	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
-	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE];
-	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE];
-	u32	sta_edca_param[4];
-	bool aggregation;
-	// Enable/Disable Rx immediate BA capability.
-	bool enable_rx_imm_BA;
-	bool bibsscoordinator;
-
-	//+by amy for DM ,080515
-	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
-	bool	bdynamic_txpower_enable;
-
-	bool bCTSToSelfEnable;
-	u8 	CTSToSelfTH;
-
-	u32 	fsync_time_interval;
-	u32	fsync_rate_bitmap;
-	u8	fsync_rssi_threshold;
-	bool	bfsync_enable;
-
-	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval
-	u32	fsync_firstdiff_ratethreshold;		// low threshold
-	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
-	Fsync_State			fsync_state;
-	bool		bis_any_nonbepkts;
-	//20Mhz 40Mhz AutoSwitch Threshold
-	bandwidth_autoswitch bandwidth_auto_switch;
-	//for txpower tracking
-	bool FwRWRF;
-
-	//added by amy for AP roaming
-	RT_LINK_DETECT_T	LinkDetectInfo;
-        //added by amy for ps
-	RT_POWER_SAVE_CONTROL	PowerSaveControl;
-//}
-	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
-	struct  tx_pending_t tx_pending;
-
-	/* used if IEEE_SOFTMAC_ASSOCIATE is set */
-	struct timer_list associate_timer;
-
-	/* used if IEEE_SOFTMAC_BEACONS is set */
-	struct timer_list beacon_timer;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-        struct work_struct associate_complete_wq;
-        struct work_struct associate_procedure_wq;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-        struct delayed_work softmac_scan_wq;
-        struct delayed_work associate_retry_wq;
-	 struct delayed_work start_ibss_wq;
-	 struct delayed_work hw_wakeup_wq;
-	struct delayed_work hw_sleep_wq;
-	struct delayed_work link_change_wq;
-#else
-        struct work_struct softmac_scan_wq;
-        struct work_struct associate_retry_wq;
-	struct work_struct start_ibss_wq;
-	struct work_struct hw_wakeup_wq;
-	struct work_struct hw_sleep_wq;
-	struct work_struct link_change_wq;
-#endif
-        struct work_struct wx_sync_scan_wq;
-        struct workqueue_struct *wq;
-#else
-	/* used for periodly scan */
-	struct timer_list scan_timer;
-
-	struct tq_struct associate_complete_wq;
-	struct tq_struct associate_retry_wq;
-	struct tq_struct start_ibss_wq;
-	struct tq_struct associate_procedure_wq;
-	struct tq_struct softmac_scan_wq;
-	struct tq_struct wx_sync_scan_wq;
-	struct tq_struct hw_wakeup_wq;
-	struct tq_struct hw_sleep_wq;
-	struct tq_struct link_change_wq;
-
-#endif
-        // Qos related. Added by Annie, 2005-11-01.
-        //STA_QOS  StaQos;
-
-        //u32 STA_EDCA_PARAM[4];
-	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
-
-
-	/* Callback functions */
-	void (*set_security)(struct net_device *dev,
-			     struct ieee80211_security *sec);
-
-	/* Used to TX data frame by using txb structs.
-	 * this is not used if in the softmac_features
-	 * is set the flag IEEE_SOFTMAC_TX_QUEUE
-	 */
-	int (*hard_start_xmit)(struct ieee80211_txb *txb,
-			       struct net_device *dev);
-
-	int (*reset_port)(struct net_device *dev);
-        int (*is_queue_full) (struct net_device * dev, int pri);
-
-        int (*handle_management) (struct net_device * dev,
-                                  struct ieee80211_network * network, u16 type);
-        int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
-
-	/* Softmac-generated frames (mamagement) are TXed via this
-	 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
-	 * not set. As some cards may have different HW queues that
-	 * one might want to use for data and management frames
-	 * the option to have two callbacks might be useful.
-	 * This fucntion can't sleep.
-	 */
-	int (*softmac_hard_start_xmit)(struct sk_buff *skb,
-			       struct net_device *dev);
-
-	/* used instead of hard_start_xmit (not softmac_hard_start_xmit)
-	 * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
-	 * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
-	 * then also management frames are sent via this callback.
-	 * This function can't sleep.
-	 */
-	void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
-			       struct net_device *dev,int rate);
-
-	/* stops the HW queue for DATA frames. Useful to avoid
-	 * waste time to TX data frame when we are reassociating
-	 * This function can sleep.
-	 */
-	void (*data_hard_stop)(struct net_device *dev);
-
-	/* OK this is complementar to data_poll_hard_stop */
-	void (*data_hard_resume)(struct net_device *dev);
-
-	/* ask to the driver to retune the radio .
-	 * This function can sleep. the driver should ensure
-	 * the radio has been swithced before return.
-	 */
-	void (*set_chan)(struct net_device *dev,short ch);
-
-	/* These are not used if the ieee stack takes care of
-	 * scanning (IEEE_SOFTMAC_SCAN feature set).
-	 * In this case only the set_chan is used.
-	 *
-	 * The syncro version is similar to the start_scan but
-	 * does not return until all channels has been scanned.
-	 * this is called in user context and should sleep,
-	 * it is called in a work_queue when swithcing to ad-hoc mode
-	 * or in behalf of iwlist scan when the card is associated
-	 * and root user ask for a scan.
-	 * the fucntion stop_scan should stop both the syncro and
-	 * background scanning and can sleep.
-	 * The fucntion start_scan should initiate the background
-	 * scanning and can't sleep.
-	 */
-	void (*scan_syncro)(struct net_device *dev);
-	void (*start_scan)(struct net_device *dev);
-	void (*stop_scan)(struct net_device *dev);
-
-	/* indicate the driver that the link state is changed
-	 * for example it may indicate the card is associated now.
-	 * Driver might be interested in this to apply RX filter
-	 * rules or simply light the LINK led
-	 */
-	void (*link_change)(struct net_device *dev);
-
-	/* these two function indicates to the HW when to start
-	 * and stop to send beacons. This is used when the
-	 * IEEE_SOFTMAC_BEACONS is not set. For now the
-	 * stop_send_bacons is NOT guaranteed to be called only
-	 * after start_send_beacons.
-	 */
-	void (*start_send_beacons) (struct net_device *dev);
-	void (*stop_send_beacons) (struct net_device *dev);
-
-	/* power save mode related */
-	void (*sta_wake_up) (struct net_device *dev);
-//	void (*ps_request_tx_ack) (struct net_device *dev);
-	void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
-	short (*ps_is_queue_empty) (struct net_device *dev);
-#if 0
-	/* Typical STA methods */
-        int (*handle_auth) (struct net_device * dev,
-                            struct ieee80211_auth * auth);
-        int (*handle_deauth) (struct net_device * dev,
-                              struct ieee80211_deauth * auth);
-        int (*handle_action) (struct net_device * dev,
-                              struct ieee80211_action * action,
-                              struct ieee80211_rx_stats * stats);
-        int (*handle_disassoc) (struct net_device * dev,
-                                struct ieee80211_disassoc * assoc);
-#endif
-        int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
-#if 0
-        int (*handle_probe_response) (struct net_device * dev,
-                                      struct ieee80211_probe_response * resp,
-                                      struct ieee80211_network * network);
-        int (*handle_probe_request) (struct net_device * dev,
-                                     struct ieee80211_probe_request * req,
-                                     struct ieee80211_rx_stats * stats);
-#endif
-        int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
-
-#if 0
-        /* Typical AP methods */
-        int (*handle_assoc_request) (struct net_device * dev);
-        int (*handle_reassoc_request) (struct net_device * dev,
-                                       struct ieee80211_reassoc_request * req);
-#endif
-
-	/* check whether Tx hw resouce available */
-	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
-	//added by wb for HT related
-//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
-	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
-//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
-	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
-	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
-	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev);
-	bool (*is_ap_in_wep_tkip)(struct net_device* dev);
-	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
-	bool (*SetFwCmdHandler)(struct net_device *dev,	FW_CMD_IO_TYPE		FwCmdIO);
-	void (*LedControlHandler)(struct net_device * dev, LED_CTL_MODE LedAction);
-	/* This must be the last item so that it points to the data
-	 * allocated beyond this structure by alloc_ieee80211 */
-	u8 priv[0];
-};
-
-#define IEEE_A            (1<<0)
-#define IEEE_B            (1<<1)
-#define IEEE_G            (1<<2)
-#define IEEE_N_24G 		  (1<<4)
-#define	IEEE_N_5G		  (1<<5)
-#define IEEE_MODE_MASK    (IEEE_A|IEEE_B|IEEE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1<<2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1<<4)
-
-/* Generate respones to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1<<5)
-
-/* The ieee802.11 stack will manages the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details. */
-#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
-
-/* Generate beacons.  The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1<<6)
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-#else
-	return ((struct ieee80211_device *)dev->priv)->priv;
-#endif
-}
-
-extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
-{
-	/* Single white space is for Linksys APs */
-	if (essid_len == 1 && essid[0] == ' ')
-		return 1;
-
-	/* Otherwise, if the entire essid is 0, we assume it is hidden */
-	while (essid_len) {
-		essid_len--;
-		if (essid[essid_len] != '\0')
-			return 0;
-	}
-
-	return 1;
-}
-
-extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
-{
-	/*
-	 * It is possible for both access points and our device to support
-	 * combinations of modes, so as long as there is one valid combination
-	 * of ap/device supported modes, then return success
-	 *
-	 */
-	if ((mode & IEEE_A) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_52GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_G) &&
-	    (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	if ((mode & IEEE_B) &&
-	    (ieee->modulation & IEEE80211_CCK_MODULATION) &&
-	    (ieee->freq_band & IEEE80211_24GHZ_BAND))
-		return 1;
-
-	return 0;
-}
-
-extern inline int ieee80211_get_hdrlen(u16 fc)
-{
-	int hdrlen = IEEE80211_3ADDR_LEN;
-
-	switch (WLAN_FC_GET_TYPE(fc)) {
-	case IEEE80211_FTYPE_DATA:
-		if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
-			hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */
-		if(IEEE80211_QOS_HAS_SEQ(fc))
-			hdrlen += 2; /* QOS ctrl*/
-		break;
-	case IEEE80211_FTYPE_CTL:
-		switch (WLAN_FC_GET_STYPE(fc)) {
-		case IEEE80211_STYPE_CTS:
-		case IEEE80211_STYPE_ACK:
-			hdrlen = IEEE80211_1ADDR_LEN;
-			break;
-		default:
-			hdrlen = IEEE80211_2ADDR_LEN;
-			break;
-		}
-		break;
-	}
-
-	return hdrlen;
-}
-
-static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
-{
-        switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
-        case IEEE80211_1ADDR_LEN:
-                return ((struct ieee80211_hdr_1addr *)hdr)->payload;
-        case IEEE80211_2ADDR_LEN:
-                return ((struct ieee80211_hdr_2addr *)hdr)->payload;
-        case IEEE80211_3ADDR_LEN:
-                return ((struct ieee80211_hdr_3addr *)hdr)->payload;
-        case IEEE80211_4ADDR_LEN:
-                return ((struct ieee80211_hdr_4addr *)hdr)->payload;
-        }
-        return NULL;
-}
-
-static inline int ieee80211_is_ofdm_rate(u8 rate)
-{
-        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
-        case IEEE80211_OFDM_RATE_6MB:
-        case IEEE80211_OFDM_RATE_9MB:
-        case IEEE80211_OFDM_RATE_12MB:
-        case IEEE80211_OFDM_RATE_18MB:
-        case IEEE80211_OFDM_RATE_24MB:
-        case IEEE80211_OFDM_RATE_36MB:
-        case IEEE80211_OFDM_RATE_48MB:
-        case IEEE80211_OFDM_RATE_54MB:
-                return 1;
-        }
-        return 0;
-}
-
-static inline int ieee80211_is_cck_rate(u8 rate)
-{
-        switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
-        case IEEE80211_CCK_RATE_1MB:
-        case IEEE80211_CCK_RATE_2MB:
-        case IEEE80211_CCK_RATE_5MB:
-        case IEEE80211_CCK_RATE_11MB:
-                return 1;
-        }
-        return 0;
-}
-
-
-/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
-
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-
-extern int ieee80211_encrypt_fragment(
-	struct ieee80211_device *ieee,
-	struct sk_buff *frag,
-	int hdr_len);
-
-extern int rtl8192_ieee80211_xmit(struct sk_buff *skb,
-			  struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-
-/* ieee80211_rx.c */
-extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
-			struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
-			     struct ieee80211_hdr_4addr *header,
-			     struct ieee80211_rx_stats *stats);
-
-/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
-				   struct iw_request_info *info,
-				   union iwreq_data *wrqu, char *key);
-#if WIRELESS_EXT >= 18
-extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data* wrqu, char *extra);
-extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data* wrqu, char *extra);
-extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
-                               struct iw_request_info *info,
-                               struct iw_param *data, char *extra);
-extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra);
-#endif
-extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
-
-/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(struct ieee80211_network net);
-extern short ieee80211_is_shortslot(struct ieee80211_network net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
-			struct ieee80211_rx_stats *rx_stats, u16 type,
-			u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
-
-void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn);
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
-
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-
-extern void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee);
-
-/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
-
-/* ieee80211_softmac_wx.c */
-
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
-			    struct iw_request_info *info,
-			    union iwreq_data *wrqu, char *ext);
-
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
-			 struct iw_request_info *info,
-			 union iwreq_data *awrq,
-			 char *extra);
-
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
-
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
-			      struct iw_request_info *a,
-			      union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
-			     union iwreq_data *wrqu, char *b);
-
-//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-#else
- extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#endif
-
-
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
-				 struct iw_request_info *info,
-				 union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
-			     struct iw_request_info *info,
-			     union iwreq_data *wrqu, char *extra);
-//HT
-#define MAX_RECEIVE_BUFFER_SIZE 9100  //
-extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
-extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
-
-void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
-extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
-extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
-extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
-extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
-extern void HTOnAssocRsp(struct ieee80211_device *ieee);
-extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
-extern void HTInitializeBssDesc(PBSS_HT pBssHT);
-extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
-extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
-extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
-extern u8 MCS_FILTER_ALL[];
-extern u16 MCS_DATA_RATE[2][2][77] ;
-extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
-//extern void HTSetConnectBwModeCallback(unsigned long data);
-extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
-extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
-extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
-extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
-extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
-//function in BAPROC.c
-extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
-extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
-extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
-extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
-extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
-extern void BaSetupTimeOut(unsigned long data);
-extern void TxBaInactTimeout(unsigned long data);
-extern void RxBaInactTimeout(unsigned long data);
-extern void ResetBaEntry( PBA_RECORD pBA);
-//function in TS.c
-extern bool GetTs(
-        struct ieee80211_device*        ieee,
-        PTS_COMMON_INFO                 *ppTS,
-        u8*                             Addr,
-        u8                              TID,
-        TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
-        bool                            bAddNewTs
-        );
-extern void TSInitialize(struct ieee80211_device *ieee);
-extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);
-extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
-extern void RemoveAllTS(struct ieee80211_device* ieee);
-void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
-
-extern const long ieee80211_wlan_frequencies[];
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
-	ieee->scans++;
-}
-
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
-	return ieee->scans;
-}
-
-static inline const char *escape_essid(const char *essid, u8 essid_len) {
-	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
-	const char *s = essid;
-	char *d = escaped;
-
-	if (ieee80211_is_empty_essid(essid, essid_len)) {
-		memcpy(escaped, "<hidden>", sizeof("<hidden>"));
-		return escaped;
-	}
-
-	essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
-	while (essid_len--) {
-		if (*s == '\0') {
-			*d++ = '\\';
-			*d++ = '0';
-			s++;
-		} else {
-			*d++ = *s++;
-		}
-	}
-	*d = '\0';
-	return escaped;
-}
-
-/* For the function is more related to hardware setting, it's better to use the
- * ieee handler to refer to it.
- */
-extern short check_nic_enough_desc(struct net_device *dev, int queue_index);
-extern int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev);
-extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
-		struct ieee80211_info_element *info_element,
-		u16 length,
-		struct ieee80211_network *network,
-		struct ieee80211_rx_stats *stats);
-
-void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
-#define RT_ASOC_RETRY_LIMIT	5
-#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192su/ieee80211/EndianFree.h b/drivers/staging/rtl8192su/ieee80211/EndianFree.h
deleted file mode 100644
index 0c417a6..0000000
--- a/drivers/staging/rtl8192su/ieee80211/EndianFree.h
+++ /dev/null
@@ -1,199 +0,0 @@
-#ifndef __INC_ENDIANFREE_H
-#define __INC_ENDIANFREE_H
-
-/*
- *	Call endian free function when
- *		1. Read/write packet content.
- *		2. Before write integer to IO.
- *		3. After read integer from IO.
- */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-#ifndef bool
-typedef enum{false = 0, true} bool;
-#endif
-#endif
-
-#define __MACHINE_LITTLE_ENDIAN 1234    /* LSB first: i386, vax */
-#define __MACHINE_BIG_ENDIAN    4321    /* MSB first: 68000, ibm, net, ppc */
-
-#define BYTE_ORDER __MACHINE_LITTLE_ENDIAN
-
-#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
-// Convert data
-#define EF1Byte(_val)				((u8)(_val))
-#define EF2Byte(_val)				((u16)(_val))
-#define EF4Byte(_val)				((u32)(_val))
-
-#else
-// Convert data
-#define EF1Byte(_val)				((u8)(_val))
-#define EF2Byte(_val)				(((((u16)(_val))&0x00ff)<<8)|((((u16)(_val))&0xff00)>>8))
-#define EF4Byte(_val)				(((((u32)(_val))&0x000000ff)<<24)|\
-						((((u32)(_val))&0x0000ff00)<<8)|\
-						((((u32)(_val))&0x00ff0000)>>8)|\
-						((((u32)(_val))&0xff000000)>>24))
-#endif
-
-// Read data from memory
-#define ReadEF1Byte(_ptr)		EF1Byte(*((u8 *)(_ptr)))
-#define ReadEF2Byte(_ptr)		EF2Byte(*((u16 *)(_ptr)))
-#define ReadEF4Byte(_ptr)		EF4Byte(*((u32 *)(_ptr)))
-
-// Write data to memory
-#define WriteEF1Byte(_ptr, _val)	(*((u8 *)(_ptr)))=EF1Byte(_val)
-#define WriteEF2Byte(_ptr, _val)	(*((u16 *)(_ptr)))=EF2Byte(_val)
-#define WriteEF4Byte(_ptr, _val)	(*((u32 *)(_ptr)))=EF4Byte(_val)
-// Convert Host system specific byte ording (litten or big endia) to Network byte ording (big endian).
-// 2006.05.07, by rcnjko.
-#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
-#define H2N1BYTE(_val)	((u8)(_val))
-#define H2N2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
-			((((u16)(_val))&0xff00)>>8))
-#define H2N4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
-			((((u32)(_val))&0x0000ff00)<<8)	|\
-			((((u32)(_val))&0x00ff0000)>>8)	|\
-			((((u32)(_val))&0xff000000)>>24))
-#else
-#define H2N1BYTE(_val)			((u8)(_val))
-#define H2N2BYTE(_val)			((u16)(_val))
-#define H2N4BYTE(_val)			((u32)(_val))
-#endif
-
-// Convert from Network byte ording (big endian) to Host system specific byte ording (litten or big endia).
-// 2006.05.07, by rcnjko.
-#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN
-#define N2H1BYTE(_val)	((u8)(_val))
-#define N2H2BYTE(_val)	(((((u16)(_val))&0x00ff)<<8)|\
-			((((u16)(_val))&0xff00)>>8))
-#define N2H4BYTE(_val)	(((((u32)(_val))&0x000000ff)<<24)|\
-			((((u32)(_val))&0x0000ff00)<<8)	|\
-			((((u32)(_val))&0x00ff0000)>>8)	|\
-			((((u32)(_val))&0xff000000)>>24))
-#else
-#define N2H1BYTE(_val)			((u8)(_val))
-#define N2H2BYTE(_val)			((u16)(_val))
-#define N2H4BYTE(_val)			((u32)(_val))
-#endif
-
-//
-//	Example:
-//		BIT_LEN_MASK_32(0) => 0x00000000
-//		BIT_LEN_MASK_32(1) => 0x00000001
-//		BIT_LEN_MASK_32(2) => 0x00000003
-//		BIT_LEN_MASK_32(32) => 0xFFFFFFFF
-//
-#define BIT_LEN_MASK_32(__BitLen) (0xFFFFFFFF >> (32 - (__BitLen)))
-//
-//	Example:
-//		BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003
-//		BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000
-//
-#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) (BIT_LEN_MASK_32(__BitLen) << (__BitOffset))
-
-//
-//	Description:
-//		Return 4-byte value in host byte ordering from
-//		4-byte pointer in litten-endian system.
-//
-#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (EF4Byte(*((u32 *)(__pStart))))
-
-//
-//	Description:
-//		Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to
-//		4-byte value in host byte ordering.
-//
-#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
-	( \
-	  ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \
-	  & \
-	  BIT_LEN_MASK_32(__BitLen) \
-	)
-
-//
-//	Description:
-//		Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering
-//		and return the result in 4-byte value in host byte ordering.
-//
-#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
-	( \
-	  LE_P4BYTE_TO_HOST_4BYTE(__pStart) \
-	  & \
-	  ( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \
-	)
-
-//
-//	Description:
-//		Set subfield of little-endian 4-byte value to specified value.
-//
-#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \
-	*((u32 *)(__pStart)) = \
-	EF4Byte( \
-	LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \
-	| \
-	( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \
-       );
-
-
-#define BIT_LEN_MASK_16(__BitLen) \
-	(0xFFFF >> (16 - (__BitLen)))
-
-#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \
-	(BIT_LEN_MASK_16(__BitLen) << (__BitOffset))
-
-#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
-	(EF2Byte(*((u16 *)(__pStart))))
-
-#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
-	( \
-	  ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \
-	  & \
-	  BIT_LEN_MASK_16(__BitLen) \
-	)
-
-#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
-	( \
-	  LE_P2BYTE_TO_HOST_2BYTE(__pStart) \
-	  & \
-	  ( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \
-	)
-
-#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \
-	*((u16 *)(__pStart)) = \
-	EF2Byte( \
-		LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \
-		| \
-		( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \
-       );
-
-#define BIT_LEN_MASK_8(__BitLen) \
-	(0xFF >> (8 - (__BitLen)))
-
-#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \
-	(BIT_LEN_MASK_8(__BitLen) << (__BitOffset))
-
-#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
-	(EF1Byte(*((u8 *)(__pStart))))
-
-#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
-	( \
-	  ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \
-	  & \
-	  BIT_LEN_MASK_8(__BitLen) \
-	)
-
-#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
-	( \
-	  LE_P1BYTE_TO_HOST_1BYTE(__pStart) \
-	  & \
-	  ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \
-	)
-
-#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \
-	*((u8 *)(__pStart)) = \
-	EF1Byte( \
-		LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \
-		| \
-		( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \
-       );
-
-#endif // #ifndef __INC_ENDIANFREE_H
diff --git a/drivers/staging/rtl8192su/ieee80211/Makefile b/drivers/staging/rtl8192su/ieee80211/Makefile
index 295a18f..a500bfa 100644
--- a/drivers/staging/rtl8192su/ieee80211/Makefile
+++ b/drivers/staging/rtl8192su/ieee80211/Makefile
@@ -5,8 +5,7 @@ EXTRA_CFLAGS += -DRTL8192S_DISABLE_FW_DM=0
 EXTRA_CFLAGS += -DRTL8192SU
 #EXTRA_CFLAGS += -DJOHN_NOCPY
 EXTRA_CFLAGS += -DTHOMAS_TURBO
-#flags to enable or disble 80211D feature
-EXTRA_CFLAGS += -DENABLE_DOT11D
+
 ieee80211-rsl-objs := ieee80211_rx.o \
 		      ieee80211_softmac.o \
 		      ieee80211_tx.o \
diff --git a/drivers/staging/rtl8192su/ieee80211/aes.c b/drivers/staging/rtl8192su/ieee80211/aes.c
deleted file mode 100644
index 0c176e2..0000000
--- a/drivers/staging/rtl8192su/ieee80211/aes.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Cryptographic API.
- *
- * AES Cipher Algorithm.
- *
- * Based on Brian Gladman's code.
- *
- * Linux developers:
- *  Alexander Kjeldaas <astor@fast.no>
- *  Herbert Valerio Riedel <hvr@hvrlab.org>
- *  Kyle McMartin <kyle@debian.org>
- *  Adam J. Richter <adam@yggdrasil.com> (conversion to 2.5 API).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * ---------------------------------------------------------------------------
- * Copyright (c) 2002, Dr Brian Gladman <brg@gladman.me.uk>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * ALTERNATIVELY, provided that this notice is retained in full, this product
- * may be distributed under the terms of the GNU General Public License (GPL),
- * in which case the provisions of the GPL apply INSTEAD OF those given above.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explicit or implied warranties
- * in respect of its properties, including, but not limited to, correctness
- * and/or fitness for purpose.
- * ---------------------------------------------------------------------------
- */
-
-/* Some changes from the Gladman version:
-    s/RIJNDAEL(e_key)/E_KEY/g
-    s/RIJNDAEL(d_key)/D_KEY/g
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <asm/byteorder.h>
-
-#define AES_MIN_KEY_SIZE	16
-#define AES_MAX_KEY_SIZE	32
-
-#define AES_BLOCK_SIZE		16
-
-static inline
-u32 generic_rotr32 (const u32 x, const unsigned bits)
-{
-	const unsigned n = bits % 32;
-	return (x >> n) | (x << (32 - n));
-}
-
-static inline
-u32 generic_rotl32 (const u32 x, const unsigned bits)
-{
-	const unsigned n = bits % 32;
-	return (x << n) | (x >> (32 - n));
-}
-
-#define rotl generic_rotl32
-#define rotr generic_rotr32
-
-/*
- * #define byte(x, nr) ((unsigned char)((x) >> (nr*8)))
- */
-inline static u8
-byte(const u32 x, const unsigned n)
-{
-	return x >> (n << 3);
-}
-
-#define u32_in(x) le32_to_cpu(*(const u32 *)(x))
-#define u32_out(to, from) (*(u32 *)(to) = cpu_to_le32(from))
-
-struct aes_ctx {
-	int key_length;
-	u32 E[60];
-	u32 D[60];
-};
-
-#define E_KEY ctx->E
-#define D_KEY ctx->D
-
-static u8 pow_tab[256] __initdata;
-static u8 log_tab[256] __initdata;
-static u8 sbx_tab[256] __initdata;
-static u8 isb_tab[256] __initdata;
-static u32 rco_tab[10];
-static u32 ft_tab[4][256];
-static u32 it_tab[4][256];
-
-static u32 fl_tab[4][256];
-static u32 il_tab[4][256];
-
-static inline u8 __init
-f_mult (u8 a, u8 b)
-{
-	u8 aa = log_tab[a], cc = aa + log_tab[b];
-
-	return pow_tab[cc + (cc < aa ? 1 : 0)];
-}
-
-#define ff_mult(a,b)    (a && b ? f_mult(a, b) : 0)
-
-#define f_rn(bo, bi, n, k)					\
-    bo[n] =  ft_tab[0][byte(bi[n],0)] ^				\
-             ft_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
-             ft_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
-             ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
-
-#define i_rn(bo, bi, n, k)					\
-    bo[n] =  it_tab[0][byte(bi[n],0)] ^				\
-             it_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
-             it_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
-             it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
-
-#define ls_box(x)				\
-    ( fl_tab[0][byte(x, 0)] ^			\
-      fl_tab[1][byte(x, 1)] ^			\
-      fl_tab[2][byte(x, 2)] ^			\
-      fl_tab[3][byte(x, 3)] )
-
-#define f_rl(bo, bi, n, k)					\
-    bo[n] =  fl_tab[0][byte(bi[n],0)] ^				\
-             fl_tab[1][byte(bi[(n + 1) & 3],1)] ^		\
-             fl_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
-             fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
-
-#define i_rl(bo, bi, n, k)					\
-    bo[n] =  il_tab[0][byte(bi[n],0)] ^				\
-             il_tab[1][byte(bi[(n + 3) & 3],1)] ^		\
-             il_tab[2][byte(bi[(n + 2) & 3],2)] ^		\
-             il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
-
-static void __init
-gen_tabs (void)
-{
-	u32 i, t;
-	u8 p, q;
-
-	/* log and power tables for GF(2**8) finite field with
-	   0x011b as modular polynomial - the simplest primitive
-	   root is 0x03, used here to generate the tables */
-
-	for (i = 0, p = 1; i < 256; ++i) {
-		pow_tab[i] = (u8) p;
-		log_tab[p] = (u8) i;
-
-		p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0);
-	}
-
-	log_tab[1] = 0;
-
-	for (i = 0, p = 1; i < 10; ++i) {
-		rco_tab[i] = p;
-
-		p = (p << 1) ^ (p & 0x80 ? 0x01b : 0);
-	}
-
-	for (i = 0; i < 256; ++i) {
-		p = (i ? pow_tab[255 - log_tab[i]] : 0);
-		q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2));
-		p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2));
-		sbx_tab[i] = p;
-		isb_tab[p] = (u8) i;
-	}
-
-	for (i = 0; i < 256; ++i) {
-		p = sbx_tab[i];
-
-		t = p;
-		fl_tab[0][i] = t;
-		fl_tab[1][i] = rotl (t, 8);
-		fl_tab[2][i] = rotl (t, 16);
-		fl_tab[3][i] = rotl (t, 24);
-
-		t = ((u32) ff_mult (2, p)) |
-		    ((u32) p << 8) |
-		    ((u32) p << 16) | ((u32) ff_mult (3, p) << 24);
-
-		ft_tab[0][i] = t;
-		ft_tab[1][i] = rotl (t, 8);
-		ft_tab[2][i] = rotl (t, 16);
-		ft_tab[3][i] = rotl (t, 24);
-
-		p = isb_tab[i];
-
-		t = p;
-		il_tab[0][i] = t;
-		il_tab[1][i] = rotl (t, 8);
-		il_tab[2][i] = rotl (t, 16);
-		il_tab[3][i] = rotl (t, 24);
-
-		t = ((u32) ff_mult (14, p)) |
-		    ((u32) ff_mult (9, p) << 8) |
-		    ((u32) ff_mult (13, p) << 16) |
-		    ((u32) ff_mult (11, p) << 24);
-
-		it_tab[0][i] = t;
-		it_tab[1][i] = rotl (t, 8);
-		it_tab[2][i] = rotl (t, 16);
-		it_tab[3][i] = rotl (t, 24);
-	}
-}
-
-#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
-
-#define imix_col(y,x)       \
-    u   = star_x(x);        \
-    v   = star_x(u);        \
-    w   = star_x(v);        \
-    t   = w ^ (x);          \
-   (y)  = u ^ v ^ w;        \
-   (y) ^= rotr(u ^ t,  8) ^ \
-          rotr(v ^ t, 16) ^ \
-          rotr(t,24)
-
-/* initialise the key schedule from the user supplied key */
-
-#define loop4(i)                                    \
-{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
-    t ^= E_KEY[4 * i];     E_KEY[4 * i + 4] = t;    \
-    t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t;    \
-    t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t;    \
-    t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t;    \
-}
-
-#define loop6(i)                                    \
-{   t = rotr(t,  8); t = ls_box(t) ^ rco_tab[i];    \
-    t ^= E_KEY[6 * i];     E_KEY[6 * i + 6] = t;    \
-    t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t;    \
-    t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t;    \
-    t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t;    \
-    t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t;   \
-    t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t;   \
-}
-
-#define loop8(i)                                    \
-{   t = rotr(t,  8); ; t = ls_box(t) ^ rco_tab[i];  \
-    t ^= E_KEY[8 * i];     E_KEY[8 * i + 8] = t;    \
-    t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t;    \
-    t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t;   \
-    t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t;   \
-    t  = E_KEY[8 * i + 4] ^ ls_box(t);    \
-    E_KEY[8 * i + 12] = t;                \
-    t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t;   \
-    t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t;   \
-    t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t;   \
-}
-
-static int
-aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
-{
-	struct aes_ctx *ctx = ctx_arg;
-	u32 i, t, u, v, w;
-
-	if (key_len != 16 && key_len != 24 && key_len != 32) {
-		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
-
-	ctx->key_length = key_len;
-
-	E_KEY[0] = u32_in (in_key);
-	E_KEY[1] = u32_in (in_key + 4);
-	E_KEY[2] = u32_in (in_key + 8);
-	E_KEY[3] = u32_in (in_key + 12);
-
-	switch (key_len) {
-	case 16:
-		t = E_KEY[3];
-		for (i = 0; i < 10; ++i)
-			loop4 (i);
-		break;
-
-	case 24:
-		E_KEY[4] = u32_in (in_key + 16);
-		t = E_KEY[5] = u32_in (in_key + 20);
-		for (i = 0; i < 8; ++i)
-			loop6 (i);
-		break;
-
-	case 32:
-		E_KEY[4] = u32_in (in_key + 16);
-		E_KEY[5] = u32_in (in_key + 20);
-		E_KEY[6] = u32_in (in_key + 24);
-		t = E_KEY[7] = u32_in (in_key + 28);
-		for (i = 0; i < 7; ++i)
-			loop8 (i);
-		break;
-	}
-
-	D_KEY[0] = E_KEY[0];
-	D_KEY[1] = E_KEY[1];
-	D_KEY[2] = E_KEY[2];
-	D_KEY[3] = E_KEY[3];
-
-	for (i = 4; i < key_len + 24; ++i) {
-		imix_col (D_KEY[i], E_KEY[i]);
-	}
-
-	return 0;
-}
-
-/* encrypt a block of text */
-
-#define f_nround(bo, bi, k) \
-    f_rn(bo, bi, 0, k);     \
-    f_rn(bo, bi, 1, k);     \
-    f_rn(bo, bi, 2, k);     \
-    f_rn(bo, bi, 3, k);     \
-    k += 4
-
-#define f_lround(bo, bi, k) \
-    f_rl(bo, bi, 0, k);     \
-    f_rl(bo, bi, 1, k);     \
-    f_rl(bo, bi, 2, k);     \
-    f_rl(bo, bi, 3, k)
-
-static void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in)
-{
-	const struct aes_ctx *ctx = ctx_arg;
-	u32 b0[4], b1[4];
-	const u32 *kp = E_KEY + 4;
-
-	b0[0] = u32_in (in) ^ E_KEY[0];
-	b0[1] = u32_in (in + 4) ^ E_KEY[1];
-	b0[2] = u32_in (in + 8) ^ E_KEY[2];
-	b0[3] = u32_in (in + 12) ^ E_KEY[3];
-
-	if (ctx->key_length > 24) {
-		f_nround (b1, b0, kp);
-		f_nround (b0, b1, kp);
-	}
-
-	if (ctx->key_length > 16) {
-		f_nround (b1, b0, kp);
-		f_nround (b0, b1, kp);
-	}
-
-	f_nround (b1, b0, kp);
-	f_nround (b0, b1, kp);
-	f_nround (b1, b0, kp);
-	f_nround (b0, b1, kp);
-	f_nround (b1, b0, kp);
-	f_nround (b0, b1, kp);
-	f_nround (b1, b0, kp);
-	f_nround (b0, b1, kp);
-	f_nround (b1, b0, kp);
-	f_lround (b0, b1, kp);
-
-	u32_out (out, b0[0]);
-	u32_out (out + 4, b0[1]);
-	u32_out (out + 8, b0[2]);
-	u32_out (out + 12, b0[3]);
-}
-
-/* decrypt a block of text */
-
-#define i_nround(bo, bi, k) \
-    i_rn(bo, bi, 0, k);     \
-    i_rn(bo, bi, 1, k);     \
-    i_rn(bo, bi, 2, k);     \
-    i_rn(bo, bi, 3, k);     \
-    k -= 4
-
-#define i_lround(bo, bi, k) \
-    i_rl(bo, bi, 0, k);     \
-    i_rl(bo, bi, 1, k);     \
-    i_rl(bo, bi, 2, k);     \
-    i_rl(bo, bi, 3, k)
-
-static void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in)
-{
-	const struct aes_ctx *ctx = ctx_arg;
-	u32 b0[4], b1[4];
-	const int key_len = ctx->key_length;
-	const u32 *kp = D_KEY + key_len + 20;
-
-	b0[0] = u32_in (in) ^ E_KEY[key_len + 24];
-	b0[1] = u32_in (in + 4) ^ E_KEY[key_len + 25];
-	b0[2] = u32_in (in + 8) ^ E_KEY[key_len + 26];
-	b0[3] = u32_in (in + 12) ^ E_KEY[key_len + 27];
-
-	if (key_len > 24) {
-		i_nround (b1, b0, kp);
-		i_nround (b0, b1, kp);
-	}
-
-	if (key_len > 16) {
-		i_nround (b1, b0, kp);
-		i_nround (b0, b1, kp);
-	}
-
-	i_nround (b1, b0, kp);
-	i_nround (b0, b1, kp);
-	i_nround (b1, b0, kp);
-	i_nround (b0, b1, kp);
-	i_nround (b1, b0, kp);
-	i_nround (b0, b1, kp);
-	i_nround (b1, b0, kp);
-	i_nround (b0, b1, kp);
-	i_nround (b1, b0, kp);
-	i_lround (b0, b1, kp);
-
-	u32_out (out, b0[0]);
-	u32_out (out + 4, b0[1]);
-	u32_out (out + 8, b0[2]);
-	u32_out (out + 12, b0[3]);
-}
-
-
-static struct crypto_alg aes_alg = {
-	.cra_name		=	"aes",
-	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
-	.cra_blocksize		=	AES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct aes_ctx),
-	.cra_module		=	THIS_MODULE,
-	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
-	.cra_u			=	{
-		.cipher = {
-			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
-			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
-			.cia_setkey	   	= 	aes_set_key,
-			.cia_encrypt	 	=	aes_encrypt,
-			.cia_decrypt	  	=	aes_decrypt
-		}
-	}
-};
-
-static int __init aes_init(void)
-{
-	gen_tabs();
-	return crypto_register_alg(&aes_alg);
-}
-
-static void __exit aes_fini(void)
-{
-	crypto_unregister_alg(&aes_alg);
-}
-
-module_init(aes_init);
-module_exit(aes_fini);
-
-MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
-MODULE_LICENSE("Dual BSD/GPL");
-
diff --git a/drivers/staging/rtl8192su/ieee80211/api.c b/drivers/staging/rtl8192su/ieee80211/api.c
deleted file mode 100644
index c627d02..0000000
--- a/drivers/staging/rtl8192su/ieee80211/api.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Scatterlist Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- * Copyright (c) 2002 David S. Miller (davem@redhat.com)
- *
- * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Mé°ˆler.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 "kmap_types.h"
-
-#include <linux/init.h>
-#include <linux/module.h>
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/errno.h>
-#include <linux/rwsem.h>
-#include <linux/slab.h>
-#include "internal.h"
-
-LIST_HEAD(crypto_alg_list);
-DECLARE_RWSEM(crypto_alg_sem);
-
-static inline int crypto_alg_get(struct crypto_alg *alg)
-{
-	return try_inc_mod_count(alg->cra_module);
-}
-
-static inline void crypto_alg_put(struct crypto_alg *alg)
-{
-	if (alg->cra_module)
-		__MOD_DEC_USE_COUNT(alg->cra_module);
-}
-
-struct crypto_alg *crypto_alg_lookup(const char *name)
-{
-	struct crypto_alg *q, *alg = NULL;
-
-	if (!name)
-		return NULL;
-
-	down_read(&crypto_alg_sem);
-
-	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (!(strcmp(q->cra_name, name))) {
-			if (crypto_alg_get(q))
-				alg = q;
-			break;
-		}
-	}
-
-	up_read(&crypto_alg_sem);
-	return alg;
-}
-
-static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
-{
-	tfm->crt_flags = 0;
-
-	switch (crypto_tfm_alg_type(tfm)) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		return crypto_init_cipher_flags(tfm, flags);
-
-	case CRYPTO_ALG_TYPE_DIGEST:
-		return crypto_init_digest_flags(tfm, flags);
-
-	case CRYPTO_ALG_TYPE_COMPRESS:
-		return crypto_init_compress_flags(tfm, flags);
-
-	default:
-		break;
-	}
-
-	BUG();
-	return -EINVAL;
-}
-
-static int crypto_init_ops(struct crypto_tfm *tfm)
-{
-	switch (crypto_tfm_alg_type(tfm)) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		return crypto_init_cipher_ops(tfm);
-
-	case CRYPTO_ALG_TYPE_DIGEST:
-		return crypto_init_digest_ops(tfm);
-
-	case CRYPTO_ALG_TYPE_COMPRESS:
-		return crypto_init_compress_ops(tfm);
-
-	default:
-		break;
-	}
-
-	BUG();
-	return -EINVAL;
-}
-
-static void crypto_exit_ops(struct crypto_tfm *tfm)
-{
-	switch (crypto_tfm_alg_type(tfm)) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		crypto_exit_cipher_ops(tfm);
-		break;
-
-	case CRYPTO_ALG_TYPE_DIGEST:
-		crypto_exit_digest_ops(tfm);
-		break;
-
-	case CRYPTO_ALG_TYPE_COMPRESS:
-		crypto_exit_compress_ops(tfm);
-		break;
-
-	default:
-		BUG();
-
-	}
-}
-
-struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
-{
-	struct crypto_tfm *tfm = NULL;
-	struct crypto_alg *alg;
-
-	alg = crypto_alg_mod_lookup(name);
-	if (alg == NULL)
-		goto out;
-
-	tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL);
-	if (tfm == NULL)
-		goto out_put;
-
-	memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize);
-
-	tfm->__crt_alg = alg;
-
-	if (crypto_init_flags(tfm, flags))
-		goto out_free_tfm;
-
-	if (crypto_init_ops(tfm)) {
-		crypto_exit_ops(tfm);
-		goto out_free_tfm;
-	}
-
-	goto out;
-
-out_free_tfm:
-	kfree(tfm);
-	tfm = NULL;
-out_put:
-	crypto_alg_put(alg);
-out:
-	return tfm;
-}
-
-void crypto_free_tfm(struct crypto_tfm *tfm)
-{
-	struct crypto_alg *alg = tfm->__crt_alg;
-	int size = sizeof(*tfm) + alg->cra_ctxsize;
-
-	crypto_exit_ops(tfm);
-	crypto_alg_put(alg);
-	memset(tfm, 0, size);
-	kfree(tfm);
-}
-
-int crypto_register_alg(struct crypto_alg *alg)
-{
-	int ret = 0;
-	struct crypto_alg *q;
-
-	down_write(&crypto_alg_sem);
-
-	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (!(strcmp(q->cra_name, alg->cra_name))) {
-			ret = -EEXIST;
-			goto out;
-		}
-	}
-
-	list_add_tail(&alg->cra_list, &crypto_alg_list);
-out:
-	up_write(&crypto_alg_sem);
-	return ret;
-}
-
-int crypto_unregister_alg(struct crypto_alg *alg)
-{
-	int ret = -ENOENT;
-	struct crypto_alg *q;
-
-	BUG_ON(!alg->cra_module);
-
-	down_write(&crypto_alg_sem);
-	list_for_each_entry(q, &crypto_alg_list, cra_list) {
-		if (alg == q) {
-			list_del(&alg->cra_list);
-			ret = 0;
-			goto out;
-		}
-	}
-out:
-	up_write(&crypto_alg_sem);
-	return ret;
-}
-
-int crypto_alg_available(const char *name, u32 flags)
-{
-	int ret = 0;
-	struct crypto_alg *alg = crypto_alg_mod_lookup(name);
-
-	if (alg) {
-		crypto_alg_put(alg);
-		ret = 1;
-	}
-
-	return ret;
-}
-
-static int __init init_crypto(void)
-{
-	printk(KERN_INFO "Initializing Cryptographic API\n");
-	crypto_init_proc();
-	return 0;
-}
-
-__initcall(init_crypto);
-
-/*
-EXPORT_SYMBOL_GPL(crypto_register_alg);
-EXPORT_SYMBOL_GPL(crypto_unregister_alg);
-EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
-EXPORT_SYMBOL_GPL(crypto_free_tfm);
-EXPORT_SYMBOL_GPL(crypto_alg_available);
-*/
-
-EXPORT_SYMBOL_NOVERS(crypto_register_alg);
-EXPORT_SYMBOL_NOVERS(crypto_unregister_alg);
-EXPORT_SYMBOL_NOVERS(crypto_alloc_tfm);
-EXPORT_SYMBOL_NOVERS(crypto_free_tfm);
-EXPORT_SYMBOL_NOVERS(crypto_alg_available);
diff --git a/drivers/staging/rtl8192su/ieee80211/arc4.c b/drivers/staging/rtl8192su/ieee80211/arc4.c
deleted file mode 100644
index e408472..0000000
--- a/drivers/staging/rtl8192su/ieee80211/arc4.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Cryptographic API
- *
- * ARC4 Cipher Algorithm
- *
- * Jon Oberheide <jon@oberheide.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.
- *
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include "rtl_crypto.h"
-
-#define ARC4_MIN_KEY_SIZE	1
-#define ARC4_MAX_KEY_SIZE	256
-#define ARC4_BLOCK_SIZE		1
-
-struct arc4_ctx {
-	u8 S[256];
-	u8 x, y;
-};
-
-static int arc4_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, u32 *flags)
-{
-	struct arc4_ctx *ctx = ctx_arg;
-	int i, j = 0, k = 0;
-
-	ctx->x = 1;
-	ctx->y = 0;
-
-	for(i = 0; i < 256; i++)
-		ctx->S[i] = i;
-
-	for(i = 0; i < 256; i++)
-	{
-		u8 a = ctx->S[i];
-		j = (j + in_key[k] + a) & 0xff;
-		ctx->S[i] = ctx->S[j];
-		ctx->S[j] = a;
-		if((unsigned int)++k >= key_len)
-			k = 0;
-	}
-
-	return 0;
-}
-
-static void arc4_crypt(void *ctx_arg, u8 *out, const u8 *in)
-{
-	struct arc4_ctx *ctx = ctx_arg;
-
-	u8 *const S = ctx->S;
-	u8 x = ctx->x;
-	u8 y = ctx->y;
-	u8 a, b;
-
-	a = S[x];
-	y = (y + a) & 0xff;
-	b = S[y];
-	S[x] = b;
-	S[y] = a;
-	x = (x + 1) & 0xff;
-	*out++ = *in ^ S[(a + b) & 0xff];
-
-	ctx->x = x;
-	ctx->y = y;
-}
-
-static struct crypto_alg arc4_alg = {
-	.cra_name		=	"arc4",
-	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
-	.cra_blocksize		=	ARC4_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct arc4_ctx),
-	.cra_module		=	THIS_MODULE,
-	.cra_list		=	LIST_HEAD_INIT(arc4_alg.cra_list),
-	.cra_u			=	{ .cipher = {
-	.cia_min_keysize	=	ARC4_MIN_KEY_SIZE,
-	.cia_max_keysize	=	ARC4_MAX_KEY_SIZE,
-	.cia_setkey	   	= 	arc4_set_key,
-	.cia_encrypt	 	=	arc4_crypt,
-	.cia_decrypt	  	=	arc4_crypt } }
-};
-
-static int __init arc4_init(void)
-{
-	return crypto_register_alg(&arc4_alg);
-}
-
-
-static void __exit arc4_exit(void)
-{
-	crypto_unregister_alg(&arc4_alg);
-}
-
-module_init(arc4_init);
-module_exit(arc4_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
-MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
diff --git a/drivers/staging/rtl8192su/ieee80211/autoload.c b/drivers/staging/rtl8192su/ieee80211/autoload.c
deleted file mode 100644
index c97756f..0000000
--- a/drivers/staging/rtl8192su/ieee80211/autoload.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Algorithm autoloader.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 "kmap_types.h"
-
-#include <linux/kernel.h>
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/string.h>
-#include <linux/kmod.h>
-#include "internal.h"
-
-/*
- * A far more intelligent version of this is planned.  For now, just
- * try an exact match on the name of the algorithm.
- */
-void crypto_alg_autoload(const char *name)
-{
-	request_module(name);
-}
-
-struct crypto_alg *crypto_alg_mod_lookup(const char *name)
-{
-	struct crypto_alg *alg = crypto_alg_lookup(name);
-	if (alg == NULL) {
-		crypto_alg_autoload(name);
-		alg = crypto_alg_lookup(name);
-	}
-	return alg;
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/cipher.c b/drivers/staging/rtl8192su/ieee80211/cipher.c
deleted file mode 100644
index 1968acf..0000000
--- a/drivers/staging/rtl8192su/ieee80211/cipher.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Cipher operations.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <asm/scatterlist.h>
-#include "internal.h"
-#include "scatterwalk.h"
-
-typedef void (cryptfn_t)(void *, u8 *, const u8 *);
-typedef void (procfn_t)(struct crypto_tfm *, u8 *,
-                        u8*, cryptfn_t, int enc, void *, int);
-
-static inline void xor_64(u8 *a, const u8 *b)
-{
-	((u32 *)a)[0] ^= ((u32 *)b)[0];
-	((u32 *)a)[1] ^= ((u32 *)b)[1];
-}
-
-static inline void xor_128(u8 *a, const u8 *b)
-{
-	((u32 *)a)[0] ^= ((u32 *)b)[0];
-	((u32 *)a)[1] ^= ((u32 *)b)[1];
-	((u32 *)a)[2] ^= ((u32 *)b)[2];
-	((u32 *)a)[3] ^= ((u32 *)b)[3];
-}
-
-
-/*
- * Generic encrypt/decrypt wrapper for ciphers, handles operations across
- * multiple page boundaries by using temporary blocks.  In user context,
- * the kernel is given a chance to schedule us once per block.
- */
-static int crypt(struct crypto_tfm *tfm,
-		 struct scatterlist *dst,
-		 struct scatterlist *src,
-                 unsigned int nbytes, cryptfn_t crfn,
-                 procfn_t prfn, int enc, void *info)
-{
-	struct scatter_walk walk_in, walk_out;
-	const unsigned int bsize = crypto_tfm_alg_blocksize(tfm);
-	u8 tmp_src[bsize];
-	u8 tmp_dst[bsize];
-
-	if (!nbytes)
-		return 0;
-
-	if (nbytes % bsize) {
-		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
-		return -EINVAL;
-	}
-
-	scatterwalk_start(&walk_in, src);
-	scatterwalk_start(&walk_out, dst);
-
-	for(;;) {
-		u8 *src_p, *dst_p;
-		int in_place;
-
-		scatterwalk_map(&walk_in, 0);
-		scatterwalk_map(&walk_out, 1);
-		src_p = scatterwalk_whichbuf(&walk_in, bsize, tmp_src);
-		dst_p = scatterwalk_whichbuf(&walk_out, bsize, tmp_dst);
-		in_place = scatterwalk_samebuf(&walk_in, &walk_out,
-					       src_p, dst_p);
-
-		nbytes -= bsize;
-
-		scatterwalk_copychunks(src_p, &walk_in, bsize, 0);
-
-		prfn(tfm, dst_p, src_p, crfn, enc, info, in_place);
-
-		scatterwalk_done(&walk_in, 0, nbytes);
-
-		scatterwalk_copychunks(dst_p, &walk_out, bsize, 1);
-		scatterwalk_done(&walk_out, 1, nbytes);
-
-		if (!nbytes)
-			return 0;
-
-		crypto_yield(tfm);
-	}
-}
-
-static void cbc_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-			cryptfn_t fn, int enc, void *info, int in_place)
-{
-	u8 *iv = info;
-
-	/* Null encryption */
-	if (!iv)
-		return;
-
-	if (enc) {
-		tfm->crt_u.cipher.cit_xor_block(iv, src);
-		fn(crypto_tfm_ctx(tfm), dst, iv);
-		memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm));
-	} else {
-		u8 stack[in_place ? crypto_tfm_alg_blocksize(tfm) : 0];
-		u8 *buf = in_place ? stack : dst;
-
-		fn(crypto_tfm_ctx(tfm), buf, src);
-		tfm->crt_u.cipher.cit_xor_block(buf, iv);
-		memcpy(iv, src, crypto_tfm_alg_blocksize(tfm));
-		if (buf != dst)
-			memcpy(dst, buf, crypto_tfm_alg_blocksize(tfm));
-	}
-}
-
-static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src,
-			cryptfn_t fn, int enc, void *info, int in_place)
-{
-	fn(crypto_tfm_ctx(tfm), dst, src);
-}
-
-static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
-{
-	struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
-
-	if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
-		tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	} else
-		return cia->cia_setkey(crypto_tfm_ctx(tfm), key, keylen,
-		                       &tfm->crt_flags);
-}
-
-static int ecb_encrypt(struct crypto_tfm *tfm,
-		       struct scatterlist *dst,
-                       struct scatterlist *src, unsigned int nbytes)
-{
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             ecb_process, 1, NULL);
-}
-
-static int ecb_decrypt(struct crypto_tfm *tfm,
-                       struct scatterlist *dst,
-                       struct scatterlist *src,
-		       unsigned int nbytes)
-{
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             ecb_process, 1, NULL);
-}
-
-static int cbc_encrypt(struct crypto_tfm *tfm,
-                       struct scatterlist *dst,
-                       struct scatterlist *src,
-		       unsigned int nbytes)
-{
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             cbc_process, 1, tfm->crt_cipher.cit_iv);
-}
-
-static int cbc_encrypt_iv(struct crypto_tfm *tfm,
-                          struct scatterlist *dst,
-                          struct scatterlist *src,
-                          unsigned int nbytes, u8 *iv)
-{
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_encrypt,
-	             cbc_process, 1, iv);
-}
-
-static int cbc_decrypt(struct crypto_tfm *tfm,
-                       struct scatterlist *dst,
-                       struct scatterlist *src,
-		       unsigned int nbytes)
-{
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             cbc_process, 0, tfm->crt_cipher.cit_iv);
-}
-
-static int cbc_decrypt_iv(struct crypto_tfm *tfm,
-                          struct scatterlist *dst,
-                          struct scatterlist *src,
-                          unsigned int nbytes, u8 *iv)
-{
-	return crypt(tfm, dst, src, nbytes,
-	             tfm->__crt_alg->cra_cipher.cia_decrypt,
-	             cbc_process, 0, iv);
-}
-
-static int nocrypt(struct crypto_tfm *tfm,
-                   struct scatterlist *dst,
-                   struct scatterlist *src,
-		   unsigned int nbytes)
-{
-	return -ENOSYS;
-}
-
-static int nocrypt_iv(struct crypto_tfm *tfm,
-                      struct scatterlist *dst,
-                      struct scatterlist *src,
-                      unsigned int nbytes, u8 *iv)
-{
-	return -ENOSYS;
-}
-
-int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
-{
-	u32 mode = flags & CRYPTO_TFM_MODE_MASK;
-
-	tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
-	if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
-		tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
-
-	return 0;
-}
-
-int crypto_init_cipher_ops(struct crypto_tfm *tfm)
-{
-	int ret = 0;
-	struct cipher_tfm *ops = &tfm->crt_cipher;
-
-	ops->cit_setkey = setkey;
-
-	switch (tfm->crt_cipher.cit_mode) {
-	case CRYPTO_TFM_MODE_ECB:
-		ops->cit_encrypt = ecb_encrypt;
-		ops->cit_decrypt = ecb_decrypt;
-		break;
-
-	case CRYPTO_TFM_MODE_CBC:
-		ops->cit_encrypt = cbc_encrypt;
-		ops->cit_decrypt = cbc_decrypt;
-		ops->cit_encrypt_iv = cbc_encrypt_iv;
-		ops->cit_decrypt_iv = cbc_decrypt_iv;
-		break;
-
-	case CRYPTO_TFM_MODE_CFB:
-		ops->cit_encrypt = nocrypt;
-		ops->cit_decrypt = nocrypt;
-		ops->cit_encrypt_iv = nocrypt_iv;
-		ops->cit_decrypt_iv = nocrypt_iv;
-		break;
-
-	case CRYPTO_TFM_MODE_CTR:
-		ops->cit_encrypt = nocrypt;
-		ops->cit_decrypt = nocrypt;
-		ops->cit_encrypt_iv = nocrypt_iv;
-		ops->cit_decrypt_iv = nocrypt_iv;
-		break;
-
-	default:
-		BUG();
-	}
-
-	if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) {
-
-	    	switch (crypto_tfm_alg_blocksize(tfm)) {
-	    	case 8:
-	    		ops->cit_xor_block = xor_64;
-	    		break;
-
-	    	case 16:
-	    		ops->cit_xor_block = xor_128;
-	    		break;
-
-	    	default:
-	    		printk(KERN_WARNING "%s: block size %u not supported\n",
-	    		       crypto_tfm_alg_name(tfm),
-	    		       crypto_tfm_alg_blocksize(tfm));
-	    		ret = -EINVAL;
-	    		goto out;
-	    	}
-
-		ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm);
-	    	ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL);
-		if (ops->cit_iv == NULL)
-			ret = -ENOMEM;
-	}
-
-out:
-	return ret;
-}
-
-void crypto_exit_cipher_ops(struct crypto_tfm *tfm)
-{
-	if (tfm->crt_cipher.cit_iv)
-		kfree(tfm->crt_cipher.cit_iv);
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/compress.c b/drivers/staging/rtl8192su/ieee80211/compress.c
deleted file mode 100644
index c2df80e..0000000
--- a/drivers/staging/rtl8192su/ieee80211/compress.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Compression operations.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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/types.h>
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/errno.h>
-#include <asm/scatterlist.h>
-#include <linux/string.h>
-#include "internal.h"
-
-static int crypto_compress(struct crypto_tfm *tfm,
-                            const u8 *src, unsigned int slen,
-                            u8 *dst, unsigned int *dlen)
-{
-	return tfm->__crt_alg->cra_compress.coa_compress(crypto_tfm_ctx(tfm),
-	                                                 src, slen, dst,
-	                                                 dlen);
-}
-
-static int crypto_decompress(struct crypto_tfm *tfm,
-                             const u8 *src, unsigned int slen,
-                             u8 *dst, unsigned int *dlen)
-{
-	return tfm->__crt_alg->cra_compress.coa_decompress(crypto_tfm_ctx(tfm),
-	                                                   src, slen, dst,
-	                                                   dlen);
-}
-
-int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags)
-{
-	return flags ? -EINVAL : 0;
-}
-
-int crypto_init_compress_ops(struct crypto_tfm *tfm)
-{
-	int ret = 0;
-	struct compress_tfm *ops = &tfm->crt_compress;
-
-	ret = tfm->__crt_alg->cra_compress.coa_init(crypto_tfm_ctx(tfm));
-	if (ret)
-		goto out;
-
-	ops->cot_compress = crypto_compress;
-	ops->cot_decompress = crypto_decompress;
-
-out:
-	return ret;
-}
-
-void crypto_exit_compress_ops(struct crypto_tfm *tfm)
-{
-	tfm->__crt_alg->cra_compress.coa_exit(crypto_tfm_ctx(tfm));
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/crypto_compat.h b/drivers/staging/rtl8192su/ieee80211/crypto_compat.h
deleted file mode 100644
index 587e8bb..0000000
--- a/drivers/staging/rtl8192su/ieee80211/crypto_compat.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Header file to maintain compatibility among different kernel versions.
- *
- * Copyright (c) 2004-2006  <lawrence_wang@realsil.com.cn>
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-#include <linux/crypto.h>
-
-static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *dst,
-                                        struct scatterlist *src,
-                                        unsigned int nbytes)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
-}
-
-
-static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *dst,
-                                        struct scatterlist *src,
-                                        unsigned int nbytes)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
-}
-
-#if 0
-/*
- *	crypto_free_tfm - Free crypto transform
- *	@tfm: Transform to free
- *
- *	crypto_free_tfm() frees up the transform and any associated resources,
- *	then drops the refcount on the associated algorithm.
- */
-void crypto_free_tfm(struct crypto_tfm *tfm)
-{
-	struct crypto_alg *alg;
-	int size;
-
-	if (unlikely(!tfm))
-		return;
-
-	alg = tfm->__crt_alg;
-	size = sizeof(*tfm) + alg->cra_ctxsize;
-
-	if (alg->cra_exit)
-		alg->cra_exit(tfm);
-	crypto_exit_ops(tfm);
-	crypto_mod_put(alg);
-	memset(tfm, 0, size);
-	kfree(tfm);
-}
-
-#endif
-#if 1
- struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
-{
-	struct crypto_tfm *tfm = NULL;
-	int err;
-	printk("call crypto_alloc_tfm!!!\n");
-	do {
-		struct crypto_alg *alg;
-
-		alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC);
-		err = PTR_ERR(alg);
-		if (IS_ERR(alg))
-			continue;
-
-		tfm = __crypto_alloc_tfm(alg, flags);
-		err = 0;
-		if (IS_ERR(tfm)) {
-			crypto_mod_put(alg);
-			err = PTR_ERR(tfm);
-			tfm = NULL;
-		}
-	} while (err == -EAGAIN && !signal_pending(current));
-
-	return tfm;
-}
-#endif
-//EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
-//EXPORT_SYMBOL_GPL(crypto_free_tfm);
-
-
diff --git a/drivers/staging/rtl8192su/ieee80211/digest.c b/drivers/staging/rtl8192su/ieee80211/digest.c
deleted file mode 100644
index 1a95f2d..0000000
--- a/drivers/staging/rtl8192su/ieee80211/digest.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Digest operations.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/highmem.h>
-#include <asm/scatterlist.h>
-#include "internal.h"
-
-static void init(struct crypto_tfm *tfm)
-{
-	tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm));
-}
-
-static void update(struct crypto_tfm *tfm,
-                   struct scatterlist *sg, unsigned int nsg)
-{
-	unsigned int i;
-
-	for (i = 0; i < nsg; i++) {
-
-		struct page *pg = sg[i].page;
-		unsigned int offset = sg[i].offset;
-		unsigned int l = sg[i].length;
-
-		do {
-			unsigned int bytes_from_page = min(l, ((unsigned int)
-							   (PAGE_SIZE)) -
-							   offset);
-			char *p = crypto_kmap(pg, 0) + offset;
-
-			tfm->__crt_alg->cra_digest.dia_update
-					(crypto_tfm_ctx(tfm), p,
-					 bytes_from_page);
-			crypto_kunmap(p, 0);
-			crypto_yield(tfm);
-			offset = 0;
-			pg++;
-			l -= bytes_from_page;
-		} while (l > 0);
-	}
-}
-
-static void final(struct crypto_tfm *tfm, u8 *out)
-{
-	tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out);
-}
-
-static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
-{
-	u32 flags;
-	if (tfm->__crt_alg->cra_digest.dia_setkey == NULL)
-		return -ENOSYS;
-	return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm),
-						     key, keylen, &flags);
-}
-
-static void digest(struct crypto_tfm *tfm,
-                   struct scatterlist *sg, unsigned int nsg, u8 *out)
-{
-	unsigned int i;
-
-	tfm->crt_digest.dit_init(tfm);
-
-	for (i = 0; i < nsg; i++) {
-		char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset;
-		tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm),
-		                                      p, sg[i].length);
-		crypto_kunmap(p, 0);
-		crypto_yield(tfm);
-	}
-	crypto_digest_final(tfm, out);
-}
-
-int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
-{
-	return flags ? -EINVAL : 0;
-}
-
-int crypto_init_digest_ops(struct crypto_tfm *tfm)
-{
-	struct digest_tfm *ops = &tfm->crt_digest;
-
-	ops->dit_init	= init;
-	ops->dit_update	= update;
-	ops->dit_final	= final;
-	ops->dit_digest	= digest;
-	ops->dit_setkey	= setkey;
-
-	return crypto_alloc_hmac_block(tfm);
-}
-
-void crypto_exit_digest_ops(struct crypto_tfm *tfm)
-{
-	crypto_free_hmac_block(tfm);
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/dot11d.c b/drivers/staging/rtl8192su/ieee80211/dot11d.c
index e5f2ded..2248462 100644
--- a/drivers/staging/rtl8192su/ieee80211/dot11d.c
+++ b/drivers/staging/rtl8192su/ieee80211/dot11d.c
@@ -1,4 +1,3 @@
-#ifdef ENABLE_DOT11D
 //-----------------------------------------------------------------------------
 //	File:
 //		Dot11d.c
@@ -35,10 +34,7 @@ Dot11d_Reset(struct ieee80211_device *ieee)
 {
 	u32 i;
 	PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-#if 0
-	if(!pDot11dInfo->bEnabled)
-		return;
-#endif
+
 	// Clear old channel map
 	memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
 	memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
@@ -218,22 +214,3 @@ int ToLegalChannel(
 
 	return default_chn;
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,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);
-#else
-EXPORT_SYMBOL_NOVERS(Dot11d_Init);
-EXPORT_SYMBOL_NOVERS(Dot11d_Reset);
-EXPORT_SYMBOL_NOVERS(Dot11d_UpdateCountryIe);
-EXPORT_SYMBOL_NOVERS(DOT11D_GetMaxTxPwrInDbm);
-EXPORT_SYMBOL_NOVERS(DOT11D_ScanComplete);
-EXPORT_SYMBOL_NOVERS(IsLegalChannel);
-EXPORT_SYMBOL_NOVERS(ToLegalChannel);
-#endif
-
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/dot11d.h b/drivers/staging/rtl8192su/ieee80211/dot11d.h
index 15b7a4b..913ac5d 100644
--- a/drivers/staging/rtl8192su/ieee80211/dot11d.h
+++ b/drivers/staging/rtl8192su/ieee80211/dot11d.h
@@ -1,11 +1,8 @@
 #ifndef __INC_DOT11D_H
 #define __INC_DOT11D_H
 
-#ifdef ENABLE_DOT11D
 #include "ieee80211.h"
 
-//#define ENABLE_DOT11D
-
 //#define DOT11D_MAX_CHNL_NUM 83
 
 typedef struct _CHNL_TXPOWER_TRIPLE {
@@ -98,5 +95,4 @@ int ToLegalChannel(
 	struct ieee80211_device * dev,
 	u8 channel
 );
-#endif //ENABLE_DOT11D
 #endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211.h b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
index 5e3a2cb..f22d024 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211.h
@@ -27,273 +27,28 @@
 #include <linux/kernel.h>   /* ARRAY_SIZE */
 #include <linux/version.h>
 #include <linux/module.h>
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 #include <linux/jiffies.h>
-#else
-#include <linux/jffs.h>
-#include <linux/tqueue.h>
-#endif
 #include <linux/timer.h>
 #include <linux/sched.h>
 
 #include <linux/delay.h>
 #include <linux/wireless.h>
+#include <linux/ieee80211.h>
 
 #include "rtl819x_HT.h"
 #include "rtl819x_BA.h"
 #include "rtl819x_TS.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-#ifndef bool
-typedef enum{false = 0, true} bool;
-#endif
-#endif
-
-#ifndef IW_MODE_MONITOR
-#define IW_MODE_MONITOR 6
-#endif
-
-#ifndef IWEVCUSTOM
-#define IWEVCUSTOM 0x8c02
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#ifndef __bitwise
-#define __bitwise __attribute__((bitwise))
-#endif
-typedef __u16  __le16;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27))
-struct iw_spy_data{
-	/* --- Standard spy support --- */
-	int 			spy_number;
-	u_char 			spy_address[IW_MAX_SPY][ETH_ALEN];
-	struct iw_quality	spy_stat[IW_MAX_SPY];
-	/* --- Enhanced spy support (event) */
-	struct iw_quality	spy_thr_low; /* Low threshold */
-	struct iw_quality	spy_thr_high; /* High threshold */
-	u_char			spy_thr_under[IW_MAX_SPY];
-};
-#endif
-#endif
-
-#ifndef container_of
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr:        the pointer to the member.
- * @type:       the type of the container struct this is embedded in.
- * @member:     the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({                      \
-        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
-        (type *)( (char *)__mptr - offsetof(type,member) );})
-#endif
-
 #define KEY_TYPE_NA		0x0
 #define KEY_TYPE_WEP40 		0x1
 #define KEY_TYPE_TKIP		0x2
 #define KEY_TYPE_CCMP		0x4
 #define KEY_TYPE_WEP104		0x5
 
-/* added for rtl819x tx procedure */
-#define MAX_QUEUE_SIZE		0x10
-
-//
-// 8190 queue mapping
-//
-#define BK_QUEUE                               0
-#define BE_QUEUE                               1
-#define VI_QUEUE                               2
-#define VO_QUEUE                               3
-#define HCCA_QUEUE                             4
-#define TXCMD_QUEUE                            5
-#define MGNT_QUEUE                             6
-#define HIGH_QUEUE                             7
-#define BEACON_QUEUE                           8
-
-#define LOW_QUEUE                              BE_QUEUE
-#define NORMAL_QUEUE                           MGNT_QUEUE
-
-//added by amy for ps
-#define SWRF_TIMEOUT				50
-
-//added by amy for LEAP related
-#define IE_CISCO_FLAG_POSITION		0x08	// Flag byte: byte 8, numbered from 0.
-#define SUPPORT_CKIP_MIC			0x08	// bit3
-#define SUPPORT_CKIP_PK			0x10	// bit4
-//added by amy for ps
-// RF Off Level for IPS or HW/SW radio off
-#define	RT_RF_OFF_LEVL_ASPM			BIT0	// PCI ASPM
-#define	RT_RF_OFF_LEVL_CLK_REQ		BIT1	// PCI clock request
-#define	RT_RF_OFF_LEVL_PCI_D3			BIT2	// PCI D3 mode
-#define	RT_RF_OFF_LEVL_HALT_NIC		BIT3	// NIC halt, re-initialize hw parameters
-#define	RT_RF_OFF_LEVL_FREE_FW		BIT4	// FW free, re-download the FW
-#define	RT_RF_OFF_LEVL_FW_32K		BIT5	// FW in 32k
-#define	RT_RF_PS_LEVEL_ALWAYS_ASPM	BIT6	// Always enable ASPM and Clock Req in initialization.
-#define	RT_RF_LPS_DISALBE_2R			BIT30	// When LPS is on, disable 2R if no packet is received or transmittd.
-#define	RT_RF_LPS_LEVEL_ASPM			BIT31	// LPS with ASPM
-#define	RT_IN_PS_LEVEL(pPSC, _PS_FLAG)	((pPSC->CurPsLevel & _PS_FLAG) ? true : false)
-#define	RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG)	(pPSC->CurPsLevel &= (~(_PS_FLAG)))
-#define	RT_SET_PS_LEVEL(pPSC, _PS_FLAG)	(pPSC->CurPsLevel->CurPsLevel |= _PS_FLAG)
-/* defined for skb cb field */
-/* At most 28 byte */
-typedef struct cb_desc {
-        /* Tx Desc Related flags (8-9) */
-	u8 bLastIniPkt:1;
-	u8 bCmdOrInit:1;
-        u8 bFirstSeg:1;
-        u8 bLastSeg:1;
-        u8 bEncrypt:1;
-        u8 bTxDisableRateFallBack:1;
-        u8 bTxUseDriverAssingedRate:1;
-        u8 bHwSec:1; //indicate whether use Hw security. WB
-
-        u8 reserved1;
-
-        /* Tx Firmware Relaged flags (10-11)*/
-        u8 bCTSEnable:1;
-        u8 bRTSEnable:1;
-        u8 bUseShortGI:1;
-        u8 bUseShortPreamble:1;
-        u8 bTxEnableFwCalcDur:1;
-        u8 bAMPDUEnable:1;
-        u8 bRTSSTBC:1;
-        u8 RTSSC:1;
-
-        u8 bRTSBW:1;
-        u8 bPacketBW:1;
-	u8 bRTSUseShortPreamble:1;
-	u8 bRTSUseShortGI:1;
-	u8 bMulticast:1;
-	u8 bBroadcast:1;
-        //u8 reserved2:2;
-        u8 drv_agg_enable:1;
-        u8 reserved2:1;
-
-        /* Tx Desc related element(12-19) */
-        u8 rata_index;
-        u8 queue_index;
-        //u8 reserved3;
-        //u8 reserved4;
-        u16 txbuf_size;
-        //u8 reserved5;
-	u8 RATRIndex;
-        u8 reserved6;
-        u8 reserved7;
-        u8 reserved8;
-
-        /* Tx firmware related element(20-27) */
-        u8 data_rate;
-        u8 rts_rate;
-        u8 ampdu_factor;
-        u8 ampdu_density;
-        //u8 reserved9;
-        //u8 reserved10;
-        //u8 reserved11;
-        u8 DrvAggrNum;
-	u16 pkt_size;
-        u8 reserved12;
-}cb_desc, *pcb_desc;
-
-/*--------------------------Define -------------------------------------------*/
-#define MGN_1M                  0x02
-#define MGN_2M                  0x04
-#define MGN_5_5M                0x0b
-#define MGN_11M                 0x16
-
-#define MGN_6M                  0x0c
-#define MGN_9M                  0x12
-#define MGN_12M                 0x18
-#define MGN_18M                 0x24
-#define MGN_24M                 0x30
-#define MGN_36M                 0x48
-#define MGN_48M                 0x60
-#define MGN_54M                 0x6c
-
-#define MGN_MCS0                0x80
-#define MGN_MCS1                0x81
-#define MGN_MCS2                0x82
-#define MGN_MCS3                0x83
-#define MGN_MCS4                0x84
-#define MGN_MCS5                0x85
-#define MGN_MCS6                0x86
-#define MGN_MCS7                0x87
-#define MGN_MCS8                0x88
-#define MGN_MCS9                0x89
-#define MGN_MCS10               0x8a
-#define MGN_MCS11               0x8b
-#define MGN_MCS12               0x8c
-#define MGN_MCS13               0x8d
-#define MGN_MCS14               0x8e
-#define MGN_MCS15               0x8f
-#define	MGN_MCS0_SG			0x90
-#define	MGN_MCS1_SG			0x91
-#define	MGN_MCS2_SG			0x92
-#define	MGN_MCS3_SG			0x93
-#define	MGN_MCS4_SG			0x94
-#define	MGN_MCS5_SG			0x95
-#define	MGN_MCS6_SG			0x96
-#define	MGN_MCS7_SG			0x97
-#define	MGN_MCS8_SG			0x98
-#define	MGN_MCS9_SG			0x99
-#define	MGN_MCS10_SG		0x9a
-#define	MGN_MCS11_SG		0x9b
-#define	MGN_MCS12_SG		0x9c
-#define	MGN_MCS13_SG		0x9d
-#define	MGN_MCS14_SG		0x9e
-#define	MGN_MCS15_SG		0x9f
-
-
-//----------------------------------------------------------------------------
-//		802.11 Management frame Reason Code field
-//----------------------------------------------------------------------------
-enum	_ReasonCode{
-	unspec_reason	= 0x1,
-	auth_not_valid	= 0x2,
-	deauth_lv_ss	= 0x3,
-	inactivity		= 0x4,
-	ap_overload 	= 0x5,
-	class2_err		= 0x6,
-	class3_err		= 0x7,
-	disas_lv_ss 	= 0x8,
-	asoc_not_auth	= 0x9,
-
-	//----MIC_CHECK
-	mic_failure 	= 0xe,
-	//----END MIC_CHECK
-
-	// Reason code defined in 802.11i D10.0 p.28.
-	invalid_IE		= 0x0d,
-	four_way_tmout	= 0x0f,
-	two_way_tmout	= 0x10,
-	IE_dismatch 	= 0x11,
-	invalid_Gcipher = 0x12,
-	invalid_Pcipher = 0x13,
-	invalid_AKMP	= 0x14,
-	unsup_RSNIEver = 0x15,
-	invalid_RSNIE	= 0x16,
-	auth_802_1x_fail= 0x17,
-	ciper_reject		= 0x18,
-
-	// Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
-	QoS_unspec		= 0x20, // 32
-	QAP_bandwidth	= 0x21, // 33
-	poor_condition	= 0x22, // 34
-	no_facility 	= 0x23, // 35
-							// Where is 36???
-	req_declined	= 0x25, // 37
-	invalid_param	= 0x26, // 38
-	req_not_honored= 0x27,	// 39
-	TS_not_created	= 0x2F, // 47
-	DL_not_allowed	= 0x30, // 48
-	dest_not_exist	= 0x31, // 49
-	dest_not_QSTA	= 0x32, // 50
-};
-
-
-
-#define aSifsTime	 (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10)
+#define aSifsTime (((priv->ieee80211->current_network.mode == IEEE_A) || \
+		    (priv->ieee80211->current_network.mode == IEEE_N_24G) || \
+		    (priv->ieee80211->current_network.mode == IEEE_N_5G)) \
+		   ? 16 : 10)
 
 #define MGMT_QUEUE_NUM 5
 
@@ -343,80 +98,6 @@ enum	_ReasonCode{
 
 #define MAX_IE_LEN  0xff
 
-// added for kernel conflict
-#define ieee80211_crypt_deinit_entries 	ieee80211_crypt_deinit_entries_rsl
-#define ieee80211_crypt_deinit_handler 	ieee80211_crypt_deinit_handler_rsl
-#define ieee80211_crypt_delayed_deinit 	ieee80211_crypt_delayed_deinit_rsl
-#define ieee80211_register_crypto_ops  	ieee80211_register_crypto_ops_rsl
-#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl
-#define ieee80211_get_crypto_ops 	ieee80211_get_crypto_ops_rsl
-
-#define ieee80211_ccmp_null		ieee80211_ccmp_null_rsl
-
-#define ieee80211_tkip_null		ieee80211_tkip_null_rsl
-
-#define ieee80211_wep_null		ieee80211_wep_null_rsl
-
-#define free_ieee80211          	free_ieee80211_rsl
-#define alloc_ieee80211        		alloc_ieee80211_rsl
-
-#define ieee80211_rx 			ieee80211_rx_rsl
-#define ieee80211_rx_mgt		ieee80211_rx_mgt_rsl
-
-#define ieee80211_get_beacon		ieee80211_get_beacon_rsl
-#define ieee80211_wake_queue		ieee80211_wake_queue_rsl
-#define ieee80211_stop_queue		ieee80211_stop_queue_rsl
-#define ieee80211_reset_queue		ieee80211_reset_queue_rsl
-#define ieee80211_softmac_stop_protocol	ieee80211_softmac_stop_protocol_rsl
-#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl
-#define ieee80211_is_shortslot		ieee80211_is_shortslot_rsl
-#define ieee80211_is_54g		ieee80211_is_54g_rsl
-#define ieee80211_wpa_supplicant_ioctl	ieee80211_wpa_supplicant_ioctl_rsl
-#define ieee80211_ps_tx_ack		ieee80211_ps_tx_ack_rsl
-#define ieee80211_softmac_xmit		ieee80211_softmac_xmit_rsl
-#define ieee80211_stop_send_beacons	ieee80211_stop_send_beacons_rsl
-#define notify_wx_assoc_event		notify_wx_assoc_event_rsl
-#define SendDisassociation		SendDisassociation_rsl
-#define ieee80211_disassociate		ieee80211_disassociate_rsl
-#define ieee80211_start_send_beacons	ieee80211_start_send_beacons_rsl
-#define ieee80211_stop_scan		ieee80211_stop_scan_rsl
-#define ieee80211_send_probe_requests	ieee80211_send_probe_requests_rsl
-#define ieee80211_softmac_scan_syncro	ieee80211_softmac_scan_syncro_rsl
-#define ieee80211_start_scan_syncro	ieee80211_start_scan_syncro_rsl
-
-#define ieee80211_wx_get_essid		ieee80211_wx_get_essid_rsl
-#define ieee80211_wx_set_essid		ieee80211_wx_set_essid_rsl
-#define ieee80211_wx_set_rate		ieee80211_wx_set_rate_rsl
-#define ieee80211_wx_get_rate		ieee80211_wx_get_rate_rsl
-#define ieee80211_wx_set_wap		ieee80211_wx_set_wap_rsl
-#define ieee80211_wx_get_wap		ieee80211_wx_get_wap_rsl
-#define ieee80211_wx_set_mode		ieee80211_wx_set_mode_rsl
-#define ieee80211_wx_get_mode		ieee80211_wx_get_mode_rsl
-#define ieee80211_wx_set_scan		ieee80211_wx_set_scan_rsl
-#define ieee80211_wx_get_freq		ieee80211_wx_get_freq_rsl
-#define ieee80211_wx_set_freq		ieee80211_wx_set_freq_rsl
-#define ieee80211_wx_set_rawtx		ieee80211_wx_set_rawtx_rsl
-#define ieee80211_wx_get_name		ieee80211_wx_get_name_rsl
-#define ieee80211_wx_set_power		ieee80211_wx_set_power_rsl
-#define ieee80211_wx_get_power		ieee80211_wx_get_power_rsl
-#define ieee80211_wlan_frequencies	ieee80211_wlan_frequencies_rsl
-#define ieee80211_wx_set_rts		ieee80211_wx_set_rts_rsl
-#define ieee80211_wx_get_rts		ieee80211_wx_get_rts_rsl
-
-#define ieee80211_txb_free		ieee80211_txb_free_rsl
-
-#define ieee80211_wx_set_gen_ie		ieee80211_wx_set_gen_ie_rsl
-#define ieee80211_wx_get_scan		ieee80211_wx_get_scan_rsl
-#define ieee80211_wx_set_encode		ieee80211_wx_set_encode_rsl
-#define ieee80211_wx_get_encode		ieee80211_wx_get_encode_rsl
-#if WIRELESS_EXT >= 18
-#define ieee80211_wx_set_mlme		ieee80211_wx_set_mlme_rsl
-#define ieee80211_wx_set_auth		ieee80211_wx_set_auth_rsl
-#define ieee80211_wx_set_encode_ext	ieee80211_wx_set_encode_ext_rsl
-#define ieee80211_wx_get_encode_ext	ieee80211_wx_get_encode_ext_rsl
-#endif
-
-
 typedef struct ieee_param {
 	u32 cmd;
 	u8 sta_addr[ETH_ALEN];
@@ -446,56 +127,8 @@ typedef struct ieee_param {
 	} u;
 }ieee_param;
 
-
-#if WIRELESS_EXT < 17
-#define IW_QUAL_QUAL_INVALID   0x10
-#define IW_QUAL_LEVEL_INVALID  0x20
-#define IW_QUAL_NOISE_INVALID  0x40
-#define IW_QUAL_QUAL_UPDATED   0x1
-#define IW_QUAL_LEVEL_UPDATED  0x2
-#define IW_QUAL_NOISE_UPDATED  0x4
-#endif
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static inline void tq_init(struct tq_struct * task, void(*func)(void *), void *data)
-{
-	task->routine = func;
-	task->data 	= data;
-	//task->next = NULL;
-	INIT_LIST_HEAD(&task->list);
-	task->sync = 0;
-}
-#endif
-
-// linux under 2.6.9 release may not support it, so modify it for common use
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
-//#define MSECS(t)	(1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
-#define MSECS(t)	(HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000)
-static inline unsigned long msleep_interruptible_rsl(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_INTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-         return timeout;
-}
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
-static inline void msleep(unsigned int msecs)
-{
-         unsigned long timeout = MSECS(msecs) + 1;
-
-         while (timeout) {
-                 set_current_state(TASK_UNINTERRUPTIBLE);
-                 timeout = schedule_timeout(timeout);
-         }
-}
-#endif
-#else
 #define MSECS(t) msecs_to_jiffies(t)
 #define msleep_interruptible_rsl  msleep_interruptible
-#endif
 
 #define IEEE80211_DATA_LEN		2304
 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
@@ -510,7 +143,7 @@ static inline void msleep(unsigned int msecs)
 #define IEEE80211_3ADDR_LEN 24
 #define IEEE80211_4ADDR_LEN 30
 #define IEEE80211_FCS_LEN    4
-#define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
+#define IEEE80211_HLEN			IEEE80211_4ADDR_LEN
 #define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
 #define IEEE80211_MGMT_HDR_LEN 24
 #define IEEE80211_DATA_HDR3_LEN 24
@@ -521,150 +154,50 @@ static inline void msleep(unsigned int msecs)
 
 
 /* Frame control field constants */
-#define IEEE80211_FCTL_VERS		0x0003
-#define IEEE80211_FCTL_FTYPE		0x000c
-#define IEEE80211_FCTL_STYPE		0x00f0
 #define IEEE80211_FCTL_FRAMETYPE	0x00fc
-#define IEEE80211_FCTL_TODS		0x0100
-#define IEEE80211_FCTL_FROMDS		0x0200
 #define IEEE80211_FCTL_DSTODS		0x0300 //added by david
-#define IEEE80211_FCTL_MOREFRAGS	0x0400
-#define IEEE80211_FCTL_RETRY		0x0800
-#define IEEE80211_FCTL_PM		0x1000
-#define IEEE80211_FCTL_MOREDATA		0x2000
 #define IEEE80211_FCTL_WEP		0x4000
-#define IEEE80211_FCTL_ORDER		0x8000
-
-#define IEEE80211_FTYPE_MGMT		0x0000
-#define IEEE80211_FTYPE_CTL		0x0004
-#define IEEE80211_FTYPE_DATA		0x0008
 
 /* management */
-#define IEEE80211_STYPE_ASSOC_REQ	0x0000
-#define IEEE80211_STYPE_ASSOC_RESP 	0x0010
-#define IEEE80211_STYPE_REASSOC_REQ	0x0020
-#define IEEE80211_STYPE_REASSOC_RESP	0x0030
-#define IEEE80211_STYPE_PROBE_REQ	0x0040
-#define IEEE80211_STYPE_PROBE_RESP	0x0050
-#define IEEE80211_STYPE_BEACON		0x0080
-#define IEEE80211_STYPE_ATIM		0x0090
-#define IEEE80211_STYPE_DISASSOC	0x00A0
-#define IEEE80211_STYPE_AUTH		0x00B0
-#define IEEE80211_STYPE_DEAUTH		0x00C0
 #define IEEE80211_STYPE_MANAGE_ACT	0x00D0
 
 /* control */
-#define IEEE80211_STYPE_PSPOLL		0x00A0
-#define IEEE80211_STYPE_RTS		0x00B0
-#define IEEE80211_STYPE_CTS		0x00C0
-#define IEEE80211_STYPE_ACK		0x00D0
-#define IEEE80211_STYPE_CFEND		0x00E0
-#define IEEE80211_STYPE_CFENDACK	0x00F0
 #define IEEE80211_STYPE_BLOCKACK   0x0094
 
-/* data */
-#define IEEE80211_STYPE_DATA		0x0000
-#define IEEE80211_STYPE_DATA_CFACK	0x0010
-#define IEEE80211_STYPE_DATA_CFPOLL	0x0020
-#define IEEE80211_STYPE_DATA_CFACKPOLL	0x0030
-#define IEEE80211_STYPE_NULLFUNC	0x0040
-#define IEEE80211_STYPE_CFACK		0x0050
-#define IEEE80211_STYPE_CFPOLL		0x0060
-#define IEEE80211_STYPE_CFACKPOLL	0x0070
-#define IEEE80211_STYPE_QOS_DATA	0x0080 //added for WMM 2006/8/2
-#define IEEE80211_STYPE_QOS_NULL	0x00C0
-
-#define IEEE80211_SCTL_FRAG		0x000F
-#define IEEE80211_SCTL_SEQ		0xFFF0
-
 /* QOS control */
 #define IEEE80211_QCTL_TID              0x000F
 
-#define	FC_QOS_BIT					BIT7
-#define IsDataFrame(pdu)			( ((pdu[0] & 0x0C)==0x08) ? true : false )
-#define	IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) )
-//added by wb. Is this right?
-#define IsQoSDataFrame(pframe)  ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA))
-#define Frame_Order(pframe)     (*(u16*)pframe&IEEE80211_FCTL_ORDER)
-#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
-#define SN_EQUAL(a, b)	(a == b)
-#define MAX_DEV_ADDR_SIZE 8
-typedef enum _ACT_CATEGORY{
-        ACT_CAT_QOS = 1,
-        ACT_CAT_DLS = 2,
-        ACT_CAT_BA  = 3,
-        ACT_CAT_HT  = 7,
-        ACT_CAT_WMM = 17,
-} ACT_CATEGORY, *PACT_CATEGORY;
-
-typedef enum _TS_ACTION{
-        ACT_ADDTSREQ = 0,
-        ACT_ADDTSRSP = 1,
-        ACT_DELTS    = 2,
-        ACT_SCHEDULE = 3,
-} TS_ACTION, *PTS_ACTION;
-
-typedef enum _BA_ACTION{
-        ACT_ADDBAREQ = 0,
-        ACT_ADDBARSP = 1,
-        ACT_DELBA    = 2,
-} BA_ACTION, *PBA_ACTION;
-
-typedef enum _InitialGainOpType{
-	IG_Backup=0,
-	IG_Restore,
-	IG_Max
-}InitialGainOpType;
-//added by amy for LED 090319
-//================================================================================
-// LED customization.
-//================================================================================
-typedef enum _LED_CTL_MODE{
-        LED_CTL_POWER_ON = 1,
-        LED_CTL_LINK = 2,
-        LED_CTL_NO_LINK = 3,
-        LED_CTL_TX = 4,
-        LED_CTL_RX = 5,
-        LED_CTL_SITE_SURVEY = 6,
-        LED_CTL_POWER_OFF = 7,
-        LED_CTL_START_TO_LINK = 8,
-        LED_CTL_START_WPS = 9,
-        LED_CTL_STOP_WPS = 10,
-        LED_CTL_START_WPS_BOTTON = 11, //added for runtop
-}LED_CTL_MODE;
-
 /* debug macros */
 #define CONFIG_IEEE80211_DEBUG
 #ifdef CONFIG_IEEE80211_DEBUG
 extern u32 ieee80211_debug_level;
 #define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
-  printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0)
-//wb added to debug out data buf
-//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA
-#define IEEE80211_DEBUG_DATA(level, data, datalen)	\
-	do{ if ((ieee80211_debug_level & (level)) == (level))	\
-		{ 	\
-			int i;					\
-			u8* pdata = (u8*) data;			\
-			printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__);	\
-			for(i=0; i<(int)(datalen); i++)			\
-			{						\
-				printk("%2x ", pdata[i]);		\
-				if ((i+1)%16 == 0) printk("\n");	\
-			}				\
-			printk("\n");			\
-		}					\
+	do { \
+		if (ieee80211_debug_level & (level)) \
+			printk(KERN_DEBUG "ieee80211: " fmt, ## args); \
+	} while (0)
+#define IEEE80211_DEBUG_DATA(level, data, datalen) \
+	do { \
+		if ((ieee80211_debug_level & (level)) == (level)) { \
+			u8 *pdata = (u8 *)data; \
+			int i; \
+			printk(KERN_DEBUG "ieee80211: %s()\n", __func__); \
+			for (i = 0; i < (int)(datalen); i++) { \
+				printk("%2x ", pdata[i]); \
+				if ((i + 1) % 16 == 0) \
+					printk("\n"); \
+			} \
+			printk("\n"); \
+		} \
 	} while (0)
 #else
 #define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
 #define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0)
 #endif	/* CONFIG_IEEE80211_DEBUG */
 
-/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */
-
 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
+#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], \
+		   ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
 
 /*
  * To use the debug system;
@@ -704,16 +237,17 @@ do { if (ieee80211_debug_level & (level)) \
 #define IEEE80211_DL_TX            (1<<8)
 #define IEEE80211_DL_RX            (1<<9)
 
-#define IEEE80211_DL_HT		   (1<<10)  //HT
-#define IEEE80211_DL_BA		   (1<<11)  //ba
-#define IEEE80211_DL_TS		   (1<<12)  //TS
-#define IEEE80211_DL_QOS           (1<<13)
-#define IEEE80211_DL_REORDER	   (1<<14)
-#define IEEE80211_DL_IOT	   (1<<15)
-#define IEEE80211_DL_IPS	   (1<<16)
-#define IEEE80211_DL_TRACE	   (1<<29)  //trace function, need to user net_ratelimit() together in order not to print too much to the screen
-#define IEEE80211_DL_DATA	   (1<<30)   //use this flag to control whether print data buf out.
-#define IEEE80211_DL_ERR	   (1<<31)   //always open
+#define IEEE80211_DL_HT		   (1 << 10)
+#define IEEE80211_DL_BA		   (1 << 11)
+#define IEEE80211_DL_TS		   (1 << 12)
+#define IEEE80211_DL_QOS           (1 << 13)
+#define IEEE80211_DL_REORDER	   (1 << 14)
+#define IEEE80211_DL_IOT	   (1 << 15)
+#define IEEE80211_DL_IPS	   (1 << 16)
+#define IEEE80211_DL_TRACE	   (1 << 29)
+#define IEEE80211_DL_DATA	   (1 << 30)
+#define IEEE80211_DL_ERR	   (1 << 31)
+
 #define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
 #define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
 #define IEEE80211_DEBUG_INFO(f, a...)   IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
@@ -729,32 +263,6 @@ do { if (ieee80211_debug_level & (level)) \
 #define IEEE80211_DEBUG_RX(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
 #define IEEE80211_DEBUG_QOS(f, a...)  IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a)
 
-#ifdef CONFIG_IEEE80211_DEBUG
-/* Added by Annie, 2005-11-22. */
-#define MAX_STR_LEN     64
-/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/
-#define PRINTABLE(_ch)  (_ch>'!' && _ch<'~')
-#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)                            	\
-                        if((_Comp) & level)   							\
-                        {                                                                       \
-                                int             __i;                                            \
-                                u8  buffer[MAX_STR_LEN];                                    	\
-                                int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ;  	\
-                                memset(buffer, 0, MAX_STR_LEN);                      		\
-                                memcpy(buffer, (u8 *)_Ptr, length );            		\
-                                for( __i=0; __i<MAX_STR_LEN; __i++ )                            \
-                                {                                                               \
-                                     if( !PRINTABLE(buffer[__i]) )   buffer[__i] = '?';     	\
-                                }                                                               \
-                                buffer[length] = '\0';                                          \
-                                printk("Rtl819x: ");                                         	\
-                                printk(_TitleString);                                         \
-                                printk(": %d, <%s>\n", _Len, buffer);                         \
-                        }
-#else
-#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len)  do {} while (0)
-#endif
-
 #include <linux/netdevice.h>
 #include <linux/if_arp.h> /* ARPHRD_ETHER */
 
@@ -796,93 +304,10 @@ struct ieee80211_snap_hdr {
 #define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
 #define WLAN_GET_SEQ_SEQ(seq)  (((seq) & IEEE80211_SCTL_SEQ) >> 4)
 
-/* Authentication algorithms */
-#define WLAN_AUTH_OPEN 0
-#define WLAN_AUTH_SHARED_KEY 1
-#define WLAN_AUTH_LEAP 2
-
-#define WLAN_AUTH_CHALLENGE_LEN 128
+#define RTL_WLAN_AUTH_LEAP 2
 
 #define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_IBSS (1<<1)
-#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
-#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
-#define WLAN_CAPABILITY_PRIVACY (1<<4)
-#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
-#define WLAN_CAPABILITY_PBCC (1<<6)
-#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
-#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8)
-#define WLAN_CAPABILITY_QOS (1<<9)
 #define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
-
-/* 802.11g ERP information element */
-#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
-#define WLAN_ERP_USE_PROTECTION (1<<1)
-#define WLAN_ERP_BARKER_PREAMBLE (1<<2)
-
-/* Status codes */
-enum ieee80211_statuscode {
-        WLAN_STATUS_SUCCESS = 0,
-        WLAN_STATUS_UNSPECIFIED_FAILURE = 1,
-        WLAN_STATUS_CAPS_UNSUPPORTED = 10,
-        WLAN_STATUS_REASSOC_NO_ASSOC = 11,
-        WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12,
-        WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13,
-        WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14,
-        WLAN_STATUS_CHALLENGE_FAIL = 15,
-        WLAN_STATUS_AUTH_TIMEOUT = 16,
-        WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17,
-        WLAN_STATUS_ASSOC_DENIED_RATES = 18,
-        /* 802.11b */
-        WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19,
-        WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20,
-        WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21,
-        /* 802.11h */
-        WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22,
-        WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23,
-        WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24,
-        /* 802.11g */
-        WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
-        WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
-        /* 802.11i */
-        WLAN_STATUS_INVALID_IE = 40,
-        WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
-        WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42,
-        WLAN_STATUS_INVALID_AKMP = 43,
-        WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
-        WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
-        WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
-};
-
-/* Reason codes */
-enum ieee80211_reasoncode {
-        WLAN_REASON_UNSPECIFIED = 1,
-        WLAN_REASON_PREV_AUTH_NOT_VALID = 2,
-        WLAN_REASON_DEAUTH_LEAVING = 3,
-        WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4,
-        WLAN_REASON_DISASSOC_AP_BUSY = 5,
-        WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6,
-        WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7,
-        WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8,
-        WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9,
-        /* 802.11h */
-        WLAN_REASON_DISASSOC_BAD_POWER = 10,
-        WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11,
-        /* 802.11i */
-        WLAN_REASON_INVALID_IE = 13,
-        WLAN_REASON_MIC_FAILURE = 14,
-        WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
-        WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16,
-        WLAN_REASON_IE_DIFFERENT = 17,
-        WLAN_REASON_INVALID_GROUP_CIPHER = 18,
-        WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19,
-        WLAN_REASON_INVALID_AKMP = 20,
-        WLAN_REASON_UNSUPP_RSN_VERSION = 21,
-        WLAN_REASON_INVALID_RSN_IE_CAP = 22,
-        WLAN_REASON_IEEE8021X_FAILED = 23,
-        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
-};
 
 #define IEEE80211_STATMASK_SIGNAL (1<<0)
 #define IEEE80211_STATMASK_RSSI (1<<1)
@@ -974,7 +399,6 @@ struct ieee_ibss_seq {
  *       information for frames received.  Not setting these will not cause
  *       any adverse affects. */
 struct ieee80211_rx_stats {
-#if 1
 	u32 mac_time[2];
 	s8 rssi;
 	u8 signal;
@@ -988,31 +412,29 @@ struct ieee80211_rx_stats {
 	u64 tsf;
 	u32 beacon_time;
 	u8 nic_type;
+
 	u16       Length;
-	//      u8        DataRate;      // In 0.5 Mbps
-	u8        SignalQuality; // in 0-100 index.
-	s32       RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation.
-	s8        RxPower; // in dBm Translate from PWdB
-	u8        SignalStrength; // in 0-100 index.
+	u8	  SignalQuality;	/* in 0-100 index */
+	/* real power in dBm for this packet, no beautification & aggregation */
+	s32       RecvSignalPower;
+	s8	  RxPower;		/* in dBm Translate from PWdB */
+	u8	  SignalStrength;	/* in 0-100 index */
 	u16       bHwError:1;
 	u16       bCRC:1;
 	u16       bICV:1;
 	u16       bShortPreamble:1;
-	u16       Antenna:1;      //for rtl8185
-	u16       Decrypted:1;    //for rtl8185, rtl8187
-	u16       Wakeup:1;       //for rtl8185
-	u16       Reserved0:1;    //for rtl8185
+	u16	  Antenna:1;		/* RTL8185 */
+	u16	  Decrypted:1;		/* RTL8185, RTL8187 */
+	u16	  Wakeup:1;		/* RTL8185 */
+	u16	  Reserved0:1;		/* RTL8185 */
 	u8        AGC;
 	u32       TimeStampLow;
 	u32       TimeStampHigh;
 	bool      bShift;
-	bool      bIsQosData;             // Added by Annie, 2005-12-22.
+	bool      bIsQosData;
 	u8        UserPriority;
 
-	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
-	//1Attention Please!!!<11n or 8190 specific code should be put below this line>
-	//1!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
+	/* < 11n or 8190 specific code */
 	u8        RxDrvInfoSize;
 	u8        RxBufShift;
 	bool      bIsAMPDU;
@@ -1020,25 +442,25 @@ struct ieee80211_rx_stats {
 	bool      bContainHTC;
 	bool      RxIs40MHzPacket;
 	u32       RxPWDBAll;
-	u8        RxMIMOSignalStrength[4];        // in 0~100 index
+	u8	  RxMIMOSignalStrength[4]; /* in 0~100 index */
 	s8        RxMIMOSignalQuality[2];
 	bool      bPacketMatchBSSID;
 	bool      bIsCCK;
 	bool      bPacketToSelf;
-	//added by amy
-	u8*       virtual_address;
-	u16          packetlength;              // Total packet length: Must equal to sum of all FragLength
-	u16          fraglength;                        // FragLength should equal to PacketLength in non-fragment case
-	u16          fragoffset;                        // Data offset for this fragment
-	u16          ntotalfrag;
-	bool      	  bisrxaggrsubframe;
-	bool		  bPacketBeacon;	//cosa add for rssi
-	bool		  bToSelfBA;		//cosa add for rssi
-	char 	  cck_adc_pwdb[4];	//cosa add for rx path selection
-	u16		  Seq_Num;
-	u8		nTotalAggPkt;		// Number of aggregated packets.
-#endif
 
+	u8	  *virtual_address;
+	/* total packet length: must equal to sum of all FragLength */
+	u16	  packetlength;
+	/* FragLength should equal to PacketLength in non-fragment case */
+	u16	  fraglength;
+	u16	  fragoffset;		/* data offset for this fragment */
+	u16	  ntotalfrag;
+	bool	  bisrxaggrsubframe;
+	bool	  bPacketBeacon;	/* for rssi */
+	bool	  bToSelfBA;		/* for rssi */
+	char	  cck_adc_pwdb[4];	/* for rx path selection */
+	u16	  Seq_Num;
+	u8	  nTotalAggPkt;		/* number of aggregated packets */
 };
 
 /* IEEE 802.11 requires that STA supports concurrent reception of at least
@@ -1093,7 +515,6 @@ struct ieee80211_device;
 #define SEC_UNICAST_GROUP (1<<6)
 #define SEC_LEVEL         (1<<7)
 #define SEC_ENABLED       (1<<8)
-#define SEC_ENCRYPT       (1<<9)
 
 #define SEC_LEVEL_0      0 /* None */
 #define SEC_LEVEL_1      1 /* WEP 40 and 104 bit */
@@ -1101,15 +522,9 @@ struct ieee80211_device;
 #define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
 #define SEC_LEVEL_3      4 /* Level 2 + CCMP */
 
-#define SEC_ALG_NONE            0
-#define SEC_ALG_WEP             1
-#define SEC_ALG_TKIP            2
-#define SEC_ALG_CCMP            3
-
 #define WEP_KEYS 		4
 #define WEP_KEY_LEN		13
 #define SCM_KEY_LEN             32
-#define SCM_TEMPORAL_KEY_LENGTH 16
 
 struct ieee80211_security {
 	u16 active_key:2,
@@ -1137,7 +552,7 @@ Total: 28-2340 bytes
 */
 
 /* Management Frame Information Element Types */
-enum ieee80211_mfie {
+enum {
         MFIE_TYPE_SSID = 0,
         MFIE_TYPE_RATES = 1,
         MFIE_TYPE_FH_SET = 2,
@@ -1173,7 +588,7 @@ enum ieee80211_mfie {
 /* Minimal header; can be used for passing 802.11 frames with sufficient
  * information to determine what type of underlying data type is actually
  * stored in the data. */
-struct ieee80211_hdr {
+struct rtl_ieee80211_hdr {
         __le16 frame_ctl;
         __le16 duration_id;
         u8 payload[0];
@@ -1249,7 +664,7 @@ struct ieee80211_authentication {
 	__le16 algorithm;
 	__le16 transaction;
 	__le16 status;
-	/*challenge*/
+	/* challenge */
 	struct ieee80211_info_element info_element[0];
 } __attribute__ ((packed));
 
@@ -1274,9 +689,6 @@ struct ieee80211_probe_response {
         struct ieee80211_info_element info_element[0];
 } __attribute__ ((packed));
 
-/* Alias beacon for probe_response */
-#define ieee80211_beacon ieee80211_probe_response
-
 struct ieee80211_assoc_request_frame {
 	struct ieee80211_hdr_3addr header;
 	__le16 capability;
@@ -1313,12 +725,6 @@ struct ieee80211_txb {
 	struct sk_buff *fragments[0];
 };
 
-#define MAX_TX_AGG_COUNT		  16
-struct ieee80211_drv_agg_txb {
-	u8 nr_drv_agg_frames;
-	struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT];
-}__attribute__((packed));
-
 #define MAX_SUBFRAME_COUNT 		  64
 struct ieee80211_rxb {
 	u8 nr_subframes;
@@ -1327,19 +733,7 @@ struct ieee80211_rxb {
 	u8 src[ETH_ALEN];
 }__attribute__((packed));
 
-typedef union _frameqos {
-	u16 shortdata;
-	u8  chardata[2];
-	struct {
-		u16 tid:4;
-		u16 eosp:1;
-		u16 ack_policy:2;
-		u16 reserved:1;
-		u16 txop:8;
-	}field;
-}frameqos,*pframeqos;
-
-/* SWEEP TABLE ENTRIES NUMBER*/
+/* SWEEP TABLE ENTRIES NUMBER */
 #define MAX_SWEEP_TAB_ENTRIES		  42
 #define MAX_SWEEP_TAB_ENTRIES_PER_PACKET  7
 /* MAX_RATES_LENGTH needs to be 12.  The spec says 8, and many APs
@@ -1351,31 +745,25 @@ typedef union _frameqos {
 #define MAX_NETWORK_COUNT                  128
 
 #define MAX_CHANNEL_NUMBER                 161
-#define IEEE80211_SOFTMAC_SCAN_TIME	   100
-//(HZ / 2)
+
+#define IEEE80211_SOFTMAC_SCAN_TIME	   100 /* (HZ / 2) */
 #define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
 
 #define CRC_LENGTH                 4U
 
 #define MAX_WPA_IE_LEN 64
 
-#define NETWORK_EMPTY_ESSID (1<<0)
-#define NETWORK_HAS_OFDM    (1<<1)
-#define NETWORK_HAS_CCK     (1<<2)
+#define NETWORK_EMPTY_ESSID	(1 << 0)
+#define NETWORK_HAS_OFDM	(1 << 1)
+#define NETWORK_HAS_CCK		(1 << 2)
 
 /* QoS structure */
-#define NETWORK_HAS_QOS_PARAMETERS      (1<<3)
-#define NETWORK_HAS_QOS_INFORMATION     (1<<4)
-#define NETWORK_HAS_QOS_MASK            (NETWORK_HAS_QOS_PARAMETERS | \
-                                         NETWORK_HAS_QOS_INFORMATION)
-/* 802.11h */
-#define NETWORK_HAS_POWER_CONSTRAINT    (1<<5)
-#define NETWORK_HAS_CSA                 (1<<6)
-#define NETWORK_HAS_QUIET               (1<<7)
-#define NETWORK_HAS_IBSS_DFS            (1<<8)
-#define NETWORK_HAS_TPC_REPORT          (1<<9)
-
-#define NETWORK_HAS_ERP_VALUE           (1<<10)
+#define NETWORK_HAS_QOS_PARAMETERS	(1 << 3)
+#define NETWORK_HAS_QOS_INFORMATION	(1 << 4)
+#define NETWORK_HAS_QOS_MASK		(NETWORK_HAS_QOS_PARAMETERS | \
+					 NETWORK_HAS_QOS_INFORMATION)
+
+#define NETWORK_HAS_ERP_VALUE		(1 << 10)
 
 #define QOS_QUEUE_NUM                   4
 #define QOS_OUI_LEN                     3
@@ -1385,7 +773,7 @@ typedef union _frameqos {
 #define QOS_OUI_PARAM_SUB_TYPE          1
 #define QOS_VERSION_1                   1
 #define QOS_AIFSN_MIN_VALUE             2
-#if 1
+
 struct ieee80211_qos_information_element {
         u8 elementID;
         u8 length;
@@ -1429,7 +817,6 @@ struct ieee80211_tim_parameters {
         u8 tim_period;
 } __attribute__ ((packed));
 
-//#else
 struct ieee80211_wmm_ac_param {
 	u8 ac_aci_acm_aifsn;
 	u8 ac_ecwmin_ecwmax;
@@ -1460,7 +847,7 @@ struct ieee80211_wmm_tspec_elem {
 	u16 surp_band_allow;
 	u16 medium_time;
 }__attribute__((packed));
-#endif
+
 enum eap_type {
 	EAP_PACKET = 0,
 	EAPOL_START,
@@ -1481,17 +868,6 @@ static inline const char *eap_get_type(int type)
 {
 	return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
 }
-//added by amy for reorder
-static inline u8 Frame_QoSTID(u8* buf)
-{
-	struct ieee80211_hdr_3addr *hdr;
-	u16 fc;
-	hdr = (struct ieee80211_hdr_3addr *)buf;
-	fc = le16_to_cpu(hdr->frame_ctl);
-	return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid;
-}
-
-//added by amy for reorder
 
 struct eapol {
 	u8 snap[6];
@@ -1501,7 +877,7 @@ struct eapol {
 	u16 length;
 } __attribute__ ((packed));
 
-struct ieee80211_softmac_stats{
+struct ieee80211_softmac_stats {
 	unsigned int rx_ass_ok;
 	unsigned int rx_ass_err;
 	unsigned int rx_probe_rq;
@@ -1549,7 +925,7 @@ struct ieee80211_info_element_hdr {
 */
 
 #define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps
+#define IEEE80211_DEFAULT_BASIC_RATE 2 /* 1Mbps */
 
 enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
 #define MAX_SP_Len  (WMM_all_frame << 4)
@@ -1579,18 +955,15 @@ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
 #define WME_AIFSN_MASK 0x03
 #define WME_AC_PRAM_LEN 16
 
-#define MAX_RECEIVE_BUFFER_SIZE 9100
-
 //UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
 //#define UP2AC(up)	((up<3) ? ((up==0)?1:0) : (up>>1))
-#if 1
 #define UP2AC(up) (		   \
 	((up) < 1) ? WME_AC_BE : \
 	((up) < 3) ? WME_AC_BK : \
 	((up) < 4) ? WME_AC_BE : \
 	((up) < 6) ? WME_AC_VI : \
 	WME_AC_VO)
-#endif
+
 //AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
 #define AC2UP(_ac)	(       \
 	((_ac) == WME_AC_VO) ? 6 : \
@@ -1599,7 +972,9 @@ enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
 	0)
 
 #define	ETHER_ADDR_LEN		6	/* length of an Ethernet address */
-#define ETHERNET_HEADER_SIZE    14      /* length of two Ethernet address plus ether type*/
+
+/* length of two Ethernet address plus ether type */
+#define ETHERNET_HEADER_SIZE	14
 
 struct	ether_header {
 	u8 ether_dhost[ETHER_ADDR_LEN];
@@ -1614,31 +989,6 @@ struct	ether_header {
 #define	ETHERTYPE_IP	0x0800		/* IP protocol */
 #endif
 
-typedef struct _bss_ht{
-
-	bool				support_ht;
-
-	// HT related elements
-	u8					ht_cap_buf[32];
-	u16					ht_cap_len;
-	u8					ht_info_buf[32];
-	u16					ht_info_len;
-
-	HT_SPEC_VER			ht_spec_ver;
-	//HT_CAPABILITY_ELE			bdHTCapEle;
-	//HT_INFORMATION_ELE		bdHTInfoEle;
-
-	bool				aggregation;
-	bool				long_slot_time;
-}bss_ht, *pbss_ht;
-
-typedef enum _erp_t{
-	ERP_NonERPpresent	= 0x01,
-	ERP_UseProtection	= 0x02,
-	ERP_BarkerPreambleMode = 0x04,
-} erp_t;
-
-
 struct ieee80211_network {
 	/* These entries are used to identify a unique network */
 	u8 bssid[ETH_ALEN];
@@ -1646,25 +996,24 @@ struct ieee80211_network {
 	/* Ensure null-terminated for any debug msgs */
 	u8 ssid[IW_ESSID_MAX_SIZE + 1];
 	u8 ssid_len;
-#if 1
+
         struct ieee80211_qos_data qos_data;
-#else
-       // Qos related. Added by Annie, 2005-11-01.
-        BSS_QOS   BssQos;
-#endif
 
-	//added by amy for LEAP
+	/* for LEAP */
 	bool	bWithAironetIE;
 	bool	bCkipSupported;
 	bool	bCcxRmEnable;
 	u16 	CcxRmState[2];
-	// CCXv4 S59, MBSSID.
+
+	/* CCXv4 S59, MBSSID. */
 	bool	bMBssidValid;
 	u8	MBssidMask;
 	u8	MBssid[6];
-	// CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20.
+
+	/* CCX 2 S38, WLAN Device Version Number element. */
 	bool	bWithCcxVerNum;
 	u8	BssCcxVerNumber;
+
 	/* These are network statistics */
 	struct ieee80211_rx_stats stats;
 	u16 capability;
@@ -1695,16 +1044,13 @@ struct ieee80211_network {
         u8 wmm_info;
         struct ieee80211_wmm_ac_param wmm_param[4];
         u8 QoS_Enable;
-#ifdef THOMAS_TURBO
 	u8 Turbo_Enable;//enable turbo mode, added by thomas
-#endif
-#ifdef ENABLE_DOT11D
 	u16 CountryIeLen;
 	u8 CountryIeBuf[MAX_IE_LEN];
-#endif
-        // HT Related, by amy, 2008.04.29
+
+	/* HT Related */
 	BSS_HT	bssht;
-	// Add to handle broadcom AP management frame CCK rate.
+	/* Added to handle broadcom AP management frame CCK rate. */
 	bool broadcom_cap_exist;
 	bool realtek_cap_exit;
 	bool marvell_cap_exist;
@@ -1712,14 +1058,12 @@ struct ieee80211_network {
 	bool atheros_cap_exist;
 	bool cisco_cap_exist;
 	bool unknown_cap_exist;
-//	u8	berp_info;
-	bool	berp_info_valid;
+	bool berp_info_valid;
 	bool buseprotection;
-	//put at the end of the structure.
-	struct list_head list;
+
+	struct list_head list;	/* put at the end of the structure */
 };
 
-#if 1
 enum ieee80211_state {
 
 	/* the card is not linked at all */
@@ -1758,24 +1102,12 @@ enum ieee80211_state {
 	IEEE80211_LINKED_SCANNING,
 
 };
-#else
-enum ieee80211_state {
-        IEEE80211_UNINITIALIZED = 0,
-        IEEE80211_INITIALIZED,
-        IEEE80211_ASSOCIATING,
-        IEEE80211_ASSOCIATED,
-        IEEE80211_AUTHENTICATING,
-        IEEE80211_AUTHENTICATED,
-        IEEE80211_SHUTDOWN
-};
-#endif
 
 #define DEFAULT_MAX_SCAN_AGE (15 * HZ)
 #define DEFAULT_FTS 2346
 
 #define CFG_IEEE80211_RESERVE_FCS (1<<0)
 #define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-#define CFG_IEEE80211_RTS (1<<2)
 
 #define IEEE80211_24GHZ_MIN_CHANNEL 1
 #define IEEE80211_24GHZ_MAX_CHANNEL 14
@@ -1787,167 +1119,12 @@ enum ieee80211_state {
 #define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
                                   IEEE80211_52GHZ_MIN_CHANNEL + 1)
 
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
-extern inline int is_multicast_ether_addr(const u8 *addr)
-{
-        return ((addr[0] != 0xff) && (0x01 & addr[0]));
-}
-#endif
-
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
-extern inline int is_broadcast_ether_addr(const u8 *addr)
-{
-	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
-		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
-}
-#endif
-
 typedef struct tx_pending_t{
 	int frag;
 	struct ieee80211_txb *txb;
 }tx_pending_t;
 
-typedef struct _bandwidth_autoswitch
-{
-	long threshold_20Mhzto40Mhz;
-	long	threshold_40Mhzto20Mhz;
-	bool bforced_tx20Mhz;
-	bool bautoswitch_enable;
-}bandwidth_autoswitch,*pbandwidth_autoswitch;
-
-
-//added by amy for order
-
-#define REORDER_WIN_SIZE	128
-#define REORDER_ENTRY_NUM	128
-typedef struct _RX_REORDER_ENTRY
-{
-	struct list_head	List;
-	u16			SeqNum;
-	struct ieee80211_rxb* prxb;
-} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
-//added by amy for order
-typedef enum _Fsync_State{
-	Default_Fsync,
-	HW_Fsync,
-	SW_Fsync
-}Fsync_State;
-
-// Power save mode configured.
-typedef	enum _RT_PS_MODE
-{
-	eActive,	// Active/Continuous access.
-	eMaxPs,		// Max power save mode.
-	eFastPs		// Fast power save mode.
-}RT_PS_MODE;
-
-typedef enum _IPS_CALLBACK_FUNCION
-{
-	IPS_CALLBACK_NONE = 0,
-	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
-	IPS_CALLBACK_JOIN_REQUEST = 2,
-}IPS_CALLBACK_FUNCION;
-
-typedef enum _RT_JOIN_ACTION{
-	RT_JOIN_INFRA   = 1,
-	RT_JOIN_IBSS  = 2,
-	RT_START_IBSS = 3,
-	RT_NO_ACTION  = 4,
-}RT_JOIN_ACTION;
-
-typedef struct _IbssParms{
-	u16   atimWin;
-}IbssParms, *PIbssParms;
-#define MAX_NUM_RATES	264 // Max num of support rates element: 8,  Max num of ext. support rate: 255. 061122, by rcnjko.
-
-// RF state.
-typedef	enum _RT_RF_POWER_STATE
-{
-	eRfOn,
-	eRfSleep,
-	eRfOff
-}RT_RF_POWER_STATE;
-
-typedef struct _RT_POWER_SAVE_CONTROL
-{
-
-	//
-	// Inactive Power Save(IPS) : Disable RF when disconnected
-	//
-	bool				bInactivePs;
-	bool				bIPSModeBackup;
-	bool				bHaltAdapterClkRQ;
-	bool				bSwRfProcessing;
-	RT_RF_POWER_STATE	eInactivePowerState;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	struct work_struct 	InactivePsWorkItem;
-#else
-	struct tq_struct	InactivePsWorkItem;
-#endif
-	struct timer_list	InactivePsTimer;
-
-	// Return point for join action
-	IPS_CALLBACK_FUNCION	ReturnPoint;
-
-	// Recored Parameters for rescheduled JoinRequest
-	bool				bTmpBssDesc;
-	RT_JOIN_ACTION		tmpJoinAction;
-	struct ieee80211_network tmpBssDesc;
-
-	// Recored Parameters for rescheduled MgntLinkRequest
-	bool				bTmpScanOnly;
-	bool				bTmpActiveScan;
-	bool				bTmpFilterHiddenAP;
-	bool				bTmpUpdateParms;
-	u8					tmpSsidBuf[33];
-	OCTET_STRING			tmpSsid2Scan;
-	bool				bTmpSsid2Scan;
-	u8					tmpNetworkType;
-	u8					tmpChannelNumber;
-	u16					tmpBcnPeriod;
-	u8					tmpDtimPeriod;
-	u16					tmpmCap;
-	OCTET_STRING			tmpSuppRateSet;
-	u8					tmpSuppRateBuf[MAX_NUM_RATES];
-	bool				bTmpSuppRate;
-	IbssParms				tmpIbpm;
-	bool				bTmpIbpm;
-
-	//
-	// Leisre Poswer Save : Disable RF if connected but traffic is not busy
-	//
-	bool				bLeisurePs;
-	u32				PowerProfile;
-	u8				LpsIdleCount;
-	u8				RegMaxLPSAwakeIntvl;
-	u8				LPSAwakeIntvl;
-
-	//RF OFF Level
-	u32				CurPsLevel;
-	u32				RegRfPsLevel;
-
-	//Fw Control LPS
-	bool				bFwCtrlLPS;
-	u8				FWCtrlPSMode;
-
-	//2009.01.01 added by tynli
-	// Record if there is a link request in IPS RF off progress.
-	bool				LinkReqInIPSRFOffPgs;
-	// To make sure that connect info should be executed, so we set the bit to filter the link info which comes after the connect info.
-	bool				BufConnectinfoBefore;
-
-}RT_POWER_SAVE_CONTROL,*PRT_POWER_SAVE_CONTROL;
-
-typedef u32 RT_RF_CHANGE_SOURCE;
-#define RF_CHANGE_BY_SW BIT31
-#define RF_CHANGE_BY_HW BIT30
-#define RF_CHANGE_BY_PS BIT29
-#define RF_CHANGE_BY_IPS BIT28
-#define RF_CHANGE_BY_INIT	0	// Do not change the RFOff reason. Defined by Bruce, 2008-01-17.
-
-#ifdef ENABLE_DOT11D
-typedef enum
-{
+enum {
 	COUNTRY_CODE_FCC = 0,
 	COUNTRY_CODE_IC = 1,
 	COUNTRY_CODE_ETSI = 2,
@@ -1959,108 +1136,66 @@ typedef enum
 	COUNTRY_CODE_TELEC,
 	COUNTRY_CODE_MIC,
 	COUNTRY_CODE_GLOBAL_DOMAIN
-}country_code_type_t;
-#endif
-	// Firmware realted CMD IO.
-typedef	enum _FW_CMD_IO_TYPE{
-	FW_CMD_DIG_ENABLE = 0, // For DIG DM
-	FW_CMD_DIG_DISABLE = 1,
-	FW_CMD_DIG_HALT = 2,
-	FW_CMD_DIG_RESUME = 3,
-	FW_CMD_HIGH_PWR_ENABLE = 4, // For High Power DM
-	FW_CMD_HIGH_PWR_DISABLE = 5,
-	FW_CMD_RA_RESET = 6, // For Rate adaptive DM
-	FW_CMD_RA_ACTIVE= 7,
-	FW_CMD_RA_REFRESH_N= 8,
-	FW_CMD_RA_REFRESH_BG= 9,
-	FW_CMD_IQK_ENABLE = 10, // For FW supported IQK
-	FW_CMD_TXPWR_TRACK_ENABLE = 11,	// Tx power tracking switch
-	FW_CMD_TXPWR_TRACK_DISABLE = 12,	// Tx power tracking switch
-	FW_CMD_PAUSE_DM_BY_SCAN = 13,
-	FW_CMD_RESUME_DM_BY_SCAN = 14,
-	FW_CMD_MID_HIGH_PWR_ENABLE = 15,
-	FW_CMD_LPS_ENTER = 16,			// Indifate firmware that driver enters LPS, For PS-Poll hardware bug
-	FW_CMD_LPS_LEAVE = 17,			// Indicate firmware that driver leave LPS, 2009/1/4, by Emily
-}FW_CMD_IO_TYPE,*PFW_CMD_IO_TYPE;
-#define RT_MAX_LD_SLOT_NUM	10
-typedef struct _RT_LINK_DETECT_T{
-
-	u32				NumRecvBcnInPeriod;
-	u32				NumRecvDataInPeriod;
-
-	u32				RxBcnNum[RT_MAX_LD_SLOT_NUM];	// number of Rx beacon / CheckForHang_period  to determine link status
-	u32				RxDataNum[RT_MAX_LD_SLOT_NUM];	// number of Rx data / CheckForHang_period  to determine link status
-	u16				SlotNum;	// number of CheckForHang period to determine link status
-	u16				SlotIndex;
-
-	u32				NumTxOkInPeriod;
-	u32				NumRxOkInPeriod;
-	bool				bBusyTraffic;
-}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T;
+};
 
+#include "ieee80211_r8192s.h"
 
 struct ieee80211_device {
 	struct net_device *dev;
         struct ieee80211_security sec;
 
-	//hw security related
-//	u8 hwsec_support; //support?
-	u8 hwsec_active;  //hw security active.
+	/* hw security related */
+	u8 hwsec_active;
 	bool is_silent_reset;
 	bool is_roaming;
 	bool ieee_up;
-	//added by amy
 	bool bSupportRemoteWakeUp;
-	RT_PS_MODE	dot11PowerSaveMode; // Power save mode configured.
+	RT_PS_MODE dot11PowerSaveMode;
 	bool actscanning;
-	//added by amy 090313
 	bool be_scan_inprogress;
 	bool beinretry;
-	RT_RF_POWER_STATE		eRFPowerState;
-	RT_RF_CHANGE_SOURCE	RfOffReason;
+	RT_RF_POWER_STATE eRFPowerState;
+	u32 RfOffReason;
 	bool is_set_key;
-	//11n spec related I wonder if These info structure need to be moved out of ieee80211_device
 
-	//11n HT below
-	PRT_HIGH_THROUGHPUT	pHTInfo;
-	//struct timer_list		SwBwTimer;
-//	spinlock_t chnlop_spinlock;
+	/* 11n HT below */
+	PRT_HIGH_THROUGHPUT pHTInfo;
 	spinlock_t bw_spinlock;
 
 	spinlock_t reorder_spinlock;
-	// for HT operation rate set.  we use this one for HT data rate to seperate different descriptors
-	//the way fill this is the same as in the IE
-	u8	Regdot11HTOperationalRateSet[16];		//use RATR format
-	u8	dot11HTOperationalRateSet[16];		//use RATR format
+	/*
+	 * for HT operation rate set, we use this one for HT data rate to
+	 * seperate different descriptors the way fill this is the same as
+	 * in the IE
+	 */
+	u8	Regdot11HTOperationalRateSet[16];	/* use RATR format */
+	u8	dot11HTOperationalRateSet[16];		/* use RATR format */
 	u8	RegHTSuppRateSet[16];
-	u8				HTCurrentOperaRate;
-	u8				HTHighestOperaRate;
-	//wb added for rate operation mode to firmware
+	u8	HTCurrentOperaRate;
+	u8	HTHighestOperaRate;
+	/* for rate operation mode to firmware */
 	u8	bTxDisableRateFallBack;
 	u8 	bTxUseDriverAssingedRate;
 	atomic_t	atm_chnlop;
 	atomic_t	atm_swbw;
-//	u8	HTHighestOperaRate;
-//	u8 	HTCurrentOperaRate;
 
-	// 802.11e and WMM Traffic Stream Info (TX)
-	struct list_head		Tx_TS_Admit_List;
-	struct list_head		Tx_TS_Pending_List;
-	struct list_head		Tx_TS_Unused_List;
+	/* 802.11e and WMM Traffic Stream Info (TX) */
+	struct list_head	Tx_TS_Admit_List;
+	struct list_head	Tx_TS_Pending_List;
+	struct list_head	Tx_TS_Unused_List;
 	TX_TS_RECORD		TxTsRecord[TOTAL_TS_NUM];
-	// 802.11e and WMM Traffic Stream Info (RX)
-	struct list_head		Rx_TS_Admit_List;
-	struct list_head		Rx_TS_Pending_List;
-	struct list_head		Rx_TS_Unused_List;
+	/* 802.11e and WMM Traffic Stream Info (RX) */
+	struct list_head	Rx_TS_Admit_List;
+	struct list_head	Rx_TS_Pending_List;
+	struct list_head	Rx_TS_Unused_List;
 	RX_TS_RECORD		RxTsRecord[TOTAL_TS_NUM];
-//#ifdef TO_DO_LIST
+
 	RX_REORDER_ENTRY	RxReorderEntry[128];
-	struct list_head		RxReorder_Unused_List;
-//#endif
-	// Qos related. Added by Annie, 2005-11-01.
-//	PSTA_QOS			pStaQos;
-	u8				ForcedPriority;		// Force per-packet priority 1~7. (default: 0, not to force it.)
+	struct list_head	RxReorder_Unused_List;
 
+	/* Qos related */
+	/* Force per-packet priority 1~7. (default: 0, not to force it.) */
+	u8 ForcedPriority;
 
 	/* Bookkeeping structures */
 	struct net_device_stats stats;
@@ -2167,14 +1302,12 @@ struct ieee80211_device {
 
         u16 prev_seq_ctl;       /* used to drop duplicate frames */
 
-	/* map of allowed channels. 0 is dummy */
-	// FIXME: remeber to default to a basic channel plan depending of the PHY type
-#ifdef ENABLE_DOT11D
-	void* pDot11dInfo;
+	/*
+	 * map of allowed channels. 0 is dummy, FIXME: remeber to default to
+	 * a basic channel plan depending of the PHY type
+	 */
+	void *pDot11dInfo;
 	bool bGlobalDomain;
-#else
-	int channel_map[MAX_CHANNEL_NUMBER+1];
-#endif
 	int rate;       /* current rate */
 	int basic_rate;
 	//FIXME: pleace callback, see if redundant with softmac_features
@@ -2242,46 +1375,46 @@ struct ieee80211_device {
 	struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
 	int mgmt_queue_head;
 	int mgmt_queue_tail;
-//{ added for rtl819x
-#define IEEE80211_QUEUE_LIMIT 128
+
+/* rtl819x start */
 	u8 AsocRetryCount;
 	unsigned int hw_header;
 	struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE];
-	struct sk_buff_head  skb_aggQ[MAX_QUEUE_SIZE];
-	struct sk_buff_head  skb_drv_aggQ[MAX_QUEUE_SIZE];
-	u32	sta_edca_param[4];
+	struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE];
+	struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE];
+	u32 sta_edca_param[4];
 	bool aggregation;
-	// Enable/Disable Rx immediate BA capability.
+	/* Enable/Disable Rx immediate BA capability. */
 	bool enable_rx_imm_BA;
 	bool bibsscoordinator;
 
-	//+by amy for DM ,080515
-	//Dynamic Tx power for near/far range enable/Disable  , by amy , 2008-05-15
-	bool	bdynamic_txpower_enable;
+	/* Dynamic Tx power for near/far range enable/disable. */
+	bool bdynamic_txpower_enable;
 
 	bool bCTSToSelfEnable;
-	u8 	CTSToSelfTH;
+	u8 CTSToSelfTH;
 
-	u32 	fsync_time_interval;
+	u32	fsync_time_interval;
 	u32	fsync_rate_bitmap;
 	u8	fsync_rssi_threshold;
 	bool	bfsync_enable;
 
-	u8	fsync_multiple_timeinterval;		// FsyncMultipleTimeInterval * FsyncTimeInterval
-	u32	fsync_firstdiff_ratethreshold;		// low threshold
-	u32	fsync_seconddiff_ratethreshold;	 // decrease threshold
-	Fsync_State			fsync_state;
+	u8	fsync_multiple_timeinterval;	/* value * FsyncTimeInterval */
+	u32	fsync_firstdiff_ratethreshold;	/* low threshold */
+	u32	fsync_seconddiff_ratethreshold;	/* decrease threshold */
+	Fsync_State	fsync_state;
 	bool		bis_any_nonbepkts;
-	//20Mhz 40Mhz AutoSwitch Threshold
-	bandwidth_autoswitch bandwidth_auto_switch;
-	//for txpower tracking
+	/* 20Mhz 40Mhz AutoSwitch Threshold */
+	struct bandwidth_autoswitch bandwidth_auto_switch;
+	/* for txpower tracking */
 	bool FwRWRF;
 
-	//added by amy for AP roaming
-	RT_LINK_DETECT_T	LinkDetectInfo;
-        //added by amy for ps
-	RT_POWER_SAVE_CONTROL	PowerSaveControl;
-//}
+	/* for AP roaming */
+	struct rt_link_detect LinkDetectInfo;
+
+	struct rt_power_save_control PowerSaveControl;
+/* rtl819x end */
+
 	/* used if IEEE_SOFTMAC_TX_QUEUE is set */
 	struct  tx_pending_t tx_pending;
 
@@ -2290,47 +1423,16 @@ struct ieee80211_device {
 
 	/* used if IEEE_SOFTMAC_BEACONS is set */
 	struct timer_list beacon_timer;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
         struct work_struct associate_complete_wq;
         struct work_struct associate_procedure_wq;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
         struct delayed_work softmac_scan_wq;
         struct delayed_work associate_retry_wq;
-	 struct delayed_work start_ibss_wq;
-	 struct delayed_work hw_wakeup_wq;
+	struct delayed_work start_ibss_wq;
+	struct delayed_work hw_wakeup_wq;
 	struct delayed_work hw_sleep_wq;
 	struct delayed_work link_change_wq;
-#else
-        struct work_struct softmac_scan_wq;
-        struct work_struct associate_retry_wq;
-	struct work_struct start_ibss_wq;
-	struct work_struct hw_wakeup_wq;
-	struct work_struct hw_sleep_wq;
-	struct work_struct link_change_wq;
-#endif
         struct work_struct wx_sync_scan_wq;
         struct workqueue_struct *wq;
-#else
-	/* used for periodly scan */
-	struct timer_list scan_timer;
-
-	struct tq_struct associate_complete_wq;
-	struct tq_struct associate_retry_wq;
-	struct tq_struct start_ibss_wq;
-	struct tq_struct associate_procedure_wq;
-	struct tq_struct softmac_scan_wq;
-	struct tq_struct wx_sync_scan_wq;
-	struct tq_struct hw_wakeup_wq;
-	struct tq_struct hw_sleep_wq;
-	struct tq_struct link_change_wq;
-
-#endif
-        // Qos related. Added by Annie, 2005-11-01.
-        //STA_QOS  StaQos;
-
-        //u32 STA_EDCA_PARAM[4];
-	//CHANNEL_ACCESS_SETTING ChannelAccessSetting;
-
 
 	/* Callback functions */
 	void (*set_security)(struct net_device *dev,
@@ -2344,11 +1446,11 @@ struct ieee80211_device {
 			       struct net_device *dev);
 
 	int (*reset_port)(struct net_device *dev);
-        int (*is_queue_full) (struct net_device * dev, int pri);
+	int (*is_queue_full)(struct net_device *dev, int pri);
 
-        int (*handle_management) (struct net_device * dev,
-                                  struct ieee80211_network * network, u16 type);
-        int (*is_qos_active) (struct net_device *dev, struct sk_buff *skb);
+	int (*handle_management)(struct net_device *dev,
+				 struct ieee80211_network *network, u16 type);
+	int (*is_qos_active)(struct net_device *dev, struct sk_buff *skb);
 
 	/* Softmac-generated frames (mamagement) are TXed via this
 	 * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
@@ -2421,52 +1523,30 @@ struct ieee80211_device {
 
 	/* power save mode related */
 	void (*sta_wake_up) (struct net_device *dev);
-//	void (*ps_request_tx_ack) (struct net_device *dev);
 	void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
 	short (*ps_is_queue_empty) (struct net_device *dev);
-#if 0
-	/* Typical STA methods */
-        int (*handle_auth) (struct net_device * dev,
-                            struct ieee80211_auth * auth);
-        int (*handle_deauth) (struct net_device * dev,
-                              struct ieee80211_deauth * auth);
-        int (*handle_action) (struct net_device * dev,
-                              struct ieee80211_action * action,
-                              struct ieee80211_rx_stats * stats);
-        int (*handle_disassoc) (struct net_device * dev,
-                                struct ieee80211_disassoc * assoc);
-#endif
-        int (*handle_beacon) (struct net_device * dev, struct ieee80211_beacon * beacon, struct ieee80211_network * network);
-#if 0
-        int (*handle_probe_response) (struct net_device * dev,
-                                      struct ieee80211_probe_response * resp,
-                                      struct ieee80211_network * network);
-        int (*handle_probe_request) (struct net_device * dev,
-                                     struct ieee80211_probe_request * req,
-                                     struct ieee80211_rx_stats * stats);
-#endif
-        int (*handle_assoc_response) (struct net_device * dev, struct ieee80211_assoc_response_frame * resp, struct ieee80211_network * network);
 
-#if 0
-        /* Typical AP methods */
-        int (*handle_assoc_request) (struct net_device * dev);
-        int (*handle_reassoc_request) (struct net_device * dev,
-                                       struct ieee80211_reassoc_request * req);
-#endif
+	int (*handle_beacon)(struct net_device *dev,
+			     struct ieee80211_probe_response *beacon,
+			     struct ieee80211_network *network);
+	int (*handle_assoc_response)(struct net_device *dev,
+				struct ieee80211_assoc_response_frame *resp,
+				struct ieee80211_network *network);
 
 	/* check whether Tx hw resouce available */
 	short (*check_nic_enough_desc)(struct net_device *dev, int queue_index);
-	//added by wb for HT related
-//	void (*SwChnlByTimerHandler)(struct net_device *dev, int channel);
-	void (*SetBWModeHandler)(struct net_device *dev, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset);
-//	void (*UpdateHalRATRTableHandler)(struct net_device* dev, u8* pMcsRate);
+	/* HT related */
+	void (*SetBWModeHandler)(struct net_device *dev,
+				 HT_CHANNEL_WIDTH Bandwidth,
+				 HT_EXTCHNL_OFFSET Offset);
 	bool (*GetNmodeSupportBySecCfg)(struct net_device* dev);
 	void (*SetWirelessMode)(struct net_device* dev, u8 wireless_mode);
 	bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device* dev);
 	bool (*is_ap_in_wep_tkip)(struct net_device* dev);
 	void (*InitialGainHandler)(struct net_device *dev, u8 Operation);
-	bool (*SetFwCmdHandler)(struct net_device *dev,	FW_CMD_IO_TYPE		FwCmdIO);
-	void (*LedControlHandler)(struct net_device * dev, LED_CTL_MODE LedAction);
+	bool (*SetFwCmdHandler)(struct net_device *dev, FW_CMD_IO_TYPE FwCmdIO);
+	void (*LedControlHandler)(struct net_device *dev,
+				  LED_CTL_MODE LedAction);
 	/* This must be the last item so that it points to the data
 	 * allocated beyond this structure by alloc_ieee80211 */
 	u8 priv[0];
@@ -2512,11 +1592,7 @@ struct ieee80211_device {
 
 static inline void *ieee80211_priv(struct net_device *dev)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-#else
-	return ((struct ieee80211_device *)dev->priv)->priv;
-#endif
 }
 
 extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
@@ -2588,7 +1664,7 @@ extern inline int ieee80211_get_hdrlen(u16 fc)
 	return hdrlen;
 }
 
-static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
+static inline u8 *ieee80211_get_payload(struct rtl_ieee80211_hdr *hdr)
 {
         switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) {
         case IEEE80211_1ADDR_LEN:
@@ -2667,10 +1743,6 @@ extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
 				   struct iw_request_info *info,
 				   union iwreq_data *wrqu, char *key);
-#if WIRELESS_EXT >= 18
-extern int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
-                            struct iw_request_info *info,
-                            union iwreq_data* wrqu, char *extra);
 extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                             struct iw_request_info *info,
                             union iwreq_data* wrqu, char *extra);
@@ -2680,7 +1752,6 @@ extern int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
 extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra);
-#endif
 extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
 
 /* ieee80211_softmac.c */
@@ -2768,13 +1839,7 @@ extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_reques
 extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b);
 
-//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-#else
- extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
-#endif
-
 
 extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
 			       struct iw_request_info *info,
@@ -2799,55 +1864,8 @@ extern int ieee80211_wx_set_rts(struct ieee80211_device *ieee,
 extern int ieee80211_wx_get_rts(struct ieee80211_device *ieee,
 			     struct iw_request_info *info,
 			     union iwreq_data *wrqu, char *extra);
-//HT
-#define MAX_RECEIVE_BUFFER_SIZE 9100  //
-extern void HTDebugHTCapability(u8* CapIE, u8* TitleString );
-extern void HTDebugHTInfo(u8*  InfoIE, u8* TitleString);
-
-void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET    Offset);
-extern void HTUpdateDefaultSetting(struct ieee80211_device* ieee);
-extern void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 isEncrypt);
-extern void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 isEncrypt);
-extern void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len);
-extern void HTOnAssocRsp(struct ieee80211_device *ieee);
-extern void HTInitializeHTInfo(struct ieee80211_device* ieee);
-extern void HTInitializeBssDesc(PBSS_HT pBssHT);
-extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork);
-extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee,   struct ieee80211_network * pNetwork);
-extern u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter);
-extern u8 MCS_FILTER_ALL[];
-extern u16 MCS_DATA_RATE[2][2][77] ;
-extern u8 HTCCheck(struct ieee80211_device* ieee, u8*   pFrame);
-//extern void HTSetConnectBwModeCallback(unsigned long data);
-extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT  pHTInfo);
-extern bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee);
-extern u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee,  u8      nMcsRate);
-extern u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate);
-extern u16  TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate);
-//function in BAPROC.c
-extern int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb);
-extern int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb);
-extern int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb);
-extern void TsInitAddBA( struct ieee80211_device* ieee, PTX_TS_RECORD   pTS, u8 Policy, u8 bOverwritePending);
-extern void TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
-extern void BaSetupTimeOut(unsigned long data);
-extern void TxBaInactTimeout(unsigned long data);
-extern void RxBaInactTimeout(unsigned long data);
-extern void ResetBaEntry( PBA_RECORD pBA);
-//function in TS.c
-extern bool GetTs(
-        struct ieee80211_device*        ieee,
-        PTS_COMMON_INFO                 *ppTS,
-        u8*                             Addr,
-        u8                              TID,
-        TR_SELECT                       TxRxSelect,  //Rx:1, Tx:0
-        bool                            bAddNewTs
-        );
-extern void TSInitialize(struct ieee80211_device *ieee);
-extern  void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD   pTxTS);
-extern void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr);
-extern void RemoveAllTS(struct ieee80211_device* ieee);
-void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
+
+extern void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee);
 
 extern const long ieee80211_wlan_frequencies[];
 
@@ -2896,6 +1914,8 @@ extern int ieee80211_parse_info_param(struct ieee80211_device *ieee,
 		struct ieee80211_network *network,
 		struct ieee80211_rx_stats *stats);
 
-void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8  index);
+extern void ieee80211_indicate_packets(struct ieee80211_device *ieee,
+				       struct ieee80211_rxb **prxbIndicateArray,
+				       u8 index);
 #define RT_ASOC_RETRY_LIMIT	5
 #endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
index 199ee16..d76a54d 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.c
@@ -55,11 +55,7 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
 
 		if (entry->ops) {
 			entry->ops->deinit(entry->priv);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 			module_put(entry->ops->owner);
-#else
-			__MOD_DEC_USE_COUNT(entry->ops->owner);
-#endif
 		}
 		kfree(entry);
 	}
@@ -208,8 +204,7 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = {
 	.owner			= THIS_MODULE,
 };
 
-
-static int __init ieee80211_crypto_init(void)
+int __init ieee80211_crypto_init(void)
 {
 	int ret = -ENOMEM;
 
@@ -230,8 +225,7 @@ out:
 	return ret;
 }
 
-
-static void __exit ieee80211_crypto_deinit(void)
+void __exit ieee80211_crypto_deinit(void)
 {
 	struct list_head *ptr, *n;
 
@@ -250,24 +244,3 @@ static void __exit ieee80211_crypto_deinit(void)
 
 	kfree(hcrypt);
 }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
-EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
-EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
-
-EXPORT_SYMBOL(ieee80211_register_crypto_ops);
-EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
-EXPORT_SYMBOL(ieee80211_get_crypto_ops);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_entries);
-EXPORT_SYMBOL_NOVERS(ieee80211_crypt_deinit_handler);
-EXPORT_SYMBOL_NOVERS(ieee80211_crypt_delayed_deinit);
-
-EXPORT_SYMBOL_NOVERS(ieee80211_register_crypto_ops);
-EXPORT_SYMBOL_NOVERS(ieee80211_unregister_crypto_ops);
-EXPORT_SYMBOL_NOVERS(ieee80211_get_crypto_ops);
-#endif
-
-module_init(ieee80211_crypto_init);
-module_exit(ieee80211_crypto_deinit);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h
index a84df4b..b58a3bc 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt.h
@@ -82,12 +82,5 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
 void ieee80211_crypt_deinit_handler(unsigned long);
 void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
 				    struct ieee80211_crypt_data **crypt);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
-#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,31))
-#define crypto_alloc_tfm crypto_alloc_tfm_rsl
-#define crypto_free_tfm crypto_free_tfm_rsl
-#endif
 
 #endif
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
index a86c26e..7bc956e 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_ccmp.c
@@ -24,27 +24,13 @@
 
 #include "ieee80211.h"
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
-    #include <linux/scatterlist.h>
-#endif
-//#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: CCMP");
 MODULE_LICENSE("GPL");
 
-#ifndef OPENSUSE_SLED
-#define OPENSUSE_SLED 0
-#endif
-
 #define AES_BLOCK_LEN 16
 #define CCMP_HDR_LEN 8
 #define CCMP_MIC_LEN 8
@@ -75,21 +61,7 @@ struct ieee80211_ccmp_data {
 void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
 			     const u8 pt[16], u8 ct[16])
 {
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	struct scatterlist src, dst;
-
-	src.page = virt_to_page(pt);
-	src.offset = offset_in_page(pt);
-	src.length = AES_BLOCK_LEN;
-
-	dst.page = virt_to_page(ct);
-	dst.offset = offset_in_page(ct);
-	dst.length = AES_BLOCK_LEN;
-
-	crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
-#else
 	crypto_cipher_encrypt_one((void*)tfm, ct, pt);
-#endif
 }
 
 static void * ieee80211_ccmp_init(int key_idx)
@@ -102,32 +74,20 @@ static void * ieee80211_ccmp_init(int key_idx)
 	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = key_idx;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	priv->tfm = crypto_alloc_tfm("aes", 0);
-	if (priv->tfm == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
-		       "crypto API aes\n");
-		goto fail;
-	}
-       #else
-       priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+	priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(priv->tfm)) {
 		printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
 		       "crypto API aes\n");
 		priv->tfm = NULL;
 		goto fail;
 	}
-	#endif
+
 	return priv;
 
 fail:
 	if (priv) {
 		if (priv->tfm)
-			#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-			crypto_free_tfm(priv->tfm);
-                    #else
 			crypto_free_cipher((void*)priv->tfm);
-		      #endif
 		kfree(priv);
 	}
 
@@ -138,12 +98,9 @@ fail:
 static void ieee80211_ccmp_deinit(void *priv)
 {
 	struct ieee80211_ccmp_data *_priv = priv;
+
 	if (_priv && _priv->tfm)
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
-		crypto_free_tfm(_priv->tfm);
-#else
 		crypto_free_cipher((void*)_priv->tfm);
-#endif
 	kfree(priv);
 }
 
@@ -512,23 +469,12 @@ static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
 	.owner			= THIS_MODULE,
 };
 
-
-static int __init ieee80211_crypto_ccmp_init(void)
+int __init ieee80211_crypto_ccmp_init(void)
 {
 	return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
 }
 
-
-static void __exit ieee80211_crypto_ccmp_exit(void)
+void __exit ieee80211_crypto_ccmp_exit(void)
 {
 	ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
 }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_ccmp_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
-#endif
-
-module_init(ieee80211_crypto_ccmp_init);
-module_exit(ieee80211_crypto_ccmp_exit);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
index b031b64..9b9438f 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_tkip.c
@@ -22,33 +22,15 @@
 #include <asm/string.h>
 
 #include "ieee80211.h"
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20))
-//#include "crypto_compat.h"
-#endif
-
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
-//#include <asm/scatterlist.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
-        #include <linux/scatterlist.h>
-#endif
-
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: TKIP");
 MODULE_LICENSE("GPL");
 
-#ifndef OPENSUSE_SLED
-#define OPENSUSE_SLED 0
-#endif
-
 struct ieee80211_tkip_data {
 #define TKIP_KEY_LEN 32
 	u8 key[TKIP_KEY_LEN];
@@ -71,17 +53,12 @@ struct ieee80211_tkip_data {
 	u32 dot11RSNAStatsTKIPLocalMICFailures;
 
 	int key_idx;
-#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
+
 	struct crypto_blkcipher *rx_tfm_arc4;
 	struct crypto_hash *rx_tfm_michael;
 	struct crypto_blkcipher *tx_tfm_arc4;
 	struct crypto_hash *tx_tfm_michael;
-#else
-	struct crypto_tfm *tx_tfm_arc4;
-	struct crypto_tfm *tx_tfm_michael;
-	struct crypto_tfm *rx_tfm_arc4;
-	struct crypto_tfm *rx_tfm_michael;
-#endif
+
 	/* scratch buffers for virt_to_page() (crypto API) */
 	u8 rx_hdr[16], tx_hdr[16];
 };
@@ -95,35 +72,7 @@ static void * ieee80211_tkip_init(int key_idx)
 		goto fail;
 	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = key_idx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	priv->tx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
-	if (priv->tx_tfm_arc4 == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-				"crypto API arc4\n");
-		goto fail;
-	}
-
-	priv->tx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
-	if (priv->tx_tfm_michael == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-				"crypto API michael_mic\n");
-		goto fail;
-	}
-
-	priv->rx_tfm_arc4 = crypto_alloc_tfm("arc4", 0);
-	if (priv->rx_tfm_arc4 == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-				"crypto API arc4\n");
-		goto fail;
-	}
 
-	priv->rx_tfm_michael = crypto_alloc_tfm("michael_mic", 0);
-	if (priv->rx_tfm_michael == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
-				"crypto API michael_mic\n");
-		goto fail;
-	}
-#else
 	priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
 			CRYPTO_ALG_ASYNC);
 	if (IS_ERR(priv->tx_tfm_arc4)) {
@@ -159,22 +108,11 @@ static void * ieee80211_tkip_init(int key_idx)
 		priv->rx_tfm_michael = NULL;
 		goto fail;
 	}
-#endif
+
 	return priv;
 
 fail:
 	if (priv) {
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-		if (priv->tx_tfm_michael)
-			crypto_free_tfm(priv->tx_tfm_michael);
-		if (priv->tx_tfm_arc4)
-			crypto_free_tfm(priv->tx_tfm_arc4);
-		if (priv->rx_tfm_michael)
-			crypto_free_tfm(priv->rx_tfm_michael);
-		if (priv->rx_tfm_arc4)
-			crypto_free_tfm(priv->rx_tfm_arc4);
-
-#else
 		if (priv->tx_tfm_michael)
 			crypto_free_hash(priv->tx_tfm_michael);
 		if (priv->tx_tfm_arc4)
@@ -183,7 +121,6 @@ fail:
 			crypto_free_hash(priv->rx_tfm_michael);
 		if (priv->rx_tfm_arc4)
 			crypto_free_blkcipher(priv->rx_tfm_arc4);
-#endif
 		kfree(priv);
 	}
 
@@ -194,16 +131,7 @@ fail:
 static void ieee80211_tkip_deinit(void *priv)
 {
 	struct ieee80211_tkip_data *_priv = priv;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	if (_priv->tx_tfm_michael)
-		crypto_free_tfm(_priv->tx_tfm_michael);
-	if (_priv->tx_tfm_arc4)
-		crypto_free_tfm(_priv->tx_tfm_arc4);
-	if (_priv->rx_tfm_michael)
-		crypto_free_tfm(_priv->rx_tfm_michael);
-	if (_priv->rx_tfm_arc4)
-		crypto_free_tfm(_priv->rx_tfm_arc4);
-#else
+
 	if (_priv) {
 		if (_priv->tx_tfm_michael)
 			crypto_free_hash(_priv->tx_tfm_michael);
@@ -214,7 +142,6 @@ static void ieee80211_tkip_deinit(void *priv)
 		if (_priv->rx_tfm_arc4)
 			crypto_free_blkcipher(_priv->rx_tfm_arc4);
 	}
-#endif
 	kfree(priv);
 }
 
@@ -384,11 +311,8 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	u8 *pos;
 	struct ieee80211_hdr_4addr *hdr;
 	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-
-	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
-	struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
+	struct blkcipher_desc desc = { .tfm = tkey->tx_tfm_arc4 };
 	int ret = 0;
-	#endif
 	u8 rc4key[16],  *icv;
 	u32 crc;
 	struct scatterlist sg;
@@ -399,18 +323,6 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
-#if 0
-printk("@@ tkey\n");
-printk("%x|", ((u32*)tkey->key)[0]);
-printk("%x|", ((u32*)tkey->key)[1]);
-printk("%x|", ((u32*)tkey->key)[2]);
-printk("%x|", ((u32*)tkey->key)[3]);
-printk("%x|", ((u32*)tkey->key)[4]);
-printk("%x|", ((u32*)tkey->key)[5]);
-printk("%x|", ((u32*)tkey->key)[6]);
-printk("%x\n", ((u32*)tkey->key)[7]);
-#endif
-
 	if (!tcb_desc->bHwSec)
 	{
 		if (!tkey->tx_phase1_done) {
@@ -451,33 +363,14 @@ printk("%x\n", ((u32*)tkey->key)[7]);
 	if (!tcb_desc->bHwSec)
 	{
 		icv = skb_put(skb, 4);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 		crc = ~crc32_le(~0, pos, len);
-#else
-		crc = ~ether_crc_le(len, pos);
-#endif
 		icv[0] = crc;
 		icv[1] = crc >> 8;
 		icv[2] = crc >> 16;
 		icv[3] = crc >> 24;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-		crypto_cipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = len + 4;
-		crypto_cipher_encrypt(tkey->tx_tfm_arc4, &sg, &sg, len + 4);
-#else
 		crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = len + 4;
-#else
-		sg_init_one(&sg, pos, len+4);
-#endif
+		sg_init_one(&sg, pos, len + 4);
 		ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-#endif
-
 	}
 
 	tkey->tx_iv16++;
@@ -487,11 +380,7 @@ printk("%x\n", ((u32*)tkey->key)[7]);
 	}
 
 	if (!tcb_desc->bHwSec)
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-		return 0;
-	#else
 		return ret;
-	#endif
 	else
         	return 0;
 
@@ -506,9 +395,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	u16 iv16;
 	struct ieee80211_hdr_4addr *hdr;
 	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
-	struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
-	#endif
+	struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
 	u8 rc4key[16];
 	u8 icv[4];
 	u32 crc;
@@ -567,21 +454,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 		plen = skb->len - hdr_len - 12;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-		crypto_cipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = plen + 4;
-		crypto_cipher_decrypt(tkey->rx_tfm_arc4, &sg, &sg, plen + 4);
-#else
 		crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = plen + 4;
-#else
-		sg_init_one(&sg, pos, plen+4);
-#endif
+		sg_init_one(&sg, pos, plen + 4);
+
 		if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
 			if (net_ratelimit()) {
 				printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -590,13 +465,8 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 			}
 			return -7;
 		}
-#endif
 
-	#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 		crc = ~crc32_le(~0, pos, plen);
-	#else
-		crc = ~ether_crc_le(plen, pos);
-	#endif
 		icv[0] = crc;
 		icv[1] = crc >> 8;
 		icv[2] = crc >> 16;
@@ -628,63 +498,9 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	skb_pull(skb, 8);
 	skb_trim(skb, skb->len - 4);
 
-//john's test
-#ifdef JOHN_DUMP
-if( ((u16*)skb->data)[0] & 0x4000){
-        printk("@@ rx decrypted skb->data");
-        int i;
-        for(i=0;i<skb->len;i++){
-                if( (i%24)==0 ) printk("\n");
-                printk("%2x ", ((u8*)skb->data)[i]);
-        }
-        printk("\n");
-}
-#endif /*JOHN_DUMP*/
 	return keyidx;
 }
 
-
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-static int michael_mic(struct crypto_tfm * tfm_michael, u8 *key, u8 *hdr,
-		       u8 *data, size_t data_len, u8 *mic)
-{
-	struct scatterlist sg[2];
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-        struct hash_desc desc;
-        int ret = 0;
-#endif
-
-	if (tfm_michael == NULL){
-		printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
-		return -1;
-	}
-	sg[0].page = virt_to_page(hdr);
-	sg[0].offset = offset_in_page(hdr);
-	sg[0].length = 16;
-
-	sg[1].page = virt_to_page(data);
-	sg[1].offset = offset_in_page(data);
-	sg[1].length = data_len;
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-	crypto_digest_init(tfm_michael);
-        crypto_digest_setkey(tfm_michael, key, 8);
-        crypto_digest_update(tfm_michael, sg, 2);
-        crypto_digest_final(tfm_michael, mic);
-        return 0;
-#else
-if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
-                return -1;
-
-//      return 0;
-              desc.tfm = tkey->tfm_michael;
-              desc.flags = 0;
-              ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
-              return ret;
-#endif
-}
-#else
 static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                        u8 * data, size_t data_len, u8 * mic)
 {
@@ -695,19 +511,10 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                 printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
                 return -1;
         }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-        sg[0].page = virt_to_page(hdr);
-        sg[0].offset = offset_in_page(hdr);
-        sg[0].length = 16;
-
-        sg[1].page = virt_to_page(data);
-        sg[1].offset = offset_in_page(data);
-        sg[1].length = data_len;
-#else
-        sg_init_table(sg, 2);
-        sg_set_buf(&sg[0], hdr, 16);
-        sg_set_buf(&sg[1], data, data_len);
-#endif
+
+	sg_init_table(sg, 2);
+	sg_set_buf(&sg[0], hdr, 16);
+	sg_set_buf(&sg[1], data, data_len);
 
         if (crypto_hash_setkey(tfm_michael, key, 8))
                 return -1;
@@ -716,9 +523,6 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
         desc.flags = 0;
         return crypto_hash_digest(&desc, sg, data_len + 16, mic);
 }
-#endif
-
-
 
 static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
 {
@@ -775,20 +579,14 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri
 	}
 	// }
 	pos = skb_put(skb, 8);
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
-				skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
-#else
+
 	if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
-				skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
-#endif
+			skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
 		return -1;
 
 	return 0;
 }
 
-
-#if WIRELESS_EXT >= 18
 static void ieee80211_michael_mic_failure(struct net_device *dev,
 				       struct ieee80211_hdr_4addr *hdr,
 				       int keyidx)
@@ -809,29 +607,6 @@ static void ieee80211_michael_mic_failure(struct net_device *dev,
 	wrqu.data.length = sizeof(ev);
 	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
 }
-#elif WIRELESS_EXT >= 15
-static void ieee80211_michael_mic_failure(struct net_device *dev,
-				       struct ieee80211_hdr_4addr *hdr,
-				       int keyidx)
-{
-	union iwreq_data wrqu;
-	char buf[128];
-
-	/* TODO: needed parameters: count, keyid, key type, TSC */
-	sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
-		MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
-		MAC_ARG(hdr->addr2));
-	memset(&wrqu, 0, sizeof(wrqu));
-	wrqu.data.length = strlen(buf);
-	wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
-}
-#else /* WIRELESS_EXT >= 15 */
-static inline void ieee80211_michael_mic_failure(struct net_device *dev,
-					      struct ieee80211_hdr_4addr *hdr,
-					      int keyidx)
-{
-}
-#endif /* WIRELESS_EXT >= 15 */
 
 static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
 				     int hdr_len, void *priv)
@@ -853,13 +628,8 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
 	}
 	// }
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
-				skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
-#else
 	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
-				skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
-#endif
+			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
             	return -1;
 	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
 		struct ieee80211_hdr_4addr *hdr;
@@ -889,32 +659,18 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
 {
 	struct ieee80211_tkip_data *tkey = priv;
 	int keyidx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	struct crypto_tfm *tfm = tkey->tx_tfm_michael;
-	struct crypto_tfm *tfm2 = tkey->tx_tfm_arc4;
-	struct crypto_tfm *tfm3 = tkey->rx_tfm_michael;
-	struct crypto_tfm *tfm4 = tkey->rx_tfm_arc4;
-#else
 	struct crypto_hash *tfm = tkey->tx_tfm_michael;
 	struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
 	struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
 	struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-#endif
 
 	keyidx = tkey->key_idx;
 	memset(tkey, 0, sizeof(*tkey));
 	tkey->key_idx = keyidx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	tkey->tx_tfm_michael = tfm;
-	tkey->tx_tfm_arc4 = tfm2;
-	tkey->rx_tfm_michael = tfm3;
-	tkey->rx_tfm_arc4 = tfm4;
-#else
 	tkey->tx_tfm_michael = tfm;
 	tkey->tx_tfm_arc4 = tfm2;
 	tkey->rx_tfm_michael = tfm3;
 	tkey->rx_tfm_arc4 = tfm4;
-#endif
 
 	if (len == TKIP_KEY_LEN) {
 		memcpy(tkey->key, key, TKIP_KEY_LEN);
@@ -1007,14 +763,12 @@ static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
 	.owner		        = THIS_MODULE,
 };
 
-
-static int __init ieee80211_crypto_tkip_init(void)
+int __init ieee80211_crypto_tkip_init(void)
 {
 	return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
 }
 
-
-static void __exit ieee80211_crypto_tkip_exit(void)
+void __exit ieee80211_crypto_tkip_exit(void)
 {
 	ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
 }
@@ -1024,11 +778,3 @@ void ieee80211_tkip_null(void)
 //    printk("============>%s()\n", __FUNCTION__);
         return;
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_tkip_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
-#endif
-
-module_init(ieee80211_crypto_tkip_init);
-module_exit(ieee80211_crypto_tkip_exit);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c
index 7e39432..64f9cf0 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_crypt_wep.c
@@ -20,41 +20,13 @@
 
 #include "ieee80211.h"
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20))
-//#include "crypto_compat.h"
-#endif
-
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
 #include <linux/crypto.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-    #include <asm/scatterlist.h>
-#else
-    #include <linux/scatterlist.h>
-#endif
-//#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
-//
-/*
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-#include "rtl_crypto.h"
-#else
-#include <linux/crypto.h>
-#endif
 
-#include <asm/scatterlist.h>
-#include <linux/crc32.h>
-*/
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Host AP crypt: WEP");
 MODULE_LICENSE("GPL");
-#ifndef OPENSUSE_SLED
-#define OPENSUSE_SLED 0
-#endif
 
 struct prism2_wep_data {
 	u32 iv;
@@ -62,12 +34,8 @@ struct prism2_wep_data {
 	u8 key[WEP_KEY_LEN + 1];
 	u8 key_len;
 	u8 key_idx;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	struct crypto_tfm *tfm;
-	#else
-        struct crypto_blkcipher *tx_tfm;
-        struct crypto_blkcipher *rx_tfm;
-        #endif
+	struct crypto_blkcipher *tx_tfm;
+	struct crypto_blkcipher *rx_tfm;
 };
 
 
@@ -81,14 +49,6 @@ static void * prism2_wep_init(int keyidx)
 	memset(priv, 0, sizeof(*priv));
 	priv->key_idx = keyidx;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	priv->tfm = crypto_alloc_tfm("arc4", 0);
-	if (priv->tfm == NULL) {
-		printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
-		       "crypto API arc4\n");
-		goto fail;
-	}
-	#else
 	priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
         if (IS_ERR(priv->tx_tfm)) {
                 printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
@@ -103,7 +63,6 @@ static void * prism2_wep_init(int keyidx)
                 priv->rx_tfm = NULL;
                 goto fail;
         }
-        #endif
 
 	/* start WEP IV from a random value */
 	get_random_bytes(&priv->iv, 4);
@@ -111,13 +70,6 @@ static void * prism2_wep_init(int keyidx)
 	return priv;
 
 fail:
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	if (priv) {
-		if (priv->tfm)
-			crypto_free_tfm(priv->tfm);
-		kfree(priv);
-	}
-	#else
 	if (priv) {
                 if (priv->tx_tfm)
                         crypto_free_blkcipher(priv->tx_tfm);
@@ -125,7 +77,7 @@ fail:
                         crypto_free_blkcipher(priv->rx_tfm);
                 kfree(priv);
         }
-        #endif
+
 	return NULL;
 }
 
@@ -133,17 +85,13 @@ fail:
 static void prism2_wep_deinit(void *priv)
 {
 	struct prism2_wep_data *_priv = priv;
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-	if (_priv && _priv->tfm)
-		crypto_free_tfm(_priv->tfm);
-	#else
+
 	if (_priv) {
                 if (_priv->tx_tfm)
                         crypto_free_blkcipher(_priv->tx_tfm);
                 if (_priv->rx_tfm)
                         crypto_free_blkcipher(_priv->rx_tfm);
         }
-        #endif
 	kfree(priv);
 }
 
@@ -160,9 +108,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	u8 key[WEP_KEY_LEN + 3];
 	u8 *pos;
 	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
-	struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
-	#endif
+	struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
 	u32 crc;
 	u8 *icv;
 	struct scatterlist sg;
@@ -201,35 +147,17 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	{
 
 		/* Append little-endian CRC32 and encrypt it to produce ICV */
-	#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 		crc = ~crc32_le(~0, pos, len);
-	#else
-		crc = ~ether_crc_le(len, pos);
-	#endif
 		icv = skb_put(skb, 4);
 		icv[0] = crc;
 		icv[1] = crc >> 8;
 		icv[2] = crc >> 16;
 		icv[3] = crc >> 24;
 
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-		crypto_cipher_setkey(wep->tfm, key, klen);
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = len + 4;
-		crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
-		return 0;
-	#else
 		crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
-	#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = len + 4;
-	#else
 		sg_init_one(&sg, pos, len+4);
-	#endif
+
 		return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-	#endif
 	}
 
 	return 0;
@@ -250,9 +178,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 	u8 key[WEP_KEY_LEN + 3];
 	u8 keyidx, *pos;
 	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-	#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) || (OPENSUSE_SLED))
-	struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
-	#endif
+	struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
 	u32 crc;
 	u8 icv[4];
 	struct scatterlist sg;
@@ -277,29 +203,13 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
 
 	if (!tcb_desc->bHwSec)
 	{
-#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!OPENSUSE_SLED))
-		crypto_cipher_setkey(wep->tfm, key, klen);
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = plen + 4;
-		crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
-	#else
 		crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
-	#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-		sg.page = virt_to_page(pos);
-		sg.offset = offset_in_page(pos);
-		sg.length = plen + 4;
-	#else
-		sg_init_one(&sg, pos, plen+4);
-	#endif
+		sg_init_one(&sg, pos, plen + 4);
+
 		if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
 			return -7;
-	#endif
-	#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+
 		crc = ~crc32_le(~0, pos, plen);
-	#else
-		crc = ~ether_crc_le(plen, pos);
-	#endif
 		icv[0] = crc;
 		icv[1] = crc >> 8;
 		icv[2] = crc >> 16;
@@ -370,14 +280,12 @@ static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
 	.owner			= THIS_MODULE,
 };
 
-
-static int __init ieee80211_crypto_wep_init(void)
+int __init ieee80211_crypto_wep_init(void)
 {
 	return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
 }
 
-
-static void __exit ieee80211_crypto_wep_exit(void)
+void __exit ieee80211_crypto_wep_exit(void)
 {
 	ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
 }
@@ -387,11 +295,3 @@ void ieee80211_wep_null(void)
 //	printk("============>%s()\n", __FUNCTION__);
         return;
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_wep_null);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
-#endif
-
-module_init(ieee80211_crypto_wep_init);
-module_exit(ieee80211_crypto_wep_exit);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
index 759032d..68dc8fa 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
@@ -113,12 +113,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 		goto failed;
 	}
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 	ieee = netdev_priv(dev);
-#else
-	ieee = (struct ieee80211_device *)dev->priv;
-#endif
-
 	memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
 	ieee->dev = dev;
 
@@ -166,12 +161,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
 	ieee80211_softmac_init(ieee);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
 	ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
-#else
-	ieee->pHTInfo = (RT_HIGH_THROUGHPUT*)kmalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL);
-	memset(ieee->pHTInfo,0,sizeof(RT_HIGH_THROUGHPUT));
-#endif
 	if (ieee->pHTInfo == NULL)
 	{
 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n");
@@ -180,13 +170,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 	HTUpdateDefaultSetting(ieee);
 	HTInitializeHTInfo(ieee); //may move to other place.
 	TSInitialize(ieee);
-#if 0
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
- 	INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq);
-#else
-	INIT_WORK(&ieee->ht_onAssRsp, (void(*)(void*)) HTOnAssocRsp_wq, ieee);
-#endif
-#endif
+
 	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
 		INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
 
@@ -205,22 +189,15 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 
  failed:
 	if (dev)
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 		free_netdev(dev);
-#else
-		kfree(dev);
-#endif
+
 	return NULL;
 }
 
 
 void free_ieee80211(struct net_device *dev)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 	struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
 	int i;
 	//struct list_head *p, *q;
 //	del_timer_sync(&ieee->SwBwTimer);
@@ -241,11 +218,7 @@ void free_ieee80211(struct net_device *dev)
 		if (crypt) {
 			if (crypt->ops) {
 				crypt->ops->deinit(crypt->priv);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 				module_put(crypt->ops->owner);
-#else
-				__MOD_DEC_USE_COUNT(crypt->ops->owner);
-#endif
 			}
 			kfree(crypt);
 			ieee->crypt[i] = NULL;
@@ -253,20 +226,7 @@ void free_ieee80211(struct net_device *dev)
 	}
 
 	ieee80211_networks_free(ieee);
-#if 0
-	for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
-		list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
-			kfree(list_entry(p, struct ieee_ibss_seq, list));
-			list_del(p);
-		}
-	}
-
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 	free_netdev(dev);
-#else
-	kfree(dev);
-#endif
 }
 
 #ifdef CONFIG_IEEE80211_DEBUG
@@ -304,7 +264,7 @@ static int store_debug_level(struct file *file, const char *buffer,
 			     unsigned long count, void *data)
 {
 	char buf[] = "0x00000000";
-	unsigned long len = min(sizeof(buf) - 1, (u32)count);
+	unsigned long len = min(sizeof(buf) - 1, count);
 	char *p = (char *)buf;
 	unsigned long val;
 
@@ -327,16 +287,13 @@ static int store_debug_level(struct file *file, const char *buffer,
 	return strnlen(buf, count);
 }
 
-static int __init ieee80211_init(void)
+int __init ieee80211_debug_init(void)
 {
 	struct proc_dir_entry *e;
 
 	ieee80211_debug_level = debug;
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
-#else
+
 	ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net);
-#endif
 	if (ieee80211_proc == NULL) {
 		IEEE80211_ERROR("Unable to create " DRV_NAME
 				" proc directory\n");
@@ -345,11 +302,7 @@ static int __init ieee80211_init(void)
 	e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
 			      ieee80211_proc);
 	if (!e) {
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-		remove_proc_entry(DRV_NAME, proc_net);
-#else
 		remove_proc_entry(DRV_NAME, init_net.proc_net);
-#endif
 		ieee80211_proc = NULL;
 		return -EIO;
 	}
@@ -360,34 +313,16 @@ static int __init ieee80211_init(void)
 	return 0;
 }
 
-static void __exit ieee80211_exit(void)
+void __exit ieee80211_debug_exit(void)
 {
 	if (ieee80211_proc) {
 		remove_proc_entry("debug_level", ieee80211_proc);
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-		remove_proc_entry(DRV_NAME, proc_net);
-#else
 		remove_proc_entry(DRV_NAME, init_net.proc_net);
-#endif
 		ieee80211_proc = NULL;
 	}
 }
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 #include <linux/moduleparam.h>
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
-
-
-module_exit(ieee80211_exit);
-module_init(ieee80211_init);
-#endif
-#endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(alloc_ieee80211);
-EXPORT_SYMBOL(free_ieee80211);
-#else
-EXPORT_SYMBOL_NOVERS(alloc_ieee80211);
-EXPORT_SYMBOL_NOVERS(free_ieee80211);
 #endif
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h b/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h
new file mode 100644
index 0000000..123abcf
--- /dev/null
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_r8192s.h
@@ -0,0 +1,436 @@
+#ifndef __IEEE80211_R8192S_H
+#define __IEEE80211_R8192S_H
+
+/* added for rtl819x tx procedure */
+#define MAX_QUEUE_SIZE		0x10
+
+/* 8190 queue mapping */
+enum {
+	BK_QUEUE	= 0,
+	BE_QUEUE	= 1,
+	VI_QUEUE	= 2,
+	VO_QUEUE	= 3,
+	HCCA_QUEUE	= 4,
+	TXCMD_QUEUE	= 5,
+	MGNT_QUEUE	= 6,
+	HIGH_QUEUE	= 7,
+	BEACON_QUEUE	= 8,
+
+	LOW_QUEUE	= BE_QUEUE,
+	NORMAL_QUEUE	= MGNT_QUEUE
+};
+
+#define SWRF_TIMEOUT		50
+
+/* LEAP related */
+/* Flag byte: byte 8, numbered from 0. */
+#define IE_CISCO_FLAG_POSITION		0x08
+#define SUPPORT_CKIP_MIC		0x08	/* bit3 */
+#define SUPPORT_CKIP_PK			0x10	/* bit4 */
+
+/* defined for skb cb field, at most 28 byte */
+typedef struct cb_desc {
+	/* Tx Desc Related flags (8-9) */
+	u8 bLastIniPkt:1;
+	u8 bCmdOrInit:1;
+	u8 bFirstSeg:1;
+	u8 bLastSeg:1;
+	u8 bEncrypt:1;
+	u8 bTxDisableRateFallBack:1;
+	u8 bTxUseDriverAssingedRate:1;
+	u8 bHwSec:1; /* indicate whether use Hw security */
+
+	u8 reserved1;
+
+	/* Tx Firmware Relaged flags (10-11) */
+	u8 bCTSEnable:1;
+	u8 bRTSEnable:1;
+	u8 bUseShortGI:1;
+	u8 bUseShortPreamble:1;
+	u8 bTxEnableFwCalcDur:1;
+	u8 bAMPDUEnable:1;
+	u8 bRTSSTBC:1;
+	u8 RTSSC:1;
+
+	u8 bRTSBW:1;
+	u8 bPacketBW:1;
+	u8 bRTSUseShortPreamble:1;
+	u8 bRTSUseShortGI:1;
+	u8 bMulticast:1;
+	u8 bBroadcast:1;
+	u8 drv_agg_enable:1;
+	u8 reserved2:1;
+
+	/* Tx Desc related element(12-19) */
+	u8 rata_index;
+	u8 queue_index;
+	u16 txbuf_size;
+	u8 RATRIndex;
+	u8 reserved6;
+	u8 reserved7;
+	u8 reserved8;
+
+	/* Tx firmware related element(20-27) */
+	u8 data_rate;
+	u8 rts_rate;
+	u8 ampdu_factor;
+	u8 ampdu_density;
+	u8 DrvAggrNum;
+	u16 pkt_size;
+	u8 reserved12;
+} cb_desc, *pcb_desc;
+
+enum {
+	MGN_1M		= 0x02,
+	MGN_2M		= 0x04,
+	MGN_5_5M	= 0x0b,
+	MGN_11M		= 0x16,
+
+	MGN_6M		= 0x0c,
+	MGN_9M		= 0x12,
+	MGN_12M		= 0x18,
+	MGN_18M		= 0x24,
+	MGN_24M		= 0x30,
+	MGN_36M		= 0x48,
+	MGN_48M		= 0x60,
+	MGN_54M		= 0x6c,
+
+	MGN_MCS0	= 0x80,
+	MGN_MCS1	= 0x81,
+	MGN_MCS2	= 0x82,
+	MGN_MCS3	= 0x83,
+	MGN_MCS4	= 0x84,
+	MGN_MCS5	= 0x85,
+	MGN_MCS6	= 0x86,
+	MGN_MCS7	= 0x87,
+	MGN_MCS8	= 0x88,
+	MGN_MCS9	= 0x89,
+	MGN_MCS10	= 0x8a,
+	MGN_MCS11	= 0x8b,
+	MGN_MCS12	= 0x8c,
+	MGN_MCS13	= 0x8d,
+	MGN_MCS14	= 0x8e,
+	MGN_MCS15	= 0x8f,
+
+	MGN_MCS0_SG	= 0x90,
+	MGN_MCS1_SG	= 0x91,
+	MGN_MCS2_SG	= 0x92,
+	MGN_MCS3_SG	= 0x93,
+	MGN_MCS4_SG	= 0x94,
+	MGN_MCS5_SG	= 0x95,
+	MGN_MCS6_SG	= 0x96,
+	MGN_MCS7_SG	= 0x97,
+	MGN_MCS8_SG	= 0x98,
+	MGN_MCS9_SG	= 0x99,
+	MGN_MCS10_SG	= 0x9a,
+	MGN_MCS11_SG	= 0x9b,
+	MGN_MCS12_SG	= 0x9c,
+	MGN_MCS13_SG	= 0x9d,
+	MGN_MCS14_SG	= 0x9e,
+	MGN_MCS15_SG	= 0x9f,
+};
+
+#define FC_QOS_BIT		BIT7
+
+#define IsDataFrame(pdu)	(((pdu[0] & 0x0C) == 0x08) ? true : false)
+#define IsLegacyDataFrame(pdu)	(IsDataFrame(pdu) && (!(pdu[0] & FC_QOS_BIT)))
+#define IsQoSDataFrame(pframe) \
+	((*(u16 *)pframe & (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA)) \
+	 == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
+
+#define Frame_Order(pframe)	(*(u16 *)pframe & IEEE80211_FCTL_ORDER)
+
+#define SN_LESS(a, b)		(((a - b) & 0x800) != 0)
+#define SN_EQUAL(a, b)		(a == b)
+
+#define MAX_DEV_ADDR_SIZE 8
+
+enum {
+	/* ACT_CATEGORY */
+	ACT_CAT_QOS	= 1,
+	ACT_CAT_DLS	= 2,
+	ACT_CAT_BA	= 3,
+	ACT_CAT_HT	= 7,
+	ACT_CAT_WMM	= 17,
+
+	/* TS_ACTION */
+	ACT_ADDTSREQ	= 0,
+	ACT_ADDTSRSP	= 1,
+	ACT_DELTS	= 2,
+	ACT_SCHEDULE	= 3,
+
+	/* BA_ACTION */
+	ACT_ADDBAREQ	= 0,
+	ACT_ADDBARSP	= 1,
+	ACT_DELBA	= 2,
+};
+
+/* InitialGainOpType */
+enum {
+	IG_Backup = 0,
+	IG_Restore,
+	IG_Max
+};
+
+typedef enum _LED_CTL_MODE {
+	LED_CTL_POWER_ON	 = 1,
+	LED_CTL_LINK		 = 2,
+	LED_CTL_NO_LINK		 = 3,
+	LED_CTL_TX		 = 4,
+	LED_CTL_RX		 = 5,
+	LED_CTL_SITE_SURVEY	 = 6,
+	LED_CTL_POWER_OFF	 = 7,
+	LED_CTL_START_TO_LINK	 = 8,
+	LED_CTL_START_WPS	 = 9,
+	LED_CTL_STOP_WPS	 = 10,
+	LED_CTL_START_WPS_BOTTON = 11,
+} LED_CTL_MODE;
+
+typedef union _frameqos {
+	u16 shortdata;
+	u8  chardata[2];
+	struct {
+		u16 tid:4;
+		u16 eosp:1;
+		u16 ack_policy:2;
+		u16 reserved:1;
+		u16 txop:8;
+	} field;
+} frameqos;
+
+static inline u8 Frame_QoSTID(u8 *buf)
+{
+	struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)buf;
+	u16 fc = le16_to_cpu(hdr->frame_ctl);
+
+	return (u8)((frameqos *)(buf +
+		(((fc & IEEE80211_FCTL_TODS) &&
+		  (fc & IEEE80211_FCTL_FROMDS)) ? 30 : 24)))->field.tid;
+}
+
+enum {
+	ERP_NonERPpresent	= 1,
+	ERP_UseProtection	= 2,
+	ERP_BarkerPreambleMode	= 4,
+};
+
+struct bandwidth_autoswitch {
+	long threshold_20Mhzto40Mhz;
+	long threshold_40Mhzto20Mhz;
+	bool bforced_tx20Mhz;
+	bool bautoswitch_enable;
+};
+
+#define REORDER_WIN_SIZE	128
+#define REORDER_ENTRY_NUM	128
+typedef struct _RX_REORDER_ENTRY {
+	struct list_head	List;
+	u16			SeqNum;
+	struct ieee80211_rxb	*prxb;
+} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY;
+
+typedef enum _Fsync_State{
+	Default_Fsync,
+	HW_Fsync,
+	SW_Fsync
+} Fsync_State;
+
+/* Power save mode configured. */
+typedef enum _RT_PS_MODE {
+	eActive,	/* Active/Continuous access. */
+	eMaxPs,		/* Max power save mode. */
+	eFastPs		/* Fast power save mode. */
+} RT_PS_MODE;
+
+typedef enum _IPS_CALLBACK_FUNCION {
+	IPS_CALLBACK_NONE = 0,
+	IPS_CALLBACK_MGNT_LINK_REQUEST = 1,
+	IPS_CALLBACK_JOIN_REQUEST = 2,
+} IPS_CALLBACK_FUNCION;
+
+typedef enum _RT_JOIN_ACTION {
+	RT_JOIN_INFRA = 1,
+	RT_JOIN_IBSS  = 2,
+	RT_START_IBSS = 3,
+	RT_NO_ACTION  = 4,
+} RT_JOIN_ACTION;
+
+struct ibss_parms {
+	u16 atimWin;
+};
+
+/* Max num of support rates element: 8,  Max num of ext. support rate: 255. */
+#define MAX_NUM_RATES	264
+
+typedef enum _RT_RF_POWER_STATE {
+	eRfOn,
+	eRfSleep,
+	eRfOff
+} RT_RF_POWER_STATE;
+
+struct rt_power_save_control {
+	/* Inactive Power Save (IPS): disable RF when disconnected */
+	bool			bInactivePs;
+	bool			bIPSModeBackup;
+	bool			bHaltAdapterClkRQ;
+	bool			bSwRfProcessing;
+	RT_RF_POWER_STATE	eInactivePowerState;
+	struct work_struct 	InactivePsWorkItem;
+	struct timer_list	InactivePsTimer;
+
+	/* return point for join action */
+	IPS_CALLBACK_FUNCION	ReturnPoint;
+
+	/* Recored Parameters for rescheduled JoinRequest */
+	bool			bTmpBssDesc;
+	RT_JOIN_ACTION		tmpJoinAction;
+	struct ieee80211_network tmpBssDesc;
+
+	/* Recored Parameters for rescheduled MgntLinkRequest */
+	bool			bTmpScanOnly;
+	bool			bTmpActiveScan;
+	bool			bTmpFilterHiddenAP;
+	bool			bTmpUpdateParms;
+	u8			tmpSsidBuf[33];
+	OCTET_STRING		tmpSsid2Scan;
+	bool			bTmpSsid2Scan;
+	u8			tmpNetworkType;
+	u8			tmpChannelNumber;
+	u16			tmpBcnPeriod;
+	u8			tmpDtimPeriod;
+	u16			tmpmCap;
+	OCTET_STRING		tmpSuppRateSet;
+	u8			tmpSuppRateBuf[MAX_NUM_RATES];
+	bool			bTmpSuppRate;
+	struct ibss_parms	tmpIbpm;
+	bool			bTmpIbpm;
+
+	/* Leisre Poswer Save: disable RF if connected but traffic isn't busy */
+	bool			bLeisurePs;
+	u32			PowerProfile;
+	u8			LpsIdleCount;
+	u8			RegMaxLPSAwakeIntvl;
+	u8			LPSAwakeIntvl;
+
+	/* RF OFF Level */
+	u32			CurPsLevel;
+	u32			RegRfPsLevel;
+
+	/* Fw Control LPS */
+	bool			bFwCtrlLPS;
+	u8			FWCtrlPSMode;
+
+	/* Record if there is a link request in IPS RF off progress. */
+	bool			LinkReqInIPSRFOffPgs;
+	/*
+	 * To make sure that connect info should be executed, so we set the
+	 * bit to filter the link info which comes after the connect info.
+	 */
+	bool			BufConnectinfoBefore;
+};
+
+enum {
+	RF_CHANGE_BY_SW		= BIT31,
+	RF_CHANGE_BY_HW		= BIT30,
+	RF_CHANGE_BY_PS		= BIT29,
+	RF_CHANGE_BY_IPS	= BIT28,
+};
+
+/* Firmware related CMD IO. */
+typedef enum _FW_CMD_IO_TYPE {
+	FW_CMD_DIG_ENABLE = 0,		/* for DIG DM */
+	FW_CMD_DIG_DISABLE = 1,
+	FW_CMD_DIG_HALT = 2,
+	FW_CMD_DIG_RESUME = 3,
+	FW_CMD_HIGH_PWR_ENABLE = 4,	/* for High Power DM */
+	FW_CMD_HIGH_PWR_DISABLE = 5,
+	FW_CMD_RA_RESET = 6,		/* for Rate adaptive DM */
+	FW_CMD_RA_ACTIVE = 7,
+	FW_CMD_RA_REFRESH_N = 8,
+	FW_CMD_RA_REFRESH_BG = 9,
+	FW_CMD_IQK_ENABLE = 10,		/* for FW supported IQK */
+	FW_CMD_TXPWR_TRACK_ENABLE = 11,	/* Tx power tracking switch */
+	FW_CMD_TXPWR_TRACK_DISABLE = 12,/* Tx power tracking switch */
+	FW_CMD_PAUSE_DM_BY_SCAN = 13,
+	FW_CMD_RESUME_DM_BY_SCAN = 14,
+	FW_CMD_MID_HIGH_PWR_ENABLE = 15,
+	/* indicate firmware that driver enters LPS, for PS-Poll hardware bug */
+	FW_CMD_LPS_ENTER = 16,
+	/* indicate firmware that driver leave LPS */
+	FW_CMD_LPS_LEAVE = 17,
+} FW_CMD_IO_TYPE;
+
+#define RT_MAX_LD_SLOT_NUM	10
+struct rt_link_detect {
+	u32	NumRecvBcnInPeriod;
+	u32	NumRecvDataInPeriod;
+
+	/* number of Rx beacon / CheckForHang_period to determine link status */
+	u32	RxBcnNum[RT_MAX_LD_SLOT_NUM];
+	/* number of Rx data / CheckForHang_period to determine link status */
+	u32	RxDataNum[RT_MAX_LD_SLOT_NUM];
+	/* number of CheckForHang period to determine link status */
+	u16	SlotNum;
+	u16	SlotIndex;
+
+	u32	NumTxOkInPeriod;
+	u32	NumRxOkInPeriod;
+	bool	bBusyTraffic;
+};
+
+/* HT */
+#define MAX_RECEIVE_BUFFER_SIZE 9100
+extern void HTDebugHTCapability(u8 *CapIE, u8 *TitleString);
+extern void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString);
+
+extern void HTSetConnectBwMode(struct ieee80211_device *ieee,
+			       HT_CHANNEL_WIDTH Bandwidth,
+			       HT_EXTCHNL_OFFSET Offset);
+extern void HTUpdateDefaultSetting(struct ieee80211_device *ieee);
+extern void HTConstructCapabilityElement(struct ieee80211_device *ieee,
+					 u8 *posHTCap, u8 *len, u8 isEncrypt);
+extern void HTConstructInfoElement(struct ieee80211_device *ieee,
+				   u8 *posHTInfo, u8 *len, u8 isEncrypt);
+extern void HTConstructRT2RTAggElement(struct ieee80211_device *ieee,
+				       u8 *posRT2RTAgg, u8 *len);
+extern void HTOnAssocRsp(struct ieee80211_device *ieee);
+extern void HTInitializeHTInfo(struct ieee80211_device *ieee);
+extern void HTInitializeBssDesc(PBSS_HT pBssHT);
+extern void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee,
+					  struct ieee80211_network *pNetwork);
+extern void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee,
+				       struct ieee80211_network *pNetwork);
+extern u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet,
+			      u8 *pMCSFilter);
+extern u8 MCS_FILTER_ALL[];
+extern u16 MCS_DATA_RATE[2][2][77] ;
+extern u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame);
+extern void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo);
+extern bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee);
+extern u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
+extern u16 HTMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate);
+extern u16  TxCountToDataRate(struct ieee80211_device *ieee, u8 nDataRate);
+extern int ieee80211_rx_ADDBAReq(struct ieee80211_device *ieee,
+				 struct sk_buff *skb);
+extern int ieee80211_rx_ADDBARsp(struct ieee80211_device *ieee,
+				 struct sk_buff *skb);
+extern int ieee80211_rx_DELBA(struct ieee80211_device *ieee,
+			      struct sk_buff *skb);
+extern void TsInitAddBA(struct ieee80211_device *ieee, PTX_TS_RECORD pTS,
+			u8 Policy, u8 bOverwritePending);
+extern void TsInitDelBA(struct ieee80211_device *ieee,
+			PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect);
+extern void BaSetupTimeOut(unsigned long data);
+extern void TxBaInactTimeout(unsigned long data);
+extern void RxBaInactTimeout(unsigned long data);
+extern void ResetBaEntry(PBA_RECORD pBA);
+extern bool GetTs(struct ieee80211_device *ieee, PTS_COMMON_INFO *ppTS,
+		  u8 *Addr, u8 TID, TR_SELECT TxRxSelect,  /* Rx:1, Tx:0 */
+		  bool bAddNewTs);
+extern void TSInitialize(struct ieee80211_device *ieee);
+extern void TsStartAddBaProcess(struct ieee80211_device *ieee,
+				PTX_TS_RECORD pTxTS);
+extern void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr);
+extern void RemoveAllTS(struct ieee80211_device *ieee);
+
+#endif /* __IEEE80211_R8192S_H */
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
index 2b2ffd3..8e56f97 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_rx.c
@@ -44,9 +44,7 @@
 #include <linux/ctype.h>
 
 #include "ieee80211.h"
-#ifdef ENABLE_DOT11D
 #include "dot11d.h"
-#endif
 static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
 					struct sk_buff *skb,
 					struct ieee80211_rx_stats *rx_stats)
@@ -55,11 +53,7 @@ static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
 	u16 fc = le16_to_cpu(hdr->frame_ctl);
 
 	skb->dev = ieee->dev;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
         skb_reset_mac_header(skb);
-#else
-        skb->mac.raw = skb->data;
-#endif
 
 	skb_pull(skb, ieee80211_get_hdrlen(fc));
 	skb->pkt_type = PACKET_OTHERHOST;
@@ -242,51 +236,6 @@ ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 	return 0;
 
-	#ifdef NOT_YET
-	if (ieee->iw_mode == IW_MODE_MASTER) {
-		printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
-		       ieee->dev->name);
-		return 0;
-/*
-  hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr_4addr *)
-  skb->data);*/
-	}
-
-	if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
-		if (stype == WLAN_FC_STYPE_BEACON &&
-		    ieee->iw_mode == IW_MODE_MASTER) {
-			struct sk_buff *skb2;
-			/* Process beacon frames also in kernel driver to
-			 * update STA(AP) table statistics */
-			skb2 = skb_clone(skb, GFP_ATOMIC);
-			if (skb2)
-				hostap_rx(skb2->dev, skb2, rx_stats);
-		}
-
-		/* send management frames to the user space daemon for
-		 * processing */
-		ieee->apdevstats.rx_packets++;
-		ieee->apdevstats.rx_bytes += skb->len;
-		prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
-		return 0;
-	}
-
-	    if (ieee->iw_mode == IW_MODE_MASTER) {
-		if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
-			printk(KERN_DEBUG "%s: unknown management frame "
-			       "(type=0x%02x, stype=0x%02x) dropped\n",
-			       skb->dev->name, type, stype);
-			return -1;
-		}
-
-		hostap_rx(skb->dev, skb, rx_stats);
-		return 0;
-	}
-
-	printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
-	       "received in non-Host AP mode\n", skb->dev->name);
-	return -1;
-	#endif
 }
 
 
@@ -626,10 +575,6 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee,
 	u8			index = 0;
 	bool			bMatchWinStart = false, bPktInBuf = false;
 	IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize);
-#if 0
-	if(!list_empty(&ieee->RxReorder_Unused_List))
-		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): ieee->RxReorder_Unused_List is nut NULL\n");
-#endif
 	/* Rx Reorder initialize condition.*/
 	if(pTS->RxIndicateSeq == 0xffff) {
 		pTS->RxIndicateSeq = SeqNum;
@@ -790,14 +735,7 @@ void RxReorderIndicatePacket( struct ieee80211_device *ieee,
 		// Set new pending timer.
 		IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__);
 		pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq;
-#if 0
-		if(timer_pending(&pTS->RxPktPendingTimer))
-			del_timer_sync(&pTS->RxPktPendingTimer);
-		pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime);
-		add_timer(&pTS->RxPktPendingTimer);
-#else
 		mod_timer(&pTS->RxPktPendingTimer,  jiffies + MSECS(pHTInfo->RxReorderPendingTime));
-#endif
 	}
 #endif
 }
@@ -866,11 +804,6 @@ u8 parse_subframe(struct sk_buff *skb,
 			nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
 
 			if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) {
-#if 0//cosa
-				RT_ASSERT(
-						(nRemain_Length>=(ETHERNET_HEADER_SIZE + nSubframe_Length)),
-						("ParseSubframe(): A-MSDU subframe parse error!! Subframe Length: %d\n", nSubframe_Length) );
-#endif
 				printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\
 						__FUNCTION__,rxb->nr_subframes);
 				printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length);
@@ -945,14 +878,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	PRX_TS_RECORD pTS = NULL;
 	//bool bIsAggregateFrame = false;
 	//added by amy for reorder
-#ifdef NOT_YET
-	struct net_device *wds = NULL;
-	struct sk_buff *skb2 = NULL;
-	struct net_device *wds = NULL;
-	int frame_authorized = 0;
-	int from_assoc_ap = 0;
-	void *sta = NULL;
-#endif
 //	u16 qos_ctl = 0;
 	u8 dst[ETH_ALEN];
 	u8 src[ETH_ALEN];
@@ -989,52 +914,19 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	}
 
 	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
-#ifdef NOT_YET
-#if WIRELESS_EXT > 15
-	/* Put this code here so that we avoid duplicating it in all
-	 * Rx paths. - Jean II */
-#ifdef IW_WIRELESS_SPY		/* defined in iw_handler.h */
-	/* If spy monitoring on */
-	if (iface->spy_data.spy_number > 0) {
-		struct iw_quality wstats;
-		wstats.level = rx_stats->rssi;
-		wstats.noise = rx_stats->noise;
-		wstats.updated = 6;	/* No qual value */
-		/* Update spy records */
-		wireless_spy_update(dev, hdr->addr2, &wstats);
-	}
-#endif /* IW_WIRELESS_SPY */
-#endif /* WIRELESS_EXT > 15 */
-	hostap_update_rx_stats(local->ap, hdr, rx_stats);
-#endif
 
-#if WIRELESS_EXT > 15
 	if (ieee->iw_mode == IW_MODE_MONITOR) {
 		ieee80211_monitor_rx(ieee, skb, rx_stats);
 		stats->rx_packets++;
 		stats->rx_bytes += skb->len;
 		return 1;
 	}
-#endif
+
 	if (ieee->host_decrypt) {
 		int idx = 0;
 		if (skb->len >= hdrlen + 3)
 			idx = skb->data[hdrlen + 3] >> 6;
 		crypt = ieee->crypt[idx];
-#ifdef NOT_YET
-		sta = NULL;
-
-		/* Use station specific key to override default keys if the
-		 * receiver address is a unicast address ("individual RA"). If
-		 * bcrx_sta_key parameter is set, station specific key is used
-		 * even with broad/multicast targets (this is against IEEE
-		 * 802.11, but makes it easier to use different keys with
-		 * stations that do not support WEP key mapping). */
-
-		if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
-			(void) hostap_handle_sta_crypto(local, hdr, &crypt,
-							&sta);
-#endif
 
 		/* allow NULL decrypt to indicate an station specific override
 		 * for default encryption */
@@ -1067,17 +959,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 	else
 	{
 		PRX_TS_RECORD pRxTS = NULL;
-	#if 0
-		struct ieee80211_hdr_3addr *hdr;
-		u16 fc;
-		hdr = (struct ieee80211_hdr_3addr *)skb->data;
-		fc = le16_to_cpu(hdr->frame_ctl);
-		u8 tmp = (fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS);
-
-		u8 tid = (*((u8*)skb->data + (((fc& IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))?30:24)))&0xf;
-		printk("====================>fc:%x, tid:%d, tmp:%d\n", fc, tid, tmp);
-		//u8 tid =  (u8)((frameqos*)(buf + ((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24))->field.tid;
-	#endif
 			//IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): QOS ENABLE AND RECEIVE QOS DATA , we will get Ts, tid:%d\n",__FUNCTION__, tid);
 #if 1
 		if(GetTs(
@@ -1111,20 +992,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 #endif
 	if (type == IEEE80211_FTYPE_MGMT) {
 
-	#if 0
-		if ( stype == IEEE80211_STYPE_AUTH &&
-		    fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
-		    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
-		{
-			printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
-			       "from " MAC_FMT "\n", dev->name,
-			       MAC_ARG(hdr->addr2));
-			/* TODO: could inform hostapd about this so that it
-			 * could send auth failure report */
-			goto rx_dropped;
-		}
-	#endif
-
 	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
 		if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
 			goto rx_dropped;
@@ -1158,46 +1025,9 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 		break;
 	}
 
-#ifdef NOT_YET
-	if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
-		goto rx_dropped;
-	if (wds) {
-		skb->dev = dev = wds;
-		stats = hostap_get_stats(dev);
-	}
-
-	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
-	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
-	    ieee->stadev &&
-	    memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
-		/* Frame from BSSID of the AP for which we are a client */
-		skb->dev = dev = ieee->stadev;
-		stats = hostap_get_stats(dev);
-		from_assoc_ap = 1;
-	}
-#endif
 
 	dev->last_rx = jiffies;
 
-#ifdef NOT_YET
-	if ((ieee->iw_mode == IW_MODE_MASTER ||
-	     ieee->iw_mode == IW_MODE_REPEAT) &&
-	    !from_assoc_ap) {
-		switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
-					     wds != NULL)) {
-		case AP_RX_CONTINUE_NOT_AUTHORIZED:
-			frame_authorized = 0;
-			break;
-		case AP_RX_CONTINUE:
-			frame_authorized = 1;
-			break;
-		case AP_RX_DROP:
-			goto rx_dropped;
-		case AP_RX_EXIT:
-			goto rx_exit;
-		}
-	}
-#endif
 	//IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
 	/* Nullfunc frames may have PS-bit set, so they must be passed to
 	 * hostap_handle_sta_rx() before being dropped here. */
@@ -1439,10 +1269,6 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
 #endif
 
  rx_exit:
-#ifdef NOT_YET
-	if (sta)
-		hostap_handle_sta_release(sta);
-#endif
 	return 1;
 
  rx_dropped:
@@ -1659,7 +1485,6 @@ static const char *get_info_element_string(u16 id)
 }
 #endif
 
-#ifdef ENABLE_DOT11D
 static inline void ieee80211_extract_country_ie(
 	struct ieee80211_device *ieee,
 	struct ieee80211_info_element *info_element,
@@ -1692,7 +1517,6 @@ static inline void ieee80211_extract_country_ie(
 	}
 
 }
-#endif
 
 int ieee80211_parse_info_param(struct ieee80211_device *ieee,
 		struct ieee80211_info_element *info_element,
@@ -1823,12 +1647,8 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
                         network->dtim_period = info_element->data[1];
                         if(ieee->state != IEEE80211_LINKED)
                                 break;
-#if 0
-                        network->last_dtim_sta_time[0] = stats->mac_time[0];
-#else
 			//we use jiffies for legacy Power save
 			network->last_dtim_sta_time[0] = jiffies;
-#endif
                         network->last_dtim_sta_time[1] = stats->mac_time[1];
 
                         network->dtim_data = IEEE80211_DTIM_VALID;
@@ -1891,7 +1711,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
 				break;
 			}
 
-#ifdef THOMAS_TURBO
                         if (info_element->len == 7 &&
                             info_element->data[0] == 0x00 &&
                             info_element->data[1] == 0xe0 &&
@@ -1900,7 +1719,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
                             info_element->data[4] == 0x02) {
                                 network->Turbo_Enable = 1;
                         }
-#endif
 
                         //for HTcap and HTinfo parameters
 			if(tmp_htcap_len == 0){
@@ -1997,16 +1815,6 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
 
 				}
 			}
-#if 0
-			if (tmp_htcap_len !=0)
-				{
-					u16 cap_ext = ((PHT_CAPABILITY_ELE)&info_element->data[0])->ExtHTCapInfo;
-					if ((cap_ext & 0x0c00) == 0x0c00)
-						{
-							network->ralink_cap_exist = true;
-						}
-				}
-#endif
 			if(info_element->len >= 3 &&
 				info_element->data[0] == 0x00 &&
 				info_element->data[1] == 0x0c &&
@@ -2183,53 +1991,12 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee,
 			       "QoS Error need to parse QOS_PARAMETER IE\n");
 			break;
 
-#ifdef ENABLE_DOT11D
 		case MFIE_TYPE_COUNTRY:
 			IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
 					     info_element->len);
 			//printk("=====>Receive <%s> Country IE\n",network->ssid);
 			ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP
 			break;
-#endif
-/* TODO */
-#if 0
-			/* 802.11h */
-		case MFIE_TYPE_POWER_CONSTRAINT:
-			network->power_constraint = info_element->data[0];
-			network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
-			break;
-
-		case MFIE_TYPE_CSA:
-			network->power_constraint = info_element->data[0];
-			network->flags |= NETWORK_HAS_CSA;
-			break;
-
-		case MFIE_TYPE_QUIET:
-			network->quiet.count = info_element->data[0];
-			network->quiet.period = info_element->data[1];
-			network->quiet.duration = info_element->data[2];
-			network->quiet.offset = info_element->data[3];
-			network->flags |= NETWORK_HAS_QUIET;
-			break;
-
-		case MFIE_TYPE_IBSS_DFS:
-			if (network->ibss_dfs)
-				break;
-			network->ibss_dfs = kmemdup(info_element->data,
-						    info_element->len,
-						    GFP_ATOMIC);
-			if (!network->ibss_dfs)
-				return 1;
-			network->flags |= NETWORK_HAS_IBSS_DFS;
-			break;
-
-		case MFIE_TYPE_TPC_REPORT:
-			network->tpc_report.transmit_power =
-			    info_element->data[0];
-			network->tpc_report.link_margin = info_element->data[1];
-			network->flags |= NETWORK_HAS_TPC_REPORT;
-			break;
-#endif
 		default:
 			IEEE80211_DEBUG_MGMT
 			    ("Unsupported info element: %s (%d)\n",
@@ -2363,13 +2130,9 @@ static inline int ieee80211_network_init(
 	network->unknown_cap_exist = false;
 	network->realtek_cap_exit = false;
 	network->marvell_cap_exist = false;
-#ifdef THOMAS_TURBO
 	network->Turbo_Enable = 0;
-#endif
-#ifdef ENABLE_DOT11D
 	network->CountryIeLen = 0;
 	memset(network->CountryIeBuf, 0, MAX_IE_LEN);
-#endif
 //Initialize HT parameters
 	//ieee80211_ht_initialize(&network->bssht);
 	HTInitializeBssDesc(&network->bssht);
@@ -2543,14 +2306,10 @@ static inline void update_network(struct ieee80211_network *dst,
 #else
 	dst->QoS_Enable = 1;//for Rtl8187 simulation
 #endif
-#ifdef THOMAS_TURBO
 	dst->Turbo_Enable = src->Turbo_Enable;
-#endif
 
-#ifdef ENABLE_DOT11D
 	dst->CountryIeLen = src->CountryIeLen;
 	memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
-#endif
 
 	//added by amy for LEAP
 	dst->bWithAironetIE = src->bWithAironetIE;
@@ -2618,7 +2377,6 @@ static inline void ieee80211_process_probe_response(
 		return;
 	}
 
-#ifdef ENABLE_DOT11D
 	// For Asus EeePc request,
 	// (1) if wireless adapter receive get any 802.11d country code in AP beacon,
 	//	   wireless adapter should follow the country code.
@@ -2675,7 +2433,6 @@ static inline void ieee80211_process_probe_response(
 			}
 		}
 	}
-#endif
 
 	/* The network parsed correctly -- so now we scan our known networks
 	 * to see if we can find it in our list.
@@ -2822,11 +2579,3 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
 
 	}
 }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_rx_mgt);
-EXPORT_SYMBOL(ieee80211_rx);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_rx_mgt);
-EXPORT_SYMBOL_NOVERS(ieee80211_rx);
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
index 6773e84..c64ae03 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac.c
@@ -20,9 +20,7 @@
 #include <linux/delay.h>
 #include <linux/version.h>
 #include <asm/uaccess.h>
-#ifdef ENABLE_DOT11D
 #include "dot11d.h"
-#endif
 
 u8 rsn_authen_cipher_suite[16][4] = {
 	{0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
@@ -129,7 +127,6 @@ void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
 	*tag_p = tag;
 }
 
-#ifdef THOMAS_TURBO
 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
 	u8 *tag = *tag_p;
 
@@ -146,7 +143,6 @@ void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
 	*tag_p = tag;
 	printk(KERN_ALERT "This is enable turbo mode IE process\n");
 }
-#endif
 
 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
 {
@@ -435,10 +431,8 @@ void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 {
 	short ch = 0;
-#ifdef ENABLE_DOT11D
 	u8 channel_map[MAX_CHANNEL_NUMBER+1];
 	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-#endif
 	ieee->be_scan_inprogress = true;
 	down(&ieee->scan_sem);
 
@@ -449,11 +443,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 			ch++;
 			if (ch > MAX_CHANNEL_NUMBER)
 				goto out; /* scan completed */
-#ifdef ENABLE_DOT11D
 		}while(!channel_map[ch]);
-#else
-		}while(!ieee->channel_map[ch]);
-#endif
 
 		/* this fuction can be called in two situations
 		 * 1- We have switched to ad-hoc mode and we are
@@ -477,9 +467,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
 		if (ieee->state == IEEE80211_LINKED)
 			goto out;
 		ieee->set_chan(ieee->dev, ch);
-#ifdef ENABLE_DOT11D
 		if(channel_map[ch] == 1)
-#endif
 		ieee80211_send_probe_requests(ieee);
 
 		/* this prevent excessive time wait when we
@@ -503,48 +491,20 @@ out:
 	}
 	else{
 	ieee->sync_scan_hurryup = 0;
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee))
 		DOT11D_ScanComplete(ieee);
-#endif
 	up(&ieee->scan_sem);
 	ieee->be_scan_inprogress = false;
 }
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-/* called both by wq with ieee->lock held */
-void ieee80211_softmac_scan(struct ieee80211_device *ieee)
-{
-#if 0
-	short watchdog = 0;
-	do{
-		ieee->current_network.channel =
-			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
-		if (watchdog++ > MAX_CHANNEL_NUMBER)
-				return; /* no good chans */
-
-	}while(!ieee->channel_map[ieee->current_network.channel]);
-#endif
-
-	schedule_task(&ieee->softmac_scan_wq);
-}
-#endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_softmac_scan_wq(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, softmac_scan_wq);
-#else
-void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
 	u8 last_channel = ieee->current_network.channel; //recored init channel inorder not change current channel when comming out the scan unexpectedly. WB.
-#ifdef ENABLE_DOT11D
 	u8 channel_map[MAX_CHANNEL_NUMBER+1];
 	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
-#endif
 	if(!ieee->ieee_up)
 		return;
 	down(&ieee->scan_sem);
@@ -554,43 +514,24 @@ void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
 		if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER)
 		{
 		//if current channel is not in channel map, set to default channel.
-		#ifdef ENABLE_DOT11D
       			if (!channel_map[ieee->current_network.channel]);
-		#else
-			if (!ieee->channel_map[ieee->current_network.channel]);
-		#endif
 				ieee->current_network.channel = 6;
 				goto out; /* no good chans */
 		}
-#ifdef ENABLE_DOT11D
         }while(!channel_map[ieee->current_network.channel]);
-#else
-	}while(!ieee->channel_map[ieee->current_network.channel]);
-#endif
 	if (ieee->scanning == 0 )
 		goto out;
 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
-#ifdef ENABLE_DOT11D
 	if(channel_map[ieee->current_network.channel] == 1)
-#endif
 	ieee80211_send_probe_requests(ieee);
 
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
-#else
-	//ieee->scan_timer.expires = jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME);
-	if (ieee->scanning == 1)
-		mod_timer(&ieee->scan_timer,(jiffies + MSECS(IEEE80211_SOFTMAC_SCAN_TIME)));
-#endif
 
 	up(&ieee->scan_sem);
 	return;
 out:
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee))
 		DOT11D_ScanComplete(ieee);
-#endif
 	ieee->current_network.channel = last_channel;
         ieee->actscanning = false;
 	ieee->scan_watch_dog = 0;
@@ -598,19 +539,6 @@ out:
 	up(&ieee->scan_sem);
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-void ieee80211_softmac_scan_cb(unsigned long _dev)
-{
-	unsigned long flags;
-	struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
-
-	spin_lock_irqsave(&ieee->lock, flags);
-	ieee80211_softmac_scan(ieee);
-	spin_unlock_irqrestore(&ieee->lock, flags);
-}
-#endif
-
-
 void ieee80211_beacons_start(struct ieee80211_device *ieee)
 {
 	unsigned long flags;
@@ -666,11 +594,7 @@ void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
 	if (ieee->scanning == 1){
 		ieee->scanning = 0;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 		cancel_delayed_work(&ieee->softmac_scan_wq);
-#else
-		del_timer_sync(&ieee->scan_timer);
-#endif
 	}
 
 //	spin_unlock_irqrestore(&ieee->lock, flags);
@@ -688,7 +612,6 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee)
 /* called with ieee->lock held */
 void ieee80211_start_scan(struct ieee80211_device *ieee)
 {
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee) )
 	{
 		if(IS_COUNTRY_IE_VALID(ieee))
@@ -696,20 +619,10 @@ void ieee80211_start_scan(struct ieee80211_device *ieee)
 			RESET_CIE_WATCHDOG(ieee);
 		}
 	}
-#endif
 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
 		if (ieee->scanning == 0){
 			ieee->scanning = 1;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 			queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
-#else
-
-			queue_work(ieee->wq, &ieee->softmac_scan_wq);
-#endif
-#else
-			ieee80211_softmac_scan(ieee);
-#endif
 		}
 	}else
 		ieee->start_scan(ieee->dev);
@@ -719,7 +632,6 @@ void ieee80211_start_scan(struct ieee80211_device *ieee)
 /* called with wx_sem held */
 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
 {
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee) )
 	{
 		if(IS_COUNTRY_IE_VALID(ieee))
@@ -727,7 +639,6 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
 			RESET_CIE_WATCHDOG(ieee);
 		}
 	}
-#endif
 	ieee->sync_scan_hurryup = 0;
 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
 		ieee80211_softmac_scan_syncro(ieee);
@@ -885,10 +796,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
 		cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
 
 	crypt = ieee->crypt[ieee->tx_keyidx];
-#if 0
-	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
-		(0 == strcmp(crypt->ops->name, "WEP"));
-#endif
+
 	if (encrypt)
 		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
 
@@ -927,14 +835,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
 		*(tag++) = 1;
 		*(tag++) = erpinfo_content;
 	}
-#if 0
-	//Include High Throuput capability
 
-	*(tag++) = MFIE_TYPE_HT_CAP;
-	*(tag++) = tmp_ht_cap_len - 2;
-	memcpy(tag, tmp_ht_cap_buf, tmp_ht_cap_len - 2);
-	tag += tmp_ht_cap_len - 2;
-#endif
 	if(rate_ex_len){
 		*(tag++) = MFIE_TYPE_RATES_EX;
 		*(tag++) = rate_ex_len-2;
@@ -942,14 +843,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
 		tag+=rate_ex_len-2;
 	}
 
-#if 0
-	//Include High Throuput info
-
-	*(tag++) = MFIE_TYPE_HT_INFO;
-	*(tag++) = tmp_ht_info_len - 2;
-	memcpy(tag, tmp_ht_info_buf, tmp_ht_info_len -2);
-	tag += tmp_ht_info_len - 2;
-#endif
 	if (wpa_ie_len)
 	{
 		if (ieee->iw_mode == IW_MODE_ADHOC)
@@ -960,28 +853,6 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d
 		tag += wpa_ie_len;
 	}
 
-#if 0
-	//
-	// Construct Realtek Proprietary Aggregation mode (Set AMPDU Factor to 2, 32k)
-	//
-	if(pHTInfo->bRegRT2RTAggregation)
-	{
-		(*tag++) = 0xdd;
-		(*tag++) = tmp_generic_ie_len - 2;
-		memcpy(tag,tmp_generic_ie_buf,tmp_generic_ie_len -2);
-		tag += tmp_generic_ie_len -2;
-
-	}
-#endif
-#if 0
-	if(ieee->qos_support)
-	{
-		(*tag++) = 0xdd;
-		(*tag++) = wmm_len;
-		memcpy(tag,QosOui,wmm_len);
-		tag += wmm_len;
-	}
-#endif
 	//skb->dev = ieee->dev;
 	return skb;
 }
@@ -1150,9 +1021,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 
 	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
 	unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
-#ifdef THOMAS_TURBO
 	unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
-#endif
 
 	int len = 0;
 
@@ -1190,7 +1059,6 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 	{
 		cxvernum_ie_len = 5+2;
 	}
-#ifdef THOMAS_TURBO
 	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
 		+ beacon->ssid_len//essid tagged val
 		+ rate_len//rates tagged val
@@ -1203,19 +1071,6 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 		+ ccxrm_ie_len
 		+ cxvernum_ie_len
 		+ ieee->tx_headroom;
-#else
-	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
-		+ beacon->ssid_len//essid tagged val
-		+ rate_len//rates tagged val
-		+ wpa_ie_len
-		+ wmm_info_len
-                + ht_cap_len
-		+ realtek_ie_len
-		+ ckip_ie_len
-		+ ccxrm_ie_len
-		+ cxvernum_ie_len
-		+ ieee->tx_headroom;
-#endif
 
 	skb = dev_alloc_skb(len);
 
@@ -1337,12 +1192,10 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
 	if(wmm_info_len) {
 	  ieee80211_WMM_Info(ieee, &tag);
 	}
-#ifdef THOMAS_TURBO
 	tag = skb_put(skb,turbo_info_len);
         if(turbo_info_len) {
                 ieee80211_TURBO_Info(ieee, &tag);
         }
-#endif
 
 	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
 		if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
@@ -1390,12 +1243,8 @@ void ieee80211_associate_abort(struct ieee80211_device *ieee)
 
 	ieee->state = IEEE80211_ASSOCIATING_RETRY;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
                            IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
-#else
-	schedule_task(&ieee->associate_retry_wq);
-#endif
 
 	spin_unlock_irqrestore(&ieee->lock, flags);
 }
@@ -1457,10 +1306,6 @@ void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int
 
 		softmac_mgmt_xmit(skb, ieee);
 		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
-#if 0
-		ieee->associate_timer.expires = jiffies + (HZ / 2);
-		add_timer(&ieee->associate_timer);
-#endif
 		//dev_kfree_skb_any(skb);//edit by thomas
 	}
 	kfree(challenge);
@@ -1482,21 +1327,14 @@ void ieee80211_associate_step2(struct ieee80211_device *ieee)
 	else{
 		softmac_mgmt_xmit(skb, ieee);
 		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
-#if 0
-		ieee->associate_timer.expires = jiffies + (HZ / 2);
-		add_timer(&ieee->associate_timer);
-#endif
 		//dev_kfree_skb_any(skb);//edit by thomas
 	}
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 void ieee80211_associate_complete_wq(struct work_struct *work)
 {
         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
-#else
-void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
-{
-#endif
+
 	printk(KERN_INFO "Associated successfully\n");
 	ieee->is_roaming = false;
 	if(ieee80211_is_54g(ieee->current_network) &&
@@ -1548,41 +1386,15 @@ void ieee80211_associate_complete(struct ieee80211_device *ieee)
 //	struct net_device* dev = ieee->dev;
 	del_timer_sync(&ieee->associate_timer);
 
-#if 0
-	for(i = 0; i < 6; i++) {
-	  ieee->seq_ctrl[i] = 0;
-	}
-#endif
 	ieee->state = IEEE80211_LINKED;
-#if 0
-	if (ieee->pHTInfo->bCurrentHTSupport)
-	{
-		printk("Successfully associated, ht enabled\n");
-		queue_work(ieee->wq, &ieee->ht_onAssRsp);
-	}
-	else
-	{
-		printk("Successfully associated, ht not enabled\n");
-		memset(ieee->dot11HTOperationalRateSet, 0, 16);
-		HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
-	}
-#endif
 	//ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	queue_work(ieee->wq, &ieee->associate_complete_wq);
-#else
-	schedule_task(&ieee->associate_complete_wq);
-#endif
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_associate_procedure_wq(struct work_struct *work)
 {
         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
-#else
-void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
-{
-#endif
+
 	ieee->sync_scan_hurryup = 1;
 	down(&ieee->wx_sem);
 
@@ -1682,11 +1494,7 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee
 					ieee->state = IEEE80211_ASSOCIATING;
 					if(ieee->LedControlHandler != NULL)
 					        ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 					queue_work(ieee->wq, &ieee->associate_procedure_wq);
-#else
-					schedule_task(&ieee->associate_procedure_wq);
-#endif
 				}else{
 					if(ieee80211_is_54g(ieee->current_network) &&
 						(ieee->modulation & IEEE80211_OFDM_MODULATION)){
@@ -1903,11 +1711,6 @@ ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
 
 	printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
 	//FIXME
-	#if 0
-	spin_lock_irqsave(&ieee->lock,flags);
-	add_associate(ieee,dest);
-	spin_unlock_irqrestore(&ieee->lock,flags);
-	#endif
 }
 
 
@@ -2090,7 +1893,8 @@ void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
 }
 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
 {
-	struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
+	struct rtl_ieee80211_hdr *header =
+		(struct rtl_ieee80211_hdr *)skb->data;
 	u8* act = ieee80211_get_payload(header);
 	u8 tmp = 0;
 //	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
@@ -2135,18 +1939,6 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
 
 	if(!ieee->proto_started)
 		return 0;
-#if 0
-	printk("%d, %d, %d, %d\n", ieee->sta_sleep, ieee->ps, ieee->iw_mode, ieee->state);
-	if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
-		ieee->iw_mode == IW_MODE_INFRA &&
-		ieee->state == IEEE80211_LINKED))
-
-		tasklet_schedule(&ieee->ps_task);
-
-	if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
-		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
-		ieee->last_rx_ps_time = jiffies;
-#endif
 
 	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
 
@@ -2194,11 +1986,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
 						"Association response status code 0x%x\n",
 						errcode);
 					if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 						queue_work(ieee->wq, &ieee->associate_procedure_wq);
-#else
-						schedule_task(&ieee->associate_procedure_wq);
-#endif
 					} else {
 						ieee80211_associate_abort(ieee);
 					}
@@ -2310,11 +2098,7 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
 				RemovePeerTS(ieee, header->addr2);
 				if(ieee->LedControlHandler != NULL)
 				        ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK); //added by amy for LED 090318
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 				queue_work(ieee->wq, &ieee->associate_procedure_wq);
-#else
-				schedule_task(&ieee->associate_procedure_wq);
-#endif
 			}
 			break;
 		case IEEE80211_STYPE_MANAGE_ACT:
@@ -2370,11 +2154,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
 #if 1
 	/* if xmit available, just xmit it immediately, else just insert it to the wait queue */
 	for(i = 0; i < txb->nr_frags; i++) {
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-		if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
-#else
 		if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
-#endif
 		(!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
 		     (ieee->queue_stop)) {
 			/* insert the skb packet to the wait queue */
@@ -2383,11 +2163,7 @@ void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *
 			 * */
 			//printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index));
 			//ieee80211_stop_queue(ieee);
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-			skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
-#else
 			skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
-#endif
 		}else{
 			ieee->softmac_data_hard_start_xmit(
 					txb->fragments[i],
@@ -2551,16 +2327,12 @@ void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
 		netif_carrier_on(ieee->dev);
 	}
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 void ieee80211_start_ibss_wq(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, start_ibss_wq);
-#else
-void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
-{
-#endif
 	/* iwconfig mode ad-hoc will schedule this and return
 	 * on the other hand this will block further iwconfig SET
 	 * operations because of the wx_sem hold.
@@ -2586,11 +2358,9 @@ void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
 	ieee80211_softmac_check_all_nets(ieee);
 
 
-#ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d.
 //	if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
 	if (ieee->state == IEEE80211_NOLINK)
 		ieee->current_network.channel = 6;
-#endif
 	/* if not then the state is not linked. Maybe the user swithced to
 	 * ad-hoc mode just after being in monitor mode, or just after
 	 * being very few time in managed mode (so the card have had no
@@ -2673,18 +2443,13 @@ void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
 
 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
-#else
-	schedule_task(&ieee->start_ibss_wq);
-#endif
 }
 
 /* this is called only in user context, with wx_sem held */
 void ieee80211_start_bss(struct ieee80211_device *ieee)
 {
 	unsigned long flags;
-#ifdef ENABLE_DOT11D
 	//
 	// Ref: 802.11d 11.1.3.3
 	// STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
@@ -2696,7 +2461,6 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
 			return;
 		}
 	}
-#endif
 	/* check if we have already found the net we
 	 * are interested in (if any).
 	 * if not (we are disassociated and we are not
@@ -2720,15 +2484,11 @@ void ieee80211_start_bss(struct ieee80211_device *ieee)
 	spin_unlock_irqrestore(&ieee->lock, flags);
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void ieee80211_link_change_wq(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, link_change_wq);
-#else
-void ieee80211_link_change_wq(struct ieee80211_device *ieee)
-{
-#endif
+
 	ieee->link_change(ieee->dev);
 }
 /* called only in userspace context */
@@ -2742,34 +2502,24 @@ void ieee80211_disassociate(struct ieee80211_device *ieee)
 
 	if (ieee->data_hard_stop)
 			ieee->data_hard_stop(ieee->dev);
-#ifdef ENABLE_DOT11D
 	if(IS_DOT11D_ENABLE(ieee))
 		Dot11d_Reset(ieee);
-#endif
 	ieee->state = IEEE80211_NOLINK;
 	ieee->is_set_key = false;
 
 	//LZM for usb dev crash.
 	//ieee->link_change(ieee->dev);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	queue_delayed_work(ieee->wq, &ieee->link_change_wq, 0);
-#else
-	schedule_task(&ieee->link_change_wq);
-#endif
 
 	//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
 	notify_wx_assoc_event(ieee);
 
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 void ieee80211_associate_retry_wq(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, associate_retry_wq);
-#else
-void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
-{
-#endif
 	unsigned long flags;
 
 	down(&ieee->wx_sem);
@@ -2868,11 +2618,9 @@ void ieee80211_stop_protocol(struct ieee80211_device *ieee)
 
 	ieee80211_stop_send_beacons(ieee);
 	del_timer_sync(&ieee->associate_timer);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	cancel_delayed_work(&ieee->associate_retry_wq);
 	cancel_delayed_work(&ieee->start_ibss_wq);
 	cancel_delayed_work(&ieee->link_change_wq);
-#endif
 	ieee80211_stop_scan(ieee);
 
 	ieee80211_disassociate(ieee);
@@ -2901,11 +2649,7 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee)
 			ch++;
 			if (ch > MAX_CHANNEL_NUMBER)
 				return; /* no channel found */
-#ifdef ENABLE_DOT11D
 		}while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
-#else
-		}while(!ieee->channel_map[ch]);
-#endif
 		ieee->current_network.channel = ch;
 	}
 
@@ -2953,12 +2697,10 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 	for(i = 0; i < 5; i++) {
 	  ieee->seq_ctrl[i] = 0;
 	}
-#ifdef ENABLE_DOT11D
 	ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
 	if (!ieee->pDot11dInfo)
 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
 	memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO));
-#endif
 	//added for  AP roaming
 	ieee->LinkDetectInfo.SlotNum = 2;
 	ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
@@ -2990,11 +2732,6 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 	ieee->sta_edca_param[3] = 0x002F3262;
 	ieee->aggregation = true;
 	ieee->enable_rx_imm_BA = 1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	init_timer(&ieee->scan_timer);
-	ieee->scan_timer.data = (unsigned long)ieee;
-	ieee->scan_timer.function = ieee80211_softmac_scan_cb;
-#endif
 	ieee->tx_pending.txb = NULL;
 
 	init_timer(&ieee->associate_timer);
@@ -3005,16 +2742,12 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 	ieee->beacon_timer.data = (unsigned long) ieee;
 	ieee->beacon_timer.function = ieee80211_send_beacon_cb;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 #ifdef PF_SYNCTHREAD
 	ieee->wq = create_workqueue(DRV_NAME,0);
 #else
 	ieee->wq = create_workqueue(DRV_NAME);
 #endif
-#endif
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
         INIT_DELAYED_WORK(&ieee->link_change_wq,ieee80211_link_change_wq);
         INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
         INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
@@ -3023,25 +2756,6 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
         INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
         INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
 
-#else
-	INIT_WORK(&ieee->link_change_wq,(void(*)(void*)) ieee80211_link_change_wq,ieee);
-	INIT_WORK(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
-	INIT_WORK(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
-	INIT_WORK(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
-	INIT_WORK(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
-	INIT_WORK(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
-	INIT_WORK(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
-#endif
-
-#else
-	tq_init(&ieee->link_change_wq,(void(*)(void*)) ieee80211_link_change_wq,ieee);
-	tq_init(&ieee->start_ibss_wq,(void(*)(void*)) ieee80211_start_ibss_wq,ieee);
-	tq_init(&ieee->associate_retry_wq,(void(*)(void*)) ieee80211_associate_retry_wq,ieee);
-	tq_init(&ieee->associate_complete_wq,(void(*)(void*)) ieee80211_associate_complete_wq,ieee);
-	tq_init(&ieee->associate_procedure_wq,(void(*)(void*)) ieee80211_associate_procedure_wq,ieee);
-	tq_init(&ieee->softmac_scan_wq,(void(*)(void*)) ieee80211_softmac_scan_wq,ieee);
-	tq_init(&ieee->wx_sync_scan_wq,(void(*)(void*)) ieee80211_wx_sync_scan_wq,ieee);
-#endif
 	sema_init(&ieee->wx_sem, 1);
 	sema_init(&ieee->scan_sem, 1);
 
@@ -3057,19 +2771,15 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee)
 void ieee80211_softmac_free(struct ieee80211_device *ieee)
 {
 	down(&ieee->wx_sem);
-#ifdef ENABLE_DOT11D
 	if(NULL != ieee->pDot11dInfo)
 	{
 		kfree(ieee->pDot11dInfo);
 		ieee->pDot11dInfo = NULL;
 	}
-#endif
 	del_timer_sync(&ieee->associate_timer);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	cancel_delayed_work(&ieee->associate_retry_wq);
 	destroy_workqueue(ieee->wq);
-#endif
 
 	up(&ieee->wx_sem);
 }
@@ -3172,7 +2882,7 @@ static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
 		ieee->auth_mode = 0;
 	}
 	else if (value & AUTH_ALG_LEAP){
-		sec.auth_mode = WLAN_AUTH_LEAP;
+		sec.auth_mode = RTL_WLAN_AUTH_LEAP;
 		ieee->open_wep = 1;
 		ieee->auth_mode = 2;
 	}
@@ -3347,11 +3057,8 @@ static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
 		}
 		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
 		new_crypt->ops = ops;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+
 		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-#else
-		if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
-#endif
 			new_crypt->priv =
 				new_crypt->ops->init(param->u.crypt.idx);
 
@@ -3533,48 +3240,3 @@ void notify_wx_assoc_event(struct ieee80211_device *ieee)
 		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
 	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
 }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_get_beacon);
-EXPORT_SYMBOL(ieee80211_wake_queue);
-EXPORT_SYMBOL(ieee80211_stop_queue);
-EXPORT_SYMBOL(ieee80211_reset_queue);
-EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
-EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
-EXPORT_SYMBOL(ieee80211_is_shortslot);
-EXPORT_SYMBOL(ieee80211_is_54g);
-EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
-EXPORT_SYMBOL(ieee80211_ps_tx_ack);
-EXPORT_SYMBOL(ieee80211_softmac_xmit);
-EXPORT_SYMBOL(ieee80211_stop_send_beacons);
-EXPORT_SYMBOL(notify_wx_assoc_event);
-EXPORT_SYMBOL(SendDisassociation);
-EXPORT_SYMBOL(ieee80211_disassociate);
-EXPORT_SYMBOL(ieee80211_start_send_beacons);
-EXPORT_SYMBOL(ieee80211_stop_scan);
-EXPORT_SYMBOL(ieee80211_send_probe_requests);
-EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
-EXPORT_SYMBOL(ieee80211_start_scan_syncro);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_get_beacon);
-EXPORT_SYMBOL_NOVERS(ieee80211_wake_queue);
-EXPORT_SYMBOL_NOVERS(ieee80211_stop_queue);
-EXPORT_SYMBOL_NOVERS(ieee80211_reset_queue);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_stop_protocol);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_start_protocol);
-EXPORT_SYMBOL_NOVERS(ieee80211_is_shortslot);
-EXPORT_SYMBOL_NOVERS(ieee80211_is_54g);
-EXPORT_SYMBOL_NOVERS(ieee80211_wpa_supplicant_ioctl);
-EXPORT_SYMBOL_NOVERS(ieee80211_ps_tx_ack);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_xmit);
-EXPORT_SYMBOL_NOVERS(ieee80211_stop_send_beacons);
-EXPORT_SYMBOL_NOVERS(notify_wx_assoc_event);
-EXPORT_SYMBOL_NOVERS(SendDisassociation);
-EXPORT_SYMBOL_NOVERS(ieee80211_disassociate);
-EXPORT_SYMBOL_NOVERS(ieee80211_start_send_beacons);
-EXPORT_SYMBOL_NOVERS(ieee80211_stop_scan);
-EXPORT_SYMBOL_NOVERS(ieee80211_send_probe_requests);
-EXPORT_SYMBOL_NOVERS(ieee80211_softmac_scan_syncro);
-EXPORT_SYMBOL_NOVERS(ieee80211_start_scan_syncro);
-#endif
-//EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c
index 191dc3f..9ded253 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c
@@ -15,9 +15,7 @@
 
 
 #include "ieee80211.h"
-#ifdef ENABLE_DOT11D
 #include "dot11d.h"
-#endif
 /* FIXME: add A freqs */
 
 const long ieee80211_wlan_frequencies[] = {
@@ -63,12 +61,10 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info
 
 	}else { /* Set the channel */
 
-#ifdef ENABLE_DOT11D
 		if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) {
 			ret = -EINVAL;
 			goto out;
 		}
-#endif
 		ieee->current_network.channel = fwrq->m;
 		ieee->set_chan(ieee->dev, ieee->current_network.channel);
 
@@ -234,7 +230,6 @@ int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
 			     union iwreq_data *wrqu, char *extra)
 {
 	u32 tmp_rate = 0;
-#ifdef RTL8192SU
 	//printk("===>mode:%d, halfNmode:%d\n", ieee->mode, ieee->bHalfWirelessN24GMode);
 	if (ieee->mode & (IEEE_A | IEEE_B | IEEE_G))
 		tmp_rate = ieee->rate;
@@ -247,10 +242,6 @@ int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
 		else
 			tmp_rate = HTMcsToDataRate(ieee, 15);
 	}
-#else
-	tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate);
-
-#endif
 	wrqu->bitrate.value = tmp_rate * 500000;
 
 	return 0;
@@ -313,14 +304,9 @@ out:
 	return 0;
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 void ieee80211_wx_sync_scan_wq(struct work_struct *work)
 {
         struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
-#else
-void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
-{
-#endif
 	short chan;
 	HT_EXTCHNL_OFFSET chan_offset=0;
 	HT_CHANNEL_WIDTH bandwidth=0;
@@ -336,16 +322,12 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
 
 	ieee->state = IEEE80211_LINKED_SCANNING;
 	ieee->link_change(ieee->dev);
-#ifndef RTL8192SE
 	ieee->InitialGainHandler(ieee->dev,IG_Backup);
-#endif
-#if(RTL8192S_DISABLE_FW_DM == 0)
 	if (ieee->SetFwCmdHandler)
 	{
 		ieee->SetFwCmdHandler(ieee->dev, FW_CMD_DIG_HALT);
 		ieee->SetFwCmdHandler(ieee->dev, FW_CMD_HIGH_PWR_DISABLE);
 	}
-#endif
 	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) {
 		b40M = 1;
 		chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset;
@@ -367,16 +349,12 @@ void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
 		ieee->set_chan(ieee->dev, chan);
 	}
 
-#ifndef RTL8192SE
 	ieee->InitialGainHandler(ieee->dev,IG_Restore);
-#endif
-#if(RTL8192S_DISABLE_FW_DM == 0)
 	if (ieee->SetFwCmdHandler)
 	{
 		ieee->SetFwCmdHandler(ieee->dev, FW_CMD_DIG_RESUME);
 		ieee->SetFwCmdHandler(ieee->dev, FW_CMD_HIGH_PWR_ENABLE);
 	}
-#endif
 	ieee->state = IEEE80211_LINKED;
 	ieee->link_change(ieee->dev);
 	// To prevent the immediately calling watch_dog after scan.
@@ -410,11 +388,7 @@ int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info
 	}
 
 	if ( ieee->state == IEEE80211_LINKED){
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 		queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
-#else
-		schedule_task(&ieee->wx_sync_scan_wq);
-#endif
 		/* intentionally forget to up sem */
 		return 0;
 	}
@@ -460,29 +434,8 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
 	if (wrqu->essid.flags && wrqu->essid.length) {
 		//first flush current network.ssid
 		len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
-#if LINUX_VERSION_CODE <  KERNEL_VERSION(2,6,20)
-		strncpy(ieee->current_network.ssid, extra, len);
-		ieee->current_network.ssid_len = len;
-#if 0
-		{
-			int i;
-			for (i=0; i<len; i++)
-				printk("%c ", extra[i]);
-			printk("\n");
-		}
-#endif
-#else
 		strncpy(ieee->current_network.ssid, extra, len+1);
 		ieee->current_network.ssid_len = len+1;
-#if 0
-		{
-			int i;
-			for (i=0; i<len + 1; i++)
-				printk("%c ", extra[i]);
-			printk("\n");
-		}
-#endif
-#endif
 		ieee->ssid_set = 1;
 	}
 	else{
@@ -670,42 +623,3 @@ exit:
 	return ret;
 
 }
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_wx_get_essid);
-EXPORT_SYMBOL(ieee80211_wx_set_essid);
-EXPORT_SYMBOL(ieee80211_wx_set_rate);
-EXPORT_SYMBOL(ieee80211_wx_get_rate);
-EXPORT_SYMBOL(ieee80211_wx_set_wap);
-EXPORT_SYMBOL(ieee80211_wx_get_wap);
-EXPORT_SYMBOL(ieee80211_wx_set_mode);
-EXPORT_SYMBOL(ieee80211_wx_get_mode);
-EXPORT_SYMBOL(ieee80211_wx_set_scan);
-EXPORT_SYMBOL(ieee80211_wx_get_freq);
-EXPORT_SYMBOL(ieee80211_wx_set_freq);
-EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
-EXPORT_SYMBOL(ieee80211_wx_get_name);
-EXPORT_SYMBOL(ieee80211_wx_set_power);
-EXPORT_SYMBOL(ieee80211_wx_get_power);
-EXPORT_SYMBOL(ieee80211_wlan_frequencies);
-EXPORT_SYMBOL(ieee80211_wx_set_rts);
-EXPORT_SYMBOL(ieee80211_wx_get_rts);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_essid);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_essid);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rate);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rate);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_wap);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_wap);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mode);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_mode);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_scan);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_freq);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_freq);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rawtx);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_name);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_power);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_power);
-EXPORT_SYMBOL_NOVERS(ieee80211_wlan_frequencies);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_rts);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_rts);
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
index cba12b8..47ff0ef 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_tx.c
@@ -193,11 +193,11 @@ int ieee80211_encrypt_fragment(
 		return -1;
 	}
 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
-	struct ieee80211_hdr *header;
+	struct rtl_ieee80211_hdr *header;
 
 	if (ieee->tkip_countermeasures &&
 	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
-		header = (struct ieee80211_hdr *) frag->data;
+		header = (struct rtl_ieee80211_hdr *)frag->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 			       "TX packet to " MAC_FMT "\n",
@@ -235,11 +235,6 @@ void ieee80211_txb_free(struct ieee80211_txb *txb) {
 	//int i;
 	if (unlikely(!txb))
 		return;
-#if 0
-	for (i = 0; i < txb->nr_frags; i++)
-		if (txb->fragments[i])
-			dev_kfree_skb_any(txb->fragments[i]);
-#endif
 	kfree(txb);
 }
 
@@ -287,11 +282,8 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
 		return 0;
 
 //	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
 	ip = ip_hdr(skb);
-#else
-	ip = (struct iphdr*)(skb->data + sizeof(struct ether_header));
-#endif
+
 	switch (ip->tos & 0xfc) {
 		case 0x20:
 			return 2;
@@ -312,7 +304,6 @@ ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
 	}
 }
 
-#define SN_LESS(a, b)		(((a-b)&0x800)!=0)
 void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc)
 {
 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
@@ -498,11 +489,7 @@ void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_
 			{
 				tcb_desc->bCTSEnable	= true;
 				tcb_desc->rts_rate  = 	MGN_24M;
-#if defined(RTL8192SE) || defined(RTL8192SU)
 				tcb_desc->bRTSEnable = false;
-#else
-				tcb_desc->bRTSEnable = true;
-#endif
 				break;
 			}
 			else if(pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_PURE_N_MODE))
@@ -620,11 +607,7 @@ void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u
 
 int rtl8192_ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 	struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
 	struct ieee80211_txb *txb = NULL;
 	struct ieee80211_hdr_3addrqos *frag_hdr;
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
@@ -943,6 +926,3 @@ int rtl8192_ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 	return 1;
 
 }
-EXPORT_SYMBOL(rtl8192_ieee80211_xmit);
-
-EXPORT_SYMBOL(ieee80211_txb_free);
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
index ae11e25..1077590 100644
--- a/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_wx.c
@@ -35,11 +35,7 @@
 #include <linux/module.h>
 
 #include "ieee80211.h"
-#if 0
-static const char *ieee80211_modes[] = {
-	"?", "a", "b", "ab", "g", "ag", "bg", "abg"
-};
-#endif
+
 struct modes_unit {
 	char *mode_string;
 	int mode_size;
@@ -53,25 +49,7 @@ struct modes_unit ieee80211_modes[] = {
 	{"N-5G",4},
 };
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static inline char *
-iwe_stream_add_event_rsl(char *     stream,         /* Stream of events */
-                     char *     ends,           /* End of stream */
-                     struct iw_event *iwe,      /* Payload */
-                     int        event_len)      /* Real size of payload */
-{
-        /* Check if it's possible */
-        if((stream + event_len) < ends) {
-                iwe->len = event_len;
-		ndelay(1);   //new
-                memcpy(stream, (char *) iwe, event_len);
-                stream += event_len;
-        }
-        return stream;
-}
-#else
 #define iwe_stream_add_event_rsl iwe_stream_add_event
-#endif
 
 #define MAX_CUSTOM_LEN 64
 static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
@@ -92,11 +70,8 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 	iwe.cmd = SIOCGIWAP;
 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 	memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
 	start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-#else
-	start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_ADDR_LEN);
-#endif
+
 	/* Remaining entries will be displayed in the order we provide them */
 
 	/* Add the ESSID */
@@ -105,22 +80,14 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 //	if (network->flags & NETWORK_EMPTY_ESSID) {
 	if (network->ssid_len == 0) {
 		iwe.u.data.length = sizeof("<hidden>");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
-#endif
         } else {
 		iwe.u.data.length = min(network->ssid_len, (u8)32);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
-#endif
         }
 	/* Add the protocol name */
 	iwe.cmd = SIOCGIWNAME;
-	for(i=0; i<(sizeof(ieee80211_modes)/sizeof(ieee80211_modes[0])); i++) {
+	for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) {
 		if(network->mode&(1<<i)) {
 			sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size);
 			pname +=ieee80211_modes[i].mode_size;
@@ -128,11 +95,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 	}
 	*pname = '\0';
 	snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_CHAR_LEN);
-#endif
         /* Add mode */
         iwe.cmd = SIOCGIWMODE;
         if (network->capability &
@@ -141,11 +104,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 			iwe.u.mode = IW_MODE_MASTER;
 		else
 			iwe.u.mode = IW_MODE_ADHOC;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN);
-#else
-                start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_UINT_LEN);
-#endif
         }
 
         /* Add frequency/channel */
@@ -155,11 +114,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 	iwe.u.freq.m = network->channel;
 	iwe.u.freq.e = 0;
 	iwe.u.freq.i = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_FREQ_LEN);
-#endif
 	/* Add encryption capability */
 	iwe.cmd = SIOCGIWENCODE;
 	if (network->capability & WLAN_CAPABILITY_PRIVACY)
@@ -167,11 +122,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 	else
 		iwe.u.data.flags = IW_ENCODE_DISABLED;
 	iwe.u.data.length = 0;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-#else
-        start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
-#endif
 	/* Add basic and extended rates */
 	max_rate = 0;
 	p = custom;
@@ -215,33 +166,18 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 		if (rate > max_rate)
 			max_rate = rate;
 	}
-#if 0
-	printk("max rate:%d ===basic rate:\n", max_rate);
-	for (i=0;i<network->rates_len;i++)
-		printk(" %x", network->rates[i]);
-	printk("\n=======extend rate\n");
-	for (i=0; i<network->rates_ex_len; i++)
-		printk(" %x", network->rates_ex[i]);
-	printk("\n");
-#endif
+
 	iwe.cmd = SIOCGIWRATE;
 	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
 	iwe.u.bitrate.value = max_rate * 500000;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe,
 				     IW_EV_PARAM_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe,
-				     IW_EV_PARAM_LEN);
-#endif
+
 	iwe.cmd = IWEVCUSTOM;
 	iwe.u.data.length = p - custom;
 	if (iwe.u.data.length)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-        start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
+
 	/* Add quality statistics */
 	/* TODO: Fix these values... */
 	iwe.cmd = IWEVQUAL;
@@ -256,60 +192,14 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 	if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
 		iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
 	iwe.u.qual.updated = 7;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
         start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-#else
-        start = iwe_stream_add_event_rsl(start, stop, &iwe, IW_EV_QUAL_LEN);
-#endif
 	iwe.cmd = IWEVCUSTOM;
 	p = custom;
 
 	iwe.u.data.length = p - custom;
 	if (iwe.u.data.length)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
             start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-            start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
-#if (WIRELESS_EXT < 18)
-	if (ieee->wpa_enabled && network->wpa_ie_len){
-		char buf[MAX_WPA_IE_LEN * 2 + 30];
-	//	printk("WPA IE\n");
-		u8 *p = buf;
-		p += sprintf(p, "wpa_ie=");
-		for (i = 0; i < network->wpa_ie_len; i++) {
-			p += sprintf(p, "%02x", network->wpa_ie[i]);
-		}
-
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = IWEVCUSTOM;
-		iwe.u.data.length = strlen(buf);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
-        }
 
-	if (ieee->wpa_enabled && network->rsn_ie_len){
-		char buf[MAX_WPA_IE_LEN * 2 + 30];
-
-		u8 *p = buf;
-		p += sprintf(p, "rsn_ie=");
-		for (i = 0; i < network->rsn_ie_len; i++) {
-			p += sprintf(p, "%02x", network->rsn_ie[i]);
-		}
-
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = IWEVCUSTOM;
-		iwe.u.data.length = strlen(buf);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
-                start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
-        }
-#else
 	memset(&iwe, 0, sizeof(iwe));
 	if (network->wpa_ie_len)
 	{
@@ -317,11 +207,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 		memcpy(buf, network->wpa_ie, network->wpa_ie_len);
 		iwe.cmd = IWEVGENIE;
 		iwe.u.data.length = network->wpa_ie_len;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
         }
 	memset(&iwe, 0, sizeof(iwe));
 	if (network->rsn_ie_len)
@@ -330,14 +216,8 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 		memcpy(buf, network->rsn_ie, network->rsn_ie_len);
 		iwe.cmd = IWEVGENIE;
 		iwe.u.data.length = network->rsn_ie_len;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
                 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
-#else
-                start = iwe_stream_add_point(start, stop, &iwe, buf);
-#endif
         }
-#endif
-
 
 	/* Add EXTRA: Age to display seconds since last beacon/probe response
 	 * for given network. */
@@ -347,11 +227,7 @@ static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee,
 		      " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
 	iwe.u.data.length = p - custom;
 	if (iwe.u.data.length)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
             start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-#else
-            start = iwe_stream_add_point(start, stop, &iwe, custom);
-#endif
 
 	return start;
 }
@@ -486,11 +362,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
 			request_module("ieee80211_crypt_wep");
 			new_crypt->ops = ieee80211_get_crypto_ops("WEP");
 		}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-#else
-		if (new_crypt->ops && try_inc_mod_count(new_crypt->ops->owner))
-#endif
 			new_crypt->priv = new_crypt->ops->init(key);
 
 		if (!new_crypt->ops || !new_crypt->priv) {
@@ -611,15 +483,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
 		erq->flags |= IW_ENCODE_DISABLED;
 		return 0;
 	}
-#if 0
-	if (strcmp(crypt->ops->name, "WEP") != 0) {
-		/* only WEP is supported with wireless extensions, so just
-		 * report that encryption is used */
-		erq->length = 0;
-		erq->flags |= IW_ENCODE_ENABLED;
-		return 0;
-	}
-#endif
+
 	len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv);
 	erq->length = (len >= 0 ? len : 0);
 
@@ -632,13 +496,12 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
 
 	return 0;
 }
-#if (WIRELESS_EXT >= 18)
+
 int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
 	int ret = 0;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct net_device *dev = ieee->dev;
         struct iw_point *encoding = &wrqu->encoding;
         struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
@@ -678,7 +541,8 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                         return -EINVAL;
         }
 
-        sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
+	sec.flags |= SEC_ENABLED;
+
         if ((encoding->flags & IW_ENCODE_DISABLED) ||
             ext->alg == IW_ENCODE_ALG_NONE) {
                 if (*crypt)
@@ -702,12 +566,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
 
 	sec.enabled = 1;
     //    sec.encrypt = 1;
-#if 0
-        if (group_key ? !ieee->host_mc_decrypt :
-            !(ieee->host_encrypt || ieee->host_decrypt ||
-              ieee->host_encrypt_msdu))
-                goto skip_host_crypt;
-#endif
+
         switch (ext->alg) {
         case IW_ENCODE_ALG_WEP:
                 alg = "WEP";
@@ -747,12 +606,7 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
 
                 ieee80211_crypt_delayed_deinit(ieee, crypt);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
                 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
-#else
-                new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
-		memset(new_crypt,0,sizeof(*new_crypt));
-#endif
                 if (new_crypt == NULL) {
                         ret = -ENOMEM;
                         goto done;
@@ -791,15 +645,12 @@ int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
                 sec.key_sizes[idx] = ext->key_len;
                 sec.flags |= (1 << idx);
                 if (ext->alg == IW_ENCODE_ALG_WEP) {
-                      //  sec.encode_alg[idx] = SEC_ALG_WEP;
                         sec.flags |= SEC_LEVEL;
                         sec.level = SEC_LEVEL_1;
                 } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
-                      //  sec.encode_alg[idx] = SEC_ALG_TKIP;
                         sec.flags |= SEC_LEVEL;
                         sec.level = SEC_LEVEL_2;
                 } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
-                       // sec.encode_alg[idx] = SEC_ALG_CCMP;
                         sec.flags |= SEC_LEVEL;
                         sec.level = SEC_LEVEL_3;
                 }
@@ -818,71 +669,16 @@ done:
                 IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
                 return -EINVAL;
         }
-#endif
-        return ret;
-}
-
-int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
-{
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	struct ieee80211_crypt_data *crypt;
-	int idx, max_key_len;
-
-	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 > WEP_KEYS)
-			return -EINVAL;
-		idx--;
-	} else
-		idx = ieee->tx_keyidx;
-
-	if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
-	    ext->alg != IW_ENCODE_ALG_WEP)
-		if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
-			return -EINVAL;
-
-	crypt = ieee->crypt[idx];
-	encoding->flags = idx + 1;
-	memset(ext, 0, sizeof(*ext));
-
-	if (crypt == NULL || crypt->ops == NULL ) {
-		ext->alg = IW_ENCODE_ALG_NONE;
-		ext->key_len = 0;
-		encoding->flags |= IW_ENCODE_DISABLED;
-	} else {
-		if (strcmp(crypt->ops->name, "WEP") == 0 )
-			ext->alg = IW_ENCODE_ALG_WEP;
-		else if (strcmp(crypt->ops->name, "TKIP"))
-			ext->alg = IW_ENCODE_ALG_TKIP;
-		else if (strcmp(crypt->ops->name, "CCMP"))
-			ext->alg = IW_ENCODE_ALG_CCMP;
-		else
-			return -EINVAL;
-		ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv);
-		encoding->flags |= IW_ENCODE_ENABLED;
-		if (ext->key_len &&
-		    (ext->alg == IW_ENCODE_ALG_TKIP ||
-		     ext->alg == IW_ENCODE_ALG_CCMP))
-			ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID;
 
-	}
-
-	return 0;
+        return ret;
 }
 
 int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
                                struct iw_request_info *info,
                                union iwreq_data *wrqu, char *extra)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct iw_mlme *mlme = (struct iw_mlme *) extra;
+
 	switch (mlme->cmd) {
         case IW_MLME_DEAUTH:
 	case IW_MLME_DISASSOC:
@@ -891,7 +687,7 @@ int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
 	 default:
                 return -EOPNOTSUPP;
         }
-#endif
+
 	return 0;
 }
 
@@ -899,7 +695,6 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
                                struct iw_request_info *info,
                                struct iw_param *data, char *extra)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	switch (data->flags & IW_AUTH_INDEX) {
         case IW_AUTH_WPA_VERSION:
 	     /*need to support wpa2 here*/
@@ -957,23 +752,13 @@ int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
 	default:
                 return -EOPNOTSUPP;
 	}
-#endif
+
 	return 0;
 }
-#endif
+
 #if 1
 int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-#if 0
-	printk("====>%s()\n", __FUNCTION__);
-	{
-		int i;
-		for (i=0; i<len; i++)
-		printk("%2x ", ie[i]&0xff);
-		printk("\n");
-	}
-#endif
 	u8 *buf;
 
 	if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
@@ -987,7 +772,7 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
 	{
 		if (len != ie[1]+2)
 		{
-			printk("len:%d, ie:%d\n", len, ie[1]);
+			printk("len: %Zd, ie:%d\n", len, ie[1]);
 			return -EINVAL;
 		}
 		buf = kmalloc(len, GFP_KERNEL);
@@ -1004,29 +789,8 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
 		ieee->wpa_ie = NULL;
 		ieee->wpa_ie_len = 0;
 	}
-#endif
+
 	return 0;
 
 }
 #endif
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
-#if (WIRELESS_EXT >= 18)
-EXPORT_SYMBOL(ieee80211_wx_set_mlme);
-EXPORT_SYMBOL(ieee80211_wx_set_auth);
-EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
-EXPORT_SYMBOL(ieee80211_wx_get_encode_ext);
-#endif
-EXPORT_SYMBOL(ieee80211_wx_get_scan);
-EXPORT_SYMBOL(ieee80211_wx_set_encode);
-EXPORT_SYMBOL(ieee80211_wx_get_encode);
-#else
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_gen_ie);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_mlme);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_auth);
-//EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode_ext);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_scan);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_set_encode);
-EXPORT_SYMBOL_NOVERS(ieee80211_wx_get_encode);
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/internal.h b/drivers/staging/rtl8192su/ieee80211/internal.h
deleted file mode 100644
index ddc2235..0000000
--- a/drivers/staging/rtl8192su/ieee80211/internal.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 _CRYPTO_INTERNAL_H
-#define _CRYPTO_INTERNAL_H
-
-
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/init.h>
-#include <asm/hardirq.h>
-#include <asm/softirq.h>
-#include <asm/kmap_types.h>
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
-#define list_for_each_entry(pos, head, member)				\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head); 					\
-	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next))
-
-static inline void cond_resched(void)
-{
-	if (need_resched()) {
-		set_current_state(TASK_RUNNING);
-		schedule();
-	}
-}
-#endif
-
-extern enum km_type crypto_km_types[];
-
-static inline enum km_type crypto_kmap_type(int out)
-{
-	return crypto_km_types[(in_softirq() ? 2 : 0) + out];
-}
-
-static inline void *crypto_kmap(struct page *page, int out)
-{
-	return kmap_atomic(page, crypto_kmap_type(out));
-}
-
-static inline void crypto_kunmap(void *vaddr, int out)
-{
-	kunmap_atomic(vaddr, crypto_kmap_type(out));
-}
-
-static inline void crypto_yield(struct crypto_tfm *tfm)
-{
-	if (!in_softirq())
-		cond_resched();
-}
-
-static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
-{
-	return (void *)&tfm[1];
-}
-
-struct crypto_alg *crypto_alg_lookup(const char *name);
-
-#ifdef CONFIG_KMOD
-void crypto_alg_autoload(const char *name);
-struct crypto_alg *crypto_alg_mod_lookup(const char *name);
-#else
-static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
-{
-	return crypto_alg_lookup(name);
-}
-#endif
-
-#ifdef CONFIG_CRYPTO_HMAC
-int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
-void crypto_free_hmac_block(struct crypto_tfm *tfm);
-#else
-static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
-{
-	return 0;
-}
-
-static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
-{ }
-#endif
-
-#ifdef CONFIG_PROC_FS
-void __init crypto_init_proc(void);
-#else
-static inline void crypto_init_proc(void)
-{ }
-#endif
-
-int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
-int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
-int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
-
-int crypto_init_digest_ops(struct crypto_tfm *tfm);
-int crypto_init_cipher_ops(struct crypto_tfm *tfm);
-int crypto_init_compress_ops(struct crypto_tfm *tfm);
-
-void crypto_exit_digest_ops(struct crypto_tfm *tfm);
-void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
-void crypto_exit_compress_ops(struct crypto_tfm *tfm);
-
-#endif	/* _CRYPTO_INTERNAL_H */
-
diff --git a/drivers/staging/rtl8192su/ieee80211/kmap_types.h b/drivers/staging/rtl8192su/ieee80211/kmap_types.h
deleted file mode 100644
index de67bb0..0000000
--- a/drivers/staging/rtl8192su/ieee80211/kmap_types.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __KMAP_TYPES_H
-
-#define __KMAP_TYPES_H
-
-
-enum km_type {
-	KM_BOUNCE_READ,
-	KM_SKB_SUNRPC_DATA,
-	KM_SKB_DATA_SOFTIRQ,
-	KM_USER0,
-	KM_USER1,
-	KM_BH_IRQ,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-	KM_TYPE_NR
-};
-
-#define _ASM_KMAP_TYPES_H
-
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/michael_mic.c b/drivers/staging/rtl8192su/ieee80211/michael_mic.c
deleted file mode 100644
index df256e4..0000000
--- a/drivers/staging/rtl8192su/ieee80211/michael_mic.c
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Cryptographic API
- *
- * Michael MIC (IEEE 802.11i/TKIP) keyed digest
- *
- * Copyright (c) 2004 Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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/module.h>
-#include <linux/string.h>
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-
-
-struct michael_mic_ctx {
-	u8 pending[4];
-	size_t pending_len;
-
-	u32 l, r;
-};
-
-
-static inline u32 rotl(u32 val, int bits)
-{
-	return (val << bits) | (val >> (32 - bits));
-}
-
-
-static inline u32 rotr(u32 val, int bits)
-{
-	return (val >> bits) | (val << (32 - bits));
-}
-
-
-static inline u32 xswap(u32 val)
-{
-	return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
-}
-
-
-#define michael_block(l, r)	\
-do {				\
-	r ^= rotl(l, 17);	\
-	l += r;			\
-	r ^= xswap(l);		\
-	l += r;			\
-	r ^= rotl(l, 3);	\
-	l += r;			\
-	r ^= rotr(l, 2);	\
-	l += r;			\
-} while (0)
-
-
-static inline u32 get_le32(const u8 *p)
-{
-	return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
-}
-
-
-static inline void put_le32(u8 *p, u32 v)
-{
-	p[0] = v;
-	p[1] = v >> 8;
-	p[2] = v >> 16;
-	p[3] = v >> 24;
-}
-
-
-static void michael_init(void *ctx)
-{
-	struct michael_mic_ctx *mctx = ctx;
-	mctx->pending_len = 0;
-}
-
-
-static void michael_update(void *ctx, const u8 *data, unsigned int len)
-{
-	struct michael_mic_ctx *mctx = ctx;
-
-	if (mctx->pending_len) {
-		int flen = 4 - mctx->pending_len;
-		if (flen > len)
-			flen = len;
-		memcpy(&mctx->pending[mctx->pending_len], data, flen);
-		mctx->pending_len += flen;
-		data += flen;
-		len -= flen;
-
-		if (mctx->pending_len < 4)
-			return;
-
-		mctx->l ^= get_le32(mctx->pending);
-		michael_block(mctx->l, mctx->r);
-		mctx->pending_len = 0;
-	}
-
-	while (len >= 4) {
-		mctx->l ^= get_le32(data);
-		michael_block(mctx->l, mctx->r);
-		data += 4;
-		len -= 4;
-	}
-
-	if (len > 0) {
-		mctx->pending_len = len;
-		memcpy(mctx->pending, data, len);
-	}
-}
-
-
-static void michael_final(void *ctx, u8 *out)
-{
-	struct michael_mic_ctx *mctx = ctx;
-	u8 *data = mctx->pending;
-
-	/* Last block and padding (0x5a, 4..7 x 0) */
-	switch (mctx->pending_len) {
-	case 0:
-		mctx->l ^= 0x5a;
-		break;
-	case 1:
-		mctx->l ^= data[0] | 0x5a00;
-		break;
-	case 2:
-		mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000;
-		break;
-	case 3:
-		mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) |
-			0x5a000000;
-		break;
-	}
-	michael_block(mctx->l, mctx->r);
-	/* l ^= 0; */
-	michael_block(mctx->l, mctx->r);
-
-	put_le32(out, mctx->l);
-	put_le32(out + 4, mctx->r);
-}
-
-
-static int michael_setkey(void *ctx, const u8 *key, unsigned int keylen,
-			  u32 *flags)
-{
-	struct michael_mic_ctx *mctx = ctx;
-	if (keylen != 8) {
-		if (flags)
-			*flags = CRYPTO_TFM_RES_BAD_KEY_LEN;
-		return -EINVAL;
-	}
-	mctx->l = get_le32(key);
-	mctx->r = get_le32(key + 4);
-	return 0;
-}
-
-
-static struct crypto_alg michael_mic_alg = {
-	.cra_name	= "michael_mic",
-	.cra_flags	= CRYPTO_ALG_TYPE_DIGEST,
-	.cra_blocksize	= 8,
-	.cra_ctxsize	= sizeof(struct michael_mic_ctx),
-	.cra_module	= THIS_MODULE,
-	.cra_list	= LIST_HEAD_INIT(michael_mic_alg.cra_list),
-	.cra_u		= { .digest = {
-	.dia_digestsize	= 8,
-	.dia_init	= michael_init,
-	.dia_update	= michael_update,
-	.dia_final	= michael_final,
-	.dia_setkey	= michael_setkey } }
-};
-
-
-static int __init michael_mic_init(void)
-{
-	return crypto_register_alg(&michael_mic_alg);
-}
-
-
-static void __exit michael_mic_exit(void)
-{
-	crypto_unregister_alg(&michael_mic_alg);
-}
-
-
-module_init(michael_mic_init);
-module_exit(michael_mic_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Michael MIC");
-MODULE_AUTHOR("Jouni Malinen <jkmaline@cc.hut.fi>");
diff --git a/drivers/staging/rtl8192su/ieee80211/proc.c b/drivers/staging/rtl8192su/ieee80211/proc.c
deleted file mode 100644
index 4f3f9ed..0000000
--- a/drivers/staging/rtl8192su/ieee80211/proc.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Scatterlist Cryptographic API.
- *
- * Procfs information.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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/init.h>
-//#include <linux/crypto.h>
-#include "rtl_crypto.h"
-#include <linux/rwsem.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include "internal.h"
-
-extern struct list_head crypto_alg_list;
-extern struct rw_semaphore crypto_alg_sem;
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
-	struct list_head *v;
-	loff_t n = *pos;
-
-	down_read(&crypto_alg_sem);
-	list_for_each(v, &crypto_alg_list)
-		if (!n--)
-			return list_entry(v, struct crypto_alg, cra_list);
-	return NULL;
-}
-
-static void *c_next(struct seq_file *m, void *p, loff_t *pos)
-{
-	struct list_head *v = p;
-
-	(*pos)++;
-	v = v->next;
-	return (v == &crypto_alg_list) ?
-		NULL : list_entry(v, struct crypto_alg, cra_list);
-}
-
-static void c_stop(struct seq_file *m, void *p)
-{
-	up_read(&crypto_alg_sem);
-}
-
-static int c_show(struct seq_file *m, void *p)
-{
-	struct crypto_alg *alg = (struct crypto_alg *)p;
-
-	seq_printf(m, "name         : %s\n", alg->cra_name);
-	seq_printf(m, "module       : %s\n",
-		   (alg->cra_module ?
-		    alg->cra_module->name :
-		    "kernel"));
-
-	switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
-	case CRYPTO_ALG_TYPE_CIPHER:
-		seq_printf(m, "type         : cipher\n");
-		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
-		seq_printf(m, "min keysize  : %u\n",
-					alg->cra_cipher.cia_min_keysize);
-		seq_printf(m, "max keysize  : %u\n",
-					alg->cra_cipher.cia_max_keysize);
-		break;
-
-	case CRYPTO_ALG_TYPE_DIGEST:
-		seq_printf(m, "type         : digest\n");
-		seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
-		seq_printf(m, "digestsize   : %u\n",
-		           alg->cra_digest.dia_digestsize);
-		break;
-	case CRYPTO_ALG_TYPE_COMPRESS:
-		seq_printf(m, "type         : compression\n");
-		break;
-	default:
-		seq_printf(m, "type         : unknown\n");
-		break;
-	}
-
-	seq_putc(m, '\n');
-	return 0;
-}
-
-static struct seq_operations crypto_seq_ops = {
-	.start		= c_start,
-	.next		= c_next,
-	.stop		= c_stop,
-	.show		= c_show
-};
-
-static int crypto_info_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &crypto_seq_ops);
-}
-
-static struct file_operations proc_crypto_ops = {
-	.open		= crypto_info_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= seq_release
-};
-
-void __init crypto_init_proc(void)
-{
-	struct proc_dir_entry *proc;
-
-	proc = create_proc_entry("crypto", 0, NULL);
-	if (proc)
-		proc->proc_fops = &proc_crypto_ops;
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
index cc5623a..8d12ffc 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_BAProc.c
@@ -174,49 +174,6 @@ static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, P
 	//return NULL;
 }
 
-#if 0 //I try to merge ADDBA_REQ and ADDBA_RSP frames together..
-/********************************************************************************************************************
- *function:  construct ADDBAREQ frame
- *   input:  u8* 		dst 	//ADDBARsp frame's destination
- *   	     PBA_RECORD 	pBA	//BA_RECORD entry which stores the necessary information for BA_RSP.
- *   	     u16 		StatusCode  //status code.
- *  output:  none
- *  return:  sk_buff* 		skb     //return constructed skb to xmit
-********************************************************************************************************************/
-static struct sk_buff* ieee80211_ADDBA_Rsp( IN	struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode)
-{
-	OCTET_STRING	osADDBAFrame, tmp;
-
-	FillOctetString(osADDBAFrame, Buffer, 0);
-	*pLength = 0;
-
-	ConstructMaFrameHdr(
-					Adapter,
-					Addr,
-					ACT_CAT_BA,
-					ACT_ADDBARSP,
-					&osADDBAFrame	);
-
-	// Dialog Token
-	FillOctetString(tmp, &pBA->DialogToken, 1);
-	PacketAppendData(&osADDBAFrame, tmp);
-
-	// Status Code
-	FillOctetString(tmp, &StatusCode, 2);
-	PacketAppendData(&osADDBAFrame, tmp);
-
-	// BA Parameter Set
-	FillOctetString(tmp, &pBA->BaParamSet, 2);
-	PacketAppendData(&osADDBAFrame, tmp);
-
-	// BA Timeout Value
-	FillOctetString(tmp, &pBA->BaTimeoutValue, 2);
-	PacketAppendData(&osADDBAFrame, tmp);
-
-	*pLength = osADDBAFrame.Length;
-}
-#endif
-
 /********************************************************************************************************************
  *function:  construct DELBA frame
  *   input:  u8* 		dst 	//DELBA frame's destination
@@ -382,7 +339,7 @@ int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb)
 
 	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
 	{
-		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %ld)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
 		return -1;
 	}
 
@@ -483,7 +440,7 @@ int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb)
 
 	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9)
 	{
-		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %ld)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 9));
 		return -1;
 	}
 	rsp = ( struct ieee80211_hdr_3addr*)skb->data;
@@ -613,7 +570,7 @@ int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb)
 
 	if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6)
 	{
-		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %d)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 6));
+		IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %ld)\n", skb->len, 	(sizeof( struct ieee80211_hdr_3addr) + 6));
 		return -1;
 	}
 
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h
index 16a7462..a97c901 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_HT.h
@@ -324,15 +324,6 @@ typedef struct _RT_HIGH_THROUGHPUT{
 	u8				RxReorderPendingTime;
 	u16				RxReorderDropCounter;
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	u8				UsbTxAggrNum;
-#endif
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	u8				UsbRxFwAggrEn;
-	u8				UsbRxFwAggrPageNum;
-	u8				UsbRxFwAggrPacketNum;
-	u8				UsbRxFwAggrTimeout;
-#endif
 
 	// Add for Broadcom(Linksys) IOT. Joseph
 	u8				bIsPeerBcm;
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
index f357085..33c7fa7 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_HTProc.c
@@ -102,24 +102,6 @@ void HTUpdateDefaultSetting(struct ieee80211_device* ieee)
 	pHTInfo->RxReorderWinSize = 64;
 	pHTInfo->RxReorderPendingTime = 30;
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	pHTInfo->UsbTxAggrNum = 4;
-#endif
-#ifdef USB_RX_AGGREGATION_SUPPORT
-#ifdef RTL8192SU
-	pHTInfo->UsbRxFwAggrEn = 1;
-	pHTInfo->UsbRxFwAggrPageNum = 16;
-	pHTInfo->UsbRxFwAggrPacketNum = 8;
-	pHTInfo->UsbRxFwAggrTimeout = 4; ////usb rx FW aggregation timeout threshold.It's in units of 64us
-	// For page size of receive packet buffer.
-	pHTInfo->UsbRxPageSize= 128;
-#else
-	pHTInfo->UsbRxFwAggrEn = 1;
-	pHTInfo->UsbRxFwAggrPageNum = 24;
-	pHTInfo->UsbRxFwAggrPacketNum = 8;
-	pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us
-#endif
-#endif
 
 
 }
@@ -358,11 +340,7 @@ bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee)
 {
 	bool			retValue = false;
 	struct ieee80211_network* net = &ieee->current_network;
-#if 0
-	if(pMgntInfo->bHalfNMode == false)
-		retValue = false;
-	else
-#endif
+
 	if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) ||
 		     (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) ||
 		     (memcmp(net->bssid, PCI_RALINK, 3)==0) ||
@@ -441,24 +419,7 @@ void HTIOTPeerDetermine(struct ieee80211_device* ieee)
 u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr)
 {
 	u8 ret = 0;
-#if 0
-	// Apply for 819u only
-#if (HAL_CODE_BASE==RTL8192 && DEV_BUS_TYPE==USB_INTERFACE)
-	if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
-    		(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)
-	    )
-	{
-		ret = 1;
-	}
-
 
-	if(pHTInfo->bCurrentRT2RTAggregation)
-	{
-		// The parameter of pHTInfo->bCurrentRT2RTAggregation must be decided previously
-		ret = 1;
-	}
-#endif
-#endif
 	return ret;
  }
 
@@ -534,7 +495,6 @@ bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee)
 //#endif
 #endif
 #if 1
-#if (defined(RTL8192SE) || (defined(RTL8192SU)))
        PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
 	if(ieee->is_ap_in_wep_tkip && ieee->is_ap_in_wep_tkip(ieee->dev))
 	{
@@ -544,7 +504,6 @@ bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee)
 			retValue = true;
 	}
 #endif
-#endif
 	return retValue;
 }
 
@@ -561,18 +520,6 @@ u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* 	ieee, u8* PeerMacAddr)
 	// Set specific EDCA parameter for different AP in DM handler.
 
 	return retValue;
-#if 0
-	if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0)||
-		(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)||
-		(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)||
-		(memcmp(PeerMacAddr, NETGEAR834Bv2_BROADCOM, 3)==0))
-
-	{
-		retValue = 1;	//Linksys disable EDCA turbo mode
-	}
-
-	return retValue;
-#endif
 }
 
 /********************************************************************************************************************
@@ -613,7 +560,6 @@ u8 HTIOTActIsForcedRTSCTS(struct ieee80211_device *ieee, struct ieee80211_networ
 	u8	retValue = 0;
 	printk("============>%s(), %d\n", __FUNCTION__, network->realtek_cap_exit);
 	// Force protection
-#if defined(RTL8192SE) || defined(RTL8192SU)
 	if(ieee->pHTInfo->bCurrentHTSupport)
 	{
 		//if(!network->realtek_cap_exit)
@@ -624,7 +570,6 @@ u8 HTIOTActIsForcedRTSCTS(struct ieee80211_device *ieee, struct ieee80211_networ
 				retValue = 1;
 		}
 	}
-#endif
 	return retValue;
 }
 
@@ -639,14 +584,12 @@ HTIOTActIsForcedAMSDU8K(struct ieee80211_device *ieee, struct ieee80211_network
 u8 HTIOTActIsCCDFsync(u8* PeerMacAddr)
 {
 	u8	retValue = 0;
-#ifndef RTL8192SE
 	if(	(memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) ||
 	    	(memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) ||
 	    	(memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0))
 	{
 		retValue = 1;
 	}
-#endif
 	return retValue;
 }
 
@@ -660,7 +603,6 @@ HTIOCActRejcectADDBARequest(struct ieee80211_network *network)
 	//if(IS_HARDWARE_TYPE_8192SE(Adapter) ||
 	//	IS_HARDWARE_TYPE_8192SU(Adapter)
 	//)
-#if (defined RTL8192SE || defined RTL8192SU)
 	{
 		// Do not reject ADDBA REQ because some of the AP may
 		// keep on sending ADDBA REQ qhich cause DHCP fail or ping loss!
@@ -670,7 +612,6 @@ HTIOCActRejcectADDBARequest(struct ieee80211_network *network)
 		//	return FALSE;
 
 	}
-#endif
 
 	return retValue;
 
@@ -684,7 +625,6 @@ HTIOCActRejcectADDBARequest(struct ieee80211_network *network)
 {
 	u8	retValue = 0;
 	//if(IS_HARDWARE_TYPE_8192SU(Adapter))
-#ifdef RTL8192SU
 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
 	{
 //#if UNDER_VISTA
@@ -698,7 +638,6 @@ HTIOCActRejcectADDBARequest(struct ieee80211_network *network)
 			return 1;
 
 	}
-#endif
 	return retValue;
 }
 
@@ -753,7 +692,6 @@ HTIOTActIsDisableTx40MHz(struct ieee80211_device* ieee,struct ieee80211_network
 {
 	u8	retValue = 0;
 
-#if (defined RTL8192SU || defined RTL8192SE)
 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
 	if(	(KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
 		(KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
@@ -764,7 +702,6 @@ HTIOTActIsDisableTx40MHz(struct ieee80211_device* ieee,struct ieee80211_network
 		if((pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK) && (network->bssht.bdSupportHT))
 			retValue = 1;
 	}
-#endif
 
 	return retValue;
 }
@@ -774,7 +711,6 @@ HTIOTActIsTxNoAggregation(struct ieee80211_device* ieee,struct ieee80211_network
 {
 	u8 retValue = 0;
 
-#if (defined RTL8192SU || defined RTL8192SE)
 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
 	if(	(KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
 		(KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
@@ -786,7 +722,6 @@ HTIOTActIsTxNoAggregation(struct ieee80211_device* ieee,struct ieee80211_network
 		    pHTInfo->IOTPeer==HT_IOT_PEER_UNKNOWN)
 			retValue = 1;
 	}
-#endif
 
 	return retValue;
 }
@@ -797,7 +732,6 @@ HTIOTActIsDisableTx2SS(struct ieee80211_device* ieee,struct ieee80211_network *n
 {
 	u8	retValue = 0;
 
-#if (defined RTL8192SU || defined RTL8192SE)
 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
 	if(	(KEY_TYPE_WEP104 == ieee->pairwise_key_type) ||
 		(KEY_TYPE_WEP40 == ieee->pairwise_key_type) ||
@@ -808,7 +742,6 @@ HTIOTActIsDisableTx2SS(struct ieee80211_device* ieee,struct ieee80211_network *n
 		if((pHTInfo->IOTPeer==HT_IOT_PEER_REALTEK) && (network->bssht.bdSupportHT))
 			retValue = 1;
 	}
-#endif
 
 	return retValue;
 }
@@ -817,14 +750,12 @@ HTIOTActIsDisableTx2SS(struct ieee80211_device* ieee,struct ieee80211_network *n
 bool HTIOCActAllowPeerAggOnePacket(struct ieee80211_device* ieee,struct ieee80211_network *network)
 {
 	bool 	retValue = false;
-#if defined(RTL8192SE) || defined(RTL8192SU)
 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
 	{
 		if(pHTInfo->IOTPeer == HT_IOT_PEER_MARVELL)
 			return true;
 
 	}
-#endif
 	return retValue;
 }
 
@@ -1239,17 +1170,7 @@ u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperate
 	return true;
 }
 void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET	Offset);
-#if 0
-//I need move this function to other places, such as rx?
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void HTOnAssocRsp_wq(struct work_struct *work)
-{
-	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ht_onAssRsp);
-#else
-void HTOnAssocRsp_wq(struct ieee80211_device *ieee)
-{
-#endif
-#endif
+
 void HTOnAssocRsp(struct ieee80211_device *ieee)
 {
 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
@@ -1356,10 +1277,6 @@ void HTOnAssocRsp(struct ieee80211_device *ieee)
 	{
 		// Set MPDU density to 2 to Realtek AP, and set it to 0 for others
 		// Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily
-#if 0
-		osTmp= PacketGetElement( asocpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE);
-		if(osTmp.Length >= 5)	//00:e0:4c:02:00
-#endif
 		if (ieee->current_network.bssht.bdRT2RTAggregation)
 		{
 			if( ieee->pairwise_key_type != KEY_TYPE_NA)
@@ -1539,187 +1456,7 @@ void HTInitializeBssDesc(PBSS_HT pBssHT)
 	pBssHT->bdRT2RTLongSlotTime = false;
 	pBssHT->RT2RT_HT_Mode = (RT_HT_CAPBILITY)0;
 }
-#if 0
-//below function has merged into ieee80211_network_init() in ieee80211_rx.c
-void
-HTParsingHTCapElement(
-	IN	PADAPTER		Adapter,
-	IN	OCTET_STRING	HTCapIE,
-	OUT	PRT_WLAN_BSS	pBssDesc
-)
-{
-	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
-
-	if( HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf) )
-	{
-		RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTCapElement(): HT Capability Element length is too long!\n") );
-		return;
-	}
 
-	// TODO: Check the correctness of HT Cap
-	//Print each field in detail. Driver should not print out this message by default
-	if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc)
-		HTDebugHTCapability(DBG_TRACE, Adapter, &HTCapIE, (pu8)"HTParsingHTCapElement()");
-
-	HTCapIE.Length = HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf)?\
-		sizeof(pBssDesc->BssHT.bdHTCapBuf):HTCapIE.Length;	//prevent from overflow
-
-	CopyMem(pBssDesc->BssHT.bdHTCapBuf, HTCapIE.Octet, HTCapIE.Length);
-	pBssDesc->BssHT.bdHTCapLen = HTCapIE.Length;
-
-}
-
-
-void
-HTParsingHTInfoElement(
-	PADAPTER		Adapter,
-	OCTET_STRING	HTInfoIE,
-	PRT_WLAN_BSS	pBssDesc
-)
-{
-	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
-
-	if( HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf))
-	{
-		RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTInfoElement(): HT Information Element length is too long!\n") );
-		return;
-	}
-
-	// TODO: Check the correctness of HT Info
-	//Print each field in detail. Driver should not print out this message by default
-	if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc)
-		HTDebugHTInfo(DBG_TRACE, Adapter, &HTInfoIE, (pu8)"HTParsingHTInfoElement()");
-
-	HTInfoIE.Length = HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)?\
-		sizeof(pBssDesc->BssHT.bdHTInfoBuf):HTInfoIE.Length;	//prevent from overflow
-
-	CopyMem( pBssDesc->BssHT.bdHTInfoBuf, HTInfoIE.Octet, HTInfoIE.Length);
-	pBssDesc->BssHT.bdHTInfoLen = HTInfoIE.Length;
-}
-
-/*
-  * Get HT related information from beacon and save it in BssDesc
-  *
-  * (1) Parse HTCap, and HTInfo, and record whether it is 11n AP
-  * (2) If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
-  * (3) Check whether peer is Realtek AP (for Realtek proprietary aggregation mode).
-  * Input:
-  * 		PADAPTER	Adapter
-  *
-  * Output:
-  *		PRT_TCB		BssDesc
-  *
-*/
-void HTGetValueFromBeaconOrProbeRsp(
-	PADAPTER			Adapter,
-	POCTET_STRING		pSRCmmpdu,
-	PRT_WLAN_BSS		bssDesc
-)
-{
-	PMGNT_INFO      			pMgntInfo = &Adapter->MgntInfo;
-	PRT_HIGH_THROUGHPUT		pHTInfo = GET_HT_INFO(pMgntInfo);
-	OCTET_STRING				HTCapIE, HTInfoIE, HTRealtekAgg, mmpdu;
-	OCTET_STRING				BroadcomElement, CiscoElement;
-
-	mmpdu.Octet = pSRCmmpdu->Octet;
-	mmpdu.Length = pSRCmmpdu->Length;
-
-	//2Note:
-	//   Mark for IOT testing using  Linksys WRT350N, This AP does not contain WMM IE  when
-	//   it is configured at pure-N mode.
-	//	if(bssDesc->BssQos.bdQoSMode & QOS_WMM)
-	//
-
-	HTInitializeBssDesc (&bssDesc->BssHT);
-
-	//2<1> Parse HTCap, and HTInfo
-	// Get HT Capability IE: (1) Get IEEE Draft N IE or (2) Get EWC IE
-	HTCapIE = PacketGetElement(mmpdu, EID_HTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE);
-	if(HTCapIE.Length == 0)
-	{
-		HTCapIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_CAP, OUI_SUBTYPE_DONT_CARE);
-		if(HTCapIE.Length != 0)
-			bssDesc->BssHT.bdHTSpecVer= HT_SPEC_VER_EWC;
-	}
-	if(HTCapIE.Length != 0)
-		HTParsingHTCapElement(Adapter, HTCapIE, bssDesc);
-
-	// Get HT Information IE: (1) Get IEEE Draft N IE or (2) Get EWC IE
-	HTInfoIE = PacketGetElement(mmpdu, EID_HTInfo, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE);
-	if(HTInfoIE.Length == 0)
-	{
-		HTInfoIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_INFO, OUI_SUBTYPE_DONT_CARE);
-		if(HTInfoIE.Length != 0)
-				bssDesc->BssHT.bdHTSpecVer  = HT_SPEC_VER_EWC;
-	}
-	if(HTInfoIE.Length != 0)
-		HTParsingHTInfoElement(Adapter, HTInfoIE, bssDesc);
-
-	//2<2>If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT()
-	if(HTCapIE.Length != 0)
-	{
-		bssDesc->BssHT.bdSupportHT = true;
-		if(bssDesc->BssQos.bdQoSMode == QOS_DISABLE)
-			QosSetLegacyWMMParamWithHT(Adapter, bssDesc);
-	}
-	else
-	{
-		bssDesc->BssHT.bdSupportHT = false;
-	}
-
-	//2<3>Check whether the peer is Realtek AP/STA
-	if(pHTInfo->bRegRT2RTAggregation)
-	{
-		if(bssDesc->BssHT.bdSupportHT)
-		{
-			HTRealtekAgg = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE);
-			if(HTRealtekAgg.Length >=5 )
-			{
-				bssDesc->BssHT.bdRT2RTAggregation = true;
-
-				if((HTRealtekAgg.Octet[4]==1) && (HTRealtekAgg.Octet[5] & 0x02))
-					bssDesc->BssHT.bdRT2RTLongSlotTime = true;
-			}
-		}
-	}
-
-	//
-	// 2008/01/25 MH Get Broadcom AP IE for manamgent frame CCK rate problem.
-	// AP can not receive CCK managemtn from from 92E.
-	//
-
-	// Initialize every new bss broadcom cap exist as false..
-	bssDesc->bBroadcomCapExist= false;
-
-	if(HTCapIE.Length != 0 || HTInfoIE.Length != 0)
-	{
-		u4Byte	Length = 0;
-
-		FillOctetString(BroadcomElement, NULL, 0);
-
-		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_1, OUI_SUBTYPE_DONT_CARE);
-		Length += BroadcomElement.Length;
-		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_2, OUI_SUBTYPE_DONT_CARE);
-		Length += BroadcomElement.Length;
-		BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_3, OUI_SUBTYPE_DONT_CARE);
-		Length += BroadcomElement.Length;
-
-		if(Length > 0)
-			bssDesc->bBroadcomCapExist = true;
-	}
-
-
-	// For Cisco IOT issue
-	CiscoElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_CISCO_IE, OUI_SUBTYPE_DONT_CARE);
-	if(CiscoElement.Length != 0){ // 3: 0x00, 0x40, 0x96 ....
-		bssDesc->bCiscoCapExist = true;
-	}else{
-		bssDesc->bCiscoCapExist = false;
-	}
-}
-
-
-#endif
 /********************************************************************************************************************
  *function:  initialize Bss HT structure(struct PBSS_HT)
  *   input:  struct ieee80211_device 	*ieee
@@ -1808,11 +1545,9 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80
 		//if(bIOTAction)
 		//	pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_RTS;
 
-#if defined(RTL8192SU)
 		bIOTAction = HTIOCActRejcectADDBARequest(pNetwork);
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_REJECT_ADDBA_REQ;
-#endif
 
 		bIOTAction = HTIOCActAllowPeerAggOnePacket(ieee, pNetwork);
 		if(bIOTAction)
@@ -1822,7 +1557,6 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_EDCA_BIAS_ON_RX;
 
-#if defined(RTL8192SU)
 		bIOTAction = HTIOTActDisableShortGI(ieee, pNetwork);
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_SHORT_GI;
@@ -1830,13 +1564,11 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80
 		bIOTAction = HTIOTActDisableHighPower(ieee, pNetwork);
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_HIGH_POWER;
-#endif
 
 		bIOTAction = HTIOTActIsForcedAMSDU8K(ieee, pNetwork);
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_TX_USE_AMSDU_8K;
 
-#if defined(RTL8192SU)
 		bIOTAction = HTIOTActIsTxNoAggregation(ieee, pNetwork);
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_TX_NO_AGGREGATION;
@@ -1848,7 +1580,6 @@ void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, 	struct ieee80
 		bIOTAction = HTIOTActIsDisableTx2SS(ieee, pNetwork);
 		if(bIOTAction)
 			pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_TX_2SS;
-#endif
 		//must after HT_IOT_ACT_TX_NO_AGGREGATION
 		bIOTAction = HTIOTActIsForcedRTSCTS(ieee, pNetwork);
 		if(bIOTAction)
@@ -2029,9 +1760,3 @@ void HTSetConnectBwModeCallback(struct ieee80211_device* ieee)
 
 	pHTInfo->bSwBwInProgress = false;
 }
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-EXPORT_SYMBOL_NOVERS(HTUpdateSelfAndPeerSetting);
-#else
-EXPORT_SYMBOL(HTUpdateSelfAndPeerSetting);
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h
index f7b882b..7aa9a77 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_Qos.h
@@ -70,147 +70,6 @@ typedef	enum _ACK_POLICY{
 }ACK_POLICY,*PACK_POLICY;
 
 #define WMM_PARAM_ELEMENT_SIZE	(8+(4*AC_PARAM_SIZE))
-#if 0
-#define GET_QOS_CTRL(_pStart)	ReadEF2Byte((u8 *)(_pStart) + 24)
-#define SET_QOS_CTRL(_pStart, _value)	WriteEF2Byte((u8 *)(_pStart) + 24, _value)
-
-// WMM control field.
-#define GET_QOS_CTRL_WMM_UP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 3))
-#define SET_QOS_CTRL_WMM_UP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 3, (u8)(_value))
-
-#define GET_QOS_CTRL_WMM_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
-#define SET_QOS_CTRL_WMM_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
-
-#define GET_QOS_CTRL_WMM_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
-#define SET_QOS_CTRL_WMM_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
-
-// 802.11e control field (by STA, data)
-#define GET_QOS_CTRL_STA_DATA_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
-#define SET_QOS_CTRL_STA_DATA_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
-
-#define GET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
-#define SET_QOS_CTRL_STA_DATA_QSIZE_FLAG(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
-
-#define GET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
-#define SET_QOS_CTRL_STA_DATA_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
-
-#define GET_QOS_CTRL_STA_DATA_TXOP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
-#define SET_QOS_CTRL_STA_DATA_TXOP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
-
-#define GET_QOS_CTRL_STA_DATA_QSIZE(_pStart)	GET_QOS_CTRL_STA_DATA_TXOP(_pStart)
-#define SET_QOS_CTRL_STA_DATA_QSIZE(_pStart, _value)	SET_QOS_CTRL_STA_DATA_TXOP(_pStart)
-
-// 802.11e control field (by HC, data)
-#define GET_QOS_CTRL_HC_DATA_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
-#define SET_QOS_CTRL_HC_DATA_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
-
-#define GET_QOS_CTRL_HC_DATA_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
-#define SET_QOS_CTRL_HC_DATA_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
-
-#define GET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
-#define SET_QOS_CTRL_HC_DATA_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
-
-#define GET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
-#define SET_QOS_CTRL_HC_DATA_PS_BUFSTATE(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
-
-// 802.11e control field (by HC, CFP)
-#define GET_QOS_CTRL_HC_CFP_TID(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 0, 4))
-#define SET_QOS_CTRL_HC_CFP_TID(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 0, 4, (u8)(_value))
-
-#define GET_QOS_CTRL_HC_CFP_EOSP(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 4, 1))
-#define SET_QOS_CTRL_HC_CFP_EOSP(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 4, 1, (u8)(_value))
-
-#define GET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 5, 2))
-#define SET_QOS_CTRL_HC_CFP_ACK_POLICY(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 5, 2, (u8)(_value))
-
-#define GET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart)	((u8)LE_BITS_TO_2BYTE((u8 *)(_pStart)+24, 8, 8))
-#define SET_QOS_CTRL_HC_CFP_TXOP_LIMIT(_pStart, _value)	SET_BITS_TO_LE_2BYTE((u8 *)(_pStart)+24, 8, 8, (u8)(_value))
-
-#define SET_WMM_QOS_INFO_FIELD(_pStart, _val)	WriteEF1Byte(_pStart, _val)
-
-#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart)	LE_BITS_TO_1BYTE(_pStart, 0, 4)
-#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val)
-
-#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 7, 1)
-#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val)
-
-#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 0, 1)
-#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val)
-
-#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 1, 1)
-#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val)
-
-#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 2, 1)
-#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val)
-
-#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart)	LE_BITS_TO_1BYTE(_pStart, 3, 1)
-#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val)
-
-#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart)	LE_BITS_TO_1BYTE(_pStart, 5, 2)
-#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val)	SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val)
-
-
-#define WMM_INFO_ELEMENT_SIZE	7
-
-#define GET_WMM_INFO_ELE_OUI(_pStart)	((u8 *)(_pStart))
-#define SET_WMM_INFO_ELE_OUI(_pStart, _pVal)	PlatformMoveMemory(_pStart, _pVal, 3);
-
-#define GET_WMM_INFO_ELE_OUI_TYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+3) ) )
-#define SET_WMM_INFO_ELE_OUI_TYPE(_pStart, _val)	( *((u8 *)(_pStart)+3) = EF1Byte(_val) )
-
-#define GET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+4) ) )
-#define SET_WMM_INFO_ELE_OUI_SUBTYPE(_pStart, _val)	( *((u8 *)(_pStart)+4) = EF1Byte(_val) )
-
-#define GET_WMM_INFO_ELE_VERSION(_pStart)	( EF1Byte( *((u8 *)(_pStart)+5) ) )
-#define SET_WMM_INFO_ELE_VERSION(_pStart, _val)	( *((u8 *)(_pStart)+5) = EF1Byte(_val) )
-
-#define GET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart)	( EF1Byte( *((u8 *)(_pStart)+6) ) )
-#define SET_WMM_INFO_ELE_QOS_INFO_FIELD(_pStart, _val)	( *((u8 *)(_pStart)+6) = EF1Byte(_val) )
-
-
-
-#define GET_WMM_AC_PARAM_AIFSN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 4) )
-#define SET_WMM_AC_PARAM_AIFSN(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 0, 4, _val)
-
-#define GET_WMM_AC_PARAM_ACM(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 4, 1) )
-#define SET_WMM_AC_PARAM_ACM(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 4, 1, _val)
-
-#define GET_WMM_AC_PARAM_ACI(_pStart)		( (u8)LE_BITS_TO_4BYTE(_pStart, 5, 2) )
-#define SET_WMM_AC_PARAM_ACI(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 5, 2, _val)
-
-#define GET_WMM_AC_PARAM_ACI_AIFSN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 0, 8) )
-#define SET_WMM_AC_PARAM_ACI_AIFSN(_pStart, _val)	SET_BTIS_TO_LE_4BYTE(_pStart, 0, 8, _val)
-
-#define GET_WMM_AC_PARAM_ECWMIN(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 8, 4) )
-#define SET_WMM_AC_PARAM_ECWMIN(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 8, 4, _val)
-
-#define GET_WMM_AC_PARAM_ECWMAX(_pStart)	( (u8)LE_BITS_TO_4BYTE(_pStart, 12, 4) )
-#define SET_WMM_AC_PARAM_ECWMAX(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 12, 4, _val)
-
-#define GET_WMM_AC_PARAM_TXOP_LIMIT(_pStart)		( (u16)LE_BITS_TO_4BYTE(_pStart, 16, 16) )
-#define SET_WMM_AC_PARAM_TXOP_LIMIT(_pStart, _val)	SET_BITS_TO_LE_4BYTE(_pStart, 16, 16, _val)
-
-
-
-
-#define GET_WMM_PARAM_ELE_OUI(_pStart)	((u8 *)(_pStart))
-#define SET_WMM_PARAM_ELE_OUI(_pStart, _pVal)	PlatformMoveMemory(_pStart, _pVal, 3)
-
-#define GET_WMM_PARAM_ELE_OUI_TYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+3) ) )
-#define SET_WMM_PARAM_ELE_OUI_TYPE(_pStart, _val)	( *((u8 *)(_pStart)+3) = EF1Byte(_val) )
-
-#define GET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart)	( EF1Byte( *((u8 *)(_pStart)+4) ) )
-#define SET_WMM_PARAM_ELE_OUI_SUBTYPE(_pStart, _val)	( *((u8 *)(_pStart)+4) = EF1Byte(_val) )
-
-#define GET_WMM_PARAM_ELE_VERSION(_pStart)	( EF1Byte( *((u8 *)(_pStart)+5) ) )
-#define SET_WMM_PARAM_ELE_VERSION(_pStart, _val)	( *((u8 *)(_pStart)+5) = EF1Byte(_val) )
-
-#define GET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart)	( EF1Byte( *((u8 *)(_pStart)+6) ) )
-#define SET_WMM_PARAM_ELE_QOS_INFO_FIELD(_pStart, _val)	( *((u8 *)(_pStart)+6) = EF1Byte(_val) )
-
-#define GET_WMM_PARAM_ELE_AC_PARAM(_pStart)	( (u8 *)(_pStart)+8 )
-#define SET_WMM_PARAM_ELE_AC_PARAM(_pStart, _pVal) PlatformMoveMemory((_pStart)+8, _pVal, 16)
-#endif
 
 //
 // QoS Control Field
@@ -361,22 +220,6 @@ typedef	union _QOS_INFO_FIELD{
 
 }QOS_INFO_FIELD, *PQOS_INFO_FIELD;
 
-#if 0
-//
-// WMM Information Element
-// Ref: WMM spec 2.2.1: WME Information Element, p.10.
-//
-typedef struct _WMM_INFO_ELEMENT{
-//	u8			ElementID;
-//	u8			Length;
-	u8			OUI[3];
-	u8			OUI_Type;
-	u8			OUI_SubType;
-	u8			Version;
-	QOS_INFO_FIELD	QosInfo;
-}WMM_INFO_ELEMENT, *PWMM_INFO_ELEMENT;
-#endif
-
 //
 // ACI to AC coding.
 // Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
@@ -650,16 +493,7 @@ typedef struct _OCTET_STRING{
         u8        	*Octet;
         u16             Length;
 }OCTET_STRING, *POCTET_STRING;
-#if 0
-#define FillOctetString(_os,_octet,_len)             \
-        (_os).Octet=(u8 *)(_octet);                  \
-        (_os).Length=(_len);
-
-#define WMM_ELEM_HDR_LEN        		     6
-#define WMMElemSkipHdr(_osWMMElem)                   \
-        (_osWMMElem).Octet += WMM_ELEM_HDR_LEN;      \
-        (_osWMMElem).Length -= WMM_ELEM_HDR_LEN;
-#endif
+
 //
 // STA QoS data.
 // Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h]
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
index 6fb7033..ad3bf35 100644
--- a/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
+++ b/drivers/staging/rtl8192su/ieee80211/rtl819x_TSProc.c
@@ -2,13 +2,6 @@
 #include <linux/etherdevice.h>
 #include "rtl819x_TS.h"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#define list_for_each_entry_safe(pos, n, head, member) \
-	for (pos = list_entry((head)->next, typeof(*pos), member), \
-		n = list_entry(pos->member.next, typeof(*pos), member); \
-		&pos->member != (head); \
-		pos = n, n = list_entry(n->member.next, typeof(*n), member))
-#endif
 void TsSetupTimeOut(unsigned long data)
 {
 	// Not implement yet
@@ -96,21 +89,7 @@ void RxPktPendingTimeout(unsigned long data)
 	if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff))
 	{
 		pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq;
-#if 0
-		if(timer_pending(&pTS->RxPktPendingTimer))
-			del_timer_sync(&pTS->RxPktPendingTimer);
-		pTS->RxPktPendingTimer.expires = jiffies + MSECS(pHTInfo->RxReorderPendingTime);
-		add_timer(&pTS->RxPktPendingTimer);
-#else
 		mod_timer(&pRxTs->RxPktPendingTimer,  jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime));
-#endif
-
-#if 0
-		if(timer_pending(&pRxTs->RxPktPendingTimer))
-			del_timer_sync(&pRxTs->RxPktPendingTimer);
-		pRxTs->RxPktPendingTimer.expires = jiffies + ieee->pHTInfo->RxReorderPendingTime;
-		add_timer(&pRxTs->RxPktPendingTimer);
-#endif
 	}
 	spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags);
 	//PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
@@ -379,17 +358,11 @@ bool GetTs(
 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n");
 		return false;
 	}
-#if 0
-	if(ieee->pStaQos->CurrentQosMode == QOS_DISABLE)
-	{	UP = 0; } //only use one TS
-	else if(ieee->pStaQos->CurrentQosMode & QOS_WMM)
-	{
-#else
+
 	if (ieee->current_network.qos_data.supported == 0)
 		UP = 0;
 	else
 	{
-#endif
 		// In WMM case: we use 4 TID only
 		if (!IsACValid(TID))
 		{
@@ -660,8 +633,3 @@ void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD	pTxTS)
 	else
 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__);
 }
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-EXPORT_SYMBOL_NOVERS(RemovePeerTS);
-#else
-EXPORT_SYMBOL(RemovePeerTS);
-#endif
diff --git a/drivers/staging/rtl8192su/ieee80211/rtl_crypto.h b/drivers/staging/rtl8192su/ieee80211/rtl_crypto.h
deleted file mode 100644
index ccf6ae7..0000000
--- a/drivers/staging/rtl8192su/ieee80211/rtl_crypto.h
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Scatterlist Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- * Copyright (c) 2002 David S. Miller (davem@redhat.com)
- *
- * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Mé°ˆler.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the 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 _LINUX_CRYPTO_H
-#define _LINUX_CRYPTO_H
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/string.h>
-#include <asm/page.h>
-#include <asm/errno.h>
-
-#define crypto_register_alg crypto_register_alg_rsl
-#define crypto_unregister_alg crypto_unregister_alg_rsl
-#define crypto_alloc_tfm crypto_alloc_tfm_rsl
-#define crypto_free_tfm crypto_free_tfm_rsl
-#define crypto_alg_available crypto_alg_available_rsl
-
-/*
- * Algorithm masks and types.
- */
-#define CRYPTO_ALG_TYPE_MASK		0x000000ff
-#define CRYPTO_ALG_TYPE_CIPHER		0x00000001
-#define CRYPTO_ALG_TYPE_DIGEST		0x00000002
-#define CRYPTO_ALG_TYPE_COMPRESS	0x00000004
-
-/*
- * Transform masks and values (for crt_flags).
- */
-#define CRYPTO_TFM_MODE_MASK		0x000000ff
-#define CRYPTO_TFM_REQ_MASK		0x000fff00
-#define CRYPTO_TFM_RES_MASK		0xfff00000
-
-#define CRYPTO_TFM_MODE_ECB		0x00000001
-#define CRYPTO_TFM_MODE_CBC		0x00000002
-#define CRYPTO_TFM_MODE_CFB		0x00000004
-#define CRYPTO_TFM_MODE_CTR		0x00000008
-
-#define CRYPTO_TFM_REQ_WEAK_KEY		0x00000100
-#define CRYPTO_TFM_RES_WEAK_KEY		0x00100000
-#define CRYPTO_TFM_RES_BAD_KEY_LEN   	0x00200000
-#define CRYPTO_TFM_RES_BAD_KEY_SCHED 	0x00400000
-#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 	0x00800000
-#define CRYPTO_TFM_RES_BAD_FLAGS 	0x01000000
-
-/*
- * Miscellaneous stuff.
- */
-#define CRYPTO_UNSPEC			0
-#define CRYPTO_MAX_ALG_NAME		64
-
-struct scatterlist;
-
-/*
- * Algorithms: modular crypto algorithm implementations, managed
- * via crypto_register_alg() and crypto_unregister_alg().
- */
-struct cipher_alg {
-	unsigned int cia_min_keysize;
-	unsigned int cia_max_keysize;
-	int (*cia_setkey)(void *ctx, const u8 *key,
-	                  unsigned int keylen, u32 *flags);
-	void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
-	void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
-};
-
-struct digest_alg {
-	unsigned int dia_digestsize;
-	void (*dia_init)(void *ctx);
-	void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
-	void (*dia_final)(void *ctx, u8 *out);
-	int (*dia_setkey)(void *ctx, const u8 *key,
-	                  unsigned int keylen, u32 *flags);
-};
-
-struct compress_alg {
-	int (*coa_init)(void *ctx);
-	void (*coa_exit)(void *ctx);
-	int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
-	                    u8 *dst, unsigned int *dlen);
-	int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
-	                      u8 *dst, unsigned int *dlen);
-};
-
-#define cra_cipher	cra_u.cipher
-#define cra_digest	cra_u.digest
-#define cra_compress	cra_u.compress
-
-struct crypto_alg {
-	struct list_head cra_list;
-	u32 cra_flags;
-	unsigned int cra_blocksize;
-	unsigned int cra_ctxsize;
-	const char cra_name[CRYPTO_MAX_ALG_NAME];
-
-	union {
-		struct cipher_alg cipher;
-		struct digest_alg digest;
-		struct compress_alg compress;
-	} cra_u;
-
-	struct module *cra_module;
-};
-
-/*
- * Algorithm registration interface.
- */
-int crypto_register_alg(struct crypto_alg *alg);
-int crypto_unregister_alg(struct crypto_alg *alg);
-
-/*
- * Algorithm query interface.
- */
-int crypto_alg_available(const char *name, u32 flags);
-
-/*
- * Transforms: user-instantiated objects which encapsulate algorithms
- * and core processing logic.  Managed via crypto_alloc_tfm() and
- * crypto_free_tfm(), as well as the various helpers below.
- */
-struct crypto_tfm;
-
-struct cipher_tfm {
-	void *cit_iv;
-	unsigned int cit_ivsize;
-	u32 cit_mode;
-	int (*cit_setkey)(struct crypto_tfm *tfm,
-	                  const u8 *key, unsigned int keylen);
-	int (*cit_encrypt)(struct crypto_tfm *tfm,
-			   struct scatterlist *dst,
-			   struct scatterlist *src,
-			   unsigned int nbytes);
-	int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
-	                      struct scatterlist *dst,
-	                      struct scatterlist *src,
-	                      unsigned int nbytes, u8 *iv);
-	int (*cit_decrypt)(struct crypto_tfm *tfm,
-			   struct scatterlist *dst,
-			   struct scatterlist *src,
-			   unsigned int nbytes);
-	int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
-			   struct scatterlist *dst,
-			   struct scatterlist *src,
-			   unsigned int nbytes, u8 *iv);
-	void (*cit_xor_block)(u8 *dst, const u8 *src);
-};
-
-struct digest_tfm {
-	void (*dit_init)(struct crypto_tfm *tfm);
-	void (*dit_update)(struct crypto_tfm *tfm,
-	                   struct scatterlist *sg, unsigned int nsg);
-	void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
-	void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
-	                   unsigned int nsg, u8 *out);
-	int (*dit_setkey)(struct crypto_tfm *tfm,
-	                  const u8 *key, unsigned int keylen);
-#ifdef CONFIG_CRYPTO_HMAC
-	void *dit_hmac_block;
-#endif
-};
-
-struct compress_tfm {
-	int (*cot_compress)(struct crypto_tfm *tfm,
-	                    const u8 *src, unsigned int slen,
-	                    u8 *dst, unsigned int *dlen);
-	int (*cot_decompress)(struct crypto_tfm *tfm,
-	                      const u8 *src, unsigned int slen,
-	                      u8 *dst, unsigned int *dlen);
-};
-
-#define crt_cipher	crt_u.cipher
-#define crt_digest	crt_u.digest
-#define crt_compress	crt_u.compress
-
-struct crypto_tfm {
-
-	u32 crt_flags;
-
-	union {
-		struct cipher_tfm cipher;
-		struct digest_tfm digest;
-		struct compress_tfm compress;
-	} crt_u;
-
-	struct crypto_alg *__crt_alg;
-};
-
-/*
- * Transform user interface.
- */
-
-/*
- * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
- * If that fails and the kernel supports dynamically loadable modules, it
- * will then attempt to load a module of the same name or alias.  A refcount
- * is grabbed on the algorithm which is then associated with the new transform.
- *
- * crypto_free_tfm() frees up the transform and any associated resources,
- * then drops the refcount on the associated algorithm.
- */
-struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
-void crypto_free_tfm(struct crypto_tfm *tfm);
-
-/*
- * Transform helpers which query the underlying algorithm.
- */
-static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
-{
-	return tfm->__crt_alg->cra_name;
-}
-
-static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
-{
-	struct crypto_alg *alg = tfm->__crt_alg;
-
-	if (alg->cra_module)
-		return alg->cra_module->name;
-	else
-		return NULL;
-}
-
-static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
-{
-	return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
-}
-
-static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->__crt_alg->cra_cipher.cia_min_keysize;
-}
-
-static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->__crt_alg->cra_cipher.cia_max_keysize;
-}
-
-static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_ivsize;
-}
-
-static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
-{
-	return tfm->__crt_alg->cra_blocksize;
-}
-
-static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	return tfm->__crt_alg->cra_digest.dia_digestsize;
-}
-
-/*
- * API wrappers.
- */
-static inline void crypto_digest_init(struct crypto_tfm *tfm)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_init(tfm);
-}
-
-static inline void crypto_digest_update(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_update(tfm, sg, nsg);
-}
-
-static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_final(tfm, out);
-}
-
-static inline void crypto_digest_digest(struct crypto_tfm *tfm,
-                                        struct scatterlist *sg,
-                                        unsigned int nsg, u8 *out)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
-}
-
-static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
-                                       const u8 *key, unsigned int keylen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-	if (tfm->crt_digest.dit_setkey == NULL)
-		return -ENOSYS;
-	return tfm->crt_digest.dit_setkey(tfm, key, keylen);
-}
-
-static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
-                                       const u8 *key, unsigned int keylen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
-}
-
-static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *dst,
-                                        struct scatterlist *src,
-                                        unsigned int nbytes)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
-}
-
-static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
-                                           struct scatterlist *dst,
-                                           struct scatterlist *src,
-                                           unsigned int nbytes, u8 *iv)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
-	return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
-}
-
-static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
-                                        struct scatterlist *dst,
-                                        struct scatterlist *src,
-                                        unsigned int nbytes)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
-}
-
-static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
-                                           struct scatterlist *dst,
-                                           struct scatterlist *src,
-                                           unsigned int nbytes, u8 *iv)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
-	return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
-}
-
-static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
-                                        const u8 *src, unsigned int len)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	memcpy(tfm->crt_cipher.cit_iv, src, len);
-}
-
-static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
-                                        u8 *dst, unsigned int len)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
-	memcpy(dst, tfm->crt_cipher.cit_iv, len);
-}
-
-static inline int crypto_comp_compress(struct crypto_tfm *tfm,
-                                       const u8 *src, unsigned int slen,
-                                       u8 *dst, unsigned int *dlen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
-	return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
-}
-
-static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
-                                         const u8 *src, unsigned int slen,
-                                         u8 *dst, unsigned int *dlen)
-{
-	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
-	return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
-}
-
-/*
- * HMAC support.
- */
-#ifdef CONFIG_CRYPTO_HMAC
-void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
-void crypto_hmac_update(struct crypto_tfm *tfm,
-                        struct scatterlist *sg, unsigned int nsg);
-void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
-                       unsigned int *keylen, u8 *out);
-void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
-                 struct scatterlist *sg, unsigned int nsg, u8 *out);
-#endif	/* CONFIG_CRYPTO_HMAC */
-
-#endif	/* _LINUX_CRYPTO_H */
-
diff --git a/drivers/staging/rtl8192su/ieee80211/scatterwalk.c b/drivers/staging/rtl8192su/ieee80211/scatterwalk.c
deleted file mode 100644
index 49f401f..0000000
--- a/drivers/staging/rtl8192su/ieee80211/scatterwalk.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Cipher operations.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *               2002 Adam J. Richter <adam@yggdrasil.com>
- *               2004 Jean-Luc Cooke <jlcooke@certainkey.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 "kmap_types.h"
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/highmem.h>
-#include <asm/scatterlist.h>
-#include "internal.h"
-#include "scatterwalk.h"
-
-enum km_type crypto_km_types[] = {
-	KM_USER0,
-	KM_USER1,
-	KM_SOFTIRQ0,
-	KM_SOFTIRQ1,
-};
-
-void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch)
-{
-	if (nbytes <= walk->len_this_page &&
-	    (((unsigned long)walk->data) & (PAGE_CACHE_SIZE - 1)) + nbytes <=
-	    PAGE_CACHE_SIZE)
-		return walk->data;
-	else
-		return scratch;
-}
-
-static void memcpy_dir(void *buf, void *sgdata, size_t nbytes, int out)
-{
-	if (out)
-		memcpy(sgdata, buf, nbytes);
-	else
-		memcpy(buf, sgdata, nbytes);
-}
-
-void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg)
-{
-	unsigned int rest_of_page;
-
-	walk->sg = sg;
-
-	walk->page = sg->page;
-	walk->len_this_segment = sg->length;
-
-	rest_of_page = PAGE_CACHE_SIZE - (sg->offset & (PAGE_CACHE_SIZE - 1));
-	walk->len_this_page = min(sg->length, rest_of_page);
-	walk->offset = sg->offset;
-}
-
-void scatterwalk_map(struct scatter_walk *walk, int out)
-{
-	walk->data = crypto_kmap(walk->page, out) + walk->offset;
-}
-
-static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
-				 unsigned int more)
-{
-	/* walk->data may be pointing the first byte of the next page;
-	   however, we know we transfered at least one byte.  So,
-	   walk->data - 1 will be a virtual address in the mapped page. */
-
-	if (out)
-		flush_dcache_page(walk->page);
-
-	if (more) {
-		walk->len_this_segment -= walk->len_this_page;
-
-		if (walk->len_this_segment) {
-			walk->page++;
-			walk->len_this_page = min(walk->len_this_segment,
-						  (unsigned)PAGE_CACHE_SIZE);
-			walk->offset = 0;
-		}
-		else
-			scatterwalk_start(walk, sg_next(walk->sg));
-	}
-}
-
-void scatterwalk_done(struct scatter_walk *walk, int out, int more)
-{
-	crypto_kunmap(walk->data, out);
-	if (walk->len_this_page == 0 || !more)
-		scatterwalk_pagedone(walk, out, more);
-}
-
-/*
- * Do not call this unless the total length of all of the fragments
- * has been verified as multiple of the block size.
- */
-int scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
-			   size_t nbytes, int out)
-{
-	if (buf != walk->data) {
-		while (nbytes > walk->len_this_page) {
-			memcpy_dir(buf, walk->data, walk->len_this_page, out);
-			buf += walk->len_this_page;
-			nbytes -= walk->len_this_page;
-
-			crypto_kunmap(walk->data, out);
-			scatterwalk_pagedone(walk, out, 1);
-			scatterwalk_map(walk, out);
-		}
-
-		memcpy_dir(buf, walk->data, nbytes, out);
-	}
-
-	walk->offset += nbytes;
-	walk->len_this_page -= nbytes;
-	walk->len_this_segment -= nbytes;
-	return 0;
-}
diff --git a/drivers/staging/rtl8192su/ieee80211/scatterwalk.h b/drivers/staging/rtl8192su/ieee80211/scatterwalk.h
deleted file mode 100644
index b164465..0000000
--- a/drivers/staging/rtl8192su/ieee80211/scatterwalk.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- * Copyright (c) 2002 Adam J. Richter <adam@yggdrasil.com>
- * Copyright (c) 2004 Jean-Luc Cooke <jlcooke@certainkey.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 _CRYPTO_SCATTERWALK_H
-#define _CRYPTO_SCATTERWALK_H
-#include <linux/mm.h>
-#include <asm/scatterlist.h>
-
-struct scatter_walk {
-	struct scatterlist	*sg;
-	struct page		*page;
-	void			*data;
-	unsigned int		len_this_page;
-	unsigned int		len_this_segment;
-	unsigned int		offset;
-};
-
-/* Define sg_next is an inline routine now in case we want to change
-   scatterlist to a linked list later. */
-static inline struct scatterlist *sg_next(struct scatterlist *sg)
-{
-	return sg + 1;
-}
-
-static inline int scatterwalk_samebuf(struct scatter_walk *walk_in,
-				      struct scatter_walk *walk_out,
-				      void *src_p, void *dst_p)
-{
-	return walk_in->page == walk_out->page &&
-	       walk_in->offset == walk_out->offset &&
-	       walk_in->data == src_p && walk_out->data == dst_p;
-}
-
-void *scatterwalk_whichbuf(struct scatter_walk *walk, unsigned int nbytes, void *scratch);
-void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
-int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out);
-void scatterwalk_map(struct scatter_walk *walk, int out);
-void scatterwalk_done(struct scatter_walk *walk, int out, int more);
-
-#endif  /* _CRYPTO_SCATTERWALK_H */
diff --git a/drivers/staging/rtl8192su/ieee80211_crypt.h b/drivers/staging/rtl8192su/ieee80211_crypt.h
deleted file mode 100644
index b58a3bc..0000000
--- a/drivers/staging/rtl8192su/ieee80211_crypt.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation. See README and COPYING for
- * more details.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
-	const char *name;
-
-	/* init new crypto context (e.g., allocate private data space,
-	 * select IV, etc.); returns NULL on failure or pointer to allocated
-	 * private data on success */
-	void * (*init)(int keyidx);
-
-	/* deinitialize crypto context and free allocated private data */
-	void (*deinit)(void *priv);
-
-	/* encrypt/decrypt return < 0 on error or >= 0 on success. The return
-	 * value from decrypt_mpdu is passed as the keyidx value for
-	 * decrypt_msdu. skb must have enough head and tail room for the
-	 * encryption; if not, error will be returned; these functions are
-	 * called for all MPDUs (i.e., fragments).
-	 */
-	int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
-	/* These functions are called for full MSDUs, i.e. full frames.
-	 * These can be NULL if full MSDU operations are not needed. */
-	int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
-	int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
-			    void *priv);
-
-	int (*set_key)(void *key, int len, u8 *seq, void *priv);
-	int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
-	/* procfs handler for printing out key information and possible
-	 * statistics */
-	char * (*print_stats)(char *p, void *priv);
-
-	/* maximum number of bytes added by encryption; encrypt buf is
-	 * allocated with extra_prefix_len bytes, copy of in_buf, and
-	 * extra_postfix_len; encrypt need not use all this space, but
-	 * the result must start at the beginning of the buffer and correct
-	 * length must be returned */
-	int extra_prefix_len, extra_postfix_len;
-
-	struct module *owner;
-};
-
-struct ieee80211_crypt_data {
-	struct list_head list; /* delayed deletion list */
-	struct ieee80211_crypto_ops *ops;
-	void *priv;
-	atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
-				    struct ieee80211_crypt_data **crypt);
-
-#endif
diff --git a/drivers/staging/rtl8192su/r8180_93cx6.h b/drivers/staging/rtl8192su/r8180_93cx6.h
index ca228d3..0309800 100644
--- a/drivers/staging/rtl8192su/r8180_93cx6.h
+++ b/drivers/staging/rtl8192su/r8180_93cx6.h
@@ -13,13 +13,8 @@
 /*This files contains card eeprom (93c46 or 93c56) programming routines*/
 /*memory is addressed by WORDS*/
 
-#ifdef RTL8192SU
 #include "r8192U.h"
 #include "r8192S_hw.h"
-#else
-#include "r8192U.h"
-#include "r8192U_hw.h"
-#endif
 
 #define EPROM_DELAY 10
 
diff --git a/drivers/staging/rtl8192su/r8190_rtl8256.c b/drivers/staging/rtl8192su/r8190_rtl8256.c
deleted file mode 100644
index 74ff337..0000000
--- a/drivers/staging/rtl8192su/r8190_rtl8256.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
-  This is part of the rtl8192 driver
-  released under the GPL (See file COPYING for details).
-
-  This files contains programming code for the rtl8256
-  radio frontend.
-
-  *Many* thanks to Realtek Corp. for their great support!
-
-*/
-
-#include "r8192U.h"
-#include "r8192U_hw.h"
-#include "r819xU_phyreg.h"
-#include "r819xU_phy.h"
-#include "r8190_rtl8256.h"
-
-/*--------------------------------------------------------------------------
- * Overview:   	set RF band width (20M or 40M)
- * Input:       struct net_device*	dev
- * 		WIRELESS_BANDWIDTH_E	Bandwidth	//20M or 40M
- * Output:      NONE
- * Return:      NONE
- * Note:	8226 support both 20M  and 40 MHz
- *---------------------------------------------------------------------------*/
-void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth)	//20M or 40M
-{
-	u8	eRFPath;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
-	for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
-	{
-		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
-				continue;
-
-		switch(Bandwidth)
-		{
-			case HT_CHANNEL_WIDTH_20:
-				if(priv->card_8192_version == VERSION_819xU_A || priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
-				{
-					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba
-					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
-					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
-
-					//cosa add for sd3's request 01/23/2008
-					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
-				}
-				else
-				{
-					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
-				}
-
-				break;
-			case HT_CHANNEL_WIDTH_20_40:
-				if(priv->card_8192_version == VERSION_819xU_A ||priv->card_8192_version == VERSION_819xU_B)// 8256 D-cut, E-cut, xiong: consider it later!
-				{
-					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba
-					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3df);
-					rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0a1);
-
-					//cosa add for sd3's request 01/23/2008
-					if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes
-						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b);
-					else
-						rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
-				}
-				else
-				{
-					RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
-				}
-
-
-				break;
-			default:
-				RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
-				break;
-
-		}
-	}
-	return;
-}
-/*--------------------------------------------------------------------------
- * Overview:    Interface to config 8256
- * Input:       struct net_device*	dev
- * Output:      NONE
- * Return:      NONE
- *---------------------------------------------------------------------------*/
-void PHY_RF8256_Config(struct net_device* dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	// Initialize general global value
-	//
-	// TODO: Extend RF_PATH_C and RF_PATH_D in the future
-	priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
-	// Config BB and RF
-	phy_RF8256_Config_ParaFile(dev);
-
-	return;
-}
-/*--------------------------------------------------------------------------
- * Overview:    Interface to config 8256
- * Input:       struct net_device*	dev
- * Output:      NONE
- * Return:      NONE
- *---------------------------------------------------------------------------*/
-void phy_RF8256_Config_ParaFile(struct net_device* dev)
-{
-	u32 	u4RegValue = 0;
-	//static s1Byte				szRadioAFile[] = RTL819X_PHY_RADIO_A;
-	//static s1Byte				szRadioBFile[] = RTL819X_PHY_RADIO_B;
-	//static s1Byte				szRadioCFile[] = RTL819X_PHY_RADIO_C;
-	//static s1Byte				szRadioDFile[] = RTL819X_PHY_RADIO_D;
-	u8 	eRFPath;
-	BB_REGISTER_DEFINITION_T	*pPhyReg;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32	RegOffSetToBeCheck = 0x3;
-	u32 	RegValueToBeCheck = 0x7f1;
-	u32	RF3_Final_Value = 0;
-	u8	ConstRetryTimes = 5, RetryTimes = 5;
-	u8 ret = 0;
-	//3//-----------------------------------------------------------------
-	//3// <2> Initialize RF
-	//3//-----------------------------------------------------------------
-	for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
-	{
-		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
-				continue;
-
-		pPhyReg = &priv->PHYRegDef[eRFPath];
-
-		// Joseph test for shorten RF config
-	//	pHalData->RfReg0Value[eRFPath] =  rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord);
-
-		/*----Store original RFENV control type----*/
-		switch(eRFPath)
-		{
-		case RF90_PATH_A:
-		case RF90_PATH_C:
-			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
-			break;
-		case RF90_PATH_B :
-		case RF90_PATH_D:
-			u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
-			break;
-		}
-
-		/*----Set RF_ENV enable----*/
-		rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
-
-		/*----Set RF_ENV output high----*/
-		rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
-
-		/* Set bit number of Address and Data for RF register */
-		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); 	// Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258
-		rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);	// Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ???
-
-		rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
-
-		/*----Check RF block (for FPGA platform only)----*/
-		// TODO: this function should be removed on ASIC , Emily 2007.2.2
-		if (rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath))
-		{
-			RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
-			goto phy_RF8256_Config_ParaFile_Fail;
-		}
-
-		RetryTimes = ConstRetryTimes;
-		RF3_Final_Value = 0;
-		/*----Initialize RF fom connfiguration file----*/
-		switch(eRFPath)
-		{
-		case RF90_PATH_A:
-			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
-			{
-				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
-				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
-				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
-				RetryTimes--;
-			}
-			break;
-		case RF90_PATH_B:
-			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
-			{
-				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
-				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
-				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
-				RetryTimes--;
-			}
-			break;
-		case RF90_PATH_C:
-			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
-			{
-				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
-				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
-				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
-				RetryTimes--;
-			}
-			break;
-		case RF90_PATH_D:
-			while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
-			{
-				ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
-				RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
-				RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
-				RetryTimes--;
-			}
-			break;
-		}
-
-		/*----Restore RFENV control type----*/;
-		switch(eRFPath)
-		{
-		case RF90_PATH_A:
-		case RF90_PATH_C:
-			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
-			break;
-		case RF90_PATH_B :
-		case RF90_PATH_D:
-			rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
-			break;
-		}
-
-		if(ret){
-			RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
-			goto phy_RF8256_Config_ParaFile_Fail;
-		}
-
-	}
-
-	RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
-	return ;
-
-phy_RF8256_Config_ParaFile_Fail:
-	RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
-	return ;
-}
-
-
-void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel)
-{
-	u32	TxAGC=0;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	//modified by vivi, 20080109
-	TxAGC = powerlevel;
-
-	if(priv->bDynamicTxLowPower == TRUE ) //cosa 05/22/2008 for scan
-	{
-		if(priv->CustomerID == RT_CID_819x_Netcore)
-			TxAGC = 0x22;
-		else
-		TxAGC += priv->CckPwEnl;
-	}
-
-	if(TxAGC > 0x24)
-		TxAGC = 0x24;
-	rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
-}
-
-
-void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	//Joseph TxPower for 8192 testing
-	u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
-	u8 index = 0;
-	u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
-	u8 byte0, byte1, byte2, byte3;
-
-	powerBase0 = powerlevel + priv->TxPowerDiff;	//OFDM rates
-	powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
-	powerBase1 = powerlevel;							//MCS rates
-	powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
-
-	for(index=0; index<6; index++)
-	{
-		writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
-		byte0 = (u8)(writeVal & 0x7f);
-		byte1 = (u8)((writeVal & 0x7f00)>>8);
-		byte2 = (u8)((writeVal & 0x7f0000)>>16);
-		byte3 = (u8)((writeVal & 0x7f000000)>>24);
-		if(byte0 > 0x24)	// Max power index = 0x24
-			byte0 = 0x24;
-		if(byte1 > 0x24)
-			byte1 = 0x24;
-		if(byte2 > 0x24)
-			byte2 = 0x24;
-		if(byte3 > 0x24)
-			byte3 = 0x24;
-
-		//for tx power track
-		if(index == 3)
-		{
-			writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
-			priv->Pwr_Track = writeVal_tmp;
-		}
-
-		if(priv->bDynamicTxHighPower == TRUE)     //Add by Jacken 2008/03/06
-		{
-			// Emily, 20080613. Set low tx power for both MCS and legacy OFDM
-			writeVal = 0x03030303;
-		}
-		else
-		{
-			writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
-		}
-		rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
-	}
-	return;
-
-}
-
diff --git a/drivers/staging/rtl8192su/r8190_rtl8256.h b/drivers/staging/rtl8192su/r8190_rtl8256.h
deleted file mode 100644
index 5c1f650..0000000
--- a/drivers/staging/rtl8192su/r8190_rtl8256.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-  This is part of the rtl8180-sa2400 driver
-  released under the GPL (See file COPYING for details).
-  Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
-
-  This files contains programming code for the rtl8256
-  radio frontend.
-
-  *Many* thanks to Realtek Corp. for their great support!
-
-*/
-
-#ifndef RTL8225H
-#define RTL8225H
-
-#ifdef RTL8190P
-#define RTL819X_TOTAL_RF_PATH 4 //for 90P
-#else
-#define RTL819X_TOTAL_RF_PATH 2 //for 8192U
-#endif
-extern void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth);
-extern void PHY_RF8256_Config(struct net_device* dev);
-extern void phy_RF8256_Config_ParaFile(struct net_device* dev);
-extern void PHY_SetRF8256CCKTxPower(struct net_device*	dev, u8	powerlevel);
-extern void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel);
-
-#endif
diff --git a/drivers/staging/rtl8192su/r8192S_Efuse.c b/drivers/staging/rtl8192su/r8192S_Efuse.c
index 394ab96..f0ce656 100644
--- a/drivers/staging/rtl8192su/r8192S_Efuse.c
+++ b/drivers/staging/rtl8192su/r8192S_Efuse.c
@@ -35,7 +35,6 @@
 //
 // In the future, we will always support EFUSE!!
 //
-#ifdef RTL8192SU
 /*---------------------------Define Local Constant---------------------------*/
 #define 	_POWERON_DELAY_
 #define 	_PRE_EXECUTE_READ_CMD_
@@ -189,10 +188,6 @@ static	u16
 efuse_GetCurrentSize(struct net_device* dev);
 static u8
 efuse_CalculateWordCnts(u8 word_en);
-#if 0
-static	void
-efuse_ResetLoader(struct net_device* dev);
-#endif
 //
 // API for power on power off!!!
 //
@@ -708,12 +703,6 @@ EFUSE_ShadowUpdate(struct net_device* dev)
 	for (offset = 0; offset < 16; offset++)
 	{
 		// Offset 0x18-1F are reserved now!!!
-#ifdef RTL8192SE
-		if(priv->card_8192 == NIC_8192SE){
-			if (offset == 3)
-				continue;
-		}
-#endif
 		word_en = 0x0F;
 		base = offset * 8;
 
@@ -729,12 +718,6 @@ EFUSE_ShadowUpdate(struct net_device* dev)
 			}
 
 			// 2008/12/11 MH HW autoload fail workaround for A/BCUT.
-#ifdef RTL8192SE
-			if (first_pg == TRUE && offset == 1 && (priv->card_8192 == NIC_8192SE))
-			{
-				continue;
-			}
-#endif
 
 			if (first_pg == TRUE)
 			{
@@ -774,21 +757,6 @@ EFUSE_ShadowUpdate(struct net_device* dev)
 	// 2008/12/01 MH For Efuse HW load bug workarounf method!!!!
 	// We will force write 0x10EC into address 10&11 after all Efuse content.
 	//
-#ifdef RTL8192SE
-	if (first_pg == TRUE && (priv->card_8192 == NIC_8192SE))
-	{
-		// 2008/12/11 MH Use new method to prevent HW autoload fail.
-		u8	tmpdata[8];
-
-		memcpy(tmpdata, (&priv->EfuseMap[EFUSE_MODIFY_MAP][8]), 8);
-		efuse_PgPacketWrite(dev, 1, 0x0, tmpdata);
-#if 0
-		u1Byte	tmpdata[8] = {0xFF, 0xFF, 0xEC, 0x10, 0xFF, 0xFF, 0xFF, 0xFF};
-
-		efuse_PgPacketWrite(pAdapter, 1, 0xD, tmpdata);
-#endif
-	}
-#endif
 
 
 	// For warm reboot, we must resume Efuse clock to 500K.
@@ -1048,49 +1016,6 @@ efuse_ReadAllMap(struct net_device*	dev, u8	*Efuse)
 	efuse_PowerSwitch(dev, TRUE);
 	ReadEFuse(dev, 0, 128, Efuse);
 	efuse_PowerSwitch(dev, FALSE);
-#if 0
-	// ==> Prevent efuse read error!!!
-	RT_TRACE(COMP_INIT, "efuse_ResetLoader\n");
-	efuse_ResetLoader(dev);
-
-	// Change Efuse Clock for write action to 40MHZ
-	write_nic_byte(dev, EFUSE_CLK, 0x03);
-
-	ReadEFuse(dev, 0, 128, Efuse);
-
-	// Change Efuse Clock for write action to 500K
-	write_nic_byte(dev, EFUSE_CLK, 0x02);
-#if 0	// Error !!!!!!
-	for(offset = 0;offset<16;offset++)	// For 8192SE
-	{
-		PlatformFillMemory((PVOID)pg_data, 8, 0xff);
-		efuse_PgPacketRead(pAdapter,offset,pg_data);
-
-		PlatformMoveMemory((PVOID)&Efuse[offset*8], (PVOID)pg_data, 8);
-	}
-#endif
-
-	//
-	// Error Check and Reset Again!!!!
-	//
-	if (Efuse[0] != 0x29 || Efuse[1] != 0x81)
-	{
-		// SW autoload fail, we have to read again!!!
-		if (index ++ < 5)
-		{
-			RT_TRACE(COMP_INIT, "EFUSE R FAIL %d\n", index);
-			efuse_ReadAllMap(dev, Efuse);
-			// Wait a few time ???? Or need to do some setting ???
-			// When we reload driver, efuse will be OK!!
-		}
-	}
-	else
-	{
-		index = 0;
-	}
-
-	//efuse_PowerSwitch(pAdapter, FALSE);
-#endif
 }	// efuse_ReadAllMap
 
 
@@ -1800,43 +1725,6 @@ efuse_CalculateWordCnts(u8	word_en)
 	return word_cnts;
 }	// efuse_CalculateWordCnts
 
-
-/*-----------------------------------------------------------------------------
- * Function:	efuse_ResetLoader
- *
- * Overview:	When read Efuse Fail we must reset loader!!!!
- *
- * Input:       NONE
- *
- * Output:      NONE
- *
- * Return:      NONE
- *
- * Revised History:
- * When			Who		Remark
- * 11/22/2008 	MHC		Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-#if 0
-static void efuse_ResetLoader(struct net_device* dev)
-{
-	u16	tmpU2b;
-
-	//
-	// 2008/11/22 MH Sometimes, we may read efuse fail, for preventing the condition
-	// We have to reset loader.
-	//
-	tmpU2b = read_nic_word(dev, SYS_FUNC_EN);
-	write_nic_word(dev, SYS_FUNC_EN, (tmpU2b&~(BIT12)));
-	//PlatformStallExecution(10000);	// How long should we delay!!!
-	mdelay(10);
-	write_nic_word(dev, SYS_FUNC_EN, (tmpU2b|BIT12));
-	//PlatformStallExecution(10000);	// How long should we delay!!!
-	mdelay(10);
-
-}	// efuse_ResetLoader
-#endif
-
 /*-----------------------------------------------------------------------------
  * Function:	EFUSE_ProgramMap
  *
@@ -2428,7 +2316,6 @@ void efuset_test_func_write(struct net_device* dev)
 
 
 
-#endif	// #if (HAL_CODE_BASE == RTL8192_S)
 
 
 
diff --git a/drivers/staging/rtl8192su/r8192S_FwImgDTM.h b/drivers/staging/rtl8192su/r8192S_FwImgDTM.h
deleted file mode 100644
index afced75..0000000
--- a/drivers/staging/rtl8192su/r8192S_FwImgDTM.h
+++ /dev/null
@@ -1,3797 +0,0 @@
-#ifndef HAL8192PciE_FW_IMG_DTM_H
-#define HAL8192PciE_FW_IMG_DTM_H
-
-/*Created on  2008/ 3/11,  8:34*/
-#include <linux/types.h>
-
-#define MACPHY_ArrayLengthDTM 18
-#define MACPHY_Array_PGLengthDTM 30
-#define AGCTAB_ArrayLengthDTM 384
-#define AGCTAB_ArrayLength 384
-
-#define BootArrayLengthDTM 344
-u8 Rtl8192PciEFwBootArrayDTM[BootArrayLengthDTM] = {
-0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08,
-0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
-0x25,0x08,0xbc,0xf0,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,
-0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b,
-0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00,
-0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
-0x25,0x08,0xbc,0xf0,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0,
-0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00,
-0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00,
-0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,
-0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,
-0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01,
-0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24,
-0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10,
-0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10,
-0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x5f,0x84,
-0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,};
-
-#define MainArrayLengthDTM 48368
-u8 Rtl8192PciEFwMainArrayDTM[MainArrayLengthDTM] = {
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x17,0x50,
-0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09,
-0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24,
-0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0,
-0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x91,0x50,0x00,0x85,0x18,0x21,
-0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00,
-0x27,0x82,0x91,0x5a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00,
-0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x91,0x50,
-0x24,0x02,0x00,0x0a,0x24,0x03,0x09,0xc4,0xa3,0x82,0x91,0x52,0x24,0x02,0x00,0x04,
-0x24,0x04,0x00,0x01,0x24,0x05,0x00,0x02,0xa7,0x83,0x91,0x66,0xa3,0x82,0x91,0x58,
-0x24,0x03,0x04,0x00,0x24,0x02,0x02,0x00,0xaf,0x83,0x91,0x6c,0xa3,0x85,0x91,0x59,
-0xa7,0x82,0x91,0x5a,0xa7,0x84,0x91,0x5c,0xaf,0x84,0x91,0x68,0xa3,0x84,0x91,0x51,
-0xa3,0x80,0x91,0x53,0xa3,0x80,0x91,0x54,0xa3,0x80,0x91,0x55,0xa3,0x84,0x91,0x56,
-0xa3,0x85,0x91,0x57,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x7c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,
-0x27,0x84,0x91,0x78,0x00,0x00,0x10,0x21,0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00,
-0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03,0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00,
-0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc0,
-0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00,0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00,
-0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00,0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00,
-0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03,0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03,
-0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03,0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11,
-0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02,0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07,
-0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66,0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10,
-0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43,0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b,
-0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20,
-0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x24,
-0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54,
-0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xaf,0x83,0x91,0x74,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18,
-0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21,0x27,0x85,0x91,0x70,0x8c,0xa3,0x00,0x00,
-0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a,
-0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00,0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01,
-0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03,0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3,
-0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23,0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40,
-0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x91,0x78,0x00,0x0a,0x20,0x0b,
-0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05,0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01,
-0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x91,0x78,0xa0,0x67,0x00,0x01,
-0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07,
-0x00,0x00,0x00,0x00,0x27,0x83,0x91,0x70,0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21,0xac,0x62,0x00,0x00,0x27,0x85,0x91,0x74,
-0x27,0x82,0x91,0x70,0x00,0xc5,0x28,0x21,0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00,
-0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03,
-0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xb7,0xac,0xa0,0x00,0x00,
-0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x91,0x8c,0x08,0x00,0x00,0xa7,
-0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xaf,0x83,0x91,0x80,0x08,0x00,0x00,0xa7,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x10,
-0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00,
-0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03,0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03,
-0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01,0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2,
-0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09,
-0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c,0x30,0x43,0x00,0x03,0x83,0x82,0x91,0x78,
-0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00,
-0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04,
-0x30,0x43,0x00,0x06,0x93,0x82,0x91,0x90,0x08,0x00,0x01,0x1f,0x00,0x43,0x10,0x21,
-0x83,0x82,0x91,0x84,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x1f,
-0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,
-0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xe4,
-0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08,
-0x24,0x02,0x00,0x01,0xaf,0x84,0x91,0xa0,0xa3,0x82,0x91,0xb0,0xa7,0x80,0x91,0xa4,
-0xa7,0x80,0x91,0xa6,0xaf,0x80,0x91,0xa8,0xaf,0x80,0x91,0xac,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x05,0x24,0x27,0xbd,0xff,0xe0,0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0xaf,0xbf,0x00,0x18,0x0c,0x00,0x01,0xe3,
-0x00,0x80,0x80,0x21,0x02,0x00,0x20,0x21,0x10,0x40,0x00,0x05,0x02,0x20,0x28,0x21,
-0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x0c,0x00,0x01,0xf9,0x00,0x00,0x00,0x00,0x08,0x00,0x01,0x58,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x05,0x80,
-0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x18,0x8f,0x90,0x91,0xa0,0x0c,0x00,0x01,0xe3,0x00,0x80,0x88,0x21,
-0x14,0x40,0x00,0x2a,0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02,0x34,0x42,0x02,0x01,
-0x24,0x02,0x02,0x01,0xae,0x02,0x00,0x00,0x97,0x84,0x91,0xa4,0x97,0x82,0x91,0xa6,
-0x3c,0x03,0xb0,0x02,0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04,0xa7,0x82,0x91,0xa6,
-0xa4,0x82,0x00,0x00,0x8f,0x84,0x91,0xa8,0x8f,0x82,0x91,0xa0,0x93,0x85,0x91,0x52,
-0x24,0x84,0x00,0x01,0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff,0x3c,0x07,0xb0,0x06,
-0x3c,0x06,0xb0,0x03,0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a,0x34,0xe7,0x80,0x18,
-0xaf,0x82,0x91,0xa0,0xaf,0x84,0x91,0xa8,0x10,0xa0,0x00,0x08,0x34,0xc6,0x01,0x08,
-0x8f,0x83,0x91,0xac,0x8f,0x84,0x91,0x6c,0x8c,0xc2,0x00,0x00,0x00,0x64,0x18,0x21,
-0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x8c,0xe2,0x00,0x00,
-0x3c,0x03,0x0f,0x00,0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24,0x10,0x44,0x00,0x03,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x03,0x95,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x6c,0xaf,0xb0,0x00,0x10,
-0x34,0x42,0x00,0x20,0x8f,0x90,0x91,0xa0,0xac,0x43,0x00,0x00,0xaf,0xb3,0x00,0x1c,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0x00,0x80,0x88,0x21,
-0x00,0xa0,0x90,0x21,0x0c,0x00,0x01,0xe3,0x00,0xc0,0x98,0x21,0x24,0x07,0x8f,0xff,
-0x14,0x40,0x00,0x19,0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03,0xae,0x02,0x00,0x00,
-0x00,0x67,0x80,0x24,0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00,0x00,0x47,0x80,0x24,
-0x97,0x86,0x91,0xa4,0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00,0x00,0x67,0x80,0x24,
-0xae,0x13,0x00,0x00,0x8f,0x84,0x91,0xa0,0x3c,0x02,0xb0,0x02,0x97,0x85,0x91,0xa6,
-0x00,0xc2,0x30,0x21,0x8f,0x82,0x91,0xa8,0x24,0x84,0x00,0x10,0x24,0xa5,0x00,0x10,
-0x00,0x87,0x20,0x24,0x24,0x42,0x00,0x01,0xa7,0x85,0x91,0xa6,0xaf,0x84,0x91,0xa0,
-0xaf,0x82,0x91,0xa8,0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x87,0x83,0x88,0x86,
-0x93,0x82,0x80,0x11,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,
-0x93,0x83,0x88,0x87,0x24,0x02,0x00,0x01,0xa3,0x82,0x80,0x10,0xa3,0x83,0x80,0x12,
-0xa3,0x83,0x80,0x11,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x93,0x82,0x80,0x12,
-0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xf6,0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xd5,
-0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,
-0xa3,0x85,0x8b,0x6b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x93,0x82,0x91,0xb0,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01,0x8f,0x82,0x91,0xa8,
-0x3c,0x05,0xb0,0x06,0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18,0x34,0x84,0x01,0x08,
-0x14,0x40,0x00,0x09,0x00,0x00,0x30,0x21,0x97,0x82,0x91,0xa4,0x8c,0x84,0x00,0x00,
-0x3c,0x03,0xb0,0x02,0x00,0x43,0x10,0x21,0xaf,0x84,0x91,0xac,0xa7,0x80,0x91,0xa6,
-0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0xc0,0x10,0x21,0x8f,0x86,0x91,0xa0,0x8f,0x82,0x91,0xa8,0x27,0xbd,0xff,0xe8,
-0xaf,0xbf,0x00,0x10,0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a,0x00,0x40,0x50,0x21,
-0x00,0x00,0x38,0x21,0x27,0x89,0x8b,0x40,0x24,0xe2,0x00,0x01,0x00,0x07,0x18,0x80,
-0x30,0x47,0x00,0xff,0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a,0x14,0x40,0xff,0xfa,
-0xac,0x60,0x00,0x00,0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6d,0x00,0x00,0x00,0x00,
-0x97,0x82,0x8b,0x46,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x8b,0x46,
-0x90,0xa3,0x00,0x15,0x97,0x82,0x8b,0x48,0x00,0x03,0x1e,0x00,0x00,0x03,0x1e,0x03,
-0x00,0x43,0x10,0x21,0xa7,0x82,0x8b,0x48,0x8c,0xa4,0x00,0x20,0x3c,0x02,0x00,0x60,
-0x3c,0x03,0x00,0x20,0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x52,0x00,0x00,0x00,0x00,
-0x14,0x80,0x00,0x45,0x00,0x00,0x00,0x00,0x97,0x82,0x8b,0x4c,0x00,0x00,0x00,0x00,
-0x24,0x42,0x00,0x01,0xa7,0x82,0x8b,0x4c,0x84,0xa3,0x00,0x06,0x8f,0x82,0x8b,0x5c,
-0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x8b,0x5c,0x25,0x42,0x00,0x01,
-0x28,0x43,0x27,0x10,0xaf,0x82,0x91,0xa8,0x10,0x60,0x00,0x09,0x24,0x02,0x00,0x04,
-0x93,0x83,0x80,0x10,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x04,
-0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x24,0x03,0x00,0x28,0xa3,0x83,0x8b,0x42,0xa3,0x82,0x8b,0x43,0x90,0xa2,0x00,0x18,
-0x93,0x83,0x8b,0x6b,0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,
-0xa7,0x82,0x8b,0x56,0xa3,0x83,0x8b,0x64,0x27,0x89,0x8b,0x40,0x24,0x05,0x8f,0xff,
-0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xe3,0x00,0x01,
-0x30,0x67,0x00,0xff,0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a,0xad,0x04,0x00,0x00,
-0x14,0x60,0xff,0xf7,0x00,0x45,0x40,0x24,0x97,0x83,0x91,0xa6,0x97,0x85,0x91,0xa4,
-0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,
-0xa7,0x83,0x91,0xa6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,
-0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,
-0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x91,0xa0,0x10,0xa2,0xff,0xd4,
-0x00,0x00,0x00,0x00,0xa3,0x80,0x80,0x10,0x0c,0x00,0x03,0x95,0x00,0x00,0x00,0x00,
-0x08,0x00,0x02,0x30,0x00,0x00,0x00,0x00,0x97,0x82,0x8b,0x4e,0x00,0x00,0x00,0x00,
-0x24,0x42,0x00,0x01,0xa7,0x82,0x8b,0x4e,0x84,0xa3,0x00,0x06,0x8f,0x82,0x8b,0x60,
-0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x8b,0x60,0x08,0x00,0x02,0x28,
-0x25,0x42,0x00,0x01,0x97,0x82,0x8b,0x4a,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
-0xa7,0x82,0x8b,0x4a,0x84,0xa3,0x00,0x06,0x8f,0x82,0x8b,0x58,0x00,0x00,0x00,0x00,
-0x00,0x43,0x10,0x21,0xaf,0x82,0x8b,0x58,0x08,0x00,0x02,0x28,0x25,0x42,0x00,0x01,
-0x97,0x82,0x8b,0x44,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x8b,0x44,
-0x08,0x00,0x02,0x10,0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x27,0xbd,0xff,0xc8,0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x09,0xf8,
-0x3c,0x03,0xb0,0x00,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb2,0x00,0x18,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21,0xaf,0xb7,0x00,0x2c,
-0xaf,0xb6,0x00,0x28,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xac,0xa2,0x00,0x00,
-0x8e,0x09,0x00,0x00,0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08,0x00,0x09,0xa6,0x02,
-0x12,0x80,0x00,0x13,0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02,0x3c,0x16,0x00,0xff,
-0x3c,0x17,0xff,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x12,0x02,
-0x24,0x42,0x00,0x02,0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76,0x30,0x51,0x00,0xff,
-0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00,0x02,0x51,0x10,0x21,
-0x30,0x52,0xff,0xff,0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2,0x02,0x11,0x80,0x21,
-0x12,0xa0,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,0x8c,0x43,0x00,0x00,
-0x3c,0x04,0x0f,0x00,0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24,0x10,0x62,0x00,0x03,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x03,0x95,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,
-0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04,0x24,0x15,0x00,0x01,
-0x8e,0x06,0x00,0x0c,0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2,0x30,0x48,0x00,0x03,
-0x00,0x09,0x14,0x02,0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02,0x11,0x15,0x00,0x45,
-0x30,0x43,0x00,0x0f,0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26,0x00,0x00,0x00,0x00,
-0x11,0x13,0x00,0x0f,0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02,0x30,0x84,0xff,0x00,
-0x3c,0x03,0x00,0xff,0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00,0x00,0x43,0x10,0x24,
-0x00,0xa4,0x28,0x25,0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00,0x00,0xa3,0x28,0x25,
-0x0c,0x00,0x01,0x9b,0x01,0x20,0x20,0x21,0x08,0x00,0x02,0xa4,0x02,0x51,0x10,0x21,
-0x11,0x95,0x00,0x0f,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07,0x00,0x00,0x00,0x00,
-0x00,0x04,0x10,0x80,0x27,0x83,0x91,0x50,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,
-0x08,0x00,0x02,0xcb,0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40,0x27,0x83,0x91,0x58,
-0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x02,0x08,0x00,0x02,0xcb,0x00,0x07,0x22,0x02,
-0x27,0x82,0x91,0x50,0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00,0x08,0x00,0x02,0xcb,
-0x00,0x07,0x22,0x02,0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21,0x10,0x75,0x00,0x05,
-0x00,0x80,0x38,0x21,0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00,0x00,0x00,0x38,0x21,
-0x00,0x43,0x38,0x0a,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e,0x3c,0x02,0xb0,0x03,
-0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x00,0xe2,0x10,0x21,0x8c,0x47,0x00,0x00,0x08,0x00,0x02,0xcb,0x00,0x07,0x22,0x02,
-0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00,0x08,0x00,0x02,0xca,
-0x30,0x67,0xff,0xff,0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00,0x08,0x00,0x02,0xca,
-0x30,0x67,0x00,0xff,0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00,0x11,0x95,0x00,0x07,
-0x00,0x44,0x38,0x21,0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x02,0xfc,
-0x3c,0x02,0xb0,0x0a,0x08,0x00,0x03,0x01,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x03,0x05,
-0x3c,0x02,0xb0,0x0a,0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08,0x8e,0x03,0x00,0x0c,
-0x00,0x09,0x41,0x42,0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02,0x30,0x84,0xff,0x00,
-0x30,0xe7,0xff,0x00,0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00,0x00,0x03,0x56,0x02,
-0x00,0x03,0x2a,0x00,0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24,0x01,0x47,0x50,0x25,
-0x00,0x02,0x16,0x00,0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00,0x01,0x66,0x58,0x25,
-0x01,0x45,0x50,0x25,0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24,0x01,0x62,0x38,0x25,
-0x01,0x43,0x30,0x25,0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02,0x31,0x08,0x00,0x03,
-0x30,0x4c,0x00,0x03,0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02,0x00,0xe0,0x58,0x21,
-0x15,0x00,0x00,0x28,0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x06,
-0x00,0x80,0x28,0x21,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69,0x02,0x51,0x10,0x21,
-0x24,0x85,0x01,0x00,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15,0x24,0x02,0x00,0x02,
-0x11,0x82,0x00,0x0a,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,
-0xac,0x62,0x00,0x00,0x08,0x00,0x02,0xa4,0x02,0x51,0x10,0x21,0x00,0xa3,0x18,0x21,
-0x94,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,
-0x00,0x45,0x10,0x25,0xa4,0x62,0x00,0x00,0x08,0x00,0x02,0xa4,0x02,0x51,0x10,0x21,
-0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,
-0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x02,0xa3,
-0xa0,0x62,0x00,0x00,0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21,0x00,0x00,0x00,0x00,
-0x15,0x13,0xff,0x42,0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17,0x00,0x00,0x00,0x00,
-0x11,0x88,0x00,0x0b,0x00,0x00,0x00,0x00,0x27,0x83,0x91,0x50,0x00,0x04,0x20,0x80,
-0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,
-0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x02,0xa3,0xac,0x82,0x00,0x18,
-0x27,0x83,0x91,0x58,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21,0x94,0x82,0x00,0x02,
-0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,
-0x08,0x00,0x02,0xa3,0xa4,0x82,0x00,0x02,0x27,0x83,0x91,0x50,0x00,0x83,0x18,0x21,
-0x90,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x03,0x59,0x00,0xe6,0x28,0x24,
-0x30,0x62,0x00,0x07,0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f,0x00,0x44,0x10,0x21,
-0x11,0x93,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,
-0x8c,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x03,0x46,0x00,0xe6,0x28,0x24,
-0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x06,0x20,0x27,
-0x08,0x00,0x03,0x4f,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x08,0x00,0x03,0x7c,
-0x00,0x43,0x18,0x21,0x97,0x85,0x91,0xa4,0x3c,0x07,0xb0,0x02,0x3c,0x04,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x0e,0x54,
-0x24,0x03,0xff,0x80,0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07,0x97,0x82,0x91,0xa6,
-0x97,0x85,0x91,0xa4,0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8,0x24,0x42,0x00,0x10,
-0x00,0xa2,0x10,0x21,0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08,0x30,0x84,0x0f,0xff,
-0x00,0x05,0x28,0xc2,0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25,0x00,0x87,0x20,0x21,
-0x34,0xc6,0x80,0x18,0xac,0xc5,0x00,0x00,0xaf,0x84,0x91,0xa0,0xa7,0x82,0x91,0xa4,
-0xa7,0x80,0x91,0xa6,0xaf,0x80,0x91,0xa8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x30,0xa5,0x00,0xff,0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0xe0,0x48,0x21,
-0x30,0xc6,0x00,0xff,0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07,0x00,0xa0,0x40,0x21,
-0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03,0x24,0x02,0x00,0x01,
-0x00,0x07,0x20,0x27,0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14,0x01,0x03,0x18,0x21,
-0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27,0x3c,0x03,0xb0,0x03,
-0x01,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,
-0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xe0,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x01,0x03,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,
-0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa0,0x62,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07,0x00,0x04,0x22,0x00,
-0x30,0xa5,0x00,0xff,0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a,0x00,0xa2,0x40,0x21,
-0x30,0xc6,0x00,0xff,0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10,0x10,0xc2,0x00,0x14,
-0x24,0x02,0x00,0x02,0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09,0x00,0xe4,0x48,0x24,
-0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,
-0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,
-0x91,0x02,0x00,0x00,0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24,0x00,0x43,0x10,0x24,
-0x00,0x44,0x10,0x25,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00,0x30,0xa9,0x00,0xff,
-0x27,0x83,0x91,0x50,0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0x07,0x50,0x27,
-0x00,0xc7,0x40,0x24,0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21,0x00,0x05,0x20,0x40,
-0x27,0x82,0x91,0x50,0x00,0x05,0x28,0x80,0x27,0x83,0x91,0x58,0x00,0x83,0x50,0x21,
-0x00,0xa2,0x20,0x21,0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27,0x11,0x22,0x00,0x07,
-0x00,0xc7,0x28,0x24,0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,
-0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18,0x95,0x42,0x00,0x02,
-0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,
-0xa5,0x42,0x00,0x02,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,
-0x00,0x48,0x10,0x25,0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00,0x00,0x04,0x32,0x02,
-0x30,0xc6,0xff,0x00,0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00,0x3c,0x05,0x00,0xff,
-0x00,0x65,0x18,0x24,0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25,0x00,0x04,0x26,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x44,0x10,0x25,0x3c,0x02,0xb0,0x02,0x34,0x42,0x00,0x08,
-0x3c,0x03,0xb0,0x02,0xaf,0x82,0x8b,0x78,0xaf,0x83,0x8b,0x7c,0xa7,0x80,0x8b,0x80,
-0xa7,0x80,0x8b,0x82,0xaf,0x80,0x8b,0x84,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x27,0xbd,0xff,0xd8,0xaf,0xbf,0x00,0x20,0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
-0x30,0x42,0xe0,0x00,0x10,0x40,0x00,0x05,0x00,0x80,0x18,0x21,0x8f,0xbf,0x00,0x20,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x90,0x84,0x00,0x02,
-0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xfc,0x0c,0x00,0x06,0xc9,0x00,0x64,0x20,0x21,
-0x08,0x00,0x04,0x47,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb2,0x00,0x18,
-0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,
-0x8f,0x90,0x91,0xa0,0x0c,0x00,0x2b,0xd1,0x00,0x80,0x90,0x21,0x00,0x40,0x88,0x21,
-0x93,0x82,0x82,0x20,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1b,0x24,0x02,0x00,0x01,
-0xa3,0x82,0x82,0x20,0x24,0x03,0x00,0x05,0x24,0x02,0x00,0x04,0xa3,0x83,0x8b,0x73,
-0xa3,0x82,0x8b,0x72,0xa7,0x80,0x82,0x22,0x00,0x00,0x28,0x21,0x27,0x86,0x8b,0x70,
-0x00,0x05,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01,
-0x30,0x65,0xff,0xff,0xae,0x04,0x00,0x00,0x10,0xa0,0xff,0xfa,0x00,0x05,0x10,0x80,
-0x8f,0x83,0x91,0xa0,0x97,0x82,0x91,0xa6,0x24,0x05,0x8f,0xff,0x24,0x63,0x00,0x04,
-0x00,0x65,0x18,0x24,0x26,0x04,0x00,0x04,0x24,0x42,0x00,0x04,0xaf,0x83,0x91,0xa0,
-0xa7,0x82,0x91,0xa6,0x00,0x85,0x80,0x24,0x97,0x84,0x82,0x22,0x27,0x93,0x80,0x2c,
-0x02,0x40,0x28,0x21,0x00,0x93,0x20,0x21,0x0c,0x00,0x2c,0x55,0x02,0x20,0x30,0x21,
-0x97,0x87,0x82,0x22,0x24,0x02,0x00,0x52,0x00,0xf1,0x18,0x21,0xa7,0x83,0x82,0x22,
-0x82,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x06,0x00,0x60,0x38,0x21,
-0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x28,0x82,0x43,0x00,0x01,0x24,0x02,0x00,0x54,0x14,0x62,0xff,0xf8,
-0x24,0x02,0x00,0x4c,0x82,0x43,0x00,0x02,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xf4,
-0x00,0x00,0x00,0x00,0x30,0xe6,0xff,0xff,0x10,0xc0,0x00,0x0c,0x00,0x00,0x28,0x21,
-0x02,0x60,0x48,0x21,0x24,0x08,0x8f,0xff,0x00,0xa9,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x24,0xa3,0x00,0x04,0x30,0x65,0xff,0xff,0x26,0x02,0x00,0x04,0x00,0xa6,0x18,0x2b,
-0xae,0x04,0x00,0x00,0x14,0x60,0xff,0xf8,0x00,0x48,0x80,0x24,0x97,0x83,0x91,0xa6,
-0x97,0x85,0x91,0xa4,0x3c,0x02,0xb0,0x02,0x00,0x67,0x18,0x21,0x00,0xa2,0x28,0x21,
-0x3c,0x04,0xb0,0x06,0xa7,0x83,0x91,0xa6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,
-0x8f,0x82,0x91,0xa0,0x8c,0x86,0x00,0x00,0x30,0xe5,0xff,0xff,0x24,0x03,0x8f,0xff,
-0x00,0x45,0x10,0x21,0x3c,0x04,0x0f,0x00,0x00,0x43,0x10,0x24,0x00,0xc4,0x30,0x24,
-0x3c,0x03,0x04,0x00,0xaf,0x82,0x91,0xa0,0x10,0xc3,0xff,0xd1,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x03,0x95,0x00,0x00,0x00,0x00,0xa3,0x80,0x82,0x20,0x08,0x00,0x04,0x88,
-0x00,0x00,0x00,0x00,0x8f,0x82,0x8b,0x7c,0x97,0x83,0x8b,0x80,0x8f,0x87,0x8b,0x78,
-0x3c,0x06,0xff,0xff,0xac,0x43,0x00,0x00,0x8f,0x82,0x8b,0x7c,0x3c,0x03,0x80,0x00,
-0x24,0xe5,0x00,0x08,0xac,0x43,0x00,0x04,0x8f,0x82,0x8b,0x7c,0x34,0xc6,0x1f,0xff,
-0x3c,0x03,0x00,0x40,0x30,0x42,0x0f,0xff,0x3c,0x04,0xb0,0x06,0x00,0x02,0x10,0xc2,
-0x00,0x43,0x10,0x25,0x00,0xa6,0x28,0x24,0x34,0x84,0x80,0x18,0x27,0xbd,0xff,0xf8,
-0xac,0x82,0x00,0x00,0xaf,0x85,0x8b,0x78,0xaf,0x87,0x8b,0x7c,0xa7,0x80,0x8b,0x80,
-0xa7,0x80,0x8b,0x82,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe0,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x8f,0x91,0x8b,0x78,
-0x00,0x80,0x80,0x21,0xaf,0xbf,0x00,0x1c,0x0c,0x00,0x05,0x78,0x00,0xa0,0x90,0x21,
-0x97,0x82,0x8b,0x80,0x36,0x10,0x12,0x00,0x26,0x2a,0x00,0x04,0x24,0x4c,0x00,0x14,
-0x2c,0x42,0x04,0x01,0x14,0x40,0x00,0x0a,0x24,0x09,0x8f,0xff,0x8f,0x82,0x80,0x18,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x80,0x18,0x8f,0xbf,0x00,0x1c,
-0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x8e,0x44,0x00,0x1c,0x86,0x47,0x00,0x06,0x97,0x86,0x8b,0x82,0x8c,0x82,0x00,0x08,
-0x00,0x07,0x3c,0x00,0x8f,0x85,0x8b,0x78,0x00,0x02,0x11,0x02,0x30,0x42,0x40,0x00,
-0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x8c,0x82,0x00,0x04,0x82,0x43,0x00,0x15,
-0x01,0x49,0x88,0x24,0x00,0x02,0x14,0xc2,0x00,0x03,0x1a,0x00,0x00,0x02,0x14,0x00,
-0x00,0x62,0x80,0x25,0xae,0x30,0x00,0x00,0x92,0x43,0x00,0x13,0x92,0x44,0x00,0x10,
-0x96,0x50,0x00,0x1a,0x00,0x03,0x1c,0x00,0x00,0x04,0x26,0x00,0x02,0x03,0x80,0x25,
-0x26,0x22,0x00,0x04,0x00,0x49,0x88,0x24,0x02,0x04,0x80,0x25,0xae,0x30,0x00,0x00,
-0x92,0x42,0x00,0x0f,0x92,0x43,0x00,0x11,0x26,0x24,0x00,0x04,0x00,0x02,0x12,0x00,
-0x00,0x89,0x88,0x24,0x00,0x62,0x80,0x25,0x02,0x07,0x80,0x25,0x26,0x22,0x00,0x04,
-0xae,0x30,0x00,0x00,0x00,0x49,0x88,0x24,0xae,0x20,0x00,0x00,0x8f,0x82,0x80,0x14,
-0x24,0xc6,0x00,0x01,0x24,0xa5,0x00,0x14,0x30,0xc8,0xff,0xff,0x3c,0x0b,0xb0,0x03,
-0x00,0xa9,0x28,0x24,0x24,0x42,0x00,0x01,0x2d,0x08,0x00,0x0a,0xaf,0x85,0x8b,0x78,
-0xa7,0x8c,0x8b,0x80,0xaf,0x82,0x80,0x14,0xa7,0x86,0x8b,0x82,0x11,0x00,0x00,0x07,
-0x35,0x6b,0x01,0x08,0x8f,0x82,0x8b,0x84,0x8d,0x63,0x00,0x00,0x24,0x42,0x04,0x00,
-0x00,0x62,0x18,0x2b,0x14,0x60,0xff,0xc1,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0xbd,
-0x00,0x00,0x00,0x00,0x08,0x00,0x04,0xf3,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,
-0xaf,0xbf,0x00,0x10,0x0c,0x00,0x05,0x78,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x27,0xbd,0xff,0xe0,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,
-0x8f,0x90,0x8b,0x78,0x0c,0x00,0x05,0x78,0x00,0x80,0x90,0x21,0x97,0x82,0x8b,0x80,
-0x24,0x11,0x8f,0xff,0x2c,0x42,0x04,0x01,0x14,0x40,0x00,0x06,0x26,0x03,0x00,0x04,
-0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x24,0x02,0x0e,0x03,0xae,0x02,0x00,0x00,0x00,0x71,0x80,0x24,
-0xae,0x00,0x00,0x00,0x8e,0x44,0x00,0x08,0x26,0x02,0x00,0x04,0x0c,0x00,0x05,0x86,
-0x00,0x51,0x80,0x24,0x97,0x86,0x8b,0x82,0x8f,0x83,0x8b,0x78,0xae,0x02,0x00,0x00,
-0x97,0x82,0x8b,0x80,0x24,0xc6,0x00,0x01,0x8e,0x47,0x00,0x0c,0x24,0x63,0x00,0x10,
-0x30,0xc5,0xff,0xff,0x26,0x04,0x00,0x04,0x3c,0x08,0xb0,0x03,0x00,0x71,0x18,0x24,
-0x00,0x91,0x80,0x24,0x24,0x42,0x00,0x10,0x2c,0xa5,0x00,0x0a,0x35,0x08,0x01,0x08,
-0xae,0x07,0x00,0x00,0xaf,0x83,0x8b,0x78,0xa7,0x82,0x8b,0x80,0xa7,0x86,0x8b,0x82,
-0x10,0xa0,0x00,0x07,0x00,0x00,0x00,0x00,0x8f,0x82,0x8b,0x84,0x8d,0x03,0x00,0x00,
-0x24,0x42,0x04,0x00,0x00,0x62,0x18,0x2b,0x14,0x60,0xff,0xd9,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x04,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x05,0x4c,0x00,0x00,0x00,0x00,
-0x97,0x82,0x8b,0x82,0x3c,0x03,0xb0,0x03,0x14,0x40,0x00,0x09,0x34,0x63,0x01,0x08,
-0x8c,0x62,0x00,0x00,0x8f,0x83,0x8b,0x7c,0xa7,0x80,0x8b,0x80,0xaf,0x82,0x8b,0x84,
-0xac,0x60,0x00,0x00,0x8f,0x82,0x8b,0x7c,0x00,0x00,0x00,0x00,0xac,0x40,0x00,0x04,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00,
-0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00,0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24,
-0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25,0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x44,0x10,0x25,0x80,0x82,0x00,0x00,0x90,0x83,0x00,0x00,0x10,0x40,0x00,0x0c,
-0x00,0x80,0x28,0x21,0x24,0x62,0xff,0x9f,0x30,0x42,0x00,0xff,0x2c,0x42,0x00,0x1a,
-0x10,0x40,0x00,0x02,0x24,0x63,0xff,0xe0,0xa0,0xa3,0x00,0x00,0x24,0xa5,0x00,0x01,
-0x90,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xf6,0x00,0x40,0x18,0x21,
-0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x80,0x82,0x00,0x00,0x90,0x83,0x00,0x00,
-0x10,0x40,0x00,0x0c,0x00,0x80,0x28,0x21,0x24,0x62,0xff,0xbf,0x30,0x42,0x00,0xff,
-0x2c,0x42,0x00,0x1a,0x10,0x40,0x00,0x02,0x24,0x63,0x00,0x20,0xa0,0xa3,0x00,0x00,
-0x24,0xa5,0x00,0x01,0x90,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xf6,
-0x00,0x40,0x18,0x21,0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x27,0xbd,0xff,0xe8,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x24,0x10,0xff,0xff,0x0c,0x00,0x29,0x11,
-0x00,0x00,0x00,0x00,0x10,0x50,0xff,0xfd,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,
-0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x27,0xbd,0xff,0xc8,0xaf,0xb3,0x00,0x1c,0x00,0x00,0x98,0x21,0xaf,0xb1,0x00,0x14,
-0x02,0x65,0x88,0x2b,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x34,0xaf,0xbe,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb4,0x00,0x20,
-0xaf,0xb2,0x00,0x18,0x00,0xa0,0xb0,0x21,0xaf,0xa4,0x00,0x38,0x00,0xc0,0xa8,0x21,
-0x12,0x20,0x00,0x17,0x00,0x80,0x80,0x21,0x24,0x17,0xff,0xff,0x24,0x1e,0x00,0x0a,
-0x0c,0x00,0x29,0x11,0x00,0x00,0x00,0x00,0x10,0x57,0x00,0x0f,0x00,0x02,0x16,0x00,
-0x00,0x02,0x26,0x03,0x10,0x9e,0x00,0x0e,0x24,0x02,0x00,0x0d,0x10,0x82,0x00,0x34,
-0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x25,0x24,0x02,0x00,0x09,0x10,0x82,0x00,0x13,
-0x00,0x00,0x90,0x21,0xa2,0x04,0x00,0x00,0x26,0x73,0x00,0x01,0x16,0xa0,0x00,0x0b,
-0x26,0x10,0x00,0x01,0x02,0x76,0x88,0x2b,0x16,0x20,0xff,0xed,0x00,0x00,0x00,0x00,
-0x7b,0xbe,0x01,0xbc,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x0c,0x00,0x29,0x04,
-0x02,0x76,0x88,0x2b,0x08,0x00,0x05,0xe6,0x00,0x00,0x00,0x00,0x24,0x14,0x00,0x20,
-0xa2,0x14,0x00,0x00,0x26,0x52,0x00,0x01,0x24,0x04,0x00,0x20,0x26,0x73,0x00,0x01,
-0x16,0xa0,0x00,0x06,0x26,0x10,0x00,0x01,0x2a,0x42,0x00,0x08,0x10,0x40,0xff,0xea,
-0x02,0x76,0x88,0x2b,0x08,0x00,0x05,0xf5,0xa2,0x14,0x00,0x00,0x0c,0x00,0x29,0x04,
-0x00,0x00,0x00,0x00,0x08,0x00,0x05,0xfb,0x2a,0x42,0x00,0x08,0x8f,0xa2,0x00,0x38,
-0x00,0x00,0x00,0x00,0x12,0x02,0xff,0xe0,0x00,0x00,0x00,0x00,0x26,0x10,0xff,0xff,
-0x12,0xa0,0xff,0xdc,0x26,0x73,0xff,0xff,0x0c,0x00,0x29,0x04,0x24,0x04,0x00,0x08,
-0x0c,0x00,0x29,0x04,0x24,0x04,0x00,0x20,0x08,0x00,0x05,0xef,0x24,0x04,0x00,0x08,
-0x08,0x00,0x05,0xe8,0xa2,0x00,0x00,0x00,0x90,0x82,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x1e,0x00,0x10,0x60,0x00,0x16,0x00,0x00,0x30,0x21,0x24,0x07,0x00,0x20,
-0x00,0x03,0x1e,0x03,0x10,0x67,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x15,
-0x00,0x00,0x00,0x00,0x10,0x67,0x00,0x0b,0x24,0xc6,0x00,0x01,0x10,0x60,0x00,0x0a,
-0x00,0x02,0x1e,0x00,0x24,0x05,0x00,0x20,0x24,0x84,0x00,0x01,0x80,0x83,0x00,0x00,
-0x90,0x82,0x00,0x00,0x10,0x65,0x00,0x03,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xfa,
-0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00,0x14,0x60,0xff,0xed,0x00,0x00,0x00,0x00,
-0x28,0xc3,0x00,0x08,0x24,0x02,0x00,0x07,0x00,0x43,0x30,0x0a,0x03,0xe0,0x00,0x08,
-0x00,0xc0,0x10,0x21,0x24,0x84,0x00,0x01,0x90,0x82,0x00,0x00,0x08,0x00,0x06,0x2a,
-0x00,0x02,0x1e,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb1,0x00,0x14,0x27,0x91,0x8b,0x88,
-0xaf,0xb0,0x00,0x10,0x24,0x06,0x00,0x20,0x00,0x80,0x80,0x21,0x00,0x00,0x28,0x21,
-0xaf,0xbf,0x00,0x18,0x0c,0x00,0x2c,0x4b,0x02,0x20,0x20,0x21,0x82,0x02,0x00,0x00,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x1f,0x00,0x00,0x30,0x21,0x02,0x20,0x20,0x21,
-0x24,0x09,0x00,0x20,0x24,0x08,0x00,0x20,0x24,0x07,0x00,0x08,0xac,0x90,0x00,0x00,
-0x82,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x49,0x00,0x0a,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x08,0x24,0x03,0x00,0x20,0x26,0x10,0x00,0x01,0x82,0x02,0x00,0x00,
-0x00,0x00,0x00,0x00,0x10,0x43,0x00,0x03,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfa,
-0x00,0x00,0x00,0x00,0xa2,0x00,0x00,0x00,0x26,0x10,0x00,0x01,0x82,0x02,0x00,0x00,
-0x92,0x03,0x00,0x00,0x10,0x48,0x00,0x0c,0x24,0x05,0x00,0x20,0x24,0xc6,0x00,0x01,
-0x10,0xc7,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x03,0x16,0x00,0x14,0x40,0xff,0xe7,
-0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x27,0x82,0x8b,0x88,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x26,0x10,0x00,0x01,0x82,0x02,0x00,0x00,
-0x92,0x03,0x00,0x00,0x10,0x45,0xff,0xfc,0x00,0x00,0x00,0x00,0x08,0x00,0x06,0x5c,
-0x24,0xc6,0x00,0x01,0x00,0x80,0x30,0x21,0x90,0x84,0x00,0x00,0x00,0x00,0x38,0x21,
-0x10,0x80,0x00,0x19,0x24,0xc6,0x00,0x01,0x24,0x82,0xff,0xd0,0x30,0x42,0x00,0xff,
-0x2c,0x43,0x00,0x0a,0x14,0x60,0x00,0x0c,0x00,0x07,0x19,0x00,0x24,0x83,0xff,0x9f,
-0x24,0x82,0xff,0xa9,0x24,0x88,0xff,0xc9,0x2c,0x63,0x00,0x06,0x24,0x84,0xff,0xbf,
-0x2c,0x84,0x00,0x06,0x14,0x60,0x00,0x03,0x30,0x42,0x00,0xff,0x10,0x80,0x00,0x0e,
-0x31,0x02,0x00,0xff,0x00,0x07,0x19,0x00,0x00,0x62,0x18,0x21,0x00,0x67,0x10,0x2b,
-0x14,0x40,0x00,0x07,0x00,0x00,0x20,0x21,0x90,0xc4,0x00,0x00,0x00,0x60,0x38,0x21,
-0x14,0x80,0xff,0xe9,0x24,0xc6,0x00,0x01,0xac,0xa7,0x00,0x00,0x24,0x04,0x00,0x01,
-0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x08,0x00,0x06,0x8c,0x00,0x00,0x20,0x21,
-0x00,0x00,0x20,0x21,0x27,0x85,0x91,0xc0,0x24,0x82,0x00,0x01,0x00,0x04,0x18,0x80,
-0x30,0x44,0x00,0xff,0x00,0x65,0x18,0x21,0x2c,0x82,0x00,0x0b,0x14,0x40,0xff,0xfa,
-0xac,0x60,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0xaf,0x84,0x8c,0x08,
-0xaf,0x85,0x8c,0x0c,0xaf,0x86,0x8c,0x10,0xaf,0x87,0x8c,0x14,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x90,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
-0x2c,0x43,0x00,0x64,0x24,0x42,0x00,0x01,0x27,0x84,0x8b,0xa8,0xaf,0x82,0x84,0x90,
-0x10,0x60,0x00,0x05,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0xaf,0x80,0x84,0x90,0x0c,0x00,0x06,0xf6,
-0x00,0x00,0x00,0x00,0x00,0x40,0x18,0x21,0x28,0x44,0x00,0x08,0x24,0x02,0x00,0x07,
-0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x80,0xff,0xf3,0x24,0x02,0x00,0x08,
-0x27,0x84,0x8b,0xa8,0x14,0x62,0xff,0xf0,0x00,0x00,0x00,0x00,0x0c,0x00,0x17,0xb0,
-0x00,0x00,0x00,0x00,0x27,0x84,0x8b,0xa8,0x0c,0x00,0x07,0x54,0x00,0x00,0x00,0x00,
-0x8f,0x83,0x84,0x94,0x3c,0x04,0x80,0x01,0x00,0x60,0x28,0x21,0x24,0x63,0x00,0x01,
-0xaf,0x83,0x84,0x94,0x0c,0x00,0x17,0x9d,0x24,0x84,0x04,0x88,0x08,0x00,0x06,0xaa,
-0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xbf,0x00,0x38,0x8c,0x85,0x00,0x0c,
-0x8c,0x88,0x00,0x08,0x18,0xa0,0x00,0x0e,0x00,0x00,0x30,0x21,0x24,0x87,0x00,0x08,
-0x27,0xa9,0x00,0x10,0x00,0x06,0x10,0x80,0x00,0x06,0x19,0x00,0x00,0x49,0x10,0x21,
-0x14,0xc0,0x00,0x1f,0x00,0x83,0x18,0x21,0xaf,0xa7,0x00,0x10,0x24,0xc2,0x00,0x01,
-0x30,0x46,0x00,0xff,0x00,0xc5,0x18,0x2a,0x14,0x60,0xff,0xf7,0x00,0x06,0x10,0x80,
-0x29,0x02,0x00,0x0a,0x14,0x40,0x00,0x05,0x00,0x08,0x18,0x40,0x8f,0xbf,0x00,0x38,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x00,0x68,0x18,0x21,
-0x27,0x82,0x83,0x8c,0x00,0x03,0x18,0xc0,0x00,0x62,0x18,0x21,0x8c,0x62,0x00,0x10,
-0x01,0x00,0x20,0x21,0x00,0x40,0xf8,0x09,0x27,0xa6,0x00,0x10,0x8f,0x83,0x84,0xa8,
-0x3c,0x04,0x80,0x01,0x00,0x60,0x28,0x21,0x24,0x63,0x00,0x01,0xaf,0x83,0x84,0xa8,
-0x0c,0x00,0x17,0x9d,0x24,0x84,0x04,0x9c,0x08,0x00,0x06,0xdf,0x00,0x00,0x00,0x00,
-0x08,0x00,0x06,0xd7,0xac,0x43,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb1,0x00,0x14,
-0xaf,0xbf,0x00,0x18,0x00,0x80,0x88,0x21,0x0c,0x00,0x17,0xd4,0xaf,0xb0,0x00,0x10,
-0x00,0x40,0x20,0x21,0x24,0x02,0xff,0xff,0x10,0x82,0x00,0x1f,0x24,0x03,0x00,0x06,
-0x8f,0x85,0x84,0xbc,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x0a,0x24,0x02,0x00,0x08,
-0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x3b,0x28,0x82,0x00,0x03,0x10,0x40,0x00,0x32,
-0x24,0x02,0x00,0x1b,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x13,0x24,0x03,0x00,0x08,
-0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x23,0x24,0x02,0x00,0x0d,0x10,0x82,0x00,0x18,
-0x02,0x25,0x10,0x21,0x24,0xa3,0x00,0x01,0xa0,0x44,0x00,0x00,0xaf,0x83,0x84,0xbc,
-0x18,0x60,0x00,0x08,0x24,0x02,0x00,0x43,0x82,0x23,0x00,0x00,0x00,0x00,0x00,0x00,
-0x10,0x62,0x00,0x0a,0x00,0x00,0x00,0x00,0x30,0x84,0xff,0xff,0x0c,0x00,0x17,0xd0,
-0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x06,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,
-0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x04,0x80,0x01,
-0x0c,0x00,0x17,0xb0,0x24,0x84,0x04,0xb0,0x08,0x00,0x07,0x1e,0x24,0x03,0x00,0x06,
-0xa0,0x40,0x00,0x00,0x24,0xa5,0x00,0x01,0xaf,0x85,0x84,0xbc,0x0c,0x00,0x17,0xd0,
-0x24,0x04,0x00,0x0d,0x24,0x03,0x00,0x07,0xaf,0x80,0x84,0xbc,0x08,0x00,0x07,0x1e,
-0x00,0x00,0x00,0x00,0x18,0xa0,0xff,0xeb,0x24,0xa5,0xff,0xff,0xaf,0x85,0x84,0xbc,
-0x0c,0x00,0x17,0xd0,0x24,0x04,0x00,0x08,0x0c,0x00,0x17,0xd0,0x24,0x04,0x00,0x20,
-0x08,0x00,0x07,0x1b,0x24,0x04,0x00,0x08,0x14,0x82,0xff,0xd2,0x24,0x02,0x00,0x08,
-0x0c,0x00,0x06,0x90,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0xbc,0x08,0x00,0x07,0x0c,
-0x24,0x04,0x00,0x0d,0x0c,0x00,0x2b,0xd1,0x02,0x20,0x20,0x21,0xaf,0x82,0x84,0xbc,
-0x04,0x40,0x00,0x0d,0x00,0x00,0x80,0x21,0x02,0x30,0x10,0x21,0x90,0x44,0x00,0x00,
-0x26,0x10,0x00,0x01,0x00,0x04,0x26,0x00,0x00,0x04,0x26,0x03,0x0c,0x00,0x17,0xd0,
-0x30,0x84,0xff,0xff,0x8f,0x83,0x84,0xbc,0x00,0x00,0x00,0x00,0x00,0x70,0x18,0x2a,
-0x10,0x60,0xff,0xf6,0x02,0x30,0x10,0x21,0x08,0x00,0x07,0x2e,0x24,0x03,0x00,0x06,
-0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x27,0x83,0x8b,0xe8,0x24,0x02,0x00,0x07,
-0x24,0x42,0xff,0xff,0xac,0x60,0x00,0x00,0x04,0x41,0xff,0xfd,0x24,0x63,0x00,0x04,
-0x0c,0x00,0x07,0x66,0x00,0x00,0x00,0x00,0x8f,0x84,0x8b,0xe8,0x27,0x86,0x8b,0xe8,
-0x0c,0x00,0x07,0x83,0x00,0x40,0x28,0x21,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x27,0xbd,0xff,0xe0,0x00,0x80,0x28,0x21,
-0x27,0x84,0x8b,0xc8,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0x0c,0x00,0x2c,0x62,
-0xaf,0xb0,0x00,0x10,0x8f,0x85,0x83,0x2c,0x27,0x84,0x8b,0xc8,0x0c,0x00,0x2c,0x26,
-0x00,0x00,0x88,0x21,0x10,0x40,0x00,0x0c,0x00,0x00,0x00,0x00,0x27,0x90,0x8b,0xe8,
-0x8f,0x85,0x83,0x2c,0x00,0x00,0x20,0x21,0xae,0x02,0x00,0x00,0x0c,0x00,0x2c,0x26,
-0x26,0x31,0x00,0x01,0x26,0x10,0x00,0x04,0x10,0x40,0x00,0x03,0x2a,0x23,0x00,0x64,
-0x14,0x60,0xff,0xf7,0x00,0x00,0x00,0x00,0x02,0x20,0x10,0x21,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd0,
-0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xbf,0x00,0x2c,
-0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,
-0x00,0xa0,0xa8,0x21,0x00,0x80,0xa0,0x21,0x00,0xc0,0xb0,0x21,0x10,0xa0,0x00,0x1d,
-0x24,0x02,0x00,0x05,0x3c,0x02,0x80,0x00,0x24,0x43,0x29,0x1c,0x8f,0x82,0x83,0x9c,
-0x00,0x00,0x00,0x00,0x10,0x43,0x00,0x1e,0x00,0x00,0x88,0x21,0x00,0x60,0x98,0x21,
-0x00,0x00,0x90,0x21,0x27,0x90,0x83,0x9c,0x8e,0x05,0xff,0xec,0x02,0x80,0x20,0x21,
-0x0c,0x00,0x2c,0x6a,0x26,0x10,0x00,0x18,0x10,0x40,0x00,0x06,0x02,0x51,0x18,0x21,
-0x8e,0x02,0x00,0x00,0x26,0x31,0x00,0x01,0x14,0x53,0xff,0xf7,0x00,0x11,0x90,0x40,
-0x02,0x51,0x18,0x21,0x27,0x82,0x83,0x8c,0x00,0x03,0x18,0xc0,0x00,0x62,0x18,0x21,
-0x8c,0x62,0x00,0x10,0x02,0x20,0x20,0x21,0x02,0xa0,0x28,0x21,0x00,0x40,0xf8,0x09,
-0x02,0xc0,0x30,0x21,0x8f,0xbf,0x00,0x2c,0x8f,0xb6,0x00,0x28,0x7b,0xb4,0x01,0x3c,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
-0x08,0x00,0x07,0xa4,0x00,0x00,0x90,0x21,0x27,0xbd,0xff,0xc0,0xaf,0xb5,0x00,0x34,
-0xaf,0xb3,0x00,0x2c,0xaf,0xb1,0x00,0x24,0xaf,0xbf,0x00,0x38,0xaf,0xb4,0x00,0x30,
-0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20,0x00,0xc0,0x98,0x21,0x30,0xa5,0x00,0xff,
-0xac,0xc0,0x00,0x00,0x24,0x15,0x00,0x0a,0x00,0x00,0x88,0x21,0x27,0xa8,0x00,0x10,
-0x00,0x91,0x18,0x21,0x80,0x62,0x00,0x00,0x26,0x27,0x00,0x01,0x10,0x40,0x00,0x0c,
-0x01,0x11,0x30,0x21,0x90,0x63,0x00,0x00,0x30,0xf1,0x00,0xff,0x2e,0x22,0x00,0x0a,
-0x14,0x40,0xff,0xf7,0xa0,0xc3,0x00,0x00,0x8f,0xbf,0x00,0x38,0x7b,0xb4,0x01,0xbc,
-0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,
-0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x23,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x1f,
-0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x1a,0x00,0x00,0x00,0x00,0x02,0x20,0x90,0x21,
-0x12,0x40,0xff,0xf1,0x00,0x00,0x88,0x21,0x27,0xb4,0x00,0x10,0x02,0x91,0x10,0x21,
-0x90,0x44,0x00,0x00,0x0c,0x00,0x08,0x0a,0x00,0x00,0x00,0x00,0x02,0x51,0x20,0x23,
-0x24,0x84,0xff,0xff,0x30,0x84,0x00,0xff,0x02,0xa0,0x28,0x21,0x0c,0x00,0x07,0xfb,
-0x00,0x40,0x80,0x21,0x02,0x02,0x00,0x18,0x8e,0x63,0x00,0x00,0x26,0x22,0x00,0x01,
-0x30,0x51,0x00,0xff,0x02,0x32,0x20,0x2b,0x00,0x00,0x80,0x12,0x00,0x70,0x18,0x21,
-0x14,0x80,0xff,0xee,0xae,0x63,0x00,0x00,0x08,0x00,0x07,0xce,0x00,0x00,0x00,0x00,
-0x80,0x82,0x00,0x00,0x08,0x00,0x07,0xce,0xae,0x62,0x00,0x00,0x08,0x00,0x07,0xdb,
-0x24,0x15,0x00,0x10,0x08,0x00,0x07,0xdb,0x24,0x15,0x00,0x0a,0x30,0x84,0x00,0xff,
-0x30,0xa5,0x00,0xff,0x24,0x06,0x00,0x01,0x10,0x80,0x00,0x09,0x00,0x00,0x10,0x21,
-0x00,0xc5,0x00,0x18,0x24,0x42,0x00,0x01,0x30,0x42,0x00,0xff,0x00,0x44,0x18,0x2b,
-0x00,0x00,0x30,0x12,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xfa,0x00,0xc5,0x00,0x18,
-0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,0x30,0x84,0x00,0xff,0x24,0x83,0xff,0xd0,
-0x30,0x62,0x00,0xff,0x2c,0x42,0x00,0x0a,0x14,0x40,0x00,0x06,0x00,0x00,0x00,0x00,
-0x24,0x82,0xff,0xbf,0x2c,0x42,0x00,0x06,0x14,0x40,0x00,0x02,0x24,0x83,0xff,0xc9,
-0x24,0x83,0xff,0xa9,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xc8,
-0x24,0x02,0x00,0x01,0xaf,0xbf,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,
-0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0x10,0xa2,0x00,0x3e,
-0xaf,0xb0,0x00,0x18,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x08,0x24,0x05,0x00,0x01,
-0x00,0x00,0x10,0x21,0x8f,0xbf,0x00,0x30,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,
-0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x8c,0xc4,0x00,0x04,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x10,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,
-0x28,0x42,0x00,0x65,0x14,0x40,0x00,0x06,0x00,0x00,0x00,0x00,0x3c,0x04,0x80,0x01,
-0x0c,0x00,0x17,0xb0,0x24,0x84,0x04,0xb4,0x08,0x00,0x08,0x25,0x24,0x02,0x00,0x01,
-0x3c,0x04,0x80,0x01,0x0c,0x00,0x17,0xb0,0x24,0x84,0x04,0xc0,0x8f,0x83,0x83,0x9c,
-0x3c,0x02,0x80,0x00,0x24,0x42,0x29,0x1c,0x10,0x62,0xff,0xe5,0x00,0x40,0x90,0x21,
-0x3c,0x13,0x80,0x01,0x27,0x95,0x83,0x88,0x3c,0x14,0x80,0x01,0x27,0x90,0x83,0x8c,
-0x00,0x00,0x88,0x21,0x8e,0x03,0x00,0x08,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,
-0x10,0x62,0x00,0x08,0x26,0x64,0x04,0xcc,0x26,0x10,0x00,0x18,0x8e,0x02,0x00,0x10,
-0x00,0x00,0x00,0x00,0x14,0x52,0xff,0xf7,0x26,0x31,0x00,0x18,0x08,0x00,0x08,0x25,
-0x00,0x00,0x10,0x21,0x0c,0x00,0x17,0xb0,0x00,0x00,0x00,0x00,0x02,0x35,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x0c,0x00,0x17,0xb0,0x00,0x00,0x00,0x00,0x0c,0x00,0x17,0xb0,
-0x26,0x84,0x04,0xd0,0x8e,0x04,0x00,0x00,0x0c,0x00,0x17,0xb0,0x26,0x10,0x00,0x18,
-0x08,0x00,0x08,0x4b,0x00,0x00,0x00,0x00,0x3c,0x04,0x80,0x01,0x0c,0x00,0x17,0xb0,
-0x24,0x84,0x04,0xd4,0x3c,0x04,0x80,0x01,0x0c,0x00,0x17,0x9d,0x24,0x84,0x04,0xe4,
-0x24,0x11,0x00,0x05,0x3c,0x12,0x80,0x01,0x27,0x90,0x88,0x8e,0x86,0x05,0x00,0x00,
-0x26,0x44,0x05,0x04,0x0c,0x00,0x17,0x9d,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xfb,
-0x26,0x10,0xff,0xfe,0x08,0x00,0x08,0x25,0x00,0x00,0x10,0x21,0x27,0xbd,0xff,0xd0,
-0x28,0xa2,0x00,0x02,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x2c,
-0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0x00,0xa0,0x80,0x21,
-0x14,0x40,0x00,0x51,0x00,0xc0,0x88,0x21,0x8c,0xc4,0x00,0x04,0x24,0x05,0x00,0x02,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x10,0x24,0x02,0x00,0x02,0x12,0x02,0x00,0x48,
-0x24,0x05,0x00,0x01,0x8e,0x24,0x00,0x08,0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x14,
-0x8f,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x30,0x42,0x0f,0xff,0xaf,0xa2,0x00,0x14,
-0x7b,0xa4,0x00,0xbc,0x0c,0x00,0x09,0x06,0x24,0x06,0x00,0x04,0x24,0x03,0x00,0x04,
-0x10,0x43,0x00,0x2a,0x24,0x04,0x00,0x04,0x8f,0xa2,0x00,0x10,0x3c,0x04,0x80,0x01,
-0x24,0x84,0x05,0x08,0x00,0x02,0x19,0x02,0x00,0x03,0x81,0x00,0x8f,0xa3,0x00,0x14,
-0x00,0x50,0x10,0x23,0x00,0x02,0x10,0x82,0x00,0x62,0x18,0x21,0x0c,0x00,0x17,0xb0,
-0xaf,0xa3,0x00,0x14,0x3c,0x04,0x80,0x01,0x0c,0x00,0x17,0xb0,0x24,0x84,0x05,0x30,
-0x8f,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x00,0x00,0x88,0x21,
-0x3c,0x13,0x80,0x01,0x3c,0x12,0x80,0x01,0x3c,0x14,0x80,0x01,0x0c,0x00,0x29,0xa1,
-0x24,0x04,0x27,0x10,0x32,0x23,0x00,0x03,0x02,0x00,0x28,0x21,0x10,0x60,0x00,0x1c,
-0x26,0x64,0x05,0x5c,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,0x02,0x02,0x10,0x23,
-0x28,0x42,0xff,0xfd,0x10,0x40,0x00,0x10,0x26,0x44,0x05,0x68,0x0c,0x00,0x17,0xb0,
-0x26,0x10,0x00,0x04,0x8f,0xa2,0x00,0x14,0x26,0x31,0x00,0x01,0x02,0x22,0x10,0x2b,
-0x14,0x40,0xff,0xee,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x21,0x8f,0xbf,0x00,0x2c,
-0x8f,0xb4,0x00,0x28,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x00,0x80,0x10,0x21,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x8e,0x05,0x00,0x00,0x26,0x84,0x05,0x6c,
-0x0c,0x00,0x17,0x9d,0x26,0x10,0x00,0x04,0x08,0x00,0x08,0xb1,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x17,0x9d,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xa9,0x00,0x00,0x00,0x00,
-0x08,0x00,0x08,0x87,0x24,0x02,0x00,0x01,0x0c,0x00,0x0a,0x52,0x00,0x00,0x00,0x00,
-0x08,0x00,0x08,0xb7,0x24,0x04,0x00,0x04,0x27,0xbd,0xff,0xd0,0x28,0xa2,0x00,0x03,
-0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0xaf,0xbf,0x00,0x28,0x00,0xa0,0x88,0x21,
-0x10,0x40,0x00,0x09,0x00,0xc0,0x80,0x21,0x0c,0x00,0x0a,0x52,0x00,0x00,0x00,0x00,
-0x24,0x04,0x00,0x04,0x8f,0xbf,0x00,0x28,0x7b,0xb0,0x01,0x3c,0x00,0x80,0x10,0x21,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x8c,0xc4,0x00,0x04,0x24,0x05,0x00,0x02,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x10,0x8e,0x04,0x00,0x08,0x24,0x05,0x00,0x02,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x14,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x1b,
-0x24,0x05,0x00,0x01,0x8e,0x04,0x00,0x0c,0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x18,
-0x8f,0xa4,0x00,0x10,0x8f,0xa5,0x00,0x18,0x0c,0x00,0x09,0x06,0x24,0x06,0x00,0x04,
-0x24,0x03,0x00,0x04,0x10,0x43,0xff,0xe7,0x24,0x04,0x00,0x04,0x8f,0xa2,0x00,0x18,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b,0x00,0x00,0x28,0x21,0x8f,0xa2,0x00,0x10,
-0x8f,0xa4,0x00,0x14,0x24,0xa5,0x00,0x01,0xac,0x44,0x00,0x00,0x8f,0xa3,0x00,0x10,
-0x8f,0xa2,0x00,0x18,0x24,0x63,0x00,0x04,0x00,0xa2,0x10,0x2b,0x14,0x40,0xff,0xf7,
-0xaf,0xa3,0x00,0x10,0x08,0x00,0x08,0xd9,0x00,0x00,0x20,0x21,0x24,0x02,0x00,0x01,
-0x08,0x00,0x08,0xec,0xaf,0xa2,0x00,0x18,0x30,0xc6,0x00,0xff,0x00,0xa6,0x00,0x18,
-0x00,0x00,0x28,0x12,0x04,0x81,0x00,0x07,0x00,0x00,0x30,0x21,0x3c,0x02,0x80,0x01,
-0x00,0x85,0x18,0x21,0x34,0x42,0x7f,0xff,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x0b,
-0x3c,0x02,0xb0,0x03,0x3c,0x02,0xaf,0xff,0x34,0x42,0xff,0xff,0x00,0x44,0x10,0x2b,
-0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x0a,0x00,0x85,0x18,0x21,0x34,0x42,0xff,0xff,
-0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0xff,0xff,
-0x00,0x44,0x10,0x2b,0x10,0x40,0x00,0x06,0x3c,0x02,0xb0,0x07,0x3c,0x02,0xb0,0x04,
-0x34,0x42,0xff,0xff,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x09,0x3c,0x02,0xb0,0x07,
-0x34,0x42,0x00,0x3f,0x00,0x44,0x10,0x2b,0x10,0x40,0x00,0x06,0x3c,0x02,0xb0,0x07,
-0x34,0x42,0xff,0xff,0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x02,0x00,0x00,0x00,0x00,
-0x24,0x06,0x00,0x01,0x14,0xc0,0x00,0x11,0x24,0x02,0x00,0x04,0x3c,0x02,0xb0,0x08,
-0x34,0x42,0x0f,0xff,0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x08,0x3c,0x02,0x4f,0xf7,
-0x00,0x85,0x20,0x21,0x34,0x42,0xf0,0x00,0x00,0x82,0x20,0x21,0x34,0x03,0xef,0xff,
-0x00,0x64,0x18,0x2b,0x14,0x60,0x00,0x02,0x00,0x00,0x00,0x00,0x24,0x06,0x00,0x02,
-0x10,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe0,0x24,0x02,0x00,0x02,0xaf,0xb0,0x00,0x18,
-0xaf,0xbf,0x00,0x1c,0x10,0xa2,0x00,0x23,0x00,0xc0,0x80,0x21,0x28,0xa2,0x00,0x03,
-0x10,0x40,0x00,0x0c,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x04,
-0x00,0x00,0x18,0x21,0x0c,0x00,0x0a,0x52,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,
-0x8f,0xbf,0x00,0x1c,0x8f,0xb0,0x00,0x18,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x14,0xa2,0xff,0xf7,0x24,0x05,0x00,0x01,0x8c,0xc4,0x00,0x04,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x10,0x8e,0x04,0x00,0x08,0x24,0x05,0x00,0x02,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x14,0x8f,0xa4,0x00,0x10,0x00,0x00,0x00,0x00,
-0x2c,0x82,0x00,0x0b,0x10,0x40,0xff,0xee,0x24,0x03,0x00,0x04,0x00,0x04,0x10,0x80,
-0x8f,0xa4,0x00,0x14,0x27,0x83,0x91,0xc0,0x00,0x43,0x10,0x21,0x08,0x00,0x09,0x4f,
-0xac,0x44,0x00,0x00,0x8c,0xc4,0x00,0x04,0x24,0x05,0x00,0x01,0x0c,0x00,0x07,0xb6,
-0x27,0xa6,0x00,0x10,0x8f,0xa5,0x00,0x10,0x27,0x83,0x91,0xc0,0x3c,0x04,0x80,0x01,
-0x00,0x05,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x46,0x00,0x00,0x0c,0x00,0x17,0x9d,
-0x24,0x84,0x05,0x74,0x08,0x00,0x09,0x50,0x00,0x00,0x18,0x21,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x8f,0x82,0x92,0x10,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
-0x8c,0x45,0x00,0x24,0x3c,0x04,0x80,0x01,0x0c,0x00,0x17,0x9d,0x24,0x84,0x05,0x88,
-0x8f,0x83,0x92,0x10,0x3c,0x04,0x80,0x01,0x8c,0x65,0x00,0x28,0x0c,0x00,0x17,0x9d,
-0x24,0x84,0x05,0x9c,0x8f,0x83,0x92,0x10,0x3c,0x04,0x80,0x01,0x8c,0x65,0x00,0x2c,
-0x0c,0x00,0x17,0x9d,0x24,0x84,0x05,0xb0,0x8f,0x83,0x92,0x10,0x3c,0x04,0x80,0x01,
-0x8c,0x65,0x00,0x30,0x0c,0x00,0x17,0x9d,0x24,0x84,0x05,0xc4,0x8f,0x83,0x92,0x10,
-0x3c,0x04,0x80,0x01,0x8c,0x65,0x00,0x34,0x0c,0x00,0x17,0x9d,0x24,0x84,0x05,0xd8,
-0x8f,0x83,0x92,0x10,0x3c,0x04,0x80,0x01,0x8c,0x65,0x00,0x38,0x0c,0x00,0x17,0x9d,
-0x24,0x84,0x05,0xec,0x8f,0x83,0x92,0x10,0x3c,0x04,0x80,0x01,0x8c,0x65,0x00,0x3c,
-0x0c,0x00,0x17,0x9d,0x24,0x84,0x05,0xfc,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x27,0xbd,0xff,0xb8,0x28,0xa5,0x00,0x04,0xaf,0xb0,0x00,0x20,0xaf,0xbf,0x00,0x40,
-0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,
-0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb1,0x00,0x24,0x10,0xa0,0x00,0x0b,
-0x00,0xc0,0x80,0x21,0x0c,0x00,0x0a,0x52,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,
-0x8f,0xbf,0x00,0x40,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,
-0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8c,0xc4,0x00,0x04,
-0x24,0x05,0x00,0x01,0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x10,0x8e,0x04,0x00,0x08,
-0x24,0x05,0x00,0x01,0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x14,0x8e,0x04,0x00,0x0c,
-0x24,0x05,0x00,0x01,0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x18,0x8f,0xa3,0x00,0x18,
-0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x3a,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x33,
-0x3c,0x04,0x80,0x01,0x97,0xb0,0x00,0x12,0x8f,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,
-0x02,0x02,0x10,0x2b,0x10,0x40,0xff,0xe2,0x3c,0x15,0x80,0x01,0x3c,0x02,0x80,0x01,
-0x24,0x52,0x06,0x3c,0x3c,0x14,0xb0,0x06,0x24,0x13,0x00,0x01,0x3c,0x17,0xb0,0x08,
-0x3c,0x16,0x80,0x01,0x32,0x02,0x00,0x01,0x02,0x00,0x28,0x21,0x10,0x40,0x00,0x1f,
-0x26,0xa4,0x06,0x30,0x8f,0xa3,0x00,0x18,0x00,0x10,0x10,0xc0,0x00,0x54,0x10,0x21,
-0x10,0x60,0x00,0x14,0x02,0x40,0x20,0x21,0x00,0x10,0x10,0xc0,0x00,0x57,0x10,0x21,
-0x10,0x73,0x00,0x09,0x26,0xc4,0x06,0x44,0x8f,0xa2,0x00,0x14,0x26,0x03,0x00,0x01,
-0x30,0x70,0xff,0xff,0x02,0x02,0x10,0x2b,0x14,0x40,0xff,0xee,0x00,0x00,0x00,0x00,
-0x08,0x00,0x09,0xb4,0x00,0x00,0x00,0x00,0x8c,0x51,0x00,0x00,0x00,0x00,0x00,0x00,
-0x32,0x25,0x00,0xff,0x0c,0x00,0x17,0x9d,0x00,0x00,0x00,0x00,0x08,0x00,0x09,0xe6,
-0x00,0x00,0x00,0x00,0x8c,0x51,0x00,0x00,0x0c,0x00,0x17,0x9d,0x00,0x11,0x2c,0x02,
-0x32,0x25,0x00,0xff,0x08,0x00,0x09,0xf1,0x02,0x40,0x20,0x21,0x0c,0x00,0x17,0x9d,
-0x00,0x00,0x00,0x00,0x08,0x00,0x09,0xdd,0x00,0x00,0x00,0x00,0x24,0x84,0x06,0x10,
-0x0c,0x00,0x17,0xb0,0x00,0x00,0x00,0x00,0x08,0x00,0x09,0xcd,0x00,0x00,0x00,0x00,
-0x3c,0x04,0x80,0x01,0x08,0x00,0x0a,0x00,0x24,0x84,0x06,0x50,0x00,0xa0,0x10,0x21,
-0x27,0xbd,0xff,0xd8,0x28,0x42,0x00,0x04,0xaf,0xb0,0x00,0x20,0xaf,0xbf,0x00,0x24,
-0x00,0xc0,0x80,0x21,0x24,0x05,0x00,0x01,0x10,0x40,0x00,0x08,0x27,0xa6,0x00,0x10,
-0x0c,0x00,0x0a,0x52,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x24,
-0x8f,0xb0,0x00,0x20,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x8e,0x04,0x00,0x04,
-0x0c,0x00,0x07,0xb6,0x00,0x00,0x00,0x00,0x8e,0x04,0x00,0x08,0x24,0x05,0x00,0x01,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x14,0x8e,0x04,0x00,0x0c,0x24,0x05,0x00,0x01,
-0x0c,0x00,0x07,0xb6,0x27,0xa6,0x00,0x18,0x08,0x00,0x0a,0x13,0x24,0x02,0x00,0x01,
-0x24,0x03,0x00,0x01,0x00,0x65,0x10,0x2a,0x27,0xbd,0xff,0xd8,0x00,0xa0,0x40,0x21,
-0x10,0x40,0x00,0x0b,0x00,0xc0,0x38,0x21,0x00,0x03,0x20,0x80,0x00,0x87,0x10,0x21,
-0x8c,0x45,0x00,0x00,0x24,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x8c,0xa6,0x00,0x00,
-0x00,0x9d,0x20,0x21,0x00,0x68,0x10,0x2a,0x14,0x40,0xff,0xf7,0xac,0x86,0xff,0xfc,
-0x8f,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x0b,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x28,0x93,0xa2,0x00,0x07,0x00,0x00,0x00,0x00,0xa3,0x82,0x87,0xec,
-0x08,0x00,0x0a,0x3b,0x00,0x00,0x00,0x00,0x93,0xa2,0x00,0x07,0x00,0x00,0x00,0x00,
-0xa3,0x82,0x91,0xb0,0x08,0x00,0x0a,0x3b,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,
-0x3c,0x04,0x80,0x01,0xaf,0xbf,0x00,0x10,0x18,0xa0,0x00,0x03,0x24,0x84,0x06,0x78,
-0x0c,0x00,0x17,0xb0,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x24,0x02,0x00,0x01,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x27,0xbd,0xff,0xe8,0xaf,0xb0,0x00,0x10,
-0x00,0x80,0x80,0x21,0x3c,0x04,0x80,0x01,0xaf,0xbf,0x00,0x14,0x0c,0x00,0x17,0xb0,
-0x24,0x84,0x06,0x8c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21,0x27,0x83,0x83,0x88,
-0x00,0x02,0x10,0xc0,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08,0x0c,0x00,0x17,0xb0,
-0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe8,
-0x34,0x63,0x00,0x20,0x24,0x42,0x29,0x94,0x3c,0x04,0xb0,0x03,0xaf,0xbf,0x00,0x14,
-0xac,0x62,0x00,0x00,0xaf,0xb0,0x00,0x10,0x34,0x84,0x00,0x2c,0x8c,0x83,0x00,0x00,
-0xa7,0x80,0xc2,0x40,0x00,0x03,0x12,0x02,0x00,0x03,0x2d,0x02,0x30,0x42,0x0f,0xff,
-0xa3,0x83,0xc2,0x48,0xa7,0x85,0xc2,0x4c,0xa7,0x82,0xc2,0x4a,0xa7,0x80,0xc2,0x42,
-0xa7,0x80,0xc2,0x44,0xa7,0x80,0xc2,0x46,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x05,0x00,
-0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,0x0c,0x00,0x0b,0xed,
-0x00,0x40,0x80,0x21,0x3c,0x02,0xf7,0xff,0x34,0x42,0xff,0xff,0x02,0x02,0x80,0x24,
-0x02,0x00,0x28,0x21,0x0c,0x00,0x0b,0xed,0x24,0x04,0x05,0x00,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0xb0,0x03,0x34,0x42,0x01,0x08,0x34,0x63,0x01,0x18,0x8c,0x45,0x00,0x00,
-0x8c,0x64,0x00,0x00,0x3c,0x02,0x00,0x0f,0x3c,0x03,0x00,0x4c,0x30,0x84,0x02,0x00,
-0x34,0x63,0x4b,0x40,0xaf,0x85,0xc2,0x50,0x10,0x80,0x00,0x06,0x34,0x42,0x42,0x40,
-0xaf,0x83,0xc2,0x54,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0xaf,0x82,0xc2,0x54,0x08,0x00,0x0a,0x95,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x34,0x63,0x00,0x20,
-0x24,0x42,0x2a,0x70,0x30,0x84,0x00,0xff,0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c,
-0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00,
-0x10,0x80,0x00,0x1c,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x08,0x00,0x00,0x00,0x00,
-0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xa7,0x80,0xc2,0x40,
-0xa7,0x80,0xc2,0x42,0xa7,0x80,0xc2,0x44,0xa7,0x80,0xc2,0x46,0x0c,0x00,0x0b,0xfa,
-0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,
-0x0c,0x00,0x0b,0xed,0x00,0x40,0x80,0x21,0x3c,0x05,0xf7,0xff,0x34,0xa5,0xff,0xff,
-0x02,0x05,0x28,0x24,0x0c,0x00,0x0b,0xed,0x24,0x04,0x05,0x00,0x08,0x00,0x0a,0xb0,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x05,0xa0,0x24,0x04,0x05,0xa4,
-0x0c,0x00,0x0b,0xfa,0x00,0x02,0xbc,0x02,0x24,0x04,0x05,0xa8,0x00,0x02,0xb4,0x02,
-0x0c,0x00,0x0b,0xfa,0x30,0x55,0xff,0xff,0x00,0x40,0x80,0x21,0x97,0x84,0xc2,0x40,
-0x97,0x82,0xc2,0x42,0x97,0x83,0xc2,0x46,0x02,0xe4,0x20,0x23,0x02,0xa2,0x10,0x23,
-0x00,0x82,0x20,0x21,0x97,0x82,0xc2,0x44,0x32,0x14,0xff,0xff,0x02,0x83,0x18,0x23,
-0x02,0xc2,0x10,0x23,0x00,0x82,0x20,0x21,0x93,0x82,0xc2,0x48,0x00,0x83,0x20,0x21,
-0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b,0x14,0x40,0x00,0xaa,0x00,0x00,0x00,0x00,
-0x97,0x82,0xc2,0x4c,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x7f,
-0x00,0x00,0x00,0x00,0x97,0x82,0xc2,0x4a,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,
-0x10,0x40,0x00,0x3a,0x00,0x00,0x00,0x00,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x04,0x50,
-0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,0x10,0x40,0x00,0x13,
-0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x17,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,
-0x26,0x31,0x00,0x01,0x00,0x51,0x80,0x25,0x02,0x00,0x28,0x21,0x0c,0x00,0x0b,0xed,
-0x24,0x04,0x04,0x50,0x02,0x00,0x28,0x21,0x0c,0x00,0x0b,0xed,0x24,0x04,0x04,0x58,
-0x02,0x00,0x28,0x21,0x0c,0x00,0x0b,0xed,0x24,0x04,0x04,0x60,0x02,0x00,0x28,0x21,
-0x24,0x04,0x04,0x68,0x0c,0x00,0x0b,0xed,0x00,0x00,0x00,0x00,0xa7,0x97,0xc2,0x40,
-0xa7,0x95,0xc2,0x42,0xa7,0x96,0xc2,0x44,0xa7,0x94,0xc2,0x46,0x08,0x00,0x0a,0xb0,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,
-0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,
-0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
-0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x0b,0xed,0x24,0x04,0x02,0x08,
-0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,
-0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x0c,0x00,0x0b,0xed,
-0x24,0x04,0x02,0x2c,0x08,0x00,0x0a,0xf7,0x24,0x02,0xff,0x80,0x0c,0x00,0x0b,0xfa,
-0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0xdb,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,
-0x02,0x40,0x28,0x21,0x0c,0x00,0x0b,0xed,0x24,0x04,0x02,0x2c,0x0c,0x00,0x0b,0xfa,
-0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,0x0c,0x00,0x0b,0xfa,0x00,0x02,0x9e,0x02,
-0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,
-0x14,0x60,0x00,0x1d,0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,
-0x24,0x04,0x02,0x2c,0x0c,0x00,0x0b,0xed,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,
-0x08,0x00,0x0b,0x05,0x24,0x04,0x02,0x2c,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x08,
-0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,
-0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xee,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
-0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x0b,0xed,0x24,0x04,0x02,0x08,
-0x08,0x00,0x0b,0x41,0x3c,0x02,0xff,0xff,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x08,
-0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,
-0x14,0x43,0xff,0xdf,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,
-0x3c,0x03,0x00,0x80,0x08,0x00,0x0b,0x56,0x00,0x43,0x28,0x25,0x0c,0x00,0x0b,0xfa,
-0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,
-0x10,0x40,0xff,0x9a,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x04,0x24,0x02,0xff,0x80,
-0x02,0x02,0x10,0x24,0x08,0x00,0x0a,0xf9,0x26,0x31,0x00,0x02,0x0c,0x00,0x0b,0xfa,
-0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,
-0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
-0x0c,0x00,0x0b,0xed,0x24,0x04,0x02,0x08,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x2c,
-0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,
-0x02,0x40,0x28,0x21,0x0c,0x00,0x0b,0xed,0x24,0x04,0x02,0x2c,0x08,0x00,0x0b,0x70,
-0x24,0x02,0xff,0x80,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x04,0x50,0x00,0x40,0x80,0x21,
-0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x1d,0x2e,0x22,0x00,0x21,
-0x14,0x40,0xff,0x72,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x26,0x31,0xff,0xff,
-0x00,0x51,0x80,0x25,0x24,0x04,0x04,0x50,0x0c,0x00,0x0b,0xed,0x02,0x00,0x28,0x21,
-0x24,0x04,0x04,0x58,0x0c,0x00,0x0b,0xed,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x60,
-0x0c,0x00,0x0b,0xed,0x02,0x00,0x28,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x0b,0xed,
-0x24,0x04,0x04,0x68,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0x60,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,
-0x34,0x42,0x3f,0xff,0x02,0x42,0x10,0x24,0x08,0x00,0x0b,0x47,0x34,0x52,0x80,0x00,
-0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,
-0x0c,0x00,0x0b,0xed,0x24,0x04,0x02,0x2c,0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x58,
-0x24,0x04,0x02,0x5c,0x0c,0x00,0x0b,0xfa,0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,
-0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x20,
-0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,
-0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,
-0x0c,0x00,0x0b,0xed,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x0b,0xed,
-0x24,0x04,0x02,0x2c,0x08,0x00,0x0b,0x94,0x2e,0x22,0x00,0x21,0x0c,0x00,0x0b,0xfa,
-0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,
-0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xec,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
-0x0c,0x00,0x0b,0xed,0x24,0x04,0x02,0x08,0x08,0x00,0x0b,0xc4,0x3c,0x02,0xff,0xff,
-0x0c,0x00,0x0b,0xfa,0x24,0x04,0x02,0x08,0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,
-0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,0x14,0x43,0xff,0xdc,0x3c,0x03,0x00,0x80,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x08,0x00,0x0b,0xdc,
-0x00,0x43,0x28,0x25,0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23,
-0x3c,0x02,0xb0,0x0a,0x00,0x82,0x20,0x21,0xac,0x85,0x00,0x00,0x00,0x00,0x18,0x21,
-0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a,0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,
-0x03,0xe0,0x00,0x08,0x24,0x63,0xff,0xff,0x30,0x86,0x00,0x03,0x00,0x04,0x28,0x40,
-0x3c,0x03,0xb0,0x0a,0x00,0xa6,0x10,0x23,0x00,0x43,0x10,0x21,0x24,0x04,0xff,0xff,
-0xac,0x44,0x10,0x00,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a,
-0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,0x24,0x63,0xff,0xff,0x00,0xa6,0x18,0x23,
-0x3c,0x02,0xb0,0x0a,0x00,0x62,0x18,0x21,0x8c,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x30,0x34,
-0x24,0x03,0x00,0x01,0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00,
-0x34,0xc6,0x01,0x04,0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
-0xa0,0x80,0x00,0x06,0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09,
-0xa0,0x80,0x00,0x0a,0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49,
-0x94,0xc2,0x00,0x00,0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x24,0x00,0x02,0x14,0x00,
-0x00,0x02,0x14,0x03,0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x83,0x00,0x46,
-0xa4,0x82,0x00,0x44,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xac,0x80,0x00,0x30,
-0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c,0x03,0xe0,0x00,0x08,
-0xac,0x80,0x00,0x40,0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x44,
-0x00,0x43,0x10,0x21,0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00,0x24,0x42,0x30,0xc4,
-0xac,0xe2,0x00,0x00,0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13,0x00,0x05,0x2c,0x00,
-0x00,0x03,0x1e,0x02,0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e,0x00,0x62,0x18,0x21,
-0x00,0x65,0x18,0x21,0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05,0x34,0x42,0x04,0x00,
-0x24,0x63,0x00,0x01,0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05,0x34,0xa5,0x04,0x20,
-0xac,0xa3,0x00,0x00,0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24,0x35,0x08,0x02,0x28,
-0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00,0xac,0x82,0x00,0x3c,
-0x03,0xe0,0x00,0x08,0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xc0,0x00,0x07,0x60,0x80,
-0x27,0x82,0xba,0x40,0xaf,0xb7,0x00,0x34,0xaf,0xb5,0x00,0x2c,0xaf,0xb3,0x00,0x24,
-0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38,0xaf,0xb6,0x00,0x30,0xaf,0xb4,0x00,0x28,
-0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x01,0x82,0x10,0x21,
-0x8c,0x43,0x00,0x00,0x3c,0x07,0xb0,0x03,0x3c,0x02,0x80,0x00,0x94,0x71,0x00,0x14,
-0x34,0xe7,0x00,0x20,0x24,0x42,0x31,0x58,0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00,
-0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00,0x00,0x11,0xa8,0xc0,0x02,0xb1,0x18,0x21,
-0x27,0x82,0x96,0x44,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00,
-0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03,0x00,0xc0,0x98,0x21,0xaf,0xa4,0x00,0x40,
-0x00,0x05,0x6c,0x03,0x8c,0x68,0x00,0x18,0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x4f,
-0x00,0x07,0xbe,0x03,0x00,0xd7,0x10,0x07,0x30,0x57,0x00,0x01,0x01,0x71,0x10,0x21,
-0x27,0x83,0x96,0x48,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x80,0x4e,0x00,0x06,
-0x8d,0x03,0x00,0x00,0x8d,0x0f,0x00,0x04,0x8d,0x0a,0x00,0x08,0x8d,0x10,0x00,0x0c,
-0x11,0xc0,0x00,0x1c,0x00,0x00,0xa0,0x21,0x27,0x82,0xba,0x40,0x01,0x82,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,
-0x30,0x63,0x00,0x04,0x14,0x60,0x00,0x13,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46,
-0x90,0x43,0x00,0x00,0x2a,0x64,0x00,0x04,0x10,0x80,0x01,0x26,0x30,0x65,0x00,0x01,
-0x8f,0xa3,0x00,0x40,0x00,0x00,0x00,0x00,0x90,0x62,0x00,0x09,0x00,0x00,0x00,0x00,
-0x12,0x62,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,
-0x00,0x00,0x38,0x21,0x12,0xe0,0x00,0x03,0x38,0xf4,0x00,0x01,0x24,0x07,0x00,0x01,
-0x38,0xf4,0x00,0x01,0x01,0x71,0x10,0x21,0x00,0x02,0x38,0x80,0x27,0x83,0x96,0x50,
-0x00,0xe3,0x48,0x21,0x91,0x25,0x00,0x00,0x00,0x0f,0x11,0xc3,0x2c,0xa3,0x00,0x04,
-0x00,0x03,0xa0,0x0b,0x12,0x80,0x00,0xc7,0x30,0x52,0x00,0x01,0x93,0x88,0xc2,0x2a,
-0x00,0x0a,0x16,0x42,0x30,0x4a,0x00,0x3f,0x2d,0x06,0x00,0x0c,0x10,0xc0,0x00,0xaf,
-0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04,0x00,0x88,0x10,0x2b,
-0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x88,0x10,0x2b,0x10,0x40,0x00,0x0b,
-0x01,0x71,0x10,0x21,0x27,0x85,0xc1,0x5c,0x00,0x08,0x10,0x40,0x00,0x48,0x10,0x21,
-0x00,0x45,0x10,0x21,0x90,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x18,0x2b,
-0x14,0x60,0xff,0xfa,0x00,0x08,0x10,0x40,0x01,0x71,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x96,0x48,0x00,0x43,0x10,0x21,0x31,0xc4,0x00,0x01,0x10,0x80,0x00,0x94,
-0xa0,0x48,0x00,0x07,0x24,0x0d,0x00,0x0e,0x24,0x11,0x01,0x06,0x27,0x82,0xba,0x40,
-0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x16,0x00,0x01,0x00,0x11,0xa8,0xc0,
-0x90,0x62,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x04,0xa0,0x62,0x00,0x16,
-0x00,0x0f,0x1b,0x43,0x30,0x7e,0x00,0x01,0x00,0x0a,0x10,0x40,0x00,0x12,0x19,0xc0,
-0x00,0x5e,0x10,0x21,0x00,0x08,0x22,0x00,0x00,0x43,0x10,0x21,0x00,0x44,0x10,0x21,
-0x00,0x0d,0x1c,0x00,0x00,0x10,0x82,0x02,0x01,0x00,0x28,0x21,0x00,0x00,0x20,0x21,
-0x00,0x43,0x90,0x21,0x0c,0x00,0x01,0xdd,0x32,0x10,0x07,0xff,0x00,0x16,0x12,0x80,
-0x00,0x10,0x84,0x80,0x02,0x22,0x10,0x21,0x00,0x50,0x10,0x21,0x3c,0x03,0xc0,0x00,
-0x16,0x60,0x00,0x2b,0x00,0x43,0x80,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x00,
-0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x52,0x00,0x00,0x34,0x63,0x04,0x04,
-0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x01,0xac,0x70,0x00,0x00,0xa0,0x82,0x00,0x00,
-0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00,0x8f,0xa2,0x00,0x40,
-0x30,0x86,0x00,0x01,0x90,0x43,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x63,0x18,0x26,
-0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21,0x12,0xe0,0x00,0x03,
-0x02,0xb1,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb1,0x10,0x21,0x27,0x83,0x96,0x48,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04,0x00,0xa0,0x30,0x21,
-0x03,0xc0,0x20,0x21,0x02,0x60,0x28,0x21,0x02,0x80,0x38,0x21,0x0c,0x00,0x00,0x70,
-0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,
-0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x3d,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x02,
-0x12,0x62,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03,0x12,0x62,0x00,0x25,
-0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x62,0x00,0x19,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x11,0x12,0x62,0x00,0x0d,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x12,
-0x16,0x62,0xff,0xcf,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05,0x34,0x42,0x04,0x20,
-0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x52,0x00,0x00,0x34,0x84,0x02,0x28,
-0xac,0x70,0x00,0x00,0x08,0x00,0x0c,0xf7,0x24,0x02,0x00,0x20,0x34,0x42,0x04,0x40,
-0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x52,0x00,0x00,0x34,0x63,0x04,0x44,
-0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x0c,0xf7,0xac,0x70,0x00,0x00,
-0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x52,0x00,0x00,
-0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80,0x08,0x00,0x0c,0xf7,
-0xac,0x70,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,
-0xac,0x52,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x08,
-0x08,0x00,0x0c,0xf7,0xac,0x70,0x00,0x00,0x34,0x42,0x04,0x10,0x3c,0x03,0xb0,0x05,
-0x3c,0x04,0xb0,0x05,0xac,0x52,0x00,0x00,0x34,0x63,0x04,0x14,0x34,0x84,0x02,0x28,
-0x24,0x02,0x00,0x04,0x08,0x00,0x0c,0xf7,0xac,0x70,0x00,0x00,0x34,0x42,0x04,0x08,
-0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x52,0x00,0x00,0x34,0x63,0x04,0x0c,
-0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x0c,0xf7,0xac,0x70,0x00,0x00,
-0x24,0x0d,0x00,0x14,0x08,0x00,0x0c,0xcf,0x24,0x11,0x01,0x02,0x30,0xa2,0x00,0x07,
-0x24,0x44,0x00,0x0c,0x00,0x88,0x18,0x2b,0x10,0x60,0x00,0x0c,0x25,0x02,0x00,0x04,
-0x27,0x85,0xc1,0x5c,0x00,0x08,0x10,0x40,0x00,0x48,0x10,0x21,0x00,0x45,0x10,0x21,
-0x90,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x18,0x2b,0x14,0x60,0xff,0xfa,
-0x00,0x08,0x10,0x40,0x2d,0x06,0x00,0x0c,0x25,0x02,0x00,0x04,0x08,0x00,0x0c,0xc6,
-0x00,0x46,0x40,0x0a,0x27,0x82,0xba,0x40,0x01,0x82,0x20,0x21,0x8c,0x86,0x00,0x00,
-0x00,0x00,0x00,0x00,0x90,0xc2,0x00,0x19,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,
-0x00,0x00,0x00,0x00,0x27,0x82,0x96,0x60,0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x12,0x00,0x00,0x00,0x00,0x90,0xc3,0x00,0x16,
-0x27,0x82,0x96,0x48,0x00,0xe2,0x10,0x21,0x34,0x63,0x00,0x20,0x90,0x48,0x00,0x07,
-0xa0,0xc3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x16,0x42,0x30,0x4a,0x00,0x3f,
-0x90,0x83,0x00,0x16,0x24,0x0d,0x00,0x18,0x24,0x11,0x01,0x03,0x30,0x63,0x00,0xfb,
-0x24,0x16,0x00,0x01,0x24,0x15,0x08,0x18,0x08,0x00,0x0c,0xd8,0xa0,0x83,0x00,0x16,
-0x8d,0x02,0x00,0x04,0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10,0x14,0x40,0x00,0x15,
-0x30,0x6a,0x00,0x3f,0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x11,
-0x30,0x6a,0x00,0x3e,0x27,0x83,0x96,0x58,0x00,0xe3,0x18,0x21,0x80,0x64,0x00,0x00,
-0x27,0x83,0xbb,0xb8,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x05,
-0x90,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24,0x30,0x63,0x00,0x01,
-0x01,0x43,0x50,0x25,0x27,0x85,0xba,0x40,0x01,0x85,0x28,0x21,0x8c,0xa6,0x00,0x00,
-0x01,0x71,0x10,0x21,0x27,0x83,0x96,0x50,0x90,0xc4,0x00,0x16,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x30,0x84,0x00,0xdf,0x90,0x48,0x00,0x00,0xa0,0xc4,0x00,0x16,
-0x8c,0xa3,0x00,0x00,0x80,0xd6,0x00,0x12,0x90,0x62,0x00,0x16,0x08,0x00,0x0c,0xd7,
-0x30,0x42,0x00,0xfb,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xdc,0x00,0x00,0x00,0x00,
-0x8f,0xa3,0x00,0x40,0x00,0x00,0x00,0x00,0x90,0x62,0x00,0x09,0x00,0x00,0x00,0x00,
-0x02,0x62,0x10,0x26,0x08,0x00,0x0c,0x9f,0x00,0x02,0x28,0x0b,0x24,0x02,0x00,0x10,
-0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0xaf,0x00,0x07,0x17,0x83,
-0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0xad,0x00,0x07,0x17,0x43,0x08,0x00,0x0c,0x7f,
-0x30,0x57,0x00,0x01,0x08,0x00,0x0c,0x7f,0x00,0x07,0xbf,0xc2,0x00,0x04,0x10,0x40,
-0x27,0x83,0x86,0xb0,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21,0x94,0x44,0x00,0x00,
-0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a,0x00,0x86,0x00,0x18,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x37,0x5c,
-0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12,0x00,0x04,0x22,0x42,
-0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b,0x24,0x82,0x00,0x60,
-0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x00,0x44,0x20,0x04,
-0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28,0x24,0x83,0x00,0x24,
-0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14,0x00,0x60,0x20,0x21,
-0x08,0x00,0x0d,0xee,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x37,0xf8,0x00,0x80,0x80,0x21,
-0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37,0x34,0x84,0x01,0x10,
-0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21,0x8c,0x87,0x00,0x00,
-0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f,0x34,0x42,0xf0,0x00,
-0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08,0x32,0x02,0x00,0x07,
-0x27,0x83,0x87,0x60,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,
-0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21,0x32,0x02,0x00,0x0f,
-0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x07,
-0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xba,0x90,0x00,0x43,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c,0x14,0x40,0x00,0x05,
-0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21,
-0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20,0x24,0x06,0x00,0x0e,
-0x0c,0x00,0x0d,0xd7,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04,0x24,0x02,0x00,0x10,
-0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01,0x14,0x60,0x00,0x02,
-0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff,0x00,0xc5,0x10,0x21,
-0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00,0x8f,0xbf,0x00,0x1c,
-0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c,0x32,0x02,0x00,0x07,
-0x27,0x83,0x87,0x58,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x08,0x00,0x0e,0x1c,
-0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80,0x27,0x82,0xba,0x40,
-0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb4,0x00,0x30,0xaf,0xbf,0x00,0x44,
-0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,
-0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21,0x8c,0xe6,0x00,0x00,
-0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x39,0x54,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0xa0,0xc3,0x00,0x12,
-0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16,0xa4,0xc3,0x00,0x14,
-0x27,0x83,0x96,0x40,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16,0x8c,0xe8,0x00,0x00,
-0xaf,0xa4,0x00,0x48,0x27,0x82,0x96,0x44,0x95,0x11,0x00,0x14,0x00,0x00,0x00,0x00,
-0x00,0x11,0xa0,0xc0,0x02,0x91,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x82,0x10,0x21,
-0x8c,0x53,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06,0x8e,0x65,0x00,0x08,
-0x8e,0x66,0x00,0x04,0x8e,0x67,0x00,0x04,0x00,0x05,0x1c,0x82,0x00,0x06,0x31,0x42,
-0x27,0x82,0x96,0x50,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01,0x00,0x82,0x20,0x21,
-0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18,0xaf,0xa6,0x00,0x1c,
-0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06,0x14,0xe0,0x00,0x42,
-0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3f,
-0x02,0x91,0x10,0x21,0x93,0x90,0xc2,0x29,0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c,
-0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40,0x00,0x43,0x10,0x21,
-0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04,0x02,0x91,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x50,0x00,0x43,0x10,0x21,0x00,0x80,0x80,0x21,
-0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,
-0x0c,0x00,0x0d,0xd7,0x02,0xa0,0x30,0x21,0x02,0x91,0x18,0x21,0x00,0x03,0x88,0x80,
-0x00,0x40,0x90,0x21,0x27,0x82,0x96,0x60,0x02,0x22,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x04,0x25,0xc2,
-0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40,0x03,0xc4,0x20,0x24,
-0x14,0x80,0x00,0x10,0x02,0x63,0x38,0x21,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48,
-0x27,0x82,0x96,0x48,0x02,0x22,0x10,0x21,0x02,0xa0,0x28,0x21,0xa4,0x52,0x00,0x04,
-0x0c,0x00,0x0c,0x56,0x00,0xc0,0x38,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,
-0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c,0x8f,0xa6,0x00,0x18,0x02,0x00,0x20,0x21,
-0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x0d,0xfe,0xaf,0xa0,0x00,0x14,
-0x08,0x00,0x0e,0xba,0x02,0x42,0x90,0x21,0x02,0x91,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x96,0x50,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x08,0x00,0x0e,0xa6,
-0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8,0xaf,0xb1,0x00,0x24,0x8f,0xb1,0x00,0x5c,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x3b,0x64,
-0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38,0xaf,0xb5,0x00,0x34,
-0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c,0x8f,0xb5,0x00,0x58,0xaf,0xbf,0x00,0x44,
-0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20,0x00,0xe0,0xb0,0x21,
-0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21,0x00,0x00,0xb8,0x21,0x16,0x20,0x00,0x2b,
-0x00,0x00,0xa0,0x21,0x27,0x85,0xba,0x40,0x00,0x07,0x10,0x80,0x00,0x45,0x10,0x21,
-0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80,0x00,0x65,0x18,0x21,0x92,0x62,0x00,0x16,
-0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x2d,0x00,0x00,0x00,0x00,
-0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x28,
-0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x18,
-0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x14,
-0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0f,
-0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05,0x34,0x63,0x01,0x44,0x34,0xa5,0x02,0x52,
-0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00,0x8f,0xa3,0x00,0x4c,0x00,0x00,0x00,0x00,
-0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x04,0x30,0xc6,0xff,0xff,
-0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09,0x24,0x05,0x00,0x14,0x02,0x20,0x10,0x21,
-0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,
-0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x0c,0x00,0x0c,0x31,
-0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x0f,0x1b,0xa3,0xc2,0x00,0x11,
-0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x17,0x00,0xc0,0x88,0x21,
-0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21,0x12,0x20,0xff,0xed,0x02,0x20,0x10,0x21,
-0x27,0x83,0xba,0x40,0x00,0x17,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28,0x80,0x86,0x00,0x12,0x8c,0x62,0x00,0x00,
-0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03,0x00,0x46,0x10,0x21,0x8f,0xa6,0x00,0x4c,
-0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21,0x0c,0x00,0x0c,0x56,0xac,0x62,0x00,0x00,
-0x08,0x00,0x0f,0x1b,0xaf,0xd1,0x00,0x40,0x96,0x74,0x00,0x1a,0x08,0x00,0x0f,0x2e,
-0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x50,0x00,0x00,
-0x02,0x60,0x20,0x21,0x0c,0x00,0x23,0x25,0x02,0x00,0x28,0x21,0x30,0x42,0x00,0xff,
-0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x23,0x25,0xaf,0xa2,0x00,0x18,
-0x30,0x50,0x00,0xff,0x8f,0xa2,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0xc3,
-0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01,0x96,0x63,0x00,0x14,
-0x96,0x44,0x00,0x14,0x27,0x85,0x96,0x40,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0,0x8c,0x46,0x00,0x08,
-0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x00,0x06,0x17,0x02,
-0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xac,0x00,0x03,0x17,0x02,
-0x10,0x44,0x00,0xab,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b,0x24,0x11,0x00,0x02,
-0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x45,
-0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbc,0x00,0x00,0x00,0x00,0x96,0x49,0x00,0x14,
-0x27,0x82,0x96,0x44,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0,0x01,0x49,0x18,0x21,
-0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42,
-0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x14,0x40,0x00,0x2c,
-0x30,0x87,0x00,0x01,0x27,0x83,0x96,0x58,0x01,0x03,0x18,0x21,0x80,0x64,0x00,0x00,
-0x27,0x83,0xba,0xe0,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x45,0x00,0x00,
-0x00,0x00,0x00,0x00,0x2c,0xa3,0x00,0x0c,0x14,0x60,0x00,0x07,0x01,0x49,0x10,0x21,
-0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0xa2,0x10,0x21,
-0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x50,
-0x00,0x43,0x10,0x21,0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08,
-0x12,0x02,0x00,0x0a,0x24,0x02,0x00,0x01,0x02,0x40,0x20,0x21,0x0c,0x00,0x23,0xa1,
-0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,
-0x02,0x02,0x10,0x25,0x08,0x00,0x0f,0x2e,0xa2,0x42,0x00,0x16,0x02,0x40,0x20,0x21,
-0x0c,0x00,0x23,0x52,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0f,0xa6,0x30,0x54,0xff,0xff,
-0x27,0x82,0x96,0x50,0x01,0x02,0x10,0x21,0x90,0x45,0x00,0x00,0x08,0x00,0x0f,0x9f,
-0xa0,0x45,0x00,0x03,0x96,0x69,0x00,0x14,0x02,0xc0,0xb8,0x21,0x24,0x0b,0x00,0x01,
-0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21,0x00,0x03,0x40,0x80,0x00,0x40,0x50,0x21,
-0x27,0x82,0x96,0x44,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42,
-0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x10,0x40,0x00,0x0d,
-0x30,0x87,0x00,0x01,0x27,0x82,0x96,0x58,0x01,0x02,0x10,0x21,0x80,0x43,0x00,0x00,
-0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xbb,0xb0,0x00,0x43,0x10,0x21,
-0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x3a,0x00,0x00,0x00,0x00,0x01,0x49,0x10,0x21,
-0x00,0x02,0x20,0x80,0x27,0x85,0x96,0x50,0x00,0x85,0x10,0x21,0x80,0x43,0x00,0x05,
-0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x2d,0x01,0x49,0x10,0x21,0x27,0x83,0x96,0x58,
-0x00,0x83,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xba,0xe0,0x00,0x04,0x11,0x00,
-0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x90,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xa3,0x00,0x0c,
-0x14,0x60,0x00,0x07,0x01,0x49,0x10,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,
-0x00,0x02,0x11,0x00,0x00,0xa2,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x50,0x00,0x43,0x10,0x21,0xa0,0x45,0x00,0x03,
-0xa0,0x45,0x00,0x00,0x8f,0xa3,0x00,0x18,0x24,0x02,0x00,0x08,0x10,0x62,0x00,0x0b,
-0x02,0x60,0x20,0x21,0x24,0x02,0x00,0x01,0x0c,0x00,0x23,0xa1,0xaf,0xa2,0x00,0x10,
-0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff,0x92,0x62,0x00,0x16,0x00,0x00,0x00,0x00,
-0x00,0x62,0x10,0x25,0x08,0x00,0x0f,0x2e,0xa2,0x62,0x00,0x16,0x0c,0x00,0x23,0x52,
-0xaf,0xa0,0x00,0x10,0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,
-0x00,0x45,0x10,0x21,0x90,0x45,0x00,0x00,0x08,0x00,0x0f,0xf9,0xa0,0x45,0x00,0x03,
-0x27,0x85,0x96,0x50,0x08,0x00,0x10,0x0b,0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,
-0x00,0x62,0x18,0x26,0x08,0x00,0x0f,0x6a,0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x57,
-0x24,0x02,0x00,0x01,0x08,0x00,0x0f,0x6f,0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,0x24,0x42,0x40,0x6c,0x34,0x63,0x00,0x20,
-0x3c,0x05,0xb0,0x05,0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,
-0xaf,0xbf,0x00,0x28,0xaf,0xb0,0x00,0x18,0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,
-0x90,0xa2,0x00,0x00,0x00,0x80,0x90,0x21,0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,
-0x24,0x02,0x00,0x10,0x12,0x22,0x00,0xcf,0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,
-0x12,0x22,0x00,0xc1,0x24,0x02,0x00,0x12,0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,
-0x14,0x60,0x00,0xad,0xae,0x43,0x00,0x40,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,
-0x8c,0x44,0x00,0x00,0x3c,0x03,0x00,0x02,0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,
-0x00,0x10,0x14,0x43,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x92,0x00,0x00,0x00,0x00,0x93,0x83,0x91,0x51,
-0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,
-0x00,0x10,0x11,0xc3,0x14,0x40,0x00,0x86,0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,
-0x02,0x00,0x10,0x21,0x26,0x22,0x00,0x01,0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,
-0x14,0x60,0xff,0xdb,0x24,0x03,0x00,0x02,0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,
-0x2a,0x62,0x00,0x03,0x10,0x40,0x00,0x58,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,
-0x12,0x62,0x00,0x4b,0x02,0x40,0x20,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,
-0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,
-0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x28,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,
-0x24,0x02,0x00,0x07,0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,
-0xaf,0xa2,0x00,0x10,0x0c,0x00,0x0e,0xd9,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,
-0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,
-0x16,0x00,0xff,0xec,0x02,0x00,0x10,0x21,0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,
-0x24,0x02,0x00,0x05,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,
-0xaf,0xa2,0x00,0x10,0x0c,0x00,0x0e,0xd9,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,
-0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,
-0x16,0x00,0xff,0xdc,0x02,0x00,0x10,0x21,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,
-0x24,0x02,0x00,0x03,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,
-0xaf,0xa2,0x00,0x10,0x0c,0x00,0x0e,0xd9,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,
-0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,
-0x16,0x00,0xff,0xcc,0x02,0x00,0x10,0x21,0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,
-0x24,0x02,0x00,0x02,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,
-0xaf,0xa2,0x00,0x10,0x0c,0x00,0x0e,0xd9,0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,
-0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,0x08,0x00,0x10,0x61,0x30,0x42,0x00,0xff,
-0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,
-0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x0e,0xd9,0xaf,0xa3,0x00,0x14,
-0x08,0x00,0x10,0x5a,0xae,0x42,0x00,0x24,0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,
-0x24,0x02,0x00,0x08,0x16,0x62,0xff,0xa8,0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,
-0x8e,0x42,0x00,0x30,0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,
-0x0c,0x00,0x0e,0xd9,0xaf,0xa2,0x00,0x14,0x08,0x00,0x10,0x5a,0xae,0x42,0x00,0x30,
-0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,
-0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x0e,0xd9,0xaf,0xa3,0x00,0x14,
-0x08,0x00,0x10,0x5a,0xae,0x42,0x00,0x2c,0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,
-0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,
-0x0c,0x00,0x0e,0xd9,0xaf,0xa3,0x00,0x14,0x08,0x00,0x10,0x5a,0xae,0x42,0x00,0x28,
-0x0c,0x00,0x01,0x60,0x24,0x04,0x00,0x01,0x08,0x00,0x10,0x4b,0x00,0x00,0x00,0x00,
-0x8f,0x84,0xba,0x80,0xae,0x40,0x00,0x34,0x94,0x85,0x00,0x14,0x0c,0x00,0x1f,0xdd,
-0x00,0x00,0x00,0x00,0x93,0x83,0x91,0x51,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,
-0x10,0x40,0xff,0x69,0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x60,0x00,0x00,0x20,0x21,
-0x08,0x00,0x10,0x43,0x00,0x00,0x00,0x00,0x02,0x40,0x20,0x21,0x0c,0x00,0x0e,0x55,
-0x02,0x20,0x28,0x21,0x08,0x00,0x10,0x37,0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x4a,0x00,0x00,0x00,0x00,0x8f,0x82,0xba,0x88,
-0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,
-0x08,0x00,0x10,0x34,0xae,0x43,0x00,0x3c,0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,
-0x14,0x40,0xff,0x3d,0x24,0x02,0x00,0x12,0x8f,0x82,0xba,0x84,0x00,0x00,0x00,0x00,
-0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x10,0x34,
-0xae,0x43,0x00,0x38,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,
-0x24,0x02,0x00,0x11,0x8f,0x82,0xba,0x80,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x10,0x34,0xae,0x43,0x00,0x34,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,
-0x24,0x42,0x44,0x20,0x3c,0x08,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,
-0x35,0x08,0x01,0x00,0xaf,0xbf,0x00,0x18,0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,
-0x00,0xa0,0x48,0x21,0x24,0x11,0x00,0x0a,0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,
-0x00,0x45,0x88,0x0a,0x30,0x63,0x00,0x01,0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,
-0x00,0x11,0x40,0x40,0x02,0x20,0x40,0x21,0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,
-0x01,0x20,0x20,0x21,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x96,0x48,0x00,0x43,0x10,0x21,0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,
-0x10,0xe0,0x00,0x06,0x02,0x23,0x80,0x21,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x0d,0xd7,
-0x00,0x00,0x00,0x00,0x02,0x11,0x18,0x21,0x08,0x00,0x11,0x2a,0x00,0x62,0x80,0x21,
-0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,
-0xaf,0xb2,0x00,0x18,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,
-0x84,0x82,0x00,0x0c,0x3c,0x06,0xb0,0x03,0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,
-0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,0x27,0x82,0x96,0x44,0x00,0x62,0x10,0x21,
-0x8c,0x53,0x00,0x18,0x3c,0x02,0x80,0x00,0x24,0x42,0x44,0xd0,0xac,0xc2,0x00,0x00,
-0x8e,0x70,0x00,0x08,0x27,0x82,0x96,0x48,0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,
-0x00,0x10,0x86,0x43,0x32,0x10,0x00,0x01,0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,
-0x00,0xa0,0xa0,0x21,0x02,0x20,0x28,0x21,0x0c,0x00,0x11,0x08,0x00,0x80,0xa8,0x21,
-0x02,0x20,0x20,0x21,0x02,0x00,0x28,0x21,0x24,0x06,0x00,0x14,0x0c,0x00,0x0d,0xd7,
-0x00,0x40,0x90,0x21,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x40,0x94,0x64,0x00,0x00,
-0x3c,0x0a,0xb0,0x09,0x3c,0x0b,0xb0,0x09,0x00,0x04,0x21,0x40,0x00,0x82,0x28,0x23,
-0x35,0x4a,0x01,0x10,0x35,0x6b,0x01,0x14,0x3c,0x0c,0xb0,0x09,0x3c,0x08,0xb0,0x09,
-0x3c,0x06,0xb0,0x09,0x00,0x44,0x10,0x2b,0x01,0x40,0x48,0x21,0x35,0x8c,0x01,0x20,
-0x01,0x60,0x38,0x21,0x35,0x08,0x01,0x24,0x34,0xc6,0x01,0x02,0x10,0x40,0x00,0x02,
-0x02,0x45,0x18,0x2b,0x00,0xa3,0x90,0x0b,0x86,0xa3,0x00,0x0c,0x27,0x84,0x96,0x50,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,
-0x80,0x43,0x00,0x06,0xa4,0xd2,0x00,0x00,0x24,0x64,0x00,0x03,0x28,0x62,0x00,0x00,
-0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x00,0x03,0x18,0x80,0x12,0x80,0x00,0x11,
-0x02,0x63,0x28,0x21,0x8c,0xa2,0x00,0x0c,0x8c,0xa3,0x00,0x08,0x00,0x02,0x14,0x00,
-0x00,0x03,0x1c,0x02,0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8c,0xa3,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0x03,0x1c,0x02,0xa4,0xe3,0x00,0x00,0x8f,0xbf,0x00,0x28,
-0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x30,0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x42,0x00,0x00,
-0x8c,0xa4,0x00,0x08,0x00,0x00,0x00,0x00,0xa5,0x64,0x00,0x00,0x78,0xa2,0x00,0x7c,
-0x00,0x00,0x00,0x00,0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21,
-0xad,0x83,0x00,0x00,0x8c,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02,
-0x08,0x00,0x11,0x87,0xa5,0x02,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c,
-0x00,0x80,0x90,0x21,0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,
-0x00,0x04,0x20,0x80,0x27,0x82,0x96,0x44,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18,
-0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x46,0x78,0x27,0x83,0x96,0x48,
-0xac,0xa2,0x00,0x00,0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07,
-0x34,0x42,0x01,0x00,0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04,
-0x24,0x02,0x00,0x10,0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43,
-0x30,0x84,0x00,0x01,0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40,
-0x02,0x00,0x10,0x21,0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x0d,0xd7,
-0x30,0x50,0x00,0xff,0x86,0x44,0x00,0x0c,0x27,0x85,0x96,0x50,0x3c,0x06,0xb0,0x09,
-0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,
-0x80,0x64,0x00,0x06,0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03,
-0x28,0x83,0x00,0x00,0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80,
-0xa4,0xc2,0x00,0x00,0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09,
-0x34,0x42,0x01,0x10,0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09,
-0x34,0x42,0x01,0x14,0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08,
-0x3c,0x06,0xb0,0x09,0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21,
-0x34,0xc6,0x01,0x20,0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09,
-0x34,0xa5,0x01,0x24,0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a,
-0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04,
-0x30,0x42,0xff,0xff,0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x96,0x58,
-0x8f,0xbf,0x00,0x1c,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,
-0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,
-0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x48,0x04,
-0x00,0x05,0x2c,0x43,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,
-0x10,0xa0,0x00,0x05,0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0xaf,0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x47,
-0x00,0x00,0x10,0x21,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x9c,0x2a,0x02,0x00,0x09,
-0x10,0x40,0x00,0x84,0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x74,
-0x2a,0x02,0x00,0x03,0x10,0x40,0x00,0x64,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,
-0x12,0x02,0x00,0x55,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x11,0x92,0x27,0x00,0x11,
-0x10,0x40,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12,
-0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xba,0x40,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14,
-0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10,
-0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xba,0x40,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12,
-0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01,
-0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12,
-0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c,
-0x27,0x84,0x96,0x50,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00,
-0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04,
-0xa2,0x20,0x00,0x15,0xa3,0x80,0x92,0x15,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x11,0x9e,
-0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x12,0x49,0x00,0x07,0x16,0x00,
-0x0c,0x00,0x11,0x34,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x96,0x48,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21,
-0x90,0x85,0x00,0x07,0x27,0x83,0x96,0x50,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13,
-0x90,0x83,0x00,0x07,0x08,0x00,0x12,0x61,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a,
-0x08,0x00,0x12,0x2a,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00,
-0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a,
-0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x12,0x22,0xa2,0x22,0x00,0x04,
-0x08,0x00,0x12,0x7b,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9f,0x24,0x02,0x00,0x01,
-0x8e,0x23,0x00,0x2c,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08,
-0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c,
-0x08,0x00,0x12,0x22,0xa2,0x22,0x00,0x06,0x08,0x00,0x12,0x8a,0xa2,0x20,0x00,0x0a,
-0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07,
-0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b,
-0xae,0x20,0x00,0x28,0x08,0x00,0x12,0x22,0xa2,0x22,0x00,0x05,0x08,0x00,0x12,0x96,
-0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x10,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x08,
-0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7f,0x24,0x02,0x00,0x12,
-0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x12,0x22,0xae,0x20,0x00,0x3c,
-0x16,0x02,0xff,0x79,0x24,0x02,0x00,0x10,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,
-0x08,0x00,0x12,0x22,0xae,0x20,0x00,0x34,0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a,
-0xa2,0x22,0x00,0x08,0x08,0x00,0x12,0x22,0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30,
-0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01,0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08,
-0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30,
-0x08,0x00,0x12,0x22,0xa2,0x22,0x00,0x07,0x08,0x00,0x12,0xba,0xa2,0x24,0x00,0x0a,
-0x8f,0x84,0xba,0x80,0xae,0x20,0x00,0x34,0x94,0x85,0x00,0x14,0x0c,0x00,0x1f,0xdd,
-0x32,0x10,0x00,0xff,0x08,0x00,0x12,0x13,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x24,0x42,0x4b,0x1c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,
-0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05,0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54,
-0x83,0x83,0x92,0x15,0x00,0x00,0x00,0x00,0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,
-0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c,0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50,
-0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01,0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01,
-0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01,
-0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8,0x34,0x63,0x00,0x20,0x24,0x42,0x4b,0xac,
-0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18,
-0x90,0xa6,0x00,0x0a,0x27,0x83,0xba,0x40,0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80,
-0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12,
-0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15,0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xd9,
-0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67,
-0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12,0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x96,0x60,0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf,0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08,
-0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45,0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04,
-0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01,
-0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17,0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff,
-0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03,0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,
-0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,
-0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08,0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06,
-0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14,0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x96,0x02,0x00,0x00,0x08,0x00,0x13,0x36,
-0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,
-0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x22,0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00,
-0x96,0x05,0x00,0x06,0x27,0x86,0x96,0x40,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,
-0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,
-0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08,
-0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24,0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24,
-0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01,
-0x00,0xa6,0x18,0x2b,0x08,0x00,0x13,0x22,0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd,
-0x00,0xa6,0x18,0x2b,0x08,0x00,0x13,0x56,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,
-0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8,
-0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x1c,0xa2,0x20,0x00,0x07,0x08,0x00,0x13,0x1c,
-0xa2,0x20,0x00,0x06,0x08,0x00,0x13,0x1c,0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x68,0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x48,
-0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,
-0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3a,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,
-0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c,
-0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,
-0x27,0x83,0x96,0x44,0x00,0xa3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18,
-0x00,0x00,0x00,0x00,0x93,0x82,0x91,0x51,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24,0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03,
-0x0c,0x00,0x1f,0xdd,0x02,0x00,0x20,0x21,0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12,
-0x30,0x42,0x00,0xe7,0x08,0x00,0x13,0x13,0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06,
-0x00,0x00,0x28,0x12,0x27,0x82,0x96,0x40,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,
-0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c,0x08,0x00,0x13,0x93,0x00,0x06,0x2c,0x00,
-0x27,0x83,0x96,0x50,0x27,0x82,0x96,0x58,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,
-0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05,0x00,0x00,0x30,0x21,0x0c,0x00,0x25,0xc4,
-0x24,0x07,0x00,0x01,0x96,0x26,0x00,0x0c,0x08,0x00,0x13,0x8d,0x00,0x00,0x00,0x00,
-0x14,0x40,0xff,0xce,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x13,0x7c,0x00,0xa2,0x10,0x07,
-0x86,0x26,0x00,0x0c,0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72,0x34,0x63,0x01,0x78,
-0x94,0x47,0x00,0x00,0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0,0x00,0x46,0x10,0x21,
-0x3c,0x04,0xb0,0x09,0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c,0x27,0x83,0x96,0x44,
-0x00,0x02,0x10,0x80,0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21,0x8c,0x43,0x00,0x18,
-0xae,0x25,0x00,0x20,0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08,0x02,0x20,0x20,0x21,
-0x0c,0x00,0x13,0xe2,0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18,0x8e,0x26,0x00,0x1c,
-0x8e,0x27,0x00,0x20,0x02,0x20,0x20,0x21,0x0c,0x00,0x20,0xdf,0xaf,0xa2,0x00,0x10,
-0x08,0x00,0x13,0x13,0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08,0x08,0x00,0x13,0x13,
-0xa2,0x22,0x00,0x09,0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xac,0x40,0x00,0x00,
-0x08,0x00,0x13,0x13,0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c,0x24,0x03,0x00,0x24,
-0x00,0x80,0x70,0x21,0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x24,0x42,0x4f,0x88,
-0xf1,0x43,0x00,0x06,0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12,0x00,0xa0,0x68,0x21,
-0xac,0x82,0x00,0x00,0x27,0x85,0x96,0x50,0x27,0x82,0x96,0x4f,0x27,0xbd,0xff,0xf8,
-0x00,0x62,0x60,0x21,0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21,0x11,0xa0,0x00,0xcc,
-0x00,0x00,0x78,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x91,0x87,0x00,0x00,
-0x80,0x48,0x00,0x04,0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80,0x27,0x83,0x96,0x44,
-0xa3,0xa7,0x00,0x00,0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18,0x25,0x02,0xff,0xff,
-0x00,0x48,0x40,0x0b,0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07,0x24,0x02,0x00,0x06,
-0x30,0x63,0x00,0x08,0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a,0x93,0xa7,0x00,0x00,
-0x27,0x82,0x96,0x58,0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0,0x38,0x63,0x00,0x50,
-0x30,0xe5,0x00,0xff,0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b,0x00,0x64,0x18,0x24,
-0x90,0x49,0x00,0x00,0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f,0x24,0x02,0x00,0x04,
-0x10,0xa2,0x00,0x9d,0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a,0x2c,0xa2,0x00,0x0c,
-0x10,0x40,0x00,0x02,0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21,0x30,0x84,0x00,0xff,
-0x00,0x04,0x10,0x40,0x27,0x83,0xc1,0x5c,0x00,0x44,0x10,0x21,0x00,0x43,0x10,0x21,
-0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c,0xa3,0xa7,0x00,0x00,
-0x10,0x60,0x00,0x02,0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21,0xa3,0xa2,0x00,0x00,
-0x91,0x65,0x00,0x00,0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff,0x00,0x62,0x10,0x2b,
-0x10,0x40,0x00,0x0e,0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0x60,0x20,0x21,
-0x30,0xa2,0x00,0x0f,0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40,0x00,0x44,0x20,0x21,
-0x27,0x83,0xc1,0x5c,0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x05,0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00,0x93,0xa2,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x27,0x83,0xba,0xe8,
-0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x83,0x00,0x0c,
-0x14,0x60,0x00,0x06,0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,
-0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x08,0x00,0x14,0x43,
-0xa1,0x82,0x00,0x00,0x8f,0x8d,0x87,0xf0,0x00,0x00,0x00,0x00,0x01,0xa8,0x10,0x21,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1,0x00,0x00,0x28,0x21,
-0x00,0x06,0x74,0x82,0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x03,
-0x00,0xe0,0x10,0x21,0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c,0x30,0x44,0x00,0xff,
-0xa3,0xa2,0x00,0x00,0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d,0x00,0x09,0x11,0x00,
-0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40,0x00,0x49,0x10,0x23,
-0x00,0x64,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x27,0x84,0xba,0xe8,
-0x00,0x44,0x10,0x21,0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x00,
-0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x44,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,
-0x14,0x60,0x00,0x33,0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23,0x27,0x83,0xbb,0xb8,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05,0x00,0x00,0x00,0x00,
-0x00,0x64,0xc0,0x24,0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe2,0x00,0x0f,
-0x10,0x40,0x00,0x0f,0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x96,0x40,
-0x00,0x44,0x10,0x21,0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0x28,0x63,0x06,0x41,
-0x14,0x60,0x00,0x04,0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f,0xa3,0xa7,0x00,0x00,
-0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06,0x00,0xe0,0x10,0x21,
-0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x47,0x10,0x21,
-0x24,0x42,0x00,0x04,0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21,0x01,0xa8,0x10,0x21,
-0x90,0x43,0x00,0x00,0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff,0x00,0xa3,0x18,0x2b,
-0x14,0x60,0xff,0xad,0x30,0xe2,0x00,0xff,0x08,0x00,0x14,0x30,0x00,0x00,0x00,0x00,
-0x08,0x00,0x14,0x91,0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48,0x00,0x00,0x00,0x00,
-0x10,0x40,0xff,0x73,0x00,0x00,0x00,0x00,0x08,0x00,0x14,0x1e,0x00,0x00,0x00,0x00,
-0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05,0x91,0x67,0x00,0x00,
-0x08,0x00,0x13,0xfe,0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x34,0x63,0x00,0x20,0x24,0x42,0x53,0x28,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,
-0x27,0xbd,0xff,0xc0,0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,
-0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xbf,0x00,0x3c,
-0xaf,0xbe,0x00,0x38,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x84,0x82,0x00,0x0c,
-0x27,0x93,0x96,0x44,0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18,0x3c,0x02,0x80,0x00,
-0x34,0xa5,0x00,0x20,0x24,0x42,0x53,0x40,0xac,0xa2,0x00,0x00,0x8f,0xd0,0x00,0x08,
-0x27,0x95,0x96,0x50,0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21,0x02,0x00,0x30,0x21,
-0x90,0x71,0x00,0x00,0x0c,0x00,0x13,0xe2,0x00,0x80,0xb0,0x21,0x00,0x40,0x90,0x21,
-0x00,0x10,0x14,0x42,0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21,0x00,0x10,0x14,0x82,
-0x02,0x80,0x28,0x21,0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2,0x86,0xc3,0x00,0x0c,
-0x30,0x50,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x55,0x10,0x21,0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x30,0x21,
-0x8c,0xc7,0x00,0x18,0x27,0x83,0x96,0x40,0x00,0x43,0x10,0x21,0x8c,0xe3,0x00,0x04,
-0x84,0x46,0x00,0x06,0x00,0x03,0x19,0x42,0x0c,0x00,0x0d,0xd7,0x30,0x73,0x00,0x01,
-0x00,0x40,0x88,0x21,0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21,0x16,0xe0,0x00,0x10,
-0x02,0x00,0x30,0x21,0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0xc0,
-0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,0x27,0x82,0x96,0x48,0x00,0x62,0x18,0x21,
-0xa4,0x71,0x00,0x04,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,
-0x86,0xc3,0x00,0x0c,0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0x80,0x47,0x00,0x06,
-0x00,0x00,0x00,0x00,0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2,0x00,0xe2,0x38,0x21,
-0x00,0x07,0x38,0x43,0x00,0x07,0x38,0x40,0x0c,0x00,0x0d,0xfe,0x03,0xc7,0x38,0x21,
-0x08,0x00,0x15,0x11,0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x27,0xbd,0xff,0xd0,0x34,0x63,0x00,0x20,0x24,0x42,0x54,0xc8,0xaf,0xb2,0x00,0x20,
-0xac,0x62,0x00,0x00,0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,
-0xaf,0xb0,0x00,0x18,0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a,0x34,0x42,0x01,0x04,
-0x94,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x27,0x82,0xba,0x40,0x00,0x62,0x18,0x21,
-0x30,0xa6,0xff,0xff,0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12,0x30,0xc8,0x00,0xff,
-0x00,0x06,0x32,0x02,0xa4,0x86,0x00,0x44,0xa4,0x88,0x00,0x46,0x82,0x22,0x00,0x12,
-0x00,0x80,0x90,0x21,0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15,0x00,0xc5,0x10,0x2a,
-0x10,0x40,0x00,0x14,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19,0x84,0x83,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x96,0x60,0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x80,0x00,0x12,
-0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf,0xa2,0x22,0x00,0x16,
-0x8f,0xbf,0x00,0x28,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x30,0x0c,0x00,0x14,0xca,0x00,0x00,0x00,0x00,0x08,0x00,0x15,0x60,
-0x00,0x00,0x00,0x00,0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x65,0x00,0x00,0x28,0x21,
-0x84,0x83,0x00,0x0c,0x27,0x84,0x96,0x50,0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x48,0x00,0x43,0x18,0x21,
-0x80,0x65,0x00,0x06,0x00,0x44,0x10,0x21,0x80,0x49,0x00,0x05,0x38,0xa5,0x00,0x00,
-0x80,0x4a,0x00,0x04,0x15,0x20,0x00,0x27,0x01,0x05,0x30,0x0b,0x15,0x40,0x00,0x11,
-0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff,
-0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x45,0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04,
-0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00,0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x27,0x84,0x96,0x50,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,
-0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21,0x00,0x64,0x28,0x21,0x94,0xa2,0x00,0x00,
-0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00,0x14,0x60,0x00,0x06,0x00,0x02,0x24,0x03,
-0x30,0x82,0x00,0x04,0x14,0x40,0x00,0x04,0x01,0x49,0x10,0x21,0x34,0x82,0x08,0x00,
-0xa4,0xa2,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,
-0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c,
-0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x96,0x50,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16,
-0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb,0x08,0x00,0x15,0x65,0xa2,0x23,0x00,0x16,
-0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x50,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05,
-0x86,0x45,0x00,0x0c,0x0c,0x00,0x23,0x1c,0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a,
-0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,
-0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,
-0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01,
-0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c,
-0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x08,0x00,0x15,0x60,
-0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00,0x08,0x00,0x15,0x60,0xa6,0x22,0x00,0x14,
-0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0x15,0xde,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,
-0x27,0x86,0x96,0x40,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,
-0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,
-0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,
-0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,
-0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,
-0x08,0x00,0x15,0xde,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,
-0x08,0x00,0x16,0x01,0x00,0x00,0x00,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,
-0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00,
-0x08,0x00,0x15,0xd9,0xa2,0x40,0x00,0x07,0x08,0x00,0x15,0xd9,0xa2,0x40,0x00,0x06,
-0x08,0x00,0x15,0xd9,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,
-0x08,0x00,0x15,0xd0,0x00,0xa2,0x10,0x07,0x0c,0x00,0x14,0xd0,0x02,0x40,0x20,0x21,
-0x08,0x00,0x15,0x60,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,
-0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x98,0x2c,0xc2,0x00,0x10,
-0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,
-0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,
-0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x7f,
-0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x86,0x43,0x00,0x0c,0x27,0x93,0x96,0x44,
-0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,
-0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x64,0x00,0x00,0x00,0x00,
-0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21,0x8c,0x43,0x00,0x18,0x93,0x82,0x91,0x51,
-0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01,0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d,
-0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1f,0xdd,
-0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06,0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff,
-0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b,
-0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04,
-0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x0c,0x00,0x1f,0xdd,0x30,0x50,0x00,0x01,
-0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef,0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,
-0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,
-0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16,0x08,0x00,0x15,0x5f,0x30,0x42,0x00,0xc3,
-0x96,0x22,0x00,0x00,0x08,0x00,0x16,0x75,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x70,
-0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0,
-0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x27,0x84,0x96,0x40,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08,
-0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08,0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24,
-0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,
-0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x16,0x70,
-0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x16,0x94,
-0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24,0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12,
-0x27,0x82,0x96,0x40,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,0x00,0x00,0x20,0x21,
-0x96,0x47,0x00,0x0c,0x08,0x00,0x16,0x52,0x00,0x07,0x2c,0x00,0x27,0x83,0x96,0x50,
-0x27,0x82,0x96,0x58,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,
-0x90,0x65,0x00,0x05,0x24,0x07,0x00,0x01,0x0c,0x00,0x25,0xc4,0x00,0x00,0x30,0x21,
-0x96,0x47,0x00,0x0c,0x08,0x00,0x16,0x45,0x00,0x07,0x1c,0x00,0x10,0xa2,0x00,0x09,
-0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x7e,
-0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x36,0xa2,0x40,0x00,0x07,0x08,0x00,0x16,0x36,
-0xa2,0x40,0x00,0x06,0x08,0x00,0x16,0x36,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0x72,
-0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,
-0x24,0x02,0x00,0x80,0x08,0x00,0x16,0x2d,0x00,0xa2,0x10,0x07,0x14,0x40,0xfe,0xc4,
-0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x15,0x88,0x00,0xa2,0x10,0x07,
-0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x44,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08,0x0c,0x00,0x13,0xe2,0x00,0x00,0x00,0x00,
-0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21,
-0x0c,0x00,0x20,0xdf,0xaf,0xa2,0x00,0x10,0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x7c,
-0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40,
-0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00,
-0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01,0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17,
-0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00,
-0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16,
-0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0,0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16,
-0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16,0x11,0x00,0xfe,0x61,0x00,0x00,0x00,0x00,
-0x92,0x22,0x00,0x16,0x08,0x00,0x15,0x5f,0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00,
-0x08,0x00,0x16,0xf7,0xa6,0x22,0x00,0x14,0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00,
-0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0xf0,0xa2,0x20,0x00,0x17,
-0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x96,0x40,0x00,0x04,0x18,0xc0,
-0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,
-0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,
-0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,
-0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,
-0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x16,0xf0,0xa2,0x23,0x00,0x17,
-0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x17,0x1f,0x00,0x00,0x00,0x00,
-0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03,
-0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0xea,0xa2,0x40,0x00,0x07,
-0x08,0x00,0x16,0xea,0xa2,0x40,0x00,0x06,0x08,0x00,0x16,0xea,0xa2,0x40,0x00,0x05,
-0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24,
-0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21,0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01,
-0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd,
-0x00,0xa4,0x10,0x2b,0x08,0x00,0x17,0x3a,0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff,
-0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x27,0x84,0x96,0x50,0x00,0x03,0x18,0x80,
-0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06,0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00,
-0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21,0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21,
-0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c,0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41,
-0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04,0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00,
-0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20,
-0x08,0x00,0x17,0x60,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06,
-0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff,
-0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21,0x8f,0x85,0x96,0x20,0x00,0x40,0x30,0x21,
-0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00,0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02,
-0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00,0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08,
-0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00,0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00,0x27,0x92,0xba,0x40,0x24,0x11,0x00,0x12,
-0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x0c,0x00,0x1d,0x55,0x00,0x00,0x00,0x00,
-0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf,0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03,
-0x0c,0x00,0x18,0x18,0xac,0x30,0x00,0x00,0x08,0x00,0x17,0x60,0x00,0x00,0x00,0x00,
-0x8f,0x85,0x96,0x20,0x08,0x00,0x17,0x76,0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95,
-0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24,0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03,
-0xac,0x30,0x00,0x00,0x0c,0x00,0x17,0xe1,0xac,0x60,0x00,0x00,0x08,0x00,0x17,0x60,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x50,0x08,0x00,0x17,0x60,
-0xac,0x46,0x00,0x00,0xaf,0xa7,0x00,0x0c,0xaf,0xa4,0x00,0x00,0xaf,0xa5,0x00,0x04,
-0xaf,0xa6,0x00,0x08,0x27,0xbd,0xfe,0xe8,0x00,0x80,0x28,0x21,0x27,0xa6,0x01,0x1c,
-0x27,0xa4,0x00,0x10,0xaf,0xbf,0x01,0x14,0x0c,0x00,0x29,0xa9,0xaf,0xb0,0x01,0x10,
-0x00,0x40,0x80,0x21,0x0c,0x00,0x17,0xb0,0x27,0xa4,0x00,0x10,0x02,0x00,0x10,0x21,
-0x8f,0xbf,0x01,0x14,0x8f,0xb0,0x01,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x01,0x18,
-0x93,0x83,0x87,0xec,0x27,0xbd,0xff,0xe8,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0x14,0x60,0x00,0x14,0x00,0x80,0x80,0x21,0x80,0x82,0x00,0x00,0x90,0x84,0x00,0x00,
-0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x00,0x04,0x26,0x00,0x00,0x04,0x26,0x03,
-0x30,0x84,0xff,0xff,0x0c,0x00,0x17,0xd0,0x26,0x10,0x00,0x01,0x92,0x03,0x00,0x00,
-0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xf8,0x00,0x60,0x20,0x21,0x08,0x00,0x17,0xba,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x14,0x43,0xff,0xef,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x04,0x52,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0xba,0x00,0x00,0x00,0x00,
-0x30,0x84,0xff,0xff,0x48,0x84,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x0c,0x00,0x29,0x11,0x00,0x00,0x00,0x00,
-0x8f,0xbf,0x00,0x10,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
-0x24,0x02,0x00,0x01,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x5f,0x84,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01,0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01,
-0x25,0x29,0x0b,0x2c,0x11,0x09,0x00,0x10,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,
-0x25,0x4a,0x5f,0xac,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06,
-0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,
-0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01,0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01,
-0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x5f,0xe8,
-0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40,0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x60,0x14,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01,
-0x24,0x63,0x0b,0x2c,0x3c,0x04,0xb0,0x00,0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00,
-0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a,
-0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0x80,0x00,0x25,0x4a,0x60,0x60,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x02,0x80,0x01,0x24,0x42,0x0b,0x30,0x3c,0x03,0x80,0x01,0x24,0x63,0x42,0x50,
-0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c,
-0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0x80,0x00,0x25,0x4a,0x60,0xa0,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0,0x27,0x9d,0x92,0x20,0x00,0x00,0x00,0x00,
-0x27,0x9d,0x96,0x08,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x60,0xc4,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00,0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00,
-0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x1a,0x4d,
-0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00,0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40,
-0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff,
-0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14,0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18,
-0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x0c,0x00,0x18,0x95,0x02,0x20,0x20,0x21,
-0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,
-0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21,0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c,
-0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21,
-0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40,
-0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21,0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00,0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01,
-0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a,
-0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21,0x8e,0x30,0x00,0x00,0x0c,0x00,0x18,0x95,
-0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27,0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04,
-0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a,
-0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00,0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x18,0x83,
-0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20,
-0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,
-0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0x00,0x80,0x80,0x21,0x00,0xa0,0x88,0x21,
-0x00,0xc0,0x90,0x21,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x03,0x82,0x02,0x00,0x13,0x00,0x11,0x24,0x00,
-0x3c,0x03,0xc0,0x00,0x00,0x02,0x12,0x00,0x00,0x44,0x10,0x21,0x3c,0x04,0xb0,0x05,
-0x24,0x42,0x00,0x09,0x34,0x84,0x04,0x20,0x34,0x63,0x04,0x00,0x3c,0x05,0xb0,0x05,
-0x3c,0x06,0xb0,0x05,0xac,0x82,0x00,0x00,0x24,0x07,0x00,0x01,0x02,0x43,0x18,0x21,
-0x34,0xa5,0x04,0x24,0x34,0xc6,0x02,0x28,0x24,0x02,0x00,0x20,0xac,0xa3,0x00,0x00,
-0xae,0x07,0x00,0x3c,0xa0,0xc2,0x00,0x00,0xa2,0x07,0x00,0x11,0x3c,0x02,0xb0,0x05,
-0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x01,0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06,
-0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50,0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,
-0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14,0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c,
-0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,
-0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,
-0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10,0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48,
-0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c,0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00,
-0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00,0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25,
-0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80,0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08,
-0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03,0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22,
-0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67,0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00,
-0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa,0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23,
-0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23,0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01,
-0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0,0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08,
-0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00,0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00,
-0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef,0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef,
-0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00,0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00,
-0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14,0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c,
-0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04,0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10,
-0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14,0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09,
-0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09,0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09,
-0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09,0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09,
-0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00,0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00,
-0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee,0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20,
-0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28,0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30,
-0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38,0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00,
-0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00,0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00,
-0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00,0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00,
-0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00,0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00,
-0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00,0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09,
-0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x65,0x50,
-0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34,0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a,
-0x14,0x40,0x00,0xed,0x00,0x80,0x28,0x21,0x8c,0x84,0x00,0x08,0x24,0x02,0x00,0x03,
-0x10,0x82,0x00,0xe0,0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x2c,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x38,0x24,0x02,0x00,0x06,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xc6,
-0xac,0xa2,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0xc5,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0x82,0x00,0xb3,0x00,0x00,0x00,0x00,0x8c,0xa6,0x00,0x04,
-0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0xa9,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0xd0,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x61,0x00,0x16,
-0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x10,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0b,0x00,0x00,0x00,0x00,
-0x80,0xa2,0x00,0x50,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,
-0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,
-0x03,0xe0,0x00,0x08,0xa0,0xa3,0x00,0x50,0x80,0xa2,0x00,0x31,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,0x8c,0x43,0x00,0x00,
-0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24,0x10,0x62,0x00,0x03,
-0x24,0x02,0x00,0x09,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x00,0x8c,0xa2,0x00,0x40,
-0x00,0x00,0x00,0x00,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x09,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,
-0x3c,0x04,0x00,0x02,0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2,0x24,0x02,0x00,0x10,
-0x3c,0x03,0xb0,0x03,0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x80,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x8c,0xa3,0x00,0x0c,
-0x00,0x00,0x00,0x00,0xac,0xa3,0x00,0x10,0x3c,0x02,0xb0,0x03,0x90,0x42,0x02,0x01,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0xac,0xa2,0x00,0x0c,0x90,0xa3,0x00,0x0f,
-0x24,0x02,0x00,0x0d,0x3c,0x01,0xb0,0x03,0x08,0x00,0x19,0x9d,0xa0,0x23,0x02,0x01,
-0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x04,0x1e,0x00,0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15,0xa0,0xa4,0x00,0x44,
-0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x03,
-0x24,0x03,0x00,0x0d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x0c,
-0xac,0xa3,0x00,0x00,0x24,0x03,0x00,0x04,0xac,0xa2,0x00,0x10,0x03,0xe0,0x00,0x08,
-0xac,0xa3,0x00,0x0c,0x24,0x02,0x00,0x0d,0xac,0xa2,0x00,0x00,0x24,0x03,0x00,0x04,
-0x24,0x02,0x00,0x06,0xac,0xa3,0x00,0x10,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x0c,
-0x8c,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09,0x24,0x02,0x00,0x01,
-0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xa2,0x00,0x14,0x24,0x02,0x00,0x01,
-0xac,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x14,0x8c,0xa3,0x00,0x38,
-0x24,0x04,0x00,0x01,0x10,0x64,0x00,0x2d,0x24,0x02,0x00,0x02,0x10,0x60,0x00,0x19,
-0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x10,0x24,0x02,0x00,0x04,0x10,0x62,0x00,0x04,
-0x00,0x00,0x00,0x00,0xac,0xa0,0x00,0x38,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x00,
-0x10,0xc4,0x00,0x07,0x24,0x02,0x00,0x03,0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00,
-0x00,0x02,0x18,0x0b,0xac,0xa3,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x38,
-0x08,0x00,0x19,0xfe,0xac,0xa2,0x00,0x00,0x10,0xc4,0x00,0x02,0x24,0x02,0x00,0x03,
-0x24,0x02,0x00,0x0c,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x04,0x03,0xe0,0x00,0x08,
-0xac,0xa2,0x00,0x38,0x10,0xc4,0x00,0x0e,0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x06,
-0xac,0xa2,0x00,0x18,0x24,0x02,0x00,0x02,0xac,0xa2,0x00,0x00,0xac,0xa0,0x00,0x18,
-0x08,0x00,0x1a,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x1a,0x14,0xac,0xa0,0x00,0x00,
-0x24,0x02,0x00,0x03,0x08,0x00,0x1a,0x14,0xac,0xa2,0x00,0x00,0x24,0x03,0x00,0x0b,
-0xac,0xa2,0x00,0x38,0x03,0xe0,0x00,0x08,0xac,0xa3,0x00,0x00,0x80,0xa2,0x00,0x30,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x55,0x24,0x02,0x00,0x04,0x08,0x00,0x19,0x9d,
-0x00,0x00,0x00,0x00,0x84,0xa2,0x00,0x20,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x75,
-0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,
-0x14,0x40,0xff,0x42,0xa4,0xa3,0x00,0x20,0x08,0x00,0x19,0x9d,0x24,0x02,0x00,0x06,
-0x8c,0xa2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x66,0x24,0x02,0x00,0x05,
-0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x32,0xac,0xa2,0x00,0x1c,0x08,0x00,0x19,0x9d,
-0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x56,0x24,0x02,0x00,0x06,
-0x08,0x00,0x19,0x62,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a,0x03,0xe0,0x00,0x08,
-0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,
-0x27,0x91,0x90,0xf8,0x27,0x90,0x8e,0x38,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,
-0x0c,0x00,0x28,0x9e,0xaf,0xb2,0x00,0x18,0x0c,0x00,0x06,0x90,0x00,0x00,0x00,0x00,
-0xaf,0x91,0x92,0x10,0xaf,0x90,0x96,0x20,0x48,0x02,0x00,0x00,0x0c,0x00,0x18,0xf2,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x1c,0x9b,0x02,0x00,0x20,0x21,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x3a,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0x83,0x96,0x24,
-0x0c,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0xfd,0x00,0x00,0x00,0x00,
-0x27,0x84,0x8c,0x78,0x0c,0x00,0x2c,0x78,0x00,0x00,0x00,0x00,0x0c,0x00,0x25,0x71,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x0c,0x0d,0x02,0x20,0x20,0x21,0x0c,0x00,0x01,0x39,
-0x00,0x00,0x00,0x00,0x27,0x84,0x8c,0x20,0x0c,0x00,0x18,0xdb,0x00,0x00,0x00,0x00,
-0x27,0x82,0x91,0x2c,0xaf,0x82,0x8c,0x60,0x0c,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09,0x3c,0x05,0xb0,0x09,
-0x8c,0x66,0x00,0x00,0x34,0x84,0x01,0x68,0x24,0x02,0xd1,0x10,0x34,0xa5,0x01,0x40,
-0x24,0x03,0x00,0x0a,0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00,0x3c,0x04,0xb0,0x03,
-0x8c,0x82,0x00,0x00,0xaf,0x86,0x8c,0x18,0x34,0x42,0x00,0x20,0xac,0x82,0x00,0x00,
-0x0c,0x00,0x06,0xa1,0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x05,0x0c,0x00,0x28,0xb6,
-0x34,0x84,0x00,0x04,0x8f,0x83,0x8c,0x20,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x11,
-0x10,0x40,0xff,0xf7,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x09,0x08,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
-0x00,0x00,0x00,0x00,0x27,0x84,0x8c,0x20,0x0c,0x00,0x19,0x54,0x00,0x00,0x00,0x00,
-0x8f,0x82,0x8c,0x54,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x8c,0x54,
-0x08,0x00,0x1a,0x88,0x00,0x00,0x00,0x00,0x27,0x84,0x8c,0x78,0x0c,0x00,0x2d,0xe5,
-0x00,0x00,0x00,0x00,0xa3,0x82,0x8c,0x51,0xaf,0x80,0x8c,0x20,0x08,0x00,0x1a,0x9c,
-0x00,0x00,0x00,0x00,0x27,0x84,0x8e,0x38,0x0c,0x00,0x1d,0xe0,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05,0xaf,0x80,0x8c,0x20,
-0xaf,0x80,0x8c,0x24,0x08,0x00,0x1a,0x9c,0x00,0x00,0x00,0x00,0x34,0x63,0x04,0x50,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x8c,0x4c,
-0x14,0x40,0x00,0x1e,0x24,0x02,0x00,0x01,0x8f,0x84,0x8c,0x28,0x00,0x00,0x00,0x00,
-0x10,0x82,0x00,0x1d,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x8c,0x34,0x14,0x40,0x00,0x13,
-0x24,0x02,0x00,0x01,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x03,0xaf,0x82,0x8c,0x24,0xaf,0x83,0x8c,0x20,
-0x08,0x00,0x1a,0x9c,0x00,0x00,0x00,0x00,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,
-0xa7,0x83,0x8c,0x40,0x14,0x40,0xff,0xf3,0x24,0x02,0x00,0x01,0xaf,0x82,0x8c,0x24,
-0x08,0x00,0x1a,0xa6,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x8c,0x3c,
-0x14,0x40,0xff,0xf6,0x24,0x02,0x00,0x01,0x08,0x00,0x1a,0xbe,0x3c,0x03,0xb0,0x09,
-0x27,0x84,0x8e,0x38,0x0c,0x00,0x1f,0x44,0x00,0x00,0x00,0x00,0x83,0x82,0x8c,0x50,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xed,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,
-0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,
-0xaf,0x82,0x8c,0x4c,0x14,0x40,0xff,0xe5,0x24,0x02,0x00,0x02,0x8f,0x84,0x8c,0x28,
-0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x12,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x05,
-0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x02,0xaf,0x82,0x8c,0x24,0x08,0x00,0x1a,0xcb,
-0x24,0x03,0x00,0x04,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x8c,0x40,
-0x14,0x40,0xff,0xf4,0x00,0x00,0x00,0x00,0x08,0x00,0x1a,0xd7,0x24,0x02,0x00,0x02,
-0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0xaf,0x82,0x8c,0x3c,0x14,0x40,0xff,0xf7,0x00,0x00,0x00,0x00,
-0x08,0x00,0x1a,0xf7,0x24,0x02,0x00,0x02,0x27,0x84,0x90,0xf8,0x0c,0x00,0x10,0x1b,
-0x00,0x00,0x00,0x00,0x8f,0x83,0x8c,0x24,0xaf,0x82,0x8c,0x3c,0x38,0x64,0x00,0x02,
-0x00,0x04,0x18,0x0a,0xaf,0x83,0x8c,0x24,0x14,0x40,0x00,0x08,0x24,0x02,0x00,0x05,
-0x8f,0x82,0x91,0x38,0xaf,0x80,0x8c,0x20,0x10,0x40,0xff,0x7d,0x24,0x04,0x00,0x01,
-0xaf,0x84,0x8c,0x28,0x08,0x00,0x1a,0x9c,0x00,0x00,0x00,0x00,0xaf,0x82,0x8c,0x20,
-0x08,0x00,0x1a,0x9c,0x00,0x00,0x00,0x00,0x83,0x82,0x8c,0x70,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x8c,0x3c,0x8f,0x85,0x8c,0x3c,
-0x27,0x84,0x90,0xf8,0x0c,0x00,0x12,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00,
-0xa3,0x82,0x8c,0x50,0xaf,0x80,0x8c,0x3c,0x10,0x60,0xff,0x73,0x3c,0x02,0xb0,0x05,
-0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,
-0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x8c,0x40,0x10,0x40,0xff,0xe7,
-0x24,0x02,0x00,0x06,0x24,0x04,0x00,0x02,0xaf,0x84,0x8c,0x28,0x08,0x00,0x1a,0xa6,
-0x00,0x00,0x00,0x00,0x27,0x84,0x8c,0x20,0x27,0x85,0x90,0xf8,0x0c,0x00,0x12,0xc7,
-0x00,0x00,0x00,0x00,0x8f,0x82,0x8c,0x44,0xaf,0x80,0x8c,0x4c,0x14,0x40,0x00,0x18,
-0x00,0x40,0x18,0x21,0x8f,0x82,0x8c,0x48,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x14,
-0x24,0x02,0x00,0x02,0x8f,0x83,0x8c,0x28,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,
-0x24,0x02,0x00,0x01,0x8f,0x83,0x8c,0x24,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x02,
-0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x06,0xaf,0x82,0x8c,0x20,0x08,0x00,0x1b,0x20,
-0x24,0x04,0x00,0x03,0x3c,0x02,0x40,0x00,0x34,0x42,0x00,0x14,0x3c,0x01,0xb0,0x05,
-0xac,0x22,0x00,0x00,0xaf,0x80,0x8c,0x20,0x08,0x00,0x1b,0x20,0x24,0x04,0x00,0x03,
-0x10,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x84,0x8c,0x20,0x27,0x85,0x90,0xf8,
-0x0c,0x00,0x12,0xeb,0x00,0x00,0x00,0x00,0x8f,0x83,0x8c,0x24,0x24,0x02,0x00,0x01,
-0xa3,0x80,0x8c,0x50,0xaf,0x80,0x8c,0x28,0x10,0x62,0x00,0x02,0x24,0x02,0x00,0x03,
-0x24,0x02,0x00,0x04,0xaf,0x82,0x8c,0x20,0xaf,0x80,0x8c,0x44,0x08,0x00,0x1a,0x9c,
-0x00,0x00,0x00,0x00,0x83,0x82,0x8c,0x70,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x04,
-0x00,0x00,0x00,0x00,0x27,0x84,0x90,0xf8,0x0c,0x00,0x15,0x32,0x00,0x00,0x00,0x00,
-0x8f,0x82,0x8c,0x24,0xa3,0x80,0x8c,0x50,0xaf,0x80,0x8c,0x20,0xaf,0x80,0x8c,0x28,
-0x14,0x40,0x00,0x02,0x24,0x02,0x00,0x02,0xaf,0x82,0x8c,0x24,0xaf,0x80,0x8c,0x48,
-0x08,0x00,0x1a,0x9c,0x00,0x00,0x00,0x00,0x27,0x84,0x8c,0x20,0x27,0x85,0x90,0xf8,
-0x0c,0x00,0x12,0xeb,0x00,0x00,0x00,0x00,0x8f,0x82,0x8c,0x24,0xa3,0x80,0x8c,0x50,
-0xaf,0x80,0x8c,0x20,0xaf,0x80,0x8c,0x28,0x14,0x40,0xff,0x11,0x24,0x02,0x00,0x02,
-0xaf,0x82,0x8c,0x24,0x08,0x00,0x1a,0x9c,0x00,0x00,0x00,0x00,0x27,0x84,0x90,0xf8,
-0x0c,0x00,0x15,0x32,0x00,0x00,0x00,0x00,0x08,0x00,0x1b,0x86,0x00,0x00,0x00,0x00,
-0x27,0x84,0x8c,0x78,0x0c,0x00,0x2e,0x70,0x00,0x00,0x00,0x00,0x08,0x00,0x1a,0xa5,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x27,0x0a,0x00,0x00,0x00,0x00,0x93,0x82,0x92,0x14,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x2b,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,
-0x8c,0x44,0x00,0x00,0x8f,0x83,0xc2,0x50,0x8f,0x82,0xc2,0x54,0x00,0x83,0x18,0x23,
-0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x23,0x3c,0x02,0xb0,0x03,0x24,0x04,0x05,0xa0,
-0x34,0x42,0x01,0x18,0x8c,0x42,0x00,0x00,0x0c,0x00,0x0b,0xfa,0x00,0x00,0x00,0x00,
-0x24,0x04,0x05,0xa4,0x0c,0x00,0x0b,0xfa,0x00,0x02,0x84,0x02,0x30,0x51,0xff,0xff,
-0x24,0x04,0x05,0xa8,0x00,0x02,0x94,0x02,0x0c,0x00,0x0b,0xfa,0x3a,0x10,0xff,0xff,
-0x3a,0x31,0xff,0xff,0x30,0x42,0xff,0xff,0x2e,0x10,0x00,0x01,0x2e,0x31,0x00,0x01,
-0x3a,0x52,0xff,0xff,0x02,0x11,0x80,0x25,0x2e,0x52,0x00,0x01,0x38,0x42,0xff,0xff,
-0x02,0x12,0x80,0x25,0x2c,0x42,0x00,0x01,0x02,0x02,0x80,0x25,0x16,0x00,0x00,0x02,
-0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21,0x0c,0x00,0x0a,0x9c,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0xaf,0x83,0xc2,0x50,0x0c,0x00,0x01,0xcb,0x00,0x00,0x00,0x00,0xaf,0x80,0x8c,0x20,
-0xaf,0x80,0x8c,0x54,0x08,0x00,0x1a,0x88,0x00,0x00,0x00,0x00,0x27,0x90,0xba,0x40,
-0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x10,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x1d,0x55,
-0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xf6,0x26,0x10,0x00,0x04,
-0x08,0x00,0x1a,0xa6,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,
-0x8c,0x44,0x00,0x00,0x8f,0x82,0x8c,0x18,0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,
-0x10,0x62,0xfe,0xc1,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,
-0x3c,0x12,0xb0,0x05,0xaf,0x84,0x8c,0x18,0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,
-0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,
-0x00,0x00,0x88,0x21,0x36,0x52,0x02,0x2c,0x27,0x90,0xba,0x40,0x8e,0x04,0x00,0x00,
-0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,
-0x10,0x40,0x00,0x06,0x30,0x62,0x00,0x1c,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,
-0x8f,0x85,0x8c,0x18,0x0c,0x00,0x22,0xc6,0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x14,0x40,0xfe,0xa3,0x00,0x00,0x00,0x00,
-0x26,0x31,0x00,0x01,0x2a,0x22,0x00,0x13,0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,
-0x08,0x00,0x1a,0xa6,0x00,0x00,0x00,0x00,0x8f,0x84,0x8c,0x2c,0x27,0x85,0x90,0xf8,
-0x0c,0x00,0x1c,0x2e,0x00,0x00,0x00,0x00,0x8f,0x83,0x8c,0x2c,0x24,0x02,0x00,0x04,
-0x14,0x62,0xfe,0x95,0x24,0x02,0x00,0x05,0x08,0x00,0x1b,0x23,0x00,0x00,0x00,0x00,
-0x27,0x84,0x90,0xf8,0x0c,0x00,0x27,0x2e,0x00,0x00,0x00,0x00,0x08,0x00,0x1a,0xcb,
-0x24,0x03,0x00,0x05,0x8f,0x82,0x91,0x2c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,
-0x00,0x00,0x00,0x00,0x8f,0x84,0xba,0x80,0xaf,0x80,0x91,0x2c,0x94,0x85,0x00,0x14,
-0x0c,0x00,0x1f,0xdd,0x00,0x00,0x00,0x00,0x93,0x82,0x91,0x51,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x60,
-0x00,0x00,0x20,0x21,0x8f,0x84,0xba,0x80,0x0c,0x00,0x1d,0x55,0x00,0x00,0x00,0x00,
-0x08,0x00,0x1a,0xa6,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe0,0x3c,0x06,0xb0,0x03,
-0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0xc6,0x00,0x5f,0xaf,0xbf,0x00,0x18,
-0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x5d,0x34,0x63,0x00,0x01,
-0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01,0xa0,0xc3,0x00,0x00,0x00,0x80,0x80,0x21,
-0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21,0x35,0x29,0x00,0x5e,0x00,0xe0,0x40,0x21,
-0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00,0x91,0x03,0x00,0x00,0x30,0x42,0x00,0x01,
-0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c,0x24,0x05,0x0f,0x00,0x24,0x02,0x00,0x06,
-0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f,0x3c,0x02,0xb0,0x03,0x34,0x42,0x02,0x00,
-0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x0f,
-0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x0f,
-0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x0f,
-0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x0f,
-0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x02,
-0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x02,
-0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x02,
-0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x18,0x5b,0x24,0x06,0x00,0x02,
-0x08,0x00,0x1c,0x4f,0x3c,0x02,0xb0,0x03,0x24,0x04,0x08,0x8c,0x0c,0x00,0x18,0x5b,
-0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,0x0c,0x00,0x18,0x5b,
-0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04,0x24,0x05,0x00,0x0f,0x0c,0x00,0x18,0x5b,
-0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,0x0c,0x00,0x18,0x5b,
-0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,0x0c,0x00,0x18,0x5b,
-0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x18,0x5b,
-0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,0x0c,0x00,0x18,0x5b,
-0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30,0x24,0x06,0x00,0x03,0x0c,0x00,0x18,0x5b,
-0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21,0x24,0x05,0x00,0x14,0x0c,0x00,0x18,0xa0,
-0x24,0x06,0x01,0x07,0x08,0x00,0x1c,0x4f,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x72,0x6c,
-0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xb8,
-0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21,
-0xa7,0x82,0x96,0x30,0x27,0x88,0x96,0x40,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08,
-0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21,
-0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21,
-0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4,
-0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x34,0x42,0x07,0xf8,
-0x3c,0x04,0xb0,0x08,0xac,0x43,0x00,0x00,0xa7,0x83,0xba,0x1c,0x24,0x06,0x01,0x00,
-0x34,0x84,0x08,0x00,0x24,0xc2,0x00,0x01,0x28,0x43,0x02,0x00,0xac,0x82,0x00,0x00,
-0x00,0x40,0x30,0x21,0x14,0x60,0xff,0xfb,0x24,0x84,0x00,0x08,0x25,0xc2,0x00,0x0c,
-0x24,0x0a,0x00,0x02,0x3c,0x06,0xb0,0x03,0xaf,0x82,0xba,0x40,0x34,0xc6,0x00,0x64,
-0xa0,0x4a,0x00,0x18,0x94,0xc5,0x00,0x00,0x8f,0x82,0xba,0x40,0x25,0xc4,0x00,0x30,
-0x24,0x08,0x00,0x03,0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,
-0xaf,0x84,0xba,0x44,0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xba,0x44,
-0x25,0xc4,0x00,0x54,0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xba,0x48,
-0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xba,0x48,0x25,0xc8,0x00,0x9c,
-0x24,0x09,0x00,0x01,0xa0,0x45,0x00,0x21,0xaf,0x87,0xba,0x4c,0xa0,0xea,0x00,0x18,
-0x94,0xc4,0x00,0x00,0x8f,0x82,0xba,0x4c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,
-0xa0,0x44,0x00,0x21,0xaf,0x88,0xba,0x50,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,
-0x8f,0x82,0xba,0x50,0x25,0xc4,0x00,0xc0,0x25,0xc6,0x00,0xe4,0xa0,0x45,0x00,0x21,
-0xaf,0x84,0xba,0x54,0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xba,0x54,
-0x3c,0x04,0xb0,0x03,0x34,0x84,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x86,0xba,0x58,
-0xa0,0xc0,0x00,0x18,0x94,0x85,0x00,0x00,0x8f,0x82,0xba,0x58,0x25,0xc3,0x01,0x08,
-0x25,0xc6,0x01,0x2c,0xa0,0x45,0x00,0x21,0xaf,0x83,0xba,0x5c,0xa0,0x60,0x00,0x18,
-0x94,0x87,0x00,0x00,0x8f,0x82,0xba,0x5c,0x25,0xc5,0x01,0x50,0x25,0xc4,0x01,0x74,
-0xa0,0x47,0x00,0x21,0x25,0xc8,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,
-0x25,0xcb,0x02,0x04,0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,
-0x3c,0x03,0xb0,0x03,0xaf,0x86,0xba,0x60,0x34,0x63,0x00,0x38,0xa0,0xc0,0x00,0x18,
-0xaf,0x85,0xba,0x64,0xa0,0xa0,0x00,0x18,0xaf,0x84,0xba,0x68,0xa0,0x80,0x00,0x18,
-0xaf,0x88,0xba,0x6c,0xa1,0x00,0x00,0x18,0xaf,0x89,0xba,0x70,0xa1,0x20,0x00,0x18,
-0xaf,0x8a,0xba,0x74,0xa1,0x40,0x00,0x18,0xaf,0x8b,0xba,0x78,0xa1,0x60,0x00,0x18,
-0xaf,0x8c,0xba,0x7c,0xa1,0x80,0x00,0x18,0xaf,0x8d,0xba,0x80,0xa1,0xa2,0x00,0x18,
-0x94,0x64,0x00,0x00,0x8f,0x82,0xba,0x80,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,
-0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x11,0xaf,0x85,0xba,0x84,0x34,0x63,0x00,0x6e,
-0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xba,0x84,0x25,0xc5,0x02,0x94,
-0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xba,0x88,
-0x34,0x63,0x00,0x6c,0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xba,0x88,
-0x24,0x05,0xff,0xff,0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,
-0x27,0x84,0xba,0x40,0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,
-0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,
-0x8c,0x82,0x00,0x00,0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,
-0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,
-0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,
-0xa4,0x45,0x00,0x14,0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,
-0xa0,0x40,0x00,0x20,0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,
-0x24,0x63,0x75,0x54,0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x00,0x80,0x60,0x21,
-0x10,0x40,0x00,0x56,0x00,0x00,0x70,0x21,0x97,0x82,0x96,0x30,0x94,0x8a,0x00,0x0c,
-0x27,0x87,0x96,0x40,0x00,0x02,0x40,0xc0,0x01,0x02,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x47,0x10,0x21,0x90,0x8b,0x00,0x18,0xa4,0x4a,0x00,0x00,0x94,0x83,0x00,0x0e,
-0x39,0x64,0x00,0x10,0x2c,0x84,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x34,0x85,0x00,0x02,0x39,0x63,0x00,0x11,0x00,0x83,0x28,0x0b,0x34,0xa3,0x00,0x08,
-0x39,0x64,0x00,0x12,0x00,0x02,0x10,0x80,0x00,0xa4,0x18,0x0b,0x00,0x47,0x10,0x21,
-0x94,0x49,0x00,0x04,0x34,0x64,0x00,0x20,0x00,0x6b,0x20,0x0b,0x34,0x83,0x00,0x40,
-0x39,0x62,0x00,0x01,0x00,0x82,0x18,0x0b,0x00,0x09,0x30,0xc0,0x34,0x64,0x00,0x80,
-0x00,0xc9,0x28,0x21,0x39,0x62,0x00,0x02,0x00,0x60,0x68,0x21,0x00,0x82,0x68,0x0a,
-0x00,0x05,0x28,0x80,0x3c,0x02,0xb0,0x08,0x00,0xa7,0x28,0x21,0x00,0xc2,0x30,0x21,
-0x01,0x02,0x40,0x21,0x34,0x03,0xff,0xff,0x35,0xa4,0x01,0x00,0x39,0x62,0x00,0x03,
-0x2d,0x67,0x00,0x13,0xad,0x0a,0x00,0x00,0xa4,0xa3,0x00,0x00,0xac,0xc3,0x00,0x00,
-0xa7,0x89,0x96,0x30,0x10,0xe0,0x00,0x0f,0x00,0x82,0x68,0x0a,0x3c,0x03,0x80,0x01,
-0x00,0x0b,0x10,0x80,0x24,0x63,0x09,0x4c,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x34,0x63,0x00,0x60,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x00,
-0x00,0x02,0x74,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x44,0x00,0x00,
-0x93,0x83,0x96,0x24,0x91,0x82,0x00,0x21,0x01,0xc4,0x20,0x21,0x91,0x85,0x00,0x10,
-0x00,0x04,0x24,0x00,0x00,0x62,0x18,0x21,0x00,0x04,0x74,0x03,0x00,0x6e,0x18,0x23,
-0x00,0x65,0x10,0x2a,0x00,0xa2,0x18,0x0a,0x00,0x0d,0x24,0x00,0x3c,0x02,0xb0,0x06,
-0x24,0x05,0xff,0xff,0x00,0x64,0x18,0x25,0x34,0x42,0x80,0x20,0xac,0x43,0x00,0x00,
-0xa5,0x85,0x00,0x0e,0xa1,0x80,0x00,0x10,0xa5,0x85,0x00,0x0c,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x08,0x00,0x1d,0x99,0x34,0x63,0x00,0x62,
-0x3c,0x03,0xb0,0x03,0x08,0x00,0x1d,0x99,0x34,0x63,0x00,0x64,0x3c,0x03,0xb0,0x03,
-0x08,0x00,0x1d,0x99,0x34,0x63,0x00,0x66,0x3c,0x03,0xb0,0x03,0x08,0x00,0x1d,0x99,
-0x34,0x63,0x00,0x38,0x3c,0x03,0xb0,0x03,0x08,0x00,0x1d,0x99,0x34,0x63,0x00,0x6e,
-0x3c,0x03,0xb0,0x03,0x08,0x00,0x1d,0x99,0x34,0x63,0x00,0x6c,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x77,0x1c,0x00,0x05,0x28,0x40,
-0xac,0x62,0x00,0x00,0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10,0x14,0x80,0x00,0x06,
-0x00,0x00,0x18,0x21,0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x18,0x21,
-0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20,0x10,0xe2,0x00,0x06,
-0x2c,0xe4,0x00,0x10,0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9,0x00,0x02,0x11,0x00,
-0x08,0x00,0x1d,0xd4,0x00,0x47,0x18,0x21,0x08,0x00,0x1d,0xd4,0x24,0xa3,0x00,0x50,
-0x27,0xbd,0xff,0xc0,0xaf,0xb7,0x00,0x34,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,
-0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38,
-0xaf,0xb6,0x00,0x30,0xaf,0xb3,0x00,0x24,0xaf,0xb0,0x00,0x18,0x84,0x85,0x00,0x08,
-0x00,0x80,0x90,0x21,0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x34,0x84,0x00,0x20,
-0x24,0x42,0x77,0x80,0x3c,0x03,0xb0,0x06,0x00,0x05,0x28,0x80,0xac,0x82,0x00,0x00,
-0x00,0xa3,0x28,0x21,0x3c,0x04,0xb0,0x06,0x8c,0xa3,0x00,0x00,0x34,0x84,0x80,0x24,
-0x8c,0xa6,0x00,0x00,0x8c,0x82,0x00,0x00,0x30,0x71,0xff,0xff,0x00,0x11,0x2a,0x00,
-0x34,0x42,0x01,0x00,0x3c,0x03,0xb0,0x00,0xac,0x82,0x00,0x00,0x00,0xa3,0x40,0x21,
-0x8d,0x1e,0x00,0x00,0x8d,0x13,0x00,0x04,0x96,0x44,0x00,0x08,0x00,0x11,0xa0,0xc0,
-0x02,0x91,0x10,0x21,0x00,0x02,0x38,0x80,0x00,0x13,0x12,0x02,0x30,0x42,0x00,0x1f,
-0x24,0x84,0x00,0x02,0x27,0x83,0x96,0x50,0xa6,0x42,0x00,0x06,0x30,0x84,0x01,0xff,
-0x24,0x02,0x00,0x10,0x00,0xe3,0x18,0x21,0xa6,0x44,0x00,0x08,0x8d,0x10,0x00,0x08,
-0xa0,0x62,0x00,0x06,0x86,0x44,0x00,0x06,0x27,0x82,0x96,0x44,0x00,0xe2,0x10,0x21,
-0xac,0x48,0x00,0x18,0x24,0x02,0x00,0x13,0x00,0x06,0xbc,0x02,0x10,0x82,0x00,0xe6,
-0x00,0x00,0xa8,0x21,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,0xa6,0x40,0x00,0x02,
-0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x45,0x00,0x00,
-0x00,0x10,0x1b,0xc2,0x00,0x04,0x20,0x82,0x27,0x82,0x96,0x40,0x00,0xe2,0x10,0x21,
-0x30,0x84,0x00,0x01,0x30,0x63,0x00,0x01,0xac,0x45,0x00,0x08,0x10,0x60,0x00,0xbc,
-0xaf,0xa4,0x00,0x10,0x00,0x10,0x16,0x82,0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,
-0x00,0x10,0x19,0xc2,0x00,0x10,0x26,0x02,0x00,0x10,0x2e,0x42,0x30,0x47,0x00,0x7f,
-0x24,0x02,0x00,0x01,0x30,0x76,0x00,0x01,0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xa7,
-0x30,0xa3,0x00,0x01,0x0c,0x00,0x1d,0xc7,0x00,0x60,0x28,0x21,0x00,0x40,0xa8,0x21,
-0x02,0x91,0x10,0x21,0x00,0x02,0x10,0x80,0x2e,0xa4,0x00,0x54,0x27,0x85,0x96,0x50,
-0x27,0x83,0x96,0x48,0x00,0x04,0xa8,0x0a,0x00,0x45,0x28,0x21,0x26,0xc4,0x00,0x02,
-0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x06,0xa0,0x55,0x00,0x07,0xa0,0xb5,0x00,0x02,
-0xa0,0xb5,0x00,0x01,0x00,0x10,0x14,0x82,0x00,0x10,0x1d,0xc2,0x30,0x48,0x00,0x01,
-0x00,0x13,0x15,0x82,0x00,0x13,0x21,0x82,0x30,0x63,0x00,0x01,0x00,0x10,0x2c,0x02,
-0x00,0x10,0x34,0x42,0x30,0x49,0x00,0x03,0x24,0x02,0x00,0x01,0xa6,0x5e,0x00,0x04,
-0xa6,0x43,0x00,0x00,0x30,0x8a,0x00,0x01,0x32,0x73,0x00,0x07,0x30,0xa5,0x00,0x01,
-0x30,0xc6,0x00,0x01,0x11,0x02,0x00,0x77,0x32,0x07,0x00,0x7f,0x15,0x40,0x00,0x03,
-0x00,0x00,0x00,0x00,0x15,0x20,0x00,0x68,0x24,0x02,0x00,0x01,0x96,0x42,0x00,0x04,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04,0xa6,0x42,0x00,0x04,0x00,0xa0,0x20,0x21,
-0x00,0xc0,0x28,0x21,0x0c,0x00,0x1d,0xc7,0x01,0x00,0x30,0x21,0x02,0x91,0x18,0x21,
-0x00,0x03,0x38,0x80,0x2e,0xa5,0x00,0x54,0x27,0x84,0x96,0x50,0x00,0xe4,0x20,0x21,
-0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
-0x96,0x45,0x00,0x04,0x27,0x82,0x96,0x40,0x00,0xe2,0x10,0x21,0xa4,0x45,0x00,0x06,
-0x27,0x83,0x96,0x44,0x00,0xe3,0x18,0x21,0x92,0x45,0x00,0x01,0x8c,0x66,0x00,0x18,
-0x27,0x82,0x96,0x60,0x00,0xe2,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x85,0x00,0x07,
-0x94,0xc3,0x00,0x10,0x24,0x02,0x00,0x04,0x30,0x63,0x00,0x0f,0x10,0x62,0x00,0x42,
-0x24,0xc6,0x00,0x10,0x94,0xc3,0x00,0x16,0x27,0x88,0x96,0x58,0x00,0xe8,0x10,0x21,
-0xa4,0x43,0x00,0x02,0x94,0xc2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0x30,0x02,0x91,0x20,0x21,0x94,0xc2,0x00,0x00,0x24,0x03,0x00,0xa4,
-0x30,0x42,0x00,0xff,0x10,0x43,0x00,0x2b,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x00,
-0x24,0x03,0x00,0x88,0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x20,0x02,0x91,0x18,0x21,
-0x27,0x84,0x96,0x60,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x3c,0x04,0x00,0x80,0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x00,0x17,0x10,0xc0,
-0x00,0x57,0x10,0x21,0x27,0x84,0x96,0x40,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,
-0x94,0x45,0x00,0x00,0x02,0x91,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x64,0x20,0x21,
-0x24,0x02,0xff,0xff,0x00,0x68,0x18,0x21,0xa0,0x73,0x00,0x00,0xa4,0x82,0x00,0x02,
-0xa4,0x97,0x00,0x04,0xae,0x51,0x02,0xb8,0xa6,0x45,0x00,0x0a,0x7b,0xbe,0x01,0xfc,
-0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,
-0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x94,0xc2,0x00,0x18,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xdd,0x02,0x91,0x18,0x21,
-0x02,0x91,0x20,0x21,0x27,0x82,0x96,0x60,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21,
-0x8c,0x83,0x00,0x00,0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24,
-0x08,0x00,0x1e,0x97,0xac,0x83,0x00,0x00,0x27,0x88,0x96,0x58,0x00,0xe8,0x10,0x21,
-0x08,0x00,0x1e,0x81,0xa4,0x40,0x00,0x02,0x11,0x22,0x00,0x07,0x00,0x00,0x00,0x00,
-0x2d,0x22,0x00,0x02,0x14,0x40,0xff,0x9a,0x00,0xa0,0x20,0x21,0x96,0x42,0x00,0x04,
-0x08,0x00,0x1e,0x5e,0x24,0x42,0x00,0x0c,0x96,0x42,0x00,0x04,0x08,0x00,0x1e,0x5e,
-0x24,0x42,0x00,0x08,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x48,0xff,0x87,
-0x02,0x91,0x18,0x21,0x27,0x82,0x96,0x44,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,
-0x8c,0x64,0x00,0x18,0x3c,0x02,0xff,0xfb,0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,
-0xac,0x82,0x00,0x08,0x08,0x00,0x1e,0x57,0x00,0x00,0x40,0x21,0x8f,0xa2,0x00,0x10,
-0x00,0x00,0x00,0x00,0x14,0x46,0xff,0x57,0x3c,0x02,0xfb,0xff,0x34,0x42,0xff,0xff,
-0x02,0x02,0x10,0x24,0xad,0x02,0x00,0x08,0x08,0x00,0x1e,0x35,0x00,0x00,0x30,0x21,
-0x93,0x88,0xc1,0x54,0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82,0x27,0x82,0x96,0x48,
-0x2d,0x05,0x00,0x0c,0x00,0xe2,0x48,0x21,0x30,0x63,0x00,0x01,0x30,0x86,0x00,0x01,
-0x14,0xa0,0x00,0x06,0x01,0x00,0x38,0x21,0x00,0x03,0x10,0x40,0x00,0x46,0x10,0x21,
-0x00,0x02,0x11,0x00,0x01,0x02,0x10,0x21,0x24,0x47,0x00,0x04,0x02,0x91,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x84,0x96,0x50,0x27,0x83,0x96,0x48,0x00,0x44,0x20,0x21,
-0x00,0x43,0x10,0x21,0xa1,0x27,0x00,0x07,0xa0,0x40,0x00,0x06,0xa0,0x80,0x00,0x02,
-0x08,0x00,0x1e,0x45,0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01,0xa6,0x42,0x00,0x02,
-0x0c,0x00,0x04,0x40,0x01,0x00,0x20,0x21,0x08,0x00,0x1e,0xa7,0x00,0x00,0x00,0x00,
-0x30,0xa7,0xff,0xff,0x00,0x07,0x18,0xc0,0x00,0x67,0x18,0x21,0x3c,0x06,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x24,0x42,0x7c,0x10,0x27,0x85,0x96,0x50,0x00,0x03,0x18,0x80,
-0x34,0xc6,0x00,0x20,0x00,0x65,0x18,0x21,0xac,0xc2,0x00,0x00,0x80,0x62,0x00,0x07,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x29,0x00,0x80,0x28,0x21,0x90,0x82,0x00,0x16,
-0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01,0x14,0x60,0x00,0x02,
-0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x90,0xa2,0x00,0x04,0x3c,0x03,0xb0,0x03,
-0x27,0x86,0x96,0x40,0x14,0x40,0x00,0x06,0x34,0x63,0x00,0x20,0x24,0x02,0x00,0x01,
-0xa0,0xa2,0x00,0x04,0xa4,0xa7,0x00,0x02,0x03,0xe0,0x00,0x08,0xa4,0xa7,0x00,0x00,
-0x94,0xa4,0x00,0x02,0x3c,0x02,0x80,0x01,0x24,0x42,0x93,0x34,0xac,0x62,0x00,0x00,
-0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,
-0x94,0x62,0x00,0x04,0xa4,0x67,0x00,0x02,0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0,
-0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x00,0x83,0x20,0x21,
-0xa4,0x47,0x00,0x00,0xac,0x87,0x00,0x00,0x90,0xa2,0x00,0x04,0xa4,0xa7,0x00,0x02,
-0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x04,0x90,0x82,0x00,0x16,
-0x24,0x85,0x00,0x06,0x34,0x42,0x00,0x01,0x30,0x43,0x00,0x02,0x14,0x60,0xff,0xda,
-0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01,0x08,0x00,0x1f,0x1a,0xa0,0x82,0x00,0x17,
-0x27,0xbd,0xff,0xe8,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x00,0x80,0x80,0x21,
-0x84,0x84,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x7d,0x10,0x10,0x80,0x00,0x38,0xac,0x62,0x00,0x00,0x8e,0x04,0x02,0xb8,
-0x0c,0x00,0x02,0x7e,0x00,0x00,0x00,0x00,0x97,0x88,0x96,0x30,0x96,0x0c,0x02,0xba,
-0x3c,0x04,0xb0,0x08,0x00,0x08,0x30,0xc0,0x00,0xc4,0x10,0x21,0xac,0x4c,0x00,0x00,
-0x8e,0x03,0x02,0xb8,0x27,0x89,0x96,0x40,0x34,0x0b,0xff,0xff,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,0x94,0x4a,0x00,0x04,
-0x00,0xc8,0x30,0x21,0x00,0x06,0x30,0x80,0x00,0x0a,0x28,0xc0,0x00,0xa4,0x20,0x21,
-0xac,0x8b,0x00,0x00,0x8e,0x02,0x02,0xb8,0x27,0x84,0x96,0x50,0x00,0xaa,0x28,0x21,
-0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,0x27,0x82,0x96,0x44,
-0x00,0x62,0x10,0x21,0x8c,0x47,0x00,0x18,0x00,0x64,0x18,0x21,0x80,0x68,0x00,0x06,
-0x8c,0xe4,0x00,0x00,0x00,0x05,0x28,0x80,0x3c,0x03,0xb0,0x06,0x30,0x84,0xff,0xff,
-0x00,0x88,0x20,0x21,0x30,0x82,0x00,0xff,0x00,0x02,0x10,0x2b,0x00,0x04,0x22,0x02,
-0x00,0x82,0x20,0x21,0x3c,0x02,0x00,0x04,0x00,0xa9,0x28,0x21,0x00,0x82,0x20,0x25,
-0x00,0xc9,0x30,0x21,0x34,0x63,0x80,0x20,0xa4,0xcc,0x00,0x00,0xac,0x64,0x00,0x00,
-0xa4,0xab,0x00,0x00,0xa7,0x8a,0x96,0x30,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x86,0x03,0x00,0x06,0x27,0x82,0xba,0x40,
-0x96,0x05,0x02,0xba,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,
-0x0c,0x00,0x1f,0x04,0x00,0x00,0x00,0x00,0x08,0x00,0x1f,0x82,0x00,0x00,0x00,0x00,
-0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21,0x27,0x8a,0x96,0x40,0x00,0x08,0x18,0xc0,
-0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03,0x00,0x03,0x18,0x80,0x3c,0x02,0x80,0x00,
-0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x7e,0x40,0x30,0xa5,0xff,0xff,
-0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02,0x11,0x05,0x00,0x35,0x24,0x04,0x00,0x01,
-0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x86,0x10,0x2a,0x10,0x40,0x00,0x10,
-0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03,0x01,0x40,0x60,0x21,0x35,0xad,0x00,0x20,
-0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01,0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21,
-0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21,0x00,0x4a,0x10,0x21,0x00,0x86,0x18,0x2a,
-0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02,0x14,0x60,0xff,0xf5,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,0x00,0x08,0x20,0xc0,0x00,0x88,0x20,0x21,
-0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80,0xa1,0x62,0x00,0x04,0x00,0x8c,0x20,0x21,
-0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0,0x94,0x46,0x00,0x02,0x00,0xa3,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21,0xa4,0x66,0x00,0x00,0xa4,0x86,0x00,0x02,
-0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08,0x3c,0x02,0x80,0x01,0x00,0xa3,0x28,0x21,
-0x24,0x42,0x93,0x34,0xad,0xa2,0x00,0x00,0x10,0x87,0x00,0x03,0xac,0xa6,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x08,0x00,0x1f,0xd0,0xa5,0x68,0x00,0x02,
-0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00,0x24,0x42,0xff,0xff,0x30,0x43,0x00,0xff,
-0x14,0x60,0xff,0xf7,0xa1,0x62,0x00,0x04,0x24,0x02,0xff,0xff,0x08,0x00,0x1f,0xd0,
-0xa5,0x62,0x00,0x02,0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21,0x27,0xbd,0xff,0xd8,
-0x00,0x06,0x30,0x80,0x27,0x82,0x96,0x44,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10,0x00,0xc2,0x10,0x21,
-0x8c,0x47,0x00,0x18,0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,
-0x34,0xa5,0x00,0x20,0x24,0x42,0x7f,0x74,0xac,0xa2,0x00,0x00,0x27,0x83,0x96,0x50,
-0x00,0xc3,0x30,0x21,0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06,0x00,0x80,0x88,0x21,
-0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x02,
-0x00,0x02,0x12,0x02,0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff,0x01,0x12,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x50,0x00,0x43,0x10,0x21,0x80,0x44,0x00,0x07,
-0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06,0x32,0x50,0xff,0xff,
-0x02,0x20,0x20,0x21,0x0c,0x00,0x1f,0x90,0x02,0x00,0x28,0x21,0x92,0x22,0x00,0x10,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08,0x3c,0x09,0x80,0x01,
-0x27,0x88,0x96,0x40,0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0,0x00,0x90,0x20,0x21,
-0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,
-0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x48,0x10,0x21,0x00,0xa3,0x28,0x21,0x25,0x26,0x93,0x34,0x34,0x03,0xff,0xff,
-0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,
-0xac,0xa3,0x00,0x00,0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a,0xa6,0x32,0x00,0x0e,
-0x02,0x62,0x10,0x21,0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10,0x92,0x22,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16,0x92,0x22,0x00,0x04,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x22,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x20,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x96,0x22,0x00,0x0e,0x27,0x88,0x96,0x40,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,
-0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x06,0xb0,0x03,
-0x3c,0x09,0x80,0x01,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0xa3,0x28,0x21,0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20,0x25,0x23,0x93,0x34,
-0xac,0xc3,0x00,0x00,0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00,0x08,0x00,0x20,0x0e,
-0xa4,0x90,0x00,0x02,0x08,0x00,0x20,0x05,0x32,0x50,0xff,0xff,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x01,0x24,0x42,0x81,0x3c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,
-0x90,0x82,0x00,0x04,0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21,0x30,0xa8,0xff,0xff,
-0x00,0x4a,0x20,0x23,0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff,0x30,0xee,0xff,0xff,
-0x11,0x09,0x00,0x73,0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0,0x00,0x08,0x10,0xc0,
-0x00,0x48,0x10,0x21,0x03,0x0e,0x20,0x21,0x27,0x8d,0x96,0x40,0x00,0x04,0x20,0x80,
-0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21,0x94,0x86,0x00,0x02,
-0x94,0x43,0x00,0x04,0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02,0x00,0x03,0x28,0xc0,
-0x00,0xa3,0x18,0x21,0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08,0x00,0x03,0x18,0x80,
-0x00,0xa2,0x28,0x21,0x00,0x6d,0x18,0x21,0x27,0x22,0x93,0x34,0x3c,0x01,0xb0,0x03,
-0xac,0x22,0x00,0x20,0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57,0xac,0xa6,0x00,0x00,
-0x01,0xe0,0x30,0x21,0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21,0x01,0x40,0x38,0x21,
-0x27,0x8b,0x96,0x44,0x27,0x8a,0x96,0x50,0x00,0x06,0x40,0xc0,0x01,0x06,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x6a,0x18,0x21,
-0x80,0x65,0x00,0x06,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0xff,0xff,
-0x00,0x45,0x10,0x21,0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02,0x01,0x22,0x18,0x21,
-0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff,0x30,0x69,0x00,0xff,
-0x01,0x06,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x24,0xe7,0xff,0xff,
-0x94,0x46,0x00,0x02,0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0,0x91,0x82,0x00,0x10,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03,0xa5,0x8f,0x00,0x0c,
-0x03,0x0e,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,
-0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21,0x27,0x26,0x93,0x34,
-0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,
-0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10,0x91,0x83,0x00,0x04,
-0xa5,0x8e,0x00,0x0e,0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05,0xa1,0x82,0x00,0x10,
-0x91,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa1,0x82,0x00,0x16,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e,0x3c,0x03,0xb0,0x08,
-0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,
-0x94,0x82,0x00,0x04,0x34,0xc6,0x00,0x20,0x27,0x27,0x93,0x34,0x00,0x02,0x28,0xc0,
-0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x4d,0x10,0x21,
-0xac,0xc7,0x00,0x00,0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00,0xac,0xaf,0x00,0x00,
-0x08,0x00,0x20,0x9d,0x03,0x0e,0x20,0x21,0x08,0x00,0x20,0x78,0xa5,0x88,0x00,0x02,
-0x00,0x0e,0xc0,0xc0,0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8d,0x96,0x40,
-0x00,0x4d,0x10,0x21,0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x05,
-0xa5,0x83,0x00,0x00,0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01,0x08,0x00,0x20,0x78,
-0xa5,0x82,0x00,0x02,0x08,0x00,0x20,0x78,0x3c,0x19,0x80,0x01,0x3c,0x08,0xb0,0x03,
-0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0x80,0x24,0x42,0x83,0x7c,0x35,0x08,0x00,0x20,
-0xaf,0xb2,0x00,0x60,0xaf,0xb1,0x00,0x5c,0xaf,0xbf,0x00,0x7c,0xaf,0xbe,0x00,0x78,
-0xaf,0xb7,0x00,0x74,0xaf,0xb6,0x00,0x70,0xaf,0xb5,0x00,0x6c,0xaf,0xb4,0x00,0x68,
-0xaf,0xb3,0x00,0x64,0xaf,0xb0,0x00,0x58,0xad,0x02,0x00,0x00,0xaf,0xa4,0x00,0x80,
-0x90,0x83,0x00,0x0a,0x27,0x82,0xba,0x40,0xaf,0xa6,0x00,0x88,0x00,0x03,0x18,0x80,
-0x00,0x62,0x18,0x21,0x8c,0x7e,0x00,0x00,0xaf,0xa7,0x00,0x8c,0x27,0x86,0x96,0x44,
-0x97,0xc3,0x00,0x14,0x30,0xb1,0xff,0xff,0x00,0x03,0x20,0xc0,0xaf,0xa3,0x00,0x1c,
-0x00,0x83,0x18,0x21,0xaf,0xa4,0x00,0x50,0x00,0x03,0x18,0x80,0x27,0x84,0x96,0x50,
-0x00,0x64,0x20,0x21,0x80,0x82,0x00,0x06,0x00,0x66,0x18,0x21,0x8c,0x66,0x00,0x18,
-0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x8c,0xc4,0x00,0x08,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0x04,0x2f,0xc2,0x00,0x04,0x1c,0x82,
-0x00,0x04,0x24,0x42,0x30,0x63,0x00,0x01,0x00,0xc2,0x38,0x21,0x30,0x84,0x00,0x01,
-0x24,0x02,0x00,0x01,0xaf,0xa5,0x00,0x3c,0xaf,0xa3,0x00,0x34,0xaf,0xa4,0x00,0x38,
-0xaf,0xa0,0x00,0x40,0xaf,0xa0,0x00,0x44,0xaf,0xa2,0x00,0x20,0x83,0xc3,0x00,0x12,
-0x8f,0xb2,0x00,0x1c,0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xa2,0xaf,0xa3,0x00,0x28,
-0x00,0x10,0x10,0x82,0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11,0xaf,0xa0,0x00,0x30,
-0x8f,0xa4,0x00,0x90,0x27,0x82,0x86,0xb0,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x21,
-0x24,0xa2,0x00,0x06,0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00,0x00,0x45,0x10,0x04,
-0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,
-0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x42,0xff,0xfc,0xaf,0xa2,0x00,0x30,
-0x8f,0xa3,0x00,0x1c,0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff,0xaf,0xa0,0x00,0x2c,
-0xaf,0xa2,0x00,0x48,0xaf,0xa3,0x00,0x4c,0x00,0x60,0xb0,0x21,0x00,0x00,0xb8,0x21,
-0x18,0x80,0x00,0x3b,0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02,0xaf,0xb1,0x00,0x54,
-0x00,0x80,0xa8,0x21,0x00,0x12,0xa0,0xc0,0x02,0x92,0x10,0x21,0x00,0x02,0x80,0x80,
-0x27,0x85,0x96,0x40,0x02,0x05,0x18,0x21,0x94,0x63,0x00,0x02,0x02,0x40,0x20,0x21,
-0x00,0x00,0x28,0x21,0x0c,0x00,0x17,0x43,0xaf,0xa3,0x00,0x18,0x90,0x42,0x00,0x00,
-0x24,0x03,0x00,0x08,0x30,0x42,0x00,0x0c,0x10,0x43,0x01,0x5c,0x24,0x04,0x00,0x01,
-0x24,0x02,0x00,0x01,0x10,0x82,0x01,0x3b,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x04,
-0x02,0x92,0x20,0x21,0x94,0x66,0x00,0x00,0x00,0x04,0x20,0x80,0x27,0x82,0x96,0x48,
-0x00,0x82,0x10,0x21,0x27,0x83,0x96,0x50,0x80,0x45,0x00,0x06,0x00,0x83,0x20,0x21,
-0x30,0xd0,0xff,0xff,0x80,0x91,0x00,0x05,0x80,0x93,0x00,0x04,0x8f,0xa4,0x00,0x80,
-0x32,0x03,0x00,0xff,0x00,0x10,0x12,0x03,0x38,0xa5,0x00,0x00,0x00,0x60,0x80,0x21,
-0x00,0x45,0x80,0x0a,0xa4,0x82,0x00,0x44,0x12,0x20,0x01,0x1c,0xa4,0x83,0x00,0x46,
-0x02,0x71,0x10,0x21,0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xbb,0x02,0x92,0x10,0x21,
-0x93,0x82,0x91,0x51,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0xae,
-0x02,0x92,0x28,0x21,0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff,0x02,0x40,0xb0,0x21,
-0x26,0xb5,0xff,0xff,0x8f,0xb2,0x00,0x18,0x16,0xa0,0xff,0xca,0x00,0x00,0x00,0x00,
-0x16,0xe0,0x00,0x9e,0x02,0xc0,0x38,0x21,0x8f,0xa5,0x00,0x90,0x00,0x00,0x00,0x00,
-0x2c,0xa2,0x00,0x10,0x10,0x40,0x00,0x2e,0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x24,
-0x00,0x00,0x00,0x00,0x18,0x40,0x00,0x2a,0x24,0x03,0x00,0x01,0x97,0xd2,0x00,0x14,
-0xa3,0xc3,0x00,0x12,0x00,0x12,0x10,0xc0,0x00,0x52,0x10,0x21,0x00,0x02,0x80,0x80,
-0x27,0x82,0x96,0x50,0x02,0x02,0x10,0x21,0x80,0x43,0x00,0x06,0x27,0x84,0x96,0x44,
-0x02,0x04,0x20,0x21,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,
-0x8c,0x85,0x00,0x18,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0x00,0xa3,0x38,0x21,
-0x8f,0xa3,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0d,0x00,0x00,0x00,0x00,
-0x27,0x82,0x96,0x40,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x24,0x02,0x00,0x01,
-0xa7,0xc3,0x00,0x1a,0x7b,0xbe,0x03,0xfc,0x7b,0xb6,0x03,0xbc,0x7b,0xb4,0x03,0x7c,
-0x7b,0xb2,0x03,0x3c,0x7b,0xb0,0x02,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x80,
-0x8f,0xa4,0x00,0x90,0x8f,0xa5,0x00,0x38,0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10,
-0x0c,0x00,0x0d,0xfe,0xaf,0xa0,0x00,0x14,0x08,0x00,0x21,0x94,0x00,0x00,0x00,0x00,
-0x8f,0xa4,0x00,0x44,0x8f,0xa3,0x00,0x24,0x8f,0xa5,0x00,0x2c,0x30,0x82,0x00,0x03,
-0xa3,0xc3,0x00,0x12,0x00,0x02,0x10,0x23,0x8f,0xa4,0x00,0x80,0x30,0x42,0x00,0x03,
-0x00,0xa2,0x10,0x23,0xa7,0xc2,0x00,0x1a,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x96,0x44,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8f,0xa5,0x00,0x50,0x8f,0xa2,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0xa2,0x18,0x21,
-0x00,0x03,0x18,0x80,0x27,0x82,0x96,0x58,0x00,0x62,0x18,0x21,0x90,0x65,0x00,0x00,
-0x27,0x83,0xba,0xe0,0x00,0x05,0x11,0x00,0x00,0x45,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x45,0x10,0x23,0x00,0x02,0x30,0x80,0x00,0xc3,0x38,0x21,0x90,0xe4,0x00,0x00,
-0x24,0x02,0x00,0x1b,0x10,0x82,0x00,0x0e,0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x24,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x04,0x00,0xa0,0x20,0x21,0x8f,0xa2,0x00,0x24,
-0x08,0x00,0x21,0x99,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x21,0x00,0x00,0x28,0x21,
-0x0c,0x00,0x25,0xc4,0x00,0x00,0x38,0x21,0x08,0x00,0x21,0xd7,0x00,0x00,0x00,0x00,
-0x27,0x82,0xbb,0xc0,0x00,0xc2,0x20,0x21,0x94,0x83,0x00,0x00,0x24,0x02,0x00,0x05,
-0x10,0x43,0x00,0x25,0x24,0x62,0x00,0x01,0xa4,0x82,0x00,0x00,0x8f,0xa3,0x00,0x24,
-0x8f,0xa4,0x00,0x28,0x00,0x00,0x00,0x00,0x10,0x64,0xff,0xec,0x00,0x00,0x00,0x00,
-0x10,0x60,0xff,0xea,0x00,0x00,0x00,0x00,0x27,0x82,0xbb,0xb8,0x00,0xc2,0x20,0x21,
-0x90,0x83,0x00,0x06,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x03,
-0x24,0x62,0x00,0x01,0xa0,0x82,0x00,0x06,0x00,0x40,0x18,0x21,0x30,0x63,0x00,0xff,
-0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x09,0x00,0x00,0x00,0x00,0x27,0x84,0xba,0xe4,
-0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x58,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x23,
-0x24,0x42,0xff,0xc0,0x08,0x00,0x21,0xd7,0xac,0xe2,0x00,0xd0,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00,0x27,0x84,0xba,0xe4,0x00,0xc4,0x10,0x21,
-0x08,0x00,0x21,0xfc,0xac,0x43,0x00,0xe0,0x27,0x83,0xbb,0xb8,0x00,0xc3,0x18,0x21,
-0x90,0x62,0x00,0x06,0x00,0x00,0x00,0x00,0x2c,0x42,0x00,0x02,0x10,0x40,0xff,0xc7,
-0xa4,0x80,0x00,0x00,0x08,0x00,0x21,0xd7,0xa0,0x60,0x00,0x06,0x8f,0xa5,0x00,0x48,
-0x8f,0xa6,0x00,0x4c,0x03,0xc0,0x20,0x21,0x0c,0x00,0x20,0x4f,0xaf,0xb7,0x00,0x10,
-0x08,0x00,0x21,0x76,0x00,0x00,0x00,0x00,0x00,0x05,0x28,0x80,0x27,0x82,0x96,0x40,
-0x00,0xa2,0x28,0x21,0x00,0x00,0x20,0x21,0x0c,0x00,0x01,0x49,0x00,0x00,0x00,0x00,
-0x08,0x00,0x21,0x6e,0x26,0xe2,0x00,0x01,0x00,0x02,0x80,0x80,0x27,0x83,0x96,0x50,
-0x02,0x03,0x18,0x21,0x26,0x31,0x00,0x01,0x03,0xc0,0x20,0x21,0x02,0x40,0x28,0x21,
-0x0c,0x00,0x23,0x1c,0xa0,0x71,0x00,0x05,0x14,0x40,0xff,0x45,0x00,0x00,0x00,0x00,
-0x16,0xe0,0x00,0x4b,0x02,0xc0,0x38,0x21,0x8f,0xa5,0x00,0x24,0x8f,0xb6,0x00,0x18,
-0x8f,0xa3,0x00,0x20,0x24,0xa5,0x00,0x01,0x24,0x02,0x00,0x01,0xaf,0xb2,0x00,0x48,
-0xaf,0xb6,0x00,0x4c,0x10,0x62,0x00,0x40,0xaf,0xa5,0x00,0x24,0x27,0x82,0x96,0x40,
-0x02,0x02,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa5,0x00,0x30,0xaf,0xa0,0x00,0x20,
-0xaf,0xa2,0x00,0x44,0x8f,0xa4,0x00,0x44,0x30,0x42,0x00,0x03,0x00,0x02,0x10,0x23,
-0x30,0x42,0x00,0x03,0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,
-0x00,0x45,0x18,0x2b,0x10,0x60,0x00,0x29,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x2c,
-0x00,0xa2,0x10,0x23,0x00,0x85,0x18,0x21,0x30,0x63,0xff,0xff,0x30,0x45,0xff,0xff,
-0xaf,0xa3,0x00,0x2c,0x02,0x92,0x30,0x21,0x00,0x06,0x30,0x80,0x27,0x82,0x96,0x44,
-0x00,0xc2,0x10,0x21,0x8c,0x47,0x00,0x18,0x3c,0x04,0x80,0xff,0x34,0x84,0xff,0xff,
-0x8c,0xe3,0x00,0x04,0x3c,0x02,0x7f,0x00,0x00,0x05,0x2d,0x40,0x00,0xa2,0x28,0x24,
-0x00,0x64,0x18,0x24,0x00,0x65,0x18,0x25,0xac,0xe3,0x00,0x04,0x8f,0xa3,0x00,0x90,
-0x27,0x82,0x96,0x50,0x00,0xc2,0x10,0x21,0xa0,0x43,0x00,0x00,0x8c,0xe4,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0x04,0x27,0xc2,0x10,0x80,0xff,0x0d,0xaf,0xa4,0x00,0x3c,
-0x80,0x42,0x00,0x06,0x8f,0xa4,0x00,0x40,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xe2,0x38,0x21,
-0xa4,0xe4,0x00,0x00,0x08,0x00,0x21,0x71,0x26,0xb5,0xff,0xff,0x8f,0xa5,0x00,0x2c,
-0x00,0x00,0x00,0x00,0x00,0xa2,0x10,0x21,0x30,0x42,0xff,0xff,0xaf,0xa2,0x00,0x2c,
-0x08,0x00,0x22,0x4d,0x00,0x00,0x28,0x21,0x08,0x00,0x22,0x37,0xa7,0xd2,0x00,0x14,
-0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x03,0xc0,0x20,0x21,0x0c,0x00,0x20,0x4f,
-0xaf,0xb7,0x00,0x10,0x08,0x00,0x22,0x2e,0x00,0x00,0xb8,0x21,0x02,0x40,0x20,0x21,
-0x0c,0x00,0x17,0x43,0x00,0x00,0x28,0x21,0x00,0x40,0x18,0x21,0x94,0x42,0x00,0x00,
-0x00,0x00,0x00,0x00,0x34,0x42,0x08,0x00,0xa4,0x62,0x00,0x00,0x08,0x00,0x21,0x65,
-0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21,0x00,0x03,0x80,0x80,0x27,0x82,0x96,0x44,
-0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x10,0x60,0x00,0x0a,0x24,0x06,0x00,0x01,
-0x93,0x82,0x91,0x51,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xd5,
-0x00,0x00,0x00,0x00,0x27,0x85,0x96,0x40,0x02,0x05,0x28,0x21,0x08,0x00,0x22,0x1e,
-0x3c,0x04,0x00,0x80,0x27,0x83,0x96,0x58,0x27,0x82,0x96,0x50,0x02,0x03,0x18,0x21,
-0x02,0x02,0x10,0x21,0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05,0x0c,0x00,0x25,0xc4,
-0x00,0x00,0x38,0x21,0x08,0x00,0x22,0x94,0x00,0x00,0x00,0x00,0x27,0x82,0x96,0x58,
-0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x02,0x8f,0xa2,0x00,0x54,0x00,0x03,0x19,0x02,
-0x00,0x62,0x18,0x23,0x30,0x63,0x0f,0xff,0x28,0x62,0x00,0x20,0x10,0x40,0x00,0x06,
-0x28,0x62,0x00,0x40,0x8f,0xa4,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x64,0x10,0x06,
-0x08,0x00,0x21,0x4c,0x30,0x44,0x00,0x01,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,
-0x8f,0xa5,0x00,0x8c,0x08,0x00,0x22,0xb4,0x00,0x65,0x10,0x06,0x08,0x00,0x21,0x4c,
-0x00,0x00,0x20,0x21,0x8f,0xa4,0x00,0x90,0x8f,0xa5,0x00,0x38,0x8f,0xa6,0x00,0x34,
-0xaf,0xa0,0x00,0x10,0x0c,0x00,0x0d,0xfe,0xaf,0xa2,0x00,0x14,0x30,0x42,0xff,0xff,
-0x08,0x00,0x21,0x1c,0xaf,0xa2,0x00,0x40,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
-0x27,0xbd,0xff,0xe0,0x34,0x42,0x00,0x20,0x24,0x63,0x8b,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a,
-0x00,0x80,0x80,0x21,0x14,0x40,0x00,0x45,0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3c,0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18,
-0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc,
-0x10,0xa0,0x00,0x03,0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,
-0x92,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05,
-0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,
-0xa2,0x02,0x00,0x16,0x10,0x60,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x00,0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14,
-0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x01,0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17,
-0x08,0x00,0x22,0xf0,0xa6,0x03,0x00,0x14,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,
-0x27,0x86,0x96,0x40,0x00,0x04,0x10,0xc0,0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21,
-0x00,0x65,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,
-0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x0c,0x00,0x17,0x34,
-0x00,0x00,0x00,0x00,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17,
-0x96,0x02,0x00,0x06,0x08,0x00,0x22,0xf0,0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00,
-0x08,0x00,0x22,0xf0,0xa6,0x02,0x00,0x14,0x96,0x05,0x00,0x00,0x0c,0x00,0x23,0x1c,
-0x02,0x00,0x20,0x21,0x08,0x00,0x22,0xd7,0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06,
-0x0c,0x00,0x23,0x1c,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xd3,0x00,0x40,0x88,0x21,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0x8c,0x70,
-0x27,0xbd,0xff,0xf0,0xac,0x62,0x00,0x00,0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x10,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,
-0x24,0x42,0x8c,0x94,0xac,0x62,0x00,0x00,0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21,
-0x11,0x20,0x00,0x05,0x00,0xa0,0x50,0x21,0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x1b,0x00,0x00,0x00,0x00,0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00,
-0x10,0xe0,0x00,0x1b,0x00,0x00,0x00,0x00,0x94,0xc8,0x00,0x00,0x27,0x83,0x96,0x40,
-0x93,0x85,0x91,0x50,0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08,0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06,
-0x01,0x44,0x18,0x23,0x8f,0x82,0x91,0x68,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b,
-0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14,
-0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00,
-0x94,0xc2,0x00,0x06,0x24,0x03,0x00,0x08,0x08,0x00,0x23,0x48,0xa4,0xc2,0x00,0x14,
-0x08,0x00,0x23,0x48,0x00,0x00,0x18,0x21,0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c,
-0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30,
-0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21,
-0x3c,0x02,0x80,0x01,0x3c,0x04,0xb0,0x03,0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20,
-0x24,0x42,0x8d,0x48,0x02,0xb1,0x48,0x21,0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80,
-0x24,0x03,0x00,0x01,0x27,0x82,0x96,0x50,0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21,
-0x27,0x84,0x96,0x44,0x01,0x24,0x20,0x21,0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18,
-0x27,0x83,0x96,0x60,0x01,0x23,0x48,0x21,0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02,
-0x8d,0x42,0x00,0x00,0x8d,0x49,0x00,0x04,0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08,
-0x01,0x02,0x40,0x21,0x00,0x04,0x25,0xc2,0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01,
-0x00,0x03,0x1f,0xc2,0x00,0x08,0x40,0x40,0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24,
-0x00,0x09,0x49,0x42,0x01,0x48,0x10,0x21,0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21,
-0x00,0x40,0x38,0x21,0x02,0x00,0x28,0x21,0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01,
-0x94,0x42,0x00,0x00,0x02,0xb1,0x88,0x21,0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80,
-0x27,0x90,0x96,0x40,0x02,0x30,0x80,0x21,0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff,
-0x02,0x60,0x20,0x21,0x00,0x60,0x30,0x21,0xa6,0x83,0x00,0x1a,0x27,0x82,0x96,0x48,
-0x0c,0x00,0x0d,0xd7,0x02,0x22,0x88,0x21,0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06,
-0xa6,0x22,0x00,0x04,0x8f,0xbf,0x00,0x30,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,
-0x7b,0xb0,0x00,0xfc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,
-0xaf,0xa9,0x00,0x10,0x0c,0x00,0x0d,0xfe,0xaf,0xa0,0x00,0x14,0x08,0x00,0x23,0x86,
-0x02,0xb1,0x88,0x21,0x27,0xbd,0xff,0xc0,0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,
-0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,
-0xaf,0xbf,0x00,0x3c,0xaf,0xb4,0x00,0x28,0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18,
-0x94,0x90,0x00,0x00,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0,
-0x00,0x50,0x18,0x21,0x00,0x40,0x88,0x21,0x3c,0x02,0x80,0x01,0x00,0x03,0x48,0x80,
-0x24,0x42,0x8e,0x84,0x00,0x80,0x98,0x21,0x27,0x84,0x96,0x50,0x01,0x24,0x20,0x21,
-0x93,0xb7,0x00,0x53,0xad,0x02,0x00,0x00,0x80,0x83,0x00,0x06,0x27,0x82,0x96,0x44,
-0x01,0x22,0x10,0x21,0x8c,0x44,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,
-0x8c,0x88,0x00,0x08,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,
-0xaf,0xa7,0x00,0x4c,0x2c,0xa2,0x00,0x10,0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21,
-0x00,0x08,0x47,0xc2,0x00,0xc0,0x58,0x21,0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c,
-0x14,0x40,0x00,0x13,0x00,0x00,0xf0,0x21,0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01,
-0x12,0x87,0x00,0x10,0x02,0x30,0x10,0x21,0x27,0x83,0x96,0x58,0x01,0x23,0x18,0x21,
-0x80,0x64,0x00,0x00,0x27,0x83,0xbb,0xb0,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x90,0x44,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00,
-0x02,0x30,0x10,0x21,0x00,0x02,0x80,0x80,0x24,0x04,0x00,0x01,0x27,0x83,0x96,0x60,
-0xa2,0x64,0x00,0x12,0x02,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e,
-0x02,0xa0,0x20,0x21,0x27,0x82,0x96,0x40,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,
-0x00,0x00,0x00,0x00,0xa6,0x63,0x00,0x1a,0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc,
-0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21,
-0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x0d,0xfe,0xaf,0xa0,0x00,0x14,
-0x08,0x00,0x23,0xed,0x00,0x00,0x00,0x00,0x27,0x83,0x96,0x60,0x01,0x23,0x18,0x21,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,
-0x01,0x02,0x10,0x24,0x14,0x40,0x00,0xaf,0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03,
-0x00,0x12,0x10,0x82,0x25,0xe3,0x00,0x0d,0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04,
-0x10,0xa0,0x00,0x0e,0x00,0x00,0x90,0x21,0x27,0x82,0x86,0xb0,0x00,0x15,0x18,0x40,
-0x00,0x62,0x18,0x21,0x94,0x64,0x00,0x00,0x24,0xa2,0x00,0x06,0x00,0x54,0x10,0x04,
-0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,
-0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21,
-0x27,0x83,0x96,0x50,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03,
-0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04,
-0x2c,0x62,0x00,0x19,0x30,0x82,0x00,0x0f,0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19,
-0x10,0x40,0x00,0x19,0x24,0x0e,0x00,0x20,0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02,
-0x14,0x40,0x00,0x15,0x24,0x0e,0x00,0x08,0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02,
-0x14,0x40,0x00,0x11,0x24,0x0e,0x00,0x04,0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e,
-0x24,0x0e,0x00,0x02,0x24,0x62,0xff,0xef,0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,
-0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xf1,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06,
-0x24,0x0e,0x00,0x04,0x24,0x62,0xff,0xf3,0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x02,
-0x24,0x03,0x00,0x01,0x00,0x62,0x70,0x0a,0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21,
-0x00,0x00,0x68,0x21,0x10,0x40,0x00,0x6d,0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff,
-0x27,0x99,0x96,0x40,0x01,0xf2,0xc0,0x23,0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a,
-0x14,0x40,0x00,0x64,0x24,0x03,0x00,0x04,0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x59,0x10,0x21,0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00,
-0x32,0xcc,0x00,0x03,0x00,0x6c,0x10,0x23,0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21,
-0x24,0x42,0x00,0x04,0x30,0x51,0xff,0xff,0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d,
-0x01,0xf1,0x10,0x23,0x02,0x51,0x10,0x23,0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34,
-0x30,0x44,0xff,0xff,0x29,0x22,0x00,0x40,0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21,
-0x25,0x22,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21,
-0x00,0x02,0x30,0x80,0x27,0x82,0x96,0x44,0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21,
-0x8c,0x67,0x00,0x18,0x00,0x04,0x25,0x40,0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04,
-0x00,0x83,0x20,0x24,0x27,0x83,0x96,0x50,0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21,
-0x00,0x44,0x10,0x25,0xac,0xe2,0x00,0x04,0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00,
-0xa0,0xb5,0x00,0x03,0x27,0x84,0x96,0x60,0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x8c,0xe8,0x00,0x08,0x00,0x02,0x15,0xc2,0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01,
-0x01,0x02,0x10,0x24,0x10,0x40,0x00,0x0a,0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00,
-0x92,0x62,0x00,0x04,0x25,0xad,0x00,0x01,0x27,0x84,0x96,0x40,0x00,0xc4,0x18,0x21,
-0x01,0xa2,0x10,0x2a,0x94,0x70,0x00,0x02,0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00,
-0x96,0x63,0x00,0x14,0x00,0x0c,0x10,0x23,0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03,
-0x01,0x62,0x10,0x23,0x00,0x03,0x80,0xc0,0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff,
-0x02,0x03,0x80,0x21,0x27,0x82,0x96,0x48,0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a,
-0x02,0xa0,0x20,0x21,0x01,0x60,0x30,0x21,0x01,0x60,0x88,0x21,0x0c,0x00,0x0d,0xd7,
-0x02,0x02,0x80,0x21,0x00,0x5e,0x10,0x21,0xa6,0x02,0x00,0x04,0x08,0x00,0x23,0xf3,
-0x02,0x20,0x10,0x21,0x01,0x62,0x10,0x2b,0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21,
-0x29,0x22,0x00,0x40,0x10,0x40,0xff,0xe6,0x01,0x71,0x18,0x21,0x08,0x00,0x24,0x69,
-0x25,0x22,0x00,0x01,0x08,0x00,0x24,0x98,0x32,0xcc,0x00,0x03,0x08,0x00,0x24,0x98,
-0x00,0x00,0x60,0x21,0x8f,0xa5,0x00,0x4c,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,
-0x0c,0x00,0x0d,0xfe,0xaf,0xb4,0x00,0x14,0x92,0x67,0x00,0x04,0x08,0x00,0x24,0x0b,
-0x30,0x5e,0xff,0xff,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21,
-0x00,0x04,0x20,0x80,0x27,0x82,0x96,0x40,0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff,
-0x00,0x82,0x20,0x21,0x00,0xc3,0x30,0x21,0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08,
-0xa4,0x85,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21,
-0x27,0x88,0x96,0x40,0x00,0x06,0x30,0x80,0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04,
-0x3c,0x02,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x82,0x20,0x21,0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff,
-0x00,0x68,0x18,0x21,0x34,0xe7,0x00,0x20,0x24,0x42,0x93,0x34,0xac,0xe2,0x00,0x00,
-0xa4,0xc5,0x00,0x02,0xa4,0x65,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00,
-0x30,0x84,0xff,0xff,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x27,0x89,0x96,0x40,
-0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,0x97,0x83,0x96,0x30,0x94,0x4a,0x00,0x04,
-0x3c,0x02,0xb0,0x08,0x00,0x03,0x38,0xc0,0x00,0x0a,0x40,0xc0,0x00,0xe3,0x18,0x21,
-0x01,0x0a,0x28,0x21,0x00,0xe2,0x38,0x21,0x01,0x02,0x40,0x21,0x00,0x03,0x18,0x80,
-0x00,0x05,0x28,0x80,0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x01,0x00,0xa9,0x28,0x21,
-0x00,0x69,0x18,0x21,0x34,0xc6,0x00,0x20,0x34,0x09,0xff,0xff,0x24,0x42,0x93,0x90,
-0xac,0xc2,0x00,0x00,0xa4,0x64,0x00,0x00,0xac,0xe4,0x00,0x00,0xa4,0xa9,0x00,0x00,
-0xad,0x09,0x00,0x00,0xa7,0x8a,0x96,0x30,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0x94,0x10,
-0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x01,0x10,0x8c,0x82,0x00,0x00,
-0x97,0x83,0x87,0xf4,0x30,0x42,0xff,0xff,0x10,0x62,0x00,0x16,0x24,0x0a,0x00,0x01,
-0xa7,0x82,0x87,0xf4,0xaf,0x80,0xba,0x90,0x00,0x40,0x28,0x21,0x24,0x06,0x00,0x01,
-0x27,0x84,0xba,0x94,0x25,0x43,0xff,0xff,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,
-0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x8c,0x83,0xff,0xfc,0x00,0x00,0x00,0x00,
-0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x38,0x42,0x00,0x00,0x01,0x42,0x18,0x0a,
-0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x14,0xac,0x83,0x00,0x00,0x14,0x40,0xff,0xf1,
-0x24,0x84,0x00,0x04,0x3c,0x0b,0xb0,0x03,0x00,0x00,0x50,0x21,0x3c,0x0c,0x80,0x00,
-0x27,0x89,0xba,0xe0,0x35,0x6b,0x01,0x20,0x8d,0x68,0x00,0x00,0x8d,0x23,0x00,0x04,
-0x01,0x0c,0x10,0x24,0x00,0x02,0x17,0xc2,0x11,0x03,0x00,0x37,0xa1,0x22,0x00,0xdc,
-0xa1,0x20,0x00,0xd5,0xa1,0x20,0x00,0xd6,0x01,0x20,0x30,0x21,0x00,0x00,0x38,0x21,
-0x00,0x00,0x28,0x21,0x01,0x20,0x20,0x21,0x00,0xa8,0x10,0x06,0x30,0x42,0x00,0x01,
-0x10,0xe0,0x00,0x10,0xa0,0x82,0x00,0x0a,0x90,0x82,0x00,0x07,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x31,0x24,0xa2,0xff,0xff,0xa0,0x82,0x00,0x08,0x90,0x82,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x08,
-0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x40,0x00,0x43,0x10,0x21,0x00,0x46,0x10,0x21,
-0xa0,0x45,0x00,0x09,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x07,
-0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x04,0x00,0x00,0x00,0x00,0xa0,0xc5,0x00,0xd5,
-0x24,0x07,0x00,0x01,0xa0,0x85,0x00,0x08,0xa0,0xc5,0x00,0xd6,0x24,0xa5,0x00,0x01,
-0x2c,0xa2,0x00,0x1c,0x14,0x40,0xff,0xe0,0x24,0x84,0x00,0x03,0x90,0xc4,0x00,0xd5,
-0x00,0x00,0x28,0x21,0x00,0xa4,0x10,0x2b,0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,
-0x00,0xc0,0x18,0x21,0xa0,0x64,0x00,0x08,0x90,0xc2,0x00,0xd5,0x24,0xa5,0x00,0x01,
-0xa0,0x62,0x00,0x09,0x90,0xc4,0x00,0xd5,0x00,0x00,0x00,0x00,0x00,0xa4,0x10,0x2b,
-0x14,0x40,0xff,0xf8,0x24,0x63,0x00,0x03,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x08,
-0xad,0x28,0x00,0x04,0x25,0x6b,0x00,0x04,0x14,0x40,0xff,0xbf,0x25,0x29,0x00,0xec,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x05,0x08,0x00,0x25,0x3f,
-0xa0,0x82,0x00,0x08,0x97,0x84,0x91,0x5a,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,
-0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0x95,0xc4,0xaf,0xbf,0x00,0x10,
-0xac,0x62,0x00,0x00,0x00,0x04,0x20,0x42,0x00,0x00,0x40,0x21,0x27,0x8f,0xba,0xe4,
-0x00,0x00,0x50,0x21,0x00,0x00,0x58,0x21,0x27,0x98,0xbb,0xc4,0x27,0x99,0xbb,0xc0,
-0x27,0x8e,0xbb,0xbe,0x27,0x8c,0xba,0xe8,0x27,0x8d,0xbb,0x40,0x27,0x89,0xbb,0xb8,
-0x00,0x0a,0x18,0x80,0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00,0xac,0x44,0x00,0x58,
-0x00,0x6e,0x28,0x21,0x00,0x78,0x10,0x21,0xa1,0x20,0xff,0xfc,0xad,0x20,0x00,0x00,
-0xa1,0x20,0x00,0x04,0xa1,0x20,0x00,0x05,0xad,0x20,0xff,0xf8,0x00,0x79,0x18,0x21,
-0x24,0x06,0x00,0x01,0x24,0xc6,0xff,0xff,0xa0,0xa0,0x00,0x00,0xa4,0x60,0x00,0x00,
-0xac,0x40,0x00,0x00,0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04,0x04,0xc1,0xff,0xf9,
-0x24,0xa5,0x00,0x01,0x00,0x0a,0x10,0x80,0x00,0x4d,0x28,0x21,0x00,0x00,0x30,0x21,
-0x00,0x4c,0x18,0x21,0x27,0x87,0x87,0xf8,0x8c,0xe2,0x00,0x00,0x24,0xe7,0x00,0x04,
-0xac,0xa2,0x00,0x00,0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01,0x24,0xc6,0x00,0x01,
-0x28,0xc2,0x00,0x1c,0xa0,0x60,0x00,0x02,0x24,0xa5,0x00,0x04,0x14,0x40,0xff,0xf6,
-0x24,0x63,0x00,0x03,0x25,0x08,0x00,0x01,0x29,0x02,0x00,0x08,0x25,0x4a,0x00,0x3b,
-0x25,0x29,0x00,0xec,0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec,0xa7,0x80,0x87,0xf4,
-0x00,0x00,0x40,0x21,0x27,0x83,0xba,0x90,0xac,0x68,0x00,0x00,0x25,0x08,0x00,0x01,
-0x29,0x02,0x00,0x0c,0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04,0x0c,0x00,0x25,0x04,
-0x00,0x00,0x00,0x00,0x27,0x83,0xba,0xe0,0x24,0x08,0x00,0x07,0x90,0x62,0x00,0xd6,
-0x25,0x08,0xff,0xff,0xa0,0x62,0x00,0x00,0x05,0x01,0xff,0xfc,0x24,0x63,0x00,0xec,
-0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x30,0x84,0x00,0xff,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xba,0xe0,0x00,0x43,0x40,0x21,
-0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x84,0x00,0x20,0x24,0x42,0x97,0x10,
-0x30,0xc6,0x00,0xff,0xac,0x82,0x00,0x00,0x30,0xa5,0x00,0xff,0x30,0xe7,0x00,0xff,
-0x10,0xc0,0x00,0x41,0x25,0x0f,0x00,0xd0,0x91,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
-0x24,0x62,0xff,0xee,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x31,0x30,0x63,0x00,0xff,
-0x24,0x02,0x00,0x1a,0x10,0x62,0x00,0x2e,0x24,0x02,0x00,0x1b,0x10,0x62,0x00,0x2c,
-0x24,0x02,0x00,0x11,0x10,0x62,0x00,0x1e,0x24,0x02,0x00,0x18,0x10,0x62,0x00,0x1c,
-0x24,0x02,0x00,0x19,0x10,0x62,0x00,0x1a,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x06,
-0x24,0x02,0x00,0x01,0x8d,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,
-0x03,0xe0,0x00,0x08,0xad,0x02,0x00,0xd0,0x10,0xa2,0x00,0x0e,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x04,
-0x00,0x00,0x00,0x00,0x8d,0x02,0x00,0xd0,0x08,0x00,0x25,0xec,0x24,0x42,0xff,0xe0,
-0x8d,0x02,0x00,0xd0,0x08,0x00,0x25,0xec,0x24,0x42,0xff,0xf8,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x8d,0x02,0x00,0xd0,0x08,0x00,0x25,0xec,0x24,0x42,0x00,0x01,
-0x10,0xa0,0xff,0xe8,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xfa,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xf5,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xed,
-0x00,0x00,0x00,0x00,0x8d,0x02,0x00,0xd0,0x08,0x00,0x25,0xec,0x24,0x42,0xff,0xe8,
-0x10,0xa0,0xff,0xf0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xeb,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe6,0x00,0x00,0x00,0x00,0x8d,0x02,0x00,0xd0,
-0x08,0x00,0x25,0xec,0x24,0x42,0xff,0xd0,0x91,0x06,0x00,0x00,0x91,0x03,0x00,0xd4,
-0x25,0x0d,0x00,0x5c,0x30,0xc4,0x00,0xff,0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21,
-0x00,0x04,0x50,0x80,0x01,0x02,0x58,0x21,0x01,0x0a,0x48,0x21,0x00,0xc0,0x60,0x21,
-0x25,0x78,0x00,0x08,0x10,0x60,0x00,0x36,0x25,0x2e,0x00,0x60,0x10,0xa0,0x00,0x25,
-0x00,0x00,0x00,0x00,0x91,0x02,0x00,0xdd,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e,
-0x00,0x00,0x00,0x00,0x27,0x86,0x87,0xf8,0x01,0x46,0x10,0x21,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xad,0x23,0x00,0x60,0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00,
-0x00,0x40,0x60,0x21,0xa1,0x02,0x00,0x00,0x31,0x82,0x00,0xff,0x00,0x02,0x10,0x80,
-0x00,0x46,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42,
-0xad,0xa3,0x00,0x00,0x91,0x04,0x00,0x00,0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80,
-0x00,0x86,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x05,0x28,0x40,0x00,0x88,0x20,0x21,
-0x00,0x03,0x32,0x80,0x00,0xa6,0x10,0x2b,0x00,0xc2,0x28,0x0a,0xac,0x85,0x00,0x60,
-0x03,0xe0,0x00,0x08,0xa1,0x00,0x00,0xd4,0x27,0x86,0x87,0xf8,0x08,0x00,0x26,0x32,
-0xa1,0x00,0x00,0xdd,0x27,0x82,0x88,0x68,0x8d,0x03,0x00,0xd8,0x00,0x82,0x10,0x21,
-0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01,0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0xab,
-0xad,0x03,0x00,0xd8,0x8d,0x22,0x00,0x60,0xa1,0x00,0x00,0xd4,0x00,0x02,0x1f,0xc2,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x03,0xe0,0x00,0x08,0xad,0x02,0x00,0x5c,
-0x10,0xe0,0x00,0x14,0x24,0xc2,0xff,0xee,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0xa4,
-0x24,0x02,0x00,0x1a,0x10,0x82,0x00,0xa2,0x24,0x02,0x00,0x1b,0x10,0x82,0x00,0xa0,
-0x24,0x02,0x00,0x11,0x10,0x82,0x00,0x92,0x24,0x02,0x00,0x18,0x10,0x82,0x00,0x90,
-0x24,0x02,0x00,0x19,0x10,0x82,0x00,0x8e,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x7c,
-0x24,0x02,0x00,0x01,0x8d,0x02,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,
-0xad,0x02,0x00,0xd0,0x8d,0xe3,0x00,0x00,0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x43,0x10,0x21,0xad,0xa2,0x00,0x00,0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,
-0x8d,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x4d,
-0x24,0x02,0x00,0x1b,0x93,0x05,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x21,
-0x00,0x00,0x00,0x00,0x91,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05,
-0x24,0x02,0x00,0x01,0xa1,0x05,0x00,0x00,0xa1,0x02,0x00,0xd4,0x03,0xe0,0x00,0x08,
-0xad,0x00,0x00,0xd8,0x91,0x02,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05,
-0x00,0x00,0x00,0x00,0xa1,0x03,0x00,0xd4,0xad,0x00,0x00,0xd8,0x03,0xe0,0x00,0x08,
-0xa1,0x03,0x00,0xdd,0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43,
-0xad,0xa2,0x00,0x00,0x91,0x03,0x00,0x00,0x27,0x82,0x87,0xf8,0x8d,0xc5,0x00,0x00,
-0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40,
-0x00,0x04,0x32,0x80,0x00,0xa6,0x10,0x2b,0x00,0xc2,0x28,0x0a,0x08,0x00,0x26,0x44,
-0xad,0xc5,0x00,0x00,0x91,0x02,0x00,0xde,0x00,0x00,0x00,0x00,0x2c,0x42,0x00,0x02,
-0x14,0x40,0xff,0xdc,0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43,
-0xad,0xa2,0x00,0x00,0x91,0x03,0x00,0x00,0x27,0x82,0x87,0xf8,0x8d,0xc5,0x00,0x00,
-0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40,
-0x3c,0x03,0xb0,0x03,0x00,0x04,0x32,0x80,0x00,0xa6,0x10,0x2b,0x00,0xc2,0x28,0x0a,
-0xad,0xc5,0x00,0x00,0x34,0x63,0x01,0x08,0x8c,0x64,0x00,0x00,0x8d,0x03,0x00,0xe4,
-0x00,0x00,0x00,0x00,0x00,0x64,0x10,0x2b,0x14,0x40,0x00,0x03,0x00,0x83,0x28,0x23,
-0x00,0x83,0x10,0x23,0x24,0x45,0xff,0xff,0x3c,0x02,0x00,0x98,0x34,0x42,0x96,0x80,
-0x00,0x45,0x10,0x2b,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0xa5,0x00,0x00,0xe0,
-0x03,0xe0,0x00,0x08,0xa1,0x00,0x00,0xde,0x24,0x02,0x00,0x03,0x03,0xe0,0x00,0x08,
-0xa1,0x02,0x00,0xde,0x97,0x82,0x91,0x5c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a,
-0x10,0x40,0xff,0x32,0x00,0x00,0x00,0x00,0x91,0x02,0x00,0xdd,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x15,0x00,0x00,0x00,0x00,0x91,0x03,0x00,0x00,0x27,0x82,0x87,0xf8,
-0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x68,0x18,0x21,
-0xac,0x64,0x00,0x60,0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80,
-0x01,0x02,0x10,0x21,0x24,0x4e,0x00,0x60,0xa1,0x05,0x00,0x00,0x8d,0xc2,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,
-0x03,0xe0,0x00,0x08,0xad,0xa2,0x00,0x00,0x08,0x00,0x26,0xdb,0xa1,0x00,0x00,0xdd,
-0x10,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x85,
-0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x8d,0x02,0x00,0xd0,
-0x08,0x00,0x26,0x6c,0x24,0x42,0xff,0xe0,0x8d,0x02,0x00,0xd0,0x08,0x00,0x26,0x6c,
-0x24,0x42,0xff,0xf8,0x8d,0x02,0x00,0xd0,0x08,0x00,0x26,0x6c,0x24,0x42,0x00,0x01,
-0x10,0xa0,0xff,0x74,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xfa,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x73,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xef,
-0x00,0x00,0x00,0x00,0x8d,0x02,0x00,0xd0,0x08,0x00,0x26,0x6c,0x24,0x42,0xff,0xe8,
-0x10,0xa0,0xff,0xf0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x69,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe8,0x00,0x00,0x00,0x00,0x8d,0x02,0x00,0xd0,
-0x08,0x00,0x26,0x6c,0x24,0x42,0xff,0xd0,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03,
-0xaf,0xbf,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x8c,0x50,0x00,0x00,
-0x00,0x00,0x00,0x00,0x32,0x03,0x00,0x01,0x14,0x60,0x00,0x14,0x00,0x00,0x00,0x00,
-0x32,0x02,0x01,0x00,0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,
-0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x01,0xa3,0x82,0x92,0x14,0x8f,0xbf,0x00,0x14,
-0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x0a,0x65,
-0x00,0x00,0x00,0x00,0x26,0x02,0xff,0x00,0xa3,0x80,0x92,0x14,0x3c,0x01,0xb0,0x03,
-0xac,0x22,0x01,0x18,0x08,0x00,0x27,0x18,0x32,0x02,0x08,0x00,0x0c,0x00,0x25,0x71,
-0x00,0x00,0x00,0x00,0x26,0x02,0xff,0xff,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,
-0x08,0x00,0x27,0x15,0x32,0x02,0x01,0x00,0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0xd0,0xaf,0xbf,0x00,0x18,0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,
-0x24,0x07,0x0f,0xff,0x00,0x03,0x33,0x02,0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,
-0x30,0x69,0x0f,0xff,0x00,0x62,0x18,0x24,0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,
-0x10,0x60,0x00,0x08,0x31,0x08,0x00,0xff,0x01,0x00,0x30,0x21,0x0c,0x00,0x27,0x4b,
-0xaf,0xa9,0x00,0x10,0x8f,0xbf,0x00,0x18,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x0c,0x00,0x27,0xae,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x34,0x63,0x00,0xd4,0x08,0x00,0x27,0x41,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xd8,
-0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e,0xaf,0xb4,0x00,0x20,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x24,0xaf,0xb3,0x00,0x1c,
-0x30,0xb1,0x00,0xff,0x8f,0xb4,0x00,0x38,0x14,0x40,0x00,0x07,0x00,0x80,0x90,0x21,
-0x8f,0xbf,0x00,0x24,0x8f,0xb4,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10,0x24,0x05,0x00,0x14,
-0x0c,0x00,0x18,0xa0,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x46,0x02,0x40,0x20,0x21,
-0x02,0x00,0x90,0x21,0x00,0x14,0x1c,0x00,0x32,0x42,0x00,0x3f,0x24,0x04,0x00,0x50,
-0x0c,0x00,0x01,0x31,0x00,0x62,0x80,0x25,0x24,0x03,0x00,0x01,0x12,0x23,0x00,0x3a,
-0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x34,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x2f,
-0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x28,0x02,0x00,0x30,0x21,0x16,0x60,0xff,0xe4,
-0x00,0x00,0x00,0x00,0x16,0x40,0x00,0x1f,0x02,0x80,0x80,0x21,0x0c,0x00,0x01,0x31,
-0x24,0x04,0x00,0x50,0x24,0x03,0x00,0x01,0x12,0x23,0x00,0x16,0x2a,0x22,0x00,0x02,
-0x14,0x40,0x00,0x0f,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,
-0x16,0x22,0xff,0xd7,0x32,0x06,0x0e,0xbf,0x00,0x06,0x34,0x00,0x24,0x04,0x08,0x4c,
-0x0c,0x00,0x18,0x5b,0x24,0x05,0xff,0xff,0x08,0x00,0x27,0x58,0x00,0x00,0x00,0x00,
-0x32,0x06,0x0e,0xbf,0x00,0x06,0x34,0x00,0x08,0x00,0x27,0x84,0x24,0x04,0x08,0x48,
-0x16,0x20,0xff,0xcb,0x32,0x06,0x0e,0xbf,0x00,0x06,0x34,0x00,0x08,0x00,0x27,0x84,
-0x24,0x04,0x08,0x40,0x32,0x06,0x0e,0xbf,0x00,0x06,0x34,0x00,0x08,0x00,0x27,0x84,
-0x24,0x04,0x08,0x44,0x02,0x20,0x20,0x21,0x0c,0x00,0x28,0x46,0x00,0x00,0x28,0x21,
-0x08,0x00,0x27,0x77,0x00,0x40,0x80,0x21,0x24,0x04,0x08,0x4c,0x0c,0x00,0x18,0x5b,
-0x24,0x05,0xff,0xff,0x08,0x00,0x27,0x73,0x00,0x00,0x00,0x00,0x02,0x00,0x30,0x21,
-0x08,0x00,0x27,0x9b,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x02,0x00,0x30,0x21,
-0x08,0x00,0x27,0x9b,0x24,0x04,0x08,0x40,0x02,0x00,0x30,0x21,0x08,0x00,0x27,0x9b,
-0x24,0x04,0x08,0x44,0x02,0x00,0x30,0x21,0x0c,0x00,0x27,0xf5,0x02,0x20,0x28,0x21,
-0x08,0x00,0x27,0x65,0x00,0x40,0x90,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e,
-0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,
-0xaf,0xb2,0x00,0x18,0x00,0xc0,0x80,0x21,0x30,0xb1,0x00,0xff,0x00,0x80,0x98,0x21,
-0x14,0x40,0x00,0x07,0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x2e,0x12,0x00,0x10,0x24,0x05,0x00,0x14,0x0c,0x00,0x18,0xa0,0x24,0x06,0x01,0x07,
-0x12,0x40,0x00,0x2a,0x02,0x00,0x10,0x21,0x30,0x45,0x00,0x3f,0x0c,0x00,0x28,0x46,
-0x02,0x20,0x20,0x21,0x12,0x40,0x00,0x03,0x00,0x40,0x98,0x21,0x08,0x00,0x27,0xba,
-0x02,0x60,0x18,0x21,0x02,0x20,0x20,0x21,0x0c,0x00,0x28,0x46,0x00,0x00,0x28,0x21,
-0x24,0x04,0x00,0x50,0x0c,0x00,0x01,0x31,0x00,0x40,0x80,0x21,0x24,0x03,0x00,0x01,
-0x12,0x23,0x00,0x16,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0f,0x24,0x02,0x00,0x02,
-0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,0x16,0x22,0xff,0xf0,0x32,0x06,0x0e,0xbf,
-0x00,0x06,0x34,0x00,0x24,0x04,0x08,0x4c,0x0c,0x00,0x18,0x5b,0x24,0x05,0xff,0xff,
-0x08,0x00,0x27,0xba,0x02,0x60,0x18,0x21,0x32,0x06,0x0e,0xbf,0x00,0x06,0x34,0x00,
-0x08,0x00,0x27,0xde,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe4,0x32,0x06,0x0e,0xbf,
-0x00,0x06,0x34,0x00,0x08,0x00,0x27,0xde,0x24,0x04,0x08,0x40,0x32,0x06,0x0e,0xbf,
-0x00,0x06,0x34,0x00,0x08,0x00,0x27,0xde,0x24,0x04,0x08,0x44,0x02,0x60,0x20,0x21,
-0x02,0x00,0x30,0x21,0x0c,0x00,0x27,0xf5,0x02,0x20,0x28,0x21,0x08,0x00,0x27,0xc7,
-0x30,0x45,0x00,0x3f,0x27,0xbd,0xff,0xe0,0xaf,0xb0,0x00,0x10,0x30,0xb0,0x00,0xff,
-0x02,0x00,0x20,0x21,0x00,0x00,0x28,0x21,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x1c,
-0x00,0xc0,0x88,0x21,0x0c,0x00,0x28,0x46,0xaf,0xb2,0x00,0x18,0x00,0x40,0x18,0x21,
-0x2e,0x22,0x00,0x1f,0x10,0x40,0x00,0x26,0x2e,0x22,0x00,0x10,0x10,0x40,0x00,0x07,
-0x34,0x62,0x01,0x00,0x02,0x20,0x10,0x21,0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x00,0x50,
-0x0c,0x00,0x01,0x31,0x00,0x02,0x94,0x00,0x24,0x03,0x00,0x01,0x12,0x03,0x00,0x15,
-0x2a,0x02,0x00,0x02,0x14,0x40,0x00,0x0f,0x24,0x02,0x00,0x02,0x12,0x02,0x00,0x0a,
-0x24,0x02,0x00,0x03,0x12,0x02,0x00,0x03,0x02,0x40,0x30,0x21,0x08,0x00,0x28,0x05,
-0x26,0x31,0xff,0xf1,0x24,0x04,0x08,0x4c,0x0c,0x00,0x18,0x5b,0x24,0x05,0xff,0xff,
-0x08,0x00,0x28,0x05,0x26,0x31,0xff,0xf1,0x02,0x40,0x30,0x21,0x08,0x00,0x28,0x1a,
-0x24,0x04,0x08,0x48,0x16,0x00,0xff,0xf5,0x02,0x40,0x30,0x21,0x08,0x00,0x28,0x1a,
-0x24,0x04,0x08,0x40,0x02,0x40,0x30,0x21,0x08,0x00,0x28,0x1a,0x24,0x04,0x08,0x44,
-0x34,0x62,0x01,0x40,0x24,0x04,0x00,0x50,0x0c,0x00,0x01,0x31,0x00,0x02,0x94,0x00,
-0x24,0x03,0x00,0x01,0x12,0x03,0x00,0x15,0x2a,0x02,0x00,0x02,0x14,0x40,0x00,0x0f,
-0x24,0x02,0x00,0x02,0x12,0x02,0x00,0x0a,0x24,0x02,0x00,0x03,0x12,0x02,0x00,0x03,
-0x02,0x40,0x30,0x21,0x08,0x00,0x28,0x05,0x26,0x31,0xff,0xe2,0x24,0x04,0x08,0x4c,
-0x0c,0x00,0x18,0x5b,0x24,0x05,0xff,0xff,0x08,0x00,0x28,0x05,0x26,0x31,0xff,0xe2,
-0x02,0x40,0x30,0x21,0x08,0x00,0x28,0x38,0x24,0x04,0x08,0x48,0x16,0x00,0xff,0xf5,
-0x02,0x40,0x30,0x21,0x08,0x00,0x28,0x38,0x24,0x04,0x08,0x40,0x02,0x40,0x30,0x21,
-0x08,0x00,0x28,0x38,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe0,0x00,0x80,0x10,0x21,
-0x24,0x04,0x00,0x50,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,
-0x00,0xa0,0x88,0x21,0x0c,0x00,0x01,0x31,0x30,0x50,0x00,0xff,0x24,0x03,0x00,0x01,
-0x12,0x03,0x00,0x3e,0x02,0x20,0x30,0x21,0x2a,0x02,0x00,0x02,0x14,0x40,0x00,0x2a,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x12,0x02,0x00,0x19,0x24,0x04,0x08,0x34,
-0x24,0x02,0x00,0x03,0x12,0x02,0x00,0x05,0x24,0x04,0x08,0x3c,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x18,0x5b,
-0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x18,0x5b,
-0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00,0x24,0x06,0x00,0x01,0x0c,0x00,0x18,0x5b,
-0x24,0x04,0x08,0x3c,0x0c,0x00,0x01,0x31,0x24,0x04,0x00,0x28,0x24,0x04,0x08,0xac,
-0x0c,0x00,0x18,0x3d,0x24,0x05,0x0f,0xff,0x08,0x00,0x28,0x5b,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x18,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x18,0x5b,0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00,0x24,0x06,0x00,0x01,
-0x0c,0x00,0x18,0x5b,0x24,0x04,0x08,0x34,0x0c,0x00,0x01,0x31,0x24,0x04,0x00,0x28,
-0x08,0x00,0x28,0x6c,0x24,0x04,0x08,0xa8,0x16,0x00,0xff,0xdc,0x02,0x20,0x30,0x21,
-0x24,0x04,0x08,0x24,0x0c,0x00,0x18,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24,
-0x3c,0x05,0x80,0x00,0x0c,0x00,0x18,0x5b,0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00,
-0x24,0x06,0x00,0x01,0x0c,0x00,0x18,0x5b,0x24,0x04,0x08,0x24,0x0c,0x00,0x01,0x31,
-0x24,0x04,0x00,0x28,0x08,0x00,0x28,0x6c,0x24,0x04,0x08,0xa0,0x24,0x04,0x08,0x2c,
-0x0c,0x00,0x18,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x18,0x5b,0x00,0x00,0x30,0x21,0x3c,0x05,0x80,0x00,0x24,0x06,0x00,0x01,
-0x0c,0x00,0x18,0x5b,0x24,0x04,0x08,0x2c,0x0c,0x00,0x01,0x31,0x24,0x04,0x00,0x28,
-0x08,0x00,0x28,0x6c,0x24,0x04,0x08,0xa4,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
-0x0c,0x00,0x29,0x4c,0x00,0x00,0x00,0x00,0x0c,0x00,0x29,0x4e,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x29,0x75,0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x04,
-0x0c,0x00,0x29,0x55,0x34,0x05,0x9c,0x40,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,
-0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x97,0x82,0x88,0x90,0x00,0x00,0x00,0x00,
-0x2c,0x43,0x00,0x64,0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x90,0x14,0x60,0x00,0x28,
-0x00,0x80,0x30,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0x20,0x00,0xa7,0x80,0x88,0x90,
-0x00,0x43,0x10,0x24,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,
-0x3c,0x03,0x80,0x00,0x00,0x43,0x10,0x25,0x97,0x83,0x88,0x84,0xac,0x82,0x00,0x00,
-0x8c,0x85,0x00,0x00,0x24,0x63,0x00,0x01,0x3c,0x02,0x40,0x64,0x34,0x42,0x64,0x00,
-0x00,0x03,0x24,0x00,0x00,0xa2,0x28,0x25,0x00,0x04,0x24,0x03,0x24,0x02,0x00,0x64,
-0xac,0xc5,0x00,0x00,0xa7,0x83,0x88,0x84,0x10,0x82,0x00,0x2b,0x00,0x00,0x00,0x00,
-0x87,0x82,0x88,0x86,0x24,0x03,0x00,0x3c,0x10,0x43,0x00,0x21,0x00,0x00,0x00,0x00,
-0x87,0x82,0x88,0x88,0x00,0x00,0x00,0x00,0x10,0x43,0x00,0x17,0x00,0x00,0x00,0x00,
-0x87,0x83,0x88,0x8a,0x24,0x02,0x00,0x18,0x10,0x62,0x00,0x0d,0x00,0x00,0x00,0x00,
-0x87,0x83,0x88,0x8c,0x24,0x02,0x01,0x6d,0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x8e,0xa7,0x80,0x88,0x8c,
-0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x8e,0x08,0x00,0x28,0xe4,0x00,0x00,0x00,0x00,
-0x97,0x82,0x88,0x8c,0xa7,0x80,0x88,0x8a,0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x8c,
-0x08,0x00,0x28,0xe0,0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x8a,0xa7,0x80,0x88,0x88,
-0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x8a,0x08,0x00,0x28,0xdc,0x00,0x00,0x00,0x00,
-0x97,0x82,0x88,0x88,0xa7,0x80,0x88,0x86,0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x88,
-0x08,0x00,0x28,0xd8,0x00,0x00,0x00,0x00,0x97,0x82,0x88,0x86,0xa7,0x80,0x88,0x84,
-0x24,0x42,0x00,0x01,0xa7,0x82,0x88,0x86,0x08,0x00,0x28,0xd4,0x00,0x00,0x00,0x00,
-0x00,0x04,0x24,0x00,0x3c,0x03,0xb0,0x07,0x00,0x04,0x24,0x03,0x34,0x63,0x00,0x28,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x40,0x10,0x40,0xff,0xfc,
-0x00,0x00,0x00,0x00,0x3c,0x01,0xb0,0x07,0xa0,0x24,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x10,0x21,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x28,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x10,0x60,0x00,0x06,0x24,0x02,0xff,0xff,
-0x3c,0x02,0xb0,0x07,0x90,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x16,0x00,
-0x00,0x02,0x16,0x03,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe0,
-0xaf,0xb0,0x00,0x10,0x3c,0x10,0x04,0xc4,0x00,0x04,0x11,0x00,0x36,0x10,0xb4,0x00,
-0x02,0x02,0x00,0x1b,0xaf,0xb1,0x00,0x14,0x3c,0x11,0xb0,0x07,0x36,0x31,0x00,0x18,
-0x24,0x04,0x00,0x0a,0xaf,0xbf,0x00,0x18,0x14,0x40,0x00,0x02,0x00,0x00,0x00,0x00,
-0x00,0x07,0x00,0x0d,0x00,0x00,0x80,0x12,0x0c,0x00,0x29,0xa1,0x00,0x00,0x00,0x00,
-0x92,0x22,0x00,0x00,0x24,0x03,0xff,0x80,0x24,0x04,0x00,0x0a,0x00,0x43,0x10,0x25,
-0x0c,0x00,0x29,0xa1,0xa2,0x22,0x00,0x00,0x24,0x04,0x00,0x0a,0x3c,0x01,0xb0,0x07,
-0xa0,0x30,0x00,0x00,0x0c,0x00,0x29,0xa1,0x00,0x10,0x82,0x03,0x3c,0x02,0xb0,0x07,
-0x34,0x42,0x00,0x08,0xa0,0x50,0x00,0x00,0x0c,0x00,0x29,0xa1,0x24,0x04,0x00,0x0a,
-0x92,0x22,0x00,0x00,0x8f,0xbf,0x00,0x18,0x8f,0xb0,0x00,0x10,0x30,0x42,0x00,0x7f,
-0xa2,0x22,0x00,0x00,0x8f,0xb1,0x00,0x14,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x58,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x42,0x07,0xa4,0x03,0xe0,0x00,0x08,
-0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xf8,0x00,0x80,0x38,0x21,0x00,0xa0,0x30,0x21,
-0x00,0x00,0x18,0x21,0x00,0x63,0x00,0x18,0x00,0x00,0x10,0x12,0x00,0xc2,0x10,0x2b,
-0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x01,0x00,
-0x14,0x40,0xff,0xf9,0x00,0x63,0x00,0x18,0x24,0x63,0xff,0xff,0x00,0x63,0x00,0x18,
-0x30,0x63,0x00,0xff,0x8c,0xe4,0x00,0x00,0x00,0x03,0x2a,0x00,0x00,0x03,0x1c,0x00,
-0x00,0x00,0x10,0x12,0x00,0xc2,0x10,0x23,0x30,0x42,0x00,0xff,0x00,0x45,0x10,0x21,
-0x00,0x43,0x10,0x21,0x00,0x82,0x20,0x25,0xac,0xe4,0x00,0x00,0x8c,0xe2,0x00,0x00,
-0x3c,0x03,0x40,0x00,0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x08,0x27,0xbd,0xff,0xe0,0xaf,0xbf,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00,0x3c,0x06,0xb0,0x03,
-0x34,0xc6,0x00,0x08,0x34,0x42,0x40,0x00,0xac,0x82,0x00,0x00,0x8c,0x83,0x00,0x00,
-0x24,0x02,0xcf,0xff,0x3c,0x11,0xb0,0x07,0x00,0x62,0x18,0x24,0xac,0x83,0x00,0x00,
-0x8c,0xc5,0x00,0x00,0x3c,0x02,0x00,0xff,0x24,0x04,0x00,0x0a,0x00,0xa2,0x28,0x25,
-0xac,0xc5,0x00,0x00,0x0c,0x00,0x29,0xa1,0x36,0x31,0x00,0x18,0x24,0x02,0xff,0x83,
-0x3c,0x04,0x00,0x01,0xa2,0x22,0x00,0x00,0x0c,0x00,0x29,0x1f,0x34,0x84,0xc2,0x00,
-0x0c,0x00,0x29,0xa1,0x24,0x04,0x00,0x0a,0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x00,
-0x24,0x04,0x00,0x0a,0x0c,0x00,0x29,0xa1,0x3c,0x10,0xb0,0x07,0x36,0x10,0x00,0x10,
-0x24,0x02,0x00,0x06,0xa2,0x02,0x00,0x00,0x0c,0x00,0x29,0xa1,0x24,0x04,0x00,0x0a,
-0xa2,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x10,0x80,0x00,0x05,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,
-0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xb5,0x00,0x34,0xaf,0xb2,0x00,0x28,
-0xaf,0xb0,0x00,0x20,0xaf,0xbf,0x00,0x38,0xaf,0xb4,0x00,0x30,0xaf,0xb3,0x00,0x2c,
-0xaf,0xb1,0x00,0x24,0xaf,0xa5,0x00,0x44,0x90,0xa7,0x00,0x00,0x00,0x80,0xa8,0x21,
-0x00,0xc0,0x90,0x21,0x00,0x07,0x1e,0x00,0x10,0x60,0x00,0x0f,0x00,0x80,0x80,0x21,
-0x00,0x03,0x1e,0x03,0x24,0x02,0x00,0x25,0x10,0x62,0x00,0x13,0x00,0x00,0x88,0x21,
-0xa2,0x07,0x00,0x00,0x8f,0xa5,0x00,0x44,0x26,0x10,0x00,0x01,0x24,0xa5,0x00,0x01,
-0xaf,0xa5,0x00,0x44,0x90,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1e,0x00,
-0x14,0x60,0xff,0xf3,0x00,0x00,0x00,0x00,0x02,0x15,0x10,0x23,0xa2,0x00,0x00,0x00,
-0x8f,0xbf,0x00,0x38,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x24,0xa5,0x00,0x01,0xaf,0xa5,0x00,0x44,
-0x80,0xa3,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x63,0xff,0xe0,0x2c,0x62,0x00,0x11,
-0x10,0x40,0x00,0x11,0x00,0xa0,0x38,0x21,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,
-0x24,0x63,0x09,0x98,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x29,0xce,0x36,0x31,0x00,0x10,
-0x08,0x00,0x29,0xce,0x36,0x31,0x00,0x08,0x08,0x00,0x29,0xce,0x36,0x31,0x00,0x20,
-0x08,0x00,0x29,0xce,0x36,0x31,0x00,0x04,0x90,0xe4,0x00,0x00,0x3c,0x02,0x80,0x01,
-0x24,0x42,0x02,0x14,0x00,0x44,0x10,0x21,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x63,0x00,0x04,0x14,0x60,0x00,0xfd,0x24,0x14,0xff,0xff,0x00,0x04,0x16,0x00,
-0x00,0x02,0x16,0x03,0x24,0x03,0x00,0x2a,0x10,0x43,0x00,0xee,0x26,0x42,0x00,0x03,
-0x80,0xa3,0x00,0x00,0x24,0x02,0x00,0x2e,0x10,0x62,0x00,0xcc,0x24,0x08,0xff,0xff,
-0x80,0xa3,0x00,0x00,0x24,0x02,0x00,0x68,0x10,0x62,0x00,0xc4,0x24,0x06,0xff,0xff,
-0x24,0x02,0x00,0x6c,0x10,0x62,0x00,0xc1,0x24,0x02,0x00,0x4c,0x10,0x62,0x00,0xbf,
-0x24,0x02,0x00,0x5a,0x10,0x62,0x00,0xbd,0x00,0x00,0x00,0x00,0x80,0xa3,0x00,0x00,
-0x00,0x00,0x00,0x00,0x24,0x63,0xff,0xdb,0x2c,0x62,0x00,0x54,0x10,0x40,0x00,0xaa,
-0x24,0x09,0x00,0x0a,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x09,0xdc,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
-0x00,0x00,0x00,0x00,0x32,0x22,0x00,0x10,0x14,0x40,0x00,0x09,0x24,0x02,0xff,0xfc,
-0x26,0x94,0xff,0xff,0x1a,0x80,0x00,0x05,0x24,0x02,0x00,0x20,0x26,0x94,0xff,0xff,
-0xa2,0x02,0x00,0x00,0x1e,0x80,0xff,0xfd,0x26,0x10,0x00,0x01,0x24,0x02,0xff,0xfc,
-0x26,0x44,0x00,0x03,0x00,0x82,0x90,0x24,0x92,0x42,0x00,0x03,0x26,0x94,0xff,0xff,
-0x26,0x52,0x00,0x04,0xa2,0x02,0x00,0x00,0x1a,0x80,0x00,0x06,0x26,0x10,0x00,0x01,
-0x24,0x02,0x00,0x20,0x26,0x94,0xff,0xff,0xa2,0x02,0x00,0x00,0x1e,0x80,0xff,0xfd,
-0x26,0x10,0x00,0x01,0x8f,0xa5,0x00,0x44,0x08,0x00,0x29,0xc0,0x24,0xa5,0x00,0x01,
-0x24,0x02,0x00,0x25,0x08,0x00,0x29,0xbd,0xa2,0x02,0x00,0x00,0x36,0x31,0x00,0x40,
-0x24,0x09,0x00,0x10,0x24,0x02,0x00,0x4c,0x10,0xc2,0x00,0x2a,0x24,0x02,0x00,0x6c,
-0x10,0xc2,0x00,0x05,0x24,0x02,0x00,0x5a,0x10,0xc2,0x00,0x1f,0x24,0x02,0x00,0x68,
-0x10,0xc2,0x00,0x13,0x24,0x02,0xff,0xfc,0x24,0x02,0xff,0xfc,0x26,0x43,0x00,0x03,
-0x00,0x62,0x90,0x24,0x32,0x22,0x00,0x02,0x8e,0x47,0x00,0x00,0x00,0x00,0x30,0x21,
-0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x00,0xe0,0x10,0x21,0x00,0x02,0x37,0xc3,
-0x02,0x00,0x20,0x21,0xaf,0xa9,0x00,0x10,0xaf,0xb4,0x00,0x14,0xaf,0xa8,0x00,0x18,
-0x0c,0x00,0x2b,0x0e,0xaf,0xb1,0x00,0x1c,0x08,0x00,0x2a,0x29,0x00,0x40,0x80,0x21,
-0x26,0x43,0x00,0x03,0x00,0x62,0x90,0x24,0x32,0x22,0x00,0x02,0x96,0x47,0x00,0x02,
-0x00,0x00,0x30,0x21,0x10,0x40,0xff,0xf2,0x26,0x52,0x00,0x04,0x00,0x07,0x14,0x00,
-0x08,0x00,0x2a,0x43,0x00,0x02,0x3c,0x03,0x26,0x42,0x00,0x03,0x24,0x03,0xff,0xfc,
-0x00,0x43,0x90,0x24,0x8e,0x47,0x00,0x00,0x00,0x00,0x30,0x21,0x08,0x00,0x2a,0x44,
-0x26,0x52,0x00,0x04,0x26,0x42,0x00,0x07,0x24,0x03,0xff,0xf8,0x00,0x43,0x90,0x24,
-0x8e,0x46,0x00,0x00,0x8e,0x47,0x00,0x04,0x08,0x00,0x2a,0x44,0x26,0x52,0x00,0x08,
-0x08,0x00,0x2a,0x31,0x36,0x31,0x00,0x02,0x26,0x44,0x00,0x03,0x24,0x02,0xff,0xfc,
-0x00,0x82,0x90,0x24,0x8e,0x44,0x00,0x00,0x02,0x15,0x10,0x23,0x26,0x52,0x00,0x04,
-0x08,0x00,0x29,0xbf,0xac,0x82,0x00,0x00,0x08,0x00,0x2a,0x31,0x24,0x09,0x00,0x08,
-0x24,0x02,0xff,0xff,0x12,0x82,0x00,0x11,0x00,0x00,0x00,0x00,0x26,0x43,0x00,0x03,
-0x24,0x02,0xff,0xfc,0x00,0x62,0x90,0x24,0x8e,0x47,0x00,0x00,0x02,0x00,0x20,0x21,
-0x24,0x02,0x00,0x10,0x00,0x00,0x30,0x21,0xaf,0xa2,0x00,0x10,0xaf,0xb4,0x00,0x14,
-0xaf,0xa8,0x00,0x18,0x0c,0x00,0x2b,0x0e,0xaf,0xb1,0x00,0x1c,0x8f,0xa5,0x00,0x44,
-0x00,0x40,0x80,0x21,0x08,0x00,0x29,0xbf,0x26,0x52,0x00,0x04,0x24,0x14,0x00,0x08,
-0x08,0x00,0x2a,0x73,0x36,0x31,0x00,0x01,0x26,0x42,0x00,0x03,0x24,0x03,0xff,0xfc,
-0x00,0x43,0x90,0x24,0x8e,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x60,0x00,0x23,
-0x26,0x52,0x00,0x04,0x02,0x60,0x20,0x21,0x0c,0x00,0x2b,0xdc,0x01,0x00,0x28,0x21,
-0x00,0x40,0x20,0x21,0x32,0x22,0x00,0x10,0x14,0x40,0x00,0x09,0x00,0x94,0x10,0x2a,
-0x10,0x40,0x00,0x07,0x26,0x94,0xff,0xff,0x24,0x03,0x00,0x20,0x00,0x94,0x10,0x2a,
-0xa2,0x03,0x00,0x00,0x26,0x94,0xff,0xff,0x14,0x40,0xff,0xfc,0x26,0x10,0x00,0x01,
-0x18,0x80,0x00,0x07,0x00,0x80,0x18,0x21,0x92,0x62,0x00,0x00,0x24,0x63,0xff,0xff,
-0x26,0x73,0x00,0x01,0xa2,0x02,0x00,0x00,0x14,0x60,0xff,0xfb,0x26,0x10,0x00,0x01,
-0x00,0x94,0x10,0x2a,0x10,0x40,0xff,0x83,0x26,0x94,0xff,0xff,0x24,0x03,0x00,0x20,
-0x00,0x94,0x10,0x2a,0xa2,0x03,0x00,0x00,0x26,0x94,0xff,0xff,0x14,0x40,0xff,0xfc,
-0x26,0x10,0x00,0x01,0x08,0x00,0x2a,0x29,0x00,0x00,0x00,0x00,0x3c,0x02,0x80,0x01,
-0x08,0x00,0x2a,0x8d,0x24,0x53,0x08,0x84,0x24,0x02,0x00,0x25,0xa2,0x02,0x00,0x00,
-0x8f,0xa5,0x00,0x44,0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x00,0x90,0xa3,0x00,0x00,
-0x10,0x40,0x00,0x03,0x26,0x10,0x00,0x01,0x08,0x00,0x29,0xbd,0xa2,0x03,0x00,0x00,
-0x24,0xa5,0xff,0xff,0x08,0x00,0x29,0xbf,0xaf,0xa5,0x00,0x44,0x80,0xa6,0x00,0x00,
-0x24,0xa5,0x00,0x01,0x08,0x00,0x2a,0x03,0xaf,0xa5,0x00,0x44,0x24,0xa5,0x00,0x01,
-0xaf,0xa5,0x00,0x44,0x90,0xa4,0x00,0x00,0x3c,0x02,0x80,0x01,0x24,0x42,0x02,0x14,
-0x00,0x44,0x10,0x21,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04,
-0x14,0x60,0x00,0x0f,0x00,0x04,0x16,0x00,0x00,0x02,0x16,0x03,0x24,0x03,0x00,0x2a,
-0x10,0x43,0x00,0x04,0x26,0x42,0x00,0x03,0x29,0x02,0x00,0x00,0x08,0x00,0x29,0xf8,
-0x00,0x02,0x40,0x0b,0x24,0x03,0xff,0xfc,0x00,0x43,0x90,0x24,0x24,0xa5,0x00,0x01,
-0x8e,0x48,0x00,0x00,0xaf,0xa5,0x00,0x44,0x08,0x00,0x2a,0xd2,0x26,0x52,0x00,0x04,
-0x0c,0x00,0x2a,0xf2,0x27,0xa4,0x00,0x44,0x8f,0xa5,0x00,0x44,0x08,0x00,0x2a,0xd2,
-0x00,0x40,0x40,0x21,0x24,0x03,0xff,0xfc,0x00,0x43,0x90,0x24,0x8e,0x54,0x00,0x00,
-0x24,0xe5,0x00,0x01,0xaf,0xa5,0x00,0x44,0x06,0x81,0xff,0x0d,0x26,0x52,0x00,0x04,
-0x00,0x14,0xa0,0x23,0x08,0x00,0x29,0xf4,0x36,0x31,0x00,0x10,0x0c,0x00,0x2a,0xf2,
-0x27,0xa4,0x00,0x44,0x8f,0xa5,0x00,0x44,0x08,0x00,0x29,0xf4,0x00,0x40,0xa0,0x21,
-0x08,0x00,0x29,0xce,0x36,0x31,0x00,0x01,0x8c,0x86,0x00,0x00,0x3c,0x02,0x80,0x01,
-0x00,0x80,0x48,0x21,0x90,0xc3,0x00,0x00,0x24,0x44,0x02,0x14,0x00,0x64,0x18,0x21,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x04,0x10,0x40,0x00,0x10,
-0x00,0x00,0x38,0x21,0x00,0x80,0x40,0x21,0x24,0xc2,0x00,0x01,0x80,0xc5,0x00,0x00,
-0xad,0x22,0x00,0x00,0x90,0x43,0x00,0x00,0x00,0x40,0x30,0x21,0x00,0x07,0x10,0x80,
-0x00,0x68,0x18,0x21,0x90,0x64,0x00,0x00,0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x40,
-0x00,0x45,0x10,0x21,0x30,0x84,0x00,0x04,0x14,0x80,0xff,0xf3,0x24,0x47,0xff,0xd0,
-0x03,0xe0,0x00,0x08,0x00,0xe0,0x10,0x21,0x27,0xbd,0xff,0x98,0xaf,0xb2,0x00,0x50,
-0x8f,0xb2,0x00,0x84,0x3c,0x02,0x80,0x01,0xaf,0xb4,0x00,0x58,0x32,0x43,0x00,0x40,
-0xaf,0xb1,0x00,0x4c,0xaf,0xb0,0x00,0x48,0xaf,0xb7,0x00,0x64,0xaf,0xb6,0x00,0x60,
-0xaf,0xb5,0x00,0x5c,0xaf,0xb3,0x00,0x54,0x00,0x80,0x68,0x21,0x00,0xc0,0x70,0x21,
-0x00,0xe0,0x78,0x21,0x8f,0xb0,0x00,0x78,0x8f,0xb8,0x00,0x7c,0x8f,0xb1,0x00,0x80,
-0x10,0x60,0x00,0x03,0x24,0x54,0x08,0x8c,0x3c,0x02,0x80,0x01,0x24,0x54,0x08,0xb4,
-0x32,0x42,0x00,0x10,0x10,0x40,0x00,0x04,0x26,0x02,0xff,0xfe,0x24,0x02,0xff,0xfe,
-0x02,0x42,0x90,0x24,0x26,0x02,0xff,0xfe,0x2c,0x42,0x00,0x23,0x10,0x40,0x00,0x5d,
-0x00,0x00,0x18,0x21,0x32,0x42,0x00,0x01,0x24,0x15,0x00,0x30,0x24,0x03,0x00,0x20,
-0x32,0x44,0x00,0x02,0x00,0x62,0xa8,0x0a,0x10,0x80,0x00,0x07,0x00,0x00,0xb8,0x21,
-0x05,0xc0,0x00,0x96,0x32,0x42,0x00,0x04,0x10,0x40,0x00,0x90,0x32,0x42,0x00,0x08,
-0x24,0x17,0x00,0x2b,0x27,0x18,0xff,0xff,0x32,0x56,0x00,0x20,0x12,0xc0,0x00,0x07,
-0x01,0xcf,0x10,0x25,0x24,0x02,0x00,0x10,0x12,0x02,0x00,0x86,0x27,0x03,0xff,0xff,
-0x3a,0x02,0x00,0x08,0x00,0x62,0xc0,0x0a,0x01,0xcf,0x10,0x25,0x14,0x40,0x00,0x55,
-0x00,0x00,0xc8,0x21,0x24,0x02,0x00,0x30,0x24,0x19,0x00,0x01,0xa3,0xa2,0x00,0x00,
-0x02,0x39,0x10,0x2a,0x03,0x22,0x88,0x0b,0x32,0x43,0x00,0x11,0x14,0x60,0x00,0x0a,
-0x03,0x11,0xc0,0x23,0x03,0x00,0x10,0x21,0x18,0x40,0x00,0x07,0x27,0x18,0xff,0xff,
-0x24,0x03,0x00,0x20,0x03,0x00,0x10,0x21,0xa1,0xa3,0x00,0x00,0x27,0x18,0xff,0xff,
-0x1c,0x40,0xff,0xfc,0x25,0xad,0x00,0x01,0x12,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,
-0xa1,0xb7,0x00,0x00,0x25,0xad,0x00,0x01,0x12,0xc0,0x00,0x07,0x32,0x42,0x00,0x10,
-0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x38,0x24,0x02,0x00,0x10,0x12,0x02,0x00,0x30,
-0x24,0x02,0x00,0x30,0x32,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,0x03,0x31,0x10,0x2a,
-0x03,0x00,0x10,0x21,0x18,0x40,0x00,0x06,0x27,0x18,0xff,0xff,0x03,0x00,0x10,0x21,
-0xa1,0xb5,0x00,0x00,0x27,0x18,0xff,0xff,0x1c,0x40,0xff,0xfc,0x25,0xad,0x00,0x01,
-0x03,0x31,0x10,0x2a,0x10,0x40,0x00,0x07,0x26,0x31,0xff,0xff,0x24,0x03,0x00,0x30,
-0x03,0x31,0x10,0x2a,0xa1,0xa3,0x00,0x00,0x26,0x31,0xff,0xff,0x14,0x40,0xff,0xfc,
-0x25,0xad,0x00,0x01,0x03,0x20,0x10,0x21,0x18,0x40,0x00,0x08,0x27,0x39,0xff,0xff,
-0x03,0xb9,0x10,0x21,0x90,0x43,0x00,0x00,0x03,0x20,0x20,0x21,0x27,0x39,0xff,0xff,
-0xa1,0xa3,0x00,0x00,0x1c,0x80,0xff,0xfa,0x25,0xad,0x00,0x01,0x03,0x00,0x10,0x21,
-0x18,0x40,0x00,0x07,0x27,0x18,0xff,0xff,0x24,0x03,0x00,0x20,0x03,0x00,0x10,0x21,
-0xa1,0xa3,0x00,0x00,0x27,0x18,0xff,0xff,0x1c,0x40,0xff,0xfc,0x25,0xad,0x00,0x01,
-0x01,0xa0,0x18,0x21,0x7b,0xb6,0x03,0x3c,0x7b,0xb4,0x02,0xfc,0x7b,0xb2,0x02,0xbc,
-0x7b,0xb0,0x02,0x7c,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x68,
-0xa1,0xa2,0x00,0x00,0x92,0x83,0x00,0x21,0x25,0xad,0x00,0x01,0xa1,0xa3,0x00,0x00,
-0x08,0x00,0x2b,0x61,0x25,0xad,0x00,0x01,0x24,0x02,0x00,0x30,0x08,0x00,0x2b,0x94,
-0xa1,0xa2,0x00,0x00,0x01,0xcf,0x10,0x25,0x10,0x40,0xff,0xad,0x00,0x00,0x60,0x21,
-0x00,0x0e,0x18,0x02,0x03,0x3d,0x98,0x21,0x00,0x60,0x20,0x21,0x01,0xe0,0x38,0x21,
-0x10,0x60,0x00,0x04,0x27,0x39,0x00,0x01,0x00,0x70,0x00,0x1b,0x00,0x00,0x20,0x12,
-0x00,0x00,0x18,0x10,0x00,0x80,0x48,0x21,0x00,0xe0,0x30,0x21,0x01,0x80,0x70,0x21,
-0x01,0x80,0x28,0x21,0x10,0x00,0x00,0x06,0x24,0x04,0x00,0x21,0x00,0x03,0x08,0x40,
-0x00,0x03,0x2f,0xc2,0x00,0x22,0x18,0x25,0x00,0x06,0x30,0x40,0x00,0x0e,0x70,0x40,
-0x14,0xa0,0x00,0x02,0x00,0x70,0x10,0x2b,0x14,0x40,0x00,0x03,0x24,0x84,0xff,0xff,
-0x00,0x70,0x18,0x23,0x25,0xce,0x00,0x01,0x14,0x80,0xff,0xf4,0x00,0x06,0x17,0xc2,
-0x02,0x83,0x18,0x21,0x01,0xc0,0x38,0x21,0x00,0x00,0x50,0x21,0x00,0x09,0x20,0x00,
-0x00,0x00,0x28,0x21,0x90,0x66,0x00,0x00,0x00,0x8a,0x70,0x25,0x00,0xa7,0x78,0x25,
-0x01,0xcf,0x10,0x25,0x14,0x40,0xff,0xda,0xa2,0x66,0x00,0x00,0x08,0x00,0x2b,0x49,
-0x02,0x39,0x10,0x2a,0x08,0x00,0x2b,0x42,0x27,0x18,0xff,0xfe,0x10,0x40,0xff,0x73,
-0x32,0x56,0x00,0x20,0x08,0x00,0x2b,0x39,0x24,0x17,0x00,0x20,0x00,0x0f,0x78,0x23,
-0x00,0x0e,0x70,0x23,0x00,0x0f,0x10,0x2b,0x01,0xc2,0x70,0x23,0x08,0x00,0x2b,0x39,
-0x24,0x17,0x00,0x2d,0x80,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x06,
-0x00,0x80,0x18,0x21,0x24,0x63,0x00,0x01,0x80,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x64,0x10,0x23,
-0x24,0xa5,0xff,0xff,0x24,0x02,0xff,0xff,0x10,0xa2,0x00,0x0d,0x00,0x80,0x18,0x21,
-0x80,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09,0x00,0x00,0x00,0x00,
-0x24,0x06,0xff,0xff,0x24,0xa5,0xff,0xff,0x10,0xa6,0x00,0x05,0x24,0x63,0x00,0x01,
-0x80,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x64,0x10,0x23,0x80,0x82,0x00,0x00,0x90,0x88,0x00,0x00,
-0x10,0x40,0x00,0x17,0x00,0x00,0x48,0x21,0x90,0xa3,0x00,0x00,0x00,0xa0,0x30,0x21,
-0x10,0x60,0x00,0x0b,0x00,0x60,0x38,0x21,0x00,0x08,0x16,0x00,0x00,0x02,0x46,0x03,
-0x00,0x07,0x16,0x00,0x00,0x02,0x16,0x03,0x11,0x02,0x00,0x05,0x24,0xc6,0x00,0x01,
-0x90,0xc3,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0xf9,0x00,0x60,0x38,0x21,
-0x00,0x03,0x16,0x00,0x10,0x40,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x84,0x00,0x01,
-0x90,0x82,0x00,0x00,0x25,0x29,0x00,0x01,0x14,0x40,0xff,0xeb,0x00,0x40,0x40,0x21,
-0x03,0xe0,0x00,0x08,0x01,0x20,0x10,0x21,0x80,0x82,0x00,0x00,0x90,0x87,0x00,0x00,
-0x10,0x40,0x00,0x17,0x00,0x00,0x18,0x21,0x90,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x1e,0x00,0x10,0x60,0x00,0x0c,0x00,0xa0,0x30,0x21,0x00,0x07,0x16,0x00,
-0x00,0x02,0x3e,0x03,0x00,0x03,0x16,0x03,0x10,0xe2,0x00,0x0d,0x00,0x80,0x18,0x21,
-0x24,0xc6,0x00,0x01,0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00,
-0x14,0x60,0xff,0xf9,0x00,0x03,0x16,0x03,0x24,0x84,0x00,0x01,0x90,0x82,0x00,0x00,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xec,0x00,0x40,0x38,0x21,0x00,0x00,0x18,0x21,
-0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xe0,0xaf,0xb0,0x00,0x10,
-0x8f,0x90,0xc2,0x58,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0x00,0x84,0x80,0x0b,
-0x00,0x00,0x30,0x21,0x12,0x00,0x00,0x0a,0x00,0xa0,0x88,0x21,0x0c,0x00,0x2b,0xee,
-0x02,0x00,0x20,0x21,0x02,0x02,0x80,0x21,0x82,0x02,0x00,0x00,0x02,0x20,0x28,0x21,
-0x02,0x00,0x20,0x21,0x14,0x40,0x00,0x07,0x00,0x00,0x30,0x21,0xaf,0x80,0xc2,0x58,
-0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x0c,0x00,0x2c,0x0a,0x00,0x00,0x00,0x00,0x00,0x40,0x18,0x21,
-0x10,0x40,0x00,0x07,0x02,0x00,0x30,0x21,0x80,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0xa0,0x60,0x00,0x00,0x24,0x63,0x00,0x01,
-0xaf,0x83,0xc2,0x58,0x08,0x00,0x2c,0x38,0x00,0x00,0x00,0x00,0x24,0xc6,0xff,0xff,
-0x24,0x02,0xff,0xff,0x10,0xc2,0x00,0x05,0x00,0x80,0x18,0x21,0x24,0xc6,0xff,0xff,
-0xa0,0x65,0x00,0x00,0x14,0xc2,0xff,0xfd,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,
-0x00,0x80,0x10,0x21,0x24,0xc6,0xff,0xff,0x24,0x02,0xff,0xff,0x10,0xc2,0x00,0x08,
-0x00,0x80,0x18,0x21,0x24,0x07,0xff,0xff,0x90,0xa2,0x00,0x00,0x24,0xc6,0xff,0xff,
-0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x00,0x14,0xc7,0xff,0xfb,0x24,0x63,0x00,0x01,
-0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x00,0x80,0x18,0x21,0x90,0xa2,0x00,0x00,
-0x24,0xa5,0x00,0x01,0xa0,0x82,0x00,0x00,0x14,0x40,0xff,0xfc,0x24,0x84,0x00,0x01,
-0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x90,0x83,0x00,0x00,0x90,0xa2,0x00,0x00,
-0x24,0x84,0x00,0x01,0x00,0x62,0x10,0x23,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,
-0x14,0x40,0x00,0x03,0x24,0xa5,0x00,0x01,0x14,0x60,0xff,0xf7,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,
-0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0xa5,0x00,0x20,0x24,0x42,0xb1,0xe0,
-0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20,0xac,0x82,0x00,0x64,
-0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,
-0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c,0xac,0x80,0x00,0x50,0xac,0x80,0x00,0x54,
-0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58,0xa0,0x80,0x00,0x5c,0x24,0x42,0xb2,0xb0,
-0x24,0x83,0x00,0x68,0x24,0x05,0x00,0x0f,0x24,0xa5,0xff,0xff,0xac,0x62,0x00,0x00,
-0x04,0xa1,0xff,0xfd,0x24,0x63,0x00,0x04,0x3c,0x02,0x80,0x01,0x3c,0x03,0x80,0x01,
-0x24,0x42,0xb3,0xe0,0x24,0x63,0xb4,0x44,0xac,0x82,0x00,0x78,0xac,0x83,0x00,0x84,
-0x3c,0x02,0x80,0x01,0x3c,0x03,0x80,0x01,0x24,0x42,0xb5,0x6c,0x24,0x63,0xb4,0xd8,
-0xac,0x82,0x00,0x88,0xac,0x83,0x00,0x98,0x3c,0x02,0x80,0x01,0x3c,0x03,0x80,0x01,
-0x24,0x42,0xb6,0x14,0x24,0x63,0xb6,0xd4,0xac,0x82,0x00,0xa0,0xac,0x83,0x00,0xa4,
-0xa0,0x80,0x01,0xba,0xac,0x80,0x01,0xa8,0xac,0x80,0x01,0xac,0xac,0x80,0x01,0xb0,
-0xac,0x80,0x01,0xb4,0xa0,0x80,0x01,0xb8,0x03,0xe0,0x00,0x08,0xa0,0x80,0x01,0xb9,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0xb2,0xb0,
-0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,
-0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0xb2,0xc8,0xaf,0xb0,0x00,0x10,
-0xac,0x62,0x00,0x00,0xaf,0xbf,0x00,0x14,0x8c,0x83,0x00,0x10,0x8f,0x82,0x91,0xe8,
-0x00,0x80,0x80,0x21,0x3c,0x04,0x80,0x01,0x30,0x46,0x00,0x01,0x10,0x60,0x00,0x11,
-0x24,0x84,0x08,0xdc,0x8e,0x02,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,
-0x00,0x00,0x00,0x00,0x8e,0x05,0x00,0x10,0x8e,0x03,0x00,0x14,0x8e,0x02,0x00,0x04,
-0x00,0xa3,0x28,0x21,0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,
-0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00,0x30,0x42,0x3f,0xff,
-0xae,0x02,0x00,0x04,0x14,0xc0,0x00,0x0a,0x00,0x00,0x00,0x00,0xae,0x00,0x00,0x00,
-0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,
-0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x8e,0x05,0x00,0x10,0x8e,0x07,0x00,0x04,0x8e,0x06,0x00,0x14,0x0c,0x00,0x17,0x9d,
-0x00,0x00,0x00,0x00,0x08,0x00,0x2c,0xd4,0xae,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0xb3,0x8c,0xac,0x62,0x00,0x00,
-0x8c,0x86,0x00,0x04,0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xc2,0x10,0x21,
-0x8c,0x45,0x00,0x00,0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02,0x30,0xa3,0x3f,0xff,
-0x30,0x42,0x00,0xff,0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14,0x8c,0x83,0x00,0x14,
-0xac,0x85,0x00,0x40,0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08,0xac,0x86,0x00,0x08,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,
-0x24,0x63,0xb3,0xe0,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,
-0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x00,0x80,0x80,0x21,
-0xae,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,
-0xae,0x00,0x00,0x0c,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x2c,0xe3,0x00,0x00,0x00,0x00,0x08,0x00,0x2d,0x05,
-0xae,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x34,0x42,0x00,0x20,0x24,0x63,0xb4,0x44,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,
-0x00,0x80,0x80,0x21,0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01,0x8e,0x04,0x00,0x44,
-0x00,0x62,0x18,0x21,0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01,0xae,0x02,0x00,0x50,
-0x30,0xa3,0x00,0xff,0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02,0x30,0x84,0x00,0x0f,
-0x30,0x42,0x00,0x03,0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34,0xae,0x02,0x00,0x2c,
-0xae,0x03,0x00,0x30,0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x2c,0xe3,0x00,0x00,0x00,0x00,
-0x08,0x00,0x2d,0x1d,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
-0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xb4,0xd8,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44,0x8e,0x02,0x00,0x40,
-0x83,0x85,0x92,0x15,0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01,0x00,0x02,0x16,0x02,
-0xae,0x04,0x00,0x14,0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18,0x10,0xa0,0x00,0x04,
-0xae,0x03,0x00,0x3c,0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x06,0x00,0x01,
-0x24,0x02,0x00,0x01,0xa3,0x86,0x92,0x15,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,
-0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x2d,0x11,
-0x00,0x00,0x00,0x00,0x08,0x00,0x2d,0x42,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xb5,0x6c,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21,0x3c,0x02,0xb0,0x03,
-0x8c,0x42,0x00,0x00,0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40,0x83,0x86,0x92,0x15,
-0x92,0x05,0x00,0x41,0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01,0x00,0x02,0x12,0xc2,
-0x00,0x03,0x1e,0x02,0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14,0x00,0x00,0x38,0x21,
-0xae,0x03,0x00,0x18,0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c,0x10,0x80,0x00,0x03,
-0x24,0x02,0x00,0x01,0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x87,0x92,0x15,
-0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x2d,0x11,0x00,0x00,0x00,0x00,0x08,0x00,0x2d,0x67,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x34,0x42,0x00,0x20,0x24,0x63,0xb6,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x21,
-0x00,0x80,0x80,0x21,0x8e,0x05,0x00,0x04,0x8e,0x04,0x00,0x44,0x3c,0x03,0x80,0x00,
-0x34,0x63,0x00,0x10,0x3c,0x02,0xb0,0x01,0x00,0xa2,0x28,0x21,0x00,0x83,0x20,0x25,
-0xac,0xa4,0x00,0x04,0x8e,0x03,0x01,0xac,0x8e,0x08,0x00,0x04,0x3c,0x07,0xb0,0x03,
-0x24,0x66,0x00,0x01,0x28,0xc5,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xc5,0x10,0x0a,
-0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xc2,0x30,0x23,
-0x00,0x70,0x18,0x21,0xae,0x06,0x01,0xac,0x34,0xe7,0x00,0x30,0xac,0x68,0x00,0xa8,
-0x8c,0xe2,0x00,0x00,0x02,0x00,0x20,0x21,0x24,0x42,0x00,0x01,0x0c,0x00,0x2c,0xb2,
-0xac,0xe2,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x2d,0x5b,0x00,0x00,0x00,0x00,0x08,0x00,0x2d,0x91,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x34,0x42,0x00,0x20,0x24,0x63,0xb6,0xd4,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x21,
-0x00,0x80,0x80,0x21,0x8e,0x05,0x00,0x04,0x8e,0x04,0x00,0x44,0x3c,0x03,0x80,0x00,
-0x34,0x63,0x00,0x10,0x3c,0x02,0xb0,0x01,0x00,0xa2,0x28,0x21,0x00,0x83,0x20,0x25,
-0xac,0xa4,0x00,0x04,0x8e,0x03,0x01,0xac,0x8e,0x08,0x00,0x04,0x3c,0x07,0xb0,0x03,
-0x24,0x66,0x00,0x01,0x28,0xc5,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xc5,0x10,0x0a,
-0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xc2,0x30,0x23,
-0x00,0x70,0x18,0x21,0xae,0x06,0x01,0xac,0x34,0xe7,0x00,0x30,0xac,0x68,0x00,0xa8,
-0x8c,0xe2,0x00,0x00,0x02,0x00,0x20,0x21,0x24,0x42,0x00,0x01,0x0c,0x00,0x2c,0xb2,
-0xac,0xe2,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x2d,0x5b,0x00,0x00,0x00,0x00,0x08,0x00,0x2d,0xc1,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,
-0x24,0x63,0xb7,0x94,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0x3c,0x02,0x80,0x01,
-0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0x00,0x80,0x80,0x21,
-0x24,0x51,0xb2,0xb0,0x3c,0x03,0xb0,0x09,0x34,0x63,0x00,0x06,0x8e,0x07,0x00,0x04,
-0x90,0x62,0x00,0x00,0x00,0x07,0x22,0x02,0x00,0x44,0x10,0x23,0x24,0x44,0x00,0x40,
-0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,
-0x00,0x02,0x11,0x80,0x24,0x84,0xff,0xff,0x10,0x44,0x00,0x5f,0x00,0x00,0x40,0x21,
-0x3c,0x02,0xb0,0x01,0x00,0xe2,0x10,0x21,0x8c,0x44,0x00,0x04,0x3c,0x03,0x7c,0x00,
-0x34,0x63,0x00,0xf0,0x00,0x83,0x18,0x24,0xae,0x04,0x00,0x44,0x8c,0x44,0x00,0x00,
-0x10,0x60,0x00,0x60,0x00,0x00,0x48,0x21,0x24,0xe2,0x01,0x00,0x30,0x45,0x3f,0xff,
-0x3c,0x03,0xb0,0x01,0xae,0x05,0x00,0x04,0x00,0xa3,0x18,0x21,0x8c,0x64,0x00,0x04,
-0x3c,0x02,0x7c,0x00,0x34,0x42,0x00,0xf0,0x00,0x82,0x30,0x24,0xae,0x04,0x00,0x44,
-0x25,0x08,0x00,0x01,0x24,0x02,0x00,0x40,0x00,0xa0,0x38,0x21,0x8c,0x64,0x00,0x00,
-0x11,0x02,0x00,0x30,0x24,0x09,0x00,0x01,0x3c,0x02,0xff,0xff,0x14,0xc0,0xff,0xee,
-0x00,0x82,0x18,0x24,0x3c,0x02,0x28,0x38,0x14,0x62,0xff,0xec,0x24,0xe2,0x01,0x00,
-0x24,0x02,0x00,0x01,0x11,0x22,0x00,0x2e,0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,
-0x8e,0x04,0x00,0x60,0x00,0x02,0x1e,0x42,0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,
-0x30,0x63,0x00,0x01,0xae,0x02,0x00,0x00,0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,
-0x8e,0x02,0x00,0x64,0x8e,0x04,0x00,0x58,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,
-0x00,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,
-0xae,0x00,0x00,0x0c,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,
-0x00,0x50,0x10,0x21,0x8c,0x42,0x00,0x68,0x00,0x00,0x00,0x00,0x10,0x51,0x00,0x06,
-0x00,0x00,0x00,0x00,0x00,0x40,0xf8,0x09,0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,
-0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x60,0x08,0x00,0x2d,0xf1,
-0xae,0x04,0x00,0x64,0x8e,0x02,0x00,0x64,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,
-0x00,0x00,0x00,0x00,0x7a,0x02,0x0d,0x7c,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,
-0x00,0x43,0x10,0x26,0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x34,0x63,0x00,0x06,0x8e,0x04,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x04,0x22,0x02,
-0x00,0x44,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,
-0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,
-0x14,0x89,0xff,0xc6,0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
-0x2c,0x62,0x00,0x03,0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d,0x10,0x62,0x00,0x03,
-0x24,0x02,0x00,0x01,0x08,0x00,0x2e,0x49,0xa2,0x02,0x00,0x5c,0x08,0x00,0x2e,0x49,
-0xa2,0x00,0x00,0x5c,0x3c,0x02,0xff,0xff,0x00,0x82,0x10,0x24,0x3c,0x03,0x28,0x38,
-0x14,0x43,0xff,0x9d,0x24,0x02,0x00,0x01,0x08,0x00,0x2e,0x21,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0xb9,0xc0,
-0xac,0x62,0x00,0x00,0x8c,0x83,0x01,0xa8,0x3c,0x05,0xb0,0x06,0x34,0xa5,0x80,0x18,
-0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0xa8,0x3c,0x03,0x00,0x80,
-0x00,0x02,0x10,0xc2,0x00,0x02,0x12,0x00,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x00,
-0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac,0x24,0x66,0x00,0x01,0x28,0xc5,0x00,0x00,
-0x24,0x63,0x00,0x40,0x00,0xc5,0x18,0x0a,0x00,0x03,0x19,0x83,0x00,0x03,0x19,0x80,
-0x00,0xc3,0x30,0x23,0x00,0xc2,0x10,0x26,0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,
-0xac,0x86,0x01,0xa8,0x90,0x87,0x00,0x00,0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x24,0x48,0x02,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x01,0x07,0x18,0x21,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x20,0x10,0x40,0x00,0x0a,
-0x00,0x00,0x80,0x21,0x24,0x84,0x00,0x01,0x90,0x87,0x00,0x00,0x00,0x00,0x00,0x00,
-0x01,0x07,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x20,
-0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x07,0x16,0x00,0x00,0x02,0x16,0x03,
-0x24,0x03,0x00,0x2d,0x10,0x43,0x00,0x0f,0x00,0x00,0x00,0x00,0x0c,0x00,0x2e,0xb8,
-0x00,0x00,0x00,0x00,0x00,0x40,0x18,0x21,0x00,0x02,0x10,0x23,0x04,0x61,0x00,0x05,
-0x00,0x70,0x10,0x0a,0x16,0x00,0x00,0x03,0x3c,0x02,0x80,0x00,0x3c,0x02,0x7f,0xff,
-0x34,0x42,0xff,0xff,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x24,0x10,0xff,0xff,0x08,0x00,0x2e,0xa7,0x24,0x84,0x00,0x01,
-0x00,0x80,0x38,0x21,0x90,0x84,0x00,0x00,0x3c,0x02,0x80,0x01,0x24,0x48,0x02,0x14,
-0x01,0x04,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x20,
-0x10,0x40,0x00,0x0a,0x00,0x00,0x50,0x21,0x24,0xe7,0x00,0x01,0x90,0xe4,0x00,0x00,
-0x00,0x00,0x00,0x00,0x01,0x04,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x20,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x04,0x16,0x00,
-0x00,0x02,0x16,0x03,0x38,0x42,0x00,0x2b,0x24,0xe3,0x00,0x01,0x24,0x04,0x00,0x10,
-0x10,0xc4,0x00,0x38,0x00,0x62,0x38,0x0a,0x90,0xe4,0x00,0x00,0x14,0xc0,0x00,0x07,
-0x00,0x80,0x18,0x21,0x00,0x04,0x16,0x00,0x00,0x02,0x16,0x03,0x24,0x03,0x00,0x30,
-0x10,0x43,0x00,0x25,0x24,0x06,0x00,0x0a,0x00,0x80,0x18,0x21,0x00,0x03,0x16,0x00,
-0x10,0x40,0x00,0x1a,0x30,0x64,0x00,0xff,0x24,0x82,0xff,0xa9,0x2c,0x83,0x00,0x61,
-0x30,0x48,0x00,0xff,0x10,0x60,0x00,0x09,0x2c,0x89,0x00,0x41,0x24,0x82,0xff,0xc9,
-0x30,0x48,0x00,0xff,0x11,0x20,0x00,0x05,0x2c,0x83,0x00,0x3a,0x24,0x82,0xff,0xd0,
-0x14,0x60,0x00,0x02,0x30,0x48,0x00,0xff,0x24,0x08,0x00,0xff,0x01,0x06,0x10,0x2a,
-0x10,0x40,0x00,0x0a,0x01,0x46,0x00,0x18,0x24,0xe7,0x00,0x01,0x00,0x00,0x18,0x12,
-0x00,0x6a,0x10,0x2b,0x14,0x40,0x00,0x0a,0x00,0x68,0x50,0x21,0x80,0xe2,0x00,0x00,
-0x90,0xe3,0x00,0x00,0x14,0x40,0xff,0xe8,0x30,0x64,0x00,0xff,0x10,0xa0,0x00,0x02,
-0x00,0x00,0x00,0x00,0xac,0xa7,0x00,0x00,0x03,0xe0,0x00,0x08,0x01,0x40,0x10,0x21,
-0x03,0xe0,0x00,0x08,0x24,0x02,0xff,0xff,0x24,0x06,0x00,0x08,0x80,0xe3,0x00,0x01,
-0x24,0x02,0x00,0x78,0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x58,0x14,0x62,0xff,0xd7,
-0x00,0x80,0x18,0x21,0x24,0xe7,0x00,0x02,0x90,0xe4,0x00,0x00,0x08,0x00,0x2e,0xda,
-0x24,0x06,0x00,0x10,0x80,0xe3,0x00,0x00,0x24,0x02,0x00,0x30,0x90,0xe4,0x00,0x00,
-0x10,0x62,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x2e,0xd3,0x00,0x00,0x00,0x00,
-0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01,0x34,0xc6,0x00,0x18,
-0x34,0x84,0x00,0x20,0x24,0x42,0xbc,0x40,0x24,0x03,0xff,0x83,0xac,0x82,0x00,0x00,
-0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8,0x3c,0x03,0xb0,0x07,
-0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00,0x90,0x64,0x00,0x00,
-0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01,0xa0,0x40,0x00,0x00,
-0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07,0xa3,0xa3,0x00,0x00,
-0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10,0x24,0x02,0x00,0x06,
-0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38,0xa0,0xa2,0x00,0x00,
-0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20,0xa3,0xa4,0x00,0x00,
-0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xc2,0x5c,0xa3,0xa3,0x00,0x00,
-0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08,
-};
-
-#define DataArrayLengthDTM 2860
-u8 Rtl8192PciEFwDataArrayDTM[DataArrayLengthDTM] = {
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x0d,0x5b,0x43,
-0x4d,0x50,0x4b,0x5d,0x00,0x00,0x00,0x00,0x80,0x01,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x28,0x28,0x28,
-0x28,0x28,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-0x08,0x08,0x08,0x08,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x10,0x10,
-0x10,0x10,0x10,0x10,0x10,0x41,0x41,0x41,0x41,0x41,0x41,0x01,0x01,0x01,0x01,0x01,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,
-0x10,0x10,0x10,0x10,0x10,0x42,0x42,0x42,0x42,0x42,0x42,0x02,0x02,0x02,0x02,0x02,
-0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,
-0x10,0x10,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0xa0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-0x10,0x10,0x10,0x10,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
-0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x10,0x01,0x01,0x01,0x01,
-0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
-0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x10,0x02,0x02,0x02,0x02,
-0x02,0x02,0x02,0x02,0x20,0x09,0x0d,0x0a,0x00,0x00,0x00,0x00,0x80,0x01,0x03,0x14,
-0x00,0x00,0x00,0x00,0x43,0x6e,0x73,0x64,0x31,0x00,0x00,0x00,0x68,0x65,0x6c,0x70,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x34,0x00,0x00,0x77,0x34,0x00,0x00,
-0x64,0x62,0x67,0x00,0x72,0x61,0x63,0x74,0x72,0x6c,0x00,0x00,0x73,0x79,0x73,0x64,
-0x00,0x00,0x00,0x00,0x73,0x79,0x73,0x63,0x74,0x72,0x6c,0x00,0x74,0x78,0x74,0x62,
-0x6c,0x00,0x00,0x00,0x70,0x72,0x61,0x6e,0x67,0x65,0x00,0x00,0x64,0x6d,0x00,0x00,
-0x75,0x6e,0x6b,0x6e,0x6f,0x77,0x00,0x00,0x80,0x01,0x03,0x2c,0x80,0x01,0x03,0x34,
-0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x20,0x5c,
-0x80,0x01,0x03,0x38,0x80,0x01,0x03,0x34,0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,
-0x00,0x00,0x00,0x00,0x80,0x00,0x21,0xbc,0x80,0x01,0x03,0x3c,0x80,0x01,0x03,0x34,
-0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x23,0x38,
-0x80,0x01,0x03,0x40,0x80,0x01,0x03,0x34,0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,
-0x00,0x00,0x00,0x00,0x80,0x00,0x25,0x04,0x80,0x01,0x03,0x44,0x80,0x01,0x03,0x34,
-0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x25,0xdc,
-0x80,0x01,0x03,0x4c,0x80,0x01,0x03,0x34,0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,
-0x00,0x00,0x00,0x00,0x80,0x00,0x25,0xe4,0x80,0x01,0x03,0x54,0x80,0x01,0x03,0x34,
-0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x26,0x88,
-0x80,0x01,0x03,0x5c,0x80,0x01,0x03,0x34,0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,
-0x00,0x00,0x00,0x00,0x80,0x00,0x26,0x90,0x80,0x01,0x03,0x64,0x80,0x01,0x03,0x34,
-0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x28,0x1c,
-0x80,0x01,0x03,0x6c,0x80,0x01,0x03,0x34,0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x01,
-0x00,0x00,0x00,0x00,0x80,0x00,0x28,0x90,0x80,0x01,0x03,0x70,0x80,0x01,0x03,0x34,
-0x80,0x01,0x03,0x34,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x01,0x80,0x00,0x29,0x1c,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x0d,0x52,0x54,0x4c,0x38,0x31,0x39,
-0x58,0x2d,0x25,0x64,0x3e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x54,0x4c,0x38,
-0x31,0x39,0x58,0x2d,0x25,0x64,0x3e,0x0a,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x2a,0x00,0x00,0x00,0x0a,0x0d,0x45,0x72,0x72,0x20,0x44,0x49,0x52,0x00,0x00,0x00,
-0x0a,0x0d,0x44,0x42,0x47,0x20,0x43,0x4d,0x44,0x73,0x3a,0x00,0x0a,0x0d,0x5b,0x00,
-0x5d,0x2d,0x00,0x00,0x0a,0x0d,0x3c,0x31,0x2e,0x43,0x4d,0x4e,0x3e,0x20,0x3c,0x32,
-0x2e,0x3f,0x3e,0x00,0x0a,0x0d,0x20,0x79,0x65,0x61,0x72,0x2d,0x64,0x61,0x79,0x2d,
-0x68,0x6f,0x75,0x72,0x2d,0x6d,0x69,0x6e,0x2d,0x73,0x65,0x63,0x2d,0x31,0x30,0x6d,
-0x73,0x3d,0x00,0x00,0x25,0x64,0x2d,0x00,0x0a,0x0d,0x09,0x20,0x20,0x20,0x20,0x20,
-0x30,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x34,0x20,0x20,0x20,0x20,0x20,
-0x20,0x20,0x30,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x43,0x00,0x00,0x00,
-0x0a,0x0d,0x09,0x20,0x20,0x20,0x20,0x20,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,
-0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,
-0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x3d,0x00,0x0d,0x0a,0x20,0x30,
-0x78,0x25,0x30,0x38,0x58,0x20,0x20,0x00,0x09,0x00,0x00,0x00,0x25,0x30,0x38,0x58,
-0x20,0x00,0x00,0x00,0x0a,0x0d,0x44,0x62,0x67,0x5f,0x46,0x6c,0x61,0x67,0x25,0x64,
-0x3d,0x30,0x78,0x25,0x30,0x38,0x78,0x00,0x0a,0x0d,0x20,0x76,0x6f,0x71,0x74,0x78,
-0x72,0x65,0x71,0x20,0x3d,0x20,0x25,0x64,0x00,0x00,0x00,0x00,0x0a,0x0d,0x20,0x76,
-0x69,0x71,0x74,0x78,0x72,0x65,0x71,0x20,0x3d,0x20,0x25,0x64,0x00,0x00,0x00,0x00,
-0x0a,0x0d,0x20,0x62,0x65,0x71,0x74,0x78,0x72,0x65,0x71,0x20,0x3d,0x20,0x25,0x64,
-0x00,0x00,0x00,0x00,0x0a,0x0d,0x20,0x62,0x6b,0x71,0x74,0x78,0x72,0x65,0x71,0x20,
-0x3d,0x20,0x25,0x64,0x00,0x00,0x00,0x00,0x0a,0x0d,0x20,0x62,0x63,0x6e,0x71,0x74,
-0x78,0x72,0x65,0x71,0x20,0x3d,0x20,0x25,0x64,0x00,0x00,0x00,0x0a,0x0d,0x20,0x68,
-0x71,0x74,0x78,0x72,0x65,0x71,0x20,0x3d,0x20,0x25,0x64,0x00,0x0a,0x0d,0x20,0x6d,
-0x67,0x71,0x74,0x78,0x72,0x65,0x71,0x20,0x3d,0x20,0x25,0x64,0x00,0x00,0x00,0x00,
-0x0a,0x0d,0x54,0x58,0x4c,0x4c,0x54,0x09,0x09,0x4e,0x45,0x58,0x54,0x20,0x20,0x20,
-0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x4e,0x45,0x58,0x54,0x0a,0x0d,0x00,
-0x0a,0x0d,0x20,0x50,0x61,0x67,0x65,0x25,0x33,0x64,0x09,0x00,0x25,0x34,0x64,0x20,
-0x20,0x20,0x20,0x00,0x25,0x34,0x64,0x20,0x20,0x20,0x20,0x09,0x00,0x00,0x00,0x00,
-0x0a,0x0d,0x54,0x58,0x4f,0x51,0x54,0x09,0x09,0x48,0x65,0x61,0x64,0x20,0x20,0x20,
-0x20,0x54,0x61,0x69,0x6c,0x20,0x20,0x20,0x20,0x48,0x65,0x61,0x64,0x20,0x20,0x20,
-0x20,0x54,0x61,0x69,0x6c,0x0a,0x0d,0x00,0x0a,0x0d,0x55,0x6e,0x6b,0x6e,0x6f,0x77,
-0x20,0x63,0x6f,0x6d,0x6d,0x61,0x6e,0x64,0x00,0x00,0x00,0x00,0x0a,0x0d,0x45,0x72,
-0x72,0x20,0x41,0x72,0x67,0x0a,0x0d,0x55,0x53,0x41,0x47,0x45,0x3a,0x00,0x00,0x00,
-0x10,0x00,0x08,0x00,0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4,
-0x00,0xab,0x00,0x72,0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,
-0x02,0x76,0x01,0x3b,0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f,
-0x01,0x3b,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20,
-0x01,0x2f,0x00,0x98,0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e,
-0x00,0x98,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f,
-0x02,0x39,0x01,0x1c,0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39,
-0x01,0x1c,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c,
-0x01,0x11,0x00,0x89,0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b,
-0x00,0x89,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e,
-0x02,0xab,0x02,0xab,0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08,
-0x04,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x54,0x4c,0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c,
-0x5f,0x64,0x61,0x74,0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00,
-0x41,0x64,0x45,0x4c,0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00,
-0x00,0x00,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78,
-0x63,0x43,0x6f,0x64,0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x42,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x4f,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x80,0x01,0x11,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,
-0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x50,
-0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20,
-0x00,0x00,0x01,0x80,0x00,0x00,0x01,0xb0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xd0,
-0x00,0x00,0x01,0x30,0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x70,0x00,0x00,0x03,0x40,
-0x00,0x00,0x03,0xa0,0x00,0x00,0x04,0x10,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0xa0,
-0x00,0x00,0x02,0x70,0x00,0x00,0x03,0x40,0x00,0x00,0x04,0xe0,0x00,0x00,0x06,0x80,
-0x00,0x00,0x07,0x50,0x00,0x00,0x07,0xf8,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,
-0x02,0x02,0x02,0x02,0x01,0x01,0x02,0x02,0x04,0x05,0x06,0x06,0x02,0x02,0x04,0x06,
-0x07,0x09,0x0a,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x4e,0x55,0x4c,0x4c,0x3e,0x00,0x00,0x30,0x31,0x32,0x33,
-0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,
-0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,
-0x00,0x00,0x00,0x00,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,
-0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,
-0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x00,0x00,0x00,0x00,0x5b,0x52,0x58,0x5d,
-0x20,0x70,0x6b,0x74,0x5f,0x6c,0x65,0x6e,0x3d,0x25,0x64,0x20,0x6f,0x66,0x66,0x73,
-0x65,0x74,0x3d,0x25,0x64,0x20,0x73,0x74,0x61,0x72,0x74,0x5f,0x61,0x64,0x64,0x72,
-0x3d,0x25,0x30,0x38,0x78,0x0a,0x0d,0x00,0x80,0x00,0x6a,0x64,0x80,0x00,0x6a,0x88,
-0x80,0x00,0x6a,0xa4,0x80,0x00,0x6b,0x90,0x80,0x00,0x6c,0x48,0x80,0x00,0x6c,0x98,
-0x80,0x00,0x6d,0x04,0x80,0x00,0x6e,0x08,0x80,0x00,0x6e,0x3c,0x80,0x00,0x6e,0x50,
-0x80,0x00,0x6e,0x64,0x80,0x00,0x6f,0x3c,0x80,0x00,0x6f,0x78,0x80,0x00,0x70,0x28,
-0x80,0x00,0x70,0x50,0x80,0x00,0x6a,0x20,0x80,0x00,0x70,0x64,0x80,0x00,0x76,0x5c,
-0x80,0x00,0x76,0xd4,0x80,0x00,0x76,0xe0,0x80,0x00,0x76,0xec,0x80,0x00,0x76,0x74,
-0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,
-0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,
-0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,0x80,0x00,0x76,0x74,0x80,0x00,0x76,0xf8,
-0x80,0x00,0x77,0x04,0x80,0x00,0x77,0x10,0x80,0x00,0xa7,0x80,0x80,0x00,0xa7,0x98,
-0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x88,0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x98,
-0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x98,
-0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x90,0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x78,
-0x80,0x00,0xa7,0x98,0x80,0x00,0xa7,0x98,0x80,0x00,0xab,0xc0,0x80,0x00,0xa8,0xb0,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xa8,0xbc,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xa8,0x44,0x80,0x00,0xa9,0x90,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xa9,0x90,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xa9,0x98,0x80,0x00,0xa9,0xb8,0x80,0x00,0xa9,0xc0,0x80,0x00,0xaa,0xc8,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0x18,0x80,0x00,0xaa,0xc8,0x80,0x00,0xa8,0xc4,
-0x80,0x00,0xaa,0xc8,0x80,0x00,0xaa,0xc8,0x80,0x00,0xa8,0xc0,};
-
-#define PHY_REGArrayLengthDTM 1
-u32 Rtl8192PciEPHY_REGArrayDTM[PHY_REGArrayLengthDTM] = {
-0x0, };
-
-#define PHY_REG_1T2RArrayLengthDTM 296
-u32 Rtl8192PciEPHY_REG_1T2RArrayDTM[PHY_REG_1T2RArrayLengthDTM] = {
-0x800,0x00000000,
-0x804,0x00000001,
-0x808,0x0000fc00,
-0x80c,0x0000001c,
-0x810,0x801010aa,
-0x814,0x008514d0,
-0x818,0x00000040,
-0x81c,0x00000000,
-0x820,0x00000004,
-0x824,0x00690000,
-0x828,0x00000004,
-0x82c,0x00e90000,
-0x830,0x00000004,
-0x834,0x00690000,
-0x838,0x00000004,
-0x83c,0x00e90000,
-0x840,0x00000000,
-0x844,0x00000000,
-0x848,0x00000000,
-0x84c,0x00000000,
-0x850,0x00000000,
-0x854,0x00000000,
-0x858,0x65a965a9,
-0x85c,0x65a965a9,
-0x860,0x001f0010,
-0x864,0x007f0010,
-0x868,0x001f0010,
-0x86c,0x007f0010,
-0x870,0x0f100f70,
-0x874,0x0f100f70,
-0x878,0x00000000,
-0x87c,0x00000000,
-0x880,0x6870e36c,
-0x884,0xe3573600,
-0x888,0x4260c340,
-0x88c,0x0000ff00,
-0x890,0x00000000,
-0x894,0xfffffffe,
-0x898,0x40302010,
-0x89c,0x00706050,
-0x8b0,0x00000000,
-0x8e0,0x00000000,
-0x8e4,0x00000000,
-0x900,0x00000000,
-0x904,0x00000023,
-0x908,0x00000000,
-0x90c,0x31121311,
-0xa00,0x00d0c7d8,
-0xa04,0x811f0008,
-0xa08,0x80cd8300,
-0xa0c,0x2e62740f,
-0xa10,0x95009b78,
-0xa14,0x11145008,
-0xa18,0x00881117,
-0xa1c,0x89140fa0,
-0xa20,0x1a1b0000,
-0xa24,0x090e1317,
-0xa28,0x00000204,
-0xa2c,0x00000000,
-0xc00,0x00000040,
-0xc04,0x00005411,
-0xc08,0x000000e4,
-0xc0c,0x6c6c6c6c,
-0xc10,0x08800000,
-0xc14,0x40000100,
-0xc18,0x08000000,
-0xc1c,0x40000100,
-0xc20,0x08000000,
-0xc24,0x40000100,
-0xc28,0x08000000,
-0xc2c,0x40000100,
-0xc30,0x6de98a44,
-0xc34,0x469652cd,
-0xc38,0x49475996,
-0xc3c,0x0a9a9764,
-0xc40,0x1f7c423f,
-0xc44,0x000100b7,
-0xc48,0xec020000,
-0xc4c,0x00000300,
-0xc50,0x69543430,
-0xc54,0x433c0094,
-0xc58,0x69543430,
-0xc5c,0x433c0094,
-0xc60,0x69543430,
-0xc64,0x433c0094,
-0xc68,0x69543430,
-0xc6c,0x433c0094,
-0xc70,0x2c7f000d,
-0xc74,0x0186175b,
-0xc78,0x0000001f,
-0xc7c,0x00b91612,
-0xc80,0x40000100,
-0xc84,0x20000000,
-0xc88,0x40000100,
-0xc8c,0x08000000,
-0xc90,0x40000100,
-0xc94,0x00000000,
-0xc98,0x40000100,
-0xc9c,0x00000000,
-0xca0,0x00492492,
-0xca4,0x00000000,
-0xca8,0x00000000,
-0xcac,0x00000000,
-0xcb0,0x00000000,
-0xcb4,0x00000000,
-0xcb8,0x00000000,
-0xcbc,0x00492492,
-0xcc0,0x00000000,
-0xcc4,0x00000000,
-0xcc8,0x00000000,
-0xccc,0x00000000,
-0xcd0,0x00000000,
-0xcd4,0x00000000,
-0xcd8,0x64b22427,
-0xcdc,0x00766932,
-0xce0,0x00222222,
-0xd00,0x00000740,
-0xd04,0x00000401,
-0xd08,0x0000907f,
-0xd0c,0x00000001,
-0xd10,0xa0633333,
-0xd14,0x33333c63,
-0xd18,0x6a8f5b6b,
-0xd1c,0x00000000,
-0xd20,0x00000000,
-0xd24,0x00000000,
-0xd28,0x00000000,
-0xd2c,0xcc979975,
-0xd30,0x00000000,
-0xd34,0x00000000,
-0xd38,0x00000000,
-0xd3c,0x00027293,
-0xd40,0x00000000,
-0xd44,0x00000000,
-0xd48,0x00000000,
-0xd4c,0x00000000,
-0xd50,0x6437140a,
-0xd54,0x024dbd02,
-0xd58,0x00000000,
-0xd5c,0x2d432064,
-0xe00,0x161a1a1a,
-0xe04,0x12121416,
-0xe08,0x00001800,
-0xe0c,0x00000000,
-0xe10,0x161a1a1a,
-0xe14,0x12121416,
-0xe18,0x161a1a1a,
-0xe1c,0x12121416,
-};
-
-#define RadioA_ArrayLengthDTM 246
-u32 Rtl8192PciERadioA_ArrayDTM[RadioA_ArrayLengthDTM] = {
-0x019,0x00000003,
-0x000,0x000000bf,
-0x001,0x00000ee0,
-0x002,0x0000004c,
-0x003,0x000007f1,
-0x004,0x00000975,
-0x005,0x00000c58,
-0x006,0x00000ae6,
-0x007,0x000000ca,
-0x008,0x00000e1c,
-0x009,0x000007f0,
-0x00a,0x000009d0,
-0x00b,0x000001ba,
-0x00c,0x00000240,
-0x00e,0x00000020,
-0x00f,0x00000ff0,
-0x012,0x00000806,
-0x014,0x000005ab,
-0x015,0x00000f80,
-0x016,0x00000020,
-0x017,0x00000597,
-0x018,0x0000050a,
-0x01a,0x00000e00,
-0x01b,0x00000f5e,
-0x01c,0x00000008,
-0x01d,0x00000607,
-0x01e,0x000006cc,
-0x01f,0x00000000,
-0x020,0x00000096,
-0x01f,0x00000001,
-0x020,0x00000076,
-0x01f,0x00000002,
-0x020,0x00000056,
-0x01f,0x00000003,
-0x020,0x00000036,
-0x01f,0x00000004,
-0x020,0x00000016,
-0x01f,0x00000005,
-0x020,0x000001f6,
-0x01f,0x00000006,
-0x020,0x000001d6,
-0x01f,0x00000007,
-0x020,0x000001b6,
-0x01f,0x00000008,
-0x020,0x00000196,
-0x01f,0x00000009,
-0x020,0x00000176,
-0x01f,0x0000000a,
-0x020,0x000000f7,
-0x01f,0x0000000b,
-0x020,0x000000d7,
-0x01f,0x0000000c,
-0x020,0x000000b7,
-0x01f,0x0000000d,
-0x020,0x00000097,
-0x01f,0x0000000e,
-0x020,0x00000077,
-0x01f,0x0000000f,
-0x020,0x00000057,
-0x01f,0x00000010,
-0x020,0x00000037,
-0x01f,0x00000011,
-0x020,0x000000fb,
-0x01f,0x00000012,
-0x020,0x000000db,
-0x01f,0x00000013,
-0x020,0x000000bb,
-0x01f,0x00000014,
-0x020,0x000000ff,
-0x01f,0x00000015,
-0x020,0x000000e3,
-0x01f,0x00000016,
-0x020,0x000000c3,
-0x01f,0x00000017,
-0x020,0x000000a3,
-0x01f,0x00000018,
-0x020,0x00000083,
-0x01f,0x00000019,
-0x020,0x00000063,
-0x01f,0x0000001a,
-0x020,0x00000043,
-0x01f,0x0000001b,
-0x020,0x00000023,
-0x01f,0x0000001c,
-0x020,0x00000003,
-0x01f,0x0000001d,
-0x020,0x000001e3,
-0x01f,0x0000001e,
-0x020,0x000001c3,
-0x01f,0x0000001f,
-0x020,0x000001a3,
-0x01f,0x00000020,
-0x020,0x00000183,
-0x01f,0x00000021,
-0x020,0x00000163,
-0x01f,0x00000022,
-0x020,0x00000143,
-0x01f,0x00000023,
-0x020,0x00000123,
-0x01f,0x00000024,
-0x020,0x00000103,
-0x023,0x00000203,
-0x024,0x00000200,
-0x00b,0x000001ba,
-0x02c,0x000003d7,
-0x02d,0x00000ff0,
-0x000,0x00000037,
-0x004,0x00000160,
-0x007,0x00000080,
-0x002,0x0000088d,
-0x0fe,0x00000000,
-0x0fe,0x00000000,
-0x016,0x00000200,
-0x016,0x00000380,
-0x016,0x00000020,
-0x016,0x000001a0,
-0x000,0x000000bf,
-0x00d,0x0000001f,
-0x00d,0x00000c9f,
-0x002,0x0000004d,
-0x000,0x00000cbf,
-0x004,0x00000975,
-0x007,0x00000700,
-};
-
-#define RadioB_ArrayLengthDTM 78
-u32 Rtl8192PciERadioB_ArrayDTM[RadioB_ArrayLengthDTM] = {
-0x019,0x00000003,
-0x000,0x000000bf,
-0x001,0x000006e0,
-0x002,0x0000004c,
-0x003,0x000007f1,
-0x004,0x00000975,
-0x005,0x00000c58,
-0x006,0x00000ae6,
-0x007,0x000000ca,
-0x008,0x00000e1c,
-0x000,0x000000b7,
-0x00a,0x00000850,
-0x000,0x000000bf,
-0x00b,0x000001ba,
-0x00c,0x00000240,
-0x00e,0x00000020,
-0x015,0x00000f80,
-0x016,0x00000020,
-0x017,0x00000597,
-0x018,0x0000050a,
-0x01a,0x00000e00,
-0x01b,0x00000f5e,
-0x01d,0x00000607,
-0x01e,0x000006cc,
-0x00b,0x000001ba,
-0x023,0x00000203,
-0x024,0x00000200,
-0x000,0x00000037,
-0x004,0x00000160,
-0x016,0x00000200,
-0x016,0x00000380,
-0x016,0x00000020,
-0x016,0x000001a0,
-0x00d,0x00000ccc,
-0x000,0x000000bf,
-0x002,0x0000004d,
-0x000,0x00000cbf,
-0x004,0x00000975,
-0x007,0x00000700,
-};
-
-#define RadioC_ArrayLengthDTM 1
-u32 Rtl8192PciERadioC_ArrayDTM[RadioC_ArrayLengthDTM] = {
-0x0, };
-
-#define RadioD_ArrayLengthDTM 1
-u32 Rtl8192PciERadioD_ArrayDTM[RadioD_ArrayLengthDTM] = {
-0x0, };
-
-u32 Rtl8192PciEMACPHY_ArrayDTM[] = {
-0x03c,0xffff0000,0x00000f0f,
-0x340,0xffffffff,0x161a1a1a,
-0x344,0xffffffff,0x12121416,
-0x348,0x0000ffff,0x00001818,
-0x12c,0xffffffff,0x04000802,
-0x318,0x00000fff,0x00000100,
-};
-
-u32 Rtl8192PciEMACPHY_Array_PGDTM[] = {
-0x03c,0xffff0000,0x00000f0f,
-0xe00,0xffffffff,0x06090909,
-0xe04,0xffffffff,0x00030306,
-0xe08,0x0000ff00,0x00000000,
-0xe10,0xffffffff,0x050b0b0e,
-0xe14,0xffffffff,0x00030305,
-0xe18,0xffffffff,0x050b0b0e,
-0xe1c,0xffffffff,0x00030305,
-0x12c,0xffffffff,0x04000802,
-0x318,0x00000fff,0x00000800,
-};
-
-u32 Rtl8192PciEAGCTAB_ArrayDTM[AGCTAB_ArrayLength] = {
-0xc78,0x7d000001,
-0xc78,0x7d010001,
-0xc78,0x7d020001,
-0xc78,0x7d030001,
-0xc78,0x7d040001,
-0xc78,0x7d050001,
-0xc78,0x7c060001,
-0xc78,0x7b070001,
-0xc78,0x7a080001,
-0xc78,0x79090001,
-0xc78,0x780a0001,
-0xc78,0x770b0001,
-0xc78,0x760c0001,
-0xc78,0x750d0001,
-0xc78,0x740e0001,
-0xc78,0x730f0001,
-0xc78,0x72100001,
-0xc78,0x71110001,
-0xc78,0x70120001,
-0xc78,0x6f130001,
-0xc78,0x6e140001,
-0xc78,0x6d150001,
-0xc78,0x6c160001,
-0xc78,0x6b170001,
-0xc78,0x6a180001,
-0xc78,0x69190001,
-0xc78,0x681a0001,
-0xc78,0x671b0001,
-0xc78,0x661c0001,
-0xc78,0x651d0001,
-0xc78,0x641e0001,
-0xc78,0x491f0001,
-0xc78,0x48200001,
-0xc78,0x47210001,
-0xc78,0x46220001,
-0xc78,0x45230001,
-0xc78,0x44240001,
-0xc78,0x43250001,
-0xc78,0x28260001,
-0xc78,0x27270001,
-0xc78,0x26280001,
-0xc78,0x25290001,
-0xc78,0x242a0001,
-0xc78,0x232b0001,
-0xc78,0x222c0001,
-0xc78,0x212d0001,
-0xc78,0x202e0001,
-0xc78,0x0a2f0001,
-0xc78,0x08300001,
-0xc78,0x06310001,
-0xc78,0x05320001,
-0xc78,0x04330001,
-0xc78,0x03340001,
-0xc78,0x02350001,
-0xc78,0x01360001,
-0xc78,0x00370001,
-0xc78,0x00380001,
-0xc78,0x00390001,
-0xc78,0x003a0001,
-0xc78,0x003b0001,
-0xc78,0x003c0001,
-0xc78,0x003d0001,
-0xc78,0x003e0001,
-0xc78,0x003f0001,
-0xc78,0x7d400001,
-0xc78,0x7d410001,
-0xc78,0x7d420001,
-0xc78,0x7d430001,
-0xc78,0x7d440001,
-0xc78,0x7d450001,
-0xc78,0x7c460001,
-0xc78,0x7b470001,
-0xc78,0x7a480001,
-0xc78,0x79490001,
-0xc78,0x784a0001,
-0xc78,0x774b0001,
-0xc78,0x764c0001,
-0xc78,0x754d0001,
-0xc78,0x744e0001,
-0xc78,0x734f0001,
-0xc78,0x72500001,
-0xc78,0x71510001,
-0xc78,0x70520001,
-0xc78,0x6f530001,
-0xc78,0x6e540001,
-0xc78,0x6d550001,
-0xc78,0x6c560001,
-0xc78,0x6b570001,
-0xc78,0x6a580001,
-0xc78,0x69590001,
-0xc78,0x685a0001,
-0xc78,0x675b0001,
-0xc78,0x665c0001,
-0xc78,0x655d0001,
-0xc78,0x645e0001,
-0xc78,0x495f0001,
-0xc78,0x48600001,
-0xc78,0x47610001,
-0xc78,0x46620001,
-0xc78,0x45630001,
-0xc78,0x44640001,
-0xc78,0x43650001,
-0xc78,0x28660001,
-0xc78,0x27670001,
-0xc78,0x26680001,
-0xc78,0x25690001,
-0xc78,0x246a0001,
-0xc78,0x236b0001,
-0xc78,0x226c0001,
-0xc78,0x216d0001,
-0xc78,0x206e0001,
-0xc78,0x0a6f0001,
-0xc78,0x08700001,
-0xc78,0x06710001,
-0xc78,0x05720001,
-0xc78,0x04730001,
-0xc78,0x03740001,
-0xc78,0x02750001,
-0xc78,0x01760001,
-0xc78,0x00770001,
-0xc78,0x00780001,
-0xc78,0x00790001,
-0xc78,0x007a0001,
-0xc78,0x007b0001,
-0xc78,0x007c0001,
-0xc78,0x007d0001,
-0xc78,0x007e0001,
-0xc78,0x007f0001,
-0xc78,0x2e00001e,
-0xc78,0x2e01001e,
-0xc78,0x2e02001e,
-0xc78,0x2e03001e,
-0xc78,0x2e04001e,
-0xc78,0x2e05001e,
-0xc78,0x3006001e,
-0xc78,0x3407001e,
-0xc78,0x3908001e,
-0xc78,0x3c09001e,
-0xc78,0x3f0a001e,
-0xc78,0x420b001e,
-0xc78,0x440c001e,
-0xc78,0x450d001e,
-0xc78,0x460e001e,
-0xc78,0x460f001e,
-0xc78,0x4710001e,
-0xc78,0x4811001e,
-0xc78,0x4912001e,
-0xc78,0x4a13001e,
-0xc78,0x4b14001e,
-0xc78,0x4b15001e,
-0xc78,0x4c16001e,
-0xc78,0x4d17001e,
-0xc78,0x4e18001e,
-0xc78,0x4f19001e,
-0xc78,0x4f1a001e,
-0xc78,0x501b001e,
-0xc78,0x511c001e,
-0xc78,0x521d001e,
-0xc78,0x521e001e,
-0xc78,0x531f001e,
-0xc78,0x5320001e,
-0xc78,0x5421001e,
-0xc78,0x5522001e,
-0xc78,0x5523001e,
-0xc78,0x5624001e,
-0xc78,0x5725001e,
-0xc78,0x5726001e,
-0xc78,0x5827001e,
-0xc78,0x5828001e,
-0xc78,0x5929001e,
-0xc78,0x592a001e,
-0xc78,0x5a2b001e,
-0xc78,0x5b2c001e,
-0xc78,0x5c2d001e,
-0xc78,0x5c2e001e,
-0xc78,0x5d2f001e,
-0xc78,0x5e30001e,
-0xc78,0x5f31001e,
-0xc78,0x6032001e,
-0xc78,0x6033001e,
-0xc78,0x6134001e,
-0xc78,0x6235001e,
-0xc78,0x6336001e,
-0xc78,0x6437001e,
-0xc78,0x6438001e,
-0xc78,0x6539001e,
-0xc78,0x663a001e,
-0xc78,0x673b001e,
-0xc78,0x673c001e,
-0xc78,0x683d001e,
-0xc78,0x693e001e,
-0xc78,0x6a3f001e,
-};
-
-#endif //__INC_HAL8192PciE_FW_IMG_DTM_H
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.c b/drivers/staging/rtl8192su/r8192S_firmware.c
index b3d69b3..3561adf 100644
--- a/drivers/staging/rtl8192su/r8192S_firmware.c
+++ b/drivers/staging/rtl8192su/r8192S_firmware.c
@@ -11,24 +11,14 @@
  *        NDIS_STATUS_FAILURE - the following initialization process should be terminated
  *        NDIS_STATUS_SUCCESS - if firmware initialization process success
 **************************************************************************************************/
-//#include "ieee80211.h"
-#if defined(RTL8192SE)||defined(RTL8192SU)
 #include "r8192U.h"
 #include "r8192S_firmware.h"
 #include <linux/unistd.h>
 
-#ifdef RTL8192SU
 #include "r8192S_hw.h"
 #include "r8192SU_HWImg.h"
-//#include "r8192S_FwImgDTM.h"
-#else
-//#include "r8192U_hw.h"
-#include "r8192xU_firmware_img.h"
-#endif
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 #include <linux/firmware.h>
-#endif
 
 #define   byte(x,n)  ( (x >> (8 * n)) & 0xff  )
 
@@ -53,9 +43,6 @@ bool FirmwareDownloadCode(struct net_device *dev, u8 *	code_virtual_address,u32
 	u8                  	    bLastIniPkt = 0;
 	u16 			    ExtraDescOffset = 0;
 
-#ifdef RTL8192SE
-	fw_SetRQPN(dev);	// For 92SE only
-#endif
 
 	RT_TRACE(COMP_FIRMWARE, "--->FirmwareDownloadCode()\n" );
 
@@ -120,19 +107,6 @@ cmdsend_downloadcode_fail:
 
 }
 
-#ifdef RTL8192SE
-static void fw_SetRQPN(struct net_device *dev)
-{
-	// Only for 92SE HW bug, we have to set RAPN before every FW download
-	// We can remove the code later.
-	write_nic_dword(dev,  RQPN, 0xffffffff);
-	write_nic_dword(dev,  RQPN+4, 0xffffffff);
-	write_nic_byte(dev,  RQPN+8, 0xff);
-	write_nic_byte(dev,  RQPN+0xB, 0x80);
-	//#if ((HAL_CODE_BASE ==  RTL8192_S) && (PLATFORM != PLATFORM_WINDOWS_USB))
-
-}	/* fw_SetRQPN */
-#endif
 
 RT_STATUS
 FirmwareEnableCPU(struct net_device *dev)
@@ -144,9 +118,6 @@ FirmwareEnableCPU(struct net_device *dev)
 	u32		iCheckTime = 200;
 
 	RT_TRACE(COMP_FIRMWARE, "-->FirmwareEnableCPU()\n" );
-#ifdef RTL8192SE
-	fw_SetRQPN(dev);	// For 92SE only
-#endif
 	// Enable CPU.
 	tmpU1b = read_nic_byte(dev, SYS_CLKR);
 	write_nic_byte(dev,  SYS_CLKR, (tmpU1b|SYS_CPU_CLKSEL)); //AFE source
@@ -305,10 +276,6 @@ FirmwareCheckReady(struct net_device *dev,	u8 LoadFWStatus)
               // <Roger_Notes> USB interface will update reserved followings parameters later!!
               // 2008.08.28.
               //
-#ifdef RTL8192SE
-		//write_nic_dword(dev, RQPN, 0x10101010);
-		//write_nic_byte(dev,  0xAB, 0x80);
-#endif
 
 	       //
               // <Roger_Notes> If right here, we can set TCR/RCR to desired value
@@ -323,13 +290,6 @@ FirmwareCheckReady(struct net_device *dev,	u8 LoadFWStatus)
 
 		RT_TRACE(COMP_FIRMWARE, "FirmwareCheckReady(): Current RCR settings(%#x)\n", tmpU4b);
 
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION) ||defined (RTL8192SU_ASIC_VERIFICATION))
-#ifdef NOT_YET   //YJ,TMP
-		priv->TransmitConfig = read_nic_dword(dev, TCR);
-		RT_TRACE(COMP_FIRMWARE, "FirmwareCheckReady(): Current TCR settings(%x)\n", priv->TransmitConfig);
-		pHalData->FwRsvdTxPageCfg = read_nic_byte(dev, FW_RSVD_PG_CRTL);
-#endif
-#endif
 
 		// Set to normal mode.
 		write_nic_byte(dev, LBKMD_SEL, LBK_NORMAL);
@@ -370,11 +330,9 @@ u8 FirmwareHeaderMapRfType(struct net_device *dev)
 void FirmwareHeaderPriveUpdate(struct net_device *dev, PRT_8192S_FIRMWARE_PRIV 	pFwPriv)
 {
 	struct r8192_priv 	*priv = ieee80211_priv(dev);
-#ifdef RTL8192SU
 	// Update USB endpoint number for RQPN settings.
 	pFwPriv->usb_ep_num = priv->EEPROMUsbEndPointNumber; // endpoint number: 4, 6 and 11.
 	RT_TRACE(COMP_INIT, "FirmwarePriveUpdate(): usb_ep_num(%#x)\n", pFwPriv->usb_ep_num);
-#endif
 
 	// Update RF types for RATR settings.
 	pFwPriv->rf_config = FirmwareHeaderMapRfType(dev);
@@ -406,16 +364,11 @@ bool FirmwareDownload92S(struct net_device *dev)
 	//3 //<1> Open Image file, and map file to contineous memory if open file success.
 	//3  //        or read image file from array. Default load from BIN file
 	//3//
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	priv->firmware_source = FW_SOURCE_HEADER_FILE;
-#else
 	priv->firmware_source = FW_SOURCE_IMG_FILE;// We should decided by Reg.
-#endif
 
 	switch( priv->firmware_source )
 	{
 		case FW_SOURCE_IMG_FILE:
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 			if(pFirmware->szFwTmpBufferLen == 0)
 			{
 
@@ -474,7 +427,6 @@ bool FirmwareDownload92S(struct net_device *dev)
 
 
 			}
-#endif
 			break;
 
 		case FW_SOURCE_HEADER_FILE:
@@ -585,439 +537,4 @@ bool FirmwareDownload92S(struct net_device *dev)
 	rtStatus = false;
 	return rtStatus;
 }
-#else
-void firmware_init_param(struct net_device *dev)
-{
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	rt_firmware		*pfirmware = priv->pFirmware;
-
-	pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE);
-}
-
-/*
- * segment the img and use the ptr and length to remember info on each segment
- *
- */
-bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buffer_len)
-{
-	struct r8192_priv   *priv = ieee80211_priv(dev);
-	bool 		    rt_status = true;
-	//u16		    frag_threshold;
-	u16		    frag_length, frag_offset = 0;
-	//u16		    total_size;
-	int		    i;
-
-	//rt_firmware	    *pfirmware = priv->pFirmware;
-	struct sk_buff	    *skb;
-	unsigned char	    *seg_ptr;
-	cb_desc		    *tcb_desc;
-	u8                  bLastIniPkt;
-#ifdef RTL8192SE
-	fw_SetRQPN(dev);	// For 92SE only
-#endif
-
-#ifndef RTL8192SU
-	if(buffer_len >= 64000-USB_HWDESC_HEADER_LEN)
-	{
-		return rt_status;
-	}
-	firmware_init_param(dev);
-	//Fragmentation might be required
-	frag_threshold = pfirmware->cmdpacket_frag_thresold;
-#endif
-
-	do {
-#ifndef RTL8192SU
-		if((buffer_len - frag_offset) > frag_threshold) {
-			frag_length = frag_threshold ;
-			bLastIniPkt = 0;
-
-		} else
-#endif
-		{
-			frag_length = buffer_len - frag_offset;
-			bLastIniPkt = 1;
-
-		}
-
-		/* Allocate skb buffer to contain firmware info and tx descriptor info
-		 * add 4 to avoid packet appending overflow.
-		 * */
-		#ifdef RTL8192U
-		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
-		#else
-		skb  = dev_alloc_skb(frag_length + 4);
-		#endif
-		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
-		tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
-		tcb_desc->queue_index = TXCMD_QUEUE;
-		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
-		tcb_desc->bLastIniPkt = bLastIniPkt;
-
-		#ifdef RTL8192U
-		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
-		#endif
-		seg_ptr = skb->data;
-		/*
-		 * Transform from little endian to big endian
-                 * and pending  zero
-		 */
-		for(i=0 ; i < frag_length; i+=4) {
-			*seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
-			*seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
-			*seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
-			*seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
-		}
-		tcb_desc->txbuf_size= (u16)i;
-		skb_put(skb, i);
-
-		if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
-			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
-			(priv->ieee80211->queue_stop) ) {
-			RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
-			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
-		} else {
-			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
-		}
-
-		code_virtual_address += frag_length;
-		frag_offset += frag_length;
-
-	}while(frag_offset < buffer_len);
-
-	return rt_status;
-
-#if 0
-cmdsend_downloadcode_fail:
-	rt_status = false;
-	RT_TRACE(COMP_ERR, "CmdSendDownloadCode fail !!\n");
-	return rt_status;
-#endif
-}
-
-bool
-fwSendNullPacket(
-	struct net_device *dev,
-	u32			Length
-)
-{
-	bool	rtStatus = true;
-	struct r8192_priv   *priv = ieee80211_priv(dev);
-	struct sk_buff	    *skb;
-	cb_desc		    *tcb_desc;
-	unsigned char	    *ptr_buf;
-	bool	bLastInitPacket = false;
-
-	//PlatformAcquireSpinLock(dev, RT_TX_SPINLOCK);
-
-	//Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
-	skb  = dev_alloc_skb(Length+ 4);
-	memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
-	tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
-	tcb_desc->queue_index = TXCMD_QUEUE;
-	tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
-	tcb_desc->bLastIniPkt = bLastInitPacket;
-	ptr_buf = skb_put(skb, Length);
-	memset(ptr_buf,0,Length);
-	tcb_desc->txbuf_size= (u16)Length;
-
-	if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
-			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
-			(priv->ieee80211->queue_stop) ) {
-			RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n");
-			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
-		} else {
-			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
-		}
-
-	//PlatformReleaseSpinLock(dev, RT_TX_SPINLOCK);
-	return rtStatus;
-}
-
-//-----------------------------------------------------------------------------
-// Procedure:    Check whether main code is download OK. If OK, turn on CPU
-//
-// Description:   CPU register locates in different page against general register.
-//			    Switch to CPU register in the begin and switch back before return
-//
-//
-// Arguments:   The pointer of the dev
-//
-// Returns:
-//        NDIS_STATUS_FAILURE - the following initialization process should be terminated
-//        NDIS_STATUS_SUCCESS - if firmware initialization process success
-//-----------------------------------------------------------------------------
-bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
-{
-	bool		rt_status = true;
-	int		check_putcodeOK_time = 200000, check_bootOk_time = 200000;
-	u32	 	CPU_status = 0;
-
-	/* Check whether put code OK */
-	do {
-		CPU_status = read_nic_dword(dev, CPU_GEN);
-
-		if(CPU_status&CPU_GEN_PUT_CODE_OK)
-			break;
-
-	}while(check_putcodeOK_time--);
-
-	if(!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
-		RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
-		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
-	} else {
-		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
-	}
-
-	/* Turn On CPU */
-	CPU_status = read_nic_dword(dev, CPU_GEN);
-	write_nic_byte(dev, CPU_GEN, (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff));
-	mdelay(1000);
-
-	/* Check whether CPU boot OK */
-	do {
-		CPU_status = read_nic_dword(dev, CPU_GEN);
-
-		if(CPU_status&CPU_GEN_BOOT_RDY)
-			break;
-	}while(check_bootOk_time--);
-
-	if(!(CPU_status&CPU_GEN_BOOT_RDY)) {
-		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
-	} else {
-		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
-	}
-
-	return rt_status;
-
-CPUCheckMainCodeOKAndTurnOnCPU_Fail:
-	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
-	rt_status = FALSE;
-	return rt_status;
-}
-
-bool CPUcheck_firmware_ready(struct net_device *dev)
-{
-
-	bool		rt_status = true;
-	int		check_time = 200000;
-	u32		CPU_status = 0;
-
-	/* Check Firmware Ready */
-	do {
-		CPU_status = read_nic_dword(dev, CPU_GEN);
-
-		if(CPU_status&CPU_GEN_FIRM_RDY)
-			break;
-
-	}while(check_time--);
-
-	if(!(CPU_status&CPU_GEN_FIRM_RDY))
-		goto CPUCheckFirmwareReady_Fail;
-	else
-		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
-
-	return rt_status;
-
-CPUCheckFirmwareReady_Fail:
-	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
-	rt_status = false;
-	return rt_status;
-
-}
-
-bool init_firmware(struct net_device *dev)
-{
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	bool			rt_status = TRUE;
-
-	u8			*firmware_img_buf[3] = { &rtl8190_fwboot_array[0],
-						   	 &rtl8190_fwmain_array[0],
-						   	 &rtl8190_fwdata_array[0]};
-
-	u32			firmware_img_len[3] = { sizeof(rtl8190_fwboot_array),
-						   	sizeof(rtl8190_fwmain_array),
-						   	sizeof(rtl8190_fwdata_array)};
-	u32			file_length = 0;
-	u8			*mapped_file = NULL;
-	u32			init_step = 0;
-	opt_rst_type_e	rst_opt = OPT_SYSTEM_RESET;
-	firmware_init_step_e 	starting_state = FW_INIT_STEP0_BOOT;
-
-	rt_firmware		*pfirmware = priv->pFirmware;
-	const struct firmware 	*fw_entry;
-	const char *fw_name[3] = { "RTL8192U/boot.img",
-                           "RTL8192U/main.img",
-			   "RTL8192U/data.img"};
-	int rc;
-
-	RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
-
-	if (pfirmware->firmware_status == FW_STATUS_0_INIT ) {
-		/* it is called by reset */
-		rst_opt = OPT_SYSTEM_RESET;
-		starting_state = FW_INIT_STEP0_BOOT;
-		// TODO: system reset
-
-	}else if(pfirmware->firmware_status == FW_STATUS_5_READY) {
-		/* it is called by Initialize */
-		rst_opt = OPT_FIRMWARE_RESET;
-		starting_state = FW_INIT_STEP2_DATA;
-	}else {
-		 RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n");
-	}
-
-	/*
-	 * Download boot, main, and data image for System reset.
-	 * Download data image for firmware reseta
-	 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	priv->firmware_source = FW_SOURCE_HEADER_FILE;
-#else
-	priv->firmware_source = FW_SOURCE_IMG_FILE;
-#endif
-	for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
-		/*
-		 * Open Image file, and map file to contineous memory if open file success.
-		 * or read image file from array. Default load from IMG file
-		 */
-		if(rst_opt == OPT_SYSTEM_RESET) {
-			switch(priv->firmware_source) {
-				case FW_SOURCE_IMG_FILE:
-				#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-					rc = request_firmware(&fw_entry, fw_name[init_step],&priv->udev->dev);
-					if(rc < 0 ) {
-						RT_TRACE(COMP_ERR, "request firmware fail!\n");
-						goto download_firmware_fail;
-					}
-
-					if(fw_entry->size > sizeof(pfirmware->firmware_buf)) {
-						RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
-						goto download_firmware_fail;
-					}
-
-					if(init_step != FW_INIT_STEP1_MAIN) {
-						memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size);
-						mapped_file = pfirmware->firmware_buf;
-						file_length = fw_entry->size;
-					} else {
-					#ifdef RTL8190P
-						memcpy(pfirmware->firmware_buf,fw_entry->data,fw_entry->size);
-						mapped_file = pfirmware->firmware_buf;
-						file_length = fw_entry->size;
-					#else
-						memset(pfirmware->firmware_buf,0,128);
-						memcpy(&pfirmware->firmware_buf[128],fw_entry->data,fw_entry->size);
-						mapped_file = pfirmware->firmware_buf;
-						file_length = fw_entry->size + 128;
-					#endif
-					}
-					pfirmware->firmware_buf_size = file_length;
-					#endif
-					break;
-
-				case FW_SOURCE_HEADER_FILE:
-					mapped_file =  firmware_img_buf[init_step];
-					file_length  = firmware_img_len[init_step];
-					if(init_step == FW_INIT_STEP2_DATA) {
-						memcpy(pfirmware->firmware_buf, mapped_file, file_length);
-						pfirmware->firmware_buf_size = file_length;
-					}
-					break;
-
-				default:
-					break;
-			}
-
-
-		}else if(rst_opt == OPT_FIRMWARE_RESET ) {
-			/* we only need to download data.img here */
-			mapped_file = pfirmware->firmware_buf;
-			file_length = pfirmware->firmware_buf_size;
-		}
-
-		/* Download image file */
-		/* The firmware download process is just as following,
-		 * 1. that is each packet will be segmented and inserted to the wait queue.
-		 * 2. each packet segment will be put in the skb_buff packet.
-		 * 3. each skb_buff packet data content will already include the firmware info
-		 *   and Tx descriptor info
-		 * */
-		rt_status = fw_download_code(dev,mapped_file,file_length);
-		#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-		if(rst_opt == OPT_SYSTEM_RESET) {
-			release_firmware(fw_entry);
-		}
-		#endif
-
-		if(rt_status != TRUE) {
-			goto download_firmware_fail;
-		}
-
-		switch(init_step) {
-			case FW_INIT_STEP0_BOOT:
-				/* Download boot
-				 * initialize command descriptor.
-				 * will set polling bit when firmware code is also configured
-				 */
-				pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
-#ifdef RTL8190P
-				// To initialize IMEM, CPU move code  from 0x80000080, hence, we send 0x80 byte packet
-				rt_status = fwSendNullPacket(dev, RTL8190_CPU_START_OFFSET);
-				if(rt_status != true)
-				{
-					RT_TRACE(COMP_INIT, "fwSendNullPacket() fail ! \n");
-					goto  download_firmware_fail;
-				}
-#endif
-				//mdelay(1000);
-				/*
-				 * To initialize IMEM, CPU move code  from 0x80000080,
-				 * hence, we send 0x80 byte packet
-				 */
-				break;
-
-			case FW_INIT_STEP1_MAIN:
-				/* Download firmware code. Wait until Boot Ready and Turn on CPU */
-				pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
-
-				/* Check Put Code OK and Turn On CPU */
-				rt_status = CPUcheck_maincodeok_turnonCPU(dev);
-				if(rt_status != TRUE) {
-					RT_TRACE(COMP_ERR, "CPUcheck_maincodeok_turnonCPU fail!\n");
-					goto download_firmware_fail;
-				}
-
-				pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
-				break;
-
-			case FW_INIT_STEP2_DATA:
-				/* download initial data code */
-				pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
-				mdelay(1);
-
-				rt_status = CPUcheck_firmware_ready(dev);
-				if(rt_status != TRUE) {
-					RT_TRACE(COMP_ERR, "CPUcheck_firmware_ready fail(%d)!\n",rt_status);
-					goto download_firmware_fail;
-				}
-
-				/* wait until data code is initialized ready.*/
-				pfirmware->firmware_status = FW_STATUS_5_READY;
-				break;
-		}
-	}
-
-	RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
-	//assert(pfirmware->firmware_status == FW_STATUS_5_READY, ("Firmware Download Fail\n"));
-
-	return rt_status;
-
-download_firmware_fail:
-	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
-	rt_status = FALSE;
-	return rt_status;
-
-}
-#endif
 
diff --git a/drivers/staging/rtl8192su/r8192S_firmware.h b/drivers/staging/rtl8192su/r8192S_firmware.h
index 047f8ae..c525380 100644
--- a/drivers/staging/rtl8192su/r8192S_firmware.h
+++ b/drivers/staging/rtl8192su/r8192S_firmware.h
@@ -30,12 +30,7 @@
 #define	MAX_FIRMWARE_CODE_SIZE	0xFF00 // Firmware Local buffer size.
 #define 	RTL8190_CPU_START_OFFSET			0x80
 
-#ifdef RTL8192SE
-//It should be double word alignment
-#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	4*(v/4) - 8
-#else
 #define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	(4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
-#endif
 
 //typedef enum _DESC_PACKET_TYPE{
 //	DESC_PACKET_TYPE_INIT = 0,
diff --git a/drivers/staging/rtl8192su/r8192S_hw.h b/drivers/staging/rtl8192su/r8192S_hw.h
index 7a3d850..82ea96b 100644
--- a/drivers/staging/rtl8192su/r8192S_hw.h
+++ b/drivers/staging/rtl8192su/r8192S_hw.h
@@ -49,10 +49,8 @@ typedef	enum _RT_RF_TYPE_DEFINITION
 	RF_1T2R = 0,
 	RF_2T4R,
 	RF_2T2R,
-#ifdef RTL8192SU
 	RF_1T1R,
 	RF_2T2R_GREEN,
-#endif
 	//RF_3T3R,
 	//RF_3T4R,
 	//RF_4T4R,
@@ -64,16 +62,6 @@ typedef enum _BaseBand_Config_Type{
 	BaseBand_Config_AGC_TAB = 1,			//Radio Path B
 }BaseBand_Config_Type, *PBaseBand_Config_Type;
 
-#if 0
-typedef enum _RT_RF_TYPE_819xU{
-	RF_TYPE_MIN = 0,
-	RF_8225,
-	RF_8256,
-	RF_8258,
-	RF_PSEUDO_11N = 4,
-}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
-#endif
-
 #define	RTL8187_REQT_READ		0xc0
 #define	RTL8187_REQT_WRITE	0x40
 #define	RTL8187_REQ_GET_REGS	0x05
@@ -1205,112 +1193,6 @@ Default: 00b.
 //       8192S EEPROM/EFUSE share register definition.
 //----------------------------------------------------------------------------
 
-#ifdef RTL8192SE
-//
-// 2008/11/05 MH Redefine EEPROM address for 8192SE
-// 92SE/SU EEPROM definition seems not the same!!!!!!
-// EEPROM MAP REgister Definition!!!! Please refer to 8192SE EEPROM V0.5 2008/10/21
-// Update to 8192SE EEPROM V0.6 2008/11/11
-//
-#define 		RTL8190_EEPROM_ID				0x8129	// 0-1
-#define 		EEPROM_HPON					0x02 // LDO settings.2-5
-#define 		EEPROM_CLK						0x06 // Clock settings.6-7
-#define 		EEPROM_TESTR					0x08 // SE Test mode.8
-
-#define 		EEPROM_VID						0x0A // SE Vendor ID.A-B
-#define 		EEPROM_DID						0x0C // SE Device ID. C-D
-#define 		EEPROM_SVID					0x0E // SE Vendor ID.E-F
-#define 		EEPROM_SMID					0x10 // SE PCI Subsystem ID. 10-11
-
-#define 		EEPROM_MAC_ADDR				0x12 // SEMAC Address. 12-17
-#define 		EEPROM_NODE_ADDRESS_BYTE_0	0x12 // MAC address.
-
-#define 		EEPROM_PwDiff					0x54 // Difference of gain index between legacy and high throughput OFDM.
-
-//
-// 0x20 - 4B EPHY parameter!!!
-//
-//
-#define 		EEPROM_TxPowerBase			0x50 // Tx Power of serving station.
-#define 		EEPROM_TxPwIndex_CCK_24G	0x5D // 0x50~0x5D Range = 0~0x24//FIXLZM
-#define 		EEPROM_TxPwIndex_OFDM_24G	0x6B // 0x5E~0x6B Range = 0~0x24//FIXLZM
-#define		EEPROM_TX_PWR_INDEX_RANGE	28		// CCK and OFDM 14 channel
-
-
-// 2009/01/21 MH Add for SD3 requirement
-#define 		EEPROM_TX_PWR_HT20_DIFF		0x62// HT20 Tx Power Index Difference
-#define 		DEFAULT_HT20_TXPWR_DIFF		2	// HT20<->40 default Tx Power Index Difference
-#define 		EEPROM_TX_PWR_OFDM_DIFF		0x65// OFDM Tx Power Index Difference
-#define 		EEPROM_TX_PWR_BAND_EDGE	0x67// TX Power offset at band-edge channel
-#define 		TX_PWR_BAND_EDGE_CHK		0x6D// Check if band-edge scheme is enabled
-
-// Oly old EEPROM format support the definition=============================
-//
-#define 		EEPROM_TxPwIndex_CCK_24G	0x5D // 0x50~0x5D Range = 0~0x24
-#define 		EEPROM_TxPwIndex_OFDM_24G	0x6B // 0x5E~0x6B Range = 0~0x24
-#define 		EEPROM_HT2T_CH1_A			0x6c //HT 2T path A channel 1 Power Index.
-#define 		EEPROM_HT2T_CH7_A			0x6d //HT 2T path A channel 7 Power Index.
-#define 		EEPROM_HT2T_CH13_A			0x6e //HT 2T path A channel 13 Power Index.
-#define 		EEPROM_HT2T_CH1_B			0x6f //HT 2T path B channel 1 Power Index.
-#define 		EEPROM_HT2T_CH7_B			0x70 //HT 2T path B channel 7 Power Index.
-#define 		EEPROM_HT2T_CH13_B			0x71 //HT 2T path B channel 13 Power Index.
-//
-#define 		EEPROM_TSSI_A					0x74 //TSSI value of path A.
-#define 		EEPROM_TSSI_B					0x75 //TSSI value of path B.
-//
-#define		EEPROM_RFInd_PowerDiff				0x76
-#define		EEPROM_Default_LegacyHTTxPowerDiff	0x3
-//
-#define 		EEPROM_ThermalMeter			0x77 // Thermal meter default value.
-#define 		EEPROM_CrystalCap				0x79 // Crystal Cap.
-#define 		EEPROM_ChannelPlan				0x7B // Map of supported channels.
-#define 		EEPROM_Version					0x7C // The EEPROM content version
-#define		EEPROM_CustomID				0x7A
-#define 		EEPROM_BoardType				0x7E
-// 0: 2x2 Green RTL8192GE miniCard (QFN68)
-// 1: 1x2            RTL8191SE miniCard (QFN64)
-// 2: 2x2            RTL8192SE miniCard (QFN68)
-// 3: 1x2            RTL8191SR minicCard(QFN64)
-
-//
-// Default Value for EEPROM or EFUSE!!!
-//
-#define		EEPROM_Default_TSSI			0x0
-#define 		EEPROM_Default_TxPowerDiff		0x0
-#define 		EEPROM_Default_CrystalCap		0x5
-#define 		EEPROM_Default_BoardType		0x02 // Default: 2X2, RTL8192SE(QFPN68)
-#define 		EEPROM_Default_TxPower		0x1010
-#define		EEPROM_Default_HT2T_TxPwr		0x10
-
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-#define 		EEPROM_Default_TxPowerBase	0x0
-#define 		EEPROM_Default_ThermalMeter	0x12
-#define 		EEPROM_Default_PwDiff			0x4
-#else
-#define		EEPROM_Default_LegacyHTTxPowerDiff	0x3
-#define		EEPROM_Default_ThermalMeter		0x12
-#define		EEPROM_Default_AntTxPowerDiff		0x0
-#define		EEPROM_Default_TxPwDiff_CrystalCap	0x5
-#define		EEPROM_Default_TxPowerLevel		0x22
-#endif
-
-#define		EEPROM_CHANNEL_PLAN_FCC				0x0
-#define		EEPROM_CHANNEL_PLAN_IC				0x1
-#define		EEPROM_CHANNEL_PLAN_ETSI			0x2
-#define		EEPROM_CHANNEL_PLAN_SPAIN			0x3
-#define		EEPROM_CHANNEL_PLAN_FRANCE			0x4
-#define		EEPROM_CHANNEL_PLAN_MKK				0x5
-#define		EEPROM_CHANNEL_PLAN_MKK1			0x6
-#define		EEPROM_CHANNEL_PLAN_ISRAEL			0x7
-#define		EEPROM_CHANNEL_PLAN_TELEC			0x8
-#define		EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN	0x9
-#define		EEPROM_CHANNEL_PLAN_WORLD_WIDE_13	0xA
-#define		EEPROM_CHANNEL_PLAN_BY_HW_MASK	0x80
-
-
-#define 		EEPROM_CID_DEFAULT					0x0
-#define 		EEPROM_CID_TOSHIBA			0x4
-#else
 //----------------------------------------------------------------------------
 //       8192S EEROM and Compatible E-Fuse definition. Added by Roger, 2008.10.21.
 //----------------------------------------------------------------------------
@@ -1330,25 +1212,6 @@ Default: 00b.
 
 
 	// <Roger_Notes> The followin are for different version of EEPROM contents purpose. 2008.11.22.
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-#define 		EEPROM_PwDiff					0x54 // Difference of gain index between legacy and high throughput OFDM.
-#define 		EEPROM_ThermalMeter			0x55 // Thermal meter default value.
-#define 		EEPROM_Reserved				0x56 // Reserved.
-#define 		EEPROM_CrystalCap				0x57 // Crystal Cap.
-#define 		EEPROM_TxPowerBase			0x58 // Tx Power of serving station.
-#define 		EEPROM_TxPwIndex_CCK_24G	0x59 // 0x59~0x66
-#define 		EEPROM_TxPwIndex_OFDM_24G	0x67 // 0x67~0x74
-#define 		EEPROM_TSSI_A					0x75 //TSSI value of path A.
-#define 		EEPROM_TSSI_B					0x76 //TSSI value of path B.
-#define 		EEPROM_TxPwTkMode			0x77 //Tx Power tracking mode.
-#define 		EEPROM_HT2T_CH1_A			0x78 //HT 2T path A channel 1 Power Index.
-#define 		EEPROM_HT2T_CH7_A			0x79 //HT 2T path A channel 7 Power Index.
-#define 		EEPROM_HT2T_CH13_A			0x7a //HT 2T path A channel 13 Power Index.
-#define 		EEPROM_HT2T_CH1_B			0x7b //HT 2T path B channel 1 Power Index.
-#define 		EEPROM_HT2T_CH7_B			0x7c //HT 2T path B channel 7 Power Index.
-#define 		EEPROM_HT2T_CH13_B			0x7d //HT 2T path B channel 13 Power Index.
-#define 		EEPROM_BoardType				0x7e //0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU
-#else
 #define 		EEPROM_BoardType				0x54 //0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU
 #define		EEPROM_TxPwIndex				0x55 //0x55-0x66, Tx Power index.
 #define 		EEPROM_PwDiff					0x67 // Difference of gain index between legacy and high throughput OFDM.
@@ -1366,7 +1229,6 @@ Default: 00b.
 #define 		EEPROM_TX_PWR_OFDM_DIFF		0x71// OFDM Tx Power Index Difference
 #define 		EEPROM_TX_PWR_BAND_EDGE	0x73// TX Power offset at band-edge channel
 #define 		TX_PWR_BAND_EDGE_CHK		0x79// Check if band-edge scheme is enabled
-#endif
 #define		EEPROM_Default_LegacyHTTxPowerDiff	0x3
 #define		EEPROM_USB_Default_OPTIONAL_FUNC	0x8
 #define		EEPROM_USB_Default_PHY_PARAM		0x0
@@ -1408,7 +1270,6 @@ Default: 00b.
 //#define EEPROM_CID_TOSHIBA						0x4
 //#define EEPROM_CID_NetCore						0x5
 #define 		EEPROM_CID_WHQL 				0xFE // added by chiyoko for dtm, 20090108
-#endif
 
 //-----------------------------------------------------------------
 // 0x2c0 FW Command Control register definition, added by Roger, 2008.11.27.
@@ -1432,51 +1293,6 @@ Default: 00b.
 #define		FW_DM_DISABLE					0xfd00aa00
 #define		FW_BB_RESET_ENABLE			0xff00000d
 #define		FW_BB_RESET_DISABLE			0xff00000e
-#if 0
-//----------------------------------------------------------------------------
-//       8190 EEROM
-//----------------------------------------------------------------------------
-#define		RTL8190_EEPROM_ID					0x8129
-//#define		EEPROM_NODE_ADDRESS_BYTE_0			0x0C
-
-#define		EEPROM_RFInd_PowerDiff				0x28
-#define		EEPROM_ThermalMeter					0x29
-#define		EEPROM_TxPwDiff_CrystalCap			0x2A	//0x2A~0x2B
-#define		EEPROM_TxPwIndex_CCK				0x2C	//0x2C~0x39
-#define		EEPROM_TxPwIndex_OFDM_24G			0x3A	//0x3A~0x47
-#define		EEPROM_TxPwIndex_OFDM_5G			0x34	//0x34~0x7B
-
-//The following definition is for eeprom 93c56......modified 20080220
-#define		EEPROM_C56_CrystalCap				0x17	//0x17
-#define		EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex	0x80	//0x80
-#define		EEPROM_C56_RfA_HT_OFDM_TxPwIndex	0x81	//0x81~0x83
-#define		EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex	0xbc	//0xb8
-#define		EEPROM_C56_RfC_HT_OFDM_TxPwIndex	0xb9	//0xb9~0xbb
-#define		EEPROM_Customer_ID					0x7B	//0x7B:CustomerID
-#define		EEPROM_ICVersion_ChannelPlan		0x7C	//0x7C:ChnlPlan,
-														//0x7D:IC_Ver
-#define		EEPROM_CRC							0x7E	//0x7E~0x7F
-
-#define		EEPROM_Default_LegacyHTTxPowerDiff	0x4
-#define		EEPROM_Default_ThermalMeter			0x77
-#define		EEPROM_Default_AntTxPowerDiff		0x0
-#define		EEPROM_Default_TxPwDiff_CrystalCap	0x5
-#define		EEPROM_Default_TxPower				0x1010
-#define		EEPROM_Default_TxPowerLevel			0x10
-
-//
-// Define Different EEPROM type for customer
-//
-#define		EEPROM_CID_DEFAULT					0x0
-#define		EEPROM_CID_CAMEO					0x1
-#define		EEPROM_CID_RUNTOP					0x2
-#define		EEPROM_CID_Senao					0x3
-#define		EEPROM_CID_TOSHIBA					0x4
-#define		EEPROM_CID_NetCore					0x5
-#define		EEPROM_CID_Nettronix				0x6
-#define		EEPROM_CID_Pronet					0x7
-
-#endif
 
 //
 //--------------92SU require delete or move to other place later
diff --git a/drivers/staging/rtl8192su/r8192S_phy.c b/drivers/staging/rtl8192su/r8192S_phy.c
index 99a4051..2c111d7 100644
--- a/drivers/staging/rtl8192su/r8192S_phy.c
+++ b/drivers/staging/rtl8192su/r8192S_phy.c
@@ -35,21 +35,12 @@
 #include "r8192U_dm.h"
 #include "r8192S_rtl6052.h"
 
-#ifdef RTL8192SU
 #include "r8192S_hw.h"
 #include "r8192S_phy.h"
 #include "r8192S_phyreg.h"
 #include "r8192SU_HWImg.h"
-//#include "r8192S_FwImgDTM.h"
-#else
-#include "r8192U_hw.h"
-#include "r819xU_phy.h"
-#include "r819xU_phyreg.h"
-#endif
 
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
+#include "ieee80211/dot11d.h"
 
 /*---------------------------Define Local Constant---------------------------*/
 /* Channel switch:The size of command tables for switch channel*/
@@ -60,26 +51,6 @@
 
 /*------------------------Define local variable------------------------------*/
 // 2004-05-11
-#ifndef RTL8192SU
-static u32	RF_CHANNEL_TABLE_ZEBRA[]={
-		0,
-		0x085c,//2412 1
-		0x08dc,//2417 2
-		0x095c,//2422 3
-		0x09dc,//2427 4
-		0x0a5c,//2432 5
-		0x0adc,//2437 6
-		0x0b5c,//2442 7
-		0x0bdc,//2447 8
-		0x0c5c,//2452 9
-		0x0cdc,//2457 10
-		0x0d5c,//2462 11
-		0x0ddc,//2467 12
-		0x0e5c,//2472 13
-		//0x0f5c,//2484
-		0x0f72,//2484  //20040810
-};
-#endif
 
 static	u32
 phy_CalculateBitShift(u32 BitMask);
@@ -111,18 +82,11 @@ phy_SwChnlStepByStep(
 	);
 static RT_STATUS
 phy_ConfigBBWithPgHeaderFile(struct net_device* dev,u8 ConfigType);
-#ifdef RTL8192SE
-static  u32 phy_FwRFSerialRead( struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset);
-static u32 phy_RFSerialRead(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset);
-static	void phy_FwRFSerialWrite( struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
-static void phy_RFSerialWrite( struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
-#endif
 static long phy_TxPwrIdxToDbm( struct net_device* dev, WIRELESS_MODE   WirelessMode, u8 TxPwrIdx);
 static u8 phy_DbmToTxPwrIdx( struct net_device* dev, WIRELESS_MODE WirelessMode, long PowerInDbm);
 void phy_SetFwCmdIOCallback(struct net_device* dev);
 
 //#if ((HAL_CODE_BASE == RTL8192_S) && (DEV_BUS_TYPE==USB_INTERFACE))
-#ifdef RTL8192SU
 //
 // Description:
 //	Base Band read by 4181 to make sure that operation could be done in unlimited cycle.
@@ -390,7 +354,6 @@ void phy_SetUsbRFReg(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32	RegAdd
 
 }
 
-#endif
 
 /*---------------------Define local function prototype-----------------------*/
 
@@ -420,9 +383,6 @@ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
 
   	u32	ReturnValue = 0, OriginalValue, BitShift;
 
-#if (DISABLE_BB_RF == 1)
-	return 0;
-#endif
 
 	RT_TRACE(COMP_RF, "--->PHY_QueryBBReg(): RegAddr(%#x), BitMask(%#x)\n", RegAddr, BitMask);
 
@@ -433,7 +393,6 @@ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
 	// 2008.09.06.
 	//
 //#if ((HAL_CODE_BASE == RTL8192_S) && (DEV_BUS_TYPE==USB_INTERFACE))
-#ifdef RTL8192SU
 	if(IS_BB_REG_OFFSET_92S(RegAddr))
 	{
 		//if(RT_USB_CANNOT_IO(Adapter))	return	FALSE;
@@ -447,7 +406,6 @@ u32 rtl8192_QueryBBReg(struct net_device* dev, u32 RegAddr, u32 BitMask)
 	OriginalValue = phy_QueryUsbBBReg(dev, RegAddr);
 	}
 	else
-#endif
 	{
 	OriginalValue = read_nic_dword(dev, RegAddr);
 	}
@@ -483,9 +441,6 @@ void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data
 {
 	u32	OriginalValue, BitShift, NewValue;
 
-#if (DISABLE_BB_RF == 1)
-	return;
-#endif
 
 	RT_TRACE(COMP_RF, "--->PHY_SetBBReg(): RegAddr(%#x), BitMask(%#x), Data(%#x)\n", RegAddr, BitMask, Data);
 
@@ -496,7 +451,6 @@ void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data
 	// 2008.09.06.
 	//
 //#if ((HAL_CODE_BASE == RTL8192_S) && (DEV_BUS_TYPE==USB_INTERFACE))
-#ifdef RTL8192SU
 	if(IS_BB_REG_OFFSET_92S(RegAddr))
 	{
 		if((RegAddr & 0x03) != 0)
@@ -515,7 +469,6 @@ void rtl8192_setBBreg(struct net_device* dev, u32 RegAddr, u32 BitMask, u32 Data
 			phy_SetUsbBBReg(dev, RegAddr, Data);
 	}
 	else
-#endif
 	{
 		if(BitMask!= bMaskDWord)
 		{//if not "double word" write
@@ -559,9 +512,6 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3
 	u32 Original_Value, Readback_Value, BitShift;//, flags;
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-#if (DISABLE_BB_RF == 1)
-	return 0;
-#endif
 
 	RT_TRACE(COMP_RF, "--->PHY_QueryRFReg(): RegAddr(%#x), eRFPath(%#x), BitMask(%#x)\n", RegAddr, eRFPath,BitMask);
 
@@ -588,19 +538,8 @@ u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u3
 	// 2008.09.06.
 	//
 //#if (HAL_CODE_BASE == RTL8192_S && DEV_BUS_TYPE==USB_INTERFACE)
-#ifdef RTL8192SU
 	//if(RT_USB_CANNOT_IO(Adapter))	return FALSE;
 	Original_Value = phy_QueryUsbRFReg(dev, eRFPath, RegAddr);
-#else
-	if (priv->Rf_Mode == RF_OP_By_FW)
-	{
-		Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
-	}
-	else
-	{
-		Original_Value = phy_RFSerialRead(dev, eRFPath, RegAddr);
-	}
-#endif
 
 	BitShift =  phy_CalculateBitShift(BitMask);
 	Readback_Value = (Original_Value & BitMask) >> BitShift;
@@ -638,9 +577,6 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32
 
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u32 Original_Value, BitShift, New_Value;//, flags;
-#if (DISABLE_BB_RF == 1)
-	return;
-#endif
 
 	RT_TRACE(COMP_RF, "--->PHY_SetRFReg(): RegAddr(%#x), BitMask(%#x), Data(%#x), eRFPath(%#x)\n",
 		RegAddr, BitMask, Data, eRFPath);
@@ -667,7 +603,6 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32
 	// 2008.09.06.
 	//
 //#if (HAL_CODE_BASE == RTL8192_S && DEV_BUS_TYPE==USB_INTERFACE)
-#ifdef RTL8192SU
 		//if(RT_USB_CANNOT_IO(Adapter))	return;
 
 		if (BitMask != bRFRegOffsetMask) // RF data is 12 bits only
@@ -679,37 +614,6 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32
 		}
 		else
 			phy_SetUsbRFReg(dev, eRFPath, RegAddr, Data);
-#else
-	if (priv->Rf_Mode == RF_OP_By_FW)
-	{
-		//DbgPrint("eRFPath-%d Addr[%02x] = %08x\n", eRFPath, RegAddr, Data);
-		if (BitMask != bRFRegOffsetMask) // RF data is 12 bits only
-		{
-			Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
-			BitShift =  phy_CalculateBitShift(BitMask);
-			New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift));
-
-			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value);
-		}
-		else
-			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data);
-	}
-	else
-	{
-		//DbgPrint("eRFPath-%d Addr[%02x] = %08x\n", eRFPath, RegAddr, Data);
-		if (BitMask != bRFRegOffsetMask) // RF data is 12 bits only
-		{
-			Original_Value = phy_RFSerialRead(dev, eRFPath, RegAddr);
-			BitShift =  phy_CalculateBitShift(BitMask);
-			New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift));
-
-			phy_RFSerialWrite(dev, eRFPath, RegAddr, New_Value);
-		}
-		else
-			phy_RFSerialWrite(dev, eRFPath, RegAddr, Data);
-
-	}
-#endif
 	//PlatformReleaseSpinLock(dev, RT_RF_OPERATE_SPINLOCK);
 	//spin_unlock_irqrestore(&priv->rf_lock, flags);   //YJ,test,090113
 	up(&priv->rf_sem);
@@ -719,579 +623,6 @@ void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32
 
 }
 
-#ifdef RTL8192SE
-/*-----------------------------------------------------------------------------
- * Function:	phy_FwRFSerialRead()
- *
- * Overview:	We support firmware to execute RF-R/W.
- *
- * Input:		NONE
- *
- * Output:		NONE
- *
- * Return:		NONE
- *
- * Revised History:
- *	When		Who		Remark
- *	01/21/2008	MHC		Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-//use in phy only
-static	u32
-phy_FwRFSerialRead(
-	struct net_device* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32				Offset	)
-{
-	u32		retValue = 0;
-	//u32		Data = 0;
-	//u8		time = 0;
-#if 0
-	//DbgPrint("FW RF CTRL\n\r");
-	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
-	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
-	   much time. This is only for site survey. */
-	// 1. Read operation need not insert data. bit 0-11
-	//Data &= bMask12Bits;
-	// 2. Write RF register address. Bit 12-19
-	Data |= ((Offset&0xFF)<<12);
-	// 3. Write RF path.  bit 20-21
-	Data |= ((eRFPath&0x3)<<20);
-	// 4. Set RF read indicator. bit 22=0
-	//Data |= 0x00000;
-	// 5. Trigger Fw to operate the command. bit 31
-	Data |= 0x80000000;
-	// 6. We can not execute read operation if bit 31 is 1.
-	while (PlatformIORead4Byte(dev, QPNR)&0x80000000)
-	{
-		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
-		if (time++ < 100)
-		{
-			//DbgPrint("FW not finish RF-R Time=%d\n\r", time);
-			delay_us(10);
-		}
-		else
-			break;
-	}
-	// 7. Execute read operation.
-	PlatformIOWrite4Byte(dev, QPNR, Data);
-	// 8. Check if firmawre send back RF content.
-	while (PlatformIORead4Byte(dev, QPNR)&0x80000000)
-	{
-		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
-		if (time++ < 100)
-		{
-			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
-			delay_us(10);
-		}
-		else
-			return	(0);
-	}
-	retValue = PlatformIORead4Byte(dev, RF_DATA);
-#endif
-	return	(retValue);
-
-}	/* phy_FwRFSerialRead */
-
-/*-----------------------------------------------------------------------------
- * Function:	phy_FwRFSerialWrite()
- *
- * Overview:	We support firmware to execute RF-R/W.
- *
- * Input:		NONE
- *
- * Output:		NONE
- *
- * Return:		NONE
- *
- * Revised History:
- *	When		Who		Remark
- *	01/21/2008	MHC		Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-//use in phy only
-static	void
-phy_FwRFSerialWrite(
-	struct net_device* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32				Offset,
-	u32				Data	)
-{
-#if 0
-	u8	time = 0;
-	DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data);
-	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
-	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
-	   much time. This is only for site survey. */
-
-	// 1. Set driver write bit and 12 bit data. bit 0-11
-	//Data &= bMask12Bits;	// Done by uper layer.
-	// 2. Write RF register address. bit 12-19
-	Data |= ((Offset&0xFF)<<12);
-	// 3. Write RF path.  bit 20-21
-	Data |= ((eRFPath&0x3)<<20);
-	// 4. Set RF write indicator. bit 22=1
-	Data |= 0x400000;
-	// 5. Trigger Fw to operate the command. bit 31=1
-	Data |= 0x80000000;
-
-	// 6. Write operation. We can not write if bit 31 is 1.
-	while (PlatformIORead4Byte(dev, QPNR)&0x80000000)
-	{
-		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
-		if (time++ < 100)
-		{
-			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
-			delay_us(10);
-		}
-		else
-			break;
-	}
-	// 7. No matter check bit. We always force the write. Because FW will
-	//    not accept the command.
-	PlatformIOWrite4Byte(dev, QPNR, Data);
-	/* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware
-	   to finish RF write operation. */
-	/* 2008/01/17 MH We support delay in firmware side now. */
-	//delay_us(20);
-#endif
-}	/* phy_FwRFSerialWrite */
-
-/**
-* Function:	phy_RFSerialRead
-*
-* OverView:	Read regster from RF chips
-*
-* Input:
-*			PADAPTER		Adapter,
-*			RF90_RADIO_PATH_E	eRFPath,	//Radio path of A/B/C/D
-*			u32			Offset,		//The target address to be read
-*
-* Output:	None
-* Return:		u32			reback value
-* Note:		Threre are three types of serial operations:
-*			1. Software serial write
-*			2. Hardware LSSI-Low Speed Serial Interface
-*			3. Hardware HSSI-High speed
-*			serial write. Driver need to implement (1) and (2).
-*			This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
-*/
-//use in phy only
-static u32 phy_RFSerialRead(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset)
-{
-
-	u32						retValue = 0;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];
-	u32						NewOffset;
-	u8						RfPiEnable=0;
-
-
-	//
-	// Make sure RF register offset is correct
-	//
-	Offset &= 0x3f;
-
-	//
-	// Switch page for 8256 RF IC
-	//
-	if(	priv->rf_chip == RF_8256 ||
-		priv->rf_chip == RF_8225 ||
-		priv->rf_chip == RF_6052)
-	{
-		//analog to digital off, for protection
-		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
-
-		if(Offset>=31)
-		{
-			priv->RFReadPageCnt[2]++;//cosa add for debug
-			priv->RfReg0Value[eRFPath] |= 0x140;
-
-			// Switch to Reg_Mode2 for Reg31~45
-			rtl8192_setBBreg(dev,
-				pPhyReg->rf3wireOffset,
-				bMaskDWord,
-				(priv->RfReg0Value[eRFPath] << 16)	);
-
-			// Modified Offset
-			NewOffset = Offset - 30;
-
-		}else if(Offset>=16)
-		{
-			priv->RFReadPageCnt[1]++;//cosa add for debug
-			priv->RfReg0Value[eRFPath] |= 0x100;
-			priv->RfReg0Value[eRFPath] &= (~0x40);
-
-			// Switch to Reg_Mode1 for Reg16~30
-			rtl8192_setBBreg(dev,
-				pPhyReg->rf3wireOffset,
-				bMaskDWord,
-				(priv->RfReg0Value[eRFPath] << 16)	);
-
-			// Modified Offset
-			NewOffset = Offset - 15;
-		}
-		else
-		{
-			priv->RFReadPageCnt[0]++;//cosa add for debug
-			NewOffset = Offset;
-	}
-	}
-	else
-		NewOffset = Offset;
-
-	//
-	// Put desired read address to LSSI control register
-	//
-	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset);
-
-	//
-	// Issue a posedge trigger
-	//
-	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x0);
-	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x1);
-
-	// TODO: we should not delay such a  long time. Ask help from SD3
-	mdelay(1);
-
-	retValue = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
-
-	// Switch back to Reg_Mode0;
-	if(	priv->rf_chip == RF_8256 ||
-		priv->rf_chip == RF_8225 ||
-		priv->rf_chip == RF_0222D)
-	{
-		if (Offset >= 0x10)
-		{
-			priv->RfReg0Value[eRFPath] &= 0xebf;
-
-			rtl8192_setBBreg(
-				dev,
-				pPhyReg->rf3wireOffset,
-				bMaskDWord,
-				(priv->RfReg0Value[eRFPath] << 16)	);
-		}
-
-		//analog to digital on
-		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8]
-	}
-
-	return retValue;
-}
-
-
-
-/**
-* Function:	phy_RFSerialWrite
-*
-* OverView:	Write data to RF register (page 8~)
-*
-* Input:
-*			PADAPTER		Adapter,
-*			RF90_RADIO_PATH_E	eRFPath,	//Radio path of A/B/C/D
-*			u32			Offset,		//The target address to be read
-*			u32			Data			//The new register Data in the target bit position
-*										//of the target to be read
-*
-* Output:	None
-* Return:		None
-* Note:		Threre are three types of serial operations:
-*			1. Software serial write
-*			2. Hardware LSSI-Low Speed Serial Interface
-*			3. Hardware HSSI-High speed
-*			serial write. Driver need to implement (1) and (2).
-*			This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
- *
- * Note: 		  For RF8256 only
- *			 The total count of RTL8256(Zebra4) register is around 36 bit it only employs
- *			 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
- *			 to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
- *			 programming guide" for more details.
- *			 Thus, we define a sub-finction for RTL8526 register address conversion
- *		       ===========================================================
- *			 Register Mode		RegCTL[1]		RegCTL[0]		Note
- *								(Reg00[12])		(Reg00[10])
- *		       ===========================================================
- *			 Reg_Mode0				0				x			Reg 0 ~15(0x0 ~ 0xf)
- *		       ------------------------------------------------------------------
- *			 Reg_Mode1				1				0			Reg 16 ~30(0x1 ~ 0xf)
- *		       ------------------------------------------------------------------
- *			 Reg_Mode2				1				1			Reg 31 ~ 45(0x1 ~ 0xf)
- *		       ------------------------------------------------------------------
-*/
-////use in phy only
-static void
-phy_RFSerialWrite(
-	struct net_device* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32				Offset,
-	u32				Data
-	)
-{
-	u32					DataAndAddr = 0;
-	struct r8192_priv 			*priv = ieee80211_priv(dev);
-	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];
-	u32					NewOffset;
-
-	Offset &= 0x3f;
-
-	// Shadow Update
-	PHY_RFShadowWrite(dev, eRFPath, Offset, Data);
-
-
-	// Switch page for 8256 RF IC
-	if( 	priv->rf_chip == RF_8256 ||
-		priv->rf_chip == RF_8225 ||
-		priv->rf_chip == RF_0222D)
-	{
-		//analog to digital off, for protection
-		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
-
-		if(Offset>=31)
-		{
-			priv->RFWritePageCnt[2]++;//cosa add for debug
-			priv->RfReg0Value[eRFPath] |= 0x140;
-
-			rtl8192_setBBreg(dev,
-				pPhyReg->rf3wireOffset,
-				bMaskDWord,
-				(priv->RfReg0Value[eRFPath] << 16)	);
-
-			NewOffset = Offset - 30;
-
-		}else if(Offset>=16)
-		{
-			priv->RFWritePageCnt[1]++;//cosa add for debug
-			priv->RfReg0Value[eRFPath] |= 0x100;
-			priv->RfReg0Value[eRFPath] &= (~0x40);
-
-
-			rtl8192_setBBreg(dev,
-				pPhyReg->rf3wireOffset,
-				bMaskDWord,
-				(priv->RfReg0Value[eRFPath] << 16)	);
-
-			NewOffset = Offset - 15;
-		}
-		else
-		{
-			priv->RFWritePageCnt[0]++;//cosa add for debug
-			NewOffset = Offset;
-	}
-	}
-	else
-		NewOffset = Offset;
-
-	//
-	// Put write addr in [5:0]  and write data in [31:16]
-	//
-	DataAndAddr = (Data<<16) | (NewOffset&0x3f);
-
-	//
-	// Write Operation
-	//
-	rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
-
-
-	if(Offset==0x0)
-		priv->RfReg0Value[eRFPath] = Data;
-
-	// Switch back to Reg_Mode0;
- 	if(	priv->rf_chip == RF_8256 ||
-		priv->rf_chip == RF_8225 ||
-		priv->rf_chip == RF_0222D)
-	{
-		if (Offset >= 0x10)
-		{
-			if(Offset != 0)
-			{
-				priv->RfReg0Value[eRFPath] &= 0xebf;
-				rtl8192_setBBreg(
-				dev,
-				pPhyReg->rf3wireOffset,
-				bMaskDWord,
-				(priv->RfReg0Value[eRFPath] << 16)	);
-			}
-		}
-		//analog to digital on
-		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8]
-	}
-
-}
-#else
-/**
-* Function:	phy_RFSerialRead
-*
-* OverView:	Read regster from RF chips
-*
-* Input:
-*			PADAPTER		Adapter,
-*			RF90_RADIO_PATH_E	eRFPath,	//Radio path of A/B/C/D
-*			u4Byte			Offset,		//The target address to be read
-*
-* Output:	None
-* Return:		u4Byte			reback value
-* Note:		Threre are three types of serial operations:
-*			1. Software serial write
-*			2. Hardware LSSI-Low Speed Serial Interface
-*			3. Hardware HSSI-High speed
-*			serial write. Driver need to implement (1) and (2).
-*			This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
-*/
-#if 0
-static	u32
-phy_RFSerialRead(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset)
-{
-
-	u32						retValue = 0;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];
-	u32						NewOffset;
-	//u32						value  = 0;
-	u32 						tmplong,tmplong2;
-	u32						RfPiEnable=0;
-#if 0
-	if(pHalData->RFChipID == RF_8225 && Offset > 0x24) //36 valid regs
-		return	retValue;
-	if(pHalData->RFChipID == RF_8256 && Offset > 0x2D) //45 valid regs
-		return	retValue;
-#endif
-	//
-	// Make sure RF register offset is correct
-	//
-	Offset &= 0x3f;
-
-	//
-	// Switch page for 8256 RF IC
-	//
-	NewOffset = Offset;
-
-	// For 92S LSSI Read RFLSSIRead
-	// For RF A/B write 0x824/82c(does not work in the future)
-	// We must use 0x824 for RF A and B to execute read trigger
-	tmplong = rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, bMaskDWord);
-	tmplong2 = rtl8192_QueryBBReg(dev, pPhyReg->rfHSSIPara2, bMaskDWord);
-	tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge;	//T65 RF
-
-	rtl8192_setBBreg(dev, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong&(~bLSSIReadEdge));
-	mdelay(1);
-
-	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bMaskDWord, tmplong2);
-	mdelay(1);
-
-	rtl8192_setBBreg(dev, rFPGA0_XA_HSSIParameter2, bMaskDWord, tmplong|bLSSIReadEdge);
-	mdelay(1);
-
-	if(eRFPath == RF90_PATH_A)
-		RfPiEnable = (u8)rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter1, BIT8);
-	else if(eRFPath == RF90_PATH_B)
-		RfPiEnable = (u8)rtl8192_QueryBBReg(dev, rFPGA0_XB_HSSIParameter1, BIT8);
-
-	if(RfPiEnable)
-	{	// Read from BBreg8b8, 12 bits for 8190, 20bits for T65 RF
-		retValue = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBackPi, bLSSIReadBackData);
-		//DbgPrint("Readback from RF-PI : 0x%x\n", retValue);
-	}
-	else
-	{	//Read from BBreg8a0, 12 bits for 8190, 20 bits for T65 RF
-		retValue = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
-		//DbgPrint("Readback from RF-SI : 0x%x\n", retValue);
-	}
-	//RTPRINT(FPHY, PHY_RFR, ("RFR-%d Addr[0x%x]=0x%x\n", eRFPath, pPhyReg->rfLSSIReadBack, retValue));
-
-	return retValue;
-
-}
-4
-
-
-/**
-* Function:	phy_RFSerialWrite
-*
-* OverView:	Write data to RF register (page 8~)
-*
-* Input:
-*			PADAPTER		Adapter,
-*			RF90_RADIO_PATH_E	eRFPath,	//Radio path of A/B/C/D
-*			u4Byte			Offset,		//The target address to be read
-*			u4Byte			Data			//The new register Data in the target bit position
-*										//of the target to be read
-*
-* Output:	None
-* Return:		None
-* Note:		Threre are three types of serial operations:
-*			1. Software serial write
-*			2. Hardware LSSI-Low Speed Serial Interface
-*			3. Hardware HSSI-High speed
-*			serial write. Driver need to implement (1) and (2).
-*			This function is equal to the combination of RF_ReadReg() and  RFLSSIRead()
- *
- * Note: 		  For RF8256 only
- *			 The total count of RTL8256(Zebra4) register is around 36 bit it only employs
- *			 4-bit RF address. RTL8256 uses "register mode control bit" (Reg00[12], Reg00[10])
- *			 to access register address bigger than 0xf. See "Appendix-4 in PHY Configuration
- *			 programming guide" for more details.
- *			 Thus, we define a sub-finction for RTL8526 register address conversion
- *		       ===========================================================
- *			 Register Mode		RegCTL[1]		RegCTL[0]		Note
- *								(Reg00[12])		(Reg00[10])
- *		       ===========================================================
- *			 Reg_Mode0				0				x			Reg 0 ~15(0x0 ~ 0xf)
- *		       ------------------------------------------------------------------
- *			 Reg_Mode1				1				0			Reg 16 ~30(0x1 ~ 0xf)
- *		       ------------------------------------------------------------------
- *			 Reg_Mode2				1				1			Reg 31 ~ 45(0x1 ~ 0xf)
- *		       ------------------------------------------------------------------
- *
- *	2008/09/02	MH	Add 92S RF definition
- *
- *
- *
-*/
-static	void
-phy_RFSerialWrite(struct net_device* dev,RF90_RADIO_PATH_E eRFPath,u32 Offset,u32	Data)
-{
-	u32						DataAndAddr = 0;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];
-	u32						NewOffset;
-
-#if 0
-	//<Roger_TODO> We should check valid regs for RF_6052 case.
-	if(pHalData->RFChipID == RF_8225 && Offset > 0x24) //36 valid regs
-		return;
-	if(pHalData->RFChipID == RF_8256 && Offset > 0x2D) //45 valid regs
-		return;
-#endif
-
-	Offset &= 0x3f;
-
-	//
-	// Shadow Update
-	//
-	PHY_RFShadowWrite(dev, eRFPath, Offset, Data);
-
-	//
-	// Switch page for 8256 RF IC
-	//
-		NewOffset = Offset;
-
-	//
-	// Put write addr in [5:0]  and write data in [31:16]
-	//
-	//DataAndAddr = (Data<<16) | (NewOffset&0x3f);
-	DataAndAddr = ((NewOffset<<20) | (Data&0x000fffff)) & 0x0fffffff;	// T65 RF
-
-	//
-	// Write Operation
-	//
-	rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
-	//RTPRINT(FPHY, PHY_RFW, ("RFW-%d Addr[0x%x]=0x%x\n", eRFPath, pPhyReg->rf3wireOffset, DataAndAddr));
-
-}
-#endif
-#endif
-
 /**
 * Function:	phy_CalculateBitShift
 *
@@ -1345,13 +676,7 @@ extern bool PHY_MACConfig8192S(struct net_device* dev)
 	//
 	// Config MAC
 	//
-#if RTL8190_Download_Firmware_From_Header
 	rtStatus = phy_ConfigMACWithHeaderFile(dev);
-#else
-	// Not make sure EEPROM, add later
-	RT_TRACE(COMP_INIT, "Read MACREG.txt\n");
-	//rtStatus = phy_ConfigMACWithParaFile(dev, RTL819X_PHY_MACREG);// lzm del it temp
-#endif
 	return (rtStatus == RT_STATUS_SUCCESS) ? true:false;
 
 }
@@ -1559,7 +884,6 @@ phy_BB8192S_Config_ParaFile(struct net_device* dev)
 	// 1. Read PHY_REG.TXT BB INIT!!
 	// We will seperate as 1T1R/1T2R/1T2R_GREEN/2T2R
 	//
-#if RTL8190_Download_Firmware_From_Header
 	if (priv->rf_type == RF_1T2R || priv->rf_type == RF_2T2R ||
 	    priv->rf_type == RF_1T1R ||priv->rf_type == RF_2T2R_GREEN)
 	{
@@ -1571,26 +895,6 @@ phy_BB8192S_Config_ParaFile(struct net_device* dev)
 		}
 	}else
 		rtStatus = RT_STATUS_FAILURE;
-#else
-	RT_TRACE(COMP_INIT, "RF_Type == %d\n", priv->rf_type);
-	// No matter what kind of RF we always read PHY_REG.txt. We must copy different
-	// type of parameter files to phy_reg.txt at first.
-	if (priv->rf_type == RF_1T2R || priv->rf_type == RF_2T2R ||
-	    priv->rf_type == RF_1T1R ||priv->rf_type == RF_2T2R_GREEN)
-	{
-		rtStatus = phy_ConfigBBWithParaFile(dev, (char* )&szBBRegFile);
-		if(priv->rf_type != RF_2T2R && priv->rf_type != RF_2T2R_GREEN)
-		{//2008.11.10 Added by tynli. The default PHY_REG.txt we read is for 2T2R,
-		  //so we should reconfig BB reg with the right PHY parameters.
-			if(priv->rf_type == RF_1T1R)
-				rtStatus = phy_SetBBtoDiffRFWithParaFile(dev, (char* )&szBBRegto1T1RFile);
-			else if(priv->rf_type == RF_1T2R)
-				rtStatus = phy_SetBBtoDiffRFWithParaFile(dev, (char* )&szBBRegto1T2RFile);
-		}
-
-	}else
-		rtStatus = RT_STATUS_FAILURE;
-#endif
 
 	if(rtStatus != RT_STATUS_SUCCESS){
 		RT_TRACE(COMP_INIT, "phy_BB8192S_Config_ParaFile():Write BB Reg Fail!!");
@@ -1602,11 +906,7 @@ phy_BB8192S_Config_ParaFile(struct net_device* dev)
 	//
 	if (priv->AutoloadFailFlag == false)
 	{
-#if	RTL8190_Download_Firmware_From_Header
 		rtStatus = phy_ConfigBBWithPgHeaderFile(dev,BaseBand_Config_PHY_REG);
-#else
-		rtStatus = phy_ConfigBBWithPgParaFile(dev, (char* )&szBBRegPgFile);
-#endif
 	}
 	if(rtStatus != RT_STATUS_SUCCESS){
 		RT_TRACE(COMP_INIT, "phy_BB8192S_Config_ParaFile():BB_PG Reg Fail!!");
@@ -1616,12 +916,7 @@ phy_BB8192S_Config_ParaFile(struct net_device* dev)
 	//
 	// 3. BB AGC table Initialization
 	//
-#if RTL8190_Download_Firmware_From_Header
 	rtStatus = phy_ConfigBBWithHeaderFile(dev,BaseBand_Config_AGC_TAB);
-#else
-	RT_TRACE(COMP_INIT, "phy_BB8192S_Config_ParaFile AGC_TAB.txt\n");
-	rtStatus = phy_ConfigBBWithParaFile(Adapter, (char* )&szAGCTableFile);
-#endif
 
 	if(rtStatus != RT_STATUS_SUCCESS){
 		printk( "phy_BB8192S_Config_ParaFile():AGC Table Fail\n");
@@ -1629,33 +924,6 @@ phy_BB8192S_Config_ParaFile(struct net_device* dev)
 	}
 
 
-#if 0	// 2008/08/18 MH Disable for 92SE
-	if(pHalData->VersionID > VERSION_8190_BD)
-	{
-		//if(pHalData->RF_Type == RF_2T4R)
-		//{
-		// Antenna gain offset from B/C/D to A
-		u4RegValue = (  pHalData->AntennaTxPwDiff[2]<<8 |
-						pHalData->AntennaTxPwDiff[1]<<4 |
-						pHalData->AntennaTxPwDiff[0]);
-		//}
-		//else
-		//u4RegValue = 0;
-
-		PHY_SetBBReg(dev, rFPGA0_TxGainStage,
-			(bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue);
-
-		// CrystalCap
-		// Simulate 8192???
-		u4RegValue = pHalData->CrystalCap;
-		PHY_SetBBReg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, u4RegValue);
-		// Simulate 8190??
-		//u4RegValue = ((pHalData->CrystalCap & 0xc)>>2);	// bit2~3 of crystal cap
-		//PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter2, bXtalCap23, u4RegValue);
-
-	}
-#endif
-
 	// Check if the CCK HighPower is turned ON.
 	// This is used to calculate PWDB.
 	priv->bCckHighPower = (bool)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
@@ -1934,11 +1202,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E
 				if(Rtl819XRadioA_Array_Table[i] == 0xfe)
 					{ // Deay specific ms. Only RF configuration require delay.
 //#if (DEV_BUS_TYPE == USB_INTERFACE)
-#ifdef RTL8192SU
 						mdelay(1000);
-#else
-						mdelay(50);
-#endif
 				}
 					else if (Rtl819XRadioA_Array_Table[i] == 0xfd)
 						mdelay(5);
@@ -1962,11 +1226,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E
 				if(Rtl819XRadioB_Array_Table[i] == 0xfe)
 					{ // Deay specific ms. Only RF configuration require delay.
 //#if (DEV_BUS_TYPE == USB_INTERFACE)
-#ifdef RTL8192SU
 						mdelay(1000);
-#else
-						mdelay(50);
-#endif
 				}
 					else if (Rtl819XRadioB_Array_Table[i] == 0xfd)
 						mdelay(5);
@@ -2435,29 +1695,6 @@ static bool phy_SetRFPowerState8192SU(struct net_device* dev,RT_RF_POWER_STATE e
 			case eRfOff:
 			  	if (priv->ieee80211->eRFPowerState == eRfSleep || priv->ieee80211->eRFPowerState == eRfOff)
 						break;
-#ifdef NOT_YET
-				// Make sure BusyQueue is empty befor turn off RFE pwoer.
-				for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
-				{
-					if(RTIsListEmpty(&Adapter->TcbBusyQueue[QueueID]))
-					{
-						QueueID++;
-						continue;
-					}
-					else
-					{
-						RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
-						udelay(10);
-						i++;
-					}
-
-					if(i >= MAX_DOZE_WAITING_TIMES_9x)
-					{
-						RT_TRACE(COMP_POWER, "\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
-						break;
-					}
-				}
-#endif
 				//
 				//RF Off/Sleep sequence. Designed/tested from SD4 Scott, SD1 Grent and Jonbon.
 				// Added by Bruce, 2008-11-22.
@@ -2641,10 +1878,6 @@ PHY_GetTxPowerLevel8192S(
 	//
 //	if(priv->epromtype == EPROM_93c46)
 	{
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-		powerlevel = priv->TxPowerLevelCCK[index];
-		powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[index];
-#else
 		//
 		// Mainly we use RF-A Tx Power to write the Tx Power registers, but the RF-B Tx
 		// Power must be calculated by the antenna diff.
@@ -2706,18 +1939,10 @@ PHY_GetTxPowerLevel8192S(
 				// Calculate Antenna pwr diff
 				if (pwrdiff[rfpath] < 8)	// 0~+7
 				{
-				#if 0//cosa, it doesn't need to add the offset here
-					if (rfpath == 0)
-						powerlevelOFDM24G += pwrdiff[rfpath];
-				#endif
 					ht20pwr[rfpath] += pwrdiff[rfpath];
 				}
 				else				// index8-15=-8~-1
 				{
-				#if 0//cosa, it doesn't need to add the offset here
-					if (rfpath == 0)
-						powerlevelOFDM24G -= (15-pwrdiff[rfpath]);
-				#endif
 					ht20pwr[rfpath] -= (15-pwrdiff[rfpath]);
 				}
 			}
@@ -2759,10 +1984,6 @@ PHY_GetTxPowerLevel8192S(
 
 					ht20pwr[rfpath] -= pwrdiff[rfpath];
 				}
-			#if 0//cosa, it doesn't need to add the offset here
-				if (rfpath == 0)
-					powerlevelOFDM24G -= pwrdiff[rfpath];
-			#endif
 			}
 
 			if (priv->rf_type == RF_2T2R)
@@ -2792,10 +2013,6 @@ PHY_GetTxPowerLevel8192S(
 				}
 			}
 		}
-#if 0//cosa, useless
-		// Read HT/Legacy OFDM diff
-		legacy_ant_pwr_diff= pHalData->TxPwrLegacyHtDiff[RF90_PATH_A][index];
-#endif
 		}
 
 	//Cosa added for protection, the reg rFPGA0_TxGainStage
@@ -2823,7 +2040,6 @@ PHY_GetTxPowerLevel8192S(
 
 		// Notify Tx power difference for B/C/D to A!!!
 		rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue);
-#endif
 	}
 
 	//
@@ -2885,10 +2101,6 @@ PHY_GetTxPowerLevel8192S(
 		break;
 
 		case RF_8256:
-#if 0
-			PHY_SetRF8256CCKTxPower(dev, powerlevel);
-			PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
-#endif
 			break;
 
 		case RF_6052:
@@ -3081,7 +2293,6 @@ PHY_ScanOperationBackup8192S(
 
 
 
-#if(RTL8192S_DISABLE_FW_DM == 0)
 
 	if(!Adapter->bDriverStopped)
 	{
@@ -3110,7 +2321,6 @@ PHY_ScanOperationBackup8192S(
 				break;
 		}
 	}
-#endif
 }
 #endif
 
@@ -3121,65 +2331,6 @@ void PHY_InitialGain8192S(struct net_device* dev,u8 Operation	)
 	//struct r8192_priv *priv = ieee80211_priv(dev);
 	//u32					BitMask;
 	//u8					initial_gain;
-
-#if 0	// For 8192s test disable
-	if(!dev->bDriverStopped)
-	{
-		switch(Operation)
-		{
-			case IG_Backup:
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("IG_Backup, backup the initial gain.\n"));
-				initial_gain = priv->DefaultInitialGain[0];
-				BitMask = bMaskByte0;
-				if(DM_DigTable.Dig_Algorithm == DIG_ALGO_BY_FALSE_ALARM)
-					PHY_SetMacReg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
-				pMgntInfo->InitGain_Backup.XAAGCCore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask);
-				pMgntInfo->InitGain_Backup.XBAGCCore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask);
-				pMgntInfo->InitGain_Backup.XCAGCCore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask);
-				pMgntInfo->InitGain_Backup.XDAGCCore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask);
-				BitMask  = bMaskByte2;
-				pMgntInfo->InitGain_Backup.CCA		= (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask);
-
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan InitialGainBackup 0xc50 is %x\n",pMgntInfo->InitGain_Backup.XAAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan InitialGainBackup 0xc58 is %x\n",pMgntInfo->InitGain_Backup.XBAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan InitialGainBackup 0xc60 is %x\n",pMgntInfo->InitGain_Backup.XCAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan InitialGainBackup 0xc68 is %x\n",pMgntInfo->InitGain_Backup.XDAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan InitialGainBackup 0xa0a is %x\n",pMgntInfo->InitGain_Backup.CCA));
-
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Write scan initial gain = 0x%x \n", initial_gain));
-				write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
-				write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
-				write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
-				write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
-				break;
-			case IG_Restore:
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("IG_Restore, restore the initial gain.\n"));
-				BitMask = 0x7f; //Bit0~ Bit6
-				if(DM_DigTable.Dig_Algorithm == DIG_ALGO_BY_FALSE_ALARM)
-					PHY_SetMacReg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
-
-				rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)pMgntInfo->InitGain_Backup.XAAGCCore1);
-				rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)pMgntInfo->InitGain_Backup.XBAGCCore1);
-				rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)pMgntInfo->InitGain_Backup.XCAGCCore1);
-				rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)pMgntInfo->InitGain_Backup.XDAGCCore1);
-				BitMask  = (BIT22|BIT23);
-				rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)pMgntInfo->InitGain_Backup.CCA);
-
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan BBInitialGainRestore 0xc50 is %x\n",pMgntInfo->InitGain_Backup.XAAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan BBInitialGainRestore 0xc58 is %x\n",pMgntInfo->InitGain_Backup.XBAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan BBInitialGainRestore 0xc60 is %x\n",pMgntInfo->InitGain_Backup.XCAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan BBInitialGainRestore 0xc68 is %x\n",pMgntInfo->InitGain_Backup.XDAGCCore1));
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Scan BBInitialGainRestore 0xa0a is %x\n",pMgntInfo->InitGain_Backup.CCA));
-
-				if(DM_DigTable.Dig_Algorithm == DIG_ALGO_BY_FALSE_ALARM)
-					PHY_SetMacReg(dev, UFWP, bMaskByte1, 0x1);	// FW DIG ON
-				break;
-			default:
-			RT_TRACE(COMP_SCAN, DBG_LOUD, ("Unknown IG Operation. \n"));
-				break;
-		}
-	}
-#endif
 }
 
 /*-----------------------------------------------------------------------------
@@ -3276,12 +2427,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
 			//write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000);
 			//write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317);
 			//write_nic_dword(dev, rCCK0_DebugPort, 0x00000204);
-			#if 0 //LZM 090219
-			rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskDWord, 0x1a1b0000);
-			rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, 0x090e1317);
-			rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskDWord, 0x00000204);
-			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00300000, 3);
-			#endif
 
 			if (priv->card_8192_version >= VERSION_8192S_BCUT)
 				write_nic_byte(dev, rFPGA0_AnalogParameter2, 0x58);
@@ -3298,11 +2443,6 @@ void PHY_SetBWModeCallback8192S(struct net_device *dev)
 			//write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000);
 			//write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e);
 			//write_nic_dword(dev, rCCK0_DebugPort, 0x00000409);
-			#if 0 //LZM 090219
-			rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskDWord, 0x35360000);
-			rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, 0x121c252e);
-			rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskDWord, 0x00000409);
-			#endif
 
 			// Set Control channel to upper or lower. These settings are required only for 40MHz
 			rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
@@ -3421,23 +2561,9 @@ void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EX
 	else
 		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
 
-#if 0
-	if(!priv->bDriverStopped)
-	{
-#ifdef USE_WORKITEM
-		PlatformScheduleWorkItem(&(priv->SetBWModeWorkItem));//SetBWModeCallback8192SUsbWorkItem
-#else
-		PlatformSetTimer(dev, &(priv->SetBWModeTimer), 0);//PHY_SetBWModeCallback8192S
-#endif
-	}
-#endif
 	if((priv->up) )// && !(RT_CANNOT_IO(Adapter) && Adapter->bInSetPower) )
 	{
-#ifdef RTL8192SE
-	PHY_SetBWModeCallback8192S(dev);
-#elif defined(RTL8192SU)
 	SetBWModeCallback8192SUsbWorkItem(dev);
-#endif
 	}
 	else
 	{
@@ -3552,11 +2678,7 @@ u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
 
 	if((priv->up))// && !(RT_CANNOT_IO(Adapter) && Adapter->bInSetPower))
 	{
-#ifdef RTL8192SE
-	PHY_SwChnlCallback8192S(dev);
-#elif defined(RTL8192SU)
 	SwChnlCallback8192SUsbWorkItem(dev);
-#endif
 #ifdef TO_DO_LIST
 	if(bResult)
 		{
@@ -3691,13 +2813,11 @@ phy_SwChnlStepByStep(
 	//RT_ASSERT(IsLegalChannel(dev, channel), ("illegal channel: %d\n", channel));
 	RT_TRACE(COMP_CH, "===========>%s(), channel:%d, stage:%d, step:%d\n", __FUNCTION__, channel, *stage, *step);
 	//RT_ASSERT((pHalData != NULL), ("pHalData should not be NULL\n"));
-#ifdef ENABLE_DOT11D
 	if (!IsLegalChannel(priv->ieee80211, channel))
 	{
 		RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
 		return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
 	}
-#endif
 
 	//pChnlAccessSetting = &Adapter->MgntInfo.Info8185.ChannelAccessSetting;
 	//RT_ASSERT((pChnlAccessSetting != NULL), ("pChnlAccessSetting should not be NULL\n"));
@@ -3809,13 +2929,9 @@ phy_SwChnlStepByStep(
 		case CmdID_RF_WriteReg:	// Only modify channel for the register now !!!!!
 			for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
 			{
-#if (defined RTL8192SE ||defined RTL8192SU )
 			// For new T65 RF 0222d register 0x18 bit 0-9 = channel number.
 				rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, 0x1f, (CurrentCmd->Para2));
 				//printk("====>%x, %x, read_back:%x\n", CurrentCmd->Para2,CurrentCmd->Para1, rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, 0x1f));
-#else
-				rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bRFRegOffsetMask, ((CurrentCmd->Para2)<<7));
-#endif
 			}
 			break;
                 default:
@@ -3881,16 +2997,6 @@ u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
 	bool				rtValue = TRUE;
 
 	// NOt check RF Path now.!
-#if 0
-	if (priv->rf_type == RF_1T2R && eRFPath != RF90_PATH_A)
-	{
-		rtValue = FALSE;
-	}
-	if (priv->rf_type == RF_1T2R && eRFPath != RF90_PATH_A)
-	{
-
-	}
-#endif
 	return	rtValue;
 
 }	/* PHY_CheckIsLegalRfPath8192S */
@@ -4283,7 +3389,6 @@ extern void PHY_IQCalibrateBcut(struct net_device* dev)
 //
 //-------------------------Move to other DIR later----------------------------*/
 //#if (DEV_BUS_TYPE == USB_INTERFACE)
-#ifdef RTL8192SU
 
 //    use in phy only (in win it's timer)
 void SwChnlCallback8192SUsb(struct net_device *dev)
@@ -4431,18 +3536,6 @@ void SetBWModeCallback8192SUsb(struct net_device *dev)
 		case HT_CHANNEL_WIDTH_20:
 			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
 			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
-			#if 0 //LZM090219
-			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00300000, 3);
-
-			// Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207
-			//write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000);
-			//write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317);
-			//write_nic_dword(dev, rCCK0_DebugPort, 0x00000204);
-			rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskDWord, 0x1a1b0000);
-			rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, 0x090e1317);
-			rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskDWord, 0x00000204);
-			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00300000, 3);
-			#endif
 
 			if (priv->card_8192_version >= VERSION_8192S_BCUT)
 				rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
@@ -4579,33 +3672,12 @@ void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
 			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
 			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
 
-			#if 0 //LZM 090219
-			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 1);
-
-			// Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207
-			rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskDWord, 0x1a1b0000);
-			rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, 0x090e1317);
-			rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskDWord, 0x00000204);
-			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
-			#endif
-
 			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0xff, 0x58);
 
 			break;
 		case HT_CHANNEL_WIDTH_20_40:
 			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
 			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
-			#if 0 //LZM 090219
-			rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
-
-			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bADClkPhase, 0);
-
-   			rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
-			// Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207
-			rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskDWord, 0x35360000);
-			rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, 0x121c252e);
-			rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskDWord, 0x00000409);
-			#endif
 
 			// Set Control channel to upper or lower. These settings are required only for 40MHz
 			rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
@@ -4660,7 +3732,6 @@ void SetBWModeCallback8192SUsbWorkItem(struct net_device *dev)
 }
 
 //--------------------------Move to oter DIR later-------------------------------*/
-#ifdef RTL8192SU
 void InitialGain8192S(struct net_device *dev,	u8 Operation)
 {
 #ifdef TO_DO_LIST
@@ -4668,7 +3739,6 @@ void InitialGain8192S(struct net_device *dev,	u8 Operation)
 #endif
 
 }
-#endif
 
 void InitialGain819xUsb(struct net_device *dev,	u8 Operation)
 {
@@ -4678,29 +3748,15 @@ void InitialGain819xUsb(struct net_device *dev,	u8 Operation)
 
 	if(priv->up)
 	{
-	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 		queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
-	#else
-		#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		schedule_task(&priv->initialgain_operate_wq);
-		#else
-		queue_work(priv->priv_wq,&priv->initialgain_operate_wq);
-		#endif
-	#endif
 	}
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
 {
 	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,initialgain_operate_wq);
        struct net_device *dev = priv->ieee80211->dev;
-#else
-extern void InitialGainOperateWorkItemCallBack(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
 #define SCAN_RX_INITIAL_GAIN	0x17
 #define POWER_DETECTION_TH	0x08
 	u32	BitMask;
@@ -4768,7 +3824,6 @@ extern void InitialGainOperateWorkItemCallBack(struct net_device *dev)
 	}
 }
 
-#endif	// #if (DEV_BUS_TYPE == USB_INTERFACE)
 
 //-----------------------------------------------------------------------------
 //	Description:
diff --git a/drivers/staging/rtl8192su/r8192S_phy.h b/drivers/staging/rtl8192su/r8192S_phy.h
index 580a7c6..b752fa3 100644
--- a/drivers/staging/rtl8192su/r8192S_phy.h
+++ b/drivers/staging/rtl8192su/r8192S_phy.h
@@ -121,11 +121,8 @@ extern	void 	PHY_IQCalibrateBcut(struct net_device* dev);
 extern	void 	PHY_IQCalibrate(struct net_device* dev);
 extern	void 	PHY_GetHWRegOriginalValue(struct net_device* dev);
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern void 	InitialGainOperateWorkItemCallBack(struct work_struct *work);
-#else
-extern void 	InitialGainOperateWorkItemCallBack(struct net_device *dev);
-#endif
+
 void PHY_SetTxPowerLevel8192S(struct net_device* dev, u8  channel);
 void PHY_InitialGain8192S(struct net_device* dev,u8 Operation   );
 
diff --git a/drivers/staging/rtl8192su/r8192S_rtl6052.c b/drivers/staging/rtl8192su/r8192S_rtl6052.c
index 71caf81..69ef6df 100644
--- a/drivers/staging/rtl8192su/r8192S_rtl6052.c
+++ b/drivers/staging/rtl8192su/r8192S_rtl6052.c
@@ -23,15 +23,9 @@
 #include "r8192U.h"
 #include "r8192S_rtl6052.h"
 
-#ifdef RTL8192SU
 #include "r8192S_hw.h"
 #include "r8192S_phyreg.h"
 #include "r8192S_phy.h"
-#else
-#include "r8192U_hw.h"
-#include "r819xU_phyreg.h"
-#include "r819xU_phy.h"
-#endif
 
 
 /*---------------------------Define Local Constant---------------------------*/
@@ -93,51 +87,6 @@ static	RF_SHADOW_T	RF_Shadow[RF6052_MAX_PATH][RF6052_MAX_REG];// = {{0}};//FIXLZ
  *---------------------------------------------------------------------------*/
 extern void RF_ChangeTxPath(struct net_device* dev,  u16 DataRate)
 {
-// We do not support gain table change inACUT now !!!! Delete later !!!
-#if 0//(RTL92SE_FPGA_VERIFY == 0)
-	static	u1Byte	RF_Path_Type = 2;	// 1 = 1T 2= 2T
-	static	u4Byte	tx_gain_tbl1[6]
-			= {0x17f50, 0x11f40, 0x0cf30, 0x08720, 0x04310, 0x00100};
-	static	u4Byte	tx_gain_tbl2[6]
-			= {0x15ea0, 0x10e90, 0x0c680, 0x08250, 0x04040, 0x00030};
-	u1Byte	i;
-
-	if (RF_Path_Type == 2 && (DataRate&0xF) <= 0x7)
-	{
-		// Set TX SYNC power G2G3 loop filter
-		PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-					RF_TXPA_G2, bMask20Bits, 0x0f000);
-		PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-					RF_TXPA_G3, bMask20Bits, 0xeacf1);
-
-		// Change TX AGC gain table
-		for (i = 0; i < 6; i++)
-			PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-						RF_TX_AGC, bMask20Bits, tx_gain_tbl1[i]);
-
-		// Set PA to high value
-		PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-					RF_TXPA_G2, bMask20Bits, 0x01e39);
-	}
-	else if (RF_Path_Type == 1 && (DataRate&0xF) >= 0x8)
-	{
-		// Set TX SYNC power G2G3 loop filter
-		PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-					RF_TXPA_G2, bMask20Bits, 0x04440);
-		PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-					RF_TXPA_G3, bMask20Bits, 0xea4f1);
-
-		// Change TX AGC gain table
-		for (i = 0; i < 6; i++)
-			PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-						RF_TX_AGC, bMask20Bits, tx_gain_tbl2[i]);
-
-		// Set PA low gain
-		PHY_SetRFReg(dev, (RF90_RADIO_PATH_E)RF90_PATH_A,
-					RF_TXPA_G2, bMask20Bits, 0x01e19);
-	}
-#endif
-
 }	/* RF_ChangeTxPath */
 
 
@@ -162,7 +111,6 @@ void PHY_RF6052SetBandwidth(struct net_device* dev, HT_CHANNEL_WIDTH Bandwidth)
 
 
 	//if (priv->card_8192 == NIC_8192SE)
-#ifdef RTL8192SU  //YJ,test,090113
 	{
 		switch(Bandwidth)
 		{
@@ -184,26 +132,6 @@ void PHY_RF6052SetBandwidth(struct net_device* dev, HT_CHANNEL_WIDTH Bandwidth)
 		}
 	}
 //	else
-#else
-	{
-	for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
-	{
-		switch(Bandwidth)
-		{
-			case HT_CHANNEL_WIDTH_20:
-					//PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, (BIT10|BIT11), 0x01);
-				break;
-			case HT_CHANNEL_WIDTH_20_40:
-					//PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A, RF_CHNLBW, (BIT10|BIT11), 0x00);
-				break;
-			default:
-					RT_TRACE(COMP_DBG, "PHY_SetRF8225Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
-				break;
-
-		}
-	}
-	}
-#endif
 }
 
 
@@ -306,15 +234,6 @@ extern void PHY_RF6052SetOFDMTxPower(struct net_device* dev, u8 powerlevel)
 		{
 			ofdm_bandedge_chnl_low = 1;
 			ofdm_bandedge_chnl_high = 11;
-		#if 0//cosa, Todo: check ofdm 40MHz, when lower and duplicate, the bandedge chnl low=3, high=9
-			if (pHalData->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
-			{	// Is it the same with the document?
-				if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
-				else if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER;
-				else
-				pHalData->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-			}
-		#endif
 			BandEdge_Pwrdiff = 0;
 			if (Channel <= ofdm_bandedge_chnl_low)
 				BandEdge_Pwrdiff = priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_A][0];
@@ -412,18 +331,6 @@ extern void PHY_RF6052SetOFDMTxPower(struct net_device* dev, u8 powerlevel)
 		//
 		if (priv->rf_type == RF_2T2R)
 		{
-		#if 0//cosa, we have only one AntennaTxPwDiff
-			// HT OFDM
-			if (index > 1)
-			{
-				rf_pwr_diff = pHalData->AntennaTxPwDiff[0];
-			}
-			// Legacy OFDM
-			else
-			{
-				rf_pwr_diff = pHalData->AntTxPwDiffLegacy[0];
-			}
-		#endif
 			rf_pwr_diff = priv->AntennaTxPwDiff[0];
 			//RTPRINT(FPHY, PHY_TXPWR, ("2T2R RF-B to RF-A PWR DIFF=%d\n", rf_pwr_diff));
 
@@ -684,21 +591,10 @@ RT_STATUS phy_RF6052_Config_ParaFile(struct net_device* dev)
 		switch(eRFPath)
 		{
 		case RF90_PATH_A:
-#if	RTL8190_Download_Firmware_From_Header
 			rtStatus= rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
-#else
-			rtStatus = PHY_ConfigRFWithParaFile(Adapter, (char* )&szRadioAFile, (RF90_RADIO_PATH_E)eRFPath);
-#endif
 			break;
 		case RF90_PATH_B:
-#if	RTL8190_Download_Firmware_From_Header
 			rtStatus= rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
-#else
-			if(priv->rf_type == RF_2T2R_GREEN)
-				rtStatus = PHY_ConfigRFWithParaFile(Adapter, (ps1Byte)&szRadioBGMFile, (RF90_RADIO_PATH_E)eRFPath);
-			else
-				rtStatus = PHY_ConfigRFWithParaFile(Adapter, (char* )&szRadioBFile, (RF90_RADIO_PATH_E)eRFPath);
-#endif
 			break;
 		case RF90_PATH_C:
 			break;
diff --git a/drivers/staging/rtl8192su/r8192S_rtl6052.h b/drivers/staging/rtl8192su/r8192S_rtl6052.h
index 916603c..3dcc9bb 100644
--- a/drivers/staging/rtl8192su/r8192S_rtl6052.h
+++ b/drivers/staging/rtl8192su/r8192S_rtl6052.h
@@ -81,53 +81,6 @@ extern	void		PHY_RF6052SetOFDMTxPower(struct net_device  * dev, u8 powerlevel);
 extern	RT_STATUS	PHY_RF6052_Config(struct net_device  * dev);
 extern void PHY_RFShadowRefresh( struct net_device  		* dev);
 extern void PHY_RFShadowWrite( struct net_device* dev, u32 eRFPath, u32 Offset, u32 Data);
-#if 0
-//
-// RF Shadow operation relative API
-//
-extern	u32
-PHY_RFShadowRead(
-	struct net_device  		* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32					Offset);
-extern void
-PHY_RFShadowCompare(
-	struct net_device  		* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32					Offset);
-extern void
-PHY_RFShadowRecorver(
-	struct net_device  		* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32					Offset);
-extern void
-PHY_RFShadowCompareAll(
-	struct net_device  		* dev);
-extern void
-PHY_RFShadowRecorverAll(
-	struct net_device  		* dev);
-extern void
-PHY_RFShadowCompareFlagSet(
-	struct net_device  		* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32					Offset,
-	u8					Type);
-extern void
-PHY_RFShadowRecorverFlagSet(
-	struct net_device  		* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32					Offset,
-	u8					Type);
-extern void
-PHY_RFShadowCompareFlagSetAll(
-	struct net_device  		* dev);
-extern void
-PHY_RFShadowRecorverFlagSetAll(
-	struct net_device  		* dev);
-extern void
-PHY_RFShadowRefresh(
-	struct net_device  		* dev);
-#endif
 /*--------------------------Exported Function prototype---------------------*/
 
 
diff --git a/drivers/staging/rtl8192su/r8192U.h b/drivers/staging/rtl8192su/r8192U.h
index a236558..2a11e01 100644
--- a/drivers/staging/rtl8192su/r8192U.h
+++ b/drivers/staging/rtl8192su/r8192U.h
@@ -39,16 +39,10 @@
 #include <linux/random.h>
 #include <linux/version.h>
 #include <asm/io.h>
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
-#include <asm/semaphore.h>
-#endif
-#include "ieee80211.h"
 
-#ifdef RTL8192SU
+#include "ieee80211/ieee80211.h"
+
 #include "r8192S_firmware.h"
-#else
-#include "r819xU_firmware.h"
-#endif
 
 //#define RTL8192U
 #define RTL819xU_MODULE_NAME "rtl819xU"
@@ -93,11 +87,6 @@
 
 // Rx smooth factor
 #define	Rx_Smooth_Factor		20
-#if 0 //we need to use RT_TRACE instead DMESG as RT_TRACE will clearly show debug level wb.
-#define DMESG(x,a...) printk(KERN_INFO RTL819xU_MODULE_NAME ": " x "\n", ## a)
-#define DMESGW(x,a...) printk(KERN_WARNING RTL819xU_MODULE_NAME ": WW:" x "\n", ## a)
-#define DMESGE(x,a...) printk(KERN_WARNING RTL819xU_MODULE_NAME ": EE:" x "\n", ## a)
-#else
 #define DMESG(x,a...)
 #define DMESGW(x,a...)
 #define DMESGE(x,a...)
@@ -155,7 +144,6 @@ do { if(rt_global_debug_component & component) \
 #define COMP_DOWN				BIT29  //for rm driver module
 #define COMP_RESET				BIT30  //for silent reset
 #define COMP_ERR				BIT31 //for error out, always on
-#endif
 
 #define RTL819x_DEBUG
 #ifdef RTL819x_DEBUG
@@ -307,7 +295,6 @@ do { if(rt_global_debug_component & component) \
 #define 	OFDM_Table_Length	19
 #define	CCK_Table_length	12
 
-#ifdef RTL8192SU
 //
 //Tx Descriptor for RLT8192SU(Normal mode)
 //
@@ -425,75 +412,9 @@ typedef struct _tx_status_desc_8192s_usb{
 	u8		RxAGC3;
 	u8		RxAGC4;
 }tx_status_desc_8192s_usb, *ptx_status_desc_8192s_usb;
-#else
-/* for rtl819x */
-typedef struct _tx_desc_819x_usb {
-        //DWORD 0
-        u16	PktSize;
-        u8	Offset;
-        u8	Reserved0:3;
-        u8	CmdInit:1;
-        u8	LastSeg:1;
-        u8	FirstSeg:1;
-        u8	LINIP:1;
-        u8	OWN:1;
-
-        //DWORD 1
-        u8	TxFWInfoSize;
-        u8	RATid:3;
-        u8	DISFB:1;
-        u8	USERATE:1;
-        u8	MOREFRAG:1;
-        u8	NoEnc:1;
-        u8	PIFS:1;
-        u8	QueueSelect:5;
-        u8	NoACM:1;
-        u8	Reserved1:2;
-        u8	SecCAMID:5;
-        u8	SecDescAssign:1;
-        u8	SecType:2;
-
-        //DWORD 2
-        u16	TxBufferSize;
-        //u16 Reserved2;
-        u8	ResvForPaddingLen:7;
-        u8	Reserved3:1;
-        u8	Reserved4;
-
-        //DWORD 3, 4, 5
-        u32	Reserved5;
-        u32	Reserved6;
-        u32	Reserved7;
-}tx_desc_819x_usb, *ptx_desc_819x_usb;
-#endif
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-typedef struct _tx_desc_819x_usb_aggr_subframe {
-	//DWORD 0
-	u16	PktSize;
-	u8	Offset;
-	u8	TxFWInfoSize;
-
-	//DWORD 1
-	u8	RATid:3;
-	u8	DISFB:1;
-	u8	USERATE:1;
-	u8	MOREFRAG:1;
-	u8	NoEnc:1;
-	u8	PIFS:1;
-	u8	QueueSelect:5;
-	u8	NoACM:1;
-	u8	Reserved1:2;
-	u8	SecCAMID:5;
-	u8	SecDescAssign:1;
-	u8	SecType:2;
-	u8	PacketID:7;
-	u8	OWN:1;
-}tx_desc_819x_usb_aggr_subframe, *ptx_desc_819x_usb_aggr_subframe;
-#endif
 
 
-#ifdef RTL8192SU
 //
 //Tx Descriptor for RLT8192SU(Load FW mode)
 //
@@ -558,39 +479,7 @@ typedef struct _tx_h2c_cmd_hdr_8192s_usb{
 	// DWORD 1
 	u32		Rsvd0;
 }tx_h2c_cmd_hdr_8192s_usb, *ptx_h2c_cmd_hdr_8192s_usb;
-#else
-typedef struct _tx_desc_cmd_819x_usb {
-        //DWORD 0
-	u16	Reserved0;
-	u8	Reserved1;
-	u8	Reserved2:3;
-	u8	CmdInit:1;
-	u8	LastSeg:1;
-	u8	FirstSeg:1;
-	u8	LINIP:1;
-	u8	OWN:1;
-
-        //DOWRD 1
-	//u32	Reserved3;
-	u8	TxFWInfoSize;
-	u8	Reserved3;
-	u8	QueueSelect;
-	u8	Reserved4;
-
-        //DOWRD 2
-	u16 	TxBufferSize;
-	u16	Reserved5;
-
-       //DWORD 3,4,5
-	//u32	TxBufferAddr;
-	//u32	NextDescAddress;
-	u32	Reserved6;
-	u32	Reserved7;
-	u32	Reserved8;
-}tx_desc_cmd_819x_usb, *ptx_desc_cmd_819x_usb;
-#endif
 
-#ifdef RTL8192SU
 typedef struct _tx_fwinfo_819x_usb{
 	//DWORD 0
 	u8			TxRate:7;
@@ -619,38 +508,6 @@ typedef struct _tx_fwinfo_819x_usb{
 	u32			Tx_INFO_RSVD:6;
 	u32			PacketID:13;
 }tx_fwinfo_819x_usb, *ptx_fwinfo_819x_usb;
-#else
-typedef struct _tx_fwinfo_819x_usb {
-        //DOWRD 0
-        u8		TxRate:7;
-        u8		CtsEnable:1;
-        u8		RtsRate:7;
-        u8		RtsEnable:1;
-        u8		TxHT:1;
-        u8		Short:1;                //Short PLCP for CCK, or short GI for 11n MCS
-        u8		TxBandwidth:1;          // This is used for HT MCS rate only.
-        u8		TxSubCarrier:2;         // This is used for legacy OFDM rate only.
-        u8		STBC:2;
-        u8		AllowAggregation:1;
-        u8		RtsHT:1;                //Interpre RtsRate field as high throughput data rate
-        u8		RtsShort:1;             //Short PLCP for CCK, or short GI for 11n MCS
-        u8		RtsBandwidth:1;         // This is used for HT MCS rate only.
-        u8		RtsSubcarrier:2;        // This is used for legacy OFDM rate only.
-        u8		RtsSTBC:2;
-        u8		EnableCPUDur:1;         //Enable firmware to recalculate and assign packet duration
-
-        //DWORD 1
-        u32		RxMF:2;
-        u32		RxAMD:3;
-        u32		TxPerPktInfoFeedback:1;//1 indicate Tx info gathtered by firmware and returned by Rx Cmd
-        u32		Reserved1:2;
-        u32		TxAGCOffSet:4;
-        u32		TxAGCSign:1;
-        u32		Tx_INFO_RSVD:6;
-	u32		PacketID:13;
-        //u32                Reserved;
-}tx_fwinfo_819x_usb, *ptx_fwinfo_819x_usb;
-#endif
 
 typedef struct rtl8192_rx_info {
 	struct urb *urb;
@@ -658,7 +515,6 @@ typedef struct rtl8192_rx_info {
 	u8 out_pipe;
 }rtl8192_rx_info ;
 
-#ifdef RTL8192SU
 //typedef struct _RX_DESC_STATUS_8192SU{
 typedef struct rx_desc_819x_usb{
 	//DWORD 0
@@ -695,11 +551,7 @@ typedef struct rx_desc_819x_usb{
 	//DWORD 2
 	u16		Seq:12;
 	u16		Frag:4;
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	u8		UsbAggPktNum;//:8;
-#else
 	u8		NextPktLen;//:8;
-#endif
 	u8		Rsvd0:6;
 	u8		NextIND:1;
 	u8		Rsvd1:1;
@@ -725,57 +577,8 @@ typedef struct rx_desc_819x_usb{
 	u32		TSFL;
 //}RX_DESC_STATUS_8192SU, *PRX_DESC_STATUS_8192SU;
 }rx_desc_819x_usb, *prx_desc_819x_usb;
-#else
-typedef struct rx_desc_819x_usb{
-	//DOWRD 0
-	u16                 Length:14;
-	u16                 CRC32:1;
-	u16                 ICV:1;
-	u8                  RxDrvInfoSize;
-	u8                  Shift:2;
-	u8                  PHYStatus:1;
-	u8                  SWDec:1;
-	//u8                LastSeg:1;
-	//u8                FirstSeg:1;
-	//u8                EOR:1;
-	//u8                OWN:1;
-	u8                  Reserved1:4;
-
-	//DWORD 1
-	u32                 Reserved2;
-
-	//DWORD 2
-	//u32               Reserved3;
-
-	//DWORD 3
-	//u32                BufferAddress;
-
-}rx_desc_819x_usb, *prx_desc_819x_usb;
-#endif
 
-#ifdef USB_RX_AGGREGATION_SUPPORT
-typedef struct _rx_desc_819x_usb_aggr_subframe{
-	//DOWRD 0
-	u16			Length:14;
-	u16			CRC32:1;
-	u16			ICV:1;
-	u8			Offset;
-	u8			RxDrvInfoSize;
-	//DOWRD 1
-	u8			Shift:2;
-	u8			PHYStatus:1;
-	u8			SWDec:1;
-	u8			Reserved1:4;
-	u8			Reserved2;
-	u16			Reserved3;
-	//DWORD 2
-	//u4Byte		Reserved3;
-	//DWORD 3
-	//u4Byte           	BufferAddress;
-}rx_desc_819x_usb_aggr_subframe, *prx_desc_819x_usb_aggr_subframe;
-#endif
 
-#ifdef RTL8192SU
 //
 // Driver info are written to the begining of the RxBuffer
 //
@@ -851,41 +654,11 @@ typedef struct rx_drvinfo_819x_usb{
 	u8			reserve:4;
 
 }rx_drvinfo_819x_usb, *prx_drvinfo_819x_usb;
-#else
-typedef struct rx_drvinfo_819x_usb{
-	//DWORD 0
-	u16                 Reserved1:12;
-	u16                 PartAggr:1;
-	u16                 FirstAGGR:1;
-	u16                 Reserved2:2;
-
-	u8                  RxRate:7;
-	u8                  RxHT:1;
-
-	u8                  BW:1;
-	u8                  SPLCP:1;
-	u8                  Reserved3:2;
-	u8                  PAM:1;
-	u8                  Mcast:1;
-	u8                  Bcast:1;
-	u8                  Reserved4:1;
-
-	//DWORD 1
-	u32                  TSFL;
-
-}rx_drvinfo_819x_usb, *prx_drvinfo_819x_usb;
-#endif
 
 	#define HWSET_MAX_SIZE_92S	128
-#ifdef RTL8192SU
 	#define MAX_802_11_HEADER_LENGTH 40
 	#define MAX_PKT_AGG_NUM		256
 	#define TX_PACKET_SHIFT_BYTES USB_HWDESC_HEADER_LEN
-#else
-	#define MAX_802_11_HEADER_LENGTH        (40 + MAX_FIRMWARE_INFORMATION_SIZE)
-	#define	MAX_PKT_AGG_NUM		64
-	#define TX_PACKET_SHIFT_BYTES (USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb))
-#endif
 
 #define MAX_DEV_ADDR_SIZE		8  /* support till 64 bit bus width OS */
 #define MAX_FIRMWARE_INFORMATION_SIZE   32 /*2006/04/30 by Emily forRTL8190*/
@@ -895,17 +668,10 @@ typedef struct rx_drvinfo_819x_usb{
 //#define TX_PACKET_SHIFT_BYTES 	  	(USB_HWDESC_HEADER_LEN + sizeof(tx_fwinfo_819x_usb))
 #define MAX_FRAGMENT_COUNT		8
 #ifdef RTL8192U
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-#define MAX_TRANSMIT_BUFFER_SIZE			32000
-#else
 #define MAX_TRANSMIT_BUFFER_SIZE			8000
-#endif
 #else
 #define MAX_TRANSMIT_BUFFER_SIZE  	(1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT)
 #endif
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-#define TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES (sizeof(tx_desc_819x_usb_aggr_subframe) + sizeof(tx_fwinfo_819x_usb))
-#endif
 #define scrclng					4		// octets for crc32 (FCS, ICV)
 
 typedef enum rf_optype
@@ -939,146 +705,6 @@ typedef enum _RTL8192SUSB_LOOPBACK{
 }RTL8192SUSB_LOOPBACK_E;
 //#endif
 
-
-#if 0
-/* due to rtl8192 firmware */
-typedef enum _desc_packet_type_e{
-	DESC_PACKET_TYPE_INIT = 0,
-	DESC_PACKET_TYPE_NORMAL = 1,
-}desc_packet_type_e;
-
-typedef enum _firmware_source{
-	FW_SOURCE_IMG_FILE = 0,
-	FW_SOURCE_HEADER_FILE = 1,		//from header file
-}firmware_source_e, *pfirmware_source_e;
-
-typedef enum _firmware_status{
-	FW_STATUS_0_INIT = 0,
-	FW_STATUS_1_MOVE_BOOT_CODE = 1,
-	FW_STATUS_2_MOVE_MAIN_CODE = 2,
-	FW_STATUS_3_TURNON_CPU = 3,
-	FW_STATUS_4_MOVE_DATA_CODE = 4,
-	FW_STATUS_5_READY = 5,
-}firmware_status_e;
-
-typedef struct _rt_firmare_seg_container {
-	u16	seg_size;
-	u8	*seg_ptr;
-}fw_seg_container, *pfw_seg_container;
-
-#ifdef RTL8192SU
-//--------------------------------------------------------------------------------
-// 8192S Firmware related
-//--------------------------------------------------------------------------------
-typedef  struct _RT_8192S_FIRMWARE_PRIV { //8-bytes alignment required
-
-	//--- LONG WORD 0 ----
-	u32		RegulatoryClass;
-	u32		Rfintfs;
-
-	//--- LONG WORD 1 ----
-	u32		ChipVer;
-	u32		HCISel;
-
-	//--- LONG WORD 2 ----
-	u32		IBKMode;
-	u32		Rsvd00;
-
-	//--- LONG WORD 3 ----
-	u32		Rsvd01;
-	u8		Qos_En;			// QoS enable
-	u8		En40MHz;		// 40MHz BW enable
-	u8		AMSDU2AMPDU_En;	//14181 convert AMSDU to AMPDU, 0: disable
-	u8		AMPDU_En;		//111n AMPDU/AMSDU enable
-
-	//--- LONG WORD 4 ----
-	u8		rate_control_offload;//FW offloads, 0: driver handles
-	u8		aggregation_offload;	// FW offloads, 0: driver handles
-	u8		beacon_offload;	//FW offloads, 0: driver handles
-	u8		MLME_offload;	// FW offloads, 0: driver handles
-	u8		hwpc_offload;	// FW offloads, 0: driver handles
-	u8		tcp_checksum_offload;	//FW offloads, 0: driver handles
-	u8		tcp_offload;			//FW offloads, 0: driver handles
-	u8		ps_control_offload;	//FW offloads, 0: driver handles
-
-	//--- LONG WORD 5 ----
-	u8		WWLAN_Offload;	// FW offloads, 0: driver handles
-	u8		MPMode;	// normal mode, 0: MP mode;
-	u16		Version;		//0x8000 ~ 0x8FFF for FPGA version, 0x0000 ~ 0x7FFF for ASIC version,
-	u16		Signature;	//0x12: 8712, 0x92: 8192S
-	u16		Rsvd11;
-
-//	u32		rsvd1;
-//	u32		wireless_band;	//no A-band exists in 8712
-}RT_8192S_FIRMWARE_PRIV, *PRT_8192S_FIRMWARE_PRIV;
-
-typedef struct _RT_8192S_FIRMWARE_HDR {//8-byte alinment required
-
-	//--- LONG WORD 0 ----
-	u16		Signature;
-	u16		Version;		  //0x8000 ~ 0x8FFF for FPGA version, 0x0000 ~ 0x7FFF for ASIC version,
-	u32		DMEMSize;    //define the size of boot loader
-
-
-	//--- LONG WORD 1 ----
-	u32		IMG_IMEM_SIZE;    //define the size of FW in IMEM
-	u32		IMG_SRAM_SIZE;    //define the size of FW in SRAM
-
-	//--- LONG WORD 2 ----
-	u32		FW_PRIV_SIZE;       //define the size of DMEM variable
-	u32		Rsvd0;
-
-	//--- LONG WORD 3 ----
-	u32		Rsvd1;
-	u32		Rsvd2;
-
-	RT_8192S_FIRMWARE_PRIV	FWPriv;
-
-}RT_8192S_FIRMWARE_HDR, *PRT_8192S_FIRMWARE_HDR;
-
-#define	RT_8192S_FIRMWARE_HDR_SIZE	80
-
-typedef enum _FIRMWARE_8192S_STATUS{
-	FW_STATUS_INIT = 0,
-	FW_STATUS_LOAD_IMEM = 1,
-	FW_STATUS_LOAD_EMEM = 2,
-	FW_STATUS_LOAD_DMEM = 3,
-	FW_STATUS_READY = 4,
-}FIRMWARE_8192S_STATUS;
-
-#define RTL8190_MAX_FIRMWARE_CODE_SIZE  64000   //64k
-
-typedef struct _rt_firmware{
-	firmware_source_e	eFWSource;
-	PRT_8192S_FIRMWARE_HDR		pFwHeader;
-	FIRMWARE_8192S_STATUS	FWStatus;
-	u8		FwIMEM[64000];
-	u8		FwEMEM[64000];
-	u32		FwIMEMLen;
-	u32		FwEMEMLen;
-	u8		szFwTmpBuffer[164000];
-	u16		CmdPacketFragThresold;
-	//firmware_status_e       firmware_status;//in 92u temp FIXLZM
-	//u16               cmdpacket_frag_thresold;//in 92u temp FIXLZM
-	//u8                firmware_buf[RTL8190_MAX_FIRMWARE_CODE_SIZE];//in 92u temp FIXLZM
-	//u16               firmware_buf_size;//in 92u temp FIXLZM
-
-}rt_firmware, *prt_firmware;
-#else
-typedef struct _rt_firmware{
-	firmware_status_e firmware_status;
-	u16               cmdpacket_frag_thresold;
-#define RTL8190_MAX_FIRMWARE_CODE_SIZE  64000   //64k
-#define MAX_FW_INIT_STEP                3
-	u8                firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE];
-	u16               firmware_buf_size[MAX_FW_INIT_STEP];
-}rt_firmware, *prt_firmware;
-#endif
-typedef struct _rt_firmware_info_819xUsb{
-	u8		sz_info[16];
-}rt_firmware_info_819xUsb, *prt_firmware_info_819xUsb;
-#endif
-
 //+by amy 080507
 #define MAX_RECEIVE_BUFFER_SIZE	9100	// Add this to 9100 bytes to receive A-MSDU from RT-AP
 
@@ -1087,18 +713,6 @@ typedef struct _rt_firmware_info_819xUsb{
 #define NUM_OF_FIRMWARE_QUEUE		10
 #define NUM_OF_PAGES_IN_FW		0x100
 
-#ifdef USE_ONE_PIPE
-#define NUM_OF_PAGE_IN_FW_QUEUE_BE	0x000
-#define NUM_OF_PAGE_IN_FW_QUEUE_BK	0x000
-#define NUM_OF_PAGE_IN_FW_QUEUE_VI	0x0ff
-#define NUM_OF_PAGE_IN_FW_QUEUE_VO	0x000
-#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA	0
-#define NUM_OF_PAGE_IN_FW_QUEUE_CMD	0x0
-#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT	0x00
-#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH	0
-#define NUM_OF_PAGE_IN_FW_QUEUE_BCN	0x0
-#define NUM_OF_PAGE_IN_FW_QUEUE_PUB	0x00
-#else
 
 #define NUM_OF_PAGE_IN_FW_QUEUE_BE	0x020
 #define NUM_OF_PAGE_IN_FW_QUEUE_BK	0x020
@@ -1111,7 +725,6 @@ typedef struct _rt_firmware_info_819xUsb{
 #define NUM_OF_PAGE_IN_FW_QUEUE_BCN	0x4
 #define NUM_OF_PAGE_IN_FW_QUEUE_PUB	0x18
 
-#endif
 
 #define APPLIED_RESERVED_QUEUE_IN_FW	0x80000000
 #define RSVD_FW_QUEUE_PAGE_BK_SHIFT	0x00
@@ -1172,21 +785,6 @@ typedef struct rtl_reg_debug{
         unsigned char buf[0xff];
 }rtl_reg_debug;
 
-
-
-
-
-#if 0
-
-typedef struct tx_pendingbuf
-{
-	struct ieee80211_txb *txb;
-	short ispending;
-	short descfrag;
-} tx_pendigbuf;
-
-#endif
-
 typedef struct _rt_9x_tx_rate_history {
 	u32             cck[4];
 	u32             ofdm[8];
@@ -1555,11 +1153,7 @@ typedef struct r8192_priv
 //	spinlock_t irq_th_lock;
 	spinlock_t tx_lock;
 	spinlock_t ps_lock;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
-	struct semaphore mutex;
-#else
         struct mutex mutex;
-#endif
 	spinlock_t rf_lock; //used to lock rf write operation added by wb
 
 	u16 irq_mask;
@@ -1619,11 +1213,9 @@ typedef struct r8192_priv
 /* modified by davad for Rx process */
        struct sk_buff_head rx_queue;
        struct sk_buff_head skb_queue;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-	struct tq_struct qos_activate;
-#else
+
        struct work_struct qos_activate;
-#endif
+
 	short  tx_urb_index;
 	atomic_t tx_pending[0x10];//UART_PRIORITY+1
 
@@ -1653,11 +1245,8 @@ typedef struct r8192_priv
 	u16 rts;
 
 	struct 	ChnlAccessSetting  ChannelAccessSetting;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+
 	struct work_struct reset_wq;
-#else
-	struct tq_struct reset_wq;
-#endif
 
 /**********************************************************/
 	//for rtl819xUsb
@@ -1686,11 +1275,6 @@ typedef struct r8192_priv
 	bool	bDmDisableProtect;
 	bool	bIgnoreDiffRateTxPowerOffset;
 
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-	u8  EEPROMTxPowerLevelCCK24G[14];		// CCK 2.4G channel 1~14
-	//u8  EEPROMTxPowerLevelOFDM24G[14];	// OFDM 2.4G channel 1~14
-	//u8  EEPROMTxPowerLevelOFDM5G[24];	// OFDM 5G
-#else
 	// For EEPROM TX Power Index like 8190 series
 	u8  EEPROMRfACCKChnl1TxPwLevel[3];	//RF-A CCK Tx Power Level at channel 7
 	u8  EEPROMRfAOfdmChnlTxPwLevel[3];//RF-A CCK Tx Power Level at [0],[1],[2] = channel 1,7,13
@@ -1702,7 +1286,6 @@ typedef struct r8192_priv
 	u8  RfCckChnlAreaTxPwr[2][3];
 	u8  RfOfdmChnlAreaTxPwr1T[2][3];
 	u8  RfOfdmChnlAreaTxPwr2T[2][3];
-#endif
 
 	// Add For EEPROM Efuse switch and  Efuse Shadow map Setting
 	bool		EepromOrEfuse;
@@ -1745,11 +1328,7 @@ typedef struct r8192_priv
 /*PHY related*/
 	BB_REGISTER_DEFINITION_T	PHYRegDef[4];	//Radio A/B/C/D
 	// Read/write are allow for following hardware information variables
-#ifdef RTL8192SU
 	u32	MCSTxPowerLevelOriginalOffset[7];//FIXLZM
-#else
-	u32	MCSTxPowerLevelOriginalOffset[6];
-#endif
 	u32	CCKTxPowerLevelOriginalOffset;
 	u8	TxPowerLevelCCK[14];			// CCK channel 1~14
 	u8	TxPowerLevelOFDM24G[14];		// OFDM 2.4G channel 1~14
@@ -1874,33 +1453,14 @@ typedef struct r8192_priv
 	u16		SifsTime;
 
 	//define work item by amy 080526
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 	struct delayed_work update_beacon_wq;
 	struct delayed_work watch_dog_wq;
 	struct delayed_work txpower_tracking_wq;
 	struct delayed_work rfpath_check_wq;
 	struct delayed_work gpio_change_rf_wq;
 	struct delayed_work initialgain_operate_wq;
-#else
-	struct work_struct update_beacon_wq;
-	struct work_struct watch_dog_wq;
-	struct work_struct txpower_tracking_wq;
-	struct work_struct rfpath_check_wq;
-	struct work_struct gpio_change_rf_wq;
-	struct work_struct initialgain_operate_wq;
-#endif
+
 	struct workqueue_struct *priv_wq;
-#else
-	/* used for periodly scan */
-	struct tq_struct update_beacon_wq;
-	struct tq_struct txpower_tracking_wq;
-	struct tq_struct rfpath_check_wq;
-	struct tq_struct watch_dog_wq;
-	struct tq_struct gpio_change_rf_wq;
-	struct tq_struct initialgain_operate_wq;
-#endif
 //#ifdef RTL8192SU
 	//lzm add for 8192S
 	 u32 			IntrMask;
@@ -1945,13 +1505,6 @@ typedef struct r8192_priv
 //#endif
 
 
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	bool		bCurrentRxAggrEnable;
-	bool		bForcedUsbRxAggr;
-	u32		ForcedUsbRxAggrInfo;
-	u32		LastUsbRxAggrInfoSetting;
-	u32		RegUsbRxAggrInfo;
-#endif
 
 
 
@@ -1986,70 +1539,6 @@ typedef enum{
 	UART_PRIORITY //0x0F
 } priority_t;
 
-#if 0
-typedef enum{
-	NIC_8192U = 1,
-	NIC_8190P = 2,
-	NIC_8192E = 3,
-	NIC_8192SE = 4,
-	NIC_8192SU = 5,
-	} nic_t;
-#endif
-
-#if 0 //defined in Qos.h
-//typedef u32 AC_CODING;
-#define AC0_BE	0		// ACI: 0x00	// Best Effort
-#define AC1_BK	1		// ACI: 0x01	// Background
-#define AC2_VI	2		// ACI: 0x10	// Video
-#define AC3_VO	3		// ACI: 0x11	// Voice
-#define AC_MAX	4		// Max: define total number; Should not to be used as a real enum.
-
-//
-// ECWmin/ECWmax field.
-// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
-//
-typedef	union _ECW{
-	u8	charData;
-	struct
-	{
-		u8	ECWmin:4;
-		u8	ECWmax:4;
-	}f;	// Field
-}ECW, *PECW;
-
-//
-// ACI/AIFSN Field.
-// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
-//
-typedef	union _ACI_AIFSN{
-	u8	charData;
-
-	struct
-	{
-		u8	AIFSN:4;
-		u8	ACM:1;
-		u8	ACI:2;
-		u8	Reserved:1;
-	}f;	// Field
-}ACI_AIFSN, *PACI_AIFSN;
-
-//
-// AC Parameters Record Format.
-// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
-//
-typedef	union _AC_PARAM{
-	u32	longData;
-	u8	charData[4];
-
-	struct
-	{
-		ACI_AIFSN	AciAifsn;
-		ECW		Ecw;
-		u16		TXOPLimit;
-	}f;	// Field
-}AC_PARAM, *PAC_PARAM;
-
-#endif
 #ifdef JOHN_HWSEC
 struct ssid_thread {
 	struct net_device *dev;
@@ -2057,14 +1546,9 @@ struct ssid_thread {
 };
 #endif
 
-#ifdef RTL8192SU
 short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
 short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
 bool FirmwareDownload92S(struct net_device *dev);
-#else
-short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
-bool init_firmware(struct net_device *dev);
-#endif
 
 short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
 short rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c
index 70f81a8..66274d7 100644
--- a/drivers/staging/rtl8192su/r8192U_core.c
+++ b/drivers/staging/rtl8192su/r8192U_core.c
@@ -24,14 +24,7 @@
  * Jerry chuang <wlanfae@realtek.com>
  */
 
-#ifndef CONFIG_FORCE_HARD_FLOAT
-double __floatsidf (int i) { return i; }
-unsigned int __fixunsdfsi (double d) { return d; }
-double __adddf3(double a, double b) { return a+b; }
-double __addsf3(float a, float b) { return a+b; }
-double __subdf3(double a, double b) { return a-b; }
-double __extendsfdf2(float a) {return a;}
-#endif
+#include <linux/vmalloc.h>
 
 #undef LOOP_TEST
 #undef DUMP_RX
@@ -58,10 +51,8 @@ double __extendsfdf2(float a) {return a;}
 
 #define CONFIG_RTL8192_IO_MAP
 
-#ifdef RTL8192SU
 #include <asm/uaccess.h>
 #include "r8192U.h"
-//#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
 #include "r8180_93cx6.h"   /* Card EEPROM */
 #include "r8192U_wx.h"
 
@@ -75,50 +66,13 @@ double __extendsfdf2(float a) {return a;}
 #include "r8192U_dm.h"
 //#include "r8192xU_phyreg.h"
 #include <linux/usb.h>
-// FIXME: check if 2.6.7 is ok
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
-#define usb_kill_urb usb_unlink_urb
-#endif
 
-#ifdef CONFIG_RTL8192_PM
 #include "r8192U_pm.h"
-#endif
 
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
+#include "ieee80211/dot11d.h"
 
-#else
 
-#include <asm/uaccess.h>
-#include "r8192U_hw.h"
-#include "r8192U.h"
-#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
-#include "r8180_93cx6.h"   /* Card EEPROM */
-#include "r8192U_wx.h"
-#include "r819xU_phy.h" //added by WB 4.30.2008
-#include "r819xU_phyreg.h"
-#include "r819xU_cmdpkt.h"
-#include "r8192U_dm.h"
-//#include "r8192xU_phyreg.h"
-#include <linux/usb.h>
-// FIXME: check if 2.6.7 is ok
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
-#define usb_kill_urb usb_unlink_urb
-#endif
-
-#ifdef CONFIG_RTL8192_PM
-#include "r8192U_pm.h"
-#endif
-
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
 
-#endif
-
-
-#ifdef RTL8192SU
 u32 rt_global_debug_component = \
 //				COMP_TRACE	|
 //    				COMP_DBG	|
@@ -152,29 +106,6 @@ u32 rt_global_debug_component = \
 				COMP_DOWN	|
 				COMP_RESET	|
 				COMP_ERR; //always open err flags on
-#else
-//set here to open your trace code. //WB
-u32 rt_global_debug_component = \
-			//	COMP_INIT    	|
-//				COMP_DBG	|
-			//	COMP_EPROM   	|
-//				COMP_PHY	|
-			//	COMP_RF		|
-//				COMP_FIRMWARE	|
-//				COMP_CH		|
-			//	COMP_POWER_TRACKING |
-//				COMP_RATE	|
-			//	COMP_TXAGC	|
-		//		COMP_TRACE	|
-				COMP_DOWN	|
-		//		COMP_RECV	|
-                //              COMP_SWBW	|
-				COMP_SEC	|
-	//			COMP_RESET	|
-		//		COMP_SEND	|
-			//	COMP_EVENTS	|
-				COMP_ERR ; //always open err flags on
-#endif
 
 #define TOTAL_CAM_ENTRY 32
 #define CAM_CONTENT_COUNT 8
@@ -201,77 +132,41 @@ static struct usb_device_id rtl8192_usb_id_tbl[] = {
 };
 
 MODULE_LICENSE("GPL");
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 MODULE_VERSION("V 1.1");
-#endif
 MODULE_DEVICE_TABLE(usb, rtl8192_usb_id_tbl);
 MODULE_DESCRIPTION("Linux driver for Realtek RTL8192 USB WiFi cards");
 
 static char* ifname = "wlan%d";
-#if 0
-static int hwseqnum = 0;
-static int hwwep = 0;
-#endif
 static int hwwep = 1;  //default use hw. set 0 to use software security
 static int channels = 0x3fff;
 
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
 module_param(ifname, charp, S_IRUGO|S_IWUSR );
 //module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
 module_param(hwwep,int, S_IRUGO|S_IWUSR);
 module_param(channels,int, S_IRUGO|S_IWUSR);
-#else
-MODULE_PARM(ifname, "s");
-//MODULE_PARM(hwseqnum,"i");
-MODULE_PARM(hwwep,"i");
-MODULE_PARM(channels,"i");
-#endif
 
 MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
 //MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
 MODULE_PARM_DESC(hwwep," Try to use hardware security support. ");
 MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id);
 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf);
-#else
-static void *__devinit rtl8192_usb_probe(struct usb_device *udev,unsigned int ifnum,
-			 const struct usb_device_id *id);
-static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr);
-#endif
-
 
 static struct usb_driver rtl8192_usb_driver = {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15)
-	.owner		= THIS_MODULE,
-#endif
 	.name		= RTL819xU_MODULE_NAME,	          /* Driver name   */
 	.id_table	= rtl8192_usb_id_tbl,	          /* PCI_ID table  */
 	.probe		= rtl8192_usb_probe,	          /* probe fn      */
 	.disconnect	= rtl8192_usb_disconnect,	  /* remove fn     */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
-#ifdef CONFIG_RTL8192_PM
 	.suspend	= rtl8192U_suspend,	          /* PM suspend fn */
 	.resume		= rtl8192U_resume,                 /* PM resume fn  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
 	.reset_resume   = rtl8192U_resume,                 /* PM reset resume fn  */
-#endif
-#else
-	.suspend	= NULL,			          /* PM suspend fn */
-	.resume      	= NULL,			          /* PM resume fn  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22)
-	.reset_resume   = NULL,                 /* PM reset resume fn  */
-#endif
-#endif
-#endif
 };
 
 
-#ifdef RTL8192SU
 static void 	rtl8192SU_read_eeprom_info(struct net_device *dev);
 short 	rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb);
 void 	rtl8192SU_rx_nomal(struct sk_buff* skb);
@@ -294,32 +189,7 @@ struct rtl819x_ops rtl8192su_ops = {
 	.rtl819x_initial_gain = InitialGain8192S,
 	.rtl819x_query_rxdesc_status = rtl8192SU_query_rxdesc_status,
 };
-#else
-static void 	rtl8192_read_eeprom_info(struct net_device *dev);
-short	rtl8192_tx(struct net_device *dev, struct sk_buff* skb);
-void 	rtl8192_rx_nomal(struct sk_buff* skb);
-void 	rtl8192_rx_cmd(struct sk_buff *skb);
-bool 	rtl8192_adapter_start(struct net_device *dev);
-short	rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb);
-void 	rtl8192_link_change(struct net_device *dev);
-void 	InitialGain819xUsb(struct net_device *dev,u8 Operation);
-void 	query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe);
-
-struct rtl819x_ops rtl8192u_ops = {
-	.nic_type = NIC_8192U,
-	.rtl819x_read_eeprom_info = rtl8192_read_eeprom_info,
-	.rtl819x_tx = rtl8192_tx,
-	.rtl819x_tx_cmd = rtl819xU_tx_cmd,
-	.rtl819x_rx_nomal = rtl8192_rx_nomal,
-	.rtl819x_rx_cmd = rtl8192_rx_cmd,
-	.rtl819x_adapter_start = rtl8192_adapter_start,
-	.rtl819x_link_change = rtl8192_link_change,
-	.rtl819x_initial_gain = InitialGain819xUsb,
-	.rtl819x_query_rxdesc_status = query_rxdesc_status,
-};
-#endif
 
-#ifdef ENABLE_DOT11D
 
 typedef struct _CHANNEL_LIST
 {
@@ -395,11 +265,9 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
 	}
 	return;
 }
-#endif
 
 #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 )
 
-#ifdef RTL8192SU
 #define		rx_hal_is_cck_rate(_pDesc)\
 			((_pDesc->RxMCS  == DESC92S_RATE1M ||\
 			_pDesc->RxMCS == DESC92S_RATE2M ||\
@@ -413,14 +281,6 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
 			 _DataRate == MGN_5_5M ||\
 			 _DataRate == MGN_11M )
 
-#else
-#define 	rx_hal_is_cck_rate(_pdrvinfo)\
-			((_pdrvinfo->RxRate == DESC90_RATE1M ||\
-			_pdrvinfo->RxRate == DESC90_RATE2M ||\
-			_pdrvinfo->RxRate == DESC90_RATE5_5M ||\
-			_pdrvinfo->RxRate == DESC90_RATE11M) &&\
-			!_pdrvinfo->RxHT)
-#endif
 
 
 
@@ -505,11 +365,7 @@ void write_nic_byte(struct net_device *dev, int indx, u8 data)
 
 	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
-#ifdef RTL8192SU
 			       indx, 0, &data, 1, HZ / 2);
-#else
-			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
-#endif
 
         if (status < 0)
         {
@@ -530,11 +386,7 @@ void write_nic_word(struct net_device *dev, int indx, u16 data)
 
 	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
-#ifdef RTL8192SU
 			       indx, 0, &data, 2, HZ / 2);
-#else
-			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
-#endif
 
         if (status < 0)
         {
@@ -554,11 +406,7 @@ void write_nic_dword(struct net_device *dev, int indx, u32 data)
 
 	status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 			       RTL8187_REQ_SET_REGS, RTL8187_REQT_WRITE,
-#ifdef RTL8192SU
 			       indx, 0, &data, 4, HZ / 2);
-#else
-			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
-#endif
 
 
         if (status < 0)
@@ -579,11 +427,7 @@ u8 read_nic_byte(struct net_device *dev, int indx)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-#ifdef RTL8192SU
 			       indx, 0, &data, 1, HZ / 2);
-#else
-			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 1, HZ / 2);
-#endif
 
         if (status < 0)
         {
@@ -604,11 +448,7 @@ u16 read_nic_word(struct net_device *dev, int indx)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-#ifdef RTL8192SU
 			       indx, 0, &data, 2, HZ / 2);
-#else
-			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 2, HZ / 2);
-#endif
 
         if (status < 0)
         {
@@ -650,11 +490,7 @@ u32 read_nic_dword(struct net_device *dev, int indx)
 
 	status = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 			       RTL8187_REQ_GET_REGS, RTL8187_REQT_READ,
-#ifdef RTL8192SU
 			       indx, 0, &data, 4, HZ / 2);
-#else
-			       (indx&0xff)|0xff00, (indx>>8)&0x0f, &data, 4, HZ / 2);
-#endif
 //	if(0 != result) {
 //	  printk(KERN_WARNING "read size of data = %d\, date = %d\n", result, data);
 //	}
@@ -686,13 +522,8 @@ inline void force_pci_posting(struct net_device *dev)
 static struct net_device_stats *rtl8192_stats(struct net_device *dev);
 void rtl8192_commit(struct net_device *dev);
 //void rtl8192_restart(struct net_device *dev);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8192_restart(struct work_struct *work);
 //void rtl8192_rq_tx_ack(struct work_struct *work);
-#else
- void rtl8192_restart(struct net_device *dev);
-// //void rtl8192_rq_tx_ack(struct net_device *dev);
- #endif
 
 void watch_dog_timer_callback(unsigned long data);
 
@@ -735,7 +566,6 @@ static int proc_get_stats_ap(char *page, char **start,
 	return len;
 }
 
-#ifdef RTL8192SU
 static int proc_get_registers(char *page, char **start,
 			  off_t offset, int count,
 			  int *eof, void *data)
@@ -1026,166 +856,6 @@ static int proc_get_registers_e(char *page, char **start,
 	*eof = 1;
 	return len;
 }
-#else
-static int proc_get_registers(char *page, char **start,
-			  off_t offset, int count,
-			  int *eof, void *data)
-{
-	struct net_device *dev = data;
-//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
-	int len = 0;
-	int i,n;
-
-	int max=0xff;
-
-	/* This dump the current register page */
-len += snprintf(page + len, count - len,
-                        "\n####################page 0##################\n ");
-
-	for(n=0;n<=max;)
-	{
-		//printk( "\nD: %2x> ", n);
-		len += snprintf(page + len, count - len,
-			"\nD:  %2x > ",n);
-
-		for(i=0;i<16 && n<=max;i++,n++)
-		len += snprintf(page + len, count - len,
-			"%2x ",read_nic_byte(dev,0x000|n));
-
-		//	printk("%2x ",read_nic_byte(dev,n));
-	}
-#if 1
-len += snprintf(page + len, count - len,
-                        "\n####################page 1##################\n ");
-        for(n=0;n<=max;)
-        {
-                //printk( "\nD: %2x> ", n);
-                len += snprintf(page + len, count - len,
-                        "\nD:  %2x > ",n);
-
-                for(i=0;i<16 && n<=max;i++,n++)
-                len += snprintf(page + len, count - len,
-                        "%2x ",read_nic_byte(dev,0x100|n));
-
-                //      printk("%2x ",read_nic_byte(dev,n));
-        }
-len += snprintf(page + len, count - len,
-                        "\n####################page 3##################\n ");
-        for(n=0;n<=max;)
-        {
-                //printk( "\nD: %2x> ", n);
-                len += snprintf(page + len, count - len,
-                        "\nD:  %2x > ",n);
-
-                for(i=0;i<16 && n<=max;i++,n++)
-                len += snprintf(page + len, count - len,
-                        "%2x ",read_nic_byte(dev,0x300|n));
-
-                //      printk("%2x ",read_nic_byte(dev,n));
-        }
-
-#endif
-
-	len += snprintf(page + len, count - len,"\n");
-	*eof = 1;
-	return len;
-
-}
-#endif
-
-#if 0
-static int proc_get_cck_reg(char *page, char **start,
-			  off_t offset, int count,
-			  int *eof, void *data)
-{
-	struct net_device *dev = data;
-//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
-	int len = 0;
-	int i,n;
-
-	int max = 0x5F;
-
-	/* This dump the current register page */
-	for(n=0;n<=max;)
-	{
-		//printk( "\nD: %2x> ", n);
-		len += snprintf(page + len, count - len,
-			"\nD:  %2x > ",n);
-
-		for(i=0;i<16 && n<=max;i++,n++)
-		len += snprintf(page + len, count - len,
-			"%2x ",read_phy_cck(dev,n));
-
-		//	printk("%2x ",read_nic_byte(dev,n));
-	}
-	len += snprintf(page + len, count - len,"\n");
-
-
-	*eof = 1;
-	return len;
-}
-
-#endif
-
-#if 0
-static int proc_get_ofdm_reg(char *page, char **start,
-			  off_t offset, int count,
-			  int *eof, void *data)
-{
-	struct net_device *dev = data;
-//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
-	int len = 0;
-	int i,n;
-
-	//int max=0xff;
-	int max = 0x40;
-
-	/* This dump the current register page */
-	for(n=0;n<=max;)
-	{
-		//printk( "\nD: %2x> ", n);
-		len += snprintf(page + len, count - len,
-			"\nD:  %2x > ",n);
-
-		for(i=0;i<16 && n<=max;i++,n++)
-		len += snprintf(page + len, count - len,
-			"%2x ",read_phy_ofdm(dev,n));
-
-		//	printk("%2x ",read_nic_byte(dev,n));
-	}
-	len += snprintf(page + len, count - len,"\n");
-
-
-
-	*eof = 1;
-	return len;
-}
-
-#endif
-
-#if 0
-static int proc_get_stats_hw(char *page, char **start,
-			  off_t offset, int count,
-			  int *eof, void *data)
-{
-	struct net_device *dev = data;
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
-	int len = 0;
-
-	len += snprintf(page + len, count - len,
-		"NIC int: %lu\n"
-		"Total int: %lu\n",
-		priv->stats.ints,
-		priv->stats.shints);
-
-	*eof = 1;
-	return len;
-}
-#endif
 
 static int proc_get_stats_tx(char *page, char **start,
 			  off_t offset, int count,
@@ -1283,35 +953,17 @@ static int proc_get_stats_rx(char *page, char **start,
 	*eof = 1;
 	return len;
 }
-#if 0
-#if WIRELESS_EXT >= 12 && WIRELESS_EXT < 17
-
-static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
-{
-       struct r8192_priv *priv = ieee80211_priv(dev);
 
-       return &priv->wstats;
-}
-#endif
-#endif
 void rtl8192_proc_module_init(void)
 {
 	RT_TRACE(COMP_INIT, "Initializing proc filesystem");
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-	rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, proc_net);
-#else
 	rtl8192_proc=create_proc_entry(RTL819xU_MODULE_NAME, S_IFDIR, init_net.proc_net);
-#endif
 }
 
 
 void rtl8192_proc_module_remove(void)
 {
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
-	remove_proc_entry(RTL819xU_MODULE_NAME, proc_net);
-#else
 	remove_proc_entry(RTL819xU_MODULE_NAME, init_net.proc_net);
-#endif
 }
 
 
@@ -1357,16 +1009,6 @@ void rtl8192_proc_init_one(struct net_device *dev)
 		      dev->name);
 		return;
 	}
-	#if 0
-	e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
-				   priv->dir_dev, proc_get_stats_hw, dev);
-
-	if (!e) {
-		DMESGE("Unable to initialize "
-		      "/proc/net/rtl8192/%s/stats-hw\n",
-		      dev->name);
-	}
-	#endif
 	e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_rx, dev);
 
@@ -1385,17 +1027,6 @@ void rtl8192_proc_init_one(struct net_device *dev)
 		      "/proc/net/rtl8192/%s/stats-tx\n",
 		      dev->name);
 	}
-	#if 0
-	e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
-				   priv->dir_dev, proc_get_stats_ieee, dev);
-
-	if (!e) {
-		DMESGE("Unable to initialize "
-		      "/proc/net/rtl8192/%s/stats-ieee\n",
-		      dev->name);
-	}
-
-	#endif
 
 	e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_stats_ap, dev);
@@ -1413,7 +1044,6 @@ void rtl8192_proc_init_one(struct net_device *dev)
 		      "/proc/net/rtl8192/%s/registers\n",
 		      dev->name);
 	}
-#ifdef RTL8192SU
 	e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO,
 				   priv->dir_dev, proc_get_registers_1, dev);
 	if (!e) {
@@ -1477,24 +1107,6 @@ void rtl8192_proc_init_one(struct net_device *dev)
 		      "/proc/net/rtl8192/%s/registers-e\n",
 		      dev->name);
 	}
-#endif
-#if 0
-	e = create_proc_read_entry("cck-registers", S_IFREG | S_IRUGO,
-				   priv->dir_dev, proc_get_cck_reg, dev);
-	if (!e) {
-		RT_TRACE(COMP_ERR, "Unable to initialize "
-		      "/proc/net/rtl8192/%s/cck-registers\n",
-		      dev->name);
-	}
-
-	e = create_proc_read_entry("ofdm-registers", S_IFREG | S_IRUGO,
-				   priv->dir_dev, proc_get_ofdm_reg, dev);
-	if (!e) {
-		RT_TRACE(COMP_ERR, "Unable to initialize "
-		      "/proc/net/rtl8192/%s/ofdm-registers\n",
-		      dev->name);
-	}
-#endif
 }
 /****************************************************************************
    -----------------------------MISC STUFF-------------------------
@@ -1533,11 +1145,7 @@ void tx_timeout(struct net_device *dev)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	//rtl8192_commit(dev);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 	schedule_work(&priv->reset_wq);
-#else
-	schedule_task(&priv->reset_wq);
-#endif
 	//DMESG("TXTIMEOUT");
 }
 
@@ -1572,31 +1180,6 @@ void rtl8192_dump_reg(struct net_device *dev)
       ------------------------------HW STUFF---------------------------
 *****************************************************************************/
 
-#if 0
-void rtl8192_irq_enable(struct net_device *dev)
-{
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	//priv->irq_enabled = 1;
-/*
-	write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
-	INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
-	INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
-	INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
-*/
-	write_nic_word(dev,INTA_MASK, priv->irq_mask);
-}
-
-
-void rtl8192_irq_disable(struct net_device *dev)
-{
-//	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
-	write_nic_word(dev,INTA_MASK,0);
-	force_pci_posting(dev);
-//	priv->irq_enabled = 0;
-}
-#endif
-
 void rtl8192_set_mode(struct net_device *dev,int mode)
 {
 	u8 ecmd;
@@ -1644,15 +1227,6 @@ void rtl8192_set_chan(struct net_device *dev,short ch)
 	RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
 	//printk("=====>%s()====ch:%d\n", __FUNCTION__, ch);
 	priv->chan=ch;
-	#if 0
-	if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
-		priv->ieee80211->iw_mode == IW_MODE_MASTER){
-
-			priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
-			priv->ieee80211->master_chan = ch;
-			rtl8192_update_beacon_ch(dev);
-		}
-	#endif
 
 	/* this hack should avoid frame TX during channel setting*/
 
@@ -1672,22 +1246,11 @@ void rtl8192_set_chan(struct net_device *dev,short ch)
 #endif
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs);
-#else
 static void rtl8192_rx_isr(struct urb *urb);
-#endif
-//static void rtl8192_rx_isr(struct urb *rx_urb);
 
 u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats)
 {
 
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	if (pstats->bisrxaggrsubframe)
-		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
-			+ pstats->RxBufShift + 8);
-	else
-#endif
 		return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize
 				+ pstats->RxBufShift);
 
@@ -1704,29 +1267,21 @@ static int rtl8192_rx_initiate(struct net_device*dev)
                 skb = __dev_alloc_skb(RX_URB_SIZE, GFP_KERNEL);
                 if (!skb)
                         break;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	        entry = usb_alloc_urb(0, GFP_KERNEL);
-#else
-	        entry = usb_alloc_urb(0);
-#endif
                 if (!entry) {
                         kfree_skb(skb);
                         break;
                 }
 //		printk("nomal packet IN request!\n");
                 usb_fill_bulk_urb(entry, priv->udev,
-                                  usb_rcvbulkpipe(priv->udev, 3), skb->tail,
+                                  usb_rcvbulkpipe(priv->udev, 3), skb_tail_pointer(skb),
                                   RX_URB_SIZE, rtl8192_rx_isr, skb);
                 info = (struct rtl8192_rx_info *) skb->cb;
                 info->urb = entry;
                 info->dev = dev;
 		info->out_pipe = 3; //denote rx normal packet queue
                 skb_queue_tail(&priv->rx_queue, skb);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                 usb_submit_urb(entry, GFP_KERNEL);
-#else
-                usb_submit_urb(entry);
-#endif
         }
 
 	/* command packet rx procedure */
@@ -1735,28 +1290,20 @@ static int rtl8192_rx_initiate(struct net_device*dev)
                 skb = __dev_alloc_skb(RX_URB_SIZE ,GFP_KERNEL);
                 if (!skb)
                         break;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                 entry = usb_alloc_urb(0, GFP_KERNEL);
-#else
-                entry = usb_alloc_urb(0);
-#endif
                 if (!entry) {
                         kfree_skb(skb);
                         break;
                 }
                 usb_fill_bulk_urb(entry, priv->udev,
-                                  usb_rcvbulkpipe(priv->udev, 9), skb->tail,
+                                  usb_rcvbulkpipe(priv->udev, 9), skb_tail_pointer(skb),
                                   RX_URB_SIZE, rtl8192_rx_isr, skb);
                 info = (struct rtl8192_rx_info *) skb->cb;
                 info->urb = entry;
                 info->dev = dev;
 		   info->out_pipe = 9; //denote rx cmd packet queue
                 skb_queue_tail(&priv->rx_queue, skb);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 		usb_submit_urb(entry, GFP_KERNEL);
-#else
-		usb_submit_urb(entry);
-#endif
         }
 
         return 0;
@@ -1825,107 +1372,13 @@ void rtl8192_rx_enable(struct net_device *dev)
 	rtl8192_rx_initiate(dev);
 
 //	rtl8192_set_rxconf(dev);
-#if 0
-	if(NIC_8187 == priv->card_8187) {
-		cmd=read_nic_byte(dev,CMD);
-		write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
-	}
-	else {
-		//write_nic_dword(dev, RX_CONF, priv->ReceiveConfig);
-	}
-#endif
 }
 
 
 void rtl8192_tx_enable(struct net_device *dev)
 {
-#if 0
-	u8 cmd;
-	u8 byte;
-	u32 txconf;
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	//test loopback
-	//	priv->TransmitConfig |= (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
-	if(NIC_8187B == priv->card_8187){
-		write_nic_dword(dev, TX_CONF, priv->TransmitConfig);
-		byte = read_nic_byte(dev, MSR);
-		byte |= MSR_LINK_ENEDCA;
-		write_nic_byte(dev, MSR, byte);
-	} else {
-		byte = read_nic_byte(dev,CW_CONF);
-		byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
-		byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
-		write_nic_byte(dev, CW_CONF, byte);
-
-		byte = read_nic_byte(dev, TX_AGC_CTL);
-		byte &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
-		byte &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
-		byte &= ~(1<<TX_AGC_CTL_FEEDBACK_ANT);
-		write_nic_byte(dev, TX_AGC_CTL, byte);
-
-		txconf= read_nic_dword(dev,TX_CONF);
-
-
-		txconf = txconf &~ TX_LOOPBACK_MASK;
-
-#ifndef LOOP_TEST
-		txconf = txconf | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT);
-#else
-		txconf = txconf | (TX_LOOPBACK_BASEBAND<<TX_LOOPBACK_SHIFT);
-#endif
-		txconf = txconf &~ TCR_SRL_MASK;
-		txconf = txconf &~ TCR_LRL_MASK;
-
-		txconf = txconf | (priv->retry_data<<TX_LRLRETRY_SHIFT); // long
-		txconf = txconf | (priv->retry_rts<<TX_SRLRETRY_SHIFT); // short
-
-		txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
-
-		txconf = txconf &~ TCR_MXDMA_MASK;
-		txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
-
-		txconf = txconf | TCR_DISReqQsize;
-		txconf = txconf | TCR_DISCW;
-		txconf = txconf &~ TCR_SWPLCPLEN;
-
-		txconf=txconf | (1<<TX_NOICV_SHIFT);
-
-		write_nic_dword(dev,TX_CONF,txconf);
-
-#ifdef DEBUG_TX
-		DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
-#endif
-
-		cmd=read_nic_byte(dev,CMD);
-		write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
-	}
-#endif
-}
-
-#if 0
-void rtl8192_beacon_tx_enable(struct net_device *dev)
-{
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
-	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
-}
-
-
-void rtl8192_
-_disable(struct net_device *dev)
-{
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
-	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
 }
 
-#endif
-
-
 void rtl8192_rtx_disable(struct net_device *dev)
 {
 	u8 cmd;
@@ -1959,91 +1412,9 @@ void rtl8192_rtx_disable(struct net_device *dev)
 
 int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
 {
-	#if 0
-	int i;
-	u32 *tmp;
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-
-	priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
-					  sizeof(u32)*8*count,
-					  &priv->txbeaconringdma);
-	if (!priv->txbeaconring) return -1;
-	for (tmp=priv->txbeaconring,i=0;i<count;i++){
-		*tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
-		/*
-		*(tmp+2) = (u32)dma_tmp;
-		*(tmp+3) = bufsize;
-		*/
-		if(i+1<count)
-			*(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
-		else
-			*(tmp+4) = (u32)priv->txbeaconringdma;
-
-		tmp=tmp+8;
-	}
-	#endif
 	return 0;
 }
 
-#if 0
-void rtl8192_reset(struct net_device *dev)
-{
-
-	//struct r8192_priv *priv = ieee80211_priv(dev);
-	//u8 cr;
-
-
-	/* make sure the analog power is on before
-	 * reset, otherwise reset may fail
-	 */
-#if 0
-	if(NIC_8187 == priv->card_8187) {
-		rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-		rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-		rtl8192_irq_disable(dev);
-		mdelay(200);
-		write_nic_byte_E(dev,0x18,0x10);
-		write_nic_byte_E(dev,0x18,0x11);
-		write_nic_byte_E(dev,0x18,0x00);
-		mdelay(200);
-	}
-#endif
-	printk("=====>reset?\n");
-#if 0
-	cr=read_nic_byte(dev,CMD);
-	cr = cr & 2;
-	cr = cr | (1<<CMD_RST_SHIFT);
-	write_nic_byte(dev,CMD,cr);
-
-	force_pci_posting(dev);
-
-	mdelay(200);
-
-	if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
-		RT_TRACE(COMP_ERR, "Card reset timeout!\n");
-	else
-		RT_TRACE(COMP_DOWN, "Card successfully reset\n");
-#endif
-#if 0
-	if(NIC_8187 == priv->card_8187) {
-
-		printk("This is RTL8187 Reset procedure\n");
-		rtl8192_set_mode(dev,EPROM_CMD_LOAD);
-		force_pci_posting(dev);
-		mdelay(200);
-
-		/* after the eeprom load cycle, make sure we have
-		 * correct anaparams
-		 */
-		rtl8192_set_anaparam(dev, RTL8225_ANAPARAM_ON);
-		rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
-	}
-	else
-#endif
-		printk("This is RTL8187B Reset procedure\n");
-
-}
-#endif
 inline u16 ieeerate2rtlrate(int rate)
 {
 	switch(rate){
@@ -2083,13 +1454,7 @@ inline u16 rtl8192_rate2rate(short rate)
 	return rtl_rate[rate];
 }
 
-
-/* The protype of rx_isr has changed since one verion of Linux Kernel */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void rtl8192_rx_isr(struct urb *urb, struct pt_regs *regs)
-#else
 static void rtl8192_rx_isr(struct urb *urb)
-#endif
 {
         struct sk_buff *skb = (struct sk_buff *) urb->context;
         struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
@@ -2107,20 +1472,8 @@ static void rtl8192_rx_isr(struct urb *urb)
 	//	printk("%s():rx status err\n",__FUNCTION__);
                 return;
         }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
+
         skb_unlink(skb, &priv->rx_queue);
-#else
-	/*
-	 * __skb_unlink before linux2.6.14 does not use spinlock to protect list head.
-	 * add spinlock function manually. john,2008/12/03
-	 */
-	{
-		unsigned long flags;
-		spin_lock_irqsave(&(priv->rx_queue.lock), flags);
-		__skb_unlink(skb,&priv->rx_queue);
-		spin_unlock_irqrestore(&(priv->rx_queue.lock), flags);
-	}
-#endif
         skb_put(skb, urb->actual_length);
 
 	skb_queue_tail(&priv->skb_queue, skb);
@@ -2135,7 +1488,8 @@ static void rtl8192_rx_isr(struct urb *urb)
         }
 
 	usb_fill_bulk_urb(urb, priv->udev,
-			usb_rcvbulkpipe(priv->udev, out_pipe), skb->tail,
+			usb_rcvbulkpipe(priv->udev, out_pipe),
+			skb_tail_pointer(skb),
 			RX_URB_SIZE, rtl8192_rx_isr, skb);
 
         info = (struct rtl8192_rx_info *) skb->cb;
@@ -2143,14 +1497,10 @@ static void rtl8192_rx_isr(struct urb *urb)
         info->dev = dev;
 	info->out_pipe = out_pipe;
 
-        urb->transfer_buffer = skb->tail;
+        urb->transfer_buffer = skb_tail_pointer(skb);
         urb->context = skb;
         skb_queue_tail(&priv->rx_queue, skb);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
         err = usb_submit_urb(urb, GFP_ATOMIC);
-#else
-        err = usb_submit_urb(urb);
-#endif
 	if(err && err != EPERM)
 		printk("can not submit rxurb, err is %x,URB status is %x\n",err,urb->status);
 }
@@ -2179,44 +1529,15 @@ rtl819xusb_rx_command_packet(
 	return status;
 }
 
-#if 0
-void rtl8192_tx_queues_stop(struct net_device *dev)
-{
-	//struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
-	dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
-	dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
-	dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
-
-	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
-	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
-}
-#endif
-
 void rtl8192_data_hard_stop(struct net_device *dev)
 {
 	//FIXME !!
-	#if 0
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
-	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
-	#endif
 }
 
 
 void rtl8192_data_hard_resume(struct net_device *dev)
 {
 	// FIXME !!
-	#if 0
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
-	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
-	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
-	#endif
 }
 
 /* this function TX data frames when the ieee80211 stack requires this.
@@ -2288,263 +1609,8 @@ int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
 
 void rtl8192_try_wake_queue(struct net_device *dev, int pri);
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb)
-{
-	u16     PaddingNum =  256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256);
-	return  (PaddingNum&0xff);
-}
 
-u8 MRateToHwRate8190Pci(u8 rate);
-u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc);
-u8 MapHwQueueToFirmwareQueue(u8 QueueID);
-struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	cb_desc 	*tcb_desc = NULL;
-	u8 		i;
-	u32		TotalLength;
-	struct sk_buff	*skb;
-	struct sk_buff  *agg_skb;
-	tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL;
-	tx_fwinfo_819x_usb	       *tx_fwinfo = NULL;
-
-	//
-	// Local variable initialization.
-	//
-	/* first skb initialization */
-	skb = pSendList->tx_agg_frames[0];
-	TotalLength = skb->len;
-
-	/* Get the total aggregation length including the padding space and
-	 * sub frame header.
-	 */
-	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
-		TotalLength += DrvAggr_PaddingAdd(dev, skb);
-		skb = pSendList->tx_agg_frames[i];
-		TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
-	}
-
-	/* allocate skb to contain the aggregated packets */
-	agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom);
-	memset(agg_skb->data, 0, agg_skb->len);
-	skb_reserve(agg_skb, ieee->tx_headroom);
-
-//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
-	/* reserve info for first subframe Tx descriptor to be set in the tx function */
-	skb = pSendList->tx_agg_frames[0];
-	tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-	tcb_desc->drv_agg_enable = 1;
-	tcb_desc->pkt_size = skb->len;
- 	tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames;
-	printk("DrvAggNum = %d\n", tcb_desc->DrvAggrNum);
-//	RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
-//	printk("========>skb->data ======> \n");
-//	RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
-	memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb));
-	memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
-
-	for(i = 1; i < pSendList->nr_drv_agg_frames; i++) {
-		/* push the next sub frame to be 256 byte aline */
-		skb_put(agg_skb,DrvAggr_PaddingAdd(dev,skb));
-
-		/* Subframe drv Tx descriptor and firmware info setting */
-		skb = pSendList->tx_agg_frames[i];
-		tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-		tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)agg_skb->tail;
-		tx_fwinfo = (tx_fwinfo_819x_usb *)(agg_skb->tail + sizeof(tx_desc_819x_usb_aggr_subframe));
-
-		memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
-		/* DWORD 0 */
-		tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
-		tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
-		tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
-		tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
-		if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
-			tx_fwinfo->AllowAggregation = 1;
-			/* DWORD 1 */
-			tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
-			tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
-		} else {
-			tx_fwinfo->AllowAggregation = 0;
-			/* DWORD 1 */
-			tx_fwinfo->RxMF = 0;
-			tx_fwinfo->RxAMD = 0;
-		}
-
-		/* Protection mode related */
-		tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
-		tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
-		tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
-		tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
-		tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
-		tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
-		tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
-		tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
-				      (tcb_desc->bRTSUseShortGI?1:0);
-
-		/* Set Bandwidth and sub-channel settings. */
-		if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
-		{
-			if(tcb_desc->bPacketBW) {
-				tx_fwinfo->TxBandwidth = 1;
-				tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
-			} else {
-				tx_fwinfo->TxBandwidth = 0;
-				tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
-			}
-		} else {
-			tx_fwinfo->TxBandwidth = 0;
-			tx_fwinfo->TxSubCarrier = 0;
-		}
-
-		/* Fill Tx descriptor */
-		memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe));
-		/* DWORD 0 */
-		//tx_agg_desc->LINIP = 0;
-		//tx_agg_desc->CmdInit = 1;
-		tx_agg_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
-		/* already raw data, need not to substract header length */
-		tx_agg_desc->PktSize = skb->len & 0xffff;
-
-		/*DWORD 1*/
-		tx_agg_desc->SecCAMID= 0;
-		tx_agg_desc->RATid = tcb_desc->RATRIndex;
-#if 0
-		/* Fill security related */
-		if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
-		{
-			EncAlg = SecGetEncryptionOverhead(
-					Adapter,
-					&EncryptionMPDUHeadOverhead,
-					&EncryptionMPDUTailOverhead,
-					NULL,
-					NULL,
-					FALSE,
-					FALSE);
-			//2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
-			//MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
-			MPDUOverhead = EncryptionMPDUTailOverhead;
-			tx_agg_desc->NoEnc = 0;
-			RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_agg_desc->SecCAMID,tx_agg_desc->SecDescAssign,EncAlg));
-			//CamDumpAll(Adapter);
-		}
-		else
-#endif
-		{
-			//MPDUOverhead = 0;
-			tx_agg_desc->NoEnc = 1;
-		}
-#if 0
-		switch(EncAlg){
-			case NO_Encryption:
-				tx_agg_desc->SecType = 0x0;
-				break;
-			case WEP40_Encryption:
-			case WEP104_Encryption:
-				tx_agg_desc->SecType = 0x1;
-				break;
-			case TKIP_Encryption:
-				tx_agg_desc->SecType = 0x2;
-				break;
-			case AESCCMP_Encryption:
-				tx_agg_desc->SecType = 0x3;
-				break;
-			default:
-				tx_agg_desc->SecType = 0x0;
-				break;
-		}
-#else
-		tx_agg_desc->SecType = 0x0;
-#endif
-
-		if (tcb_desc->bHwSec) {
-			switch (priv->ieee80211->pairwise_key_type)
-			{
-				case KEY_TYPE_WEP40:
-				case KEY_TYPE_WEP104:
-					tx_agg_desc->SecType = 0x1;
-					tx_agg_desc->NoEnc = 0;
-					break;
-				case KEY_TYPE_TKIP:
-					tx_agg_desc->SecType = 0x2;
-					tx_agg_desc->NoEnc = 0;
-					break;
-				case KEY_TYPE_CCMP:
-					tx_agg_desc->SecType = 0x3;
-					tx_agg_desc->NoEnc = 0;
-					break;
-				case KEY_TYPE_NA:
-					tx_agg_desc->SecType = 0x0;
-					tx_agg_desc->NoEnc = 1;
-					break;
-			}
-		}
-
-		tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
-		tx_agg_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
-
-		tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
-		tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
-
-		tx_agg_desc->OWN = 1;
-
-		//DWORD 2
-		/* According windows driver, it seems that there no need to fill this field */
-		//tx_agg_desc->TxBufferSize= (u32)(skb->len - USB_HWDESC_HEADER_LEN);
-
-		/* to fill next packet */
-		skb_put(agg_skb,TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES);
-		memcpy(skb_put(agg_skb,skb->len),skb->data,skb->len);
-	}
-
-	for(i = 0; i < pSendList->nr_drv_agg_frames; i++) {
-		dev_kfree_skb_any(pSendList->tx_agg_frames[i]);
-	}
-
-	return agg_skb;
-}
-
-/* NOTE:
-	This function return a list of PTCB which is proper to be aggregate with the input TCB.
-	If no proper TCB is found to do aggregation, SendList will only contain the input TCB.
-*/
-u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb,
-		struct ieee80211_drv_agg_txb *pSendList)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-	struct ieee80211_device *ieee = netdev_priv(dev);
-#else
-	struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
-#endif
-	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
-	u16		nMaxAggrNum = pHTInfo->UsbTxAggrNum;
-	cb_desc 	*tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-	u8		QueueID = tcb_desc->queue_index;
-
-	do {
-		pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb;
-		if(pSendList->nr_drv_agg_frames >= nMaxAggrNum) {
-			break;
-		}
-
-	} while((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID])));
-
-	RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames);
-	return pSendList->nr_drv_agg_frames;
-}
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void rtl8192_tx_isr(struct urb *tx_urb, struct pt_regs *reg)
-#else
 static void rtl8192_tx_isr(struct urb *tx_urb)
-#endif
 {
 	struct sk_buff *skb = (struct sk_buff*)tx_urb->context;
 	struct net_device *dev = NULL;
@@ -2580,29 +1646,11 @@ static void rtl8192_tx_isr(struct urb *tx_urb)
 		atomic_dec(&priv->tx_pending[queue_index]);
 	}
 
-#if 0  //we need to send zero byte packet just after 512 byte(64 byte)packet is transmitted, or we will halt. It will greatly reduced available page in FW, and ruin our throughput. WB 2008.08.27
-	if(BufLen > 0 && ((BufLen % 512 == 0)||(BufLen % 64 == 0))) {
-		bToSend0Byte = true;
-	}
-
-	bToSend0Byte = false;
-	//
-	// Note that, we at most handle 1 MPDU to send here, either
-	// fragment or MPDU in wait queue.
-	//
-	if(!bToSend0Byte)
-#endif
 	{
 		//
 		// Handle HW Beacon:
 		// We had transfer our beacon frame to host controler at this moment.
 		//
-#if 0
-		if(tcb_desc->tx_queue == BEACON_QUEUE)
-		{
-			priv->bSendingBeacon = FALSE;
-		}
-#endif
 		//
 		// Caution:
 		// Handling the wait queue of command packets.
@@ -2627,74 +1675,8 @@ static void rtl8192_tx_isr(struct urb *tx_urb)
 
 				return; //modified by david to avoid further processing AMSDU
 			}
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-			else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index])!= 0)&&\
- 				(!(priv->ieee80211->queue_stop))) {
-				// Tx Driver Aggregation process
-				/* The driver will aggregation the packets according to the following stets
-				 * 1. check whether there's tx irq available, for it's a completion return
-				 *    function, it should contain enough tx irq;
-				 * 2. check pakcet type;
-				 * 3. intialize sendlist, check whether the to-be send packet no greater than 1
-				 * 4. aggregation the packets, and fill firmware info and tx desc to it, etc.
-				 * 5. check whehter the packet could be sent, otherwise just insert to wait head
-				 * */
-				skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]);
-				if(!check_nic_enough_desc(dev, queue_index)) {
-					skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb);
-					return;
-				}
-
-				{
-					/*TODO*/
-					/*
-					u8* pHeader = skb->data;
-
-					if(IsMgntQosData(pHeader) ||
-				            IsMgntQData_Ack(pHeader) ||
-					    IsMgntQData_Poll(pHeader) ||
-					    IsMgntQData_Poll_Ack(pHeader)
-					  )
-					*/
-					{
-						struct ieee80211_drv_agg_txb SendList;
-
-						memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb));
-						if(DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) {
-							skb = DrvAggr_Aggregation(dev, &SendList);
-
-#if 0
-						printk("=============>to send aggregated packet!\n");
-						RT_DEBUG_DATA(COMP_SEND, skb->cb, sizeof(skb->cb));
-						printk("\n=================skb->len = %d\n", skb->len);
-						RT_DEBUG_DATA(COMP_SEND, skb->data, skb->len);
-#endif
-						}
-					}
-					priv->ieee80211->softmac_hard_start_xmit(skb, dev);
-				}
-			}
-#endif
 		}
 	}
-
-#if 0
-	else
-	{
-		RT_TRACE( COMP_SEND,"HalUsbOutComplete(%d): bToSend0Byte.\n", PipeIndex);
-
-		//
-		// In this case, we don't return skb now.
-		// It will be returned when the 0-byte request completed.
-		//
-
-		//
-		// Bulk out an 0-byte padding transfer.
-		//
-		HalUsbOut0Byte(pAdapter, PipeIndex, skb);
-	}
-
-#endif
 }
 
 void rtl8192_beacon_stop(struct net_device *dev)
@@ -2775,7 +1757,6 @@ void rtl8192_update_cap(struct net_device* dev, u16 cap)
 	priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
 
 	//LZM MOD 090303 HW_VAR_ACK_PREAMBLE
-#ifdef RTL8192SU
 	if(0)
 	{
 		u8 tmp = 0;
@@ -2784,15 +1765,6 @@ void rtl8192_update_cap(struct net_device* dev, u16 cap)
 			tmp |= 0x80;
 		write_nic_byte(dev, RRSR+2, tmp);
 	}
-#else
-	{
-	u32 tmp = 0;
-	tmp = priv->basic_rate;
-	if (priv->short_preamble)
-		tmp |= BRSR_AckShortPmb;
-	write_nic_dword(dev, RRSR, tmp);
-	}
-#endif
 
 	if (net->mode & (IEEE_G|IEEE_N_24G))
 	{
@@ -2851,41 +1823,6 @@ void rtl8192_net_update(struct net_device *dev)
 #if 1
 void rtl819xusb_beacon_tx(struct net_device *dev,u16  tx_rate)
 {
-
-#if 0
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	struct sk_buff *skb;
-	int i = 0;
-	//u8 cr;
-
-	rtl8192_net_update(dev);
-
-	skb = ieee80211_get_beacon(priv->ieee80211);
-		if(!skb){
-			DMESG("not enought memory for allocating beacon");
-			return;
-		}
-
-
-		write_nic_byte(dev, BQREQ, read_nic_byte(dev, BQREQ) | (1<<7));
-
-		i=0;
-		//while(!read_nic_byte(dev,BQREQ & (1<<7)))
-		while( (read_nic_byte(dev, BQREQ) & (1<<7)) == 0 )
-		{
-			msleep_interruptible_rtl(HZ/2);
-			if(i++ > 10){
-				DMESGW("get stuck to wait HW beacon to be ready");
-				return ;
-			}
-		}
-	skb->cb[0] = NORM_PRIORITY;
-	skb->cb[1] = 0; //morefragment = 0
-	skb->cb[2] = ieeerate2rtlrate(tx_rate);
-
-	rtl8192_tx(dev,skb);
-
-#endif
 }
 #endif
 inline u8 rtl8192_IsWirelessBMode(u16 rate)
@@ -2976,38 +1913,6 @@ u16 N_DBPSOfRate(u16 DataRate)
 
 void rtl819xU_cmd_isr(struct urb *tx_cmd_urb, struct pt_regs *regs)
 {
-#if 0
-	struct net_device *dev = (struct net_device*)tx_cmd_urb->context;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	int		   last_init_packet = 0;
-	u8		   *ptr_cmd_buf;
-	u16		    cmd_buf_len;
-
-	if(tx_cmd_urb->status != 0) {
-		priv->pFirmware.firmware_seg_index = 0; //only begin transter, should it can be set to 1
-	}
-
-	/* Free the urb and the corresponding buf for common Tx cmd packet, or
-	 * last segment of each firmware img.
-	 */
-	if((priv->pFirmware.firmware_seg_index == 0) ||(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum)) {
-		priv->pFirmware.firmware_seg_index = 0;//only begin transter, should it can be set to 1
-	} else {
-		/* prepare for last transfer */
-		/* update some infomation for */
-		/* last segment of the firmware img need indicate to device */
-		priv->pFirmware.firmware_seg_index++;
-		if(priv->pFirmware.firmware_seg_index == priv->pFirmware.firmware_seg_maxnum) {
-			last_init_packet = 1;
-		}
-
-		cmd_buf_len = priv->pFirmware.firmware_seg_container[priv->pFirmware.firmware_seg_index-1].seg_size;
-		ptr_cmd_buf = priv->pFfirmware.firmware_seg_container[priv->pFfirmware.firmware_seg_index-1].seg_ptr;
-		rtl819xU_tx_cmd(dev, ptr_cmd_buf, cmd_buf_len, last_init_packet, DESC_PACKET_TYPE_INIT);
-	}
-
-	kfree(tx_cmd_urb->transfer_buffer);
-#endif
 	usb_free_urb(tx_cmd_urb);
 }
 
@@ -3021,7 +1926,6 @@ unsigned int txqueue2outpipe(struct r8192_priv* priv,unsigned int tx_queue) {
 	return priv->txqueue_to_outpipemap[tx_queue];
 }
 
-#ifdef RTL8192SU
 short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
@@ -3036,11 +1940,7 @@ short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
 	//printk("\n %s::::::::::::::::::::::queue_index = %d\n",__FUNCTION__, queue_index);
 	atomic_inc(&priv->tx_pending[queue_index]);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
-#else
-	tx_urb = usb_alloc_urb(0);
-#endif
 	if(!tx_urb){
 		dev_kfree_skb(skb);
 		return -ENOMEM;
@@ -3060,14 +1960,6 @@ short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
 	idx_pipe = txqueue2outpipe(priv,queue_index);
 	//printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,queue_index,priv->RtOutPipes[idx_pipe]);
 
-#ifdef JOHN_DUMP_TXDESC
-	int i;
-	printk("Len = %d\n", skb->len);
-	for (i = 0; i < 8; i++)
-		printk("%2.2x ", *((u8*)skb->data+i));
-	printk("\n");
-#endif
-
 	usb_fill_bulk_urb(tx_urb,
 	                            priv->udev,
 	                            usb_sndbulkpipe(priv->udev,priv->RtOutPipes[idx_pipe]),
@@ -3076,12 +1968,7 @@ short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
 	                            rtl8192_tx_isr,
 	                            skb);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
-#else
-	status = usb_submit_urb(tx_urb);
-#endif
-
 	if (!status){
 		return 0;
 	}else{
@@ -3090,74 +1977,6 @@ short rtl8192SU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
 		return -1;
 	}
 }
-#else
-short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	//u8			*tx;
-	int			status;
-	struct urb		*tx_urb;
-	//int			urb_buf_len;
-	unsigned int 		idx_pipe;
-	tx_desc_cmd_819x_usb *pdesc = (tx_desc_cmd_819x_usb *)skb->data;
-	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-	u8 queue_index = tcb_desc->queue_index;
-
-	//printk("\n %s::queue_index = %d\n",__FUNCTION__, queue_index);
-	atomic_inc(&priv->tx_pending[queue_index]);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
-#else
-	tx_urb = usb_alloc_urb(0);
-#endif
-	if(!tx_urb){
-		dev_kfree_skb(skb);
-		return -ENOMEM;
-	}
-
-	memset(pdesc, 0, USB_HWDESC_HEADER_LEN);
-	/* Tx descriptor ought to be set according to the skb->cb */
-	pdesc->FirstSeg = 1;//bFirstSeg;
-	pdesc->LastSeg = 1;//bLastSeg;
-	pdesc->CmdInit = tcb_desc->bCmdOrInit;
-	pdesc->TxBufferSize = tcb_desc->txbuf_size;
-	pdesc->OWN = 1;
-	pdesc->LINIP = tcb_desc->bLastIniPkt;
-
-	//----------------------------------------------------------------------------
-	// Fill up USB_OUT_CONTEXT.
-	//----------------------------------------------------------------------------
-	// Get index to out pipe from specified QueueID.
-#ifndef USE_ONE_PIPE
-	idx_pipe = txqueue2outpipe(priv,queue_index);
-#else
-	idx_pipe = 0x04;
-#endif
-#ifdef JOHN_DUMP_TXDESC
-	int i;
-	printk("<Tx descriptor>--rate %x---",rate);
-	for (i = 0; i < 8; i++)
-		printk("%8x ", tx[i]);
-	printk("\n");
-#endif
-	usb_fill_bulk_urb(tx_urb,priv->udev, usb_sndbulkpipe(priv->udev,idx_pipe), \
-			skb->data, skb->len, rtl8192_tx_isr, skb);
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
-#else
-	status = usb_submit_urb(tx_urb);
-#endif
-
-	if (!status){
-		return 0;
-	}else{
-		DMESGE("Error TX CMD URB, error %d",
-				status);
-		return -1;
-	}
-}
-#endif
 
 /*
  * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
@@ -3212,7 +2031,6 @@ u8 MapHwQueueToFirmwareQueue(u8 QueueID)
 	return QueueSelect;
 }
 
-#ifdef RTL8192SU
 u8 MRateToHwRate8190Pci(u8 rate)
 {
 	u8	ret = DESC92S_RATE1M;
@@ -3277,49 +2095,6 @@ u8 MRateToHwRate8190Pci(u8 rate)
 	}
 	return ret;
 }
-#else
-u8 MRateToHwRate8190Pci(u8 rate)
-{
-	u8  ret = DESC90_RATE1M;
-
-	switch(rate) {
-		case MGN_1M:    ret = DESC90_RATE1M;    break;
-		case MGN_2M:    ret = DESC90_RATE2M;    break;
-		case MGN_5_5M:  ret = DESC90_RATE5_5M;  break;
-		case MGN_11M:   ret = DESC90_RATE11M;   break;
-		case MGN_6M:    ret = DESC90_RATE6M;    break;
-		case MGN_9M:    ret = DESC90_RATE9M;    break;
-		case MGN_12M:   ret = DESC90_RATE12M;   break;
-		case MGN_18M:   ret = DESC90_RATE18M;   break;
-		case MGN_24M:   ret = DESC90_RATE24M;   break;
-		case MGN_36M:   ret = DESC90_RATE36M;   break;
-		case MGN_48M:   ret = DESC90_RATE48M;   break;
-		case MGN_54M:   ret = DESC90_RATE54M;   break;
-
-		// HT rate since here
-		case MGN_MCS0:  ret = DESC90_RATEMCS0;  break;
-		case MGN_MCS1:  ret = DESC90_RATEMCS1;  break;
-		case MGN_MCS2:  ret = DESC90_RATEMCS2;  break;
-		case MGN_MCS3:  ret = DESC90_RATEMCS3;  break;
-		case MGN_MCS4:  ret = DESC90_RATEMCS4;  break;
-		case MGN_MCS5:  ret = DESC90_RATEMCS5;  break;
-		case MGN_MCS6:  ret = DESC90_RATEMCS6;  break;
-		case MGN_MCS7:  ret = DESC90_RATEMCS7;  break;
-		case MGN_MCS8:  ret = DESC90_RATEMCS8;  break;
-		case MGN_MCS9:  ret = DESC90_RATEMCS9;  break;
-		case MGN_MCS10: ret = DESC90_RATEMCS10; break;
-		case MGN_MCS11: ret = DESC90_RATEMCS11; break;
-		case MGN_MCS12: ret = DESC90_RATEMCS12; break;
-		case MGN_MCS13: ret = DESC90_RATEMCS13; break;
-		case MGN_MCS14: ret = DESC90_RATEMCS14; break;
-		case MGN_MCS15: ret = DESC90_RATEMCS15; break;
-		case (0x80|0x20): ret = DESC90_RATEMCS32; break;
-
-		default:       break;
-	}
-	return ret;
-}
-#endif
 
 u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
 {
@@ -3333,17 +2108,12 @@ u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
 	return tmp_Short;
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void tx_zero_isr(struct urb *tx_urb, struct pt_regs *reg)
-#else
 static void tx_zero_isr(struct urb *tx_urb)
-#endif
 {
 	return;
 }
 
 
-#ifdef RTL8192SU
 /*
  * The tx procedure is just as following,  skb->cb will contain all the following
  *information: * priority, morefrag, rate, &dev.
@@ -3372,12 +2142,6 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 	u16		MPDUOverhead = 0;
  	//RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
 
-#if 0
-	/* Added by Annie for filling Len_Adjust field. 2005-12-14. */
-        RT_ENC_ALG  EncAlg = NO_Encryption;
-#endif
-
-
 	pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
 	/* we are locked here so the two atomic_read and inc are executed
 	 * without interleaves  * !!! For debug purpose 	  */
@@ -3401,11 +2165,7 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 		return -1;
 	}
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
-#else
-	tx_urb = usb_alloc_urb(0);
-#endif
 	if(!tx_urb){
 		dev_kfree_skb_any(skb);
 		return -ENOMEM;
@@ -3414,22 +2174,7 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 	memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
 
 
-#if RTL8192SU_FPGA_UNSPECIFIED_NETWORK
-		if(IsQoSDataFrame(skb->data))
-		{
-			tcb_desc->bAMPDUEnable = TRUE;
-			tx_desc->NonQos = 0;
-		}
-		else
-			tcb_desc->bAMPDUEnable = FALSE;
-
-		tcb_desc->bPacketBW = TRUE;
-		priv->CurrentChannelBW = HT_CHANNEL_WIDTH_20_40;
-#endif
-
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
 		tx_desc->NonQos = (IsQoSDataFrame(skb->data)==TRUE)? 0:1;
-#endif
 
 	/* Fill Tx descriptor */
 	//memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
@@ -3438,10 +2183,6 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 	/* DWORD 0 */
 	tx_desc->TxHT = (tcb_desc->data_rate&0x80)?1:0;
 
-#ifdef RTL8192SU_DISABLE_CCK_RATE
-		if(tx_hal_is_cck_rate(tcb_desc->data_rate))
-			tcb_desc->data_rate = MGN_6M;
-#endif
 
 	tx_desc->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
 	//tx_desc->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
@@ -3509,12 +2250,6 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 		tx_desc->TxSubCarrier = 0;
 	}
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	if (tcb_desc->drv_agg_enable)
-	{
-		//tx_desc->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1; //92su del
-	}
-#endif
 
 	//memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
 	/* DWORD 0 */
@@ -3522,11 +2257,6 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
         //tx_desc->CmdInit = 1; //92su del
         tx_desc->Offset =  USB_HWDESC_HEADER_LEN;
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	if (tcb_desc->drv_agg_enable) {
-		tx_desc->PktSize = tcb_desc->pkt_size;//FIXLZM
-	} else
-#endif
 	{
 		tx_desc->PktSize = (skb->len - USB_HWDESC_HEADER_LEN) & 0xffff;
 	}
@@ -3535,57 +2265,14 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 	//tx_desc->SecCAMID= 0;//92su del
 	tx_desc->RaBRSRID= tcb_desc->RATRIndex;
 //#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
-#if 0//LZM 090219
-	tx_desc->RaBRSRID= 1;
-#endif
 
-#if 0
-	/* Fill security related */
-	if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
-	{
-		EncAlg = SecGetEncryptionOverhead(
-				Adapter,
-				&EncryptionMPDUHeadOverhead,
-				&EncryptionMPDUTailOverhead,
-				NULL,
-				NULL,
-				FALSE,
-				FALSE);
-		//2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
-		//MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
-		MPDUOverhead = EncryptionMPDUTailOverhead;
-		tx_desc->NoEnc = 0;
-		RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_desc->SecCAMID,tx_desc->SecDescAssign,EncAlg));
-		//CamDumpAll(Adapter);
-	}
-	else
-#endif
 	{
 		MPDUOverhead = 0;
 		//tx_desc->NoEnc = 1;//92su del
 	}
-#if 0
-	switch(EncAlg){
-		case NO_Encryption:
-			tx_desc->SecType = 0x0;
-			break;
-		case WEP40_Encryption:
-		case WEP104_Encryption:
-			tx_desc->SecType = 0x1;
-			break;
-		case TKIP_Encryption:
-			tx_desc->SecType = 0x2;
-			break;
-		case AESCCMP_Encryption:
-			tx_desc->SecType = 0x3;
-			break;
-		default:
-			tx_desc->SecType = 0x0;
-			break;
-	}
-#else
+
 	tx_desc->SecType = 0x0;
-#endif
+
 		if (tcb_desc->bHwSec)
 			{
 				switch (priv->ieee80211->pairwise_key_type)
@@ -3626,40 +2313,16 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 
         /* Fill fields that are required to be initialized in all of the descriptors */
         //DWORD 0
-#if 0
-        tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
-        tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
-#else
         tx_desc->FirstSeg = 1;
         tx_desc->LastSeg = 1;
-#endif
         tx_desc->OWN = 1;
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	if (tcb_desc->drv_agg_enable) {
-		tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
-	} else
-#endif
 	{
 		//DWORD 2
 		//tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
 		tx_desc->TxBufferSize = (u32)(skb->len);//92su mod FIXLZM
 	}
 
-#if 0
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(1)TxFillDescriptor8192SUsb(): DataRate(%#x)\n", pTcb->DataRate));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(2)TxFillDescriptor8192SUsb(): bTxUseDriverAssingedRate(%#x)\n", pTcb->bTxUseDriverAssingedRate));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(3)TxFillDescriptor8192SUsb(): bAMPDUEnable(%d)\n", pTcb->bAMPDUEnable));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(4)TxFillDescriptor8192SUsb(): bRTSEnable(%d)\n", pTcb->bRTSEnable));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(5)TxFillDescriptor8192SUsb(): RTSRate(%#x)\n", pTcb->RTSRate));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(6)TxFillDescriptor8192SUsb(): bCTSEnable(%d)\n", pTcb->bCTSEnable));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(7)TxFillDescriptor8192SUsb(): bUseShortGI(%d)\n", pTcb->bUseShortGI));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(8)TxFillDescriptor8192SUsb(): bPacketBW(%d)\n", pTcb->bPacketBW));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(9)TxFillDescriptor8192SUsb(): CurrentChannelBW(%d)\n", pHalData->CurrentChannelBW));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(10)TxFillDescriptor8192SUsb(): bTxDisableRateFallBack(%d)\n", pTcb->bTxDisableRateFallBack));
-	RT_TRACE(COMP_FPGA, DBG_LOUD, ("(11)TxFillDescriptor8192SUsb(): RATRIndex(%d)\n", pTcb->RATRIndex));
-#endif
-
 	/* Get index to out pipe from specified QueueID */
 	idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
 	//printk("=============>%s queue_index:%d, outpipe:%d\n", __func__,tcb_desc->queue_index,priv->RtOutPipes[idx_pipe]);
@@ -3674,309 +2337,7 @@ short rtl8192SU_tx(struct net_device *dev, struct sk_buff* skb)
 				    skb->data,
 				    skb->len, rtl8192_tx_isr, skb);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
-#else
-	status = usb_submit_urb(tx_urb);
-#endif
-	if (!status){
-//we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
-		bool bSend0Byte = false;
-		u8 zero = 0;
-		if(udev->speed == USB_SPEED_HIGH)
-		{
-			if (skb->len > 0 && skb->len % 512 == 0)
-				bSend0Byte = true;
-		}
-		else
-		{
-			if (skb->len > 0 && skb->len % 64 == 0)
-				bSend0Byte = true;
-		}
-		if (bSend0Byte)
-		{
-#if 1
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-			tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
-#else
-			tx_urb_zero = usb_alloc_urb(0);
-#endif
-			if(!tx_urb_zero){
-				RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
-				return -ENOMEM;
-			}
-			usb_fill_bulk_urb(tx_urb_zero,udev,
-					usb_sndbulkpipe(udev,idx_pipe), &zero,
-					0, tx_zero_isr, dev);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-			status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
-#else
-			status = usb_submit_urb(tx_urb_zero);
-#endif
-			if (status){
-			RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
-			return -1;
-			}
-#endif
-		}
-		dev->trans_start = jiffies;
-		atomic_inc(&priv->tx_pending[tcb_desc->queue_index]);
-		return 0;
-	}else{
-		RT_TRACE(COMP_ERR, "Error TX URB %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]),
-				status);
-		return -1;
-	}
-}
-#else
-
-/*
- * The tx procedure is just as following,
- * skb->cb will contain all the following information,
- * priority, morefrag, rate, &dev.
- * */
-short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
-	tx_desc_819x_usb *tx_desc = (tx_desc_819x_usb *)skb->data;
-	tx_fwinfo_819x_usb *tx_fwinfo = (tx_fwinfo_819x_usb *)(skb->data + USB_HWDESC_HEADER_LEN);
-	struct usb_device *udev = priv->udev;
-	int pend;
-	int status;
-	struct urb *tx_urb = NULL, *tx_urb_zero = NULL;
-	//int urb_len;
-	unsigned int idx_pipe;
-//	RT_DEBUG_DATA(COMP_SEND, tcb_desc, sizeof(cb_desc));
-#if 0
-	/* Added by Annie for filling Len_Adjust field. 2005-12-14. */
-        RT_ENC_ALG  EncAlg = NO_Encryption;
-#endif
-//	printk("=============> %s\n", __FUNCTION__);
-	pend = atomic_read(&priv->tx_pending[tcb_desc->queue_index]);
-	/* we are locked here so the two atomic_read and inc are executed
-	 * without interleaves
-	 * !!! For debug purpose
-	 */
-	if( pend > MAX_TX_URB){
-#if 0
-		switch (tcb_desc->queue_index) {
-			case VO_PRIORITY:
-				priv->stats.txvodrop++;
-				break;
-			case VI_PRIORITY:
-				priv->stats.txvidrop++;
-				break;
-			case BE_PRIORITY:
-				priv->stats.txbedrop++;
-				break;
-			default://BK_PRIORITY
-				priv->stats.txbkdrop++;
-				break;
-		}
-#endif
-		printk("To discard skb packet!\n");
-		dev_kfree_skb_any(skb);
-		return -1;
-	}
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	tx_urb = usb_alloc_urb(0,GFP_ATOMIC);
-#else
-	tx_urb = usb_alloc_urb(0);
-#endif
-	if(!tx_urb){
-		dev_kfree_skb_any(skb);
-		return -ENOMEM;
-	}
-
-	/* Fill Tx firmware info */
-	memset(tx_fwinfo,0,sizeof(tx_fwinfo_819x_usb));
-	/* DWORD 0 */
-	tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
-	tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate);
-	tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
-	tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc);
-	if(tcb_desc->bAMPDUEnable) {//AMPDU enabled
-		tx_fwinfo->AllowAggregation = 1;
-		/* DWORD 1 */
-		tx_fwinfo->RxMF = tcb_desc->ampdu_factor;
-		tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity
-	} else {
-		tx_fwinfo->AllowAggregation = 0;
-		/* DWORD 1 */
-		tx_fwinfo->RxMF = 0;
-		tx_fwinfo->RxAMD = 0;
-	}
-
-	/* Protection mode related */
-	tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable)?1:0;
-	tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable)?1:0;
-	tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC)?1:0;
-	tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80)?1:0;
-	tx_fwinfo->RtsRate =  MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
-	tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT==0)?(tcb_desc->RTSSC):0;
-	tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT==1)?((tcb_desc->bRTSBW)?1:0):0;
-	tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):\
-				(tcb_desc->bRTSUseShortGI?1:0);
-
-	/* Set Bandwidth and sub-channel settings. */
-	if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
-	{
-		if(tcb_desc->bPacketBW) {
-			tx_fwinfo->TxBandwidth = 1;
-			tx_fwinfo->TxSubCarrier = 0;    //By SD3's Jerry suggestion, use duplicated mode
-		} else {
-			tx_fwinfo->TxBandwidth = 0;
-			tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
-		}
-	} else {
-		tx_fwinfo->TxBandwidth = 0;
-		tx_fwinfo->TxSubCarrier = 0;
-	}
-
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	if (tcb_desc->drv_agg_enable)
-	{
-		tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1;
-	}
-#endif
-	/* Fill Tx descriptor */
-	memset(tx_desc, 0, sizeof(tx_desc_819x_usb));
-	/* DWORD 0 */
-        tx_desc->LINIP = 0;
-        tx_desc->CmdInit = 1;
-        tx_desc->Offset =  sizeof(tx_fwinfo_819x_usb) + 8;
-
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	if (tcb_desc->drv_agg_enable) {
-		tx_desc->PktSize = tcb_desc->pkt_size;
-	} else
-#endif
-	{
-		tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff;
-	}
-
-	/*DWORD 1*/
-	tx_desc->SecCAMID= 0;
-	tx_desc->RATid = tcb_desc->RATRIndex;
-#if 0
-	/* Fill security related */
-	if( pTcb->bEncrypt && !Adapter->MgntInfo.SecurityInfo.SWTxEncryptFlag)
-	{
-		EncAlg = SecGetEncryptionOverhead(
-				Adapter,
-				&EncryptionMPDUHeadOverhead,
-				&EncryptionMPDUTailOverhead,
-				NULL,
-				NULL,
-				FALSE,
-				FALSE);
-		//2004/07/22, kcwu, EncryptionMPDUHeadOverhead has been added in previous code
-		//MPDUOverhead = EncryptionMPDUHeadOverhead + EncryptionMPDUTailOverhead;
-		MPDUOverhead = EncryptionMPDUTailOverhead;
-		tx_desc->NoEnc = 0;
-		RT_TRACE(COMP_SEC, DBG_LOUD, ("******We in the loop SecCAMID is %d SecDescAssign is %d The Sec is %d********\n",tx_desc->SecCAMID,tx_desc->SecDescAssign,EncAlg));
-		//CamDumpAll(Adapter);
-	}
-	else
-#endif
-	{
-		//MPDUOverhead = 0;
-		tx_desc->NoEnc = 1;
-	}
-#if 0
-	switch(EncAlg){
-		case NO_Encryption:
-			tx_desc->SecType = 0x0;
-			break;
-		case WEP40_Encryption:
-		case WEP104_Encryption:
-			tx_desc->SecType = 0x1;
-			break;
-		case TKIP_Encryption:
-			tx_desc->SecType = 0x2;
-			break;
-		case AESCCMP_Encryption:
-			tx_desc->SecType = 0x3;
-			break;
-		default:
-			tx_desc->SecType = 0x0;
-			break;
-	}
-#else
-	tx_desc->SecType = 0x0;
-#endif
-		if (tcb_desc->bHwSec)
-			{
-				switch (priv->ieee80211->pairwise_key_type)
-				{
-					case KEY_TYPE_WEP40:
-					case KEY_TYPE_WEP104:
-						 tx_desc->SecType = 0x1;
-						 tx_desc->NoEnc = 0;
-						 break;
-					case KEY_TYPE_TKIP:
-						 tx_desc->SecType = 0x2;
-						 tx_desc->NoEnc = 0;
-						 break;
-					case KEY_TYPE_CCMP:
-						 tx_desc->SecType = 0x3;
-						 tx_desc->NoEnc = 0;
-						 break;
-					case KEY_TYPE_NA:
-						 tx_desc->SecType = 0x0;
-						 tx_desc->NoEnc = 1;
-						 break;
-				}
-			}
-
-	tx_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
-	tx_desc->TxFWInfoSize =  sizeof(tx_fwinfo_819x_usb);
-
-	tx_desc->DISFB = tcb_desc->bTxDisableRateFallBack;
-	tx_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
-
-        /* Fill fields that are required to be initialized in all of the descriptors */
-        //DWORD 0
-#if 0
-        tx_desc->FirstSeg = (tcb_desc->bFirstSeg)? 1:0;
-        tx_desc->LastSeg = (tcb_desc->bLastSeg)?1:0;
-#else
-        tx_desc->FirstSeg = 1;
-        tx_desc->LastSeg = 1;
-#endif
-        tx_desc->OWN = 1;
-
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	if (tcb_desc->drv_agg_enable) {
-		tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb);
-	} else
-#endif
-	{
-		//DWORD 2
-		tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN);
-	}
-	/* Get index to out pipe from specified QueueID */
-#ifndef USE_ONE_PIPE
-	idx_pipe = txqueue2outpipe(priv,tcb_desc->queue_index);
-#else
-	idx_pipe = 0x5;
-#endif
-
-	//RT_DEBUG_DATA(COMP_SEND,tx_fwinfo,sizeof(tx_fwinfo_819x_usb));
-	//RT_DEBUG_DATA(COMP_SEND,tx_desc,sizeof(tx_desc_819x_usb));
-
-	/* To submit bulk urb */
-	usb_fill_bulk_urb(tx_urb,udev,
-			usb_sndbulkpipe(udev,idx_pipe), skb->data,
-			skb->len, rtl8192_tx_isr, skb);
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	status = usb_submit_urb(tx_urb, GFP_ATOMIC);
-#else
-	status = usb_submit_urb(tx_urb);
-#endif
 	if (!status){
 //we need to send 0 byte packet whenever 512N bytes/64N(HIGN SPEED/NORMAL SPEED) bytes packet has been transmitted. Otherwise, it will be halt to wait for another packet. WB. 2008.08.27
 		bool bSend0Byte = false;
@@ -3994,11 +2355,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
 		if (bSend0Byte)
 		{
 #if 1
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 			tx_urb_zero = usb_alloc_urb(0,GFP_ATOMIC);
-#else
-			tx_urb_zero = usb_alloc_urb(0);
-#endif
 			if(!tx_urb_zero){
 				RT_TRACE(COMP_ERR, "can't alloc urb for zero byte\n");
 				return -ENOMEM;
@@ -4006,11 +2363,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
 			usb_fill_bulk_urb(tx_urb_zero,udev,
 					usb_sndbulkpipe(udev,idx_pipe), &zero,
 					0, tx_zero_isr, dev);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 			status = usb_submit_urb(tx_urb_zero, GFP_ATOMIC);
-#else
-			status = usb_submit_urb(tx_urb_zero);
-#endif
 			if (status){
 			RT_TRACE(COMP_ERR, "Error TX URB for zero byte %d, error %d", atomic_read(&priv->tx_pending[tcb_desc->queue_index]), status);
 			return -1;
@@ -4026,49 +2379,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
 		return -1;
 	}
 }
-#endif
-
-#if 0
-void rtl8192_set_rate(struct net_device *dev)
-{
-	int i;
-	u16 word;
-	int basic_rate,min_rr_rate,max_rr_rate;
-
-//	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	//if (ieee80211_is_54g(priv->ieee80211->current_network) &&
-//		priv->ieee80211->state == IEEE80211_LINKED){
-	basic_rate = ieeerate2rtlrate(240);
-	min_rr_rate = ieeerate2rtlrate(60);
-	max_rr_rate = ieeerate2rtlrate(240);
-
-//
-//	}else{
-//		basic_rate = ieeerate2rtlrate(20);
-//		min_rr_rate = ieeerate2rtlrate(10);
-//		max_rr_rate = ieeerate2rtlrate(110);
-//	}
-
-	write_nic_byte(dev, RESP_RATE,
-			max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
-
-	//word  = read_nic_word(dev, BRSR);
-	word  = read_nic_word(dev, BRSR_8187);
-	word &= ~BRSR_MBR_8185;
-
-
-	for(i=0;i<=basic_rate;i++)
-		word |= (1<<i);
 
-	//write_nic_word(dev, BRSR, word);
-	write_nic_word(dev, BRSR_8187, word);
-	//DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE), read_nic_word(dev,BRSR));
-}
-#endif
-
-
-#ifdef RTL8192SU
 void rtl8192SU_net_update(struct net_device *dev)
 {
 
@@ -4088,11 +2399,7 @@ void rtl8192SU_net_update(struct net_device *dev)
 	//update Basic rate: RR, BRSR
 	rtl8192_config_rate(dev, &rate_config);	//HalSetBrateCfg
 
-#ifdef RTL8192SU_DISABLE_CCK_RATE
-	priv->basic_rate = rate_config  = rate_config & 0x150; // Disable CCK 11M, 5.5M, 2M, and 1M rates.
-#else
 	priv->basic_rate = rate_config  = rate_config & 0x15f;
-#endif
 
 	// Set RRSR rate table.
 	write_nic_byte(dev, RRSR, rate_config&0xff);
@@ -4221,11 +2528,7 @@ void rtl8192SU_update_ratr_table(struct net_device* dev)
 			break;
 	}
 
-#ifdef RTL8192SU_DISABLE_CCK_RATE
-	ratr_value &= 0x0FFFFFF0;
-#else
 	ratr_value &= 0x0FFFFFFF;
-#endif
 
 	// Get MAX MCS available.
 	if (   (bNMode && ((ieee->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_SHORT_GI)==0)) &&
@@ -4287,42 +2590,6 @@ void rtl8192SU_link_change(struct net_device *dev)
 
 	printk("<=====%s 2\n", __func__);
 }
-#else
-extern void rtl8192_update_ratr_table(struct net_device* dev);
-void rtl8192_link_change(struct net_device *dev)
-{
-//	int i;
-
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device* ieee = priv->ieee80211;
-	//write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
-	if (ieee->state == IEEE80211_LINKED)
-	{
-		rtl8192_net_update(dev);
-		rtl8192_update_ratr_table(dev);
-#if 1
-		//add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
-		if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
-		EnableHWSecurityConfig8192(dev);
-#endif
-	}
-	/*update timing params*/
-//	RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
-//	rtl8192_set_chan(dev, priv->chan);
-	 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
-        {
-                u32 reg = 0;
-                reg = read_nic_dword(dev, RCR);
-                if (priv->ieee80211->state == IEEE80211_LINKED)
-                        priv->ReceiveConfig = reg |= RCR_CBSSID;
-                else
-                        priv->ReceiveConfig = reg &= ~RCR_CBSSID;
-                write_nic_dword(dev, RCR, reg);
-        }
-
-//	rtl8192_set_rxconf(dev);
-}
-#endif
 
 static struct ieee80211_qos_parameters def_qos_parameters = {
         {3,3,3,3},/* cw_min */
@@ -4333,16 +2600,10 @@ static struct ieee80211_qos_parameters def_qos_parameters = {
 };
 
 
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
 void rtl8192_update_beacon(struct work_struct * work)
 {
         struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
         struct net_device *dev = priv->ieee80211->dev;
-#else
-void rtl8192_update_beacon(struct net_device *dev)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
  	struct ieee80211_device* ieee = priv->ieee80211;
 	struct ieee80211_network* net = &ieee->current_network;
 
@@ -4357,16 +2618,11 @@ void rtl8192_update_beacon(struct net_device *dev)
 * background support to run QoS activate functionality
 */
 int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+
 void rtl8192_qos_activate(struct work_struct * work)
 {
         struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
         struct net_device *dev = priv->ieee80211->dev;
-#else
-void rtl8192_qos_activate(struct net_device *dev)
-{
-        struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
         struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
         u8 mode = priv->ieee80211->current_network.mode;
         //u32 size = sizeof(struct ieee80211_qos_parameters);
@@ -4377,11 +2633,8 @@ void rtl8192_qos_activate(struct net_device *dev)
         if (priv == NULL)
                 return;
 
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
-	down(&priv->mutex);
-#else
        mutex_lock(&priv->mutex);
-#endif
+
         if(priv->ieee80211->state != IEEE80211_LINKED)
 		goto success;
 	RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
@@ -4401,11 +2654,7 @@ void rtl8192_qos_activate(struct net_device *dev)
 	}
 
 success:
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
-	up(&priv->mutex);
-#else
        mutex_unlock(&priv->mutex);
-#endif
 }
 
 static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
@@ -4432,11 +2681,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
 				 network->qos_data.param_count)) {
 			network->qos_data.old_param_count =
 				network->qos_data.param_count;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 			queue_work(priv->priv_wq, &priv->qos_activate);
-#else
-			schedule_task(&priv->qos_activate);
-#endif
 			RT_TRACE (COMP_QOS, "QoS parameters change call "
 					"qos_activate\n");
 		}
@@ -4445,11 +2690,7 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
 		       &def_qos_parameters, size);
 
 		if ((network->qos_data.active == 1) && (active_network == 1)) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 			queue_work(priv->priv_wq, &priv->qos_activate);
-#else
-			schedule_task(&priv->qos_activate);
-#endif
 			RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
 		}
 		network->qos_data.active = 0;
@@ -4461,22 +2702,14 @@ static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
 
 /* handle manage frame frame beacon and probe response */
 static int rtl8192_handle_beacon(struct net_device * dev,
-                              struct ieee80211_beacon * beacon,
-                              struct ieee80211_network * network)
+				 struct ieee80211_probe_response *beacon,
+				 struct ieee80211_network *network)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
 	rtl8192_qos_handle_probe_response(priv,1,network);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 	queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
-#else
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	schedule_task(&priv->update_beacon_wq);
-#else
-	queue_work(priv->priv_wq, &priv->update_beacon_wq);
-#endif
 
-#endif
 	return 0;
 
 }
@@ -4509,10 +2742,6 @@ static int rtl8192_qos_association_resp(struct r8192_priv *priv,
 			 &network->qos_data.parameters,\
 			sizeof(struct ieee80211_qos_parameters));
 		priv->ieee80211->current_network.qos_data.active = 1;
-#if 0
-		if((priv->ieee80211->current_network.qos_data.param_count != \
-					network->qos_data.param_count))
-#endif
 		 {
                         set_qos_param = 1;
 			/* update qos parameter for current network */
@@ -4533,12 +2762,7 @@ static int rtl8192_qos_association_resp(struct r8192_priv *priv,
 
 	RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
 	if (set_qos_param == 1)
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 		queue_work(priv->priv_wq, &priv->qos_activate);
-#else
-		schedule_task(&priv->qos_activate);
-#endif
-
 
         return ret;
 }
@@ -4614,9 +2838,7 @@ bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
         int wpa_ie_len= ieee->wpa_ie_len;
         struct ieee80211_crypt_data* crypt;
         int encrypt;
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
 	return TRUE;
-#endif
 
         crypt = ieee->crypt[ieee->tx_keyidx];
 	//we use connecting AP's capability instead of only security config on our driver to distinguish whether it should use N mode or G mode
@@ -4638,18 +2860,6 @@ bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
 		return true;
 	}
 
-#if 0
-        //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
-        //We can't force in G mode if Pairwie key is AES and group key is TKIP
-        if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption)  ||
-           (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
-           (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
-        {
-                return  false;
-        }
-        else
-                return true;
-#endif
 	return true;
 #endif
 }
@@ -4661,9 +2871,7 @@ bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
 	struct ieee80211_device* ieee = priv->ieee80211;
 
 // 	Added by Roger, 2008.08.29.
-#ifdef RTL8192SU
 	return false;
-#endif
 
 	if(ieee->bHalfWirelessN24GMode == true)
 		Reval = true;
@@ -4745,10 +2953,8 @@ void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
 #ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
 	ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
 #endif
-#ifdef RTL8192SU
 	//LZM 090306 usb crash here, mark it temp
 	//write_nic_word(dev, SIFS_OFDM, 0x0e0e);
-#endif
 	priv->ieee80211->mode = wireless_mode;
 
 	if ((wireless_mode == WIRELESS_MODE_N_24G) ||  (wireless_mode == WIRELESS_MODE_N_5G))
@@ -4779,13 +2985,7 @@ short rtl8192_is_tx_queue_empty(struct net_device *dev)
 	}
 	return 1;
 }
-#if 0
-void rtl8192_rq_tx_ack(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	priv->ieee80211->ack_tx_to_ieee = 1;
-}
-#endif
+
 void rtl8192_hw_sleep_down(struct net_device *dev)
 {
 	RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
@@ -4793,7 +2993,7 @@ void rtl8192_hw_sleep_down(struct net_device *dev)
 //	MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
 #endif
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 void rtl8192_hw_sleep_wq (struct work_struct *work)
 {
 //      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
@@ -4802,10 +3002,7 @@ void rtl8192_hw_sleep_wq (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,hw_sleep_wq);
         struct net_device *dev = ieee->dev;
-#else
-void rtl8192_hw_sleep_wq(struct net_device* dev)
-{
-#endif
+
 	//printk("=========>%s()\n", __FUNCTION__);
         rtl8192_hw_sleep_down(dev);
 }
@@ -4823,7 +3020,7 @@ void rtl8192_hw_wakeup(struct net_device* dev)
 	//FIXME: will we send package stored while nic is sleep?
 //	spin_unlock_irqrestore(&priv->ps_lock,flags);
 }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+
 void rtl8192_hw_wakeup_wq (struct work_struct *work)
 {
 //	struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
@@ -4832,12 +3029,8 @@ void rtl8192_hw_wakeup_wq (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,hw_wakeup_wq);
 	struct net_device *dev = ieee->dev;
-#else
-void rtl8192_hw_wakeup_wq(struct net_device* dev)
-{
-#endif
-	rtl8192_hw_wakeup(dev);
 
+	rtl8192_hw_wakeup(dev);
 }
 
 #define MIN_SLEEP_TIME 50
@@ -4881,11 +3074,7 @@ void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
 		u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
 	//	if (tl<rb)
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		schedule_task(&priv->ieee80211->hw_wakeup_wq);
-#else
 		queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
-#endif
 	}
 	/* if we suspect the TimerInt is gone beyond tl
 	 * while setting it, then give up
@@ -4902,11 +3091,8 @@ void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
 //		priv->rf_sleep(dev);
 
 	//printk("<=========%s()\n", __FUNCTION__);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	schedule_task(&priv->ieee80211->hw_sleep_wq);
-#else
 	queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
-#endif
+
 	spin_unlock_irqrestore(&priv->ps_lock,flags);
 }
 //init priv variables here. only non_zero value should be initialized here.
@@ -4977,7 +3163,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev)
 	priv->ieee80211->InitialGainHandler = priv->ops->rtl819x_initial_gain;
 	priv->card_type = USB;
 
-#ifdef RTL8192SU
 //1 RTL8192SU/
 	priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
 	priv->ieee80211->SetFwCmdHandler = HalSetFwCmd8192S;
@@ -5036,51 +3221,6 @@ static void rtl8192_init_priv_variable(struct net_device* dev)
 
 //1 End
 
-#else
-
-#ifdef TO_DO_LIST
-	if(Adapter->bInHctTest)
-  	{
-		pHalData->ShortRetryLimit = 7;
-		pHalData->LongRetryLimit = 7;
-  	}
-#endif
-	{
-		priv->ShortRetryLimit = 0x30;
-		priv->LongRetryLimit = 0x30;
-	}
-	priv->EarlyRxThreshold = 7;
-	priv->enable_gpio0 = 0;
-	priv->TransmitConfig =
-	//	TCR_DurProcMode |	//for RTL8185B, duration setting by HW
-	//?	TCR_DISReqQsize |
-                (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)|  // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
-		(priv->ShortRetryLimit<<TCR_SRL_OFFSET)|	// Short retry limit
-		(priv->LongRetryLimit<<TCR_LRL_OFFSET) |	// Long retry limit
-		(false ? TCR_SAT: 0);	// FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
-#ifdef TO_DO_LIST
-	if(Adapter->bInHctTest)
-		pHalData->ReceiveConfig	=	pHalData->CSMethod |
-						RCR_AMF | RCR_ADF |	//RCR_AAP | 	//accept management/data
-						//guangan200710
-						RCR_ACF |	//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
-						RCR_AB | RCR_AM | RCR_APM |		//accept BC/MC/UC
-						RCR_AICV | RCR_ACRC32 | 		//accept ICV/CRC error packet
-						((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
-						(pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
-						(pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
-	else
-
-#endif
-	priv->ReceiveConfig	=
-		RCR_AMF | RCR_ADF |		//accept management/data
-		RCR_ACF |			//accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
-		RCR_AB | RCR_AM | RCR_APM |	//accept BC/MC/UC
-		//RCR_AICV | RCR_ACRC32 | 	//accept ICV/CRC error packet
-		((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
-		(priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
-		(priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
-#endif
 
 	priv->AcmControl = 0;
 	priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
@@ -5113,18 +3253,10 @@ static void rtl8192_init_priv_lock(struct r8192_priv* priv)
 	sema_init(&priv->wx_sem,1);
 	sema_init(&priv->rf_sem,1);
 	spin_lock_init(&priv->ps_lock);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
-	sema_init(&priv->mutex, 1);
-#else
 	mutex_init(&priv->mutex);
-#endif
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
-#else
-extern  void    rtl819x_watchdog_wqcallback(struct net_device *dev);
-#endif
 
 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
 //init tasklet and wait_queue here. only 2.6 above kernel is considered
@@ -5133,15 +3265,12 @@ static void rtl8192_init_priv_task(struct net_device* dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 #ifdef PF_SYNCTHREAD
 	priv->priv_wq = create_workqueue(DRV_NAME,0);
 #else
 	priv->priv_wq = create_workqueue(DRV_NAME);
 #endif
-#endif
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 	INIT_WORK(&priv->reset_wq, rtl8192_restart);
 
 	//INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
@@ -5157,36 +3286,6 @@ static void rtl8192_init_priv_task(struct net_device* dev)
 	INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
 	INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
 
-#else
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-	tq_init(&priv->reset_wq, (void*)rtl8192_restart, dev);
-	tq_init(&priv->watch_dog_wq, (void*)rtl819x_watchdog_wqcallback, dev);
-	tq_init(&priv->txpower_tracking_wq, (void*)dm_txpower_trackingcallback, dev);
-	tq_init(&priv->rfpath_check_wq, (void*)dm_rf_pathcheck_workitemcallback, dev);
-	tq_init(&priv->update_beacon_wq, (void*)rtl8192_update_beacon, dev);
-	//tq_init(&priv->SwChnlWorkItem, (void*) rtl8192_SwChnl_WorkItem, dev);
-	//tq_init(&priv->SetBWModeWorkItem, (void*)rtl8192_SetBWModeWorkItem, dev);
-	tq_init(&priv->qos_activate, (void *)rtl8192_qos_activate, dev);
-	tq_init(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
-	tq_init(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
-
-#else
-	INIT_WORK(&priv->reset_wq,(void(*)(void*)) rtl8192_restart,dev);
-	//INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) hal_dm_watchdog,dev);
-	INIT_WORK(&priv->watch_dog_wq, (void(*)(void*)) rtl819x_watchdog_wqcallback,dev);
-	INIT_WORK(&priv->txpower_tracking_wq, (void(*)(void*)) dm_txpower_trackingcallback,dev);
-//	INIT_WORK(&priv->gpio_change_rf_wq, (void(*)(void*)) dm_gpio_change_rf_callback,dev);
-	INIT_WORK(&priv->rfpath_check_wq, (void(*)(void*)) dm_rf_pathcheck_workitemcallback,dev);
-	INIT_WORK(&priv->update_beacon_wq, (void(*)(void*))rtl8192_update_beacon,dev);
-	INIT_WORK(&priv->initialgain_operate_wq, (void(*)(void*))InitialGainOperateWorkItemCallBack,dev);
-	//INIT_WORK(&priv->SwChnlWorkItem, (void(*)(void*)) rtl8192_SwChnl_WorkItem, dev);
-	//INIT_WORK(&priv->SetBWModeWorkItem, (void(*)(void*)) rtl8192_SetBWModeWorkItem, dev);
-	INIT_WORK(&priv->qos_activate, (void(*)(void *))rtl8192_qos_activate, dev);
-	INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq, dev);
-	INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq, dev);
-#endif
-#endif
-
 	tasklet_init(&priv->irq_rx_tasklet,
 	     (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
 	     (unsigned long)priv);
@@ -5212,7 +3311,6 @@ static inline u16 endian_swap(u16* data)
 	return *data;
 }
 
-#ifdef RTL8192SU
 u8 rtl8192SU_UsbOptionToEndPointNumber(u8 UsbOption)
 {
 	u8	nEndPoint = 0;
@@ -5342,26 +3440,6 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
 	priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
 
 
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-	for(i=0; i<6; i++)
-		{
-		priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
-		}
-
-		for(i=0; i<14; i++)
-		{
-		priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
-			priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
-		}
-
-	//
-	// Update HAL variables.
-	//
-	memcpy( priv->TxPowerLevelOFDM24G, priv->EEPROMTxPowerLevelOFDM24G, 14);
-	memcpy( priv->TxPowerLevelCCK, priv->EEPROMTxPowerLevelCCK24G, 14);
-	//RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("HAL CCK 2.4G TxPwr: \n"), priv->TxPowerLevelCCK, 14);
-	//RT_PRINT_DATA(COMP_INIT|COMP_EFUSE, DBG_LOUD, ("HAL OFDM 2.4G TxPwr: \n"), priv->TxPowerLevelOFDM24G, 14);
-#else
 
 	for (rf_path = 0; rf_path < 2; rf_path++)
 	{
@@ -5411,7 +3489,6 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
 		//priv->RfTxPwrLevelOfdm1T[0][i] ,
 		//priv->RfTxPwrLevelOfdm2T[0][i] );
 		}
-#endif
 
 	//
 	// Update remained HAL variables.
@@ -5431,747 +3508,6 @@ rtl8192SU_ConfigAdapterInfo8192SForAutoLoadFail(struct net_device* dev)
 
 }
 
-#if 0
-static void rtl8192SU_ReadAdapterInfo8192SEEPROM(struct net_device* dev)
-{
-	u16 				EEPROMId = 0;
-	u8 				bLoad_From_EEPOM = false;
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	u16 				tmpValue = 0;
-	u8				tmpBuffer[30];
-	int i;
-
-	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
-
-
-	write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
-	udelay(10000);
-	write_nic_byte(dev, PMC_FSM, 0x02); // Enable Loader Data Keep
-
-
-	EEPROMId = eprom_read(dev, 0); //first read EEPROM ID out;
-	RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", EEPROMId);
-
-	if (EEPROMId != RTL8190_EEPROM_ID)
-	{
-		priv->AutoloadFailFlag = true;
-		RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", EEPROMId, RTL8190_EEPROM_ID);
-	}
-	else
-	{
-		priv->AutoloadFailFlag = false;
-		bLoad_From_EEPOM = true;
-	}
-
-	if (bLoad_From_EEPOM)
-	{
-		tmpValue = eprom_read(dev, (EEPROM_VID>>1));
-		priv->eeprom_vid = endian_swap(&tmpValue);
-		priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
-
-		// Version ID, Channel plan
-		tmpValue = eprom_read(dev, (EEPROM_Version>>1));
-		//pHalData->card_8192_version = (VERSION_8192S)((usValue&0x00ff));
-		priv->eeprom_ChannelPlan =(tmpValue&0xff00)>>8;
-		priv->bTXPowerDataReadFromEEPORM = true;
-
-		// Customer ID, 0x00 and 0xff are reserved for Realtek.
-		tmpValue = eprom_read(dev, (u16)(EEPROM_CustomID>>1)) ;
-		priv->eeprom_CustomerID = (u8)( tmpValue & 0xff);
-		priv->eeprom_SubCustomerID = (u8)((tmpValue & 0xff00)>>8);
-	}
-	else
-	{
-		priv->eeprom_vid = 0;
-		priv->eeprom_pid = 0;
-		//priv->card_8192_version = VERSION_8192SU_A;
-		priv->eeprom_ChannelPlan = 0;
-		priv->eeprom_CustomerID = 0;
-		priv->eeprom_SubCustomerID = 0;
-	}
-	RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
-	//set channelplan from eeprom
-	priv->ChannelPlan = priv->eeprom_ChannelPlan;// FIXLZM
-
-	RT_TRACE(COMP_INIT, "EEPROMId = 0x%4x\n", EEPROMId);
-	RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
-	RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
-	//RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM Version ID: 0x%2x\n", pHalData->VersionID));
-	RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
-	RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
-	RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
-
-	// Read USB optional function.
-	if(bLoad_From_EEPOM)
-	{
-		tmpValue = eprom_read(dev, (EEPROM_USB_OPTIONAL>>1));
-		priv->EEPROMUsbOption = (u8)(tmpValue&0xff);
-	}
-	else
-	{
-		priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
-	}
-
-	RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
-
-
-	if (bLoad_From_EEPOM)
-	{
-		int i;
-		for (i=0; i<6; i+=2)
-		{
-			u16 tmp = 0;
-			tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
-			*(u16*)(&dev->dev_addr[i]) = tmp;
-		}
-	}
-	else
-	{
-		//<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
-		static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
-		u8	i;
-
-		//sMacAddr[5] = (u8)GetRandomNumber(1, 254);
-
-		for(i = 0; i < 6; i++)
-			dev->dev_addr[i] = sMacAddr[i];
-
-		//memcpy(dev->dev_addr, sMacAddr, 6);
-		//should I set IDR0 here?
-	}
-	write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
-	write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
-	RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
-
-	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
-	priv->rf_chip = RF_6052;
-	priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
-	//priv->card_8192_version = VERSION_8192SU_A; //Over write for temporally experiment. 2008.10.16. By Roger.
-#else
-	priv->rf_chip = RF_8256;
-#endif
-
-	{
-#if 0
-		if(bLoad_From_EEPOM)
-		{
-			tempval = (ReadEEprom(Adapter, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
-			if (tempval&0x80)	//RF-indication, bit[7]
-				pHalData->RF_Type = RF_1T2R;
-			else
-				pHalData->RF_Type = RF_2T4R;
-		}
-#endif
-
-		priv->EEPROMTxPowerDiff = EEPROM_Default_TxPowerDiff;
-		RT_TRACE(COMP_INIT, "TxPowerDiff = %#x\n", priv->EEPROMTxPowerDiff);
-
-
-		//
-		// Read antenna tx power offset of B/C/D to A  from EEPROM
-		// and read ThermalMeter from EEPROM
-		//
-		if(bLoad_From_EEPOM)
-		{
-			tmpValue = eprom_read(dev, (EEPROM_PwDiff>>1));
-			priv->EEPROMPwDiff = tmpValue&0x00ff;
-			priv->EEPROMThermalMeter = (tmpValue&0xff00)>>8;
-		}
-		else
-		{
-			priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
-			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
-		}
-		RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMPwDiff);
-		RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
-
-		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
-
-
-		// Read CrystalCap from EEPROM
-		if(bLoad_From_EEPOM)
-		{
-			priv->EEPROMCrystalCap =(u8) (((eprom_read(dev, (EEPROM_CrystalCap>>1)))&0xf000)>>12);
-		}
-		else
-		{
-			priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
-		}
-		RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
-
-
-		//if(pHalData->EEPROM_Def_Ver == 0)	// old eeprom definition
-		{
-
-			//
-			// Get Tx Power Base.//===>
-			//
-			if(bLoad_From_EEPOM)
-			{
-				priv->EEPROMTxPwrBase =(u8) ((eprom_read(dev, (EEPROM_TxPowerBase>>1)))&0xff);
-			}
-			else
-			{
-				priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
-			}
-
-			RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
-
-			//
-			// Get CustomerID(Boad Type)
-			// i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
-			// Others: Reserved. Default is 0x2: RTL8192SU.
-			//
-			if(bLoad_From_EEPOM)
-			{
-				tmpValue = eprom_read(dev, (u16) (EEPROM_BoardType>>1));
-				priv->EEPROMBoardType = (u8)(tmpValue&0xff);
-			}
-			else
-			{
-				priv->EEPROMBoardType = EEPROM_Default_BoardType;
-			}
-
-			RT_TRACE(COMP_INIT, "BoardType = %#x\n", priv->EEPROMBoardType);
-
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-
-			//
-			// Buffer TxPwIdx(i.e., from offset 0x58~0x75, total 30Bytes)
-			//
-			if(bLoad_From_EEPOM)
-			{
-				for(i = 0; i < 30; i += 2)
-				{
-					tmpValue = eprom_read(dev, (u16) ((EEPROM_TxPowerBase+i)>>1));
-					*((u16 *)(&tmpBuffer[i])) = tmpValue;
-				}
-			}
-
-			//
-			// Update CCK, OFDM Tx Power Index from above buffer.
-			//
-			if(bLoad_From_EEPOM)
-			{
-				for(i=0; i<14; i++)
-				{
-					priv->EEPROMTxPowerLevelCCK24G[i] = (u8)tmpBuffer[i+1];
-					priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)tmpBuffer[i+15];
-				}
-
-			}
-			else
-			{
-				for(i=0; i<14; i++)
-				{
-					priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
-					priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
-				}
-			}
-
-			for(i=0; i<14; i++)
-			{
-				RT_TRACE(COMP_INIT, "CCK 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK24G[i]);
-				RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
-			}
-#else
-			// Please add code in the section!!!!
-			// And merge tx power difference section.
-#endif
-
-			//
-			// Get TSSI value for each path.
-			//
-			if(bLoad_From_EEPOM)
-			{
-				tmpValue = eprom_read(dev, (u16) ((EEPROM_TSSI_A)>>1));
-				priv->EEPROMTSSI_A = (u8)((tmpValue&0xff00)>>8);
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
-			}
-
-			if(bLoad_From_EEPOM)
-			{
-				tmpValue = eprom_read(dev, (u16) ((EEPROM_TSSI_B)>>1));
-				priv->EEPROMTSSI_B = (u8)(tmpValue&0xff);
-				priv->EEPROMTxPwrTkMode = (u8)((tmpValue&0xff00)>>8);
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
-				priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
-			}
-
-			RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n", priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
-			RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
-
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-			//
-			// Get HT 2T Path A and B Power Index.
-			//
-			if(bLoad_From_EEPOM)
-			{
-				for(i = 0; i < 6; i += 2)
-				{
-					tmpValue = eprom_read(dev, (u16) ((EEPROM_HT2T_CH1_A+i)>>1));
-					*((u16*)(&priv->EEPROMHT2T_TxPwr[i])) = tmpValue;
-				}
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				for(i=0; i<6; i++)
-				{
-					priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
-				}
-			}
-
-			for(i=0; i<6; i++)
-			{
-				RT_TRACE(COMP_INIT, "EEPROMHT2T_TxPwr, Index %d = 0x%02x\n", i, priv->EEPROMHT2T_TxPwr[i]);
-			}
-#else
-
-#endif
-		}
-
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-		//
-		// Update HAL variables.
-		//
-		for(i=0; i<14; i++)
-		{
-			priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
-			priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK24G[i];
-		}
-#else
-
-#endif
-		priv->TxPowerDiff = priv->EEPROMPwDiff;
-		// Antenna B gain offset to antenna A, bit0~3
-		priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
-		// Antenna C gain offset to antenna A, bit4~7
-		priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
-		// CrystalCap, bit12~15
-		priv->CrystalCap = priv->EEPROMCrystalCap;
-		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
-		// 92U does not enable TX power tracking.
-		priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
-	}
-
-	priv->LedStrategy = SW_LED_MODE0;
-
-	if(priv->rf_type == RF_1T2R)
-	{
-		RT_TRACE(COMP_EPROM, "\n1T2R config\n");
-	}
-	else
-	{
-		RT_TRACE(COMP_EPROM, "\n2T4R config\n");
-	}
-
-	// 2008/01/16 MH We can only know RF type in the function. So we have to init
-	// DIG RATR table again.
-	init_rate_adaptive(dev);
-	//we need init DIG RATR table here again.
-
-	RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
-	return;
-}
-
-//
-//	Description:
-//		1. Read HW adapter information by E-Fuse.
-//		2. Refered from SD1 Richard.
-//
-//	Assumption:
-//		1. Boot from E-Fuse and CR9346 regiser has verified.
-//		2. PASSIVE_LEVEL (USB interface)
-//
-//	Created by Roger, 2008.10.21.
-//
-void
-rtl8192SU_ReadAdapterInfo8192SEFuse(struct net_device* dev)
-{
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	u16			i,usValue;
-	u16			EEPROMId;
-	u8			readbyte;
-	u8			OFDMTxPwr[14];
-	u8			CCKTxPwr[14];
-	u8			HT2T_TxPwr[6];
-	u8			UsbPhyParam[5];
-	u8			hwinfo[HWSET_MAX_SIZE_92S];
-
-
-	RT_TRACE(COMP_INIT, "====> ReadAdapterInfo8192SEFuse\n");
-
-	//
-	// <Roger_Notes> We set Isolation signals from Loader and reset EEPROM after system resuming
-	// from suspend mode.
-	// 2008.10.21.
-	//
-	write_nic_byte(dev, SYS_ISO_CTRL+1, 0xE8); // Isolation signals from Loader
-	//PlatformStallExecution(10000);
-	mdelay(10);
-	write_nic_byte(dev, SYS_FUNC_EN+1, 0x40);
-	write_nic_byte(dev, SYS_FUNC_EN+1, 0x50);
-
-	readbyte = read_nic_byte(dev, EFUSE_TEST+3);
-	write_nic_byte(dev, EFUSE_TEST+3, (readbyte | 0x80));
-	write_nic_byte(dev, EFUSE_TEST+3, 0x72);
-	write_nic_byte(dev, EFUSE_CLK, 0x03);
-
-	//
-	// Dump EFUSe at init time for later use
-	//
-	// Read EFUSE real map to shadow!!
-	EFUSE_ShadowMapUpdate(dev);
-
-	memcpy(hwinfo, (void*)&priv->EfuseMap[EFUSE_INIT_MAP][0], HWSET_MAX_SIZE_92S);
-	//RT_PRINT_DATA(COMP_INIT, DBG_LOUD, ("MAP \n"), hwinfo, HWSET_MAX_SIZE_92S);
-
-	//
-	// <Roger_Notes> Event though CR9346 regiser can verify whether Autoload is success or not, but we still
-	// double check ID codes for 92S here(e.g., due to HW GPIO polling fail issue).
-	// 2008.10.21.
-	//
-	ReadEFuse(dev, 0, 2, (unsigned char*) &EEPROMId);
-
-	if( EEPROMId != RTL8190_EEPROM_ID )
-	{
-		RT_TRACE(COMP_INIT, "EEPROM ID(%#x) is invalid!!\n", EEPROMId);
-		priv->AutoloadFailFlag=true;
-	}
-	else
-	{
-		priv->AutoloadFailFlag=false;
-	}
-
-       // Read IC Version && Channel Plan
-	if(!priv->AutoloadFailFlag)
-	{
-
-        	// VID, PID
-	    	ReadEFuse(dev, EEPROM_VID, 2, (unsigned char*) &priv->eeprom_vid);
-		ReadEFuse(dev, EEPROM_PID, 2, (unsigned char*) &priv->eeprom_pid);
-
-		// Version ID, Channel plan
-		ReadEFuse(dev, EEPROM_Version, 2, (unsigned char*) &usValue);
-		//pHalData->VersionID = (VERSION_8192S)(usValue&0x00ff);
-		priv->eeprom_ChannelPlan = (usValue&0xff00>>8);
-		priv->bTXPowerDataReadFromEEPORM = true;
-
-		// Customer ID, 0x00 and 0xff are reserved for Realtek.
-		ReadEFuse(dev, EEPROM_CustomID, 2, (unsigned char*) &usValue);
-		priv->eeprom_CustomerID = (u8)( usValue & 0xff);
-		priv->eeprom_SubCustomerID = (u8)((usValue & 0xff00)>>8);
-	}
-	else
-	{
-		priv->eeprom_vid = 0;
-		priv->eeprom_pid = 0;
-		priv->eeprom_ChannelPlan = 0;
-		priv->eeprom_CustomerID = 0;
-		priv->eeprom_SubCustomerID = 0;
-	}
-
-	RT_TRACE(COMP_INIT, "EEPROM Id = 0x%4x\n", EEPROMId);
-	RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
-	RT_TRACE(COMP_INIT, "EEPROM PID = 0x%4x\n", priv->eeprom_pid);
-	//RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROM Version ID: 0x%2x\n", pHalData->VersionID));
-	RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
-	RT_TRACE(COMP_INIT, "EEPROM SubCustomer ID: 0x%2x\n", priv->eeprom_SubCustomerID);
-	RT_TRACE(COMP_INIT, "EEPROM ChannelPlan = 0x%4x\n", priv->eeprom_ChannelPlan);
-
-
-	// Read USB optional function.
-	if(!priv->AutoloadFailFlag)
-	{
-		ReadEFuse(dev, EEPROM_USB_OPTIONAL, 1, (unsigned char*) &priv->EEPROMUsbOption);
-	}
-	else
-	{
-		priv->EEPROMUsbOption = EEPROM_USB_Default_OPTIONAL_FUNC;
-	}
-
-	RT_TRACE(COMP_INIT, "USB Option = %#x\n", priv->EEPROMUsbOption);
-
-
-	// Read USB PHY parameters.
-	if(!priv->AutoloadFailFlag)
-	{
-		ReadEFuse(dev, EEPROM_USB_PHY_PARA1, 5, (unsigned char*)UsbPhyParam);
-		for(i=0; i<5; i++)
-		{
-			priv->EEPROMUsbPhyParam[i] = UsbPhyParam[i];
-			RT_TRACE(COMP_INIT, "USB Param = index(%d) = %#x\n", i, priv->EEPROMUsbPhyParam[i]);
-		}
-	}
-	else
-	{
-		for(i=0; i<5; i++)
-		{
-			priv->EEPROMUsbPhyParam[i] = EEPROM_USB_Default_PHY_PARAM;
-			RT_TRACE(COMP_INIT, "USB Param = index(%d) = %#x\n", i, priv->EEPROMUsbPhyParam[i]);
-		}
-	}
-
-
-       //Read Permanent MAC address
-	if(!priv->AutoloadFailFlag)
-	{
-		u8			macaddr[6] = {0x00, 0xe1, 0x86, 0x4c, 0x92, 0x00};
-
-		ReadEFuse(dev, EEPROM_NODE_ADDRESS_BYTE_0, 6, (unsigned char*)macaddr);
-		for(i=0; i<6; i++)
-			dev->dev_addr[i] = macaddr[i];
-	}
-	else
-	{//Auto load fail
-
-		//<Roger_Notes> In this case, we random assigh MAC address here. 2008.10.15.
-		static u8 sMacAddr[6] = {0x00, 0xE0, 0x4C, 0x81, 0x92, 0x00};
-		u8	i;
-
-		//if(!Adapter->bInHctTest)
-                    //sMacAddr[5] = (u8)GetRandomNumber(1, 254);
-
-		for(i = 0; i < 6; i++)
-			dev->dev_addr[i] = sMacAddr[i];
-	}
-
-	//NicIFSetMacAddress(Adapter, Adapter->PermanentAddress);
-	write_nic_dword(dev, IDR0, ((u32*)dev->dev_addr)[0]);
-	write_nic_word(dev, IDR4, ((u16*)(dev->dev_addr + 4))[0]);
-
-	RT_TRACE(COMP_INIT, "ReadAdapterInfo8192SEFuse(), Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
-			dev->dev_addr[0], dev->dev_addr[1],
-			dev->dev_addr[2], dev->dev_addr[3],
-			dev->dev_addr[4], dev->dev_addr[5]);
-
-	// 2007/11/15 MH For RTL8192USB we assign as 1T2R now.
-	priv->rf_type = RTL819X_DEFAULT_RF_TYPE;	// default : 1T2R
-
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
-	priv->rf_chip = RF_6052;
-	priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
-#else
-	priv->rf_chip = RF_8256;
-#endif
-
-	{
-		//
-		// Read antenna tx power offset of B/C/D to A  from EEPROM
-		// and read ThermalMeter from EEPROM
-		//
-		if(!priv->AutoloadFailFlag)
-		{
-			ReadEFuse(dev, EEPROM_PwDiff, 2, (unsigned char*) &usValue);
-			priv->EEPROMPwDiff = usValue&0x00ff;
-			priv->EEPROMThermalMeter = (usValue&0xff00)>>8;
-		}
-		else
-		{
-			priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
-			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
-		}
-
-		RT_TRACE(COMP_INIT, "PwDiff = %#x\n", priv->EEPROMPwDiff);
-		RT_TRACE(COMP_INIT, "ThermalMeter = %#x\n", priv->EEPROMThermalMeter);
-
-		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
-
-		//
-		// Read Tx Power gain offset of legacy OFDM to HT rate.
-		// Read CrystalCap from EEPROM
-		//
-		if(!priv->AutoloadFailFlag)
-		{
-			ReadEFuse(dev, EEPROM_CrystalCap, 1, (unsigned char*) &usValue);
-			priv->EEPROMCrystalCap = (u8)((usValue&0xf0)>>4);
-		}
-		else
-		{
-			priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
-		}
-
-		RT_TRACE(COMP_INIT, "CrystalCap = %#x\n", priv->EEPROMCrystalCap);
-
-		priv->EEPROMTxPowerDiff = EEPROM_Default_TxPowerDiff;
-		RT_TRACE(COMP_INIT, "TxPowerDiff = %d\n", priv->EEPROMTxPowerDiff);
-
-
-		//
-		// Get Tx Power Base.
-		//
-		if(!priv->AutoloadFailFlag)
-		{
-			ReadEFuse(dev, EEPROM_TxPowerBase, 1, (unsigned char*) &priv->EEPROMTxPwrBase );
-		}
-		else
-		{
-			priv->EEPROMTxPwrBase = EEPROM_Default_TxPowerBase;
-		}
-
-		RT_TRACE(COMP_INIT, "TxPwrBase = %#x\n", priv->EEPROMTxPwrBase);
-
-		//
-		// Get CustomerID(Boad Type)
-		// i.e., 0x0: RTL8188SU, 0x1: RTL8191SU, 0x2: RTL8192SU, 0x3: RTL8191GU.
-		// Others: Reserved. Default is 0x2: RTL8192SU.
-		//
-		if(!priv->AutoloadFailFlag)
-		{
-			ReadEFuse(dev, EEPROM_BoardType, 1, (unsigned char*) &priv->EEPROMBoardType );
-		}
-		else
-		{
-			priv->EEPROMBoardType = EEPROM_Default_BoardType;
-		}
-
-		RT_TRACE(COMP_INIT, "BoardType = %#x\n", priv->EEPROMBoardType);
-
-		//if(pHalData->EEPROM_Def_Ver == 0)
-		{
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-			//
-			// Get CCK Tx Power Index.
-			//
-			if(!priv->AutoloadFailFlag)
-			{
-				ReadEFuse(dev, EEPROM_TxPwIndex_CCK_24G, 14, (unsigned char*)CCKTxPwr);
-				for(i=0; i<14; i++)
-				{
-					RT_TRACE(COMP_INIT, "CCK 2.4G Tx Power Level, Index %d = 0x%02x\n", i, CCKTxPwr[i]);
-					priv->EEPROMTxPowerLevelCCK24G[i] = CCKTxPwr[i];
-				}
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				for(i=0; i<14; i++)
-					priv->EEPROMTxPowerLevelCCK24G[i] = (u8)(EEPROM_Default_TxPower & 0xff);
-			}
-
-			//
-			// Get OFDM Tx Power Index.
-			//
-			if(!priv->AutoloadFailFlag)
-			{
-				ReadEFuse(dev, EEPROM_TxPwIndex_OFDM_24G, 14, (unsigned char*)OFDMTxPwr);
-				for(i=0; i<14; i++)
-				{
-					RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, OFDMTxPwr[i]);
-					priv->EEPROMTxPowerLevelOFDM24G[i] = OFDMTxPwr[i];
-				}
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				usValue = 0x10;
-				for(i=0; i<14; i++)
-					priv->EEPROMTxPowerLevelOFDM24G[i] = (u8)usValue;
-			}
-#else
-			// Please add code in the section!!!!
-			// And merge tx power difference section.
-#endif
-
-			//
-			// Get TSSI value for each path.
-			//
-			if(!priv->AutoloadFailFlag)
-			{
-				ReadEFuse(dev, EEPROM_TSSI_A, 2, (unsigned char*)&usValue);
-				priv->EEPROMTSSI_A = (u8)(usValue&0xff);
-				priv->EEPROMTSSI_B = (u8)((usValue&0xff00)>>8);
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				priv->EEPROMTSSI_A = EEPROM_Default_TSSI;
-				priv->EEPROMTSSI_B = EEPROM_Default_TSSI;
-			}
-
-			RT_TRACE(COMP_INIT, "TSSI_A = %#x, TSSI_B = %#x\n",
-					priv->EEPROMTSSI_A, priv->EEPROMTSSI_B);
-
-			//
-			// Get Tx Power tracking mode.
-			//
-			if(!priv->AutoloadFailFlag)
-			{
-				ReadEFuse(dev, EEPROM_TxPwTkMode, 1, (unsigned char*)&priv->EEPROMTxPwrTkMode);
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				priv->EEPROMTxPwrTkMode = EEPROM_Default_TxPwrTkMode;
-			}
-
-			RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
-
-
-			// TODO: The following HT 2T Path A and B Power Index should be updated.!! Added by Roger, 2008.20.23.
-
-			//
-			// Get HT 2T Path A and B Power Index.
-			//
-			if(!priv->AutoloadFailFlag)
-			{
-				ReadEFuse(dev, EEPROM_HT2T_CH1_A, 6, (unsigned char*)HT2T_TxPwr);
-				for(i=0; i<6; i++)
-				{
-					priv->EEPROMHT2T_TxPwr[i] = HT2T_TxPwr[i];
-				}
-			}
-			else
-			{ // Default setting for Empty EEPROM
-				for(i=0; i<6; i++)
-				{
-					priv->EEPROMHT2T_TxPwr[i] = EEPROM_Default_HT2T_TxPwr;
-				}
-			}
-
-			for(i=0; i<6; i++)
-			{
-				RT_TRACE(COMP_INIT, "EEPROMHT2T_TxPwr, Index %d = 0x%02x\n",
-						i, priv->EEPROMHT2T_TxPwr[i]);
-			}
-		}
-
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-		//
-		// Update HAL variables.
-		//
-		for(i=0; i<14; i++)
-		{
-			priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
-			priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK24G[i];
-		}
-#else
-
-#endif
-		priv->TxPowerDiff = priv->EEPROMPwDiff;
-		// Antenna B gain offset to antenna A, bit0~3
-		priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
-		// Antenna C gain offset to antenna A, bit4~7
-		priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
-		// CrystalCap, bit12~15
-		priv->CrystalCap = priv->EEPROMCrystalCap;
-		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
-		// 92U does not enable TX power tracking.
-		priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
-	}
-
-	priv->LedStrategy = SW_LED_MODE0;
-
-	init_rate_adaptive(dev);
-
-	RT_TRACE(COMP_INIT, "<==== ReadAdapterInfo8192SEFuse\n");
-
-}
-#endif
-
 //
 //	Description:
 //		Read HW adapter information by E-Fuse or EEPROM according CR9346 reported.
@@ -6290,12 +3626,7 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
 	else
 	{
 		priv->AutoloadFailFlag=FALSE;
-#if RTL8192SU_USE_PARAM_TXPWR
-		priv->bTXPowerDataReadFromEEPORM = FALSE;
-#else
 		priv->bTXPowerDataReadFromEEPORM = TRUE;
-#endif
-
 	}
        // Read IC Version && Channel Plan
 	if(!priv->AutoloadFailFlag)
@@ -6455,11 +3786,7 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
 	//	priv->rf_type = RF_1T2R;
 	//}
 
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
 	priv->rf_chip = RF_6052;
-#else
-	priv->rf_chip = RF_8256;
-#endif
 
 	priv->rf_chip = RF_6052;//lzm test
 	RT_TRACE(COMP_INIT, "BoardType = 0x%2x\n", priv->EEPROMBoardType);
@@ -6540,52 +3867,6 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
 	RT_TRACE(COMP_INIT, "TxPwrTkMod = %#x\n", priv->EEPROMTxPwrTkMode);
 
 
-#ifdef EEPROM_OLD_FORMAT_SUPPORT
-
-	//
-	// <Roger_Notes> The following settings are EFUSE version dependence.
-	// So we need to adjust reading offset.
-	// 2008.11.22.
-	//
-	{
-			//
-			// Get HT 2T Path A and B Power Index.
-			//
-			//if(!priv->AutoloadFailFlag)
-			{
-				for(i=0; i<6; i++)
-				{
-				priv->EEPROMHT2T_TxPwr[i] = *(u8 *)&hwinfo[EEPROM_HT2T_CH1_A+i];
-				}
-			}
-
-		//RT_PRINT_DATA(COMP_EFUSE, "HT2T TxPwr: \n"), pHalData->EEPROMHT2T_TxPwr, 6);
-
-		//
-		// Get CCK and OFDM Tx Power Index.
-		//
-		//if(!priv->AutoloadFailFlag)
-		{
-			for(i=0; i<14; i++)
-			{
-				priv->EEPROMTxPowerLevelCCK24G[i] = *(u8 *)&hwinfo[EEPROM_TxPwIndex_CCK_24G+i];
-				priv->EEPROMTxPowerLevelOFDM24G[i] = *(u8 *)&hwinfo[EEPROM_TxPwIndex_OFDM_24G+i];
-			}
-		}
-
-		//RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("CCK 2.4G TxPwr: \n"), pHalData->EEPROMTxPowerLevelCCK24G, 14);
-		//RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("OFDM 2.4G TxPwr: \n"), pHalData->EEPROMTxPowerLevelOFDM24G, 14);
-
-		//
-		// Update HAL variables.
-		//
-		memcpy( priv->TxPowerLevelOFDM24G, priv->EEPROMTxPowerLevelOFDM24G, 14);
-		memcpy( priv->TxPowerLevelCCK, priv->EEPROMTxPowerLevelCCK24G, 14);
-		//RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("HAL CCK 2.4G TxPwr: \n"), pHalData->TxPowerLevelCCK, 14);
-		//RT_PRINT_DATA(COMP_EFUSE, DBG_LOUD, ("HAL OFDM 2.4G TxPwr: \n"), pHalData->TxPowerLevelOFDM24G, 14);
-
-	}
-#else // Support new version of EFUSE content, 2008.11.22.
 	{
 		//
 		// Buffer TxPwIdx(i.e., from offset 0x55~0x66, total 18Bytes)
@@ -6753,7 +4034,6 @@ rtl8192SU_ReadAdapterInfo8192SUsb(struct net_device* dev)
 		priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][0],
 		priv->TxPwrbandEdgeLegacyOfdm[RF90_PATH_B][1]);
 	RT_TRACE((COMP_INIT&COMP_DBG), "Band-edge enable flag = %d\n", priv->TxPwrbandEdgeFlag);
-#endif
 
 	//
 	// Update remained HAL variables.
@@ -6863,256 +4143,10 @@ static void rtl8192SU_read_eeprom_info(struct net_device *dev)
 
 	//return RT_STATUS_SUCCESS;
 }
-#else
-static void rtl8192_read_eeprom_info(struct net_device* dev)
-{
-	u16 wEPROM_ID = 0;
-	u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
-	u8 bLoad_From_EEPOM = false;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u16 tmpValue = 0;
-	RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
-	wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
-	RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
-
-	if (wEPROM_ID != RTL8190_EEPROM_ID)
-	{
-		RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
-	}
-	else
-		bLoad_From_EEPOM = true;
-
-	if (bLoad_From_EEPOM)
-	{
-		tmpValue = eprom_read(dev, (EEPROM_VID>>1));
-		priv->eeprom_vid = endian_swap(&tmpValue);
-		priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
-		tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
-		priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
-		priv->btxpowerdata_readfromEEPORM = true;
-		priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
-	}
-	else
-	{
-		priv->eeprom_vid = 0;
-		priv->eeprom_pid = 0;
-		priv->card_8192_version = VERSION_819xU_B;
-		priv->eeprom_ChannelPlan = 0;
-		priv->eeprom_CustomerID = 0;
-	}
-	RT_TRACE(COMP_EPROM, "vid:0x%4x, pid:0x%4x, CustomID:0x%2x, ChanPlan:0x%x\n", priv->eeprom_vid, priv->eeprom_pid, priv->eeprom_CustomerID, priv->eeprom_ChannelPlan);
-	//set channelplan from eeprom
-	priv->ChannelPlan = priv->eeprom_ChannelPlan;
-	if (bLoad_From_EEPOM)
-	{
-		int i;
-		for (i=0; i<6; i+=2)
-		{
-			u16 tmp = 0;
-			tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
-			*(u16*)(&dev->dev_addr[i]) = tmp;
-		}
-	}
-	else
-	{
-		memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
-		//should I set IDR0 here?
-	}
-	RT_TRACE(COMP_EPROM, "MAC addr:"MAC_FMT"\n", MAC_ARG(dev->dev_addr));
-	priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
-	priv->rf_chip = RF_8256;
-
-	if (priv->card_8192_version == (u8)VERSION_819xU_A)
-	{
-		//read Tx power gain offset of legacy OFDM to HT rate
-		if (bLoad_From_EEPOM)
-			priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
-		else
-			priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
-		RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
-		//read ThermalMeter from EEPROM
-		if (bLoad_From_EEPOM)
-			priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
-		else
-			priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
-		RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
-		//vivi, for tx power track
-		priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
-		//read antenna tx power offset of B/C/D to A from EEPROM
-		if (bLoad_From_EEPOM)
-			priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
-		else
-			priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
-		RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
-		// Read CrystalCap from EEPROM
-		if (bLoad_From_EEPOM)
-			priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
-		else
-			priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
-		RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
-		//get per-channel Tx power level
-		if (bLoad_From_EEPOM)
-			priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
-		else
-			priv->EEPROM_Def_Ver = 1;
-		RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
-		if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
-		{
-			int i;
-			if (bLoad_From_EEPOM)
-				priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
-			else
-				priv->EEPROMTxPowerLevelCCK = 0x10;
-			RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
-			for (i=0; i<3; i++)
-			{
-				if (bLoad_From_EEPOM)
-				{
-					tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
-					if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
-						tmpValue = tmpValue & 0x00ff;
-					else
-						tmpValue = (tmpValue & 0xff00) >> 8;
-				}
-				else
-					tmpValue = 0x10;
-				priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
-				RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
-			}
-		}//end if EEPROM_DEF_VER == 0
-		else if (priv->EEPROM_Def_Ver == 1)
-		{
-			if (bLoad_From_EEPOM)
-			{
-				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
-				tmpValue = (tmpValue & 0xff00) >> 8;
-			}
-			else
-				tmpValue = 0x10;
-			priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
-
-			if (bLoad_From_EEPOM)
-				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
-			else
-				tmpValue = 0x1010;
-			*((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
-			if (bLoad_From_EEPOM)
-				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
-			else
-				tmpValue = 0x1010;
-			*((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
-			if (bLoad_From_EEPOM)
-				tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
-			else
-				tmpValue = 0x10;
-			priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
-		}//endif EEPROM_Def_Ver == 1
-
-		//update HAL variables
-		//
-		{
-			int i;
-			for (i=0; i<14; i++)
-			{
-				if (i<=3)
-					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
-				else if (i>=4 && i<=9)
-					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
-				else
-					priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
-			}
-
-			for (i=0; i<14; i++)
-			{
-				if (priv->EEPROM_Def_Ver == 0)
-				{
-					if (i<=3)
-						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
-					else if (i>=4 && i<=9)
-						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
-					else
-						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
-				}
-				else if (priv->EEPROM_Def_Ver == 1)
-				{
-					if (i<=3)
-						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
-					else if (i>=4 && i<=9)
-						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
-					else
-						priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
-				}
-			}
-		}//end update HAL variables
-		priv->TxPowerDiff = priv->EEPROMPwDiff;
-// Antenna B gain offset to antenna A, bit0~3
-		priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
-		// Antenna C gain offset to antenna A, bit4~7
-		priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
-		// CrystalCap, bit12~15
-		priv->CrystalCap = priv->EEPROMCrystalCap;
-		// ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
-		// 92U does not enable TX power tracking.
-		priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
-	}//end if VersionID == VERSION_819xU_A
-
-//added by vivi, for dlink led, 20080416
-	switch(priv->eeprom_CustomerID)
-	{
-		case EEPROM_CID_RUNTOP:
-			priv->CustomerID = RT_CID_819x_RUNTOP;
-			break;
-
-		case EEPROM_CID_DLINK:
-			priv->CustomerID = RT_CID_DLINK;
-			break;
-
-		default:
-			priv->CustomerID = RT_CID_DEFAULT;
-			break;
-
-	}
-
-	switch(priv->CustomerID)
-	{
-		case RT_CID_819x_RUNTOP:
-			priv->LedStrategy = SW_LED_MODE2;
-			break;
-
- 		case RT_CID_DLINK:
-			priv->LedStrategy = SW_LED_MODE4;
-			break;
-
-		default:
-			priv->LedStrategy = SW_LED_MODE0;
-			break;
-
-	}
-
-
-	if(priv->rf_type == RF_1T2R)
-	{
-		RT_TRACE(COMP_EPROM, "\n1T2R config\n");
-	}
-	else
-	{
-		RT_TRACE(COMP_EPROM, "\n2T4R config\n");
-	}
-
-	// 2008/01/16 MH We can only know RF type in the function. So we have to init
-	// DIG RATR table again.
-	init_rate_adaptive(dev);
-	//we need init DIG RATR table here again.
-
-	RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
-	return;
-}
-#endif
 
 short rtl8192_get_channel_map(struct net_device * dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-#ifdef ENABLE_DOT11D
 	if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
 		printk("rtl8180_init:Error channel plan! Set to default.\n");
 		priv->ChannelPlan= 0;
@@ -7120,21 +4154,6 @@ short rtl8192_get_channel_map(struct net_device * dev)
 	RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
 
 	rtl819x_set_channel_map(priv->ChannelPlan, priv);
-#else
-	int ch,i;
-	//Set Default Channel Plan
-	if(!channels){
-		DMESG("No channels, aborting");
-		return -1;
-	}
-	ch=channels;
-	priv->ChannelPlan= 0;//hikaru
-	 // set channels 1..14 allowed in given locale
-	for (i=1; i<=14; i++) {
-		(priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
-		ch >>= 1;
-	}
-#endif
 	return 0;
 }
 
@@ -7143,28 +4162,6 @@ short rtl8192_init(struct net_device *dev)
 
 	struct r8192_priv *priv = ieee80211_priv(dev);
 
-#ifndef RTL8192SU
-	memset(&(priv->stats),0,sizeof(struct Stats));
-	memset(priv->txqueue_to_outpipemap,0,9);
-#ifdef PIPE12
-	{
-		int i=0;
-		u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
-		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
-/*		for(i=0;i<9;i++)
-			printk("%d ",priv->txqueue_to_outpipemap[i]);
-		printk("\n");*/
-	}
-#else
-	{
-		u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
-		memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
-/*		for(i=0;i<9;i++)
-			printk("%d ",priv->txqueue_to_outpipemap[i]);
-		printk("\n");*/
-	}
-#endif
-#endif
 	rtl8192_init_priv_variable(dev);
 	rtl8192_init_priv_lock(priv);
 	rtl8192_init_priv_task(dev);
@@ -7278,21 +4275,6 @@ void rtl8192_hwconfig(struct net_device* dev)
 
 }
 
-#ifdef RTL8192SU
-#ifdef USB_RX_AGGREGATION_SUPPORT
-u8 rtl8192SU_MapRxPageSizeToIdx(u16 RxPktSize	)
-{
-	switch(RxPktSize)
-	{
-		case 64:		return 0; break;
-		case 128	:	return 1; break;
-		case 256:		return 2; break;
-		case 512:		return 3; break;
-		case 1024:	return 4; break;
-		default:		return 0;	// We use 64bytes in defult.
-	}
-}
-#endif
 
 //
 //	Description:
@@ -7450,203 +4432,6 @@ static void rtl8192SU_MacConfigBeforeFwDownloadASIC(struct net_device *dev)
 
 	RT_TRACE(COMP_INIT, "<---MacConfigBeforeFwDownloadASIC()\n");
 }
-#ifdef USB_RX_AGGREGATION_SUPPORT
-void rtl8192SU_HalUsbRxAggr8192SUsb(struct net_device *dev, bool Value)
-{
-	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
-	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;;
-
-
-	//
-	// <Roger_Notes> We decrease Rx page aggregated threshold in B/G mode.
-	// 2008.10.29
-	//
-	if(priv->ieee80211->mode == WIRELESS_MODE_B ||  priv->ieee80211->mode == WIRELESS_MODE_G)
-	{// Overwrite current settings to disable Rx Aggregation.
-		Value = false;
-	}
-
-	// Alway set Rx Aggregation to Disable if current platform is Win2K USB 1.1, by Emily
-	//if(PLATFORM_LIMITED_RX_BUF_SIZE(Adapter))
-	//	Value = FALSE;
-
-	// Always set Rx Aggregation to Disable if connected AP is Realtek AP, by Joseph
-	//if(pHTInfo->bCurrentRT2RTAggregation)
-	//	Value = FALSE;
-
-	// The RX aggregation may be enabled/disabled dynamically according current traffic stream.
-	//Enable Rx aggregation if downlink traffic is busier than uplink traffic. by Guangan
-	if(priv->bCurrentRxAggrEnable != Value)
-	{
-		priv->bCurrentRxAggrEnable = Value;
-		//Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_USB_RX_AGGR, (pu1Byte)&pHalData->bCurrentRxAggrEnable);
-		{
-			//u8 	Setting = ((pu1Byte)(val))[0];
-			u8 	Setting = priv->bCurrentRxAggrEnable
-			u32 	ulValue;
-
-			if(Setting==0)
-			{
-				//
-				// <Roger_Notes> Reduce aggregated page threshold to 0x01 and set minimal threshold 0x0a.
-				// i.e., disable Rx aggregation.
-				//
-				ulValue = 0x0001000a;
-			}
-			else
-			{
-				//PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
-				//HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
-
-				if (priv->bForcedUsbRxAggr)
-				{// Using forced settings.
-					ulValue = priv->ForcedUsbRxAggrInfo;
-				}
-				else
-				{// Using default settings.
-
-					ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
-							(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
-				}
-			}
-
-			write_nic_byte(dev, RXDMA_AGG_PG_TH, (u8)((ulValue&0xff0000)>>16));
-			write_nic_byte_E(dev, USB_RX_AGG_TIMEOUT, (u8)(ulValue&0xff));
-
-			priv->LastUsbRxAggrInfoSetting = ulValue;
-
-			RT_TRACE(COMP_HT|COMP_RECV, "Set HW_VAR_USB_RX_AGGR: ulValue(%#x)\n", ulValue);
-		}
-		RT_TRACE(COMP_RECV, "HalUsbRxAggr8192SUsb() :  Set RxAggregation to %s\n", Value?"ON":"OFF");
-	}
-
-}
-#endif
-
-#ifdef USB_RX_AGGREGATION_SUPPORT
-void rtl8192SU_HalUsbRxAggr8192SUsb(struct net_device *dev, bool Value)
-{
-	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
-	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;;
-
-
-	//
-	// <Roger_Notes> We decrease Rx page aggregated threshold in B/G mode.
-	// 2008.10.29
-	//
-	if((priv->ieee80211->mode & WIRELESS_MODE_B) || (priv->ieee80211->mode & WIRELESS_MODE_G))
-	{// Overwrite current settings to disable Rx Aggregation.
-		Value = false;
-	}
-
-	// Alway set Rx Aggregation to Disable if current platform is Win2K USB 1.1, by Emily
-	//if(PLATFORM_LIMITED_RX_BUF_SIZE(Adapter))
-	//	Value = FALSE;
-
-	// Always set Rx Aggregation to Disable if connected AP is Realtek AP, by Joseph
-	//if(pHTInfo->bCurrentRT2RTAggregation)
-	//	Value = FALSE;
-
-	// The RX aggregation may be enabled/disabled dynamically according current traffic stream.
-	//Enable Rx aggregation if downlink traffic is busier than uplink traffic. by Guangan
-	if(priv->bCurrentRxAggrEnable != Value)
-	{
-		priv->bCurrentRxAggrEnable = Value;
-		//Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_USB_RX_AGGR, (pu1Byte)&pHalData->bCurrentRxAggrEnable);
-		{
-			//u8 	Setting = ((pu1Byte)(val))[0];
-			u8 	Setting = priv->bCurrentRxAggrEnable
-			u32 	ulValue;
-
-			if(Setting==0)
-			{
-				//
-				// <Roger_Notes> Reduce aggregated page threshold to 0x01 and set minimal threshold 0x0a.
-				// i.e., disable Rx aggregation.
-				//
-				ulValue = 0x0001000a;
-			}
-			else
-			{
-				//PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
-				//HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
-
-				if (priv->bForcedUsbRxAggr)
-				{// Using forced settings.
-					ulValue = priv->ForcedUsbRxAggrInfo;
-				}
-				else
-				{// Using default settings.
-
-					ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
-							(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
-				}
-			}
-
-			write_nic_byte(dev, RXDMA_AGG_PG_TH, (u8)((ulValue&0xff0000)>>16));
-			write_nic_byte_E(dev, USB_RX_AGG_TIMEOUT, (u8)(ulValue&0xff));
-
-			priv->LastUsbRxAggrInfoSetting = ulValue;
-
-			RT_TRACE(COMP_HT|COMP_RECV, "Set HW_VAR_USB_RX_AGGR: ulValue(%#x)\n", ulValue);
-		}
-		RT_TRACE(COMP_RECV, "HalUsbRxAggr8192SUsb() :  Set RxAggregation to %s\n", Value?"ON":"OFF");
-	}
-
-}
-
-u8 rtl8192SU_MapRxPageSizeToIdx(u16 RxPktSize	)
-{
-	switch(RxPktSize)
-	{
-		case 64:		return 0; break;
-		case 128	:	return 1; break;
-		case 256:		return 2; break;
-		case 512:		return 3; break;
-		case 1024:	return 4; break;
-		default:		return 0;	// We use 64bytes in defult.
-	}
-}
-#endif
-
-#if 0
-static void rtl8192SU_SetHwRegAmpduMinSpace(struct net_device *dev, u8 MinSpaceCfg)
-{
-	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
-	struct ieee80211_device* ieee = priv->ieee80211;
-	u8	MinSpacingToSet;
-	u8	SecMinSpace;
-
-#ifdef RTL8192S_PREPARE_FOR_NORMAL_RELEASE
-	MinSpacingToSet = MinSpaceCfg;
-	if(MinSpacingToSet <= 7)
-	{
-		switch(ieee->pairwise_key_type)
-		{
-			case	KEY_TYPE_NA:			SecMinSpace = 0;		break;
-			case	KEY_TYPE_CCMP:
-			case	KEY_TYPE_WEP40:
-			case	KEY_TYPE_WEP104:
-			case	KEY_TYPE_TKIP:		SecMinSpace = 6;		break;
-			default:					SecMinSpace = 7;		break;
-		}
-
-		if(MinSpacingToSet < SecMinSpace)
-			MinSpacingToSet = SecMinSpace;
-		priv->MinSpaceCfg = ((priv->MinSpaceCfg&0xf8) |MinSpacingToSet);
-		RT_TRACE(COMP_SEC, "Set AMPDU_MIN_SPACE: %x\n", priv->MinSpaceCfg);
-		write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);
-	}
-
-#else
-	MinSpacingToSet = MinSpaceCfg;
-	MinSpacingToSet &= 0x07; // We only care about bit[2:0]
-	priv->MinSpaceCfg |= MinSpacingToSet;
-	RT_TRACE(COMP_SEC, "Set AMPDU_MIN_SPACE: %x\n", priv->MinSpaceCfg);
-	write_nic_byte(dev, AMPDU_MIN_SPACE, priv->MinSpaceCfg);//FIXLZM
-#endif
-}
-#endif
 
 //
 //	Description:
@@ -7709,96 +4494,11 @@ static void rtl8192SU_MacConfigAfterFwDownload(struct net_device *dev)
 	//
 	//write_nic_dword(Adapter, 0xa0, 0x07070707); //BKQ, BEQ, VIQ and VOQ
 	//write_nic_byte(dev, 0xa4, 0x00); // HCCAQ
-#if 0	 //LZM 090219
-#ifdef USE_SIX_USB_ENDPOINT
-	//write_nic_dword(Adapter, 0xa5, 0x00000003); //CMDQ, MGTQ, HQ and BCNQ
-	//write_nic_byte(dev, 0xa9, 0xdd); // PUBQ
-	tmpU1b = read_nic_byte(dev, 0xab); // RQPN
-	write_nic_byte(dev, 0xab, tmpU1b|BIT7|BIT6);// reduce to 6 endpoints.
-#else
-	write_nic_dword(dev, 0xa5, 0x02030300); //CMDQ, MGTQ, HQ and BCNQ
-	write_nic_byte(dev, 0xa9, 0xd8); // PUBQ
-	tmpU1b = read_nic_byte(dev, 0xab); // RQPN
-	write_nic_byte(dev, 0xab, (tmpU1b&(~BIT6))|BIT7); // Disable reduced endpoint.
-#endif
-#endif
-
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	// Size of Tx/Rx packet buffer.
-	tmpU1b = read_nic_byte(dev, PBP);
-	RxPageCfg = rtl8192SU_MapRxPageSizeToIdx(priv->ieee80211->pHTInfo.UsbRxPageSize);
-	write_nic_byte(dev, PBP, tmpU1b|RxPageCfg); // Set page size of Rx packet buffer to 128 bytes.
-	tmpU1b = read_nic_byte(dev, RXDMA);
-
-	write_nic_byte(dev, RXDMA, tmpU1b|RXDMA_AGG_EN); // Rx aggregation enable.
-	//PlatformIOWrite1Byte(Adapter, RXDMA_AGG_PG_TH, 0x14);	// Set page size of RxDMA aggregation threshold, default: 20.
-	//write_nic_byte(dev, RXDMA_AGG_PG_TH, 0x40); // By Scott's suggestion, 2008.09.30.//92su del
-	//write_nic_byte(dev, USB_RX_AGG_TIMEOUT, RXDMA_AGG_TIMEOUT_17_4_MS); // Set aggregation time-out to 17ms/4.
-	rtl8192SU_HalUsbRxAggr8192SUsb(dev, true);
-#endif
 
 	// Fix the RX FIFO issue(USB error), Rivesed by Roger, 2008-06-14
 	tmpU1b = read_nic_byte_E(dev, 0x5C);
 	write_nic_byte_E(dev, 0x5C, tmpU1b|BIT7);
 
-	//
-	// Revise USB PHY to solve the issue of Rx payload error, Rivesed by Roger,  2008-04-10
-	// Suggest by SD1 Alex.
-	//
-	// <Roger_Notes> The following operation are ONLY for USB PHY test chip.
-	// 2008.10.07.
-	//
-#if RTL8192SU_USB_PHY_TEST
-	write_nic_byte(dev, 0x41,0xf4);
-	write_nic_byte(dev, 0x40,0x00);
-	write_nic_byte(dev, 0x42,0x00);
-	write_nic_byte(dev, 0x42,0x01);
-	write_nic_byte(dev, 0x40,0x0f);
-	write_nic_byte(dev, 0x42,0x00);
-	write_nic_byte(dev, 0x42,0x01);
-#endif
-
-#if 0 //LZM 090219
-	//
-	// Suggested by SD1 Alex, 2008-06-14.
-	//
-	write_nic_byte(dev, TXOP_STALL_CTRL, 0x80);//NAV
-
-
-	//
-	// Set Data Auto Rate Fallback Retry Count register.
-	//
-	write_nic_dword(dev, DARFRC, 0x04010000);
-	write_nic_dword(dev, DARFRC+4, 0x09070605);
-	write_nic_dword(dev, RARFRC, 0x04010000);
-	write_nic_dword(dev, RARFRC+4, 0x09070605);
-
-	// Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
-	for (i = 0; i < 8; i++)
-#ifdef RTL8192SU_DISABLE_CCK_RATE
-		write_nic_dword(dev, ARFR0+i*4, 0x1f0ff0f0);
-#else
-		write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
-#endif
-
-	//
-	// Set driver info, we only accept PHY status now.
-	//
-	//write_nic_byte(dev, RXDRVINFO_SZ, 4);
-
-	//
-	// Aggregation length limit. Revised by Roger. 2008.09.22.
-	//
-	write_nic_dword(dev, AGGLEN_LMT_L, 0x66666666); // Long GI
-	write_nic_byte(dev, AGGLEN_LMT_H, 0x06);	// Set AMPDU length to 12Kbytes for ShortGI case.
-
-	//
-	// For Min Spacing configuration.
-	//
-	//Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AMPDU_MIN_SPACE, (u8*)(&Adapter->MgntInfo.MinSpaceCfg));
-	rtl8192SU_SetHwRegAmpduMinSpace(dev,priv->MinSpaceCfg);
-#endif
-
 	// For EFUSE init configuration.
 	//if (IS_BOOT_FROM_EFUSE(Adapter))	// We may R/W EFUSE in EFUSE mode
 	if (priv->bBootFromEfuse)
@@ -7889,11 +4589,7 @@ void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
 	// 2008.09.23.
 	//
 	regTmp = read_nic_byte(dev, INIRTSMCS_SEL);
-#ifdef RTL8192SU_DISABLE_CCK_RATE
-	regRRSR = ((regRRSR & 0x000ffff0)<<8) | regTmp;
-#else
 	regRRSR = ((regRRSR & 0x000fffff)<<8) | regTmp;
-#endif
 
 	//
 	// Update SIFS timing.
@@ -7930,11 +4626,7 @@ void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
 
 	// Set Data Auto Rate Fallback Reg. Added by Roger, 2008.09.22.
 	for (i = 0; i < 8; i++)
-#ifdef RTL8192SU_DISABLE_CCK_RATE
-		write_nic_dword(dev, ARFR0+i*4, 0x1f0ff0f0);
-#else
 		write_nic_dword(dev, ARFR0+i*4, 0x1f0ffff0);
-#endif
 
 	//
 	// Aggregation length limit. Revised by Roger. 2008.09.22.
@@ -7987,9 +4679,7 @@ void rtl8192SU_HwConfigureRTL8192SUsb(struct net_device *dev)
 	//rtl8192SU_SetHwRegAmpduMinSpace(dev, priv->MinSpaceCfg);
 }
 
-#endif
 
-#ifdef RTL8192SU
 //	Description:	Initial HW relted registers.
 //
 //	Assumption:	This function is only invoked at driver intialization once.
@@ -8050,9 +4740,6 @@ start:
 	//
 	rtl8192SU_MacConfigAfterFwDownload(dev);
 
-#if (RTL8192S_DISABLE_FW_DM == 1)
-	write_nic_dword(dev, WFM5, FW_DM_DISABLE);
-#endif
 	//priv->bLbusEnable = TRUE;
 	//if(priv->RegRfOff == TRUE)
 	//	priv->eRFPowerState = eRfOff;
@@ -8131,17 +4818,6 @@ start:
 		//PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, bMaskByte0, 0x11);
 	}
 
-#if (RTL8192SU_DISABLE_IQK==0)
-		// For 1T2R IQK only currently.
-		if (priv->card_8192_version == VERSION_8192S_BCUT)
-		{
-			PHY_IQCalibrateBcut(dev);
-		}
-		else if (priv->card_8192_version == VERSION_8192S_ACUT)
-		{
-			PHY_IQCalibrate(dev);
-		}
-#endif
 
 	//LZM 090219
 	// Set CCK and OFDM Block "ON"
@@ -8198,17 +4874,6 @@ start:
 		write_nic_byte(dev, SECR, SECR_value);
 	}
 
-#if 0
-
-	if(pHalData->VersionID == VERSION_8192SU_A)
-	{
-		// cosa add for tx power level initialization.
-		GetTxPowerOriginalOffset(Adapter);
-		SetTxPowerLevel819xUsb(Adapter, Channel);
-	}
-#endif
-
-
 #ifdef TO_DO_LIST
 
 	//PHY_UpdateInitialGain(dev);
@@ -8324,351 +4989,11 @@ start:
 
 // <Roger_Notes> We return status here for temporal FPGA verification. 2008.05.12.
 //
-#if RTL8192SU_FPGA_UNSPECIFIED_NETWORK
-	//
-	// To send specific number of packets to verify MAC Lookback mode.
-	//
-	//SendRandomTxPkt(Adapter, 0); // Burst mode for verification.
-	//rtStatus = RT_STATUS_FAILURE;
-	rtStatus = true;
-        goto end;
-#endif
 
-// The following IO was for FPGA verification purpose. Added by Roger, 2008.09.11.
-#if 0
-	// 2008/08/19 MH From SD1 Jong, we must write some register for true PHY/MAC FPGA.
-	write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x30);
-	write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x30);
-
-	write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
-
-	//write_nic_dword(Adapter, RCR, 0x817FF02F);
-
-	write_nic_dword(Adapter, rTxAGC_Mcs15_Mcs12, 0x06060606);
-#endif
 end:
 return rtStatus;
 }
 
-#else
-
-//InitializeAdapter and PhyCfg
-bool rtl8192_adapter_start(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32 dwRegRead = 0;
-	bool init_status = true;
-	RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
-	priv->Rf_Mode = RF_OP_By_SW_3wire;
-	//for ASIC power on sequence
-	write_nic_byte_E(dev, 0x5f, 0x80);
-	mdelay(50);
-	write_nic_byte_E(dev, 0x5f, 0xf0);
-	write_nic_byte_E(dev, 0x5d, 0x00);
-	write_nic_byte_E(dev, 0x5e, 0x80);
-	write_nic_byte(dev, 0x17, 0x37);
-	mdelay(10);
-//#ifdef TO_DO_LIST
-	priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
-	//config CPUReset Register
-	//Firmware Reset or not?
-	dwRegRead = read_nic_dword(dev, CPU_GEN);
-	if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
-		dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
-	else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
-		dwRegRead |= CPU_GEN_FIRMWARE_RESET;
-	else
-		RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__,   priv->pFirmware->firmware_status);
-
-	write_nic_dword(dev, CPU_GEN, dwRegRead);
-	//mdelay(30);
-	//config BB.
-	rtl8192_BBConfig(dev);
-
-#if 1
-	//Loopback mode or not
-	priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
-//	priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
-
-	dwRegRead = read_nic_dword(dev, CPU_GEN);
-	if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
-		dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
-	else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
-		dwRegRead |= CPU_CCK_LOOPBACK;
-	else
-		RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__,  priv->LoopbackMode);
-
-	write_nic_dword(dev, CPU_GEN, dwRegRead);
-
-	//after reset cpu, we need wait for a seconds to write in register.
-	udelay(500);
-
-	//xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
-	write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
-
-	//Set Hardware
-	rtl8192_hwconfig(dev);
-
-	//turn on Tx/Rx
-	write_nic_byte(dev, CMDR, CR_RE|CR_TE);
-
-	//set IDR0 here
-	write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
-	write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
-
-	//set RCR
-	write_nic_dword(dev, RCR, priv->ReceiveConfig);
-
-	//Initialize Number of Reserved Pages in Firmware Queue
-	write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
-						NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
-						NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
-						NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
-	write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
-						NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
-	write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
-						NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
-//						| NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
-						);
-	write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
-
-	//Set AckTimeout
-	// TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
-	write_nic_byte(dev, ACK_TIMEOUT, 0x30);
-
-//	RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
-	if(priv->ResetProgress == RESET_TYPE_NORESET)
-	rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
-	if(priv->ResetProgress == RESET_TYPE_NORESET){
-	CamResetAllEntry(dev);
-	{
-		u8 SECR_value = 0x0;
-		SECR_value |= SCR_TxEncEnable;
-		SECR_value |= SCR_RxDecEnable;
-		SECR_value |= SCR_NoSKMC;
-		write_nic_byte(dev, SECR, SECR_value);
-	}
-	}
-
-	//Beacon related
-	write_nic_word(dev, ATIMWND, 2);
-	write_nic_word(dev, BCN_INTERVAL, 100);
-
-	{
-#define DEFAULT_EDCA 0x005e4332
-		int i;
-		for (i=0; i<QOS_QUEUE_NUM; i++)
-		write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
-	}
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	//3 For usb rx firmware aggregation control
-	if(priv->ResetProgress == RESET_TYPE_NORESET)
-	{
-		u32 ulValue;
-		PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
-		ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
-					(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
-		/*
-		 * If usb rx firmware aggregation is enabled,
-		 * when anyone of three threshold conditions above is reached,
-		 * firmware will send aggregated packet to driver.
-		 */
-		write_nic_dword(dev, 0x1a8, ulValue);
-		priv->bCurrentRxAggrEnable = true;
-	}
-#endif
-
-	rtl8192_phy_configmac(dev);
-
-	if (priv->card_8192_version == (u8) VERSION_819xU_A)
-	{
-		rtl8192_phy_getTxPower(dev);
-		rtl8192_phy_setTxPower(dev, priv->chan);
-	}
-
-
-	priv->usb_error = false;
-	//Firmware download
-	init_status = init_firmware(dev);
-	if(!init_status)
-	{
-		RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
-		return init_status;
-	}
-	RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
-	//
-#ifdef TO_DO_LIST
-if(Adapter->ResetProgress == RESET_TYPE_NORESET)
-	{
-		if(pMgntInfo->RegRfOff == TRUE)
-		{ // User disable RF via registry.
-			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
-			MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
-			// Those action will be discard in MgntActSet_RF_State because off the same state
-			for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
-				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
-		}
-		else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
-		{ // H/W or S/W RF OFF before sleep.
-			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
-			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
-		}
-		else
-		{
-			pHalData->eRFPowerState = eRfOn;
-			pMgntInfo->RfOffReason = 0;
-			RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
-		}
-	}
-	else
-	{
-		if(pHalData->eRFPowerState == eRfOff)
-		{
-			MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
-			// Those action will be discard in MgntActSet_RF_State because off the same state
-			for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
-				PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
-		}
-	}
-#endif
-	//config RF.
-	if(priv->ResetProgress == RESET_TYPE_NORESET){
-	rtl8192_phy_RFConfig(dev);
-	RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
-	}
-
-
-	if(priv->ieee80211->FwRWRF)
-		// We can force firmware to do RF-R/W
-		priv->Rf_Mode = RF_OP_By_FW;
-	else
-		priv->Rf_Mode = RF_OP_By_SW_3wire;
-
-
-	rtl8192_phy_updateInitGain(dev);
-	/*--set CCK and OFDM Block "ON"--*/
-	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
-	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
-
-	if(priv->ResetProgress == RESET_TYPE_NORESET)
-	{
-		//if D or C cut
-		u8 tmpvalue = read_nic_byte(dev, 0x301);
-		if(tmpvalue ==0x03)
-		{
-			priv->bDcut = TRUE;
-			RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
-		}
-		else
-		{
-			priv->bDcut = FALSE;
-			RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
-		}
-		dm_initialize_txpower_tracking(dev);
-
-		if(priv->bDcut == TRUE)
-		{
-			u32 i, TempCCk;
-			u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
-		//	u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
-			for(i = 0; i<TxBBGainTableLength; i++)
-			{
-				if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
-				{
-					priv->rfa_txpowertrackingindex= (u8)i;
-					priv->rfa_txpowertrackingindex_real= (u8)i;
-					priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
-					break;
-				}
-			}
-
-			TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
-
-			for(i=0 ; i<CCKTxBBGainTableLength ; i++)
-			{
-
-				if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
-				{
-					priv->cck_present_attentuation_20Mdefault=(u8) i;
-					break;
-				}
-			}
-			priv->cck_present_attentuation_40Mdefault= 0;
-			priv->cck_present_attentuation_difference= 0;
-			priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
-
-	//		pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
-		}
-	}
-	write_nic_byte(dev, 0x87, 0x0);
-
-
-#endif
-	return init_status;
-}
-
-#endif
-/* this configures registers for beacon tx and enables it via
- * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
- * be used to stop beacon transmission
- */
-#if 0
-void rtl8192_start_tx_beacon(struct net_device *dev)
-{
-	int i;
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	u16 word;
-	DMESG("Enabling beacon TX");
-	//write_nic_byte(dev, TX_CONF,0xe6);// TX_CONF
-	//rtl8192_init_beacon(dev);
-	//set_nic_txring(dev);
-//	rtl8192_prepare_beacon(dev);
-	rtl8192_irq_disable(dev);
-//	rtl8192_beacon_tx_enable(dev);
-	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
-	//write_nic_byte(dev,0x9d,0x20); //DMA Poll
-	//write_nic_word(dev,0x7a,0);
-	//write_nic_word(dev,0x7a,0x8000);
-
-
-	word  = read_nic_word(dev, BcnItv);
-	word &= ~BcnItv_BcnItv; // clear Bcn_Itv
-	write_nic_word(dev, BcnItv, word);
-
-	write_nic_word(dev, AtimWnd,
-		       read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd);
-
-	word  = read_nic_word(dev, BCN_INTR_ITV);
-	word &= ~BCN_INTR_ITV_MASK;
-
-	//word |= priv->ieee80211->beacon_interval *
-	//	((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
-	// FIXME:FIXME check if correct ^^ worked with 0x3e8;
-
-	write_nic_word(dev, BCN_INTR_ITV, word);
-
-	//write_nic_word(dev,0x2e,0xe002);
-	//write_nic_dword(dev,0x30,0xb8c7832e);
-	for(i=0; i<ETH_ALEN; i++)
-		write_nic_byte(dev, BSSID+i, priv->ieee80211->beacon_cell_ssid[i]);
-
-//	rtl8192_update_msr(dev);
-
-
-	//write_nic_byte(dev,CONFIG4,3); /* !!!!!!!!!! */
-
-	rtl8192_set_mode(dev, EPROM_CMD_NORMAL);
-
-	rtl8192_irq_enable(dev);
-
-	/* VV !!!!!!!!!! VV*/
-	/*
-	rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
-	write_nic_byte(dev,0x9d,0x00);
-	rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
-*/
-}
-#endif
 /***************************************************************************
     -------------------------------NET STUFF---------------------------
 ***************************************************************************/
@@ -8723,11 +5048,7 @@ TxCheckStuck(struct net_device *dev)
 	     		if(QueueID == TXCMD_QUEUE)
 		         continue;
 #if 1
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-			if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_drv_aggQ[QueueID]) == 0))
-#else
 		     	if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0)  && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
-#endif
 			 	continue;
 #endif
 
@@ -8865,9 +5186,7 @@ rtl819x_ifcheck_resetornot(struct net_device *dev)
 	RESET_TYPE	RxResetType = RESET_TYPE_NORESET;
 	RT_RF_POWER_STATE 	rfState;
 
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
 	return RESET_TYPE_NORESET;
-#endif
 
 	rfState = priv->ieee80211->eRFPowerState;
 
@@ -9092,9 +5411,7 @@ RESET_START:
 			printk("ieee->state is IEEE80211_LINKED\n");
 			ieee80211_stop_send_beacons(priv->ieee80211);
 			del_timer_sync(&ieee->associate_timer);
-			#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 			cancel_delayed_work(&ieee->associate_retry_wq);
-			#endif
 			ieee80211_stop_scan(ieee);
 			netif_carrier_off(dev);
 			up(&ieee->wx_sem);
@@ -9131,11 +5448,7 @@ RESET_START:
 			ieee->set_chan(ieee->dev, ieee->current_network.channel);
 
 #if 1
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 			queue_work(ieee->wq, &ieee->associate_complete_wq);
-#else
-			schedule_task(&ieee->associate_complete_wq);
-#endif
 #endif
 
 		}
@@ -9231,18 +5544,11 @@ void rtl819x_update_rxcounts(
 	}
 }
 
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern	void	rtl819x_watchdog_wqcallback(struct work_struct *work)
 {
 	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
        struct net_device *dev = priv->ieee80211->dev;
-#else
-extern	void	rtl819x_watchdog_wqcallback(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
 	struct ieee80211_device* ieee = priv->ieee80211;
 	RESET_TYPE	ResetType = RESET_TYPE_NORESET;
       	static u8	check_reset_cnt=0;
@@ -9288,12 +5594,7 @@ extern	void	rtl819x_watchdog_wqcallback(struct net_device *dev)
 				RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
 				ieee->is_roaming = true;
 				priv->ieee80211->link_change(dev);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
                                 queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
-#else
-                                schedule_task(&priv->ieee80211->associate_procedure_wq);
-#endif
-
 			}
 		}
 		priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
@@ -9328,20 +5629,8 @@ void watch_dog_timer_callback(unsigned long data)
 {
 	struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
 	//printk("===============>watch_dog  timer\n");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 	queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
-#else
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	schedule_task(&priv->watch_dog_wq);
-#else
-	queue_work(priv->priv_wq,&priv->watch_dog_wq);
-#endif
-#endif
 	mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
-#if 0
-	priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME);
-	add_timer(&priv->watch_dog_timer);
-#endif
 }
 int _rtl8192_up(struct net_device *dev)
 {
@@ -9488,17 +5777,10 @@ void rtl8192_restart(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 void rtl8192_restart(struct work_struct *work)
 {
         struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
         struct net_device *dev = priv->ieee80211->dev;
-#else
-void rtl8192_restart(struct net_device *dev)
-{
-
-        struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
 
 	down(&priv->wx_sem);
 
@@ -9537,11 +5819,8 @@ int r8192_set_mac_adr(struct net_device *dev, void *mac)
 
 	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 	schedule_work(&priv->reset_wq);
-#else
-	schedule_task(&priv->reset_wq);
-#endif
+
 	up(&priv->wx_sem);
 
 	return 0;
@@ -9666,7 +5945,6 @@ out:
 	return ret;
 }
 
-#ifdef RTL8192SU
 u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
 {
 
@@ -9769,7 +6047,6 @@ u8 rtl8192SU_HwRateToMRate(bool bIsHT, u8 rate,bool bFirstAMPDU)
 	}
 	return ret_rate;
 }
-#endif
 
 u8 HwRateToMRate90(bool bIsHT, u8 rate)
 {
@@ -9903,14 +6180,6 @@ void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee802
 		bcheck = true;
 	}else
 	{
-	#if 0
-		// if previous packet is aggregated packet, and current packet
-		//  (1) is not AMPDU
-		//  (2) is the first packet of one AMPDU
-		// that means the previous packet is the last one aggregated packet
-		if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
-			bcheck = true;
-	#endif
 	}
 
 
@@ -10220,7 +6489,6 @@ rtl819x_signal_scale_mapping(
 	return retsig;
 }
 
-#ifdef RTL8192SU
 /*-----------------------------------------------------------------------------
  * Function:	QueryRxPhyStatus8192S()
  *
@@ -10286,17 +6554,6 @@ static void rtl8192SU_query_rxphystatus(
 	pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
 	pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
 
-#ifndef RTL8192SU
-	phy_sts_ofdm_819xusb_t*	pofdm_buf = NULL;
-	prxpkt = (u8*)pdrvinfo;
-
-	/* Move pointer to the 16th bytes. Phy status start address. */
-	prxpkt += sizeof(rx_drvinfo_819x_usb);
-
-	/* Initial the cck and ofdm buffer pointer */
-	pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
-	pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
-#endif
 
 	pstats->RxMIMOSignalQuality[0] = -1;
 	pstats->RxMIMOSignalQuality[1] = -1;
@@ -10485,9 +6742,6 @@ static void rtl8192SU_query_rxphystatus(
 			//evm = rtl819x_evm_dbtopercentage(rx_evmX);
 			evm = rtl819x_evm_dbtopercentage( (pdrvinfo->rxevm[i] /*/ 2*/));	//dbm
 			RT_TRACE(COMP_RF, "RXRATE=%x RXEVM=%x EVM=%s%d\n", pDesc->RxMCS, pdrvinfo->rxevm[i], "%", evm);
-#if 0
-			EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100//=====>from here
-#endif
 
 			//if(bpacket_match_bssid)
 			{
@@ -10523,256 +6777,6 @@ static void rtl8192SU_query_rxphystatus(
 			pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
 	}
 }/* QueryRxPhyStatus8192S */
-#else
-static void rtl8192_query_rxphystatus(
-	struct r8192_priv * priv,
-	struct ieee80211_rx_stats * pstats,
-	rx_drvinfo_819x_usb  * pdrvinfo,
-	struct ieee80211_rx_stats * precord_stats,
-	bool bpacket_match_bssid,
-	bool bpacket_toself,
-	bool bPacketBeacon,
-	bool bToSelfBA
-	)
-{
-	//PRT_RFD_STATUS		pRtRfdStatus = &(pRfd->Status);
-	phy_sts_ofdm_819xusb_t*	pofdm_buf;
-	phy_sts_cck_819xusb_t	*	pcck_buf;
-	phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
-	u8				*prxpkt;
-	u8				i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
-	char				rx_pwr[4], rx_pwr_all=0;
-	//long				rx_avg_pwr = 0;
-	char				rx_snrX, rx_evmX;
-	u8				evm, pwdb_all;
-	u32				RSSI, total_rssi=0;//, total_evm=0;
-//	long				signal_strength_index = 0;
-	u8				is_cck_rate=0;
-	u8				rf_rx_num = 0;
-
-
-	priv->stats.numqry_phystatus++;
-
-	is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
-
-	// Record it for next packet processing
-	memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
-	pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
-	pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
-	pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
-	pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
-	pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
-
-	prxpkt = (u8*)pdrvinfo;
-
-	/* Move pointer to the 16th bytes. Phy status start address. */
-	prxpkt += sizeof(rx_drvinfo_819x_usb);
-
-	/* Initial the cck and ofdm buffer pointer */
-	pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
-	pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
-
-	pstats->RxMIMOSignalQuality[0] = -1;
-	pstats->RxMIMOSignalQuality[1] = -1;
-	precord_stats->RxMIMOSignalQuality[0] = -1;
-	precord_stats->RxMIMOSignalQuality[1] = -1;
-
-	if(is_cck_rate)
-	{
-		//
-		// (1)Hardware does not provide RSSI for CCK
-		//
-
-		//
-		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
-		//
-		u8 report;//, cck_agc_rpt;
-
-		priv->stats.numqry_phystatusCCK++;
-
-		if(!priv->bCckHighPower)
-		{
-			report = pcck_buf->cck_agc_rpt & 0xc0;
-			report = report>>6;
-			switch(report)
-			{
-				//Fixed by Jacken from Bryant 2008-03-20
-				//Original value is -38 , -26 , -14 , -2
-				//Fixed value is -35 , -23 , -11 , 6
-				case 0x3:
-					rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
-					break;
-				case 0x2:
-					rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
-					break;
-				case 0x1:
-					rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
-					break;
-				case 0x0:
-					rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
-					break;
-			}
-		}
-		else
-		{
-			report = pcck_buf->cck_agc_rpt & 0x60;
-			report = report>>5;
-			switch(report)
-			{
-				case 0x3:
-					rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
-					break;
-				case 0x2:
-					rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
-					break;
-				case 0x1:
-					rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
-					break;
-				case 0x0:
-					rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
-					break;
-			}
-		}
-
-		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
-		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
-		pstats->RecvSignalPower = pwdb_all;
-
-		//
-		// (3) Get Signal Quality (EVM)
-		//
-		//if(bpacket_match_bssid)
-		{
-			u8	sq;
-
-			if(pstats->RxPWDBAll > 40)
-			{
-				sq = 100;
-			}else
-			{
-				sq = pcck_buf->sq_rpt;
-
-				if(pcck_buf->sq_rpt > 64)
-					sq = 0;
-				else if (pcck_buf->sq_rpt < 20)
-					sq = 100;
-				else
-					sq = ((64-sq) * 100) / 44;
-			}
-			pstats->SignalQuality = precord_stats->SignalQuality = sq;
-			pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
-			pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
-		}
-	}
-	else
-	{
-		priv->stats.numqry_phystatusHT++;
-		//
-		// (1)Get RSSI for HT rate
-		//
-		for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
-		{
-			// 2008/01/30 MH we will judge RF RX path now.
-			if (priv->brfpath_rxenable[i])
-				rf_rx_num++;
-			else
-				continue;
-
-		if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
-				continue;
-
-			//Fixed by Jacken from Bryant 2008-03-20
-			//Original value is 106
-			rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
-
-			//Get Rx snr value in DB
-			tmp_rxsnr =	pofdm_buf->rxsnr_X[i];
-			rx_snrX = (char)(tmp_rxsnr);
-			//rx_snrX >>= 1;;
-			rx_snrX /= 2;
-			priv->stats.rxSNRdB[i] = (long)rx_snrX;
-
-			/* Translate DBM to percentage. */
-			RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
-			total_rssi += RSSI;
-
-			/* Record Signal Strength for next packet */
-			//if(bpacket_match_bssid)
-			{
-				pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
-				precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
-			}
-		}
-
-
-		//
-		// (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
-		//
-		//Fixed by Jacken from Bryant 2008-03-20
-		//Original value is 106
-		rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
-		pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
-
-		pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
-		pstats->RxPower = precord_stats->RxPower =  rx_pwr_all;
-
-		//
-		// (3)EVM of HT rate
-		//
-		if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
-		 	pdrvinfo->RxRate<=DESC90_RATEMCS15)
-			max_spatial_stream = 2; //both spatial stream make sense
-		else
-			max_spatial_stream = 1; //only spatial stream 1 makes sense
-
-		for(i=0; i<max_spatial_stream; i++)
-		{
-			tmp_rxevm =	pofdm_buf->rxevm_X[i];
-			rx_evmX = (char)(tmp_rxevm);
-
-			// Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
-			// fill most significant bit to "zero" when doing shifting operation which may change a negative
-			// value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore.
-			rx_evmX /= 2;	//dbm
-
-			evm = rtl819x_evm_dbtopercentage(rx_evmX);
-#if 0
-			EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
-#endif
-			//if(bpacket_match_bssid)
-			{
-				if(i==0) // Fill value in RFD, Get the first spatial stream only
-					pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
-				pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
-			}
-		}
-
-
-		/* record rx statistics for debug */
-		rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
-		prxsc =	(phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
-		if(pdrvinfo->BW)	//40M channel
-			priv->stats.received_bwtype[1+prxsc->rxsc]++;
-		else				//20M channel
-			priv->stats.received_bwtype[0]++;
-	}
-
-	//UI BSS List signal strength(in percentage), make it good looking, from 0~100.
-	//It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
-	if(is_cck_rate)
-	{
-		pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
-
-	}
-	else
-	{
-		//pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
-		// We can judge RX path number now.
-		if (rf_rx_num != 0)
-			pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
-	}
-}	/* QueryRxPhyStatus8190Pci */
-#endif
 
 void
 rtl8192_record_rxdesc_forlateruse(
@@ -10785,7 +6789,6 @@ rtl8192_record_rxdesc_forlateruse(
 	ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
 }
 
-#ifdef RTL8192SU
 static void rtl8192SU_query_rxphystatus(
 	struct r8192_priv * priv,
 	struct ieee80211_rx_stats * pstats,
@@ -10865,75 +6868,6 @@ void rtl8192SU_TranslateRxSignalStuff(struct sk_buff *skb,
 	rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
 
 }
-#else
-void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
-				   struct ieee80211_rx_stats * pstats,
-                                   rx_drvinfo_819x_usb  *pdrvinfo)
-{
-	// TODO: We must only check packet for current MAC address. Not finish
-	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
-	struct net_device *dev=info->dev;
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	bool bpacket_match_bssid, bpacket_toself;
-	bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
-	static struct ieee80211_rx_stats  previous_stats;
-	struct ieee80211_hdr_3addr *hdr;//by amy
-       u16 fc,type;
-
-	// Get Signal Quality for only RX data queue (but not command queue)
-
-	u8* tmp_buf;
-	//u16 tmp_buf_len = 0;
-	u8  *praddr;
-
-	/* Get MAC frame start address. */
-	tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
-
-	hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
-	fc = le16_to_cpu(hdr->frame_ctl);
-	type = WLAN_FC_GET_TYPE(fc);
-	praddr = hdr->addr1;
-
-	/* Check if the received packet is acceptabe. */
-	bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
-                                			(eqMacAddr(priv->ieee80211->current_network.bssid,  (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
-                                				 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
-	bpacket_toself =  bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
-
-#if 1//cosa
-		if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
-		{
-			bPacketBeacon = true;
-			//DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
-		}
-		if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
-		{
-			if((eqMacAddr(praddr,dev->dev_addr)))
-				bToSelfBA = true;
-				//DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
-		}
-
-#endif
-
-
-	if(bpacket_match_bssid)
-	{
-		priv->stats.numpacket_matchbssid++;
-	}
-	if(bpacket_toself){
-		priv->stats.numpacket_toself++;
-	}
-	//
-	// Process PHY information for previous packet (RSSI/PWDB/EVM)
-	//
-	// Because phy information is contained in the last packet of AMPDU only, so driver
-	// should process phy information of previous packet
-	rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
-	rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
-	rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
-
-}
-#endif
 
 /**
 * Function:	UpdateReceivedRateHistogramStatistics
@@ -11017,7 +6951,6 @@ UpdateReceivedRateHistogramStatistics8190(
     priv->stats.received_rate_histogram[rcvType][rateIndex]++;
 }
 
-#ifdef RTL8192SU
 void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
 {
 	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
@@ -11031,11 +6964,6 @@ void rtl8192SU_query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stat
 	//pu1Byte		pDesc = (pu1Byte)pDescIn;
 	//PRX_DRIVER_INFO_8192S		pDrvInfo;
 
-#ifdef USB_RX_AGGREGATION_SUPPORT//FIXLZM
-	//if (bIsRxAggrSubframe)
-		rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
-	else
-#endif
 	rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
 
 	if(0)
@@ -11160,247 +7088,7 @@ if(stats->bHwError)
 		rtl8192SU_TranslateRxSignalStuff(skb, stats, desc, driver_info);
 	}
 }
-#else
-void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
-{
-	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
-	struct net_device *dev=info->dev;
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	//rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
-	rx_drvinfo_819x_usb  *driver_info = NULL;
-
-	//
-	//Get Rx Descriptor Information
-	//
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	if (bIsRxAggrSubframe)
-	{
-		rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
-		stats->Length = desc->Length ;
-		stats->RxDrvInfoSize = desc->RxDrvInfoSize;
-		stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
-		stats->bICV = desc->ICV;
-		stats->bCRC = desc->CRC32;
-		stats->bHwError = stats->bCRC|stats->bICV;
-		stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
-	} else
-#endif
-	{
-		rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
-
-		stats->Length = desc->Length;
-		stats->RxDrvInfoSize = desc->RxDrvInfoSize;
-		stats->RxBufShift = 0;//desc->Shift&0x03;
-		stats->bICV = desc->ICV;
-		stats->bCRC = desc->CRC32;
-		stats->bHwError = stats->bCRC|stats->bICV;
-		//RTL8190 set this bit to indicate that Hw does not decrypt packet
-		stats->Decrypted = !desc->SWDec;
-	}
-
-	if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
-	{
-		stats->bHwError = false;
-	}
-	else
-	{
-		stats->bHwError = stats->bCRC|stats->bICV;
-	}
-
-	if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
-		stats->bHwError |= 1;
-	//
-	//Get Driver Info
-	//
-	// TODO: Need to verify it on FGPA platform
-	//Driver info are written to the RxBuffer following rx desc
-	if (stats->RxDrvInfoSize != 0) {
-		driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
-				stats->RxBufShift);
-		/* unit: 0.5M */
-		/* TODO */
-		if(!stats->bHwError){
-			u8	ret_rate;
-			ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
-			if(ret_rate == 0xff)
-			{
-				// Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
-				// Special Error Handling here, 2008.05.16, by Emily
-
-				stats->bHwError = 1;
-				stats->rate = MGN_1M;	//Set 1M rate by default
-			}else
-			{
-				stats->rate = ret_rate;
-			}
-		}
-		else
-			stats->rate = 0x02;
-
-		stats->bShortPreamble = driver_info->SPLCP;
-
 
-		UpdateReceivedRateHistogramStatistics8190(dev, stats);
-
-		stats->bIsAMPDU = (driver_info->PartAggr==1);
-		stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
-#if 0
-		// TODO: it is debug only. It should be disabled in released driver. 2007.1.12 by Joseph
-		UpdateRxAMPDUHistogramStatistics8190(Adapter, pRfd);
-#endif
-		stats->TimeStampLow = driver_info->TSFL;
-		// xiong mask it, 070514
-		//pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
-		// stats->TimeStampHigh = read_nic_dword(dev,  TSFR+4);
-
-		UpdateRxPktTimeStamp8190(dev, stats);
-
-		//
-		// Rx A-MPDU
-		//
-		if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
-			RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
-					driver_info->FirstAGGR, driver_info->PartAggr);
-
-	}
-
-	skb_pull(skb,sizeof(rx_desc_819x_usb));
-	//
-	// Get Total offset of MPDU Frame Body
-	//
-	if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
-		stats->bShift = 1;
-		skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
-	}
-
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	/* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
-	if(bIsRxAggrSubframe) {
-		skb_pull(skb, 8);
-	}
-#endif
-	/* for debug 2008.5.29 */
-#if 0
-	{
-		int i;
-		printk("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-		for(i = 0; i < skb->len; i++) {
-			if(i % 10 == 0) printk("\n");
-			printk("%02x ", skb->data[i]);
-		}
-		printk("\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
-	}
-#endif
-
-	//added by vivi, for MP, 20080108
-	stats->RxIs40MHzPacket = driver_info->BW;
-	if(stats->RxDrvInfoSize != 0)
-		TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
-
-}
-#endif
-
-#ifdef RTL8192SU
-#if 0
-/*-----------------------------------------------------------------------------
- * Function:	UpdateRxAMPDUHistogramStatistics8192S
- *
- * Overview:	Recored down the received A-MPDU aggregation size and pkt number
- *
- * Input:       Adapter
- *
- * Output:      Adapter
- *				(Adapter->RxStats.RxAMPDUSizeHistogram[] is updated)
- *				(Adapter->RxStats.RxAMPDUNumHistogram[] is updated)
- *
- * Return:      NONE
- *
- * Revised History:
- * When			Who		Remark
- * 09/18/2008 	MHC		Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-static	void
-UpdateRxAMPDUHistogramStatistics8192S(
-	struct net_device *dev,
-	struct ieee80211_rx_stats *stats
-	)
-{
-	//HAL_DATA_TYPE			*pHalData = GET_HAL_DATA(Adapter);
-	u8 	size_index;
-	u8	num_index;
-	u16	update_size = 0;
-	u8	update_num = 0;
-
-	if(stats->bIsAMPDU)
-	{
-		if(stats->bFirstMPDU)
-		{
-			if(stats->nRxAMPDU_Size!=0 && stats->nRxAMPDU_AggrNum!=0)
-			{
-				update_size = stats->nRxAMPDU_Size;
-				update_num = stats->nRxAMPDU_AggrNum;
-			}
-			stats->nRxAMPDU_Size = stats->Length;
-			stats->nRxAMPDU_AggrNum = 1;
-		}
-		else
-		{
-			stats->nRxAMPDU_Size += stats->Length;
-			stats->nRxAMPDU_AggrNum++;
-		}
-	}
-	else
-	{
-		if(stats->nRxAMPDU_Size!=0 && stats->nRxAMPDU_AggrNum!=0)
-		{
-			update_size = stats->nRxAMPDU_Size;
-			update_num = stats->nRxAMPDU_AggrNum;
-		}
-		stats->nRxAMPDU_Size = 0;
-		stats->nRxAMPDU_AggrNum = 0;
-	}
-
-	if(update_size!=0 && update_num!= 0)
-	{
-		if(update_size < 4096)
-			size_index = 0;
-		else if(update_size < 8192)
-			size_index = 1;
-		else if(update_size < 16384)
-			size_index = 2;
-		else if(update_size < 32768)
-			size_index = 3;
-		else if(update_size < 65536)
-			size_index = 4;
-		else
-		{
-			RT_TRACE(COMP_RXDESC,
-			("UpdateRxAMPDUHistogramStatistics8192S(): A-MPDU too large\n");
-		}
-
-		Adapter->RxStats.RxAMPDUSizeHistogram[size_index]++;
-
-		if(update_num < 5)
-			num_index = 0;
-		else if(update_num < 10)
-			num_index = 1;
-		else if(update_num < 20)
-			num_index = 2;
-		else if(update_num < 40)
-			num_index = 3;
-		else
-			num_index = 4;
-
-		Adapter->RxStats.RxAMPDUNumHistogram[num_index]++;
-	}
-}	// UpdateRxAMPDUHistogramStatistics8192S
-#endif
-
-#endif
-
-
-#ifdef RTL8192SU
 //
 // Description:
 // 	The strarting address of wireless lan header will shift 1 or 2 or 3 or "more" bytes for the following reason :
@@ -11441,27 +7129,6 @@ void rtl8192SU_rx_nomal(struct sk_buff* skb)
 	struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
 	bool unicast_packet = false;
 
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	struct sk_buff *agg_skb = NULL;
-	u32  TotalLength = 0;//Total packet length for all aggregated packets.
-	u32  TempDWord = 0;
-	u32  PacketLength = 0;// Per-packet length include size of RxDesc.
-	u32  PacketOccupiedLendth = 0;
-	u8   TempByte = 0;
-	u32  PacketShiftBytes = 0;
-	rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
-	u8  PaddingBytes = 0;
-	//add just for testing
-	u8   testing;
-
-	u8	TotalAggPkt = 0;
-	PRT_HIGH_THROUGHPUT	pHTInfo =priv-> ieee80211->pHTInfo;
-	u16	RxPageSize = pHTInfo->UsbRxPageSize;
-
-	stats->nTotalAggPkt = 0;
-	//stats->bIsRxAggrSubframe = FALSE;
-
-#endif
 	//printk("**********skb->len = %d\n", skb->len);
 	/* 20 is for ps-poll */
 	if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
@@ -11471,14 +7138,6 @@ void rtl8192SU_rx_nomal(struct sk_buff* skb)
 		/* TODO */
 
 		/* hardware related info */
-#ifdef USB_RX_AGGREGATION_SUPPORT
-		TotalAggPkt = stats->nTotalAggPkt;
-		PacketLength = stats->Length + GetRxPacketShiftBytes8192SU(&stats, false);
-
-		agg_skb = skb;
-		skb = dev_alloc_skb(PacketLength);
-		memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
-#endif
 		priv->stats.rxoktotal++;  //YJ,test,090108
 
 		/* Process the MPDU recevied */
@@ -11506,106 +7165,6 @@ void rtl8192SU_rx_nomal(struct sk_buff* skb)
 		}
 
 		//up is firs pkt, follow is next and next
-#ifdef USB_RX_AGGREGATION_SUPPORT
-		//
-		// The following operations are for processing Rx aggregated packets.
-		//
-		if(TotalAggPkt>0)
-			TotalAggPkt--;
-
-		while ( TotalAggPkt>0 )
-		{// More aggregated packets need to process.
-
-			u8 tmpCRC = 0, tmpICV = 0;
-
-			//Page size must align to multiple of 128-Bytes.
-			if((PacketLength%RxPageSize) != 0)
-				//PacketLength = ((PacketLength/RxPageSize)+1)*RxPageSize;
-				PacketLength = ((PacketLength>>7)+1)*RxPageSize; // RxPageSize is 128bytes as default.
-
-			// Current total packet occupied length in this buffer.
-			PacketOccupiedLendth += PacketLength;
-
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
-			//if(PacketOccupiedLendth>pContext->BufLenUsed)
-			if(PacketOccupiedLendth>skb->len)
-			{
-				RT_TRACE(COMP_RECV, "(1)HalUsbInMpduComplete8192SUsb(): pRtRfdStatus->Length(%#x)!!\n", stats->Length);
-				RT_TRACE(COMP_RECV, "(1)HalUsbInMpduComplete8192SUsb(): Invalid PacketOccupiedLendth(%#x)!!, BufLenUsed(%#x)\n", PacketOccupiedLendth, stats->BufLenUsed);
-				break;
-			}
-#endif
-
-			skb_pull(agg_skb, PacketLength);
-
-			//
-			// Process the MPDU recevied.
-			//
-			//RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
-			RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
-
-#if 0//92SU del
-			tmpCRC = RxDescr->CRC32;
-			tmpICV = RxDescr->ICV;
-			memcpy(agg_skb->data, &agg_skb->data[44], 2);
-			RxDescr->CRC32 = tmpCRC;
-			RxDescr->ICV = tmpICV;
-#endif
-			memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
-			stats.signal = 0;
-			stats.noise = -98;
-			stats.rate = 0;
-			stats.freq = IEEE80211_24GHZ_BAND;
-
-			rtl8192SU_query_rxdesc_status(agg_skb, &stats, true);
-			//PacketLength = stats.Length;
-			PacketLength = stats.Length +  GetRxPacketShiftBytes8192SU(&stats, true);
-
-#if (defined (RTL8192SU_FPGA_2MAC_VERIFICATION)||defined (RTL8192SU_ASIC_VERIFICATION))
-			if((PacketOccupiedLendth+PacketLength)>skb->len)
-			{
-				RT_TRACE(COMP_RECV, "(2)HalUsbInMpduComplete8192SUsb(): Invalid PacketOccupiedLendth(%#x)+PacketLength(%#x)!!, BufLenUsed(%#x)\n",
-					PacketOccupiedLendth, PacketLength, pContext->BufLenUsed);
-				break;
-			}
-#endif
-
-			if(PacketLength > agg_skb->len) {
-				break;
-			}
-
-			/* Process the MPDU recevied */
-			skb = dev_alloc_skb(PacketLength);
-			memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
-			skb_trim(skb, skb->len - 4/*sCrcLng*/);
-
-			rx_pkt_len = skb->len;
-			ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
-			unicast_packet = false;
-			if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
-				//TODO
-			}else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
-				//TODO
-			}else {
-				/* unicast packet */
-				unicast_packet = true;
-			}
-			if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
-				dev_kfree_skb_any(skb);
-			} else {
-				priv->stats.rxoktotal++;
-				if(unicast_packet) {
-					priv->stats.rxbytesunicast += rx_pkt_len;
-				}
-			}
-
-			TotalAggPkt--;
-
-			skb_pull(agg_skb, TempDWord);
-		}
-
-		dev_kfree_skb(agg_skb);
-#endif
 	}
 	else
 	{
@@ -11615,178 +7174,6 @@ void rtl8192SU_rx_nomal(struct sk_buff* skb)
 	}
 
 }
-#else
-u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats  *Status, bool bIsRxAggrSubframe)
-{
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	if (bIsRxAggrSubframe)
-		return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
-			+ Status->RxBufShift + 8);
-	else
-#endif
-		return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
-				+ Status->RxBufShift);
-}
-
-void rtl8192_rx_nomal(struct sk_buff* skb)
-{
-	rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
-	struct net_device *dev=info->dev;
-	struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
-	struct ieee80211_rx_stats stats = {
-		.signal = 0,
-		.noise = -98,
-		.rate = 0,
-		//      .mac_time = jiffies,
-		.freq = IEEE80211_24GHZ_BAND,
-	};
-	u32 rx_pkt_len = 0;
-	struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
-	bool unicast_packet = false;
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	struct sk_buff *agg_skb = NULL;
-	u32  TotalLength = 0;
-	u32  TempDWord = 0;
-	u32  PacketLength = 0;
-	u32  PacketOccupiedLendth = 0;
-	u8   TempByte = 0;
-	u32  PacketShiftBytes = 0;
-	rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
-	u8  PaddingBytes = 0;
-	//add just for testing
-	u8   testing;
-
-#endif
-
-	/* 20 is for ps-poll */
-	if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
-#ifdef USB_RX_AGGREGATION_SUPPORT
-		TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
-#endif
-		/* first packet should not contain Rx aggregation header */
-		query_rxdesc_status(skb, &stats, false);
-		/* TODO */
-		/* hardware related info */
-#ifdef USB_RX_AGGREGATION_SUPPORT
-		if (TempByte & BIT0) {
-			agg_skb = skb;
-			//TotalLength = agg_skb->len - 4; /*sCrcLng*/
-			TotalLength = stats.Length - 4; /*sCrcLng*/
-			//RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
-			/* though the head pointer has passed this position  */
-			TempDWord = *(u32 *)(agg_skb->data - 4);
-			PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
-			skb = dev_alloc_skb(PacketLength);
-			memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
-			PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
-		}
-#endif
-		/* Process the MPDU recevied */
-		skb_trim(skb, skb->len - 4/*sCrcLng*/);
-
-		rx_pkt_len = skb->len;
-		ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
-		unicast_packet = false;
-		if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
-			//TODO
-		}else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
-			//TODO
-		}else {
-			/* unicast packet */
-			unicast_packet = true;
-		}
-
-		if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
-			dev_kfree_skb_any(skb);
-		} else {
-			priv->stats.rxoktotal++;
-			if(unicast_packet) {
-				priv->stats.rxbytesunicast += rx_pkt_len;
-			}
-		}
-#ifdef USB_RX_AGGREGATION_SUPPORT
-		testing = 1;
-		// (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
-		if (TotalLength > 0) {
-			PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
-			if ((PacketOccupiedLendth & 0xFF) != 0)
-				PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
-			PacketOccupiedLendth -= 8;
-			TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
-			if (agg_skb->len > TempDWord)
-				skb_pull(agg_skb, TempDWord);
-			else
-				agg_skb->len = 0;
-
-			while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
-				u8 tmpCRC = 0, tmpICV = 0;
-				//RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
-				RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
-				tmpCRC = RxDescr->CRC32;
-				tmpICV = RxDescr->ICV;
-				memcpy(agg_skb->data, &agg_skb->data[44], 2);
-				RxDescr->CRC32 = tmpCRC;
-				RxDescr->ICV = tmpICV;
-
-				memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
-				stats.signal = 0;
-				stats.noise = -98;
-				stats.rate = 0;
-				stats.freq = IEEE80211_24GHZ_BAND;
-				query_rxdesc_status(agg_skb, &stats, true);
-				PacketLength = stats.Length;
-
-				if(PacketLength > agg_skb->len) {
-					break;
-				}
-				/* Process the MPDU recevied */
-				skb = dev_alloc_skb(PacketLength);
-				memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
-				skb_trim(skb, skb->len - 4/*sCrcLng*/);
-
-				rx_pkt_len = skb->len;
-				ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
-				unicast_packet = false;
-				if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
-					//TODO
-				}else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
-					//TODO
-				}else {
-					/* unicast packet */
-					unicast_packet = true;
-				}
-				if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
-					dev_kfree_skb_any(skb);
-				} else {
-					priv->stats.rxoktotal++;
-					if(unicast_packet) {
-						priv->stats.rxbytesunicast += rx_pkt_len;
-					}
-				}
-				/* should trim the packet which has been copied to target skb */
-				skb_pull(agg_skb, PacketLength);
-				PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
-				PacketOccupiedLendth = PacketLength + PacketShiftBytes;
-				if ((PacketOccupiedLendth & 0xFF) != 0) {
-					PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
-					if (agg_skb->len > PaddingBytes)
-						skb_pull(agg_skb, PaddingBytes);
-					else
-						agg_skb->len = 0;
-				}
-			}
-			dev_kfree_skb(agg_skb);
-		}
-#endif
-	} else {
-		priv->stats.rxurberr++;
-		printk("actual_length:%d\n", skb->len);
-		dev_kfree_skb_any(skb);
-	}
-
-}
-
-#endif
 
 void
 rtl819xusb_process_received_packet(
@@ -11865,7 +7252,6 @@ void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats
 	stats->ntotalfrag = 1;
 }
 
-#ifdef RTL8192SU
 void rtl8192SU_rx_cmd(struct sk_buff *skb)
 {
 	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
@@ -11889,21 +7275,6 @@ void rtl8192SU_rx_cmd(struct sk_buff *skb)
 		//
 		// Collection information in Rx descriptor.
 		//
-#if 0
-		pRxDesc = pContext->Buffer;
-
-		pRfd->Buffer.VirtualAddress = pContext->Buffer; // 061109, rcnjko, for multi-platform consideration..
-
-		pRtRfdStatus->Length = (u2Byte)GET_RX_DESC_PKT_LEN(pRxDesc);
-		pRtRfdStatus->RxDrvInfoSize = 0;
-		pRtRfdStatus->RxBufShift = 0;
-
-		pRfd->PacketLength	= pRfd->Status.Length - sCrcLng;
-		pRfd->FragLength	= pRfd->PacketLength;
-		pRfd->FragOffset	= 0;
-		pRfd->nTotalFrag	= 1;
-		pRfd->queue_id = PipeIndex;
-#endif
 		query_rx_cmdpkt_desc_status(skb,&stats);
 		// this is to be done by amy 080508     prfd->queue_id = 1;
 
@@ -11936,70 +7307,6 @@ void rtl8192SU_rx_cmd(struct sk_buff *skb)
 	RT_TRACE(COMP_RECV, "<--- HalUsbInCommandComplete8192SUsb()\n");
 
 }
-#else
-void rtl8192_rx_cmd(struct sk_buff *skb)
-{
-	struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
-	struct net_device *dev = info->dev;
-	//int ret;
-//	struct urb *rx_urb = info->urb;
-	/* TODO */
-	struct ieee80211_rx_stats stats = {
-		.signal = 0,
-		.noise = -98,
-		.rate = 0,
-		//      .mac_time = jiffies,
-		.freq = IEEE80211_24GHZ_BAND,
-	};
-
-	if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
-	{
-
-		query_rx_cmdpkt_desc_status(skb,&stats);
-		// this is to be done by amy 080508     prfd->queue_id = 1;
-
-
-		//
-		//  Process the command packet received.
-		//
-
-		rtl819xusb_process_received_packet(dev,&stats);
-
-		dev_kfree_skb_any(skb);
-	}
-	else
-		;
-
-
-#if 0
-	desc = (u32*)(skb->data);
-	cmd = (desc[0] >> 30) & 0x03;
-
-	if(cmd == 0x00) {//beacon interrupt
-		//send beacon packet
-		skb = ieee80211_get_beacon(priv->ieee80211);
-
-		if(!skb){
-			DMESG("not enought memory for allocating beacon");
-			return;
-		}
-		skb->cb[0] = BEACON_PRIORITY;
-		skb->cb[1] = 0;
-		skb->cb[2] = ieeerate2rtlrate(priv->ieee80211->basic_rate);
-		ret = rtl8192_tx(dev, skb);
-
-		if( ret != 0 ){
-			printk(KERN_ALERT "tx beacon packet error : %d !\n", ret);
-		}
-		dev_kfree_skb_any(skb);
-	} else {//0x00
-		//{ log the device information
-		// At present, It is not implemented just now.
-		//}
-	}
-#endif
-}
-#endif
 
 void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
 {
@@ -12038,7 +7345,6 @@ void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
 /****************************************************************************
      ---------------------------- USB_STUFF---------------------------
 *****************************************************************************/
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 //LZM Merge from windows HalUsbSetQueuePipeMapping8192SUsb 090319
 static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct net_device *dev)
 {
@@ -12052,13 +7358,11 @@ static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct
 	memset(priv->RtOutPipes,0,16);
 	memset(priv->RtInPipes,0,16);
 
-#ifndef USE_ONE_PIPE
 	iface_desc = intf->cur_altsetting;
 	priv->ep_num = iface_desc->desc.bNumEndpoints;
 
 	for (i = 0; i < priv->ep_num; ++i) {
 		endpoint = &iface_desc->endpoint[i].desc;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
 		if (usb_endpoint_is_bulk_in(endpoint)) {
 			priv->RtInPipes[priv->ep_in_num] = usb_endpoint_num(endpoint);
 			priv->ep_in_num ++;
@@ -12068,19 +7372,6 @@ static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct
 			priv->ep_out_num ++;
 			//printk("out_endpoint_idx = %d\n", usb_endpoint_num(endpoint));
 		}
-#else
-		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) &&
-		     ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) {
-			/* we found a bulk in endpoint */
-			priv->RtInPipes[priv->ep_in_num] = (endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-			priv->ep_in_num ++;
-		} else if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
-		     ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK)) {
-			/* We found bulk out endpoint */
-			priv->RtOutPipes[priv->ep_out_num] = endpoint->bEndpointAddress;
-			priv->ep_out_num ++;
-			}
-#endif
 	}
 	{
 		memset(priv->txqueue_to_outpipemap,0,9);
@@ -12121,16 +7412,9 @@ static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct
 	for(i=0; i < 9; i++)
 		printk("%d  ", priv->txqueue_to_outpipemap[i]);
 	printk("\n");
-#else
-	{
-		memset(priv->txqueue_to_outpipemap,0,9);
-		memset(priv->RtOutPipes,4,16);//all use endpoint 4 for out
-	}
-#endif
 
 	return;
 }
-#endif
 
 static const struct net_device_ops rtl8192_netdev_ops = {
 	.ndo_open		= rtl8192_open,
@@ -12145,69 +7429,34 @@ static const struct net_device_ops rtl8192_netdev_ops = {
 	.ndo_start_xmit		= rtl8192_ieee80211_xmit,
 };
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id)
-#else
-static void * __devinit rtl8192_usb_probe(struct usb_device *udev,
-			                unsigned int ifnum,
-			          const struct usb_device_id *id)
-#endif
 {
 //	unsigned long ioaddr = 0;
 	struct net_device *dev = NULL;
 	struct r8192_priv *priv= NULL;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct usb_device *udev = interface_to_usbdev(intf);
-#endif
+
         RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
 
 	dev = alloc_ieee80211(sizeof(struct r8192_priv));
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-	SET_MODULE_OWNER(dev);
-#endif
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	usb_set_intfdata(intf, dev);
 	SET_NETDEV_DEV(dev, &intf->dev);
-#endif
 	priv = ieee80211_priv(dev);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	priv->ieee80211 = netdev_priv(dev);
-#else
-	priv->ieee80211 = (struct net_device *)dev->priv;
-#endif
 	priv->udev=udev;
 
-#ifdef RTL8192SU
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	HalUsbSetQueuePipeMapping8192SUsb(intf, dev);
-#else//use one pipe
-	{
-		memset(priv->txqueue_to_outpipemap,0,9);
-		memset(priv->RtOutPipes,4,16);//all use endpoint 4 for out
-	}
-#endif
-#endif
 
-#ifdef RTL8192SU
 	//printk("===============>NIC 8192SU\n");
 	priv->ops = &rtl8192su_ops;
-#else
-	//printk("===============>NIC 8192U\n");
-	priv->ops = &rtl8192u_ops;
-#endif
 
 	dev->netdev_ops = &rtl8192_netdev_ops;
 
          //DMESG("Oops: i'm coming\n");
-#if WIRELESS_EXT >= 12
-#if WIRELESS_EXT < 17
-        dev->get_wireless_stats = r8192_get_wireless_stats;
-#endif
         dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
-#endif
+
 	dev->type=ARPHRD_ETHER;
 
 	dev->watchdog_timeo = HZ*3;	//modified by john, 0805
@@ -12234,29 +7483,17 @@ static void * __devinit rtl8192_usb_probe(struct usb_device *udev,
 
 
 	RT_TRACE(COMP_INIT, "Driver probe completed\n");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	return dev;
-#else
 	return 0;
-#endif
-
-
 fail:
 	free_ieee80211(dev);
 
 	RT_TRACE(COMP_ERR, "wlan driver load failed\n");
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	return NULL;
-#else
 	return -ENODEV;
-#endif
-
 }
 
 //detach all the work and timer structure declared or inititialize in r8192U_init function.
 void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
 	cancel_work_sync(&priv->reset_wq);
 	cancel_work_sync(&priv->qos_activate);
 	cancel_delayed_work(&priv->watch_dog_wq);
@@ -12265,35 +7502,11 @@ void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
 	cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
 	//cancel_work_sync(&priv->SetBWModeWorkItem);
 	//cancel_work_sync(&priv->SwChnlWorkItem);
-#else
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	cancel_delayed_work(&priv->reset_wq);
-	cancel_delayed_work(&priv->qos_activate);
-	cancel_delayed_work(&priv->watch_dog_wq);
-	cancel_delayed_work(&priv->update_beacon_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
-	cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
-
-	//cancel_delayed_work(&priv->SetBWModeWorkItem);
-	//cancel_delayed_work(&priv->SwChnlWorkItem);
-#endif
-#endif
-
 }
 
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
-#else
-static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr)
-#endif
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct net_device *dev = usb_get_intfdata(intf);
-#else
-	struct net_device *dev = (struct net_device *)ptr;
-#endif
-
 	struct r8192_priv *priv = ieee80211_priv(dev);
  	if(dev){
 
@@ -12310,9 +7523,7 @@ static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr)
 		}
 	//	priv->rf_close(dev);
 //		rtl8192_SetRFPowerState(dev, eRfOff);
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 		destroy_workqueue(priv->priv_wq);
-#endif
 		//rtl8192_irq_disable(dev);
 		//rtl8192_reset(dev);
 		mdelay(10);
@@ -12322,8 +7533,55 @@ static void __devexit rtl8192_usb_disconnect(struct usb_device *udev, void *ptr)
 	RT_TRACE(COMP_DOWN, "wlan driver removed\n");
 }
 
+/* fun with the built-in ieee80211 stack... */
+extern int ieee80211_debug_init(void);
+extern void ieee80211_debug_exit(void);
+extern int ieee80211_crypto_init(void);
+extern void ieee80211_crypto_deinit(void);
+extern int ieee80211_crypto_tkip_init(void);
+extern void ieee80211_crypto_tkip_exit(void);
+extern int ieee80211_crypto_ccmp_init(void);
+extern void ieee80211_crypto_ccmp_exit(void);
+extern int ieee80211_crypto_wep_init(void);
+extern void ieee80211_crypto_wep_exit(void);
+
 static int __init rtl8192_usb_module_init(void)
 {
+	int ret;
+
+#ifdef CONFIG_IEEE80211_DEBUG
+	ret = ieee80211_debug_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
+		return ret;
+	}
+#endif
+	ret = ieee80211_crypto_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
+		return ret;
+	}
+
+	ret = ieee80211_crypto_tkip_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = ieee80211_crypto_ccmp_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
+			ret);
+		return ret;
+	}
+
+	ret = ieee80211_crypto_wep_init();
+	if (ret) {
+		printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
+		return ret;
+	}
+
 	printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
 	printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
 	RT_TRACE(COMP_INIT, "Initializing module");
@@ -12339,6 +7597,14 @@ static void __exit rtl8192_usb_module_exit(void)
 
 	RT_TRACE(COMP_DOWN, "Exiting");
 	rtl8192_proc_module_remove();
+
+	ieee80211_crypto_tkip_exit();
+	ieee80211_crypto_ccmp_exit();
+	ieee80211_crypto_wep_exit();
+	ieee80211_crypto_deinit();
+#ifdef CONFIG_IEEE80211_DEBUG
+	ieee80211_debug_exit();
+#endif
 }
 
 
@@ -12356,14 +7622,6 @@ void rtl8192_try_wake_queue(struct net_device *dev, int pri)
 		ieee80211_wake_queue(priv->ieee80211);
 }
 
-#if 0
-void DisableHWSecurityConfig8192SUsb(struct net_device *dev)
-{
-	u8 SECR_value = 0x0;
-	write_nic_byte(dev, SECR,  SECR_value);//SECR_value |  SCR_UseDK );
-}
-#endif
-
 void EnableHWSecurityConfig8192(struct net_device *dev)
 {
         u8 SECR_value = 0x0;
diff --git a/drivers/staging/rtl8192su/r8192U_dm.c b/drivers/staging/rtl8192su/r8192U_dm.c
index 304274b..5358ae8 100644
--- a/drivers/staging/rtl8192su/r8192U_dm.c
+++ b/drivers/staging/rtl8192su/r8192U_dm.c
@@ -15,42 +15,18 @@ Major Change History:
 --*/
 
 
-#ifdef RTL8192SU
 #include "r8192U.h"
 #include "r8192U_dm.h"
-//#include "r8190_rtl8256.h"
 #include "r819xU_cmdpkt.h"
 #include "r8192S_hw.h"
 #include "r8192S_phy.h"
 #include "r8192S_phyreg.h"
-#else
-#include "r8192U.h"
-#include "r8192U_dm.h"
-#include "r8192U_hw.h"
-#include "r819xU_phy.h"
-#include "r819xU_phyreg.h"
-#include "r8190_rtl8256.h"
-#include "r819xU_cmdpkt.h"
-#endif
 
 /*---------------------------Define Local Constant---------------------------*/
 //
 // Indicate different AP vendor for IOT issue.
 //
-#if 0
-typedef enum _HT_IOT_PEER
-{
-	HT_IOT_PEER_UNKNOWN = 0,
-	HT_IOT_PEER_REALTEK = 1,
-	HT_IOT_PEER_BROADCOM = 2,
-	HT_IOT_PEER_RALINK = 3,
-	HT_IOT_PEER_ATHEROS = 4,
-	HT_IOT_PEER_CISCO = 5,
-	HT_IOT_PEER_MAX = 6
-}HT_IOT_PEER_E, *PHTIOT_PEER_E;
-#endif
 #if 1
-#ifdef RTL8192SU
 		static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
 		// UNKNOWN	REALTEK_90	/*REALTEK_92SE*/	BROADCOM	RALINK		ATHEROS		CISCO		MARVELL		92U_AP		SELF_AP
 		   { 0xa44f, 	0x5ea44f, 	0x5ea44f,		0xa44f,		0xa44f, 		0xa44f, 		0xa630,		0xa42b,		0x5e4322,	0x5e4322};
@@ -58,14 +34,6 @@ typedef enum _HT_IOT_PEER
 		// UNKNOWN	REALTEK		/*REALTEK_92SE*/	BROADCOM	RALINK		ATHEROS		CISCO		MARVELL		92U_AP		SELF_AP
 		   { 0x5ea44f, 	0xa44f, 	0x5ea44f,		0x5e4322, 	0x5ea422, 	0x5e4322, 	0x3ea44f,	0x5ea42b,	0x5e4322,	0x5e4322};
 
-#else
-
-static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
-		{ 0x5e4322, 	0x5e4322, 	0x5ea44f,		0x5e4322, 	0x604322, 	0xa44f, 	0x5ea44f};
-static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
-		{ 0x5e4322, 	0xa44f, 	0x5ea44f,	        0x5e4322, 	0x604322, 	0x5ea44f, 	0x5ea44f};
-
-#endif
 #endif
 
 #define RTK_UL_EDCA 0xa44f
@@ -98,12 +66,7 @@ extern void hal_dm_watchdog(struct net_device *dev);
 
 
 extern	void	init_rate_adaptive(struct net_device *dev);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern	void	dm_txpower_trackingcallback(struct work_struct *work);
-#else
-extern	void	dm_txpower_trackingcallback(struct net_device *dev);
-#endif
-
 extern	void	dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
 extern	void	dm_restore_dynamic_mechanism_state(struct net_device *dev);
 extern	void	dm_backup_dynamic_mechanism_state(struct net_device *dev);
@@ -118,15 +81,8 @@ extern	void dm_force_tx_fw_info(struct net_device *dev,
 										u32		force_value);
 extern	void	dm_init_edca_turbo(struct net_device *dev);
 extern	void	dm_rf_operation_test_callback(unsigned long data);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern	void	dm_rf_pathcheck_workitemcallback(struct work_struct *work);
-#else
-extern	void	dm_rf_pathcheck_workitemcallback(struct net_device *dev);
-#endif
 extern	void dm_fsync_timer_callback(unsigned long data);
-#if 0
-extern	bool	dm_check_lbus_status(struct net_device *dev);
-#endif
 extern	void dm_check_fsync(struct net_device *dev);
 extern	void	dm_shadow_init(struct net_device *dev);
 
@@ -211,7 +167,6 @@ static	void	dm_ctstoself(struct net_device *dev);
 //================================================================================
 //	HW Dynamic mechanism interface.
 //================================================================================
-#ifdef RTL8192SU
 static void dm_CheckAggrPolicy(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
@@ -282,7 +237,6 @@ static void dm_CheckAggrPolicy(struct net_device *dev)
 	lastTxOkCnt = priv->stats.txbytesunicast;
 	lastRxOkCnt = priv->stats.rxbytesunicast;
 }
-#endif
 //
 //	Description:
 //		Prepare SW resource for HW dynamic mechanism.
@@ -302,11 +256,7 @@ init_hal_dm(struct net_device *dev)
 	//Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
 	dm_init_dynamic_txpower(dev);
 	init_rate_adaptive(dev);
-#ifdef RTL8192SU
 	dm_initialize_txpower_tracking(dev);
-#else
-	//dm_initialize_txpower_tracking(dev);
-#endif
 	dm_dig_init(dev);
 	dm_init_edca_turbo(dev);
 	dm_init_bandwidth_autoswitch(dev);
@@ -324,101 +274,8 @@ extern void deinit_hal_dm(struct net_device *dev)
 }
 
 
-#ifdef USB_RX_AGGREGATION_SUPPORT
-void dm_CheckRxAggregation(struct net_device *dev) {
-	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
-	PRT_HIGH_THROUGHPUT	pHTInfo = priv->ieee80211->pHTInfo;
-	static unsigned long	lastTxOkCnt = 0;
-	static unsigned long	lastRxOkCnt = 0;
-	unsigned long		curTxOkCnt = 0;
-	unsigned long		curRxOkCnt = 0;
 
-/*
-	if (pHalData->bForcedUsbRxAggr) {
-		if (pHalData->ForcedUsbRxAggrInfo == 0) {
-			if (pHalData->bCurrentRxAggrEnable) {
-				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
-			}
-		} else {
-			if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) {
-				Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE);
-			}
-		}
-		return;
-	}
 
-*/
-#ifdef RTL8192SU
-	if (priv->bForcedUsbRxAggr) {
-		if (priv->ForcedUsbRxAggrInfo == 0) {
-			if (priv->bCurrentRxAggrEnable) {
-				//Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
-				write_nic_dword(dev, 0x1a8, 0);
-				priv->bCurrentRxAggrEnable = false;
-			}
-		} else {
-			if (!priv->bCurrentRxAggrEnable || (priv->ForcedUsbRxAggrInfo != priv->LastUsbRxAggrInfoSetting)) {
-				u32 ulValue;
-				ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
-						(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
-				/*
-				 * If usb rx firmware aggregation is enabled,
-				 * when anyone of three threshold conditions above is reached,
-				 * firmware will send aggregated packet to driver.
-			 	*/
-				write_nic_dword(dev, 0x1a8, ulValue);
-				priv->bCurrentRxAggrEnable = true;
-			}
-		}
-		return;
-	}
-
-	if((priv->ieee80211->mode & WIRELESS_MODE_B) || (priv->ieee80211->mode & WIRELESS_MODE_G))
-	{
-		if (priv->bCurrentRxAggrEnable)
-		{
-			RT_TRACE(COMP_RECV, "dm_CheckRxAggregation() :  Disable Rx Aggregation!!\n");
-			write_nic_dword(dev, 0x1a8, 0);
-			priv->bCurrentRxAggrEnable = false;
-			return;
-		}
-	}
-#endif
-
-	curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
-	curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
-
-	if((curTxOkCnt + curRxOkCnt) < 15000000) {
-		return;
-	}
-
-	if(curTxOkCnt > 4*curRxOkCnt) {
-		if (priv->bCurrentRxAggrEnable) {
-			write_nic_dword(dev, 0x1a8, 0);
-			priv->bCurrentRxAggrEnable = false;
-		}
-	}else{
-		if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
-			u32 ulValue;
-			ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
-				(pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
-			/*
-			 * If usb rx firmware aggregation is enabled,
-			 * when anyone of three threshold conditions above is reached,
-			 * firmware will send aggregated packet to driver.
-			 */
-			write_nic_dword(dev, 0x1a8, ulValue);
-			priv->bCurrentRxAggrEnable = true;
-		}
-	}
-
-	lastTxOkCnt = priv->stats.txbytesunicast;
-	lastRxOkCnt = priv->stats.rxbytesunicast;
-}	// dm_CheckEdcaTurbo
-#endif
-
-
-#ifdef RTL8192SU
 //#if 0
 extern  void    hal_dm_watchdog(struct net_device *dev)
 {
@@ -447,9 +304,6 @@ extern  void    hal_dm_watchdog(struct net_device *dev)
 	//if (IS_HARDWARE_TYPE_8192S(dev))
 	return;
 
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	dm_CheckRxAggregation(dev);
-#endif
 #ifdef TO_DO_LIST
 	if(Adapter->MgntInfo.mActingAsAp)
 	{
@@ -476,34 +330,6 @@ extern  void    hal_dm_watchdog(struct net_device *dev)
 	dm_ctstoself(dev);
 
 }	//HalDmWatchDog
-#else
-extern  void    hal_dm_watchdog(struct net_device *dev)
-{
-        //struct r8192_priv *priv = ieee80211_priv(dev);
-
-	//static u8 	previous_bssid[6] ={0};
-
-	/*Add by amy 2008/05/15 ,porting from windows code.*/
-	dm_check_rate_adaptive(dev);
-	dm_dynamic_txpower(dev);
-	dm_check_txrateandretrycount(dev);
-	dm_check_txpower_tracking(dev);
-	dm_ctrl_initgain_byrssi(dev);
-	dm_check_edca_turbo(dev);
-	dm_bandwidth_autoswitch(dev);
-	dm_check_rfctrl_gpio(dev);
-	dm_check_rx_path_selection(dev);
-	dm_check_fsync(dev);
-
-	// Add by amy 2008-05-15 porting from windows code.
-	dm_check_pbc_gpio(dev);
-	dm_send_rssi_tofw(dev);
-	dm_ctstoself(dev);
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	dm_CheckRxAggregation(dev);
-#endif
-}	//HalDmWatchDog
-#endif
 
 /*
   * Decide Rate Adaptive Set according to distance (signal strength)
@@ -1081,33 +907,6 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
 		return;
 	}
 
-	//==========================
-	// this is only for test, should be masked
-#if 0
-{
-	//UINT32	eRFPath;
-	//UINT32	start_rf, end_rf;
-	UINT32	curr_addr;
-	//UINT32	reg_addr;
-	//UINT32	reg_addr_end;
-	UINT32	reg_value;
-	//start_rf 		= RF90_PATH_A;
-	//end_rf 			= RF90_PATH_B;//RF90_PATH_MAX;
-	//reg_addr 		= 0x0;
-	//reg_addr_end 	= 0x2F;
-
-		for (curr_addr = 0; curr_addr < 0x2d; curr_addr++)
-		{
-			reg_value = PHY_QueryRFReg(	Adapter, (RF90_RADIO_PATH_E)RF90_PATH_A,
-										curr_addr, bMaskDWord);
-		}
-
-	pHalData->TXPowercount = 0;
-	return;
-}
-#endif
-	//==========================
-
 	// read and filter out unreasonable value
 	tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);	// 0x12: RF Reg[10:7]
 	RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
@@ -1180,17 +979,11 @@ static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
 	priv->txpower_count = 0;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern	void	dm_txpower_trackingcallback(struct work_struct *work)
 {
 	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
        struct net_device *dev = priv->ieee80211->dev;
-#else
-extern	void	dm_txpower_trackingcallback(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
 
 #ifdef RTL8190P
 	dm_TXPowerTrackingCallback_TSSI(dev);
@@ -1708,37 +1501,15 @@ static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
 
 }
 
-#ifndef RTL8192SU
-static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	// Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism
-	// can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
-	// 3-wire by driver cause RF goes into wrong state.
-	if(priv->ieee80211->FwRWRF)
-		priv->btxpower_tracking = TRUE;
-	else
-		priv->btxpower_tracking = FALSE;
-	priv->txpower_count       = 0;
-	priv->btxpower_trackingInit = FALSE;
-}
-#endif
 
 void dm_initialize_txpower_tracking(struct net_device *dev)
 {
 #if (defined RTL8190P)
 	dm_InitializeTXPowerTracking_TSSI(dev);
-#elif (defined RTL8192SU)
+#else
 	// 2009/01/12 MH Enable for 92S series channel 1-14 CCK tx pwer setting for MP.
 	//
 	dm_InitializeTXPowerTracking_TSSI(dev);
-#else
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	if(priv->bDcut == TRUE)
-		dm_InitializeTXPowerTracking_TSSI(dev);
-	else
-		dm_InitializeTXPowerTracking_ThermalMeter(dev);
 #endif
 }// dm_InitializeTXPowerTracking
 
@@ -1754,15 +1525,7 @@ static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
 	{
 	 	if((tx_power_track_counter % 30 == 0)&&(tx_power_track_counter != 0))
 	 	{
-	 		#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 				queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
-			#else
-				#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-				schedule_task(&priv->txpower_tracking_wq);
-				#else
-				queue_work(priv->priv_wq,&priv->txpower_tracking_wq);
-				#endif
-			#endif
 	 	}
 		tx_power_track_counter++;
 	}
@@ -1774,19 +1537,7 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	static u8 	TM_Trigger=0;
-#if 0
-	u1Byte					i;
-	u4Byte tmpRegA;
-	for(i=0; i<50; i++)
-	{
-		tmpRegA = PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x12, 0x078);	// 0x12: RF Reg[10:7]
-		PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
-		//delay_us(100);
-		PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
-		//delay_us(100);
-	}
-	DbgPrint("Trigger and readback ThermalMeter, write RF reg0x2 = 0x4d to 0x4f for 50 times\n");
-#else
+
 	//DbgPrint("dm_CheckTXPowerTracking() \n");
 	if(!priv->btxpower_tracking)
 		return;
@@ -1804,35 +1555,19 @@ static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
 		//Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
 		//actually write reg0x02 bit1=0, then bit1=1.
 		//DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
-#ifdef RTL8192SU
 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4d);
 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4f);
 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4d);
 		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4f);
-#else
-		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
-		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
-		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
-		rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
-#endif
 		TM_Trigger = 1;
 		return;
 	}
 	else
 	{
 		//DbgPrint("Schedule TxPowerTrackingWorkItem\n");
-		#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 			queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
-		#else
-			#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-			schedule_task(&priv->txpower_tracking_wq);
-			#else
-			queue_work(priv->priv_wq,&priv->txpower_tracking_wq);
-			#endif
-		#endif
 		TM_Trigger = 0;
 	}
-#endif
 }
 
 
@@ -2040,14 +1775,6 @@ extern void dm_restore_dynamic_mechanism_state(struct net_device *dev)
 			//cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);
 			write_nic_dword(dev, RATR0, ratr_value);
 			write_nic_byte(dev, UFWP, 1);
-#if 0		// Disable old code.
-			u1Byte index;
-			u4Byte input_value;
-			index = (u1Byte)((((pu4Byte)(val))[0]) >> 28);
-			input_value = (((pu4Byte)(val))[0]) & 0x0fffffff;
-			// TODO: Correct it. Emily 2007.01.11
-			PlatformEFIOWrite4Byte(Adapter, RATR0+index*4, input_value);
-#endif
 	}
 	//Resore TX Power Tracking Index
 	if(priv->btxpower_trackingInit && priv->btxpower_tracking){
@@ -2150,14 +1877,12 @@ extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
 								u32		dm_type,
 								u32		dm_value)
 {
-#ifdef RTL8192SU
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	if(dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
 		priv->MidHighPwrTHR_L2 = (u8)dm_value;
 	else if(dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW)
 		priv->MidHighPwrTHR_L1 = (u8)dm_value;
 	return;
-#endif
 	if (dm_type == DIG_TYPE_THRESH_HIGH)
 	{
 		dm_digtable.rssi_high_thresh = dm_value;
@@ -2318,29 +2043,6 @@ dm_change_rxpath_selection_setting(
 	}
 }
 
-#if 0
-extern void dm_force_tx_fw_info(struct net_device *dev,
-										u32		force_type,
-										u32		force_value)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	if (force_type == 0)	// don't force TxSC
-	{
-		//DbgPrint("Set Force SubCarrier Off\n");
-		priv->tx_fwinfo_force_subcarriermode = 0;
-	}
-	else if(force_type == 1) //force
-	{
-		//DbgPrint("Set Force SubCarrier On\n");
-		priv->tx_fwinfo_force_subcarriermode = 1;
-		if(force_value > 3)
-			force_value = 3;
-		priv->tx_fwinfo_force_subcarrierval = (u8)force_value;
-	}
-}
-#endif
-
 /*-----------------------------------------------------------------------------
  * Function:	dm_dig_init()
  *
@@ -2529,15 +2231,7 @@ static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
 		{
 			/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
 			// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-#ifdef RTL8192SU
 			rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x00);
-#else
-			#ifdef RTL8190P
-				write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
-			#else
-				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
-			#endif
-#endif
 			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 				write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
 			*/
@@ -2681,15 +2375,7 @@ static void dm_ctrl_initgain_byrssi_highpwr(
 		// 3.1 Higher PD_TH for OFDM for high power state.
 		if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
 		{
-#ifdef RTL8192SU
 			rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x10);
-#else
-			#ifdef RTL8190P
-				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
-			#else
-				write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
-			#endif
-#endif
 			/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 				write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
 			*/
@@ -2856,15 +2542,7 @@ static void dm_pd_th(
 				{
 					/* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
 					// 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
-#ifdef RTL8192SU
 					rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x00);
-#else
-					#ifdef RTL8190P
-						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
-					#else
-						write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
-					#endif
-#endif
 					/*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
 						write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
 					*/
@@ -3028,7 +2706,6 @@ static void dm_check_edca_turbo(
 	{
 		curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
 		curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
-#ifdef RTL8192SU
 		// Modify EDCA parameters selection bias
 		// For some APs, use downlink EDCA parameters for uplink+downlink
 		if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX)
@@ -3071,31 +2748,6 @@ static void dm_check_edca_turbo(
 			}
 			priv->bcurrent_turbo_EDCA = true;
 		}
-#else
-		// For RT-AP, we needs to turn it on when Rx>Tx
-		if(curRxOkCnt > 4*curTxOkCnt)
-		{
-			//printk("%s():curRxOkCnt > 4*curTxOkCnt\n");
-			if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
-			{
-				write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
-				priv->bis_cur_rdlstate = true;
-			}
-		}
-		else
-		{
-
-			//printk("%s():curRxOkCnt < 4*curTxOkCnt\n");
-			if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
-			{
-				write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
-				priv->bis_cur_rdlstate = false;
-			}
-
-		}
-
-		priv->bcurrent_turbo_EDCA = true;
-#endif
 	}
 	else
 	{
@@ -3235,80 +2887,6 @@ static void dm_ctstoself(struct net_device *dev)
 	}
 }
 
-
-#if 0
-/*-----------------------------------------------------------------------------
- * Function:	dm_rf_operation_test_callback()
- *
- * Overview:	Only for RF operation test now.
- *
- * Input:		NONE
- *
- * Output:		NONE
- *
- * Return:		NONE
- *
- * Revised History:
- *	When		Who		Remark
- *	05/29/2008	amy		Create Version 0 porting from windows code.
- *
- *---------------------------------------------------------------------------*/
-extern void dm_rf_operation_test_callback(unsigned long dev)
-{
-//	struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
-	u8 erfpath;
-
-
-	for(erfpath=0; erfpath<4; erfpath++)
-	{
-		//DbgPrint("Set RF-%d\n\r", eRFPath);
-		//PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
-		udelay(100);
-	}
-
-	{
-		//PlatformSetPeriodicTimer(Adapter, &pHalData->RfTest1Timer, 500);
-	}
-
-	// For test
-	{
-		//u8 i;
-		//PlatformSetPeriodicTimer(Adapter, &pHalData->RfTest1Timer, 500);
-#if 0
-		for(i=0; i<50; i++)
-		{
-			// Write Test
-			PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
-			//delay_us(100);
-			PHY_SetRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
-			//delay_us(100);
-			PHY_SetRFReg(Adapter, RF90_PATH_C, 0x02, bMask12Bits, 0x4d);
-			//delay_us(100);
-			PHY_SetRFReg(Adapter, RF90_PATH_C, 0x02, bMask12Bits, 0x4f);
-			//delay_us(100);
-
-#if 0
-			// Read test
-			PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits);
-			//delay_us(100);
-			PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x02, bMask12Bits);
-			//delay_us(100);
-			PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x12, bMask12Bits);
-			//delay_us(100);
-			PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x12, bMask12Bits);
-			//delay_us(100);
-			PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x21, bMask12Bits);
-			//delay_us(100);
-			PHY_QueryRFReg(Adapter, RF90_PATH_A, 0x21, bMask12Bits);
-			//delay_us(100);
-#endif
-		}
-#endif
-	}
-
-}	/* DM_RfOperationTestCallBack */
-#endif
-
 /*-----------------------------------------------------------------------------
  * Function:	dm_check_rfctrl_gpio()
  *
@@ -3341,19 +2919,9 @@ static void dm_check_rfctrl_gpio(struct net_device * dev)
 #ifdef RTL8192U
 	return;
 #endif
-#ifdef RTL8192SU
 	return;
-#endif
 #ifdef RTL8192E
-	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
 		queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
-	#else
-		#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		schedule_task(&priv->gpio_change_rf_wq);
-             #else
-		queue_work(priv->priv_wq,&priv->gpio_change_rf_wq);
-		#endif
-	#endif
 #endif
 
 }	/* dm_CheckRfCtrlGPIO */
@@ -3394,7 +2962,6 @@ static	void	dm_check_pbc_gpio(struct net_device *dev)
 		priv->bpbc_pressed = true;
 	}
 #endif
-#ifdef RTL8192SU
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	u8	tmp1byte;
 
@@ -3420,7 +2987,6 @@ static	void	dm_check_pbc_gpio(struct net_device *dev)
 		priv->bpbc_pressed = true;
 	}
 
-#endif
 
 
 }
@@ -3442,17 +3008,11 @@ static	void	dm_check_pbc_gpio(struct net_device *dev)
  *	02/21/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern	void	dm_gpio_change_rf_callback(struct work_struct *work)
 {
 	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
        struct net_device *dev = priv->ieee80211->dev;
-#else
-extern	void	dm_gpio_change_rf_callback(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
 	u8 tmp1byte;
 	RT_RF_POWER_STATE	eRfPowerStateToSet;
 	bool bActuallySet = false;
@@ -3520,17 +3080,11 @@ extern	void	dm_gpio_change_rf_callback(struct net_device *dev)
  *	01/30/2008	MHC		Create Version 0.
  *
  *---------------------------------------------------------------------------*/
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern	void	dm_rf_pathcheck_workitemcallback(struct work_struct *work)
 {
 	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
        struct net_device *dev =priv->ieee80211->dev;
-#else
-extern	void	dm_rf_pathcheck_workitemcallback(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
 	//bool bactually_set = false;
 	u8 rfpath = 0, i;
 
@@ -3855,15 +3409,8 @@ static void dm_rxpath_sel_byrssi(struct net_device * dev)
 static	void	dm_check_rx_path_selection(struct net_device *dev)
 {
 	struct r8192_priv *priv = ieee80211_priv(dev);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+
 	queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
-#else
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	schedule_task(&priv->rfpath_check_wq);
-#else
-	queue_work(priv->priv_wq,&priv->rfpath_check_wq);
-#endif
-#endif
 }	/* dm_CheckRxRFPath */
 
 
@@ -4018,15 +3565,7 @@ extern void dm_fsync_timer_callback(unsigned long data)
 			write_nic_byte(dev, 0xC3e, 0x96);
 		}
 		priv->ContiuneDiffCount = 0;
-#ifdef RTL8192SU
 	rtl8192_setBBreg(dev, rOFDM0_RxDetector2, bMaskDWord, 0x164052cd);
-#else
-	#ifdef RTL8190P
-		write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd);
-	#else
-		write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
-	#endif
-#endif
 	}
 	RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
 	RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
@@ -4215,12 +3754,6 @@ void dm_check_fsync(struct net_device *dev)
 						#endif
 
 						reg_c38_State = RegC38_NonFsync_Other_AP;
-					#if 0//cosa
-						if (Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
-							DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x10);
-						else
-							DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x90);
-					#endif
 					}
 				}
 				else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
@@ -4265,51 +3798,6 @@ void dm_check_fsync(struct net_device *dev)
 	}
 }
 
-#if 0
-/*-----------------------------------------------------------------------------
- * Function:	DM_CheckLBusStatus()
- *
- * Overview:	For 9x series, we must make sure LBUS is active for IO.
- *
- * Input:		NONE
- *
- * Output:		NONE
- *
- * Return:		NONE
- *
- * Revised History:
- *	When		Who		Remark
- *	02/22/2008	MHC		Create Version 0.
- *
- *---------------------------------------------------------------------------*/
-extern	s1Byte	DM_CheckLBusStatus(IN	PADAPTER	Adapter)
-{
-	PMGNT_INFO	pMgntInfo=&Adapter->MgntInfo;
-
-#if (HAL_CODE_BASE & RTL819X)
-
-#if (HAL_CODE_BASE == RTL8192)
-
-#if( DEV_BUS_TYPE==PCI_INTERFACE)
-	//return (pMgntInfo->bLbusEnable);	// For debug only
-	return TRUE;
-#endif
-
-#if( DEV_BUS_TYPE==USB_INTERFACE)
-	return TRUE;
-#endif
-
-#endif	// #if (HAL_CODE_BASE == RTL8192)
-
-#if (HAL_CODE_BASE == RTL8190)
-	return TRUE;
-#endif	// #if (HAL_CODE_BASE == RTL8190)
-
-#endif	// #if (HAL_CODE_BASE & RTL819X)
-}	/* DM_CheckLBusStatus */
-
-#endif
-
 /*-----------------------------------------------------------------------------
  * Function:	dm_shadow_init()
  *
@@ -4439,16 +3927,6 @@ static void dm_dynamic_txpower(struct net_device *dev)
 		(priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
 	{
 		RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190()  channel = %d \n" , priv->ieee80211->current_network.channel);
-#ifndef RTL8192SU
-#if  defined(RTL8190P) || defined(RTL8192E)
-		SetTxPowerLevel8190(Adapter,pHalData->CurrentChannel);
-#endif
-
-#ifdef RTL8192U
-		rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
-		//pHalData->bStartTxCtrlByTPCNFR = FALSE;    //Clear th flag of Set TX Power from Sitesurvey
-#endif
-#endif
 	}
 	priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
 	priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
@@ -4462,11 +3940,7 @@ static void dm_check_txrateandretrycount(struct net_device * dev)
 	struct ieee80211_device* ieee = priv->ieee80211;
 	//for 11n tx rate
 //	priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
-#ifdef RTL8192SU
 	ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, TX_RATE_REG);
-#else
-	ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
-#endif
 	//printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
 	//for initial tx rate
 //	priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
@@ -4478,24 +3952,6 @@ static void dm_check_txrateandretrycount(struct net_device * dev)
 
 static void dm_send_rssi_tofw(struct net_device *dev)
 {
-#ifndef RTL8192SU
-	DCMD_TXCMD_T			tx_cmd;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	// If we test chariot, we should stop the TX command ?
-	// Because 92E will always silent reset when we send tx command. We use register
-	// 0x1e0(byte) to botify driver.
-	write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
-	return;
-#if 1
-	tx_cmd.Op		= TXCMD_SET_RX_RSSI;
-	tx_cmd.Length	= 4;
-	tx_cmd.Value		= priv->undecorated_smoothed_pwdb;
-
-	cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
-								DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
-#endif
-#endif
 }
 
 #ifdef TO_DO_LIST
diff --git a/drivers/staging/rtl8192su/r8192U_dm.h b/drivers/staging/rtl8192su/r8192U_dm.h
index 1e05d75..1b48436 100644
--- a/drivers/staging/rtl8192su/r8192U_dm.h
+++ b/drivers/staging/rtl8192su/r8192U_dm.h
@@ -62,50 +62,6 @@
 #define 		Initial_Tx_Rate_Reg         	  0x1b9
 #define 		Tx_Retry_Count_Reg         0x1ac
 #define		RegC38_TH				 20
-#if 0
-//----------------------------------------------------------------------------
-//       8190 Rate Adaptive Table Register	(offset 0x320, 4 byte)
-//----------------------------------------------------------------------------
-
-//CCK
-#define	RATR_1M					0x00000001
-#define	RATR_2M					0x00000002
-#define	RATR_55M					0x00000004
-#define	RATR_11M					0x00000008
-//OFDM
-#define	RATR_6M					0x00000010
-#define	RATR_9M					0x00000020
-#define	RATR_12M					0x00000040
-#define	RATR_18M					0x00000080
-#define	RATR_24M					0x00000100
-#define	RATR_36M					0x00000200
-#define	RATR_48M					0x00000400
-#define	RATR_54M					0x00000800
-//MCS 1 Spatial Stream
-#define	RATR_MCS0					0x00001000
-#define	RATR_MCS1					0x00002000
-#define	RATR_MCS2					0x00004000
-#define	RATR_MCS3					0x00008000
-#define	RATR_MCS4					0x00010000
-#define	RATR_MCS5					0x00020000
-#define	RATR_MCS6					0x00040000
-#define	RATR_MCS7					0x00080000
-//MCS 2 Spatial Stream
-#define	RATR_MCS8					0x00100000
-#define	RATR_MCS9					0x00200000
-#define	RATR_MCS10					0x00400000
-#define	RATR_MCS11					0x00800000
-#define	RATR_MCS12					0x01000000
-#define	RATR_MCS13					0x02000000
-#define	RATR_MCS14					0x04000000
-#define	RATR_MCS15					0x08000000
-// ALL CCK Rate
-#define RATE_ALL_CCK				RATR_1M|RATR_2M|RATR_55M|RATR_11M
-#define RATE_ALL_OFDM_AG			RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M\
-									|RATR_36M|RATR_48M|RATR_54M
-#define RATE_ALL_OFDM_2SS			RATR_MCS8|RATR_MCS9	|RATR_MCS10|RATR_MCS11| \
-									RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
-#endif
 /*--------------------------Define Parameters-------------------------------*/
 
 
@@ -275,11 +231,7 @@ extern  void deinit_hal_dm(struct net_device *dev);
 extern void hal_dm_watchdog(struct net_device *dev);
 
 extern  void    init_rate_adaptive(struct net_device *dev);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern  void    dm_txpower_trackingcallback(struct work_struct *work);
-#else
-extern  void    dm_txpower_trackingcallback(struct net_device *dev);
-#endif
 extern  void    dm_restore_dynamic_mechanism_state(struct net_device *dev);
 extern  void    dm_backup_dynamic_mechanism_state(struct net_device *dev);
 extern  void    dm_change_dynamic_initgain_thresh(struct net_device *dev,
@@ -287,16 +239,9 @@ extern  void    dm_change_dynamic_initgain_thresh(struct net_device *dev,
 extern  void    dm_force_tx_fw_info(struct net_device *dev,u32 force_type, u32 force_value);
 extern  void    dm_init_edca_turbo(struct net_device *dev);
 extern  void    dm_rf_operation_test_callback(unsigned long data);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
 extern  void    dm_rf_pathcheck_workitemcallback(struct work_struct *work);
-#else
-extern  void    dm_rf_pathcheck_workitemcallback(struct net_device *dev);
-#endif
 extern  void dm_fsync_timer_callback(unsigned long data);
 extern	void	dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
-#if 0
-extern  char    dm_check_lbus_status(IN PADAPTER        Adapter);
-#endif
 extern  void    dm_shadow_init(struct net_device *dev);
 extern void dm_initialize_txpower_tracking(struct net_device *dev);
 /*--------------------------Exported Function prototype---------------------*/
diff --git a/drivers/staging/rtl8192su/r8192U_hw.h b/drivers/staging/rtl8192su/r8192U_hw.h
deleted file mode 100644
index f2500e6..0000000
--- a/drivers/staging/rtl8192su/r8192U_hw.h
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
-	This is part of rtl8187 OpenSource driver.
-	Copyright (C) Andrea Merello 2004-2005  <andreamrl@tiscali.it>
-	Released under the terms of GPL (General Public Licence)
-
-	Parts of this driver are based on the GPL part of the
-	official Realtek driver.
-	Parts of this driver are based on the rtl8180 driver skeleton
-	from Patric Schenke & Andres Salomon.
-	Parts of this driver are based on the Intel Pro Wireless
-	2100 GPL driver.
-
-	We want to tanks the Authors of those projects
-	and the Ndiswrapper project Authors.
-*/
-
-/* Mariusz Matuszek added full registers definition with Realtek's name */
-
-/* this file contains register definitions for the rtl8187 MAC controller */
-#ifndef R8192_HW
-#define R8192_HW
-
-typedef enum _VERSION_819xU{
-	VERSION_819xU_A, // A-cut
-	VERSION_819xU_B, // B-cut
-	VERSION_819xU_C,// C-cut
-}VERSION_819xU,*PVERSION_819xU;
-//added for different RF type
-typedef enum _RT_RF_TYPE_DEF
-{
-	RF_1T2R = 0,
-	RF_2T4R,
-
-	RF_819X_MAX_TYPE
-}RT_RF_TYPE_DEF;
-
-
-typedef enum _BaseBand_Config_Type{
-	BaseBand_Config_PHY_REG = 0,			//Radio Path A
-	BaseBand_Config_AGC_TAB = 1,			//Radio Path B
-}BaseBand_Config_Type, *PBaseBand_Config_Type;
-#if 0
-typedef enum _RT_RF_TYPE_819xU{
-	RF_TYPE_MIN = 0,
-	RF_8225,
-	RF_8256,
-	RF_8258,
-	RF_PSEUDO_11N = 4,
-}RT_RF_TYPE_819xU, *PRT_RF_TYPE_819xU;
-#endif
-#define	RTL8187_REQT_READ	0xc0
-#define	RTL8187_REQT_WRITE	0x40
-#define	RTL8187_REQ_GET_REGS	0x05
-#define	RTL8187_REQ_SET_REGS	0x05
-
-#define MAX_TX_URB 16  //less URB will cause 2.4.31 crash, need to fix it further
-#define MAX_RX_URB 16
-
-#define R8180_MAX_RETRY 255
-//#define MAX_RX_NORMAL_URB 3
-//#define MAX_RX_COMMAND_URB 2
-#define RX_URB_SIZE 9100
-
-#define BB_ANTATTEN_CHAN14	0x0c
-#define BB_ANTENNA_B 0x40
-
-#define BB_HOST_BANG (1<<30)
-#define BB_HOST_BANG_EN (1<<2)
-#define BB_HOST_BANG_CLK (1<<1)
-#define BB_HOST_BANG_RW (1<<3)
-#define BB_HOST_BANG_DATA	 1
-
-//#if (RTL819X_FPGA_VER & RTL819X_FPGA_VIVI_070920)
-#define AFR			0x010
-#define AFR_CardBEn		(1<<0)
-#define AFR_CLKRUN_SEL		(1<<1)
-#define AFR_FuncRegEn		(1<<2)
-#define RTL8190_EEPROM_ID	0x8129
-#define EEPROM_VID		0x02
-#define EEPROM_PID		0x04
-#define EEPROM_NODE_ADDRESS_BYTE_0	0x0C
-
-#define EEPROM_TxPowerDiff	0x1F
-#define EEPROM_ThermalMeter	0x20
-#define EEPROM_PwDiff		0x21	//0x21
-#define EEPROM_CrystalCap	0x22	//0x22
-
-#define EEPROM_TxPwIndex_CCK	0x23	//0x23
-#define EEPROM_TxPwIndex_OFDM_24G	0x24	//0x24~0x26
-#define EEPROM_TxPwIndex_CCK_V1		0x29	//0x29~0x2B
-#define EEPROM_TxPwIndex_OFDM_24G_V1	0x2C	//0x2C~0x2E
-#define EEPROM_TxPwIndex_Ver		0x27	//0x27
-
-#define EEPROM_Default_TxPowerDiff		0x0
-#define EEPROM_Default_ThermalMeter		0x7
-#define EEPROM_Default_PwDiff			0x4
-#define EEPROM_Default_CrystalCap		0x5
-#define EEPROM_Default_TxPower			0x1010
-#define EEPROM_Customer_ID			0x7B	//0x7B:CustomerID
-#define EEPROM_ChannelPlan			0x16	//0x7C
-#define EEPROM_IC_VER				0x7d	//0x7D
-#define EEPROM_CRC				0x7e	//0x7E~0x7F
-
-#define EEPROM_CID_DEFAULT			0x0
-#define EEPROM_CID_CAMEO				0x1
-#define EEPROM_CID_RUNTOP				0x2
-#define EEPROM_CID_Senao				0x3
-#define EEPROM_CID_TOSHIBA				0x4	// Toshiba setting, Merge by Jacken, 2008/01/31
-#define EEPROM_CID_NetCore				0x5
-#define EEPROM_CID_Nettronix			0x6
-#define EEPROM_CID_Pronet				0x7
-#define EEPROM_CID_DLINK				0x8
-
-#define AC_PARAM_TXOP_LIMIT_OFFSET	16
-#define AC_PARAM_ECW_MAX_OFFSET		12
-#define AC_PARAM_ECW_MIN_OFFSET		8
-#define AC_PARAM_AIFS_OFFSET		0
-
-//#endif
-enum _RTL8192Usb_HW {
-
-	PCIF			= 0x009, // PCI Function Register 0x0009h~0x000bh
-#define	BB_GLOBAL_RESET_BIT	0x1
-	BB_GLOBAL_RESET		= 0x020, // BasebandGlobal Reset Register
-	BSSIDR			= 0x02E, // BSSID Register
-	CMDR			= 0x037, // Command register
-#define CR_RST			0x10
-#define CR_RE			0x08
-#define CR_TE			0x04
-#define CR_MulRW		0x01
-	SIFS			= 0x03E, // SIFS register
-	TCR			= 0x040, // Transmit Configuration Register
-
-#define TCR_MXDMA_2048 		7
-#define TCR_LRL_OFFSET		0
-#define TCR_SRL_OFFSET		8
-#define TCR_MXDMA_OFFSET	21
-#define TCR_SAT			BIT24		// Enable Rate depedent ack timeout timer
-	RCR			= 0x044, // Receive Configuration Register
-#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
-		(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
-#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
-#define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_128 3
-#define RX_FIFO_THRESHOLD_256 4
-#define RX_FIFO_THRESHOLD_512 5
-#define RX_FIFO_THRESHOLD_1024 6
-#define RX_FIFO_THRESHOLD_NONE 7
-#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-#define RCR_MXDMA_OFFSET	8
-#define RCR_FIFO_OFFSET		13
-#define RCR_ONLYERLPKT		BIT31			// Early Receiving based on Packet Size.
-#define RCR_ENCS2		BIT30			// Enable Carrier Sense Detection Method 2
-#define RCR_ENCS1		BIT29			// Enable Carrier Sense Detection Method 1
-#define RCR_ENMBID		BIT27			// Enable Multiple BssId.
-#define RCR_ACKTXBW		(BIT24|BIT25)		// TXBW Setting of ACK frames
-#define RCR_CBSSID		BIT23			// Accept BSSID match packet
-#define RCR_APWRMGT		BIT22			// Accept power management packet
-#define	RCR_ADD3		BIT21			// Accept address 3 match packet
-#define RCR_AMF			BIT20			// Accept management type frame
-#define RCR_ACF			BIT19			// Accept control type frame
-#define RCR_ADF			BIT18			// Accept data type frame
-#define RCR_RXFTH		BIT13			// Rx FIFO Threshold
-#define RCR_AICV		BIT12			// Accept ICV error packet
-#define	RCR_ACRC32		BIT5			// Accept CRC32 error packet
-#define	RCR_AB			BIT3			// Accept broadcast packet
-#define	RCR_AM			BIT2			// Accept multicast packet
-#define	RCR_APM			BIT1			// Accept physical match packet
-#define	RCR_AAP			BIT0			// Accept all unicast packet
-	SLOT_TIME		= 0x049, // Slot Time Register
-	ACK_TIMEOUT		= 0x04c, // Ack Timeout Register
-	PIFS_TIME		= 0x04d, // PIFS time
-	USTIME			= 0x04e, // Microsecond Tuning Register, Sets the microsecond time unit used by MAC clock.
-	EDCAPARA_BE		= 0x050, // EDCA Parameter of AC BE
-	EDCAPARA_BK		= 0x054, // EDCA Parameter of AC BK
-	EDCAPARA_VO		= 0x058, // EDCA Parameter of AC VO
-	EDCAPARA_VI		= 0x05C, // EDCA Parameter of AC VI
-	RFPC			= 0x05F, // Rx FIFO Packet Count
-	CWRR			= 0x060, // Contention Window Report Register
-	BCN_TCFG		= 0x062, // Beacon Time Configuration
-#define BCN_TCFG_CW_SHIFT		8
-#define BCN_TCFG_IFS			0
-	BCN_INTERVAL		= 0x070, // Beacon Interval (TU)
-	ATIMWND			= 0x072, // ATIM Window Size (TU)
-	BCN_DRV_EARLY_INT	= 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT
-	BCN_DMATIME		= 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA
-	BCN_ERR_THRESH		= 0x078, // Beacon Error Threshold
-	RWCAM			= 0x0A0, //IN 8190 Data Sheet is called CAMcmd
-	WCAMI			= 0x0A4, // Software write CAM input content
-	RCAMO			= 0x0A8, // Software read/write CAM config
-	SECR			= 0x0B0, //Security Configuration Register
-#define	SCR_TxUseDK		BIT0			//Force Tx Use Default Key
-#define SCR_RxUseDK		BIT1			//Force Rx Use Default Key
-#define SCR_TxEncEnable		BIT2			//Enable Tx Encryption
-#define SCR_RxDecEnable		BIT3			//Enable Rx Decryption
-#define SCR_SKByA2		BIT4			//Search kEY BY A2
-#define SCR_NoSKMC		BIT5			//No Key Search for Multicast
-#define SCR_UseDK		0x01
-#define SCR_TxSecEnable		0x02
-#define SCR_RxSecEnable		0x04
-	TPPoll			= 0x0fd, // Transmit priority polling register
-	PSR			= 0x0ff, // Page Select Register
-#define CPU_CCK_LOOPBACK	0x00030000
-#define CPU_GEN_SYSTEM_RESET	0x00000001
-#define CPU_GEN_FIRMWARE_RESET	0x00000008
-#define CPU_GEN_BOOT_RDY	0x00000010
-#define CPU_GEN_FIRM_RDY	0x00000020
-#define CPU_GEN_PUT_CODE_OK	0x00000080
-#define CPU_GEN_BB_RST		0x00000100
-#define CPU_GEN_PWR_STB_CPU	0x00000004
-#define CPU_GEN_NO_LOOPBACK_MSK	0xFFF8FFFF		// Set bit18,17,16 to 0. Set bit19
-#define CPU_GEN_NO_LOOPBACK_SET	0x00080000		// Set BIT19 to 1
-
-//----------------------------------------------------------------------------
-//       8190 CPU General Register		(offset 0x100, 4 byte)
-//----------------------------------------------------------------------------
-#define	CPU_CCK_LOOPBACK	0x00030000
-#define	CPU_GEN_SYSTEM_RESET	0x00000001
-#define	CPU_GEN_FIRMWARE_RESET	0x00000008
-#define	CPU_GEN_BOOT_RDY	0x00000010
-#define	CPU_GEN_FIRM_RDY	0x00000020
-#define	CPU_GEN_PUT_CODE_OK	0x00000080
-#define	CPU_GEN_BB_RST		0x00000100
-#define	CPU_GEN_PWR_STB_CPU	0x00000004
-#define CPU_GEN_NO_LOOPBACK_MSK	0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19
-#define CPU_GEN_NO_LOOPBACK_SET	0x00080000 // Set BIT19 to 1
-	CPU_GEN			= 0x100, // CPU Reset Register
-	LED1Cfg			=		0x154,// LED1 Configuration Register
- 	LED0Cfg			=		0x155,// LED0 Configuration Register
-
-	AcmAvg			= 0x170, // ACM Average Period Register
-	AcmHwCtrl		= 0x171, // ACM Hardware Control Register
-//----------------------------------------------------------------------------
-////
-////       8190 AcmHwCtrl bits                                    (offset 0x171, 1 byte)
-////----------------------------------------------------------------------------
-//
-#define AcmHw_HwEn              BIT0
-#define AcmHw_BeqEn             BIT1
-#define AcmHw_ViqEn             BIT2
-#define AcmHw_VoqEn             BIT3
-#define AcmHw_BeqStatus         BIT4
-#define AcmHw_ViqStatus         BIT5
-#define AcmHw_VoqStatus         BIT6
-
-	AcmFwCtrl		= 0x172, // ACM Firmware Control Register
-	AES_11N_FIX		= 0x173,
-	VOAdmTime		= 0x174, // VO Queue Admitted Time Register
-	VIAdmTime		= 0x178, // VI Queue Admitted Time Register
-	BEAdmTime		= 0x17C, // BE Queue Admitted Time Register
-	RQPN1			= 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk
-	RQPN2			= 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High
-	RQPN3			= 0x188, // Reserved Queue Page Number, Bcn, Public,
-//	QPRR			= 0x1E0, // Queue Page Report per TID
-	QPNR			= 0x1D0, //0x1F0, // Queue Packet Number report per TID
-	BQDA			= 0x200, // Beacon Queue Descriptor Address
-	HQDA			= 0x204, // High Priority Queue Descriptor Address
-	CQDA			= 0x208, // Command Queue Descriptor Address
-	MQDA			= 0x20C, // Management Queue Descriptor Address
-	HCCAQDA			= 0x210, // HCCA Queue Descriptor Address
-	VOQDA			= 0x214, // VO Queue Descriptor Address
-	VIQDA			= 0x218, // VI Queue Descriptor Address
-	BEQDA			= 0x21C, // BE Queue Descriptor Address
-	BKQDA			= 0x220, // BK Queue Descriptor Address
-	RCQDA			= 0x224, // Receive command Queue Descriptor Address
-	RDQDA			= 0x228, // Receive Queue Descriptor Start Address
-
-	MAR0			= 0x240, // Multicast filter.
-	MAR4			= 0x244,
-
-	CCX_PERIOD		= 0x250, // CCX Measurement Period Register, in unit of TU.
-	CLM_RESULT		= 0x251, // CCA Busy fraction register.
-	NHM_PERIOD		= 0x252, // NHM Measurement Period register, in unit of TU.
-
-	NHM_THRESHOLD0		= 0x253, // Noise Histogram Meashorement0.
-	NHM_THRESHOLD1		= 0x254, // Noise Histogram Meashorement1.
-	NHM_THRESHOLD2		= 0x255, // Noise Histogram Meashorement2.
-	NHM_THRESHOLD3		= 0x256, // Noise Histogram Meashorement3.
-	NHM_THRESHOLD4		= 0x257, // Noise Histogram Meashorement4.
-	NHM_THRESHOLD5		= 0x258, // Noise Histogram Meashorement5.
-	NHM_THRESHOLD6		= 0x259, // Noise Histogram Meashorement6
-
-	MCTRL			= 0x25A, // Measurement Control
-
-	NHM_RPI_COUNTER0	= 0x264, // Noise Histogram RPI counter0, the fraction of signal strength < NHM_THRESHOLD0.
-	NHM_RPI_COUNTER1	= 0x265, // Noise Histogram RPI counter1, the fraction of signal strength in (NHM_THRESHOLD0, NHM_THRESHOLD1].
-	NHM_RPI_COUNTER2	= 0x266, // Noise Histogram RPI counter2, the fraction of signal strength in (NHM_THRESHOLD1, NHM_THRESHOLD2].
-	NHM_RPI_COUNTER3	= 0x267, // Noise Histogram RPI counter3, the fraction of signal strength in (NHM_THRESHOLD2, NHM_THRESHOLD3].
-	NHM_RPI_COUNTER4	= 0x268, // Noise Histogram RPI counter4, the fraction of signal strength in (NHM_THRESHOLD3, NHM_THRESHOLD4].
-	NHM_RPI_COUNTER5	= 0x269, // Noise Histogram RPI counter5, the fraction of signal strength in (NHM_THRESHOLD4, NHM_THRESHOLD5].
-	NHM_RPI_COUNTER6	= 0x26A, // Noise Histogram RPI counter6, the fraction of signal strength in (NHM_THRESHOLD5, NHM_THRESHOLD6].
-	NHM_RPI_COUNTER7	= 0x26B, // Noise Histogram RPI counter7, the fraction of signal strength in (NHM_THRESHOLD6, NHM_THRESHOLD7].
-#define	BW_OPMODE_11J			BIT0
-#define	BW_OPMODE_5G			BIT1
-#define	BW_OPMODE_20MHZ			BIT2
-	BW_OPMODE		= 0x300, // Bandwidth operation mode
-	MSR			= 0x303, // Media Status register
-#define MSR_LINK_MASK      ((1<<0)|(1<<1))
-#define MSR_LINK_MANAGED   2
-#define MSR_LINK_NONE      0
-#define MSR_LINK_SHIFT     0
-#define MSR_LINK_ADHOC     1
-#define MSR_LINK_MASTER    3
-#define MSR_LINK_ENEDCA	   (1<<4)
-	RETRY_LIMIT		= 0x304, // Retry Limit [15:8]-short, [7:0]-long
-#define RETRY_LIMIT_SHORT_SHIFT 8
-#define RETRY_LIMIT_LONG_SHIFT 0
-	TSFR			= 0x308,
-	RRSR			= 0x310, // Response Rate Set
-#define RRSR_RSC_OFFSET			21
-#define RRSR_SHORT_OFFSET			23
-#define RRSR_RSC_DUPLICATE			0x600000
-#define RRSR_RSC_LOWSUBCHNL		0x400000
-#define RRSR_RSC_UPSUBCHANL		0x200000
-#define RRSR_SHORT					0x800000
-#define RRSR_1M						BIT0
-#define RRSR_2M						BIT1
-#define RRSR_5_5M					BIT2
-#define RRSR_11M					BIT3
-#define RRSR_6M						BIT4
-#define RRSR_9M						BIT5
-#define RRSR_12M					BIT6
-#define RRSR_18M					BIT7
-#define RRSR_24M					BIT8
-#define RRSR_36M					BIT9
-#define RRSR_48M					BIT10
-#define RRSR_54M					BIT11
-#define RRSR_MCS0					BIT12
-#define RRSR_MCS1					BIT13
-#define RRSR_MCS2					BIT14
-#define RRSR_MCS3					BIT15
-#define RRSR_MCS4					BIT16
-#define RRSR_MCS5					BIT17
-#define RRSR_MCS6					BIT18
-#define RRSR_MCS7					BIT19
-#define BRSR_AckShortPmb			BIT23		// CCK ACK: use Short Preamble or not.
-	RATR0			= 0x320, // Rate Adaptive Table register1
-	UFWP			= 0x318,
-	DRIVER_RSSI		= 0x32c,					// Driver tell Firmware current RSSI
-//----------------------------------------------------------------------------
-//       8190 Rate Adaptive Table Register	(offset 0x320, 4 byte)
-//----------------------------------------------------------------------------
-//CCK
-#define	RATR_1M			0x00000001
-#define	RATR_2M			0x00000002
-#define	RATR_55M		0x00000004
-#define	RATR_11M		0x00000008
-//OFDM
-#define	RATR_6M			0x00000010
-#define	RATR_9M			0x00000020
-#define	RATR_12M		0x00000040
-#define	RATR_18M		0x00000080
-#define	RATR_24M		0x00000100
-#define	RATR_36M		0x00000200
-#define	RATR_48M		0x00000400
-#define	RATR_54M		0x00000800
-//MCS 1 Spatial Stream
-#define	RATR_MCS0		0x00001000
-#define	RATR_MCS1		0x00002000
-#define	RATR_MCS2		0x00004000
-#define	RATR_MCS3		0x00008000
-#define	RATR_MCS4		0x00010000
-#define	RATR_MCS5		0x00020000
-#define	RATR_MCS6		0x00040000
-#define	RATR_MCS7		0x00080000
-//MCS 2 Spatial Stream
-#define	RATR_MCS8		0x00100000
-#define	RATR_MCS9		0x00200000
-#define	RATR_MCS10		0x00400000
-#define	RATR_MCS11		0x00800000
-#define	RATR_MCS12		0x01000000
-#define	RATR_MCS13		0x02000000
-#define	RATR_MCS14		0x04000000
-#define	RATR_MCS15		0x08000000
-// ALL CCK Rate
-#define RATE_ALL_CCK		RATR_1M|RATR_2M|RATR_55M|RATR_11M
-#define RATE_ALL_OFDM_AG	RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M\
-							|RATR_36M|RATR_48M|RATR_54M
-#define RATE_ALL_OFDM_1SS	RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 | \
-							RATR_MCS4|RATR_MCS5|RATR_MCS6|RATR_MCS7
-#define RATE_ALL_OFDM_2SS	RATR_MCS8|RATR_MCS9	|RATR_MCS10|RATR_MCS11| \
-							RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15
-
-	MCS_TXAGC		= 0x340, // MCS AGC
-	CCK_TXAGC		= 0x348, // CCK AGC
-//	ISR			= 0x350, // Interrupt Status Register
-//	IMR			= 0x354, // Interrupt Mask Register
-//	IMR_POLL		= 0x360,
-	MacBlkCtrl		= 0x403, // Mac block on/off control register
-
-	EPROM_CMD 		= 0xfe58,
-#define Cmd9346CR_9356SEL	(1<<4)
-#define EPROM_CMD_RESERVED_MASK (1<<5)
-#define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
-#define EPROM_CMD_CONFIG 0x3
-#define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_LOAD 1
-#define EPROM_CMD_PROGRAM 2
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define EPROM_W_SHIFT 1
-#define EPROM_R_SHIFT 0
-	MAC0 			= 0x000,
-	MAC1 			= 0x001,
-	MAC2 			= 0x002,
-	MAC3 			= 0x003,
-	MAC4 			= 0x004,
-	MAC5 			= 0x005,
-
-#if 0
-/* 0x0006 - 0x0007 - reserved */
-	RXFIFOCOUNT 		= 0x010,
-	TXFIFOCOUNT 		= 0x012,
-	BQREQ 			= 0x013,
-/* 0x0010 - 0x0017 - reserved */
-	TSFTR 			= 0x018,
-	TLPDA 			= 0x020,
-	TNPDA 			= 0x024,
-	THPDA 			= 0x028,
-	BSSID 			= 0x02E,
-	RESP_RATE 		= 0x034,
-	CMD 			= 0x037,
-#define CMD_RST_SHIFT 4
-#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
-#define CMD_RX_ENABLE_SHIFT 3
-#define CMD_TX_ENABLE_SHIFT 2
-#define CR_RST      ((1<< 4))
-#define CR_RE       ((1<< 3))
-#define CR_TE       ((1<< 2))
-#define CR_MulRW    ((1<< 0))
-
-	INTA_MASK 		= 0x03c,
-	INTA 			= 0x03e,
-#define INTA_TXOVERFLOW (1<<15)
-#define INTA_TIMEOUT (1<<14)
-#define INTA_BEACONTIMEOUT (1<<13)
-#define INTA_ATIM (1<<12)
-#define INTA_BEACONDESCERR (1<<11)
-#define INTA_BEACONDESCOK (1<<10)
-#define INTA_HIPRIORITYDESCERR (1<<9)
-#define INTA_HIPRIORITYDESCOK (1<<8)
-#define INTA_NORMPRIORITYDESCERR (1<<7)
-#define INTA_NORMPRIORITYDESCOK (1<<6)
-#define INTA_RXOVERFLOW (1<<5)
-#define INTA_RXDESCERR (1<<4)
-#define INTA_LOWPRIORITYDESCERR (1<<3)
-#define INTA_LOWPRIORITYDESCOK (1<<2)
-#define INTA_RXCRCERR (1<<1)
-#define INTA_RXOK (1)
-	TX_CONF 		= 0x040,
-#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
-#define TX_LOOPBACK_SHIFT 17
-#define TX_LOOPBACK_MAC 1
-#define TX_LOOPBACK_BASEBAND 2
-#define TX_LOOPBACK_NONE 0
-#define TX_LOOPBACK_CONTINUE 3
-#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
-#define TX_LRLRETRY_SHIFT 0
-#define TX_SRLRETRY_SHIFT 8
-#define TX_NOICV_SHIFT 19
-#define TX_NOCRC_SHIFT 16
-#define TCR_DurProcMode  ((1<<30))
-#define TCR_DISReqQsize  ((1<<28))
-#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
-#define TCR_HWVERID_SHIFT 25
-#define TCR_SWPLCPLEN     ((1<<24))
-#define TCR_PLCP_LEN TCR_SAT // rtl8180
-#define TCR_MXDMA_MASK   ((1<<23)|(1<<22)|(1<<21))
-#define TCR_MXDMA_1024 6
-#define TCR_MXDMA_2048 7
-#define TCR_MXDMA_SHIFT  21
-#define TCR_DISCW   ((1<<20))
-#define TCR_ICV     ((1<<19))
-#define TCR_LBK     ((1<<18)|(1<<17))
-#define TCR_LBK1    ((1<<18))
-#define TCR_LBK0    ((1<<17))
-#define TCR_CRC     ((1<<16))
-#define TCR_SRL_MASK   ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
-#define TCR_LRL_MASK   ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
-#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
-	RX_CONF 		= 0x044,
-#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
-(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
-#define RX_CHECK_BSSID_SHIFT 23
-#define ACCEPT_PWR_FRAME_SHIFT 22
-#define ACCEPT_MNG_FRAME_SHIFT 20
-#define ACCEPT_CTL_FRAME_SHIFT 19
-#define ACCEPT_DATA_FRAME_SHIFT 18
-#define ACCEPT_ICVERR_FRAME_SHIFT 12
-#define ACCEPT_CRCERR_FRAME_SHIFT 5
-#define ACCEPT_BCAST_FRAME_SHIFT 3
-#define ACCEPT_MCAST_FRAME_SHIFT 2
-#define ACCEPT_ALLMAC_FRAME_SHIFT 0
-#define ACCEPT_NICMAC_FRAME_SHIFT 1
-#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
-#define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_128 3
-#define RX_FIFO_THRESHOLD_256 4
-#define RX_FIFO_THRESHOLD_512 5
-#define RX_FIFO_THRESHOLD_1024 6
-#define RX_FIFO_THRESHOLD_NONE 7
-#define RX_AUTORESETPHY_SHIFT 28
-#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-#define MAX_RX_DMA_2048 7
-#define MAX_RX_DMA_1024	6
-#define MAX_RX_DMA_SHIFT 10
-#define RCR_ONLYERLPKT ((1<<31))
-#define RCR_CS_SHIFT   29
-#define RCR_CS_MASK    ((1<<30) | (1<<29))
-#define RCR_ENMARP     ((1<<28))
-#define RCR_CBSSID     ((1<<23))
-#define RCR_APWRMGT    ((1<<22))
-#define RCR_ADD3       ((1<<21))
-#define RCR_AMF        ((1<<20))
-#define RCR_ACF        ((1<<19))
-#define RCR_ADF        ((1<<18))
-#define RCR_RXFTH      ((1<<15)|(1<<14)|(1<<13))
-#define RCR_RXFTH2     ((1<<15))
-#define RCR_RXFTH1     ((1<<14))
-#define RCR_RXFTH0     ((1<<13))
-#define RCR_AICV       ((1<<12))
-#define RCR_MXDMA      ((1<<10)|(1<< 9)|(1<< 8))
-#define RCR_MXDMA2     ((1<<10))
-#define RCR_MXDMA1     ((1<< 9))
-#define RCR_MXDMA0     ((1<< 8))
-#define RCR_9356SEL    ((1<< 6))
-#define RCR_ACRC32     ((1<< 5))
-#define RCR_AB         ((1<< 3))
-#define RCR_AM         ((1<< 2))
-#define RCR_APM        ((1<< 1))
-#define RCR_AAP        ((1<< 0))
-	INT_TIMEOUT 		= 0x048,
-	TX_BEACON_RING_ADDR 	= 0x04c,
-	EPROM_CMD 		= 0x58,
-#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
-#define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
-#define EPROM_CMD_CONFIG 0x3
-#define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_LOAD 1
-#define EPROM_CMD_PROGRAM 2
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define EPROM_W_SHIFT 1
-#define EPROM_R_SHIFT 0
-	CONFIG0 		= 0x051,
-#define CONFIG0_WEP104     ((1<<6))
-#define CONFIG0_LEDGPO_En  ((1<<4))
-#define CONFIG0_Aux_Status ((1<<3))
-#define CONFIG0_GL         ((1<<1)|(1<<0))
-#define CONFIG0_GL1        ((1<<1))
-#define CONFIG0_GL0        ((1<<0))
-	CONFIG1 		= 0x052,
-#define CONFIG1_LEDS       ((1<<7)|(1<<6))
-#define CONFIG1_LEDS1      ((1<<7))
-#define CONFIG1_LEDS0      ((1<<6))
-#define CONFIG1_LWACT      ((1<<4))
-#define CONFIG1_MEMMAP     ((1<<3))
-#define CONFIG1_IOMAP      ((1<<2))
-#define CONFIG1_VPD        ((1<<1))
-#define CONFIG1_PMEn       ((1<<0))
-	CONFIG2 		= 0x053,
-#define CONFIG2_LCK        ((1<<7))
-#define CONFIG2_ANT        ((1<<6))
-#define CONFIG2_DPS        ((1<<3))
-#define CONFIG2_PAPE_sign  ((1<<2))
-#define CONFIG2_PAPE_time  ((1<<1)|(1<<0))
-#define CONFIG2_PAPE_time1 ((1<<1))
-#define CONFIG2_PAPE_time0 ((1<<0))
-	ANA_PARAM 		= 0x054,
-	CONFIG3 		= 0x059,
-#define CONFIG3_GNTSel     ((1<<7))
-#define CONFIG3_PARM_En    ((1<<6))
-#define CONFIG3_Magic      ((1<<5))
-#define CONFIG3_CardB_En   ((1<<3))
-#define CONFIG3_CLKRUN_En  ((1<<2))
-#define CONFIG3_FuncRegEn  ((1<<1))
-#define CONFIG3_FBtbEn     ((1<<0))
-#define CONFIG3_CLKRUN_SHIFT 2
-#define CONFIG3_ANAPARAM_W_SHIFT 6
-	CONFIG4 		= 0x05a,
-#define CONFIG4_VCOPDN     ((1<<7))
-#define CONFIG4_PWROFF     ((1<<6))
-#define CONFIG4_PWRMGT     ((1<<5))
-#define CONFIG4_LWPME      ((1<<4))
-#define CONFIG4_LWPTN      ((1<<2))
-#define CONFIG4_RFTYPE     ((1<<1)|(1<<0))
-#define CONFIG4_RFTYPE1    ((1<<1))
-#define CONFIG4_RFTYPE0    ((1<<0))
-	TESTR 			= 0x05b,
-#define TFPC_AC  0x05C
-
-#define SCR 0x05F
-	PGSELECT 		= 0x05e,
-#define PGSELECT_PG_SHIFT 0
-	SECURITY 		= 0x05f,
-#define SECURITY_WEP_TX_ENABLE_SHIFT 1
-#define SECURITY_WEP_RX_ENABLE_SHIFT 0
-#define SECURITY_ENCRYP_104 1
-#define SECURITY_ENCRYP_SHIFT 4
-#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
-	ANA_PARAM2 		= 0x060,
-	BEACON_INTERVAL 	= 0x070,
-#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
-(1<<6)|(1<<7)|(1<<8)|(1<<9))
-	ATIM_WND 		= 0x072,
-#define ATIM_WND_MASK      (0x01FF)
-	BCN_INTR_ITV 		= 0x074,
-#define BCN_INTR_ITV_MASK  (0x01FF)
-	ATIM_INTR_ITV		= 0x076,
-#define ATIM_INTR_ITV_MASK  (0x01FF)
-	AckTimeOutReg      	= 0x079, //ACK timeout register, in unit of 4 us.
-	PHY_ADR 		= 0x07c,
-	PHY_READ 		= 0x07e,
-	RFPinsOutput 		= 0x080,
-	RFPinsEnable 		= 0x082,
-
-//Page 0
-	RFPinsSelect 		= 0x084,
-#define SW_CONTROL_GPIO 0x400
-	RFPinsInput 		= 0x086,
-	RF_PARA 		= 0x088,
-	RF_TIMING 		= 0x08c,
-	GP_ENABLE 		= 0x090,
-	GPIO 			= 0x091,
-	TX_AGC_CTL 		= 0x09c,
-#define TX_AGC_CTL_PER_PACKET_TXAGC	0x01
-#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
-#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
-#define TX_AGC_CTL_FEEDBACK_ANT 2
-#define TXAGC_CTL_PER_PACKET_ANT_SEL 0x02
-	OFDM_TXAGC 		= 0x09e,
-	ANTSEL 			= 0x09f,
-	WPA_CONFIG 		= 0x0b0,
-	SIFS 			= 0x0b4,
-	DIFS 			= 0x0b5,
-	SLOT 			= 0x0b6,
-	CW_CONF 		= 0x0bc,
-#define CW_CONF_PERPACKET_RETRY_LIMIT 0x02
-#define CW_CONF_PERPACKET_CW 0x01
-#define CW_CONF_PERPACKET_RETRY_SHIFT 1
-#define CW_CONF_PERPACKET_CW_SHIFT 0
-	CW_VAL 			= 0x0bd,
-	RATE_FALLBACK 		= 0x0be,
-#define MAX_RESP_RATE_SHIFT 4
-#define MIN_RESP_RATE_SHIFT 0
-#define RATE_FALLBACK_CTL_ENABLE  0x80
-#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
-	ACM_CONTROL             = 0x0BF,      // ACM Control Registe
-//----------------------------------------------------------------------------
-//       8187B ACM_CONTROL bits						(Offset 0xBF, 1 Byte)
-//----------------------------------------------------------------------------
-#define VOQ_ACM_EN				(0x01 << 7) //BIT7
-#define VIQ_ACM_EN				(0x01 << 6) //BIT6
-#define BEQ_ACM_EN				(0x01 << 5) //BIT5
-#define ACM_HW_EN				(0x01 << 4) //BIT4
-#define TXOPSEL					(0x01 << 3) //BIT3
-#define VOQ_ACM_CTL				(0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
-#define VIQ_ACM_CTL				(0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
-#define BEQ_ACM_CTL				(0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
-	CONFIG5 		= 0x0D8,
-#define CONFIG5_TX_FIFO_OK ((1<<7))
-#define CONFIG5_RX_FIFO_OK ((1<<6))
-#define CONFIG5_CALON      ((1<<5))
-#define CONFIG5_EACPI      ((1<<2))
-#define CONFIG5_LANWake    ((1<<1))
-#define CONFIG5_PME_STS    ((1<<0))
-	TX_DMA_POLLING 		= 0x0d9,
-#define TX_DMA_POLLING_BEACON_SHIFT 7
-#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
-#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
-#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
-#define TX_DMA_STOP_BEACON_SHIFT 3
-#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
-#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
-#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
-	CWR 			= 0x0DC,
-	RetryCTR 		= 0x0DE,
-	INT_MIG                 = 0x0E2,      // Interrupt Migration (0xE2 ~ 0xE3)
-	TID_AC_MAP         	= 0x0E8,     // TID to AC Mapping Register
-	ANA_PARAM3 		= 0x0EE,
-
-
-//page 1
-	Wakeup0 		= 0x084,
-	Wakeup1 		= 0x08C,
-	Wakeup2LD 		= 0x094,
-	Wakeup2HD 		= 0x09C,
-	Wakeup3LD 		= 0x0A4,
-	Wakeup3HD 		= 0x0AC,
-	Wakeup4LD 		= 0x0B4,
-	Wakeup4HD 		= 0x0BC,
-	CRC0 			= 0x0C4,
-	CRC1 			= 0x0C6,
-	CRC2 			= 0x0C8,
-	CRC3 			= 0x0CA,
-	CRC4 			= 0x0CC,
-/* 0x00CE - 0x00D3 - reserved */
-
-	RFSW_CTRL               = 0x272,   // 0x272-0x273.
-
-//Reg Diff between rtl8187 and rtl8187B
-/**************************************************************************/
-	BRSR_8187 		= 0x02C,
-	BRSR_8187B 		= 0x034,
-#define BRSR_BPLCP  ((1<< 8))
-#define BRSR_MBR    ((1<< 1)|(1<< 0))
-#define BRSR_MBR_8185 ((1<< 11)|(1<< 10)|(1<< 9)|(1<< 8)|(1<< 7)|(1<< 6)|(1<< 5)|(1<< 4)|(1<< 3)|(1<< 2)|(1<< 1)|(1<< 0))
-#define BRSR_MBR0   ((1<< 0))
-#define BRSR_MBR1   ((1<< 1))
-
-/**************************************************************************/
-	EIFS_8187  		= 0x035,
-	EIFS_8187B 		= 0x02D,
-
-/**************************************************************************/
-	FER 			= 0x0F0,
-	FEMR 			= 0x0F4,
-	FPSR 			= 0x0F8,
-	FFER 			= 0x0FC,
-
-	AC_VO_PARAM             = 0x0F0,      // AC_VO Parameters Record
-	AC_VI_PARAM             = 0x0F4,      // AC_VI Parameters Record
-	AC_BE_PARAM             = 0x0F8,      // AC_BE Parameters Record
-	AC_BK_PARAM             = 0x0FC,      // AC_BK Parameters Record
-	TALLY_SEL 		= 0x0fc,
-//----------------------------------------------------------------------------
-//       8187B AC_XX_PARAM bits
-//----------------------------------------------------------------------------
-#define AC_PARAM_TXOP_LIMIT_OFFSET		16
-#define AC_PARAM_ECW_MAX_OFFSET			12
-#define AC_PARAM_ECW_MIN_OFFSET			8
-#define AC_PARAM_AIFS_OFFSET			0
-
-#endif
-};
-//----------------------------------------------------------------------------
-//       818xB AnaParm & AnaParm2 Register
-//----------------------------------------------------------------------------
-//#define ANAPARM_ASIC_ON    0x45090658
-//#define ANAPARM2_ASIC_ON   0x727f3f52
-#define GPI 0x108
-#define GPO 0x109
-#define GPE 0x10a
-#endif
diff --git a/drivers/staging/rtl8192su/r8192U_pm.c b/drivers/staging/rtl8192su/r8192U_pm.c
index b1531a8..60d739b 100644
--- a/drivers/staging/rtl8192su/r8192U_pm.c
+++ b/drivers/staging/rtl8192su/r8192U_pm.c
@@ -9,7 +9,6 @@
    Released under the terms of GPL (General Public Licence)
 */
 
-#ifdef CONFIG_RTL8192_PM
 #include "r8192U.h"
 #include "r8192U_pm.h"
 
@@ -22,11 +21,8 @@ int rtl8192U_save_state (struct pci_dev *dev, u32 state)
 
 int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct net_device *dev = usb_get_intfdata(intf);
-#else
-	//struct net_device *dev = (struct net_device *)ptr;
-#endif
+
 	RT_TRACE(COMP_POWER, "============> r8192U suspend call.\n");
 
 	if(dev) {
@@ -48,11 +44,7 @@ int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state)
 
 int rtl8192U_resume (struct usb_interface *intf)
 {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct net_device *dev = usb_get_intfdata(intf);
-#else
-	//struct net_device *dev = (struct net_device *)ptr;
-#endif
 
 	RT_TRACE(COMP_POWER, "================>r8192U resume call.");
 
@@ -78,4 +70,3 @@ int rtl8192U_enable_wake (struct pci_dev *dev, u32 state, int enable)
 	return(-EAGAIN);
 }
 
-#endif //CONFIG_RTL8192_PM
diff --git a/drivers/staging/rtl8192su/r8192U_pm.h b/drivers/staging/rtl8192su/r8192U_pm.h
index ab025d6..d89e423 100644
--- a/drivers/staging/rtl8192su/r8192U_pm.h
+++ b/drivers/staging/rtl8192su/r8192U_pm.h
@@ -10,7 +10,6 @@
 
 */
 
-#ifdef CONFIG_RTL8192_PM
 
 #ifndef R8192_PM_H
 #define R8192_PM_H
@@ -24,4 +23,3 @@ int rtl8192U_resume (struct usb_interface *intf);
 int rtl8192U_enable_wake (struct pci_dev *dev, u32 state, int enable);
 
 #endif //R8192U_PM_H
-#endif // CONFIG_RTL8192_PM
diff --git a/drivers/staging/rtl8192su/r8192U_wx.c b/drivers/staging/rtl8192su/r8192U_wx.c
index f9eafb1..2208c9b 100644
--- a/drivers/staging/rtl8192su/r8192U_wx.c
+++ b/drivers/staging/rtl8192su/r8192U_wx.c
@@ -17,19 +17,11 @@
    project Authors.
 */
 
-#ifdef RTL8192SU
 #include <linux/string.h>
 #include "r8192U.h"
 #include "r8192S_hw.h"
-#else
-#include <linux/string.h>
-#include "r8192U.h"
-#include "r8192U_hw.h"
-#endif
 
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
+#include "ieee80211/dot11d.h"
 
 #define RATE_COUNT 12
 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
@@ -49,41 +41,6 @@ static int r8192_wx_get_freq(struct net_device *dev,
 	return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b);
 }
 
-
-#if 0
-
-static int r8192_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
-			  union iwreq_data *wrqu, char *b)
-{
-	int *parms = (int *)b;
-	int bi = parms[0];
-
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	down(&priv->wx_sem);
-	DMESG("setting beacon interval to %x",bi);
-
-	priv->ieee80211->beacon_interval=bi;
-	rtl8180_commit(dev);
-	up(&priv->wx_sem);
-
-	return 0;
-}
-
-
-static int r8192_wx_set_forceassociate(struct net_device *dev, struct iw_request_info *aa,
-			  union iwreq_data *wrqu, char *extra)
-{
-	struct r8192_priv *priv=ieee80211_priv(dev);
-	int *parms = (int *)extra;
-
-	priv->ieee80211->force_associate = (parms[0] > 0);
-
-
-	return 0;
-}
-
-#endif
 static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
 			     union iwreq_data *wrqu, char *b)
 {
@@ -221,10 +178,6 @@ static int r8192_wx_read_bb(struct net_device *dev,
 {
         struct r8192_priv *priv = ieee80211_priv(dev);
 	u8 databb;
-#if 0
-	int i;
-	for(i=0;i<12;i++) printk("%8x\n", read_cam(dev, i) );
-#endif
 
         down(&priv->wx_sem);
 
@@ -323,14 +276,6 @@ static int r8192_wx_get_ap_status(struct net_device *dev,
 
 
 #endif
-#if 0
-static int r8192_wx_null(struct net_device *dev,
-		struct iw_request_info *info,
-		union iwreq_data *wrqu, char *extra)
-{
-	return 0;
-}
-#endif
 static int r8192_wx_force_reset(struct net_device *dev,
 		struct iw_request_info *info,
 		union iwreq_data *wrqu, char *extra)
@@ -346,7 +291,6 @@ static int r8192_wx_force_reset(struct net_device *dev,
 
 }
 
-#ifdef RTL8192SU
 static int r8191su_wx_get_firm_version(struct net_device *dev,
 		struct iw_request_info *info,
 		struct iw_param *wrqu, char *extra)
@@ -362,7 +306,6 @@ static int r8191su_wx_get_firm_version(struct net_device *dev,
 	up(&priv->wx_sem);
 	return 0;
 }
-#endif
 
 
 
@@ -529,11 +472,7 @@ static int rtl8180_wx_get_range(struct net_device *dev,
 	for (i = 0, val = 0; i < 14; i++) {
 
 		// Include only legal frequencies for some countries
-#ifdef ENABLE_DOT11D
 		if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
-#else
-		if ((priv->ieee80211->channel_map)[i+1]) {
-#endif
 		        range->freq[val].i = i + 1;
 			range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
 			range->freq[val].e = 1;
@@ -548,10 +487,8 @@ static int rtl8180_wx_get_range(struct net_device *dev,
 	}
 	range->num_frequency = val;
         range->num_channels = val;
-#if WIRELESS_EXT > 17
 	range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2|
 			  IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP;
-#endif
 	tmp->scan_capa = 0x01;
 	return 0;
 }
@@ -568,7 +505,7 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
 
 	if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true)
 		return -EAGAIN;
-#if WIRELESS_EXT > 17
+
 	if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
 	{
 		struct iw_scan_req* req = (struct iw_scan_req*)b;
@@ -580,7 +517,6 @@ static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
 			//printk("=====>network ssid:%s\n", ieee->current_network.ssid);
 		}
 	}
-#endif
 
 	down(&priv->wx_sem);
 	if(priv->ieee80211->state != IEEE80211_LINKED){
@@ -963,25 +899,12 @@ exit:
 	return err;
 }
 
-#if (WIRELESS_EXT >= 18)
-#if 0
-static int r8192_wx_get_enc_ext(struct net_device *dev,
-                                        struct iw_request_info *info,
-                                        union iwreq_data *wrqu, char *extra)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-	ret = ieee80211_wx_get_encode_ext(priv->ieee80211, info, wrqu, extra);
-	return ret;
-}
-#endif
 //hw security need to reorganized.
 static int r8192_wx_set_enc_ext(struct net_device *dev,
                                         struct iw_request_info *info,
                                         union iwreq_data *wrqu, char *extra)
 {
 	int ret=0;
-	#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device* ieee = priv->ieee80211;
 	//printk("===>%s()\n", __FUNCTION__);
@@ -996,13 +919,6 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
 		u32 key[4] = {0};
 		struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 		struct iw_point *encoding = &wrqu->encoding;
-#if 0
-		static u8 CAM_CONST_ADDR[4][6] = {
-			{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-			{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
-			{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
-			{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
-#endif
 		u8 idx = 0, alg = 0, group = 0;
 		if ((encoding->flags & IW_ENCODE_DISABLED) ||
 		ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01
@@ -1065,22 +981,19 @@ static int r8192_wx_set_enc_ext(struct net_device *dev,
 end_hw_sec:
 
 	up(&priv->wx_sem);
-#endif
 	return ret;
-
 }
 static int r8192_wx_set_auth(struct net_device *dev,
                                         struct iw_request_info *info,
                                         union iwreq_data *data, char *extra)
 {
 	int ret=0;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+
 	//printk("====>%s()\n", __FUNCTION__);
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	down(&priv->wx_sem);
 	ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra);
 	up(&priv->wx_sem);
-#endif
 	return ret;
 }
 
@@ -1091,23 +1004,19 @@ static int r8192_wx_set_mlme(struct net_device *dev,
 	//printk("====>%s()\n", __FUNCTION__);
 
 	int ret=0;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	struct r8192_priv *priv = ieee80211_priv(dev);
 	down(&priv->wx_sem);
 	ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
-
 	up(&priv->wx_sem);
-#endif
 	return ret;
 }
-#endif
+
 static int r8192_wx_set_gen_ie(struct net_device *dev,
                                         struct iw_request_info *info,
                                         union iwreq_data *data, char *extra)
 {
 	   //printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
 	int ret=0;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
         struct r8192_priv *priv = ieee80211_priv(dev);
         down(&priv->wx_sem);
 #if 1
@@ -1115,7 +1024,6 @@ static int r8192_wx_set_gen_ie(struct net_device *dev,
 #endif
         up(&priv->wx_sem);
 	//printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
-#endif
         return ret;
 
 
@@ -1152,11 +1060,7 @@ static iw_handler r8192_wx_handlers[] =
         NULL,                     /* SIOCWIWTHRSPY */
         r8192_wx_set_wap,      	  /* SIOCSIWAP */
         r8192_wx_get_wap,         /* SIOCGIWAP */
-#if (WIRELESS_EXT >= 18)
         r8192_wx_set_mlme,                     /* MLME-- */
-#else
-	 NULL,
-#endif
         dummy,                     /* SIOCGIWAPLIST -- depricated */
         r8192_wx_set_scan,        /* SIOCSIWSCAN */
         r8192_wx_get_scan,        /* SIOCGIWSCAN */
@@ -1185,17 +1089,10 @@ static iw_handler r8192_wx_handlers[] =
 	r8192_wx_set_gen_ie,//NULL, 			/* SIOCSIWGENIE */
 	NULL, 			/* SIOCSIWGENIE */
 
-#if (WIRELESS_EXT >= 18)
 	r8192_wx_set_auth,//NULL, 			/* SIOCSIWAUTH */
 	NULL,//r8192_wx_get_auth,//NULL, 			/* SIOCSIWAUTH */
 	r8192_wx_set_enc_ext, 			/* SIOCSIWENCODEEXT */
 	NULL,//r8192_wx_get_enc_ext,//NULL, 			/* SIOCSIWENCODEEXT */
-#else
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-#endif
 	NULL, 			/* SIOCSIWPMKSA */
 	NULL, 			 /*---hole---*/
 
@@ -1262,14 +1159,12 @@ static const struct iw_priv_args r8192_private_args[] = {
 		IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset"
 	}
 
-#ifdef RTL8192SU
 	,
 	{
 		SIOCIWFIRSTPRIV + 0x5,
 		IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1,
 		"firm_ver"
 	}
-#endif
 };
 
 
@@ -1292,12 +1187,9 @@ static iw_handler r8192_private_handler[] = {
 #endif
 	r8192_wx_force_reset,
         (iw_handler)NULL,
-#ifdef RTL8192SU
         (iw_handler)r8191su_wx_get_firm_version,
-#endif
 };
 
-//#if WIRELESS_EXT >= 17
 struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
 {
        struct r8192_priv *priv = ieee80211_priv(dev);
@@ -1311,11 +1203,7 @@ struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
 		wstats->qual.qual = 0;
 		wstats->qual.level = 0;
 		wstats->qual.noise = 0;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
 		wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
-#else
-		wstats->qual.updated = 0x0f;
-#endif
 		return wstats;
 	}
 
@@ -1327,24 +1215,16 @@ struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev)
 	wstats->qual.level = tmp_level;
 	wstats->qual.qual = tmp_qual;
 	wstats->qual.noise = tmp_noise;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14))
 	wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
-#else
-        wstats->qual.updated = 0x0f;
-#endif
 	return wstats;
 }
-//#endif
-
 
 struct iw_handler_def  r8192_wx_handlers_def={
 	.standard = r8192_wx_handlers,
-	.num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler),
+	.num_standard = ARRAY_SIZE(r8192_wx_handlers),
 	.private = r8192_private_handler,
-	.num_private = sizeof(r8192_private_handler) / sizeof(iw_handler),
+	.num_private = ARRAY_SIZE(r8192_private_handler),
  	.num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args),
-#if WIRELESS_EXT >= 17
 	.get_wireless_stats = r8192_get_wireless_stats,
-#endif
 	.private_args = (struct iw_priv_args *)r8192_private_args,
 };
diff --git a/drivers/staging/rtl8192su/r8192U_wx.h b/drivers/staging/rtl8192su/r8192U_wx.h
index b2f7a57..61a2c26 100644
--- a/drivers/staging/rtl8192su/r8192U_wx.h
+++ b/drivers/staging/rtl8192su/r8192U_wx.h
@@ -15,7 +15,6 @@
 #ifndef R8180_WX_H
 #define R8180_WX_H
 //#include <linux/wireless.h>
-//#include "ieee80211.h"
 extern struct iw_handler_def r8192_wx_handlers_def;
 /* Enable  the rtl819x_core.c to share this function, david 2008.9.22 */
 extern struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev);
diff --git a/drivers/staging/rtl8192su/r819xU_HTType.h b/drivers/staging/rtl8192su/r819xU_HTType.h
index 2994aa0..3f379e0 100644
--- a/drivers/staging/rtl8192su/r819xU_HTType.h
+++ b/drivers/staging/rtl8192su/r819xU_HTType.h
@@ -293,15 +293,6 @@ typedef struct _RT_HIGH_THROUGHPUT{
 	u8				RxReorderPendingTime;
 	u16				RxReorderDropCounter;
 
-#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
-	u8				UsbTxAggrNum;
-#endif
-#ifdef USB_RX_AGGREGATION_SUPPORT
-	u8				UsbRxFwAggrEn;
-	u8				UsbRxFwAggrPageNum;
-	u8				UsbRxFwAggrPacketNum;
-	u8				UsbRxFwAggrTimeout;
-#endif
 
 	// Add for Broadcom(Linksys) IOT. Joseph
 	u8				bIsPeerBcm;
diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.c b/drivers/staging/rtl8192su/r819xU_cmdpkt.c
index c1149c6..e2ba93e 100644
--- a/drivers/staging/rtl8192su/r819xU_cmdpkt.c
+++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.c
@@ -108,84 +108,7 @@ SendTxCommandPacket(
 {
 
 	bool 	    rt_status = true;
-#ifdef RTL8192SU
 	return rt_status;
-#else
-#ifdef RTL8192U
-	return rt_status;
-#else
-	struct r8192_priv   *priv = ieee80211_priv(dev);
-	u16		    frag_threshold;
-	u16		    frag_length, frag_offset = 0;
-	//u16		    total_size;
-	//int		    i;
-
-	rt_firmware	    *pfirmware = priv->pFirmware;
-	struct sk_buff	    *skb;
-	unsigned char	    *seg_ptr;
-	cb_desc		    *tcb_desc;
-	u8                  bLastIniPkt;
-
-	firmware_init_param(dev);
-	//Fragmentation might be required
-	frag_threshold = pfirmware->cmdpacket_frag_thresold;
-	do {
-		if((buffer_len - frag_offset) > frag_threshold) {
-			frag_length = frag_threshold ;
-			bLastIniPkt = 0;
-
-		} else {
-			frag_length = buffer_len - frag_offset;
-			bLastIniPkt = 1;
-
-		}
-
-		/* Allocate skb buffer to contain firmware info and tx descriptor info
-		 * add 4 to avoid packet appending overflow.
-		 * */
-		#ifdef RTL8192U
-		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
-		#else
-		skb  = dev_alloc_skb(frag_length + 4);
-		#endif
-		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
-		tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
-		tcb_desc->queue_index = TXCMD_QUEUE;
-		tcb_desc->bCmdOrInit = packettype;
-		tcb_desc->bLastIniPkt = bLastIniPkt;
-
-		#ifdef RTL8192U
-		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
-		#endif
-
-		seg_ptr = skb_put(skb, buffer_len);
-		/*
-		 * Transform from little endian to big endian
-                 * and pending  zero
-		 */
-		memcpy(seg_ptr,codevirtualaddress,buffer_len);
-		tcb_desc->txbuf_size= (u16)buffer_len;
-
-
-		if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
-			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
-			(priv->ieee80211->queue_stop) ) {
-			RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
-			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
-		} else {
-			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
-		}
-
-		codevirtualaddress += frag_length;
-		frag_offset += frag_length;
-
-	}while(frag_offset < buffer_len);
-
-	return rt_status;
-
-
-#endif
-#endif
 }	/* CMPK_Message_Handle_Tx */
 
 /*-----------------------------------------------------------------------------
@@ -319,45 +242,13 @@ cmpk_handle_tx_feedback(
 	//cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg);
 
 	/* 1. Extract TX feedback info from RFD to temp structure buffer. */
-	/* It seems that FW use big endian(MIPS) and DRV use little endian in
-	   windows OS. So we have to read the content byte by byte or transfer
-	   endian type before copy the message copy. */
-#if 0		// The TX FEEDBACK packet element address
-	//rx_tx_fb.Element_ID 	= pMsg[0];
-	//rx_tx_fb.Length 		= pMsg[1];
-	rx_tx_fb.TOK 			= pMsg[2]>>7;
-	rx_tx_fb.Fail_Reason 	= (pMsg[2] & 0x70) >> 4;
-	rx_tx_fb.TID 			= (pMsg[2] & 0x0F);
-	rx_tx_fb.Qos_Pkt 		= pMsg[3] >> 7;
-	rx_tx_fb.Bandwidth 		= (pMsg[3] & 0x40) >> 6;
-	rx_tx_fb.Retry_Cnt 		= pMsg[5];
-	rx_tx_fb.Pkt_ID 		= (pMsg[6] << 8) | pMsg[7];
-	rx_tx_fb.Seq_Num 		= (pMsg[8] << 8) | pMsg[9];
-	rx_tx_fb.S_Rate 		= pMsg[10];
-	rx_tx_fb.F_Rate 		= pMsg[11];
-	rx_tx_fb.S_RTS_Rate 	= pMsg[12];
-	rx_tx_fb.F_RTS_Rate 	= pMsg[13];
-	rx_tx_fb.pkt_length	= (pMsg[14] << 8) | pMsg[15];
-#endif
+
 	/* 2007/07/05 MH Use pointer to transfer structure memory. */
 	//memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
 	memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
 	/* 2. Use tx feedback info to count TX statistics. */
 	cmpk_count_txstatistic(dev, &rx_tx_fb);
-#if 0
-	/* 2007/07/11 MH Assign current operate rate.  */
-	if (pAdapter->RegWirelessMode == WIRELESS_MODE_A ||
-		pAdapter->RegWirelessMode == WIRELESS_MODE_B ||
-		pAdapter->RegWirelessMode == WIRELESS_MODE_G)
-	{
-		pMgntInfo->CurrentOperaRate = (rx_tx_fb.F_Rate & 0x7F);
-	}
-	else if (pAdapter->RegWirelessMode == WIRELESS_MODE_N_24G ||
-		 	 pAdapter->RegWirelessMode == WIRELESS_MODE_N_5G)
-	{
-		pMgntInfo->HTCurrentOperaRate = (rx_tx_fb.F_Rate & 0x8F);
-	}
-#endif
+
 	/* 2007/01/17 MH Comment previous method for TX statistic function. */
 	/* Collect info TX feedback packet to fill TCB. */
 	/* We can not know the packet length and transmit type: broadcast or uni
diff --git a/drivers/staging/rtl8192su/r819xU_cmdpkt.h b/drivers/staging/rtl8192su/r819xU_cmdpkt.h
index f67af6c..cced8e0 100644
--- a/drivers/staging/rtl8192su/r819xU_cmdpkt.h
+++ b/drivers/staging/rtl8192su/r819xU_cmdpkt.h
@@ -13,17 +13,6 @@
 #define ISR_TxBcnErr				BIT26			// Transmit Beacon Error
 #define ISR_BcnTimerIntr			BIT13			// Beacon Timer Interrupt
 
-#if 0
-/* Define packet type. */
-typedef enum tag_packet_type
-{
-    PACKET_BROADCAST,
-    PACKET_MULTICAST,
-    PACKET_UNICAST,
-    PACKET_TYPE_MAX
-}cmpk_pkt_type_e;
-#endif
-
 /* Define element ID of command packet. */
 
 /*------------------------------Define structure----------------------------*/
@@ -201,15 +190,6 @@ typedef enum tag_command_packet_directories
     RX_CMD_ELE_MAX
 }cmpk_element_e;
 
-#if 0
-typedef enum _rt_status{
-        RT_STATUS_SUCCESS,
-        RT_STATUS_FAILURE,
-        RT_STATUS_PENDING,
-        RT_STATUS_RESOURCE
-}rt_status,*prt_status;
-#endif
-
 extern bool cmpk_message_handle_tx(struct net_device *dev, u8* codevirtualaddress, u32 packettype, u32 buffer_len);
 
 extern  u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats * pstats);
diff --git a/drivers/staging/rtl8192su/r819xU_firmware.c b/drivers/staging/rtl8192su/r819xU_firmware.c
deleted file mode 100644
index 219f71e..0000000
--- a/drivers/staging/rtl8192su/r819xU_firmware.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/**************************************************************************************************
- * Procedure:    Init boot code/firmware code/data session
- *
- * Description: This routine will intialize firmware. If any error occurs during the initialization
- * 		process, the routine shall terminate immediately and return fail.
- *		NIC driver should call NdisOpenFile only from MiniportInitialize.
- *
- * Arguments:   The pointer of the adapter
-
- * Returns:
- *        NDIS_STATUS_FAILURE - the following initialization process should be terminated
- *        NDIS_STATUS_SUCCESS - if firmware initialization process success
-**************************************************************************************************/
-//#include "ieee80211.h"
-#include "r8192U.h"
-#include "r8192U_hw.h"
-#include "r819xU_firmware_img.h"
-#include "r819xU_firmware.h"
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-#include <linux/firmware.h>
-#endif
-void firmware_init_param(struct net_device *dev)
-{
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	rt_firmware		*pfirmware = priv->pFirmware;
-
-	pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE);
-}
-
-/*
- * segment the img and use the ptr and length to remember info on each segment
- *
- */
-bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, u32 buffer_len)
-{
-	struct r8192_priv   *priv = ieee80211_priv(dev);
-	bool 		    rt_status = true;
-	u16		    frag_threshold;
-	u16		    frag_length, frag_offset = 0;
-	//u16		    total_size;
-	int		    i;
-
-	rt_firmware	    *pfirmware = priv->pFirmware;
-	struct sk_buff	    *skb;
-	unsigned char	    *seg_ptr;
-	cb_desc		    *tcb_desc;
-	u8                  bLastIniPkt;
-
-	firmware_init_param(dev);
-	//Fragmentation might be required
-	frag_threshold = pfirmware->cmdpacket_frag_thresold;
-	do {
-		if((buffer_len - frag_offset) > frag_threshold) {
-			frag_length = frag_threshold ;
-			bLastIniPkt = 0;
-
-		} else {
-			frag_length = buffer_len - frag_offset;
-			bLastIniPkt = 1;
-
-		}
-
-		/* Allocate skb buffer to contain firmware info and tx descriptor info
-		 * add 4 to avoid packet appending overflow.
-		 * */
-		#ifdef RTL8192U
-		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
-		#else
-		skb  = dev_alloc_skb(frag_length + 4);
-		#endif
-		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
-		tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
-		tcb_desc->queue_index = TXCMD_QUEUE;
-		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
-		tcb_desc->bLastIniPkt = bLastIniPkt;
-
-		#ifdef RTL8192U
-		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
-		#endif
-		seg_ptr = skb->data;
-		/*
-		 * Transform from little endian to big endian
-                 * and pending  zero
-		 */
-		for(i=0 ; i < frag_length; i+=4) {
-			*seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
-			*seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
-			*seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
-			*seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
-		}
-		tcb_desc->txbuf_size= (u16)i;
-		skb_put(skb, i);
-
-		if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
-			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
-			(priv->ieee80211->queue_stop) ) {
-			RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
-			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
-		} else {
-			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
-		}
-
-		code_virtual_address += frag_length;
-		frag_offset += frag_length;
-
-	}while(frag_offset < buffer_len);
-
-	return rt_status;
-
-#if 0
-cmdsend_downloadcode_fail:
-	rt_status = false;
-	RT_TRACE(COMP_ERR, "CmdSendDownloadCode fail !!\n");
-	return rt_status;
-#endif
-}
-
-bool
-fwSendNullPacket(
-	struct net_device *dev,
-	u32			Length
-)
-{
-	bool	rtStatus = true;
-	struct r8192_priv   *priv = ieee80211_priv(dev);
-	struct sk_buff	    *skb;
-	cb_desc		    *tcb_desc;
-	unsigned char	    *ptr_buf;
-	bool	bLastInitPacket = false;
-
-	//PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
-
-	//Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
-	skb  = dev_alloc_skb(Length+ 4);
-	memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
-	tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
-	tcb_desc->queue_index = TXCMD_QUEUE;
-	tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
-	tcb_desc->bLastIniPkt = bLastInitPacket;
-	ptr_buf = skb_put(skb, Length);
-	memset(ptr_buf,0,Length);
-	tcb_desc->txbuf_size= (u16)Length;
-
-	if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
-			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
-			(priv->ieee80211->queue_stop) ) {
-			RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n");
-			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
-		} else {
-			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
-		}
-
-	//PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
-	return rtStatus;
-}
-
-#if 0
-/*
- * Procedure  :   Download code into IMEM or DMEM
- * Description:   This routine will intialize firmware. If any error occurs during the initialization
- *				process, the routine shall terminate immediately and return fail.
- *				The routine copy virtual address get from opening of file into shared memory
- *				allocated during initialization. If code size larger than a conitneous shared
- *				memory may contain, the code should be divided into several section.
- *				!!!NOTES This finction should only be called during MPInitialization because
- *				A NIC driver should call NdisOpenFile only from MiniportInitialize.
- * Arguments :    The pointer of the adapter
- *			   Code address (Virtual address, should fill descriptor with physical address)
- *			   Code size
- * Returns  :
- *        RT_STATUS_FAILURE - the following initialization process should be terminated
- *        RT_STATUS_SUCCESS - if firmware initialization process success
- */
-bool fwsend_download_code(struct net_device *dev)
-{
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	rt_firmware		*pfirmware = (rt_firmware*)(&priv->firmware);
-
-	bool			rt_status = true;
-	u16			length = 0;
-	u16			offset = 0;
-	u16			frag_threhold;
-	bool			last_init_packet = false;
-	u32			check_txcmdwait_queueemptytime = 100000;
-	u16			cmd_buf_len;
-	u8			*ptr_cmd_buf;
-
-	/* reset to 0 for first segment of img download */
-	pfirmware->firmware_seg_index = 1;
-
-	if(pfirmware->firmware_seg_index == pfirmware->firmware_seg_maxnum) {
-		last_init_packet = 1;
-	}
-
-	cmd_buf_len = pfirmware->firmware_seg_container[pfirmware->firmware_seg_index-1].seg_size;
-	ptr_cmd_buf = pfirmware->firmware_seg_container[pfirmware->firmware_seg_index-1].seg_ptr;
-	rtl819xU_tx_cmd(dev, ptr_cmd_buf, cmd_buf_len, last_init_packet, DESC_PACKET_TYPE_INIT);
-
-	rt_status = true;
-	return rt_status;
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// Procedure:    Check whether main code is download OK. If OK, turn on CPU
-//
-// Description:   CPU register locates in different page against general register.
-//			    Switch to CPU register in the begin and switch back before return
-//
-//
-// Arguments:   The pointer of the adapter
-//
-// Returns:
-//        NDIS_STATUS_FAILURE - the following initialization process should be terminated
-//        NDIS_STATUS_SUCCESS - if firmware initialization process success
-//-----------------------------------------------------------------------------
-bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev)
-{
-	struct r8192_priv  *priv = ieee80211_priv(dev);
-	bool rt_status = true;
-	int  check_putcodeOK_time = 200000, check_bootOk_time = 200000;
-	u32  CPU_status = 0;
-
-	/* Check whether put code OK */
-	do {
-		CPU_status = read_nic_dword(dev, CPU_GEN);
-
-		if((CPU_status&CPU_GEN_PUT_CODE_OK) || (priv->usb_error==true))
-			break;
-
-	}while(check_putcodeOK_time--);
-
-	if(!(CPU_status&CPU_GEN_PUT_CODE_OK)) {
-		RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n");
-		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
-	} else {
-		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n");
-	}
-
-	/* Turn On CPU */
-	CPU_status = read_nic_dword(dev, CPU_GEN);
-	write_nic_byte(dev, CPU_GEN, (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff));
-	mdelay(1000);
-
-	/* Check whether CPU boot OK */
-	do {
-		CPU_status = read_nic_dword(dev, CPU_GEN);
-
-		if((CPU_status&CPU_GEN_BOOT_RDY)||(priv->usb_error == true))
-			break;
-	}while(check_bootOk_time--);
-
-	if(!(CPU_status&CPU_GEN_BOOT_RDY)) {
-		goto CPUCheckMainCodeOKAndTurnOnCPU_Fail;
-	} else {
-		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n");
-	}
-
-	return rt_status;
-
-CPUCheckMainCodeOKAndTurnOnCPU_Fail:
-	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
-	rt_status = FALSE;
-	return rt_status;
-}
-
-bool CPUcheck_firmware_ready(struct net_device *dev)
-{
-	struct r8192_priv  *priv = ieee80211_priv(dev);
-	bool		rt_status = true;
-	int		check_time = 200000;
-	u32		CPU_status = 0;
-
-	/* Check Firmware Ready */
-	do {
-		CPU_status = read_nic_dword(dev, CPU_GEN);
-
-		if((CPU_status&CPU_GEN_FIRM_RDY)||(priv->usb_error == true))
-			break;
-
-	}while(check_time--);
-
-	if(!(CPU_status&CPU_GEN_FIRM_RDY))
-		goto CPUCheckFirmwareReady_Fail;
-	else
-		RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n");
-
-	return rt_status;
-
-CPUCheckFirmwareReady_Fail:
-	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
-	rt_status = false;
-	return rt_status;
-
-}
-
-bool init_firmware(struct net_device *dev)
-{
-	struct r8192_priv 	*priv = ieee80211_priv(dev);
-	bool			rt_status = TRUE;
-
-	u8			*firmware_img_buf[3] = { &rtl8190_fwboot_array[0],
-						   	 &rtl8190_fwmain_array[0],
-						   	 &rtl8190_fwdata_array[0]};
-
-	u32			firmware_img_len[3] = { sizeof(rtl8190_fwboot_array),
-						   	sizeof(rtl8190_fwmain_array),
-						   	sizeof(rtl8190_fwdata_array)};
-	u32			file_length = 0;
-	u8			*mapped_file = NULL;
-	u32			init_step = 0;
-	opt_rst_type_e	rst_opt = OPT_SYSTEM_RESET;
-	firmware_init_step_e 	starting_state = FW_INIT_STEP0_BOOT;
-
-	rt_firmware		*pfirmware = priv->pFirmware;
-	const struct firmware 	*fw_entry;
-	const char *fw_name[3] = { "RTL8192U/boot.img",
-                           "RTL8192U/main.img",
-			   "RTL8192U/data.img"};
-	int rc;
-
-	RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n");
-
-	if (pfirmware->firmware_status == FW_STATUS_0_INIT ) {
-		/* it is called by reset */
-		rst_opt = OPT_SYSTEM_RESET;
-		starting_state = FW_INIT_STEP0_BOOT;
-		// TODO: system reset
-
-	}else if(pfirmware->firmware_status == FW_STATUS_5_READY) {
-		/* it is called by Initialize */
-		rst_opt = OPT_FIRMWARE_RESET;
-		starting_state = FW_INIT_STEP2_DATA;
-	}else {
-		 RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined firmware state\n");
-	}
-
-	/*
-	 * Download boot, main, and data image for System reset.
-	 * Download data image for firmware reseta
-	 */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	priv->firmware_source = FW_SOURCE_HEADER_FILE;
-#else
-	priv->firmware_source = FW_SOURCE_IMG_FILE;
-#endif
-	for(init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; init_step++) {
-		/*
-		 * Open Image file, and map file to contineous memory if open file success.
-		 * or read image file from array. Default load from IMG file
-		 */
-		if(rst_opt == OPT_SYSTEM_RESET) {
-			switch(priv->firmware_source) {
-				case FW_SOURCE_IMG_FILE:
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-					if(pfirmware->firmware_buf_size[init_step] == 0) {
-						rc = request_firmware(&fw_entry, fw_name[init_step],&priv->udev->dev);
-						if(rc < 0 ) {
-							RT_TRACE(COMP_ERR, "request firmware fail!\n");
-							goto download_firmware_fail;
-						}
-
-						if(fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) {
-							//RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
-							 RT_TRACE(COMP_FIRMWARE, "img file size exceed the container buffer fail!, entry_size = %d, buf_size = %d\n",fw_entry->size,sizeof(pfirmware->firmware_buf[init_step]));
-
-							goto download_firmware_fail;
-						}
-
-						if(init_step != FW_INIT_STEP1_MAIN) {
-							memcpy(pfirmware->firmware_buf[init_step],fw_entry->data,fw_entry->size);
-							pfirmware->firmware_buf_size[init_step] = fw_entry->size;
-						} else {
-#ifdef RTL8190P
-							memcpy(pfirmware->firmware_buf[init_step],fw_entry->data,fw_entry->size);
-							pfirmware->firmware_buf_size[init_step] = fw_entry->size;
-#else
-							memset(pfirmware->firmware_buf[init_step],0,128);
-							memcpy(&pfirmware->firmware_buf[init_step][128],fw_entry->data,fw_entry->size);
-							mapped_file = pfirmware->firmware_buf[init_step];
-							pfirmware->firmware_buf_size[init_step] = fw_entry->size+128;
-#endif
-						}
-						//pfirmware->firmware_buf_size = file_length;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-						if(rst_opt == OPT_SYSTEM_RESET) {
-							release_firmware(fw_entry);
-						}
-#endif
-					}
-					mapped_file = pfirmware->firmware_buf[init_step];
-					file_length = pfirmware->firmware_buf_size[init_step];
-#endif
-
-					break;
-
-				case FW_SOURCE_HEADER_FILE:
-					mapped_file =  firmware_img_buf[init_step];
-					file_length  = firmware_img_len[init_step];
-					if(init_step == FW_INIT_STEP2_DATA) {
-						memcpy(pfirmware->firmware_buf[init_step], mapped_file, file_length);
-						pfirmware->firmware_buf_size[init_step] = file_length;
-					}
-					break;
-
-				default:
-					break;
-			}
-
-
-		}else if(rst_opt == OPT_FIRMWARE_RESET ) {
-			/* we only need to download data.img here */
-			mapped_file = pfirmware->firmware_buf[init_step];
-			file_length = pfirmware->firmware_buf_size[init_step];
-		}
-
-		/* Download image file */
-		/* The firmware download process is just as following,
-		 * 1. that is each packet will be segmented and inserted to the wait queue.
-		 * 2. each packet segment will be put in the skb_buff packet.
-		 * 3. each skb_buff packet data content will already include the firmware info
-		 *   and Tx descriptor info
-		 * */
-		rt_status = fw_download_code(dev,mapped_file,file_length);
-
-		if(rt_status != TRUE) {
-			goto download_firmware_fail;
-		}
-
-		switch(init_step) {
-			case FW_INIT_STEP0_BOOT:
-				/* Download boot
-				 * initialize command descriptor.
-				 * will set polling bit when firmware code is also configured
-				 */
-				pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE;
-#ifdef RTL8190P
-				// To initialize IMEM, CPU move code  from 0x80000080, hence, we send 0x80 byte packet
-				rt_status = fwSendNullPacket(dev, RTL8190_CPU_START_OFFSET);
-				if(rt_status != true)
-				{
-					RT_TRACE(COMP_INIT, "fwSendNullPacket() fail ! \n");
-					goto  download_firmware_fail;
-				}
-#endif
-				//mdelay(1000);
-				/*
-				 * To initialize IMEM, CPU move code  from 0x80000080,
-				 * hence, we send 0x80 byte packet
-				 */
-				break;
-
-			case FW_INIT_STEP1_MAIN:
-				/* Download firmware code. Wait until Boot Ready and Turn on CPU */
-				pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE;
-
-				/* Check Put Code OK and Turn On CPU */
-				rt_status = CPUcheck_maincodeok_turnonCPU(dev);
-				if(rt_status != TRUE) {
-					RT_TRACE(COMP_ERR, "CPUcheck_maincodeok_turnonCPU fail!\n");
-					goto download_firmware_fail;
-				}
-
-				pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU;
-				break;
-
-			case FW_INIT_STEP2_DATA:
-				/* download initial data code */
-				pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE;
-				mdelay(1);
-
-				rt_status = CPUcheck_firmware_ready(dev);
-				if(rt_status != TRUE) {
-					RT_TRACE(COMP_ERR, "CPUcheck_firmware_ready fail(%d)!\n",rt_status);
-					goto download_firmware_fail;
-				}
-
-				/* wait until data code is initialized ready.*/
-				pfirmware->firmware_status = FW_STATUS_5_READY;
-				break;
-		}
-	}
-
-	RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n");
-	//assert(pfirmware->firmware_status == FW_STATUS_5_READY, ("Firmware Download Fail\n"));
-
-	return rt_status;
-
-download_firmware_fail:
-	RT_TRACE(COMP_ERR, "ERR in %s()\n", __FUNCTION__);
-	rt_status = FALSE;
-	return rt_status;
-
-}
-
-#if 0
-/*
- * Procedure:   (1)  Transform firmware code from little endian to big endian if required.
- *	        (2)  Number of bytes in Firmware downloading should be multiple
- *	   	     of 4 bytes. If length is not multiple of 4 bytes, appending of zeros is required
- *
- */
-void CmdAppendZeroAndEndianTransform(
-	u1Byte	*pDst,
-	u1Byte	*pSrc,
-	u2Byte   	*pLength)
-{
-
-	u2Byte	ulAppendBytes = 0, i;
-	u2Byte	ulLength = *pLength;
-
-//test only
-	//memset(pDst, 0xcc, 12);
-
-
-	/* Transform from little endian to big endian */
-//#if DEV_BUS_TYPE==PCI_INTERFACE
-#if 0
-	for( i=0 ; i<(*pLength) ; i+=4)
-	{
-		if((i+3) < (*pLength))	pDst[i+0] = pSrc[i+3];
-		if((i+2) < (*pLength))	pDst[i+1] = pSrc[i+2];
-		if((i+1) < (*pLength))	pDst[i+2] = pSrc[i+1];
-		if((i+0) < (*pLength))	pDst[i+3] = pSrc[i+0];
-	}
-#else
-	pDst += USB_HWDESC_HEADER_LEN;
-	ulLength -= USB_HWDESC_HEADER_LEN;
-
-	for( i=0 ; i<ulLength ; i+=4) {
-		if((i+3) < ulLength)	pDst[i+0] = pSrc[i+3];
-		if((i+2) < ulLength)	pDst[i+1] = pSrc[i+2];
-		if((i+1) < ulLength)	pDst[i+2] = pSrc[i+1];
-		if((i+0) < ulLength)	pDst[i+3] = pSrc[i+0];
-
-	}
-#endif
-
-	//1(2) Append Zero
-	if(  ((*pLength) % 4)  >0)
-	{
-		ulAppendBytes = 4-((*pLength) % 4);
-
-		for(i=0 ; i<ulAppendBytes; i++)
-			pDst[  4*((*pLength)/4)  + i ] = 0x0;
-
-		*pLength += ulAppendBytes;
-	}
-}
-#endif
-
-#if 0
-RT_STATUS
-CmdSendPacket(
-	PADAPTER				Adapter,
-	PRT_TCB					pTcb,
-	PRT_TX_LOCAL_BUFFER 			pBuf,
-	u4Byte					BufferLen,
-	u4Byte					PacketType,
-	BOOLEAN					bLastInitPacket
-	)
-{
-	s2Byte		i;
-	u1Byte		QueueID;
-	u2Byte		firstDesc,curDesc = 0;
-	u2Byte		FragIndex=0, FragBufferIndex=0;
-
-	RT_STATUS	rtStatus = RT_STATUS_SUCCESS;
-
-	CmdInitTCB(Adapter, pTcb, pBuf, BufferLen);
-
-
-	if(CmdCheckFragment(Adapter, pTcb, pBuf))
-		CmdFragmentTCB(Adapter, pTcb);
-	else
-		pTcb->FragLength[0] = (u2Byte)pTcb->BufferList[0].Length;
-
-	QueueID=pTcb->SpecifiedQueueID;
-#if DEV_BUS_TYPE!=USB_INTERFACE
-	firstDesc=curDesc=Adapter->NextTxDescToFill[QueueID];
-#endif
-
-#if DEV_BUS_TYPE!=USB_INTERFACE
-	if(VacancyTxDescNum(Adapter, QueueID) > pTcb->BufferCount)
-#else
-	if(PlatformIsTxQueueAvailable(Adapter, QueueID, pTcb->BufferCount) &&
-		RTIsListEmpty(&Adapter->TcbWaitQueue[QueueID]))
-#endif
-	{
-		pTcb->nDescUsed=0;
-
-		for(i=0 ; i<pTcb->BufferCount ; i++)
-		{
-			Adapter->HalFunc.TxFillCmdDescHandler(
-				Adapter,
-				pTcb,
-				QueueID,							//QueueIndex
-				curDesc,							//index
-				FragBufferIndex==0,						//bFirstSeg
-				FragBufferIndex==(pTcb->FragBufCount[FragIndex]-1),		//bLastSeg
-				pTcb->BufferList[i].VirtualAddress,				//VirtualAddress
-				pTcb->BufferList[i].PhysicalAddressLow,				//PhyAddressLow
-				pTcb->BufferList[i].Length,					//BufferLen
-				i!=0,								//bSetOwnBit
-				(i==(pTcb->BufferCount-1)) && bLastInitPacket,			//bLastInitPacket
-				PacketType,							//DescPacketType
-				pTcb->FragLength[FragIndex]					//PktLen
-				);
-
-			if(FragBufferIndex==(pTcb->FragBufCount[FragIndex]-1))
-			{ // Last segment of the fragment.
-				pTcb->nFragSent++;
-			}
-
-			FragBufferIndex++;
-			if(FragBufferIndex==pTcb->FragBufCount[FragIndex])
-			{
-				FragIndex++;
-				FragBufferIndex=0;
-			}
-
-#if DEV_BUS_TYPE!=USB_INTERFACE
-			curDesc=(curDesc+1)%Adapter->NumTxDesc[QueueID];
-#endif
-			pTcb->nDescUsed++;
-		}
-
-#if DEV_BUS_TYPE!=USB_INTERFACE
-		RTInsertTailList(&Adapter->TcbBusyQueue[QueueID], &pTcb->List);
-		IncrementTxDescToFill(Adapter, QueueID, pTcb->nDescUsed);
-		Adapter->HalFunc.SetTxDescOWNHandler(Adapter, QueueID, firstDesc);
-		// TODO: should call poll use QueueID
-		Adapter->HalFunc.TxPollingHandler(Adapter, TXCMD_QUEUE);
-#endif
-	}
-	else
-#if DEV_BUS_TYPE!=USB_INTERFACE
-		goto CmdSendPacket_Fail;
-#else
-	{
-		pTcb->bLastInitPacket = bLastInitPacket;
-		RTInsertTailList(&Adapter->TcbWaitQueue[pTcb->SpecifiedQueueID], &pTcb->List);
-	}
-#endif
-
-	return rtStatus;
-
-#if DEV_BUS_TYPE!=USB_INTERFACE
-CmdSendPacket_Fail:
-	rtStatus = RT_STATUS_FAILURE;
-	return rtStatus;
-#endif
-
-}
-#endif
-
-
-
-
-#if 0
-RT_STATUS
-FWSendNullPacket(
-	IN	PADAPTER		Adapter,
-	IN	u4Byte			Length
-)
-{
-	RT_STATUS	rtStatus = RT_STATUS_SUCCESS;
-
-
-	PRT_TCB					pTcb;
-	PRT_TX_LOCAL_BUFFER 	pBuf;
-	BOOLEAN					bLastInitPacket = FALSE;
-
-	PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
-
-#if DEV_BUS_TYPE==USB_INTERFACE
-	Length += USB_HWDESC_HEADER_LEN;
-#endif
-
-	//Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
-	if(MgntGetBuffer(Adapter, &pTcb, &pBuf))
-	{
-		PlatformZeroMemory(pBuf->Buffer.VirtualAddress, Length);
-		rtStatus = CmdSendPacket(Adapter, pTcb, pBuf, Length, DESC_PACKET_TYPE_INIT, bLastInitPacket);	//0 : always set LastInitPacket to zero
-//#if HAL_CODE_BASE != RTL8190HW
-//		// TODO: for test only
-//		ReturnTCB(Adapter, pTcb, RT_STATUS_SUCCESS);
-//#endif
-		if(rtStatus == RT_STATUS_FAILURE)
-			goto CmdSendNullPacket_Fail;
-	}else
-		goto CmdSendNullPacket_Fail;
-
-	PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
-	return rtStatus;
-
-
-CmdSendNullPacket_Fail:
-	PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
-	rtStatus = RT_STATUS_FAILURE;
-	RT_ASSERT(rtStatus == RT_STATUS_SUCCESS, ("CmdSendDownloadCode fail !!\n"));
-	return rtStatus;
-}
-#endif
-
-
diff --git a/drivers/staging/rtl8192su/r819xU_firmware.h b/drivers/staging/rtl8192su/r819xU_firmware.h
deleted file mode 100644
index 10801be..0000000
--- a/drivers/staging/rtl8192su/r819xU_firmware.h
+++ /dev/null
@@ -1,106 +0,0 @@
-#ifndef __INC_FIRMWARE_H
-#define __INC_FIRMWARE_H
-
-#define RTL8190_CPU_START_OFFSET	0x80
-/* TODO: this definition is TBD */
-//#define USB_HWDESC_HEADER_LEN	0
-
-/* It should be double word alignment */
-//#if DEV_BUS_TYPE==PCI_INTERFACE
-//#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	4*(v/4) - 8
-//#else
-#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v)	(4*(v/4) - 8 - USB_HWDESC_HEADER_LEN)
-//#endif
-
-typedef enum _firmware_init_step{
-	FW_INIT_STEP0_BOOT = 0,
-	FW_INIT_STEP1_MAIN = 1,
-	FW_INIT_STEP2_DATA = 2,
-}firmware_init_step_e;
-
-typedef enum _opt_rst_type{
-	OPT_SYSTEM_RESET = 0,
-	OPT_FIRMWARE_RESET = 1,
-}opt_rst_type_e;
-
-/* due to rtl8192 firmware */
-typedef enum _desc_packet_type_e{
-	DESC_PACKET_TYPE_INIT = 0,
-	DESC_PACKET_TYPE_NORMAL = 1,
-}desc_packet_type_e;
-
-typedef enum _firmware_source{
-	FW_SOURCE_IMG_FILE = 0,
-	FW_SOURCE_HEADER_FILE = 1,              //from header file
-}firmware_source_e, *pfirmware_source_e;
-
-typedef enum _firmware_status{
-	FW_STATUS_0_INIT = 0,
-	FW_STATUS_1_MOVE_BOOT_CODE = 1,
-	FW_STATUS_2_MOVE_MAIN_CODE = 2,
-	FW_STATUS_3_TURNON_CPU = 3,
-	FW_STATUS_4_MOVE_DATA_CODE = 4,
-	FW_STATUS_5_READY = 5,
-}firmware_status_e;
-
-typedef struct _rt_firmare_seg_container {
-	u16     seg_size;
-	u8      *seg_ptr;
-}fw_seg_container, *pfw_seg_container;
-
-#define RTL8190_MAX_FIRMWARE_CODE_SIZE  64000   //64k
-#define MAX_FW_INIT_STEP                3
-typedef struct _rt_firmware{
-	firmware_status_e firmware_status;
-	u16               cmdpacket_frag_thresold;
-	u8                firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE];
-	u16               firmware_buf_size[MAX_FW_INIT_STEP];
-}rt_firmware, *prt_firmware;
-
-typedef struct _rt_firmware_info_819xUsb{
-	u8		sz_info[16];
-}rt_firmware_info_819xUsb, *prt_firmware_info_819xUsb;
-
-#if 0
-/* CPU related */
-RT_STATUS
-CPUCheckMainCodeOKAndTurnOnCPU(
-	IN	PADAPTER			Adapter
-	);
-
-RT_STATUS
-CPUCheckFirmwareReady(
-	IN	PADAPTER			Adapter
-	);
-
-/* Firmware related */
-VOID
-FWInitializeParameters(
-	IN	PADAPTER		Adapter
-	);
-
-RT_STATUS
-FWSendDownloadCode(
-	IN	PADAPTER		Adapter,
-	IN	pu1Byte			CodeVirtualAddrress,
-	IN	u4Byte			BufferLen
-	);
-
-RT_STATUS
-FWSendNullPacket(
-	IN	PADAPTER		Adapter,
-	IN	u4Byte			Length
-	);
-
-RT_STATUS
-CmdSendPacket(
-	PADAPTER				Adapter,
-	PRT_TCB					pTcb,
-	PRT_TX_LOCAL_BUFFER 	pBuf,
-	u4Byte					BufferLen,
-	u4Byte					PacketType,
-	BOOLEAN					bLastInitPacket
-	);
-#endif
-#endif
-
diff --git a/drivers/staging/rtl8192su/r819xU_firmware_img.c b/drivers/staging/rtl8192su/r819xU_firmware_img.c
deleted file mode 100644
index 29b656d..0000000
--- a/drivers/staging/rtl8192su/r819xU_firmware_img.c
+++ /dev/null
@@ -1,3447 +0,0 @@
-/*Created on  2008/ 7/16,  5:31*/
-#include <linux/types.h>
-
-u8 rtl8190_fwboot_array[] = {
-0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08,
-0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
-0x25,0x08,0xb0,0x50,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,
-0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b,
-0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00,
-0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01,
-0x25,0x08,0xb0,0x50,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0,
-0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00,
-0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00,
-0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,
-0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,
-0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01,
-0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24,
-0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10,
-0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10,
-0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x4b,0x84,
-0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,};
-
-u8 rtl8190_fwmain_array[] = {
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x12,0x94,
-0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09,
-0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24,
-0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0,
-0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x8b,0x60,0x00,0x85,0x18,0x21,
-0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00,
-0x27,0x82,0x8b,0x6a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00,
-0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x8b,0x60,
-0x24,0x02,0x09,0xc4,0x24,0x03,0x01,0x00,0xa7,0x82,0x8b,0x76,0x24,0x02,0x04,0x00,
-0xaf,0x83,0x8b,0x78,0xaf,0x82,0x8b,0x7c,0x24,0x03,0x00,0x0a,0x24,0x02,0x00,0x04,
-0x24,0x05,0x00,0x02,0x24,0x04,0x00,0x01,0xa3,0x83,0x8b,0x62,0xa3,0x82,0x8b,0x68,
-0x24,0x03,0x00,0x01,0x24,0x02,0x02,0x00,0xa3,0x84,0x8b,0x66,0xa3,0x85,0x8b,0x69,
-0xa7,0x82,0x8b,0x6a,0xa7,0x83,0x8b,0x6c,0xa3,0x84,0x8b,0x61,0xa3,0x80,0x8b,0x63,
-0xa3,0x80,0x8b,0x64,0xa3,0x80,0x8b,0x65,0xa3,0x85,0x8b,0x67,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x84,
-0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x27,0x84,0x8b,0x88,0x00,0x00,0x10,0x21,
-0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03,
-0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00,0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc8,0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00,
-0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00,0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00,
-0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00,0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03,
-0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03,0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03,
-0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11,0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02,
-0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66,
-0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43,
-0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b,0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01,
-0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20,0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,
-0x08,0x00,0x00,0x96,0x34,0x42,0x01,0x24,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x96,
-0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x84,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18,0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21,
-0x27,0x85,0x8b,0x80,0x8c,0xa3,0x00,0x00,0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,
-0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a,0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00,
-0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03,
-0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3,0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03,
-0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23,
-0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40,0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x8b,0x88,0x00,0x0a,0x20,0x0b,0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05,
-0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,
-0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,
-0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01,0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80,
-0x27,0x82,0x8b,0x88,0xa0,0x67,0x00,0x01,0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01,
-0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x80,
-0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21,
-0xac,0x62,0x00,0x00,0x27,0x85,0x8b,0x84,0x27,0x82,0x8b,0x80,0x00,0xc5,0x28,0x21,
-0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00,0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
-0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x08,0x00,0x00,0xb9,0xac,0xa0,0x00,0x00,0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0xaf,0x83,0x8b,0x9c,0x08,0x00,0x00,0xa9,0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x90,
-0x08,0x00,0x00,0xa9,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x18,0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00,
-0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00,0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03,
-0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03,0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01,
-0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2,0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21,
-0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09,0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c,
-0x30,0x43,0x00,0x03,0x83,0x82,0x8b,0x88,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04,0x30,0x43,0x00,0x06,0x93,0x82,0x8b,0xa0,
-0x08,0x00,0x01,0x21,0x00,0x43,0x10,0x21,0x83,0x82,0x8b,0x94,0x00,0x00,0x00,0x00,
-0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x21,0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05,
-0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xec,0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20,
-0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01,0xaf,0x84,0x8b,0xb0,
-0xa3,0x82,0x8b,0xc0,0xa7,0x80,0x8b,0xb4,0xa7,0x80,0x8b,0xb6,0xaf,0x80,0x8b,0xb8,
-0xaf,0x80,0x8b,0xbc,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x05,0x2c,0x3c,0x04,0xb0,0x03,
-0xac,0x62,0x00,0x00,0x34,0x84,0x00,0xac,0x80,0xa2,0x00,0x15,0x8c,0x83,0x00,0x00,
-0x27,0xbd,0xff,0xf0,0x00,0x43,0x10,0x21,0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x10,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,
-0x24,0x63,0x05,0x64,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0x8f,0x90,0x8b,0xb0,0x0c,0x00,0x02,0x9a,
-0x00,0x80,0x88,0x21,0x14,0x40,0x00,0x2a,0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02,
-0x34,0x42,0x02,0x01,0x24,0x02,0x02,0x01,0xae,0x02,0x00,0x00,0x97,0x84,0x8b,0xb4,
-0x97,0x82,0x8b,0xb6,0x3c,0x03,0xb0,0x02,0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04,
-0xa7,0x82,0x8b,0xb6,0xa4,0x82,0x00,0x00,0x8f,0x84,0x8b,0xb8,0x8f,0x82,0x8b,0xb0,
-0x93,0x85,0x8b,0x62,0x24,0x84,0x00,0x01,0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff,
-0x3c,0x07,0xb0,0x06,0x3c,0x06,0xb0,0x03,0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a,
-0x34,0xe7,0x80,0x18,0xaf,0x82,0x8b,0xb0,0xaf,0x84,0x8b,0xb8,0x10,0xa0,0x00,0x08,
-0x34,0xc6,0x01,0x08,0x8f,0x83,0x8b,0xbc,0x8f,0x84,0x8b,0x7c,0x8c,0xc2,0x00,0x00,
-0x00,0x64,0x18,0x21,0x00,0x43,0x10,0x2b,0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,
-0x8c,0xe2,0x00,0x00,0x3c,0x03,0x0f,0x00,0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24,
-0x10,0x44,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,
-0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x27,0xbd,0xff,0xd8,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x50,
-0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20,0x8f,0x90,0x8b,0xb0,0xac,0x43,0x00,0x00,
-0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,
-0x00,0x80,0x88,0x21,0x00,0xa0,0x90,0x21,0x0c,0x00,0x02,0x9a,0x00,0xc0,0x98,0x21,
-0x24,0x07,0x8f,0xff,0x14,0x40,0x00,0x19,0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03,
-0xae,0x02,0x00,0x00,0x00,0x67,0x80,0x24,0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00,
-0x00,0x47,0x80,0x24,0x97,0x86,0x8b,0xb4,0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00,
-0x00,0x67,0x80,0x24,0xae,0x13,0x00,0x00,0x8f,0x84,0x8b,0xb0,0x3c,0x02,0xb0,0x02,
-0x97,0x85,0x8b,0xb6,0x00,0xc2,0x30,0x21,0x8f,0x82,0x8b,0xb8,0x24,0x84,0x00,0x10,
-0x24,0xa5,0x00,0x10,0x00,0x87,0x20,0x24,0x24,0x42,0x00,0x01,0xa7,0x85,0x8b,0xb6,
-0xaf,0x84,0x8b,0xb0,0xaf,0x82,0x8b,0xb8,0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
-0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x14,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x02,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfc,0x00,0x82,0x28,0x21,0x8c,0xa4,0x00,0x00,
-0x3c,0x02,0x00,0x70,0x8c,0xa6,0x00,0x08,0x00,0x82,0x10,0x21,0x2c,0x43,0x00,0x06,
-0x10,0x60,0x00,0x09,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80,0x24,0x63,0x01,0xe8,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
-0x00,0x00,0x00,0x00,0xaf,0x86,0x80,0x14,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x8c,0xa4,0x00,0x00,0x0c,0x00,0x17,0xb3,
-0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xde,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0xaa,
-0x00,0xc0,0x20,0x21,0x08,0x00,0x01,0xde,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x80,0x18,0x3c,0x03,0x00,0x0f,
-0x34,0x63,0x42,0x40,0x00,0x43,0x10,0x21,0x00,0x82,0x20,0x2b,0x10,0x80,0x00,0x09,
-0x24,0x03,0x00,0x05,0x8f,0x82,0x83,0x30,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
-0xaf,0x82,0x83,0x30,0x10,0x43,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x8c,0x63,0x01,0x08,0x24,0x02,0x00,0x01,
-0xa3,0x82,0x80,0x11,0xaf,0x80,0x83,0x30,0xaf,0x83,0x80,0x18,0x08,0x00,0x01,0xfb,
-0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x2f,0x00,0x00,0x00,0x00,
-0x8f,0x82,0x80,0x14,0xa3,0x85,0x83,0x63,0x10,0x40,0x00,0x2b,0x2c,0xa2,0x00,0x04,
-0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xfc,0x2c,0x42,0x00,0x08,
-0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xf0,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x6c,
-0x00,0x44,0x10,0x21,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,
-0x03,0xe0,0x00,0x08,0xa4,0x43,0x00,0x00,0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,
-0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xe0,0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x06,
-0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xd0,0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x09,
-0x24,0xa2,0xff,0xc0,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x6c,0x00,0x44,0x10,0x21,
-0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,
-0xa4,0x43,0xff,0xf8,0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x07,0x00,0x05,0x10,0x40,
-0x27,0x84,0x83,0x6c,0x00,0x44,0x10,0x21,0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,
-0x24,0x63,0x00,0x01,0xa4,0x43,0xff,0xf8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x8f,0x86,0x8b,0xb0,0x8f,0x82,0x80,0x14,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
-0x10,0x40,0x00,0x2a,0x00,0xc0,0x38,0x21,0x24,0x02,0x00,0x07,0x24,0x03,0xff,0x9c,
-0xa3,0x82,0x83,0x6b,0xa3,0x83,0x83,0x6a,0x27,0x8a,0x83,0x68,0x00,0x00,0x20,0x21,
-0x24,0x09,0x8f,0xff,0x00,0x04,0x10,0x80,0x00,0x4a,0x28,0x21,0x8c,0xa2,0x00,0x00,
-0x24,0xe3,0x00,0x04,0x24,0x88,0x00,0x01,0xac,0xe2,0x00,0x00,0x10,0x80,0x00,0x02,
-0x00,0x69,0x38,0x24,0xac,0xa0,0x00,0x00,0x31,0x04,0x00,0xff,0x2c,0x82,0x00,0x27,
-0x14,0x40,0xff,0xf5,0x00,0x04,0x10,0x80,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,
-0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x9c,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,
-0xa7,0x83,0x8b,0xb6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,
-0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x9c,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,
-0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x8f,0x86,0x8b,0xb0,
-0x27,0xbd,0xff,0xc8,0x24,0x02,0x00,0x08,0x24,0x03,0x00,0x20,0xaf,0xbf,0x00,0x30,
-0xa3,0xa2,0x00,0x13,0xa3,0xa3,0x00,0x12,0xa7,0xa4,0x00,0x10,0x00,0xc0,0x28,0x21,
-0x27,0xa9,0x00,0x10,0x00,0x00,0x38,0x21,0x24,0x08,0x8f,0xff,0x00,0x07,0x10,0x80,
-0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,
-0x24,0xa2,0x00,0x04,0x2c,0xe3,0x00,0x08,0xac,0xa4,0x00,0x00,0x14,0x60,0xff,0xf7,
-0x00,0x48,0x28,0x24,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02,
-0x24,0x63,0x00,0x20,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6,
-0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,
-0x24,0xc6,0x00,0x20,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,
-0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x93,0x82,0x8b,0xc0,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01,0x8f,0x82,0x8b,0xb8,0x3c,0x05,0xb0,0x06,
-0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18,0x34,0x84,0x01,0x08,0x14,0x40,0x00,0x09,
-0x00,0x00,0x30,0x21,0x97,0x82,0x8b,0xb4,0x8c,0x84,0x00,0x00,0x3c,0x03,0xb0,0x02,
-0x00,0x43,0x10,0x21,0xaf,0x84,0x8b,0xbc,0xa7,0x80,0x8b,0xb6,0xac,0x40,0x00,0x00,
-0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,
-0x8f,0x86,0x8b,0xb0,0x8f,0x82,0x8b,0xb8,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
-0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a,0x00,0x40,0x50,0x21,0x00,0x00,0x38,0x21,
-0x27,0x89,0x83,0x38,0x24,0xe2,0x00,0x01,0x00,0x07,0x18,0x80,0x30,0x47,0x00,0xff,
-0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a,0x14,0x40,0xff,0xfa,0xac,0x60,0x00,0x00,
-0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6f,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x3e,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x3e,0x90,0xa3,0x00,0x15,
-0x97,0x82,0x83,0x40,0x00,0x03,0x1e,0x00,0x00,0x03,0x1e,0x03,0x00,0x43,0x10,0x21,
-0xa7,0x82,0x83,0x40,0x8c,0xa4,0x00,0x20,0x3c,0x02,0x00,0x60,0x3c,0x03,0x00,0x20,
-0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x54,0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x47,
-0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x44,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
-0xa7,0x82,0x83,0x44,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x54,0x00,0x00,0x00,0x00,
-0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x54,0x25,0x42,0x00,0x01,0x28,0x43,0x27,0x10,
-0xaf,0x82,0x8b,0xb8,0x10,0x60,0x00,0x09,0x24,0x02,0x00,0x04,0x93,0x83,0x80,0x11,
-0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x10,
-0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x03,0x00,0x28,
-0xa3,0x83,0x83,0x3a,0xa3,0x82,0x83,0x3b,0x90,0xa2,0x00,0x18,0x93,0x83,0x83,0x63,
-0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,0xa7,0x82,0x83,0x4e,
-0xa3,0x83,0x83,0x5c,0x27,0x89,0x83,0x38,0x24,0x05,0x8f,0xff,0x00,0x07,0x10,0x80,
-0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,
-0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a,0xad,0x04,0x00,0x00,0x14,0x60,0xff,0xf7,
-0x00,0x45,0x40,0x24,0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02,
-0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6,
-0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,
-0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,
-0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x0c,0x00,0x02,0x38,0x00,0x00,0x00,0x00,
-0xa3,0x80,0x80,0x11,0x08,0x00,0x02,0xe7,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x46,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x46,0x84,0xa3,0x00,0x06,
-0x8f,0x82,0x83,0x58,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x58,
-0x08,0x00,0x02,0xdf,0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x42,0x00,0x00,0x00,0x00,
-0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x42,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x50,
-0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x50,0x08,0x00,0x02,0xdf,
-0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x3c,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,
-0xa7,0x82,0x83,0x3c,0x08,0x00,0x02,0xc7,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd0,
-0xaf,0xbf,0x00,0x28,0x8c,0xa3,0x00,0x20,0x8f,0x8a,0x8b,0xb0,0x3c,0x02,0x00,0x10,
-0x00,0x62,0x10,0x24,0x00,0xa0,0x38,0x21,0x01,0x40,0x48,0x21,0x10,0x40,0x00,0x3d,
-0x00,0x80,0x28,0x21,0x8c,0xe4,0x00,0x1c,0x34,0xa5,0x12,0x06,0xaf,0xa5,0x00,0x10,
-0x8c,0x82,0x00,0x08,0x00,0x03,0x1c,0x42,0x30,0x63,0x00,0x30,0x00,0x02,0x13,0x02,
-0x30,0x42,0x00,0x40,0x00,0x43,0x10,0x25,0x90,0xe6,0x00,0x10,0x90,0xe4,0x00,0x13,
-0x94,0xe8,0x00,0x0c,0x94,0xe3,0x00,0x1a,0x00,0x02,0x16,0x00,0x90,0xe7,0x00,0x12,
-0x00,0xa2,0x28,0x25,0x24,0x02,0x12,0x34,0xa7,0xa2,0x00,0x1c,0x24,0x02,0x56,0x78,
-0xaf,0xa5,0x00,0x10,0xa3,0xa6,0x00,0x18,0xa3,0xa7,0x00,0x1f,0xa7,0xa3,0x00,0x1a,
-0xa3,0xa4,0x00,0x19,0xa7,0xa8,0x00,0x20,0xa7,0xa2,0x00,0x22,0x00,0x00,0x28,0x21,
-0x27,0xa7,0x00,0x10,0x24,0x06,0x8f,0xff,0x00,0x05,0x10,0x80,0x00,0x47,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01,0x30,0x65,0x00,0xff,0x25,0x22,0x00,0x04,
-0x2c,0xa3,0x00,0x05,0xad,0x24,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x46,0x48,0x24,
-0x97,0x83,0x8b,0xb6,0x97,0x85,0x8b,0xb4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x14,
-0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xb6,0x34,0x84,0x80,0x18,
-0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x25,0x46,0x00,0x14,
-0x3c,0x03,0x0f,0x00,0x00,0xc2,0x50,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,
-0xaf,0x8a,0x8b,0xb0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x98,
-0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x28,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x30,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,
-0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x0e,0x04,0x3c,0x03,0xb0,0x00,
-0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,
-0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xac,0xa2,0x00,0x00,0x8e,0x09,0x00,0x00,
-0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08,0x00,0x09,0xa6,0x02,0x12,0x80,0x00,0x13,
-0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02,0x3c,0x16,0x00,0xff,0x3c,0x17,0xff,0x00,
-0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x12,0x02,0x24,0x42,0x00,0x02,
-0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76,0x30,0x51,0x00,0xff,0x24,0x02,0x00,0x03,
-0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00,0x02,0x51,0x10,0x21,0x30,0x52,0xff,0xff,
-0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2,0x02,0x11,0x80,0x21,0x12,0xa0,0x00,0x0a,
-0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,0x8c,0x43,0x00,0x00,0x3c,0x04,0x0f,0x00,
-0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24,0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x04,0x98,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,
-0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04,0x24,0x15,0x00,0x01,0x8e,0x06,0x00,0x0c,
-0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2,0x30,0x48,0x00,0x03,0x00,0x09,0x14,0x02,
-0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02,0x11,0x15,0x00,0x45,0x30,0x43,0x00,0x0f,
-0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26,0x00,0x00,0x00,0x00,0x11,0x13,0x00,0x0f,
-0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02,0x30,0x84,0xff,0x00,0x3c,0x03,0x00,0xff,
-0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00,0x00,0x43,0x10,0x24,0x00,0xa4,0x28,0x25,
-0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00,0x00,0xa3,0x28,0x25,0x0c,0x00,0x01,0x94,
-0x01,0x20,0x20,0x21,0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x11,0x95,0x00,0x0f,
-0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x80,
-0x27,0x83,0x8b,0x60,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,0x08,0x00,0x03,0xce,
-0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40,0x27,0x83,0x8b,0x68,0x00,0x43,0x10,0x21,
-0x94,0x47,0x00,0x02,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,0x27,0x82,0x8b,0x60,
-0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,
-0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21,0x10,0x75,0x00,0x05,0x00,0x80,0x38,0x21,
-0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00,0x00,0x00,0x38,0x21,0x00,0x43,0x38,0x0a,
-0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e,0x3c,0x02,0xb0,0x03,0x24,0x02,0x00,0x02,
-0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,
-0x8c,0x47,0x00,0x00,0x08,0x00,0x03,0xce,0x00,0x07,0x22,0x02,0x3c,0x02,0xb0,0x03,
-0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00,0x08,0x00,0x03,0xcd,0x30,0x67,0xff,0xff,
-0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00,0x08,0x00,0x03,0xcd,0x30,0x67,0x00,0xff,
-0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00,0x11,0x95,0x00,0x07,0x00,0x44,0x38,0x21,
-0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x03,0xff,0x3c,0x02,0xb0,0x0a,
-0x08,0x00,0x04,0x04,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x04,0x08,0x3c,0x02,0xb0,0x0a,
-0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08,0x8e,0x03,0x00,0x0c,0x00,0x09,0x41,0x42,
-0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02,0x30,0x84,0xff,0x00,0x30,0xe7,0xff,0x00,
-0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00,0x00,0x03,0x56,0x02,0x00,0x03,0x2a,0x00,
-0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24,0x01,0x47,0x50,0x25,0x00,0x02,0x16,0x00,
-0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00,0x01,0x66,0x58,0x25,0x01,0x45,0x50,0x25,
-0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24,0x01,0x62,0x38,0x25,0x01,0x43,0x30,0x25,
-0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02,0x31,0x08,0x00,0x03,0x30,0x4c,0x00,0x03,
-0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02,0x00,0xe0,0x58,0x21,0x15,0x00,0x00,0x28,
-0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x06,0x00,0x80,0x28,0x21,
-0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69,0x02,0x51,0x10,0x21,0x24,0x85,0x01,0x00,
-0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15,0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x0a,
-0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,
-0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xac,0x62,0x00,0x00,
-0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,
-0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,
-0xa4,0x62,0x00,0x00,0x08,0x00,0x03,0xa7,0x02,0x51,0x10,0x21,0x3c,0x03,0xb0,0x03,
-0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,
-0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,0xa0,0x62,0x00,0x00,
-0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21,0x00,0x00,0x00,0x00,0x15,0x13,0xff,0x42,
-0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x0b,
-0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x60,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,
-0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,
-0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,0xac,0x82,0x00,0x18,0x27,0x83,0x8b,0x68,
-0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21,0x94,0x82,0x00,0x02,0x00,0x06,0x18,0x27,
-0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa6,
-0xa4,0x82,0x00,0x02,0x27,0x83,0x8b,0x60,0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x00,
-0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x5c,0x00,0xe6,0x28,0x24,0x30,0x62,0x00,0x07,
-0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f,0x00,0x44,0x10,0x21,0x11,0x93,0x00,0x07,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x49,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x52,
-0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x08,0x00,0x04,0x7f,0x00,0x43,0x18,0x21,
-0x97,0x85,0x8b,0xb4,0x3c,0x07,0xb0,0x02,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x12,0x60,0x24,0x03,0xff,0x80,
-0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07,0x97,0x82,0x8b,0xb6,0x97,0x85,0x8b,0xb4,
-0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8,0x24,0x42,0x00,0x10,0x00,0xa2,0x10,0x21,
-0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08,0x30,0x84,0x0f,0xff,0x00,0x05,0x28,0xc2,
-0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25,0x00,0x87,0x20,0x21,0x34,0xc6,0x80,0x18,
-0xac,0xc5,0x00,0x00,0xaf,0x84,0x8b,0xb0,0xa7,0x82,0x8b,0xb4,0xa7,0x80,0x8b,0xb6,
-0xaf,0x80,0x8b,0xb8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,
-0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0xe0,0x48,0x21,0x30,0xc6,0x00,0xff,
-0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07,0x00,0xa0,0x40,0x21,0x24,0x02,0x00,0x03,
-0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03,0x24,0x02,0x00,0x01,0x00,0x07,0x20,0x27,
-0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14,0x01,0x03,0x18,0x21,0x24,0x02,0x00,0x02,
-0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27,0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,
-0x08,0x00,0x04,0xe3,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,
-0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,
-0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa0,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07,0x00,0x04,0x22,0x00,0x30,0xa5,0x00,0xff,
-0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a,0x00,0xa2,0x40,0x21,0x30,0xc6,0x00,0xff,
-0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10,0x10,0xc2,0x00,0x14,0x24,0x02,0x00,0x02,
-0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09,0x00,0xe4,0x48,0x24,0x3c,0x03,0xb0,0x0a,
-0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,
-0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x0a,
-0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,
-0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00,0x91,0x02,0x00,0x00,
-0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24,0x00,0x43,0x10,0x24,0x00,0x44,0x10,0x25,
-0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00,0x30,0xa9,0x00,0xff,0x27,0x83,0x8b,0x60,
-0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01,0x00,0x07,0x50,0x27,0x00,0xc7,0x40,0x24,
-0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21,0x00,0x05,0x20,0x40,0x27,0x82,0x8b,0x60,
-0x00,0x05,0x28,0x80,0x27,0x83,0x8b,0x68,0x00,0x83,0x50,0x21,0x00,0xa2,0x20,0x21,
-0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27,0x11,0x22,0x00,0x07,0x00,0xc7,0x28,0x24,
-0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,
-0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18,0x95,0x42,0x00,0x02,0x00,0x00,0x00,0x00,
-0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa5,0x42,0x00,0x02,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x48,0x10,0x25,
-0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00,0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00,
-0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00,0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24,
-0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25,0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x44,0x10,0x25,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe8,
-0x34,0x63,0x00,0x20,0x24,0x42,0x14,0xe4,0x3c,0x04,0xb0,0x03,0xaf,0xbf,0x00,0x14,
-0xac,0x62,0x00,0x00,0xaf,0xb0,0x00,0x10,0x34,0x84,0x00,0x2c,0x8c,0x83,0x00,0x00,
-0xa7,0x80,0xbb,0xf0,0x00,0x03,0x12,0x02,0x00,0x03,0x2d,0x02,0x30,0x42,0x0f,0xff,
-0xa3,0x83,0xbb,0xf8,0xa7,0x85,0xbb,0xfc,0xa7,0x82,0xbb,0xfa,0xa7,0x80,0xbb,0xf2,
-0xa7,0x80,0xbb,0xf4,0xa7,0x80,0xbb,0xf6,0x0c,0x00,0x06,0xce,0x24,0x04,0x05,0x00,
-0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xc1,
-0x00,0x40,0x80,0x21,0x3c,0x02,0xf7,0xff,0x34,0x42,0xff,0xff,0x02,0x02,0x80,0x24,
-0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x05,0x00,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0xb0,0x03,0x34,0x42,0x01,0x08,0x34,0x63,0x01,0x18,0x8c,0x45,0x00,0x00,
-0x8c,0x64,0x00,0x00,0x3c,0x02,0x00,0x0f,0x3c,0x03,0x00,0x4c,0x30,0x84,0x02,0x00,
-0x34,0x63,0x4b,0x40,0xaf,0x85,0xbc,0x00,0x10,0x80,0x00,0x06,0x34,0x42,0x42,0x40,
-0xaf,0x83,0xbc,0x04,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0xaf,0x82,0xbc,0x04,0x08,0x00,0x05,0x69,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x34,0x63,0x00,0x20,
-0x24,0x42,0x15,0xc0,0x30,0x84,0x00,0xff,0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c,
-0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00,
-0x10,0x80,0x00,0x1c,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x08,0x00,0x00,0x00,0x00,
-0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xa7,0x80,0xbb,0xf0,
-0xa7,0x80,0xbb,0xf2,0xa7,0x80,0xbb,0xf4,0xa7,0x80,0xbb,0xf6,0x0c,0x00,0x06,0xce,
-0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,
-0x0c,0x00,0x06,0xc1,0x00,0x40,0x80,0x21,0x3c,0x05,0xf7,0xff,0x34,0xa5,0xff,0xff,
-0x02,0x05,0x28,0x24,0x0c,0x00,0x06,0xc1,0x24,0x04,0x05,0x00,0x08,0x00,0x05,0x84,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x05,0xa0,0x24,0x04,0x05,0xa4,
-0x0c,0x00,0x06,0xce,0x00,0x02,0xbc,0x02,0x24,0x04,0x05,0xa8,0x00,0x02,0xb4,0x02,
-0x0c,0x00,0x06,0xce,0x30,0x55,0xff,0xff,0x00,0x40,0x80,0x21,0x97,0x84,0xbb,0xf0,
-0x97,0x82,0xbb,0xf2,0x97,0x83,0xbb,0xf6,0x02,0xe4,0x20,0x23,0x02,0xa2,0x10,0x23,
-0x00,0x82,0x20,0x21,0x97,0x82,0xbb,0xf4,0x32,0x14,0xff,0xff,0x02,0x83,0x18,0x23,
-0x02,0xc2,0x10,0x23,0x00,0x82,0x20,0x21,0x93,0x82,0xbb,0xf8,0x00,0x83,0x20,0x21,
-0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b,0x14,0x40,0x00,0xaa,0x00,0x00,0x00,0x00,
-0x97,0x82,0xbb,0xfc,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x7f,
-0x00,0x00,0x00,0x00,0x97,0x82,0xbb,0xfa,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,
-0x10,0x40,0x00,0x3a,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x50,
-0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,0x10,0x40,0x00,0x13,
-0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x17,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,
-0x26,0x31,0x00,0x01,0x00,0x51,0x80,0x25,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,
-0x24,0x04,0x04,0x50,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x58,
-0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x60,0x02,0x00,0x28,0x21,
-0x24,0x04,0x04,0x68,0x0c,0x00,0x06,0xc1,0x00,0x00,0x00,0x00,0xa7,0x97,0xbb,0xf0,
-0xa7,0x95,0xbb,0xf2,0xa7,0x96,0xbb,0xf4,0xa7,0x94,0xbb,0xf6,0x08,0x00,0x05,0x84,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,
-0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,
-0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
-0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,
-0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,
-0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,
-0x24,0x04,0x02,0x2c,0x08,0x00,0x05,0xcb,0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xce,
-0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0xdb,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,
-0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,
-0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xce,0x00,0x02,0x9e,0x02,
-0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,
-0x14,0x60,0x00,0x1d,0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,
-0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xc1,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,
-0x08,0x00,0x05,0xd9,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,
-0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,
-0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xee,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,
-0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,
-0x08,0x00,0x06,0x15,0x3c,0x02,0xff,0xff,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,
-0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,
-0x14,0x43,0xff,0xdf,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,
-0x3c,0x03,0x00,0x80,0x08,0x00,0x06,0x2a,0x00,0x43,0x28,0x25,0x0c,0x00,0x06,0xce,
-0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,
-0x10,0x40,0xff,0x9a,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x04,0x24,0x02,0xff,0x80,
-0x02,0x02,0x10,0x24,0x08,0x00,0x05,0xcd,0x26,0x31,0x00,0x02,0x0c,0x00,0x06,0xce,
-0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,
-0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
-0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,
-0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,
-0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x44,
-0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x50,0x00,0x40,0x80,0x21,
-0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x1d,0x2e,0x22,0x00,0x21,
-0x14,0x40,0xff,0x72,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x26,0x31,0xff,0xff,
-0x00,0x51,0x80,0x25,0x24,0x04,0x04,0x50,0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,
-0x24,0x04,0x04,0x58,0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x60,
-0x0c,0x00,0x06,0xc1,0x02,0x00,0x28,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xc1,
-0x24,0x04,0x04,0x68,0x24,0x02,0x00,0x20,0x16,0x22,0xff,0x60,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,
-0x34,0x42,0x3f,0xff,0x02,0x42,0x10,0x24,0x08,0x00,0x06,0x1b,0x34,0x52,0x80,0x00,
-0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,
-0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x58,
-0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xce,0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,
-0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x20,
-0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,
-0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,
-0x0c,0x00,0x06,0xc1,0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,
-0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x68,0x2e,0x22,0x00,0x21,0x0c,0x00,0x06,0xce,
-0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,
-0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xec,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,
-0x0c,0x00,0x06,0xc1,0x24,0x04,0x02,0x08,0x08,0x00,0x06,0x98,0x3c,0x02,0xff,0xff,
-0x0c,0x00,0x06,0xce,0x24,0x04,0x02,0x08,0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,
-0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,0x14,0x43,0xff,0xdc,0x3c,0x03,0x00,0x80,
-0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x08,0x00,0x06,0xb0,
-0x00,0x43,0x28,0x25,0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23,
-0x3c,0x02,0xb0,0x0a,0x00,0x82,0x20,0x21,0xac,0x85,0x00,0x00,0x00,0x00,0x18,0x21,
-0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a,0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,
-0x03,0xe0,0x00,0x08,0x24,0x63,0xff,0xff,0x30,0x86,0x00,0x03,0x00,0x04,0x28,0x40,
-0x3c,0x03,0xb0,0x0a,0x00,0xa6,0x10,0x23,0x00,0x43,0x10,0x21,0x24,0x04,0xff,0xff,
-0xac,0x44,0x10,0x00,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x0a,
-0x14,0x40,0xff,0xfe,0x24,0x63,0x00,0x01,0x24,0x63,0xff,0xff,0x00,0xa6,0x18,0x23,
-0x3c,0x02,0xb0,0x0a,0x00,0x62,0x18,0x21,0x8c,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x1b,0x84,
-0x24,0x03,0x00,0x01,0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00,
-0x34,0xc6,0x01,0x04,0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
-0xa0,0x80,0x00,0x06,0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09,
-0xa0,0x80,0x00,0x0a,0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49,
-0x94,0xc2,0x00,0x00,0xac,0x80,0x00,0x00,0xa0,0x80,0x00,0x4e,0x00,0x02,0x14,0x00,
-0x00,0x02,0x14,0x03,0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x82,0x00,0x44,
-0xa4,0x83,0x00,0x46,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,
-0xac,0x80,0x00,0x30,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c,
-0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x40,0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03,
-0x34,0xe7,0x00,0x20,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00,
-0x24,0x42,0x1c,0x18,0xac,0xe2,0x00,0x00,0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13,
-0x00,0x05,0x2c,0x00,0x00,0x03,0x1e,0x02,0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e,
-0x00,0x62,0x18,0x21,0x00,0x65,0x18,0x21,0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05,
-0x34,0x42,0x04,0x00,0x24,0x63,0x00,0x01,0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05,
-0x34,0xa5,0x04,0x20,0xac,0xa3,0x00,0x00,0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24,
-0x35,0x08,0x02,0x28,0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00,
-0xac,0x82,0x00,0x3c,0x03,0xe0,0x00,0x08,0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xa8,
-0x00,0x07,0x60,0x80,0x27,0x82,0xb3,0xf0,0xaf,0xbe,0x00,0x50,0xaf,0xb7,0x00,0x4c,
-0xaf,0xb5,0x00,0x44,0xaf,0xb4,0x00,0x40,0xaf,0xbf,0x00,0x54,0xaf,0xb6,0x00,0x48,
-0xaf,0xb3,0x00,0x3c,0xaf,0xb2,0x00,0x38,0xaf,0xb1,0x00,0x34,0xaf,0xb0,0x00,0x30,
-0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0xe0,0x70,0x21,0x3c,0x02,0x80,0x00,
-0x94,0x73,0x00,0x14,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,0x24,0x42,0x1c,0xac,
-0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00,0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00,
-0x00,0x13,0xa8,0xc0,0x02,0xb3,0x18,0x21,0x27,0x82,0x8f,0xf4,0x00,0x03,0x18,0x80,
-0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00,0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03,
-0x00,0xc0,0xa0,0x21,0x00,0x80,0x78,0x21,0x00,0x05,0xbc,0x03,0x8c,0x68,0x00,0x18,
-0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x81,0x00,0x07,0xf6,0x03,0x00,0xde,0x10,0x07,
-0x30,0x5e,0x00,0x01,0x01,0x73,0x10,0x21,0x27,0x83,0x8f,0xf8,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x80,0x4d,0x00,0x06,0x8d,0x03,0x00,0x00,0x8d,0x02,0x00,0x04,
-0x8d,0x0a,0x00,0x08,0x8d,0x03,0x00,0x0c,0xaf,0xa2,0x00,0x20,0x11,0xa0,0x01,0x71,
-0xaf,0xa3,0x00,0x18,0x27,0x82,0xb3,0xf0,0x01,0x82,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04,
-0x14,0x60,0x00,0x12,0x00,0x00,0xb0,0x21,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46,
-0x90,0x43,0x00,0x00,0x2a,0x84,0x00,0x04,0x10,0x80,0x01,0x56,0x30,0x65,0x00,0x01,
-0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x12,0x82,0x00,0x02,0x00,0x00,0x00,0x00,
-0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,0x00,0x00,0x38,0x21,0x13,0xc0,0x00,0x03,
-0x38,0xf6,0x00,0x01,0x24,0x07,0x00,0x01,0x38,0xf6,0x00,0x01,0x01,0x73,0x10,0x21,
-0x00,0x02,0x30,0x80,0x27,0x83,0x90,0x00,0x00,0xc3,0x48,0x21,0x91,0x25,0x00,0x00,
-0x8f,0xa4,0x00,0x20,0x2c,0xa3,0x00,0x04,0x00,0x04,0x11,0xc3,0x30,0x42,0x00,0x01,
-0x00,0x03,0xb0,0x0b,0x12,0xc0,0x00,0xd8,0xaf,0xa2,0x00,0x24,0x93,0x90,0xbb,0xda,
-0x00,0x0a,0x16,0x42,0x30,0x52,0x00,0x3f,0x2e,0x06,0x00,0x0c,0x10,0xc0,0x00,0xc0,
-0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04,0x00,0x90,0x10,0x2b,
-0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x90,0x10,0x2b,0x10,0x40,0x00,0x0b,
-0x01,0x73,0x10,0x21,0x27,0x85,0xbb,0x0c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21,
-0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b,
-0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x01,0x73,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x8f,0xf8,0x00,0x43,0x10,0x21,0x31,0xa4,0x00,0x01,0x10,0x80,0x00,0xa5,
-0xa0,0x50,0x00,0x07,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01,
-0x3c,0x03,0x80,0x00,0xa1,0xe2,0x00,0x4e,0xac,0x83,0x00,0x00,0x8c,0x85,0x00,0x00,
-0x3c,0x02,0x00,0xf0,0x3c,0x03,0x40,0xf0,0x34,0x42,0xf0,0x00,0x34,0x63,0xf0,0x00,
-0x24,0x17,0x00,0x0e,0x24,0x13,0x01,0x06,0xac,0x82,0x00,0x00,0xac,0x83,0x00,0x00,
-0x27,0x82,0xb3,0xf0,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x05,0x00,0x01,
-0xaf,0xa5,0x00,0x1c,0x90,0x62,0x00,0x16,0x00,0x13,0xa8,0xc0,0x32,0x51,0x00,0x02,
-0x34,0x42,0x00,0x04,0xa0,0x62,0x00,0x16,0x8f,0xa3,0x00,0x20,0x8f,0xa4,0x00,0x18,
-0x00,0x03,0x13,0x43,0x00,0x04,0x1a,0x02,0x30,0x47,0x00,0x01,0x12,0x20,0x00,0x04,
-0x30,0x64,0x07,0xff,0x2e,0x03,0x00,0x04,0x32,0x42,0x00,0x33,0x00,0x43,0x90,0x0b,
-0x8f,0xa5,0x00,0x24,0x8f,0xa6,0x00,0x1c,0x00,0x12,0x10,0x40,0x00,0x05,0x19,0xc0,
-0x00,0x47,0x10,0x21,0x00,0x06,0x2a,0x80,0x00,0x43,0x10,0x21,0x00,0x10,0x32,0x00,
-0x00,0x04,0x24,0x80,0x02,0x65,0x28,0x21,0x00,0xa4,0x28,0x21,0x00,0x46,0x10,0x21,
-0x00,0x17,0x1c,0x00,0x3c,0x04,0xc0,0x00,0x00,0x43,0x30,0x21,0x16,0x80,0x00,0x29,
-0x00,0xa4,0x28,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x00,0x3c,0x03,0xb0,0x05,
-0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x04,0x34,0x84,0x02,0x28,
-0x24,0x02,0x00,0x01,0xac,0x65,0x00,0x00,0xa0,0x82,0x00,0x00,0x3c,0x02,0xb0,0x09,
-0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00,0x91,0xe3,0x00,0x09,0x30,0x86,0x00,0x01,
-0x02,0x83,0x18,0x26,0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21,
-0x13,0xc0,0x00,0x03,0x02,0xb3,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb3,0x10,0x21,
-0x27,0x83,0x8f,0xf8,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04,
-0x00,0xa0,0x30,0x21,0x00,0xe0,0x20,0x21,0x02,0x80,0x28,0x21,0x02,0xc0,0x38,0x21,
-0x0c,0x00,0x00,0x72,0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x02,0xbc,0x7b,0xb6,0x02,0x7c,
-0x7b,0xb4,0x02,0x3c,0x7b,0xb2,0x01,0xfc,0x7b,0xb0,0x01,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x58,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x3d,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x02,0x12,0x82,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03,
-0x12,0x82,0x00,0x25,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x82,0x00,0x19,
-0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x11,0x12,0x82,0x00,0x0d,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x12,0x16,0x82,0xff,0xd1,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05,
-0x34,0x42,0x04,0x20,0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x46,0x00,0x00,
-0x34,0x84,0x02,0x28,0xac,0x65,0x00,0x00,0x08,0x00,0x07,0xe2,0x24,0x02,0x00,0x20,
-0x34,0x42,0x04,0x40,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,
-0x34,0x63,0x04,0x44,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x07,0xe2,
-0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,
-0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80,
-0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05,
-0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28,
-0x24,0x02,0x00,0x08,0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x10,
-0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x14,
-0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x04,0x08,0x00,0x07,0xe2,0xac,0x65,0x00,0x00,
-0x34,0x42,0x04,0x08,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,
-0x34,0x63,0x04,0x0c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x07,0xe2,
-0xac,0x65,0x00,0x00,0x24,0x17,0x00,0x14,0x08,0x00,0x07,0xb4,0x24,0x13,0x01,0x02,
-0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x0c,0x00,0x90,0x18,0x2b,0x10,0x60,0x00,0x0c,
-0x26,0x02,0x00,0x04,0x27,0x85,0xbb,0x0c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21,
-0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b,
-0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x2e,0x06,0x00,0x0c,0x26,0x02,0x00,0x04,
-0x08,0x00,0x07,0x9e,0x00,0x46,0x80,0x0a,0x27,0x82,0xb3,0xf0,0x01,0x82,0x20,0x21,
-0x8c,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xe2,0x00,0x19,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x10,0x00,0xc2,0x10,0x21,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x14,0x00,0x00,0x00,0x00,
-0x90,0xe3,0x00,0x16,0x27,0x82,0x8f,0xf8,0x00,0xc2,0x10,0x21,0x34,0x63,0x00,0x20,
-0x90,0x50,0x00,0x07,0xa0,0xe3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x1e,0x42,
-0x24,0x06,0x00,0x01,0x90,0x82,0x00,0x16,0x30,0x71,0x00,0x02,0x30,0x72,0x00,0x3f,
-0x30,0x42,0x00,0xfb,0x24,0x17,0x00,0x18,0x24,0x13,0x01,0x03,0x24,0x15,0x08,0x18,
-0xaf,0xa6,0x00,0x1c,0x08,0x00,0x07,0xbe,0xa0,0x82,0x00,0x16,0x8d,0x02,0x00,0x04,
-0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10,0x14,0x40,0x00,0x15,0x30,0x72,0x00,0x3f,
-0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x11,0x30,0x72,0x00,0x3e,
-0x27,0x83,0x90,0x08,0x00,0xc3,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x68,
-0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x05,0x90,0x43,0x00,0x04,
-0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24,0x30,0x63,0x00,0x01,0x02,0x43,0x90,0x25,
-0x27,0x85,0xb3,0xf0,0x01,0x85,0x28,0x21,0x8c,0xa6,0x00,0x00,0x01,0x73,0x10,0x21,
-0x27,0x83,0x90,0x00,0x90,0xc4,0x00,0x16,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x30,0x84,0x00,0xdf,0x90,0x50,0x00,0x00,0xa0,0xc4,0x00,0x16,0x80,0xc6,0x00,0x12,
-0x8c,0xa3,0x00,0x00,0x2d,0xc4,0x00,0x02,0xaf,0xa6,0x00,0x1c,0x90,0x62,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfb,0x14,0x80,0x00,0x06,0xa0,0x62,0x00,0x16,
-0x24,0x02,0x00,0x06,0x11,0xc2,0x00,0x03,0x24,0x02,0x00,0x04,0x15,0xc2,0xff,0x0e,
-0x32,0x51,0x00,0x02,0x32,0x51,0x00,0x02,0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x0f,
-0x00,0x11,0x18,0x2b,0x32,0x02,0x00,0x0f,0x34,0x42,0x00,0x10,0x00,0x03,0x19,0x00,
-0x00,0x43,0x18,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xb8,0xa0,0x43,0x00,0x00,
-0x00,0x00,0x20,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x02,0x05,0xaf,0xaf,0x00,0x28,
-0x8f,0xaf,0x00,0x28,0x08,0x00,0x07,0xbe,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xb9,
-0x32,0x03,0x00,0xff,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xaa,0x00,0x00,0x00,0x00,
-0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x82,0x10,0x26,0x08,0x00,0x07,0x75,
-0x00,0x02,0x28,0x0b,0x08,0x00,0x07,0x7b,0x00,0x00,0xb0,0x21,0x24,0x02,0x00,0x10,
-0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0x7d,0x00,0x07,0x17,0x83,
-0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0x7b,0x00,0x07,0x17,0x43,0x08,0x00,0x07,0x55,
-0x30,0x5e,0x00,0x01,0x08,0x00,0x07,0x55,0x00,0x07,0xf7,0xc2,0x00,0x04,0x10,0x40,
-0x27,0x83,0x80,0x1c,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21,0x94,0x44,0x00,0x00,
-0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a,0x00,0x86,0x00,0x18,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x23,0x7c,
-0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12,0x00,0x04,0x22,0x42,
-0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b,0x24,0x82,0x00,0x60,
-0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x00,0x44,0x20,0x04,
-0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28,0x24,0x83,0x00,0x24,
-0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14,0x00,0x60,0x20,0x21,
-0x08,0x00,0x08,0xf6,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x24,0x18,0x00,0x80,0x80,0x21,
-0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37,0x34,0x84,0x01,0x10,
-0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21,0x8c,0x87,0x00,0x00,
-0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f,0x34,0x42,0xf0,0x00,
-0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08,0x32,0x02,0x00,0x07,
-0x27,0x83,0x80,0xcc,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,
-0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21,0x32,0x02,0x00,0x0f,
-0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x07,
-0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xb4,0x40,0x00,0x43,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c,0x14,0x40,0x00,0x05,
-0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21,
-0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20,0x24,0x06,0x00,0x0e,
-0x0c,0x00,0x08,0xdf,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04,0x24,0x02,0x00,0x10,
-0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01,0x14,0x60,0x00,0x02,
-0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff,0x00,0xc5,0x10,0x21,
-0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00,0x8f,0xbf,0x00,0x1c,
-0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c,0x32,0x02,0x00,0x07,
-0x27,0x83,0x80,0xc4,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x08,0x00,0x09,0x24,
-0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80,0x27,0x82,0xb3,0xf0,
-0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb3,0x00,0x2c,0xaf,0xbf,0x00,0x44,
-0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xb2,0x00,0x28,
-0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21,0x8c,0xe6,0x00,0x00,
-0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x25,0x74,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0xa0,0xc3,0x00,0x12,
-0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16,0xa4,0xc3,0x00,0x14,
-0x27,0x83,0x8f,0xf0,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16,0x8c,0xe8,0x00,0x00,
-0xaf,0xa4,0x00,0x48,0x27,0x82,0x8f,0xf4,0x95,0x11,0x00,0x14,0x00,0x00,0x00,0x00,
-0x00,0x11,0x98,0xc0,0x02,0x71,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x82,0x10,0x21,
-0x8c,0x52,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06,0x8e,0x45,0x00,0x08,
-0x8e,0x46,0x00,0x04,0x8e,0x47,0x00,0x04,0x00,0x05,0x1c,0x82,0x00,0x06,0x31,0x42,
-0x27,0x82,0x90,0x00,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01,0x00,0x82,0x20,0x21,
-0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18,0xaf,0xa6,0x00,0x1c,
-0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06,0x14,0xe0,0x00,0x47,
-0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x44,
-0x02,0x71,0x10,0x21,0x93,0x90,0xbb,0xd9,0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c,
-0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40,0x00,0x43,0x10,0x21,
-0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04,0x02,0x71,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x00,0x80,0x80,0x21,
-0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,
-0x0c,0x00,0x08,0xdf,0x02,0xa0,0x30,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x88,0x80,
-0x00,0x40,0xa0,0x21,0x27,0x82,0x90,0x10,0x02,0x22,0x10,0x21,0x8c,0x44,0x00,0x00,
-0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x04,0x25,0xc2,
-0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40,0x03,0xc4,0x20,0x24,
-0x14,0x80,0x00,0x15,0x02,0x43,0x38,0x21,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x28,
-0x8d,0x03,0x00,0x00,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48,0x27,0x82,0x8f,0xf8,
-0x02,0x22,0x10,0x21,0x24,0x63,0x00,0x01,0x02,0xa0,0x28,0x21,0xa4,0x54,0x00,0x04,
-0x00,0xc0,0x38,0x21,0x0c,0x00,0x07,0x2b,0xad,0x03,0x00,0x00,0x7b,0xbe,0x02,0x3c,
-0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c,0x8f,0xa6,0x00,0x18,
-0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0x06,
-0xaf,0xa0,0x00,0x14,0x08,0x00,0x09,0xc2,0x02,0x82,0xa0,0x21,0x02,0x71,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,
-0x08,0x00,0x09,0xae,0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8,0xaf,0xb1,0x00,0x24,
-0x8f,0xb1,0x00,0x5c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x27,0x98,0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38,
-0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c,0x8f,0xb5,0x00,0x58,
-0xaf,0xbf,0x00,0x44,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20,
-0x00,0xe0,0xb0,0x21,0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21,0x00,0x00,0xb8,0x21,
-0x16,0x20,0x00,0x2b,0x00,0x00,0xa0,0x21,0x27,0x85,0xb3,0xf0,0x00,0x07,0x10,0x80,
-0x00,0x45,0x10,0x21,0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80,0x00,0x65,0x18,0x21,
-0x92,0x62,0x00,0x16,0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x2d,
-0x00,0x00,0x00,0x00,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03,
-0x14,0x40,0x00,0x28,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x18,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x14,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x0f,0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05,0x34,0x63,0x01,0x44,
-0x34,0xa5,0x02,0x52,0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00,0x8f,0xa3,0x00,0x4c,
-0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x04,
-0x30,0xc6,0xff,0xff,0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09,0x24,0x05,0x00,0x14,
-0x02,0x20,0x10,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,
-0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,
-0x0c,0x00,0x07,0x06,0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x28,
-0xa3,0xc2,0x00,0x11,0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x17,
-0x00,0xc0,0x88,0x21,0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21,0x12,0x20,0xff,0xed,
-0x02,0x20,0x10,0x21,0x27,0x83,0xb3,0xf0,0x00,0x17,0x10,0x80,0x00,0x43,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28,0x80,0x86,0x00,0x12,
-0x8c,0x62,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03,0x00,0x46,0x10,0x21,
-0x8f,0xa6,0x00,0x4c,0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21,0x0c,0x00,0x07,0x2b,
-0xac,0x62,0x00,0x00,0x08,0x00,0x0a,0x28,0xaf,0xd1,0x00,0x40,0x96,0x74,0x00,0x1a,
-0x08,0x00,0x0a,0x3b,0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,
-0x8c,0x50,0x00,0x00,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x11,0x02,0x00,0x28,0x21,
-0x30,0x42,0x00,0xff,0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x11,
-0xaf,0xa2,0x00,0x18,0x8f,0xa4,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0xed,
-0x30,0x50,0x00,0xff,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01,0x96,0x63,0x00,0x14,
-0x96,0x44,0x00,0x14,0x27,0x85,0x8f,0xf0,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0,0x8c,0x46,0x00,0x08,
-0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x00,0x06,0x17,0x02,
-0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xd6,0x00,0x03,0x17,0x02,
-0x10,0x44,0x00,0xd5,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b,0x24,0x11,0x00,0x02,
-0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x5a,
-0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbd,0x00,0x00,0x00,0x00,0x96,0x49,0x00,0x14,
-0x27,0x82,0x8f,0xf4,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0,0x01,0x49,0x18,0x21,
-0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42,
-0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x14,0x40,0x00,0x41,
-0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x08,0x01,0x02,0x10,0x21,0x80,0x44,0x00,0x00,
-0x27,0x82,0xb5,0x68,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,
-0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,
-0x27,0x84,0xb4,0x90,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2b,
-0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,
-0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xb9,
-0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,
-0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,
-0x27,0x83,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,
-0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x0b,
-0x24,0x02,0x00,0x01,0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x8d,
-0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,
-0x02,0x02,0x10,0x25,0x08,0x00,0x0a,0x3b,0xa2,0x42,0x00,0x16,0x00,0x60,0x28,0x21,
-0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x3e,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0a,0xbe,
-0x30,0x54,0xff,0xff,0x08,0x00,0x0a,0xa6,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd,
-0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0a,0xa6,
-0x24,0x42,0x00,0x04,0x27,0x82,0x90,0x00,0x01,0x02,0x10,0x21,0x90,0x43,0x00,0x00,
-0x08,0x00,0x0a,0xb6,0xa0,0x43,0x00,0x03,0x96,0x69,0x00,0x14,0x02,0xc0,0xb8,0x21,
-0x24,0x0b,0x00,0x01,0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21,0x00,0x03,0x40,0x80,
-0x00,0x40,0x50,0x21,0x27,0x82,0x8f,0xf4,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,
-0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,
-0x10,0x40,0x00,0x0d,0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x08,0x01,0x02,0x10,0x21,
-0x80,0x43,0x00,0x00,0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00,0x00,0x43,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb5,0x60,
-0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x4f,0x00,0x00,0x00,0x00,
-0x01,0x49,0x10,0x21,0x00,0x02,0x20,0x80,0x27,0x85,0x90,0x00,0x00,0x85,0x10,0x21,
-0x80,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x42,0x01,0x49,0x10,0x21,
-0x27,0x82,0x90,0x08,0x00,0x82,0x10,0x21,0x80,0x44,0x00,0x00,0x27,0x82,0xb5,0x68,
-0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x23,
-0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,0x27,0x84,0xb4,0x90,
-0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2c,0x2c,0x64,0x00,0x0c,
-0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,
-0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xb9,0x14,0x80,0x00,0x06,
-0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,
-0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,0x27,0x83,0x90,0x00,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,0xa0,0x45,0x00,0x03,
-0xa0,0x45,0x00,0x00,0x8f,0xa4,0x00,0x18,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x0c,
-0x00,0x60,0x28,0x21,0x24,0x02,0x00,0x01,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x8d,
-0xaf,0xa2,0x00,0x10,0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff,0x92,0x62,0x00,0x16,
-0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x25,0x08,0x00,0x0a,0x3b,0xa2,0x62,0x00,0x16,
-0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x3e,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0b,0x2d,
-0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0x15,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd,
-0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0b,0x15,
-0x24,0x42,0x00,0x04,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x90,0x43,0x00,0x00,
-0x08,0x00,0x0b,0x25,0xa0,0x43,0x00,0x03,0x27,0x85,0x90,0x00,0x08,0x00,0x0b,0x41,
-0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,0x00,0x62,0x18,0x26,0x08,0x00,0x0a,0x76,
-0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x2d,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x7b,
-0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,
-0x24,0x42,0x2d,0x44,0x34,0x63,0x00,0x20,0x3c,0x05,0xb0,0x05,0xaf,0xb3,0x00,0x24,
-0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x28,0xaf,0xb0,0x00,0x18,
-0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,0x90,0xa2,0x00,0x00,0x00,0x80,0x90,0x21,
-0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,0x24,0x02,0x00,0x10,0x12,0x22,0x00,0xcf,
-0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,0x12,0x22,0x00,0xc1,0x24,0x02,0x00,0x12,
-0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0xad,0xae,0x43,0x00,0x40,
-0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x44,0x00,0x00,0x3c,0x03,0x00,0x02,
-0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,0x00,0x10,0x14,0x43,0x10,0x40,0x00,0x05,
-0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x92,
-0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,
-0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,0x00,0x10,0x11,0xc3,0x14,0x40,0x00,0x86,
-0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,0x02,0x00,0x10,0x21,0x26,0x22,0x00,0x01,
-0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,0x14,0x60,0xff,0xdb,0x24,0x03,0x00,0x02,
-0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,0x2a,0x62,0x00,0x03,0x10,0x40,0x00,0x58,
-0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x4b,0x02,0x40,0x20,0x21,
-0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x28,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
-0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x02,0x40,0x20,0x21,
-0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xec,0x02,0x00,0x10,0x21,
-0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x24,0x02,0x00,0x05,0x02,0x40,0x20,0x21,
-0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xdc,0x02,0x00,0x10,0x21,
-0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x24,0x02,0x00,0x03,0x02,0x40,0x20,0x21,
-0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xcc,0x02,0x00,0x10,0x21,
-0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,0x24,0x02,0x00,0x02,0x02,0x40,0x20,0x21,
-0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,
-0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c,
-0x08,0x00,0x0b,0x97,0x30,0x42,0x00,0xff,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,
-0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,
-0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x24,
-0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x08,0x16,0x62,0xff,0xa8,
-0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,0x8e,0x42,0x00,0x30,0x24,0x05,0x00,0x03,
-0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,0x0c,0x00,0x09,0xe6,0xaf,0xa2,0x00,0x14,
-0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x30,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,
-0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,
-0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x2c,
-0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01,
-0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xe6,0xaf,0xa3,0x00,0x14,
-0x08,0x00,0x0b,0x90,0xae,0x42,0x00,0x28,0x0c,0x00,0x01,0x59,0x24,0x04,0x00,0x01,
-0x08,0x00,0x0b,0x81,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x30,0xae,0x40,0x00,0x34,
-0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x61,
-0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0xff,0x69,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x01,0x59,0x00,0x00,0x20,0x21,0x08,0x00,0x0b,0x79,0x00,0x00,0x00,0x00,
-0x02,0x40,0x20,0x21,0x0c,0x00,0x09,0x5d,0x02,0x20,0x28,0x21,0x08,0x00,0x0b,0x6d,
-0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x4a,
-0x00,0x00,0x00,0x00,0x8f,0x82,0xb4,0x38,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x3c,
-0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3d,0x24,0x02,0x00,0x12,
-0x8f,0x82,0xb4,0x34,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,
-0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x38,0x8e,0x42,0x00,0x34,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,0x24,0x02,0x00,0x11,0x8f,0x82,0xb4,0x30,
-0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,
-0x08,0x00,0x0b,0x6a,0xae,0x43,0x00,0x34,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,0x24,0x42,0x30,0xf8,0x3c,0x08,0xb0,0x03,
-0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,0x35,0x08,0x01,0x00,0xaf,0xbf,0x00,0x18,
-0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,0x00,0xa0,0x48,0x21,0x24,0x11,0x00,0x0a,
-0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,0x00,0x45,0x88,0x0a,0x30,0x63,0x00,0x01,
-0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,0x00,0x11,0x40,0x40,0x02,0x20,0x40,0x21,
-0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,0x01,0x20,0x20,0x21,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf8,0x00,0x43,0x10,0x21,
-0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,0x10,0xe0,0x00,0x06,0x02,0x23,0x80,0x21,
-0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x0c,0x00,0x08,0xdf,0x00,0x00,0x00,0x00,0x02,0x11,0x18,0x21,
-0x08,0x00,0x0c,0x60,0x00,0x62,0x80,0x21,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,
-0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb5,0x00,0x24,
-0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x84,0x82,0x00,0x0c,0x3c,0x06,0xb0,0x03,
-0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,
-0x27,0x82,0x8f,0xf4,0x00,0x62,0x10,0x21,0x8c,0x55,0x00,0x18,0x3c,0x02,0x80,0x00,
-0x24,0x42,0x31,0xa8,0xac,0xc2,0x00,0x00,0x8e,0xb0,0x00,0x08,0x27,0x82,0x8f,0xf8,
-0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,0x00,0x10,0x86,0x43,0x32,0x10,0x00,0x01,
-0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,0x00,0xa0,0x98,0x21,0x02,0x20,0x28,0x21,
-0x0c,0x00,0x0c,0x3e,0x00,0x80,0x90,0x21,0x02,0x20,0x20,0x21,0x02,0x00,0x28,0x21,
-0x24,0x06,0x00,0x14,0x0c,0x00,0x08,0xdf,0x00,0x40,0xa0,0x21,0x86,0x43,0x00,0x0c,
-0x3c,0x09,0xb0,0x09,0x3c,0x08,0xb0,0x09,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x80,0x43,0x00,0x06,
-0x3c,0x07,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x28,0x62,0x00,0x00,0x24,0x64,0x00,0x03,
-0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x3c,0x02,0xb0,0x09,0x00,0x03,0x18,0x80,
-0x34,0x42,0x01,0x02,0x35,0x29,0x01,0x10,0x35,0x08,0x01,0x14,0x34,0xe7,0x01,0x20,
-0x34,0xa5,0x01,0x24,0xa4,0x54,0x00,0x00,0x12,0x60,0x00,0x11,0x02,0xa3,0xa8,0x21,
-0x8e,0xa2,0x00,0x0c,0x8e,0xa3,0x00,0x08,0x00,0x02,0x14,0x00,0x00,0x03,0x1c,0x02,
-0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8e,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x1c,0x02,0xa5,0x03,0x00,0x00,0x8f,0xbf,0x00,0x28,0x7b,0xb4,0x01,0x3c,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
-0x8e,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x22,0x00,0x00,0x8e,0xa4,0x00,0x08,
-0x00,0x00,0x00,0x00,0xa5,0x04,0x00,0x00,0x7a,0xa2,0x00,0x7c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21,0xac,0xe3,0x00,0x00,
-0x8e,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02,0x08,0x00,0x0c,0xb2,
-0xa4,0xa2,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c,0x00,0x80,0x90,0x21,
-0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,
-0x27,0x82,0x8f,0xf4,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18,0x3c,0x02,0x80,0x00,
-0x34,0xa5,0x00,0x20,0x24,0x42,0x33,0x24,0x27,0x83,0x8f,0xf8,0xac,0xa2,0x00,0x00,
-0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07,0x34,0x42,0x01,0x00,
-0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04,0x24,0x02,0x00,0x10,
-0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43,0x30,0x84,0x00,0x01,
-0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40,0x02,0x00,0x10,0x21,
-0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x08,0xdf,0x30,0x50,0x00,0xff,
-0x86,0x44,0x00,0x0c,0x27,0x85,0x90,0x00,0x3c,0x06,0xb0,0x09,0x00,0x04,0x18,0xc0,
-0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x80,0x64,0x00,0x06,
-0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03,0x28,0x83,0x00,0x00,
-0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80,0xa4,0xc2,0x00,0x00,
-0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x10,
-0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x14,
-0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08,0x3c,0x06,0xb0,0x09,
-0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21,0x34,0xc6,0x01,0x20,
-0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x24,
-0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a,0x3c,0x03,0xb0,0x09,
-0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,
-0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x90,0x08,0x8f,0xbf,0x00,0x1c,
-0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x3c,0x05,0xb0,0x09,
-0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0xaf,0xb0,0x00,0x10,
-0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x34,0xb0,0x00,0x05,0x2c,0x43,
-0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x10,0xa0,0x00,0x05,
-0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0xb6,
-0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x4c,0x00,0x00,0x10,0x21,
-0x24,0x02,0x00,0x08,0x12,0x02,0x00,0xa3,0x2a,0x02,0x00,0x09,0x10,0x40,0x00,0x89,
-0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x79,0x2a,0x02,0x00,0x03,
-0x10,0x40,0x00,0x69,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x02,0x00,0x5a,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x3c,0x03,0x80,0x00,
-0xa2,0x20,0x00,0x4e,0xac,0x43,0x00,0x00,0x82,0x24,0x00,0x11,0x92,0x27,0x00,0x11,
-0x10,0x80,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12,
-0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xb3,0xf0,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14,
-0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10,
-0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xb3,0xf0,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12,
-0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01,
-0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12,
-0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c,
-0x27,0x84,0x90,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00,
-0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04,
-0xa2,0x20,0x00,0x15,0xa3,0x80,0x8b,0xc4,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x0c,0xc9,
-0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x0d,0x79,0x00,0x07,0x16,0x00,
-0x0c,0x00,0x0c,0x6a,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x8f,0xf8,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21,
-0x90,0x85,0x00,0x07,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13,
-0x90,0x83,0x00,0x07,0x08,0x00,0x0d,0x91,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a,
-0x08,0x00,0x0d,0x5a,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00,
-0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a,
-0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x04,
-0x08,0x00,0x0d,0xab,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9b,0x3c,0x02,0xb0,0x05,
-0x8e,0x23,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08,
-0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c,
-0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x06,0x08,0x00,0x0d,0xba,0xa2,0x20,0x00,0x0a,
-0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07,
-0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b,
-0xae,0x20,0x00,0x28,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x05,0x08,0x00,0x0d,0xc6,
-0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x12,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x09,
-0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7b,0x3c,0x02,0xb0,0x05,
-0x24,0x02,0x00,0x12,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d,
-0xae,0x20,0x00,0x3c,0x16,0x02,0xff,0x74,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,
-0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d,0xae,0x20,0x00,0x34,
-0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x4d,
-0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30,0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01,
-0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08,0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a,
-0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30,0x08,0x00,0x0d,0x4d,0xa2,0x22,0x00,0x07,
-0x08,0x00,0x0d,0xec,0xa2,0x24,0x00,0x0a,0x8f,0x84,0xb4,0x30,0xae,0x20,0x00,0x34,
-0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x32,0x10,0x00,0xff,0x08,0x00,0x0d,0x3e,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x37,0xe4,
-0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05,
-0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54,0x83,0x83,0x8b,0xc4,0x00,0x00,0x00,0x00,
-0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,
-0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c,
-0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50,0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01,
-0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,
-0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,
-0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08,
-0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8,
-0x34,0x63,0x00,0x20,0x24,0x42,0x38,0x74,0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c,
-0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18,0x90,0xa6,0x00,0x0a,0x27,0x83,0xb3,0xf0,
-0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,
-0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12,0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15,
-0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xda,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12,
-0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,
-0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf,
-0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,
-0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45,
-0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04,0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00,
-0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01,0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17,
-0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03,
-0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05,
-0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,
-0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08,
-0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14,
-0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x96,0x02,0x00,0x00,0x08,0x00,0x0e,0x68,0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x54,
-0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x8f,0xf0,
-0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,
-0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,
-0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24,
-0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,
-0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x54,
-0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x88,
-0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,
-0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x4e,
-0xa2,0x20,0x00,0x07,0x08,0x00,0x0e,0x4e,0xa2,0x20,0x00,0x06,0x08,0x00,0x0e,0x4e,
-0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x69,
-0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x49,0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3b,
-0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,
-0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c,0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,0x27,0x83,0x8f,0xf4,0x00,0xa3,0x18,0x21,
-0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18,0x24,0x07,0x00,0x01,0x93,0x82,0x8b,0x61,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24,
-0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x84,0x02,0x00,0x20,0x21,
-0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12,0x30,0x42,0x00,0xe7,0x08,0x00,0x0e,0x45,
-0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06,0x00,0x00,0x28,0x12,0x27,0x82,0x8f,0xf0,
-0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x4b,0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c,
-0x08,0x00,0x0e,0xc5,0x00,0x06,0x2c,0x00,0x27,0x83,0x90,0x00,0x27,0x82,0x90,0x08,
-0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05,
-0x93,0x82,0x80,0x10,0x00,0x00,0x30,0x21,0x0c,0x00,0x21,0xf5,0xaf,0xa2,0x00,0x10,
-0x96,0x26,0x00,0x0c,0x08,0x00,0x0e,0xbf,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xcd,
-0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,
-0x24,0x02,0x00,0x80,0x08,0x00,0x0e,0xae,0x00,0xa2,0x10,0x07,0x86,0x26,0x00,0x0c,
-0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72,0x34,0x63,0x01,0x78,0x94,0x47,0x00,0x00,
-0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0,0x00,0x46,0x10,0x21,0x3c,0x04,0xb0,0x09,
-0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c,0x27,0x83,0x8f,0xf4,0x00,0x02,0x10,0x80,
-0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21,0x8c,0x43,0x00,0x18,0xae,0x25,0x00,0x20,
-0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08,0x02,0x20,0x20,0x21,0x0c,0x00,0x0f,0x15,
-0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18,0x8e,0x26,0x00,0x1c,0x8e,0x27,0x00,0x20,
-0x02,0x20,0x20,0x21,0x0c,0x00,0x1c,0x86,0xaf,0xa2,0x00,0x10,0x08,0x00,0x0e,0x45,
-0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08,0x08,0x00,0x0e,0x45,0xa2,0x22,0x00,0x09,
-0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xac,0x40,0x00,0x00,0x08,0x00,0x0e,0x45,
-0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c,0x24,0x03,0x00,0x24,0x00,0x80,0x70,0x21,
-0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x24,0x42,0x3c,0x54,0xf1,0x43,0x00,0x06,
-0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12,0x00,0xa0,0x68,0x21,0xac,0x82,0x00,0x00,
-0x27,0x85,0x90,0x00,0x27,0x82,0x8f,0xff,0x27,0xbd,0xff,0xf8,0x00,0x62,0x60,0x21,
-0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21,0x11,0xa0,0x00,0xcc,0x00,0x00,0x78,0x21,
-0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x91,0x87,0x00,0x00,0x80,0x48,0x00,0x04,
-0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80,0x27,0x83,0x8f,0xf4,0xa3,0xa7,0x00,0x00,
-0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18,0x25,0x02,0xff,0xff,0x00,0x48,0x40,0x0b,
-0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07,0x24,0x02,0x00,0x06,0x30,0x63,0x00,0x08,
-0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a,0x93,0xa7,0x00,0x00,0x27,0x82,0x90,0x08,
-0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0,0x38,0x63,0x00,0x50,0x30,0xe5,0x00,0xff,
-0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b,0x00,0x64,0x18,0x24,0x90,0x49,0x00,0x00,
-0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f,0x24,0x02,0x00,0x04,0x10,0xa2,0x00,0x9d,
-0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a,0x2c,0xa2,0x00,0x0c,0x10,0x40,0x00,0x02,
-0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21,0x30,0x84,0x00,0xff,0x00,0x04,0x10,0x40,
-0x27,0x83,0xbb,0x0c,0x00,0x44,0x10,0x21,0x00,0x43,0x10,0x21,0x90,0x47,0x00,0x00,
-0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c,0xa3,0xa7,0x00,0x00,0x10,0x60,0x00,0x02,
-0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21,0xa3,0xa2,0x00,0x00,0x91,0x65,0x00,0x00,
-0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff,0x00,0x62,0x10,0x2b,0x10,0x40,0x00,0x0e,
-0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0x60,0x20,0x21,0x30,0xa2,0x00,0x0f,
-0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40,0x00,0x44,0x20,0x21,0x27,0x83,0xbb,0x0c,
-0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,
-0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00,0x93,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x27,0x83,0xb4,0x98,0x00,0x43,0x10,0x21,
-0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x83,0x00,0x0c,0x14,0x60,0x00,0x06,
-0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,
-0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x08,0x00,0x0f,0x76,0xa1,0x82,0x00,0x00,
-0x8f,0x8d,0x81,0x5c,0x00,0x00,0x00,0x00,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1,0x00,0x00,0x28,0x21,0x00,0x06,0x74,0x82,
-0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0xe0,0x10,0x21,
-0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c,0x30,0x44,0x00,0xff,0xa3,0xa2,0x00,0x00,
-0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40,0x00,0x49,0x10,0x23,0x00,0x64,0x18,0x21,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x27,0x84,0xb4,0x98,0x00,0x44,0x10,0x21,
-0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x00,0x00,0x0a,0x1c,0x00,
-0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,
-0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x33,
-0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,
-0x00,0x49,0x10,0x23,0x27,0x83,0xb5,0x68,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x64,0xc0,0x24,
-0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe2,0x00,0x0f,0x10,0x40,0x00,0x0f,
-0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x8f,0xf0,0x00,0x44,0x10,0x21,
-0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0x28,0x63,0x06,0x41,0x14,0x60,0x00,0x04,
-0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f,0xa3,0xa7,0x00,0x00,0x30,0xe2,0x00,0xff,
-0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06,0x00,0xe0,0x10,0x21,0x00,0x18,0x10,0x40,
-0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x47,0x10,0x21,0x24,0x42,0x00,0x04,
-0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00,
-0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff,0x00,0xa3,0x18,0x2b,0x14,0x60,0xff,0xad,
-0x30,0xe2,0x00,0xff,0x08,0x00,0x0f,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0xc4,
-0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x73,
-0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0x51,0x00,0x00,0x00,0x00,0x00,0x0a,0x1c,0x00,
-0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05,0x91,0x67,0x00,0x00,0x08,0x00,0x0f,0x31,
-0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x3f,0xf4,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,
-0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,
-0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38,
-0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x84,0x82,0x00,0x0c,0x27,0x93,0x8f,0xf4,
-0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80,
-0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18,0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x40,0x0c,0xac,0xa2,0x00,0x00,0x8f,0xd0,0x00,0x08,0x27,0x95,0x90,0x00,
-0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21,0x02,0x00,0x30,0x21,0x90,0x71,0x00,0x00,
-0x0c,0x00,0x0f,0x15,0x00,0x80,0xb0,0x21,0x00,0x40,0x90,0x21,0x00,0x10,0x14,0x42,
-0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21,0x00,0x10,0x14,0x82,0x02,0x80,0x28,0x21,
-0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2,0x86,0xc3,0x00,0x0c,0x30,0x50,0x00,0x01,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,
-0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x30,0x21,0x8c,0xc7,0x00,0x18,
-0x27,0x83,0x8f,0xf0,0x00,0x43,0x10,0x21,0x8c,0xe3,0x00,0x04,0x84,0x46,0x00,0x06,
-0x00,0x03,0x19,0x42,0x0c,0x00,0x08,0xdf,0x30,0x73,0x00,0x01,0x00,0x40,0x88,0x21,
-0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21,0x16,0xe0,0x00,0x10,0x02,0x00,0x30,0x21,
-0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,
-0x00,0x03,0x18,0x80,0x27,0x82,0x8f,0xf8,0x00,0x62,0x18,0x21,0xa4,0x71,0x00,0x04,
-0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,
-0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x86,0xc3,0x00,0x0c,
-0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0x80,0x47,0x00,0x06,0x00,0x00,0x00,0x00,
-0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2,0x00,0xe2,0x38,0x21,0x00,0x07,0x38,0x43,
-0x00,0x07,0x38,0x40,0x0c,0x00,0x09,0x06,0x03,0xc7,0x38,0x21,0x08,0x00,0x10,0x44,
-0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0,
-0x34,0x63,0x00,0x20,0x24,0x42,0x41,0x94,0xaf,0xb2,0x00,0x20,0xac,0x62,0x00,0x00,
-0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,
-0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a,0x34,0x42,0x01,0x04,0x94,0x45,0x00,0x00,
-0x00,0x03,0x18,0x80,0x27,0x82,0xb3,0xf0,0x00,0x62,0x18,0x21,0x30,0xa6,0xff,0xff,
-0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12,0x30,0xc9,0x00,0xff,0x00,0x06,0x32,0x02,
-0xa4,0x86,0x00,0x44,0xa4,0x89,0x00,0x46,0x82,0x22,0x00,0x12,0x00,0x80,0x90,0x21,
-0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15,0x00,0xc5,0x10,0x2a,0x10,0x40,0x00,0x14,
-0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,
-0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x80,0x00,0x12,0x92,0x22,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x28,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,
-0x0c,0x00,0x0f,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x93,0x00,0x00,0x00,0x00,
-0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x76,0x00,0x00,0x28,0x21,0x94,0x87,0x00,0x0c,
-0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0x21,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03,
-0x00,0x07,0x24,0x00,0x00,0x04,0x24,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,
-0x00,0x04,0x28,0xc0,0x00,0xa4,0x28,0x21,0x27,0x82,0x90,0x10,0x00,0x03,0x18,0x80,
-0x00,0x62,0x18,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf8,0x00,0xa2,0x10,0x21,
-0x8c,0x68,0x00,0x00,0x80,0x44,0x00,0x06,0x27,0x82,0x90,0x00,0x00,0x08,0x1d,0x02,
-0x00,0xa2,0x28,0x21,0x38,0x84,0x00,0x00,0x30,0x63,0x00,0x01,0x01,0x24,0x30,0x0b,
-0x80,0xaa,0x00,0x04,0x80,0xa9,0x00,0x05,0x10,0x60,0x00,0x02,0x00,0x08,0x14,0x02,
-0x30,0x46,0x00,0x0f,0x15,0x20,0x00,0x28,0x01,0x49,0x10,0x21,0x15,0x40,0x00,0x11,
-0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff,
-0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x46,0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04,
-0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00,0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00,
-0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x27,0x84,0x90,0x00,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,
-0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21,0x00,0x64,0x20,0x21,0x94,0x82,0x00,0x00,
-0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00,0x14,0x60,0x00,0x06,0x00,0x02,0x3c,0x03,
-0x30,0xe2,0x00,0x04,0x14,0x40,0x00,0x04,0x01,0x49,0x10,0x21,0x34,0xe2,0x08,0x00,
-0xa4,0x82,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03,
-0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c,
-0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16,
-0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb,0x08,0x00,0x10,0x98,0xa2,0x23,0x00,0x16,
-0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05,
-0x86,0x45,0x00,0x0c,0x0c,0x00,0x1f,0x08,0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a,
-0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,
-0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,
-0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01,
-0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c,
-0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x08,0x00,0x10,0x93,
-0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00,0x08,0x00,0x10,0x93,0xa6,0x22,0x00,0x14,
-0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
-0x08,0x00,0x11,0x22,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,
-0x27,0x86,0x8f,0xf0,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,
-0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,
-0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,
-0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,
-0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,
-0x08,0x00,0x11,0x22,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,
-0x08,0x00,0x11,0x45,0x00,0x00,0x00,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,
-0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00,
-0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x07,0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x06,
-0x08,0x00,0x11,0x1d,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05,
-0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,
-0x08,0x00,0x11,0x14,0x00,0xa2,0x10,0x07,0x0c,0x00,0x10,0x03,0x02,0x40,0x20,0x21,
-0x08,0x00,0x10,0x93,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,
-0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x99,0x2c,0xc2,0x00,0x10,
-0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,
-0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,
-0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x80,
-0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x86,0x43,0x00,0x0c,0x27,0x93,0x8f,0xf4,
-0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,
-0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x64,0x00,0x00,0x30,0x21,
-0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21,0x8c,0x43,0x00,0x18,0x93,0x82,0x8b,0x61,
-0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01,0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d,
-0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x84,
-0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06,0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff,
-0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b,
-0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04,
-0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x0c,0x00,0x1b,0x84,0x30,0x50,0x00,0x01,
-0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef,0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,
-0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,
-0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x92,0x30,0x42,0x00,0xc3,
-0x96,0x22,0x00,0x00,0x08,0x00,0x11,0xb9,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0xb4,
-0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0,
-0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x27,0x84,0x8f,0xf0,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08,
-0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08,0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24,
-0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,
-0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xb4,
-0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xd8,
-0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24,0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12,
-0x27,0x82,0x8f,0xf0,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x4b,0x00,0x00,0x20,0x21,
-0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x96,0x00,0x07,0x2c,0x00,0x27,0x83,0x90,0x00,
-0x27,0x82,0x90,0x08,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,
-0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10,0x24,0x07,0x00,0x01,0x0c,0x00,0x21,0xf5,
-0xaf,0xa2,0x00,0x10,0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x89,0x00,0x07,0x1c,0x00,
-0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0x7d,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x07,
-0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x06,0x08,0x00,0x11,0x7a,0xa2,0x40,0x00,0x05,
-0x14,0x40,0xff,0x71,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x11,0x71,0x00,0xa2,0x10,0x07,
-0x14,0x40,0xfe,0xc3,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,
-0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x10,0xcc,0x00,0xa2,0x10,0x07,
-0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08,0x0c,0x00,0x0f,0x15,0x00,0x00,0x00,0x00,
-0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21,
-0x0c,0x00,0x1c,0x86,0xaf,0xa2,0x00,0x10,0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x6b,
-0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40,
-0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00,
-0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01,0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17,
-0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00,
-0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16,
-0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0,0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16,
-0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16,0x11,0x00,0xfe,0x50,0x00,0x00,0x00,0x00,
-0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x92,0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00,
-0x08,0x00,0x12,0x3b,0xa6,0x22,0x00,0x14,0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00,
-0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x34,0xa2,0x20,0x00,0x17,
-0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x8f,0xf0,0x00,0x04,0x18,0xc0,
-0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,
-0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,
-0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,
-0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,
-0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x34,0xa2,0x23,0x00,0x17,
-0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x63,0x00,0x00,0x00,0x00,
-0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03,
-0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x07,
-0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x06,0x08,0x00,0x12,0x2e,0xa2,0x40,0x00,0x05,
-0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24,
-0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21,0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01,
-0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd,
-0x00,0xa4,0x10,0x2b,0x08,0x00,0x12,0x7e,0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff,
-0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x27,0x84,0x90,0x00,0x00,0x03,0x18,0x80,
-0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06,0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00,
-0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21,0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21,
-0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c,0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41,
-0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04,0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00,
-0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20,
-0x08,0x00,0x12,0xa4,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06,
-0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff,
-0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21,0x8f,0x85,0x8f,0xd0,0x00,0x40,0x30,0x21,
-0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00,0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02,
-0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00,0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08,
-0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00,0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00,0x27,0x92,0xb3,0xf0,0x24,0x11,0x00,0x12,
-0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x0c,0x00,0x20,0xd0,0x00,0x00,0x00,0x00,
-0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf,0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03,
-0x0c,0x00,0x13,0x18,0xac,0x30,0x00,0x00,0x08,0x00,0x12,0xa4,0x00,0x00,0x00,0x00,
-0x8f,0x85,0x8f,0xd0,0x08,0x00,0x12,0xba,0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95,
-0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24,0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03,
-0xac,0x30,0x00,0x00,0x0c,0x00,0x12,0xe1,0xac,0x60,0x00,0x00,0x08,0x00,0x12,0xa4,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x50,0x08,0x00,0x12,0xa4,
-0xac,0x46,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0x84,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01,0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01,
-0x25,0x29,0x03,0x1c,0x11,0x09,0x00,0x10,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,
-0x25,0x4a,0x4b,0xac,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06,
-0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,
-0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01,0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01,
-0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0xe8,
-0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40,0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x14,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01,
-0x24,0x63,0x03,0x1c,0x3c,0x04,0xb0,0x00,0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00,
-0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a,
-0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0x18,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x60,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x02,0x80,0x01,0x24,0x42,0x03,0x20,0x3c,0x03,0x80,0x01,0x24,0x63,0x3f,0x14,
-0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c,
-0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,
-0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xa0,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,
-0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0,0x27,0x9d,0x8b,0xd0,0x00,0x00,0x00,0x00,
-0x27,0x9d,0x8f,0xb8,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xc4,0x3c,0x0b,0xb0,0x03,
-0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00,0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00,
-0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x15,0x65,
-0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00,0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40,
-0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff,
-0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14,0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18,
-0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x0c,0x00,0x13,0x95,0x02,0x20,0x20,0x21,
-0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,
-0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21,0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c,
-0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21,
-0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40,
-0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21,0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a,
-0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00,0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01,
-0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a,
-0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21,0x8e,0x30,0x00,0x00,0x0c,0x00,0x13,0x95,
-0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27,0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04,
-0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a,
-0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00,0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00,
-0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x83,
-0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20,
-0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,
-0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0x00,0x80,0x90,0x21,0x00,0xa0,0x80,0x21,
-0x00,0xc0,0x88,0x21,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x3c,0x02,0xc0,0x00,0x00,0x10,0x1c,0x00,
-0x34,0x42,0x04,0x00,0x3c,0x04,0xb0,0x05,0x3c,0x05,0xb0,0x05,0x24,0x63,0x16,0x09,
-0x02,0x22,0x10,0x21,0x34,0x84,0x04,0x20,0x34,0xa5,0x04,0x24,0x3c,0x06,0xb0,0x05,
-0xac,0x83,0x00,0x00,0x24,0x07,0x00,0x01,0xac,0xa2,0x00,0x00,0x34,0xc6,0x02,0x28,
-0x24,0x02,0x00,0x20,0xae,0x47,0x00,0x3c,0x24,0x04,0x08,0x24,0xa0,0xc2,0x00,0x00,
-0x3c,0x05,0x00,0xc0,0xa2,0x47,0x00,0x11,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,
-0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,
-0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06,0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50,
-0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14,
-0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c,0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24,
-0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31,
-0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10,
-0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48,0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c,
-0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00,0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00,
-0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25,0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80,
-0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03,
-0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22,0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67,
-0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00,0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa,
-0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23,0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23,
-0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01,0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0,
-0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08,0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00,
-0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00,0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef,
-0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef,0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00,
-0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00,0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14,
-0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c,0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04,
-0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10,0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14,
-0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09,0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09,
-0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09,0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09,
-0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09,0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00,
-0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00,0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee,
-0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20,0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28,
-0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30,0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38,
-0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00,0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00,
-0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00,0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00,
-0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00,0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00,
-0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00,0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00,
-0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09,0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x34,0x63,0x00,0x20,0x24,0x42,0x51,0x38,0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34,
-0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a,0x14,0x40,0x01,0x0b,0x00,0x80,0x30,0x21,
-0x8c,0x84,0x00,0x08,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0xfe,0x00,0x00,0x00,0x00,
-0x8c,0xc2,0x00,0x2c,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x47,0x24,0x02,0x00,0x06,
-0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xe4,0xac,0xc2,0x00,0x2c,0x24,0x02,0x00,0x01,
-0x10,0x82,0x00,0xe3,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0xd1,
-0x00,0x00,0x00,0x00,0x8c,0xc7,0x00,0x04,0x24,0x02,0x00,0x02,0x10,0xe2,0x00,0xc7,
-0x00,0x00,0x00,0x00,0x8c,0xc2,0x00,0x14,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09,
-0x24,0x02,0x00,0x01,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xc2,0x00,0x14,
-0x24,0x02,0x00,0x01,0xac,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x14,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x04,0x61,0x00,0x16,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x10,0x3c,0x02,0xb0,0x05,
-0x34,0x42,0x02,0x42,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0b,
-0x00,0x00,0x00,0x00,0x80,0xc2,0x00,0x50,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,
-0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01,
-0xac,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xc3,0x00,0x50,0x80,0xc2,0x00,0x31,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,
-0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24,
-0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x03,0xe0,0x00,0x08,0xac,0xc2,0x00,0x00,
-0x8c,0xc2,0x00,0x40,0x00,0x00,0x00,0x00,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x10,0x60,0x00,0x09,0x3c,0x03,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,
-0x8c,0x43,0x00,0x00,0x3c,0x04,0x00,0x02,0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2,
-0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x80,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,
-0x8c,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0xac,0xc3,0x00,0x10,0x3c,0x02,0xb0,0x03,
-0x90,0x42,0x02,0x01,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0xac,0xc2,0x00,0x0c,
-0x90,0xc3,0x00,0x0f,0x24,0x02,0x00,0x0d,0x3c,0x01,0xb0,0x03,0x08,0x00,0x14,0xa6,
-0xa0,0x23,0x02,0x01,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x04,0x1e,0x00,0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15,
-0xa0,0xc4,0x00,0x44,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02,
-0x10,0x62,0x00,0x03,0x24,0x03,0x00,0x0d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x8c,0xc2,0x00,0x0c,0xac,0xc3,0x00,0x00,0x24,0x03,0x00,0x04,0xac,0xc2,0x00,0x10,
-0x03,0xe0,0x00,0x08,0xac,0xc3,0x00,0x0c,0x24,0x02,0x00,0x0d,0xac,0xc2,0x00,0x00,
-0x24,0x03,0x00,0x04,0x24,0x02,0x00,0x06,0xac,0xc3,0x00,0x10,0x03,0xe0,0x00,0x08,
-0xac,0xc2,0x00,0x0c,0x8c,0xc3,0x00,0x38,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x06,
-0x10,0x40,0x00,0x2e,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x02,0x00,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x06,0x24,0x02,0x00,0x03,
-0x8c,0xa2,0x02,0xbc,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x06,0x3c,0x03,0xb0,0x06,
-0x24,0x02,0x00,0x02,0xac,0xc2,0x00,0x00,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
-0xac,0xc2,0x00,0x38,0x34,0x63,0x80,0x24,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xc2,0x00,0x18,0x24,0x02,0x00,0x02,
-0xac,0xc2,0x00,0x00,0x08,0x00,0x14,0xfa,0xac,0xc0,0x00,0x18,0x08,0x00,0x14,0xfa,
-0xac,0xc0,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x0b,0xac,0xc2,0x00,0x38,
-0x03,0xe0,0x00,0x08,0xac,0xc3,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x05,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0c,0xac,0xc2,0x00,0x00,0x08,0x00,0x14,0xfb,
-0x24,0x02,0x00,0x04,0x08,0x00,0x15,0x12,0x24,0x02,0x00,0x03,0xac,0xc0,0x00,0x38,
-0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x05,
-0x24,0x02,0x00,0x03,0x80,0xc2,0x00,0x30,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x08,
-0x24,0x02,0x00,0x04,0xac,0xc2,0x00,0x00,0x93,0x82,0x86,0x3c,0x00,0x00,0x00,0x00,
-0x14,0x40,0xff,0xd6,0x24,0x02,0x00,0x05,0x03,0xe0,0x00,0x08,0xac,0xc0,0x00,0x38,
-0x08,0x00,0x15,0x22,0xac,0xc0,0x00,0x00,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18,
-0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24,
-0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x08,0x00,0x15,0x26,0xac,0xc2,0x00,0x00,
-0x24,0x02,0x00,0x05,0x08,0x00,0x15,0x18,0xac,0xc2,0x00,0x38,0x80,0xc2,0x00,0x30,
-0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x37,0x24,0x02,0x00,0x04,0x08,0x00,0x14,0xa6,
-0x00,0x00,0x00,0x00,0x84,0xc2,0x00,0x20,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x66,
-0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,
-0x14,0x40,0xff,0x24,0xa4,0xc3,0x00,0x20,0x08,0x00,0x14,0xa6,0x24,0x02,0x00,0x06,
-0x8c,0xc2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x57,0x24,0x02,0x00,0x05,
-0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x14,0xac,0xc2,0x00,0x1c,0x08,0x00,0x14,0xa6,
-0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x47,0x24,0x02,0x00,0x06,
-0x08,0x00,0x14,0x5c,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a,0x03,0xe0,0x00,0x08,
-0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10,0x27,0x90,0x86,0x48,
-0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0x0c,0x00,0x2b,0xe8,
-0xaf,0xb1,0x00,0x14,0xaf,0x90,0x8f,0xd0,0x48,0x02,0x00,0x00,0x0c,0x00,0x13,0xec,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x4e,0x02,0x00,0x20,0x21,0x0c,0x00,0x00,0x34,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0xf7,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,
-0x0c,0x00,0x27,0xc1,0x00,0x00,0x00,0x00,0x93,0x84,0x80,0x10,0x0c,0x00,0x21,0x9a,
-0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x06,0xe1,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x01,0x3b,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x0c,0x00,0x13,0xd5,
-0x00,0x00,0x00,0x00,0x27,0x82,0x89,0x3c,0xaf,0x82,0x84,0x50,0x0c,0x00,0x00,0x61,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09,
-0x3c,0x05,0xb0,0x09,0x8c,0x66,0x00,0x00,0x34,0x84,0x01,0x68,0x24,0x02,0xc8,0x80,
-0x34,0xa5,0x01,0x40,0x24,0x03,0x00,0x0a,0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00,
-0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00,0x8f,0x87,0x84,0x10,0xaf,0x86,0x84,0x08,
-0x34,0x42,0x00,0x20,0xac,0x82,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x58,
-0x8c,0x43,0x00,0x00,0x2c,0xe4,0x00,0x11,0x34,0x63,0x01,0x00,0xac,0x43,0x00,0x00,
-0x10,0x80,0xff,0xfa,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x00,0x07,0x10,0x80,
-0x24,0x63,0x02,0x18,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x26,0xe5,
-0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x27,0x85,0x86,0x48,0x0c,0x00,0x14,0x4e,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x07,0x3c,0x03,0xb0,0x06,
-0x90,0x44,0x00,0x00,0x34,0x63,0x80,0x18,0x8c,0x65,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0xec,0x3c,0x03,0xb0,0x03,0x30,0x86,0x00,0xff,0xa0,0x46,0x00,0x00,
-0x00,0x05,0x2f,0x02,0x34,0x63,0x00,0xed,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x2c,
-0xa0,0x65,0x00,0x00,0xa3,0x80,0x81,0x58,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01,
-0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x87,0x84,0x10,0x8f,0x82,0x84,0x44,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0x9b,
-0x3c,0x02,0xb0,0x03,0x8f,0x87,0x84,0x10,0x00,0x00,0x00,0x00,0x24,0xe2,0xff,0xfc,
-0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,0x3c,0x03,0xb0,0x06,0x93,0x82,0x86,0x3c,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x07,0x34,0x63,0x80,0x18,0x27,0x84,0x84,0x68,
-0x0c,0x00,0x27,0x75,0x00,0x00,0x00,0x00,0x8f,0x87,0x84,0x10,0x3c,0x03,0xb0,0x06,
-0x34,0x63,0x80,0x18,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,
-0x10,0x40,0xff,0xe6,0x00,0x00,0x00,0x00,0x8f,0x82,0xbc,0x10,0x8f,0x84,0xbc,0x18,
-0x3c,0x05,0xb0,0x01,0x00,0x45,0x10,0x21,0xac,0x44,0x00,0x00,0x8f,0x83,0xbc,0x10,
-0x8f,0x82,0xbc,0x14,0x00,0x65,0x18,0x21,0x08,0x00,0x15,0xc7,0xac,0x62,0x00,0x04,
-0x14,0xa0,0xff,0xd4,0x3c,0x02,0xb0,0x03,0x93,0x83,0x81,0x58,0x34,0x42,0x00,0xee,
-0x24,0x63,0x00,0x01,0x30,0x64,0x00,0xff,0x2c,0x84,0x00,0xf1,0xa0,0x43,0x00,0x00,
-0xa3,0x83,0x81,0x58,0x14,0x80,0xff,0xcc,0x00,0x00,0x00,0x00,0xaf,0x86,0x84,0x24,
-0xa3,0x86,0x86,0x23,0x08,0x00,0x15,0xc1,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,
-0x0c,0x00,0x29,0x6e,0x00,0x00,0x00,0x00,0xa3,0x82,0x84,0x41,0x8f,0x82,0x84,0x44,
-0xaf,0x80,0x84,0x10,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0x9a,
-0x00,0x00,0x38,0x21,0x27,0x84,0x86,0x48,0x0c,0x00,0x19,0x19,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05,0xaf,0x80,0x84,0x10,
-0xaf,0x80,0x84,0x14,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x34,0x63,0x04,0x50,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x3c,
-0x14,0x40,0x00,0x20,0x24,0x02,0x00,0x01,0x8f,0x84,0x84,0x18,0x00,0x00,0x00,0x00,
-0x10,0x82,0x00,0x20,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x24,0x14,0x40,0x00,0x15,
-0x24,0x02,0x00,0x01,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07,0x00,0x00,0x00,0x00,
-0x24,0x07,0x00,0x03,0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x14,0xaf,0x87,0x84,0x10,
-0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,
-0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,
-0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x30,0x14,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x14,0xaf,0x80,0x84,0x10,0x08,0x00,0x15,0xc6,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x2c,0x14,0x40,0xff,0xf5,
-0x24,0x02,0x00,0x01,0x08,0x00,0x16,0x1a,0x3c,0x03,0xb0,0x09,0x27,0x84,0x86,0x48,
-0x0c,0x00,0x1a,0xde,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x40,0x00,0x00,0x00,0x00,
-0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x3c,
-0x14,0x40,0xff,0xe4,0x24,0x02,0x00,0x02,0x8f,0x84,0x84,0x18,0x24,0x02,0x00,0x01,
-0x10,0x82,0x00,0x12,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x04,0x00,0x00,0x00,0x00,
-0x24,0x07,0x00,0x04,0x08,0x00,0x16,0x26,0x24,0x02,0x00,0x02,0x3c,0x02,0xb0,0x05,
-0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,
-0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x30,0x14,0x40,0xff,0xf4,
-0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x35,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,
-0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,
-0xaf,0x82,0x84,0x2c,0x14,0x40,0xff,0xf7,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x56,
-0x24,0x02,0x00,0x02,0x27,0x84,0x89,0x08,0x0c,0x00,0x0b,0x51,0x00,0x00,0x00,0x00,
-0x8f,0x83,0x84,0x14,0xaf,0x82,0x84,0x2c,0x38,0x64,0x00,0x02,0x00,0x04,0x18,0x0a,
-0xaf,0x83,0x84,0x14,0x14,0x40,0xff,0xad,0x24,0x07,0x00,0x05,0x8f,0x82,0x89,0x48,
-0xaf,0x80,0x84,0x10,0x10,0x40,0x00,0x02,0x24,0x04,0x00,0x01,0xaf,0x84,0x84,0x18,
-0x93,0x82,0x89,0x56,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x43,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x8c,0x43,0x00,0x00,0x3c,0x04,0x20,0x00,
-0x00,0x64,0x18,0x24,0x10,0x60,0xff,0x3c,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0xa0,0x8c,0x43,0x00,0x00,0x3c,0x04,0x80,0x00,0xaf,0x80,0x89,0x30,
-0x24,0x63,0x00,0x01,0xac,0x43,0x00,0x00,0x3c,0x01,0xb0,0x05,0xac,0x24,0x00,0x08,
-0xaf,0x80,0x89,0x2c,0xaf,0x80,0x89,0x34,0xaf,0x80,0x89,0x38,0xaf,0x80,0x89,0x44,
-0xaf,0x80,0x89,0x3c,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x60,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x84,0x2c,
-0x8f,0x85,0x84,0x2c,0x27,0x84,0x89,0x08,0x0c,0x00,0x0d,0x2c,0x00,0x00,0x00,0x00,
-0x00,0x02,0x1e,0x00,0xa3,0x82,0x84,0x40,0xaf,0x80,0x84,0x2c,0x10,0x60,0xff,0x8e,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,
-0xa7,0x83,0x84,0x30,0x10,0x40,0x00,0x04,0x24,0x04,0x00,0x02,0xaf,0x84,0x84,0x18,
-0x08,0x00,0x16,0x36,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x27,0x24,0x07,0x00,0x06,
-0x27,0x84,0x84,0x10,0x27,0x85,0x89,0x08,0x0c,0x00,0x0d,0xf9,0x00,0x00,0x00,0x00,
-0x8f,0x82,0x84,0x34,0xaf,0x80,0x84,0x3c,0x14,0x40,0x00,0x19,0x00,0x40,0x18,0x21,
-0x8f,0x82,0x84,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x02,
-0x8f,0x83,0x84,0x18,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x0b,0x3c,0x02,0x40,0x00,
-0x8f,0x83,0x84,0x14,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x02,0x24,0x07,0x00,0x03,
-0x24,0x07,0x00,0x06,0xaf,0x87,0x84,0x10,0x24,0x04,0x00,0x03,0xaf,0x84,0x84,0x18,
-0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x14,0x3c,0x01,0xb0,0x05,
-0xac,0x22,0x00,0x00,0xaf,0x80,0x84,0x10,0x08,0x00,0x16,0xcf,0x24,0x04,0x00,0x03,
-0x10,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,0x27,0x85,0x89,0x08,
-0x0c,0x00,0x0e,0x1d,0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x14,0x24,0x02,0x00,0x01,
-0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x18,0x10,0x62,0x00,0x02,0x24,0x07,0x00,0x03,
-0x24,0x07,0x00,0x04,0xaf,0x87,0x84,0x10,0xaf,0x80,0x84,0x34,0x08,0x00,0x15,0xc6,
-0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x60,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x04,
-0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x10,0x65,0x00,0x00,0x00,0x00,
-0x8f,0x82,0x84,0x14,0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x18,
-0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x14,
-0xaf,0x80,0x84,0x38,0x08,0x00,0x15,0xc6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,
-0x27,0x85,0x89,0x08,0x0c,0x00,0x0e,0x1d,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x14,
-0xa3,0x80,0x84,0x40,0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x18,0x14,0x40,0xfe,0xc2,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x14,0x08,0x00,0x15,0xc6,
-0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x08,0x0c,0x00,0x10,0x65,0x00,0x00,0x00,0x00,
-0x08,0x00,0x16,0xff,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x2a,0x96,
-0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xfe,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x66,
-0x00,0x00,0x00,0x00,0x0c,0x00,0x27,0x56,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x40,
-0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x68,0x0c,0x00,0x27,0x64,0x00,0x00,0x00,0x00,
-0x93,0x83,0xbc,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x2b,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x83,0xbc,0x00,0x8f,0x82,0xbc,0x04,
-0x00,0x83,0x18,0x23,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x23,0x3c,0x02,0xb0,0x03,
-0x24,0x04,0x05,0xa0,0x34,0x42,0x01,0x18,0x8c,0x42,0x00,0x00,0x0c,0x00,0x06,0xce,
-0x00,0x00,0x00,0x00,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xce,0x00,0x02,0x84,0x02,
-0x30,0x51,0xff,0xff,0x24,0x04,0x05,0xa8,0x00,0x02,0x94,0x02,0x0c,0x00,0x06,0xce,
-0x3a,0x10,0xff,0xff,0x3a,0x31,0xff,0xff,0x30,0x42,0xff,0xff,0x2e,0x10,0x00,0x01,
-0x2e,0x31,0x00,0x01,0x3a,0x52,0xff,0xff,0x02,0x11,0x80,0x25,0x2e,0x52,0x00,0x01,
-0x38,0x42,0xff,0xff,0x02,0x12,0x80,0x25,0x2c,0x42,0x00,0x01,0x02,0x02,0x80,0x25,
-0x16,0x00,0x00,0x02,0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21,0x0c,0x00,0x05,0x70,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xaf,0x83,0xbc,0x00,0x0c,0x00,0x01,0xeb,0x00,0x00,0x00,0x00,
-0xaf,0x80,0x84,0x10,0xaf,0x80,0x84,0x44,0x08,0x00,0x15,0x9a,0x00,0x00,0x38,0x21,
-0x27,0x90,0xb3,0xf0,0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
-0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x20,0xd0,0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xf6,
-0x26,0x10,0x00,0x04,0xaf,0x80,0x84,0x10,0x08,0x00,0x15,0xc7,0x00,0x00,0x38,0x21,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x84,0x08,
-0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,0x10,0x62,0xff,0xf6,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,0x3c,0x12,0xb0,0x05,
-0xaf,0x84,0x84,0x08,0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,0x00,0x43,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,0x00,0x00,0x88,0x21,
-0x36,0x52,0x02,0x2c,0x27,0x90,0xb3,0xf0,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
-0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,0x10,0x40,0x00,0x06,
-0x30,0x62,0x00,0x1c,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x08,
-0x0c,0x00,0x1e,0xb2,0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xff,0x14,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x26,0x31,0x00,0x01,
-0x2a,0x22,0x00,0x13,0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,0x08,0x00,0x17,0x5d,
-0x00,0x00,0x00,0x00,0x8f,0x84,0x84,0x1c,0x27,0x85,0x89,0x08,0x0c,0x00,0x17,0xd3,
-0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x1c,0x24,0x02,0x00,0x04,0x14,0x62,0xfe,0xa2,
-0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x27,0x24,0x07,0x00,0x05,0x27,0x84,0x89,0x08,
-0x0c,0x00,0x24,0x8d,0x00,0x00,0x00,0x00,0x24,0x07,0x00,0x05,0xaf,0x87,0x84,0x10,
-0x08,0x00,0x15,0xc7,0x00,0x00,0x00,0x00,0x8f,0x82,0x89,0x3c,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x30,0xaf,0x80,0x89,0x3c,
-0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x84,0x00,0x00,0x00,0x00,0x93,0x82,0x8b,0x61,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x01,0x59,0x00,0x00,0x20,0x21,0x8f,0x84,0xb4,0x30,0x0c,0x00,0x20,0xd0,
-0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x5d,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x90,
-0x27,0xbd,0xff,0xe8,0x00,0x80,0x18,0x21,0x34,0x42,0x00,0x01,0x27,0x84,0x89,0x08,
-0x10,0x62,0x00,0x05,0xaf,0xbf,0x00,0x10,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x06,0xe1,0x00,0x00,0x00,0x00,
-0x27,0x84,0x86,0x48,0x0c,0x00,0x18,0x4e,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x10,
-0x0c,0x00,0x13,0xd5,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0xba,0x00,0x00,0x00,0x00,
-0x8f,0x82,0x89,0x48,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x18,0x21,
-0x8f,0x82,0x84,0x18,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,
-0x24,0x03,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x27,0xbd,0xff,0xe0,
-0x3c,0x06,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0xc6,0x00,0x5f,
-0xaf,0xbf,0x00,0x18,0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x5d,
-0x34,0x63,0x00,0x01,0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01,0xa0,0xc3,0x00,0x00,
-0x00,0x80,0x80,0x21,0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21,0x35,0x29,0x00,0x5e,
-0x00,0xe0,0x40,0x21,0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00,0x91,0x03,0x00,0x00,
-0x30,0x42,0x00,0x01,0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfa,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c,0x24,0x05,0x0f,0x00,
-0x24,0x02,0x00,0x06,0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x02,0x00,0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x0f,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5b,
-0x24,0x06,0x00,0x02,0x08,0x00,0x17,0xf4,0x3c,0x02,0xb0,0x03,0x24,0x04,0x08,0x8c,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04,0x24,0x05,0x00,0x0f,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30,0x24,0x06,0x00,0x03,
-0x0c,0x00,0x13,0x5b,0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21,0x24,0x05,0x00,0x14,
-0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07,0x08,0x00,0x17,0xf4,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x02,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0x59,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0x59,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x61,0x38,0x3c,0x04,0xb0,0x03,
-0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xbc,0xad,0xc0,0x02,0xb8,
-0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21,
-0xa7,0x82,0x8f,0xe0,0x27,0x88,0x8f,0xf0,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08,
-0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21,
-0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21,
-0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4,
-0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x25,0xc4,0x00,0x0c,
-0x24,0x0a,0x00,0x02,0x34,0x42,0x07,0xf8,0x3c,0x06,0xb0,0x03,0xa7,0x83,0xb3,0xcc,
-0xac,0x43,0x00,0x00,0xaf,0x84,0xb3,0xf0,0x34,0xc6,0x00,0x64,0xa0,0x8a,0x00,0x18,
-0x94,0xc5,0x00,0x00,0x8f,0x82,0xb3,0xf0,0x25,0xc4,0x00,0x30,0x24,0x08,0x00,0x03,
-0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,0xaf,0x84,0xb3,0xf4,
-0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb3,0xf4,0x25,0xc4,0x00,0x54,
-0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb3,0xf8,0xa0,0x88,0x00,0x18,
-0x94,0x65,0x00,0x00,0x8f,0x82,0xb3,0xf8,0x25,0xc8,0x00,0x9c,0x24,0x09,0x00,0x01,
-0xa0,0x45,0x00,0x21,0xaf,0x87,0xb3,0xfc,0xa0,0xea,0x00,0x18,0x94,0xc4,0x00,0x00,
-0x8f,0x82,0xb3,0xfc,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,0xa0,0x44,0x00,0x21,
-0xaf,0x88,0xb4,0x00,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x00,
-0x25,0xc4,0x00,0xc0,0x3c,0x06,0xb0,0x03,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x04,
-0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x04,0x25,0xc4,0x00,0xe4,
-0x34,0xc6,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x08,0xa0,0x80,0x00,0x18,
-0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x08,0x25,0xc3,0x01,0x08,0x25,0xc7,0x01,0x2c,
-0xa0,0x45,0x00,0x21,0xaf,0x83,0xb4,0x0c,0xa0,0x60,0x00,0x18,0x94,0xc8,0x00,0x00,
-0x8f,0x82,0xb4,0x0c,0x25,0xc4,0x01,0x50,0x25,0xc5,0x01,0x74,0xa0,0x48,0x00,0x21,
-0x25,0xc6,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,0x25,0xcb,0x02,0x04,
-0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,
-0xaf,0x87,0xb4,0x10,0x34,0x63,0x00,0x38,0xa0,0xe0,0x00,0x18,0xaf,0x84,0xb4,0x14,
-0xa0,0x80,0x00,0x18,0xaf,0x85,0xb4,0x18,0xa0,0xa0,0x00,0x18,0xaf,0x86,0xb4,0x1c,
-0xa0,0xc0,0x00,0x18,0xaf,0x89,0xb4,0x20,0xa1,0x20,0x00,0x18,0xaf,0x8a,0xb4,0x24,
-0xa1,0x40,0x00,0x18,0xaf,0x8b,0xb4,0x28,0xa1,0x60,0x00,0x18,0xaf,0x8c,0xb4,0x2c,
-0xa1,0x80,0x00,0x18,0xaf,0x8d,0xb4,0x30,0xa1,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,
-0x8f,0x82,0xb4,0x30,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21,
-0x24,0x02,0x00,0x11,0xaf,0x85,0xb4,0x34,0x34,0x63,0x00,0x6e,0xa0,0xa2,0x00,0x18,
-0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x34,0x25,0xc5,0x02,0x94,0x3c,0x03,0xb0,0x03,
-0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xb4,0x38,0x34,0x63,0x00,0x6c,
-0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x38,0x24,0x05,0xff,0xff,
-0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,0x27,0x84,0xb3,0xf0,
-0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,0x8c,0x83,0x00,0x00,
-0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,0x8c,0x82,0x00,0x00,
-0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,0x8c,0x83,0x00,0x00,
-0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,0x8c,0x82,0x00,0x00,
-0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x14,
-0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,0xa0,0x40,0x00,0x20,
-0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x64,0x00,
-0x00,0x05,0x28,0x40,0xac,0x62,0x00,0x00,0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10,
-0x14,0x80,0x00,0x06,0x00,0x00,0x18,0x21,0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,
-0x00,0xe0,0x18,0x21,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20,
-0x10,0xe2,0x00,0x06,0x2c,0xe4,0x00,0x10,0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9,
-0x00,0x02,0x11,0x00,0x08,0x00,0x19,0x0d,0x00,0x47,0x18,0x21,0x08,0x00,0x19,0x0d,
-0x24,0xa3,0x00,0x50,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,
-0x34,0x63,0x00,0x20,0x24,0x42,0x64,0x64,0xaf,0xb2,0x00,0x18,0xaf,0xbf,0x00,0x34,
-0xaf,0xbe,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,
-0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,
-0xac,0x62,0x00,0x00,0x8c,0x86,0x02,0xbc,0x00,0x80,0x90,0x21,0x14,0xc0,0x01,0x66,
-0x00,0xc0,0x38,0x21,0x84,0x82,0x00,0x08,0x3c,0x03,0xb0,0x06,0x94,0x84,0x00,0x08,
-0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x45,0x00,0x00,0x8c,0x43,0x00,0x00,
-0x24,0x84,0x00,0x02,0x30,0x84,0x01,0xff,0x30,0xb1,0xff,0xff,0x00,0x03,0x44,0x02,
-0xa6,0x44,0x00,0x08,0x14,0xe0,0x00,0x08,0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x42,0x01,0x00,0xac,0x62,0x00,0x00,
-0x8e,0x46,0x02,0xbc,0x00,0x00,0x00,0x00,0x14,0xc0,0x01,0x4c,0x00,0x11,0x98,0xc0,
-0x00,0x11,0x3a,0x00,0x3c,0x04,0xb0,0x00,0x00,0xe4,0x20,0x21,0x8c,0x83,0x00,0x0c,
-0x00,0x11,0x98,0xc0,0x02,0x71,0x10,0x21,0x00,0x03,0x1b,0x82,0x30,0x63,0x00,0x1f,
-0x00,0x02,0x10,0x80,0x27,0x9e,0x8f,0xf4,0x00,0x5e,0x10,0x21,0x00,0x60,0x30,0x21,
-0xac,0x44,0x00,0x18,0xae,0x43,0x02,0xbc,0x14,0xc0,0x00,0x10,0x3c,0x02,0xb0,0x00,
-0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x27,0x84,0x8f,0xf0,0x00,0x02,0x10,0x80,
-0x00,0x44,0x10,0x21,0x94,0x45,0x00,0x00,0x02,0x71,0x18,0x21,0x00,0x03,0x18,0x80,
-0x00,0x64,0x18,0x21,0x24,0x02,0xff,0xff,0xa4,0x62,0x00,0x02,0xa4,0x68,0x00,0x04,
-0xae,0x51,0x02,0xb8,0xa6,0x45,0x00,0x0a,0x3c,0x02,0xb0,0x00,0x00,0xe2,0x40,0x21,
-0x8d,0x16,0x00,0x00,0x8d,0x14,0x00,0x04,0x02,0x71,0x10,0x21,0x00,0x02,0x38,0x80,
-0x00,0x14,0x1a,0x02,0x27,0x84,0x90,0x00,0x30,0x63,0x00,0x1f,0x24,0x02,0x00,0x10,
-0x00,0xe4,0x20,0x21,0xa6,0x43,0x00,0x06,0x8d,0x10,0x00,0x08,0xa0,0x82,0x00,0x06,
-0x86,0x45,0x00,0x06,0x00,0xfe,0x10,0x21,0x24,0x03,0x00,0x13,0x10,0xa3,0x01,0x15,
-0xac,0x48,0x00,0x18,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00,0xa6,0x40,0x00,0x02,
-0x3c,0x02,0xb0,0x03,0x90,0x64,0x00,0x00,0x34,0x42,0x01,0x08,0x8c,0x45,0x00,0x00,
-0x00,0x10,0x1b,0xc2,0x27,0x82,0x8f,0xf0,0x00,0x04,0x20,0x82,0x00,0xe2,0x10,0x21,
-0x30,0x63,0x00,0x01,0xac,0x45,0x00,0x08,0x10,0x60,0x00,0xec,0x30,0x97,0x00,0x01,
-0x00,0x10,0x16,0x82,0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,0x00,0x10,0x19,0xc2,
-0x00,0x10,0x26,0x02,0x00,0x10,0x2e,0x42,0x30,0x47,0x00,0x7f,0x24,0x02,0x00,0x01,
-0x30,0x75,0x00,0x01,0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xd9,0x30,0xa3,0x00,0x01,
-0x0c,0x00,0x19,0x00,0x00,0x60,0x28,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x18,0x80,
-0x2c,0x46,0x00,0x54,0x27,0x85,0x90,0x00,0x27,0x84,0x8f,0xf8,0x00,0x06,0x10,0x0a,
-0x00,0x65,0x28,0x21,0x26,0xa6,0x00,0x02,0x00,0x64,0x18,0x21,0xa0,0xa2,0x00,0x02,
-0xa0,0x66,0x00,0x06,0xa0,0x62,0x00,0x07,0xa0,0xa2,0x00,0x01,0x02,0x71,0x20,0x21,
-0x00,0x04,0x20,0x80,0x00,0x9e,0x60,0x21,0x8d,0x85,0x00,0x18,0x00,0x10,0x15,0xc2,
-0x30,0x42,0x00,0x01,0x8c,0xa3,0x00,0x0c,0xa6,0x42,0x00,0x00,0x27,0x82,0x90,0x10,
-0x00,0x82,0x50,0x21,0xa6,0x56,0x00,0x04,0x8d,0x45,0x00,0x00,0x00,0x03,0x19,0x42,
-0x3c,0x02,0xff,0xef,0x34,0x42,0xff,0xff,0x30,0x63,0x00,0x01,0x00,0xa2,0x48,0x24,
-0x00,0x03,0x1d,0x00,0x01,0x23,0x48,0x25,0x00,0x09,0x15,0x02,0x26,0xc5,0x00,0x10,
-0x00,0x14,0x19,0x82,0x00,0x14,0x25,0x82,0x00,0x10,0x34,0x02,0x00,0x10,0x3c,0x42,
-0x00,0x10,0x44,0x82,0x30,0x42,0x00,0x01,0x30,0xb5,0xff,0xff,0x30,0xce,0x00,0x01,
-0x30,0xe5,0x00,0x01,0x30,0x6d,0x00,0x01,0x30,0x8b,0x00,0x03,0x32,0x94,0x00,0x07,
-0x31,0x06,0x00,0x01,0xad,0x49,0x00,0x00,0x10,0x40,0x00,0x0b,0x32,0x07,0x00,0x7f,
-0x8d,0x84,0x00,0x18,0x3c,0x03,0xff,0xf0,0x34,0x63,0xff,0xff,0x8c,0x82,0x00,0x0c,
-0x01,0x23,0x18,0x24,0x00,0x02,0x13,0x82,0x30,0x42,0x00,0x0f,0x00,0x02,0x14,0x00,
-0x00,0x62,0x18,0x25,0xad,0x43,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x90,
-0x00,0x00,0x00,0x00,0x15,0xa0,0x00,0x03,0x00,0x00,0x00,0x00,0x15,0x60,0x00,0x81,
-0x24,0x02,0x00,0x01,0x96,0x42,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04,
-0xa6,0x42,0x00,0x04,0x0c,0x00,0x19,0x00,0x01,0xc0,0x20,0x21,0x02,0x71,0x18,0x21,
-0x00,0x03,0x38,0x80,0x2c,0x45,0x00,0x54,0x27,0x84,0x90,0x00,0x00,0xe4,0x20,0x21,
-0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05,
-0x96,0x45,0x00,0x04,0x27,0x82,0x8f,0xf0,0x00,0xe2,0x10,0x21,0xa4,0x45,0x00,0x06,
-0x00,0xfe,0x18,0x21,0x92,0x45,0x00,0x01,0x8c,0x66,0x00,0x18,0x27,0x82,0x90,0x10,
-0x00,0xe2,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x85,0x00,0x07,0x94,0xc3,0x00,0x10,
-0x24,0x02,0x00,0x04,0x30,0x63,0x00,0x0f,0x10,0x62,0x00,0x5e,0x24,0xc6,0x00,0x10,
-0x94,0xc3,0x00,0x16,0x27,0x85,0x90,0x08,0x00,0xe5,0x10,0x21,0xa4,0x43,0x00,0x02,
-0x94,0xc2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x4c,
-0x02,0x71,0x20,0x21,0x94,0xc2,0x00,0x00,0x24,0x03,0x00,0xa4,0x30,0x42,0x00,0xff,
-0x10,0x43,0x00,0x47,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x00,0x24,0x03,0x00,0x88,
-0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x3c,0x02,0x71,0x18,0x21,0x27,0x84,0x90,0x10,
-0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,0x3c,0x04,0x00,0x80,
-0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x45,0x10,0x21,0xa0,0x54,0x00,0x00,0x92,0x43,0x02,0xbf,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x00,0xc3,0xa0,0x43,0x00,0x00,0x8e,0x4b,0x02,0xbc,0x00,0x00,0x00,0x00,
-0x11,0x60,0x00,0x1c,0x32,0xa2,0x00,0xff,0x00,0x15,0x1a,0x02,0x30,0x64,0xff,0xff,
-0x38,0x42,0x00,0x00,0x24,0x65,0x00,0x01,0x00,0x82,0x28,0x0a,0x02,0x20,0x30,0x21,
-0x10,0xa0,0x00,0x12,0x00,0x00,0x38,0x21,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x8f,0xf0,0x00,0x43,0x20,0x21,0x24,0xa9,0xff,0xff,0x3c,0x0a,0xb0,0x08,
-0x24,0x0c,0xff,0xff,0x00,0x06,0x10,0xc0,0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x00,
-0x24,0xe8,0x00,0x01,0x10,0xe9,0x00,0x0f,0x30,0x63,0x00,0xff,0x31,0x07,0xff,0xff,
-0x00,0xe5,0x10,0x2b,0x14,0x40,0xff,0xf7,0x00,0x60,0x30,0x21,0x25,0x62,0xff,0xff,
-0xae,0x42,0x02,0xbc,0x7b,0xbe,0x01,0xbc,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x38,0xa4,0x86,0x00,0x04,0xa4,0x8c,0x00,0x02,0xae,0x51,0x02,0xb8,
-0x08,0x00,0x1a,0x2f,0xa6,0x43,0x00,0x0a,0x94,0xc2,0x00,0x18,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xc1,0x02,0x71,0x18,0x21,0x02,0x71,0x20,0x21,
-0x27,0x82,0x90,0x10,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21,0x8c,0x83,0x00,0x00,
-0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24,0x08,0x00,0x1a,0x0e,
-0xac,0x83,0x00,0x00,0x27,0x85,0x90,0x08,0x00,0xe5,0x10,0x21,0x08,0x00,0x19,0xf8,
-0xa4,0x40,0x00,0x02,0x11,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x2d,0x62,0x00,0x02,
-0x14,0x40,0xff,0x80,0x00,0x00,0x00,0x00,0x96,0x42,0x00,0x04,0x08,0x00,0x19,0xd8,
-0x24,0x42,0x00,0x0c,0x96,0x42,0x00,0x04,0x08,0x00,0x19,0xd8,0x24,0x42,0x00,0x08,
-0x16,0xe6,0xff,0x70,0x3c,0x02,0xff,0xfb,0x8d,0x83,0x00,0x18,0x34,0x42,0xff,0xff,
-0x02,0x02,0x10,0x24,0xac,0x62,0x00,0x08,0x08,0x00,0x19,0xd1,0x00,0x00,0x30,0x21,
-0x16,0xe6,0xff,0x27,0x3c,0x02,0xfb,0xff,0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,
-0xad,0x02,0x00,0x08,0x08,0x00,0x19,0x90,0x00,0x00,0x30,0x21,0x93,0x88,0xbb,0x04,
-0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82,0x27,0x82,0x8f,0xf8,0x2d,0x05,0x00,0x0c,
-0x00,0xe2,0x48,0x21,0x30,0x63,0x00,0x01,0x30,0x86,0x00,0x01,0x14,0xa0,0x00,0x06,
-0x01,0x00,0x38,0x21,0x00,0x03,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,
-0x01,0x02,0x10,0x21,0x24,0x47,0x00,0x04,0x02,0x71,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x84,0x90,0x00,0x27,0x83,0x8f,0xf8,0x00,0x44,0x20,0x21,0x00,0x43,0x10,0x21,
-0xa1,0x27,0x00,0x07,0xa0,0x40,0x00,0x06,0xa0,0x80,0x00,0x02,0x08,0x00,0x19,0x9f,
-0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01,0xa6,0x42,0x00,0x02,0x0c,0x00,0x01,0xc4,
-0x01,0x00,0x20,0x21,0x08,0x00,0x1a,0x35,0x00,0x00,0x00,0x00,0x27,0x9e,0x8f,0xf4,
-0x08,0x00,0x19,0x52,0x00,0x11,0x3a,0x00,0x94,0x91,0x00,0x0a,0x08,0x00,0x19,0x39,
-0x00,0x00,0x00,0x00,0x30,0xa9,0xff,0xff,0x00,0x09,0x18,0xc0,0x00,0x69,0x18,0x21,
-0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6a,0x54,0x00,0x03,0x18,0x80,
-0x34,0xc6,0x00,0x20,0x27,0x85,0x90,0x00,0xac,0xc2,0x00,0x00,0x00,0x65,0x18,0x21,
-0x80,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x32,0x24,0x88,0x00,0x06,
-0x90,0x82,0x00,0x16,0x00,0x80,0x40,0x21,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01,
-0x14,0x60,0x00,0x02,0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x95,0x03,0x00,0x02,
-0x00,0x00,0x00,0x00,0x10,0x69,0x00,0x22,0x3c,0x02,0x34,0x34,0x91,0x02,0x00,0x04,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x06,0x00,0x03,0x20,0xc0,0x24,0x02,0x00,0x01,
-0xa1,0x02,0x00,0x04,0xa5,0x09,0x00,0x02,0x03,0xe0,0x00,0x08,0xa5,0x09,0x00,0x00,
-0x00,0x83,0x20,0x21,0x27,0x87,0x8f,0xf0,0x00,0x04,0x20,0x80,0x00,0x87,0x20,0x21,
-0x94,0x83,0x00,0x04,0x3c,0x02,0xb0,0x08,0x3c,0x06,0xb0,0x03,0x00,0x03,0x28,0xc0,
-0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,0x3c,0x02,0x80,0x01,
-0x24,0x42,0x82,0xe4,0x00,0x67,0x18,0x21,0x34,0xc6,0x00,0x20,0xac,0xc2,0x00,0x00,
-0xa4,0x69,0x00,0x00,0xa4,0x89,0x00,0x02,0xac,0xa9,0x00,0x00,0x91,0x02,0x00,0x04,
-0xa5,0x09,0x00,0x02,0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x04,
-0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xb0,0x34,0x42,0x34,0x34,0x03,0xe0,0x00,0x08,
-0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x01,
-0x30,0x43,0x00,0x02,0x14,0x60,0xff,0xd1,0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01,
-0x08,0x00,0x1a,0xab,0xa0,0x82,0x00,0x17,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,
-0x00,0x80,0x38,0x21,0x84,0x84,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x3c,0x0a,0xb0,0x06,0x34,0x63,0x00,0x20,0x24,0x42,0x6b,0x78,0x3c,0x0b,0xb0,0x08,
-0x27,0x89,0x8f,0xf0,0x34,0x0c,0xff,0xff,0x35,0x4a,0x80,0x20,0x10,0x80,0x00,0x30,
-0xac,0x62,0x00,0x00,0x97,0x82,0x8f,0xe0,0x94,0xe6,0x02,0xba,0x00,0x02,0x18,0xc0,
-0x00,0x6b,0x28,0x21,0xac,0xa6,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x00,0x62,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x49,0x10,0x21,0x94,0x48,0x00,0x04,0x00,0x69,0x18,0x21,0xa4,0x66,0x00,0x00,
-0x00,0x08,0x28,0xc0,0x00,0xab,0x10,0x21,0xac,0x4c,0x00,0x00,0x8c,0xe4,0x02,0xb8,
-0x27,0x82,0x8f,0xf4,0x00,0xa8,0x28,0x21,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x46,0x00,0x18,0x27,0x84,0x90,0x00,
-0x00,0x64,0x18,0x21,0x8c,0xc2,0x00,0x00,0x80,0x67,0x00,0x06,0x00,0x05,0x28,0x80,
-0x30,0x42,0xff,0xff,0x00,0x47,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,
-0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x3c,0x04,0x00,0x04,0x00,0xa9,0x28,0x21,
-0x00,0x44,0x10,0x25,0xa4,0xac,0x00,0x00,0xad,0x42,0x00,0x00,0xa7,0x88,0x8f,0xe0,
-0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x84,0xe3,0x00,0x06,0x27,0x82,0xb3,0xf0,0x94,0xe5,0x02,0xba,0x00,0x03,0x18,0x80,
-0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x0c,0x00,0x1a,0x95,0x00,0x00,0x00,0x00,
-0x08,0x00,0x1b,0x18,0x00,0x00,0x00,0x00,0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21,
-0x27,0x8a,0x8f,0xf0,0x00,0x08,0x18,0xc0,0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03,
-0x00,0x03,0x18,0x80,0x3c,0x02,0x80,0x00,0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20,
-0x24,0x42,0x6c,0x98,0x30,0xa5,0xff,0xff,0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02,
-0x11,0x05,0x00,0x35,0x24,0x04,0x00,0x01,0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00,
-0x00,0x86,0x10,0x2a,0x10,0x40,0x00,0x10,0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03,
-0x01,0x40,0x60,0x21,0x35,0xad,0x00,0x20,0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01,
-0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21,
-0x00,0x4a,0x10,0x21,0x00,0x86,0x18,0x2a,0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02,
-0x14,0x60,0xff,0xf5,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,
-0x00,0x08,0x20,0xc0,0x00,0x88,0x20,0x21,0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80,
-0xa1,0x62,0x00,0x04,0x00,0x8c,0x20,0x21,0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0,
-0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0,
-0x94,0x46,0x00,0x02,0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21,
-0xa4,0x66,0x00,0x00,0xa4,0x86,0x00,0x02,0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08,
-0x3c,0x02,0x80,0x01,0x00,0xa3,0x28,0x21,0x24,0x42,0x82,0xe4,0xad,0xa2,0x00,0x00,
-0x10,0x87,0x00,0x03,0xac,0xa6,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,
-0x08,0x00,0x1b,0x66,0xa5,0x68,0x00,0x02,0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00,
-0x24,0x42,0xff,0xff,0x30,0x43,0x00,0xff,0x14,0x60,0x00,0x03,0xa1,0x62,0x00,0x04,
-0x24,0x02,0xff,0xff,0xa5,0x62,0x00,0x02,0x91,0x65,0x00,0x04,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xf1,0x00,0x00,0x00,0x00,0x95,0x66,0x00,0x00,0x34,0x02,0xff,0xff,
-0x14,0xc2,0xff,0xed,0x3c,0x03,0xb0,0x03,0x95,0x64,0x00,0x02,0x3c,0x02,0xee,0xee,
-0x00,0xa2,0x10,0x25,0x34,0x63,0x00,0xbc,0xac,0x62,0x00,0x00,0x10,0x86,0xff,0xe6,
-0xa1,0x60,0x00,0x04,0x24,0x02,0xff,0xff,0x08,0x00,0x1b,0x66,0xa5,0x62,0x00,0x02,
-0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21,0x27,0xbd,0xff,0xd8,0x00,0x06,0x30,0x80,
-0x27,0x82,0x8f,0xf4,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,
-0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10,0x00,0xc2,0x10,0x21,0x8c,0x47,0x00,0x18,
-0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,
-0x24,0x42,0x6e,0x10,0xac,0xa2,0x00,0x00,0x27,0x83,0x90,0x00,0x00,0xc3,0x30,0x21,
-0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06,0x00,0x80,0x88,0x21,0x30,0x42,0xff,0xff,
-0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x02,0x00,0x02,0x12,0x02,
-0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff,0x01,0x12,0x10,0x21,0x00,0x02,0x10,0x80,
-0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x80,0x44,0x00,0x07,0x00,0x00,0x00,0x00,
-0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06,0x32,0x50,0xff,0xff,0x02,0x20,0x20,0x21,
-0x0c,0x00,0x1b,0x26,0x02,0x00,0x28,0x21,0x92,0x22,0x00,0x10,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08,0x3c,0x09,0x80,0x01,0x27,0x88,0x8f,0xf0,
-0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0,0x00,0x90,0x20,0x21,0x00,0x04,0x20,0x80,
-0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,
-0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x48,0x10,0x21,
-0x00,0xa3,0x28,0x21,0x25,0x26,0x82,0xe4,0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,
-0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,
-0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a,0xa6,0x32,0x00,0x0e,0x02,0x62,0x10,0x21,
-0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10,0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x96,0x22,0x00,0x0e,
-0x27,0x88,0x8f,0xf0,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,
-0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x06,0xb0,0x03,0x3c,0x09,0x80,0x01,
-0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,
-0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20,0x25,0x23,0x82,0xe4,0xac,0xc3,0x00,0x00,
-0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00,0x08,0x00,0x1b,0xb5,0xa4,0x90,0x00,0x02,
-0x08,0x00,0x1b,0xac,0x32,0x50,0xff,0xff,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x24,0x42,0x6f,0xd8,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x04,
-0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21,0x30,0xa8,0xff,0xff,0x00,0x4a,0x20,0x23,
-0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff,0x30,0xee,0xff,0xff,0x11,0x09,0x00,0x73,
-0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0,0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,
-0x03,0x0e,0x20,0x21,0x27,0x8d,0x8f,0xf0,0x00,0x04,0x20,0x80,0x00,0x02,0x10,0x80,
-0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21,0x94,0x86,0x00,0x02,0x94,0x43,0x00,0x04,
-0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02,0x00,0x03,0x28,0xc0,0x00,0xa3,0x18,0x21,
-0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,
-0x00,0x6d,0x18,0x21,0x27,0x22,0x82,0xe4,0x3c,0x01,0xb0,0x03,0xac,0x22,0x00,0x20,
-0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57,0xac,0xa6,0x00,0x00,0x01,0xe0,0x30,0x21,
-0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21,0x01,0x40,0x38,0x21,0x27,0x8b,0x8f,0xf4,
-0x27,0x8a,0x90,0x00,0x00,0x06,0x40,0xc0,0x01,0x06,0x18,0x21,0x00,0x03,0x18,0x80,
-0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x6a,0x18,0x21,0x80,0x65,0x00,0x06,
-0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,
-0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02,0x01,0x22,0x18,0x21,0x24,0x62,0x00,0x01,
-0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff,0x30,0x69,0x00,0xff,0x01,0x06,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x24,0xe7,0xff,0xff,0x94,0x46,0x00,0x02,
-0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0,0x91,0x82,0x00,0x10,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03,0xa5,0x8f,0x00,0x0c,0x03,0x0e,0x20,0x21,
-0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,
-0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21,0x27,0x26,0x82,0xe4,0x34,0x03,0xff,0xff,
-0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,
-0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10,0x91,0x83,0x00,0x04,0xa5,0x8e,0x00,0x0e,
-0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05,0xa1,0x82,0x00,0x10,0x91,0x82,0x00,0x16,
-0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa1,0x82,0x00,0x16,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e,0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0,
-0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,
-0x34,0xc6,0x00,0x20,0x27,0x27,0x82,0xe4,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x4d,0x10,0x21,0xac,0xc7,0x00,0x00,
-0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00,0xac,0xaf,0x00,0x00,0x08,0x00,0x1c,0x44,
-0x03,0x0e,0x20,0x21,0x08,0x00,0x1c,0x1f,0xa5,0x88,0x00,0x02,0x00,0x0e,0xc0,0xc0,
-0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8d,0x8f,0xf0,0x00,0x4d,0x10,0x21,
-0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff,0x14,0x80,0x00,0x05,0xa5,0x83,0x00,0x00,
-0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01,0x08,0x00,0x1c,0x1f,0xa5,0x82,0x00,0x02,
-0x08,0x00,0x1c,0x1f,0x3c,0x19,0x80,0x01,0x3c,0x08,0xb0,0x03,0x3c,0x02,0x80,0x00,
-0x27,0xbd,0xff,0x78,0x35,0x08,0x00,0x20,0x24,0x42,0x72,0x18,0xaf,0xb2,0x00,0x68,
-0xaf,0xb1,0x00,0x64,0xaf,0xb0,0x00,0x60,0xad,0x02,0x00,0x00,0xaf,0xbf,0x00,0x84,
-0xaf,0xbe,0x00,0x80,0xaf,0xb7,0x00,0x7c,0xaf,0xb6,0x00,0x78,0xaf,0xb5,0x00,0x74,
-0xaf,0xb4,0x00,0x70,0xaf,0xb3,0x00,0x6c,0xaf,0xa4,0x00,0x88,0x90,0x83,0x00,0x0a,
-0x27,0x82,0xb3,0xf0,0xaf,0xa6,0x00,0x90,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,
-0x8c,0x63,0x00,0x00,0xaf,0xa7,0x00,0x94,0x27,0x86,0x8f,0xf4,0xaf,0xa3,0x00,0x1c,
-0x94,0x63,0x00,0x14,0x30,0xb1,0xff,0xff,0x24,0x08,0x00,0x01,0x00,0x03,0x20,0xc0,
-0xaf,0xa3,0x00,0x18,0x00,0x83,0x18,0x21,0xaf,0xa4,0x00,0x54,0x00,0x03,0x18,0x80,
-0x27,0x84,0x90,0x00,0x00,0x64,0x20,0x21,0x80,0x82,0x00,0x06,0x00,0x66,0x18,0x21,
-0x8c,0x66,0x00,0x18,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x8c,0xc4,0x00,0x08,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0x04,0x2f,0xc2,
-0x00,0x04,0x1c,0x82,0x00,0xc2,0x38,0x21,0x00,0x04,0x24,0x42,0x8f,0xa2,0x00,0x1c,
-0x30,0x63,0x00,0x01,0x30,0x84,0x00,0x01,0xaf,0xa5,0x00,0x3c,0xaf,0xa3,0x00,0x34,
-0xaf,0xa4,0x00,0x38,0xaf,0xa0,0x00,0x40,0xaf,0xa0,0x00,0x44,0xaf,0xa0,0x00,0x50,
-0xaf,0xa8,0x00,0x20,0x80,0x42,0x00,0x12,0x8f,0xb2,0x00,0x18,0xaf,0xa2,0x00,0x28,
-0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xe4,0x00,0x60,0x30,0x21,0x00,0x10,0x10,0x82,
-0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11,0xaf,0xa0,0x00,0x30,0x8f,0xa4,0x00,0x98,
-0x27,0x82,0x80,0x1c,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x21,0x24,0xa2,0x00,0x06,
-0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00,0x00,0x45,0x10,0x04,0x00,0x44,0x00,0x1a,
-0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,
-0x24,0x42,0x00,0x20,0x30,0x42,0xff,0xfc,0xaf,0xa2,0x00,0x30,0x8f,0xa3,0x00,0x18,
-0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff,0xaf,0xa0,0x00,0x2c,0xaf,0xa2,0x00,0x48,
-0xaf,0xa3,0x00,0x4c,0x00,0x60,0xf0,0x21,0x00,0x00,0xb8,0x21,0x18,0x80,0x00,0x48,
-0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02,0xaf,0xb1,0x00,0x58,0x00,0x80,0xa8,0x21,
-0x00,0x12,0x10,0xc0,0x00,0x52,0x18,0x21,0x00,0x03,0x80,0x80,0x27,0x85,0x8f,0xf0,
-0x02,0x40,0x20,0x21,0x00,0x40,0xa0,0x21,0x02,0x05,0x10,0x21,0x94,0x56,0x00,0x02,
-0x0c,0x00,0x12,0x87,0x00,0x00,0x28,0x21,0x90,0x42,0x00,0x00,0x24,0x03,0x00,0x08,
-0x30,0x42,0x00,0x0c,0x10,0x43,0x01,0x9e,0x24,0x04,0x00,0x01,0x24,0x02,0x00,0x01,
-0x10,0x82,0x01,0x7c,0x3c,0x02,0xb0,0x03,0x8f,0xa6,0x00,0x88,0x34,0x42,0x01,0x04,
-0x84,0xc5,0x00,0x0c,0x02,0x92,0x18,0x21,0x94,0x46,0x00,0x00,0x00,0x05,0x20,0xc0,
-0x00,0x85,0x20,0x21,0x00,0x03,0x18,0x80,0x27,0x82,0x90,0x00,0x27,0x85,0x8f,0xf8,
-0x00,0x65,0x28,0x21,0x00,0x62,0x18,0x21,0x80,0x71,0x00,0x05,0x80,0x73,0x00,0x04,
-0x8f,0xa3,0x00,0x88,0x30,0xd0,0xff,0xff,0x00,0x10,0x3a,0x03,0x32,0x08,0x00,0xff,
-0x27,0x82,0x90,0x10,0x00,0x04,0x20,0x80,0x80,0xa6,0x00,0x06,0x00,0x82,0x20,0x21,
-0xa4,0x67,0x00,0x44,0xa4,0x68,0x00,0x46,0x8c,0x84,0x00,0x00,0x38,0xc6,0x00,0x00,
-0x01,0x00,0x80,0x21,0x00,0x04,0x15,0x02,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x03,
-0x00,0xe6,0x80,0x0a,0x00,0x04,0x14,0x02,0x30,0x50,0x00,0x0f,0x12,0x20,0x01,0x50,
-0x02,0x40,0x20,0x21,0x02,0x71,0x10,0x21,0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xed,
-0x02,0x92,0x10,0x21,0x93,0x82,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,
-0x14,0x40,0x00,0xe0,0x02,0x92,0x28,0x21,0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff,
-0x02,0x40,0xf0,0x21,0x26,0xb5,0xff,0xff,0x16,0xa0,0xff,0xbd,0x02,0xc0,0x90,0x21,
-0x16,0xe0,0x00,0xd0,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x98,0x00,0x00,0x00,0x00,
-0x2c,0x62,0x00,0x10,0x10,0x40,0x00,0x2e,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x24,
-0x00,0x00,0x00,0x00,0x18,0x80,0x00,0x2a,0x24,0x03,0x00,0x01,0x8f,0xa5,0x00,0x1c,
-0x27,0x84,0x8f,0xf4,0x94,0xb2,0x00,0x14,0xa0,0xa3,0x00,0x12,0x8f,0xa6,0x00,0x3c,
-0x00,0x12,0x10,0xc0,0x00,0x52,0x10,0x21,0x00,0x02,0x80,0x80,0x27,0x82,0x90,0x00,
-0x02,0x02,0x10,0x21,0x80,0x43,0x00,0x06,0x02,0x04,0x20,0x21,0x8c,0x85,0x00,0x18,
-0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,
-0x00,0x03,0x18,0x40,0x14,0xc0,0x00,0x0e,0x00,0xa3,0x38,0x21,0x27,0x82,0x8f,0xf0,
-0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x8f,0xa8,0x00,0x1c,0x24,0x02,0x00,0x01,
-0xa5,0x03,0x00,0x1a,0x7b,0xbe,0x04,0x3c,0x7b,0xb6,0x03,0xfc,0x7b,0xb4,0x03,0xbc,
-0x7b,0xb2,0x03,0x7c,0x7b,0xb0,0x03,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x88,
-0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10,
-0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1d,0x4b,0x00,0x00,0x00,0x00,
-0x8f,0xa3,0x00,0x44,0x93,0x82,0x81,0x59,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x61,
-0x30,0x69,0x00,0x03,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x28,0x00,0x00,0x00,0x00,
-0x00,0x85,0x10,0x2a,0x10,0x40,0x00,0x8f,0x00,0x00,0x00,0x00,0x8f,0xa6,0x00,0x1c,
-0x00,0x00,0x00,0x00,0x90,0xc4,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,
-0x00,0xa3,0x10,0x2a,0x10,0x40,0x00,0x87,0x00,0x00,0x00,0x00,0x8f,0xa8,0x00,0x24,
-0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x83,0x00,0x65,0x10,0x23,0x00,0xa8,0x18,0x23,
-0x00,0x62,0x10,0x2a,0x14,0x40,0x00,0x7d,0x30,0x63,0x00,0xff,0x00,0x85,0x10,0x23,
-0x30,0x42,0x00,0xff,0xaf,0xa2,0x00,0x50,0x8f,0xa2,0x00,0x50,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x73,0x00,0x00,0xa8,0x21,0x27,0x8c,0x8f,0xf0,0x3c,0x0b,0x80,0xff,
-0x24,0x10,0x00,0x04,0x27,0x91,0x8f,0xf4,0x35,0x6b,0xff,0xff,0x3c,0x0d,0x7f,0x00,
-0x27,0x8e,0x90,0x00,0x01,0x80,0x78,0x21,0x00,0x12,0x30,0xc0,0x00,0xd2,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa3,0x00,0x2c,
-0x8f,0xa4,0x00,0x30,0xaf,0xa2,0x00,0x44,0x8f,0xa5,0x00,0x44,0x30,0x49,0x00,0x03,
-0x02,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x00,0xa2,0x10,0x21,0x8f,0xa8,0x00,0x30,
-0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,0x00,0x64,0x38,0x21,0x01,0x02,0x28,0x23,
-0x00,0x62,0x18,0x21,0x00,0x48,0x10,0x2b,0x10,0x40,0x00,0x52,0x00,0x00,0x20,0x21,
-0x30,0xe7,0xff,0xff,0x30,0xa4,0xff,0xff,0xaf,0xa7,0x00,0x2c,0x00,0xd2,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x51,0x18,0x21,0x8c,0x65,0x00,0x18,0x00,0x04,0x25,0x40,
-0x00,0x8d,0x20,0x24,0x8c,0xa8,0x00,0x04,0x00,0x4e,0x18,0x21,0x00,0x4f,0x50,0x21,
-0x01,0x0b,0x40,0x24,0x01,0x04,0x40,0x25,0xac,0xa8,0x00,0x04,0x8f,0xa4,0x00,0x98,
-0x8f,0xa2,0x00,0x50,0x26,0xb5,0x00,0x01,0xa0,0x64,0x00,0x00,0x8c,0xa4,0x00,0x08,
-0x00,0x00,0x00,0x00,0x04,0x81,0x00,0x0c,0x02,0xa2,0x30,0x2a,0x80,0x62,0x00,0x06,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xa2,0x38,0x21,0x8f,0xa5,0x00,0x40,
-0x00,0x00,0x00,0x00,0xa4,0xe5,0x00,0x00,0x95,0x52,0x00,0x02,0x14,0xc0,0xff,0xc7,
-0x00,0x12,0x30,0xc0,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x50,0x8f,0xa6,0x00,0x1c,
-0x8f,0xa3,0x00,0x2c,0x00,0x85,0x80,0x21,0xa0,0xd0,0x00,0x12,0x00,0x09,0x10,0x23,
-0x30,0x42,0x00,0x03,0x8f,0xa8,0x00,0x88,0x00,0x62,0x10,0x23,0xa4,0xc2,0x00,0x1a,
-0x85,0x03,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x80,0x27,0x83,0x8f,0xf4,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,
-0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,
-0x14,0x60,0xff,0x74,0x02,0x00,0x10,0x21,0x8f,0xa3,0x00,0x54,0x8f,0xa4,0x00,0x18,
-0x8f,0xa5,0x00,0x24,0x00,0x64,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x08,
-0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x10,0xa0,0x00,0x03,0x00,0x00,0x30,0x21,
-0x08,0x00,0x1d,0x51,0x02,0x00,0x10,0x21,0x93,0x82,0x80,0x10,0x00,0x00,0x28,0x21,
-0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0xf5,0xaf,0xa2,0x00,0x10,0x08,0x00,0x1d,0x51,
-0x02,0x00,0x10,0x21,0x30,0x63,0xff,0xff,0x08,0x00,0x1d,0xa3,0xaf,0xa3,0x00,0x2c,
-0x8f,0xa8,0x00,0x44,0x08,0x00,0x1d,0xc5,0x31,0x09,0x00,0x03,0x08,0x00,0x1d,0x7e,
-0xaf,0xa3,0x00,0x50,0x8f,0xa6,0x00,0x44,0xaf,0xa0,0x00,0x50,0x08,0x00,0x1d,0xc5,
-0x30,0xc9,0x00,0x03,0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,
-0x03,0xc0,0x38,0x21,0x0c,0x00,0x1b,0xf6,0xaf,0xb7,0x00,0x10,0x08,0x00,0x1d,0x2e,
-0x00,0x00,0x00,0x00,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf0,0x00,0xa2,0x28,0x21,
-0x00,0x00,0x20,0x21,0x0c,0x00,0x01,0x4b,0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x27,
-0x26,0xe2,0x00,0x01,0x00,0x02,0x80,0x80,0x27,0x83,0x90,0x00,0x8f,0xa4,0x00,0x1c,
-0x02,0x03,0x18,0x21,0x26,0x31,0x00,0x01,0x02,0x40,0x28,0x21,0x0c,0x00,0x1f,0x08,
-0xa0,0x71,0x00,0x05,0x14,0x40,0xff,0x13,0x00,0x00,0x00,0x00,0x16,0xe0,0x00,0x4d,
-0x03,0xc0,0x38,0x21,0x8f,0xa4,0x00,0x24,0x8f,0xa5,0x00,0x20,0x24,0x02,0x00,0x01,
-0x24,0x84,0x00,0x01,0xaf,0xb2,0x00,0x48,0xaf,0xb6,0x00,0x4c,0x02,0xc0,0xf0,0x21,
-0x10,0xa2,0x00,0x41,0xaf,0xa4,0x00,0x24,0x27,0x82,0x8f,0xf0,0x02,0x02,0x10,0x21,
-0x94,0x42,0x00,0x06,0x8f,0xa4,0x00,0x30,0xaf,0xa0,0x00,0x20,0xaf,0xa2,0x00,0x44,
-0x30,0x49,0x00,0x03,0x8f,0xa8,0x00,0x44,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,
-0x01,0x02,0x10,0x21,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff,0x00,0x44,0x18,0x2b,
-0x10,0x60,0x00,0x2b,0x00,0x00,0x00,0x00,0x8f,0xa5,0x00,0x2c,0x00,0x82,0x10,0x23,
-0x00,0xa4,0x18,0x21,0x30,0x63,0xff,0xff,0x30,0x44,0xff,0xff,0xaf,0xa3,0x00,0x2c,
-0x02,0x92,0x28,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x8f,0xf4,0x00,0xa2,0x10,0x21,
-0x8c,0x46,0x00,0x18,0x3c,0x03,0x80,0xff,0x3c,0x02,0x7f,0x00,0x8c,0xc8,0x00,0x04,
-0x00,0x04,0x25,0x40,0x34,0x63,0xff,0xff,0x00,0x82,0x20,0x24,0x01,0x03,0x40,0x24,
-0x01,0x04,0x40,0x25,0xac,0xc8,0x00,0x04,0x8f,0xa8,0x00,0x98,0x27,0x82,0x90,0x00,
-0x00,0xa2,0x10,0x21,0xa0,0x48,0x00,0x00,0x8c,0xc4,0x00,0x08,0x00,0x00,0x00,0x00,
-0x00,0x04,0x27,0xc2,0x10,0x80,0xfe,0xdb,0xaf,0xa4,0x00,0x3c,0x80,0x42,0x00,0x06,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xc2,0x38,0x21,0x8f,0xa2,0x00,0x40,
-0x00,0x00,0x00,0x00,0xa4,0xe2,0x00,0x00,0x08,0x00,0x1d,0x2a,0x26,0xb5,0xff,0xff,
-0x8f,0xa6,0x00,0x2c,0x00,0x00,0x20,0x21,0x00,0xc2,0x10,0x21,0x30,0x42,0xff,0xff,
-0x08,0x00,0x1e,0x38,0xaf,0xa2,0x00,0x2c,0x8f,0xa6,0x00,0x1c,0x08,0x00,0x1e,0x22,
-0xa4,0xd2,0x00,0x14,0x8f,0xa5,0x00,0x48,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,
-0x0c,0x00,0x1b,0xf6,0xaf,0xb7,0x00,0x10,0x08,0x00,0x1e,0x19,0x00,0x00,0xb8,0x21,
-0x0c,0x00,0x12,0x87,0x00,0x00,0x28,0x21,0x00,0x40,0x18,0x21,0x94,0x42,0x00,0x00,
-0x00,0x00,0x00,0x00,0x34,0x42,0x08,0x00,0xa4,0x62,0x00,0x00,0x08,0x00,0x1d,0x1e,
-0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21,0x00,0x03,0x80,0x80,0x27,0x82,0x8f,0xf4,
-0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,
-0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x10,0x60,0x00,0x09,0x24,0x06,0x00,0x01,
-0x93,0x82,0x8b,0x61,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xa2,
-0x3c,0x04,0x00,0x80,0x27,0x85,0x8f,0xf0,0x08,0x00,0x1e,0x09,0x02,0x05,0x28,0x21,
-0x27,0x83,0x90,0x08,0x27,0x82,0x90,0x00,0x02,0x03,0x18,0x21,0x02,0x02,0x10,0x21,
-0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05,0x93,0x83,0x80,0x10,0x00,0x00,0x38,0x21,
-0x0c,0x00,0x21,0xf5,0xaf,0xa3,0x00,0x10,0x08,0x00,0x1e,0x80,0x00,0x00,0x00,0x00,
-0x27,0x82,0x90,0x08,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x02,0x8f,0xa6,0x00,0x58,
-0x00,0x03,0x19,0x02,0x00,0x66,0x18,0x23,0x30,0x63,0x0f,0xff,0x28,0x62,0x00,0x20,
-0x10,0x40,0x00,0x06,0x28,0x62,0x00,0x40,0x8f,0xa8,0x00,0x90,0x00,0x00,0x00,0x00,
-0x00,0x68,0x10,0x06,0x08,0x00,0x1c,0xf7,0x30,0x44,0x00,0x01,0x10,0x40,0x00,0x04,
-0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x94,0x08,0x00,0x1e,0xa1,0x00,0x64,0x10,0x06,
-0x08,0x00,0x1c,0xf7,0x00,0x00,0x20,0x21,0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,
-0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa8,0x00,0x14,0x30,0x42,0xff,0xff,
-0x08,0x00,0x1c,0xc7,0xaf,0xa2,0x00,0x40,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,
-0x27,0xbd,0xff,0xe0,0x34,0x42,0x00,0x20,0x24,0x63,0x7a,0xc8,0xaf,0xb1,0x00,0x14,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a,
-0x00,0x80,0x80,0x21,0x14,0x40,0x00,0x45,0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04,
-0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3c,0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18,
-0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc,
-0x10,0xa0,0x00,0x03,0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,
-0x92,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05,
-0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,
-0xa2,0x02,0x00,0x16,0x10,0x60,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x00,0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14,
-0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x01,0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17,
-0x08,0x00,0x1e,0xdc,0xa6,0x03,0x00,0x14,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,
-0x27,0x86,0x8f,0xf0,0x00,0x04,0x10,0xc0,0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21,
-0x00,0x65,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,
-0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x0c,0x00,0x12,0x78,
-0x00,0x00,0x00,0x00,0x30,0x43,0x00,0xff,0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17,
-0x96,0x02,0x00,0x06,0x08,0x00,0x1e,0xdc,0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00,
-0x08,0x00,0x1e,0xdc,0xa6,0x02,0x00,0x14,0x96,0x05,0x00,0x00,0x0c,0x00,0x1f,0x08,
-0x02,0x00,0x20,0x21,0x08,0x00,0x1e,0xc3,0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06,
-0x0c,0x00,0x1f,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x1e,0xbf,0x00,0x40,0x88,0x21,
-0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x7c,0x20,
-0x27,0xbd,0xff,0xf0,0xac,0x62,0x00,0x00,0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x10,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,
-0x24,0x42,0x7c,0x44,0xac,0x62,0x00,0x00,0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21,
-0x11,0x20,0x00,0x05,0x00,0xa0,0x50,0x21,0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x1b,0x00,0x00,0x00,0x00,0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00,
-0x10,0xe0,0x00,0x1b,0x00,0x00,0x00,0x00,0x94,0xc8,0x00,0x00,0x27,0x83,0x8f,0xf0,
-0x93,0x85,0x8b,0x60,0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08,0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06,
-0x01,0x44,0x18,0x23,0x8f,0x82,0x8b,0x78,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b,
-0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14,
-0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21,0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00,
-0x94,0xc2,0x00,0x06,0x24,0x03,0x00,0x08,0x08,0x00,0x1f,0x34,0xa4,0xc2,0x00,0x14,
-0x08,0x00,0x1f,0x34,0x00,0x00,0x18,0x21,0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c,
-0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30,
-0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21,
-0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20,
-0x24,0x42,0x7c,0xf8,0x02,0xb1,0x48,0x21,0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80,
-0x24,0x03,0x00,0x01,0x27,0x82,0x90,0x00,0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21,
-0x27,0x84,0x8f,0xf4,0x01,0x24,0x20,0x21,0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18,
-0x27,0x83,0x90,0x10,0x01,0x23,0x48,0x21,0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02,
-0x8d,0x42,0x00,0x00,0x8d,0x49,0x00,0x04,0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08,
-0x01,0x02,0x40,0x21,0x00,0x04,0x25,0xc2,0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01,
-0x00,0x03,0x1f,0xc2,0x00,0x08,0x40,0x40,0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24,
-0x00,0x09,0x49,0x42,0x01,0x48,0x10,0x21,0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21,
-0x00,0x40,0x38,0x21,0x02,0x00,0x28,0x21,0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01,
-0x94,0x42,0x00,0x00,0x02,0xb1,0x88,0x21,0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80,
-0x27,0x90,0x8f,0xf0,0x02,0x30,0x80,0x21,0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff,
-0x02,0x60,0x20,0x21,0x00,0x60,0x30,0x21,0xa6,0x83,0x00,0x1a,0x27,0x82,0x8f,0xf8,
-0x0c,0x00,0x08,0xdf,0x02,0x22,0x88,0x21,0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06,
-0xa6,0x22,0x00,0x04,0x8f,0xbf,0x00,0x30,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,
-0x7b,0xb0,0x00,0xfc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,
-0xaf,0xa9,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0x72,
-0x02,0xb1,0x88,0x21,0x27,0xbd,0xff,0xc0,0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,
-0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,
-0xaf,0xbf,0x00,0x3c,0xaf,0xb4,0x00,0x28,0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18,
-0x94,0x90,0x00,0x00,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0,
-0x00,0x50,0x18,0x21,0x00,0x40,0x88,0x21,0x3c,0x02,0x80,0x00,0x00,0x03,0x48,0x80,
-0x24,0x42,0x7e,0x34,0x00,0x80,0x98,0x21,0x27,0x84,0x90,0x00,0x01,0x24,0x20,0x21,
-0x93,0xb7,0x00,0x53,0xad,0x02,0x00,0x00,0x80,0x83,0x00,0x06,0x27,0x82,0x8f,0xf4,
-0x01,0x22,0x10,0x21,0x8c,0x44,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,
-0x8c,0x88,0x00,0x08,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,
-0xaf,0xa7,0x00,0x4c,0x2c,0xa2,0x00,0x10,0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21,
-0x00,0x08,0x47,0xc2,0x00,0xc0,0x58,0x21,0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c,
-0x14,0x40,0x00,0x13,0x00,0x00,0xf0,0x21,0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01,
-0x12,0x87,0x00,0x10,0x02,0x30,0x10,0x21,0x27,0x83,0x90,0x08,0x01,0x23,0x18,0x21,
-0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x60,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,
-0x90,0x44,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00,
-0x02,0x30,0x10,0x21,0x00,0x02,0x80,0x80,0x24,0x04,0x00,0x01,0x27,0x83,0x90,0x10,
-0xa2,0x64,0x00,0x12,0x02,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e,
-0x02,0xa0,0x20,0x21,0x27,0x82,0x8f,0xf0,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,
-0x00,0x00,0x00,0x00,0xa6,0x63,0x00,0x1a,0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc,
-0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21,
-0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x06,0xaf,0xa0,0x00,0x14,
-0x08,0x00,0x1f,0xd9,0x00,0x00,0x00,0x00,0x27,0x83,0x90,0x10,0x01,0x23,0x18,0x21,
-0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,
-0x01,0x02,0x10,0x24,0x14,0x40,0x00,0xaf,0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03,
-0x00,0x12,0x10,0x82,0x25,0xe3,0x00,0x0d,0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04,
-0x10,0xa0,0x00,0x0e,0x00,0x00,0x90,0x21,0x27,0x82,0x80,0x1c,0x00,0x15,0x18,0x40,
-0x00,0x62,0x18,0x21,0x94,0x64,0x00,0x00,0x24,0xa2,0x00,0x06,0x00,0x54,0x10,0x04,
-0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,
-0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21,
-0x27,0x83,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03,
-0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04,
-0x2c,0x62,0x00,0x19,0x30,0x82,0x00,0x0f,0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19,
-0x10,0x40,0x00,0x19,0x24,0x0e,0x00,0x20,0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02,
-0x14,0x40,0x00,0x15,0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02,
-0x14,0x40,0x00,0x11,0x24,0x0e,0x00,0x08,0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e,
-0x24,0x0e,0x00,0x02,0x24,0x62,0xff,0xef,0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,
-0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xf1,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06,
-0x24,0x0e,0x00,0x08,0x24,0x62,0xff,0xf3,0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x04,
-0x24,0x03,0x00,0x02,0x00,0x62,0x70,0x0a,0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21,
-0x00,0x00,0x68,0x21,0x10,0x40,0x00,0x6d,0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff,
-0x27,0x99,0x8f,0xf0,0x01,0xf2,0xc0,0x23,0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a,
-0x14,0x40,0x00,0x64,0x24,0x03,0x00,0x04,0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21,
-0x00,0x02,0x10,0x80,0x00,0x59,0x10,0x21,0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00,
-0x32,0xcc,0x00,0x03,0x00,0x6c,0x10,0x23,0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21,
-0x24,0x42,0x00,0x04,0x30,0x51,0xff,0xff,0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d,
-0x01,0xf1,0x10,0x23,0x02,0x51,0x10,0x23,0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34,
-0x30,0x44,0xff,0xff,0x29,0x22,0x00,0x40,0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21,
-0x25,0x22,0x00,0x01,0x00,0x02,0x16,0x00,0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21,
-0x00,0x02,0x30,0x80,0x27,0x82,0x8f,0xf4,0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21,
-0x8c,0x67,0x00,0x18,0x00,0x04,0x25,0x40,0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04,
-0x00,0x83,0x20,0x24,0x27,0x83,0x90,0x00,0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21,
-0x00,0x44,0x10,0x25,0xac,0xe2,0x00,0x04,0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00,
-0xa0,0xb5,0x00,0x03,0x27,0x84,0x90,0x10,0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00,
-0x8c,0xe8,0x00,0x08,0x00,0x02,0x15,0xc2,0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01,
-0x01,0x02,0x10,0x24,0x10,0x40,0x00,0x0a,0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06,
-0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,
-0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40,0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00,
-0x92,0x62,0x00,0x04,0x25,0xad,0x00,0x01,0x27,0x84,0x8f,0xf0,0x00,0xc4,0x18,0x21,
-0x01,0xa2,0x10,0x2a,0x94,0x70,0x00,0x02,0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00,
-0x96,0x63,0x00,0x14,0x00,0x0c,0x10,0x23,0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03,
-0x01,0x62,0x10,0x23,0x00,0x03,0x80,0xc0,0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff,
-0x02,0x03,0x80,0x21,0x27,0x82,0x8f,0xf8,0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a,
-0x02,0xa0,0x20,0x21,0x01,0x60,0x30,0x21,0x01,0x60,0x88,0x21,0x0c,0x00,0x08,0xdf,
-0x02,0x02,0x80,0x21,0x00,0x5e,0x10,0x21,0xa6,0x02,0x00,0x04,0x08,0x00,0x1f,0xdf,
-0x02,0x20,0x10,0x21,0x01,0x62,0x10,0x2b,0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21,
-0x29,0x22,0x00,0x40,0x10,0x40,0xff,0xe6,0x01,0x71,0x18,0x21,0x08,0x00,0x20,0x55,
-0x25,0x22,0x00,0x01,0x08,0x00,0x20,0x84,0x32,0xcc,0x00,0x03,0x08,0x00,0x20,0x84,
-0x00,0x00,0x60,0x21,0x8f,0xa5,0x00,0x4c,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,
-0x0c,0x00,0x09,0x06,0xaf,0xb4,0x00,0x14,0x92,0x67,0x00,0x04,0x08,0x00,0x1f,0xf7,
-0x30,0x5e,0xff,0xff,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21,
-0x00,0x04,0x20,0x80,0x27,0x82,0x8f,0xf0,0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff,
-0x00,0x82,0x20,0x21,0x00,0xc3,0x30,0x21,0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08,
-0xa4,0x85,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21,
-0x27,0x88,0x8f,0xf0,0x00,0x06,0x30,0x80,0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04,
-0x3c,0x02,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x82,0x20,0x21,0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff,
-0x00,0x68,0x18,0x21,0x34,0xe7,0x00,0x20,0x24,0x42,0x82,0xe4,0xac,0xe2,0x00,0x00,
-0xa4,0xc5,0x00,0x02,0xa4,0x65,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0x83,0x40,
-0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x3c,0x08,0xb0,0x03,0x3c,0x09,0xb0,0x06,
-0x27,0x87,0x8f,0xf0,0x3c,0x0d,0xb0,0x08,0x34,0x0e,0xff,0xff,0x35,0x08,0x00,0x62,
-0x00,0x80,0x30,0x21,0x24,0x0c,0xff,0xff,0x10,0x40,0x00,0x2c,0x35,0x29,0x80,0x20,
-0x97,0x82,0x8f,0xe0,0x94,0x85,0x00,0x0c,0x3c,0x0b,0xb0,0x03,0x00,0x02,0x18,0xc0,
-0x00,0x62,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0xa4,0x45,0x00,0x00,
-0x94,0x84,0x00,0x0e,0x00,0x6d,0x18,0x21,0xac,0x65,0x00,0x00,0x00,0x04,0x10,0xc0,
-0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0x94,0x45,0x00,0x04,
-0x3c,0x0a,0x77,0x77,0x35,0x6b,0x00,0xb4,0x00,0x05,0x10,0xc0,0x00,0x45,0x18,0x21,
-0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0x00,0x4d,0x10,0x21,0xac,0x4e,0x00,0x00,
-0xa4,0x6e,0x00,0x00,0x95,0x04,0x00,0x00,0x90,0xc3,0x00,0x10,0x24,0x02,0x00,0xff,
-0x00,0x44,0x10,0x23,0x00,0x43,0x10,0x2a,0xa7,0x85,0x8f,0xe0,0x10,0x40,0x00,0x04,
-0x35,0x4a,0x88,0x88,0xad,0x6a,0x00,0x00,0x90,0xc3,0x00,0x10,0x00,0x00,0x00,0x00,
-0x30,0x63,0x00,0xff,0x3c,0x02,0x00,0x40,0x00,0x62,0x18,0x25,0xad,0x23,0x00,0x00,
-0xa4,0xcc,0x00,0x0e,0xa4,0xcc,0x00,0x0c,0xa0,0xc0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,
-0x27,0x89,0x8f,0xf0,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21,0x97,0x83,0x8f,0xe0,
-0x94,0x4a,0x00,0x04,0x3c,0x02,0xb0,0x08,0x00,0x03,0x38,0xc0,0x00,0x0a,0x40,0xc0,
-0x00,0xe3,0x18,0x21,0x01,0x0a,0x28,0x21,0x00,0xe2,0x38,0x21,0x01,0x02,0x40,0x21,
-0x00,0x03,0x18,0x80,0x00,0x05,0x28,0x80,0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x01,
-0x00,0xa9,0x28,0x21,0x00,0x69,0x18,0x21,0x34,0xc6,0x00,0x20,0x34,0x09,0xff,0xff,
-0x24,0x42,0x84,0x34,0xac,0xc2,0x00,0x00,0xa4,0x64,0x00,0x00,0xac,0xe4,0x00,0x00,
-0xa4,0xa9,0x00,0x00,0xad,0x09,0x00,0x00,0xa7,0x8a,0x8f,0xe0,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,
-0x24,0x42,0x84,0xb4,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x01,0x10,
-0x8c,0x82,0x00,0x00,0x97,0x83,0x81,0x60,0x30,0x42,0xff,0xff,0x10,0x62,0x00,0x16,
-0x24,0x0a,0x00,0x01,0xa7,0x82,0x81,0x60,0xaf,0x80,0xb4,0x40,0x00,0x40,0x28,0x21,
-0x24,0x06,0x00,0x01,0x27,0x84,0xb4,0x44,0x25,0x43,0xff,0xff,0x00,0x66,0x10,0x04,
-0x00,0xa2,0x10,0x24,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x8c,0x83,0xff,0xfc,
-0x00,0x00,0x00,0x00,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x38,0x42,0x00,0x00,
-0x01,0x42,0x18,0x0a,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x14,0xac,0x83,0x00,0x00,
-0x14,0x40,0xff,0xf1,0x24,0x84,0x00,0x04,0x3c,0x0b,0xb0,0x03,0x00,0x00,0x50,0x21,
-0x3c,0x0c,0x80,0x00,0x27,0x89,0xb4,0x90,0x35,0x6b,0x01,0x20,0x8d,0x68,0x00,0x00,
-0x8d,0x23,0x00,0x04,0x01,0x0c,0x10,0x24,0x00,0x02,0x17,0xc2,0x11,0x03,0x00,0x37,
-0xa1,0x22,0x00,0xdc,0xa1,0x20,0x00,0xd5,0xa1,0x20,0x00,0xd6,0x01,0x20,0x30,0x21,
-0x00,0x00,0x38,0x21,0x00,0x00,0x28,0x21,0x01,0x20,0x20,0x21,0x00,0xa8,0x10,0x06,
-0x30,0x42,0x00,0x01,0x10,0xe0,0x00,0x10,0xa0,0x82,0x00,0x0a,0x90,0x82,0x00,0x07,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x31,0x24,0xa2,0xff,0xff,0xa0,0x82,0x00,0x08,
-0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09,0x00,0x00,0x00,0x00,
-0x90,0x83,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x40,0x00,0x43,0x10,0x21,
-0x00,0x46,0x10,0x21,0xa0,0x45,0x00,0x09,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x04,0x00,0x00,0x00,0x00,
-0xa0,0xc5,0x00,0xd5,0x24,0x07,0x00,0x01,0xa0,0x85,0x00,0x08,0xa0,0xc5,0x00,0xd6,
-0x24,0xa5,0x00,0x01,0x2c,0xa2,0x00,0x1c,0x14,0x40,0xff,0xe0,0x24,0x84,0x00,0x03,
-0x90,0xc4,0x00,0xd5,0x00,0x00,0x28,0x21,0x00,0xa4,0x10,0x2b,0x10,0x40,0x00,0x0b,
-0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0x21,0xa0,0x64,0x00,0x08,0x90,0xc2,0x00,0xd5,
-0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x09,0x90,0xc4,0x00,0xd5,0x00,0x00,0x00,0x00,
-0x00,0xa4,0x10,0x2b,0x14,0x40,0xff,0xf8,0x24,0x63,0x00,0x03,0x25,0x4a,0x00,0x01,
-0x2d,0x42,0x00,0x08,0xad,0x28,0x00,0x04,0x25,0x6b,0x00,0x04,0x14,0x40,0xff,0xbf,
-0x25,0x29,0x00,0xec,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x05,
-0x08,0x00,0x21,0x68,0xa0,0x82,0x00,0x08,0x97,0x85,0x8b,0x6a,0x3c,0x03,0xb0,0x03,
-0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0x86,0x68,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00,0x30,0x90,0x00,0xff,
-0x00,0x05,0x28,0x42,0x00,0x00,0x48,0x21,0x27,0x8f,0xb4,0x94,0x00,0x00,0x50,0x21,
-0x00,0x00,0x58,0x21,0x27,0x98,0xb5,0x74,0x27,0x99,0xb5,0x70,0x27,0x8e,0xb5,0x6e,
-0x27,0x8c,0xb4,0x98,0x27,0x8d,0xb4,0xf0,0x27,0x88,0xb5,0x68,0x00,0x0a,0x18,0x80,
-0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00,0xac,0x45,0x00,0x58,0x00,0x6e,0x20,0x21,
-0x00,0x78,0x10,0x21,0xa1,0x00,0xff,0xfc,0xad,0x00,0x00,0x00,0xa1,0x00,0x00,0x04,
-0xa1,0x00,0x00,0x05,0xad,0x00,0xff,0xf8,0x00,0x79,0x18,0x21,0x24,0x06,0x00,0x01,
-0x24,0xc6,0xff,0xff,0xa0,0x80,0x00,0x00,0xa4,0x60,0x00,0x00,0xac,0x40,0x00,0x00,
-0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04,0x04,0xc1,0xff,0xf9,0x24,0x84,0x00,0x01,
-0x00,0x0a,0x10,0x80,0x00,0x4d,0x20,0x21,0x00,0x00,0x30,0x21,0x00,0x4c,0x18,0x21,
-0x27,0x87,0x81,0x64,0x8c,0xe2,0x00,0x00,0x24,0xe7,0x00,0x04,0xac,0x82,0x00,0x00,
-0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01,0x24,0xc6,0x00,0x01,0x28,0xc2,0x00,0x1c,
-0xa0,0x60,0x00,0x02,0x24,0x84,0x00,0x04,0x14,0x40,0xff,0xf6,0x24,0x63,0x00,0x03,
-0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x08,0x25,0x4a,0x00,0x3b,0x25,0x08,0x00,0xec,
-0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec,0xa7,0x80,0x81,0x60,0x00,0x00,0x48,0x21,
-0x27,0x83,0xb4,0x40,0xac,0x69,0x00,0x00,0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x0c,
-0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04,0x0c,0x00,0x21,0x2d,0x00,0x00,0x00,0x00,
-0x2e,0x04,0x00,0x14,0x27,0x83,0xb4,0x90,0x24,0x09,0x00,0x07,0x10,0x80,0x00,0x0a,
-0x00,0x00,0x00,0x00,0x90,0x62,0x00,0xd5,0x25,0x29,0xff,0xff,0xa0,0x62,0x00,0x00,
-0x05,0x21,0xff,0xfa,0x24,0x63,0x00,0xec,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x90,0x62,0x00,0xd6,0x08,0x00,0x21,0xeb,
-0x25,0x29,0xff,0xff,0x30,0x84,0x00,0xff,0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,
-0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb4,0x90,
-0x00,0x43,0x60,0x21,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x84,0x00,0x20,
-0x24,0x42,0x87,0xd4,0x30,0xc6,0x00,0xff,0x93,0xa9,0x00,0x13,0x30,0xa5,0x00,0xff,
-0x30,0xe7,0x00,0xff,0xac,0x82,0x00,0x00,0x10,0xc0,0x00,0xeb,0x25,0x8f,0x00,0xd0,
-0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xfc,0x2c,0x43,0x00,0x18,
-0x10,0x60,0x00,0xcf,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80,0x24,0x63,0x02,0x5c,
-0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,
-0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x2d,0x10,0x40,0x00,0x14,0x00,0x00,0x00,0x00,
-0x10,0xa0,0x00,0x0f,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x09,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xd0,0x03,0xe0,0x00,0x08,
-0xad,0x82,0x00,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xe0,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0x00,0x01,0x10,0xa0,0x00,0x0f,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xf9,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x07,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0xf0,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,
-0x24,0x42,0xff,0xe8,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x22,0x23,0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xfc,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0xf4,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xef,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xf8,0x2d,0x22,0x00,0x19,
-0x14,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xec,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0xe4,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xf0,0x2d,0x22,0x00,0x1b,
-0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdc,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc6,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x14,0xa2,0xff,0xce,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,
-0x24,0x42,0xff,0xf4,0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xce,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc9,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x34,
-0x24,0x02,0x00,0x03,0x2d,0x22,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xaf,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xbd,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0x9f,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,
-0x2d,0x22,0x00,0x25,0x10,0x40,0xff,0xc8,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa0,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x97,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x80,
-0x24,0x02,0x00,0x03,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xfc,
-0x2d,0x22,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa3,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x9b,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xa8,
-0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0x23,0x24,0x42,0xff,0xfa,
-0x10,0xa0,0xff,0x96,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x80,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x8e,0x00,0x00,0x00,0x00,
-0x08,0x00,0x22,0x48,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x17,0x14,0x40,0xff,0x9e,
-0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x97,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x19,
-0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x84,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x7c,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x89,0x00,0x00,0x00,0x00,
-0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xb4,0x2d,0x22,0x00,0x1b,
-0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x73,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5d,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x6b,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x88,
-0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x25,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x23,
-0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x4e,0x00,0x00,0x00,0x00,
-0x08,0x00,0x22,0x4c,0x2d,0x22,0x00,0x25,0x08,0x00,0x22,0x85,0x2d,0x22,0x00,0x27,
-0x10,0xa0,0xff,0x5e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x48,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x56,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x91,0x00,0x00,0x00,0x00,
-0x2d,0x22,0x00,0x27,0x14,0x40,0xff,0x8e,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x3e,
-0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x29,0x14,0x40,0xff,0x89,0x00,0x00,0x00,0x00,
-0x08,0x00,0x22,0x2b,0x00,0x00,0x00,0x00,0x91,0x86,0x00,0x00,0x91,0x83,0x00,0xd4,
-0x25,0x8d,0x00,0x5c,0x30,0xc4,0x00,0xff,0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21,
-0x00,0x04,0x50,0x80,0x01,0x82,0x58,0x21,0x01,0x8a,0x40,0x21,0x25,0x78,0x00,0x08,
-0x10,0x60,0x00,0x37,0x25,0x0e,0x00,0x60,0x2c,0xa2,0x00,0x03,0x14,0x40,0x00,0x25,
-0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e,
-0x00,0x00,0x00,0x00,0x27,0x87,0x81,0x64,0x01,0x47,0x10,0x21,0x8c,0x43,0x00,0x00,
-0x00,0x00,0x00,0x00,0xad,0x03,0x00,0x60,0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00,
-0x00,0x40,0x30,0x21,0xa1,0x82,0x00,0x00,0x30,0xc2,0x00,0xff,0x00,0x02,0x10,0x80,
-0x00,0x47,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42,
-0xad,0xa3,0x00,0x00,0x91,0x84,0x00,0x00,0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80,
-0x00,0x87,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x05,0x28,0x40,0x00,0x8c,0x20,0x21,
-0x00,0x03,0x18,0x80,0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0xac,0x85,0x00,0x60,
-0x03,0xe0,0x00,0x08,0xa1,0x80,0x00,0xd4,0x27,0x87,0x81,0x64,0x08,0x00,0x23,0x0e,
-0xa1,0x80,0x00,0xdd,0x27,0x82,0x81,0xd4,0x8d,0x83,0x00,0xd8,0x00,0x82,0x10,0x21,
-0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01,0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0x0d,
-0xad,0x83,0x00,0xd8,0x8d,0x02,0x00,0x60,0xa1,0x80,0x00,0xd4,0x00,0x02,0x1f,0xc2,
-0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0x5c,
-0x10,0xe0,0x00,0x1a,0x24,0x83,0xff,0xfc,0x2c,0x62,0x00,0x18,0x10,0x40,0x01,0x18,
-0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01,0x24,0x63,0x02,0xbc,0x00,0x43,0x10,0x21,
-0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,
-0x2d,0x22,0x00,0x2d,0x10,0x40,0x00,0x5f,0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x5a,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x54,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x51,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,
-0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xd0,0xad,0x82,0x00,0xd0,0x8d,0xe3,0x00,0x00,
-0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xad,0xa2,0x00,0x00,
-0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,0x8d,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00,0x93,0x05,0x00,0x01,
-0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05,0x24,0x02,0x00,0x01,
-0xa1,0x85,0x00,0x00,0xa1,0x82,0x00,0xd4,0x03,0xe0,0x00,0x08,0xad,0x80,0x00,0xd8,
-0x91,0x82,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05,0x00,0x00,0x00,0x00,
-0xa1,0x83,0x00,0xd4,0xad,0x80,0x00,0xd8,0x03,0xe0,0x00,0x08,0xa1,0x83,0x00,0xdd,
-0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43,0xad,0xa2,0x00,0x00,
-0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x8d,0xc5,0x00,0x00,0x00,0x03,0x18,0x80,
-0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40,0x00,0x04,0x18,0x80,
-0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0x08,0x00,0x23,0x20,0xad,0xc5,0x00,0x00,
-0x97,0x82,0x8b,0x6c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a,0x10,0x40,0xfe,0xb9,
-0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,
-0x00,0x00,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x00,0x03,0x18,0x80,
-0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x6c,0x18,0x21,0xac,0x64,0x00,0x60,
-0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80,0x01,0x82,0x10,0x21,
-0x24,0x4e,0x00,0x60,0xa1,0x85,0x00,0x00,0x8d,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x03,0xe0,0x00,0x08,
-0xad,0xa2,0x00,0x00,0x08,0x00,0x23,0x92,0xa1,0x80,0x00,0xdd,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xe0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,
-0x24,0x42,0x00,0x01,0x10,0xa0,0x00,0x0d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,
-0x10,0xa2,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xa7,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xf0,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xe8,0x8d,0x82,0x00,0xd0,
-0x08,0x00,0x23,0x4e,0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xfc,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x96,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xf8,0x2d,0x22,0x00,0x19,
-0x14,0x40,0xff,0xe0,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xec,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x86,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,
-0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xf0,0x2d,0x22,0x00,0x1b,
-0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdc,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc8,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x14,0xa2,0xff,0xd0,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,
-0x24,0x42,0xff,0xf4,0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xce,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6b,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xaa,
-0x24,0x02,0x00,0x03,0x2d,0x22,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,
-0x10,0xa0,0xff,0xb1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5f,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0x56,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,
-0x2d,0x22,0x00,0x25,0x10,0x40,0xff,0xc8,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa2,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x99,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xf4,
-0x24,0x02,0x00,0x03,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xfc,
-0x2d,0x22,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa3,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8f,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x3d,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xa8,
-0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x23,0x4e,0x24,0x42,0xff,0xfa,
-0x10,0xa0,0xff,0x96,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x82,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x30,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0xbc,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x17,0x14,0x40,0xff,0x9e,
-0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x0b,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x19,
-0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x84,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0xa2,0xff,0x1e,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x89,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x28,0x2d,0x22,0x00,0x1b,
-0x2d,0x22,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x73,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5f,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x0d,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x88,
-0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x9b,0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x23,
-0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xc2,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0xc0,0x2d,0x22,0x00,0x25,0x08,0x00,0x23,0xf9,0x2d,0x22,0x00,0x27,
-0x10,0xa0,0xff,0x5e,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x4a,
-0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xfe,0xf8,0x24,0x02,0x00,0x03,
-0x14,0xa2,0xff,0x63,0x00,0x00,0x00,0x00,0x08,0x00,0x24,0x05,0x00,0x00,0x00,0x00,
-0x2d,0x22,0x00,0x27,0x14,0x40,0xff,0x8e,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xb2,
-0x00,0x00,0x00,0x00,0x2d,0x22,0x00,0x29,0x14,0x40,0xff,0x89,0x00,0x00,0x00,0x00,
-0x08,0x00,0x23,0xa1,0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03,
-0xaf,0xbf,0x00,0x14,0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x3c,0x03,0xb0,0x03,
-0x8c,0x50,0x00,0x00,0x34,0x63,0x01,0x2c,0x90,0x62,0x00,0x00,0x32,0x05,0x00,0x01,
-0xa3,0x82,0x80,0x10,0x14,0xa0,0x00,0x14,0x30,0x44,0x00,0xff,0x32,0x02,0x01,0x00,
-0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x10,0x40,0x00,0x02,
-0x24,0x02,0x00,0x01,0xa3,0x82,0xbc,0x08,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x05,0x39,0x00,0x00,0x00,0x00,
-0x26,0x02,0xff,0x00,0xa3,0x80,0xbc,0x08,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,
-0x08,0x00,0x24,0x77,0x32,0x02,0x08,0x00,0x0c,0x00,0x21,0x9a,0x00,0x00,0x00,0x00,
-0x26,0x02,0xff,0xff,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x74,
-0x32,0x02,0x01,0x00,0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,
-0xaf,0xbf,0x00,0x18,0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,0x24,0x07,0x0f,0xff,
-0x00,0x03,0x33,0x02,0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,0x30,0x69,0x0f,0xff,
-0x00,0x62,0x18,0x24,0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,0x10,0x60,0x00,0x08,
-0x31,0x08,0x00,0xff,0x01,0x00,0x30,0x21,0x0c,0x00,0x25,0x38,0xaf,0xa9,0x00,0x10,
-0x8f,0xbf,0x00,0x18,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,
-0x0c,0x00,0x25,0x8a,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xd4,
-0x08,0x00,0x24,0xa0,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0xaf,0xb6,0x00,0x30,
-0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x3c,
-0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,
-0xaf,0xb2,0x00,0x20,0x0c,0x00,0x17,0xc8,0x00,0x80,0x80,0x21,0x00,0x00,0xb0,0x21,
-0x00,0x00,0x88,0x21,0x10,0x40,0x00,0x12,0x00,0x00,0x98,0x21,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0xb0,0x03,0x3c,0x04,0xb0,0x03,0x24,0x05,0x00,0x01,0x34,0x42,0x00,0xbc,
-0x34,0x63,0x00,0xbb,0x34,0x84,0x00,0xba,0xa4,0x40,0x00,0x00,0xa0,0x65,0x00,0x00,
-0xa0,0x85,0x00,0x00,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,
-0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x47,0x90,0x44,0x00,0x00,0x00,0x10,0x1a,0x02,
-0x3c,0x15,0xfd,0xff,0x30,0x84,0x00,0xff,0xa0,0x50,0x00,0x00,0x30,0x74,0x00,0x0f,
-0xaf,0xa4,0x00,0x10,0x00,0x00,0x90,0x21,0x3c,0x17,0x02,0x00,0x36,0xb5,0xff,0xff,
-0x3c,0x1e,0xb0,0x03,0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x00,0x00,0x57,0x10,0x25,
-0x00,0x40,0x28,0x21,0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x00,0x00,0x00,0x80,0x21,
-0x0c,0x00,0x26,0x52,0x00,0x00,0x00,0x00,0x26,0x03,0x00,0x01,0x30,0x70,0x00,0xff,
-0x10,0x40,0x00,0x47,0x2e,0x03,0x00,0x02,0x14,0x60,0xff,0xf9,0x00,0x00,0x00,0x00,
-0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0x00,0x00,0x55,0x10,0x24,0x00,0x40,0x28,0x21,
-0x0c,0x00,0x06,0xc1,0x24,0x04,0x04,0x00,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x38,
-0x00,0x00,0x00,0x00,0x12,0x80,0x00,0x36,0x00,0x00,0x00,0x00,0x32,0x22,0x00,0x60,
-0x32,0x23,0x0c,0x00,0x00,0x03,0x1a,0x02,0x3c,0x05,0x00,0x60,0x00,0x02,0x11,0x42,
-0x02,0x25,0x20,0x24,0x00,0x43,0x10,0x25,0x3c,0x03,0x04,0x00,0x02,0x23,0x28,0x24,
-0x00,0x04,0x24,0x42,0x00,0x44,0x10,0x25,0x00,0x05,0x2d,0x02,0x00,0x45,0x88,0x25,
-0x12,0x20,0x00,0x05,0x26,0x42,0x00,0x01,0x26,0xc2,0x00,0x01,0x30,0x56,0x00,0xff,
-0x02,0x71,0x98,0x21,0x26,0x42,0x00,0x01,0x02,0x5e,0x20,0x21,0x30,0x52,0x00,0xff,
-0x2e,0x43,0x00,0x05,0xa0,0x91,0x00,0xd8,0x14,0x60,0xff,0xce,0x3c,0x02,0xb0,0x03,
-0x8f,0xa5,0x00,0x10,0x34,0x42,0x01,0x47,0xa0,0x45,0x00,0x00,0x12,0x60,0x00,0x0e,
-0x3c,0x02,0xb0,0x03,0x12,0xc0,0x00,0x0d,0x34,0x42,0x00,0xbc,0x00,0x13,0x10,0x40,
-0x00,0x53,0x10,0x21,0x00,0x02,0x10,0xc0,0x00,0x53,0x10,0x21,0x00,0x02,0x98,0x80,
-0x02,0x76,0x00,0x1b,0x16,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,
-0x00,0x00,0x98,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xbc,0x3c,0x03,0xb0,0x03,
-0x3c,0x04,0xb0,0x03,0xa4,0x53,0x00,0x00,0x34,0x63,0x00,0xbb,0x34,0x84,0x00,0xba,
-0x24,0x02,0x00,0x01,0xa0,0x60,0x00,0x00,0x08,0x00,0x24,0xc5,0xa0,0x82,0x00,0x00,
-0x0c,0x00,0x06,0xce,0x24,0x04,0x04,0xfc,0x08,0x00,0x24,0xf3,0x00,0x40,0x88,0x21,
-0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xbc,0x3c,0x04,0xb0,0x03,0x3c,0x05,0xb0,0x03,
-0xa4,0x60,0x00,0x00,0x34,0x84,0x00,0xbb,0x34,0xa5,0x00,0xba,0x24,0x02,0x00,0x02,
-0x24,0x03,0x00,0x01,0xa0,0x82,0x00,0x00,0x08,0x00,0x24,0xc5,0xa0,0xa3,0x00,0x00,
-0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,
-0x30,0xb1,0x00,0xff,0x14,0x40,0x00,0x06,0x00,0x80,0x90,0x21,0x8f,0xbf,0x00,0x20,
-0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x2e,0x13,0x00,0x10,0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07,
-0x12,0x60,0x00,0x38,0x02,0x00,0x30,0x21,0x8f,0xa2,0x00,0x38,0x30,0xc3,0x00,0x3f,
-0x3c,0x04,0xb0,0x09,0x00,0x02,0x14,0x00,0x00,0x43,0x30,0x25,0x34,0x84,0x01,0x60,
-0x90,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x24,0x02,0x00,0x01,
-0x12,0x22,0x00,0x2a,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x24,0x24,0x02,0x00,0x02,
-0x12,0x22,0x00,0x20,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x19,0x00,0x00,0x00,0x00,
-0x16,0x60,0xff,0xe2,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x13,0x2a,0x22,0x00,0x02,
-0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,
-0x16,0x22,0xff,0xda,0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,
-0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x43,0x00,0x00,0x00,0x00,
-0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x00,0x00,0x00,0x00,
-0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x6b,0x24,0x04,0x08,0x44,
-0x24,0x04,0x08,0x4c,0x0c,0x00,0x13,0x5b,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x60,
-0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x79,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe0,
-0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x79,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x79,
-0x24,0x04,0x08,0x44,0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0xca,0x02,0x20,0x28,0x21,
-0x08,0x00,0x25,0x4e,0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e,
-0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,
-0xaf,0xb3,0x00,0x1c,0x00,0xc0,0x80,0x21,0x30,0xb1,0x00,0xff,0x00,0x80,0x90,0x21,
-0x14,0x40,0x00,0x07,0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,
-0x2e,0x13,0x00,0x10,0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa0,0x24,0x06,0x01,0x07,
-0x12,0x60,0x00,0x24,0x02,0x00,0x30,0x21,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x30,0xc5,0x00,0x3f,
-0x0c,0x00,0x26,0x07,0x02,0x20,0x20,0x21,0x16,0x60,0x00,0x0a,0x00,0x40,0x80,0x21,
-0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x15,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0f,
-0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x0b,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x03,
-0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x96,0x02,0x00,0x18,0x21,0x24,0x04,0x08,0x4c,
-0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x96,
-0x02,0x00,0x18,0x21,0x08,0x00,0x25,0xb8,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xf5,
-0x00,0x00,0x00,0x00,0x08,0x00,0x25,0xb8,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xb8,
-0x24,0x04,0x08,0x44,0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0xca,0x02,0x20,0x28,0x21,
-0x08,0x00,0x25,0xa2,0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xe8,0x2c,0xc2,0x00,0x1f,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0x00,0xc0,0x80,0x21,0x14,0x40,0x00,0x1d,
-0x30,0xa5,0x00,0xff,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x18,0x28,0xa2,0x00,0x02,
-0x14,0x40,0x00,0x12,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0e,0x24,0x02,0x00,0x03,
-0x10,0xa2,0x00,0x07,0x24,0x04,0x08,0x4c,0x26,0x10,0xff,0xe2,0x02,0x00,0x10,0x21,
-0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,0x3c,0x06,0x0d,0xf8,0x08,0x00,0x25,0xdb,
-0x26,0x10,0xff,0xe2,0x08,0x00,0x25,0xe0,0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf2,
-0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xe1,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0xe0,
-0x24,0x04,0x08,0x44,0x2c,0xc2,0x00,0x10,0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x01,
-0x10,0xa2,0x00,0x14,0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x0e,0x24,0x02,0x00,0x02,
-0x10,0xa2,0x00,0x0a,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x03,0x24,0x04,0x08,0x4c,
-0x08,0x00,0x25,0xdb,0x26,0x10,0xff,0xf1,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5b,
-0x3c,0x06,0x0d,0xb8,0x08,0x00,0x25,0xdb,0x26,0x10,0xff,0xf1,0x08,0x00,0x25,0xfa,
-0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf6,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xfb,
-0x24,0x05,0xff,0xff,0x08,0x00,0x25,0xfa,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe8,
-0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x39,0xaf,0xbf,0x00,0x10,
-0x28,0x82,0x00,0x02,0x14,0x40,0x00,0x27,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,
-0x10,0x82,0x00,0x17,0x00,0xa0,0x30,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x05,
-0x24,0x04,0x08,0x3c,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c,
-0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x3c,
-0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0xac,
-0x0c,0x00,0x13,0x3d,0x24,0x05,0x0f,0xff,0x08,0x00,0x26,0x15,0x00,0x00,0x00,0x00,
-0x24,0x04,0x08,0x34,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34,
-0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x34,
-0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x08,0x00,0x26,0x24,
-0x24,0x04,0x08,0xa8,0x14,0x80,0xff,0xdf,0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x24,
-0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,
-0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,0x08,0x00,0x26,0x24,0x24,0x04,0x08,0xa0,
-0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x2c,0x0c,0x00,0x13,0x5b,0x3c,0x05,0x3f,0x00,
-0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x00,0x00,0x30,0x21,
-0x24,0x04,0x08,0x2c,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5b,0x24,0x06,0x00,0x01,
-0x08,0x00,0x26,0x24,0x24,0x04,0x08,0xa4,0x3c,0x05,0x00,0x14,0x3c,0x02,0xb0,0x05,
-0x34,0x42,0x04,0x20,0x3c,0x06,0xc0,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,
-0x34,0xa5,0x17,0x09,0xac,0x45,0x00,0x00,0x34,0xc6,0x05,0x07,0x34,0x63,0x04,0x24,
-0x34,0x84,0x02,0x28,0x3c,0x07,0xb0,0x05,0x24,0x02,0x00,0x20,0xac,0x66,0x00,0x00,
-0x34,0xe7,0x04,0x50,0xa0,0x82,0x00,0x00,0x90,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x42,0x00,0x03,0x10,0x40,0xff,0xfc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x93,0x85,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0xa2,0x00,0x51,
-0x00,0x80,0x40,0x21,0x8c,0x89,0x00,0x04,0x3c,0x03,0xb0,0x01,0x01,0x23,0x30,0x21,
-0x8c,0xc2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x08,0x10,0x45,0x00,0x59,
-0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x24,0x03,0x00,0xb4,0x30,0x44,0x00,0xff,
-0x10,0x83,0x00,0x61,0x24,0x02,0x00,0xc4,0x10,0x82,0x00,0x54,0x24,0x02,0x00,0x94,
-0x10,0x82,0x00,0x45,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x00,0x00,0x00,0x00,
-0x30,0x47,0xff,0xff,0x30,0xe3,0x40,0xff,0x24,0x02,0x40,0x88,0x14,0x62,0x00,0x39,
-0x30,0xe3,0x03,0x00,0x24,0x02,0x03,0x00,0x10,0x62,0x00,0x38,0x00,0x00,0x00,0x00,
-0x94,0xc2,0x00,0x56,0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,0x30,0xe2,0x00,0x80,
-0x14,0x40,0x00,0x30,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x94,0xc3,0x00,0x60,
-0x24,0x02,0x00,0x08,0x14,0x43,0x00,0x3b,0x00,0x00,0x00,0x00,0x90,0xc2,0x00,0x62,
-0x24,0x03,0x00,0x04,0x00,0x02,0x39,0x02,0x10,0xe3,0x00,0x15,0x24,0x02,0x00,0x06,
-0x14,0xe2,0x00,0x34,0x00,0x00,0x00,0x00,0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x66,
-0x27,0x82,0x89,0x58,0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,
-0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,
-0x24,0x42,0x00,0x5e,0x24,0x03,0xc0,0x00,0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,
-0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,0x08,0x00,0x26,0xcd,0xad,0x07,0x00,0x10,
-0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x64,0x27,0x82,0x89,0x58,0x00,0x05,0x28,0x80,
-0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,
-0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x36,0x3c,0x03,0xff,0xff,
-0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,
-0xad,0x07,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x50,
-0x08,0x00,0x26,0x8b,0x30,0x47,0xff,0xff,0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x58,
-0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff,
-0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x2e,0xac,0x82,0x00,0x00,0x24,0x03,0x00,0x2e,
-0xad,0x03,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x04,0x01,0xac,
-0x27,0x83,0x89,0x58,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,
-0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x0e,0x24,0x03,0x00,0x0e,
-0x08,0x00,0x26,0xcc,0xac,0x82,0x00,0x00,0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x58,
-0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff,
-0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x14,0x24,0x03,0x00,0x14,0x08,0x00,0x26,0xcc,
-0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xc6,0x00,0xff,
-0x00,0x06,0x48,0x40,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x8b,0xbc,0x20,
-0x27,0x83,0xbc,0x26,0x00,0x4b,0x40,0x21,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x00,
-0x30,0xa2,0x3f,0xff,0x10,0xe2,0x00,0x29,0x30,0x8a,0xff,0xff,0x95,0x02,0x00,0x02,
-0x24,0x03,0x00,0x01,0x00,0x02,0x11,0x82,0x30,0x42,0x00,0x01,0x10,0x43,0x00,0x18,
-0x00,0x00,0x00,0x00,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4b,0x30,0x21,
-0x94,0xc4,0x00,0x02,0x27,0x83,0xbc,0x26,0x27,0x85,0xbc,0x24,0x00,0x45,0x28,0x21,
-0x30,0x84,0xff,0xdf,0x00,0x43,0x10,0x21,0xa4,0xc4,0x00,0x02,0xa4,0x40,0x00,0x00,
-0xa4,0xa0,0x00,0x00,0x94,0xc3,0x00,0x02,0x3c,0x04,0xb0,0x01,0x01,0x44,0x20,0x21,
-0x30,0x63,0xff,0xbf,0xa4,0xc3,0x00,0x02,0xa0,0xc0,0x00,0x00,0x8c,0x82,0x00,0x04,
-0x24,0x03,0xf0,0xff,0x00,0x43,0x10,0x24,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x04,
-0x24,0x02,0xc0,0x00,0x91,0x04,0x00,0x01,0x00,0xa2,0x10,0x24,0x00,0x47,0x28,0x25,
-0x3c,0x03,0xb0,0x01,0x24,0x02,0x00,0x02,0x14,0x82,0xff,0xe2,0x01,0x43,0x18,0x21,
-0xac,0x65,0x00,0x00,0x08,0x00,0x26,0xfa,0x01,0x26,0x10,0x21,0x08,0x00,0x26,0xfa,
-0x01,0x26,0x10,0x21,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0x62,0x00,0x0d,
-0x3c,0x02,0xb0,0x01,0x8c,0x84,0x00,0x04,0x3c,0x06,0xb0,0x09,0x00,0x82,0x20,0x21,
-0x8c,0x85,0x00,0x08,0x8c,0x83,0x00,0x04,0x3c,0x02,0x01,0x00,0x34,0xc6,0x01,0x00,
-0x00,0x62,0x18,0x24,0x14,0x60,0x00,0x05,0x30,0xa5,0x20,0x00,0x24,0x02,0x00,0x06,
-0xa0,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x09,
-0x10,0xa0,0xff,0xfc,0x34,0x63,0x01,0x00,0x24,0x02,0x00,0x0e,0x08,0x00,0x27,0x2d,
-0xa0,0x62,0x00,0x00,0x3c,0x02,0xb0,0x01,0x30,0xa5,0xff,0xff,0x00,0xa2,0x28,0x21,
-0x8c,0xa3,0x00,0x00,0x3c,0x02,0x10,0x00,0x00,0x80,0x30,0x21,0x00,0x62,0x18,0x24,
-0x8c,0xa2,0x00,0x04,0x10,0x60,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x80,0x00,
-0x10,0x40,0x00,0x13,0x00,0x00,0x00,0x00,0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,
-0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,
-0x93,0x83,0x81,0xf0,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,
-0x24,0x63,0xff,0xff,0xac,0xc4,0x01,0xa8,0xa3,0x83,0x81,0xf0,0x8c,0xc4,0x01,0xac,
-0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x26,0x00,0x02,0x10,0x2b,
-0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,
-0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x04,
-0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0xf1,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0xf1,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa8,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,
-0x30,0x62,0x00,0xff,0x00,0x03,0x2e,0x02,0x00,0x02,0x39,0x80,0x2c,0xa2,0x00,0x02,
-0x00,0x03,0x34,0x02,0x10,0x40,0x00,0x05,0x00,0x03,0x1a,0x02,0xa4,0x87,0x01,0xd8,
-0xa0,0x85,0x01,0xd4,0xa0,0x86,0x01,0xd5,0xa0,0x83,0x01,0xd6,0x03,0xe0,0x00,0x08,
-0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x3c,0x05,0xb0,0x01,0x00,0x80,0x50,0x21,
-0x00,0x45,0x10,0x21,0x8c,0x43,0x00,0x04,0x24,0x02,0x00,0x05,0x00,0x03,0x1a,0x02,
-0x30,0x69,0x00,0x0f,0x11,0x22,0x00,0x0b,0x24,0x02,0x00,0x07,0x11,0x22,0x00,0x09,
-0x24,0x02,0x00,0x0a,0x11,0x22,0x00,0x07,0x24,0x02,0x00,0x0b,0x11,0x22,0x00,0x05,
-0x24,0x02,0x00,0x01,0x93,0x83,0x81,0xf0,0x3c,0x04,0xb0,0x06,0x10,0x62,0x00,0x03,
-0x34,0x84,0x80,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,
-0x8d,0x43,0x01,0xa8,0x27,0x82,0x89,0x58,0x00,0x03,0x18,0x80,0x00,0x6a,0x20,0x21,
-0x8c,0x87,0x00,0xa8,0x00,0x62,0x18,0x21,0x8c,0x68,0x00,0x00,0x00,0xe5,0x28,0x21,
-0x8c,0xa9,0x00,0x00,0x3c,0x02,0xff,0xff,0x27,0x83,0x8a,0x58,0x01,0x22,0x10,0x24,
-0x00,0x48,0x10,0x25,0xac,0xa2,0x00,0x00,0x8d,0x44,0x01,0xa8,0x00,0x07,0x30,0xc2,
-0x3c,0x02,0x00,0x80,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x00,0x06,0x32,0x00,
-0x8c,0xa9,0x00,0x04,0x00,0xc2,0x30,0x25,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00,
-0x01,0x22,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x10,
-0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x82,0xbc,0x18,0x8c,0xa3,0x00,0x04,
-0x3c,0x01,0xb0,0x07,0xac,0x26,0x80,0x18,0x8d,0x42,0x01,0xa8,0xaf,0x83,0xbc,0x14,
-0x93,0x85,0x81,0xf0,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,
-0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0xa5,0xff,0xff,
-0x00,0x82,0x20,0x23,0xad,0x44,0x01,0xa8,0xa3,0x85,0x81,0xf0,0x08,0x00,0x27,0x89,
-0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x24,0x42,0x9f,0x04,
-0x34,0xa5,0x00,0x20,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20,
-0xac,0x82,0x00,0x64,0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0x00,0x80,0x38,0x21,
-0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c,
-0xac,0x80,0x00,0x50,0xac,0x80,0x00,0x54,0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58,
-0xa0,0x80,0x00,0x5c,0x24,0x83,0x00,0x68,0x24,0x42,0xa0,0x14,0x24,0x04,0x00,0x0f,
-0x24,0x84,0xff,0xff,0xac,0x62,0x00,0x00,0x04,0x81,0xff,0xfd,0x24,0x63,0x00,0x04,
-0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa8,0xac,0xe0,0x01,0xa8,0xac,0xe0,0x01,0xac,
-0xac,0xe0,0x01,0xb0,0xac,0xe0,0x01,0xb4,0xa0,0xe0,0x01,0xb8,0xa0,0xe0,0x01,0xb9,
-0xa0,0xe0,0x01,0xba,0xa0,0xe0,0x01,0xc0,0xa0,0xe0,0x01,0xc1,0xac,0xe0,0x01,0xc4,
-0xac,0xe0,0x01,0xc8,0xac,0xe0,0x01,0xcc,0xac,0xe0,0x01,0xd0,0x8c,0x44,0x00,0x00,
-0x3c,0x02,0x80,0x01,0x24,0x42,0xa0,0xfc,0x30,0x83,0x00,0xff,0x00,0x03,0x19,0x80,
-0xa4,0xe3,0x01,0xd8,0xac,0xe2,0x00,0x78,0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,
-0x24,0x63,0xa2,0x88,0x24,0x42,0xa1,0xf4,0xac,0xe3,0x00,0x88,0xac,0xe2,0x00,0x98,
-0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,0x00,0x04,0x2e,0x03,0x00,0x04,0x34,0x03,
-0x24,0x63,0xa3,0x30,0x00,0x04,0x22,0x03,0x24,0x42,0xa4,0x74,0xac,0xe3,0x00,0xa0,
-0xac,0xe2,0x00,0xa4,0xa0,0xe5,0x01,0xd4,0xa0,0xe6,0x01,0xd5,0x03,0xe0,0x00,0x08,
-0xa0,0xe4,0x01,0xd6,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,
-0x24,0x42,0xa0,0x14,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x2c,0xac,0x43,0x00,0x00,
-0x8c,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x00,0x80,0x28,0x21,
-0x8c,0x82,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,
-0x8c,0x84,0x00,0x10,0x8c,0xa3,0x00,0x14,0x8c,0xa2,0x00,0x04,0x00,0x83,0x20,0x21,
-0x00,0x44,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02,
-0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00,0x30,0x42,0x3f,0xff,0xac,0xa2,0x00,0x04,
-0xac,0xa0,0x00,0x00,0xac,0xa0,0x00,0x4c,0xac,0xa0,0x00,0x50,0xac,0xa0,0x00,0x54,
-0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,
-0x34,0x63,0x00,0x20,0x24,0x42,0xa0,0xa8,0xac,0x62,0x00,0x00,0x8c,0x86,0x00,0x04,
-0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xc2,0x10,0x21,0x8c,0x45,0x00,0x00,
-0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02,0x30,0xa3,0x3f,0xff,0x30,0x42,0x00,0xff,
-0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14,0x8c,0x83,0x00,0x14,0xac,0x85,0x00,0x40,
-0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08,0xac,0x86,0x00,0x08,0x3c,0x02,0xb0,0x03,
-0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0xfc,
-0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,
-0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x00,0x80,0x80,0x21,0xae,0x00,0x00,0x00,
-0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,
-0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x0c,0x00,0x28,0x2a,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x4c,0xae,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,
-0x24,0x63,0xa1,0x60,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,
-0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,
-0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01,0x8e,0x04,0x00,0x44,0x00,0x62,0x18,0x21,
-0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01,0xae,0x02,0x00,0x50,0x30,0xa3,0x00,0xff,
-0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02,0x30,0x84,0x00,0x0f,0x30,0x42,0x00,0x03,
-0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34,0xae,0x02,0x00,0x2c,0xae,0x03,0x00,0x30,
-0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x2a,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x64,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x34,0x42,0x00,0x20,0x24,0x63,0xa1,0xf4,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16,
-0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44,0x8e,0x02,0x00,0x40,0x83,0x85,0x8b,0xc4,
-0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01,0x00,0x02,0x16,0x02,0xae,0x04,0x00,0x14,
-0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18,0x10,0xa0,0x00,0x04,0xae,0x03,0x00,0x3c,
-0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x06,0x00,0x01,0x24,0x02,0x00,0x01,
-0xa3,0x86,0x8b,0xc4,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x58,0x00,0x00,0x00,0x00,
-0x08,0x00,0x28,0x89,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
-0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa2,0x88,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00,
-0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21,0x3c,0x02,0xb0,0x03,0x8c,0x42,0x00,0x00,
-0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40,0x83,0x86,0x8b,0xc4,0x92,0x05,0x00,0x41,
-0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01,0x00,0x02,0x12,0xc2,0x00,0x03,0x1e,0x02,
-0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14,0x00,0x00,0x38,0x21,0xae,0x03,0x00,0x18,
-0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c,0x10,0x80,0x00,0x03,0x24,0x02,0x00,0x01,
-0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x87,0x8b,0xc4,0x8f,0xbf,0x00,0x14,
-0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,
-0x0c,0x00,0x28,0x58,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xae,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,
-0x24,0x63,0xa3,0x30,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,
-0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x42,0x00,0x80,0x80,0x21,
-0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,0x3c,0x08,0xb0,0x01,
-0x34,0x42,0x00,0x10,0x00,0x88,0x20,0x21,0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04,
-0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x89,0x89,0x58,0x00,0x48,0x10,0x21,
-0x8c,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x00,0x69,0x18,0x21,0xac,0x65,0x00,0x00,
-0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x87,0x8a,0x58,0x00,0x48,0x10,0x21,
-0x8c,0x45,0x00,0x04,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0xac,0x65,0x00,0x00,
-0x8e,0x02,0x01,0xac,0x8e,0x06,0x00,0x04,0x02,0x00,0x20,0x21,0x00,0x02,0x10,0x80,
-0x00,0x47,0x38,0x21,0x94,0xe3,0x00,0x02,0x00,0x49,0x10,0x21,0x90,0x45,0x00,0x00,
-0x00,0x03,0x1a,0x00,0x00,0xc8,0x30,0x21,0x00,0xa3,0x28,0x25,0x0c,0x00,0x26,0x69,
-0xa4,0xc5,0x00,0x2e,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03,
-0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a,
-0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23,
-0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30,
-0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01,
-0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,0x0c,0x00,0x28,0x0b,
-0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0xa2,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xd8,
-0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,
-0x34,0x42,0x00,0x20,0x24,0x63,0xa4,0x74,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,
-0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x42,
-0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,
-0x3c,0x08,0xb0,0x01,0x34,0x42,0x00,0x10,0x00,0x88,0x20,0x21,0x00,0x62,0x18,0x25,
-0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x89,0x89,0x58,
-0x00,0x48,0x10,0x21,0x8c,0x45,0x00,0x00,0x00,0x03,0x18,0x80,0x00,0x69,0x18,0x21,
-0xac,0x65,0x00,0x00,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x27,0x87,0x8a,0x58,
-0x00,0x48,0x10,0x21,0x8c,0x45,0x00,0x04,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,
-0xac,0x65,0x00,0x00,0x8e,0x02,0x01,0xac,0x8e,0x06,0x00,0x04,0x02,0x00,0x20,0x21,
-0x00,0x02,0x10,0x80,0x00,0x47,0x38,0x21,0x94,0xe3,0x00,0x02,0x00,0x49,0x10,0x21,
-0x90,0x45,0x00,0x00,0x00,0x03,0x1a,0x00,0x00,0xc8,0x30,0x21,0x00,0xa3,0x28,0x25,
-0x0c,0x00,0x26,0x69,0xa4,0xc5,0x00,0x2e,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,
-0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,
-0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,
-0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,
-0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,
-0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,
-0x0c,0x00,0x28,0x0b,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0xa2,0x00,0x00,0x00,0x00,
-0x08,0x00,0x29,0x29,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
-0x27,0xbd,0xff,0xd8,0x34,0x42,0x00,0x20,0x24,0x63,0xa5,0xb8,0xaf,0xb2,0x00,0x18,
-0xac,0x43,0x00,0x00,0x3c,0x12,0xb0,0x03,0x3c,0x02,0x80,0x01,0xaf,0xb4,0x00,0x20,
-0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x24,
-0x00,0x80,0x80,0x21,0x24,0x54,0xa0,0x14,0x00,0x00,0x88,0x21,0x3c,0x13,0xb0,0x01,
-0x36,0x52,0x00,0xef,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x06,0x90,0x43,0x00,0x00,
-0x8e,0x04,0x00,0x04,0x92,0x02,0x01,0xbb,0x30,0x69,0x00,0xff,0x00,0x04,0x42,0x02,
-0x10,0x40,0x00,0x1e,0x00,0x00,0x38,0x21,0x8e,0x03,0x01,0xa8,0x3c,0x06,0x28,0x38,
-0x34,0xc6,0x00,0x20,0x24,0x64,0x00,0x3d,0x28,0x82,0x00,0x00,0x24,0x63,0x00,0x7c,
-0x00,0x82,0x18,0x0a,0x00,0x03,0x19,0x83,0x00,0x03,0x19,0x80,0x00,0x83,0x20,0x23,
-0x00,0x04,0x10,0x80,0x00,0x50,0x10,0x21,0x8c,0x45,0x00,0xa8,0xae,0x04,0x01,0xac,
-0xae,0x04,0x01,0xa8,0x00,0xb3,0x18,0x21,0xae,0x05,0x00,0x04,0xac,0x66,0x00,0x00,
-0x8e,0x02,0x00,0x04,0x3c,0x03,0x80,0x00,0x34,0x63,0x4e,0x00,0x00,0x53,0x10,0x21,
-0xac,0x43,0x00,0x04,0xa2,0x00,0x01,0xbb,0x93,0x83,0x81,0xf7,0x00,0x00,0x00,0x00,
-0x24,0x62,0x00,0x01,0xa3,0x82,0x81,0xf7,0xa2,0x43,0x00,0x00,0x01,0x28,0x10,0x23,
-0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,
-0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0x84,0xff,0xff,0x10,0x44,0x00,0x6b,
-0x3c,0x02,0xb0,0x01,0x8e,0x03,0x00,0x04,0x3c,0x04,0x7c,0x00,0x00,0x62,0x18,0x21,
-0x8c,0x65,0x00,0x04,0x34,0x84,0x00,0xf0,0x00,0x00,0x30,0x21,0xae,0x05,0x00,0x44,
-0x00,0xa4,0x20,0x24,0x8c,0x63,0x00,0x00,0x10,0x80,0x00,0x6b,0x3c,0x02,0xff,0xff,
-0x3c,0x09,0xb0,0x03,0x3c,0x05,0x7c,0x00,0x35,0x29,0x00,0x99,0x3c,0x0a,0xb0,0x01,
-0x24,0x08,0x00,0x40,0x34,0xa5,0x00,0xf0,0x3c,0x0b,0xff,0xff,0x3c,0x0c,0x28,0x38,
-0x16,0x20,0x00,0x06,0x24,0xe7,0x00,0x01,0x93,0x82,0x81,0xf6,0x24,0x11,0x00,0x01,
-0x24,0x42,0x00,0x01,0xa1,0x22,0x00,0x00,0xa3,0x82,0x81,0xf6,0x8e,0x02,0x00,0x04,
-0x24,0x06,0x00,0x01,0x24,0x42,0x01,0x00,0x30,0x42,0x3f,0xff,0xae,0x02,0x00,0x04,
-0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x44,
-0x00,0x65,0x20,0x24,0x8c,0x43,0x00,0x00,0x10,0xe8,0x00,0x2d,0x00,0x00,0x00,0x00,
-0x14,0x80,0xff,0xeb,0x00,0x6b,0x10,0x24,0x14,0x4c,0xff,0xe9,0x24,0x02,0x00,0x01,
-0x10,0xc2,0x00,0x30,0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,0x8e,0x04,0x00,0x60,
-0x00,0x02,0x1e,0x42,0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,0x30,0x63,0x00,0x01,
-0xae,0x02,0x00,0x00,0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,0x8e,0x02,0x00,0x64,
-0x8e,0x04,0x00,0x58,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,0x00,0x00,0x00,0x00,
-0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,
-0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,0x00,0x50,0x10,0x21,
-0x8c,0x42,0x00,0x68,0x00,0x00,0x00,0x00,0x10,0x54,0x00,0x06,0x00,0x00,0x00,0x00,
-0x00,0x40,0xf8,0x09,0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,0x8e,0x03,0x00,0x00,
-0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x60,0x08,0x00,0x29,0x81,0xae,0x04,0x00,0x64,
-0x8e,0x02,0x00,0x64,0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,0x00,0x00,0x00,0x00,
-0x7a,0x02,0x0d,0x7c,0x8f,0xbf,0x00,0x24,0x8f,0xb4,0x00,0x20,0x7b,0xb2,0x00,0xfc,
-0x7b,0xb0,0x00,0xbc,0x00,0x43,0x10,0x26,0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x28,0x8e,0x04,0x00,0x04,0x34,0x63,0x00,0x06,0x90,0x62,0x00,0x00,
-0x00,0x04,0x42,0x02,0x00,0x48,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,
-0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
-0x00,0x82,0x20,0x23,0x14,0x86,0xff,0xc4,0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00,
-0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x03,0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d,
-0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x01,0x08,0x00,0x2a,0x04,0xa2,0x02,0x00,0x5c,
-0x08,0x00,0x2a,0x04,0xa2,0x00,0x00,0x5c,0x00,0x62,0x10,0x24,0x3c,0x03,0x28,0x38,
-0x14,0x43,0xff,0x93,0x24,0x02,0x00,0x01,0x08,0x00,0x29,0xdc,0x00,0x00,0x00,0x00,
-0x3c,0x02,0xb0,0x01,0x00,0xa2,0x40,0x21,0x00,0xa0,0x48,0x21,0x8d,0x05,0x00,0x00,
-0x24,0x02,0xc0,0x00,0x00,0x09,0x38,0xc2,0x00,0xa2,0x28,0x24,0x24,0xc2,0xff,0xff,
-0x00,0x07,0x3a,0x00,0x3c,0x0a,0xb0,0x06,0x3c,0x03,0x00,0x80,0x00,0xa6,0x28,0x25,
-0x2c,0x42,0x1f,0xff,0x00,0xe3,0x38,0x25,0x35,0x4a,0x80,0x18,0x10,0x40,0x00,0x0e,
-0xad,0x05,0x00,0x00,0xaf,0x89,0xbc,0x10,0x8d,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
-0xaf,0x82,0xbc,0x18,0x8d,0x03,0x00,0x04,0xad,0x47,0x00,0x00,0xaf,0x83,0xbc,0x14,
-0xac,0x80,0x01,0xd0,0xac,0x80,0x01,0xc4,0xa0,0x80,0x01,0xc0,0xa0,0x80,0x01,0xc1,
-0xac,0x80,0x01,0xc8,0xac,0x80,0x01,0xcc,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,
-0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x8c,0x83,0x01,0xc4,0x00,0x80,0x38,0x21,
-0x90,0x84,0x01,0xc0,0x00,0x03,0x18,0x80,0x00,0x67,0x18,0x21,0x8c,0x65,0x00,0xa8,
-0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xa2,0x10,0x21,0x8c,0x42,0x00,0x00,
-0x10,0x83,0x00,0x18,0x00,0x02,0x14,0x02,0x8c,0xe9,0x01,0xcc,0x8c,0xea,0x01,0xc8,
-0x30,0x46,0x00,0xff,0x01,0x2a,0x18,0x21,0x30,0x64,0x00,0xff,0x00,0x03,0x1a,0x02,
-0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x48,0x00,0xff,0x30,0x68,0x00,0xff,
-0x90,0xe2,0x01,0xc1,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x23,0x00,0x02,0x12,0x00,
-0x00,0x49,0x10,0x21,0x00,0x4a,0x10,0x21,0x00,0x46,0x30,0x23,0x0c,0x00,0x2a,0x2c,
-0x00,0xe0,0x20,0x21,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x8c,0xe6,0x01,0xc8,0x08,0x00,0x2a,0x6b,0x00,0x00,0x00,0x00,
-0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x14,0xaf,0xb0,0x00,0x10,0x8c,0x82,0x01,0xc4,
-0x90,0x87,0x01,0xc1,0x00,0x80,0x80,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,
-0x8c,0x48,0x00,0xa8,0x3c,0x02,0xb0,0x01,0x00,0x07,0x3a,0x00,0x01,0x02,0x10,0x21,
-0x8c,0x43,0x00,0x00,0x00,0xe5,0x38,0x21,0x00,0xe6,0x38,0x21,0x00,0x03,0x1c,0x02,
-0x30,0x63,0x00,0xff,0x00,0xe3,0x38,0x23,0x01,0x00,0x28,0x21,0x0c,0x00,0x2a,0x2c,
-0x00,0xe0,0x30,0x21,0x8e,0x02,0x01,0xa8,0x8f,0xbf,0x00,0x14,0x24,0x44,0x00,0x01,
-0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,
-0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0xae,0x04,0x01,0xa8,0x8f,0xb0,0x00,0x10,
-0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,
-0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xaa,0x58,0xaf,0xb0,0x00,0x10,
-0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x90,0x82,0x01,0xd4,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x6a,0x00,0x80,0x80,0x21,0x90,0x82,0x01,0xc0,0x00,0x00,0x00,0x00,
-0x14,0x40,0x00,0x61,0x00,0x00,0x00,0x00,0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac,
-0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x22,0x00,0x00,0x28,0x21,0x93,0x82,0x81,0xf1,
-0x00,0x03,0x30,0x80,0x00,0xc4,0x18,0x21,0x24,0x04,0x00,0x01,0x8c,0x67,0x00,0xa8,
-0x10,0x44,0x00,0x20,0x3c,0x04,0xb0,0x01,0xaf,0x87,0xbc,0x10,0x00,0xe4,0x20,0x21,
-0x8c,0x86,0x00,0x00,0x00,0x07,0x18,0xc2,0x3c,0x02,0x00,0x80,0xaf,0x86,0xbc,0x18,
-0x8c,0x86,0x00,0x04,0x00,0x03,0x1a,0x00,0x3c,0x05,0xb0,0x06,0x00,0x62,0x18,0x25,
-0x34,0xa5,0x80,0x18,0xac,0xa3,0x00,0x00,0x8e,0x02,0x01,0xa8,0x8e,0x09,0x01,0xac,
-0xaf,0x86,0xbc,0x14,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,
-0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,
-0x00,0x80,0x30,0x21,0xae,0x04,0x01,0xa8,0x00,0xc9,0x10,0x26,0x00,0x02,0x28,0x2b,
-0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x00,0xa0,0x10,0x21,0x03,0xe0,0x00,0x08,
-0x27,0xbd,0x00,0x18,0x93,0x82,0x81,0xf0,0x00,0x00,0x00,0x00,0x2c,0x42,0x00,0x02,
-0x14,0x40,0xff,0xf7,0x00,0x00,0x28,0x21,0x3c,0x05,0xb0,0x01,0x00,0xe5,0x28,0x21,
-0x27,0x83,0x89,0x58,0x00,0xc3,0x18,0x21,0x8c,0xa6,0x00,0x00,0x8c,0x64,0x00,0x00,
-0x24,0x02,0xc0,0x00,0x00,0xc2,0x10,0x24,0x00,0x44,0x10,0x25,0xac,0xa2,0x00,0x00,
-0x8e,0x03,0x01,0xa8,0x27,0x84,0x8a,0x58,0x8c,0xa6,0x00,0x04,0x00,0x03,0x18,0x80,
-0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00,0x3c,0x03,0x80,0x00,0x00,0x07,0x20,0xc2,
-0x00,0xc2,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x10,
-0x8c,0xa6,0x00,0x00,0x3c,0x02,0x00,0x80,0x00,0x04,0x22,0x00,0x3c,0x03,0xb0,0x06,
-0xaf,0x86,0xbc,0x18,0x00,0x82,0x20,0x25,0x34,0x63,0x80,0x18,0x8c,0xa6,0x00,0x04,
-0xac,0x64,0x00,0x00,0x8e,0x02,0x01,0xa8,0xaf,0x86,0xbc,0x14,0x24,0x44,0x00,0x01,
-0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x93,0x83,0x81,0xf0,
-0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0x24,0x63,0xff,0xff,
-0xae,0x04,0x01,0xa8,0xa3,0x83,0x81,0xf0,0x8e,0x04,0x01,0xac,0x8e,0x02,0x01,0xa8,
-0x08,0x00,0x2a,0xcb,0x00,0x44,0x10,0x26,0x0c,0x00,0x2a,0x4c,0x00,0x00,0x00,0x00,
-0x7a,0x02,0x0d,0x7c,0x08,0x00,0x2a,0xcb,0x00,0x43,0x10,0x26,0x8c,0x86,0x01,0xa8,
-0x8c,0x89,0x01,0xac,0x00,0x00,0x00,0x00,0x10,0xc9,0x00,0xb4,0x00,0xc0,0x68,0x21,
-0x00,0x06,0x10,0x80,0x27,0x83,0x89,0x58,0x00,0x43,0x18,0x21,0x00,0x44,0x10,0x21,
-0x8c,0x47,0x00,0xa8,0x94,0x65,0x00,0x02,0x3c,0x02,0xb0,0x01,0x00,0xe2,0x10,0x21,
-0x30,0xa5,0x3f,0xff,0xa4,0x45,0x00,0x2c,0x90,0x8a,0x01,0xc0,0x00,0x00,0x00,0x00,
-0x11,0x40,0x00,0x0c,0x00,0x07,0x32,0x02,0x8c,0x83,0x01,0xc4,0x90,0x85,0x01,0xc1,
-0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0xa8,0x00,0x00,0x00,0x00,
-0x00,0x02,0x12,0x02,0x00,0x45,0x10,0x21,0x30,0x42,0x00,0x3f,0x14,0xc2,0xff,0xde,
-0x00,0x00,0x00,0x00,0x3c,0x04,0xb0,0x01,0x00,0xe4,0x40,0x21,0x8d,0x06,0x00,0x00,
-0x00,0x0d,0x28,0x80,0x00,0x06,0x14,0x02,0x30,0x4b,0x00,0xff,0x00,0xeb,0x70,0x21,
-0x01,0xc4,0x20,0x21,0x90,0x83,0x00,0x00,0x27,0x82,0x89,0x58,0x00,0xa2,0x28,0x21,
-0x8c,0xa4,0x00,0x00,0x00,0x03,0x18,0x82,0x30,0x63,0x00,0x03,0x2c,0x62,0x00,0x02,
-0x14,0x40,0x00,0x66,0x30,0x8c,0x3f,0xff,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x61,
-0x2d,0x82,0x08,0x00,0x15,0x40,0x00,0x36,0x01,0x6c,0x10,0x21,0x01,0x6c,0x18,0x21,
-0x30,0x62,0x00,0xff,0x00,0x02,0x10,0x2b,0x00,0x03,0x1a,0x02,0x3c,0x04,0xb0,0x01,
-0x00,0x62,0x18,0x21,0x00,0xe4,0x20,0x21,0x24,0x02,0x00,0x01,0xa2,0x03,0x01,0xc1,
-0xa0,0x82,0x00,0x08,0x8e,0x06,0x01,0xa8,0x3c,0x03,0xb0,0x00,0x34,0x63,0xff,0xf4,
-0x24,0xc5,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0xc2,0x00,0x40,0x00,0xa4,0x10,0x0a,
-0x01,0xc3,0x18,0x21,0xa4,0x6c,0x00,0x00,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
-0x92,0x04,0x01,0xc0,0x00,0xa2,0x38,0x23,0x3c,0x03,0xb0,0x03,0xae,0x0b,0x01,0xcc,
-0xae,0x0c,0x01,0xc8,0xae,0x06,0x01,0xc4,0xae,0x07,0x01,0xa8,0x34,0x63,0x01,0x08,
-0x92,0x05,0x01,0xd6,0x8c,0x66,0x00,0x00,0x24,0x84,0x00,0x01,0x30,0x82,0x00,0xff,
-0x00,0x45,0x10,0x2b,0xae,0x06,0x01,0xd0,0x10,0x40,0x00,0x07,0xa2,0x04,0x01,0xc0,
-0x92,0x02,0x01,0xd5,0x92,0x03,0x01,0xc1,0x24,0x42,0xff,0xfc,0x00,0x62,0x18,0x2a,
-0x14,0x60,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x00,0x20,0x21,0x0c,0x00,0x2a,0x4c,
-0x00,0x00,0x00,0x00,0x8e,0x09,0x01,0xac,0x8e,0x06,0x01,0xa8,0x08,0x00,0x2a,0xcb,
-0x00,0xc9,0x10,0x26,0x8e,0x09,0x01,0xac,0x08,0x00,0x2a,0xca,0x00,0xe0,0x30,0x21,
-0x30,0x43,0x00,0xff,0x92,0x07,0x01,0xc1,0x00,0x02,0x12,0x02,0x30,0x44,0x00,0xff,
-0x38,0x63,0x00,0x00,0x24,0x46,0x00,0x01,0x92,0x05,0x01,0xd5,0x00,0x83,0x30,0x0a,
-0x00,0xc7,0x18,0x21,0x00,0xa3,0x10,0x2a,0x14,0x40,0xff,0xeb,0x00,0x00,0x00,0x00,
-0x24,0xa2,0xff,0xfc,0x00,0x62,0x10,0x2a,0x10,0x40,0x00,0x07,0x01,0x80,0x28,0x21,
-0x92,0x03,0x01,0xd6,0x25,0x42,0x00,0x01,0x00,0x43,0x10,0x2a,0x14,0x40,0x00,0x07,
-0x25,0xa4,0x00,0x01,0x01,0x80,0x28,0x21,0x01,0x60,0x30,0x21,0x0c,0x00,0x2a,0x74,
-0x02,0x00,0x20,0x21,0x08,0x00,0x2b,0x6d,0x00,0x00,0x00,0x00,0x28,0x83,0x00,0x00,
-0x25,0xa2,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,
-0x00,0x82,0x20,0x23,0x00,0xc7,0x18,0x21,0x25,0x42,0x00,0x01,0x00,0x80,0x30,0x21,
-0xa2,0x03,0x01,0xc1,0xae,0x0b,0x01,0xcc,0xae,0x0c,0x01,0xc8,0x08,0x00,0x2a,0xc9,
-0xa2,0x02,0x01,0xc0,0x14,0x40,0xff,0x9f,0x00,0x00,0x00,0x00,0x15,0x40,0x00,0x14,
-0x24,0x02,0xc0,0x00,0x00,0xc2,0x10,0x24,0x00,0x4c,0x10,0x25,0xad,0x02,0x00,0x00,
-0xaf,0x87,0xbc,0x10,0x8d,0x05,0x00,0x00,0x00,0x07,0x18,0xc2,0x3c,0x02,0x00,0x80,
-0x00,0x03,0x1a,0x00,0x3c,0x04,0xb0,0x06,0xaf,0x85,0xbc,0x18,0x00,0x62,0x18,0x25,
-0x34,0x84,0x80,0x18,0x8d,0x05,0x00,0x04,0xac,0x83,0x00,0x00,0x8e,0x02,0x01,0xa8,
-0x8e,0x09,0x01,0xac,0xaf,0x85,0xbc,0x14,0x08,0x00,0x2a,0xc2,0x24,0x44,0x00,0x01,
-0x01,0x6c,0x10,0x21,0x30,0x45,0x00,0xff,0x92,0x04,0x01,0xc1,0x00,0x02,0x12,0x02,
-0x30,0x46,0x00,0xff,0x38,0xa5,0x00,0x00,0x24,0x42,0x00,0x01,0x92,0x03,0x01,0xd5,
-0x00,0xc5,0x10,0x0a,0x00,0x82,0x20,0x21,0x00,0x64,0x18,0x2a,0x10,0x60,0xff,0xca,
-0x01,0x80,0x28,0x21,0x08,0x00,0x2b,0x6b,0x02,0x00,0x20,0x21,0x90,0x87,0x01,0xc0,
-0x00,0x00,0x00,0x00,0x10,0xe0,0xff,0x06,0x00,0x00,0x28,0x21,0x3c,0x02,0xb0,0x03,
-0x34,0x42,0x01,0x08,0x94,0x83,0x01,0xd8,0x8c,0x88,0x01,0xd0,0x8c,0x45,0x00,0x00,
-0x01,0x03,0x18,0x21,0x00,0xa3,0x10,0x2b,0x10,0x40,0x00,0x0b,0x2c,0xe2,0x00,0x02,
-0x00,0xa8,0x10,0x2b,0x10,0x40,0xfe,0xf9,0x00,0xc9,0x10,0x26,0x3c,0x02,0x80,0x00,
-0x00,0x62,0x18,0x21,0x00,0xa2,0x10,0x21,0x00,0x43,0x10,0x2b,0x14,0x40,0xfe,0xf3,
-0x00,0xc9,0x10,0x26,0x2c,0xe2,0x00,0x02,0x10,0x40,0xff,0x90,0x00,0x00,0x00,0x00,
-0x24,0x02,0x00,0x01,0x14,0xe2,0xfe,0xed,0x00,0xc9,0x10,0x26,0x3c,0x03,0xb0,0x06,
-0x34,0x63,0x80,0x18,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,
-0x14,0x40,0xfe,0xe5,0x00,0x00,0x00,0x00,0x08,0x00,0x2b,0x6b,0x00,0x00,0x00,0x00,
-0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01,0x34,0xc6,0x00,0x18,
-0x34,0x84,0x00,0x20,0x24,0x42,0xaf,0xa0,0x24,0x03,0xff,0x83,0xac,0x82,0x00,0x00,
-0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8,0x3c,0x03,0xb0,0x07,
-0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00,0x90,0x64,0x00,0x00,
-0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01,0xa0,0x40,0x00,0x00,
-0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07,0xa3,0xa3,0x00,0x00,
-0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10,0x24,0x02,0x00,0x06,
-0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38,0xa0,0xa2,0x00,0x00,
-0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20,0xa3,0xa4,0x00,0x00,
-0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xbf,0x20,0xa3,0xa3,0x00,0x00,
-0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x08,
-};
-
-u8 rtl8190_fwdata_array[] ={
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,
-0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4,0x00,0xab,0x00,0x72,
-0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x02,0x76,0x01,0x3b,
-0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f,0x01,0x3b,0x00,0x9e,
-0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20,0x01,0x2f,0x00,0x98,
-0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e,0x00,0x98,0x00,0x4c,
-0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f,0x02,0x39,0x01,0x1c,
-0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39,0x01,0x1c,0x00,0x8e,
-0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c,0x01,0x11,0x00,0x89,
-0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b,0x00,0x89,0x00,0x44,
-0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e,0x02,0xab,0x02,0xab,
-0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08,0x04,0x06,0x07,0x08,
-0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x4c,
-0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c,0x5f,0x64,0x61,0x74,
-0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x64,0x45,0x4c,
-0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00,0x00,0x00,0x00,0x00,
-0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64,
-0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x70,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x76,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x0b,0x53,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x2c,
-0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60,
-0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20,0x00,0x00,0x01,0x80,
-0x00,0x00,0x01,0xb0,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x9c,
-0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xd4,
-0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,
-0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x6f,0x00,0x00,0x03,0x40,0x00,0x00,0x03,0xa8,
-0x00,0x00,0x04,0x10,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,
-0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x07,0x74,0x80,0x00,0x07,0x88,
-0x80,0x00,0x07,0x88,0x80,0x00,0x07,0x78,0x80,0x00,0x07,0x78,0x80,0x00,0x07,0x9c,
-0x80,0x00,0x53,0xc4,0x80,0x00,0x54,0x24,0x80,0x00,0x54,0x38,0x80,0x00,0x54,0x5c,
-0x80,0x00,0x54,0x68,0x80,0x00,0x54,0xa8,0x80,0x00,0x56,0xa8,0x80,0x00,0x57,0xec,
-0x80,0x00,0x58,0x14,0x80,0x00,0x59,0x0c,0x80,0x00,0x59,0xc4,0x80,0x00,0x5a,0x6c,
-0x80,0x00,0x5a,0xe0,0x80,0x00,0x5b,0xec,0x80,0x00,0x5c,0x24,0x80,0x00,0x5c,0x38,
-0x80,0x00,0x5c,0x4c,0x80,0x00,0x5d,0x40,0x80,0x00,0x5d,0x80,0x80,0x00,0x5e,0x34,
-0x80,0x00,0x5e,0x5c,0x80,0x00,0x56,0x68,0x80,0x00,0x5e,0x78,0x80,0x00,0x88,0xf8,
-0x80,0x00,0x88,0xf8,0x80,0x00,0x88,0xf8,0x80,0x00,0x89,0x2c,0x80,0x00,0x89,0x6c,
-0x80,0x00,0x89,0xa4,0x80,0x00,0x89,0xd4,0x80,0x00,0x8a,0x10,0x80,0x00,0x8a,0x50,
-0x80,0x00,0x8a,0xb8,0x80,0x00,0x8a,0xcc,0x80,0x00,0x8b,0x08,0x80,0x00,0x8b,0x10,
-0x80,0x00,0x8b,0x4c,0x80,0x00,0x8b,0x60,0x80,0x00,0x8b,0x68,0x80,0x00,0x8b,0x70,
-0x80,0x00,0x8b,0x70,0x80,0x00,0x8b,0x70,0x80,0x00,0x8b,0x70,0x80,0x00,0x8a,0x90,
-0x80,0x00,0x8b,0xa0,0x80,0x00,0x8b,0xb4,0x80,0x00,0x88,0x54,0x80,0x00,0x8e,0xc8,
-0x80,0x00,0x8e,0xc8,0x80,0x00,0x8e,0xc8,0x80,0x00,0x8e,0xfc,0x80,0x00,0x8f,0x3c,
-0x80,0x00,0x8f,0x74,0x80,0x00,0x8f,0xa4,0x80,0x00,0x8f,0xe0,0x80,0x00,0x90,0x20,
-0x80,0x00,0x90,0x88,0x80,0x00,0x90,0x9c,0x80,0x00,0x90,0xd8,0x80,0x00,0x90,0xe0,
-0x80,0x00,0x91,0x1c,0x80,0x00,0x91,0x30,0x80,0x00,0x91,0x38,0x80,0x00,0x91,0x40,
-0x80,0x00,0x91,0x40,0x80,0x00,0x91,0x40,0x80,0x00,0x91,0x40,0x80,0x00,0x90,0x60,
-0x80,0x00,0x91,0x70,0x80,0x00,0x91,0x84,0x80,0x00,0x8d,0x00,};
-
-u32 Rtl8192UsbPHY_REGArray[] = {
-0x0, };
-
-u32 Rtl8192UsbPHY_REG_1T2RArray[] = {
-0x800,0x00000000,
-0x804,0x00000001,
-0x808,0x0000fc00,
-0x80c,0x0000001c,
-0x810,0x801010aa,
-0x814,0x008514d0,
-0x818,0x00000040,
-0x81c,0x00000000,
-0x820,0x00000004,
-0x824,0x00690000,
-0x828,0x00000004,
-0x82c,0x00e90000,
-0x830,0x00000004,
-0x834,0x00690000,
-0x838,0x00000004,
-0x83c,0x00e90000,
-0x840,0x00000000,
-0x844,0x00000000,
-0x848,0x00000000,
-0x84c,0x00000000,
-0x850,0x00000000,
-0x854,0x00000000,
-0x858,0x65a965a9,
-0x85c,0x65a965a9,
-0x860,0x001f0010,
-0x864,0x007f0010,
-0x868,0x001f0010,
-0x86c,0x007f0010,
-0x870,0x0f100f70,
-0x874,0x0f100f70,
-0x878,0x00000000,
-0x87c,0x00000000,
-0x880,0x6870e36c,
-0x884,0xe3573600,
-0x888,0x4260c340,
-0x88c,0x0000ff00,
-0x890,0x00000000,
-0x894,0xfffffffe,
-0x898,0x4c42382f,
-0x89c,0x00656056,
-0x8b0,0x00000000,
-0x8e0,0x00000000,
-0x8e4,0x00000000,
-0x900,0x00000000,
-0x904,0x00000023,
-0x908,0x00000000,
-0x90c,0x31121311,
-0xa00,0x00d0c7d8,
-0xa04,0x811f0008,
-0xa08,0x80cd8300,
-0xa0c,0x2e62740f,
-0xa10,0x95009b78,
-0xa14,0x11145008,
-0xa18,0x00881117,
-0xa1c,0x89140fa0,
-0xa20,0x1a1b0000,
-0xa24,0x090e1317,
-0xa28,0x00000204,
-0xa2c,0x00000000,
-0xc00,0x00000040,
-0xc04,0x00005433,
-0xc08,0x000000e4,
-0xc0c,0x6c6c6c6c,
-0xc10,0x08800000,
-0xc14,0x40000100,
-0xc18,0x08000000,
-0xc1c,0x40000100,
-0xc20,0x08000000,
-0xc24,0x40000100,
-0xc28,0x08000000,
-0xc2c,0x40000100,
-0xc30,0x6de9ac44,
-0xc34,0x465c52cd,
-0xc38,0x497f5994,
-0xc3c,0x0a969764,
-0xc40,0x1f7c403f,
-0xc44,0x000100b7,
-0xc48,0xec020000,
-0xc4c,0x00000300,
-0xc50,0x69543420,
-0xc54,0x433c0094,
-0xc58,0x69543420,
-0xc5c,0x433c0094,
-0xc60,0x69543420,
-0xc64,0x433c0094,
-0xc68,0x69543420,
-0xc6c,0x433c0094,
-0xc70,0x2c7f000d,
-0xc74,0x0186175b,
-0xc78,0x0000001f,
-0xc7c,0x00b91612,
-0xc80,0x40000100,
-0xc84,0x20000000,
-0xc88,0x40000100,
-0xc8c,0x20200000,
-0xc90,0x40000100,
-0xc94,0x00000000,
-0xc98,0x40000100,
-0xc9c,0x00000000,
-0xca0,0x00492492,
-0xca4,0x00000000,
-0xca8,0x00000000,
-0xcac,0x00000000,
-0xcb0,0x00000000,
-0xcb4,0x00000000,
-0xcb8,0x00000000,
-0xcbc,0x00492492,
-0xcc0,0x00000000,
-0xcc4,0x00000000,
-0xcc8,0x00000000,
-0xccc,0x00000000,
-0xcd0,0x00000000,
-0xcd4,0x00000000,
-0xcd8,0x64b22427,
-0xcdc,0x00766932,
-0xce0,0x00222222,
-0xd00,0x00000750,
-0xd04,0x00000403,
-0xd08,0x0000907f,
-0xd0c,0x00000001,
-0xd10,0xa0633333,
-0xd14,0x33333c63,
-0xd18,0x6a8f5b6b,
-0xd1c,0x00000000,
-0xd20,0x00000000,
-0xd24,0x00000000,
-0xd28,0x00000000,
-0xd2c,0xcc979975,
-0xd30,0x00000000,
-0xd34,0x00000000,
-0xd38,0x00000000,
-0xd3c,0x00027293,
-0xd40,0x00000000,
-0xd44,0x00000000,
-0xd48,0x00000000,
-0xd4c,0x00000000,
-0xd50,0x6437140a,
-0xd54,0x024dbd02,
-0xd58,0x00000000,
-0xd5c,0x04032064,
-0xe00,0x161a1a1a,
-0xe04,0x12121416,
-0xe08,0x00001800,
-0xe0c,0x00000000,
-0xe10,0x161a1a1a,
-0xe14,0x12121416,
-0xe18,0x161a1a1a,
-0xe1c,0x12121416,
-};
-
-u32 Rtl8192UsbRadioA_Array[] = {
-0x019,0x00000003,
-0x000,0x000000bf,
-0x001,0x00000ee0,
-0x002,0x0000004c,
-0x003,0x000007f1,
-0x004,0x00000975,
-0x005,0x00000c58,
-0x006,0x00000ae6,
-0x007,0x000000ca,
-0x008,0x00000e1c,
-0x009,0x000007f0,
-0x00a,0x000009d0,
-0x00b,0x000001ba,
-0x00c,0x00000240,
-0x00e,0x00000020,
-0x00f,0x00000990,
-0x012,0x00000806,
-0x014,0x000005ab,
-0x015,0x00000f80,
-0x016,0x00000020,
-0x017,0x00000597,
-0x018,0x0000050a,
-0x01a,0x00000f80,
-0x01b,0x00000f5e,
-0x01c,0x00000008,
-0x01d,0x00000607,
-0x01e,0x000006cc,
-0x01f,0x00000000,
-0x020,0x000001a5,
-0x01f,0x00000001,
-0x020,0x00000165,
-0x01f,0x00000002,
-0x020,0x000000c6,
-0x01f,0x00000003,
-0x020,0x00000086,
-0x01f,0x00000004,
-0x020,0x00000046,
-0x01f,0x00000005,
-0x020,0x000001e6,
-0x01f,0x00000006,
-0x020,0x000001a6,
-0x01f,0x00000007,
-0x020,0x00000166,
-0x01f,0x00000008,
-0x020,0x000000c7,
-0x01f,0x00000009,
-0x020,0x00000087,
-0x01f,0x0000000a,
-0x020,0x000000f7,
-0x01f,0x0000000b,
-0x020,0x000000d7,
-0x01f,0x0000000c,
-0x020,0x000000b7,
-0x01f,0x0000000d,
-0x020,0x00000097,
-0x01f,0x0000000e,
-0x020,0x00000077,
-0x01f,0x0000000f,
-0x020,0x00000057,
-0x01f,0x00000010,
-0x020,0x00000037,
-0x01f,0x00000011,
-0x020,0x000000fb,
-0x01f,0x00000012,
-0x020,0x000000db,
-0x01f,0x00000013,
-0x020,0x000000bb,
-0x01f,0x00000014,
-0x020,0x000000ff,
-0x01f,0x00000015,
-0x020,0x000000e3,
-0x01f,0x00000016,
-0x020,0x000000c3,
-0x01f,0x00000017,
-0x020,0x000000a3,
-0x01f,0x00000018,
-0x020,0x00000083,
-0x01f,0x00000019,
-0x020,0x00000063,
-0x01f,0x0000001a,
-0x020,0x00000043,
-0x01f,0x0000001b,
-0x020,0x00000023,
-0x01f,0x0000001c,
-0x020,0x00000003,
-0x01f,0x0000001d,
-0x020,0x000001e3,
-0x01f,0x0000001e,
-0x020,0x000001c3,
-0x01f,0x0000001f,
-0x020,0x000001a3,
-0x01f,0x00000020,
-0x020,0x00000183,
-0x01f,0x00000021,
-0x020,0x00000163,
-0x01f,0x00000022,
-0x020,0x00000143,
-0x01f,0x00000023,
-0x020,0x00000123,
-0x01f,0x00000024,
-0x020,0x00000103,
-0x023,0x00000203,
-0x024,0x00000200,
-0x00b,0x000001ba,
-0x02c,0x000003d7,
-0x02d,0x00000ff0,
-0x000,0x00000037,
-0x004,0x00000160,
-0x007,0x00000080,
-0x002,0x0000088d,
-0x0fe,0x00000000,
-0x0fe,0x00000000,
-0x016,0x00000200,
-0x016,0x00000380,
-0x016,0x00000020,
-0x016,0x000001a0,
-0x000,0x000000bf,
-0x00d,0x0000001f,
-0x00d,0x00000c9f,
-0x002,0x0000004d,
-0x000,0x00000cbf,
-0x004,0x00000975,
-0x007,0x00000700,
-};
-
-u32 Rtl8192UsbRadioB_Array[] = {
-0x019,0x00000003,
-0x000,0x000000bf,
-0x001,0x000006e0,
-0x002,0x0000004c,
-0x003,0x000007f1,
-0x004,0x00000975,
-0x005,0x00000c58,
-0x006,0x00000ae6,
-0x007,0x000000ca,
-0x008,0x00000e1c,
-0x000,0x000000b7,
-0x00a,0x00000850,
-0x000,0x000000bf,
-0x00b,0x000001ba,
-0x00c,0x00000240,
-0x00e,0x00000020,
-0x015,0x00000f80,
-0x016,0x00000020,
-0x017,0x00000597,
-0x018,0x0000050a,
-0x01a,0x00000e00,
-0x01b,0x00000f5e,
-0x01d,0x00000607,
-0x01e,0x000006cc,
-0x00b,0x000001ba,
-0x023,0x00000203,
-0x024,0x00000200,
-0x000,0x00000037,
-0x004,0x00000160,
-0x016,0x00000200,
-0x016,0x00000380,
-0x016,0x00000020,
-0x016,0x000001a0,
-0x00d,0x00000ccc,
-0x000,0x000000bf,
-0x002,0x0000004d,
-0x000,0x00000cbf,
-0x004,0x00000975,
-0x007,0x00000700,
-};
-
-u32 Rtl8192UsbRadioC_Array[] = {
-0x0, };
-
-u32 Rtl8192UsbRadioD_Array[] = {
-0x0, };
-
-u32 Rtl8192UsbMACPHY_Array[] = {
-0x03c,0xffff0000,0x00000f0f,
-0x340,0xffffffff,0x161a1a1a,
-0x344,0xffffffff,0x12121416,
-0x348,0x0000ffff,0x00001818,
-0x12c,0xffffffff,0x04000802,
-0x318,0x00000fff,0x00000100,
-};
-
-u32 Rtl8192UsbMACPHY_Array_PG[] = {
-0x03c,0xffff0000,0x00000f0f,
-0xe00,0xffffffff,0x06090909,
-0xe04,0xffffffff,0x00030306,
-0xe08,0x0000ff00,0x00000000,
-0xe10,0xffffffff,0x0a0c0d0f,
-0xe14,0xffffffff,0x06070809,
-0xe18,0xffffffff,0x0a0c0d0f,
-0xe1c,0xffffffff,0x06070809,
-0x12c,0xffffffff,0x04000802,
-0x318,0x00000fff,0x00000800,
-};
-
-u32 Rtl8192UsbAGCTAB_Array[] = {
-0xc78,0x7d000001,
-0xc78,0x7d010001,
-0xc78,0x7d020001,
-0xc78,0x7d030001,
-0xc78,0x7d040001,
-0xc78,0x7d050001,
-0xc78,0x7c060001,
-0xc78,0x7b070001,
-0xc78,0x7a080001,
-0xc78,0x79090001,
-0xc78,0x780a0001,
-0xc78,0x770b0001,
-0xc78,0x760c0001,
-0xc78,0x750d0001,
-0xc78,0x740e0001,
-0xc78,0x730f0001,
-0xc78,0x72100001,
-0xc78,0x71110001,
-0xc78,0x70120001,
-0xc78,0x6f130001,
-0xc78,0x6e140001,
-0xc78,0x6d150001,
-0xc78,0x6c160001,
-0xc78,0x6b170001,
-0xc78,0x6a180001,
-0xc78,0x69190001,
-0xc78,0x681a0001,
-0xc78,0x671b0001,
-0xc78,0x661c0001,
-0xc78,0x651d0001,
-0xc78,0x641e0001,
-0xc78,0x491f0001,
-0xc78,0x48200001,
-0xc78,0x47210001,
-0xc78,0x46220001,
-0xc78,0x45230001,
-0xc78,0x44240001,
-0xc78,0x43250001,
-0xc78,0x28260001,
-0xc78,0x27270001,
-0xc78,0x26280001,
-0xc78,0x25290001,
-0xc78,0x242a0001,
-0xc78,0x232b0001,
-0xc78,0x222c0001,
-0xc78,0x212d0001,
-0xc78,0x202e0001,
-0xc78,0x0a2f0001,
-0xc78,0x08300001,
-0xc78,0x06310001,
-0xc78,0x05320001,
-0xc78,0x04330001,
-0xc78,0x03340001,
-0xc78,0x02350001,
-0xc78,0x01360001,
-0xc78,0x00370001,
-0xc78,0x00380001,
-0xc78,0x00390001,
-0xc78,0x003a0001,
-0xc78,0x003b0001,
-0xc78,0x003c0001,
-0xc78,0x003d0001,
-0xc78,0x003e0001,
-0xc78,0x003f0001,
-0xc78,0x7d400001,
-0xc78,0x7d410001,
-0xc78,0x7d420001,
-0xc78,0x7d430001,
-0xc78,0x7d440001,
-0xc78,0x7d450001,
-0xc78,0x7c460001,
-0xc78,0x7b470001,
-0xc78,0x7a480001,
-0xc78,0x79490001,
-0xc78,0x784a0001,
-0xc78,0x774b0001,
-0xc78,0x764c0001,
-0xc78,0x754d0001,
-0xc78,0x744e0001,
-0xc78,0x734f0001,
-0xc78,0x72500001,
-0xc78,0x71510001,
-0xc78,0x70520001,
-0xc78,0x6f530001,
-0xc78,0x6e540001,
-0xc78,0x6d550001,
-0xc78,0x6c560001,
-0xc78,0x6b570001,
-0xc78,0x6a580001,
-0xc78,0x69590001,
-0xc78,0x685a0001,
-0xc78,0x675b0001,
-0xc78,0x665c0001,
-0xc78,0x655d0001,
-0xc78,0x645e0001,
-0xc78,0x495f0001,
-0xc78,0x48600001,
-0xc78,0x47610001,
-0xc78,0x46620001,
-0xc78,0x45630001,
-0xc78,0x44640001,
-0xc78,0x43650001,
-0xc78,0x28660001,
-0xc78,0x27670001,
-0xc78,0x26680001,
-0xc78,0x25690001,
-0xc78,0x246a0001,
-0xc78,0x236b0001,
-0xc78,0x226c0001,
-0xc78,0x216d0001,
-0xc78,0x206e0001,
-0xc78,0x0a6f0001,
-0xc78,0x08700001,
-0xc78,0x06710001,
-0xc78,0x05720001,
-0xc78,0x04730001,
-0xc78,0x03740001,
-0xc78,0x02750001,
-0xc78,0x01760001,
-0xc78,0x00770001,
-0xc78,0x00780001,
-0xc78,0x00790001,
-0xc78,0x007a0001,
-0xc78,0x007b0001,
-0xc78,0x007c0001,
-0xc78,0x007d0001,
-0xc78,0x007e0001,
-0xc78,0x007f0001,
-0xc78,0x2e00001e,
-0xc78,0x2e01001e,
-0xc78,0x2e02001e,
-0xc78,0x2e03001e,
-0xc78,0x2e04001e,
-0xc78,0x2e05001e,
-0xc78,0x3006001e,
-0xc78,0x3407001e,
-0xc78,0x3908001e,
-0xc78,0x3c09001e,
-0xc78,0x3f0a001e,
-0xc78,0x420b001e,
-0xc78,0x440c001e,
-0xc78,0x450d001e,
-0xc78,0x460e001e,
-0xc78,0x460f001e,
-0xc78,0x4710001e,
-0xc78,0x4811001e,
-0xc78,0x4912001e,
-0xc78,0x4a13001e,
-0xc78,0x4b14001e,
-0xc78,0x4b15001e,
-0xc78,0x4c16001e,
-0xc78,0x4d17001e,
-0xc78,0x4e18001e,
-0xc78,0x4f19001e,
-0xc78,0x4f1a001e,
-0xc78,0x501b001e,
-0xc78,0x511c001e,
-0xc78,0x521d001e,
-0xc78,0x521e001e,
-0xc78,0x531f001e,
-0xc78,0x5320001e,
-0xc78,0x5421001e,
-0xc78,0x5522001e,
-0xc78,0x5523001e,
-0xc78,0x5624001e,
-0xc78,0x5725001e,
-0xc78,0x5726001e,
-0xc78,0x5827001e,
-0xc78,0x5828001e,
-0xc78,0x5929001e,
-0xc78,0x592a001e,
-0xc78,0x5a2b001e,
-0xc78,0x5b2c001e,
-0xc78,0x5c2d001e,
-0xc78,0x5c2e001e,
-0xc78,0x5d2f001e,
-0xc78,0x5e30001e,
-0xc78,0x5f31001e,
-0xc78,0x6032001e,
-0xc78,0x6033001e,
-0xc78,0x6134001e,
-0xc78,0x6235001e,
-0xc78,0x6336001e,
-0xc78,0x6437001e,
-0xc78,0x6438001e,
-0xc78,0x6539001e,
-0xc78,0x663a001e,
-0xc78,0x673b001e,
-0xc78,0x673c001e,
-0xc78,0x683d001e,
-0xc78,0x693e001e,
-0xc78,0x6a3f001e,
-};
diff --git a/drivers/staging/rtl8192su/r819xU_firmware_img.h b/drivers/staging/rtl8192su/r819xU_firmware_img.h
deleted file mode 100644
index d9d9515..0000000
--- a/drivers/staging/rtl8192su/r819xU_firmware_img.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef IMG_H
-#define IMG_H
-
-#define BOOT_ARR_LEN 344
-#define MAIN_ARR_LEN 45136
-#define DATA_ARR_LEN 796
-#define MACPHY_Array_PGLength 30
-#define PHY_REG_1T2RArrayLength 296
-#define AGCTAB_ArrayLength 384
-#define MACPHY_ArrayLength 18
-
-#define RadioA_ArrayLength 246
-#define RadioB_ArrayLength 78
-#define RadioC_ArrayLength 1
-#define RadioD_ArrayLength 1
-#define PHY_REGArrayLength 1
-
-
-extern u8 rtl8190_fwboot_array[BOOT_ARR_LEN];
-extern u8 rtl8190_fwmain_array[MAIN_ARR_LEN];
-extern u8 rtl8190_fwdata_array[DATA_ARR_LEN];
-
-extern u32 Rtl8192UsbPHY_REGArray[];
-extern u32 Rtl8192UsbPHY_REG_1T2RArray[];
-extern u32 Rtl8192UsbRadioA_Array[];
-extern u32 Rtl8192UsbRadioB_Array[];
-extern u32 Rtl8192UsbRadioC_Array[];
-extern u32 Rtl8192UsbRadioD_Array[];
-extern u32 Rtl8192UsbMACPHY_Array[];
-extern u32 Rtl8192UsbMACPHY_Array_PG[];
-extern u32 Rtl8192UsbAGCTAB_Array[];
-
-
-
-#endif
diff --git a/drivers/staging/rtl8192su/r819xU_phy.c b/drivers/staging/rtl8192su/r819xU_phy.c
deleted file mode 100644
index 00497d3..0000000
--- a/drivers/staging/rtl8192su/r819xU_phy.c
+++ /dev/null
@@ -1,1826 +0,0 @@
-#include "r8192U.h"
-#include "r8192U_hw.h"
-#include "r819xU_phy.h"
-#include "r819xU_phyreg.h"
-#include "r8190_rtl8256.h"
-#include "r8192U_dm.h"
-#include "r819xU_firmware_img.h"
-
-#ifdef ENABLE_DOT11D
-#include "dot11d.h"
-#endif
-static u32 RF_CHANNEL_TABLE_ZEBRA[] = {
-	0,
-	0x085c, //2412 1
-	0x08dc, //2417 2
-	0x095c, //2422 3
-	0x09dc, //2427 4
-	0x0a5c, //2432 5
-	0x0adc, //2437 6
-	0x0b5c, //2442 7
-	0x0bdc, //2447 8
-	0x0c5c, //2452 9
-	0x0cdc, //2457 10
-	0x0d5c, //2462 11
-	0x0ddc, //2467 12
-	0x0e5c, //2472 13
-	0x0f72, //2484
-};
-
-
-#define rtl819XPHY_REG_1T2RArray Rtl8192UsbPHY_REG_1T2RArray
-#define rtl819XMACPHY_Array_PG Rtl8192UsbMACPHY_Array_PG
-#define rtl819XMACPHY_Array Rtl8192UsbMACPHY_Array
-#define rtl819XRadioA_Array  Rtl8192UsbRadioA_Array
-#define rtl819XRadioB_Array Rtl8192UsbRadioB_Array
-#define rtl819XRadioC_Array Rtl8192UsbRadioC_Array
-#define rtl819XRadioD_Array Rtl8192UsbRadioD_Array
-#define rtl819XAGCTAB_Array Rtl8192UsbAGCTAB_Array
-
-/******************************************************************************
- *function:  This function read BB parameters from Header file we gen,
- *	     and do register read/write
- *   input:  u32	dwBitMask  //taget bit pos in the addr to be modified
- *  output:  none
- *  return:  u32	return the shift bit bit position of the mask
- * ****************************************************************************/
-u32 rtl8192_CalculateBitShift(u32 dwBitMask)
-{
-	u32 i;
-	for (i=0; i<=31; i++)
-	{
-		if (((dwBitMask>>i)&0x1) == 1)
-			break;
-	}
-	return i;
-}
-/******************************************************************************
- *function:  This function check different RF type to execute legal judgement. If RF Path is illegal, we will return false.
- *   input:  none
- *  output:  none
- *  return:  0(illegal, false), 1(legal,true)
- * ***************************************************************************/
-u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath)
-{
-	u8 ret = 1;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	if (priv->rf_type == RF_2T4R)
-		ret = 0;
-	else if (priv->rf_type == RF_1T2R)
-	{
-		if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B)
-			ret = 1;
-		else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D)
-			ret = 0;
-	}
-	return ret;
-}
-/******************************************************************************
- *function:  This function set specific bits to BB register
- *   input:  net_device dev
- *           u32	dwRegAddr  //target addr to be modified
- *           u32	dwBitMask  //taget bit pos in the addr to be modified
- *           u32	dwData     //value to be write
- *  output:  none
- *  return:  none
- *  notice:
- * ****************************************************************************/
-void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData)
-{
-
-	u32 OriginalValue, BitShift, NewValue;
-
-	if(dwBitMask!= bMaskDWord)
-	{//if not "double word" write
-		OriginalValue = read_nic_dword(dev, dwRegAddr);
-		BitShift = rtl8192_CalculateBitShift(dwBitMask);
-            	NewValue = (((OriginalValue) & (~dwBitMask)) | (dwData << BitShift));
-		write_nic_dword(dev, dwRegAddr, NewValue);
-	}else
-		write_nic_dword(dev, dwRegAddr, dwData);
-	return;
-}
-/******************************************************************************
- *function:  This function reads specific bits from BB register
- *   input:  net_device dev
- *           u32	dwRegAddr  //target addr to be readback
- *           u32	dwBitMask  //taget bit pos in the addr to be readback
- *  output:  none
- *  return:  u32	Data	//the readback register value
- *  notice:
- * ****************************************************************************/
-u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask)
-{
-	u32 Ret = 0, OriginalValue, BitShift;
-
-	OriginalValue = read_nic_dword(dev, dwRegAddr);
-	BitShift = rtl8192_CalculateBitShift(dwBitMask);
-	Ret =(OriginalValue & dwBitMask) >> BitShift;
-
-	return (Ret);
-}
-static  u32 phy_FwRFSerialRead( struct net_device* dev, RF90_RADIO_PATH_E       eRFPath, u32 Offset  );
-
-static void phy_FwRFSerialWrite( struct net_device* dev, RF90_RADIO_PATH_E       eRFPath, u32  Offset, u32  Data);
-
-/******************************************************************************
- *function:  This function read register from RF chip
- *   input:  net_device dev
- *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
- *           u32	Offset     //target address to be read
- *  output:  none
- *  return:  u32 	readback value
- *  notice:  There are three types of serial operations:(1) Software serial write.(2)Hardware LSSI-Low Speed Serial Interface.(3)Hardware HSSI-High speed serial write. Driver here need to implement (1) and (2)---need more spec for this information.
- * ****************************************************************************/
-u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32 ret = 0;
-	u32 NewOffset = 0;
-	BB_REGISTER_DEFINITION_T* pPhyReg = &priv->PHYRegDef[eRFPath];
-	rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0);
-	//make sure RF register offset is correct
-	Offset &= 0x3f;
-
-	//switch page for 8256 RF IC
-	if (priv->rf_chip == RF_8256)
-	{
-		if (Offset >= 31)
-		{
-			priv->RfReg0Value[eRFPath] |= 0x140;
-			//Switch to Reg_Mode2 for Reg 31-45
-			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) );
-			//modify offset
-			NewOffset = Offset -30;
-		}
-		else if (Offset >= 16)
-		{
-			priv->RfReg0Value[eRFPath] |= 0x100;
-			priv->RfReg0Value[eRFPath] &= (~0x40);
-			//Switch to Reg_Mode 1 for Reg16-30
-			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) );
-
-			NewOffset = Offset - 15;
-		}
-		else
-			NewOffset = Offset;
-	}
-	else
-	{
-		RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
-		NewOffset = Offset;
-	}
-	//put desired read addr to LSSI control Register
-	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset);
-	//Issue a posedge trigger
-	//
-	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x0);
-	rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2,  bLSSIReadEdge, 0x1);
-
-
-	// TODO: we should not delay such a  long time. Ask help from SD3
-	msleep(1);
-
-	ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData);
-
-
-	// Switch back to Reg_Mode0;
-	if(priv->rf_chip == RF_8256)
-	{
-		priv->RfReg0Value[eRFPath] &= 0xebf;
-
-		rtl8192_setBBreg(
-			dev,
-			pPhyReg->rf3wireOffset,
-			bMaskDWord,
-			(priv->RfReg0Value[eRFPath] << 16));
-	}
-
-	return ret;
-
-}
-
-/******************************************************************************
- *function:  This function write data to RF register
- *   input:  net_device dev
- *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
- *           u32	Offset     //target address to be written
- *           u32	Data	//The new register data to be written
- *  output:  none
- *  return:  none
- *  notice:  For RF8256 only.
-  ===========================================================
- *Reg Mode	RegCTL[1]	RegCTL[0]		Note
- *		(Reg00[12])	(Reg00[10])
- *===========================================================
- *Reg_Mode0	0		x			Reg 0 ~15(0x0 ~ 0xf)
- *------------------------------------------------------------------
- *Reg_Mode1	1		0			Reg 16 ~30(0x1 ~ 0xf)
- *------------------------------------------------------------------
- * Reg_Mode2	1		1			Reg 31 ~ 45(0x1 ~ 0xf)
- *------------------------------------------------------------------
- * ****************************************************************************/
-void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32 DataAndAddr = 0, NewOffset = 0;
-	BB_REGISTER_DEFINITION_T	*pPhyReg = &priv->PHYRegDef[eRFPath];
-
-	Offset &= 0x3f;
-	//spin_lock_irqsave(&priv->rf_lock, flags);
-//	down(&priv->rf_sem);
-	if (priv->rf_chip == RF_8256)
-	{
-
-		if (Offset >= 31)
-		{
-			priv->RfReg0Value[eRFPath] |= 0x140;
-			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16));
-			NewOffset = Offset - 30;
-		}
-		else if (Offset >= 16)
-		{
-			priv->RfReg0Value[eRFPath] |= 0x100;
-			priv->RfReg0Value[eRFPath] &= (~0x40);
-			rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16));
-			NewOffset = Offset - 15;
-		}
-		else
-			NewOffset = Offset;
-	}
-	else
-	{
-		RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be 8256\n");
-		NewOffset = Offset;
-	}
-
-	// Put write addr in [5:0]  and write data in [31:16]
-	DataAndAddr = (Data<<16) | (NewOffset&0x3f);
-
-	// Write Operation
-	rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr);
-
-
-	if(Offset==0x0)
-		priv->RfReg0Value[eRFPath] = Data;
-
-	// Switch back to Reg_Mode0;
- 	if(priv->rf_chip == RF_8256)
-	{
-		if(Offset != 0)
-		{
-			priv->RfReg0Value[eRFPath] &= 0xebf;
-			rtl8192_setBBreg(
-				dev,
-				pPhyReg->rf3wireOffset,
-				bMaskDWord,
-				(priv->RfReg0Value[eRFPath] << 16));
-		}
-	}
-	//spin_unlock_irqrestore(&priv->rf_lock, flags);
-//	up(&priv->rf_sem);
-	return;
-}
-
-/******************************************************************************
- *function:  This function set specific bits to RF register
- *   input:  net_device dev
- *   	     RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D
- *           u32	RegAddr  //target addr to be modified
- *           u32	BitMask  //taget bit pos in the addr to be modified
- *           u32	Data     //value to be write
- *  output:  none
- *  return:  none
- *  notice:
- * ****************************************************************************/
-void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32 Original_Value, BitShift, New_Value;
-//	u8	time = 0;
-
-	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
-		return;
-
-	if (priv->Rf_Mode == RF_OP_By_FW)
-	{
-		if (BitMask != bMask12Bits) // RF data is 12 bits only
-		{
-			Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
-			BitShift =  rtl8192_CalculateBitShift(BitMask);
-			New_Value = ((Original_Value) & (~BitMask)) | (Data<< BitShift);
-
-			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value);
-		}else
-			phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data);
-
-		udelay(200);
-
-	}
-	else
-	{
-		if (BitMask != bMask12Bits) // RF data is 12 bits only
-   	        {
-			Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
-      			BitShift =  rtl8192_CalculateBitShift(BitMask);
-      			New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift));
-
-			rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, New_Value);
-	        }else
-			rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data);
-	}
-	return;
-}
-
-/******************************************************************************
- *function:  This function reads specific bits from RF register
- *   input:  net_device dev
- *           u32	RegAddr  //target addr to be readback
- *           u32	BitMask  //taget bit pos in the addr to be readback
- *  output:  none
- *  return:  u32	Data	//the readback register value
- *  notice:
- * ****************************************************************************/
-u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask)
-{
-	u32 Original_Value, Readback_Value, BitShift;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-
-	if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
-		return 0;
-	if (priv->Rf_Mode == RF_OP_By_FW)
-	{
-		Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr);
-		BitShift =  rtl8192_CalculateBitShift(BitMask);
-		Readback_Value = (Original_Value & BitMask) >> BitShift;
-		udelay(200);
-		return (Readback_Value);
-	}
-	else
-	{
-		Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, RegAddr);
-   		BitShift =  rtl8192_CalculateBitShift(BitMask);
-   		Readback_Value = (Original_Value & BitMask) >> BitShift;
-		return (Readback_Value);
-	}
-}
-/******************************************************************************
- *function:  We support firmware to execute RF-R/W.
- *   input:  dev
- *  output:  none
- *  return:  none
- *  notice:
- * ***************************************************************************/
-static	u32
-phy_FwRFSerialRead(
-	struct net_device* dev,
-	RF90_RADIO_PATH_E	eRFPath,
-	u32				Offset	)
-{
-	u32		retValue = 0;
-	u32		Data = 0;
-	u8		time = 0;
-	//DbgPrint("FW RF CTRL\n\r");
-	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
-	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
-	   much time. This is only for site survey. */
-	// 1. Read operation need not insert data. bit 0-11
-	//Data &= bMask12Bits;
-	// 2. Write RF register address. Bit 12-19
-	Data |= ((Offset&0xFF)<<12);
-	// 3. Write RF path.  bit 20-21
-	Data |= ((eRFPath&0x3)<<20);
-	// 4. Set RF read indicator. bit 22=0
-	//Data |= 0x00000;
-	// 5. Trigger Fw to operate the command. bit 31
-	Data |= 0x80000000;
-	// 6. We can not execute read operation if bit 31 is 1.
-	while (read_nic_dword(dev, QPNR)&0x80000000)
-	{
-		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
-		if (time++ < 100)
-		{
-			//DbgPrint("FW not finish RF-R Time=%d\n\r", time);
-			udelay(10);
-		}
-		else
-			break;
-	}
-	// 7. Execute read operation.
-	write_nic_dword(dev, QPNR, Data);
-	// 8. Check if firmawre send back RF content.
-	while (read_nic_dword(dev, QPNR)&0x80000000)
-	{
-		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
-		if (time++ < 100)
-		{
-			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
-			udelay(10);
-		}
-		else
-			return	(0);
-	}
-	retValue = read_nic_dword(dev, RF_DATA);
-
-	return	(retValue);
-
-}	/* phy_FwRFSerialRead */
-
-/******************************************************************************
- *function:  We support firmware to execute RF-R/W.
- *   input:  dev
- *  output:  none
- *  return:  none
- *  notice:
- * ***************************************************************************/
-static void
-phy_FwRFSerialWrite(
-		struct net_device* dev,
-		RF90_RADIO_PATH_E	eRFPath,
-		u32				Offset,
-		u32				Data	)
-{
-	u8	time = 0;
-
-	//DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data);
-	/* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can
-	   not execute the scheme in the initial step. Otherwise, RF-R/W will waste
-	   much time. This is only for site survey. */
-
-	// 1. Set driver write bit and 12 bit data. bit 0-11
-	//Data &= bMask12Bits;	// Done by uper layer.
-	// 2. Write RF register address. bit 12-19
-	Data |= ((Offset&0xFF)<<12);
-	// 3. Write RF path.  bit 20-21
-	Data |= ((eRFPath&0x3)<<20);
-	// 4. Set RF write indicator. bit 22=1
-	Data |= 0x400000;
-	// 5. Trigger Fw to operate the command. bit 31=1
-	Data |= 0x80000000;
-
-	// 6. Write operation. We can not write if bit 31 is 1.
-	while (read_nic_dword(dev, QPNR)&0x80000000)
-	{
-		// If FW can not finish RF-R/W for more than ?? times. We must reset FW.
-		if (time++ < 100)
-		{
-			//DbgPrint("FW not finish RF-W Time=%d\n\r", time);
-			udelay(10);
-		}
-		else
-			break;
-	}
-	// 7. No matter check bit. We always force the write. Because FW will
-	//    not accept the command.
-	write_nic_dword(dev, QPNR, Data);
-	/* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware
-	   to finish RF write operation. */
-	/* 2008/01/17 MH We support delay in firmware side now. */
-	//delay_us(20);
-
-}	/* phy_FwRFSerialWrite */
-
-
-/******************************************************************************
- *function:  This function read BB parameters from Header file we gen,
- *	     and do register read/write
- *   input:  dev
- *  output:  none
- *  return:  none
- *  notice:  BB parameters may change all the time, so please make
- *           sure it has been synced with the newest.
- * ***************************************************************************/
-void rtl8192_phy_configmac(struct net_device* dev)
-{
-	u32 dwArrayLen = 0, i;
-	u32* pdwArray = NULL;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	if(priv->btxpowerdata_readfromEEPORM)
-	{
-		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n");
-		dwArrayLen = MACPHY_Array_PGLength;
-		pdwArray = rtl819XMACPHY_Array_PG;
-
-	}
-	else
-	{
-		RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array\n");
-		dwArrayLen = MACPHY_ArrayLength;
-		pdwArray = rtl819XMACPHY_Array;
-	}
-	for(i = 0; i<dwArrayLen; i=i+3){
-		if(pdwArray[i] == 0x318)
-		{
-			pdwArray[i+2] = 0x00000800;
-			//DbgPrint("ptrArray[i], ptrArray[i+1], ptrArray[i+2] = %x, %x, %x\n",
-			//	ptrArray[i], ptrArray[i+1], ptrArray[i+2]);
-		}
-
-		RT_TRACE(COMP_DBG, "The Rtl8190MACPHY_Array[0] is %x Rtl8190MACPHY_Array[1] is %x Rtl8190MACPHY_Array[2] is %x\n",
-				pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
-		rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], pdwArray[i+2]);
-	}
-	return;
-
-}
-
-/******************************************************************************
- *function:  This function do dirty work
- *   input:  dev
- *  output:  none
- *  return:  none
- *  notice:  BB parameters may change all the time, so please make
- *           sure it has been synced with the newest.
- * ***************************************************************************/
-
-void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType)
-{
-	u32 i;
-
-#ifdef TO_DO_LIST
-	u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL;
-	if(Adapter->bInHctTest)
-	{
-		PHY_REGArrayLen = PHY_REGArrayLengthDTM;
-		AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM;
-		Rtl8190PHY_REGArray_Table = Rtl819XPHY_REGArrayDTM;
-		Rtl8190AGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM;
-	}
-#endif
-	if (ConfigType == BaseBand_Config_PHY_REG)
-	{
-		for (i=0; i<PHY_REG_1T2RArrayLength; i+=2)
-		{
-			rtl8192_setBBreg(dev, rtl819XPHY_REG_1T2RArray[i], bMaskDWord, rtl819XPHY_REG_1T2RArray[i+1]);
-			RT_TRACE(COMP_DBG, "i: %x, The Rtl819xUsbPHY_REGArray[0] is %x Rtl819xUsbPHY_REGArray[1] is %x \n",i, rtl819XPHY_REG_1T2RArray[i], rtl819XPHY_REG_1T2RArray[i+1]);
-		}
-	}
-	else if (ConfigType == BaseBand_Config_AGC_TAB)
-	{
-		for (i=0; i<AGCTAB_ArrayLength; i+=2)
-		{
-			rtl8192_setBBreg(dev, rtl819XAGCTAB_Array[i], bMaskDWord, rtl819XAGCTAB_Array[i+1]);
-			RT_TRACE(COMP_DBG, "i:%x, The rtl819XAGCTAB_Array[0] is %x rtl819XAGCTAB_Array[1] is %x \n",i, rtl819XAGCTAB_Array[i], rtl819XAGCTAB_Array[i+1]);
-		}
-	}
-	return;
-
-
-}
-/******************************************************************************
- *function:  This function initialize Register definition offset for Radio Path
- *	     A/B/C/D
- *   input:  net_device dev
- *  output:  none
- *  return:  none
- *  notice:  Initialization value here is constant and it should never be changed
- * ***************************************************************************/
-void rtl8192_InitBBRFRegDef(struct net_device* dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-// RF Interface Sowrtware Control
-	priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870
-	priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872)
-	priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874
-	priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876)
-
-	// RF Interface Readback Value
-	priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0
-	priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2)
-	priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4
-	priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6)
-
-	// RF Interface Output (and Enable)
-	priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860
-	priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864
-	priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868
-	priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C
-
-	// RF Interface (Output and)  Enable
-	priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862)
-	priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866)
-	priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A)
-	priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E)
-
-	//Addr of LSSI. Wirte RF register by driver
-	priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter
-	priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter;
-	priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter;
-	priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter;
-
-	// RF parameter
-	priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter;  //BB Band Select
-	priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter;
-	priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter;
-	priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter;
-
-	// Tx AGC Gain Stage (same for all path. Should we remove this?)
-	priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
-	priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
-	priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
-	priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage
-
-	// Tranceiver A~D HSSI Parameter-1
-	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1;  //wire control parameter1
-	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1;  //wire control parameter1
-	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1;  //wire control parameter1
-	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1;  //wire control parameter1
-
-	// Tranceiver A~D HSSI Parameter-2
-	priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2;  //wire control parameter2
-	priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2;  //wire control parameter2
-	priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2;  //wire control parameter2
-	priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2;  //wire control parameter1
-
-	// RF switch Control
-	priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control
-	priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl;
-	priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl;
-	priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl;
-
-	// AGC control 1
-	priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1;
-	priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1;
-	priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1;
-	priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1;
-
-	// AGC control 2
-	priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2;
-	priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2;
-	priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2;
-	priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2;
-
-	// RX AFE control 1
-	priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance;
-	priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance;
-	priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance;
-	priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance;
-
-	// RX AFE control 1
-	priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE;
-	priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE;
-	priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE;
-	priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE;
-
-	// Tx AFE control 1
-	priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance;
-	priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance;
-	priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance;
-	priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance;
-
-	// Tx AFE control 2
-	priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE;
-	priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE;
-	priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE;
-	priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE;
-
-	// Tranceiver LSSI Readback
-	priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack;
-	priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack;
-	priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack;
-	priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack;
-
-}
-/******************************************************************************
- *function:  This function is to write register and then readback to make sure whether BB and RF is OK
- *   input:  net_device dev
- *   	     HW90_BLOCK_E CheckBlock
- *   	     RF90_RADIO_PATH_E eRFPath  //only used when checkblock is HW90_BLOCK_RF
- *  output:  none
- *  return:  return whether BB and RF is ok(0:OK; 1:Fail)
- *  notice:  This function may be removed in the ASIC
- * ***************************************************************************/
-u8 rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath)
-{
-//	struct r8192_priv *priv = ieee80211_priv(dev);
-//	BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath];
-	u8 ret = 0;
-	u32 i, CheckTimes = 4, dwRegRead = 0;
-	u32 WriteAddr[4];
-	u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f};
-	// Initialize register address offset to be checked
-	WriteAddr[HW90_BLOCK_MAC] = 0x100;
-	WriteAddr[HW90_BLOCK_PHY0] = 0x900;
-	WriteAddr[HW90_BLOCK_PHY1] = 0x800;
-	WriteAddr[HW90_BLOCK_RF] = 0x3;
-	RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __FUNCTION__, CheckBlock);
-	for(i=0 ; i < CheckTimes ; i++)
-	{
-
-		//
-		// Write Data to register and readback
-		//
-		switch(CheckBlock)
-		{
-		case HW90_BLOCK_MAC:
-			RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write 0x100 here!");
-			break;
-
-		case HW90_BLOCK_PHY0:
-		case HW90_BLOCK_PHY1:
-			write_nic_dword(dev, WriteAddr[CheckBlock], WriteData[i]);
-			dwRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]);
-			break;
-
-		case HW90_BLOCK_RF:
-			WriteData[i] &= 0xfff;
-			rtl8192_phy_SetRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]);
-			// TODO: we should not delay for such a long time. Ask SD3
-			msleep(1);
-			dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits);
-			msleep(1);
-			break;
-
-		default:
-			ret = 1;
-			break;
-		}
-
-
-		//
-		// Check whether readback data is correct
-		//
-		if(dwRegRead != WriteData[i])
-		{
-			RT_TRACE((COMP_PHY|COMP_ERR), "====>error=====dwRegRead: %x, WriteData: %x \n", dwRegRead, WriteData[i]);
-			ret = 1;
-			break;
-		}
-	}
-
-	return ret;
-}
-
-
-/******************************************************************************
- *function:  This function initialize BB&RF
- *   input:  net_device dev
- *  output:  none
- *  return:  none
- *  notice:  Initialization value may change all the time, so please make
- *           sure it has been synced with the newest.
- * ***************************************************************************/
-void rtl8192_BB_Config_ParaFile(struct net_device* dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u8 bRegValue = 0, eCheckItem = 0, rtStatus = 0;
-	u32 dwRegValue = 0;
-	/**************************************
-	//<1>Initialize BaseBand
-	**************************************/
-
-	/*--set BB Global Reset--*/
-	bRegValue = read_nic_byte(dev, BB_GLOBAL_RESET);
-	write_nic_byte(dev, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT));
-	mdelay(50);
-	/*---set BB reset Active---*/
-	dwRegValue = read_nic_dword(dev, CPU_GEN);
-	write_nic_dword(dev, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST)));
-
-	/*----Ckeck FPGAPHY0 and PHY1 board is OK----*/
-	// TODO: this function should be removed on ASIC , Emily 2007.2.2
-	for(eCheckItem=(HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem<=HW90_BLOCK_PHY1; eCheckItem++)
-	{
-		rtStatus  = rtl8192_phy_checkBBAndRF(dev, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path
-		if(rtStatus != 0)
-		{
-			RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1);
-			return ;
-		}
-	}
-	/*---- Set CCK and OFDM Block "OFF"----*/
-	rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0);
-	/*----BB Register Initilazation----*/
-	//==m==>Set PHY REG From Header<==m==
-	rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG);
-
-	/*----Set BB reset de-Active----*/
-	dwRegValue = read_nic_dword(dev, CPU_GEN);
-	write_nic_dword(dev, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST));
-
- 	/*----BB AGC table Initialization----*/
-	//==m==>Set PHY REG From Header<==m==
-	rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB);
-
-	/*----Enable XSTAL ----*/
-	write_nic_byte_E(dev, 0x5e, 0x00);
-	if (priv->card_8192_version == (u8)VERSION_819xU_A)
-	{
-		//Antenna gain offset from B/C/D to A
-		dwRegValue = (priv->AntennaTxPwDiff[1]<<4 | priv->AntennaTxPwDiff[0]);
-		rtl8192_setBBreg(dev, rFPGA0_TxGainStage, (bXBTxAGC|bXCTxAGC), dwRegValue);
-
-		//XSTALLCap
-		dwRegValue = priv->CrystalCap & 0xf;
-		rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap, dwRegValue);
-	}
-
-	// Check if the CCK HighPower is turned ON.
-	// This is used to calculate PWDB.
-	priv->bCckHighPower = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200));
-	return;
-}
-/******************************************************************************
- *function:  This function initialize BB&RF
- *   input:  net_device dev
- *  output:  none
- *  return:  none
- *  notice:  Initialization value may change all the time, so please make
- *           sure it has been synced with the newest.
- * ***************************************************************************/
-void rtl8192_BBConfig(struct net_device* dev)
-{
-	rtl8192_InitBBRFRegDef(dev);
-	//config BB&RF. As hardCode based initialization has not been well
-	//implemented, so use file first.FIXME:should implement it for hardcode?
-	rtl8192_BB_Config_ParaFile(dev);
-	return;
-}
-
-/******************************************************************************
- *function:  This function obtains the initialization value of Tx power Level offset
- *   input:  net_device dev
- *  output:  none
- *  return:  none
- * ***************************************************************************/
-void rtl8192_phy_getTxPower(struct net_device* dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	priv->MCSTxPowerLevelOriginalOffset[0] =
-		read_nic_dword(dev, rTxAGC_Rate18_06);
-	priv->MCSTxPowerLevelOriginalOffset[1] =
-		read_nic_dword(dev, rTxAGC_Rate54_24);
-	priv->MCSTxPowerLevelOriginalOffset[2] =
-		read_nic_dword(dev, rTxAGC_Mcs03_Mcs00);
-	priv->MCSTxPowerLevelOriginalOffset[3] =
-		read_nic_dword(dev, rTxAGC_Mcs07_Mcs04);
-	priv->MCSTxPowerLevelOriginalOffset[4] =
-		read_nic_dword(dev, rTxAGC_Mcs11_Mcs08);
-	priv->MCSTxPowerLevelOriginalOffset[5] =
-		read_nic_dword(dev, rTxAGC_Mcs15_Mcs12);
-
-	// read rx initial gain
-	priv->DefaultInitialGain[0] = read_nic_byte(dev, rOFDM0_XAAGCCore1);
-	priv->DefaultInitialGain[1] = read_nic_byte(dev, rOFDM0_XBAGCCore1);
-	priv->DefaultInitialGain[2] = read_nic_byte(dev, rOFDM0_XCAGCCore1);
-	priv->DefaultInitialGain[3] = read_nic_byte(dev, rOFDM0_XDAGCCore1);
-	RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x) \n",
-		priv->DefaultInitialGain[0], priv->DefaultInitialGain[1],
-		priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]);
-
-	// read framesync
-	priv->framesync = read_nic_byte(dev, rOFDM0_RxDetector3);
-	priv->framesyncC34 = read_nic_byte(dev, rOFDM0_RxDetector2);
-	RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x \n",
-		rOFDM0_RxDetector3, priv->framesync);
-
-	// read SIFS (save the value read fome MACPHY_REG.txt)
-	priv->SifsTime = read_nic_word(dev, SIFS);
-
-	return;
-}
-
-/******************************************************************************
- *function:  This function obtains the initialization value of Tx power Level offset
- *   input:  net_device dev
- *  output:  none
- *  return:  none
- * ***************************************************************************/
-void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u8	powerlevel = priv->TxPowerLevelCCK[channel-1];
-	u8	powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
-
-	switch(priv->rf_chip)
-	{
-	case RF_8256:
-		PHY_SetRF8256CCKTxPower(dev, powerlevel); //need further implement
-		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
-		break;
-	default:
-//	case RF_8225:
-//	case RF_8258:
-		RT_TRACE((COMP_PHY|COMP_ERR), "error RF chipID(8225 or 8258) in function %s()\n", __FUNCTION__);
-		break;
-	}
-	return;
-}
-
-/******************************************************************************
- *function:  This function check Rf chip to do RF config
- *   input:  net_device dev
- *  output:  none
- *  return:  only 8256 is supported
- * ***************************************************************************/
-void rtl8192_phy_RFConfig(struct net_device* dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	switch(priv->rf_chip)
-	{
-		case RF_8256:
-			PHY_RF8256_Config(dev);
-			break;
-	//	case RF_8225:
-	//	case RF_8258:
-		default:
-			RT_TRACE(COMP_ERR, "error chip id\n");
-			break;
-	}
-	return;
-}
-
-/******************************************************************************
- *function:  This function update Initial gain
- *   input:  net_device dev
- *  output:  none
- *  return:  As Windows has not implemented this, wait for complement
- * ***************************************************************************/
-void rtl8192_phy_updateInitGain(struct net_device* dev)
-{
-	return;
-}
-
-/******************************************************************************
- *function:  This function read RF parameters from general head file, and do RF 3-wire
- *   input:  net_device dev
- *  output:  none
- *  return:  return code show if RF configuration is successful(0:pass, 1:fail)
- *    Note:  Delay may be required for RF configuration
- * ***************************************************************************/
-u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E	eRFPath)
-{
-
-	int i;
-	//u32* pRFArray;
-	u8 ret = 0;
-
-	switch(eRFPath){
-		case RF90_PATH_A:
-			for(i = 0;i<RadioA_ArrayLength; i=i+2){
-
-				if(rtl819XRadioA_Array[i] == 0xfe){
-						mdelay(100);
-						continue;
-				}
-				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioA_Array[i], bMask12Bits, rtl819XRadioA_Array[i+1]);
-				mdelay(1);
-
-			}
-			break;
-		case RF90_PATH_B:
-			for(i = 0;i<RadioB_ArrayLength; i=i+2){
-
-				if(rtl819XRadioB_Array[i] == 0xfe){
-						mdelay(100);
-						continue;
-				}
-				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioB_Array[i], bMask12Bits, rtl819XRadioB_Array[i+1]);
-				mdelay(1);
-
-			}
-			break;
-		case RF90_PATH_C:
-			for(i = 0;i<RadioC_ArrayLength; i=i+2){
-
-				if(rtl819XRadioC_Array[i] == 0xfe){
-						mdelay(100);
-						continue;
-				}
-				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioC_Array[i], bMask12Bits, rtl819XRadioC_Array[i+1]);
-				mdelay(1);
-
-			}
-			break;
-		case RF90_PATH_D:
-			for(i = 0;i<RadioD_ArrayLength; i=i+2){
-
-				if(rtl819XRadioD_Array[i] == 0xfe){
-						mdelay(100);
-						continue;
-				}
-				rtl8192_phy_SetRFReg(dev, eRFPath, rtl819XRadioD_Array[i], bMask12Bits, rtl819XRadioD_Array[i+1]);
-				mdelay(1);
-
-			}
-			break;
-		default:
-			break;
-	}
-
-	return ret;;
-
-}
-/******************************************************************************
- *function:  This function set Tx Power of the channel
- *   input:  struct net_device *dev
- *   	     u8 		channel
- *  output:  none
- *  return:  none
- *    Note:
- * ***************************************************************************/
-void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u8	powerlevel = priv->TxPowerLevelCCK[channel-1];
-	u8	powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1];
-
-	switch(priv->rf_chip)
-	{
-	case RF_8225:
-#ifdef TO_DO_LIST
-		PHY_SetRF8225CckTxPower(Adapter, powerlevel);
-		PHY_SetRF8225OfdmTxPower(Adapter, powerlevelOFDM24G);
-#endif
-		break;
-
-	case RF_8256:
-		PHY_SetRF8256CCKTxPower(dev, powerlevel);
-		PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G);
-		break;
-
-	case RF_8258:
-		break;
-	default:
-		RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPowerLevel()\n");
-		break;
-	}
-	return;
-}
-
-/******************************************************************************
- *function:  This function set RF state on or off
- *   input:  struct net_device *dev
- *   	     RT_RF_POWER_STATE eRFPowerState  //Power State to set
- *  output:  none
- *  return:  none
- *    Note:
- * ***************************************************************************/
-bool rtl8192_SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState)
-{
-	bool				bResult = true;
-//	u8					eRFPath;
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	if(eRFPowerState == priv->ieee80211->eRFPowerState)
-		return false;
-
-	if(priv->SetRFPowerStateInProgress == true)
-		return false;
-
-	priv->SetRFPowerStateInProgress = true;
-
-	switch(priv->rf_chip)
-	{
-		case RF_8256:
-		switch( eRFPowerState )
-		{
-			case eRfOn:
-#if 0
-						rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1);		// 0x860[4]
-						rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);		// 0x88c[4]
-						rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); 		// 0x880[6:5]
-						rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x3);			// 0xc04[3:0]
-						rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x3);			// 0xd04[3:0]
-						rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x7000, 0x3);	// 0x884[14:12]
-	//					for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
-		//					PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
-
-						//SwChnl(Adapter->ChannelID);
-#endif
-	//RF-A, RF-B
-					//enable RF-Chip A/B
-					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1);	// 0x860[4]
-					//analog to digital on
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8]
-					//digital to analog on
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3]
-					//rx antenna on
-					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
-					//rx antenna on
-					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
-					//analog to digital part2 on
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5]
-
-				break;
-
-			case eRfSleep:
-
-				break;
-
-			case eRfOff:
-#if 0
-						rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);		// 0x860[4]
-						rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0);		// 0x88c[4]
-						rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); 		// 0x880[6:5]
-						rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0);			// 0xc04[3:0]
-						rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0);			// 0xd04[3:0]
-						rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x7000, 0x0);	// 0x884[14:12]
-	//					for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
-		//					PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
-#endif
-					//RF-A, RF-B
-					//disable RF-Chip A/B
-					rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);	// 0x860[4]
-					//analog to digital off, for power save
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
-					//digital to analog off, for power save
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
-					//rx antenna off
-					rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
-					//rx antenna off
-					rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
-					//analog to digital part2 off, for power save
-					rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); // 0x880[6:5]
-
-				break;
-
-			default:
-				bResult = false;
-				RT_TRACE(COMP_ERR, "SetRFPowerState819xUsb(): unknow state to set: 0x%X!!!\n", eRFPowerState);
-				break;
-		}
-			break;
-		default:
-			RT_TRACE(COMP_ERR, "Not support rf_chip(%x)\n", priv->rf_chip);
-			break;
-	}
-#ifdef TO_DO_LIST
-	if(bResult)
-	{
-		// Update current RF state variable.
-		pHalData->eRFPowerState = eRFPowerState;
-		switch(pHalData->RFChipID )
-		{
-			case RF_8256:
-		switch(pHalData->eRFPowerState)
-				{
-				case eRfOff:
-					//
-					//If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
-					//
-					if(pMgntInfo->RfOffReason==RF_CHANGE_BY_IPS )
-					{
-						Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
-					}
-					else
-					{
-						// Turn off LED if RF is not ON.
-						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
-					}
-					break;
-
-				case eRfOn:
-					// Turn on RF we are still linked, which might happen when
-					// we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
-					if( pMgntInfo->bMediaConnect == TRUE )
-					{
-						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
-					}
-					else
-					{
-						// Turn off LED if RF is not ON.
-						Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
-					}
-					break;
-
-				default:
-					// do nothing.
-					break;
-				}// Switch RF state
-				break;
-
-				default:
-					RT_TRACE(COMP_RF, DBG_LOUD, ("SetRFPowerState8190(): Unknown RF type\n"));
-					break;
-			}
-
-	}
-#endif
-	priv->SetRFPowerStateInProgress = false;
-
-	return bResult;
-}
-
-/****************************************************************************************
- *function:  This function set command table variable(struct SwChnlCmd).
- *   input:  SwChnlCmd*		CmdTable 	//table to be set.
- *   	     u32		CmdTableIdx 	//variable index in table to be set
- *   	     u32		CmdTableSz	//table size.
- *   	     SwChnlCmdID	CmdID		//command ID to set.
- *	     u32		Para1
- *	     u32		Para2
- *	     u32		msDelay
- *  output:
- *  return:  true if finished, false otherwise
- *    Note:
- * ************************************************************************************/
-u8 rtl8192_phy_SetSwChnlCmdArray(
-	SwChnlCmd*		CmdTable,
-	u32			CmdTableIdx,
-	u32			CmdTableSz,
-	SwChnlCmdID		CmdID,
-	u32			Para1,
-	u32			Para2,
-	u32			msDelay
-	)
-{
-	SwChnlCmd* pCmd;
-
-	if(CmdTable == NULL)
-	{
-		RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n");
-		return false;
-	}
-	if(CmdTableIdx >= CmdTableSz)
-	{
-		RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n",
-				CmdTableIdx, CmdTableSz);
-		return false;
-	}
-
-	pCmd = CmdTable + CmdTableIdx;
-	pCmd->CmdID = CmdID;
-	pCmd->Para1 = Para1;
-	pCmd->Para2 = Para2;
-	pCmd->msDelay = msDelay;
-
-	return true;
-}
-/******************************************************************************
- *function:  This function set channel step by step
- *   input:  struct net_device *dev
- *   	     u8 		channel
- *   	     u8* 		stage //3 stages
- *   	     u8* 		step  //
- *   	     u32* 		delay //whether need to delay
- *  output:  store new stage, step and delay for next step(combine with function above)
- *  return:  true if finished, false otherwise
- *    Note:  Wait for simpler function to replace it //wb
- * ***************************************************************************/
-u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u8* step, u32* delay)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-//	PCHANNEL_ACCESS_SETTING	pChnlAccessSetting;
-	SwChnlCmd				PreCommonCmd[MAX_PRECMD_CNT];
-	u32					PreCommonCmdCnt;
-	SwChnlCmd				PostCommonCmd[MAX_POSTCMD_CNT];
-	u32					PostCommonCmdCnt;
-	SwChnlCmd				RfDependCmd[MAX_RFDEPENDCMD_CNT];
-	u32					RfDependCmdCnt;
-	SwChnlCmd				*CurrentCmd = NULL;
-	//RF90_RADIO_PATH_E		eRFPath;
-	u8		eRFPath;
-//	u32		RfRetVal;
-//	u8		RetryCnt;
-
-	RT_TRACE(COMP_CH, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel);
-//	RT_ASSERT(IsLegalChannel(Adapter, channel), ("illegal channel: %d\n", channel));
-#ifdef ENABLE_DOT11D
-	if (!IsLegalChannel(priv->ieee80211, channel))
-	{
-		RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel);
-		return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop.
-	}
-#endif
-//FIXME:need to check whether channel is legal or not here.WB
-
-
-	//for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
-//	for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++)
-//	{
-//		if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
-//			continue;
-		// <1> Fill up pre common command.
-		PreCommonCmdCnt = 0;
-		rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
-					CmdID_SetTxPowerLevel, 0, 0, 0);
-		rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT,
-					CmdID_End, 0, 0, 0);
-
-		// <2> Fill up post common command.
-		PostCommonCmdCnt = 0;
-
-		rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT,
-					CmdID_End, 0, 0, 0);
-
-		// <3> Fill up RF dependent command.
-		RfDependCmdCnt = 0;
-		switch( priv->rf_chip )
-		{
-		case RF_8225:
-			if (!(channel >= 1 && channel <= 14))
-			{
-				RT_TRACE(COMP_ERR, "illegal channel for Zebra 8225: %d\n", channel);
-				return true;
-			}
-			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
-				CmdID_RF_WriteReg, rZebra1_Channel, RF_CHANNEL_TABLE_ZEBRA[channel], 10);
-			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
-				CmdID_End, 0, 0, 0);
-			break;
-
-		case RF_8256:
-			// TEST!! This is not the table for 8256!!
-			if (!(channel >= 1 && channel <= 14))
-			{
-				RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel);
-				return true;
-			}
-			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
-				CmdID_RF_WriteReg, rZebra1_Channel, channel, 10);
-			rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT,
-			CmdID_End, 0, 0, 0);
-			break;
-
-		case RF_8258:
-			break;
-
-		default:
-			RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
-			return true;
-			break;
-		}
-
-
-		do{
-			switch(*stage)
-			{
-			case 0:
-				CurrentCmd=&PreCommonCmd[*step];
-				break;
-			case 1:
-				CurrentCmd=&RfDependCmd[*step];
-				break;
-			case 2:
-				CurrentCmd=&PostCommonCmd[*step];
-				break;
-			}
-
-			if(CurrentCmd->CmdID==CmdID_End)
-			{
-				if((*stage)==2)
-				{
-					(*delay)=CurrentCmd->msDelay;
-					return true;
-				}
-				else
-				{
-					(*stage)++;
-					(*step)=0;
-					continue;
-				}
-			}
-
-			switch(CurrentCmd->CmdID)
-			{
-			case CmdID_SetTxPowerLevel:
-				if(priv->card_8192_version == (u8)VERSION_819xU_A) //xiong: consider it later!
-					rtl8192_SetTxPowerLevel(dev,channel);
-				break;
-			case CmdID_WritePortUlong:
-				write_nic_dword(dev, CurrentCmd->Para1, CurrentCmd->Para2);
-				break;
-			case CmdID_WritePortUshort:
-				write_nic_word(dev, CurrentCmd->Para1, (u16)CurrentCmd->Para2);
-				break;
-			case CmdID_WritePortUchar:
-				write_nic_byte(dev, CurrentCmd->Para1, (u8)CurrentCmd->Para2);
-				break;
-			case CmdID_RF_WriteReg:
-				for(eRFPath = 0; eRFPath < RF90_PATH_MAX; eRFPath++)
-				{
-				rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bZebra1_ChannelNum, CurrentCmd->Para2);
-				}
-				break;
-			default:
-				break;
-			}
-
-			break;
-		}while(true);
-//	}/*for(Number of RF paths)*/
-
-	(*delay)=CurrentCmd->msDelay;
-	(*step)++;
-	return false;
-}
-
-/******************************************************************************
- *function:  This function does acturally set channel work
- *   input:  struct net_device *dev
- *   	     u8 		channel
- *  output:  none
- *  return:  noin
- *    Note:  We should not call this function directly
- * ***************************************************************************/
-void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u32	delay = 0;
-
-	while(!rtl8192_phy_SwChnlStepByStep(dev,channel,&priv->SwChnlStage,&priv->SwChnlStep,&delay))
-	{
-	//	if(delay>0)
-	//		msleep(delay);//or mdelay? need further consideration
-		if(!priv->up)
-			break;
-	}
-}
-/******************************************************************************
- *function:  Callback routine of the work item for switch channel.
- *   input:
- *
- *  output:  none
- *  return:  noin
- * ***************************************************************************/
-void rtl8192_SwChnl_WorkItem(struct net_device *dev)
-{
-
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	RT_TRACE(COMP_CH, "==> SwChnlCallback819xUsbWorkItem(), chan:%d\n", priv->chan);
-
-
-	rtl8192_phy_FinishSwChnlNow(dev , priv->chan);
-
-	RT_TRACE(COMP_CH, "<== SwChnlCallback819xUsbWorkItem()\n");
-}
-
-/******************************************************************************
- *function:  This function scheduled actural workitem to set channel
- *   input:  net_device dev
- *   	     u8		channel //channel to set
- *  output:  none
- *  return:  return code show if workitem is scheduled(1:pass, 0:fail)
- *    Note:  Delay may be required for RF configuration
- * ***************************************************************************/
-u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	RT_TRACE(COMP_CH, "=====>%s(), SwChnlInProgress:%d\n", __FUNCTION__, priv->SwChnlInProgress);
-	if(!priv->up)
-		return false;
-	if(priv->SwChnlInProgress)
-		return false;
-
-//	if(pHalData->SetBWModeInProgress)
-//		return;
-if (0) //to test current channel from RF reg 0x7.
-{
-	u8		eRFPath;
-	for(eRFPath = 0; eRFPath < 2; eRFPath++){
-	printk("====>set channel:%x\n",rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x7, bZebra1_ChannelNum));
-	udelay(10);
-	}
-}
-	//--------------------------------------------
-	switch(priv->ieee80211->mode)
-	{
-	case WIRELESS_MODE_A:
-	case WIRELESS_MODE_N_5G:
-		if (channel<=14){
-			RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14");
-			return false;
-		}
-		break;
-	case WIRELESS_MODE_B:
-		if (channel>14){
-			RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14");
-			return false;
-		}
-		break;
-	case WIRELESS_MODE_G:
-	case WIRELESS_MODE_N_24G:
-		if (channel>14){
-			RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14");
-			return false;
-		}
-		break;
-	}
-	//--------------------------------------------
-
-	priv->SwChnlInProgress = true;
-	if(channel == 0)
-		channel = 1;
-
-	priv->chan=channel;
-
-	priv->SwChnlStage=0;
-	priv->SwChnlStep=0;
-//	schedule_work(&(priv->SwChnlWorkItem));
-//	rtl8192_SwChnl_WorkItem(dev);
-	if(priv->up) {
-//		queue_work(priv->priv_wq,&(priv->SwChnlWorkItem));
-	rtl8192_SwChnl_WorkItem(dev);
-	}
-
-	priv->SwChnlInProgress = false;
-	return true;
-}
-
-
-//
-/******************************************************************************
- *function:  Callback routine of the work item for set bandwidth mode.
- *   input:  struct net_device *dev
- *   	     HT_CHANNEL_WIDTH	Bandwidth  //20M or 40M
- *   	     HT_EXTCHNL_OFFSET Offset 	   //Upper, Lower, or Don't care
- *  output:  none
- *  return:  none
- *    Note:  I doubt whether SetBWModeInProgress flag is necessary as we can
- *    	     test whether current work in the queue or not.//do I?
- * ***************************************************************************/
-void rtl8192_SetBWModeWorkItem(struct net_device *dev)
-{
-
-	struct r8192_priv *priv = ieee80211_priv(dev);
-	u8 regBwOpMode;
-
-	RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem()  Switch to %s bandwidth\n", \
-					priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz")
-
-
-	if(priv->rf_chip == RF_PSEUDO_11N)
-	{
-		priv->SetBWModeInProgress= false;
-		return;
-	}
-
-	//<1>Set MAC register
-	regBwOpMode = read_nic_byte(dev, BW_OPMODE);
-
-	switch(priv->CurrentChannelBW)
-	{
-		case HT_CHANNEL_WIDTH_20:
-			regBwOpMode |= BW_OPMODE_20MHZ;
-		       // 2007/02/07 Mark by Emily becasue we have not verify whether this register works
-			write_nic_byte(dev, BW_OPMODE, regBwOpMode);
-			break;
-
-		case HT_CHANNEL_WIDTH_20_40:
-			regBwOpMode &= ~BW_OPMODE_20MHZ;
-        		// 2007/02/07 Mark by Emily becasue we have not verify whether this register works
-			write_nic_byte(dev, BW_OPMODE, regBwOpMode);
-			break;
-
-		default:
-			RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",priv->CurrentChannelBW);
-			break;
-	}
-
-	//<2>Set PHY related register
-	switch(priv->CurrentChannelBW)
-	{
-		case HT_CHANNEL_WIDTH_20:
-			// Add by Vivi 20071119
-			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0);
-			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0);
-			rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1);
-
-			// Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207
-#if 0
-			write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000);
-			write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317);
-			write_nic_dword(dev, rCCK0_DebugPort, 0x00000204);
-#endif
-			priv->cck_present_attentuation =
-				priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
-
-			if(priv->cck_present_attentuation > 22)
-				priv->cck_present_attentuation= 22;
-			if(priv->cck_present_attentuation< 0)
-				priv->cck_present_attentuation = 0;
-			RT_TRACE(COMP_INIT, "20M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
-
-			if(priv->chan == 14 && !priv->bcck_in_ch14)
-			{
-				priv->bcck_in_ch14 = TRUE;
-				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-			}
-			else if(priv->chan != 14 && priv->bcck_in_ch14)
-			{
-				priv->bcck_in_ch14 = FALSE;
-				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-			}
-			else
-				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-
-			break;
-		case HT_CHANNEL_WIDTH_20_40:
-			// Add by Vivi 20071119
-			rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1);
-			rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1);
-			rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1));
-                   	rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0);
-			rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC);
-#if 0
-			// Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207
-			write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000);
-			write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e);
-			write_nic_dword(dev, rCCK0_DebugPort, 0x00000409);
-#endif
-			priv->cck_present_attentuation =
-				priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
-
-			if(priv->cck_present_attentuation > 22)
-				priv->cck_present_attentuation = 22;
-			if(priv->cck_present_attentuation < 0)
-				priv->cck_present_attentuation = 0;
-
-			RT_TRACE(COMP_INIT, "40M, pHalData->CCKPresentAttentuation = %d\n", priv->cck_present_attentuation);
-			if(priv->chan == 14 && !priv->bcck_in_ch14)
-			{
-				priv->bcck_in_ch14 = true;
-				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-			}
-			else if(priv->chan!= 14 && priv->bcck_in_ch14)
-			{
-				priv->bcck_in_ch14 = false;
-				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-			}
-			else
-				dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
-
-			break;
-		default:
-			RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW);
-			break;
-
-	}
-	//Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315
-
-#if 1
-	//<3>Set RF related register
-	switch( priv->rf_chip )
-	{
-		case RF_8225:
-#ifdef TO_DO_LIST
-			PHY_SetRF8225Bandwidth(Adapter, pHalData->CurrentChannelBW);
-#endif
-			break;
-
-		case RF_8256:
-			PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW);
-			break;
-
-		case RF_8258:
-			// PHY_SetRF8258Bandwidth();
-			break;
-
-		case RF_PSEUDO_11N:
-			// Do Nothing
-			break;
-
-		default:
-			RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip);
-			break;
-	}
-#endif
-	priv->SetBWModeInProgress= false;
-
-	RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb(), %d", atomic_read(&(priv->ieee80211->atm_swbw)) );
-}
-
-/******************************************************************************
- *function:  This function schedules bandwith switch work.
- *   input:  struct net_device *dev
- *   	     HT_CHANNEL_WIDTH	Bandwidth  //20M or 40M
- *   	     HT_EXTCHNL_OFFSET Offset 	   //Upper, Lower, or Don't care
- *  output:  none
- *  return:  none
- *    Note:  I doubt whether SetBWModeInProgress flag is necessary as we can
- *    	     test whether current work in the queue or not.//do I?
- * ***************************************************************************/
-void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET Offset)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	if(priv->SetBWModeInProgress)
-		return;
-	priv->SetBWModeInProgress= true;
-
-	priv->CurrentChannelBW = Bandwidth;
-
-	if(Offset==HT_EXTCHNL_OFFSET_LOWER)
-		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER;
-	else if(Offset==HT_EXTCHNL_OFFSET_UPPER)
-		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER;
-	else
-		priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
-	//queue_work(priv->priv_wq, &(priv->SetBWModeWorkItem));
-	//	schedule_work(&(priv->SetBWModeWorkItem));
-	rtl8192_SetBWModeWorkItem(dev);
-
-}
-
-void InitialGain819xUsb(struct net_device *dev,	u8 Operation)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-
-	priv->InitialGainOperateType = Operation;
-
-	if(priv->up)
-	{
-	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
-		queue_delayed_work(priv->priv_wq,&priv->initialgain_operate_wq,0);
-	#else
-		#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-		schedule_task(&priv->initialgain_operate_wq);
-		#else
-		queue_work(priv->priv_wq,&priv->initialgain_operate_wq);
-		#endif
-	#endif
-	}
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-extern void InitialGainOperateWorkItemCallBack(struct work_struct *work)
-{
-	struct delayed_work *dwork = container_of(work,struct delayed_work,work);
-       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,initialgain_operate_wq);
-       struct net_device *dev = priv->ieee80211->dev;
-#else
-extern void InitialGainOperateWorkItemCallBack(struct net_device *dev)
-{
-	struct r8192_priv *priv = ieee80211_priv(dev);
-#endif
-#define SCAN_RX_INITIAL_GAIN	0x17
-#define POWER_DETECTION_TH	0x08
-	u32	BitMask;
-	u8	initial_gain;
-	u8	Operation;
-
-	Operation = priv->InitialGainOperateType;
-
-	switch(Operation)
-	{
-		case IG_Backup:
-			RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n");
-			initial_gain = SCAN_RX_INITIAL_GAIN;//priv->DefaultInitialGain[0];//
-			BitMask = bMaskByte0;
-			if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
-				rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
-			priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, BitMask);
-			priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, BitMask);
-			priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, BitMask);
-			priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, BitMask);
-			BitMask  = bMaskByte2;
-			priv->initgain_backup.cca		= (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, BitMask);
-
-			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
-			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
-			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
-			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
-			RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
-
-			RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain);
-			write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
-			write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
-			write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
-			write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
-			RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH);
-			write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH);
-			break;
-		case IG_Restore:
-			RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n");
-			BitMask = 0x7f; //Bit0~ Bit6
-			if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
-				rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);	// FW DIG OFF
-
-			rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1);
-			rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1);
-			rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1);
-			rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1);
-			BitMask  = bMaskByte2;
-			rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca);
-
-			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
-			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
-			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
-			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
-			RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
-
-#ifdef RTL8190P
-			SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
-#endif
-#ifdef RTL8192E
-			SetTxPowerLevel8190(Adapter,priv->CurrentChannel);
-#endif
-//#ifdef RTL8192U
-			rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
-//#endif
-
-			if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
-				rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);	// FW DIG ON
-			break;
-		default:
-			RT_TRACE(COMP_SCAN, "Unknown IG Operation. \n");
-			break;
-	}
-}
-
diff --git a/drivers/staging/rtl8192su/r819xU_phy.h b/drivers/staging/rtl8192su/r819xU_phy.h
deleted file mode 100644
index c165ac1..0000000
--- a/drivers/staging/rtl8192su/r819xU_phy.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef _R819XU_PHY_H
-#define _R819XU_PHY_H
-
-/* Channel switch:The size of command tables for switch channel*/
-#define MAX_PRECMD_CNT 16
-#define MAX_RFDEPENDCMD_CNT 16
-#define MAX_POSTCMD_CNT 16
-
-typedef enum _SwChnlCmdID{
-	CmdID_End,
-	CmdID_SetTxPowerLevel,
-	CmdID_BBRegWrite10,
-	CmdID_WritePortUlong,
-	CmdID_WritePortUshort,
-	CmdID_WritePortUchar,
-	CmdID_RF_WriteReg,
-}SwChnlCmdID;
-
-/*--------------------------------Define structure--------------------------------*/
-/* 1. Switch channel related */
-typedef struct _SwChnlCmd{
-	SwChnlCmdID	CmdID;
-	u32			Para1;
-	u32			Para2;
-	u32			msDelay;
-}__attribute__ ((packed)) SwChnlCmd;
-
-extern u32 rtl819XMACPHY_Array_PG[];
-extern u32 rtl819XPHY_REG_1T2RArray[];
-extern u32 rtl819XAGCTAB_Array[];
-extern u32 rtl819XRadioA_Array[];
-extern u32 rtl819XRadioB_Array[];
-extern u32 rtl819XRadioC_Array[];
-extern u32 rtl819XRadioD_Array[];
-
-typedef enum _HW90_BLOCK{
-	HW90_BLOCK_MAC = 0,
-	HW90_BLOCK_PHY0 = 1,
-	HW90_BLOCK_PHY1 = 2,
-	HW90_BLOCK_RF = 3,
-	HW90_BLOCK_MAXIMUM = 4, // Never use this
-}HW90_BLOCK_E, *PHW90_BLOCK_E;
-
-typedef enum _RF90_RADIO_PATH{
-	RF90_PATH_A = 0,			//Radio Path A
-	RF90_PATH_B = 1,			//Radio Path B
-	RF90_PATH_C = 2,			//Radio Path C
-	RF90_PATH_D = 3,			//Radio Path D
-	RF90_PATH_MAX				//Max RF number 92 support
-}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E;
-
-#define bMaskByte0                0xff
-#define bMaskByte1                0xff00
-#define bMaskByte2                0xff0000
-#define bMaskByte3                0xff000000
-#define bMaskHWord                0xffff0000
-#define bMaskLWord                0x0000ffff
-#define bMaskDWord                0xffffffff
-
-//extern u32 rtl8192_CalculateBitShift(u32 dwBitMask);
-extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device* dev, u32 eRFPath);
-extern void rtl8192_setBBreg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask, u32 dwData);
-extern u32 rtl8192_QueryBBReg(struct net_device* dev, u32 dwRegAddr, u32 dwBitMask);
-//extern u32 rtl8192_phy_RFSerialRead(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset);
-//extern void rtl8192_phy_RFSerialWrite(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data);
-extern void rtl8192_phy_SetRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask, u32 Data);
-extern u32 rtl8192_phy_QueryRFReg(struct net_device* dev, RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask);
-extern void rtl8192_phy_configmac(struct net_device* dev);
-extern void rtl8192_phyConfigBB(struct net_device* dev, u8 ConfigType);
-//extern void rtl8192_InitBBRFRegDef(struct net_device* dev);
-extern u8 rtl8192_phy_checkBBAndRF(struct net_device* dev, HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath);
-//extern void rtl8192_BB_Config_ParaFile(struct net_device* dev);
-extern void rtl8192_BBConfig(struct net_device* dev);
-extern void rtl8192_phy_getTxPower(struct net_device* dev);
-extern void rtl8192_phy_setTxPower(struct net_device* dev, u8 channel);
-extern void rtl8192_phy_RFConfig(struct net_device* dev);
-extern void rtl8192_phy_updateInitGain(struct net_device* dev);
-extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E	eRFPath);
-
-extern u8 rtl8192_phy_SwChnl(struct net_device* dev, u8 channel);
-extern void rtl8192_SetBWMode(struct net_device *dev, HT_CHANNEL_WIDTH	Bandwidth, HT_EXTCHNL_OFFSET Offset);
-extern void rtl8192_SwChnl_WorkItem(struct net_device *dev);
-void rtl8192_SetBWModeWorkItem(struct net_device *dev);
-extern bool rtl8192_SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState);
-//added by amy
-extern void InitialGain819xUsb(struct net_device *dev,	u8 Operation);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-extern void InitialGainOperateWorkItemCallBack(struct work_struct *work);
-#else
-extern void InitialGainOperateWorkItemCallBack(struct net_device *dev);
-#endif
-
-#endif
diff --git a/drivers/staging/rtl8192su/r819xU_phyreg.h b/drivers/staging/rtl8192su/r819xU_phyreg.h
deleted file mode 100644
index b62f1a6..0000000
--- a/drivers/staging/rtl8192su/r819xU_phyreg.h
+++ /dev/null
@@ -1,871 +0,0 @@
-#ifndef _R819XU_PHYREG_H
-#define _R819XU_PHYREG_H
-
-
-#define   RF_DATA				0x1d4					// FW will write RF data in the register.
-
-//Register   //duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF
-//page 1
-#define rPMAC_Reset               		0x100
-#define rPMAC_TxStart             		0x104
-#define rPMAC_TxLegacySIG         		0x108
-#define rPMAC_TxHTSIG1            		0x10c
-#define rPMAC_TxHTSIG2            		0x110
-#define rPMAC_PHYDebug            		0x114
-#define rPMAC_TxPacketNum         		0x118
-#define rPMAC_TxIdle              		0x11c
-#define rPMAC_TxMACHeader0       	0x120
-#define rPMAC_TxMACHeader1       	0x124
-#define rPMAC_TxMACHeader2       	0x128
-#define rPMAC_TxMACHeader3       	0x12c
-#define rPMAC_TxMACHeader4       	0x130
-#define rPMAC_TxMACHeader5       	0x134
-#define rPMAC_TxDataType          		0x138
-#define rPMAC_TxRandomSeed      		0x13c
-#define rPMAC_CCKPLCPPreamble  		0x140
-#define rPMAC_CCKPLCPHeader     		0x144
-#define rPMAC_CCKCRC16            		0x148
-#define rPMAC_OFDMRxCRC32OK  		0x170
-#define rPMAC_OFDMRxCRC32Er   		0x174
-#define rPMAC_OFDMRxParityEr    		0x178
-#define rPMAC_OFDMRxCRC8Er     		0x17c
-#define rPMAC_CCKCRxRC16Er       		0x180
-#define rPMAC_CCKCRxRC32Er       		0x184
-#define rPMAC_CCKCRxRC32OK      		0x188
-#define rPMAC_TxStatus            		0x18c
-
-//page8
-#define rFPGA0_RFMOD              		0x800  //RF mode & CCK TxSC
-#define rFPGA0_TxInfo             		0x804
-#define rFPGA0_PSDFunction        		0x808
-#define rFPGA0_TxGainStage        		0x80c
-#define rFPGA0_RFTiming1          		0x810
-#define rFPGA0_RFTiming2          		0x814
-//#define rFPGA0_XC_RFTiming        		0x818
-//#define rFPGA0_XD_RFTiming        		0x81c
-#define rFPGA0_XA_HSSIParameter1  	0x820
-#define rFPGA0_XA_HSSIParameter2  	0x824
-#define rFPGA0_XB_HSSIParameter1  	0x828
-#define rFPGA0_XB_HSSIParameter2  	0x82c
-#define rFPGA0_XC_HSSIParameter1  	0x830
-#define rFPGA0_XC_HSSIParameter2  	0x834
-#define rFPGA0_XD_HSSIParameter1  	0x838
-#define rFPGA0_XD_HSSIParameter2  	0x83c
-#define rFPGA0_XA_LSSIParameter   	0x840
-#define rFPGA0_XB_LSSIParameter   	0x844
-#define rFPGA0_XC_LSSIParameter   	0x848
-#define rFPGA0_XD_LSSIParameter   	0x84c
-#define rFPGA0_RFWakeUpParameter  	0x850
-#define rFPGA0_RFSleepUpParameter 	0x854
-#define rFPGA0_XAB_SwitchControl  	0x858
-#define rFPGA0_XCD_SwitchControl  	0x85c
-#define rFPGA0_XA_RFInterfaceOE   	0x860
-#define rFPGA0_XB_RFInterfaceOE   	0x864
-#define rFPGA0_XC_RFInterfaceOE   	0x868
-#define rFPGA0_XD_RFInterfaceOE   	0x86c
-#define rFPGA0_XAB_RFInterfaceSW  	0x870
-#define rFPGA0_XCD_RFInterfaceSW  	0x874
-#define rFPGA0_XAB_RFParameter    	0x878
-#define rFPGA0_XCD_RFParameter    	0x87c
-#define rFPGA0_AnalogParameter1   	0x880
-#define rFPGA0_AnalogParameter2   	0x884
-#define rFPGA0_AnalogParameter3   	0x888
-#define rFPGA0_AnalogParameter4   	0x88c
-#define rFPGA0_XA_LSSIReadBack    	0x8a0
-#define rFPGA0_XB_LSSIReadBack    	0x8a4
-#define rFPGA0_XC_LSSIReadBack    	0x8a8
-#define rFPGA0_XD_LSSIReadBack    	0x8ac
-#define rFPGA0_PSDReport          		0x8b4
-#define rFPGA0_XAB_RFInterfaceRB  	0x8e0
-#define rFPGA0_XCD_RFInterfaceRB  	0x8e4
-
-//page 9
-#define rFPGA1_RFMOD              		0x900  //RF mode & OFDM TxSC
-#define rFPGA1_TxBlock            		0x904
-#define rFPGA1_DebugSelect        		0x908
-#define rFPGA1_TxInfo             		0x90c
-
-//page a
-#define rCCK0_System              		0xa00
-#define rCCK0_AFESetting          		0xa04
-#define rCCK0_CCA                 			0xa08
-#define rCCK0_RxAGC1              		0xa0c  //AGC default value, saturation level
-#define rCCK0_RxAGC2              		0xa10  //AGC & DAGC
-#define rCCK0_RxHP                		0xa14
-#define rCCK0_DSPParameter1       	0xa18  //Timing recovery & Channel estimation threshold
-#define rCCK0_DSPParameter2       	0xa1c  //SQ threshold
-#define rCCK0_TxFilter1           		0xa20
-#define rCCK0_TxFilter2           		0xa24
-#define rCCK0_DebugPort           		0xa28  //debug port and Tx filter3
-#define rCCK0_FalseAlarmReport    	0xa2c  //0xa2d
-#define rCCK0_TRSSIReport         		0xa50
-#define rCCK0_RxReport            		0xa54  //0xa57
-#define rCCK0_FACounterLower      	0xa5c  //0xa5b
-#define rCCK0_FACounterUpper      	0xa58  //0xa5c
-
-//page c
-#define rOFDM0_LSTF               		0xc00
-#define rOFDM0_TRxPathEnable      	0xc04
-#define rOFDM0_TRMuxPar           		0xc08
-#define rOFDM0_TRSWIsolation      		0xc0c
-#define rOFDM0_XARxAFE            		0xc10  //RxIQ DC offset, Rx digital filter, DC notch filter
-#define rOFDM0_XARxIQImbalance    	0xc14  //RxIQ imblance matrix
-#define rOFDM0_XBRxAFE            		0xc18
-#define rOFDM0_XBRxIQImbalance    	0xc1c
-#define rOFDM0_XCRxAFE            		0xc20
-#define rOFDM0_XCRxIQImbalance    	0xc24
-#define rOFDM0_XDRxAFE            		0xc28
-#define rOFDM0_XDRxIQImbalance    	0xc2c
-#define rOFDM0_RxDetector1        		0xc30  //PD,BW & SBD
-#define rOFDM0_RxDetector2        		0xc34  //SBD & Fame Sync.
-#define rOFDM0_RxDetector3        		0xc38  //Frame Sync.
-#define rOFDM0_RxDetector4        		0xc3c  //PD, SBD, Frame Sync & Short-GI
-#define rOFDM0_RxDSP              		0xc40  //Rx Sync Path
-#define rOFDM0_CFOandDAGC         	0xc44  //CFO & DAGC
-#define rOFDM0_CCADropThreshold   	0xc48 //CCA Drop threshold
-#define rOFDM0_ECCAThreshold      	0xc4c // energy CCA
-#define rOFDM0_XAAGCCore1         	0xc50
-#define rOFDM0_XAAGCCore2         	0xc54
-#define rOFDM0_XBAGCCore1         	0xc58
-#define rOFDM0_XBAGCCore2         	0xc5c
-#define rOFDM0_XCAGCCore1         	0xc60
-#define rOFDM0_XCAGCCore2         	0xc64
-#define rOFDM0_XDAGCCore1         	0xc68
-#define rOFDM0_XDAGCCore2         	0xc6c
-#define rOFDM0_AGCParameter1      	0xc70
-#define rOFDM0_AGCParameter2      	0xc74
-#define rOFDM0_AGCRSSITable       	0xc78
-#define rOFDM0_HTSTFAGC           		0xc7c
-#define rOFDM0_XATxIQImbalance   	0xc80
-#define rOFDM0_XATxAFE            		0xc84
-#define rOFDM0_XBTxIQImbalance    	0xc88
-#define rOFDM0_XBTxAFE            		0xc8c
-#define rOFDM0_XCTxIQImbalance    	0xc90
-#define rOFDM0_XCTxAFE            		0xc94
-#define rOFDM0_XDTxIQImbalance    	0xc98
-#define rOFDM0_XDTxAFE            		0xc9c
-#define rOFDM0_RxHPParameter      	0xce0
-#define rOFDM0_TxPseudoNoiseWgt   	0xce4
-#define rOFDM0_FrameSync          		0xcf0
-#define rOFDM0_DFSReport          		0xcf4
-#define rOFDM0_TxCoeff1           		0xca4
-#define rOFDM0_TxCoeff2           		0xca8
-#define rOFDM0_TxCoeff3           		0xcac
-#define rOFDM0_TxCoeff4           		0xcb0
-#define rOFDM0_TxCoeff5           		0xcb4
-#define rOFDM0_TxCoeff6           		0xcb8
-
-
-//page d
-#define rOFDM1_LSTF               		0xd00
-#define rOFDM1_TRxPathEnable      	0xd04
-#define rOFDM1_CFO                		0xd08
-#define rOFDM1_CSI1               		0xd10
-#define rOFDM1_SBD                		0xd14
-#define rOFDM1_CSI2               		0xd18
-#define rOFDM1_CFOTracking        		0xd2c
-#define rOFDM1_TRxMesaure1        	0xd34
-#define rOFDM1_IntfDet            		0xd3c
-#define rOFDM1_PseudoNoiseStateAB 0xd50
-#define rOFDM1_PseudoNoiseStateCD 0xd54
-#define rOFDM1_RxPseudoNoiseWgt   0xd58
-#define rOFDM_PHYCounter1         		0xda0  //cca, parity fail
-#define rOFDM_PHYCounter2         		0xda4  //rate illegal, crc8 fail
-#define rOFDM_PHYCounter3         		0xda8  //MCS not support
-#define rOFDM_ShortCFOAB          		0xdac
-#define rOFDM_ShortCFOCD          		0xdb0
-#define rOFDM_LongCFOAB           		0xdb4
-#define rOFDM_LongCFOCD           		0xdb8
-#define rOFDM_TailCFOAB           		0xdbc
-#define rOFDM_TailCFOCD           		0xdc0
-#define rOFDM_PWMeasure1          	0xdc4
-#define rOFDM_PWMeasure2          	0xdc8
-#define rOFDM_BWReport            		0xdcc
-#define rOFDM_AGCReport           		0xdd0
-#define rOFDM_RxSNR               		0xdd4
-#define rOFDM_RxEVMCSI            		0xdd8
-#define rOFDM_SIGReport           		0xddc
-
-//page e
-#define rTxAGC_Rate18_06			0xe00
-#define rTxAGC_Rate54_24			0xe04
-#define rTxAGC_CCK_Mcs32			0xe08
-#define rTxAGC_Mcs03_Mcs00			0xe10
-#define rTxAGC_Mcs07_Mcs04			0xe14
-#define rTxAGC_Mcs11_Mcs08			0xe18
-#define rTxAGC_Mcs15_Mcs12			0xe1c
-
-
-//RF
-//Zebra1
-#define rZebra1_HSSIEnable            	0x0
-#define rZebra1_TRxEnable1            	0x1
-#define rZebra1_TRxEnable2           	0x2
-#define rZebra1_AGC                   		0x4
-#define rZebra1_ChargePump            	0x5
-#define rZebra1_Channel               		0x7
-#define rZebra1_TxGain               	 	0x8
-#define rZebra1_TxLPF                 		0x9
-#define rZebra1_RxLPF                 		0xb
-#define rZebra1_RxHPFCorner           	0xc
-
-//Zebra4
-#define rGlobalCtrl                   		0
-#define rRTL8256_TxLPF                		19
-#define rRTL8256_RxLPF                		11
-
-//RTL8258
-#define rRTL8258_TxLPF                		0x11
-#define rRTL8258_RxLPF                		0x13
-#define rRTL8258_RSSILPF              	0xa
-
-//Bit Mask
-//page-1
-#define bBBResetB                 			0x100
-#define bGlobalResetB             		0x200
-#define bOFDMTxStart              		0x4
-#define bCCKTxStart               			0x8
-#define bCRC32Debug               		0x100
-#define bPMACLoopback             		0x10
-#define bTxLSIG                   			0xffffff
-#define bOFDMTxRate               		0xf
-#define bOFDMTxReserved           		0x10
-#define bOFDMTxLength             		0x1ffe0
-#define bOFDMTxParity             		0x20000
-#define bTxHTSIG1                 			0xffffff
-#define bTxHTMCSRate              		0x7f
-#define bTxHTBW                   			0x80
-#define bTxHTLength               		0xffff00
-#define bTxHTSIG2                 			0xffffff
-#define bTxHTSmoothing            		0x1
-#define bTxHTSounding             		0x2
-#define bTxHTReserved             		0x4
-#define bTxHTAggreation           		0x8
-#define bTxHTSTBC                 			0x30
-#define bTxHTAdvanceCoding        		0x40
-#define bTxHTShortGI              		0x80
-#define bTxHTNumberHT_LTF         		0x300
-#define bTxHTCRC8                 			0x3fc00
-#define bCounterReset             		0x10000
-#define bNumOfOFDMTx              		0xffff
-#define bNumOfCCKTx               		0xffff0000
-#define bTxIdleInterval           			0xffff
-#define bOFDMService              		0xffff0000
-#define bTxMACHeader              		0xffffffff
-#define bTxDataInit               			0xff
-#define bTxHTMode                 		0x100
-#define bTxDataType               		0x30000
-#define bTxRandomSeed             		0xffffffff
-#define bCCKTxPreamble           		0x1
-#define bCCKTxSFD                 			0xffff0000
-#define bCCKTxSIG                 			0xff
-#define bCCKTxService             		0xff00
-#define bCCKLengthExt             		0x8000
-#define bCCKTxLength              		0xffff0000
-#define bCCKTxCRC16               		0xffff
-#define bCCKTxStatus              		0x1
-#define bOFDMTxStatus             		0x2
-
-//page-8
-#define bRFMOD                    			0x1
-#define bJapanMode                		0x2
-#define bCCKTxSC                  			0x30
-#define bCCKEn                    			0x1000000
-#define bOFDMEn                   			0x2000000
-#define bOFDMRxADCPhase           		0x10000
-#define bOFDMTxDACPhase           		0x40000
-#define bXATxAGC                  			0x3f
-#define bXBTxAGC                  			0xf00
-#define bXCTxAGC                  			0xf000
-#define bXDTxAGC                  			0xf0000
-#define bPAStart                  			0xf0000000
-#define bTRStart                  			0x00f00000
-#define bRFStart                  			0x0000f000
-#define bBBStart                  			0x000000f0
-#define bBBCCKStart               		0x0000000f
-#define bPAEnd                    			0xf          //Reg0x814
-#define bTREnd                    			0x0f000000
-#define bRFEnd                    			0x000f0000
-#define bCCAMask                  			0x000000f0   //T2R
-#define bR2RCCAMask               		0x00000f00
-#define bHSSI_R2TDelay            		0xf8000000
-#define bHSSI_T2RDelay            		0xf80000
-#define bContTxHSSI               		0x400     //chane gain at continue Tx
-#define bIGFromCCK                		0x200
-#define bAGCAddress               		0x3f
-#define bRxHPTx                   			0x7000
-#define bRxHPT2R                  			0x38000
-#define bRxHPCCKIni               		0xc0000
-#define bAGCTxCode                		0xc00000
-#define bAGCRxCode                		0x300000
-#define b3WireDataLength          		0x800
-#define b3WireAddressLength       		0x400
-#define b3WireRFPowerDown         		0x1
-//#define bHWSISelect               		0x8
-#define b5GPAPEPolarity           		0x40000000
-#define b2GPAPEPolarity           		0x80000000
-#define bRFSW_TxDefaultAnt        		0x3
-#define bRFSW_TxOptionAnt         		0x30
-#define bRFSW_RxDefaultAnt        		0x300
-#define bRFSW_RxOptionAnt         		0x3000
-#define bRFSI_3WireData           		0x1
-#define bRFSI_3WireClock          		0x2
-#define bRFSI_3WireLoad           		0x4
-#define bRFSI_3WireRW             		0x8
-#define bRFSI_3Wire               			0xf  //3-wire total control
-#define bRFSI_RFENV               		0x10
-#define bRFSI_TRSW                		0x20
-#define bRFSI_TRSWB               		0x40
-#define bRFSI_ANTSW               		0x100
-#define bRFSI_ANTSWB              		0x200
-#define bRFSI_PAPE                			0x400
-#define bRFSI_PAPE5G              		0x800
-#define bBandSelect               			0x1
-#define bHTSIG2_GI                			0x80
-#define bHTSIG2_Smoothing         		0x01
-#define bHTSIG2_Sounding          		0x02
-#define bHTSIG2_Aggreaton         		0x08
-#define bHTSIG2_STBC              		0x30
-#define bHTSIG2_AdvCoding         		0x40
-#define bHTSIG2_NumOfHTLTF        	0x300
-#define bHTSIG2_CRC8              		0x3fc
-#define bHTSIG1_MCS               		0x7f
-#define bHTSIG1_BandWidth         		0x80
-#define bHTSIG1_HTLength          		0xffff
-#define bLSIG_Rate                			0xf
-#define bLSIG_Reserved            		0x10
-#define bLSIG_Length              		0x1fffe
-#define bLSIG_Parity              			0x20
-#define bCCKRxPhase               		0x4
-#define bLSSIReadAddress          		0x3f000000   //LSSI "Read" Address
-#define bLSSIReadEdge             		0x80000000   //LSSI "Read" edge signal
-#define bLSSIReadBackData         		0xfff
-#define bLSSIReadOKFlag           		0x1000
-#define bCCKSampleRate            		0x8       //0: 44MHz, 1:88MHz
-
-#define bRegulator0Standby        		0x1
-#define bRegulatorPLLStandby      		0x2
-#define bRegulator1Standby        		0x4
-#define bPLLPowerUp               		0x8
-#define bDPLLPowerUp              		0x10
-#define bDA10PowerUp              		0x20
-#define bAD7PowerUp               		0x200
-#define bDA6PowerUp               		0x2000
-#define bXtalPowerUp              		0x4000
-#define b40MDClkPowerUP           		0x8000
-#define bDA6DebugMode             		0x20000
-#define bDA6Swing                 			0x380000
-#define bADClkPhase               		0x4000000
-#define b80MClkDelay              		0x18000000
-#define bAFEWatchDogEnable        		0x20000000
-#define bXtalCap                			0x0f000000
-#define bIntDifClkEnable          		0x400
-#define bExtSigClkEnable         	 	0x800
-#define bBandgapMbiasPowerUp      	0x10000
-#define bAD11SHGain               		0xc0000
-#define bAD11InputRange           		0x700000
-#define bAD11OPCurrent            		0x3800000
-#define bIPathLoopback            		0x4000000
-#define bQPathLoopback            		0x8000000
-#define bAFELoopback              		0x10000000
-#define bDA10Swing                		0x7e0
-#define bDA10Reverse              		0x800
-#define bDAClkSource              		0x1000
-#define bAD7InputRange            		0x6000
-#define bAD7Gain                  			0x38000
-#define bAD7OutputCMMode          		0x40000
-#define bAD7InputCMMode           		0x380000
-#define bAD7Current               			0xc00000
-#define bRegulatorAdjust          		0x7000000
-#define bAD11PowerUpAtTx          		0x1
-#define bDA10PSAtTx               		0x10
-#define bAD11PowerUpAtRx          		0x100
-#define bDA10PSAtRx               		0x1000
-
-#define bCCKRxAGCFormat           		0x200
-
-#define bPSDFFTSamplepPoint       		0xc000
-#define bPSDAverageNum            		0x3000
-#define bIQPathControl            		0xc00
-#define bPSDFreq                  			0x3ff
-#define bPSDAntennaPath           		0x30
-#define bPSDIQSwitch              		0x40
-#define bPSDRxTrigger             		0x400000
-#define bPSDTxTrigger             		0x80000000
-#define bPSDSineToneScale        		0x7f000000
-#define bPSDReport                			0xffff
-
-//page-9
-#define bOFDMTxSC                 		0x30000000
-#define bCCKTxOn                  			0x1
-#define bOFDMTxOn                 		0x2
-#define bDebugPage                		0xfff  //reset debug page and also HWord, LWord
-#define bDebugItem                		0xff   //reset debug page and LWord
-#define bAntL              	       		0x10
-#define bAntNonHT           	      			0x100
-#define bAntHT1               			0x1000
-#define bAntHT2                   			0x10000
-#define bAntHT1S1                 			0x100000
-#define bAntNonHTS1               		0x1000000
-
-//page-a
-#define bCCKBBMode                		0x3
-#define bCCKTxPowerSaving         		0x80
-#define bCCKRxPowerSaving         		0x40
-#define bCCKSideBand              		0x10
-#define bCCKScramble              		0x8
-#define bCCKAntDiversity    		      	0x8000
-#define bCCKCarrierRecovery   	    	0x4000
-#define bCCKTxRate           		     	0x3000
-#define bCCKDCCancel             	 	0x0800
-#define bCCKISICancel             		0x0400
-#define bCCKMatchFilter           		0x0200
-#define bCCKEqualizer             		0x0100
-#define bCCKPreambleDetect       	 	0x800000
-#define bCCKFastFalseCCA          		0x400000
-#define bCCKChEstStart            		0x300000
-#define bCCKCCACount              		0x080000
-#define bCCKcs_lim                			0x070000
-#define bCCKBistMode              		0x80000000
-#define bCCKCCAMask             	  	0x40000000
-#define bCCKTxDACPhase         	   	0x4
-#define bCCKRxADCPhase         	   	0x20000000   //r_rx_clk
-#define bCCKr_cp_mode0         	   	0x0100
-#define bCCKTxDCOffset           	 	0xf0
-#define bCCKRxDCOffset           	 	0xf
-#define bCCKCCAMode              	 	0xc000
-#define bCCKFalseCS_lim           		0x3f00
-#define bCCKCS_ratio              		0xc00000
-#define bCCKCorgBit_sel           		0x300000
-#define bCCKPD_lim                			0x0f0000
-#define bCCKNewCCA                		0x80000000
-#define bCCKRxHPofIG              		0x8000
-#define bCCKRxIG                  			0x7f00
-#define bCCKLNAPolarity           		0x800000
-#define bCCKRx1stGain             		0x7f0000
-#define bCCKRFExtend              		0x20000000 //CCK Rx Iinital gain polarity
-#define bCCKRxAGCSatLevel        	 	0x1f000000
-#define bCCKRxAGCSatCount       	  	0xe0
-#define bCCKRxRFSettle            		0x1f       //AGCsamp_dly
-#define bCCKFixedRxAGC           	 	0x8000
-//#define bCCKRxAGCFormat         	 	0x4000   //remove to HSSI register 0x824
-#define bCCKAntennaPolarity      	 	0x2000
-#define bCCKTxFilterType          		0x0c00
-#define bCCKRxAGCReportType   	   	0x0300
-#define bCCKRxDAGCEn              		0x80000000
-#define bCCKRxDAGCPeriod        	  	0x20000000
-#define bCCKRxDAGCSatLevel     	   	0x1f000000
-#define bCCKTimingRecovery       	 	0x800000
-#define bCCKTxC0                  			0x3f0000
-#define bCCKTxC1                  			0x3f000000
-#define bCCKTxC2                  			0x3f
-#define bCCKTxC3                  			0x3f00
-#define bCCKTxC4                  			0x3f0000
-#define bCCKTxC5                  			0x3f000000
-#define bCCKTxC6                  			0x3f
-#define bCCKTxC7                  			0x3f00
-#define bCCKDebugPort             		0xff0000
-#define bCCKDACDebug              		0x0f000000
-#define bCCKFalseAlarmEnable      		0x8000
-#define bCCKFalseAlarmRead        		0x4000
-#define bCCKTRSSI                 			0x7f
-#define bCCKRxAGCReport           		0xfe
-#define bCCKRxReport_AntSel       		0x80000000
-#define bCCKRxReport_MFOff        		0x40000000
-#define bCCKRxRxReport_SQLoss     	0x20000000
-#define bCCKRxReport_Pktloss      		0x10000000
-#define bCCKRxReport_Lockedbit    	0x08000000
-#define bCCKRxReport_RateError    	0x04000000
-#define bCCKRxReport_RxRate       		0x03000000
-#define bCCKRxFACounterLower      	0xff
-#define bCCKRxFACounterUpper      	0xff000000
-#define bCCKRxHPAGCStart          		0xe000
-#define bCCKRxHPAGCFinal          		0x1c00
-
-#define bCCKRxFalseAlarmEnable    	0x8000
-#define bCCKFACounterFreeze       		0x4000
-
-#define bCCKTxPathSel             		0x10000000
-#define bCCKDefaultRxPath         		0xc000000
-#define bCCKOptionRxPath          		0x3000000
-
-//page c
-#define bNumOfSTF                			0x3
-#define bShift_L                 			0xc0
-#define bGI_TH                   			0xc
-#define bRxPathA                 			0x1
-#define bRxPathB                 			0x2
-#define bRxPathC                 			0x4
-#define bRxPathD                 			0x8
-#define bTxPathA                 			0x1
-#define bTxPathB                 			0x2
-#define bTxPathC                 			0x4
-#define bTxPathD                 			0x8
-#define bTRSSIFreq               			0x200
-#define bADCBackoff              			0x3000
-#define bDFIRBackoff             			0xc000
-#define bTRSSILatchPhase         		0x10000
-#define bRxIDCOffset             			0xff
-#define bRxQDCOffset             			0xff00
-#define bRxDFIRMode              		0x1800000
-#define bRxDCNFType              		0xe000000
-#define bRXIQImb_A               			0x3ff
-#define bRXIQImb_B               			0xfc00
-#define bRXIQImb_C               			0x3f0000
-#define bRXIQImb_D               			0xffc00000
-#define bDC_dc_Notch             		0x60000
-#define bRxNBINotch              			0x1f000000
-#define bPD_TH                   			0xf
-#define bPD_TH_Opt2              		0xc000
-#define bPWED_TH                 			0x700
-#define bIfMF_Win_L              			0x800
-#define bPD_Option               			0x1000
-#define bMF_Win_L                			0xe000
-#define bBW_Search_L             		0x30000
-#define bwin_enh_L               			0xc0000
-#define bBW_TH                   			0x700000
-#define bED_TH2                  			0x3800000
-#define bBW_option               			0x4000000
-#define bRatio_TH                			0x18000000
-#define bWindow_L                			0xe0000000
-#define bSBD_Option              			0x1
-#define bFrame_TH                			0x1c
-#define bFS_Option               			0x60
-#define bDC_Slope_check          		0x80
-#define bFGuard_Counter_DC_L     		0xe00
-#define bFrame_Weight_Short      		0x7000
-#define bSub_Tune                			0xe00000
-#define bFrame_DC_Length         		0xe000000
-#define bSBD_start_offset        		0x30000000
-#define bFrame_TH_2              		0x7
-#define bFrame_GI2_TH            		0x38
-#define bGI2_Sync_en             		0x40
-#define bSarch_Short_Early       		0x300
-#define bSarch_Short_Late        		0xc00
-#define bSarch_GI2_Late          		0x70000
-#define bCFOAntSum               		0x1
-#define bCFOAcc                  			0x2
-#define bCFOStartOffset          		0xc
-#define bCFOLookBack             		0x70
-#define bCFOSumWeight            		0x80
-#define bDAGCEnable              			0x10000
-#define bTXIQImb_A               			0x3ff
-#define bTXIQImb_B               			0xfc00
-#define bTXIQImb_C               			0x3f0000
-#define bTXIQImb_D               			0xffc00000
-#define bTxIDCOffset             			0xff
-#define bTxQDCOffset             			0xff00
-#define bTxDFIRMode              		0x10000
-#define bTxPesudoNoiseOn         		0x4000000
-#define bTxPesudoNoise_A         		0xff
-#define bTxPesudoNoise_B         		0xff00
-#define bTxPesudoNoise_C         		0xff0000
-#define bTxPesudoNoise_D         		0xff000000
-#define bCCADropOption           		0x20000
-#define bCCADropThres            		0xfff00000
-#define bEDCCA_H                 			0xf
-#define bEDCCA_L                 			0xf0
-#define bLambda_ED               0x300
-#define bRxInitialGain           0x7f
-#define bRxAntDivEn              0x80
-#define bRxAGCAddressForLNA      0x7f00
-#define bRxHighPowerFlow         0x8000
-#define bRxAGCFreezeThres        0xc0000
-#define bRxFreezeStep_AGC1       0x300000
-#define bRxFreezeStep_AGC2       0xc00000
-#define bRxFreezeStep_AGC3       0x3000000
-#define bRxFreezeStep_AGC0       0xc000000
-#define bRxRssi_Cmp_En           0x10000000
-#define bRxQuickAGCEn            0x20000000
-#define bRxAGCFreezeThresMode    0x40000000
-#define bRxOverFlowCheckType     0x80000000
-#define bRxAGCShift              0x7f
-#define bTRSW_Tri_Only           0x80
-#define bPowerThres              0x300
-#define bRxAGCEn                 0x1
-#define bRxAGCTogetherEn         0x2
-#define bRxAGCMin                0x4
-#define bRxHP_Ini                0x7
-#define bRxHP_TRLNA              0x70
-#define bRxHP_RSSI               0x700
-#define bRxHP_BBP1               0x7000
-#define bRxHP_BBP2               0x70000
-#define bRxHP_BBP3               0x700000
-#define bRSSI_H                  0x7f0000     //the threshold for high power
-#define bRSSI_Gen                0x7f000000   //the threshold for ant diversity
-#define bRxSettle_TRSW           0x7
-#define bRxSettle_LNA            0x38
-#define bRxSettle_RSSI           0x1c0
-#define bRxSettle_BBP            0xe00
-#define bRxSettle_RxHP           0x7000
-#define bRxSettle_AntSW_RSSI     0x38000
-#define bRxSettle_AntSW          0xc0000
-#define bRxProcessTime_DAGC      0x300000
-#define bRxSettle_HSSI           0x400000
-#define bRxProcessTime_BBPPW     0x800000
-#define bRxAntennaPowerShift     0x3000000
-#define bRSSITableSelect         0xc000000
-#define bRxHP_Final              0x7000000
-#define bRxHTSettle_BBP          0x7
-#define bRxHTSettle_HSSI         0x8
-#define bRxHTSettle_RxHP         0x70
-#define bRxHTSettle_BBPPW        0x80
-#define bRxHTSettle_Idle         0x300
-#define bRxHTSettle_Reserved     0x1c00
-#define bRxHTRxHPEn              0x8000
-#define bRxHTAGCFreezeThres      0x30000
-#define bRxHTAGCTogetherEn       0x40000
-#define bRxHTAGCMin              0x80000
-#define bRxHTAGCEn               0x100000
-#define bRxHTDAGCEn              0x200000
-#define bRxHTRxHP_BBP            0x1c00000
-#define bRxHTRxHP_Final          0xe0000000
-#define bRxPWRatioTH             0x3
-#define bRxPWRatioEn             0x4
-#define bRxMFHold                0x3800
-#define bRxPD_Delay_TH1          0x38
-#define bRxPD_Delay_TH2          0x1c0
-#define bRxPD_DC_COUNT_MAX       0x600
-//#define bRxMF_Hold               0x3800
-#define bRxPD_Delay_TH           0x8000
-#define bRxProcess_Delay         0xf0000
-#define bRxSearchrange_GI2_Early 0x700000
-#define bRxFrame_Guard_Counter_L 0x3800000
-#define bRxSGI_Guard_L           0xc000000
-#define bRxSGI_Search_L          0x30000000
-#define bRxSGI_TH                0xc0000000
-#define bDFSCnt0                 0xff
-#define bDFSCnt1                 0xff00
-#define bDFSFlag                 0xf0000
-
-#define bMFWeightSum             0x300000
-#define bMinIdxTH                0x7f000000
-
-#define bDAFormat                0x40000
-
-#define bTxChEmuEnable           0x01000000
-
-#define bTRSWIsolation_A         0x7f
-#define bTRSWIsolation_B         0x7f00
-#define bTRSWIsolation_C         0x7f0000
-#define bTRSWIsolation_D         0x7f000000
-
-#define bExtLNAGain              0x7c00
-
-//page d
-#define bSTBCEn                  0x4
-#define bAntennaMapping          0x10
-#define bNss                     0x20
-#define bCFOAntSumD              0x200
-#define bPHYCounterReset         0x8000000
-#define bCFOReportGet            0x4000000
-#define bOFDMContinueTx          0x10000000
-#define bOFDMSingleCarrier       0x20000000
-#define bOFDMSingleTone          0x40000000
-//#define bRxPath1                 0x01
-//#define bRxPath2                 0x02
-//#define bRxPath3                 0x04
-//#define bRxPath4                 0x08
-//#define bTxPath1                 0x10
-//#define bTxPath2                 0x20
-#define bHTDetect                0x100
-#define bCFOEn                   0x10000
-#define bCFOValue                0xfff00000
-#define bSigTone_Re              0x3f
-#define bSigTone_Im              0x7f00
-#define bCounter_CCA             0xffff
-#define bCounter_ParityFail      0xffff0000
-#define bCounter_RateIllegal     0xffff
-#define bCounter_CRC8Fail        0xffff0000
-#define bCounter_MCSNoSupport    0xffff
-#define bCounter_FastSync        0xffff
-#define bShortCFO                0xfff
-#define bShortCFOTLength         12   //total
-#define bShortCFOFLength         11   //fraction
-#define bLongCFO                 0x7ff
-#define bLongCFOTLength          11
-#define bLongCFOFLength          11
-#define bTailCFO                 0x1fff
-#define bTailCFOTLength          13
-#define bTailCFOFLength          12
-
-#define bmax_en_pwdB             0xffff
-#define bCC_power_dB             0xffff0000
-#define bnoise_pwdB              0xffff
-#define bPowerMeasTLength        10
-#define bPowerMeasFLength        3
-#define bRx_HT_BW                0x1
-#define bRxSC                    0x6
-#define bRx_HT                   0x8
-
-#define bNB_intf_det_on          0x1
-#define bIntf_win_len_cfg        0x30
-#define bNB_Intf_TH_cfg          0x1c0
-
-#define bRFGain                  0x3f
-#define bTableSel                0x40
-#define bTRSW                    0x80
-
-#define bRxSNR_A                 0xff
-#define bRxSNR_B                 0xff00
-#define bRxSNR_C                 0xff0000
-#define bRxSNR_D                 0xff000000
-#define bSNREVMTLength           8
-#define bSNREVMFLength           1
-
-#define bCSI1st                  0xff
-#define bCSI2nd                  0xff00
-#define bRxEVM1st                0xff0000
-#define bRxEVM2nd                0xff000000
-
-#define bSIGEVM                  0xff
-#define bPWDB                    0xff00
-#define bSGIEN                   0x10000
-
-#define bSFactorQAM1             0xf
-#define bSFactorQAM2             0xf0
-#define bSFactorQAM3             0xf00
-#define bSFactorQAM4             0xf000
-#define bSFactorQAM5             0xf0000
-#define bSFactorQAM6             0xf0000
-#define bSFactorQAM7             0xf00000
-#define bSFactorQAM8             0xf000000
-#define bSFactorQAM9             0xf0000000
-#define bCSIScheme               0x100000
-
-#define bNoiseLvlTopSet          0x3
-#define bChSmooth                0x4
-#define bChSmoothCfg1            0x38
-#define bChSmoothCfg2            0x1c0
-#define bChSmoothCfg3            0xe00
-#define bChSmoothCfg4            0x7000
-#define bMRCMode                 0x800000
-#define bTHEVMCfg                0x7000000
-
-#define bLoopFitType             0x1
-#define bUpdCFO                  0x40
-#define bUpdCFOOffData           0x80
-#define bAdvUpdCFO               0x100
-#define bAdvTimeCtrl             0x800
-#define bUpdClko                 0x1000
-#define bFC                      0x6000
-#define bTrackingMode            0x8000
-#define bPhCmpEnable             0x10000
-#define bUpdClkoLTF              0x20000
-#define bComChCFO                0x40000
-#define bCSIEstiMode             0x80000
-#define bAdvUpdEqz               0x100000
-#define bUChCfg                  0x7000000
-#define bUpdEqz                  0x8000000
-
-//page e
-#define bTxAGCRate18_06			0x7f7f7f7f
-#define bTxAGCRate54_24			0x7f7f7f7f
-#define bTxAGCRateMCS32		0x7f
-#define bTxAGCRateCCK			0x7f00
-#define bTxAGCRateMCS3_MCS0	0x7f7f7f7f
-#define bTxAGCRateMCS7_MCS4	0x7f7f7f7f
-#define bTxAGCRateMCS11_MCS8	0x7f7f7f7f
-#define bTxAGCRateMCS15_MCS12	0x7f7f7f7f
-
-
-//Rx Pseduo noise
-#define bRxPesudoNoiseOn         0x20000000
-#define bRxPesudoNoise_A         0xff
-#define bRxPesudoNoise_B         0xff00
-#define bRxPesudoNoise_C         0xff0000
-#define bRxPesudoNoise_D         0xff000000
-#define bPesudoNoiseState_A      0xffff
-#define bPesudoNoiseState_B      0xffff0000
-#define bPesudoNoiseState_C      0xffff
-#define bPesudoNoiseState_D      0xffff0000
-
-//RF
-//Zebra1
-#define bZebra1_HSSIEnable        0x8
-#define bZebra1_TRxControl        0xc00
-#define bZebra1_TRxGainSetting    0x07f
-#define bZebra1_RxCorner          0xc00
-#define bZebra1_TxChargePump      0x38
-#define bZebra1_RxChargePump      0x7
-#define bZebra1_ChannelNum        0xf80
-#define bZebra1_TxLPFBW           0x400
-#define bZebra1_RxLPFBW           0x600
-
-//Zebra4
-#define bRTL8256RegModeCtrl1      0x100
-#define bRTL8256RegModeCtrl0      0x40
-#define bRTL8256_TxLPFBW          0x18
-#define bRTL8256_RxLPFBW          0x600
-
-//RTL8258
-#define bRTL8258_TxLPFBW          0xc
-#define bRTL8258_RxLPFBW          0xc00
-#define bRTL8258_RSSILPFBW        0xc0
-
-//byte endable for sb_write
-#define bByte0                    0x1
-#define bByte1                    0x2
-#define bByte2                    0x4
-#define bByte3                    0x8
-#define bWord0                    0x3
-#define bWord1                    0xc
-#define bDWord                    0xf
-
-//for PutRegsetting & GetRegSetting BitMask
-#define bMaskByte0                0xff
-#define bMaskByte1                0xff00
-#define bMaskByte2                0xff0000
-#define bMaskByte3                0xff000000
-#define bMaskHWord                0xffff0000
-#define bMaskLWord                0x0000ffff
-#define bMaskDWord                0xffffffff
-
-//for PutRFRegsetting & GetRFRegSetting BitMask
-#define bMask12Bits               0xfff
-
-#define bEnable                   0x1
-#define bDisable                  0x0
-
-#define LeftAntenna               0x0
-#define RightAntenna              0x1
-
-#define tCheckTxStatus            500   //500ms
-#define tUpdateRxCounter          100   //100ms
-
-#define rateCCK     0
-#define rateOFDM    1
-#define rateHT      2
-
-//define Register-End
-#define bPMAC_End                 0x1ff
-#define bFPGAPHY0_End             0x8ff
-#define bFPGAPHY1_End             0x9ff
-#define bCCKPHY0_End              0xaff
-#define bOFDMPHY0_End             0xcff
-#define bOFDMPHY1_End             0xdff
-
-//define max debug item in each debug page
-//#define bMaxItem_FPGA_PHY0        0x9
-//#define bMaxItem_FPGA_PHY1        0x3
-//#define bMaxItem_PHY_11B          0x16
-//#define bMaxItem_OFDM_PHY0        0x29
-//#define bMaxItem_OFDM_PHY1        0x0
-
-#define bPMACControl              0x0
-#define bWMACControl              0x1
-#define bWNICControl              0x2
-
-#define PathA                     0x0
-#define PathB                     0x1
-#define PathC                     0x2
-#define PathD                     0x3
-
-#define	rRTL8256RxMixerPole		0xb
-#define 	bZebraRxMixerPole		0x6
-#define 	rRTL8256TxBBOPBias        0x9
-#define 	bRTL8256TxBBOPBias       0x400
-#define 	rRTL8256TxBBBW             19
-#define 	bRTL8256TxBBBW            	0x18
-
-#endif	//__INC_HAL8190PCIPHYREG_H
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig
new file mode 100644
index 0000000..0a9c39c
--- /dev/null
+++ b/drivers/staging/sep/Kconfig
@@ -0,0 +1,10 @@
+config DX_SEP
+	tristate "Discretix SEP driver"
+#	depends on MRST
+	depends on RAR_REGISTER && PCI
+	default y
+	help
+	  Discretix SEP driver
+
+	  If unsure say M. The compiled module will be
+	  called sep_driver.ko
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile
new file mode 100644
index 0000000..628d5f9
--- /dev/null
+++ b/drivers/staging/sep/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_DX_SEP) := sep_driver.o
+
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO
new file mode 100644
index 0000000..ff0e931
--- /dev/null
+++ b/drivers/staging/sep/TODO
@@ -0,0 +1,8 @@
+Todo's so far (from Alan Cox)
+- Fix firmware loading
+- Get firmware into firmware git tree
+- Review and tidy each algorithm function
+- Check whether it can be plugged into any of the kernel crypto API
+  interfaces
+- Do something about the magic shared memory interface and replace it
+  with something saner (in Linux terms)
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h
new file mode 100644
index 0000000..9200524
--- /dev/null
+++ b/drivers/staging/sep/sep_dev.h
@@ -0,0 +1,110 @@
+#ifndef __SEP_DEV_H__
+#define __SEP_DEV_H__
+
+/*
+ *
+ *  sep_dev.h - Security Processor Device Structures
+ *
+ *  Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *  Copyright(c) 2009 Discretix. 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., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Alan Cox		alan@linux.intel.com
+ *
+ */
+
+struct sep_device {
+	/* pointer to pci dev */
+	struct pci_dev *pdev;
+
+	unsigned long in_use;
+
+	/* address of the shared memory allocated during init for SEP driver
+	   (coherent alloc) */
+	void *shared_addr;
+	/* the physical address of the shared area */
+	dma_addr_t shared_bus;
+
+	/* restricted access region (coherent alloc) */
+	dma_addr_t rar_bus;
+	void *rar_addr;
+	/* firmware regions: cache is at rar_addr */
+	unsigned long cache_size;
+
+	/* follows the cache */
+	dma_addr_t resident_bus;
+	unsigned long resident_size;
+	void *resident_addr;
+
+	/* start address of the access to the SEP registers from driver */
+	void __iomem *reg_addr;
+	/* transaction counter that coordinates the transactions between SEP and HOST */
+	unsigned long send_ct;
+	/* counter for the messages from sep */
+	unsigned long reply_ct;
+	/* counter for the number of bytes allocated in the pool for the current
+	   transaction */
+	unsigned long data_pool_bytes_allocated;
+
+	/* array of pointers to the pages that represent input data for the synchronic
+	   DMA action */
+	struct page **in_page_array;
+
+	/* array of pointers to the pages that represent out data for the synchronic
+	   DMA action */
+	struct page **out_page_array;
+
+	/* number of pages in the sep_in_page_array */
+	unsigned long in_num_pages;
+
+	/* number of pages in the sep_out_page_array */
+	unsigned long out_num_pages;
+
+	/* global data for every flow */
+	struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS];
+
+	/* pointer to the workqueue that handles the flow done interrupts */
+	struct workqueue_struct *flow_wq;
+
+};
+
+static struct sep_device *sep_dev;
+
+static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value)
+{
+	void __iomem *addr = dev->reg_addr + reg;
+	writel(value, addr);
+}
+
+static inline u32 sep_read_reg(struct sep_device *dev, int reg)
+{
+	void __iomem *addr = dev->reg_addr + reg;
+	return readl(addr);
+}
+
+/* wait for SRAM write complete(indirect write */
+static inline void sep_wait_sram_write(struct sep_device *dev)
+{
+	u32 reg_val;
+	do
+		reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR);
+	while (!(reg_val & 1));
+}
+
+
+#endif
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
new file mode 100644
index 0000000..87f8a11
--- /dev/null
+++ b/drivers/staging/sep/sep_driver.c
@@ -0,0 +1,2707 @@
+/*
+ *
+ *  sep_driver.c - Security Processor Driver main group of functions
+ *
+ *  Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *  Copyright(c) 2009 Discretix. 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., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Mark Allyn		mark.a.allyn@intel.com
+ *
+ *  CHANGES:
+ *
+ *  2009.06.26	Initial publish
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/kdev_t.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/pci.h>
+#include <linux/firmware.h>
+#include <asm/ioctl.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <asm/cacheflush.h>
+#include "sep_driver_hw_defs.h"
+#include "sep_driver_config.h"
+#include "sep_driver_api.h"
+#include "sep_dev.h"
+
+#if SEP_DRIVER_ARM_DEBUG_MODE
+
+#define  CRYS_SEP_ROM_length                  0x4000
+#define  CRYS_SEP_ROM_start_address           0x8000C000UL
+#define  CRYS_SEP_ROM_start_address_offset    0xC000UL
+#define  SEP_ROM_BANK_register                0x80008420UL
+#define  SEP_ROM_BANK_register_offset         0x8420UL
+#define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0x82000000
+
+/*
+ * THESE 2 definitions are specific to the board - must be
+ * defined during integration
+ */
+#define SEP_RAR_IO_MEM_REGION_START_ADDRESS   0xFF0D0000
+
+/* 2M size */
+
+static void sep_load_rom_code(struct sep_device *sep)
+{
+	/* Index variables */
+	unsigned long i, k, j;
+	u32 reg;
+	u32 error;
+	u32 warning;
+
+	/* Loading ROM from SEP_ROM_image.h file */
+	k = sizeof(CRYS_SEP_ROM);
+
+	edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n");
+
+	edbg("SEP Driver: k is %lu\n", k);
+	edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr);
+	edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset);
+
+	for (i = 0; i < 4; i++) {
+		/* write bank */
+		sep_write_reg(sep, SEP_ROM_BANK_register_offset, i);
+
+		for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) {
+			sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]);
+
+			k = k - 4;
+
+			if (k == 0) {
+				j = CRYS_SEP_ROM_length;
+				i = 4;
+			}
+		}
+	}
+
+	/* reset the SEP */
+	sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1);
+
+	/* poll for SEP ROM boot finish */
+	do
+		reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+	while (!reg);
+
+	edbg("SEP Driver: ROM polling ended\n");
+
+	switch (reg) {
+	case 0x1:
+		/* fatal error - read erro status from GPRO */
+		error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+		edbg("SEP Driver: ROM polling case 1\n");
+		break;
+	case 0x4:
+		/* Cold boot ended successfully  */
+	case 0x8:
+		/* Warmboot ended successfully */
+	case 0x10:
+		/* ColdWarm boot ended successfully */
+		error = 0;
+	case 0x2:
+		/* Boot First Phase ended  */
+		warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+	case 0x20:
+		edbg("SEP Driver: ROM polling case %d\n", reg);
+		break;
+	}
+
+}
+
+#else
+static void sep_load_rom_code(struct sep_device *sep) { }
+#endif				/* SEP_DRIVER_ARM_DEBUG_MODE */
+
+
+
+/*----------------------------------------
+	DEFINES
+-----------------------------------------*/
+
+#define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000
+#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000
+
+/*--------------------------------------------
+	GLOBAL variables
+--------------------------------------------*/
+
+/* debug messages level */
+static int debug;
+module_param(debug, int , 0);
+MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages");
+
+/* Keep this a single static object for now to keep the conversion easy */
+
+static struct sep_device sep_instance;
+static struct sep_device *sep_dev = &sep_instance;
+
+/*
+  mutex for the access to the internals of the sep driver
+*/
+static DEFINE_MUTEX(sep_mutex);
+
+
+/* wait queue head (event) of the driver */
+static DECLARE_WAIT_QUEUE_HEAD(sep_event);
+
+/**
+ *	sep_load_firmware	-	copy firmware cache/resident
+ *	@sep: device we are loading
+ *
+ *	This functions copies the cache and resident from their source
+ *	location into destination shared memory.
+ */
+
+static int sep_load_firmware(struct sep_device *sep)
+{
+	const struct firmware *fw;
+	char *cache_name = "cache.image.bin";
+	char *res_name = "resident.image.bin";
+	int error;
+
+	edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
+	edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
+
+	/* load cache */
+	error = request_firmware(&fw, cache_name, &sep->pdev->dev);
+	if (error) {
+		edbg("SEP Driver:cant request cache fw\n");
+		return error;
+	}
+	edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data);
+
+	memcpy(sep->rar_addr, (void *)fw->data, fw->size);
+	sep->cache_size = fw->size;
+	release_firmware(fw);
+
+	sep->resident_bus = sep->rar_bus + sep->cache_size;
+	sep->resident_addr = sep->rar_addr + sep->cache_size;
+
+	/* load resident */
+	error = request_firmware(&fw, res_name, &sep->pdev->dev);
+	if (error) {
+		edbg("SEP Driver:cant request res fw\n");
+		return error;
+	}
+	edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data);
+
+	memcpy(sep->resident_addr, (void *) fw->data, fw->size);
+	sep->resident_size = fw->size;
+	release_firmware(fw);
+
+	edbg("sep: resident v %p b %08llx cache v %p b %08llx\n",
+		sep->resident_addr, (unsigned long long)sep->resident_bus,
+		sep->rar_addr, (unsigned long long)sep->rar_bus);
+	return 0;
+}
+
+/**
+ *	sep_map_and_alloc_shared_area	-	allocate shared block
+ *	@sep: security processor
+ *	@size: size of shared area
+ *
+ *	Allocate a shared buffer in host memory that can be used by both the
+ *	kernel and also the hardware interface via DMA.
+ */
+
+static int sep_map_and_alloc_shared_area(struct sep_device *sep,
+							unsigned long size)
+{
+	/* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */
+	sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size,
+					&sep->shared_bus, GFP_KERNEL);
+
+	if (!sep->shared_addr) {
+		edbg("sep_driver :shared memory dma_alloc_coherent failed\n");
+		return -ENOMEM;
+	}
+	/* set the bus address of the shared area */
+	edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n",
+		size, sep->shared_addr, (unsigned long long)sep->shared_bus);
+	return 0;
+}
+
+/**
+ *	sep_unmap_and_free_shared_area	-	free shared block
+ *	@sep: security processor
+ *
+ *	Free the shared area allocated to the security processor. The
+ *	processor must have finished with this and any final posted
+ *	writes cleared before we do so.
+ */
+static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size)
+{
+	dma_free_coherent(&sep->pdev->dev, size,
+				sep->shared_addr, sep->shared_bus);
+}
+
+/**
+ *	sep_shared_virt_to_bus	-	convert bus/virt addresses
+ *
+ *	Returns the bus address inside the shared area according
+ *	to the virtual address.
+ */
+
+static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep,
+						void *virt_address)
+{
+	dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
+	edbg("sep: virt to bus b %08llx v %p\n", pa, virt_address);
+	return pa;
+}
+
+/**
+ *	sep_shared_bus_to_virt	-	convert bus/virt addresses
+ *
+ *	Returns virtual address inside the shared area according
+ *	to the bus address.
+ */
+
+static void *sep_shared_bus_to_virt(struct sep_device *sep,
+						dma_addr_t bus_address)
+{
+	return sep->shared_addr + (bus_address - sep->shared_bus);
+}
+
+
+/**
+ *	sep_try_open		-	attempt to open a SEP device
+ *	@sep: device to attempt to open
+ *
+ *	Atomically attempt to get ownership of a SEP device.
+ *	Returns 1 if the device was opened, 0 on failure.
+ */
+
+static int sep_try_open(struct sep_device *sep)
+{
+	if (!test_and_set_bit(0, &sep->in_use))
+		return 1;
+	return 0;
+}
+
+/**
+ *	sep_open		-	device open method
+ *	@inode: inode of sep device
+ *	@filp: file handle to sep device
+ *
+ *	Open method for the SEP device. Called when userspace opens
+ *	the SEP device node. Must also release the memory data pool
+ *	allocations.
+ *
+ *	Returns zero on success otherwise an error code.
+ */
+
+static int sep_open(struct inode *inode, struct file *filp)
+{
+	if (sep_dev == NULL)
+		return -ENODEV;
+
+	/* check the blocking mode */
+	if (filp->f_flags & O_NDELAY) {
+		if (sep_try_open(sep_dev) == 0)
+			return -EAGAIN;
+	} else
+		if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0)
+			return -EINTR;
+
+	/* Bind to the device, we only have one which makes it easy */
+	filp->private_data = sep_dev;
+	/* release data pool allocations */
+	sep_dev->data_pool_bytes_allocated = 0;
+	return 0;
+}
+
+
+/**
+ *	sep_release		-	close a SEP device
+ *	@inode: inode of SEP device
+ *	@filp: file handle being closed
+ *
+ *	Called on the final close of a SEP device. As the open protects against
+ *	multiple simultaenous opens that means this method is called when the
+ *	final reference to the open handle is dropped.
+ */
+
+static int sep_release(struct inode *inode, struct file *filp)
+{
+	struct sep_device *sep =  filp->private_data;
+#if 0				/*!SEP_DRIVER_POLLING_MODE */
+	/* close IMR */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
+	/* release IRQ line */
+	free_irq(SEP_DIRVER_IRQ_NUM, sep);
+
+#endif
+	/* Ensure any blocked open progresses */
+	clear_bit(0, &sep->in_use);
+	wake_up(&sep_event);
+	return 0;
+}
+
+/*---------------------------------------------------------------
+  map function - this functions maps the message shared area
+-----------------------------------------------------------------*/
+static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	dma_addr_t bus_addr;
+	struct sep_device *sep = filp->private_data;
+
+	dbg("-------->SEP Driver: mmap start\n");
+
+	/* check that the size of the mapped range is as the size of the message
+	   shared area */
+	if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
+		edbg("SEP Driver mmap requested size is more than allowed\n");
+		printk(KERN_WARNING "SEP Driver mmap requested size is more \
+			than allowed\n");
+		printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end);
+		printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start);
+		return -EAGAIN;
+	}
+
+	edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
+
+	/* get bus address */
+	bus_addr = sep->shared_bus;
+
+	edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr);
+
+	if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
+		edbg("SEP Driver remap_page_range failed\n");
+		printk(KERN_WARNING "SEP Driver remap_page_range failed\n");
+		return -EAGAIN;
+	}
+
+	dbg("SEP Driver:<-------- mmap end\n");
+
+	return 0;
+}
+
+
+/*-----------------------------------------------
+  poll function
+*----------------------------------------------*/
+static unsigned int sep_poll(struct file *filp, poll_table * wait)
+{
+	unsigned long count;
+	unsigned int mask = 0;
+	unsigned long retval = 0;	/* flow id */
+	struct sep_device *sep = filp->private_data;
+
+	dbg("---------->SEP Driver poll: start\n");
+
+
+#if SEP_DRIVER_POLLING_MODE
+
+	while (sep->send_ct != (retval & 0x7FFFFFFF)) {
+		retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+
+		for (count = 0; count < 10 * 4; count += 4)
+			edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count)));
+	}
+
+	sep->reply_ct++;
+#else
+	/* add the event to the polling wait table */
+	poll_wait(filp, &sep_event, wait);
+
+#endif
+
+	edbg("sep->send_ct is %lu\n", sep->send_ct);
+	edbg("sep->reply_ct is %lu\n", sep->reply_ct);
+
+	/* check if the data is ready */
+	if (sep->send_ct == sep->reply_ct) {
+		for (count = 0; count < 12 * 4; count += 4)
+			edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count)));
+
+		for (count = 0; count < 10 * 4; count += 4)
+			edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count)));
+
+		retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
+		edbg("retval is %lu\n", retval);
+		/* check if the this is sep reply or request */
+		if (retval >> 31) {
+			edbg("SEP Driver: sep request in\n");
+			/* request */
+			mask |= POLLOUT | POLLWRNORM;
+		} else {
+			edbg("SEP Driver: sep reply in\n");
+			mask |= POLLIN | POLLRDNORM;
+		}
+	}
+	dbg("SEP Driver:<-------- poll exit\n");
+	return mask;
+}
+
+/**
+ *	sep_time_address	-	address in SEP memory of time
+ *	@sep: SEP device we want the address from
+ *
+ *	Return the address of the two dwords in memory used for time
+ *	setting.
+ */
+
+static u32 *sep_time_address(struct sep_device *sep)
+{
+	return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
+}
+
+/**
+ *	sep_set_time		-	set the SEP time
+ *	@sep: the SEP we are setting the time for
+ *
+ *	Calculates time and sets it at the predefined address.
+ *	Called with the sep mutex held.
+ */
+static unsigned long sep_set_time(struct sep_device *sep)
+{
+	struct timeval time;
+	u32 *time_addr;	/* address of time as seen by the kernel */
+
+
+	dbg("sep:sep_set_time start\n");
+
+	do_gettimeofday(&time);
+
+	/* set value in the SYSTEM MEMORY offset */
+	time_addr = sep_time_address(sep);
+
+	time_addr[0] = SEP_TIME_VAL_TOKEN;
+	time_addr[1] = time.tv_sec;
+
+	edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec);
+	edbg("SEP Driver:time_addr is %p\n", time_addr);
+	edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
+
+	return time.tv_sec;
+}
+
+/**
+ *	sep_dump_message	- dump the message that is pending
+ *	@sep: sep device
+ *
+ *	Dump out the message pending in the shared message area
+ */
+
+static void sep_dump_message(struct sep_device *sep)
+{
+	int count;
+	for (count = 0; count < 12 * 4; count += 4)
+		edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count)));
+}
+
+/**
+ *	sep_send_command_handler	-	kick off a command
+ *	@sep: sep being signalled
+ *
+ *	This function raises interrupt to SEP that signals that is has a new
+ *	command from the host
+ */
+
+static void sep_send_command_handler(struct sep_device *sep)
+{
+	dbg("sep:sep_send_command_handler start\n");
+
+	mutex_lock(&sep_mutex);
+	sep_set_time(sep);
+
+	/* FIXME: flush cache */
+	flush_cache_all();
+
+	sep_dump_message(sep);
+	/* update counter */
+	sep->send_ct++;
+	/* send interrupt to SEP */
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
+	dbg("SEP Driver:<-------- sep_send_command_handler end\n");
+	mutex_unlock(&sep_mutex);
+	return;
+}
+
+/**
+ *	sep_send_reply_command_handler	-	kick off a command reply
+ *	@sep: sep being signalled
+ *
+ *	This function raises interrupt to SEP that signals that is has a new
+ *	command from the host
+ */
+
+static void sep_send_reply_command_handler(struct sep_device *sep)
+{
+	dbg("sep:sep_send_reply_command_handler start\n");
+
+	/* flash cache */
+	flush_cache_all();
+
+	sep_dump_message(sep);
+
+	mutex_lock(&sep_mutex);
+	sep->send_ct++;  	/* update counter */
+	/* send the interrupt to SEP */
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
+	/* update both counters */
+	sep->send_ct++;
+	sep->reply_ct++;
+	mutex_unlock(&sep_mutex);
+	dbg("sep: sep_send_reply_command_handler end\n");
+}
+
+/*
+  This function handles the allocate data pool memory request
+  This function returns calculates the bus address of the
+  allocated memory, and the offset of this area from the mapped address.
+  Therefore, the FVOs in user space can calculate the exact virtual
+  address of this allocated memory
+*/
+static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
+							unsigned long arg)
+{
+	int error;
+	struct sep_driver_alloc_t command_args;
+
+	dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n");
+
+	error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t));
+	if (error)
+		goto end_function;
+
+	/* allocate memory */
+	if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	/* set the virtual and bus address */
+	command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
+	command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated;
+
+	/* write the memory back to the user space */
+	error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t));
+	if (error)
+		goto end_function;
+
+	/* set the allocation */
+	sep->data_pool_bytes_allocated += command_args.num_bytes;
+
+end_function:
+	dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n");
+	return error;
+}
+
+/*
+  This function  handles write into allocated data pool command
+*/
+static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg)
+{
+	int error;
+	void *virt_address;
+	unsigned long va;
+	unsigned long app_in_address;
+	unsigned long num_bytes;
+	void *data_pool_area_addr;
+
+	dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n");
+
+	/* get the application address */
+	error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address));
+	if (error)
+		goto end_function;
+
+	/* get the virtual kernel address address */
+	error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
+	if (error)
+		goto end_function;
+	virt_address = (void *)va;
+
+	/* get the number of bytes */
+	error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
+	if (error)
+		goto end_function;
+
+	/* calculate the start of the data pool */
+	data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
+
+
+	/* check that the range of the virtual kernel address is correct */
+	if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) {
+		error = -EINVAL;
+		goto end_function;
+	}
+	/* copy the application data */
+	error = copy_from_user(virt_address, (void *) app_in_address, num_bytes);
+end_function:
+	dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n");
+	return error;
+}
+
+/*
+  this function handles the read from data pool command
+*/
+static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg)
+{
+	int error;
+	/* virtual address of dest application buffer */
+	unsigned long app_out_address;
+	/* virtual address of the data pool */
+	unsigned long va;
+	void *virt_address;
+	unsigned long num_bytes;
+	void *data_pool_area_addr;
+
+	dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n");
+
+	/* get the application address */
+	error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address));
+	if (error)
+		goto end_function;
+
+	/* get the virtual kernel address address */
+	error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address));
+	if (error)
+		goto end_function;
+	virt_address = (void *)va;
+
+	/* get the number of bytes */
+	error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes));
+	if (error)
+		goto end_function;
+
+	/* calculate the start of the data pool */
+	data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES;
+
+	/* FIXME: These are incomplete all over the driver: what about + len
+	   and when doing that also overflows */
+	/* check that the range of the virtual kernel address is correct */
+	if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	/* copy the application data */
+	error = copy_to_user((void *) app_out_address, virt_address, num_bytes);
+end_function:
+	dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n");
+	return error;
+}
+
+/*
+  This function releases all the application virtual buffer physical pages,
+	that were previously locked
+*/
+static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag)
+{
+	unsigned long count;
+
+	if (dirtyFlag) {
+		for (count = 0; count < num_pages; count++) {
+			/* the out array was written, therefore the data was changed */
+			if (!PageReserved(page_array_ptr[count]))
+				SetPageDirty(page_array_ptr[count]);
+			page_cache_release(page_array_ptr[count]);
+		}
+	} else {
+		/* free in pages - the data was only read, therefore no update was done
+		   on those pages */
+		for (count = 0; count < num_pages; count++)
+			page_cache_release(page_array_ptr[count]);
+	}
+
+	if (page_array_ptr)
+		/* free the array */
+		kfree(page_array_ptr);
+
+	return 0;
+}
+
+/*
+  This function locks all the physical pages of the kernel virtual buffer
+  and construct a basic lli  array, where each entry holds the physical
+  page address and the size that application data holds in this physical pages
+*/
+static int sep_lock_kernel_pages(struct sep_device *sep,
+				 unsigned long kernel_virt_addr,
+				 unsigned long data_size,
+				 unsigned long *num_pages_ptr,
+				 struct sep_lli_entry_t **lli_array_ptr,
+				 struct page ***page_array_ptr)
+{
+	int error = 0;
+	/* the the page of the end address of the user space buffer */
+	unsigned long end_page;
+	/* the page of the start address of the user space buffer */
+	unsigned long start_page;
+	/* the range in pages */
+	unsigned long num_pages;
+	struct sep_lli_entry_t *lli_array;
+	/* next kernel address to map */
+	unsigned long next_kernel_address;
+	unsigned long count;
+
+	dbg("SEP Driver:--------> sep_lock_kernel_pages start\n");
+
+	/* set start and end pages  and num pages */
+	end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT;
+	start_page = kernel_virt_addr >> PAGE_SHIFT;
+	num_pages = end_page - start_page + 1;
+
+	edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr);
+	edbg("SEP Driver: data_size is %lu\n", data_size);
+	edbg("SEP Driver: start_page is %lx\n", start_page);
+	edbg("SEP Driver: end_page is %lx\n", end_page);
+	edbg("SEP Driver: num_pages is %lu\n", num_pages);
+
+	lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
+	if (!lli_array) {
+		edbg("SEP Driver: kmalloc for lli_array failed\n");
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	/* set the start address of the first page - app data may start not at
+	   the beginning of the page */
+	lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr);
+
+	/* check that not all the data is in the first page only */
+	if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size)
+		lli_array[0].block_size = data_size;
+	else
+		lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK));
+
+	/* debug print */
+	dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
+
+	/* advance the address to the start of the next page */
+	next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE;
+
+	/* go from the second page to the prev before last */
+	for (count = 1; count < (num_pages - 1); count++) {
+		lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
+		lli_array[count].block_size = PAGE_SIZE;
+
+		edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+		next_kernel_address += PAGE_SIZE;
+	}
+
+	/* if more then 1 pages locked - then update for the last page size needed */
+	if (num_pages > 1) {
+		/* update the address of the last page */
+		lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address);
+
+		/* set the size of the last page */
+		lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK);
+
+		if (lli_array[count].block_size == 0) {
+			dbg("app_virt_addr is %08lx\n", kernel_virt_addr);
+			dbg("data_size is %lu\n", data_size);
+			while (1);
+		}
+
+		edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+	}
+	/* set output params */
+	*lli_array_ptr = lli_array;
+	*num_pages_ptr = num_pages;
+	*page_array_ptr = 0;
+end_function:
+	dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n");
+	return 0;
+}
+
+/*
+  This function locks all the physical pages of the application virtual buffer
+  and construct a basic lli  array, where each entry holds the physical page
+  address and the size that application data holds in this physical pages
+*/
+static int sep_lock_user_pages(struct sep_device *sep,
+			unsigned long app_virt_addr,
+			unsigned long data_size,
+			unsigned long *num_pages_ptr,
+			struct sep_lli_entry_t **lli_array_ptr,
+			struct page ***page_array_ptr)
+{
+	int error = 0;
+	/* the the page of the end address of the user space buffer */
+	unsigned long end_page;
+	/* the page of the start address of the user space buffer */
+	unsigned long start_page;
+	/* the range in pages */
+	unsigned long num_pages;
+	struct page **page_array;
+	struct sep_lli_entry_t *lli_array;
+	unsigned long count;
+	int result;
+
+	dbg("SEP Driver:--------> sep_lock_user_pages start\n");
+
+	/* set start and end pages  and num pages */
+	end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
+	start_page = app_virt_addr >> PAGE_SHIFT;
+	num_pages = end_page - start_page + 1;
+
+	edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr);
+	edbg("SEP Driver: data_size is %lu\n", data_size);
+	edbg("SEP Driver: start_page is %lu\n", start_page);
+	edbg("SEP Driver: end_page is %lu\n", end_page);
+	edbg("SEP Driver: num_pages is %lu\n", num_pages);
+
+	/* allocate array of pages structure pointers */
+	page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
+	if (!page_array) {
+		edbg("SEP Driver: kmalloc for page_array failed\n");
+
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC);
+	if (!lli_array) {
+		edbg("SEP Driver: kmalloc for lli_array failed\n");
+
+		error = -ENOMEM;
+		goto end_function_with_error1;
+	}
+
+	/* convert the application virtual address into a set of physical */
+	down_read(&current->mm->mmap_sem);
+	result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0);
+	up_read(&current->mm->mmap_sem);
+
+	/* check the number of pages locked - if not all then exit with error */
+	if (result != num_pages) {
+		dbg("SEP Driver: not all pages locked by get_user_pages\n");
+
+		error = -ENOMEM;
+		goto end_function_with_error2;
+	}
+
+	/* flush the cache */
+	for (count = 0; count < num_pages; count++)
+		flush_dcache_page(page_array[count]);
+
+	/* set the start address of the first page - app data may start not at
+	   the beginning of the page */
+	lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK));
+
+	/* check that not all the data is in the first page only */
+	if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
+		lli_array[0].block_size = data_size;
+	else
+		lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));
+
+	/* debug print */
+	dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size);
+
+	/* go from the second page to the prev before last */
+	for (count = 1; count < (num_pages - 1); count++) {
+		lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
+		lli_array[count].block_size = PAGE_SIZE;
+
+		edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+	}
+
+	/* if more then 1 pages locked - then update for the last page size needed */
+	if (num_pages > 1) {
+		/* update the address of the last page */
+		lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]);
+
+		/* set the size of the last page */
+		lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK);
+
+		if (lli_array[count].block_size == 0) {
+			dbg("app_virt_addr is %08lx\n", app_virt_addr);
+			dbg("data_size is %lu\n", data_size);
+			while (1);
+		}
+		edbg("lli_array[%lu].physical_address is %08lx, \
+		lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size);
+	}
+
+	/* set output params */
+	*lli_array_ptr = lli_array;
+	*num_pages_ptr = num_pages;
+	*page_array_ptr = page_array;
+	goto end_function;
+
+end_function_with_error2:
+	/* release the cache */
+	for (count = 0; count < num_pages; count++)
+		page_cache_release(page_array[count]);
+	kfree(lli_array);
+end_function_with_error1:
+	kfree(page_array);
+end_function:
+	dbg("SEP Driver:<-------- sep_lock_user_pages end\n");
+	return 0;
+}
+
+
+/*
+  this function calculates the size of data that can be inserted into the lli
+  table from this array the condition is that either the table is full
+  (all etnries are entered), or there are no more entries in the lli array
+*/
+static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries)
+{
+	unsigned long table_data_size = 0;
+	unsigned long counter;
+
+	/* calculate the data in the out lli table if till we fill the whole
+	   table or till the data has ended */
+	for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++)
+		table_data_size += lli_in_array_ptr[counter].block_size;
+	return table_data_size;
+}
+
+/*
+  this functions builds ont lli table from the lli_array according to
+  the given size of data
+*/
+static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size)
+{
+	unsigned long curr_table_data_size;
+	/* counter of lli array entry */
+	unsigned long array_counter;
+
+	dbg("SEP Driver:--------> sep_build_lli_table start\n");
+
+	/* init currrent table data size and lli array entry counter */
+	curr_table_data_size = 0;
+	array_counter = 0;
+	*num_table_entries_ptr = 1;
+
+	edbg("SEP Driver:table_data_size is %lu\n", table_data_size);
+
+	/* fill the table till table size reaches the needed amount */
+	while (curr_table_data_size < table_data_size) {
+		/* update the number of entries in table */
+		(*num_table_entries_ptr)++;
+
+		lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address;
+		lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size;
+		curr_table_data_size += lli_table_ptr->block_size;
+
+		edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
+		edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+		edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+
+		/* check for overflow of the table data */
+		if (curr_table_data_size > table_data_size) {
+			edbg("SEP Driver:curr_table_data_size > table_data_size\n");
+
+			/* update the size of block in the table */
+			lli_table_ptr->block_size -= (curr_table_data_size - table_data_size);
+
+			/* update the physical address in the lli array */
+			lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size;
+
+			/* update the block size left in the lli array */
+			lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size);
+		} else
+			/* advance to the next entry in the lli_array */
+			array_counter++;
+
+		edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+		edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+
+		/* move to the next entry in table */
+		lli_table_ptr++;
+	}
+
+	/* set the info entry to default */
+	lli_table_ptr->physical_address = 0xffffffff;
+	lli_table_ptr->block_size = 0;
+
+	edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr);
+	edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+	edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+
+	/* set the output parameter */
+	*num_processed_entries_ptr += array_counter;
+
+	edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr);
+	dbg("SEP Driver:<-------- sep_build_lli_table end\n");
+	return;
+}
+
+/*
+  this function goes over the list of the print created tables and
+  prints all the data
+*/
+static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size)
+{
+	unsigned long table_count;
+	unsigned long entries_count;
+
+	dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n");
+
+	table_count = 1;
+	while ((unsigned long) lli_table_ptr != 0xffffffff) {
+		edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size);
+		edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries);
+
+		/* print entries of the table (without info entry) */
+		for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) {
+			edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr);
+			edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size);
+		}
+
+		/* point to the info entry */
+		lli_table_ptr--;
+
+		edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size);
+		edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address);
+
+
+		table_data_size = lli_table_ptr->block_size & 0xffffff;
+		num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;
+		lli_table_ptr = (struct sep_lli_entry_t *)
+		    (lli_table_ptr->physical_address);
+
+		edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr);
+
+		if ((unsigned long) lli_table_ptr != 0xffffffff)
+			lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr);
+
+		table_count++;
+	}
+	dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n");
+}
+
+
+/*
+  This function prepares only input DMA table for synhronic symmetric
+  operations (HASH)
+*/
+static int sep_prepare_input_dma_table(struct sep_device *sep,
+				unsigned long app_virt_addr,
+				unsigned long data_size,
+				unsigned long block_size,
+				unsigned long *lli_table_ptr,
+				unsigned long *num_entries_ptr,
+				unsigned long *table_data_size_ptr,
+				bool isKernelVirtualAddress)
+{
+	/* pointer to the info entry of the table - the last entry */
+	struct sep_lli_entry_t *info_entry_ptr;
+	/* array of pointers ot page */
+	struct sep_lli_entry_t *lli_array_ptr;
+	/* points to the first entry to be processed in the lli_in_array */
+	unsigned long current_entry;
+	/* num entries in the virtual buffer */
+	unsigned long sep_lli_entries;
+	/* lli table pointer */
+	struct sep_lli_entry_t *in_lli_table_ptr;
+	/* the total data in one table */
+	unsigned long table_data_size;
+	/* number of entries in lli table */
+	unsigned long num_entries_in_table;
+	/* next table address */
+	void *lli_table_alloc_addr;
+	unsigned long result;
+
+	dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n");
+
+	edbg("SEP Driver:data_size is %lu\n", data_size);
+	edbg("SEP Driver:block_size is %lu\n", block_size);
+
+	/* initialize the pages pointers */
+	sep->in_page_array = 0;
+	sep->in_num_pages = 0;
+
+	if (data_size == 0) {
+		/* special case  - created 2 entries table with zero data */
+		in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES);
+		/* FIXME: Should the entry below not be for _bus */
+		in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+		in_lli_table_ptr->block_size = 0;
+
+		in_lli_table_ptr++;
+		in_lli_table_ptr->physical_address = 0xFFFFFFFF;
+		in_lli_table_ptr->block_size = 0;
+
+		*lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+		*num_entries_ptr = 2;
+		*table_data_size_ptr = 0;
+
+		goto end_function;
+	}
+
+	/* check if the pages are in Kernel Virtual Address layout */
+	if (isKernelVirtualAddress == true)
+		/* lock the pages of the kernel buffer and translate them to pages */
+		result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
+	else
+		/* lock the pages of the user buffer and translate them to pages */
+		result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array);
+
+	if (result)
+		return result;
+
+	edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages);
+
+	current_entry = 0;
+	info_entry_ptr = 0;
+	sep_lli_entries = sep->in_num_pages;
+
+	/* initiate to point after the message area */
+	lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+
+	/* loop till all the entries in in array are not processed */
+	while (current_entry < sep_lli_entries) {
+		/* set the new input and output tables */
+		in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
+
+		lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+		/* calculate the maximum size of data for input table */
+		table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry));
+
+		/* now calculate the table size so that it will be module block size */
+		table_data_size = (table_data_size / block_size) * block_size;
+
+		edbg("SEP Driver:output table_data_size is %lu\n", table_data_size);
+
+		/* construct input lli table */
+		sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, &current_entry, &num_entries_in_table, table_data_size);
+
+		if (info_entry_ptr == 0) {
+			/* set the output parameters to physical addresses */
+			*lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+			*num_entries_ptr = num_entries_in_table;
+			*table_data_size_ptr = table_data_size;
+
+			edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr);
+		} else {
+			/* update the info entry of the previous in table */
+			info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+			info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
+		}
+
+		/* save the pointer to the info entry of the current tables */
+		info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
+	}
+
+	/* print input tables */
+	sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
+				   sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr);
+
+	/* the array of the pages */
+	kfree(lli_array_ptr);
+end_function:
+	dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n");
+	return 0;
+
+}
+
+/*
+ This function creates the input and output dma tables for
+ symmetric operations (AES/DES) according to the block size from LLI arays
+*/
+static int sep_construct_dma_tables_from_lli(struct sep_device *sep,
+				      struct sep_lli_entry_t *lli_in_array,
+				      unsigned long sep_in_lli_entries,
+				      struct sep_lli_entry_t *lli_out_array,
+				      unsigned long sep_out_lli_entries,
+				      unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr)
+{
+	/* points to the area where next lli table can be allocated: keep void *
+	   as there is pointer scaling to fix otherwise */
+	void *lli_table_alloc_addr;
+	/* input lli table */
+	struct sep_lli_entry_t *in_lli_table_ptr;
+	/* output lli table */
+	struct sep_lli_entry_t *out_lli_table_ptr;
+	/* pointer to the info entry of the table - the last entry */
+	struct sep_lli_entry_t *info_in_entry_ptr;
+	/* pointer to the info entry of the table - the last entry */
+	struct sep_lli_entry_t *info_out_entry_ptr;
+	/* points to the first entry to be processed in the lli_in_array */
+	unsigned long current_in_entry;
+	/* points to the first entry to be processed in the lli_out_array */
+	unsigned long current_out_entry;
+	/* max size of the input table */
+	unsigned long in_table_data_size;
+	/* max size of the output table */
+	unsigned long out_table_data_size;
+	/* flag te signifies if this is the first tables build from the arrays */
+	unsigned long first_table_flag;
+	/* the data size that should be in table */
+	unsigned long table_data_size;
+	/* number of etnries in the input table */
+	unsigned long num_entries_in_table;
+	/* number of etnries in the output table */
+	unsigned long num_entries_out_table;
+
+	dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n");
+
+	/* initiate to pint after the message area */
+	lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+
+	current_in_entry = 0;
+	current_out_entry = 0;
+	first_table_flag = 1;
+	info_in_entry_ptr = 0;
+	info_out_entry_ptr = 0;
+
+	/* loop till all the entries in in array are not processed */
+	while (current_in_entry < sep_in_lli_entries) {
+		/* set the new input and output tables */
+		in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
+
+		lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+		/* set the first output tables */
+		out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr;
+
+		lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;
+
+		/* calculate the maximum size of data for input table */
+		in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry));
+
+		/* calculate the maximum size of data for output table */
+		out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry));
+
+		edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size);
+		edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size);
+
+		/* check where the data is smallest */
+		table_data_size = in_table_data_size;
+		if (table_data_size > out_table_data_size)
+			table_data_size = out_table_data_size;
+
+		/* now calculate the table size so that it will be module block size */
+		table_data_size = (table_data_size / block_size) * block_size;
+
+		dbg("SEP Driver:table_data_size is %lu\n", table_data_size);
+
+		/* construct input lli table */
+		sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, &current_in_entry, &num_entries_in_table, table_data_size);
+
+		/* construct output lli table */
+		sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, &current_out_entry, &num_entries_out_table, table_data_size);
+
+		/* if info entry is null - this is the first table built */
+		if (info_in_entry_ptr == 0) {
+			/* set the output parameters to physical addresses */
+			*lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+			*in_num_entries_ptr = num_entries_in_table;
+			*lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
+			*out_num_entries_ptr = num_entries_out_table;
+			*table_data_size_ptr = table_data_size;
+
+			edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr);
+			edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr);
+		} else {
+			/* update the info entry of the previous in table */
+			info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr);
+			info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size);
+
+			/* update the info entry of the previous in table */
+			info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr);
+			info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size);
+		}
+
+		/* save the pointer to the info entry of the current tables */
+		info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
+		info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1;
+
+		edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table);
+		edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr);
+		edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr);
+	}
+
+	/* print input tables */
+	sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
+				   sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr);
+	/* print output tables */
+	sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *)
+				   sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr);
+	dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n");
+	return 0;
+}
+
+
+/*
+  This function builds input and output DMA tables for synhronic
+  symmetric operations (AES, DES). It also checks that each table
+  is of the modular block size
+*/
+static int sep_prepare_input_output_dma_table(struct sep_device *sep,
+				       unsigned long app_virt_in_addr,
+				       unsigned long app_virt_out_addr,
+				       unsigned long data_size,
+				       unsigned long block_size,
+				       unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress)
+{
+	/* array of pointers of page */
+	struct sep_lli_entry_t *lli_in_array;
+	/* array of pointers of page */
+	struct sep_lli_entry_t *lli_out_array;
+	int result = 0;
+
+	dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n");
+
+	/* initialize the pages pointers */
+	sep->in_page_array = 0;
+	sep->out_page_array = 0;
+
+	/* check if the pages are in Kernel Virtual Address layout */
+	if (isKernelVirtualAddress == true) {
+		/* lock the pages of the kernel buffer and translate them to pages */
+		result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
+		if (result) {
+			edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n");
+			goto end_function;
+		}
+	} else {
+		/* lock the pages of the user buffer and translate them to pages */
+		result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array);
+		if (result) {
+			edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n");
+			goto end_function;
+		}
+	}
+
+	if (isKernelVirtualAddress == true) {
+		result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
+		if (result) {
+			edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n");
+			goto end_function_with_error1;
+		}
+	} else {
+		result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array);
+		if (result) {
+			edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n");
+			goto end_function_with_error1;
+		}
+	}
+	edbg("sep->in_num_pages is %lu\n", sep->in_num_pages);
+	edbg("sep->out_num_pages is %lu\n", sep->out_num_pages);
+	edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);
+
+
+	/* call the fucntion that creates table from the lli arrays */
+	result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);
+	if (result) {
+		edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n");
+		goto end_function_with_error2;
+	}
+
+	/* fall through - free the lli entry arrays */
+	dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr);
+	dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr);
+	dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr);
+end_function_with_error2:
+	kfree(lli_out_array);
+end_function_with_error1:
+	kfree(lli_in_array);
+end_function:
+	dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result);
+	return result;
+
+}
+
+/*
+  this function handles tha request for creation of the DMA table
+  for the synchronic symmetric operations (AES,DES)
+*/
+static int sep_create_sync_dma_tables_handler(struct sep_device *sep,
+						unsigned long arg)
+{
+	int error;
+	/* command arguments */
+	struct sep_driver_build_sync_table_t command_args;
+
+	dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n");
+
+	error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t));
+	if (error)
+		goto end_function;
+
+	edbg("app_in_address is %08lx\n", command_args.app_in_address);
+	edbg("app_out_address is %08lx\n", command_args.app_out_address);
+	edbg("data_size is %lu\n", command_args.data_in_size);
+	edbg("block_size is %lu\n", command_args.block_size);
+
+	/* check if we need to build only input table or input/output */
+	if (command_args.app_out_address)
+		/* prepare input and output tables */
+		error = sep_prepare_input_output_dma_table(sep,
+							   command_args.app_in_address,
+							   command_args.app_out_address,
+							   command_args.data_in_size,
+							   command_args.block_size,
+							   &command_args.in_table_address,
+							   &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
+	else
+		/* prepare input tables */
+		error = sep_prepare_input_dma_table(sep,
+						    command_args.app_in_address,
+						    command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress);
+
+	if (error)
+		goto end_function;
+	/* copy to user */
+	if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t)))
+		error = -EFAULT;
+end_function:
+	dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n");
+	return error;
+}
+
+/*
+  this function handles the request for freeing dma table for synhronic actions
+*/
+static int sep_free_dma_table_data_handler(struct sep_device *sep)
+{
+	dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n");
+
+	/* free input pages array */
+	sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0);
+
+	/* free output pages array if needed */
+	if (sep->out_page_array)
+		sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1);
+
+	/* reset all the values */
+	sep->in_page_array = 0;
+	sep->out_page_array = 0;
+	sep->in_num_pages = 0;
+	sep->out_num_pages = 0;
+	dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n");
+	return 0;
+}
+
+/*
+  this function find a space for the new flow dma table
+*/
+static int sep_find_free_flow_dma_table_space(struct sep_device *sep,
+					unsigned long **table_address_ptr)
+{
+	int error = 0;
+	/* pointer to the id field of the flow dma table */
+	unsigned long *start_table_ptr;
+	/* Do not make start_addr unsigned long * unless fixing the offset
+	   computations ! */
+	void *flow_dma_area_start_addr;
+	unsigned long *flow_dma_area_end_addr;
+	/* maximum table size in words */
+	unsigned long table_size_in_words;
+
+	/* find the start address of the flow DMA table area */
+	flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES;
+
+	/* set end address of the flow table area */
+	flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES;
+
+	/* set table size in words */
+	table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2;
+
+	/* set the pointer to the start address of DMA area */
+	start_table_ptr = flow_dma_area_start_addr;
+
+	/* find the space for the next table */
+	while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr)
+		start_table_ptr += table_size_in_words;
+
+	/* check if we reached the end of floa tables area */
+	if (start_table_ptr >= flow_dma_area_end_addr)
+		error = -1;
+	else
+		*table_address_ptr = start_table_ptr;
+
+	return error;
+}
+
+/*
+  This function creates one DMA table for flow and returns its data,
+  and pointer to its info entry
+*/
+static int sep_prepare_one_flow_dma_table(struct sep_device *sep,
+					unsigned long virt_buff_addr,
+					unsigned long virt_buff_size,
+					struct sep_lli_entry_t *table_data,
+					struct sep_lli_entry_t **info_entry_ptr,
+					struct sep_flow_context_t *flow_data_ptr,
+					bool isKernelVirtualAddress)
+{
+	int error;
+	/* the range in pages */
+	unsigned long lli_array_size;
+	struct sep_lli_entry_t *lli_array;
+	struct sep_lli_entry_t *flow_dma_table_entry_ptr;
+	unsigned long *start_dma_table_ptr;
+	/* total table data counter */
+	unsigned long dma_table_data_count;
+	/* pointer that will keep the pointer to the pages of the virtual buffer */
+	struct page **page_array_ptr;
+	unsigned long entry_count;
+
+	/* find the space for the new table */
+	error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr);
+	if (error)
+		goto end_function;
+
+	/* check if the pages are in Kernel Virtual Address layout */
+	if (isKernelVirtualAddress == true)
+		/* lock kernel buffer in the memory */
+		error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
+	else
+		/* lock user buffer in the memory */
+		error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr);
+
+	if (error)
+		goto end_function;
+
+	/* set the pointer to page array at the beginning of table - this table is
+	   now considered taken */
+	*start_dma_table_ptr = lli_array_size;
+
+	/* point to the place of the pages pointers of the table */
+	start_dma_table_ptr++;
+
+	/* set the pages pointer */
+	*start_dma_table_ptr = (unsigned long) page_array_ptr;
+
+	/* set the pointer to the first entry */
+	flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr);
+
+	/* now create the entries for table */
+	for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) {
+		flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address;
+
+		flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size;
+
+		/* set the total data of a table */
+		dma_table_data_count += lli_array[entry_count].block_size;
+
+		flow_dma_table_entry_ptr++;
+	}
+
+	/* set the physical address */
+	table_data->physical_address = virt_to_phys(start_dma_table_ptr);
+
+	/* set the num_entries and total data size */
+	table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count);
+
+	/* set the info entry */
+	flow_dma_table_entry_ptr->physical_address = 0xffffffff;
+	flow_dma_table_entry_ptr->block_size = 0;
+
+	/* set the pointer to info entry */
+	*info_entry_ptr = flow_dma_table_entry_ptr;
+
+	/* the array of the lli entries */
+	kfree(lli_array);
+end_function:
+	return error;
+}
+
+
+
+/*
+  This function creates a list of tables for flow and returns the data for
+	the first and last tables of the list
+*/
+static int sep_prepare_flow_dma_tables(struct sep_device *sep,
+					unsigned long num_virtual_buffers,
+				        unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress)
+{
+	int error;
+	unsigned long virt_buff_addr;
+	unsigned long virt_buff_size;
+	struct sep_lli_entry_t table_data;
+	struct sep_lli_entry_t *info_entry_ptr;
+	struct sep_lli_entry_t *prev_info_entry_ptr;
+	unsigned long i;
+
+	/* init vars */
+	error = 0;
+	prev_info_entry_ptr = 0;
+
+	/* init the first table to default */
+	table_data.physical_address = 0xffffffff;
+	first_table_data_ptr->physical_address = 0xffffffff;
+	table_data.block_size = 0;
+
+	for (i = 0; i < num_virtual_buffers; i++) {
+		/* get the virtual buffer address */
+		error = get_user(virt_buff_addr, &first_buff_addr);
+		if (error)
+			goto end_function;
+
+		/* get the virtual buffer size */
+		first_buff_addr++;
+		error = get_user(virt_buff_size, &first_buff_addr);
+		if (error)
+			goto end_function;
+
+		/* advance the address to point to the next pair of address|size */
+		first_buff_addr++;
+
+		/* now prepare the one flow LLI table from the data */
+		error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress);
+		if (error)
+			goto end_function;
+
+		if (i == 0) {
+			/* if this is the first table - save it to return to the user
+			   application */
+			*first_table_data_ptr = table_data;
+
+			/* set the pointer to info entry */
+			prev_info_entry_ptr = info_entry_ptr;
+		} else {
+			/* not first table - the previous table info entry should
+			   be updated */
+			prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size);
+
+			/* set the pointer to info entry */
+			prev_info_entry_ptr = info_entry_ptr;
+		}
+	}
+
+	/* set the last table data */
+	*last_table_data_ptr = table_data;
+end_function:
+	return error;
+}
+
+/*
+  this function goes over all the flow tables connected to the given
+	table and deallocate them
+*/
+static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr)
+{
+	/* id pointer */
+	unsigned long *table_ptr;
+	/* end address of the flow dma area */
+	unsigned long num_entries;
+	unsigned long num_pages;
+	struct page **pages_ptr;
+	/* maximum table size in words */
+	struct sep_lli_entry_t *info_entry_ptr;
+
+	/* set the pointer to the first table */
+	table_ptr = (unsigned long *) first_table_ptr->physical_address;
+
+	/* set the num of entries */
+	num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS)
+	    & SEP_NUM_ENTRIES_MASK;
+
+	/* go over all the connected tables */
+	while (*table_ptr != 0xffffffff) {
+		/* get number of pages */
+		num_pages = *(table_ptr - 2);
+
+		/* get the pointer to the pages */
+		pages_ptr = (struct page **) (*(table_ptr - 1));
+
+		/* free the pages */
+		sep_free_dma_pages(pages_ptr, num_pages, 1);
+
+		/* goto to the info entry */
+		info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1);
+
+		table_ptr = (unsigned long *) info_entry_ptr->physical_address;
+		num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
+	}
+
+	return;
+}
+
+/**
+ *	sep_find_flow_context	-	find a flow
+ *	@sep: the SEP we are working with
+ *	@flow_id: flow identifier
+ *
+ *	Returns a pointer the matching flow, or NULL if the flow does not
+ *	exist.
+ */
+
+static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep,
+				unsigned long flow_id)
+{
+	int count;
+	/*
+	 *  always search for flow with id default first - in case we
+	 *  already started working on the flow there can be no situation
+	 *  when 2 flows are with default flag
+	 */
+	for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) {
+		if (sep->flows[count].flow_id == flow_id)
+			return &sep->flows[count];
+	}
+	return NULL;
+}
+
+
+/*
+  this function handles the request to create the DMA tables for flow
+*/
+static int sep_create_flow_dma_tables_handler(struct sep_device *sep,
+							unsigned long arg)
+{
+	int error;
+	struct sep_driver_build_flow_table_t command_args;
+	/* first table - output */
+	struct sep_lli_entry_t first_table_data;
+	/* dma table data */
+	struct sep_lli_entry_t last_table_data;
+	/* pointer to the info entry of the previuos DMA table */
+	struct sep_lli_entry_t *prev_info_entry_ptr;
+	/* pointer to the flow data strucutre */
+	struct sep_flow_context_t *flow_context_ptr;
+
+	dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n");
+
+	/* init variables */
+	prev_info_entry_ptr = 0;
+	first_table_data.physical_address = 0xffffffff;
+
+	/* find the free structure for flow data */
+	flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID);
+	if (flow_context_ptr == NULL)
+		goto end_function;
+
+	error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t));
+	if (error)
+		goto end_function;
+
+	/* create flow tables */
+	error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
+	if (error)
+		goto end_function_with_error;
+
+	/* check if flow is static */
+	if (!command_args.flow_type)
+		/* point the info entry of the last to the info entry of the first */
+		last_table_data = first_table_data;
+
+	/* set output params */
+	command_args.first_table_addr = first_table_data.physical_address;
+	command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
+	command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
+
+	/* send the parameters to user application */
+	error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t));
+	if (error)
+		goto end_function_with_error;
+
+	/* all the flow created  - update the flow entry with temp id */
+	flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID;
+
+	/* set the processing tables data in the context */
+	if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG)
+		flow_context_ptr->input_tables_in_process = first_table_data;
+	else
+		flow_context_ptr->output_tables_in_process = first_table_data;
+
+	goto end_function;
+
+end_function_with_error:
+	/* free the allocated tables */
+	sep_deallocated_flow_tables(&first_table_data);
+end_function:
+	dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n");
+	return error;
+}
+
+/*
+  this function handles add tables to flow
+*/
+static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg)
+{
+	int error;
+	unsigned long num_entries;
+	struct sep_driver_add_flow_table_t command_args;
+	struct sep_flow_context_t *flow_context_ptr;
+	/* first dma table data */
+	struct sep_lli_entry_t first_table_data;
+	/* last dma table data */
+	struct sep_lli_entry_t last_table_data;
+	/* pointer to the info entry of the current DMA table */
+	struct sep_lli_entry_t *info_entry_ptr;
+
+	dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n");
+
+	/* get input parameters */
+	error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t));
+	if (error)
+		goto end_function;
+
+	/* find the flow structure for the flow id */
+	flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
+	if (flow_context_ptr == NULL)
+		goto end_function;
+
+	/* prepare the flow dma tables */
+	error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress);
+	if (error)
+		goto end_function_with_error;
+
+	/* now check if there is already an existing add table for this flow */
+	if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) {
+		/* this buffer was for input buffers */
+		if (flow_context_ptr->input_tables_flag) {
+			/* add table already exists - add the new tables to the end
+			   of the previous */
+			num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
+
+			info_entry_ptr = (struct sep_lli_entry_t *)
+			    (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
+
+			/* connect to list of tables */
+			*info_entry_ptr = first_table_data;
+
+			/* set the first table data */
+			first_table_data = flow_context_ptr->first_input_table;
+		} else {
+			/* set the input flag */
+			flow_context_ptr->input_tables_flag = 1;
+
+			/* set the first table data */
+			flow_context_ptr->first_input_table = first_table_data;
+		}
+		/* set the last table data */
+		flow_context_ptr->last_input_table = last_table_data;
+	} else {		/* this is output tables */
+
+		/* this buffer was for input buffers */
+		if (flow_context_ptr->output_tables_flag) {
+			/* add table already exists - add the new tables to
+			   the end of the previous */
+			num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK;
+
+			info_entry_ptr = (struct sep_lli_entry_t *)
+			    (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1)));
+
+			/* connect to list of tables */
+			*info_entry_ptr = first_table_data;
+
+			/* set the first table data */
+			first_table_data = flow_context_ptr->first_output_table;
+		} else {
+			/* set the input flag */
+			flow_context_ptr->output_tables_flag = 1;
+
+			/* set the first table data */
+			flow_context_ptr->first_output_table = first_table_data;
+		}
+		/* set the last table data */
+		flow_context_ptr->last_output_table = last_table_data;
+	}
+
+	/* set output params */
+	command_args.first_table_addr = first_table_data.physical_address;
+	command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK);
+	command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK);
+
+	/* send the parameters to user application */
+	error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t));
+end_function_with_error:
+	/* free the allocated tables */
+	sep_deallocated_flow_tables(&first_table_data);
+end_function:
+	dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n");
+	return error;
+}
+
+/*
+  this function add the flow add message to the specific flow
+*/
+static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg)
+{
+	int error;
+	struct sep_driver_add_message_t command_args;
+	struct sep_flow_context_t *flow_context_ptr;
+
+	dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n");
+
+	error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t));
+	if (error)
+		goto end_function;
+
+	/* check input */
+	if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) {
+		error = -ENOMEM;
+		goto end_function;
+	}
+
+	/* find the flow context */
+	flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id);
+	if (flow_context_ptr == NULL)
+		goto end_function;
+
+	/* copy the message into context */
+	flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes;
+	error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes);
+end_function:
+	dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n");
+	return error;
+}
+
+
+/*
+  this function returns the bus and virtual addresses of the static pool
+*/
+static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg)
+{
+	int error;
+	struct sep_driver_static_pool_addr_t command_args;
+
+	dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n");
+
+	/*prepare the output parameters in the struct */
+	command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
+	command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;
+
+	edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address);
+
+	/* send the parameters to user application */
+	error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t));
+	dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n");
+	return error;
+}
+
+/*
+  this address gets the offset of the physical address from the start
+  of the mapped area
+*/
+static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg)
+{
+	int error;
+	struct sep_driver_get_mapped_offset_t command_args;
+
+	dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n");
+
+	error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t));
+	if (error)
+		goto end_function;
+
+	if (command_args.physical_address < sep->shared_bus) {
+		error = -EINVAL;
+		goto end_function;
+	}
+
+	/*prepare the output parameters in the struct */
+	command_args.offset = command_args.physical_address - sep->shared_bus;
+
+	edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset);
+
+	/* send the parameters to user application */
+	error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t));
+end_function:
+	dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n");
+	return error;
+}
+
+
+/*
+  ?
+*/
+static int sep_start_handler(struct sep_device *sep)
+{
+	unsigned long reg_val;
+	unsigned long error = 0;
+
+	dbg("SEP Driver:--------> sep_start_handler start\n");
+
+	/* wait in polling for message from SEP */
+	do
+		reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+	while (!reg_val);
+
+	/* check the value */
+	if (reg_val == 0x1)
+		/* fatal error - read error status from GPRO */
+		error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+	dbg("SEP Driver:<-------- sep_start_handler end\n");
+	return error;
+}
+
+/*
+  this function handles the request for SEP initialization
+*/
+static int sep_init_handler(struct sep_device *sep, unsigned long arg)
+{
+	unsigned long message_word;
+	unsigned long *message_ptr;
+	struct sep_driver_init_t command_args;
+	unsigned long counter;
+	unsigned long error;
+	unsigned long reg_val;
+
+	dbg("SEP Driver:--------> sep_init_handler start\n");
+	error = 0;
+
+	error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t));
+
+	dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user \n");
+
+	if (error)
+		goto end_function;
+
+	/* PATCH - configure the DMA to single -burst instead of multi-burst */
+	/*sep_configure_dma_burst(); */
+
+	dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n");
+
+	message_ptr = (unsigned long *) command_args.message_addr;
+
+	/* set the base address of the SRAM  */
+	sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS);
+
+	for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) {
+		get_user(message_word, message_ptr);
+		/* write data to SRAM */
+		sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word);
+		edbg("SEP Driver:message_word is %lu\n", message_word);
+		/* wait for write complete */
+		sep_wait_sram_write(sep);
+	}
+	dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n");
+	/* signal SEP */
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1);
+
+	do
+		reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
+	while (!(reg_val & 0xFFFFFFFD));
+
+	dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n");
+
+	/* check the value */
+	if (reg_val == 0x1) {
+		edbg("SEP Driver:init failed\n");
+
+		error = sep_read_reg(sep, 0x8060);
+		edbg("SEP Driver:sw monitor is %lu\n", error);
+
+		/* fatal error - read erro status from GPRO */
+		error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR);
+		edbg("SEP Driver:error is %lu\n", error);
+	}
+end_function:
+	dbg("SEP Driver:<-------- sep_init_handler end\n");
+	return error;
+
+}
+
+/*
+  this function handles the request cache and resident reallocation
+*/
+static int sep_realloc_cache_resident_handler(struct sep_device *sep,
+						unsigned long arg)
+{
+	struct sep_driver_realloc_cache_resident_t command_args;
+	int error;
+
+	/* copy cache and resident to the their intended locations */
+	error = sep_load_firmware(sep);
+	if (error)
+		return error;
+
+	command_args.new_base_addr = sep->shared_bus;
+
+	/* find the new base address according to the lowest address between
+	   cache, resident and shared area */
+	if (sep->resident_bus < command_args.new_base_addr)
+		command_args.new_base_addr = sep->resident_bus;
+	if (sep->rar_bus < command_args.new_base_addr)
+		command_args.new_base_addr = sep->rar_bus;
+
+	/* set the return parameters */
+	command_args.new_cache_addr = sep->rar_bus;
+	command_args.new_resident_addr = sep->resident_bus;
+
+	/* set the new shared area */
+	command_args.new_shared_area_addr = sep->shared_bus;
+
+	edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr);
+	edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr);
+	edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr);
+	edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr);
+
+	/* return to user */
+	if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)))
+		return -EFAULT;
+	return 0;
+}
+
+/**
+ *	sep_get_time_handler	-	time request from user space
+ *	@sep: sep we are to set the time for
+ *	@arg: pointer to user space arg buffer
+ *
+ *	This function reports back the time and the address in the SEP
+ *	shared buffer at which it has been placed. (Do we really need this!!!)
+ */
+
+static int sep_get_time_handler(struct sep_device *sep, unsigned long arg)
+{
+	struct sep_driver_get_time_t command_args;
+
+	mutex_lock(&sep_mutex);
+	command_args.time_value = sep_set_time(sep);
+	command_args.time_physical_address = (unsigned long)sep_time_address(sep);
+	mutex_unlock(&sep_mutex);
+	if (copy_to_user((void __user *)arg,
+			&command_args, sizeof(struct sep_driver_get_time_t)))
+			return -EFAULT;
+	return 0;
+
+}
+
+/*
+  This API handles the end transaction request
+*/
+static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg)
+{
+	dbg("SEP Driver:--------> sep_end_transaction_handler start\n");
+
+#if 0				/*!SEP_DRIVER_POLLING_MODE */
+	/* close IMR */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF);
+
+	/* release IRQ line */
+	free_irq(SEP_DIRVER_IRQ_NUM, sep);
+
+	/* lock the sep mutex */
+	mutex_unlock(&sep_mutex);
+#endif
+
+	dbg("SEP Driver:<-------- sep_end_transaction_handler end\n");
+
+	return 0;
+}
+
+
+/**
+ *	sep_set_flow_id_handler	-	handle flow setting
+ *	@sep: the SEP we are configuring
+ *	@flow_id: the flow we are setting
+ *
+ * This function handler the set flow id command
+ */
+static int sep_set_flow_id_handler(struct sep_device *sep,
+						unsigned long flow_id)
+{
+	int error = 0;
+	struct sep_flow_context_t *flow_data_ptr;
+
+	/* find the flow data structure that was just used for creating new flow
+	   - its id should be default */
+
+	mutex_lock(&sep_mutex);
+	flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID);
+	if (flow_data_ptr)
+		flow_data_ptr->flow_id = flow_id;	/* set flow id */
+	else
+		error = -EINVAL;
+	mutex_unlock(&sep_mutex);
+	return error;
+}
+
+static int sep_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int error = 0;
+	struct sep_device *sep = filp->private_data;
+
+	dbg("------------>SEP Driver: ioctl start\n");
+
+	edbg("SEP Driver: cmd is %x\n", cmd);
+
+	switch (cmd) {
+	case SEP_IOCSENDSEPCOMMAND:
+		/* send command to SEP */
+		sep_send_command_handler(sep);
+		edbg("SEP Driver: after sep_send_command_handler\n");
+		break;
+	case SEP_IOCSENDSEPRPLYCOMMAND:
+		/* send reply command to SEP */
+		sep_send_reply_command_handler(sep);
+		break;
+	case SEP_IOCALLOCDATAPOLL:
+		/* allocate data pool */
+		error = sep_allocate_data_pool_memory_handler(sep, arg);
+		break;
+	case SEP_IOCWRITEDATAPOLL:
+		/* write data into memory pool */
+		error = sep_write_into_data_pool_handler(sep, arg);
+		break;
+	case SEP_IOCREADDATAPOLL:
+		/* read data from data pool into application memory */
+		error = sep_read_from_data_pool_handler(sep, arg);
+		break;
+	case SEP_IOCCREATESYMDMATABLE:
+		/* create dma table for synhronic operation */
+		error = sep_create_sync_dma_tables_handler(sep, arg);
+		break;
+	case SEP_IOCCREATEFLOWDMATABLE:
+		/* create flow dma tables */
+		error = sep_create_flow_dma_tables_handler(sep, arg);
+		break;
+	case SEP_IOCFREEDMATABLEDATA:
+		/* free the pages */
+		error = sep_free_dma_table_data_handler(sep);
+		break;
+	case SEP_IOCSETFLOWID:
+		/* set flow id */
+		error = sep_set_flow_id_handler(sep, (unsigned long)arg);
+		break;
+	case SEP_IOCADDFLOWTABLE:
+		/* add tables to the dynamic flow */
+		error = sep_add_flow_tables_handler(sep, arg);
+		break;
+	case SEP_IOCADDFLOWMESSAGE:
+		/* add message of add tables to flow */
+		error = sep_add_flow_tables_message_handler(sep, arg);
+		break;
+	case SEP_IOCSEPSTART:
+		/* start command to sep */
+		error = sep_start_handler(sep);
+		break;
+	case SEP_IOCSEPINIT:
+		/* init command to sep */
+		error = sep_init_handler(sep, arg);
+		break;
+	case SEP_IOCGETSTATICPOOLADDR:
+		/* get the physical and virtual addresses of the static pool */
+		error = sep_get_static_pool_addr_handler(sep, arg);
+		break;
+	case SEP_IOCENDTRANSACTION:
+		error = sep_end_transaction_handler(sep, arg);
+		break;
+	case SEP_IOCREALLOCCACHERES:
+		error = sep_realloc_cache_resident_handler(sep, arg);
+		break;
+	case SEP_IOCGETMAPPEDADDROFFSET:
+		error = sep_get_physical_mapped_offset_handler(sep, arg);
+		break;
+	case SEP_IOCGETIME:
+		error = sep_get_time_handler(sep, arg);
+		break;
+	default:
+		error = -ENOTTY;
+		break;
+	}
+	dbg("SEP Driver:<-------- ioctl end\n");
+	return error;
+}
+
+
+
+#if !SEP_DRIVER_POLLING_MODE
+
+/* handler for flow done interrupt */
+
+static void sep_flow_done_handler(struct work_struct *work)
+{
+	struct sep_flow_context_t *flow_data_ptr;
+
+	/* obtain the mutex */
+	mutex_lock(&sep_mutex);
+
+	/* get the pointer to context */
+	flow_data_ptr = (struct sep_flow_context_t *) work;
+
+	/* free all the current input tables in sep */
+	sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process);
+
+	/* free all the current tables output tables in SEP (if needed) */
+	if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff)
+		sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process);
+
+	/* check if we have additional tables to be sent to SEP only input
+	   flag may be checked */
+	if (flow_data_ptr->input_tables_flag) {
+		/* copy the message to the shared RAM and signal SEP */
+		memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes);
+
+		sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2);
+	}
+	mutex_unlock(&sep_mutex);
+}
+/*
+  interrupt handler function
+*/
+static irqreturn_t sep_inthandler(int irq, void *dev_id)
+{
+	irqreturn_t int_error;
+	unsigned long reg_val;
+	unsigned long flow_id;
+	struct sep_flow_context_t *flow_context_ptr;
+	struct sep_device *sep = dev_id;
+
+	int_error = IRQ_HANDLED;
+
+	/* read the IRR register to check if this is SEP interrupt */
+	reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
+	edbg("SEP Interrupt - reg is %08lx\n", reg_val);
+
+	/* check if this is the flow interrupt */
+	if (0 /*reg_val & (0x1 << 11) */ ) {
+		/* read GPRO to find out the which flow is done */
+		flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);
+
+		/* find the contex of the flow */
+		flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28);
+		if (flow_context_ptr == NULL)
+			goto end_function_with_error;
+
+		/* queue the work */
+		INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler);
+		queue_work(sep->flow_wq, &flow_context_ptr->flow_wq);
+
+	} else {
+		/* check if this is reply interrupt from SEP */
+		if (reg_val & (0x1 << 13)) {
+			/* update the counter of reply messages */
+			sep->reply_ct++;
+			/* wake up the waiting process */
+			wake_up(&sep_event);
+		} else {
+			int_error = IRQ_NONE;
+			goto end_function;
+		}
+	}
+end_function_with_error:
+	/* clear the interrupt */
+	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);
+end_function:
+	return int_error;
+}
+
+#endif
+
+
+
+#if 0
+
+static void sep_wait_busy(struct sep_device *sep)
+{
+	u32 reg;
+
+	do {
+		reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR);
+	} while (reg);
+}
+
+/*
+  PATCH for configuring the DMA to single burst instead of multi-burst
+*/
+static void sep_configure_dma_burst(struct sep_device *sep)
+{
+#define 	 HW_AHB_RD_WR_BURSTS_REG_ADDR 		 0x0E10UL
+
+	dbg("SEP Driver:<-------- sep_configure_dma_burst start \n");
+
+	/* request access to registers from SEP */
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
+
+	dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg)  \n");
+
+	sep_wait_busy(sep);
+
+	dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop)  \n");
+
+	/* set the DMA burst register to single burst */
+	sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL);
+
+	/* release the sep busy */
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL);
+	sep_wait_busy(sep);
+
+	dbg("SEP Driver:<-------- sep_configure_dma_burst done  \n");
+
+}
+
+#endif
+
+/*
+  Function that is activaed on the succesful probe of the SEP device
+*/
+static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	int error = 0;
+	struct sep_device *sep;
+	int counter;
+	int size;		/* size of memory for allocation */
+
+	edbg("Sep pci probe starting\n");
+	if (sep_dev != NULL) {
+		dev_warn(&pdev->dev, "only one SEP supported.\n");
+		return -EBUSY;
+	}
+
+	/* enable the device */
+	error = pci_enable_device(pdev);
+	if (error) {
+		edbg("error enabling pci device\n");
+		goto end_function;
+	}
+
+	/* set the pci dev pointer */
+	sep_dev = &sep_instance;
+	sep = &sep_instance;
+
+	edbg("sep->shared_addr = %p\n", sep->shared_addr);
+	/* transaction counter that coordinates the transactions between SEP
+	and HOST */
+	sep->send_ct = 0;
+	/* counter for the messages from sep */
+	sep->reply_ct = 0;
+	/* counter for the number of bytes allocated in the pool
+	for the current transaction */
+	sep->data_pool_bytes_allocated = 0;
+
+	/* calculate the total size for allocation */
+	size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
+	    SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
+
+	/* allocate the shared area */
+	if (sep_map_and_alloc_shared_area(sep, size)) {
+		error = -ENOMEM;
+		/* allocation failed */
+		goto end_function_error;
+	}
+	/* now set the memory regions */
+#if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1)
+	/* Note: this test section will need moving before it could ever
+	   work as the registers are not yet mapped ! */
+	/* send the new SHARED MESSAGE AREA to the SEP */
+	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
+
+	/* poll for SEP response */
+	retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
+	while (retval != 0xffffffff && retval != sep->shared_bus)
+		retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);
+
+	/* check the return value (register) */
+	if (retval != sep->shared_bus) {
+		error = -ENOMEM;
+		goto end_function_deallocate_sep_shared_area;
+	}
+#endif
+	/* init the flow contextes */
+	for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++)
+		sep->flows[counter].flow_id = SEP_FREE_FLOW_ID;
+
+	sep->flow_wq = create_singlethread_workqueue("sepflowwq");
+	if (sep->flow_wq == NULL) {
+		error = -ENOMEM;
+		edbg("sep_driver:flow queue creation failed\n");
+		goto end_function_deallocate_sep_shared_area;
+	}
+	edbg("SEP Driver: create flow workqueue \n");
+	sep->pdev = pci_dev_get(pdev);
+
+	sep->reg_addr = pci_ioremap_bar(pdev, 0);
+	if (!sep->reg_addr) {
+		edbg("sep: ioremap of registers failed.\n");
+		goto end_function_deallocate_sep_shared_area;
+	}
+	edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr);
+
+	/* load the rom code */
+	sep_load_rom_code(sep);
+
+	/* set up system base address and shared memory location */
+	sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev,
+			2 * SEP_RAR_IO_MEM_REGION_SIZE,
+			&sep->rar_bus, GFP_KERNEL);
+
+	if (!sep->rar_addr) {
+		edbg("SEP Driver:can't allocate rar\n");
+		goto end_function_uniomap;
+	}
+
+
+	edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
+	edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
+
+#if !SEP_DRIVER_POLLING_MODE
+
+	edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n");
+
+	/* clear ICR register */
+	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);
+
+	/* set the IMR register - open only GPR 2 */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
+
+	edbg("SEP Driver: about to call request_irq\n");
+	/* get the interrupt line */
+	error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep);
+	if (error)
+		goto end_function_free_res;
+	return 0;
+	edbg("SEP Driver: about to write IMR REG_ADDR");
+
+	/* set the IMR register - open only GPR 2 */
+	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
+
+end_function_free_res:
+	dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE,
+			sep->rar_addr, sep->rar_bus);
+#endif				/* SEP_DRIVER_POLLING_MODE */
+end_function_uniomap:
+	iounmap(sep->reg_addr);
+end_function_deallocate_sep_shared_area:
+	/* de-allocate shared area */
+	sep_unmap_and_free_shared_area(sep, size);
+end_function_error:
+	sep_dev = NULL;
+end_function:
+	return error;
+}
+
+static struct pci_device_id sep_pci_id_tbl[] = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)},
+	{0}
+};
+
+MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);
+
+/* field for registering driver to PCI device */
+static struct pci_driver sep_pci_driver = {
+	.name = "sep_sec_driver",
+	.id_table = sep_pci_id_tbl,
+	.probe = sep_probe
+	/* FIXME: remove handler */
+};
+
+/* major and minor device numbers */
+static dev_t sep_devno;
+
+/* the files operations structure of the driver */
+static struct file_operations sep_file_operations = {
+	.owner = THIS_MODULE,
+	.ioctl = sep_ioctl,
+	.poll = sep_poll,
+	.open = sep_open,
+	.release = sep_release,
+	.mmap = sep_mmap,
+};
+
+
+/* cdev struct of the driver */
+static struct cdev sep_cdev;
+
+/*
+  this function registers the driver to the file system
+*/
+static int sep_register_driver_to_fs(void)
+{
+	int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver");
+	if (ret_val) {
+		edbg("sep: major number allocation failed, retval is %d\n",
+								ret_val);
+		return ret_val;
+	}
+	/* init cdev */
+	cdev_init(&sep_cdev, &sep_file_operations);
+	sep_cdev.owner = THIS_MODULE;
+
+	/* register the driver with the kernel */
+	ret_val = cdev_add(&sep_cdev, sep_devno, 1);
+	if (ret_val) {
+		edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val);
+		/* unregister dev numbers */
+		unregister_chrdev_region(sep_devno, 1);
+	}
+	return ret_val;
+}
+
+
+/*--------------------------------------------------------------
+  init function
+----------------------------------------------------------------*/
+static int __init sep_init(void)
+{
+	int ret_val = 0;
+	dbg("SEP Driver:-------->Init start\n");
+	/* FIXME: Probe can occur before we are ready to survive a probe */
+	ret_val = pci_register_driver(&sep_pci_driver);
+	if (ret_val) {
+		edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val);
+		goto end_function_unregister_from_fs;
+	}
+	/* register driver to fs */
+	ret_val = sep_register_driver_to_fs();
+	if (ret_val)
+		goto end_function_unregister_pci;
+	goto end_function;
+end_function_unregister_pci:
+	pci_unregister_driver(&sep_pci_driver);
+end_function_unregister_from_fs:
+	/* unregister from fs */
+	cdev_del(&sep_cdev);
+	/* unregister dev numbers */
+	unregister_chrdev_region(sep_devno, 1);
+end_function:
+	dbg("SEP Driver:<-------- Init end\n");
+	return ret_val;
+}
+
+
+/*-------------------------------------------------------------
+  exit function
+--------------------------------------------------------------*/
+static void __exit sep_exit(void)
+{
+	int size;
+
+	dbg("SEP Driver:--------> Exit start\n");
+
+	/* unregister from fs */
+	cdev_del(&sep_cdev);
+	/* unregister dev numbers */
+	unregister_chrdev_region(sep_devno, 1);
+	/* calculate the total size for de-allocation */
+	size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
+	    SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;
+	/* FIXME: We need to do this in the unload for the device */
+	/* free shared area  */
+	if (sep_dev) {
+		sep_unmap_and_free_shared_area(sep_dev, size);
+		edbg("SEP Driver: free pages SEP SHARED AREA \n");
+		iounmap((void *) sep_dev->reg_addr);
+		edbg("SEP Driver: iounmap \n");
+	}
+	edbg("SEP Driver: release_mem_region \n");
+	dbg("SEP Driver:<-------- Exit end\n");
+}
+
+
+module_init(sep_init);
+module_exit(sep_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h
new file mode 100644
index 0000000..383543d
--- /dev/null
+++ b/drivers/staging/sep/sep_driver_api.h
@@ -0,0 +1,425 @@
+/*
+ *
+ *  sep_driver_api.h - Security Processor Driver api definitions
+ *
+ *  Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *  Copyright(c) 2009 Discretix. 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., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Mark Allyn		mark.a.allyn@intel.com
+ *
+ *  CHANGES:
+ *
+ *  2009.06.26	Initial publish
+ *
+ */
+
+#ifndef __SEP_DRIVER_API_H__
+#define __SEP_DRIVER_API_H__
+
+
+
+/*----------------------------------------------------------------
+  IOCTL command defines
+  -----------------------------------------------------------------*/
+
+/* magic number 1 of the sep IOCTL command */
+#define SEP_IOC_MAGIC_NUMBER                           's'
+
+/* sends interrupt to sep that message is ready */
+#define SEP_IOCSENDSEPCOMMAND                 _IO(SEP_IOC_MAGIC_NUMBER , 0)
+
+/* sends interrupt to sep that message is ready */
+#define SEP_IOCSENDSEPRPLYCOMMAND             _IO(SEP_IOC_MAGIC_NUMBER , 1)
+
+/* allocate memory in data pool */
+#define SEP_IOCALLOCDATAPOLL                  _IO(SEP_IOC_MAGIC_NUMBER , 2)
+
+/* write to pre-allocated  memory in data pool */
+#define SEP_IOCWRITEDATAPOLL                  _IO(SEP_IOC_MAGIC_NUMBER , 3)
+
+/* read from  pre-allocated  memory in data pool */
+#define SEP_IOCREADDATAPOLL                   _IO(SEP_IOC_MAGIC_NUMBER , 4)
+
+/* create sym dma lli tables */
+#define SEP_IOCCREATESYMDMATABLE              _IO(SEP_IOC_MAGIC_NUMBER , 5)
+
+/* create flow dma lli tables */
+#define SEP_IOCCREATEFLOWDMATABLE             _IO(SEP_IOC_MAGIC_NUMBER , 6)
+
+/* free dynamic data aalocated during table creation */
+#define SEP_IOCFREEDMATABLEDATA                _IO(SEP_IOC_MAGIC_NUMBER , 7)
+
+/* get the static pool area addersses (physical and virtual) */
+#define SEP_IOCGETSTATICPOOLADDR               _IO(SEP_IOC_MAGIC_NUMBER , 8)
+
+/* set flow id command */
+#define SEP_IOCSETFLOWID                       _IO(SEP_IOC_MAGIC_NUMBER , 9)
+
+/* add tables to the dynamic flow */
+#define SEP_IOCADDFLOWTABLE                    _IO(SEP_IOC_MAGIC_NUMBER , 10)
+
+/* add flow add tables message */
+#define SEP_IOCADDFLOWMESSAGE                  _IO(SEP_IOC_MAGIC_NUMBER , 11)
+
+/* start sep command */
+#define SEP_IOCSEPSTART                        _IO(SEP_IOC_MAGIC_NUMBER , 12)
+
+/* init sep command */
+#define SEP_IOCSEPINIT                         _IO(SEP_IOC_MAGIC_NUMBER , 13)
+
+/* end transaction command */
+#define SEP_IOCENDTRANSACTION                  _IO(SEP_IOC_MAGIC_NUMBER , 15)
+
+/* reallocate cache and resident */
+#define SEP_IOCREALLOCCACHERES                 _IO(SEP_IOC_MAGIC_NUMBER , 16)
+
+/* get the offset of the address starting from the beginnnig of the map area */
+#define SEP_IOCGETMAPPEDADDROFFSET             _IO(SEP_IOC_MAGIC_NUMBER , 17)
+
+/* get time address and value */
+#define SEP_IOCGETIME                          _IO(SEP_IOC_MAGIC_NUMBER , 19)
+
+/*-------------------------------------------
+    TYPEDEFS
+----------------------------------------------*/
+
+/*
+  init command struct
+*/
+struct sep_driver_init_t {
+	/* start of the 1G of the host memory address that SEP can access */
+	unsigned long message_addr;
+
+	/* start address of resident */
+	unsigned long message_size_in_words;
+
+};
+
+
+/*
+  realloc cache resident command
+*/
+struct sep_driver_realloc_cache_resident_t {
+	/* new cache address */
+	u64 new_cache_addr;
+	/* new resident address */
+	u64 new_resident_addr;
+	/* new resident address */
+	u64  new_shared_area_addr;
+	/* new base address */
+	u64 new_base_addr;
+};
+
+struct sep_driver_alloc_t {
+	/* virtual address of allocated space */
+	unsigned long offset;
+
+	/* physical address of allocated space */
+	unsigned long phys_address;
+
+	/* number of bytes to allocate */
+	unsigned long num_bytes;
+};
+
+/*
+ */
+struct sep_driver_write_t {
+	/* application space address */
+	unsigned long app_address;
+
+	/* address of the data pool */
+	unsigned long datapool_address;
+
+	/* number of bytes to write */
+	unsigned long num_bytes;
+};
+
+/*
+ */
+struct sep_driver_read_t {
+	/* application space address */
+	unsigned long app_address;
+
+	/* address of the data pool */
+	unsigned long datapool_address;
+
+	/* number of bytes to read */
+	unsigned long num_bytes;
+};
+
+/*
+*/
+struct sep_driver_build_sync_table_t {
+	/* address value of the data in */
+	unsigned long app_in_address;
+
+	/* size of data in */
+	unsigned long data_in_size;
+
+	/* address of the data out */
+	unsigned long app_out_address;
+
+	/* the size of the block of the operation - if needed,
+	   every table will be modulo this parameter */
+	unsigned long block_size;
+
+	/* the physical address of the first input DMA table */
+	unsigned long in_table_address;
+
+	/* number of entries in the first input DMA table */
+	unsigned long in_table_num_entries;
+
+	/* the physical address of the first output DMA table */
+	unsigned long out_table_address;
+
+	/* number of entries in the first output DMA table */
+	unsigned long out_table_num_entries;
+
+	/* data in the first input table */
+	unsigned long table_data_size;
+
+	/* distinct user/kernel layout */
+	bool isKernelVirtualAddress;
+
+};
+
+/*
+*/
+struct sep_driver_build_flow_table_t {
+	/* flow type */
+	unsigned long flow_type;
+
+	/* flag for input output */
+	unsigned long input_output_flag;
+
+	/* address value of the data in */
+	unsigned long virt_buff_data_addr;
+
+	/* size of data in */
+	unsigned long num_virtual_buffers;
+
+	/* the physical address of the first input DMA table */
+	unsigned long first_table_addr;
+
+	/* number of entries in the first input DMA table */
+	unsigned long first_table_num_entries;
+
+	/* data in the first input table */
+	unsigned long first_table_data_size;
+
+	/* distinct user/kernel layout */
+	bool isKernelVirtualAddress;
+};
+
+
+struct sep_driver_add_flow_table_t {
+	/* flow id  */
+	unsigned long flow_id;
+
+	/* flag for input output */
+	unsigned long inputOutputFlag;
+
+	/* address value of the data in */
+	unsigned long virt_buff_data_addr;
+
+	/* size of data in */
+	unsigned long num_virtual_buffers;
+
+	/* address of the first table */
+	unsigned long first_table_addr;
+
+	/* number of entries in the first table */
+	unsigned long first_table_num_entries;
+
+	/* data size of the first table */
+	unsigned long first_table_data_size;
+
+	/* distinct user/kernel layout */
+	bool isKernelVirtualAddress;
+
+};
+
+/*
+  command struct for set flow id
+*/
+struct sep_driver_set_flow_id_t {
+	/* flow id to set */
+	unsigned long flow_id;
+};
+
+
+/* command struct for add tables message */
+struct sep_driver_add_message_t {
+	/* flow id to set */
+	unsigned long flow_id;
+
+	/* message size in bytes */
+	unsigned long message_size_in_bytes;
+
+	/* address of the message */
+	unsigned long message_address;
+};
+
+/* command struct for static pool addresses  */
+struct sep_driver_static_pool_addr_t {
+	/* physical address of the static pool */
+	unsigned long physical_static_address;
+
+	/* virtual address of the static pool */
+	unsigned long virtual_static_address;
+};
+
+/* command struct for getiing offset of the physical address from
+	the start of the mapped area  */
+struct sep_driver_get_mapped_offset_t {
+	/* physical address of the static pool */
+	unsigned long physical_address;
+
+	/* virtual address of the static pool */
+	unsigned long offset;
+};
+
+/* command struct for getting time value and address */
+struct sep_driver_get_time_t {
+	/* physical address of stored time */
+	unsigned long time_physical_address;
+
+	/* value of the stored time */
+	unsigned long time_value;
+};
+
+
+/*
+  structure that represent one entry in the DMA LLI table
+*/
+struct sep_lli_entry_t {
+	/* physical address */
+	unsigned long physical_address;
+
+	/* block size */
+	unsigned long block_size;
+};
+
+/*
+  structure that reperesents data needed for lli table construction
+*/
+struct sep_lli_prepare_table_data_t {
+	/* pointer to the memory where the first lli entry to be built */
+	struct sep_lli_entry_t *lli_entry_ptr;
+
+	/* pointer to the array of lli entries from which the table is to be built */
+	struct sep_lli_entry_t *lli_array_ptr;
+
+	/* number of elements in lli array */
+	int lli_array_size;
+
+	/* number of entries in the created table */
+	int num_table_entries;
+
+	/* number of array entries processed during table creation */
+	int num_array_entries_processed;
+
+	/* the totatl data size in the created table */
+	int lli_table_total_data_size;
+};
+
+/*
+  structure that represent tone table - it is not used in code, jkust
+  to show what table looks like
+*/
+struct sep_lli_table_t {
+	/* number of pages mapped in this tables. If 0 - means that the table
+	   is not defined (used as a valid flag) */
+	unsigned long num_pages;
+	/*
+	   pointer to array of page pointers that represent the mapping of the
+	   virtual buffer defined by the table to the physical memory. If this
+	   pointer is NULL, it means that the table is not defined
+	   (used as a valid flag)
+	 */
+	struct page **table_page_array_ptr;
+
+	/* maximum flow entries in table */
+	struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE];
+};
+
+
+/*
+  structure for keeping the mapping of the virtual buffer into physical pages
+*/
+struct sep_flow_buffer_data {
+	/* pointer to the array of page structs pointers to the pages of the
+	   virtual buffer */
+	struct page **page_array_ptr;
+
+	/* number of pages taken by the virtual buffer */
+	unsigned long num_pages;
+
+	/* this flag signals if this page_array is the last one among many that were
+	   sent in one setting to SEP */
+	unsigned long last_page_array_flag;
+};
+
+/*
+  struct that keeps all the data for one flow
+*/
+struct sep_flow_context_t {
+	/*
+	   work struct for handling the flow done interrupt in the workqueue
+	   this structure must be in the first place, since it will be used
+	   forcasting to the containing flow context
+	 */
+	struct work_struct flow_wq;
+
+	/* flow id */
+	unsigned long flow_id;
+
+	/* additional input tables exists */
+	unsigned long input_tables_flag;
+
+	/* additional output tables exists */
+	unsigned long output_tables_flag;
+
+	/*  data of the first input file */
+	struct sep_lli_entry_t first_input_table;
+
+	/* data of the first output table */
+	struct sep_lli_entry_t first_output_table;
+
+	/* last input table data */
+	struct sep_lli_entry_t last_input_table;
+
+	/* last output table data */
+	struct sep_lli_entry_t last_output_table;
+
+	/* first list of table */
+	struct sep_lli_entry_t input_tables_in_process;
+
+	/* output table in process (in sep) */
+	struct sep_lli_entry_t output_tables_in_process;
+
+	/* size of messages in bytes */
+	unsigned long message_size_in_bytes;
+
+	/* message */
+	unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES];
+};
+
+
+#endif
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h
new file mode 100644
index 0000000..6008fe5
--- /dev/null
+++ b/drivers/staging/sep/sep_driver_config.h
@@ -0,0 +1,225 @@
+/*
+ *
+ *  sep_driver_config.h - Security Processor Driver configuration
+ *
+ *  Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *  Copyright(c) 2009 Discretix. 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., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Mark Allyn		mark.a.allyn@intel.com
+ *
+ *  CHANGES:
+ *
+ *  2009.06.26	Initial publish
+ *
+ */
+
+#ifndef __SEP_DRIVER_CONFIG_H__
+#define __SEP_DRIVER_CONFIG_H__
+
+
+/*--------------------------------------
+  DRIVER CONFIGURATION FLAGS
+  -------------------------------------*/
+
+/* if flag is on , then the driver is running in polling and
+	not interrupt mode */
+#define SEP_DRIVER_POLLING_MODE                         1
+
+/* flag which defines if the shared area address should be
+	reconfiged (send to SEP anew) during init of the driver */
+#define SEP_DRIVER_RECONFIG_MESSAGE_AREA                0
+
+/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */
+#define SEP_DRIVER_ARM_DEBUG_MODE                       0
+
+/*-------------------------------------------
+	INTERNAL DATA CONFIGURATION
+	-------------------------------------------*/
+
+/* flag for the input array */
+#define SEP_DRIVER_IN_FLAG                              0
+
+/* flag for output array */
+#define SEP_DRIVER_OUT_FLAG                             1
+
+/* maximum number of entries in one LLI tables */
+#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP             8
+
+
+/*--------------------------------------------------------
+	SHARED AREA  memory total size is 36K
+	it is divided is following:
+
+	SHARED_MESSAGE_AREA                     8K         }
+									}
+	STATIC_POOL_AREA                        4K         } MAPPED AREA ( 24 K)
+									}
+	DATA_POOL_AREA                          12K        }
+
+	SYNCHRONIC_DMA_TABLES_AREA              5K
+
+	FLOW_DMA_TABLES_AREA                    4K
+
+	SYSTEM_MEMORY_AREA                      3k
+
+	SYSTEM_MEMORY total size is 3k
+	it is divided as following:
+
+	TIME_MEMORY_AREA                     8B
+-----------------------------------------------------------*/
+
+
+
+/*
+	the maximum length of the message - the rest of the message shared
+	area will be dedicated to the dma lli tables
+*/
+#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES                  (8 * 1024)
+
+/* the size of the message shared area in pages */
+#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES          (8 * 1024)
+
+/* the size of the data pool static area in pages */
+#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES                  (4 * 1024)
+
+/* the size of the data pool shared area size in pages */
+#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES        (12 * 1024)
+
+/* the size of the message shared area in pages */
+#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES   (1024 * 5)
+
+
+/* the size of the data pool shared area size in pages */
+#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES         (1024 * 4)
+
+/* system data (time, caller id etc') pool */
+#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES           100
+
+
+/* area size that is mapped  - we map the MESSAGE AREA, STATIC POOL and
+	DATA POOL areas. area must be module 4k */
+#define SEP_DRIVER_MMMAP_AREA_SIZE                            (1024 * 24)
+
+
+/*-----------------------------------------------
+	offsets of the areas starting from the shared area start address
+*/
+
+/* message area offset */
+#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES               0
+
+/* static pool area offset */
+#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \
+		(SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES)
+
+/* data pool area offset */
+#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \
+	(SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \
+	SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES)
+
+/* synhronic dma tables area offset */
+#define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \
+	(SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \
+	SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)
+
+/* sep driver flow dma tables area offset */
+#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \
+	(SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
+	SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES)
+
+/* system memory offset in bytes */
+#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \
+	(SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \
+	SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES)
+
+/* offset of the time area */
+#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \
+	(SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES)
+
+
+
+/* start physical address of the SEP registers memory in HOST */
+#define SEP_IO_MEM_REGION_START_ADDRESS                       0x80000000
+
+/* size of the SEP registers memory region  in HOST (for now 100 registers) */
+#define SEP_IO_MEM_REGION_SIZE                                (2 * 0x100000)
+
+/* define the number of IRQ for SEP interrupts */
+#define SEP_DIRVER_IRQ_NUM                                    1
+
+/* maximum number of add buffers */
+#define SEP_MAX_NUM_ADD_BUFFERS                               100
+
+/* number of flows */
+#define SEP_DRIVER_NUM_FLOWS                                  4
+
+/* maximum number of entries in flow table */
+#define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE              25
+
+/* offset of the num entries in the block length entry of the LLI */
+#define SEP_NUM_ENTRIES_OFFSET_IN_BITS                        24
+
+/* offset of the interrupt flag in the block length entry of the LLI */
+#define SEP_INT_FLAG_OFFSET_IN_BITS                           31
+
+/* mask for extracting data size from LLI */
+#define SEP_TABLE_DATA_SIZE_MASK                              0xFFFFFF
+
+/* mask for entries after being shifted left */
+#define SEP_NUM_ENTRIES_MASK                                  0x7F
+
+/* default flow id */
+#define SEP_FREE_FLOW_ID                                      0xFFFFFFFF
+
+/* temp flow id used during cretiong of new flow until receiving
+	real flow id from sep */
+#define SEP_TEMP_FLOW_ID                   (SEP_DRIVER_NUM_FLOWS + 1)
+
+/* maximum add buffers message length in bytes */
+#define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES                   (7 * 4)
+
+/* maximum number of concurrent virtual buffers */
+#define SEP_MAX_VIRT_BUFFERS_CONCURRENT                       100
+
+/* the token that defines the start of time address */
+#define SEP_TIME_VAL_TOKEN                                    0x12345678
+
+/* DEBUG LEVEL MASKS */
+#define SEP_DEBUG_LEVEL_BASIC       0x1
+
+#define SEP_DEBUG_LEVEL_EXTENDED    0x4
+
+
+/* Debug helpers */
+
+#define dbg(fmt, args...) \
+do {\
+	if (debug & SEP_DEBUG_LEVEL_BASIC) \
+		printk(KERN_DEBUG fmt, ##args); \
+} while(0);
+
+#define edbg(fmt, args...) \
+do { \
+	if (debug & SEP_DEBUG_LEVEL_EXTENDED) \
+		printk(KERN_DEBUG fmt, ##args); \
+} while(0);
+
+
+
+#endif
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h
new file mode 100644
index 0000000..ea6abd8
--- /dev/null
+++ b/drivers/staging/sep/sep_driver_hw_defs.h
@@ -0,0 +1,232 @@
+/*
+ *
+ *  sep_driver_hw_defs.h - Security Processor Driver hardware definitions
+ *
+ *  Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *  Copyright(c) 2009 Discretix. 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., 59
+ *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *  CONTACTS:
+ *
+ *  Mark Allyn		mark.a.allyn@intel.com
+ *
+ *  CHANGES:
+ *
+ *  2009.06.26	Initial publish
+ *
+ */
+
+#ifndef SEP_DRIVER_HW_DEFS__H
+#define SEP_DRIVER_HW_DEFS__H
+
+/*--------------------------------------------------------------------------*/
+/* Abstract: HW Registers Defines.                                          */
+/*                                                                          */
+/* Note: This file was automatically created !!!                            */
+/*       DO NOT EDIT THIS FILE !!!                                          */
+/*--------------------------------------------------------------------------*/
+
+
+/* cf registers */
+#define 	 HW_R0B_ADDR_0_REG_ADDR 		 0x0000UL
+#define 	 HW_R0B_ADDR_1_REG_ADDR 		 0x0004UL
+#define 	 HW_R0B_ADDR_2_REG_ADDR 		 0x0008UL
+#define 	 HW_R0B_ADDR_3_REG_ADDR 		 0x000cUL
+#define 	 HW_R0B_ADDR_4_REG_ADDR 		 0x0010UL
+#define 	 HW_R0B_ADDR_5_REG_ADDR 		 0x0014UL
+#define 	 HW_R0B_ADDR_6_REG_ADDR 		 0x0018UL
+#define 	 HW_R0B_ADDR_7_REG_ADDR 		 0x001cUL
+#define 	 HW_R0B_ADDR_8_REG_ADDR 		 0x0020UL
+#define 	 HW_R2B_ADDR_0_REG_ADDR 		 0x0080UL
+#define 	 HW_R2B_ADDR_1_REG_ADDR 		 0x0084UL
+#define 	 HW_R2B_ADDR_2_REG_ADDR 		 0x0088UL
+#define 	 HW_R2B_ADDR_3_REG_ADDR 		 0x008cUL
+#define 	 HW_R2B_ADDR_4_REG_ADDR 		 0x0090UL
+#define 	 HW_R2B_ADDR_5_REG_ADDR 		 0x0094UL
+#define 	 HW_R2B_ADDR_6_REG_ADDR 		 0x0098UL
+#define 	 HW_R2B_ADDR_7_REG_ADDR 		 0x009cUL
+#define 	 HW_R2B_ADDR_8_REG_ADDR 		 0x00a0UL
+#define 	 HW_R3B_REG_ADDR 		         0x00C0UL
+#define 	 HW_R4B_REG_ADDR 		         0x0100UL
+#define 	 HW_CSA_ADDR_0_REG_ADDR 		 0x0140UL
+#define 	 HW_CSA_ADDR_1_REG_ADDR 		 0x0144UL
+#define 	 HW_CSA_ADDR_2_REG_ADDR 		 0x0148UL
+#define 	 HW_CSA_ADDR_3_REG_ADDR 		 0x014cUL
+#define 	 HW_CSA_ADDR_4_REG_ADDR 		 0x0150UL
+#define 	 HW_CSA_ADDR_5_REG_ADDR 		 0x0154UL
+#define 	 HW_CSA_ADDR_6_REG_ADDR 		 0x0158UL
+#define 	 HW_CSA_ADDR_7_REG_ADDR 		 0x015cUL
+#define 	 HW_CSA_ADDR_8_REG_ADDR 		 0x0160UL
+#define 	 HW_CSA_REG_ADDR 		         0x0140UL
+#define 	 HW_SINB_REG_ADDR 		         0x0180UL
+#define 	 HW_SOUTB_REG_ADDR 		         0x0184UL
+#define 	 HW_PKI_CONTROL_REG_ADDR 		 0x01C0UL
+#define 	 HW_PKI_STATUS_REG_ADDR 		 0x01C4UL
+#define 	 HW_PKI_BUSY_REG_ADDR 		     0x01C8UL
+#define 	 HW_PKI_A_1025_REG_ADDR 		 0x01CCUL
+#define 	 HW_PKI_SDMA_CTL_REG_ADDR 		 0x01D0UL
+#define 	 HW_PKI_SDMA_OFFSET_REG_ADDR 	 0x01D4UL
+#define 	 HW_PKI_SDMA_POINTERS_REG_ADDR 	 0x01D8UL
+#define 	 HW_PKI_SDMA_DLENG_REG_ADDR 		 0x01DCUL
+#define 	 HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 	 0x01E0UL
+#define 	 HW_PKI_SDMA_RES_POINTERS_REG_ADDR 	 0x01E4UL
+#define 	 HW_PKI_CLR_REG_ADDR 		         0x01E8UL
+#define 	 HW_PKI_SDMA_BUSY_REG_ADDR 		     0x01E8UL
+#define 	 HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 	 0x01ECUL
+#define 	 HW_PKI_SDMA_MUL_BY1_REG_ADDR 		 0x01F0UL
+#define 	 HW_PKI_SDMA_RMUL_SEL_REG_ADDR 		 0x01F4UL
+#define 	 HW_DES_KEY_0_REG_ADDR 		         0x0208UL
+#define 	 HW_DES_KEY_1_REG_ADDR 		         0x020CUL
+#define 	 HW_DES_KEY_2_REG_ADDR 		         0x0210UL
+#define 	 HW_DES_KEY_3_REG_ADDR 		         0x0214UL
+#define 	 HW_DES_KEY_4_REG_ADDR 		         0x0218UL
+#define 	 HW_DES_KEY_5_REG_ADDR 		         0x021CUL
+#define 	 HW_DES_CONTROL_0_REG_ADDR 	         0x0220UL
+#define 	 HW_DES_CONTROL_1_REG_ADDR 	         0x0224UL
+#define 	 HW_DES_IV_0_REG_ADDR 		         0x0228UL
+#define 	 HW_DES_IV_1_REG_ADDR 		         0x022CUL
+#define 	 HW_AES_KEY_0_ADDR_0_REG_ADDR 		 0x0400UL
+#define 	 HW_AES_KEY_0_ADDR_1_REG_ADDR 		 0x0404UL
+#define 	 HW_AES_KEY_0_ADDR_2_REG_ADDR 		 0x0408UL
+#define 	 HW_AES_KEY_0_ADDR_3_REG_ADDR 		 0x040cUL
+#define 	 HW_AES_KEY_0_ADDR_4_REG_ADDR 		 0x0410UL
+#define 	 HW_AES_KEY_0_ADDR_5_REG_ADDR 		 0x0414UL
+#define 	 HW_AES_KEY_0_ADDR_6_REG_ADDR 		 0x0418UL
+#define 	 HW_AES_KEY_0_ADDR_7_REG_ADDR 		 0x041cUL
+#define 	 HW_AES_KEY_0_REG_ADDR 		         0x0400UL
+#define 	 HW_AES_IV_0_ADDR_0_REG_ADDR 		 0x0440UL
+#define 	 HW_AES_IV_0_ADDR_1_REG_ADDR 		 0x0444UL
+#define 	 HW_AES_IV_0_ADDR_2_REG_ADDR 		 0x0448UL
+#define 	 HW_AES_IV_0_ADDR_3_REG_ADDR 		 0x044cUL
+#define 	 HW_AES_IV_0_REG_ADDR 		         0x0440UL
+#define 	 HW_AES_CTR1_ADDR_0_REG_ADDR 		 0x0460UL
+#define 	 HW_AES_CTR1_ADDR_1_REG_ADDR 		 0x0464UL
+#define 	 HW_AES_CTR1_ADDR_2_REG_ADDR 		 0x0468UL
+#define 	 HW_AES_CTR1_ADDR_3_REG_ADDR 		 0x046cUL
+#define 	 HW_AES_CTR1_REG_ADDR 		         0x0460UL
+#define 	 HW_AES_SK_REG_ADDR 		         0x0478UL
+#define 	 HW_AES_MAC_OK_REG_ADDR 		     0x0480UL
+#define 	 HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 	 0x0490UL
+#define 	 HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 	 0x0494UL
+#define 	 HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 	 0x0498UL
+#define 	 HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 	 0x049cUL
+#define 	 HW_AES_PREV_IV_0_REG_ADDR 		     0x0490UL
+#define 	 HW_AES_CONTROL_REG_ADDR 		     0x04C0UL
+#define 	 HW_HASH_H0_REG_ADDR 		     0x0640UL
+#define 	 HW_HASH_H1_REG_ADDR 		     0x0644UL
+#define 	 HW_HASH_H2_REG_ADDR 		     0x0648UL
+#define 	 HW_HASH_H3_REG_ADDR 		     0x064CUL
+#define 	 HW_HASH_H4_REG_ADDR 		     0x0650UL
+#define 	 HW_HASH_H5_REG_ADDR 		     0x0654UL
+#define 	 HW_HASH_H6_REG_ADDR 		     0x0658UL
+#define 	 HW_HASH_H7_REG_ADDR 		     0x065CUL
+#define 	 HW_HASH_H8_REG_ADDR 		     0x0660UL
+#define 	 HW_HASH_H9_REG_ADDR 		     0x0664UL
+#define 	 HW_HASH_H10_REG_ADDR 		     0x0668UL
+#define 	 HW_HASH_H11_REG_ADDR 		     0x066CUL
+#define 	 HW_HASH_H12_REG_ADDR 		     0x0670UL
+#define 	 HW_HASH_H13_REG_ADDR 		     0x0674UL
+#define 	 HW_HASH_H14_REG_ADDR 		     0x0678UL
+#define 	 HW_HASH_H15_REG_ADDR 		     0x067CUL
+#define 	 HW_HASH_CONTROL_REG_ADDR 		 0x07C0UL
+#define 	 HW_HASH_PAD_EN_REG_ADDR 		 0x07C4UL
+#define 	 HW_HASH_PAD_CFG_REG_ADDR 		 0x07C8UL
+#define 	 HW_HASH_CUR_LEN_0_REG_ADDR 	 0x07CCUL
+#define 	 HW_HASH_CUR_LEN_1_REG_ADDR 	 0x07D0UL
+#define 	 HW_HASH_CUR_LEN_2_REG_ADDR 	 0x07D4UL
+#define 	 HW_HASH_CUR_LEN_3_REG_ADDR 	 0x07D8UL
+#define 	 HW_HASH_PARAM_REG_ADDR 		 0x07DCUL
+#define 	 HW_HASH_INT_BUSY_REG_ADDR 		 0x07E0UL
+#define 	 HW_HASH_SW_RESET_REG_ADDR 		 0x07E4UL
+#define 	 HW_HASH_ENDIANESS_REG_ADDR 	 0x07E8UL
+#define 	 HW_HASH_DATA_REG_ADDR 		     0x07ECUL
+#define 	 HW_DRNG_CONTROL_REG_ADDR 		 0x0800UL
+#define 	 HW_DRNG_VALID_REG_ADDR 		 0x0804UL
+#define 	 HW_DRNG_DATA_REG_ADDR 		     0x0808UL
+#define 	 HW_RND_SRC_EN_REG_ADDR 		 0x080CUL
+#define 	 HW_AES_CLK_ENABLE_REG_ADDR 	 0x0810UL
+#define 	 HW_DES_CLK_ENABLE_REG_ADDR 	 0x0814UL
+#define 	 HW_HASH_CLK_ENABLE_REG_ADDR 	 0x0818UL
+#define 	 HW_PKI_CLK_ENABLE_REG_ADDR 	 0x081CUL
+#define 	 HW_CLK_STATUS_REG_ADDR 		 0x0824UL
+#define 	 HW_CLK_ENABLE_REG_ADDR 		 0x0828UL
+#define 	 HW_DRNG_SAMPLE_REG_ADDR 		 0x0850UL
+#define 	 HW_RND_SRC_CTL_REG_ADDR 		 0x0858UL
+#define 	 HW_CRYPTO_CTL_REG_ADDR 		 0x0900UL
+#define 	 HW_CRYPTO_STATUS_REG_ADDR 		 0x090CUL
+#define 	 HW_CRYPTO_BUSY_REG_ADDR 		 0x0910UL
+#define 	 HW_AES_BUSY_REG_ADDR 		     0x0914UL
+#define 	 HW_DES_BUSY_REG_ADDR 		     0x0918UL
+#define 	 HW_HASH_BUSY_REG_ADDR 		     0x091CUL
+#define 	 HW_CONTENT_REG_ADDR 		     0x0924UL
+#define 	 HW_VERSION_REG_ADDR 		     0x0928UL
+#define 	 HW_CONTEXT_ID_REG_ADDR 		 0x0930UL
+#define 	 HW_DIN_BUFFER_REG_ADDR 		 0x0C00UL
+#define 	 HW_DIN_MEM_DMA_BUSY_REG_ADDR 	 0x0c20UL
+#define 	 HW_SRC_LLI_MEM_ADDR_REG_ADDR 	 0x0c24UL
+#define 	 HW_SRC_LLI_WORD0_REG_ADDR 		 0x0C28UL
+#define 	 HW_SRC_LLI_WORD1_REG_ADDR 		 0x0C2CUL
+#define 	 HW_SRAM_SRC_ADDR_REG_ADDR 		 0x0c30UL
+#define 	 HW_DIN_SRAM_BYTES_LEN_REG_ADDR  0x0c34UL
+#define 	 HW_DIN_SRAM_DMA_BUSY_REG_ADDR 	 0x0C38UL
+#define 	 HW_WRITE_ALIGN_REG_ADDR 		 0x0C3CUL
+#define 	 HW_OLD_DATA_REG_ADDR 		     0x0C48UL
+#define 	 HW_WRITE_ALIGN_LAST_REG_ADDR 	 0x0C4CUL
+#define 	 HW_DOUT_BUFFER_REG_ADDR 		 0x0C00UL
+#define 	 HW_DST_LLI_WORD0_REG_ADDR 		 0x0D28UL
+#define 	 HW_DST_LLI_WORD1_REG_ADDR 		 0x0D2CUL
+#define 	 HW_DST_LLI_MEM_ADDR_REG_ADDR 	 0x0D24UL
+#define 	 HW_DOUT_MEM_DMA_BUSY_REG_ADDR 	 0x0D20UL
+#define 	 HW_SRAM_DEST_ADDR_REG_ADDR 	 0x0D30UL
+#define 	 HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL
+#define 	 HW_DOUT_SRAM_DMA_BUSY_REG_ADDR  0x0D38UL
+#define 	 HW_READ_ALIGN_REG_ADDR 		 0x0D3CUL
+#define 	 HW_READ_LAST_DATA_REG_ADDR 	 0x0D44UL
+#define 	 HW_RC4_THRU_CPU_REG_ADDR 		 0x0D4CUL
+#define 	 HW_AHB_SINGLE_REG_ADDR 		 0x0E00UL
+#define 	 HW_SRAM_DATA_REG_ADDR 		     0x0F00UL
+#define 	 HW_SRAM_ADDR_REG_ADDR 		     0x0F04UL
+#define 	 HW_SRAM_DATA_READY_REG_ADDR 	 0x0F08UL
+#define 	 HW_HOST_IRR_REG_ADDR 		          0x0A00UL
+#define 	 HW_HOST_IMR_REG_ADDR 		          0x0A04UL
+#define 	 HW_HOST_ICR_REG_ADDR 		          0x0A08UL
+#define 	 HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR  0x0A10UL
+#define 	 HW_HOST_SEP_BUSY_REG_ADDR 		      0x0A14UL
+#define 	 HW_HOST_SEP_LCS_REG_ADDR 		      0x0A18UL
+#define 	 HW_HOST_CC_SW_RST_REG_ADDR 		  0x0A40UL
+#define 	 HW_HOST_SEP_SW_RST_REG_ADDR 		  0x0A44UL
+#define 	 HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 	  0x0A80UL
+#define 	 HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 	  0x0A84UL
+#define 	 HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 	  0x0A88UL
+#define 	 HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 	  0x0A8cUL
+#define 	 HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 	  0x0A90UL
+#define 	 HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 	  0x0A94UL
+#define 	 HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR    0x0A98UL
+#define 	 HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 	  0x0A9cUL
+#define 	 HW_HOST_SEP_HOST_GPR0_REG_ADDR 	  0x0B00UL
+#define 	 HW_HOST_SEP_HOST_GPR1_REG_ADDR 	  0x0B04UL
+#define 	 HW_HOST_SEP_HOST_GPR2_REG_ADDR 	  0x0B08UL
+#define 	 HW_HOST_SEP_HOST_GPR3_REG_ADDR       0x0B0CUL
+#define 	 HW_HOST_HOST_SEP_GPR0_REG_ADDR       0x0B80UL
+#define 	 HW_HOST_HOST_SEP_GPR1_REG_ADDR       0x0B84UL
+#define 	 HW_HOST_HOST_SEP_GPR2_REG_ADDR       0x0B88UL
+#define 	 HW_HOST_HOST_SEP_GPR3_REG_ADDR       0x0B8CUL
+#define 	 HW_HOST_HOST_ENDIAN_REG_ADDR 	      0x0B90UL
+#define 	 HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 	  0x0B94UL
+#define 	 HW_CLR_SRAM_BUSY_REG_REG_ADDR 	      0x0F0CUL
+#define    HW_CC_SRAM_BASE_ADDRESS              0x5800UL
+
+#endif				/* ifndef HW_DEFS */
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
index 0fdf8c6..52af44c 100644
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c
@@ -874,7 +874,7 @@ static void qt_release(struct usb_serial *serial)
 }
 
 static int qt_open(struct tty_struct *tty,
-	    struct usb_serial_port *port, struct file *filp)
+		   struct usb_serial_port *port)
 {
 	struct usb_serial *serial;
 	struct quatech_port *quatech_port;
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index ed47db5..e67a130 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -845,7 +845,7 @@ static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
 				 hcmd->paddrh, DONT_FLUSH);
 	}
 xmit_done:
-	return 0;
+	return NETDEV_TX_OK;
 xmit_fail:
 	slic_xmit_fail(adapter, skb, offloadcmd, skbtype, status);
 	goto xmit_done;
@@ -1306,7 +1306,7 @@ static void slic_mcast_init_crc32(void)
 
 	static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
 
-	for (i = 0; i < sizeof(p) / sizeof(int); i++)
+	for (i = 0; i < ARRAY_SIZE(p); i++)
 		e |= 1L << (31 - p[i]);
 
 	for (i = 1; i < 256; i++) {
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c
index a137c78..12d414d 100644
--- a/drivers/staging/stlc45xx/stlc45xx.c
+++ b/drivers/staging/stlc45xx/stlc45xx.c
@@ -1429,7 +1429,8 @@ static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
 	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);
+	memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
+	ieee80211_rx(stlc->hw, skb);
 
 	return 0;
 }
diff --git a/drivers/staging/sxg/Kconfig b/drivers/staging/sxg/Kconfig
deleted file mode 100644
index c5cbdaf..0000000
--- a/drivers/staging/sxg/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-config SXG
-	tristate "Alacritech SLIC Technology Non-Accelerated 10Gbe support"
-	depends on PCI && NETDEV_10000
-	depends on X86
-	default n
-	help
-	  This driver supports the Alacritech SLIC Technology Non-Accelerated
-	  10Gbe network cards.
-
-	  To compile this driver as a module, choose
-	  M here: the module will be called sxg_nic.
diff --git a/drivers/staging/sxg/Makefile b/drivers/staging/sxg/Makefile
deleted file mode 100644
index 8e05322..0000000
--- a/drivers/staging/sxg/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-obj-$(CONFIG_SXG)	+= sxg_nic.o
-
-sxg_nic-y := sxg.o sxg_ethtool.o
diff --git a/drivers/staging/sxg/README b/drivers/staging/sxg/README
deleted file mode 100644
index e42f344..0000000
--- a/drivers/staging/sxg/README
+++ /dev/null
@@ -1,12 +0,0 @@
-This is the rough cut at a driver for the Alacritech SLIC Technology
-Non-Accelerated 10Gbe network driver.
-
-TODO:
-	- remove wrappers
-	- checkpatch.pl cleanups
-	- new functionality that the card needs
-	- remove reliance on x86
-
-Please send patches to:
-        Greg Kroah-Hartman <gregkh@suse.de>
-for any cleanups that you do to this driver.
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c
deleted file mode 100644
index 3a0dac9..0000000
--- a/drivers/staging/sxg/sxg.c
+++ /dev/null
@@ -1,4543 +0,0 @@
-/**************************************************************************
- *
- * 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.
- *
- * Parts developed by LinSysSoft Sahara team
- *
- **************************************************************************/
-
-/*
- * FILENAME: sxg.c
- *
- * The 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/string.h>
-#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>
-#include <linux/timer.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#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_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 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-1.2.h"
-
-static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size,
-				      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,
-					     dma_addr_t PhysicalAddress,
-					     u32 Length);
-
-static void sxg_mcast_init_crc32(void);
-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 int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
-				struct sxg_scatter_gather *SxgSgl);
-
-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,
-			 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 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);
-
-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(struct net_device *dev, void *ptr);
-#endif
-static void sxg_mcast_set_list(struct net_device *dev);
-
-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 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";
-
-static int sxg_debug = 1;
-static int debug = -1;
-static struct net_device *head_netdevice = NULL;
-
-static struct sxgbase_driver sxg_global = {
-	.dynamic_intagg = 1,
-};
-static int intagg_delay = 100;
-static u32 dynamic_intagg = 0;
-
-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."
-
-MODULE_AUTHOR(DRV_AUTHOR);
-MODULE_DESCRIPTION(DRV_DESCRIPTION);
-MODULE_LICENSE("GPL");
-
-module_param(dynamic_intagg, int, 0);
-MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting");
-module_param(intagg_delay, int, 0);
-MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
-
-static struct pci_device_id sxg_pci_tbl[] __devinitdata = {
-	{PCI_DEVICE(SXG_VENDOR_ID, SXG_DEVICE_ID)},
-	{0,}
-};
-
-MODULE_DEVICE_TABLE(pci, sxg_pci_tbl);
-
-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_init_driver(void)
-{
-	if (sxg_first_init) {
-		DBG_ERROR("sxg: %s sxg_first_init set jiffies[%lx]\n",
-			  __func__, jiffies);
-		sxg_first_init = 0;
-		spin_lock_init(&sxg_global.driver_lock);
-	}
-}
-
-static void sxg_dbg_macaddrs(struct adapter_t *adapter)
-{
-	DBG_ERROR("  (%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_ERROR("  (%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;
-}
-
-/* SXG Globals */
-static struct sxg_driver SxgDriver;
-
-#ifdef  ATKDBG
-static struct sxg_trace_buffer LSxgTraceBuffer;
-#endif /* ATKDBG */
-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) {
-		spin_unlock_irqrestore(&sxg_global.driver_lock,
-					sxg_global.flags);
-		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) {
-				spin_lock_irqsave(&sxg_global.driver_lock,
-						 sxg_global.flags);
-				DBG_ERROR("sxg: MSI-X request_irq (%s) "
-					"FAILED [%x]\n", adapter->netdev->name,
-					 ret);
-				return (ret);
-			}
-		}
-	}
-	spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
-	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",__func__,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 using the Linux
- * Firmware module to get the ucode.sys file.
- *
- * Arguments -
- *		adapter		- A pointer to our adapter structure
- *		UcodeSel	- microcode file selection
- *
- * Return
- *	int
- */
-static bool sxg_download_microcode(struct adapter_t *adapter,
-						enum SXG_UCODE_SEL UcodeSel)
-{
-	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 = 0;
-	u32 BaseAddress, AddressOffset, Address;
-	/* u32 Failure; */
-	u32 ValueRead;
-	u32 i;
-	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);
-
-	/*
-	 *  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;
-	}
-
-	/*
-	 *  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
-	 * 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];
-		/* 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 (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, first_instr, FLUSH);
-		}
-	}
-	/*
-	 * 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];
-		/* Size in instructions */
-		ThisSectionSize = sectionSize[Section] / 12;
-		for (AddressOffset = 0; AddressOffset < ThisSectionSize;
-		     AddressOffset++) {
-			Address = BaseAddress + AddressOffset;
-			/* Write the address with the READ bit set */
-			WRITE_REG(HwRegs->UcodeAddr,
-				  (Address | MICROCODE_ADDRESS_READ), FLUSH);
-			/* Read it back and check parity bit. */
-			READ_REG(HwRegs->UcodeAddr, ValueRead);
-			if (ValueRead & MICROCODE_ADDRESS_PARITY) {
-				DBG_ERROR("sxg: %s PARITY ERROR\n",
-					  __func__);
-
-				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) {
-				DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
-					  __func__);
-				return FALSE;	/* Miscompare */
-			}
-			instruction = *(u32 *)(fw->data + index);
-			index += 4;
-			READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
-			if (ValueRead != instruction) {
-				DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
-					  __func__);
-				return FALSE;	/* Miscompare */
-			}
-			instruction = *(u32 *)(fw->data + index);
-			index += 4;
-			READ_REG(HwRegs->UcodeDataHigh, ValueRead);
-			if (ValueRead != instruction) {
-				DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
-					  __func__);
-				return FALSE;	/* Miscompare */
-			}
-		}
-	}
-
-	/* 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).
-	 */
-	for (i = 0; i < 10000; i++) {
-		udelay(50);
-		READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
-		if (ValueRead == 0xCAFE) {
-			break;
-		}
-	}
-	if (i == 10000) {
-		DBG_ERROR("sxg: %s TIMEOUT bringing up card - verify MICROCODE\n", __func__);
-
-		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_SYSTEM) {
-		WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH);
-	}
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd",
-		  adapter, 0, 0, 0);
-	return (TRUE);
-}
-
-/*
- * sxg_allocate_resources - Allocate memory and locks
- *
- * Arguments -
- *	adapter	- A pointer to our adapter structure
- *
- * Return - int
- */
-static int sxg_allocate_resources(struct adapter_t *adapter)
-{
-	int status = STATUS_SUCCESS;
-	u32 RssIds, IsrCount;
-	/* struct sxg_xmt_ring	*XmtRing; */
-	/* struct sxg_rcv_ring	*RcvRing; */
-
-	DBG_ERROR("%s ENTER\n", __func__);
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocRes",
-		  adapter, 0, 0, 0);
-
-	/* Windows tells us how many CPUs it plans to use for */
-	/* RSS */
-	RssIds = SXG_RSS_CPU_COUNT(adapter);
-	IsrCount = adapter->msi_enabled ? RssIds : 1;
-
-	DBG_ERROR("%s Setup the spinlocks\n", __func__);
-
-	/* Allocate spinlocks and initialize listheads first. */
-	spin_lock_init(&adapter->RcvQLock);
-	spin_lock_init(&adapter->SglQLock);
-	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__);
-
-	InitializeListHead(&adapter->FreeRcvBuffers);
-	InitializeListHead(&adapter->FreeRcvBlocks);
-	InitializeListHead(&adapter->AllRcvBlocks);
-	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.
-	 */
-	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.
-	 */
-
-	for (;;) {
-		DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__,
-			  (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 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);
-		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);
-
-		DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__,
-			  (unsigned int)(sizeof(struct sxg_rcv_ring) * 1));
-		adapter->RcvRings =
-		    pci_alloc_consistent(adapter->pcidev,
-					 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);
-		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) * 1,
-					    adapter->XmtRings,
-					    adapter->PXmtRings);
-			adapter->XmtRings = NULL;
-		}
-		if (adapter->RcvRings) {
-			pci_free_consistent(adapter->pcidev,
-					    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__);
-	/* Initialize rcv zero and xmt zero rings */
-	SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE);
-	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) ==
-	       SXG_RCV_DESCRIPTOR_BLOCK_SIZE);
-
-	DBG_ERROR("%s Allocate EventRings size[%x]\n", __func__,
-		  (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);
-
-	if (!adapter->EventRings) {
-		/* 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);
-
-	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 */
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9",
-			  adapter, SXG_MAX_ENTRIES, 0, 0);
-		status = STATUS_RESOURCES;
-		goto per_tcb_allocation_failed;
-	}
-	memset(adapter->Isr, 0, sizeof(u32) * IsrCount);
-
-	DBG_ERROR("%s Allocate shared XMT ring zero index location size[%x]\n",
-		  __func__, (unsigned int)sizeof(u32));
-
-	/* Allocate shared XMT ring zero index location */
-	adapter->XmtRingZeroIndex = pci_alloc_consistent(adapter->pcidev,
-							 sizeof(u32),
-							 &adapter->
-							 PXmtRingZeroIndex);
-	if (!adapter->XmtRingZeroIndex) {
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF10",
-			  adapter, SXG_MAX_ENTRIES, 0, 0);
-		status = STATUS_RESOURCES;
-		goto per_tcb_allocation_failed;
-	}
-	memset(adapter->XmtRingZeroIndex, 0, sizeof(u32));
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS",
-		  adapter, SXG_MAX_ENTRIES, 0, 0);
-
-	return status;
-}
-
-/*
- * sxg_config_pci -
- *
- * Set up PCI Configuration space
- *
- * Arguments -
- *		pcidev			- A pointer to our adapter structure
- */
-static void sxg_config_pci(struct pci_dev *pcidev)
-{
-	u16 pci_command;
-	u16 new_command;
-
-	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 | (
-				     /* 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);
-		pci_write_config_word(pcidev, PCI_COMMAND, new_command);
-	}
-}
-
-/*
- * 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", __func__);
-		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", __func__, 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 const struct net_device_ops sxg_netdev_ops = {
-	.ndo_open		= sxg_entry_open,
-	.ndo_stop		= sxg_entry_halt,
-	.ndo_start_xmit		= sxg_send_packets,
-	.ndo_do_ioctl		= sxg_ioctl,
-	.ndo_change_mtu		= sxg_change_mtu,
-	.ndo_get_stats		= sxg_get_stats,
-	.ndo_set_multicast_list	= sxg_mcast_set_list,
-	.ndo_validate_addr	= eth_validate_addr,
-#if XXXTODO
-	.ndo_set_mac_address	= sxg_mac_set_address,
-#else
-	.ndo_set_mac_address	= eth_mac_addr,
-#endif
-};
-
-static int sxg_entry_probe(struct pci_dev *pcidev,
-			   const struct pci_device_id *pci_tbl_entry)
-{
-	static int did_version = 0;
-	int err;
-	struct net_device *netdev;
-	struct adapter_t *adapter;
-	void __iomem *memmapped_ioaddr;
-	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());
-
-	/* Initialize trace buffer */
-#ifdef ATKDBG
-	SxgTraceBuffer = &LSxgTraceBuffer;
-	SXG_TRACE_INIT(SxgTraceBuffer, TRACE_NOISY);
-#endif
-
-	sxg_global.dynamic_intagg = dynamic_intagg;
-
-	err = pci_enable_device(pcidev);
-
-	DBG_ERROR("Call pci_enable_device(%p)  status[%x]\n", pcidev, err);
-	if (err) {
-		return err;
-	}
-
-	if (sxg_debug > 0 && did_version++ == 0) {
-		printk(KERN_INFO "%s\n", sxg_banner);
-		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_BIT_MASK(64)))) {
-		DBG_ERROR("pci_set_dma_mask(DMA_BIT_MASK(64)) successful\n");
-	} else {
-		if ((err = pci_set_dma_mask(pcidev, DMA_BIT_MASK(32)))) {
-			DBG_ERROR
-			    ("No usable DMA configuration, aborting  err[%x]\n",
-			     err);
-			return err;
-		}
-		DBG_ERROR("pci_set_dma_mask(DMA_BIT_MASK(32)) successful\n");
-	}
-
-	DBG_ERROR("Call pci_request_regions\n");
-
-	err = pci_request_regions(pcidev, sxg_driver_name);
-	if (err) {
-		DBG_ERROR("pci_request_regions FAILED err[%x]\n", err);
-		return err;
-	}
-
-	DBG_ERROR("call pci_set_master\n");
-	pci_set_master(pcidev);
-
-	DBG_ERROR("call alloc_etherdev\n");
-	netdev = alloc_etherdev(sizeof(struct adapter_t));
-	if (!netdev) {
-		err = -ENOMEM;
-		goto err_out_exit_sxg_probe;
-	}
-	DBG_ERROR("alloc_etherdev for slic netdev[%p]\n", netdev);
-
-	SET_NETDEV_DEV(netdev, &pcidev->dev);
-
-	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", __func__, revision_id);
-		goto err_out_exit_sxg_probe;
-	}
-	adapter->netdev = netdev;
-	adapter->pcidev = pcidev;
-
-	mmio_start = pci_resource_start(pcidev, 0);
-	mmio_len = pci_resource_len(pcidev, 0);
-
-	DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
-		  mmio_start, mmio_len);
-
-	memmapped_ioaddr = ioremap(mmio_start, mmio_len);
-	DBG_ERROR("sxg: %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_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);
-
-	adapter->HwRegs = (void *)memmapped_ioaddr;
-	adapter->base_addr = memmapped_ioaddr;
-
-	mmio_start = pci_resource_start(pcidev, 2);
-	mmio_len = pci_resource_len(pcidev, 2);
-
-	DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
-		  mmio_start, mmio_len);
-
-	memmapped_ioaddr = ioremap(mmio_start, mmio_len);
-	DBG_ERROR("sxg: %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_2;
-	}
-
-	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->UcodeRegs = (void *)memmapped_ioaddr;
-
-	adapter->State = SXG_STATE_INITIALIZING;
-	/*
-	 * Maintain a list of all adapters anchored by
-	 * the global SxgDriver structure.
-	 */
-	adapter->Next = SxgDriver.Adapters;
-	SxgDriver.Adapters = adapter;
-	adapter->AdapterID = ++SxgDriver.AdapterID;
-
-	/* Initialize CRC table used to determine multicast hash */
-	sxg_mcast_init_crc32();
-
-	adapter->JumboEnabled = FALSE;
-	adapter->RssEnabled = FALSE;
-	if (adapter->JumboEnabled) {
-		adapter->FrameSize = JUMBOMAXFRAME;
-		adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE;
-	} else {
-		adapter->FrameSize = ETHERMAXFRAME;
-		adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
-	}
-
-	/*
-	 *    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);
-	DBG_ERROR("sxg: %s EXIT sxg_config_pci\n", __func__);
-
-	DBG_ERROR("sxg: %s ENTER sxg_init_driver\n", __func__);
-	sxg_init_driver();
-	DBG_ERROR("sxg: %s EXIT sxg_init_driver\n", __func__);
-
-	adapter->vendid = pci_tbl_entry->vendor;
-	adapter->devid = pci_tbl_entry->device;
-	adapter->subsysid = pci_tbl_entry->subdevice;
-	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->port = 0;	/*adapter->functionnumber; */
-
-	/* Allocate memory and other resources */
-	DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__);
-	status = sxg_allocate_resources(adapter);
-	DBG_ERROR("sxg: %s EXIT sxg_allocate_resources status %x\n",
-		  __func__, status);
-	if (status != STATUS_SUCCESS) {
-		goto err_out_unmap;
-	}
-
-	DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__);
-	if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
-		DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
-			  __func__);
-		sxg_read_config(adapter);
-		status = sxg_adapter_set_hwaddr(adapter);
-	} else {
-		adapter->state = ADAPT_FAIL;
-		adapter->linkstate = LINK_DOWN;
-		DBG_ERROR("sxg_download_microcode FAILED status[%x]\n", status);
-	}
-
-	netdev->base_addr = (unsigned long)adapter->base_addr;
-	netdev->irq = adapter->irq;
-	netdev->netdev_ops = &sxg_netdev_ops;
-	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)); */
-	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",
-	     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: */
-	ASSERT(status == FALSE);
-	/* 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:
-	sxg_free_resources(adapter);
-
-      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:
-
-	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", __func__);
-        kfree(netdev);
-	printk("Exit %s, Sxg driver loading failed..\n", __func__);
-
-	return -ENODEV;
-}
-
-/*
- * LINE BASE Interrupt routines..
- *
- * sxg_disable_interrupt
- *
- * DisableInterrupt Handler
- *
- * Arguments:
- *
- *   adapter:	Our adapter structure
- *
- * Return Value:
- * 	None.
- */
-static void sxg_disable_interrupt(struct adapter_t *adapter)
-{
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DisIntr",
-		  adapter, adapter->InterruptsEnabled, 0, 0);
-	/* For now, RSS is disabled with line based interrupts */
-	ASSERT(adapter->RssEnabled == 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;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDisIntr",
-		  adapter, adapter->InterruptsEnabled, 0, 0);
-}
-
-/*
- * sxg_enable_interrupt
- *
- * EnableInterrupt Handler
- *
- * Arguments:
- *
- *   adapter:	Our adapter structure
- *
- * Return Value:
- * 	None.
- */
-static void sxg_enable_interrupt(struct adapter_t *adapter)
-{
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "EnIntr",
-		  adapter, adapter->InterruptsEnabled, 0, 0);
-	/* For now, RSS is disabled with line based interrupts */
-	ASSERT(adapter->RssEnabled == 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;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XEnIntr",
-		  adapter, 0, 0, 0);
-}
-
-/*
- * sxg_isr - Process an line-based interrupt
- *
- * Arguments:
- * 		Context		- Our adapter structure
- *		QueueDefault 	- Output parameter to queue to default CPU
- *		TargetCpus	- Output bitmap to schedule DPC's
- *
- * Return Value: TRUE if our interrupt
- */
-static irqreturn_t sxg_isr(int irq, void *dev_id)
-{
-	struct net_device *dev = (struct net_device *) dev_id;
-	struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
-
-	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.
-		 */
-		adapter->Stats.FalseInts++;
-		return IRQ_NONE;
-	}
-	/*
-	 * 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 (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) {
-		for (i = 0;
-		     i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount;
-		     i++) {
-			struct sxg_event_ring *EventRing =
-						&adapter->EventRings[i];
-			struct sxg_event *Event =
-			    &EventRing->Ring[adapter->NextEvent[i]];
-			unsigned char Cpu =
-			    adapter->RssSystemInfo->RssIdToCpu[i];
-			if (Event->Status & EVENT_STATUS_VALID) {
-				adapter->IsrDpcsPending++;
-				CpuMask |= (1 << Cpu);
-			}
-		}
-	}
-	/*
-	 * Now, either schedule the CPUs specified by the CpuMask,
-	 * or queue default
-	 */
-	if (CpuMask) {
-		*QueueDefault = FALSE;
-	} else {
-		adapter->IsrDpcsPending = 1;
-		*QueueDefault = TRUE;
-	}
-	*TargetCpus = CpuMask;
-#endif
-	sxg_interrupt(adapter);
-
-	return IRQ_HANDLED;
-}
-
-static void sxg_interrupt(struct adapter_t *adapter)
-{
-	WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
-
-	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);
-
-	adapter->IsrCopy[0] = adapter->Isr[0];
-	adapter->Isr[0] = 0;
-
-	/* Always process the event queue. */
-	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) {
-		/* We're done. */
-		ASSERT(adapter->RssEnabled);
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DPCsPend",
-			  adapter, 0, 0, 0);
-		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);
-
-	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
- *
- * Arguments:
- * 		adapter			- Our adapter structure
- *		Queue			- The ISR that needs processing
- *
- * Return Value:
- * 	None
- */
-static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
-{
-	u32 Isr = adapter->IsrCopy[MessageId];
-	u32 NewIsr = 0;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ProcIsr",
-		  adapter, Isr, 0, 0);
-
-	/* Error */
-	if (Isr & SXG_ISR_ERR) {
-		if (Isr & SXG_ISR_PDQF) {
-			adapter->Stats.PdqFull++;
-			DBG_ERROR("%s: SXG_ISR_ERR  PDQF!!\n", __func__);
-		}
-		/* 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 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);
-			adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH);
-			adapter->Dead = TRUE;
-			DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __func__,
-				  adapter->CrashLocation, adapter->CrashCpu);
-		}
-		/* 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.
-			 */
-			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) {
-			DBG_ERROR("%s: SXG_ISR_ERR  XDROP!!\n", __func__);
-		}
-	}
-	/* Slowpath send completions */
-	if (Isr & SXG_ISR_SPSEND) {
-		sxg_complete_slow_send(adapter);
-	}
-	/* Dump */
-	if (Isr & SXG_ISR_UPC) {
-		/* Maybe change when debug is added.. */
-//		ASSERT(adapter->DumpCmdRunning);
-		adapter->DumpCmdRunning = FALSE;
-	}
-	/* Link event */
-	if (Isr & SXG_ISR_LINK) {
-		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.
-		 */
-		ASSERT(0);
-	}
-	/* Heartbeat response */
-	if (Isr & SXG_ISR_PING) {
-		adapter->PingOutstanding = FALSE;
-	}
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XProcIsr",
-		  adapter, Isr, NewIsr, 0);
-
-	return (NewIsr);
-}
-
-/*
- * 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:
- * 		- adapter	- Adapter structure
- *		- RssId		- The event queue requiring processing
- *
- * Return Value:
- * 	None.
- */
-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]];
-	u32 EventsProcessed = 0, Batches = 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;
-#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.
-	 */
-	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.
-	 */
-	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:
-			/* 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;
-#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
-				/* Add it to our indication list */
-				SXG_ADD_RCV_PACKET(adapter, skb, prev_skb,
-						   IndicationList, num_skbs);
-				/*
-				 * 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); */
-				/* (rcvbuf->length & IRHDDR_FLEN_MSK); */
-				rx_bytes = Event->Length;
-				adapter->stats.rx_packets++;
-				adapter->stats.rx_bytes += rx_bytes;
-				sxg_rcv_checksum(adapter, skb, Event);
-				skb->dev = adapter->netdev;
-				netif_receive_skb(skb);
-#endif
-			}
-			break;
-		default:
-			DBG_ERROR("%s: ERROR  Invalid EventCode %d\n",
-				  __func__, Event->Code);
-		/* 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 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...
-		 */
-		Event->Status &= ~EVENT_STATUS_VALID;
-		/* Advance to the next event */
-		SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE);
-		Event = &EventRing->Ring[adapter->NextEvent[RssId]];
-		EventsProcessed++;
-		if (EventsProcessed == EVENT_RING_BATCH) {
-			/* Release a batch of events back to the card */
-			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 (Batches++ == EVENT_BATCH_LIMIT) {
-				SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
-					  TRACE_NOISY, "EvtLimit", Batches,
-					  adapter->NextEvent, 0, 0);
-				ReturnStatus = SXG_ISR_EVENT;
-				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);
-	}
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XPrcEvnt",
-		  Batches, EventsProcessed, adapter->NextEvent, num_skbs);
-
-	return (ReturnStatus);
-}
-
-/*
- * sxg_complete_slow_send - Complete slowpath or dumb-nic sends
- *
- * 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;
-	u32 *ContextType;
-	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_irqsave(&adapter->XmtZeroLock, flags);
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
-		  adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
-
-	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",
-			  XmtRingInfo->Head, XmtRingInfo->Tail, XmtCmd, 0);
-		/* Clear the SGL field. */
-		XmtCmd->Sgl = 0;
-
-		switch (*ContextType) {
-		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);
-				/*
-				 * 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_irqsave(&adapter->XmtZeroLock, flags);
-			}
-			break;
-		default:
-			ASSERT(0);
-		}
-	}
-	spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
-		  adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
-}
-
-/*
- * sxg_slow_receive
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *	Event		- Receive event
- *
- * Return - skb
- */
-static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
-						struct sxg_event *Event)
-{
-	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;
-	if(read_counter++ & 0x100)
-	{
-		sxg_collect_statistics(adapter);
-		read_counter = 0;
-	}
-	ASSERT(RcvDataBufferHdr);
-	ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
-		  RcvDataBufferHdr, RcvDataBufferHdr->State,
-		  /*RcvDataBufferHdr->VirtualAddress*/ 0);
-	/* Drop rcv frames in non-running state */
-	switch (adapter->State) {
-	case SXG_STATE_RUNNING:
-		break;
-	case SXG_STATE_PAUSING:
-	case SXG_STATE_PAUSED:
-	case SXG_STATE_HALTING:
-		goto drop;
-	default:
-		ASSERT(0);
-		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);
-		sxg_process_rcv_error(adapter, *(u32 *)
-				      SXG_RECEIVE_DATA_LOCATION
-				      (RcvDataBufferHdr));
-		goto drop;
-	}
-#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 (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) !=
-		    STATUS_SUCCESS) {
-			SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY,
-				  "BadVlan", Event,
-				  SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
-				  Event->Length, 0);
-			goto drop;
-		}
-	}
-#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)) {
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr",
-			    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. */
-	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.rx_dropped++;
-//	adapter->Stats.RcvDiscards++;
-	spin_lock(&adapter->RcvQLock);
-	SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
-	spin_unlock(&adapter->RcvQLock);
-	return (NULL);
-}
-
-/*
- * sxg_process_rcv_error - process receive error and update
- * stats
- *
- * Arguments:
- *		adapter		- Adapter structure
- *		ErrorStatus	- 4-byte receive error status
- *
- * Return Value		: None
- */
-static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus)
-{
-	u32 Error;
-
-	adapter->stats.rx_errors++;
-
-	if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) {
-		Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK;
-		switch (Error) {
-		case SXG_RCV_STATUS_TRANSPORT_CSUM:
-			adapter->Stats.TransportCsum++;
-			break;
-		case SXG_RCV_STATUS_TRANSPORT_UFLOW:
-			adapter->Stats.TransportUflow++;
-			break;
-		case SXG_RCV_STATUS_TRANSPORT_HDRLEN:
-			adapter->Stats.TransportHdrLen++;
-			break;
-		}
-	}
-	if (ErrorStatus & SXG_RCV_STATUS_NETWORK_ERROR) {
-		Error = ErrorStatus & SXG_RCV_STATUS_NETWORK_MASK;
-		switch (Error) {
-		case SXG_RCV_STATUS_NETWORK_CSUM:
-			adapter->Stats.NetworkCsum++;
-			break;
-		case SXG_RCV_STATUS_NETWORK_UFLOW:
-			adapter->Stats.NetworkUflow++;
-			break;
-		case SXG_RCV_STATUS_NETWORK_HDRLEN:
-			adapter->Stats.NetworkHdrLen++;
-			break;
-		}
-	}
-	if (ErrorStatus & SXG_RCV_STATUS_PARITY) {
-		adapter->Stats.Parity++;
-	}
-	if (ErrorStatus & SXG_RCV_STATUS_LINK_ERROR) {
-		Error = ErrorStatus & SXG_RCV_STATUS_LINK_MASK;
-		switch (Error) {
-		case SXG_RCV_STATUS_LINK_PARITY:
-			adapter->Stats.LinkParity++;
-			break;
-		case SXG_RCV_STATUS_LINK_EARLY:
-			adapter->Stats.LinkEarly++;
-			break;
-		case SXG_RCV_STATUS_LINK_BUFOFLOW:
-			adapter->Stats.LinkBufOflow++;
-			break;
-		case SXG_RCV_STATUS_LINK_CODE:
-			adapter->Stats.LinkCode++;
-			break;
-		case SXG_RCV_STATUS_LINK_DRIBBLE:
-			adapter->Stats.LinkDribble++;
-			break;
-		case SXG_RCV_STATUS_LINK_CRC:
-			adapter->Stats.LinkCrc++;
-			break;
-		case SXG_RCV_STATUS_LINK_OFLOW:
-			adapter->Stats.LinkOflow++;
-			break;
-		case SXG_RCV_STATUS_LINK_UFLOW:
-			adapter->Stats.LinkUflow++;
-			break;
-		}
-	}
-}
-
-/*
- * sxg_mac_filter
- *
- * Arguments:
- *		adapter		- Adapter structure
- *		pether		- Ethernet header
- *		length		- Frame length
- *
- * 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)
-{
-	bool EqualAddr;
-	struct net_device *dev = adapter->netdev;
-
-	if (SXG_MULTICAST_PACKET(EtherHdr)) {
-		if (SXG_BROADCAST_PACKET(EtherHdr)) {
-			/* broadcast */
-			if (adapter->MacFilter & MAC_BCAST) {
-				adapter->Stats.DumbRcvBcastPkts++;
-				adapter->Stats.DumbRcvBcastBytes += length;
-				return (TRUE);
-			}
-		} else {
-			/* multicast */
-			if (adapter->MacFilter & MAC_ALLMCAST) {
-				adapter->Stats.DumbRcvMcastPkts++;
-				adapter->Stats.DumbRcvMcastBytes += length;
-				return (TRUE);
-			}
-			if (adapter->MacFilter & MAC_MCAST) {
-				struct dev_mc_list *mclist = dev->mc_list;
-				while (mclist) {
-					ETHER_EQ_ADDR(mclist->da_addr,
-						      EtherHdr->ether_dhost,
-						      EqualAddr);
-					if (EqualAddr) {
-						adapter->Stats.
-						    DumbRcvMcastPkts++;
-						adapter->Stats.
-						    DumbRcvMcastBytes += length;
-						return (TRUE);
-					}
-					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
-		 */
-		adapter->Stats.DumbRcvUcastPkts++;
-		adapter->Stats.DumbRcvUcastBytes += length;
-		return (TRUE);
-	}
-	if (adapter->MacFilter & MAC_PROMISC) {
-		/* Whatever it is, keep it. */
-		return (TRUE);
-	}
-	return (FALSE);
-}
-
-static int sxg_register_interrupt(struct adapter_t *adapter)
-{
-	if (!adapter->intrregistered) {
-		int retval;
-
-		DBG_ERROR
-		    ("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x] %x\n",
-		     __func__, adapter, adapter->netdev->irq, NR_IRQS);
-
-		spin_unlock_irqrestore(&sxg_global.driver_lock,
-				       sxg_global.flags);
-
-		retval = request_irq(adapter->netdev->irq,
-				     &sxg_isr,
-				     IRQF_SHARED,
-				     adapter->netdev->name, adapter->netdev);
-
-		spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
-
-		if (retval) {
-			DBG_ERROR("sxg: request_irq (%s) FAILED [%x]\n",
-				  adapter->netdev->name, retval);
-			return (retval);
-		}
-		adapter->intrregistered = 1;
-		adapter->IntRegistered = TRUE;
-		/* Disable RSS with line-based interrupts */
-		adapter->RssEnabled = FALSE;
-		DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n",
-			  __func__, adapter, adapter->netdev->irq);
-	}
-	return (STATUS_SUCCESS);
-}
-
-static void sxg_deregister_interrupt(struct adapter_t *adapter)
-{
-	DBG_ERROR("sxg: %s ENTER adapter[%p]\n", __func__, adapter);
-#if XXXTODO
-	slic_init_cleanup(adapter);
-#endif
-	memset(&adapter->stats, 0, sizeof(struct net_device_stats));
-	adapter->error_interrupts = 0;
-	adapter->rcv_interrupts = 0;
-	adapter->xmit_interrupts = 0;
-	adapter->linkevent_interrupts = 0;
-	adapter->upr_interrupts = 0;
-	adapter->num_isrs = 0;
-	adapter->xmit_completes = 0;
-	adapter->rcv_broadcasts = 0;
-	adapter->rcv_multicasts = 0;
-	adapter->rcv_unicasts = 0;
-	DBG_ERROR("sxg: %s EXIT\n", __func__);
-}
-
-/*
- *  sxg_if_init
- *
- *  Perform initialization of our slic interface.
- *
- */
-static int sxg_if_init(struct adapter_t *adapter)
-{
-	struct net_device *dev = adapter->netdev;
-	int status = 0;
-
-	DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d] flags[%x]\n",
-		  __func__, adapter->netdev->name,
-		  adapter->state,
-		  adapter->linkstate, dev->flags);
-
-	/* adapter should be down at this point */
-	if (adapter->state != ADAPT_DOWN) {
-		DBG_ERROR("sxg_if_init adapter->state != ADAPT_DOWN\n");
-		return (-EIO);
-	}
-	ASSERT(adapter->linkstate == LINK_DOWN);
-
-	adapter->devflags_prev = dev->flags;
-	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->MacFilter |= MAC_BCAST;
-			DBG_ERROR("BCAST ");
-		}
-		if (dev->flags & IFF_PROMISC) {
-			adapter->MacFilter |= MAC_PROMISC;
-			DBG_ERROR("PROMISC ");
-		}
-		if (dev->flags & IFF_ALLMULTI) {
-			adapter->MacFilter |= MAC_ALLMCAST;
-			DBG_ERROR("ALL_MCAST ");
-		}
-		if (dev->flags & IFF_MULTICAST) {
-			adapter->MacFilter |= MAC_MCAST;
-			DBG_ERROR("MCAST ");
-		}
-		DBG_ERROR("\n");
-	}
-	status = sxg_register_intr(adapter);
-	if (status != STATUS_SUCCESS) {
-		DBG_ERROR("sxg_if_init: sxg_register_intr FAILED %x\n",
-			  status);
-		sxg_deregister_interrupt(adapter);
-		return (status);
-	}
-
-	adapter->state = ADAPT_UP;
-
-	/*    clear any pending events, then enable interrupts */
-	DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__);
-
-	return (STATUS_SUCCESS);
-}
-
-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", __func__);
-	if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
-		DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
-				__func__);
-		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__,
-		  adapter->activated);
-	DBG_ERROR
-	    ("sxg: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] port[%d]\n",
-	     __func__, adapter->netdev->name, jiffies, smp_processor_id(),
-	     adapter->netdev, adapter, adapter->port);
-
-	netif_stop_queue(adapter->netdev);
-
-	spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
-	if (!adapter->activated) {
-		sxg_global.num_sxg_ports_active++;
-		adapter->activated = 1;
-	}
-	/* Initialize the adapter */
-	DBG_ERROR("sxg: %s ENTER sxg_initialize_adapter\n", __func__);
-	status = sxg_initialize_adapter(adapter);
-	DBG_ERROR("sxg: %s EXIT sxg_initialize_adapter status[%x]\n",
-		  __func__, status);
-
-	if (status == STATUS_SUCCESS) {
-		DBG_ERROR("sxg: %s ENTER sxg_if_init\n", __func__);
-		status = sxg_if_init(adapter);
-		DBG_ERROR("sxg: %s EXIT sxg_if_init status[%x]\n", __func__,
-			  status);
-	}
-
-	if (status != STATUS_SUCCESS) {
-		if (adapter->activated) {
-			sxg_global.num_sxg_ports_active--;
-			adapter->activated = 0;
-		}
-		spin_unlock_irqrestore(&sxg_global.driver_lock,
-				       sxg_global.flags);
-		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);
-
-	DBG_ERROR("sxg: %s EXIT\n", __func__);
-
-	spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
-	mod_timer(&adapter->watchdog_timer, jiffies);
-
-	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)
-{
-        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);
-
-	flush_scheduled_work();
-
-	/* Deallocate Resources */
-	unregister_netdev(dev);
-	sxg_reset_interrupt_capability(adapter);
-	sxg_free_resources(adapter);
-
-	ASSERT(adapter);
-
-        mmio_start = pci_resource_start(pcidev, 0);
-        mmio_len = pci_resource_len(pcidev, 0);
-
-        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, 2);
-        mmio_len = pci_resource_len(pcidev, 2);
-
-        DBG_ERROR("sxg: %s rel_region(2) start[%x] len[%x]\n", __func__,
-                  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(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);
-	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);
-
-	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", __func__, dev->name);
-	return (STATUS_SUCCESS);
-}
-
-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);*/
-	switch (cmd) {
-	case SIOCSLICSETINTAGG:
-		{
-			/* 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");
-				return -EFAULT;
-			}
-			intagg = data[0];
-			printk(KERN_EMERG
-			       "%s: set interrupt aggregation to %d\n",
-			       __func__, intagg);
-			return 0;
-		}
-
-	default:
-		/* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
-		return -EOPNOTSUPP;
-	}
-	return 0;
-}
-
-#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
- *
- * Return:
- *		0   regardless of outcome    XXXTODO refer to e1000 driver
- */
-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);
-	 */
-
-	/* Check the adapter state */
-	switch (adapter->State) {
-	case SXG_STATE_INITIALIZING:
-	case SXG_STATE_HALTED:
-	case SXG_STATE_SHUTDOWN:
-		ASSERT(0);	/* unexpected */
-		/* fall through */
-	case SXG_STATE_RESETTING:
-	case SXG_STATE_SLEEP:
-	case SXG_STATE_BOOTDIAG:
-	case SXG_STATE_DIAG:
-	case SXG_STATE_HALTING:
-		status = STATUS_FAILURE;
-		break;
-	case SXG_STATE_RUNNING:
-		if (adapter->LinkState != SXG_LINK_UP) {
-			status = STATUS_FAILURE;
-		}
-		break;
-	default:
-		ASSERT(0);
-		status = STATUS_FAILURE;
-	}
-	if (status != STATUS_SUCCESS) {
-		goto xmit_fail;
-	}
-	/* send a packet */
-	status = sxg_transmit_packet(adapter, skb);
-	if (status == STATUS_SUCCESS) {
-		goto xmit_done;
-	}
-
-      xmit_fail:
-	/* reject & complete all the packets if they cant be sent */
-	if (status != STATUS_SUCCESS) {
-#if XXXTODO
-	/* 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 NETDEV_TX_OK;
-}
-
-/*
- * sxg_transmit_packet
- *
- * This function transmits a single packet.
- *
- * Arguments -
- *		adapter			- Pointer to our adapter structure
- *      skb             - The packet to be sent
- *
- * Return - STATUS of send
- */
-static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
-{
-	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.
-	 */
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend",
-		  adapter, skb, 0, 0);
-
-	/* Allocate a SGL buffer */
-	SXG_GET_SGL_BUFFER(adapter, SxgSgl, 0);
-	if (!SxgSgl) {
-		adapter->Stats.NoSglBuf++;
-		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; */
-	SxgSgl->VlanTag.VlanTci = 0;
-	SxgSgl->VlanTag.VlanTpid = 0;
-	SxgSgl->Type = SXG_SGL_DUMB;
-	SxgSgl->DumbPacket = skb;
-	pSgl = NULL;
-
-	/* Call the common sxg_dumb_sgl routine to complete the send. */
-	return (sxg_dumb_sgl(pSgl, SxgSgl));
-}
-
-/*
- * sxg_dumb_sgl
- *
- * Arguments:
- *		pSgl     -
- *		SxgSgl   - struct sxg_scatter_gather
- *
- * Return Value:
- * 	Status of send operation.
- */
-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; */
-	u32 DataLength = skb->len;
-	/* unsigned int BufLen; */
-	/* u32 SglOffset; */
-	u64 phys_addr;
-	unsigned long flags;
-	unsigned long queue_id=0;
-	int offload_cksum = 0;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
-		  pSgl, SxgSgl, 0, 0);
-
-	/* Set aside a pointer to the sgl */
-	SxgSgl->pSgl = pSgl;
-
-	/* Sanity check that our SGL format is as we expect. */
-	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.
-	 */
-
-	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)
-			offload_cksum = 1;
-		if (!offload_cksum || !tcp_hdr(skb))
-			queue_id = 0;
-		else if (offload_cksum && (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)
-			offload_cksum = 1;
-		if (!offload_cksum || !tcp_hdr(skb))
-			queue_id = 0;
-		else if (offload_cksum && (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_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_irqrestore(&adapter->XmtZeroLock, flags);
-		sxg_complete_slow_send(adapter);
-		spin_lock_irqsave(&adapter->XmtZeroLock, flags);
-		SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
-		if (XmtCmd == NULL) {
-			adapter->Stats.XmtZeroFull++;
-			goto abortcmd;
-		}
-	}
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
-		  XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
-	memset(XmtCmd, '\0', sizeof(*XmtCmd));
-	XmtCmd->SgEntries = 1;
-	XmtCmd->Flags = 0;
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		/*
-		 * We need to set the Checkum in IP  header to 0. This is
-		 * required by hardware.
-		 */
-		if (offload_cksum) {
-			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;
-		} else {
-			if (skb_checksum_help(skb)){
-				printk(KERN_EMERG "Dropped UDP packet for"
-					" incorrect checksum calculation\n");
-				if (XmtCmd)
-					SXG_ABORT_CMD(XmtRingInfo);
-				spin_unlock_irqrestore(&adapter->XmtZeroLock,
-							 flags);
-				return STATUS_SUCCESS;
-			}
-		}
-	}
-
-	/*
-	 * 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);
-
-	/*
-	 * 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);
-		if (XmtCmd)
-			SXG_ABORT_CMD(XmtRingInfo);
-		/* Silently drop this packet */
-		printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n");
-		return STATUS_SUCCESS;
-	}
-	XmtCmd->Buffer.FirstSgeAddress = phys_addr;
-	XmtCmd->Buffer.FirstSgeLength = DataLength;
-	XmtCmd->Buffer.SgeOffset = 0;
-	XmtCmd->Buffer.TotalLength = DataLength;
-
-	/*
-	 * 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 */
-	/* Update stats */
-	adapter->stats.tx_packets++;
-	adapter->stats.tx_bytes += DataLength;
-#if XXXTODO			/* Stats stuff */
-	if (SXG_MULTICAST_PACKET(EtherHdr)) {
-		if (SXG_BROADCAST_PACKET(EtherHdr)) {
-			adapter->Stats.DumbXmtBcastPkts++;
-			adapter->Stats.DumbXmtBcastBytes += DataLength;
-		} else {
-			adapter->Stats.DumbXmtMcastPkts++;
-			adapter->Stats.DumbXmtMcastBytes += DataLength;
-		}
-	} else {
-		adapter->Stats.DumbXmtUcastPkts++;
-		adapter->Stats.DumbXmtUcastBytes += DataLength;
-	}
-#endif
-
-	spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
-		  XmtCmd, pSgl, SxgSgl, 0);
-	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.
-	 */
-	if (XmtCmd) {
-		SXG_ABORT_CMD(XmtRingInfo);
-	}
-	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 -
- *	adapter		- A pointer to our adapter structure
- *
- * Return
- *	status
- */
-static int sxg_initialize_link(struct adapter_t *adapter)
-{
-	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",
-		  adapter, 0, 0, 0);
-
-	/* Reset PHY and XGXS module */
-	WRITE_REG(HwRegs->LinkStatus, LS_SERDES_POWER_DOWN, TRUE);
-
-	/* Reset transmit configuration register */
-	WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_RESET, TRUE);
-
-	/* Reset receive configuration register */
-	WRITE_REG(HwRegs->RcvConfig, RCV_CONFIG_RESET, TRUE);
-
-	/* 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;
-	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);
-	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);
-	WRITE_REG(HwRegs->MacAddressHigh, Value, TRUE);
-	/* Link address 1 */
-	WRITE_REG(HwRegs->LinkAddress1Low, 0, TRUE);
-	WRITE_REG(HwRegs->LinkAddress1High, 0, TRUE);
-	/* Link address 2 */
-	WRITE_REG(HwRegs->LinkAddress2Low, 0, TRUE);
-	WRITE_REG(HwRegs->LinkAddress2High, 0, TRUE);
-	/* Link address 3 */
-	WRITE_REG(HwRegs->LinkAddress3Low, 0, TRUE);
-	WRITE_REG(HwRegs->LinkAddress3High, 0, TRUE);
-
-	/* Enable MAC modules */
-	WRITE_REG(HwRegs->MacConfig0, 0, TRUE);
-
-	/* Configure MAC */
-	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.
-	 */
-	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);
-	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.
-	 */
-	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);
-	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 */
-		return (STATUS_FAILURE);
-
-	/* The SERDES should be initialized by now - confirm */
-	READ_REG(HwRegs->LinkStatus, Value);
-	if (Value & LS_SERDES_DOWN)	/* verify SERDES is initialized */
-		return (STATUS_FAILURE);
-
-	/* The XAUI link should also be up - confirm */
-	if (!(Value & LS_XAUI_LINK_UP))	/* verify XAUI link is up */
-		return (STATUS_FAILURE);
-
-	/* Initialize the PHY */
-	status = sxg_phy_init(adapter);
-	if (status != STATUS_SUCCESS)
-		return (STATUS_FAILURE);
-
-	/* Enable the Link Alarm */
-
-	/* 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 */
-
-	/* 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)) {
-		DBG_ERROR("Error!  LASI Control Alarm Enable bit not set!\n");
-	}
-	/* Enable receive */
-	MaxFrame = adapter->JumboEnabled ? JUMBOMAXFRAME : ETHERMAXFRAME;
-	ConfigData = (RCV_CONFIG_ENABLE |
-		      RCV_CONFIG_ENPARSE |
-		      RCV_CONFIG_RCVBAD |
-		      RCV_CONFIG_RCVPAUSE |
-		      RCV_CONFIG_TZIPV6 |
-		      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);
-
-	/* Mark the link as down.  We'll get a link event when it comes up. */
-	sxg_link_state(adapter, SXG_LINK_DOWN);
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInitLnk",
-		  adapter, 0, 0, 0);
-	return (STATUS_SUCCESS);
-}
-
-/*
- * sxg_phy_init - Initialize the PHY
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *
- * Return
- *	status
- */
-static int sxg_phy_init(struct adapter_t *adapter)
-{
-	u32 Value;
-	struct phy_ucode *p;
-	int status;
-
-	DBG_ERROR("ENTER %s\n", __func__);
-
-	/* 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");
-
-		/* Initialize AEL2005C PHY and download PHY microcode */
-		for (p = PhyUcode; p->Addr != 0xFFFF; p++) {
-			if (p->Addr == 0) {
-				/* 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 address */
-							    p->Addr,
-							/* PHY data */
-							    p->Data);
-				if (status != STATUS_SUCCESS)
-					return (STATUS_FAILURE);
-			}
-		}
-	}
-	DBG_ERROR("EXIT %s\n", __func__);
-
-	return (STATUS_SUCCESS);
-}
-
-/*
- * sxg_link_event - Process a link event notification from the card
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *
- * Return
- *	None
- */
-static void sxg_link_event(struct adapter_t *adapter)
-{
-	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__);
-
-	/* 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)
-		 */
-		mdelay(10);
-
-		/* Now clear the alarm by reading the 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); */
-		}
-		/*
-		 * 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.
-	 	 */
-		DBG_ERROR("SXG: sxg_link_event: Can't get here!\n");
-		DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value);
-		/* ASSERT(0); */
-	}
-	DBG_ERROR("EXIT %s\n", __func__);
-
-}
-
-/*
- * sxg_get_link_state - Determine if the link is up or down
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *
- * Return
- *	Link State
- */
-static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
-{
-	int status;
-	u32 Value;
-
-	DBG_ERROR("ENTER %s\n", __func__);
-
-	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.
-	 */
-
-	/* 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;
-
-	/* If PMA/PMD receive signal detect is 0, then the link is down */
-	if (!(Value & PMA_RCV_DETECT))
-		return (SXG_LINK_DOWN);
-
-	/* 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;
-
-	/* If PCS is not locked to receive blocks, then the link is down */
-	if (!(Value & PCS_10B_BLOCK_LOCK))
-		return (SXG_LINK_DOWN);
-
-	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;
-
-	/* If XS transmit lanes are not aligned, then the link is down */
-	if (!(Value & XS_LANE_ALIGN))
-		return (SXG_LINK_DOWN);
-
-	/* All 3 bits are true, so the link is up */
-	DBG_ERROR("EXIT %s\n", __func__);
-
-	return (SXG_LINK_UP);
-
-      bad:
-	/* 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);
-}
-
-static void sxg_indicate_link_state(struct adapter_t *adapter,
-				    enum SXG_LINK_STATE LinkState)
-{
-	if (adapter->LinkState == SXG_LINK_UP) {
-		DBG_ERROR("%s: LINK now UP, call netif_start_queue\n",
-			  __func__);
-		netif_start_queue(adapter->netdev);
-	} else {
-		DBG_ERROR("%s: LINK now DOWN, call netif_stop_queue\n",
-			  __func__);
-		netif_stop_queue(adapter->netdev);
-	}
-}
-
-/*
- * 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
- *	link state indications
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *	LinkState 	- The link state
- *
- * Return
- *	None
- */
-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.
-	 */
-	/* 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. 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);
-	DBG_ERROR("EXIT #1 %s\n", __func__);
-
-	sxg_indicate_link_state(adapter, LinkState);
-}
-
-/*
- * sxg_write_mdio_reg - Write to a register on the MDIO bus
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *  DevAddr     - MDIO device number being addressed
- *  RegAddr     - register address for the specified MDIO device
- *  Value		- value to write to the MDIO register
- *
- * Return
- *	status
- */
-static int sxg_write_mdio_reg(struct adapter_t *adapter,
-			      u32 DevAddr, u32 RegAddr, u32 Value)
-{
-	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__); */
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
-		  adapter, 0, 0, 0);
-
-	/* Ensure values don't exceed field width */
-	DevAddr &= 0x001F;	/* 5-bit field */
-	RegAddr &= 0xFFFF;	/* 16-bit field */
-	Value &= 0xFFFF;	/* 16-bit field */
-
-	/* Set MIIM field register bits for an MIIM address operation */
-	AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
-	    (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
-	    (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
-	    (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
-
-	/* Set MIIM field register bits for an MIIM write operation */
-	WriteOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
-	    (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
-	    (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
-	    (MIIM_OP_WRITE << AXGMAC_AMIIM_FIELD_OP_SHIFT) | Value;
-
-	/* Set MIIM command register bits to execute an MIIM command */
-	Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
-
-	/* Reset the command register command bit (in case it's not 0) */
-	WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
-
-	/* MIIM write to set the address of the specified MDIO register */
-	WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
-
-	/* Write to MIIM Command Register to execute to address operation */
-	WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
-
-	/* Poll AMIIM Indicator register to wait for completion */
-	Timeout = SXG_LINK_TIMEOUT;
-	do {
-		udelay(100);	/* Timeout in 100us units */
-		READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
-		if (--Timeout == 0) {
-			return (STATUS_FAILURE);
-		}
-	} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
-
-	/* Reset the command register command bit */
-	WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
-
-	/* MIIM write to set up an MDIO write operation */
-	WRITE_REG(HwRegs->MacAmiimField, WriteOp, TRUE);
-
-	/* Write to MIIM Command Register to execute the write operation */
-	WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
-
-	/* Poll AMIIM Indicator register to wait for completion */
-	Timeout = SXG_LINK_TIMEOUT;
-	do {
-		udelay(100);	/* Timeout in 100us units */
-		READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
-		if (--Timeout == 0) {
-			return (STATUS_FAILURE);
-		}
-	} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
-
-	/* DBG_ERROR("EXIT %s\n", __func__); */
-
-	return (STATUS_SUCCESS);
-}
-
-/*
- * sxg_read_mdio_reg - Read a register on the MDIO bus
- *
- * Arguments -
- *	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
- *
- * Return
- *	status
- */
-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) */
-	u32 ValueRead;
-	u32 Timeout;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
-		  adapter, 0, 0, 0);
-	DBG_ERROR("ENTER %s\n", __func__);
-
-	/* Ensure values don't exceed field width */
-	DevAddr &= 0x001F;	/* 5-bit field */
-	RegAddr &= 0xFFFF;	/* 16-bit field */
-
-	/* Set MIIM field register bits for an MIIM address operation */
-	AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
-	    (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
-	    (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
-	    (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
-
-	/* Set MIIM field register bits for an MIIM read operation */
-	ReadOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
-	    (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
-	    (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
-	    (MIIM_OP_READ << AXGMAC_AMIIM_FIELD_OP_SHIFT);
-
-	/* Set MIIM command register bits to execute an MIIM command */
-	Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
-
-	/* Reset the command register command bit (in case it's not 0) */
-	WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
-
-	/* MIIM write to set the address of the specified MDIO register */
-	WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
-
-	/* Write to MIIM Command Register to execute to address operation */
-	WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
-
-	/* Poll AMIIM Indicator register to wait for completion */
-	Timeout = SXG_LINK_TIMEOUT;
-	do {
-		udelay(100);	/* Timeout in 100us units */
-		READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
-		if (--Timeout == 0) {
-            DBG_ERROR("EXIT %s with STATUS_FAILURE 1\n", __func__);
-
-			return (STATUS_FAILURE);
-		}
-	} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
-
-	/* Reset the command register command bit */
-	WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
-
-	/* MIIM write to set up an MDIO register read operation */
-	WRITE_REG(HwRegs->MacAmiimField, ReadOp, TRUE);
-
-	/* Write to MIIM Command Register to execute the read operation */
-	WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
-
-	/* Poll AMIIM Indicator register to wait for completion */
-	Timeout = SXG_LINK_TIMEOUT;
-	do {
-		udelay(100);	/* Timeout in 100us units */
-		READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
-		if (--Timeout == 0) {
-            DBG_ERROR("EXIT %s with STATUS_FAILURE 2\n", __func__);
-
-			return (STATUS_FAILURE);
-		}
-	} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
-
-	/* Read the MDIO register data back from the field register */
-	READ_REG(HwRegs->MacAmiimField, *pValue);
-	*pValue &= 0xFFFF;	/* data is in the lower 16 bits */
-
-	DBG_ERROR("EXIT %s\n", __func__);
-
-	return (STATUS_SUCCESS);
-}
-
-/*
- * 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.
- *
- * 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_init;	/* Is table initialized */
-
-/* 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 */
-	int k;			/*  byte being shifted into crc  */
-
-	static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
-
-	for (i = 0; i < sizeof(p) / sizeof(int); i++) {
-		e |= 1L << (31 - p[i]);
-	}
-
-	for (i = 1; i < 256; i++) {
-		c = i;
-		for (k = 8; k; k--) {
-			c = c & 1 ? (c >> 1) ^ e : c >> 1;
-		}
-		sxg_crc_table[i] = c;
-	}
-}
-
-/*
- *  Return the MAC hast as described above.
- */
-static unsigned char sxg_mcast_get_mac_hash(char *macaddr)
-{
-	u32 crc;
-	char *p;
-	int i;
-	unsigned char machash = 0;
-
-	if (!sxg_crc_init) {
-		sxg_mcast_init_crc32();
-		sxg_crc_init = 1;
-	}
-
-	crc = 0xFFFFFFFF;	/* Preload shift register, per crc-32 spec */
-	for (i = 0, p = macaddr; i < 6; ++p, ++i) {
-		crc = (crc >> 8) ^ sxg_crc_table[(crc ^ *p) & 0xFF];
-	}
-
-	/* Return bits 1-8, transposed */
-	for (i = 1; i < 9; i++) {
-		machash |= (((crc >> i) & 1) << (8 - i));
-	}
-
-	return (machash);
-}
-
-static void sxg_mcast_set_mask(struct adapter_t *adapter)
-{
-	struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs;
-
-	DBG_ERROR("%s ENTER (%s) MacFilter[%x] mask[%llx]\n", __func__,
-		  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 keep state about the MAC configuration
-		 */
-		/* 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);
-		 */
-
-	} else {
-		/*
-		 * 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,
-			  ((ulong) (adapter->MulticastMask & 0xFFFFFFFF)),
-			  ((ulong)
-			   ((adapter->MulticastMask >> 32) & 0xFFFFFFFF)));
-
-		WRITE_REG(sxg_regs->McastLow,
-			  (u32) (adapter->MulticastMask & 0xFFFFFFFF), FLUSH);
-		WRITE_REG(sxg_regs->McastHigh,
-			  (u32) ((adapter->
-				  MulticastMask >> 32) & 0xFFFFFFFF), FLUSH);
-	}
-}
-
-static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
-{
-	unsigned char crcpoly;
-
-	/* 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
-	 * off the top two bits. (2^6 = 64)
-	 */
-	crcpoly &= 0x3F;
-
-	/* OR in the new bit into our 64 bit mask. */
-	adapter->MulticastMask |= (u64) 1 << crcpoly;
-}
-
-/*
- *   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);
-
-	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;
-
-	//XXX handle other flags as well
-	sxg_set_mcast_addr(adapter);
-}
-
-void sxg_free_sgl_buffers(struct adapter_t *adapter)
-{
-        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--;
-        }
-}
-
-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);
-}
-
-
-
-/*
- * sxg_free_resources - Free everything allocated in SxgAllocateResources
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *
- * Return
- *	none
- */
-void sxg_free_resources(struct adapter_t *adapter)
-{
-	u32 RssIds, IsrCount;
-	RssIds = SXG_RSS_CPU_COUNT(adapter);
-	IsrCount = adapter->msi_enabled ? RssIds : 1;
-
-	if (adapter->BasicAllocations == FALSE) {
-		/*
-		 * No allocations have been made, including spinlocks,
-		 * or listhead initializations.  Return.
-		 */
-		return;
-	}
-
-	if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
-		sxg_free_rcvblocks(adapter);
-	}
-	if (!(IsListEmpty(&adapter->AllSglBuffers))) {
-		sxg_free_sgl_buffers(adapter);
-	}
-
-	if (adapter->XmtRingZeroIndex) {
-		pci_free_consistent(adapter->pcidev,
-				    sizeof(u32),
-				    adapter->XmtRingZeroIndex,
-				    adapter->PXmtRingZeroIndex);
-	}
-        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;
-	}
-
-
-	/* Unmap register spaces */
-	sxg_unmap_resources(adapter);
-
-	sxg_free_mcast_addrs(adapter);
-
-	adapter->BasicAllocations = FALSE;
-
-}
-
-/*
- * sxg_allocate_complete -
- *
- * This routine is called when a memory allocation has completed.
- *
- * Arguments -
- *	struct adapter_t *   	- Our adapter structure
- *	VirtualAddress	- Memory virtual address
- *	PhysicalAddress	- Memory physical address
- *	Length		- Length of memory allocated (or 0)
- *	Context		- The type of buffer allocated
- *
- * Return
- *	None.
- */
-static int sxg_allocate_complete(struct adapter_t *adapter,
-				  void *VirtualAddress,
-				  dma_addr_t PhysicalAddress,
-				  u32 Length, enum sxg_buffer_type Context)
-{
-	int status = 0;
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp",
-		  adapter, VirtualAddress, Length, Context);
-	ASSERT(atomic_read(&adapter->pending_allocations));
-	atomic_dec(&adapter->pending_allocations);
-
-	switch (Context) {
-
-	case SXG_BUFFER_TYPE_RCV:
-		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 *)
-						 VirtualAddress,
-						 PhysicalAddress, Length);
-		break;
-	}
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp",
-		  adapter, VirtualAddress, Length, Context);
-
-	return status;
-}
-
-/*
- * sxg_allocate_buffer_memory - Shared memory allocation routine used for
- *		synchronous and asynchronous buffer allocations
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *	Size		- block size to allocate
- *	BufferType	- Type of buffer to allocate
- *
- * Return
- *	int
- */
-static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
-				      u32 Size, enum sxg_buffer_type BufferType)
-{
-	int status;
-	void *Buffer;
-	dma_addr_t pBuffer;
-
-	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
-	 */
-
- 	atomic_inc(&adapter->pending_allocations);
-
-	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) {
-		/*
-		 * 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);
-	}
-	status = sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem",
-		  adapter, Size, BufferType, status);
-	return status;
-}
-
-/*
- * sxg_allocate_rcvblock_complete - Complete a receive descriptor
- * 					block allocation
- *
- * Arguments -
- *	adapter				- A pointer to our adapter structure
- *	RcvBlock			- receive block virtual address
- *	PhysicalAddress		- Physical address
- *	Length				- Memory length
- *
- * Return
- */
-static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
-					   void *RcvBlock,
-					   dma_addr_t PhysicalAddress,
-					   u32 Length)
-{
-	u32 i;
-	u32 BufferSize = adapter->ReceiveBufferSize;
-	u64 Paddr;
-	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);
-	if (RcvBlock == NULL) {
-		goto fail;
-	}
-	memset(RcvBlock, 0, Length);
-	ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
-	       (BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
-	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;
-
-	}
-
-	/*
-	 * 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(SXG_RCV_DATA_HDR_SIZE));
-	RcvBlockHdr->VirtualAddress = RcvBlock;
-	RcvBlockHdr->PhysicalAddress = PhysicalAddress;
-	spin_lock(&adapter->RcvQLock);
-	adapter->AllRcvBlockCount++;
-	InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList);
-	spin_unlock(&adapter->RcvQLock);
-
-	/* 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 += 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);
-	}
-
-	/* Locate the descriptor block and put it on a separate free queue */
-	RcvDescriptorBlock =
-	    (struct sxg_rcv_descriptor_block *) ((unsigned char *)RcvBlock +
-					 SXG_RCV_DESCRIPTOR_BLOCK_OFFSET
-					 (SXG_RCV_DATA_HDR_SIZE));
-	RcvDescriptorBlockHdr =
-	    (struct sxg_rcv_descriptor_block_hdr *) ((unsigned char *)RcvBlock +
-					     SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET
-					     (SXG_RCV_DATA_HDR_SIZE));
-	RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock;
-	RcvDescriptorBlockHdr->PhysicalAddress = Paddr;
-	spin_lock(&adapter->RcvQLock);
-	SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, RcvDescriptorBlockHdr);
-	spin_unlock(&adapter->RcvQLock);
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk",
-		  adapter, RcvBlock, Length, 0);
-	return STATUS_SUCCESS;
-fail:
-	/* Free any allocated resources */
-	if (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;
-			SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
-		}
-		pci_free_consistent(adapter->pcidev,
-				    Length, RcvBlock, PhysicalAddress);
-	}
-	DBG_ERROR("%s: OUT OF RESOURCES\n", __func__);
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "RcvAFail",
-		  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;
-}
-
-/*
- * sxg_allocate_sgl_buffer_complete - Complete a SGL buffer allocation
- *
- * Arguments -
- *	adapter				- A pointer to our adapter structure
- *	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,
-					     dma_addr_t PhysicalAddress,
-					     u32 Length)
-{
-	unsigned long sgl_flags;
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
-		  adapter, SxgSgl, Length, 0);
-	spin_lock_irqsave(&adapter->SglQLock, sgl_flags);
-	adapter->AllSglBufferCount++;
-	/* PhysicalAddress; */
-	SxgSgl->PhysicalAddress = PhysicalAddress;
-	/* Initialize backpointer once */
-	SxgSgl->adapter = adapter;
-	InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
-	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 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 AFTER copying from config.macinfo into currmacaddr\n",
-	 *	   		__func__);
-	 */
-
-	/* sxg_dbg_macaddrs(adapter); */
-
-	struct net_device * dev = adapter->netdev;
-	if(!dev)
-	{
-		printk("sxg: Dev is Null\n");
-	}
-
-        DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name);
-
-        if (netif_running(dev)) {
-                return -EBUSY;
-        }
-        if (!adapter) {
-                return -EBUSY;
-        }
-
-	if (!(adapter->currmacaddr[0] ||
-	      adapter->currmacaddr[1] ||
-	      adapter->currmacaddr[2] ||
-	      adapter->currmacaddr[3] ||
-	      adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
-		memcpy(adapter->currmacaddr, adapter->macaddr, 6);
-	}
-	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); */
-	sxg_dbg_macaddrs(adapter);
-
-	return 0;
-}
-
-#if XXXTODO
-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;
-
-	DBG_ERROR("%s ENTER (%s)\n", __func__, adapter->netdev->name);
-
-	if (netif_running(dev)) {
-		return -EBUSY;
-	}
-	if (!adapter) {
-		return -EBUSY;
-	}
-	DBG_ERROR("sxg: %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_ERROR("sxg: %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]);
-
-	sxg_config_set(adapter, TRUE);
-	return 0;
-}
-#endif
-
-/*
- * SXG DRIVER FUNCTIONS  (below)
- *
- * sxg_initialize_adapter - Initialize adapter
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *
- * 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->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);
-
-	/* Disable interrupts */
-	SXG_DISABLE_ALL_INTERRUPTS(adapter);
-
-	/* Set MTU */
-	ASSERT((adapter->FrameSize == ETHERMAXFRAME) ||
-	       (adapter->FrameSize == JUMBOMAXFRAME));
-	WRITE_REG(adapter->UcodeRegs[0].LinkMtu, adapter->FrameSize, TRUE);
-
-	/* Set event ring base address and size */
-	WRITE_REG64(adapter,
-		    adapter->UcodeRegs[0].EventBase, adapter->PEventRings, 0);
-	WRITE_REG(adapter->UcodeRegs[0].EventSize, EVENT_RING_SIZE, TRUE);
-
-	/* Per-ISR initialization */
-	for (i = 0; i < IsrCount; i++) {
-		u64 Addr;
-		/* Set interrupt status pointer */
-		Addr = adapter->PIsr + (i * sizeof(u32));
-		WRITE_REG64(adapter, adapter->UcodeRegs[i].Isp, Addr, i);
-	}
-
-	/* XMT ring zero index */
-	WRITE_REG64(adapter,
-		    adapter->UcodeRegs[0].SPSendIndex,
-		    adapter->PXmtRingZeroIndex, 0);
-
-	/* Per-RSS initialization */
-	for (i = 0; i < RssIds; i++) {
-		/* Release all event ring entries to the Microcode */
-		WRITE_REG(adapter->UcodeRegs[i].EventRelease, EVENT_RING_SIZE,
-			  TRUE);
-	}
-
-	/* Transmit ring base and size */
-	WRITE_REG64(adapter,
-		    adapter->UcodeRegs[0].XmtBase, adapter->PXmtRings, 0);
-	WRITE_REG(adapter->UcodeRegs[0].XmtSize, SXG_XMT_RING_SIZE, TRUE);
-
-	/* Receive ring base and size */
-	WRITE_REG64(adapter,
-		    adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0);
-	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.
-	 */
-	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);
-	DBG_ERROR("sxg: %s EXIT sxg_initialize_link status[%x]\n", __func__,
-		  status);
-	if (status != STATUS_SUCCESS) {
-		return (status);
-	}
-	/*
-	 * 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);
-	return (STATUS_SUCCESS);
-}
-
-/*
- * sxg_fill_descriptor_block - Populate a descriptor block and give it to
- * the card.  The caller should hold the RcvQLock
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *  RcvDescriptorBlockHdr	- Descriptor block to fill
- *
- * Return
- *	status
- */
-static int sxg_fill_descriptor_block(struct adapter_t *adapter,
-	     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];
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk",
-		  adapter, adapter->RcvBuffersOnCard,
-		  adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
-
-	ASSERT(RcvDescriptorBlockHdr);
-
-	/*
-	 * 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++;
-		return (STATUS_FAILURE);
-	}
-	/* Get a ring descriptor command */
-	SXG_GET_CMD(RingZero,
-		    RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr);
-	ASSERT(RingDescriptorCmd);
-	RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD;
-	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;
-
-		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.
-	 */
-	adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk",
-		  RcvDescriptorBlockHdr,
-		  RingDescriptorCmd, RcvRingInfo->Head, RcvRingInfo->Tail);
-
-	WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 1, true);
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlk",
-		  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);
-}
-
-/*
- * sxg_stock_rcv_buffers - Stock the card with receive buffers
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *
- * Return
- *	None
- */
-static void sxg_stock_rcv_buffers(struct adapter_t *adapter)
-{
-	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->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) &&
-	    (atomic_read(&adapter->pending_allocations) == 0)) {
-		sxg_allocate_buffer_memory(adapter,
-					   SXG_RCV_BLOCK_SIZE
-					   (SXG_RCV_DATA_HDR_SIZE),
-					   SXG_BUFFER_TYPE_RCV);
-	}
-	/* Now grab the RcvQLock lock and proceed */
-	spin_lock(&adapter->RcvQLock);
-	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,
-					 FreeList);
-			adapter->FreeRcvBlockCount--;
-			RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY;
-		}
-
-		if (RcvDescriptorBlockHdr == NULL) {
-			/* Bail out.. */
-			adapter->Stats.NoMem++;
-			break;
-		}
-		/* Fill in the descriptor block and give it to the card */
-		if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
-		    STATUS_FAILURE) {
-			/* Free the descriptor block */
-			SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
-						      RcvDescriptorBlockHdr);
-			break;
-		}
-	}
-	spin_unlock(&adapter->RcvQLock);
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlks",
-		  adapter, adapter->RcvBuffersOnCard,
-		  adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
-}
-
-/*
- * sxg_complete_descriptor_blocks - Return descriptor blocks that have been
- * completed by the microcode
- *
- * Arguments -
- *	adapter		- A pointer to our adapter structure
- *	Index		- Where the microcode is up to
- *
- * Return
- *	None
- */
-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;
-
-	SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks",
-		  adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
-
-	/* Now grab the RcvQLock lock and proceed */
-	spin_lock(&adapter->RcvQLock);
-	ASSERT(Index != RcvRingInfo->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);
-		SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlk",
-			  RcvRingInfo->Head, RcvRingInfo->Tail,
-			  RingDescriptorCmd, RcvDescriptorBlockHdr);
-
-		/* 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)
-			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 = sxg_driver_name,
-	.id_table = sxg_pci_tbl,
-	.probe = sxg_entry_probe,
-	.remove = __devexit_p(sxg_entry_remove),
-#if SXG_POWER_MANAGEMENT_ENABLED
-	.suspend = sxgpm_suspend,
-	.resume = sxgpm_resume,
-#endif
-	/* .shutdown   =     slic_shutdown,  MOOK_INVESTIGATE */
-};
-
-static int __init sxg_module_init(void)
-{
-	sxg_init_driver();
-
-	if (debug >= 0)
-		sxg_debug = debug;
-
-	return pci_register_driver(&sxg_driver);
-}
-
-static void __exit sxg_module_cleanup(void)
-{
-	pci_unregister_driver(&sxg_driver);
-}
-
-module_init(sxg_module_init);
-module_exit(sxg_module_cleanup);
diff --git a/drivers/staging/sxg/sxg.h b/drivers/staging/sxg/sxg.h
deleted file mode 100644
index f07aa70..0000000
--- a/drivers/staging/sxg/sxg.h
+++ /dev/null
@@ -1,787 +0,0 @@
-/**************************************************************************
- *
- * Copyright © 2000-2008 Alacritech, Inc.  All rights reserved.
- *
- * $Id: sxg.h,v 1.3 2008/07/24 17:25:08 chris Exp $
- *
- * 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.h
- *
- * This is the base set of header definitions for the SXG driver.
- */
-#ifndef __SXG_DRIVER_H__
-#define __SXG_DRIVER_H__
-
-#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 */
-
-#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);							\
-}
-
-/*
- * 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 */
-#define PSXG_PACKET       struct sk_buff *
-/* Indications array size */
-#define SXG_RCV_ARRAYSIZE	64
-
-#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);		\
-    }                                                                  	\
-}
-
-/*
- * 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_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) (((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_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));			\
-}
-
-#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;						\
-}
-
-#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);			\
-	}									\
-}
-
-#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++;						\
-	ASSERT((_pAdapt)->AllRcvBlockCount >= (_pAdapt)->FreeRcvBlockCount);	\
-	InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList);		\
-}
-
-/* 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, _irq) {			\
-	struct list_entry *_ple;					\
-	if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) &&	\
-	   (_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) &&	\
-	   (atomic_read(&_pAdapt->pending_allocations) == 0)) {		\
-		sxg_allocate_buffer_memory(_pAdapt,			\
-			(sizeof(struct sxg_scatter_gather) + SXG_SGL_BUF_SIZE),\
-			SXG_BUFFER_TYPE_SGL);				\
-	}								\
-	_Sgl = NULL;							\
-	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); 		\
-            (_pAdapt)->FreeSglBufferCount--;				\
-		ASSERT((_Sgl)->State == SXG_BUFFER_FREE);		\
-		(_Sgl)->State = SXG_BUFFER_BUSY;			\
-		(_Sgl)->pSgl = NULL;					\
-	}								\
-	if(!_irq)							\
-		spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
-	else								\
-		spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
-}
-
-/*
- * 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 */
-};
-
-#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 {							\
-		(_Buffer)->Direction = NDIS_SG_LIST_WRITE_TO_DEVICE;	\
-	}								\
-	(_Buffer)->Bytes = 0;						\
-	(_Buffer)->Head = NULL;						\
-	(_Buffer)->Tail = NULL;						\
-}
-
-
-#define SXG_RSS_CPU_COUNT(_pAdapt) 					\
-	((_pAdapt)->RssEnabled 	?  NR_CPUS : 1)
-
-/* DRIVER and ADAPTER structures */
-
-/*
- * 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 */
-};
-
-/* 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! */
-
-
-/* Microcode file selection codes */
-enum SXG_UCODE_SEL {
-	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 */
-#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))
-
-/* For DbgPrints */
-#define SXG_ID      DPFLTR_IHVNETWORK_ID
-#define SXG_ERROR   DPFLTR_ERROR_LEVEL
-
-/*
- * 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
-#define STATUS_ERROR               -2
-#define STATUS_NOT_SUPPORTED       -3
-#define STATUS_BUFFER_TOO_SHORT    -4
-#define STATUS_RESOURCES           -5
-
-#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
-
-#define MIN(a, b) ((u32)(a) < (u32)(b) ? (a) : (b))
-#define MAX(a, b) ((u32)(a) > (u32)(b) ? (a) : (b))
-
-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 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
-#define ADAPT_FLAGS_PENDINGLINKDOWN     0x0004
-#define ADAPT_FLAGS_FIBERMEDIA          0x0008
-#define ADAPT_FLAGS_LOCKS_ALLOCED       0x0010
-#define ADAPT_FLAGS_INT_REGISTERED      0x0020
-#define ADAPT_FLAGS_LOAD_TIMER_SET      0x0040
-#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_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 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_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")
-
-
-struct ether_header {
-    unsigned char    ether_dhost[6];
-    unsigned char    ether_shost[6];
-    ushort   ether_type;
-};
-
-
-#define NUM_CFG_SPACES      2
-#define NUM_CFG_REGS        64
-
-/*
- * 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 {
-	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	*phys_card;
-};
-
-
-struct adapter_t {
-	void *               ifp;
-	unsigned int                port;
-	struct napi_struct 	napi;
-	struct physcard        *physcard;
-	unsigned int                physport;
-	unsigned int                slotnumber;
-	unsigned int                functionnumber;
-	ushort              vendid;
-	ushort              devid;
-	ushort              subsysid;
-	u32             irq;
-
-	void __iomem *	base_addr;
-	u32             memorylength;
-	u32             drambase;
-	u32             dramlength;
-	enum asic_type	asictype;      /* type of ASIC (chip) */
-	unsigned int                activated;
-	u32             intrregistered;
-	unsigned int                isp_initialized;
-	unsigned char               state;
-	unsigned char               linkstate;
-	unsigned int                flags;
-	unsigned char               macaddr[6];
-	unsigned char               currmacaddr[6];
-	u32             macopts;
-	ushort              devflags_prev;
-	u64             mcastmask;
-	struct mcast_address   *mcastaddrs;
-	struct timer_list   pingtimer;
-	u32             pingtimerset;
-	struct timer_list   statstimer;
-	u32             statstimerset;
-	struct timer_list   vpci_timer;
-	u32             vpci_timerset;
-	struct timer_list   loadtimer;
-	u32             loadtimerset;
-
-	u32             xmitq_full;
-	u32             all_reg_writes;
-	u32             icr_reg_writes;
-	u32             isr_reg_writes;
-	u32             error_interrupts;
-	u32             error_rmiss_interrupts;
-	u32             rx_errors;
-	u32             rcv_drops;
-	u32             rcv_interrupts;
-	u32             xmit_interrupts;
-	u32             linkevent_interrupts;
-	u32             upr_interrupts;
-	u32             num_isrs;
-	u32             false_interrupts;
-	u32             tx_packets;
-	u32             xmit_completes;
-	u32             tx_drops;
-	u32             rcv_broadcasts;
-	u32             rcv_multicasts;
-	u32             rcv_unicasts;
-	u32             max_isr_rcvs;
-	u32             max_isr_xmits;
-	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 */
-	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         	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 */
-
-	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;
-
-	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 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 */
-#endif
-	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
-#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)                        \
-{                                                                        \
-    if ((newstat) < (oldstat))                                           \
-        (largestat) += ((newstat) + (0xFFFFFFFF - oldstat + 1));         \
-    else                                                                 \
-        (largestat) += ((newstat) - (oldstat));                          \
-}
-
-#define UPDATE_STATS_GB(largestat, newstat, oldstat)                     \
-{                                                                        \
-    (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 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)
-#else
-#define   SXG_GET_ADDR_LOW(_addr)   (u32)_addr
-#define   SXG_GET_ADDR_HIGH(_addr)  (u32)0
-#endif
-
-#define FLUSH       TRUE
-#define DONT_FLUSH  FALSE
-
-#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
deleted file mode 100644
index ad89cb8..0000000
--- a/drivers/staging/sxg/sxg_ethtool.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/**************************************************************************
- *
- * 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", __func__);
-                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
deleted file mode 100644
index 68e1a04..0000000
--- a/drivers/staging/sxg/sxg_os.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/**************************************************************************
- *
- * 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_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)
-
-struct list_entry {
-	struct list_entry *nle_flink;
-	struct list_entry *nle_blink;
-};
-
-#define InitializeListHead(l)                   			\
-        (l)->nle_flink = (l)->nle_blink = (l)
-
-#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;               			\
-        } while (0)
-
-/* These two have to be inlined since they return things. */
-
-static inline struct list_entry *RemoveHeadList(struct list_entry *l)
-{
-	struct list_entry *f;
-	struct list_entry *e;
-
-	e = l->nle_flink;
-	f = e->nle_flink;
-	l->nle_flink = f;
-	f->nle_blink = l;
-
-	return (e);
-}
-
-static inline struct list_entry *RemoveTailList(struct list_entry *l)
-{
-	struct list_entry *b;
-	struct list_entry *e;
-
-	e = l->nle_blink;
-	b = e->nle_blink;
-	l->nle_blink = b;
-	b->nle_flink = l;
-
-	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);           			\
-        } 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);           			\
-        } 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;                  	\
-}
-#else
-#define SLIC_TIMESTAMP(value)
-#endif
-
-/* SXG DEFINES */
-
-#ifdef  ATKDBG
-#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 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
deleted file mode 100644
index e613a97..0000000
--- a/drivers/staging/sxg/sxgdbg.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/**************************************************************************
- *
- * Copyright © 2000-2008 Alacritech, Inc.  All rights reserved.
- *
- * $Id: sxgdbg.h,v 1.1 2008/06/27 12:49:28 mook Exp $
- *
- * 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: sxgdbg.h
- *
- * All debug and assertion-based definitions and macros are included
- * in this file for the SXGOSS driver.
- */
-#ifndef _SXG_DEBUG_H_
-#define _SXG_DEBUG_H_
-
-#define ATKDBG  1
-#define ATK_TRACE_ENABLED 0
-
-#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__);                             \
-        }                                                                  \
-    }
-#endif
-#else
-#ifndef ASSERT
-#define ASSERT(a)
-#endif
-#endif /* SXG_ASSERT_ENABLED  */
-
-
-#ifdef ATKDBG
-/*
- *  Global for timer granularity; every driver must have an instance
- *  of this initialized to 0
- */
-
-extern ulong ATKTimerDiv;
-
-/*
- * trace_entry -
- *
- * This structure defines an entry in the trace buffer.  The
- * first few fields mean the same from entry to entry, while
- * the meaning of last several fields change to suit the
- * needs of the trace entry.  Typically they are function call
- * parameters.
- */
-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 struct trace_entry */
-#define TRACE_SXG             1
-#define TRACE_VPCI            2
-#define TRACE_SLIC            3
-
-#define TRACE_ENTRIES   1024
-
-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 */
-};
-
-/*
- * The trace levels
- *
- * XXX At the moment I am only defining critical, important, and noisy.
- * I am leaving room for more if anyone wants them.
- */
-#define TRACE_NONE              0   /* For trace level - if no tracing wanted */
-#define TRACE_CRITICAL          1   /* minimal tracing - only critical stuff */
-#define TRACE_IMPORTANT         5   /* more tracing - anything important */
-#define TRACE_NOISY             10  /* Everything in the world */
-
-
-/* The macros themselves */
-#if ATK_TRACE_ENABLED
-#define SXG_TRACE_INIT(buffer, tlevel)				\
-{								\
-	memset((buffer), 0, sizeof(struct sxg_trace_buffer));	\
-	(buffer)->level = (tlevel);				\
-	(buffer)->size = TRACE_ENTRIES;				\
-	spin_lock_init(&(buffer)->lock);			\
-}
-#else
-#define SXG_TRACE_INIT(buffer, tlevel)
-#endif
-
-/*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	*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)
-#endif
-
-#endif
-
-#endif  /*  _SXG_DEBUG_H_  */
diff --git a/drivers/staging/sxg/sxghif.h b/drivers/staging/sxg/sxghif.h
deleted file mode 100644
index e190d6a..0000000
--- a/drivers/staging/sxg/sxghif.h
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*******************************************************************
- * Copyright © 1997-2007 Alacritech, Inc. All rights reserved
- *
- * $Id: sxghif.h,v 1.5 2008/07/24 19:18:22 chris Exp $
- *
- * sxghif.h:
- *
- * This file contains structures and definitions for the
- * Alacritech Sahara host interface
- ******************************************************************/
-
-#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 */
-	u32 PadEx3[15];
-	/* 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 */
-	u32 PadEx5[15];
-	/* 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 */
-	u32 PadEx7[15];
-	/* 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 */
-	u32 PadEx9[15];
-	/* ExCode 10 = Receive ring size */
-	u32	RcvSize;	/* Code = 0 (extended), ExCode = 10 */
-	u32 PadEx10[15];
-	/* 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 */
-	u32 PadEx12[15];
-	/* 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 */
-	u32 PadEx14[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 */
-	u32 PadEx16[15];
-	/* 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 */
-	u32 PadEx18[15];
-	/* ExCode 19 = Get ucode statistics */
-	u32	GetUcodeStats;	/* Code = 0 (extended), ExCode = 19 */
-	u32 PadEx19[15];
-	/* 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 */
-	u32 PadEx21[15];
-	/* ExCode 22 = ACK Frequency */
-	u32	AckFrequency;	/* Code = 0 (extended), ExCode = 22 */
-	u32 PadEx22[15];
-	/* ExCode 23 = TOE NA */
-	u32 RsvdReg23;
-	u32 PadEx23[15];
-	/* ExCode 24 = TOE NA */
-	u32 RsvdReg24;
-	u32 PadEx24[15];
-	/* 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 */
-	u32 PadEx26[15];
-	/* 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 */
-	u32 PadEx28[15];
-	/* 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 */
-	u32 PadEx30[15];
-	/* 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 */
-	u32 PadEx32[15];
-	/* 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)*/
-};
-
-/* Interrupt control register (0) values */
-#define SXG_ICR_DISABLE					0x00000000
-#define SXG_ICR_ENABLE					0x00000001
-#define SXG_ICR_MASK					0x00000002
-#define SXG_ICR_MSGID_MASK				0xFFFF0000
-#define SXG_ICR_MSGID_SHIFT			16
-#define SXG_ICR(_MessageId, _Data)	\
-	((((_MessageId) << SXG_ICR_MSGID_SHIFT) &	\
-	  SXG_ICR_MSGID_MASK) | (_Data))
-
-#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
-
-/* 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_SHIFT			16
-
-#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
-
-/*
- * 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
-
-/*
- * 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
- * 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 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. */
-};
-
-/***************************************************************************
- * ISR Format
- *                31                                      0
- *                 _______________________________________
- *                |    |    |    |    |    |    |    |    |
- *                |____|____|____|____|____|____|____|____|
- *                 ^^^^ ^^^^ ^^^^ ^^^^ \                 /
- *           ERR --|||| |||| |||| ||||  -----------------
- *         EVENT ---||| |||| |||| ||||          |
- *               ----|| |||| |||| ||||          |-- Crash Address
- *           UPC -----| |||| |||| ||||
- *        LEVENT -------|||| |||| ||||
- *          PDQF --------||| |||| ||||
- *         RMISS ---------|| |||| ||||
- *         BREAK ----------| |||| ||||
- *       HBEATOK ------------|||| ||||
- *       NOHBEAT -------------||| ||||
- *        ERFULL --------------|| ||||
- *         XDROP ---------------| ||||
- *               -----------------||||
- *               -----------------||||--\
- *                                 ||---|-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 */
-
-/***************************************************************************
- * Event Ring entry
- *
- *  31                  15                 0
- *  .___________________.___________________.
- *  |<------------    Pad 0    ------------>|
- *  |_________|_________|_________|_________|0		0x00
- *  |<------------    Pad 1    ------------>|
- *  |_________|_________|_________|_________|4		0x04
- *  |<------------    Pad 2    ------------>|
- *  |_________|_________|_________|_________|8 		0x08
- *  |<----------- Event Word 0 ------------>|
- *  |_________|_________|_________|_________|12		0x0c
- *  |<----------- Event Word 1 ------------>|
- *  |_________|_________|_________|_________|16		0x10
- *  |<------------- Toeplitz   ------------>|
- *  |_________|_________|_________|_________|20		0x14
- *  |<----- Length ---->|<------ TCB Id --->|
- *  |_________|_________|_________|_________|24		0x18
- *  |<----- Status ---->|Evnt Code|Flsh Code|
- *  |_________|_________|_________|_________|28		0x1c
- *   ^                   ^^^^ ^^^^
- *   |- VALID            |||| ||||- RBUFC
- *                       |||| |||-- SLOWR
- *                       |||| ||--- UNUSED
- *                       |||| |---- FASTC
- *                       ||||------ FASTR
- *                       |||-------
- *                       ||--------
- *                       |---------
- *
- * Slowpath status:
- *   _______________________________________
- *  |<----- Status ---->|Evnt Code|Flsh Code|
- *  |_________|Cmd Index|_________|_________|28		0x1c
- *    ^^^ ^^^^
- *    ||| ||||- ISTCPIP6
- *    ||| |||-- IPONLY
- *    ||| ||--- RCVERR
- *    ||| |---- IPCBAD
- *    |||------ TCPCBAD
- *    ||------- ISTCPIP
- *    |-------- SCERR
- *
- ************************************************************************/
-#pragma pack(push, 1)
-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 */
-		struct {
-			u32 NotUsed;
-			u32	Rsvd2;		/* TOE NA */
-		} Flush;
-	};
-	u32			Toeplitz;	/* RSS Toeplitz hash */
-	union {
-		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 */
-};
-#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 */
-
-/* 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 */
-
-/*
- * 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];
-};
-
-/* TCB Buffers */
-/* Maximum number of TCBS supported by hardware/microcode */
-#define SXG_MAX_TCB		4096
-/* 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.
- */
-#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_BUFFER_SIZE	512	/* ASSERT format is correct */
-
-#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	: 	\
-	  &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.SxgTcp))
-
-#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:		\
-	&(_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;	\
-		}							\
-	}								\
-}
-#else
-/* Do nothing with free build */
-#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath)
-#endif
-
-/* 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_MAX_ENTRIES     4096
-#define SXG_JUMBO_RCV_RING_SIZE       32
-
-/* 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_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));		\
-}
-/*
- * 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);			\
-	}								\
-}
-
-/*
- * 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];		\
-	(_context) = (_ringinfo)->Context[(_ringinfo)->Tail];       	\
-	(_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 -------------->|
- *  |_________|_________|_________|_________|0		0x00
- *  |<-------------- Sgl High ------------->|
- *  |_________|_________|_________|_________|4		0x04
- *  |<-------------  Sge 0 Low  ----------->|
- *  |_________|_________|_________|_________|8 		0x08
- *  |<-------------  Sge 0 High ----------->|
- *  |_________|_________|_________|_________|12		0x0c
- *  |<------------  Sge 0 Length ---------->|
- *  |_________|_________|_________|_________|16		0x10
- *  |<----------- Window Update ----------->|
- *  |<-------- SP 1st SGE offset ---------->|
- *  |_________|_________|_________|_________|20		0x14
- *  |<----------- Total Length ------------>|
- *  |_________|_________|_________|_________|24		0x18
- *  |<----- LCnt ------>|<----- Flags ----->|
- *  |_________|_________|_________|_________|28		0x1c
- ****************************************************************/
-#pragma pack(push, 1)
-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 */
-			union {
-				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 */
-			};
-		} Buffer;
-	};
-	union {
-		struct {
-			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 */
-		} LsoFlags;
-		ushort		Flags;		/* flags */
-	};
-	union {
-		ushort	SgEntries;	/* SG entry count including first sge */
-		struct {
-			unsigned char Status;	/* Copied from event status */
-			unsigned char NotUsed;
-		} Status;
-	};
-};
-#pragma pack(pop)
-
-#pragma pack(push, 1)
-struct vlan_hdr {
-	ushort VlanTci;
-	ushort VlanTpid;
-};
-#pragma pack(pop)
-
-/********************************************************************
- * Slowpath Flags:
- *
- *
- * LSS Flags:
- *                                        .---
- *                                       /.--- TCP Large segment send
- *                                      //.---
- *                                     ///.---
- *  3                   1     1       ////
- *  1                   5     0      ||||
- *  .___________________.____________vvvv.
- *  |                   |MAC |  TCP |    |
- *  |      LCnt         |hlen|hdroff|Flgs|
- *  |___________________|||||||||||||____|
- *
- *
- * Checksum Flags
- *
- *                                           .---
- *                                          /.---
- *                                         //.--- Checksum TCP
- *                                        ///.--- Checksum IP
- *  3                   1                //// No bits - normal send
- *  1                   5          7    ||||
- *  .___________________._______________vvvv.
- *  |                   | Offload | IP |    |
- *  |      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 */
-
-struct sxg_xmt_ring {
-	struct sxg_cmd Descriptors[SXG_XMT_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 */
-};
-
-/* 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.
- * This is accomplished by filling in a "receive descriptor block"
- * with 128 "receive descriptors".  Each descriptor consists of
- * a physical address, which the card uses as the address to
- * 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.
- *
- * This receive descriptor block is given to the card by filling
- * 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.
- *
- * 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 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 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        |
- * |_________________________________________| <== Even 2k or 10k boundary
- * |                                         |
- * |         ... repeat 2-128 ..             |
- * |_________________________________________|
- * |                                         |
- * |      struct sxg_rcv_descriptor_block    |
- * |  Contains sxg_rcv_data_descriptor * 128 |
- * |_________________________________________|
- * |                                         |
- * |   struct sxg_rcv_descriptor_block_hdr   |
- * |_________________________________________|
- * |                                         |
- * |      struct sxg_rcv_block_hdr           |
- * |_________________________________________|
- *
- * Memory consumption:
- *	  Non-jumbo:
- *      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
- *    + 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		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 {
-	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 struct sxg_rcv_data_buffer_hdr when indicating dumb-nic data
- */
-#define SxgDumbRcvPacket	        skb
-
-/* 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 {
-	union {
-		struct sk_buff *VirtualAddress;	/* Host handle */
-		u64		ForceTo8Bytes;	/*Force x86 to 8-byte boundary*/
-	};
-	dma64_addr_t PhysicalAddress;
-};
-
-/* Receive descriptor block */
-#define SXG_RCV_DESCRIPTORS_PER_BLOCK		128
-#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];
-};
-
-/* 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 */
-	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) 				\
-	(((_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)))
-#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)			\
-	((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK)
-#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize)		\
-	(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_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)))
-
-/* 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 */
-};
-
-/*
- * 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},				\
-};
-
-extern struct sxg_sgl_pool_properties SxgSglPoolProperties[];
-
-#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 */
-};
-
-/*
- * 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 */
-};
-
-/*
- * 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 sxg_x64_sge		Elements[1];   /* Variable */
-};
-
-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 */
-};
-
-/*
- * 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_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_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
deleted file mode 100644
index 81f81d4..0000000
--- a/drivers/staging/sxg/sxghw.h
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*************************************************************
- * Copyright © 1997-2007 Alacritech, Inc. All rights reserved
- *
- * $Id: sxghw.h,v 1.2 2008/07/24 17:24:23 chris Exp $
- *
- * sxghw.h:
- *
- * This file contains structures and definitions for the
- * Alacritech Sahara hardware
- *
- **********************************************************/
-
-
-/* PCI Configuration space */
-/*  PCI Vendor ID */
-#define SXG_VENDOR_ID			0x139A	/* Alacritech's Vendor ID */
-
-/*  PCI Device ID */
-#define SXG_DEVICE_ID			0x0009	/* Sahara Device ID */
-
-
-/* Type of ASIC in use */
-enum asic_type {
-	SAHARA_REV_A,
-	SAHARA_REV_B
-};
-
-/* 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.
- */
-
-/* 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 */
-};
-#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 */
-
-/* Link Address Registers */
-/* Applied to link address high */
-#define LINK_ADDRESS_ENABLE	0x80000000
-
-/* 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 */
-#define SXG_ADDRESS_CODE_MASK		0x0000003C
-/* 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_MASK		0x0003E000
-/* 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 */
-/* 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
-
-#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 */
-
-/* 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)
-
-/* 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 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 */
-/* 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 */
-/* Enable IPG extension algorithm */
-#define AXGMAC_CFG2_IPG_EXTEN		0x00000020
-#define AXGMAC_CFG2_IPGEX_MASK		0x0000001F /* IPG extension */
-
-/* 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 5-6 */
-#define AXGMAC_SARHIGH_OCTET_FIVE	0xFF000000	/* Fifth octet */
-#define AXGMAC_SARHIGH_OCTET_SIX	0x00FF0000	/* Sixth octet */
-
-/* A-XGMAC Maximum frame length register */
-/* Maximum transmit frame length */
-#define AXGMAC_MAXFRAME_XMT		0x3FFF0000
-#define AXGMAC_MAXFRAME_XMT_SHIFT	16
-/* 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 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 */
-#define AXGMAC_AMIIM_FIELD_ST_SHIFT		30
-#define AXGMAC_AMIIM_FIELD_OP		0x30000000	/* 2-bit OP field */
-#define AXGMAC_AMIIM_FIELD_OP_SHIFT		28
-/* Port address field (hstphyadx in spec) */
-#define AXGMAC_AMIIM_FIELD_PORT_ADDR 	0x0F800000
-#define AXGMAC_AMIIM_FIELD_PORT_SHIFT		23
-/* 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_SHIFT		16
-#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 */
-#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_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 */
-
-/* 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 */
-/* 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 */
-/* 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 */
-
-
-/*
- * 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 */
-
-/* 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 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 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 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 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_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 */
-
-/* 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 - 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_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_XS_LANE_STATUS register bit definitions */
-#define	XS_LANE_ALIGN		0x1000		/* XS transmit lanes aligned */
-
-#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.
- */
-#pragma pack(push, 1)
-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)
-
-/* 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)
-
-/*
- * 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
-
-/* struct xmt_desc XmtBufId definition */
-/*
- * The Xmt buffer ID is formed by dividing the buffer (DRAM) address
- * by 256 (or << 8)
- */
-
-#define XMT_BUF_ID_SHFT		8
-
-/* Receiver Sequencer Definitions */
-
-/* Receive Event Queue (queues 3 - 6) bit definitions */
-/* bit mask for the Receive Buffer ID */
-#define	RCV_EVTQ_RBFID_MASK	0x0000FFFF
-
-/* 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 */
-	union {
-		ushort		TcpCsum;	/* TCP checksum */
-		struct {
-			/* 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 */
-};
-#pragma pack(pop)
-
-/* 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 */
-/* 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 */
-/* 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 */
-
-/* Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q) */
-/* 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 */
-
-/* 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)
-/*
- * Structure for an element of H/W configuration data.
- * Read by the Sahara hardware
- */
-struct hw_cfg_data {
-	ushort	Addr;
-	ushort	Data;
-};
-
-/*
- * 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 structure */
-struct sxg_config_mac {
-	unsigned char	MacAddr[6];	/* MAC Address */
-};
-
-/* FRU data structure */
-struct atk_fru {
-	unsigned char		PartNum[6];
-	unsigned char		Revision[2];
-	unsigned char		Serial[14];
-};
-
-/* OEM FRU Format types */
-#define	ATK_FRU_FORMAT		0x0000
-#define CPQ_FRU_FORMAT		0x0001
-#define DELL_FRU_FORMAT		0x0002
-#define HP_FRU_FORMAT		0x0003
-#define IBM_FRU_FORMAT		0x0004
-#define EMC_FRU_FORMAT		0x0005
-#define NO_FRU_FORMAT		0xFFFF
-
-#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 */
-
-/* Hardware Type definitions  */
-
-/* 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
deleted file mode 100644
index b5448b9..0000000
--- a/drivers/staging/sxg/sxgphycode-1.2.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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/udlfb/udlfb.h b/drivers/staging/udlfb/udlfb.h
index 08bd671..40ad85e 100644
--- a/drivers/staging/udlfb/udlfb.h
+++ b/drivers/staging/udlfb/udlfb.h
@@ -205,7 +205,7 @@ static int dlfb_set_video_mode(struct dlfb_data *dev_info, int width, int height
 
 			/* send */
 			ret = dlfb_bulk_msg(dev_info, bufptr - dev_info->buf);
-			printk("ret bulk 2: %d %d\n", ret,
+			printk("ret bulk 2: %d %td\n", ret,
 			       bufptr - dev_info->buf);
 
 			/* flush */
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig
index 217fb7e..350d5d6 100644
--- a/drivers/staging/usbip/Kconfig
+++ b/drivers/staging/usbip/Kconfig
@@ -6,7 +6,7 @@ config USB_IP_COMMON
 	  This enables pushing USB packets over IP to allow remote
 	  machines access to USB devices directly.  For more details,
 	  and links to the userspace utility programs to let this work
-	  properly, see http://usbip.naist.jp/
+	  properly, see http://usbip.sourceforge.net/.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called usbip_common_mod.
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index 1e320ca..173b018 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -211,7 +211,7 @@ static void stub_shutdown_connection(struct usbip_device *ud)
 	 * step 1?
 	 */
 	if (ud->tcp_socket) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
+		usbip_udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
 		kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
 	}
 
@@ -259,7 +259,7 @@ static void stub_device_reset(struct usbip_device *ud)
 	struct usb_device *udev = interface_to_usbdev(sdev->interface);
 	int ret;
 
-	udbg("device reset");
+	usbip_udbg("device reset");
 	ret = usb_lock_device_for_reset(udev, sdev->interface);
 	if (ret < 0) {
 		dev_err(&udev->dev, "lock for reset\n");
@@ -356,7 +356,7 @@ static struct stub_device *stub_device_alloc(struct usb_interface *interface)
 
 	usbip_start_eh(&sdev->ud);
 
-	udbg("register new interface\n");
+	usbip_udbg("register new interface\n");
 	return sdev;
 }
 
@@ -366,7 +366,7 @@ static int stub_device_free(struct stub_device *sdev)
 		return -EINVAL;
 
 	kfree(sdev);
-	udbg("kfree udev ok\n");
+	usbip_udbg("kfree udev ok\n");
 
 	return 0;
 }
@@ -409,13 +409,13 @@ static int stub_probe(struct usb_interface *interface,
 	}
 
 	if (udev->descriptor.bDeviceClass ==  USB_CLASS_HUB) {
-		udbg("this device %s is a usb hub device. skip!\n",
+		usbip_udbg("this device %s is a usb hub device. skip!\n",
 								udev_busid);
 		return -ENODEV;
 	}
 
 	if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-		udbg("this device %s is attached on vhci_hcd. skip!\n",
+		usbip_udbg("this device %s is attached on vhci_hcd. skip!\n",
 								udev_busid);
 		return -ENODEV;
 	}
@@ -451,7 +451,7 @@ static void stub_disconnect(struct usb_interface *interface)
 {
 	struct stub_device *sdev = usb_get_intfdata(interface);
 
-	udbg("Enter\n");
+	usbip_udbg("Enter\n");
 
 	/* get stub_device */
 	if (!sdev) {
@@ -479,5 +479,5 @@ static void stub_disconnect(struct usb_interface *interface)
 	stub_device_free(sdev);
 
 
-	udbg("bye\n");
+	usbip_udbg("bye\n");
 }
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c
index 05e4c60..ba1678f 100644
--- a/drivers/staging/usbip/stub_main.c
+++ b/drivers/staging/usbip/stub_main.c
@@ -145,14 +145,14 @@ static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
 		if (add_match_busid(busid) < 0)
 			return -ENOMEM;
 		else {
-			udbg("add busid %s\n", busid);
+			usbip_udbg("add busid %s\n", busid);
 			return count;
 		}
 	} else if (!strncmp(buf, "del ", 4)) {
 		if (del_match_busid(busid) < 0)
 			return -ENODEV;
 		else {
-			udbg("del busid %s\n", busid);
+			usbip_udbg("del busid %s\n", busid);
 			return count;
 		}
 	} else
@@ -213,12 +213,12 @@ void stub_device_cleanup_urbs(struct stub_device *sdev)
 {
 	struct stub_priv *priv;
 
-	udbg("free sdev %p\n", sdev);
+	usbip_udbg("free sdev %p\n", sdev);
 
 	while ((priv = stub_priv_pop(sdev))) {
 		struct urb *urb = priv->urb;
 
-		udbg("   free urb %p\n", urb);
+		usbip_udbg("   free urb %p\n", urb);
 		usb_kill_urb(urb);
 
 		kmem_cache_free(stub_priv_cache, priv);
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 1c71062..815fb7c 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -65,8 +65,8 @@ static int is_reset_device_cmd(struct urb *urb)
 
 	if ((req->bRequest == USB_REQ_SET_FEATURE) &&
 			(req->bRequestType == USB_RT_PORT) &&
-			(value = USB_PORT_FEAT_RESET)) {
-		dbg_stub_rx("reset_device_cmd, port %u\n", index);
+			(value == USB_PORT_FEAT_RESET)) {
+		usbip_dbg_stub_rx("reset_device_cmd, port %u\n", index);
 		return 1;
 	} else
 		return 0;
@@ -99,11 +99,11 @@ static int tweak_clear_halt_cmd(struct urb *urb)
 
 	ret = usb_clear_halt(urb->dev, target_pipe);
 	if (ret < 0)
-		uinfo("clear_halt error: devnum %d endp %d, %d\n",
-				urb->dev->devnum, target_endp, ret);
+		usbip_uinfo("clear_halt error: devnum %d endp %d, %d\n",
+					urb->dev->devnum, target_endp, ret);
 	else
-		uinfo("clear_halt done: devnum %d endp %d\n",
-				urb->dev->devnum, target_endp);
+		usbip_uinfo("clear_halt done: devnum %d endp %d\n",
+					urb->dev->devnum, target_endp);
 
 	return ret;
 }
@@ -119,14 +119,15 @@ static int tweak_set_interface_cmd(struct urb *urb)
 	alternate = le16_to_cpu(req->wValue);
 	interface = le16_to_cpu(req->wIndex);
 
-	dbg_stub_rx("set_interface: inf %u alt %u\n", interface, alternate);
+	usbip_dbg_stub_rx("set_interface: inf %u alt %u\n", interface,
+								alternate);
 
 	ret = usb_set_interface(urb->dev, interface, alternate);
 	if (ret < 0)
-		uinfo("set_interface error: inf %u alt %u, %d\n",
-				interface, alternate, ret);
+		usbip_uinfo("set_interface error: inf %u alt %u, %d\n",
+					interface, alternate, ret);
 	else
-		uinfo("set_interface done: inf %u alt %u\n",
+		usbip_uinfo("set_interface done: inf %u alt %u\n",
 							interface,
 							alternate);
 
@@ -157,8 +158,9 @@ static int tweak_set_configuration_cmd(struct urb *urb)
 	 * A user may need to set a special configuration value before
 	 * exporting the device.
 	 */
-	uinfo("set_configuration (%d) to %s\n", config, dev_name(&urb->dev->dev));
-	uinfo("but, skip!\n");
+	usbip_uinfo("set_configuration (%d) to %s\n", config,
+						dev_name(&urb->dev->dev));
+	usbip_uinfo("but, skip!\n");
 
 	return 0;
 	/* return usb_driver_set_configuration(urb->dev, config); */
@@ -175,7 +177,8 @@ static int tweak_reset_device_cmd(struct urb *urb)
 	value = le16_to_cpu(req->wValue);
 	index = le16_to_cpu(req->wIndex);
 
-	uinfo("reset_device (port %d) to %s\n", index, dev_name(&urb->dev->dev));
+	usbip_uinfo("reset_device (port %d) to %s\n", index,
+						dev_name(&urb->dev->dev));
 
 	/* all interfaces should be owned by usbip driver, so just reset it.  */
 	ret = usb_lock_device_for_reset(urb->dev, NULL);
@@ -220,7 +223,7 @@ static void tweak_special_requests(struct urb *urb)
 	else if (is_reset_device_cmd(urb))
 		tweak_reset_device_cmd(urb);
 	else
-		dbg_stub_rx("no need to tweak\n");
+		usbip_dbg_stub_rx("no need to tweak\n");
 }
 
 /*
@@ -292,7 +295,8 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev,
 		}
 	}
 
-	dbg_stub_rx("seqnum %d is not pending\n", pdu->u.cmd_unlink.seqnum);
+	usbip_dbg_stub_rx("seqnum %d is not pending\n",
+						pdu->u.cmd_unlink.seqnum);
 
 	/*
 	 * The urb of the unlink target is not found in priv_init queue. It was
@@ -383,7 +387,7 @@ static struct usb_host_endpoint *get_ep_from_epnum(struct usb_device *udev,
 			epnum = (ep->desc.bEndpointAddress & 0x7f);
 
 			if (epnum == epnum0) {
-				/* uinfo("found epnum %d\n", epnum0); */
+				/* usbip_uinfo("found epnum %d\n", epnum0);*/
 				found = 1;
 				break;
 			}
@@ -526,7 +530,8 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
 	ret = usb_submit_urb(priv->urb, GFP_KERNEL);
 
 	if (ret == 0)
-		dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum);
+		usbip_dbg_stub_rx("submit urb ok, seqnum %u\n",
+							pdu->base.seqnum);
 	else {
 		dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret);
 		usbip_dump_header(pdu);
@@ -539,7 +544,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
 		usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
 	}
 
-	dbg_stub_rx("Leave\n");
+	usbip_dbg_stub_rx("Leave\n");
 	return;
 }
 
@@ -551,7 +556,7 @@ static void stub_rx_pdu(struct usbip_device *ud)
 	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
 	struct device *dev = &sdev->interface->dev;
 
-	dbg_stub_rx("Enter\n");
+	usbip_dbg_stub_rx("Enter\n");
 
 	memset(&pdu, 0, sizeof(pdu));
 
@@ -565,7 +570,7 @@ static void stub_rx_pdu(struct usbip_device *ud)
 
 	usbip_header_correct_endian(&pdu, 0);
 
-	if (dbg_flag_stub_rx)
+	if (usbip_dbg_flag_stub_rx)
 		usbip_dump_header(&pdu);
 
 	if (!valid_request(sdev, &pdu)) {
@@ -598,11 +603,11 @@ void stub_rx_loop(struct usbip_task *ut)
 
 	while (1) {
 		if (signal_pending(current)) {
-			dbg_stub_rx("signal caught!\n");
+			usbip_dbg_stub_rx("signal caught!\n");
 			break;
 		}
 
-		if (usbip_event_happend(ud))
+		if (usbip_event_happened(ud))
 			break;
 
 		stub_rx_pdu(ud);
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c
index 78058f5..e2ab4f3 100644
--- a/drivers/staging/usbip/stub_tx.c
+++ b/drivers/staging/usbip/stub_tx.c
@@ -66,7 +66,7 @@ void stub_complete(struct urb *urb)
 	struct stub_device *sdev = priv->sdev;
 	unsigned long flags;
 
-	dbg_stub_tx("complete! status %d\n", urb->status);
+	usbip_dbg_stub_tx("complete! status %d\n", urb->status);
 
 
 	switch (urb->status) {
@@ -74,20 +74,22 @@ void stub_complete(struct urb *urb)
 		/* OK */
 		break;
 	case -ENOENT:
-		uinfo("stopped by a call of usb_kill_urb() because of"
+		usbip_uinfo("stopped by a call of usb_kill_urb() because of"
 					"cleaning up a virtual connection\n");
 		return;
 	case -ECONNRESET:
-		uinfo("unlinked by a call of usb_unlink_urb()\n");
+		usbip_uinfo("unlinked by a call of usb_unlink_urb()\n");
 		break;
 	case -EPIPE:
-		uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
+		usbip_uinfo("endpoint %d is stalled\n",
+						usb_pipeendpoint(urb->pipe));
 		break;
 	case -ESHUTDOWN:
-		uinfo("device removed?\n");
+		usbip_uinfo("device removed?\n");
 		break;
 	default:
-		uinfo("urb completion with non-zero status %d\n", urb->status);
+		usbip_uinfo("urb completion with non-zero status %d\n",
+							urb->status);
 	}
 
 	/* link a urb to the queue of tx. */
@@ -181,7 +183,7 @@ static int stub_send_ret_submit(struct stub_device *sdev)
 		memset(&msg, 0, sizeof(msg));
 		memset(&iov, 0, sizeof(iov));
 
-		dbg_stub_tx("setup txdata urb %p\n", urb);
+		usbip_dbg_stub_tx("setup txdata urb %p\n", urb);
 
 
 		/* 1. setup usbip_header */
@@ -227,7 +229,7 @@ static int stub_send_ret_submit(struct stub_device *sdev)
 		}
 
 		kfree(iso_buffer);
-		dbg_stub_tx("send txdata\n");
+		usbip_dbg_stub_tx("send txdata\n");
 
 		total_size += txsize;
 	}
@@ -287,7 +289,7 @@ static int stub_send_ret_unlink(struct stub_device *sdev)
 		memset(&msg, 0, sizeof(msg));
 		memset(&iov, 0, sizeof(iov));
 
-		dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
+		usbip_dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
 
 		/* 1. setup usbip_header */
 		setup_ret_unlink_pdu(&pdu_header, unlink);
@@ -308,7 +310,7 @@ static int stub_send_ret_unlink(struct stub_device *sdev)
 		}
 
 
-		dbg_stub_tx("send txdata\n");
+		usbip_dbg_stub_tx("send txdata\n");
 
 		total_size += txsize;
 	}
@@ -336,11 +338,11 @@ void stub_tx_loop(struct usbip_task *ut)
 
 	while (1) {
 		if (signal_pending(current)) {
-			dbg_stub_tx("signal catched\n");
+			usbip_dbg_stub_tx("signal catched\n");
 			break;
 		}
 
-		if (usbip_event_happend(ud))
+		if (usbip_event_happened(ud))
 			break;
 
 		/*
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 251220d..ddb6f5f 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -22,6 +22,7 @@
 #include <linux/file.h>
 #include <linux/tcp.h>
 #include <linux/in.h>
+#include <linux/kthread.h>
 #include "usbip_common.h"
 
 /* version information */
@@ -70,27 +71,27 @@ static void usbip_dump_buffer(char *buff, int bufflen)
 	if (bufflen > 128) {
 		for (i = 0; i < 128; i++) {
 			if (i%24 == 0)
-				printk("   ");
-			printk("%02x ", (unsigned char) buff[i]);
+				printk(KERN_DEBUG "   ");
+			printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
 			if (i%4 == 3)
-				printk("| ");
+				printk(KERN_DEBUG "| ");
 			if (i%24 == 23)
-				printk("\n");
+				printk(KERN_DEBUG "\n");
 		}
-		printk("... (%d byte)\n", bufflen);
+		printk(KERN_DEBUG "... (%d byte)\n", bufflen);
 		return;
 	}
 
 	for (i = 0; i < bufflen; i++) {
 		if (i%24 == 0)
-			printk("   ");
-		printk("%02x ", (unsigned char) buff[i]);
+			printk(KERN_DEBUG "   ");
+		printk(KERN_DEBUG "%02x ", (unsigned char) buff[i]);
 		if (i%4 == 3)
-			printk("| ");
+			printk(KERN_DEBUG "| ");
 		if (i%24 == 23)
-			printk("\n");
+			printk(KERN_DEBUG "\n");
 	}
-	printk("\n");
+	printk(KERN_DEBUG "\n");
 
 }
 
@@ -101,28 +102,28 @@ static void usbip_dump_pipe(unsigned int p)
 	unsigned char dev = usb_pipedevice(p);
 	unsigned char dir = usb_pipein(p);
 
-	printk("dev(%d) ", dev);
-	printk("ep(%d) ",  ep);
-	printk("%s ", dir ? "IN" : "OUT");
+	printk(KERN_DEBUG "dev(%d) ", dev);
+	printk(KERN_DEBUG "ep(%d) ",  ep);
+	printk(KERN_DEBUG "%s ", dir ? "IN" : "OUT");
 
 	switch (type) {
 	case PIPE_ISOCHRONOUS:
-		printk("%s ", "ISO");
+		printk(KERN_DEBUG "%s ", "ISO");
 		break;
 	case PIPE_INTERRUPT:
-		printk("%s ", "INT");
+		printk(KERN_DEBUG "%s ", "INT");
 		break;
 	case PIPE_CONTROL:
-		printk("%s ", "CTL");
+		printk(KERN_DEBUG "%s ", "CTL");
 		break;
 	case PIPE_BULK:
-		printk("%s ", "BLK");
+		printk(KERN_DEBUG "%s ", "BLK");
 		break;
 	default:
-		printk("ERR");
+		printk(KERN_DEBUG "ERR");
 	}
 
-	printk("\n");
+	printk(KERN_DEBUG "\n");
 
 }
 
@@ -136,55 +137,55 @@ static void usbip_dump_usb_device(struct usb_device *udev)
 
 	switch (udev->speed) {
 	case USB_SPEED_HIGH:
-		printk(" SPD_HIGH");
+		printk(KERN_DEBUG " SPD_HIGH");
 		break;
 	case USB_SPEED_FULL:
-		printk(" SPD_FULL");
+		printk(KERN_DEBUG " SPD_FULL");
 		break;
 	case USB_SPEED_LOW:
-		printk(" SPD_LOW");
+		printk(KERN_DEBUG " SPD_LOW");
 		break;
 	case USB_SPEED_UNKNOWN:
-		printk(" SPD_UNKNOWN");
+		printk(KERN_DEBUG " SPD_UNKNOWN");
 		break;
 	default:
-		printk(" SPD_ERROR");
+		printk(KERN_DEBUG " SPD_ERROR");
 	}
 
-	printk(" tt %p, ttport %d", udev->tt, udev->ttport);
-	printk("\n");
+	printk(KERN_DEBUG " tt %p, ttport %d", udev->tt, udev->ttport);
+	printk(KERN_DEBUG "\n");
 
 	dev_dbg(dev, "                    ");
 	for (i = 0; i < 16; i++)
-		printk(" %2u", i);
-	printk("\n");
+		printk(KERN_DEBUG " %2u", i);
+	printk(KERN_DEBUG "\n");
 
 	dev_dbg(dev, "       toggle0(IN) :");
 	for (i = 0; i < 16; i++)
-		printk(" %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0);
-	printk("\n");
+		printk(KERN_DEBUG " %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0);
+	printk(KERN_DEBUG "\n");
 
 	dev_dbg(dev, "       toggle1(OUT):");
 	for (i = 0; i < 16; i++)
-		printk(" %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0);
-	printk("\n");
+		printk(KERN_DEBUG " %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0);
+	printk(KERN_DEBUG "\n");
 
 
 	dev_dbg(dev, "       epmaxp_in   :");
 	for (i = 0; i < 16; i++) {
 		if (udev->ep_in[i])
-			printk(" %2u",
+			printk(KERN_DEBUG " %2u",
 			     le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize));
 	}
-	printk("\n");
+	printk(KERN_DEBUG "\n");
 
 	dev_dbg(dev, "       epmaxp_out  :");
 	for (i = 0; i < 16; i++) {
 		if (udev->ep_out[i])
-			printk(" %2u",
+			printk(KERN_DEBUG " %2u",
 			     le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize));
 	}
-	printk("\n");
+	printk(KERN_DEBUG "\n");
 
 	dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus);
 
@@ -203,91 +204,91 @@ static void usbip_dump_request_type(__u8 rt)
 {
 	switch (rt & USB_RECIP_MASK) {
 	case USB_RECIP_DEVICE:
-		printk("DEVICE");
+		printk(KERN_DEBUG "DEVICE");
 		break;
 	case USB_RECIP_INTERFACE:
-		printk("INTERF");
+		printk(KERN_DEBUG "INTERF");
 		break;
 	case USB_RECIP_ENDPOINT:
-		printk("ENDPOI");
+		printk(KERN_DEBUG "ENDPOI");
 		break;
 	case USB_RECIP_OTHER:
-		printk("OTHER ");
+		printk(KERN_DEBUG "OTHER ");
 		break;
 	default:
-		printk("------");
+		printk(KERN_DEBUG "------");
 	}
 }
 
 static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
 {
 	if (!cmd) {
-		printk("      %s : null pointer\n", __func__);
+		printk(KERN_DEBUG "      %s : null pointer\n", __func__);
 		return;
 	}
 
-	printk("       ");
-	printk("bRequestType(%02X) ", cmd->bRequestType);
-	printk("bRequest(%02X) " , cmd->bRequest);
-	printk("wValue(%04X) ", cmd->wValue);
-	printk("wIndex(%04X) ", cmd->wIndex);
-	printk("wLength(%04X) ", cmd->wLength);
+	printk(KERN_DEBUG "       ");
+	printk(KERN_DEBUG "bRequestType(%02X) ", cmd->bRequestType);
+	printk(KERN_DEBUG "bRequest(%02X) " , cmd->bRequest);
+	printk(KERN_DEBUG "wValue(%04X) ", cmd->wValue);
+	printk(KERN_DEBUG "wIndex(%04X) ", cmd->wIndex);
+	printk(KERN_DEBUG "wLength(%04X) ", cmd->wLength);
 
-	printk("\n       ");
+	printk(KERN_DEBUG "\n       ");
 
 	if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-		printk("STANDARD ");
+		printk(KERN_DEBUG "STANDARD ");
 		switch (cmd->bRequest) {
 		case USB_REQ_GET_STATUS:
-			printk("GET_STATUS");
+			printk(KERN_DEBUG "GET_STATUS");
 			break;
 		case USB_REQ_CLEAR_FEATURE:
-			printk("CLEAR_FEAT");
+			printk(KERN_DEBUG "CLEAR_FEAT");
 			break;
 		case USB_REQ_SET_FEATURE:
-			printk("SET_FEAT  ");
+			printk(KERN_DEBUG "SET_FEAT  ");
 			break;
 		case USB_REQ_SET_ADDRESS:
-			printk("SET_ADDRRS");
+			printk(KERN_DEBUG "SET_ADDRRS");
 			break;
 		case USB_REQ_GET_DESCRIPTOR:
-			printk("GET_DESCRI");
+			printk(KERN_DEBUG "GET_DESCRI");
 			break;
 		case USB_REQ_SET_DESCRIPTOR:
-			printk("SET_DESCRI");
+			printk(KERN_DEBUG "SET_DESCRI");
 			break;
 		case USB_REQ_GET_CONFIGURATION:
-			printk("GET_CONFIG");
+			printk(KERN_DEBUG "GET_CONFIG");
 			break;
 		case USB_REQ_SET_CONFIGURATION:
-			printk("SET_CONFIG");
+			printk(KERN_DEBUG "SET_CONFIG");
 			break;
 		case USB_REQ_GET_INTERFACE:
-			printk("GET_INTERF");
+			printk(KERN_DEBUG "GET_INTERF");
 			break;
 		case USB_REQ_SET_INTERFACE:
-			printk("SET_INTERF");
+			printk(KERN_DEBUG "SET_INTERF");
 			break;
 		case USB_REQ_SYNCH_FRAME:
-			printk("SYNC_FRAME");
+			printk(KERN_DEBUG "SYNC_FRAME");
 			break;
 		default:
-			printk("REQ(%02X) ", cmd->bRequest);
+			printk(KERN_DEBUG "REQ(%02X) ", cmd->bRequest);
 		}
 
-		printk(" ");
+		printk(KERN_DEBUG " ");
 		usbip_dump_request_type(cmd->bRequestType);
 
 	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
-		printk("CLASS   ");
+		printk(KERN_DEBUG "CLASS   ");
 
 	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR)
-		printk("VENDOR  ");
+		printk(KERN_DEBUG "VENDOR  ");
 
 	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED)
-		printk("RESERVED");
+		printk(KERN_DEBUG "RESERVED");
 
-	printk("\n");
+	printk(KERN_DEBUG "\n");
 }
 
 void usbip_dump_urb(struct urb *urb)
@@ -319,7 +320,8 @@ void usbip_dump_urb(struct urb *urb)
 	dev_dbg(dev, "   status                :%d\n", urb->status);
 	dev_dbg(dev, "   transfer_flags        :%08X\n", urb->transfer_flags);
 	dev_dbg(dev, "   transfer_buffer       :%p\n", urb->transfer_buffer);
-	dev_dbg(dev, "   transfer_buffer_length:%d\n", urb->transfer_buffer_length);
+	dev_dbg(dev, "   transfer_buffer_length:%d\n",
+						urb->transfer_buffer_length);
 	dev_dbg(dev, "   actual_length         :%d\n", urb->actual_length);
 	dev_dbg(dev, "   setup_packet          :%p\n", urb->setup_packet);
 
@@ -338,7 +340,7 @@ EXPORT_SYMBOL_GPL(usbip_dump_urb);
 
 void usbip_dump_header(struct usbip_header *pdu)
 {
-	udbg("BASE: cmd %u seq %u devid %u dir %u ep %u\n",
+	usbip_udbg("BASE: cmd %u seq %u devid %u dir %u ep %u\n",
 			pdu->base.command,
 			pdu->base.seqnum,
 			pdu->base.devid,
@@ -347,7 +349,8 @@ void usbip_dump_header(struct usbip_header *pdu)
 
 	switch (pdu->base.command) {
 	case USBIP_CMD_SUBMIT:
-		udbg("CMD_SUBMIT: x_flags %u x_len %u sf %u #p %u iv %u\n",
+		usbip_udbg("CMD_SUBMIT: "
+				"x_flags %u x_len %u sf %u #p %u iv %u\n",
 				pdu->u.cmd_submit.transfer_flags,
 				pdu->u.cmd_submit.transfer_buffer_length,
 				pdu->u.cmd_submit.start_frame,
@@ -355,20 +358,20 @@ void usbip_dump_header(struct usbip_header *pdu)
 				pdu->u.cmd_submit.interval);
 				break;
 	case USBIP_CMD_UNLINK:
-		udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
+		usbip_udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
 		break;
 	case USBIP_RET_SUBMIT:
-		udbg("RET_SUBMIT: st %d al %u sf %d ec %d\n",
+		usbip_udbg("RET_SUBMIT: st %d al %u sf %d ec %d\n",
 				pdu->u.ret_submit.status,
 				pdu->u.ret_submit.actual_length,
 				pdu->u.ret_submit.start_frame,
 				pdu->u.ret_submit.error_count);
 	case USBIP_RET_UNLINK:
-		udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
+		usbip_udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
 		break;
 	default:
 		/* NOT REACHED */
-		udbg("UNKNOWN\n");
+		usbip_udbg("UNKNOWN\n");
 	}
 }
 EXPORT_SYMBOL_GPL(usbip_dump_header);
@@ -402,29 +405,30 @@ int usbip_thread(void *param)
 	complete_and_exit(&ut->thread_done, 0);
 }
 
-void usbip_start_threads(struct usbip_device *ud)
+int usbip_start_threads(struct usbip_device *ud)
 {
 	/*
 	 * threads are invoked per one device (per one connection).
 	 */
-	int retval;
+	struct task_struct *th;
 
-	retval = kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0);
-	if (retval < 0) {
-		printk(KERN_ERR "Creating tcp_rx thread for ud %p failed.\n",
-				ud);
-		return;
+	th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
+	if (IS_ERR(th)) {
+		printk(KERN_WARNING
+			"Unable to start control thread\n");
+		return PTR_ERR(th);
 	}
-	retval = kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0);
-	if (retval < 0) {
-		printk(KERN_ERR "Creating tcp_tx thread for ud %p failed.\n",
-				ud);
-		return;
+	th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
+	if (IS_ERR(th)) {
+		printk(KERN_WARNING
+			"Unable to start control thread\n");
+		return PTR_ERR(th);
 	}
 
 	/* confirm threads are starting */
 	wait_for_completion(&ud->tcp_rx.thread_done);
 	wait_for_completion(&ud->tcp_tx.thread_done);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(usbip_start_threads);
 
@@ -434,13 +438,13 @@ void usbip_stop_threads(struct usbip_device *ud)
 	if (ud->tcp_rx.thread != NULL) {
 		send_sig(SIGKILL, ud->tcp_rx.thread, 1);
 		wait_for_completion(&ud->tcp_rx.thread_done);
-		udbg("rx_thread for ud %p has finished\n", ud);
+		usbip_udbg("rx_thread for ud %p has finished\n", ud);
 	}
 
 	if (ud->tcp_tx.thread != NULL) {
 		send_sig(SIGKILL, ud->tcp_tx.thread, 1);
 		wait_for_completion(&ud->tcp_tx.thread_done);
-		udbg("tx_thread for ud %p has finished\n", ud);
+		usbip_udbg("tx_thread for ud %p has finished\n", ud);
 	}
 }
 EXPORT_SYMBOL_GPL(usbip_stop_threads);
@@ -468,11 +472,11 @@ int usbip_xmit(int send, struct socket *sock, char *buf,
 	struct kvec iov;
 	int total = 0;
 
-	/* for blocks of if (dbg_flag_xmit) */
+	/* for blocks of if (usbip_dbg_flag_xmit) */
 	char *bp = buf;
 	int osize = size;
 
-	dbg_xmit("enter\n");
+	usbip_dbg_xmit("enter\n");
 
 	if (!sock || !buf || !size) {
 		printk(KERN_ERR "%s: invalid arg, sock %p buff %p size %d\n",
@@ -481,14 +485,14 @@ int usbip_xmit(int send, struct socket *sock, char *buf,
 	}
 
 
-	if (dbg_flag_xmit) {
+	if (usbip_dbg_flag_xmit) {
 		if (send) {
 			if (!in_interrupt())
 				printk(KERN_DEBUG "%-10s:", current->comm);
 			else
-				printk(KERN_DEBUG "interupt  :");
+				printk(KERN_DEBUG "interrupt  :");
 
-			printk("%s: sending... , sock %p, buf %p, "
+			printk(KERN_DEBUG "%s: sending... , sock %p, buf %p, "
 			       "size %d, msg_flags %d\n", __func__,
 			       sock, buf, size, msg_flags);
 			usbip_dump_buffer(buf, size);
@@ -514,8 +518,8 @@ int usbip_xmit(int send, struct socket *sock, char *buf,
 								MSG_WAITALL);
 
 		if (result <= 0) {
-			udbg("usbip_xmit: %s sock %p buf %p size %u ret %d"
-					" total %d\n",
+			usbip_udbg("usbip_xmit: %s sock %p buf %p size %u ret "
+					"%d total %d\n",
 					send ? "send" : "receive", sock, buf,
 					size, result, total);
 			goto err;
@@ -528,22 +532,23 @@ int usbip_xmit(int send, struct socket *sock, char *buf,
 	} while (size > 0);
 
 
-	if (dbg_flag_xmit) {
+	if (usbip_dbg_flag_xmit) {
 		if (!send) {
 			if (!in_interrupt())
 				printk(KERN_DEBUG "%-10s:", current->comm);
 			else
-				printk(KERN_DEBUG "interupt  :");
+				printk(KERN_DEBUG "interrupt  :");
 
-			printk("usbip_xmit: receiving....\n");
+			printk(KERN_DEBUG "usbip_xmit: receiving....\n");
 			usbip_dump_buffer(bp, osize);
-			printk("usbip_xmit: received, osize %d ret %d size %d "
-					"total %d\n", osize, result, size,
-					total);
+			printk(KERN_DEBUG "usbip_xmit: received, osize %d ret "
+					"%d size %d total %d\n", osize, result,
+					size, total);
 		}
 
 		if (send)
-			printk("usbip_xmit: send, total %d\n", total);
+			printk(KERN_DEBUG "usbip_xmit: send, total %d\n",
+									total);
 	}
 
 	return total;
@@ -638,19 +643,7 @@ EXPORT_SYMBOL_GPL(sockfd_to_socket);
 /* there may be more cases to tweak the flags. */
 static unsigned int tweak_transfer_flags(unsigned int flags)
 {
-
-	if (flags & URB_NO_TRANSFER_DMA_MAP)
-		/*
-		 * vhci_hcd does not provide DMA-mapped I/O. The upper
-		 * driver does not need to set this flag. The remote
-		 * usbip.ko does not still perform DMA-mapped I/O for
-		 * DMA-caplable host controllers. So, clear this flag.
-		 */
-		flags &= ~URB_NO_TRANSFER_DMA_MAP;
-
-	if (flags & URB_NO_SETUP_DMA_MAP)
-		flags &= ~URB_NO_SETUP_DMA_MAP;
-
+	flags &= ~(URB_NO_TRANSFER_DMA_MAP|URB_NO_SETUP_DMA_MAP);
 	return flags;
 }
 
@@ -904,7 +897,7 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
 
 	/* my Bluetooth dongle gets ISO URBs which are np = 0 */
 	if (np == 0) {
-		/* uinfo("iso np == 0\n"); */
+		/* usbip_uinfo("iso np == 0\n"); */
 		/* usbip_dump_urb(urb); */
 		return 0;
 	}
@@ -934,7 +927,6 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
 		usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
 	}
 
-
 	kfree(buff);
 
 	return ret;
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index b0186b7..1ca3eab 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -33,23 +33,23 @@
  */
 
 /**
- * udbg - print debug messages if CONFIG_USB_DEBUG is defined
+ * usbip_udbg - print debug messages if CONFIG_USB_DEBUG is defined
  * @fmt:
  * @args:
  */
 
 #ifdef CONFIG_USB_DEBUG
 
-#define udbg(fmt, args...)						\
+#define usbip_udbg(fmt, args...)					\
 	do {								\
 		printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt,		\
 			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __func__, ##args);	\
+			__FILE__, __LINE__, __func__, ##args);		\
 	} while (0)
 
 #else  /* CONFIG_USB_DEBUG */
 
-#define udbg(fmt, args...)		do { } while (0)
+#define usbip_udbg(fmt, args...)		do { } while (0)
 
 #endif /* CONFIG_USB_DEBUG */
 
@@ -72,58 +72,58 @@ enum {
 	usbip_debug_vhci_sysfs  = (1 << 12)
 };
 
-#define dbg_flag_xmit		(usbip_debug_flag & usbip_debug_xmit)
-#define dbg_flag_vhci_rh	(usbip_debug_flag & usbip_debug_vhci_rh)
-#define dbg_flag_vhci_hc	(usbip_debug_flag & usbip_debug_vhci_hc)
-#define dbg_flag_vhci_rx	(usbip_debug_flag & usbip_debug_vhci_rx)
-#define dbg_flag_vhci_tx	(usbip_debug_flag & usbip_debug_vhci_tx)
-#define dbg_flag_vhci_sysfs	(usbip_debug_flag & usbip_debug_vhci_sysfs)
-#define dbg_flag_stub_rx	(usbip_debug_flag & usbip_debug_stub_rx)
-#define dbg_flag_stub_tx	(usbip_debug_flag & usbip_debug_stub_tx)
+#define usbip_dbg_flag_xmit	(usbip_debug_flag & usbip_debug_xmit)
+#define usbip_dbg_flag_vhci_rh	(usbip_debug_flag & usbip_debug_vhci_rh)
+#define usbip_dbg_flag_vhci_hc	(usbip_debug_flag & usbip_debug_vhci_hc)
+#define usbip_dbg_flag_vhci_rx	(usbip_debug_flag & usbip_debug_vhci_rx)
+#define usbip_dbg_flag_vhci_tx	(usbip_debug_flag & usbip_debug_vhci_tx)
+#define usbip_dbg_flag_stub_rx	(usbip_debug_flag & usbip_debug_stub_rx)
+#define usbip_dbg_flag_stub_tx	(usbip_debug_flag & usbip_debug_stub_tx)
+#define usbip_dbg_flag_vhci_sysfs   (usbip_debug_flag & usbip_debug_vhci_sysfs)
 
 extern unsigned long usbip_debug_flag;
 extern struct device_attribute dev_attr_usbip_debug;
 
-#define dbg_with_flag(flag, fmt, args...)		\
+#define usbip_dbg_with_flag(flag, fmt, args...)		\
 	do {						\
 		if (flag & usbip_debug_flag)		\
-			udbg(fmt , ##args);		\
+			usbip_udbg(fmt , ##args);		\
 	} while (0)
 
-#define dbg_sysfs(fmt, args...)		\
-	dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
-#define dbg_xmit(fmt, args...)		\
-	dbg_with_flag(usbip_debug_xmit, fmt , ##args)
-#define dbg_urb(fmt, args...)		\
-	dbg_with_flag(usbip_debug_urb, fmt , ##args)
-#define dbg_eh(fmt, args...)		\
-	dbg_with_flag(usbip_debug_eh, fmt , ##args)
-
-#define dbg_vhci_rh(fmt, args...)	\
-	dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
-#define dbg_vhci_hc(fmt, args...)	\
-	dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
-#define dbg_vhci_rx(fmt, args...)	\
-	dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
-#define dbg_vhci_tx(fmt, args...)	\
-	dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
-#define dbg_vhci_sysfs(fmt, args...)	\
-	dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
-
-#define dbg_stub_cmp(fmt, args...)	\
-	dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
-#define dbg_stub_rx(fmt, args...)	\
-	dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
-#define dbg_stub_tx(fmt, args...)	\
-	dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
+#define usbip_dbg_sysfs(fmt, args...)		\
+	usbip_dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
+#define usbip_dbg_xmit(fmt, args...)		\
+	usbip_dbg_with_flag(usbip_debug_xmit, fmt , ##args)
+#define usbip_dbg_urb(fmt, args...)		\
+	usbip_dbg_with_flag(usbip_debug_urb, fmt , ##args)
+#define usbip_dbg_eh(fmt, args...)		\
+	usbip_dbg_with_flag(usbip_debug_eh, fmt , ##args)
+
+#define usbip_dbg_vhci_rh(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
+#define usbip_dbg_vhci_hc(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
+#define usbip_dbg_vhci_rx(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
+#define usbip_dbg_vhci_tx(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
+#define usbip_dbg_vhci_sysfs(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
+
+#define usbip_dbg_stub_cmp(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
+#define usbip_dbg_stub_rx(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
+#define usbip_dbg_stub_tx(fmt, args...)	\
+	usbip_dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
 
 
 /**
- * uerr - print error messages
+ * usbip_uerr - print error messages
  * @fmt:
  * @args:
  */
-#define uerr(fmt, args...)						\
+#define usbip_uerr(fmt, args...)					\
 	do {								\
 		printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt,	\
 			(in_interrupt() ? "interrupt" : (current)->comm),\
@@ -131,11 +131,11 @@ extern struct device_attribute dev_attr_usbip_debug;
 	} while (0)
 
 /**
- * uinfo - print information messages
+ * usbip_uinfo - print information messages
  * @fmt:
  * @args:
  */
-#define uinfo(fmt, args...)					\
+#define usbip_uinfo(fmt, args...)				\
 	do {							\
 		printk(KERN_INFO "usbip: " fmt , ## args);	\
 	} while (0)
@@ -355,7 +355,7 @@ struct usbip_device {
 #define USBIP_EH_RESET		(1 << 2)
 #define USBIP_EH_UNUSABLE	(1 << 3)
 
-#define SDEV_EVENT_REMOVED	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
+#define SDEV_EVENT_REMOVED   (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
 #define	SDEV_EVENT_DOWN		(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define	SDEV_EVENT_ERROR_TCP	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
 #define	SDEV_EVENT_ERROR_SUBMIT	(USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
@@ -381,7 +381,7 @@ struct usbip_device {
 void usbip_task_init(struct usbip_task *ut, char *,
 				void (*loop_ops)(struct usbip_task *));
 
-void usbip_start_threads(struct usbip_device *ud);
+int usbip_start_threads(struct usbip_device *ud);
 void usbip_stop_threads(struct usbip_device *ud);
 int usbip_thread(void *param);
 
@@ -397,10 +397,10 @@ void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
 
 
 /* usbip_event.c */
-void usbip_start_eh(struct usbip_device *ud);
+int usbip_start_eh(struct usbip_device *ud);
 void usbip_stop_eh(struct usbip_device *ud);
 void usbip_event_add(struct usbip_device *ud, unsigned long event);
-int usbip_event_happend(struct usbip_device *ud);
+int usbip_event_happened(struct usbip_device *ud);
 
 
 #endif
diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c
index 4318553..6da1021 100644
--- a/drivers/staging/usbip/usbip_event.c
+++ b/drivers/staging/usbip/usbip_event.c
@@ -18,16 +18,17 @@
  */
 
 #include "usbip_common.h"
+#include <linux/kthread.h>
 
 static int event_handler(struct usbip_device *ud)
 {
-	dbg_eh("enter\n");
+	usbip_dbg_eh("enter\n");
 
 	/*
 	 * Events are handled by only this thread.
 	 */
-	while (usbip_event_happend(ud)) {
-		dbg_eh("pending event %lx\n", ud->event);
+	while (usbip_event_happened(ud)) {
+		usbip_dbg_eh("pending event %lx\n", ud->event);
 
 		/*
 		 * NOTE: shutdown must come first.
@@ -77,30 +78,38 @@ static void event_handler_loop(struct usbip_task *ut)
 
 	while (1) {
 		if (signal_pending(current)) {
-			dbg_eh("signal catched!\n");
+			usbip_dbg_eh("signal catched!\n");
 			break;
 		}
 
 		if (event_handler(ud) < 0)
 			break;
 
-		wait_event_interruptible(ud->eh_waitq, usbip_event_happend(ud));
-		dbg_eh("wakeup\n");
+		wait_event_interruptible(ud->eh_waitq,
+					usbip_event_happened(ud));
+		usbip_dbg_eh("wakeup\n");
 	}
 }
 
-void usbip_start_eh(struct usbip_device *ud)
+int usbip_start_eh(struct usbip_device *ud)
 {
 	struct usbip_task *eh = &ud->eh;
+	struct task_struct *th;
 
 	init_waitqueue_head(&ud->eh_waitq);
 	ud->event = 0;
 
 	usbip_task_init(eh, "usbip_eh", event_handler_loop);
 
-	kernel_thread(usbip_thread, (void *)eh, 0);
+	th = kthread_run(usbip_thread, (void *)eh, "usbip");
+	if (IS_ERR(th)) {
+		printk(KERN_WARNING
+			"Unable to start control thread\n");
+		return PTR_ERR(th);
+	}
 
 	wait_for_completion(&eh->thread_done);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(usbip_start_eh);
 
@@ -109,7 +118,7 @@ void usbip_stop_eh(struct usbip_device *ud)
 	struct usbip_task *eh = &ud->eh;
 
 	wait_for_completion(&eh->thread_done);
-	dbg_eh("usbip_eh has finished\n");
+	usbip_dbg_eh("usbip_eh has finished\n");
 }
 EXPORT_SYMBOL_GPL(usbip_stop_eh);
 
@@ -125,17 +134,17 @@ void usbip_event_add(struct usbip_device *ud, unsigned long event)
 }
 EXPORT_SYMBOL_GPL(usbip_event_add);
 
-int usbip_event_happend(struct usbip_device *ud)
+int usbip_event_happened(struct usbip_device *ud)
 {
-	int happend = 0;
+	int happened = 0;
 
 	spin_lock(&ud->lock);
 
 	if (ud->event != 0)
-		happend = 1;
+		happened = 1;
 
 	spin_unlock(&ud->lock);
 
-	return happend;
+	return happened;
 }
-EXPORT_SYMBOL_GPL(usbip_event_happend);
+EXPORT_SYMBOL_GPL(usbip_event_happened);
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index f69ca34..6e91fc2 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -115,7 +115,7 @@ void rh_port_connect(int rhport, enum usb_device_speed speed)
 {
 	unsigned long	flags;
 
-	dbg_vhci_rh("rh_port_connect %d\n", rhport);
+	usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport);
 
 	spin_lock_irqsave(&the_controller->lock, flags);
 
@@ -148,7 +148,7 @@ void rh_port_disconnect(int rhport)
 {
 	unsigned long flags;
 
-	dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
+	usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
 
 	spin_lock_irqsave(&the_controller->lock, flags);
 	/* stop_activity(dum, driver); */
@@ -215,7 +215,7 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf)
 
 	spin_lock_irqsave(&vhci->lock, flags);
 	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
-		dbg_vhci_rh("hw accessible flag in on?\n");
+		usbip_dbg_vhci_rh("hw accessible flag in on?\n");
 		goto done;
 	}
 
@@ -223,14 +223,14 @@ static int vhci_hub_status(struct usb_hcd *hcd, char *buf)
 	for (rhport = 0; rhport < VHCI_NPORTS; rhport++) {
 		if ((vhci->port_status[rhport] & PORT_C_MASK)) {
 			/* The status of a port has been changed, */
-			dbg_vhci_rh("port %d is changed\n", rhport);
+			usbip_dbg_vhci_rh("port %d is changed\n", rhport);
 
 			*event_bits |= 1 << (rhport + 1);
 			changed = 1;
 		}
 	}
 
-	uinfo("changed %d\n", changed);
+	usbip_uinfo("changed %d\n", changed);
 
 	if (hcd->state == HC_STATE_SUSPENDED)
 		usb_hcd_resume_root_hub(hcd);
@@ -275,10 +275,11 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	 * NOTE:
 	 * wIndex shows the port number and begins from 1.
 	 */
-	dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue,
+	usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue,
 								wIndex);
 	if (wIndex > VHCI_NPORTS)
-		printk(KERN_ERR "%s: invalid port number %d\n", __func__, wIndex);
+		printk(KERN_ERR "%s: invalid port number %d\n", __func__,
+								wIndex);
 	rhport = ((__u8)(wIndex & 0x00ff)) - 1;
 
 	dum = hcd_to_vhci(hcd);
@@ -286,7 +287,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	spin_lock_irqsave(&dum->lock, flags);
 
 	/* store old status and compare now and old later */
-	if (dbg_flag_vhci_rh) {
+	if (usbip_dbg_flag_vhci_rh) {
 		int i = 0;
 		for (i = 0; i < VHCI_NPORTS; i++)
 			prev_port_status[i] = dum->port_status[i];
@@ -294,7 +295,7 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 	switch (typeReq) {
 	case ClearHubFeature:
-		dbg_vhci_rh(" ClearHubFeature\n");
+		usbip_dbg_vhci_rh(" ClearHubFeature\n");
 		break;
 	case ClearPortFeature:
 		switch (wValue) {
@@ -307,15 +308,16 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 			}
 			break;
 		case USB_PORT_FEAT_POWER:
-			dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_POWER\n");
+			usbip_dbg_vhci_rh(" ClearPortFeature: "
+						"USB_PORT_FEAT_POWER\n");
 			dum->port_status[rhport] = 0;
 			/* dum->address = 0; */
 			/* dum->hdev = 0; */
 			dum->resuming = 0;
 			break;
 		case USB_PORT_FEAT_C_RESET:
-			dbg_vhci_rh(" ClearPortFeature: "
-					"USB_PORT_FEAT_C_RESET\n");
+			usbip_dbg_vhci_rh(" ClearPortFeature: "
+						"USB_PORT_FEAT_C_RESET\n");
 			switch (dum->vdev[rhport].speed) {
 			case USB_SPEED_HIGH:
 				dum->port_status[rhport] |=
@@ -329,20 +331,21 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 				break;
 			}
 		default:
-			dbg_vhci_rh(" ClearPortFeature: default %x\n", wValue);
+			usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n",
+								wValue);
 			dum->port_status[rhport] &= ~(1 << wValue);
 		}
 		break;
 	case GetHubDescriptor:
-		dbg_vhci_rh(" GetHubDescriptor\n");
+		usbip_dbg_vhci_rh(" GetHubDescriptor\n");
 		hub_descriptor((struct usb_hub_descriptor *) buf);
 		break;
 	case GetHubStatus:
-		dbg_vhci_rh(" GetHubStatus\n");
+		usbip_dbg_vhci_rh(" GetHubStatus\n");
 		*(__le32 *) buf = __constant_cpu_to_le32(0);
 		break;
 	case GetPortStatus:
-		dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
+		usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
 		if (wIndex > VHCI_NPORTS || wIndex < 1) {
 			printk(KERN_ERR "%s: invalid port number %d\n",
 			       __func__, wIndex);
@@ -379,7 +382,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 			if (dum->vdev[rhport].ud.status ==
 							VDEV_ST_NOTASSIGNED) {
-				dbg_vhci_rh(" enable rhport %d (status %u)\n",
+				usbip_dbg_vhci_rh(" enable rhport %d "
+						"(status %u)\n",
 						rhport,
 						dum->vdev[rhport].ud.status);
 				dum->port_status[rhport] |=
@@ -415,17 +419,17 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		((u16 *) buf)[1] =
 				cpu_to_le16(dum->port_status[rhport] >> 16);
 
-		dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0],
+		usbip_dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0],
 							((u16 *)buf)[1]);
 		break;
 	case SetHubFeature:
-		dbg_vhci_rh(" SetHubFeature\n");
+		usbip_dbg_vhci_rh(" SetHubFeature\n");
 		retval = -EPIPE;
 		break;
 	case SetPortFeature:
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
-			dbg_vhci_rh(" SetPortFeature: "
+			usbip_dbg_vhci_rh(" SetPortFeature: "
 					"USB_PORT_FEAT_SUSPEND\n");
 			printk(KERN_ERR "%s: not yet\n", __func__);
 #if 0
@@ -439,7 +443,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 #endif
 			break;
 		case USB_PORT_FEAT_RESET:
-			dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_RESET\n");
+			usbip_dbg_vhci_rh(" SetPortFeature: "
+						"USB_PORT_FEAT_RESET\n");
 			/* if it's already running, disconnect first */
 			if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
 				dum->port_status[rhport] &=
@@ -460,7 +465,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 
 			/* FALLTHROUGH */
 		default:
-			dbg_vhci_rh(" SetPortFeature: default %d\n", wValue);
+			usbip_dbg_vhci_rh(" SetPortFeature: default %d\n",
+								wValue);
 			dum->port_status[rhport] |= (1 << wValue);
 		}
 		break;
@@ -475,12 +481,12 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		retval = -EPIPE;
 	}
 
-	if (dbg_flag_vhci_rh) {
+	if (usbip_dbg_flag_vhci_rh) {
 		printk(KERN_DEBUG "port %d\n", rhport);
 		dump_port_status(prev_port_status[rhport]);
 		dump_port_status(dum->port_status[rhport]);
 	}
-	dbg_vhci_rh(" bye\n");
+	usbip_dbg_vhci_rh(" bye\n");
 
 	spin_unlock_irqrestore(&dum->lock, flags);
 
@@ -517,9 +523,10 @@ static void vhci_tx_urb(struct urb *urb)
 		return;
 	}
 
+	priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
+
 	spin_lock_irqsave(&vdev->priv_lock, flag);
 
-	priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
 	if (!priv) {
 		dev_err(&urb->dev->dev, "malloc vhci_priv\n");
 		spin_unlock_irqrestore(&vdev->priv_lock, flag);
@@ -529,7 +536,7 @@ static void vhci_tx_urb(struct urb *urb)
 
 	priv->seqnum = atomic_inc_return(&the_controller->seqnum);
 	if (priv->seqnum == 0xffff)
-		uinfo("seqnum max\n");
+		usbip_uinfo("seqnum max\n");
 
 	priv->vdev = vdev;
 	priv->urb = urb;
@@ -550,7 +557,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 	int ret = 0;
 	unsigned long flags;
 
-	dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n",
+	usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n",
 		    hcd, urb, mem_flags);
 
 	/* patch to usb_sg_init() is in 2.5.60 */
@@ -558,13 +565,6 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 
 	spin_lock_irqsave(&the_controller->lock, flags);
 
-	/* check HC is active or not */
-	if (!HC_IS_RUNNING(hcd->state)) {
-		dev_err(dev, "HC is not running\n");
-		spin_unlock_irqrestore(&the_controller->lock, flags);
-		return -ENODEV;
-	}
-
 	if (urb->status != -EINPROGRESS) {
 		dev_err(dev, "URB already unlinked!, status %d\n", urb->status);
 		spin_unlock_irqrestore(&the_controller->lock, flags);
@@ -576,7 +576,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 		goto no_need_unlink;
 
 	/*
-	 * The enumelation process is as follows;
+	 * The enumeration process is as follows;
 	 *
 	 *  1. Get_Descriptor request to DevAddrs(0) EndPoint(0)
 	 *     to get max packet length of default pipe
@@ -594,7 +594,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 
 		if (type != PIPE_CONTROL || !ctrlreq) {
 			dev_err(dev, "invalid request to devnum 0\n");
-			ret = EINVAL;
+			ret = -EINVAL;
 			goto no_need_xmit;
 		}
 
@@ -620,7 +620,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 
 		case USB_REQ_GET_DESCRIPTOR:
 			if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
-				dbg_vhci_hc("Not yet?: "
+				usbip_dbg_vhci_hc("Not yet?: "
 						"Get_Descriptor to device 0 "
 						"(get max pipe size)\n");
 
@@ -653,7 +653,7 @@ no_need_unlink:
 
 	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
 
-	return 0;
+	return ret;
 }
 
 /*
@@ -708,7 +708,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 	struct vhci_priv *priv;
 	struct vhci_device *vdev;
 
-	uinfo("vhci_hcd: dequeue a urb %p\n", urb);
+	usbip_uinfo("vhci_hcd: dequeue a urb %p\n", urb);
 
 
 	spin_lock_irqsave(&the_controller->lock, flags);
@@ -726,7 +726,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 		ret = usb_hcd_check_unlink_urb(hcd, urb, status);
 		if (ret) {
 			spin_unlock_irqrestore(&the_controller->lock, flags);
-			return 0;
+			return ret;
 		}
 	}
 
@@ -739,13 +739,29 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 
 		spin_lock_irqsave(&vdev->priv_lock, flags2);
 
-		uinfo("vhci_hcd: device %p seems to be disconnected\n", vdev);
+		usbip_uinfo("vhci_hcd: device %p seems to be disconnected\n",
+									vdev);
 		list_del(&priv->list);
 		kfree(priv);
 		urb->hcpriv = NULL;
 
 		spin_unlock_irqrestore(&vdev->priv_lock, flags2);
 
+		/*
+		 * If tcp connection is alive, we have sent CMD_UNLINK.
+		 * vhci_rx will receive RET_UNLINK and give back the URB.
+		 * Otherwise, we give back it here.
+		 */
+		usbip_uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n",
+									urb);
+
+		usb_hcd_unlink_urb_from_ep(hcd, urb);
+
+		spin_unlock_irqrestore(&the_controller->lock, flags);
+		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
+								urb->status);
+		spin_lock_irqsave(&the_controller->lock, flags);
+
 	} else {
 		/* tcp connection is alive */
 		unsigned long flags2;
@@ -756,7 +772,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 		/* setup CMD_UNLINK pdu */
 		unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
 		if (!unlink) {
-			uerr("malloc vhci_unlink\n");
+			usbip_uerr("malloc vhci_unlink\n");
 			spin_unlock_irqrestore(&vdev->priv_lock, flags2);
 			spin_unlock_irqrestore(&the_controller->lock, flags);
 			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
@@ -765,11 +781,11 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 
 		unlink->seqnum = atomic_inc_return(&the_controller->seqnum);
 		if (unlink->seqnum == 0xffff)
-			uinfo("seqnum max\n");
+			usbip_uinfo("seqnum max\n");
 
 		unlink->unlink_seqnum = priv->seqnum;
 
-		uinfo("vhci_hcd: device %p seems to be still connected\n",
+		usbip_uinfo("vhci_hcd: device %p seems to be still connected\n",
 									vdev);
 
 		/* send cmd_unlink and try to cancel the pending URB in the
@@ -781,14 +797,10 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 	}
 
 
-	/*
-	 * If tcp connection is alive, we have sent CMD_UNLINK.
-	 * vhci_rx will receive RET_UNLINK and give back the URB.
-	 * Otherwise, we give back it here.
-	 */
 	if (!vdev->ud.tcp_socket) {
 		/* tcp connection is closed */
-		uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n", urb);
+		usbip_uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n",
+									urb);
 
 		usb_hcd_unlink_urb_from_ep(hcd, urb);
 
@@ -800,7 +812,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
 
 	spin_unlock_irqrestore(&the_controller->lock, flags);
 
-	dbg_vhci_hc("leave\n");
+	usbip_dbg_vhci_hc("leave\n");
 	return 0;
 }
 
@@ -835,19 +847,19 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
 
 	/* need this? see stub_dev.c */
 	if (ud->tcp_socket) {
-		udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
+		usbip_udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
 		kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
 	}
 
 	usbip_stop_threads(&vdev->ud);
-	uinfo("stop threads\n");
+	usbip_uinfo("stop threads\n");
 
 	/* active connection is closed */
 	if (vdev->ud.tcp_socket != NULL) {
 		sock_release(vdev->ud.tcp_socket);
 		vdev->ud.tcp_socket = NULL;
 	}
-	uinfo("release socket\n");
+	usbip_uinfo("release socket\n");
 
 	vhci_device_unlink_cleanup(vdev);
 
@@ -873,7 +885,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
 	 */
 	rh_port_disconnect(vdev->rhport);
 
-	uinfo("disconnect device\n");
+	usbip_uinfo("disconnect device\n");
 }
 
 
@@ -939,7 +951,7 @@ static int vhci_start(struct usb_hcd *hcd)
 	int rhport;
 	int err = 0;
 
-	dbg_vhci_hc("enter vhci_start\n");
+	usbip_dbg_vhci_hc("enter vhci_start\n");
 
 
 	/* initialize private data of usb_hcd */
@@ -963,7 +975,7 @@ static int vhci_start(struct usb_hcd *hcd)
 	/* vhci_hcd is now ready to be controlled through sysfs */
 	err = sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
 	if (err) {
-		uerr("create sysfs files\n");
+		usbip_uerr("create sysfs files\n");
 		return err;
 	}
 
@@ -975,7 +987,7 @@ static void vhci_stop(struct usb_hcd *hcd)
 	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
 	int rhport = 0;
 
-	dbg_vhci_hc("stop VHCI controller\n");
+	usbip_dbg_vhci_hc("stop VHCI controller\n");
 
 
 	/* 1. remove the userland interface of vhci_hcd */
@@ -990,14 +1002,14 @@ static void vhci_stop(struct usb_hcd *hcd)
 	}
 
 
-	uinfo("vhci_stop done\n");
+	usbip_uinfo("vhci_stop done\n");
 }
 
 /*----------------------------------------------------------------------*/
 
 static int vhci_get_frame_number(struct usb_hcd *hcd)
 {
-	uerr("Not yet implemented\n");
+	usbip_uerr("Not yet implemented\n");
 	return 0;
 }
 
@@ -1077,9 +1089,9 @@ static int vhci_hcd_probe(struct platform_device *pdev)
 	struct usb_hcd		*hcd;
 	int			ret;
 
-	uinfo("proving...\n");
+	usbip_uinfo("proving...\n");
 
-	dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
+	usbip_dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
 
 	/* will be removed */
 	if (pdev->dev.dma_mask) {
@@ -1093,7 +1105,7 @@ static int vhci_hcd_probe(struct platform_device *pdev)
 	 */
 	hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd) {
-		uerr("create hcd failed\n");
+		usbip_uerr("create hcd failed\n");
 		return -ENOMEM;
 	}
 
@@ -1107,14 +1119,14 @@ static int vhci_hcd_probe(struct platform_device *pdev)
 	 */
 	ret = usb_add_hcd(hcd, 0, 0);
 	if (ret != 0) {
-		uerr("usb_add_hcd failed %d\n", ret);
+		usbip_uerr("usb_add_hcd failed %d\n", ret);
 		usb_put_hcd(hcd);
 		the_controller = NULL;
 		return ret;
 	}
 
 
-	dbg_vhci_hc("bye\n");
+	usbip_dbg_vhci_hc("bye\n");
 	return 0;
 }
 
@@ -1166,11 +1178,11 @@ static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state)
 	spin_unlock(&the_controller->lock);
 
 	if (connected > 0) {
-		uinfo("We have %d active connection%s. Do not suspend.\n",
+		usbip_uinfo("We have %d active connection%s. Do not suspend.\n",
 				connected, (connected == 1 ? "" : "s"));
 		ret =  -EBUSY;
 	} else {
-		uinfo("suspend vhci_hcd");
+		usbip_uinfo("suspend vhci_hcd");
 		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	}
 
@@ -1235,7 +1247,7 @@ static int __init vhci_init(void)
 {
 	int ret;
 
-	dbg_vhci_hc("enter\n");
+	usbip_dbg_vhci_hc("enter\n");
 	if (usb_disabled())
 		return -ENODEV;
 
@@ -1250,7 +1262,7 @@ static int __init vhci_init(void)
 	if (ret < 0)
 		goto err_platform_device_register;
 
-	dbg_vhci_hc("bye\n");
+	usbip_dbg_vhci_hc("bye\n");
 	return ret;
 
 	/* error occurred */
@@ -1258,18 +1270,18 @@ err_platform_device_register:
 	platform_driver_unregister(&vhci_driver);
 
 err_driver_register:
-	dbg_vhci_hc("bye\n");
+	usbip_dbg_vhci_hc("bye\n");
 	return ret;
 }
 module_init(vhci_init);
 
 static void __exit vhci_cleanup(void)
 {
-	dbg_vhci_hc("enter\n");
+	usbip_dbg_vhci_hc("enter\n");
 
 	platform_device_unregister(&the_pdev);
 	platform_driver_unregister(&vhci_driver);
 
-	dbg_vhci_hc("bye\n");
+	usbip_dbg_vhci_hc("bye\n");
 }
 module_exit(vhci_cleanup);
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index 58e3995..7636d86 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -36,7 +36,7 @@ static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
 			urb = priv->urb;
 			status = urb->status;
 
-			dbg_vhci_rx("find urb %p vurb %p seqnum %u\n",
+			usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n",
 				    urb, priv, seqnum);
 
 			/* TODO: fix logic here to improve indent situtation */
@@ -77,8 +77,10 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 
 
 	if (!urb) {
-		uerr("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
-		uinfo("max seqnum %d\n", atomic_read(&the_controller->seqnum));
+		usbip_uerr("cannot find a urb of seqnum %u\n",
+							pdu->base.seqnum);
+		usbip_uinfo("max seqnum %d\n",
+					atomic_read(&the_controller->seqnum));
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
 		return;
 	}
@@ -98,11 +100,11 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 		return;
 
 
-	if (dbg_flag_vhci_rx)
+	if (usbip_dbg_flag_vhci_rx)
 		usbip_dump_urb(urb);
 
 
-	dbg_vhci_rx("now giveback urb %p\n", urb);
+	usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
 
 	spin_lock(&the_controller->lock);
 	usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
@@ -111,7 +113,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
 	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
 
 
-	dbg_vhci_rx("Leave\n");
+	usbip_dbg_vhci_rx("Leave\n");
 
 	return;
 }
@@ -125,9 +127,9 @@ static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
 	spin_lock(&vdev->priv_lock);
 
 	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		uinfo("unlink->seqnum %lu\n", unlink->seqnum);
+		usbip_uinfo("unlink->seqnum %lu\n", unlink->seqnum);
 		if (unlink->seqnum == pdu->base.seqnum) {
-			dbg_vhci_rx("found pending unlink, %lu\n",
+			usbip_dbg_vhci_rx("found pending unlink, %lu\n",
 							unlink->seqnum);
 			list_del(&unlink->list);
 
@@ -152,7 +154,8 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
 
 	unlink = dequeue_pending_unlink(vdev, pdu);
 	if (!unlink) {
-		uinfo("cannot find the pending unlink %u\n", pdu->base.seqnum);
+		usbip_uinfo("cannot find the pending unlink %u\n",
+							pdu->base.seqnum);
 		return;
 	}
 
@@ -163,14 +166,14 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
 		 * already received the result of its submit result and gave
 		 * back the URB.
 		 */
-		uinfo("the urb (seqnum %d) was already given backed\n",
+		usbip_uinfo("the urb (seqnum %d) was already given backed\n",
 							pdu->base.seqnum);
 	} else {
-		dbg_vhci_rx("now giveback urb %p\n", urb);
+		usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
 
 		/* If unlink is succeed, status is -ECONNRESET */
 		urb->status = pdu->u.ret_unlink.status;
-		uinfo("%d\n", urb->status);
+		usbip_uinfo("%d\n", urb->status);
 
 		spin_lock(&the_controller->lock);
 		usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
@@ -193,7 +196,7 @@ static void vhci_rx_pdu(struct usbip_device *ud)
 	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
 
 
-	dbg_vhci_rx("Enter\n");
+	usbip_dbg_vhci_rx("Enter\n");
 
 	memset(&pdu, 0, sizeof(pdu));
 
@@ -201,15 +204,15 @@ static void vhci_rx_pdu(struct usbip_device *ud)
 	/* 1. receive a pdu header */
 	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
 	if (ret != sizeof(pdu)) {
-		uerr("receiving pdu failed! size is %d, should be %d\n",
-				ret, (unsigned int)sizeof(pdu));
+		usbip_uerr("receiving pdu failed! size is %d, should be %d\n",
+					ret, (unsigned int)sizeof(pdu));
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
 		return;
 	}
 
 	usbip_header_correct_endian(&pdu, 0);
 
-	if (dbg_flag_vhci_rx)
+	if (usbip_dbg_flag_vhci_rx)
 		usbip_dump_header(&pdu);
 
 	switch (pdu.base.command) {
@@ -221,7 +224,7 @@ static void vhci_rx_pdu(struct usbip_device *ud)
 		break;
 	default:
 		/* NOTREACHED */
-		uerr("unknown pdu %u\n", pdu.base.command);
+		usbip_uerr("unknown pdu %u\n", pdu.base.command);
 		usbip_dump_header(&pdu);
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
 	}
@@ -237,12 +240,12 @@ void vhci_rx_loop(struct usbip_task *ut)
 
 	while (1) {
 		if (signal_pending(current)) {
-			dbg_vhci_rx("signal catched!\n");
+			usbip_dbg_vhci_rx("signal catched!\n");
 			break;
 		}
 
 
-		if (usbip_event_happend(ud))
+		if (usbip_event_happened(ud))
 			break;
 
 		vhci_rx_pdu(ud);
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index e4c7143..d8992d1 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -80,7 +80,7 @@ static int vhci_port_disconnect(__u32 rhport)
 {
 	struct vhci_device *vdev;
 
-	dbg_vhci_sysfs("enter\n");
+	usbip_dbg_vhci_sysfs("enter\n");
 
 	/* lock */
 	spin_lock(&the_controller->lock);
@@ -89,7 +89,7 @@ static int vhci_port_disconnect(__u32 rhport)
 
 	spin_lock(&vdev->ud.lock);
 	if (vdev->ud.status == VDEV_ST_NULL) {
-		uerr("not connected %d\n", vdev->ud.status);
+		usbip_uerr("not connected %d\n", vdev->ud.status);
 
 		/* unlock */
 		spin_unlock(&vdev->ud.lock);
@@ -117,7 +117,7 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
 
 	/* check rhport */
 	if (rhport >= VHCI_NPORTS) {
-		uerr("invalid port %u\n", rhport);
+		usbip_uerr("invalid port %u\n", rhport);
 		return -EINVAL;
 	}
 
@@ -125,7 +125,7 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
 	if (err < 0)
 		return -EINVAL;
 
-	dbg_vhci_sysfs("Leave\n");
+	usbip_dbg_vhci_sysfs("Leave\n");
 	return count;
 }
 static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
@@ -135,7 +135,7 @@ static int valid_args(__u32 rhport, enum usb_device_speed speed)
 {
 	/* check rhport */
 	if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
-		uerr("port %u\n", rhport);
+		usbip_uerr("port %u\n", rhport);
 		return -EINVAL;
 	}
 
@@ -147,7 +147,7 @@ static int valid_args(__u32 rhport, enum usb_device_speed speed)
 	case USB_SPEED_VARIABLE:
 		break;
 	default:
-		uerr("speed %d\n", speed);
+		usbip_uerr("speed %d\n", speed);
 		return -EINVAL;
 	}
 
@@ -181,8 +181,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
 	 */
 	sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed);
 
-	dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n",
-			rhport, sockfd, devid, speed);
+	usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n",
+				rhport, sockfd, devid, speed);
 
 
 	/* check received parameters */
@@ -208,12 +208,12 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
 		spin_unlock(&vdev->ud.lock);
 		spin_unlock(&the_controller->lock);
 
-		uerr("port %d already used\n", rhport);
+		usbip_uerr("port %d already used\n", rhport);
 		return -EINVAL;
 	}
 
-	uinfo("rhport(%u) sockfd(%d) devid(%u) speed(%u)\n",
-			rhport, sockfd, devid, speed);
+	usbip_uinfo("rhport(%u) sockfd(%d) devid(%u) speed(%u)\n",
+				rhport, sockfd, devid, speed);
 
 	vdev->devid         = devid;
 	vdev->speed         = speed;
diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c
index 1f552a9..7a00eb4 100644
--- a/drivers/staging/usbip/vhci_tx.c
+++ b/drivers/staging/usbip/vhci_tx.c
@@ -26,7 +26,7 @@ static void setup_cmd_submit_pdu(struct usbip_header *pdup,  struct urb *urb)
 	struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
 	struct vhci_device *vdev = priv->vdev;
 
-	dbg_vhci_tx("URB, local devnum %u, remote devid %u\n",
+	usbip_dbg_vhci_tx("URB, local devnum %u, remote devid %u\n",
 				usb_pipedevice(urb->pipe), vdev->devid);
 
 	pdup->base.command = USBIP_CMD_SUBMIT;
@@ -85,7 +85,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 		memset(&msg, 0, sizeof(msg));
 		memset(&iov, 0, sizeof(iov));
 
-		dbg_vhci_tx("setup txdata urb %p\n", urb);
+		usbip_dbg_vhci_tx("setup txdata urb %p\n", urb);
 
 
 		/* 1. setup usbip_header */
@@ -121,15 +121,15 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 
 		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize);
 		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret,
-								txsize);
+			usbip_uerr("sendmsg failed!, retval %d for %zd\n", ret,
+									txsize);
 			kfree(iso_buffer);
 			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
 			return -1;
 		}
 
 		kfree(iso_buffer);
-		dbg_vhci_tx("send txdata\n");
+		usbip_dbg_vhci_tx("send txdata\n");
 
 		total_size += txsize;
 	}
@@ -177,7 +177,7 @@ static int vhci_send_cmd_unlink(struct vhci_device *vdev)
 		memset(&msg, 0, sizeof(msg));
 		memset(&iov, 0, sizeof(iov));
 
-		dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum);
+		usbip_dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum);
 
 
 		/* 1. setup usbip_header */
@@ -195,14 +195,14 @@ static int vhci_send_cmd_unlink(struct vhci_device *vdev)
 
 		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize);
 		if (ret != txsize) {
-			uerr("sendmsg failed!, retval %d for %zd\n", ret,
-								txsize);
+			usbip_uerr("sendmsg failed!, retval %d for %zd\n", ret,
+									txsize);
 			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
 			return -1;
 		}
 
 
-		dbg_vhci_tx("send txdata\n");
+		usbip_dbg_vhci_tx("send txdata\n");
 
 		total_size += txsize;
 	}
@@ -220,7 +220,7 @@ void vhci_tx_loop(struct usbip_task *ut)
 
 	while (1) {
 		if (signal_pending(current)) {
-			uinfo("vhci_tx signal catched\n");
+			usbip_uinfo("vhci_tx signal catched\n");
 			break;
 		}
 
@@ -234,6 +234,6 @@ void vhci_tx_loop(struct usbip_task *ut)
 				(!list_empty(&vdev->priv_tx) ||
 				 !list_empty(&vdev->unlink_tx)));
 
-		dbg_vhci_tx("pending urbs ?, now wake up\n");
+		usbip_dbg_vhci_tx("pending urbs ?, now wake up\n");
 	}
 }
diff --git a/drivers/staging/vme/Kconfig b/drivers/staging/vme/Kconfig
new file mode 100644
index 0000000..ae628a5
--- /dev/null
+++ b/drivers/staging/vme/Kconfig
@@ -0,0 +1,17 @@
+#
+# VME configuration.
+#
+
+menuconfig VME_BUS
+	tristate "VME bridge support"
+	depends on PCI
+	---help---
+	  If you say Y here you get support for the VME bridge Framework.
+
+if VME_BUS
+
+source "drivers/staging/vme/bridges/Kconfig"
+
+source "drivers/staging/vme/devices/Kconfig"
+
+endif # VME
diff --git a/drivers/staging/vme/Makefile b/drivers/staging/vme/Makefile
new file mode 100644
index 0000000..8c3b90e
--- /dev/null
+++ b/drivers/staging/vme/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the VME bridge device drivers.
+#
+obj-$(CONFIG_VME_BUS)		+= vme.o
+
+obj-y				+= bridges/
+obj-y				+= devices/
diff --git a/drivers/staging/vme/TODO b/drivers/staging/vme/TODO
new file mode 100644
index 0000000..adc5fca
--- /dev/null
+++ b/drivers/staging/vme/TODO
@@ -0,0 +1,98 @@
+				TODO
+				====
+
+API
+===
+
+DMA Resource Allocation incomplete
+----------------------------------
+
+The current DMA resource Allocation provides no means of selecting the
+suitability of a DMA controller based on it's supported modes of operation, as
+opposed to the resource allocation mechanisms for master and slave windows:
+
+	struct vme_resource *vme_request_dma(struct device *dev);
+
+As opposed to:
+
+	struct vme_resource * vme_master_request(struct device *dev,
+		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
+
+The TSI148 can perform, VME-to-PCI, PCI-to-VME, PATTERN-to-VME, PATTERN-to-PCI,
+VME-to-VME and PCI-to-PCI transfers. The CA91C142 can only provide VME-to-PCI
+and PCI-to-VME.
+
+Add a mechanism to select a VME controller based on source/target type,
+required aspace, cycle and width requirements.
+
+
+Master window broadcast select mask
+-----------------------------------
+
+API currently provides no method to set or get Broadcast Select mask. Suggest
+somthing like:
+
+	int vme_master_bmsk_set (struct vme_resource *res, int mask);
+	int vme_master_bmsk_get (struct vme_resource *res, int *mask);
+
+
+Interrupt Generation
+--------------------
+
+Add optional timeout when waiting for an IACK.
+
+
+CR/CSR Buffer
+-------------
+
+The VME API provides no functions to access the buffer mapped into the CR/CSR
+space.
+
+
+Mailboxes
+---------
+
+Whilst not part of the VME specification, they are provided by a number of
+chips. They are currently not supported at all by the API.
+
+
+Core
+====
+
+- Rename vme_master_resource's "pci_resource" to be bus agnostic.
+- Improve generic sanity checks (Such as does an offset and size fit within a
+  window and parameter checking).
+
+Bridge Support
+==============
+
+Tempe (tsi148)
+--------------
+
+- Driver can currently only support a single bridge.
+- 2eSST Broadcast mode.
+- Mailboxes unsupported.
+- Improve error detection.
+- Control of prefetch size, threshold.
+- Arbiter control
+- Requestor control
+
+Universe II (ca91c142)
+----------------------
+
+- Driver can currently only support a single bridge.
+- DMA unsupported.
+- RMW transactions unsupported.
+- Location Monitors unsupported.
+- Mailboxes unsupported.
+- Error Detection.
+- Control of prefetch size, threshold.
+- Arbiter control
+- Requestor control
+- Slot detection
+
+Universe I (ca91x042)
+---------------------
+
+Currently completely unsupported.
+
diff --git a/drivers/staging/vme/bridges/Kconfig b/drivers/staging/vme/bridges/Kconfig
new file mode 100644
index 0000000..023cceb
--- /dev/null
+++ b/drivers/staging/vme/bridges/Kconfig
@@ -0,0 +1,13 @@
+comment "VME Bridge Drivers"
+
+config VME_CA91CX42
+	tristate "Universe II"
+	help
+	 If you say Y here you get support for the Tundra CA91C142
+	 (Universe II) VME bridge chip.
+
+config VME_TSI148
+	tristate "Tempe"
+	help
+	 If you say Y here you get support for the Tundra TSI148 VME bridge
+	 chip.
diff --git a/drivers/staging/vme/bridges/Makefile b/drivers/staging/vme/bridges/Makefile
new file mode 100644
index 0000000..59638af
--- /dev/null
+++ b/drivers/staging/vme/bridges/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_VME_CA91CX42)	+= vme_ca91cx42.o
+obj-$(CONFIG_VME_TSI148)	+= vme_tsi148.o
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
new file mode 100644
index 0000000..3d2a84c
--- /dev/null
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -0,0 +1,1933 @@
+/*
+ * Support for the Tundra Universe I/II VME-PCI Bridge Chips
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by Tom Armistead and Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ *
+ * Derived from ca91c042.c by Michael Wyrick
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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/version.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/poll.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "../vme.h"
+#include "../vme_bridge.h"
+#include "vme_ca91cx42.h"
+
+static int __init ca91cx42_init(void);
+static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *);
+static void ca91cx42_remove(struct pci_dev *);
+static void __exit ca91cx42_exit(void);
+
+struct vme_bridge *ca91cx42_bridge;
+wait_queue_head_t dma_queue;
+wait_queue_head_t iack_queue;
+wait_queue_head_t lm_queue;
+wait_queue_head_t mbox_queue;
+
+void (*lm_callback[4])(int);    /* Called in interrupt handler, be careful! */
+void *crcsr_kernel;
+dma_addr_t crcsr_bus;
+
+struct mutex vme_rmw;   /* Only one RMW cycle at a time */
+struct mutex vme_int;   /*
+			 * Only one VME interrupt can be
+			 * generated at a time, provide locking
+			 */
+struct mutex vme_irq;   /* Locking for VME irq callback configuration */
+
+
+
+static char driver_name[] = "vme_ca91cx42";
+
+static struct pci_device_id ca91cx42_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) },
+	{ },
+};
+
+static struct pci_driver ca91cx42_driver = {
+	.name = driver_name,
+	.id_table = ca91cx42_ids,
+	.probe = ca91cx42_probe,
+	.remove = ca91cx42_remove,
+};
+
+static u32 ca91cx42_DMA_irqhandler(void)
+{
+	wake_up(&dma_queue);
+
+	return CA91CX42_LINT_DMA;
+}
+
+static u32 ca91cx42_LM_irqhandler(u32 stat)
+{
+	int i;
+	u32 serviced = 0;
+
+	for (i = 0; i < 4; i++) {
+		if (stat & CA91CX42_LINT_LM[i]) {
+			/* We only enable interrupts if the callback is set */
+			lm_callback[i](i);
+			serviced |= CA91CX42_LINT_LM[i];
+		}
+	}
+
+	return serviced;
+}
+
+/* XXX This needs to be split into 4 queues */
+static u32 ca91cx42_MB_irqhandler(int mbox_mask)
+{
+	wake_up(&mbox_queue);
+
+	return CA91CX42_LINT_MBOX;
+}
+
+static u32 ca91cx42_IACK_irqhandler(void)
+{
+	wake_up(&iack_queue);
+
+	return CA91CX42_LINT_SW_IACK;
+}
+
+#if 0
+int ca91cx42_bus_error_chk(int clrflag)
+{
+	int tmp;
+	tmp = ioread32(ca91cx42_bridge->base + PCI_COMMAND);
+	if (tmp & 0x08000000) {	/* S_TA is Set */
+		if (clrflag)
+			iowrite32(tmp | 0x08000000,
+			       ca91cx42_bridge->base + PCI_COMMAND);
+		return 1;
+	}
+	return 0;
+}
+#endif
+
+static u32 ca91cx42_VERR_irqhandler(void)
+{
+	int val;
+
+	val = ioread32(ca91cx42_bridge->base + DGCS);
+
+	if (!(val & 0x00000800)) {
+		printk(KERN_ERR "ca91c042: ca91cx42_VERR_irqhandler DMA Read "
+			"Error DGCS=%08X\n", val);
+	}
+
+	return CA91CX42_LINT_VERR;
+}
+
+static u32 ca91cx42_LERR_irqhandler(void)
+{
+	int val;
+
+	val = ioread32(ca91cx42_bridge->base + DGCS);
+
+	if (!(val & 0x00000800)) {
+		printk(KERN_ERR "ca91c042: ca91cx42_LERR_irqhandler DMA Read "
+			"Error DGCS=%08X\n", val);
+
+	}
+
+	return CA91CX42_LINT_LERR;
+}
+
+
+static u32 ca91cx42_VIRQ_irqhandler(int stat)
+{
+	int vec, i, serviced = 0;
+	void (*call)(int, int, void *);
+	void *priv_data;
+
+	for (i = 7; i > 0; i--) {
+		if (stat & (1 << i)) {
+			vec = ioread32(ca91cx42_bridge->base +
+				CA91CX42_V_STATID[i]) & 0xff;
+
+			call = ca91cx42_bridge->irq[i - 1].callback[vec].func;
+			priv_data =
+			ca91cx42_bridge->irq[i - 1].callback[vec].priv_data;
+
+			if (call != NULL)
+				call(i, vec, priv_data);
+			else
+				printk("Spurilous VME interrupt, level:%x, "
+					"vector:%x\n", i, vec);
+
+			serviced |= (1 << i);
+		}
+	}
+
+	return serviced;
+}
+
+static irqreturn_t ca91cx42_irqhandler(int irq, void *dev_id)
+{
+	u32 stat, enable, serviced = 0;
+
+	if (dev_id != ca91cx42_bridge->base)
+		return IRQ_NONE;
+
+	enable = ioread32(ca91cx42_bridge->base + LINT_EN);
+	stat = ioread32(ca91cx42_bridge->base + LINT_STAT);
+
+	/* Only look at unmasked interrupts */
+	stat &= enable;
+
+	if (unlikely(!stat))
+		return IRQ_NONE;
+
+	if (stat & CA91CX42_LINT_DMA)
+		serviced |= ca91cx42_DMA_irqhandler();
+	if (stat & (CA91CX42_LINT_LM0 | CA91CX42_LINT_LM1 | CA91CX42_LINT_LM2 |
+			CA91CX42_LINT_LM3))
+		serviced |= ca91cx42_LM_irqhandler(stat);
+	if (stat & CA91CX42_LINT_MBOX)
+		serviced |= ca91cx42_MB_irqhandler(stat);
+	if (stat & CA91CX42_LINT_SW_IACK)
+		serviced |= ca91cx42_IACK_irqhandler();
+	if (stat & CA91CX42_LINT_VERR)
+		serviced |= ca91cx42_VERR_irqhandler();
+	if (stat & CA91CX42_LINT_LERR)
+		serviced |= ca91cx42_LERR_irqhandler();
+	if (stat & (CA91CX42_LINT_VIRQ1 | CA91CX42_LINT_VIRQ2 |
+			CA91CX42_LINT_VIRQ3 | CA91CX42_LINT_VIRQ4 |
+			CA91CX42_LINT_VIRQ5 | CA91CX42_LINT_VIRQ6 |
+			CA91CX42_LINT_VIRQ7))
+		serviced |= ca91cx42_VIRQ_irqhandler(stat);
+
+	/* Clear serviced interrupts */
+	iowrite32(stat, ca91cx42_bridge->base + LINT_STAT);
+
+	return IRQ_HANDLED;
+}
+
+static int ca91cx42_irq_init(struct vme_bridge *bridge)
+{
+	int result, tmp;
+	struct pci_dev *pdev;
+
+	/* Need pdev */
+	pdev = container_of(bridge->parent, struct pci_dev, dev);
+
+	/* Initialise list for VME bus errors */
+	INIT_LIST_HEAD(&(bridge->vme_errors));
+
+	/* Disable interrupts from PCI to VME */
+	iowrite32(0, bridge->base + VINT_EN);
+
+	/* Disable PCI interrupts */
+	iowrite32(0, bridge->base + LINT_EN);
+	/* Clear Any Pending PCI Interrupts */
+	iowrite32(0x00FFFFFF, bridge->base + LINT_STAT);
+
+	result = request_irq(pdev->irq, ca91cx42_irqhandler, IRQF_SHARED,
+			driver_name, pdev);
+	if (result) {
+		dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
+		       pdev->irq);
+		return result;
+	}
+
+	/* Ensure all interrupts are mapped to PCI Interrupt 0 */
+	iowrite32(0, bridge->base + LINT_MAP0);
+	iowrite32(0, bridge->base + LINT_MAP1);
+	iowrite32(0, bridge->base + LINT_MAP2);
+
+	/* Enable DMA, mailbox & LM Interrupts */
+	tmp = CA91CX42_LINT_MBOX3 | CA91CX42_LINT_MBOX2 | CA91CX42_LINT_MBOX1 |
+		CA91CX42_LINT_MBOX0 | CA91CX42_LINT_SW_IACK |
+		CA91CX42_LINT_VERR | CA91CX42_LINT_LERR | CA91CX42_LINT_DMA;
+
+	iowrite32(tmp, bridge->base + LINT_EN);
+
+	return 0;
+}
+
+static void ca91cx42_irq_exit(struct pci_dev *pdev)
+{
+	/* Disable interrupts from PCI to VME */
+	iowrite32(0, ca91cx42_bridge->base + VINT_EN);
+
+	/* Disable PCI interrupts */
+	iowrite32(0, ca91cx42_bridge->base + LINT_EN);
+	/* Clear Any Pending PCI Interrupts */
+	iowrite32(0x00FFFFFF, ca91cx42_bridge->base + LINT_STAT);
+
+	free_irq(pdev->irq, pdev);
+}
+
+/*
+ * Set up an VME interrupt
+ */
+int ca91cx42_request_irq(int level, int statid,
+	void (*callback)(int level, int vector, void *priv_data),
+	void *priv_data)
+{
+	u32 tmp;
+
+	mutex_lock(&(vme_irq));
+
+	if (ca91cx42_bridge->irq[level - 1].callback[statid].func) {
+		mutex_unlock(&(vme_irq));
+		printk("VME Interrupt already taken\n");
+		return -EBUSY;
+	}
+
+
+	ca91cx42_bridge->irq[level - 1].count++;
+	ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = priv_data;
+	ca91cx42_bridge->irq[level - 1].callback[statid].func = callback;
+
+	/* Enable IRQ level */
+	tmp = ioread32(ca91cx42_bridge->base + LINT_EN);
+	tmp |= CA91CX42_LINT_VIRQ[level];
+	iowrite32(tmp, ca91cx42_bridge->base + LINT_EN);
+
+	mutex_unlock(&(vme_irq));
+
+	return 0;
+}
+
+/*
+ * Free VME interrupt
+ */
+void ca91cx42_free_irq(int level, int statid)
+{
+	u32 tmp;
+	struct pci_dev *pdev;
+
+	mutex_lock(&(vme_irq));
+
+	ca91cx42_bridge->irq[level - 1].count--;
+
+	/* Disable IRQ level if no more interrupts attached at this level*/
+	if (ca91cx42_bridge->irq[level - 1].count == 0) {
+		tmp = ioread32(ca91cx42_bridge->base + LINT_EN);
+		tmp &= ~CA91CX42_LINT_VIRQ[level];
+		iowrite32(tmp, ca91cx42_bridge->base + LINT_EN);
+
+		pdev = container_of(ca91cx42_bridge->parent, struct pci_dev,
+			dev);
+
+		synchronize_irq(pdev->irq);
+	}
+
+	ca91cx42_bridge->irq[level - 1].callback[statid].func = NULL;
+	ca91cx42_bridge->irq[level - 1].callback[statid].priv_data = NULL;
+
+	mutex_unlock(&(vme_irq));
+}
+
+int ca91cx42_generate_irq(int level, int statid)
+{
+	u32 tmp;
+
+	/* Universe can only generate even vectors */
+	if (statid & 1)
+		return -EINVAL;
+
+	mutex_lock(&(vme_int));
+
+	tmp = ioread32(ca91cx42_bridge->base + VINT_EN);
+
+	/* Set Status/ID */
+	iowrite32(statid << 24, ca91cx42_bridge->base + STATID);
+
+	/* Assert VMEbus IRQ */
+	tmp = tmp | (1 << (level + 24));
+	iowrite32(tmp, ca91cx42_bridge->base + VINT_EN);
+
+	/* Wait for IACK */
+	wait_event_interruptible(iack_queue, 0);
+
+	/* Return interrupt to low state */
+	tmp = ioread32(ca91cx42_bridge->base + VINT_EN);
+	tmp = tmp & ~(1 << (level + 24));
+	iowrite32(tmp, ca91cx42_bridge->base + VINT_EN);
+
+	mutex_unlock(&(vme_int));
+
+	return 0;
+}
+
+int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled,
+	unsigned long long vme_base, unsigned long long size,
+	dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
+{
+	unsigned int i, addr = 0, granularity = 0;
+	unsigned int temp_ctl = 0;
+	unsigned int vme_bound, pci_offset;
+
+	i = image->number;
+
+	switch (aspace) {
+	case VME_A16:
+		addr |= CA91CX42_VSI_CTL_VAS_A16;
+		break;
+	case VME_A24:
+		addr |= CA91CX42_VSI_CTL_VAS_A24;
+		break;
+	case VME_A32:
+		addr |= CA91CX42_VSI_CTL_VAS_A32;
+		break;
+	case VME_USER1:
+		addr |= CA91CX42_VSI_CTL_VAS_USER1;
+		break;
+	case VME_USER2:
+		addr |= CA91CX42_VSI_CTL_VAS_USER2;
+		break;
+	case VME_A64:
+	case VME_CRCSR:
+	case VME_USER3:
+	case VME_USER4:
+	default:
+		printk(KERN_ERR "Invalid address space\n");
+		return -EINVAL;
+		break;
+	}
+
+	/*
+	 * Bound address is a valid address for the window, adjust
+	 * accordingly
+	 */
+	vme_bound = vme_base + size - granularity;
+	pci_offset = pci_base - vme_base;
+
+	/* XXX Need to check that vme_base, vme_bound and pci_offset aren't
+	 * too big for registers
+	 */
+
+	if ((i == 0) || (i == 4))
+		granularity = 0x1000;
+	else
+		granularity = 0x10000;
+
+	if (vme_base & (granularity - 1)) {
+		printk(KERN_ERR "Invalid VME base alignment\n");
+		return -EINVAL;
+	}
+	if (vme_bound & (granularity - 1)) {
+		printk(KERN_ERR "Invalid VME bound alignment\n");
+		return -EINVAL;
+	}
+	if (pci_offset & (granularity - 1)) {
+		printk(KERN_ERR "Invalid PCI Offset alignment\n");
+		return -EINVAL;
+	}
+
+	/* Disable while we are mucking around */
+	temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+	temp_ctl &= ~CA91CX42_VSI_CTL_EN;
+	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+
+	/* Setup mapping */
+	iowrite32(vme_base, ca91cx42_bridge->base + CA91CX42_VSI_BS[i]);
+	iowrite32(vme_bound, ca91cx42_bridge->base + CA91CX42_VSI_BD[i]);
+	iowrite32(pci_offset, ca91cx42_bridge->base + CA91CX42_VSI_TO[i]);
+
+/* XXX Prefetch stuff currently unsupported */
+#if 0
+	if (vmeIn->wrPostEnable)
+		temp_ctl |= CA91CX42_VSI_CTL_PWEN;
+	if (vmeIn->prefetchEnable)
+		temp_ctl |= CA91CX42_VSI_CTL_PREN;
+	if (vmeIn->rmwLock)
+		temp_ctl |= CA91CX42_VSI_CTL_LLRMW;
+	if (vmeIn->data64BitCapable)
+		temp_ctl |= CA91CX42_VSI_CTL_LD64EN;
+#endif
+
+	/* Setup address space */
+	temp_ctl &= ~CA91CX42_VSI_CTL_VAS_M;
+	temp_ctl |= addr;
+
+	/* Setup cycle types */
+	temp_ctl &= ~(CA91CX42_VSI_CTL_PGM_M | CA91CX42_VSI_CTL_SUPER_M);
+	if (cycle & VME_SUPER)
+		temp_ctl |= CA91CX42_VSI_CTL_SUPER_SUPR;
+	if (cycle & VME_USER)
+		temp_ctl |= CA91CX42_VSI_CTL_SUPER_NPRIV;
+	if (cycle & VME_PROG)
+		temp_ctl |= CA91CX42_VSI_CTL_PGM_PGM;
+	if (cycle & VME_DATA)
+		temp_ctl |= CA91CX42_VSI_CTL_PGM_DATA;
+
+	/* Write ctl reg without enable */
+	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+
+	if (enabled)
+		temp_ctl |= CA91CX42_VSI_CTL_EN;
+
+	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+
+	return 0;
+}
+
+int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle)
+{
+	unsigned int i, granularity = 0, ctl = 0;
+	unsigned long long vme_bound, pci_offset;
+
+	i = image->number;
+
+	if ((i == 0) || (i == 4))
+		granularity = 0x1000;
+	else
+		granularity = 0x10000;
+
+	/* Read Registers */
+	ctl = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_CTL[i]);
+
+	*vme_base = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BS[i]);
+	vme_bound = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_BD[i]);
+	pci_offset = ioread32(ca91cx42_bridge->base + CA91CX42_VSI_TO[i]);
+
+	*pci_base = (dma_addr_t)vme_base + pci_offset;
+	*size = (unsigned long long)((vme_bound - *vme_base) + granularity);
+
+	*enabled = 0;
+	*aspace = 0;
+	*cycle = 0;
+
+	if (ctl & CA91CX42_VSI_CTL_EN)
+		*enabled = 1;
+
+	if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A16)
+		*aspace = VME_A16;
+	if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A24)
+		*aspace = VME_A24;
+	if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_A32)
+		*aspace = VME_A32;
+	if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER1)
+		*aspace = VME_USER1;
+	if ((ctl & CA91CX42_VSI_CTL_VAS_M) == CA91CX42_VSI_CTL_VAS_USER2)
+		*aspace = VME_USER2;
+
+	if (ctl & CA91CX42_VSI_CTL_SUPER_SUPR)
+		*cycle |= VME_SUPER;
+	if (ctl & CA91CX42_VSI_CTL_SUPER_NPRIV)
+		*cycle |= VME_USER;
+	if (ctl & CA91CX42_VSI_CTL_PGM_PGM)
+		*cycle |= VME_PROG;
+	if (ctl & CA91CX42_VSI_CTL_PGM_DATA)
+		*cycle |= VME_DATA;
+
+	return 0;
+}
+
+/*
+ * Allocate and map PCI Resource
+ */
+static int ca91cx42_alloc_resource(struct vme_master_resource *image,
+	unsigned long long size)
+{
+	unsigned long long existing_size;
+	int retval = 0;
+	struct pci_dev *pdev;
+
+	/* Find pci_dev container of dev */
+	if (ca91cx42_bridge->parent == NULL) {
+		printk(KERN_ERR "Dev entry NULL\n");
+		return -EINVAL;
+	}
+	pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev);
+
+	existing_size = (unsigned long long)(image->pci_resource.end -
+		image->pci_resource.start);
+
+	/* If the existing size is OK, return */
+	if (existing_size == (size - 1))
+		return 0;
+
+	if (existing_size != 0) {
+		iounmap(image->kern_base);
+		image->kern_base = NULL;
+		if (image->pci_resource.name != NULL)
+			kfree(image->pci_resource.name);
+		release_resource(&(image->pci_resource));
+		memset(&(image->pci_resource), 0, sizeof(struct resource));
+	}
+
+	if (image->pci_resource.name == NULL) {
+		image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
+		if (image->pci_resource.name == NULL) {
+			printk(KERN_ERR "Unable to allocate memory for resource"
+				" name\n");
+			retval = -ENOMEM;
+			goto err_name;
+		}
+	}
+
+	sprintf((char *)image->pci_resource.name, "%s.%d",
+		ca91cx42_bridge->name, image->number);
+
+	image->pci_resource.start = 0;
+	image->pci_resource.end = (unsigned long)size;
+	image->pci_resource.flags = IORESOURCE_MEM;
+
+	retval = pci_bus_alloc_resource(pdev->bus,
+		&(image->pci_resource), size, size, PCIBIOS_MIN_MEM,
+		0, NULL, NULL);
+	if (retval) {
+		printk(KERN_ERR "Failed to allocate mem resource for "
+			"window %d size 0x%lx start 0x%lx\n",
+			image->number, (unsigned long)size,
+			(unsigned long)image->pci_resource.start);
+		goto err_resource;
+	}
+
+	image->kern_base = ioremap_nocache(
+		image->pci_resource.start, size);
+	if (image->kern_base == NULL) {
+		printk(KERN_ERR "Failed to remap resource\n");
+		retval = -ENOMEM;
+		goto err_remap;
+	}
+
+	return 0;
+
+	iounmap(image->kern_base);
+	image->kern_base = NULL;
+err_remap:
+	release_resource(&(image->pci_resource));
+err_resource:
+	kfree(image->pci_resource.name);
+	memset(&(image->pci_resource), 0, sizeof(struct resource));
+err_name:
+	return retval;
+}
+
+/*
+ *  * Free and unmap PCI Resource
+ *   */
+static void ca91cx42_free_resource(struct vme_master_resource *image)
+{
+	iounmap(image->kern_base);
+	image->kern_base = NULL;
+	release_resource(&(image->pci_resource));
+	kfree(image->pci_resource.name);
+	memset(&(image->pci_resource), 0, sizeof(struct resource));
+}
+
+
+int ca91cx42_master_set(struct vme_master_resource *image, int enabled,
+	unsigned long long vme_base, unsigned long long size,
+	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+{
+	int retval = 0;
+	unsigned int i;
+	unsigned int temp_ctl = 0;
+	unsigned long long pci_bound, vme_offset, pci_base;
+
+	/* Verify input data */
+	if (vme_base & 0xFFF) {
+		printk(KERN_ERR "Invalid VME Window alignment\n");
+		retval = -EINVAL;
+		goto err_window;
+	}
+	if (size & 0xFFF) {
+		printk(KERN_ERR "Invalid VME Window alignment\n");
+		retval = -EINVAL;
+		goto err_window;
+	}
+
+	spin_lock(&(image->lock));
+
+	/* XXX We should do this much later, so that we can exit without
+	 *     needing to redo the mapping...
+	 */
+	/*
+	 * Let's allocate the resource here rather than further up the stack as
+	 * it avoids pushing loads of bus dependant stuff up the stack
+	 */
+	retval = ca91cx42_alloc_resource(image, size);
+	if (retval) {
+		spin_unlock(&(image->lock));
+		printk(KERN_ERR "Unable to allocate memory for resource "
+			"name\n");
+		retval = -ENOMEM;
+		goto err_res;
+	}
+
+	pci_base = (unsigned long long)image->pci_resource.start;
+
+	/*
+	 * Bound address is a valid address for the window, adjust
+	 * according to window granularity.
+	 */
+	pci_bound = pci_base + (size - 0x1000);
+	vme_offset = vme_base - pci_base;
+
+	i = image->number;
+
+	/* Disable while we are mucking around */
+	temp_ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+	temp_ctl &= ~CA91CX42_LSI_CTL_EN;
+	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+
+/* XXX Prefetch stuff currently unsupported */
+#if 0
+	if (vmeOut->wrPostEnable)
+		temp_ctl |= 0x40000000;
+#endif
+
+	/* Setup cycle types */
+	temp_ctl &= ~CA91CX42_LSI_CTL_VCT_M;
+	if (cycle & VME_BLT)
+		temp_ctl |= CA91CX42_LSI_CTL_VCT_BLT;
+	if (cycle & VME_MBLT)
+		temp_ctl |= CA91CX42_LSI_CTL_VCT_MBLT;
+
+	/* Setup data width */
+	temp_ctl &= ~CA91CX42_LSI_CTL_VDW_M;
+	switch (dwidth) {
+	case VME_D8:
+		temp_ctl |= CA91CX42_LSI_CTL_VDW_D8;
+		break;
+	case VME_D16:
+		temp_ctl |= CA91CX42_LSI_CTL_VDW_D16;
+		break;
+	case VME_D32:
+		temp_ctl |= CA91CX42_LSI_CTL_VDW_D32;
+		break;
+	case VME_D64:
+		temp_ctl |= CA91CX42_LSI_CTL_VDW_D64;
+		break;
+	default:
+		spin_unlock(&(image->lock));
+		printk(KERN_ERR "Invalid data width\n");
+		retval = -EINVAL;
+		goto err_dwidth;
+		break;
+	}
+
+	/* Setup address space */
+	temp_ctl &= ~CA91CX42_LSI_CTL_VAS_M;
+	switch (aspace) {
+	case VME_A16:
+		temp_ctl |= CA91CX42_LSI_CTL_VAS_A16;
+		break;
+	case VME_A24:
+		temp_ctl |= CA91CX42_LSI_CTL_VAS_A24;
+		break;
+	case VME_A32:
+		temp_ctl |= CA91CX42_LSI_CTL_VAS_A32;
+		break;
+	case VME_CRCSR:
+		temp_ctl |= CA91CX42_LSI_CTL_VAS_CRCSR;
+		break;
+	case VME_USER1:
+		temp_ctl |= CA91CX42_LSI_CTL_VAS_USER1;
+		break;
+	case VME_USER2:
+		temp_ctl |= CA91CX42_LSI_CTL_VAS_USER2;
+		break;
+	case VME_A64:
+	case VME_USER3:
+	case VME_USER4:
+	default:
+		spin_unlock(&(image->lock));
+		printk(KERN_ERR "Invalid address space\n");
+		retval = -EINVAL;
+		goto err_aspace;
+		break;
+	}
+
+	temp_ctl &= ~(CA91CX42_LSI_CTL_PGM_M | CA91CX42_LSI_CTL_SUPER_M);
+	if (cycle & VME_SUPER)
+		temp_ctl |= CA91CX42_LSI_CTL_SUPER_SUPR;
+	if (cycle & VME_PROG)
+		temp_ctl |= CA91CX42_LSI_CTL_PGM_PGM;
+
+	/* Setup mapping */
+	iowrite32(pci_base, ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
+	iowrite32(pci_bound, ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
+	iowrite32(vme_offset, ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
+
+	/* Write ctl reg without enable */
+	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+
+	if (enabled)
+		temp_ctl |= CA91CX42_LSI_CTL_EN;
+
+	iowrite32(temp_ctl, ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+
+	spin_unlock(&(image->lock));
+	return 0;
+
+err_aspace:
+err_dwidth:
+	ca91cx42_free_resource(image);
+err_res:
+err_window:
+	return retval;
+}
+
+int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+{
+	unsigned int i, ctl;
+	unsigned long long pci_base, pci_bound, vme_offset;
+
+	i = image->number;
+
+	ctl = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_CTL[i]);
+
+	pci_base = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
+	vme_offset = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
+	pci_bound = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
+
+	*vme_base = pci_base + vme_offset;
+	*size = (pci_bound - pci_base) + 0x1000;
+
+	*enabled = 0;
+	*aspace = 0;
+	*cycle = 0;
+	*dwidth = 0;
+
+	if (ctl & CA91CX42_LSI_CTL_EN)
+		*enabled = 1;
+
+	/* Setup address space */
+	switch (ctl & CA91CX42_LSI_CTL_VAS_M) {
+	case CA91CX42_LSI_CTL_VAS_A16:
+		*aspace = VME_A16;
+		break;
+	case CA91CX42_LSI_CTL_VAS_A24:
+		*aspace = VME_A24;
+		break;
+	case CA91CX42_LSI_CTL_VAS_A32:
+		*aspace = VME_A32;
+		break;
+	case CA91CX42_LSI_CTL_VAS_CRCSR:
+		*aspace = VME_CRCSR;
+		break;
+	case CA91CX42_LSI_CTL_VAS_USER1:
+		*aspace = VME_USER1;
+		break;
+	case CA91CX42_LSI_CTL_VAS_USER2:
+		*aspace = VME_USER2;
+		break;
+	}
+
+	/* XXX Not sure howto check for MBLT */
+	/* Setup cycle types */
+	if (ctl & CA91CX42_LSI_CTL_VCT_BLT)
+		*cycle |= VME_BLT;
+	else
+		*cycle |= VME_SCT;
+
+	if (ctl & CA91CX42_LSI_CTL_SUPER_SUPR)
+		*cycle |= VME_SUPER;
+	else
+		*cycle |= VME_USER;
+
+	if (ctl & CA91CX42_LSI_CTL_PGM_PGM)
+		*cycle = VME_PROG;
+	else
+		*cycle = VME_DATA;
+
+	/* Setup data width */
+	switch (ctl & CA91CX42_LSI_CTL_VDW_M) {
+	case CA91CX42_LSI_CTL_VDW_D8:
+		*dwidth = VME_D8;
+		break;
+	case CA91CX42_LSI_CTL_VDW_D16:
+		*dwidth = VME_D16;
+		break;
+	case CA91CX42_LSI_CTL_VDW_D32:
+		*dwidth = VME_D32;
+		break;
+	case CA91CX42_LSI_CTL_VDW_D64:
+		*dwidth = VME_D64;
+		break;
+	}
+
+/* XXX Prefetch stuff currently unsupported */
+#if 0
+	if (ctl & 0x40000000)
+		vmeOut->wrPostEnable = 1;
+#endif
+
+	return 0;
+}
+
+int ca91cx42_master_get(struct vme_master_resource *image, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+{
+	int retval;
+
+	spin_lock(&(image->lock));
+
+	retval = __ca91cx42_master_get(image, enabled, vme_base, size, aspace,
+		cycle, dwidth);
+
+	spin_unlock(&(image->lock));
+
+	return retval;
+}
+
+ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf,
+	size_t count, loff_t offset)
+{
+	int retval;
+
+	spin_lock(&(image->lock));
+
+	memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count);
+	retval = count;
+
+	spin_unlock(&(image->lock));
+
+	return retval;
+}
+
+ssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf,
+	size_t count, loff_t offset)
+{
+	int retval = 0;
+
+	spin_lock(&(image->lock));
+
+	memcpy_toio(image->kern_base + offset, buf, (unsigned int)count);
+	retval = count;
+
+	spin_unlock(&(image->lock));
+
+	return retval;
+}
+
+int ca91cx42_slot_get(void)
+{
+	u32 slot = 0;
+
+	slot = ioread32(ca91cx42_bridge->base + VCSR_BS);
+	slot = ((slot & CA91CX42_VCSR_BS_SLOT_M) >> 27);
+	return (int)slot;
+
+}
+
+static int __init ca91cx42_init(void)
+{
+	return pci_register_driver(&ca91cx42_driver);
+}
+
+/*
+ * Configure CR/CSR space
+ *
+ * Access to the CR/CSR can be configured at power-up. The location of the
+ * CR/CSR registers in the CR/CSR address space is determined by the boards
+ * Auto-ID or Geographic address. This function ensures that the window is
+ * enabled at an offset consistent with the boards geopgraphic address.
+ */
+static int ca91cx42_crcsr_init(struct pci_dev *pdev)
+{
+	unsigned int crcsr_addr;
+	int tmp, slot;
+
+/* XXX We may need to set this somehow as the Universe II does not support
+ *     geographical addressing.
+ */
+#if 0
+	if (vme_slotnum != -1)
+		iowrite32(vme_slotnum << 27, ca91cx42_bridge->base + VCSR_BS);
+#endif
+	slot = ca91cx42_slot_get();
+	dev_info(&pdev->dev, "CR/CSR Offset: %d\n", slot);
+	if (slot == 0) {
+		dev_err(&pdev->dev, "Slot number is unset, not configuring "
+			"CR/CSR space\n");
+		return -EINVAL;
+	}
+
+	/* Allocate mem for CR/CSR image */
+	crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
+		&crcsr_bus);
+	if (crcsr_kernel == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
+			"image\n");
+		return -ENOMEM;
+	}
+
+	memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
+
+	crcsr_addr = slot * (512 * 1024);
+	iowrite32(crcsr_bus - crcsr_addr, ca91cx42_bridge->base + VCSR_TO);
+
+	tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL);
+	tmp |= CA91CX42_VCSR_CTL_EN;
+	iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL);
+
+	return 0;
+}
+
+static void ca91cx42_crcsr_exit(struct pci_dev *pdev)
+{
+	u32 tmp;
+
+	/* Turn off CR/CSR space */
+	tmp = ioread32(ca91cx42_bridge->base + VCSR_CTL);
+	tmp &= ~CA91CX42_VCSR_CTL_EN;
+	iowrite32(tmp, ca91cx42_bridge->base + VCSR_CTL);
+
+	/* Free image */
+	iowrite32(0, ca91cx42_bridge->base + VCSR_TO);
+
+	pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus);
+}
+
+static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	int retval, i;
+	u32 data;
+	struct list_head *pos = NULL;
+	struct vme_master_resource *master_image;
+	struct vme_slave_resource *slave_image;
+#if 0
+	struct vme_dma_resource *dma_ctrlr;
+#endif
+	struct vme_lm_resource *lm;
+
+	/* We want to support more than one of each bridge so we need to
+	 * dynamically allocate the bridge structure
+	 */
+	ca91cx42_bridge = kmalloc(sizeof(struct vme_bridge), GFP_KERNEL);
+
+	if (ca91cx42_bridge == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for device "
+			"structure\n");
+		retval = -ENOMEM;
+		goto err_struct;
+	}
+
+	memset(ca91cx42_bridge, 0, sizeof(struct vme_bridge));
+
+	/* Enable the device */
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to enable device\n");
+		goto err_enable;
+	}
+
+	/* Map Registers */
+	retval = pci_request_regions(pdev, driver_name);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to reserve resources\n");
+		goto err_resource;
+	}
+
+	/* map registers in BAR 0 */
+	ca91cx42_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0),
+		4096);
+	if (!ca91cx42_bridge->base) {
+		dev_err(&pdev->dev, "Unable to remap CRG region\n");
+		retval = -EIO;
+		goto err_remap;
+	}
+
+	/* Check to see if the mapping worked out */
+	data = ioread32(ca91cx42_bridge->base + CA91CX42_PCI_ID) & 0x0000FFFF;
+	if (data != PCI_VENDOR_ID_TUNDRA) {
+		dev_err(&pdev->dev, "PCI_ID check failed\n");
+		retval = -EIO;
+		goto err_test;
+	}
+
+	/* Initialize wait queues & mutual exclusion flags */
+	/* XXX These need to be moved to the vme_bridge structure */
+	init_waitqueue_head(&dma_queue);
+	init_waitqueue_head(&iack_queue);
+	mutex_init(&(vme_int));
+	mutex_init(&(vme_irq));
+	mutex_init(&(vme_rmw));
+
+	ca91cx42_bridge->parent = &(pdev->dev);
+	strcpy(ca91cx42_bridge->name, driver_name);
+
+	/* Setup IRQ */
+	retval = ca91cx42_irq_init(ca91cx42_bridge);
+	if (retval != 0) {
+		dev_err(&pdev->dev, "Chip Initialization failed.\n");
+		goto err_irq;
+	}
+
+	/* Add master windows to list */
+	INIT_LIST_HEAD(&(ca91cx42_bridge->master_resources));
+	for (i = 0; i < CA91C142_MAX_MASTER; i++) {
+		master_image = kmalloc(sizeof(struct vme_master_resource),
+			GFP_KERNEL);
+		if (master_image == NULL) {
+			dev_err(&pdev->dev, "Failed to allocate memory for "
+			"master resource structure\n");
+			retval = -ENOMEM;
+			goto err_master;
+		}
+		master_image->parent = ca91cx42_bridge;
+		spin_lock_init(&(master_image->lock));
+		master_image->locked = 0;
+		master_image->number = i;
+		master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+			VME_CRCSR | VME_USER1 | VME_USER2;
+		master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+			VME_SUPER | VME_USER | VME_PROG | VME_DATA;
+		master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64;
+		memset(&(master_image->pci_resource), 0,
+			sizeof(struct resource));
+		master_image->kern_base  = NULL;
+		list_add_tail(&(master_image->list),
+			&(ca91cx42_bridge->master_resources));
+	}
+
+	/* Add slave windows to list */
+	INIT_LIST_HEAD(&(ca91cx42_bridge->slave_resources));
+	for (i = 0; i < CA91C142_MAX_SLAVE; i++) {
+		slave_image = kmalloc(sizeof(struct vme_slave_resource),
+			GFP_KERNEL);
+		if (slave_image == NULL) {
+			dev_err(&pdev->dev, "Failed to allocate memory for "
+			"slave resource structure\n");
+			retval = -ENOMEM;
+			goto err_slave;
+		}
+		slave_image->parent = ca91cx42_bridge;
+		mutex_init(&(slave_image->mtx));
+		slave_image->locked = 0;
+		slave_image->number = i;
+		slave_image->address_attr = VME_A24 | VME_A32 | VME_USER1 |
+			VME_USER2;
+
+		/* Only windows 0 and 4 support A16 */
+		if (i == 0 || i == 4)
+			slave_image->address_attr |= VME_A16;
+
+		slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+			VME_SUPER | VME_USER | VME_PROG | VME_DATA;
+		list_add_tail(&(slave_image->list),
+			&(ca91cx42_bridge->slave_resources));
+	}
+#if 0
+	/* Add dma engines to list */
+	INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources));
+	for (i = 0; i < CA91C142_MAX_DMA; i++) {
+		dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource),
+			GFP_KERNEL);
+		if (dma_ctrlr == NULL) {
+			dev_err(&pdev->dev, "Failed to allocate memory for "
+			"dma resource structure\n");
+			retval = -ENOMEM;
+			goto err_dma;
+		}
+		dma_ctrlr->parent = ca91cx42_bridge;
+		mutex_init(&(dma_ctrlr->mtx));
+		dma_ctrlr->locked = 0;
+		dma_ctrlr->number = i;
+		INIT_LIST_HEAD(&(dma_ctrlr->pending));
+		INIT_LIST_HEAD(&(dma_ctrlr->running));
+		list_add_tail(&(dma_ctrlr->list),
+			&(ca91cx42_bridge->dma_resources));
+	}
+#endif
+	/* Add location monitor to list */
+	INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources));
+	lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
+	if (lm == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for "
+		"location monitor resource structure\n");
+		retval = -ENOMEM;
+		goto err_lm;
+	}
+	lm->parent = ca91cx42_bridge;
+	mutex_init(&(lm->mtx));
+	lm->locked = 0;
+	lm->number = 1;
+	lm->monitors = 4;
+	list_add_tail(&(lm->list), &(ca91cx42_bridge->lm_resources));
+
+	ca91cx42_bridge->slave_get = ca91cx42_slave_get;
+	ca91cx42_bridge->slave_set = ca91cx42_slave_set;
+	ca91cx42_bridge->master_get = ca91cx42_master_get;
+	ca91cx42_bridge->master_set = ca91cx42_master_set;
+	ca91cx42_bridge->master_read = ca91cx42_master_read;
+	ca91cx42_bridge->master_write = ca91cx42_master_write;
+#if 0
+	ca91cx42_bridge->master_rmw = ca91cx42_master_rmw;
+	ca91cx42_bridge->dma_list_add = ca91cx42_dma_list_add;
+	ca91cx42_bridge->dma_list_exec = ca91cx42_dma_list_exec;
+	ca91cx42_bridge->dma_list_empty = ca91cx42_dma_list_empty;
+#endif
+	ca91cx42_bridge->request_irq = ca91cx42_request_irq;
+	ca91cx42_bridge->free_irq = ca91cx42_free_irq;
+	ca91cx42_bridge->generate_irq = ca91cx42_generate_irq;
+#if 0
+	ca91cx42_bridge->lm_set = ca91cx42_lm_set;
+	ca91cx42_bridge->lm_get = ca91cx42_lm_get;
+	ca91cx42_bridge->lm_attach = ca91cx42_lm_attach;
+	ca91cx42_bridge->lm_detach = ca91cx42_lm_detach;
+#endif
+	ca91cx42_bridge->slot_get = ca91cx42_slot_get;
+
+	data = ioread32(ca91cx42_bridge->base + MISC_CTL);
+	dev_info(&pdev->dev, "Board is%s the VME system controller\n",
+		(data & CA91CX42_MISC_CTL_SYSCON) ? "" : " not");
+	dev_info(&pdev->dev, "Slot ID is %d\n", ca91cx42_slot_get());
+
+	if (ca91cx42_crcsr_init(pdev)) {
+		dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
+		retval = -EINVAL;
+#if 0
+		goto err_crcsr;
+#endif
+	}
+
+	/* Need to save ca91cx42_bridge pointer locally in link list for use in
+	 * ca91cx42_remove()
+	 */
+	retval = vme_register_bridge(ca91cx42_bridge);
+	if (retval != 0) {
+		dev_err(&pdev->dev, "Chip Registration failed.\n");
+		goto err_reg;
+	}
+
+	return 0;
+
+	vme_unregister_bridge(ca91cx42_bridge);
+err_reg:
+	ca91cx42_crcsr_exit(pdev);
+err_crcsr:
+err_lm:
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
+		lm = list_entry(pos, struct vme_lm_resource, list);
+		list_del(pos);
+		kfree(lm);
+	}
+#if 0
+err_dma:
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->dma_resources)) {
+		dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
+		list_del(pos);
+		kfree(dma_ctrlr);
+	}
+#endif
+err_slave:
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->slave_resources)) {
+		slave_image = list_entry(pos, struct vme_slave_resource, list);
+		list_del(pos);
+		kfree(slave_image);
+	}
+err_master:
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->master_resources)) {
+		master_image = list_entry(pos, struct vme_master_resource,
+			list);
+		list_del(pos);
+		kfree(master_image);
+	}
+
+	ca91cx42_irq_exit(pdev);
+err_irq:
+err_test:
+	iounmap(ca91cx42_bridge->base);
+err_remap:
+	pci_release_regions(pdev);
+err_resource:
+	pci_disable_device(pdev);
+err_enable:
+	kfree(ca91cx42_bridge);
+err_struct:
+	return retval;
+
+}
+
+void ca91cx42_remove(struct pci_dev *pdev)
+{
+	struct list_head *pos = NULL;
+	struct vme_master_resource *master_image;
+	struct vme_slave_resource *slave_image;
+	struct vme_dma_resource *dma_ctrlr;
+	struct vme_lm_resource *lm;
+	int i;
+
+	/* Turn off Ints */
+	iowrite32(0, ca91cx42_bridge->base + LINT_EN);
+
+	/* Turn off the windows */
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI0_CTL);
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI1_CTL);
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI2_CTL);
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI3_CTL);
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI4_CTL);
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI5_CTL);
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI6_CTL);
+	iowrite32(0x00800000, ca91cx42_bridge->base + LSI7_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI0_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI1_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI2_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI3_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI4_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI5_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI6_CTL);
+	iowrite32(0x00F00000, ca91cx42_bridge->base + VSI7_CTL);
+
+	vme_unregister_bridge(ca91cx42_bridge);
+#if 0
+	ca91cx42_crcsr_exit(pdev);
+#endif
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->lm_resources)) {
+		lm = list_entry(pos, struct vme_lm_resource, list);
+		list_del(pos);
+		kfree(lm);
+	}
+
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->dma_resources)) {
+		dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
+		list_del(pos);
+		kfree(dma_ctrlr);
+	}
+
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->slave_resources)) {
+		slave_image = list_entry(pos, struct vme_slave_resource, list);
+		list_del(pos);
+		kfree(slave_image);
+	}
+
+	/* resources are stored in link list */
+	list_for_each(pos, &(ca91cx42_bridge->master_resources)) {
+		master_image = list_entry(pos, struct vme_master_resource,
+			list);
+		list_del(pos);
+		kfree(master_image);
+	}
+
+	ca91cx42_irq_exit(pdev);
+
+	iounmap(ca91cx42_bridge->base);
+
+	pci_release_regions(pdev);
+
+	pci_disable_device(pdev);
+
+	kfree(ca91cx42_bridge);
+}
+
+static void __exit ca91cx42_exit(void)
+{
+	pci_unregister_driver(&ca91cx42_driver);
+}
+
+MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge");
+MODULE_LICENSE("GPL");
+
+module_init(ca91cx42_init);
+module_exit(ca91cx42_exit);
+
+/*----------------------------------------------------------------------------
+ * STAGING
+ *--------------------------------------------------------------------------*/
+
+#if 0
+#define	SWIZZLE(X) ( ((X & 0xFF000000) >> 24) | ((X & 0x00FF0000) >>  8) | ((X & 0x0000FF00) <<  8) | ((X & 0x000000FF) << 24))
+
+int ca91cx42_master_rmw(vmeRmwCfg_t *vmeRmw)
+{
+	int temp_ctl = 0;
+	int tempBS = 0;
+	int tempBD = 0;
+	int tempTO = 0;
+	int vmeBS = 0;
+	int vmeBD = 0;
+	int *rmw_pci_data_ptr = NULL;
+	int *vaDataPtr = NULL;
+	int i;
+	vmeOutWindowCfg_t vmeOut;
+	if (vmeRmw->maxAttempts < 1) {
+		return -EINVAL;
+	}
+	if (vmeRmw->targetAddrU) {
+		return -EINVAL;
+	}
+	/* Find the PCI address that maps to the desired VME address */
+	for (i = 0; i < 8; i++) {
+		temp_ctl = ioread32(ca91cx42_bridge->base +
+			CA91CX42_LSI_CTL[i]);
+		if ((temp_ctl & 0x80000000) == 0) {
+			continue;
+		}
+		memset(&vmeOut, 0, sizeof(vmeOut));
+		vmeOut.windowNbr = i;
+		ca91cx42_get_out_bound(&vmeOut);
+		if (vmeOut.addrSpace != vmeRmw->addrSpace) {
+			continue;
+		}
+		tempBS = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BS[i]);
+		tempBD = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_BD[i]);
+		tempTO = ioread32(ca91cx42_bridge->base + CA91CX42_LSI_TO[i]);
+		vmeBS = tempBS + tempTO;
+		vmeBD = tempBD + tempTO;
+		if ((vmeRmw->targetAddr >= vmeBS) &&
+		    (vmeRmw->targetAddr < vmeBD)) {
+			rmw_pci_data_ptr =
+			    (int *)(tempBS + (vmeRmw->targetAddr - vmeBS));
+			vaDataPtr =
+			    (int *)(out_image_va[i] +
+				    (vmeRmw->targetAddr - vmeBS));
+			break;
+		}
+	}
+
+	/* If no window - fail. */
+	if (rmw_pci_data_ptr == NULL) {
+		return -EINVAL;
+	}
+	/* Setup the RMW registers. */
+	iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
+	iowrite32(SWIZZLE(vmeRmw->enableMask), ca91cx42_bridge->base + SCYC_EN);
+	iowrite32(SWIZZLE(vmeRmw->compareData), ca91cx42_bridge->base +
+		SCYC_CMP);
+	iowrite32(SWIZZLE(vmeRmw->swapData), ca91cx42_bridge->base + SCYC_SWP);
+	iowrite32((int)rmw_pci_data_ptr, ca91cx42_bridge->base + SCYC_ADDR);
+	iowrite32(1, ca91cx42_bridge->base + SCYC_CTL);
+
+	/* Run the RMW cycle until either success or max attempts. */
+	vmeRmw->numAttempts = 1;
+	while (vmeRmw->numAttempts <= vmeRmw->maxAttempts) {
+
+		if ((ioread32(vaDataPtr) & vmeRmw->enableMask) ==
+		    (vmeRmw->swapData & vmeRmw->enableMask)) {
+
+			iowrite32(0, ca91cx42_bridge->base + SCYC_CTL);
+			break;
+
+		}
+		vmeRmw->numAttempts++;
+	}
+
+	/* If no success, set num Attempts to be greater than max attempts */
+	if (vmeRmw->numAttempts > vmeRmw->maxAttempts) {
+		vmeRmw->numAttempts = vmeRmw->maxAttempts + 1;
+	}
+
+	return 0;
+}
+
+int uniSetupDctlReg(vmeDmaPacket_t * vmeDma, int *dctlregreturn)
+{
+	unsigned int dctlreg = 0x80;
+	struct vmeAttr *vmeAttr;
+
+	if (vmeDma->srcBus == VME_DMA_VME) {
+		dctlreg = 0;
+		vmeAttr = &vmeDma->srcVmeAttr;
+	} else {
+		dctlreg = 0x80000000;
+		vmeAttr = &vmeDma->dstVmeAttr;
+	}
+
+	switch (vmeAttr->maxDataWidth) {
+	case VME_D8:
+		break;
+	case VME_D16:
+		dctlreg |= 0x00400000;
+		break;
+	case VME_D32:
+		dctlreg |= 0x00800000;
+		break;
+	case VME_D64:
+		dctlreg |= 0x00C00000;
+		break;
+	}
+
+	switch (vmeAttr->addrSpace) {
+	case VME_A16:
+		break;
+	case VME_A24:
+		dctlreg |= 0x00010000;
+		break;
+	case VME_A32:
+		dctlreg |= 0x00020000;
+		break;
+	case VME_USER1:
+		dctlreg |= 0x00060000;
+		break;
+	case VME_USER2:
+		dctlreg |= 0x00070000;
+		break;
+
+	case VME_A64:		/* not supported in Universe DMA */
+	case VME_CRCSR:
+	case VME_USER3:
+	case VME_USER4:
+		return -EINVAL;
+		break;
+	}
+	if (vmeAttr->userAccessType == VME_PROG) {
+		dctlreg |= 0x00004000;
+	}
+	if (vmeAttr->dataAccessType == VME_SUPER) {
+		dctlreg |= 0x00001000;
+	}
+	if (vmeAttr->xferProtocol != VME_SCT) {
+		dctlreg |= 0x00000100;
+	}
+	*dctlregreturn = dctlreg;
+	return 0;
+}
+
+unsigned int
+ca91cx42_start_dma(int channel, unsigned int dgcsreg, TDMA_Cmd_Packet *vmeLL)
+{
+	unsigned int val;
+
+	/* Setup registers as needed for direct or chained. */
+	if (dgcsreg & 0x8000000) {
+		iowrite32(0, ca91cx42_bridge->base + DTBC);
+		iowrite32((unsigned int)vmeLL, ca91cx42_bridge->base + DCPP);
+	} else {
+#if	0
+		printk(KERN_ERR "Starting: DGCS = %08x\n", dgcsreg);
+		printk(KERN_ERR "Starting: DVA  = %08x\n",
+			ioread32(&vmeLL->dva));
+		printk(KERN_ERR "Starting: DLV  = %08x\n",
+			ioread32(&vmeLL->dlv));
+		printk(KERN_ERR "Starting: DTBC = %08x\n",
+			ioread32(&vmeLL->dtbc));
+		printk(KERN_ERR "Starting: DCTL = %08x\n",
+			ioread32(&vmeLL->dctl));
+#endif
+		/* Write registers */
+		iowrite32(ioread32(&vmeLL->dva), ca91cx42_bridge->base + DVA);
+		iowrite32(ioread32(&vmeLL->dlv), ca91cx42_bridge->base + DLA);
+		iowrite32(ioread32(&vmeLL->dtbc), ca91cx42_bridge->base + DTBC);
+		iowrite32(ioread32(&vmeLL->dctl), ca91cx42_bridge->base + DCTL);
+		iowrite32(0, ca91cx42_bridge->base + DCPP);
+	}
+
+	/* Start the operation */
+	iowrite32(dgcsreg, ca91cx42_bridge->base + DGCS);
+	val = get_tbl();
+	iowrite32(dgcsreg | 0x8000000F, ca91cx42_bridge->base + DGCS);
+	return val;
+}
+
+TDMA_Cmd_Packet *ca91cx42_setup_dma(vmeDmaPacket_t * vmeDma)
+{
+	vmeDmaPacket_t *vmeCur;
+	int maxPerPage;
+	int currentLLcount;
+	TDMA_Cmd_Packet *startLL;
+	TDMA_Cmd_Packet *currentLL;
+	TDMA_Cmd_Packet *nextLL;
+	unsigned int dctlreg = 0;
+
+	maxPerPage = PAGESIZE / sizeof(TDMA_Cmd_Packet) - 1;
+	startLL = (TDMA_Cmd_Packet *) __get_free_pages(GFP_KERNEL, 0);
+	if (startLL == 0) {
+		return startLL;
+	}
+	/* First allocate pages for descriptors and create linked list */
+	vmeCur = vmeDma;
+	currentLL = startLL;
+	currentLLcount = 0;
+	while (vmeCur != 0) {
+		if (vmeCur->pNextPacket != 0) {
+			currentLL->dcpp = (unsigned int)(currentLL + 1);
+			currentLLcount++;
+			if (currentLLcount >= maxPerPage) {
+				currentLL->dcpp =
+				    __get_free_pages(GFP_KERNEL, 0);
+				currentLLcount = 0;
+			}
+			currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		} else {
+			currentLL->dcpp = (unsigned int)0;
+		}
+		vmeCur = vmeCur->pNextPacket;
+	}
+
+	/* Next fill in information for each descriptor */
+	vmeCur = vmeDma;
+	currentLL = startLL;
+	while (vmeCur != 0) {
+		if (vmeCur->srcBus == VME_DMA_VME) {
+			iowrite32(vmeCur->srcAddr, &currentLL->dva);
+			iowrite32(vmeCur->dstAddr, &currentLL->dlv);
+		} else {
+			iowrite32(vmeCur->srcAddr, &currentLL->dlv);
+			iowrite32(vmeCur->dstAddr, &currentLL->dva);
+		}
+		uniSetupDctlReg(vmeCur, &dctlreg);
+		iowrite32(dctlreg, &currentLL->dctl);
+		iowrite32(vmeCur->byteCount, &currentLL->dtbc);
+
+		currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		vmeCur = vmeCur->pNextPacket;
+	}
+
+	/* Convert Links to PCI addresses. */
+	currentLL = startLL;
+	while (currentLL != 0) {
+		nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		if (nextLL == 0) {
+			iowrite32(1, &currentLL->dcpp);
+		} else {
+			iowrite32((unsigned int)virt_to_bus(nextLL),
+			       &currentLL->dcpp);
+		}
+		currentLL = nextLL;
+	}
+
+	/* Return pointer to descriptors list */
+	return startLL;
+}
+
+int ca91cx42_free_dma(TDMA_Cmd_Packet *startLL)
+{
+	TDMA_Cmd_Packet *currentLL;
+	TDMA_Cmd_Packet *prevLL;
+	TDMA_Cmd_Packet *nextLL;
+	unsigned int dcppreg;
+
+	/* Convert Links to virtual addresses. */
+	currentLL = startLL;
+	while (currentLL != 0) {
+		dcppreg = ioread32(&currentLL->dcpp);
+		dcppreg &= ~6;
+		if (dcppreg & 1) {
+			currentLL->dcpp = 0;
+		} else {
+			currentLL->dcpp = (unsigned int)bus_to_virt(dcppreg);
+		}
+		currentLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+	}
+
+	/* Free all pages associated with the descriptors. */
+	currentLL = startLL;
+	prevLL = currentLL;
+	while (currentLL != 0) {
+		nextLL = (TDMA_Cmd_Packet *) currentLL->dcpp;
+		if (currentLL + 1 != nextLL) {
+			free_pages((int)prevLL, 0);
+			prevLL = nextLL;
+		}
+		currentLL = nextLL;
+	}
+
+	/* Return pointer to descriptors list */
+	return 0;
+}
+
+int ca91cx42_do_dma(vmeDmaPacket_t *vmeDma)
+{
+	unsigned int dgcsreg = 0;
+	unsigned int dctlreg = 0;
+	int val;
+	int channel, x;
+	vmeDmaPacket_t *curDma;
+	TDMA_Cmd_Packet *dmaLL;
+
+	/* Sanity check the VME chain. */
+	channel = vmeDma->channel_number;
+	if (channel > 0) {
+		return -EINVAL;
+	}
+	curDma = vmeDma;
+	while (curDma != 0) {
+		if (curDma->byteCount == 0) {
+			return -EINVAL;
+		}
+		if (curDma->byteCount >= 0x1000000) {
+			return -EINVAL;
+		}
+		if ((curDma->srcAddr & 7) != (curDma->dstAddr & 7)) {
+			return -EINVAL;
+		}
+		switch (curDma->srcBus) {
+		case VME_DMA_PCI:
+			if (curDma->dstBus != VME_DMA_VME) {
+				return -EINVAL;
+			}
+			break;
+		case VME_DMA_VME:
+			if (curDma->dstBus != VME_DMA_PCI) {
+				return -EINVAL;
+			}
+			break;
+		default:
+			return -EINVAL;
+			break;
+		}
+		if (uniSetupDctlReg(curDma, &dctlreg) < 0) {
+			return -EINVAL;
+		}
+
+		curDma = curDma->pNextPacket;
+		if (curDma == vmeDma) {	/* Endless Loop! */
+			return -EINVAL;
+		}
+	}
+
+	/* calculate control register */
+	if (vmeDma->pNextPacket != 0) {
+		dgcsreg = 0x8000000;
+	} else {
+		dgcsreg = 0;
+	}
+
+	for (x = 0; x < 8; x++) {	/* vme block size */
+		if ((256 << x) >= vmeDma->maxVmeBlockSize) {
+			break;
+		}
+	}
+	if (x == 8)
+		x = 7;
+	dgcsreg |= (x << 20);
+
+	if (vmeDma->vmeBackOffTimer) {
+		for (x = 1; x < 8; x++) {	/* vme timer */
+			if ((16 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
+				break;
+			}
+		}
+		if (x == 8)
+			x = 7;
+		dgcsreg |= (x << 16);
+	}
+	/*` Setup the dma chain */
+	dmaLL = ca91cx42_setup_dma(vmeDma);
+
+	/* Start the DMA */
+	if (dgcsreg & 0x8000000) {
+		vmeDma->vmeDmaStartTick =
+		    ca91cx42_start_dma(channel, dgcsreg,
+				  (TDMA_Cmd_Packet *) virt_to_phys(dmaLL));
+	} else {
+		vmeDma->vmeDmaStartTick =
+		    ca91cx42_start_dma(channel, dgcsreg, dmaLL);
+	}
+
+	wait_event_interruptible(dma_queue,
+		ioread32(ca91cx42_bridge->base + DGCS) & 0x800);
+
+	val = ioread32(ca91cx42_bridge->base + DGCS);
+	iowrite32(val | 0xF00, ca91cx42_bridge->base + DGCS);
+
+	vmeDma->vmeDmaStatus = 0;
+
+	if (!(val & 0x00000800)) {
+		vmeDma->vmeDmaStatus = val & 0x700;
+		printk(KERN_ERR "ca91c042: DMA Error in ca91cx42_DMA_irqhandler"
+			" DGCS=%08X\n", val);
+		val = ioread32(ca91cx42_bridge->base + DCPP);
+		printk(KERN_ERR "ca91c042: DCPP=%08X\n", val);
+		val = ioread32(ca91cx42_bridge->base + DCTL);
+		printk(KERN_ERR "ca91c042: DCTL=%08X\n", val);
+		val = ioread32(ca91cx42_bridge->base + DTBC);
+		printk(KERN_ERR "ca91c042: DTBC=%08X\n", val);
+		val = ioread32(ca91cx42_bridge->base + DLA);
+		printk(KERN_ERR "ca91c042: DLA=%08X\n", val);
+		val = ioread32(ca91cx42_bridge->base + DVA);
+		printk(KERN_ERR "ca91c042: DVA=%08X\n", val);
+
+	}
+	/* Free the dma chain */
+	ca91cx42_free_dma(dmaLL);
+
+	return 0;
+}
+
+int ca91cx42_lm_set(vmeLmCfg_t *vmeLm)
+{
+	int temp_ctl = 0;
+
+	if (vmeLm->addrU)
+		return -EINVAL;
+
+	switch (vmeLm->addrSpace) {
+	case VME_A64:
+	case VME_USER3:
+	case VME_USER4:
+		return -EINVAL;
+	case VME_A16:
+		temp_ctl |= 0x00000;
+		break;
+	case VME_A24:
+		temp_ctl |= 0x10000;
+		break;
+	case VME_A32:
+		temp_ctl |= 0x20000;
+		break;
+	case VME_CRCSR:
+		temp_ctl |= 0x50000;
+		break;
+	case VME_USER1:
+		temp_ctl |= 0x60000;
+		break;
+	case VME_USER2:
+		temp_ctl |= 0x70000;
+		break;
+	}
+
+	/* Disable while we are mucking around */
+	iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
+
+	iowrite32(vmeLm->addr, ca91cx42_bridge->base + LM_BS);
+
+	/* Setup CTL register. */
+	if (vmeLm->userAccessType & VME_SUPER)
+		temp_ctl |= 0x00200000;
+	if (vmeLm->userAccessType & VME_USER)
+		temp_ctl |= 0x00100000;
+	if (vmeLm->dataAccessType & VME_PROG)
+		temp_ctl |= 0x00800000;
+	if (vmeLm->dataAccessType & VME_DATA)
+		temp_ctl |= 0x00400000;
+
+
+	/* Write ctl reg and enable */
+	iowrite32(0x80000000 | temp_ctl, ca91cx42_bridge->base + LM_CTL);
+	temp_ctl = ioread32(ca91cx42_bridge->base + LM_CTL);
+
+	return 0;
+}
+
+int ca91cx42_wait_lm(vmeLmCfg_t *vmeLm)
+{
+	unsigned long flags;
+	unsigned int tmp;
+
+	spin_lock_irqsave(&lm_lock, flags);
+	spin_unlock_irqrestore(&lm_lock, flags);
+	if (tmp == 0) {
+		if (vmeLm->lmWait < 10)
+			vmeLm->lmWait = 10;
+		interruptible_sleep_on_timeout(&lm_queue, vmeLm->lmWait);
+	}
+	iowrite32(0x00000000, ca91cx42_bridge->base + LM_CTL);
+
+	return 0;
+}
+
+
+
+int ca91cx42_set_arbiter(vmeArbiterCfg_t *vmeArb)
+{
+	int temp_ctl = 0;
+	int vbto = 0;
+
+	temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
+	temp_ctl &= 0x00FFFFFF;
+
+	if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
+		vbto = 7;
+	} else if (vmeArb->globalTimeoutTimer > 1024) {
+		return -EINVAL;
+	} else if (vmeArb->globalTimeoutTimer == 0) {
+		vbto = 0;
+	} else {
+		vbto = 1;
+		while ((16 * (1 << (vbto - 1))) < vmeArb->globalTimeoutTimer)
+			vbto += 1;
+	}
+	temp_ctl |= (vbto << 28);
+
+	if (vmeArb->arbiterMode == VME_PRIORITY_MODE)
+		temp_ctl |= 1 << 26;
+
+	if (vmeArb->arbiterTimeoutFlag)
+		temp_ctl |= 2 << 24;
+
+	iowrite32(temp_ctl, ca91cx42_bridge->base + MISC_CTL);
+	return 0;
+}
+
+int ca91cx42_get_arbiter(vmeArbiterCfg_t *vmeArb)
+{
+	int temp_ctl = 0;
+	int vbto = 0;
+
+	temp_ctl = ioread32(ca91cx42_bridge->base + MISC_CTL);
+
+	vbto = (temp_ctl >> 28) & 0xF;
+	if (vbto != 0)
+		vmeArb->globalTimeoutTimer = (16 * (1 << (vbto - 1)));
+
+	if (temp_ctl & (1 << 26))
+		vmeArb->arbiterMode = VME_PRIORITY_MODE;
+	else
+		vmeArb->arbiterMode = VME_R_ROBIN_MODE;
+
+	if (temp_ctl & (3 << 24))
+		vmeArb->arbiterTimeoutFlag = 1;
+
+	return 0;
+}
+
+int ca91cx42_set_requestor(vmeRequesterCfg_t *vmeReq)
+{
+	int temp_ctl = 0;
+
+	temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
+	temp_ctl &= 0xFF0FFFFF;
+
+	if (vmeReq->releaseMode == 1)
+		temp_ctl |= (1 << 20);
+
+	if (vmeReq->fairMode == 1)
+		temp_ctl |= (1 << 21);
+
+	temp_ctl |= (vmeReq->requestLevel << 22);
+
+	iowrite32(temp_ctl, ca91cx42_bridge->base + MAST_CTL);
+	return 0;
+}
+
+int ca91cx42_get_requestor(vmeRequesterCfg_t *vmeReq)
+{
+	int temp_ctl = 0;
+
+	temp_ctl = ioread32(ca91cx42_bridge->base + MAST_CTL);
+
+	if (temp_ctl & (1 << 20))
+		vmeReq->releaseMode = 1;
+
+	if (temp_ctl & (1 << 21))
+		vmeReq->fairMode = 1;
+
+	vmeReq->requestLevel = (temp_ctl & 0xC00000) >> 22;
+
+	return 0;
+}
+
+
+#endif
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.h b/drivers/staging/vme/bridges/vme_ca91cx42.h
new file mode 100644
index 0000000..95a42c2
--- /dev/null
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.h
@@ -0,0 +1,505 @@
+/*
+ * ca91c042.h
+ *
+ * Support for the Tundra Universe 1 and Universe II VME bridge chips
+ *
+ * Author: Tom Armistead
+ * Updated by Ajit Prem
+ * Copyright 2004 Motorola Inc.
+ *
+ * Further updated by Martyn Welch <martyn.welch@gefanuc.com>
+ * Copyright 2009 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Derived from ca91c042.h by Michael Wyrick
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the 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 _CA91CX42_H
+#define _CA91CX42_H
+
+#ifndef	PCI_VENDOR_ID_TUNDRA
+#define	PCI_VENDOR_ID_TUNDRA 0x10e3
+#endif
+
+#ifndef	PCI_DEVICE_ID_TUNDRA_CA91C142
+#define	PCI_DEVICE_ID_TUNDRA_CA91C142 0x0000
+#endif
+
+/*
+ *  Define the number of each that the CA91C142 supports.
+ */
+#define CA91C142_MAX_MASTER		8	/* Max Master Windows */
+#define CA91C142_MAX_SLAVE		8	/* Max Slave Windows */
+#define CA91C142_MAX_DMA		1	/* Max DMA Controllers */
+#define CA91C142_MAX_MAILBOX		4	/* Max Mail Box registers */
+
+/* See Page 2-77 in the Universe User Manual */
+struct ca91cx42_dma_descriptor {
+	unsigned int dctl;      /* DMA Control */
+	unsigned int dtbc;      /* Transfer Byte Count */
+	unsigned int dlv;       /* PCI Address */
+	unsigned int res1;      /* Reserved */
+	unsigned int dva;       /* Vme Address */
+	unsigned int res2;      /* Reserved */
+	unsigned int dcpp;      /* Pointer to Numed Cmd Packet with rPN */
+	unsigned int res3;      /* Reserved */
+};
+
+struct ca91cx42_dma_entry {
+	struct ca91cx42_dma_descriptor descriptor;
+	struct list_head list;
+};
+
+/* Universe Register Offsets */
+/* general PCI configuration registers */
+#define CA91CX42_PCI_ID		0x000
+#define CA91CX42_PCI_CSR	0x004
+#define CA91CX42_PCI_CLASS	0x008
+#define CA91CX42_PCI_MISC0	0x00C
+#define CA91CX42_PCI_BS		0x010
+#define CA91CX42_PCI_MISC1	0x03C
+
+#define LSI0_CTL		0x0100
+#define LSI0_BS			0x0104
+#define LSI0_BD			0x0108
+#define LSI0_TO			0x010C
+
+#define LSI1_CTL		0x0114
+#define LSI1_BS			0x0118
+#define LSI1_BD			0x011C
+#define LSI1_TO			0x0120
+
+#define LSI2_CTL		0x0128
+#define LSI2_BS			0x012C
+#define LSI2_BD			0x0130
+#define LSI2_TO			0x0134
+
+#define LSI3_CTL		0x013C
+#define LSI3_BS			0x0140
+#define LSI3_BD			0x0144
+#define LSI3_TO			0x0148
+
+#define LSI4_CTL		0x01A0
+#define LSI4_BS			0x01A4
+#define LSI4_BD			0x01A8
+#define LSI4_TO			0x01AC
+
+#define LSI5_CTL		0x01B4
+#define LSI5_BS			0x01B8
+#define LSI5_BD			0x01BC
+#define LSI5_TO			0x01C0
+
+#define LSI6_CTL		0x01C8
+#define LSI6_BS			0x01CC
+#define LSI6_BD			0x01D0
+#define LSI6_TO			0x01D4
+
+#define LSI7_CTL		0x01DC
+#define LSI7_BS			0x01E0
+#define LSI7_BD			0x01E4
+#define LSI7_TO			0x01E8
+
+static const int CA91CX42_LSI_CTL[] = { LSI0_CTL, LSI1_CTL, LSI2_CTL, LSI3_CTL,
+				LSI4_CTL, LSI5_CTL, LSI6_CTL, LSI7_CTL };
+
+static const int CA91CX42_LSI_BS[] = { LSI0_BS, LSI1_BS, LSI2_BS, LSI3_BS,
+				LSI4_BS, LSI5_BS, LSI6_BS, LSI7_BS };
+
+static const int CA91CX42_LSI_BD[] = { LSI0_BD, LSI1_BD, LSI2_BD, LSI3_BD,
+				LSI4_BD, LSI5_BD, LSI6_BD, LSI7_BD };
+
+static const int CA91CX42_LSI_TO[] = { LSI0_TO, LSI1_TO, LSI2_TO, LSI3_TO,
+				LSI4_TO, LSI5_TO, LSI6_TO, LSI7_TO };
+
+#define SCYC_CTL		0x0170
+#define SCYC_ADDR		0x0174
+#define SCYC_EN			0x0178
+#define SCYC_CMP		0x017C
+#define SCYC_SWP		0x0180
+#define LMISC			0x0184
+#define SLSI		        0x0188
+#define L_CMDERR		0x018C
+#define LAERR		        0x0190
+
+#define DCTL		        0x0200
+#define DTBC		        0x0204
+#define DLA			0x0208
+#define DVA			0x0210
+#define DCPP		        0x0218
+#define DGCS		        0x0220
+#define D_LLUE			0x0224
+
+#define LINT_EN			0x0300
+#define LINT_STAT		0x0304
+#define LINT_MAP0		0x0308
+#define LINT_MAP1		0x030C
+#define VINT_EN			0x0310
+#define VINT_STAT		0x0314
+#define VINT_MAP0		0x0318
+#define VINT_MAP1		0x031C
+#define STATID			0x0320
+
+#define V1_STATID		0x0324
+#define V2_STATID		0x0328
+#define V3_STATID		0x032C
+#define V4_STATID		0x0330
+#define V5_STATID		0x0334
+#define V6_STATID		0x0338
+#define V7_STATID		0x033C
+
+static const int CA91CX42_V_STATID[8] = { 0, V1_STATID, V2_STATID, V3_STATID,
+					V4_STATID, V5_STATID, V6_STATID,
+					V7_STATID };
+
+#define LINT_MAP2		0x0340
+#define VINT_MAP2		0x0344
+
+#define MBOX0			0x0348
+#define MBOX1			0x034C
+#define MBOX2			0x0350
+#define MBOX3			0x0354
+#define SEMA0			0x0358
+#define SEMA1			0x035C
+
+#define MAST_CTL		0x0400
+#define MISC_CTL		0x0404
+#define MISC_STAT		0x0408
+#define USER_AM			0x040C
+
+#define VSI0_CTL		0x0F00
+#define VSI0_BS			0x0F04
+#define VSI0_BD			0x0F08
+#define VSI0_TO			0x0F0C
+
+#define VSI1_CTL		0x0F14
+#define VSI1_BS			0x0F18
+#define VSI1_BD			0x0F1C
+#define VSI1_TO			0x0F20
+
+#define VSI2_CTL		0x0F28
+#define VSI2_BS			0x0F2C
+#define VSI2_BD			0x0F30
+#define VSI2_TO			0x0F34
+
+#define VSI3_CTL		0x0F3C
+#define VSI3_BS			0x0F40
+#define VSI3_BD			0x0F44
+#define VSI3_TO			0x0F48
+
+#define LM_CTL			0x0F64
+#define LM_BS			0x0F68
+
+#define VRAI_CTL		0x0F70
+
+#define VRAI_BS			0x0F74
+#define VCSR_CTL		0x0F80
+#define VCSR_TO			0x0F84
+#define V_AMERR			0x0F88
+#define VAERR			0x0F8C
+
+#define VSI4_CTL		0x0F90
+#define VSI4_BS			0x0F94
+#define VSI4_BD			0x0F98
+#define VSI4_TO			0x0F9C
+
+#define VSI5_CTL		0x0FA4
+#define VSI5_BS			0x0FA8
+#define VSI5_BD			0x0FAC
+#define VSI5_TO			0x0FB0
+
+#define VSI6_CTL		0x0FB8
+#define VSI6_BS			0x0FBC
+#define VSI6_BD			0x0FC0
+#define VSI6_TO			0x0FC4
+
+#define VSI7_CTL		0x0FCC
+#define VSI7_BS			0x0FD0
+#define VSI7_BD			0x0FD4
+#define VSI7_TO			0x0FD8
+
+static const int CA91CX42_VSI_CTL[] = { VSI0_CTL, VSI1_CTL, VSI2_CTL, VSI3_CTL,
+				VSI4_CTL, VSI5_CTL, VSI6_CTL, VSI7_CTL };
+
+static const int CA91CX42_VSI_BS[] = { VSI0_BS, VSI1_BS, VSI2_BS, VSI3_BS,
+				VSI4_BS, VSI5_BS, VSI6_BS, VSI7_BS };
+
+static const int CA91CX42_VSI_BD[] = { VSI0_BD, VSI1_BD, VSI2_BD, VSI3_BD,
+				VSI4_BD, VSI5_BD, VSI6_BD, VSI7_BD };
+
+static const int CA91CX42_VSI_TO[] = { VSI0_TO, VSI1_TO, VSI2_TO, VSI3_TO,
+				VSI4_TO, VSI5_TO, VSI6_TO, VSI7_TO };
+
+#define VCSR_CLR		0x0FF4
+#define VCSR_SET		0x0FF8
+#define VCSR_BS			0x0FFC
+
+// DMA General Control/Status Register DGCS (0x220)
+// 32-24 ||  GO   | STOPR | HALTR |   0   || CHAIN |   0   |   0   |   0   ||
+// 23-16 ||              VON              ||             VOFF              ||
+// 15-08 ||  ACT  | STOP  | HALT  |   0   || DONE  | LERR  | VERR  | P_ERR ||
+// 07-00 ||   0   | INT_S | INT_H |   0   || I_DNE | I_LER | I_VER | I_PER ||
+
+// VON - Length Per DMA VMEBus Transfer
+//  0000 = None
+//  0001 = 256 Bytes
+//  0010 = 512
+//  0011 = 1024
+//  0100 = 2048
+//  0101 = 4096
+//  0110 = 8192
+//  0111 = 16384
+
+// VOFF - wait between DMA tenures
+//  0000 = 0    us
+//  0001 = 16
+//  0010 = 32
+//  0011 = 64
+//  0100 = 128
+//  0101 = 256
+//  0110 = 512
+//  0111 = 1024
+
+/*
+ * PCI Class Register
+ * offset 008
+ */
+#define CA91CX42_BM_PCI_CLASS_BASE          0xFF000000
+#define CA91CX42_OF_PCI_CLASS_BASE          24
+#define CA91CX42_BM_PCI_CLASS_SUB           0x00FF0000
+#define CA91CX42_OF_PCI_CLASS_SUB           16
+#define CA91CX42_BM_PCI_CLASS_PROG          0x0000FF00
+#define CA91CX42_OF_PCI_CLASS_PROG          8
+#define CA91CX42_BM_PCI_CLASS_RID           0x000000FF
+#define CA91CX42_OF_PCI_CLASS_RID           0
+
+#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_I 0
+#define CA91CX42_OF_PCI_CLASS_RID_UNIVERSE_II 1
+
+/*
+ * PCI Misc Register
+ * offset 00C
+ */
+#define CA91CX42_BM_PCI_MISC0_BISTC         0x80000000
+#define CA91CX42_BM_PCI_MISC0_SBIST         0x60000000
+#define CA91CX42_BM_PCI_MISC0_CCODE         0x0F000000
+#define CA91CX42_BM_PCI_MISC0_MFUNCT        0x00800000
+#define CA91CX42_BM_PCI_MISC0_LAYOUT        0x007F0000
+#define CA91CX42_BM_PCI_MISC0_LTIMER        0x0000FF00
+#define CA91CX42_OF_PCI_MISC0_LTIMER        8
+
+
+/*
+ * LSI Control Register
+ * offset  100
+ */
+#define CA91CX42_LSI_CTL_EN		(1<<31)
+#define CA91CX42_LSI_CTL_PWEN		(1<<30)
+
+#define CA91CX42_LSI_CTL_VDW_M		(3<<22)
+#define CA91CX42_LSI_CTL_VDW_D8		0
+#define CA91CX42_LSI_CTL_VDW_D16	(1<<22)
+#define CA91CX42_LSI_CTL_VDW_D32	(1<<23)
+#define CA91CX42_LSI_CTL_VDW_D64	(3<<22)
+
+#define CA91CX42_LSI_CTL_VAS_M		(7<<16)
+#define CA91CX42_LSI_CTL_VAS_A16	0
+#define CA91CX42_LSI_CTL_VAS_A24	(1<<16)
+#define CA91CX42_LSI_CTL_VAS_A32	(1<<17)
+#define CA91CX42_LSI_CTL_VAS_CRCSR	(5<<16)
+#define CA91CX42_LSI_CTL_VAS_USER1	(3<<17)
+#define CA91CX42_LSI_CTL_VAS_USER2	(7<<16)
+
+#define CA91CX42_LSI_CTL_PGM_M		(1<<14)
+#define CA91CX42_LSI_CTL_PGM_DATA	0
+#define CA91CX42_LSI_CTL_PGM_PGM	(1<<14)
+
+#define CA91CX42_LSI_CTL_SUPER_M	(1<<12)
+#define CA91CX42_LSI_CTL_SUPER_NPRIV	0
+#define CA91CX42_LSI_CTL_SUPER_SUPR	(1<<12)
+
+#define CA91CX42_LSI_CTL_VCT_M		(1<<8)
+#define CA91CX42_LSI_CTL_VCT_BLT	(1<<8)
+#define CA91CX42_LSI_CTL_VCT_MBLT	(1<<8)
+#define CA91CX42_LSI_CTL_LAS		(1<<0)
+
+
+/*
+ * LMISC Register
+ * offset  184
+ */
+#define CA91CX42_BM_LMISC_CRT               0xF0000000
+#define CA91CX42_OF_LMISC_CRT               28
+#define CA91CX42_BM_LMISC_CWT               0x0F000000
+#define CA91CX42_OF_LMISC_CWT               24
+
+/*
+ * SLSI Register
+ * offset  188
+ */
+#define CA91CX42_BM_SLSI_EN                 0x80000000
+#define CA91CX42_BM_SLSI_PWEN               0x40000000
+#define CA91CX42_BM_SLSI_VDW                0x00F00000
+#define CA91CX42_OF_SLSI_VDW                20
+#define CA91CX42_BM_SLSI_PGM                0x0000F000
+#define CA91CX42_OF_SLSI_PGM                12
+#define CA91CX42_BM_SLSI_SUPER              0x00000F00
+#define CA91CX42_OF_SLSI_SUPER              8
+#define CA91CX42_BM_SLSI_BS                 0x000000F6
+#define CA91CX42_OF_SLSI_BS                 2
+#define CA91CX42_BM_SLSI_LAS                0x00000003
+#define CA91CX42_OF_SLSI_LAS                0
+#define CA91CX42_BM_SLSI_RESERVED           0x3F0F0000
+
+/*
+ * PCI Interrupt Enable Register
+ * offset  300
+ */
+#define CA91CX42_LINT_LM3		0x00800000
+#define CA91CX42_LINT_LM2		0x00400000
+#define CA91CX42_LINT_LM1		0x00200000
+#define CA91CX42_LINT_LM0		0x00100000
+#define CA91CX42_LINT_MBOX3		0x00080000
+#define CA91CX42_LINT_MBOX2		0x00040000
+#define CA91CX42_LINT_MBOX1		0x00020000
+#define CA91CX42_LINT_MBOX0		0x00010000
+#define CA91CX42_LINT_ACFAIL		0x00008000
+#define CA91CX42_LINT_SYSFAIL		0x00004000
+#define CA91CX42_LINT_SW_INT		0x00002000
+#define CA91CX42_LINT_SW_IACK		0x00001000
+
+#define CA91CX42_LINT_VERR		0x00000400
+#define CA91CX42_LINT_LERR		0x00000200
+#define CA91CX42_LINT_DMA		0x00000100
+#define CA91CX42_LINT_VIRQ7		0x00000080
+#define CA91CX42_LINT_VIRQ6		0x00000040
+#define CA91CX42_LINT_VIRQ5		0x00000020
+#define CA91CX42_LINT_VIRQ4		0x00000010
+#define CA91CX42_LINT_VIRQ3		0x00000008
+#define CA91CX42_LINT_VIRQ2		0x00000004
+#define CA91CX42_LINT_VIRQ1		0x00000002
+#define CA91CX42_LINT_VOWN		0x00000001
+
+static const int CA91CX42_LINT_VIRQ[] = { 0, CA91CX42_LINT_VIRQ1,
+				CA91CX42_LINT_VIRQ2, CA91CX42_LINT_VIRQ3,
+				CA91CX42_LINT_VIRQ4, CA91CX42_LINT_VIRQ5,
+				CA91CX42_LINT_VIRQ6, CA91CX42_LINT_VIRQ7 };
+
+#define CA91CX42_LINT_MBOX		0x000F0000
+
+static const int CA91CX42_LINT_LM[] = { CA91CX42_LINT_LM0, CA91CX42_LINT_LM1,
+					CA91CX42_LINT_LM2, CA91CX42_LINT_LM3 };
+
+/*
+ * MAST_CTL Register
+ * offset  400
+ */
+#define CA91CX42_BM_MAST_CTL_MAXRTRY        0xF0000000
+#define CA91CX42_OF_MAST_CTL_MAXRTRY        28
+#define CA91CX42_BM_MAST_CTL_PWON           0x0F000000
+#define CA91CX42_OF_MAST_CTL_PWON           24
+#define CA91CX42_BM_MAST_CTL_VRL            0x00C00000
+#define CA91CX42_OF_MAST_CTL_VRL            22
+#define CA91CX42_BM_MAST_CTL_VRM            0x00200000
+#define CA91CX42_BM_MAST_CTL_VREL           0x00100000
+#define CA91CX42_BM_MAST_CTL_VOWN           0x00080000
+#define CA91CX42_BM_MAST_CTL_VOWN_ACK       0x00040000
+#define CA91CX42_BM_MAST_CTL_PABS           0x00001000
+#define CA91CX42_BM_MAST_CTL_BUS_NO         0x0000000F
+#define CA91CX42_OF_MAST_CTL_BUS_NO         0
+
+/*
+ * MISC_CTL Register
+ * offset  404
+ */
+#define CA91CX42_MISC_CTL_VBTO           0xF0000000
+#define CA91CX42_MISC_CTL_VARB           0x04000000
+#define CA91CX42_MISC_CTL_VARBTO         0x03000000
+#define CA91CX42_MISC_CTL_SW_LRST        0x00800000
+#define CA91CX42_MISC_CTL_SW_SRST        0x00400000
+#define CA91CX42_MISC_CTL_BI             0x00100000
+#define CA91CX42_MISC_CTL_ENGBI          0x00080000
+#define CA91CX42_MISC_CTL_RESCIND        0x00040000
+#define CA91CX42_MISC_CTL_SYSCON         0x00020000
+#define CA91CX42_MISC_CTL_V64AUTO        0x00010000
+#define CA91CX42_MISC_CTL_RESERVED       0x0820FFFF
+
+#define CA91CX42_OF_MISC_CTL_VARBTO         24
+#define CA91CX42_OF_MISC_CTL_VBTO           28
+
+/*
+ * MISC_STAT Register
+ * offset  408
+ */
+#define CA91CX42_BM_MISC_STAT_ENDIAN        0x80000000
+#define CA91CX42_BM_MISC_STAT_LCLSIZE       0x40000000
+#define CA91CX42_BM_MISC_STAT_DY4AUTO       0x08000000
+#define CA91CX42_BM_MISC_STAT_MYBBSY        0x00200000
+#define CA91CX42_BM_MISC_STAT_DY4DONE       0x00080000
+#define CA91CX42_BM_MISC_STAT_TXFE          0x00040000
+#define CA91CX42_BM_MISC_STAT_RXFE          0x00020000
+#define CA91CX42_BM_MISC_STAT_DY4AUTOID     0x0000FF00
+#define CA91CX42_OF_MISC_STAT_DY4AUTOID     8
+
+/*
+ * VSI Control Register
+ * offset  F00
+ */
+#define CA91CX42_VSI_CTL_EN		(1<<31)
+#define CA91CX42_VSI_CTL_PWEN		(1<<30)
+#define CA91CX42_VSI_CTL_PREN		(1<<29)
+
+#define CA91CX42_VSI_CTL_PGM_M		(3<<22)
+#define CA91CX42_VSI_CTL_PGM_DATA	(1<<22)
+#define CA91CX42_VSI_CTL_PGM_PGM	(1<<23)
+
+#define CA91CX42_VSI_CTL_SUPER_M	(3<<20)
+#define CA91CX42_VSI_CTL_SUPER_NPRIV	(1<<20)
+#define CA91CX42_VSI_CTL_SUPER_SUPR	(1<<21)
+
+#define CA91CX42_VSI_CTL_VAS_M		(7<<16)
+#define CA91CX42_VSI_CTL_VAS_A16	0
+#define CA91CX42_VSI_CTL_VAS_A24	(1<<16)
+#define CA91CX42_VSI_CTL_VAS_A32	(1<<17)
+#define CA91CX42_VSI_CTL_VAS_USER1	(3<<17)
+#define CA91CX42_VSI_CTL_VAS_USER2	(7<<16)
+
+#define CA91CX42_VSI_CTL_LD64EN		(1<<7)
+#define CA91CX42_VSI_CTL_LLRMW		(1<<6)
+
+#define CA91CX42_VSI_CTL_LAS_M		(3<<0)
+#define CA91CX42_VSI_CTL_LAS_PCI_MS	0
+#define CA91CX42_VSI_CTL_LAS_PCI_IO	(1<<0)
+#define CA91CX42_VSI_CTL_LAS_PCI_CONF	(1<<1)
+
+/*
+ * VRAI_CTL Register
+ * offset  F70
+ */
+#define CA91CX42_BM_VRAI_CTL_EN             0x80000000
+#define CA91CX42_BM_VRAI_CTL_PGM            0x00C00000
+#define CA91CX42_OF_VRAI_CTL_PGM            22
+#define CA91CX42_BM_VRAI_CTL_SUPER          0x00300000
+#define CA91CX42_OF_VRAI_CTL_SUPER          20
+#define CA91CX42_BM_VRAI_CTL_VAS            0x00030000
+#define CA91CX42_OF_VRAI_CTL_VAS            16
+
+/* VCSR_CTL Register
+ * offset F80
+ */
+#define CA91CX42_VCSR_CTL_EN		(1<<31)
+
+#define CA91CX42_VCSR_CTL_LAS_M		(3<<0)
+#define CA91CX42_VCSR_CTL_LAS_PCI_MS	0
+#define CA91CX42_VCSR_CTL_LAS_PCI_IO	(1<<0)
+#define CA91CX42_VCSR_CTL_LAS_PCI_CONF	(1<<1)
+
+/* VCSR_BS Register
+ * offset FFC
+ */
+#define CA91CX42_VCSR_BS_SLOT_M		(0x1F<<27)
+
+#endif /* _CA91CX42_H */
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
new file mode 100644
index 0000000..8960fa9
--- /dev/null
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -0,0 +1,2925 @@
+/*
+ * Support for the Tundra TSI148 VME-PCI Bridge Chip
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by Tom Armistead and Ajit Prem
+ * Copyright 2004 Motorola 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/version.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "../vme.h"
+#include "../vme_bridge.h"
+#include "vme_tsi148.h"
+
+static int __init tsi148_init(void);
+static int tsi148_probe(struct pci_dev *, const struct pci_device_id *);
+static void tsi148_remove(struct pci_dev *);
+static void __exit tsi148_exit(void);
+
+
+int tsi148_slave_set(struct vme_slave_resource *, int, unsigned long long,
+	unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
+int tsi148_slave_get(struct vme_slave_resource *, int *, unsigned long long *,
+	unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *);
+
+int tsi148_master_get(struct vme_master_resource *, int *, unsigned long long *,
+        unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *);
+int tsi148_master_set(struct vme_master_resource *, int, unsigned long long,
+	unsigned long long, vme_address_t, vme_cycle_t,	vme_width_t);
+ssize_t tsi148_master_read(struct vme_master_resource *, void *, size_t,
+	loff_t);
+ssize_t tsi148_master_write(struct vme_master_resource *, void *, size_t,
+	loff_t);
+unsigned int tsi148_master_rmw(struct vme_master_resource *, unsigned int,
+	unsigned int, unsigned int, loff_t);
+int tsi148_dma_list_add (struct vme_dma_list *, struct vme_dma_attr *,
+	struct vme_dma_attr *, size_t);
+int tsi148_dma_list_exec(struct vme_dma_list *);
+int tsi148_dma_list_empty(struct vme_dma_list *);
+int tsi148_generate_irq(int, int);
+int tsi148_slot_get(void);
+
+/* Modue parameter */
+int err_chk = 0;
+
+/* XXX These should all be in a per device structure */
+struct vme_bridge *tsi148_bridge;
+wait_queue_head_t dma_queue[2];
+wait_queue_head_t iack_queue;
+void (*lm_callback[4])(int);	/* Called in interrupt handler, be careful! */
+void *crcsr_kernel;
+dma_addr_t crcsr_bus;
+struct vme_master_resource *flush_image;
+struct mutex vme_rmw;	/* Only one RMW cycle at a time */
+struct mutex vme_int;	/*
+				 * Only one VME interrupt can be
+				 * generated at a time, provide locking
+				 */
+struct mutex vme_irq;	/* Locking for VME irq callback configuration */
+
+
+static char driver_name[] = "vme_tsi148";
+
+static struct pci_device_id tsi148_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) },
+	{ },
+};
+
+static struct pci_driver tsi148_driver = {
+	.name = driver_name,
+	.id_table = tsi148_ids,
+	.probe = tsi148_probe,
+	.remove = tsi148_remove,
+};
+
+static void reg_join(unsigned int high, unsigned int low,
+	unsigned long long *variable)
+{
+	*variable = (unsigned long long)high << 32;
+	*variable |= (unsigned long long)low;
+}
+
+static void reg_split(unsigned long long variable, unsigned int *high,
+	unsigned int *low)
+{
+	*low = (unsigned int)variable & 0xFFFFFFFF;
+	*high = (unsigned int)(variable >> 32);
+}
+
+/*
+ * Wakes up DMA queue.
+ */
+static u32 tsi148_DMA_irqhandler(int channel_mask)
+{
+	u32 serviced = 0;
+
+	if (channel_mask & TSI148_LCSR_INTS_DMA0S) {
+		wake_up(&dma_queue[0]);
+		serviced |= TSI148_LCSR_INTC_DMA0C;
+	}
+	if (channel_mask & TSI148_LCSR_INTS_DMA1S) {
+		wake_up(&dma_queue[1]);
+		serviced |= TSI148_LCSR_INTC_DMA1C;
+	}
+
+	return serviced;
+}
+
+/*
+ * Wake up location monitor queue
+ */
+static u32 tsi148_LM_irqhandler(u32 stat)
+{
+	int i;
+	u32 serviced = 0;
+
+	for (i = 0; i < 4; i++) {
+		if(stat & TSI148_LCSR_INTS_LMS[i]) {
+			/* We only enable interrupts if the callback is set */
+			lm_callback[i](i);
+			serviced |= TSI148_LCSR_INTC_LMC[i];
+		}
+	}
+
+	return serviced;
+}
+
+/*
+ * Wake up mail box queue.
+ *
+ * XXX This functionality is not exposed up though API.
+ */
+static u32 tsi148_MB_irqhandler(u32 stat)
+{
+	int i;
+	u32 val;
+	u32 serviced = 0;
+
+	for (i = 0; i < 4; i++) {
+		if(stat & TSI148_LCSR_INTS_MBS[i]) {
+			val = ioread32be(tsi148_bridge->base +
+				TSI148_GCSR_MBOX[i]);
+			printk("VME Mailbox %d received: 0x%x\n", i, val);
+			serviced |= TSI148_LCSR_INTC_MBC[i];
+		}
+	}
+
+	return serviced;
+}
+
+/*
+ * Display error & status message when PERR (PCI) exception interrupt occurs.
+ */
+static u32 tsi148_PERR_irqhandler(void)
+{
+	printk(KERN_ERR
+		"PCI Exception at address: 0x%08x:%08x, attributes: %08x\n",
+		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAU),
+		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAL),
+		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPAT)
+		);
+	printk(KERN_ERR
+		"PCI-X attribute reg: %08x, PCI-X split completion reg: %08x\n",
+		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXA),
+		ioread32be(tsi148_bridge->base + TSI148_LCSR_EDPXS)
+		);
+
+	iowrite32be(TSI148_LCSR_EDPAT_EDPCL,
+		tsi148_bridge->base + TSI148_LCSR_EDPAT);
+
+	return TSI148_LCSR_INTC_PERRC;
+}
+
+/*
+ * Save address and status when VME error interrupt occurs.
+ */
+static u32 tsi148_VERR_irqhandler(void)
+{
+	unsigned int error_addr_high, error_addr_low;
+	unsigned long long error_addr;
+	u32 error_attrib;
+	struct vme_bus_error *error;
+
+	error_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAU);
+	error_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAL);
+	error_attrib = ioread32be(tsi148_bridge->base + TSI148_LCSR_VEAT);
+
+	reg_join(error_addr_high, error_addr_low, &error_addr);
+
+	/* Check for exception register overflow (we have lost error data) */
+	if(error_attrib & TSI148_LCSR_VEAT_VEOF) {
+		printk(KERN_ERR "VME Bus Exception Overflow Occurred\n");
+	}
+
+	error = (struct vme_bus_error *)kmalloc(sizeof (struct vme_bus_error),
+		GFP_ATOMIC);
+	if (error) {
+		error->address = error_addr;
+		error->attributes = error_attrib;
+		list_add_tail(&(error->list), &(tsi148_bridge->vme_errors));
+	} else {
+		printk(KERN_ERR
+			"Unable to alloc memory for VMEbus Error reporting\n");
+		printk(KERN_ERR
+			"VME Bus Error at address: 0x%llx, attributes: %08x\n",
+			error_addr, error_attrib);
+	}
+
+	/* Clear Status */
+	iowrite32be(TSI148_LCSR_VEAT_VESCL,
+		tsi148_bridge->base + TSI148_LCSR_VEAT);
+
+	return TSI148_LCSR_INTC_VERRC;
+}
+
+/*
+ * Wake up IACK queue.
+ */
+static u32 tsi148_IACK_irqhandler(void)
+{
+	printk("tsi148_IACK_irqhandler\n");
+	wake_up(&iack_queue);
+
+	return TSI148_LCSR_INTC_IACKC;
+}
+
+/*
+ * Calling VME bus interrupt callback if provided.
+ */
+static u32 tsi148_VIRQ_irqhandler(u32 stat)
+{
+	int vec, i, serviced = 0;
+	void (*call)(int, int, void *);
+	void *priv_data;
+
+	for (i = 7; i > 0; i--) {
+		if (stat & (1 << i)) {
+			/*
+			 * 	Note:   Even though the registers are defined
+			 * 	as 32-bits in the spec, we only want to issue
+			 * 	8-bit IACK cycles on the bus, read from offset
+			 * 	3.
+			 */
+			vec = ioread8(tsi148_bridge->base +
+				TSI148_LCSR_VIACK[i] + 3);
+
+			call = tsi148_bridge->irq[i - 1].callback[vec].func;
+			priv_data =
+				tsi148_bridge->irq[i-1].callback[vec].priv_data;
+
+			if (call != NULL)
+				call(i, vec, priv_data);
+			else
+				printk("Spurilous VME interrupt, level:%x, "
+					"vector:%x\n", i, vec);
+
+			serviced |= (1 << i);
+		}
+	}
+
+	return serviced;
+}
+
+/*
+ * Top level interrupt handler.  Clears appropriate interrupt status bits and
+ * then calls appropriate sub handler(s).
+ */
+static irqreturn_t tsi148_irqhandler(int irq, void *dev_id)
+{
+	u32 stat, enable, serviced = 0;
+
+	/* Determine which interrupts are unmasked and set */
+	enable = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+	stat = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTS);
+
+	/* Only look at unmasked interrupts */
+	stat &= enable;
+
+	if (unlikely(!stat)) {
+		return IRQ_NONE;
+	}
+
+	/* Call subhandlers as appropriate */
+	/* DMA irqs */
+	if (stat & (TSI148_LCSR_INTS_DMA1S | TSI148_LCSR_INTS_DMA0S))
+		serviced |= tsi148_DMA_irqhandler(stat);
+
+	/* Location monitor irqs */
+	if (stat & (TSI148_LCSR_INTS_LM3S | TSI148_LCSR_INTS_LM2S |
+			TSI148_LCSR_INTS_LM1S | TSI148_LCSR_INTS_LM0S))
+		serviced |= tsi148_LM_irqhandler(stat);
+
+	/* Mail box irqs */
+	if (stat & (TSI148_LCSR_INTS_MB3S | TSI148_LCSR_INTS_MB2S |
+			TSI148_LCSR_INTS_MB1S | TSI148_LCSR_INTS_MB0S))
+		serviced |= tsi148_MB_irqhandler(stat);
+
+	/* PCI bus error */
+	if (stat & TSI148_LCSR_INTS_PERRS)
+		serviced |= tsi148_PERR_irqhandler();
+
+	/* VME bus error */
+	if (stat & TSI148_LCSR_INTS_VERRS)
+		serviced |= tsi148_VERR_irqhandler();
+
+	/* IACK irq */
+	if (stat & TSI148_LCSR_INTS_IACKS)
+		serviced |= tsi148_IACK_irqhandler();
+
+	/* VME bus irqs */
+	if (stat & (TSI148_LCSR_INTS_IRQ7S | TSI148_LCSR_INTS_IRQ6S |
+			TSI148_LCSR_INTS_IRQ5S | TSI148_LCSR_INTS_IRQ4S |
+			TSI148_LCSR_INTS_IRQ3S | TSI148_LCSR_INTS_IRQ2S |
+			TSI148_LCSR_INTS_IRQ1S))
+		serviced |= tsi148_VIRQ_irqhandler(stat);
+
+	/* Clear serviced interrupts */
+	iowrite32be(serviced, tsi148_bridge->base + TSI148_LCSR_INTC);
+
+	return IRQ_HANDLED;
+}
+
+static int tsi148_irq_init(struct vme_bridge *bridge)
+{
+	int result;
+	unsigned int tmp;
+	struct pci_dev *pdev;
+
+	/* Need pdev */
+        pdev = container_of(bridge->parent, struct pci_dev, dev);
+
+	/* Initialise list for VME bus errors */
+	INIT_LIST_HEAD(&(bridge->vme_errors));
+
+	result = request_irq(pdev->irq,
+			     tsi148_irqhandler,
+			     IRQF_SHARED,
+			     driver_name, pdev);
+	if (result) {
+		dev_err(&pdev->dev, "Can't get assigned pci irq vector %02X\n",
+			pdev->irq);
+		return result;
+	}
+
+	/* Enable and unmask interrupts */
+	tmp = TSI148_LCSR_INTEO_DMA1EO | TSI148_LCSR_INTEO_DMA0EO |
+		TSI148_LCSR_INTEO_MB3EO | TSI148_LCSR_INTEO_MB2EO |
+		TSI148_LCSR_INTEO_MB1EO | TSI148_LCSR_INTEO_MB0EO |
+		TSI148_LCSR_INTEO_PERREO | TSI148_LCSR_INTEO_VERREO |
+		TSI148_LCSR_INTEO_IACKEO;
+
+	/* XXX This leaves the following interrupts masked.
+	 * TSI148_LCSR_INTEO_VIEEO
+	 * TSI148_LCSR_INTEO_SYSFLEO
+	 * TSI148_LCSR_INTEO_ACFLEO
+	 */
+
+	/* Don't enable Location Monitor interrupts here - they will be
+	 * enabled when the location monitors are properly configured and
+	 * a callback has been attached.
+	 * TSI148_LCSR_INTEO_LM0EO
+	 * TSI148_LCSR_INTEO_LM1EO
+	 * TSI148_LCSR_INTEO_LM2EO
+	 * TSI148_LCSR_INTEO_LM3EO
+	 */
+
+	/* Don't enable VME interrupts until we add a handler, else the board
+	 * will respond to it and we don't want that unless it knows how to
+	 * properly deal with it.
+	 * TSI148_LCSR_INTEO_IRQ7EO
+	 * TSI148_LCSR_INTEO_IRQ6EO
+	 * TSI148_LCSR_INTEO_IRQ5EO
+	 * TSI148_LCSR_INTEO_IRQ4EO
+	 * TSI148_LCSR_INTEO_IRQ3EO
+	 * TSI148_LCSR_INTEO_IRQ2EO
+	 * TSI148_LCSR_INTEO_IRQ1EO
+	 */
+
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
+	iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEN);
+
+	return 0;
+}
+
+static void tsi148_irq_exit(struct pci_dev *pdev)
+{
+	/* Turn off interrupts */
+	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEO);
+	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEN);
+
+	/* Clear all interrupts */
+	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTC);
+
+	/* Detach interrupt handler */
+	free_irq(pdev->irq, pdev);
+}
+
+/*
+ * Check to see if an IACk has been received, return true (1) or false (0).
+ */
+int tsi148_iack_received(void)
+{
+	u32 tmp;
+
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR);
+
+	if (tmp & TSI148_LCSR_VICR_IRQS)
+		return 0;
+	else
+		return 1;
+}
+
+/*
+ * Set up an VME interrupt
+ */
+int tsi148_request_irq(int level, int statid,
+	void (*callback)(int level, int vector, void *priv_data),
+        void *priv_data)
+{
+	u32 tmp;
+
+	mutex_lock(&(vme_irq));
+
+	if(tsi148_bridge->irq[level - 1].callback[statid].func) {
+		mutex_unlock(&(vme_irq));
+		printk("VME Interrupt already taken\n");
+		return -EBUSY;
+	}
+
+
+	tsi148_bridge->irq[level - 1].count++;
+	tsi148_bridge->irq[level - 1].callback[statid].priv_data = priv_data;
+	tsi148_bridge->irq[level - 1].callback[statid].func = callback;
+
+	/* Enable IRQ level */
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+	tmp |= TSI148_LCSR_INTEO_IRQEO[level - 1];
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+	tmp |= TSI148_LCSR_INTEN_IRQEN[level - 1];
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+
+	mutex_unlock(&(vme_irq));
+
+	return 0;
+}
+
+/*
+ * Free VME interrupt
+ */
+void tsi148_free_irq(int level, int statid)
+{
+	u32 tmp;
+	struct pci_dev *pdev;
+
+	mutex_lock(&(vme_irq));
+
+	tsi148_bridge->irq[level - 1].count--;
+
+	/* Disable IRQ level if no more interrupts attached at this level*/
+	if (tsi148_bridge->irq[level - 1].count == 0) {
+		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+		tmp &= ~TSI148_LCSR_INTEN_IRQEN[level - 1];
+		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+
+		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+		tmp &= ~TSI148_LCSR_INTEO_IRQEO[level - 1];
+		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+
+		pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+
+		synchronize_irq(pdev->irq);
+	}
+
+	tsi148_bridge->irq[level - 1].callback[statid].func = NULL;
+	tsi148_bridge->irq[level - 1].callback[statid].priv_data = NULL;
+
+	mutex_unlock(&(vme_irq));
+}
+
+/*
+ * Generate a VME bus interrupt at the requested level & vector. Wait for
+ * interrupt to be acked.
+ */
+int tsi148_generate_irq(int level, int statid)
+{
+	u32 tmp;
+
+	mutex_lock(&(vme_int));
+
+	/* Read VICR register */
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR);
+
+	/* Set Status/ID */
+	tmp = (tmp & ~TSI148_LCSR_VICR_STID_M) |
+		(statid & TSI148_LCSR_VICR_STID_M);
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR);
+
+	/* Assert VMEbus IRQ */
+	tmp = tmp | TSI148_LCSR_VICR_IRQL[level];
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VICR);
+
+	/* XXX Consider implementing a timeout? */
+	wait_event_interruptible(iack_queue, tsi148_iack_received());
+
+	mutex_unlock(&(vme_int));
+
+	return 0;
+}
+
+/*
+ * Find the first error in this address range
+ */
+static struct vme_bus_error *tsi148_find_error(vme_address_t aspace,
+	unsigned long long address, size_t count)
+{
+	struct list_head *err_pos;
+	struct vme_bus_error *vme_err, *valid = NULL;
+	unsigned long long bound;
+
+	bound = address + count;
+
+	/*
+	 * XXX We are currently not looking at the address space when parsing
+	 *     for errors. This is because parsing the Address Modifier Codes
+	 *     is going to be quite resource intensive to do properly. We
+	 *     should be OK just looking at the addresses and this is certainly
+	 *     much better than what we had before.
+	 */
+	err_pos = NULL;
+	/* Iterate through errors */
+	list_for_each(err_pos, &(tsi148_bridge->vme_errors)) {
+		vme_err = list_entry(err_pos, struct vme_bus_error, list);
+		if((vme_err->address >= address) && (vme_err->address < bound)){
+			valid = vme_err;
+			break;
+		}
+	}
+
+	return valid;
+}
+
+/*
+ * Clear errors in the provided address range.
+ */
+static void tsi148_clear_errors(vme_address_t aspace,
+	unsigned long long address, size_t count)
+{
+	struct list_head *err_pos, *temp;
+	struct vme_bus_error *vme_err;
+	unsigned long long bound;
+
+	bound = address + count;
+
+	/*
+	 * XXX We are currently not looking at the address space when parsing
+	 *     for errors. This is because parsing the Address Modifier Codes
+	 *     is going to be quite resource intensive to do properly. We
+	 *     should be OK just looking at the addresses and this is certainly
+	 *     much better than what we had before.
+	 */
+	err_pos = NULL;
+	/* Iterate through errors */
+	list_for_each_safe(err_pos, temp, &(tsi148_bridge->vme_errors)) {
+		vme_err = list_entry(err_pos, struct vme_bus_error, list);
+
+		if((vme_err->address >= address) && (vme_err->address < bound)){
+			list_del(err_pos);
+			kfree(vme_err);
+		}
+	}
+}
+
+/*
+ * Initialize a slave window with the requested attributes.
+ */
+int tsi148_slave_set(struct vme_slave_resource *image, int enabled,
+	unsigned long long vme_base, unsigned long long size,
+	dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle)
+{
+	unsigned int i, addr = 0, granularity = 0;
+	unsigned int temp_ctl = 0;
+	unsigned int vme_base_low, vme_base_high;
+	unsigned int vme_bound_low, vme_bound_high;
+	unsigned int pci_offset_low, pci_offset_high;
+	unsigned long long vme_bound, pci_offset;
+
+#if 0
+        printk("Set slave image %d to:\n", image->number);
+ 	printk("\tEnabled: %s\n", (enabled == 1)? "yes" : "no");
+	printk("\tVME Base:0x%llx\n", vme_base);
+	printk("\tWindow Size:0x%llx\n", size);
+	printk("\tPCI Base:0x%lx\n", (unsigned long)pci_base);
+	printk("\tAddress Space:0x%x\n", aspace);
+	printk("\tTransfer Cycle Properties:0x%x\n", cycle);
+#endif
+
+	i = image->number;
+
+	switch (aspace) {
+	case VME_A16:
+		granularity = 0x10;
+		addr |= TSI148_LCSR_ITAT_AS_A16;
+		break;
+	case VME_A24:
+		granularity = 0x1000;
+		addr |= TSI148_LCSR_ITAT_AS_A24;
+		break;
+	case VME_A32:
+		granularity = 0x10000;
+		addr |= TSI148_LCSR_ITAT_AS_A32;
+		break;
+	case VME_A64:
+		granularity = 0x10000;
+		addr |= TSI148_LCSR_ITAT_AS_A64;
+		break;
+	case VME_CRCSR:
+	case VME_USER1:
+	case VME_USER2:
+	case VME_USER3:
+	case VME_USER4:
+	default:
+		printk("Invalid address space\n");
+		return -EINVAL;
+		break;
+	}
+
+	/* Convert 64-bit variables to 2x 32-bit variables */
+	reg_split(vme_base, &vme_base_high, &vme_base_low);
+
+	/*
+	 * Bound address is a valid address for the window, adjust
+	 * accordingly
+	 */
+	vme_bound = vme_base + size - granularity;
+	reg_split(vme_bound, &vme_bound_high, &vme_bound_low);
+	pci_offset = (unsigned long long)pci_base - vme_base;
+	reg_split(pci_offset, &pci_offset_high, &pci_offset_low);
+
+	if (vme_base_low & (granularity - 1)) {
+		printk("Invalid VME base alignment\n");
+		return -EINVAL;
+	}
+	if (vme_bound_low & (granularity - 1)) {
+		printk("Invalid VME bound alignment\n");
+		return -EINVAL;
+	}
+	if (pci_offset_low & (granularity - 1)) {
+		printk("Invalid PCI Offset alignment\n");
+		return -EINVAL;
+	}
+
+#if 0
+	printk("\tVME Bound:0x%llx\n", vme_bound);
+	printk("\tPCI Offset:0x%llx\n", pci_offset);
+#endif
+
+	/*  Disable while we are mucking around */
+	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITAT);
+	temp_ctl &= ~TSI148_LCSR_ITAT_EN;
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITAT);
+
+	/* Setup mapping */
+	iowrite32be(vme_base_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITSAU);
+	iowrite32be(vme_base_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITSAL);
+	iowrite32be(vme_bound_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITEAU);
+	iowrite32be(vme_bound_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITEAL);
+	iowrite32be(pci_offset_high, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITOFU);
+	iowrite32be(pci_offset_low, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITOFL);
+
+/* XXX Prefetch stuff currently unsupported */
+#if 0
+
+	for (x = 0; x < 4; x++) {
+		if ((64 << x) >= vmeIn->prefetchSize) {
+			break;
+		}
+	}
+	if (x == 4)
+		x--;
+	temp_ctl |= (x << 16);
+
+	if (vmeIn->prefetchThreshold)
+		if (vmeIn->prefetchThreshold)
+			temp_ctl |= 0x40000;
+#endif
+
+	/* Setup 2eSST speeds */
+	temp_ctl &= ~TSI148_LCSR_ITAT_2eSSTM_M;
+	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+	case VME_2eSST160:
+		temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_160;
+		break;
+	case VME_2eSST267:
+		temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_267;
+		break;
+	case VME_2eSST320:
+		temp_ctl |= TSI148_LCSR_ITAT_2eSSTM_320;
+		break;
+	}
+
+	/* Setup cycle types */
+	temp_ctl &= ~(0x1F << 7);
+	if (cycle & VME_BLT)
+		temp_ctl |= TSI148_LCSR_ITAT_BLT;
+	if (cycle & VME_MBLT)
+		temp_ctl |= TSI148_LCSR_ITAT_MBLT;
+	if (cycle & VME_2eVME)
+		temp_ctl |= TSI148_LCSR_ITAT_2eVME;
+	if (cycle & VME_2eSST)
+		temp_ctl |= TSI148_LCSR_ITAT_2eSST;
+	if (cycle & VME_2eSSTB)
+		temp_ctl |= TSI148_LCSR_ITAT_2eSSTB;
+
+	/* Setup address space */
+	temp_ctl &= ~TSI148_LCSR_ITAT_AS_M;
+	temp_ctl |= addr;
+
+	temp_ctl &= ~0xF;
+	if (cycle & VME_SUPER)
+		temp_ctl |= TSI148_LCSR_ITAT_SUPR ;
+	if (cycle & VME_USER)
+		temp_ctl |= TSI148_LCSR_ITAT_NPRIV;
+	if (cycle & VME_PROG)
+		temp_ctl |= TSI148_LCSR_ITAT_PGM;
+	if (cycle & VME_DATA)
+		temp_ctl |= TSI148_LCSR_ITAT_DATA;
+
+	/* Write ctl reg without enable */
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITAT);
+
+	if (enabled)
+		temp_ctl |= TSI148_LCSR_ITAT_EN;
+
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITAT);
+
+	return 0;
+}
+
+/*
+ * Get slave window configuration.
+ *
+ * XXX Prefetch currently unsupported.
+ */
+int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle)
+{
+	unsigned int i, granularity = 0, ctl = 0;
+	unsigned int vme_base_low, vme_base_high;
+	unsigned int vme_bound_low, vme_bound_high;
+	unsigned int pci_offset_low, pci_offset_high;
+	unsigned long long vme_bound, pci_offset;
+
+
+	i = image->number;
+
+	/* Read registers */
+	ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITAT);
+
+	vme_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITSAU);
+	vme_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITSAL);
+	vme_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITEAU);
+	vme_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITEAL);
+	pci_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITOFU);
+	pci_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_IT[i] +
+		TSI148_LCSR_OFFSET_ITOFL);
+
+	/* Convert 64-bit variables to 2x 32-bit variables */
+	reg_join(vme_base_high, vme_base_low, vme_base);
+	reg_join(vme_bound_high, vme_bound_low, &vme_bound);
+	reg_join(pci_offset_high, pci_offset_low, &pci_offset);
+
+	*pci_base = (dma_addr_t)vme_base + pci_offset;
+
+	*enabled = 0;
+	*aspace = 0;
+	*cycle = 0;
+
+	if (ctl & TSI148_LCSR_ITAT_EN)
+		*enabled = 1;
+
+	if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A16) {
+		granularity = 0x10;
+		*aspace |= VME_A16;
+	}
+	if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A24) {
+		granularity = 0x1000;
+		*aspace |= VME_A24;
+	}
+	if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A32) {
+		granularity = 0x10000;
+		*aspace |= VME_A32;
+	}
+	if ((ctl & TSI148_LCSR_ITAT_AS_M) == TSI148_LCSR_ITAT_AS_A64) {
+		granularity = 0x10000;
+		*aspace |= VME_A64;
+	}
+
+	/* Need granularity before we set the size */
+	*size = (unsigned long long)((vme_bound - *vme_base) + granularity);
+
+
+	if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_160)
+		*cycle |= VME_2eSST160;
+	if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_267)
+		*cycle |= VME_2eSST267;
+	if ((ctl & TSI148_LCSR_ITAT_2eSSTM_M) == TSI148_LCSR_ITAT_2eSSTM_320)
+		*cycle |= VME_2eSST320;
+
+	if (ctl & TSI148_LCSR_ITAT_BLT)
+		*cycle |= VME_BLT;
+	if (ctl & TSI148_LCSR_ITAT_MBLT)
+		*cycle |= VME_MBLT;
+	if (ctl & TSI148_LCSR_ITAT_2eVME)
+		*cycle |= VME_2eVME;
+	if (ctl & TSI148_LCSR_ITAT_2eSST)
+		*cycle |= VME_2eSST;
+	if (ctl & TSI148_LCSR_ITAT_2eSSTB)
+		*cycle |= VME_2eSSTB;
+
+	if (ctl & TSI148_LCSR_ITAT_SUPR)
+		*cycle |= VME_SUPER;
+	if (ctl & TSI148_LCSR_ITAT_NPRIV)
+		*cycle |= VME_USER;
+	if (ctl & TSI148_LCSR_ITAT_PGM)
+		*cycle |= VME_PROG;
+	if (ctl & TSI148_LCSR_ITAT_DATA)
+		*cycle |= VME_DATA;
+
+	return 0;
+}
+
+/*
+ * Allocate and map PCI Resource
+ */
+static int tsi148_alloc_resource(struct vme_master_resource *image,
+	unsigned long long size)
+{
+	unsigned long long existing_size;
+	int retval = 0;
+	struct pci_dev *pdev;
+
+	/* Find pci_dev container of dev */
+        if (tsi148_bridge->parent == NULL) {
+                printk("Dev entry NULL\n");
+                return -EINVAL;
+        }
+        pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+
+	existing_size = (unsigned long long)(image->pci_resource.end -
+		image->pci_resource.start);
+
+	/* If the existing size is OK, return */
+	if (existing_size == (size - 1))
+		return 0;
+
+	if (existing_size != 0) {
+		iounmap(image->kern_base);
+		image->kern_base = NULL;
+		if (image->pci_resource.name != NULL)
+			kfree(image->pci_resource.name);
+		release_resource(&(image->pci_resource));
+		memset(&(image->pci_resource), 0, sizeof(struct resource));
+	}
+
+	if (image->pci_resource.name == NULL) {
+		image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL);
+		if (image->pci_resource.name == NULL) {
+			printk(KERN_ERR "Unable to allocate memory for resource"
+				" name\n");
+			retval = -ENOMEM;
+			goto err_name;
+		}
+	}
+
+	sprintf((char *)image->pci_resource.name, "%s.%d", tsi148_bridge->name,
+		image->number);
+
+	image->pci_resource.start = 0;
+	image->pci_resource.end = (unsigned long)size;
+	image->pci_resource.flags = IORESOURCE_MEM;
+
+	retval = pci_bus_alloc_resource(pdev->bus,
+		&(image->pci_resource), size, size, PCIBIOS_MIN_MEM,
+		0, NULL, NULL);
+	if (retval) {
+		printk(KERN_ERR "Failed to allocate mem resource for "
+			"window %d size 0x%lx start 0x%lx\n",
+			image->number, (unsigned long)size,
+			(unsigned long)image->pci_resource.start);
+		goto err_resource;
+	}
+
+	image->kern_base = ioremap_nocache(
+		image->pci_resource.start, size);
+	if (image->kern_base == NULL) {
+		printk(KERN_ERR "Failed to remap resource\n");
+		retval = -ENOMEM;
+		goto err_remap;
+	}
+
+	return 0;
+
+	iounmap(image->kern_base);
+	image->kern_base = NULL;
+err_remap:
+	release_resource(&(image->pci_resource));
+err_resource:
+	kfree(image->pci_resource.name);
+	memset(&(image->pci_resource), 0, sizeof(struct resource));
+err_name:
+	return retval;
+}
+
+/*
+ * Free and unmap PCI Resource
+ */
+static void tsi148_free_resource(struct vme_master_resource *image)
+{
+	iounmap(image->kern_base);
+	image->kern_base = NULL;
+	release_resource(&(image->pci_resource));
+	kfree(image->pci_resource.name);
+	memset(&(image->pci_resource), 0, sizeof(struct resource));
+}
+
+/*
+ * Set the attributes of an outbound window.
+ */
+int tsi148_master_set( struct vme_master_resource *image, int enabled,
+	unsigned long long vme_base, unsigned long long size,
+	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+{
+	int retval = 0;
+	unsigned int i;
+	unsigned int temp_ctl = 0;
+	unsigned int pci_base_low, pci_base_high;
+	unsigned int pci_bound_low, pci_bound_high;
+	unsigned int vme_offset_low, vme_offset_high;
+	unsigned long long pci_bound, vme_offset, pci_base;
+
+	/* Verify input data */
+	if (vme_base & 0xFFFF) {
+		printk("Invalid VME Window alignment\n");
+		retval = -EINVAL;
+		goto err_window;
+	}
+	if (size < 0x10000) {
+		printk("Invalid VME Window size\n");
+		retval = -EINVAL;
+		goto err_window;
+	}
+
+	spin_lock(&(image->lock));
+
+	/* Let's allocate the resource here rather than further up the stack as
+	 * it avoids pushing loads of bus dependant stuff up the stack
+	 */
+	retval = tsi148_alloc_resource(image, size);
+	if (retval) {
+		spin_unlock(&(image->lock));
+		printk(KERN_ERR "Unable to allocate memory for resource "
+			"name\n");
+		retval = -ENOMEM;
+		goto err_res;
+	}
+
+	pci_base = (unsigned long long)image->pci_resource.start;
+
+
+	/*
+	 * Bound address is a valid address for the window, adjust
+	 * according to window granularity.
+	 */
+	pci_bound = pci_base + (size - 0x10000);
+	vme_offset = vme_base - pci_base;
+
+	/* Convert 64-bit variables to 2x 32-bit variables */
+	reg_split(pci_base, &pci_base_high, &pci_base_low);
+	reg_split(pci_bound, &pci_bound_high, &pci_bound_low);
+	reg_split(vme_offset, &vme_offset_high, &vme_offset_low);
+
+	if (pci_base_low & 0xFFFF) {
+		spin_unlock(&(image->lock));
+		printk("Invalid PCI base alignment\n");
+		retval = -EINVAL;
+		goto err_gran;
+	}
+	if (pci_bound_low & 0xFFFF) {
+		spin_unlock(&(image->lock));
+		printk("Invalid PCI bound alignment\n");
+		retval = -EINVAL;
+		goto err_gran;
+	}
+	if (vme_offset_low & 0xFFFF) {
+		spin_unlock(&(image->lock));
+		printk("Invalid VME Offset alignment\n");
+		retval = -EINVAL;
+		goto err_gran;
+	}
+
+	i = image->number;
+
+	/* Disable while we are mucking around */
+	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTAT);
+	temp_ctl &= ~TSI148_LCSR_OTAT_EN;
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTAT);
+
+/* XXX Prefetch stuff currently unsupported */
+#if 0
+	if (vmeOut->prefetchEnable) {
+		temp_ctl |= 0x40000;
+		for (x = 0; x < 4; x++) {
+			if ((2 << x) >= vmeOut->prefetchSize)
+				break;
+		}
+		if (x == 4)
+			x = 3;
+		temp_ctl |= (x << 16);
+	}
+#endif
+
+	/* Setup 2eSST speeds */
+	temp_ctl &= ~TSI148_LCSR_OTAT_2eSSTM_M;
+	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+	case VME_2eSST160:
+		temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_160;
+		break;
+	case VME_2eSST267:
+		temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_267;
+		break;
+	case VME_2eSST320:
+		temp_ctl |= TSI148_LCSR_OTAT_2eSSTM_320;
+		break;
+	}
+
+	/* Setup cycle types */
+	if (cycle & VME_BLT) {
+		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+		temp_ctl |= TSI148_LCSR_OTAT_TM_BLT;
+	}
+	if (cycle & VME_MBLT) {
+		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+		temp_ctl |= TSI148_LCSR_OTAT_TM_MBLT;
+	}
+	if (cycle & VME_2eVME) {
+		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+		temp_ctl |= TSI148_LCSR_OTAT_TM_2eVME;
+	}
+	if (cycle & VME_2eSST) {
+		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST;
+	}
+	if (cycle & VME_2eSSTB) {
+		printk("Currently not setting Broadcast Select Registers\n");
+		temp_ctl &= ~TSI148_LCSR_OTAT_TM_M;
+		temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB;
+	}
+
+	/* Setup data width */
+	temp_ctl &= ~TSI148_LCSR_OTAT_DBW_M;
+	switch (dwidth) {
+	case VME_D16:
+		temp_ctl |= TSI148_LCSR_OTAT_DBW_16;
+		break;
+	case VME_D32:
+		temp_ctl |= TSI148_LCSR_OTAT_DBW_32;
+		break;
+	default:
+		spin_unlock(&(image->lock));
+		printk("Invalid data width\n");
+		retval = -EINVAL;
+		goto err_dwidth;
+	}
+
+	/* Setup address space */
+	temp_ctl &= ~TSI148_LCSR_OTAT_AMODE_M;
+	switch (aspace) {
+	case VME_A16:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_A16;
+		break;
+	case VME_A24:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_A24;
+		break;
+	case VME_A32:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_A32;
+		break;
+	case VME_A64:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_A64;
+		break;
+	case VME_CRCSR:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_CRCSR;
+		break;
+	case VME_USER1:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER1;
+		break;
+	case VME_USER2:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER2;
+		break;
+	case VME_USER3:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER3;
+		break;
+	case VME_USER4:
+		temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4;
+		break;
+	default:
+		spin_unlock(&(image->lock));
+		printk("Invalid address space\n");
+		retval = -EINVAL;
+		goto err_aspace;
+		break;
+	}
+
+	temp_ctl &= ~(3<<4);
+	if (cycle & VME_SUPER)
+		temp_ctl |= TSI148_LCSR_OTAT_SUP;
+	if (cycle & VME_PROG)
+		temp_ctl |= TSI148_LCSR_OTAT_PGM;
+
+	/* Setup mapping */
+	iowrite32be(pci_base_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTSAU);
+	iowrite32be(pci_base_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTSAL);
+	iowrite32be(pci_bound_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTEAU);
+	iowrite32be(pci_bound_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTEAL);
+	iowrite32be(vme_offset_high, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTOFU);
+	iowrite32be(vme_offset_low, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTOFL);
+
+/* XXX We need to deal with OTBS */
+#if 0
+	iowrite32be(vmeOut->bcastSelect2esst, tsi148_bridge->base +
+		TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTBS);
+#endif
+
+	/* Write ctl reg without enable */
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTAT);
+
+	if (enabled)
+		temp_ctl |= TSI148_LCSR_OTAT_EN;
+
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTAT);
+
+	spin_unlock(&(image->lock));
+	return 0;
+
+err_aspace:
+err_dwidth:
+err_gran:
+	tsi148_free_resource(image);
+err_res:
+err_window:
+	return retval;
+
+}
+
+/*
+ * Set the attributes of an outbound window.
+ *
+ * XXX Not parsing prefetch information.
+ */
+int __tsi148_master_get( struct vme_master_resource *image, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+{
+	unsigned int i, ctl;
+	unsigned int pci_base_low, pci_base_high;
+	unsigned int pci_bound_low, pci_bound_high;
+	unsigned int vme_offset_low, vme_offset_high;
+
+	unsigned long long pci_base, pci_bound, vme_offset;
+
+	i = image->number;
+
+	ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTAT);
+
+	pci_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTSAU);
+	pci_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTSAL);
+	pci_bound_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTEAU);
+	pci_bound_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTEAL);
+	vme_offset_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTOFU);
+	vme_offset_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTOFL);
+
+	/* Convert 64-bit variables to 2x 32-bit variables */
+	reg_join(pci_base_high, pci_base_low, &pci_base);
+	reg_join(pci_bound_high, pci_bound_low, &pci_bound);
+	reg_join(vme_offset_high, vme_offset_low, &vme_offset);
+
+	*vme_base = pci_base + vme_offset;
+	*size = (unsigned long long)(pci_bound - pci_base) + 0x10000;
+
+	*enabled = 0;
+	*aspace = 0;
+	*cycle = 0;
+	*dwidth = 0;
+
+	if (ctl & TSI148_LCSR_OTAT_EN)
+		*enabled = 1;
+
+	/* Setup address space */
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A16)
+		*aspace |= VME_A16;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A24)
+		*aspace |= VME_A24;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A32)
+		*aspace |= VME_A32;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_A64)
+		*aspace |= VME_A64;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_CRCSR)
+		*aspace |= VME_CRCSR;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER1)
+		*aspace |= VME_USER1;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER2)
+		*aspace |= VME_USER2;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER3)
+		*aspace |= VME_USER3;
+	if ((ctl & TSI148_LCSR_OTAT_AMODE_M) == TSI148_LCSR_OTAT_AMODE_USER4)
+		*aspace |= VME_USER4;
+
+	/* Setup 2eSST speeds */
+	if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_160)
+		*cycle |= VME_2eSST160;
+	if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_267)
+		*cycle |= VME_2eSST267;
+	if ((ctl & TSI148_LCSR_OTAT_2eSSTM_M) == TSI148_LCSR_OTAT_2eSSTM_320)
+		*cycle |= VME_2eSST320;
+
+	/* Setup cycle types */
+	if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_SCT)
+		*cycle |= VME_SCT;
+	if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_BLT)
+		*cycle |= VME_BLT;
+	if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_MBLT)
+		*cycle |= VME_MBLT;
+	if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eVME)
+		*cycle |= VME_2eVME;
+	if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eSST)
+		*cycle |= VME_2eSST;
+	if ((ctl & TSI148_LCSR_OTAT_TM_M ) == TSI148_LCSR_OTAT_TM_2eSSTB)
+		*cycle |= VME_2eSSTB;
+
+	if (ctl & TSI148_LCSR_OTAT_SUP)
+		*cycle |= VME_SUPER;
+	else
+		*cycle |= VME_USER;
+
+	if (ctl & TSI148_LCSR_OTAT_PGM)
+		*cycle |= VME_PROG;
+	else
+		*cycle |= VME_DATA;
+
+	/* Setup data width */
+	if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_16)
+		*dwidth = VME_D16;
+	if ((ctl & TSI148_LCSR_OTAT_DBW_M) == TSI148_LCSR_OTAT_DBW_32)
+		*dwidth = VME_D32;
+
+	return 0;
+}
+
+
+int tsi148_master_get( struct vme_master_resource *image, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+{
+	int retval;
+
+	spin_lock(&(image->lock));
+
+	retval = __tsi148_master_get(image, enabled, vme_base, size, aspace,
+		cycle, dwidth);
+
+	spin_unlock(&(image->lock));
+
+	return retval;
+}
+
+ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
+	size_t count, loff_t offset)
+{
+	int retval, enabled;
+	unsigned long long vme_base, size;
+	vme_address_t aspace;
+	vme_cycle_t cycle;
+	vme_width_t dwidth;
+	struct vme_bus_error *vme_err = NULL;
+
+	spin_lock(&(image->lock));
+
+	memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count);
+	retval = count;
+
+	if (!err_chk)
+		goto skip_chk;
+
+	__tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
+		&dwidth);
+
+	vme_err = tsi148_find_error(aspace, vme_base + offset, count);
+	if(vme_err != NULL) {
+		dev_err(image->parent->parent, "First VME read error detected "
+			"an at address 0x%llx\n", vme_err->address);
+		retval = vme_err->address - (vme_base + offset);
+		/* Clear down save errors in this address range */
+		tsi148_clear_errors(aspace, vme_base + offset, count);
+	}
+
+skip_chk:
+	spin_unlock(&(image->lock));
+
+	return retval;
+}
+
+
+/* XXX We need to change vme_master_resource->mtx to a spinlock so that read
+ *     and write functions can be used in an interrupt context
+ */
+ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
+	size_t count, loff_t offset)
+{
+	int retval = 0, enabled;
+	unsigned long long vme_base, size;
+	vme_address_t aspace;
+	vme_cycle_t cycle;
+	vme_width_t dwidth;
+
+	struct vme_bus_error *vme_err = NULL;
+
+	spin_lock(&(image->lock));
+
+	memcpy_toio(image->kern_base + offset, buf, (unsigned int)count);
+	retval = count;
+
+	/*
+	 * Writes are posted. We need to do a read on the VME bus to flush out
+	 * all of the writes before we check for errors. We can't guarentee
+	 * that reading the data we have just written is safe. It is believed
+	 * that there isn't any read, write re-ordering, so we can read any
+	 * location in VME space, so lets read the Device ID from the tsi148's
+	 * own registers as mapped into CR/CSR space.
+	 *
+	 * We check for saved errors in the written address range/space.
+	 */
+
+	if (!err_chk)
+		goto skip_chk;
+
+	/*
+	 * Get window info first, to maximise the time that the buffers may
+	 * fluch on their own
+	 */
+	__tsi148_master_get(image, &enabled, &vme_base, &size, &aspace, &cycle,
+		&dwidth);
+
+	ioread16(flush_image->kern_base + 0x7F000);
+
+	vme_err = tsi148_find_error(aspace, vme_base + offset, count);
+	if(vme_err != NULL) {
+		printk("First VME write error detected an at address 0x%llx\n",
+			vme_err->address);
+		retval = vme_err->address - (vme_base + offset);
+		/* Clear down save errors in this address range */
+		tsi148_clear_errors(aspace, vme_base + offset, count);
+	}
+
+skip_chk:
+	spin_unlock(&(image->lock));
+
+	return retval;
+}
+
+/*
+ * Perform an RMW cycle on the VME bus.
+ *
+ * Requires a previously configured master window, returns final value.
+ */
+unsigned int tsi148_master_rmw(struct vme_master_resource *image,
+	unsigned int mask, unsigned int compare, unsigned int swap,
+	loff_t offset)
+{
+	unsigned long long pci_addr;
+	unsigned int pci_addr_high, pci_addr_low;
+	u32 tmp, result;
+	int i;
+
+
+	/* Find the PCI address that maps to the desired VME address */
+	i = image->number;
+
+	/* Locking as we can only do one of these at a time */
+	mutex_lock(&(vme_rmw));
+
+	/* Lock image */
+	spin_lock(&(image->lock));
+
+	pci_addr_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTSAU);
+	pci_addr_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_OT[i] +
+		TSI148_LCSR_OFFSET_OTSAL);
+
+	reg_join(pci_addr_high, pci_addr_low, &pci_addr);
+	reg_split(pci_addr + offset, &pci_addr_high, &pci_addr_low);
+
+	/* Configure registers */
+	iowrite32be(mask, tsi148_bridge->base + TSI148_LCSR_RMWEN);
+	iowrite32be(compare, tsi148_bridge->base + TSI148_LCSR_RMWC);
+	iowrite32be(swap, tsi148_bridge->base + TSI148_LCSR_RMWS);
+	iowrite32be(pci_addr_high, tsi148_bridge->base + TSI148_LCSR_RMWAU);
+	iowrite32be(pci_addr_low, tsi148_bridge->base + TSI148_LCSR_RMWAL);
+
+	/* Enable RMW */
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	tmp |= TSI148_LCSR_VMCTRL_RMWEN;
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+
+	/* Kick process off with a read to the required address. */
+	result = ioread32be(image->kern_base + offset);
+
+	/* Disable RMW */
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	tmp &= ~TSI148_LCSR_VMCTRL_RMWEN;
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+
+	spin_unlock(&(image->lock));
+
+	mutex_unlock(&(vme_rmw));
+
+	return result;
+}
+
+static int tsi148_dma_set_vme_src_attributes (u32 *attr, vme_address_t aspace,
+	vme_cycle_t cycle, vme_width_t dwidth)
+{
+	/* Setup 2eSST speeds */
+	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+	case VME_2eSST160:
+		*attr |= TSI148_LCSR_DSAT_2eSSTM_160;
+		break;
+	case VME_2eSST267:
+		*attr |= TSI148_LCSR_DSAT_2eSSTM_267;
+		break;
+	case VME_2eSST320:
+		*attr |= TSI148_LCSR_DSAT_2eSSTM_320;
+		break;
+	}
+
+	/* Setup cycle types */
+	if (cycle & VME_SCT) {
+		*attr |= TSI148_LCSR_DSAT_TM_SCT;
+	}
+	if (cycle & VME_BLT) {
+		*attr |= TSI148_LCSR_DSAT_TM_BLT;
+	}
+	if (cycle & VME_MBLT) {
+		*attr |= TSI148_LCSR_DSAT_TM_MBLT;
+	}
+	if (cycle & VME_2eVME) {
+		*attr |= TSI148_LCSR_DSAT_TM_2eVME;
+	}
+	if (cycle & VME_2eSST) {
+		*attr |= TSI148_LCSR_DSAT_TM_2eSST;
+	}
+	if (cycle & VME_2eSSTB) {
+		printk("Currently not setting Broadcast Select Registers\n");
+		*attr |= TSI148_LCSR_DSAT_TM_2eSSTB;
+	}
+
+	/* Setup data width */
+	switch (dwidth) {
+	case VME_D16:
+		*attr |= TSI148_LCSR_DSAT_DBW_16;
+		break;
+	case VME_D32:
+		*attr |= TSI148_LCSR_DSAT_DBW_32;
+		break;
+	default:
+		printk("Invalid data width\n");
+		return -EINVAL;
+	}
+
+	/* Setup address space */
+	switch (aspace) {
+	case VME_A16:
+		*attr |= TSI148_LCSR_DSAT_AMODE_A16;
+		break;
+	case VME_A24:
+		*attr |= TSI148_LCSR_DSAT_AMODE_A24;
+		break;
+	case VME_A32:
+		*attr |= TSI148_LCSR_DSAT_AMODE_A32;
+		break;
+	case VME_A64:
+		*attr |= TSI148_LCSR_DSAT_AMODE_A64;
+		break;
+	case VME_CRCSR:
+		*attr |= TSI148_LCSR_DSAT_AMODE_CRCSR;
+		break;
+	case VME_USER1:
+		*attr |= TSI148_LCSR_DSAT_AMODE_USER1;
+		break;
+	case VME_USER2:
+		*attr |= TSI148_LCSR_DSAT_AMODE_USER2;
+		break;
+	case VME_USER3:
+		*attr |= TSI148_LCSR_DSAT_AMODE_USER3;
+		break;
+	case VME_USER4:
+		*attr |= TSI148_LCSR_DSAT_AMODE_USER4;
+		break;
+	default:
+		printk("Invalid address space\n");
+		return -EINVAL;
+		break;
+	}
+
+	if (cycle & VME_SUPER)
+		*attr |= TSI148_LCSR_DSAT_SUP;
+	if (cycle & VME_PROG)
+		*attr |= TSI148_LCSR_DSAT_PGM;
+
+	return 0;
+}
+
+static int tsi148_dma_set_vme_dest_attributes(u32 *attr, vme_address_t aspace,
+	vme_cycle_t cycle, vme_width_t dwidth)
+{
+	/* Setup 2eSST speeds */
+	switch (cycle & (VME_2eSST160 | VME_2eSST267 | VME_2eSST320)) {
+	case VME_2eSST160:
+		*attr |= TSI148_LCSR_DDAT_2eSSTM_160;
+		break;
+	case VME_2eSST267:
+		*attr |= TSI148_LCSR_DDAT_2eSSTM_267;
+		break;
+	case VME_2eSST320:
+		*attr |= TSI148_LCSR_DDAT_2eSSTM_320;
+		break;
+	}
+
+	/* Setup cycle types */
+	if (cycle & VME_SCT) {
+		*attr |= TSI148_LCSR_DDAT_TM_SCT;
+	}
+	if (cycle & VME_BLT) {
+		*attr |= TSI148_LCSR_DDAT_TM_BLT;
+	}
+	if (cycle & VME_MBLT) {
+		*attr |= TSI148_LCSR_DDAT_TM_MBLT;
+	}
+	if (cycle & VME_2eVME) {
+		*attr |= TSI148_LCSR_DDAT_TM_2eVME;
+	}
+	if (cycle & VME_2eSST) {
+		*attr |= TSI148_LCSR_DDAT_TM_2eSST;
+	}
+	if (cycle & VME_2eSSTB) {
+		printk("Currently not setting Broadcast Select Registers\n");
+		*attr |= TSI148_LCSR_DDAT_TM_2eSSTB;
+	}
+
+	/* Setup data width */
+	switch (dwidth) {
+	case VME_D16:
+		*attr |= TSI148_LCSR_DDAT_DBW_16;
+		break;
+	case VME_D32:
+		*attr |= TSI148_LCSR_DDAT_DBW_32;
+		break;
+	default:
+		printk("Invalid data width\n");
+		return -EINVAL;
+	}
+
+	/* Setup address space */
+	switch (aspace) {
+	case VME_A16:
+		*attr |= TSI148_LCSR_DDAT_AMODE_A16;
+		break;
+	case VME_A24:
+		*attr |= TSI148_LCSR_DDAT_AMODE_A24;
+		break;
+	case VME_A32:
+		*attr |= TSI148_LCSR_DDAT_AMODE_A32;
+		break;
+	case VME_A64:
+		*attr |= TSI148_LCSR_DDAT_AMODE_A64;
+		break;
+	case VME_CRCSR:
+		*attr |= TSI148_LCSR_DDAT_AMODE_CRCSR;
+		break;
+	case VME_USER1:
+		*attr |= TSI148_LCSR_DDAT_AMODE_USER1;
+		break;
+	case VME_USER2:
+		*attr |= TSI148_LCSR_DDAT_AMODE_USER2;
+		break;
+	case VME_USER3:
+		*attr |= TSI148_LCSR_DDAT_AMODE_USER3;
+		break;
+	case VME_USER4:
+		*attr |= TSI148_LCSR_DDAT_AMODE_USER4;
+		break;
+	default:
+		printk("Invalid address space\n");
+		return -EINVAL;
+		break;
+	}
+
+	if (cycle & VME_SUPER)
+		*attr |= TSI148_LCSR_DDAT_SUP;
+	if (cycle & VME_PROG)
+		*attr |= TSI148_LCSR_DDAT_PGM;
+
+	return 0;
+}
+
+/*
+ * Add a link list descriptor to the list
+ *
+ * XXX Need to handle 2eSST Broadcast select bits
+ */
+int tsi148_dma_list_add (struct vme_dma_list *list, struct vme_dma_attr *src,
+	struct vme_dma_attr *dest, size_t count)
+{
+	struct tsi148_dma_entry *entry, *prev;
+	u32 address_high, address_low;
+	struct vme_dma_pattern *pattern_attr;
+	struct vme_dma_pci *pci_attr;
+	struct vme_dma_vme *vme_attr;
+	dma_addr_t desc_ptr;
+	int retval = 0;
+
+	/* XXX descriptor must be aligned on 64-bit boundaries */
+	entry = (struct tsi148_dma_entry *)kmalloc(
+		sizeof(struct tsi148_dma_entry), GFP_KERNEL);
+	if (entry == NULL) {
+		printk("Failed to allocate memory for dma resource "
+			"structure\n");
+		retval = -ENOMEM;
+		goto err_mem;
+	}
+
+	/* Test descriptor alignment */
+	if ((unsigned long)&(entry->descriptor) & 0x7) {
+		printk("Descriptor not aligned to 8 byte boundary as "
+			"required: %p\n", &(entry->descriptor));
+		retval = -EINVAL;
+		goto err_align;
+	}
+
+	/* Given we are going to fill out the structure, we probably don't
+	 * need to zero it, but better safe than sorry for now.
+	 */
+	memset(&(entry->descriptor), 0, sizeof(struct tsi148_dma_descriptor));
+
+	/* Fill out source part */
+	switch (src->type) {
+	case VME_DMA_PATTERN:
+		pattern_attr = (struct vme_dma_pattern *)src->private;
+
+		entry->descriptor.dsal = pattern_attr->pattern;
+		entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PAT;
+		/* Default behaviour is 32 bit pattern */
+		if (pattern_attr->type & VME_DMA_PATTERN_BYTE) {
+			entry->descriptor.dsat |= TSI148_LCSR_DSAT_PSZ;
+		}
+		/* It seems that the default behaviour is to increment */
+		if ((pattern_attr->type & VME_DMA_PATTERN_INCREMENT) == 0) {
+			entry->descriptor.dsat |= TSI148_LCSR_DSAT_NIN;
+		}
+		break;
+	case VME_DMA_PCI:
+		pci_attr = (struct vme_dma_pci *)src->private;
+
+		reg_split((unsigned long long)pci_attr->address, &address_high,
+			&address_low);
+		entry->descriptor.dsau = address_high;
+		entry->descriptor.dsal = address_low;
+		entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_PCI;
+		break;
+	case VME_DMA_VME:
+		vme_attr = (struct vme_dma_vme *)src->private;
+
+		reg_split((unsigned long long)vme_attr->address, &address_high,
+			&address_low);
+		entry->descriptor.dsau = address_high;
+		entry->descriptor.dsal = address_low;
+		entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_VME;
+
+		retval = tsi148_dma_set_vme_src_attributes(
+			&(entry->descriptor.dsat), vme_attr->aspace,
+			vme_attr->cycle, vme_attr->dwidth);
+		if(retval < 0 )
+			goto err_source;
+		break;
+	default:
+		printk("Invalid source type\n");
+		retval = -EINVAL;
+		goto err_source;
+		break;
+	}
+
+	/* Assume last link - this will be over-written by adding another */
+	entry->descriptor.dnlau = 0;
+	entry->descriptor.dnlal = TSI148_LCSR_DNLAL_LLA;
+
+
+	/* Fill out destination part */
+	switch (dest->type) {
+	case VME_DMA_PCI:
+		pci_attr = (struct vme_dma_pci *)dest->private;
+
+		reg_split((unsigned long long)pci_attr->address, &address_high,
+			&address_low);
+		entry->descriptor.ddau = address_high;
+		entry->descriptor.ddal = address_low;
+		entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_PCI;
+		break;
+	case VME_DMA_VME:
+		vme_attr = (struct vme_dma_vme *)dest->private;
+
+		reg_split((unsigned long long)vme_attr->address, &address_high,
+			&address_low);
+		entry->descriptor.ddau = address_high;
+		entry->descriptor.ddal = address_low;
+		entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_VME;
+
+		retval = tsi148_dma_set_vme_dest_attributes(
+			&(entry->descriptor.ddat), vme_attr->aspace,
+			vme_attr->cycle, vme_attr->dwidth);
+		if(retval < 0 )
+			goto err_dest;
+		break;
+	default:
+		printk("Invalid destination type\n");
+		retval = -EINVAL;
+		goto err_dest;
+		break;
+	}
+
+	/* Fill out count */
+	entry->descriptor.dcnt = (u32)count;
+
+	/* Add to list */
+	list_add_tail(&(entry->list), &(list->entries));
+
+	/* Fill out previous descriptors "Next Address" */
+	if(entry->list.prev != &(list->entries)){
+		prev = list_entry(entry->list.prev, struct tsi148_dma_entry,
+			list);
+		/* We need the bus address for the pointer */
+		desc_ptr = virt_to_bus(&(entry->descriptor));
+		reg_split(desc_ptr, &(prev->descriptor.dnlau),
+			&(prev->descriptor.dnlal));
+	}
+
+	return 0;
+
+err_dest:
+err_source:
+err_align:
+		kfree(entry);
+err_mem:
+	return retval;
+}
+
+/*
+ * Check to see if the provided DMA channel is busy.
+ */
+static int tsi148_dma_busy(int channel)
+{
+	u32 tmp;
+
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+		TSI148_LCSR_OFFSET_DSTA);
+
+	if (tmp & TSI148_LCSR_DSTA_BSY)
+		return 0;
+	else
+		return 1;
+
+}
+
+/*
+ * Execute a previously generated link list
+ *
+ * XXX Need to provide control register configuration.
+ */
+int tsi148_dma_list_exec(struct vme_dma_list *list)
+{
+	struct vme_dma_resource *ctrlr;
+	int channel, retval = 0;
+	struct tsi148_dma_entry *entry;
+	dma_addr_t bus_addr;
+	u32 bus_addr_high, bus_addr_low;
+	u32 val, dctlreg = 0;
+#if 0
+	int x;
+#endif
+
+	ctrlr = list->parent;
+
+	mutex_lock(&(ctrlr->mtx));
+
+	channel = ctrlr->number;
+
+	if (! list_empty(&(ctrlr->running))) {
+		/*
+		 * XXX We have an active DMA transfer and currently haven't
+		 *     sorted out the mechanism for "pending" DMA transfers.
+		 *     Return busy.
+		 */
+		/* Need to add to pending here */
+		mutex_unlock(&(ctrlr->mtx));
+		return -EBUSY;
+	} else {
+		list_add(&(list->list), &(ctrlr->running));
+	}
+#if 0
+	/* XXX Still todo */
+	for (x = 0; x < 8; x++) {	/* vme block size */
+		if ((32 << x) >= vmeDma->maxVmeBlockSize) {
+			break;
+		}
+	}
+	if (x == 8)
+		x = 7;
+	dctlreg |= (x << 12);
+
+	for (x = 0; x < 8; x++) {	/* pci block size */
+		if ((32 << x) >= vmeDma->maxPciBlockSize) {
+			break;
+		}
+	}
+	if (x == 8)
+		x = 7;
+	dctlreg |= (x << 4);
+
+	if (vmeDma->vmeBackOffTimer) {
+		for (x = 1; x < 8; x++) {	/* vme timer */
+			if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
+				break;
+			}
+		}
+		if (x == 8)
+			x = 7;
+		dctlreg |= (x << 8);
+	}
+
+	if (vmeDma->pciBackOffTimer) {
+		for (x = 1; x < 8; x++) {	/* pci timer */
+			if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
+				break;
+			}
+		}
+		if (x == 8)
+			x = 7;
+		dctlreg |= (x << 0);
+	}
+#endif
+
+	/* Get first bus address and write into registers */
+	entry = list_first_entry(&(list->entries), struct tsi148_dma_entry,
+		list);
+
+	bus_addr = virt_to_bus(&(entry->descriptor));
+
+	mutex_unlock(&(ctrlr->mtx));
+
+	reg_split(bus_addr, &bus_addr_high, &bus_addr_low);
+
+	iowrite32be(bus_addr_high, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAU);
+	iowrite32be(bus_addr_low, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DNLAL);
+
+	/* Start the operation */
+	iowrite32be(dctlreg | TSI148_LCSR_DCTL_DGO, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
+
+	wait_event_interruptible(dma_queue[channel], tsi148_dma_busy(channel));
+	/*
+	 * Read status register, this register is valid until we kick off a
+	 * new transfer.
+	 */
+	val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+		TSI148_LCSR_OFFSET_DSTA);
+
+	if (val & TSI148_LCSR_DSTA_VBE) {
+		printk(KERN_ERR "tsi148: DMA Error. DSTA=%08X\n", val);
+		retval = -EIO;
+	}
+
+	/* Remove list from running list */
+	mutex_lock(&(ctrlr->mtx));
+	list_del(&(list->list));
+	mutex_unlock(&(ctrlr->mtx));
+
+	return retval;
+}
+
+/*
+ * Clean up a previously generated link list
+ *
+ * We have a separate function, don't assume that the chain can't be reused.
+ */
+int tsi148_dma_list_empty(struct vme_dma_list *list)
+{
+	struct list_head *pos, *temp;
+        struct tsi148_dma_entry *entry;
+
+	/* detach and free each entry */
+	list_for_each_safe(pos, temp, &(list->entries)) {
+		list_del(pos);
+		entry = list_entry(pos, struct tsi148_dma_entry, list);
+		kfree(entry);
+	}
+
+	return (0);
+}
+
+/*
+ * All 4 location monitors reside at the same base - this is therefore a
+ * system wide configuration.
+ *
+ * This does not enable the LM monitor - that should be done when the first
+ * callback is attached and disabled when the last callback is removed.
+ */
+int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base,
+	vme_address_t aspace, vme_cycle_t cycle)
+{
+	u32 lm_base_high, lm_base_low, lm_ctl = 0;
+	int i;
+
+	mutex_lock(&(lm->mtx));
+
+	/* If we already have a callback attached, we can't move it! */
+	for (i = 0; i < lm->monitors; i++) {
+		if(lm_callback[i] != NULL) {
+			mutex_unlock(&(lm->mtx));
+			printk("Location monitor callback attached, can't "
+				"reset\n");
+			return -EBUSY;
+		}
+	}
+
+	switch (aspace) {
+	case VME_A16:
+		lm_ctl |= TSI148_LCSR_LMAT_AS_A16;
+		break;
+	case VME_A24:
+		lm_ctl |= TSI148_LCSR_LMAT_AS_A24;
+		break;
+	case VME_A32:
+		lm_ctl |= TSI148_LCSR_LMAT_AS_A32;
+		break;
+	case VME_A64:
+		lm_ctl |= TSI148_LCSR_LMAT_AS_A64;
+		break;
+	default:
+		mutex_unlock(&(lm->mtx));
+		printk("Invalid address space\n");
+		return -EINVAL;
+		break;
+	}
+
+	if (cycle & VME_SUPER)
+		lm_ctl |= TSI148_LCSR_LMAT_SUPR ;
+	if (cycle & VME_USER)
+		lm_ctl |= TSI148_LCSR_LMAT_NPRIV;
+	if (cycle & VME_PROG)
+		lm_ctl |= TSI148_LCSR_LMAT_PGM;
+	if (cycle & VME_DATA)
+		lm_ctl |= TSI148_LCSR_LMAT_DATA;
+
+	reg_split(lm_base, &lm_base_high, &lm_base_low);
+
+	iowrite32be(lm_base_high, tsi148_bridge->base + TSI148_LCSR_LMBAU);
+	iowrite32be(lm_base_low, tsi148_bridge->base + TSI148_LCSR_LMBAL);
+	iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
+
+	mutex_unlock(&(lm->mtx));
+
+	return 0;
+}
+
+/* Get configuration of the callback monitor and return whether it is enabled
+ * or disabled.
+ */
+int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base,
+	vme_address_t *aspace, vme_cycle_t *cycle)
+{
+	u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0;
+
+	mutex_lock(&(lm->mtx));
+
+	lm_base_high = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAU);
+	lm_base_low = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMBAL);
+	lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+
+	reg_join(lm_base_high, lm_base_low, lm_base);
+
+	if (lm_ctl & TSI148_LCSR_LMAT_EN)
+		enabled = 1;
+
+	if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A16) {
+		*aspace |= VME_A16;
+	}
+	if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A24) {
+		*aspace |= VME_A24;
+	}
+	if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A32) {
+		*aspace |= VME_A32;
+	}
+	if ((lm_ctl & TSI148_LCSR_LMAT_AS_M) == TSI148_LCSR_LMAT_AS_A64) {
+		*aspace |= VME_A64;
+	}
+
+	if (lm_ctl & TSI148_LCSR_LMAT_SUPR)
+		*cycle |= VME_SUPER;
+	if (lm_ctl & TSI148_LCSR_LMAT_NPRIV)
+		*cycle |= VME_USER;
+	if (lm_ctl & TSI148_LCSR_LMAT_PGM)
+		*cycle |= VME_PROG;
+	if (lm_ctl & TSI148_LCSR_LMAT_DATA)
+		*cycle |= VME_DATA;
+
+	mutex_unlock(&(lm->mtx));
+
+	return enabled;
+}
+
+/*
+ * Attach a callback to a specific location monitor.
+ *
+ * Callback will be passed the monitor triggered.
+ */
+int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor,
+	void (*callback)(int))
+{
+	u32 lm_ctl, tmp;
+
+	mutex_lock(&(lm->mtx));
+
+	/* Ensure that the location monitor is configured - need PGM or DATA */
+	lm_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+	if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) {
+		mutex_unlock(&(lm->mtx));
+		printk("Location monitor not properly configured\n");
+		return -EINVAL;
+	}
+
+	/* Check that a callback isn't already attached */
+	if (lm_callback[monitor] != NULL) {
+		mutex_unlock(&(lm->mtx));
+		printk("Existing callback attached\n");
+		return -EBUSY;
+	}
+
+	/* Attach callback */
+	lm_callback[monitor] = callback;
+
+	/* Enable Location Monitor interrupt */
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+	tmp |= TSI148_LCSR_INTEN_LMEN[monitor];
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEN);
+
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+	tmp |= TSI148_LCSR_INTEO_LMEO[monitor];
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+
+	/* Ensure that global Location Monitor Enable set */
+	if ((lm_ctl & TSI148_LCSR_LMAT_EN) == 0) {
+		lm_ctl |= TSI148_LCSR_LMAT_EN;
+		iowrite32be(lm_ctl, tsi148_bridge->base + TSI148_LCSR_LMAT);
+	}
+
+	mutex_unlock(&(lm->mtx));
+
+	return 0;
+}
+
+/*
+ * Detach a callback function forn a specific location monitor.
+ */
+int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor)
+{
+	u32 lm_en, tmp;
+
+	mutex_lock(&(lm->mtx));
+
+	/* Disable Location Monitor and ensure previous interrupts are clear */
+	lm_en = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEN);
+	lm_en &= ~TSI148_LCSR_INTEN_LMEN[monitor];
+	iowrite32be(lm_en, tsi148_bridge->base + TSI148_LCSR_INTEN);
+
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_INTEO);
+	tmp &= ~TSI148_LCSR_INTEO_LMEO[monitor];
+	iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_INTEO);
+
+	iowrite32be(TSI148_LCSR_INTC_LMC[monitor],
+		 tsi148_bridge->base + TSI148_LCSR_INTEO);
+
+	/* Detach callback */
+	lm_callback[monitor] = NULL;
+
+	/* If all location monitors disabled, disable global Location Monitor */
+	if ((lm_en & (TSI148_LCSR_INTS_LM0S | TSI148_LCSR_INTS_LM1S |
+			TSI148_LCSR_INTS_LM2S | TSI148_LCSR_INTS_LM3S)) == 0) {
+		tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_LMAT);
+		tmp &= ~TSI148_LCSR_LMAT_EN;
+		iowrite32be(tmp, tsi148_bridge->base + TSI148_LCSR_LMAT);
+	}
+
+	mutex_unlock(&(lm->mtx));
+
+	return 0;
+}
+
+/*
+ * Determine Geographical Addressing
+ */
+int tsi148_slot_get(void)
+{
+        u32 slot = 0;
+
+	slot = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
+	slot = slot & TSI148_LCSR_VSTAT_GA_M;
+	return (int)slot;
+}
+
+static int __init tsi148_init(void)
+{
+	return pci_register_driver(&tsi148_driver);
+}
+
+/*
+ * Configure CR/CSR space
+ *
+ * Access to the CR/CSR can be configured at power-up. The location of the
+ * CR/CSR registers in the CR/CSR address space is determined by the boards
+ * Auto-ID or Geographic address. This function ensures that the window is
+ * enabled at an offset consistent with the boards geopgraphic address.
+ *
+ * Each board has a 512kB window, with the highest 4kB being used for the
+ * boards registers, this means there is a fix length 508kB window which must
+ * be mapped onto PCI memory.
+ */
+static int tsi148_crcsr_init(struct pci_dev *pdev)
+{
+	u32 cbar, crat, vstat;
+	u32 crcsr_bus_high, crcsr_bus_low;
+	int retval;
+
+	/* Allocate mem for CR/CSR image */
+	crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE,
+		&crcsr_bus);
+	if (crcsr_kernel == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR "
+			"image\n");
+		return -ENOMEM;
+	}
+
+	memset(crcsr_kernel, 0, VME_CRCSR_BUF_SIZE);
+
+	reg_split(crcsr_bus, &crcsr_bus_high, &crcsr_bus_low);
+
+	iowrite32be(crcsr_bus_high, tsi148_bridge->base + TSI148_LCSR_CROU);
+	iowrite32be(crcsr_bus_low, tsi148_bridge->base + TSI148_LCSR_CROL);
+
+	/* Ensure that the CR/CSR is configured at the correct offset */
+	cbar = ioread32be(tsi148_bridge->base + TSI148_CBAR);
+	cbar = (cbar & TSI148_CRCSR_CBAR_M)>>3;
+
+	vstat = tsi148_slot_get();
+
+	if (cbar != vstat) {
+		dev_info(&pdev->dev, "Setting CR/CSR offset\n");
+		iowrite32be(cbar<<3, tsi148_bridge->base + TSI148_CBAR);
+	}
+	dev_info(&pdev->dev, "CR/CSR Offset: %d\n", cbar);
+
+	crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT);
+	if (crat & TSI148_LCSR_CRAT_EN) {
+		dev_info(&pdev->dev, "Enabling CR/CSR space\n");
+		iowrite32be(crat | TSI148_LCSR_CRAT_EN,
+			tsi148_bridge->base + TSI148_LCSR_CRAT);
+	} else
+		dev_info(&pdev->dev, "CR/CSR already enabled\n");
+
+	/* If we want flushed, error-checked writes, set up a window
+	 * over the CR/CSR registers. We read from here to safely flush
+	 * through VME writes.
+	 */
+	if(err_chk) {
+		retval = tsi148_master_set(flush_image, 1, (vstat * 0x80000),
+			0x80000, VME_CRCSR, VME_SCT, VME_D16);
+		if (retval)
+			dev_err(&pdev->dev, "Configuring flush image failed\n");
+	}
+
+	return 0;
+
+}
+
+static void tsi148_crcsr_exit(struct pci_dev *pdev)
+{
+	u32 crat;
+
+	/* Turn off CR/CSR space */
+	crat = ioread32be(tsi148_bridge->base + TSI148_LCSR_CRAT);
+	iowrite32be(crat & ~TSI148_LCSR_CRAT_EN,
+		tsi148_bridge->base + TSI148_LCSR_CRAT);
+
+	/* Free image */
+	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROU);
+	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CROL);
+
+	pci_free_consistent(pdev, VME_CRCSR_BUF_SIZE, crcsr_kernel, crcsr_bus);
+}
+
+static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	int retval, i, master_num;
+	u32 data;
+	struct list_head *pos = NULL;
+	struct vme_master_resource *master_image;
+	struct vme_slave_resource *slave_image;
+	struct vme_dma_resource *dma_ctrlr;
+	struct vme_lm_resource *lm;
+
+	/* If we want to support more than one of each bridge, we need to
+	 * dynamically generate this so we get one per device
+	 */
+	tsi148_bridge = (struct vme_bridge *)kmalloc(sizeof(struct vme_bridge),
+		GFP_KERNEL);
+	if (tsi148_bridge == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for device "
+			"structure\n");
+		retval = -ENOMEM;
+		goto err_struct;
+	}
+
+	memset(tsi148_bridge, 0, sizeof(struct vme_bridge));
+
+	/* Enable the device */
+	retval = pci_enable_device(pdev);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to enable device\n");
+		goto err_enable;
+	}
+
+	/* Map Registers */
+	retval = pci_request_regions(pdev, driver_name);
+	if (retval) {
+		dev_err(&pdev->dev, "Unable to reserve resources\n");
+		goto err_resource;
+	}
+
+	/* map registers in BAR 0 */
+	tsi148_bridge->base = ioremap_nocache(pci_resource_start(pdev, 0), 4096);
+	if (!tsi148_bridge->base) {
+		dev_err(&pdev->dev, "Unable to remap CRG region\n");
+		retval = -EIO;
+		goto err_remap;
+	}
+
+	/* Check to see if the mapping worked out */
+	data = ioread32(tsi148_bridge->base + TSI148_PCFS_ID) & 0x0000FFFF;
+	if (data != PCI_VENDOR_ID_TUNDRA) {
+		dev_err(&pdev->dev, "CRG region check failed\n");
+		retval = -EIO;
+		goto err_test;
+	}
+
+	/* Initialize wait queues & mutual exclusion flags */
+	/* XXX These need to be moved to the vme_bridge structure */
+	init_waitqueue_head(&dma_queue[0]);
+	init_waitqueue_head(&dma_queue[1]);
+	init_waitqueue_head(&iack_queue);
+	mutex_init(&(vme_int));
+	mutex_init(&(vme_irq));
+	mutex_init(&(vme_rmw));
+
+	tsi148_bridge->parent = &(pdev->dev);
+	strcpy(tsi148_bridge->name, driver_name);
+
+	/* Setup IRQ */
+	retval = tsi148_irq_init(tsi148_bridge);
+	if (retval != 0) {
+		dev_err(&pdev->dev, "Chip Initialization failed.\n");
+		goto err_irq;
+	}
+
+	/* If we are going to flush writes, we need to read from the VME bus.
+	 * We need to do this safely, thus we read the devices own CR/CSR
+	 * register. To do this we must set up a window in CR/CSR space and
+	 * hence have one less master window resource available.
+	 */
+	master_num = TSI148_MAX_MASTER;
+	if(err_chk){
+		master_num--;
+		/* XXX */
+		flush_image = (struct vme_master_resource *)kmalloc(
+			sizeof(struct vme_master_resource), GFP_KERNEL);
+		if (flush_image == NULL) {
+			dev_err(&pdev->dev, "Failed to allocate memory for "
+			"flush resource structure\n");
+			retval = -ENOMEM;
+			goto err_master;
+		}
+		flush_image->parent = tsi148_bridge;
+		spin_lock_init(&(flush_image->lock));
+		flush_image->locked = 1;
+		flush_image->number = master_num;
+		flush_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+			VME_A64;
+		flush_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+			VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
+			VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
+			VME_PROG | VME_DATA;
+		flush_image->width_attr = VME_D16 | VME_D32;
+		memset(&(flush_image->pci_resource), 0,
+			sizeof(struct resource));
+		flush_image->kern_base  = NULL;
+	}
+
+	/* Add master windows to list */
+	INIT_LIST_HEAD(&(tsi148_bridge->master_resources));
+	for (i = 0; i < master_num; i++) {
+		master_image = (struct vme_master_resource *)kmalloc(
+			sizeof(struct vme_master_resource), GFP_KERNEL);
+		if (master_image == NULL) {
+			dev_err(&pdev->dev, "Failed to allocate memory for "
+			"master resource structure\n");
+			retval = -ENOMEM;
+			goto err_master;
+		}
+		master_image->parent = tsi148_bridge;
+		spin_lock_init(&(master_image->lock));
+		master_image->locked = 0;
+		master_image->number = i;
+		master_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+			VME_A64;
+		master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+			VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
+			VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
+			VME_PROG | VME_DATA;
+		master_image->width_attr = VME_D16 | VME_D32;
+		memset(&(master_image->pci_resource), 0,
+			sizeof(struct resource));
+		master_image->kern_base  = NULL;
+		list_add_tail(&(master_image->list),
+			&(tsi148_bridge->master_resources));
+	}
+
+	/* Add slave windows to list */
+	INIT_LIST_HEAD(&(tsi148_bridge->slave_resources));
+	for (i = 0; i < TSI148_MAX_SLAVE; i++) {
+		slave_image = (struct vme_slave_resource *)kmalloc(
+			sizeof(struct vme_slave_resource), GFP_KERNEL);
+		if (slave_image == NULL) {
+			dev_err(&pdev->dev, "Failed to allocate memory for "
+			"slave resource structure\n");
+			retval = -ENOMEM;
+			goto err_slave;
+		}
+		slave_image->parent = tsi148_bridge;
+		mutex_init(&(slave_image->mtx));
+		slave_image->locked = 0;
+		slave_image->number = i;
+		slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 |
+			VME_A64 | VME_CRCSR | VME_USER1 | VME_USER2 |
+			VME_USER3 | VME_USER4;
+		slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT |
+			VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 |
+			VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER |
+			VME_PROG | VME_DATA;
+		list_add_tail(&(slave_image->list),
+			&(tsi148_bridge->slave_resources));
+	}
+
+	/* Add dma engines to list */
+	INIT_LIST_HEAD(&(tsi148_bridge->dma_resources));
+	for (i = 0; i < TSI148_MAX_DMA; i++) {
+		dma_ctrlr = (struct vme_dma_resource *)kmalloc(
+			sizeof(struct vme_dma_resource), GFP_KERNEL);
+		if (dma_ctrlr == NULL) {
+			dev_err(&pdev->dev, "Failed to allocate memory for "
+			"dma resource structure\n");
+			retval = -ENOMEM;
+			goto err_dma;
+		}
+		dma_ctrlr->parent = tsi148_bridge;
+		mutex_init(&(dma_ctrlr->mtx));
+		dma_ctrlr->locked = 0;
+		dma_ctrlr->number = i;
+		INIT_LIST_HEAD(&(dma_ctrlr->pending));
+		INIT_LIST_HEAD(&(dma_ctrlr->running));
+		list_add_tail(&(dma_ctrlr->list),
+			&(tsi148_bridge->dma_resources));
+	}
+
+	/* Add location monitor to list */
+	INIT_LIST_HEAD(&(tsi148_bridge->lm_resources));
+	lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL);
+	if (lm == NULL) {
+		dev_err(&pdev->dev, "Failed to allocate memory for "
+		"location monitor resource structure\n");
+		retval = -ENOMEM;
+		goto err_lm;
+	}
+	lm->parent = tsi148_bridge;
+	mutex_init(&(lm->mtx));
+	lm->locked = 0;
+	lm->number = 1;
+	lm->monitors = 4;
+	list_add_tail(&(lm->list), &(tsi148_bridge->lm_resources));
+
+	tsi148_bridge->slave_get = tsi148_slave_get;
+	tsi148_bridge->slave_set = tsi148_slave_set;
+	tsi148_bridge->master_get = tsi148_master_get;
+	tsi148_bridge->master_set = tsi148_master_set;
+	tsi148_bridge->master_read = tsi148_master_read;
+	tsi148_bridge->master_write = tsi148_master_write;
+	tsi148_bridge->master_rmw = tsi148_master_rmw;
+	tsi148_bridge->dma_list_add = tsi148_dma_list_add;
+	tsi148_bridge->dma_list_exec = tsi148_dma_list_exec;
+	tsi148_bridge->dma_list_empty = tsi148_dma_list_empty;
+	tsi148_bridge->request_irq = tsi148_request_irq;
+	tsi148_bridge->free_irq = tsi148_free_irq;
+	tsi148_bridge->generate_irq = tsi148_generate_irq;
+	tsi148_bridge->lm_set = tsi148_lm_set;
+	tsi148_bridge->lm_get = tsi148_lm_get;
+	tsi148_bridge->lm_attach = tsi148_lm_attach;
+	tsi148_bridge->lm_detach = tsi148_lm_detach;
+	tsi148_bridge->slot_get = tsi148_slot_get;
+
+	data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
+	dev_info(&pdev->dev, "Board is%s the VME system controller\n",
+		(data & TSI148_LCSR_VSTAT_SCONS)? "" : " not");
+	dev_info(&pdev->dev, "VME geographical address is %d\n",
+		data & TSI148_LCSR_VSTAT_GA_M);
+	dev_info(&pdev->dev, "VME Write and flush and error check is %s\n",
+		err_chk ? "enabled" : "disabled");
+
+	if(tsi148_crcsr_init(pdev)) {
+		dev_err(&pdev->dev, "CR/CSR configuration failed.\n");
+		goto err_crcsr;
+
+	}
+
+	/* Need to save tsi148_bridge pointer locally in link list for use in
+	 * tsi148_remove()
+	 */
+	retval = vme_register_bridge(tsi148_bridge);
+	if (retval != 0) {
+		dev_err(&pdev->dev, "Chip Registration failed.\n");
+		goto err_reg;
+	}
+
+	/* Clear VME bus "board fail", and "power-up reset" lines */
+	data = ioread32be(tsi148_bridge->base + TSI148_LCSR_VSTAT);
+	data &= ~TSI148_LCSR_VSTAT_BRDFL;
+	data |= TSI148_LCSR_VSTAT_CPURST;
+	iowrite32be(data, tsi148_bridge->base + TSI148_LCSR_VSTAT);
+
+	return 0;
+
+	vme_unregister_bridge(tsi148_bridge);
+err_reg:
+	tsi148_crcsr_exit(pdev);
+err_crcsr:
+err_lm:
+	/* resources are stored in link list */
+	list_for_each(pos, &(tsi148_bridge->lm_resources)) {
+		lm = list_entry(pos, struct vme_lm_resource, list);
+		list_del(pos);
+		kfree(lm);
+	}
+err_dma:
+	/* resources are stored in link list */
+	list_for_each(pos, &(tsi148_bridge->dma_resources)) {
+		dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
+		list_del(pos);
+		kfree(dma_ctrlr);
+	}
+err_slave:
+	/* resources are stored in link list */
+	list_for_each(pos, &(tsi148_bridge->slave_resources)) {
+		slave_image = list_entry(pos, struct vme_slave_resource, list);
+		list_del(pos);
+		kfree(slave_image);
+	}
+err_master:
+	/* resources are stored in link list */
+	list_for_each(pos, &(tsi148_bridge->master_resources)) {
+		master_image = list_entry(pos, struct vme_master_resource,				list);
+		list_del(pos);
+		kfree(master_image);
+	}
+
+	tsi148_irq_exit(pdev);
+err_irq:
+err_test:
+	iounmap(tsi148_bridge->base);
+err_remap:
+	pci_release_regions(pdev);
+err_resource:
+	pci_disable_device(pdev);
+err_enable:
+	kfree(tsi148_bridge);
+err_struct:
+	return retval;
+
+}
+
+static void tsi148_remove(struct pci_dev *pdev)
+{
+	struct list_head *pos = NULL;
+	struct vme_master_resource *master_image;
+	struct vme_slave_resource *slave_image;
+	struct vme_dma_resource *dma_ctrlr;
+	int i;
+
+	dev_dbg(&pdev->dev, "Driver is being unloaded.\n");
+
+	/* XXX We need to find the pdev->dev in the list of vme_bridge->dev's */
+
+	/*
+	 *  Shutdown all inbound and outbound windows.
+	 */
+	for (i = 0; i < 8; i++) {
+		iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_IT[i] +
+			TSI148_LCSR_OFFSET_ITAT);
+		iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_OT[i] +
+			TSI148_LCSR_OFFSET_OTAT);
+	}
+
+	/*
+	 *  Shutdown Location monitor.
+	 */
+	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_LMAT);
+
+	/*
+	 *  Shutdown CRG map.
+	 */
+	iowrite32be(0, tsi148_bridge->base + TSI148_LCSR_CSRAT);
+
+	/*
+	 *  Clear error status.
+	 */
+	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_EDPAT);
+	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_VEAT);
+	iowrite32be(0x07000700, tsi148_bridge->base + TSI148_LCSR_PSTAT);
+
+	/*
+	 *  Remove VIRQ interrupt (if any)
+	 */
+	if (ioread32be(tsi148_bridge->base + TSI148_LCSR_VICR) & 0x800) {
+		iowrite32be(0x8000, tsi148_bridge->base + TSI148_LCSR_VICR);
+	}
+
+	/*
+	 *  Disable and clear all interrupts.
+	 */
+	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTEO);
+	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTC);
+	iowrite32be(0xFFFFFFFF, tsi148_bridge->base + TSI148_LCSR_INTEN);
+
+	/*
+	 *  Map all Interrupts to PCI INTA
+	 */
+	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM1);
+	iowrite32be(0x0, tsi148_bridge->base + TSI148_LCSR_INTM2);
+
+	tsi148_irq_exit(pdev);
+
+	vme_unregister_bridge(tsi148_bridge);
+
+	tsi148_crcsr_exit(pdev);
+
+	/* resources are stored in link list */
+	list_for_each(pos, &(tsi148_bridge->dma_resources)) {
+		dma_ctrlr = list_entry(pos, struct vme_dma_resource, list);
+		list_del(pos);
+		kfree(dma_ctrlr);
+	}
+
+	/* resources are stored in link list */
+	list_for_each(pos, &(tsi148_bridge->slave_resources)) {
+		slave_image = list_entry(pos, struct vme_slave_resource, list);
+		list_del(pos);
+		kfree(slave_image);
+	}
+
+	/* resources are stored in link list */
+	list_for_each(pos, &(tsi148_bridge->master_resources)) {
+		master_image = list_entry(pos, struct vme_master_resource,				list);
+		list_del(pos);
+		kfree(master_image);
+	}
+
+	tsi148_irq_exit(pdev);
+
+	iounmap(tsi148_bridge->base);
+
+	pci_release_regions(pdev);
+
+	pci_disable_device(pdev);
+
+	kfree(tsi148_bridge);
+}
+
+static void __exit tsi148_exit(void)
+{
+	pci_unregister_driver(&tsi148_driver);
+
+	printk(KERN_DEBUG "Driver removed.\n");
+}
+
+MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes");
+module_param(err_chk, bool, 0);
+
+MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge");
+MODULE_LICENSE("GPL");
+
+module_init(tsi148_init);
+module_exit(tsi148_exit);
+
+/*----------------------------------------------------------------------------
+ * STAGING
+ *--------------------------------------------------------------------------*/
+
+#if 0
+/*
+ * Direct Mode DMA transfer
+ *
+ * XXX Not looking at direct mode for now, we can always use link list mode
+ *     with a single entry.
+ */
+int tsi148_dma_run(struct vme_dma_resource *resource, struct vme_dma_attr src,
+	struct vme_dma_attr dest, size_t count)
+{
+	u32 dctlreg = 0;
+	unsigned int tmp;
+	int val;
+	int channel, x;
+	struct vmeDmaPacket *cur_dma;
+	struct tsi148_dma_descriptor *dmaLL;
+
+	/* direct mode */
+	dctlreg = 0x800000;
+
+	for (x = 0; x < 8; x++) {	/* vme block size */
+		if ((32 << x) >= vmeDma->maxVmeBlockSize) {
+			break;
+		}
+	}
+	if (x == 8)
+		x = 7;
+	dctlreg |= (x << 12);
+
+	for (x = 0; x < 8; x++) {	/* pci block size */
+		if ((32 << x) >= vmeDma->maxPciBlockSize) {
+			break;
+		}
+	}
+	if (x == 8)
+		x = 7;
+	dctlreg |= (x << 4);
+
+	if (vmeDma->vmeBackOffTimer) {
+		for (x = 1; x < 8; x++) {	/* vme timer */
+			if ((1 << (x - 1)) >= vmeDma->vmeBackOffTimer) {
+				break;
+			}
+		}
+		if (x == 8)
+			x = 7;
+		dctlreg |= (x << 8);
+	}
+
+	if (vmeDma->pciBackOffTimer) {
+		for (x = 1; x < 8; x++) {	/* pci timer */
+			if ((1 << (x - 1)) >= vmeDma->pciBackOffTimer) {
+				break;
+			}
+		}
+		if (x == 8)
+			x = 7;
+		dctlreg |= (x << 0);
+	}
+
+	/* Program registers for DMA transfer */
+	iowrite32be(dmaLL->dsau, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAU);
+	iowrite32be(dmaLL->dsal, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAL);
+	iowrite32be(dmaLL->ddau, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAU);
+	iowrite32be(dmaLL->ddal, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAL);
+	iowrite32be(dmaLL->dsat, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DSAT);
+	iowrite32be(dmaLL->ddat, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDAT);
+	iowrite32be(dmaLL->dcnt, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCNT);
+	iowrite32be(dmaLL->ddbs, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DDBS);
+
+	/* Start the operation */
+	iowrite32be(dctlreg | 0x2000000, tsi148_bridge->base +
+		TSI148_LCSR_DMA[channel] + TSI148_LCSR_OFFSET_DCTL);
+
+	tmp = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+		TSI148_LCSR_OFFSET_DSTA);
+	wait_event_interruptible(dma_queue[channel], (tmp & 0x1000000) == 0);
+
+	/*
+	 * Read status register, we should probably do this in some error
+	 * handler rather than here so that we can be sure we haven't kicked off
+	 * another DMA transfer.
+	 */
+	val = ioread32be(tsi148_bridge->base + TSI148_LCSR_DMA[channel] +
+		TSI148_LCSR_OFFSET_DSTA);
+
+	vmeDma->vmeDmaStatus = 0;
+	if (val & 0x10000000) {
+		printk(KERN_ERR
+			"DMA Error in DMA_tempe_irqhandler DSTA=%08X\n",
+			val);
+		vmeDma->vmeDmaStatus = val;
+
+	}
+	return (0);
+}
+#endif
+
+#if 0
+
+/* Global VME controller information */
+struct pci_dev *vme_pci_dev;
+
+/*
+ * Set the VME bus arbiter with the requested attributes
+ */
+int tempe_set_arbiter(vmeArbiterCfg_t * vmeArb)
+{
+	int temp_ctl = 0;
+	int gto = 0;
+
+	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
+	temp_ctl &= 0xFFEFFF00;
+
+	if (vmeArb->globalTimeoutTimer == 0xFFFFFFFF) {
+		gto = 8;
+	} else if (vmeArb->globalTimeoutTimer > 2048) {
+		return (-EINVAL);
+	} else if (vmeArb->globalTimeoutTimer == 0) {
+		gto = 0;
+	} else {
+		gto = 1;
+		while ((16 * (1 << (gto - 1))) < vmeArb->globalTimeoutTimer) {
+			gto += 1;
+		}
+	}
+	temp_ctl |= gto;
+
+	if (vmeArb->arbiterMode != VME_PRIORITY_MODE) {
+		temp_ctl |= 1 << 6;
+	}
+
+	if (vmeArb->arbiterTimeoutFlag) {
+		temp_ctl |= 1 << 7;
+	}
+
+	if (vmeArb->noEarlyReleaseFlag) {
+		temp_ctl |= 1 << 20;
+	}
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VCTRL);
+
+	return (0);
+}
+
+/*
+ * Return the attributes of the VME bus arbiter.
+ */
+int tempe_get_arbiter(vmeArbiterCfg_t * vmeArb)
+{
+	int temp_ctl = 0;
+	int gto = 0;
+
+
+	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VCTRL);
+
+	gto = temp_ctl & 0xF;
+	if (gto != 0) {
+		vmeArb->globalTimeoutTimer = (16 * (1 << (gto - 1)));
+	}
+
+	if (temp_ctl & (1 << 6)) {
+		vmeArb->arbiterMode = VME_R_ROBIN_MODE;
+	} else {
+		vmeArb->arbiterMode = VME_PRIORITY_MODE;
+	}
+
+	if (temp_ctl & (1 << 7)) {
+		vmeArb->arbiterTimeoutFlag = 1;
+	}
+
+	if (temp_ctl & (1 << 20)) {
+		vmeArb->noEarlyReleaseFlag = 1;
+	}
+
+	return (0);
+}
+
+/*
+ * Set the VME bus requestor with the requested attributes
+ */
+int tempe_set_requestor(vmeRequesterCfg_t * vmeReq)
+{
+	int temp_ctl = 0;
+
+	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	temp_ctl &= 0xFFFF0000;
+
+	if (vmeReq->releaseMode == 1) {
+		temp_ctl |= (1 << 3);
+	}
+
+	if (vmeReq->fairMode == 1) {
+		temp_ctl |= (1 << 2);
+	}
+
+	temp_ctl |= (vmeReq->timeonTimeoutTimer & 7) << 8;
+	temp_ctl |= (vmeReq->timeoffTimeoutTimer & 7) << 12;
+	temp_ctl |= vmeReq->requestLevel;
+
+	iowrite32be(temp_ctl, tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+	return (0);
+}
+
+/*
+ * Return the attributes of the VME bus requestor
+ */
+int tempe_get_requestor(vmeRequesterCfg_t * vmeReq)
+{
+	int temp_ctl = 0;
+
+	temp_ctl = ioread32be(tsi148_bridge->base + TSI148_LCSR_VMCTRL);
+
+	if (temp_ctl & 0x18) {
+		vmeReq->releaseMode = 1;
+	}
+
+	if (temp_ctl & (1 << 2)) {
+		vmeReq->fairMode = 1;
+	}
+
+	vmeReq->requestLevel = temp_ctl & 3;
+	vmeReq->timeonTimeoutTimer = (temp_ctl >> 8) & 7;
+	vmeReq->timeoffTimeoutTimer = (temp_ctl >> 12) & 7;
+
+	return (0);
+}
+
+
+#endif
diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h
new file mode 100644
index 0000000..6f0f705
--- /dev/null
+++ b/drivers/staging/vme/bridges/vme_tsi148.h
@@ -0,0 +1,1387 @@
+/*
+ * tsi148.h
+ *
+ * Support for the Tundra TSI148 VME Bridge chip
+ *
+ * Author: Tom Armistead
+ * Updated and maintained by Ajit Prem
+ * Copyright 2004 Motorola 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.
+ */
+
+#ifndef TSI148_H
+#define TSI148_H
+
+#ifndef	PCI_VENDOR_ID_TUNDRA
+#define	PCI_VENDOR_ID_TUNDRA 0x10e3
+#endif
+
+#ifndef	PCI_DEVICE_ID_TUNDRA_TSI148
+#define	PCI_DEVICE_ID_TUNDRA_TSI148 0x148
+#endif
+
+/*
+ *  Define the number of each that the Tsi148 supports.
+ */
+#define TSI148_MAX_MASTER		8	/* Max Master Windows */
+#define TSI148_MAX_SLAVE		8	/* Max Slave Windows */
+#define TSI148_MAX_DMA			2	/* Max DMA Controllers */
+#define TSI148_MAX_MAILBOX		4	/* Max Mail Box registers */
+#define TSI148_MAX_SEMAPHORE		8	/* Max Semaphores */
+
+/*
+ * Layout of a DMAC Linked-List Descriptor
+ *
+ * Note: This structure is accessed via the chip and therefore must be
+ *       correctly laid out - It must also be aligned on 64-bit boundaries.
+ */
+struct tsi148_dma_descriptor {
+	u32 dsau;      /* Source Address */
+	u32 dsal;
+	u32 ddau;      /* Destination Address */
+	u32 ddal;
+	u32 dsat;      /* Source attributes */
+	u32 ddat;      /* Destination attributes */
+	u32 dnlau;     /* Next link address */
+	u32 dnlal;
+	u32 dcnt;      /* Byte count */
+	u32 ddbs;      /* 2eSST Broadcast select */
+};
+
+struct tsi148_dma_entry {
+	/*
+	 * The descriptor needs to be aligned on a 64-bit boundary, we increase
+	 * the chance of this by putting it first in the structure.
+	 */
+	struct tsi148_dma_descriptor descriptor;
+	struct list_head list;
+};
+
+/*
+ *  TSI148 ASIC register structure overlays and bit field definitions.
+ *
+ *      Note:   Tsi148 Register Group (CRG) consists of the following
+ *              combination of registers:
+ *                      PCFS    - PCI Configuration Space Registers
+ *                      LCSR    - Local Control and Status Registers
+ *                      GCSR    - Global Control and Status Registers
+ *                      CR/CSR  - Subset of Configuration ROM /
+ *                                Control and Status Registers
+ */
+
+
+/*
+ *  Command/Status Registers (CRG + $004)
+ */
+#define TSI148_PCFS_ID			0x0
+#define TSI148_PCFS_CSR			0x4
+#define TSI148_PCFS_CLASS		0x8
+#define TSI148_PCFS_MISC0		0xC
+#define TSI148_PCFS_MBARL		0x10
+#define TSI148_PCFS_MBARU		0x14
+
+#define TSI148_PCFS_SUBID		0x28
+
+#define TSI148_PCFS_CAPP		0x34
+
+#define TSI148_PCFS_MISC1		0x3C
+
+#define TSI148_PCFS_XCAPP		0x40
+#define TSI148_PCFS_XSTAT		0x44
+
+/*
+ * LCSR definitions
+ */
+
+/*
+ *    Outbound Translations
+ */
+#define TSI148_LCSR_OT0_OTSAU		0x100
+#define TSI148_LCSR_OT0_OTSAL		0x104
+#define TSI148_LCSR_OT0_OTEAU		0x108
+#define TSI148_LCSR_OT0_OTEAL		0x10C
+#define TSI148_LCSR_OT0_OTOFU		0x110
+#define TSI148_LCSR_OT0_OTOFL		0x114
+#define TSI148_LCSR_OT0_OTBS		0x118
+#define TSI148_LCSR_OT0_OTAT		0x11C
+
+#define TSI148_LCSR_OT1_OTSAU		0x120
+#define TSI148_LCSR_OT1_OTSAL		0x124
+#define TSI148_LCSR_OT1_OTEAU		0x128
+#define TSI148_LCSR_OT1_OTEAL		0x12C
+#define TSI148_LCSR_OT1_OTOFU		0x130
+#define TSI148_LCSR_OT1_OTOFL		0x134
+#define TSI148_LCSR_OT1_OTBS		0x138
+#define TSI148_LCSR_OT1_OTAT		0x13C
+
+#define TSI148_LCSR_OT2_OTSAU		0x140
+#define TSI148_LCSR_OT2_OTSAL		0x144
+#define TSI148_LCSR_OT2_OTEAU		0x148
+#define TSI148_LCSR_OT2_OTEAL		0x14C
+#define TSI148_LCSR_OT2_OTOFU		0x150
+#define TSI148_LCSR_OT2_OTOFL		0x154
+#define TSI148_LCSR_OT2_OTBS		0x158
+#define TSI148_LCSR_OT2_OTAT		0x15C
+
+#define TSI148_LCSR_OT3_OTSAU		0x160
+#define TSI148_LCSR_OT3_OTSAL		0x164
+#define TSI148_LCSR_OT3_OTEAU		0x168
+#define TSI148_LCSR_OT3_OTEAL		0x16C
+#define TSI148_LCSR_OT3_OTOFU		0x170
+#define TSI148_LCSR_OT3_OTOFL		0x174
+#define TSI148_LCSR_OT3_OTBS		0x178
+#define TSI148_LCSR_OT3_OTAT		0x17C
+
+#define TSI148_LCSR_OT4_OTSAU		0x180
+#define TSI148_LCSR_OT4_OTSAL		0x184
+#define TSI148_LCSR_OT4_OTEAU		0x188
+#define TSI148_LCSR_OT4_OTEAL		0x18C
+#define TSI148_LCSR_OT4_OTOFU		0x190
+#define TSI148_LCSR_OT4_OTOFL		0x194
+#define TSI148_LCSR_OT4_OTBS		0x198
+#define TSI148_LCSR_OT4_OTAT		0x19C
+
+#define TSI148_LCSR_OT5_OTSAU		0x1A0
+#define TSI148_LCSR_OT5_OTSAL		0x1A4
+#define TSI148_LCSR_OT5_OTEAU		0x1A8
+#define TSI148_LCSR_OT5_OTEAL		0x1AC
+#define TSI148_LCSR_OT5_OTOFU		0x1B0
+#define TSI148_LCSR_OT5_OTOFL		0x1B4
+#define TSI148_LCSR_OT5_OTBS		0x1B8
+#define TSI148_LCSR_OT5_OTAT		0x1BC
+
+#define TSI148_LCSR_OT6_OTSAU		0x1C0
+#define TSI148_LCSR_OT6_OTSAL		0x1C4
+#define TSI148_LCSR_OT6_OTEAU		0x1C8
+#define TSI148_LCSR_OT6_OTEAL		0x1CC
+#define TSI148_LCSR_OT6_OTOFU		0x1D0
+#define TSI148_LCSR_OT6_OTOFL		0x1D4
+#define TSI148_LCSR_OT6_OTBS		0x1D8
+#define TSI148_LCSR_OT6_OTAT		0x1DC
+
+#define TSI148_LCSR_OT7_OTSAU		0x1E0
+#define TSI148_LCSR_OT7_OTSAL		0x1E4
+#define TSI148_LCSR_OT7_OTEAU		0x1E8
+#define TSI148_LCSR_OT7_OTEAL		0x1EC
+#define TSI148_LCSR_OT7_OTOFU		0x1F0
+#define TSI148_LCSR_OT7_OTOFL		0x1F4
+#define TSI148_LCSR_OT7_OTBS		0x1F8
+#define TSI148_LCSR_OT7_OTAT		0x1FC
+
+#define TSI148_LCSR_OT0		0x100
+#define TSI148_LCSR_OT1		0x120
+#define TSI148_LCSR_OT2		0x140
+#define TSI148_LCSR_OT3		0x160
+#define TSI148_LCSR_OT4		0x180
+#define TSI148_LCSR_OT5		0x1A0
+#define TSI148_LCSR_OT6		0x1C0
+#define TSI148_LCSR_OT7		0x1E0
+
+static const int TSI148_LCSR_OT[8] = { TSI148_LCSR_OT0, TSI148_LCSR_OT1,
+					 TSI148_LCSR_OT2, TSI148_LCSR_OT3,
+					 TSI148_LCSR_OT4, TSI148_LCSR_OT5,
+					 TSI148_LCSR_OT6, TSI148_LCSR_OT7 };
+
+#define TSI148_LCSR_OFFSET_OTSAU	0x0
+#define TSI148_LCSR_OFFSET_OTSAL	0x4
+#define TSI148_LCSR_OFFSET_OTEAU	0x8
+#define TSI148_LCSR_OFFSET_OTEAL	0xC
+#define TSI148_LCSR_OFFSET_OTOFU	0x10
+#define TSI148_LCSR_OFFSET_OTOFL	0x14
+#define TSI148_LCSR_OFFSET_OTBS		0x18
+#define TSI148_LCSR_OFFSET_OTAT		0x1C
+
+/*
+ * VMEbus interupt ack
+ * offset  200
+ */
+#define TSI148_LCSR_VIACK1	0x204
+#define TSI148_LCSR_VIACK2	0x208
+#define TSI148_LCSR_VIACK3	0x20C
+#define TSI148_LCSR_VIACK4	0x210
+#define TSI148_LCSR_VIACK5	0x214
+#define TSI148_LCSR_VIACK6	0x218
+#define TSI148_LCSR_VIACK7	0x21C
+
+static const int TSI148_LCSR_VIACK[8] = { 0, TSI148_LCSR_VIACK1,
+				TSI148_LCSR_VIACK2, TSI148_LCSR_VIACK3,
+				TSI148_LCSR_VIACK4, TSI148_LCSR_VIACK5,
+				TSI148_LCSR_VIACK6, TSI148_LCSR_VIACK7 };
+
+/*
+ * RMW
+ * offset    220
+ */
+#define TSI148_LCSR_RMWAU	0x220
+#define TSI148_LCSR_RMWAL	0x224
+#define TSI148_LCSR_RMWEN	0x228
+#define TSI148_LCSR_RMWC	0x22C
+#define TSI148_LCSR_RMWS	0x230
+
+/*
+ * VMEbus control
+ * offset    234
+ */
+#define TSI148_LCSR_VMCTRL	0x234
+#define TSI148_LCSR_VCTRL	0x238
+#define TSI148_LCSR_VSTAT	0x23C
+
+/*
+ * PCI status
+ * offset  240
+ */
+#define TSI148_LCSR_PSTAT	0x240
+
+/*
+ * VME filter.
+ * offset  250
+ */
+#define TSI148_LCSR_VMEFL	0x250
+
+	/*
+	 * VME exception.
+	 * offset  260
+ */
+#define TSI148_LCSR_VEAU	0x260
+#define TSI148_LCSR_VEAL	0x264
+#define TSI148_LCSR_VEAT	0x268
+
+	/*
+	 * PCI error
+	 * offset  270
+	 */
+#define TSI148_LCSR_EDPAU	0x270
+#define TSI148_LCSR_EDPAL	0x274
+#define TSI148_LCSR_EDPXA	0x278
+#define TSI148_LCSR_EDPXS	0x27C
+#define TSI148_LCSR_EDPAT	0x280
+
+	/*
+	 * Inbound Translations
+	 * offset  300
+	 */
+#define TSI148_LCSR_IT0_ITSAU		0x300
+#define TSI148_LCSR_IT0_ITSAL		0x304
+#define TSI148_LCSR_IT0_ITEAU		0x308
+#define TSI148_LCSR_IT0_ITEAL		0x30C
+#define TSI148_LCSR_IT0_ITOFU		0x310
+#define TSI148_LCSR_IT0_ITOFL		0x314
+#define TSI148_LCSR_IT0_ITAT		0x318
+
+#define TSI148_LCSR_IT1_ITSAU		0x320
+#define TSI148_LCSR_IT1_ITSAL		0x324
+#define TSI148_LCSR_IT1_ITEAU		0x328
+#define TSI148_LCSR_IT1_ITEAL		0x32C
+#define TSI148_LCSR_IT1_ITOFU		0x330
+#define TSI148_LCSR_IT1_ITOFL		0x334
+#define TSI148_LCSR_IT1_ITAT		0x338
+
+#define TSI148_LCSR_IT2_ITSAU		0x340
+#define TSI148_LCSR_IT2_ITSAL		0x344
+#define TSI148_LCSR_IT2_ITEAU		0x348
+#define TSI148_LCSR_IT2_ITEAL		0x34C
+#define TSI148_LCSR_IT2_ITOFU		0x350
+#define TSI148_LCSR_IT2_ITOFL		0x354
+#define TSI148_LCSR_IT2_ITAT		0x358
+
+#define TSI148_LCSR_IT3_ITSAU		0x360
+#define TSI148_LCSR_IT3_ITSAL		0x364
+#define TSI148_LCSR_IT3_ITEAU		0x368
+#define TSI148_LCSR_IT3_ITEAL		0x36C
+#define TSI148_LCSR_IT3_ITOFU		0x370
+#define TSI148_LCSR_IT3_ITOFL		0x374
+#define TSI148_LCSR_IT3_ITAT		0x378
+
+#define TSI148_LCSR_IT4_ITSAU		0x380
+#define TSI148_LCSR_IT4_ITSAL		0x384
+#define TSI148_LCSR_IT4_ITEAU		0x388
+#define TSI148_LCSR_IT4_ITEAL		0x38C
+#define TSI148_LCSR_IT4_ITOFU		0x390
+#define TSI148_LCSR_IT4_ITOFL		0x394
+#define TSI148_LCSR_IT4_ITAT		0x398
+
+#define TSI148_LCSR_IT5_ITSAU		0x3A0
+#define TSI148_LCSR_IT5_ITSAL		0x3A4
+#define TSI148_LCSR_IT5_ITEAU		0x3A8
+#define TSI148_LCSR_IT5_ITEAL		0x3AC
+#define TSI148_LCSR_IT5_ITOFU		0x3B0
+#define TSI148_LCSR_IT5_ITOFL		0x3B4
+#define TSI148_LCSR_IT5_ITAT		0x3B8
+
+#define TSI148_LCSR_IT6_ITSAU		0x3C0
+#define TSI148_LCSR_IT6_ITSAL		0x3C4
+#define TSI148_LCSR_IT6_ITEAU		0x3C8
+#define TSI148_LCSR_IT6_ITEAL		0x3CC
+#define TSI148_LCSR_IT6_ITOFU		0x3D0
+#define TSI148_LCSR_IT6_ITOFL		0x3D4
+#define TSI148_LCSR_IT6_ITAT		0x3D8
+
+#define TSI148_LCSR_IT7_ITSAU		0x3E0
+#define TSI148_LCSR_IT7_ITSAL		0x3E4
+#define TSI148_LCSR_IT7_ITEAU		0x3E8
+#define TSI148_LCSR_IT7_ITEAL		0x3EC
+#define TSI148_LCSR_IT7_ITOFU		0x3F0
+#define TSI148_LCSR_IT7_ITOFL		0x3F4
+#define TSI148_LCSR_IT7_ITAT		0x3F8
+
+
+#define TSI148_LCSR_IT0		0x300
+#define TSI148_LCSR_IT1		0x320
+#define TSI148_LCSR_IT2		0x340
+#define TSI148_LCSR_IT3		0x360
+#define TSI148_LCSR_IT4		0x380
+#define TSI148_LCSR_IT5		0x3A0
+#define TSI148_LCSR_IT6		0x3C0
+#define TSI148_LCSR_IT7		0x3E0
+
+static const int TSI148_LCSR_IT[8] = { TSI148_LCSR_IT0, TSI148_LCSR_IT1,
+					 TSI148_LCSR_IT2, TSI148_LCSR_IT3,
+					 TSI148_LCSR_IT4, TSI148_LCSR_IT5,
+					 TSI148_LCSR_IT6, TSI148_LCSR_IT7 };
+
+#define TSI148_LCSR_OFFSET_ITSAU	0x0
+#define TSI148_LCSR_OFFSET_ITSAL	0x4
+#define TSI148_LCSR_OFFSET_ITEAU	0x8
+#define TSI148_LCSR_OFFSET_ITEAL	0xC
+#define TSI148_LCSR_OFFSET_ITOFU	0x10
+#define TSI148_LCSR_OFFSET_ITOFL	0x14
+#define TSI148_LCSR_OFFSET_ITAT		0x18
+
+	/*
+	 * Inbound Translation GCSR
+	 * offset  400
+	 */
+#define TSI148_LCSR_GBAU	0x400
+#define TSI148_LCSR_GBAL	0x404
+#define TSI148_LCSR_GCSRAT	0x408
+
+	/*
+	 * Inbound Translation CRG
+	 * offset  40C
+	 */
+#define TSI148_LCSR_CBAU	0x40C
+#define TSI148_LCSR_CBAL	0x410
+#define TSI148_LCSR_CSRAT	0x414
+
+	/*
+	 * Inbound Translation CR/CSR
+	 *         CRG
+	 * offset  418
+	 */
+#define TSI148_LCSR_CROU	0x418
+#define TSI148_LCSR_CROL	0x41C
+#define TSI148_LCSR_CRAT	0x420
+
+	/*
+	 * Inbound Translation Location Monitor
+	 * offset  424
+	 */
+#define TSI148_LCSR_LMBAU	0x424
+#define TSI148_LCSR_LMBAL	0x428
+#define TSI148_LCSR_LMAT	0x42C
+
+	/*
+	 * VMEbus Interrupt Control.
+	 * offset  430
+	 */
+#define TSI148_LCSR_BCU		0x430
+#define TSI148_LCSR_BCL		0x434
+#define TSI148_LCSR_BPGTR	0x438
+#define TSI148_LCSR_BPCTR	0x43C
+#define TSI148_LCSR_VICR	0x440
+
+	/*
+	 * Local Bus Interrupt Control.
+	 * offset  448
+	 */
+#define TSI148_LCSR_INTEN	0x448
+#define TSI148_LCSR_INTEO	0x44C
+#define TSI148_LCSR_INTS	0x450
+#define TSI148_LCSR_INTC	0x454
+#define TSI148_LCSR_INTM1	0x458
+#define TSI148_LCSR_INTM2	0x45C
+
+	/*
+	 * DMA Controllers
+	 * offset 500
+	 */
+#define TSI148_LCSR_DCTL0	0x500
+#define TSI148_LCSR_DSTA0	0x504
+#define TSI148_LCSR_DCSAU0	0x508
+#define TSI148_LCSR_DCSAL0	0x50C
+#define TSI148_LCSR_DCDAU0	0x510
+#define TSI148_LCSR_DCDAL0	0x514
+#define TSI148_LCSR_DCLAU0	0x518
+#define TSI148_LCSR_DCLAL0	0x51C
+#define TSI148_LCSR_DSAU0	0x520
+#define TSI148_LCSR_DSAL0	0x524
+#define TSI148_LCSR_DDAU0	0x528
+#define TSI148_LCSR_DDAL0	0x52C
+#define TSI148_LCSR_DSAT0	0x530
+#define TSI148_LCSR_DDAT0	0x534
+#define TSI148_LCSR_DNLAU0	0x538
+#define TSI148_LCSR_DNLAL0	0x53C
+#define TSI148_LCSR_DCNT0	0x540
+#define TSI148_LCSR_DDBS0	0x544
+
+#define TSI148_LCSR_DCTL1	0x580
+#define TSI148_LCSR_DSTA1	0x584
+#define TSI148_LCSR_DCSAU1	0x588
+#define TSI148_LCSR_DCSAL1	0x58C
+#define TSI148_LCSR_DCDAU1	0x590
+#define TSI148_LCSR_DCDAL1	0x594
+#define TSI148_LCSR_DCLAU1	0x598
+#define TSI148_LCSR_DCLAL1	0x59C
+#define TSI148_LCSR_DSAU1	0x5A0
+#define TSI148_LCSR_DSAL1	0x5A4
+#define TSI148_LCSR_DDAU1	0x5A8
+#define TSI148_LCSR_DDAL1	0x5AC
+#define TSI148_LCSR_DSAT1	0x5B0
+#define TSI148_LCSR_DDAT1	0x5B4
+#define TSI148_LCSR_DNLAU1	0x5B8
+#define TSI148_LCSR_DNLAL1	0x5BC
+#define TSI148_LCSR_DCNT1	0x5C0
+#define TSI148_LCSR_DDBS1	0x5C4
+
+#define TSI148_LCSR_DMA0	0x500
+#define TSI148_LCSR_DMA1	0x580
+
+
+static const int TSI148_LCSR_DMA[TSI148_MAX_DMA] = { TSI148_LCSR_DMA0,
+						TSI148_LCSR_DMA1 };
+
+#define TSI148_LCSR_OFFSET_DCTL		0x0
+#define TSI148_LCSR_OFFSET_DSTA		0x4
+#define TSI148_LCSR_OFFSET_DCSAU	0x8
+#define TSI148_LCSR_OFFSET_DCSAL	0xC
+#define TSI148_LCSR_OFFSET_DCDAU	0x10
+#define TSI148_LCSR_OFFSET_DCDAL	0x14
+#define TSI148_LCSR_OFFSET_DCLAU	0x18
+#define TSI148_LCSR_OFFSET_DCLAL	0x1C
+#define TSI148_LCSR_OFFSET_DSAU		0x20
+#define TSI148_LCSR_OFFSET_DSAL		0x24
+#define TSI148_LCSR_OFFSET_DDAU		0x28
+#define TSI148_LCSR_OFFSET_DDAL		0x2C
+#define TSI148_LCSR_OFFSET_DSAT		0x30
+#define TSI148_LCSR_OFFSET_DDAT		0x34
+#define TSI148_LCSR_OFFSET_DNLAU	0x38
+#define TSI148_LCSR_OFFSET_DNLAL	0x3C
+#define TSI148_LCSR_OFFSET_DCNT		0x40
+#define TSI148_LCSR_OFFSET_DDBS		0x44
+
+	/*
+	 * GCSR Register Group
+	 */
+
+	/*
+	 *         GCSR    CRG
+	 * offset   00     600 - DEVI/VENI
+	 * offset   04     604 - CTRL/GA/REVID
+	 * offset   08     608 - Semaphore3/2/1/0
+	 * offset   0C     60C - Seamphore7/6/5/4
+	 */
+#define TSI148_GCSR_ID		0x600
+#define TSI148_GCSR_CSR		0x604
+#define TSI148_GCSR_SEMA0	0x608
+#define TSI148_GCSR_SEMA1	0x60C
+
+	/*
+	 * Mail Box
+	 *         GCSR    CRG
+	 * offset   10     610 - Mailbox0
+	 */
+#define TSI148_GCSR_MBOX0	0x610
+#define TSI148_GCSR_MBOX1	0x614
+#define TSI148_GCSR_MBOX2	0x618
+#define TSI148_GCSR_MBOX3	0x61C
+
+static const int TSI148_GCSR_MBOX[4] = { TSI148_GCSR_MBOX0,
+					TSI148_GCSR_MBOX1,
+					TSI148_GCSR_MBOX2,
+					TSI148_GCSR_MBOX3 };
+
+	/*
+	 * CR/CSR
+	 */
+
+	/*
+	 *        CR/CSR   CRG
+	 * offset  7FFF4   FF4 - CSRBCR
+	 * offset  7FFF8   FF8 - CSRBSR
+	 * offset  7FFFC   FFC - CBAR
+	 */
+#define TSI148_CSRBCR	0xFF4
+#define TSI148_CSRBSR	0xFF8
+#define TSI148_CBAR	0xFFC
+
+
+
+
+	/*
+	 *  TSI148 Register Bit Definitions
+	 */
+
+	/*
+	 *  PFCS Register Set
+	 */
+#define TSI148_PCFS_CMMD_SERR          (1<<8)	/* SERR_L out pin ssys err */
+#define TSI148_PCFS_CMMD_PERR          (1<<6)	/* PERR_L out pin  parity */
+#define TSI148_PCFS_CMMD_MSTR          (1<<2)	/* PCI bus master */
+#define TSI148_PCFS_CMMD_MEMSP         (1<<1)	/* PCI mem space access  */
+#define TSI148_PCFS_CMMD_IOSP          (1<<0)	/* PCI I/O space enable */
+
+#define TSI148_PCFS_STAT_RCPVE         (1<<15)	/* Detected Parity Error */
+#define TSI148_PCFS_STAT_SIGSE         (1<<14)	/* Signalled System Error */
+#define TSI148_PCFS_STAT_RCVMA         (1<<13)	/* Received Master Abort */
+#define TSI148_PCFS_STAT_RCVTA         (1<<12)	/* Received Target Abort */
+#define TSI148_PCFS_STAT_SIGTA         (1<<11)	/* Signalled Target Abort */
+#define TSI148_PCFS_STAT_SELTIM        (3<<9)	/* DELSEL Timing */
+#define TSI148_PCFS_STAT_DPAR          (1<<8)	/* Data Parity Err Reported */
+#define TSI148_PCFS_STAT_FAST          (1<<7)	/* Fast back-to-back Cap */
+#define TSI148_PCFS_STAT_P66M          (1<<5)	/* 66 MHz Capable */
+#define TSI148_PCFS_STAT_CAPL          (1<<4)	/* Capab List - address $34 */
+
+/*
+ *  Revision ID/Class Code Registers   (CRG +$008)
+ */
+#define TSI148_PCFS_CLAS_M             (0xFF<<24)	/* Class ID */
+#define TSI148_PCFS_SUBCLAS_M          (0xFF<<16)	/* Sub-Class ID */
+#define TSI148_PCFS_PROGIF_M           (0xFF<<8)	/* Sub-Class ID */
+#define TSI148_PCFS_REVID_M            (0xFF<<0)	/* Rev ID */
+
+/*
+ * Cache Line Size/ Master Latency Timer/ Header Type Registers (CRG + $00C)
+ */
+#define TSI148_PCFS_HEAD_M             (0xFF<<16)	/* Master Lat Timer */
+#define TSI148_PCFS_MLAT_M             (0xFF<<8)	/* Master Lat Timer */
+#define TSI148_PCFS_CLSZ_M             (0xFF<<0)	/* Cache Line Size */
+
+/*
+ *  Memory Base Address Lower Reg (CRG + $010)
+ */
+#define TSI148_PCFS_MBARL_BASEL_M      (0xFFFFF<<12)	/* Base Addr Lower Mask */
+#define TSI148_PCFS_MBARL_PRE          (1<<3)	/* Prefetch */
+#define TSI148_PCFS_MBARL_MTYPE_M      (3<<1)	/* Memory Type Mask */
+#define TSI148_PCFS_MBARL_IOMEM        (1<<0)	/* I/O Space Indicator */
+
+/*
+ *  Message Signaled Interrupt Capabilities Register (CRG + $040)
+ */
+#define TSI148_PCFS_MSICAP_64BAC       (1<<7)	/* 64-bit Address Capable */
+#define TSI148_PCFS_MSICAP_MME_M       (7<<4)	/* Multiple Msg Enable Mask */
+#define TSI148_PCFS_MSICAP_MMC_M       (7<<1)	/* Multiple Msg Capable Mask */
+#define TSI148_PCFS_MSICAP_MSIEN       (1<<0)	/* Msg signaled INT Enable */
+
+/*
+ *  Message Address Lower Register (CRG +$044)
+ */
+#define TSI148_PCFS_MSIAL_M            (0x3FFFFFFF<<2)	/* Mask */
+
+/*
+ *  Message Data Register (CRG + 4C)
+ */
+#define TSI148_PCFS_MSIMD_M            (0xFFFF<<0)	/* Mask */
+
+/*
+ *  PCI-X Capabilities Register (CRG + $050)
+ */
+#define TSI148_PCFS_PCIXCAP_MOST_M     (7<<4)	/* Max outstanding Split Tran */
+#define TSI148_PCFS_PCIXCAP_MMRBC_M    (3<<2)	/* Max Mem Read byte cnt */
+#define TSI148_PCFS_PCIXCAP_ERO        (1<<1)	/* Enable Relaxed Ordering */
+#define TSI148_PCFS_PCIXCAP_DPERE      (1<<0)	/* Data Parity Recover Enable */
+
+/*
+ *  PCI-X Status Register (CRG +$054)
+ */
+#define TSI148_PCFS_PCIXSTAT_RSCEM     (1<<29)	/* Recieved Split Comp Error */
+#define TSI148_PCFS_PCIXSTAT_DMCRS_M   (7<<26)	/* max Cumulative Read Size */
+#define TSI148_PCFS_PCIXSTAT_DMOST_M   (7<<23)	/* max outstanding Split Trans */
+#define TSI148_PCFS_PCIXSTAT_DMMRC_M   (3<<21)	/* max mem read byte count */
+#define TSI148_PCFS_PCIXSTAT_DC        (1<<20)	/* Device Complexity */
+#define TSI148_PCFS_PCIXSTAT_USC       (1<<19)	/* Unexpected Split comp */
+#define TSI148_PCFS_PCIXSTAT_SCD       (1<<18)	/* Split completion discard */
+#define TSI148_PCFS_PCIXSTAT_133C      (1<<17)	/* 133MHz capable */
+#define TSI148_PCFS_PCIXSTAT_64D       (1<<16)	/* 64 bit device */
+#define TSI148_PCFS_PCIXSTAT_BN_M      (0xFF<<8)	/* Bus number */
+#define TSI148_PCFS_PCIXSTAT_DN_M      (0x1F<<3)	/* Device number */
+#define TSI148_PCFS_PCIXSTAT_FN_M      (7<<0)	/* Function Number */
+
+/*
+ *  LCSR Registers
+ */
+
+/*
+ *  Outbound Translation Starting Address Lower
+ */
+#define TSI148_LCSR_OTSAL_M            (0xFFFF<<16)	/* Mask */
+
+/*
+ *  Outbound Translation Ending Address Lower
+ */
+#define TSI148_LCSR_OTEAL_M            (0xFFFF<<16)	/* Mask */
+
+/*
+ *  Outbound Translation Offset Lower
+ */
+#define TSI148_LCSR_OTOFFL_M           (0xFFFF<<16)	/* Mask */
+
+/*
+ *  Outbound Translation 2eSST Broadcast Select
+ */
+#define TSI148_LCSR_OTBS_M             (0xFFFFF<<0)	/* Mask */
+
+/*
+ *  Outbound Translation Attribute
+ */
+#define TSI148_LCSR_OTAT_EN            (1<<31)	/* Window Enable */
+#define TSI148_LCSR_OTAT_MRPFD         (1<<18)	/* Prefetch Disable */
+
+#define TSI148_LCSR_OTAT_PFS_M         (3<<16)	/* Prefetch Size Mask */
+#define TSI148_LCSR_OTAT_PFS_2         (0<<16)	/* 2 Cache Lines P Size */
+#define TSI148_LCSR_OTAT_PFS_4         (1<<16)	/* 4 Cache Lines P Size */
+#define TSI148_LCSR_OTAT_PFS_8         (2<<16)	/* 8 Cache Lines P Size */
+#define TSI148_LCSR_OTAT_PFS_16        (3<<16)	/* 16 Cache Lines P Size */
+
+#define TSI148_LCSR_OTAT_2eSSTM_M      (7<<11)	/* 2eSST Xfer Rate Mask */
+#define TSI148_LCSR_OTAT_2eSSTM_160    (0<<11)	/* 160MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_OTAT_2eSSTM_267    (1<<11)	/* 267MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_OTAT_2eSSTM_320    (2<<11)	/* 320MB/s 2eSST Xfer Rate */
+
+#define TSI148_LCSR_OTAT_TM_M          (7<<8)	/* Xfer Protocol Mask */
+#define TSI148_LCSR_OTAT_TM_SCT        (0<<8)	/* SCT Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_BLT        (1<<8)	/* BLT Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_MBLT       (2<<8)	/* MBLT Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_2eVME      (3<<8)	/* 2eVME Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_2eSST      (4<<8)	/* 2eSST Xfer Protocol */
+#define TSI148_LCSR_OTAT_TM_2eSSTB     (5<<8)	/* 2eSST Bcast Xfer Protocol */
+
+#define TSI148_LCSR_OTAT_DBW_M         (3<<6)	/* Max Data Width */
+#define TSI148_LCSR_OTAT_DBW_16        (0<<6)	/* 16-bit Data Width */
+#define TSI148_LCSR_OTAT_DBW_32        (1<<6)	/* 32-bit Data Width */
+
+#define TSI148_LCSR_OTAT_SUP           (1<<5)	/* Supervisory Access */
+#define TSI148_LCSR_OTAT_PGM           (1<<4)	/* Program Access */
+
+#define TSI148_LCSR_OTAT_AMODE_M       (0xf<<0)	/* Address Mode Mask */
+#define TSI148_LCSR_OTAT_AMODE_A16     (0<<0)	/* A16 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_A24     (1<<0)	/* A24 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_A32     (2<<0)	/* A32 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_A64     (4<<0)	/* A32 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_CRCSR   (5<<0)	/* CR/CSR Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER1   (8<<0)	/* User1 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER2   (9<<0)	/* User2 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER3   (10<<0)	/* User3 Address Space */
+#define TSI148_LCSR_OTAT_AMODE_USER4   (11<<0)	/* User4 Address Space */
+
+/*
+ *  VME Master Control Register  CRG+$234
+ */
+#define TSI148_LCSR_VMCTRL_VSA         (1<<27)	/* VMEbus Stop Ack */
+#define TSI148_LCSR_VMCTRL_VS          (1<<26)	/* VMEbus Stop */
+#define TSI148_LCSR_VMCTRL_DHB         (1<<25)	/* Device Has Bus */
+#define TSI148_LCSR_VMCTRL_DWB         (1<<24)	/* Device Wants Bus */
+
+#define TSI148_LCSR_VMCTRL_RMWEN       (1<<20)	/* RMW Enable */
+
+#define TSI148_LCSR_VMCTRL_ATO_M       (7<<16)	/* Master Access Time-out Mask */
+#define TSI148_LCSR_VMCTRL_ATO_32      (0<<16)	/* 32 us */
+#define TSI148_LCSR_VMCTRL_ATO_128     (1<<16)	/* 128 us */
+#define TSI148_LCSR_VMCTRL_ATO_512     (2<<16)	/* 512 us */
+#define TSI148_LCSR_VMCTRL_ATO_2M      (3<<16)	/* 2 ms */
+#define TSI148_LCSR_VMCTRL_ATO_8M      (4<<16)	/* 8 ms */
+#define TSI148_LCSR_VMCTRL_ATO_32M     (5<<16)	/* 32 ms */
+#define TSI148_LCSR_VMCTRL_ATO_128M    (6<<16)	/* 128 ms */
+#define TSI148_LCSR_VMCTRL_ATO_DIS     (7<<16)	/* Disabled */
+
+#define TSI148_LCSR_VMCTRL_VTOFF_M     (7<<12)	/* VMEbus Master Time off */
+#define TSI148_LCSR_VMCTRL_VTOFF_0     (0<<12)	/* 0us */
+#define TSI148_LCSR_VMCTRL_VTOFF_1     (1<<12)	/* 1us */
+#define TSI148_LCSR_VMCTRL_VTOFF_2     (2<<12)	/* 2us */
+#define TSI148_LCSR_VMCTRL_VTOFF_4     (3<<12)	/* 4us */
+#define TSI148_LCSR_VMCTRL_VTOFF_8     (4<<12)	/* 8us */
+#define TSI148_LCSR_VMCTRL_VTOFF_16    (5<<12)	/* 16us */
+#define TSI148_LCSR_VMCTRL_VTOFF_32    (6<<12)	/* 32us */
+#define TSI148_LCSR_VMCTRL_VTOFF_64    (7<<12)	/* 64us */
+
+#define TSI148_LCSR_VMCTRL_VTON_M      (7<<8)	/* VMEbus Master Time On */
+#define TSI148_LCSR_VMCTRL_VTON_4      (0<<8)	/* 8us */
+#define TSI148_LCSR_VMCTRL_VTON_8      (1<<8)	/* 8us */
+#define TSI148_LCSR_VMCTRL_VTON_16     (2<<8)	/* 16us */
+#define TSI148_LCSR_VMCTRL_VTON_32     (3<<8)	/* 32us */
+#define TSI148_LCSR_VMCTRL_VTON_64     (4<<8)	/* 64us */
+#define TSI148_LCSR_VMCTRL_VTON_128    (5<<8)	/* 128us */
+#define TSI148_LCSR_VMCTRL_VTON_256    (6<<8)	/* 256us */
+#define TSI148_LCSR_VMCTRL_VTON_512    (7<<8)	/* 512us */
+
+#define TSI148_LCSR_VMCTRL_VREL_M      (3<<3)	/* VMEbus Master Rel Mode Mask */
+#define TSI148_LCSR_VMCTRL_VREL_T_D    (0<<3)	/* Time on or Done */
+#define TSI148_LCSR_VMCTRL_VREL_T_R_D  (1<<3)	/* Time on and REQ or Done */
+#define TSI148_LCSR_VMCTRL_VREL_T_B_D  (2<<3)	/* Time on and BCLR or Done */
+#define TSI148_LCSR_VMCTRL_VREL_T_D_R  (3<<3)	/* Time on or Done and REQ */
+
+#define TSI148_LCSR_VMCTRL_VFAIR       (1<<2)	/* VMEbus Master Fair Mode */
+#define TSI148_LCSR_VMCTRL_VREQL_M     (3<<0)	/* VMEbus Master Req Level Mask */
+
+/*
+ *  VMEbus Control Register CRG+$238
+ */
+#define TSI148_LCSR_VCTRL_LRE          (1<<31)	/* Late Retry Enable */
+
+#define TSI148_LCSR_VCTRL_DLT_M        (0xF<<24)	/* Deadlock Timer */
+#define TSI148_LCSR_VCTRL_DLT_OFF      (0<<24)	/* Deadlock Timer Off */
+#define TSI148_LCSR_VCTRL_DLT_16       (1<<24)	/* 16 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_32       (2<<24)	/* 32 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_64       (3<<24)	/* 64 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_128      (4<<24)	/* 128 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_256      (5<<24)	/* 256 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_512      (6<<24)	/* 512 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_1024     (7<<24)	/* 1024 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_2048     (8<<24)	/* 2048 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_4096     (9<<24)	/* 4096 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_8192     (0xA<<24)	/* 8192 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_16384    (0xB<<24)	/* 16384 VCLKS */
+#define TSI148_LCSR_VCTRL_DLT_32768    (0xC<<24)	/* 32768 VCLKS */
+
+#define TSI148_LCSR_VCTRL_NERBB        (1<<20)	/* No Early Release of Bus Busy */
+
+#define TSI148_LCSR_VCTRL_SRESET       (1<<17)	/* System Reset */
+#define TSI148_LCSR_VCTRL_LRESET       (1<<16)	/* Local Reset */
+
+#define TSI148_LCSR_VCTRL_SFAILAI      (1<<15)	/* SYSFAIL Auto Slot ID */
+#define TSI148_LCSR_VCTRL_BID_M        (0x1F<<8)	/* Broadcast ID Mask */
+
+#define TSI148_LCSR_VCTRL_ATOEN        (1<<7)	/* Arbiter Time-out Enable */
+#define TSI148_LCSR_VCTRL_ROBIN        (1<<6)	/* VMEbus Round Robin */
+
+#define TSI148_LCSR_VCTRL_GTO_M        (7<<0)	/* VMEbus Global Time-out Mask */
+#define TSI148_LCSR_VCTRL_GTO_8	      (0<<0)	/* 8 us */
+#define TSI148_LCSR_VCTRL_GTO_16	      (1<<0)	/* 16 us */
+#define TSI148_LCSR_VCTRL_GTO_32	      (2<<0)	/* 32 us */
+#define TSI148_LCSR_VCTRL_GTO_64	      (3<<0)	/* 64 us */
+#define TSI148_LCSR_VCTRL_GTO_128      (4<<0)	/* 128 us */
+#define TSI148_LCSR_VCTRL_GTO_256      (5<<0)	/* 256 us */
+#define TSI148_LCSR_VCTRL_GTO_512      (6<<0)	/* 512 us */
+#define TSI148_LCSR_VCTRL_GTO_DIS      (7<<0)	/* Disabled */
+
+/*
+ *  VMEbus Status Register  CRG + $23C
+ */
+#define TSI148_LCSR_VSTAT_CPURST       (1<<15)	/* Clear power up reset */
+#define TSI148_LCSR_VSTAT_BRDFL        (1<<14)	/* Board fail */
+#define TSI148_LCSR_VSTAT_PURSTS       (1<<12)	/* Power up reset status */
+#define TSI148_LCSR_VSTAT_BDFAILS      (1<<11)	/* Board Fail Status */
+#define TSI148_LCSR_VSTAT_SYSFAILS     (1<<10)	/* System Fail Status */
+#define TSI148_LCSR_VSTAT_ACFAILS      (1<<9)	/* AC fail status */
+#define TSI148_LCSR_VSTAT_SCONS        (1<<8)	/* System Cont Status */
+#define TSI148_LCSR_VSTAT_GAP          (1<<5)	/* Geographic Addr Parity */
+#define TSI148_LCSR_VSTAT_GA_M         (0x1F<<0)	/* Geographic Addr Mask */
+
+/*
+ *  PCI Configuration Status Register CRG+$240
+ */
+#define TSI148_LCSR_PSTAT_REQ64S       (1<<6)	/* Request 64 status set */
+#define TSI148_LCSR_PSTAT_M66ENS       (1<<5)	/* M66ENS 66Mhz enable */
+#define TSI148_LCSR_PSTAT_FRAMES       (1<<4)	/* Frame Status */
+#define TSI148_LCSR_PSTAT_IRDYS        (1<<3)	/* IRDY status */
+#define TSI148_LCSR_PSTAT_DEVSELS      (1<<2)	/* DEVL status */
+#define TSI148_LCSR_PSTAT_STOPS        (1<<1)	/* STOP status */
+#define TSI148_LCSR_PSTAT_TRDYS        (1<<0)	/* TRDY status */
+
+/*
+ *  VMEbus Exception Attributes Register  CRG + $268
+ */
+#define TSI148_LCSR_VEAT_VES           (1<<31)	/* Status */
+#define TSI148_LCSR_VEAT_VEOF          (1<<30)	/* Overflow */
+#define TSI148_LCSR_VEAT_VESCL         (1<<29)	/* Status Clear */
+#define TSI148_LCSR_VEAT_2EOT          (1<<21)	/* 2e Odd Termination */
+#define TSI148_LCSR_VEAT_2EST          (1<<20)	/* 2e Slave terminated */
+#define TSI148_LCSR_VEAT_BERR          (1<<19)	/* Bus Error */
+#define TSI148_LCSR_VEAT_LWORD         (1<<18)	/* LWORD_ signal state */
+#define TSI148_LCSR_VEAT_WRITE         (1<<17)	/* WRITE_ signal state */
+#define TSI148_LCSR_VEAT_IACK          (1<<16)	/* IACK_ signal state */
+#define TSI148_LCSR_VEAT_DS1           (1<<15)	/* DS1_ signal state */
+#define TSI148_LCSR_VEAT_DS0           (1<<14)	/* DS0_ signal state */
+#define TSI148_LCSR_VEAT_AM_M          (0x3F<<8)	/* Address Mode Mask */
+#define TSI148_LCSR_VEAT_XAM_M         (0xFF<<0)	/* Master AMode Mask */
+
+
+/*
+ * VMEbus PCI Error Diagnostics PCI/X Attributes Register  CRG + $280
+ */
+#define TSI148_LCSR_EDPAT_EDPCL        (1<<29)
+
+/*
+ *  Inbound Translation Starting Address Lower
+ */
+#define TSI148_LCSR_ITSAL6432_M        (0xFFFF<<16)	/* Mask */
+#define TSI148_LCSR_ITSAL24_M          (0x00FFF<<12)	/* Mask */
+#define TSI148_LCSR_ITSAL16_M          (0x0000FFF<<4)	/* Mask */
+
+/*
+ *  Inbound Translation Ending Address Lower
+ */
+#define TSI148_LCSR_ITEAL6432_M        (0xFFFF<<16)	/* Mask */
+#define TSI148_LCSR_ITEAL24_M          (0x00FFF<<12)	/* Mask */
+#define TSI148_LCSR_ITEAL16_M          (0x0000FFF<<4)	/* Mask */
+
+/*
+ *  Inbound Translation Offset Lower
+ */
+#define TSI148_LCSR_ITOFFL6432_M       (0xFFFF<<16)	/* Mask */
+#define TSI148_LCSR_ITOFFL24_M         (0xFFFFF<<12)	/* Mask */
+#define TSI148_LCSR_ITOFFL16_M         (0xFFFFFFF<<4)	/* Mask */
+
+/*
+ *  Inbound Translation Attribute
+ */
+#define TSI148_LCSR_ITAT_EN            (1<<31)	/* Window Enable */
+#define TSI148_LCSR_ITAT_TH            (1<<18)	/* Prefetch Threshold */
+
+#define TSI148_LCSR_ITAT_VFS_M         (3<<16)	/* Virtual FIFO Size Mask */
+#define TSI148_LCSR_ITAT_VFS_64        (0<<16)	/* 64 bytes Virtual FIFO Size */
+#define TSI148_LCSR_ITAT_VFS_128       (1<<16)	/* 128 bytes Virtual FIFO Sz */
+#define TSI148_LCSR_ITAT_VFS_256       (2<<16)	/* 256 bytes Virtual FIFO Sz */
+#define TSI148_LCSR_ITAT_VFS_512       (3<<16)	/* 512 bytes Virtual FIFO Sz */
+
+#define TSI148_LCSR_ITAT_2eSSTM_M      (7<<12)	/* 2eSST Xfer Rate Mask */
+#define TSI148_LCSR_ITAT_2eSSTM_160    (0<<12)	/* 160MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_ITAT_2eSSTM_267    (1<<12)	/* 267MB/s 2eSST Xfer Rate */
+#define TSI148_LCSR_ITAT_2eSSTM_320    (2<<12)	/* 320MB/s 2eSST Xfer Rate */
+
+#define TSI148_LCSR_ITAT_2eSSTB        (1<<11)	/* 2eSST Bcast Xfer Protocol */
+#define TSI148_LCSR_ITAT_2eSST         (1<<10)	/* 2eSST Xfer Protocol */
+#define TSI148_LCSR_ITAT_2eVME         (1<<9)	/* 2eVME Xfer Protocol */
+#define TSI148_LCSR_ITAT_MBLT          (1<<8)	/* MBLT Xfer Protocol */
+#define TSI148_LCSR_ITAT_BLT           (1<<7)	/* BLT Xfer Protocol */
+
+#define TSI148_LCSR_ITAT_AS_M          (7<<4)	/* Address Space Mask */
+#define TSI148_LCSR_ITAT_AS_A16        (0<<4)	/* A16 Address Space */
+#define TSI148_LCSR_ITAT_AS_A24        (1<<4)	/* A24 Address Space */
+#define TSI148_LCSR_ITAT_AS_A32        (2<<4)	/* A32 Address Space */
+#define TSI148_LCSR_ITAT_AS_A64        (4<<4)	/* A64 Address Space */
+
+#define TSI148_LCSR_ITAT_SUPR          (1<<3)	/* Supervisor Access */
+#define TSI148_LCSR_ITAT_NPRIV         (1<<2)	/* Non-Priv (User) Access */
+#define TSI148_LCSR_ITAT_PGM           (1<<1)	/* Program Access */
+#define TSI148_LCSR_ITAT_DATA          (1<<0)	/* Data Access */
+
+/*
+ *  GCSR Base Address Lower Address  CRG +$404
+ */
+#define TSI148_LCSR_GBAL_M             (0x7FFFFFF<<5)	/* Mask */
+
+/*
+ *  GCSR Attribute Register CRG + $408
+ */
+#define TSI148_LCSR_GCSRAT_EN          (1<<7)	/* Enable access to GCSR */
+
+#define TSI148_LCSR_GCSRAT_AS_M        (7<<4)	/* Address Space Mask */
+#define TSI148_LCSR_GCSRAT_AS_A16       (0<<4)	/* Address Space 16 */
+#define TSI148_LCSR_GCSRAT_AS_A24       (1<<4)	/* Address Space 24 */
+#define TSI148_LCSR_GCSRAT_AS_A32       (2<<4)	/* Address Space 32 */
+#define TSI148_LCSR_GCSRAT_AS_A64       (4<<4)	/* Address Space 64 */
+
+#define TSI148_LCSR_GCSRAT_SUPR        (1<<3)	/* Sup set -GCSR decoder */
+#define TSI148_LCSR_GCSRAT_NPRIV       (1<<2)	/* Non-Privliged set - CGSR */
+#define TSI148_LCSR_GCSRAT_PGM         (1<<1)	/* Program set - GCSR decoder */
+#define TSI148_LCSR_GCSRAT_DATA        (1<<0)	/* DATA set GCSR decoder */
+
+/*
+ *  CRG Base Address Lower Address  CRG + $410
+ */
+#define TSI148_LCSR_CBAL_M             (0xFFFFF<<12)
+
+/*
+ *  CRG Attribute Register  CRG + $414
+ */
+#define TSI148_LCSR_CRGAT_EN           (1<<7)	/* Enable PRG Access */
+
+#define TSI148_LCSR_CRGAT_AS_M         (7<<4)	/* Address Space */
+#define TSI148_LCSR_CRGAT_AS_A16       (0<<4)	/* Address Space 16 */
+#define TSI148_LCSR_CRGAT_AS_A24       (1<<4)	/* Address Space 24 */
+#define TSI148_LCSR_CRGAT_AS_A32       (2<<4)	/* Address Space 32 */
+#define TSI148_LCSR_CRGAT_AS_A64       (4<<4)	/* Address Space 64 */
+
+#define TSI148_LCSR_CRGAT_SUPR         (1<<3)	/* Supervisor Access */
+#define TSI148_LCSR_CRGAT_NPRIV        (1<<2)	/* Non-Privliged(User) Access */
+#define TSI148_LCSR_CRGAT_PGM          (1<<1)	/* Program Access */
+#define TSI148_LCSR_CRGAT_DATA         (1<<0)	/* Data Access */
+
+/*
+ *  CR/CSR Offset Lower Register  CRG + $41C
+ */
+#define TSI148_LCSR_CROL_M             (0x1FFF<<19)	/* Mask */
+
+/*
+ *  CR/CSR Attribute register  CRG + $420
+ */
+#define TSI148_LCSR_CRAT_EN            (1<<7)	/* Enable access to CR/CSR */
+
+/*
+ *  Location Monitor base address lower register  CRG + $428
+ */
+#define TSI148_LCSR_LMBAL_M            (0x7FFFFFF<<5)	/* Mask */
+
+/*
+ *  Location Monitor Attribute Register  CRG + $42C
+ */
+#define TSI148_LCSR_LMAT_EN            (1<<7)	/* Enable Location Monitor */
+
+#define TSI148_LCSR_LMAT_AS_M          (7<<4)	/* Address Space MASK  */
+#define TSI148_LCSR_LMAT_AS_A16        (0<<4)	/* A16 */
+#define TSI148_LCSR_LMAT_AS_A24        (1<<4)	/* A24 */
+#define TSI148_LCSR_LMAT_AS_A32        (2<<4)	/* A32 */
+#define TSI148_LCSR_LMAT_AS_A64        (4<<4)	/* A64 */
+
+#define TSI148_LCSR_LMAT_SUPR          (1<<3)	/* Supervisor Access */
+#define TSI148_LCSR_LMAT_NPRIV         (1<<2)	/* Non-Priv (User) Access */
+#define TSI148_LCSR_LMAT_PGM           (1<<1)	/* Program Access */
+#define TSI148_LCSR_LMAT_DATA          (1<<0)	/* Data Access  */
+
+/*
+ *  Broadcast Pulse Generator Timer Register  CRG + $438
+ */
+#define TSI148_LCSR_BPGTR_BPGT_M       (0xFFFF<<0)	/* Mask */
+
+/*
+ *  Broadcast Programmable Clock Timer Register  CRG + $43C
+ */
+#define TSI148_LCSR_BPCTR_BPCT_M       (0xFFFFFF<<0)	/* Mask */
+
+/*
+ *  VMEbus Interrupt Control Register           CRG + $43C
+ */
+#define TSI148_LCSR_VICR_CNTS_M        (3<<22)	/* Cntr Source MASK */
+#define TSI148_LCSR_VICR_CNTS_DIS      (1<<22)	/* Cntr Disable */
+#define TSI148_LCSR_VICR_CNTS_IRQ1     (2<<22)	/* IRQ1 to Cntr */
+#define TSI148_LCSR_VICR_CNTS_IRQ2     (3<<22)	/* IRQ2 to Cntr */
+
+#define TSI148_LCSR_VICR_EDGIS_M       (3<<20)	/* Edge interupt MASK */
+#define TSI148_LCSR_VICR_EDGIS_DIS     (1<<20)	/* Edge interupt Disable */
+#define TSI148_LCSR_VICR_EDGIS_IRQ1    (2<<20)	/* IRQ1 to Edge */
+#define TSI148_LCSR_VICR_EDGIS_IRQ2    (3<<20)	/* IRQ2 to Edge */
+
+#define TSI148_LCSR_VICR_IRQIF_M       (3<<18)	/* IRQ1* Function MASK */
+#define TSI148_LCSR_VICR_IRQIF_NORM    (1<<18)	/* Normal */
+#define TSI148_LCSR_VICR_IRQIF_PULSE   (2<<18)	/* Pulse Generator */
+#define TSI148_LCSR_VICR_IRQIF_PROG    (3<<18)	/* Programmable Clock */
+#define TSI148_LCSR_VICR_IRQIF_1U      (4<<18)	/* 1us Clock */
+
+#define TSI148_LCSR_VICR_IRQ2F_M       (3<<16)	/* IRQ2* Function MASK */
+#define TSI148_LCSR_VICR_IRQ2F_NORM    (1<<16)	/* Normal */
+#define TSI148_LCSR_VICR_IRQ2F_PULSE   (2<<16)	/* Pulse Generator */
+#define TSI148_LCSR_VICR_IRQ2F_PROG    (3<<16)	/* Programmable Clock */
+#define TSI148_LCSR_VICR_IRQ2F_1U      (4<<16)	/* 1us Clock */
+
+#define TSI148_LCSR_VICR_BIP           (1<<15)	/* Broadcast Interrupt Pulse */
+
+#define TSI148_LCSR_VICR_IRQC          (1<<12)	/* VMEbus IRQ Clear */
+#define TSI148_LCSR_VICR_IRQS          (1<<11)	/* VMEbus IRQ Status */
+
+#define TSI148_LCSR_VICR_IRQL_M        (7<<8)	/* VMEbus SW IRQ Level Mask */
+#define TSI148_LCSR_VICR_IRQL_1        (1<<8)	/* VMEbus SW IRQ Level 1 */
+#define TSI148_LCSR_VICR_IRQL_2        (2<<8)	/* VMEbus SW IRQ Level 2 */
+#define TSI148_LCSR_VICR_IRQL_3        (3<<8)	/* VMEbus SW IRQ Level 3 */
+#define TSI148_LCSR_VICR_IRQL_4        (4<<8)	/* VMEbus SW IRQ Level 4 */
+#define TSI148_LCSR_VICR_IRQL_5        (5<<8)	/* VMEbus SW IRQ Level 5 */
+#define TSI148_LCSR_VICR_IRQL_6        (6<<8)	/* VMEbus SW IRQ Level 6 */
+#define TSI148_LCSR_VICR_IRQL_7        (7<<8)	/* VMEbus SW IRQ Level 7 */
+
+static const int TSI148_LCSR_VICR_IRQL[8] = { 0, TSI148_LCSR_VICR_IRQL_1,
+			TSI148_LCSR_VICR_IRQL_2, TSI148_LCSR_VICR_IRQL_3,
+			TSI148_LCSR_VICR_IRQL_4, TSI148_LCSR_VICR_IRQL_5,
+			TSI148_LCSR_VICR_IRQL_6, TSI148_LCSR_VICR_IRQL_7 };
+
+#define TSI148_LCSR_VICR_STID_M        (0xFF<<0)	/* Status/ID Mask */
+
+/*
+ *  Interrupt Enable Register   CRG + $440
+ */
+#define TSI148_LCSR_INTEN_DMA1EN       (1<<25)	/* DMAC 1 */
+#define TSI148_LCSR_INTEN_DMA0EN       (1<<24)	/* DMAC 0 */
+#define TSI148_LCSR_INTEN_LM3EN        (1<<23)	/* Location Monitor 3 */
+#define TSI148_LCSR_INTEN_LM2EN        (1<<22)	/* Location Monitor 2 */
+#define TSI148_LCSR_INTEN_LM1EN        (1<<21)	/* Location Monitor 1 */
+#define TSI148_LCSR_INTEN_LM0EN        (1<<20)	/* Location Monitor 0 */
+#define TSI148_LCSR_INTEN_MB3EN        (1<<19)	/* Mail Box 3 */
+#define TSI148_LCSR_INTEN_MB2EN        (1<<18)	/* Mail Box 2 */
+#define TSI148_LCSR_INTEN_MB1EN        (1<<17)	/* Mail Box 1 */
+#define TSI148_LCSR_INTEN_MB0EN        (1<<16)	/* Mail Box 0 */
+#define TSI148_LCSR_INTEN_PERREN       (1<<13)	/* PCI/X Error */
+#define TSI148_LCSR_INTEN_VERREN       (1<<12)	/* VMEbus Error */
+#define TSI148_LCSR_INTEN_VIEEN        (1<<11)	/* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTEN_IACKEN       (1<<10)	/* IACK */
+#define TSI148_LCSR_INTEN_SYSFLEN      (1<<9)	/* System Fail */
+#define TSI148_LCSR_INTEN_ACFLEN       (1<<8)	/* AC Fail */
+#define TSI148_LCSR_INTEN_IRQ7EN       (1<<7)	/* IRQ7 */
+#define TSI148_LCSR_INTEN_IRQ6EN       (1<<6)	/* IRQ6 */
+#define TSI148_LCSR_INTEN_IRQ5EN       (1<<5)	/* IRQ5 */
+#define TSI148_LCSR_INTEN_IRQ4EN       (1<<4)	/* IRQ4 */
+#define TSI148_LCSR_INTEN_IRQ3EN       (1<<3)	/* IRQ3 */
+#define TSI148_LCSR_INTEN_IRQ2EN       (1<<2)	/* IRQ2 */
+#define TSI148_LCSR_INTEN_IRQ1EN       (1<<1)	/* IRQ1 */
+
+static const int TSI148_LCSR_INTEN_LMEN[4] = { TSI148_LCSR_INTEN_LM0EN,
+					TSI148_LCSR_INTEN_LM1EN,
+					TSI148_LCSR_INTEN_LM2EN,
+					TSI148_LCSR_INTEN_LM3EN };
+
+static const int TSI148_LCSR_INTEN_IRQEN[7] = { TSI148_LCSR_INTEN_IRQ1EN,
+					TSI148_LCSR_INTEN_IRQ2EN,
+					TSI148_LCSR_INTEN_IRQ3EN,
+					TSI148_LCSR_INTEN_IRQ4EN,
+					TSI148_LCSR_INTEN_IRQ5EN,
+					TSI148_LCSR_INTEN_IRQ6EN,
+					TSI148_LCSR_INTEN_IRQ7EN };
+
+/*
+ *  Interrupt Enable Out Register CRG + $444
+ */
+#define TSI148_LCSR_INTEO_DMA1EO       (1<<25)	/* DMAC 1 */
+#define TSI148_LCSR_INTEO_DMA0EO       (1<<24)	/* DMAC 0 */
+#define TSI148_LCSR_INTEO_LM3EO        (1<<23)	/* Loc Monitor 3 */
+#define TSI148_LCSR_INTEO_LM2EO        (1<<22)	/* Loc Monitor 2 */
+#define TSI148_LCSR_INTEO_LM1EO        (1<<21)	/* Loc Monitor 1 */
+#define TSI148_LCSR_INTEO_LM0EO        (1<<20)	/* Location Monitor 0 */
+#define TSI148_LCSR_INTEO_MB3EO        (1<<19)	/* Mail Box 3 */
+#define TSI148_LCSR_INTEO_MB2EO        (1<<18)	/* Mail Box 2 */
+#define TSI148_LCSR_INTEO_MB1EO        (1<<17)	/* Mail Box 1 */
+#define TSI148_LCSR_INTEO_MB0EO        (1<<16)	/* Mail Box 0 */
+#define TSI148_LCSR_INTEO_PERREO       (1<<13)	/* PCI/X Error */
+#define TSI148_LCSR_INTEO_VERREO       (1<<12)	/* VMEbus Error */
+#define TSI148_LCSR_INTEO_VIEEO        (1<<11)	/* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTEO_IACKEO       (1<<10)	/* IACK */
+#define TSI148_LCSR_INTEO_SYSFLEO      (1<<9)	/* System Fail */
+#define TSI148_LCSR_INTEO_ACFLEO       (1<<8)	/* AC Fail */
+#define TSI148_LCSR_INTEO_IRQ7EO       (1<<7)	/* IRQ7 */
+#define TSI148_LCSR_INTEO_IRQ6EO       (1<<6)	/* IRQ6 */
+#define TSI148_LCSR_INTEO_IRQ5EO       (1<<5)	/* IRQ5 */
+#define TSI148_LCSR_INTEO_IRQ4EO       (1<<4)	/* IRQ4 */
+#define TSI148_LCSR_INTEO_IRQ3EO       (1<<3)	/* IRQ3 */
+#define TSI148_LCSR_INTEO_IRQ2EO       (1<<2)	/* IRQ2 */
+#define TSI148_LCSR_INTEO_IRQ1EO       (1<<1)	/* IRQ1 */
+
+static const int TSI148_LCSR_INTEO_LMEO[4] = { TSI148_LCSR_INTEO_LM0EO,
+					TSI148_LCSR_INTEO_LM1EO,
+					TSI148_LCSR_INTEO_LM2EO,
+					TSI148_LCSR_INTEO_LM3EO };
+
+static const int TSI148_LCSR_INTEO_IRQEO[7] = { TSI148_LCSR_INTEO_IRQ1EO,
+					TSI148_LCSR_INTEO_IRQ2EO,
+					TSI148_LCSR_INTEO_IRQ3EO,
+					TSI148_LCSR_INTEO_IRQ4EO,
+					TSI148_LCSR_INTEO_IRQ5EO,
+					TSI148_LCSR_INTEO_IRQ6EO,
+					TSI148_LCSR_INTEO_IRQ7EO };
+
+/*
+ *  Interrupt Status Register CRG + $448
+ */
+#define TSI148_LCSR_INTS_DMA1S         (1<<25)	/* DMA 1 */
+#define TSI148_LCSR_INTS_DMA0S         (1<<24)	/* DMA 0 */
+#define TSI148_LCSR_INTS_LM3S          (1<<23)	/* Location Monitor 3 */
+#define TSI148_LCSR_INTS_LM2S          (1<<22)	/* Location Monitor 2 */
+#define TSI148_LCSR_INTS_LM1S          (1<<21)	/* Location Monitor 1 */
+#define TSI148_LCSR_INTS_LM0S          (1<<20)	/* Location Monitor 0 */
+#define TSI148_LCSR_INTS_MB3S          (1<<19)	/* Mail Box 3 */
+#define TSI148_LCSR_INTS_MB2S          (1<<18)	/* Mail Box 2 */
+#define TSI148_LCSR_INTS_MB1S          (1<<17)	/* Mail Box 1 */
+#define TSI148_LCSR_INTS_MB0S          (1<<16)	/* Mail Box 0 */
+#define TSI148_LCSR_INTS_PERRS         (1<<13)	/* PCI/X Error */
+#define TSI148_LCSR_INTS_VERRS         (1<<12)	/* VMEbus Error */
+#define TSI148_LCSR_INTS_VIES          (1<<11)	/* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTS_IACKS         (1<<10)	/* IACK */
+#define TSI148_LCSR_INTS_SYSFLS        (1<<9)	/* System Fail */
+#define TSI148_LCSR_INTS_ACFLS         (1<<8)	/* AC Fail */
+#define TSI148_LCSR_INTS_IRQ7S         (1<<7)	/* IRQ7 */
+#define TSI148_LCSR_INTS_IRQ6S         (1<<6)	/* IRQ6 */
+#define TSI148_LCSR_INTS_IRQ5S         (1<<5)	/* IRQ5 */
+#define TSI148_LCSR_INTS_IRQ4S         (1<<4)	/* IRQ4 */
+#define TSI148_LCSR_INTS_IRQ3S         (1<<3)	/* IRQ3 */
+#define TSI148_LCSR_INTS_IRQ2S         (1<<2)	/* IRQ2 */
+#define TSI148_LCSR_INTS_IRQ1S         (1<<1)	/* IRQ1 */
+
+static const int TSI148_LCSR_INTS_LMS[4] = { TSI148_LCSR_INTS_LM0S,
+					TSI148_LCSR_INTS_LM1S,
+					TSI148_LCSR_INTS_LM2S,
+					TSI148_LCSR_INTS_LM3S };
+
+static const int TSI148_LCSR_INTS_MBS[4] = { TSI148_LCSR_INTS_MB0S,
+					TSI148_LCSR_INTS_MB1S,
+					TSI148_LCSR_INTS_MB2S,
+					TSI148_LCSR_INTS_MB3S };
+
+/*
+ *  Interrupt Clear Register CRG + $44C
+ */
+#define TSI148_LCSR_INTC_DMA1C         (1<<25)	/* DMA 1 */
+#define TSI148_LCSR_INTC_DMA0C         (1<<24)	/* DMA 0 */
+#define TSI148_LCSR_INTC_LM3C          (1<<23)	/* Location Monitor 3 */
+#define TSI148_LCSR_INTC_LM2C          (1<<22)	/* Location Monitor 2 */
+#define TSI148_LCSR_INTC_LM1C          (1<<21)	/* Location Monitor 1 */
+#define TSI148_LCSR_INTC_LM0C          (1<<20)	/* Location Monitor 0 */
+#define TSI148_LCSR_INTC_MB3C          (1<<19)	/* Mail Box 3 */
+#define TSI148_LCSR_INTC_MB2C          (1<<18)	/* Mail Box 2 */
+#define TSI148_LCSR_INTC_MB1C          (1<<17)	/* Mail Box 1 */
+#define TSI148_LCSR_INTC_MB0C          (1<<16)	/* Mail Box 0 */
+#define TSI148_LCSR_INTC_PERRC         (1<<13)	/* VMEbus Error */
+#define TSI148_LCSR_INTC_VERRC         (1<<12)	/* VMEbus Access Time-out */
+#define TSI148_LCSR_INTC_VIEC          (1<<11)	/* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTC_IACKC         (1<<10)	/* IACK */
+#define TSI148_LCSR_INTC_SYSFLC        (1<<9)	/* System Fail */
+#define TSI148_LCSR_INTC_ACFLC         (1<<8)	/* AC Fail */
+
+static const int TSI148_LCSR_INTC_LMC[4] = { TSI148_LCSR_INTC_LM0C,
+					TSI148_LCSR_INTC_LM1C,
+					TSI148_LCSR_INTC_LM2C,
+					TSI148_LCSR_INTC_LM3C };
+
+static const int TSI148_LCSR_INTC_MBC[4] = { TSI148_LCSR_INTC_MB0C,
+					TSI148_LCSR_INTC_MB1C,
+					TSI148_LCSR_INTC_MB2C,
+					TSI148_LCSR_INTC_MB3C };
+
+/*
+ *  Interrupt Map Register 1 CRG + $458
+ */
+#define TSI148_LCSR_INTM1_DMA1M_M      (3<<18)	/* DMA 1 */
+#define TSI148_LCSR_INTM1_DMA0M_M      (3<<16)	/* DMA 0 */
+#define TSI148_LCSR_INTM1_LM3M_M       (3<<14)	/* Location Monitor 3 */
+#define TSI148_LCSR_INTM1_LM2M_M       (3<<12)	/* Location Monitor 2 */
+#define TSI148_LCSR_INTM1_LM1M_M       (3<<10)	/* Location Monitor 1 */
+#define TSI148_LCSR_INTM1_LM0M_M       (3<<8)	/* Location Monitor 0 */
+#define TSI148_LCSR_INTM1_MB3M_M       (3<<6)	/* Mail Box 3 */
+#define TSI148_LCSR_INTM1_MB2M_M       (3<<4)	/* Mail Box 2 */
+#define TSI148_LCSR_INTM1_MB1M_M       (3<<2)	/* Mail Box 1 */
+#define TSI148_LCSR_INTM1_MB0M_M       (3<<0)	/* Mail Box 0 */
+
+/*
+ *  Interrupt Map Register 2 CRG + $45C
+ */
+#define TSI148_LCSR_INTM2_PERRM_M      (3<<26)	/* PCI Bus Error */
+#define TSI148_LCSR_INTM2_VERRM_M      (3<<24)	/* VMEbus Error */
+#define TSI148_LCSR_INTM2_VIEM_M       (3<<22)	/* VMEbus IRQ Edge */
+#define TSI148_LCSR_INTM2_IACKM_M      (3<<20)	/* IACK */
+#define TSI148_LCSR_INTM2_SYSFLM_M     (3<<18)	/* System Fail */
+#define TSI148_LCSR_INTM2_ACFLM_M      (3<<16)	/* AC Fail */
+#define TSI148_LCSR_INTM2_IRQ7M_M      (3<<14)	/* IRQ7 */
+#define TSI148_LCSR_INTM2_IRQ6M_M      (3<<12)	/* IRQ6 */
+#define TSI148_LCSR_INTM2_IRQ5M_M      (3<<10)	/* IRQ5 */
+#define TSI148_LCSR_INTM2_IRQ4M_M      (3<<8)	/* IRQ4 */
+#define TSI148_LCSR_INTM2_IRQ3M_M      (3<<6)	/* IRQ3 */
+#define TSI148_LCSR_INTM2_IRQ2M_M      (3<<4)	/* IRQ2 */
+#define TSI148_LCSR_INTM2_IRQ1M_M      (3<<2)	/* IRQ1 */
+
+/*
+ *  DMA Control (0-1) Registers CRG + $500
+ */
+#define TSI148_LCSR_DCTL_ABT           (1<<27)	/* Abort */
+#define TSI148_LCSR_DCTL_PAU           (1<<26)	/* Pause */
+#define TSI148_LCSR_DCTL_DGO           (1<<25)	/* DMA Go */
+
+#define TSI148_LCSR_DCTL_MOD           (1<<23)	/* Mode */
+
+#define TSI148_LCSR_DCTL_VBKS_M        (7<<12)	/* VMEbus block Size MASK */
+#define TSI148_LCSR_DCTL_VBKS_32       (0<<12)	/* VMEbus block Size 32 */
+#define TSI148_LCSR_DCTL_VBKS_64       (1<<12)	/* VMEbus block Size 64 */
+#define TSI148_LCSR_DCTL_VBKS_128      (2<<12)	/* VMEbus block Size 128 */
+#define TSI148_LCSR_DCTL_VBKS_256      (3<<12)	/* VMEbus block Size 256 */
+#define TSI148_LCSR_DCTL_VBKS_512      (4<<12)	/* VMEbus block Size 512 */
+#define TSI148_LCSR_DCTL_VBKS_1024     (5<<12)	/* VMEbus block Size 1024 */
+#define TSI148_LCSR_DCTL_VBKS_2048     (6<<12)	/* VMEbus block Size 2048 */
+#define TSI148_LCSR_DCTL_VBKS_4096     (7<<12)	/* VMEbus block Size 4096 */
+
+#define TSI148_LCSR_DCTL_VBOT_M        (7<<8)	/* VMEbus back-off MASK */
+#define TSI148_LCSR_DCTL_VBOT_0        (0<<8)	/* VMEbus back-off  0us */
+#define TSI148_LCSR_DCTL_VBOT_1        (1<<8)	/* VMEbus back-off 1us */
+#define TSI148_LCSR_DCTL_VBOT_2        (2<<8)	/* VMEbus back-off 2us */
+#define TSI148_LCSR_DCTL_VBOT_4        (3<<8)	/* VMEbus back-off 4us */
+#define TSI148_LCSR_DCTL_VBOT_8        (4<<8)	/* VMEbus back-off 8us */
+#define TSI148_LCSR_DCTL_VBOT_16       (5<<8)	/* VMEbus back-off 16us */
+#define TSI148_LCSR_DCTL_VBOT_32       (6<<8)	/* VMEbus back-off 32us */
+#define TSI148_LCSR_DCTL_VBOT_64       (7<<8)	/* VMEbus back-off 64us */
+
+#define TSI148_LCSR_DCTL_PBKS_M        (7<<4)	/* PCI block size MASK */
+#define TSI148_LCSR_DCTL_PBKS_32       (0<<4)	/* PCI block size 32 bytes */
+#define TSI148_LCSR_DCTL_PBKS_64       (1<<4)	/* PCI block size 64 bytes */
+#define TSI148_LCSR_DCTL_PBKS_128      (2<<4)	/* PCI block size 128 bytes */
+#define TSI148_LCSR_DCTL_PBKS_256      (3<<4)	/* PCI block size 256 bytes */
+#define TSI148_LCSR_DCTL_PBKS_512      (4<<4)	/* PCI block size 512 bytes */
+#define TSI148_LCSR_DCTL_PBKS_1024     (5<<4)	/* PCI block size 1024 bytes */
+#define TSI148_LCSR_DCTL_PBKS_2048     (6<<4)	/* PCI block size 2048 bytes */
+#define TSI148_LCSR_DCTL_PBKS_4096     (7<<4)	/* PCI block size 4096 bytes */
+
+#define TSI148_LCSR_DCTL_PBOT_M        (7<<0)	/* PCI back off MASK */
+#define TSI148_LCSR_DCTL_PBOT_0        (0<<0)	/* PCI back off 0us */
+#define TSI148_LCSR_DCTL_PBOT_1        (1<<0)	/* PCI back off 1us */
+#define TSI148_LCSR_DCTL_PBOT_2        (2<<0)	/* PCI back off 2us */
+#define TSI148_LCSR_DCTL_PBOT_4        (3<<0)	/* PCI back off 3us */
+#define TSI148_LCSR_DCTL_PBOT_8        (4<<0)	/* PCI back off 4us */
+#define TSI148_LCSR_DCTL_PBOT_16       (5<<0)	/* PCI back off 8us */
+#define TSI148_LCSR_DCTL_PBOT_32       (6<<0)	/* PCI back off 16us */
+#define TSI148_LCSR_DCTL_PBOT_64       (7<<0)	/* PCI back off 32us */
+
+/*
+ *  DMA Status Registers (0-1)  CRG + $504
+ */
+#define TSI148_LCSR_DSTA_SMA           (1<<31)	/* PCI Signalled Master Abt */
+#define TSI148_LCSR_DSTA_RTA           (1<<30)	/* PCI Received Target Abt */
+#define TSI148_LCSR_DSTA_MRC           (1<<29)	/* PCI Max Retry Count */
+#define TSI148_LCSR_DSTA_VBE           (1<<28)	/* VMEbus error */
+#define TSI148_LCSR_DSTA_ABT           (1<<27)	/* Abort */
+#define TSI148_LCSR_DSTA_PAU           (1<<26)	/* Pause */
+#define TSI148_LCSR_DSTA_DON           (1<<25)	/* Done */
+#define TSI148_LCSR_DSTA_BSY           (1<<24)	/* Busy */
+
+/*
+ *  DMA Current Link Address Lower (0-1)
+ */
+#define TSI148_LCSR_DCLAL_M            (0x3FFFFFF<<6)	/* Mask */
+
+/*
+ *  DMA Source Attribute (0-1) Reg
+ */
+#define TSI148_LCSR_DSAT_TYP_M         (3<<28)	/* Source Bus Type */
+#define TSI148_LCSR_DSAT_TYP_PCI       (0<<28)	/* PCI Bus */
+#define TSI148_LCSR_DSAT_TYP_VME       (1<<28)	/* VMEbus */
+#define TSI148_LCSR_DSAT_TYP_PAT       (2<<28)	/* Data Pattern */
+
+#define TSI148_LCSR_DSAT_PSZ           (1<<25)	/* Pattern Size */
+#define TSI148_LCSR_DSAT_NIN           (1<<24)	/* No Increment */
+
+#define TSI148_LCSR_DSAT_2eSSTM_M      (3<<11)	/* 2eSST Trans Rate Mask */
+#define TSI148_LCSR_DSAT_2eSSTM_160    (0<<11)	/* 160 MB/s */
+#define TSI148_LCSR_DSAT_2eSSTM_267    (1<<11)	/* 267 MB/s */
+#define TSI148_LCSR_DSAT_2eSSTM_320    (2<<11)	/* 320 MB/s */
+
+#define TSI148_LCSR_DSAT_TM_M          (7<<8)	/* Bus Transfer Protocol Mask */
+#define TSI148_LCSR_DSAT_TM_SCT        (0<<8)	/* SCT */
+#define TSI148_LCSR_DSAT_TM_BLT        (1<<8)	/* BLT */
+#define TSI148_LCSR_DSAT_TM_MBLT       (2<<8)	/* MBLT */
+#define TSI148_LCSR_DSAT_TM_2eVME      (3<<8)	/* 2eVME */
+#define TSI148_LCSR_DSAT_TM_2eSST      (4<<8)	/* 2eSST */
+#define TSI148_LCSR_DSAT_TM_2eSSTB     (5<<8)	/* 2eSST Broadcast */
+
+#define TSI148_LCSR_DSAT_DBW_M         (3<<6)	/* Max Data Width MASK */
+#define TSI148_LCSR_DSAT_DBW_16        (0<<6)	/* 16 Bits */
+#define TSI148_LCSR_DSAT_DBW_32        (1<<6)	/* 32 Bits */
+
+#define TSI148_LCSR_DSAT_SUP           (1<<5)	/* Supervisory Mode */
+#define TSI148_LCSR_DSAT_PGM           (1<<4)	/* Program Mode */
+
+#define TSI148_LCSR_DSAT_AMODE_M       (0xf<<0)	/* Address Space Mask */
+#define TSI148_LCSR_DSAT_AMODE_A16     (0<<0)	/* A16 */
+#define TSI148_LCSR_DSAT_AMODE_A24     (1<<0)	/* A24 */
+#define TSI148_LCSR_DSAT_AMODE_A32     (2<<0)	/* A32 */
+#define TSI148_LCSR_DSAT_AMODE_A64     (4<<0)	/* A64 */
+#define TSI148_LCSR_DSAT_AMODE_CRCSR   (5<<0)	/* CR/CSR */
+#define TSI148_LCSR_DSAT_AMODE_USER1   (8<<0)	/* User1 */
+#define TSI148_LCSR_DSAT_AMODE_USER2   (9<<0)	/* User2 */
+#define TSI148_LCSR_DSAT_AMODE_USER3   (0xa<<0)	/* User3 */
+#define TSI148_LCSR_DSAT_AMODE_USER4   (0xb<<0)	/* User4 */
+
+/*
+ *  DMA Destination Attribute Registers (0-1)
+ */
+#define TSI148_LCSR_DDAT_TYP_PCI       (0<<28)	/* Destination PCI Bus  */
+#define TSI148_LCSR_DDAT_TYP_VME       (1<<28)	/* Destination VMEbus */
+
+#define TSI148_LCSR_DDAT_2eSSTM_M      (3<<11)	/* 2eSST Transfer Rate Mask */
+#define TSI148_LCSR_DDAT_2eSSTM_160    (0<<11)	/* 160 MB/s */
+#define TSI148_LCSR_DDAT_2eSSTM_267    (1<<11)	/* 267 MB/s */
+#define TSI148_LCSR_DDAT_2eSSTM_320    (2<<11)	/* 320 MB/s */
+
+#define TSI148_LCSR_DDAT_TM_M          (7<<8)	/* Bus Transfer Protocol Mask */
+#define TSI148_LCSR_DDAT_TM_SCT        (0<<8)	/* SCT */
+#define TSI148_LCSR_DDAT_TM_BLT        (1<<8)	/* BLT */
+#define TSI148_LCSR_DDAT_TM_MBLT       (2<<8)	/* MBLT */
+#define TSI148_LCSR_DDAT_TM_2eVME      (3<<8)	/* 2eVME */
+#define TSI148_LCSR_DDAT_TM_2eSST      (4<<8)	/* 2eSST */
+#define TSI148_LCSR_DDAT_TM_2eSSTB     (5<<8)	/* 2eSST Broadcast */
+
+#define TSI148_LCSR_DDAT_DBW_M         (3<<6)	/* Max Data Width MASK */
+#define TSI148_LCSR_DDAT_DBW_16        (0<<6)	/* 16 Bits */
+#define TSI148_LCSR_DDAT_DBW_32        (1<<6)	/* 32 Bits */
+
+#define TSI148_LCSR_DDAT_SUP           (1<<5)	/* Supervisory/User Access */
+#define TSI148_LCSR_DDAT_PGM           (1<<4)	/* Program/Data Access */
+
+#define TSI148_LCSR_DDAT_AMODE_M       (0xf<<0)	/* Address Space Mask */
+#define TSI148_LCSR_DDAT_AMODE_A16      (0<<0)	/* A16 */
+#define TSI148_LCSR_DDAT_AMODE_A24      (1<<0)	/* A24 */
+#define TSI148_LCSR_DDAT_AMODE_A32      (2<<0)	/* A32 */
+#define TSI148_LCSR_DDAT_AMODE_A64      (4<<0)	/* A64 */
+#define TSI148_LCSR_DDAT_AMODE_CRCSR   (5<<0)	/* CRC/SR */
+#define TSI148_LCSR_DDAT_AMODE_USER1   (8<<0)	/* User1 */
+#define TSI148_LCSR_DDAT_AMODE_USER2   (9<<0)	/* User2 */
+#define TSI148_LCSR_DDAT_AMODE_USER3   (0xa<<0)	/* User3 */
+#define TSI148_LCSR_DDAT_AMODE_USER4   (0xb<<0)	/* User4 */
+
+/*
+ *  DMA Next Link Address Lower
+ */
+#define TSI148_LCSR_DNLAL_DNLAL_M      (0x3FFFFFF<<6)	/* Address Mask */
+#define TSI148_LCSR_DNLAL_LLA          (1<<0)	/* Last Link Address Indicator */
+
+/*
+ *  DMA 2eSST Broadcast Select
+ */
+#define TSI148_LCSR_DBS_M              (0x1FFFFF<<0)	/* Mask */
+
+/*
+ *  GCSR Register Group
+ */
+
+/*
+ *  GCSR Control and Status Register  CRG + $604
+ */
+#define TSI148_GCSR_GCTRL_LRST         (1<<15)	/* Local Reset */
+#define TSI148_GCSR_GCTRL_SFAILEN      (1<<14)	/* System Fail enable */
+#define TSI148_GCSR_GCTRL_BDFAILS      (1<<13)	/* Board Fail Status */
+#define TSI148_GCSR_GCTRL_SCON         (1<<12)	/* System Copntroller */
+#define TSI148_GCSR_GCTRL_MEN          (1<<11)	/* Module Enable (READY) */
+
+#define TSI148_GCSR_GCTRL_LMI3S        (1<<7)	/* Loc Monitor 3 Int Status */
+#define TSI148_GCSR_GCTRL_LMI2S        (1<<6)	/* Loc Monitor 2 Int Status */
+#define TSI148_GCSR_GCTRL_LMI1S        (1<<5)	/* Loc Monitor 1 Int Status */
+#define TSI148_GCSR_GCTRL_LMI0S        (1<<4)	/* Loc Monitor 0 Int Status */
+#define TSI148_GCSR_GCTRL_MBI3S        (1<<3)	/* Mail box 3 Int Status */
+#define TSI148_GCSR_GCTRL_MBI2S        (1<<2)	/* Mail box 2 Int Status */
+#define TSI148_GCSR_GCTRL_MBI1S        (1<<1)	/* Mail box 1 Int Status */
+#define TSI148_GCSR_GCTRL_MBI0S        (1<<0)	/* Mail box 0 Int Status */
+
+#define TSI148_GCSR_GAP                (1<<5)	/* Geographic Addr Parity */
+#define TSI148_GCSR_GA_M               (0x1F<<0)	/* Geographic Address Mask */
+
+/*
+ *  CR/CSR Register Group
+ */
+
+/*
+ *  CR/CSR Bit Clear Register CRG + $FF4
+ */
+#define TSI148_CRCSR_CSRBCR_LRSTC      (1<<7)	/* Local Reset Clear */
+#define TSI148_CRCSR_CSRBCR_SFAILC     (1<<6)	/* System Fail Enable Clear */
+#define TSI148_CRCSR_CSRBCR_BDFAILS    (1<<5)	/* Board Fail Status */
+#define TSI148_CRCSR_CSRBCR_MENC       (1<<4)	/* Module Enable Clear */
+#define TSI148_CRCSR_CSRBCR_BERRSC     (1<<3)	/* Bus Error Status Clear */
+
+/*
+ *  CR/CSR Bit Set Register CRG+$FF8
+ */
+#define TSI148_CRCSR_CSRBSR_LISTS      (1<<7)	/* Local Reset Clear */
+#define TSI148_CRCSR_CSRBSR_SFAILS     (1<<6)	/* System Fail Enable Clear */
+#define TSI148_CRCSR_CSRBSR_BDFAILS    (1<<5)	/* Board Fail Status */
+#define TSI148_CRCSR_CSRBSR_MENS       (1<<4)	/* Module Enable Clear */
+#define TSI148_CRCSR_CSRBSR_BERRS      (1<<3)	/* Bus Error Status Clear */
+
+/*
+ *  CR/CSR Base Address Register CRG + FFC
+ */
+#define TSI148_CRCSR_CBAR_M            (0x1F<<3)	/* Mask */
+
+#endif				/* TSI148_H */
diff --git a/drivers/staging/vme/devices/Kconfig b/drivers/staging/vme/devices/Kconfig
new file mode 100644
index 0000000..ca5ba89
--- /dev/null
+++ b/drivers/staging/vme/devices/Kconfig
@@ -0,0 +1,8 @@
+comment "VME Device Drivers"
+
+config VME_USER
+	tristate "VME user space access driver"
+	help
+	  If you say Y here you want to be able to access a limited number of
+	  VME windows in a manner at least semi-compatible with the interface
+	  provided with the original driver at http://vmelinux.org/.
diff --git a/drivers/staging/vme/devices/Makefile b/drivers/staging/vme/devices/Makefile
new file mode 100644
index 0000000..459742a
--- /dev/null
+++ b/drivers/staging/vme/devices/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the VME device drivers.
+#
+
+obj-$(CONFIG_VME_USER)		+= vme_user.o
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
new file mode 100644
index 0000000..7891288
--- /dev/null
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -0,0 +1,826 @@
+/*
+ * VMEbus User access driver
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by:
+ *   Tom Armistead and Ajit Prem
+ *     Copyright 2004 Motorola 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/cdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <linux/pci.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/syscalls.h>
+#include <linux/types.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "../vme.h"
+#include "vme_user.h"
+
+static char driver_name[] = "vme_user";
+
+static int bus[USER_BUS_MAX];
+static int bus_num;
+
+/* Currently Documentation/devices.txt defines the following for VME:
+ *
+ * 221 char	VME bus
+ * 		  0 = /dev/bus/vme/m0		First master image
+ * 		  1 = /dev/bus/vme/m1		Second master image
+ * 		  2 = /dev/bus/vme/m2		Third master image
+ * 		  3 = /dev/bus/vme/m3		Fourth master image
+ * 		  4 = /dev/bus/vme/s0		First slave image
+ * 		  5 = /dev/bus/vme/s1		Second slave image
+ * 		  6 = /dev/bus/vme/s2		Third slave image
+ * 		  7 = /dev/bus/vme/s3		Fourth slave image
+ * 		  8 = /dev/bus/vme/ctl		Control
+ *
+ * 		It is expected that all VME bus drivers will use the
+ * 		same interface.  For interface documentation see
+ * 		http://www.vmelinux.org/.
+ *
+ * However the VME driver at http://www.vmelinux.org/ is rather old and doesn't
+ * even support the tsi148 chipset (which has 8 master and 8 slave windows).
+ * We'll run with this or now as far as possible, however it probably makes
+ * sense to get rid of the old mappings and just do everything dynamically.
+ *
+ * So for now, we'll restrict the driver to providing 4 masters and 4 slaves as
+ * defined above and try to support at least some of the interface from
+ * http://www.vmelinux.org/ as an alternative drive can be written providing a
+ * saner interface later.
+ *
+ * The vmelinux.org driver never supported slave images, the devices reserved
+ * for slaves were repurposed to support all 8 master images on the UniverseII!
+ * We shall support 4 masters and 4 slaves with this driver.
+ */
+#define VME_MAJOR	221	/* VME Major Device Number */
+#define VME_DEVS	9	/* Number of dev entries */
+
+#define MASTER_MINOR	0
+#define MASTER_MAX	3
+#define SLAVE_MINOR	4
+#define SLAVE_MAX	7
+#define CONTROL_MINOR	8
+
+#define PCI_BUF_SIZE  0x20000	/* Size of one slave image buffer */
+
+/*
+ * Structure to handle image related parameters.
+ */
+typedef struct {
+	void __iomem *kern_buf;	/* Buffer address in kernel space */
+	dma_addr_t pci_buf;	/* Buffer address in PCI address space */
+	unsigned long long size_buf;	/* Buffer size */
+	struct semaphore sem;	/* Semaphore for locking image */
+	struct device *device;	/* Sysfs device */
+	struct vme_resource *resource;	/* VME resource */
+	int users;		/* Number of current users */
+} image_desc_t;
+static image_desc_t image[VME_DEVS];
+
+typedef struct {
+	unsigned long reads;
+	unsigned long writes;
+	unsigned long ioctls;
+	unsigned long irqs;
+	unsigned long berrs;
+	unsigned long dmaErrors;
+	unsigned long timeouts;
+	unsigned long external;
+} driver_stats_t;
+static driver_stats_t statistics;
+
+struct cdev *vme_user_cdev;		/* Character device */
+struct class *vme_user_sysfs_class;	/* Sysfs class */
+struct device *vme_user_bridge;		/* Pointer to the bridge device */
+
+
+static const int type[VME_DEVS] = {	MASTER_MINOR,	MASTER_MINOR,
+					MASTER_MINOR,	MASTER_MINOR,
+					SLAVE_MINOR,	SLAVE_MINOR,
+					SLAVE_MINOR,	SLAVE_MINOR,
+					CONTROL_MINOR
+				};
+
+
+static int vme_user_open(struct inode *, struct file *);
+static int vme_user_release(struct inode *, struct file *);
+static ssize_t vme_user_read(struct file *, char *, size_t, loff_t *);
+static ssize_t vme_user_write(struct file *, const char *, size_t, loff_t *);
+static loff_t vme_user_llseek(struct file *, loff_t, int);
+static int vme_user_ioctl(struct inode *, struct file *, unsigned int,
+	unsigned long);
+
+static int __init vme_user_probe(struct device *, int, int);
+static int __exit vme_user_remove(struct device *, int, int);
+
+static struct file_operations vme_user_fops = {
+        .open = vme_user_open,
+        .release = vme_user_release,
+        .read = vme_user_read,
+        .write = vme_user_write,
+        .llseek = vme_user_llseek,
+        .ioctl = vme_user_ioctl,
+};
+
+
+/*
+ * Reset all the statistic counters
+ */
+static void reset_counters(void)
+{
+        statistics.reads = 0;
+        statistics.writes = 0;
+        statistics.ioctls = 0;
+        statistics.irqs = 0;
+        statistics.berrs = 0;
+        statistics.dmaErrors = 0;
+        statistics.timeouts = 0;
+}
+
+static int vme_user_open(struct inode *inode, struct file *file)
+{
+	int err;
+	unsigned int minor = MINOR(inode->i_rdev);
+
+	down(&image[minor].sem);
+	/* Only allow device to be opened if a resource is allocated */
+	if (image[minor].resource == NULL) {
+		printk(KERN_ERR "No resources allocated for device\n");
+		err = -EINVAL;
+		goto err_res;
+	}
+
+	/* Increment user count */
+	image[minor].users++;
+
+	up(&image[minor].sem);
+
+	return 0;
+
+err_res:
+	up(&image[minor].sem);
+
+	return err;
+}
+
+static int vme_user_release(struct inode *inode, struct file *file)
+{
+	unsigned int minor = MINOR(inode->i_rdev);
+
+	down(&image[minor].sem);
+
+	/* Decrement user count */
+	image[minor].users--;
+
+	up(&image[minor].sem);
+
+	return 0;
+}
+
+/*
+ * We are going ot alloc a page during init per window for small transfers.
+ * Small transfers will go VME -> buffer -> user space. Larger (more than a
+ * page) transfers will lock the user space buffer into memory and then
+ * transfer the data directly into the user space buffers.
+ */
+static ssize_t resource_to_user(int minor, char __user *buf, size_t count,
+	loff_t *ppos)
+{
+	ssize_t retval;
+	ssize_t copied = 0;
+
+	if (count <= image[minor].size_buf) {
+		/* We copy to kernel buffer */
+		copied = vme_master_read(image[minor].resource,
+			image[minor].kern_buf, count, *ppos);
+		if (copied < 0) {
+			return (int)copied;
+		}
+
+		retval = __copy_to_user(buf, image[minor].kern_buf,
+			(unsigned long)copied);
+		if (retval != 0) {
+			copied = (copied - retval);
+			printk("User copy failed\n");
+			return -EINVAL;
+		}
+
+	} else {
+		/* XXX Need to write this */
+		printk("Currently don't support large transfers\n");
+		/* Map in pages from userspace */
+
+		/* Call vme_master_read to do the transfer */
+		return -EINVAL;
+	}
+
+	return copied;
+}
+
+/*
+ * We are going ot alloc a page during init per window for small transfers.
+ * Small transfers will go user space -> buffer -> VME. Larger (more than a
+ * page) transfers will lock the user space buffer into memory and then
+ * transfer the data directly from the user space buffers out to VME.
+ */
+static ssize_t resource_from_user(unsigned int minor, const char *buf,
+	size_t count, loff_t *ppos)
+{
+	ssize_t retval;
+	ssize_t copied = 0;
+
+	if (count <= image[minor].size_buf) {
+		retval = __copy_from_user(image[minor].kern_buf, buf,
+			(unsigned long)count);
+		if (retval != 0)
+			copied = (copied - retval);
+		else
+			copied = count;
+
+		copied = vme_master_write(image[minor].resource,
+			image[minor].kern_buf, copied, *ppos);
+	} else {
+		/* XXX Need to write this */
+		printk("Currently don't support large transfers\n");
+		/* Map in pages from userspace */
+
+		/* Call vme_master_write to do the transfer */
+		return -EINVAL;
+	}
+
+	return copied;
+}
+
+static ssize_t buffer_to_user(unsigned int minor, char __user *buf,
+	size_t count, loff_t *ppos)
+{
+	void __iomem *image_ptr;
+	ssize_t retval;
+
+	image_ptr = image[minor].kern_buf + *ppos;
+
+	retval = __copy_to_user(buf, image_ptr, (unsigned long)count);
+	if (retval != 0) {
+		retval = (count - retval);
+		printk(KERN_WARNING "Partial copy to userspace\n");
+	} else
+		retval = count;
+
+	/* Return number of bytes successfully read */
+	return retval;
+}
+
+static ssize_t buffer_from_user(unsigned int minor, const char *buf,
+	size_t count, loff_t *ppos)
+{
+	void __iomem *image_ptr;
+	size_t retval;
+
+	image_ptr = image[minor].kern_buf + *ppos;
+
+	retval = __copy_from_user(image_ptr, buf, (unsigned long)count);
+	if (retval != 0) {
+		retval = (count - retval);
+		printk(KERN_WARNING "Partial copy to userspace\n");
+	} else
+		retval = count;
+
+	/* Return number of bytes successfully read */
+	return retval;
+}
+
+static ssize_t vme_user_read(struct file *file, char *buf, size_t count,
+			loff_t * ppos)
+{
+	unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+	ssize_t retval;
+	size_t image_size;
+	size_t okcount;
+
+	down(&image[minor].sem);
+
+	/* XXX Do we *really* want this helper - we can use vme_*_get ? */
+	image_size = vme_get_size(image[minor].resource);
+
+	/* Ensure we are starting at a valid location */
+	if ((*ppos < 0) || (*ppos > (image_size - 1))) {
+		up(&image[minor].sem);
+		return 0;
+	}
+
+	/* Ensure not reading past end of the image */
+	if (*ppos + count > image_size)
+		okcount = image_size - *ppos;
+	else
+		okcount = count;
+
+	switch (type[minor]){
+	case MASTER_MINOR:
+		retval = resource_to_user(minor, buf, okcount, ppos);
+		break;
+	case SLAVE_MINOR:
+		retval = buffer_to_user(minor, buf, okcount, ppos);
+		break;
+	default:
+		retval = -EINVAL;
+	}
+
+	up(&image[minor].sem);
+
+	if (retval > 0)
+		*ppos += retval;
+
+	return retval;
+}
+
+static ssize_t vme_user_write(struct file *file, const char *buf, size_t count,
+			 loff_t *ppos)
+{
+	unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+	ssize_t retval;
+	size_t image_size;
+	size_t okcount;
+
+	down(&image[minor].sem);
+
+	image_size = vme_get_size(image[minor].resource);
+
+	/* Ensure we are starting at a valid location */
+	if ((*ppos < 0) || (*ppos > (image_size - 1))) {
+		up(&image[minor].sem);
+		return 0;
+	}
+
+	/* Ensure not reading past end of the image */
+	if (*ppos + count > image_size)
+		okcount = image_size - *ppos;
+	else
+		okcount = count;
+
+	switch (type[minor]){
+	case MASTER_MINOR:
+		retval = resource_from_user(minor, buf, okcount, ppos);
+		break;
+	case SLAVE_MINOR:
+		retval = buffer_from_user(minor, buf, okcount, ppos);
+		break;
+	default:
+		retval = -EINVAL;
+	}
+
+	up(&image[minor].sem);
+
+	if (retval > 0)
+		*ppos += retval;
+
+	return retval;
+}
+
+static loff_t vme_user_llseek(struct file *file, loff_t off, int whence)
+{
+	printk(KERN_ERR "Llseek currently incomplete\n");
+	return -EINVAL;
+}
+
+/*
+ * The ioctls provided by the old VME access method (the one at vmelinux.org)
+ * are most certainly wrong as the effectively push the registers layout
+ * through to user space. Given that the VME core can handle multiple bridges,
+ * with different register layouts this is most certainly not the way to go.
+ *
+ * We aren't using the structures defined in the Motorola driver either - these
+ * are also quite low level, however we should use the definitions that have
+ * already been defined.
+ */
+static int vme_user_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	struct vme_master master;
+	struct vme_slave slave;
+	unsigned long copied;
+	unsigned int minor = MINOR(inode->i_rdev);
+	int retval;
+	dma_addr_t pci_addr;
+
+	statistics.ioctls++;
+
+	switch (type[minor]) {
+	case CONTROL_MINOR:
+		break;
+	case MASTER_MINOR:
+		switch (cmd) {
+		case VME_GET_MASTER:
+			memset(&master, 0, sizeof(struct vme_master));
+
+			/* XXX	We do not want to push aspace, cycle and width
+			 *	to userspace as they are
+			 */
+			retval = vme_master_get(image[minor].resource,
+				&(master.enable), &(master.vme_addr),
+				&(master.size), &(master.aspace),
+				&(master.cycle), &(master.dwidth));
+
+			copied = copy_to_user((char *)arg, &master,
+				sizeof(struct vme_master));
+			if (copied != 0) {
+				printk(KERN_WARNING "Partial copy to "
+					"userspace\n");
+				return -EFAULT;
+			}
+
+			return retval;
+			break;
+
+		case VME_SET_MASTER:
+
+			copied = copy_from_user(&master, (char *)arg,
+				sizeof(master));
+			if (copied != 0) {
+				printk(KERN_WARNING "Partial copy from "
+					"userspace\n");
+				return -EFAULT;
+			}
+
+			/* XXX	We do not want to push aspace, cycle and width
+			 *	to userspace as they are
+			 */
+			return vme_master_set(image[minor].resource,
+				master.enable, master.vme_addr, master.size,
+				master.aspace, master.cycle, master.dwidth);
+
+			break;
+		}
+		break;
+	case SLAVE_MINOR:
+		switch (cmd) {
+		case VME_GET_SLAVE:
+			memset(&slave, 0, sizeof(struct vme_slave));
+
+			/* XXX	We do not want to push aspace, cycle and width
+			 *	to userspace as they are
+			 */
+			retval = vme_slave_get(image[minor].resource,
+				&(slave.enable), &(slave.vme_addr),
+				&(slave.size), &pci_addr, &(slave.aspace),
+				&(slave.cycle));
+
+			copied = copy_to_user((char *)arg, &slave,
+				sizeof(struct vme_slave));
+			if (copied != 0) {
+				printk(KERN_WARNING "Partial copy to "
+					"userspace\n");
+				return -EFAULT;
+			}
+
+			return retval;
+			break;
+
+		case VME_SET_SLAVE:
+
+			copied = copy_from_user(&slave, (char *)arg,
+				sizeof(slave));
+			if (copied != 0) {
+				printk(KERN_WARNING "Partial copy from "
+					"userspace\n");
+				return -EFAULT;
+			}
+
+			/* XXX	We do not want to push aspace, cycle and width
+			 *	to userspace as they are
+			 */
+			return vme_slave_set(image[minor].resource,
+				slave.enable, slave.vme_addr, slave.size,
+				image[minor].pci_buf, slave.aspace,
+				slave.cycle);
+
+			break;
+		}
+		break;
+	}
+
+	return -EINVAL;
+}
+
+
+/*
+ * Unallocate a previously allocated buffer
+ */
+static void buf_unalloc (int num)
+{
+	if (image[num].kern_buf) {
+#ifdef VME_DEBUG
+		printk(KERN_DEBUG "UniverseII:Releasing buffer at %p\n",
+			image[num].pci_buf);
+#endif
+
+		vme_free_consistent(image[num].resource, image[num].size_buf,
+			image[num].kern_buf, image[num].pci_buf);
+
+		image[num].kern_buf = NULL;
+		image[num].pci_buf = 0;
+		image[num].size_buf = 0;
+
+#ifdef VME_DEBUG
+	} else {
+		printk(KERN_DEBUG "UniverseII: Buffer not allocated\n");
+#endif
+	}
+}
+
+static struct vme_driver vme_user_driver = {
+        .name = driver_name,
+        .probe = vme_user_probe,
+	.remove = vme_user_remove,
+};
+
+
+static int __init vme_user_init(void)
+{
+	int retval = 0;
+	int i;
+	struct vme_device_id *ids;
+
+	printk(KERN_INFO "VME User Space Access Driver\n");
+
+	if (bus_num == 0) {
+		printk(KERN_ERR "%s: No cards, skipping registration\n",
+			driver_name);
+		goto err_nocard;
+	}
+
+	/* Let's start by supporting one bus, we can support more than one
+	 * in future revisions if that ever becomes necessary.
+	 */
+	if (bus_num > USER_BUS_MAX) {
+		printk(KERN_ERR "%s: Driver only able to handle %d PIO2 "
+			"Cards\n", driver_name, USER_BUS_MAX);
+		bus_num = USER_BUS_MAX;
+	}
+
+
+	/* Dynamically create the bind table based on module parameters */
+	ids = kmalloc(sizeof(struct vme_device_id) * (bus_num + 1), GFP_KERNEL);
+	if (ids == NULL) {
+		printk(KERN_ERR "%s: Unable to allocate ID table\n",
+			driver_name);
+		goto err_id;
+	}
+
+	memset(ids, 0, (sizeof(struct vme_device_id) * (bus_num + 1)));
+
+	for (i = 0; i < bus_num; i++) {
+		ids[i].bus = bus[i];
+		/*
+		 * We register the driver against the slot occupied by *this*
+		 * card, since it's really a low level way of controlling
+		 * the VME bridge
+		 */
+		ids[i].slot = VME_SLOT_CURRENT;
+	}
+
+	vme_user_driver.bind_table = ids;
+
+	retval = vme_register_driver(&vme_user_driver);
+	if (retval != 0)
+		goto err_reg;
+
+	return retval;
+
+	vme_unregister_driver(&vme_user_driver);
+err_reg:
+	kfree(ids);
+err_id:
+err_nocard:
+	return retval;
+}
+
+/*
+ * In this simple access driver, the old behaviour is being preserved as much
+ * as practical. We will therefore reserve the buffers and request the images
+ * here so that we don't have to do it later.
+ */
+static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot)
+{
+	int i, err;
+	char name[8];
+
+	/* Save pointer to the bridge device */
+	if (vme_user_bridge != NULL) {
+		printk(KERN_ERR "%s: Driver can only be loaded for 1 device\n",
+			driver_name);
+		err = -EINVAL;
+		goto err_dev;
+	}
+	vme_user_bridge = dev;
+
+	/* Initialise descriptors */
+	for (i = 0; i < VME_DEVS; i++) {
+		image[i].kern_buf = NULL;
+		image[i].pci_buf = 0;
+		init_MUTEX(&(image[i].sem));
+		image[i].device = NULL;
+		image[i].resource = NULL;
+		image[i].users = 0;
+	}
+
+	/* Initialise statistics counters */
+	reset_counters();
+
+	/* Assign major and minor numbers for the driver */
+	err = register_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS,
+		driver_name);
+	if (err) {
+		printk(KERN_WARNING "%s: Error getting Major Number %d for "
+		"driver.\n", driver_name, VME_MAJOR);
+		goto err_region;
+	}
+
+	/* Register the driver as a char device */
+	vme_user_cdev = cdev_alloc();
+	vme_user_cdev->ops = &vme_user_fops;
+	vme_user_cdev->owner = THIS_MODULE;
+	err = cdev_add(vme_user_cdev, MKDEV(VME_MAJOR, 0), VME_DEVS);
+	if (err) {
+		printk(KERN_WARNING "%s: cdev_all failed\n", driver_name);
+		goto err_char;
+	}
+
+	/* Request slave resources and allocate buffers (128kB wide) */
+	for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
+		/* XXX Need to properly request attributes */
+		image[i].resource = vme_slave_request(vme_user_bridge,
+			VME_A16, VME_SCT);
+		if (image[i].resource == NULL) {
+			printk(KERN_WARNING "Unable to allocate slave "
+				"resource\n");
+			goto err_slave;
+		}
+		image[i].size_buf = PCI_BUF_SIZE;
+		image[i].kern_buf = vme_alloc_consistent(image[i].resource,
+			image[i].size_buf, &(image[i].pci_buf));
+		if (image[i].kern_buf == NULL) {
+			printk(KERN_WARNING "Unable to allocate memory for "
+				"buffer\n");
+			image[i].pci_buf = 0;
+			vme_slave_free(image[i].resource);
+			err = -ENOMEM;
+			goto err_slave;
+		}
+	}
+
+	/*
+	 * Request master resources allocate page sized buffers for small
+	 * reads and writes
+	 */
+	for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) {
+		/* XXX Need to properly request attributes */
+		image[i].resource = vme_master_request(vme_user_bridge,
+			VME_A32, VME_SCT, VME_D32);
+		if (image[i].resource == NULL) {
+			printk(KERN_WARNING "Unable to allocate master "
+				"resource\n");
+			goto err_master;
+		}
+	}
+
+	/* Create sysfs entries - on udev systems this creates the dev files */
+	vme_user_sysfs_class = class_create(THIS_MODULE, driver_name);
+	if (IS_ERR(vme_user_sysfs_class)) {
+		printk(KERN_ERR "Error creating vme_user class.\n");
+		err = PTR_ERR(vme_user_sysfs_class);
+		goto err_class;
+	}
+
+	/* Add sysfs Entries */
+	for (i=0; i<VME_DEVS; i++) {
+		switch (type[i]) {
+		case MASTER_MINOR:
+			sprintf(name,"bus/vme/m%%d");
+			break;
+		case CONTROL_MINOR:
+			sprintf(name,"bus/vme/ctl");
+			break;
+		case SLAVE_MINOR:
+			sprintf(name,"bus/vme/s%%d");
+			break;
+		default:
+			err = -EINVAL;
+			goto err_sysfs;
+			break;
+		}
+
+		image[i].device =
+			device_create(vme_user_sysfs_class, NULL,
+				MKDEV(VME_MAJOR, i), NULL, name,
+				(type[i] == SLAVE_MINOR)? i - (MASTER_MAX + 1) : i);
+		if (IS_ERR(image[i].device)) {
+			printk("%s: Error creating sysfs device\n",
+				driver_name);
+			err = PTR_ERR(image[i].device);
+			goto err_sysfs;
+		}
+	}
+
+	return 0;
+
+	/* Ensure counter set correcty to destroy all sysfs devices */
+	i = VME_DEVS;
+err_sysfs:
+	while (i > 0){
+		i--;
+		device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i));
+	}
+	class_destroy(vme_user_sysfs_class);
+
+	/* Ensure counter set correcty to unalloc all master windows */
+	i = MASTER_MAX + 1;
+err_master:
+	while (i > MASTER_MINOR) {
+		i--;
+		vme_master_free(image[i].resource);
+	}
+
+	/*
+	 * Ensure counter set correcty to unalloc all slave windows and buffers
+	 */
+	i = SLAVE_MAX + 1;
+err_slave:
+	while (i > SLAVE_MINOR) {
+		i--;
+		vme_slave_free(image[i].resource);
+		buf_unalloc(i);
+	}
+err_class:
+	cdev_del(vme_user_cdev);
+err_char:
+	unregister_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS);
+err_region:
+err_dev:
+	return err;
+}
+
+static int __exit vme_user_remove(struct device *dev, int cur_bus, int cur_slot)
+{
+	int i;
+
+	/* Remove sysfs Entries */
+	for(i=0; i<VME_DEVS; i++) {
+		device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i));
+	}
+	class_destroy(vme_user_sysfs_class);
+
+	for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) {
+		vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0);
+		vme_slave_free(image[i].resource);
+		buf_unalloc(i);
+	}
+
+	/* Unregister device driver */
+	cdev_del(vme_user_cdev);
+
+	/* Unregiser the major and minor device numbers */
+	unregister_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS);
+
+	return 0;
+}
+
+static void __exit vme_user_exit(void)
+{
+	vme_unregister_driver(&vme_user_driver);
+
+	kfree(vme_user_driver.bind_table);
+}
+
+
+MODULE_PARM_DESC(bus, "Enumeration of VMEbus to which the driver is connected");
+module_param_array(bus, int, &bus_num, 0);
+
+MODULE_DESCRIPTION("VME User Space Access Driver");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_LICENSE("GPL");
+
+module_init(vme_user_init);
+module_exit(vme_user_exit);
diff --git a/drivers/staging/vme/devices/vme_user.h b/drivers/staging/vme/devices/vme_user.h
new file mode 100644
index 0000000..ede77d7
--- /dev/null
+++ b/drivers/staging/vme/devices/vme_user.h
@@ -0,0 +1,52 @@
+#ifndef _VME_USER_H_
+#define _VME_USER_H_
+
+#define USER_BUS_MAX                  1
+
+/*
+ * VMEbus Master Window Configuration Structure
+ */
+struct vme_master {
+	int enable;			/* State of Window */
+	unsigned long long vme_addr;	/* Starting Address on the VMEbus */
+	unsigned long long size;	/* Window Size */
+	vme_address_t aspace;		/* Address Space */
+	vme_cycle_t cycle;		/* Cycle properties */
+	vme_width_t dwidth;		/* Maximum Data Width */
+#if 0
+	char prefetchEnable;		/* Prefetch Read Enable State */
+	int prefetchSize;		/* Prefetch Read Size (Cache Lines) */
+	char wrPostEnable;		/* Write Post State */
+#endif
+};
+
+
+/*
+ * IOCTL Commands and structures
+ */
+
+/* Magic number for use in ioctls */
+#define VME_IOC_MAGIC 0xAE
+
+
+/* VMEbus Slave Window Configuration Structure */
+struct vme_slave {
+	int enable;			/* State of Window */
+	unsigned long long vme_addr;	/* Starting Address on the VMEbus */
+	unsigned long long size;	/* Window Size */
+	vme_address_t aspace;		/* Address Space */
+	vme_cycle_t cycle;		/* Cycle properties */
+#if 0
+	char wrPostEnable;		/* Write Post State */
+	char rmwLock;			/* Lock PCI during RMW Cycles */
+	char data64BitCapable;		/* non-VMEbus capable of 64-bit Data */
+#endif
+};
+
+#define VME_GET_SLAVE _IOR(VME_IOC_MAGIC, 1, struct vme_slave)
+#define VME_SET_SLAVE _IOW(VME_IOC_MAGIC, 2, struct vme_slave)
+#define VME_GET_MASTER _IOR(VME_IOC_MAGIC, 3, struct vme_master)
+#define VME_SET_MASTER _IOW(VME_IOC_MAGIC, 4, struct vme_master)
+
+#endif /* _VME_USER_H_ */
+
diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c
new file mode 100644
index 0000000..477a1ad
--- /dev/null
+++ b/drivers/staging/vme/vme.c
@@ -0,0 +1,1497 @@
+/*
+ * VME Bridge Framework
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * Based on work by Tom Armistead and Ajit Prem
+ * Copyright 2004 Motorola 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/version.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/pagemap.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/syscalls.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
+#include "vme.h"
+#include "vme_bridge.h"
+
+/* Bitmask and mutex to keep track of bridge numbers */
+static unsigned int vme_bus_numbers;
+DEFINE_MUTEX(vme_bus_num_mtx);
+
+static void __exit vme_exit (void);
+static int __init vme_init (void);
+
+
+/*
+ * Find the bridge resource associated with a specific device resource
+ */
+static struct vme_bridge *dev_to_bridge(struct device *dev)
+{
+	return dev->platform_data;
+}
+
+/*
+ * Find the bridge that the resource is associated with.
+ */
+static struct vme_bridge *find_bridge(struct vme_resource *resource)
+{
+	/* Get list to search */
+	switch (resource->type) {
+	case VME_MASTER:
+		return list_entry(resource->entry, struct vme_master_resource,
+			list)->parent;
+		break;
+	case VME_SLAVE:
+		return list_entry(resource->entry, struct vme_slave_resource,
+			list)->parent;
+		break;
+	case VME_DMA:
+		return list_entry(resource->entry, struct vme_dma_resource,
+			list)->parent;
+		break;
+	case VME_LM:
+		return list_entry(resource->entry, struct vme_lm_resource,
+			list)->parent;
+		break;
+	default:
+		printk(KERN_ERR "Unknown resource type\n");
+		return NULL;
+		break;
+	}
+}
+
+/*
+ * Allocate a contiguous block of memory for use by the driver. This is used to
+ * create the buffers for the slave windows.
+ *
+ * XXX VME bridges could be available on buses other than PCI. At the momment
+ *     this framework only supports PCI devices.
+ */
+void * vme_alloc_consistent(struct vme_resource *resource, size_t size,
+	dma_addr_t *dma)
+{
+	struct vme_bridge *bridge;
+	struct pci_dev *pdev;
+
+	if(resource == NULL) {
+		printk("No resource\n");
+		return NULL;
+	}
+
+	bridge = find_bridge(resource);
+	if(bridge == NULL) {
+		printk("Can't find bridge\n");
+		return NULL;
+	}
+
+	/* Find pci_dev container of dev */
+	if (bridge->parent == NULL) {
+		printk("Dev entry NULL\n");
+		return NULL;
+	}
+	pdev = container_of(bridge->parent, struct pci_dev, dev);
+
+	return pci_alloc_consistent(pdev, size, dma);
+}
+EXPORT_SYMBOL(vme_alloc_consistent);
+
+/*
+ * Free previously allocated contiguous block of memory.
+ *
+ * XXX VME bridges could be available on buses other than PCI. At the momment
+ *     this framework only supports PCI devices.
+ */
+void vme_free_consistent(struct vme_resource *resource, size_t size,
+	void *vaddr, dma_addr_t dma)
+{
+	struct vme_bridge *bridge;
+	struct pci_dev *pdev;
+
+	if(resource == NULL) {
+		printk("No resource\n");
+		return;
+	}
+
+	bridge = find_bridge(resource);
+	if(bridge == NULL) {
+		printk("Can't find bridge\n");
+		return;
+	}
+
+	/* Find pci_dev container of dev */
+	pdev = container_of(bridge->parent, struct pci_dev, dev);
+
+	pci_free_consistent(pdev, size, vaddr, dma);
+}
+EXPORT_SYMBOL(vme_free_consistent);
+
+size_t vme_get_size(struct vme_resource *resource)
+{
+	int enabled, retval;
+	unsigned long long base, size;
+	dma_addr_t buf_base;
+	vme_address_t aspace;
+	vme_cycle_t cycle;
+	vme_width_t dwidth;
+
+	switch (resource->type) {
+	case VME_MASTER:
+		retval = vme_master_get(resource, &enabled, &base, &size,
+			&aspace, &cycle, &dwidth);
+
+		return size;
+		break;
+	case VME_SLAVE:
+		retval = vme_slave_get(resource, &enabled, &base, &size,
+			&buf_base, &aspace, &cycle);
+
+		return size;
+		break;
+	case VME_DMA:
+		return 0;
+		break;
+	default:
+		printk(KERN_ERR "Unknown resource type\n");
+		return 0;
+		break;
+	}
+}
+EXPORT_SYMBOL(vme_get_size);
+
+static int vme_check_window(vme_address_t aspace, unsigned long long vme_base,
+	unsigned long long size)
+{
+	int retval = 0;
+
+	switch (aspace) {
+	case VME_A16:
+		if (((vme_base + size) > VME_A16_MAX) ||
+				(vme_base > VME_A16_MAX))
+			retval = -EFAULT;
+		break;
+	case VME_A24:
+		if (((vme_base + size) > VME_A24_MAX) ||
+				(vme_base > VME_A24_MAX))
+			retval = -EFAULT;
+		break;
+	case VME_A32:
+		if (((vme_base + size) > VME_A32_MAX) ||
+				(vme_base > VME_A32_MAX))
+			retval = -EFAULT;
+		break;
+	case VME_A64:
+		/*
+		 * Any value held in an unsigned long long can be used as the
+		 * base
+		 */
+		break;
+	case VME_CRCSR:
+		if (((vme_base + size) > VME_CRCSR_MAX) ||
+				(vme_base > VME_CRCSR_MAX))
+			retval = -EFAULT;
+		break;
+	case VME_USER1:
+	case VME_USER2:
+	case VME_USER3:
+	case VME_USER4:
+		/* User Defined */
+		break;
+	default:
+		printk("Invalid address space\n");
+		retval = -EINVAL;
+		break;
+	}
+
+	return retval;
+}
+
+/*
+ * Request a slave image with specific attributes, return some unique
+ * identifier.
+ */
+struct vme_resource * vme_slave_request(struct device *dev,
+	vme_address_t address, vme_cycle_t cycle)
+{
+	struct vme_bridge *bridge;
+	struct list_head *slave_pos = NULL;
+	struct vme_slave_resource *allocated_image = NULL;
+	struct vme_slave_resource *slave_image = NULL;
+	struct vme_resource *resource = NULL;
+
+	bridge = dev_to_bridge(dev);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		goto err_bus;
+	}
+
+	/* Loop through slave resources */
+	list_for_each(slave_pos, &(bridge->slave_resources)) {
+		slave_image = list_entry(slave_pos,
+			struct vme_slave_resource, list);
+
+		if (slave_image == NULL) {
+			printk("Registered NULL Slave resource\n");
+			continue;
+		}
+
+		/* Find an unlocked and compatible image */
+		mutex_lock(&(slave_image->mtx));
+		if(((slave_image->address_attr & address) == address) &&
+			((slave_image->cycle_attr & cycle) == cycle) &&
+			(slave_image->locked == 0)) {
+
+			slave_image->locked = 1;
+			mutex_unlock(&(slave_image->mtx));
+			allocated_image = slave_image;
+			break;
+		}
+		mutex_unlock(&(slave_image->mtx));
+	}
+
+	/* No free image */
+	if (allocated_image == NULL)
+		goto err_image;
+
+	resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
+	if (resource == NULL) {
+		printk(KERN_WARNING "Unable to allocate resource structure\n");
+		goto err_alloc;
+	}
+	resource->type = VME_SLAVE;
+	resource->entry = &(allocated_image->list);
+
+	return resource;
+
+err_alloc:
+	/* Unlock image */
+	mutex_lock(&(slave_image->mtx));
+	slave_image->locked = 0;
+	mutex_unlock(&(slave_image->mtx));
+err_image:
+err_bus:
+	return NULL;
+}
+EXPORT_SYMBOL(vme_slave_request);
+
+int vme_slave_set (struct vme_resource *resource, int enabled,
+	unsigned long long vme_base, unsigned long long size,
+	dma_addr_t buf_base, vme_address_t aspace, vme_cycle_t cycle)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_slave_resource *image;
+	int retval;
+
+	if (resource->type != VME_SLAVE) {
+		printk("Not a slave resource\n");
+		return -EINVAL;
+	}
+
+	image = list_entry(resource->entry, struct vme_slave_resource, list);
+
+	if (bridge->slave_set == NULL) {
+		printk("Function not supported\n");
+		return -ENOSYS;
+	}
+
+	if(!(((image->address_attr & aspace) == aspace) &&
+		((image->cycle_attr & cycle) == cycle))) {
+		printk("Invalid attributes\n");
+		return -EINVAL;
+	}
+
+	retval = vme_check_window(aspace, vme_base, size);
+	if(retval)
+		return retval;
+
+	return bridge->slave_set(image, enabled, vme_base, size, buf_base,
+		aspace, cycle);
+}
+EXPORT_SYMBOL(vme_slave_set);
+
+int vme_slave_get (struct vme_resource *resource, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	dma_addr_t *buf_base, vme_address_t *aspace, vme_cycle_t *cycle)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_slave_resource *image;
+
+	if (resource->type != VME_SLAVE) {
+		printk("Not a slave resource\n");
+		return -EINVAL;
+	}
+
+	image = list_entry(resource->entry, struct vme_slave_resource, list);
+
+	if (bridge->slave_get == NULL) {
+		printk("vme_slave_get not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->slave_get(image, enabled, vme_base, size, buf_base,
+		aspace, cycle);
+}
+EXPORT_SYMBOL(vme_slave_get);
+
+void vme_slave_free(struct vme_resource *resource)
+{
+	struct vme_slave_resource *slave_image;
+
+	if (resource->type != VME_SLAVE) {
+		printk("Not a slave resource\n");
+		return;
+	}
+
+	slave_image = list_entry(resource->entry, struct vme_slave_resource,
+		list);
+	if (slave_image == NULL) {
+		printk("Can't find slave resource\n");
+		return;
+	}
+
+	/* Unlock image */
+	mutex_lock(&(slave_image->mtx));
+	if (slave_image->locked == 0)
+		printk(KERN_ERR "Image is already free\n");
+
+	slave_image->locked = 0;
+	mutex_unlock(&(slave_image->mtx));
+
+	/* Free up resource memory */
+	kfree(resource);
+}
+EXPORT_SYMBOL(vme_slave_free);
+
+/*
+ * Request a master image with specific attributes, return some unique
+ * identifier.
+ */
+struct vme_resource * vme_master_request(struct device *dev,
+	vme_address_t address, vme_cycle_t cycle, vme_width_t dwidth)
+{
+	struct vme_bridge *bridge;
+	struct list_head *master_pos = NULL;
+	struct vme_master_resource *allocated_image = NULL;
+	struct vme_master_resource *master_image = NULL;
+	struct vme_resource *resource = NULL;
+
+	bridge = dev_to_bridge(dev);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		goto err_bus;
+	}
+
+	/* Loop through master resources */
+	list_for_each(master_pos, &(bridge->master_resources)) {
+		master_image = list_entry(master_pos,
+			struct vme_master_resource, list);
+
+		if (master_image == NULL) {
+			printk(KERN_WARNING "Registered NULL master resource\n");
+			continue;
+		}
+
+		/* Find an unlocked and compatible image */
+		spin_lock(&(master_image->lock));
+		if(((master_image->address_attr & address) == address) &&
+			((master_image->cycle_attr & cycle) == cycle) &&
+			((master_image->width_attr & dwidth) == dwidth) &&
+			(master_image->locked == 0)) {
+
+			master_image->locked = 1;
+			spin_unlock(&(master_image->lock));
+			allocated_image = master_image;
+			break;
+		}
+		spin_unlock(&(master_image->lock));
+	}
+
+	/* Check to see if we found a resource */
+	if (allocated_image == NULL) {
+		printk(KERN_ERR "Can't find a suitable resource\n");
+		goto err_image;
+	}
+
+	resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
+	if (resource == NULL) {
+		printk(KERN_ERR "Unable to allocate resource structure\n");
+		goto err_alloc;
+	}
+	resource->type = VME_MASTER;
+	resource->entry = &(allocated_image->list);
+
+	return resource;
+
+	kfree(resource);
+err_alloc:
+	/* Unlock image */
+	spin_lock(&(master_image->lock));
+	master_image->locked = 0;
+	spin_unlock(&(master_image->lock));
+err_image:
+err_bus:
+	return NULL;
+}
+EXPORT_SYMBOL(vme_master_request);
+
+int vme_master_set (struct vme_resource *resource, int enabled,
+	unsigned long long vme_base, unsigned long long size,
+	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_master_resource *image;
+	int retval;
+
+	if (resource->type != VME_MASTER) {
+		printk("Not a master resource\n");
+		return -EINVAL;
+	}
+
+	image = list_entry(resource->entry, struct vme_master_resource, list);
+
+	if (bridge->master_set == NULL) {
+		printk("vme_master_set not supported\n");
+		return -EINVAL;
+	}
+
+	if(!(((image->address_attr & aspace) == aspace) &&
+		((image->cycle_attr & cycle) == cycle) &&
+		((image->width_attr & dwidth) == dwidth))) {
+		printk("Invalid attributes\n");
+		return -EINVAL;
+	}
+
+	retval = vme_check_window(aspace, vme_base, size);
+	if(retval)
+		return retval;
+
+	return bridge->master_set(image, enabled, vme_base, size, aspace,
+		cycle, dwidth);
+}
+EXPORT_SYMBOL(vme_master_set);
+
+int vme_master_get (struct vme_resource *resource, int *enabled,
+	unsigned long long *vme_base, unsigned long long *size,
+	vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_master_resource *image;
+
+	if (resource->type != VME_MASTER) {
+		printk("Not a master resource\n");
+		return -EINVAL;
+	}
+
+	image = list_entry(resource->entry, struct vme_master_resource, list);
+
+	if (bridge->master_get == NULL) {
+		printk("vme_master_set not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->master_get(image, enabled, vme_base, size, aspace,
+		cycle, dwidth);
+}
+EXPORT_SYMBOL(vme_master_get);
+
+/*
+ * Read data out of VME space into a buffer.
+ */
+ssize_t vme_master_read (struct vme_resource *resource, void *buf, size_t count,
+	loff_t offset)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_master_resource *image;
+	size_t length;
+
+	if (bridge->master_read == NULL) {
+		printk("Reading from resource not supported\n");
+		return -EINVAL;
+	}
+
+	if (resource->type != VME_MASTER) {
+		printk("Not a master resource\n");
+		return -EINVAL;
+	}
+
+	image = list_entry(resource->entry, struct vme_master_resource, list);
+
+	length = vme_get_size(resource);
+
+	if (offset > length) {
+		printk("Invalid Offset\n");
+		return -EFAULT;
+	}
+
+	if ((offset + count) > length)
+		count = length - offset;
+
+	return bridge->master_read(image, buf, count, offset);
+
+}
+EXPORT_SYMBOL(vme_master_read);
+
+/*
+ * Write data out to VME space from a buffer.
+ */
+ssize_t vme_master_write (struct vme_resource *resource, void *buf,
+	size_t count, loff_t offset)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_master_resource *image;
+	size_t length;
+
+	if (bridge->master_write == NULL) {
+		printk("Writing to resource not supported\n");
+		return -EINVAL;
+	}
+
+	if (resource->type != VME_MASTER) {
+		printk("Not a master resource\n");
+		return -EINVAL;
+	}
+
+	image = list_entry(resource->entry, struct vme_master_resource, list);
+
+	length = vme_get_size(resource);
+
+	if (offset > length) {
+		printk("Invalid Offset\n");
+		return -EFAULT;
+	}
+
+	if ((offset + count) > length)
+		count = length - offset;
+
+	return bridge->master_write(image, buf, count, offset);
+}
+EXPORT_SYMBOL(vme_master_write);
+
+/*
+ * Perform RMW cycle to provided location.
+ */
+unsigned int vme_master_rmw (struct vme_resource *resource, unsigned int mask,
+	unsigned int compare, unsigned int swap, loff_t offset)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_master_resource *image;
+
+	if (bridge->master_rmw == NULL) {
+		printk("Writing to resource not supported\n");
+		return -EINVAL;
+	}
+
+	if (resource->type != VME_MASTER) {
+		printk("Not a master resource\n");
+		return -EINVAL;
+	}
+
+	image = list_entry(resource->entry, struct vme_master_resource, list);
+
+	return bridge->master_rmw(image, mask, compare, swap, offset);
+}
+EXPORT_SYMBOL(vme_master_rmw);
+
+void vme_master_free(struct vme_resource *resource)
+{
+	struct vme_master_resource *master_image;
+
+	if (resource->type != VME_MASTER) {
+		printk("Not a master resource\n");
+		return;
+	}
+
+	master_image = list_entry(resource->entry, struct vme_master_resource,
+		list);
+	if (master_image == NULL) {
+		printk("Can't find master resource\n");
+		return;
+	}
+
+	/* Unlock image */
+	spin_lock(&(master_image->lock));
+	if (master_image->locked == 0)
+		printk(KERN_ERR "Image is already free\n");
+
+	master_image->locked = 0;
+	spin_unlock(&(master_image->lock));
+
+	/* Free up resource memory */
+	kfree(resource);
+}
+EXPORT_SYMBOL(vme_master_free);
+
+/*
+ * Request a DMA controller with specific attributes, return some unique
+ * identifier.
+ */
+struct vme_resource *vme_request_dma(struct device *dev)
+{
+	struct vme_bridge *bridge;
+	struct list_head *dma_pos = NULL;
+	struct vme_dma_resource *allocated_ctrlr = NULL;
+	struct vme_dma_resource *dma_ctrlr = NULL;
+	struct vme_resource *resource = NULL;
+
+	/* XXX Not checking resource attributes */
+	printk(KERN_ERR "No VME resource Attribute tests done\n");
+
+	bridge = dev_to_bridge(dev);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		goto err_bus;
+	}
+
+	/* Loop through DMA resources */
+	list_for_each(dma_pos, &(bridge->dma_resources)) {
+		dma_ctrlr = list_entry(dma_pos,
+			struct vme_dma_resource, list);
+
+		if (dma_ctrlr == NULL) {
+			printk("Registered NULL DMA resource\n");
+			continue;
+		}
+
+		/* Find an unlocked controller */
+		mutex_lock(&(dma_ctrlr->mtx));
+		if(dma_ctrlr->locked == 0) {
+			dma_ctrlr->locked = 1;
+			mutex_unlock(&(dma_ctrlr->mtx));
+			allocated_ctrlr = dma_ctrlr;
+			break;
+		}
+		mutex_unlock(&(dma_ctrlr->mtx));
+	}
+
+	/* Check to see if we found a resource */
+	if (allocated_ctrlr == NULL)
+		goto err_ctrlr;
+
+	resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
+	if (resource == NULL) {
+		printk(KERN_WARNING "Unable to allocate resource structure\n");
+		goto err_alloc;
+	}
+	resource->type = VME_DMA;
+	resource->entry = &(allocated_ctrlr->list);
+
+	return resource;
+
+err_alloc:
+	/* Unlock image */
+	mutex_lock(&(dma_ctrlr->mtx));
+	dma_ctrlr->locked = 0;
+	mutex_unlock(&(dma_ctrlr->mtx));
+err_ctrlr:
+err_bus:
+	return NULL;
+}
+EXPORT_SYMBOL(vme_request_dma);
+
+/*
+ * Start new list
+ */
+struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource)
+{
+	struct vme_dma_resource *ctrlr;
+	struct vme_dma_list *dma_list;
+
+	if (resource->type != VME_DMA) {
+		printk("Not a DMA resource\n");
+		return NULL;
+	}
+
+	ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
+
+	dma_list = (struct vme_dma_list *)kmalloc(
+		sizeof(struct vme_dma_list), GFP_KERNEL);
+	if(dma_list == NULL) {
+		printk("Unable to allocate memory for new dma list\n");
+		return NULL;
+	}
+	INIT_LIST_HEAD(&(dma_list->entries));
+	dma_list->parent = ctrlr;
+	mutex_init(&(dma_list->mtx));
+
+	return dma_list;
+}
+EXPORT_SYMBOL(vme_new_dma_list);
+
+/*
+ * Create "Pattern" type attributes
+ */
+struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern,
+	vme_pattern_t type)
+{
+	struct vme_dma_attr *attributes;
+	struct vme_dma_pattern *pattern_attr;
+
+	attributes = (struct vme_dma_attr *)kmalloc(
+		sizeof(struct vme_dma_attr), GFP_KERNEL);
+	if(attributes == NULL) {
+		printk("Unable to allocate memory for attributes structure\n");
+		goto err_attr;
+	}
+
+	pattern_attr = (struct vme_dma_pattern *)kmalloc(
+		sizeof(struct vme_dma_pattern), GFP_KERNEL);
+	if(pattern_attr == NULL) {
+		printk("Unable to allocate memory for pattern attributes\n");
+		goto err_pat;
+	}
+
+	attributes->type = VME_DMA_PATTERN;
+	attributes->private = (void *)pattern_attr;
+
+	pattern_attr->pattern = pattern;
+	pattern_attr->type = type;
+
+	return attributes;
+
+	kfree(pattern_attr);
+err_pat:
+	kfree(attributes);
+err_attr:
+	return NULL;
+}
+EXPORT_SYMBOL(vme_dma_pattern_attribute);
+
+/*
+ * Create "PCI" type attributes
+ */
+struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address)
+{
+	struct vme_dma_attr *attributes;
+	struct vme_dma_pci *pci_attr;
+
+	/* XXX Run some sanity checks here */
+
+	attributes = (struct vme_dma_attr *)kmalloc(
+		sizeof(struct vme_dma_attr), GFP_KERNEL);
+	if(attributes == NULL) {
+		printk("Unable to allocate memory for attributes structure\n");
+		goto err_attr;
+	}
+
+	pci_attr = (struct vme_dma_pci *)kmalloc(sizeof(struct vme_dma_pci),
+		GFP_KERNEL);
+	if(pci_attr == NULL) {
+		printk("Unable to allocate memory for pci attributes\n");
+		goto err_pci;
+	}
+
+
+
+	attributes->type = VME_DMA_PCI;
+	attributes->private = (void *)pci_attr;
+
+	pci_attr->address = address;
+
+	return attributes;
+
+	kfree(pci_attr);
+err_pci:
+	kfree(attributes);
+err_attr:
+	return NULL;
+}
+EXPORT_SYMBOL(vme_dma_pci_attribute);
+
+/*
+ * Create "VME" type attributes
+ */
+struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address,
+	vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth)
+{
+	struct vme_dma_attr *attributes;
+	struct vme_dma_vme *vme_attr;
+
+	/* XXX Run some sanity checks here */
+
+	attributes = (struct vme_dma_attr *)kmalloc(
+		sizeof(struct vme_dma_attr), GFP_KERNEL);
+	if(attributes == NULL) {
+		printk("Unable to allocate memory for attributes structure\n");
+		goto err_attr;
+	}
+
+	vme_attr = (struct vme_dma_vme *)kmalloc(sizeof(struct vme_dma_vme),
+		GFP_KERNEL);
+	if(vme_attr == NULL) {
+		printk("Unable to allocate memory for vme attributes\n");
+		goto err_vme;
+	}
+
+	attributes->type = VME_DMA_VME;
+	attributes->private = (void *)vme_attr;
+
+	vme_attr->address = address;
+	vme_attr->aspace = aspace;
+	vme_attr->cycle = cycle;
+	vme_attr->dwidth = dwidth;
+
+	return attributes;
+
+	kfree(vme_attr);
+err_vme:
+	kfree(attributes);
+err_attr:
+	return NULL;
+}
+EXPORT_SYMBOL(vme_dma_vme_attribute);
+
+/*
+ * Free attribute
+ */
+void vme_dma_free_attribute(struct vme_dma_attr *attributes)
+{
+	kfree(attributes->private);
+	kfree(attributes);
+}
+EXPORT_SYMBOL(vme_dma_free_attribute);
+
+int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src,
+	struct vme_dma_attr *dest, size_t count)
+{
+	struct vme_bridge *bridge = list->parent->parent;
+	int retval;
+
+	if (bridge->dma_list_add == NULL) {
+		printk("Link List DMA generation not supported\n");
+		return -EINVAL;
+	}
+
+	if (mutex_trylock(&(list->mtx))) {
+		printk("Link List already submitted\n");
+		return -EINVAL;
+	}
+
+	retval = bridge->dma_list_add(list, src, dest, count);
+
+	mutex_unlock(&(list->mtx));
+
+	return retval;
+}
+EXPORT_SYMBOL(vme_dma_list_add);
+
+int vme_dma_list_exec(struct vme_dma_list *list)
+{
+	struct vme_bridge *bridge = list->parent->parent;
+	int retval;
+
+	if (bridge->dma_list_exec == NULL) {
+		printk("Link List DMA execution not supported\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&(list->mtx));
+
+	retval = bridge->dma_list_exec(list);
+
+	mutex_unlock(&(list->mtx));
+
+	return retval;
+}
+EXPORT_SYMBOL(vme_dma_list_exec);
+
+int vme_dma_list_free(struct vme_dma_list *list)
+{
+	struct vme_bridge *bridge = list->parent->parent;
+	int retval;
+
+	if (bridge->dma_list_empty == NULL) {
+		printk("Emptying of Link Lists not supported\n");
+		return -EINVAL;
+	}
+
+	if (mutex_trylock(&(list->mtx))) {
+		printk("Link List in use\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Empty out all of the entries from the dma list. We need to go to the
+	 * low level driver as dma entries are driver specific.
+	 */
+	retval = bridge->dma_list_empty(list);
+	if (retval) {
+		printk("Unable to empty link-list entries\n");
+		mutex_unlock(&(list->mtx));
+		return retval;
+	}
+	mutex_unlock(&(list->mtx));
+	kfree(list);
+
+	return retval;
+}
+EXPORT_SYMBOL(vme_dma_list_free);
+
+int vme_dma_free(struct vme_resource *resource)
+{
+	struct vme_dma_resource *ctrlr;
+
+	if (resource->type != VME_DMA) {
+		printk("Not a DMA resource\n");
+		return -EINVAL;
+	}
+
+	ctrlr = list_entry(resource->entry, struct vme_dma_resource, list);
+
+	if (mutex_trylock(&(ctrlr->mtx))) {
+		printk("Resource busy, can't free\n");
+		return -EBUSY;
+	}
+
+	if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) {
+		printk("Resource still processing transfers\n");
+		mutex_unlock(&(ctrlr->mtx));
+		return -EBUSY;
+	}
+
+	ctrlr->locked = 0;
+
+	mutex_unlock(&(ctrlr->mtx));
+
+	return 0;
+}
+EXPORT_SYMBOL(vme_dma_free);
+
+int vme_request_irq(struct device *dev, int level, int statid,
+	void (*callback)(int level, int vector, void *priv_data),
+	void *priv_data)
+{
+	struct vme_bridge *bridge;
+
+	bridge = dev_to_bridge(dev);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		return -EINVAL;
+	}
+
+	if((level < 1) || (level > 7)) {
+		printk(KERN_WARNING "Invalid interrupt level\n");
+		return -EINVAL;
+	}
+
+	if (bridge->request_irq == NULL) {
+		printk("Registering interrupts not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->request_irq(level, statid, callback, priv_data);
+}
+EXPORT_SYMBOL(vme_request_irq);
+
+void vme_free_irq(struct device *dev, int level, int statid)
+{
+	struct vme_bridge *bridge;
+
+	bridge = dev_to_bridge(dev);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		return;
+	}
+
+	if((level < 1) || (level > 7)) {
+		printk(KERN_WARNING "Invalid interrupt level\n");
+		return;
+	}
+
+	if (bridge->free_irq == NULL) {
+		printk("Freeing interrupts not supported\n");
+		return;
+	}
+
+	bridge->free_irq(level, statid);
+}
+EXPORT_SYMBOL(vme_free_irq);
+
+int vme_generate_irq(struct device *dev, int level, int statid)
+{
+	struct vme_bridge *bridge;
+
+	bridge = dev_to_bridge(dev);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		return -EINVAL;
+	}
+
+	if((level < 1) || (level > 7)) {
+		printk(KERN_WARNING "Invalid interrupt level\n");
+		return -EINVAL;
+	}
+
+	if (bridge->generate_irq == NULL) {
+		printk("Interrupt generation not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->generate_irq(level, statid);
+}
+EXPORT_SYMBOL(vme_generate_irq);
+
+/*
+ * Request the location monitor, return resource or NULL
+ */
+struct vme_resource *vme_lm_request(struct device *dev)
+{
+	struct vme_bridge *bridge;
+	struct list_head *lm_pos = NULL;
+	struct vme_lm_resource *allocated_lm = NULL;
+	struct vme_lm_resource *lm = NULL;
+	struct vme_resource *resource = NULL;
+
+	bridge = dev_to_bridge(dev);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		goto err_bus;
+	}
+
+	/* Loop through DMA resources */
+	list_for_each(lm_pos, &(bridge->lm_resources)) {
+		lm = list_entry(lm_pos,
+			struct vme_lm_resource, list);
+
+		if (lm == NULL) {
+			printk(KERN_ERR "Registered NULL Location Monitor "
+				"resource\n");
+			continue;
+		}
+
+		/* Find an unlocked controller */
+		mutex_lock(&(lm->mtx));
+		if (lm->locked == 0) {
+			lm->locked = 1;
+			mutex_unlock(&(lm->mtx));
+			allocated_lm = lm;
+			break;
+		}
+		mutex_unlock(&(lm->mtx));
+	}
+
+	/* Check to see if we found a resource */
+	if (allocated_lm == NULL)
+		goto err_lm;
+
+	resource = kmalloc(sizeof(struct vme_resource), GFP_KERNEL);
+	if (resource == NULL) {
+		printk(KERN_ERR "Unable to allocate resource structure\n");
+		goto err_alloc;
+	}
+	resource->type = VME_LM;
+	resource->entry = &(allocated_lm->list);
+
+	return resource;
+
+err_alloc:
+	/* Unlock image */
+	mutex_lock(&(lm->mtx));
+	lm->locked = 0;
+	mutex_unlock(&(lm->mtx));
+err_lm:
+err_bus:
+	return NULL;
+}
+EXPORT_SYMBOL(vme_lm_request);
+
+int vme_lm_count(struct vme_resource *resource)
+{
+	struct vme_lm_resource *lm;
+
+	if (resource->type != VME_LM) {
+		printk(KERN_ERR "Not a Location Monitor resource\n");
+		return -EINVAL;
+	}
+
+	lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+	return lm->monitors;
+}
+EXPORT_SYMBOL(vme_lm_count);
+
+int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base,
+	vme_address_t aspace, vme_cycle_t cycle)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_lm_resource *lm;
+
+	if (resource->type != VME_LM) {
+		printk(KERN_ERR "Not a Location Monitor resource\n");
+		return -EINVAL;
+	}
+
+	lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+	if (bridge->lm_set == NULL) {
+		printk(KERN_ERR "vme_lm_set not supported\n");
+		return -EINVAL;
+	}
+
+	/* XXX Check parameters */
+
+	return lm->parent->lm_set(lm, lm_base, aspace, cycle);
+}
+EXPORT_SYMBOL(vme_lm_set);
+
+int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base,
+	vme_address_t *aspace, vme_cycle_t *cycle)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_lm_resource *lm;
+
+	if (resource->type != VME_LM) {
+		printk(KERN_ERR "Not a Location Monitor resource\n");
+		return -EINVAL;
+	}
+
+	lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+	if (bridge->lm_get == NULL) {
+		printk(KERN_ERR "vme_lm_get not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->lm_get(lm, lm_base, aspace, cycle);
+}
+EXPORT_SYMBOL(vme_lm_get);
+
+int vme_lm_attach(struct vme_resource *resource, int monitor,
+	void (*callback)(int))
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_lm_resource *lm;
+
+	if (resource->type != VME_LM) {
+		printk(KERN_ERR "Not a Location Monitor resource\n");
+		return -EINVAL;
+	}
+
+	lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+	if (bridge->lm_attach == NULL) {
+		printk(KERN_ERR "vme_lm_attach not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->lm_attach(lm, monitor, callback);
+}
+EXPORT_SYMBOL(vme_lm_attach);
+
+int vme_lm_detach(struct vme_resource *resource, int monitor)
+{
+	struct vme_bridge *bridge = find_bridge(resource);
+	struct vme_lm_resource *lm;
+
+	if (resource->type != VME_LM) {
+		printk(KERN_ERR "Not a Location Monitor resource\n");
+		return -EINVAL;
+	}
+
+	lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+	if (bridge->lm_detach == NULL) {
+		printk(KERN_ERR "vme_lm_detach not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->lm_detach(lm, monitor);
+}
+EXPORT_SYMBOL(vme_lm_detach);
+
+void vme_lm_free(struct vme_resource *resource)
+{
+	struct vme_lm_resource *lm;
+
+	if (resource->type != VME_LM) {
+		printk(KERN_ERR "Not a Location Monitor resource\n");
+		return;
+	}
+
+	lm = list_entry(resource->entry, struct vme_lm_resource, list);
+
+	if (mutex_trylock(&(lm->mtx))) {
+		printk(KERN_ERR "Resource busy, can't free\n");
+		return;
+	}
+
+	/* XXX Check to see that there aren't any callbacks still attached */
+
+	lm->locked = 0;
+
+	mutex_unlock(&(lm->mtx));
+}
+EXPORT_SYMBOL(vme_lm_free);
+
+int vme_slot_get(struct device *bus)
+{
+	struct vme_bridge *bridge;
+
+	bridge = dev_to_bridge(bus);
+	if (bridge == NULL) {
+		printk(KERN_ERR "Can't find VME bus\n");
+		return -EINVAL;
+	}
+
+	if (bridge->slot_get == NULL) {
+		printk("vme_slot_get not supported\n");
+		return -EINVAL;
+	}
+
+	return bridge->slot_get();
+}
+EXPORT_SYMBOL(vme_slot_get);
+
+
+/* - Bridge Registration --------------------------------------------------- */
+
+static int vme_alloc_bus_num(void)
+{
+	int i;
+
+	mutex_lock(&vme_bus_num_mtx);
+	for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) {
+		if (((vme_bus_numbers >> i) & 0x1) == 0) {
+			vme_bus_numbers |= (0x1 << i);
+			break;
+		}
+	}
+	mutex_unlock(&vme_bus_num_mtx);
+
+	return i;
+}
+
+static void vme_free_bus_num(int bus)
+{
+	mutex_lock(&vme_bus_num_mtx);
+	vme_bus_numbers |= ~(0x1 << bus);
+	mutex_unlock(&vme_bus_num_mtx);
+}
+
+int vme_register_bridge (struct vme_bridge *bridge)
+{
+	struct device *dev;
+	int retval;
+	int i;
+
+	bridge->num = vme_alloc_bus_num();
+
+	/* This creates 32 vme "slot" devices. This equates to a slot for each
+	 * ID available in a system conforming to the ANSI/VITA 1-1994
+	 * specification.
+	 */
+	for (i = 0; i < VME_SLOTS_MAX; i++) {
+		dev = &(bridge->dev[i]);
+		memset(dev, 0, sizeof(struct device));
+
+		dev->parent = bridge->parent;
+		dev->bus = &(vme_bus_type);
+		/*
+		 * We save a pointer to the bridge in platform_data so that we
+		 * can get to it later. We keep driver_data for use by the
+		 * driver that binds against the slot
+		 */
+		dev->platform_data = bridge;
+		dev_set_name(dev, "vme-%x.%x", bridge->num, i + 1);
+
+		retval = device_register(dev);
+		if(retval)
+			goto err_reg;
+	}
+
+	return retval;
+
+	i = VME_SLOTS_MAX;
+err_reg:
+	while (i > -1) {
+		dev = &(bridge->dev[i]);
+		device_unregister(dev);
+	}
+	vme_free_bus_num(bridge->num);
+	return retval;
+}
+EXPORT_SYMBOL(vme_register_bridge);
+
+void vme_unregister_bridge (struct vme_bridge *bridge)
+{
+	int i;
+	struct device *dev;
+
+
+	for (i = 0; i < VME_SLOTS_MAX; i++) {
+		dev = &(bridge->dev[i]);
+		device_unregister(dev);
+	}
+	vme_free_bus_num(bridge->num);
+}
+EXPORT_SYMBOL(vme_unregister_bridge);
+
+
+/* - Driver Registration --------------------------------------------------- */
+
+int vme_register_driver (struct vme_driver *drv)
+{
+	drv->driver.name = drv->name;
+	drv->driver.bus = &vme_bus_type;
+
+	return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL(vme_register_driver);
+
+void vme_unregister_driver (struct vme_driver *drv)
+{
+	driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL(vme_unregister_driver);
+
+/* - Bus Registration ------------------------------------------------------ */
+
+int vme_calc_slot(struct device *dev)
+{
+	struct vme_bridge *bridge;
+	int num;
+
+	bridge = dev_to_bridge(dev);
+
+	/* Determine slot number */
+	num = 0;
+	while(num < VME_SLOTS_MAX) {
+		if(&(bridge->dev[num]) == dev) {
+			break;
+		}
+		num++;
+	}
+	if (num == VME_SLOTS_MAX) {
+		dev_err(dev, "Failed to identify slot\n");
+		num = 0;
+		goto err_dev;
+	}
+	num++;
+
+err_dev:
+	return num;
+}
+
+static struct vme_driver *dev_to_vme_driver(struct device *dev)
+{
+	if(dev->driver == NULL)
+		printk("Bugger dev->driver is NULL\n");
+
+	return container_of(dev->driver, struct vme_driver, driver);
+}
+
+static int vme_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct vme_bridge *bridge;
+	struct vme_driver *driver;
+	int i, num;
+
+	bridge = dev_to_bridge(dev);
+	driver = container_of(drv, struct vme_driver, driver);
+
+	num = vme_calc_slot(dev);
+	if (!num)
+		goto err_dev;
+
+	if (driver->bind_table == NULL) {
+		dev_err(dev, "Bind table NULL\n");
+		goto err_table;
+	}
+
+	i = 0;
+	while((driver->bind_table[i].bus != 0) ||
+		(driver->bind_table[i].slot != 0)) {
+
+		if (bridge->num == driver->bind_table[i].bus) {
+			if (num == driver->bind_table[i].slot)
+				return 1;
+
+			if (driver->bind_table[i].slot == VME_SLOT_ALL)
+				return 1;
+
+			if ((driver->bind_table[i].slot == VME_SLOT_CURRENT) &&
+				(num == vme_slot_get(dev)))
+				return 1;
+		}
+		i++;
+	}
+
+err_dev:
+err_table:
+	return 0;
+}
+
+static int vme_bus_probe(struct device *dev)
+{
+	struct vme_bridge *bridge;
+	struct vme_driver *driver;
+	int retval = -ENODEV;
+
+	driver = dev_to_vme_driver(dev);
+	bridge = dev_to_bridge(dev);
+
+	if(driver->probe != NULL) {
+		retval = driver->probe(dev, bridge->num, vme_calc_slot(dev));
+	}
+
+	return retval;
+}
+
+static int vme_bus_remove(struct device *dev)
+{
+	struct vme_bridge *bridge;
+	struct vme_driver *driver;
+	int retval = -ENODEV;
+
+	driver = dev_to_vme_driver(dev);
+	bridge = dev_to_bridge(dev);
+
+	if(driver->remove != NULL) {
+		retval = driver->remove(dev, bridge->num, vme_calc_slot(dev));
+	}
+
+	return retval;
+}
+
+struct bus_type vme_bus_type = {
+	.name = "vme",
+	.match = vme_bus_match,
+	.probe = vme_bus_probe,
+	.remove = vme_bus_remove,
+};
+EXPORT_SYMBOL(vme_bus_type);
+
+static int __init vme_init (void)
+{
+	return bus_register(&vme_bus_type);
+}
+
+static void __exit vme_exit (void)
+{
+	bus_unregister(&vme_bus_type);
+}
+
+MODULE_DESCRIPTION("VME bridge driver framework");
+MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com");
+MODULE_LICENSE("GPL");
+
+module_init(vme_init);
+module_exit(vme_exit);
diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h
new file mode 100644
index 0000000..6206e91
--- /dev/null
+++ b/drivers/staging/vme/vme.h
@@ -0,0 +1,161 @@
+#ifndef _VME_H_
+#define _VME_H_
+
+/* Resource Type */
+enum vme_resource_type {
+	VME_MASTER,
+	VME_SLAVE,
+	VME_DMA,
+	VME_LM
+};
+
+/* VME Address Spaces */
+typedef u32 vme_address_t;
+#define VME_A16		0x1
+#define VME_A24		0x2
+#define	VME_A32		0x4
+#define VME_A64		0x8
+#define VME_CRCSR	0x10
+#define VME_USER1	0x20
+#define VME_USER2	0x40
+#define VME_USER3	0x80
+#define VME_USER4	0x100
+
+#define VME_A16_MAX	0x10000ULL
+#define VME_A24_MAX	0x1000000ULL
+#define VME_A32_MAX	0x100000000ULL
+#define VME_A64_MAX	0x10000000000000000ULL
+#define VME_CRCSR_MAX	0x1000000ULL
+
+
+/* VME Cycle Types */
+typedef u32 vme_cycle_t;
+#define VME_SCT		0x1
+#define VME_BLT		0x2
+#define VME_MBLT	0x4
+#define VME_2eVME	0x8
+#define VME_2eSST	0x10
+#define VME_2eSSTB	0x20
+
+#define VME_2eSST160	0x100
+#define VME_2eSST267	0x200
+#define VME_2eSST320	0x400
+
+#define	VME_SUPER	0x1000
+#define	VME_USER	0x2000
+#define	VME_PROG	0x4000
+#define	VME_DATA	0x8000
+
+/* VME Data Widths */
+typedef u32 vme_width_t;
+#define VME_D8		0x1
+#define VME_D16		0x2
+#define VME_D32		0x4
+#define VME_D64		0x8
+
+/* Arbitration Scheduling Modes */
+typedef u32 vme_arbitration_t;
+#define VME_R_ROBIN_MODE	0x1
+#define VME_PRIORITY_MODE	0x2
+
+typedef u32 vme_dma_t;
+#define VME_DMA_PATTERN			(1<<0)
+#define VME_DMA_PCI			(1<<1)
+#define VME_DMA_VME			(1<<2)
+
+typedef u32 vme_pattern_t;
+#define VME_DMA_PATTERN_BYTE		(1<<0)
+#define VME_DMA_PATTERN_WORD		(1<<1)
+#define VME_DMA_PATTERN_INCREMENT	(1<<2)
+
+struct vme_dma_attr {
+	vme_dma_t type;
+	void *private;
+};
+
+struct vme_resource {
+	enum vme_resource_type type;
+	struct list_head *entry;
+};
+
+extern struct bus_type vme_bus_type;
+
+#define VME_SLOT_CURRENT	-1
+#define VME_SLOT_ALL		-2
+
+struct vme_device_id {
+	int bus;
+	int slot;
+};
+
+struct vme_driver {
+	struct list_head node;
+	char *name;
+	const struct vme_device_id *bind_table;
+	int (*probe)  (struct device *, int, int);
+	int (*remove) (struct device *, int, int);
+	void (*shutdown) (void);
+	struct device_driver    driver;
+};
+
+void * vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *);
+void vme_free_consistent(struct vme_resource *, size_t,  void *,
+	dma_addr_t);
+
+size_t vme_get_size(struct vme_resource *);
+
+struct vme_resource * vme_slave_request(struct device *, vme_address_t, vme_cycle_t);
+int vme_slave_set (struct vme_resource *, int, unsigned long long,
+	unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
+int vme_slave_get (struct vme_resource *, int *, unsigned long long *,
+	unsigned long long *, dma_addr_t *, vme_address_t *, vme_cycle_t *);
+void vme_slave_free(struct vme_resource *);
+
+struct vme_resource * vme_master_request(struct device *, vme_address_t, vme_cycle_t,
+	vme_width_t);
+int vme_master_set (struct vme_resource *, int, unsigned long long,
+	unsigned long long, vme_address_t, vme_cycle_t, vme_width_t);
+int vme_master_get (struct vme_resource *, int *, unsigned long long *,
+	unsigned long long *, vme_address_t *, vme_cycle_t *, vme_width_t *);
+ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t);
+ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t);
+unsigned int vme_master_rmw (struct vme_resource *, unsigned int, unsigned int,
+	unsigned int, loff_t);
+void vme_master_free(struct vme_resource *);
+
+struct vme_resource *vme_request_dma(struct device *);
+struct vme_dma_list *vme_new_dma_list(struct vme_resource *);
+struct vme_dma_attr *vme_dma_pattern_attribute(u32, vme_pattern_t);
+struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t);
+struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long, vme_address_t,
+	vme_cycle_t, vme_width_t);
+void vme_dma_free_attribute(struct vme_dma_attr *);
+int vme_dma_list_add(struct vme_dma_list *, struct vme_dma_attr *,
+	struct vme_dma_attr *, size_t);
+int vme_dma_list_exec(struct vme_dma_list *);
+int vme_dma_list_free(struct vme_dma_list *);
+int vme_dma_free(struct vme_resource *);
+
+int vme_request_irq(struct device *, int, int,
+	void (*callback)(int, int, void *), void *);
+void vme_free_irq(struct device *, int, int);
+int vme_generate_irq(struct device *, int, int);
+
+struct vme_resource * vme_lm_request(struct device *);
+int vme_lm_count(struct vme_resource *);
+int vme_lm_set(struct vme_resource *, unsigned long long, vme_address_t,
+	vme_cycle_t);
+int vme_lm_get(struct vme_resource *, unsigned long long *, vme_address_t *,
+	vme_cycle_t *);
+int vme_lm_attach(struct vme_resource *, int, void (*callback)(int));
+int vme_lm_detach(struct vme_resource *, int);
+void vme_lm_free(struct vme_resource *);
+
+int vme_slot_get(struct device *);
+
+int vme_register_driver (struct vme_driver *);
+void vme_unregister_driver (struct vme_driver *);
+
+
+#endif /* _VME_H_ */
+
diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt
new file mode 100644
index 0000000..591eba5
--- /dev/null
+++ b/drivers/staging/vme/vme_api.txt
@@ -0,0 +1,372 @@
+			VME Device Driver API
+			=====================
+
+Driver registration
+===================
+
+As with other subsystems within the Linux kernel, VME device drivers register
+with the VME subsystem, typically called from the devices init routine.  This is
+achieved via a call to the follwoing function:
+
+	int vme_register_driver (struct vme_driver *driver);
+
+If driver registration is successful this function returns zero, if an error
+occurred a negative error code will be returned.
+
+A pointer to a structure of type 'vme_driver' must be provided to the
+registration function. The structure is as follows:
+
+	struct vme_driver {
+		struct list_head node;
+		char *name;
+		const struct vme_device_id *bind_table;
+		int (*probe)  (struct device *, int, int);
+		int (*remove) (struct device *, int, int);
+		void (*shutdown) (void);
+		struct device_driver    driver;
+	};
+
+At the minimum, the '.name', '.probe' and '.bind_table' elements of this
+structure should be correctly set. The '.name' element is a pointer to a string
+holding the device driver's name. The '.probe' element should contain a pointer
+to the probe routine.
+
+The arguments of the probe routine are as follows:
+
+	probe(struct device *dev, int bus, int slot);
+
+The '.bind_table' is a pointer to an array of type 'vme_device_id':
+
+	struct vme_device_id {
+		int bus;
+		int slot;
+	};
+
+Each structure in this array should provide a bus and slot number where the core
+should probe, using the driver's probe routine, for a device on the specified
+VME bus.
+
+The VME subsystem supports a single VME driver per 'slot'. There are considered
+to be 32 slots per bus, one for each slot-ID as defined in the ANSI/VITA 1-1994
+specification and are analogious to the physical slots on the VME backplane.
+
+A function is also provided to unregister the driver from the VME core and is
+usually called from the device driver's exit routine:
+
+	void vme_unregister_driver (struct vme_driver *driver);
+
+
+Resource management
+===================
+
+Once a driver has registered with the VME core the provided probe routine will
+be called for each of the bus/slot combination that becomes valid as VME buses
+are themselves registered.  The probe routine is passed a pointer to the devices
+device structure. This pointer should be saved, it will be required for
+requesting VME resources.
+
+The driver can request ownership of one or more master windows, slave windows
+and/or dma channels. Rather than allowing the device driver to request a
+specific window or DMA channel (which may be used by a different driver) this
+driver allows a resource to be assigned based on the required attributes of the
+driver in question:
+
+	struct vme_resource * vme_master_request(struct device *dev,
+		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
+
+	struct vme_resource * vme_slave_request(struct device *dev,
+		vme_address_t aspace, vme_cycle_t cycle);
+
+	struct vme_resource *vme_request_dma(struct device *dev);
+
+For slave windows these attributes are split into those of type 'vme_address_t'
+and 'vme_cycle_t'. Master windows add a further set of attributes 'vme_cycle_t'.
+These attributes are defined as bitmasks and as such any combination of the
+attributes can be requested for a single window, the core will assign a window
+that meets the requirements, returning a pointer of type vme_resource that
+should be used to identify the allocated resource when it is used. If an
+unallocated window fitting the requirements can not be found a NULL pointer will
+be returned.
+
+Functions are also provided to free window allocations once they are no longer
+required. These functions should be passed the pointer to the resource provided
+during resource allocation:
+
+	void vme_master_free(struct vme_resource *res);
+
+	void vme_slave_free(struct vme_resource *res);
+
+	void vme_dma_free(struct vme_resource *res);
+
+
+Master windows
+==============
+
+Master windows provide access from the local processor[s] out onto the VME bus.
+The number of windows available and the available access modes is dependant on
+the underlying chipset. A window must be configured before it can be used.
+
+
+Master window configuration
+---------------------------
+
+Once a master window has been assigned the following functions can be used to
+configure it and retrieve the current settings:
+
+	int vme_master_set (struct vme_resource *res, int enabled,
+		unsigned long long base, unsigned long long size,
+		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
+
+	int vme_master_get (struct vme_resource *res, int *enabled,
+		unsigned long long *base, unsigned long long *size,
+		vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *width);
+
+The address spaces, transfer widths and cycle types are the same as described
+under resource management, however some of the options are mutually exclusive.
+For example, only one address space may be specified.
+
+These functions return 0 on success or an error code should the call fail.
+
+
+Master window access
+--------------------
+
+The following functions can be used to read from and write to configured master
+windows. These functions return the number of bytes copied:
+
+	ssize_t vme_master_read(struct vme_resource *res, void *buf,
+		size_t count, loff_t offset);
+
+	ssize_t vme_master_write(struct vme_resource *res, void *buf,
+		size_t count, loff_t offset);
+
+In addition to simple reads and writes, a function is provided to do a
+read-modify-write transaction. This function returns the original value of the
+VME bus location :
+
+	unsigned int vme_master_rmw (struct vme_resource *res,
+		unsigned int mask, unsigned int compare, unsigned int swap,
+		loff_t offset);
+
+This functions by reading the offset, applying the mask. If the bits selected in
+the mask match with the values of the corresponding bits in the compare field,
+the value of swap is written the specified offset.
+
+
+Slave windows
+=============
+
+Slave windows provide devices on the VME bus access into mapped portions of the
+local memory. The number of windows available and the access modes that can be
+used is dependant on the underlying chipset. A window must be configured before
+it can be used.
+
+
+Slave window configuration
+--------------------------
+
+Once a slave window has been assigned the following functions can be used to
+configure it and retrieve the current settings:
+
+	int vme_slave_set (struct vme_resource *res, int enabled,
+		unsigned long long base, unsigned long long size,
+		dma_addr_t mem, vme_address_t aspace, vme_cycle_t cycle);
+
+	int vme_slave_get (struct vme_resource *res, int *enabled,
+		unsigned long long *base, unsigned long long *size,
+		dma_addr_t *mem, vme_address_t *aspace, vme_cycle_t *cycle);
+
+The address spaces, transfer widths and cycle types are the same as described
+under resource management, however some of the options are mutually exclusive.
+For example, only one address space may be specified.
+
+These functions return 0 on success or an error code should the call fail.
+
+
+Slave window buffer allocation
+------------------------------
+
+Functions are provided to allow the user to allocate and free a contiguous
+buffers which will be accessible by the VME bridge. These functions do not have
+to be used, other methods can be used to allocate a buffer, though care must be
+taken to ensure that they are contiguous and accessible by the VME bridge:
+
+	void * vme_alloc_consistent(struct vme_resource *res, size_t size,
+		dma_addr_t *mem);
+
+	void vme_free_consistent(struct vme_resource *res, size_t size,
+		void *virt,	dma_addr_t mem);
+
+
+Slave window access
+-------------------
+
+Slave windows map local memory onto the VME bus, the standard methods for
+accessing memory should be used.
+
+
+DMA channels
+============
+
+The VME DMA transfer provides the ability to run link-list DMA transfers. The
+API introduces the concept of DMA lists. Each DMA list is a link-list which can
+be passed to a DMA controller. Multiple lists can be created, extended,
+executed, reused and destroyed.
+
+
+List Management
+---------------
+
+The following functions are provided to create and destroy DMA lists. Execution
+of a list will not automatically destroy the list, thus enabling a list to be
+reused for repetitive tasks:
+
+	struct vme_dma_list *vme_new_dma_list(struct vme_resource *res);
+
+	int vme_dma_list_free(struct vme_dma_list *list);
+
+
+List Population
+---------------
+
+An item can be added to a list using the following function ( the source and
+destination attributes need to be created before calling this function, this is
+covered under "Transfer Attributes"):
+
+	int vme_dma_list_add(struct vme_dma_list *list,
+		struct vme_dma_attr *src, struct vme_dma_attr *dest,
+		size_t count);
+
+
+Transfer Attributes
+-------------------
+
+The attributes for the source and destination are handled separately from adding
+an item to a list. This is due to the diverse attributes required for each type
+of source and destination. There are functions to create attributes for PCI, VME
+and pattern sources and destinations (where appropriate):
+
+Pattern source:
+
+	struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern,
+		vme_pattern_t type);
+
+PCI source or destination:
+
+	struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t mem);
+
+VME source or destination:
+
+	struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long base,
+		vme_address_t aspace, vme_cycle_t cycle, vme_width_t width);
+
+The following function should be used to free an attribute:
+
+	void vme_dma_free_attribute(struct vme_dma_attr *attr);
+
+
+List Execution
+--------------
+
+The following function queues a list for execution. The function will return
+once the list has been executed:
+
+	int vme_dma_list_exec(struct vme_dma_list *list);
+
+
+Interrupts
+==========
+
+The VME API provides functions to attach and detach callbacks to specific VME
+level and status ID combinations and for the generation of VME interrupts with
+specific VME level and status IDs.
+
+
+Attaching Interrupt Handlers
+----------------------------
+
+The following functions can be used to attach and free a specific VME level and
+status ID combination. Any given combination can only be assigned a single
+callback function. A void pointer parameter is provided, the value of which is
+passed to the callback function, the use of this pointer is user undefined:
+
+	int vme_request_irq(struct device *dev, int level, int statid,
+		void (*callback)(int, int, void *), void *priv);
+
+	void vme_free_irq(struct device *dev, int level, int statid);
+
+The callback parameters are as follows. Care must be taken in writing a callback
+function, callback functions run in interrupt context:
+
+	void callback(int level, int statid, void *priv);
+
+
+Interrupt Generation
+--------------------
+
+The following function can be used to generate a VME interrupt at a given VME
+level and VME status ID:
+
+	int vme_generate_irq(struct device *dev, int level, int statid);
+
+
+Location monitors
+=================
+
+The VME API provides the following functionality to configure the location
+monitor.
+
+
+Location Monitor Management
+---------------------------
+
+The following functions are provided to request the use of a block of location
+monitors and to free them after they are no longer required:
+
+	struct vme_resource * vme_lm_request(struct device *dev);
+
+	void vme_lm_free(struct vme_resource * res);
+
+Each block may provide a number of location monitors, monitoring adjacent
+locations. The following function can be used to determine how many locations
+are provided:
+
+	int vme_lm_count(struct vme_resource * res);
+
+
+Location Monitor Configuration
+------------------------------
+
+Once a bank of location monitors has been allocated, the following functions
+are provided to configure the location and mode of the location monitor:
+
+	int vme_lm_set(struct vme_resource *res, unsigned long long base,
+		vme_address_t aspace, vme_cycle_t cycle);
+
+	int vme_lm_get(struct vme_resource *res, unsigned long long *base,
+		vme_address_t *aspace, vme_cycle_t *cycle);
+
+
+Location Monitor Use
+--------------------
+
+The following functions allow a callback to be attached and detached from each
+location monitor location. Each location monitor can monitor a number of
+adjacent locations:
+
+	int vme_lm_attach(struct vme_resource *res, int num,
+		void (*callback)(int));
+
+	int vme_lm_detach(struct vme_resource *res, int num);
+
+The callback function is declared as follows.
+
+	void callback(int num);
+
+
+Slot Detection
+==============
+
+This function returns the slot ID of the provided bridge.
+
+	int vme_slot_get(struct device *dev);
diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h
new file mode 100644
index 0000000..e43cc19
--- /dev/null
+++ b/drivers/staging/vme/vme_bridge.h
@@ -0,0 +1,261 @@
+#ifndef _VME_BRIDGE_H_
+#define _VME_BRIDGE_H_
+
+#define VME_CRCSR_BUF_SIZE (508*1024)
+#define VME_SLOTS_MAX 32
+/*
+ * Resource structures
+ */
+struct vme_master_resource {
+	struct list_head list;
+	struct vme_bridge *parent;
+	/*
+	 * We are likely to need to access the VME bus in interrupt context, so
+	 * protect master routines with a spinlock rather than a mutex.
+	 */
+	spinlock_t lock;
+	int locked;
+	int number;
+	vme_address_t address_attr;
+	vme_cycle_t cycle_attr;
+	vme_width_t width_attr;
+	struct resource pci_resource;	/* XXX Rename to be bus agnostic */
+	void *kern_base;
+};
+
+struct vme_slave_resource {
+	struct list_head list;
+	struct vme_bridge *parent;
+	struct mutex mtx;
+	int locked;
+	int number;
+	vme_address_t address_attr;
+	vme_cycle_t cycle_attr;
+};
+
+struct vme_dma_pattern {
+	u32 pattern;
+	vme_pattern_t type;
+};
+
+struct vme_dma_pci {
+	dma_addr_t address;
+};
+
+struct vme_dma_vme {
+	unsigned long long address;
+	vme_address_t aspace;
+	vme_cycle_t cycle;
+	vme_width_t dwidth;
+};
+
+struct vme_dma_list {
+	struct list_head list;
+	struct vme_dma_resource *parent;
+	struct list_head entries;
+	struct mutex mtx;
+};
+
+struct vme_dma_resource {
+	struct list_head list;
+	struct vme_bridge *parent;
+	struct mutex mtx;
+	int locked;
+	int number;
+	struct list_head pending;
+	struct list_head running;
+};
+
+struct vme_lm_resource {
+	struct list_head list;
+	struct vme_bridge *parent;
+	struct mutex mtx;
+	int locked;
+	int number;
+	int monitors;
+};
+
+struct vme_bus_error {
+	struct list_head list;
+	unsigned long long address;
+	u32 attributes;
+};
+
+struct vme_callback {
+	void (*func)(int, int, void*);
+	void *priv_data;
+};
+
+struct vme_irq {
+	int count;
+	struct vme_callback callback[255];
+};
+
+/* Allow 16 characters for name (including null character) */
+#define VMENAMSIZ 16
+
+/* This structure stores all the information about one bridge
+ * The structure should be dynamically allocated by the driver and one instance
+ * of the structure should be present for each VME chip present in the system.
+ *
+ * Currently we assume that all chips are PCI-based
+ */
+struct vme_bridge {
+        char name[VMENAMSIZ];
+	int num;
+	struct list_head master_resources;
+	struct list_head slave_resources;
+	struct list_head dma_resources;
+	struct list_head lm_resources;
+
+	struct list_head vme_errors;	/* List for errors generated on VME */
+
+	/* Bridge Info - XXX Move to private structure? */
+	struct device *parent;	/* Generic device struct (pdev->dev for PCI) */
+	void * base;		/* Base Address of device registers */
+
+	struct device dev[VME_SLOTS_MAX];	/* Device registered with
+						 * device model on VME bus
+						 */
+
+	/* Interrupt callbacks */
+	struct vme_irq irq[7];
+
+	/* Slave Functions */
+	int (*slave_get) (struct vme_slave_resource *, int *,
+		unsigned long long *, unsigned long long *, dma_addr_t *,
+		vme_address_t *, vme_cycle_t *);
+	int (*slave_set) (struct vme_slave_resource *, int, unsigned long long,
+		unsigned long long, dma_addr_t, vme_address_t, vme_cycle_t);
+
+	/* Master Functions */
+	int (*master_get) (struct vme_master_resource *, int *,
+		unsigned long long *, unsigned long long *, vme_address_t *,
+		vme_cycle_t *, vme_width_t *);
+	int (*master_set) (struct vme_master_resource *, int,
+		unsigned long long, unsigned long long,  vme_address_t,
+		vme_cycle_t, vme_width_t);
+	ssize_t (*master_read) (struct vme_master_resource *, void *, size_t,
+		loff_t);
+	ssize_t (*master_write) (struct vme_master_resource *, void *, size_t,
+		loff_t);
+	unsigned int (*master_rmw) (struct vme_master_resource *, unsigned int,
+		unsigned int, unsigned int, loff_t);
+
+	/* DMA Functions */
+	int (*dma_list_add) (struct vme_dma_list *, struct vme_dma_attr *,
+		struct vme_dma_attr *, size_t);
+	int (*dma_list_exec) (struct vme_dma_list *);
+	int (*dma_list_empty) (struct vme_dma_list *);
+
+	/* Interrupt Functions */
+	int (*request_irq) (int, int, void (*cback)(int, int, void*), void *);
+	void (*free_irq) (int, int);
+	int (*generate_irq) (int, int);
+
+	/* Location monitor functions */
+	int (*lm_set) (struct vme_lm_resource *, unsigned long long,
+		vme_address_t, vme_cycle_t);
+	int (*lm_get) (struct vme_lm_resource *, unsigned long long *,
+		vme_address_t *, vme_cycle_t *);
+	int (*lm_attach) (struct vme_lm_resource *, int, void (*callback)(int));
+	int (*lm_detach) (struct vme_lm_resource *, int);
+
+	/* CR/CSR space functions */
+	int (*slot_get) (void);
+	/* Use standard master read and write functions to access CR/CSR */
+
+#if 0
+	int (*set_prefetch) (void);
+	int (*get_prefetch) (void);
+	int (*set_arbiter) (void);
+	int (*get_arbiter) (void);
+	int (*set_requestor) (void);
+	int (*get_requestor) (void);
+#endif
+};
+
+int vme_register_bridge (struct vme_bridge *);
+void vme_unregister_bridge (struct vme_bridge *);
+
+#endif /* _VME_BRIDGE_H_ */
+
+#if 0
+/*
+ *  VMEbus GET INFO Arg Structure
+ */
+struct vmeInfoCfg {
+	int vmeSlotNum;		/*  VME slot number of interest */
+	int boardResponded;	/* Board responded */
+	char sysConFlag;	/*  System controller flag */
+	int vmeControllerID;	/*  Vendor/device ID of VME bridge */
+	int vmeControllerRev;	/*  Revision of VME bridge */
+	char osName[8];		/*  Name of OS e.g. "Linux" */
+	int vmeSharedDataValid;	/*  Validity of data struct */
+	int vmeDriverRev;	/*  Revision of VME driver */
+	unsigned int vmeAddrHi[8];	/* Address on VME bus */
+	unsigned int vmeAddrLo[8];	/* Address on VME bus */
+	unsigned int vmeSize[8];	/* Size on VME bus */
+	unsigned int vmeAm[8];	/* Address modifier on VME bus */
+	int reserved;		/* For future use */
+};
+typedef struct vmeInfoCfg vmeInfoCfg_t;
+
+/*
+ *  VMEbus Requester Arg Structure
+ */
+struct vmeRequesterCfg {
+	int requestLevel;	/*  Requester Bus Request Level */
+	char fairMode;		/*  Requester Fairness Mode Indicator */
+	int releaseMode;	/*  Requester Bus Release Mode */
+	int timeonTimeoutTimer;	/*  Master Time-on Time-out Timer */
+	int timeoffTimeoutTimer;	/*  Master Time-off Time-out Timer */
+	int reserved;		/* For future use */
+};
+typedef struct vmeRequesterCfg vmeRequesterCfg_t;
+
+/*
+ *  VMEbus Arbiter Arg Structure
+ */
+struct vmeArbiterCfg {
+	vme_arbitration_t arbiterMode;	/*  Arbitration Scheduling Algorithm */
+	char arbiterTimeoutFlag;	/*  Arbiter Time-out Timer Indicator */
+	int globalTimeoutTimer;	/*  VMEbus Global Time-out Timer */
+	char noEarlyReleaseFlag;	/*  No Early Release on BBUSY */
+	int reserved;		/* For future use */
+};
+typedef struct vmeArbiterCfg vmeArbiterCfg_t;
+
+
+/*
+ *  VMEbus RMW Configuration Data
+ */
+struct vmeRmwCfg {
+	unsigned int targetAddrU;	/*  VME Address (Upper) to trigger RMW cycle */
+	unsigned int targetAddr;	/*  VME Address (Lower) to trigger RMW cycle */
+	vme_address_t addrSpace;	/*  VME Address Space */
+	int enableMask;		/*  Bit mask defining the bits of interest */
+	int compareData;	/*  Data to be compared with the data read */
+	int swapData;		/*  Data written to the VMEbus on success */
+	int maxAttempts;	/*  Maximum times to try */
+	int numAttempts;	/*  Number of attempts before success */
+	int reserved;		/* For future use */
+
+};
+typedef struct vmeRmwCfg vmeRmwCfg_t;
+
+/*
+ *  VMEbus Location Monitor Arg Structure
+ */
+struct vmeLmCfg {
+	unsigned int addrU;	/*  Location Monitor Address upper */
+	unsigned int addr;	/*  Location Monitor Address lower */
+	vme_address_t addrSpace;	/*  Address Space */
+	int userAccessType;	/*  User/Supervisor Access Type */
+	int dataAccessType;	/*  Data/Program Access Type */
+	int lmWait;		/* Time to wait for access */
+	int lmEvents;		/* Lm event mask */
+	int reserved;		/* For future use */
+};
+typedef struct vmeLmCfg vmeLmCfg_t;
+#endif
diff --git a/drivers/staging/vt6655/80211hdr.h b/drivers/staging/vt6655/80211hdr.h
index b4bbb8d..e5cee6f 100644
--- a/drivers/staging/vt6655/80211hdr.h
+++ b/drivers/staging/vt6655/80211hdr.h
@@ -16,10 +16,11 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: 80211hdr.h
  *
- * Purpose: Defines the macros, types, and functions for dealing
- *          with 802.11 MAC headers.
+ * Purpose: 802.11 MAC headers related pre-defines and macros.
+ *
  *
  * Author: Lyndon Chen
  *
@@ -27,15 +28,10 @@
  *
  */
 
-
-
 #ifndef __80211HDR_H__
 #define __80211HDR_H__
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
 
 /*---------------------  Export Definitions -------------------------*/
 // bit type
diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c
index 84745fb..d309049 100644
--- a/drivers/staging/vt6655/80211mgr.c
+++ b/drivers/staging/vt6655/80211mgr.c
@@ -16,10 +16,9 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- *
  * File: 80211mgr.c
  *
- * Purpose: Handles the 802.11 managment support functions
+ * Purpose: Handles the 802.11 management support functions
  *
  * Author: Lyndon Chen
  *
@@ -53,28 +52,12 @@
  *
  */
 
-
-
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WPA_H__)
 #include "wpa.h"
-#endif
-
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -236,7 +219,7 @@ vMgrDecodeBeacon(
                 break;
 
             default:
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
                 break;
 
         }
@@ -431,7 +414,7 @@ vMgrDecodeAssocRequest(
                 break;
 
             default:
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
                         pItem->byElementID);
                 break;
         }
@@ -509,7 +492,7 @@ vMgrDecodeAssocResponse(
 
     if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
         pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
     }
     else {
         pFrame->pExtSuppRates = NULL;
@@ -610,7 +593,7 @@ vMgrDecodeReassocRequest(
                     pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
                 break;
             default:
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
                             pItem->byElementID);
                 break;
         }
@@ -685,7 +668,7 @@ vMgrDecodeProbeRequest(
                 break;
 
             default:
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
                 break;
         }
 
@@ -747,7 +730,6 @@ vMgrDecodeProbeResponse(
     )
 {
     PWLAN_IE    pItem;
-//    BYTE        byCheckEID = 0;
 
 
     pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
@@ -765,12 +747,6 @@ vMgrDecodeProbeResponse(
                        + WLAN_PROBERESP_OFF_SSID);
 
     while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
-		/*
-        if (pItem->byElementID < byCheckEID)
-            break;
-        else
-            byCheckEID = pItem->byElementID;
-*/
         switch (pItem->byElementID) {
             case WLAN_EID_SSID:
                 if (pFrame->pSSID == NULL)
@@ -841,7 +817,7 @@ vMgrDecodeProbeResponse(
                 break;
 
             default:
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
                 break;
         }
 
diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h
index dc54a65..5efc132 100644
--- a/drivers/staging/vt6655/80211mgr.h
+++ b/drivers/staging/vt6655/80211mgr.h
@@ -16,10 +16,11 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: 80211mgr.h
  *
- * Purpose: Defines the macros, types, and functions for dealing
- *          with 802.11 managment frames.
+ * Purpose: 802.11 managment frames pre-defines.
+ *
  *
  * Author: Lyndon Chen
  *
@@ -27,17 +28,11 @@
  *
  */
 
-
 #ifndef __80211MGR_H__
 #define __80211MGR_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -273,7 +268,6 @@ typedef struct _WLAN_IE_FH_PARMS {
     BYTE    byHopIndex;
 } WLAN_IE_FH_PARMS,  *PWLAN_IE_FH_PARMS;
 
-
 // DS Parameter Set
 #pragma pack(1)
 typedef struct tagWLAN_IE_DS_PARMS {
@@ -719,6 +713,7 @@ typedef struct tagWLAN_FR_DEAUTHEN {
 } WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN;
 
 /*---------------------  Export Functions  --------------------------*/
+
 VOID
 vMgrEncodeBeacon(
     IN  PWLAN_FR_BEACON  pFrame
diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c
index 5f25b8e..2567143 100644
--- a/drivers/staging/vt6655/IEEE11h.c
+++ b/drivers/staging/vt6655/IEEE11h.c
@@ -31,34 +31,13 @@
  *
  */
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__IEEE11h_H__)
 #include "IEEE11h.h"
-#endif
-
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-
-
 
 /*---------------------  Static Definitions -------------------------*/
 static int          msglevel                =MSG_LEVEL_INFO;
@@ -120,13 +99,13 @@ typedef struct _WLAN_FRAME_TPCREP {
 /*---------------------  Static Functions  --------------------------*/
 static BOOL s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, UINT uLength)
 {
-    UINT    uNumOfEIDs = 0;
+    size_t    uNumOfEIDs = 0;
     BOOL    bResult = TRUE;
 
     if (uLength <= WLAN_A3FR_MAXLEN) {
-        MEMvCopy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
+        memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
     }
-    uNumOfEIDs = ((uLength - OFFSET(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
+    uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
     pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]);
     pMgmt->uLengthOfRepEIDs = 0;
     bResult = CARDbStartMeasure(pMgmt->pAdapter,
@@ -153,9 +132,9 @@ static BOOL s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, BYTE byR
                                     WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
                                 );
 
-    MEMvCopy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN);
-    MEMvCopy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
-    MEMvCopy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    memcpy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN);
+    memcpy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
+    memcpy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
 
     pFrame->byCategory = 0;
     pFrame->byAction = 3;
@@ -271,11 +250,11 @@ IEEE11hbMgrRxAction (
                 }
                 break;
             default:
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
                 break;
         }
     } else {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
         pAction->byCategory |= 0x80;
 
        //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength));
@@ -291,7 +270,7 @@ BOOL IEEE11hbMSRRepTx (
 {
     PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
     PWLAN_FRAME_MSRREP      pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
-    UINT                    uLength = 0;
+    size_t                    uLength = 0;
     PSTxMgmtPacket          pTxPacket = NULL;
 
     pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
@@ -303,15 +282,15 @@ BOOL IEEE11hbMSRRepTx (
                                     WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
                                 );
 
-    MEMvCopy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
-    MEMvCopy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
-    MEMvCopy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    memcpy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
+    memcpy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
+    memcpy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
 
     pMSRRep->byCategory = 0;
     pMSRRep->byAction = 1;
     pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;
 
-    uLength = pMgmt->uLengthOfRepEIDs + OFFSET(WLAN_FRAME_MSRREP, sMSRRepEIDs);
+    uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs);
 
     pTxPacket->cbMPDULen = uLength;
     pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
diff --git a/drivers/staging/vt6655/IEEE11h.h b/drivers/staging/vt6655/IEEE11h.h
index 22bcaf1..0f61edd 100644
--- a/drivers/staging/vt6655/IEEE11h.h
+++ b/drivers/staging/vt6655/IEEE11h.h
@@ -31,17 +31,9 @@
 #ifndef __IEEE11h_H__
 #define __IEEE11h_H__
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -52,17 +44,9 @@
 /*---------------------  Export Types  ------------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 BOOL IEEE11hbMSRRepTx (
     IN PVOID pMgmtHandle
     );
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif // __IEEE11h_H__
diff --git a/drivers/staging/vt6655/Kconfig b/drivers/staging/vt6655/Kconfig
index a01b1e4..9bec95a 100644
--- a/drivers/staging/vt6655/Kconfig
+++ b/drivers/staging/vt6655/Kconfig
@@ -1,6 +1,6 @@
 config VT6655
    tristate "VIA Technologies VT6655 support"
-   depends on PCI
+   depends on WIRELESS_EXT && PCI
    ---help---
    This is a vendor-written driver for VIA VT6655.
 
diff --git a/drivers/staging/vt6655/Makefile b/drivers/staging/vt6655/Makefile
index 7d76e7e..931deb1 100644
--- a/drivers/staging/vt6655/Makefile
+++ b/drivers/staging/vt6655/Makefile
@@ -1,8 +1,8 @@
 # TODO: all of these should be removed
-EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DMODULE  -DEXPORT_SYMTAB -D__NO_VERSION__
+EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -D__NO_VERSION__
 EXTRA_CFLAGS += -DHOSTAP
 
-vt6655-y +=	device_main.o \
+vt6655_stage-y +=	device_main.o \
 	card.o \
 	mac.o \
 	baseband.o \
@@ -35,4 +35,4 @@ vt6655-y +=	device_main.o \
 	vntwifi.o \
 	IEEE11h.o
 
-obj-$(CONFIG_VT6655) +=	vt6655.o
+obj-$(CONFIG_VT6655) +=	vt6655_stage.o
diff --git a/drivers/staging/vt6655/Makefile.arm b/drivers/staging/vt6655/Makefile.arm
deleted file mode 100644
index 2d2ccad..0000000
--- a/drivers/staging/vt6655/Makefile.arm
+++ /dev/null
@@ -1,181 +0,0 @@
-#
-#
-# Build options:
-#   PRIV_OBJ   := 1 for object version
-#   BIG_ENDIAN := 1 for big-endian mode
-#
-#   arm-linux-tools chain are located at:
-#     /usr/local/bin/arm-linux-gcc
-#     /usr/local/bin/arm-linux-ld
-#
-
-IO_MAP := 0
-HOSTAP := 1
-PRIV_OBJ := 1
-BIG_ENDIAN := 1
-
-test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
-KSP := $(foreach dir, $(KSP), $(test_dir))
-
-KSRC := $(firstword $(KSP))
-
-#ifeq (,$(KSRC))
-#  $(error Linux kernel source not found)
-#endif
-
-# check kernel version
-KVER := $(shell uname -r | cut -c1-3 | sed 's/2\.[56]/2\.6/')
-KERVER2=$(shell uname -r | cut -d. -f2)
-
-ifeq ($(KVER), 2.6)
-# 2.6 kernel
-TARGET = viawget.ko
-
-else
-TARGET = viawget.o
-
-endif
-
-INSTDIR	:= $(shell find /lib/modules/$(shell uname -r) -name $(TARGET) -printf "%h\n" | sort | head -1)
-ifeq (,$(INSTDIR))
-	ifeq (,$(KERVER2))
-		ifneq (,$(wildcard /lib/modules/$(shell uname -r)/kernel))
-			INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net
-		else
-			INSTDIR := /lib/modules/$(shell uname -r)/net
-		endif
-	else
-		ifneq ($(KERVER2),2)
-			INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net
-		else
-			INSTDIR := /lib/modules/$(shell uname -r)/net
-		endif
-	endif
-endif
-
-
-SRC = device_main.c card.c mac.c baseband.c wctl.c 80211mgr.c \
-      wcmd.c wmgr.c bssdb.c rxtx.c dpc.c power.c datarate.c srom.c \
-      mib.c rc4.c tether.c tcrc.c ioctl.c hostap.c wpa.c key.c tkip.c \
-      michael.c wroute.c rf.c iwctl.c wpactl.c wpa2.c aes_ccmp.c
-
-ifeq ($(IO_MAP), 1)
-  CFLAGS += -DIO_MAP
-endif
-
-ifeq ($(HOSTAP), 1)
-  CFLAGS += -DHOSTAP
-endif
-
-ifeq ($(PRIV_OBJ), 1)
-  CFLAGS += -DPRIVATE_OBJ
-endif
-
-ifeq ($(BIG_ENDIAN), 1)
-  CFLAGS += -D__BIG_ENDIAN
-  CFLAGS += -mbig-endian
-  LDOPTS += -EB
-else
-  CFLAGS += -mlittle-endian
-  LDOPTS += -EL
-endif
-
-CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/../solomon
-
-
-# build rule
-ifeq ($(KVER), 2.6)
-# 2.6 kernel
-
-ifndef KERNEL_CONF
-KERNEL_CONF=	$(KSRC)/.config
-endif
-
-include ${KERNEL_CONF}
-
-obj-m += viawget.o
-
-viawget-objs :=	device_main.o card.o mac.o baseband.o wctl.o 80211mgr.o \
-	wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o srom.o \
-	mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
-	michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o
-
-.c.o:
-	$(CC) $(CFLAGS) -o $@ $<
-
-default:
-	make -C $(KSRC) SUBDIRS=$(shell pwd) modules
-
-else
-
-# 2.2/2.4 kernel
-OBJS :=	device_main.o card.o mac.o baseband.o wctl.o 80211mgr.o \
-	wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o srom.o \
-	mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
-	michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o
-
-
-CC := /usr/local/bin/arm-linux-gcc
-LD := /usr/local/bin/arm-linux-ld
-
-CFLAGS += -Wall -DLINUX -D__KERNEL__ -DMODULE  -DEXPORT_SYMTAB -D__NO_VERSION__ -O2 -pipe
-#CFLAGS += -Wstrict-prototypes -fomit-frame-pointer
-COPTS+= -march=armv4 -fno-strict-aliasing -fno-common
-#COPTS+= -mapcs-32 -mtune=xscale  -mshort-load-bytes -msoft-float -mfp=2
-#COPTS+= -mthumb  -mcpu=arm9 -ffunction-sections -fdata-sections
-
-
-.SILENT: $(TARGET) clean
-
-
-
-ifeq ($(PRIV_OBJ), 1)
-
-ifeq ($(BIG_ENDIAN), 1)
-  TARGET = arm_be_g.o
-else
-  TARGET = arm_le_g.o
-endif
-
-endif
-
-
-
-$(TARGET): $(filter-out $(TARGET), $(SRC:.c=.o))
-	$(LD) $(LDOPTS) -r $^ -o $@
-	echo
-	echo "***********************************"
-	echo "Build options:"
-	echo "   VERSION    $(KVER)"
-	echo -n "   SMP             "
-	if [ "$(SMP)" = "1" ]; \
-		then echo "Enabled"; else echo "Disabled"; fi
-
-
-endif # ifeq ($(KVER),2.6)
-
-
-ifeq ($(KVER), 2.6)
-install: default
-else
-install: clean $(TARGET)
-endif
-	mkdir -p $(MOD_ROOT)$(INSTDIR)
-	install -m 644 -o root $(TARGET) $(MOD_ROOT)$(INSTDIR)
-
-ifeq (,$(MOD_ROOT))
-	/sbin/depmod -a || true
-else
-	/sbin/depmod -b $(MOD_ROOT) -a || true
-endif
-
-
-uninstall:
-	rm -f $(INSTDIR)/$(TARGET)
-	/sbin/depmod -a
-
-clean:
-	rm -f $(TARGET) $(SRC:.c=.o) *~
-	rm -f .*.o.d .*.o.cmd .*.ko.cmd *.mod.c *.mod.o
-
--include .depend.mak
diff --git a/drivers/staging/vt6655/Makefile.x86 b/drivers/staging/vt6655/Makefile.x86
deleted file mode 100644
index 69082f0..0000000
--- a/drivers/staging/vt6655/Makefile.x86
+++ /dev/null
@@ -1,209 +0,0 @@
-#
-# Build options:
-#   PRIV_OBJ := 1 for object version
-#
-
-IO_MAP := 0
-HOSTAP := 1
-PRIV_OBJ := 1
-
-KSP :=  /lib/modules/$(shell uname -r)/build \
-	/usr/src/linux-$(shell uname -r) \
-	/usr/src/linux-$(shell uname -r | sed 's/-.*//') \
-	/usr/src/kernel-headers-$(shell uname -r) \
-	/usr/src/kernel-source-$(shell uname -r) \
-	/usr/src/linux-$(shell uname -r | sed 's/\([0-9]*\.[0-9]*\)\..*/\1/') \
-	/usr/src/linux
-
-test_dir = $(shell [ -e $(dir)/include/linux ] && echo $(dir))
-KSP := $(foreach dir, $(KSP), $(test_dir))
-
-KSRC := $(firstword $(KSP))
-
-ifeq (,$(KSRC))
-  $(error Linux kernel source not found)
-endif
-
-# check kernel version
-KVER := $(shell uname -r | cut -c1-3 | sed 's/2\.[56]/2\.6/')
-KERVER2=$(shell uname -r | cut -d. -f2)
-
-ifeq ($(KVER), 2.6)
-# 2.6 kernel
-TARGET = viawget.ko
-
-else
-TARGET = viawget.o
-
-endif
-
-INSTDIR	:= $(shell find /lib/modules/$(shell uname -r) -name $(TARGET) -printf "%h\n" | sort | head -1)
-ifeq (,$(INSTDIR))
-	ifeq (,$(KERVER2))
-		ifneq (,$(wildcard /lib/modules/$(shell uname -r)/kernel))
-			INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net
-		else
-			INSTDIR := /lib/modules/$(shell uname -r)/net
-		endif
-	else
-		ifneq ($(KERVER2),2)
-			INSTDIR := /lib/modules/$(shell uname -r)/kernel/drivers/net
-		else
-			INSTDIR := /lib/modules/$(shell uname -r)/net
-		endif
-	endif
-endif
-
-
-SRC = device_main.c card.c mac.c baseband.c wctl.c 80211mgr.c \
-      wcmd.c wmgr.c bssdb.c  wpa2.c rxtx.c dpc.c power.c datarate.c \
-      srom.c mib.c rc4.c tether.c tcrc.c ioctl.c hostap.c wpa.c key.c \
-      tkip.c michael.c wroute.c rf.c iwctl.c wpactl.c aes_ccmp.c
-
-ifeq ($(IO_MAP), 1)
-  CFLAGS += -DIO_MAP
-endif
-
-ifeq ($(HOSTAP), 1)
-  CFLAGS += -DHOSTAP
-endif
-
-ifeq ($(PRIV_OBJ), 1)
-  CFLAGS += -DPRIVATE_OBJ
-endif
-
-CFLAGS += -I$(PWD) -I$(PWD)/../include -I$(PWD)/../solomon
-
-
-# build rule
-ifeq ($(KVER), 2.6)
-# 2.6 kernel
-
-ifndef KERNEL_CONF
-KERNEL_CONF=	$(KSRC)/.config
-endif
-
-include ${KERNEL_CONF}
-
-obj-m += viawget.o
-
-viawget-objs :=	device_main.o card.o mac.o baseband.o wctl.o 80211mgr.o \
-	wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o srom.o \
-	mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
-	michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o
-
-.c.o:
-	$(CC) $(CFLAGS) -o $@ $<
-
-default:
-	make -C $(KSRC) SUBDIRS=$(shell pwd) modules
-
-else
-
-# 2.2/2.4 kernel
-OBJS :=	device_main.o card.o mac.o baseband.o wctl.o 80211mgr.o \
-	wcmd.o wmgr.o bssdb.o rxtx.o dpc.o power.o datarate.o srom.o \
-	mib.o rc4.o tether.o tcrc.o ioctl.o hostap.o wpa.o key.o tkip.o \
-	michael.o wroute.o rf.o iwctl.o wpactl.o wpa2.o aes_ccmp.o
-
-VERSION_FILE := $(KSRC)/include/linux/version.h
-CONFIG_FILE  := $(KSRC)/include/linux/config.h
-
-
-ifeq (,$(wildcard $(VERSION_FILE)))
-  $(error Linux kernel source not configured - missing version.h)
-endif
-
-ifeq (,$(wildcard $(CONFIG_FILE)))
-  $(error Linux kernel source not configured - missing config.h)
-endif
-
-ifneq (,$(findstring egcs-2.91.66, $(shell cat /proc/version)))
-  CC := kgcc gcc cc
-else
-  CC := gcc cc
-endif
-
-test_cc = $(shell which $(cc) > /dev/null 2>&1 && echo $(cc))
-CC := $(foreach cc, $(CC), $(test_cc))
-CC := $(firstword $(CC))
-
-CFLAGS += -Wall -DLINUX -D__KERNEL__ -DMODULE  -DEXPORT_SYMTAB -D__NO_VERSION__ -O2 -pipe
-CFLAGS += -I$(KSRC)/include -Wstrict-prototypes -fomit-frame-pointer
-CFLAGS += $(shell [ -f $(KSRC)/include/linux/modversions.h ] && \
-            echo "-DMODVERSIONS -include $(KSRC)/include/linux/modversions.h")
-
-.SILENT: $(TARGET) clean
-
-
-# look for SMP in config.h
-SMP := $(shell $(CC) $(CFLAGS) -E -dM $(CONFIG_FILE) | \
-         grep CONFIG_SMP | awk '{ print $$3 }')
-
-ifneq ($(SMP),1)
-  SMP := 0
-endif
-
-
-ifeq ($(SMP), 1)
-  CFLAGS += -D__SMP__
-endif
-
-
-ifeq ($(PRIV_OBJ), 1)
-  CFLAGS += -DPRIVATE_OBJ
-  TARGET = x86g_up.o
-
-ifeq ($(SMP), 1)
-  TARGET = x86g_smp.o
-endif
-
-endif
-
-
-# check x86_64
-SUBARCH := $(shell uname -m)
-ifeq ($(SUBARCH),x86_64)
-    CFLAGS += -mcmodel=kernel -mno-red-zone
-endif
-
-
-$(TARGET): $(filter-out $(TARGET), $(SRC:.c=.o))
-	$(LD) -r $^ -o $@
-	echo; echo
-	echo "**************************************************"
-	echo "Build options:"
-	echo "   VERSION    $(KVER)"
-	echo -n "   SMP             "
-	if [ "$(SMP)" = "1" ]; \
-		then echo "Enabled"; else echo "Disabled"; fi
-
-
-
-endif # ifeq ($(KVER),2.6)
-
-
-ifeq ($(KVER), 2.6)
-install: default
-else
-install: clean $(TARGET)
-endif
-	mkdir -p $(MOD_ROOT)$(INSTDIR)
-	install -m 644 -o root $(TARGET) $(MOD_ROOT)$(INSTDIR)
-
-ifeq (,$(MOD_ROOT))
-	/sbin/depmod -a || true
-else
-	/sbin/depmod -b $(MOD_ROOT) -a || true
-endif
-
-
-uninstall:
-	rm -f $(INSTDIR)/$(TARGET)
-	/sbin/depmod -a
-
-clean:
-	rm -f $(TARGET) $(SRC:.c=.o) *~
-	rm -f .*.o.d .*.o.cmd .*.ko.cmd *.mod.c *.mod.o
-
--include .depend.mak
diff --git a/drivers/staging/vt6655/TODO b/drivers/staging/vt6655/TODO
new file mode 100644
index 0000000..8462cd1
--- /dev/null
+++ b/drivers/staging/vt6655/TODO
@@ -0,0 +1,21 @@
+TODO:
+- remove __cplusplus ifdefs -- done
+- prepare for merge with vt6656 driver:
+  - rename DEVICE_PRT() to DBG_PRT() -- done
+  - share 80211*.h includes
+  - move code for channel mapping from card.c to channel.c
+  - split rf.c
+  - remove dead code
+  - abstract VT3253 chipset specific code
+- add common vt665x infrastructure
+- kill ttype.h
+- switch to use LIB80211
+- switch to use MAC80211
+- use kernel coding style
+- checkpatch.pl fixes
+- sparse fixes
+- integrate with drivers/net/wireless
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
+Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
+<bzolnier@gmail.com>.
diff --git a/drivers/staging/vt6655/aes_ccmp.c b/drivers/staging/vt6655/aes_ccmp.c
index 59cc018..2614ed3 100644
--- a/drivers/staging/vt6655/aes_ccmp.c
+++ b/drivers/staging/vt6655/aes_ccmp.c
@@ -33,16 +33,8 @@
  *
  */
 
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -285,7 +277,7 @@ int             ii,jj,kk;
     pbyPayload = pbyIV + 8; //IV-length
 
     abyNonce[0]  = 0x00; //now is 0, if Qos here will be priority
-    MEMvCopy(&(abyNonce[1]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
+    memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
     abyNonce[7]  = pbyIV[7];
     abyNonce[8]  = pbyIV[6];
     abyNonce[9]  = pbyIV[5];
@@ -295,7 +287,7 @@ int             ii,jj,kk;
 
     //MIC_IV
     MIC_IV[0] = 0x59;
-    MEMvCopy(&(MIC_IV[1]), &(abyNonce[0]), 13);
+    memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
     MIC_IV[14] = (BYTE)(wPayloadSize >> 8);
     MIC_IV[15] = (BYTE)(wPayloadSize & 0xff);
 
@@ -307,16 +299,16 @@ int             ii,jj,kk;
     byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8);
     byTmp &= 0x87;
     MIC_HDR1[3] = byTmp | 0x40;
-    MEMvCopy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, U_ETHER_ADDR_LEN);
-    MEMvCopy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
+    memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, U_ETHER_ADDR_LEN);
+    memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
 
     //MIC_HDR2
-    MEMvCopy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, U_ETHER_ADDR_LEN);
+    memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, U_ETHER_ADDR_LEN);
     byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff);
     MIC_HDR2[6] = byTmp & 0x0f;
     MIC_HDR2[7] = 0;
     if ( bA4 ) {
-        MEMvCopy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, U_ETHER_ADDR_LEN);
+        memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, U_ETHER_ADDR_LEN);
     } else {
         MIC_HDR2[8]  = 0x00;
         MIC_HDR2[9]  = 0x00;
@@ -341,7 +333,7 @@ int             ii,jj,kk;
 
     wCnt = 1;
     abyCTRPLD[0] = 0x01;
-    MEMvCopy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
+    memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
 
     for(jj=wPayloadSize; jj>16; jj=jj-16) {
 
@@ -358,13 +350,13 @@ int             ii,jj,kk;
         }
         AESv128(pbyRxKey,abyTmp,abyMIC);
 
-        MEMvCopy(pbyPayload, abyPlainText, 16);
+        memcpy(pbyPayload, abyPlainText, 16);
         wCnt++;
         pbyPayload += 16;
     } //for wPayloadSize
 
     //last payload
-    MEMvCopy(&(abyLastCipher[0]), pbyPayload, jj);
+    memcpy(&(abyLastCipher[0]), pbyPayload, jj);
     for ( ii=jj; ii<16; ii++ ) {
         abyLastCipher[ii] = 0x00;
     }
@@ -376,7 +368,7 @@ int             ii,jj,kk;
     for ( kk=0; kk<16; kk++ ) {
         abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
     }
-    MEMvCopy(pbyPayload, abyPlainText, jj);
+    memcpy(pbyPayload, abyPlainText, jj);
     pbyPayload += jj;
 
     //for MIC calculation
@@ -401,7 +393,7 @@ int             ii,jj,kk;
     //=>above is the dec-MIC from packet
     //--------------------------------------------
 
-    if ( MEMEqualMemory(abyMIC,abyTmp,8) ) {
+    if ( !memcmp(abyMIC,abyTmp,8) ) {
         return TRUE;
     } else {
         return FALSE;
diff --git a/drivers/staging/vt6655/aes_ccmp.h b/drivers/staging/vt6655/aes_ccmp.h
index 2b1920f..f2ba1d5 100644
--- a/drivers/staging/vt6655/aes_ccmp.h
+++ b/drivers/staging/vt6655/aes_ccmp.h
@@ -30,9 +30,7 @@
 #ifndef __AES_H__
 #define __AES_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
 
 /*---------------------  Export Definitions -------------------------*/
 
diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c
index bc6db86..cd5b8ea 100644
--- a/drivers/staging/vt6655/baseband.c
+++ b/drivers/staging/vt6655/baseband.c
@@ -16,6 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: baseband.c
  *
  * Purpose: Implement functions to access baseband
@@ -44,32 +45,16 @@
  *                                Add the comments.
  *      09-01-2003 Bryan YC Fan:  RF & BB tables updated.
  *                                Modified BBvLoopbackOn & BBvLoopbackOff().
+ *
+ *
  */
 
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__SROM_H__)
 #include "srom.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 //static int          msglevel                =MSG_LEVEL_DEBUG;
@@ -80,6 +65,7 @@ static int          msglevel                =MSG_LEVEL_INFO;
 /*---------------------  Static Classes  ----------------------------*/
 
 /*---------------------  Static Variables  --------------------------*/
+
 /*---------------------  Static Functions  --------------------------*/
 
 /*---------------------  Export Variables  --------------------------*/
@@ -1806,6 +1792,7 @@ BBuGetFrameTime (
 
 
     if (uRateIdx > RATE_54M) {
+	    ASSERT(0);
         return 0;
     }
 
@@ -2041,7 +2028,7 @@ BOOL BBbReadEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData)
     // W_MAX_TIMEOUT is the timeout period
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue);
-        if (BITbIsBitOn(byValue, BBREGCTL_DONE))
+        if (byValue & BBREGCTL_DONE)
             break;
     }
 
@@ -2050,7 +2037,7 @@ BOOL BBbReadEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, PBYTE pbyData)
 
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x30);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x30)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x30)\n");
         return FALSE;
     }
     return TRUE;
@@ -2086,13 +2073,13 @@ BOOL BBbWriteEmbeded (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byData)
     // W_MAX_TIMEOUT is the timeout period
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_BBREGCTL, &byValue);
-        if (BITbIsBitOn(byValue, BBREGCTL_DONE))
+        if (byValue & BBREGCTL_DONE)
             break;
     }
 
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x31);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x31)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x31)\n");
         return FALSE;
     }
     return TRUE;
@@ -2118,7 +2105,7 @@ BOOL BBbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
     BYTE byOrgData;
 
     BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData);
-    return BITbIsAllBitsOn(byOrgData, byTestBits);
+    return (byOrgData & byTestBits) == byTestBits;
 }
 
 
@@ -2141,7 +2128,7 @@ BOOL BBbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byBBAddr, BYTE byTestBits)
     BYTE byOrgData;
 
     BBbReadEmbeded(dwIoBase, byBBAddr, &byOrgData);
-    return BITbIsAllBitsOff(byOrgData, byTestBits);
+    return (byOrgData & byTestBits) == 0;
 }
 
 /*
@@ -2807,24 +2794,24 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3)
         return;
     }
     pDevice->uDiversityCnt++;
-   // DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt);
+   // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt);
 
     pDevice->uNumSQ3[byRxRate]++;
 
     if (pDevice->byAntennaState == 0) {
 
         if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ulDiversityNValue=[%d],54M-[%d]\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ulDiversityNValue=[%d],54M-[%d]\n",
                           (int)pDevice->ulDiversityNValue, (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate]);
 
             if (pDevice->uNumSQ3[pDevice->wAntDiversityMaxRate] < pDevice->uDiversityCnt/2) {
 
                 pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0, rate = [%08x]\n", (int)pDevice->ulRatio_State0);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0, rate = [%08x]\n", (int)pDevice->ulRatio_State0);
 
                 if ( pDevice->byTMax == 0 )
                     return;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1.[%08x], uNumSQ3[%d]=%d, %d\n",
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1.[%08x], uNumSQ3[%d]=%d, %d\n",
                               (int)pDevice->ulRatio_State0, (int)pDevice->wAntDiversityMaxRate,
                               (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt);
 #ifdef	PLICE_DEBUG
@@ -2852,11 +2839,11 @@ BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3)
             del_timer(&pDevice->TimerSQ3Tmax1);
 
             pDevice->ulRatio_State1 = s_ulGetRatio(pDevice);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n",
                           (int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1);
 
             if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
                               (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1,
                               (int)pDevice->wAntDiversityMaxRate,
                               (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt);
@@ -2896,12 +2883,10 @@ TimerSQ3CallBack (
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack...");
-
-
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack...");
     spin_lock_irq(&pDevice->lock);
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.[%08x][%08x], %d\n",(int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, (int)pDevice->uDiversityCnt);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.[%08x][%08x], %d\n",(int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, (int)pDevice->uDiversityCnt);
 #ifdef	PLICE_DEBUG
 		//printk("TimerSQ3CallBack1:call s_vChangeAntenna\n");
 #endif
@@ -2915,8 +2900,8 @@ TimerSQ3CallBack (
     add_timer(&pDevice->TimerSQ3Tmax3);
     add_timer(&pDevice->TimerSQ3Tmax2);
 
-    spin_unlock_irq(&pDevice->lock);
 
+    spin_unlock_irq(&pDevice->lock);
     return;
 }
 
@@ -2946,7 +2931,7 @@ TimerState1CallBack (
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerState1CallBack...");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerState1CallBack...");
 
     spin_lock_irq(&pDevice->lock);
     if (pDevice->uDiversityCnt < pDevice->ulDiversityMValue/100) {
@@ -2961,11 +2946,11 @@ TimerState1CallBack (
         add_timer(&pDevice->TimerSQ3Tmax2);
     } else {
         pDevice->ulRatio_State1 = s_ulGetRatio(pDevice);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State1, rate0 = %08x,rate1 = %08x\n",
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State1, rate0 = %08x,rate1 = %08x\n",
                       (int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1);
 
         if ( pDevice->ulRatio_State1 < pDevice->ulRatio_State0 ) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n",
                           (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1,
                           (int)pDevice->wAntDiversityMaxRate,
                           (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt);
diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h
index 09cf4f9..0682a39 100644
--- a/drivers/staging/vt6655/baseband.h
+++ b/drivers/staging/vt6655/baseband.h
@@ -16,6 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: baseband.h
  *
  * Purpose: Implement functions to access baseband
@@ -26,23 +27,12 @@
  *
  */
 
-
 #ifndef __BASEBAND_H__
 #define __BASEBAND_H__
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -106,12 +96,11 @@
 #define TOP_RATE_2M         0x00200000
 #define TOP_RATE_1M         0x00100000
 
+
 /*---------------------  Export Types  ------------------------------*/
 
 /*---------------------  Export Macros ------------------------------*/
 
-
-
 #define BBvClearFOE(dwIoBase)                               \
 {                                                           \
     BBbWriteEmbeded(dwIoBase, 0xB1, 0);                     \
@@ -128,9 +117,6 @@
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 UINT
 BBuGetFrameTime(
@@ -173,26 +159,19 @@ VOID BBvSetDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID);
 VOID BBvExitDeepSleep(DWORD_PTR dwIoBase, BYTE byLocalID);
 
 // timer for antenna diversity
+
 VOID
-TimerSQ3CallBack(
-    IN  HANDLE hDeviceContext
+TimerSQ3CallBack (
+    IN  HANDLE      hDeviceContext
     );
+
 VOID
 TimerState1CallBack(
-    IN  HANDLE hDeviceContext
+    IN  HANDLE      hDeviceContext
     );
 
 void BBvAntennaDiversity(PSDevice pDevice, BYTE byRxRate, BYTE bySQ3);
 VOID
 BBvClearAntDivSQ3Value (PSDevice pDevice);
 
-
-#ifdef __cplusplus
-}                /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif // __BASEBAND_H__
-
-
-
diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c
index 746fadc..9535d44 100644
--- a/drivers/staging/vt6655/bssdb.c
+++ b/drivers/staging/vt6655/bssdb.c
@@ -39,65 +39,23 @@
  *
  */
 
-
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif//chester
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__DATARATE_H__)
 #include "datarate.h"
-#endif
-#if !defined(__DESC_H__)
 #include "desc.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-#if !defined(__WPA_H__)
 #include "wpa.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__WPA2_H__)
 #include "wpa2.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-//DavidWang
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
-#endif
 
 //#define	PLICE_DEBUG
 /*---------------------  Static Definitions -------------------------*/
@@ -170,7 +128,7 @@ BSSpSearchBSSList(
     IN HANDLE hDeviceContext,
     IN PBYTE pbyDesireBSSID,
     IN PBYTE pbyDesireSSID,
-    IN CARD_PHY_TYPE ePhyType
+    IN CARD_PHY_TYPE  ePhyType
     )
 {
     PSDevice        pDevice = (PSDevice)hDeviceContext;
@@ -183,11 +141,11 @@ BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
     UINT            ii = 0;
 //    UINT            jj = 0;   //DavidWang
     if (pbyDesireBSSID != NULL) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n",
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n",
                             *pbyDesireBSSID,*(pbyDesireBSSID+1),*(pbyDesireBSSID+2),
                             *(pbyDesireBSSID+3),*(pbyDesireBSSID+4),*(pbyDesireBSSID+5));
         if ((!IS_BROADCAST_ADDRESS(pbyDesireBSSID)) &&
-	     (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)) {
+	     (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){
             pbyBSSID = pbyDesireBSSID;
         }
     }
@@ -207,7 +165,7 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
                 if (IS_ETH_ADDRESS_EQUAL(pCurrBSS->abyBSSID, pbyBSSID)) {
                     if (pSSID != NULL) {
                         // compare ssid
-                        if (MEMEqualMemory(pSSID->abySSID,
+                        if ( !memcmp(pSSID->abySSID,
                             ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
                             pSSID->len)) {
                             if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
@@ -240,19 +198,19 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
 
                 if (pSSID != NULL) {
                     // matched SSID
-                    if (!MEMEqualMemory(pSSID->abySSID,
+                    if (! !memcmp(pSSID->abySSID,
                         ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
                         pSSID->len) ||
                         (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) {
                         // SSID not match skip this BSS
                         continue;
-                    }
+                      }
                 }
                 if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
                     ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))
-                    ) {
+                    ){
                     // Type not match skip this BSS
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
                     continue;
                 }
 
@@ -260,7 +218,7 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
                     if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) ||
                         ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
                         // PhyType not match skip this BSS
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
                         continue;
                     }
                 }
@@ -299,8 +257,8 @@ if(pDevice->bLinkPass==FALSE) pCurrBSS->bSelected = FALSE;
 /*
                         if (pDevice->bRoaming == FALSE)  {
 	//       Einsn Add @20070907
-			ZERO_MEMORY(pbyDesireSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-			MEMvCopy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ;
+			memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+			memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ;
                                                 }*/
 
             return(pSelect);
@@ -398,7 +356,6 @@ BSSpAddrIsInBSSList(
 
 
 
-
 /*+
  *
  * Routine Description:
@@ -450,7 +407,7 @@ BSSbInsertToBSSList (
     }
 
     if (ii == MAX_BSS_NUM){
-        DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Get free KnowBSS node failed.\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
         return FALSE;
     }
     // save the BSS info
@@ -476,7 +433,7 @@ BSSbInsertToBSSList (
         if (pExtSuppRates->len > WLAN_RATES_MAXLEN)
             pExtSuppRates->len = WLAN_RATES_MAXLEN;
         memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len);
 
     } else {
         memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
@@ -543,7 +500,7 @@ BSSbInsertToBSSList (
             }
         }
         if ((bIs802_1x == TRUE) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
-            (MEMEqualMemory(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
+            ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
 
             bAdd_PMKID_Candidate((HANDLE)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj);
 
@@ -575,8 +532,6 @@ BSSbInsertToBSSList (
                             pIE_Country);
     }
 
-
-
     if ((bParsingQuiet == TRUE) && (pIE_Quiet != NULL)) {
         if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
             (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
@@ -611,7 +566,7 @@ BSSbInsertToBSSList (
     pBSSList->uIELength = uIELength;
     if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
         pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
-    MEMvCopy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
+    memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
 
     return TRUE;
 }
@@ -663,13 +618,14 @@ BSSbUpdateToBSSList (
     if (pBSSList == NULL)
         return FALSE;
 
+
     HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
     LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
     pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
     pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
     pBSSList->uClearCount = 0;
     pBSSList->uChannel = byCurrChannel;
-//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);
 
     if (pSSID->len > WLAN_SSID_MAXLEN)
         pSSID->len = WLAN_SSID_MAXLEN;
@@ -711,7 +667,7 @@ BSSbUpdateToBSSList (
         }
     }
 
-    WPA_ClearRSN(pBSSList);         //mike update
+   WPA_ClearRSN(pBSSList);         //mike update
 
     if (pRSNWPA != NULL) {
         UINT uLen = pRSNWPA->len + 2;
@@ -722,7 +678,7 @@ BSSbUpdateToBSSList (
         }
     }
 
-  WPA2_ClearRSN(pBSSList);  //mike update
+   WPA2_ClearRSN(pBSSList);  //mike update
 
     if (pRSN != NULL) {
         UINT uLen = pRSN->len + 2;
@@ -872,7 +828,7 @@ BSSvCreateOneNode(
     // if not found replace uInActiveCount is largest one.
     if ( ii == (MAX_NODE_NUM + 1)) {
         *puNodeIndex = SelectIndex;
-        DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
+        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
         // clear ps buffer
         if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
       	    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
@@ -890,7 +846,7 @@ BSSvCreateOneNode(
     skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
     pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
     pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
     return;
 };
 
@@ -982,7 +938,7 @@ BSSvUpdateAPNode(
 #endif
     // Auto rate fallback function initiation.
     // RATEbInit(pDevice);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
 
 };
 
@@ -1067,7 +1023,7 @@ BSSvSecondCallBack(
     UINT            uSleepySTACnt = 0;
     UINT            uNonShortSlotSTACnt = 0;
     UINT            uLongPreambleSTACnt = 0;
-viawget_wpa_header* wpahdr;
+    viawget_wpa_header* wpahdr;  //DavidWang
 
     spin_lock_irq(&pDevice->lock);
 
@@ -1078,14 +1034,14 @@ viawget_wpa_header* wpahdr;
  //2008-4-14 <add> by chester for led issue
 #ifdef FOR_LED_ON_NOTEBOOK
 MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
-if (((BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA)&&(pDevice->bHWRadioOff == FALSE))||(BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA)&&(pDevice->bHWRadioOff == TRUE)))&&(cc==FALSE)){
+if ((( !(pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == FALSE))||((pDevice->byGPIO & GPIO0_DATA)&&(pDevice->bHWRadioOff == TRUE)))&&(cc==FALSE)){
 cc=TRUE;
 }
 else if(cc==TRUE){
 
 if(pDevice->bHWRadioOff == TRUE){
-            if (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA))
-//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+            if ( !(pDevice->byGPIO & GPIO0_DATA))
+//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
 {if(status==1) goto start;
 status=1;
 CARDbRadioPowerOff(pDevice);
@@ -1096,15 +1052,15 @@ CARDbRadioPowerOff(pDevice);
                 pDevice->bLinkPass = FALSE;
 
 }
-  if (BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA))
-//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+  if (pDevice->byGPIO &GPIO0_DATA)
+//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
 {if(status==2) goto start;
 status=2;
 CARDbRadioPowerOn(pDevice);
 } }
 else{
-            if (BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA))
-//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+            if (pDevice->byGPIO & GPIO0_DATA)
+//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
 {if(status==3) goto start;
 status=3;
 CARDbRadioPowerOff(pDevice);
@@ -1115,8 +1071,8 @@ CARDbRadioPowerOff(pDevice);
                 pDevice->bLinkPass = FALSE;
 
 }
-  if (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA))
-//||(BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV)))
+  if ( !(pDevice->byGPIO & GPIO0_DATA))
+//||( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV)))
 {if(status==4) goto start;
 status=4;
 CARDbRadioPowerOn(pDevice);
@@ -1145,7 +1101,7 @@ start:
                   	union iwreq_data  wrqu;
                   	memset(&wrqu, 0, sizeof (wrqu));
                           wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-                  	printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+                  	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
                   	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
                        }
                     #endif
@@ -1161,14 +1117,13 @@ start:
     for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
 
         if (pMgmt->sNodeDBTable[ii].bActive) {
-
             // Increase in-activity counter
             pMgmt->sNodeDBTable[ii].uInActiveCount++;
 
             if (ii > 0) {
                 if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) {
                     BSSvRemoveOneNode(pDevice, ii);
-                    DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
                         "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii);
                     continue;
                 }
@@ -1200,7 +1155,6 @@ start:
             }
 
             // Rate fallback check
-
             if (!pDevice->bFixRate) {
 /*
                 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
@@ -1227,11 +1181,11 @@ start:
 
             // check if pending PS queue
             if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
                            ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
                 if ((ii >0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
                     BSSvRemoveOneNode(pDevice, ii);
-                    DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
+                    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
                     continue;
                 }
             }
@@ -1300,26 +1254,27 @@ start:
 
     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
     pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-//printk("pCurrSSID=%s\n",pCurrSSID->abySSID);
+
     if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
 
         if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
-           // DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+           // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount);
             //if (pDevice->bUpdateBBVGA) {
             //  s_vCheckSensitivity((HANDLE) pDevice);
             //}
+
             if (pDevice->bUpdateBBVGA) {
                // s_vCheckSensitivity((HANDLE) pDevice);
                s_vCheckPreEDThreshold((HANDLE)pDevice);
             }
+
     	    if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) &&
     	        (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) {
     	        pDevice->byBBVGANew = pDevice->abyBBVGA[0];
                 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
     	    }
 
-
         	if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) {
                 pMgmt->sNodeDBTable[0].bActive = FALSE;
                 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
@@ -1327,7 +1282,7 @@ start:
                 netif_stop_queue(pDevice->dev);
                 pDevice->bLinkPass = FALSE;
                 pDevice->bRoaming = TRUE;
-                DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
         if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
              wpahdr = (viawget_wpa_header *)pDevice->skb->data;
              wpahdr->type = VIAWGET_DISASSOC_MSG;
@@ -1335,7 +1290,7 @@ start:
              wpahdr->req_ie_len = 0;
              skb_put(pDevice->skb, sizeof(viawget_wpa_header));
              pDevice->skb->dev = pDevice->wpadev;
-             pDevice->skb->mac_header = pDevice->skb->data;
+	     skb_reset_mac_header(pDevice->skb);
              pDevice->skb->pkt_type = PACKET_HOST;
              pDevice->skb->protocol = htons(ETH_P_802_2);
              memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
@@ -1348,29 +1303,29 @@ start:
 	union iwreq_data  wrqu;
 	memset(&wrqu, 0, sizeof (wrqu));
         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
 	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
      }
   #endif
-			}
+	    }
         }
         else if (pItemSSID->len != 0) {
             if (pDevice->uAutoReConnectTime < 10) {
                 pDevice->uAutoReConnectTime++;
-	#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	       #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
                 //network manager support need not do Roaming scan???
                 if(pDevice->bWPASuppWextEnabled ==TRUE)
 		 pDevice->uAutoReConnectTime = 0;
 	     #endif
-
             }
             else {
-		    //mike use old encryption status for wpa reauthen
+	   //mike use old encryption status for wpa reauthen
 	      if(pDevice->bWPADEVUp)
 	          pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n");
+
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n");
                 BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
-	pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+ 	      pMgmt->eScanType = WMAC_SCAN_ACTIVE;
                 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
                 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
                 pDevice->uAutoReConnectTime = 0;
@@ -1385,20 +1340,21 @@ start:
                 pDevice->uAutoReConnectTime++;
             }
             else {
-                DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scaning ...\n");
-	pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scaning ...\n");
+	      pMgmt->eScanType = WMAC_SCAN_ACTIVE;
                 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
                 bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
                 pDevice->uAutoReConnectTime = 0;
             };
         }
         if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
+
             if (pDevice->bUpdateBBVGA) {
                //s_vCheckSensitivity((HANDLE) pDevice);
                s_vCheckPreEDThreshold((HANDLE)pDevice);
             }
         	if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) {
-        	    DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+        	    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
                 pMgmt->eCurrState = WMAC_STATE_STARTED;
                 netif_stop_queue(pDevice->dev);
@@ -1474,7 +1430,7 @@ BSSvUpdateNodeTxCounter(
 ////#endif
     // Only Unicast using support rates
     if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1);
         if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
             pMgmt->sNodeDBTable[0].uTxAttempts += 1;
             if ((byTsr1 & TSR1_TERR) == 0) {
@@ -1600,6 +1556,7 @@ BSSvUpdateNodeTxCounter(
 
     return;
 
+
 }
 
 
@@ -1641,7 +1598,7 @@ BSSvClearNodeDBTable(
             // check if sTxPSQueue has been initial
             if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) {
                 while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL){
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
                         dev_kfree_skb(skb);
                 }
             }
@@ -1683,7 +1640,7 @@ VOID s_vCheckSensitivity(
             if (uNumofdBm > 0) {
                 LocalldBmAverage = LocalldBmAverage/uNumofdBm;
                 for (ii=0;ii<BB_VGA_LEVEL;ii++) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]);
                     if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) {
                 	    pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
                         break;
@@ -1784,3 +1741,4 @@ VOID s_vCheckPreEDThreshold(
     }
     return;
 }
+
diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h
index d35616d..5ce4ef9 100644
--- a/drivers/staging/vt6655/bssdb.h
+++ b/drivers/staging/vt6655/bssdb.h
@@ -30,21 +30,10 @@
 #ifndef __BSSDB_H__
 #define __BSSDB_H__
 
-//#if !defined(__DEVICE_H__)
-//#include "device.h"
-//#endif
 #include <linux/skbuff.h>
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -103,13 +92,13 @@ typedef enum _NDIS_802_11_NETWORK_TYPE
 typedef struct tagSERPObject {
     BOOL    bERPExist;
     BYTE    byERP;
-} ERPObject, DEF* PERPObject;
+}ERPObject, *PERPObject;
 
 
 typedef struct tagSRSNCapObject {
     BOOL    bRSNCapExist;
     WORD    wRSNCap;
-} SRSNCapObject, DEF* PSRSNCapObject;
+}SRSNCapObject, *PSRSNCapObject;
 
 // BSS info(AP)
 #pragma pack(1)
@@ -126,11 +115,12 @@ typedef struct tagKnownBSS {
     WORD            wCapInfo;
     BYTE            abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
     BYTE            byRxRate;
+
 //    WORD            wATIMWindow;
     BYTE            byRSSIStatCnt;
     LONG            ldBmMAX;
     LONG            ldBmAverage[RSSI_STAT_COUNT];
-     LONG            ldBmAverRange;
+    LONG            ldBmAverRange;
     //For any BSSID selection improvment
     BOOL            bSelected;
 
@@ -174,7 +164,7 @@ typedef struct tagKnownBSS {
     BYTE            abyIEs[1024];   // don't move this field !!
 
 }__attribute__ ((__packed__))
-KnownBSS , DEF* PKnownBSS;
+KnownBSS , *PKnownBSS;
 
 //2006-1116-01,<Add> by NomadZhao
 #pragma pack()
@@ -245,7 +235,7 @@ typedef struct tagKnownNodeDB {
     UINT            uTxFail[MAX_RATE+1];
     UINT            uTimeCount;
 
-} KnownNodeDB, DEF* PKnownNodeDB;
+} KnownNodeDB, *PKnownNodeDB;
 
 
 /*---------------------  Export Functions  --------------------------*/
@@ -345,6 +335,7 @@ BSSvSecondCallBack(
     IN HANDLE hDeviceContext
     );
 
+
 VOID
 BSSvUpdateNodeTxCounter(
     IN HANDLE hDeviceContext,
diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c
index 723f44e..db78614 100644
--- a/drivers/staging/vt6655/card.c
+++ b/drivers/staging/vt6655/card.c
@@ -45,47 +45,17 @@
  *
  */
 
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__DESC_H__)
 #include "desc.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-#if !defined(__VNTWIFI_H__)
 #include "vntwifi.h"
-#endif
-#if !defined(__POWER_H__)
 #include "power.h"
-#endif
-#if !defined(__KEY_H__)
 #include "key.h"
-#endif
-#if !defined(__RC4_H__)
 #include "rc4.h"
-#endif
-#if !defined(__COUNTRY_H__)
 #include "country.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -115,7 +85,7 @@ typedef struct tagSChannelTblElement {
     UINT    uFrequency;
     BOOL    bValid;
     BYTE    byMAP;
-}SChannelTblElement, DEF* PSChannelTblElement;
+}SChannelTblElement, *PSChannelTblElement;
 
                                                               //1M,   2M,   5M,  11M,  18M,  24M,  36M,  54M
 static BYTE abyDefaultSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
@@ -837,7 +807,7 @@ BOOL CARDbSetChannel (PVOID pDeviceHandler, UINT uConnectionChannel)
         RFvWriteWakeProgSyn(pDevice->PortOffset, pDevice->byRFType, uConnectionChannel);
 
 
-    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDbSetMediaChannel: %d\n", (BYTE)uConnectionChannel);
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDbSetMediaChannel: %d\n", (BYTE)uConnectionChannel);
     BBvSoftwareReset(pDevice->PortOffset);
 
     if (pDevice->byLocalID > REV_ID_VT3253_B1) {
@@ -1332,7 +1302,7 @@ BOOL CARDbSetBSSID(PVOID pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode)
     PSDevice    pDevice = (PSDevice) pDeviceHandler;
 
     MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID);
-    MEMvCopy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN);
+    memcpy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN);
     if (eOPMode == OP_MODE_ADHOC) {
         MACvRegBitsOn(pDevice->PortOffset, MAC_REG_HOSTCR, HOSTCR_ADHOC);
     } else {
@@ -1347,14 +1317,14 @@ BOOL CARDbSetBSSID(PVOID pDeviceHandler, PBYTE pbyBSSID, CARD_OP_MODE eOPMode)
         MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
         pDevice->bBSSIDFilter = FALSE;
         pDevice->byRxMode &= ~RCR_BSSID;
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
     } else {
         if (IS_NULL_ADDRESS(pDevice->abyBSSID) == FALSE) {
             MACvRegBitsOn(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
             pDevice->bBSSIDFilter = TRUE;
             pDevice->byRxMode |= RCR_BSSID;
 	    }
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode );
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode );
     }
     // Adopt BSS state in Adapter Device Object
     pDevice->eOPMode = eOPMode;
@@ -1444,7 +1414,7 @@ CARDbPowerDown(
     }
 
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Go to Doze ZZZZZZZZZZZZZZZ\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Go to Doze ZZZZZZZZZZZZZZZ\n");
     return TRUE;
 }
 
@@ -1590,23 +1560,23 @@ CARDbAdd_PMKID_Candidate (
     PPMKID_CANDIDATE    pCandidateList;
     UINT                ii = 0;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
 
     if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 3\n");
-        ZERO_MEMORY(&pDevice->gsPMKIDCandidate, sizeof(SPMKIDCandidateEvent));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 3\n");
+        memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
     }
 
     for (ii = 0; ii < 6; ii++) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02X ", *(pbyBSSID + ii));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02X ", *(pbyBSSID + ii));
     }
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 
 
     // Update Old Candidate
     for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
         pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
-        if (MEMEqualMemory(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) {
+        if ( !memcmp(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) {
             if ((bRSNCapExist == TRUE) && (wRSNCap & BIT0)) {
                 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
             } else {
@@ -1623,9 +1593,9 @@ CARDbAdd_PMKID_Candidate (
     } else {
         pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
     }
-    MEMvCopy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN);
+    memcpy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN);
     pDevice->gsPMKIDCandidate.NumCandidates++;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
     return TRUE;
 }
 
@@ -1709,7 +1679,7 @@ VOID CARDvInitChannelTable (PVOID pDeviceHandler)
             }
         }
     }
- DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
+ DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
     for(ii=0;ii<CARD_MAX_CHANNEL_TBL;ii++) {
         if (pDevice->abyRegPwr[ii+1] == 0) {
             pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
@@ -2304,7 +2274,7 @@ CARDbChannelGetList (
     if (uCountryCodeIdx >= CCODE_MAX) {
         return (FALSE);
     }
-    MEMvCopy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL);
+    memcpy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL);
     return (TRUE);
 }
 
@@ -2403,7 +2373,7 @@ CARDbyAutoChannelSelect(
                 }
                 if (sChannelTbl[ii].byMAP == 0) {
                     return ((BYTE) ii);
-                } else if (BITbIsBitOff(sChannelTbl[ii].byMAP, 0x08)) {
+                } else if ( !(sChannelTbl[ii].byMAP & 0x08)) {
                     byOptionChannel = (BYTE) ii;
                 }
             }
@@ -2414,7 +2384,7 @@ CARDbyAutoChannelSelect(
             if (sChannelTbl[ii].bValid == TRUE) {
                 if (sChannelTbl[ii].byMAP == 0) {
                     aiWeight[ii] += 100;
-                } else if (BITbIsBitOn(sChannelTbl[ii].byMAP, 0x01)) {
+                } else if (sChannelTbl[ii].byMAP & 0x01) {
                     if (ii > 3) {
                         aiWeight[ii-3] -= 10;
                     }
@@ -2599,22 +2569,22 @@ WORD CARDwGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx)
     PSDevice pDevice = (PSDevice) pDeviceHandler;
     UINT ui = (UINT)wRateIdx;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate);
 
     if (!CARDbIsOFDMinBasicRate((PVOID)pDevice)) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
         if (wRateIdx > RATE_24M)
             wRateIdx = RATE_24M;
         return wRateIdx;
     }
     while (ui > RATE_11M) {
         if (pDevice->wBasicRate & ((WORD)1 << ui)) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate : %d\n", ui);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate : %d\n", ui);
             return (WORD)ui;
         }
         ui --;
     }
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate: 6M\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CARDwGetOFDMControlRate: 6M\n");
     return (WORD)RATE_24M;
 }
 
@@ -3002,7 +2972,7 @@ BOOL CARDbGetCurrentTSF (DWORD_PTR dwIoBase, PQWORD pqwCurrTSF)
     MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TSFCNTRRD);
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_TFTCTL, &byData);
-        if (BITbIsBitOff(byData, TFTCTL_TSFCNTRRD))
+        if ( !(byData & TFTCTL_TSFCNTRRD))
             break;
     }
     if (ww == W_MAX_TIMEOUT)
@@ -3085,7 +3055,7 @@ void CARDvSetFirstNextTBTT (DWORD_PTR dwIoBase, WORD wBeaconInterval)
     VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT));
     VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT));
     MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
-    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:First Next TBTT[%8xh:%8xh] \n", HIDWORD(qwNextTBTT), LODWORD(qwNextTBTT));
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:First Next TBTT[%8xh:%8xh] \n", HIDWORD(qwNextTBTT), LODWORD(qwNextTBTT));
     return;
 }
 
@@ -3113,7 +3083,7 @@ void CARDvUpdateNextTBTT (DWORD_PTR dwIoBase, QWORD qwTSF, WORD wBeaconInterval)
     VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF));
     VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF));
     MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n",(UINT)HIDWORD(qwTSF), (UINT)LODWORD(qwTSF));
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n",(UINT)HIDWORD(qwTSF), (UINT)LODWORD(qwTSF));
 
     return;
 }
diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h
index bb292e1..264b844 100644
--- a/drivers/staging/vt6655/card.h
+++ b/drivers/staging/vt6655/card.h
@@ -26,19 +26,10 @@
  *
  */
 
-
 #ifndef __CARD_H__
 #define __CARD_H__
 
-//#if !defined(__DEVICE_H__)
-//#include "device.h"
-//#endif
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 //
@@ -94,9 +85,6 @@ typedef enum _CARD_OP_MODE {
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 BOOL ChannelValid(UINT CountryCode, UINT ChannelIndex);
 void CARDvSetRSPINF(PVOID pDeviceHandler, CARD_PHY_TYPE ePHYType);
@@ -262,11 +250,6 @@ CARDbyAutoChannelSelect(
 
 BYTE CARDbyGetChannelNumber(PVOID pDeviceHandler, BYTE byChannelIndex);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif // __CARD_H__
 
 
diff --git a/drivers/staging/vt6655/country.h b/drivers/staging/vt6655/country.h
index 65d1e52..2005d27 100644
--- a/drivers/staging/vt6655/country.h
+++ b/drivers/staging/vt6655/country.h
@@ -30,10 +30,7 @@
 #ifndef __COUNTRY_H__
 #define __COUNTRY_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 /************************************************************************
@@ -168,7 +165,7 @@ typedef struct tagSCountryTable
     CHAR    chCountryCode[2];
     BYTE    bChannelIdxList[CB_MAX_CHANNEL];  /* Available channels Index */
     BYTE    byPower[CB_MAX_CHANNEL];
-}   SCountryTable, DEF* PSCountryTable;
+}   SCountryTable, *PSCountryTable;
 
 /*---------------------  Export Classes  ----------------------------*/
 
@@ -176,17 +173,5 @@ typedef struct tagSCountryTable
 extern SCountryTable ChannelRuleTab[CCODE_MAX+1];
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
-
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
 
-
-/************************************************************************
- * Function prototype
- ************************************************************************/
 #endif  /* __COUNTRY_H__ */
diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c
index f58f963..10da57f 100644
--- a/drivers/staging/vt6655/datarate.c
+++ b/drivers/staging/vt6655/datarate.c
@@ -33,33 +33,15 @@
  *
  */
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__DATARATE_H__)
 #include "datarate.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__SROM_H__)
 #include "srom.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -239,7 +221,7 @@ UINT  uRateLen;
     *pwSuppRate = 0;
     uRateLen = pItemRates->len;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
     if (pDevice->eCurrentPHYType != PHY_TYPE_11B) {
         if (uRateLen > WLAN_RATES_MAXLEN)
             uRateLen = WLAN_RATES_MAXLEN;
@@ -254,7 +236,7 @@ UINT  uRateLen;
             (bUpdateBasicRate == TRUE))  {
             // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
             CARDbAddBasicRate((PVOID)pDevice, wGetRateIdx(byRate));
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
         }
         byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
         if (byHighSuppRate == 0)
@@ -277,7 +259,7 @@ UINT  uRateLen;
             if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
             	// Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
                 CARDbAddBasicRate((PVOID)pDevice, wGetRateIdx(byRate));
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate));
             }
             byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F);
             if (byHighSuppRate == 0)
@@ -303,7 +285,7 @@ UINT  uRateLen;
     if (wOldBasicRate != pDevice->wBasicRate)
         CARDvSetRSPINF((PVOID)pDevice, pDevice->eCurrentPHYType);
 
-     DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
+     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
 }
 
 
diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h
index c0fc1d3..b573ef7 100644
--- a/drivers/staging/vt6655/desc.h
+++ b/drivers/staging/vt6655/desc.h
@@ -28,26 +28,13 @@
  *
  */
 
-
 #ifndef __DESC_H__
 #define __DESC_H__
 
 #include <linux/types.h>
 #include <linux/mm.h>
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-// #ifdef PRIVATE_OBJ
-//#if !defined(__DEVICE_MODULE_H)
-//#include "device_module.h"
-//#endif
-
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -135,6 +122,7 @@
 #define CB_PROTOCOL_RESERVED_SECTION    16
 
 
+
 // if retrys excess 15 times , tx will abort, and
 // if tx fifo underflow, tx will fail
 // we should try to resend it
@@ -237,9 +225,6 @@
 
 typedef struct tagDEVICE_RD_INFO {
     struct sk_buff* skb;
-#ifdef PRIVATE_OBJ
-    ref_sk_buff ref_skb;
-#endif
     dma_addr_t  skb_dma;
     dma_addr_t  curr_desc;
 } DEVICE_RD_INFO,   *PDEVICE_RD_INFO;
@@ -311,8 +296,8 @@ typedef struct tagSRxDesc {
     volatile PDEVICE_RD_INFO    pRDInfo;//4 bytes
     volatile U32    Reserved[2];//8 bytes
 } __attribute__ ((__packed__))
-SRxDesc, DEF* PSRxDesc;
-typedef const SRxDesc DEF*      PCSRxDesc;
+SRxDesc, *PSRxDesc;
+typedef const SRxDesc *PCSRxDesc;
 
 #ifdef __BIG_ENDIAN
 
@@ -397,8 +382,8 @@ typedef struct tagSTxDesc {
     volatile    PDEVICE_TD_INFO pTDInfo;//4 bytes
     volatile    U32    Reserved[2];//8 bytes
 } __attribute__ ((__packed__))
-STxDesc, DEF* PSTxDesc;
-typedef const STxDesc DEF*      PCSTxDesc;
+STxDesc, *PSTxDesc;
+typedef const STxDesc *PCSTxDesc;
 
 
 typedef struct tagSTxSyncDesc {
@@ -412,8 +397,8 @@ typedef struct tagSTxSyncDesc {
     volatile    PDEVICE_TD_INFO pTDInfo;//4 bytes
     volatile    DWORD   m_dwReserved2;
 } __attribute__ ((__packed__))
-STxSyncDesc, DEF* PSTxSyncDesc;
-typedef const STxSyncDesc DEF*      PCSTxSyncDesc;
+STxSyncDesc, *PSTxSyncDesc;
+typedef const STxSyncDesc *PCSTxSyncDesc;
 
 
 //
@@ -427,8 +412,8 @@ typedef struct tagSRrvTime_gRTS {
     WORD        wTxRrvTime_b;
     WORD        wTxRrvTime_a;
 }__attribute__ ((__packed__))
-SRrvTime_gRTS, DEF* PSRrvTime_gRTS;
-typedef const SRrvTime_gRTS DEF*     PCSRrvTime_gRTS;
+SRrvTime_gRTS, *PSRrvTime_gRTS;
+typedef const SRrvTime_gRTS *PCSRrvTime_gRTS;
 
 typedef struct tagSRrvTime_gCTS {
     WORD        wCTSTxRrvTime_ba;
@@ -436,22 +421,22 @@ typedef struct tagSRrvTime_gCTS {
     WORD        wTxRrvTime_b;
     WORD        wTxRrvTime_a;
 }__attribute__ ((__packed__))
-SRrvTime_gCTS, DEF* PSRrvTime_gCTS;
-typedef const SRrvTime_gCTS DEF*     PCSRrvTime_gCTS;
+SRrvTime_gCTS, *PSRrvTime_gCTS;
+typedef const SRrvTime_gCTS *PCSRrvTime_gCTS;
 
 typedef struct tagSRrvTime_ab {
     WORD        wRTSTxRrvTime;
     WORD        wTxRrvTime;
 }__attribute__ ((__packed__))
-SRrvTime_ab, DEF* PSRrvTime_ab;
-typedef const SRrvTime_ab DEF*     PCSRrvTime_ab;
+SRrvTime_ab, *PSRrvTime_ab;
+typedef const SRrvTime_ab *PCSRrvTime_ab;
 
 typedef struct tagSRrvTime_atim {
     WORD        wCTSTxRrvTime_ba;
     WORD        wTxRrvTime_a;
 }__attribute__ ((__packed__))
-SRrvTime_atim, DEF* PSRrvTime_atim;
-typedef const SRrvTime_atim DEF*     PCSRrvTime_atim;
+SRrvTime_atim, *PSRrvTime_atim;
+typedef const SRrvTime_atim *PCSRrvTime_atim;
 
 //
 // RTS buffer header
@@ -462,8 +447,8 @@ typedef struct tagSRTSData {
     BYTE    abyRA[U_ETHER_ADDR_LEN];
     BYTE    abyTA[U_ETHER_ADDR_LEN];
 }__attribute__ ((__packed__))
-SRTSData, DEF* PSRTSData;
-typedef const SRTSData DEF*      PCSRTSData;
+SRTSData, *PSRTSData;
+typedef const SRTSData *PCSRTSData;
 
 typedef struct tagSRTS_g {
     BYTE        bySignalField_b;
@@ -478,8 +463,8 @@ typedef struct tagSRTS_g {
     WORD        wReserved;
     SRTSData    Data;
 }__attribute__ ((__packed__))
-SRTS_g, DEF* PSRTS_g;
-typedef const SRTS_g DEF*     PCSRTS_g;
+SRTS_g, *PSRTS_g;
+typedef const SRTS_g *PCSRTS_g;
 
 
 typedef struct tagSRTS_g_FB {
@@ -499,8 +484,8 @@ typedef struct tagSRTS_g_FB {
     WORD        wRTSDuration_aa_f1;
     SRTSData    Data;
 }__attribute__ ((__packed__))
-SRTS_g_FB, DEF* PSRTS_g_FB;
-typedef const SRTS_g_FB DEF*     PCSRTS_g_FB;
+SRTS_g_FB, *PSRTS_g_FB;
+typedef const SRTS_g_FB *PCSRTS_g_FB;
 
 
 typedef struct tagSRTS_ab {
@@ -511,8 +496,8 @@ typedef struct tagSRTS_ab {
     WORD        wReserved;
     SRTSData    Data;
 }__attribute__ ((__packed__))
-SRTS_ab, DEF* PSRTS_ab;
-typedef const SRTS_ab DEF*     PCSRTS_ab;
+SRTS_ab, *PSRTS_ab;
+typedef const SRTS_ab *PCSRTS_ab;
 
 
 typedef struct tagSRTS_a_FB {
@@ -525,8 +510,8 @@ typedef struct tagSRTS_a_FB {
     WORD        wRTSDuration_f1;
     SRTSData    Data;
 }__attribute__ ((__packed__))
-SRTS_a_FB, DEF* PSRTS_a_FB;
-typedef const SRTS_a_FB DEF*     PCSRTS_a_FB;
+SRTS_a_FB, *PSRTS_a_FB;
+typedef const SRTS_a_FB *PCSRTS_a_FB;
 
 
 //
@@ -538,7 +523,7 @@ typedef struct tagSCTSData {
     BYTE    abyRA[U_ETHER_ADDR_LEN];
     WORD    wReserved;
 }__attribute__ ((__packed__))
-SCTSData, DEF* PSCTSData;
+SCTSData, *PSCTSData;
 
 typedef struct tagSCTS {
     BYTE        bySignalField_b;
@@ -548,8 +533,8 @@ typedef struct tagSCTS {
     WORD        wReserved;
     SCTSData    Data;
 }__attribute__ ((__packed__))
-SCTS, DEF* PSCTS;
-typedef const SCTS DEF*     PCSCTS;
+SCTS, *PSCTS;
+typedef const SCTS *PCSCTS;
 
 typedef struct tagSCTS_FB {
     BYTE        bySignalField_b;
@@ -561,8 +546,8 @@ typedef struct tagSCTS_FB {
     WORD        wCTSDuration_ba_f1;
     SCTSData    Data;
 }__attribute__ ((__packed__))
-SCTS_FB, DEF* PSCTS_FB;
-typedef const SCTS_FB DEF*     PCSCTS_FB;
+SCTS_FB, *PSCTS_FB;
+typedef const SCTS_FB *PCSCTS_FB;
 
 
 //
@@ -576,15 +561,15 @@ typedef struct tagSTxBufHead {
     BYTE    byTxPower;
     BYTE    wReserved;
 }__attribute__ ((__packed__))
-STxBufHead, DEF* PSTxBufHead;
-typedef const STxBufHead DEF*   PCSTxBufHead;
+STxBufHead, *PSTxBufHead;
+typedef const STxBufHead *PCSTxBufHead;
 
 typedef struct tagSTxShortBufHead {
     WORD    wFIFOCtl;
     WORD    wTimeStamp;
 }__attribute__ ((__packed__))
-STxShortBufHead, DEF* PSTxShortBufHead;
-typedef const STxShortBufHead DEF*   PCSTxShortBufHead;
+STxShortBufHead, *PSTxShortBufHead;
+typedef const STxShortBufHead *PCSTxShortBufHead;
 
 //
 // Tx data header
@@ -601,8 +586,8 @@ typedef struct tagSTxDataHead_g {
     WORD    wTimeStampOff_b;
     WORD    wTimeStampOff_a;
 }__attribute__ ((__packed__))
-STxDataHead_g, DEF* PSTxDataHead_g;
-typedef const STxDataHead_g DEF*  PCSTxDataHead_g;
+STxDataHead_g, *PSTxDataHead_g;
+typedef const STxDataHead_g *PCSTxDataHead_g;
 
 typedef struct tagSTxDataHead_g_FB {
     BYTE    bySignalField_b;
@@ -618,8 +603,8 @@ typedef struct tagSTxDataHead_g_FB {
     WORD    wTimeStampOff_b;
     WORD    wTimeStampOff_a;
 }__attribute__ ((__packed__))
-STxDataHead_g_FB, DEF* PSTxDataHead_g_FB;
-typedef const STxDataHead_g_FB DEF*  PCSTxDataHead_g_FB;
+STxDataHead_g_FB, *PSTxDataHead_g_FB;
+typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB;
 
 
 typedef struct tagSTxDataHead_ab {
@@ -629,8 +614,8 @@ typedef struct tagSTxDataHead_ab {
     WORD    wDuration;
     WORD    wTimeStampOff;
 }__attribute__ ((__packed__))
-STxDataHead_ab, DEF* PSTxDataHead_ab;
-typedef const STxDataHead_ab DEF*  PCSTxDataHead_ab;
+STxDataHead_ab, *PSTxDataHead_ab;
+typedef const STxDataHead_ab *PCSTxDataHead_ab;
 
 
 typedef struct tagSTxDataHead_a_FB {
@@ -642,8 +627,8 @@ typedef struct tagSTxDataHead_a_FB {
     WORD    wDuration_f0;
     WORD    wDuration_f1;
 }__attribute__ ((__packed__))
-STxDataHead_a_FB, DEF* PSTxDataHead_a_FB;
-typedef const STxDataHead_a_FB DEF*  PCSTxDataHead_a_FB;
+STxDataHead_a_FB, *PSTxDataHead_a_FB;
+typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
 
 //
 // MICHDR data header
@@ -653,8 +638,8 @@ typedef struct tagSMICHDRHead {
     DWORD   adwHDR1[4];
     DWORD   adwHDR2[4];
 }__attribute__ ((__packed__))
-SMICHDRHead, DEF* PSMICHDRHead;
-typedef const SMICHDRHead DEF*   PCSMICHDRHead;
+SMICHDRHead, *PSMICHDRHead;
+typedef const SMICHDRHead *PCSMICHDRHead;
 
 typedef struct tagSBEACONCtl {
     DWORD   BufReady : 1;
diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h
index 264d1bb..fa7f0fc 100644
--- a/drivers/staging/vt6655/device.h
+++ b/drivers/staging/vt6655/device.h
@@ -29,13 +29,7 @@
 #ifndef __DEVICE_H__
 #define __DEVICE_H__
 
-#ifdef MODULE
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif /* MODVERSIONS */
 #include <linux/module.h>
-#endif /* MODULE */
-
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/mm.h>
@@ -70,70 +64,34 @@
 #endif
 /* Include Wireless Extension definition and check version - Jean II */
 #include <linux/wireless.h>
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>	// New driver API
-#endif	/* WIRELESS_EXT > 12 */
 
 //2008-0409-07, <Add> by Einsn Liu
-#if WIRELESS_EXT > 17
 #ifndef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 #define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 #endif
-#endif
 //2008-4-14<add> by chester for led issue
 //#define FOR_LED_ON_NOTEBOOK
 //
 
 
-
-//  device specific
 //
-#if !defined(_KCOMPAT_H)
-#include "kcompat.h"
-#endif
+// device specific
+//
 
-#if !defined(__DEVICE_CONFIG_H)
+#include "kcompat.h"
 #include "device_cfg.h"
-#endif
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-#if !defined(__MIB_H__)
 #include "mib.h"
-#endif
-#if !defined(__SROM_H__)
 #include "srom.h"
-#endif
-#if !defined(__RC4_H__)
 #include "rc4.h"
-#endif
-#if !defined(__TPCI_H__)
-#include "tpci.h"
-#endif
-#if !defined(__DESC_H__)
 #include "desc.h"
-#endif
-
-#if !defined(__KEY_H__)
 #include "key.h"
-#endif
-
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
 
 //PLICE_DEBUG->
 //#define		THREAD
@@ -141,11 +99,6 @@
 //#define	TASK_LET
 //PLICE_DEBUG<-
 
-// #ifdef PRIVATE_OBJ
-//#if !defined(__DEVICE_MODULE_H)
-//#include "device_module.h"
-//#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -198,6 +151,7 @@
 #define BB_VGA_CHANGE_THRESHOLD 16
 
 
+
 #ifndef RUN_AT
 #define RUN_AT(x)                       (jiffies+(x))
 #endif
@@ -207,93 +161,6 @@
 
 
 // BUILD OBJ mode
-#ifdef PRIVATE_OBJ
-
-#undef dev_kfree_skb
-#undef dev_kfree_skb_irq
-#undef dev_alloc_skb
-#undef kfree
-#undef del_timer
-#undef init_timer
-#undef add_timer
-#undef kmalloc
-#undef netif_stop_queue
-#undef netif_start_queue
-#undef netif_wake_queue
-#undef netif_queue_stopped
-#undef netif_rx
-#undef netif_running
-#undef udelay
-#undef mdelay
-#undef eth_type_trans
-#undef skb_put
-#undef HZ
-#undef RUN_AT
-#undef pci_alloc_consistent
-#undef pci_free_consistent
-#undef register_netdevice
-#undef register_netdev
-#undef unregister_netdevice
-#undef unregister_netdev
-#undef skb_queue_head_init
-#undef skb_queue_tail
-#undef skb_queue_empty
-#undef free_irq
-#undef copy_from_user
-#undef copy_to_user
-#undef spin_lock_init
-#undef pci_map_single
-#undef pci_unmap_single
-
-// redefine kernel dependent fucntion
-#define dev_kfree_skb       ref_dev_kfree_skb
-#define dev_kfree_skb_irq   ref_dev_kfree_skb_irq
-#define dev_alloc_skb       ref_dev_alloc_skb
-#define kfree               ref_kfree
-#define del_timer           ref_del_timer
-#define init_timer          ref_init_timer
-#define add_timer           ref_add_timer
-#define kmalloc             ref_kmalloc
-#define netif_stop_queue    ref_netif_stop_queue
-#define netif_start_queue   ref_netif_start_queue
-#define netif_wake_queue    ref_netif_wake_queue
-#define netif_queue_stopped ref_netif_queue_stopped
-#define netif_rx            ref_netif_rx
-#define netif_running       ref_netif_running
-#define udelay              ref_udelay
-#define mdelay              ref_mdelay
-#define get_jiffies()       ref_get_jiffies()
-#define RUN_AT(x)           (get_jiffies()+(x))
-#define HZ                  ref_HZ_tick()
-#define eth_type_trans      ref_eth_type_trans
-#define skb_put             ref_skb_put
-#define skb_queue_head_init ref_skb_queue_head_init
-#define skb_queue_tail      ref_skb_queue_tail
-#define skb_queue_empty     ref_skb_queue_empty
-
-#define pci_alloc_consistent    ref_pci_alloc_consistent
-#define pci_free_consistent     ref_pci_free_consistent
-#define register_netdevice      ref_register_netdevice
-#define register_netdev         ref_register_netdev
-#define unregister_netdevice    ref_unregister_netdevice
-#define unregister_netdev       ref_unregister_netdev
-
-#define free_irq                ref_free_irq
-#define copy_from_user          ref_copy_from_user
-#define copy_to_user            ref_copy_to_user
-#define spin_lock_init          ref_spin_lock_init
-#define pci_map_single          ref_pci_map_single
-#define pci_unmap_single        ref_pci_unmap_single
-#endif
-
-
-#ifdef PRIVATE_OBJ
-#undef  printk
-#define DEVICE_PRT(l, p, args...) {if (l<=msglevel) do {} while (0);}
-//#define DEVICE_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
-#else
-#define DEVICE_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
-#endif
 
 
 #define	AVAIL_TD(p,q)	((p)->sOpts.nTxDescs[(q)]-((p)->iTDUsed[(q)]))
@@ -304,9 +171,14 @@
 
 
 
+#define PRIVATE_Message                 0
+
 /*---------------------  Export Types  ------------------------------*/
 
 
+#define DBG_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
+#define PRINT_K(p, args...) {if (PRIVATE_Message) printk( p ,##args);}
+
 //0:11A 1:11B 2:11G
 typedef enum _VIA_BB_TYPE
 {
@@ -401,8 +273,7 @@ typedef struct tagSPMKIDCandidateEvent {
     ULONG Version;       // Version of the structure
     ULONG NumCandidates; // No. of pmkid candidates
     PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST];
-} SPMKIDCandidateEvent, DEF* PSPMKIDCandidateEvent;
-
+} SPMKIDCandidateEvent, *PSPMKIDCandidateEvent;
 
 //--
 
@@ -414,7 +285,7 @@ typedef struct tagSQuietControl {
     DWORD       dwStartTime;
     BYTE        byPeriod;
     WORD        wDuration;
-} SQuietControl, DEF* PSQuietControl;
+} SQuietControl, *PSQuietControl;
 
 //--
 typedef struct __chip_info_tbl{
@@ -438,7 +309,6 @@ typedef struct tagSCacheEntry{
     BYTE        abyAddr2[U_ETHER_ADDR_LEN];
 } SCacheEntry, *PSCacheEntry;
 
-
 typedef struct tagSCache{
 /* The receive cache is updated circularly.  The next entry to be written is
  * indexed by the "InPtr".
@@ -456,14 +326,10 @@ typedef struct tagSDeFragControlBlock
     BYTE            abyAddr2[U_ETHER_ADDR_LEN];
 	UINT            uLifetime;
     struct sk_buff* skb;
-#ifdef PRIVATE_OBJ
-    ref_sk_buff     ref_skb;
-#endif
     PBYTE           pbyRxBuffer;
     UINT            cbFrameLength;
     BOOL            bInUse;
-} SDeFragControlBlock, DEF* PSDeFragControlBlock;
-
+} SDeFragControlBlock, *PSDeFragControlBlock;
 
 
 
@@ -511,11 +377,11 @@ typedef	struct _RxManagementQueue
 
 
 typedef struct __device_opt {
-    int         nRxDescs0;      //Number of RX descriptors0
-    int         nRxDescs1;      //Number of RX descriptors1
-    int         nTxDescs[2];    //Number of TX descriptors 0, 1
-    int         int_works;      //interrupt limits
-    int         rts_thresh;     //rts threshold
+    int         nRxDescs0;    //Number of RX descriptors0
+    int         nRxDescs1;    //Number of RX descriptors1
+    int         nTxDescs[2];  //Number of TX descriptors 0, 1
+    int         int_works;    //interrupt limits
+    int         rts_thresh;   //rts threshold
     int         frag_thresh;
     int         data_rate;
     int         channel_num;
@@ -703,8 +569,8 @@ typedef struct __device_info {
     BYTE                        byERPFlag;
     WORD                        wUseProtectCntDown;
 
-    BOOL                    bRadioControlOff;
-    BOOL                    bRadioOff;
+    BOOL                        bRadioControlOff;
+    BOOL                        bRadioOff;
     BOOL                    bEnablePSMode;
     WORD                    wListenInterval;
     BOOL                    bPWBitOn;
@@ -760,6 +626,7 @@ typedef struct __device_info {
 //2007-0925-01<Add>by MikeLiu
 //mike add :save old Encryption
     NDIS_802_11_WEP_STATUS  eOldEncryptionStatus;
+
     SKeyManagement          sKey;
     DWORD                   dwIVCounter;
 
@@ -768,7 +635,6 @@ typedef struct __device_info {
 
     RC4Ext                  SBox;
     BYTE                    abyPRNG[WLAN_WEPMAX_KEYLEN+3];
-
     BYTE                    byKeyIndex;
     UINT                    uKeyLength;
     BYTE                    abyKey[WLAN_WEP232_KEYLEN];
@@ -807,6 +673,7 @@ typedef struct __device_info {
     BYTE                    byBBPreEDRSSI;
     BYTE                    byBBPreEDIndex;
 
+
     BOOL                    bRadioCmd;
     DWORD                   dwDiagRefCount;
 
@@ -954,9 +821,7 @@ typedef struct __device_info {
     UINT                    uChannel;
     BOOL                    bMACSuspend;
 
-#ifdef WIRELESS_EXT
 	struct iw_statistics	wstats;		// wireless stats
-#endif /* WIRELESS_EXT */
     BOOL                    bCommit;
 
 } DEVICE_INFO, *PSDevice;
diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h
index 1cbb444..d1e9c19 100644
--- a/drivers/staging/vt6655/device_cfg.h
+++ b/drivers/staging/vt6655/device_cfg.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 1996, 2003 VIA Networking, Inc. All rights reserved.
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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
@@ -15,7 +16,6 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- *
  * File: device_cfg.h
  *
  * Purpose: Driver configuration header
@@ -30,46 +30,13 @@
 //#include <linux/config.h>
 #include <linux/types.h>
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-
-
-typedef __u8    UINT8,   *PUINT8;
-typedef __u16   UINT16,  *PUINT16;
-typedef __u32   UINT32,  *PUINT32;
-
-
-#ifndef VOID
-#define VOID            void
-#endif
-
-#ifndef CONST
-#define CONST           const
-#endif
-
-#ifndef STATIC
-#define STATIC          static
-#endif
-
-#ifndef DEF
-#define DEF
-#endif
-
-#ifndef IN
-#define IN
-#endif
-
-#ifndef OUT
-#define OUT
-#endif
 
 typedef
 struct _version {
-    UINT8   major;
-    UINT8   minor;
-    UINT8   build;
+    unsigned char   major;
+    unsigned char   minor;
+    unsigned char   build;
 } version_t, *pversion_t;
 
 #ifndef FALSE
@@ -100,6 +67,7 @@ struct _version {
 #ifndef DEVICE_VERSION
 #define DEVICE_VERSION       "1.19.12"
 #endif
+
 //config file
 #include <linux/fs.h>
 #include <linux/fcntl.h>
@@ -111,8 +79,6 @@ struct _version {
 #define PKT_BUF_SZ          2390
 
 
-#define MALLOC(x,y)         kmalloc((x),(y))
-#define FREE(x)             kfree((x))
 #define MAX_UINTS           8
 #define OPTION_DEFAULT      { [0 ... MAX_UINTS-1] = -1}
 
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index f43ca41..53450b4 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -60,88 +60,31 @@
  */
 #undef __NO_VERSION__
 
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__WCTL_H__)
 #include "wctl.h"
-#endif
-#if !defined(__POWER_H__)
 #include "power.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-#if !defined(__IOCMD_H__)
 #include "iocmd.h"
-#endif
-#if !defined(__TCRC_H__)
 #include "tcrc.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-#if !defined(__WROUTE_H__)
 #include "wroute.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__HOSTAP_H__)
 #include "hostap.h"
-#endif
-#if !defined(__WPACTL_H__)
 #include "wpactl.h"
-#endif
-#if !defined(__IOCTL_H__)
 #include "ioctl.h"
-#endif
-#if !defined(__IWCTL_H__)
 #include "iwctl.h"
-#endif
-#if !defined(__DPC_H__)
 #include "dpc.h"
-#endif
-#if !defined(__DATARATE_H__)
 #include "datarate.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
-#endif
-
 #include <linux/delay.h>
 #include <linux/kthread.h>
-// #ifdef PRIVATE_OBJ
-//#if !defined(__DEVICE_EXP_H)
-//#include "device_exp.h"
-//#endif
-//#if !defined(__DEVICE_MODULE_H)
-//#include "device_module.h"
-//#endif
-
 
-// #endif
 //#define	DEBUG
 /*---------------------  Static Definitions -------------------------*/
 //static int          msglevel                =MSG_LEVEL_DEBUG;
@@ -151,11 +94,9 @@ static int          msglevel                =   MSG_LEVEL_INFO;
 //
 // Define module options
 //
-#ifndef PRIVATE_OBJ
 MODULE_AUTHOR("VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("VIA Networking Solomon-A/B/G Wireless LAN Adapter Driver");
-#endif
 
 //PLICE_DEBUG ->
 	static int mlme_kill;
@@ -332,7 +273,6 @@ DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode");
 //
 
 
-#ifndef PRIVATE_OBJ
 static int          device_nics             =0;
 static PSDevice     pDevice_Infos           =NULL;
 static struct net_device *root_device_dev = NULL;
@@ -343,15 +283,13 @@ static CHIP_INFO chip_info_table[]= {
     {0,NULL}
 };
 
-static struct pci_device_id device_id_table[] __devinitdata = {
-{ 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long)&chip_info_table[0]},
-{ 0, }
+DEFINE_PCI_DEVICE_TABLE(device_id_table) = {
+	{ PCI_VDEVICE(VIA, 0x3253), (kernel_ulong_t)chip_info_table},
+	{ 0, }
 };
-#endif
 
 /*---------------------  Static Functions  --------------------------*/
 
-#ifndef PRIVATE_OBJ
 
 static int  device_found1(struct pci_dev *pcid, const struct pci_device_id *ent);
 static BOOL device_init_info(struct pci_dev* pcid, PSDevice* ppDevice, PCHIP_INFO);
@@ -378,7 +316,6 @@ struct notifier_block device_notifier = {
 };
 #endif
 
-#endif // #ifndef PRIVATE_OBJ
 
 static void device_init_rd0_ring(PSDevice pDevice);
 static void device_init_rd1_ring(PSDevice pDevice);
@@ -386,9 +323,7 @@ static void device_init_defrag_cb(PSDevice pDevice);
 static void device_init_td0_ring(PSDevice pDevice);
 static void device_init_td1_ring(PSDevice pDevice);
 
-#ifndef PRIVATE_OBJ
 static int  device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
-#endif
 //2008-0714<Add>by Mike Liu
 static BOOL device_release_WPADEV(PSDevice pDevice);
 
@@ -412,7 +347,6 @@ static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source);
 /*---------------------  Export Functions  --------------------------*/
 
 
-#ifndef PRIVATE_OBJ
 
 static char* get_chip_name(int chip_id) {
     int i;
@@ -422,7 +356,7 @@ static char* get_chip_name(int chip_id) {
     return chip_info_table[i].name;
 }
 
-static void __devexit device_remove1(struct pci_dev *pcid)
+static void device_remove1(struct pci_dev *pcid)
 {
     PSDevice pDevice=pci_get_drvdata(pcid);
 
@@ -432,34 +366,33 @@ static void __devexit device_remove1(struct pci_dev *pcid)
 
 }
 
-#endif
 /*
 static void
 device_set_int_opt(int *opt, int val, int min, int max, int def,char* name,char* devname) {
     if (val==-1)
         *opt=def;
     else if (val<min || val>max) {
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n" ,
+        DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n" ,
             devname,name, min,max);
         *opt=def;
     } else {
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n",
             devname, name, val);
         *opt=val;
     }
 }
 
 static void
-device_set_bool_opt(PU32 opt, int val,BOOL def,U32 flag, char* name,char* devname) {
+device_set_bool_opt(unsigned int *opt, int val,BOOL def,U32 flag, char* name,char* devname) {
     (*opt)&=(~flag);
     if (val==-1)
         *opt|=(def ? flag : 0);
     else if (val<0 || val>1) {
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_NOTICE
+        DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE
             "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",devname,name);
         *opt|=(def ? flag : 0);
     } else {
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: set parameter %s to %s\n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: set parameter %s to %s\n",
             devname,name , val ? "TRUE" : "FALSE");
         *opt|=(val ? flag : 0);
     }
@@ -530,18 +463,18 @@ pDevice->bUpdateBBVGA = TRUE;
     pDevice->byPreambleType = 0;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uChannel= %d\n",(INT)pDevice->uChannel);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byOpMode= %d\n",(INT)pDevice->byOpMode);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ePSMode= %d\n",(INT)pDevice->ePSMode);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" wRTSThreshold= %d\n",(INT)pDevice->wRTSThreshold);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortRetryLimit= %d\n",(INT)pDevice->byShortRetryLimit);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byLongRetryLimit= %d\n",(INT)pDevice->byLongRetryLimit);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byPreambleType= %d\n",(INT)pDevice->byPreambleType);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortPreamble= %d\n",(INT)pDevice->byShortPreamble);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uConnectionRate= %d\n",(INT)pDevice->uConnectionRate);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byBBType= %d\n",(INT)pDevice->byBBType);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->b11hEnable= %d\n",(INT)pDevice->b11hEnable);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(INT)pDevice->bDiversityRegCtlON);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uChannel= %d\n",(INT)pDevice->uChannel);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byOpMode= %d\n",(INT)pDevice->byOpMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ePSMode= %d\n",(INT)pDevice->ePSMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" wRTSThreshold= %d\n",(INT)pDevice->wRTSThreshold);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortRetryLimit= %d\n",(INT)pDevice->byShortRetryLimit);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byLongRetryLimit= %d\n",(INT)pDevice->byLongRetryLimit);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byPreambleType= %d\n",(INT)pDevice->byPreambleType);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byShortPreamble= %d\n",(INT)pDevice->byShortPreamble);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" uConnectionRate= %d\n",(INT)pDevice->uConnectionRate);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" byBBType= %d\n",(INT)pDevice->byBBType);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->b11hEnable= %d\n",(INT)pDevice->b11hEnable);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pDevice->bDiversityRegCtlON= %d\n",(INT)pDevice->bDiversityRegCtlON);
 }
 
 static VOID s_vCompleteCurrentMeasure (IN PSDevice pDevice, IN BYTE byResult)
@@ -697,7 +630,7 @@ byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
 #ifdef	PLICE_DEBUG
 	//printk("init registers: TxAntennaMode is %d\n",pDevice->byTxAntennaMode);
 #endif
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n",
             pDevice->bDiversityEnable,(int)pDevice->ulDiversityNValue,(int)pDevice->ulDiversityMValue,pDevice->byTMax,pDevice->byTMax2);
 
 //#ifdef ZoneType_DefaultSetting
@@ -709,7 +642,7 @@ byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
         (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){          //for USA
     pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
     pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n");
   }
  else if((zonetype == 1)&&
  	     (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x01)){   //for Japan
@@ -720,7 +653,7 @@ byValue1 = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_ANTENNA);
  	     (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x02)){   //for Europe
     pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
     pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n");
   }
 
 else
@@ -743,12 +676,12 @@ else
         }
 
         pDevice->byRFType &= RF_MASK;
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType);
 
         if (pDevice->bZoneRegExist == FALSE) {
             pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType);
 
         //Init RF module
         RFbInit(pDevice);
@@ -855,8 +788,8 @@ else
             MACvGPIOIn(pDevice->PortOffset, &pDevice->byGPIO);
 //2008-4-14 <add> by chester for led issue
  #ifdef FOR_LED_ON_NOTEBOOK
-if (BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA)){pDevice->bHWRadioOff = TRUE;}
-if (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA)){pDevice->bHWRadioOff = FALSE;}
+if (pDevice->byGPIO & GPIO0_DATA){pDevice->bHWRadioOff = TRUE;}
+if ( !(pDevice->byGPIO & GPIO0_DATA)){pDevice->bHWRadioOff = FALSE;}
 
             }
         if ( (pDevice->bRadioControlOff == TRUE)) {
@@ -864,8 +797,8 @@ if (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA)){pDevice->bHWRadioOff = FALSE;}
         }
 else  CARDbRadioPowerOn(pDevice);
 #else
-            if ((BITbIsBitOn(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOff(pDevice->byRadioCtl, EEP_RADIOCTL_INV)) ||
-                (BITbIsBitOff(pDevice->byGPIO,GPIO0_DATA) && BITbIsBitOn(pDevice->byRadioCtl, EEP_RADIOCTL_INV))) {
+            if (((pDevice->byGPIO & GPIO0_DATA) && !(pDevice->byRadioCtl & EEP_RADIOCTL_INV)) ||
+                ( !(pDevice->byGPIO & GPIO0_DATA) && (pDevice->byRadioCtl & EEP_RADIOCTL_INV))) {
                 pDevice->bHWRadioOff = TRUE;
             }
         }
@@ -878,7 +811,7 @@ else  CARDbRadioPowerOn(pDevice);
             pMgmt->eScanType = WMAC_SCAN_PASSIVE;
     // get Permanent network address
     SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n",
         pDevice->abyCurrentNetAddr[0],
         pDevice->abyCurrentNetAddr[1],
         pDevice->abyCurrentNetAddr[2],
@@ -946,7 +879,7 @@ static BOOL device_release_WPADEV(PSDevice pDevice)
                  wpahdr->req_ie_len = 0;
                  skb_put(pDevice->skb, sizeof(viawget_wpa_header));
                  pDevice->skb->dev = pDevice->wpadev;
-                 pDevice->skb->mac_header = pDevice->skb->data;
+		 skb_reset_mac_header(pDevice->skb);
                  pDevice->skb->pkt_type = PACKET_HOST;
                  pDevice->skb->protocol = htons(ETH_P_802_2);
                  memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
@@ -978,7 +911,6 @@ static const struct net_device_ops device_netdev_ops = {
 };
 
 
-#ifndef PRIVATE_OBJ
 
 static int
 device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
@@ -1146,14 +1078,7 @@ device_found1(struct pci_dev *pcid, const struct pci_device_id *ent)
     dev->irq                = pcid->irq;
     dev->netdev_ops         = &device_netdev_ops;
 
-#ifdef WIRELESS_EXT
-//Einsn Modify for ubuntu-7.04
-//	dev->wireless_handlers->get_wireless_stats = iwctl_get_wireless_stats;
-#if WIRELESS_EXT > 12
 	dev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
-//	netdev->wireless_handlers = NULL;
-#endif /* WIRELESS_EXT > 12 */
-#endif /* WIRELESS_EXT */
 
     rc = register_netdev(dev);
     if (rc)
@@ -1179,17 +1104,17 @@ static void device_print_info(PSDevice pDevice)
 {
     struct net_device* dev=pDevice->dev;
 
-    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id));
-    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n",dev->name, get_chip_name(pDevice->chip_id));
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
         dev->name,
         dev->dev_addr[0],dev->dev_addr[1],dev->dev_addr[2],
         dev->dev_addr[3],dev->dev_addr[4],dev->dev_addr[5]);
 #ifdef IO_MAP
-    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx  ",(ULONG) pDevice->ioaddr);
-    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx  ",(ULONG) pDevice->ioaddr);
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
 #else
-    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx Mem=0x%lx ",(ULONG) pDevice->ioaddr,(ULONG) pDevice->PortOffset);
-    DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IO=0x%lx Mem=0x%lx ",(ULONG) pDevice->ioaddr,(ULONG) pDevice->PortOffset);
+    DBG_PRT(MSG_LEVEL_INFO, KERN_INFO" IRQ=%d \n", pDevice->dev->irq);
 #endif
 
 }
@@ -1254,17 +1179,17 @@ static BOOL device_get_pci_info(PSDevice pDevice, struct pci_dev* pcid) {
 
     pDevice->pcid = pcid;
 
-    pci_read_config_byte(pcid, PCI_REG_COMMAND, &b);
-    pci_write_config_byte(pcid, PCI_REG_COMMAND, (b|COMMAND_BUSM));
+    pci_read_config_byte(pcid, PCI_COMMAND, &b);
+    pci_write_config_byte(pcid, PCI_COMMAND, (b|PCI_COMMAND_MASTER));
 
 #ifdef	PLICE_DEBUG
-   	//pci_read_config_word(pcid,PCI_REG_MAX_LAT,&max_lat);
+   	//pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat);
 	//printk("max lat is %x,SubSystemID is %x\n",max_lat,pDevice->SubSystemID);
 	//for (ii=0;ii<0xFF;ii++)
-	//pci_read_config_word(pcid,PCI_REG_MAX_LAT,&max_lat);
+	//pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat);
 	//max_lat  = 0x20;
-	//pci_write_config_word(pcid,PCI_REG_MAX_LAT,max_lat);
-	//pci_read_config_word(pcid,PCI_REG_MAX_LAT,&max_lat);
+	//pci_write_config_word(pcid,PCI_MAX_LAT,max_lat);
+	//pci_read_config_word(pcid,PCI_MAX_LAT,&max_lat);
 	//printk("max lat is %x\n",max_lat);
 
 	for (ii=0;ii<0xFF;ii++)
@@ -1314,7 +1239,7 @@ device_release_WPADEV(pDevice);
             ptr->prev->next=ptr->next;
     }
     else {
-        DEVICE_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n");
+        DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n");
         return;
     }
 #ifdef HOSTAP
@@ -1336,7 +1261,6 @@ device_release_WPADEV(pDevice);
         pci_set_drvdata(pDevice->pcid,NULL);
     }
 }
-#endif// ifndef PRIVATE_OBJ
 
 static BOOL device_init_rings(PSDevice pDevice) {
     void*   vir_pool;
@@ -1351,7 +1275,7 @@ static BOOL device_init_rings(PSDevice pDevice) {
                     &pDevice->pool_dma);
 
     if (vir_pool == NULL) {
-        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name);
+        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name);
         return FALSE;
     }
 
@@ -1379,7 +1303,7 @@ static BOOL device_init_rings(PSDevice pDevice) {
                     &pDevice->tx_bufs_dma0);
 
     if (pDevice->tx0_bufs == NULL) {
-        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name);
+        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name);
         pci_free_consistent(pDevice->pcid,
             pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) +
             pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) +
@@ -1468,7 +1392,7 @@ static void device_init_rd0_ring(PSDevice pDevice) {
         pDesc->pRDInfo = alloc_rd_info();
         ASSERT(pDesc->pRDInfo);
         if (!device_alloc_rx_buf(pDevice, pDesc)) {
-            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n",
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n",
             pDevice->dev->name);
         }
         pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]);
@@ -1476,7 +1400,8 @@ static void device_init_rd0_ring(PSDevice pDevice) {
         pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
     }
 
-    pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma);
+    if (i > 0)
+        pDevice->aRD0Ring[i-1].next_desc = cpu_to_le32(pDevice->rd0_pool_dma);
     pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]);
 }
 
@@ -1492,7 +1417,7 @@ static void device_init_rd1_ring(PSDevice pDevice) {
         pDesc->pRDInfo = alloc_rd_info();
         ASSERT(pDesc->pRDInfo);
         if (!device_alloc_rx_buf(pDevice, pDesc)) {
-            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n",
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc rx bufs\n",
             pDevice->dev->name);
         }
         pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]);
@@ -1500,7 +1425,8 @@ static void device_init_rd1_ring(PSDevice pDevice) {
         pDesc->next_desc = cpu_to_le32(curr + sizeof(SRxDesc));
     }
 
-    pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma);
+    if (i > 0)
+        pDevice->aRD1Ring[i-1].next_desc = cpu_to_le32(pDevice->rd1_pool_dma);
     pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]);
 }
 
@@ -1513,7 +1439,7 @@ static void device_init_defrag_cb(PSDevice pDevice) {
     for (i = 0; i < CB_MAX_RX_FRAG; i++) {
         pDeF = &(pDevice->sRxDFCB[i]);
         if (!device_alloc_frag_buf(pDevice, pDeF)) {
-            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
                 pDevice->dev->name);
         };
     }
@@ -1593,7 +1519,8 @@ static void device_init_td0_ring(PSDevice pDevice) {
         pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
     }
 
-    pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma);
+    if (i > 0)
+        pDevice->apTD0Rings[i-1].next_desc = cpu_to_le32(pDevice->td0_pool_dma);
     pDevice->apTailTD[0] = pDevice->apCurrTD[0] =&(pDevice->apTD0Rings[0]);
 
 }
@@ -1618,7 +1545,8 @@ static void device_init_td1_ring(PSDevice pDevice) {
         pDesc->next_desc = cpu_to_le32(curr+sizeof(STxDesc));
     }
 
-    pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma);
+    if (i > 0)
+        pDevice->apTD1Rings[i-1].next_desc = cpu_to_le32(pDevice->td1_pool_dma);
     pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]);
 }
 
@@ -1672,22 +1600,18 @@ static int device_rx_srv(PSDevice pDevice, UINT uIdx) {
     for (pRD = pDevice->pCurrRD[uIdx];
          pRD->m_rd0RD0.f1Owner == OWNED_BY_HOST;
          pRD = pRD->next) {
-//        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->pCurrRD = %x, works = %d\n", pRD, works);
+//        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->pCurrRD = %x, works = %d\n", pRD, works);
         if (works++>15)
             break;
         if (device_receive_frame(pDevice, pRD)) {
             if (!device_alloc_rx_buf(pDevice,pRD)) {
-                    DEVICE_PRT(MSG_LEVEL_ERR, KERN_ERR
+                    DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
                     "%s: can not allocate rx buf\n", pDevice->dev->name);
                     break;
             }
         }
         pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
-#ifdef PRIVATE_OBJ
-        ref_set_rx_jiffies(pDevice->dev);
-#else
         pDevice->dev->last_rx = jiffies;
-#endif
     }
 
     pDevice->pCurrRD[uIdx]=pRD;
@@ -1700,15 +1624,6 @@ static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
 
     PDEVICE_RD_INFO pRDInfo=pRD->pRDInfo;
 
-#ifdef PRIVATE_OBJ
-
-    pRDInfo->skb=dev_alloc_skb(pDevice->rx_buf_sz);
-    if (pRDInfo->skb==NULL)
-        return FALSE;
-    ref_skb_remap(pDevice->dev, &(pRDInfo->ref_skb), pRDInfo->skb);
-    pRDInfo->skb_dma = pci_map_single(pDevice->pcid, pRDInfo->ref_skb.tail, pDevice->rx_buf_sz,
-                        PCI_DMA_FROMDEVICE);
-#else
 
     pRDInfo->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
 #ifdef	PLICE_DEBUG
@@ -1718,10 +1633,9 @@ static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
         return FALSE;
     ASSERT(pRDInfo->skb);
     pRDInfo->skb->dev = pDevice->dev;
-    pRDInfo->skb_dma = pci_map_single(pDevice->pcid, pRDInfo->skb->tail, pDevice->rx_buf_sz,
-                        PCI_DMA_FROMDEVICE);
-#endif
-    *((PU32) &(pRD->m_rd0RD0)) = 0;
+    pRDInfo->skb_dma = pci_map_single(pDevice->pcid, skb_tail_pointer(pRDInfo->skb),
+				      pDevice->rx_buf_sz, PCI_DMA_FROMDEVICE);
+    *((unsigned int *) &(pRD->m_rd0RD0)) = 0; /* FIX cast */
 
     pRD->m_rd0RD0.wResCount = cpu_to_le16(pDevice->rx_buf_sz);
     pRD->m_rd0RD0.f1Owner = OWNED_BY_NIC;
@@ -1735,20 +1649,11 @@ static BOOL device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) {
 
 BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
 
-#ifdef PRIVATE_OBJ
-
-    pDeF->skb=dev_alloc_skb(pDevice->rx_buf_sz);
-    if (pDeF->skb==NULL)
-        return FALSE;
-    ref_skb_remap(pDevice->dev, &(pDeF->ref_skb), pDeF->skb);
-
-#else
     pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
     if (pDeF->skb == NULL)
         return FALSE;
     ASSERT(pDeF->skb);
     pDeF->skb->dev = pDevice->dev;
-#endif
 
     return TRUE;
 }
@@ -1767,9 +1672,6 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
     struct sk_buff*          skb;
     UINT                     uNodeIndex;
     PSMgmtObject             pMgmt = pDevice->pMgmt;
-#ifdef PRIVATE_OBJ
-    ref_sk_buff              ref_skb;
-#endif
 
 
     for (pTD = pDevice->apTailTD[uIdx]; pDevice->iTDUsed[uIdx] >0; pTD = pTD->next) {
@@ -1789,9 +1691,6 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
                 uFIFOHeaderSize = pTD->pTDInfo->dwHeaderLength;
                 uFrameSize = pTD->pTDInfo->dwReqCount - uFIFOHeaderSize;
                 pTxBufHead = (PSTxBufHead) (pTD->pTDInfo->buf);
-#ifdef PRIVATE_OBJ
-                ref_skb_remap(pDevice->dev, &ref_skb, pTD->pTDInfo->skb);
-#endif
                 // Update the statistics based on the Transmit status
                 // now, we DO'NT check TSR0_CDH
 
@@ -1807,23 +1706,19 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
                          uFIFOHeaderSize
                          );
 
-                if (BITbIsBitOff(byTsr1, TSR1_TERR)) {
+                if ( !(byTsr1 & TSR1_TERR)) {
                     if (byTsr0 != 0) {
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n",
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n",
                            (INT)uIdx, byTsr1, byTsr0);
                     }
                     if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) {
                         pDevice->s802_11Counter.TransmittedFragmentCount ++;
                     }
                     pStats->tx_packets++;
-#ifdef PRIVATE_OBJ
-                    pStats->tx_bytes += *(ref_skb.len);
-#else
                     pStats->tx_bytes += pTD->pTDInfo->skb->len;
-#endif
                 }
                 else {
-                     DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n",
+                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n",
                            (INT)uIdx, byTsr1, byTsr0);
                     pStats->tx_errors++;
                     pStats->tx_dropped++;
@@ -1832,33 +1727,24 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
 
             if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
                 if (pDevice->bEnableHostapd) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif.. \n");
-#ifdef PRIVATE_OBJ
-                    ref_skb_remap(pDevice->apdev, &(ref_skb), pTD->pTDInfo->skb);
-	                ref_skb.mac.raw = ref_skb.data;
-	                *(ref_skb.pkt_type) = PACKET_OTHERHOST;
-    	            //*(ref_skb.protocol) = htons(ETH_P_802_2);
-	                memset(ref_skb.cb, 0, sizeof(ref_skb.cb));
-	                netif_rx(ref_skb.skb);
-#else
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif.. \n");
                     skb = pTD->pTDInfo->skb;
 	                skb->dev = pDevice->apdev;
-			        skb->mac_header = skb->data;
+			skb_reset_mac_header(skb);
 	                skb->pkt_type = PACKET_OTHERHOST;
     	            //skb->protocol = htons(ETH_P_802_2);
 	                memset(skb->cb, 0, sizeof(skb->cb));
 	                netif_rx(skb);
-#endif
 	            }
             }
 
-            if (BITbIsBitOn(byTsr1, TSR1_TERR)) {
+            if (byTsr1 & TSR1_TERR) {
             if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
                           (INT)uIdx, byTsr1, byTsr0);
             }
 
-//                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
+//                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n",
 //                          (INT)uIdx, byTsr1, byTsr0);
 
                 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
@@ -1875,7 +1761,7 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
                             wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
                             pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
                             pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB);
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n"
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n"
                                     ,(INT)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt);
                             pStats->tx_errors--;
                             pStats->tx_dropped--;
@@ -1894,7 +1780,7 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
 
         if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) {
             bFull = TRUE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]);
         }
         if (netif_queue_stopped(pDevice->dev) && (bFull==FALSE)){
             netif_wake_queue(pDevice->dev);
@@ -1911,7 +1797,7 @@ static int device_tx_srv(PSDevice pDevice, UINT uIdx) {
 static void device_error(PSDevice pDevice, WORD status) {
 
     if (status & ISR_FETALERR) {
-        DEVICE_PRT(MSG_LEVEL_ERR, KERN_ERR
+        DBG_PRT(MSG_LEVEL_ERR, KERN_ERR
             "%s: Hardware fatal error.\n",
             pDevice->dev->name);
         netif_stop_queue(pDevice->dev);
@@ -2005,31 +1891,24 @@ INT MlmeThread(
 }
 
 
-#ifdef PRIVATE_OBJ
-
-int __device_open(HANDLE pExDevice) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-
-#else
 
 static int  device_open(struct net_device *dev) {
     PSDevice    pDevice=(PSDevice) netdev_priv(dev);
     int i;
+#ifdef WPA_SM_Transtatus
+    extern SWPAResult wpa_Result;
 #endif
+
     pDevice->rx_buf_sz = PKT_BUF_SZ;
     if (!device_init_rings(pDevice)) {
         return -ENOMEM;
     }
 //2008-5-13 <add> by chester
-#ifndef PRIVATE_OBJ
     i=request_irq(pDevice->pcid->irq, &device_intr, IRQF_SHARED, dev->name, dev);
     if (i)
         return i;
-#endif
 	//printk("DEBUG1\n");
 #ifdef WPA_SM_Transtatus
-     extern SWPAResult wpa_Result;
      memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
      wpa_Result.proto = 0;
      wpa_Result.key_mgmt = 0;
@@ -2037,7 +1916,7 @@ static int  device_open(struct net_device *dev) {
      wpa_Result.authenticated = FALSE;
      pDevice->fWPA_Authened = FALSE;
 #endif
-DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n");
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n");
 device_init_rd0_ring(pDevice);
     device_init_rd1_ring(pDevice);
     device_init_defrag_cb(pDevice);
@@ -2088,15 +1967,11 @@ device_init_rd0_ring(pDevice);
 
   // if (( SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RADIOCTL)&0x06)==0x04)
     //    return -ENOMEM;
-DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
 	device_init_registers(pDevice, DEVICE_INIT_COLD);
     MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr);
     memcpy(pDevice->pMgmt->abyMACAddr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN);
-#ifdef PRIVATE_OBJ
-    __device_set_multi(pExDevice);
-#else
     device_set_multi(pDevice->dev);
-#endif
 
     // Init for Key Management
     KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
@@ -2131,7 +2006,7 @@ DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n");
 //printk("DEBUG2\n");
 
 
-DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n");
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n");
 	MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE);
 
     if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) {
@@ -2143,22 +2018,13 @@ DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n");
     }
     pDevice->flags |=DEVICE_FLAGS_OPENED;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
     return 0;
 }
 
 
-#ifdef PRIVATE_OBJ
-
-int  __device_close(HANDLE pExDevice) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    struct net_device *dev = pDevice_info->dev;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-
-#else
 static int  device_close(struct net_device *dev) {
     PSDevice  pDevice=(PSDevice) netdev_priv(dev);
-#endif
     PSMgmtObject     pMgmt = pDevice->pMgmt;
  //PLICE_DEBUG->
 #ifdef	THREAD
@@ -2207,32 +2073,23 @@ device_release_WPADEV(pDevice);
 //PLICE_DEBUG->
 	//tasklet_kill(&pDevice->RxMngWorkItem);
 //PLICE_DEBUG<-
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close.. \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close.. \n");
     return 0;
 }
 
-#ifdef PRIVATE_OBJ
-
-int  __device_dma0_tx_80211(HANDLE pExDevice, struct sk_buff *skb) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-    ref_sk_buff     ref_skb;
-
-#else
 
 
 static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
     PSDevice        pDevice=netdev_priv(dev);
-#endif
     PBYTE           pbMPDU;
     UINT            cbMPDULen = 0;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
     spin_lock_irq(&pDevice->lock);
 
     if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n");
         dev_kfree_skb_irq(skb);
         spin_unlock_irq(&pDevice->lock);
         return 0;
@@ -2244,14 +2101,8 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
         return 0;
     };
 
-#ifdef PRIVATE_OBJ
-    ref_skb_remap(pDevice->dev, &ref_skb, skb);
-    cbMPDULen = *(ref_skb.len);
-    pbMPDU = ref_skb.data;
-#else
     cbMPDULen = skb->len;
     pbMPDU = skb->data;
-#endif
 
     vDMA0_tx_80211(pDevice, skb, pbMPDU, cbMPDULen);
 
@@ -2268,16 +2119,13 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
     PSTxDesc        pHeadTD, pLastTD;
     UINT            cbFrameBodySize;
     UINT            uMACfragNum;
-    BYTE            byPktTyp;
+    BYTE            byPktType;
     BOOL            bNeedEncryption = FALSE;
     PSKeyItem       pTransmitKey = NULL;
     UINT            cbHeaderSize;
     UINT            ii;
     SKeyItem        STempKey;
 //    BYTE            byKeyIndex = 0;
-#ifdef PRIVATE_OBJ
-    ref_sk_buff     ref_skb;
-#endif
 
 
     if (pDevice->bStopTx0Pkt == TRUE) {
@@ -2287,33 +2135,24 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
 
     if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
         dev_kfree_skb_irq(skb);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n");
         return FALSE;
     }
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
         if (pDevice->uAssocCount == 0) {
             dev_kfree_skb_irq(skb);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n");
             return FALSE;
         }
     }
 
-#ifdef PRIVATE_OBJ
-    ref_skb_remap(pDevice->dev, &(ref_skb), skb);
-#endif
     pHeadTD = pDevice->apCurrTD[TYPE_TXDMA0];
 
     pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
 
-#ifdef PRIVATE_OBJ
-    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(ref_skb.data), U_HEADER_LEN);
-    cbFrameBodySize = *(ref_skb.len) - U_HEADER_LEN;
-
-#else
     memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN);
     cbFrameBodySize = skb->len - U_HEADER_LEN;
-#endif
 
     // 802.1H
     if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) {
@@ -2325,7 +2164,7 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
         dev_kfree_skb_irq(skb);
         return FALSE;
     }
-    byPktTyp = (BYTE)pDevice->byPacketType;
+    byPktType = (BYTE)pDevice->byPacketType;
 
 
     if (pDevice->bFixRate) {
@@ -2354,18 +2193,18 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
         pDevice->byPreambleType = PREAMBLE_LONG;
     }
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
 
 
     if (pDevice->wCurrentRate <= RATE_11M) {
-        byPktTyp = PK_TYPE_11B;
+        byPktType = PK_TYPE_11B;
     } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
-        byPktTyp = PK_TYPE_11A;
+        byPktType = PK_TYPE_11A;
     } else {
         if (pDevice->bProtectMode == TRUE) {
-            byPktTyp = PK_TYPE_11GB;
+            byPktType = PK_TYPE_11GB;
         } else {
-            byPktTyp = PK_TYPE_11GA;
+            byPktType = PK_TYPE_11GA;
         }
     }
 
@@ -2384,7 +2223,7 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
             pTransmitKey->uKeyLength
             );
     }
-    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
+    vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
                         cbFrameBodySize, TYPE_TXDMA0, pHeadTD,
                         &pDevice->sTxEthHeader, (PBYTE)skb->data, pTransmitKey, uNodeIndex,
                         &uMACfragNum,
@@ -2424,19 +2263,9 @@ BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex) {
 }
 
 //TYPE_AC0DMA data tx
-#ifdef PRIVATE_OBJ
-
-int  __device_xmit(HANDLE pExDevice, struct sk_buff *skb) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-    struct net_device *dev = pDevice_info->dev;
-    ref_sk_buff     ref_skb;
-
-#else
 static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
     PSDevice pDevice=netdev_priv(dev);
 
-#endif
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSTxDesc        pHeadTD, pLastTD;
     UINT            uNodeIndex = 0;
@@ -2444,7 +2273,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
     WORD            wAID;
     UINT            uMACfragNum = 1;
     UINT            cbFrameBodySize;
-    BYTE            byPktTyp;
+    BYTE            byPktType;
     UINT            cbHeaderSize;
     BOOL            bNeedEncryption = FALSE;
     PSKeyItem       pTransmitKey = NULL;
@@ -2470,9 +2299,6 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
         return 0;
     }
 
-#ifdef PRIVATE_OBJ
-    ref_skb_remap(pDevice->dev, &ref_skb, skb);
-#endif
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
         if (pDevice->uAssocCount == 0) {
@@ -2480,19 +2306,11 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
             spin_unlock_irq(&pDevice->lock);
             return 0;
         }
-#ifdef PRIVATE_OBJ
-        if (IS_MULTICAST_ADDRESS((PBYTE)(ref_skb.data))) {
-#else
         if (IS_MULTICAST_ADDRESS((PBYTE)(skb->data))) {
-#endif
             uNodeIndex = 0;
             bNodeExist = TRUE;
             if (pMgmt->sNodeDBTable[0].bPSEnable) {
-#ifdef PRIVATE_OBJ
-                skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), ref_skb.skb);
-#else
                 skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
-#endif
                 pMgmt->sNodeDBTable[0].wEnQueueCnt++;
                 // set tx map
                 pMgmt->abyPSTxMap[0] |= byMask[0];
@@ -2500,22 +2318,14 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                 return 0;
             }
 }else {
-#ifdef PRIVATE_OBJ
-            if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(ref_skb.data), &uNodeIndex)) {
-#else
             if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(skb->data), &uNodeIndex)) {
-#endif
                 if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
-#ifdef PRIVATE_OBJ
-                    skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, ref_skb.skb);
-#else
                     skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
-#endif
                     pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
                     // set tx map
                     wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
                     pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
                              (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
                     spin_unlock_irq(&pDevice->lock);
                     return 0;
@@ -2533,7 +2343,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
         }
 
         if (bNodeExist == FALSE) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
             dev_kfree_skb_irq(skb);
             spin_unlock_irq(&pDevice->lock);
             return 0;
@@ -2545,13 +2355,8 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
     pHeadTD->m_td1TD1.byTCR = (TCR_EDP|TCR_STP);
 
 
-#ifdef PRIVATE_OBJ
-    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(ref_skb.data), U_HEADER_LEN);
-    cbFrameBodySize = *(ref_skb.len) - U_HEADER_LEN;
-#else
     memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN);
     cbFrameBodySize = skb->len - U_HEADER_LEN;
-#endif
     // 802.1H
     if (ntohs(pDevice->sTxEthHeader.wType) > MAX_DATA_LEN) {
         cbFrameBodySize += 8;
@@ -2570,20 +2375,20 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
                     // get group key
                     if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
                         bTKIP_UseGTK = TRUE;
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
                         break;
                     }
                 } else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
                     break;
                 }
             }else if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
 
                 pbyBSSID = pDevice->sTxEthHeader.abyDstAddr;  //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
                 for (ii = 0; ii< 6; ii++)
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
 
                 // get pairwise key
                 if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE)
@@ -2594,19 +2399,19 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
             if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
                 pTransmitKey = NULL;
                 if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
                 }
                 else
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
             } else {
                 bTKIP_UseGTK = TRUE;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
             }
         } while(FALSE);
     }
 
     if (pDevice->bEnableHostWEP) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
         if (pDevice->bEncryptionEnable == TRUE) {
             pTransmitKey = &STempKey;
             pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
@@ -2624,7 +2429,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
     uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader);
 
     if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) {
-        DEVICE_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum);
+        DBG_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum);
         dev_kfree_skb_irq(skb);
         spin_unlock_irq(&pDevice->lock);
         return 0;
@@ -2637,7 +2442,7 @@ static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
         }
     }
 
-    byPktTyp = (BYTE)pDevice->byPacketType;
+    byPktType = (BYTE)pDevice->byPacketType;
 
     if (pDevice->bFixRate) {
 #ifdef	PLICE_DEBUG
@@ -2708,17 +2513,17 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
 		}
     }
 
-//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
 
     if (pDevice->wCurrentRate <= RATE_11M) {
-        byPktTyp = PK_TYPE_11B;
+        byPktType = PK_TYPE_11B;
     } else if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
-        byPktTyp = PK_TYPE_11A;
+        byPktType = PK_TYPE_11A;
     } else {
         if (pDevice->bProtectMode == TRUE) {
-            byPktTyp = PK_TYPE_11GB;
+            byPktType = PK_TYPE_11GB;
         } else {
-            byPktTyp = PK_TYPE_11GA;
+            byPktType = PK_TYPE_11GA;
         }
     }
 
@@ -2727,20 +2532,20 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
 //#endif
 
     if (bNeedEncryption == TRUE) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
         if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
             bNeedEncryption = FALSE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
             if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
                 if (pTransmitKey == NULL) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
                 }
                 else {
                     if (bTKIP_UseGTK == TRUE) {
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
                     }
                     else {
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
                         bNeedEncryption = TRUE;
                     }
                 }
@@ -2754,14 +2559,14 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
             if (pDevice->bEnableHostWEP) {
                 if ((uNodeIndex != 0) &&
                     (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
                     bNeedEncryption = TRUE;
                  }
              }
         }
         else {
             if (pTransmitKey == NULL) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
                 dev_kfree_skb_irq(skb);
                 spin_unlock_irq(&pDevice->lock);
                 return 0;
@@ -2770,27 +2575,18 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
     }
 
 
-#ifdef PRIVATE_OBJ
-    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
-                        cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
-                        &pDevice->sTxEthHeader, (PBYTE)ref_skb.data, pTransmitKey, uNodeIndex,
-                        &uMACfragNum,
-                        &cbHeaderSize
-                        );
-#else
 #ifdef	PLICE_DEBUG
 	//if (skb->len == 98)
 	//{
 	//	printk("ping:len is %d\n");
 	//}
 #endif
-    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
+    vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
                         cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
                         &pDevice->sTxEthHeader, (PBYTE)skb->data, pTransmitKey, uNodeIndex,
                         &uMACfragNum,
                         &cbHeaderSize
                         );
-#endif
 
     if (MACbIsRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_PS)) {
         // Disable PS
@@ -2811,11 +2607,7 @@ pDevice->byTopCCKBasicRate,pDevice->byTopOFDMBasicRate);
 
     // Save the information needed by the tx interrupt handler
     // to complete the Send request
-#ifdef PRIVATE_OBJ
-    pLastTD->pTDInfo->skb = ref_skb.skb;
-#else
     pLastTD->pTDInfo->skb = skb;
-#endif
     pLastTD->pTDInfo->byFlags = 0;
     pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB;
 #ifdef TxInSleep
@@ -2867,31 +2659,18 @@ BOOL            bTxeapol_key = FALSE;
 }
 
     MACvTransmitAC0(pDevice->PortOffset);
-//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0:pDevice->apCurrTD= %p\n", pHeadTD);
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "acdma0:pDevice->apCurrTD= %p\n", pHeadTD);
 
-#ifdef PRIVATE_OBJ
-    ref_set_tx_jiffies(pDevice->dev);
-#else
     dev->trans_start = jiffies;
-#endif
 
     spin_unlock_irq(&pDevice->lock);
     return 0;
 
 }
 
-#ifdef PRIVATE_OBJ
-
-int __device_intr(int irq, HANDLE pExDevice, struct pt_regs *regs) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-
-
-#else
 static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
     struct net_device* dev=dev_instance;
     PSDevice     pDevice=(PSDevice) netdev_priv(dev);
-#endif
 
     int             max_count=0;
     DWORD           dwMIBCounter=0;
@@ -2909,13 +2688,13 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
         return IRQ_RETVAL(handled);
 
     if (pDevice->dwIsr == 0xffffffff) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n");
         return IRQ_RETVAL(handled);
     }
     /*
       // 2008-05-21 <mark> by Richardtai, we can't read RSSI here, because no packet bound with RSSI
 
-    	if ((BITbIsBitOn(pDevice->dwIsr, ISR_RXDMA0)) &&
+    	if ((pDevice->dwIsr & ISR_RXDMA0) &&
         (pDevice->byLocalID != REV_ID_VT3253_B0) &&
         (pDevice->bBSSIDFilter == TRUE)) {
         // update RSSI
@@ -2948,7 +2727,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
         MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr);
 
         if (pDevice->dwIsr & ISR_FETALERR){
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR \n");
             VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0);
             VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI);
             device_error(pDevice, pDevice->dwIsr);
@@ -2956,7 +2735,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
 
         if (pDevice->byLocalID > REV_ID_VT3253_B1) {
 
-            if (BITbIsBitOn(pDevice->dwIsr, ISR_MEASURESTART)) {
+            if (pDevice->dwIsr & ISR_MEASURESTART) {
                 // 802.11h measure start
                 pDevice->byOrgChannel = pDevice->byCurrentCh;
                 VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byOrgRCR));
@@ -2988,7 +2767,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                     MACvSelectPage0(pDevice->PortOffset);
                 }
             }
-            if (BITbIsBitOn(pDevice->dwIsr, ISR_MEASUREEND)) {
+            if (pDevice->dwIsr & ISR_MEASUREEND) {
                 // 802.11h measure end
                 pDevice->bMeasureInProgress = FALSE;
                 VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byOrgRCR);
@@ -3007,7 +2786,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                 MACvSelectPage1(pDevice->PortOffset);
                 MACvRegBitsOn(pDevice->PortOffset, MAC_REG_MSRCTL+1, MSRCTL1_TXPAUSE);
                 MACvSelectPage0(pDevice->PortOffset);
-                if (BITbIsBitOn(byData, MSRCTL_FINISH)) {
+                if (byData & MSRCTL_FINISH) {
                     // measure success
                     s_vCompleteCurrentMeasure(pDevice, 0);
                 } else {
@@ -3015,7 +2794,7 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                     s_vCompleteCurrentMeasure(pDevice, MEASURE_MODE_LATE);
                 }
             }
-            if (BITbIsBitOn(pDevice->dwIsr, ISR_QUIETSTART)) {
+            if (pDevice->dwIsr & ISR_QUIETSTART) {
                 do {
                     ;
                 } while (CARDbStartQuiet(pDevice) == FALSE);
@@ -3064,11 +2843,11 @@ static  irqreturn_t  device_intr(int irq,  void *dev_instance) {
                         if (pDevice->uBBVGADiffCount == 1) {
                             // first VGA diff gain
                             BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
                                             (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
                         }
                         if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) {
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n",
                                             (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount);
                             BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
                         }
@@ -3297,18 +3076,9 @@ error2:
 }
 
 
-#ifdef PRIVATE_OBJ
-
-void __device_set_multi(HANDLE pExDevice) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    ref_net_device  *dev = &(pDevice_info->ref_dev);
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-
-#else
 
 static void device_set_multi(struct net_device *dev) {
     PSDevice         pDevice = (PSDevice) netdev_priv(dev);
-#endif
 
     PSMgmtObject     pMgmt = pDevice->pMgmt;
     u32              mc_filter[2];
@@ -3318,24 +3088,13 @@ static void device_set_multi(struct net_device *dev) {
 
     VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
 
-#ifdef PRIVATE_OBJ
-    if (*(dev->flags) & IFF_PROMISC) {         /* Set promiscuous. */
-        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: Promiscuous mode enabled.\n", pDevice->dev->name);
-
-#else
     if (dev->flags & IFF_PROMISC) {         /* Set promiscuous. */
-        DEVICE_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
-#endif
+        DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
         /* Unconditionally log net taps. */
         pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
     }
-#ifdef PRIVATE_OBJ
-    else if ((*(dev->mc_count) > pDevice->multicast_limit)
-        ||  (*(dev->flags) & IFF_ALLMULTI)) {
-#else
     else if ((dev->mc_count > pDevice->multicast_limit)
         ||  (dev->flags & IFF_ALLMULTI)) {
-#endif
         MACvSelectPage1(pDevice->PortOffset);
         VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0, 0xffffffff);
         VNSvOutPortD(pDevice->PortOffset + MAC_REG_MAR0 + 4, 0xffffffff);
@@ -3344,13 +3103,8 @@ static void device_set_multi(struct net_device *dev) {
     }
     else {
         memset(mc_filter, 0, sizeof(mc_filter));
-#ifdef PRIVATE_OBJ
-        for (i = 0, mclist = dev->mc_list; mclist && i < *(dev->mc_count);
-             i++, mclist = mclist->next) {
-#else
         for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
              i++, mclist = mclist->next) {
-#endif
             int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
             mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
         }
@@ -3369,42 +3123,23 @@ static void device_set_multi(struct net_device *dev) {
     }
 
     VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode );
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode );
 }
 
 
-#ifdef PRIVATE_OBJ
-
-struct net_device_stats *__device_get_stats(HANDLE pExDevice) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-
-#else
 static struct net_device_stats *device_get_stats(struct net_device *dev) {
     PSDevice pDevice=(PSDevice) netdev_priv(dev);
-#endif
 
     return &pDevice->stats;
 }
 
 
-#ifdef PRIVATE_OBJ
-
-int __device_ioctl(HANDLE pExDevice, struct ifreq *rq, int cmd) {
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    struct net_device *dev = pDevice_info->dev;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-
-#else
 
 static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
-#endif
 
-#ifdef WIRELESS_EXT
 	struct iwreq *wrq = (struct iwreq *) rq;
 	int                 rc =0;
-#endif
     PSMgmtObject        pMgmt = pDevice->pMgmt;
     PSCmdRequest        pReq;
 
@@ -3416,9 +3151,6 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 
     switch(cmd) {
 
-#ifdef WIRELESS_EXT
-//#if WIRELESS_EXT < 13
-
 	case SIOCGIWNAME:
 		rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
 		break;
@@ -3490,13 +3222,13 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 
 		// Set desired station name
 	case SIOCSIWNICKN:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
         rc = -EOPNOTSUPP;
 		break;
 
 		// Get current station name
 	case SIOCGIWNICKN:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
         rc = -EOPNOTSUPP;
 		break;
 
@@ -3593,21 +3325,17 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		}
 		break;
 
-#if WIRELESS_EXT > 9
 		// Get the current Tx-Power
 	case SIOCGIWTXPOW:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
         rc = -EOPNOTSUPP;
 		break;
 
 	case SIOCSIWTXPOW:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
         rc = -EOPNOTSUPP;
 		break;
 
-#endif // WIRELESS_EXT > 9
-
-#if WIRELESS_EXT > 10
 	case SIOCSIWRETRY:
 
 		rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
@@ -3618,8 +3346,6 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
 		break;
 
-#endif // WIRELESS_EXT > 10
-
 		// Get range of parameters
 	case SIOCGIWRANGE:
 
@@ -3651,7 +3377,7 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		break;
 
 	case SIOCSIWSENS:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
 		rc = -EOPNOTSUPP;
 		break;
 
@@ -3677,21 +3403,21 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		// Set the spy list
 	case SIOCSIWSPY:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
 		rc = -EOPNOTSUPP;
 		break;
 
 		// Get the spy list
 	case SIOCGIWSPY:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
 		rc = -EOPNOTSUPP;
 		break;
 
 #endif // WIRELESS_SPY
 
 	case SIOCGIWPRIV:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
 		rc = -EOPNOTSUPP;
 /*
 		if(wrq->u.data.pointer) {
@@ -3706,33 +3432,32 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		break;
 
 
-//#endif // WIRELESS_EXT < 13
 //2008-0409-07, <Add> by Einsn Liu
 #ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 	case SIOCSIWAUTH:
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
 		rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
 		break;
 
 	case SIOCGIWAUTH:
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
 		rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
 		break;
 
 	case SIOCSIWGENIE:
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
 		rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
 		break;
 
 	case SIOCGIWGENIE:
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
 		rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
 		break;
 
 	case SIOCSIWENCODEEXT:
 		{
 			char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
-			DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
 			if(wrq->u.encoding.pointer){
 				memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
 				if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
@@ -3752,20 +3477,18 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 		break;
 
 	case SIOCGIWENCODEEXT:
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
 		rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
 		break;
 
 	case SIOCSIWMLME:
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
 		rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
 		break;
 
 #endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 //End Add -- //2008-0409-07, <Add> by Einsn Liu
 
-#endif // WIRELESS_EXT
-
     case IOCTL_CMD_TEST:
 
 		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
@@ -3804,20 +3527,12 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
     case IOCTL_CMD_HOSTAPD:
 
 
-#if WIRELESS_EXT > 8
-		rc = hostap_ioctl(pDevice, &wrq->u.data);
-#else // WIRELESS_EXT > 8
-		rc = hostap_ioctl(pDevice, (struct iw_point *) &wrq->u.data);
-#endif // WIRELESS_EXT > 8
+	rc = hostap_ioctl(pDevice, &wrq->u.data);
         break;
 
     case IOCTL_CMD_WPA:
 
-#if WIRELESS_EXT > 8
-		rc = wpa_ioctl(pDevice, &wrq->u.data);
-#else // WIRELESS_EXT > 8
-		rc = wpa_ioctl(pDevice, (struct iw_point *) &wrq->u.data);
-#endif // WIRELESS_EXT > 8
+	rc = wpa_ioctl(pDevice, &wrq->u.data);
         break;
 
 	case SIOCETHTOOL:
@@ -3826,7 +3541,7 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
 
 	default:
 		rc = -EOPNOTSUPP;
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
 
 
     }
@@ -3839,7 +3554,7 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
            spin_unlock_irq(&pDevice->lock);
        }
        else {
-           DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
+           DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
            spin_lock_irq(&pDevice->lock);
            pDevice->bLinkPass = FALSE;
            memset(pMgmt->abyCurrBSSID, 0, 6);
@@ -3883,7 +3598,6 @@ static int ethtool_ioctl(struct net_device *dev, void *useraddr)
 }
 
 /*------------------------------------------------------------------*/
-#ifndef PRIVATE_OBJ
 
 MODULE_DEVICE_TABLE(pci, device_id_table);
 
@@ -4016,59 +3730,6 @@ viawget_resume(struct pci_dev *pcid)
 
 #endif
 
-#endif //#ifndef PRIVATE_OBJ
-
-#ifdef PRIVATE_OBJ
-
-
-int __device_hw_reset(HANDLE pExDevice){
-     PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-
-     return MACbSoftwareReset(pDevice_info->port_offset);
-}
-
 
-int __device_hw_init(HANDLE pExDevice){
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    PSDevice    pDevice;
-
-    pDevice = (PSDevice)kmalloc(sizeof(DEVICE_INFO), (int)GFP_ATOMIC);
-    if (pDevice == NULL)
-        return FALSE;
-
-    memset(pDevice, 0, sizeof(DEVICE_INFO));
-    pDevice_info->pWDevice = pDevice;
-    pDevice->PortOffset = pDevice_info->port_offset;
-    pDevice->dev = pDevice_info->dev;
-    pDevice->pcid = pDevice_info->pcid;
-    pDevice->chip_id = pDevice_info->chip_id;
-    pDevice->memaddr = pDevice_info->mem_addr;
-    pDevice->ioaddr = pDevice_info->io_addr;
-    pDevice->io_size = pDevice_info->io_size;
-    pDevice->nTxQueues = pDevice_info->nTxQueues;
-    pDevice->multicast_limit = pDevice_info->multicast_limit;
-    pDevice->sMgmtObj.pAdapter = (PVOID)pDevice;
-    pDevice->pMgmt = &(pDevice->sMgmtObj);
-    MACvInitialize(pDevice->PortOffset);
-    device_get_options(pDevice, 0 , pDevice_info->dev->name);
-    device_set_options(pDevice);
-    pDevice->sOpts.flags &= pDevice_info->flags;
-    pDevice->flags = pDevice->sOpts.flags | (pDevice_info->flags & 0xFF000000UL);
-    spin_lock_init(&(pDevice->lock));
-
-    return TRUE;
-}
-
-
-void __device_read_mac(HANDLE pExDevice, PBYTE dev_addr){
-    PSDevice_info pDevice_info = (PSDevice_info)pExDevice;
-    PSDevice    pDevice = (PSDevice)(pDevice_info->pWDevice);
-
-    MACvReadEtherAddress(pDevice->PortOffset, dev_addr);
-    return;
-}
-
-
-#endif
 
 
diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c
index acc6d82..67f238c 100644
--- a/drivers/staging/vt6655/dpc.c
+++ b/drivers/staging/vt6655/dpc.c
@@ -38,61 +38,22 @@
  *
  */
 
-
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__MICHAEL_H__)
 #include "michael.h"
-#endif
-#if !defined(__TKIP_H__)
 #include "tkip.h"
-#endif
-#if !defined(__TCRC_H__)
 #include "tcrc.h"
-#endif
-#if !defined(__WCTL_H__)
 #include "wctl.h"
-#endif
-#if !defined(__WROUTE_H__)
 #include "wroute.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__HOSTAP_H__)
 #include "hostap.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
-#endif
-#if !defined(__AES_H__)
 #include "aes_ccmp.h"
-#endif
 
 //#define	PLICE_DEBUG
 
@@ -143,17 +104,7 @@ static BOOL s_bAPModeRxCtl(
     IN INT      iSANodeIndex
     );
 
-#ifdef PRIVATE_OBJ
 
-static BOOL s_bAPModeRxData (
-    IN PSDevice pDevice,
-    IN ref_sk_buff* skb,
-    IN UINT     FrameSize,
-    IN UINT     cbHeaderOffset,
-    IN INT      iSANodeIndex,
-    IN INT      iDANodeIndex
-    );
-#else
 
 static BOOL s_bAPModeRxData (
     IN PSDevice pDevice,
@@ -163,7 +114,6 @@ static BOOL s_bAPModeRxData (
     IN INT      iSANodeIndex,
     IN INT      iDANodeIndex
     );
-#endif
 
 
 static BOOL s_bHandleRxEncryption(
@@ -173,7 +123,7 @@ static BOOL s_bHandleRxEncryption(
     IN PBYTE        pbyRsr,
     OUT PBYTE       pbyNewRsr,
     OUT PSKeyItem   *pKeyOut,
-    OUT PBOOL       pbExtIV,
+    int *       pbExtIV,
     OUT PWORD       pwRxTSC15_0,
     OUT PDWORD      pdwRxTSC47_16
     );
@@ -187,7 +137,7 @@ static BOOL s_bHostWepRxEncryption(
     IN BOOL         bOnFly,
     IN PSKeyItem    pKey,
     OUT PBYTE       pbyNewRsr,
-    OUT PBOOL       pbExtIV,
+    int *       pbExtIV,
     OUT PWORD       pwRxTSC15_0,
     OUT PDWORD      pdwRxTSC47_16
 
@@ -395,11 +345,7 @@ device_receive_frame (
 	//printk("device_receive_frame:pCurrRD is %x,pRDInfo is %x\n",pCurrRD,pCurrRD->pRDInfo);
 #endif
     struct net_device_stats* pStats=&pDevice->stats;
-#ifdef PRIVATE_OBJ
-    ref_sk_buff*    skb;
-#else
     struct sk_buff* skb;
-#endif
     PSMgmtObject    pMgmt = pDevice->pMgmt;
     PSRxMgmtPacket  pRxPacket = &(pDevice->pMgmt->sRxPacket);
     PS802_11Header  p802_11Header;
@@ -434,13 +380,9 @@ device_receive_frame (
     PS802_11Header pMACHeader;
  BOOL            bRxeapol_key = FALSE;
 
-//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- device_receive_frame---\n");
-#ifdef PRIVATE_OBJ
-    skb = &(pRDInfo->ref_skb);
-#else
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- device_receive_frame---\n");
 
     skb = pRDInfo->skb;
-#endif
 
 
 //PLICE_DEBUG->
@@ -456,7 +398,7 @@ device_receive_frame (
     // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
     if ((FrameSize > 2364)||(FrameSize <= 32)) {
         // Frame Size error drop this packet.
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
         return FALSE;
     }
 
@@ -474,7 +416,7 @@ device_receive_frame (
 
     if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC
                                                // Min: 14 bytes ACK
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
         return FALSE;
     }
 //PLICE_DEBUG->
@@ -498,7 +440,7 @@ device_receive_frame (
         dwDuration = (FrameSize << 4);
         dwDuration /= acbyRxRate[*pbyRxRate%MAX_RATE];
         if (*pbyRxRate <= RATE_11M) {
-            if (BITbIsBitOn(*pbyRxSts, 0x01)) {
+            if (*pbyRxSts & 0x01) {
                 // long preamble
                 dwDuration += 192;
             } else {
@@ -541,11 +483,7 @@ device_receive_frame (
             p802_11Header = (PS802_11Header) (pbyFrame);
             // get SA NodeIndex
             if (BSSDBbIsSTAInNodeDB(pMgmt, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) {
-#ifdef PRIVATE_OBJ
-                pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = get_jiffies();
-#else
                 pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
-#endif
                 pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
             }
         }
@@ -556,10 +494,12 @@ device_receive_frame (
             return FALSE;
         }
     }
+
+
     if (IS_FC_WEP(pbyFrame)) {
         BOOL     bRxDecryOK = FALSE;
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
         bIsWEP = TRUE;
         if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) {
             pKey = &STempKey;
@@ -597,7 +537,7 @@ device_receive_frame (
 
         if (bRxDecryOK) {
             if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
                 if ( (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
                     (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
                     (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
@@ -615,7 +555,7 @@ device_receive_frame (
                 return FALSE;
             }
         } else {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
             return FALSE;
         }
         if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
@@ -631,7 +571,7 @@ device_receive_frame (
     //remove the CRC length
     FrameSize -= U_CRC_LEN;
 
-    if ((BITbIsAllBitsOff(*pbyRsr, (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address
+    if (( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI))) && // unicast address
         (IS_FRAGMENT_PKT((skb->data+4)))
         ) {
         // defragment
@@ -639,11 +579,7 @@ device_receive_frame (
         pDevice->s802_11Counter.ReceivedFragmentCount++;
         if (bDeFragRx) {
             // defrag complete
-#ifdef PRIVATE_OBJ
-            skb = &(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].ref_skb);
-#else
             skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
-#endif
             FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
 
         }
@@ -705,25 +641,14 @@ device_receive_frame (
             // hostap Deamon handle 802.11 management
             if (pDevice->bEnableHostapd) {
 	            skb->dev = pDevice->apdev;
-#ifdef PRIVATE_OBJ
-                ref_skb_add_offset(skb->skb, 4);
-                ref_skb_set_dev(pDevice->apdev, skb->skb);
-                skb_put(skb->skb, FrameSize);
-	            skb->mac_header = skb->data;
-	            *(skb->pkt_type) = PACKET_OTHERHOST;
-    	        *(skb->protocol) = htons(ETH_P_802_2);
-	            memset(skb->cb, 0, sizeof(skb->cb));
-	            netif_rx(skb->skb);
-#else
 	            skb->data += 4;
 	            skb->tail += 4;
                      skb_put(skb, FrameSize);
-	            skb->mac_header = skb->data;
+		skb_reset_mac_header(skb);
 	            skb->pkt_type = PACKET_OTHERHOST;
     	        skb->protocol = htons(ETH_P_802_2);
 	            memset(skb->cb, 0, sizeof(skb->cb));
 	            netif_rx(skb);
-#endif
                 return TRUE;
 	        }
         }
@@ -735,10 +660,10 @@ device_receive_frame (
     else {
         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
             //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
-            if (BITbIsBitOff(*pbyRsr, RSR_BSSIDOK)) {
+            if ( !(*pbyRsr & RSR_BSSIDOK)) {
                 if (bDeFragRx) {
                     if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
-                        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                         pDevice->dev->name);
                     }
                 }
@@ -748,16 +673,15 @@ device_receive_frame (
         else {
             // discard DATA packet while not associate || BSSID error
             if ((pDevice->bLinkPass == FALSE) ||
-                BITbIsBitOff(*pbyRsr, RSR_BSSIDOK)) {
+                !(*pbyRsr & RSR_BSSIDOK)) {
                 if (bDeFragRx) {
                     if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
-                        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                         pDevice->dev->name);
                     }
                 }
                 return FALSE;
             }
-
    //mike add:station mode check eapol-key challenge--->
    	  {
    	    BYTE  Protocol_Version;    //802.1x Authentication
@@ -781,11 +705,13 @@ device_receive_frame (
         }
     }
 
+
 // Data frame Handle
 
+
     if (pDevice->bEnablePSMode) {
         if (IS_FC_MOREDATA((skb->data+4))) {
-            if (BITbIsBitOn(*pbyRsr, RSR_ADDROK)) {
+            if (*pbyRsr & RSR_ADDROK) {
                 //PSbSendPSPOLL((PSDevice)pDevice);
             }
         }
@@ -837,7 +763,7 @@ device_receive_frame (
         wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) |
                     skb->data[cbIVOffset + 4 + 24 + 6 + 1];
 
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType);
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType);
         if (wEtherType == ETH_P_PAE) {
             skb->dev = pDevice->apdev;
 
@@ -846,26 +772,15 @@ device_receive_frame (
                 memcpy(&abyMacHdr[0], (skb->data + 4), 24);
                 memcpy((skb->data + 4 + cbIVOffset), &abyMacHdr[0], 24);
             }
-#ifdef PRIVATE_OBJ
-            ref_skb_add_offset(skb->skb, (cbIVOffset + 4));
-            ref_skb_set_dev(pDevice->apdev, skb->skb);
-            skb_put(skb->skb, FrameSize);
-			skb->mac_header = skb->data;
-            *(skb->pkt_type) = PACKET_OTHERHOST;
-	        *(skb->protocol) = htons(ETH_P_802_2);
-            memset(skb->cb, 0, sizeof(skb->cb));
-            netif_rx(skb->skb);
-#else
             skb->data +=  (cbIVOffset + 4);
             skb->tail +=  (cbIVOffset + 4);
             skb_put(skb, FrameSize);
-           skb->mac_header = skb->data;
+	    skb_reset_mac_header(skb);
 
 	skb->pkt_type = PACKET_OTHERHOST;
             skb->protocol = htons(ETH_P_802_2);
             memset(skb->cb, 0, sizeof(skb->cb));
             netif_rx(skb);
-#endif
             return TRUE;
 
 }
@@ -925,27 +840,26 @@ device_receive_frame (
             pdwMIC_R = (PDWORD)(skb->data + 4 + FrameSize + 4);
             //DBG_PRN_GRP12(("RxL: %lx, RxR: %lx\n", *pdwMIC_L, *pdwMIC_R));
             //DBG_PRN_GRP12(("LocalL: %lx, LocalR: %lx\n", dwLocalMIC_L, dwLocalMIC_R));
-            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1);
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwMICKey0= %lx,dwMICKey1= %lx \n", dwMICKey0, dwMICKey1);
 
 
             if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
                 (pDevice->bRxMICFail == TRUE)) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
                 pDevice->bRxMICFail = FALSE;
                 //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++;
                 pDevice->s802_11Counter.TKIPLocalMICFailures++;
                 if (bDeFragRx) {
                     if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
-                        DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                             pDevice->dev->name);
                     }
                 }
-
-//2008-0409-07, <Add> by Einsn Liu
+               //2008-0409-07, <Add> by Einsn Liu
        #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
 				//send event to wpa_supplicant
 				//if(pDevice->bWPADevEnable == TRUE)
-					{
+				{
 					union iwreq_data wrqu;
 					struct iw_michaelmicfailure ev;
 					int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
@@ -967,6 +881,8 @@ device_receive_frame (
 
 				}
          #endif
+
+
                 if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
                      wpahdr = (viawget_wpa_header *)pDevice->skb->data;
                      if ((pDevice->pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
@@ -982,7 +898,7 @@ device_receive_frame (
                      wpahdr->req_ie_len = 0;
                      skb_put(pDevice->skb, sizeof(viawget_wpa_header));
                      pDevice->skb->dev = pDevice->wpadev;
-                     pDevice->skb->mac_header = pDevice->skb->data;
+		     skb_reset_mac_header(pDevice->skb);
                      pDevice->skb->pkt_type = PACKET_HOST;
                      pDevice->skb->protocol = htons(ETH_P_802_2);
                      memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
@@ -1012,7 +928,7 @@ device_receive_frame (
             RSC = dwRxTSC47_16;
             RSC <<= 16;
             RSC += wRxTSC15_0;
-            MEMvCopy(&(pKey->KeyRSC), &RSC,  sizeof(QWORD));
+            memcpy(&(pKey->KeyRSC), &RSC,  sizeof(QWORD));
 
             if ( (pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) &&
                  (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) {
@@ -1020,7 +936,7 @@ device_receive_frame (
                 if ( (wRxTSC15_0 < wLocalTSC15_0) &&
                      (dwRxTSC47_16 <= dwLocalTSC47_16) &&
                      !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n ");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n ");
                     if (pKey->byCipherSuite == KEY_CTL_TKIP)
                         //pDevice->s802_11Counter.TKIPReplays.QuadPart++;
                         pDevice->s802_11Counter.TKIPReplays++;
@@ -1030,7 +946,7 @@ device_receive_frame (
 
                     if (bDeFragRx) {
                         if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
-                            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                                 pDevice->dev->name);
                         }
                     }
@@ -1066,7 +982,7 @@ device_receive_frame (
 
             if (bDeFragRx) {
                 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
-                    DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                     pDevice->dev->name);
                 }
             }
@@ -1081,34 +997,22 @@ device_receive_frame (
 
     }
 
-#ifdef PRIVATE_OBJ
-    ref_skb_add_offset(skb->skb, cbHeaderOffset);
-    skb_put(skb->skb, FrameSize);
-    *(skb->protocol)=eth_type_trans(skb->skb, skb->dev);
-
-#else
 	skb->data += cbHeaderOffset;
 	skb->tail += cbHeaderOffset;
     skb_put(skb, FrameSize);
     skb->protocol=eth_type_trans(skb, skb->dev);
-#endif
 
 
 	//drop frame not met IEEE 802.3
 /*
 	if (pDevice->flags & DEVICE_FLAGS_VAL_PKT_LEN) {
-#ifdef PRIVATE_OBJ
-		if ((*(skb->protocol)==htons(ETH_P_802_3)) &&
-			(*(skb->len)!=htons(skb->mac.ethernet->h_proto))) {
-#else
 		if ((skb->protocol==htons(ETH_P_802_3)) &&
 			(skb->len!=htons(skb->mac.ethernet->h_proto))) {
-#endif
 			pStats->rx_length_errors++;
 			pStats->rx_dropped++;
             if (bDeFragRx) {
                 if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
-                    DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                     pDevice->dev->name);
                 }
             }
@@ -1117,25 +1021,19 @@ device_receive_frame (
 	}
 */
 
-#ifdef PRIVATE_OBJ
-    *(skb->ip_summed)=CHECKSUM_NONE;
-    pStats->rx_bytes +=*(skb->len);
-    pStats->rx_packets++;
-    netif_rx(skb->skb);
-#else
     skb->ip_summed=CHECKSUM_NONE;
     pStats->rx_bytes +=skb->len;
     pStats->rx_packets++;
     netif_rx(skb);
-#endif
 
     if (bDeFragRx) {
         if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
-            DEVICE_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
                 pDevice->dev->name);
         }
         return FALSE;
     }
+
     return TRUE;
 }
 
@@ -1169,7 +1067,7 @@ static BOOL s_bAPModeRxCtl (
                                          (WLAN_MGMT_REASON_CLASS2_NONAUTH),
                                          &Status
                                          );
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
                     return TRUE;
                 };
                 if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
@@ -1181,7 +1079,7 @@ static BOOL s_bAPModeRxCtl (
                                          (WLAN_MGMT_REASON_CLASS3_NONASSOC),
                                          &Status
                                          );
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
                     return TRUE;
                 };
 
@@ -1190,7 +1088,7 @@ static BOOL s_bAPModeRxCtl (
                     if (IS_CTL_PSPOLL(pbyFrame)) {
                         pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
                         bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n");
                     }
                     else {
                         // check Data PS state
@@ -1199,7 +1097,7 @@ static BOOL s_bAPModeRxCtl (
                             pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
                             pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
                             bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n");
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n");
                         }
                     }
                 }
@@ -1215,7 +1113,7 @@ static BOOL s_bAPModeRxCtl (
                           pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
                           pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
                           bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
-                         DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n");
+                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n");
 
                       }
                    }
@@ -1228,8 +1126,8 @@ static BOOL s_bAPModeRxCtl (
                                        (WLAN_MGMT_REASON_CLASS2_NONAUTH),
                                        &Status
                                        );
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n");
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%02x-%02x-%02x=%02x-%02x-%02x \n",
                                 p802_11Header->abyAddr3[0],
                                 p802_11Header->abyAddr3[1],
                                 p802_11Header->abyAddr3[2],
@@ -1237,7 +1135,7 @@ static BOOL s_bAPModeRxCtl (
                                 p802_11Header->abyAddr3[4],
                                 p802_11Header->abyAddr3[5]
                                );
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%02x-%02x-%02x=%02x-%02x-%02x \n",
                                 p802_11Header->abyAddr2[0],
                                 p802_11Header->abyAddr2[1],
                                 p802_11Header->abyAddr2[2],
@@ -1245,7 +1143,7 @@ static BOOL s_bAPModeRxCtl (
                                 p802_11Header->abyAddr2[4],
                                 p802_11Header->abyAddr2[5]
                                );
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%02x-%02x-%02x=%02x-%02x-%02x \n",
                                 p802_11Header->abyAddr1[0],
                                 p802_11Header->abyAddr1[1],
                                 p802_11Header->abyAddr1[2],
@@ -1253,9 +1151,9 @@ static BOOL s_bAPModeRxCtl (
                                 p802_11Header->abyAddr1[4],
                                 p802_11Header->abyAddr1[5]
                                );
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl );
                     VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode));
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode );
                     return TRUE;
             }
         }
@@ -1271,7 +1169,7 @@ static BOOL s_bHandleRxEncryption (
     IN PBYTE        pbyRsr,
     OUT PBYTE       pbyNewRsr,
     OUT PSKeyItem   *pKeyOut,
-    OUT PBOOL       pbExtIV,
+    int *       pbExtIV,
     OUT PWORD       pwRxTSC15_0,
     OUT PDWORD      pdwRxTSC47_16
     )
@@ -1295,7 +1193,7 @@ static BOOL s_bHandleRxEncryption (
     }
     byKeyIdx = (*(pbyIV+3) & 0xc0);
     byKeyIdx >>= 6;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
 
     if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
         (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
@@ -1305,14 +1203,14 @@ static BOOL s_bHandleRxEncryption (
         if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
             (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) {
             // unicast pkt use pairwise key
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
             if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == TRUE) {
                 if (pDevice->pMgmt->byCSSPK == KEY_CTL_TKIP)
                     byDecMode = KEY_CTL_TKIP;
                 else if (pDevice->pMgmt->byCSSPK == KEY_CTL_CCMP)
                     byDecMode = KEY_CTL_CCMP;
             }
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey);
         } else {
             // use group key
             KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
@@ -1320,7 +1218,7 @@ static BOOL s_bHandleRxEncryption (
                 byDecMode = KEY_CTL_TKIP;
             else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
                 byDecMode = KEY_CTL_CCMP;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
         }
     }
     // our WEP only support Default Key
@@ -1334,10 +1232,10 @@ static BOOL s_bHandleRxEncryption (
     }
     *pKeyOut = pKey;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
 
     if (pKey == NULL) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
         if (byDecMode == KEY_CTL_WEP) {
 //            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
         } else if (pDevice->bLinkPass == TRUE) {
@@ -1363,8 +1261,8 @@ static BOOL s_bHandleRxEncryption (
             // 2. WEP 256
 
             PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
-            MEMvCopy(pDevice->abyPRNG, pbyIV, 3);
-            MEMvCopy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
+            memcpy(pDevice->abyPRNG, pbyIV, 3);
+            memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
             rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
             rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
 
@@ -1378,13 +1276,13 @@ static BOOL s_bHandleRxEncryption (
 
         PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
         *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
         if (byDecMode == KEY_CTL_TKIP) {
             *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
         } else {
             *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
 
         if ((byDecMode == KEY_CTL_TKIP) &&
             (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
@@ -1396,10 +1294,10 @@ static BOOL s_bHandleRxEncryption (
             rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
             if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
                 *pbyNewRsr |= NEWRSR_DECRYPTOK;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
             } else {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
             }
         }
     }// end of TKIP/AES
@@ -1418,7 +1316,7 @@ static BOOL s_bHostWepRxEncryption (
     IN BOOL         bOnFly,
     IN PSKeyItem    pKey,
     OUT PBYTE       pbyNewRsr,
-    OUT PBOOL       pbExtIV,
+    int *       pbExtIV,
     OUT PWORD       pwRxTSC15_0,
     OUT PDWORD      pdwRxTSC47_16
     )
@@ -1442,7 +1340,7 @@ static BOOL s_bHostWepRxEncryption (
     }
     byKeyIdx = (*(pbyIV+3) & 0xc0);
     byKeyIdx >>= 6;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
 
 
     if (pDevice->pMgmt->byCSSGK == KEY_CTL_TKIP)
@@ -1450,7 +1348,7 @@ static BOOL s_bHostWepRxEncryption (
     else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP)
         byDecMode = KEY_CTL_CCMP;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode);
 
     if (byDecMode != pKey->byCipherSuite) {
         if (byDecMode == KEY_CTL_WEP) {
@@ -1463,7 +1361,7 @@ static BOOL s_bHostWepRxEncryption (
 
     if (byDecMode == KEY_CTL_WEP) {
         // handle WEP
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n");
         if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
             (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE) ||
             (bOnFly == FALSE)) {
@@ -1473,8 +1371,8 @@ static BOOL s_bHostWepRxEncryption (
             // 3. NotOnFly
 
             PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
-            MEMvCopy(pDevice->abyPRNG, pbyIV, 3);
-            MEMvCopy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
+            memcpy(pDevice->abyPRNG, pbyIV, 3);
+            memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
             rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
             rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
 
@@ -1488,31 +1386,32 @@ static BOOL s_bHostWepRxEncryption (
 
         PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
         *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
 
         if (byDecMode == KEY_CTL_TKIP) {
             *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
         } else {
             *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
 
         if (byDecMode == KEY_CTL_TKIP) {
+
             if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == FALSE)) {
                 // Software TKIP
                 // 1. 3253 A
                 // 2. NotOnFly
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_TKIP \n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_TKIP \n");
                 pMACHeader = (PS802_11Header) (pbyFrame);
                 TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
                 rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
                 rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
                 if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
                     *pbyNewRsr |= NEWRSR_DECRYPTOK;
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
                 } else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
                 }
             }
         }
@@ -1521,12 +1420,12 @@ static BOOL s_bHostWepRxEncryption (
             if (bOnFly == FALSE) {
                 // Software CCMP
                 // NotOnFly
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n");
                 if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) {
                     *pbyNewRsr |= NEWRSR_DECRYPTOK;
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n");
                 } else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n");
                 }
             }
         }
@@ -1540,20 +1439,6 @@ static BOOL s_bHostWepRxEncryption (
 
 
 
-
-#ifdef PRIVATE_OBJ
-
-static BOOL s_bAPModeRxData (
-    IN PSDevice pDevice,
-    IN ref_sk_buff* skb,
-    IN UINT     FrameSize,
-    IN UINT     cbHeaderOffset,
-    IN INT      iSANodeIndex,
-    IN INT      iDANodeIndex
-    )
-
-#else
-
 static BOOL s_bAPModeRxData (
     IN PSDevice pDevice,
     IN struct sk_buff* skb,
@@ -1562,22 +1447,15 @@ static BOOL s_bAPModeRxData (
     IN INT      iSANodeIndex,
     IN INT      iDANodeIndex
     )
-#endif
 {
     PSMgmtObject        pMgmt = pDevice->pMgmt;
     BOOL                bRelayAndForward = FALSE;
     BOOL                bRelayOnly = FALSE;
     BYTE                byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
     WORD                wAID;
-#ifdef PRIVATE_OBJ
-    struct sk_buff* tmp_skb;
-    ref_sk_buff     s_ref_skb;
-    ref_sk_buff*    skbcpy = &s_ref_skb;
-#else
-    struct sk_buff* skbcpy = NULL;
-#endif
 
 
+    struct sk_buff* skbcpy = NULL;
 
     if (FrameSize > CB_MAX_BUF_SIZE)
         return FALSE;
@@ -1585,28 +1463,18 @@ static BOOL s_bAPModeRxData (
     if(IS_MULTICAST_ADDRESS((PBYTE)(skb->data+cbHeaderOffset))) {
        if (pMgmt->sNodeDBTable[0].bPSEnable) {
 
-#ifdef PRIVATE_OBJ
-           tmp_skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-           skbcpy = &s_ref_skb;
-           ref_skb_remap(pDevice->dev, skbcpy, tmp_skb);
-#else
            skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
-#endif
+
         // if any node in PS mode, buffer packet until DTIM.
            if (skbcpy == NULL) {
-               DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
+               DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
            }
            else {
                skbcpy->dev = pDevice->dev;
-#ifdef PRIVATE_OBJ
-               *(skbcpy->len) = FrameSize;
-               memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
-               skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy->skb);
-#else
                skbcpy->len = FrameSize;
                memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
                skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy);
-#endif
+
                pMgmt->sNodeDBTable[0].wEnQueueCnt++;
                // set tx map
                pMgmt->abyPSTxMap[0] |= byMask[0];
@@ -1623,20 +1491,14 @@ static BOOL s_bAPModeRxData (
                 if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) {
                     // queue this skb until next PS tx, and then release.
 
-#ifdef PRIVATE_OBJ
-                    ref_skb_add_offset(skb->skb, cbHeaderOffset);
-                    skb_put(skb->skb, FrameSize);
-                    skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb->skb);
-#else
 	                skb->data += cbHeaderOffset;
 	                skb->tail += cbHeaderOffset;
                     skb_put(skb, FrameSize);
                     skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb);
-#endif
                     pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++;
                     wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID;
                     pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
                                iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
                     return TRUE;
                 }
diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h
index 68447c4..51508b9 100644
--- a/drivers/staging/vt6655/dpc.h
+++ b/drivers/staging/vt6655/dpc.h
@@ -16,7 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * File: whdr.h
+ * File: dpc.h
  *
  * Purpose:
  *
@@ -26,20 +26,12 @@
  *
  */
 
-
 #ifndef __DPC_H__
 #define __DPC_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -49,26 +41,14 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
-
 BOOL
 device_receive_frame (
     IN  PSDevice pDevice,
     IN  PSRxDesc pCurrRD
     );
 
-
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
 VOID	MngWorkItem(PVOID Context);
+
 #endif // __RXTX_H__
 
 
diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c
index 91f189d..58abf44 100644
--- a/drivers/staging/vt6655/hostap.c
+++ b/drivers/staging/vt6655/hostap.c
@@ -30,32 +30,13 @@
  *
  */
 
-
-#if !defined(__HOSTAP_H__)
 #include "hostap.h"
-#endif
-#if !defined(__IOCMD_H__)
 #include "iocmd.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__WPACTL_H__)
 #include "wpactl.h"
-#endif
-#if !defined(__KEY_H__)
 #include "key.h"
-#endif
-#if !defined(__MAC_H__)
-#include "mac.h"
-#endif
-
 
 #define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024
 #define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0
@@ -103,29 +84,13 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
     PSDevice apdev_priv;
 	struct net_device *dev = pDevice->dev;
 	int ret;
+	const struct net_device_ops apdev_netdev_ops = {
+		.ndo_start_xmit         = pDevice->tx_80211,
+	};
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
-
-#ifdef PRIVATE_OBJ
-    pDevice->apdev = ref_init_apdev(dev);
-
-    if (pDevice->apdev == NULL)
-		return -ENOMEM;
-
-	if (rtnl_locked)
-		ret = register_netdevice(pDevice->apdev);
-	else
-		ret = register_netdev(pDevice->apdev);
-	if (ret) {
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
-		       dev->name);
-		return -1;
-	}
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
-	       dev->name, pDevice->apdev->name);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
 
-#else
-    pDevice->apdev = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);
+	pDevice->apdev = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);
 	if (pDevice->apdev == NULL)
 		return -ENOMEM;
 	memset(pDevice->apdev, 0, sizeof(struct net_device));
@@ -134,10 +99,7 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
     *apdev_priv = *pDevice;
 	memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
 
-    const struct net_device_ops apdev_netdev_ops = {
-        .ndo_start_xmit         = pDevice->tx_80211,
-    };
-    pDevice->apdev->netdev_ops = &apdev_netdev_ops;
+	pDevice->apdev->netdev_ops = &apdev_netdev_ops;
 
 	pDevice->apdev->type = ARPHRD_IEEE80211;
 
@@ -151,16 +113,15 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
 	else
 		ret = register_netdev(pDevice->apdev);
 	if (ret) {
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
 		       dev->name);
 		return -1;
 	}
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
 	       dev->name, pDevice->apdev->name);
 
     KeyvInitTable(&pDevice->sKey, pDevice->PortOffset);
-#endif
 
 	return 0;
 }
@@ -182,14 +143,14 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
 static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked)
 {
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);
 
     if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) {
 		if (rtnl_locked)
 			unregister_netdevice(pDevice->apdev);
 		else
 			unregister_netdev(pDevice->apdev);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
 		       pDevice->dev->name, pDevice->apdev->name);
 	}
 	kfree(pDevice->apdev);
@@ -308,13 +269,11 @@ static int hostap_add_sta(PSDevice pDevice,
             WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo);
 
     pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid;
-#ifdef PRIVATE_OBJ
-    pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = get_jiffies();
-#else
+
     pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
-#endif
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
                param->sta_addr[0],
                param->sta_addr[1],
                param->sta_addr[2],
@@ -322,7 +281,7 @@ static int hostap_add_sta(PSDevice pDevice,
                param->sta_addr[4],
                param->sta_addr[5]
               ) ;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
                pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
 
 	return 0;
@@ -349,13 +308,9 @@ static int hostap_get_info_sta(PSDevice pDevice,
 	UINT uNodeIndex;
 
     if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
-#ifdef PRIVATE_OBJ
-	    param->u.get_info_sta.inactive_sec =
-	        (get_jiffies() - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
-#else
 	    param->u.get_info_sta.inactive_sec =
 	        (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
-#endif
+
 	    //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts;
 	}
 	else {
@@ -419,7 +374,7 @@ static int hostap_set_flags_sta(PSDevice pDevice,
     if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &uNodeIndex)) {
 		pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
 		pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n",
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n",
 		            (UINT)pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
 	}
 	else {
@@ -458,18 +413,18 @@ static int hostap_set_generic_element(PSDevice pDevice,
 
     pMgmt->wWPAIELen = 	param->u.generic_elem.len;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n",  pMgmt->wWPAIELen);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n",  pMgmt->wWPAIELen);
 
     // disable wpa
     if (pMgmt->wWPAIELen == 0) {
         pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
     } else  {
         // enable wpa
         if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) ||
              (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) {
               pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
-               DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n");
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n");
         } else
             return -EINVAL;
     }
@@ -543,7 +498,7 @@ static int hostap_set_encryption(PSDevice pDevice,
 
 	if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) {
 		param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n");
 		return -EINVAL;
 	}
 
@@ -557,12 +512,12 @@ static int hostap_set_encryption(PSDevice pDevice,
 	} else {
 	    if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == FALSE) {
 	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
 	        return -EINVAL;
 	    }
 	}
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
 
 	if (param->u.crypt.alg == WPA_ALG_NONE) {
 
@@ -571,7 +526,7 @@ static int hostap_set_encryption(PSDevice pDevice,
                                 param->sta_addr,
                                 pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex,
                                 pDevice->PortOffset) == FALSE) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
             }
             pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
         }
@@ -706,7 +661,7 @@ static int hostap_set_encryption(PSDevice pDevice,
             // Key Table Full
             pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
             bKeyTableFull = TRUE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
         }
 
     }
@@ -720,10 +675,10 @@ static int hostap_set_encryption(PSDevice pDevice,
         MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
     }
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
                param->u.crypt.key_len );
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1],
                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2],
@@ -775,11 +730,11 @@ static int hostap_get_encryption(PSDevice pDevice,
 	} else {
 	    if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == FALSE) {
 	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
 	        return -EINVAL;
 	    }
 	}
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
     memset(param->u.crypt.seq, 0, 8);
     for (ii = 0 ; ii < 8 ; ii++) {
         param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
@@ -824,74 +779,74 @@ int hostap_ioctl(PSDevice pDevice, struct iw_point *p)
 
 	switch (param->cmd) {
 	case VIAWGET_HOSTAPD_SET_ENCRYPTION:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
         spin_lock_irq(&pDevice->lock);
 		ret = hostap_set_encryption(pDevice, param, p->length);
         spin_unlock_irq(&pDevice->lock);
 		break;
 	case VIAWGET_HOSTAPD_GET_ENCRYPTION:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
         spin_lock_irq(&pDevice->lock);
 		ret = hostap_get_encryption(pDevice, param, p->length);
         spin_unlock_irq(&pDevice->lock);
 		break;
 	case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
 		return -EOPNOTSUPP;
 		break;
 	case VIAWGET_HOSTAPD_FLUSH:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
         spin_lock_irq(&pDevice->lock);
     	hostap_flush_sta(pDevice);
         spin_unlock_irq(&pDevice->lock);
 		break;
 	case VIAWGET_HOSTAPD_ADD_STA:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
          spin_lock_irq(&pDevice->lock);
 		 ret = hostap_add_sta(pDevice, param);
          spin_unlock_irq(&pDevice->lock);
 		break;
 	case VIAWGET_HOSTAPD_REMOVE_STA:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
          spin_lock_irq(&pDevice->lock);
 		 ret = hostap_remove_sta(pDevice, param);
          spin_unlock_irq(&pDevice->lock);
 		break;
 	case VIAWGET_HOSTAPD_GET_INFO_STA:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
 		 ret = hostap_get_info_sta(pDevice, param);
 		 ap_ioctl = 1;
 		break;
 /*
 	case VIAWGET_HOSTAPD_RESET_TXEXC_STA:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n");
 		 ret = hostap_reset_txexc_sta(pDevice, param);
 		break;
 */
 	case VIAWGET_HOSTAPD_SET_FLAGS_STA:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
 		 ret = hostap_set_flags_sta(pDevice, param);
 		break;
 
 	case VIAWGET_HOSTAPD_MLME:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
 	    return -EOPNOTSUPP;
 
 	case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
 		ret = hostap_set_generic_element(pDevice, param);
 		break;
 
 	case VIAWGET_HOSTAPD_SCAN_REQ:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
 	    return -EOPNOTSUPP;
 
 	case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
 	    return -EOPNOTSUPP;
 
 	default:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_ioctl: unknown cmd=%d\n",
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_ioctl: unknown cmd=%d\n",
 		       (int)param->cmd);
 		return -EOPNOTSUPP;
 		break;
diff --git a/drivers/staging/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h
index 1fcb2f0..8fd667b 100644
--- a/drivers/staging/vt6655/hostap.h
+++ b/drivers/staging/vt6655/hostap.h
@@ -26,25 +26,13 @@
  *
  */
 
-
 #ifndef __HOSTAP_H__
 #define __HOSTAP_H__
 
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
-#if WIRELESS_EXT < 9
-struct iw_point {
-	caddr_t pointer;
-	__u16 length;
-	__u16 flags;
-};
-#endif /* WIRELESS_EXT < 9 */
-
 #define WLAN_RATE_1M    BIT0
 #define WLAN_RATE_2M    BIT1
 #define WLAN_RATE_5M5   BIT2
@@ -65,11 +53,6 @@ struct iw_point {
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 #ifndef ETH_P_PAE
 #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
 #endif /* ETH_P_PAE */
@@ -81,13 +64,6 @@ extern "C" {                            /* Assume C declarations for C++ */
 int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked);
 int hostap_ioctl(PSDevice pDevice, struct iw_point *p);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __HOSTAP_H__
 
 
diff --git a/drivers/staging/vt6655/iocmd.h b/drivers/staging/vt6655/iocmd.h
index ada9ee9..60c0a36 100644
--- a/drivers/staging/vt6655/iocmd.h
+++ b/drivers/staging/vt6655/iocmd.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 1996, 2003 VIA Networking, Inc. All rights reserved.
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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
@@ -28,10 +29,7 @@
 #ifndef __IOCMD_H__
 #define __IOCMD_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -73,12 +71,12 @@ typedef enum tagWMAC_CMD {
     WLAN_CMD_SET_HOST_WEP,
     WLAN_CMD_SET_WPA,
     WLAN_CMD_GET_NODE_CNT,
-     WLAN_CMD_ZONETYPE_SET,
+    WLAN_CMD_ZONETYPE_SET,
     WLAN_CMD_GET_NODE_LIST
 
-} WMAC_CMD, DEF* PWMAC_CMD;
+} WMAC_CMD, *PWMAC_CMD;
 
-	typedef enum tagWZONETYPE {
+typedef enum tagWZONETYPE {
   ZoneType_USA=0,
   ZoneType_Japan=1,
   ZoneType_Europe=2
@@ -106,7 +104,6 @@ typedef enum tagWMAC_CMD {
 #define WEP_104BIT_LEN         13
 #define WEP_232BIT_LEN         16
 
-
 // Ioctl interface structure
 // Command structure
 //
@@ -118,7 +115,6 @@ typedef struct tagSCmdRequest {
 	U16     wCmdCode;
 } SCmdRequest, *PSCmdRequest;
 
-
 //
 // Scan
 //
@@ -145,6 +141,10 @@ typedef struct tagSCmdBSSJoin {
 
 } SCmdBSSJoin, *PSCmdBSSJoin;
 
+//
+// Zonetype Setting
+//
+
 typedef struct tagSCmdZoneTypeSet {
 
  BOOL       bWrite;
@@ -162,7 +162,6 @@ typedef struct tagSWPAResult {
 } SWPAResult, *PSWPAResult;
 #endif
 
-
 typedef struct tagSCmdStartAP {
 
     U16	    wBSSType;
@@ -242,7 +241,7 @@ typedef struct tagSDot11MIBCount {
     U32 ReceivedFragmentCount;
     U32 MulticastReceivedFrameCount;
     U32 FCSErrorCount;
-} SDot11MIBCount, DEF* PSDot11MIBCount;
+} SDot11MIBCount, *PSDot11MIBCount;
 
 
 
@@ -349,7 +348,7 @@ typedef struct tagSStatMIBCount {
     U32   ullTxBroadcastBytes[2];
     U32   ullTxMulticastBytes[2];
     U32   ullTxDirectedBytes[2];
-} SStatMIBCount, DEF* PSStatMIBCount;
+} SStatMIBCount, *PSStatMIBCount;
 
 
 typedef struct tagSNodeItem {
diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c
index 4869107..fc9cbe0 100644
--- a/drivers/staging/vt6655/ioctl.c
+++ b/drivers/staging/vt6655/ioctl.c
@@ -30,32 +30,13 @@
  *
  */
 
-
-#if !defined(__IOCTL_H__)
 #include "ioctl.h"
-#endif
-#if !defined(__IOCMD_H__)
 #include "iocmd.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__HOSTAP_H__)
 #include "hostap.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__WPACTL_H__)
 #include "wpactl.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -65,12 +46,11 @@
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 static int          msglevel                =MSG_LEVEL_INFO;
 
-/*---------------------  Static Functions  --------------------------*/
-
 #ifdef WPA_SM_Transtatus
     SWPAResult wpa_Result;
 #endif
 
+/*---------------------  Static Functions  --------------------------*/
 
 /*---------------------  Export Variables  --------------------------*/
 
@@ -101,14 +81,13 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
     BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
     LONG                ldBm;
 
-
     pReq->wResult = 0;
 
     switch(pReq->wCmdCode) {
 
     case WLAN_CMD_BSS_SCAN:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin \n");
         if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) {
 			result = -EFAULT;
 			break;
@@ -214,31 +193,31 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 		memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
 	    if (sJoinCmd.wBSSType == ADHOC) {
 	        pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
-	        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n");
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n");
 	    }
 	    else {
 	        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
-	        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n");
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n");
 	    }
 	    if (sJoinCmd.bPSEnable == TRUE) {
             pDevice->ePSMode = WMAC_POWER_FAST;
 //            pDevice->ePSMode = WMAC_POWER_MAX;
             pMgmt->wListenInterval = 2;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n");
         }
         else {
             pDevice->ePSMode = WMAC_POWER_CAM;
             pMgmt->wListenInterval = 1;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off \n");
         }
 
         if (sJoinCmd.bShareKeyAuth == TRUE){
             pMgmt->bShareKeyAlgorithm = TRUE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
         }
         else {
             pMgmt->bShareKeyAlgorithm = FALSE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
         }
 	    pDevice->uChannel = sJoinCmd.uChannel;
         netif_stop_queue(pDevice->dev);
@@ -250,8 +229,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         break;
 
     case WLAN_CMD_SET_WEP:
-
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key. \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key. \n");
         memset(&sWEPCmd, 0 ,sizeof(SCmdSetWEP));
         if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) {
 			result = -EFAULT;
@@ -261,7 +239,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
             pDevice->bEncryptionEnable = FALSE;
             pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
             MACvDisableDefaultKey(pDevice->PortOffset);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable. \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable. \n");
             break;
         }
 
@@ -293,7 +271,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         break;
 
     case WLAN_CMD_GET_LINK:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status. \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status. \n");
 
         memset(sLinkStatus.abySSID, 0 , WLAN_SSID_MAXLEN + 1);
 
@@ -314,7 +292,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 		    memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len);
 		    memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
 		    sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Link Success ! \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Link Success ! \n");
         }
         else {
             sLinkStatus.bLink = FALSE;
@@ -409,7 +387,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         break;
     case WLAN_CMD_STOP_MAC:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n");
         netif_stop_queue(pDevice->dev);
 
         spin_lock_irq(&pDevice->lock);
@@ -430,7 +408,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
     case WLAN_CMD_START_MAC:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
 
         if (pDevice->bMACSuspend == TRUE) {
             if (pDevice->bRadioOff == TRUE)
@@ -444,7 +422,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
     case WLAN_CMD_SET_HOSTAPD:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n");
 
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
@@ -452,7 +430,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 		};
 		if (sValue.dwValue == 1) {
             if (hostap_set_hostapd(pDevice, 1, 1) == 0){
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
             }
             else {
 			    result = -EFAULT;
@@ -461,19 +439,19 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         }
         else {
             hostap_set_hostapd(pDevice, 0, 1);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n");
         }
 
         break;
 
     case WLAN_CMD_SET_HOSTAPD_STA:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n");
 
         break;
     case WLAN_CMD_SET_802_1X:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n");
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
@@ -481,11 +459,11 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
 		if (sValue.dwValue == 1) {
             pDevice->bEnable8021x = TRUE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
         }
         else {
             pDevice->bEnable8021x = FALSE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
         }
 
         break;
@@ -493,7 +471,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
     case WLAN_CMD_SET_HOST_WEP:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n");
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
@@ -501,29 +479,29 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
 		if (sValue.dwValue == 1) {
             pDevice->bEnableHostWEP = TRUE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
         }
         else {
             pDevice->bEnableHostWEP = FALSE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
         }
 
         break;
 
     case WLAN_CMD_SET_WPA:
-         DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n");
+         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n");
 
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
 		};
 		if (sValue.dwValue == 1) {
-                     DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
+                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
 		   memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, U_ETHER_ADDR_LEN);
 		   pDevice->bWPADEVUp = TRUE;
         }
         else {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
 	   pDevice->bWPADEVUp = FALSE;
         }
 
@@ -531,7 +509,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
     case WLAN_CMD_AP_START:
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
         if (pDevice->bRadioOff == TRUE) {
             CARDbRadioPowerOn(pDevice);
             vMgrTimerInit(pDevice);
@@ -545,10 +523,10 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
 	    if (sStartAPCmd.wBSSType == AP) {
 	        pMgmt->eConfigMode = WMAC_CONFIG_AP;
-	        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n");
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n");
 	    }
 	    else {
-	        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n");
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n");
 			result = -EFAULT;
 			break;
 	    }
@@ -578,11 +556,11 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 
         if (sStartAPCmd.bShareKeyAuth == TRUE){
             pMgmt->bShareKeyAlgorithm = TRUE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
         }
         else {
             pMgmt->bShareKeyAlgorithm = FALSE;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
         }
         memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6);
 
@@ -606,7 +584,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
              pMgmt->abyIBSSSuppRates[3] |= BIT7;
         }
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %x %x %x %x\n",
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %x %x %x %x\n",
                 pMgmt->abyIBSSSuppRates[2],
                 pMgmt->abyIBSSSuppRates[3],
                 pMgmt->abyIBSSSuppRates[4],
@@ -664,7 +642,7 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
     		    pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex;
     		    pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength;
     		    memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
                             pNodeList->sNodeList[jj].abyWepKey[0],
                             pNodeList->sNodeList[jj].abyWepKey[1],
                             pNodeList->sNodeList[jj].abyWepKey[2],
@@ -695,13 +673,13 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
 	    wpa_Result.key_mgmt = 0;
 	    wpa_Result.eap_type = 0;
 	    wpa_Result.authenticated = FALSE;
-		  pDevice->fWPA_Authened = FALSE;
+	      pDevice->fWPA_Authened = FALSE;
         if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) {
             result = -EFAULT;
 			break;
 		}
 
-	if(wpa_Result.authenticated==TRUE) {
+if(wpa_Result.authenticated==TRUE) {
    #ifdef SndEvt_ToAPI
    {
      union iwreq_data      wrqu;
@@ -728,9 +706,8 @@ int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
         break;
 #endif
 
-
     default:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n");
     }
 
     return result;
@@ -748,8 +725,8 @@ vConfigWEPKey (
     int ii;
 
 
-    ZERO_MEMORY(&pDevice->abyWepKey[dwKeyIndex][0], WLAN_WEPMAX_KEYLEN);
-    MEMvCopy(&pDevice->abyWepKey[dwKeyIndex][0], pbyKey, uKeyLength);
+    memset(&pDevice->abyWepKey[dwKeyIndex][0], 0, WLAN_WEPMAX_KEYLEN);
+    memcpy(&pDevice->abyWepKey[dwKeyIndex][0], pbyKey, uKeyLength);
 
     pDevice->bWepKeyAvailable[dwKeyIndex] = TRUE;
     pDevice->auWepKeyLength[dwKeyIndex] = uKeyLength;
diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h
index 9c6816e..07d2283 100644
--- a/drivers/staging/vt6655/ioctl.h
+++ b/drivers/staging/vt6655/ioctl.h
@@ -26,14 +26,10 @@
  *
  */
 
-
 #ifndef __IOCTL_H__
 #define __IOCTL_H__
 
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -44,12 +40,6 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
-
 int private_ioctl(PSDevice pDevice, struct ifreq *rq);
 
 /*
@@ -61,13 +51,6 @@ VOID vConfigWEPKey (
     );
 */
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __IOCTL_H__
 
 
diff --git a/drivers/staging/vt6655/iowpa.h b/drivers/staging/vt6655/iowpa.h
index 451e2ef..33ae054 100644
--- a/drivers/staging/vt6655/iowpa.h
+++ b/drivers/staging/vt6655/iowpa.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 1996, 2003 VIA Networking, Inc. All rights reserved.
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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
@@ -28,7 +29,6 @@
 #ifndef __IOWPA_H__
 #define __IOWPA_H__
 
-
 /*---------------------  Export Definitions -------------------------*/
 
 
diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c
index 4d5a1da..108830f 100644
--- a/drivers/staging/vt6655/iwctl.c
+++ b/drivers/staging/vt6655/iwctl.c
@@ -30,47 +30,21 @@
  *
  */
 
-
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__IOCTL_H__)
 #include "ioctl.h"
-#endif
-#if !defined(__IOCMD_H__)
 #include "iocmd.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__HOSTAP_H__)
 #include "hostap.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__POWER_H__)
 #include "power.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
 
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
-#endif
-#if !defined(__WPACTL_H__)
 #include "wpactl.h"
 #endif
-#endif
 
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif
 extern WORD TxRate_iwconfig;//2008-5-8 <add> by chester
 
 /*---------------------  Static Definitions -------------------------*/
@@ -82,8 +56,6 @@ extern WORD TxRate_iwconfig;//2008-5-8 <add> by chester
 #define SUPPORTED_WIRELESS_EXT                  17
 #endif
 
-#ifdef WIRELESS_EXT
-
 static const long frequency_list[] = {
     2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
     4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
@@ -92,8 +64,6 @@ static const long frequency_list[] = {
     5700, 5745, 5765, 5785, 5805, 5825
 	};
 
-#endif
-
 
 /*---------------------  Static Classes  ----------------------------*/
 
@@ -107,14 +77,11 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 /*---------------------  Export Variables  --------------------------*/
 
-#ifdef WIRELESS_EXT
-
-#if WIRELESS_EXT > 12
-
 struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
 {
 	PSDevice pDevice = netdev_priv(dev);
 	long ldBm;
+
 	pDevice->wstats.status = pDevice->eOPMode;
 	#ifdef Calcu_LinkQual
 	 #if 0
@@ -156,8 +123,6 @@ struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
 	return &pDevice->wstats;
 }
 
-#endif
-
 
 
 /*------------------------------------------------------------------*/
@@ -168,12 +133,11 @@ static int iwctl_commit(struct net_device *dev,
 			      void *wrq,
 			      char *extra)
 {
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
 
 	return 0;
 
 }
-
 /*
  * Wireless Handler : get protocol name
  */
@@ -198,7 +162,6 @@ int iwctl_giwnwid(struct net_device *dev,
 	//return 0;
   return -EOPNOTSUPP;
 }
-#if WIRELESS_EXT > 13
 
 /*
  * Wireless Handler : set scan
@@ -210,24 +173,24 @@ int iwctl_siwscan(struct net_device *dev,
              char *extra)
 {
 	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
-		struct iw_scan_req  *req = (struct iw_scan_req *)extra;
-		 PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	 PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	struct iw_scan_req  *req = (struct iw_scan_req *)extra;
 	BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
 	PWLAN_IE_SSID       pItemSSID=NULL;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN \n");
 
 
 if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
 //send scan event to wpa_Supplicant
   union iwreq_data wrqu;
- printk("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
+ PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
  memset(&wrqu, 0, sizeof(wrqu));
  wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
   return 0;
 }
 
 	spin_lock_irq(&pDevice->lock);
-	   BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+	 BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
 
 //mike add: active scan OR passive scan OR desire_ssid scan
  if(wrq->length == sizeof(struct iw_scan_req)) {
@@ -243,7 +206,7 @@ if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
 	else
 	  pItemSSID->len = req->essid_len;
 	  pMgmt->eScanType = WMAC_SCAN_PASSIVE;
-         printk("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID,
+         PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID,
 		 	                                                                                ((PWLAN_IE_SSID)abyScanSSID)->len);
 	bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
 	spin_unlock_irq(&pDevice->lock);
@@ -259,6 +222,7 @@ if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
  }
 
 	 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+          //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n");
 	bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
 	spin_unlock_irq(&pDevice->lock);
 
@@ -286,12 +250,10 @@ int iwctl_giwscan(struct net_device *dev,
 	char *current_val = NULL;
 	struct iw_event iwe;
 	long ldBm;
-#if WIRELESS_EXT > 14
 	char buf[MAX_WPA_IE_LEN * 2 + 30];
-#endif /* WIRELESS_EXT > 14 */
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
 
     if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
         // In scanning..
@@ -303,18 +265,19 @@ int iwctl_giwscan(struct net_device *dev,
 			break;
         pBSS = &(pMgmt->sBSSList[jj]);
         if (pBSS->bActive) {
+		//ADD 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, pBSS->abyBSSID, WLAN_BSSID_LEN);
-            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);
                  //ADD ssid
 	             memset(&iwe, 0, sizeof(iwe));
                       iwe.cmd = SIOCGIWESSID;
                       pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
                        iwe.u.data.length = pItemSSID->len;
                        iwe.u.data.flags = 1;
-            current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
+                      current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
 		//ADD mode
 		    memset(&iwe, 0, sizeof(iwe));
 		    iwe.cmd = SIOCGIWMODE;
@@ -325,7 +288,7 @@ int iwctl_giwscan(struct net_device *dev,
                 iwe.u.mode = IW_MODE_ADHOC;
 		    }
 	        iwe.len = IW_EV_UINT_LEN;
-            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);
            //ADD frequency
             pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
             pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
@@ -334,9 +297,7 @@ int iwctl_giwscan(struct net_device *dev,
            	iwe.u.freq.m = pBSS->uChannel;
            	iwe.u.freq.e = 0;
            	iwe.u.freq.i = 0;
-            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);
             //2008-0409-04, <Add> by Einsn Liu
 			{
 			int f = (int)pBSS->uChannel - 1;
@@ -344,7 +305,7 @@ int iwctl_giwscan(struct net_device *dev,
 			iwe.u.freq.m = frequency_list[f] * 100000;
 			iwe.u.freq.e = 1;
 			}
-            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
             memset(&iwe, 0, sizeof(iwe));
 	        iwe.cmd = IWEVQUAL;
@@ -384,27 +345,25 @@ int iwctl_giwscan(struct net_device *dev,
 			        break;
 		        // Bit rate given in 500 kb/s units (+ 0x80)
 		        iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
-                current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
-			}
+                           current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+		}
        		for (kk = 0 ; kk < 8 ; kk++) {
 		        if (pExtSuppRates->abyRates[kk] == 0)
 			        break;
 		        // Bit rate given in 500 kb/s units (+ 0x80)
 		        iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
-                current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+                          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;
 
-#if WIRELESS_EXT > 14
             memset(&iwe, 0, sizeof(iwe));
             iwe.cmd = IWEVCUSTOM;
             sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
             iwe.u.data.length = strlen(buf);
-            current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
+             current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
 
-#if WIRELESS_EXT > 17
             if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
                 memset(&iwe, 0, sizeof(iwe));
                 iwe.cmd = IWEVGENIE;
@@ -419,33 +378,6 @@ int iwctl_giwscan(struct net_device *dev,
                 current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE);
             }
 
-#else // WIRELESS_EXT > 17
-            if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
-                u8 *p = buf;
-                memset(&iwe, 0, sizeof(iwe));
-                iwe.cmd = IWEVCUSTOM;
-		        p += sprintf(p, "wpa_ie=");
-		        for (ii = 0; ii < pBSS->wWPALen; ii++) {
-			        p += sprintf(p, "%02x", pBSS->byWPAIE[ii]);
-		        }
-		        iwe.u.data.length = strlen(buf);
-                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
-		    }
-
-
-            if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
-                u8 *p = buf;
-                memset(&iwe, 0, sizeof(iwe));
-                iwe.cmd = IWEVCUSTOM;
-		        p += sprintf(p, "rsn_ie=");
-		        for (ii = 0; ii < pBSS->wRSNLen; ii++) {
-			        p += sprintf(p, "%02x", pBSS->byRSNIE[ii]);
-		        }
-		        iwe.u.data.length = strlen(buf);
-                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
-		    }
-#endif
-#endif
         }
     }// for
 
@@ -454,8 +386,6 @@ int iwctl_giwscan(struct net_device *dev,
 
 }
 
-#endif	/* WIRELESS_EXT > 13 */
-
 
 /*
  * Wireless Handler : set frequence or channel
@@ -469,7 +399,7 @@ int iwctl_siwfreq(struct net_device *dev,
 	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
 	int rc = 0;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
 
 	// If setting by frequency, convert to a channel
 	if((wrq->e == 1) &&
@@ -488,11 +418,11 @@ int iwctl_siwfreq(struct net_device *dev,
 	else {
 		int channel = wrq->m;
 		if((channel < 1) || (channel > 14)) {
-			DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
 			rc = -EINVAL;
 		} else {
 			  // Yes ! We can set it !!!
-              DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
+              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
 			  pDevice->uChannel = channel;
  			 //2007-0207-04,<Add> by EinsnLiu
 			 //Make change effect at once
@@ -515,7 +445,7 @@ int iwctl_giwfreq(struct net_device *dev,
 	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
 
 #ifdef WEXT_USECHANNELS
 	wrq->m = (int)pMgmt->uCurrChannel;
@@ -546,10 +476,10 @@ int iwctl_siwmode(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
     int rc = 0;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
 
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
         return rc;
     }
 
@@ -562,7 +492,7 @@ int iwctl_siwmode(struct net_device *dev,
 		        pDevice->bCommit = TRUE;
    		    }
 		}
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
 		break;
 	case IW_MODE_AUTO:
 	case IW_MODE_INFRA:
@@ -572,7 +502,7 @@ int iwctl_siwmode(struct net_device *dev,
 		        pDevice->bCommit = TRUE;
    		    }
 		}
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
 		break;
 	case IW_MODE_MASTER:
 
@@ -586,7 +516,7 @@ int iwctl_siwmode(struct net_device *dev,
 		        pDevice->bCommit = TRUE;
    		    }
 		}
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
 		break;
 
 	case IW_MODE_REPEAT:
@@ -613,7 +543,7 @@ int iwctl_giwmode(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
 	// If not managed, assume it's ad-hoc
 	switch (pMgmt->eConfigMode) {
 	case WMAC_CONFIG_ESS_STA:
@@ -650,7 +580,7 @@ int iwctl_giwrange(struct net_device *dev,
     BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
 	if (wrq->pointer) {
 		wrq->length = sizeof(struct iw_range);
 		memset(range, 0, sizeof(struct iw_range));
@@ -708,12 +638,9 @@ int iwctl_giwrange(struct net_device *dev,
 	    // 4 keys are allowed
 	    range->max_encoding_tokens = 4;
 
-#if WIRELESS_EXT > 17
 	    range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
 		    IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-#endif
 
-#if WIRELESS_EXT > 9
 		range->min_pmp = 0;
 		range->max_pmp = 1000000;// 1 secs
 		range->min_pmt = 0;
@@ -727,8 +654,6 @@ int iwctl_giwrange(struct net_device *dev,
         range->txpower[0] = 100;
 		range->num_txpower = 1;
 		range->txpower_capa = IW_TXPOW_MWATT;
-#endif // WIRELESS_EXT > 9
-#if WIRELESS_EXT > 10
 		range->we_version_source = SUPPORTED_WIRELESS_EXT;
 		range->we_version_compiled = WIRELESS_EXT;
 		range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
@@ -738,15 +663,12 @@ int iwctl_giwrange(struct net_device *dev,
 		range->max_retry = 65535;
 		range->min_r_time = 1024;
 		range->max_r_time = 65535 * 1024;
-#endif // WIRELESS_EXT > 10
-#if WIRELESS_EXT > 11
 		// Experimental measurements - boundary 11/5.5 Mb/s
 		// Note : with or without the (local->rssi), results
 		//  are somewhat different. - Jean II
 		range->avg_qual.qual = 6;
 		range->avg_qual.level = 176;	// -80 dBm
 		range->avg_qual.noise = 0;
-#endif // WIRELESS_EXT > 11
 	}
 
 
@@ -766,9 +688,9 @@ int iwctl_siwap(struct net_device *dev,
 	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
     int rc = 0;
-        BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
+    BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP \n");
 if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
         // In scanning..
      printk("SIOCSIWAP(??)-->In scanning...\n");
@@ -787,7 +709,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
 	//mike :add
 	 if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
 	     (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
-	      printk("SIOCSIWAP:invalid desired BSSID return!\n");
+	      PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
                return rc;
          }
        //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
@@ -801,10 +723,11 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
                      }
                   }
 	     if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
-                 printk("SIOCSIWAP:ignore for desired AP in hidden mode\n");
+                 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
 	        return rc;
 	     }
        	}
+
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
 		    pDevice->bCommit = TRUE;
    		}
@@ -825,7 +748,7 @@ int iwctl_giwap(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
 
     memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
    //2008-0410,<Modify> by Einsn Liu
@@ -859,7 +782,7 @@ int iwctl_giwaplist(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
 	// Only super-user can see AP list
 
 	if (!capable(CAP_NET_ADMIN)) {
@@ -911,7 +834,7 @@ int iwctl_siwessid(struct net_device *dev,
     BYTE  len;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID \n");
  pDevice->fWPA_Authened = FALSE;
 if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
         // In scanning..
@@ -921,10 +844,9 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
 	// Check if we asked for `any'
 	if(wrq->flags == 0) {
 		// Just send an empty SSID list
-		// Just send an empty SSID list
 		memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
                   memset(pMgmt->abyDesireBSSID, 0xFF,6);
-	    printk("set essid to 'any' \n");
+	    PRINT_K("set essid to 'any' \n");
            #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
              //Unknown desired AP,so here need not associate??
             //if(pDevice->bWPASuppWextEnabled == TRUE)  {
@@ -936,8 +858,9 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
 		memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
         pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
         pItemSSID->byElementID = WLAN_EID_SSID;
+
 		memcpy(pItemSSID->abySSID, extra, wrq->length);
-		         if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
+	 if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
            if(wrq->length>0)
 		pItemSSID->len = wrq->length - 1;
          }
@@ -950,7 +873,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
   	(memcmp(pItemSSID->abySSID,((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,len)==0))
          return 0;
 
-        //mike:need clear desiredBSSID
+     //mike:need clear desiredBSSID
      if(pItemSSID->len==0) {
         memset(pMgmt->abyDesireBSSID, 0xFF,6);
         return 0;
@@ -975,7 +898,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
                                       );
 
             if (pCurr == NULL){
-               printk("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
+               PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
 	      vResetCommandTimer((HANDLE) pDevice);
 	      pMgmt->eScanType = WMAC_SCAN_ACTIVE;
                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
@@ -1002,16 +925,7 @@ if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
   }
 	     #endif
 
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
-/*
-	             #if WIRELESS_EXT < 21
- DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO " SIOCSIWESSID1 \n");
-		pItemSSID->len = wrq->length - 1;
-	     #else
- DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO " SIOCSIWESSID2 \n");
-		pItemSSID->len = wrq->length;
-	     #endif
-	     */
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
 	}
 
     if (pDevice->flags & DEVICE_FLAGS_OPENED) {
@@ -1037,7 +951,7 @@ int iwctl_giwessid(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 	PWLAN_IE_SSID       pItemSSID;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
 
 	// Note : if wrq->u.data.flags != 0, we should
 	// get the relevant SSID from the SSID list...
@@ -1049,11 +963,7 @@ int iwctl_giwessid(struct net_device *dev,
 	extra[pItemSSID->len] = '\0';
 	wrq->length = pItemSSID->len + 1;
 	        //2008-0409-03, <Add> by Einsn Liu
-        #if WIRELESS_EXT < 21
-	wrq->length = pItemSSID->len + 1;
-        #else
         wrq->length = pItemSSID->len;
-        #endif
 	wrq->flags = 1; // active
 
 
@@ -1076,7 +986,7 @@ int iwctl_siwrate(struct net_device *dev,
 	BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
     if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
         rc = -EINVAL;
         return rc;
@@ -1127,12 +1037,11 @@ int iwctl_siwrate(struct net_device *dev,
 	printk("Rate Fix\n");
 		pDevice->bFixRate = TRUE;
         if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
-
-			pDevice->uConnectionRate = 3;
+	    pDevice->uConnectionRate = 3;
         }
         else {
             pDevice->uConnectionRate = brate;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
         }
 
 	}
@@ -1140,7 +1049,7 @@ int iwctl_siwrate(struct net_device *dev,
         pDevice->bFixRate = FALSE;
         pDevice->uConnectionRate = 13;
 	printk("auto rate:connection_rate is 13\n");
-}
+     }
 
 	return rc;
 }
@@ -1159,7 +1068,7 @@ int iwctl_giwrate(struct net_device *dev,
 //Mark the unnecessary sentences.
 //    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
     {
         BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
 	    int brate = 0;
@@ -1223,7 +1132,7 @@ int iwctl_siwrts(struct net_device *dev,
 	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
 	int rc = 0;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
 
 	{
 	    int rthr = wrq->value;
@@ -1250,7 +1159,7 @@ int iwctl_giwrts(struct net_device *dev,
 {
 	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
 	wrq->value = pDevice->wRTSThreshold;
 	wrq->disabled = (wrq->value >= 2312);
 	wrq->fixed = 1;
@@ -1272,7 +1181,7 @@ int iwctl_siwfrag(struct net_device *dev,
     int fthr = wrq->value;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
 
 
     if (wrq->disabled)
@@ -1298,7 +1207,7 @@ int iwctl_giwfrag(struct net_device *dev,
 {
     PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
 	wrq->value = pDevice->wFragmentationThreshold;
 	wrq->disabled = (wrq->value >= 2312);
 	wrq->fixed = 1;
@@ -1320,7 +1229,7 @@ int iwctl_siwretry(struct net_device *dev,
     int rc = 0;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
 
 	if (wrq->disabled) {
 		rc = -EINVAL;
@@ -1355,7 +1264,7 @@ int iwctl_giwretry(struct net_device *dev,
              char *extra)
 {
     PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
 	wrq->disabled = 0;      // Can't be disabled
 
 	// Note : by default, display the min retry number
@@ -1402,7 +1311,7 @@ int iwctl_siwencode(struct net_device *dev,
 
 	PSKeyTable pkeytab;
 
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
 
 if((wrq->flags & IW_ENCODE_DISABLED)==0){
 	//Not disable encryption
@@ -1429,13 +1338,13 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 	if(wrq->length>0){//have key
 
         if (wrq->length ==  WLAN_WEP232_KEYLEN) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
         }
         else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
         }
         else if (wrq->length == WLAN_WEP40_KEYLEN) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
         }else {//no support length
 		rc = -EINVAL;
         return rc;
@@ -1443,9 +1352,9 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
         memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
         memcpy(pDevice->abyKey, extra, wrq->length);
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
         for (ii = 0; ii < wrq->length; ii++) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
         }
 
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
@@ -1475,10 +1384,10 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 		rc = -EINVAL;
         	return rc;
 	}
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n");
 	pkeytab=&(pDevice->sKey.KeyTable[MAX_KEY_TABLE-1]);
 	if(pkeytab->GroupKey[(BYTE)dwKeyIndex].uKeyLength==0){
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n");
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n");
 		rc = -EINVAL;
       	  	return rc;
 		}
@@ -1488,7 +1397,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 	}
 
 }else {//disable the key
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
 	if(pDevice->bEncryptionEnable==FALSE)
 		return 0;
 	pMgmt->bShareKeyAlgorithm = FALSE;
@@ -1504,7 +1413,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 //End Modify,Einsn
 
 /*
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
+     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
 
 	// Check the size of the key
 	if (wrq->length > WLAN_WEP232_KEYLEN) {
@@ -1524,20 +1433,20 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 	if (wrq->length > 0) {
 
         if (wrq->length ==  WLAN_WEP232_KEYLEN) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
         }
         else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
         }
         else if (wrq->length == WLAN_WEP40_KEYLEN) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
         }
         memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
         memcpy(pDevice->abyKey, extra, wrq->length);
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
         for (ii = 0; ii < wrq->length; ii++) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
         }
 
         if (pDevice->flags & DEVICE_FLAGS_OPENED) {
@@ -1571,7 +1480,7 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 	// Read the flags
 	if(wrq->flags & IW_ENCODE_DISABLED){
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
 		pMgmt->bShareKeyAlgorithm = FALSE;
         pDevice->bEncryptionEnable = FALSE;
         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
@@ -1585,11 +1494,11 @@ if((wrq->flags & IW_ENCODE_DISABLED)==0){
 */
 
 	if(wrq->flags & IW_ENCODE_RESTRICTED) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
 		pMgmt->bShareKeyAlgorithm = TRUE;
 	}
 	if(wrq->flags & IW_ENCODE_OPEN) {
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
 		pMgmt->bShareKeyAlgorithm = FALSE;
 	}
 	return rc;
@@ -1611,7 +1520,7 @@ int iwctl_giwencode(struct net_device *dev,
 	UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
 	PSKeyItem   pKey = NULL;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
 //2007-0207-06,<Add> by EinsnLiu
 //the key index in iwconfig is 1-4 when our driver is 0-3
 //so it can't be used directly.
@@ -1680,7 +1589,7 @@ int iwctl_giwencode(struct net_device *dev,
 	UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
 	PSKeyItem	pKey = NULL;
 
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
 
 	if (index > WLAN_WEP_NKEYS) {
 		return	-EINVAL;
@@ -1726,6 +1635,7 @@ int iwctl_giwencode(struct net_device *dev,
 	return 0;
 }
 
+
 /*
  * Wireless Handler : set power mode
  */
@@ -1738,7 +1648,7 @@ int iwctl_siwpower(struct net_device *dev,
     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
     int rc = 0;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
 
     if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
 		 rc = -EINVAL;
@@ -1760,14 +1670,14 @@ int iwctl_siwpower(struct net_device *dev,
 	}
 	switch (wrq->flags & IW_POWER_MODE) {
 	case IW_POWER_UNICAST_R:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
 		rc = -EINVAL;
 		break;
 	case IW_POWER_ALL_R:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
 		rc = -EINVAL;
 	case IW_POWER_ON:
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
 		break;
 	default:
 		rc = -EINVAL;
@@ -1789,7 +1699,7 @@ int iwctl_giwpower(struct net_device *dev,
     int mode = pDevice->ePSMode;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
 
 
 	if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
@@ -1819,7 +1729,7 @@ int iwctl_giwsens(struct net_device *dev,
     PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
     long ldBm;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
     if (pDevice->bLinkPass == TRUE) {
         RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
 	    wrq->value = ldBm;
@@ -1848,25 +1758,24 @@ int iwctl_siwauth(struct net_device *dev,
 	static int wpa_version=0;  //must be static to save the last value,einsn liu
 	static int pairwise=0;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
 	switch (wrq->flags & IW_AUTH_INDEX) {
 	case IW_AUTH_WPA_VERSION:
 		wpa_version = wrq->value;
 		if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
-		       printk("iwctl_siwauth:set WPADEV to disable at 1??????\n");
+		       PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
 			//pDevice->bWPADevEnable = FALSE;
 		}
 		else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
-                          printk("iwctl_siwauth:set WPADEV to WPA1******\n");
+                          PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
 		}
 		else {
-                          printk("iwctl_siwauth:set WPADEV to WPA2******\n");
+                          PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
 		}
 		//pDevice->bWPASuppWextEnabled =TRUE;
 		break;
 	case IW_AUTH_CIPHER_PAIRWISE:
 		pairwise = wrq->value;
-
 		if(pairwise == IW_AUTH_CIPHER_CCMP){
 			pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
 		}else if(pairwise == IW_AUTH_CIPHER_TKIP){
@@ -1940,13 +1849,13 @@ int iwctl_siwauth(struct net_device *dev,
 		break;
 	}
 /*
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
-	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"TRUE":"FALSE");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADevEnable = %s\n",pDevice->bWPADevEnable?"TRUE":"FALSE");
 */
    return ret;
 }
@@ -2031,10 +1940,10 @@ int iwctl_siwencodeext(struct net_device *dev,
 //original member
     wpa_alg alg_name;
     u8  addr[6];
-    int key_idx, set_tx;
+    int key_idx, set_tx=0;
     u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
     u8 key[64];
-    size_t seq_len,key_len=0;
+    size_t seq_len=0,key_len=0;
 //
    // int ii;
     u8 *buf;
@@ -2042,7 +1951,7 @@ int iwctl_siwencodeext(struct net_device *dev,
     u8 key_array[64];
     int ret=0;
 
-printk("SIOCSIWENCODEEXT...... \n");
+PRINT_K("SIOCSIWENCODEEXT...... \n");
 
 blen = sizeof(*param);
 buf = kmalloc((int)blen, (int)GFP_KERNEL);
@@ -2066,7 +1975,7 @@ switch (ext->alg) {
                   alg_name = WPA_ALG_CCMP;
 		break;
     default:
-		printk("Unknown alg = %d\n",ext->alg);
+		PRINT_K("Unknown alg = %d\n",ext->alg);
 		ret= -ENOMEM;
 		goto error;
 		}
@@ -2109,7 +2018,6 @@ param->u.wpa_key.seq = (u8 *)seq;
 param->u.wpa_key.seq_len = seq_len;
 
 #if 0
-int ii;
 printk("param->u.wpa_key.alg_name =%d\n",param->u.wpa_key.alg_name);
 printk("param->addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
 	      param->addr[0],param->addr[1],param->addr[2],
@@ -2217,8 +2125,6 @@ int iwctl_siwmlme(struct net_device *dev,
  */
 
 
-#if WIRELESS_EXT > 12
-
 /*
 static const iw_handler		iwctl_handler[] =
 {
@@ -2246,13 +2152,8 @@ static const iw_handler		iwctl_handler[] =
 	(iw_handler) iwctl_giwap,		    // SIOCGIWAP
 	(iw_handler) NULL,				    // -- hole -- 0x16
 	(iw_handler) iwctl_giwaplist,       // SIOCGIWAPLIST
-#if WIRELESS_EXT > 13
 	(iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
 	(iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
-#else
-	(iw_handler) NULL,
-	(iw_handler) NULL,
-#endif
 	(iw_handler) iwctl_siwessid,		// SIOCSIWESSID
 	(iw_handler) iwctl_giwessid,		// SIOCGIWESSID
 	(iw_handler) NULL,		// SIOCSIWNICKN
@@ -2273,7 +2174,6 @@ static const iw_handler		iwctl_handler[] =
 	(iw_handler) iwctl_giwencode,		// SIOCGIWENCODE
 	(iw_handler) iwctl_siwpower,		// SIOCSIWPOWER
 	(iw_handler) iwctl_giwpower,		// SIOCGIWPOWER
-#if WIRELESS_EXT > 17
 	(iw_handler) NULL,			// -- hole --
 	(iw_handler) NULL,			// -- hole --
 	(iw_handler) iwctl_siwgenie,    // SIOCSIWGENIE
@@ -2284,7 +2184,6 @@ static const iw_handler		iwctl_handler[] =
 	(iw_handler) iwctl_giwencodeext,		// SIOCGIWENCODEEXT
 	(iw_handler) NULL,				// SIOCSIWPMKSA
 	(iw_handler) NULL,				// -- hole --
-#endif // WIRELESS_EXT > 17
 
 };
 */
@@ -2315,13 +2214,8 @@ static const iw_handler		iwctl_handler[] =
 	(iw_handler) NULL,		    // SIOCGIWAP
 	(iw_handler) NULL,				    // -- hole -- 0x16
 	(iw_handler) NULL,       // SIOCGIWAPLIST
-#if WIRELESS_EXT > 13
 	(iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
 	(iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
-#else
-	(iw_handler) NULL,
-	(iw_handler) NULL,
-#endif
 	(iw_handler) NULL,		// SIOCSIWESSID
 	(iw_handler) NULL,		// SIOCGIWESSID
 	(iw_handler) NULL,		// SIOCSIWNICKN
@@ -2344,7 +2238,6 @@ static const iw_handler		iwctl_handler[] =
 	(iw_handler) NULL,		// SIOCGIWPOWER
 
 //2008-0409-07, <Add> by Einsn Liu
-#if WIRELESS_EXT > 17
 	(iw_handler) NULL,			// -- hole --
 	(iw_handler) NULL,			// -- hole --
 	(iw_handler) NULL,    // SIOCSIWGENIE
@@ -2355,7 +2248,6 @@ static const iw_handler		iwctl_handler[] =
 	(iw_handler) NULL,		// SIOCGIWENCODEEXT
 	(iw_handler) NULL,				// SIOCSIWPMKSA
 	(iw_handler) NULL,				// -- hole --
-#endif // WIRELESS_EXT > 17
 };
 
 
@@ -2375,9 +2267,7 @@ struct iw_priv_args iwctl_private_args[] = {
 
 const struct iw_handler_def	iwctl_handler_def =
 {
-#if WIRELESS_EXT > 16
 	.get_wireless_stats = &iwctl_get_wireless_stats,
-#endif
 	.num_standard	= sizeof(iwctl_handler)/sizeof(iw_handler),
 //	.num_private	= sizeof(iwctl_private_handler)/sizeof(iw_handler),
 //	.num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args),
@@ -2389,9 +2279,3 @@ const struct iw_handler_def	iwctl_handler_def =
 	.private	= NULL,
 	.private_args	= NULL,
 };
-
-
-#endif // WIRELESS_EXT > 12
-
-
-#endif // WIRELESS_EXT
diff --git a/drivers/staging/vt6655/iwctl.h b/drivers/staging/vt6655/iwctl.h
index 07554e1..3096de0 100644
--- a/drivers/staging/vt6655/iwctl.h
+++ b/drivers/staging/vt6655/iwctl.h
@@ -26,14 +26,10 @@
  *
  */
 
-
 #ifndef __IWCTL_H__
 #define __IWCTL_H__
 
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -44,93 +40,6 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
-
-#if WIRELESS_EXT < 18
-
-
-#define SIOCSIWMLME	        0x8B16
-#define SIOCSIWGENIE	    0x8B30
-
-// WPA : Authentication mode parameters
-#define SIOCSIWAUTH	        0x8B32
-#define SIOCGIWAUTH	        0x8B33
-
-// WPA : Extended version of encoding configuration
-#define SIOCSIWENCODEEXT    0x8B34
-#define SIOCGIWENCODEEXT    0x8B35
-
-#define IW_AUTH_WPA_VERSION		0
-#define IW_AUTH_CIPHER_PAIRWISE		1
-#define IW_AUTH_CIPHER_GROUP		2
-#define IW_AUTH_KEY_MGMT		3
-#define IW_AUTH_TKIP_COUNTERMEASURES	4
-#define IW_AUTH_DROP_UNENCRYPTED	5
-#define IW_AUTH_80211_AUTH_ALG		6
-#define IW_AUTH_WPA_ENABLED		7
-#define IW_AUTH_RX_UNENCRYPTED_EAPOL	8
-#define IW_AUTH_ROAMING_CONTROL		9
-#define IW_AUTH_PRIVACY_INVOKED		10
-
-#define IW_AUTH_WPA_VERSION_DISABLED	0x00000001
-#define IW_AUTH_WPA_VERSION_WPA		0x00000002
-#define IW_AUTH_WPA_VERSION_WPA2	0x00000004
-
-#define IW_AUTH_CIPHER_NONE	    0x00000001
-#define IW_AUTH_CIPHER_WEP40	0x00000002
-#define IW_AUTH_CIPHER_TKIP	    0x00000004
-#define IW_AUTH_CIPHER_CCMP	    0x00000008
-#define IW_AUTH_CIPHER_WEP104	0x00000010
-
-#define IW_AUTH_KEY_MGMT_802_1X	1
-#define IW_AUTH_KEY_MGMT_PSK	2
-
-#define IW_AUTH_ALG_OPEN_SYSTEM	0x00000001
-#define IW_AUTH_ALG_SHARED_KEY	0x00000002
-#define IW_AUTH_ALG_LEAP	0x00000004
-
-#define IW_AUTH_ROAMING_ENABLE	0
-#define IW_AUTH_ROAMING_DISABLE	1
-
-#define IW_ENCODE_SEQ_MAX_SIZE	8
-
-#define IW_ENCODE_ALG_NONE	0
-#define IW_ENCODE_ALG_WEP	1
-#define IW_ENCODE_ALG_TKIP	2
-#define IW_ENCODE_ALG_CCMP	3
-
-
-struct	iw_encode_ext
-{
-	__u32		ext_flags; // IW_ENCODE_EXT_*
-	__u8		tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; // LSB first
-	__u8		rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; // LSB first
-	struct sockaddr	addr; // ff:ff:ff:ff:ff:ff for broadcast/multicast
-			              // (group) keys or unicast address for
-			              // individual keys
-	__u16		alg; // IW_ENCODE_ALG_*
-	__u16		key_len;
-	__u8		key[0];
-};
-
-
-struct	iw_mlme
-{
-	__u16		cmd; /* IW_MLME_* */
-	__u16		reason_code;
-	struct sockaddr	addr;
-};
-
-#endif // WIRELESS_EXT < 18
-
-
-
-#ifdef WIRELESS_EXT
-
 struct iw_statistics *iwctl_get_wireless_stats (struct net_device *dev);
 
 
@@ -308,23 +217,11 @@ int iwctl_siwmlme(struct net_device *dev,
 			struct iw_point *wrq,
 			char *extra);
 #endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//End Add -- //2008-0409-07, <Add> by Einsn Liu
 
 
-#endif
-
-#if WIRELESS_EXT > 12
 extern const struct iw_handler_def	iwctl_handler_def;
 extern const struct iw_priv_args	iwctl_private_args;
-#else
-struct iw_request_info {};
-#endif	//WIRELESS_EXT > 12
-
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
 
 #endif // __IWCTL_H__
 
diff --git a/drivers/staging/vt6655/kcompat.h b/drivers/staging/vt6655/kcompat.h
index 652c2c7..2cf634c 100644
--- a/drivers/staging/vt6655/kcompat.h
+++ b/drivers/staging/vt6655/kcompat.h
@@ -1,6 +1,5 @@
 /*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
- * All rights reserved.
+ * Copyright (c) 1996, 2003 VIA Networking, 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
@@ -26,59 +25,15 @@
  * Date: Apr 8, 2002
  *
  */
+
 #ifndef _KCOMPAT_H
 #define _KCOMPAT_H
 
 #include <linux/version.h>
 
-#ifndef __init
-#define __init
-#endif
-
-#ifndef __exit
-#define __exit
-#endif
-
-#ifndef __devexit
-#define __devexit
-#endif
-
-#ifndef __devinitdata
-#define __devinitdata
-#endif
-
-#ifndef MODULE_LICENSE
-#define MODULE_LICENSE(license)
-#endif
-
-#ifndef MOD_INC_USE_COUNT
-#define MOD_INC_USE_COUNT do {} while (0)
-#endif
-
-#ifndef MOD_DEC_USE_COUNT
-#define MOD_DEC_USE_COUNT do {} while (0)
-#endif
-
 #ifndef HAVE_NETDEV_PRIV
 #define netdev_priv(dev) (dev->priv)
 #endif
 
-#ifndef IRQ_RETVAL
-typedef void irqreturn_t;
-
-#ifdef PRIVATE_OBJ
-#define IRQ_RETVAL(x)   (int)x
-#else
-#define IRQ_RETVAL(x)
-#endif
-
-#endif
-
-
-#ifndef MODULE_LICESEN
-#define MODULE_LICESEN(x)
-#endif
-
-
 #endif
 
diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c
index 168ebd3..a4d2184 100644
--- a/drivers/staging/vt6655/key.c
+++ b/drivers/staging/vt6655/key.c
@@ -36,23 +36,9 @@
  *
  */
 
-
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__KEY_H__)
 #include "key.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -85,6 +71,7 @@ s_vCheckKeyTableValid (PSKeyManagement pTable, DWORD_PTR dwIoBase)
             (pTable->KeyTable[i].GroupKey[2].bKeyValid == FALSE) &&
             (pTable->KeyTable[i].GroupKey[3].bKeyValid == FALSE)
             ) {
+
             pTable->KeyTable[i].bInUse = FALSE;
             pTable->KeyTable[i].wKeyCtl = 0;
             pTable->KeyTable[i].bSoftWEP = FALSE;
@@ -153,7 +140,7 @@ BOOL KeybGetKey (
 {
     int i;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey() \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey() \n");
 
     *pKey = NULL;
     for (i=0;i<MAX_KEY_TABLE;i++) {
@@ -219,7 +206,7 @@ BOOL KeybSetKey (
     PSKeyItem   pKey;
     UINT        uKeyIdx;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
 
     j = (MAX_KEY_TABLE-1);
     for (i=0;i<(MAX_KEY_TABLE-1);i++) {
@@ -245,7 +232,7 @@ BOOL KeybSetKey (
                 if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
                     // Group transmit key
                     pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
                 }
                 pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
                 pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
@@ -258,7 +245,7 @@ BOOL KeybSetKey (
             pKey->uKeyLength = uKeyLength;
             pKey->dwKeyIndex = dwKeyIndex;
             pKey->byCipherSuite = byKeyDecMode;
-            MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+            memcpy(pKey->abyKey, pbyKey, uKeyLength);
             if (byKeyDecMode == KEY_CTL_WEP) {
                 if (uKeyLength == WLAN_WEP40_KEYLEN)
                     pKey->abyKey[15] &= 0x7F;
@@ -269,32 +256,32 @@ BOOL KeybSetKey (
 
             if ((dwKeyIndex & USE_KEYRSC) == 0) {
                 // RSC set by NIC
-                ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+		    memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
             }
             else {
-                MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+                memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
             }
             pKey->dwTSC47_16 = 0;
             pKey->wTSC15_0 = 0;
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
-            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
             for (ii = 0; ii < pKey->uKeyLength; ii++) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
             }
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
 
             return (TRUE);
         }
     }
     if (j < (MAX_KEY_TABLE-1)) {
-        MEMvCopy(pTable->KeyTable[j].abyBSSID,pbyBSSID,U_ETHER_ADDR_LEN);
+        memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,U_ETHER_ADDR_LEN);
         pTable->KeyTable[j].bInUse = TRUE;
         if ((dwKeyIndex & PAIRWISE_KEY) != 0)  {
             // Pairwise key
@@ -310,7 +297,7 @@ BOOL KeybSetKey (
             if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
                 // Group transmit key
                 pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
             }
             pTable->KeyTable[j].wKeyCtl &= 0xFF0F;          // clear group key control filed
             pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
@@ -323,7 +310,7 @@ BOOL KeybSetKey (
         pKey->uKeyLength = uKeyLength;
         pKey->dwKeyIndex = dwKeyIndex;
         pKey->byCipherSuite = byKeyDecMode;
-        MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+        memcpy(pKey->abyKey, pbyKey, uKeyLength);
         if (byKeyDecMode == KEY_CTL_WEP) {
             if (uKeyLength == WLAN_WEP40_KEYLEN)
                 pKey->abyKey[15] &= 0x7F;
@@ -334,26 +321,26 @@ BOOL KeybSetKey (
 
         if ((dwKeyIndex & USE_KEYRSC) == 0) {
             // RSC set by NIC
-            ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+		memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
         }
         else {
-            MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+            memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
         }
         pKey->dwTSC47_16 = 0;
         pKey->wTSC15_0 = 0;
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
         for (ii = 0; ii < pKey->uKeyLength; ii++) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
 
         return (TRUE);
     }
@@ -549,51 +536,51 @@ BOOL KeybGetTransmitKey (
                 if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
                     *pKey = &(pTable->KeyTable[i].PairwiseKey);
 
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
                     for (ii = 0; ii < 6; ii++) {
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
                     }
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 
 
                     return (TRUE);
                 }
                 else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == FALSE\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == FALSE\n");
                     return (FALSE);
                 }
             } // End of Type == PAIRWISE
             else {
                 if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
                     return FALSE;
                 }
                 if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == TRUE) {
                     *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
 
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
                         for (ii = 0; ii < 6; ii++) {
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
                         }
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
 
                     return (TRUE);
                 }
                 else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == FALSE\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == FALSE\n");
                     return (FALSE);
                 }
             } // End of Type = GROUP
         } // BSSID match
     }
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
     for (ii = 0; ii < 6; ii++) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
     }
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
     return (FALSE);
 }
 
@@ -659,7 +646,7 @@ BOOL KeybSetDefaultKey (
     PSKeyItem   pKey;
     UINT        uKeyIdx;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
 
 
     if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
@@ -677,7 +664,7 @@ BOOL KeybSetDefaultKey (
     if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
         // Group transmit key
         pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1);
 
     }
     pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00;          // clear all key control filed
@@ -699,7 +686,7 @@ BOOL KeybSetDefaultKey (
     pKey->uKeyLength = uKeyLength;
     pKey->dwKeyIndex = dwKeyIndex;
     pKey->byCipherSuite = byKeyDecMode;
-    MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+    memcpy(pKey->abyKey, pbyKey, uKeyLength);
     if (byKeyDecMode == KEY_CTL_WEP) {
         if (uKeyLength == WLAN_WEP40_KEYLEN)
             pKey->abyKey[15] &= 0x7F;
@@ -710,26 +697,26 @@ BOOL KeybSetDefaultKey (
 
     if ((dwKeyIndex & USE_KEYRSC) == 0) {
         // RSC set by NIC
-        ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+	    memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
     } else {
-        MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+        memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
     }
     pKey->dwTSC47_16 = 0;
     pKey->wTSC15_0 = 0;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
     for (ii = 0; ii < pKey->uKeyLength; ii++) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
     }
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
 
     return (TRUE);
 }
@@ -767,7 +754,7 @@ BOOL KeybSetAllGroupKey (
     PSKeyItem   pKey;
     UINT        uKeyIdx;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
 
 
     if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
@@ -784,7 +771,7 @@ BOOL KeybSetAllGroupKey (
             if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
                 // Group transmit key
                 pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
 
             }
             pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
@@ -798,7 +785,7 @@ BOOL KeybSetAllGroupKey (
             pKey->uKeyLength = uKeyLength;
             pKey->dwKeyIndex = dwKeyIndex;
             pKey->byCipherSuite = byKeyDecMode;
-            MEMvCopy(pKey->abyKey, pbyKey, uKeyLength);
+            memcpy(pKey->abyKey, pbyKey, uKeyLength);
             if (byKeyDecMode == KEY_CTL_WEP) {
                 if (uKeyLength == WLAN_WEP40_KEYLEN)
                     pKey->abyKey[15] &= 0x7F;
@@ -809,22 +796,22 @@ BOOL KeybSetAllGroupKey (
 
             if ((dwKeyIndex & USE_KEYRSC) == 0) {
                 // RSC set by NIC
-                ZERO_MEMORY(&(pKey->KeyRSC), sizeof(QWORD));
+		    memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
             }
             else {
-                MEMvCopy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+                memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
             }
             pKey->dwTSC47_16 = 0;
             pKey->wTSC15_0 = 0;
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
             for (ii = 0; ii < pKey->uKeyLength; ii++) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
             }
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 
             //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
             //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h
index 9c7d335..ba797c7 100644
--- a/drivers/staging/vt6655/key.h
+++ b/drivers/staging/vt6655/key.h
@@ -27,21 +27,12 @@
  *
  */
 
-
 #ifndef __KEY_H__
 #define __KEY_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
 
 /*---------------------  Export Definitions -------------------------*/
 #define MAX_GROUP_KEY       4
@@ -76,7 +67,7 @@ typedef struct tagSKeyItem
     BYTE        byReserved0;
     DWORD       dwKeyIndex;
     PVOID       pvKeyTable;
-} SKeyItem, DEF* PSKeyItem; //64
+} SKeyItem, *PSKeyItem; //64
 
 typedef struct tagSKeyTable
 {
@@ -93,12 +84,12 @@ typedef struct tagSKeyTable
     WORD        wKeyCtl;      // for address of wKeyCtl at align 4
 
     BYTE        byReserved1[6];
-} SKeyTable, DEF* PSKeyTable; //348
+} SKeyTable, *PSKeyTable; //348
 
 typedef struct tagSKeyManagement
 {
     SKeyTable   KeyTable[MAX_KEY_TABLE];
-} SKeyManagement, DEF* PSKeyManagement;
+} SKeyManagement, * PSKeyManagement;
 
 /*---------------------  Export Types  ------------------------------*/
 
@@ -109,9 +100,6 @@ typedef struct tagSKeyManagement
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 VOID KeyvInitTable(PSKeyManagement pTable, DWORD_PTR dwIoBase);
 
@@ -192,11 +180,5 @@ BOOL KeybSetAllGroupKey (
     BYTE            byLocalID
     );
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-
-#endif /* __cplusplus */
-
-
 #endif // __KEY_H__
 
diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c
index 0283ed3..cdd7cd5 100644
--- a/drivers/staging/vt6655/mac.c
+++ b/drivers/staging/vt6655/mac.c
@@ -16,6 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: mac.c
  *
  * Purpose:  MAC routines
@@ -67,19 +68,9 @@
  *
  */
 
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-
 
 WORD TxRate_iwconfig;//2008-5-8 <add> by chester
 /*---------------------  Static Definitions -------------------------*/
@@ -95,6 +86,10 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 /*---------------------  Export Functions  --------------------------*/
 
+
+
+
+
 /*
  * Description:
  *      Read All MAC Registers to buffer
@@ -150,7 +145,7 @@ BOOL MACbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
     BYTE byData;
 
     VNSvInPortB(dwIoBase + byRegOfs, &byData);
-    return BITbIsAllBitsOn(byData, byTestBits);
+    return (byData & byTestBits) == byTestBits;
 }
 
 /*
@@ -173,7 +168,7 @@ BOOL MACbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byRegOfs, BYTE byTestBits)
     BYTE byData;
 
     VNSvInPortB(dwIoBase + byRegOfs, &byData);
-    return BITbIsAllBitsOff(byData, byTestBits);
+    return !(byData & byTestBits);
 }
 
 /*
@@ -569,7 +564,7 @@ BOOL MACbIsInLoopbackMode (DWORD_PTR dwIoBase)
     BYTE byOrgValue;
 
     VNSvInPortB(dwIoBase + MAC_REG_TEST, &byOrgValue);
-    if (BITbIsAnyBitsOn(byOrgValue, (TEST_LBINT | TEST_LBEXT)))
+    if (byOrgValue & (TEST_LBINT | TEST_LBEXT))
         return TRUE;
     return FALSE;
 }
@@ -596,7 +591,7 @@ void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
     // if only in DIRECTED mode, multicast-address will set to zero,
     // but if other mode exist (e.g. PROMISCUOUS), multicast-address
     // will be open
-    if (BITbIsBitOn(wFilterType, PKT_TYPE_DIRECTED)) {
+    if (wFilterType & PKT_TYPE_DIRECTED) {
         // set multicast address to accept none
         MACvSelectPage1(dwIoBase);
         VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0L);
@@ -604,7 +599,7 @@ void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
         MACvSelectPage0(dwIoBase);
     }
 
-    if (BITbIsAnyBitsOn(wFilterType, PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) {
+    if (wFilterType & (PKT_TYPE_PROMISCUOUS | PKT_TYPE_ALL_MULTICAST)) {
         // set multicast address to accept all
         MACvSelectPage1(dwIoBase);
         VNSvOutPortD(dwIoBase + MAC_REG_MAR0, 0xFFFFFFFFL);
@@ -612,20 +607,20 @@ void MACvSetPacketFilter (DWORD_PTR dwIoBase, WORD wFilterType)
         MACvSelectPage0(dwIoBase);
     }
 
-    if (BITbIsBitOn(wFilterType, PKT_TYPE_PROMISCUOUS)) {
+    if (wFilterType & PKT_TYPE_PROMISCUOUS) {
 
         byNewRCR |= (RCR_RXALLTYPE | RCR_UNICAST | RCR_MULTICAST | RCR_BROADCAST);
 
         byNewRCR &= ~RCR_BSSID;
     }
 
-    if (BITbIsAnyBitsOn(wFilterType, (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST)))
+    if (wFilterType & (PKT_TYPE_ALL_MULTICAST | PKT_TYPE_MULTICAST))
         byNewRCR |= RCR_MULTICAST;
 
-    if (BITbIsBitOn(wFilterType, PKT_TYPE_BROADCAST))
+    if (wFilterType & PKT_TYPE_BROADCAST)
         byNewRCR |= RCR_BROADCAST;
 
-    if (BITbIsBitOn(wFilterType, PKT_TYPE_ERROR_CRC))
+    if (wFilterType & PKT_TYPE_ERROR_CRC)
         byNewRCR |= RCR_ERRCRC;
 
     VNSvInPortB(dwIoBase + MAC_REG_RCR,  &byOldRCR);
@@ -789,7 +784,7 @@ BOOL MACbSoftwareReset (DWORD_PTR dwIoBase)
 
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
-        if (BITbIsBitOff(byData, HOSTCR_SOFTRST))
+        if ( !(byData & HOSTCR_SOFTRST))
             break;
     }
     if (ww == W_MAX_TIMEOUT)
@@ -857,22 +852,22 @@ BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
     VNSvOutPortD(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_CLRRUN);
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL0, &dwData);
-        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+        if (!(dwData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x10);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x10)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x10)\n");
         return(FALSE);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_RXDMACTL1, &dwData);
-        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+        if ( !(dwData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x11);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x11)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x11)\n");
         return(FALSE);
     }
 
@@ -881,12 +876,12 @@ BOOL MACbSafeRxOff (DWORD_PTR dwIoBase)
     // W_MAX_TIMEOUT is the timeout period
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
-        if (BITbIsAllBitsOff(byData, HOSTCR_RXONST))
+        if ( !(byData & HOSTCR_RXONST))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x12);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x12)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x12)\n");
         return(FALSE);
     }
     return TRUE;
@@ -920,22 +915,22 @@ BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
 
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_TXDMACTL0, &dwData);
-        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+        if ( !(dwData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x20);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x20)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x20)\n");
         return(FALSE);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_AC0DMACTL, &dwData);
-        if (BITbIsAllBitsOff(dwData, DMACTL_RUN))
+        if ( !(dwData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x21);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x21)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x21)\n");
         return(FALSE);
     }
 
@@ -945,12 +940,12 @@ BOOL MACbSafeTxOff (DWORD_PTR dwIoBase)
     // W_MAX_TIMEOUT is the timeout period
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_HOSTCR, &byData);
-        if (BITbIsAllBitsOff(byData, HOSTCR_TXONST))
+        if ( !(byData & HOSTCR_TXONST))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x24);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x24)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x24)\n");
         return(FALSE);
     }
     return TRUE;
@@ -975,13 +970,13 @@ BOOL MACbSafeStop (DWORD_PTR dwIoBase)
 
     if (MACbSafeRxOff(dwIoBase) == FALSE) {
         DBG_PORT80(0xA1);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeRxOff == FALSE)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeRxOff == FALSE)\n");
         MACbSafeSoftwareReset(dwIoBase);
         return FALSE;
     }
     if (MACbSafeTxOff(dwIoBase) == FALSE) {
         DBG_PORT80(0xA2);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeTxOff == FALSE)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" MACbSafeTxOff == FALSE)\n");
         MACbSafeSoftwareReset(dwIoBase);
         return FALSE;
     }
@@ -1053,7 +1048,7 @@ void MACvInitialize (DWORD_PTR dwIoBase)
     //while (TRUE) {
     //    U8 u8Data;
     //    VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &u8Data);
-    //    if (BITbIsBitOff(u8Data, I2MCSR_AUTOLD))
+    //    if ( !(u8Data & I2MCSR_AUTOLD))
     //        break;
     //}
 
@@ -1091,19 +1086,19 @@ BYTE    byData;
 BYTE    byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byOrgDMACtl);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0+2, DMACTL_RUN);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL0, &byData);
-        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+        if ( !(byData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x13);
     }
     VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR0, dwCurrDescAddr);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL0, DMACTL_RUN);
     }
 }
@@ -1129,19 +1124,19 @@ BYTE    byData;
 BYTE    byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byOrgDMACtl);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1+2, DMACTL_RUN);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_RXDMACTL1, &byData);
-        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+        if ( !(byData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x14);
     }
     VNSvOutPortD(dwIoBase + MAC_REG_RXDMAPTR1, dwCurrDescAddr);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_RXDMACTL1, DMACTL_RUN);
     }
 }
@@ -1167,19 +1162,19 @@ BYTE    byData;
 BYTE    byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byOrgDMACtl);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
-        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+        if ( !(byData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x25);
     }
     VNSvOutPortD(dwIoBase + MAC_REG_TXDMAPTR0, dwCurrDescAddr);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0, DMACTL_RUN);
     }
 }
@@ -1206,20 +1201,20 @@ BYTE    byData;
 BYTE    byOrgDMACtl;
 
     VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byOrgDMACtl);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
     }
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
-        if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+        if (!(byData & DMACTL_RUN))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x26);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x26)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x26)\n");
     }
     VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr);
-    if (BITbIsAllBitsOn(byOrgDMACtl, DMACTL_RUN)) {
+    if (byOrgDMACtl & DMACTL_RUN) {
         VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL, DMACTL_RUN);
     }
 }
@@ -1261,7 +1256,7 @@ UINT uu,ii;
         for (uu = 0; uu < uDelay; uu++) {
             VNSvInPortB(dwIoBase + MAC_REG_TMCTL0, &byValue);
             if ((byValue == 0) ||
-                (BITbIsAllBitsOn(byValue, TMCTL_TSUSP))) {
+                (byValue & TMCTL_TSUSP)) {
                 VNSvOutPortB(dwIoBase + MAC_REG_TMCTL0, 0);
                 return;
             }
@@ -1333,20 +1328,20 @@ UINT ww = 0;
         VNSvOutPortB(dwIoBase + MAC_REG_TXDMACTL0+2, DMACTL_RUN);
         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
             VNSvInPortB(dwIoBase + MAC_REG_TXDMACTL0, &byData);
-            if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+            if ( !(byData & DMACTL_RUN))
                 break;
         }
     } else if (idx == TYPE_AC0DMA) {
         VNSvOutPortB(dwIoBase + MAC_REG_AC0DMACTL+2, DMACTL_RUN);
         for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
             VNSvInPortB(dwIoBase + MAC_REG_AC0DMACTL, &byData);
-            if (BITbIsAllBitsOff(byData, DMACTL_RUN))
+            if ( !(byData & DMACTL_RUN))
                 break;
         }
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x29);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x29)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x29)\n");
         return FALSE;
     }
     return TRUE;
@@ -1358,19 +1353,19 @@ void MACvClearBusSusInd (DWORD_PTR dwIoBase)
     UINT ww;
     // check if BcnSusInd enabled
     VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
-    if(BITbIsBitOff(dwOrgValue, EnCFG_BcnSusInd))
+    if( !(dwOrgValue & EnCFG_BcnSusInd))
         return;
     //Set BcnSusClr
     dwOrgValue = dwOrgValue | EnCFG_BcnSusClr;
     VNSvOutPortD(dwIoBase + MAC_REG_ENCFG, dwOrgValue);
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
-        if(BITbIsBitOff(dwOrgValue, EnCFG_BcnSusInd))
+        if( !(dwOrgValue & EnCFG_BcnSusInd))
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x33);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
     }
 }
 
@@ -1387,12 +1382,12 @@ void MACvEnableBusSusEn (DWORD_PTR dwIoBase)
     VNSvOutPortB(dwIoBase + MAC_REG_ENCFG, byOrgValue);
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_ENCFG , &dwOrgValue);
-        if(BITbIsBitOn(dwOrgValue, EnCFG_BcnSusInd))
+        if(dwOrgValue & EnCFG_BcnSusInd)
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x34);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x34)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x34)\n");
     }
 }
 
@@ -1410,12 +1405,12 @@ BOOL MACbFlushSYNCFifo (DWORD_PTR dwIoBase)
     // Check if SyncFlushOK
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_MACCR , &byOrgValue);
-        if(BITbIsBitOn(byOrgValue, MACCR_SYNCFLUSHOK))
+        if(byOrgValue & MACCR_SYNCFLUSHOK)
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x35);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
     }
     return TRUE;
 }
@@ -1434,12 +1429,12 @@ BOOL MACbPSWakeup (DWORD_PTR dwIoBase)
     // Check if SyncFlushOK
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortB(dwIoBase + MAC_REG_PSCTL , &byOrgValue);
-        if(BITbIsBitOn(byOrgValue, PSCTL_WAKEDONE))
+        if(byOrgValue & PSCTL_WAKEDONE)
             break;
     }
     if (ww == W_MAX_TIMEOUT) {
         DBG_PORT80(0x36);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" DBG_PORT80(0x33)\n");
         return FALSE;
     }
     return TRUE;
@@ -1470,7 +1465,7 @@ int     ii;
         return;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n");
     wOffset = MISCFIFO_KEYETRY0;
     wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
 
@@ -1478,7 +1473,7 @@ int     ii;
     dwData |= wKeyCtl;
     dwData <<= 16;
     dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
 
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
     VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
@@ -1493,7 +1488,7 @@ int     ii;
     dwData |= *(pbyAddr+1);
     dwData <<= 8;
     dwData |= *(pbyAddr+0);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData);
 
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
     VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
@@ -1503,7 +1498,7 @@ int     ii;
     wOffset += (uKeyIdx * 4);
     for (ii=0;ii<4;ii++) {
         // alway push 128 bits
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
@@ -1563,7 +1558,7 @@ int     ii;
     if (byLocalID <= 1)
         return;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultKeyEntry\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultKeyEntry\n");
     wOffset = MISCFIFO_KEYETRY0;
     wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
 
@@ -1572,7 +1567,7 @@ int     ii;
     wOffset += (uKeyIdx * 4);
     // alway push 128 bits
     for (ii=0; ii<3; ii++) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
@@ -1584,7 +1579,7 @@ int     ii;
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3);
     VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End. wOffset: %d, Data: %lX\n", wOffset+3, dwData);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End. wOffset: %d, Data: %lX\n", wOffset+3, dwData);
 
 }
 
@@ -1620,7 +1615,7 @@ DWORD   dwData;
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
     VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
 
 }
 */
@@ -1652,7 +1647,7 @@ DWORD   dwData;
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
     VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData);
 }
 
 /*
@@ -1679,7 +1674,7 @@ int     ii;
         return;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultTKIPKeyEntry\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetDefaultTKIPKeyEntry\n");
     wOffset = MISCFIFO_KEYETRY0;
     // Kyle test : change offset from 10 -> 0
     wOffset += (10 * MISCFIFO_KEYENTRYSIZE);
@@ -1697,10 +1692,10 @@ int     ii;
     wOffset++;
 
     wOffset += (uKeyIdx * 4);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx);
     // alway push 128 bits
     for (ii=0; ii<4; ii++) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
         VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
         VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
@@ -1734,7 +1729,7 @@ DWORD   dwData;
         return;
 
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MACvSetKeyEntry\n");
     wOffset = MISCFIFO_KEYETRY0;
     wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
 
@@ -1742,7 +1737,7 @@ DWORD   dwData;
     dwData |= wKeyCtl;
     dwData <<= 16;
     dwData |= 0xffff;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl);
 
     VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
     VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h
index edb7096..3ba87fb 100644
--- a/drivers/staging/vt6655/mac.h
+++ b/drivers/staging/vt6655/mac.h
@@ -24,27 +24,19 @@
  * Author: Tevin Chen
  *
  * Date: May 21, 1996
+ *
  * Revision History:
  *      07-01-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
  *      08-25-2003 Kyle Hsu:      Porting MAC functions from sim53.
  *      09-03-2003 Bryan YC Fan:  Add MACvDisableProtectMD & MACvEnableProtectMD
- *
  */
 
 #ifndef __MAC_H__
 #define __MAC_H__
 
-
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__UPC_H__)
 #include "upc.h"
-#endif
 
 /*---------------------  Export Definitions -------------------------*/
 //
@@ -130,7 +122,7 @@
 #define MAC_REG_IFREGCTL    0x70        //
 #define MAC_REG_IFDATA      0x71        //
 #define MAC_REG_ITRTMSET    0x74        //
-#define MAC_REG_PAPEDELAY   0x77        //
+#define MAC_REG_PAPEDELAY   0x77
 #define MAC_REG_SOFTPWRCTL  0x78        //
 #define MAC_REG_GPIOCTL0    0x7A        //
 #define MAC_REG_GPIOCTL1    0x7B        //
@@ -1081,9 +1073,6 @@
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 extern WORD TxRate_iwconfig;//2008-5-8 <add> by chester
 VOID MACvReadAllRegs(DWORD_PTR dwIoBase, PBYTE pbyMacRegs);
@@ -1158,9 +1147,5 @@ void MACvDisableDefaultKey(DWORD_PTR dwIoBase);
 void MACvSetDefaultTKIPKeyEntry(DWORD_PTR dwIoBase, UINT uKeyLen, UINT uKeyIdx, PDWORD pdwKey, BYTE byLocalID);
 void MACvSetDefaultKeyCtl(DWORD_PTR dwIoBase, WORD wKeyCtl, UINT uEntryIdx, BYTE byLocalID);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
 #endif // __MAC_H__
 
diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c
index 3f06de1..fb11595 100644
--- a/drivers/staging/vt6655/mib.c
+++ b/drivers/staging/vt6655/mib.c
@@ -37,31 +37,12 @@
  *
  */
 
-
-#if !defined(__UPC_H__)
 #include "upc.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__MIB_H__)
 #include "mib.h"
-#endif
-#if !defined(__WCTL_H__)
 #include "wctl.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 static int          msglevel                =MSG_LEVEL_INFO;
@@ -92,7 +73,7 @@ static int          msglevel                =MSG_LEVEL_INFO;
 void STAvClearAllCounter (PSStatCounter pStatistic)
 {
     // set memory to zero
-    ZERO_MEMORY(pStatistic, sizeof(SStatCounter));
+	memset(pStatistic, 0, sizeof(SStatCounter));
 }
 
 
@@ -122,58 +103,58 @@ void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, DWORD dwIsr)
     }
 
 //Added by Kyle
-    if (BITbIsBitOn(dwIsr, ISR_TXDMA0))               // ISR, bit0
+    if (dwIsr & ISR_TXDMA0)               // ISR, bit0
         pStatistic->ISRStat.dwIsrTx0OK++;             // TXDMA0 successful
 
-    if (BITbIsBitOn(dwIsr, ISR_AC0DMA))               // ISR, bit1
+    if (dwIsr & ISR_AC0DMA)               // ISR, bit1
         pStatistic->ISRStat.dwIsrAC0TxOK++;           // AC0DMA successful
 
-    if (BITbIsBitOn(dwIsr, ISR_BNTX))                 // ISR, bit2
+    if (dwIsr & ISR_BNTX)                 // ISR, bit2
         pStatistic->ISRStat.dwIsrBeaconTxOK++;        // BeaconTx successful
 
-    if (BITbIsBitOn(dwIsr, ISR_RXDMA0))               // ISR, bit3
+    if (dwIsr & ISR_RXDMA0)               // ISR, bit3
         pStatistic->ISRStat.dwIsrRx0OK++;             // Rx0 successful
 
-    if (BITbIsBitOn(dwIsr, ISR_TBTT))                 // ISR, bit4
+    if (dwIsr & ISR_TBTT)                 // ISR, bit4
         pStatistic->ISRStat.dwIsrTBTTInt++;           // TBTT successful
 
-    if (BITbIsBitOn(dwIsr, ISR_SOFTTIMER))            // ISR, bit6
+    if (dwIsr & ISR_SOFTTIMER)            // ISR, bit6
         pStatistic->ISRStat.dwIsrSTIMERInt++;
 
-    if (BITbIsBitOn(dwIsr, ISR_WATCHDOG))             // ISR, bit7
+    if (dwIsr & ISR_WATCHDOG)             // ISR, bit7
         pStatistic->ISRStat.dwIsrWatchDog++;
 
-    if (BITbIsBitOn(dwIsr, ISR_FETALERR))             // ISR, bit8
+    if (dwIsr & ISR_FETALERR)             // ISR, bit8
         pStatistic->ISRStat.dwIsrUnrecoverableError++;
 
-    if (BITbIsBitOn(dwIsr, ISR_SOFTINT))              // ISR, bit9
+    if (dwIsr & ISR_SOFTINT)              // ISR, bit9
         pStatistic->ISRStat.dwIsrSoftInterrupt++;     // software interrupt
 
-    if (BITbIsBitOn(dwIsr, ISR_MIBNEARFULL))          // ISR, bit10
+    if (dwIsr & ISR_MIBNEARFULL)          // ISR, bit10
         pStatistic->ISRStat.dwIsrMIBNearfull++;
 
-    if (BITbIsBitOn(dwIsr, ISR_RXNOBUF))              // ISR, bit11
+    if (dwIsr & ISR_RXNOBUF)              // ISR, bit11
         pStatistic->ISRStat.dwIsrRxNoBuf++;           // Rx No Buff
 
-    if (BITbIsBitOn(dwIsr, ISR_RXDMA1))               // ISR, bit12
+    if (dwIsr & ISR_RXDMA1)               // ISR, bit12
         pStatistic->ISRStat.dwIsrRx1OK++;             // Rx1 successful
 
-//    if (BITbIsBitOn(dwIsr, ISR_ATIMTX))               // ISR, bit13
+//    if (dwIsr & ISR_ATIMTX)               // ISR, bit13
 //        pStatistic->ISRStat.dwIsrATIMTxOK++;          // ATIMTX successful
 
-//    if (BITbIsBitOn(dwIsr, ISR_SYNCTX))               // ISR, bit14
+//    if (dwIsr & ISR_SYNCTX)               // ISR, bit14
 //        pStatistic->ISRStat.dwIsrSYNCTxOK++;          // SYNCTX successful
 
-//    if (BITbIsBitOn(dwIsr, ISR_CFPEND))               // ISR, bit18
+//    if (dwIsr & ISR_CFPEND)               // ISR, bit18
 //        pStatistic->ISRStat.dwIsrCFPEnd++;
 
-//    if (BITbIsBitOn(dwIsr, ISR_ATIMEND))              // ISR, bit19
+//    if (dwIsr & ISR_ATIMEND)              // ISR, bit19
 //        pStatistic->ISRStat.dwIsrATIMEnd++;
 
-//    if (BITbIsBitOn(dwIsr, ISR_SYNCFLUSHOK))          // ISR, bit20
+//    if (dwIsr & ISR_SYNCFLUSHOK)          // ISR, bit20
 //        pStatistic->ISRStat.dwIsrSYNCFlushOK++;
 
-    if (BITbIsBitOn(dwIsr, ISR_SOFTTIMER1))           // ISR, bit21
+    if (dwIsr & ISR_SOFTTIMER1)           // ISR, bit21
         pStatistic->ISRStat.dwIsrSTIMER1Int++;
 
 }
@@ -202,20 +183,20 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
     //need change
     PS802_11Header pHeader = (PS802_11Header)pbyBuffer;
 
-    if (BITbIsBitOn(byRSR, RSR_ADDROK))
+    if (byRSR & RSR_ADDROK)
         pStatistic->dwRsrADDROk++;
-    if (BITbIsBitOn(byRSR, RSR_CRCOK)) {
+    if (byRSR & RSR_CRCOK) {
         pStatistic->dwRsrCRCOk++;
 
         pStatistic->ullRsrOK++;
 
         if (cbFrameLength >= U_ETHER_ADDR_LEN) {
             // update counters in case that successful transmit
-            if (BITbIsBitOn(byRSR, RSR_ADDRBROAD)) {
+            if (byRSR & RSR_ADDRBROAD) {
                 pStatistic->ullRxBroadcastFrames++;
                 pStatistic->ullRxBroadcastBytes += (ULONGLONG)cbFrameLength;
             }
-            else if (BITbIsBitOn(byRSR, RSR_ADDRMULTI)) {
+            else if (byRSR & RSR_ADDRMULTI) {
                 pStatistic->ullRxMulticastFrames++;
                 pStatistic->ullRxMulticastBytes += (ULONGLONG)cbFrameLength;
             }
@@ -228,113 +209,113 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
 
     if(byRxRate==22) {
         pStatistic->CustomStat.ullRsr11M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr11MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr11M, (INT)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr11M, (INT)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR);
     }
     else if(byRxRate==11) {
         pStatistic->CustomStat.ullRsr5M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr5MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr5M, (INT)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr5M, (INT)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR);
     }
     else if(byRxRate==4) {
         pStatistic->CustomStat.ullRsr2M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr2MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr2M, (INT)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr2M, (INT)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR);
     }
     else if(byRxRate==2){
         pStatistic->CustomStat.ullRsr1M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr1MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr1M, (INT)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr1M, (INT)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR);
     }
     else if(byRxRate==12){
         pStatistic->CustomStat.ullRsr6M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr6MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr6M, (INT)pStatistic->CustomStat.ullRsr6MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr6M, (INT)pStatistic->CustomStat.ullRsr6MCRCOk);
     }
     else if(byRxRate==18){
         pStatistic->CustomStat.ullRsr9M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr9MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr9M, (INT)pStatistic->CustomStat.ullRsr9MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr9M, (INT)pStatistic->CustomStat.ullRsr9MCRCOk);
     }
     else if(byRxRate==24){
         pStatistic->CustomStat.ullRsr12M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr12MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr12M, (INT)pStatistic->CustomStat.ullRsr12MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr12M, (INT)pStatistic->CustomStat.ullRsr12MCRCOk);
     }
     else if(byRxRate==36){
         pStatistic->CustomStat.ullRsr18M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr18MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr18M, (INT)pStatistic->CustomStat.ullRsr18MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr18M, (INT)pStatistic->CustomStat.ullRsr18MCRCOk);
     }
     else if(byRxRate==48){
         pStatistic->CustomStat.ullRsr24M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr24MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr24M, (INT)pStatistic->CustomStat.ullRsr24MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr24M, (INT)pStatistic->CustomStat.ullRsr24MCRCOk);
     }
     else if(byRxRate==72){
         pStatistic->CustomStat.ullRsr36M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr36MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr36M, (INT)pStatistic->CustomStat.ullRsr36MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr36M, (INT)pStatistic->CustomStat.ullRsr36MCRCOk);
     }
     else if(byRxRate==96){
         pStatistic->CustomStat.ullRsr48M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr48MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr48M, (INT)pStatistic->CustomStat.ullRsr48MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr48M, (INT)pStatistic->CustomStat.ullRsr48MCRCOk);
     }
     else if(byRxRate==108){
         pStatistic->CustomStat.ullRsr54M++;
-        if(BITbIsBitOn(byRSR, RSR_CRCOK)) {
+        if(byRSR & RSR_CRCOK) {
             pStatistic->CustomStat.ullRsr54MCRCOk++;
         }
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr54M, (INT)pStatistic->CustomStat.ullRsr54MCRCOk);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr54M, (INT)pStatistic->CustomStat.ullRsr54MCRCOk);
     }
     else {
-    	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (INT)pStatistic->dwRsrRxPacket+1, (INT)pStatistic->dwRsrCRCOk);
+    	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (INT)pStatistic->dwRsrRxPacket+1, (INT)pStatistic->dwRsrCRCOk);
     }
 
-    if (BITbIsBitOn(byRSR, RSR_BSSIDOK))
+    if (byRSR & RSR_BSSIDOK)
         pStatistic->dwRsrBSSIDOk++;
 
-    if (BITbIsBitOn(byRSR, RSR_BCNSSIDOK))
+    if (byRSR & RSR_BCNSSIDOK)
         pStatistic->dwRsrBCNSSIDOk++;
-    if (BITbIsBitOn(byRSR, RSR_IVLDLEN))  //invalid len (> 2312 byte)
+    if (byRSR & RSR_IVLDLEN)  //invalid len (> 2312 byte)
         pStatistic->dwRsrLENErr++;
-    if (BITbIsBitOn(byRSR, RSR_IVLDTYP))  //invalid packet type
+    if (byRSR & RSR_IVLDTYP)  //invalid packet type
         pStatistic->dwRsrTYPErr++;
-    if (BITbIsBitOn(byRSR, (RSR_IVLDTYP | RSR_IVLDLEN)))
+    if (byRSR & (RSR_IVLDTYP | RSR_IVLDLEN))
         pStatistic->dwRsrErr++;
 
-    if (BITbIsBitOn(byNewRSR, NEWRSR_DECRYPTOK))
+    if (byNewRSR & NEWRSR_DECRYPTOK)
         pStatistic->dwNewRsrDECRYPTOK++;
-    if (BITbIsBitOn(byNewRSR, NEWRSR_CFPIND))
+    if (byNewRSR & NEWRSR_CFPIND)
         pStatistic->dwNewRsrCFP++;
-    if (BITbIsBitOn(byNewRSR, NEWRSR_HWUTSF))
+    if (byNewRSR & NEWRSR_HWUTSF)
         pStatistic->dwNewRsrUTSF++;
-    if (BITbIsBitOn(byNewRSR, NEWRSR_BCNHITAID))
+    if (byNewRSR & NEWRSR_BCNHITAID)
         pStatistic->dwNewRsrHITAID++;
-    if (BITbIsBitOn(byNewRSR, NEWRSR_BCNHITAID0))
+    if (byNewRSR & NEWRSR_BCNHITAID0)
         pStatistic->dwNewRsrHITAID0++;
 
     // increase rx packet count
@@ -350,9 +331,9 @@ void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
         pStatistic->dwRsrRxControl++;
     }
 
-    if (BITbIsBitOn(byRSR, RSR_ADDRBROAD))
+    if (byRSR & RSR_ADDRBROAD)
         pStatistic->dwRsrBroadcast++;
-    else if (BITbIsBitOn(byRSR, RSR_ADDRMULTI))
+    else if (byRSR & RSR_ADDRMULTI)
         pStatistic->dwRsrMulticast++;
     else
         pStatistic->dwRsrDirected++;
@@ -427,7 +408,7 @@ STAvUpdateRDStatCounterEx (
     // rx length
     pStatistic->dwCntRxFrmLength = cbFrameLength;
     // rx pattern, we just see 10 bytes for sample
-    MEMvCopy(pStatistic->abyCntRxPattern, (PBYTE)pbyBuffer, 10);
+    memcpy(pStatistic->abyCntRxPattern, (PBYTE)pbyBuffer, 10);
 }
 
 
@@ -504,13 +485,13 @@ STAvUpdateTDStatCounter (
         }
     }
     else {
-        if (BITbIsBitOn(byTSR1, TSR1_TERR))
+        if (byTSR1 & TSR1_TERR)
             pStatistic->dwTsrErr[uIdx]++;
-        if (BITbIsBitOn(byTSR1, TSR1_RETRYTMO))
+        if (byTSR1 & TSR1_RETRYTMO)
             pStatistic->dwTsrRetryTimeout[uIdx]++;
-        if (BITbIsBitOn(byTSR1, TSR1_TMO))
+        if (byTSR1 & TSR1_TMO)
             pStatistic->dwTsrTransmitTimeout[uIdx]++;
-        if (BITbIsBitOn(byTSR1, ACK_DATA))
+        if (byTSR1 & ACK_DATA)
             pStatistic->dwTsrACKData[uIdx]++;
     }
 
@@ -552,7 +533,7 @@ STAvUpdateTDStatCounterEx (
     // tx length
     pStatistic->dwCntTxBufLength = uPktLength;
     // tx pattern, we just see 16 bytes for sample
-    MEMvCopy(pStatistic->abyCntTxPattern, pbyBuffer, 16);
+    memcpy(pStatistic->abyCntTxPattern, pbyBuffer, 16);
 }
 
 
@@ -612,5 +593,5 @@ void
 STAvClear802_11Counter(PSDot11Counters p802_11Counter)
 {
     // set memory to zero
-    ZERO_MEMORY(p802_11Counter, sizeof(SDot11Counters));
+	memset(p802_11Counter, 0, sizeof(SDot11Counters));
 }
diff --git a/drivers/staging/vt6655/mib.h b/drivers/staging/vt6655/mib.h
index b4e1c4a..69e04f7 100644
--- a/drivers/staging/vt6655/mib.h
+++ b/drivers/staging/vt6655/mib.h
@@ -29,19 +29,9 @@
 #ifndef __MIB_H__
 #define __MIB_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__DESC_H__)
 #include "desc.h"
-#endif
-
-
-
-//#define ULONGLONG   ULONG
 
 /*---------------------  Export Definitions -------------------------*/
 //
@@ -75,7 +65,7 @@ typedef struct tagSDot11Counters {
 //    ULONGLONG   WEPICVErrorCount;
 //    ULONGLONG   DecryptSuccessCount;
 //    ULONGLONG   DecryptFailureCount;
-} SDot11Counters, DEF* PSDot11Counters;
+} SDot11Counters, *PSDot11Counters;
 
 
 //
@@ -83,7 +73,7 @@ typedef struct tagSDot11Counters {
 //
 typedef struct tagSMib2Counter {
     LONG    ifIndex;
-    TCHAR   ifDescr[256];               // max size 255 plus zero ending
+    char    ifDescr[256];               // max size 255 plus zero ending
                                         // e.g. "interface 1"
     LONG    ifType;
     LONG    ifMtu;
@@ -105,7 +95,7 @@ typedef struct tagSMib2Counter {
     DWORD   ifOutErrors;
     DWORD   ifOutQLen;
     DWORD   ifSpecific;
-} SMib2Counter, DEF* PSMib2Counter;
+} SMib2Counter, *PSMib2Counter;
 
 // Value in the ifType entry
 //#define ETHERNETCSMACD      6           //
@@ -142,7 +132,7 @@ typedef struct tagSRmonCounter {
     DWORD   etherStatsPkt1024to1518Octets;
     DWORD   etherStatsOwners;
     DWORD   etherStatsStatus;
-} SRmonCounter, DEF* PSRmonCounter;
+} SRmonCounter, *PSRmonCounter;
 
 //
 // Custom counter
@@ -180,7 +170,7 @@ typedef struct tagSCustomCounters {
     ULONGLONG   ullRsr9MCRCOk;
     ULONGLONG   ullRsr6MCRCOk;
 
-} SCustomCounters, DEF* PSCustomCounters;
+} SCustomCounters, *PSCustomCounters;
 
 
 //
@@ -211,7 +201,7 @@ typedef struct tagSISRCounters {
     DWORD   dwIsrSYNCFlushOK;
     DWORD   dwIsrSTIMER1Int;
     /////////////////////////////////////
-} SISRCounters, DEF* PSISRCounters;
+} SISRCounters, *PSISRCounters;
 
 
 // Value in the etherStatsStatus entry
@@ -344,17 +334,13 @@ typedef struct tagSStatCounter {
     ULONG SignalStren;
     ULONG LinkQuality;
    #endif
-} SStatCounter, DEF* PSStatCounter;
+} SStatCounter, *PSStatCounter;
 
 /*---------------------  Export Classes  ----------------------------*/
 
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 
 void STAvClearAllCounter(PSStatCounter pStatistic);
 
@@ -386,13 +372,6 @@ void STAvUpdate802_11Counter(
 
 void STAvClear802_11Counter(PSDot11Counters p802_11Counter);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __MIB_H__
 
 
diff --git a/drivers/staging/vt6655/michael.c b/drivers/staging/vt6655/michael.c
index 7bda4c1..c930e0c 100644
--- a/drivers/staging/vt6655/michael.c
+++ b/drivers/staging/vt6655/michael.c
@@ -39,15 +39,8 @@
  *
  */
 
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__MICHAEL_H__)
 #include "michael.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
diff --git a/drivers/staging/vt6655/michael.h b/drivers/staging/vt6655/michael.h
index 62a24a6..3f79b52 100644
--- a/drivers/staging/vt6655/michael.h
+++ b/drivers/staging/vt6655/michael.h
@@ -28,13 +28,9 @@
  *
  */
 
-
 #ifndef __MICHAEL_H__
 #define __MICHAEL_H__
 
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
 /*---------------------  Export Definitions -------------------------*/
 
 /*---------------------  Export Types  ------------------------------*/
diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c
index edd8336..84eda04 100644
--- a/drivers/staging/vt6655/power.c
+++ b/drivers/staging/vt6655/power.c
@@ -16,9 +16,10 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: power.c
  *
- * Purpose: Handles 802.11 power managment  functions
+ * Purpose: Handles 802.11 power management  functions
  *
  * Author: Lyndon Chen
  *
@@ -36,44 +37,14 @@
  *
  */
 
-
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__POWER_H__)
 #include "power.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-
-
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -154,7 +125,7 @@ PSvEnablePowerSaving(
         PSbSendNullPacket(pDevice);
     }
     pDevice->bPWBitOn = TRUE;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n");
     return;
 }
 
@@ -261,7 +232,7 @@ PSbConsiderPowerDown(
 
     // no Tx, no Rx isr, now go to Doze
     MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
     return TRUE;
 }
 
@@ -305,10 +276,10 @@ PSvSendPSPOLL(
     pTxPacket->cbPayloadLen = 0;
     // send the frame
     if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
     }
     else {
-//        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n");
+//        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n");
     };
 
     return;
@@ -389,12 +360,12 @@ PSbSendNullPacket(
     pTxPacket->cbPayloadLen = 0;
     // send the frame
     if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
         return FALSE;
     }
     else {
 
-//            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n");
+//            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n");
     }
 
 
diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h
index a01e7e9..30634fa 100644
--- a/drivers/staging/vt6655/power.h
+++ b/drivers/staging/vt6655/power.h
@@ -16,10 +16,9 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- *
  * File: power.h
  *
- * Purpose: Handles 802.11 power managment  functions
+ * Purpose: Handles 802.11 power management  functions
  *
  * Author: Lyndon Chen
  *
diff --git a/drivers/staging/vt6655/rc4.c b/drivers/staging/vt6655/rc4.c
index 0345e32..e6c6131 100644
--- a/drivers/staging/vt6655/rc4.c
+++ b/drivers/staging/vt6655/rc4.c
@@ -1,5 +1,6 @@
 /*
- * File: rc4.c
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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
@@ -15,6 +16,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ * File: rc4.c
+ *
  * Purpose:
  *
  * Functions:
@@ -27,9 +30,7 @@
  *
  */
 
-#if !defined(__RC4_H__)
 #include "rc4.h"
-#endif
 
 VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len)
 {
diff --git a/drivers/staging/vt6655/rc4.h b/drivers/staging/vt6655/rc4.h
index 4e3ccc5..bf607c9 100644
--- a/drivers/staging/vt6655/rc4.h
+++ b/drivers/staging/vt6655/rc4.h
@@ -30,11 +30,7 @@
 #ifndef __RC4_H__
 #define __RC4_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 /*---------------------  Export Types  ------------------------------*/
@@ -42,7 +38,7 @@ typedef struct {
     UINT ux;
     UINT uy;
     BYTE abystate[256];
-} RC4Ext, DEF* PRC4Ext;
+} RC4Ext, *PRC4Ext;
 
 VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len);
 UINT rc4_byte(PRC4Ext pRC4);
diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c
index 9d4e3eb..01ab73f 100644
--- a/drivers/staging/vt6655/rf.c
+++ b/drivers/staging/vt6655/rf.c
@@ -31,21 +31,11 @@
  * Revision History:
  *
  */
-#if !defined(__MAC_H__)
+
 #include "mac.h"
-#endif
-#if !defined(__SROM_H__)
 #include "srom.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -642,7 +632,7 @@ BOOL IFRFbWriteEmbeded (DWORD_PTR dwIoBase, DWORD dwData)
     // W_MAX_TIMEOUT is the timeout period
     for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
         VNSvInPortD(dwIoBase + MAC_REG_IFREGCTL, &dwValue);
-        if (BITbIsBitOn(dwValue, IFREGCTL_DONE))
+        if (dwValue & IFREGCTL_DONE)
             break;
     }
 
@@ -1215,7 +1205,7 @@ VOID
 RFvRSSITodBm (
     IN  PSDevice pDevice,
     IN  BYTE     byCurrRSSI,
-    OUT PLONG    pldBm
+    long *    pldBm
     )
 {
     BYTE byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h
index 05fe17b..f316bcc 100644
--- a/drivers/staging/vt6655/rf.h
+++ b/drivers/staging/vt6655/rf.h
@@ -27,16 +27,12 @@
  *
  */
 
-
 #ifndef __RF_H__
 #define __RF_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
+
 /*---------------------  Export Definitions -------------------------*/
 //
 // Baseband RF pair definition in eeprom (Bits 6..0)
@@ -79,9 +75,6 @@
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 BOOL IFRFbWriteEmbeded(DWORD_PTR dwIoBase, DWORD dwData);
 BOOL RFbSelectChannel(DWORD_PTR dwIoBase, BYTE byRFType, BYTE byChannel);
@@ -100,18 +93,13 @@ VOID
 RFvRSSITodBm(
     IN  PSDevice pDevice,
     IN  BYTE     byCurrRSSI,
-    OUT PLONG    pldBm
+    long    *pldBm
     );
 
 //{{ RobertYu: 20050104
 BOOL RFbAL7230SelectChannelPostProcess(DWORD_PTR dwIoBase, BYTE byOldChannel, BYTE byNewChannel);
 //}} RobertYu
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif // __RF_H__
 
 
diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c
index c8a4a55..ed3070e 100644
--- a/drivers/staging/vt6655/rxtx.c
+++ b/drivers/staging/vt6655/rxtx.c
@@ -48,55 +48,20 @@
  *
  */
 
-
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__MICHAEL_H__)
 #include "michael.h"
-#endif
-#if !defined(__TKIP_H__)
 #include "tkip.h"
-#endif
-#if !defined(__TCRC_H__)
 #include "tcrc.h"
-#endif
-#if !defined(__WCTL_H__)
 #include "wctl.h"
-#endif
-#if !defined(__WROUTE_H__)
 #include "wroute.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__HOSTAP_H__)
 #include "hostap.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -167,7 +132,7 @@ static
 VOID
 s_vFillRTSHead(
     IN PSDevice         pDevice,
-    IN BYTE             byPktTyp,
+    IN BYTE             byPktType,
     IN PVOID            pvRTS,
     IN UINT             cbFrameLength,
     IN BOOL             bNeedAck,
@@ -181,7 +146,7 @@ static
 VOID
 s_vGenerateTxParameter(
     IN PSDevice         pDevice,
-    IN  BYTE            byPktTyp,
+    IN  BYTE            byPktType,
     IN PVOID            pTxBufHead,
     IN PVOID            pvRrvTime,
     IN PVOID            pvRTS,
@@ -209,7 +174,7 @@ static
 UINT
 s_cbFillTxBufHead (
     IN  PSDevice         pDevice,
-    IN  BYTE             byPktTyp,
+    IN  BYTE             byPktType,
     IN  PBYTE            pbyTxBufferAddr,
     IN  UINT             cbFrameBodySize,
     IN  UINT             uDMAIdx,
@@ -227,7 +192,7 @@ static
 UINT
 s_uFillDataHead (
     IN PSDevice pDevice,
-    IN BYTE     byPktTyp,
+    IN BYTE     byPktType,
     IN PVOID    pTxDataHead,
     IN UINT     cbFrameLength,
     IN UINT     uDMAIdx,
@@ -275,16 +240,16 @@ s_vFillTxKey (
 
     if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
         if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
-            MEMvCopy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3);
-            MEMvCopy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+            memcpy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3);
+            memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
         } else {
-            MEMvCopy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3);
-            MEMvCopy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+            memcpy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3);
+            memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
             if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
-                MEMvCopy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3);
-                MEMvCopy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+                memcpy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3);
+                memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
             }
-            MEMvCopy(pDevice->abyPRNG, pbyBuf, 16);
+            memcpy(pDevice->abyPRNG, pbyBuf, 16);
         }
         // Append IV after Mac Header
         *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
@@ -301,21 +266,21 @@ s_vFillTxKey (
         }
         TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
                     pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
-        MEMvCopy(pbyBuf, pDevice->abyPRNG, 16);
+        memcpy(pbyBuf, pDevice->abyPRNG, 16);
         // Make IV
-        MEMvCopy(pdwIV, pDevice->abyPRNG, 3);
+        memcpy(pdwIV, pDevice->abyPRNG, 3);
 
         *(pbyIVHead+3) = (BYTE)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
         // Append IV&ExtIV after Mac Header
         *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
 
     } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
         pTransmitKey->wTSC15_0++;
         if (pTransmitKey->wTSC15_0 == 0) {
             pTransmitKey->dwTSC47_16++;
         }
-        MEMvCopy(pbyBuf, pTransmitKey->abyKey, 16);
+        memcpy(pbyBuf, pTransmitKey->abyKey, 16);
 
         // Make IV
         *pdwIV = 0;
@@ -327,7 +292,7 @@ s_vFillTxKey (
         //Fill MICHDR0
         *pMICHDR = 0x59;
         *((PBYTE)(pMICHDR+1)) = 0; // TxPriority
-        MEMvCopy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6);
+        memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6);
         *((PBYTE)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
         *((PBYTE)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
         *((PBYTE)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
@@ -345,18 +310,18 @@ s_vFillTxKey (
             *((PBYTE)(pMICHDR+17)) = 22; // HLEN[7:0]
         }
         wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F);
-        MEMvCopy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL
-        MEMvCopy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6);
-        MEMvCopy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6);
+        memcpy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL
+        memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6);
+        memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6);
 
         //Fill MICHDR2
-        MEMvCopy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6);
+        memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6);
         wValue = pMACHeader->wSeqCtl;
         wValue &= 0x000F;
         wValue = cpu_to_le16(wValue);
-        MEMvCopy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL
+        memcpy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL
         if (pDevice->bLongHeader) {
-            MEMvCopy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6);
+            memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6);
         }
     }
 }
@@ -406,7 +371,7 @@ s_vSWencryption (
 
 
 
-/*byPktTyp : PK_TYPE_11A     0
+/*byPktType : PK_TYPE_11A     0
              PK_TYPE_11B     1
              PK_TYPE_11GB    2
              PK_TYPE_11GA    3
@@ -415,7 +380,7 @@ static
 UINT
 s_uGetTxRsvTime (
     IN PSDevice pDevice,
-    IN BYTE     byPktTyp,
+    IN BYTE     byPktType,
     IN UINT     cbFrameLength,
     IN WORD     wRate,
     IN BOOL     bNeedAck
@@ -423,14 +388,14 @@ s_uGetTxRsvTime (
 {
     UINT uDataTime, uAckTime;
 
-    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, cbFrameLength, wRate);
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
 #ifdef	PLICE_DEBUG
 	//printk("s_uGetTxRsvTime is %d\n",uDataTime);
 #endif
-    if (byPktTyp == PK_TYPE_11B) {//llb,CCK mode
-        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, (WORD)pDevice->byTopCCKBasicRate);
+    if (byPktType == PK_TYPE_11B) {//llb,CCK mode
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopCCKBasicRate);
     } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
-        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, (WORD)pDevice->byTopOFDMBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopOFDMBasicRate);
     }
 
     if (bNeedAck) {
@@ -447,7 +412,7 @@ UINT
 s_uGetRTSCTSRsvTime (
     IN PSDevice pDevice,
     IN BYTE byRTSRsvType,
-    IN BYTE byPktTyp,
+    IN BYTE byPktType,
     IN UINT cbFrameLength,
     IN WORD wCurrentRate
     )
@@ -457,23 +422,23 @@ s_uGetRTSCTSRsvTime (
     uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
 
 
-    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, cbFrameLength, wCurrentRate);
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
     if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
-        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 20, pDevice->byTopCCKBasicRate);
-        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopCCKBasicRate);
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
     }
     else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
-        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 20, pDevice->byTopCCKBasicRate);
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopCCKBasicRate);
-        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopOFDMBasicRate);
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
     }
     else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
-        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 20, pDevice->byTopOFDMBasicRate);
-        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopOFDMBasicRate);
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
     }
     else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
-        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopCCKBasicRate);
-        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktTyp, 14, pDevice->byTopOFDMBasicRate);
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
         uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
         return uRrvTime;
     }
@@ -757,7 +722,7 @@ static
 UINT
 s_uFillDataHead (
     IN PSDevice pDevice,
-    IN BYTE     byPktTyp,
+    IN BYTE     byPktType,
     IN PVOID    pTxDataHead,
     IN UINT     cbFrameLength,
     IN UINT     uDMAIdx,
@@ -775,11 +740,11 @@ s_uFillDataHead (
         return 0;
     }
 
-    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
         if (byFBOption == AUTO_FB_NONE) {
             PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
             //Get SignalField,ServiceField,Length
-            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
@@ -789,7 +754,7 @@ s_uFillDataHead (
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             //Get Duration and TimeStamp
             pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
-                                                         byPktTyp, wCurrentRate, bNeedAck, uFragIdx,
+                                                         byPktType, wCurrentRate, bNeedAck, uFragIdx,
                                                          cbLastFragmentSize, uMACfragNum,
                                                          byFBOption)); //1: 2.4GHz
             pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
@@ -805,7 +770,7 @@ s_uFillDataHead (
             // Auto Fallback
             PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
             //Get SignalField,ServiceField,Length
-            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
@@ -814,13 +779,13 @@ s_uFillDataHead (
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             //Get Duration and TimeStamp
-            pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktTyp,
+            pBuf->wDuration_a = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
                                          wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
             pBuf->wDuration_b = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
                                          pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
-            pBuf->wDuration_a_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktTyp,
+            pBuf->wDuration_a_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
                                          wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
-            pBuf->wDuration_a_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktTyp,
+            pBuf->wDuration_a_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
                                          wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //1: 2.4GHz
 
             pBuf->wTimeStampOff_a = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
@@ -829,35 +794,35 @@ s_uFillDataHead (
             return (pBuf->wDuration_a);
         } //if (byFBOption == AUTO_FB_NONE)
     }
-    else if (byPktTyp == PK_TYPE_11A) {
+    else if (byPktType == PK_TYPE_11A) {
         if ((byFBOption != AUTO_FB_NONE)) {
             // Auto Fallback
             PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
             //Get SignalField,ServiceField,Length
-            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration and TimeStampOff
 
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktTyp,
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
-            pBuf->wDuration_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktTyp,
+            pBuf->wDuration_f0 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
-            pBuf->wDuration_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktTyp,
+            pBuf->wDuration_f1 = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
                                         wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); //0: 5GHz
             pBuf->wTimeStampOff = cpu_to_le16(wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE]);
             return (pBuf->wDuration);
         } else {
             PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
             //Get SignalField,ServiceField,Length
-            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration and TimeStampOff
 
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktTyp,
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
                                                        wCurrentRate, bNeedAck, uFragIdx,
                                                        cbLastFragmentSize, uMACfragNum,
                                                        byFBOption));
@@ -869,12 +834,12 @@ s_uFillDataHead (
     else {
             PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
             //Get SignalField,ServiceField,Length
-            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktTyp,
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration and TimeStampOff
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktTyp,
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
                                                        wCurrentRate, bNeedAck, uFragIdx,
                                                        cbLastFragmentSize, uMACfragNum,
                                                        byFBOption));
@@ -889,7 +854,7 @@ static
 VOID
 s_vFillRTSHead (
     IN PSDevice         pDevice,
-    IN BYTE             byPktTyp,
+    IN BYTE             byPktType,
     IN PVOID            pvRTS,
     IN UINT             cbFrameLength,
     IN BOOL             bNeedAck,
@@ -902,9 +867,6 @@ s_vFillRTSHead (
     UINT uRTSFrameLen = 20;
     WORD  wLen = 0x0000;
 
-    // dummy code, only to avoid compiler warning message
-    UNREFERENCED_PARAMETER(bNeedAck);
-
     if (pvRTS == NULL)
     	return;
 
@@ -916,7 +878,7 @@ s_vFillRTSHead (
 
     // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
     //       Otherwise, we need to modified codes for them.
-    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
         if (byFBOption == AUTO_FB_NONE) {
             PSRTS_g pBuf = (PSRTS_g)pvRTS;
             //Get SignalField,ServiceField,Length
@@ -924,30 +886,30 @@ s_vFillRTSHead (
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
-            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
             //Get Duration
             pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
-            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
-            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
 
             pBuf->Data.wDurationID = pBuf->wDuration_aa;
             //Get RTS Frame body
             pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
             if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
                 (pDevice->eOPMode == OP_MODE_AP)) {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
             if (pDevice->eOPMode == OP_MODE_AP) {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
             }
         }
         else {
@@ -957,101 +919,101 @@ s_vFillRTSHead (
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
-            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
             );
             pBuf->wTransmitLength_a = cpu_to_le16(wLen);
 
             //Get Duration
             pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
-            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
-            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
-            pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
-            pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
-            pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
-            pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption));    //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
+            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
             pBuf->Data.wDurationID = pBuf->wDuration_aa;
             //Get RTS Frame body
             pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
 
             if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
                 (pDevice->eOPMode == OP_MODE_AP)) {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
 
             if (pDevice->eOPMode == OP_MODE_AP) {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
             }
 
         } // if (byFBOption == AUTO_FB_NONE)
     }
-    else if (byPktTyp == PK_TYPE_11A) {
+    else if (byPktType == PK_TYPE_11A) {
         if (byFBOption == AUTO_FB_NONE) {
             PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
             //Get SignalField,ServiceField,Length
-            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
     	    pBuf->Data.wDurationID = pBuf->wDuration;
             //Get RTS Frame body
             pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
 
             if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
                 (pDevice->eOPMode == OP_MODE_AP)) {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
 
             if (pDevice->eOPMode == OP_MODE_AP) {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
             }
 
         }
         else {
             PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
             //Get SignalField,ServiceField,Length
-            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktTyp,
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
                 (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
             );
             pBuf->wTransmitLength = cpu_to_le16(wLen);
             //Get Duration
-            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
-    	    pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
-    	    pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+    	    pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
+    	    pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
     	    pBuf->Data.wDurationID = pBuf->wDuration;
     	    //Get RTS Frame body
             pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
 
             if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
                 (pDevice->eOPMode == OP_MODE_AP)) {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
             if (pDevice->eOPMode == OP_MODE_AP) {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             }
             else {
-                MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
             }
         }
     }
-    else if (byPktTyp == PK_TYPE_11B) {
+    else if (byPktType == PK_TYPE_11B) {
         PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
         //Get SignalField,ServiceField,Length
         BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
@@ -1059,7 +1021,7 @@ s_vFillRTSHead (
         );
         pBuf->wTransmitLength = cpu_to_le16(wLen);
         //Get Duration
-        pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+        pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
         pBuf->Data.wDurationID = pBuf->wDuration;
         //Get RTS Frame body
         pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
@@ -1067,17 +1029,17 @@ s_vFillRTSHead (
 
         if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
             (pDevice->eOPMode == OP_MODE_AP)) {
-            MEMvCopy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
         }
         else {
-            MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
         }
 
         if (pDevice->eOPMode == OP_MODE_AP) {
-            MEMvCopy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
         }
         else {
-            MEMvCopy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
         }
     }
 }
@@ -1087,7 +1049,7 @@ VOID
 s_vFillCTSHead (
     IN PSDevice pDevice,
     IN UINT     uDMAIdx,
-    IN BYTE     byPktTyp,
+    IN BYTE     byPktType,
     IN PVOID    pvCTS,
     IN UINT     cbFrameLength,
     IN BOOL     bNeedAck,
@@ -1109,7 +1071,7 @@ s_vFillCTSHead (
         uCTSFrameLen -= 4;
     }
 
-    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
         if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
             // Auto Fall back
             PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
@@ -1121,22 +1083,22 @@ s_vFillCTSHead (
 
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
 
-            pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wDuration_ba += pDevice->wCTSDuration;
             pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
             //Get CTSDuration_ba_f0
-            pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration;
             pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
             //Get CTSDuration_ba_f1
-            pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration;
             pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
             //Get CTS Frame body
             pBuf->Data.wDurationID = pBuf->wDuration_ba;
             pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
             pBuf->Data.wReserved = 0x0000;
-            MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
 
         } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
             PSCTS pBuf = (PSCTS)pvCTS;
@@ -1146,7 +1108,7 @@ s_vFillCTSHead (
             );
             pBuf->wTransmitLength_b = cpu_to_le16(wLen);
             //Get CTSDuration_ba
-            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktTyp, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
             pBuf->wDuration_ba += pDevice->wCTSDuration;
             pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
 
@@ -1154,7 +1116,7 @@ s_vFillCTSHead (
             pBuf->Data.wDurationID = pBuf->wDuration_ba;
             pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
             pBuf->Data.wReserved = 0x0000;
-            MEMvCopy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
         }
     }
 }
@@ -1191,7 +1153,7 @@ static
 VOID
 s_vGenerateTxParameter (
     IN PSDevice         pDevice,
-    IN BYTE             byPktTyp,
+    IN BYTE             byPktType,
     IN PVOID            pTxBufHead,
     IN PVOID            pvRrvTime,
     IN PVOID            pvRTS,
@@ -1209,7 +1171,7 @@ s_vGenerateTxParameter (
     BYTE byFBOption = AUTO_FB_NONE;
 //    WORD wCurrentRate = pDevice->wCurrentRate;
 
-    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
     PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
     pFifoHead->wReserved = wCurrentRate;
     wFifoCtl = pFifoHead->wFIFOCtl;
@@ -1228,47 +1190,47 @@ s_vGenerateTxParameter (
     if (pDevice->bLongHeader)
         cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
 
-    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
 
         if (pvRTS != NULL) { //RTS_need
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
-                pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktTyp, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
-                pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktTyp, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
-                pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktTyp, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
-                pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktTyp, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
                 pBuf->wTxRrvTime_b = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
             }
             //Fill RTS
-            s_vFillRTSHead(pDevice, byPktTyp, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
         }
         else {//RTS_needless, PCF mode
 
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
-                pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktTyp, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
                 pBuf->wTxRrvTime_b = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
-                pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktTyp, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
+                pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
             }
 
 
             //Fill CTS
-            s_vFillCTSHead(pDevice, uDMAIdx, byPktTyp, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
+            s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
         }
     }
-    else if (byPktTyp == PK_TYPE_11A) {
+    else if (byPktType == PK_TYPE_11A) {
 
         if (pvRTS != NULL) {//RTS_need, non PCF mode
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
-                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktTyp, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
-                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktTyp, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
+                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
             }
             //Fill RTS
-            s_vFillRTSHead(pDevice, byPktTyp, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
         }
         else if (pvRTS == NULL) {//RTS_needless, non PCF mode
             //Fill RsvTime
@@ -1278,17 +1240,17 @@ s_vGenerateTxParameter (
             }
         }
     }
-    else if (byPktTyp == PK_TYPE_11B) {
+    else if (byPktType == PK_TYPE_11B) {
 
         if ((pvRTS != NULL)) {//RTS_need, non PCF mode
             //Fill RsvTime
             if (pvRrvTime) {
                 PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
-                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktTyp, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
                 pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
             }
             //Fill RTS
-            s_vFillRTSHead(pDevice, byPktTyp, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
         }
         else { //RTS_needless, non PCF mode
             //Fill RsvTime
@@ -1298,7 +1260,7 @@ s_vGenerateTxParameter (
             }
         }
     }
-    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
 }
 /*
     PBYTE pbyBuffer,//point to pTxBufHead
@@ -1317,7 +1279,7 @@ s_vFillFragParameter(
     )
 {
     PSTxBufHead pTxBufHead = (PSTxBufHead) pbyBuffer;
-    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter...\n");
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter...\n");
 
     if (uTxType == TYPE_SYNCDMA) {
         //PSTxSyncDesc ptdCurr = (PSTxSyncDesc)s_pvGetTxDescHead(pDevice, uTxType, uCurIdx);
@@ -1350,14 +1312,14 @@ s_vFillFragParameter(
 
     pTxBufHead->wFragCtl |= (WORD)wFragType;//0x0001; //0000 0000 0000 0001
 
-    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter END\n");
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vFillFragParameter END\n");
 }
 
 static
 UINT
 s_cbFillTxBufHead (
     IN  PSDevice         pDevice,
-    IN  BYTE             byPktTyp,
+    IN  BYTE             byPktType,
     IN  PBYTE            pbyTxBufferAddr,
     IN  UINT             cbFrameBodySize,
     IN  UINT             uDMAIdx,
@@ -1428,7 +1390,7 @@ s_cbFillTxBufHead (
 
     pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
 
-    //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_cbFillTxBufHead...\n");
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_cbFillTxBufHead...\n");
     if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
         (pDevice->eOPMode == OP_MODE_AP)) {
 
@@ -1504,7 +1466,7 @@ s_cbFillTxBufHead (
     //////////////////////////////////////////////////////
     //Set RrvTime/RTS/CTS Buffer
     wTxBufSize = sizeof(STxBufHead);
-    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {//802.11g packet
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
 
         if (byFBOption == AUTO_FB_NONE) {
             if (bRTS == TRUE) {//RTS_need
@@ -1582,7 +1544,7 @@ s_cbFillTxBufHead (
             }
         } // Auto Fall Back
     }
-    ZERO_MEMORY((PVOID)(pbyTxBufferAddr + wTxBufSize), (cbHeaderLength - wTxBufSize));
+    memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderLength - wTxBufSize));
 
 //////////////////////////////////////////////////////////////////
     if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
@@ -1603,7 +1565,7 @@ s_cbFillTxBufHead (
         MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12);
         dwMIC_Priority = 0;
         MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
     }
 
 ///////////////////////////////////////////////////////////////////
@@ -1633,15 +1595,15 @@ s_cbFillTxBufHead (
                 //=========================
                 //    Start Fragmentation
                 //=========================
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start Fragmentation...\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start Fragmentation...\n");
                 wFragType = FRAGCTL_STAFRAG;
 
 
                 //Fill FIFO,RrvTime,RTS,and CTS
-                s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+                s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
                                        cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
                 //Fill DataHead
-                uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
+                uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
                                             uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
                 // Generate TX MAC Header
                 vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncrypt,
@@ -1663,13 +1625,13 @@ s_cbFillTxBufHead (
                 if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
                     if ((psEthHeader->wType == TYPE_PKT_IPX) ||
                         (psEthHeader->wType == cpu_to_le16(0xF380))) {
-                        MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
+                        memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
                     }
                     else {
-                        MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
+                        memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
                     }
                     pbyType = (PBYTE) (pbyPayloadHead + 6);
-                    MEMvCopy(pbyType, &(psEthHeader->wType), sizeof(WORD));
+                    memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD));
                     cb802_1_H_len = 8;
                 }
 
@@ -1691,16 +1653,16 @@ s_cbFillTxBufHead (
 
                 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
                 //copy TxBufferHeader + MacHeader to desc
-                MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+                memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength);
 
                 // Copy the Packet into a tx Buffer
-                MEMvCopy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len));
+                memcpy((pbyBuffer + uLength), (pPacket + 14), (cbFragPayloadSize - cb802_1_H_len));
 
 
                 uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len;
 
                 if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start MIC: %d\n", cbFragPayloadSize);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Start MIC: %d\n", cbFragPayloadSize);
                     MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize);
 
                 }
@@ -1736,16 +1698,16 @@ s_cbFillTxBufHead (
                 //=========================
                 //    Last Fragmentation
                 //=========================
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last Fragmentation...\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last Fragmentation...\n");
                 //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx];
 
                 wFragType = FRAGCTL_ENDFRAG;
 
                 //Fill FIFO,RrvTime,RTS,and CTS
-                s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+                s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
                                        cbLastFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
                 //Fill DataHead
-                uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK,
+                uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbLastFragmentSize, uDMAIdx, bNeedACK,
                                             uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
 
                 // Generate TX MAC Header
@@ -1778,12 +1740,12 @@ s_cbFillTxBufHead (
                 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
 
                 //copy TxBufferHeader + MacHeader to desc
-                MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+                memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength);
 
                 // Copy the Packet into a tx Buffer
                 if (bMIC2Frag == FALSE) {
 
-                    MEMvCopy((pbyBuffer + uLength),
+                    memcpy((pbyBuffer + uLength),
                              (pPacket + 14 + uTotalCopyLength),
                              (cbLastFragPayloadSize - cbMIClen)
                              );
@@ -1792,7 +1754,7 @@ s_cbFillTxBufHead (
 
                 }
                 if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n",
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n",
                                    uMICFragLen, cbLastFragPayloadSize, uTmpLen);
 
                     if (bMIC2Frag == FALSE) {
@@ -1801,28 +1763,28 @@ s_cbFillTxBufHead (
                         pdwMIC_L = (PDWORD)(pbyBuffer + uLength + uTmpLen);
                         pdwMIC_R = (PDWORD)(pbyBuffer + uLength + uTmpLen + 4);
                         MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Last MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
                     } else {
                         if (uMICFragLen >= 4) {
-                            MEMvCopy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)),
+                            memcpy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)),
                                      (cbMIClen - uMICFragLen));
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen >= 4: %X, %d\n",
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen >= 4: %X, %d\n",
                                            *(PBYTE)((PBYTE)&dwSafeMIC_R + (uMICFragLen - 4)),
                                            (cbMIClen - uMICFragLen));
 
                         } else {
-                            MEMvCopy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_L + uMICFragLen),
+                            memcpy((pbyBuffer + uLength), ((PBYTE)&dwSafeMIC_L + uMICFragLen),
                                      (4 - uMICFragLen));
-                            MEMvCopy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4);
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen < 4: %X, %d\n",
+                            memcpy((pbyBuffer + uLength + (4 - uMICFragLen)), &dwSafeMIC_R, 4);
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LAST: uMICFragLen < 4: %X, %d\n",
                                            *(PBYTE)((PBYTE)&dwSafeMIC_R + uMICFragLen - 4),
                                            (cbMIClen - uMICFragLen));
                         }
                         /*
                         for (ii = 0; ii < cbLastFragPayloadSize + 8 + 24; ii++) {
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii - 8 - 24)));
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii - 8 - 24)));
                         }
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
                         */
                     }
                     MIC_vUnInit();
@@ -1866,16 +1828,16 @@ s_cbFillTxBufHead (
                 //=========================
                 //    Middle Fragmentation
                 //=========================
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle Fragmentation...\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle Fragmentation...\n");
                 //tmpDescIdx = (uDescIdx + uFragIdx) % pDevice->cbTD[uDMAIdx];
 
                 wFragType = FRAGCTL_MIDFRAG;
 
                 //Fill FIFO,RrvTime,RTS,and CTS
-                s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+                s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
                                        cbFragmentSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
                 //Fill DataHead
-                uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
+                uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFragmentSize, uDMAIdx, bNeedACK,
                                             uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption, pDevice->wCurrentRate);
 
                 // Generate TX MAC Header
@@ -1913,10 +1875,10 @@ s_cbFillTxBufHead (
                 uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen;
 
                 //copy TxBufferHeader + MacHeader to desc
-                MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+                memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength);
 
                 // Copy the Packet into a tx Buffer
-                MEMvCopy((pbyBuffer + uLength),
+                memcpy((pbyBuffer + uLength),
                          (pPacket + 14 + uTotalCopyLength),
                          cbFragPayloadSize
                         );
@@ -1939,23 +1901,23 @@ s_cbFillTxBufHead (
                         dwSafeMIC_L = *pdwMIC_L;
                         dwSafeMIC_R = *pdwMIC_R;
 
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n",
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n",
                                        uMICFragLen, cbFragPayloadSize, uTmpLen);
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MIC in Middle frag [%d]\n", uMICFragLen);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MIC in Middle frag [%d]\n", uMICFragLen);
                         /*
                         for (ii = 0; ii < uMICFragLen; ii++) {
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength + uTmpLen) + ii)));
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength + uTmpLen) + ii)));
                         }
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
                         */
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
                     }
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle frag len: %d\n", uTmpLen);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Middle frag len: %d\n", uTmpLen);
                     /*
                     for (ii = 0; ii < uTmpLen; ii++) {
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
                     }
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n\n");
                     */
 
                 } else {
@@ -1994,18 +1956,18 @@ s_cbFillTxBufHead (
         //=========================
         //    No Fragmentation
         //=========================
-        //DEVICE_PRTGRP03(("No Fragmentation...\n"));
-        //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
+        //DBG_PRTGRP03(("No Fragmentation...\n"));
+        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
         wFragType = FRAGCTL_NONFRAG;
 
         //Set FragCtl in TxBufferHead
         psTxBufHd->wFragCtl |= (WORD)wFragType;
 
         //Fill FIFO,RrvTime,RTS,and CTS
-        s_vGenerateTxParameter(pDevice, byPktTyp, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
+        s_vGenerateTxParameter(pDevice, byPktType, (PVOID)psTxBufHd, pvRrvTime, pvRTS, pvCTS,
                                cbFrameSize, bNeedACK, uDMAIdx, psEthHeader, pDevice->wCurrentRate);
         //Fill DataHead
-        uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
+        uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
                                     0, 0, uMACfragNum, byFBOption, pDevice->wCurrentRate);
 
         // Generate TX MAC Header
@@ -2027,13 +1989,13 @@ s_cbFillTxBufHead (
         if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
             if ((psEthHeader->wType == TYPE_PKT_IPX) ||
                 (psEthHeader->wType == cpu_to_le16(0xF380))) {
-                MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
+                memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_Bridgetunnel[0], 6);
             }
             else {
-                MEMvCopy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
+                memcpy((PBYTE) (pbyPayloadHead), &pDevice->abySNAP_RFC1042[0], 6);
             }
             pbyType = (PBYTE) (pbyPayloadHead + 6);
-            MEMvCopy(pbyType, &(psEthHeader->wType), sizeof(WORD));
+            memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD));
             cb802_1_H_len = 8;
         }
 
@@ -2043,7 +2005,7 @@ s_cbFillTxBufHead (
         //---------------------------
         //Fill MICHDR
         //if (pDevice->bAES) {
-        //    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MICHDR...\n");
+        //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Fill MICHDR...\n");
         //    s_vFillMICHDR(pDevice, (PBYTE)pMICHDR, pbyMacHdr, (WORD)cbFrameBodySize);
         //}
 
@@ -2053,22 +2015,22 @@ s_cbFillTxBufHead (
         uLength = cbHeaderLength + cbMACHdLen + uPadding + cbIVlen + cb802_1_H_len;
 
         //copy TxBufferHeader + MacHeader to desc
-        MEMvCopy(pbyBuffer, (PVOID)psTxBufHd, uLength);
+        memcpy(pbyBuffer, (PVOID)psTxBufHd, uLength);
 
         // Copy the Packet into a tx Buffer
-        MEMvCopy((pbyBuffer + uLength),
+        memcpy((pbyBuffer + uLength),
                  (pPacket + 14),
                  cbFrameBodySize - cb802_1_H_len
                  );
 
         if ((bNeedEncrypt == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)){
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength);
             /*
             for (ii = 0; ii < (cbFrameBodySize - cb802_1_H_len); ii++) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *((PBYTE)((pbyBuffer + uLength) + ii)));
             }
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
             */
 
             MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize);
@@ -2086,14 +2048,14 @@ s_cbFillTxBufHead (
                 pDevice->bTxMICFail = FALSE;
             }
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
 /*
             for (ii = 0; ii < 8; ii++) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(((PBYTE)(pdwMIC_L) + ii)));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(((PBYTE)(pdwMIC_L) + ii)));
             }
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
 */
 
         }
@@ -2121,12 +2083,12 @@ s_cbFillTxBufHead (
         pDevice->iTDUsed[uDMAIdx]++;
 
 
-//   DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ptdCurr->m_dwReserved0[%d] ptdCurr->m_dwReserved1[%d].\n", ptdCurr->pTDInfo->dwReqCount, ptdCurr->pTDInfo->dwHeaderLength);
-//   DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cbHeaderLength[%d]\n", cbHeaderLength);
+//   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" ptdCurr->m_dwReserved0[%d] ptdCurr->m_dwReserved1[%d].\n", ptdCurr->pTDInfo->dwReqCount, ptdCurr->pTDInfo->dwHeaderLength);
+//   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cbHeaderLength[%d]\n", cbHeaderLength);
 
     }
     *puMACfragNum = uMACfragNum;
-    //DEVICE_PRTGRP03(("s_cbFillTxBufHead END\n"));
+    //DBG_PRTGRP03(("s_cbFillTxBufHead END\n"));
     return cbHeaderLength;
 }
 
@@ -2134,7 +2096,7 @@ s_cbFillTxBufHead (
 VOID
 vGenerateFIFOHeader (
     IN  PSDevice         pDevice,
-    IN  BYTE             byPktTyp,
+    IN  BYTE             byPktType,
     IN  PBYTE            pbyTxBufferAddr,
     IN  BOOL             bNeedEncrypt,
     IN  UINT             cbPayloadSize,
@@ -2156,7 +2118,7 @@ vGenerateFIFOHeader (
 
     wTxBufSize = sizeof(STxBufHead);
 
-    ZERO_MEMORY(pTxBufHead, wTxBufSize);
+    memset(pTxBufHead, 0, wTxBufSize);
     //Set FIFOCTL_NEEDACK
 
     if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
@@ -2206,16 +2168,16 @@ vGenerateFIFOHeader (
     pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10));
 
     //Set packet type
-    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
+    if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
         ;
     }
-    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+    else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
     }
-    else if (byPktTyp == PK_TYPE_11GB) {//0000 0010 0000 0000
+    else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
     }
-    else if (byPktTyp == PK_TYPE_11GA) {//0000 0011 0000 0000
+    else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
     }
     //Set FIFOCTL_GrpAckPolicy
@@ -2273,7 +2235,7 @@ vGenerateFIFOHeader (
     if(pDevice->bEnableHostWEP)
         pTxBufHead->wFragCtl &=  ~(FRAGCTL_TKIP | FRAGCTL_LEGACY |FRAGCTL_AES);
 */
-    *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktTyp, pbyTxBufferAddr, cbPayloadSize,
+    *pcbHeaderSize = s_cbFillTxBufHead(pDevice, byPktType, pbyTxBufferAddr, cbPayloadSize,
                                    uDMAIdx, pHeadTD, psEthHeader, pPacket, bNeedEncrypt,
                                    pTransmitKey, uNodeIndex, puMACfragNum);
 
@@ -2316,7 +2278,7 @@ vGenerateMACHeader (
 {
     PS802_11Header  pMACHeader = (PS802_11Header)pbyBufferAddr;
 
-    ZERO_MEMORY(pMACHeader, (sizeof(S802_11Header)));  //- sizeof(pMACHeader->dwIV)));
+    memset(pMACHeader, 0, (sizeof(S802_11Header)));  //- sizeof(pMACHeader->dwIV)));
 
     if (uDMAIdx == TYPE_ATIMDMA) {
     	pMACHeader->wFrameCtl = TYPE_802_11_ATIM;
@@ -2325,21 +2287,21 @@ vGenerateMACHeader (
     }
 
     if (pDevice->eOPMode == OP_MODE_AP) {
-        MEMvCopy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
-        MEMvCopy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
-        MEMvCopy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+        memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+        memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
         pMACHeader->wFrameCtl |= FC_FROMDS;
     }
     else {
         if (pDevice->eOPMode == OP_MODE_ADHOC) {
-            MEMvCopy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
-            MEMvCopy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
-            MEMvCopy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
         }
         else {
-            MEMvCopy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
-            MEMvCopy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
-            MEMvCopy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
             pMACHeader->wFrameCtl |= FC_TODS;
         }
     }
@@ -2352,7 +2314,7 @@ vGenerateMACHeader (
     if (pDevice->bLongHeader) {
         PWLAN_80211HDR_A4 pMACA4Header  = (PWLAN_80211HDR_A4) pbyBufferAddr;
         pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
-        MEMvCopy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
+        memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
     }
     pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
 
@@ -2378,7 +2340,7 @@ vGenerateMACHeader (
 CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
     PSTxDesc        pFrstTD;
-    BYTE            byPktTyp;
+    BYTE            byPktType;
     PBYTE           pbyTxBufferAddr;
     PVOID           pvRTS;
     PSCTS           pCTS;
@@ -2419,10 +2381,10 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
     if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
         wCurrentRate = RATE_6M;
-        byPktTyp = PK_TYPE_11A;
+        byPktType = PK_TYPE_11A;
     } else {
         wCurrentRate = RATE_1M;
-        byPktTyp = PK_TYPE_11B;
+        byPktType = PK_TYPE_11B;
     }
 
     // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
@@ -2440,21 +2402,21 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     if (pDevice->byFOETuning) {
         if ((pPacket->p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
             wCurrentRate = RATE_24M;
-            byPktTyp = PK_TYPE_11GA;
+            byPktType = PK_TYPE_11GA;
         }
     }
 
     //Set packet type
-    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
+    if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
         pTxBufHead->wFIFOCtl = 0;
     }
-    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+    else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
     }
-    else if (byPktTyp == PK_TYPE_11GB) {//0000 0010 0000 0000
+    else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
     }
-    else if (byPktTyp == PK_TYPE_11GA) {//0000 0011 0000 0000
+    else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
     }
 
@@ -2536,7 +2498,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
 
     //Set RrvTime/RTS/CTS Buffer
-    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {//802.11g packet
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
 
         pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
         pMICHDR = NULL;
@@ -2554,10 +2516,10 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
         cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
     }
 
-    ZERO_MEMORY((PVOID)(pbyTxBufferAddr + wTxBufSize), (cbHeaderSize - wTxBufSize));
+    memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
 
-    MEMvCopy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
-    MEMvCopy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
+    memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
+    memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
     //=========================
     //    No Fragmentation
     //=========================
@@ -2565,11 +2527,11 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
 
     //Fill FIFO,RrvTime,RTS,and CTS
-    s_vGenerateTxParameter(pDevice, byPktTyp, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
+    s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
                            cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
 
     //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+    uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
                                 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
 
     pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
@@ -2606,11 +2568,11 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
                 if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
                     // get group key
                     if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
                         break;
                     }
                 } else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
                     break;
                 }
             }
@@ -2618,22 +2580,22 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
             pbyBSSID = pDevice->abyBroadcastAddr;
             if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
                 pTransmitKey = NULL;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
             } else {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
             }
         } while(FALSE);
         //Fill TXKEY
         s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
                      (PBYTE)pMACHeader, (WORD)cbFrameBodySize, NULL);
 
-        MEMvCopy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
-        MEMvCopy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen),
+        memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
+        memcpy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen),
                  cbFrameBodySize);
     }
     else {
         // Copy the Packet into a tx Buffer
-        MEMvCopy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+        memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
     }
 
     pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
@@ -2647,7 +2609,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
         // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
-        if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
             ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
             ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
         } else {
@@ -2677,7 +2639,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
     pDevice->iTDUsed[TYPE_TXDMA0]++;
 
     if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
     }
 
     pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
@@ -2699,7 +2661,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
 CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
-    BYTE             byPktTyp;
+    BYTE             byPktType;
     PBYTE            pbyBuffer = (PBYTE)pDevice->tx_beacon_bufs;
     UINT             cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
     UINT             cbHeaderSize = 0;
@@ -2715,10 +2677,10 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
     if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
         wCurrentRate = RATE_6M;
-        byPktTyp = PK_TYPE_11A;
+        byPktType = PK_TYPE_11A;
     } else {
         wCurrentRate = RATE_2M;
-        byPktTyp = PK_TYPE_11B;
+        byPktType = PK_TYPE_11B;
     }
 
     //Set Preamble type always long
@@ -2730,17 +2692,17 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
 
     //Set packet type & Get Duration
-    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
-        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktTyp,
+    if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
+        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, byPktType,
                                                           wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
     }
-    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+    else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
-        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktTyp,
+        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, byPktType,
                                                           wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
     }
 
-    BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktTyp,
+    BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, byPktType,
         (PWORD)&(wLen), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField)
     );
     pTxDataHead->wTransmitLength = cpu_to_le16(wLen);
@@ -2750,7 +2712,7 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) {
 
    //Generate Beacon Header
     pMACHeader = (PS802_11Header)(pbyBuffer + cbHeaderSize);
-    MEMvCopy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+    memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
 
     pMACHeader->wDurationID = 0;
     pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
@@ -2867,7 +2829,7 @@ VOID
 vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDULen) {
 
     PSTxDesc        pFrstTD;
-    BYTE            byPktTyp;
+    BYTE            byPktType;
     PBYTE           pbyTxBufferAddr;
     PVOID           pvRTS;
     PVOID           pvCTS;
@@ -2931,10 +2893,10 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
     if (pDevice->eCurrentPHYType == PHY_TYPE_11A) {
         wCurrentRate = RATE_6M;
-        byPktTyp = PK_TYPE_11A;
+        byPktType = PK_TYPE_11A;
     } else {
         wCurrentRate = RATE_1M;
-        byPktTyp = PK_TYPE_11B;
+        byPktType = PK_TYPE_11B;
     }
 
     // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
@@ -2952,23 +2914,23 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
     if (pDevice->byFOETuning) {
         if ((p80211Header->sA3.wFrameCtl & TYPE_DATE_NULL) == TYPE_DATE_NULL) {
             wCurrentRate = RATE_24M;
-            byPktTyp = PK_TYPE_11GA;
+            byPktType = PK_TYPE_11GA;
         }
     }
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
 
     //Set packet type
-    if (byPktTyp == PK_TYPE_11A) {//0000 0000 0000 0000
+    if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
         pTxBufHead->wFIFOCtl = 0;
     }
-    else if (byPktTyp == PK_TYPE_11B) {//0000 0001 0000 0000
+    else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
     }
-    else if (byPktTyp == PK_TYPE_11GB) {//0000 0010 0000 0000
+    else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
     }
-    else if (byPktTyp == PK_TYPE_11GA) {//0000 0011 0000 0000
+    else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
         pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
     }
 
@@ -3078,7 +3040,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
     //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
 
 
-    if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {//802.11g packet
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
 
         pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
         pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
@@ -3099,9 +3061,9 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
     }
 
-    ZERO_MEMORY((PVOID)(pbyTxBufferAddr + wTxBufSize), (cbHeaderSize - wTxBufSize));
-    MEMvCopy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
-    MEMvCopy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
+    memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
+    memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
+    memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
     //=========================
     //    No Fragmentation
     //=========================
@@ -3109,11 +3071,11 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
 
 
     //Fill FIFO,RrvTime,RTS,and CTS
-    s_vGenerateTxParameter(pDevice, byPktTyp, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
+    s_vGenerateTxParameter(pDevice, byPktType, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
                            cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader, wCurrentRate);
 
     //Fill DataHead
-    uDuration = s_uFillDataHead(pDevice, byPktTyp, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+    uDuration = s_uFillDataHead(pDevice, byPktType, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
                                 0, 0, 1, AUTO_FB_NONE, wCurrentRate);
 
     pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
@@ -3173,7 +3135,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
             MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12);
             dwMIC_Priority = 0;
             MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
 
             uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
 
@@ -3191,9 +3153,9 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
                 pDevice->bTxMICFail = FALSE;
             }
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
 
         }
 
@@ -3223,7 +3185,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
         // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
         // in the same place of other packet's Duration-field).
         // And it will cause Cisco-AP to issue Disassociation-packet
-        if (byPktTyp == PK_TYPE_11GB || byPktTyp == PK_TYPE_11GA) {
+        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
             ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
             ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
         } else {
@@ -3255,7 +3217,7 @@ vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb, PBYTE pbMPDU, UINT cbMPDU
     pDevice->iTDUsed[TYPE_TXDMA0]++;
 
     if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n");
     }
 
     pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next;
diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h
index 3e85264..17bd1b1 100644
--- a/drivers/staging/vt6655/rxtx.h
+++ b/drivers/staging/vt6655/rxtx.h
@@ -16,7 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * File: whdr.h
+ * File: rxtx.h
  *
  * Purpose:
  *
@@ -26,20 +26,12 @@
  *
  */
 
-
 #ifndef __RXTX_H__
 #define __RXTX_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c
index 655d685..5a7c6ca 100644
--- a/drivers/staging/vt6655/srom.c
+++ b/drivers/staging/vt6655/srom.c
@@ -42,28 +42,11 @@
  *
  */
 
-
-#if !defined(__UPC_H__)
 #include "upc.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__SROM_H__)
 #include "srom.h"
-#endif
-
-
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -113,12 +96,12 @@ BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset)
         // wait DONE be set
         for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) {
             VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
-            if (BITbIsAnyBitsOn(byWait, (I2MCSR_DONE | I2MCSR_NACK)))
+            if (byWait & (I2MCSR_DONE | I2MCSR_NACK))
                 break;
             PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
         }
         if ((wDelay < W_MAX_TIMEOUT) &&
-             (BITbIsBitOff(byWait, I2MCSR_NACK))) {
+             ( !(byWait & I2MCSR_NACK))) {
             break;
         }
     }
@@ -162,13 +145,13 @@ BOOL SROMbWriteEmbedded (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData)
         // wait DONE be set
         for (wDelay = 0; wDelay < W_MAX_TIMEOUT; wDelay++) {
             VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
-            if (BITbIsAnyBitsOn(byWait, (I2MCSR_DONE | I2MCSR_NACK)))
+            if (byWait & (I2MCSR_DONE | I2MCSR_NACK))
                 break;
             PCAvDelayByIO(CB_DELAY_LOOP_WAIT);
         }
 
         if ((wDelay < W_MAX_TIMEOUT) &&
-             (BITbIsBitOff(byWait, I2MCSR_NACK))) {
+             ( !(byWait & I2MCSR_NACK))) {
             break;
         }
     }
@@ -244,7 +227,7 @@ BOOL SROMbIsRegBitsOn (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits)
     BYTE    byOrgData;
 
     byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
-    return BITbIsAllBitsOn(byOrgData, byTestBits);
+    return (byOrgData & byTestBits) == byTestBits;
 }
 
 
@@ -267,7 +250,7 @@ BOOL SROMbIsRegBitsOff (DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byTestBits
     BYTE    byOrgData;
 
     byOrgData = SROMbyReadEmbedded(dwIoBase, byContntOffset);
-    return BITbIsAllBitsOff(byOrgData, byTestBits);
+    return !(byOrgData & byTestBits);
 }
 
 
@@ -423,7 +406,7 @@ BOOL SROMbAutoLoad (DWORD_PTR dwIoBase)
     for (ii = 0; ii < EEP_MAX_CONTEXT_SIZE; ii++) {
         MACvTimer0MicroSDelay(dwIoBase, CB_EEPROM_READBYTE_WAIT);
         VNSvInPortB(dwIoBase + MAC_REG_I2MCSR, &byWait);
-        if (BITbIsBitOff(byWait, I2MCSR_AUTOLD))
+        if ( !(byWait & I2MCSR_AUTOLD))
             break;
     }
 
diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h
index a4ca5f0..ba123ee 100644
--- a/drivers/staging/vt6655/srom.h
+++ b/drivers/staging/vt6655/srom.h
@@ -27,18 +27,13 @@
  *
  */
 
-
 #ifndef __SROM_H__
 #define __SROM_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
-
 #define EEP_MAX_CONTEXT_SIZE    256
 
 #define CB_EEPROM_READBYTE_WAIT 900     //us
@@ -48,7 +43,6 @@
 //
 // Contents in the EEPROM
 //
-
 #define EEP_OFS_PAR         0x00        // physical address
 #define EEP_OFS_ANTENNA     0x16
 #define EEP_OFS_RADIOCTL    0x17
@@ -97,8 +91,6 @@
 #define EEP_RADIOCTL_ENABLE 0x80
 #define EEP_RADIOCTL_INV    0x01
 
-
-
 /*---------------------  Export Types  ------------------------------*/
 
 // AT24C02 eeprom contents
@@ -133,7 +125,7 @@ typedef struct tagSSromReg {
 
     BYTE    abyReserved0[96];           // 0x10 (WORD)
     BYTE    abyCIS[128];                // 0x80 (WORD)
-} SSromReg, DEF* PSSromReg;
+} SSromReg, *PSSromReg;
 
 /*---------------------  Export Macros ------------------------------*/
 
@@ -142,10 +134,6 @@ typedef struct tagSSromReg {
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 
 BYTE SROMbyReadEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset);
 BOOL SROMbWriteEmbedded(DWORD_PTR dwIoBase, BYTE byContntOffset, BYTE byData);
@@ -166,14 +154,4 @@ VOID SROMvReadSubSysVenId(DWORD_PTR dwIoBase, PDWORD pdwSubSysVenId);
 
 BOOL SROMbAutoLoad (DWORD_PTR dwIoBase);
 
-
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __EEPROM_H__
-
-
diff --git a/drivers/staging/vt6655/tbit.h b/drivers/staging/vt6655/tbit.h
deleted file mode 100644
index 7c3a82e..0000000
--- a/drivers/staging/vt6655/tbit.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: tbit.h
- *
- * Purpose: Bit routines
- *
- * Author: Tevin Chen
- *
- * Date: May 21, 1996
- *
- */
-
-
-#ifndef __TBIT_H__
-#define __TBIT_H__
-
-#if !defined(__TTYPE_H__)
-#include "ttype.h"
-#endif
-
-
-
-/*---------------------  Export Definitions -------------------------*/
-
-/*---------------------  Export Types  ------------------------------*/
-
-/*---------------------  Export Macros ------------------------------*/
-
-// test single bit on
-#define BITbIsBitOn(tData, tTestBit)                \
-    (((tData) & (tTestBit)) != 0)
-
-// test single bit off
-#define BITbIsBitOff(tData, tTestBit)               \
-    (((tData) & (tTestBit)) == 0)
-
-
-#define BITbIsAllBitsOn(tData, tTestBit)            \
-    (((tData) & (tTestBit)) == (tTestBit))
-
-#define BITbIsAllBitsOff(tData, tTestBit)           \
-    (((tData) & (tTestBit)) == 0)
-
-#define BITbIsAnyBitsOn(tData, tTestBit)            \
-    (((tData) & (tTestBit)) != 0)
-
-#define BITbIsAnyBitsOff(tData, tTestBit)           \
-    (((tData) & (tTestBit)) != (tTestBit))
-
-/*---------------------  Export Classes  ----------------------------*/
-
-/*---------------------  Export Variables  --------------------------*/
-
-/*---------------------  Export Functions  --------------------------*/
-
-
-
-#endif // __TBIT_H__
-
-
-
diff --git a/drivers/staging/vt6655/tcrc.c b/drivers/staging/vt6655/tcrc.c
index b70080c..5f0c747 100644
--- a/drivers/staging/vt6655/tcrc.c
+++ b/drivers/staging/vt6655/tcrc.c
@@ -33,16 +33,7 @@
  *
  */
 
-
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__TCRC_H__)
 #include "tcrc.h"
-#endif
-
-
-
 
 /*---------------------  Static Definitions -------------------------*/
 
diff --git a/drivers/staging/vt6655/tcrc.h b/drivers/staging/vt6655/tcrc.h
index ebea22e..5faa48b 100644
--- a/drivers/staging/vt6655/tcrc.h
+++ b/drivers/staging/vt6655/tcrc.h
@@ -26,16 +26,10 @@
  *
  */
 
-
 #ifndef __TCRC_H__
 #define __TCRC_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -48,23 +42,11 @@
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 
 DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed);
 DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte);
 DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC);
 
-
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __TCRC_H__
 
 
diff --git a/drivers/staging/vt6655/tether.c b/drivers/staging/vt6655/tether.c
index fd69423..c90b469 100644
--- a/drivers/staging/vt6655/tether.c
+++ b/drivers/staging/vt6655/tether.c
@@ -32,24 +32,10 @@
  *
  */
 
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__TCRC_H__)
 #include "tcrc.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-
-
-
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -87,7 +73,7 @@ BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr)
     // reverse most bit to least bit
     for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) {
         byHash <<= 1;
-        if (BITbIsBitOn(byTmpHash, 0x01))
+        if (byTmpHash & 0x01)
             byHash |= 1;
         byTmpHash >>= 1;
     }
diff --git a/drivers/staging/vt6655/tether.h b/drivers/staging/vt6655/tether.h
index 920a8bb..5a3c326 100644
--- a/drivers/staging/vt6655/tether.h
+++ b/drivers/staging/vt6655/tether.h
@@ -26,18 +26,10 @@
  *
  */
 
-
-
 #ifndef __TETHER_H__
 #define __TETHER_H__
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 //
@@ -179,7 +171,7 @@ typedef struct tagSEthernetHeader {
     BYTE    abySrcAddr[U_ETHER_ADDR_LEN];
     WORD    wType;
 }__attribute__ ((__packed__))
-SEthernetHeader, DEF* PSEthernetHeader;
+SEthernetHeader, *PSEthernetHeader;
 
 
 //
@@ -190,7 +182,7 @@ typedef struct tagS802_3Header {
     BYTE    abySrcAddr[U_ETHER_ADDR_LEN];
     WORD    wLen;
 }__attribute__ ((__packed__))
-S802_3Header, DEF* PS802_3Header;
+S802_3Header, *PS802_3Header;
 
 //
 // 802_11 packet
@@ -204,7 +196,7 @@ typedef struct tagS802_11Header {
     WORD    wSeqCtl;
     BYTE    abyAddr4[U_ETHER_ADDR_LEN];
 }__attribute__ ((__packed__))
-S802_11Header, DEF* PS802_11Header;
+S802_11Header, *PS802_11Header;
 
 /*---------------------  Export Macros ------------------------------*/
 // Frame type macro
@@ -233,23 +225,11 @@ S802_11Header, DEF* PS802_11Header;
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 
 BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr);
 //BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr);
 BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength);
 
-
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __TETHER_H__
 
 
diff --git a/drivers/staging/vt6655/tkip.c b/drivers/staging/vt6655/tkip.c
index 2ded842..8ca1540 100644
--- a/drivers/staging/vt6655/tkip.c
+++ b/drivers/staging/vt6655/tkip.c
@@ -32,20 +32,8 @@
  *
  */
 
-
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__TKIP_H__)
 #include "tkip.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-
 
 /*---------------------  Static Definitions -------------------------*/
 
diff --git a/drivers/staging/vt6655/tkip.h b/drivers/staging/vt6655/tkip.h
index dc8382b..847ecdf 100644
--- a/drivers/staging/vt6655/tkip.h
+++ b/drivers/staging/vt6655/tkip.h
@@ -27,19 +27,11 @@
  *
  */
 
-
 #ifndef __TKIP_H__
 #define __TKIP_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 #define TKIP_KEY_LEN        16
@@ -53,9 +45,6 @@
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 VOID TKIPvMixKey(
     PBYTE   pbyTKey,
@@ -65,11 +54,6 @@ VOID TKIPvMixKey(
     PBYTE   pbyRC4Key
     );
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif // __TKIP_H__
 
 
diff --git a/drivers/staging/vt6655/tmacro.h b/drivers/staging/vt6655/tmacro.h
index 3d932a2..e96c140 100644
--- a/drivers/staging/vt6655/tmacro.h
+++ b/drivers/staging/vt6655/tmacro.h
@@ -26,27 +26,13 @@
  *
  */
 
-
 #ifndef __TMACRO_H__
 #define __TMACRO_H__
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-
-
-
 
 /****** Common helper macros ***********************************************/
 
-#if !defined(LONIBBLE)
-#define LONIBBLE(b)         ((BYTE)(b) & 0x0F)
-#endif
-#if !defined(HINIBBLE)
-#define HINIBBLE(b)         ((BYTE)(((WORD)(b) >> 4) & 0x0F))
-#endif
-
 #if !defined(LOBYTE)
 #define LOBYTE(w)           ((BYTE)(w))
 #endif
@@ -64,88 +50,12 @@
 #define LODWORD(q)          ((q).u.dwLowDword)
 #define HIDWORD(q)          ((q).u.dwHighDword)
 
-
-
-#if !defined(MAKEBYTE)
-#define MAKEBYTE(ln, hn)    ((BYTE)(((BYTE)(ln) & 0x0F) | ((BYTE)(hn) << 4)))
-#endif
 #if !defined(MAKEWORD)
 #define MAKEWORD(lb, hb)    ((WORD)(((BYTE)(lb)) | (((WORD)((BYTE)(hb))) << 8)))
 #endif
 #if !defined(MAKEDWORD)
 #define MAKEDWORD(lw, hw)   ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16)))
 #endif
-#if !defined(MAKEQWORD)
-#define MAKEQWORD(ld, hd, pq) {pq->u.dwLowDword = ld; pq->u.dwHighDword = hd;}
-#endif
-
-#if !defined(MAKELONG)
-#define MAKELONG(low, high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16)))
-#endif
-
-
-
-// Bytes Reverse: big endian to little endian convert
-#if !defined(REVWORD)
-#define REVWORD(w) ((WORD)( ((WORD)(w) >> 8) | ((WORD)(w) << 8) ))
-#endif
-#if !defined(REVDWORD)
-#define REVDWORD(d) (MAKEDWORD(MAKEWORD(HIBYTE(HIWORD(d)),LOBYTE(HIWORD(d))),MAKEWORD(HIBYTE(LOWORD(d)),LOBYTE(LOWORD(d)))))
-#endif
-
-/* map to known network names */
-/*
-#define ntohs(x)        REVWORD(x)
-#define ntohl(x)        REVDWORD(x)
-#define htons(x)        REVWORD(x)
-#define htonl(x)        REVDWORD(x)
-*/
-
-
-/*
-#ifndef NOMINMAX
-#ifndef max
-#define max(a,b)            (((a) > (b)) ? (a) : (b))
-#endif
-#ifndef min
-#define min(a,b)            (((a) < (b)) ? (a) : (b))
-#endif
-#endif // NOMINMAX
-*/
-
-
-
-/****** Misc macros ********************************************************/
-
-// get the field offset in the type(struct, class, ...)
-#define OFFSET(type, field) ((int)(&((type NEAR*)1)->field)-1)
-
-
-/* string equality shorthand */
-#define STR_EQ(x, y)        (strcmp(x, y) == 0)
-#define STR_NE(x, y)        (strcmp(x, y) != 0)
-
-
-// calculate element # of array
-#define ELEMENT_NUM(array)  (sizeof(array) / sizeof(array[0]))
-//#define ARRAY_SIZE(a)       (sizeof(a) / sizeof(a[0]))
-
-
-// null statement
-#define NULL_FUNC()
-
-
-/* Since not all compilers support structure assignment, the ASSIGN()
- * macro is used. This controls how it's actually implemented.
- */
-#ifdef	NOSTRUCTASSIGN	/* Version for old compilers that don't support it */
-#define	ASSIGN(a,b)	memcpy((char *)&(a),(char *)&(b),sizeof(b);
-#else			/* Version for compilers that do */
-#define	ASSIGN(a,b)	((a) = (b))
-#endif
-
-
-
 
 #endif // __TMACRO_H__
 
diff --git a/drivers/staging/vt6655/tpci.h b/drivers/staging/vt6655/tpci.h
deleted file mode 100644
index 4a1c8ed..0000000
--- a/drivers/staging/vt6655/tpci.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: tpci.h
- *
- * Purpose: PCI routines
- *
- * Author: Tevin Chen
- *
- * Date: May 21, 1996
- *
- */
-
-
-#ifndef __TPCI_H__
-#define __TPCI_H__
-
-#if !defined(__TTYPE_H__)
-#include "ttype.h"
-#endif
-
-
-
-
-/*---------------------  Export Definitions -------------------------*/
-#define MAX_PCI_BUS             4       // max. # of PCI bus that we support
-#define MAX_PCI_DEVICE          32      // max. # of PCI devices
-
-
-//
-// Registers in the PCI configuration space
-//
-#define PCI_REG_VENDOR_ID       0x00    //
-#define PCI_REG_DEVICE_ID       0x02    //
-#define PCI_REG_COMMAND         0x04    //
-#define PCI_REG_STATUS          0x06    //
-#define PCI_REG_REV_ID          0x08    //
-#define PCI_REG_CLASS_CODE      0x09    //
-#define PCI_REG_CACHELINE_SIZE  0x0C    //
-#define PCI_REG_LAT_TIMER       0x0D    //
-#define PCI_REG_HDR_TYPE        0x0E    //
-#define PCI_REG_BIST            0x0F    //
-
-#define PCI_REG_BAR0            0x10    //
-#define PCI_REG_BAR1            0x14    //
-#define PCI_REG_BAR2            0x18    //
-#define PCI_REG_CARDBUS_CIS_PTR 0x28    //
-
-#define PCI_REG_SUB_VEN_ID      0x2C    //
-#define PCI_REG_SUB_SYS_ID      0x2E    //
-#define PCI_REG_EXP_ROM_BAR     0x30    //
-#define PCI_REG_CAP             0x34    //
-
-#define PCI_REG_INT_LINE        0x3C    //
-#define PCI_REG_INT_PIN         0x3D    //
-#define PCI_REG_MIN_GNT         0x3E    //
-#define PCI_REG_MAX_LAT         0x3F    //
-
-#define PCI_REG_MAX_SIZE        0x100   // maximun total PCI registers
-
-
-//
-// Bits in the COMMAND register
-//
-#define COMMAND_BUSM        0x04        //
-#define COMMAND_WAIT        0x80        //
-
-/*---------------------  Export Types  ------------------------------*/
-
-/*---------------------  Export Macros ------------------------------*/
-
-// macro MAKE Bus Dev Fun ID into WORD
-#define MAKE_BDF_TO_WORD(byBusId, byDevId, byFunId) \
-    MAKEWORD(                                       \
-        ((((BYTE)(byDevId)) & 0x1F) << 3) +         \
-            (((BYTE)(byFunId)) & 0x07),             \
-        (byBusId)                                   \
-        )
-
-#define GET_BUSID(wBusDevFunId) \
-    HIBYTE(wBusDevFunId)
-
-#define GET_DEVID(wBusDevFunId) \
-    (LOBYTE(wBusDevFunId) >> 3)
-
-#define GET_FUNID(wBusDevFunId) \
-    (LOBYTE(wBusDevFunId) & 0x07)
-
-
-/*---------------------  Export Classes  ----------------------------*/
-
-/*---------------------  Export Variables  --------------------------*/
-
-/*---------------------  Export Functions  --------------------------*/
-
-
-
-
-#endif // __TPCI_H__
-
-
diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h
index 1f26702..4dfad04 100644
--- a/drivers/staging/vt6655/ttype.h
+++ b/drivers/staging/vt6655/ttype.h
@@ -1,5 +1,6 @@
 /*
- * File: ttype.h
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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
@@ -15,6 +16,8 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ * File: ttype.h
+ *
  * Purpose: define basic common types and macros
  *
  * Author: Tevin Chen
@@ -34,14 +37,6 @@
 #define VOID            void
 #endif
 
-#ifndef CONST
-#define CONST           const
-#endif
-
-#ifndef STATIC
-#define STATIC          static
-#endif
-
 #ifndef IN
 #define IN
 #endif
@@ -53,11 +48,8 @@
 #ifndef TxInSleep
 #define TxInSleep
 #endif
-#if! defined(__CPU8051)
+
 typedef int             BOOL;
-#else   // __CPU8051
-#define BOOL            int
-#endif  // __CPU8051
 
 #if !defined(TRUE)
 #define TRUE            1
@@ -70,9 +62,6 @@ typedef int             BOOL;
 #if !defined(SUCCESS)
 #define SUCCESS         0
 #endif
-#if !defined(FAILED)
-#define FAILED          -1
-#endif
 
 //2007-0809-01<Add>by MikeLiu
 #ifndef  update_BssList
@@ -95,28 +84,18 @@ typedef int             BOOL;
 
 /****** Simple typedefs  ***************************************************/
 
-#if! defined(__CPU8051)
-
 /* These lines assume that your compiler's longs are 32 bits and
  * shorts are 16 bits. It is already assumed that chars are 8 bits,
  * but it doesn't matter if they're signed or unsigned.
  */
 
 typedef signed char             I8;     /* 8-bit signed integer */
-typedef signed short            I16;    /* 16-bit signed integer */
-typedef signed long             I32;    /* 32-bit signed integer */
 
 typedef unsigned char           U8;     /* 8-bit unsigned integer */
 typedef unsigned short          U16;    /* 16-bit unsigned integer */
 typedef unsigned long           U32;    /* 32-bit unsigned integer */
 
 
-#if defined(__WIN32)
-typedef signed __int64          I64;    /* 64-bit signed integer */
-typedef unsigned __int64        U64;    /* 64-bit unsigned integer */
-#endif // __WIN32
-
-
 typedef char            CHAR;
 typedef signed short    SHORT;
 typedef signed int      INT;
@@ -127,7 +106,6 @@ typedef unsigned short  USHORT;
 typedef unsigned int    UINT;
 typedef unsigned long   ULONG;
 typedef unsigned long long	ULONGLONG; //64 bit
-typedef unsigned long long	ULONGULONG;
 
 
 
@@ -147,170 +125,23 @@ typedef union tagUQuadWord {
 } UQuadWord;
 typedef UQuadWord       QWORD;          // 64-bit
 
-
-
-#ifndef _TCHAR_DEFINED
-typedef char            TCHAR;
-typedef char*           PTCHAR;
-typedef unsigned char   TBYTE;
-typedef unsigned char*  PTBYTE;
-#define _TCHAR_DEFINED
-#endif
-
-#else   // __CPU8051
-
-#define U8              unsigned char
-#define U16             unsigned short
-#define U32             unsigned long
-
-#define USHORT          unsigned short
-#define UINT            unsigned int
-
-#define BYTE            unsigned char
-#define WORD            unsigned short
-#define DWORD           unsigned long
-
-
-#endif  // __CPU8051
-
-
-// maybe this should be defined in <limits.h>
-#define U8_MAX          0xFFU
-#define U16_MAX         0xFFFFU
-#define U32_MAX         0xFFFFFFFFUL
-
-#define BYTE_MAX        0xFFU
-#define WORD_MAX        0xFFFFU
-#define DWORD_MAX       0xFFFFFFFFUL
-
-
-
-
-/******* 32-bit vs. 16-bit definitions and typedefs ************************/
-
-#if !defined(NULL)
-#ifdef __cplusplus
-#define NULL            0
-#else
-#define NULL            ((void *)0)
-#endif // __cplusplus
-#endif // !NULL
-
-
-
-
-#if defined(__WIN32) || defined(__CPU8051)
-
-#if !defined(FAR)
-#define FAR
-#endif
-#if !defined(NEAR)
-#define NEAR
-#endif
-#if !defined(DEF)
-#define DEF
-#endif
-#if !defined(CALLBACK)
-#define CALLBACK
-#endif
-
-#else  // !__WIN32__
-
-#if !defined(FAR)
-#define FAR
-#endif
-#if !defined(NEAR)
-#define NEAR
-#endif
-#if !defined(DEF)
-// default pointer type is FAR, if you want near pointer just redefine it to NEAR
-#define DEF
-#endif
-#if !defined(CALLBACK)
-#define CALLBACK
-#endif
-
-#endif // !__WIN32__
-
-
-
-
 /****** Common pointer types ***********************************************/
 
-#if! defined(__CPU8051)
+typedef unsigned long   ULONG_PTR;      // 32-bit
+typedef unsigned long   DWORD_PTR;      // 32-bit
 
-typedef signed char DEF*        PI8;
-typedef signed short DEF*       PI16;
-typedef signed long DEF*        PI32;
+// boolean pointer
+typedef unsigned int *   PUINT;
 
-typedef unsigned char DEF*      PU8;
-typedef unsigned short DEF*     PU16;
-typedef unsigned long DEF*      PU32;
+typedef BYTE *           PBYTE;
 
-#if defined(__WIN32)
-typedef signed __int64 DEF*     PI64;
-typedef unsigned __int64 DEF*   PU64;
-#endif // __WIN32
+typedef WORD *           PWORD;
 
-#if !defined(_WIN64)
-typedef unsigned long   ULONG_PTR;      // 32-bit
-typedef unsigned long   DWORD_PTR;      // 32-bit
-#endif // _WIN64
+typedef DWORD *          PDWORD;
 
+typedef QWORD *          PQWORD;
 
-// boolean pointer
-typedef int DEF*            PBOOL;
-typedef int NEAR*           NPBOOL;
-typedef int FAR*            LPBOOL;
-
-typedef int DEF*            PINT;
-typedef int NEAR*           NPINT;
-typedef int FAR*            LPINT;
-typedef const int DEF*      PCINT;
-typedef const int NEAR*     NPCINT;
-typedef const int FAR*      LPCINT;
-
-typedef unsigned int DEF*           PUINT;
-typedef const unsigned int DEF*     PCUINT;
-
-typedef long DEF*           PLONG;
-typedef long NEAR*          NPLONG;
-typedef long FAR*           LPLONG;
-//typedef const long DEF*     PCLONG;
-typedef const long NEAR*    NPCLONG;
-typedef const long FAR*     LPCLONG;
-
-typedef BYTE DEF*           PBYTE;
-typedef BYTE NEAR*          NPBYTE;
-typedef BYTE FAR*           LPBYTE;
-typedef const BYTE DEF*     PCBYTE;
-typedef const BYTE NEAR*    NPCBYTE;
-typedef const BYTE FAR*     LPCBYTE;
-
-typedef WORD DEF*           PWORD;
-typedef WORD NEAR*          NPWORD;
-typedef WORD FAR*           LPWORD;
-typedef const WORD DEF*     PCWORD;
-typedef const WORD NEAR*    NPCWORD;
-typedef const WORD FAR*     LPCWORD;
-
-typedef DWORD DEF*          PDWORD;
-typedef DWORD NEAR*         NPDWORD;
-typedef DWORD FAR*          LPDWORD;
-typedef const DWORD DEF*    PCDWORD;
-typedef const DWORD NEAR*   NPCDWORD;
-typedef const DWORD FAR*    LPCDWORD;
-
-typedef QWORD DEF*          PQWORD;
-typedef QWORD NEAR*         NPQWORD;
-typedef QWORD FAR*          LPQWORD;
-typedef const QWORD DEF*    PCQWORD;
-typedef const QWORD NEAR*   NPCQWORD;
-typedef const QWORD FAR*    LPCQWORD;
-
-typedef void DEF*           PVOID;
-typedef void NEAR*          NPVOID;
-typedef void FAR*           LPVOID;
+typedef void *           PVOID;
 
 // handle declaration
 #ifdef STRICT
@@ -319,68 +150,4 @@ typedef void *HANDLE;
 typedef PVOID HANDLE;
 #endif
 
-//
-// ANSI (Single-byte Character) types
-//
-typedef char DEF*           PCH;
-typedef char NEAR*          NPCH;
-typedef char FAR*           LPCH;
-typedef const char DEF*     PCCH;
-typedef const char NEAR*    NPCCH;
-typedef const char FAR*     LPCCH;
-
-typedef char DEF*           PSTR;
-typedef char NEAR*          NPSTR;
-typedef char FAR*           LPSTR;
-typedef const char DEF*     PCSTR;
-typedef const char NEAR*    NPCSTR;
-typedef const char FAR*     LPCSTR;
-
-#endif  // !__CPU8051
-
-
-
-
-/****** Misc definitions, types ********************************************/
-
-// parameter prefix
-#ifndef IN
-#define IN
-#endif
-
-#ifndef OUT
-#define OUT
-#endif
-
-
-// unreferenced parameter macro to avoid warning message in MS C
-#if defined(__TURBOC__)
-
-//you should use "#pragma argsused" to avoid warning message in Borland C
-#ifndef UNREFERENCED_PARAMETER
-#define UNREFERENCED_PARAMETER(x)
-#endif
-
-#else
-
-#ifndef UNREFERENCED_PARAMETER
-//#define UNREFERENCED_PARAMETER(x) x
-#define UNREFERENCED_PARAMETER(x)
-#endif
-
-#endif
-
-
-// in-line assembly prefix
-#if defined(__TURBOC__)
-#define ASM             asm
-#else  // !__TURBOC__
-#define ASM             _asm
-#endif // !__TURBOC__
-
-
-
-
 #endif // __TTYPE_H__
-
-
diff --git a/drivers/staging/vt6655/umem.h b/drivers/staging/vt6655/umem.h
deleted file mode 100644
index 2c3eafa..0000000
--- a/drivers/staging/vt6655/umem.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * File: umem.h
- *
- * Purpose: Define Memory macros
- *
- * Author: Tevin Chen
- *
- * Date: Mar 17, 1997
- *
- */
-
-
-#ifndef __UMEM_H__
-#define __UMEM_H__
-
-#if !defined(__TTYPE_H__)
-#include "ttype.h"
-#endif
-
-
-
-/*---------------------  Export Definitions -------------------------*/
-// 4-byte memory tag
-#define MEM_TAG 'mTEW'
-
-// Macros used for memory allocation and deallocation.
-
-
-
-#define ZERO_MEMORY(Destination,Length) {       \
-            memset((PVOID)(Destination),        \
-            0,                                  \
-            (ULONG)(Length)                     \
-            );                                  \
-}
-
-#define MEMvCopy(pvDest, pvSource, uCount) {    \
-            memcpy((PVOID)(pvDest),             \
-            (PVOID)(pvSource),                  \
-            (ULONG)(uCount)                     \
-            );                                  \
-}
-
-
-#define MEMEqualMemory(Destination,Source,Length)   (!memcmp((Destination),(Source),(Length)))
-/*---------------------  Export Classes  ----------------------------*/
-
-/*---------------------  Export Variables  --------------------------*/
-
-/*---------------------  Export Functions  --------------------------*/
-
-
-
-
-#endif // __UMEM_H__
-
-
diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h
index 113fc2c..acd1b66 100644
--- a/drivers/staging/vt6655/upc.h
+++ b/drivers/staging/vt6655/upc.h
@@ -26,16 +26,11 @@
  *
  */
 
-
 #ifndef __UPC_H__
 #define __UPC_H__
 
-#if !defined(DEVICE_H)
 #include "device.h"
-#endif
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
 
 /*---------------------  Export Definitions -------------------------*/
 
diff --git a/drivers/staging/vt6655/vntwifi.c b/drivers/staging/vt6655/vntwifi.c
index 58a1ba0..fbe27a8 100644
--- a/drivers/staging/vt6655/vntwifi.c
+++ b/drivers/staging/vt6655/vntwifi.c
@@ -31,32 +31,13 @@
  *
  */
 
-#if !defined(__VNTWIFI_H__)
 #include "vntwifi.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-
-
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__IEEE11h_H__)
 #include "IEEE11h.h"
-#endif
-#if !defined(__COUNTRY_H__)
 #include "country.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__DATARATE_H__)
 #include "datarate.h"
-#endif
+
 //#define	PLICE_DEBUG
 
 /*---------------------  Static Definitions -------------------------*/
@@ -694,7 +675,7 @@ VNTWIFIbSetPMKIDCache (
         return (FALSE);
     }
     pMgmt->gsPMKIDCache.BSSIDInfoCount = ulCount;
-    MEMvCopy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo)));
+    memcpy(pMgmt->gsPMKIDCache.BSSIDInfo, pPMKIDInfo, (ulCount*sizeof(PMKIDInfo)));
     return (TRUE);
 }
 
@@ -709,7 +690,7 @@ VNTWIFIwGetMaxSupportRate(
     PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtObject;
 
     for(wRate = RATE_54M; wRate > RATE_1M; wRate--) {
-        if (BITbIsBitOn(pMgmt->sNodeDBTable[0].wSuppRate, (1<<wRate))) {
+        if (pMgmt->sNodeDBTable[0].wSuppRate & (1<<wRate)) {
             return (wRate);
         }
     }
@@ -758,24 +739,24 @@ VNTWIFIbMeasureReport(
         switch (pMgmt->pCurrMeasureEIDRep->byType) {
             case MEASURE_TYPE_BASIC :
                 pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_BASIC);
-                MEMvCopy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sBasic),
+                memcpy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sBasic),
                             &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
                             sizeof(MEASEURE_REQ));
                 pMgmt->pCurrMeasureEIDRep->sRep.sBasic.byMap = byBasicMap;
                 break;
             case MEASURE_TYPE_CCA :
                 pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_CCA);
-                MEMvCopy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sCCA),
+                memcpy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sCCA),
                             &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
                             sizeof(MEASEURE_REQ));
                 pMgmt->pCurrMeasureEIDRep->sRep.sCCA.byCCABusyFraction = byCCAFraction;
                 break;
             case MEASURE_TYPE_RPI :
                 pMgmt->pCurrMeasureEIDRep->len += sizeof(MEASEURE_REP_RPI);
-                MEMvCopy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sRPI),
+                memcpy(   &(pMgmt->pCurrMeasureEIDRep->sRep.sRPI),
                             &(((PWLAN_IE_MEASURE_REQ) pvMeasureEID)->sReq),
                             sizeof(MEASEURE_REQ));
-                MEMvCopy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8);
+                memcpy(pMgmt->pCurrMeasureEIDRep->sRep.sRPI.abyRPIdensity, pbyRPIs, 8);
                 break;
             default :
                 break;
diff --git a/drivers/staging/vt6655/vntwifi.h b/drivers/staging/vt6655/vntwifi.h
index 3e620a7..2854dfc 100644
--- a/drivers/staging/vt6655/vntwifi.h
+++ b/drivers/staging/vt6655/vntwifi.h
@@ -30,15 +30,10 @@
 #ifndef __VNTWIFI_H__
 #define __VNTWIFI_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
+#include "wpa2.h"
 
 /*---------------------  Export Definitions -------------------------*/
 #define RATE_1M         0
@@ -67,8 +62,6 @@
 
 #define MAX_BSS_NUM             42
 
-#define MAX_PMKID_CACHE         16
-
 // Pre-configured Authenticaiton Mode (from XP)
 typedef enum tagWMAC_AUTHENTICATION_MODE {
 
@@ -147,11 +140,6 @@ typedef enum tagWMAC_POWER_MODE {
 
 /*---------------------  Export Functions  --------------------------*/
 
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
-
 VOID
 VNTWIFIvSetIBSSParameter (
     IN PVOID pMgmtHandle,
@@ -322,9 +310,4 @@ VNTWIFIbRadarPresent(
     );
 */
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif //__VNTWIFI_H__
diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c
index 92563bd..d81f5b7 100644
--- a/drivers/staging/vt6655/wcmd.c
+++ b/drivers/staging/vt6655/wcmd.c
@@ -1,4 +1,4 @@
- /*
+/*
  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
  * All rights reserved.
  *
@@ -16,7 +16,6 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- *
  * File: wcmd.c
  *
  * Purpose: Handles the management command interface functions
@@ -39,58 +38,21 @@
  *
  */
 
-
-
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__POWER_H__)
 #include "power.h"
-#endif
-#if !defined(__WCTL_H__)
 #include "wctl.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-//DavidWang
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -122,6 +84,7 @@ s_MgrMakeProbeRequest(
     IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
     );
 
+
 static
 BOOL
 s_bCommandComplete (
@@ -134,6 +97,7 @@ s_bCommandComplete (
 /*---------------------  Export Functions  --------------------------*/
 
 
+
 /*
  * Description:
  *      Stop AdHoc beacon during scan process
@@ -186,7 +150,8 @@ vAdHocBeaconStop(PSDevice  pDevice)
         MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
     }
 
-}
+} /* vAdHocBeaconStop */
+
 
 /*
  * Description:
@@ -224,6 +189,8 @@ vAdHocBeaconRestart(PSDevice pDevice)
 
 
 
+
+
 /*+
  *
  * Routine Description:
@@ -274,10 +241,10 @@ s_vProbeChannel(
     if (pTxPacket != NULL ){
         for (ii = 0; ii < 2 ; ii++) {
             if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
             }
             else {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n");
             }
         }
     }
@@ -350,6 +317,7 @@ s_MgrMakeProbeRequest(
 
 
 
+
 VOID
 vCommandTimerWait(
     IN HANDLE    hDeviceContext,
@@ -369,6 +337,7 @@ vCommandTimerWait(
 
 
 
+
 VOID
 vCommandTimer (
     IN  HANDLE      hDeviceContext
@@ -409,7 +378,7 @@ vCommandTimer (
                 return;
             }
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SCAN_START\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SCAN_START\n");
             pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
             // wait all Data TD complete
             if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){
@@ -429,7 +398,7 @@ vCommandTimer (
                 // Set Baseband's sensitivity back.
                 // Set channel back
                 CARDbSetChannel(pMgmt->pAdapter, pMgmt->uCurrChannel);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
                 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
                     CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
                 } else {
@@ -441,7 +410,7 @@ vCommandTimer (
             } else {
 //2008-8-4 <add> by chester
                  if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
                     s_bCommandComplete(pDevice);
                     return;
                 }
@@ -464,9 +433,9 @@ vCommandTimer (
                 vAdHocBeaconStop(pDevice);
 
                 if (CARDbSetChannel(pMgmt->pAdapter, pMgmt->uScanChannel) == TRUE) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SCAN Channel: %d\n", pMgmt->uScanChannel);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SCAN Channel: %d\n", pMgmt->uScanChannel);
                 } else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel);
                 }
                 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_UNKNOWN);
 //	printk("chester-mxch=%d\n",pDevice->byMaxChannel);
@@ -502,7 +471,7 @@ vCommandTimer (
             // Set Baseband's sensitivity back.
             // Set channel back
             CARDbSetChannel(pMgmt->pAdapter, pMgmt->uCurrChannel);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
             if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
                 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
             } else {
@@ -531,7 +500,7 @@ vCommandTimer (
                 spin_unlock_irq(&pDevice->lock);
                 return;
             } else {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
                 // reason = 8 : disassoc because sta has left
                 vMgrDisassocBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status);
                 pDevice->bLinkPass = FALSE;
@@ -551,7 +520,7 @@ vCommandTimer (
                 spin_unlock_irq(&pDevice->lock);
                 return;
             };
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" CARDbRadioPowerOff\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" CARDbRadioPowerOff\n");
 	//2008-09-02  <mark>	by chester
            // CARDbRadioPowerOff(pDevice);
             s_bCommandComplete(pDevice);
@@ -582,15 +551,15 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                               //((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
             pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
             pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
 
             if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID);
             }
 
             if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
@@ -629,7 +598,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                     pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
                     vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT);
                     spin_unlock_irq(&pDevice->lock);
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
                     return;
                 }
             }
@@ -649,7 +618,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                     // start own IBSS
                     vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
                     if (Status != CMD_STATUS_SUCCESS){
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
                     };
                     BSSvAddMulticastNode(pDevice);
                 }
@@ -661,7 +630,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                     // start own IBSS
                     vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
                     if (Status != CMD_STATUS_SUCCESS){
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n");
                     };
                     BSSvAddMulticastNode(pDevice);
                     if (netif_queue_stopped(pDevice->dev)){
@@ -670,7 +639,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                     pDevice->bLinkPass = TRUE;
                 }
                 else {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
 		  #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
                     // if(pDevice->bWPASuppWextEnabled == TRUE)
                         {
@@ -688,15 +657,15 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
             break;
 
         case WLAN_AUTHENTICATE_WAIT :
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
             if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
                 // Call mgr to begin the association
                 	pDevice->byLinkWaitCount = 0;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
                 vMgrAssocBeginSta((HANDLE)pDevice, pMgmt, &Status);
                 if (Status == CMD_STATUS_SUCCESS) {
 		pDevice->byLinkWaitCount = 0;
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
                     pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
                     vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT);
                     spin_unlock_irq(&pDevice->lock);
@@ -732,7 +701,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
 
         case WLAN_ASSOCIATE_WAIT :
             if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
                 if (pDevice->ePSMode != WMAC_POWER_CAM) {
                     PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
                 }
@@ -796,7 +765,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
             break;
 
         case WLAN_CMD_AP_MODE_START :
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
 
             if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
                 del_timer(&pMgmt->sTimerSecondCallback);
@@ -813,12 +782,12 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
 
                 vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
                 if (Status != CMD_STATUS_SUCCESS){
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n");
                 };
                 // alway turn off unicast bit
                 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST);
                 pDevice->byRxMode &= ~RCR_UNICAST;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
                 BSSvAddMulticastNode(pDevice);
                 if (netif_queue_stopped(pDevice->dev)){
                     netif_wake_queue(pDevice->dev);
@@ -841,7 +810,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                         pDevice->bMoreData = TRUE;
                     }
                     if (!device_dma0_xmit(pDevice, skb, 0)) {
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
                     }
                     pMgmt->sNodeDBTable[0].wEnQueueCnt--;
                 }
@@ -851,7 +820,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
             for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
                 if (pMgmt->sNodeDBTable[ii].bActive &&
                     pMgmt->sNodeDBTable[ii].bRxPSPoll) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
                                ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
                     while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
                         if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
@@ -864,7 +833,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                             pDevice->bMoreData = TRUE;
                         }
                         if (!device_dma0_xmit(pDevice, skb, ii)) {
-                            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
                         }
                         pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
                         // check if sta ps enable, wait next pspoll
@@ -876,7 +845,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
                         // clear tx map
                         pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
                                     ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
-                        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
                     }
                     pMgmt->sNodeDBTable[ii].bRxPSPoll = FALSE;
                 }
@@ -887,7 +856,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
 
 
         case WLAN_CMD_RADIO_START :
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
             if (pDevice->bRadioCmd == TRUE)
                 CARDbRadioPowerOn(pDevice);
             else
@@ -898,7 +867,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
 
 
         case WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE :
-            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_CHECK_BBSENSITIVITY_START\n");
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_CHECK_BBSENSITIVITY_START\n");
             // wait all TD complete
             if (pDevice->iTDUsed[TYPE_AC0DMA] != 0){
                 vCommandTimerWait((HANDLE)pDevice, 10);
@@ -912,7 +881,7 @@ printk("chester-abyDesireSSID=%s\n",((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySS
             }
             pDevice->byBBVGACurrent = pDevice->byBBVGANew;
             BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent);
             s_bCommandComplete(pDevice);
             break;
 
@@ -956,18 +925,18 @@ s_bCommandComplete (
         pDevice->bCmdRunning = TRUE;
         switch ( pDevice->eCommand ) {
             case WLAN_CMD_BSSID_SCAN:
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
                 pDevice->eCommandState = WLAN_CMD_SCAN_START;
                 pMgmt->uScanChannel = 0;
                 if (pSSID->len != 0) {
-                    MEMvCopy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                    memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
                 } else {
                     memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
                 }
 /*
                 if ((bForceSCAN == FALSE) && (pDevice->bLinkPass == TRUE)) {
                     if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
-                        (MEMEqualMemory(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
+                        ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
                         pDevice->eCommandState = WLAN_CMD_IDLE;
                     }
                 }
@@ -978,8 +947,8 @@ s_bCommandComplete (
                 if (pSSID->len > WLAN_SSID_MAXLEN)
                     pSSID->len = WLAN_SSID_MAXLEN;
                 if (pSSID->len != 0)
-                    MEMvCopy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n");
+                    memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n");
                 break;
             case WLAN_CMD_DISASSOCIATE:
                 pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
@@ -1031,18 +1000,18 @@ BOOL bScheduleCommand (
         switch (eCommand) {
 
             case WLAN_CMD_BSSID_SCAN:
-                MEMvCopy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
                          pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
                 pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = FALSE;
                 break;
 
             case WLAN_CMD_SSID:
-                MEMvCopy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
                          pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
                 break;
 
             case WLAN_CMD_DISASSOCIATE:
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((PBOOL)pbyItem0);
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
                 break;
 /*
             case WLAN_CMD_DEAUTH:
@@ -1054,7 +1023,7 @@ BOOL bScheduleCommand (
                 break;
 
             case WLAN_CMD_RADIO:
-                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((PBOOL)pbyItem0);
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
                 break;
 
             case WLAN_CMD_CHANGE_BBSENSITIVITY:
diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h
index 8c6bbc4..af32e57 100644
--- a/drivers/staging/vt6655/wcmd.h
+++ b/drivers/staging/vt6655/wcmd.h
@@ -29,15 +29,9 @@
 #ifndef __WCMD_H__
 #define __WCMD_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -46,6 +40,7 @@
 #define AUTHENTICATE_TIMEOUT   1000 //ms
 #define ASSOCIATE_TIMEOUT      1000 //ms
 
+
 // Command code
 typedef enum tagCMD_CODE {
     WLAN_CMD_BSSID_SCAN,
@@ -63,21 +58,19 @@ typedef enum tagCMD_CODE {
     WLAN_CMD_MAC_DISPOWERSAVING,
     WLAN_CMD_11H_CHSW,
     WLAN_CMD_RUN_AP
-} CMD_CODE, DEF* PCMD_CODE;
+} CMD_CODE, *PCMD_CODE;
 
 #define CMD_Q_SIZE              32
 
-
-// Command code
 typedef enum tagCMD_STATUS {
 
-    CMD_STATUS_SUCCESS,
+    CMD_STATUS_SUCCESS = 0,
     CMD_STATUS_FAILURE,
     CMD_STATUS_RESOURCES,
     CMD_STATUS_TIMEOUT,
     CMD_STATUS_PENDING
 
-} CMD_STATUS, DEF* PCMD_STATUS;
+} CMD_STATUS, *PCMD_STATUS;
 
 
 typedef struct tagCMD_ITEM {
@@ -87,7 +80,7 @@ typedef struct tagCMD_ITEM {
     WORD     wDeAuthenReason;
     BOOL     bRadioCmd;
     BOOL     bForceSCAN;
-} CMD_ITEM, DEF* PCMD_ITEM;
+} CMD_ITEM, *PCMD_ITEM;
 
 // Command state
 typedef enum tagCMD_STATE {
@@ -103,7 +96,8 @@ typedef enum tagCMD_STATE {
     WLAN_CMD_RADIO_START,
     WLAN_CMD_CHECK_BBSENSITIVITY_CHANGE,
     WLAN_CMD_IDLE
-} CMD_STATE, DEF* PCMD_STATE;
+} CMD_STATE, *PCMD_STATE;
+
 
 
 /*---------------------  Export Classes  ----------------------------*/
@@ -115,7 +109,6 @@ typedef enum tagCMD_STATE {
 
 
 /*---------------------  Export Functions  --------------------------*/
-
 VOID
 vResetCommandTimer(
     IN HANDLE      hDeviceContext
@@ -148,4 +141,5 @@ BSSvSecondTxData(
     IN  HANDLE      hDeviceContext
     );
 #endif
+
 #endif //__WCMD_H__
diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c
index b4fecc2..4406f8c 100644
--- a/drivers/staging/vt6655/wctl.c
+++ b/drivers/staging/vt6655/wctl.c
@@ -34,16 +34,9 @@
  *
  */
 
-
-#if !defined(__WCTL_H__)
 #include "wctl.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -212,16 +205,12 @@ UINT            uHeaderSize;
             }
         }
         // reserve 4 byte to match MAC RX Buffer
-#ifdef PRIVATE_OBJ
-        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].ref_skb.data + 4);
-#else
         pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4);
-#endif
         memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength);
         pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength;
         pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength;
         pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
-        //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
         return(FALSE);
     }
     else {
@@ -235,7 +224,7 @@ UINT            uHeaderSize;
                 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize);
                 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize);
                 pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
-                //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+                //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
             }
             else {
                 // seq error or frag # error flush DFCB
@@ -251,7 +240,7 @@ UINT            uHeaderSize;
             //enq defragcontrolblock
             pDevice->cbFreeDFCB++;
             pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = FALSE;
-            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
             return(TRUE);
         }
         return(FALSE);
diff --git a/drivers/staging/vt6655/wctl.h b/drivers/staging/vt6655/wctl.h
index f75ca59..a1ac479 100644
--- a/drivers/staging/vt6655/wctl.h
+++ b/drivers/staging/vt6655/wctl.h
@@ -26,21 +26,12 @@
  *
  */
 
-
 #ifndef __WCTL_H__
 #define __WCTL_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -105,22 +96,12 @@
 /*---------------------  Export Variables  --------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 BOOL WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader);
 BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV);
 UINT WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
 UINT WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __WCTL_H__
 
 
diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c
index c0886ed..659be05 100644
--- a/drivers/staging/vt6655/wmgr.c
+++ b/drivers/staging/vt6655/wmgr.c
@@ -16,6 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: wmgr.c
  *
  * Purpose: Handles the 802.11 management functions
@@ -60,64 +61,23 @@
  *
  */
 
-
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TBIT_H__)
-#include "tbit.h"
-#endif
-#if !defined(__DESC_H__)
 #include "desc.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__POWER_H__)
 #include "power.h"
-#endif
-#if !defined(__DATARATE_H__)
 #include "datarate.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-#if !defined(__WPA_H__)
 #include "wpa.h"
-#endif
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
-#endif
 
 #define	PLICE_DEBUG
 
@@ -137,6 +97,7 @@ static BOOL ChannelExceedZoneType(
     IN PSDevice pDevice,
     IN BYTE byCurrChannel
     );
+
 // Association/diassociation functions
 static
 PSTxMgmtPacket
@@ -363,33 +324,10 @@ s_bCipherMatch (
     OUT PBYTE                           pbyCCSGK
     );
 
-
  static VOID  Encyption_Rebuild(
     IN PSDevice pDevice,
     IN PKnownBSS pCurr
  );
-/*
-static
-VOID
-s_vProbeChannel(
-    IN PSDevice pDevice
-    );
-
-static
-VOID
-s_vListenChannel(
-    IN PSDevice pDevice
-    );
-
-static
-PSTxMgmtPacket
-s_MgrMakeProbeRequest(
-    IN PSMgmtObject pMgmt,
-    IN PBYTE pScanBSSID,
-    IN PWLAN_IE_SSID pSSID,
-    IN PWLAN_IE_SUPP_RATES pCurrRates
-    );
-*/
 
 
 
@@ -656,10 +594,10 @@ vMgrReAssocBeginSta(
         /* send the frame */
         *pStatus = csMgmt_xmit(pDevice, pTxPacket);
         if (*pStatus != CMD_STATUS_PENDING) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
         }
         else {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
         }
     }
 
@@ -836,8 +774,8 @@ s_vMgrRxAssocRequest(
             pDevice->bBarkerPreambleMd = TRUE;
         }
 
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
                    sFrame.pHdr->sA3.abyAddr2[0],
                    sFrame.pHdr->sA3.abyAddr2[1],
                    sFrame.pHdr->sA3.abyAddr2[2],
@@ -845,7 +783,7 @@ s_vMgrRxAssocRequest(
                    sFrame.pHdr->sA3.abyAddr2[4],
                    sFrame.pHdr->sA3.abyAddr2[5]
                   ) ;
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
                    pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
     }//else { TODO: received STA under state1 handle }
     else {
@@ -873,10 +811,10 @@ s_vMgrRxAssocRequest(
         /* send the frame */
         Status = csMgmt_xmit(pDevice, pTxPacket);
         if (Status != CMD_STATUS_PENDING) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
         }
         else {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
         }
 
     }
@@ -996,8 +934,8 @@ s_vMgrRxReAssocRequest(
             pDevice->bBarkerPreambleMd = TRUE;
         }
 
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
                    sFrame.pHdr->sA3.abyAddr2[0],
                    sFrame.pHdr->sA3.abyAddr2[1],
                    sFrame.pHdr->sA3.abyAddr2[2],
@@ -1005,7 +943,7 @@ s_vMgrRxReAssocRequest(
                    sFrame.pHdr->sA3.abyAddr2[4],
                    sFrame.pHdr->sA3.abyAddr2[5]
                   ) ;
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
                    pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
 
     }
@@ -1031,10 +969,10 @@ s_vMgrRxReAssocRequest(
         }
         Status = csMgmt_xmit(pDevice, pTxPacket);
         if (Status != CMD_STATUS_PENDING) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
         }
         else {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
         }
     }
     return;
@@ -1099,13 +1037,13 @@ s_vMgrRxAssocResponse(
             pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid)));
             if ( (pMgmt->wCurrAID >> 14) != (BIT0 | BIT1) )
             {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
             };
-            DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
+            DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
             pMgmt->eCurrState = WMAC_STATE_ASSOC;
             BSSvUpdateAPNode((HANDLE)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
             pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
-            DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
+            DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
             pDevice->bLinkPass = TRUE;
             pDevice->uBBVGADiffCount = 0;
             if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
@@ -1125,7 +1063,7 @@ s_vMgrRxAssocResponse(
                        );
                 skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len);
                 pDevice->skb->dev = pDevice->wpadev;
-                pDevice->skb->mac_header = pDevice->skb->data;
+		skb_reset_mac_header(pDevice->skb);
                 pDevice->skb->pkt_type = PACKET_HOST;
                 pDevice->skb->protocol = htons(ETH_P_802_2);
                 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
@@ -1362,7 +1300,7 @@ s_vMgrRxAuthentication(
             s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame);
             break;
         default:
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
                         cpu_to_le16((*(sFrame.pwAuthSequence))));
             break;
     }
@@ -1469,9 +1407,9 @@ s_vMgrRxAuthenSequence_1(
     if (pDevice->bEnableHostapd) {
         return;
     }
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
     if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
     }
     return;
 }
@@ -1506,12 +1444,12 @@ s_vMgrRxAuthenSequence_2(
     {
         case WLAN_AUTH_ALG_OPENSYSTEM:
             if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
-                DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
+                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
                 pMgmt->eCurrState = WMAC_STATE_AUTH;
 	 timer_expire(pDevice->sTimerCommand, 0);
             }
             else {
-                DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
+                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
                 s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
                 pMgmt->eCurrState = WMAC_STATE_IDLE;
             }
@@ -1556,12 +1494,12 @@ s_vMgrRxAuthenSequence_2(
                 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
                 // send the frame
                 if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
                 }
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
             }
             else {
-            	DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
+            	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
                 if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
 //                    spin_unlock_irq(&pDevice->lock);
 //                    vCommandTimerWait((HANDLE)pDevice, 0);
@@ -1571,7 +1509,7 @@ s_vMgrRxAuthenSequence_2(
             }
             break;
         default:
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
             break;
     }
     return;
@@ -1629,7 +1567,7 @@ s_vMgrRxAuthenSequence_3(
         pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0;
     }
     uStatusCode = WLAN_MGMT_STATUS_SUCCESS;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
 
 reply:
     // send auth reply
@@ -1662,7 +1600,7 @@ reply:
         return;
     }
     if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
     }
     return;
 
@@ -1690,12 +1628,12 @@ s_vMgrRxAuthenSequence_4(
 {
 
     if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
         pMgmt->eCurrState = WMAC_STATE_AUTH;
 	  timer_expire(pDevice->sTimerCommand, 0);
     }
     else{
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
         s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))) );
         pMgmt->eCurrState = WMAC_STATE_IDLE;
     }
@@ -1741,14 +1679,14 @@ s_vMgrRxDisassociation(
             BSSvRemoveOneNode(pDevice, uNodeIndex);
         }
         else {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
         }
     }
     else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ){
         sFrame.len = pRxPacket->cbMPDULen;
         sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
         vMgrDecodeDisassociation(&sFrame);
-        DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
+        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
         //TODO: do something let upper layer know or
         //try to send associate packet again because of inactivity timeout
       //  if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
@@ -1761,7 +1699,7 @@ s_vMgrRxDisassociation(
              wpahdr->req_ie_len = 0;
              skb_put(pDevice->skb, sizeof(viawget_wpa_header));
              pDevice->skb->dev = pDevice->wpadev;
-	         pDevice->skb->mac_header = pDevice->skb->data;
+	     skb_reset_mac_header(pDevice->skb);
 
              pDevice->skb->pkt_type = PACKET_HOST;
              pDevice->skb->protocol = htons(ETH_P_802_2);
@@ -1780,7 +1718,6 @@ s_vMgrRxDisassociation(
 	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
      }
   #endif
-
     }
     /* else, ignore it */
 
@@ -1822,7 +1759,7 @@ s_vMgrRxDeauthentication(
             BSSvRemoveOneNode(pDevice, uNodeIndex);
         }
         else {
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
         }
     }
     else {
@@ -1830,7 +1767,7 @@ s_vMgrRxDeauthentication(
             sFrame.len = pRxPacket->cbMPDULen;
             sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
             vMgrDecodeDeauthen(&sFrame);
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
             // TODO: update BSS list for specific BSSID if pre-authentication case
             if (IS_ETH_ADDRESS_EQUAL(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
                 if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
@@ -1849,7 +1786,7 @@ s_vMgrRxDeauthentication(
                  wpahdr->req_ie_len = 0;
                  skb_put(pDevice->skb, sizeof(viawget_wpa_header));
                  pDevice->skb->dev = pDevice->wpadev;
-                 pDevice->skb->mac_header = pDevice->skb->data;
+		 skb_reset_mac_header(pDevice->skb);
                  pDevice->skb->pkt_type = PACKET_HOST;
                  pDevice->skb->protocol = htons(ETH_P_802_2);
                  memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
@@ -1857,13 +1794,13 @@ s_vMgrRxDeauthentication(
                  pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
            };
 
-	   #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+   #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
   // if(pDevice->bWPASuppWextEnabled == TRUE)
       {
 	union iwreq_data  wrqu;
 	memset(&wrqu, 0, sizeof (wrqu));
         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	printk("wireless_send_event--->SIOCGIWAP(disauthen)\n");
+	PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
 	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
      }
   #endif
@@ -1972,7 +1909,7 @@ s_vMgrRxBeacon(
         (sFrame.pwCapInfo == 0) ||
         (sFrame.pSSID == 0) ||
         (sFrame.pSuppRates == 0) ) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
         return;
     };
 
@@ -2008,7 +1945,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
 
     pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
     if (pBSSList == NULL) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel);
         BSSbInsertToBSSList((HANDLE)pDevice,
                             sFrame.pHdr->sA3.abyAddr3,
                             *sFrame.pqwTimestamp,
@@ -2029,7 +1966,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                            );
     }
     else {
-//        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel);
+//        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel);
         BSSbUpdateToBSSList((HANDLE)pDevice,
                             *sFrame.pqwTimestamp,
                             *sFrame.pwBeaconInterval,
@@ -2106,7 +2043,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
 
         if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
             pMgmt->sNodeDBTable[0].uInActiveCount = 0;
-            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
         }
     }
     // check if SSID the same
@@ -2195,7 +2132,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
         }
     }
 
-//    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n");
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n");
     // check if CF field exisit
     if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
         if (sFrame.pCFParms->wCFPDurRemaining > 0) {
@@ -2276,23 +2213,23 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                 (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
                 pMgmt->bInTIMWake = TRUE;
                 // send out ps-poll packet
-//                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
+//                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
                 if (pMgmt->bInTIM) {
                     PSvSendPSPOLL((PSDevice)pDevice);
-//                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
+//                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
                 };
 
             }
             else {
                 pMgmt->bInTIMWake = FALSE;
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
                 if (pDevice->bPWBitOn == FALSE) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
                     if (PSbSendNullPacket(pDevice))
                         pDevice->bPWBitOn = TRUE;
                 }
                 if(PSbConsiderPowerDown(pDevice, FALSE, FALSE)) {
-                   DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
+                   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
                 };
             }
 
@@ -2369,7 +2306,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
 
             // if other stations jointed, indicate connect to upper layer..
             if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
                 pMgmt->eCurrState = WMAC_STATE_JOINTED;
                 pDevice->bLinkPass = TRUE;
                 if (netif_queue_stopped(pDevice->dev)){
@@ -2397,7 +2334,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                                                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
                                                       WLAN_RATES_MAXLEN_11B);
                      // set HW beacon interval and re-synchronizing....
-                     DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
+                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
                      VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod);
                      CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF);
                      CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
@@ -2466,7 +2403,7 @@ vMgrCreateOwnIBSS(
     BYTE    abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
     WORD                wSuppRate;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
 
     if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
@@ -2559,7 +2496,7 @@ vMgrCreateOwnIBSS(
     }
 
     if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
-        MEMvCopy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6);
+        memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6);
         pMgmt->byIBSSDFSRecovery = 10;
         pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
     }
@@ -2583,7 +2520,7 @@ vMgrCreateOwnIBSS(
     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
         // AP mode BSSID = MAC addr
         memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%02x-%02x-%02x-%02x-%02x-%02x \n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%02x-%02x-%02x-%02x-%02x-%02x \n",
                       pMgmt->abyCurrBSSID[0],
                       pMgmt->abyCurrBSSID[1],
                       pMgmt->abyCurrBSSID[2],
@@ -2612,7 +2549,7 @@ vMgrCreateOwnIBSS(
         pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
 
 
-        DEVICE_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%02x-%02x-%02x-%02x-%02x-%02x \n",
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%02x-%02x-%02x-%02x-%02x-%02x \n",
                       pMgmt->abyCurrBSSID[0],
                       pMgmt->abyCurrBSSID[1],
                       pMgmt->abyCurrBSSID[2],
@@ -2743,7 +2680,7 @@ vMgrJoinBSSBegin(
 
     if (ii == MAX_BSS_NUM) {
        *pStatus = CMD_STATUS_RESOURCES;
-        DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
+        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
        return;
     };
 
@@ -2759,11 +2696,11 @@ vMgrJoinBSSBegin(
     if (pCurr == NULL){
        *pStatus = CMD_STATUS_RESOURCES;
        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
-       DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
+       DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
        return;
     };
 
-    DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
+    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
     if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){
 
         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA)||(pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
@@ -2772,14 +2709,14 @@ vMgrJoinBSSBegin(
 /*
             if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
                 if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
                     // encryption mode error
                     pMgmt->eCurrState = WMAC_STATE_IDLE;
                     return;
                 }
             } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
                 if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
                     // encryption mode error
                     pMgmt->eCurrState = WMAC_STATE_IDLE;
                     return;
@@ -2866,10 +2803,10 @@ vMgrJoinBSSBegin(
             // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
             if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
                 BOOL bResult = bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
                 if (bResult == FALSE) {
                     vFlush_PMKID_Candidate((HANDLE)pDevice);
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n");
                     bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
                 }
             }
@@ -2877,11 +2814,11 @@ vMgrJoinBSSBegin(
             // Preamble type auto-switch: if AP can receive short-preamble cap,
             // we can turn on too.
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n");
 
 
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End of Join AP -- A/B/G Action\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End of Join AP -- A/B/G Action\n");
         }
         else {
             pMgmt->eCurrState = WMAC_STATE_IDLE;
@@ -2949,7 +2886,7 @@ vMgrJoinBSSBegin(
 //            pDevice->bLinkPass = TRUE;
 //            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n",
                   pMgmt->abyCurrBSSID[0],
                   pMgmt->abyCurrBSSID[1],
                   pMgmt->abyCurrBSSID[2],
@@ -3008,7 +2945,7 @@ s_vMgrSynchBSS (
                        pDevice->eEncryptionStatus,
                        &(pMgmt->byCSSPK),
                        &(pMgmt->byCSSGK)) == FALSE) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
         return;
     }
 
@@ -3046,7 +2983,7 @@ s_vMgrSynchBSS (
 
     MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = %02x-%02x-%02x=%02x-%02x-%02x\n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = %02x-%02x-%02x=%02x-%02x-%02x\n",
         pMgmt->abyCurrBSSID[0],
         pMgmt->abyCurrBSSID[1],
         pMgmt->abyCurrBSSID[2],
@@ -3081,14 +3018,14 @@ s_vMgrSynchBSS (
     }
 
     if (ePhyType == PHY_TYPE_11A) {
-        MEMvCopy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
+        memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
         pMgmt->abyCurrExtSuppRates[1] = 0;
     } else if (ePhyType == PHY_TYPE_11B) {
-        MEMvCopy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
+        memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
         pMgmt->abyCurrExtSuppRates[1] = 0;
     } else {
-        MEMvCopy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
-        MEMvCopy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
+        memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
+        memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
     }
 
 
@@ -3110,12 +3047,12 @@ s_vMgrSynchBSS (
                                 pMgmt->abyCurrSuppRates,
                                 pMgmt->abyCurrExtSuppRates
                             ) != TRUE) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
         return;
     }
     // set channel and clear NAV
     if (CARDbSetChannel(pMgmt->pAdapter, pCurr->uChannel) == FALSE) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
         return;
     }
 
@@ -3128,7 +3065,7 @@ s_vMgrSynchBSS (
     }
 
     if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] \n",
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RSSI[%d] NewGain[%d] OldGain[%d] \n",
                         (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
         printk("RSSI[%d] NewGain[%d] OldGain[%d] \n",
                         (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
@@ -3140,7 +3077,7 @@ s_vMgrSynchBSS (
     pMgmt->uCurrChannel = pCurr->uChannel;
     pMgmt->eCurrentPHYMode = ePhyType;
     pMgmt->byERPContext = pCurr->sERP.byERP;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (INT)pCurr->uChannel);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (INT)pCurr->uChannel);
 
 
     *pStatus = CMD_STATUS_SUCCESS;
@@ -3172,22 +3109,22 @@ s_vMgrSynchBSS (
                           pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
 		    if(pCurr->abyPKType[0] == WPA_TKIP) {
      		        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
-     		        printk("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
+     		        PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
 		      }
      		   else if(pCurr->abyPKType[0] == WPA_AESCCMP) {
 		        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
-                          printk("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
+                          PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
      		     }
                	}
                else if(pCurr->bWPA2Valid == TRUE) {  //WPA2-PSK
                          pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
 		       if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
       		           pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
-                             printk("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
+                             PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
 		       	}
       		       else if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
 		           pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
-                            printk("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
+                            PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
       		       	}
                	}
               }
@@ -3438,7 +3375,7 @@ s_MgrMakeBeacon(
             pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
             pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
             pIBSSDFS->len = 7;
-            MEMvCopy(   pIBSSDFS->abyDFSOwner,
+            memcpy(   pIBSSDFS->abyDFSOwner,
                         pMgmt->abyIBSSDFSOwner,
                         6);
             pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
@@ -3471,7 +3408,7 @@ s_MgrMakeBeacon(
     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
-        MEMvCopy(sFrame.pExtSuppRates,
+        memcpy(sFrame.pExtSuppRates,
              pCurrExtSuppRates,
              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
              );
@@ -3642,7 +3579,7 @@ s_MgrMakeProbeResponse(
             pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
             pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
             pIBSSDFS->len = 7;
-            MEMvCopy(   pIBSSDFS->abyDFSOwner,
+            memcpy(   pIBSSDFS->abyDFSOwner,
                         pMgmt->abyIBSSDFSOwner,
                         6);
             pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
@@ -3663,7 +3600,7 @@ s_MgrMakeProbeResponse(
     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
-        MEMvCopy(sFrame.pExtSuppRates,
+        memcpy(sFrame.pExtSuppRates,
              pCurrExtSuppRates,
              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
              );
@@ -3749,7 +3686,7 @@ s_MgrMakeAssocRequest(
     pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
     pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
     pbyIEs = pMgmt->sAssocInfo.abyIEs;
-    MEMvCopy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+    memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
     pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
 
     // Copy the rate set
@@ -3768,7 +3705,7 @@ s_MgrMakeAssocRequest(
     }
 
     pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
-    MEMvCopy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
     pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
 
     // for 802.11h
@@ -3832,6 +3769,7 @@ s_MgrMakeAssocRequest(
         *pbyRSN++=0x01;
         *pbyRSN++=0x00;
         *pbyRSN++=0x00;
+
         *pbyRSN++=0x50;
         *pbyRSN++=0xf2;
         if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
@@ -3843,16 +3781,19 @@ s_MgrMakeAssocRequest(
         else {
             *pbyRSN++=WPA_NONE;
         }
+
         sFrame.pRSNWPA->len +=6;
 
         // RSN Capabilites
+
         *pbyRSN++=0x00;
         *pbyRSN++=0x00;
         sFrame.pRSNWPA->len +=2;
+
         sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
-        MEMvCopy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
+        memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
         pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
 
     } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
@@ -3914,7 +3855,7 @@ s_MgrMakeAssocRequest(
 
         // RSN Capabilites
         if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
-            MEMvCopy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+            memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
         } else {
             sFrame.pRSN->abyRSN[16] = 0;
             sFrame.pRSN->abyRSN[17] = 0;
@@ -3928,9 +3869,9 @@ s_MgrMakeAssocRequest(
             *pwPMKID = 0;            // Initialize PMKID count
             pbyRSN += 2;             // Point to PMKID list
             for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
-                if (MEMEqualMemory(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
                     (*pwPMKID) ++;
-                    MEMvCopy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
+                    memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
                     pbyRSN += 16;
                 }
             }
@@ -3942,7 +3883,7 @@ s_MgrMakeAssocRequest(
         sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
-        MEMvCopy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
+        memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
         pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
     }
 
@@ -4024,7 +3965,7 @@ s_MgrMakeReAssocRequest(
     pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
     pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
     pbyIEs = pMgmt->sAssocInfo.abyIEs;
-    MEMvCopy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+    memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
     pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
 
     /* Copy the rate set */
@@ -4041,7 +3982,7 @@ s_MgrMakeReAssocRequest(
     }
 
     pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
-    MEMvCopy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
     pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
 
     if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
@@ -4087,6 +4028,7 @@ s_MgrMakeReAssocRequest(
         *pbyRSN++=0x01;
         *pbyRSN++=0x00;
         *pbyRSN++=0x00;
+
         *pbyRSN++=0x50;
         *pbyRSN++=0xf2;
         if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
@@ -4096,16 +4038,18 @@ s_MgrMakeReAssocRequest(
         } else {
             *pbyRSN++=WPA_NONE;
         }
+
         sFrame.pRSNWPA->len +=6;
 
         // RSN Capabilites
         *pbyRSN++=0x00;
         *pbyRSN++=0x00;
         sFrame.pRSNWPA->len +=2;
+
         sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
-        MEMvCopy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
+        memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
         pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
 
     } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
@@ -4167,7 +4111,7 @@ s_MgrMakeReAssocRequest(
 
         // RSN Capabilites
         if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
-            MEMvCopy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+            memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
         } else {
             sFrame.pRSN->abyRSN[16] = 0;
             sFrame.pRSN->abyRSN[17] = 0;
@@ -4181,9 +4125,9 @@ s_MgrMakeReAssocRequest(
             *pwPMKID = 0;            // Initialize PMKID count
             pbyRSN += 2;             // Point to PMKID list
             for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
-                if (MEMEqualMemory(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
                     (*pwPMKID) ++;
-                    MEMvCopy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
+                    memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
                     pbyRSN += 16;
                 }
             }
@@ -4195,7 +4139,7 @@ s_MgrMakeReAssocRequest(
         sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
-        MEMvCopy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
+        memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
         pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
     }
 
@@ -4269,7 +4213,7 @@ s_MgrMakeAssocResponse(
     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
-        MEMvCopy(sFrame.pExtSuppRates,
+        memcpy(sFrame.pExtSuppRates,
              pCurrExtSuppRates,
              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
              );
@@ -4343,7 +4287,7 @@ s_MgrMakeReAssocResponse(
     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
-        MEMvCopy(sFrame.pExtSuppRates,
+        memcpy(sFrame.pExtSuppRates,
              pCurrExtSuppRates,
              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
              );
@@ -4395,13 +4339,13 @@ s_vMgrRxProbeResponse(
         (sFrame.pwCapInfo == 0) ||
         (sFrame.pSSID == 0) ||
         (sFrame.pSuppRates == 0)) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
         DBG_PORT80(0xCC);
         return;
     };
 
     if(sFrame.pSSID->len == 0)
-       DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
 
     if (sFrame.pDSParms != 0) {
         if (byCurrChannel > CB_MAX_CHANNEL_24G) {
@@ -4457,7 +4401,7 @@ if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
                            );
     }
     else {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
         BSSbInsertToBSSList((HANDLE)pDevice,
                             sFrame.pHdr->sA3.abyAddr3,
                             *sFrame.pqwTimestamp,
@@ -4517,7 +4461,7 @@ s_vMgrRxProbeRequest(
         sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
         vMgrDecodeProbeRequest(&sFrame);
 /*
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n",
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n",
                   sFrame.pHdr->sA3.abyAddr2[0],
                   sFrame.pHdr->sA3.abyAddr2[1],
                   sFrame.pHdr->sA3.abyAddr2[2],
@@ -4560,10 +4504,10 @@ s_vMgrRxProbeRequest(
             /* send the frame */
             Status = csMgmt_xmit(pDevice, pTxPacket);
             if (Status != CMD_STATUS_PENDING) {
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
             }
             else {
-//                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
+//                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
             }
         }
     }
@@ -4613,7 +4557,7 @@ vMgrRxManagePacket(
 
         case WLAN_FSTYPE_ASSOCREQ:
             // Frame Clase = 2
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
             if (eNodeState < NODE_AUTH) {
                 // send deauth notification
                 // reason = (6) class 2 received from nonauth sta
@@ -4623,7 +4567,7 @@ vMgrRxManagePacket(
                                      (6),
                                      &Status
                                      );
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
             }
             else {
                 s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
@@ -4632,14 +4576,14 @@ vMgrRxManagePacket(
 
         case WLAN_FSTYPE_ASSOCRESP:
             // Frame Clase = 2
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
             s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, FALSE);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
             break;
 
         case WLAN_FSTYPE_REASSOCREQ:
             // Frame Clase = 2
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
             // Todo: reassoc
             if (eNodeState < NODE_AUTH) {
                 // send deauth notification
@@ -4650,7 +4594,7 @@ vMgrRxManagePacket(
                                      (6),
                                      &Status
                                      );
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
 
             }
             s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
@@ -4658,26 +4602,26 @@ vMgrRxManagePacket(
 
         case WLAN_FSTYPE_REASSOCRESP:
             // Frame Clase = 2
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
             s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, TRUE);
             break;
 
         case WLAN_FSTYPE_PROBEREQ:
             // Frame Clase = 0
-            //DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
             s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
             break;
 
         case WLAN_FSTYPE_PROBERESP:
             // Frame Clase = 0
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
 
             s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
             break;
 
         case WLAN_FSTYPE_BEACON:
             // Frame Clase = 0
-            // DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
             if (pMgmt->eScanState != WMAC_NO_SCANNING) {
                 bInScan = TRUE;
             };
@@ -4686,12 +4630,12 @@ vMgrRxManagePacket(
 
         case WLAN_FSTYPE_ATIM:
             // Frame Clase = 1
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
             break;
 
         case WLAN_FSTYPE_DISASSOC:
             // Frame Clase = 2
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
             if (eNodeState < NODE_AUTH) {
                 // send deauth notification
                 // reason = (6) class 2 received from nonauth sta
@@ -4701,25 +4645,25 @@ vMgrRxManagePacket(
                                      (6),
                                      &Status
                                      );
-                DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
             }
             s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
             break;
 
         case WLAN_FSTYPE_AUTHEN:
             // Frame Clase = 1
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO  "rx authen\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO  "rx authen\n");
             s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
             break;
 
         case WLAN_FSTYPE_DEAUTHEN:
             // Frame Clase = 1
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
             s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
             break;
 
         default:
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
     }
 
     return;
@@ -4802,46 +4746,46 @@ s_vMgrLogStatus(
 {
     switch( wStatus ){
         case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
             break;
         case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
             break;
         case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
             break;
         case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
             break;
         case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
             break;
         case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
             break;
         case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge  failure.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge  failure.\n");
             break;
         case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
             break;
         case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
             break;
         case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
             break;
         case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
             break;
         case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
             break;
         case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
             break;
         default:
-            DEVICE_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
             break;
     }
 }
@@ -4874,7 +4818,7 @@ bAdd_PMKID_Candidate (
     PPMKID_CANDIDATE pCandidateList;
     UINT             ii = 0;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
 
     if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
         return FALSE;
@@ -4887,7 +4831,7 @@ bAdd_PMKID_Candidate (
     // Update Old Candidate
     for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
         pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
-        if (MEMEqualMemory(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) {
+        if ( !memcmp(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) {
             if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
                 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
             } else {
@@ -4904,9 +4848,9 @@ bAdd_PMKID_Candidate (
     } else {
         pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
     }
-    MEMvCopy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN);
+    memcpy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN);
     pDevice->gsPMKIDCandidate.NumCandidates++;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
     return TRUE;
 }
 
@@ -4934,7 +4878,7 @@ vFlush_PMKID_Candidate (
     if (pDevice == NULL)
         return;
 
-    ZERO_MEMORY(&pDevice->gsPMKIDCandidate, sizeof(SPMKIDCandidateEvent));
+    memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
 }
 
 static BOOL
@@ -4953,7 +4897,6 @@ s_bCipherMatch (
         return FALSE;
 
     // check cap. of BSS
-
     if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
          (EncStatus == Ndis802_11Encryption1Enabled)) {
         // default is WEP only
@@ -4962,8 +4905,8 @@ s_bCipherMatch (
 
     if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
         (pBSSNode->bWPA2Valid == TRUE) &&
+          //20080123-01,<Add> by Einsn Liu
         ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) {
-
         //WPA2
         // check Group Key Cipher
         if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
@@ -4993,10 +4936,10 @@ s_bCipherMatch (
                 i = pBSSNode->wCSSPKCount;
             }
         }
+
     } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
                 (pBSSNode->bWPAValid == TRUE) &&
-                ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) {
-
+                ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
         //WPA
         // check Group Key Cipher
         if ((pBSSNode->byGKType == WPA_WEP40) ||
@@ -5024,11 +4967,12 @@ s_bCipherMatch (
         }
     }
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%d, %d, %d, %d, EncStatus:%d\n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%d, %d, %d, %d, EncStatus:%d\n",
         byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
 
     // mask our cap. with BSS
     if (EncStatus == Ndis802_11Encryption1Enabled) {
+
         // For supporting Cisco migration mode, don't care pairwise key cipher
         if ((byMulticastCipher == KEY_CTL_WEP) &&
             (byCipherMask == 0)) {
diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h
index 5b526ab..1c1f2ea 100644
--- a/drivers/staging/vt6655/wmgr.h
+++ b/drivers/staging/vt6655/wmgr.h
@@ -31,36 +31,17 @@
  *
  */
 
-
 #ifndef __WMGR_H__
 #define __WMGR_H__
 
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__WCMD_H__)
 #include "wcmd.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__CARD_H__)
-#include "card.h"
-#endif
-#if !defined(__WPA2_H__)
 #include "wpa2.h"
-#endif
-#if !defined(__VNTWIFI_H__)
 #include "vntwifi.h"
-#endif
-
-
+#include "card.h"
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -143,7 +124,7 @@ typedef struct tagSAssocInfo {
     // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION
     ULONG                                   RequestIELength;
     BYTE                                    abyReqIEs[WLAN_BEACON_FR_MAXLEN];
-} SAssocInfo, DEF* PSAssocInfo;
+} SAssocInfo, *PSAssocInfo;
 //---
 
 
@@ -246,7 +227,7 @@ typedef struct tagSTxMgmtPacket {
     UINT                cbMPDULen;
     UINT                cbPayloadLen;
 
-} STxMgmtPacket, DEF* PSTxMgmtPacket;
+} STxMgmtPacket, *PSTxMgmtPacket;
 
 
 // Rx Managment Packet descriptor
@@ -261,7 +242,7 @@ typedef struct tagSRxMgmtPacket {
     BYTE                byRxRate;
     BYTE                byRxChannel;
 
-} SRxMgmtPacket, DEF* PSRxMgmtPacket;
+} SRxMgmtPacket, *PSRxMgmtPacket;
 
 
 
@@ -356,11 +337,11 @@ typedef struct tagSMgmtObject
     BOOL                    bRxBeaconInTBTTWake;
     BYTE                    abyPSTxMap[MAX_NODE_NUM + 1];
 
-    // managment command related
+    // management command related
     UINT                    uCmdBusy;
     UINT                    uCmdHostAPBusy;
 
-    // managment packet pool
+    // management packet pool
     PBYTE                   pbyMgmtPacketPool;
     BYTE                    byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
 
@@ -409,7 +390,7 @@ typedef struct tagSMgmtObject
 
     struct sk_buff  skb;
 
-} SMgmtObject, DEF *PSMgmtObject;
+} SMgmtObject, *PSMgmtObject;
 
 
 /*---------------------  Export Macros ------------------------------*/
diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c
index 8b4e7fc..f92d33f 100644
--- a/drivers/staging/vt6655/wpa.c
+++ b/drivers/staging/vt6655/wpa.c
@@ -32,38 +32,15 @@
  *
  */
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__TMACRO_H__)
 #include "tmacro.h"
-#endif
-#if !defined(__TETHER_H__)
 #include "tether.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__WPA_H__)
 #include "wpa.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-
 
 /*---------------------  Static Variables  --------------------------*/
 static int          msglevel                =MSG_LEVEL_INFO;
@@ -139,47 +116,47 @@ WPA_ParseRSN (
 
     WPA_ClearRSN(pBSSList);
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA_ParseRSN: [%d]\n", pRSN->len);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA_ParseRSN: [%d]\n", pRSN->len);
 
     // information element header makes sense
     if ((pRSN->len >= 6) // oui1(4)+ver(2)
-         && (pRSN->byElementID == WLAN_EID_RSN_WPA) && MEMEqualMemory(pRSN->abyOUI, abyOUI01, 4)
+         && (pRSN->byElementID == WLAN_EID_RSN_WPA) &&  !memcmp(pRSN->abyOUI, abyOUI01, 4)
          && (pRSN->wVersion == 1)) {
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal RSN\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal RSN\n");
         // update each variable if pRSN is long enough to contain the variable
         if (pRSN->len >= 10) //oui1(4)+ver(2)+GKSuite(4)
         {
-            if (MEMEqualMemory(pRSN->abyMulticast, abyOUI01, 4))
+            if ( !memcmp(pRSN->abyMulticast, abyOUI01, 4))
                 pBSSList->byGKType = WPA_WEP40;
-            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI02, 4))
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI02, 4))
                 pBSSList->byGKType = WPA_TKIP;
-            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI03, 4))
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI03, 4))
                 pBSSList->byGKType = WPA_AESWRAP;
-            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI04, 4))
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI04, 4))
                 pBSSList->byGKType = WPA_AESCCMP;
-            else if (MEMEqualMemory(pRSN->abyMulticast, abyOUI05, 4))
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI05, 4))
                 pBSSList->byGKType = WPA_WEP104;
             else
                 // any vendor checks here
                 pBSSList->byGKType = WPA_NONE;
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byGKType: %x\n", pBSSList->byGKType);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byGKType: %x\n", pBSSList->byGKType);
         }
 
         if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
         {
             j = 0;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %d\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %ld\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
             for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
-                    if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
+                    if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
                         pBSSList->abyPKType[j++] = WPA_NONE;
-                    else if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI02, 4))
+                    else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4))
                         pBSSList->abyPKType[j++] = WPA_TKIP;
-                    else if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI03, 4))
+                    else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4))
                         pBSSList->abyPKType[j++] = WPA_AESWRAP;
-                    else if (MEMEqualMemory(pRSN->PKSList[i].abyOUI, abyOUI04, 4))
+                    else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI04, 4))
                         pBSSList->abyPKType[j++] = WPA_AESCCMP;
                     else
                         // any vendor checks here
@@ -190,24 +167,24 @@ WPA_ParseRSN (
                 //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1]));
             } //for
             pBSSList->wPKCount = (WORD)j;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount);
         }
 
         m = pRSN->wPKCount;
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"m: %d\n", m);
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+m*4: %d\n", 14+m*4);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"m: %d\n", m);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+m*4: %d\n", 14+m*4);
 
         if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)
             // overlay IE_RSN_Auth structure into correct place
             pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI;
             j = 0;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %d\n",
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %ld\n",
                           pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
             for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
                 if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
-                    if (MEMEqualMemory(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
+                    if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
                         pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X;
-                    else if (MEMEqualMemory(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4))
+                    else if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4))
                         pBSSList->abyAuthType[j++] = WPA_AUTH_PSK;
                     else
                     // any vendor checks here
@@ -219,15 +196,15 @@ WPA_ParseRSN (
             }
             if(j > 0)
                 pBSSList->wAuthCount = (WORD)j;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount);
         }
 
         if (pIE_RSN_Auth != NULL) {
 
             n = pIE_RSN_Auth->wAuthCount;
 
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"n: %d\n", n);
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"n: %d\n", n);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4);
 
             if(pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2)
                 pbyCaps = (PBYTE)pIE_RSN_Auth->AuthKSList[n].abyOUI;
@@ -329,7 +306,7 @@ WPAb_Is_RSN (
         return FALSE;
 
     if ((pRSN->len >= 6) && // oui1(4)+ver(2)
-        (pRSN->byElementID == WLAN_EID_RSN_WPA) && MEMEqualMemory(pRSN->abyOUI, abyOUI01, 4) &&
+        (pRSN->byElementID == WLAN_EID_RSN_WPA) &&  !memcmp(pRSN->abyOUI, abyOUI01, 4) &&
         (pRSN->wVersion == 1)) {
         return TRUE;
     }
diff --git a/drivers/staging/vt6655/wpa.h b/drivers/staging/vt6655/wpa.h
index 8000a37..9d9ce01 100644
--- a/drivers/staging/vt6655/wpa.h
+++ b/drivers/staging/vt6655/wpa.h
@@ -31,14 +31,8 @@
 #ifndef __WPA_H__
 #define __WPA_H__
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -63,9 +57,6 @@
 
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 VOID
 WPA_ClearRSN(
@@ -90,9 +81,4 @@ WPAb_Is_RSN(
     IN PWLAN_IE_RSN_EXT pRSN
     );
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif // __WPA_H__
diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c
index e2fdb33..931b6bd 100644
--- a/drivers/staging/vt6655/wpa2.c
+++ b/drivers/staging/vt6655/wpa2.c
@@ -30,19 +30,10 @@
  * Date: Oct. 4, 2004
  *
  */
-#if !defined(__WPA2_H__)
+
 #include "wpa2.h"
-#endif
-#if !defined(__UMEM_H__)
-#include "umem.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-
 
 /*---------------------  Static Definitions -------------------------*/
 static int          msglevel                =MSG_LEVEL_INFO;
@@ -127,7 +118,7 @@ WPA2vParseRSN (
     PBYTE               pbyOUI;
     BOOL                bUseGK = FALSE;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len);
 
     WPA2_ClearRSN(pBSSNode);
 
@@ -147,25 +138,25 @@ WPA2vParseRSN (
     if ((pRSN->byElementID == WLAN_EID_RSN) &&
         (pRSN->wVersion == 1)) {
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal 802.11i RSN\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal 802.11i RSN\n");
 
         pbyOUI = &(pRSN->abyRSN[0]);
-        if (MEMEqualMemory(pbyOUI, abyOUIWEP40, 4))
+        if ( !memcmp(pbyOUI, abyOUIWEP40, 4))
             pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40;
-        else if (MEMEqualMemory(pbyOUI, abyOUITKIP, 4))
+        else if ( !memcmp(pbyOUI, abyOUITKIP, 4))
             pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP;
-        else if (MEMEqualMemory(pbyOUI, abyOUICCMP, 4))
+        else if ( !memcmp(pbyOUI, abyOUICCMP, 4))
             pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
-        else if (MEMEqualMemory(pbyOUI, abyOUIWEP104, 4))
+        else if ( !memcmp(pbyOUI, abyOUIWEP104, 4))
             pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104;
-        else if (MEMEqualMemory(pbyOUI, abyOUIGK, 4)) {
+        else if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
             // invalid CSS, P802.11i/D10.0, p32
             return;
         } else
             // any vendor checks here
             pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN;
 
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"802.11i CSS: %X\n", pBSSNode->byCSSGK);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"802.11i CSS: %X\n", pBSSNode->byCSSGK);
 
         if (pRSN->len == 6) {
             pBSSNode->bWPA2Valid = TRUE;
@@ -180,26 +171,26 @@ WPA2vParseRSN (
             for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(BYTE)); i++) {
 
                 if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i)
-                    if (MEMEqualMemory(pbyOUI, abyOUIGK, 4)) {
+                    if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
                         pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP;
                         bUseGK = TRUE;
-                    } else if (MEMEqualMemory(pbyOUI, abyOUIWEP40, 4)) {
+                    } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) {
                         // Invialid CSS, continue to parsing
-                    } else if (MEMEqualMemory(pbyOUI, abyOUITKIP, 4)) {
+                    } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) {
                         if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP)
                             pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP;
                         else
                             ; // Invialid CSS, continue to parsing
-                    } else if (MEMEqualMemory(pbyOUI, abyOUICCMP, 4)) {
+                    } else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) {
                         pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP;
-                    } else if (MEMEqualMemory(pbyOUI, abyOUIWEP104, 4)) {
+                    } else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) {
                         // Invialid CSS, continue to parsing
                     } else {
                         // any vendor checks here
                         pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN;
                     }
                     pbyOUI += 4;
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]);
                 } else
                     break;
             } //for
@@ -219,7 +210,7 @@ WPA2vParseRSN (
                 return;
             }
             pBSSNode->wCSSPKCount = (WORD)j;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount);
         }
 
         m = *((PWORD) &(pRSN->abyRSN[4]));
@@ -230,19 +221,19 @@ WPA2vParseRSN (
             pbyOUI = &(pRSN->abyRSN[8+4*m]);
             for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(BYTE)); i++) {
                 if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i)
-                    if (MEMEqualMemory(pbyOUI, abyOUI8021X, 4))
+                    if ( !memcmp(pbyOUI, abyOUI8021X, 4))
                         pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X;
-                    else if (MEMEqualMemory(pbyOUI, abyOUIPSK, 4))
+                    else if ( !memcmp(pbyOUI, abyOUIPSK, 4))
                         pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK;
                     else
                         // any vendor checks here
                         pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN;
-                    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]);
                 } else
                     break;
             }
             pBSSNode->wAKMSSAuthCount = (WORD)j;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount);
 
             n = *((PWORD) &(pRSN->abyRSN[6+4*m]));;
             if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2)
@@ -340,7 +331,7 @@ WPA2uSetIEs(
 
         // RSN Capabilites
         if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
-            MEMvCopy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+            memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
         } else {
             pRSNIEs->abyRSN[16] = 0;
             pRSNIEs->abyRSN[17] = 0;
@@ -355,9 +346,9 @@ WPA2uSetIEs(
             *pwPMKID = 0;                               // Initialize PMKID count
             pbyBuffer = &pRSNIEs->abyRSN[20];           // Point to PMKID list
             for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) {
-                if (MEMEqualMemory(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                if ( !memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
                     (*pwPMKID) ++;
-                    MEMvCopy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16);
+                    memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16);
                     pbyBuffer += 16;
                 }
             }
diff --git a/drivers/staging/vt6655/wpa2.h b/drivers/staging/vt6655/wpa2.h
index bda045b..e553b38 100644
--- a/drivers/staging/vt6655/wpa2.h
+++ b/drivers/staging/vt6655/wpa2.h
@@ -31,26 +31,13 @@
 #ifndef __WPA2_H__
 #define __WPA2_H__
 
-
-#if !defined(__TTYPE_H__)
 #include "ttype.h"
-#endif
-#if !defined(__80211MGR_H__)
 #include "80211mgr.h"
-#endif
-#if !defined(__80211HDR_H__)
 #include "80211hdr.h"
-#endif
-#if !defined(__BSSDB_H__)
 #include "bssdb.h"
-#endif
-#if !defined(__VNTWIFI_H__)
-#include "vntwifi.h"
-#endif
-
-
 
 /*---------------------  Export Definitions -------------------------*/
+#define MAX_PMKID_CACHE         16
 
 typedef struct tagsPMKIDInfo {
     BYTE    abyBSSID[6];
@@ -70,9 +57,6 @@ typedef struct tagSPMKIDCache {
 /*---------------------  Export Types  ------------------------------*/
 
 /*---------------------  Export Functions  --------------------------*/
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
 
 VOID
 WPA2_ClearRSN (
@@ -91,10 +75,4 @@ WPA2uSetIEs(
     OUT PWLAN_IE_RSN pRSNIEs
     );
 
-
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
 #endif // __WPA2_H__
diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c
index cc4f0ad..574e0b0 100644
--- a/drivers/staging/vt6655/wpactl.c
+++ b/drivers/staging/vt6655/wpactl.c
@@ -16,6 +16,7 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
+ *
  * File: wpactl.c
  *
  * Purpose: handle wpa supplicant ioctl input/out functions
@@ -30,32 +31,14 @@
  *
  */
 
-
-#if !defined(__WPACTL_H__)
 #include "wpactl.h"
-#endif
-#if !defined(__KEY_H__)
 #include "key.h"
-#endif
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-#if !defined(__WMGR_H__)
 #include "wmgr.h"
-#endif
-#if !defined(__IOCMD_H__)
 #include "iocmd.h"
-#endif
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
-#endif
-//2008-0717-05, <Add> by James
-#if !defined(__RF_H__)
 #include "rf.h"
-#endif
 
 /*---------------------  Static Definitions -------------------------*/
 
@@ -79,8 +62,6 @@ static int          msglevel                =MSG_LEVEL_INFO;
 
 
 /*---------------------  Export Variables  --------------------------*/
-
-
 static void wpadev_setup(struct net_device *dev)
 {
 	dev->type               = ARPHRD_IEEE80211;
@@ -94,8 +75,6 @@ static void wpadev_setup(struct net_device *dev)
 	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
 }
 
-
-
 /*
  * Description:
  *      register netdev for wpa supplicant deamon
@@ -122,7 +101,6 @@ static int wpa_init_wpadev(PSDevice pDevice)
 
     wpadev_priv = netdev_priv(pDevice->wpadev);
     *wpadev_priv = *pDevice;
-
 	memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, U_ETHER_ADDR_LEN);
          pDevice->wpadev->base_addr = dev->base_addr;
 	pDevice->wpadev->irq = dev->irq;
@@ -130,7 +108,7 @@ static int wpa_init_wpadev(PSDevice pDevice)
 	pDevice->wpadev->mem_end = dev->mem_end;
 	ret = register_netdev(pDevice->wpadev);
 	if (ret) {
-		DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
 		       dev->name);
 		free_netdev(pDevice->wpadev);
 		return -1;
@@ -142,7 +120,7 @@ static int wpa_init_wpadev(PSDevice pDevice)
 		    return -ENOMEM;
     }
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
 	       dev->name, pDevice->wpadev->name);
 
 	return 0;
@@ -164,14 +142,13 @@ static int wpa_init_wpadev(PSDevice pDevice)
 
 static int wpa_release_wpadev(PSDevice pDevice)
 {
-
     if (pDevice->skb) {
         dev_kfree_skb(pDevice->skb);
         pDevice->skb = NULL;
     }
 
     if (pDevice->wpadev) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
 	       pDevice->dev->name, pDevice->wpadev->name);
 	unregister_netdev(pDevice->wpadev);
 	free_netdev(pDevice->wpadev);
@@ -201,8 +178,6 @@ static int wpa_release_wpadev(PSDevice pDevice)
 
 int wpa_set_wpadev(PSDevice pDevice, int val)
 {
-
-
 	if (val)
 		return wpa_init_wpadev(pDevice);
 	else
@@ -224,9 +199,9 @@ int wpa_set_wpadev(PSDevice pDevice, int val)
  *
  */
 
-int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
+ int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
 {
- struct viawget_wpa_param *param=ctx;
+    struct viawget_wpa_param *param=ctx;
     PSMgmtObject pMgmt = pDevice->pMgmt;
     DWORD   dwKeyIndex = 0;
     BYTE    abyKey[MAX_KEY_LEN];
@@ -241,7 +216,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
 	if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
 		return -EINVAL;
 
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
 	if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
         pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
         pDevice->bEncryptionEnable = FALSE;
@@ -261,8 +236,8 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
     else {
 	spin_unlock_irq(&pDevice->lock);
 	if (param->u.wpa_key.key &&
-	    copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)){
-	        spin_lock_irq(&pDevice->lock);
+	    copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) {
+	    spin_lock_irq(&pDevice->lock);
 	    return -EINVAL;
     	}
 spin_lock_irq(&pDevice->lock);
@@ -302,9 +277,8 @@ spin_lock_irq(&pDevice->lock);
        else {
 	   	spin_unlock_irq(&pDevice->lock);
 	if (param->u.wpa_key.seq &&
-	    copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)){
-
-	 spin_lock_irq(&pDevice->lock);
+	    copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) {
+	    spin_lock_irq(&pDevice->lock);
 	    return -EINVAL;
        	}
 spin_lock_irq(&pDevice->lock);
@@ -322,7 +296,7 @@ spin_lock_irq(&pDevice->lock);
 	}
 
     if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
         return -EINVAL;
     }
 
@@ -337,6 +311,7 @@ spin_lock_irq(&pDevice->lock);
 	if (param->u.wpa_key.set_tx)
 		dwKeyIndex |= (1 << 31);
 
+
     if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
         byKeyDecMode = KEY_CTL_CCMP;
     else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
@@ -359,13 +334,12 @@ spin_lock_irq(&pDevice->lock);
             byKeyDecMode = KEY_CTL_WEP;
     }
 
-
     // Check TKIP key length
     if ((byKeyDecMode == KEY_CTL_TKIP) &&
         (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
         // TKIP Key must be 256 bits
         //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n"));
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
         return -EINVAL;
     }
     // Check AES key length
@@ -379,7 +353,7 @@ spin_lock_irq(&pDevice->lock);
    // spin_lock_irq(&pDevice->lock);
     if (IS_BROADCAST_ADDRESS(&param->addr[0]) || (param->addr == NULL)) {
         // If IS_BROADCAST_ADDRESS, set the key as every key entry's group key.
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
 
         if ((KeybSetAllGroupKey(&(pDevice->sKey),
                             dwKeyIndex,
@@ -397,7 +371,7 @@ spin_lock_irq(&pDevice->lock);
                             byKeyDecMode,
                             pDevice->PortOffset,
                             pDevice->byLocalID) == TRUE) ) {
-             DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
+             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
 
         } else {
             //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n"));
@@ -406,11 +380,11 @@ spin_lock_irq(&pDevice->lock);
         }
 
     } else {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
         // BSSID not 0xffffffffffff
         // Pairwise Key can't be WEP
         if (byKeyDecMode == KEY_CTL_WEP) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
             //spin_unlock_irq(&pDevice->lock);
             return -EINVAL;
         }
@@ -430,7 +404,7 @@ spin_lock_irq(&pDevice->lock);
                         byKeyDecMode,
                         pDevice->PortOffset,
                         pDevice->byLocalID) == TRUE) {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
 
         } else {
             // Key Table Full
@@ -455,7 +429,7 @@ spin_lock_irq(&pDevice->lock);
     //spin_unlock_irq(&pDevice->lock);
 
 /*
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0],
                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1],
                pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2],
@@ -752,7 +726,7 @@ static int wpa_get_scan(PSDevice pDevice,
 		ret = -EFAULT;
 	};
 	param->u.scan_results.scan_count = count;
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
 
     kfree(pBuf);
     return ret;
@@ -785,12 +759,12 @@ static int wpa_set_associate(PSDevice pDevice,
     BOOL bWepEnabled=FALSE;
 
 	// set key type & algorithm
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
-    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
 
 
 	if (param->u.wpa_associate.wpa_ie &&
@@ -943,59 +917,59 @@ int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
 	switch (param->cmd) {
 	case VIAWGET_SET_WPA:
         ret = wpa_set_wpa(pDevice, param);
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
 		break;
 
 	case VIAWGET_SET_KEY:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
 	    spin_lock_irq(&pDevice->lock);
         ret = wpa_set_keys(pDevice, param, FALSE);
         spin_unlock_irq(&pDevice->lock);
 		break;
 
 	case VIAWGET_SET_SCAN:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
         ret = wpa_set_scan(pDevice, param);
 		break;
 
 	case VIAWGET_GET_SCAN:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
         ret = wpa_get_scan(pDevice, param);
 		wpa_ioctl = 1;
 		break;
 
 	case VIAWGET_GET_SSID:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
         ret = wpa_get_ssid(pDevice, param);
 		wpa_ioctl = 1;
 		break;
 
 	case VIAWGET_GET_BSSID:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
         ret = wpa_get_bssid(pDevice, param);
 		wpa_ioctl = 1;
 		break;
 
 	case VIAWGET_SET_ASSOCIATE:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
         ret = wpa_set_associate(pDevice, param);
 		break;
 
 	case VIAWGET_SET_DISASSOCIATE:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
         ret = wpa_set_disassociate(pDevice, param);
 		break;
 
 	case VIAWGET_SET_DROP_UNENCRYPT:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
 		break;
 
     case VIAWGET_SET_DEAUTHENTICATE:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
 		break;
 
 	default:
-	    DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
 		       param->cmd);
 		return -EOPNOTSUPP;
 		break;
diff --git a/drivers/staging/vt6655/wpactl.h b/drivers/staging/vt6655/wpactl.h
index 9e78897..b0d92d5 100644
--- a/drivers/staging/vt6655/wpactl.h
+++ b/drivers/staging/vt6655/wpactl.h
@@ -26,18 +26,13 @@
  *
  */
 
-
 #ifndef __WPACTL_H__
 #define __WPACTL_H__
 
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
-#if !defined(__IOWPA_H__)
 #include "iowpa.h"
 #endif
-#endif
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -67,22 +62,10 @@ typedef ULONGLONG   NDIS_802_11_KEY_RSC;
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 int wpa_set_wpadev(PSDevice pDevice, int val);
 int wpa_ioctl(PSDevice pDevice, struct iw_point *p);
 int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __WPACL_H__
 
 
diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c
index 219ae21..ab99161 100644
--- a/drivers/staging/vt6655/wroute.c
+++ b/drivers/staging/vt6655/wroute.c
@@ -31,25 +31,13 @@
  *
  */
 
-
-#if !defined(__MAC_H__)
 #include "mac.h"
-#endif
-#if !defined(__TCRC_H__)
 #include "tcrc.h"
-#endif
-#if !defined(__RXTX_H__)
 #include "rxtx.h"
-#endif
-#if !defined(__WROUTE_H__)
 #include "wroute.h"
-#endif
-#if !defined(__CARD_H__)
 #include "card.h"
-#endif
-#if !defined(__BASEBAND_H__)
 #include "baseband.h"
-#endif
+
 /*---------------------  Static Definitions -------------------------*/
 
 /*---------------------  Static Classes  ----------------------------*/
@@ -83,7 +71,7 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
     PSTxDesc        pHeadTD, pLastTD;
     UINT            cbFrameBodySize;
     UINT            uMACfragNum;
-    BYTE            byPktTyp;
+    BYTE            byPktType;
     BOOL            bNeedEncryption = FALSE;
     SKeyItem        STempKey;
     PSKeyItem       pTransmitKey = NULL;
@@ -95,7 +83,7 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
 
 
     if (AVAIL_TD(pDevice, TYPE_AC0DMA)<=0) {
-        DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Relay can't allocate TD1..\n");
         return FALSE;
     }
 
@@ -118,9 +106,9 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
         pbyBSSID = pDevice->abyBroadcastAddr;
         if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
             pTransmitKey = NULL;
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode);
         } else {
-            DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
         }
     }
 
@@ -144,7 +132,7 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
     if (uMACfragNum > AVAIL_TD(pDevice,TYPE_AC0DMA)) {
         return FALSE;
     }
-    byPktTyp = (BYTE)pDevice->byPacketType;
+    byPktType = (BYTE)pDevice->byPacketType;
 
     if (pDevice->bFixRate) {
         if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
@@ -170,9 +158,9 @@ BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeI
     }
 
     if (pDevice->wCurrentRate <= RATE_11M)
-        byPktTyp = PK_TYPE_11B;
+        byPktType = PK_TYPE_11B;
 
-    vGenerateFIFOHeader(pDevice, byPktTyp, pDevice->pbyTmpBuff, bNeedEncryption,
+    vGenerateFIFOHeader(pDevice, byPktType, pDevice->pbyTmpBuff, bNeedEncryption,
                         cbFrameBodySize, TYPE_AC0DMA, pHeadTD,
                         &pDevice->sTxEthHeader, pbySkbData, pTransmitKey, uNodeIndex,
                         &uMACfragNum,
diff --git a/drivers/staging/vt6655/wroute.h b/drivers/staging/vt6655/wroute.h
index ea5f589..295cdc5 100644
--- a/drivers/staging/vt6655/wroute.h
+++ b/drivers/staging/vt6655/wroute.h
@@ -26,16 +26,10 @@
  *
  */
 
-
 #ifndef __WROUTE_H__
 #define __WROUTE_H__
 
-
-#if !defined(__DEVICE_H__)
 #include "device.h"
-#endif
-
-
 
 /*---------------------  Export Definitions -------------------------*/
 
@@ -45,20 +39,8 @@
 
 /*---------------------  Export Functions  --------------------------*/
 
-
-#ifdef __cplusplus
-extern "C" {                            /* Assume C declarations for C++ */
-#endif /* __cplusplus */
-
 BOOL ROUTEbRelay (PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex);
 
-#ifdef __cplusplus
-}                                       /* End of extern "C" { */
-#endif /* __cplusplus */
-
-
-
-
 #endif // __WROUTE_H__
 
 
diff --git a/drivers/staging/vt6656/80211hdr.h b/drivers/staging/vt6656/80211hdr.h
new file mode 100644
index 0000000..e5cee6f
--- /dev/null
+++ b/drivers/staging/vt6656/80211hdr.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: 80211hdr.h
+ *
+ * Purpose: 802.11 MAC headers related pre-defines and macros.
+ *
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Apr 8, 2002
+ *
+ */
+
+#ifndef __80211HDR_H__
+#define __80211HDR_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+// bit type
+#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
+
+// 802.11 frame related, defined as 802.11 spec
+#define WLAN_ADDR_LEN               6
+#define WLAN_CRC_LEN                4
+#define WLAN_CRC32_LEN              4
+#define WLAN_FCS_LEN                4
+#define WLAN_BSSID_LEN              6
+#define WLAN_BSS_TS_LEN             8
+#define WLAN_HDR_ADDR2_LEN          16
+#define WLAN_HDR_ADDR3_LEN          24
+#define WLAN_HDR_ADDR4_LEN          30
+#define WLAN_IEHDR_LEN              2
+#define WLAN_SSID_MAXLEN            32
+//#define WLAN_RATES_MAXLEN           255
+#define WLAN_RATES_MAXLEN           16
+#define WLAN_RATES_MAXLEN_11B       4
+#define WLAN_RSN_MAXLEN             32
+#define WLAN_DATA_MAXLEN            2312
+#define WLAN_A3FR_MAXLEN            (WLAN_HDR_ADDR3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
+
+
+#define WLAN_BEACON_FR_MAXLEN       WLAN_A3FR_MAXLEN
+#define WLAN_ATIM_FR_MAXLEN         (WLAN_HDR_ADDR3_LEN + 0)
+#define WLAN_NULLDATA_FR_MAXLEN     (WLAN_HDR_ADDR3_LEN + 0)
+#define WLAN_DISASSOC_FR_MAXLEN     (WLAN_HDR_ADDR3_LEN + 2)
+#define WLAN_ASSOCREQ_FR_MAXLEN     WLAN_A3FR_MAXLEN
+#define WLAN_ASSOCRESP_FR_MAXLEN    WLAN_A3FR_MAXLEN
+#define WLAN_REASSOCREQ_FR_MAXLEN   WLAN_A3FR_MAXLEN
+#define WLAN_REASSOCRESP_FR_MAXLEN  WLAN_A3FR_MAXLEN
+#define WLAN_PROBEREQ_FR_MAXLEN     WLAN_A3FR_MAXLEN
+#define WLAN_PROBERESP_FR_MAXLEN    WLAN_A3FR_MAXLEN
+#define WLAN_AUTHEN_FR_MAXLEN       WLAN_A3FR_MAXLEN
+#define WLAN_DEAUTHEN_FR_MAXLEN     (WLAN_HDR_ADDR3_LEN + 2)
+
+
+#define WLAN_WEP_NKEYS              4
+#define WLAN_WEP40_KEYLEN           5
+#define WLAN_WEP104_KEYLEN          13
+#define WLAN_WEP232_KEYLEN          29
+//#define WLAN_WEPMAX_KEYLEN          29
+#define WLAN_WEPMAX_KEYLEN          32
+#define WLAN_CHALLENGE_IE_MAXLEN    255
+#define WLAN_CHALLENGE_IE_LEN       130
+#define WLAN_CHALLENGE_LEN          128
+#define WLAN_WEP_IV_LEN             4
+#define WLAN_WEP_ICV_LEN            4
+#define WLAN_FRAGS_MAX              16
+
+// Frame Type
+#define WLAN_TYPE_MGR 0x00
+#define WLAN_TYPE_CTL  0x01
+#define WLAN_TYPE_DATA 0x02
+
+#define WLAN_FTYPE_MGMT 0x00
+#define WLAN_FTYPE_CTL  0x01
+#define WLAN_FTYPE_DATA 0x02
+
+
+// Frame Subtypes
+#define WLAN_FSTYPE_ASSOCREQ        0x00
+#define WLAN_FSTYPE_ASSOCRESP       0x01
+#define WLAN_FSTYPE_REASSOCREQ      0x02
+#define WLAN_FSTYPE_REASSOCRESP     0x03
+#define WLAN_FSTYPE_PROBEREQ        0x04
+#define WLAN_FSTYPE_PROBERESP       0x05
+#define WLAN_FSTYPE_BEACON          0x08
+#define WLAN_FSTYPE_ATIM            0x09
+#define WLAN_FSTYPE_DISASSOC        0x0a
+#define WLAN_FSTYPE_AUTHEN          0x0b
+#define WLAN_FSTYPE_DEAUTHEN        0x0c
+#define WLAN_FSTYPE_ACTION          0x0d
+
+// Control
+#define WLAN_FSTYPE_PSPOLL          0x0a
+#define WLAN_FSTYPE_RTS             0x0b
+#define WLAN_FSTYPE_CTS             0x0c
+#define WLAN_FSTYPE_ACK             0x0d
+#define WLAN_FSTYPE_CFEND           0x0e
+#define WLAN_FSTYPE_CFENDCFACK      0x0f
+
+// Data
+#define WLAN_FSTYPE_DATAONLY        0x00
+#define WLAN_FSTYPE_DATA_CFACK      0x01
+#define WLAN_FSTYPE_DATA_CFPOLL     0x02
+#define WLAN_FSTYPE_DATA_CFACK_CFPOLL   0x03
+#define WLAN_FSTYPE_NULL            0x04
+#define WLAN_FSTYPE_CFACK           0x05
+#define WLAN_FSTYPE_CFPOLL          0x06
+#define WLAN_FSTYPE_CFACK_CFPOLL    0x07
+
+
+#ifdef __BIG_ENDIAN
+
+// GET & SET Frame Control bit
+#define WLAN_GET_FC_PRVER(n)    ((((WORD)(n) >> 8) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n)    ((((WORD)(n) >> 8) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)   ((((WORD)(n) >> 8) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n)     ((((WORD)(n) << 8) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n)   ((((WORD)(n) << 8) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n) << 8) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n)    ((((WORD)(n) << 8) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n)   ((((WORD)(n) << 8) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n) << 8) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n)    ((((WORD)(n) << 8) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n)    ((((WORD)(n) << 8) & (BIT15)) >> 15)
+
+// Sequence Field bit
+#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n) >> 8) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n) >> 8) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+
+
+// Capability Field bit
+#define WLAN_GET_CAP_INFO_ESS(n)           (((n) >> 8) & BIT0)
+#define WLAN_GET_CAP_INFO_IBSS(n)          ((((n) >> 8) & BIT1) >> 1)
+#define WLAN_GET_CAP_INFO_CFPOLLABLE(n)    ((((n) >> 8) & BIT2) >> 2)
+#define WLAN_GET_CAP_INFO_CFPOLLREQ(n)     ((((n) >> 8) & BIT3) >> 3)
+#define WLAN_GET_CAP_INFO_PRIVACY(n)       ((((n) >> 8) & BIT4) >> 4)
+#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) ((((n) >> 8) & BIT5) >> 5)
+#define WLAN_GET_CAP_INFO_PBCC(n)          ((((n) >> 8) & BIT6) >> 6)
+#define WLAN_GET_CAP_INFO_AGILITY(n)       ((((n) >> 8) & BIT7) >> 7)
+#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n)   ((((n))      & BIT8) >> 10)
+#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) ((((n))      & BIT10) >> 10)
+#define WLAN_GET_CAP_INFO_DSSSOFDM(n)      ((((n))      & BIT13) >> 13)
+#define WLAN_GET_CAP_INFO_GRPACK(n)        ((((n))      & BIT14) >> 14)
+
+
+#else
+
+// GET & SET Frame Control bit
+#define WLAN_GET_FC_PRVER(n)    (((WORD)(n)) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n)    ((((WORD)(n)) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)   ((((WORD)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n)     ((((WORD)(n)) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n)   ((((WORD)(n)) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((WORD)(n)) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n)    ((((WORD)(n)) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n)   ((((WORD)(n)) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((WORD)(n)) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n)    ((((WORD)(n)) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n)    ((((WORD)(n)) & (BIT15)) >> 15)
+
+
+// Sequence Field bit
+#define WLAN_GET_SEQ_FRGNUM(n) (((WORD)(n)) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((WORD)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+
+
+// Capability Field bit
+#define WLAN_GET_CAP_INFO_ESS(n)           ((n) & BIT0)
+#define WLAN_GET_CAP_INFO_IBSS(n)          (((n) & BIT1) >> 1)
+#define WLAN_GET_CAP_INFO_CFPOLLABLE(n)    (((n) & BIT2) >> 2)
+#define WLAN_GET_CAP_INFO_CFPOLLREQ(n)     (((n) & BIT3) >> 3)
+#define WLAN_GET_CAP_INFO_PRIVACY(n)       (((n) & BIT4) >> 4)
+#define WLAN_GET_CAP_INFO_SHORTPREAMBLE(n) (((n) & BIT5) >> 5)
+#define WLAN_GET_CAP_INFO_PBCC(n)          (((n) & BIT6) >> 6)
+#define WLAN_GET_CAP_INFO_AGILITY(n)       (((n) & BIT7) >> 7)
+#define WLAN_GET_CAP_INFO_SPECTRUMMNG(n)   (((n) & BIT8) >> 10)
+#define WLAN_GET_CAP_INFO_SHORTSLOTTIME(n) (((n) & BIT10) >> 10)
+#define WLAN_GET_CAP_INFO_DSSSOFDM(n)      (((n) & BIT13) >> 13)
+#define WLAN_GET_CAP_INFO_GRPACK(n)        (((n) & BIT14) >> 14)
+
+
+#endif //#ifdef __BIG_ENDIAN
+
+
+#define WLAN_SET_CAP_INFO_ESS(n)           (n)
+#define WLAN_SET_CAP_INFO_IBSS(n)          ((n) << 1)
+#define WLAN_SET_CAP_INFO_CFPOLLABLE(n)    ((n) << 2)
+#define WLAN_SET_CAP_INFO_CFPOLLREQ(n)     ((n) << 3)
+#define WLAN_SET_CAP_INFO_PRIVACY(n)       ((n) << 4)
+#define WLAN_SET_CAP_INFO_SHORTPREAMBLE(n) ((n) << 5)
+#define WLAN_SET_CAP_INFO_SPECTRUMMNG(n)   ((n) << 8)
+#define WLAN_SET_CAP_INFO_PBCC(n)          ((n) << 6)
+#define WLAN_SET_CAP_INFO_AGILITY(n)       ((n) << 7)
+#define WLAN_SET_CAP_INFO_SHORTSLOTTIME(n) ((n) << 10)
+#define WLAN_SET_CAP_INFO_DSSSOFDM(n)      ((n) << 13)
+#define WLAN_SET_CAP_INFO_GRPACK(n)        ((n) << 14)
+
+
+#define WLAN_SET_FC_PRVER(n)    ((WORD)(n))
+#define WLAN_SET_FC_FTYPE(n)    (((WORD)(n)) << 2)
+#define WLAN_SET_FC_FSTYPE(n)   (((WORD)(n)) << 4)
+#define WLAN_SET_FC_TODS(n)     (((WORD)(n)) << 8)
+#define WLAN_SET_FC_FROMDS(n)   (((WORD)(n)) << 9)
+#define WLAN_SET_FC_MOREFRAG(n) (((WORD)(n)) << 10)
+#define WLAN_SET_FC_RETRY(n)    (((WORD)(n)) << 11)
+#define WLAN_SET_FC_PWRMGT(n)   (((WORD)(n)) << 12)
+#define WLAN_SET_FC_MOREDATA(n) (((WORD)(n)) << 13)
+#define WLAN_SET_FC_ISWEP(n)    (((WORD)(n)) << 14)
+#define WLAN_SET_FC_ORDER(n)    (((WORD)(n)) << 15)
+
+#define WLAN_SET_SEQ_FRGNUM(n) ((WORD)(n))
+#define WLAN_SET_SEQ_SEQNUM(n) (((WORD)(n)) << 4)
+
+// ERP Field bit
+
+#define WLAN_GET_ERP_NONERP_PRESENT(n)     ((n) & BIT0)
+#define WLAN_GET_ERP_USE_PROTECTION(n)     (((n) & BIT1) >> 1)
+#define WLAN_GET_ERP_BARKER_MODE(n)        (((n) & BIT2) >> 2)
+
+#define WLAN_SET_ERP_NONERP_PRESENT(n)     (n)
+#define WLAN_SET_ERP_USE_PROTECTION(n)     ((n) << 1)
+#define WLAN_SET_ERP_BARKER_MODE(n)        ((n) << 2)
+
+
+
+// Support & Basic Rates field
+#define WLAN_MGMT_IS_BASICRATE(b)    ((b) & BIT7)
+#define WLAN_MGMT_GET_RATE(b)        ((b) & ~BIT7)
+
+// TIM field
+#define WLAN_MGMT_IS_MULTICAST_TIM(b)   ((b) & BIT0)
+#define WLAN_MGMT_GET_TIM_OFFSET(b)     (((b) & ~BIT0) >> 1)
+
+// 3-Addr & 4-Addr
+#define WLAN_HDR_A3_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR3_LEN)
+#define WLAN_HDR_A4_DATA_PTR(p) (((PBYTE)(p)) + WLAN_HDR_ADDR4_LEN)
+
+// IEEE ADDR
+#define IEEE_ADDR_UNIVERSAL         0x02
+#define IEEE_ADDR_GROUP             0x01
+
+typedef struct {
+    BYTE            abyAddr[6];
+} IEEE_ADDR, *PIEEE_ADDR;
+
+// 802.11 Header Format
+
+typedef struct tagWLAN_80211HDR_A2 {
+
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[WLAN_ADDR_LEN];
+    BYTE    abyAddr2[WLAN_ADDR_LEN];
+
+}__attribute__ ((__packed__))
+WLAN_80211HDR_A2, *PWLAN_80211HDR_A2;
+
+typedef struct tagWLAN_80211HDR_A3 {
+
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[WLAN_ADDR_LEN];
+    BYTE    abyAddr2[WLAN_ADDR_LEN];
+    BYTE    abyAddr3[WLAN_ADDR_LEN];
+    WORD    wSeqCtl;
+
+}__attribute__ ((__packed__))
+WLAN_80211HDR_A3, *PWLAN_80211HDR_A3;
+
+typedef struct tagWLAN_80211HDR_A4 {
+
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[WLAN_ADDR_LEN];
+    BYTE    abyAddr2[WLAN_ADDR_LEN];
+    BYTE    abyAddr3[WLAN_ADDR_LEN];
+    WORD    wSeqCtl;
+    BYTE    abyAddr4[WLAN_ADDR_LEN];
+
+}__attribute__ ((__packed__))
+WLAN_80211HDR_A4, *PWLAN_80211HDR_A4;
+
+
+typedef union tagUWLAN_80211HDR {
+
+    WLAN_80211HDR_A2        sA2;
+    WLAN_80211HDR_A3        sA3;
+    WLAN_80211HDR_A4        sA4;
+
+} UWLAN_80211HDR, *PUWLAN_80211HDR;
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+#endif // __80211HDR_H__
+
+
diff --git a/drivers/staging/vt6656/80211mgr.c b/drivers/staging/vt6656/80211mgr.c
new file mode 100644
index 0000000..8fa1a8e
--- /dev/null
+++ b/drivers/staging/vt6656/80211mgr.c
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: 80211mgr.c
+ *
+ * Purpose: Handles the 802.11 managment support functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ * Functions:
+ *      vMgrEncodeBeacon - Encode the Beacon frame
+ *      vMgrDecodeBeacon - Decode the Beacon frame
+ *      vMgrEncodeIBSSATIM - Encode the IBSS ATIM frame
+ *      vMgrDecodeIBSSATIM - Decode the IBSS ATIM frame
+ *      vMgrEncodeDisassociation - Encode the Disassociation frame
+ *      vMgrDecodeDisassociation - Decode the Disassociation frame
+ *      vMgrEncodeAssocRequest - Encode the Association request frame
+ *      vMgrDecodeAssocRequest - Decode the Association request frame
+ *      vMgrEncodeAssocResponse - Encode the Association response frame
+ *      vMgrDecodeAssocResponse - Decode the Association response frame
+ *      vMgrEncodeReAssocRequest - Encode the ReAssociation request frame
+ *      vMgrDecodeReAssocRequest - Decode the ReAssociation request frame
+ *      vMgrEncodeProbeRequest - Encode the Probe request frame
+ *      vMgrDecodeProbeRequest - Decode the Probe request frame
+ *      vMgrEncodeProbeResponse - Encode the Probe response frame
+ *      vMgrDecodeProbeResponse - Decode the Probe response frame
+ *      vMgrEncodeAuthen - Encode the Authentication frame
+ *      vMgrDecodeAuthen - Decode the Authentication frame
+ *      vMgrEncodeDeauthen - Encode the DeAuthentication frame
+ *      vMgrDecodeDeauthen - Decode the DeAuthentication frame
+ *      vMgrEncodeReassocResponse - Encode the Reassociation response frame
+ *      vMgrDecodeReassocResponse - Decode the Reassociation response frame
+ *
+ * Revision History:
+ *
+ */
+
+#include "tmacro.h"
+#include "tether.h"
+#include "80211mgr.h"
+#include "80211hdr.h"
+#include "device.h"
+#include "wpa.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Functions  --------------------------*/
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ * Routine Description:
+ * Encode Beacon frame body offset
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_BEACON_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_BEACON_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_BEACON_OFF_CAPINFO);
+
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_BEACON_OFF_SSID;
+
+    return;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Decode Beacon frame body offset
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrDecodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+    )
+{
+    PWLAN_IE        pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_BEACON_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_BEACON_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_BEACON_OFF_CAPINFO);
+
+    // Information elements
+    pItem = (PWLAN_IE)((PBYTE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)))
+                       + WLAN_BEACON_OFF_SSID);
+    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ){
+
+        switch (pItem->byElementID) {
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+            case WLAN_EID_FH_PARMS:
+                //pFrame->pFHParms = (PWLAN_IE_FH_PARMS)pItem;
+                break;
+            case WLAN_EID_DS_PARMS:
+                if (pFrame->pDSParms == NULL)
+                    pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+                break;
+            case WLAN_EID_CF_PARMS:
+                if (pFrame->pCFParms == NULL)
+                    pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+                break;
+            case WLAN_EID_IBSS_PARMS:
+                if (pFrame->pIBSSParms == NULL)
+                    pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+                break;
+            case WLAN_EID_TIM:
+                if (pFrame->pTIM == NULL)
+                    pFrame->pTIM = (PWLAN_IE_TIM)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+
+            case WLAN_EID_ERP:
+                if (pFrame->pERP == NULL)
+                    pFrame->pERP = (PWLAN_IE_ERP)pItem;
+                break;
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_COUNTRY:      //7
+                if (pFrame->pIE_Country == NULL)
+                    pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+                break;
+
+            case WLAN_EID_PWR_CONSTRAINT:   //32
+                if (pFrame->pIE_PowerConstraint == NULL)
+                    pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+                break;
+
+            case WLAN_EID_CH_SWITCH:    //37
+                if (pFrame->pIE_CHSW == NULL)
+                    pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+                break;
+
+            case WLAN_EID_QUIET:        //40
+                if (pFrame->pIE_Quiet == NULL)
+                    pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+                break;
+
+            case WLAN_EID_IBSS_DFS:
+                if (pFrame->pIE_IBSSDFS == NULL)
+                    pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", pItem->byElementID);
+                break;
+
+        }
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    }
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode IBSS ATIM
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    pFrame->len = WLAN_HDR_ADDR3_LEN;
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode IBSS ATIM
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Disassociation
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DISASSOC_OFF_REASON);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DISASSOC_OFF_REASON + sizeof(*(pFrame->pwReason));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Disassociation
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DISASSOC_OFF_REASON);
+
+    return;
+}
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Association Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_ASSOCREQ_OFF_LISTEN_INT);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCREQ_OFF_LISTEN_INT + sizeof(*(pFrame->pwListenInterval));
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description: (AP)
+ *  Decode Association Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCREQ_OFF_LISTEN_INT);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_ASSOCREQ_OFF_SSID);
+
+    while (((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
+        switch (pItem->byElementID){
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n",
+                        pItem->byElementID);
+                break;
+        }
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    }
+    return;
+}
+
+/*+
+ *
+ * Routine Description: (AP)
+ *  Encode Association Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeAssocResponse(
+    IN  PWLAN_FR_ASSOCRESP  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_ASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_ASSOCRESP_OFF_AID);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_ASSOCRESP_OFF_AID
+                  + sizeof(*(pFrame->pwAid));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Association Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeAssocResponse(
+    IN PWLAN_FR_ASSOCRESP  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_ASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_ASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_ASSOCRESP_OFF_AID);
+
+    // Information elements
+    pFrame->pSuppRates  = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                           + WLAN_ASSOCRESP_OFF_SUPP_RATES);
+
+    pItem = (PWLAN_IE)(pFrame->pSuppRates);
+    pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+        pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pFrame->pExtSuppRates=[%p].\n", pItem);
+    }
+    else {
+        pFrame->pExtSuppRates = NULL;
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Reassociation Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_REASSOCREQ_OFF_LISTEN_INT);
+    pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_REASSOCREQ_OFF_CURR_AP);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCREQ_OFF_CURR_AP + sizeof(*(pFrame->pAddrCurrAP));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description: (AP)
+ *  Decode Reassociation Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrDecodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCREQ_OFF_CAP_INFO);
+    pFrame->pwListenInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_REASSOCREQ_OFF_LISTEN_INT);
+    pFrame->pAddrCurrAP = (PIEEE_ADDR)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_REASSOCREQ_OFF_CURR_AP);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                       + WLAN_REASSOCREQ_OFF_SSID);
+
+    while(((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) {
+
+        switch (pItem->byElementID){
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n",
+                            pItem->byElementID);
+                break;
+        }
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Probe Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+    pFrame->len = WLAN_HDR_ADDR3_LEN;
+    return;
+}
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Probe Request
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)));
+
+    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+
+        switch (pItem->byElementID) {
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                    pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in probereq\n", pItem->byElementID);
+                break;
+        }
+
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Encode Probe Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrEncodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_PROBERESP_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_PROBERESP_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_PROBERESP_OFF_CAP_INFO);
+
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_PROBERESP_OFF_CAP_INFO +
+                  sizeof(*(pFrame->pwCapInfo));
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Decode Probe Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    )
+{
+    PWLAN_IE    pItem;
+
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pqwTimestamp = (PQWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                    + WLAN_PROBERESP_OFF_TS);
+    pFrame->pwBeaconInterval = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                       + WLAN_PROBERESP_OFF_BCN_INT);
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_PROBERESP_OFF_CAP_INFO);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                       + WLAN_PROBERESP_OFF_SSID);
+
+    while( ((PBYTE)pItem) < (pFrame->pBuf + pFrame->len) ) {
+        switch (pItem->byElementID) {
+            case WLAN_EID_SSID:
+                if (pFrame->pSSID == NULL)
+                pFrame->pSSID = (PWLAN_IE_SSID)pItem;
+                break;
+            case WLAN_EID_SUPP_RATES:
+                if (pFrame->pSuppRates == NULL)
+                pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+            case WLAN_EID_FH_PARMS:
+                break;
+            case WLAN_EID_DS_PARMS:
+                if (pFrame->pDSParms == NULL)
+                    pFrame->pDSParms = (PWLAN_IE_DS_PARMS)pItem;
+                break;
+            case WLAN_EID_CF_PARMS:
+                if (pFrame->pCFParms == NULL)
+                    pFrame->pCFParms = (PWLAN_IE_CF_PARMS)pItem;
+                break;
+            case WLAN_EID_IBSS_PARMS:
+                if (pFrame->pIBSSParms == NULL)
+                    pFrame->pIBSSParms = (PWLAN_IE_IBSS_PARMS)pItem;
+                break;
+
+            case WLAN_EID_RSN:
+                if (pFrame->pRSN == NULL) {
+                    pFrame->pRSN = (PWLAN_IE_RSN)pItem;
+                }
+                break;
+            case WLAN_EID_RSN_WPA:
+                if (pFrame->pRSNWPA == NULL) {
+                    if (WPAb_Is_RSN((PWLAN_IE_RSN_EXT)pItem) == TRUE)
+                        pFrame->pRSNWPA = (PWLAN_IE_RSN_EXT)pItem;
+                }
+                break;
+            case WLAN_EID_ERP:
+                if (pFrame->pERP == NULL)
+                    pFrame->pERP = (PWLAN_IE_ERP)pItem;
+                break;
+            case WLAN_EID_EXTSUPP_RATES:
+                if (pFrame->pExtSuppRates == NULL)
+                    pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+                break;
+
+            case WLAN_EID_COUNTRY:      //7
+                if (pFrame->pIE_Country == NULL)
+                    pFrame->pIE_Country = (PWLAN_IE_COUNTRY)pItem;
+                break;
+
+            case WLAN_EID_PWR_CONSTRAINT:   //32
+                if (pFrame->pIE_PowerConstraint == NULL)
+                    pFrame->pIE_PowerConstraint = (PWLAN_IE_PW_CONST)pItem;
+                break;
+
+            case WLAN_EID_CH_SWITCH:    //37
+                if (pFrame->pIE_CHSW == NULL)
+                    pFrame->pIE_CHSW = (PWLAN_IE_CH_SW)pItem;
+                break;
+
+            case WLAN_EID_QUIET:        //40
+                if (pFrame->pIE_Quiet == NULL)
+                    pFrame->pIE_Quiet = (PWLAN_IE_QUIET)pItem;
+                break;
+
+            case WLAN_EID_IBSS_DFS:
+                if (pFrame->pIE_IBSSDFS == NULL)
+                    pFrame->pIE_IBSSDFS = (PWLAN_IE_IBSS_DFS)pItem;
+                break;
+
+            default:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Bad EID=%dd in proberesp\n", pItem->byElementID);
+                break;
+        }
+
+        pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 +  pItem->len);
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *     Encode Authentication frame
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_AUTHEN_OFF_AUTH_ALG);
+    pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                     + WLAN_AUTHEN_OFF_AUTH_SEQ);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_AUTHEN_OFF_STATUS);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_AUTHEN_OFF_STATUS + sizeof(*(pFrame->pwStatus));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Decode Authentication
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    )
+{
+    PWLAN_IE    pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwAuthAlgorithm = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                      + WLAN_AUTHEN_OFF_AUTH_ALG);
+    pFrame->pwAuthSequence = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                     + WLAN_AUTHEN_OFF_AUTH_SEQ);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_AUTHEN_OFF_STATUS);
+
+    // Information elements
+    pItem = (PWLAN_IE)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                       + WLAN_AUTHEN_OFF_CHALLENGE);
+
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_CHALLENGE)) {
+        pFrame->pChallenge = (PWLAN_IE_CHALLENGE)pItem;
+    }
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Encode Authentication
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DEAUTHEN_OFF_REASON);
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_DEAUTHEN_OFF_REASON + sizeof(*(pFrame->pwReason));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Decode Deauthentication
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDecodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwReason = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_DEAUTHEN_OFF_REASON);
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description: (AP)
+ *   Encode Reassociation Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrEncodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+     )
+{
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_REASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_REASSOCRESP_OFF_AID);
+
+    pFrame->len = WLAN_HDR_ADDR3_LEN + WLAN_REASSOCRESP_OFF_AID + sizeof(*(pFrame->pwAid));
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Decode Reassociation Response
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrDecodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+     )
+{
+    PWLAN_IE   pItem;
+
+    pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf;
+
+    // Fixed Fields
+    pFrame->pwCapInfo = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                + WLAN_REASSOCRESP_OFF_CAP_INFO);
+    pFrame->pwStatus = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                               + WLAN_REASSOCRESP_OFF_STATUS);
+    pFrame->pwAid = (PWORD)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                            + WLAN_REASSOCRESP_OFF_AID);
+
+    //Information elements
+    pFrame->pSuppRates = (PWLAN_IE_SUPP_RATES)(WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3))
+                                               + WLAN_REASSOCRESP_OFF_SUPP_RATES);
+
+    pItem = (PWLAN_IE)(pFrame->pSuppRates);
+    pItem = (PWLAN_IE)(((PBYTE)pItem) + 2 + pItem->len);
+
+    if ((((PBYTE)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) {
+        pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem;
+    }
+    return;
+}
diff --git a/drivers/staging/vt6656/80211mgr.h b/drivers/staging/vt6656/80211mgr.h
new file mode 100644
index 0000000..a4ea824
--- /dev/null
+++ b/drivers/staging/vt6656/80211mgr.h
@@ -0,0 +1,861 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: 80211mgr.h
+ *
+ * Purpose: 802.11 managment frames pre-defines.
+ *
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __80211MGR_H__
+#define __80211MGR_H__
+
+#include "ttype.h"
+#include "80211hdr.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define WLAN_MIN_ARRAY          1
+
+// Information Element ID value
+#define WLAN_EID_SSID           0
+#define WLAN_EID_SUPP_RATES     1
+#define WLAN_EID_FH_PARMS       2
+#define WLAN_EID_DS_PARMS       3
+#define WLAN_EID_CF_PARMS       4
+#define WLAN_EID_TIM            5
+#define WLAN_EID_IBSS_PARMS     6
+#define WLAN_EID_COUNTRY        7
+#define WLAN_EID_CHALLENGE      16
+#define WLAN_EID_PWR_CONSTRAINT 32
+#define WLAN_EID_PWR_CAPABILITY 33
+#define WLAN_EID_TPC_REQ        34
+#define WLAN_EID_TPC_REP        35
+#define WLAN_EID_SUPP_CH        36
+#define WLAN_EID_CH_SWITCH      37
+#define WLAN_EID_MEASURE_REQ    38
+#define WLAN_EID_MEASURE_REP    39
+#define WLAN_EID_QUIET          40
+#define WLAN_EID_IBSS_DFS       41
+#define WLAN_EID_ERP            42
+// reference 802.11i 7.3.2 table 20
+#define WLAN_EID_RSN            48
+#define WLAN_EID_EXTSUPP_RATES  50
+// reference WiFi WPA spec.
+#define WLAN_EID_RSN_WPA        221
+
+#ifdef Cisco_ccx
+#define WLAN_EID_CCX        133            //DavidWang
+#define WLAN_EID_CCX_IP        149            //DavidWang
+#define WLAN_EID_CCX_Ver        221            //DavidWang
+#endif
+
+#define WLAN_EID_ERP_NONERP_PRESENT             0x01
+#define WLAN_EID_ERP_USE_PROTECTION             0x02
+#define WLAN_EID_ERP_BARKER_MODE                0x04
+
+// Reason Codes
+#define WLAN_MGMT_REASON_RSVD                       0
+#define WLAN_MGMT_REASON_UNSPEC                     1
+#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID         2
+#define WLAN_MGMT_REASON_DEAUTH_LEAVING             3
+#define WLAN_MGMT_REASON_DISASSOC_INACTIVE          4
+#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY           5
+#define WLAN_MGMT_REASON_CLASS2_NONAUTH             6
+#define WLAN_MGMT_REASON_CLASS3_NONASSOC            7
+#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT       8
+#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH         9
+#define WLAN_MGMT_REASON_DISASSOC_PWR_CAP_UNACCEPT      10
+#define WLAN_MGMT_REASON_DISASSOC_SUPP_CH_UNACCEPT      11
+#define WLAN_MGMT_REASON_INVALID_IE                 13
+#define WLAN_MGMT_REASON_MIC_FAILURE                14
+#define WLAN_MGMT_REASON_4WAY_HANDSHAKE_TIMEOUT     15
+#define WLAN_MGMT_REASON_GRPKEY_UPDATE_TIMEOUT      16
+#define WLAN_MGMT_REASON_4WAY_INFO_DIFFERENT        17
+#define WLAN_MGMT_REASON_MULTCAST_CIPHER_INVALID    18
+#define WLAN_MGMT_REASON_UNCAST_CIPHER_INVALID      19
+#define WLAN_MGMT_REASON_AKMP_INVALID               20
+#define WLAN_MGMT_REASON_RSNE_UNSUPPORTED           21
+#define WLAN_MGMT_REASON_RSNE_CAP_INVALID           22
+#define WLAN_MGMT_REASON_80211X_AUTH_FAILED         23
+
+// Status Codes
+#define WLAN_MGMT_STATUS_SUCCESS                        0
+#define WLAN_MGMT_STATUS_UNSPEC_FAILURE                 1
+#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED               10
+#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC               11
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC            12
+#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG            13
+#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ                  14
+#define WLAN_MGMT_STATUS_CHALLENGE_FAIL                 15
+#define WLAN_MGMT_STATUS_AUTH_TIMEOUT                   16
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY              17
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES             18
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE     19
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC              20
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY           21
+
+// reference 802.11h 7.3.1.9
+//
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SPECTRUM_MNG  22
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_PWR_CAP       23
+#define WLAN_MGMT_STATUS_ASSOC_REJECT_BCS_SUPP_CH       24
+//
+// reference 802.11g 7.3.1.9
+//
+#define WLAN_MGMT_STATUS_SHORTSLOTTIME_UNSUPPORTED      25
+#define WLAN_MGMT_STATUS_DSSSOFDM_UNSUPPORTED           26
+//
+// reference 802.11i 7.3.1.9 table 19
+//
+#define WLAN_MGMT_STATUS_INVALID_IE                     40
+#define WLAN_MGMT_STATUS_GROUP_CIPHER_INVALID           41
+#define WLAN_MGMT_STATUS_PAIRWISE_CIPHER_INVALID        42
+#define WLAN_MGMT_STATUS_AKMP_INVALID                   43
+#define WLAN_MGMT_STATUS_UNSUPPORT_RSN_IE_VER           44
+#define WLAN_MGMT_STATUS_INVALID_RSN_IE_CAP             45
+#define WLAN_MGMT_STATUS_CIPHER_REJECT                  46
+
+
+
+// Auth Algorithm
+#define WLAN_AUTH_ALG_OPENSYSTEM                0
+#define WLAN_AUTH_ALG_SHAREDKEY                 1
+
+
+
+// Management Frame Field Offsets
+// Note: Not all fields are listed because of variable lengths.
+// Note: These offsets are from the start of the frame data
+
+#define WLAN_BEACON_OFF_TS                  0
+#define WLAN_BEACON_OFF_BCN_INT             8
+#define WLAN_BEACON_OFF_CAPINFO             10
+#define WLAN_BEACON_OFF_SSID                12
+
+#define WLAN_DISASSOC_OFF_REASON            0
+
+#define WLAN_ASSOCREQ_OFF_CAP_INFO          0
+#define WLAN_ASSOCREQ_OFF_LISTEN_INT        2
+#define WLAN_ASSOCREQ_OFF_SSID              4
+
+#define WLAN_ASSOCRESP_OFF_CAP_INFO         0
+#define WLAN_ASSOCRESP_OFF_STATUS           2
+#define WLAN_ASSOCRESP_OFF_AID              4
+#define WLAN_ASSOCRESP_OFF_SUPP_RATES       6
+
+#define WLAN_REASSOCREQ_OFF_CAP_INFO        0
+#define WLAN_REASSOCREQ_OFF_LISTEN_INT      2
+#define WLAN_REASSOCREQ_OFF_CURR_AP         4
+#define WLAN_REASSOCREQ_OFF_SSID            10
+
+#define WLAN_REASSOCRESP_OFF_CAP_INFO       0
+#define WLAN_REASSOCRESP_OFF_STATUS         2
+#define WLAN_REASSOCRESP_OFF_AID            4
+#define WLAN_REASSOCRESP_OFF_SUPP_RATES     6
+
+#define WLAN_PROBEREQ_OFF_SSID              0
+
+#define WLAN_PROBERESP_OFF_TS               0
+#define WLAN_PROBERESP_OFF_BCN_INT          8
+#define WLAN_PROBERESP_OFF_CAP_INFO         10
+#define WLAN_PROBERESP_OFF_SSID             12
+
+#define WLAN_AUTHEN_OFF_AUTH_ALG            0
+#define WLAN_AUTHEN_OFF_AUTH_SEQ            2
+#define WLAN_AUTHEN_OFF_STATUS              4
+#define WLAN_AUTHEN_OFF_CHALLENGE           6
+
+#define WLAN_DEAUTHEN_OFF_REASON            0
+
+
+//
+// Cipher Suite Selectors defiened in 802.11i
+//
+#define WLAN_11i_CSS_USE_GROUP              0
+#define WLAN_11i_CSS_WEP40                  1
+#define WLAN_11i_CSS_TKIP                   2
+#define WLAN_11i_CSS_CCMP                   4
+#define WLAN_11i_CSS_WEP104                 5
+#define WLAN_11i_CSS_UNKNOWN                255
+
+//
+// Authentication and Key Management Suite Selectors defined in 802.11i
+//
+#define WLAN_11i_AKMSS_802_1X               1
+#define WLAN_11i_AKMSS_PSK                  2
+#define WLAN_11i_AKMSS_UNKNOWN              255
+
+// Measurement type definitions reference ieee 802.11h Table 20b
+#define MEASURE_TYPE_BASIC      0
+#define MEASURE_TYPE_CCA        1
+#define MEASURE_TYPE_RPI        2
+
+// Measurement request mode definitions reference ieee 802.11h Figure 46h
+#define MEASURE_MODE_ENABLE     0x02
+#define MEASURE_MODE_REQ        0x04
+#define MEASURE_MODE_REP        0x08
+
+// Measurement report mode definitions reference ieee 802.11h Figure 46m
+#define MEASURE_MODE_LATE       0x01
+#define MEASURE_MODE_INCAPABLE  0x02
+#define MEASURE_MODE_REFUSED    0x04
+
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+// Information Element Types
+
+#pragma pack(1)
+typedef struct tagWLAN_IE {
+    BYTE   byElementID;
+    BYTE   len;
+}__attribute__ ((__packed__))
+WLAN_IE, *PWLAN_IE;
+
+
+// Service Set Identity (SSID)
+#pragma pack(1)
+typedef struct tagWLAN_IE_SSID {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   abySSID[1];
+}__attribute__ ((__packed__))
+WLAN_IE_SSID, *PWLAN_IE_SSID;
+
+
+// Supported Rates
+#pragma pack(1)
+typedef struct tagWLAN_IE_SUPP_RATES {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   abyRates[1];
+}__attribute__ ((__packed__))
+WLAN_IE_SUPP_RATES,  *PWLAN_IE_SUPP_RATES;
+
+
+
+// FH Parameter Set
+#pragma pack(1)
+typedef struct _WLAN_IE_FH_PARMS {
+    BYTE    byElementID;
+    BYTE    len;
+    WORD    wDwellTime;
+    BYTE    byHopSet;
+    BYTE    byHopPattern;
+    BYTE    byHopIndex;
+} WLAN_IE_FH_PARMS,  *PWLAN_IE_FH_PARMS;
+
+// DS Parameter Set
+#pragma pack(1)
+typedef struct tagWLAN_IE_DS_PARMS {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byCurrChannel;
+}__attribute__ ((__packed__))
+WLAN_IE_DS_PARMS,  *PWLAN_IE_DS_PARMS;
+
+
+// CF Parameter Set
+#pragma pack(1)
+typedef struct tagWLAN_IE_CF_PARMS {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byCFPCount;
+    BYTE   byCFPPeriod;
+    WORD   wCFPMaxDuration;
+    WORD   wCFPDurRemaining;
+}__attribute__ ((__packed__))
+WLAN_IE_CF_PARMS,  *PWLAN_IE_CF_PARMS;
+
+
+// TIM
+#pragma pack(1)
+typedef struct tagWLAN_IE_TIM {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byDTIMCount;
+    BYTE   byDTIMPeriod;
+    BYTE   byBitMapCtl;
+    BYTE   byVirtBitMap[1];
+}__attribute__ ((__packed__))
+WLAN_IE_TIM,  *PWLAN_IE_TIM;
+
+
+// IBSS Parameter Set
+#pragma pack(1)
+typedef struct tagWLAN_IE_IBSS_PARMS {
+    BYTE   byElementID;
+    BYTE   len;
+    WORD   wATIMWindow;
+}__attribute__ ((__packed__))
+WLAN_IE_IBSS_PARMS, *PWLAN_IE_IBSS_PARMS;
+
+
+// Challenge Text
+#pragma pack(1)
+typedef struct tagWLAN_IE_CHALLENGE {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   abyChallenge[1];
+}__attribute__ ((__packed__))
+WLAN_IE_CHALLENGE,  *PWLAN_IE_CHALLENGE;
+
+
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN_EXT {
+    BYTE byElementID;
+    BYTE len;
+    BYTE abyOUI[4];
+    WORD wVersion;
+    BYTE abyMulticast[4];
+    WORD wPKCount;
+    struct {
+        BYTE abyOUI[4];
+    } PKSList[1]; // the rest is variable so need to
+    // overlay ieauth structure
+} WLAN_IE_RSN_EXT, *PWLAN_IE_RSN_EXT;
+
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN_AUTH {
+    WORD wAuthCount;
+    struct {
+        BYTE abyOUI[4];
+    } AuthKSList[1];
+} WLAN_IE_RSN_AUTH, *PWLAN_IE_RSN_AUTH;
+
+// RSN Identity
+#pragma pack(1)
+typedef struct tagWLAN_IE_RSN {
+    BYTE   byElementID;
+    BYTE   len;
+    WORD   wVersion;
+    BYTE   abyRSN[WLAN_MIN_ARRAY];
+} WLAN_IE_RSN, *PWLAN_IE_RSN;
+
+//DavidWang
+// CCX Identity DavidWang
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX {
+BYTE   byElementID;
+BYTE   len;
+BYTE   abyCCX[30];
+} WLAN_IE_CCX, *PWLAN_IE_CCX;
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX_IP {
+BYTE   byElementID;
+BYTE   len;
+BYTE   abyCCXOUI[4];
+BYTE   abyCCXIP[4];
+BYTE   abyCCXREV[2];
+} WLAN_IE_CCX_IP, *PWLAN_IE_CCX_IP;
+#pragma pack(1)
+typedef struct tagWLAN_IE_CCX_Ver {
+BYTE   byElementID;
+BYTE   len;
+BYTE   abyCCXVer[5];
+} WLAN_IE_CCX_Ver, *PWLAN_IE_CCX_Ver;
+
+//DavidWang
+
+// ERP
+#pragma pack(1)
+typedef struct tagWLAN_IE_ERP {
+    BYTE   byElementID;
+    BYTE   len;
+    BYTE   byContext;
+}__attribute__ ((__packed__))
+WLAN_IE_ERP,  *PWLAN_IE_ERP;
+
+
+#pragma pack(1)
+typedef struct _MEASEURE_REQ {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+} MEASEURE_REQ, *PMEASEURE_REQ,
+  MEASEURE_REQ_BASIC, *PMEASEURE_REQ_BASIC,
+  MEASEURE_REQ_CCA, *PMEASEURE_REQ_CCA,
+  MEASEURE_REQ_RPI, *PMEASEURE_REQ_RPI;
+
+typedef struct _MEASEURE_REP_BASIC {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+    BYTE                byMap;
+} MEASEURE_REP_BASIC, *PMEASEURE_REP_BASIC;
+
+typedef struct _MEASEURE_REP_CCA {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+    BYTE                byCCABusyFraction;
+} MEASEURE_REP_CCA, *PMEASEURE_REP_CCA;
+
+typedef struct _MEASEURE_REP_RPI {
+    BYTE                byChannel;
+    BYTE                abyStartTime[8];
+    BYTE                abyDuration[2];
+    BYTE                abyRPIdensity[8];
+} MEASEURE_REP_RPI, *PMEASEURE_REP_RPI;
+
+typedef union _MEASEURE_REP {
+
+    MEASEURE_REP_BASIC  sBasic;
+    MEASEURE_REP_CCA    sCCA;
+    MEASEURE_REP_RPI    sRPI;
+
+} MEASEURE_REP, *PMEASEURE_REP;
+
+typedef struct _WLAN_IE_MEASURE_REQ {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byToken;
+    BYTE                byMode;
+    BYTE                byType;
+    MEASEURE_REQ        sReq;
+} WLAN_IE_MEASURE_REQ, *PWLAN_IE_MEASURE_REQ;
+
+typedef struct _WLAN_IE_MEASURE_REP {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byToken;
+    BYTE                byMode;
+    BYTE                byType;
+    MEASEURE_REP        sRep;
+} WLAN_IE_MEASURE_REP, *PWLAN_IE_MEASURE_REP;
+
+typedef struct _WLAN_IE_CH_SW {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byMode;
+    BYTE                byChannel;
+    BYTE                byCount;
+} WLAN_IE_CH_SW, *PWLAN_IE_CH_SW;
+
+typedef struct _WLAN_IE_QUIET {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byQuietCount;
+    BYTE                byQuietPeriod;
+    BYTE                abyQuietDuration[2];
+    BYTE                abyQuietOffset[2];
+} WLAN_IE_QUIET, *PWLAN_IE_QUIET;
+
+typedef struct _WLAN_IE_COUNTRY {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                abyCountryString[3];
+    BYTE                abyCountryInfo[3];
+} WLAN_IE_COUNTRY, *PWLAN_IE_COUNTRY;
+
+typedef struct _WLAN_IE_PW_CONST {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byPower;
+} WLAN_IE_PW_CONST, *PWLAN_IE_PW_CONST;
+
+typedef struct _WLAN_IE_PW_CAP {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byMinPower;
+    BYTE                byMaxPower;
+} WLAN_IE_PW_CAP, *PWLAN_IE_PW_CAP;
+
+typedef struct _WLAN_IE_SUPP_CH {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                abyChannelTuple[2];
+} WLAN_IE_SUPP_CH, *PWLAN_IE_SUPP_CH;
+
+typedef struct _WLAN_IE_TPC_REQ {
+    BYTE                byElementID;
+    BYTE                len;
+} WLAN_IE_TPC_REQ, *PWLAN_IE_TPC_REQ;
+
+typedef struct _WLAN_IE_TPC_REP {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                byTxPower;
+    BYTE                byLinkMargin;
+} WLAN_IE_TPC_REP, *PWLAN_IE_TPC_REP;
+
+
+typedef struct _WLAN_IE_IBSS_DFS {
+    BYTE                byElementID;
+    BYTE                len;
+    BYTE                abyDFSOwner[6];
+    BYTE                byDFSRecovery;
+    BYTE                abyChannelMap[2];
+} WLAN_IE_IBSS_DFS, *PWLAN_IE_IBSS_DFS;
+
+#pragma pack()
+
+
+
+// Frame Types
+// prototype structure, all mgmt frame types will start with these members
+typedef struct tagWLAN_FR_MGMT {
+
+    UINT                  uType;
+    UINT                  len;
+    PBYTE                 pBuf;
+    PUWLAN_80211HDR       pHdr;
+
+} WLAN_FR_MGMT,  *PWLAN_FR_MGMT;
+
+// Beacon frame
+typedef struct tagWLAN_FR_BEACON {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    // fixed fields
+    PQWORD                  pqwTimestamp;
+    PWORD                   pwBeaconInterval;
+    PWORD                   pwCapInfo;
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+//  PWLAN_IE_FH_PARMS       pFHParms;
+    PWLAN_IE_DS_PARMS       pDSParms;
+    PWLAN_IE_CF_PARMS       pCFParms;
+    PWLAN_IE_TIM            pTIM;
+    PWLAN_IE_IBSS_PARMS     pIBSSParms;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_ERP            pERP;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+    PWLAN_IE_COUNTRY        pIE_Country;
+    PWLAN_IE_PW_CONST       pIE_PowerConstraint;
+    PWLAN_IE_CH_SW          pIE_CHSW;
+    PWLAN_IE_IBSS_DFS       pIE_IBSSDFS;
+    PWLAN_IE_QUIET          pIE_Quiet;
+
+} WLAN_FR_BEACON, *PWLAN_FR_BEACON;
+
+
+// IBSS ATIM frame
+typedef struct tagWLAN_FR_IBSSATIM {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+
+    // fixed fields
+    // info elements
+    // this frame type has a null body
+
+} WLAN_FR_IBSSATIM, *PWLAN_FR_IBSSATIM;
+
+// Disassociation
+typedef struct tagWLAN_FR_DISASSOC {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwReason;
+    /*-- info elements ----------*/
+
+} WLAN_FR_DISASSOC, *PWLAN_FR_DISASSOC;
+
+// Association Request
+typedef struct tagWLAN_FR_ASSOCREQ {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwListenInterval;
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_CCX            pCCX;
+    PWLAN_IE_CCX_IP            pCCXIP;
+    PWLAN_IE_CCX_Ver            pCCXVER;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+    PWLAN_IE_PW_CAP         pCurrPowerCap;
+    PWLAN_IE_SUPP_CH        pCurrSuppCh;
+
+} WLAN_FR_ASSOCREQ, *PWLAN_FR_ASSOCREQ;
+
+// Association Response
+typedef struct tagWLAN_FR_ASSOCRESP {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwStatus;
+    PWORD                   pwAid;
+    /*-- info elements ----------*/
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_ASSOCRESP, *PWLAN_FR_ASSOCRESP;
+
+// Reassociation Request
+typedef struct tagWLAN_FR_REASSOCREQ {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwListenInterval;
+    PIEEE_ADDR              pAddrCurrAP;
+
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_CCX            pCCX;
+    PWLAN_IE_CCX_IP            pCCXIP;
+    PWLAN_IE_CCX_Ver            pCCXVER;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_REASSOCREQ, *PWLAN_FR_REASSOCREQ;
+
+// Reassociation Response
+typedef struct tagWLAN_FR_REASSOCRESP {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwCapInfo;
+    PWORD                   pwStatus;
+    PWORD                   pwAid;
+    /*-- info elements ----------*/
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_REASSOCRESP, *PWLAN_FR_REASSOCRESP;
+
+// Probe Request
+typedef struct tagWLAN_FR_PROBEREQ {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+
+} WLAN_FR_PROBEREQ, *PWLAN_FR_PROBEREQ;
+
+// Probe Response
+typedef struct tagWLAN_FR_PROBERESP {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PQWORD                  pqwTimestamp;
+    PWORD                   pwBeaconInterval;
+    PWORD                   pwCapInfo;
+    /*-- info elements ----------*/
+    PWLAN_IE_SSID           pSSID;
+    PWLAN_IE_SUPP_RATES     pSuppRates;
+    PWLAN_IE_DS_PARMS       pDSParms;
+    PWLAN_IE_CF_PARMS       pCFParms;
+    PWLAN_IE_IBSS_PARMS     pIBSSParms;
+    PWLAN_IE_RSN            pRSN;
+    PWLAN_IE_RSN_EXT        pRSNWPA;
+    PWLAN_IE_ERP            pERP;
+    PWLAN_IE_SUPP_RATES     pExtSuppRates;
+    PWLAN_IE_COUNTRY        pIE_Country;
+    PWLAN_IE_PW_CONST       pIE_PowerConstraint;
+    PWLAN_IE_CH_SW          pIE_CHSW;
+    PWLAN_IE_IBSS_DFS       pIE_IBSSDFS;
+    PWLAN_IE_QUIET          pIE_Quiet;
+
+} WLAN_FR_PROBERESP, *PWLAN_FR_PROBERESP;
+
+// Authentication
+typedef struct tagWLAN_FR_AUTHEN {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwAuthAlgorithm;
+    PWORD                   pwAuthSequence;
+    PWORD                   pwStatus;
+    /*-- info elements ----------*/
+    PWLAN_IE_CHALLENGE      pChallenge;
+
+} WLAN_FR_AUTHEN, *PWLAN_FR_AUTHEN;
+
+// Deauthenication
+typedef struct tagWLAN_FR_DEAUTHEN {
+
+    UINT                    uType;
+    UINT                    len;
+    PBYTE                   pBuf;
+    PUWLAN_80211HDR         pHdr;
+    /*-- fixed fields -----------*/
+    PWORD                   pwReason;
+
+    /*-- info elements ----------*/
+
+} WLAN_FR_DEAUTHEN, *PWLAN_FR_DEAUTHEN;
+
+/*---------------------  Export Functions  --------------------------*/
+VOID
+vMgrEncodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+     );
+
+VOID
+vMgrDecodeBeacon(
+    IN  PWLAN_FR_BEACON  pFrame
+    );
+
+VOID
+vMgrEncodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    );
+
+VOID
+vMgrDecodeIBSSATIM(
+    IN  PWLAN_FR_IBSSATIM   pFrame
+    );
+
+VOID
+vMgrEncodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    );
+
+VOID
+vMgrDecodeDisassociation(
+    IN  PWLAN_FR_DISASSOC  pFrame
+    );
+
+VOID
+vMgrEncodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    );
+
+VOID
+vMgrDecodeAssocRequest(
+    IN  PWLAN_FR_ASSOCREQ  pFrame
+    );
+
+VOID
+vMgrEncodeAssocResponse(
+    IN  PWLAN_FR_ASSOCRESP  pFrame
+    );
+
+VOID
+vMgrDecodeAssocResponse(
+    IN PWLAN_FR_ASSOCRESP  pFrame
+    );
+
+VOID
+vMgrEncodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+    );
+
+VOID
+vMgrDecodeReassocRequest(
+    IN  PWLAN_FR_REASSOCREQ  pFrame
+    );
+
+VOID
+vMgrEncodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+    );
+
+VOID
+vMgrDecodeProbeRequest(
+    IN PWLAN_FR_PROBEREQ  pFrame
+    );
+
+VOID
+vMgrEncodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    );
+
+VOID
+vMgrDecodeProbeResponse(
+    IN PWLAN_FR_PROBERESP  pFrame
+    );
+
+VOID
+vMgrEncodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    );
+
+VOID
+vMgrDecodeAuthen(
+    IN  PWLAN_FR_AUTHEN  pFrame
+    );
+
+VOID
+vMgrEncodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    );
+
+VOID
+vMgrDecodeDeauthen(
+    IN  PWLAN_FR_DEAUTHEN  pFrame
+    );
+
+VOID
+vMgrEncodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+    );
+
+VOID
+vMgrDecodeReassocResponse(
+    IN  PWLAN_FR_REASSOCRESP  pFrame
+    );
+
+#endif// __80211MGR_H__
diff --git a/drivers/staging/vt6656/Kconfig b/drivers/staging/vt6656/Kconfig
new file mode 100644
index 0000000..3165f2c
--- /dev/null
+++ b/drivers/staging/vt6656/Kconfig
@@ -0,0 +1,6 @@
+config VT6656
+	tristate "VIA Technologies VT6656 support"
+	depends on WIRELESS_EXT && USB
+	---help---
+	This is a vendor-written driver for VIA VT6656.
+
diff --git a/drivers/staging/vt6656/Makefile b/drivers/staging/vt6656/Makefile
new file mode 100644
index 0000000..582a351
--- /dev/null
+++ b/drivers/staging/vt6656/Makefile
@@ -0,0 +1,39 @@
+# TODO: all of these should be removed
+EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DEXPORT_SYMTAB -D__NO_VERSION__
+EXTRA_CFLAGS += -DHOSTAP
+
+vt6656_stage-y +=	main_usb.o \
+			card.o  \
+			mac.o   \
+			baseband.o \
+			wctl.o  \
+			80211mgr.o \
+			wcmd.o\
+			wmgr.o \
+			bssdb.o \
+			wpa2.o \
+			rxtx.o \
+			dpc.o \
+			power.o \
+			datarate.o \
+			mib.o \
+			rc4.o \
+			tether.o \
+			tcrc.o \
+			ioctl.o \
+			hostap.o \
+			wpa.o \
+			key.o \
+			tkip.o \
+			michael.o \
+			rf.o \
+			iwctl.o \
+			wpactl.o \
+			aes_ccmp.o \
+			usbpipe.o \
+			channel.o \
+			control.o \
+			firmware.o \
+			int.o
+
+obj-$(CONFIG_VT6656) +=	vt6656_stage.o
diff --git a/drivers/staging/vt6656/TODO b/drivers/staging/vt6656/TODO
new file mode 100644
index 0000000..17cf50c
--- /dev/null
+++ b/drivers/staging/vt6656/TODO
@@ -0,0 +1,20 @@
+TODO:
+- remove __cplusplus ifdefs -- done
+- remove kernel version compatibility wrappers
+- remove support for older wireless extensions
+- prepare for merge with vt6655 driver:
+  - remove PRINT_K() macro
+  - split rf.c
+  - abstract VT3184 chipset specific code
+- add common vt665x infrastructure
+- kill ttype.h
+- switch to use LIB80211
+- switch to use MAC80211
+- use kernel coding style
+- checkpatch.pl fixes
+- sparse fixes
+- integrate with drivers/net/wireless
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
+Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
+<bzolnier@gmail.com>.
diff --git a/drivers/staging/vt6656/aes_ccmp.c b/drivers/staging/vt6656/aes_ccmp.c
new file mode 100644
index 0000000..401a7d2
--- /dev/null
+++ b/drivers/staging/vt6656/aes_ccmp.c
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: aes_ccmp.c
+ *
+ * Purpose: AES_CCMP decryption
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Feb 15, 2005
+ *
+ * Functions:
+ *      AESbGenCCMP - Parsing RX-packet
+ *
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "80211hdr.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*
+ * SBOX Table
+ */
+
+BYTE sbox_table[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
+};
+
+BYTE dot2_table[256] = {
+0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
+0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
+0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
+0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
+0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
+0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
+0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
+0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
+0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
+0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
+0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
+0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
+0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
+0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
+};
+
+BYTE dot3_table[256] = {
+0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
+0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
+0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
+0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
+0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
+0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
+0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
+0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
+0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
+0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
+0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
+0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
+0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
+0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
+0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
+0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
+};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+void xor_128(BYTE *a, BYTE *b, BYTE *out)
+{
+PDWORD dwPtrA = (PDWORD) a;
+PDWORD dwPtrB = (PDWORD) b;
+PDWORD dwPtrOut =(PDWORD) out;
+
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+}
+
+
+void xor_32(BYTE *a, BYTE *b, BYTE *out)
+{
+PDWORD dwPtrA = (PDWORD) a;
+PDWORD dwPtrB = (PDWORD) b;
+PDWORD dwPtrOut =(PDWORD) out;
+
+    (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++);
+}
+
+void AddRoundKey(BYTE *key, int round)
+{
+BYTE sbox_key[4];
+BYTE rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
+
+    sbox_key[0] = sbox_table[key[13]];
+    sbox_key[1] = sbox_table[key[14]];
+    sbox_key[2] = sbox_table[key[15]];
+    sbox_key[3] = sbox_table[key[12]];
+
+    key[0] = key[0] ^ rcon_table[round];
+    xor_32(&key[0], sbox_key, &key[0]);
+
+    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 SubBytes(BYTE *in, BYTE *out)
+{
+int i;
+
+    for (i=0; i< 16; i++)
+    {
+        out[i] = sbox_table[in[i]];
+    }
+}
+
+void ShiftRows(BYTE *in, BYTE *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 MixColumns(BYTE *in, BYTE *out)
+{
+
+    out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3];
+    out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3];
+    out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]];
+    out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]];
+}
+
+
+void AESv128(BYTE *key, BYTE *data, BYTE *ciphertext)
+{
+int  i;
+int  round;
+BYTE TmpdataA[16];
+BYTE TmpdataB[16];
+BYTE abyRoundKey[16];
+
+    for(i=0; i<16; i++)
+        abyRoundKey[i] = key[i];
+
+    for (round = 0; round < 11; round++)
+    {
+        if (round == 0)
+        {
+            xor_128(abyRoundKey, data, ciphertext);
+            AddRoundKey(abyRoundKey, round);
+        }
+        else if (round == 10)
+        {
+            SubBytes(ciphertext, TmpdataA);
+            ShiftRows(TmpdataA, TmpdataB);
+            xor_128(TmpdataB, abyRoundKey, ciphertext);
+        }
+        else // round 1 ~ 9
+        {
+            SubBytes(ciphertext, TmpdataA);
+            ShiftRows(TmpdataA, TmpdataB);
+            MixColumns(&TmpdataB[0], &TmpdataA[0]);
+            MixColumns(&TmpdataB[4], &TmpdataA[4]);
+            MixColumns(&TmpdataB[8], &TmpdataA[8]);
+            MixColumns(&TmpdataB[12], &TmpdataA[12]);
+            xor_128(TmpdataA, abyRoundKey, ciphertext);
+            AddRoundKey(abyRoundKey, round);
+        }
+    }
+
+}
+
+/*
+ * Description: AES decryption
+ *
+ * Parameters:
+ *  In:
+ *      pbyRxKey            - The key used to decrypt
+ *      pbyFrame            - Starting address of packet header
+ *      wFrameSize          - Total packet size including CRC
+ *  Out:
+ *      none
+ *
+ * Return Value: MIC compare result
+ *
+ */
+BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize)
+{
+BYTE            abyNonce[13];
+BYTE            MIC_IV[16];
+BYTE            MIC_HDR1[16];
+BYTE            MIC_HDR2[16];
+BYTE            abyMIC[16];
+BYTE            abyCTRPLD[16];
+BYTE            abyTmp[16];
+BYTE            abyPlainText[16];
+BYTE            abyLastCipher[16];
+
+PS802_11Header  pMACHeader = (PS802_11Header) pbyFrame;
+PBYTE           pbyIV;
+PBYTE           pbyPayload;
+WORD            wHLen = 22;
+WORD            wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC
+BOOL            bA4 = FALSE;
+BYTE            byTmp;
+WORD            wCnt;
+int             ii,jj,kk;
+
+
+    pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+         bA4 = TRUE;
+         pbyIV += 6;             // 6 is 802.11 address4
+         wHLen += 6;
+         wPayloadSize -= 6;
+    }
+    pbyPayload = pbyIV + 8; //IV-length
+
+    abyNonce[0]  = 0x00; //now is 0, if Qos here will be priority
+    memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
+    abyNonce[7]  = pbyIV[7];
+    abyNonce[8]  = pbyIV[6];
+    abyNonce[9]  = pbyIV[5];
+    abyNonce[10] = pbyIV[4];
+    abyNonce[11] = pbyIV[1];
+    abyNonce[12] = pbyIV[0];
+
+    //MIC_IV
+    MIC_IV[0] = 0x59;
+    memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13);
+    MIC_IV[14] = (BYTE)(wPayloadSize >> 8);
+    MIC_IV[15] = (BYTE)(wPayloadSize & 0xff);
+
+    //MIC_HDR1
+    MIC_HDR1[0] = (BYTE)(wHLen >> 8);
+    MIC_HDR1[1] = (BYTE)(wHLen & 0xff);
+    byTmp = (BYTE)(pMACHeader->wFrameCtl & 0xff);
+    MIC_HDR1[2] = byTmp & 0x8f;
+    byTmp = (BYTE)(pMACHeader->wFrameCtl >> 8);
+    byTmp &= 0x87;
+    MIC_HDR1[3] = byTmp | 0x40;
+    memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, U_ETHER_ADDR_LEN);
+    memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, U_ETHER_ADDR_LEN);
+
+    //MIC_HDR2
+    memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, U_ETHER_ADDR_LEN);
+    byTmp = (BYTE)(pMACHeader->wSeqCtl & 0xff);
+    MIC_HDR2[6] = byTmp & 0x0f;
+    MIC_HDR2[7] = 0;
+    if ( bA4 ) {
+        memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, U_ETHER_ADDR_LEN);
+    } else {
+        MIC_HDR2[8]  = 0x00;
+        MIC_HDR2[9]  = 0x00;
+        MIC_HDR2[10] = 0x00;
+        MIC_HDR2[11] = 0x00;
+        MIC_HDR2[12] = 0x00;
+        MIC_HDR2[13] = 0x00;
+    }
+    MIC_HDR2[14] = 0x00;
+    MIC_HDR2[15] = 0x00;
+
+    //CCMP
+    AESv128(pbyRxKey,MIC_IV,abyMIC);
+    for ( kk=0; kk<16; kk++ ) {
+        abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk];
+    }
+    AESv128(pbyRxKey,abyTmp,abyMIC);
+    for ( kk=0; kk<16; kk++ ) {
+        abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk];
+    }
+    AESv128(pbyRxKey,abyTmp,abyMIC);
+
+    wCnt = 1;
+    abyCTRPLD[0] = 0x01;
+    memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13);
+
+    for(jj=wPayloadSize; jj>16; jj=jj-16) {
+
+        abyCTRPLD[14] = (BYTE) (wCnt >> 8);
+        abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+
+        AESv128(pbyRxKey,abyCTRPLD,abyTmp);
+
+        for ( kk=0; kk<16; kk++ ) {
+            abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk];
+        }
+        for ( kk=0; kk<16; kk++ ) {
+            abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
+        }
+        AESv128(pbyRxKey,abyTmp,abyMIC);
+
+        memcpy(pbyPayload, abyPlainText, 16);
+        wCnt++;
+        pbyPayload += 16;
+    } //for wPayloadSize
+
+    //last payload
+    memcpy(&(abyLastCipher[0]), pbyPayload, jj);
+    for ( ii=jj; ii<16; ii++ ) {
+        abyLastCipher[ii] = 0x00;
+    }
+
+    abyCTRPLD[14] = (BYTE) (wCnt >> 8);
+    abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+
+    AESv128(pbyRxKey,abyCTRPLD,abyTmp);
+    for ( kk=0; kk<16; kk++ ) {
+        abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk];
+    }
+    memcpy(pbyPayload, abyPlainText, jj);
+    pbyPayload += jj;
+
+    //for MIC calculation
+    for ( ii=jj; ii<16; ii++ ) {
+        abyPlainText[ii] = 0x00;
+    }
+    for ( kk=0; kk<16; kk++ ) {
+        abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk];
+    }
+    AESv128(pbyRxKey,abyTmp,abyMIC);
+
+    //=>above is the calculate MIC
+    //--------------------------------------------
+
+    wCnt = 0;
+    abyCTRPLD[14] = (BYTE) (wCnt >> 8);
+    abyCTRPLD[15] = (BYTE) (wCnt & 0xff);
+    AESv128(pbyRxKey,abyCTRPLD,abyTmp);
+    for ( kk=0; kk<8; kk++ ) {
+        abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk];
+    }
+    //=>above is the dec-MIC from packet
+    //--------------------------------------------
+
+    if (  !memcmp(abyMIC,abyTmp,8) ) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+
+}
diff --git a/drivers/staging/vt6656/aes_ccmp.h b/drivers/staging/vt6656/aes_ccmp.h
new file mode 100644
index 0000000..f2ba1d5
--- /dev/null
+++ b/drivers/staging/vt6656/aes_ccmp.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: aes_ccmp.h
+ *
+ * Purpose: AES_CCMP Decryption
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Feb 15, 2005
+ *
+ */
+
+#ifndef __AES_H__
+#define __AES_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+BOOL AESbGenCCMP(PBYTE pbyRxKey, PBYTE pbyFrame, WORD wFrameSize);
+
+#endif //__AES_H__
diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c
new file mode 100644
index 0000000..820a7b8
--- /dev/null
+++ b/drivers/staging/vt6656/baseband.c
@@ -0,0 +1,2105 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.c
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 5, 2002
+ *
+ * Functions:
+ *      BBuGetFrameTime        - Calculate data frame transmitting time
+ *      BBvCaculateParameter   - Caculate PhyLength, PhyService and Phy Signal parameter for baseband Tx
+ *      BBbVT3184Init          - VIA VT3184 baseband chip init code
+ *      BBvLoopbackOn          - Turn on BaseBand Loopback mode
+ *      BBvLoopbackOff         - Turn off BaseBand Loopback mode
+ *
+ * Revision History:
+ *
+ *
+ */
+
+#include "tmacro.h"
+#include "tether.h"
+#include "mac.h"
+#include "baseband.h"
+#include "rf.h"
+#include "srom.h"
+#include "control.h"
+#include "datarate.h"
+#include "rndis.h"
+#include "control.h"
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+
+BYTE abyVT3184_AGC[] = {
+    0x00,   //0
+    0x00,   //1
+    0x02,   //2
+    0x02,   //3  //RobertYu:20060505, 0x04,   //3
+    0x04,   //4
+    0x04,   //5  //RobertYu:20060505, 0x06,   //5
+    0x06,   //6
+    0x06,   //7
+    0x08,   //8
+    0x08,   //9
+    0x0A,   //A
+    0x0A,   //B
+    0x0C,   //C
+    0x0C,   //D
+    0x0E,   //E
+    0x0E,   //F
+    0x10,   //10
+    0x10,   //11
+    0x12,   //12
+    0x12,   //13
+    0x14,   //14
+    0x14,   //15
+    0x16,   //16
+    0x16,   //17
+    0x18,   //18
+    0x18,   //19
+    0x1A,   //1A
+    0x1A,   //1B
+    0x1C,   //1C
+    0x1C,   //1D
+    0x1E,   //1E
+    0x1E,   //1F
+    0x20,   //20
+    0x20,   //21
+    0x22,   //22
+    0x22,   //23
+    0x24,   //24
+    0x24,   //25
+    0x26,   //26
+    0x26,   //27
+    0x28,   //28
+    0x28,   //29
+    0x2A,   //2A
+    0x2A,   //2B
+    0x2C,   //2C
+    0x2C,   //2D
+    0x2E,   //2E
+    0x2E,   //2F
+    0x30,   //30
+    0x30,   //31
+    0x32,   //32
+    0x32,   //33
+    0x34,   //34
+    0x34,   //35
+    0x36,   //36
+    0x36,   //37
+    0x38,   //38
+    0x38,   //39
+    0x3A,   //3A
+    0x3A,   //3B
+    0x3C,   //3C
+    0x3C,   //3D
+    0x3E,   //3E
+    0x3E    //3F
+};
+
+
+BYTE abyVT3184_AL2230[] = {
+        0x31,//00
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,
+        0x70,
+        0x45,//tx   //0x64 for FPGA
+        0x2A,
+        0x76,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,//10
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8e,       //RobertYu:20060522, //0x8d,
+        0x0a,       //RobertYu:20060515, //0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//20
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x0c,       //RobertYu:20060522, //0x10,
+        0x26,//30
+        0x5b,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xaa,
+        0xaa,
+        0xff,
+        0xff,
+        0x79,
+        0x00,
+        0x00,
+        0x0b,
+        0x48,
+        0x04,
+        0x00,//40
+        0x08,
+        0x00,
+        0x08,
+        0x08,
+        0x14,
+        0x05,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x09,
+        0x73,
+        0x00,
+        0xc5,
+        0x00,//50   //RobertYu:20060505, //0x15,//50
+        0x19,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xd0,       //RobertYu:20060505, //0xb0,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xe4,//60
+        0x80,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x98,
+        0x0a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,       //0x80 for FPGA
+        0x03,
+        0x01,
+        0x00,
+        0x00,//70
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8c,//80
+        0x01,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x08,
+        0x00,
+        0x1f,       //RobertYu:20060516, //0x0f,
+        0xb7,
+        0x88,
+        0x47,
+        0xaa,
+        0x00,       //RobertYu:20060505, //0x02,
+        0x20,//90   //RobertYu:20060505, //0x22,//90
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xeb,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x01,
+        0x00,//a0
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x18,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x15,       //RobertYu:20060516, //0x00,
+        0x00,
+        0x18,
+        0x38,//b0
+        0x30,
+        0x00,
+        0x00,
+        0xff,
+        0x0f,
+        0xe4,
+        0xe2,
+        0x00,
+        0x00,
+        0x00,
+        0x03,
+        0x01,
+        0x00,
+        0x00,
+        0x00,
+        0x18,//c0
+        0x20,
+        0x07,
+        0x18,
+        0xff,
+        0xff,       //RobertYu:20060509, //0x2c,
+        0x0e,       //RobertYu:20060530, //0x0c,
+        0x0a,
+        0x0e,
+        0x00,       //RobertYu:20060505, //0x01,
+        0x82,       //RobertYu:20060516, //0x8f,
+        0xa7,
+        0x3c,
+        0x10,
+        0x30,       //RobertYu:20060627, //0x0b,
+        0x05,       //RobertYu:20060516, //0x25,
+        0x40,//d0
+        0x12,
+        0x00,
+        0x00,
+        0x10,
+        0x28,
+        0x80,
+        0x2A,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//e0
+        0xf3,       //RobertYu:20060516, //0xd3,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x12,       //RobertYu:20060627, //0x10,
+        0x00,
+        0xf4,
+        0x00,
+        0xff,
+        0x79,
+        0x20,
+        0x30,
+        0x05,       //RobertYu:20060516, //0x0c,
+        0x00,//f0
+        0x3e,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00
+};
+
+
+
+//{{RobertYu:20060515, new BB setting for VT3226D0
+BYTE abyVT3184_VT3226D0[] = {
+        0x31,//00
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,
+        0x70,
+        0x45,//tx   //0x64 for FPGA
+        0x2A,
+        0x76,
+        0x00,
+        0x00,
+        0x80,
+        0x00,
+        0x00,//10
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8e,       //RobertYu:20060525, //0x8d,
+        0x0a,       //RobertYu:20060515, //0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//20
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x4a,
+        0x00,
+        0x0c,       //RobertYu:20060525, //0x10,
+        0x26,//30
+        0x5b,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xaa,
+        0xaa,
+        0xff,
+        0xff,
+        0x79,
+        0x00,
+        0x00,
+        0x0b,
+        0x48,
+        0x04,
+        0x00,//40
+        0x08,
+        0x00,
+        0x08,
+        0x08,
+        0x14,
+        0x05,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x09,
+        0x73,
+        0x00,
+        0xc5,
+        0x00,//50   //RobertYu:20060505, //0x15,//50
+        0x19,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xd0,       //RobertYu:20060505, //0xb0,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xe4,//60
+        0x80,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x98,
+        0x0a,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,       //0x80 for FPGA
+        0x03,
+        0x01,
+        0x00,
+        0x00,//70
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x8c,//80
+        0x01,
+        0x09,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x08,
+        0x00,
+        0x1f,       //RobertYu:20060515, //0x0f,
+        0xb7,
+        0x88,
+        0x47,
+        0xaa,
+        0x00,       //RobertYu:20060505, //0x02,
+        0x20,//90   //RobertYu:20060505, //0x22,//90
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0xeb,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x01,
+        0x00,//a0
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x18,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x18,
+        0x38,//b0
+        0x30,
+        0x00,
+        0x00,
+        0xff,
+        0x0f,
+        0xe4,
+        0xe2,
+        0x00,
+        0x00,
+        0x00,
+        0x03,
+        0x01,
+        0x00,
+        0x00,
+        0x00,
+        0x18,//c0
+        0x20,
+        0x07,
+        0x18,
+        0xff,
+        0xff,       //RobertYu:20060509, //0x2c,
+        0x10,       //RobertYu:20060525, //0x0c,
+        0x0a,
+        0x0e,
+        0x00,       //RobertYu:20060505, //0x01,
+        0x84,       //RobertYu:20060525, //0x8f,
+        0xa7,
+        0x3c,
+        0x10,
+        0x24,       //RobertYu:20060627, //0x18,
+        0x05,       //RobertYu:20060515, //0x25,
+        0x40,//d0
+        0x12,
+        0x00,
+        0x00,
+        0x10,
+        0x28,
+        0x80,
+        0x2A,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,//e0
+        0xf3,       //RobertYu:20060515, //0xd3,
+        0x00,
+        0x00,
+        0x00,
+        0x10,
+        0x00,
+        0x10,       //RobertYu:20060627, //0x0e,
+        0x00,
+        0xf4,
+        0x00,
+        0xff,
+        0x79,
+        0x20,
+        0x30,
+        0x08,       //RobertYu:20060515, //0x0c,
+        0x00,//f0
+        0x3e,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+        0x00,
+};
+
+const WORD awcFrameTime[MAX_RATE] =
+{10, 20, 55, 110, 24, 36, 48, 72, 96, 144, 192, 216};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*
+static
+ULONG
+s_ulGetLowSQ3(PSDevice pDevice);
+
+static
+ULONG
+s_ulGetRatio(PSDevice pDevice);
+
+static
+void
+s_vClearSQ3Value(PSDevice pDevice);
+*/
+
+/*---------------------  Export Variables  --------------------------*/
+/*
+ * Description: Calculate data frame transmitting time
+ *
+ * Parameters:
+ *  In:
+ *      byPreambleType  - Preamble Type
+ *      byPktType        - PK_TYPE_11A, PK_TYPE_11B, PK_TYPE_11GB, PK_TYPE_11GA
+ *      cbFrameLength   - Baseband Type
+ *      wRate           - Tx Rate
+ *  Out:
+ *
+ * Return Value: FrameTime
+ *
+ */
+UINT
+BBuGetFrameTime (
+    IN BYTE byPreambleType,
+    IN BYTE byPktType,
+    IN UINT cbFrameLength,
+    IN WORD wRate
+    )
+{
+    UINT uFrameTime;
+    UINT uPreamble;
+    UINT uTmp;
+    UINT uRateIdx = (UINT)wRate;
+    UINT uRate = 0;
+
+
+    if (uRateIdx > RATE_54M) {
+        ASSERT(0);
+        return 0;
+    }
+
+    uRate = (UINT)awcFrameTime[uRateIdx];
+
+    if (uRateIdx <= 3) {          //CCK mode
+
+        if (byPreambleType == 1) {//Short
+            uPreamble = 96;
+        } else {
+            uPreamble = 192;
+        }
+        uFrameTime = (cbFrameLength * 80) / uRate;  //?????
+        uTmp = (uFrameTime * uRate) / 80;
+        if (cbFrameLength != uTmp) {
+            uFrameTime ++;
+        }
+
+        return (uPreamble + uFrameTime);
+    }
+    else {
+        uFrameTime = (cbFrameLength * 8 + 22) / uRate;   //????????
+        uTmp = ((uFrameTime * uRate) - 22) / 8;
+        if(cbFrameLength != uTmp) {
+            uFrameTime ++;
+        }
+        uFrameTime = uFrameTime * 4;    //???????
+        if(byPktType != PK_TYPE_11A) {
+            uFrameTime += 6;
+        }
+        return (20 + uFrameTime); //??????
+    }
+}
+
+/*
+ * Description: Caculate Length, Service, and Signal fields of Phy for Tx
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Device Structure
+ *      cbFrameLength   - Tx Frame Length
+ *      wRate           - Tx Rate
+ *  Out:
+ *      pwPhyLen        - pointer to Phy Length field
+ *      pbyPhySrv       - pointer to Phy Service field
+ *      pbyPhySgn       - pointer to Phy Signal field
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvCaculateParameter (
+    IN  PSDevice pDevice,
+    IN  UINT cbFrameLength,
+    IN  WORD wRate,
+    IN  BYTE byPacketType,
+    OUT PWORD pwPhyLen,
+    OUT PBYTE pbyPhySrv,
+    OUT PBYTE pbyPhySgn
+    )
+{
+    UINT cbBitCount;
+    UINT cbUsCount = 0;
+    UINT cbTmp;
+    BOOL bExtBit;
+    BYTE byPreambleType = pDevice->byPreambleType;
+    BOOL bCCK = pDevice->bCCK;
+
+    cbBitCount = cbFrameLength * 8;
+    bExtBit = FALSE;
+
+    switch (wRate) {
+    case RATE_1M :
+        cbUsCount = cbBitCount;
+        *pbyPhySgn = 0x00;
+        break;
+
+    case RATE_2M :
+        cbUsCount = cbBitCount / 2;
+        if (byPreambleType == 1)
+            *pbyPhySgn = 0x09;
+        else // long preamble
+            *pbyPhySgn = 0x01;
+        break;
+
+    case RATE_5M :
+        if (bCCK == FALSE)
+            cbBitCount ++;
+        cbUsCount = (cbBitCount * 10) / 55;
+        cbTmp = (cbUsCount * 55) / 10;
+        if (cbTmp != cbBitCount)
+            cbUsCount ++;
+        if (byPreambleType == 1)
+            *pbyPhySgn = 0x0a;
+        else // long preamble
+            *pbyPhySgn = 0x02;
+        break;
+
+    case RATE_11M :
+
+        if (bCCK == FALSE)
+            cbBitCount ++;
+        cbUsCount = cbBitCount / 11;
+        cbTmp = cbUsCount * 11;
+        if (cbTmp != cbBitCount) {
+            cbUsCount ++;
+            if ((cbBitCount - cbTmp) <= 3)
+                bExtBit = TRUE;
+        }
+        if (byPreambleType == 1)
+            *pbyPhySgn = 0x0b;
+        else // long preamble
+            *pbyPhySgn = 0x03;
+        break;
+
+    case RATE_6M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9B; //1001 1011
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8B; //1000 1011
+        }
+        break;
+
+    case RATE_9M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9F; //1001 1111
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8F; //1000 1111
+        }
+        break;
+
+    case RATE_12M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9A; //1001 1010
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8A; //1000 1010
+        }
+        break;
+
+    case RATE_18M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9E; //1001 1110
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8E; //1000 1110
+        }
+        break;
+
+    case RATE_24M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x99; //1001 1001
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x89; //1000 1001
+        }
+        break;
+
+    case RATE_36M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9D; //1001 1101
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8D; //1000 1101
+        }
+        break;
+
+    case RATE_48M :
+        if(byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x98; //1001 1000
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x88; //1000 1000
+        }
+        break;
+
+    case RATE_54M :
+        if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9C; //1001 1100
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8C; //1000 1100
+        }
+        break;
+
+    default :
+        if (byPacketType == PK_TYPE_11A) {//11a, 5GHZ
+            *pbyPhySgn = 0x9C; //1001 1100
+        }
+        else {//11g, 2.4GHZ
+            *pbyPhySgn = 0x8C; //1000 1100
+        }
+        break;
+    }
+
+    if (byPacketType == PK_TYPE_11B) {
+        *pbyPhySrv = 0x00;
+        if (bExtBit)
+            *pbyPhySrv = *pbyPhySrv | 0x80;
+        *pwPhyLen = (WORD) cbUsCount;
+    }
+    else {
+        *pbyPhySrv = 0x00;
+        *pwPhyLen = (WORD)cbFrameLength;
+    }
+}
+
+
+/*
+ * Description: Set Antenna mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byAntennaMode    - Antenna Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetAntennaMode (PSDevice pDevice, BYTE byAntennaMode)
+{
+    //{{ RobertYu: 20041124, ABG Mode, VC1/VC2 define, make the ANT_A, ANT_B inverted
+    /*if ( (pDevice->byRFType == RF_MAXIM2829) ||
+         (pDevice->byRFType == RF_UW2452) ||
+         (pDevice->byRFType == RF_AIROHA7230) ) { // RobertYu: 20041210, 20050104
+
+        switch (byAntennaMode) {
+            case ANT_TXA:
+                byAntennaMode = ANT_TXB;
+                break;
+            case ANT_TXB:
+                byAntennaMode = ANT_TXA;
+                break;
+            case ANT_RXA:
+                byAntennaMode = ANT_RXB;
+                break;
+            case ANT_RXB:
+                byAntennaMode = ANT_RXA;
+                break;
+        }
+    }*/
+
+    switch (byAntennaMode) {
+        case ANT_TXA:
+            break;
+        case ANT_TXB:
+            break;
+        case ANT_RXA:
+            pDevice->byBBRxConf &= 0xFC;
+            break;
+        case ANT_RXB:
+            pDevice->byBBRxConf &= 0xFE;
+            pDevice->byBBRxConf |= 0x02;;
+            break;
+    }
+
+
+    CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_SET_ANTMD,
+                    (WORD) byAntennaMode,
+                    0,
+                    0,
+                    NULL);
+}
+
+/*
+ * Description: Set Antenna mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byAntennaMode    - Antenna Mode
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+BOOL
+BBbVT3184Init (PSDevice pDevice)
+{
+    NTSTATUS                ntStatus;
+    WORD                    wLength;
+    PBYTE                   pbyAddr;
+    PBYTE                   pbyAgc;
+    WORD                    wLengthAgc;
+    BYTE                    abyArray[256];
+
+    ntStatus = CONTROLnsRequestIn(pDevice,
+                                  MESSAGE_TYPE_READ,
+                                  0,
+                                  MESSAGE_REQUEST_EEPROM,
+                                  EEP_MAX_CONTEXT_SIZE,
+                                  pDevice->abyEEPROM);
+    if (ntStatus != STATUS_SUCCESS) {
+        return FALSE;
+    }
+
+
+    //20080215-01,<Add> by Mike Liu
+//    if ((pDevice->abyEEPROM[EEP_OFS_RADIOCTL]&0x06)==0x04)
+//        return FALSE;
+
+//20080804-01,<Add> by Mike Liu
+//zonetype initial
+ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+ if(pDevice->config_file.ZoneType >= 0) {         //read zonetype file ok!
+  if ((pDevice->config_file.ZoneType == 0)&&
+        (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] !=0x00)){          //for USA
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :USA\n");
+  }
+ else if((pDevice->config_file.ZoneType == 1)&&
+ 	     (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x01)){   //for Japan
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x01;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Japan\n");
+  }
+ else if((pDevice->config_file.ZoneType == 2)&&
+ 	     (pDevice->abyEEPROM[EEP_OFS_ZONETYPE]!=0x02)){   //for Europe
+    pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02;
+    pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Init Zone Type :Europe\n");
+  }
+else {
+   if(pDevice->config_file.ZoneType !=pDevice->abyEEPROM[EEP_OFS_ZONETYPE])
+      printk("zonetype in file[%02x] mismatch with in EEPROM[%02x]\n",pDevice->config_file.ZoneType,pDevice->abyEEPROM[EEP_OFS_ZONETYPE]);
+   else
+      printk("Read Zonetype file sucess,use default zonetype setting[%02x]\n",pDevice->config_file.ZoneType);
+ }
+}
+
+    if ( !pDevice->bZoneRegExist ) {
+        pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
+    }
+    pDevice->byRFType = pDevice->abyEEPROM[EEP_OFS_RFTYPE];
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Zone Type %x\n", pDevice->byZoneType);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RF Type %d\n", pDevice->byRFType);
+
+    if ((pDevice->byRFType == RF_AL2230) || (pDevice->byRFType == RF_AL2230S)) {
+        pDevice->byBBRxConf = abyVT3184_AL2230[10];
+        wLength = sizeof(abyVT3184_AL2230);
+        pbyAddr = abyVT3184_AL2230;
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        pDevice->abyBBVGA[0] = 0x1C;
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+    }
+    else if (pDevice->byRFType == RF_AIROHA7230) {
+        pDevice->byBBRxConf = abyVT3184_AL2230[10];
+        wLength = sizeof(abyVT3184_AL2230);
+        pbyAddr = abyVT3184_AL2230;
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        // Init ANT B select,TX Config CR09 = 0x61->0x45, 0x45->0x41(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //pbyAddr[0x09] = 0x41;
+        // Init ANT B select,RX Config CR10 = 0x28->0x2A, 0x2A->0x28(VC1/VC2 define, make the ANT_A, ANT_B inverted)
+        //pbyAddr[0x0a] = 0x28;
+        // Select VC1/VC2, CR215 = 0x02->0x06
+        pbyAddr[0xd7] = 0x06;
+
+        pDevice->abyBBVGA[0] = 0x1C;
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+    }
+    else if ( (pDevice->byRFType == RF_VT3226) || (pDevice->byRFType == RF_VT3226D0) ) {
+        pDevice->byBBRxConf = abyVT3184_VT3226D0[10];   //RobertYu:20060515
+        wLength = sizeof(abyVT3184_VT3226D0);           //RobertYu:20060515
+        pbyAddr = abyVT3184_VT3226D0;                   //RobertYu:20060515
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        pDevice->abyBBVGA[0] = 0x20; //RobertYu:20060104, reguest by Jack
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+        // Fix VT3226 DFC system timing issue
+        MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
+    //}}
+    //{{RobertYu:20060609
+    } else if ( (pDevice->byRFType == RF_VT3342A0) ) {
+        pDevice->byBBRxConf = abyVT3184_VT3226D0[10];
+        wLength = sizeof(abyVT3184_VT3226D0);
+        pbyAddr = abyVT3184_VT3226D0;
+        pbyAgc = abyVT3184_AGC;
+        wLengthAgc = sizeof(abyVT3184_AGC);
+
+        pDevice->abyBBVGA[0] = 0x20;
+        pDevice->abyBBVGA[1] = 0x10;
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+        pDevice->ldBmThreshold[0] = -70;
+        pDevice->ldBmThreshold[1] = -48;
+        pDevice->ldBmThreshold[2] = 0;
+        pDevice->ldBmThreshold[3] = 0;
+        // Fix VT3226 DFC system timing issue
+        MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL2, SOFTPWRCTL_RFLEOPT);
+    //}}
+    } else {
+        return TRUE;
+    }
+
+   memcpy(abyArray, pbyAddr, wLength);
+   CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_BBREG,
+                    wLength,
+                    abyArray
+                    );
+
+   memcpy(abyArray, pbyAgc, wLengthAgc);
+   CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_BBAGC,
+                    wLengthAgc,
+                    abyArray
+                    );
+
+
+    if ((pDevice->byRFType == RF_VT3226) || //RobertYu:20051116, 20060111 remove VT3226D0
+         (pDevice->byRFType == RF_VT3342A0)  //RobertYu:20060609
+         ) {
+        ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x23);
+        MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01);
+    }
+    else if (pDevice->byRFType == RF_VT3226D0)
+    {
+        ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_ITRTMSET,0x11);
+        MACvRegBitsOn(pDevice,MAC_REG_PAPEDELAY,0x01);
+    }
+
+
+    ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x04,0x7F);
+    ControlvWriteByte(pDevice,MESSAGE_REQUEST_BBREG,0x0D,0x01);
+
+    RFbRFTableDownload(pDevice);
+    return TRUE;//ntStatus;
+}
+
+
+/*
+ * Description: Turn on BaseBand Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Device Structure
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void BBvLoopbackOn (PSDevice pDevice)
+{
+    BYTE      byData;
+
+    //CR C9 = 0x00
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0xC9, &pDevice->byBBCRc9);//CR201
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0);
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x4D, &pDevice->byBBCR4d);//CR77
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x4D, 0x90);
+
+    //CR 88 = 0x02(CCK), 0x03(OFDM)
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x88, &pDevice->byBBCR88);//CR136
+
+    if (pDevice->wCurrentRate <= RATE_11M) { //CCK
+        // Enable internal digital loopback: CR33 |= 0000 0001
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x21, &byData);//CR33
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (BYTE)(byData | 0x01));//CR33
+        // CR154 = 0x00
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, 0);   //CR154
+
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);//CR239
+    }
+    else { //OFDM
+        // Enable internal digital loopback:CR154 |= 0000 0001
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x9A, &byData);//CR154
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (BYTE)(byData | 0x01));//CR154
+        // CR33 = 0x00
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, 0);   //CR33
+
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);//CR239
+    }
+
+    //CR14 = 0x00
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0E, 0);//CR14
+
+    // Disable TX_IQUN
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x09, &pDevice->byBBCR09);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x09, (BYTE)(pDevice->byBBCR09 & 0xDE));
+}
+
+/*
+ * Description: Turn off BaseBand Loopback mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Device Structure
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void BBvLoopbackOff (PSDevice pDevice)
+{
+    BYTE      byData;
+
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, pDevice->byBBCRc9);//CR201
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, pDevice->byBBCR88);//CR136
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x09, pDevice->byBBCR09);//CR136
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x4D, pDevice->byBBCR4d);//CR77
+
+    if (pDevice->wCurrentRate <= RATE_11M) { // CCK
+        // Set the CR33 Bit2 to disable internal Loopback.
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x21, &byData);//CR33
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x21, (BYTE)(byData & 0xFE));//CR33
+    }
+    else { // OFDM
+        ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x9A, &byData);//CR154
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9A, (BYTE)(byData & 0xFE));//CR154
+    }
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0x0E, &byData);//CR14
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0E, (BYTE)(byData | 0x80));//CR14
+
+}
+
+
+/*
+ * Description: Set ShortSlotTime mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Device Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetShortSlotTime (PSDevice pDevice)
+{
+    BYTE byBBVGA=0;
+
+    if (pDevice->bShortSlotTime) {
+        pDevice->byBBRxConf &= 0xDF;//1101 1111
+    } else {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    }
+
+    ControlvReadByte (pDevice, MESSAGE_REQUEST_BBREG, 0xE7, &byBBVGA);
+    if (byBBVGA == pDevice->abyBBVGA[0]) {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    }
+
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);
+
+}
+
+
+VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData)
+{
+
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, byData);
+
+    // patch for 3253B0 Baseband with Cardbus module
+    if (byData == pDevice->abyBBVGA[0]) {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    } else if (pDevice->bShortSlotTime) {
+        pDevice->byBBRxConf &= 0xDF;//1101 1111
+    } else {
+        pDevice->byBBRxConf |= 0x20;//0010 0000
+    }
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0A, pDevice->byBBRxConf);//CR10
+}
+
+
+/*
+ * Description: Baseband SoftwareReset
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase    - I/O base address
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSoftwareReset (PSDevice pDevice)
+{
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x50, 0x40);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x50, 0);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9C, 0x01);
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x9C, 0);
+}
+
+/*
+ * Description: BBvSetDeepSleep
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID
+BBvSetDeepSleep (PSDevice pDevice)
+{
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0c, 0x17);//CR12
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0D, 0xB9);//CR13
+}
+
+VOID
+BBvExitDeepSleep (PSDevice pDevice)
+{
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0C, 0x00);//CR12
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x0D, 0x01);//CR13
+}
+
+
+static
+ULONG
+s_ulGetLowSQ3(PSDevice pDevice)
+{
+int   ii;
+ULONG ulSQ3 = 0;
+ULONG ulMaxPacket;
+
+    ulMaxPacket = pDevice->aulPktNum[RATE_54M];
+    if ( pDevice->aulPktNum[RATE_54M] != 0 ) {
+        ulSQ3 = pDevice->aulSQ3Val[RATE_54M] / pDevice->aulPktNum[RATE_54M];
+    }
+    for ( ii=RATE_48M;ii>=RATE_6M;ii-- ) {
+        if ( pDevice->aulPktNum[ii] > ulMaxPacket ) {
+            ulMaxPacket = pDevice->aulPktNum[ii];
+            ulSQ3 = pDevice->aulSQ3Val[ii] / pDevice->aulPktNum[ii];
+        }
+    }
+
+    return ulSQ3;
+}
+
+
+
+static
+ULONG
+s_ulGetRatio (PSDevice pDevice)
+{
+int     ii,jj;
+ULONG   ulRatio = 0;
+ULONG   ulMaxPacket;
+ULONG   ulPacketNum;
+
+    //This is a thousand-ratio
+    ulMaxPacket = pDevice->aulPktNum[RATE_54M];
+    if ( pDevice->aulPktNum[RATE_54M] != 0 ) {
+        ulPacketNum = pDevice->aulPktNum[RATE_54M];
+        ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+        ulRatio += TOP_RATE_54M;
+    }
+    for ( ii=RATE_48M;ii>=RATE_1M;ii-- ) {
+        if ( pDevice->aulPktNum[ii] > ulMaxPacket ) {
+            ulPacketNum = 0;
+            for ( jj=RATE_54M;jj>=ii;jj--)
+                ulPacketNum += pDevice->aulPktNum[jj];
+            ulRatio = (ulPacketNum * 1000 / pDevice->uDiversityCnt);
+            ulRatio += TOP_RATE_48M;
+            ulMaxPacket = pDevice->aulPktNum[ii];
+        }
+
+    }
+
+    return ulRatio;
+}
+
+
+static
+void
+s_vClearSQ3Value (PSDevice pDevice)
+{
+    int ii;
+    pDevice->uDiversityCnt = 0;
+
+    for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
+        pDevice->aulPktNum[ii] = 0;
+        pDevice->aulSQ3Val[ii] = 0;
+    }
+}
+
+
+/*
+ * Description: Antenna Diversity
+ *
+ * Parameters:
+ *  In:
+ *      pDevice          - Device Structure
+ *      byRSR            - RSR from received packet
+ *      bySQ3            - SQ3 value from received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+VOID
+BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3)
+{
+
+    pDevice->uDiversityCnt++;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pDevice->uDiversityCnt = %d\n", (int)pDevice->uDiversityCnt);
+
+    if (byRxRate == 2) {
+        pDevice->aulPktNum[RATE_1M]++;
+    }
+    else if (byRxRate==4) {
+        pDevice->aulPktNum[RATE_2M]++;
+    }
+    else if (byRxRate==11) {
+        pDevice->aulPktNum[RATE_5M]++;
+    }
+    else if (byRxRate==22) {
+        pDevice->aulPktNum[RATE_11M]++;
+    }
+    else if(byRxRate==12){
+        pDevice->aulPktNum[RATE_6M]++;
+        pDevice->aulSQ3Val[RATE_6M] += bySQ3;
+    }
+    else if(byRxRate==18){
+        pDevice->aulPktNum[RATE_9M]++;
+        pDevice->aulSQ3Val[RATE_9M] += bySQ3;
+    }
+    else if(byRxRate==24){
+        pDevice->aulPktNum[RATE_12M]++;
+        pDevice->aulSQ3Val[RATE_12M] += bySQ3;
+    }
+    else if(byRxRate==36){
+        pDevice->aulPktNum[RATE_18M]++;
+        pDevice->aulSQ3Val[RATE_18M] += bySQ3;
+    }
+    else if(byRxRate==48){
+        pDevice->aulPktNum[RATE_24M]++;
+        pDevice->aulSQ3Val[RATE_24M] += bySQ3;
+    }
+    else if(byRxRate==72){
+        pDevice->aulPktNum[RATE_36M]++;
+        pDevice->aulSQ3Val[RATE_36M] += bySQ3;
+    }
+    else if(byRxRate==96){
+        pDevice->aulPktNum[RATE_48M]++;
+        pDevice->aulSQ3Val[RATE_48M] += bySQ3;
+    }
+    else if(byRxRate==108){
+        pDevice->aulPktNum[RATE_54M]++;
+        pDevice->aulSQ3Val[RATE_54M] += bySQ3;
+    }
+
+    if (pDevice->byAntennaState == 0) {
+
+        if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ulDiversityNValue=[%d],54M-[%d]\n",(int)pDevice->ulDiversityNValue, (int)pDevice->aulPktNum[RATE_54M]);
+
+            pDevice->ulSQ3_State0 = s_ulGetLowSQ3(pDevice);
+            pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0, SQ3= [%08x] rate = [%08x]\n",(int)pDevice->ulSQ3_State0,(int)pDevice->ulRatio_State0);
+
+            if ( ((pDevice->aulPktNum[RATE_54M] < pDevice->ulDiversityNValue/2) &&
+                  (pDevice->ulSQ3_State0 > pDevice->ulSQ3TH) ) ||
+                 (pDevice->ulSQ3_State0 == 0 ) )  {
+
+                if ( pDevice->byTMax == 0 )
+                    return;
+
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+
+                pDevice->byAntennaState = 1;
+
+                del_timer(&pDevice->TimerSQ3Tmax3);
+                del_timer(&pDevice->TimerSQ3Tmax2);
+                pDevice->TimerSQ3Tmax1.expires =  RUN_AT(pDevice->byTMax * HZ);
+                add_timer(&pDevice->TimerSQ3Tmax1);
+
+            } else {
+                pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+                add_timer(&pDevice->TimerSQ3Tmax3);
+            }
+            s_vClearSQ3Value(pDevice);
+
+        }
+    } else { //byAntennaState == 1
+
+        if (pDevice->uDiversityCnt > pDevice->ulDiversityMValue) {
+
+            del_timer(&pDevice->TimerSQ3Tmax1);
+            pDevice->ulSQ3_State1 = s_ulGetLowSQ3(pDevice);
+            pDevice->ulRatio_State1 = s_ulGetRatio(pDevice);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State1, rate0 = %08x,rate1 = %08x\n",(int)pDevice->ulRatio_State0,(int)pDevice->ulRatio_State1);
+
+            if ( ((pDevice->ulSQ3_State1 == 0) && (pDevice->ulSQ3_State0 != 0)) ||
+                 ((pDevice->ulSQ3_State1 == 0) && (pDevice->ulSQ3_State0 == 0) && (pDevice->ulRatio_State1 < pDevice->ulRatio_State0)) ||
+                 ((pDevice->ulSQ3_State1 != 0) && (pDevice->ulSQ3_State0 != 0) && (pDevice->ulSQ3_State0 < pDevice->ulSQ3_State1))
+               ) {
+
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+
+                pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+                pDevice->TimerSQ3Tmax2.expires =  RUN_AT(pDevice->byTMax2 * HZ);
+                add_timer(&pDevice->TimerSQ3Tmax3);
+                add_timer(&pDevice->TimerSQ3Tmax2);
+
+            }
+            pDevice->byAntennaState = 0;
+            s_vClearSQ3Value(pDevice);
+        }
+    } //byAntennaState
+}
+
+
+/*+
+ *
+ * Description:
+ *  Timer for SQ3 antenna diversity
+ *
+ * Parameters:
+ *  In:
+ *      pvSysSpec1
+ *      hDeviceContext - Pointer to the adapter
+ *      pvSysSpec2
+ *      pvSysSpec3
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+
+VOID
+TimerSQ3CallBack (
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3CallBack...");
+    spin_lock_irq(&pDevice->lock);
+
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+    pDevice->byAntennaState = 0;
+    s_vClearSQ3Value(pDevice);
+    pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+    pDevice->TimerSQ3Tmax2.expires =  RUN_AT(pDevice->byTMax2 * HZ);
+    add_timer(&pDevice->TimerSQ3Tmax3);
+    add_timer(&pDevice->TimerSQ3Tmax2);
+
+
+    spin_unlock_irq(&pDevice->lock);
+    return;
+}
+
+
+/*+
+ *
+ * Description:
+ *  Timer for SQ3 antenna diversity
+ *
+ * Parameters:
+ *  In:
+ *      pvSysSpec1
+ *      hDeviceContext - Pointer to the adapter
+ *      pvSysSpec2
+ *      pvSysSpec3
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+
+VOID
+TimerSQ3Tmax3CallBack (
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TimerSQ3Tmax3CallBack...");
+    spin_lock_irq(&pDevice->lock);
+
+    pDevice->ulRatio_State0 = s_ulGetRatio(pDevice);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"SQ3_State0 = [%08x]\n",(int)pDevice->ulRatio_State0);
+
+    s_vClearSQ3Value(pDevice);
+    if ( pDevice->byTMax == 0 ) {
+        pDevice->TimerSQ3Tmax3.expires =  RUN_AT(pDevice->byTMax3 * HZ);
+        add_timer(&pDevice->TimerSQ3Tmax3);
+        spin_unlock_irq(&pDevice->lock);
+        return;
+    }
+
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_ANTENNA, NULL);
+    pDevice->byAntennaState = 1;
+    del_timer(&pDevice->TimerSQ3Tmax3);
+    del_timer(&pDevice->TimerSQ3Tmax2);
+    pDevice->TimerSQ3Tmax1.expires =  RUN_AT(pDevice->byTMax * HZ);
+    add_timer(&pDevice->TimerSQ3Tmax1);
+
+    spin_unlock_irq(&pDevice->lock);
+    return;
+}
+
+VOID
+BBvUpdatePreEDThreshold(
+    IN  PSDevice    pDevice,
+    IN  BOOL        bScanning)
+{
+
+
+    switch(pDevice->byRFType)
+    {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+            //RobertYu:20060627, update new table
+
+            if( bScanning )
+            {   // need Max sensitivity //RSSI -69, -70,....
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70, -71,...\n");
+                break;
+            }
+
+            if(pDevice->byBBPreEDRSSI <= 45) { // RSSI 0, -1,-2,....-45
+                if(pDevice->byBBPreEDIndex == 20) break;
+                pDevice->byBBPreEDIndex = 20;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI 0, -1,-2,..-45\n");
+            } else if(pDevice->byBBPreEDRSSI <= 46)  { //RSSI -46
+                if(pDevice->byBBPreEDIndex == 19) break;
+                pDevice->byBBPreEDIndex = 19;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x1A); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -46\n");
+            } else if(pDevice->byBBPreEDRSSI <= 47)  { //RSSI -47
+                if(pDevice->byBBPreEDIndex == 18) break;
+                pDevice->byBBPreEDIndex = 18;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x15); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -47\n");
+            } else if(pDevice->byBBPreEDRSSI <= 49)  { //RSSI -48, -49
+                if(pDevice->byBBPreEDIndex == 17) break;
+                pDevice->byBBPreEDIndex = 17;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0E); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -48,-49\n");
+            } else if(pDevice->byBBPreEDRSSI <= 51)  { //RSSI -50, -51
+                if(pDevice->byBBPreEDIndex == 16) break;
+                pDevice->byBBPreEDIndex = 16;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x09); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -50,-51\n");
+            } else if(pDevice->byBBPreEDRSSI <= 53)  { //RSSI -52, -53
+                if(pDevice->byBBPreEDIndex == 15) break;
+                pDevice->byBBPreEDIndex = 15;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x06); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -52,-53\n");
+            } else if(pDevice->byBBPreEDRSSI <= 55)  { //RSSI -54, -55
+                if(pDevice->byBBPreEDIndex == 14) break;
+                pDevice->byBBPreEDIndex = 14;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x03); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -54,-55\n");
+            } else if(pDevice->byBBPreEDRSSI <= 56)  { //RSSI -56
+                if(pDevice->byBBPreEDIndex == 13) break;
+                pDevice->byBBPreEDIndex = 13;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xA0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -56\n");
+            } else if(pDevice->byBBPreEDRSSI <= 57)  { //RSSI -57
+                if(pDevice->byBBPreEDIndex == 12) break;
+                pDevice->byBBPreEDIndex = 12;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x20); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -57\n");
+            } else if(pDevice->byBBPreEDRSSI <= 58)  { //RSSI -58
+                if(pDevice->byBBPreEDIndex == 11) break;
+                pDevice->byBBPreEDIndex = 11;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xA0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -58\n");
+            } else if(pDevice->byBBPreEDRSSI <= 59)  { //RSSI -59
+                if(pDevice->byBBPreEDIndex == 10) break;
+                pDevice->byBBPreEDIndex = 10;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x54); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -59\n");
+            } else if(pDevice->byBBPreEDRSSI <= 60)  { //RSSI -60
+                if(pDevice->byBBPreEDIndex == 9) break;
+                pDevice->byBBPreEDIndex = 9;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x18); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -60\n");
+            } else if(pDevice->byBBPreEDRSSI <= 61)  { //RSSI -61
+                if(pDevice->byBBPreEDIndex == 8) break;
+                pDevice->byBBPreEDIndex = 8;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xE3); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -61\n");
+            } else if(pDevice->byBBPreEDRSSI <= 62)  { //RSSI -62
+                if(pDevice->byBBPreEDIndex == 7) break;
+                pDevice->byBBPreEDIndex = 7;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB9); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -62\n");
+            } else if(pDevice->byBBPreEDRSSI <= 63)  { //RSSI -63
+                if(pDevice->byBBPreEDIndex == 6) break;
+                pDevice->byBBPreEDIndex = 6;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x93); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -63\n");
+            } else if(pDevice->byBBPreEDRSSI <= 64)  { //RSSI -64
+                if(pDevice->byBBPreEDIndex == 5) break;
+                pDevice->byBBPreEDIndex = 5;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x79); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -64\n");
+            } else if(pDevice->byBBPreEDRSSI <= 65)  { //RSSI -65
+                if(pDevice->byBBPreEDIndex == 4) break;
+                pDevice->byBBPreEDIndex = 4;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x62); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -65\n");
+            } else if(pDevice->byBBPreEDRSSI <= 66)  { //RSSI -66
+                if(pDevice->byBBPreEDIndex == 3) break;
+                pDevice->byBBPreEDIndex = 3;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x51); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -66\n");
+            } else if(pDevice->byBBPreEDRSSI <= 67)  { //RSSI -67
+                if(pDevice->byBBPreEDIndex == 2) break;
+                pDevice->byBBPreEDIndex = 2;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67\n");
+            } else if(pDevice->byBBPreEDRSSI <= 68)  { //RSSI -68
+                if(pDevice->byBBPreEDIndex == 1) break;
+                pDevice->byBBPreEDIndex = 1;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x36); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -68\n");
+            } else { //RSSI -69, -70,....
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70,...\n");
+            }
+            break;
+
+        case RF_VT3226:
+        case RF_VT3226D0:
+            //RobertYu:20060627, update new table
+
+            if( bScanning )
+            {   // need Max sensitivity  //RSSI -69, -70, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70,..\n");
+                break;
+            }
+
+            if(pDevice->byBBPreEDRSSI <= 41) { // RSSI 0, -1,-2,....-41
+                if(pDevice->byBBPreEDIndex == 22) break;
+                pDevice->byBBPreEDIndex = 22;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI 0, -1,-2,..-41\n");
+            } else if(pDevice->byBBPreEDRSSI <= 42)  { //RSSI -42
+                if(pDevice->byBBPreEDIndex == 21) break;
+                pDevice->byBBPreEDIndex = 21;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x36); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -42\n");
+            } else if(pDevice->byBBPreEDRSSI <= 43)  { //RSSI -43
+                if(pDevice->byBBPreEDIndex == 20) break;
+                pDevice->byBBPreEDIndex = 20;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x26); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -43\n");
+            } else if(pDevice->byBBPreEDRSSI <= 45)  { //RSSI -44, -45
+                if(pDevice->byBBPreEDIndex == 19) break;
+                pDevice->byBBPreEDIndex = 19;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x18); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -44,-45\n");
+            } else if(pDevice->byBBPreEDRSSI <= 47)  { //RSSI -46, -47
+                if(pDevice->byBBPreEDIndex == 18) break;
+                pDevice->byBBPreEDIndex = 18;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x11); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -46,-47\n");
+            } else if(pDevice->byBBPreEDRSSI <= 49)  { //RSSI -48, -49
+                if(pDevice->byBBPreEDIndex == 17) break;
+                pDevice->byBBPreEDIndex = 17;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0a); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -48,-49\n");
+            } else if(pDevice->byBBPreEDRSSI <= 51)  { //RSSI -50, -51
+                if(pDevice->byBBPreEDIndex == 16) break;
+                pDevice->byBBPreEDIndex = 16;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x07); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -50,-51\n");
+            } else if(pDevice->byBBPreEDRSSI <= 53)  { //RSSI -52, -53
+                if(pDevice->byBBPreEDIndex == 15) break;
+                pDevice->byBBPreEDIndex = 15;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x04); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -52,-53\n");
+            } else if(pDevice->byBBPreEDRSSI <= 55)  { //RSSI -54, -55
+                if(pDevice->byBBPreEDIndex == 14) break;
+                pDevice->byBBPreEDIndex = 14;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -54,-55\n");
+            } else if(pDevice->byBBPreEDRSSI <= 56)  { //RSSI -56
+                if(pDevice->byBBPreEDIndex == 13) break;
+                pDevice->byBBPreEDIndex = 13;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -56\n");
+            } else if(pDevice->byBBPreEDRSSI <= 57)  { //RSSI -57
+                if(pDevice->byBBPreEDIndex == 12) break;
+                pDevice->byBBPreEDIndex = 12;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -57\n");
+            } else if(pDevice->byBBPreEDRSSI <= 58)  { //RSSI -58
+                if(pDevice->byBBPreEDIndex == 11) break;
+                pDevice->byBBPreEDIndex = 11;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x70); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -58\n");
+            } else if(pDevice->byBBPreEDRSSI <= 59)  { //RSSI -59
+                if(pDevice->byBBPreEDIndex == 10) break;
+                pDevice->byBBPreEDIndex = 10;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -59\n");
+            } else if(pDevice->byBBPreEDRSSI <= 60)  { //RSSI -60
+                if(pDevice->byBBPreEDIndex == 9) break;
+                pDevice->byBBPreEDIndex = 9;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xEA); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -60\n");
+            } else if(pDevice->byBBPreEDRSSI <= 61)  { //RSSI -61
+                if(pDevice->byBBPreEDIndex == 8) break;
+                pDevice->byBBPreEDIndex = 8;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -61\n");
+            } else if(pDevice->byBBPreEDRSSI <= 62)  { //RSSI -62
+                if(pDevice->byBBPreEDIndex == 7) break;
+                pDevice->byBBPreEDIndex = 7;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x9C); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -62\n");
+            } else if(pDevice->byBBPreEDRSSI <= 63)  { //RSSI -63
+                if(pDevice->byBBPreEDIndex == 6) break;
+                pDevice->byBBPreEDIndex = 6;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x80); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -63\n");
+            } else if(pDevice->byBBPreEDRSSI <= 64)  { //RSSI -64
+                if(pDevice->byBBPreEDIndex == 5) break;
+                pDevice->byBBPreEDIndex = 5;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x68); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -64\n");
+            } else if(pDevice->byBBPreEDRSSI <= 65)  { //RSSI -65
+                if(pDevice->byBBPreEDIndex == 4) break;
+                pDevice->byBBPreEDIndex = 4;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x52); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -65\n");
+            } else if(pDevice->byBBPreEDRSSI <= 66)  { //RSSI -66
+                if(pDevice->byBBPreEDIndex == 3) break;
+                pDevice->byBBPreEDIndex = 3;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -66\n");
+            } else if(pDevice->byBBPreEDRSSI <= 67)  { //RSSI -67
+                if(pDevice->byBBPreEDIndex == 2) break;
+                pDevice->byBBPreEDIndex = 2;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x36); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67\n");
+            } else if(pDevice->byBBPreEDRSSI <= 68)  { //RSSI -68
+                if(pDevice->byBBPreEDIndex == 1) break;
+                pDevice->byBBPreEDIndex = 1;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x2D); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -68\n");
+            } else { //RSSI -69, -70, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x24); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -69, -70,..\n");
+            }
+            break;
+
+        case RF_VT3342A0: //RobertYu:20060627, testing table
+            if( bScanning )
+            {   // need Max sensitivity  //RSSI -67, -68, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67, -68,..\n");
+                break;
+            }
+
+            if(pDevice->byBBPreEDRSSI <= 41) { // RSSI 0, -1,-2,....-41
+                if(pDevice->byBBPreEDIndex == 20) break;
+                pDevice->byBBPreEDIndex = 20;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0xFF); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI 0, -1,-2,..-41\n");
+            } else if(pDevice->byBBPreEDRSSI <= 42)  { //RSSI -42
+                if(pDevice->byBBPreEDIndex == 19) break;
+                pDevice->byBBPreEDIndex = 19;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x36); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -42\n");
+            } else if(pDevice->byBBPreEDRSSI <= 43)  { //RSSI -43
+                if(pDevice->byBBPreEDIndex == 18) break;
+                pDevice->byBBPreEDIndex = 18;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x26); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -43\n");
+            } else if(pDevice->byBBPreEDRSSI <= 45)  { //RSSI -44, -45
+                if(pDevice->byBBPreEDIndex == 17) break;
+                pDevice->byBBPreEDIndex = 17;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x18); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -44,-45\n");
+            } else if(pDevice->byBBPreEDRSSI <= 47)  { //RSSI -46, -47
+                if(pDevice->byBBPreEDIndex == 16) break;
+                pDevice->byBBPreEDIndex = 16;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x11); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -46,-47\n");
+            } else if(pDevice->byBBPreEDRSSI <= 49)  { //RSSI -48, -49
+                if(pDevice->byBBPreEDIndex == 15) break;
+                pDevice->byBBPreEDIndex = 15;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x0a); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -48,-49\n");
+            } else if(pDevice->byBBPreEDRSSI <= 51)  { //RSSI -50, -51
+                if(pDevice->byBBPreEDIndex == 14) break;
+                pDevice->byBBPreEDIndex = 14;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x07); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -50,-51\n");
+            } else if(pDevice->byBBPreEDRSSI <= 53)  { //RSSI -52, -53
+                if(pDevice->byBBPreEDIndex == 13) break;
+                pDevice->byBBPreEDIndex = 13;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x04); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x00); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -52,-53\n");
+            } else if(pDevice->byBBPreEDRSSI <= 55)  { //RSSI -54, -55
+                if(pDevice->byBBPreEDIndex == 12) break;
+                pDevice->byBBPreEDIndex = 12;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -54,-55\n");
+            } else if(pDevice->byBBPreEDRSSI <= 56)  { //RSSI -56
+                if(pDevice->byBBPreEDIndex == 11) break;
+                pDevice->byBBPreEDIndex = 11;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x02); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -56\n");
+            } else if(pDevice->byBBPreEDRSSI <= 57)  { //RSSI -57
+                if(pDevice->byBBPreEDIndex == 10) break;
+                pDevice->byBBPreEDIndex = 10;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xB0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -57\n");
+            } else if(pDevice->byBBPreEDRSSI <= 58)  { //RSSI -58
+                if(pDevice->byBBPreEDIndex == 9) break;
+                pDevice->byBBPreEDIndex = 9;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x70); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -58\n");
+            } else if(pDevice->byBBPreEDRSSI <= 59)  { //RSSI -59
+                if(pDevice->byBBPreEDIndex == 8) break;
+                pDevice->byBBPreEDIndex = 8;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x01); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x30); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -59\n");
+            } else if(pDevice->byBBPreEDRSSI <= 60)  { //RSSI -60
+                if(pDevice->byBBPreEDIndex == 7) break;
+                pDevice->byBBPreEDIndex = 7;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xEA); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -60\n");
+            } else if(pDevice->byBBPreEDRSSI <= 61)  { //RSSI -61
+                if(pDevice->byBBPreEDIndex == 6) break;
+                pDevice->byBBPreEDIndex = 6;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0xC0); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -61\n");
+            } else if(pDevice->byBBPreEDRSSI <= 62)  { //RSSI -62
+                if(pDevice->byBBPreEDIndex == 5) break;
+                pDevice->byBBPreEDIndex = 5;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x9C); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -62\n");
+            } else if(pDevice->byBBPreEDRSSI <= 63)  { //RSSI -63
+                if(pDevice->byBBPreEDIndex == 4) break;
+                pDevice->byBBPreEDIndex = 4;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x80); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -63\n");
+            } else if(pDevice->byBBPreEDRSSI <= 64)  { //RSSI -64
+                if(pDevice->byBBPreEDIndex == 3) break;
+                pDevice->byBBPreEDIndex = 3;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x68); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -64\n");
+            } else if(pDevice->byBBPreEDRSSI <= 65)  { //RSSI -65
+                if(pDevice->byBBPreEDIndex == 2) break;
+                pDevice->byBBPreEDIndex = 2;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x52); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -65\n");
+            } else if(pDevice->byBBPreEDRSSI <= 66)  { //RSSI -66
+                if(pDevice->byBBPreEDIndex == 1) break;
+                pDevice->byBBPreEDIndex = 1;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x43); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -66\n");
+            } else { //RSSI -67, -68, ...
+                if(pDevice->byBBPreEDIndex == 0) break;
+                pDevice->byBBPreEDIndex = 0;
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xC9, 0x00); //CR201(0xC9)
+                ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xCE, 0x38); //CR206(0xCE)
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"            pDevice->byBBPreEDRSSI -67, -68,..\n");
+            }
+            break;
+
+    }
+
+}
+
diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h
new file mode 100644
index 0000000..e991a7e
--- /dev/null
+++ b/drivers/staging/vt6656/baseband.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.h
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 5, 2002
+ *
+ * Revision History:
+ *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
+ *      08-26-2003 Kyle Hsu    :  Add defines of packet type and TX rate.
+ */
+
+#ifndef __BASEBAND_H__
+#define __BASEBAND_H__
+
+#include "ttype.h"
+#include "tether.h"
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define PREAMBLE_LONG   0
+#define PREAMBLE_SHORT  1
+
+//
+// Registers in the BASEBAND
+//
+#define BB_MAX_CONTEXT_SIZE 256
+
+#define C_SIFS_A      16      // micro sec.
+#define C_SIFS_BG     10
+
+#define C_EIFS      80      // micro sec.
+
+
+#define C_SLOT_SHORT   9      // micro sec.
+#define C_SLOT_LONG   20
+
+#define C_CWMIN_A     15       // slot time
+#define C_CWMIN_B     31
+
+#define C_CWMAX      1023     // slot time
+
+//0:11A 1:11B 2:11G
+#define BB_TYPE_11A    0
+#define BB_TYPE_11B    1
+#define BB_TYPE_11G    2
+
+//0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
+#define PK_TYPE_11A     0
+#define PK_TYPE_11B     1
+#define PK_TYPE_11GB    2
+#define PK_TYPE_11GA    3
+
+#define TOP_RATE_54M        0x80000000
+#define TOP_RATE_48M        0x40000000
+#define TOP_RATE_36M        0x20000000
+#define TOP_RATE_24M        0x10000000
+#define TOP_RATE_18M        0x08000000
+#define TOP_RATE_12M        0x04000000
+#define TOP_RATE_11M        0x02000000
+#define TOP_RATE_9M         0x01000000
+#define TOP_RATE_6M         0x00800000
+#define TOP_RATE_55M        0x00400000
+#define TOP_RATE_2M         0x00200000
+#define TOP_RATE_1M         0x00100000
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+UINT
+BBuGetFrameTime(
+    IN BYTE byPreambleType,
+    IN BYTE byFreqType,
+    IN UINT cbFrameLength,
+    IN WORD wRate
+    );
+
+VOID
+BBvCaculateParameter (
+    IN  PSDevice pDevice,
+    IN  UINT cbFrameLength,
+    IN  WORD wRate,
+    IN  BYTE byPacketType,
+    OUT PWORD pwPhyLen,
+    OUT PBYTE pbyPhySrv,
+    OUT PBYTE pbyPhySgn
+    );
+
+// timer for antenna diversity
+
+VOID
+TimerSQ3CallBack (
+    IN  HANDLE      hDeviceContext
+    );
+
+VOID
+TimerSQ3Tmax3CallBack (
+    IN  HANDLE      hDeviceContext
+    );
+
+VOID BBvAntennaDiversity (PSDevice pDevice, BYTE byRxRate, BYTE bySQ3);
+void BBvLoopbackOn (PSDevice pDevice);
+void BBvLoopbackOff (PSDevice pDevice);
+void BBvSoftwareReset (PSDevice pDevice);
+
+void BBvSetShortSlotTime(PSDevice pDevice);
+VOID BBvSetVGAGainOffset(PSDevice pDevice, BYTE byData);
+void BBvSetAntennaMode(PSDevice pDevice, BYTE byAntennaMode);
+BOOL BBbVT3184Init (PSDevice pDevice);
+VOID BBvSetDeepSleep (PSDevice pDevice);
+VOID BBvExitDeepSleep (PSDevice pDevice);
+VOID BBvUpdatePreEDThreshold(
+     IN  PSDevice    pDevice,
+     IN  BOOL        bScanning
+     );
+
+#endif // __BASEBAND_H__
diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c
new file mode 100644
index 0000000..6b1678b
--- /dev/null
+++ b/drivers/staging/vt6656/bssdb.c
@@ -0,0 +1,1721 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: bssdb.c
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Functions:
+ *      BSSpSearchBSSList - Search known BSS list for Desire SSID or BSSID
+ *      BSSvClearBSSList - Clear BSS List
+ *      BSSbInsertToBSSList - Insert a BSS set into known BSS list
+ *      BSSbUpdateToBSSList - Update BSS set in known BSS list
+ *      BSSbIsSTAInNodeDB - Search Node DB table to find the index of matched DstAddr
+ *      BSSvCreateOneNode - Allocate an Node for Node DB
+ *      BSSvUpdateAPNode - Update AP Node content in Index 0 of KnownNodeDB
+ *      BSSvSecondCallBack - One second timer callback function to update Node DB info & AP link status
+ *      BSSvUpdateNodeTxCounter - Update Tx attemps, Tx failure counter in Node DB for auto-fall back rate control
+ *
+ * Revision History:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ */
+
+#include "ttype.h"
+#include "tmacro.h"
+#include "tether.h"
+#include "device.h"
+#include "80211hdr.h"
+#include "bssdb.h"
+#include "wmgr.h"
+#include "datarate.h"
+#include "desc.h"
+#include "wcmd.h"
+#include "wpa.h"
+#include "baseband.h"
+#include "rf.h"
+#include "card.h"
+#include "mac.h"
+#include "wpa2.h"
+#include "control.h"
+#include "rndis.h"
+#include "iowpa.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+
+
+const WORD             awHWRetry0[5][5] = {
+                                            {RATE_18M, RATE_18M, RATE_12M, RATE_12M, RATE_12M},
+                                            {RATE_24M, RATE_24M, RATE_18M, RATE_12M, RATE_12M},
+                                            {RATE_36M, RATE_36M, RATE_24M, RATE_18M, RATE_18M},
+                                            {RATE_48M, RATE_48M, RATE_36M, RATE_24M, RATE_24M},
+                                            {RATE_54M, RATE_54M, RATE_48M, RATE_36M, RATE_36M}
+                                           };
+const WORD             awHWRetry1[5][5] = {
+                                            {RATE_18M, RATE_18M, RATE_12M, RATE_6M, RATE_6M},
+                                            {RATE_24M, RATE_24M, RATE_18M, RATE_6M, RATE_6M},
+                                            {RATE_36M, RATE_36M, RATE_24M, RATE_12M, RATE_12M},
+                                            {RATE_48M, RATE_48M, RATE_24M, RATE_12M, RATE_12M},
+                                            {RATE_54M, RATE_54M, RATE_36M, RATE_18M, RATE_18M}
+                                           };
+
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+VOID s_vCheckSensitivity(
+    IN HANDLE hDeviceContext
+    );
+
+VOID s_vCheckPreEDThreshold(
+    IN HANDLE hDeviceContext
+    );
+
+#ifdef Calcu_LinkQual
+VOID s_uCalculateLinkQual(
+    IN HANDLE hDeviceContext
+    );
+#endif
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Search known BSS list for Desire SSID or BSSID.
+ *
+ * Return Value:
+ *    PTR to KnownBSS or NULL
+ *
+-*/
+
+PKnownBSS
+BSSpSearchBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE pbyDesireBSSID,
+    IN PBYTE pbyDesireSSID,
+    IN CARD_PHY_TYPE  ePhyType
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PBYTE           pbyBSSID = NULL;
+    PWLAN_IE_SSID   pSSID = NULL;
+    PKnownBSS       pCurrBSS = NULL;
+    PKnownBSS       pSelect = NULL;
+    BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
+    UINT            ii = 0;
+    UINT            jj = 0;   //DavidWang
+    if (pbyDesireBSSID != NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList BSSID[%02X %02X %02X-%02X %02X %02X]\n",
+                            *pbyDesireBSSID,*(pbyDesireBSSID+1),*(pbyDesireBSSID+2),
+                            *(pbyDesireBSSID+3),*(pbyDesireBSSID+4),*(pbyDesireBSSID+5));
+        if ((!IS_BROADCAST_ADDRESS(pbyDesireBSSID)) &&
+	     (memcmp(pbyDesireBSSID, ZeroBSSID, 6)!= 0)){
+            pbyBSSID = pbyDesireBSSID;
+        }
+    }
+    if (pbyDesireSSID != NULL) {
+        if (((PWLAN_IE_SSID)pbyDesireSSID)->len != 0) {
+            pSSID = (PWLAN_IE_SSID) pbyDesireSSID;
+        }
+    }
+
+    if ((pbyBSSID != NULL)&&(pDevice->bRoaming == FALSE)) {
+        // match BSSID first
+        for (ii = 0; ii <MAX_BSS_NUM; ii++) {
+            pCurrBSS = &(pMgmt->sBSSList[ii]);
+
+	//2008-0718-01<Add>by MikeLiu
+	   pCurrBSS->bSelected = FALSE;
+
+            if ((pCurrBSS->bActive) &&
+                (pCurrBSS->bSelected == FALSE)) {
+                if (IS_ETH_ADDRESS_EQUAL(pCurrBSS->abyBSSID, pbyBSSID)) {
+                    if (pSSID != NULL) {
+                        // compare ssid
+                        if ( !memcmp(pSSID->abySSID,
+                            ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
+                            pSSID->len)) {
+                            if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
+                                ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
+                                ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
+                                ) {
+                                pCurrBSS->bSelected = TRUE;
+                                return(pCurrBSS);
+                            }
+                        }
+                    } else {
+                        if ((pMgmt->eConfigMode == WMAC_CONFIG_AUTO) ||
+                            ((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ||
+                            ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))
+                            ) {
+                            pCurrBSS->bSelected = TRUE;
+                            return(pCurrBSS);
+                        }
+                    }
+                }
+            }
+        }
+    } else {
+        // ignore BSSID
+        for (ii = 0; ii <MAX_BSS_NUM; ii++) {
+            pCurrBSS = &(pMgmt->sBSSList[ii]);
+
+           //2007-0721-01<Mark>by MikeLiu
+         //   if ((pCurrBSS->bActive) &&
+         //       (pCurrBSS->bSelected == FALSE)) {
+
+	//2007-0721-01<Add>by MikeLiu
+	  pCurrBSS->bSelected = FALSE;
+          if (pCurrBSS->bActive) {
+
+                if (pSSID != NULL) {
+                    // matched SSID
+                    if (memcmp(pSSID->abySSID,
+                        ((PWLAN_IE_SSID)pCurrBSS->abySSID)->abySSID,
+                        pSSID->len) ||
+                        (pSSID->len != ((PWLAN_IE_SSID)pCurrBSS->abySSID)->len)) {
+                        // SSID not match skip this BSS
+                        continue;
+                      }
+                }
+                if (((pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) ||
+                    ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo))
+                    ){
+                    // Type not match skip this BSS
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo);
+                    continue;
+                }
+
+                if (ePhyType != PHY_TYPE_AUTO) {
+                    if (((ePhyType == PHY_TYPE_11A) && (PHY_TYPE_11A != pCurrBSS->eNetworkTypeInUse)) ||
+                        ((ePhyType != PHY_TYPE_11A) && (PHY_TYPE_11A == pCurrBSS->eNetworkTypeInUse))) {
+                        // PhyType not match skip this BSS
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse);
+                        continue;
+                    }
+                }
+/*
+                if (pMgmt->eAuthenMode < WMAC_AUTH_WPA) {
+                    if (pCurrBSS->bWPAValid == TRUE) {
+                        // WPA AP will reject connection of station without WPA enable.
+                        continue;
+                    }
+                } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+                           (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
+                    if (pCurrBSS->bWPAValid == FALSE) {
+                        // station with WPA enable can't join NonWPA AP.
+                        continue;
+                    }
+                } else if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                           (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+                    if (pCurrBSS->bWPA2Valid == FALSE) {
+                        // station with WPA2 enable can't join NonWPA2 AP.
+                        continue;
+                    }
+                }
+*/
+//DavidWang
+        pMgmt->pSameBSS[jj].uChannel = pCurrBSS->uChannel;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSpSearchBSSList pSelect1[%02X %02X %02X-%02X %02X %02X]\n",*pCurrBSS->abyBSSID,*(pCurrBSS->abyBSSID+1),*(pCurrBSS->abyBSSID+2),*(pCurrBSS->abyBSSID+3),*(pCurrBSS->abyBSSID+4),*(pCurrBSS->abyBSSID+5));
+        jj++;
+
+//DavidWang
+                if (pSelect == NULL) {
+                    pSelect = pCurrBSS;
+                } else {
+                    // compare RSSI, select signal strong one
+                    if (pCurrBSS->uRSSI < pSelect->uRSSI) {
+                        pSelect = pCurrBSS;
+                    }
+                }
+            }
+        }
+//DavidWang
+pDevice->bSameBSSMaxNum = jj;
+//DavidWang
+        if (pSelect != NULL) {
+            pSelect->bSelected = TRUE;
+                        if (pDevice->bRoaming == FALSE)  {
+	//       Einsn Add @20070907
+				memset(pbyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+			memcpy(pbyDesireSSID,pCurrBSS->abySSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1) ;
+                                                }
+
+            return(pSelect);
+        }
+    }
+    return(NULL);
+
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Clear BSS List
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+BSSvClearBSSList(
+    IN HANDLE hDeviceContext,
+    IN BOOL bKeepCurrBSSID
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        if (bKeepCurrBSSID) {
+            if (pMgmt->sBSSList[ii].bActive &&
+                IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pMgmt->abyCurrBSSID)) {
+ //mike mark: there are two same BSSID in list if that AP is in hidden ssid mode,one 's SSID is null,
+ //                 but other's is obvious, so if it acssociate with your STA  exactly,you must keep two
+ //                 of them!!!!!!!!!
+               // bKeepCurrBSSID = FALSE;
+                continue;
+            }
+        }
+/*
+        if ((pMgmt->sBSSList[ii].bActive) && (pMgmt->sBSSList[ii].uClearCount < BSS_CLEAR_COUNT)) {
+             pMgmt->sBSSList[ii].uClearCount ++;
+             continue;
+        }
+*/
+        pMgmt->sBSSList[ii].bActive = FALSE;
+        memset(&pMgmt->sBSSList[ii], 0, sizeof(KnownBSS));
+    }
+    BSSvClearAnyBSSJoinRecord(pDevice);
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    search BSS list by BSSID & SSID if matched
+ *
+ * Return Value:
+ *    TRUE if found.
+ *
+-*/
+PKnownBSS
+BSSpAddrIsInBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSID,
+    IN PWLAN_IE_SSID pSSID
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PKnownBSS       pBSSList = NULL;
+    UINT            ii;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pBSSList = &(pMgmt->sBSSList[ii]);
+        if (pBSSList->bActive) {
+            if (IS_ETH_ADDRESS_EQUAL(pBSSList->abyBSSID, abyBSSID)) {
+                if (pSSID->len == ((PWLAN_IE_SSID)pBSSList->abySSID)->len){
+                    if (memcmp(pSSID->abySSID,
+                            ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
+                            pSSID->len) == 0)
+                        return pBSSList;
+                }
+            }
+        }
+    }
+
+    return NULL;
+};
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Insert a BSS set into known BSS list
+ *
+ * Return Value:
+ *    TRUE if success.
+ *
+-*/
+
+BOOL
+BSSbInsertToBSSList (
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSIDAddr,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    )
+{
+
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
+    PKnownBSS       pBSSList = NULL;
+    UINT            ii;
+    BOOL            bParsingQuiet = FALSE;
+
+
+
+    pBSSList = (PKnownBSS)&(pMgmt->sBSSList[0]);
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pBSSList = (PKnownBSS)&(pMgmt->sBSSList[ii]);
+        if (!pBSSList->bActive)
+                break;
+    }
+
+    if (ii == MAX_BSS_NUM){
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n");
+        return FALSE;
+    }
+    // save the BSS info
+    pBSSList->bActive = TRUE;
+    memcpy( pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN);
+    HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
+    LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
+    pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
+    pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
+    pBSSList->uClearCount = 0;
+
+    if (pSSID->len > WLAN_SSID_MAXLEN)
+        pSSID->len = WLAN_SSID_MAXLEN;
+    memcpy( pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+
+    pBSSList->uChannel = byCurrChannel;
+
+    if (pSuppRates->len > WLAN_RATES_MAXLEN)
+        pSuppRates->len = WLAN_RATES_MAXLEN;
+    memcpy( pBSSList->abySuppRates, pSuppRates, pSuppRates->len + WLAN_IEHDR_LEN);
+
+    if (pExtSuppRates != NULL) {
+        if (pExtSuppRates->len > WLAN_RATES_MAXLEN)
+            pExtSuppRates->len = WLAN_RATES_MAXLEN;
+        memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len);
+
+    } else {
+        memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    }
+    pBSSList->sERP.byERP = psERP->byERP;
+    pBSSList->sERP.bERPExist = psERP->bERPExist;
+
+    // Check if BSS is 802.11a/b/g
+    if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
+        pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
+    } else {
+        if (pBSSList->sERP.bERPExist == TRUE) {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
+        } else {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
+        }
+    }
+
+    pBSSList->byRxRate = pRxPacket->byRxRate;
+    pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
+    pBSSList->uRSSI = pRxPacket->uRSSI;
+    pBSSList->bySQ = pRxPacket->bySQ;
+
+   if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+        (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+        // assoc with BSS
+        if (pBSSList == pMgmt->pCurrBSS) {
+            bParsingQuiet = TRUE;
+        }
+    }
+
+    WPA_ClearRSN(pBSSList);
+
+    if (pRSNWPA != NULL) {
+        UINT uLen = pRSNWPA->len + 2;
+
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) {
+            pBSSList->wWPALen = uLen;
+            memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
+            WPA_ParseRSN(pBSSList, pRSNWPA);
+        }
+    }
+
+    WPA2_ClearRSN(pBSSList);
+
+    if (pRSN != NULL) {
+        UINT uLen = pRSN->len + 2;
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) {
+            pBSSList->wRSNLen = uLen;
+            memcpy(pBSSList->byRSNIE, pRSN, uLen);
+            WPA2vParseRSN(pBSSList, pRSN);
+        }
+    }
+
+    if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) || (pBSSList->bWPA2Valid == TRUE)) {
+
+        PSKeyItem  pTransmitKey = NULL;
+        BOOL       bIs802_1x = FALSE;
+
+        for (ii = 0; ii < pBSSList->wAKMSSAuthCount; ii ++) {
+            if (pBSSList->abyAKMSSAuthType[ii] == WLAN_11i_AKMSS_802_1X) {
+                bIs802_1x = TRUE;
+                break;
+            }
+        }
+        if ((bIs802_1x == TRUE) && (pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len) &&
+            ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID, pSSID->len))) {
+
+            bAdd_PMKID_Candidate((HANDLE)pDevice, pBSSList->abyBSSID, &pBSSList->sRSNCapObj);
+
+            if ((pDevice->bLinkPass == TRUE) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                if ((KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE) ||
+                    (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBSSID, GROUP_KEY, &pTransmitKey) == TRUE)) {
+                    pDevice->gsPMKIDCandidate.StatusType = Ndis802_11StatusType_PMKID_CandidateList;
+                    pDevice->gsPMKIDCandidate.Version = 1;
+
+                }
+
+            }
+        }
+    }
+
+    if (pDevice->bUpdateBBVGA) {
+        // Moniter if RSSI is too strong.
+        pBSSList->byRSSIStatCnt = 0;
+        RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &pBSSList->ldBmMAX);
+        pBSSList->ldBmAverage[0] = pBSSList->ldBmMAX;
+        pBSSList->ldBmAverRange = pBSSList->ldBmMAX;
+        for (ii = 1; ii < RSSI_STAT_COUNT; ii++)
+            pBSSList->ldBmAverage[ii] = 0;
+    }
+
+/*
+    if ((pIE_Country != NULL) &&
+        (pMgmt->b11hEnable == TRUE)) {
+        CARDvSetCountryInfo(pMgmt->pAdapter,
+                            pBSSList->eNetworkTypeInUse,
+                            pIE_Country);
+    }
+
+    if ((bParsingQuiet == TRUE) && (pIE_Quiet != NULL)) {
+        if ((((PWLAN_IE_QUIET)pIE_Quiet)->len == 8) &&
+            (((PWLAN_IE_QUIET)pIE_Quiet)->byQuietCount != 0)) {
+            // valid EID
+            if (pQuiet == NULL) {
+                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
+                CARDbSetQuiet(  pMgmt->pAdapter,
+                                TRUE,
+                                pQuiet->byQuietCount,
+                                pQuiet->byQuietPeriod,
+                                *((PWORD)pQuiet->abyQuietDuration),
+                                *((PWORD)pQuiet->abyQuietOffset)
+                                );
+            } else {
+                pQuiet = (PWLAN_IE_QUIET)pIE_Quiet;
+                CARDbSetQuiet(  pMgmt->pAdapter,
+                                FALSE,
+                                pQuiet->byQuietCount,
+                                pQuiet->byQuietPeriod,
+                                *((PWORD)pQuiet->abyQuietDuration),
+                                *((PWORD)pQuiet->abyQuietOffset)
+                                );
+            }
+        }
+    }
+
+    if ((bParsingQuiet == TRUE) &&
+        (pQuiet != NULL)) {
+        CARDbStartQuiet(pMgmt->pAdapter);
+    }
+*/
+
+    pBSSList->uIELength = uIELength;
+    if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
+        pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
+    memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
+
+    return TRUE;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Update BSS set in known BSS list
+ *
+ * Return Value:
+ *    TRUE if success.
+ *
+-*/
+// TODO: input structure modify
+
+BOOL
+BSSbUpdateToBSSList (
+    IN HANDLE hDeviceContext,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN BOOL bChannelHit,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN PKnownBSS pBSSList,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    )
+{
+    int             ii, jj;
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PSRxMgmtPacket  pRxPacket = (PSRxMgmtPacket)pRxPacketContext;
+    LONG            ldBm, ldBmSum;
+    BOOL            bParsingQuiet = FALSE;
+  //  BYTE            abyTmpSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+
+
+    if (pBSSList == NULL)
+        return FALSE;
+
+
+    HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp));
+    LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp));
+    pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval);
+    pBSSList->wCapInfo = cpu_to_le16(wCapInfo);
+    pBSSList->uClearCount = 0;
+    pBSSList->uChannel = byCurrChannel;
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BSSbUpdateToBSSList: pBSSList->uChannel: %d\n", pBSSList->uChannel);
+
+    if (pSSID->len > WLAN_SSID_MAXLEN)
+        pSSID->len = WLAN_SSID_MAXLEN;
+
+    if ((pSSID->len != 0) && (pSSID->abySSID[0] != 0))
+        memcpy(pBSSList->abySSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+    memcpy(pBSSList->abySuppRates, pSuppRates,pSuppRates->len + WLAN_IEHDR_LEN);
+
+    if (pExtSuppRates != NULL) {
+        memcpy(pBSSList->abyExtSuppRates, pExtSuppRates,pExtSuppRates->len + WLAN_IEHDR_LEN);
+    } else {
+        memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    }
+    pBSSList->sERP.byERP = psERP->byERP;
+    pBSSList->sERP.bERPExist = psERP->bERPExist;
+
+    // Check if BSS is 802.11a/b/g
+    if (pBSSList->uChannel > CB_MAX_CHANNEL_24G) {
+        pBSSList->eNetworkTypeInUse = PHY_TYPE_11A;
+    } else {
+        if (pBSSList->sERP.bERPExist == TRUE) {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11G;
+        } else {
+            pBSSList->eNetworkTypeInUse = PHY_TYPE_11B;
+        }
+    }
+
+    pBSSList->byRxRate = pRxPacket->byRxRate;
+    pBSSList->qwLocalTSF = pRxPacket->qwLocalTSF;
+    if(bChannelHit)
+        pBSSList->uRSSI = pRxPacket->uRSSI;
+    pBSSList->bySQ = pRxPacket->bySQ;
+
+   if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+        (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+        // assoc with BSS
+        if (pBSSList == pMgmt->pCurrBSS) {
+            bParsingQuiet = TRUE;
+        }
+    }
+
+   WPA_ClearRSN(pBSSList);         //mike update
+
+    if (pRSNWPA != NULL) {
+        UINT uLen = pRSNWPA->len + 2;
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSNWPA - pbyIEs))) {
+            pBSSList->wWPALen = uLen;
+            memcpy(pBSSList->byWPAIE, pRSNWPA, uLen);
+            WPA_ParseRSN(pBSSList, pRSNWPA);
+        }
+    }
+
+   WPA2_ClearRSN(pBSSList);  //mike update
+
+    if (pRSN != NULL) {
+        UINT uLen = pRSN->len + 2;
+        if (uLen <= (uIELength - (UINT)(ULONG_PTR)((PBYTE)pRSN - pbyIEs))) {
+            pBSSList->wRSNLen = uLen;
+            memcpy(pBSSList->byRSNIE, pRSN, uLen);
+            WPA2vParseRSN(pBSSList, pRSN);
+        }
+    }
+
+    if (pRxPacket->uRSSI != 0) {
+        RFvRSSITodBm(pDevice, (BYTE)(pRxPacket->uRSSI), &ldBm);
+        // Moniter if RSSI is too strong.
+        pBSSList->byRSSIStatCnt++;
+        pBSSList->byRSSIStatCnt %= RSSI_STAT_COUNT;
+        pBSSList->ldBmAverage[pBSSList->byRSSIStatCnt] = ldBm;
+        ldBmSum = 0;
+        for(ii=0, jj=0;ii<RSSI_STAT_COUNT;ii++) {
+            if (pBSSList->ldBmAverage[ii] != 0) {
+                pBSSList->ldBmMAX = max(pBSSList->ldBmAverage[ii], ldBm);
+                ldBmSum += pBSSList->ldBmAverage[ii];
+                jj++;
+            }
+        }
+        pBSSList->ldBmAverRange = ldBmSum /jj;
+    }
+
+    pBSSList->uIELength = uIELength;
+    if (pBSSList->uIELength > WLAN_BEACON_FR_MAXLEN)
+        pBSSList->uIELength = WLAN_BEACON_FR_MAXLEN;
+    memcpy(pBSSList->abyIEs, pbyIEs, pBSSList->uIELength);
+
+//mike add: if  the AP in this pBSSList is hidden ssid and we can find two of them,
+//                  you need upgrade the other related pBSSList of which ssid is obvious,
+//                  for these two AP is the same one!!!!
+/********judge by:BSSID is the same,but ssid is different!*****************/
+#if 0
+   for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+      if (IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pBSSList->abyBSSID)) {   //BSSID is the same!
+         if (memcmp(((PWLAN_IE_SSID)pMgmt->sBSSList[ii].abySSID)->abySSID,                  //ssid is different??
+		 	      ((PWLAN_IE_SSID)pBSSList->abySSID)->abySSID,
+		 	      ((PWLAN_IE_SSID)pBSSList->abySSID)->len) != 0) {
+                  //reserve temp
+               memset(abyTmpSSID,0,sizeof(abyTmpSSID));
+	      memcpy(abyTmpSSID,pMgmt->sBSSList[ii].abySSID,sizeof(abyTmpSSID));
+		  //upgrade the other one pBSSList
+	      memcpy(&(pMgmt->sBSSList[ii]),pBSSList,sizeof(KnownBSS));
+		  //recover ssid info
+	      memcpy(pMgmt->sBSSList[ii].abySSID,abyTmpSSID,sizeof(abyTmpSSID));
+           }
+       }
+    }
+#endif
+
+    return TRUE;
+}
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Search Node DB table to find the index of matched DstAddr
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+
+BOOL
+BSSbIsSTAInNodeDB(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyDstAddr,
+    OUT PUINT puNodeIndex
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+
+    // Index = 0 reserved for AP Node
+    for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            if (IS_ETH_ADDRESS_EQUAL(abyDstAddr, pMgmt->sNodeDBTable[ii].abyMACAddr)) {
+                *puNodeIndex = ii;
+                return TRUE;
+            }
+        }
+    }
+
+   return FALSE;
+};
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Find an empty node and allocated; if no empty found,
+ *    instand used of most inactive one.
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+VOID
+BSSvCreateOneNode(
+    IN HANDLE hDeviceContext,
+    OUT PUINT puNodeIndex
+    )
+{
+
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+    UINT            BigestCount = 0;
+    UINT            SelectIndex;
+    struct sk_buff  *skb;
+    // Index = 0 reserved for AP Node (In STA mode)
+    // Index = 0 reserved for Broadcast/MultiCast (In AP mode)
+    SelectIndex = 1;
+    for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            if (pMgmt->sNodeDBTable[ii].uInActiveCount > BigestCount) {
+                BigestCount = pMgmt->sNodeDBTable[ii].uInActiveCount;
+                SelectIndex = ii;
+            }
+        }
+        else {
+            break;
+        }
+    }
+
+    // if not found replace uInActiveCount is largest one.
+    if ( ii == (MAX_NODE_NUM + 1)) {
+        *puNodeIndex = SelectIndex;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Replace inactive node = %d\n", SelectIndex);
+        // clear ps buffer
+        if (pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue.next != NULL) {
+      	    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue)) != NULL)
+            dev_kfree_skb(skb);
+        }
+    }
+    else {
+        *puNodeIndex = ii;
+    }
+
+    memset(&pMgmt->sNodeDBTable[*puNodeIndex], 0, sizeof(KnownNodeDB));
+    pMgmt->sNodeDBTable[*puNodeIndex].bActive = TRUE;
+    pMgmt->sNodeDBTable[*puNodeIndex].uRatePollTimeout = FALLBACK_POLL_SECOND;
+    // for AP mode PS queue
+    skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue);
+    pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0;
+    pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii);
+    return;
+};
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Remove Node by NodeIndex
+ *
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+VOID
+BSSvRemoveOneNode(
+    IN HANDLE hDeviceContext,
+    IN UINT uNodeIndex
+    )
+{
+
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    struct sk_buff  *skb;
+
+
+    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue)) != NULL)
+            dev_kfree_skb(skb);
+    // clear context
+    memset(&pMgmt->sNodeDBTable[uNodeIndex], 0, sizeof(KnownNodeDB));
+    // clear tx bit map
+    pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[uNodeIndex].wAID >> 3] &=  ~byMask[pMgmt->sNodeDBTable[uNodeIndex].wAID & 7];
+
+    return;
+};
+/*+
+ *
+ * Routine Description:
+ *    Update AP Node content in Index 0 of KnownNodeDB
+ *
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+
+VOID
+BSSvUpdateAPNode(
+    IN HANDLE hDeviceContext,
+    IN PWORD pwCapInfo,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            uRateLen = WLAN_RATES_MAXLEN;
+
+    memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
+
+    pMgmt->sNodeDBTable[0].bActive = TRUE;
+    if (pDevice->byBBType == BB_TYPE_11B) {
+        uRateLen = WLAN_RATES_MAXLEN_11B;
+    }
+    pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pSuppRates,
+                                            (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                            uRateLen);
+    pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pExtSuppRates,
+                                            (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                                            uRateLen);
+    RATEvParseMaxRate((PVOID) pDevice,
+                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                       TRUE,
+                       &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
+                       &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
+                       &(pMgmt->sNodeDBTable[0].wSuppRate),
+                       &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
+                       &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
+                      );
+    memcpy(pMgmt->sNodeDBTable[0].abyMACAddr, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxSuppRate;
+    pMgmt->sNodeDBTable[0].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*pwCapInfo);
+    pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
+    // Auto rate fallback function initiation.
+    // RATEbInit(pDevice);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->sNodeDBTable[0].wTxDataRate = %d \n", pMgmt->sNodeDBTable[0].wTxDataRate);
+
+};
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Add Multicast Node content in Index 0 of KnownNodeDB
+ *
+ *
+ * Return Value:
+ *    None
+ *
+-*/
+
+
+VOID
+BSSvAddMulticastNode(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+    if (!pDevice->bEnableHostWEP)
+        memset(&pMgmt->sNodeDBTable[0], 0, sizeof(KnownNodeDB));
+    memset(pMgmt->sNodeDBTable[0].abyMACAddr, 0xff, WLAN_ADDR_LEN);
+    pMgmt->sNodeDBTable[0].bActive = TRUE;
+    pMgmt->sNodeDBTable[0].bPSEnable = FALSE;
+    skb_queue_head_init(&pMgmt->sNodeDBTable[0].sTxPSQueue);
+    RATEvParseMaxRate((PVOID) pDevice,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                      TRUE,
+                      &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
+                      &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
+                       &(pMgmt->sNodeDBTable[0].wSuppRate),
+                      &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
+                      &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
+                     );
+    pMgmt->sNodeDBTable[0].wTxDataRate = pMgmt->sNodeDBTable[0].wMaxBasicRate;
+    pMgmt->sNodeDBTable[0].uRatePollTimeout = FALLBACK_POLL_SECOND;
+
+};
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ *  Second call back function to update Node DB info & AP link status
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+VOID
+BSSvSecondCallBack(
+    IN  HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+    PWLAN_IE_SSID   pItemSSID, pCurrSSID;
+    UINT            uSleepySTACnt = 0;
+    UINT            uNonShortSlotSTACnt = 0;
+    UINT            uLongPreambleSTACnt = 0;
+    viawget_wpa_header *wpahdr;  //DavidWang
+
+    spin_lock_irq(&pDevice->lock);
+
+    pDevice->uAssocCount = 0;
+
+    //Power Saving Mode Tx Burst
+    if ( pDevice->bEnablePSMode == TRUE ) {
+        pDevice->ulPSModeWaitTx++;
+        if ( pDevice->ulPSModeWaitTx >= 2 ) {
+            pDevice->ulPSModeWaitTx = 0;
+            pDevice->bPSModeTxBurst = FALSE;
+        }
+    }
+
+    pDevice->byERPFlag &=
+        ~(WLAN_SET_ERP_BARKER_MODE(1) | WLAN_SET_ERP_NONERP_PRESENT(1));
+
+    if (pDevice->wUseProtectCntDown > 0) {
+        pDevice->wUseProtectCntDown --;
+    }
+    else {
+        // disable protect mode
+        pDevice->byERPFlag &= ~(WLAN_SET_ERP_USE_PROTECTION(1));
+    }
+
+if(pDevice->byReAssocCount > 0) {
+       pDevice->byReAssocCount++;
+   if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != TRUE)) {  //10 sec timeout
+                     printk("Re-association timeout!!!\n");
+		   pDevice->byReAssocCount = 0;
+                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                        {
+                  	union iwreq_data  wrqu;
+                  	memset(&wrqu, 0, sizeof (wrqu));
+                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                  	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+                  	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+     }
+   else if(pDevice->bLinkPass == TRUE)
+   	pDevice->byReAssocCount = 0;
+}
+
+#ifdef SndEvt_ToAPI
+if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) &&
+     (pMgmt->eLastState==WMAC_STATE_ASSOC))
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_DISCONNECTED_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+ pMgmt->eLastState = pMgmt->eCurrState ;
+#endif
+
+#ifdef Calcu_LinkQual
+   s_uCalculateLinkQual((HANDLE)pDevice);
+#endif
+
+    for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            // Increase in-activity counter
+            pMgmt->sNodeDBTable[ii].uInActiveCount++;
+
+            if (ii > 0) {
+                if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) {
+                    BSSvRemoveOneNode(pDevice, ii);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO
+                        "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii);
+                    continue;
+                }
+
+                if (pMgmt->sNodeDBTable[ii].eNodeState >= NODE_ASSOC) {
+
+                    pDevice->uAssocCount++;
+
+                    // check if Non ERP exist
+                    if (pMgmt->sNodeDBTable[ii].uInActiveCount < ERP_RECOVER_COUNT) {
+                        if (!pMgmt->sNodeDBTable[ii].bShortPreamble) {
+                            pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
+                            uLongPreambleSTACnt ++;
+                        }
+                        if (!pMgmt->sNodeDBTable[ii].bERPExist) {
+                            pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
+                            pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
+                        }
+                        if (!pMgmt->sNodeDBTable[ii].bShortSlotTime)
+                            uNonShortSlotSTACnt++;
+                    }
+                }
+
+                // check if any STA in PS mode
+                if (pMgmt->sNodeDBTable[ii].bPSEnable)
+                    uSleepySTACnt++;
+
+
+            }
+
+            // Rate fallback check
+            if (!pDevice->bFixRate) {
+/*
+                if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (ii == 0))
+                    RATEvTxRateFallBack(pDevice, &(pMgmt->sNodeDBTable[ii]));
+*/
+                if (ii > 0) {
+                    // ii = 0 for multicast node (AP & Adhoc)
+                    RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii]));
+                }
+                else {
+                    // ii = 0 reserved for unicast AP node (Infra STA)
+                    if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)
+                        RATEvTxRateFallBack((PVOID)pDevice, &(pMgmt->sNodeDBTable[ii]));
+                }
+
+            }
+
+            // check if pending PS queue
+            if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending \n",
+                           ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
+                if ((ii >0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) {
+                    BSSvRemoveOneNode(pDevice, ii);
+                    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove \n", ii);
+                    continue;
+                }
+            }
+        }
+
+    }
+
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->byBBType == BB_TYPE_11G)) {
+
+        // on/off protect mode
+        if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
+            if (!pDevice->bProtectMode) {
+                MACvEnableProtectMD(pDevice);
+                pDevice->bProtectMode = TRUE;
+            }
+        }
+        else {
+            if (pDevice->bProtectMode) {
+                MACvDisableProtectMD(pDevice);
+                pDevice->bProtectMode = FALSE;
+            }
+        }
+        // on/off short slot time
+
+        if (uNonShortSlotSTACnt > 0) {
+            if (pDevice->bShortSlotTime) {
+                pDevice->bShortSlotTime = FALSE;
+                BBvSetShortSlotTime(pDevice);
+                vUpdateIFS((PVOID)pDevice);
+            }
+        }
+        else {
+            if (!pDevice->bShortSlotTime) {
+                pDevice->bShortSlotTime = TRUE;
+                BBvSetShortSlotTime(pDevice);
+                vUpdateIFS((PVOID)pDevice);
+            }
+        }
+
+        // on/off barker long preamble mode
+
+        if (uLongPreambleSTACnt > 0) {
+            if (!pDevice->bBarkerPreambleMd) {
+                MACvEnableBarkerPreambleMd(pDevice);
+                pDevice->bBarkerPreambleMd = TRUE;
+            }
+        }
+        else {
+            if (pDevice->bBarkerPreambleMd) {
+                MACvDisableBarkerPreambleMd(pDevice);
+                pDevice->bBarkerPreambleMd = FALSE;
+            }
+        }
+
+    }
+
+
+    // Check if any STA in PS mode, enable DTIM multicast deliver
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (uSleepySTACnt > 0)
+            pMgmt->sNodeDBTable[0].bPSEnable = TRUE;
+        else
+            pMgmt->sNodeDBTable[0].bPSEnable = FALSE;
+    }
+
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+    pCurrSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
+
+        if (pMgmt->sNodeDBTable[0].bActive) { // Assoc with BSS
+           // DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Callback inactive Count = [%d]\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+
+            if (pDevice->bUpdateBBVGA) {
+               // s_vCheckSensitivity((HANDLE) pDevice);
+               s_vCheckPreEDThreshold((HANDLE)pDevice);
+            }
+
+    	    if ((pMgmt->sNodeDBTable[0].uInActiveCount >= (LOST_BEACON_COUNT/2)) &&
+    	        (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0]) ) {
+    	        pDevice->byBBVGANew = pDevice->abyBBVGA[0];
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
+    	    }
+
+        	if (pMgmt->sNodeDBTable[0].uInActiveCount >= LOST_BEACON_COUNT) {
+                pMgmt->sNodeDBTable[0].bActive = FALSE;
+                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+                pDevice->bRoaming = TRUE;
+                pDevice->bIsRoaming = FALSE;
+
+                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+	//let wpa supplicant know AP may disconnect.//20080717-01,<Add> by James Li
+        if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+             wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+             wpahdr->type = VIAWGET_DISASSOC_MSG;
+             wpahdr->resp_ie_len = 0;
+             wpahdr->req_ie_len = 0;
+             skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+             pDevice->skb->dev = pDevice->wpadev;
+	     skb_reset_mac_header(pDevice->skb);
+             pDevice->skb->pkt_type = PACKET_HOST;
+             pDevice->skb->protocol = htons(ETH_P_802_2);
+             memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+             netif_rx(pDevice->skb);
+             pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+         };
+   #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+  // if(pDevice->bWPASuppWextEnabled == TRUE)
+      {
+	union iwreq_data  wrqu;
+	memset(&wrqu, 0, sizeof (wrqu));
+        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+     }
+  #endif
+            }
+        }
+        else if (pItemSSID->len != 0) {
+//Davidwang
+      if ((pDevice->bEnableRoaming == TRUE)&&(!(pMgmt->Cisco_cckm))) {
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bRoaming %d, !\n", pDevice->bRoaming );
+DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bIsRoaming %d, !\n", pDevice->bIsRoaming );
+          if ((pDevice->bRoaming == TRUE)&&(pDevice->bIsRoaming == TRUE)){
+	    	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fast   Roaming ...\n");
+                BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+                pDevice->uAutoReConnectTime = 0;
+                pDevice->uIsroamingTime = 0;
+                pDevice->bRoaming = FALSE;
+
+//            if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+             wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+             wpahdr->type = VIAWGET_CCKM_ROAM_MSG;
+             wpahdr->resp_ie_len = 0;
+             wpahdr->req_ie_len = 0;
+             skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+             pDevice->skb->dev = pDevice->wpadev;
+	     skb_reset_mac_header(pDevice->skb);
+             pDevice->skb->pkt_type = PACKET_HOST;
+             pDevice->skb->protocol = htons(ETH_P_802_2);
+             memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+             netif_rx(pDevice->skb);
+            pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+
+//         }
+          }
+      else if ((pDevice->bRoaming == FALSE)&&(pDevice->bIsRoaming == TRUE)) {
+                            pDevice->uIsroamingTime++;
+       if (pDevice->uIsroamingTime >= 20)
+            pDevice->bIsRoaming = FALSE;
+         }
+
+   }
+else {
+            if (pDevice->uAutoReConnectTime < 10) {
+                pDevice->uAutoReConnectTime++;
+               #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                //network manager support need not do Roaming scan???
+                if(pDevice->bWPASuppWextEnabled ==TRUE)
+		 pDevice->uAutoReConnectTime = 0;
+	     #endif
+            }
+            else {
+	    //mike use old encryption status for wpa reauthen
+	      if(pDevice->bWPADEVUp)
+	          pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus;
+
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n");
+                BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+	       pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+                pDevice->uAutoReConnectTime = 0;
+            }
+        }
+    }
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+        // if adhoc started which essid is NULL string, rescaning.
+        if ((pMgmt->eCurrState == WMAC_STATE_STARTED) && (pCurrSSID->len == 0)) {
+            if (pDevice->uAutoReConnectTime < 10) {
+                pDevice->uAutoReConnectTime++;
+            }
+            else {
+                DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scaning ...\n");
+	       pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+                pDevice->uAutoReConnectTime = 0;
+            };
+        }
+        if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
+
+            if (pDevice->bUpdateBBVGA) {
+               //s_vCheckSensitivity((HANDLE) pDevice);
+               s_vCheckPreEDThreshold((HANDLE)pDevice);
+            }
+        	if (pMgmt->sNodeDBTable[0].uInActiveCount >=ADHOC_LOST_BEACON_COUNT) {
+        	    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount);
+                pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+                pMgmt->eCurrState = WMAC_STATE_STARTED;
+                netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+            }
+        }
+    }
+
+    if (pDevice->bLinkPass == TRUE) {
+        if (netif_queue_stopped(pDevice->dev))
+            netif_wake_queue(pDevice->dev);
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+
+    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
+    add_timer(&pMgmt->sTimerSecondCallback);
+    return;
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ *  Update Tx attemps, Tx failure counter in Node DB
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+
+VOID
+BSSvUpdateNodeTxCounter(
+    IN HANDLE      hDeviceContext,
+    IN PSStatCounter    pStatistic,
+    IN BYTE             byTSR,
+    IN BYTE             byPktNO
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            uNodeIndex = 0;
+    BYTE            byTxRetry;
+    WORD            wRate;
+    WORD            wFallBackRate = RATE_1M;
+    BYTE            byFallBack;
+    UINT            ii;
+    PBYTE           pbyDestAddr;
+    BYTE            byPktNum;
+    WORD            wFIFOCtl;
+
+
+
+    byPktNum = (byPktNO & 0x0F) >> 4;
+    byTxRetry = (byTSR & 0xF0) >> 4;
+    wRate = (WORD) (byPktNO & 0xF0) >> 4;
+    wFIFOCtl = pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl;
+    pbyDestAddr = (PBYTE) &( pStatistic->abyTxPktInfo[byPktNum].abyDestAddr[0]);
+
+    if (wFIFOCtl & FIFOCTL_AUTO_FB_0) {
+        byFallBack = AUTO_FB_0;
+    } else if (wFIFOCtl & FIFOCTL_AUTO_FB_1) {
+        byFallBack = AUTO_FB_1;
+    } else {
+        byFallBack = AUTO_FB_NONE;
+    }
+
+    // Only Unicast using support rates
+    if (wFIFOCtl & FIFOCTL_NEEDACK) {
+        //DBG_PRN_GRP21(("Device %08X, wRate %04X, byTSR %02X\n", hDeviceContext, wRate, byTSR));
+        if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
+            pMgmt->sNodeDBTable[0].uTxAttempts += 1;
+            if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
+                // transmit success, TxAttempts at least plus one
+                pMgmt->sNodeDBTable[0].uTxOk[MAX_RATE]++;
+                if ( (byFallBack == AUTO_FB_NONE) ||
+                     (wRate < RATE_18M) ) {
+                    wFallBackRate = wRate;
+                } else if (byFallBack == AUTO_FB_0) {
+                    if (byTxRetry < 5)
+                        wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
+                    else
+                        wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                } else if (byFallBack == AUTO_FB_1) {
+                    if (byTxRetry < 5)
+                        wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
+                    else
+                        wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                }
+                pMgmt->sNodeDBTable[0].uTxOk[wFallBackRate]++;
+            } else {
+                pMgmt->sNodeDBTable[0].uTxFailures ++;
+            }
+            pMgmt->sNodeDBTable[0].uTxRetry += byTxRetry;
+            if (byTxRetry != 0) {
+                pMgmt->sNodeDBTable[0].uTxFail[MAX_RATE]+=byTxRetry;
+                if ( (byFallBack == AUTO_FB_NONE) ||
+                     (wRate < RATE_18M) ) {
+                    pMgmt->sNodeDBTable[0].uTxFail[wRate]+=byTxRetry;
+                } else if (byFallBack == AUTO_FB_0) {
+                    for(ii=0;ii<byTxRetry;ii++) {
+                        if (ii < 5)
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
+                        else
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                        pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+                    }
+                } else if (byFallBack == AUTO_FB_1) {
+                    for(ii=0;ii<byTxRetry;ii++) {
+                        if (ii < 5)
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
+                        else
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                        pMgmt->sNodeDBTable[0].uTxFail[wFallBackRate]++;
+                    }
+                }
+            }
+        };
+
+        if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
+            (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
+
+            if (BSSbIsSTAInNodeDB((HANDLE)pDevice, pbyDestAddr, &uNodeIndex)){
+                pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts += 1;
+                if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
+                    // transmit success, TxAttempts at least plus one
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxOk[MAX_RATE]++;
+                    if ( (byFallBack == AUTO_FB_NONE) ||
+                         (wRate < RATE_18M) ) {
+                        wFallBackRate = wRate;
+                    } else if (byFallBack == AUTO_FB_0) {
+                        if (byTxRetry < 5)
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][byTxRetry];
+                        else
+                            wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                    } else if (byFallBack == AUTO_FB_1) {
+                        if (byTxRetry < 5)
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][byTxRetry];
+                        else
+                            wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                    }
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxOk[wFallBackRate]++;
+                } else {
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxFailures ++;
+                }
+                pMgmt->sNodeDBTable[uNodeIndex].uTxRetry += byTxRetry;
+                if (byTxRetry != 0) {
+                    pMgmt->sNodeDBTable[uNodeIndex].uTxFail[MAX_RATE]+=byTxRetry;
+                    if ( (byFallBack == AUTO_FB_NONE) ||
+                         (wRate < RATE_18M) ) {
+                        pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wRate]+=byTxRetry;
+                    } else if (byFallBack == AUTO_FB_0) {
+                        for(ii=0;ii<byTxRetry;ii++) {
+                            if (ii < 5)
+                                wFallBackRate = awHWRetry0[wRate-RATE_18M][ii];
+                            else
+                                wFallBackRate = awHWRetry0[wRate-RATE_18M][4];
+                            pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+                        }
+                    } else if (byFallBack == AUTO_FB_1) {
+                        for(ii=0;ii<byTxRetry;ii++) {
+                            if (ii < 5)
+                                wFallBackRate = awHWRetry1[wRate-RATE_18M][ii];
+                            else
+                                wFallBackRate = awHWRetry1[wRate-RATE_18M][4];
+                            pMgmt->sNodeDBTable[uNodeIndex].uTxFail[wFallBackRate]++;
+                        }
+                    }
+                }
+            };
+        }
+    };
+
+    return;
+
+
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Clear Nodes & skb in DB Table
+ *
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext        - The adapter context.
+ *      uStartIndex           - starting index
+ *  Out:
+ *      none
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+BSSvClearNodeDBTable(
+    IN HANDLE hDeviceContext,
+    IN UINT uStartIndex
+    )
+
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    struct sk_buff  *skb;
+    UINT            ii;
+
+    for (ii = uStartIndex; ii < (MAX_NODE_NUM + 1); ii++) {
+        if (pMgmt->sNodeDBTable[ii].bActive) {
+            // check if sTxPSQueue has been initial
+            if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) {
+                while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL){
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii);
+                        dev_kfree_skb(skb);
+                }
+            }
+            memset(&pMgmt->sNodeDBTable[ii], 0, sizeof(KnownNodeDB));
+        }
+    }
+
+    return;
+};
+
+
+VOID s_vCheckSensitivity(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PKnownBSS       pBSSList = NULL;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    int             ii;
+
+    if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+        ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+        pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
+        if (pBSSList != NULL) {
+            // Updata BB Reg if RSSI is too strong.
+            LONG    LocalldBmAverage = 0;
+            LONG    uNumofdBm = 0;
+            for (ii = 0; ii < RSSI_STAT_COUNT; ii++) {
+                if (pBSSList->ldBmAverage[ii] != 0) {
+                    uNumofdBm ++;
+                    LocalldBmAverage += pBSSList->ldBmAverage[ii];
+                }
+            }
+            if (uNumofdBm > 0) {
+                LocalldBmAverage = LocalldBmAverage/uNumofdBm;
+                for (ii=0;ii<BB_VGA_LEVEL;ii++) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[ii]);
+                    if (LocalldBmAverage < pDevice->ldBmThreshold[ii]) {
+                	    pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
+                        break;
+                    }
+                }
+                if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
+                    pDevice->uBBVGADiffCount++;
+                    if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD)
+                        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_CHANGE_BBSENSITIVITY, NULL);
+                } else {
+                    pDevice->uBBVGADiffCount = 0;
+                }
+            }
+        }
+    }
+}
+
+#ifdef Calcu_LinkQual
+VOID s_uCalculateLinkQual(
+    IN HANDLE hDeviceContext
+    )
+{
+   PSDevice        pDevice = (PSDevice)hDeviceContext;
+   ULONG TxOkRatio, TxCnt;
+   ULONG RxOkRatio,RxCnt;
+   ULONG RssiRatio;
+   long ldBm;
+
+TxCnt = pDevice->scStatistic.TxNoRetryOkCount +
+	      pDevice->scStatistic.TxRetryOkCount +
+	      pDevice->scStatistic.TxFailCount;
+RxCnt = pDevice->scStatistic.RxFcsErrCnt +
+	      pDevice->scStatistic.RxOkCnt;
+TxOkRatio = (TxCnt < 6) ? 4000:((pDevice->scStatistic.TxNoRetryOkCount * 4000) / TxCnt);
+RxOkRatio = (RxCnt < 6) ? 2000:((pDevice->scStatistic.RxOkCnt * 2000) / RxCnt);
+//decide link quality
+if(pDevice->bLinkPass !=TRUE)
+{
+ //  printk("s_uCalculateLinkQual-->Link disconnect and Poor quality**\n");
+   pDevice->scStatistic.LinkQuality = 0;
+   pDevice->scStatistic.SignalStren = 0;
+}
+else
+{
+   RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+   if(-ldBm < 50)  {
+   	RssiRatio = 4000;
+     }
+   else if(-ldBm > 90) {
+   	RssiRatio = 0;
+     }
+   else {
+   	RssiRatio = (40-(-ldBm-50))*4000/40;
+     }
+   pDevice->scStatistic.SignalStren = RssiRatio/40;
+   pDevice->scStatistic.LinkQuality = (RssiRatio+TxOkRatio+RxOkRatio)/100;
+}
+   pDevice->scStatistic.RxFcsErrCnt = 0;
+   pDevice->scStatistic.RxOkCnt = 0;
+   pDevice->scStatistic.TxFailCount = 0;
+   pDevice->scStatistic.TxNoRetryOkCount = 0;
+   pDevice->scStatistic.TxRetryOkCount = 0;
+   return;
+}
+#endif
+
+VOID
+BSSvClearAnyBSSJoinRecord (
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pMgmt->sBSSList[ii].bSelected = FALSE;
+    }
+    return;
+}
+
+VOID s_vCheckPreEDThreshold(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PKnownBSS       pBSSList = NULL;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+    if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+        ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+        pBSSList = BSSpAddrIsInBSSList(pDevice, pMgmt->abyCurrBSSID, (PWLAN_IE_SSID)pMgmt->abyCurrSSID);
+        if (pBSSList != NULL) {
+            pDevice->byBBPreEDRSSI = (BYTE) (~(pBSSList->ldBmAverRange) + 1);
+            BBvUpdatePreEDThreshold(pDevice, FALSE);
+        }
+    }
+    return;
+}
+
diff --git a/drivers/staging/vt6656/bssdb.h b/drivers/staging/vt6656/bssdb.h
new file mode 100644
index 0000000..f365b6b
--- /dev/null
+++ b/drivers/staging/vt6656/bssdb.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: bssdb.h
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 16, 2002
+ *
+ */
+
+#ifndef __BSSDB_H__
+#define __BSSDB_H__
+
+#include <linux/skbuff.h>
+#include "80211hdr.h"
+#include "80211mgr.h"
+#include "card.h"
+#include "mib.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define MAX_NODE_NUM             64
+#define MAX_BSS_NUM              42
+#define LOST_BEACON_COUNT      	 10   // 10 sec, XP defined
+#define MAX_PS_TX_BUF            32   // sta max power saving tx buf
+#define ADHOC_LOST_BEACON_COUNT  30   // 30 sec, beacon lost for adhoc only
+#define MAX_INACTIVE_COUNT       300  // 300 sec, inactive STA node refresh
+
+#define USE_PROTECT_PERIOD       10   // 10 sec, Use protect mode check period
+#define ERP_RECOVER_COUNT        30   // 30 sec, ERP support callback check
+#define BSS_CLEAR_COUNT           1
+
+#define RSSI_STAT_COUNT          10
+#define MAX_CHECK_RSSI_COUNT     8
+
+// STA dwflags
+#define WLAN_STA_AUTH            BIT0
+#define WLAN_STA_ASSOC           BIT1
+#define WLAN_STA_PS              BIT2
+#define WLAN_STA_TIM             BIT3
+// permanent; do not remove entry on expiration
+#define WLAN_STA_PERM            BIT4
+// If 802.1X is used, this flag is
+// controlling whether STA is authorized to
+// send and receive non-IEEE 802.1X frames
+#define WLAN_STA_AUTHORIZED      BIT5
+
+//#define MAX_RATE            12
+
+#define MAX_WPA_IE_LEN      64
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+//
+// IEEE 802.11 Structures and definitions
+//
+
+typedef struct tagSERPObject {
+    BOOL    bERPExist;
+    BYTE    byERP;
+}ERPObject, *PERPObject;
+
+
+typedef struct tagSRSNCapObject {
+    BOOL    bRSNCapExist;
+    WORD    wRSNCap;
+}SRSNCapObject, *PSRSNCapObject;
+
+// BSS info(AP)
+#pragma pack(1)
+typedef struct tagKnownBSS {
+    // BSS info
+    BOOL            bActive;
+    BYTE            abyBSSID[WLAN_BSSID_LEN];
+    UINT            uChannel;
+    BYTE            abySuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE            abyExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    UINT            uRSSI;
+    BYTE            bySQ;
+    WORD            wBeaconInterval;
+    WORD            wCapInfo;
+    BYTE            abySSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE            byRxRate;
+
+//    WORD            wATIMWindow;
+    BYTE            byRSSIStatCnt;
+    LONG            ldBmMAX;
+    LONG            ldBmAverage[RSSI_STAT_COUNT];
+    LONG            ldBmAverRange;
+    //For any BSSID selection improvment
+    BOOL            bSelected;
+
+    //++ WPA informations
+    BOOL            bWPAValid;
+    BYTE            byGKType;
+    BYTE            abyPKType[4];
+    WORD            wPKCount;
+    BYTE            abyAuthType[4];
+    WORD            wAuthCount;
+    BYTE            byDefaultK_as_PK;
+    BYTE            byReplayIdx;
+    //--
+
+    //++ WPA2 informations
+    BOOL            bWPA2Valid;
+    BYTE            byCSSGK;
+    WORD            wCSSPKCount;
+    BYTE            abyCSSPK[4];
+    WORD            wAKMSSAuthCount;
+    BYTE            abyAKMSSAuthType[4];
+
+    //++  wpactl
+    BYTE            byWPAIE[MAX_WPA_IE_LEN];
+    BYTE            byRSNIE[MAX_WPA_IE_LEN];
+    WORD            wWPALen;
+    WORD            wRSNLen;
+
+    // Clear count
+    UINT            uClearCount;
+//    BYTE            abyIEs[WLAN_BEACON_FR_MAXLEN];
+    UINT            uIELength;
+    QWORD           qwBSSTimestamp;
+    QWORD           qwLocalTSF;     // local TSF timer
+
+    CARD_PHY_TYPE   eNetworkTypeInUse;
+
+    ERPObject       sERP;
+    SRSNCapObject   sRSNCapObj;
+    BYTE            abyIEs[1024];   // don't move this field !!
+
+}__attribute__ ((__packed__))
+KnownBSS , *PKnownBSS;
+
+
+
+typedef enum tagNODE_STATE {
+    NODE_FREE,
+    NODE_AGED,
+    NODE_KNOWN,
+    NODE_AUTH,
+    NODE_ASSOC
+} NODE_STATE, *PNODE_STATE;
+
+
+// STA node info
+typedef struct tagKnownNodeDB {
+    // STA info
+    BOOL            bActive;
+    BYTE            abyMACAddr[WLAN_ADDR_LEN];
+    BYTE            abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+    BYTE            abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+    WORD            wTxDataRate;
+    BOOL            bShortPreamble;
+    BOOL            bERPExist;
+    BOOL            bShortSlotTime;
+    UINT            uInActiveCount;
+    WORD            wMaxBasicRate;     //Get from byTopOFDMBasicRate or byTopCCKBasicRate which depends on packetTyp.
+    WORD            wMaxSuppRate;      //Records the highest supported rate getting from SuppRates IE and ExtSuppRates IE in Beacon.
+    WORD            wSuppRate;
+    BYTE            byTopOFDMBasicRate;//Records the highest basic rate in OFDM mode
+    BYTE            byTopCCKBasicRate; //Records the highest basic rate in CCK mode
+
+    // For AP mode
+    struct sk_buff_head sTxPSQueue;
+    WORD            wCapInfo;
+    WORD            wListenInterval;
+    WORD            wAID;
+    NODE_STATE      eNodeState;
+    BOOL            bPSEnable;
+    BOOL            bRxPSPoll;
+    BYTE            byAuthSequence;
+    ULONG           ulLastRxJiffer;
+    BYTE            bySuppRate;
+    DWORD           dwFlags;
+    WORD            wEnQueueCnt;
+
+    BOOL            bOnFly;
+    ULONGLONG       KeyRSC;
+    BYTE            byKeyIndex;
+    DWORD           dwKeyIndex;
+    BYTE            byCipherSuite;
+    DWORD           dwTSC47_16;
+    WORD            wTSC15_0;
+    UINT            uWepKeyLength;
+    BYTE            abyWepKey[WLAN_WEPMAX_KEYLEN];
+    //
+    // Auto rate fallback vars
+    BOOL            bIsInFallback;
+    UINT            uAverageRSSI;
+    UINT            uRateRecoveryTimeout;
+    UINT            uRatePollTimeout;
+    UINT            uTxFailures;
+    UINT            uTxAttempts;
+
+    UINT            uTxRetry;
+    UINT            uFailureRatio;
+    UINT            uRetryRatio;
+    UINT            uTxOk[MAX_RATE+1];
+    UINT            uTxFail[MAX_RATE+1];
+    UINT            uTimeCount;
+
+} KnownNodeDB, *PKnownNodeDB;
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+PKnownBSS
+BSSpSearchBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE pbyDesireBSSID,
+    IN PBYTE pbyDesireSSID,
+    IN CARD_PHY_TYPE ePhyType
+    );
+
+PKnownBSS
+BSSpAddrIsInBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSID,
+    IN PWLAN_IE_SSID pSSID
+    );
+
+VOID
+BSSvClearBSSList(
+    IN HANDLE hDeviceContext,
+    IN BOOL bKeepCurrBSSID
+    );
+
+BOOL
+BSSbInsertToBSSList(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyBSSIDAddr,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    );
+
+
+BOOL
+BSSbUpdateToBSSList(
+    IN HANDLE hDeviceContext,
+    IN QWORD qwTimestamp,
+    IN WORD wBeaconInterval,
+    IN WORD wCapInfo,
+    IN BYTE byCurrChannel,
+    IN BOOL bChannelHit,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pSuppRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates,
+    IN PERPObject psERP,
+    IN PWLAN_IE_RSN pRSN,
+    IN PWLAN_IE_RSN_EXT pRSNWPA,
+    IN PWLAN_IE_COUNTRY pIE_Country,
+    IN PWLAN_IE_QUIET pIE_Quiet,
+    IN PKnownBSS pBSSList,
+    IN UINT uIELength,
+    IN PBYTE pbyIEs,
+    IN HANDLE pRxPacketContext
+    );
+
+
+BOOL
+BSSbIsSTAInNodeDB(
+    IN HANDLE hDeviceContext,
+    IN PBYTE abyDstAddr,
+    OUT PUINT puNodeIndex
+    );
+
+VOID
+BSSvCreateOneNode(
+    IN HANDLE hDeviceContext,
+    OUT PUINT puNodeIndex
+    );
+
+VOID
+BSSvUpdateAPNode(
+    IN HANDLE hDeviceContext,
+    IN PWORD pwCapInfo,
+    IN PWLAN_IE_SUPP_RATES pItemRates,
+    IN PWLAN_IE_SUPP_RATES pExtSuppRates
+    );
+
+
+VOID
+BSSvSecondCallBack(
+    IN HANDLE hDeviceContext
+    );
+
+
+VOID
+BSSvUpdateNodeTxCounter(
+    IN HANDLE      hDeviceContext,
+    IN PSStatCounter    pStatistic,
+    IN BYTE             byTSR,
+    IN BYTE             byPktNO
+    );
+
+VOID
+BSSvRemoveOneNode(
+    IN HANDLE hDeviceContext,
+    IN UINT uNodeIndex
+    );
+
+VOID
+BSSvAddMulticastNode(
+    IN HANDLE hDeviceContext
+    );
+
+
+VOID
+BSSvClearNodeDBTable(
+    IN HANDLE hDeviceContext,
+    IN UINT uStartIndex
+    );
+
+VOID
+BSSvClearAnyBSSJoinRecord(
+    IN HANDLE hDeviceContext
+    );
+
+#endif //__BSSDB_H__
diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c
new file mode 100644
index 0000000..d73efee
--- /dev/null
+++ b/drivers/staging/vt6656/card.c
@@ -0,0 +1,1113 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: card.c
+ * Purpose: Provide functions to setup NIC operation mode
+ * Functions:
+ *      s_vSafeResetTx - Rest Tx
+ *      CARDvSetRSPINF - Set RSPINF
+ *      vUpdateIFS - Update slotTime,SIFS,DIFS, and EIFS
+ *      CARDvUpdateBasicTopRate - Update BasicTopRate
+ *      CARDbAddBasicRate - Add to BasicRateSet
+ *      CARDbSetBasicRate - Set Basic Tx Rate
+ *      CARDbIsOFDMinBasicRate - Check if any OFDM rate is in BasicRateSet
+ *      CARDvSetLoopbackMode - Set Loopback mode
+ *      CARDbSoftwareReset - Sortware reset NIC
+ *      CARDqGetTSFOffset - Caculate TSFOffset
+ *      CARDbGetCurrentTSF - Read Current NIC TSF counter
+ *      CARDqGetNextTBTT - Caculate Next Beacon TSF counter
+ *      CARDvSetFirstNextTBTT - Set NIC Beacon time
+ *      CARDvUpdateNextTBTT - Sync. NIC Beacon time
+ *      CARDbRadioPowerOff - Turn Off NIC Radio Power
+ *      CARDbRadioPowerOn - Turn On NIC Radio Power
+ *      CARDbSetWEPMode - Set NIC Wep mode
+ *      CARDbSetTxPower - Set NIC tx power
+ *
+ * Revision History:
+ *      06-10-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
+ *      08-26-2003 Kyle Hsu:      Modify the defination type of dwIoBase.
+ *      09-01-2003 Bryan YC Fan:  Add vUpdateIFS().
+ *
+ */
+
+#include "tmacro.h"
+#include "card.h"
+#include "baseband.h"
+#include "mac.h"
+#include "desc.h"
+#include "rf.h"
+#include "power.h"
+#include "key.h"
+#include "rc4.h"
+#include "country.h"
+#include "datarate.h"
+#include "rndis.h"
+#include "control.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+/*---------------------  Static Definitions -------------------------*/
+#define CB_TXPOWER_LEVEL            6
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//const WORD cwRXBCNTSFOff[MAX_RATE] =
+//{17, 34, 96, 192, 34, 23, 17, 11, 8, 5, 4, 3};
+
+const WORD cwRXBCNTSFOff[MAX_RATE] =
+{192, 96, 34, 17, 34, 23, 17, 11, 8, 5, 4, 3};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+/*
+ * Description: Set NIC media channel
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      uConnectionChannel  - Channel to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL CARDbSetMediaChannel (PVOID pDeviceHandler, UINT uConnectionChannel)
+{
+PSDevice            pDevice = (PSDevice) pDeviceHandler;
+BOOL                bResult = TRUE;
+
+
+    if (pDevice->byBBType == BB_TYPE_11A) { // 15 ~ 38
+        if ((uConnectionChannel < (CB_MAX_CHANNEL_24G+1)) || (uConnectionChannel > CB_MAX_CHANNEL))
+            uConnectionChannel = (CB_MAX_CHANNEL_24G+1);
+    } else {
+        if ((uConnectionChannel > CB_MAX_CHANNEL_24G) || (uConnectionChannel == 0)) // 1 ~ 14
+            uConnectionChannel = 1;
+    }
+
+    // clear NAV
+    MACvRegBitsOn(pDevice, MAC_REG_MACCR, MACCR_CLRNAV);
+
+    // Set Channel[7] = 0 to tell H/W channel is changing now.
+    MACvRegBitsOff(pDevice, MAC_REG_CHANNEL, 0x80);
+
+    //if (pMgmt->uCurrChannel == uConnectionChannel)
+    //    return bResult;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SELECT_CHANNLE,
+                        (WORD) uConnectionChannel,
+                        0,
+                        0,
+                        NULL
+                        );
+
+    //{{ RobertYu: 20041202
+    //// TX_PE will reserve 3 us for MAX2829 A mode only, it is for better TX throughput
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        pDevice->byCurPwr = 0xFF;
+        RFbRawSetPower(pDevice, pDevice->abyOFDMAPwrTbl[uConnectionChannel-15], RATE_54M);
+    } else if (pDevice->byBBType == BB_TYPE_11G) {
+        pDevice->byCurPwr = 0xFF;
+        RFbRawSetPower(pDevice, pDevice->abyOFDMPwrTbl[uConnectionChannel-1], RATE_54M);
+    } else {
+        pDevice->byCurPwr = 0xFF;
+        RFbRawSetPower(pDevice, pDevice->abyCCKPwrTbl[uConnectionChannel-1], RATE_1M);
+    }
+    ControlvWriteByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_CHANNEL,(BYTE)(uConnectionChannel|0x80));
+    return(bResult);
+}
+
+/*
+ * Description: Get CCK mode basic rate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      wRateIdx            - Receiving data rate
+ *  Out:
+ *      none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+static
+WORD swGetCCKControlRate(PVOID pDeviceHandler, WORD wRateIdx)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT ui = (UINT)wRateIdx;
+    while (ui > RATE_1M) {
+        if (pDevice->wBasicRate & ((WORD)1 << ui)) {
+            return (WORD)ui;
+        }
+        ui --;
+    }
+    return (WORD)RATE_1M;
+}
+
+/*
+ * Description: Get OFDM mode basic rate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *      wRateIdx            - Receiving data rate
+ *  Out:
+ *      none
+ *
+ * Return Value: response Control frame rate
+ *
+ */
+static
+WORD swGetOFDMControlRate (PVOID pDeviceHandler, WORD wRateIdx)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT ui = (UINT)wRateIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BASIC RATE: %X\n", pDevice->wBasicRate);
+
+    if (!CARDbIsOFDMinBasicRate(pDevice)) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx);
+        if (wRateIdx > RATE_24M)
+            wRateIdx = RATE_24M;
+        return wRateIdx;
+    }
+    while (ui > RATE_11M) {
+        if (pDevice->wBasicRate & ((WORD)1 << ui)) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate : %d\n", ui);
+            return (WORD)ui;
+        }
+        ui --;
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"swGetOFDMControlRate: 6M\n");
+    return (WORD)RATE_24M;
+}
+
+/*
+ * Description: Caculate TxRate and RsvTime fields for RSPINF in OFDM mode.
+ *
+ * Parameters:
+ *  In:
+ *      wRate           - Tx Rate
+ *      byPktType       - Tx Packet type
+ *  Out:
+ *      pbyTxRate       - pointer to RSPINF TxRate field
+ *      pbyRsvTime      - pointer to RSPINF RsvTime field
+ *
+ * Return Value: none
+ *
+ */
+VOID
+CARDvCaculateOFDMRParameter (
+    IN  WORD wRate,
+    IN  BYTE byBBType,
+    OUT PBYTE pbyTxRate,
+    OUT PBYTE pbyRsvTime
+    )
+{
+    switch (wRate) {
+    case RATE_6M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9B;
+            *pbyRsvTime = 24;
+        }
+        else {
+            *pbyTxRate = 0x8B;
+            *pbyRsvTime = 30;
+        }
+        break;
+
+    case RATE_9M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9F;
+            *pbyRsvTime = 16;
+        }
+        else {
+            *pbyTxRate = 0x8F;
+            *pbyRsvTime = 22;
+        }
+        break;
+
+   case RATE_12M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9A;
+            *pbyRsvTime = 12;
+        }
+        else {
+            *pbyTxRate = 0x8A;
+            *pbyRsvTime = 18;
+        }
+        break;
+
+   case RATE_18M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9E;
+            *pbyRsvTime = 8;
+        }
+        else {
+            *pbyTxRate = 0x8E;
+            *pbyRsvTime = 14;
+        }
+        break;
+
+    case RATE_36M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9D;
+            *pbyRsvTime = 4;
+        }
+        else {
+            *pbyTxRate = 0x8D;
+            *pbyRsvTime = 10;
+        }
+        break;
+
+    case RATE_48M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x98;
+            *pbyRsvTime = 4;
+        }
+        else {
+            *pbyTxRate = 0x88;
+            *pbyRsvTime = 10;
+        }
+        break;
+
+    case RATE_54M :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x9C;
+            *pbyRsvTime = 4;
+        }
+        else {
+            *pbyTxRate = 0x8C;
+            *pbyRsvTime = 10;
+        }
+        break;
+
+    case RATE_24M :
+    default :
+        if (byBBType == BB_TYPE_11A) {//5GHZ
+            *pbyTxRate = 0x99;
+            *pbyRsvTime = 8;
+        }
+        else {
+            *pbyTxRate = 0x89;
+            *pbyRsvTime = 14;
+        }
+        break;
+    }
+}
+
+/*
+ * Description: Set RSPINF
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+void CARDvSetRSPINF (PVOID pDeviceHandler, BYTE byBBType)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BYTE    abyServ[4] = {0,0,0,0};             // For CCK
+    BYTE    abySignal[4] = {0,0,0,0};
+    WORD    awLen[4] = {0,0,0,0};
+    BYTE    abyTxRate[9] = {0,0,0,0,0,0,0,0,0}; // For OFDM
+    BYTE    abyRsvTime[9] = {0,0,0,0,0,0,0,0,0};
+    BYTE    abyData[34];
+    int     i;
+
+    //RSPINF_b_1
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_1M),
+                         PK_TYPE_11B,
+                         &awLen[0],
+                         &abyServ[0],
+                         &abySignal[0]
+    );
+
+    ///RSPINF_b_2
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_2M),
+                         PK_TYPE_11B,
+                         &awLen[1],
+                         &abyServ[1],
+                         &abySignal[1]
+    );
+
+    //RSPINF_b_5
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_5M),
+                         PK_TYPE_11B,
+                         &awLen[2],
+                         &abyServ[2],
+                         &abySignal[2]
+    );
+
+    //RSPINF_b_11
+    BBvCaculateParameter(pDevice,
+                         14,
+                         swGetCCKControlRate(pDevice, RATE_11M),
+                         PK_TYPE_11B,
+                         &awLen[3],
+                         &abyServ[3],
+                         &abySignal[3]
+    );
+
+    //RSPINF_a_6
+    CARDvCaculateOFDMRParameter (RATE_6M,
+                                 byBBType,
+                                 &abyTxRate[0],
+                                 &abyRsvTime[0]);
+
+    //RSPINF_a_9
+    CARDvCaculateOFDMRParameter (RATE_9M,
+                                 byBBType,
+                                 &abyTxRate[1],
+                                 &abyRsvTime[1]);
+
+    //RSPINF_a_12
+    CARDvCaculateOFDMRParameter (RATE_12M,
+                                 byBBType,
+                                 &abyTxRate[2],
+                                 &abyRsvTime[2]);
+
+    //RSPINF_a_18
+    CARDvCaculateOFDMRParameter (RATE_18M,
+                                 byBBType,
+                                 &abyTxRate[3],
+                                 &abyRsvTime[3]);
+
+    //RSPINF_a_24
+    CARDvCaculateOFDMRParameter (RATE_24M,
+                                 byBBType,
+                                 &abyTxRate[4],
+                                 &abyRsvTime[4]);
+
+    //RSPINF_a_36
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_36M),
+                                 byBBType,
+                                 &abyTxRate[5],
+                                 &abyRsvTime[5]);
+
+    //RSPINF_a_48
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_48M),
+                                 byBBType,
+                                 &abyTxRate[6],
+                                 &abyRsvTime[6]);
+
+    //RSPINF_a_54
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
+                                 byBBType,
+                                 &abyTxRate[7],
+                                 &abyRsvTime[7]);
+
+    //RSPINF_a_72
+    CARDvCaculateOFDMRParameter (swGetOFDMControlRate(pDevice, RATE_54M),
+                                 byBBType,
+                                 &abyTxRate[8],
+                                 &abyRsvTime[8]);
+
+    abyData[0] = (BYTE)(awLen[0]&0xFF);
+    abyData[1] = (BYTE)(awLen[0]>>8);
+    abyData[2] = abySignal[0];
+    abyData[3] = abyServ[0];
+
+    abyData[4] = (BYTE)(awLen[1]&0xFF);
+    abyData[5] = (BYTE)(awLen[1]>>8);
+    abyData[6] = abySignal[1];
+    abyData[7] = abyServ[1];
+
+    abyData[8] = (BYTE)(awLen[2]&0xFF);
+    abyData[9] = (BYTE)(awLen[2]>>8);
+    abyData[10] = abySignal[2];
+    abyData[11] = abyServ[2];
+
+    abyData[12] = (BYTE)(awLen[3]&0xFF);
+    abyData[13] = (BYTE)(awLen[3]>>8);
+    abyData[14] = abySignal[3];
+    abyData[15] = abyServ[3];
+
+    for(i=0;i<9;i++) {
+        abyData[16+i*2] = abyTxRate[i];
+        abyData[16+i*2+1] = abyRsvTime[i];
+    }
+
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_RSPINF_B_1,
+                        MESSAGE_REQUEST_MACREG,
+                        34,
+                        &abyData[0]);
+
+}
+
+/*
+ * Description: Update IFS
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             - The adapter to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+ */
+void vUpdateIFS (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    //Set SIFS, DIFS, EIFS, SlotTime, CwMin
+    BYTE byMaxMin = 0;
+    BYTE byData[4];
+
+    if (pDevice->byPacketType==PK_TYPE_11A) {//0000 0000 0000 0000,11a
+        pDevice->uSlot = C_SLOT_SHORT;
+        pDevice->uSIFS = C_SIFS_A;
+        pDevice->uDIFS = C_SIFS_A + 2*C_SLOT_SHORT;
+        pDevice->uCwMin = C_CWMIN_A;
+        byMaxMin = 4;
+    }
+    else if (pDevice->byPacketType==PK_TYPE_11B) {//0000 0001 0000 0000,11b
+        pDevice->uSlot = C_SLOT_LONG;
+        pDevice->uSIFS = C_SIFS_BG;
+        pDevice->uDIFS = C_SIFS_BG + 2*C_SLOT_LONG;
+          pDevice->uCwMin = C_CWMIN_B;
+        byMaxMin = 5;
+    }
+    else {// PK_TYPE_11GA & PK_TYPE_11GB
+        BYTE byRate = 0;
+        BOOL bOFDMRate = FALSE;
+        UINT ii = 0;
+        PWLAN_IE_SUPP_RATES pItemRates = NULL;
+
+        pDevice->uSIFS = C_SIFS_BG;
+        if (pDevice->bShortSlotTime) {
+            pDevice->uSlot = C_SLOT_SHORT;
+        } else {
+            pDevice->uSlot = C_SLOT_LONG;
+        }
+        pDevice->uDIFS = C_SIFS_BG + 2*pDevice->uSlot;
+
+        pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->sMgmtObj.abyCurrSuppRates;
+        for (ii = 0; ii < pItemRates->len; ii++) {
+            byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+            if (RATEwGetRateIdx(byRate) > RATE_11M) {
+                bOFDMRate = TRUE;
+                break;
+            }
+        }
+        if (bOFDMRate == FALSE) {
+            pItemRates = (PWLAN_IE_SUPP_RATES)pDevice->sMgmtObj.abyCurrExtSuppRates;
+            for (ii = 0; ii < pItemRates->len; ii++) {
+                byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+                if (RATEwGetRateIdx(byRate) > RATE_11M) {
+                    bOFDMRate = TRUE;
+                    break;
+                }
+            }
+        }
+        if (bOFDMRate == TRUE) {
+            pDevice->uCwMin = C_CWMIN_A;
+            byMaxMin = 4;
+        } else {
+            pDevice->uCwMin = C_CWMIN_B;
+            byMaxMin = 5;
+        }
+    }
+
+    pDevice->uCwMax = C_CWMAX;
+    pDevice->uEIFS = C_EIFS;
+
+    byData[0] = (BYTE)pDevice->uSIFS;
+    byData[1] = (BYTE)pDevice->uDIFS;
+    byData[2] = (BYTE)pDevice->uEIFS;
+    byData[3] = (BYTE)pDevice->uSlot;
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_SIFS,
+                        MESSAGE_REQUEST_MACREG,
+                        4,
+                        &byData[0]);
+
+    byMaxMin |= 0xA0;//1010 1111,C_CWMAX = 1023
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_CWMAXMIN0,
+                        MESSAGE_REQUEST_MACREG,
+                        1,
+                        &byMaxMin);
+}
+
+void CARDvUpdateBasicTopRate (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+BYTE byTopOFDM = RATE_24M, byTopCCK = RATE_1M;
+BYTE ii;
+
+     //Determines the highest basic rate.
+     for (ii = RATE_54M; ii >= RATE_6M; ii --) {
+         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
+             byTopOFDM = ii;
+             break;
+         }
+     }
+     pDevice->byTopOFDMBasicRate = byTopOFDM;
+
+     for (ii = RATE_11M;; ii --) {
+         if ( (pDevice->wBasicRate) & ((WORD)(1<<ii)) ) {
+             byTopCCK = ii;
+             break;
+         }
+         if (ii == RATE_1M)
+            break;
+     }
+     pDevice->byTopCCKBasicRate = byTopCCK;
+ }
+
+/*
+ * Description: Set NIC Tx Basic Rate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be set
+ *      wBasicRate      - Basic Rate to be set
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL CARDbAddBasicRate (PVOID pDeviceHandler, WORD wRateIdx)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+WORD wRate = (WORD)(1<<wRateIdx);
+
+    pDevice->wBasicRate |= wRate;
+
+    //Determines the highest basic rate.
+    CARDvUpdateBasicTopRate(pDevice);
+
+    return(TRUE);
+}
+
+BOOL CARDbIsOFDMinBasicRate (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+int ii;
+
+    for (ii = RATE_54M; ii >= RATE_6M; ii --) {
+        if ((pDevice->wBasicRate) & ((WORD)(1<<ii)))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+BYTE CARDbyGetPktType (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) {
+        return (BYTE)pDevice->byBBType;
+    }
+    else if (CARDbIsOFDMinBasicRate(pDevice)) {
+        return PK_TYPE_11GA;
+    }
+    else {
+        return PK_TYPE_11GB;
+    }
+}
+
+
+/*
+ * Description: Caculate TSF offset of two TSF input
+ *              Get TSF Offset from RxBCN's TSF and local TSF
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be sync.
+ *      qwTSF1          - Rx BCN's TSF
+ *      qwTSF2          - Local TSF
+ *  Out:
+ *      none
+ *
+ * Return Value: TSF Offset value
+ *
+ */
+QWORD CARDqGetTSFOffset (BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2)
+{
+    QWORD   qwTSFOffset;
+    WORD    wRxBcnTSFOffst = 0;
+
+    HIDWORD(qwTSFOffset) = 0;
+    LODWORD(qwTSFOffset) = 0;
+
+    wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE];
+    (qwTSF2).u.dwLowDword += (DWORD)(wRxBcnTSFOffst);
+    if ((qwTSF2).u.dwLowDword < (DWORD)(wRxBcnTSFOffst)) {
+        (qwTSF2).u.dwHighDword++;
+    }
+    LODWORD(qwTSFOffset) = LODWORD(qwTSF1) - LODWORD(qwTSF2);
+    if (LODWORD(qwTSF1) < LODWORD(qwTSF2)) {
+        // if borrow needed
+        HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1 ;
+    }
+    else {
+        HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2);
+    };
+    return (qwTSFOffset);
+}
+
+
+
+/*
+ * Description: Sync. TSF counter to BSS
+ *              Get TSF offset and write to HW
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be sync.
+ *      qwBSSTimestamp  - Rx BCN's TSF
+ *      qwLocalTSF      - Local TSF
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvAdjustTSF (PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF)
+{
+
+    PSDevice        pDevice = (PSDevice) pDeviceHandler;
+    QWORD           qwTSFOffset;
+    DWORD           dwTSFOffset1,dwTSFOffset2;
+    BYTE            pbyData[8];
+
+    HIDWORD(qwTSFOffset) = 0;
+    LODWORD(qwTSFOffset) = 0;
+
+    qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF);
+    // adjust TSF
+    // HW's TSF add TSF Offset reg
+    dwTSFOffset1 = LODWORD(qwTSFOffset);
+    dwTSFOffset2 = HIDWORD(qwTSFOffset);
+
+
+    pbyData[0] = (BYTE)dwTSFOffset1;
+    pbyData[1] = (BYTE)(dwTSFOffset1>>8);
+    pbyData[2] = (BYTE)(dwTSFOffset1>>16);
+    pbyData[3] = (BYTE)(dwTSFOffset1>>24);
+    pbyData[4] = (BYTE)dwTSFOffset2;
+    pbyData[5] = (BYTE)(dwTSFOffset2>>8);
+    pbyData[6] = (BYTE)(dwTSFOffset2>>16);
+    pbyData[7] = (BYTE)(dwTSFOffset2>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SET_TSFTBTT,
+                        MESSAGE_REQUEST_TSF,
+                        0,
+                        8,
+                        pbyData
+                        );
+
+}
+/*
+ * Description: Read NIC TSF counter
+ *              Get local TSF counter
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be read
+ *  Out:
+ *      qwCurrTSF       - Current TSF counter
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbGetCurrentTSF (PVOID pDeviceHandler, PQWORD pqwCurrTSF)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    LODWORD(*pqwCurrTSF) = LODWORD(pDevice->qwCurrTSF);
+    HIDWORD(*pqwCurrTSF) = HIDWORD(pDevice->qwCurrTSF);
+
+    return(TRUE);
+}
+
+
+/*
+ * Description: Clear NIC TSF counter
+ *              Clear local TSF counter
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be read
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbClearCurrentTSF(PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    MACvRegBitsOn(pDevice,MAC_REG_TFTCTL,TFTCTL_TSFCNTRST);
+
+    LODWORD(pDevice->qwCurrTSF) = 0;
+    HIDWORD(pDevice->qwCurrTSF) = 0;
+
+    return(TRUE);
+}
+
+/*
+ * Description: Read NIC TSF counter
+ *              Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ *  In:
+ *      qwTSF           - Current TSF counter
+ *      wbeaconInterval - Beacon Interval
+ *  Out:
+ *      qwCurrTSF       - Current TSF counter
+ *
+ * Return Value: TSF value of next Beacon
+ *
+ */
+QWORD CARDqGetNextTBTT (QWORD qwTSF, WORD wBeaconInterval)
+{
+
+    UINT    uLowNextTBTT;
+    UINT    uHighRemain, uLowRemain;
+    UINT    uBeaconInterval;
+
+    uBeaconInterval = wBeaconInterval * 1024;
+    // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
+    uLowNextTBTT = (LODWORD(qwTSF) >> 10) << 10;
+    uLowRemain = (uLowNextTBTT) % uBeaconInterval;
+    uHighRemain = ((0x80000000 % uBeaconInterval)* 2 * HIDWORD(qwTSF))
+                  % uBeaconInterval;
+    uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval;
+    uLowRemain = uBeaconInterval - uLowRemain;
+
+    // check if carry when add one beacon interval
+    if ((~uLowNextTBTT) < uLowRemain)
+        HIDWORD(qwTSF) ++ ;
+
+    LODWORD(qwTSF) = uLowNextTBTT + uLowRemain;
+
+    return (qwTSF);
+}
+
+
+/*
+ * Description: Set NIC TSF counter for first Beacon time
+ *              Get NEXTTBTT from adjusted TSF and Beacon Interval
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - IO Base
+ *      wBeaconInterval - Beacon Interval
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvSetFirstNextTBTT (PVOID pDeviceHandler, WORD wBeaconInterval)
+{
+
+    PSDevice        pDevice = (PSDevice) pDeviceHandler;
+    QWORD           qwNextTBTT;
+    DWORD           dwLoTBTT,dwHiTBTT;
+    BYTE            pbyData[8];
+
+    HIDWORD(qwNextTBTT) = 0;
+    LODWORD(qwNextTBTT) = 0;
+    CARDbClearCurrentTSF(pDevice);
+    //CARDbGetCurrentTSF(pDevice, &qwNextTBTT); //Get Local TSF counter
+    qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval);
+    // Set NextTBTT
+
+    dwLoTBTT = LODWORD(qwNextTBTT);
+    dwHiTBTT = HIDWORD(qwNextTBTT);
+
+    pbyData[0] = (BYTE)dwLoTBTT;
+    pbyData[1] = (BYTE)(dwLoTBTT>>8);
+    pbyData[2] = (BYTE)(dwLoTBTT>>16);
+    pbyData[3] = (BYTE)(dwLoTBTT>>24);
+    pbyData[4] = (BYTE)dwHiTBTT;
+    pbyData[5] = (BYTE)(dwHiTBTT>>8);
+    pbyData[6] = (BYTE)(dwHiTBTT>>16);
+    pbyData[7] = (BYTE)(dwHiTBTT>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SET_TSFTBTT,
+                        MESSAGE_REQUEST_TBTT,
+                        0,
+                        8,
+                        pbyData
+                        );
+
+    return;
+}
+
+
+/*
+ * Description: Sync NIC TSF counter for Beacon time
+ *              Get NEXTTBTT and write to HW
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be set
+ *      qwTSF           - Current TSF counter
+ *      wBeaconInterval - Beacon Interval
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void CARDvUpdateNextTBTT (PVOID pDeviceHandler, QWORD qwTSF, WORD wBeaconInterval)
+{
+    PSDevice        pDevice = (PSDevice) pDeviceHandler;
+    DWORD           dwLoTBTT,dwHiTBTT;
+    BYTE            pbyData[8];
+
+    qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval);
+
+    // Set NextTBTT
+    dwLoTBTT = LODWORD(qwTSF);
+    dwHiTBTT = HIDWORD(qwTSF);
+
+    pbyData[0] = (BYTE)dwLoTBTT;
+    pbyData[1] = (BYTE)(dwLoTBTT>>8);
+    pbyData[2] = (BYTE)(dwLoTBTT>>16);
+    pbyData[3] = (BYTE)(dwLoTBTT>>24);
+    pbyData[4] = (BYTE)dwHiTBTT;
+    pbyData[5] = (BYTE)(dwHiTBTT>>8);
+    pbyData[6] = (BYTE)(dwHiTBTT>>16);
+    pbyData[7] = (BYTE)(dwHiTBTT>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SET_TSFTBTT,
+                        MESSAGE_REQUEST_TBTT,
+                        0,
+                        8,
+                        pbyData
+                        );
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Card:Update Next TBTT[%8xh:%8xh] \n",(int)HIDWORD(qwTSF), (int)LODWORD(qwTSF));
+
+    return;
+}
+
+/*
+ * Description: Turn off Radio power
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be turned off
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbRadioPowerOff (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+BOOL bResult = TRUE;
+
+    //if (pDevice->bRadioOff == TRUE)
+    //    return TRUE;
+
+    pDevice->bRadioOff = TRUE;
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+        case RF_VT3226:     //RobertYu:20051111
+        case RF_VT3226D0:
+        case RF_VT3342A0:   //RobertYu:20060609
+            MACvRegBitsOff(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+            break;
+    }
+
+    MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+    BBvSetDeepSleep(pDevice);
+
+    return bResult;
+}
+
+
+/*
+ * Description: Turn on Radio power
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be turned on
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL CARDbRadioPowerOn (PVOID pDeviceHandler)
+{
+PSDevice    pDevice = (PSDevice) pDeviceHandler;
+BOOL bResult = TRUE;
+
+
+    if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
+        return FALSE;
+    }
+
+    //if (pDevice->bRadioOff == FALSE)
+    //    return TRUE;
+
+    pDevice->bRadioOff = FALSE;
+
+    BBvExitDeepSleep(pDevice);
+
+    MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_RXON);
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+        case RF_VT3226:     //RobertYu:20051111
+        case RF_VT3226D0:
+        case RF_VT3342A0:   //RobertYu:20060609
+            MACvRegBitsOn(pDevice, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE2 | SOFTPWRCTL_SWPE3));
+            break;
+    }
+
+    return bResult;
+}
+
+void CARDvSetBSSMode (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    // Set BB and packet type at the same time.//{{RobertYu:20050222, AL7230 have two TX PA output, only connet to b/g now
+    // so in 11a mode need to set the MAC Reg0x4C to 11b/g mode to turn on PA
+    if( (pDevice->byRFType == RF_AIROHA7230 ) && (pDevice->byBBType == BB_TYPE_11A) )
+    {
+        MACvSetBBType(pDevice, BB_TYPE_11G);
+    }
+    else
+    {
+        MACvSetBBType(pDevice, pDevice->byBBType);
+    }
+    pDevice->byPacketType = CARDbyGetPktType(pDevice);
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x03);
+    } else if (pDevice->byBBType == BB_TYPE_11B) {
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x02);
+    } else if (pDevice->byBBType == BB_TYPE_11G) {
+        ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0x88, 0x08);
+    }
+
+    vUpdateIFS(pDevice);
+    CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
+
+    if ( pDevice->byBBType == BB_TYPE_11A ) {
+        //request by Jack 2005-04-26
+        if (pDevice->byRFType == RF_AIROHA7230) {
+            pDevice->abyBBVGA[0] = 0x20;
+            ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
+        }
+        pDevice->abyBBVGA[2] = 0x10;
+        pDevice->abyBBVGA[3] = 0x10;
+    } else {
+        //request by Jack 2005-04-26
+        if (pDevice->byRFType == RF_AIROHA7230) {
+            pDevice->abyBBVGA[0] = 0x1C;
+            ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xE7, pDevice->abyBBVGA[0]);
+        }
+        pDevice->abyBBVGA[2] = 0x0;
+        pDevice->abyBBVGA[3] = 0x0;
+    }
+}
+
+/*
+ *
+ * Description:
+ *    Do Channel Switch defined in 802.11h
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+CARDbChannelSwitch (
+    IN PVOID            pDeviceHandler,
+    IN BYTE             byMode,
+    IN BYTE             byNewChannel,
+    IN BYTE             byCount
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BOOL        bResult = TRUE;
+
+    if (byCount == 0) {
+        pDevice->sMgmtObj.uCurrChannel = byNewChannel;
+        bResult = CARDbSetMediaChannel(pDevice, byNewChannel);
+
+        return(bResult);
+    }
+    pDevice->byChannelSwitchCount = byCount;
+    pDevice->byNewChannel = byNewChannel;
+    pDevice->bChannelSwitch = TRUE;
+
+    if (byMode == 1) {
+        //bResult=CARDbStopTxPacket(pDevice, PKT_TYPE_802_11_ALL);
+        pDevice->bStopDataPkt = TRUE;
+    }
+    return (bResult);
+}
+
+
+
+
+
+
diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h
new file mode 100644
index 0000000..aa90c2c
--- /dev/null
+++ b/drivers/staging/vt6656/card.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: card.h
+ *
+ * Purpose: Provide functions to setup NIC operation mode
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __CARD_H__
+#define __CARD_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+// Init card type
+
+typedef enum _CARD_PHY_TYPE {
+
+    PHY_TYPE_AUTO=0,
+    PHY_TYPE_11B,
+    PHY_TYPE_11G,
+    PHY_TYPE_11A
+} CARD_PHY_TYPE, *PCARD_PHY_TYPE;
+
+typedef enum _CARD_OP_MODE {
+
+    OP_MODE_INFRASTRUCTURE=0,
+    OP_MODE_ADHOC,
+    OP_MODE_AP,
+    OP_MODE_UNKNOWN
+} CARD_OP_MODE, *PCARD_OP_MODE;
+
+#define CB_MAX_CHANNEL_24G  14
+//#define CB_MAX_CHANNEL_5G   24
+#define CB_MAX_CHANNEL_5G       42 //[20050104] add channel9(5045MHz), 41==>42
+#define CB_MAX_CHANNEL      (CB_MAX_CHANNEL_24G+CB_MAX_CHANNEL_5G)
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+BOOL CARDbSetMediaChannel(PVOID pDeviceHandler, UINT uConnectionChannel);
+void CARDvSetRSPINF(PVOID pDeviceHandler, BYTE byBBType);
+void vUpdateIFS(PVOID pDeviceHandler);
+void CARDvUpdateBasicTopRate(PVOID pDeviceHandler);
+BOOL CARDbAddBasicRate(PVOID pDeviceHandler, WORD wRateIdx);
+BOOL CARDbIsOFDMinBasicRate(PVOID pDeviceHandler);
+void CARDvAdjustTSF(PVOID pDeviceHandler, BYTE byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF);
+BOOL CARDbGetCurrentTSF (PVOID pDeviceHandler, PQWORD pqwCurrTSF);
+BOOL CARDbClearCurrentTSF(PVOID pDeviceHandler);
+void CARDvSetFirstNextTBTT(PVOID pDeviceHandler, WORD wBeaconInterval);
+void CARDvUpdateNextTBTT(PVOID pDeviceHandler, QWORD qwTSF, WORD wBeaconInterval);
+QWORD CARDqGetNextTBTT(QWORD qwTSF, WORD wBeaconInterval);
+QWORD CARDqGetTSFOffset(BYTE byRxRate, QWORD qwTSF1, QWORD qwTSF2);
+BOOL CARDbRadioPowerOff(PVOID pDeviceHandler);
+BOOL CARDbRadioPowerOn(PVOID pDeviceHandler);
+BYTE CARDbyGetPktType(PVOID pDeviceHandler);
+void CARDvSetBSSMode(PVOID pDeviceHandler);
+
+BOOL
+CARDbChannelSwitch (
+    IN PVOID            pDeviceHandler,
+    IN BYTE             byMode,
+    IN BYTE             byNewChannel,
+    IN BYTE             byCount
+    );
+
+#endif // __CARD_H__
+
+
+
diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c
new file mode 100644
index 0000000..e49796f
--- /dev/null
+++ b/drivers/staging/vt6656/channel.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: channel.c
+ *
+ * Purpose: Channel number maping
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 24, 2004
+ *
+ *
+ *
+ * Revision History:
+ *      01-18-2005      RobertYu:  remove the for loop searching in ChannelValid,
+ *                                 change ChannelRuleTab to lookup-type, reorder table items.
+ *
+ *
+ */
+
+#include "country.h"
+#include "channel.h"
+#include "rf.h"
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+static SChannelTblElement sChannelTbl[CB_MAX_CHANNEL+1] =
+{
+  {0,   0,    FALSE},
+  {1,   2412, TRUE},
+  {2,   2417, TRUE},
+  {3,   2422, TRUE},
+  {4,   2427, TRUE},
+  {5,   2432, TRUE},
+  {6,   2437, TRUE},
+  {7,   2442, TRUE},
+  {8,   2447, TRUE},
+  {9,   2452, TRUE},
+  {10,  2457, TRUE},
+  {11,  2462, TRUE},
+  {12,  2467, TRUE},
+  {13,  2472, TRUE},
+  {14,  2484, TRUE},
+  {183, 4915, TRUE}, //15
+  {184, 4920, TRUE}, //16
+  {185, 4925, TRUE}, //17
+  {187, 4935, TRUE}, //18
+  {188, 4940, TRUE}, //19
+  {189, 4945, TRUE}, //20
+  {192, 4960, TRUE}, //21
+  {196, 4980, TRUE}, //22
+  {7,   5035, TRUE}, //23
+  {8,   5040, TRUE}, //24
+  {9,   5045, TRUE}, //25
+  {11,  5055, TRUE}, //26
+  {12,  5060, TRUE}, //27
+  {16,  5080, TRUE}, //28
+  {34,  5170, TRUE}, //29
+  {36,  5180, TRUE}, //30
+  {38,  5190, TRUE}, //31
+  {40,  5200, TRUE}, //32
+  {42,  5210, TRUE}, //33
+  {44,  5220, TRUE}, //34
+  {46,  5230, TRUE}, //35
+  {48,  5240, TRUE}, //36
+  {52,  5260, TRUE}, //37
+  {56,  5280, TRUE}, //38
+  {60,  5300, TRUE}, //39
+  {64,  5320, TRUE}, //40
+  {100, 5500, TRUE}, //41
+  {104, 5520, TRUE}, //42
+  {108, 5540, TRUE}, //43
+  {112, 5560, TRUE}, //44
+  {116, 5580, TRUE}, //45
+  {120, 5600, TRUE}, //46
+  {124, 5620, TRUE}, //47
+  {128, 5640, TRUE}, //48
+  {132, 5660, TRUE}, //49
+  {136, 5680, TRUE}, //50
+  {140, 5700, TRUE}, //51
+  {149, 5745, TRUE}, //52
+  {153, 5765, TRUE}, //53
+  {157, 5785, TRUE}, //54
+  {161, 5805, TRUE}, //55
+  {165, 5825, TRUE}  //56
+};
+
+
+
+/************************************************************************
+ * The Radar regulation rules for each country
+ ************************************************************************/
+static  struct
+{
+    BYTE    byChannelCountryCode;             /* The country code         */
+    CHAR    chCountryCode[2];
+    BYTE    bChannelIdxList[CB_MAX_CHANNEL];  /* Available channels Index */
+    BYTE    byPower[CB_MAX_CHANNEL];
+}   ChannelRuleTab[] =
+{
+/************************************************************************
+ * This table is based on Athero driver rules
+ ************************************************************************/
+/* Country          Available channels, ended with 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  */
+{CCODE_FCC,                     {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_TELEC,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  0,  0,  1,  0,  1,  1,  0,  1,  0,  0,  1,  1,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0, 23,  0,  0, 23,  0, 23, 23,  0, 23,  0,  0, 23, 23, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ETSI,                    {'E','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_RESV3,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV4,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV5,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV6,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV7,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV8,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESV9,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVa,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVb,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVc,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVd,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RESVe,                   {' ',' '},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALLBAND,                 {' ',' '},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALBANIA,                 {'A','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ALGERIA,                 {'D','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ARGENTINA,               {'A','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
+{CCODE_ARMENIA,                 {'A','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_AUSTRALIA,               {'A','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_AUSTRIA,                 {'A','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15,  0, 15,  0, 15,  0, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_AZERBAIJAN,              {'A','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BAHRAIN,                 {'B','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELARUS,                 {'B','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELGIUM,                 {'B','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BELIZE,                  {'B','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BOLIVIA,                 {'B','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BRAZIL,                  {'B','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_BRUNEI_DARUSSALAM,       {'B','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_BULGARIA,                {'B','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23,  0,  0, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0}  },
+{CCODE_CANADA,                  {'C','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_CHILE,                   {'C','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17, 17}  },
+{CCODE_CHINA,                   {'C','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_COLOMBIA,                {'C','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_COSTA_RICA,              {'C','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_CROATIA,                 {'H','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_CYPRUS,                  {'C','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_CZECH,                   {'C','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_DENMARK,                 {'D','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_DOMINICAN_REPUBLIC,      {'D','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_ECUADOR,                 {'E','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_EGYPT,                   {'E','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_EL_SALVADOR,             {'S','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ESTONIA,                 {'E','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_FINLAND,                 {'F','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_FRANCE,                  {'F','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GERMANY,                 {'D','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_GREECE,                  {'G','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GEORGIA,                 {'G','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_GUATEMALA,               {'G','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_HONDURAS,                {'H','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_HONG_KONG,               {'H','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_HUNGARY,                 {'H','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ICELAND,                 {'I','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_INDIA,                   {'I','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_INDONESIA,               {'I','D'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_IRAN,                    {'I','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_IRELAND,                 {'I','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_ITALY,                   {'I','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_ISRAEL,                  {'I','L'},  {   0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JAPAN,                   {'J','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JORDAN,                  {'J','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_KAZAKHSTAN,              {'K','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_KUWAIT,                  {'K','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LATVIA,                  {'L','V'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LEBANON,                 {'L','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LEICHTENSTEIN,           {'L','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_LITHUANIA,               {'L','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_LUXEMBURG,               {'L','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_MACAU,                   {'M','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_MACEDONIA,               {'M','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MALTA,                   {'M','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_MALAYSIA,                {'M','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MEXICO,                  {'M','X'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_MONACO,                  {'M','C'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MOROCCO,                 {'M','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_NETHERLANDS,             {'N','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_NEW_ZEALAND,             {'N','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0, 23,  0, 23,  0, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_NORTH_KOREA,             {'K','P'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_NORWAY,                  {'N','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_OMAN,                    {'O','M'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PAKISTAN,                {'P','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PANAMA,                  {'P','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_PERU,                    {'P','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_PHILIPPINES,             {'P','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_POLAND,                  {'P','L'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_PORTUGAL,                {'P','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_PUERTO_RICO,             {'P','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_QATAR,                   {'Q','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ROMANIA,                 {'R','O'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_RUSSIA,                  {'R','U'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SAUDI_ARABIA,            {'S','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SINGAPORE,               {'S','G'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 20, 20, 20, 20}  },
+{CCODE_SLOVAKIA,                {'S','K'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_SLOVENIA,                {'S','I'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SOUTH_AFRICA,            {'Z','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SOUTH_KOREA,             {'K','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_SPAIN,                   {'E','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, 16,  0, 16,  0, 16, 16, 16, 16, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16, 16, 16, 16,  0}  },
+{CCODE_SWEDEN,                  {'S','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_SWITZERLAND,             {'C','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_SYRIA,                   {'S','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TAIWAN,                  {'T','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30,  0}  },
+{CCODE_THAILAND,                {'T','H'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_TRINIDAD_TOBAGO,         {'T','T'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 18,  0, 18,  0, 18, 18, 18, 18, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TUNISIA,                 {'T','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_TURKEY,                  {'T','R'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UK,                      {'G','B'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,  0, 20,  0, 20,  0, 20, 20, 20, 20, 20, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0}  },
+{CCODE_UKRAINE,                 {'U','A'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UNITED_ARAB_EMIRATES,    {'A','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_UNITED_STATES,           {'U','S'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1}
+                                      ,  {  27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17,  0, 17,  0, 17,  0, 17, 23, 23, 23, 23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 30, 30, 30, 30, 30}  },
+{CCODE_URUGUAY,                 {'U','Y'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_UZBEKISTAN,              {'U','Z'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_VENEZUELA,               {'V','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0}
+                                      ,  {  20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23, 23, 23, 23,  0}  },
+{CCODE_VIETNAM,                 {'V','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_YEMEN,                   {'Y','E'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_ZIMBABWE,                {'Z','W'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_JAPAN_W52_W53,           {'J','J'},  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  1,  0,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  },
+{CCODE_MAX,                     {'U','N'},  {   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1}
+                                      ,  {   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}  }
+/*                                           1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  */
+};
+
+#define NUM_RULES	(sizeof(ChannelRuleTab) / sizeof(ChannelRuleTab[0]))
+
+/*---------------------  Export function  -------------------------*/
+/************************************************************************
+ * Country Channel Valid
+ *  Input:  CountryCode, ChannelNum
+ *          ChanneIndex is defined as VT3253 MAC channel:
+ *              1   = 2.4G channel 1
+ *              2   = 2.4G channel 2
+ *              ...
+ *              14  = 2.4G channel 14
+ *              15  = 4.9G channel 183
+ *              16  = 4.9G channel 184
+ *              .....
+ *  Output: TRUE if the specified 5GHz band is allowed to be used.
+            False otherwise.
+// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196 (Value:15 ~ 22)
+
+// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165 (Value 23 ~ 56)
+ ************************************************************************/
+BOOL
+ChannelValid(UINT CountryCode, UINT ChannelIndex)
+{
+    BOOL    bValid;
+
+    bValid = FALSE;
+    /*
+     * If Channel Index is invalid, return invalid
+     */
+    if ((ChannelIndex > CB_MAX_CHANNEL) ||
+        (ChannelIndex == 0))
+    {
+        bValid = FALSE;
+        goto exit;
+    }
+
+    bValid = sChannelTbl[ChannelIndex].bValid;
+
+exit:
+    return (bValid);
+
+} /* end ChannelValid */
+
+/************************************************************************
+ * CHvChannelGetList
+ * Get Available Channel List for a given country
+ * Input:
+ *      CountryCode     =   The country code defined in country.h
+ * Output:
+ *      ChannelBitMask  =   (QWORD *) correspondent bit mask
+ *                          of available channels
+ *                          0x0000000000000001 means channel 1 is supported
+ *                          0x0000000000000003 means channel 1,2 are supported
+ *                          0x000000000000000F means channel 1,2,..15 are supported
+ ************************************************************************/
+BOOL
+CHvChannelGetList (
+    IN  UINT       uCountryCodeIdx,
+    OUT PBYTE      pbyChannelTable
+    )
+{
+    if (uCountryCodeIdx >= CCODE_MAX) {
+        return (FALSE);
+    }
+    memcpy(pbyChannelTable, ChannelRuleTab[uCountryCodeIdx].bChannelIdxList, CB_MAX_CHANNEL);
+    return (TRUE);
+}
+
+
+VOID CHvInitChannelTable (PVOID pDeviceHandler)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    BOOL        bMultiBand = FALSE;
+    UINT        ii;
+
+    for(ii=1;ii<=CB_MAX_CHANNEL;ii++) {
+        sChannelTbl[ii].bValid = FALSE;
+    }
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_VT3226:
+        case RF_VT3226D0:
+            bMultiBand = FALSE;
+            break;
+        case RF_AIROHA7230:
+        case RF_VT3342A0:
+        default :
+            bMultiBand = TRUE;
+            break;
+    }
+
+    if ((pDevice->dwDiagRefCount != 0) ||
+        (pDevice->b11hEable == TRUE)) {
+        if (bMultiBand == TRUE) {
+            for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
+                sChannelTbl[ii+1].bValid = TRUE;
+                //pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+                //pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+            }
+            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+                //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+            }
+        } else {
+            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+                sChannelTbl[ii+1].bValid = TRUE;
+                //pDevice->abyRegPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+                //pDevice->abyLocalPwr[ii+1] = pDevice->abyCCKDefaultPwr[ii+1];
+            }
+        }
+    } else if (pDevice->byZoneType <= CCODE_MAX) {
+        if (bMultiBand == TRUE) {
+            for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
+                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                    sChannelTbl[ii+1].bValid = TRUE;
+                    //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                    //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                }
+            }
+        } else {
+            for(ii=0;ii<CB_MAX_CHANNEL_24G;ii++) {
+                if (ChannelRuleTab[pDevice->byZoneType].bChannelIdxList[ii] != 0) {
+                    sChannelTbl[ii+1].bValid = TRUE;
+                    //pDevice->abyRegPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                    //pDevice->abyLocalPwr[ii+1] = ChannelRuleTab[pDevice->byZoneType].byPower[ii];
+                }
+            }
+        }
+    }
+    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO"Zone=[%d][%c][%c]!!\n",pDevice->byZoneType,ChannelRuleTab[pDevice->byZoneType].chCountryCode[0],ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]);
+    for(ii=0;ii<CB_MAX_CHANNEL;ii++) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Channel[%d] is [%d]\n",sChannelTbl[ii].byChannelNumber,sChannelTbl[ii+1].bValid);
+        /*if (pDevice->abyRegPwr[ii+1] == 0) {
+            pDevice->abyRegPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+        }
+        if (pDevice->abyLocalPwr[ii+1] == 0) {
+            pDevice->abyLocalPwr[ii+1] = pDevice->abyOFDMDefaultPwr[ii+1];
+        }*/
+    }
+}
+
+BYTE CHbyGetChannelMapping(BYTE byChannelNumber)
+{
+BYTE    ii;
+BYTE    byCHMapping = 0;
+
+    for (ii=1; ii<=CB_MAX_CHANNEL; ii++ ) {
+        if ( sChannelTbl[ii].byChannelNumber == byChannelNumber ) {
+            byCHMapping = ii;
+        }
+    }
+    return byCHMapping;
+}
diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h
new file mode 100644
index 0000000..2306b20
--- /dev/null
+++ b/drivers/staging/vt6656/channel.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: channel.h
+ *
+ * Purpose: Country Regulation Rules header file
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 23, 2004
+ *
+ */
+
+#ifndef _CHANNEL_H_
+#define _CHANNEL_H_
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+typedef struct tagSChannelTblElement {
+    BYTE    byChannelNumber;
+    UINT    uFrequency;
+    BOOL    bValid;
+}SChannelTblElement, *PSChannelTblElement;
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+BOOL    ChannelValid(UINT CountryCode, UINT ChannelNum);
+VOID    CHvInitChannelTable (PVOID pDeviceHandler);
+BYTE    CHbyGetChannelMapping(BYTE byChannelNumber);
+
+BOOL
+CHvChannelGetList (
+    IN  UINT       uCountryCodeIdx,
+    OUT PBYTE      pbyChannelTable
+    );
+
+#endif  /* _REGULATE_H_ */
diff --git a/drivers/staging/vt6656/control.c b/drivers/staging/vt6656/control.c
new file mode 100644
index 0000000..7dba771
--- /dev/null
+++ b/drivers/staging/vt6656/control.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: control.c
+ *
+ * Purpose: Handle USB control endpoint
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 5, 2004
+ *
+ * Functions:
+ *      CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM
+ *      CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM
+ *      ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM
+ *      ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM
+ *      ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
+ *
+ * Revision History:
+ *      04-05-2004 Jerry Chen:  Initial release
+ *      11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
+ *
+ */
+
+#include "control.h"
+#include "rndis.h"
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+void ControlvWriteByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, BYTE byData)
+{
+BYTE            byData1;
+
+    byData1 = byData;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        byRegOfs,
+                        byRegType,
+                        1,
+                        &byData1
+                        );
+
+}
+
+
+void ControlvReadByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, PBYTE pbyData)
+{
+NTSTATUS        ntStatus;
+BYTE            byData1;
+
+
+    ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    byRegOfs,
+                                    byRegType,
+                                    1,
+                                    &byData1);
+
+    *pbyData = byData1;
+
+}
+
+
+
+void ControlvMaskByte(PSDevice pDevice, BYTE byRegType, BYTE byRegOfs, BYTE byMask, BYTE byData)
+{
+BYTE            pbyData[2];
+
+    pbyData[0] = byData;
+    pbyData[1] = byMask;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        byRegOfs,
+                        byRegType,
+                        2,
+                        pbyData
+                        );
+
+}
diff --git a/drivers/staging/vt6656/control.h b/drivers/staging/vt6656/control.h
new file mode 100644
index 0000000..4d9a777
--- /dev/null
+++ b/drivers/staging/vt6656/control.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: control.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 5, 2004
+ *
+ */
+
+#ifndef __CONTROL_H__
+#define __CONTROL_H__
+
+#include "ttype.h"
+#include "device.h"
+#include "usbpipe.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+#define CONTROLnsRequestOut( Device,Request,Value,Index,Length,Buffer) \
+        PIPEnsControlOut( Device,Request,Value,Index,Length,Buffer)
+
+#define CONTROLnsRequestOutAsyn( Device,Request,Value,Index,Length,Buffer) \
+        PIPEnsControlOutAsyn( Device,Request,Value,Index,Length,Buffer)
+
+#define CONTROLnsRequestIn( Device,Request,Value,Index,Length,Buffer) \
+        PIPEnsControlIn( Device,Request,Value,Index,Length,Buffer)
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+void ControlvWriteByte(
+    IN PSDevice pDevice,
+    IN BYTE byRegType,
+    IN BYTE byRegOfs,
+    IN BYTE byData
+    );
+
+
+void ControlvReadByte(
+    IN PSDevice pDevice,
+    IN BYTE byRegType,
+    IN BYTE byRegOfs,
+    IN PBYTE pbyData
+    );
+
+
+void ControlvMaskByte(
+    IN PSDevice pDevice,
+    IN BYTE byRegType,
+    IN BYTE byRegOfs,
+    IN BYTE byMask,
+    IN BYTE byData
+    );
+
+#endif // __RCV_H__
+
+
+
diff --git a/drivers/staging/vt6656/country.h b/drivers/staging/vt6656/country.h
new file mode 100644
index 0000000..7bdc8d4
--- /dev/null
+++ b/drivers/staging/vt6656/country.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: country.h
+ *
+ * Purpose: Country Code information
+ *
+ * Author: Lucas Lin
+ *
+ * Date: Dec 23, 2004
+ *
+ */
+
+#ifndef __COUNTRY_H__
+#define __COUNTRY_H__
+
+/************************************************************************
+ * The definition here should be complied with the INF country order
+ * Please check with VNWL.inf/VNWL64.inf/VNWL*.inf
+ ************************************************************************/
+typedef enum _COUNTRY_CODE {
+    CCODE_FCC = 0,
+    CCODE_TELEC,
+    CCODE_ETSI,
+    CCODE_RESV3,
+    CCODE_RESV4,
+    CCODE_RESV5,
+    CCODE_RESV6,
+    CCODE_RESV7,
+    CCODE_RESV8,
+    CCODE_RESV9,
+    CCODE_RESVa,
+    CCODE_RESVb,
+    CCODE_RESVc,
+    CCODE_RESVd,
+    CCODE_RESVe,
+    CCODE_ALLBAND,
+    CCODE_ALBANIA,
+    CCODE_ALGERIA,
+    CCODE_ARGENTINA,
+    CCODE_ARMENIA,
+    CCODE_AUSTRALIA,
+    CCODE_AUSTRIA,
+    CCODE_AZERBAIJAN,
+    CCODE_BAHRAIN,
+    CCODE_BELARUS,
+    CCODE_BELGIUM,
+    CCODE_BELIZE,
+    CCODE_BOLIVIA,
+    CCODE_BRAZIL,
+    CCODE_BRUNEI_DARUSSALAM,
+    CCODE_BULGARIA,
+    CCODE_CANADA,
+    CCODE_CHILE,
+    CCODE_CHINA,
+    CCODE_COLOMBIA,
+    CCODE_COSTA_RICA,
+    CCODE_CROATIA,
+    CCODE_CYPRUS,
+    CCODE_CZECH,
+    CCODE_DENMARK,
+    CCODE_DOMINICAN_REPUBLIC,
+    CCODE_ECUADOR,
+    CCODE_EGYPT,
+    CCODE_EL_SALVADOR,
+    CCODE_ESTONIA,
+    CCODE_FINLAND,
+    CCODE_FRANCE,
+    CCODE_GERMANY,
+    CCODE_GREECE,
+    CCODE_GEORGIA,
+    CCODE_GUATEMALA,
+    CCODE_HONDURAS,
+    CCODE_HONG_KONG,
+    CCODE_HUNGARY,
+    CCODE_ICELAND,
+    CCODE_INDIA,
+    CCODE_INDONESIA,
+    CCODE_IRAN,
+    CCODE_IRELAND,
+    CCODE_ITALY,
+    CCODE_ISRAEL,
+    CCODE_JAPAN,
+    CCODE_JORDAN,
+    CCODE_KAZAKHSTAN,
+    CCODE_KUWAIT,
+    CCODE_LATVIA,
+    CCODE_LEBANON,
+    CCODE_LEICHTENSTEIN,
+    CCODE_LITHUANIA,
+    CCODE_LUXEMBURG,
+    CCODE_MACAU,
+    CCODE_MACEDONIA,
+    CCODE_MALTA,
+    CCODE_MALAYSIA,
+    CCODE_MEXICO,
+    CCODE_MONACO,
+    CCODE_MOROCCO,
+    CCODE_NETHERLANDS,
+    CCODE_NEW_ZEALAND,
+    CCODE_NORTH_KOREA,
+    CCODE_NORWAY,
+    CCODE_OMAN,
+    CCODE_PAKISTAN,
+    CCODE_PANAMA,
+    CCODE_PERU,
+    CCODE_PHILIPPINES,
+    CCODE_POLAND,
+    CCODE_PORTUGAL,
+    CCODE_PUERTO_RICO,
+    CCODE_QATAR,
+    CCODE_ROMANIA,
+    CCODE_RUSSIA,
+    CCODE_SAUDI_ARABIA,
+    CCODE_SINGAPORE,
+    CCODE_SLOVAKIA,
+    CCODE_SLOVENIA,
+    CCODE_SOUTH_AFRICA,
+    CCODE_SOUTH_KOREA,
+    CCODE_SPAIN,
+    CCODE_SWEDEN,
+    CCODE_SWITZERLAND,
+    CCODE_SYRIA,
+    CCODE_TAIWAN,
+    CCODE_THAILAND,
+    CCODE_TRINIDAD_TOBAGO,
+    CCODE_TUNISIA,
+    CCODE_TURKEY,
+    CCODE_UK,
+    CCODE_UKRAINE,
+    CCODE_UNITED_ARAB_EMIRATES,
+    CCODE_UNITED_STATES,
+    CCODE_URUGUAY,
+    CCODE_UZBEKISTAN,
+    CCODE_VENEZUELA,
+    CCODE_VIETNAM,
+    CCODE_YEMEN,
+    CCODE_ZIMBABWE,
+    CCODE_JAPAN_W52_W53,
+    CCODE_MAX
+} COUNTRY_CODE;
+
+
+/************************************************************************
+ * Function prototype
+ ************************************************************************/
+#endif  /* __COUNTRY_H__ */
diff --git a/drivers/staging/vt6656/datarate.c b/drivers/staging/vt6656/datarate.c
new file mode 100644
index 0000000..968feb4
--- /dev/null
+++ b/drivers/staging/vt6656/datarate.c
@@ -0,0 +1,499 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: datarate.c
+ *
+ * Purpose: Handles the auto fallback & data rates functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ * Functions:
+ *      RATEvParseMaxRate - Parsing the highest basic & support rate in rate field of frame
+ *      RATEvTxRateFallBack - Rate fallback Algorithm Implementaion
+ *      RATEuSetIE- Set rate IE field.
+ *
+ * Revision History:
+ *
+ */
+
+#include "ttype.h"
+#include "tmacro.h"
+#include "mac.h"
+#include "80211mgr.h"
+#include "bssdb.h"
+#include "datarate.h"
+#include "card.h"
+#include "baseband.h"
+#include "srom.h"
+#include "rf.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+const BYTE acbyIERate[MAX_RATE] =
+{0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+
+#define AUTORATE_TXOK_CNT       0x0400
+#define AUTORATE_TXFAIL_CNT     0x0064
+#define AUTORATE_TIMEOUT        10
+
+/*---------------------  Static Functions  --------------------------*/
+
+VOID s_vResetCounter (
+    IN PKnownNodeDB psNodeDBTable
+    );
+
+
+
+VOID
+s_vResetCounter (
+    IN PKnownNodeDB psNodeDBTable
+    )
+{
+    BYTE            ii;
+
+    // clear statistic counter for auto_rate
+    for(ii=0;ii<=MAX_RATE;ii++) {
+        psNodeDBTable->uTxOk[ii] = 0;
+        psNodeDBTable->uTxFail[ii] = 0;
+    }
+}
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ * Description:
+ *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
+ *
+ * Parameters:
+ *  In:
+ *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
+ *  Out:
+ *      none
+ *
+ * Return Value: RateIdx
+ *
+-*/
+BYTE
+DATARATEbyGetRateIdx (
+    IN BYTE byRate
+    )
+{
+    BYTE    ii;
+
+    //Erase basicRate flag.
+    byRate = byRate & 0x7F;//0111 1111
+
+    for (ii = 0; ii < MAX_RATE; ii ++) {
+        if (acbyIERate[ii] == byRate)
+            return ii;
+    }
+    return 0;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *      Rate fallback Algorithm Implementaion
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      psNodeDBTable   - Pointer to Node Data Base
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+#define AUTORATE_TXCNT_THRESHOLD        20
+#define AUTORATE_INC_THRESHOLD          30
+
+
+
+
+/*+
+ *
+ * Description:
+ *      Get RateIdx from the value in SuppRates IE or ExtSuppRates IE
+ *
+ * Parameters:
+ *  In:
+ *      BYTE    - Rate value in SuppRates IE or ExtSuppRates IE
+ *  Out:
+ *      none
+ *
+ * Return Value: RateIdx
+ *
+-*/
+WORD
+RATEwGetRateIdx(
+    IN BYTE byRate
+    )
+{
+    WORD    ii;
+
+    //Erase basicRate flag.
+    byRate = byRate & 0x7F;//0111 1111
+
+    for (ii = 0; ii < MAX_RATE; ii ++) {
+        if (acbyIERate[ii] == byRate)
+            return ii;
+    }
+    return 0;
+}
+
+/*+
+ *
+ * Description:
+ *      Parsing the highest basic & support rate in rate field of frame.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      pItemRates      - Pointer to Rate field defined in 802.11 spec.
+ *      pItemExtRates      - Pointer to Extended Rate field defined in 802.11 spec.
+ *  Out:
+ *      pwMaxBasicRate  - Maximum Basic Rate
+ *      pwMaxSuppRate   - Maximum Supported Rate
+ *      pbyTopCCKRate   - Maximum Basic Rate in CCK mode
+ *      pbyTopOFDMRate  - Maximum Basic Rate in OFDM mode
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+RATEvParseMaxRate (
+    IN PVOID pDeviceHandler,
+    IN PWLAN_IE_SUPP_RATES pItemRates,
+    IN PWLAN_IE_SUPP_RATES pItemExtRates,
+    IN BOOL bUpdateBasicRate,
+    OUT PWORD pwMaxBasicRate,
+    OUT PWORD pwMaxSuppRate,
+    OUT PWORD pwSuppRate,
+    OUT PBYTE pbyTopCCKRate,
+    OUT PBYTE pbyTopOFDMRate
+    )
+{
+PSDevice  pDevice = (PSDevice) pDeviceHandler;
+UINT  ii;
+BYTE  byHighSuppRate = 0;
+BYTE  byRate = 0;
+WORD  wOldBasicRate = pDevice->wBasicRate;
+UINT  uRateLen;
+
+
+    if (pItemRates == NULL)
+        return;
+
+    *pwSuppRate = 0;
+    uRateLen = pItemRates->len;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate Len: %d\n", uRateLen);
+    if (pDevice->byBBType != BB_TYPE_11B) {
+        if (uRateLen > WLAN_RATES_MAXLEN)
+            uRateLen = WLAN_RATES_MAXLEN;
+    } else {
+        if (uRateLen > WLAN_RATES_MAXLEN_11B)
+            uRateLen = WLAN_RATES_MAXLEN_11B;
+    }
+
+    for (ii = 0; ii < uRateLen; ii++) {
+    	byRate = (BYTE)(pItemRates->abyRates[ii]);
+        if (WLAN_MGMT_IS_BASICRATE(byRate) &&
+            (bUpdateBasicRate == TRUE))  {
+            // Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
+            CARDbAddBasicRate((PVOID)pDevice, RATEwGetRateIdx(byRate));
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
+        }
+        byRate = (BYTE)(pItemRates->abyRates[ii]&0x7F);
+        if (byHighSuppRate == 0)
+            byHighSuppRate = byRate;
+        if (byRate > byHighSuppRate)
+            byHighSuppRate = byRate;
+        *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+    }
+    if ((pItemExtRates != NULL) && (pItemExtRates->byElementID == WLAN_EID_EXTSUPP_RATES) &&
+        (pDevice->byBBType != BB_TYPE_11B)) {
+
+        UINT  uExtRateLen = pItemExtRates->len;
+
+        if (uExtRateLen > WLAN_RATES_MAXLEN)
+            uExtRateLen = WLAN_RATES_MAXLEN;
+
+        for (ii = 0; ii < uExtRateLen ; ii++) {
+            byRate = (BYTE)(pItemExtRates->abyRates[ii]);
+            // select highest basic rate
+            if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) {
+            	// Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate
+                CARDbAddBasicRate((PVOID)pDevice, RATEwGetRateIdx(byRate));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ParseMaxRate AddBasicRate: %d\n", RATEwGetRateIdx(byRate));
+            }
+            byRate = (BYTE)(pItemExtRates->abyRates[ii]&0x7F);
+            if (byHighSuppRate == 0)
+                byHighSuppRate = byRate;
+            if (byRate > byHighSuppRate)
+                byHighSuppRate = byRate;
+            *pwSuppRate |= (1<<RATEwGetRateIdx(byRate));
+            //DBG_PRN_GRP09(("ParseMaxRate : HighSuppRate: %d, %X\n", RATEwGetRateIdx(byRate), byRate));
+        }
+    } //if(pItemExtRates != NULL)
+
+    if ((pDevice->byPacketType == PK_TYPE_11GB) && CARDbIsOFDMinBasicRate((PVOID)pDevice)) {
+        pDevice->byPacketType = PK_TYPE_11GA;
+    }
+
+    *pbyTopCCKRate = pDevice->byTopCCKBasicRate;
+    *pbyTopOFDMRate = pDevice->byTopOFDMBasicRate;
+    *pwMaxSuppRate = RATEwGetRateIdx(byHighSuppRate);
+    if ((pDevice->byPacketType==PK_TYPE_11B) || (pDevice->byPacketType==PK_TYPE_11GB))
+       *pwMaxBasicRate = pDevice->byTopCCKBasicRate;
+    else
+       *pwMaxBasicRate = pDevice->byTopOFDMBasicRate;
+    if (wOldBasicRate != pDevice->wBasicRate)
+        CARDvSetRSPINF((PVOID)pDevice, pDevice->byBBType);
+
+     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Exit ParseMaxRate\n");
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *      Rate fallback Algorithm Implementaion
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      psNodeDBTable   - Pointer to Node Data Base
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+#define AUTORATE_TXCNT_THRESHOLD        20
+#define AUTORATE_INC_THRESHOLD          30
+
+VOID
+RATEvTxRateFallBack (
+    IN PVOID pDeviceHandler,
+    IN PKnownNodeDB psNodeDBTable
+    )
+{
+PSDevice        pDevice = (PSDevice) pDeviceHandler;
+PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+#if 1  //mike fixed old: use packet lose ratio algorithm to control rate
+WORD            wIdxDownRate = 0;
+UINT            ii;
+BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
+DWORD           dwThroughputTbl[MAX_RATE] = {10, 20, 55, 110, 60, 90, 120, 180, 240, 360, 480, 540};
+DWORD           dwThroughput = 0;
+WORD            wIdxUpRate = 0;
+DWORD           dwTxDiff = 0;
+
+    if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+        // Don't do Fallback when scanning Channel
+        return;
+    }
+    psNodeDBTable->uTimeCount ++;
+
+    if (psNodeDBTable->uTxFail[MAX_RATE] > psNodeDBTable->uTxOk[MAX_RATE])
+        dwTxDiff = psNodeDBTable->uTxFail[MAX_RATE] - psNodeDBTable->uTxOk[MAX_RATE];
+
+    if ((psNodeDBTable->uTxOk[MAX_RATE] < AUTORATE_TXOK_CNT) &&
+        (dwTxDiff < AUTORATE_TXFAIL_CNT) &&
+        (psNodeDBTable->uTimeCount < AUTORATE_TIMEOUT)) {
+        return;
+    }
+
+    if (psNodeDBTable->uTimeCount >= AUTORATE_TIMEOUT) {
+        psNodeDBTable->uTimeCount = 0;
+    }
+
+    for(ii=0;ii<MAX_RATE;ii++) {
+        if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
+            if (bAutoRate[ii] == TRUE) {
+                wIdxUpRate = (WORD) ii;
+            }
+        } else {
+            bAutoRate[ii] = FALSE;
+        }
+    }
+
+    for(ii=0;ii<=psNodeDBTable->wTxDataRate;ii++) {
+        if ( (psNodeDBTable->uTxOk[ii] != 0) ||
+             (psNodeDBTable->uTxFail[ii] != 0) ) {
+            dwThroughputTbl[ii] *= psNodeDBTable->uTxOk[ii];
+            if (ii < RATE_11M) {
+                psNodeDBTable->uTxFail[ii] *= 4;
+            }
+            dwThroughputTbl[ii] /= (psNodeDBTable->uTxOk[ii] + psNodeDBTable->uTxFail[ii]);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate %d,Ok: %d, Fail:%d, Throughput:%d\n",
+                       ii, (int)psNodeDBTable->uTxOk[ii], (int)psNodeDBTable->uTxFail[ii], (int)dwThroughputTbl[ii]);
+    }
+    dwThroughput = dwThroughputTbl[psNodeDBTable->wTxDataRate];
+
+    wIdxDownRate = psNodeDBTable->wTxDataRate;
+    for(ii = psNodeDBTable->wTxDataRate; ii > 0;) {
+        ii--;
+        if ( (dwThroughputTbl[ii] > dwThroughput) &&
+             (bAutoRate[ii]==TRUE) ) {
+            dwThroughput = dwThroughputTbl[ii];
+            wIdxDownRate = (WORD) ii;
+        }
+    }
+    psNodeDBTable->wTxDataRate = wIdxDownRate;
+    if (psNodeDBTable->uTxOk[MAX_RATE]) {
+        if (psNodeDBTable->uTxOk[MAX_RATE] >
+           (psNodeDBTable->uTxFail[MAX_RATE] * 4) ) {
+            psNodeDBTable->wTxDataRate = wIdxUpRate;
+        }
+    }else { // adhoc, if uTxOk(total) =0 & uTxFail(total) = 0
+        if (psNodeDBTable->uTxFail[MAX_RATE] == 0)
+            psNodeDBTable->wTxDataRate = wIdxUpRate;
+    }
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        if (psNodeDBTable->wTxDataRate <= RATE_11M)
+            psNodeDBTable->wTxDataRate = RATE_6M;
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uTxOk[MAX_RATE] %d, uTxFail[MAX_RATE]:%d\n",(int)psNodeDBTable->uTxOk[MAX_RATE], (int)psNodeDBTable->uTxFail[MAX_RATE]);
+    s_vResetCounter(psNodeDBTable);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rate: %d, U:%d, D:%d\n", (int)psNodeDBTable->wTxDataRate, (int)wIdxUpRate, (int)wIdxDownRate);
+    return;
+#else  //mike fixed new: use differ-signal strength to control rate
+WORD            wIdxUpRate = 0;
+BOOL            bAutoRate[MAX_RATE]    = {TRUE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE};
+UINT            ii;
+long  ldBm;
+
+    if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+        // Don't do Fallback when scanning Channel
+        return;
+    }
+
+    for(ii=0;ii<MAX_RATE;ii++) {
+        if (psNodeDBTable->wSuppRate & (0x0001<<ii)) {
+            if (bAutoRate[ii] == TRUE) {
+                wIdxUpRate = (WORD) ii;
+            }
+        } else {
+            bAutoRate[ii] = FALSE;
+        }
+    }
+
+         RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+
+	if (ldBm > -55) {
+		if ( psNodeDBTable->wSuppRate & (0x0001<<RATE_54M) )  //11a/g
+      		{
+	  		psNodeDBTable->wTxDataRate = RATE_54M;
+		}
+		else{ //11b
+	  		psNodeDBTable->wTxDataRate = RATE_11M;
+		}
+	}
+
+if (wIdxUpRate == RATE_54M ) {     //11a/g
+		if (ldBm > -56 )
+			psNodeDBTable->wTxDataRate = RATE_54M;
+		else if (ldBm > -61 )
+			psNodeDBTable->wTxDataRate = RATE_48M;
+		else if (ldBm > -66 )
+			psNodeDBTable->wTxDataRate = RATE_36M;
+		else if (ldBm > -72 )
+			psNodeDBTable->wTxDataRate = RATE_24M;
+		else if (ldBm > -80 )
+			psNodeDBTable->wTxDataRate = RATE_5M;
+		else {
+			psNodeDBTable->wTxDataRate = RATE_1M;
+			//increasingVGA = TRUE;
+		}
+	}
+	else {  //11b
+		if (ldBm > -65 )
+			psNodeDBTable->wTxDataRate = RATE_11M;
+		else if (ldBm > -75 )
+			psNodeDBTable->wTxDataRate = RATE_5M;
+		else
+			psNodeDBTable->wTxDataRate = RATE_1M;
+	}
+
+   return;
+#endif
+}
+
+/*+
+ *
+ * Description:
+ *    This routine is used to assemble available Rate IE.
+ *
+ * Parameters:
+ *  In:
+ *    pDevice
+ *  Out:
+ *
+ * Return Value: None
+ *
+-*/
+BYTE
+RATEuSetIE (
+    IN PWLAN_IE_SUPP_RATES pSrcRates,
+    IN PWLAN_IE_SUPP_RATES pDstRates,
+    IN UINT                uRateLen
+    )
+{
+    UINT ii, uu, uRateCnt = 0;
+
+    if ((pSrcRates == NULL) || (pDstRates == NULL))
+        return 0;
+
+    if (pSrcRates->len == 0)
+        return 0;
+
+    for (ii = 0; ii < uRateLen; ii++) {
+        for (uu = 0; uu < pSrcRates->len; uu++) {
+            if ((pSrcRates->abyRates[uu] & 0x7F) == acbyIERate[ii]) {
+                pDstRates->abyRates[uRateCnt ++] = pSrcRates->abyRates[uu];
+                break;
+            }
+        }
+    }
+    return (BYTE)uRateCnt;
+}
+
diff --git a/drivers/staging/vt6656/datarate.h b/drivers/staging/vt6656/datarate.h
new file mode 100644
index 0000000..68f206e
--- /dev/null
+++ b/drivers/staging/vt6656/datarate.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: datarate.h
+ *
+ * Purpose: Handles the auto fallback & data rates functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 16, 2002
+ *
+ */
+#ifndef __DATARATE_H__
+#define __DATARATE_H__
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define FALLBACK_PKT_COLLECT_TR_H  50   // pkts
+#define FALLBACK_PKT_COLLECT_TR_L  10   // pkts
+#define FALLBACK_POLL_SECOND       5    // 5 sec
+#define FALLBACK_RECOVER_SECOND    30   // 30 sec
+#define FALLBACK_THRESHOLD         15   // percent
+#define UPGRADE_THRESHOLD          5    // percent
+#define UPGRADE_CNT_THRD           3    // times
+#define RETRY_TIMES_THRD_H         2    // times
+#define RETRY_TIMES_THRD_L         1    // times
+
+
+#define RATE_1M         0
+#define RATE_2M         1
+#define RATE_5M         2
+#define RATE_11M        3
+#define RATE_6M         4
+#define RATE_9M         5
+#define RATE_12M        6
+#define RATE_18M        7
+#define RATE_24M        8
+#define RATE_36M        9
+#define RATE_48M       10
+#define RATE_54M       11
+#define RATE_AUTO      12
+#define MAX_RATE       12
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+VOID
+RATEvParseMaxRate(
+    IN PVOID pDeviceHandler,
+    IN PWLAN_IE_SUPP_RATES pItemRates,
+    IN PWLAN_IE_SUPP_RATES pItemExtRates,
+    IN BOOL bUpdateBasicRate,
+    OUT PWORD pwMaxBasicRate,
+    OUT PWORD pwMaxSuppRate,
+    OUT PWORD pwSuppRate,
+    OUT PBYTE pbyTopCCKRate,
+    OUT PBYTE pbyTopOFDMRate
+    );
+
+VOID
+RATEvTxRateFallBack(
+    IN PVOID pDeviceHandler,
+    IN PKnownNodeDB psNodeDBTable
+    );
+
+BYTE
+RATEuSetIE(
+    IN PWLAN_IE_SUPP_RATES pSrcRates,
+    IN PWLAN_IE_SUPP_RATES pDstRates,
+    IN UINT                uRateLen
+    );
+
+WORD
+RATEwGetRateIdx(
+    IN BYTE byRate
+    );
+
+
+BYTE
+DATARATEbyGetRateIdx(
+    IN BYTE byRate
+    );
+
+
+#endif //__DATARATE_H__
diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h
new file mode 100644
index 0000000..f10530f
--- /dev/null
+++ b/drivers/staging/vt6656/desc.h
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: desc.h
+ *
+ * Purpose:The header file of descriptor
+ *
+ * Revision History:
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __DESC_H__
+#define __DESC_H__
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include "ttype.h"
+#include "tether.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+// max transmit or receive buffer size
+#define CB_MAX_BUF_SIZE     2900U       // max buffer size
+                                        // NOTE: must be multiple of 4
+
+#define CB_MAX_TX_BUF_SIZE          CB_MAX_BUF_SIZE // max Tx buffer size
+#define CB_MAX_RX_BUF_SIZE_NORMAL   CB_MAX_BUF_SIZE // max Rx buffer size when not use Multi-RD
+
+#define CB_BEACON_BUF_SIZE  512U        // default beacon buffer size
+
+#define MAX_TOTAL_SIZE_WITH_ALL_HEADERS CB_MAX_BUF_SIZE
+
+#define MAX_INTERRUPT_SIZE              32
+
+
+#define RX_BLOCKS           64          // form 0x60 to 0xA0
+#define TX_BLOCKS           32          // from 0xA0 to 0xC0
+
+#define CB_MAX_RX_DESC      128         // max # of descriptor
+#define CB_MIN_RX_DESC      16          // min # of rx descriptor
+#define CB_MAX_TX_DESC      128         // max # of descriptor
+#define CB_MIN_TX_DESC      16          // min # of tx descriptor
+
+#define CB_RD_NUM           64          // default # of RD
+#define CB_TD_NUM           64          // default # of TD
+
+
+
+//
+// Bits in the RSR register
+//
+#define RSR_ADDRBROAD       0x80        // 1000 0000
+#define RSR_ADDRMULTI       0x40        // 0100 0000
+#define RSR_ADDRUNI         0x00        // 0000 0000
+#define RSR_IVLDTYP         0x20        // 0010 0000 , invalid packet type
+#define RSR_IVLDLEN         0x10        // 0001 0000 , invalid len (> 2312 byte)
+#define RSR_BSSIDOK         0x08        // 0000 1000
+#define RSR_CRCOK           0x04        // 0000 0100
+#define RSR_BCNSSIDOK       0x02        // 0000 0010
+#define RSR_ADDROK          0x01        // 0000 0001
+
+//
+// Bits in the new RSR register
+//
+#define NEWRSR_DECRYPTOK    0x10        // 0001 0000
+#define NEWRSR_CFPIND       0x08        // 0000 1000
+#define NEWRSR_HWUTSF       0x04        // 0000 0100
+#define NEWRSR_BCNHITAID    0x02        // 0000 0010
+#define NEWRSR_BCNHITAID0   0x01        // 0000 0001
+
+
+//
+// Bits in the TSR register
+//
+#define TSR_RETRYTMO        0x08        // 0000 1000
+#define TSR_TMO             0x04        // 0000 0100
+#define TSR_ACKDATA         0x02        // 0000 0010
+#define TSR_VALID           0x01        // 0000 0001
+
+
+#define CB_PROTOCOL_RESERVED_SECTION    16
+
+
+
+// if retrys excess 15 times , tx will abort, and
+// if tx fifo underflow, tx will fail
+// we should try to resend it
+#define CB_MAX_TX_ABORT_RETRY   3
+
+
+#define FIFOCTL_AUTO_FB_1   0x1000 // 0001 0000 0000 0000
+#define FIFOCTL_AUTO_FB_0   0x0800 // 0000 1000 0000 0000
+#define FIFOCTL_GRPACK      0x0400 // 0000 0100 0000 0000
+#define FIFOCTL_11GA        0x0300 // 0000 0011 0000 0000
+#define FIFOCTL_11GB        0x0200 // 0000 0010 0000 0000
+#define FIFOCTL_11B         0x0100 // 0000 0001 0000 0000
+#define FIFOCTL_11A         0x0000 // 0000 0000 0000 0000
+#define FIFOCTL_RTS         0x0080 // 0000 0000 1000 0000
+#define FIFOCTL_ISDMA0      0x0040 // 0000 0000 0100 0000
+#define FIFOCTL_GENINT      0x0020 // 0000 0000 0010 0000
+#define FIFOCTL_TMOEN       0x0010 // 0000 0000 0001 0000
+#define FIFOCTL_LRETRY      0x0008 // 0000 0000 0000 1000
+#define FIFOCTL_CRCDIS      0x0004 // 0000 0000 0000 0100
+#define FIFOCTL_NEEDACK     0x0002 // 0000 0000 0000 0010
+#define FIFOCTL_LHEAD       0x0001 // 0000 0000 0000 0001
+
+//WMAC definition Frag Control
+#define FRAGCTL_AES         0x0300 // 0000 0011 0000 0000
+#define FRAGCTL_TKIP        0x0200 // 0000 0010 0000 0000
+#define FRAGCTL_LEGACY      0x0100 // 0000 0001 0000 0000
+#define FRAGCTL_NONENCRYPT  0x0000 // 0000 0000 0000 0000
+//#define FRAGCTL_AC3         0x000C // 0000 0000 0000 1100
+//#define FRAGCTL_AC2         0x0008 // 0000 0000 0000 1000
+//#define FRAGCTL_AC1         0x0004 // 0000 0000 0000 0100
+//#define FRAGCTL_AC0         0x0000 // 0000 0000 0000 0000
+#define FRAGCTL_ENDFRAG     0x0003 // 0000 0000 0000 0011
+#define FRAGCTL_MIDFRAG     0x0002 // 0000 0000 0000 0010
+#define FRAGCTL_STAFRAG     0x0001 // 0000 0000 0000 0001
+#define FRAGCTL_NONFRAG     0x0000 // 0000 0000 0000 0000
+
+
+//#define TYPE_AC0DMA     0
+//#define TYPE_TXDMA0     1
+#define TYPE_TXDMA0     0
+#define TYPE_AC0DMA     1
+#define TYPE_ATIMDMA    2
+#define TYPE_SYNCDMA    3
+#define TYPE_MAXTD      2
+
+#define TYPE_BEACONDMA  4
+
+#define TYPE_RXDMA0     0
+#define TYPE_RXDMA1     1
+#define TYPE_MAXRD      2
+
+
+
+// TD_INFO flags control bit
+#define TD_FLAGS_NETIF_SKB               0x01       // check if need release skb
+#define TD_FLAGS_PRIV_SKB                0x02       // check if called from private skb(hostap)
+#define TD_FLAGS_PS_RETRY                0x04       // check if PS STA frame re-transmit
+//#define TD_FLAGS_NETIF_SKB                0x04
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+//
+// RsvTime buffer header
+//
+typedef struct tagSRrvTime_gRTS {
+    WORD        wRTSTxRrvTime_ba;
+    WORD        wRTSTxRrvTime_aa;
+    WORD        wRTSTxRrvTime_bb;
+    WORD        wReserved;
+    WORD        wTxRrvTime_b;
+    WORD        wTxRrvTime_a;
+}__attribute__ ((__packed__))
+SRrvTime_gRTS, *PSRrvTime_gRTS;
+typedef const SRrvTime_gRTS *PCSRrvTime_gRTS;
+
+typedef struct tagSRrvTime_gCTS {
+    WORD        wCTSTxRrvTime_ba;
+    WORD        wReserved;
+    WORD        wTxRrvTime_b;
+    WORD        wTxRrvTime_a;
+}__attribute__ ((__packed__))
+SRrvTime_gCTS, *PSRrvTime_gCTS;
+typedef const SRrvTime_gCTS *PCSRrvTime_gCTS;
+
+typedef struct tagSRrvTime_ab {
+    WORD        wRTSTxRrvTime;
+    WORD        wTxRrvTime;
+}__attribute__ ((__packed__))
+SRrvTime_ab, *PSRrvTime_ab;
+typedef const SRrvTime_ab *PCSRrvTime_ab;
+
+typedef struct tagSRrvTime_atim {
+    WORD        wCTSTxRrvTime_ba;
+    WORD        wTxRrvTime_a;
+}__attribute__ ((__packed__))
+SRrvTime_atim, *PSRrvTime_atim;
+typedef const SRrvTime_atim *PCSRrvTime_atim;
+
+//
+// RTS buffer header
+//
+typedef struct tagSRTSData {
+    WORD    wFrameControl;
+    WORD    wDurationID;
+    BYTE    abyRA[U_ETHER_ADDR_LEN];
+    BYTE    abyTA[U_ETHER_ADDR_LEN];
+}__attribute__ ((__packed__))
+SRTSData, *PSRTSData;
+typedef const SRTSData *PCSRTSData;
+
+typedef struct tagSRTS_g {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    BYTE        bySignalField_a;
+    BYTE        byServiceField_a;
+    WORD        wTransmitLength_a;
+    WORD        wDuration_ba;
+    WORD        wDuration_aa;
+    WORD        wDuration_bb;
+    WORD        wReserved;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_g, *PSRTS_g;
+typedef const SRTS_g *PCSRTS_g;
+
+
+typedef struct tagSRTS_g_FB {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    BYTE        bySignalField_a;
+    BYTE        byServiceField_a;
+    WORD        wTransmitLength_a;
+    WORD        wDuration_ba;
+    WORD        wDuration_aa;
+    WORD        wDuration_bb;
+    WORD        wReserved;
+    WORD        wRTSDuration_ba_f0;
+    WORD        wRTSDuration_aa_f0;
+    WORD        wRTSDuration_ba_f1;
+    WORD        wRTSDuration_aa_f1;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_g_FB, *PSRTS_g_FB;
+typedef const SRTS_g_FB *PCSRTS_g_FB;
+
+
+typedef struct tagSRTS_ab {
+    BYTE        bySignalField;
+    BYTE        byServiceField;
+    WORD        wTransmitLength;
+    WORD        wDuration;
+    WORD        wReserved;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_ab, *PSRTS_ab;
+typedef const SRTS_ab *PCSRTS_ab;
+
+
+typedef struct tagSRTS_a_FB {
+    BYTE        bySignalField;
+    BYTE        byServiceField;
+    WORD        wTransmitLength;
+    WORD        wDuration;
+    WORD        wReserved;
+    WORD        wRTSDuration_f0;
+    WORD        wRTSDuration_f1;
+    SRTSData    Data;
+}__attribute__ ((__packed__))
+SRTS_a_FB, *PSRTS_a_FB;
+typedef const SRTS_a_FB *PCSRTS_a_FB;
+
+
+//
+// CTS buffer header
+//
+typedef struct tagSCTSData {
+    WORD    wFrameControl;
+    WORD    wDurationID;
+    BYTE    abyRA[U_ETHER_ADDR_LEN];
+    WORD    wReserved;
+}__attribute__ ((__packed__))
+SCTSData, *PSCTSData;
+
+typedef struct tagSCTS {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    WORD        wDuration_ba;
+    WORD        wReserved;
+    SCTSData    Data;
+}__attribute__ ((__packed__))
+SCTS, *PSCTS;
+typedef const SCTS *PCSCTS;
+
+typedef struct tagSCTS_FB {
+    BYTE        bySignalField_b;
+    BYTE        byServiceField_b;
+    WORD        wTransmitLength_b;
+    WORD        wDuration_ba;
+    WORD        wReserved;
+    WORD        wCTSDuration_ba_f0;
+    WORD        wCTSDuration_ba_f1;
+    SCTSData    Data;
+}__attribute__ ((__packed__))
+SCTS_FB, *PSCTS_FB;
+typedef const SCTS_FB *PCSCTS_FB;
+
+
+//
+// Tx FIFO header
+//
+typedef struct tagSTxBufHead {
+    DWORD   adwTxKey[4];
+    WORD    wFIFOCtl;
+    WORD    wTimeStamp;
+    WORD    wFragCtl;
+    WORD    wReserved;
+}__attribute__ ((__packed__))
+STxBufHead, *PSTxBufHead;
+typedef const STxBufHead *PCSTxBufHead;
+
+typedef struct tagSTxShortBufHead {
+    WORD    wFIFOCtl;
+    WORD    wTimeStamp;
+}__attribute__ ((__packed__))
+STxShortBufHead, *PSTxShortBufHead;
+typedef const STxShortBufHead *PCSTxShortBufHead;
+
+//
+// Tx data header
+//
+typedef struct tagSTxDataHead_g {
+    BYTE    bySignalField_b;
+    BYTE    byServiceField_b;
+    WORD    wTransmitLength_b;
+    BYTE    bySignalField_a;
+    BYTE    byServiceField_a;
+    WORD    wTransmitLength_a;
+    WORD    wDuration_b;
+    WORD    wDuration_a;
+    WORD    wTimeStampOff_b;
+    WORD    wTimeStampOff_a;
+}__attribute__ ((__packed__))
+STxDataHead_g, *PSTxDataHead_g;
+typedef const STxDataHead_g *PCSTxDataHead_g;
+
+typedef struct tagSTxDataHead_g_FB {
+    BYTE    bySignalField_b;
+    BYTE    byServiceField_b;
+    WORD    wTransmitLength_b;
+    BYTE    bySignalField_a;
+    BYTE    byServiceField_a;
+    WORD    wTransmitLength_a;
+    WORD    wDuration_b;
+    WORD    wDuration_a;
+    WORD    wDuration_a_f0;
+    WORD    wDuration_a_f1;
+    WORD    wTimeStampOff_b;
+    WORD    wTimeStampOff_a;
+}__attribute__ ((__packed__))
+STxDataHead_g_FB, *PSTxDataHead_g_FB;
+typedef const STxDataHead_g_FB *PCSTxDataHead_g_FB;
+
+
+typedef struct tagSTxDataHead_ab {
+    BYTE    bySignalField;
+    BYTE    byServiceField;
+    WORD    wTransmitLength;
+    WORD    wDuration;
+    WORD    wTimeStampOff;
+}__attribute__ ((__packed__))
+STxDataHead_ab, *PSTxDataHead_ab;
+typedef const STxDataHead_ab *PCSTxDataHead_ab;
+
+
+typedef struct tagSTxDataHead_a_FB {
+    BYTE    bySignalField;
+    BYTE    byServiceField;
+    WORD    wTransmitLength;
+    WORD    wDuration;
+    WORD    wTimeStampOff;
+    WORD    wDuration_f0;
+    WORD    wDuration_f1;
+}__attribute__ ((__packed__))
+STxDataHead_a_FB, *PSTxDataHead_a_FB;
+typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB;
+
+//
+// MICHDR data header
+//
+typedef struct tagSMICHDRHead {
+    DWORD   adwHDR0[4];
+    DWORD   adwHDR1[4];
+    DWORD   adwHDR2[4];
+}__attribute__ ((__packed__))
+SMICHDRHead, *PSMICHDRHead;
+typedef const SMICHDRHead *PCSMICHDRHead;
+
+typedef struct tagSBEACONCtl {
+    DWORD   BufReady : 1;
+    DWORD   TSF      : 15;
+    DWORD   BufLen   : 11;
+    DWORD   Reserved : 5;
+}__attribute__ ((__packed__))
+SBEACONCtl;
+
+
+typedef struct tagSSecretKey {
+    DWORD   dwLowDword;
+    BYTE    byHighByte;
+}__attribute__ ((__packed__))
+SSecretKey;
+
+typedef struct tagSKeyEntry {
+    BYTE  abyAddrHi[2];
+    WORD  wKCTL;
+    BYTE  abyAddrLo[4];
+    DWORD dwKey0[4];
+    DWORD dwKey1[4];
+    DWORD dwKey2[4];
+    DWORD dwKey3[4];
+    DWORD dwKey4[4];
+}__attribute__ ((__packed__))
+SKeyEntry;
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+#endif // __DESC_H__
+
diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h
new file mode 100644
index 0000000..b02ca2d
--- /dev/null
+++ b/drivers/staging/vt6656/device.h
@@ -0,0 +1,939 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: device.h
+ *
+ * Purpose: MAC Data structure
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Mar 17, 1997
+ *
+ */
+
+#ifndef __DEVICE_H__
+#define __DEVICE_H__
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/wait.h>
+#include <linux/if_arp.h>
+#include <linux/sched.h>
+#include <linux/if.h>
+#include <linux/rtnetlink.h>//James
+#include <linux/proc_fs.h>
+#include <linux/inetdevice.h>
+#include <linux/reboot.h>
+#include <linux/usb.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#ifdef SIOCETHTOOL
+#define DEVICE_ETHTOOL_IOCTL_SUPPORT
+#include <linux/ethtool.h>
+#else
+#undef DEVICE_ETHTOOL_IOCTL_SUPPORT
+#endif
+/* Include Wireless Extension definition and check version - Jean II */
+#include <linux/wireless.h>
+#include <net/iw_handler.h>	// New driver API
+
+#ifndef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#endif
+
+//2007-0920-01<Add>by MikeLiu
+#ifndef SndEvt_ToAPI
+#define SndEvt_ToAPI
+//please copy below macro to driver_event.c for API
+#define RT_INSMOD_EVENT_FLAG                             0x0101
+#define RT_UPDEV_EVENT_FLAG                               0x0102
+#define RT_DISCONNECTED_EVENT_FLAG               0x0103
+#define RT_WPACONNECTED_EVENT_FLAG             0x0104
+#define RT_DOWNDEV_EVENT_FLAG                        0x0105
+#define RT_RMMOD_EVENT_FLAG                              0x0106
+#endif
+
+//
+// device specific
+//
+
+#include "kcompat.h"
+#include "device_cfg.h"
+#include "ttype.h"
+#include "80211hdr.h"
+#include "tether.h"
+#include "wmgr.h"
+#include "wcmd.h"
+#include "mib.h"
+#include "srom.h"
+#include "rc4.h"
+#include "desc.h"
+#include "key.h"
+#include "card.h"
+
+/*---------------------  Export Definitions -------------------------*/
+#define VNT_USB_VENDOR_ID                     0x160A
+#define VNT_USB_PRODUCT_ID                    0x3184
+
+#define MAC_MAX_CONTEXT_REG     (256+128)
+
+#define MAX_MULTICAST_ADDRESS_NUM       32
+#define MULTICAST_ADDRESS_LIST_SIZE     (MAX_MULTICAST_ADDRESS_NUM * U_ETHER_ADDR_LEN)
+
+
+//#define OP_MODE_INFRASTRUCTURE  0
+//#define OP_MODE_ADHOC           1
+//#define OP_MODE_AP              2
+
+#define DUPLICATE_RX_CACHE_LENGTH       5
+
+#define NUM_KEY_ENTRY                   11
+
+#define TX_WEP_NONE                     0
+#define TX_WEP_OTF                      1
+#define TX_WEP_SW                       2
+#define TX_WEP_SWOTP                    3
+#define TX_WEP_OTPSW                    4
+#define TX_WEP_SW232                    5
+
+#define KEYSEL_WEP40                    0
+#define KEYSEL_WEP104                   1
+#define KEYSEL_TKIP                     2
+#define KEYSEL_CCMP                     3
+
+
+
+#define AUTO_FB_NONE            0
+#define AUTO_FB_0               1
+#define AUTO_FB_1               2
+
+#define FB_RATE0                0
+#define FB_RATE1                1
+
+// Antenna Mode
+#define ANT_A                   0
+#define ANT_B                   1
+#define ANT_DIVERSITY           2
+#define ANT_RXD_TXA             3
+#define ANT_RXD_TXB             4
+#define ANT_UNKNOWN             0xFF
+#define ANT_TXA                 0
+#define ANT_TXB                 1
+#define ANT_RXA                 2
+#define ANT_RXB                 3
+
+
+#define MAXCHECKHANGCNT         4
+
+//Packet type
+#define TX_PKT_UNI              0x00
+#define TX_PKT_MULTI            0x01
+#define TX_PKT_BROAD            0x02
+
+#define BB_VGA_LEVEL            4
+#define BB_VGA_CHANGE_THRESHOLD 3
+
+
+
+#ifndef RUN_AT
+#define RUN_AT(x)                       (jiffies+(x))
+#endif
+
+// DMA related
+#define RESERV_AC0DMA                   4
+
+#define PRIVATE_Message                 0
+
+/*---------------------  Export Types  ------------------------------*/
+
+#define DBG_PRT(l, p, args...) {if (l<=msglevel) printk( p ,##args);}
+#define PRINT_K(p, args...) {if (PRIVATE_Message) printk( p ,##args);}
+
+typedef enum __device_msg_level {
+    MSG_LEVEL_ERR=0,            //Errors that will cause abnormal operation.
+    MSG_LEVEL_NOTICE=1,         //Some errors need users to be notified.
+    MSG_LEVEL_INFO=2,           //Normal message.
+    MSG_LEVEL_VERBOSE=3,        //Will report all trival errors.
+    MSG_LEVEL_DEBUG=4           //Only for debug purpose.
+} DEVICE_MSG_LEVEL, *PDEVICE_MSG_LEVEL;
+
+typedef enum __device_init_type {
+    DEVICE_INIT_COLD=0,         // cold init
+    DEVICE_INIT_RESET,          // reset init or Dx to D0 power remain init
+    DEVICE_INIT_DXPL            // Dx to D0 power lost init
+} DEVICE_INIT_TYPE, *PDEVICE_INIT_TYPE;
+
+
+//USB
+
+//
+// Enum of context types for SendPacket
+//
+typedef enum _CONTEXT_TYPE {
+    CONTEXT_DATA_PACKET = 1,
+    CONTEXT_MGMT_PACKET
+} CONTEXT_TYPE;
+
+
+
+
+// RCB (Receive Control Block)
+typedef struct _RCB
+{
+    PVOID                   Next;
+    LONG                    Ref;
+    PVOID                   pDevice;
+    struct urb              *pUrb;
+    SRxMgmtPacket           sMngPacket;
+    struct sk_buff*         skb;
+    BOOL                    bBoolInUse;
+
+} RCB, *PRCB;
+
+
+// used to track bulk out irps
+typedef struct _USB_SEND_CONTEXT {
+    PVOID           pDevice;
+    struct sk_buff *pPacket;
+    struct urb      *pUrb;
+    UINT            uBufLen;
+    CONTEXT_TYPE    Type;
+    SEthernetHeader sEthHeader;
+    PVOID           Next;
+    BOOL            bBoolInUse;
+    UCHAR           Data[MAX_TOTAL_SIZE_WITH_ALL_HEADERS];
+} USB_SEND_CONTEXT, *PUSB_SEND_CONTEXT;
+
+
+//structure got from configuration file as user desired default setting.
+typedef struct _DEFAULT_CONFIG{
+    INT    ZoneType;
+    INT    eConfigMode;
+    INT    eAuthenMode;    //open/wep/wpa
+    INT    bShareKeyAlgorithm;  //open-open/open-sharekey/wep-sharekey
+    INT    keyidx;               //wepkey index
+    INT    eEncryptionStatus;
+
+}DEFAULT_CONFIG,*PDEFAULT_CONFIG;
+
+//
+// Structure to keep track of usb interrupt packets
+//
+typedef struct {
+    UINT            uDataLen;
+    PBYTE           pDataBuf;
+//    struct urb      *pUrb;
+    BOOL            bInUse;
+} INT_BUFFER, *PINT_BUFFER;
+
+
+
+//0:11A 1:11B 2:11G
+typedef enum _VIA_BB_TYPE
+{
+    BB_TYPE_11A=0,
+    BB_TYPE_11B,
+    BB_TYPE_11G
+} VIA_BB_TYPE, *PVIA_BB_TYPE;
+
+//0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
+typedef enum _VIA_PKT_TYPE
+{
+    PK_TYPE_11A=0,
+    PK_TYPE_11B,
+    PK_TYPE_11GB,
+    PK_TYPE_11GA
+} VIA_PKT_TYPE, *PVIA_PKT_TYPE;
+
+
+
+
+//++ NDIS related
+
+#define NDIS_STATUS     int
+#define NTSTATUS        int
+
+typedef enum __DEVICE_NDIS_STATUS {
+    STATUS_SUCCESS=0,
+    STATUS_FAILURE,
+    STATUS_RESOURCES,
+    STATUS_PENDING,
+} DEVICE_NDIS_STATUS, *PDEVICE_NDIS_STATUS;
+
+
+#define MAX_BSSIDINFO_4_PMKID   16
+#define MAX_PMKIDLIST           5
+//Flags for PMKID Candidate list structure
+#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED	0x01
+
+// PMKID Structures
+typedef UCHAR   NDIS_802_11_PMKID_VALUE[16];
+
+
+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
+} 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_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;
+
+//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 _BSSID_INFO
+{
+    NDIS_802_11_MAC_ADDRESS BSSID;
+    NDIS_802_11_PMKID_VALUE PMKID;
+} BSSID_INFO, *PBSSID_INFO;
+
+typedef struct tagSPMKID {
+    ULONG Length;
+    ULONG BSSIDInfoCount;
+    BSSID_INFO BSSIDInfo[MAX_BSSIDINFO_4_PMKID];
+} SPMKID, *PSPMKID;
+
+typedef struct tagSPMKIDCandidateEvent {
+    NDIS_802_11_STATUS_TYPE     StatusType;
+    ULONG Version;       // Version of the structure
+    ULONG NumCandidates; // No. of pmkid candidates
+    PMKID_CANDIDATE CandidateList[MAX_PMKIDLIST];
+} SPMKIDCandidateEvent, *PSPMKIDCandidateEvent;
+
+//--
+
+//++ 802.11h related
+#define MAX_QUIET_COUNT     8
+
+typedef struct tagSQuietControl {
+    BOOL        bEnable;
+    DWORD       dwStartTime;
+    BYTE        byPeriod;
+    WORD        wDuration;
+} SQuietControl, *PSQuietControl;
+
+//--
+
+
+// The receive duplicate detection cache entry
+typedef struct tagSCacheEntry{
+    WORD        wFmSequence;
+    BYTE        abyAddr2[U_ETHER_ADDR_LEN];
+    WORD        wFrameCtl;
+} SCacheEntry, *PSCacheEntry;
+
+typedef struct tagSCache{
+/* The receive cache is updated circularly.  The next entry to be written is
+ * indexed by the "InPtr".
+*/
+    UINT            uInPtr;         // Place to use next
+    SCacheEntry     asCacheEntry[DUPLICATE_RX_CACHE_LENGTH];
+} SCache, *PSCache;
+
+#define CB_MAX_RX_FRAG                 64
+// DeFragment Control Block, used for collecting fragments prior to reassembly
+typedef struct tagSDeFragControlBlock
+{
+    WORD            wSequence;
+    WORD            wFragNum;
+    BYTE            abyAddr2[U_ETHER_ADDR_LEN];
+	UINT            uLifetime;
+    struct sk_buff* skb;
+    PBYTE           pbyRxBuffer;
+    UINT            cbFrameLength;
+    BOOL            bInUse;
+} SDeFragControlBlock, *PSDeFragControlBlock;
+
+
+
+//flags for options
+#define     DEVICE_FLAGS_UNPLUG          0x00000001UL
+#define     DEVICE_FLAGS_PREAMBLE_TYPE   0x00000002UL
+#define     DEVICE_FLAGS_OP_MODE         0x00000004UL
+#define     DEVICE_FLAGS_PS_MODE         0x00000008UL
+#define		DEVICE_FLAGS_80211h_MODE	 0x00000010UL
+
+//flags for driver status
+#define     DEVICE_FLAGS_OPENED          0x00010000UL
+#define     DEVICE_FLAGS_WOL_ENABLED     0x00080000UL
+//flags for capbilities
+#define     DEVICE_FLAGS_TX_ALIGN        0x01000000UL
+#define     DEVICE_FLAGS_HAVE_CAM        0x02000000UL
+#define     DEVICE_FLAGS_FLOW_CTRL       0x04000000UL
+
+//flags for MII status
+#define     DEVICE_LINK_FAIL             0x00000001UL
+#define     DEVICE_SPEED_10              0x00000002UL
+#define     DEVICE_SPEED_100             0x00000004UL
+#define     DEVICE_SPEED_1000            0x00000008UL
+#define     DEVICE_DUPLEX_FULL           0x00000010UL
+#define     DEVICE_AUTONEG_ENABLE        0x00000020UL
+#define     DEVICE_FORCED_BY_EEPROM      0x00000040UL
+//for device_set_media_duplex
+#define     DEVICE_LINK_CHANGE           0x00000001UL
+
+
+typedef struct __device_opt {
+    int         nRxDescs0;    //Number of RX descriptors0
+    int         nTxDescs0;    //Number of TX descriptors 0, 1, 2, 3
+    int         rts_thresh;   //rts threshold
+    int         frag_thresh;
+    int         OpMode;
+    int         data_rate;
+    int         channel_num;
+    int         short_retry;
+    int         long_retry;
+    int         bbp_type;
+    U32         flags;
+} OPTIONS, *POPTIONS;
+
+
+typedef struct __device_info {
+
+// netdev
+	struct usb_device*          usb;
+    struct net_device*          dev;
+    struct net_device_stats     stats;
+
+    OPTIONS                     sOpts;
+
+	struct tasklet_struct       CmdWorkItem;
+	struct tasklet_struct       EventWorkItem;
+	struct tasklet_struct       ReadWorkItem;
+	struct tasklet_struct       RxMngWorkItem;
+
+    U32                         rx_buf_sz;
+    int                         multicast_limit;
+    BYTE                        byRxMode;
+
+    spinlock_t                  lock;
+
+    U32                         rx_bytes;
+
+    BYTE                        byRevId;
+
+    U32                         flags;
+    ULONG                       Flags;
+
+    SCache                      sDupRxCache;
+
+    SDeFragControlBlock         sRxDFCB[CB_MAX_RX_FRAG];
+    UINT                        cbDFCB;
+    UINT                        cbFreeDFCB;
+    UINT                        uCurrentDFCBIdx;
+
+    // +++USB
+
+    struct urb                  *pControlURB;
+    struct urb                  *pInterruptURB;
+	struct usb_ctrlrequest      sUsbCtlRequest;
+
+    UINT                        int_interval;
+    //
+    // Variables to track resources for the BULK In Pipe
+    //
+    PRCB                        pRCBMem;
+    PRCB                        apRCB[CB_MAX_RX_DESC];
+    UINT                        cbRD;
+    PRCB                        FirstRecvFreeList;
+    PRCB                        LastRecvFreeList;
+    UINT                        NumRecvFreeList;
+    PRCB                        FirstRecvMngList;
+    PRCB                        LastRecvMngList;
+    UINT                        NumRecvMngList;
+    BOOL                        bIsRxWorkItemQueued;
+    BOOL                        bIsRxMngWorkItemQueued;
+    ULONG                       ulRcvRefCount;      // number of packets that have not been returned back
+
+    //
+    //  Variables to track resources for the BULK Out Pipe
+    //
+
+    PUSB_SEND_CONTEXT           apTD[CB_MAX_TX_DESC];
+    UINT                        cbTD;
+
+    //
+    //  Variables to track resources for the Interript In Pipe
+    //
+    INT_BUFFER                  intBuf;
+    BOOL                        fKillEventPollingThread;
+    BOOL                        bEventAvailable;
+
+
+  //default config from file by user setting
+    DEFAULT_CONFIG    config_file;
+
+
+    //
+    // Statistic for USB
+    // protect with spinlock
+    ULONG                       ulBulkInPosted;
+    ULONG                       ulBulkInError;
+    ULONG                       ulBulkInContCRCError;
+    ULONG                       ulBulkInBytesRead;
+
+    ULONG                       ulBulkOutPosted;
+    ULONG                       ulBulkOutError;
+    ULONG                       ulBulkOutContCRCError;
+    ULONG                       ulBulkOutBytesWrite;
+
+    ULONG                       ulIntInPosted;
+    ULONG                       ulIntInError;
+    ULONG                       ulIntInContCRCError;
+    ULONG                       ulIntInBytesRead;
+
+
+    // Version control
+    WORD                        wFirmwareVersion;
+    BYTE                        byLocalID;
+    BYTE                        byRFType;
+    BYTE                        byBBRxConf;
+
+
+    BYTE                        byZoneType;
+    BOOL                        bZoneRegExist;
+
+    BYTE                        byOriginalZonetype;
+
+    BOOL                        bLinkPass;          // link status: OK or fail
+    BYTE                        abyCurrentNetAddr[U_ETHER_ADDR_LEN];
+    BYTE                        abyPermanentNetAddr[U_ETHER_ADDR_LEN];
+    // SW network address
+//    BYTE                        abySoftwareNetAddr[U_ETHER_ADDR_LEN];
+    BOOL                        bExistSWNetAddr;
+
+    // Adapter statistics
+    SStatCounter                scStatistic;
+    // 802.11 counter
+    SDot11Counters              s802_11Counter;
+
+    //
+    // Maintain statistical debug info.
+    //
+    ULONG                       packetsReceived;
+    ULONG                       packetsReceivedDropped;
+    ULONG                       packetsReceivedOverflow;
+    ULONG                       packetsSent;
+    ULONG                       packetsSentDropped;
+    ULONG                       SendContextsInUse;
+    ULONG                       RcvBuffersInUse;
+
+
+    // 802.11 management
+    SMgmtObject                 sMgmtObj;
+
+    QWORD                       qwCurrTSF;
+    UINT                        cbBulkInMax;
+    BOOL                        bPSRxBeacon;
+
+    // 802.11 MAC specific
+    UINT                        uCurrRSSI;
+    BYTE                        byCurrSQ;
+
+
+    //Antenna Diversity
+    BOOL                        bTxRxAntInv;
+    DWORD                       dwRxAntennaSel;
+    DWORD                       dwTxAntennaSel;
+    BYTE                        byAntennaCount;
+    BYTE                        byRxAntennaMode;
+    BYTE                        byTxAntennaMode;
+    BYTE                        byRadioCtl;
+    BYTE                        bHWRadioOff;
+
+    //SQ3 functions for antenna diversity
+    struct timer_list           TimerSQ3Tmax1;
+    struct timer_list           TimerSQ3Tmax2;
+    struct timer_list           TimerSQ3Tmax3;
+
+    BOOL                        bDiversityRegCtlON;
+    BOOL                        bDiversityEnable;
+    ULONG                       ulDiversityNValue;
+    ULONG                       ulDiversityMValue;
+    BYTE                        byTMax;
+    BYTE                        byTMax2;
+    BYTE                        byTMax3;
+    ULONG                       ulSQ3TH;
+
+    ULONG                       uDiversityCnt;
+    BYTE                        byAntennaState;
+    ULONG                       ulRatio_State0;
+    ULONG                       ulRatio_State1;
+    ULONG                       ulSQ3_State0;
+    ULONG                       ulSQ3_State1;
+
+    ULONG                       aulSQ3Val[MAX_RATE];
+    ULONG                       aulPktNum[MAX_RATE];
+
+    // IFS & Cw
+    UINT                        uSIFS;    //Current SIFS
+    UINT                        uDIFS;    //Current DIFS
+    UINT                        uEIFS;    //Current EIFS
+    UINT                        uSlot;    //Current SlotTime
+    UINT                        uCwMin;   //Current CwMin
+    UINT                        uCwMax;   //CwMax is fixed on 1023.
+    // PHY parameter
+    BYTE                        bySIFS;
+    BYTE                        byDIFS;
+    BYTE                        byEIFS;
+    BYTE                        bySlot;
+    BYTE                        byCWMaxMin;
+
+    // Rate
+    VIA_BB_TYPE                 byBBType; //0: 11A, 1:11B, 2:11G
+    VIA_PKT_TYPE                byPacketType; //0:11a,1:11b,2:11gb(only CCK in BasicRate),3:11ga(OFDM in Basic Rate)
+    WORD                        wBasicRate;
+    BYTE                        byACKRate;
+    BYTE                        byTopOFDMBasicRate;
+    BYTE                        byTopCCKBasicRate;
+
+
+    DWORD                       dwAotoRateTxOkCnt;
+    DWORD                       dwAotoRateTxFailCnt;
+    DWORD                       dwErrorRateThreshold[13];
+    DWORD                       dwTPTable[MAX_RATE];
+    BYTE                        abyEEPROM[EEP_MAX_CONTEXT_SIZE];  //DWORD alignment
+
+    BYTE                        byMinChannel;
+    BYTE                        byMaxChannel;
+    UINT                        uConnectionRate;
+
+    BYTE                        byPreambleType;
+    BYTE                        byShortPreamble;
+    // CARD_PHY_TYPE
+    BYTE                        eConfigPHYMode;
+
+    // For RF Power table
+    BYTE                        byCCKPwr;
+    BYTE                        byOFDMPwrG;
+    BYTE                        byOFDMPwrA;
+    BYTE                        byCurPwr;
+    BYTE                        abyCCKPwrTbl[14];
+    BYTE                        abyOFDMPwrTbl[14];
+    BYTE                        abyOFDMAPwrTbl[42];
+
+    WORD                        wCurrentRate;
+    WORD                        wRTSThreshold;
+    WORD                        wFragmentationThreshold;
+    BYTE                        byShortRetryLimit;
+    BYTE                        byLongRetryLimit;
+    CARD_OP_MODE                eOPMode;
+    BOOL                        bBSSIDFilter;
+    WORD                        wMaxTransmitMSDULifetime;
+    BYTE                        abyBSSID[U_ETHER_ADDR_LEN];
+    BYTE                        abyDesireBSSID[U_ETHER_ADDR_LEN];
+    WORD                        wCTSDuration;       // update while speed change
+    WORD                        wACKDuration;       // update while speed change
+    WORD                        wRTSTransmitLen;    // update while speed change
+    BYTE                        byRTSServiceField;  // update while speed change
+    BYTE                        byRTSSignalField;   // update while speed change
+
+    DWORD                       dwMaxReceiveLifetime;       // dot11MaxReceiveLifetime
+
+    BOOL                        bCCK;
+    BOOL                        bEncryptionEnable;
+    BOOL                        bLongHeader;
+    BOOL                        bSoftwareGenCrcErr;
+    BOOL                        bShortSlotTime;
+    BOOL                        bProtectMode;
+    BOOL                        bNonERPPresent;
+    BOOL                        bBarkerPreambleMd;
+
+    BYTE                        byERPFlag;
+    WORD                        wUseProtectCntDown;
+
+    BOOL                        bRadioControlOff;
+    BOOL                        bRadioOff;
+
+    // Power save
+    BOOL                        bEnablePSMode;
+    WORD                        wListenInterval;
+    BOOL                        bPWBitOn;
+    WMAC_POWER_MODE             ePSMode;
+    ULONG                       ulPSModeWaitTx;
+    BOOL                        bPSModeTxBurst;
+
+    // Beacon releated
+    WORD                    wSeqCounter;
+    BOOL                    bBeaconBufReady;
+    BOOL                    bBeaconSent;
+    BOOL                    bFixRate;
+    BYTE                    byCurrentCh;
+    UINT                    uScanTime;
+
+    CMD_STATE               eCommandState;
+
+    CMD_CODE                eCommand;
+    BOOL                    bBeaconTx;
+    BYTE                    byScanBBType;
+
+    BOOL                    bStopBeacon;
+    BOOL                    bStopDataPkt;
+    BOOL                    bStopTx0Pkt;
+    UINT                    uAutoReConnectTime;
+    UINT                    uIsroamingTime;
+
+    // 802.11 counter
+
+    CMD_ITEM                eCmdQueue[CMD_Q_SIZE];
+    UINT                    uCmdDequeueIdx;
+    UINT                    uCmdEnqueueIdx;
+    UINT                    cbFreeCmdQueue;
+    BOOL                    bCmdRunning;
+    BOOL                    bCmdClear;
+    BOOL                    bNeedRadioOFF;
+
+    BOOL                    bEnableRoaming;  //DavidWang
+    BOOL                    bIsRoaming;  //DavidWang
+    BOOL                    bFastRoaming;  //DavidWang
+    BYTE                    bSameBSSMaxNum;  //Davidwang
+    BYTE                    bSameBSSCurNum;  //DavidWang
+    BOOL                    bRoaming;
+    BOOL                    b11hEable;
+    ULONG                   ulTxPower;
+
+    // Encryption
+    NDIS_802_11_WEP_STATUS  eEncryptionStatus;
+    BOOL                    bTransmitKey;
+
+//2007-0925-01<Add>by MikeLiu
+//mike add :save old Encryption
+    NDIS_802_11_WEP_STATUS  eOldEncryptionStatus;
+
+    SKeyManagement          sKey;
+    DWORD                   dwIVCounter;
+
+
+    RC4Ext                  SBox;
+    BYTE                    abyPRNG[WLAN_WEPMAX_KEYLEN+3];
+    BYTE                    byKeyIndex;
+
+    BOOL                    bAES;
+    BYTE                    byCntMeasure;
+
+    UINT                    uKeyLength;
+    BYTE                    abyKey[WLAN_WEP232_KEYLEN];
+
+    // for AP mode
+    UINT                    uAssocCount;
+    BOOL                    bMoreData;
+
+    // QoS
+    BOOL                    bGrpAckPolicy;
+
+
+    BYTE                    byAutoFBCtrl;
+
+    BOOL                    bTxMICFail;
+    BOOL                    bRxMICFail;
+
+
+    // For Update BaseBand VGA Gain Offset
+    BOOL                    bUpdateBBVGA;
+    UINT                    uBBVGADiffCount;
+    BYTE                    byBBVGANew;
+    BYTE                    byBBVGACurrent;
+    BYTE                    abyBBVGA[BB_VGA_LEVEL];
+    LONG                    ldBmThreshold[BB_VGA_LEVEL];
+
+    BYTE                    byBBPreEDRSSI;
+    BYTE                    byBBPreEDIndex;
+
+
+    BOOL                    bRadioCmd;
+    DWORD                   dwDiagRefCount;
+
+    // For FOE Tuning
+    BYTE                    byFOETuning;
+
+    // For Auto Power Tunning
+
+    BYTE                    byAutoPwrTunning;
+
+    // BaseBand Loopback Use
+    BYTE                    byBBCR4d;
+    BYTE                    byBBCRc9;
+    BYTE                    byBBCR88;
+    BYTE                    byBBCR09;
+
+    // command timer
+    struct timer_list       sTimerCommand;
+
+//2007-0115-01<Add>by MikeLiu
+#ifdef TxInSleep
+     struct timer_list       sTimerTxData;
+     ULONG                       nTxDataTimeCout;
+     BOOL  fTxDataInSleep;
+     BOOL  IsTxDataTrigger;
+#endif
+
+#ifdef WPA_SM_Transtatus
+    BOOL  fWPA_Authened;           //is WPA/WPA-PSK or WPA2/WPA2-PSK authen??
+#endif
+    BYTE            byReAssocCount;   //mike add:re-association retry times!
+    BYTE            byLinkWaitCount;
+
+    SEthernetHeader         sTxEthHeader;
+    SEthernetHeader         sRxEthHeader;
+    BYTE                    abyBroadcastAddr[U_ETHER_ADDR_LEN];
+    BYTE                    abySNAP_RFC1042[U_ETHER_ADDR_LEN];
+    BYTE                    abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN];
+
+    // Pre-Authentication & PMK cache
+    SPMKID                  gsPMKID;
+    SPMKIDCandidateEvent    gsPMKIDCandidate;
+
+
+    // for 802.11h
+    BOOL                    b11hEnable;
+
+    BOOL                    bChannelSwitch;
+    BYTE                    byNewChannel;
+    BYTE                    byChannelSwitchCount;
+
+    //WPA supplicant daemon
+	struct net_device       *wpadev;
+	BOOL                    bWPADEVUp;
+    struct sk_buff          *skb;
+    //--
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+        BOOL                 bwextstep0;
+        BOOL                 bwextstep1;
+        BOOL                 bwextstep2;
+        BOOL                 bwextstep3;
+        BOOL                 bWPASuppWextEnabled;
+#endif
+
+#ifdef HOSTAP
+    // user space daemon: hostapd, is used for HOSTAP
+	BOOL                    bEnableHostapd;
+	BOOL                    bEnable8021x;
+	BOOL                    bEnableHostWEP;
+	struct net_device       *apdev;
+	int (*tx_80211)(struct sk_buff *skb, struct net_device *dev);
+#endif
+    UINT                    uChannel;
+
+	struct iw_statistics	wstats;		// wireless stats
+    BOOL                    bCommit;
+
+} DEVICE_INFO, *PSDevice;
+
+
+
+
+#define EnqueueRCB(_Head, _Tail, _RCB)                  \
+{                                                       \
+    if (!_Head) {                                       \
+        _Head = _RCB;                                   \
+    }                                                   \
+    else {                                              \
+        _Tail->Next = _RCB;                             \
+    }                                                   \
+    _RCB->Next = NULL;                                  \
+    _Tail = _RCB;                                       \
+}
+
+#define DequeueRCB(Head, Tail)                          \
+{                                                       \
+    PRCB   RCB = Head;                                  \
+    if (!RCB->Next) {                                   \
+        Tail = NULL;                                    \
+    }                                                   \
+    Head = RCB->Next;                                   \
+}
+
+
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) {   \
+    if ((uVar) >= ((uModulo) - 1))                  \
+        (uVar) = 0;                                 \
+    else                                            \
+        (uVar)++;                                   \
+}
+
+
+#define fMP_RESET_IN_PROGRESS               0x00000001
+#define fMP_DISCONNECTED                    0x00000002
+#define fMP_HALT_IN_PROGRESS                0x00000004
+#define fMP_SURPRISE_REMOVED                0x00000008
+#define fMP_RECV_LOOKASIDE                  0x00000010
+#define fMP_INIT_IN_PROGRESS                0x00000020
+#define fMP_SEND_SIDE_RESOURCE_ALLOCATED    0x00000040
+#define fMP_RECV_SIDE_RESOURCE_ALLOCATED    0x00000080
+#define fMP_POST_READS                      0x00000100
+#define fMP_POST_WRITES                     0x00000200
+#define fMP_CONTROL_READS                   0x00000400
+#define fMP_CONTROL_WRITES                  0x00000800
+
+
+
+#define MP_SET_FLAG(_M, _F)             ((_M)->Flags |= (_F))
+#define MP_CLEAR_FLAG(_M, _F)            ((_M)->Flags &= ~(_F))
+#define MP_TEST_FLAG(_M, _F)            (((_M)->Flags & (_F)) != 0)
+#define MP_TEST_FLAGS(_M, _F)            (((_M)->Flags & (_F)) == (_F))
+
+#define MP_IS_READY(_M)        (((_M)->Flags & \
+                                 (fMP_DISCONNECTED | fMP_RESET_IN_PROGRESS | fMP_HALT_IN_PROGRESS | fMP_INIT_IN_PROGRESS | fMP_SURPRISE_REMOVED)) == 0)
+
+/*---------------------  Export Functions  --------------------------*/
+
+//BOOL device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, UINT uNodeIndex);
+BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF);
+
+#endif
+
+
diff --git a/drivers/staging/vt6656/device_cfg.h b/drivers/staging/vt6656/device_cfg.h
new file mode 100644
index 0000000..c816901
--- /dev/null
+++ b/drivers/staging/vt6656/device_cfg.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: device_cfg.h
+ *
+ * Purpose: Driver configuration header
+ * Author: Lyndon Chen
+ *
+ * Date: Dec 9, 2005
+ *
+ */
+#ifndef __DEVICE_CONFIG_H
+#define __DEVICE_CONFIG_H
+
+#include <linux/types.h>
+
+#include "ttype.h"
+
+typedef
+struct _version {
+    unsigned char   major;
+    unsigned char   minor;
+    unsigned char   build;
+} version_t, *pversion_t;
+
+#ifndef FALSE
+#define FALSE   (0)
+#endif
+
+#ifndef TRUE
+#define TRUE    (!(FALSE))
+#endif
+
+#define VID_TABLE_SIZE      64
+#define MCAST_TABLE_SIZE    64
+#define MCAM_SIZE           32
+#define VCAM_SIZE           32
+#define TX_QUEUE_NO         8
+
+#define DEVICE_NAME         "vt6656"
+#define DEVICE_FULL_DRV_NAM "VIA Networking Wireless LAN USB Driver"
+
+#ifndef MAJOR_VERSION
+#define MAJOR_VERSION       1
+#endif
+
+#ifndef MINOR_VERSION
+#define MINOR_VERSION       13
+#endif
+
+#ifndef DEVICE_VERSION
+#define DEVICE_VERSION       "1.19_12"
+#endif
+
+//config file
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#ifndef CONFIG_PATH
+#define CONFIG_PATH            "/etc/vntconfiguration.dat"
+#endif
+
+//Max: 2378=2312Payload + 30HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR
+#define PKT_BUF_SZ          2390
+
+
+#define MAX_UINTS           8
+#define OPTION_DEFAULT      { [0 ... MAX_UINTS-1] = -1}
+
+
+
+typedef enum  _chip_type{
+    VT3184=1
+} CHIP_TYPE, *PCHIP_TYPE;
+
+
+
+#ifdef VIAWET_DEBUG
+#define ASSERT(x) { \
+    if (!(x)) { \
+        printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\
+        __FUNCTION__, __LINE__);\
+        *(int*) 0=0;\
+    }\
+}
+#define DBG_PORT80(value)                   outb(value, 0x80)
+#else
+#define ASSERT(x)
+#define DBG_PORT80(value)
+#endif
+
+
+#endif
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c
new file mode 100644
index 0000000..835c6d6
--- /dev/null
+++ b/drivers/staging/vt6656/dpc.c
@@ -0,0 +1,1616 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: dpc.c
+ *
+ * Purpose: handle dpc rx functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 20, 2003
+ *
+ * Functions:
+ *      device_receive_frame - Rcv 802.11 frame function
+ *      s_bAPModeRxCtl- AP Rcv frame filer Ctl.
+ *      s_bAPModeRxData- AP Rcv data frame handle
+ *      s_bHandleRxEncryption- Rcv decrypted data via on-fly
+ *      s_bHostWepRxEncryption- Rcv encrypted data via host
+ *      s_byGetRateIdx- get rate index
+ *      s_vGetDASA- get data offset
+ *      s_vProcessRxMACHeader- Rcv 802.11 and translate to 802.3
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "rxtx.h"
+#include "tether.h"
+#include "card.h"
+#include "bssdb.h"
+#include "mac.h"
+#include "baseband.h"
+#include "michael.h"
+#include "tkip.h"
+#include "tcrc.h"
+#include "wctl.h"
+#include "hostap.h"
+#include "rf.h"
+#include "iowpa.h"
+#include "aes_ccmp.h"
+#include "datarate.h"
+#include "usbpipe.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+const BYTE acbyRxRate[MAX_RATE] =
+{2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108};
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+static BYTE s_byGetRateIdx(IN BYTE byRate);
+
+
+static
+VOID
+s_vGetDASA(
+    IN  PBYTE pbyRxBufferAddr,
+    OUT PUINT pcbHeaderSize,
+    OUT PSEthernetHeader psEthHeader
+    );
+
+static
+VOID
+s_vProcessRxMACHeader (
+    IN  PSDevice pDevice,
+    IN  PBYTE pbyRxBufferAddr,
+    IN  UINT cbPacketSize,
+    IN  BOOL bIsWEP,
+    IN  BOOL bExtIV,
+    OUT PUINT pcbHeadSize
+    );
+
+static BOOL s_bAPModeRxCtl(
+    IN PSDevice pDevice,
+    IN PBYTE    pbyFrame,
+    IN INT      iSANodeIndex
+    );
+
+
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN struct sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    );
+
+
+static BOOL s_bHandleRxEncryption(
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    OUT PBYTE       pbyNewRsr,
+    OUT PSKeyItem   *pKeyOut,
+    int *       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+    );
+
+static BOOL s_bHostWepRxEncryption(
+
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    IN BOOL         bOnFly,
+    IN PSKeyItem    pKey,
+    OUT PBYTE       pbyNewRsr,
+    int *       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+
+    );
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*+
+ *
+ * Description:
+ *    Translate Rcv 802.11 header to 802.3 header with Rx buffer
+ *
+ * Parameters:
+ *  In:
+ *      pDevice
+ *      dwRxBufferAddr  - Address of Rcv Buffer
+ *      cbPacketSize    - Rcv Packet size
+ *      bIsWEP          - If Rcv with WEP
+ *  Out:
+ *      pcbHeaderSize   - 802.11 header size
+ *
+ * Return Value: None
+ *
+-*/
+static
+VOID
+s_vProcessRxMACHeader (
+    IN  PSDevice pDevice,
+    IN  PBYTE pbyRxBufferAddr,
+    IN  UINT cbPacketSize,
+    IN  BOOL bIsWEP,
+    IN  BOOL bExtIV,
+    OUT PUINT pcbHeadSize
+    )
+{
+    PBYTE           pbyRxBuffer;
+    UINT            cbHeaderSize = 0;
+    PWORD           pwType;
+    PS802_11Header  pMACHeader;
+    int             ii;
+
+
+    pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
+
+    s_vGetDASA((PBYTE)pMACHeader, &cbHeaderSize, &pDevice->sRxEthHeader);
+
+    if (bIsWEP) {
+        if (bExtIV) {
+            // strip IV&ExtIV , add 8 byte
+            cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 8);
+        } else {
+            // strip IV , add 4 byte
+            cbHeaderSize += (WLAN_HDR_ADDR3_LEN + 4);
+        }
+    }
+    else {
+        cbHeaderSize += WLAN_HDR_ADDR3_LEN;
+    };
+
+    pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize);
+    if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_Bridgetunnel[0])) {
+        cbHeaderSize += 6;
+    }
+    else if (IS_ETH_ADDRESS_EQUAL(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) {
+        cbHeaderSize += 6;
+        pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+        if ((*pwType!= TYPE_PKT_IPX) && (*pwType != cpu_to_le16(0xF380))) {
+        }
+        else {
+            cbHeaderSize -= 8;
+            pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+            if (bIsWEP) {
+                if (bExtIV) {
+                    *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
+                } else {
+                    *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
+                }
+            }
+            else {
+                *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
+            }
+        }
+    }
+    else {
+        cbHeaderSize -= 2;
+        pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize);
+        if (bIsWEP) {
+            if (bExtIV) {
+                *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 8);    // 8 is IV&ExtIV
+            } else {
+                *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN - 4);    // 4 is IV
+            }
+        }
+        else {
+            *pwType = htons(cbPacketSize - WLAN_HDR_ADDR3_LEN);
+        }
+    }
+
+    cbHeaderSize -= (U_ETHER_ADDR_LEN * 2);
+    pbyRxBuffer = (PBYTE) (pbyRxBufferAddr + cbHeaderSize);
+    for(ii=0;ii<U_ETHER_ADDR_LEN;ii++)
+        *pbyRxBuffer++ = pDevice->sRxEthHeader.abyDstAddr[ii];
+    for(ii=0;ii<U_ETHER_ADDR_LEN;ii++)
+        *pbyRxBuffer++ = pDevice->sRxEthHeader.abySrcAddr[ii];
+
+    *pcbHeadSize = cbHeaderSize;
+}
+
+
+
+
+static BYTE s_byGetRateIdx (IN BYTE byRate)
+{
+    BYTE    byRateIdx;
+
+    for (byRateIdx = 0; byRateIdx <MAX_RATE ; byRateIdx++) {
+        if (acbyRxRate[byRateIdx%MAX_RATE] == byRate)
+            return byRateIdx;
+    }
+    return 0;
+}
+
+
+static
+VOID
+s_vGetDASA (
+    IN  PBYTE pbyRxBufferAddr,
+    OUT PUINT pcbHeaderSize,
+    OUT PSEthernetHeader psEthHeader
+    )
+{
+    UINT            cbHeaderSize = 0;
+    PS802_11Header  pMACHeader;
+    int             ii;
+
+    pMACHeader = (PS802_11Header) (pbyRxBufferAddr + cbHeaderSize);
+
+    if ((pMACHeader->wFrameCtl & FC_TODS) == 0) {
+        if (pMACHeader->wFrameCtl & FC_FROMDS) {
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr3[ii];
+            }
+        }
+        else {
+            // IBSS mode
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr1[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
+            }
+        }
+    }
+    else {
+        // Is AP mode..
+        if (pMACHeader->wFrameCtl & FC_FROMDS) {
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr4[ii];
+                cbHeaderSize += 6;
+            }
+        }
+        else {
+            for(ii=0;ii<U_ETHER_ADDR_LEN;ii++) {
+                psEthHeader->abyDstAddr[ii] = pMACHeader->abyAddr3[ii];
+                psEthHeader->abySrcAddr[ii] = pMACHeader->abyAddr2[ii];
+            }
+        }
+    };
+    *pcbHeaderSize = cbHeaderSize;
+}
+
+
+
+
+BOOL
+RXbBulkInProcessData (
+    IN PSDevice         pDevice,
+    IN PRCB             pRCB,
+    IN ULONG            BytesToIndicate
+    )
+{
+
+    struct net_device_stats* pStats=&pDevice->stats;
+    struct sk_buff* skb;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PSRxMgmtPacket  pRxPacket = &(pMgmt->sRxPacket);
+    PS802_11Header  p802_11Header;
+    PBYTE           pbyRsr;
+    PBYTE           pbyNewRsr;
+    PBYTE           pbyRSSI;
+    PQWORD          pqwTSFTime;
+    PBYTE           pbyFrame;
+    BOOL            bDeFragRx = FALSE;
+    UINT            cbHeaderOffset;
+    UINT            FrameSize;
+    WORD            wEtherType = 0;
+    INT             iSANodeIndex = -1;
+    INT             iDANodeIndex = -1;
+    UINT            ii;
+    UINT            cbIVOffset;
+    PBYTE           pbyRxSts;
+    PBYTE           pbyRxRate;
+    PBYTE           pbySQ;
+#ifdef Calcu_LinkQual
+    PBYTE           pby3SQ;
+#endif
+    UINT            cbHeaderSize;
+    PSKeyItem       pKey = NULL;
+    WORD            wRxTSC15_0 = 0;
+    DWORD           dwRxTSC47_16 = 0;
+    SKeyItem        STempKey;
+    // 802.11h RPI
+    //LONG            ldBm = 0;
+    BOOL            bIsWEP = FALSE;
+    BOOL            bExtIV = FALSE;
+    DWORD           dwWbkStatus;
+    PRCB            pRCBIndicate = pRCB;
+    PBYTE           pbyDAddress;
+    PWORD           pwPLCP_Length;
+    BYTE            abyVaildRate[MAX_RATE] = {2,4,11,22,12,18,24,36,48,72,96,108};
+    WORD            wPLCPwithPadding;
+    PS802_11Header  pMACHeader;
+    BOOL            bRxeapol_key = FALSE;
+
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- RXbBulkInProcessData---\n");
+
+    skb = pRCB->skb;
+
+    //[31:16]RcvByteCount ( not include 4-byte Status )
+    dwWbkStatus =  *( (PDWORD)(skb->data) );
+    FrameSize = (UINT)(dwWbkStatus >> 16);
+    FrameSize += 4;
+
+    if (BytesToIndicate != FrameSize) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n");
+        return FALSE;
+    }
+
+    if ((BytesToIndicate > 2372)||(BytesToIndicate <= 40)) {
+        // Frame Size error drop this packet.
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 2 \n");
+        return FALSE;
+    }
+
+    pbyDAddress = (PBYTE)(skb->data);
+    pbyRxSts = pbyDAddress+4;
+    pbyRxRate = pbyDAddress+5;
+
+    //real Frame Size = USBFrameSize -4WbkStatus - 4RxStatus - 8TSF - 4RSR - 4SQ3 - ?Padding
+    //if SQ3 the range is 24~27, if no SQ3 the range is 20~23
+    //real Frame size in PLCPLength field.
+    pwPLCP_Length = (PWORD) (pbyDAddress + 6);
+    //Fix hardware bug => PLCP_Length error
+    if ( ((BytesToIndicate - (*pwPLCP_Length)) > 27) ||
+         ((BytesToIndicate - (*pwPLCP_Length)) < 24) ||
+         (BytesToIndicate < (*pwPLCP_Length)) ) {
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong PLCP Length %x\n", (int) *pwPLCP_Length);
+        ASSERT(0);
+        return FALSE;
+    }
+    for ( ii=RATE_1M;ii<MAX_RATE;ii++) {
+        if ( *pbyRxRate == abyVaildRate[ii] ) {
+            break;
+        }
+    }
+    if ( ii==MAX_RATE ) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Wrong RxRate %x\n",(int) *pbyRxRate);
+        return FALSE;
+    }
+
+    wPLCPwithPadding = ( (*pwPLCP_Length / 4) + ( (*pwPLCP_Length % 4) ? 1:0 ) ) *4;
+
+    pqwTSFTime = (PQWORD) (pbyDAddress + 8 + wPLCPwithPadding);
+#ifdef Calcu_LinkQual
+  if(pDevice->byBBType == BB_TYPE_11G)  {
+      pby3SQ = pbyDAddress + 8 + wPLCPwithPadding + 12;
+      pbySQ = pby3SQ;
+    }
+  else {
+   pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
+   pby3SQ = pbySQ;
+  }
+#else
+    pbySQ = pbyDAddress + 8 + wPLCPwithPadding + 8;
+#endif
+    pbyNewRsr = pbyDAddress + 8 + wPLCPwithPadding + 9;
+    pbyRSSI = pbyDAddress + 8 + wPLCPwithPadding + 10;
+    pbyRsr = pbyDAddress + 8 + wPLCPwithPadding + 11;
+
+    FrameSize = *pwPLCP_Length;
+
+    pbyFrame = pbyDAddress + 8;
+    // update receive statistic counter
+
+    STAvUpdateRDStatCounter(&pDevice->scStatistic,
+                            *pbyRsr,
+                            *pbyNewRsr,
+                            *pbyRxSts,
+                            *pbyRxRate,
+                            pbyFrame,
+                            FrameSize
+                            );
+
+
+    pMACHeader = (PS802_11Header) pbyFrame;
+
+//mike add: to judge if current AP is activated?
+    if ((pMgmt->eCurrMode == WMAC_MODE_STANDBY) ||
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_STA)) {
+       if (pMgmt->sNodeDBTable[0].bActive) {
+         if(IS_ETH_ADDRESS_EQUAL (pMgmt->abyCurrBSSID, pMACHeader->abyAddr2) ) {
+	    if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
+                  pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+           }
+       }
+    }
+
+    if (!IS_MULTICAST_ADDRESS(pMACHeader->abyAddr1) && !IS_BROADCAST_ADDRESS(pMACHeader->abyAddr1)) {
+        if ( WCTLbIsDuplicate(&(pDevice->sDupRxCache), (PS802_11Header) pbyFrame) ) {
+            pDevice->s802_11Counter.FrameDuplicateCount++;
+            return FALSE;
+        }
+
+        if ( !IS_ETH_ADDRESS_EQUAL (pDevice->abyCurrentNetAddr, pMACHeader->abyAddr1) ) {
+            return FALSE;
+        }
+    }
+
+
+    // Use for TKIP MIC
+    s_vGetDASA(pbyFrame, &cbHeaderSize, &pDevice->sRxEthHeader);
+
+    if (IS_ETH_ADDRESS_EQUAL((PBYTE)&(pDevice->sRxEthHeader.abySrcAddr[0]), pDevice->abyCurrentNetAddr))
+        return FALSE;
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) || (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)) {
+        if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
+            p802_11Header = (PS802_11Header) (pbyFrame);
+            // get SA NodeIndex
+            if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p802_11Header->abyAddr2), &iSANodeIndex)) {
+                pMgmt->sNodeDBTable[iSANodeIndex].ulLastRxJiffer = jiffies;
+                pMgmt->sNodeDBTable[iSANodeIndex].uInActiveCount = 0;
+            }
+        }
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (s_bAPModeRxCtl(pDevice, pbyFrame, iSANodeIndex) == TRUE) {
+            return FALSE;
+        }
+    }
+
+
+    if (IS_FC_WEP(pbyFrame)) {
+        BOOL     bRxDecryOK = FALSE;
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"rx WEP pkt\n");
+        bIsWEP = TRUE;
+        if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) {
+            pKey = &STempKey;
+            pKey->byCipherSuite = pMgmt->sNodeDBTable[iSANodeIndex].byCipherSuite;
+            pKey->dwKeyIndex = pMgmt->sNodeDBTable[iSANodeIndex].dwKeyIndex;
+            pKey->uKeyLength = pMgmt->sNodeDBTable[iSANodeIndex].uWepKeyLength;
+            pKey->dwTSC47_16 = pMgmt->sNodeDBTable[iSANodeIndex].dwTSC47_16;
+            pKey->wTSC15_0 = pMgmt->sNodeDBTable[iSANodeIndex].wTSC15_0;
+            memcpy(pKey->abyKey,
+                &pMgmt->sNodeDBTable[iSANodeIndex].abyWepKey[0],
+                pKey->uKeyLength
+                );
+
+            bRxDecryOK = s_bHostWepRxEncryption(pDevice,
+                                                pbyFrame,
+                                                FrameSize,
+                                                pbyRsr,
+                                                pMgmt->sNodeDBTable[iSANodeIndex].bOnFly,
+                                                pKey,
+                                                pbyNewRsr,
+                                                &bExtIV,
+                                                &wRxTSC15_0,
+                                                &dwRxTSC47_16);
+        } else {
+            bRxDecryOK = s_bHandleRxEncryption(pDevice,
+                                                pbyFrame,
+                                                FrameSize,
+                                                pbyRsr,
+                                                pbyNewRsr,
+                                                &pKey,
+                                                &bExtIV,
+                                                &wRxTSC15_0,
+                                                &dwRxTSC47_16);
+        }
+
+        if (bRxDecryOK) {
+            if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV Fail\n");
+                if ( (pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                    (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+
+                    if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+                        pDevice->s802_11Counter.TKIPICVErrors++;
+                    } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) {
+                        pDevice->s802_11Counter.CCMPDecryptErrors++;
+                    } else if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_WEP)) {
+//                      pDevice->s802_11Counter.WEPICVErrorCount.QuadPart++;
+                    }
+                }
+                return FALSE;
+            }
+        } else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WEP Func Fail\n");
+            return FALSE;
+        }
+        if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP))
+            FrameSize -= 8;         // Message Integrity Code
+        else
+            FrameSize -= 4;         // 4 is ICV
+    }
+
+
+    //
+    // RX OK
+    //
+    //remove the CRC length
+    FrameSize -= U_CRC_LEN;
+
+    if ( !(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) && // unicast address
+        (IS_FRAGMENT_PKT((pbyFrame)))
+        ) {
+        // defragment
+        bDeFragRx = WCTLbHandleFragment(pDevice, (PS802_11Header) (pbyFrame), FrameSize, bIsWEP, bExtIV);
+        pDevice->s802_11Counter.ReceivedFragmentCount++;
+        if (bDeFragRx) {
+            // defrag complete
+            // TODO skb, pbyFrame
+            skb = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb;
+            FrameSize = pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength;
+            pbyFrame = skb->data + 8;
+        }
+        else {
+            return FALSE;
+        }
+    }
+
+    //
+    // Management & Control frame Handle
+    //
+    if ((IS_TYPE_DATA((pbyFrame))) == FALSE) {
+        // Handle Control & Manage Frame
+
+        if (IS_TYPE_MGMT((pbyFrame))) {
+            PBYTE pbyData1;
+            PBYTE pbyData2;
+
+            pRxPacket = &(pRCB->sMngPacket);
+            pRxPacket->p80211Header = (PUWLAN_80211HDR)(pbyFrame);
+            pRxPacket->cbMPDULen = FrameSize;
+            pRxPacket->uRSSI = *pbyRSSI;
+            pRxPacket->bySQ = *pbySQ;
+            HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime));
+            LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime));
+            if (bIsWEP) {
+                // strip IV
+                pbyData1 = WLAN_HDR_A3_DATA_PTR(pbyFrame);
+                pbyData2 = WLAN_HDR_A3_DATA_PTR(pbyFrame) + 4;
+                for (ii = 0; ii < (FrameSize - 4); ii++) {
+                    *pbyData1 = *pbyData2;
+                     pbyData1++;
+                     pbyData2++;
+                }
+            }
+
+            pRxPacket->byRxRate = s_byGetRateIdx(*pbyRxRate);
+
+            if ( *pbyRxSts == 0 ) {
+                //Discard beacon packet which channel is 0
+                if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) ||
+                     (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) {
+                    return TRUE;
+                }
+            }
+            pRxPacket->byRxChannel = (*pbyRxSts) >> 2;
+
+            // hostap Deamon handle 802.11 management
+            if (pDevice->bEnableHostapd) {
+	            skb->dev = pDevice->apdev;
+	            //skb->data += 4;
+	            //skb->tail += 4;
+	            skb->data += 8;
+	            skb->tail += 8;
+                skb_put(skb, FrameSize);
+		skb_reset_mac_header(skb);
+	            skb->pkt_type = PACKET_OTHERHOST;
+    	        skb->protocol = htons(ETH_P_802_2);
+	            memset(skb->cb, 0, sizeof(skb->cb));
+	            netif_rx(skb);
+                return TRUE;
+	        }
+
+            //
+            // Insert the RCB in the Recv Mng list
+            //
+            EnqueueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList, pRCBIndicate);
+            pDevice->NumRecvMngList++;
+            if ( bDeFragRx == FALSE) {
+                pRCB->Ref++;
+            }
+            if (pDevice->bIsRxMngWorkItemQueued == FALSE) {
+                pDevice->bIsRxMngWorkItemQueued = TRUE;
+                tasklet_schedule(&pDevice->RxMngWorkItem);
+            }
+
+        }
+        else {
+            // Control Frame
+        };
+        return FALSE;
+    }
+    else {
+        if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+            //In AP mode, hw only check addr1(BSSID or RA) if equal to local MAC.
+            if ( !(*pbyRsr & RSR_BSSIDOK)) {
+                if (bDeFragRx) {
+                    if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                        pDevice->dev->name);
+                    }
+                }
+                return FALSE;
+            }
+        }
+        else {
+            // discard DATA packet while not associate || BSSID error
+            if ((pDevice->bLinkPass == FALSE) ||
+                !(*pbyRsr & RSR_BSSIDOK)) {
+                if (bDeFragRx) {
+                    if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                        pDevice->dev->name);
+                    }
+                }
+                return FALSE;
+            }
+   //mike add:station mode check eapol-key challenge--->
+   	  {
+   	    BYTE  Protocol_Version;    //802.1x Authentication
+	    BYTE  Packet_Type;           //802.1x Authentication
+	    BYTE  Descriptor_type;
+             WORD Key_info;
+              if (bIsWEP)
+                  cbIVOffset = 8;
+              else
+                  cbIVOffset = 0;
+              wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
+                          skb->data[cbIVOffset + 8 + 24 + 6 + 1];
+	      Protocol_Version = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1];
+	      Packet_Type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1];
+	     if (wEtherType == ETH_P_PAE) {         //Protocol Type in LLC-Header
+                  if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
+		     (Packet_Type==3)) {  //802.1x OR eapol-key challenge frame receive
+                        bRxeapol_key = TRUE;
+		      Descriptor_type = skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2];
+		      Key_info = (skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+1]<<8) |skb->data[cbIVOffset + 8 + 24 + 6 + 1 +1+1+1+2+2] ;
+		      if(Descriptor_type==2) {    //RSN
+                         //  printk("WPA2_Rx_eapol-key_info<-----:%x\n",Key_info);
+		      }
+		     else  if(Descriptor_type==254) {
+                        //  printk("WPA_Rx_eapol-key_info<-----:%x\n",Key_info);
+		     }
+                  }
+	      }
+   	  }
+    //mike add:station mode check eapol-key challenge<---
+        }
+    }
+
+
+// Data frame Handle
+
+
+    if (pDevice->bEnablePSMode) {
+        if (IS_FC_MOREDATA((pbyFrame))) {
+            if (*pbyRsr & RSR_ADDROK) {
+                //PSbSendPSPOLL((PSDevice)pDevice);
+            }
+        }
+        else {
+            if (pMgmt->bInTIMWake == TRUE) {
+                pMgmt->bInTIMWake = FALSE;
+            }
+        }
+    };
+
+    // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
+    if (pDevice->bDiversityEnable && (FrameSize>50) &&
+       (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
+       (pDevice->bLinkPass == TRUE)) {
+        BBvAntennaDiversity(pDevice, s_byGetRateIdx(*pbyRxRate), 0);
+    }
+
+    // ++++++++ For BaseBand Algorithm +++++++++++++++
+    pDevice->uCurrRSSI = *pbyRSSI;
+    pDevice->byCurrSQ = *pbySQ;
+
+    // todo
+/*
+    if ((*pbyRSSI != 0) &&
+        (pMgmt->pCurrBSS!=NULL)) {
+        RFvRSSITodBm(pDevice, *pbyRSSI, &ldBm);
+        // Moniter if RSSI is too strong.
+        pMgmt->pCurrBSS->byRSSIStatCnt++;
+        pMgmt->pCurrBSS->byRSSIStatCnt %= RSSI_STAT_COUNT;
+        pMgmt->pCurrBSS->ldBmAverage[pMgmt->pCurrBSS->byRSSIStatCnt] = ldBm;
+        for(ii=0;ii<RSSI_STAT_COUNT;ii++) {
+            if (pMgmt->pCurrBSS->ldBmAverage[ii] != 0) {
+            pMgmt->pCurrBSS->ldBmMAX = max(pMgmt->pCurrBSS->ldBmAverage[ii], ldBm);
+            }
+        }
+    }
+*/
+
+
+    // -----------------------------------------------
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnable8021x == TRUE)){
+        BYTE    abyMacHdr[24];
+
+        // Only 802.1x packet incoming allowed
+        if (bIsWEP)
+            cbIVOffset = 8;
+        else
+            cbIVOffset = 0;
+        wEtherType = (skb->data[cbIVOffset + 8 + 24 + 6] << 8) |
+                    skb->data[cbIVOffset + 8 + 24 + 6 + 1];
+
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wEtherType = %04x \n", wEtherType);
+        if (wEtherType == ETH_P_PAE) {
+            skb->dev = pDevice->apdev;
+
+            if (bIsWEP == TRUE) {
+                // strip IV header(8)
+                memcpy(&abyMacHdr[0], (skb->data + 8), 24);
+                memcpy((skb->data + 8 + cbIVOffset), &abyMacHdr[0], 24);
+            }
+
+            skb->data +=  (cbIVOffset + 8);
+            skb->tail +=  (cbIVOffset + 8);
+            skb_put(skb, FrameSize);
+	    skb_reset_mac_header(skb);
+            skb->pkt_type = PACKET_OTHERHOST;
+            skb->protocol = htons(ETH_P_802_2);
+            memset(skb->cb, 0, sizeof(skb->cb));
+            netif_rx(skb);
+            return TRUE;
+
+        }
+        // check if 802.1x authorized
+        if (!(pMgmt->sNodeDBTable[iSANodeIndex].dwFlags & WLAN_STA_AUTHORIZED))
+            return FALSE;
+    }
+
+
+    if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+        if (bIsWEP) {
+            FrameSize -= 8;  //MIC
+        }
+    }
+
+    //--------------------------------------------------------------------------------
+    // Soft MIC
+    if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_TKIP)) {
+        if (bIsWEP) {
+            PDWORD          pdwMIC_L;
+            PDWORD          pdwMIC_R;
+            DWORD           dwMIC_Priority;
+            DWORD           dwMICKey0 = 0, dwMICKey1 = 0;
+            DWORD           dwLocalMIC_L = 0;
+            DWORD           dwLocalMIC_R = 0;
+            viawget_wpa_header *wpahdr;
+
+
+            if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+                dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24]));
+                dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28]));
+            }
+            else {
+                if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16]));
+                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20]));
+                } else if ((pKey->dwKeyIndex & BIT28) == 0) {
+                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[16]));
+                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[20]));
+                } else {
+                    dwMICKey0 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[24]));
+                    dwMICKey1 = cpu_to_le32(*(PDWORD)(&pKey->abyKey[28]));
+                }
+            }
+
+            MIC_vInit(dwMICKey0, dwMICKey1);
+            MIC_vAppend((PBYTE)&(pDevice->sRxEthHeader.abyDstAddr[0]), 12);
+            dwMIC_Priority = 0;
+            MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+            // 4 is Rcv buffer header, 24 is MAC Header, and 8 is IV and Ext IV.
+            MIC_vAppend((PBYTE)(skb->data + 8 + WLAN_HDR_ADDR3_LEN + 8),
+                        FrameSize - WLAN_HDR_ADDR3_LEN - 8);
+            MIC_vGetMIC(&dwLocalMIC_L, &dwLocalMIC_R);
+            MIC_vUnInit();
+
+            pdwMIC_L = (PDWORD)(skb->data + 8 + FrameSize);
+            pdwMIC_R = (PDWORD)(skb->data + 8 + FrameSize + 4);
+
+
+            if ((cpu_to_le32(*pdwMIC_L) != dwLocalMIC_L) || (cpu_to_le32(*pdwMIC_R) != dwLocalMIC_R) ||
+                (pDevice->bRxMICFail == TRUE)) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC comparison is fail!\n");
+                pDevice->bRxMICFail = FALSE;
+                //pDevice->s802_11Counter.TKIPLocalMICFailures.QuadPart++;
+                pDevice->s802_11Counter.TKIPLocalMICFailures++;
+                if (bDeFragRx) {
+                    if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                            pDevice->dev->name);
+                    }
+                }
+		//2008-0409-07, <Add> by Einsn Liu
+       #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+				//send event to wpa_supplicant
+				//if(pDevice->bWPASuppWextEnabled == TRUE)
+				{
+					union iwreq_data wrqu;
+					struct iw_michaelmicfailure ev;
+					int keyidx = pbyFrame[cbHeaderSize+3] >> 6; //top two-bits
+					memset(&ev, 0, sizeof(ev));
+					ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
+					if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+							(pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
+								(*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
+						ev.flags |= IW_MICFAILURE_PAIRWISE;
+					} else {
+						ev.flags |= IW_MICFAILURE_GROUP;
+					}
+
+					ev.src_addr.sa_family = ARPHRD_ETHER;
+					memcpy(ev.src_addr.sa_data, pMACHeader->abyAddr2, ETH_ALEN);
+					memset(&wrqu, 0, sizeof(wrqu));
+					wrqu.data.length = sizeof(ev);
+			PRINT_K("wireless_send_event--->IWEVMICHAELMICFAILURE\n");
+					wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev);
+
+				}
+         #endif
+
+
+                if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+                     wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                         (pMgmt->eCurrState == WMAC_STATE_ASSOC) &&
+                         (*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) {
+                         //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR;
+                         wpahdr->type = VIAWGET_PTK_MIC_MSG;
+                     } else {
+                         //s802_11_Status.Flags = NDIS_802_11_AUTH_REQUEST_GROUP_ERROR;
+                         wpahdr->type = VIAWGET_GTK_MIC_MSG;
+                     }
+                     wpahdr->resp_ie_len = 0;
+                     wpahdr->req_ie_len = 0;
+                     skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+                     pDevice->skb->dev = pDevice->wpadev;
+		     skb_reset_mac_header(pDevice->skb);
+                     pDevice->skb->pkt_type = PACKET_HOST;
+                     pDevice->skb->protocol = htons(ETH_P_802_2);
+                     memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+                     netif_rx(pDevice->skb);
+                     pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+                 };
+
+                return FALSE;
+
+            }
+        }
+    } //---end of SOFT MIC-----------------------------------------------------------------------
+
+    // ++++++++++ Reply Counter Check +++++++++++++
+
+    if ((pKey != NULL) && ((pKey->byCipherSuite == KEY_CTL_TKIP) ||
+                           (pKey->byCipherSuite == KEY_CTL_CCMP))) {
+        if (bIsWEP) {
+            WORD        wLocalTSC15_0 = 0;
+            DWORD       dwLocalTSC47_16 = 0;
+            ULONGLONG       RSC = 0;
+            // endian issues
+            RSC = *((ULONGLONG *) &(pKey->KeyRSC));
+            wLocalTSC15_0 = (WORD) RSC;
+            dwLocalTSC47_16 = (DWORD) (RSC>>16);
+
+            RSC = dwRxTSC47_16;
+            RSC <<= 16;
+            RSC += wRxTSC15_0;
+            memcpy(&(pKey->KeyRSC), &RSC,  sizeof(QWORD));
+
+            if ( (pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) &&
+                 (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) {
+                // check RSC
+                if ( (wRxTSC15_0 < wLocalTSC15_0) &&
+                     (dwRxTSC47_16 <= dwLocalTSC47_16) &&
+                     !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC is illegal~~!\n ");
+                    if (pKey->byCipherSuite == KEY_CTL_TKIP)
+                        //pDevice->s802_11Counter.TKIPReplays.QuadPart++;
+                        pDevice->s802_11Counter.TKIPReplays++;
+                    else
+                        //pDevice->s802_11Counter.CCMPReplays.QuadPart++;
+                        pDevice->s802_11Counter.CCMPReplays++;
+
+                    if (bDeFragRx) {
+                        if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                                pDevice->dev->name);
+                        }
+                    }
+                    return FALSE;
+                }
+            }
+        }
+    } // ----- End of Reply Counter Check --------------------------
+
+
+    s_vProcessRxMACHeader(pDevice, (PBYTE)(skb->data+8), FrameSize, bIsWEP, bExtIV, &cbHeaderOffset);
+    FrameSize -= cbHeaderOffset;
+    cbHeaderOffset += 8;        // 8 is Rcv buffer header
+
+    // Null data, framesize = 12
+    if (FrameSize < 12)
+        return FALSE;
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (s_bAPModeRxData(pDevice,
+                            skb,
+                            FrameSize,
+                            cbHeaderOffset,
+                            iSANodeIndex,
+                            iDANodeIndex
+                            ) == FALSE) {
+
+            if (bDeFragRx) {
+                if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+                    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                    pDevice->dev->name);
+                }
+            }
+            return FALSE;
+        }
+
+    }
+
+	skb->data += cbHeaderOffset;
+	skb->tail += cbHeaderOffset;
+    skb_put(skb, FrameSize);
+    skb->protocol=eth_type_trans(skb, skb->dev);
+    skb->ip_summed=CHECKSUM_NONE;
+    pStats->rx_bytes +=skb->len;
+    pStats->rx_packets++;
+    netif_rx(skb);
+    if (bDeFragRx) {
+        if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc more frag bufs\n",
+                pDevice->dev->name);
+        }
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+static BOOL s_bAPModeRxCtl (
+    IN PSDevice pDevice,
+    IN PBYTE    pbyFrame,
+    IN INT      iSANodeIndex
+    )
+{
+    PS802_11Header      p802_11Header;
+    CMD_STATUS          Status;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    if (IS_CTL_PSPOLL(pbyFrame) || !IS_TYPE_CONTROL(pbyFrame)) {
+
+        p802_11Header = (PS802_11Header) (pbyFrame);
+        if (!IS_TYPE_MGMT(pbyFrame)) {
+
+            // Data & PS-Poll packet
+            // check frame class
+            if (iSANodeIndex > 0) {
+                // frame class 3 fliter & checking
+                if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_AUTH) {
+                    // send deauth notification
+                    // reason = (6) class 2 received from nonauth sta
+                    vMgrDeAuthenBeginSta(pDevice,
+                                         pMgmt,
+                                         (PBYTE)(p802_11Header->abyAddr2),
+                                         (WLAN_MGMT_REASON_CLASS2_NONAUTH),
+                                         &Status
+                                         );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
+                    return TRUE;
+                };
+                if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
+                    // send deassoc notification
+                    // reason = (7) class 3 received from nonassoc sta
+                    vMgrDisassocBeginSta(pDevice,
+                                         pMgmt,
+                                         (PBYTE)(p802_11Header->abyAddr2),
+                                         (WLAN_MGMT_REASON_CLASS3_NONASSOC),
+                                         &Status
+                                         );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
+                    return TRUE;
+                };
+
+                if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
+                    // delcare received ps-poll event
+                    if (IS_CTL_PSPOLL(pbyFrame)) {
+                        pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n");
+                    }
+                    else {
+                        // check Data PS state
+                        // if PW bit off, send out all PS bufferring packets.
+                        if (!IS_FC_POWERMGT(pbyFrame)) {
+                            pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
+                            pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                            bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n");
+                        }
+                    }
+                }
+                else {
+                   if (IS_FC_POWERMGT(pbyFrame)) {
+                       pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = TRUE;
+                       // Once if STA in PS state, enable multicast bufferring
+                       pMgmt->sNodeDBTable[0].bPSEnable = TRUE;
+                   }
+                   else {
+                      // clear all pending PS frame.
+                      if (pMgmt->sNodeDBTable[iSANodeIndex].wEnQueueCnt > 0) {
+                          pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = FALSE;
+                          pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = TRUE;
+                          bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n");
+
+                      }
+                   }
+                }
+            }
+            else {
+                  vMgrDeAuthenBeginSta(pDevice,
+                                       pMgmt,
+                                       (PBYTE)(p802_11Header->abyAddr2),
+                                       (WLAN_MGMT_REASON_CLASS2_NONAUTH),
+                                       &Status
+                                       );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                                p802_11Header->abyAddr3[0],
+                                p802_11Header->abyAddr3[1],
+                                p802_11Header->abyAddr3[2],
+                                p802_11Header->abyAddr3[3],
+                                p802_11Header->abyAddr3[4],
+                                p802_11Header->abyAddr3[5]
+                               );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                                p802_11Header->abyAddr2[0],
+                                p802_11Header->abyAddr2[1],
+                                p802_11Header->abyAddr2[2],
+                                p802_11Header->abyAddr2[3],
+                                p802_11Header->abyAddr2[4],
+                                p802_11Header->abyAddr2[5]
+                               );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                                p802_11Header->abyAddr1[0],
+                                p802_11Header->abyAddr1[1],
+                                p802_11Header->abyAddr1[2],
+                                p802_11Header->abyAddr1[3],
+                                p802_11Header->abyAddr1[4],
+                                p802_11Header->abyAddr1[5]
+                               );
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl );
+                    return TRUE;
+            }
+        }
+    }
+    return FALSE;
+
+}
+
+static BOOL s_bHandleRxEncryption (
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    OUT PBYTE       pbyNewRsr,
+    OUT PSKeyItem   *pKeyOut,
+    int *       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+    )
+{
+    UINT            PayloadLen = FrameSize;
+    PBYTE           pbyIV;
+    BYTE            byKeyIdx;
+    PSKeyItem       pKey = NULL;
+    BYTE            byDecMode = KEY_CTL_WEP;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+
+    *pwRxTSC15_0 = 0;
+    *pdwRxTSC47_16 = 0;
+
+    pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+         pbyIV += 6;             // 6 is 802.11 address4
+         PayloadLen -= 6;
+    }
+    byKeyIdx = (*(pbyIV+3) & 0xc0);
+    byKeyIdx >>= 6;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+
+    if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+        (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {
+        if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) &&
+            (pMgmt->byCSSPK != KEY_CTL_NONE)) {
+            // unicast pkt use pairwise key
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt\n");
+            if (KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, 0xFFFFFFFF, &pKey) == TRUE) {
+                if (pMgmt->byCSSPK == KEY_CTL_TKIP)
+                    byDecMode = KEY_CTL_TKIP;
+                else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
+                    byDecMode = KEY_CTL_CCMP;
+            }
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"unicast pkt: %d, %p\n", byDecMode, pKey);
+        } else {
+            // use group key
+            KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey);
+            if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+                byDecMode = KEY_CTL_TKIP;
+            else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+                byDecMode = KEY_CTL_CCMP;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey);
+        }
+    }
+    // our WEP only support Default Key
+    if (pKey == NULL) {
+        // use default group key
+        KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, byKeyIdx, &pKey);
+        if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+            byDecMode = KEY_CTL_TKIP;
+        else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+            byDecMode = KEY_CTL_CCMP;
+    }
+    *pKeyOut = pKey;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
+
+    if (pKey == NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey == NULL\n");
+        if (byDecMode == KEY_CTL_WEP) {
+//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+        } else if (pDevice->bLinkPass == TRUE) {
+//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+        }
+        return FALSE;
+    }
+    if (byDecMode != pKey->byCipherSuite) {
+        if (byDecMode == KEY_CTL_WEP) {
+//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+        } else if (pDevice->bLinkPass == TRUE) {
+//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+        }
+        *pKeyOut = NULL;
+        return FALSE;
+    }
+    if (byDecMode == KEY_CTL_WEP) {
+        // handle WEP
+        if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
+            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE)) {
+            // Software WEP
+            // 1. 3253A
+            // 2. WEP 256
+
+            PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
+            memcpy(pDevice->abyPRNG, pbyIV, 3);
+            memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
+            rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
+
+            if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
+                *pbyNewRsr |= NEWRSR_DECRYPTOK;
+            }
+        }
+    } else if ((byDecMode == KEY_CTL_TKIP) ||
+               (byDecMode == KEY_CTL_CCMP)) {
+        // TKIP/AES
+
+        PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
+        *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+        if (byDecMode == KEY_CTL_TKIP) {
+            *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+        } else {
+            *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+
+        if ((byDecMode == KEY_CTL_TKIP) &&
+            (pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+            // Software TKIP
+            // 1. 3253 A
+            PS802_11Header  pMACHeader = (PS802_11Header) (pbyFrame);
+            TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+            rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
+            if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
+                *pbyNewRsr |= NEWRSR_DECRYPTOK;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+            } else {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+            }
+        }
+    }// end of TKIP/AES
+
+    if ((*(pbyIV+3) & 0x20) != 0)
+        *pbExtIV = TRUE;
+    return TRUE;
+}
+
+
+static BOOL s_bHostWepRxEncryption (
+    IN PSDevice     pDevice,
+    IN PBYTE        pbyFrame,
+    IN UINT         FrameSize,
+    IN PBYTE        pbyRsr,
+    IN BOOL         bOnFly,
+    IN PSKeyItem    pKey,
+    OUT PBYTE       pbyNewRsr,
+    int *       pbExtIV,
+    OUT PWORD       pwRxTSC15_0,
+    OUT PDWORD      pdwRxTSC47_16
+    )
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            PayloadLen = FrameSize;
+    PBYTE           pbyIV;
+    BYTE            byKeyIdx;
+    BYTE            byDecMode = KEY_CTL_WEP;
+    PS802_11Header  pMACHeader;
+
+
+
+    *pwRxTSC15_0 = 0;
+    *pdwRxTSC47_16 = 0;
+
+    pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN;
+    if ( WLAN_GET_FC_TODS(*(PWORD)pbyFrame) &&
+         WLAN_GET_FC_FROMDS(*(PWORD)pbyFrame) ) {
+         pbyIV += 6;             // 6 is 802.11 address4
+         PayloadLen -= 6;
+    }
+    byKeyIdx = (*(pbyIV+3) & 0xc0);
+    byKeyIdx >>= 6;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\nKeyIdx: %d\n", byKeyIdx);
+
+
+    if (pMgmt->byCSSGK == KEY_CTL_TKIP)
+        byDecMode = KEY_CTL_TKIP;
+    else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
+        byDecMode = KEY_CTL_CCMP;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"AES:%d %d %d\n", pMgmt->byCSSPK, pMgmt->byCSSGK, byDecMode);
+
+    if (byDecMode != pKey->byCipherSuite) {
+        if (byDecMode == KEY_CTL_WEP) {
+//            pDevice->s802_11Counter.WEPUndecryptableCount.QuadPart++;
+        } else if (pDevice->bLinkPass == TRUE) {
+//            pDevice->s802_11Counter.DecryptFailureCount.QuadPart++;
+        }
+        return FALSE;
+    }
+
+    if (byDecMode == KEY_CTL_WEP) {
+        // handle WEP
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n");
+        if ((pDevice->byLocalID <= REV_ID_VT3253_A1) ||
+            (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE) ||
+            (bOnFly == FALSE)) {
+            // Software WEP
+            // 1. 3253A
+            // 2. WEP 256
+            // 3. NotOnFly
+
+            PayloadLen -= (WLAN_HDR_ADDR3_LEN + 4 + 4); // 24 is 802.11 header,4 is IV, 4 is crc
+            memcpy(pDevice->abyPRNG, pbyIV, 3);
+            memcpy(pDevice->abyPRNG + 3, pKey->abyKey, pKey->uKeyLength);
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, pKey->uKeyLength + 3);
+            rc4_encrypt(&pDevice->SBox, pbyIV+4, pbyIV+4, PayloadLen);
+
+            if (ETHbIsBufferCrc32Ok(pbyIV+4, PayloadLen)) {
+                *pbyNewRsr |= NEWRSR_DECRYPTOK;
+            }
+        }
+    } else if ((byDecMode == KEY_CTL_TKIP) ||
+               (byDecMode == KEY_CTL_CCMP)) {
+        // TKIP/AES
+
+        PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc
+        *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16);
+
+        if (byDecMode == KEY_CTL_TKIP) {
+            *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV));
+        } else {
+            *pwRxTSC15_0 = cpu_to_le16(*(PWORD)pbyIV);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"TSC0_15: %x\n", *pwRxTSC15_0);
+
+        if (byDecMode == KEY_CTL_TKIP) {
+
+            if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (bOnFly == FALSE)) {
+                // Software TKIP
+                // 1. 3253 A
+                // 2. NotOnFly
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_TKIP \n");
+                pMACHeader = (PS802_11Header) (pbyFrame);
+                TKIPvMixKey(pKey->abyKey, pMACHeader->abyAddr2, *pwRxTSC15_0, *pdwRxTSC47_16, pDevice->abyPRNG);
+                rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+                rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen);
+                if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) {
+                    *pbyNewRsr |= NEWRSR_DECRYPTOK;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV OK!\n");
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ICV FAIL!!!\n");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PayloadLen = %d\n", PayloadLen);
+                }
+            }
+        }
+
+        if (byDecMode == KEY_CTL_CCMP) {
+            if (bOnFly == FALSE) {
+                // Software CCMP
+                // NotOnFly
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"soft KEY_CTL_CCMP\n");
+                if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) {
+                    *pbyNewRsr |= NEWRSR_DECRYPTOK;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC compare OK!\n");
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"CCMP MIC fail!\n");
+                }
+            }
+        }
+
+    }// end of TKIP/AES
+
+    if ((*(pbyIV+3) & 0x20) != 0)
+        *pbExtIV = TRUE;
+    return TRUE;
+}
+
+
+
+static BOOL s_bAPModeRxData (
+    IN PSDevice pDevice,
+    IN struct sk_buff* skb,
+    IN UINT     FrameSize,
+    IN UINT     cbHeaderOffset,
+    IN INT      iSANodeIndex,
+    IN INT      iDANodeIndex
+    )
+
+{
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    BOOL                bRelayAndForward = FALSE;
+    BOOL                bRelayOnly = FALSE;
+    BYTE                byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    WORD                wAID;
+
+
+    struct sk_buff* skbcpy = NULL;
+
+    if (FrameSize > CB_MAX_BUF_SIZE)
+        return FALSE;
+    // check DA
+    if(IS_MULTICAST_ADDRESS((PBYTE)(skb->data+cbHeaderOffset))) {
+       if (pMgmt->sNodeDBTable[0].bPSEnable) {
+
+           skbcpy = dev_alloc_skb((int)pDevice->rx_buf_sz);
+
+        // if any node in PS mode, buffer packet until DTIM.
+           if (skbcpy == NULL) {
+               DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available \n");
+           }
+           else {
+               skbcpy->dev = pDevice->dev;
+               skbcpy->len = FrameSize;
+               memcpy(skbcpy->data, skb->data+cbHeaderOffset, FrameSize);
+               skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skbcpy);
+               pMgmt->sNodeDBTable[0].wEnQueueCnt++;
+               // set tx map
+               pMgmt->abyPSTxMap[0] |= byMask[0];
+           }
+       }
+       else {
+           bRelayAndForward = TRUE;
+       }
+    }
+    else {
+        // check if relay
+        if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(skb->data+cbHeaderOffset), &iDANodeIndex)) {
+            if (pMgmt->sNodeDBTable[iDANodeIndex].eNodeState >= NODE_ASSOC) {
+                if (pMgmt->sNodeDBTable[iDANodeIndex].bPSEnable) {
+                    // queue this skb until next PS tx, and then release.
+
+	                skb->data += cbHeaderOffset;
+	                skb->tail += cbHeaderOffset;
+                    skb_put(skb, FrameSize);
+                    skb_queue_tail(&pMgmt->sNodeDBTable[iDANodeIndex].sTxPSQueue, skb);
+
+                    pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++;
+                    wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID;
+                    pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n",
+                               iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
+                    return TRUE;
+                }
+                else {
+                    bRelayOnly = TRUE;
+                }
+            }
+        };
+    }
+
+    if (bRelayOnly || bRelayAndForward) {
+        // relay this packet right now
+        if (bRelayAndForward)
+            iDANodeIndex = 0;
+
+        if ((pDevice->uAssocCount > 1) && (iDANodeIndex >= 0)) {
+            bRelayPacketSend(pDevice, (PBYTE)(skb->data + cbHeaderOffset), FrameSize, (UINT)iDANodeIndex);
+        }
+
+        if (bRelayOnly)
+            return FALSE;
+    }
+    // none associate, don't forward
+    if (pDevice->uAssocCount == 0)
+        return FALSE;
+
+    return TRUE;
+}
+
+
+
+
+VOID
+RXvWorkItem(
+    PVOID Context
+    )
+{
+    PSDevice pDevice = (PSDevice) Context;
+    NTSTATUS        ntStatus;
+    PRCB            pRCB=NULL;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Polling Thread\n");
+    spin_lock_irq(&pDevice->lock);
+    while ( MP_TEST_FLAG(pDevice, fMP_POST_READS) &&
+            MP_IS_READY(pDevice) &&
+            (pDevice->NumRecvFreeList != 0) ) {
+        pRCB = pDevice->FirstRecvFreeList;
+        pDevice->NumRecvFreeList--;
+        ASSERT(pRCB);// cannot be NULL
+        DequeueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList);
+        ntStatus = PIPEnsBulkInUsbRead(pDevice, pRCB);
+    }
+    pDevice->bIsRxWorkItemQueued = FALSE;
+    spin_unlock_irq(&pDevice->lock);
+
+}
+
+
+VOID
+RXvFreeRCB(
+    IN PRCB pRCB,
+    IN BOOL bReAllocSkb
+    )
+{
+    PSDevice pDevice = (PSDevice)pRCB->pDevice;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->RXvFreeRCB\n");
+
+    ASSERT(!pRCB->Ref);     // should be 0
+    ASSERT(pRCB->pDevice);  // shouldn't be NULL
+
+    if (bReAllocSkb == TRUE) {
+        pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+        // todo error handling
+        if (pRCB->skb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to re-alloc rx skb\n");
+        }else {
+            pRCB->skb->dev = pDevice->dev;
+        }
+    }
+    //
+    // Insert the RCB back in the Recv free list
+    //
+    EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
+    pDevice->NumRecvFreeList++;
+
+
+    if (MP_TEST_FLAG(pDevice, fMP_POST_READS) && MP_IS_READY(pDevice) &&
+        (pDevice->bIsRxWorkItemQueued == FALSE) ) {
+
+        pDevice->bIsRxWorkItemQueued = TRUE;
+        tasklet_schedule(&pDevice->ReadWorkItem);
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----RXFreeRCB %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+}
+
+
+VOID
+RXvMngWorkItem(
+    PVOID Context
+    )
+{
+    PSDevice pDevice = (PSDevice) Context;
+    PRCB            pRCB=NULL;
+    PSRxMgmtPacket  pRxPacket;
+    BOOL            bReAllocSkb = FALSE;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Rx Mng Thread\n");
+
+    spin_lock_irq(&pDevice->lock);
+    while (pDevice->NumRecvMngList!=0)
+    {
+        pRCB = pDevice->FirstRecvMngList;
+        pDevice->NumRecvMngList--;
+        DequeueRCB(pDevice->FirstRecvMngList, pDevice->LastRecvMngList);
+        if(!pRCB){
+            break;
+        }
+        ASSERT(pRCB);// cannot be NULL
+        pRxPacket = &(pRCB->sMngPacket);
+        vMgrRxManagePacket((HANDLE)pDevice, &(pDevice->sMgmtObj), pRxPacket);
+        pRCB->Ref--;
+        if(pRCB->Ref == 0) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeMng %d %d\n",pDevice->NumRecvFreeList, pDevice->NumRecvMngList);
+            RXvFreeRCB(pRCB, bReAllocSkb);
+        } else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Rx Mng Only we have the right to free RCB\n");
+        }
+    }
+
+    pDevice->bIsRxMngWorkItemQueued = FALSE;
+    spin_unlock_irq(&pDevice->lock);
+
+}
+
+
diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h
new file mode 100644
index 0000000..df148b4
--- /dev/null
+++ b/drivers/staging/vt6656/dpc.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: dpc.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __DPC_H__
+#define __DPC_H__
+
+#include "ttype.h"
+#include "device.h"
+#include "wcmd.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+VOID
+RXvWorkItem(
+    PVOID Context
+    );
+
+VOID
+RXvMngWorkItem(
+    PVOID Context
+    );
+
+VOID
+RXvFreeRCB(
+    IN PRCB pRCB,
+    IN BOOL bReAllocSkb
+    );
+
+BOOL
+RXbBulkInProcessData(
+    IN PSDevice         pDevice,
+    IN PRCB             pRCB,
+    IN ULONG            BytesToIndicate
+    );
+
+#endif // __RXTX_H__
+
+
+
diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c
new file mode 100644
index 0000000..52daa3b
--- /dev/null
+++ b/drivers/staging/vt6656/firmware.c
@@ -0,0 +1,876 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: baseband.c
+ *
+ * Purpose: Implement functions to access baseband
+ *
+ * Author: Yiching Chen
+ *
+ * Date: May 20, 2004
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "firmware.h"
+#include "control.h"
+#include "rndis.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*
+ *  This is firmware version 1.51
+ */
+#define FIRMWARE_VERSION        0x133
+
+const BYTE abyFirmware[] = {
+
+0x02, 0x35, 0x62, 0x02, 0x3B, 0xED, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x3E, 0x21, 0xD2, 0x04,
+0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x21, 0xE0, 0x90, 0x45, 0x39, 0xF0, 0xE0, 0x90,
+0x06, 0x21, 0xF0, 0x90, 0x06, 0x10, 0xE0, 0x54, 0x60, 0x60, 0x03, 0x02, 0x1A, 0xE9, 0xA3, 0xE0,
+0x12, 0x28, 0x7E, 0x18, 0x15, 0x00, 0x18, 0xF6, 0x01, 0x19, 0xD1, 0x03, 0x16, 0x79, 0x05, 0x12,
+0x52, 0x06, 0x17, 0xE5, 0x08, 0x16, 0xAF, 0x09, 0x17, 0x33, 0x0A, 0x17, 0x91, 0x0B, 0x00, 0x00,
+0x1A, 0xE1, 0x90, 0x06, 0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x31,
+0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x05, 0xF0, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0,
+0x90, 0x06, 0x13, 0xE0, 0x24, 0xFE, 0x60, 0x47, 0x14, 0x70, 0x03, 0x02, 0x14, 0x79, 0x24, 0xFD,
+0x60, 0x25, 0x14, 0x70, 0x03, 0x02, 0x13, 0x9C, 0x24, 0x06, 0x60, 0x03, 0x02, 0x16, 0x54, 0x7B,
+0x01, 0x7A, 0x10, 0x79, 0x8B, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0,
+0xA3, 0x74, 0x12, 0xF0, 0x02, 0x16, 0x5C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x81, 0x90, 0x10, 0x46,
+0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x02, 0x16, 0x5C, 0x7B,
+0x01, 0x7A, 0x10, 0x79, 0x51, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x52, 0x74, 0x02,
+0xF0, 0x90, 0x10, 0x54, 0xE0, 0xFE, 0x90, 0x10, 0x53, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x4C, 0xF0,
+0xED, 0xA3, 0xF0, 0x30, 0x06, 0x5A, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5,
+0x83, 0xE4, 0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0,
+0x74, 0x4E, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4F, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10,
+0x97, 0xE0, 0xFB, 0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C,
+0x74, 0x50, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x02, 0x16, 0x5C,
+0x90, 0x10, 0x4D, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40,
+0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4E, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4,
+0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB,
+0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x02, 0x16, 0x5C, 0x7B, 0x01, 0x7A, 0x10,
+0x79, 0x51, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x52, 0x74, 0x07, 0xF0, 0x90, 0x10,
+0x54, 0xE0, 0xFE, 0x90, 0x10, 0x53, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x4C, 0xF0, 0xED, 0xA3, 0xF0,
+0x30, 0x06, 0x59, 0xE0, 0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40,
+0xF0, 0x74, 0x48, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4E, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x40, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4,
+0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB,
+0xEE, 0xEB, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D,
+0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x4D, 0xE0,
+0xFD, 0x24, 0x47, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x48, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x02, 0xF0, 0x74, 0x4E, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
+0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x74, 0x4F, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83, 0x74,
+0x02, 0xF0, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFB, 0xEE, 0xEB, 0xC3, 0x94,
+0x20, 0xEE, 0x94, 0x01, 0x40, 0x03, 0x02, 0x16, 0x5C, 0x74, 0x50, 0x2D, 0xF5, 0x82, 0xE4, 0x34,
+0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x06, 0x12, 0xE0, 0x14, 0x60, 0x2F,
+0x14, 0x70, 0x03, 0x02, 0x15, 0x34, 0x14, 0x70, 0x03, 0x02, 0x15, 0xD5, 0x24, 0x03, 0x60, 0x03,
+0x02, 0x16, 0x4C, 0x7B, 0x01, 0x7A, 0x43, 0x79, 0x1A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x43, 0x1A, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90,
+0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE, 0xED, 0xC3, 0x94, 0x20, 0xEE, 0x94,
+0x01, 0x50, 0x1C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x14, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x10, 0x14, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90,
+0x10, 0x3C, 0xE0, 0xC3, 0x94, 0x01, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22,
+0x90, 0x10, 0x0D, 0xE0, 0x20, 0xE0, 0x1C, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x14, 0x90, 0x10, 0x46,
+0x12, 0x27, 0xBA, 0x90, 0x10, 0x14, 0xE0, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0,
+0x02, 0x16, 0x5C, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF,
+0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE, 0xED,
+0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x50, 0x33, 0x90, 0x10, 0x99, 0xE0, 0x70, 0x0C, 0xA3, 0xE0,
+0x70, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A,
+0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF,
+0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x3C, 0xE0, 0xC3,
+0x94, 0x02, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x0D, 0xE0,
+0x20, 0xE0, 0x21, 0x90, 0x10, 0x2E, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90,
+0x10, 0x2E, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF,
+0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA,
+0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3,
+0xEF, 0xF0, 0x02, 0x16, 0x5C, 0x90, 0x10, 0x98, 0xE0, 0xFE, 0x90, 0x10, 0x97, 0xE0, 0xFD, 0xEE,
+0xED, 0xC3, 0x94, 0x20, 0xEE, 0x94, 0x01, 0x50, 0x32, 0x90, 0x10, 0x99, 0xE0, 0x60, 0x04, 0xA3,
+0xE0, 0x70, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x31, 0x12, 0x27,
+0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26, 0x36,
+0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x41, 0x90, 0x10, 0x3C, 0xE0, 0xC3,
+0x94, 0x03, 0x50, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x31, 0x12,
+0x27, 0x9A, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x31, 0x12, 0x27, 0x9A, 0x12, 0x26,
+0x36, 0xFF, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0xEF, 0xF0, 0x80, 0x10, 0x90, 0x06, 0x22, 0xE0,
+0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x45, 0x31, 0xE0,
+0xFE, 0xA3, 0xE0, 0xFF, 0xD3, 0x90, 0x10, 0x4D, 0xE0, 0x9F, 0x90, 0x10, 0x4C, 0xE0, 0x9E, 0x40,
+0x05, 0xEE, 0xF0, 0xA3, 0xEF, 0xF0, 0x02, 0x33, 0xF6, 0x90, 0x06, 0x12, 0xE0, 0x90, 0x10, 0x3E,
+0xF0, 0x90, 0x10, 0x3D, 0x74, 0x04, 0xF0, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08,
+0xF0, 0xA3, 0xF0, 0x90, 0x10, 0x3E, 0xE0, 0xFF, 0x44, 0x80, 0x90, 0x06, 0x06, 0xF0, 0xEF, 0x70,
+0x07, 0x90, 0x10, 0x38, 0x74, 0x07, 0xF0, 0x22, 0x90, 0x10, 0x38, 0x74, 0x0F, 0xF0, 0x22, 0x90,
+0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED, 0xA3,
+0xF0, 0x90, 0x45, 0x35, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x01, 0x4E, 0x60, 0x0C, 0xEF, 0x4E,
+0x60, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x12, 0xE0, 0x90, 0x10,
+0x3A, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x08, 0x74, 0x02, 0xF0, 0xA3, 0x04,
+0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3,
+0xF0, 0x90, 0x10, 0x3A, 0xE0, 0x70, 0x0D, 0x90, 0x10, 0x38, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x07,
+0x74, 0x02, 0xF0, 0x22, 0x90, 0x10, 0x38, 0x74, 0x1F, 0xF0, 0x90, 0x06, 0x07, 0xE0, 0x44, 0x1C,
+0xF0, 0x90, 0x06, 0x0B, 0x74, 0x70, 0xF0, 0xE4, 0x90, 0x10, 0x34, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0,
+0xA3, 0xF0, 0x22, 0x90, 0x10, 0x38, 0xE0, 0x64, 0x1F, 0x70, 0x4E, 0x90, 0x06, 0x15, 0xE0, 0xFE,
+0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x55,
+0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45, 0x33, 0xE0, 0x94, 0x00, 0x50, 0x21,
+0xE4, 0x90, 0x06, 0x60, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x09, 0xF0, 0xE4, 0x90, 0x10, 0x4C, 0xF0,
+0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x81, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0,
+0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0,
+0x22, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45,
+0x33, 0xF0, 0xED, 0xA3, 0xF0, 0xA3, 0xE0, 0x70, 0x02, 0xA3, 0xE0, 0x70, 0x13, 0x90, 0x10, 0x55,
+0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45, 0x33, 0xE0, 0x94, 0x00, 0x40, 0x08,
+0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74,
+0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x1F, 0x08, 0x90, 0x06, 0x60, 0x74,
+0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0x90, 0x10, 0x3D, 0x74, 0x07, 0xF0, 0xE4,
+0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x81, 0xF0, 0xA3, 0x74,
+0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0x7F, 0x60, 0x14, 0x14, 0x60, 0x4E,
+0x24, 0x02, 0x60, 0x03, 0x02, 0x18, 0xD2, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xA3, 0xF0, 0x02, 0x18,
+0xDA, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x10, 0x55, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x34, 0xE0, 0x9F, 0x90, 0x45,
+0x33, 0xE0, 0x94, 0x00, 0x50, 0x07, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x0F, 0x08, 0x90, 0x06, 0x22,
+0xE0, 0x44, 0x08, 0xF0, 0x22, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xA3, 0xF0, 0x80, 0x6C, 0x90, 0x06,
+0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0,
+0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x81, 0x4E, 0x60, 0x0C, 0xEF, 0x64, 0x82,
+0x4E, 0x60, 0x06, 0xEF, 0x64, 0x03, 0x4E, 0x70, 0x0B, 0x90, 0x10, 0x38, 0xE0, 0xB4, 0x0F, 0x0C,
+0xEF, 0x4E, 0x60, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7E, 0x00, 0xEF, 0x54,
+0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0xE0, 0xB4, 0x01, 0x08, 0x90, 0x06,
+0x60, 0x74, 0x01, 0xF0, 0x80, 0x05, 0xE4, 0x90, 0x06, 0x60, 0xF0, 0xE4, 0x90, 0x06, 0x61, 0xF0,
+0x80, 0x08, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x10, 0x3D, 0x74, 0x01, 0xF0,
+0xE4, 0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x82, 0xF0, 0xA3,
+0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0xFE, 0x60, 0x03, 0x02, 0x19,
+0xBA, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45,
+0x35, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x10, 0x38, 0xE0, 0xF9, 0x64, 0x1F, 0x70, 0x76, 0x90, 0x45,
+0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x81, 0x4E, 0x70, 0x19, 0x90, 0x06, 0x0B, 0xE0, 0x54,
+0xFB, 0xF0, 0x7C, 0x00, 0xEF, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEC, 0x34, 0x10, 0xF5, 0x83,
+0xE4, 0xF0, 0x80, 0x6E, 0xEF, 0x64, 0x82, 0x4E, 0x70, 0x1C, 0x90, 0x06, 0x0B, 0xE0, 0x54, 0xFE,
+0xF0, 0x7E, 0x00, 0x90, 0x45, 0x34, 0xE0, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10,
+0xF5, 0x83, 0xE4, 0xF0, 0x80, 0x4C, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x03,
+0x4E, 0x70, 0x19, 0x90, 0x06, 0x0B, 0xE0, 0x54, 0xFD, 0xF0, 0x7E, 0x00, 0xEF, 0x54, 0x7F, 0x24,
+0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0xE4, 0xF0, 0x80, 0x26, 0x90, 0x06, 0x22, 0xE0,
+0x44, 0x08, 0xF0, 0x22, 0xE9, 0xB4, 0x0F, 0x1A, 0x90, 0x45, 0x33, 0xE0, 0x70, 0x02, 0xA3, 0xE0,
+0x60, 0x10, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08,
+0xF0, 0x22, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0,
+0x22, 0x90, 0x06, 0x10, 0xE0, 0x24, 0xFE, 0x60, 0x44, 0x24, 0x02, 0x60, 0x03, 0x02, 0x1A, 0xCA,
+0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED,
+0xA3, 0xF0, 0x90, 0x45, 0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x02, 0x70, 0x17, 0x90, 0x06,
+0x14, 0xE0, 0x70, 0x11, 0x90, 0x10, 0x3D, 0x74, 0x0F, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0x90, 0x10,
+0x50, 0xF0, 0x02, 0x1A, 0xD2, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x15,
+0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x33, 0xF0, 0xED, 0xA3, 0xF0, 0x90,
+0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x45, 0x35, 0xF0, 0xED, 0xA3,
+0xF0, 0x90, 0x10, 0x38, 0xE0, 0x64, 0x1F, 0x70, 0x79, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x64, 0x81, 0x4E, 0x70, 0x1A, 0x90, 0x06, 0x0B, 0xE0, 0x44, 0x04, 0xF0, 0x7C, 0x00, 0xEF,
+0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEC, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x80, 0x62,
+0xEF, 0x64, 0x82, 0x4E, 0x70, 0x1D, 0x90, 0x06, 0x0B, 0xE0, 0x44, 0x01, 0xF0, 0x7E, 0x00, 0x90,
+0x45, 0x34, 0xE0, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82, 0xEE, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01,
+0xF0, 0x80, 0x3F, 0x90, 0x45, 0x33, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x64, 0x03, 0x4E, 0x70, 0x1A,
+0x90, 0x06, 0x0B, 0xE0, 0x44, 0x02, 0xF0, 0x7E, 0x00, 0xEF, 0x54, 0x7F, 0x24, 0x34, 0xF5, 0x82,
+0xEE, 0x34, 0x10, 0xF5, 0x83, 0x74, 0x01, 0xF0, 0x80, 0x18, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08,
+0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08,
+0xF0, 0x22, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0,
+0x22, 0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x64, 0x40, 0x60,
+0x03, 0x02, 0x1C, 0xA2, 0xE0, 0x90, 0x43, 0x1E, 0xF0, 0x90, 0x06, 0x11, 0xE0, 0x90, 0x43, 0x1F,
+0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x20, 0xF0,
+0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0, 0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x43,
+0x22, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06, 0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE,
+0x90, 0x43, 0x24, 0xF0, 0xED, 0xA3, 0xF0, 0xE4, 0x90, 0x10, 0x44, 0xF0, 0xA3, 0xF0, 0x90, 0x43,
+0x24, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x42, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90, 0x43, 0x1F,
+0xE0, 0x12, 0x28, 0x7E, 0x1B, 0x70, 0x00, 0x1B, 0xE6, 0x01, 0x1B, 0x79, 0x07, 0x1B, 0x8F, 0x0B,
+0x1B, 0xAF, 0x0C, 0x1B, 0xC9, 0x10, 0x1B, 0xD9, 0x12, 0x1B, 0xFE, 0x13, 0x00, 0x00, 0x1C, 0x6A,
+0x90, 0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x02, 0x1C, 0x8E, 0x90, 0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x12,
+0x3D, 0x31, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
+0x10, 0x3D, 0x74, 0x0B, 0xF0, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x90, 0x45, 0x45, 0xE0, 0xFD, 0x12,
+0x39, 0xB4, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90,
+0x45, 0x45, 0xE0, 0xFF, 0x90, 0x06, 0x12, 0xE0, 0xFD, 0x12, 0x39, 0x2D, 0x90, 0x06, 0x23, 0x74,
+0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x12, 0x3E, 0x03, 0x90, 0x06, 0x23, 0x74,
+0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3,
+0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x22, 0x90, 0x10, 0x3D, 0x74, 0x10, 0xF0, 0x90, 0x06, 0x23, 0x74,
+0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x12, 0x3D, 0xBA, 0x02, 0x1C, 0x8E, 0x90, 0x06,
+0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0xA3, 0xF0, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45,
+0x39, 0xF0, 0xE0, 0x54, 0x7F, 0xF0, 0x44, 0x80, 0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x7D, 0x17, 0x7F,
+0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01,
+0xF0, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0x90, 0x04,
+0x59, 0x74, 0x10, 0xF0, 0xE4, 0x90, 0x06, 0x05, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x03, 0xF0, 0x75,
+0xA8, 0x81, 0x43, 0x87, 0x01, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04, 0x58, 0x74, 0x14,
+0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x43, 0xA8, 0x81, 0x80, 0x24, 0x90, 0x10, 0x3D, 0x74, 0x0D, 0xF0,
+0x7B, 0x01, 0x7A, 0x43, 0x79, 0x26, 0x90, 0x10, 0x3F, 0x12, 0x27, 0xBA, 0x90, 0x06, 0x17, 0xE0,
+0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x10, 0x42, 0xF0, 0xED, 0xA3, 0xF0, 0xE4, 0x90,
+0x06, 0x24, 0xF0, 0x90, 0x06, 0x23, 0x74, 0xC0, 0xF0, 0x90, 0x06, 0x25, 0x74, 0x08, 0xF0, 0xC2,
+0x04, 0x22, 0x90, 0x06, 0x10, 0xE0, 0x64, 0xC0, 0x60, 0x03, 0x02, 0x1E, 0x86, 0xE0, 0x90, 0x43,
+0x1E, 0xF0, 0x90, 0x06, 0x11, 0xE0, 0x90, 0x43, 0x1F, 0xF0, 0x90, 0x06, 0x13, 0xE0, 0xFE, 0x90,
+0x06, 0x12, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x20, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06, 0x15, 0xE0,
+0xFE, 0x90, 0x06, 0x14, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x22, 0xF0, 0xED, 0xA3, 0xF0, 0x90, 0x06,
+0x17, 0xE0, 0xFE, 0x90, 0x06, 0x16, 0xE0, 0xFD, 0xEE, 0x90, 0x43, 0x24, 0xF0, 0xED, 0xA3, 0xF0,
+0x90, 0x43, 0x24, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x4C, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x90,
+0x43, 0x1F, 0xE0, 0x24, 0xFA, 0x70, 0x03, 0x02, 0x1E, 0x58, 0x24, 0x05, 0x60, 0x03, 0x02, 0x1E,
+0x6F, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, 0x02, 0x1E, 0x50, 0xEF,
+0x24, 0xFE, 0x70, 0x03, 0x02, 0x1D, 0xCD, 0x14, 0x60, 0x31, 0x14, 0x60, 0x4E, 0x24, 0xFC, 0x70,
+0x03, 0x02, 0x1E, 0x1A, 0x24, 0x07, 0x60, 0x03, 0x02, 0x1E, 0x50, 0x7B, 0x01, 0x7A, 0x00, 0x79,
+0x00, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90,
+0x10, 0x47, 0xEE, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x02, 0x1E, 0x77, 0x7B, 0x01, 0x7A, 0x04, 0x79,
+0x00, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90,
+0x10, 0x47, 0xEE, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x02, 0x1E, 0x77, 0x7B, 0x01, 0x7A, 0x43, 0x79,
+0x26, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xE4, 0x90, 0x45, 0x37, 0xF0, 0xA3, 0xF0, 0x90, 0x43,
+0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x38, 0xE0, 0x9F, 0x90, 0x45, 0x37, 0xE0,
+0x9E, 0x40, 0x03, 0x02, 0x1E, 0x77, 0xA3, 0xE0, 0xFF, 0x90, 0x43, 0x21, 0xE0, 0x2F, 0xFF, 0x12,
+0x3B, 0x25, 0x90, 0x45, 0x38, 0xE0, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xEF,
+0xF0, 0x90, 0x45, 0x37, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC1, 0x7B, 0x01, 0x7A,
+0x43, 0x79, 0x26, 0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xE4, 0x90, 0x45, 0x37, 0xF0, 0xA3, 0xF0,
+0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x38, 0xE0, 0x9F, 0x90, 0x45,
+0x37, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x1E, 0x77, 0xA3, 0xE0, 0xFE, 0x90, 0x43, 0x21, 0xE0, 0x2E,
+0xFF, 0x74, 0x26, 0x2E, 0xF9, 0xE4, 0x34, 0x43, 0xFA, 0x7B, 0x01, 0x12, 0x3C, 0xCD, 0x90, 0x45,
+0x37, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC6, 0x7B, 0x01, 0x7A, 0x43, 0x79, 0x26,
+0x90, 0x10, 0x46, 0x12, 0x27, 0xBA, 0xD3, 0x90, 0x43, 0x25, 0xE0, 0x94, 0x02, 0x90, 0x43, 0x24,
+0xE0, 0x94, 0x00, 0x40, 0x0F, 0xE4, 0xF0, 0xA3, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x4C, 0xE4, 0xF0,
+0xA3, 0x74, 0x02, 0xF0, 0x90, 0x43, 0x26, 0x74, 0x33, 0xF0, 0xA3, 0x74, 0x01, 0xF0, 0x80, 0x27,
+0x90, 0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x7B, 0x01, 0x7A, 0x44, 0x79, 0x2E, 0x90, 0x10,
+0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4C, 0xE4, 0xF0, 0xA3, 0x74, 0x0A, 0xF0, 0x80, 0x08, 0x90,
+0x06, 0x22, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x12, 0x33, 0xF6,
+0x90, 0x10, 0x3D, 0x74, 0x0C, 0xF0, 0x22, 0xD2, 0x00, 0x90, 0x43, 0x1F, 0xE0, 0x12, 0x28, 0x7E,
+0x1E, 0xAF, 0x04, 0x1F, 0xB1, 0x05, 0x1F, 0xC4, 0x08, 0x20, 0xE2, 0x09, 0x21, 0x37, 0x0A, 0x21,
+0xE9, 0x0D, 0x22, 0x7F, 0x0E, 0x22, 0xB1, 0x0F, 0x23, 0x3B, 0x11, 0x00, 0x00, 0x23, 0x4F, 0x90,
+0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60, 0x03, 0x02, 0x23, 0x4F, 0xEF, 0x24, 0xFE,
+0x70, 0x03, 0x02, 0x1F, 0x7D, 0x14, 0x60, 0x4B, 0x14, 0x70, 0x03, 0x02, 0x1F, 0x51, 0x24, 0x03,
+0x60, 0x03, 0x02, 0x23, 0x4F, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34,
+0x00, 0xF5, 0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFE, 0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFD, 0xEE,
+0x5D, 0xD0, 0x82, 0xD0, 0x83, 0xF0, 0x74, 0x00, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x00, 0xF5, 0x83,
+0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0,
+0x83, 0xF0, 0x22, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x24, 0x00, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5,
+0x83, 0xC0, 0x83, 0xC0, 0x82, 0xE0, 0xFE, 0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFD, 0xEE, 0x5D, 0xD0,
+0x82, 0xD0, 0x83, 0xF0, 0x74, 0x00, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xC0, 0x83,
+0xC0, 0x82, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0xFE, 0xEF, 0x4E, 0xD0, 0x82, 0xD0, 0x83, 0xF0,
+0x22, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x37, 0xEF, 0xF0, 0x90, 0x43,
+0x27, 0xE0, 0xF4, 0x5F, 0xFF, 0x90, 0x45, 0x37, 0xF0, 0xFE, 0x90, 0x43, 0x21, 0xE0, 0xFF, 0x90,
+0x43, 0x26, 0xE0, 0x4E, 0xFD, 0x12, 0x3A, 0x33, 0x72, 0x00, 0x92, 0x00, 0x22, 0x90, 0x43, 0x21,
+0xE0, 0xFF, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x37, 0x12, 0x3C, 0xCD, 0x90, 0x45, 0x37, 0xE0, 0xFF,
+0x90, 0x43, 0x27, 0xE0, 0xF4, 0xFE, 0xEF, 0x5E, 0xFF, 0x90, 0x45, 0x37, 0xF0, 0xFE, 0x90, 0x43,
+0x21, 0xE0, 0xFF, 0x90, 0x43, 0x26, 0xE0, 0x4E, 0xFD, 0x12, 0x3D, 0x00, 0x72, 0x00, 0x92, 0x00,
+0x22, 0x7B, 0x01, 0x7A, 0x44, 0x79, 0x2E, 0x90, 0x45, 0x3B, 0x12, 0x27, 0xBA, 0x7A, 0x43, 0x79,
+0x26, 0x02, 0x2A, 0xF6, 0x90, 0x43, 0x21, 0xE0, 0xFD, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x43, 0x20,
+0xE0, 0xFA, 0xA3, 0xE0, 0xFB, 0xEA, 0x90, 0x04, 0xBD, 0xF0, 0x90, 0x43, 0x26, 0xE0, 0x90, 0x04,
+0xC0, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x43, 0x28, 0xE0, 0x90, 0x04,
+0xC2, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01, 0xF0,
+0xED, 0x04, 0x90, 0x04, 0xBC, 0xF0, 0xEB, 0x24, 0x01, 0xE4, 0x3A, 0xA3, 0xF0, 0x90, 0x43, 0x2A,
+0xE0, 0x90, 0x04, 0xC0, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x43, 0x2C,
+0xE0, 0x90, 0x04, 0xC2, 0xF0, 0x90, 0x43, 0x2D, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE,
+0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x35, 0xE0, 0xFE, 0xA3,
+0xE0, 0xFF, 0xC3, 0x94, 0x04, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x40, 0x03, 0x02, 0x23, 0x4F, 0x90,
+0x43, 0x21, 0xE0, 0x24, 0x02, 0xFD, 0x90, 0x45, 0x36, 0xE0, 0xF9, 0x2D, 0xFD, 0x90, 0x43, 0x23,
+0xE0, 0x25, 0xE0, 0x25, 0xE0, 0x2D, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x43, 0x21, 0xE0, 0x24, 0x02,
+0xFD, 0x90, 0x43, 0x20, 0xE0, 0x34, 0x00, 0xCD, 0x2F, 0xCD, 0x3E, 0xFC, 0x90, 0x43, 0x22, 0xE0,
+0xFE, 0xA3, 0xE0, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9, 0x2D, 0xEC, 0x3E, 0x90,
+0x04, 0xBD, 0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x2E, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04,
+0xC0, 0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x2F, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC1,
+0xF0, 0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x30, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC2, 0xF0,
+0x75, 0xF0, 0x04, 0xE9, 0x90, 0x43, 0x31, 0x12, 0x27, 0x8E, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90,
+0x04, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x02,
+0x20, 0x3A, 0xE4, 0x90, 0x04, 0xBD, 0xF0, 0x90, 0x04, 0xC0, 0xF0, 0xA3, 0xF0, 0xA3, 0xF0, 0xA3,
+0xF0, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3,
+0x90, 0x45, 0x36, 0xE0, 0x9F, 0x90, 0x45, 0x35, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x23, 0x4F, 0xA3,
+0xE0, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0x75, 0xF0, 0x16, 0xA4, 0x24,
+0x20, 0x90, 0x04, 0xBC, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75,
+0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0xC0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0xFD, 0xFC,
+0x90, 0x43, 0x24, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x90, 0x45, 0x36, 0xE0, 0x9F, 0x90, 0x45,
+0x35, 0xE0, 0x9E, 0x40, 0x03, 0x02, 0x23, 0x4F, 0x90, 0x43, 0x21, 0xE0, 0x2D, 0x90, 0x04, 0xBC,
+0xF0, 0x90, 0x43, 0x21, 0xE0, 0x2D, 0x90, 0x43, 0x20, 0xE0, 0x3C, 0x90, 0x04, 0xBD, 0xF0, 0x90,
+0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82,
+0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC0, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0,
+0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83,
+0xE0, 0x90, 0x04, 0xC1, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE,
+0x74, 0x26, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC2, 0xF0,
+0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFE, 0x74, 0x26, 0x25, 0xF0, 0xF5,
+0x82, 0x74, 0x43, 0x3E, 0xF5, 0x83, 0xE0, 0x90, 0x04, 0xC3, 0xF0, 0x90, 0x04, 0xBE, 0x74, 0x01,
+0xF0, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0x02, 0x21, 0x40, 0x90, 0x43, 0x20, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0x64, 0x05, 0x4E, 0x70, 0x40, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0,
+0xFD, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0xFC, 0x74, 0x40, 0x2D, 0xF5,
+0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEC, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12,
+0x26, 0xB0, 0x90, 0x45, 0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x08, 0x70, 0xCE, 0x90, 0x04,
+0x48, 0xE0, 0x44, 0x04, 0xF0, 0x22, 0xEF, 0x64, 0x06, 0x4E, 0x60, 0x03, 0x02, 0x23, 0x4F, 0x90,
+0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0, 0xFF, 0x24, 0x26, 0xF5, 0x82, 0xE4, 0x34,
+0x43, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0x38, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEE,
+0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x90, 0x45, 0x35, 0xE0, 0x70,
+0x04, 0xA3, 0xE0, 0x64, 0x08, 0x70, 0xCE, 0x90, 0x04, 0x48, 0xE0, 0x44, 0x08, 0xF0, 0x22, 0x90,
+0x43, 0x26, 0xE0, 0x90, 0x04, 0x22, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0x23, 0xF0, 0x90,
+0x43, 0x28, 0xE0, 0x90, 0x04, 0x24, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0x25, 0xF0, 0x90,
+0x43, 0x2A, 0xE0, 0x90, 0x04, 0x28, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0xFD, 0x7F, 0x0A, 0x02, 0x3D,
+0x00, 0x90, 0x43, 0x26, 0xE0, 0x90, 0x04, 0x22, 0xF0, 0x90, 0x43, 0x27, 0xE0, 0x90, 0x04, 0x23,
+0xF0, 0x90, 0x43, 0x28, 0xE0, 0x90, 0x04, 0x24, 0xF0, 0x90, 0x43, 0x29, 0xE0, 0x90, 0x04, 0x25,
+0xF0, 0x90, 0x43, 0x2A, 0xE0, 0x90, 0x04, 0x28, 0xF0, 0x90, 0x43, 0x2B, 0xE0, 0xFD, 0x7F, 0x0A,
+0x12, 0x3D, 0x00, 0x90, 0x43, 0x2C, 0xE0, 0xFD, 0x7F, 0x88, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x4C,
+0xE0, 0x54, 0xFC, 0xF0, 0xE0, 0xFF, 0x90, 0x43, 0x2D, 0xE0, 0xFE, 0xEF, 0x4E, 0x90, 0x04, 0x4C,
+0xF0, 0xE4, 0x90, 0x45, 0x35, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x36, 0xE0, 0xFF, 0x24, 0x2E, 0xF5,
+0x82, 0xE4, 0x34, 0x43, 0xF5, 0x83, 0xE0, 0xFE, 0x74, 0xDC, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04,
+0xF5, 0x83, 0xEE, 0xF0, 0x90, 0x45, 0x35, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x90, 0x45,
+0x35, 0xE0, 0x70, 0x04, 0xA3, 0xE0, 0x64, 0x22, 0x70, 0xCE, 0x22, 0x90, 0x43, 0x26, 0xE0, 0xFF,
+0xA3, 0xE0, 0xFD, 0xA3, 0xE0, 0xFB, 0xA3, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x12, 0x3C, 0x90, 0x22,
+0x90, 0x06, 0x30, 0x74, 0x70, 0xF0, 0x90, 0x06, 0x31, 0x74, 0xA0, 0xF0, 0xE0, 0x90, 0x06, 0x35,
+0xF0, 0x90, 0x06, 0x36, 0x74, 0xC0, 0xF0, 0x90, 0x06, 0x37, 0x74, 0x08, 0xF0, 0xE4, 0x90, 0x45,
+0x46, 0xF0, 0xA3, 0xF0, 0xC2, 0x05, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04, 0x58, 0x74,
+0x14, 0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x12, 0x3C, 0x43, 0x75, 0xA8, 0x81, 0x90, 0x06, 0x05, 0x74,
+0x04, 0xF0, 0x90, 0x06, 0x0F, 0xE0, 0x30, 0xE4, 0x04, 0xD2, 0x06, 0x80, 0x02, 0xC2, 0x06, 0xE4,
+0x90, 0x43, 0x19, 0xF0, 0x20, 0x05, 0x03, 0x02, 0x25, 0xFB, 0xC2, 0x05, 0x90, 0x10, 0x39, 0xE0,
+0xFF, 0x20, 0xE5, 0x03, 0x02, 0x24, 0xCD, 0x54, 0xDF, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x20, 0xE0,
+0x03, 0x02, 0x24, 0x4D, 0x7D, 0x17, 0x7F, 0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12,
+0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x2F, 0xF0, 0xA3, 0xF0, 0x90,
+0x04, 0x54, 0xE0, 0x30, 0xE0, 0x16, 0x90, 0x45, 0x2F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0,
+0x90, 0x45, 0x2F, 0xE0, 0xB4, 0x07, 0xE8, 0xA3, 0xE0, 0xB4, 0xFF, 0xE3, 0xE4, 0x90, 0x04, 0x78,
+0xF0, 0xA3, 0x74, 0x11, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x54, 0x01, 0xF0, 0x90, 0x06, 0x30, 0x74,
+0x70, 0xF0, 0x90, 0x06, 0x31, 0x74, 0xA0, 0xF0, 0xE0, 0x90, 0x06, 0x35, 0xF0, 0x90, 0x06, 0x36,
+0x74, 0xC0, 0xF0, 0x90, 0x06, 0x37, 0x74, 0x08, 0xF0, 0x90, 0x06, 0x38, 0x74, 0x03, 0xF0, 0x90,
+0x06, 0x01, 0xE0, 0x44, 0x20, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x02, 0xF0, 0x90, 0x10, 0x38, 0x74,
+0x07, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE1, 0x04, 0xE0, 0x54, 0x02, 0xF0, 0x90, 0x06, 0x0E,
+0xE0, 0x30, 0xE3, 0x11, 0xE0, 0x54, 0x08, 0xF0, 0x90, 0x06, 0x0F, 0xE0, 0x30, 0xE4, 0x04, 0xD2,
+0x06, 0x80, 0x02, 0xC2, 0x06, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE2, 0x0A, 0xE0, 0x54, 0x04, 0xF0,
+0x90, 0x04, 0x79, 0x74, 0x11, 0xF0, 0x90, 0x06, 0x0E, 0xE0, 0x30, 0xE1, 0x50, 0xE0, 0x20, 0xE0,
+0x4C, 0x7D, 0x17, 0x7F, 0x0C, 0x12, 0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90,
+0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x0E, 0xE0,
+0x54, 0x02, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0xE4, 0x90, 0x04, 0x58, 0xF0, 0x90, 0x06,
+0x07, 0x74, 0x03, 0xF0, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0xF9, 0xF0,
+0x44, 0x02, 0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x43, 0xA8, 0x81, 0x43, 0x87, 0x01, 0x90, 0x10, 0x39,
+0xE0, 0x30, 0xE0, 0x22, 0x90, 0x06, 0x24, 0xE0, 0x30, 0xE4, 0x05, 0x12, 0x12, 0x0E, 0x80, 0x0F,
+0x90, 0x06, 0x24, 0xE0, 0x30, 0xE3, 0x05, 0x12, 0x34, 0xB9, 0x80, 0x03, 0x12, 0x28, 0xF4, 0x90,
+0x10, 0x39, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x45, 0x46, 0xE0, 0x54, 0x14, 0x70, 0x09, 0xA3, 0xE0,
+0xFF, 0x20, 0xE6, 0x03, 0x30, 0xE3, 0x4F, 0x7B, 0x01, 0x7A, 0x06, 0x79, 0x40, 0x12, 0x33, 0x2B,
+0x90, 0x45, 0x46, 0xE0, 0xFF, 0x90, 0x06, 0x48, 0xF0, 0x90, 0x45, 0x47, 0xE0, 0x90, 0x06, 0x49,
+0xF0, 0x90, 0x04, 0x2C, 0xE0, 0x90, 0x06, 0x4A, 0xF0, 0x90, 0x04, 0x2D, 0xE0, 0x90, 0x06, 0x4B,
+0xF0, 0x90, 0x04, 0x2E, 0xE0, 0x90, 0x06, 0x4C, 0xF0, 0x90, 0x04, 0x2F, 0xE0, 0x90, 0x06, 0x4D,
+0xF0, 0x90, 0x06, 0x3F, 0x74, 0x01, 0xF0, 0xEF, 0x54, 0xEB, 0x90, 0x45, 0x46, 0xF0, 0xA3, 0xE0,
+0x54, 0xBF, 0xF0, 0x54, 0xF7, 0xF0, 0x90, 0x45, 0x47, 0xE0, 0xFF, 0x20, 0xE4, 0x03, 0x02, 0x25,
+0xE8, 0x90, 0x04, 0x7A, 0xE0, 0x54, 0xDF, 0xF0, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x20, 0xE6,
+0x54, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0x7F, 0xF0, 0x44, 0x80, 0xF0,
+0x90, 0x04, 0x7A, 0xF0, 0xEF, 0x54, 0xEF, 0x90, 0x45, 0x47, 0xF0, 0x7D, 0x17, 0x7F, 0x0C, 0x12,
+0x3D, 0x00, 0x7D, 0xB9, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4,
+0x90, 0x04, 0x78, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x20, 0xF0, 0x90, 0x04, 0x59, 0x74,
+0x10, 0xF0, 0xE4, 0x90, 0x06, 0x05, 0xF0, 0x90, 0x06, 0x07, 0x74, 0x03, 0xF0, 0x75, 0xA8, 0x81,
+0x43, 0x87, 0x01, 0x80, 0x23, 0x90, 0x04, 0x7A, 0xE0, 0x90, 0x45, 0x2E, 0xF0, 0xE0, 0x54, 0x7F,
+0xF0, 0x90, 0x04, 0x7A, 0xF0, 0x90, 0x10, 0x38, 0x74, 0x07, 0xF0, 0x90, 0x06, 0x05, 0x74, 0x04,
+0xF0, 0x90, 0x45, 0x47, 0xE0, 0x54, 0xEF, 0xF0, 0x90, 0x06, 0x20, 0x74, 0x21, 0xF0, 0x90, 0x04,
+0x58, 0x74, 0x14, 0xF0, 0xA3, 0x74, 0x50, 0xF0, 0x43, 0xA8, 0x81, 0x90, 0x43, 0x19, 0xE0, 0x64,
+0x01, 0x60, 0x03, 0x02, 0x23, 0xA4, 0xF0, 0x90, 0x06, 0x24, 0xE0, 0x30, 0xE3, 0x03, 0x02, 0x23,
+0xA4, 0x90, 0x06, 0x25, 0xE0, 0x54, 0xF7, 0xF0, 0x30, 0x04, 0x07, 0xE4, 0x90, 0x06, 0x23, 0xF0,
+0x80, 0x06, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0x90, 0x06, 0x24, 0x74, 0x08, 0xF0, 0x90, 0x06,
+0x25, 0xF0, 0x02, 0x23, 0xA4, 0x22, 0xBB, 0x01, 0x06, 0x89, 0x82, 0x8A, 0x83, 0xE0, 0x22, 0x50,
+0x02, 0xE7, 0x22, 0xBB, 0xFE, 0x02, 0xE3, 0x22, 0x89, 0x82, 0x8A, 0x83, 0xE4, 0x93, 0x22, 0xBB,
+0x01, 0x0C, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0x22, 0x50, 0x06,
+0xE9, 0x25, 0x82, 0xF8, 0xE6, 0x22, 0xBB, 0xFE, 0x06, 0xE9, 0x25, 0x82, 0xF8, 0xE2, 0x22, 0xE5,
+0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0xBB, 0x01, 0x06, 0x89,
+0x82, 0x8A, 0x83, 0xF0, 0x22, 0x50, 0x02, 0xF7, 0x22, 0xBB, 0xFE, 0x01, 0xF3, 0x22, 0xF8, 0xBB,
+0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8, 0xF0, 0x22, 0x50,
+0x06, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x22, 0xBB, 0xFE, 0x05, 0xE9, 0x25, 0x82, 0xC8, 0xF2, 0x22,
+0xC5, 0xF0, 0xF8, 0xA3, 0xE0, 0x28, 0xF0, 0xC5, 0xF0, 0xF8, 0xE5, 0x82, 0x15, 0x82, 0x70, 0x02,
+0x15, 0x83, 0xE0, 0x38, 0xF0, 0x22, 0xA3, 0xF8, 0xE0, 0xC5, 0xF0, 0x25, 0xF0, 0xF0, 0xE5, 0x82,
+0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xC8, 0x38, 0xF0, 0xE8, 0x22, 0xBB, 0x01, 0x10, 0xE5,
+0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE0, 0xF5, 0xF0, 0xA3, 0xE0, 0x22, 0x50,
+0x09, 0xE9, 0x25, 0x82, 0xF8, 0x86, 0xF0, 0x08, 0xE6, 0x22, 0xBB, 0xFE, 0x0A, 0xE9, 0x25, 0x82,
+0xF8, 0xE2, 0xF5, 0xF0, 0x08, 0xE2, 0x22, 0xE5, 0x83, 0x2A, 0xF5, 0x83, 0xE9, 0x93, 0xF5, 0xF0,
+0xA3, 0xE9, 0x93, 0x22, 0xBB, 0x01, 0x0D, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A, 0xC5,
+0x83, 0x02, 0x26, 0xB0, 0x50, 0x11, 0xC5, 0x82, 0x29, 0xF8, 0x08, 0xE5, 0xF0, 0x26, 0xF6, 0x18,
+0xF5, 0xF0, 0xE5, 0x82, 0x36, 0xF6, 0x22, 0xBB, 0xFE, 0x11, 0xC5, 0x82, 0x29, 0xF8, 0x08, 0xE2,
+0x25, 0xF0, 0xF5, 0xF0, 0xF2, 0x18, 0xE2, 0x35, 0x82, 0xF2, 0x22, 0xF8, 0xE5, 0x82, 0x29, 0xF5,
+0x82, 0xE5, 0x83, 0x2A, 0xF5, 0x83, 0x74, 0x01, 0x93, 0x25, 0xF0, 0xF5, 0xF0, 0xE4, 0x93, 0x38,
+0x22, 0xF8, 0xBB, 0x01, 0x11, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83, 0xE8,
+0xF0, 0xE5, 0xF0, 0xA3, 0xF0, 0x22, 0x50, 0x09, 0xE9, 0x25, 0x82, 0xC8, 0xF6, 0x08, 0xA6, 0xF0,
+0x22, 0xBB, 0xFE, 0x09, 0xE9, 0x25, 0x82, 0xC8, 0xF2, 0xE5, 0xF0, 0x08, 0xF2, 0x22, 0xA4, 0x25,
+0x82, 0xF5, 0x82, 0xE5, 0xF0, 0x35, 0x83, 0xF5, 0x83, 0x22, 0xE0, 0xFB, 0xA3, 0xE0, 0xFA, 0xA3,
+0xE0, 0xF9, 0x22, 0xF8, 0xE0, 0xFB, 0xA3, 0xA3, 0xE0, 0xF9, 0x25, 0xF0, 0xF0, 0xE5, 0x82, 0x15,
+0x82, 0x70, 0x02, 0x15, 0x83, 0xE0, 0xFA, 0x38, 0xF0, 0x22, 0xEB, 0xF0, 0xA3, 0xEA, 0xF0, 0xA3,
+0xE9, 0xF0, 0x22, 0xBB, 0x01, 0x0D, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83,
+0x02, 0x27, 0x9A, 0x50, 0x07, 0xE9, 0x25, 0x82, 0xF8, 0x02, 0x28, 0xA4, 0xBB, 0xFE, 0x07, 0xE9,
+0x25, 0x82, 0xF8, 0x02, 0x28, 0xC6, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A, 0xF5, 0x83,
+0x02, 0x28, 0xE8, 0xBB, 0x01, 0x0D, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A, 0xC5, 0x83,
+0x02, 0x27, 0xA3, 0x50, 0x08, 0xF8, 0xE9, 0x25, 0x82, 0xC8, 0x02, 0x28, 0xAD, 0xBB, 0xFE, 0x08,
+0xF8, 0xE9, 0x25, 0x82, 0xC8, 0x02, 0x28, 0xCF, 0xC5, 0x82, 0x29, 0xC5, 0x82, 0xC5, 0x83, 0x3A,
+0xC5, 0x83, 0x02, 0x28, 0xE8, 0xBB, 0x01, 0x20, 0xE5, 0x82, 0x29, 0xF5, 0x82, 0xE5, 0x83, 0x3A,
+0xF5, 0x83, 0xD0, 0xF0, 0xD0, 0xE0, 0xF8, 0xD0, 0xE0, 0xF9, 0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB,
+0xE8, 0xC0, 0xE0, 0xC0, 0xF0, 0x02, 0x27, 0xBA, 0x50, 0x18, 0xE9, 0x25, 0x82, 0xF8, 0xD0, 0x83,
+0xD0, 0x82, 0xD0, 0xE0, 0xF9, 0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB, 0xC0, 0x82, 0xC0, 0x83, 0x02,
+0x28, 0xBD, 0xBB, 0xFE, 0x18, 0xE9, 0x25, 0x82, 0xF8, 0xD0, 0x83, 0xD0, 0x82, 0xD0, 0xE0, 0xF9,
+0xD0, 0xE0, 0xFA, 0xD0, 0xE0, 0xFB, 0xC0, 0x82, 0xC0, 0x83, 0x02, 0x28, 0xDF, 0x22, 0xD0, 0x83,
+0xD0, 0x82, 0xF8, 0xE4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0D, 0xA3, 0xA3, 0x93, 0xF8,
+0x74, 0x01, 0x93, 0xF5, 0x82, 0x88, 0x83, 0xE4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xEF, 0xA3,
+0xA3, 0xA3, 0x80, 0xDF, 0xE6, 0xFB, 0x08, 0xE6, 0xFA, 0x08, 0xE6, 0xF9, 0x22, 0xFA, 0xE6, 0xFB,
+0x08, 0x08, 0xE6, 0xF9, 0x25, 0xF0, 0xF6, 0x18, 0xE6, 0xCA, 0x3A, 0xF6, 0x22, 0xEB, 0xF6, 0x08,
+0xEA, 0xF6, 0x08, 0xE9, 0xF6, 0x22, 0xE2, 0xFB, 0x08, 0xE2, 0xFA, 0x08, 0xE2, 0xF9, 0x22, 0xFA,
+0xE2, 0xFB, 0x08, 0x08, 0xE2, 0xF9, 0x25, 0xF0, 0xF2, 0x18, 0xE2, 0xCA, 0x3A, 0xF2, 0x22, 0xEB,
+0xF2, 0x08, 0xEA, 0xF2, 0x08, 0xE9, 0xF2, 0x22, 0xE4, 0x93, 0xFB, 0x74, 0x01, 0x93, 0xFA, 0x74,
+0x02, 0x93, 0xF9, 0x22, 0x90, 0x06, 0x23, 0xE0, 0x54, 0x7F, 0xFF, 0xC3, 0x74, 0x40, 0x9F, 0x90,
+0x45, 0x31, 0xF0, 0xE4, 0xA3, 0xF0, 0x90, 0x10, 0x3D, 0xE0, 0x64, 0x0B, 0x60, 0x03, 0x02, 0x2A,
+0x60, 0x90, 0x10, 0x44, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x43, 0x21, 0xE0, 0x2F, 0x90, 0x45,
+0x34, 0xF0, 0x90, 0x43, 0x20, 0xE0, 0x3E, 0x90, 0x45, 0x33, 0xF0, 0x90, 0x45, 0x31, 0xE0, 0x70,
+0x03, 0x02, 0x2A, 0xA6, 0x14, 0xF0, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xEE, 0x60,
+0x03, 0x02, 0x2A, 0x57, 0xEF, 0x12, 0x28, 0x7E, 0x29, 0x6A, 0x01, 0x29, 0x94, 0x02, 0x29, 0xB5,
+0x03, 0x29, 0xDE, 0x04, 0x29, 0xFE, 0x07, 0x2A, 0x31, 0x09, 0x2A, 0x31, 0x0A, 0x2A, 0x31, 0x0B,
+0x2A, 0x31, 0x0C, 0x2A, 0x31, 0x0D, 0x00, 0x00, 0x2A, 0x57, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60,
+0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01,
+0x12, 0x26, 0xC6, 0xFC, 0x74, 0x00, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x00, 0x3C, 0xF5, 0x83, 0xEF,
+0xF0, 0x02, 0x2A, 0x57, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAF, 0xF0,
+0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x12,
+0x3D, 0x00, 0x02, 0x2A, 0x57, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06,
+0xF5, 0x83, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xFC, 0x74,
+0x00, 0x25, 0xF0, 0xF5, 0x82, 0x74, 0x04, 0x3C, 0xF5, 0x83, 0xEF, 0xF0, 0x80, 0x79, 0x90, 0x45,
+0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAF, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60,
+0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x12, 0x3A, 0x33, 0x80, 0x59, 0x90, 0x45,
+0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFD, 0x7F, 0xF1, 0x12,
+0x3D, 0x00, 0x90, 0x45, 0x34, 0xE0, 0x44, 0x80, 0xFD, 0x7F, 0xF0, 0x12, 0x3D, 0x00, 0x90, 0x45,
+0x33, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xC6, 0xAD, 0xF0, 0x7F, 0xF0, 0x12, 0x3D, 0x00, 0x80,
+0x26, 0x90, 0x43, 0x22, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0x90, 0x45, 0x33, 0xE4, 0x75, 0xF0, 0x01,
+0x12, 0x26, 0xC6, 0xAD, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0x24, 0x60, 0xF5, 0x82, 0xE4, 0x34, 0x06,
+0xF5, 0x83, 0xE0, 0xFB, 0x12, 0x3A, 0xAE, 0x90, 0x45, 0x32, 0xE0, 0x04, 0xF0, 0x02, 0x29, 0x2B,
+0x90, 0x10, 0x3D, 0xE0, 0xFF, 0xB4, 0x0D, 0x2D, 0x90, 0x45, 0x31, 0xE0, 0x60, 0x38, 0xA3, 0xE0,
+0xFE, 0x04, 0xF0, 0x74, 0x60, 0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xE0, 0xFE, 0x90,
+0x10, 0x3F, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEE, 0x12, 0x26, 0x7C, 0x90, 0x45, 0x31,
+0xE0, 0x14, 0xF0, 0x80, 0xD3, 0xEF, 0xB4, 0x0C, 0x07, 0xC2, 0x8C, 0xE4, 0x90, 0x43, 0x19, 0xF0,
+0xE4, 0x90, 0x10, 0x3D, 0xF0, 0x22, 0x30, 0x04, 0x0A, 0xC2, 0x04, 0x90, 0x06, 0x23, 0x74, 0xC0,
+0xF0, 0x80, 0x08, 0xD2, 0x04, 0x90, 0x06, 0x23, 0x74, 0x40, 0xF0, 0x90, 0x45, 0x32, 0xE0, 0xFF,
+0x90, 0x10, 0x44, 0xE4, 0x8F, 0xF0, 0x12, 0x26, 0xB0, 0x90, 0x10, 0x42, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0xA3, 0xE0, 0xB5, 0x06, 0x19, 0xA3, 0xE0, 0xB5, 0x07, 0x14, 0x90, 0x10, 0x3D, 0xE0, 0xB4,
+0x0D, 0x03, 0x12, 0x1E, 0x87, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xA3, 0x74, 0x08, 0xF0, 0x90,
+0x06, 0x25, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x45, 0x38, 0x12, 0x27, 0xBA, 0x12, 0x26, 0x36, 0x60,
+0x03, 0x02, 0x2B, 0x8F, 0x7F, 0x1C, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90,
+0x00, 0x08, 0xEF, 0x12, 0x26, 0x8E, 0x7F, 0x1D, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B, 0x12, 0x27,
+0x9A, 0x90, 0x00, 0x09, 0xEF, 0x12, 0x26, 0x8E, 0x7F, 0x1B, 0x12, 0x3B, 0x25, 0x90, 0x45, 0x3B,
+0x12, 0x27, 0x9A, 0x90, 0x00, 0x07, 0xEF, 0x12, 0x26, 0x8E, 0xE9, 0x24, 0x07, 0xF9, 0xE4, 0x3A,
+0xFA, 0x12, 0x26, 0x36, 0x54, 0x7F, 0x12, 0x26, 0x7C, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90,
+0x00, 0x07, 0x12, 0x26, 0x4F, 0x90, 0x45, 0x45, 0xF0, 0x90, 0x04, 0x2B, 0x74, 0xFF, 0xF0, 0x12,
+0x3C, 0x43, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x07, 0x12, 0x26, 0x4F, 0xFF, 0x12,
+0x3D, 0x62, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x08, 0x12, 0x26, 0x4F, 0xFD, 0x90,
+0x40, 0xC0, 0xF0, 0x90, 0x00, 0x07, 0x12, 0x26, 0x4F, 0xFF, 0x12, 0x39, 0x2D, 0x80, 0x1B, 0x12,
+0x3D, 0xE2, 0x90, 0x04, 0x54, 0xE0, 0x54, 0xFB, 0xF0, 0x90, 0x06, 0x38, 0x74, 0x03, 0xF0, 0x12,
+0x3D, 0x31, 0x90, 0x04, 0x48, 0x74, 0x02, 0xF0, 0x14, 0xF0, 0xE4, 0xFF, 0xFE, 0x74, 0xC4, 0x2F,
+0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0xE9,
+0x24, 0x01, 0xF9, 0xE4, 0x3A, 0xFA, 0xE9, 0x2F, 0xF9, 0xEA, 0x3E, 0xFA, 0xED, 0x12, 0x26, 0x7C,
+0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xEF, 0x64, 0x06, 0x4E, 0x70, 0xD2, 0x90, 0x45, 0x38, 0x12, 0x27,
+0x9A, 0x90, 0x00, 0x01, 0x12, 0x26, 0x4F, 0x60, 0x31, 0xE4, 0xFE, 0xFF, 0x90, 0x45, 0x38, 0x12,
+0x27, 0x9A, 0xE9, 0x24, 0x02, 0xF9, 0xE4, 0x3A, 0xFA, 0xE9, 0x2F, 0xF9, 0xEA, 0x3E, 0xFA, 0x12,
+0x26, 0x36, 0xFD, 0x74, 0xC4, 0x2F, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xED, 0xF0, 0x0F,
+0xBF, 0x00, 0x01, 0x0E, 0xEF, 0x64, 0x06, 0x4E, 0x70, 0xD2, 0x90, 0x45, 0x38, 0x12, 0x27, 0x9A,
+0x90, 0x00, 0x08, 0x12, 0x26, 0x4F, 0x90, 0x04, 0x21, 0xF0, 0x90, 0x00, 0x09, 0x12, 0x26, 0x4F,
+0x90, 0x04, 0x20, 0xF0, 0x90, 0x04, 0x50, 0xE0, 0x44, 0x82, 0xF0, 0x90, 0x04, 0x54, 0x74, 0x0E,
+0xF0, 0x90, 0x45, 0x3B, 0x12, 0x27, 0x9A, 0xE4, 0x12, 0x26, 0x7C, 0xD3, 0x22, 0xAC, 0x07, 0xAA,
+0x05, 0xD2, 0x03, 0x90, 0x04, 0x78, 0xE0, 0x54, 0xFE, 0xF0, 0xEC, 0xD3, 0x94, 0x0E, 0x40, 0x03,
+0x02, 0x2C, 0xFA, 0xEA, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2C, 0xFA, 0x90, 0x40, 0xC9, 0xE0, 0xFD,
+0x90, 0x40, 0xC8, 0xE0, 0xFB, 0x90, 0x40, 0xC7, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90,
+0x40, 0xCC, 0xE0, 0xFD, 0x90, 0x40, 0xCB, 0xE0, 0xFB, 0x90, 0x40, 0xCA, 0x12, 0x3C, 0x89, 0x82,
+0x03, 0x92, 0x03, 0x90, 0x40, 0xD2, 0xE0, 0xFD, 0x90, 0x40, 0xD1, 0xE0, 0xFB, 0x90, 0x40, 0xD0,
+0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xD8, 0xE0, 0xFD, 0x90, 0x40, 0xD7, 0xE0,
+0xFB, 0x90, 0x40, 0xD6, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xE1, 0xE0, 0xFD,
+0x90, 0x40, 0xE0, 0xE0, 0xFB, 0x90, 0x40, 0xDF, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90,
+0x40, 0xE7, 0xE0, 0xFD, 0x90, 0x40, 0xE6, 0xE0, 0xFB, 0x90, 0x40, 0xE5, 0x12, 0x3C, 0x89, 0x82,
+0x03, 0x92, 0x03, 0x90, 0x40, 0xF0, 0xE0, 0xFD, 0x90, 0x40, 0xEF, 0xE0, 0xFB, 0x90, 0x40, 0xEE,
+0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x02, 0x2D, 0x98, 0xEC, 0xD3, 0x94, 0x0E, 0x50, 0x03,
+0x02, 0x2D, 0x98, 0xEA, 0xD3, 0x94, 0x0E, 0x40, 0x03, 0x02, 0x2D, 0x98, 0x90, 0x42, 0xF1, 0xE0,
+0xFD, 0x90, 0x42, 0xF0, 0xE0, 0xFB, 0x90, 0x42, 0xEF, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03,
+0x90, 0x42, 0xF4, 0xE0, 0xFD, 0x90, 0x42, 0xF3, 0xE0, 0xFB, 0x90, 0x42, 0xF2, 0x12, 0x3C, 0x89,
+0x82, 0x03, 0x92, 0x03, 0x90, 0x42, 0xFA, 0xE0, 0xFD, 0x90, 0x42, 0xF9, 0xE0, 0xFB, 0x90, 0x42,
+0xF8, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x00, 0xE0, 0xFD, 0x90, 0x42, 0xFF,
+0xE0, 0xFB, 0x90, 0x42, 0xFE, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x09, 0xE0,
+0xFD, 0x90, 0x43, 0x08, 0xE0, 0xFB, 0x90, 0x43, 0x07, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03,
+0x90, 0x43, 0x0F, 0xE0, 0xFD, 0x90, 0x43, 0x0E, 0xE0, 0xFB, 0x90, 0x43, 0x0D, 0x12, 0x3C, 0x89,
+0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x18, 0xE0, 0xFD, 0x90, 0x43, 0x17, 0xE0, 0xFB, 0x90, 0x43,
+0x16, 0x12, 0x3C, 0x89, 0x82, 0x03, 0x92, 0x03, 0x90, 0x04, 0x78, 0xE0, 0x44, 0x01, 0xF0, 0xA2,
+0x03, 0x22, 0xAC, 0x07, 0xAA, 0x05, 0xD2, 0x03, 0xEC, 0xD3, 0x94, 0x0E, 0x40, 0x03, 0x02, 0x2E,
+0x43, 0xEA, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2E, 0x43, 0x90, 0x40, 0xC9, 0xE0, 0xFD, 0x90, 0x40,
+0xC8, 0xE0, 0xFB, 0x90, 0x40, 0xC7, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xD8, 0xE0, 0xFD, 0x90, 0x40, 0xD7, 0xE0, 0xFB, 0x90, 0x40,
+0xD6, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90,
+0x40, 0xDE, 0xE0, 0xFD, 0x90, 0x40, 0xDD, 0xE0, 0xFB, 0x90, 0x40, 0xDC, 0xE0, 0x90, 0x45, 0x44,
+0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xE7, 0xE0, 0xFD, 0x90,
+0x40, 0xE6, 0xE0, 0xFB, 0x90, 0x40, 0xE5, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C,
+0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x40, 0xED, 0xE0, 0xFD, 0x90, 0x40, 0xEC, 0xE0, 0xFB, 0x90,
+0x40, 0xEB, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03,
+0x02, 0x2E, 0xDC, 0xEC, 0xD3, 0x94, 0x0E, 0x50, 0x03, 0x02, 0x2E, 0xDC, 0xEA, 0xD3, 0x94, 0x0E,
+0x40, 0x03, 0x02, 0x2E, 0xDC, 0x90, 0x42, 0xF1, 0xE0, 0xFD, 0x90, 0x42, 0xF0, 0xE0, 0xFB, 0x90,
+0x42, 0xEF, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03,
+0x90, 0x43, 0x00, 0xE0, 0xFD, 0x90, 0x42, 0xFF, 0xE0, 0xFB, 0x90, 0x42, 0xFE, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x06, 0xE0, 0xFD,
+0x90, 0x43, 0x05, 0xE0, 0xFB, 0x90, 0x43, 0x04, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12,
+0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0x90, 0x43, 0x0F, 0xE0, 0xFD, 0x90, 0x43, 0x0E, 0xE0, 0xFB,
+0x90, 0x43, 0x0D, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92,
+0x03, 0x90, 0x43, 0x15, 0xE0, 0xFD, 0x90, 0x43, 0x14, 0xE0, 0xFB, 0x90, 0x43, 0x13, 0xE0, 0x90,
+0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x03, 0x92, 0x03, 0xA2, 0x03, 0x22, 0x90,
+0x45, 0x40, 0xEF, 0xF0, 0xD2, 0x02, 0x90, 0x40, 0xC0, 0xE0, 0xFF, 0x90, 0x45, 0x40, 0xE0, 0xFD,
+0x12, 0x2D, 0xA2, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFC, 0xD3, 0x94, 0x0E, 0x50,
+0x10, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x8A, 0x7D, 0xF1, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80,
+0x3A, 0xEC, 0xD3, 0x94, 0x28, 0x50, 0x10, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0xF1,
+0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80, 0x24, 0xEC, 0xD3, 0x94, 0x33, 0x50, 0x10, 0xE4, 0x90, 0x45,
+0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0xB1, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x80, 0x0E, 0xE4, 0x90, 0x45,
+0x44, 0xF0, 0x7B, 0x8B, 0x7D, 0x91, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x90, 0x45, 0x40, 0xE0, 0xFF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x40, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFD, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x3F, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFB, 0xEF,
+0x75, 0xF0, 0x03, 0xA4, 0x24, 0x3E, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0,
+0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78,
+0xF0, 0xA3, 0x74, 0x13, 0xF0, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x40, 0x7F, 0x0D, 0x12, 0x3C, 0xCD,
+0x90, 0x45, 0x40, 0xE0, 0x54, 0xFE, 0xFF, 0xF0, 0xFD, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0xE4, 0x90,
+0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x10,
+0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27,
+0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75,
+0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0,
+0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4,
+0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01,
+0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97, 0x90, 0x04,
+0x78, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x96, 0x12, 0x3D, 0x90,
+0x90, 0x45, 0x44, 0x74, 0x9A, 0xF0, 0x7B, 0xBA, 0x7D, 0x8F, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82,
+0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90, 0x90,
+0x45, 0x44, 0x74, 0x3A, 0xF0, 0x7B, 0xBA, 0x7D, 0x8F, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01,
+0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90, 0x90, 0x43,
+0x18, 0xE0, 0xFD, 0x90, 0x43, 0x17, 0xE0, 0xFB, 0x90, 0x43, 0x16, 0xE0, 0x90, 0x45, 0x44, 0xF0,
+0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x04, 0x79, 0x74, 0x13, 0xF0, 0x90,
+0x04, 0x78, 0x74, 0x05, 0xF0, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x40, 0x7F, 0x0D, 0x12, 0x3C, 0xCD,
+0x90, 0x45, 0x40, 0xE0, 0x44, 0x01, 0xFF, 0xF0, 0xFD, 0x7F, 0x0D, 0x12, 0x3D, 0x00, 0x90, 0x04,
+0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74,
+0x13, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0,
+0xFF, 0xC3, 0x94, 0x0F, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0,
+0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD,
+0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25,
+0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE,
+0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12,
+0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0,
+0x80, 0x97, 0x90, 0x04, 0x78, 0x74, 0x01, 0xF0, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F,
+0x96, 0x12, 0x3D, 0x90, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0xD8, 0x7D, 0x0F, 0x7F, 0xB9, 0x12,
+0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12,
+0x3D, 0x90, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0x7B, 0x78, 0x7D, 0x0F, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x01, 0x92, 0x01, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0x1E, 0x12, 0x3D, 0x90,
+0x90, 0x43, 0x15, 0xE0, 0xFD, 0x90, 0x43, 0x14, 0xE0, 0xFB, 0x90, 0x43, 0x13, 0xE0, 0x90, 0x45,
+0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x04, 0x78, 0x74, 0x05,
+0xF0, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0x90, 0x45, 0x40, 0xEF, 0xF0, 0xD2,
+0x02, 0x90, 0x04, 0x78, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x40, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFD, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x3F, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0xFB, 0xEF, 0x75, 0xF0, 0x03,
+0xA4, 0x24, 0x3E, 0xF5, 0x82, 0xE4, 0x34, 0x42, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0x90, 0x04, 0x78, 0xE0, 0x44, 0x01, 0xF0, 0xE4,
+0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0x90, 0x40, 0xC0, 0xE0, 0xFF,
+0x90, 0x45, 0x40, 0xE0, 0xFD, 0x12, 0x2C, 0x4D, 0xA2, 0x02, 0x22, 0x90, 0x45, 0x31, 0x12, 0x27,
+0xBA, 0xE4, 0xFF, 0x90, 0x04, 0x48, 0xE0, 0x44, 0x10, 0xF0, 0xE4, 0xFD, 0xFC, 0x90, 0x04, 0x48,
+0xE0, 0xFF, 0x30, 0xE4, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07, 0xF0, 0xBD, 0xFF, 0xED,
+0xAE, 0x04, 0xAF, 0x05, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0x90, 0x04, 0x30, 0xE0,
+0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90,
+0x04, 0x31, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12,
+0x26, 0x7C, 0x90, 0x04, 0x32, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27,
+0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x33, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0,
+0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x34, 0xE0, 0xFF, 0x90, 0x45, 0x31,
+0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04, 0x35, 0xE0, 0xFF,
+0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26, 0x7C, 0x90, 0x04,
+0x36, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3, 0xEF, 0x12, 0x26,
+0x7C, 0x90, 0x04, 0x37, 0xE0, 0xFF, 0x90, 0x45, 0x31, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xA3,
+0xEF, 0x12, 0x26, 0x7C, 0xD3, 0x22, 0x7B, 0x01, 0x7A, 0x10, 0x79, 0x34, 0x90, 0x45, 0x3A, 0x12,
+0x27, 0xBA, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x12, 0x12, 0x27, 0xC3, 0xC0, 0x03,
+0xC0, 0x02, 0xC0, 0x01, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x15, 0x12, 0x28, 0x25,
+0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x12, 0x26, 0xDC, 0xFF, 0x90, 0x00, 0x1A,
+0xE5, 0xF0, 0x8F, 0xF0, 0x12, 0x27, 0x61, 0xE4, 0xFF, 0xEF, 0xC3, 0x94, 0x40, 0x50, 0x44, 0x90,
+0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x12, 0x26, 0xDC, 0xD3, 0x94, 0x00, 0xE5, 0xF0,
+0x94, 0x00, 0x40, 0x2F, 0x90, 0x00, 0x12, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x27, 0xF3, 0x12, 0x26,
+0x36, 0xFE, 0xAD, 0x07, 0x0F, 0x74, 0x60, 0x2D, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83, 0xEE,
+0xF0, 0x90, 0x45, 0x3A, 0x12, 0x27, 0x9A, 0x90, 0x00, 0x18, 0x74, 0xFF, 0xF5, 0xF0, 0x12, 0x27,
+0x14, 0x80, 0xB6, 0xEF, 0x70, 0x17, 0x90, 0x06, 0x23, 0x74, 0x80, 0xF0, 0xE4, 0xA3, 0xF0, 0x90,
+0x10, 0x3D, 0xE0, 0xB4, 0x0C, 0x1C, 0x12, 0x3E, 0x36, 0xD2, 0x8C, 0x80, 0x15, 0x30, 0x04, 0x0B,
+0xC2, 0x04, 0xEF, 0x44, 0x80, 0x90, 0x06, 0x23, 0xF0, 0x80, 0x07, 0xD2, 0x04, 0x90, 0x06, 0x23,
+0xEF, 0xF0, 0x90, 0x06, 0x25, 0x74, 0x08, 0xF0, 0x22, 0x90, 0x06, 0x25, 0xE0, 0x30, 0xE0, 0x2F,
+0x90, 0x10, 0x3D, 0xE0, 0x24, 0xFB, 0x70, 0x1D, 0x90, 0x10, 0x49, 0x12, 0x27, 0x9A, 0x90, 0x10,
+0x46, 0x12, 0x27, 0xBA, 0x90, 0x10, 0x4E, 0xE0, 0xFF, 0xA3, 0xE0, 0x90, 0x10, 0x4C, 0xCF, 0xF0,
+0xA3, 0xEF, 0xF0, 0x80, 0x07, 0xE4, 0x90, 0x10, 0x4C, 0xF0, 0xA3, 0xF0, 0x02, 0x33, 0xF6, 0x90,
+0x10, 0x3D, 0xE0, 0x12, 0x28, 0x7E, 0x35, 0x12, 0x01, 0x35, 0x12, 0x05, 0x35, 0x12, 0x07, 0x35,
+0x12, 0x09, 0x35, 0x15, 0x0B, 0x35, 0x12, 0x0C, 0x35, 0x1B, 0x0D, 0x35, 0x21, 0x0F, 0x00, 0x00,
+0x35, 0x5C, 0x02, 0x33, 0xF6, 0xE4, 0x90, 0x10, 0x3D, 0xF0, 0x22, 0xE4, 0x90, 0x10, 0x3D, 0xF0,
+0x22, 0x90, 0x10, 0x50, 0xE0, 0xFF, 0xB4, 0x01, 0x07, 0x90, 0x06, 0x07, 0x74, 0x20, 0xF0, 0x22,
+0xEF, 0xB4, 0x02, 0x07, 0x90, 0x06, 0x07, 0x74, 0x40, 0xF0, 0x22, 0xEF, 0xB4, 0x03, 0x07, 0x90,
+0x06, 0x07, 0x74, 0x60, 0xF0, 0x22, 0xEF, 0xB4, 0x04, 0x07, 0x90, 0x06, 0x07, 0x74, 0x80, 0xF0,
+0x22, 0xEF, 0xB4, 0x05, 0x0C, 0x90, 0x06, 0x07, 0x74, 0xA0, 0xF0, 0x22, 0xE4, 0x90, 0x10, 0x3D,
+0xF0, 0x22, 0x78, 0x7F, 0xE4, 0xF6, 0xD8, 0xFD, 0x75, 0x81, 0x20, 0x02, 0x35, 0xA9, 0x02, 0x23,
+0x50, 0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0x40, 0x03, 0xF6, 0x80, 0x01, 0xF2, 0x08, 0xDF,
+0xF4, 0x80, 0x29, 0xE4, 0x93, 0xA3, 0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33, 0xC4, 0x54,
+0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40, 0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF, 0xE4, 0x80,
+0x0B, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x3E, 0x45, 0xE4, 0x7E, 0x01, 0x93,
+0x60, 0xBC, 0xA3, 0xFF, 0x54, 0x3F, 0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93, 0xA3, 0x60,
+0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25, 0xE0, 0x60, 0xA8, 0x40, 0xB8, 0xE4, 0x93, 0xA3, 0xFA, 0xE4,
+0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xF0, 0xA3,
+0xC8, 0xC5, 0x82, 0xC8, 0xCA, 0xC5, 0x83, 0xCA, 0xDF, 0xE9, 0xDE, 0xE7, 0x80, 0xBE, 0xAC, 0x07,
+0xD2, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83,
+0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83,
+0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83,
+0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xEC, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75,
+0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44,
+0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB,
+0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xAC, 0x07, 0xD2, 0x02, 0xEC, 0x75, 0xF0,
+0x03, 0xA4, 0x24, 0xF0, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0,
+0x03, 0xA4, 0x24, 0xEF, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0,
+0x03, 0xA4, 0x24, 0xEE, 0xF5, 0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0,
+0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98,
+0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97,
+0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96,
+0xF5, 0x82, 0xE4, 0x34, 0x41, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C,
+0x90, 0x82, 0x02, 0x92, 0x02, 0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D,
+0x90, 0xA2, 0x02, 0x22, 0xAC, 0x07, 0xD2, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xF0, 0xF5,
+0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEF, 0xF5,
+0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0xEE, 0xF5,
+0x82, 0xE4, 0x34, 0x40, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x02, 0x92, 0x02, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x98, 0xF5, 0x82, 0xE4, 0x34, 0x41,
+0xF5, 0x83, 0xE0, 0xFD, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x97, 0xF5, 0x82, 0xE4, 0x34, 0x41,
+0xF5, 0x83, 0xE0, 0xFB, 0xEC, 0x75, 0xF0, 0x03, 0xA4, 0x24, 0x96, 0xF5, 0x82, 0xE4, 0x34, 0x41,
+0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x02, 0x92, 0x02,
+0xE4, 0x90, 0x45, 0x44, 0xF0, 0xFB, 0xFD, 0x7F, 0xC8, 0x12, 0x3D, 0x90, 0xA2, 0x02, 0x22, 0xD2,
+0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04, 0x78, 0x74, 0x05, 0xF0,
+0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3,
+0x94, 0x0B, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF,
+0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42,
+0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5,
+0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0,
+0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90,
+0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97,
+0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0,
+0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04, 0x78, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3,
+0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE, 0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x0D, 0xEE, 0x64, 0x80, 0x94,
+0x80, 0x50, 0x57, 0x90, 0x42, 0xEB, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0,
+0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12,
+0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9,
+0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83,
+0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45,
+0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12, 0x26, 0xB0, 0x80, 0x97, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0,
+0xA2, 0x01, 0x22, 0xD2, 0x01, 0xE4, 0x90, 0x04, 0x78, 0xF0, 0xA3, 0x74, 0x1B, 0xF0, 0x90, 0x04,
+0x78, 0x74, 0x05, 0xF0, 0xE4, 0x90, 0x45, 0x3E, 0xF0, 0xA3, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFE,
+0xA3, 0xE0, 0xFF, 0xC3, 0x94, 0x0F, 0xEE, 0x64, 0x80, 0x94, 0x80, 0x50, 0x57, 0x90, 0x42, 0xEB,
+0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83,
+0xE0, 0xFD, 0x90, 0x42, 0xEA, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27, 0x8E, 0xEE, 0x75, 0xF0, 0x03,
+0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0xFB, 0x90, 0x42, 0xE9, 0x75, 0xF0, 0x03, 0xEF, 0x12, 0x27,
+0x8E, 0xEE, 0x75, 0xF0, 0x03, 0xA4, 0x25, 0x83, 0xF5, 0x83, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F,
+0xB9, 0x12, 0x3C, 0x90, 0x82, 0x01, 0x92, 0x01, 0x90, 0x45, 0x3E, 0xE4, 0x75, 0xF0, 0x01, 0x12,
+0x26, 0xB0, 0x80, 0x97, 0x90, 0x04, 0x62, 0x74, 0xC0, 0xF0, 0xA2, 0x01, 0x22, 0x90, 0x45, 0x3E,
+0xED, 0xF0, 0xD2, 0x01, 0x90, 0x04, 0x57, 0xE0, 0x90, 0x45, 0x3F, 0xF0, 0x90, 0x04, 0x57, 0xE0,
+0x54, 0xFE, 0xF0, 0xEF, 0x12, 0x28, 0x7E, 0x39, 0x60, 0x03, 0x39, 0x78, 0x09, 0x39, 0x6C, 0x0A,
+0x39, 0x78, 0x0C, 0x39, 0x84, 0x0D, 0x39, 0x60, 0x0E, 0x39, 0x90, 0x0F, 0x00, 0x00, 0x39, 0x9C,
+0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x35, 0xEE, 0x92, 0x01, 0x80, 0x32, 0x90, 0x45, 0x3E, 0xE0,
+0xFF, 0x12, 0x32, 0x3A, 0x92, 0x01, 0x80, 0x26, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x36, 0x79,
+0x92, 0x01, 0x80, 0x1A, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x37, 0x04, 0x92, 0x01, 0x80, 0x0E,
+0x90, 0x45, 0x3E, 0xE0, 0xFF, 0x12, 0x2E, 0xDF, 0x92, 0x01, 0x80, 0x02, 0xC2, 0x01, 0x12, 0x3D,
+0xE2, 0x90, 0x45, 0x3F, 0xE0, 0x90, 0x04, 0x57, 0xF0, 0x90, 0x45, 0x3E, 0xE0, 0x90, 0x40, 0xC0,
+0xF0, 0xA2, 0x01, 0x22, 0xAC, 0x07, 0xE4, 0x90, 0x45, 0x3A, 0xF0, 0xA3, 0xF0, 0xD2, 0x00, 0x7D,
+0x03, 0xEC, 0x70, 0x13, 0x12, 0x3C, 0xC5, 0x90, 0x45, 0x3B, 0xE0, 0x54, 0xF9, 0xFF, 0xF0, 0xFD,
+0x7F, 0x09, 0x12, 0x3D, 0x00, 0x80, 0x59, 0xEC, 0xB4, 0x01, 0x16, 0x12, 0x3C, 0xC5, 0x90, 0x45,
+0x3B, 0xE0, 0x54, 0xFD, 0xF0, 0x44, 0x04, 0xFF, 0xF0, 0xFD, 0x7F, 0x09, 0x12, 0x3D, 0x00, 0x80,
+0x3F, 0xEC, 0xB4, 0x02, 0x1B, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3A, 0x7F, 0x0A, 0x12, 0x3C, 0xCD,
+0x90, 0x45, 0x3A, 0xE0, 0x54, 0xFC, 0xFF, 0xF0, 0xFD, 0x7F, 0x0A, 0x12, 0x3D, 0x00, 0x80, 0x20,
+0xEC, 0xB4, 0x03, 0x1C, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3A, 0x7F, 0x0A, 0x12, 0x3C, 0xCD, 0x90,
+0x45, 0x3A, 0xE0, 0x54, 0xFE, 0xF0, 0x44, 0x02, 0xFF, 0xF0, 0xFD, 0x7F, 0x0A, 0x12, 0x3D, 0x00,
+0xA2, 0x00, 0x22, 0x90, 0x45, 0x38, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0x90, 0x04, 0x0B, 0xE0, 0xF9,
+0x54, 0xFB, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x09, 0x74, 0x50, 0xF0, 0x90, 0x45, 0x38, 0xE0,
+0x90, 0x04, 0x0A, 0xF0, 0x90, 0x45, 0x39, 0xE0, 0x90, 0x04, 0x0E, 0xF0, 0x90, 0x04, 0x08, 0x74,
+0x80, 0xF0, 0xE4, 0xFD, 0xFC, 0x90, 0x04, 0x08, 0xE0, 0x90, 0x45, 0x3A, 0xF0, 0xE0, 0x54, 0x03,
+0x70, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07, 0xEB, 0xBD, 0xFF, 0xE8, 0xC3, 0xED, 0x94,
+0xFF, 0xEC, 0x94, 0x07, 0x50, 0x07, 0x90, 0x45, 0x3A, 0xE0, 0x30, 0xE1, 0x0B, 0x0F, 0xBF, 0x00,
+0x01, 0x0E, 0xBE, 0x07, 0xB1, 0xBF, 0xFF, 0xAE, 0xBE, 0x07, 0x0A, 0xBF, 0xFF, 0x07, 0x90, 0x04,
+0x0B, 0xE9, 0xF0, 0xC3, 0x22, 0xAF, 0x01, 0x90, 0x04, 0x0B, 0xE9, 0xF0, 0xD3, 0x22, 0x90, 0x45,
+0x35, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0xEE, 0x70, 0x56, 0xEF, 0x24, 0xF6, 0x60, 0x1B, 0x14, 0x60,
+0x26, 0x14, 0x60, 0x31, 0x14, 0x60, 0x3C, 0x24, 0x04, 0x70, 0x44, 0x7B, 0x01, 0x7A, 0x42, 0x79,
+0xE9, 0x90, 0x45, 0x37, 0x12, 0x27, 0xBA, 0x80, 0x36, 0x7B, 0x01, 0x7A, 0x40, 0x79, 0xC1, 0x90,
+0x45, 0x37, 0x12, 0x27, 0xBA, 0x80, 0x28, 0x7B, 0x01, 0x7A, 0x40, 0x79, 0xF1, 0x90, 0x45, 0x37,
+0x12, 0x27, 0xBA, 0x80, 0x1A, 0x7B, 0x01, 0x7A, 0x41, 0x79, 0x99, 0x90, 0x45, 0x37, 0x12, 0x27,
+0xBA, 0x80, 0x0C, 0x7B, 0x01, 0x7A, 0x42, 0x79, 0x41, 0x90, 0x45, 0x37, 0x12, 0x27, 0xBA, 0x90,
+0x45, 0x36, 0xE0, 0xFF, 0xA3, 0x12, 0x27, 0x9A, 0x90, 0x45, 0x35, 0xE0, 0xF5, 0x82, 0x75, 0x83,
+0x00, 0xEF, 0x02, 0x26, 0x8E, 0x90, 0x45, 0x3F, 0xEF, 0xF0, 0xA3, 0x74, 0xFF, 0xF0, 0x90, 0x04,
+0x0B, 0xE0, 0x90, 0x45, 0x41, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x09, 0x74, 0x50, 0xF0, 0x90,
+0x45, 0x3F, 0xE0, 0x90, 0x04, 0x0A, 0xF0, 0x90, 0x04, 0x08, 0x74, 0x40, 0xF0, 0xE4, 0xFD, 0xFC,
+0x90, 0x04, 0x08, 0xE0, 0xF9, 0x54, 0x03, 0x70, 0x0B, 0x0D, 0xBD, 0x00, 0x01, 0x0C, 0xBC, 0x07,
+0xEF, 0xBD, 0xFF, 0xEC, 0xC3, 0xED, 0x94, 0xFF, 0xEC, 0x94, 0x07, 0x50, 0x04, 0xE9, 0x30, 0xE1,
+0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xC0, 0xBF, 0xFF, 0xBD, 0x90, 0x04, 0x0C, 0xE0,
+0x90, 0x45, 0x40, 0xF0, 0xA3, 0xE0, 0x90, 0x04, 0x0B, 0xF0, 0x90, 0x45, 0x40, 0xE0, 0xFF, 0x22,
+0xE4, 0xFE, 0xEF, 0x30, 0xE5, 0x11, 0xE4, 0xFC, 0xFD, 0x7C, 0x08, 0x90, 0x04, 0xD4, 0xE4, 0xF0,
+0xA3, 0xDC, 0xFC, 0x7C, 0x00, 0x7D, 0x08, 0xEF, 0x54, 0xC0, 0x60, 0x12, 0xE4, 0xFC, 0xFD, 0x7C,
+0x08, 0x90, 0x04, 0xD4, 0x74, 0xFF, 0xF0, 0xA3, 0xDC, 0xFC, 0x7C, 0x00, 0x7D, 0x08, 0xEF, 0x30,
+0xE6, 0x07, 0xEE, 0x44, 0x78, 0xFE, 0x54, 0xFE, 0xFE, 0xEF, 0x54, 0x88, 0x60, 0x04, 0xEE, 0x44,
+0x08, 0xFE, 0xEF, 0x30, 0xE4, 0x04, 0xEE, 0x44, 0x10, 0xFE, 0xEF, 0x30, 0xE1, 0x04, 0xEE, 0x44,
+0x02, 0xFE, 0x90, 0x04, 0x56, 0xE0, 0xFF, 0x6E, 0x60, 0x02, 0xEE, 0xF0, 0x22, 0xC0, 0xE0, 0xC0,
+0x83, 0xC0, 0x82, 0xC0, 0xD0, 0x75, 0xD0, 0x00, 0xC0, 0x07, 0xD2, 0x05, 0x53, 0xA8, 0xFE, 0x90,
+0x06, 0x20, 0xE4, 0xF0, 0x90, 0x04, 0x58, 0xF0, 0xA3, 0xF0, 0x90, 0x06, 0x21, 0xE0, 0xFF, 0x90,
+0x10, 0x39, 0xE0, 0x4F, 0xF0, 0x90, 0x06, 0x21, 0xEF, 0xF0, 0x90, 0x04, 0x5C, 0xE0, 0xFF, 0x90,
+0x45, 0x46, 0xE0, 0x4F, 0xF0, 0x90, 0x04, 0x5C, 0xEF, 0xF0, 0xA3, 0xE0, 0xFF, 0x90, 0x45, 0x47,
+0xE0, 0x4F, 0xF0, 0x90, 0x04, 0x5D, 0xEF, 0xF0, 0xD0, 0x07, 0xD0, 0xD0, 0xD0, 0x82, 0xD0, 0x83,
+0xD0, 0xE0, 0x32, 0x90, 0x04, 0x79, 0x74, 0x11, 0xF0, 0x12, 0x3D, 0x31, 0xE4, 0x90, 0x45, 0x3E,
+0xF0, 0x90, 0x45, 0x3E, 0xE0, 0xFF, 0xC3, 0x94, 0x06, 0x50, 0x1A, 0x12, 0x3B, 0x25, 0x90, 0x45,
+0x3E, 0xE0, 0x24, 0xC4, 0xF5, 0x82, 0xE4, 0x34, 0x04, 0xF5, 0x83, 0xEF, 0xF0, 0x90, 0x45, 0x3E,
+0xE0, 0x04, 0xF0, 0x80, 0xDC, 0x90, 0x04, 0x48, 0x74, 0x02, 0xF0, 0x14, 0xF0, 0x7F, 0x30, 0x12,
+0x3B, 0x90, 0x90, 0x04, 0x54, 0x74, 0x02, 0xF0, 0x22, 0xE0, 0x90, 0x45, 0x44, 0xF0, 0x7F, 0xB9,
+0x90, 0x04, 0x71, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x45, 0x44, 0xE0, 0x90, 0x04, 0x73, 0xF0,
+0x90, 0x04, 0x70, 0xEF, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x70, 0xE0, 0xFD, 0x20, 0xE2, 0x0B,
+0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05, 0xBF, 0xFF,
+0x02, 0xC3, 0x22, 0xD3, 0x22, 0x7B, 0x01, 0x7A, 0x45, 0x79, 0x3B, 0x7F, 0x09, 0x90, 0x04, 0x6E,
+0xEF, 0xF0, 0x90, 0x04, 0x6C, 0xE0, 0x44, 0x02, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x6C, 0xE0,
+0xFD, 0x20, 0xE2, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0x90,
+0x04, 0x6F, 0xE0, 0x12, 0x26, 0x7C, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0xD3, 0x22,
+0x90, 0x04, 0x6E, 0xEF, 0xF0, 0x90, 0x04, 0x6F, 0xED, 0xF0, 0x90, 0x04, 0x6C, 0xE0, 0x44, 0x01,
+0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x6C, 0xE0, 0xFD, 0x20, 0xE2, 0x0B, 0x0F, 0xBF, 0x00, 0x01,
+0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05, 0xBF, 0xFF, 0x02, 0xC3, 0x22, 0xD3,
+0x22, 0x90, 0x04, 0x54, 0x74, 0x01, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x54, 0xE0, 0xFD, 0x30,
+0xE0, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED, 0xBE, 0x07, 0x05,
+0xBF, 0xFF, 0x02, 0xC3, 0x22, 0x90, 0x06, 0x38, 0xE0, 0x44, 0x02, 0xF0, 0xE0, 0x44, 0x01, 0xF0,
+0xD3, 0x22, 0xEF, 0x12, 0x28, 0x7E, 0x3D, 0x7F, 0x03, 0x3D, 0x85, 0x09, 0x3D, 0x82, 0x0A, 0x3D,
+0x85, 0x0C, 0x3D, 0x88, 0x0D, 0x3D, 0x7F, 0x0E, 0x3D, 0x8B, 0x0F, 0x00, 0x00, 0x3D, 0x8E, 0x02,
+0x31, 0x47, 0x02, 0x30, 0x1A, 0x02, 0x37, 0x8F, 0x02, 0x38, 0x19, 0x02, 0x38, 0xA3, 0xC3, 0x22,
+0x90, 0x04, 0x1C, 0xEF, 0xF0, 0xA3, 0xED, 0xF0, 0xA3, 0xEB, 0xF0, 0x90, 0x45, 0x44, 0xE0, 0x90,
+0x04, 0x1F, 0xF0, 0x90, 0x04, 0x18, 0x74, 0x03, 0xF0, 0x90, 0x04, 0x18, 0xE0, 0xFF, 0x60, 0x04,
+0xEF, 0x30, 0xE2, 0xF5, 0xE4, 0x90, 0x04, 0x18, 0xF0, 0x22, 0x7F, 0xFF, 0x90, 0x04, 0x14, 0xE0,
+0xFF, 0x14, 0x60, 0x0E, 0x14, 0x60, 0x0F, 0x14, 0x60, 0x10, 0x24, 0x03, 0x70, 0x10, 0x02, 0x0B,
+0xBE, 0x22, 0x02, 0x0B, 0xB5, 0x22, 0x02, 0x0B, 0xAE, 0x22, 0x02, 0x0B, 0xEF, 0x22, 0x02, 0x00,
+0x00, 0x22, 0xD2, 0x02, 0x7D, 0x40, 0x7F, 0x50, 0x12, 0x3D, 0x00, 0xE4, 0xFD, 0x7F, 0x50, 0x12,
+0x3D, 0x00, 0x7D, 0x01, 0x7F, 0x9C, 0x12, 0x3D, 0x00, 0xE4, 0xFD, 0x7F, 0x9C, 0x12, 0x3D, 0x00,
+0xA2, 0x02, 0x22, 0x90, 0x04, 0x61, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0xFF, 0xFE, 0x90, 0x04, 0x61,
+0xE0, 0xFD, 0x20, 0xE5, 0x0B, 0x0F, 0xBF, 0x00, 0x01, 0x0E, 0xBE, 0x07, 0xF0, 0xBF, 0xFF, 0xED,
+0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xC2, 0x8C, 0x90, 0x43, 0x19, 0x74, 0x01, 0xF0, 0xD0,
+0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC2, 0x8C, 0x75, 0x89, 0x01, 0x75, 0x8C, 0xF9, 0x75, 0x8A,
+0x7E, 0x43, 0xA8, 0x02, 0x22, 0x44, 0x43, 0x1A, 0x04, 0x03, 0x09, 0x04, 0x00,
+};
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+BOOL
+FIRMWAREbDownload(
+    IN PSDevice pDevice
+    )
+{
+    NDIS_STATUS NdisStatus;
+    PBYTE       pBuffer = NULL;
+    WORD        wLength;
+    int         ii;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n");
+    spin_unlock_irq(&pDevice->lock);
+    pBuffer = kmalloc(sizeof(abyFirmware), GFP_KERNEL);
+    if (pBuffer != NULL) {
+
+        for (ii=0;ii<sizeof(abyFirmware);ii++)
+            pBuffer[ii] = abyFirmware[ii];
+
+        for (ii=0;ii<sizeof(abyFirmware);ii+=0x400) {
+
+            if ((sizeof(abyFirmware) - ii) < 0x400)
+                wLength = (sizeof(abyFirmware) - ii);
+            else
+                wLength = 0x400;
+
+            NdisStatus = CONTROLnsRequestOutAsyn(pDevice,
+                                            0,
+                                            0x1200+ii,
+                                            0x0000,
+                                            wLength,
+                                            &(pBuffer[ii])
+                                            );
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Download firmware...%d %ld\n", ii, sizeof(abyFirmware));
+            if (NdisStatus != STATUS_SUCCESS) {
+                if (pBuffer)
+                    kfree(pBuffer);
+                spin_lock_irq(&pDevice->lock);
+                return (FALSE);
+            }
+        }
+    }
+
+    if (pBuffer)
+        kfree(pBuffer);
+
+    spin_lock_irq(&pDevice->lock);
+    return (TRUE);
+}
+
+BOOL
+FIRMWAREbBrach2Sram(
+    IN PSDevice pDevice
+    )
+{
+    NDIS_STATUS NdisStatus;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Branch to Sram\n");
+
+    NdisStatus = CONTROLnsRequestOut(pDevice,
+                                    1,
+                                    0x1200,
+                                    0x0000,
+                                    0,
+                                    NULL
+                                    );
+
+    if (NdisStatus != STATUS_SUCCESS) {
+        return (FALSE);
+    } else {
+        return (TRUE);
+    }
+}
+
+
+BOOL
+FIRMWAREbCheckVersion(
+    IN PSDevice pDevice
+    )
+{
+    NTSTATUS                ntStatus;
+
+    ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    0,
+                                    MESSAGE_REQUEST_VERSION,
+                                    2,
+                                    (PBYTE) &(pDevice->wFirmwareVersion));
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
+    if (ntStatus != STATUS_SUCCESS) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Invalid.\n");
+        return FALSE;
+    }
+    if (pDevice->wFirmwareVersion == 0xFFFF) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"In Loader.\n");
+        return FALSE;
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Firmware Version [%04x]\n", pDevice->wFirmwareVersion);
+    if (pDevice->wFirmwareVersion != FIRMWARE_VERSION) {
+        // branch to loader for download new firmware
+        FIRMWAREbBrach2Sram(pDevice);
+        return FALSE;
+    }
+    return TRUE;
+}
diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h
new file mode 100644
index 0000000..97f8559
--- /dev/null
+++ b/drivers/staging/vt6656/firmware.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: firmware.h
+ *
+ * Purpose: Version and Release Information
+ *
+ * Author: Yiching Chen
+ *
+ * Date: May 20, 2004
+ *
+ */
+
+#ifndef __FIRMWARE_H__
+#define __FIRMWARE_H__
+
+#include "ttype.h"
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+BOOL
+FIRMWAREbDownload(
+    IN PSDevice pDevice
+    );
+
+BOOL
+FIRMWAREbBrach2Sram(
+    IN PSDevice pDevice
+    );
+
+BOOL
+FIRMWAREbCheckVersion(
+    IN PSDevice pDevice
+    );
+
+
+#endif // __FIRMWARE_H__
diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c
new file mode 100644
index 0000000..0c8267a
--- /dev/null
+++ b/drivers/staging/vt6656/hostap.c
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: hostap.c
+ *
+ * Purpose: handle hostap deamon ioctl input/out functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Oct. 20, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "hostap.h"
+#include "iocmd.h"
+#include "mac.h"
+#include "card.h"
+#include "baseband.h"
+#include "wpactl.h"
+#include "key.h"
+#include "mac.h"
+#include "datarate.h"
+
+#define VIAWGET_HOSTAPD_MAX_BUF_SIZE 1024
+#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT0
+#define HOSTAP_CRYPT_FLAG_PERMANENT BIT1
+#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2
+#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3
+#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4
+#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5
+#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6
+#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+/*---------------------  Static Functions  --------------------------*/
+
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*
+ * Description:
+ *      register net_device (AP) for hostap deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      rtnl_locked         -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked)
+{
+    PSDevice apdev_priv;
+	struct net_device *dev = pDevice->dev;
+	int ret;
+	const struct net_device_ops apdev_netdev_ops = {
+		.ndo_start_xmit         = pDevice->tx_80211,
+	};
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name);
+
+	pDevice->apdev = (struct net_device *)kmalloc(sizeof(struct net_device), GFP_KERNEL);
+	if (pDevice->apdev == NULL)
+		return -ENOMEM;
+	memset(pDevice->apdev, 0, sizeof(struct net_device));
+
+    apdev_priv = netdev_priv(pDevice->apdev);
+    *apdev_priv = *pDevice;
+	memcpy(pDevice->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
+
+	pDevice->apdev->netdev_ops = &apdev_netdev_ops;
+
+	pDevice->apdev->type = ARPHRD_IEEE80211;
+
+	pDevice->apdev->base_addr = dev->base_addr;
+	pDevice->apdev->irq = dev->irq;
+	pDevice->apdev->mem_start = dev->mem_start;
+	pDevice->apdev->mem_end = dev->mem_end;
+	sprintf(pDevice->apdev->name, "%sap", dev->name);
+	if (rtnl_locked)
+		ret = register_netdevice(pDevice->apdev);
+	else
+		ret = register_netdev(pDevice->apdev);
+	if (ret) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n",
+		       dev->name);
+		return -1;
+	}
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n",
+	       dev->name, pDevice->apdev->name);
+
+    KeyvInitTable(pDevice,&pDevice->sKey);
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      unregister net_device(AP)
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      rtnl_locked         -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked)
+{
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name);
+
+    if (pDevice->apdev && pDevice->apdev->name && pDevice->apdev->name[0]) {
+		if (rtnl_locked)
+			unregister_netdevice(pDevice->apdev);
+		else
+			unregister_netdev(pDevice->apdev);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+		       pDevice->dev->name, pDevice->apdev->name);
+	}
+	kfree(pDevice->apdev);
+	pDevice->apdev = NULL;
+    pDevice->bEnable8021x = FALSE;
+    pDevice->bEnableHostWEP = FALSE;
+    pDevice->bEncryptionEnable = FALSE;
+
+	return 0;
+}
+
+
+/*
+ * Description:
+ *      Set enable/disable hostapd mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      rtnl_locked         -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked)
+{
+	if (val < 0 || val > 1)
+		return -EINVAL;
+
+	if (pDevice->bEnableHostapd == val)
+		return 0;
+
+	pDevice->bEnableHostapd = val;
+
+	if (val)
+		return hostap_enable_hostapd(pDevice, rtnl_locked);
+	else
+		return hostap_disable_hostapd(pDevice, rtnl_locked);
+}
+
+
+/*
+ * Description:
+ *      remove station function supported for hostap deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_remove_sta(PSDevice pDevice,
+				     struct viawget_hostapd_param *param)
+{
+	UINT uNodeIndex;
+
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+        BSSvRemoveOneNode(pDevice, uNodeIndex);
+    }
+    else {
+        return -ENOENT;
+    }
+	return 0;
+}
+
+/*
+ * Description:
+ *      add a station from hostap deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_add_sta(PSDevice pDevice,
+				  struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+
+    if (!BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+        BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
+    }
+    memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN);
+    pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
+    pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = param->u.add_sta.capability;
+// TODO listenInterval
+//    pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = 1;
+    pMgmt->sNodeDBTable[uNodeIndex].bPSEnable = FALSE;
+    pMgmt->sNodeDBTable[uNodeIndex].bySuppRate = param->u.add_sta.tx_supp_rates;
+
+    // set max tx rate
+    pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
+           pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+    // set max basic rate
+    pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate = RATE_2M;
+    // Todo: check sta preamble, if ap can't support, set status code
+    pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
+            WLAN_GET_CAP_INFO_SHORTPREAMBLE(pMgmt->sNodeDBTable[uNodeIndex].wCapInfo);
+
+    pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)param->u.add_sta.aid;
+
+    pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d \n", pMgmt->sNodeDBTable[uNodeIndex].wAID);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+               param->sta_addr[0],
+               param->sta_addr[1],
+               param->sta_addr[2],
+               param->sta_addr[3],
+               param->sta_addr[4],
+               param->sta_addr[5]
+              ) ;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d \n",
+               pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      get station info
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int hostap_get_info_sta(PSDevice pDevice,
+				       struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+	    param->u.get_info_sta.inactive_sec =
+	        (jiffies - pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer) / HZ;
+
+	    //param->u.get_info_sta.txexc = pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts;
+	}
+	else {
+	    return -ENOENT;
+	}
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      reset txexec
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *      TURE, FALSE
+ *
+ * Return Value:
+ *
+ */
+/*
+static int hostap_reset_txexc_sta(PSDevice pDevice,
+					  struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+        pMgmt->sNodeDBTable[uNodeIndex].uTxAttempts = 0;
+	}
+	else {
+	    return -ENOENT;
+	}
+
+	return 0;
+}
+*/
+
+/*
+ * Description:
+ *      set station flag
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_set_flags_sta(PSDevice pDevice,
+					struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	UINT uNodeIndex;
+
+    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &uNodeIndex)) {
+		pMgmt->sNodeDBTable[uNodeIndex].dwFlags |= param->u.set_flags_sta.flags_or;
+		pMgmt->sNodeDBTable[uNodeIndex].dwFlags &= param->u.set_flags_sta.flags_and;
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x \n",
+		            (UINT)pMgmt->sNodeDBTable[uNodeIndex].dwFlags);
+	}
+	else {
+	    return -ENOENT;
+	}
+
+	return 0;
+}
+
+
+
+/*
+ * Description:
+ *      set generic element (wpa ie)
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_set_generic_element(PSDevice pDevice,
+					struct viawget_hostapd_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+
+
+    memcpy( pMgmt->abyWPAIE,
+            param->u.generic_elem.data,
+            param->u.generic_elem.len
+           );
+
+    pMgmt->wWPAIELen = 	param->u.generic_elem.len;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pMgmt->wWPAIELen = %d\n",  pMgmt->wWPAIELen);
+
+    // disable wpa
+    if (pMgmt->wWPAIELen == 0) {
+        pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA \n");
+    } else  {
+        // enable wpa
+        if ((pMgmt->abyWPAIE[0] == WLAN_EID_RSN_WPA) ||
+             (pMgmt->abyWPAIE[0] == WLAN_EID_RSN)) {
+              pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+               DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n");
+        } else
+            return -EINVAL;
+    }
+
+	return 0;
+}
+
+/*
+ * Description:
+ *      flush station nodes table.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static void hostap_flush_sta(PSDevice pDevice)
+{
+    // reserved node index =0 for multicast node.
+    BSSvClearNodeDBTable(pDevice, 1);
+    pDevice->uAssocCount = 0;
+
+    return;
+}
+
+/*
+ * Description:
+ *      set each stations encryption key
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_set_encryption(PSDevice pDevice,
+				       struct viawget_hostapd_param *param,
+				       int param_len)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    DWORD   dwKeyIndex = 0;
+    BYTE    abyKey[MAX_KEY_LEN];
+    BYTE    abySeq[MAX_KEY_LEN];
+    NDIS_802_11_KEY_RSC   KeyRSC;
+    BYTE    byKeyDecMode = KEY_CTL_WEP;
+	int     ret = 0;
+	int     iNodeIndex = -1;
+	int     ii;
+	BOOL    bKeyTableFull = FALSE;
+	WORD    wKeyCtl = 0;
+
+
+	param->u.crypt.err = 0;
+/*
+	if (param_len !=
+	    (int) ((char *) param->u.crypt.key - (char *) param) +
+	    param->u.crypt.key_len)
+		return -EINVAL;
+*/
+
+	if (param->u.crypt.alg > WPA_ALG_CCMP)
+		return -EINVAL;
+
+
+	if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) {
+		param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED;
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n");
+		return -EINVAL;
+	}
+
+	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+		if (param->u.crypt.idx >= MAX_GROUP_KEY)
+			return -EINVAL;
+        iNodeIndex = 0;
+
+	} else {
+	    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) {
+	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+	        return -EINVAL;
+	    }
+	}
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d \n", iNodeIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d \n", param->u.crypt.alg);
+
+	if (param->u.crypt.alg == WPA_ALG_NONE) {
+
+        if (pMgmt->sNodeDBTable[iNodeIndex].bOnFly == TRUE) {
+            if (KeybRemoveKey( pDevice,
+                               &(pDevice->sKey),
+                               param->sta_addr,
+                               pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex
+                              ) == FALSE) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail \n");
+            }
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+        }
+        pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
+        pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = 0;
+        memset(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+                0,
+                MAX_KEY_LEN
+               );
+
+        return ret;
+	}
+
+    memcpy(abyKey, param->u.crypt.key, param->u.crypt.key_len);
+    // copy to node key tbl
+    pMgmt->sNodeDBTable[iNodeIndex].byKeyIndex = param->u.crypt.idx;
+    pMgmt->sNodeDBTable[iNodeIndex].uWepKeyLength = param->u.crypt.key_len;
+    memcpy(&pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+            param->u.crypt.key,
+            param->u.crypt.key_len
+           );
+
+    dwKeyIndex = (DWORD)(param->u.crypt.idx);
+    if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) {
+        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+        pDevice->bTransmitKey = TRUE;
+        dwKeyIndex |= (1 << 31);
+    }
+
+	if (param->u.crypt.alg == WPA_ALG_WEP) {
+
+        if ((pDevice->bEnable8021x == FALSE) || (iNodeIndex == 0)) {
+            KeybSetDefaultKey(  pDevice,
+                                &(pDevice->sKey),
+                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+                                param->u.crypt.key_len,
+                                NULL,
+                                abyKey,
+                                KEY_CTL_WEP
+                             );
+
+        } else {
+            // 8021x enable, individual key
+            dwKeyIndex |= (1 << 30); // set pairwise key
+            if (KeybSetKey(pDevice,
+                           &(pDevice->sKey),
+                           &param->sta_addr[0],
+                           dwKeyIndex & ~(USE_KEYRSC),
+                           param->u.crypt.key_len,
+                           (PQWORD) &(KeyRSC),
+                           (PBYTE)abyKey,
+                            KEY_CTL_WEP
+                           ) == TRUE) {
+
+
+                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+            } else {
+                // Key Table Full
+                pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+                bKeyTableFull = TRUE;
+            }
+        }
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+        pDevice->bEncryptionEnable = TRUE;
+        pMgmt->byCSSPK = KEY_CTL_WEP;
+        pMgmt->byCSSGK = KEY_CTL_WEP;
+        pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = KEY_CTL_WEP;
+        pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
+        return ret;
+	}
+
+	if (param->u.crypt.seq) {
+	    memcpy(&abySeq, param->u.crypt.seq, 8);
+		for (ii = 0 ; ii < 8 ; ii++) {
+	         KeyRSC |= (abySeq[ii] << (ii * 8));
+		}
+		dwKeyIndex |= 1 << 29;
+		pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC;
+	}
+
+	if (param->u.crypt.alg == WPA_ALG_TKIP) {
+	    if (param->u.crypt.key_len != MAX_KEY_LEN)
+	        return -EINVAL;
+	    pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+        byKeyDecMode = KEY_CTL_TKIP;
+        pMgmt->byCSSPK = KEY_CTL_TKIP;
+        pMgmt->byCSSGK = KEY_CTL_TKIP;
+	}
+
+	if (param->u.crypt.alg == WPA_ALG_CCMP) {
+	    if ((param->u.crypt.key_len != AES_KEY_LEN) ||
+	        (pDevice->byLocalID <= REV_ID_VT3253_A1))
+	        return -EINVAL;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+        byKeyDecMode = KEY_CTL_CCMP;
+        pMgmt->byCSSPK = KEY_CTL_CCMP;
+        pMgmt->byCSSGK = KEY_CTL_CCMP;
+    }
+
+
+    if (iNodeIndex == 0) {
+       KeybSetDefaultKey(  pDevice,
+                           &(pDevice->sKey),
+                           dwKeyIndex,
+                           param->u.crypt.key_len,
+                           (PQWORD) &(KeyRSC),
+                           abyKey,
+                           byKeyDecMode
+                          );
+       pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+    } else {
+        dwKeyIndex |= (1 << 30); // set pairwise key
+        if (KeybSetKey(pDevice,
+                       &(pDevice->sKey),
+                       &param->sta_addr[0],
+                       dwKeyIndex,
+                       param->u.crypt.key_len,
+                       (PQWORD) &(KeyRSC),
+                       (PBYTE)abyKey,
+                        byKeyDecMode
+                       ) == TRUE) {
+
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = TRUE;
+
+        } else {
+            // Key Table Full
+            pMgmt->sNodeDBTable[iNodeIndex].bOnFly = FALSE;
+            bKeyTableFull = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n");
+        }
+
+    }
+
+    if (bKeyTableFull == TRUE) {
+        wKeyCtl &= 0x7F00;              // clear all key control filed
+        wKeyCtl |= (byKeyDecMode << 4);
+        wKeyCtl |= (byKeyDecMode);
+        wKeyCtl |= 0x0044;              // use group key for all address
+        wKeyCtl |= 0x4000;              // disable KeyTable[MAX_KEY_TABLE-1] on-fly to genernate rx int
+// Todo.. xxxxxx
+        //MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID);
+    }
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d \n", iNodeIndex);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d \n", param->u.crypt.idx,
+               param->u.crypt.key_len );
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[0],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[1],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[2],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[3],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[4]
+              );
+
+	// set wep key
+    pDevice->bEncryptionEnable = TRUE;
+    pMgmt->sNodeDBTable[iNodeIndex].byCipherSuite = byKeyDecMode;
+    pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex = dwKeyIndex;
+    pMgmt->sNodeDBTable[iNodeIndex].dwTSC47_16 = 0;
+    pMgmt->sNodeDBTable[iNodeIndex].wTSC15_0 = 0;
+
+	return ret;
+}
+
+
+
+/*
+ * Description:
+ *      get each stations encryption key
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+static int hostap_get_encryption(PSDevice pDevice,
+				       struct viawget_hostapd_param *param,
+				       int param_len)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	int     ret = 0;
+	int     ii;
+	int     iNodeIndex =0;
+
+
+	param->u.crypt.err = 0;
+
+	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
+	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
+	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
+        iNodeIndex = 0;
+	} else {
+	    if (BSSbIsSTAInNodeDB(pDevice, param->sta_addr, &iNodeIndex) == FALSE) {
+	        param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n");
+	        return -EINVAL;
+	    }
+	}
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex);
+    memset(param->u.crypt.seq, 0, 8);
+    for (ii = 0 ; ii < 8 ; ii++) {
+        param->u.crypt.seq[ii] = (BYTE)pMgmt->sNodeDBTable[iNodeIndex].KeyRSC >> (ii * 8);
+    }
+
+	return ret;
+}
+
+
+/*
+ * Description:
+ *      hostap_ioctl main function supported for hostap deamon.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      iw_point  -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int hostap_ioctl(PSDevice pDevice, struct iw_point *p)
+{
+	struct viawget_hostapd_param *param;
+	int ret = 0;
+	int ap_ioctl = 0;
+
+	if (p->length < sizeof(struct viawget_hostapd_param) ||
+	    p->length > VIAWGET_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
+		return -EINVAL;
+
+	param = (struct viawget_hostapd_param *) kmalloc((int)p->length, (int)GFP_KERNEL);
+	if (param == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(param, p->pointer, p->length)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	switch (param->cmd) {
+	case VIAWGET_HOSTAPD_SET_ENCRYPTION:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION \n");
+        spin_lock_irq(&pDevice->lock);
+		ret = hostap_set_encryption(pDevice, param, p->length);
+        spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_GET_ENCRYPTION:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION \n");
+        spin_lock_irq(&pDevice->lock);
+		ret = hostap_get_encryption(pDevice, param, p->length);
+        spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR \n");
+		return -EOPNOTSUPP;
+		break;
+	case VIAWGET_HOSTAPD_FLUSH:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH \n");
+        spin_lock_irq(&pDevice->lock);
+    	hostap_flush_sta(pDevice);
+        spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_ADD_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA \n");
+         spin_lock_irq(&pDevice->lock);
+		 ret = hostap_add_sta(pDevice, param);
+         spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_REMOVE_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA \n");
+         spin_lock_irq(&pDevice->lock);
+		 ret = hostap_remove_sta(pDevice, param);
+         spin_unlock_irq(&pDevice->lock);
+		break;
+	case VIAWGET_HOSTAPD_GET_INFO_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA \n");
+		 ret = hostap_get_info_sta(pDevice, param);
+		 ap_ioctl = 1;
+		break;
+/*
+	case VIAWGET_HOSTAPD_RESET_TXEXC_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_RESET_TXEXC_STA \n");
+		 ret = hostap_reset_txexc_sta(pDevice, param);
+		break;
+*/
+	case VIAWGET_HOSTAPD_SET_FLAGS_STA:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA \n");
+		 ret = hostap_set_flags_sta(pDevice, param);
+		break;
+
+	case VIAWGET_HOSTAPD_MLME:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME \n");
+	    return -EOPNOTSUPP;
+
+	case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT \n");
+		ret = hostap_set_generic_element(pDevice, param);
+		break;
+
+	case VIAWGET_HOSTAPD_SCAN_REQ:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ \n");
+	    return -EOPNOTSUPP;
+
+	case VIAWGET_HOSTAPD_STA_CLEAR_STATS:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS \n");
+	    return -EOPNOTSUPP;
+
+	default:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_ioctl: unknown cmd=%d\n",
+		       (int)param->cmd);
+		return -EOPNOTSUPP;
+		break;
+	}
+
+
+	if ((ret == 0) && ap_ioctl) {
+		if (copy_to_user(p->pointer, param, p->length)) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+
+ out:
+	if (param != NULL)
+		kfree(param);
+
+	return ret;
+}
+
diff --git a/drivers/staging/vt6656/hostap.h b/drivers/staging/vt6656/hostap.h
new file mode 100644
index 0000000..8fd667b
--- /dev/null
+++ b/drivers/staging/vt6656/hostap.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: hostap.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2003
+ *
+ */
+
+#ifndef __HOSTAP_H__
+#define __HOSTAP_H__
+
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define WLAN_RATE_1M    BIT0
+#define WLAN_RATE_2M    BIT1
+#define WLAN_RATE_5M5   BIT2
+#define WLAN_RATE_11M   BIT3
+#define WLAN_RATE_6M    BIT4
+#define WLAN_RATE_9M    BIT5
+#define WLAN_RATE_12M   BIT6
+#define WLAN_RATE_18M   BIT7
+#define WLAN_RATE_24M   BIT8
+#define WLAN_RATE_36M   BIT9
+#define WLAN_RATE_48M   BIT10
+#define WLAN_RATE_54M   BIT11
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
+#endif /* ETH_P_PAE */
+
+#ifndef ARPHRD_IEEE80211
+#define ARPHRD_IEEE80211 801
+#endif
+
+int hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked);
+int hostap_ioctl(PSDevice pDevice, struct iw_point *p);
+
+#endif // __HOSTAP_H__
+
+
+
diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c
new file mode 100644
index 0000000..35053be
--- /dev/null
+++ b/drivers/staging/vt6656/int.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: int.c
+ *
+ * Purpose: Handle USB interrupt endpoint
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 2, 2004
+ *
+ * Functions:
+ *
+ * Revision History:
+ *      04-02-2004 Jerry Chen:  Initial release
+ *
+ */
+
+#include "int.h"
+#include "mib.h"
+#include "tmacro.h"
+#include "mac.h"
+#include "power.h"
+#include "bssdb.h"
+#include "usbpipe.h"
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ *  Function:   InterruptPollingThread
+ *
+ *  Synopsis:   Thread running at IRQL PASSIVE_LEVEL.
+ *
+ *  Arguments: Device Extension
+ *
+ *  Returns:
+ *
+ *  Algorithm:  Call USBD for input data;
+ *
+ *  History:    dd-mm-yyyy   Author    Comment
+ *
+ *
+ *  Notes:
+ *
+ *  USB reads are by nature 'Blocking', and when in a read, the device looks like it's
+ *  in a 'stall' condition, so we deliberately time out every second if we've gotten no data
+ *
+-*/
+VOID
+INTvWorkItem(
+    PVOID Context
+    )
+{
+    PSDevice pDevice = (PSDevice) Context;
+    NTSTATUS ntStatus;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Interrupt Polling Thread\n");
+
+    spin_lock_irq(&pDevice->lock);
+    if (pDevice->fKillEventPollingThread != TRUE) {
+        ntStatus = PIPEnsInterruptRead(pDevice);
+    }
+    spin_unlock_irq(&pDevice->lock);
+
+ }
+
+
+NTSTATUS
+INTnsProcessData(
+    IN  PSDevice pDevice
+    )
+{
+    NTSTATUS        status = STATUS_SUCCESS;
+    PSINTData       pINTData;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    struct net_device_stats* pStats = &pDevice->stats;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptProcessData\n");
+
+    pINTData = (PSINTData) pDevice->intBuf.pDataBuf;
+    if (pINTData->byTSR0 & TSR_VALID) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt0 & 0x0F), (BYTE) (pINTData->byPkt0>>4), pINTData->byTSR0);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR0, pINTData->byPkt0);
+        //DBG_PRN_GRP01(("TSR0 %02x\n", pINTData->byTSR0));
+    }
+    if (pINTData->byTSR1 & TSR_VALID) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt1 & 0x0F), (BYTE) (pINTData->byPkt1>>4), pINTData->byTSR1);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR1, pINTData->byPkt1);
+        //DBG_PRN_GRP01(("TSR1 %02x\n", pINTData->byTSR1));
+    }
+    if (pINTData->byTSR2 & TSR_VALID) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt2 & 0x0F), (BYTE) (pINTData->byPkt2>>4), pINTData->byTSR2);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR2, pINTData->byPkt2);
+        //DBG_PRN_GRP01(("TSR2 %02x\n", pINTData->byTSR2));
+    }
+    if (pINTData->byTSR3 & TSR_VALID) {
+        STAvUpdateTDStatCounter (&(pDevice->scStatistic), (BYTE) (pINTData->byPkt3 & 0x0F), (BYTE) (pINTData->byPkt3>>4), pINTData->byTSR3);
+        BSSvUpdateNodeTxCounter (pDevice, &(pDevice->scStatistic),  pINTData->byTSR3, pINTData->byPkt3);
+        //DBG_PRN_GRP01(("TSR3 %02x\n", pINTData->byTSR3));
+    }
+    if ( pINTData->byISR0 != 0 ) {
+        if (pINTData->byISR0 & ISR_BNTX) {
+
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                if(pMgmt->byDTIMCount > 0) {
+                    pMgmt->byDTIMCount --;
+                    pMgmt->sNodeDBTable[0].bRxPSPoll = FALSE;
+                } else if(pMgmt->byDTIMCount == 0) {
+                    // check if mutltcast tx bufferring
+                    pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
+                    pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
+                    if (pMgmt->sNodeDBTable[0].bPSEnable) {
+                        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RX_PSPOLL, NULL);
+                    }
+                }
+                bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BECON_SEND, NULL);
+            } // if (pDevice->eOPMode == OP_MODE_AP)
+
+            pDevice->bBeaconSent = TRUE;
+        } else {
+            pDevice->bBeaconSent = FALSE;
+        }
+        if (pINTData->byISR0 & ISR_TBTT) {
+            if ( pDevice->bEnablePSMode ) {
+                bScheduleCommand((HANDLE) pDevice, WLAN_CMD_TBTT_WAKEUP, NULL);
+            }
+            if ( pDevice->bChannelSwitch ) {
+                pDevice->byChannelSwitchCount--;
+                if ( pDevice->byChannelSwitchCount == 0 ) {
+                    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_11H_CHSW, NULL);
+                }
+            }
+        }
+        LODWORD(pDevice->qwCurrTSF) = pINTData->dwLoTSF;
+        HIDWORD(pDevice->qwCurrTSF) = pINTData->dwHiTSF;
+        //DBG_PRN_GRP01(("ISR0 = %02x ,LoTsf =  %08x,HiTsf =  %08x\n", pINTData->byISR0, pINTData->dwLoTSF,pINTData->dwHiTSF));
+
+        STAvUpdate802_11Counter(&pDevice->s802_11Counter, &pDevice->scStatistic, pINTData->byRTSSuccess,
+                                pINTData->byRTSFail, pINTData->byACKFail, pINTData->byFCSErr );
+        STAvUpdateIsrStatCounter(&pDevice->scStatistic, pINTData->byISR0, pINTData->byISR1);
+
+    }
+
+    if ( pINTData->byISR1 != 0 ) {
+        if (pINTData->byISR1 & ISR_GPIO3) {
+            bScheduleCommand((HANDLE) pDevice, WLAN_CMD_RADIO, NULL);
+        }
+    }
+    pDevice->intBuf.uDataLen = 0;
+    pDevice->intBuf.bInUse = FALSE;
+
+    pStats->tx_packets = pDevice->scStatistic.ullTsrOK;
+    pStats->tx_bytes = pDevice->scStatistic.ullTxDirectedBytes +
+                       pDevice->scStatistic.ullTxMulticastBytes +
+                       pDevice->scStatistic.ullTxBroadcastBytes;
+    pStats->tx_errors = pDevice->scStatistic.dwTsrErr;
+    pStats->tx_dropped = pDevice->scStatistic.dwTsrErr;
+
+    return status;
+}
diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h
new file mode 100644
index 0000000..15e815a
--- /dev/null
+++ b/drivers/staging/vt6656/int.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: int.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Apr. 2, 2004
+ *
+ */
+
+#ifndef __INT_H__
+#define __INT_H__
+
+#include "ttype.h"
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+#pragma pack(1)
+typedef struct tagSINTData {
+    BYTE    byTSR0;
+    BYTE    byPkt0;
+    WORD    wTime0;
+    BYTE    byTSR1;
+    BYTE    byPkt1;
+    WORD    wTime1;
+    BYTE    byTSR2;
+    BYTE    byPkt2;
+    WORD    wTime2;
+    BYTE    byTSR3;
+    BYTE    byPkt3;
+    WORD    wTime3;
+    DWORD   dwLoTSF;
+    DWORD   dwHiTSF;
+    BYTE    byISR0;
+    BYTE    byISR1;
+    BYTE    byRTSSuccess;
+    BYTE    byRTSFail;
+    BYTE    byACKFail;
+    BYTE    byFCSErr;
+    BYTE    abySW[2];
+}__attribute__ ((__packed__))
+SINTData, *PSINTData;
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+VOID
+INTvWorkItem(
+    PVOID Context
+    );
+
+NTSTATUS
+INTnsProcessData(
+    IN  PSDevice pDevice
+    );
+
+#endif // __INT_H__
+
+
+
diff --git a/drivers/staging/vt6656/iocmd.h b/drivers/staging/vt6656/iocmd.h
new file mode 100644
index 0000000..49bfe15
--- /dev/null
+++ b/drivers/staging/vt6656/iocmd.h
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: iocmd.h
+ *
+ * Purpose: Handles the viawget ioctl private interface functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __IOCMD_H__
+#define __IOCMD_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#if !defined(DEF)
+#define DEF
+#endif
+
+//typedef int BOOL;
+//typedef uint32_t u32;
+//typedef uint16_t u16;
+//typedef uint8_t u8;
+
+
+// ioctl Command code
+#define MAGIC_CODE	                 0x3142
+#define IOCTL_CMD_TEST	            (SIOCDEVPRIVATE + 0)
+#define IOCTL_CMD_SET			    (SIOCDEVPRIVATE + 1)
+#define IOCTL_CMD_HOSTAPD           (SIOCDEVPRIVATE + 2)
+#define IOCTL_CMD_WPA               (SIOCDEVPRIVATE + 3)
+
+
+typedef enum tagWMAC_CMD {
+
+    WLAN_CMD_BSS_SCAN,
+    WLAN_CMD_BSS_JOIN,
+    WLAN_CMD_DISASSOC,
+    WLAN_CMD_SET_WEP,
+    WLAN_CMD_GET_LINK,
+    WLAN_CMD_GET_LISTLEN,
+    WLAN_CMD_GET_LIST,
+    WLAN_CMD_GET_MIB,
+    WLAN_CMD_GET_STAT,
+    WLAN_CMD_STOP_MAC,
+    WLAN_CMD_START_MAC,
+    WLAN_CMD_AP_START,
+    WLAN_CMD_SET_HOSTAPD,
+    WLAN_CMD_SET_HOSTAPD_STA,
+    WLAN_CMD_SET_802_1X,
+    WLAN_CMD_SET_HOST_WEP,
+    WLAN_CMD_SET_WPA,
+    WLAN_CMD_GET_NODE_CNT,
+    WLAN_CMD_ZONETYPE_SET,
+    WLAN_CMD_GET_NODE_LIST
+
+} WMAC_CMD, *PWMAC_CMD;
+
+typedef enum tagWZONETYPE {
+  ZoneType_USA=0,
+  ZoneType_Japan=1,
+  ZoneType_Europe=2
+}WZONETYPE;
+
+#define ADHOC	0
+#define INFRA	1
+#define BOTH	2
+#define AP	    3
+
+#define ADHOC_STARTED	   1
+#define ADHOC_JOINTED	   2
+
+
+#define PHY80211a 	    0
+#define PHY80211b       1
+#define PHY80211g       2
+
+#define SSID_ID                0
+#define SSID_MAXLEN            32
+#define BSSID_LEN              6
+#define WEP_NKEYS              4
+#define WEP_KEYMAXLEN          29
+#define WEP_40BIT_LEN          5
+#define WEP_104BIT_LEN         13
+#define WEP_232BIT_LEN         16
+
+// Ioctl interface structure
+// Command structure
+//
+#pragma pack(1)
+typedef struct tagSCmdRequest {
+	U8 	    name[16];
+	void	*data;
+	U16	    wResult;
+	U16     wCmdCode;
+} SCmdRequest, *PSCmdRequest;
+
+//
+// Scan
+//
+
+typedef struct tagSCmdScan {
+
+    U8	    ssid[SSID_MAXLEN + 2];
+
+} SCmdScan, *PSCmdScan;
+
+
+//
+// BSS Join
+//
+
+typedef struct tagSCmdBSSJoin {
+
+    U16	    wBSSType;
+    U16     wBBPType;
+    U8	    ssid[SSID_MAXLEN + 2];
+    U32	    uChannel;
+    BOOL    bPSEnable;
+    BOOL    bShareKeyAuth;
+
+} SCmdBSSJoin, *PSCmdBSSJoin;
+
+//
+// Zonetype Setting
+//
+
+typedef struct tagSCmdZoneTypeSet {
+
+ BOOL       bWrite;
+ WZONETYPE  ZoneType;
+
+} SCmdZoneTypeSet, *PSCmdZoneTypeSet;
+
+#ifdef WPA_SM_Transtatus
+typedef struct tagSWPAResult {
+         char	ifname[100];
+         U8		proto;
+         U8   key_mgmt;
+         U8   eap_type;
+         BOOL authenticated;
+} SWPAResult, *PSWPAResult;
+#endif
+
+typedef struct tagSCmdStartAP {
+
+    U16	    wBSSType;
+    U16     wBBPType;
+    U8	    ssid[SSID_MAXLEN + 2];
+    U32 	uChannel;
+    U32     uBeaconInt;
+    BOOL    bShareKeyAuth;
+    U8      byBasicRate;
+
+} SCmdStartAP, *PSCmdStartAP;
+
+
+typedef struct tagSCmdSetWEP {
+
+    BOOL    bEnableWep;
+    U8      byKeyIndex;
+    U8      abyWepKey[WEP_NKEYS][WEP_KEYMAXLEN];
+    BOOL    bWepKeyAvailable[WEP_NKEYS];
+    U32     auWepKeyLength[WEP_NKEYS];
+
+} SCmdSetWEP, *PSCmdSetWEP;
+
+
+
+typedef struct tagSBSSIDItem {
+
+	U32	    uChannel;
+    U8      abyBSSID[BSSID_LEN];
+    U8      abySSID[SSID_MAXLEN + 1];
+    U16	    wBeaconInterval;
+    U16	    wCapInfo;
+    U8      byNetType;
+    BOOL    bWEPOn;
+    U32     uRSSI;
+
+} SBSSIDItem;
+
+
+typedef struct tagSBSSIDList {
+
+	U32		    uItem;
+	SBSSIDItem	sBSSIDList[0];
+} SBSSIDList, *PSBSSIDList;
+
+
+typedef struct tagSNodeItem {
+    // STA info
+    U16            wAID;
+    U8             abyMACAddr[6];
+    U16            wTxDataRate;
+    U16            wInActiveCount;
+    U16            wEnQueueCnt;
+    U16            wFlags;
+    BOOL           bPWBitOn;
+    U8             byKeyIndex;
+    U16            wWepKeyLength;
+    U8            abyWepKey[WEP_KEYMAXLEN];
+    // Auto rate fallback vars
+    BOOL           bIsInFallback;
+    U32            uTxFailures;
+    U32            uTxAttempts;
+    U16            wFailureRatio;
+
+} SNodeItem;
+
+
+typedef struct tagSNodeList {
+
+	U32		    uItem;
+	SNodeItem	sNodeList[0];
+
+} SNodeList, *PSNodeList;
+
+
+typedef struct tagSCmdLinkStatus {
+
+    BOOL    bLink;
+	U16	    wBSSType;
+	U8      byState;
+    U8      abyBSSID[BSSID_LEN];
+    U8      abySSID[SSID_MAXLEN + 2];
+    U32     uChannel;
+    U32     uLinkRate;
+
+} SCmdLinkStatus, *PSCmdLinkStatus;
+
+//
+// 802.11 counter
+//
+typedef struct tagSDot11MIBCount {
+    U32 TransmittedFragmentCount;
+    U32 MulticastTransmittedFrameCount;
+    U32 FailedCount;
+    U32 RetryCount;
+    U32 MultipleRetryCount;
+    U32 RTSSuccessCount;
+    U32 RTSFailureCount;
+    U32 ACKFailureCount;
+    U32 FrameDuplicateCount;
+    U32 ReceivedFragmentCount;
+    U32 MulticastReceivedFrameCount;
+    U32 FCSErrorCount;
+} SDot11MIBCount, *PSDot11MIBCount;
+
+
+
+//
+// statistic counter
+//
+typedef struct tagSStatMIBCount {
+    //
+    // ISR status count
+    //
+    U32   dwIsrTx0OK;
+    U32   dwIsrTx1OK;
+    U32   dwIsrBeaconTxOK;
+    U32   dwIsrRxOK;
+    U32   dwIsrTBTTInt;
+    U32   dwIsrSTIMERInt;
+    U32   dwIsrUnrecoverableError;
+    U32   dwIsrSoftInterrupt;
+    U32   dwIsrRxNoBuf;
+    /////////////////////////////////////
+
+    U32   dwIsrUnknown;               // unknown interrupt count
+
+    // RSR status count
+    //
+    U32   dwRsrFrmAlgnErr;
+    U32   dwRsrErr;
+    U32   dwRsrCRCErr;
+    U32   dwRsrCRCOk;
+    U32   dwRsrBSSIDOk;
+    U32   dwRsrADDROk;
+    U32   dwRsrICVOk;
+    U32   dwNewRsrShortPreamble;
+    U32   dwRsrLong;
+    U32   dwRsrRunt;
+
+    U32   dwRsrRxControl;
+    U32   dwRsrRxData;
+    U32   dwRsrRxManage;
+
+    U32   dwRsrRxPacket;
+    U32   dwRsrRxOctet;
+    U32   dwRsrBroadcast;
+    U32   dwRsrMulticast;
+    U32   dwRsrDirected;
+    // 64-bit OID
+    U32   ullRsrOK;
+
+    // for some optional OIDs (64 bits) and DMI support
+    U32   ullRxBroadcastBytes;
+    U32   ullRxMulticastBytes;
+    U32   ullRxDirectedBytes;
+    U32   ullRxBroadcastFrames;
+    U32   ullRxMulticastFrames;
+    U32   ullRxDirectedFrames;
+
+    U32   dwRsrRxFragment;
+    U32   dwRsrRxFrmLen64;
+    U32   dwRsrRxFrmLen65_127;
+    U32   dwRsrRxFrmLen128_255;
+    U32   dwRsrRxFrmLen256_511;
+    U32   dwRsrRxFrmLen512_1023;
+    U32   dwRsrRxFrmLen1024_1518;
+
+    // TSR0,1 status count
+    //
+    U32   dwTsrTotalRetry[2];        // total collision retry count
+    U32   dwTsrOnceRetry[2];         // this packet only occur one collision
+    U32   dwTsrMoreThanOnceRetry[2]; // this packet occur more than one collision
+    U32   dwTsrRetry[2];             // this packet has ever occur collision,
+                                       // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0)
+    U32   dwTsrACKData[2];
+    U32   dwTsrErr[2];
+    U32   dwAllTsrOK[2];
+    U32   dwTsrRetryTimeout[2];
+    U32   dwTsrTransmitTimeout[2];
+
+    U32   dwTsrTxPacket[2];
+    U32   dwTsrTxOctet[2];
+    U32   dwTsrBroadcast[2];
+    U32   dwTsrMulticast[2];
+    U32   dwTsrDirected[2];
+
+    // RD/TD count
+    U32   dwCntRxFrmLength;
+    U32   dwCntTxBufLength;
+
+    U8    abyCntRxPattern[16];
+    U8    abyCntTxPattern[16];
+
+    // Software check....
+    U32   dwCntRxDataErr;             // rx buffer data software compare CRC err count
+    U32   dwCntDecryptErr;            // rx buffer data software compare CRC err count
+    U32   dwCntRxICVErr;              // rx buffer data software compare CRC err count
+    U32    idxRxErrorDesc;             // index for rx data error RD
+
+    // 64-bit OID
+    U32   ullTsrOK[2];
+
+    // for some optional OIDs (64 bits) and DMI support
+    U32   ullTxBroadcastFrames[2];
+    U32   ullTxMulticastFrames[2];
+    U32   ullTxDirectedFrames[2];
+    U32   ullTxBroadcastBytes[2];
+    U32   ullTxMulticastBytes[2];
+    U32   ullTxDirectedBytes[2];
+} SStatMIBCount, *PSStatMIBCount;
+
+
+
+
+typedef struct tagSCmdValue {
+
+    U32     dwValue;
+
+} SCmdValue,  *PSCmdValue;
+
+
+//
+// hostapd & viawget ioctl related
+//
+
+
+// VIAGWET_IOCTL_HOSTAPD ioctl() cmd:
+enum {
+	VIAWGET_HOSTAPD_FLUSH = 1,
+	VIAWGET_HOSTAPD_ADD_STA = 2,
+	VIAWGET_HOSTAPD_REMOVE_STA = 3,
+	VIAWGET_HOSTAPD_GET_INFO_STA = 4,
+	VIAWGET_HOSTAPD_SET_ENCRYPTION = 5,
+	VIAWGET_HOSTAPD_GET_ENCRYPTION = 6,
+	VIAWGET_HOSTAPD_SET_FLAGS_STA = 7,
+	VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR = 8,
+	VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT = 9,
+	VIAWGET_HOSTAPD_MLME = 10,
+	VIAWGET_HOSTAPD_SCAN_REQ = 11,
+	VIAWGET_HOSTAPD_STA_CLEAR_STATS = 12,
+};
+
+
+#define VIAWGET_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
+((int) (&((struct viawget_hostapd_param *) 0)->u.generic_elem.data))
+
+// Maximum length for algorithm names (-1 for nul termination) used in ioctl()
+
+
+
+struct viawget_hostapd_param {
+	U32 cmd;
+	U8 sta_addr[6];
+	union {
+		struct {
+			U16 aid;
+			U16 capability;
+			U8 tx_supp_rates;
+		} add_sta;
+		struct {
+			U32 inactive_sec;
+		} get_info_sta;
+		struct {
+			U8 alg;
+			U32 flags;
+			U32 err;
+			U8 idx;
+			U8 seq[8];
+			U16 key_len;
+			U8 key[0];
+		} crypt;
+		struct {
+			U32 flags_and;
+			U32 flags_or;
+		} set_flags_sta;
+		struct {
+			U16 rid;
+			U16 len;
+			U8 data[0];
+		} rid;
+		struct {
+			U8 len;
+			U8 data[0];
+		} generic_elem;
+		struct {
+			U16 cmd;
+			U16 reason_code;
+		} mlme;
+		struct {
+			U8 ssid_len;
+			U8 ssid[32];
+		} scan_req;
+	} u;
+};
+
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+#endif //__IOCMD_H__
diff --git a/drivers/staging/vt6656/ioctl.c b/drivers/staging/vt6656/ioctl.c
new file mode 100644
index 0000000..d94131f
--- /dev/null
+++ b/drivers/staging/vt6656/ioctl.c
@@ -0,0 +1,701 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: ioctl.c
+ *
+ * Purpose:  private ioctl functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Auguest 20, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "ioctl.h"
+#include "iocmd.h"
+#include "mac.h"
+#include "card.h"
+#include "hostap.h"
+#include "wpactl.h"
+#include "control.h"
+#include "rndis.h"
+#include "rf.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+#ifdef WPA_SM_Transtatus
+    SWPAResult wpa_Result;
+#endif
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+int private_ioctl(PSDevice pDevice, struct ifreq *rq) {
+
+	PSCmdRequest        pReq = (PSCmdRequest)rq;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	int 		        result = 0;
+    PWLAN_IE_SSID       pItemSSID;
+    SCmdBSSJoin         sJoinCmd;
+    SCmdZoneTypeSet sZoneTypeCmd;
+    SCmdScan            sScanCmd;
+    SCmdStartAP         sStartAPCmd;
+    SCmdSetWEP          sWEPCmd;
+    SCmdValue           sValue;
+    SBSSIDList          sList;
+    SNodeList           sNodeList;
+    PSBSSIDList         pList;
+    PSNodeList          pNodeList;
+    UINT                cbListCount;
+    PKnownBSS           pBSS;
+    PKnownNodeDB        pNode;
+    UINT                ii, jj;
+    SCmdLinkStatus      sLinkStatus;
+    BYTE                abySuppRates[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+    BYTE                abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    DWORD               dwKeyIndex= 0;
+    BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    LONG                ldBm;
+
+    pReq->wResult = 0;
+
+    switch(pReq->wCmdCode) {
+
+    case WLAN_CMD_BSS_SCAN:
+
+        if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) {
+			result = -EFAULT;
+			break;
+		};
+
+        pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid;
+        if (pItemSSID->len != 0) {
+            memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+            memcpy(abyScanSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
+        }
+        spin_lock_irq(&pDevice->lock);
+        if (memcmp(pMgmt->abyCurrBSSID, &abyNullAddr[0], 6) == 0)
+            BSSvClearBSSList((HANDLE)pDevice, FALSE);
+        else
+            BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin \n");
+
+        if (pItemSSID->len != 0)
+            bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
+        else
+            bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+        spin_unlock_irq(&pDevice->lock);
+        break;
+
+    case WLAN_CMD_ZONETYPE_SET:
+	//mike add :cann't support.
+           result=-EOPNOTSUPP;
+	  break;
+
+        if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) {
+			result = -EFAULT;
+			break;
+		};
+
+          if(sZoneTypeCmd.bWrite==TRUE) {
+	  //////write zonetype
+                if(sZoneTypeCmd.ZoneType == ZoneType_USA) {
+                  //set to USA
+                   printk("set_ZoneType:USA\n");
+		}
+                else if(sZoneTypeCmd.ZoneType == ZoneType_Japan) {
+                  //set to Japan
+                  printk("set_ZoneType:Japan\n");
+		}
+	       else if(sZoneTypeCmd.ZoneType == ZoneType_Europe) {
+                  //set to Europe
+                  printk("set_ZoneType:Europe\n");
+		}
+            }
+	else {
+          ///////read zonetype
+	  BYTE                       zonetype=0;
+
+
+           if(zonetype == 0x00)  { //USA
+             sZoneTypeCmd.ZoneType = ZoneType_USA;
+           }
+	 else if(zonetype == 0x01) { //Japan
+             sZoneTypeCmd.ZoneType = ZoneType_Japan;
+	  }
+	 else if(zonetype == 0x02) { //Europe
+             sZoneTypeCmd.ZoneType = ZoneType_Europe;
+	 }
+	 else { //Unknow ZoneType
+	        printk("Error:ZoneType[%x] Unknown ???\n",zonetype);
+	         result = -EFAULT;
+		break;
+	 }
+	   if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) {
+			result = -EFAULT;
+			break;
+		};
+	}
+
+	     break;
+
+    case WLAN_CMD_BSS_JOIN:
+
+        if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) {
+			result = -EFAULT;
+			break;
+		};
+
+        pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid;
+        memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+		memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
+	    if (sJoinCmd.wBSSType == ADHOC) {
+	        pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n");
+	    }
+	    else {
+	        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n");
+	    }
+	    if (sJoinCmd.bPSEnable == TRUE) {
+            pDevice->ePSMode = WMAC_POWER_FAST;
+//            pDevice->ePSMode = WMAC_POWER_MAX;
+            pMgmt->wListenInterval = 2;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n");
+        }
+        else {
+            pDevice->ePSMode = WMAC_POWER_CAM;
+            pMgmt->wListenInterval = 1;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off \n");
+        }
+
+        if (sJoinCmd.bShareKeyAuth == TRUE){
+            pMgmt->bShareKeyAlgorithm = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+        }
+        else {
+            pMgmt->bShareKeyAlgorithm = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
+        }
+	    pDevice->uChannel = sJoinCmd.uChannel;
+        netif_stop_queue(pDevice->dev);
+        spin_lock_irq(&pDevice->lock);
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+        spin_unlock_irq(&pDevice->lock);
+        break;
+
+    case WLAN_CMD_SET_WEP:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key. \n");
+        memset(&sWEPCmd, 0 ,sizeof(SCmdSetWEP));
+        if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) {
+			result = -EFAULT;
+			break;
+		};
+	    if (sWEPCmd.bEnableWep != TRUE) {
+	        int uu;
+
+            pDevice->bEncryptionEnable = FALSE;
+            pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+            spin_lock_irq(&pDevice->lock);
+            for(uu=0;uu<MAX_KEY_TABLE;uu++)
+                MACvDisableKeyEntry(pDevice,uu);
+            spin_unlock_irq(&pDevice->lock);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable. \n");
+            break;
+        }
+
+        for (ii = 0; ii < WLAN_WEP_NKEYS; ii ++) {
+            if (sWEPCmd.bWepKeyAvailable[ii]) {
+                if (ii == sWEPCmd.byKeyIndex)
+//2006-1207-01<Modify>by Einsn Liu
+//		    dwKeyIndex|= (1 << 31);
+                    dwKeyIndex=ii|(1 << 31);
+                else
+                    dwKeyIndex = ii;
+                spin_lock_irq(&pDevice->lock);
+                KeybSetDefaultKey(  pDevice,
+                                    &(pDevice->sKey),
+                                    dwKeyIndex,
+                                    sWEPCmd.auWepKeyLength[ii],
+                                    NULL,
+                                    (PBYTE)&sWEPCmd.abyWepKey[ii][0],
+                                    KEY_CTL_WEP
+                                  );
+               spin_unlock_irq(&pDevice->lock);
+
+            }
+        }
+        pDevice->byKeyIndex = sWEPCmd.byKeyIndex;
+        pDevice->bTransmitKey = TRUE;
+        pDevice->bEncryptionEnable = TRUE;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+
+        break;
+
+    case WLAN_CMD_GET_LINK:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status. \n");
+
+        memset(sLinkStatus.abySSID, 0 , WLAN_SSID_MAXLEN + 1);
+
+        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
+            sLinkStatus.wBSSType = ADHOC;
+        else
+            sLinkStatus.wBSSType = INFRA;
+
+        if (pMgmt->eCurrState == WMAC_STATE_JOINTED)
+            sLinkStatus.byState = ADHOC_JOINTED;
+        else
+            sLinkStatus.byState = ADHOC_STARTED;
+
+        sLinkStatus.uChannel = pMgmt->uCurrChannel;
+        if (pDevice->bLinkPass == TRUE) {
+            sLinkStatus.bLink = TRUE;
+ 		    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+		    memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len);
+		    memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+		    sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Link Success ! \n");
+        }
+        else {
+            sLinkStatus.bLink = FALSE;
+        }
+        if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) {
+			result = -EFAULT;
+			break;
+		};
+
+        break;
+
+    case WLAN_CMD_GET_LISTLEN:
+		cbListCount = 0;
+		pBSS = &(pMgmt->sBSSList[0]);
+        for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+            pBSS = &(pMgmt->sBSSList[ii]);
+            if (!pBSS->bActive)
+                continue;
+            cbListCount++;
+        };
+        sList.uItem = cbListCount;
+        if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) {
+			result = -EFAULT;
+			break;
+		};
+        pReq->wResult = 0;
+        break;
+
+    case WLAN_CMD_GET_LIST:
+        if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) {
+			result = -EFAULT;
+			break;
+		};
+        pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC);
+        if (pList == NULL) {
+            result = -ENOMEM;
+            break;
+        }
+		pList->uItem = sList.uItem;
+		pBSS = &(pMgmt->sBSSList[0]);
+        for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
+            pBSS = &(pMgmt->sBSSList[jj]);
+            if (pBSS->bActive) {
+    		    pList->sBSSIDList[ii].uChannel = pBSS->uChannel;
+    		    pList->sBSSIDList[ii].wBeaconInterval = pBSS->wBeaconInterval;
+    		    pList->sBSSIDList[ii].wCapInfo = pBSS->wCapInfo;
+    		    RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+    		    pList->sBSSIDList[ii].uRSSI = (UINT)ldBm;
+//    		    pList->sBSSIDList[ii].uRSSI = pBSS->uRSSI;
+    		    memcpy(pList->sBSSIDList[ii].abyBSSID, pBSS->abyBSSID, WLAN_BSSID_LEN);
+    		    pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
+    		    memset(pList->sBSSIDList[ii].abySSID, 0, WLAN_SSID_MAXLEN + 1);
+    		    memcpy(pList->sBSSIDList[ii].abySSID, pItemSSID->abySSID, pItemSSID->len);
+                if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
+    		        pList->sBSSIDList[ii].byNetType = INFRA;
+                }
+                else {
+    		        pList->sBSSIDList[ii].byNetType = ADHOC;
+    		    }
+    		    if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
+    		        pList->sBSSIDList[ii].bWEPOn = TRUE;
+                }
+                else {
+    		        pList->sBSSIDList[ii].bWEPOn = FALSE;
+    		    }
+    		    ii ++;
+    		    if (ii >= pList->uItem)
+    		        break;
+            }
+        }
+
+        if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) {
+			result = -EFAULT;
+			break;
+		};
+        kfree(pList);
+        pReq->wResult = 0;
+        break;
+
+    case WLAN_CMD_GET_MIB:
+        if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) {
+			result = -EFAULT;
+			break;
+		};
+        break;
+
+    case WLAN_CMD_GET_STAT:
+        if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) {
+			result = -EFAULT;
+			break;
+		};
+        break;
+    case WLAN_CMD_STOP_MAC:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n");
+        // Todo xxxxxx
+        netif_stop_queue(pDevice->dev);
+        spin_lock_irq(&pDevice->lock);
+        if (pDevice->bRadioOff == FALSE) {
+            CARDbRadioPowerOff(pDevice);
+        }
+        pDevice->bLinkPass = FALSE;
+        ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+        memset(pMgmt->abyCurrBSSID, 0, 6);
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+//        del_timer(&pDevice->sTimerCommand);
+//        del_timer(&pMgmt->sTimerSecondCallback);
+        pDevice->bCmdRunning = FALSE;
+        spin_unlock_irq(&pDevice->lock);
+
+        break;
+
+    case WLAN_CMD_START_MAC:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n");
+        // Todo xxxxxxx
+        if (pDevice->bRadioOff == TRUE)
+            CARDbRadioPowerOn(pDevice);
+        break;
+
+    case WLAN_CMD_SET_HOSTAPD:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n");
+
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+		if (sValue.dwValue == 1) {
+            if (hostap_set_hostapd(pDevice, 1, 1) == 0){
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
+            }
+            else {
+			    result = -EFAULT;
+			    break;
+			}
+        }
+        else {
+            hostap_set_hostapd(pDevice, 0, 1);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n");
+        }
+
+        break;
+
+    case WLAN_CMD_SET_HOSTAPD_STA:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n");
+
+        break;
+    case WLAN_CMD_SET_802_1X:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n");
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+
+		if (sValue.dwValue == 1) {
+            pDevice->bEnable8021x = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n");
+        }
+        else {
+            pDevice->bEnable8021x = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n");
+        }
+
+        break;
+
+
+    case WLAN_CMD_SET_HOST_WEP:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n");
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+
+		if (sValue.dwValue == 1) {
+            pDevice->bEnableHostWEP = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n");
+        }
+        else {
+            pDevice->bEnableHostWEP = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n");
+        }
+
+        break;
+
+    case WLAN_CMD_SET_WPA:
+         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n");
+
+        if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
+			result = -EFAULT;
+			break;
+		};
+		if (sValue.dwValue == 1) {
+                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
+		   memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, U_ETHER_ADDR_LEN);
+		   pDevice->bWPADEVUp = TRUE;
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n");
+	   pDevice->bWPADEVUp = FALSE;
+        }
+
+        break;
+
+    case WLAN_CMD_AP_START:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n");
+        if (pDevice->bRadioOff == TRUE) {
+            CARDbRadioPowerOn(pDevice);
+            add_timer(&pMgmt->sTimerSecondCallback);
+        }
+        if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) {
+			result = -EFAULT;
+			break;
+		};
+
+	    if (sStartAPCmd.wBSSType == AP) {
+	        pMgmt->eConfigMode = WMAC_CONFIG_AP;
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n");
+	    }
+	    else {
+	        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n");
+			result = -EFAULT;
+			break;
+	    }
+
+
+	    if (sStartAPCmd.wBBPType == PHY80211g) {
+            pMgmt->byAPBBType = PHY_TYPE_11G;
+        }
+        else if (sStartAPCmd.wBBPType == PHY80211a) {
+                 pMgmt->byAPBBType = PHY_TYPE_11A;
+        }
+        else {
+            pMgmt->byAPBBType = PHY_TYPE_11B;
+        }
+
+        pItemSSID = (PWLAN_IE_SSID)sStartAPCmd.ssid;
+        memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+		memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN);
+
+	    if ((sStartAPCmd.uChannel > 0)&&(sStartAPCmd.uChannel <= 14))
+	        pDevice->uChannel = sStartAPCmd.uChannel;
+
+	    if ((sStartAPCmd.uBeaconInt >= 20) && (sStartAPCmd.uBeaconInt <= 1000))
+            pMgmt->wIBSSBeaconPeriod = sStartAPCmd.uBeaconInt;
+        else
+            pMgmt->wIBSSBeaconPeriod = 100;
+
+        if (sStartAPCmd.bShareKeyAuth == TRUE){
+            pMgmt->bShareKeyAlgorithm = TRUE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key \n");
+        }
+        else {
+            pMgmt->bShareKeyAlgorithm = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System \n");
+        }
+        memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6);
+
+        if (sStartAPCmd.byBasicRate & BIT3) {
+            pMgmt->abyIBSSSuppRates[2] |= BIT7;
+            pMgmt->abyIBSSSuppRates[3] |= BIT7;
+            pMgmt->abyIBSSSuppRates[4] |= BIT7;
+            pMgmt->abyIBSSSuppRates[5] |= BIT7;
+        }else if (sStartAPCmd.byBasicRate & BIT2) {
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+             pMgmt->abyIBSSSuppRates[3] |= BIT7;
+             pMgmt->abyIBSSSuppRates[4] |= BIT7;
+        }else if (sStartAPCmd.byBasicRate & BIT1) {
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+             pMgmt->abyIBSSSuppRates[3] |= BIT7;
+        }else if (sStartAPCmd.byBasicRate & BIT1) {
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+        }else {
+            //default 1,2M
+             pMgmt->abyIBSSSuppRates[2] |= BIT7;
+             pMgmt->abyIBSSSuppRates[3] |= BIT7;
+        }
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %x %x %x %x\n",
+                pMgmt->abyIBSSSuppRates[2],
+                pMgmt->abyIBSSSuppRates[3],
+                pMgmt->abyIBSSSuppRates[4],
+                pMgmt->abyIBSSSuppRates[5]
+                );
+
+        netif_stop_queue(pDevice->dev);
+        spin_lock_irq(&pDevice->lock);
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL);
+        spin_unlock_irq(&pDevice->lock);
+        break;
+
+    case WLAN_CMD_GET_NODE_CNT:
+
+		cbListCount = 0;
+		pNode = &(pMgmt->sNodeDBTable[0]);
+        for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+            pNode = &(pMgmt->sNodeDBTable[ii]);
+            if (!pNode->bActive)
+                continue;
+            cbListCount++;
+        };
+
+        sNodeList.uItem = cbListCount;
+        if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) {
+			result = -EFAULT;
+			break;
+		};
+        pReq->wResult = 0;
+        break;
+
+    case WLAN_CMD_GET_NODE_LIST:
+
+        if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) {
+			result = -EFAULT;
+			break;
+		};
+        pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
+        if (pNodeList == NULL) {
+            result = -ENOMEM;
+            break;
+        }
+		pNodeList->uItem = sNodeList.uItem;
+		pNode = &(pMgmt->sNodeDBTable[0]);
+        for (ii = 0, jj = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+            pNode = &(pMgmt->sNodeDBTable[ii]);
+            if (pNode->bActive) {
+    		    pNodeList->sNodeList[jj].wAID = pNode->wAID;
+    		    memcpy(pNodeList->sNodeList[jj].abyMACAddr, pNode->abyMACAddr, WLAN_ADDR_LEN);
+    		    pNodeList->sNodeList[jj].wTxDataRate = pNode->wTxDataRate;
+    		    pNodeList->sNodeList[jj].wInActiveCount = (WORD)pNode->uInActiveCount;
+    		    pNodeList->sNodeList[jj].wEnQueueCnt = (WORD)pNode->wEnQueueCnt;
+    		    pNodeList->sNodeList[jj].wFlags = (WORD)pNode->dwFlags;
+    		    pNodeList->sNodeList[jj].bPWBitOn = pNode->bPSEnable;
+    		    pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex;
+    		    pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength;
+    		    memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key= %2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+                            pNodeList->sNodeList[jj].abyWepKey[0],
+                            pNodeList->sNodeList[jj].abyWepKey[1],
+                            pNodeList->sNodeList[jj].abyWepKey[2],
+                            pNodeList->sNodeList[jj].abyWepKey[3],
+                            pNodeList->sNodeList[jj].abyWepKey[4]
+                           );
+    		    pNodeList->sNodeList[jj].bIsInFallback = pNode->bIsInFallback;
+    		    pNodeList->sNodeList[jj].uTxFailures = pNode->uTxFailures;
+    		    pNodeList->sNodeList[jj].uTxAttempts = pNode->uTxAttempts;
+    		    pNodeList->sNodeList[jj].wFailureRatio = (WORD)pNode->uFailureRatio;
+    		    jj ++;
+    		    if (jj >= pNodeList->uItem)
+    		        break;
+    		}
+		};
+        if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
+			result = -EFAULT;
+			break;
+		};
+        kfree(pNodeList);
+        pReq->wResult = 0;
+        break;
+
+#ifdef WPA_SM_Transtatus
+    case 0xFF:
+        memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
+	    wpa_Result.proto = 0;
+	    wpa_Result.key_mgmt = 0;
+	    wpa_Result.eap_type = 0;
+	    wpa_Result.authenticated = FALSE;
+	      pDevice->fWPA_Authened = FALSE;
+        if (copy_from_user(&wpa_Result, pReq->data, sizeof(wpa_Result))) {
+            result = -EFAULT;
+			break;
+		}
+//DavidWang  for some AP maybe good authenticate
+   if(wpa_Result.key_mgmt==0x20)
+      pMgmt->Cisco_cckm =1;
+    else
+    pMgmt->Cisco_cckm =0;
+//DavidWang
+
+if(wpa_Result.authenticated==TRUE) {
+   #ifdef SndEvt_ToAPI
+   {
+     union iwreq_data      wrqu;
+
+     pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+
+     memset(&wrqu, 0, sizeof(wrqu));
+     wrqu.data.flags = RT_WPACONNECTED_EVENT_FLAG;
+     wrqu.data.length =pItemSSID->len;
+     wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pItemSSID->abySSID);
+   }
+   #endif
+         pDevice->fWPA_Authened = TRUE;           //is sucessful peer to wpa_Result.authenticated?
+}
+
+        //printk("get private wpa_supplicant announce WPA SM\n");
+	//printk("wpa-->ifname=%s\n",wpa_Result.ifname);
+	//printk("wpa-->proto=%d\n",wpa_Result.proto);
+	//printk("wpa-->key-mgmt=%d\n",wpa_Result.key_mgmt);
+	//printk("wpa-->eap_type=%d\n",wpa_Result.eap_type);
+	//printk("wpa-->authenticated is %s\n",(wpa_Result.authenticated==TRUE)?"TRUE":"FALSE");
+
+	pReq->wResult = 0;
+        break;
+#endif
+
+    default:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n");
+    }
+
+    return result;
+}
diff --git a/drivers/staging/vt6656/ioctl.h b/drivers/staging/vt6656/ioctl.h
new file mode 100644
index 0000000..07d2283
--- /dev/null
+++ b/drivers/staging/vt6656/ioctl.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: hostap.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2003
+ *
+ */
+
+#ifndef __IOCTL_H__
+#define __IOCTL_H__
+
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+int private_ioctl(PSDevice pDevice, struct ifreq *rq);
+
+/*
+VOID vConfigWEPKey (
+    IN PSDevice pDevice,
+    IN DWORD    dwKeyIndex,
+    IN PBYTE    pbyKey,
+    IN ULONG    uKeyLength
+    );
+*/
+
+#endif // __IOCTL_H__
+
+
+
diff --git a/drivers/staging/vt6656/iowpa.h b/drivers/staging/vt6656/iowpa.h
new file mode 100644
index 0000000..5750b5b
--- /dev/null
+++ b/drivers/staging/vt6656/iowpa.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: iowpa.h
+ *
+ * Purpose: Handles wpa supplicant ioctl interface
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __IOWPA_H__
+#define __IOWPA_H__
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+#define WPA_IE_LEN 64
+
+
+//WPA related
+/*
+typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
+typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
+	       CIPHER_WEP104 } wpa_cipher;
+typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
+	       KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt;
+*/
+
+enum {
+	VIAWGET_SET_WPA = 1,
+	VIAWGET_SET_KEY = 2,
+	VIAWGET_SET_SCAN = 3,
+	VIAWGET_GET_SCAN = 4,
+	VIAWGET_GET_SSID = 5,
+	VIAWGET_GET_BSSID = 6,
+	VIAWGET_SET_DROP_UNENCRYPT = 7,
+	VIAWGET_SET_DEAUTHENTICATE = 8,
+	VIAWGET_SET_ASSOCIATE = 9,
+	VIAWGET_SET_DISASSOCIATE= 10
+};
+
+
+enum {
+	VIAWGET_ASSOC_MSG = 1,
+	VIAWGET_DISASSOC_MSG = 2,
+	VIAWGET_PTK_MIC_MSG = 3,
+	VIAWGET_GTK_MIC_MSG = 4,
+	VIAWGET_CCKM_ROAM_MSG = 5,
+	VIAWGET_DEVICECLOSE_MSG = 6
+};
+
+
+
+#pragma pack(1)
+typedef struct viawget_wpa_header {
+	u8 type;
+	u16 req_ie_len;
+	u16 resp_ie_len;
+} viawget_wpa_header;
+
+
+
+struct viawget_wpa_param {
+	u32 cmd;
+	u8 addr[6];
+	union {
+		struct {
+			u8 len;
+			u8 data[0];
+		} generic_elem;
+
+		struct {
+        	u8 bssid[6];
+			u8 ssid[32];
+			u8 ssid_len;
+        	u8 *wpa_ie;
+        	u16 wpa_ie_len;
+        	int pairwise_suite;
+        	int group_suite;
+        	int key_mgmt_suite;
+        	int auth_alg;
+        	int mode;
+                u8 roam_dbm;  //DavidWang
+		} wpa_associate;
+
+		struct {
+	        int alg_name;
+	        u16 key_index;
+	        u16 set_tx;
+	        u8 *seq;
+	        u16 seq_len;
+	        u8 *key;
+	        u16 key_len;
+		} wpa_key;
+
+		struct {
+			u8 ssid_len;
+			u8 ssid[32];
+		} scan_req;
+
+		struct {
+			u16 scan_count;
+			u8 *buf;
+		} scan_results;
+
+	} u;
+
+};
+
+#pragma pack(1)
+struct viawget_scan_result {
+	u8 bssid[6];
+	u8 ssid[32];
+	u16 ssid_len;
+	u8 wpa_ie[WPA_IE_LEN];
+	u16 wpa_ie_len;
+	u8 rsn_ie[WPA_IE_LEN];
+	u16 rsn_ie_len;
+	int freq; // MHz
+	int caps; // e.g. privacy
+	int qual; // signal quality
+	int noise;
+	int level;
+	int maxrate;
+};
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+#endif //__IOWPA_H__
diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c
new file mode 100644
index 0000000..aa8d1a2
--- /dev/null
+++ b/drivers/staging/vt6656/iwctl.c
@@ -0,0 +1,2190 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: iwctl.c
+ *
+ * Purpose:  wireless ext & ioctl functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 5, 2006
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "ioctl.h"
+#include "iocmd.h"
+#include "mac.h"
+#include "card.h"
+#include "hostap.h"
+#include "power.h"
+#include "rf.h"
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#include "iowpa.h"
+#include "wpactl.h"
+#endif
+
+#include <net/iw_handler.h>
+
+
+/*---------------------  Static Definitions -------------------------*/
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#define SUPPORTED_WIRELESS_EXT                  18
+#else
+#define SUPPORTED_WIRELESS_EXT                  17
+#endif
+
+static const long frequency_list[] = {
+    2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
+    4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
+    5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
+    5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
+    5700, 5745, 5765, 5785, 5805, 5825
+	};
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+/*---------------------  Static Variables  --------------------------*/
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev)
+{
+	PSDevice pDevice = netdev_priv(dev);
+	long ldBm;
+
+	pDevice->wstats.status = pDevice->eOPMode;
+	#ifdef Calcu_LinkQual
+	 #if 0
+	  if(pDevice->byBBType == BB_TYPE_11B) {
+	     if(pDevice->byCurrSQ > 120)
+                  pDevice->scStatistic.LinkQuality = 100;
+	     else
+		 pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
+	    }
+	  else if(pDevice->byBBType == BB_TYPE_11G) {
+                if(pDevice->byCurrSQ < 20)
+		   pDevice->scStatistic.LinkQuality = 100;
+	       else if(pDevice->byCurrSQ >96)
+		   pDevice->scStatistic.LinkQuality  = 0;
+	       else
+		   pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
+	   }
+	   if(pDevice->bLinkPass !=TRUE)
+	       pDevice->scStatistic.LinkQuality = 0;
+	  #endif
+	   if(pDevice->scStatistic.LinkQuality > 100)
+   	       pDevice->scStatistic.LinkQuality = 100;
+               pDevice->wstats.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
+	#else
+	pDevice->wstats.qual.qual = pDevice->byCurrSQ;
+	#endif
+	RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+	pDevice->wstats.qual.level = ldBm;
+	//pDevice->wstats.qual.level = 0x100 - pDevice->uCurrRSSI;
+	pDevice->wstats.qual.noise = 0;
+	pDevice->wstats.qual.updated = 1;
+	pDevice->wstats.discard.nwid = 0;
+	pDevice->wstats.discard.code = 0;
+	pDevice->wstats.discard.fragment = 0;
+	pDevice->wstats.discard.retries = pDevice->scStatistic.dwTsrErr;
+	pDevice->wstats.discard.misc = 0;
+	pDevice->wstats.miss.beacon = 0;
+
+	return &pDevice->wstats;
+}
+
+
+
+/*------------------------------------------------------------------*/
+
+
+static int iwctl_commit(struct net_device *dev,
+			      struct iw_request_info *info,
+			      void *wrq,
+			      char *extra)
+{
+//2008-0409-02, <Mark> by Einsn Liu
+/*
+#ifdef Safe_Close
+  PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+#endif
+*/
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT \n");
+
+	return 0;
+
+}
+
+/*
+ * Wireless Handler : get protocol name
+ */
+
+int iwctl_giwname(struct net_device *dev,
+			 struct iw_request_info *info,
+			 char *wrq,
+			 char *extra)
+{
+	strcpy(wrq, "802.11-a/b/g");
+	return 0;
+}
+
+int iwctl_giwnwid(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+                   char *extra)
+{
+ 	//wrq->value = 0x100;
+	//wrq->disabled = 0;
+	//wrq->fixed = 1;
+	//return 0;
+  return -EOPNOTSUPP;
+}
+/*
+ * Wireless Handler : set scan
+ */
+
+int iwctl_siwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_point *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+	 PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	struct iw_scan_req  *req = (struct iw_scan_req *)extra;
+	BYTE                abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+	PWLAN_IE_SSID       pItemSSID=NULL;
+
+//2008-0920-01<Add>by MikeLiu
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+
+    PRINT_K(" SIOCSIWSCAN \n");
+
+if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
+        // In scanning..
+     PRINT_K("SIOCSIWSCAN(overlap??)-->In scanning...\n");
+     return -EAGAIN;
+  }
+
+if(pDevice->byReAssocCount > 0) {   //reject scan when re-associating!
+//send scan event to wpa_Supplicant
+  union iwreq_data wrqu;
+ PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
+ memset(&wrqu, 0, sizeof(wrqu));
+ wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
+  return 0;
+}
+
+	spin_lock_irq(&pDevice->lock);
+
+   #ifdef update_BssList
+        BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+   #endif
+
+//mike add: active scan OR passive scan OR desire_ssid scan
+ if(wrq->length == sizeof(struct iw_scan_req)) {
+   if (wrq->flags & IW_SCAN_THIS_ESSID)  {                               //desire_ssid scan
+       memset(abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+       pItemSSID = (PWLAN_IE_SSID)abyScanSSID;
+       pItemSSID->byElementID = WLAN_EID_SSID;
+       memcpy(pItemSSID->abySSID, req->essid, (int)req->essid_len);
+         if (pItemSSID->abySSID[req->essid_len - 1] == '\0') {
+           if(req->essid_len>0)
+		pItemSSID->len = req->essid_len - 1;
+         }
+	else
+	  pItemSSID->len = req->essid_len;
+	  pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+         PRINT_K("SIOCSIWSCAN:[desired_ssid=%s,len=%d]\n",((PWLAN_IE_SSID)abyScanSSID)->abySSID,
+		 	                                                                                ((PWLAN_IE_SSID)abyScanSSID)->len);
+	bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, abyScanSSID);
+	spin_unlock_irq(&pDevice->lock);
+
+	return 0;
+   }
+   else if(req->scan_type == IW_SCAN_TYPE_PASSIVE) {          //passive scan
+       pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+   }
+ }
+ else {           //active scan
+     pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+ }
+
+	 pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+         //printk("SIOCSIWSCAN:WLAN_CMD_BSSID_SCAN\n");
+	bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+	spin_unlock_irq(&pDevice->lock);
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get scan results
+ */
+
+int iwctl_giwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_point *wrq,
+             char *extra)
+{
+    int ii, jj, kk;
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PKnownBSS           pBSS;
+    PWLAN_IE_SSID       pItemSSID;
+    PWLAN_IE_SUPP_RATES pSuppRates, pExtSuppRates;
+	char *current_ev = extra;
+	char *end_buf = extra + IW_SCAN_MAX_DATA;
+	char *current_val = NULL;
+	struct iw_event iwe;
+	long ldBm;
+	char buf[MAX_WPA_IE_LEN * 2 + 30];
+
+//2008-0409-02, <Mark> by Einsn Liu
+/*
+#ifdef Safe_Close
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+#endif
+*/
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN \n");
+
+    if (pMgmt->eScanState ==  WMAC_IS_SCANNING) {
+        // In scanning..
+		return -EAGAIN;
+	}
+	pBSS = &(pMgmt->sBSSList[0]);
+    for (ii = 0, jj = 0; jj < MAX_BSS_NUM ; jj++) {
+		if (current_ev >= end_buf)
+			break;
+        pBSS = &(pMgmt->sBSSList[jj]);
+        if (pBSS->bActive) {
+		//ADD 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, pBSS->abyBSSID, WLAN_BSSID_LEN);
+                           current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
+                 //ADD ssid
+	             memset(&iwe, 0, sizeof(iwe));
+                      iwe.cmd = SIOCGIWESSID;
+                      pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
+                       iwe.u.data.length = pItemSSID->len;
+                       iwe.u.data.flags = 1;
+                      current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
+		//ADD mode
+		    memset(&iwe, 0, sizeof(iwe));
+		    iwe.cmd = SIOCGIWMODE;
+            if (WLAN_GET_CAP_INFO_ESS(pBSS->wCapInfo)) {
+		        iwe.u.mode = IW_MODE_INFRA;
+            }
+            else {
+                iwe.u.mode = IW_MODE_ADHOC;
+		    }
+	        iwe.len = IW_EV_UINT_LEN;
+                      current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe,  IW_EV_UINT_LEN);
+           //ADD frequency
+            pSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abySuppRates;
+            pExtSuppRates = (PWLAN_IE_SUPP_RATES)pBSS->abyExtSuppRates;
+            memset(&iwe, 0, sizeof(iwe));
+           	iwe.cmd = SIOCGIWFREQ;
+           	iwe.u.freq.m = pBSS->uChannel;
+           	iwe.u.freq.e = 0;
+           	iwe.u.freq.i = 0;
+                  current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+            //2008-0409-04, <Add> by Einsn Liu
+			{
+			int f = (int)pBSS->uChannel - 1;
+			if(f < 0)f = 0;
+			iwe.u.freq.m = frequency_list[f] * 100000;
+			iwe.u.freq.e = 1;
+			}
+                  current_ev = iwe_stream_add_event(info,current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
+       		//ADD quality
+            memset(&iwe, 0, sizeof(iwe));
+	        iwe.cmd = IWEVQUAL;
+	        RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+		    iwe.u.qual.level = ldBm;
+	        iwe.u.qual.noise = 0;
+//2008-0409-01, <Add> by Einsn Liu
+			if(-ldBm<50){
+				iwe.u.qual.qual = 100;
+			}else  if(-ldBm > 90) {
+				 iwe.u.qual.qual = 0;
+			}else {
+				iwe.u.qual.qual=(40-(-ldBm-50))*100/40;
+			}
+			iwe.u.qual.updated=7;
+
+//2008-0409-01, <Mark> by Einsn Liu
+/*
+//2008-0220-03, <Modify>  by Einsn Liu
+	if(pDevice->bLinkPass== TRUE && IS_ETH_ADDRESS_EQUAL(pBSS->abyBSSID, pMgmt->abyCurrBSSID)){
+	#ifdef Calcu_LinkQual
+	 #if 0
+	  if(pDevice->byBBType == BB_TYPE_11B) {
+	     if(pDevice->byCurrSQ > 120)
+                  pDevice->scStatistic.LinkQuality = 100;
+	     else
+		 pDevice->scStatistic.LinkQuality = pDevice->byCurrSQ*100/120;
+	    }
+	  else if(pDevice->byBBType == BB_TYPE_11G) {
+                if(pDevice->byCurrSQ < 20)
+		   pDevice->scStatistic.LinkQuality = 100;
+	       else if(pDevice->byCurrSQ >96)
+		   pDevice->scStatistic.LinkQuality  = 0;
+	       else
+		   pDevice->scStatistic.LinkQuality = (96-pDevice->byCurrSQ)*100/76;
+	   }
+	   if(pDevice->bLinkPass !=TRUE)
+	       pDevice->scStatistic.LinkQuality = 0;
+	  #endif
+	   if(pDevice->scStatistic.LinkQuality > 100)
+   	       pDevice->scStatistic.LinkQuality = 100;
+              iwe.u.qual.qual =(BYTE) pDevice->scStatistic.LinkQuality;
+	#else
+	iwe.u.qual.qual = pDevice->byCurrSQ;
+	#endif
+		}else {
+	        iwe.u.qual.qual = 0;
+		}
+*/
+                 current_ev = iwe_stream_add_event(info,current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+       	//ADD encryption
+            memset(&iwe, 0, sizeof(iwe));
+            iwe.cmd = SIOCGIWENCODE;
+            iwe.u.data.length = 0;
+            if (WLAN_GET_CAP_INFO_PRIVACY(pBSS->wCapInfo)) {
+                iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+            }else {
+                iwe.u.data.flags = IW_ENCODE_DISABLED;
+            }
+            current_ev = iwe_stream_add_point(info,current_ev,end_buf, &iwe, pItemSSID->abySSID);
+
+            memset(&iwe, 0, sizeof(iwe));
+            iwe.cmd = SIOCGIWRATE;
+           	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+      		current_val = current_ev + IW_EV_LCP_LEN;
+
+       		for (kk = 0 ; kk < 12 ; kk++) {
+		        if (pSuppRates->abyRates[kk] == 0)
+			        break;
+		        // Bit rate given in 500 kb/s units (+ 0x80)
+		        iwe.u.bitrate.value = ((pSuppRates->abyRates[kk] & 0x7f) * 500000);
+                          current_val = iwe_stream_add_value(info,current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+	        }
+       		for (kk = 0 ; kk < 8 ; kk++) {
+		        if (pExtSuppRates->abyRates[kk] == 0)
+			        break;
+		        // Bit rate given in 500 kb/s units (+ 0x80)
+		        iwe.u.bitrate.value = ((pExtSuppRates->abyRates[kk] & 0x7f) * 500000);
+                         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;
+
+            memset(&iwe, 0, sizeof(iwe));
+            iwe.cmd = IWEVCUSTOM;
+            sprintf(buf, "bcn_int=%d", pBSS->wBeaconInterval);
+            iwe.u.data.length = strlen(buf);
+             current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, buf);
+
+            if ((pBSS->wWPALen > 0) && (pBSS->wWPALen <= MAX_WPA_IE_LEN)) {
+                memset(&iwe, 0, sizeof(iwe));
+                iwe.cmd = IWEVGENIE;
+                iwe.u.data.length = pBSS->wWPALen;
+                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byWPAIE);
+            }
+
+            if ((pBSS->wRSNLen > 0) && (pBSS->wRSNLen <= MAX_WPA_IE_LEN)) {
+                memset(&iwe, 0, sizeof(iwe));
+                iwe.cmd = IWEVGENIE;
+                iwe.u.data.length = pBSS->wRSNLen;
+                current_ev = iwe_stream_add_point(info,current_ev, end_buf, &iwe, pBSS->byRSNIE);
+            }
+
+        }
+    }// for
+
+	wrq->length = current_ev - extra;
+	return 0;
+
+}
+
+
+/*
+ * Wireless Handler : set frequence or channel
+ */
+
+int iwctl_siwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+	int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ \n");
+
+	// If setting by frequency, convert to a channel
+	if((wrq->e == 1) &&
+	   (wrq->m >= (int) 2.412e8) &&
+	   (wrq->m <= (int) 2.487e8)) {
+		int f = wrq->m / 100000;
+		int c = 0;
+		while((c < 14) && (f != frequency_list[c]))
+			c++;
+		wrq->e = 0;
+		wrq->m = c + 1;
+	}
+	// Setting by channel number
+	if((wrq->m > 14) || (wrq->e > 0))
+		rc = -EOPNOTSUPP;
+	else {
+		int channel = wrq->m;
+		if((channel < 1) || (channel > 14)) {
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m);
+			rc = -EINVAL;
+		} else {
+			  // Yes ! We can set it !!!
+              DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel);
+			  pDevice->uChannel = channel;
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get frequence or channel
+ */
+
+int iwctl_giwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ \n");
+
+#ifdef WEXT_USECHANNELS
+	wrq->m = (int)pMgmt->uCurrChannel;
+	wrq->e = 0;
+#else
+	{
+		int f = (int)pMgmt->uCurrChannel - 1;
+		if(f < 0)
+		   f = 0;
+		wrq->m = frequency_list[f] * 100000;
+		wrq->e = 1;
+	}
+#endif
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : set operation mode
+ */
+
+int iwctl_siwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE \n");
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Can't set operation mode, hostapd is running \n");
+        return rc;
+    }
+
+	switch(*wmode) {
+
+	case IW_MODE_ADHOC:
+	    if (pMgmt->eConfigMode != WMAC_CONFIG_IBSS_STA) {
+            pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		        pDevice->bCommit = TRUE;
+   		    }
+		}
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc \n");
+		break;
+	case IW_MODE_AUTO:
+	case IW_MODE_INFRA:
+	    if (pMgmt->eConfigMode != WMAC_CONFIG_ESS_STA) {
+            pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		        pDevice->bCommit = TRUE;
+   		    }
+		}
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure \n");
+		break;
+	case IW_MODE_MASTER:
+
+        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+		rc = -EOPNOTSUPP;
+		break;
+
+	    if (pMgmt->eConfigMode != WMAC_CONFIG_AP) {
+            pMgmt->eConfigMode = WMAC_CONFIG_AP;
+            if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		        pDevice->bCommit = TRUE;
+   		    }
+		}
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point \n");
+		break;
+
+	case IW_MODE_REPEAT:
+        pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+		rc = -EOPNOTSUPP;
+		break;
+	default:
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get operation mode
+ */
+
+int iwctl_giwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE \n");
+	// If not managed, assume it's ad-hoc
+	switch (pMgmt->eConfigMode) {
+	case WMAC_CONFIG_ESS_STA:
+		*wmode = IW_MODE_INFRA;
+		break;
+	case WMAC_CONFIG_IBSS_STA:
+        *wmode = IW_MODE_ADHOC;
+		break;
+	case WMAC_CONFIG_AUTO:
+		*wmode = IW_MODE_INFRA;
+		break;
+	case WMAC_CONFIG_AP:
+		*wmode = IW_MODE_MASTER;
+		break;
+	default:
+		*wmode = IW_MODE_ADHOC;
+	}
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get capability range
+ */
+
+int iwctl_giwrange(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+	struct iw_range *range = (struct iw_range *) extra;
+	int		i,k;
+    BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+//2008-0409-02, <Mark> by Einsn Liu
+/*
+ #ifdef Safe_Close
+  PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+#endif
+ */
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE \n");
+	if (wrq->pointer) {
+		wrq->length = sizeof(struct iw_range);
+		memset(range, 0, sizeof(struct iw_range));
+		range->min_nwid = 0x0000;
+		range->max_nwid = 0x0000;
+		range->num_channels = 14;
+		// Should be based on cap_rid.country to give only
+		//  what the current card support
+		k = 0;
+		for(i = 0; i < 14; i++) {
+			range->freq[k].i = i + 1; // List index
+			range->freq[k].m = frequency_list[i] * 100000;
+			range->freq[k++].e = 1;	// Values in table in MHz -> * 10^5 * 10
+		}
+		range->num_frequency = k;
+		// Hum... Should put the right values there
+	     #ifdef Calcu_LinkQual
+                 range->max_qual.qual = 100;
+	     #else
+		range->max_qual.qual = 255;
+	     #endif
+		range->max_qual.level = 0;
+		range->max_qual.noise = 0;
+		range->sensitivity = 255;
+
+		for(i = 0 ; i < 13 ; i++) {
+			range->bitrate[i] = abySupportedRates[i] * 500000;
+			if(range->bitrate[i] == 0)
+				break;
+		}
+		range->num_bitrates = i;
+
+		// Set an indication of the max TCP throughput
+		// in bit/s that we can expect using this interface.
+		//  May be use for QoS stuff... Jean II
+		if(i > 2)
+			range->throughput = 5 * 1000 * 1000;
+		else
+			range->throughput = 1.5 * 1000 * 1000;
+
+		range->min_rts = 0;
+		range->max_rts = 2312;
+		range->min_frag = 256;
+		range->max_frag = 2312;
+
+
+	    // the encoding capabilities
+	    range->num_encoding_sizes = 3;
+	    // 64(40) bits WEP
+	    range->encoding_size[0] = 5;
+	    // 128(104) bits WEP
+	    range->encoding_size[1] = 13;
+	    // 256 bits for WPA-PSK
+	    range->encoding_size[2] = 32;
+	    // 4 keys are allowed
+	    range->max_encoding_tokens = 4;
+
+	    range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+		    IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+
+		range->min_pmp = 0;
+		range->max_pmp = 1000000;// 1 secs
+		range->min_pmt = 0;
+		range->max_pmt = 1000000;// 1 secs
+		range->pmp_flags = IW_POWER_PERIOD;
+		range->pmt_flags = IW_POWER_TIMEOUT;
+		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
+
+		// Transmit Power - values are in mW
+
+        range->txpower[0] = 100;
+		range->num_txpower = 1;
+		range->txpower_capa = IW_TXPOW_MWATT;
+		range->we_version_source = SUPPORTED_WIRELESS_EXT;
+		range->we_version_compiled = WIRELESS_EXT;
+		range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
+		range->retry_flags = IW_RETRY_LIMIT;
+		range->r_time_flags = IW_RETRY_LIFETIME;
+		range->min_retry = 1;
+		range->max_retry = 65535;
+		range->min_r_time = 1024;
+		range->max_r_time = 65535 * 1024;
+		// Experimental measurements - boundary 11/5.5 Mb/s
+		// Note : with or without the (local->rssi), results
+		//  are somewhat different. - Jean II
+		range->avg_qual.qual = 6;
+		range->avg_qual.level = 176;	// -80 dBm
+		range->avg_qual.noise = 0;
+	}
+
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : set ap mac address
+ */
+
+int iwctl_siwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+    BYTE                 ZeroBSSID[WLAN_BSSID_LEN]={0x00,0x00,0x00,0x00,0x00,0x00};
+
+   PRINT_K(" SIOCSIWAP \n");
+
+	if (wrq->sa_family != ARPHRD_ETHER)
+		rc = -EINVAL;
+	else {
+		memset(pMgmt->abyDesireBSSID, 0xFF, 6);
+		memcpy(pMgmt->abyDesireBSSID, wrq->sa_data, 6);
+
+	//mike :add
+	 if ((IS_BROADCAST_ADDRESS(pMgmt->abyDesireBSSID)) ||
+	     (memcmp(pMgmt->abyDesireBSSID, ZeroBSSID, 6) == 0)){
+	      PRINT_K("SIOCSIWAP:invalid desired BSSID return!\n");
+               return rc;
+         }
+       //mike add: if desired AP is hidden ssid(there are two same BSSID in list),
+       //                  then ignore,because you don't known which one to be connect with??
+       	{
+           UINT            ii , uSameBssidNum=0;
+                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+                     if (pMgmt->sBSSList[ii].bActive &&
+                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID,pMgmt->abyDesireBSSID)) {
+                        uSameBssidNum++;
+                     }
+                  }
+	     if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
+                 PRINT_K("SIOCSIWAP:ignore for desired AP in hidden mode\n");
+	        return rc;
+	     }
+       	}
+
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+		    pDevice->bCommit = TRUE;
+   		}
+	}
+	return rc;
+}
+
+/*
+ * Wireless Handler : get ap mac address
+ */
+
+int iwctl_giwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP \n");
+
+    memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
+
+//20080123-02,<Modify> by Einsn Liu
+ if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode != WMAC_MODE_ESS_AP))
+ //   if ((pDevice->bLinkPass == FALSE) && (pMgmt->eCurrMode == WMAC_MODE_ESS_STA))
+        memset(wrq->sa_data, 0, 6);
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6);
+    }
+
+	wrq->sa_family = ARPHRD_ETHER;
+
+	return 0;
+
+}
+
+
+/*
+ * Wireless Handler : get ap list
+ */
+
+int iwctl_giwaplist(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+	int ii,jj, rc = 0;
+	struct sockaddr sock[IW_MAX_AP];
+	struct iw_quality qual[IW_MAX_AP];
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n");
+	// Only super-user can see AP list
+
+	if (!capable(CAP_NET_ADMIN)) {
+		rc = -EPERM;
+		return rc;
+	}
+
+	if (wrq->pointer) {
+
+		PKnownBSS pBSS = &(pMgmt->sBSSList[0]);
+
+		for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) {
+		    pBSS = &(pMgmt->sBSSList[ii]);
+            if (!pBSS->bActive)
+                continue;
+            if ( jj >= IW_MAX_AP)
+                break;
+			memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6);
+			sock[jj].sa_family = ARPHRD_ETHER;
+			qual[jj].level = pBSS->uRSSI;
+			qual[jj].qual = qual[jj].noise = 0;
+			qual[jj].updated = 2;
+			jj++;
+		}
+
+		wrq->flags = 1; // Should be define'd
+		wrq->length = jj;
+		memcpy(extra, sock, sizeof(struct sockaddr)*jj);
+		memcpy(extra + sizeof(struct sockaddr)*jj, qual, sizeof(struct iw_quality)*jj);
+	}
+
+	return rc;
+}
+
+
+/*
+ * Wireless Handler : set essid
+ */
+
+int iwctl_siwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PWLAN_IE_SSID       pItemSSID;
+
+//2008-0920-01<Add>by MikeLiu
+  if (!(pDevice->flags & DEVICE_FLAGS_OPENED))
+        return -EINVAL;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID :\n");
+
+         pDevice->fWPA_Authened = FALSE;
+	// Check if we asked for `any'
+	if(wrq->flags == 0) {
+		// Just send an empty SSID list
+		memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                  memset(pMgmt->abyDesireBSSID, 0xFF,6);
+	    PRINT_K("set essid to 'any' \n");
+           #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+             //Unknown desired AP,so here need not associate??
+                  return 0;
+            #endif
+	} else {
+		// Set the SSID
+		memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+        pItemSSID->byElementID = WLAN_EID_SSID;
+
+		memcpy(pItemSSID->abySSID, extra, wrq->length);
+         if (pItemSSID->abySSID[wrq->length - 1] == '\0') {
+           if(wrq->length>0)
+		pItemSSID->len = wrq->length - 1;
+         }
+	else
+	  pItemSSID->len = wrq->length;
+	PRINT_K("set essid to %s \n",pItemSSID->abySSID);
+
+     //mike:need clear desiredBSSID
+     if(pItemSSID->len==0) {
+        memset(pMgmt->abyDesireBSSID, 0xFF,6);
+        return 0;
+     }
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+ //Wext wil order another command of siwap to link with desired AP,
+ //so here need not associate??
+  if(pDevice->bWPASuppWextEnabled == TRUE)  {
+        /*******search if  in hidden ssid mode ****/
+        {
+           PKnownBSS       pCurr = NULL;
+           BYTE                   abyTmpDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+	  UINT            ii , uSameBssidNum=0;
+
+	  memset(abyTmpDesireSSID,0,sizeof(abyTmpDesireSSID));
+	  memcpy(abyTmpDesireSSID,pMgmt->abyDesireSSID,sizeof(abyTmpDesireSSID));
+            pCurr = BSSpSearchBSSList(pDevice,
+                                      NULL,
+                                      abyTmpDesireSSID,
+                                      pDevice->eConfigPHYMode
+                                      );
+
+            if (pCurr == NULL){
+               PRINT_K("SIOCSIWESSID:hidden ssid site survey before associate.......\n");
+	      vResetCommandTimer((HANDLE) pDevice);
+	      pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+               bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+	      bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+          }
+	 else {  //mike:to find out if that desired SSID is a hidden-ssid AP ,
+                     //         by means of judging if there are two same BSSID exist in list ?
+                  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+                     if (pMgmt->sBSSList[ii].bActive &&
+                        IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+                        uSameBssidNum++;
+                     }
+                  }
+	     if(uSameBssidNum >= 2) {  //hit: desired AP is in hidden ssid mode!!!
+                 PRINT_K("SIOCSIWESSID:hidden ssid directly associate.......\n");
+	        vResetCommandTimer((HANDLE) pDevice);
+	        pMgmt->eScanType = WMAC_SCAN_PASSIVE;          //this scan type,you'll submit scan result!
+	        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+	        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, pMgmt->abyDesireSSID);
+	     }
+	 }
+        }
+     return 0;
+  }
+	     #endif
+
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID);
+	}
+
+    if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+	    pDevice->bCommit = TRUE;
+	}
+
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get essid
+ */
+
+int iwctl_giwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	PWLAN_IE_SSID       pItemSSID;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID \n");
+
+	// Note : if wrq->u.data.flags != 0, we should
+	// get the relevant SSID from the SSID list...
+
+	// Get the current SSID
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+	//pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+	memcpy(extra, pItemSSID->abySSID , pItemSSID->len);
+	extra[pItemSSID->len] = '\0';
+        //2008-0409-03, <Add> by Einsn Liu
+        wrq->length = pItemSSID->len;
+	wrq->flags = 1; // active
+
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : set data rate
+ */
+
+int iwctl_siwrate(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    int rc = 0;
+	u8	brate = 0;
+	int	i;
+	BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE \n");
+    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+        rc = -EINVAL;
+        return rc;
+    }
+
+	// First : get a valid bit rate value
+
+	// Which type of value
+	if((wrq->value < 13) &&
+	   (wrq->value >= 0)) {
+		// Setting by rate index
+		// Find value in the magic rate table
+		brate = wrq->value;
+	} else {
+		// Setting by frequency value
+		u8	normvalue = (u8) (wrq->value/500000);
+
+		// Check if rate is valid
+		for(i = 0 ; i < 13 ; i++) {
+			if(normvalue == abySupportedRates[i]) {
+				brate = i;
+				break;
+			}
+		}
+	}
+	// -1 designed the max rate (mostly auto mode)
+	if(wrq->value == -1) {
+		// Get the highest available rate
+		for(i = 0 ; i < 13 ; i++) {
+			if(abySupportedRates[i] == 0)
+				break;
+		}
+		if(i != 0)
+			brate = i - 1;
+
+	}
+	// Check that it is valid
+	// brate is index of abySupportedRates[]
+	if(brate > 13 ) {
+		rc = -EINVAL;
+		return rc;
+	}
+
+	// Now, check if we want a fixed or auto value
+	if(wrq->fixed != 0) {
+		// Fixed mode
+		// One rate, fixed
+		pDevice->bFixRate = TRUE;
+        if ((pDevice->byBBType == BB_TYPE_11B)&& (brate > 3)) {
+            pDevice->uConnectionRate = 3;
+        }
+        else {
+            pDevice->uConnectionRate = brate;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d \n", pDevice->uConnectionRate);
+        }
+
+	}
+	else {
+        pDevice->bFixRate = FALSE;
+        pDevice->uConnectionRate = 13;
+    }
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get data rate
+ */
+
+int iwctl_giwrate(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE \n");
+    {
+        BYTE abySupportedRates[13]= {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90};
+	    int brate = 0;
+		if (pDevice->uConnectionRate < 13) {
+	        brate = abySupportedRates[pDevice->uConnectionRate];
+	    }else {
+            if (pDevice->byBBType == BB_TYPE_11B)
+	            brate = 0x16;
+            if (pDevice->byBBType == BB_TYPE_11G)
+	            brate = 0x6C;
+            if (pDevice->byBBType == BB_TYPE_11A)
+	            brate = 0x6C;
+	    }
+
+	    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+            if (pDevice->byBBType == BB_TYPE_11B)
+	            brate = 0x16;
+            if (pDevice->byBBType == BB_TYPE_11G)
+	            brate = 0x6C;
+            if (pDevice->byBBType == BB_TYPE_11A)
+	            brate = 0x6C;
+	    }
+    		if (pDevice->uConnectionRate == 13)
+                brate = abySupportedRates[pDevice->wCurrentRate];
+	    wrq->value = brate * 500000;
+	    // If more than one rate, set auto
+	    if (pDevice->bFixRate == TRUE)
+	        wrq->fixed = TRUE;
+    }
+
+
+	return 0;
+}
+
+
+
+/*
+ * Wireless Handler : set rts threshold
+ */
+
+int iwctl_siwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+	int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS \n");
+
+	{
+	    int rthr = wrq->value;
+	    if(wrq->disabled)
+			rthr = 2312;
+	    if((rthr < 0) || (rthr > 2312)) {
+			rc = -EINVAL;
+    	}else {
+		    pDevice->wRTSThreshold = rthr;
+	    }
+    }
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : get rts
+ */
+
+int iwctl_giwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS \n");
+	wrq->value = pDevice->wRTSThreshold;
+	wrq->disabled = (wrq->value >= 2312);
+	wrq->fixed = 1;
+
+	return 0;
+}
+
+/*
+ * Wireless Handler : set fragment threshold
+ */
+
+int iwctl_siwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    int rc = 0;
+    int fthr = wrq->value;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG \n");
+
+
+    if (wrq->disabled)
+		fthr = 2312;
+    if((fthr < 256) || (fthr > 2312)) {
+		rc = -EINVAL;
+    }else {
+		 fthr &= ~0x1;	// Get an even value
+	     pDevice->wFragmentationThreshold = (u16)fthr;
+    }
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get fragment threshold
+ */
+
+int iwctl_giwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG \n");
+	wrq->value = pDevice->wFragmentationThreshold;
+	wrq->disabled = (wrq->value >= 2312);
+	wrq->fixed = 1;
+
+	return 0;
+}
+
+
+
+/*
+ * Wireless Handler : set retry threshold
+ */
+int iwctl_siwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    int rc = 0;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY \n");
+
+	if (wrq->disabled) {
+		rc = -EINVAL;
+		return rc;
+	}
+
+	if (wrq->flags & IW_RETRY_LIMIT) {
+		if(wrq->flags & IW_RETRY_MAX)
+			pDevice->byLongRetryLimit = wrq->value;
+		else if (wrq->flags & IW_RETRY_MIN)
+			pDevice->byShortRetryLimit = wrq->value;
+		else {
+			// No modifier : set both
+			pDevice->byShortRetryLimit = wrq->value;
+			pDevice->byLongRetryLimit = wrq->value;
+		}
+	}
+	if (wrq->flags & IW_RETRY_LIFETIME) {
+		pDevice->wMaxTransmitMSDULifetime = wrq->value;
+	}
+
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get retry threshold
+ */
+int iwctl_giwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY \n");
+	wrq->disabled = 0;      // Can't be disabled
+
+	// Note : by default, display the min retry number
+	if((wrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+		wrq->flags = IW_RETRY_LIFETIME;
+		wrq->value = (int)pDevice->wMaxTransmitMSDULifetime; //ms
+	} else if((wrq->flags & IW_RETRY_MAX)) {
+		wrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+		wrq->value = (int)pDevice->byLongRetryLimit;
+	} else {
+		wrq->flags = IW_RETRY_LIMIT;
+		wrq->value = (int)pDevice->byShortRetryLimit;
+		if((int)pDevice->byShortRetryLimit != (int)pDevice->byLongRetryLimit)
+			wrq->flags |= IW_RETRY_MIN;
+	}
+
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : set encode mode
+ */
+int iwctl_siwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	DWORD dwKeyIndex = (DWORD)(wrq->flags & IW_ENCODE_INDEX);
+	int ii,uu, rc = 0;
+	int index = (wrq->flags & IW_ENCODE_INDEX);
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE \n");
+
+	// Check the size of the key
+	if (wrq->length > WLAN_WEP232_KEYLEN) {
+		rc = -EINVAL;
+        return rc;
+	}
+
+	if (dwKeyIndex > WLAN_WEP_NKEYS) {
+		rc = -EINVAL;
+        return rc;
+    }
+
+    if (dwKeyIndex > 0)
+		dwKeyIndex--;
+
+	// Send the key to the card
+	if (wrq->length > 0) {
+
+        if (wrq->length ==  WLAN_WEP232_KEYLEN) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n");
+        }
+        else if (wrq->length ==  WLAN_WEP104_KEYLEN) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n");
+        }
+        else if (wrq->length == WLAN_WEP40_KEYLEN) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex);
+        }
+        memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN);
+        memcpy(pDevice->abyKey, extra, wrq->length);
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyKey: ");
+        for (ii = 0; ii < wrq->length; ii++) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]);
+        }
+
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+            spin_lock_irq(&pDevice->lock);
+            KeybSetDefaultKey(  pDevice,
+                                &(pDevice->sKey),
+                                dwKeyIndex | (1 << 31),
+                                wrq->length,
+                                NULL,
+                                pDevice->abyKey,
+                                KEY_CTL_WEP
+                              );
+            spin_unlock_irq(&pDevice->lock);
+        }
+        pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+        pDevice->uKeyLength = wrq->length;
+        pDevice->bTransmitKey = TRUE;
+        pDevice->bEncryptionEnable = TRUE;
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+
+		// Do we want to just set the transmit key index ?
+		if ( index < 4 ) {
+		    pDevice->byKeyIndex = index;
+		} else if (!(wrq->flags & IW_ENCODE_MODE)) {
+				rc = -EINVAL;
+				return rc;
+	    }
+	}
+	// Read the flags
+	if(wrq->flags & IW_ENCODE_DISABLED){
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n");
+		pMgmt->bShareKeyAlgorithm = FALSE;
+        pDevice->bEncryptionEnable = FALSE;
+        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+        if (pDevice->flags & DEVICE_FLAGS_OPENED) {
+            spin_lock_irq(&pDevice->lock);
+            for(uu=0;uu<MAX_KEY_TABLE;uu++)
+                MACvDisableKeyEntry(pDevice,uu);
+            spin_unlock_irq(&pDevice->lock);
+        }
+	}
+	if(wrq->flags & IW_ENCODE_RESTRICTED) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n");
+		pMgmt->bShareKeyAlgorithm = TRUE;
+	}
+	if(wrq->flags & IW_ENCODE_OPEN) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n");
+		pMgmt->bShareKeyAlgorithm = FALSE;
+	}
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	   memset(pMgmt->abyDesireBSSID, 0xFF,6);
+#endif
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get encode mode
+ */
+//2008-0409-06, <Mark> by Einsn Liu
+ /*
+int iwctl_giwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+    char abyKey[WLAN_WEP232_KEYLEN];
+	UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
+	PSKeyItem   pKey = NULL;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+
+
+	memset(abyKey, 0, sizeof(abyKey));
+	// Check encryption mode
+	wrq->flags = IW_ENCODE_NOKEY;
+	// Is WEP enabled ???
+	if (pDevice->bEncryptionEnable)
+		wrq->flags |=  IW_ENCODE_ENABLED;
+    else
+		wrq->flags |=  IW_ENCODE_DISABLED;
+
+    if (pMgmt->bShareKeyAlgorithm)
+		wrq->flags |=  IW_ENCODE_RESTRICTED;
+	else
+		wrq->flags |=  IW_ENCODE_OPEN;
+
+	if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
+        wrq->length = pKey->uKeyLength;
+        memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
+    }
+    else {
+        rc = -EINVAL;
+        return rc;
+    }
+	wrq->flags |= index;
+	// Copy the key to the user buffer
+	memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
+	return 0;
+}
+*/
+
+//2008-0409-06, <Add> by Einsn Liu
+
+int iwctl_giwencode(struct net_device *dev,
+			struct iw_request_info *info,
+			struct iw_point *wrq,
+			char *extra)
+{
+	PSDevice			pDevice = (PSDevice)netdev_priv(dev);
+	PSMgmtObject		pMgmt = &(pDevice->sMgmtObj);
+	char abyKey[WLAN_WEP232_KEYLEN];
+
+	UINT index = (UINT)(wrq->flags & IW_ENCODE_INDEX);
+	PSKeyItem	pKey = NULL;
+
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n");
+
+	if (index > WLAN_WEP_NKEYS) {
+		return	-EINVAL;
+	}
+	if(index<1){//get default key
+		if(pDevice->byKeyIndex<WLAN_WEP_NKEYS){
+			index=pDevice->byKeyIndex;
+         	} else
+                      index=0;
+	}else
+             index--;
+
+	memset(abyKey, 0, WLAN_WEP232_KEYLEN);
+	// Check encryption mode
+	wrq->flags = IW_ENCODE_NOKEY;
+	// Is WEP enabled ???
+	if (pDevice->bEncryptionEnable)
+		wrq->flags |=  IW_ENCODE_ENABLED;
+	else
+		wrq->flags |=  IW_ENCODE_DISABLED;
+
+	if (pMgmt->bShareKeyAlgorithm)
+		wrq->flags |=  IW_ENCODE_RESTRICTED;
+	else
+		wrq->flags |=  IW_ENCODE_OPEN;
+		wrq->length=0;
+
+	if((index==0)&&(pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled||
+		pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)){//get wpa pairwise  key
+			if (KeybGetKey(&(pDevice->sKey),pMgmt->abyCurrBSSID, 0xffffffff, &pKey)){
+			   wrq->length = pKey->uKeyLength;
+				  memcpy(abyKey, pKey->abyKey,	pKey->uKeyLength);
+				  memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
+			   }
+	}else if (KeybGetKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, (BYTE)index , &pKey)){
+			wrq->length = pKey->uKeyLength;
+			memcpy(abyKey, pKey->abyKey,  pKey->uKeyLength);
+		memcpy(extra,  abyKey, WLAN_WEP232_KEYLEN);
+	}
+
+	wrq->flags |= index+1;
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : set power mode
+ */
+int iwctl_siwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int rc = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER \n");
+
+    if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		 rc = -EINVAL;
+		 return rc;
+	}
+
+	if (wrq->disabled) {
+		pDevice->ePSMode = WMAC_POWER_CAM;
+		PSvDisablePowerSaving(pDevice);
+		return rc;
+	}
+	if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+         pDevice->ePSMode = WMAC_POWER_FAST;
+         PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
+
+	} else if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
+	     pDevice->ePSMode = WMAC_POWER_FAST;
+         PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
+	}
+	switch (wrq->flags & IW_POWER_MODE) {
+	case IW_POWER_UNICAST_R:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R \n");
+		rc = -EINVAL;
+		break;
+	case IW_POWER_ALL_R:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R \n");
+		rc = -EINVAL;
+	case IW_POWER_ON:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON \n");
+		break;
+	default:
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
+/*
+ * Wireless Handler : get power mode
+ */
+int iwctl_giwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra)
+{
+    PSDevice            pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    int mode = pDevice->ePSMode;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER \n");
+
+
+	if ((wrq->disabled = (mode == WMAC_POWER_CAM)))
+	    return 0;
+
+	if ((wrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
+		wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
+		wrq->flags = IW_POWER_TIMEOUT;
+	} else {
+		wrq->value = (int)((pMgmt->wListenInterval * pMgmt->wCurrBeaconPeriod) << 10);
+		wrq->flags = IW_POWER_PERIOD;
+	}
+	wrq->flags |= IW_POWER_ALL_R;
+
+	return 0;
+}
+
+
+/*
+ * Wireless Handler : get Sensitivity
+ */
+int iwctl_giwsens(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_param *wrq,
+			 char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    long ldBm;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS \n");
+    if (pDevice->bLinkPass == TRUE) {
+        RFvRSSITodBm(pDevice, (BYTE)(pDevice->uCurrRSSI), &ldBm);
+	    wrq->value = ldBm;
+	}
+	else {
+	    wrq->value = 0;
+    };
+	wrq->disabled = (wrq->value == 0);
+	wrq->fixed = 1;
+
+
+	return 0;
+}
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+
+int iwctl_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra)
+{
+	PSDevice			pDevice = (PSDevice)netdev_priv(dev);
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	int ret=0;
+	static int wpa_version=0;  //must be static to save the last value,einsn liu
+	static int pairwise=0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+	switch (wrq->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+		wpa_version = wrq->value;
+		if(wrq->value == IW_AUTH_WPA_VERSION_DISABLED) {
+		       PRINT_K("iwctl_siwauth:set WPADEV to disable at 1??????\n");
+			//pDevice->bWPADEVUp = FALSE;
+		}
+		else if(wrq->value == IW_AUTH_WPA_VERSION_WPA) {
+                          PRINT_K("iwctl_siwauth:set WPADEV to WPA1******\n");
+		}
+		else {
+                          PRINT_K("iwctl_siwauth:set WPADEV to WPA2******\n");
+		}
+		//pDevice->bWPASuppWextEnabled =TRUE;
+		break;
+	case IW_AUTH_CIPHER_PAIRWISE:
+		pairwise = wrq->value;
+                   PRINT_K("iwctl_siwauth:set pairwise=%d\n",pairwise);
+		if(pairwise == IW_AUTH_CIPHER_CCMP){
+			pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+		}else if(pairwise == IW_AUTH_CIPHER_TKIP){
+			pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+		}else if(pairwise == IW_AUTH_CIPHER_WEP40||pairwise == IW_AUTH_CIPHER_WEP104){
+			pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+		}else if(pairwise == IW_AUTH_CIPHER_NONE){
+			//do nothing,einsn liu
+		}else pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+
+		break;
+	case IW_AUTH_CIPHER_GROUP:
+		 PRINT_K("iwctl_siwauth:set GROUP=%d\n",wrq->value);
+		if(wpa_version == IW_AUTH_WPA_VERSION_DISABLED)
+			break;
+		if(pairwise == IW_AUTH_CIPHER_NONE){
+			if(wrq->value == IW_AUTH_CIPHER_CCMP){
+				pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+			}else {
+				pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+			}
+		}
+		break;
+	case IW_AUTH_KEY_MGMT:
+                    PRINT_K("iwctl_siwauth(wpa_version=%d):set KEY_MGMT=%d\n",wpa_version,wrq->value);
+		if(wpa_version == IW_AUTH_WPA_VERSION_WPA2){
+			if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
+				pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
+			else pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
+		}else if(wpa_version == IW_AUTH_WPA_VERSION_WPA){
+			if(wrq->value == 0){
+				pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+			}else if(wrq->value == IW_AUTH_KEY_MGMT_PSK)
+				pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+			else pMgmt->eAuthenMode = WMAC_AUTH_WPA;
+		}
+
+		break;
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		break;		/* FIXME */
+	case IW_AUTH_DROP_UNENCRYPTED:
+		break;
+	case IW_AUTH_80211_AUTH_ALG:
+		 PRINT_K("iwctl_siwauth:set AUTH_ALG=%d\n",wrq->value);
+		if(wrq->value==IW_AUTH_ALG_OPEN_SYSTEM){
+			pMgmt->bShareKeyAlgorithm=FALSE;
+		}else if(wrq->value==IW_AUTH_ALG_SHARED_KEY){
+			pMgmt->bShareKeyAlgorithm=TRUE;
+		}
+		break;
+	case IW_AUTH_WPA_ENABLED:
+		//pDevice->bWPADEVUp = !! wrq->value;
+		//if(pDevice->bWPADEVUp==TRUE)
+		  // printk("iwctl_siwauth:set WPADEV to enable sucessful*******\n");
+		//else
+		 //  printk("iwctl_siwauth:set WPADEV to enable fail?????\n");
+		break;
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		break;
+	case IW_AUTH_ROAMING_CONTROL:
+		ret = -EOPNOTSUPP;
+		break;
+	case IW_AUTH_PRIVACY_INVOKED:
+		pDevice->bEncryptionEnable = !!wrq->value;
+		if(pDevice->bEncryptionEnable == FALSE){
+			wpa_version = 0;
+			pairwise = 0;
+			pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+			pMgmt->bShareKeyAlgorithm = FALSE;
+			pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+			//pDevice->bWPADEVUp = FALSE;
+			 PRINT_K("iwctl_siwauth:set WPADEV to disaable at 2?????\n");
+		}
+
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+/*
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_version = %d\n",wpa_version);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise = %d\n",pairwise);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->eEncryptionStatus = %d\n",pDevice->eEncryptionStatus);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->eAuthenMode  = %d\n",pMgmt->eAuthenMode);
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->bShareKeyAlgorithm = %s\n",pMgmt->bShareKeyAlgorithm?"TRUE":"FALSE");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bEncryptionEnable = %s\n",pDevice->bEncryptionEnable?"TRUE":"FALSE");
+	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->bWPADEVUp = %s\n",pDevice->bWPADEVUp?"TRUE":"FALSE");
+*/
+   return ret;
+}
+
+
+int iwctl_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra)
+{
+	return -EOPNOTSUPP;
+}
+
+
+
+int iwctl_siwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra)
+{
+	PSDevice			pDevice = (PSDevice)netdev_priv(dev);
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	int ret=0;
+
+	if(wrq->length){
+		if ((wrq->length < 2) || (extra[1]+2 != wrq->length)) {
+			ret = -EINVAL;
+			goto out;
+		}
+		if(wrq->length > MAX_WPA_IE_LEN){
+			ret = -ENOMEM;
+			goto out;
+		}
+		memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
+		if(copy_from_user(pMgmt->abyWPAIE, extra, wrq->length)){
+			ret = -EFAULT;
+			goto out;
+		}
+		pMgmt->wWPAIELen = wrq->length;
+	}else {
+		memset(pMgmt->abyWPAIE, 0, MAX_WPA_IE_LEN);
+		pMgmt->wWPAIELen = 0;
+	}
+
+	out://not completely ...not necessary in wpa_supplicant 0.5.8
+	return 0;
+}
+
+int iwctl_giwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra)
+{
+	PSDevice			pDevice = (PSDevice)netdev_priv(dev);
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	int ret=0;
+	int space = wrq->length;
+
+	wrq->length = 0;
+	if(pMgmt->wWPAIELen > 0){
+		wrq->length = pMgmt->wWPAIELen;
+		if(pMgmt->wWPAIELen <= space){
+			if(copy_to_user(extra, pMgmt->abyWPAIE, pMgmt->wWPAIELen)){
+				ret = -EFAULT;
+			}
+		}else
+			ret = -E2BIG;
+	}
+
+	return ret;
+}
+
+
+int iwctl_siwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+    PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
+    struct viawget_wpa_param *param=NULL;
+//original member
+    wpa_alg alg_name;
+    u8  addr[6];
+    int key_idx, set_tx=0;
+    u8  seq[IW_ENCODE_SEQ_MAX_SIZE];
+    u8 key[64];
+    size_t seq_len=0,key_len=0;
+//
+   // int ii;
+    u8 *buf;
+    size_t blen;
+    u8 key_array[64];
+    int ret=0;
+
+PRINT_K("SIOCSIWENCODEEXT...... \n");
+
+blen = sizeof(*param);
+buf = kmalloc((int)blen, (int)GFP_KERNEL);
+if (buf == NULL)
+    return -ENOMEM;
+memset(buf, 0, blen);
+param = (struct viawget_wpa_param *) buf;
+
+//recover alg_name
+switch (ext->alg) {
+    case IW_ENCODE_ALG_NONE:
+                  alg_name = WPA_ALG_NONE;
+		break;
+    case IW_ENCODE_ALG_WEP:
+                  alg_name = WPA_ALG_WEP;
+		break;
+    case IW_ENCODE_ALG_TKIP:
+                  alg_name = WPA_ALG_TKIP;
+		break;
+    case IW_ENCODE_ALG_CCMP:
+                  alg_name = WPA_ALG_CCMP;
+		break;
+    default:
+		PRINT_K("Unknown alg = %d\n",ext->alg);
+		ret= -ENOMEM;
+		goto error;
+		}
+//recover addr
+ memcpy(addr, ext->addr.sa_data, ETH_ALEN);
+//recover key_idx
+  key_idx = (wrq->flags&IW_ENCODE_INDEX) - 1;
+//recover set_tx
+if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+   set_tx = 1;
+//recover seq,seq_len
+	if(ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+   seq_len=IW_ENCODE_SEQ_MAX_SIZE;
+   memcpy(seq, ext->rx_seq, seq_len);
+		}
+//recover key,key_len
+if(ext->key_len) {
+  key_len=ext->key_len;
+  memcpy(key, &ext->key[0], key_len);
+	}
+
+memset(key_array, 0, 64);
+if ( key_len > 0) {
+     memcpy(key_array, key, key_len);
+    if (key_len == 32) {
+          // notice ! the oder
+	  memcpy(&key_array[16], &key[24], 8);
+	  memcpy(&key_array[24], &key[16], 8);
+	}
+	}
+
+/**************Translate iw_encode_ext to viawget_wpa_param****************/
+memcpy(param->addr, addr, ETH_ALEN);
+param->u.wpa_key.alg_name = (int)alg_name;
+param->u.wpa_key.set_tx = set_tx;
+param->u.wpa_key.key_index = key_idx;
+param->u.wpa_key.key_len = key_len;
+param->u.wpa_key.key = (u8 *)key_array;
+param->u.wpa_key.seq = (u8 *)seq;
+param->u.wpa_key.seq_len = seq_len;
+
+#if 0
+printk("param->u.wpa_key.alg_name =%d\n",param->u.wpa_key.alg_name);
+printk("param->addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
+	      param->addr[0],param->addr[1],param->addr[2],
+	      param->addr[3],param->addr[4],param->addr[5]);
+printk("param->u.wpa_key.set_tx =%d\n",param->u.wpa_key.set_tx);
+printk("param->u.wpa_key.key_index =%d\n",param->u.wpa_key.key_index);
+printk("param->u.wpa_key.key_len =%d\n",param->u.wpa_key.key_len);
+printk("param->u.wpa_key.key =");
+for(ii=0;ii<param->u.wpa_key.key_len;ii++)
+	printk("%02x:",param->u.wpa_key.key[ii]);
+         printk("\n");
+printk("param->u.wpa_key.seq_len =%d\n",param->u.wpa_key.seq_len);
+printk("param->u.wpa_key.seq =");
+for(ii=0;ii<param->u.wpa_key.seq_len;ii++)
+	printk("%02x:",param->u.wpa_key.seq[ii]);
+         printk("\n");
+
+printk("...........\n");
+#endif
+//****set if current action is Network Manager count??
+//****this method is so foolish,but there is no other way???
+if(param->u.wpa_key.alg_name == WPA_ALG_NONE) {
+   if(param->u.wpa_key.key_index ==0) {
+     pDevice->bwextstep0 = TRUE;
+    }
+   if((pDevice->bwextstep0 = TRUE)&&(param->u.wpa_key.key_index ==1)) {
+     pDevice->bwextstep0 = FALSE;
+     pDevice->bwextstep1 = TRUE;
+    }
+   if((pDevice->bwextstep1 = TRUE)&&(param->u.wpa_key.key_index ==2)) {
+     pDevice->bwextstep1 = FALSE;
+     pDevice->bwextstep2 = TRUE;
+	}
+   if((pDevice->bwextstep2 = TRUE)&&(param->u.wpa_key.key_index ==3)) {
+     pDevice->bwextstep2 = FALSE;
+     pDevice->bwextstep3 = TRUE;
+        }
+		 }
+if(pDevice->bwextstep3 == TRUE) {
+    PRINT_K("SIOCSIWENCODEEXT:Enable WPA WEXT SUPPORT!!!!!\n");
+     pDevice->bwextstep0 = FALSE;
+     pDevice->bwextstep1 = FALSE;
+     pDevice->bwextstep2 = FALSE;
+     pDevice->bwextstep3 = FALSE;
+     pDevice->bWPASuppWextEnabled = TRUE;
+     memset(pMgmt->abyDesireBSSID, 0xFF,6);
+     KeyvInitTable(pDevice,&pDevice->sKey);
+		 }
+//******
+
+		spin_lock_irq(&pDevice->lock);
+ ret = wpa_set_keys(pDevice, param, TRUE);
+		spin_unlock_irq(&pDevice->lock);
+
+error:
+kfree(param);
+	return ret;
+}
+
+
+
+int iwctl_giwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra)
+{
+		return -EOPNOTSUPP;;
+}
+
+int iwctl_siwmlme(struct net_device *dev,
+				struct iw_request_info * info,
+				struct iw_point *wrq,
+				char *extra)
+{
+	PSDevice			pDevice = (PSDevice)netdev_priv(dev);
+	PSMgmtObject	pMgmt = &(pDevice->sMgmtObj);
+	struct iw_mlme *mlme = (struct iw_mlme *)extra;
+	//u16 reason = cpu_to_le16(mlme->reason_code);
+	int ret = 0;
+
+	if(memcmp(pMgmt->abyCurrBSSID, mlme->addr.sa_data, ETH_ALEN)){
+		ret = -EINVAL;
+		return ret;
+	}
+	switch(mlme->cmd){
+	case IW_MLME_DEAUTH:
+		//this command seems to be not complete,please test it --einsnliu
+		//printk("iwctl_siwmlme--->send DEAUTH\n");
+		//bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&reason);
+		//break;
+	case IW_MLME_DISASSOC:
+		if(pDevice->bLinkPass == TRUE){
+		  PRINT_K("iwctl_siwmlme--->send DISASSOCIATE\n");
+		  bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+		}
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+
+}
+
+#endif
+//End Add --//2008-0409-07, <Add> by Einsn Liu
+
+
+
+/*------------------------------------------------------------------*/
+/*
+ * Structures to export the Wireless Handlers
+ */
+
+
+/*
+static const iw_handler		iwctl_handler[] =
+{
+	(iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
+	(iw_handler) iwctl_giwname,     // SIOCGIWNAME
+	(iw_handler) NULL,				// SIOCSIWNWID
+	(iw_handler) NULL,				// SIOCGIWNWID
+	(iw_handler) iwctl_siwfreq,		// SIOCSIWFREQ
+	(iw_handler) iwctl_giwfreq,		// SIOCGIWFREQ
+	(iw_handler) iwctl_siwmode,		// SIOCSIWMODE
+	(iw_handler) iwctl_giwmode,		// SIOCGIWMODE
+	(iw_handler) NULL,		        // SIOCSIWSENS
+	(iw_handler) iwctl_giwsens,		        // SIOCGIWSENS
+	(iw_handler) NULL, 		        // SIOCSIWRANGE
+	(iw_handler) iwctl_giwrange,		// SIOCGIWRANGE
+	(iw_handler) NULL,         		    // SIOCSIWPRIV
+	(iw_handler) NULL,             		// SIOCGIWPRIV
+	(iw_handler) NULL,             		// SIOCSIWSTATS
+	(iw_handler) NULL,                  // SIOCGIWSTATS
+    (iw_handler) NULL,                  // SIOCSIWSPY
+	(iw_handler) NULL,		            // SIOCGIWSPY
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) iwctl_siwap,		    // SIOCSIWAP
+	(iw_handler) iwctl_giwap,		    // SIOCGIWAP
+	(iw_handler) NULL,				    // -- hole -- 0x16
+	(iw_handler) iwctl_giwaplist,       // SIOCGIWAPLIST
+	(iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
+	(iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
+	(iw_handler) iwctl_siwessid,		// SIOCSIWESSID
+	(iw_handler) iwctl_giwessid,		// SIOCGIWESSID
+	(iw_handler) NULL,		// SIOCSIWNICKN
+	(iw_handler) NULL,		// SIOCGIWNICKN
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) iwctl_siwrate,		// SIOCSIWRATE 0x20
+	(iw_handler) iwctl_giwrate,		// SIOCGIWRATE
+	(iw_handler) iwctl_siwrts,		// SIOCSIWRTS
+	(iw_handler) iwctl_giwrts,		// SIOCGIWRTS
+	(iw_handler) iwctl_siwfrag,		// SIOCSIWFRAG
+	(iw_handler) iwctl_giwfrag,		// SIOCGIWFRAG
+	(iw_handler) NULL,		// SIOCSIWTXPOW
+	(iw_handler) NULL,		// SIOCGIWTXPOW
+	(iw_handler) iwctl_siwretry,		// SIOCSIWRETRY
+	(iw_handler) iwctl_giwretry,		// SIOCGIWRETRY
+	(iw_handler) iwctl_siwencode,		// SIOCSIWENCODE
+	(iw_handler) iwctl_giwencode,		// SIOCGIWENCODE
+	(iw_handler) iwctl_siwpower,		// SIOCSIWPOWER
+	(iw_handler) iwctl_giwpower,		// SIOCGIWPOWER
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) iwctl_siwgenie,    // SIOCSIWGENIE
+	(iw_handler) iwctl_giwgenie,    // SIOCGIWGENIE
+	(iw_handler) iwctl_siwauth,		// SIOCSIWAUTH
+	(iw_handler) iwctl_giwauth,		// SIOCGIWAUTH
+	(iw_handler) iwctl_siwencodeext,		// SIOCSIWENCODEEXT
+	(iw_handler) iwctl_giwencodeext,		// SIOCGIWENCODEEXT
+	(iw_handler) NULL,				// SIOCSIWPMKSA
+	(iw_handler) NULL,				// -- hole --
+
+};
+*/
+
+static const iw_handler		iwctl_handler[] =
+{
+	(iw_handler) iwctl_commit,      // SIOCSIWCOMMIT
+	(iw_handler) NULL,      // SIOCGIWNAME
+	(iw_handler) NULL,				// SIOCSIWNWID
+	(iw_handler) NULL,				// SIOCGIWNWID
+	(iw_handler) NULL,		// SIOCSIWFREQ
+	(iw_handler) NULL,		// SIOCGIWFREQ
+	(iw_handler) NULL,		// SIOCSIWMODE
+	(iw_handler) NULL,		// SIOCGIWMODE
+	(iw_handler) NULL,		        // SIOCSIWSENS
+	(iw_handler) NULL,		        // SIOCGIWSENS
+	(iw_handler) NULL, 		        // SIOCSIWRANGE
+	(iw_handler) iwctl_giwrange,		// SIOCGIWRANGE
+	(iw_handler) NULL,         		    // SIOCSIWPRIV
+	(iw_handler) NULL,             		// SIOCGIWPRIV
+	(iw_handler) NULL,             		// SIOCSIWSTATS
+	(iw_handler) NULL,                  // SIOCGIWSTATS
+    (iw_handler) NULL,                  // SIOCSIWSPY
+	(iw_handler) NULL,		            // SIOCGIWSPY
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,				    // -- hole --
+	(iw_handler) NULL,		    // SIOCSIWAP
+	(iw_handler) NULL,		    // SIOCGIWAP
+	(iw_handler) NULL,				    // -- hole -- 0x16
+	(iw_handler) NULL,       // SIOCGIWAPLIST
+	(iw_handler) iwctl_siwscan,         // SIOCSIWSCAN
+	(iw_handler) iwctl_giwscan,         // SIOCGIWSCAN
+	(iw_handler) NULL,		// SIOCSIWESSID
+	(iw_handler) NULL,		// SIOCGIWESSID
+	(iw_handler) NULL,		// SIOCSIWNICKN
+	(iw_handler) NULL,		// SIOCGIWNICKN
+	(iw_handler) NULL,		// -- hole --
+	(iw_handler) NULL,		// -- hole --
+	(iw_handler) NULL,		// SIOCSIWRATE 0x20
+	(iw_handler) NULL,		// SIOCGIWRATE
+	(iw_handler) NULL,		// SIOCSIWRTS
+	(iw_handler) NULL,		// SIOCGIWRTS
+	(iw_handler) NULL,		// SIOCSIWFRAG
+	(iw_handler) NULL,		// SIOCGIWFRAG
+	(iw_handler) NULL,		// SIOCSIWTXPOW
+	(iw_handler) NULL,		// SIOCGIWTXPOW
+	(iw_handler) NULL,		// SIOCSIWRETRY
+	(iw_handler) NULL,		// SIOCGIWRETRY
+	(iw_handler) NULL,		// SIOCSIWENCODE
+	(iw_handler) NULL,		// SIOCGIWENCODE
+	(iw_handler) NULL,		// SIOCSIWPOWER
+	(iw_handler) NULL,		// SIOCGIWPOWER
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) NULL,			// -- hole --
+	(iw_handler) NULL,    // SIOCSIWGENIE
+	(iw_handler) NULL,    // SIOCGIWGENIE
+	(iw_handler) NULL,		// SIOCSIWAUTH
+	(iw_handler) NULL,		// SIOCGIWAUTH
+	(iw_handler) NULL,		// SIOCSIWENCODEEXT
+	(iw_handler) NULL,		// SIOCGIWENCODEEXT
+	(iw_handler) NULL,				// SIOCSIWPMKSA
+	(iw_handler) NULL,				// -- hole --
+};
+
+
+static const iw_handler		iwctl_private_handler[] =
+{
+	NULL,				// SIOCIWFIRSTPRIV
+};
+
+
+struct iw_priv_args iwctl_private_args[] = {
+{ IOCTL_CMD_SET,
+  IW_PRIV_TYPE_CHAR | 1024, 0,
+  "set"},
+};
+
+
+
+const struct iw_handler_def	iwctl_handler_def =
+{
+	.get_wireless_stats = &iwctl_get_wireless_stats,
+	.num_standard	= sizeof(iwctl_handler)/sizeof(iw_handler),
+//	.num_private	= sizeof(iwctl_private_handler)/sizeof(iw_handler),
+//	.num_private_args = sizeof(iwctl_private_args)/sizeof(struct iw_priv_args),
+	.num_private	= 0,
+	.num_private_args = 0,
+	.standard	= (iw_handler *) iwctl_handler,
+//	.private	= (iw_handler *) iwctl_private_handler,
+//	.private_args	= (struct iw_priv_args *)iwctl_private_args,
+	.private	= NULL,
+	.private_args	= NULL,
+};
diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h
new file mode 100644
index 0000000..3096de0
--- /dev/null
+++ b/drivers/staging/vt6656/iwctl.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: iwctl.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 21, 2004
+ *
+ */
+
+#ifndef __IWCTL_H__
+#define __IWCTL_H__
+
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+struct iw_statistics *iwctl_get_wireless_stats (struct net_device *dev);
+
+
+int iwctl_siwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra);
+
+int iwctl_giwrange(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+
+int iwctl_giwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra);
+
+int iwctl_siwmode(struct net_device *dev,
+             struct iw_request_info *info,
+             __u32 *wmode,
+             char *extra);
+
+int iwctl_giwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra);
+
+int iwctl_siwfreq(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_freq *wrq,
+             char *extra);
+
+int iwctl_giwname(struct net_device *dev,
+			 struct iw_request_info *info,
+			 char *wrq,
+			 char *extra);
+
+int iwctl_giwnwid(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+                   char *extra) ;
+
+int iwctl_giwsens(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_param *wrq,
+			 char *extra);
+
+int iwctl_giwap(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct sockaddr *wrq,
+             char *extra);
+
+int iwctl_giwaplist(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_giwessid(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwrate(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwrate(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+
+int iwctl_giwrts(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwfrag(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwretry(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_siwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_giwencode(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwpower(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+int iwctl_giwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwscan(struct net_device *dev,
+             struct iw_request_info *info,
+			 struct iw_param *wrq,
+             char *extra);
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+int iwctl_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra);
+
+int iwctl_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *wrq,
+			  char *extra);
+
+int iwctl_siwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra);
+
+int iwctl_giwgenie(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *wrq,
+			  char *extra);
+
+int iwctl_siwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_giwencodeext(struct net_device *dev,
+             struct iw_request_info *info,
+             struct iw_point *wrq,
+             char *extra);
+
+int iwctl_siwmlme(struct net_device *dev,
+			struct iw_request_info * info,
+			struct iw_point *wrq,
+			char *extra);
+#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//End Add -- //2008-0409-07, <Add> by Einsn Liu
+
+
+extern const struct iw_handler_def	iwctl_handler_def;
+extern const struct iw_priv_args	iwctl_private_args;
+
+#endif // __IWCTL_H__
+
+
+
diff --git a/drivers/staging/vt6656/kcompat.h b/drivers/staging/vt6656/kcompat.h
new file mode 100644
index 0000000..2cf634c
--- /dev/null
+++ b/drivers/staging/vt6656/kcompat.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: kcompat.h
+ *
+ * Purpose: define kernel compatibility header
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Apr 8, 2002
+ *
+ */
+
+#ifndef _KCOMPAT_H
+#define _KCOMPAT_H
+
+#include <linux/version.h>
+
+#ifndef HAVE_NETDEV_PRIV
+#define netdev_priv(dev) (dev->priv)
+#endif
+
+#endif
+
diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c
new file mode 100644
index 0000000..13fc69a
--- /dev/null
+++ b/drivers/staging/vt6656/key.c
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: key.c
+ *
+ * Purpose: Implement functions for 802.11i Key management
+ *
+ * Author: Jerry Chen
+ *
+ * Date: May 29, 2003
+ *
+ * Functions:
+ *      KeyvInitTable - Init Key management table
+ *      KeybGetKey - Get Key from table
+ *      KeybSetKey - Set Key to table
+ *      KeybRemoveKey - Remove Key from table
+ *      KeybGetTransmitKey - Get Transmit Key from table
+ *
+ * Revision History:
+ *
+ */
+
+#include "tmacro.h"
+#include "key.h"
+#include "mac.h"
+#include "rndis.h"
+#include "control.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+static VOID
+s_vCheckKeyTableValid (PVOID pDeviceHandler, PSKeyManagement pTable)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int         i;
+    WORD        wLength = 0;
+    BYTE        pbyData[MAX_KEY_TABLE];
+
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            (pTable->KeyTable[i].PairwiseKey.bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[0].bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[1].bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[2].bKeyValid == FALSE) &&
+            (pTable->KeyTable[i].GroupKey[3].bKeyValid == FALSE)
+            ) {
+
+            pTable->KeyTable[i].bInUse = FALSE;
+            pTable->KeyTable[i].wKeyCtl = 0;
+            pTable->KeyTable[i].bSoftWEP = FALSE;
+            pbyData[wLength++] = (BYTE) i;
+            //MACvDisableKeyEntry(pDevice, i);
+        }
+    }
+    if ( wLength != 0 ) {
+        CONTROLnsRequestOut(pDevice,
+                            MESSAGE_TYPE_CLRKEYENTRY,
+                            0,
+                            0,
+                            wLength,
+                            pbyData
+                            );
+    }
+
+}
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*
+ * Description: Init Key management table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable)
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int i;
+    int jj;
+    BYTE       pbyData[MAX_KEY_TABLE+1];
+
+    spin_lock_irq(&pDevice->lock);
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        pTable->KeyTable[i].bInUse = FALSE;
+        pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+        pTable->KeyTable[i].PairwiseKey.pvKeyTable = (PVOID)&pTable->KeyTable[i];
+        for (jj=0; jj < MAX_GROUP_KEY; jj++) {
+            pTable->KeyTable[i].GroupKey[jj].bKeyValid = FALSE;
+            pTable->KeyTable[i].GroupKey[jj].pvKeyTable = (PVOID) &(pTable->KeyTable[i]);
+        }
+        pTable->KeyTable[i].wKeyCtl = 0;
+        pTable->KeyTable[i].dwGTKeyIndex = 0;
+        pTable->KeyTable[i].bSoftWEP = FALSE;
+        pbyData[i] = (BYTE) i;
+    }
+    pbyData[i] = (BYTE) i;
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_CLRKEYENTRY,
+                        0,
+                        0,
+                        11,
+                        pbyData
+                        );
+
+    spin_unlock_irq(&pDevice->lock);
+
+    return;
+}
+
+
+/*
+ * Description: Get Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *      dwKeyIndex      - Key Index (0xFFFFFFFF means pairwise key)
+ *  Out:
+ *      pKey            - Key return
+ *
+ * Return Value: TRUE if found otherwise FALSE
+ *
+ */
+BOOL KeybGetKey (
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyIndex,
+    OUT PSKeyItem       *pKey
+    )
+{
+    int i;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetKey() \n");
+
+    *pKey = NULL;
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+            if (dwKeyIndex == 0xFFFFFFFF) {
+                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].PairwiseKey);
+                    return (TRUE);
+                }
+                else {
+                    return (FALSE);
+                }
+            } else if (dwKeyIndex < MAX_GROUP_KEY) {
+                if (pTable->KeyTable[i].GroupKey[dwKeyIndex].bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex]);
+                    return (TRUE);
+                }
+                else {
+                    return (FALSE);
+                }
+            }
+            else {
+                return (FALSE);
+            }
+        }
+    }
+    return (FALSE);
+}
+
+
+/*
+ * Description: Set Key to table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *      dwKeyIndex      - Key index (reference to NDIS DDK)
+ *      uKeyLength      - Key length
+ *      KeyRSC          - Key RSC
+ *      pbyKey          - Pointer to key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybSetKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int         i,j;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex);
+
+    j = (MAX_KEY_TABLE-1);
+    for (i=0;i<(MAX_KEY_TABLE-1);i++) {
+        if ((pTable->KeyTable[i].bInUse == FALSE) &&
+            (j == (MAX_KEY_TABLE-1))) {
+            // found empty table
+            j = i;
+        }
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+            // found table already exist
+            if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+                // Pairwise key
+                pKey = &(pTable->KeyTable[i].PairwiseKey);
+                pTable->KeyTable[i].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
+                pTable->KeyTable[i].wKeyCtl |= byKeyDecMode;
+                uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
+            } else {
+                // Group key
+                if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
+                    return (FALSE);
+                pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
+                if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+                    // Group transmit key
+                    pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+                }
+                pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
+                pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
+                pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
+                uKeyIdx = (dwKeyIndex & 0x000000FF);
+            }
+            pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
+
+            pKey->bKeyValid = TRUE;
+            pKey->uKeyLength = uKeyLength;
+            pKey->dwKeyIndex = dwKeyIndex;
+            pKey->byCipherSuite = byKeyDecMode;
+            memcpy(pKey->abyKey, pbyKey, uKeyLength);
+            if (byKeyDecMode == KEY_CTL_WEP) {
+                if (uKeyLength == WLAN_WEP40_KEYLEN)
+                    pKey->abyKey[15] &= 0x7F;
+                if (uKeyLength == WLAN_WEP104_KEYLEN)
+                    pKey->abyKey[15] |= 0x80;
+            }
+            MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey);
+
+            if ((dwKeyIndex & USE_KEYRSC) == 0) {
+                // RSC set by NIC
+		    memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
+            }
+            else {
+                memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+            }
+            pKey->dwTSC47_16 = 0;
+            pKey->wTSC15_0 = 0;
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", pKey->uKeyLength);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            for (ii = 0; ii < pKey->uKeyLength; ii++) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+            }
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+
+            return (TRUE);
+        }
+    }
+    if (j < (MAX_KEY_TABLE-1)) {
+        memcpy(pTable->KeyTable[j].abyBSSID,pbyBSSID,U_ETHER_ADDR_LEN);
+        pTable->KeyTable[j].bInUse = TRUE;
+        if ((dwKeyIndex & PAIRWISE_KEY) != 0)  {
+            // Pairwise key
+            pKey = &(pTable->KeyTable[j].PairwiseKey);
+            pTable->KeyTable[j].wKeyCtl &= 0xFFF0;          // clear pairwise key control filed
+            pTable->KeyTable[j].wKeyCtl |= byKeyDecMode;
+            uKeyIdx = 4;                                    // use HW key entry 4 for pairwise key
+        } else {
+            // Group key
+            if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY)
+                return (FALSE);
+            pKey = &(pTable->KeyTable[j].GroupKey[dwKeyIndex & 0x000000FF]);
+            if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+                // Group transmit key
+                pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j);
+            }
+            pTable->KeyTable[j].wKeyCtl &= 0xFF0F;          // clear group key control filed
+            pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4);
+            pTable->KeyTable[j].wKeyCtl |= 0x0040;          // use group key for group address
+            uKeyIdx = (dwKeyIndex & 0x000000FF);
+        }
+        pTable->KeyTable[j].wKeyCtl |= 0x8000;              // enable on-fly
+
+        pKey->bKeyValid = TRUE;
+        pKey->uKeyLength = uKeyLength;
+        pKey->dwKeyIndex = dwKeyIndex;
+        pKey->byCipherSuite = byKeyDecMode;
+        memcpy(pKey->abyKey, pbyKey, uKeyLength);
+        if (byKeyDecMode == KEY_CTL_WEP) {
+            if (uKeyLength == WLAN_WEP40_KEYLEN)
+                pKey->abyKey[15] &= 0x7F;
+            if (uKeyLength == WLAN_WEP104_KEYLEN)
+                pKey->abyKey[15] |= 0x80;
+        }
+        MACvSetKeyEntry(pDevice, pTable->KeyTable[j].wKeyCtl, j, uKeyIdx, pbyBSSID, (PDWORD)pKey->abyKey);
+
+        if ((dwKeyIndex & USE_KEYRSC) == 0) {
+            // RSC set by NIC
+		memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
+        }
+        else {
+            memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+        }
+        pKey->dwTSC47_16 = 0;
+        pKey->wTSC15_0 = 0;
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(N): \n");
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+        for (ii = 0; ii < pKey->uKeyLength; ii++) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]);
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex);
+
+        return (TRUE);
+    }
+    return (FALSE);
+}
+
+
+/*
+ * Description: Remove Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *      dwKeyIndex      - Key Index (reference to NDIS DDK)
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybRemoveKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int     i;
+    BOOL    bReturnValue = FALSE;
+
+    if (IS_BROADCAST_ADDRESS(pbyBSSID)) {
+        // dealte all key
+        if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+            for (i=0;i<MAX_KEY_TABLE;i++) {
+                pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+            }
+            bReturnValue =  TRUE;
+        }
+        else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+            for (i=0;i<MAX_KEY_TABLE;i++) {
+                pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
+                    // remove Group transmit key
+                    pTable->KeyTable[i].dwGTKeyIndex = 0;
+                }
+            }
+            bReturnValue = TRUE;
+        }
+        else {
+            bReturnValue = FALSE;
+        }
+
+    } else {
+        for (i=0;i<MAX_KEY_TABLE;i++) {
+            if ( (pTable->KeyTable[i].bInUse == TRUE) &&
+                 IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+
+                if ((dwKeyIndex & PAIRWISE_KEY) != 0) {
+                    pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+                    bReturnValue = TRUE;
+                    break;
+                }
+                else if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+                    pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                    if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[i].dwGTKeyIndex & 0x7FFFFFFF)) {
+                        // remove Group transmit key
+                        pTable->KeyTable[i].dwGTKeyIndex = 0;
+                    }
+                    bReturnValue = TRUE;
+                    break;
+                }
+                else {
+                    bReturnValue = FALSE;
+                    break;
+                }
+            } //pTable->KeyTable[i].bInUse == TRUE
+        }  //for
+        bReturnValue = TRUE;
+    }
+
+    s_vCheckKeyTableValid(pDevice,pTable);
+    return bReturnValue;
+
+
+}
+
+
+/*
+ * Description: Remove Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybRemoveAllKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int  i,u;
+
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+            pTable->KeyTable[i].PairwiseKey.bKeyValid = FALSE;
+            for(u=0;u<MAX_GROUP_KEY;u++) {
+                pTable->KeyTable[i].GroupKey[u].bKeyValid = FALSE;
+            }
+            pTable->KeyTable[i].dwGTKeyIndex = 0;
+            s_vCheckKeyTableValid(pDevice, pTable);
+            return (TRUE);
+        }
+    }
+    return (FALSE);
+}
+
+/*
+ * Description: Remove WEP Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+VOID KeyvRemoveWEPKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+   if ((dwKeyIndex & 0x000000FF) < MAX_GROUP_KEY) {
+        if (pTable->KeyTable[MAX_KEY_TABLE-1].bInUse == TRUE) {
+            if (pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].byCipherSuite == KEY_CTL_WEP) {
+                pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF].bKeyValid = FALSE;
+                if ((dwKeyIndex & 0x7FFFFFFF) == (pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex & 0x7FFFFFFF)) {
+                    // remove Group transmit key
+                    pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = 0;
+                }
+            }
+        }
+        s_vCheckKeyTableValid(pDevice, pTable);
+    }
+    return;
+}
+
+VOID KeyvRemoveAllWEPKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+
+    int i;
+
+    for(i=0;i<MAX_GROUP_KEY;i++) {
+        KeyvRemoveWEPKey(pDevice,pTable, i);
+    }
+
+}
+
+/*
+ * Description: Get Transmit Key from table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      pbyBSSID        - BSSID of Key
+ *  Out:
+ *      pKey            - Key return
+ *
+ * Return Value: TRUE if found otherwise FALSE
+ *
+ */
+BOOL KeybGetTransmitKey (
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyType,
+    OUT PSKeyItem       *pKey
+    )
+{
+    int i, ii;
+
+    *pKey = NULL;
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            IS_ETH_ADDRESS_EQUAL(pTable->KeyTable[i].abyBSSID,pbyBSSID)) {
+
+            if (dwKeyType == PAIRWISE_KEY) {
+
+                if (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].PairwiseKey);
+
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PAIRWISE_KEY: KeyTable.abyBSSID: ");
+                    for (ii = 0; ii < 6; ii++) {
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                    }
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+
+                    return (TRUE);
+                }
+                else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"PairwiseKey.bKeyValid == FALSE\n");
+                    return (FALSE);
+                }
+            } // End of Type == PAIRWISE
+            else {
+                if (pTable->KeyTable[i].dwGTKeyIndex == 0) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: dwGTKeyIndex == 0 !!!\n");
+                    return FALSE;
+                }
+                if (pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)].bKeyValid == TRUE) {
+                    *pKey = &(pTable->KeyTable[i].GroupKey[(pTable->KeyTable[i].dwGTKeyIndex&0x000000FF)]);
+
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybGetTransmitKey:");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GROUP_KEY: KeyTable.abyBSSID\n");
+                        for (ii = 0; ii < 6; ii++) {
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]);
+                        }
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex);
+
+                    return (TRUE);
+                }
+                else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GroupKey.bKeyValid == FALSE\n");
+                    return (FALSE);
+                }
+            } // End of Type = GROUP
+        } // BSSID match
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ERROR: NO Match BSSID !!! ");
+    for (ii = 0; ii < 6; ii++) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", *(pbyBSSID+ii));
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+    return (FALSE);
+}
+
+
+/*
+ * Description: Check Pairewise Key
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if found otherwise FALSE
+ *
+ */
+BOOL KeybCheckPairewiseKey (
+    IN  PSKeyManagement pTable,
+    OUT PSKeyItem       *pKey
+    )
+{
+    int i;
+
+    *pKey = NULL;
+    for (i=0;i<MAX_KEY_TABLE;i++) {
+        if ((pTable->KeyTable[i].bInUse == TRUE) &&
+            (pTable->KeyTable[i].PairwiseKey.bKeyValid == TRUE)) {
+            *pKey = &(pTable->KeyTable[i].PairwiseKey);
+            return (TRUE);
+        }
+    }
+    return (FALSE);
+}
+
+/*
+ * Description: Set Key to table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      dwKeyIndex      - Key index (reference to NDIS DDK)
+ *      uKeyLength      - Key length
+ *      KeyRSC          - Key RSC
+ *      pbyKey          - Pointer to key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybSetDefaultKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetDefaultKey: %1x, %d \n", (int)dwKeyIndex, (int)uKeyLength);
+
+
+    if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
+        return (FALSE);
+    } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
+        return (FALSE);
+    }
+
+    pTable->KeyTable[MAX_KEY_TABLE-1].bInUse = TRUE;
+    for(ii=0;ii<U_ETHER_ADDR_LEN;ii++)
+        pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID[ii] = 0xFF;
+
+    // Group key
+    pKey = &(pTable->KeyTable[MAX_KEY_TABLE-1].GroupKey[dwKeyIndex & 0x000000FF]);
+    if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+        // Group transmit key
+        pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1);
+
+    }
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00;          // clear all key control filed
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode << 4);
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= (byKeyDecMode);
+    pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x0044;          // use group key for all address
+    uKeyIdx = (dwKeyIndex & 0x000000FF);
+
+    if ((uKeyLength == WLAN_WEP232_KEYLEN) &&
+        (byKeyDecMode == KEY_CTL_WEP)) {
+        pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0x4000;              // disable on-fly disable address match
+        pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP = TRUE;
+    } else {
+        if (pTable->KeyTable[MAX_KEY_TABLE-1].bSoftWEP == FALSE)
+            pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl |= 0xC000;          // enable on-fly disable address match
+    }
+
+    pKey->bKeyValid = TRUE;
+    pKey->uKeyLength = uKeyLength;
+    pKey->dwKeyIndex = dwKeyIndex;
+    pKey->byCipherSuite = byKeyDecMode;
+    memcpy(pKey->abyKey, pbyKey, uKeyLength);
+    if (byKeyDecMode == KEY_CTL_WEP) {
+        if (uKeyLength == WLAN_WEP40_KEYLEN)
+            pKey->abyKey[15] &= 0x7F;
+        if (uKeyLength == WLAN_WEP104_KEYLEN)
+            pKey->abyKey[15] |= 0x80;
+    }
+
+    MACvSetKeyEntry(pDevice, pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl, MAX_KEY_TABLE-1, uKeyIdx, pTable->KeyTable[MAX_KEY_TABLE-1].abyBSSID, (PDWORD) pKey->abyKey);
+
+    if ((dwKeyIndex & USE_KEYRSC) == 0) {
+        // RSC set by NIC
+	    memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
+    } else {
+        memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+    }
+    pKey->dwTSC47_16 = 0;
+    pKey->wTSC15_0 = 0;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n", pKey->bKeyValid);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n", (int)pKey->uKeyLength);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: \n");
+    for (ii = 0; ii < pKey->uKeyLength; ii++) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x", pKey->abyKey[ii]);
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex);
+
+    return (TRUE);
+}
+
+
+/*
+ * Description: Set Key to table
+ *
+ * Parameters:
+ *  In:
+ *      pTable          - Pointer to Key table
+ *      dwKeyIndex      - Key index (reference to NDIS DDK)
+ *      uKeyLength      - Key length
+ *      KeyRSC          - Key RSC
+ *      pbyKey          - Pointer to key
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success otherwise FALSE
+ *
+ */
+BOOL KeybSetAllGroupKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    )
+{
+    PSDevice    pDevice = (PSDevice) pDeviceHandler;
+    int         i;
+    UINT        ii;
+    PSKeyItem   pKey;
+    UINT        uKeyIdx;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex);
+
+
+    if ((dwKeyIndex & PAIRWISE_KEY) != 0) {                  // Pairwise key
+        return (FALSE);
+    } else if ((dwKeyIndex & 0x000000FF) >= MAX_GROUP_KEY) {
+        return (FALSE);
+    }
+
+    for (i=0; i < MAX_KEY_TABLE-1; i++) {
+        if (pTable->KeyTable[i].bInUse == TRUE) {
+            // found table already exist
+            // Group key
+            pKey = &(pTable->KeyTable[i].GroupKey[dwKeyIndex & 0x000000FF]);
+            if ((dwKeyIndex & TRANSMIT_KEY) != 0)  {
+                // Group transmit key
+                pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i);
+
+            }
+            pTable->KeyTable[i].wKeyCtl &= 0xFF0F;          // clear group key control filed
+            pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4);
+            pTable->KeyTable[i].wKeyCtl |= 0x0040;          // use group key for group address
+            uKeyIdx = (dwKeyIndex & 0x000000FF);
+
+            pTable->KeyTable[i].wKeyCtl |= 0x8000;              // enable on-fly
+
+            pKey->bKeyValid = TRUE;
+            pKey->uKeyLength = uKeyLength;
+            pKey->dwKeyIndex = dwKeyIndex;
+            pKey->byCipherSuite = byKeyDecMode;
+            memcpy(pKey->abyKey, pbyKey, uKeyLength);
+            if (byKeyDecMode == KEY_CTL_WEP) {
+                if (uKeyLength == WLAN_WEP40_KEYLEN)
+                    pKey->abyKey[15] &= 0x7F;
+                if (uKeyLength == WLAN_WEP104_KEYLEN)
+                    pKey->abyKey[15] |= 0x80;
+            }
+
+            MACvSetKeyEntry(pDevice, pTable->KeyTable[i].wKeyCtl, i, uKeyIdx, pTable->KeyTable[i].abyBSSID, (PDWORD) pKey->abyKey);
+
+            if ((dwKeyIndex & USE_KEYRSC) == 0) {
+                // RSC set by NIC
+		    memset(&(pKey->KeyRSC), 0, sizeof(QWORD));
+            }
+            else {
+                memcpy(&(pKey->KeyRSC), pKeyRSC,  sizeof(QWORD));
+            }
+            pKey->dwTSC47_16 = 0;
+            pKey->wTSC15_0 = 0;
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KeybSetKey(R): \n");
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->bKeyValid: %d\n ", pKey->bKeyValid);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->abyKey: ");
+            for (ii = 0; ii < pKey->uKeyLength; ii++) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%02x ", pKey->abyKey[ii]);
+            }
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n");
+
+            //DBG_PRN_GRP12(("pKey->dwTSC47_16: %lX\n ", pKey->dwTSC47_16));
+            //DBG_PRN_GRP12(("pKey->wTSC15_0: %X\n ", pKey->wTSC15_0));
+            //DBG_PRN_GRP12(("pKey->dwKeyIndex: %lX\n ", pKey->dwKeyIndex));
+
+        } // (pTable->KeyTable[i].bInUse == TRUE)
+    }
+    return (TRUE);
+}
diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h
new file mode 100644
index 0000000..b15a64c
--- /dev/null
+++ b/drivers/staging/vt6656/key.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: key.h
+ *
+ * Purpose: Implement functions for 802.11i Key management
+ *
+ * Author: Jerry Chen
+ *
+ * Date: May 29, 2003
+ *
+ */
+
+#ifndef __KEY_H__
+#define __KEY_H__
+
+#include "ttype.h"
+#include "tether.h"
+#include "80211mgr.h"
+
+/*---------------------  Export Definitions -------------------------*/
+#define MAX_GROUP_KEY       4
+#define MAX_KEY_TABLE       11
+#define MAX_KEY_LEN         32
+#define AES_KEY_LEN         16
+
+
+#define AUTHENTICATOR_KEY   0x10000000
+#define USE_KEYRSC          0x20000000
+#define PAIRWISE_KEY        0x40000000
+#define TRANSMIT_KEY        0x80000000
+
+#define GROUP_KEY           0x00000000
+
+#define KEY_CTL_WEP         0x00
+#define KEY_CTL_NONE        0x01
+#define KEY_CTL_TKIP        0x02
+#define KEY_CTL_CCMP        0x03
+#define KEY_CTL_INVALID     0xFF
+
+
+typedef struct tagSKeyItem
+{
+    BOOL        bKeyValid;
+    ULONG       uKeyLength;
+    BYTE        abyKey[MAX_KEY_LEN];
+    QWORD       KeyRSC;
+    DWORD       dwTSC47_16;
+    WORD        wTSC15_0;
+    BYTE        byCipherSuite;
+    BYTE        byReserved0;
+    DWORD       dwKeyIndex;
+    PVOID       pvKeyTable;
+} SKeyItem, *PSKeyItem; //64
+
+typedef struct tagSKeyTable
+{
+    BYTE        abyBSSID[U_ETHER_ADDR_LEN];  //6
+    BYTE        byReserved0[2];              //8
+    SKeyItem    PairwiseKey;
+    SKeyItem    GroupKey[MAX_GROUP_KEY]; //64*5 = 320, 320+8=328
+    DWORD       dwGTKeyIndex;            // GroupTransmitKey Index
+    BOOL        bInUse;
+    WORD        wKeyCtl;
+    BOOL        bSoftWEP;
+    BYTE        byReserved1[6];
+} SKeyTable, *PSKeyTable; //352
+
+typedef struct tagSKeyManagement
+{
+    SKeyTable   KeyTable[MAX_KEY_TABLE];
+} SKeyManagement, *PSKeyManagement;
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+VOID KeyvInitTable(PVOID pDeviceHandler, PSKeyManagement pTable);
+
+BOOL KeybGetKey(
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyIndex,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybSetKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    );
+
+BOOL KeybRemoveKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID,
+    DWORD           dwKeyIndex
+    );
+
+BOOL KeybRemoveAllKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    PBYTE           pbyBSSID
+    );
+
+VOID KeyvRemoveWEPKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex
+    );
+
+VOID KeyvRemoveAllWEPKey(
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable
+    );
+
+BOOL KeybGetTransmitKey(
+    IN  PSKeyManagement pTable,
+    IN  PBYTE           pbyBSSID,
+    IN  DWORD           dwKeyType,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybCheckPairewiseKey(
+    IN  PSKeyManagement pTable,
+    OUT PSKeyItem       *pKey
+    );
+
+BOOL KeybSetDefaultKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    );
+
+BOOL KeybSetAllGroupKey (
+    PVOID           pDeviceHandler,
+    PSKeyManagement pTable,
+    DWORD           dwKeyIndex,
+    ULONG           uKeyLength,
+    PQWORD          pKeyRSC,
+    PBYTE           pbyKey,
+    BYTE            byKeyDecMode
+    );
+
+#endif // __KEY_H__
+
diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c
new file mode 100644
index 0000000..55a7986
--- /dev/null
+++ b/drivers/staging/vt6656/mac.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: mac.c
+ *
+ * Purpose:  MAC routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *
+ * Revision History:
+ */
+
+#include "tmacro.h"
+#include "tether.h"
+#include "desc.h"
+#include "mac.h"
+#include "80211hdr.h"
+#include "rndis.h"
+#include "control.h"
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+
+/*
+ * Description:
+ *      Set this hash index into multicast address register bit
+ *
+ * Parameters:
+ *  In:
+ *      byHashIdx   - Hash index to set
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx)
+{
+    UINT            uByteIdx;
+    BYTE            byBitMask;
+    BYTE            pbyData[2];
+
+
+    // calculate byte position
+    uByteIdx = byHashIdx / 8;
+
+    // calculate bit position
+    byBitMask = 1;
+    byBitMask <<= (byHashIdx % 8);
+    // turn on the bit
+
+    pbyData[0] = byBitMask;
+    pbyData[1] = byBitMask;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        (WORD) (MAC_REG_MAR0 + uByteIdx),
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData);
+}
+
+
+
+/*
+ * Description:
+ *      Write MAC Multicast Address Mask
+ *
+ * Parameters:
+ *  In:
+ *      uByteidx    - Index of Mask
+ *      byData      - Mask Value to write
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+VOID MACvWriteMultiAddr (PSDevice pDevice, UINT uByteIdx, BYTE byData)
+{
+    BYTE            byData1;
+
+    byData1 = byData;
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        (WORD) (MAC_REG_MAR0 + uByteIdx),
+                        MESSAGE_REQUEST_MACREG,
+                        1,
+                        &byData1);
+}
+
+
+/*
+ * Description:
+ *      Shut Down MAC
+ *
+ * Parameters:
+ *  In:
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+BOOL MACbShutdown (PSDevice pDevice)
+{
+    CONTROLnsRequestOutAsyn(pDevice,
+                        MESSAGE_TYPE_MACSHUTDOWN,
+                        0,
+                        0,
+                        0,
+                        NULL
+                        );
+    return TRUE;
+}
+
+void MACvSetBBType(PSDevice pDevice,BYTE byType)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = byType;
+    pbyData[1] = EnCFG_BBType_MASK;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG0,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData)
+{
+BYTE    pbyData[4];
+
+    if (wOffset > 273)
+        return;
+    pbyData[0] = (BYTE)dwData;
+    pbyData[1] = (BYTE)(dwData>>8);
+    pbyData[2] = (BYTE)(dwData>>16);
+    pbyData[3] = (BYTE)(dwData>>24);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MISCFF,
+                        wOffset,
+                        0,
+                        4,
+                        pbyData
+                        );
+}
+
+/*
+ * Description:
+ *      Disable the Key Entry by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvDisableKeyEntry (PSDevice pDevice, UINT uEntryIdx)
+{
+WORD    wOffset;
+BYTE            byData;
+
+
+    byData = (BYTE) uEntryIdx;
+
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, 0);
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+    //issue write misc fifo command to device
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_CLRKEYENTRY,
+                        0,
+                        0,
+                        1,
+                        &byData
+                        );
+}
+
+
+/*
+ * Description:
+ *      Set the Key by MISCFIFO
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase        - Base Address for MAC
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void MACvSetKeyEntry (PSDevice pDevice, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey)
+{
+PBYTE           pbyKey;
+WORD            wOffset;
+DWORD           dwData1,dwData2;
+int             ii;
+BYTE            pbyData[24];
+
+
+
+
+
+    if ( pDevice->byLocalID <= MAC_REVISION_A1 ) {
+        if ( pDevice->sMgmtObj.byCSSPK == KEY_CTL_CCMP )
+            return;
+    }
+
+    wOffset = MISCFIFO_KEYETRY0;
+    wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE);
+
+    dwData1 = 0;
+    dwData1 |= wKeyCtl;
+    dwData1 <<= 16;
+    dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5));
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData1, wKeyCtl);
+
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+    //wOffset++;
+
+    dwData2 = 0;
+    dwData2 |= *(pbyAddr+3);
+    dwData2 <<= 8;
+    dwData2 |= *(pbyAddr+2);
+    dwData2 <<= 8;
+    dwData2 |= *(pbyAddr+1);
+    dwData2 <<= 8;
+    dwData2 |= *(pbyAddr+0);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData2);
+
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset);
+    //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData);
+    //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+
+    //wOffset++;
+
+    //wOffset += (uKeyIdx * 4);
+/*    for (ii=0;ii<4;ii++) {
+        // alway push 128 bits
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"3.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey);
+        VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii);
+        VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++);
+        VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE);
+    }
+*/
+    pbyKey = (PBYTE)pdwKey;
+
+    pbyData[0] = (BYTE)dwData1;
+    pbyData[1] = (BYTE)(dwData1>>8);
+    pbyData[2] = (BYTE)(dwData1>>16);
+    pbyData[3] = (BYTE)(dwData1>>24);
+    pbyData[4] = (BYTE)dwData2;
+    pbyData[5] = (BYTE)(dwData2>>8);
+    pbyData[6] = (BYTE)(dwData2>>16);
+    pbyData[7] = (BYTE)(dwData2>>24);
+    for(ii=8;ii<24;ii++)
+        pbyData[ii] = *pbyKey++;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_SETKEY,
+                        wOffset,
+                        (WORD)uKeyIdx,
+                        24,
+                        pbyData
+                        );
+
+
+}
+
+
+void MACvRegBitsOff(PSDevice pDevice, BYTE byRegOfs, BYTE byBits)
+{
+BYTE            pbyData[2];
+
+    pbyData[0] = 0;
+    pbyData[1] = byBits;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        byRegOfs,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+
+void MACvRegBitsOn(PSDevice pDevice, BYTE byRegOfs, BYTE byBits)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = byBits;
+    pbyData[1] = byBits;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        byRegOfs,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvWriteWord(PSDevice pDevice, BYTE byRegOfs, WORD wData)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = (BYTE)(wData & 0xff);
+    pbyData[1] = (BYTE)(wData >> 8);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        byRegOfs,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+
+}
+
+void MACvWriteBSSIDAddress(PSDevice pDevice, PBYTE pbyEtherAddr)
+{
+BYTE            pbyData[6];
+
+
+    pbyData[0] = *((PBYTE)pbyEtherAddr);
+    pbyData[1] = *((PBYTE)pbyEtherAddr+1);
+    pbyData[2] = *((PBYTE)pbyEtherAddr+2);
+    pbyData[3] = *((PBYTE)pbyEtherAddr+3);
+    pbyData[4] = *((PBYTE)pbyEtherAddr+4);
+    pbyData[5] = *((PBYTE)pbyEtherAddr+5);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_BSSID0,
+                        MESSAGE_REQUEST_MACREG,
+                        6,
+                        pbyData
+                        );
+}
+
+void MACvEnableProtectMD(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = EnCFG_ProtectMd;
+    pbyData[1] = EnCFG_ProtectMd;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG0,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvDisableProtectMD(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = 0;
+    pbyData[1] = EnCFG_ProtectMd;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG0,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvEnableBarkerPreambleMd(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = EnCFG_BarkerPream;
+    pbyData[1] = EnCFG_BarkerPream;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG2,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+void MACvDisableBarkerPreambleMd(PSDevice pDevice)
+{
+BYTE            pbyData[2];
+
+
+    pbyData[0] = 0;
+    pbyData[1] = EnCFG_BarkerPream;
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE_MASK,
+                        MAC_REG_ENCFG2,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
+
+
+void MACvWriteBeaconInterval(PSDevice pDevice, WORD wInterval)
+{
+BYTE            pbyData[2];
+
+    pbyData[0] = (BYTE) (wInterval & 0xff);
+    pbyData[1] = (BYTE) (wInterval >> 8);
+
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        MAC_REG_BI,
+                        MESSAGE_REQUEST_MACREG,
+                        2,
+                        pbyData
+                        );
+}
diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h
new file mode 100644
index 0000000..fe99e3d
--- /dev/null
+++ b/drivers/staging/vt6656/mac.h
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: mac.h
+ *
+ * Purpose: MAC routines
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Revision History:
+ *      07-01-2003 Bryan YC Fan:  Re-write codes to support VT3253 spec.
+ *      08-25-2003 Kyle Hsu:      Porting MAC functions from sim53.
+ *      09-03-2003 Bryan YC Fan:  Add MACvDisableProtectMD & MACvEnableProtectMD
+ */
+
+#ifndef __MAC_H__
+#define __MAC_H__
+
+#include "ttype.h"
+#include "device.h"
+#include "tmacro.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define REV_ID_VT3253_A0    0x00
+#define REV_ID_VT3253_A1    0x01
+#define REV_ID_VT3253_B0    0x08
+#define REV_ID_VT3253_B1    0x09
+
+//
+// Registers in the MAC
+//
+#define MAC_REG_BISTCMD     0x04
+#define MAC_REG_BISTSR0     0x05
+#define MAC_REG_BISTSR1     0x06
+#define MAC_REG_BISTSR2     0x07
+#define MAC_REG_I2MCSR      0x08
+#define MAC_REG_I2MTGID     0x09
+#define MAC_REG_I2MTGAD     0x0A
+#define MAC_REG_I2MCFG      0x0B
+#define MAC_REG_I2MDIPT     0x0C
+#define MAC_REG_I2MDOPT     0x0E
+#define MAC_REG_USBSUS      0x0F
+
+#define MAC_REG_LOCALID     0x14
+#define MAC_REG_TESTCFG     0x15
+#define MAC_REG_JUMPER0     0x16
+#define MAC_REG_JUMPER1     0x17
+#define MAC_REG_TMCTL       0x18
+#define MAC_REG_TMDATA0     0x1C
+#define MAC_REG_TMDATA1     0x1D
+#define MAC_REG_TMDATA2     0x1E
+#define MAC_REG_TMDATA3     0x1F
+
+// MAC Parameter related
+#define MAC_REG_LRT         0x20        //
+#define MAC_REG_SRT         0x21        //
+#define MAC_REG_SIFS        0x22        //
+#define MAC_REG_DIFS        0x23        //
+#define MAC_REG_EIFS        0x24        //
+#define MAC_REG_SLOT        0x25        //
+#define MAC_REG_BI          0x26        //
+#define MAC_REG_CWMAXMIN0   0x28        //
+#define MAC_REG_LINKOFFTOTM 0x2A
+#define MAC_REG_SWTMOT      0x2B
+#define MAC_REG_RTSOKCNT    0x2C
+#define MAC_REG_RTSFAILCNT  0x2D
+#define MAC_REG_ACKFAILCNT  0x2E
+#define MAC_REG_FCSERRCNT   0x2F
+// TSF Related
+#define MAC_REG_TSFCNTR     0x30        //
+#define MAC_REG_NEXTTBTT    0x38        //
+#define MAC_REG_TSFOFST     0x40        //
+#define MAC_REG_TFTCTL      0x48        //
+// WMAC Control/Status Related
+#define MAC_REG_ENCFG0      0x4C        //
+#define MAC_REG_ENCFG1      0x4D        //
+#define MAC_REG_ENCFG2      0x4E        //
+
+#define MAC_REG_CFG         0x50        //
+#define MAC_REG_TEST        0x52        //
+#define MAC_REG_HOSTCR      0x54        //
+#define MAC_REG_MACCR       0x55        //
+#define MAC_REG_RCR         0x56        //
+#define MAC_REG_TCR         0x57        //
+#define MAC_REG_IMR         0x58        //
+#define MAC_REG_ISR         0x5C
+#define MAC_REG_ISR1        0x5D
+// Power Saving Related
+#define MAC_REG_PSCFG       0x60        //
+#define MAC_REG_PSCTL       0x61        //
+#define MAC_REG_PSPWRSIG    0x62        //
+#define MAC_REG_BBCR13      0x63
+#define MAC_REG_AIDATIM     0x64
+#define MAC_REG_PWBT        0x66
+#define MAC_REG_WAKEOKTMR   0x68
+#define MAC_REG_CALTMR      0x69
+#define MAC_REG_SYNSPACCNT  0x6A
+#define MAC_REG_WAKSYNOPT   0x6B
+// Baseband/IF Control Group
+#define MAC_REG_BBREGCTL    0x6C        //
+#define MAC_REG_CHANNEL     0x6D
+#define MAC_REG_BBREGADR    0x6E
+#define MAC_REG_BBREGDATA   0x6F
+#define MAC_REG_IFREGCTL    0x70        //
+#define MAC_REG_IFDATA      0x71        //
+#define MAC_REG_ITRTMSET    0x74        //
+#define MAC_REG_PAPEDELAY   0x77
+#define MAC_REG_SOFTPWRCTL  0x78        //
+#define MAC_REG_SOFTPWRCTL2 0x79        //
+#define MAC_REG_GPIOCTL0    0x7A        //
+#define MAC_REG_GPIOCTL1    0x7B        //
+
+// MiscFF PIO related
+#define MAC_REG_MISCFFNDEX  0xBC
+#define MAC_REG_MISCFFCTL   0xBE
+#define MAC_REG_MISCFFDATA  0xC0
+
+// MAC Configuration Group
+#define MAC_REG_PAR0        0xC4
+#define MAC_REG_PAR4        0xC8
+#define MAC_REG_BSSID0      0xCC
+#define MAC_REG_BSSID4      0xD0
+#define MAC_REG_MAR0        0xD4
+#define MAC_REG_MAR4        0xD8
+// MAC RSPPKT INFO Group
+#define MAC_REG_RSPINF_B_1  0xDC
+#define MAC_REG_RSPINF_B_2  0xE0
+#define MAC_REG_RSPINF_B_5  0xE4
+#define MAC_REG_RSPINF_B_11 0xE8
+#define MAC_REG_RSPINF_A_6  0xEC
+#define MAC_REG_RSPINF_A_9  0xEE
+#define MAC_REG_RSPINF_A_12 0xF0
+#define MAC_REG_RSPINF_A_18 0xF2
+#define MAC_REG_RSPINF_A_24 0xF4
+#define MAC_REG_RSPINF_A_36 0xF6
+#define MAC_REG_RSPINF_A_48 0xF8
+#define MAC_REG_RSPINF_A_54 0xFA
+#define MAC_REG_RSPINF_A_72 0xFC
+
+
+//
+// Bits in the I2MCFG EEPROM register
+//
+#define I2MCFG_BOUNDCTL     0x80
+#define I2MCFG_WAITCTL      0x20
+#define I2MCFG_SCLOECTL     0x10
+#define I2MCFG_WBUSYCTL     0x08
+#define I2MCFG_NORETRY      0x04
+#define I2MCFG_I2MLDSEQ     0x02
+#define I2MCFG_I2CMFAST     0x01
+
+//
+// Bits in the I2MCSR EEPROM register
+//
+#define I2MCSR_EEMW         0x80
+#define I2MCSR_EEMR         0x40
+#define I2MCSR_AUTOLD       0x08
+#define I2MCSR_NACK         0x02
+#define I2MCSR_DONE         0x01
+
+//
+// Bits in the TMCTL register
+//
+#define TMCTL_TSUSP         0x04
+#define TMCTL_TMD           0x02
+#define TMCTL_TE            0x01
+
+//
+// Bits in the TFTCTL register
+//
+#define TFTCTL_HWUTSF       0x80        //
+#define TFTCTL_TBTTSYNC     0x40
+#define TFTCTL_HWUTSFEN     0x20
+#define TFTCTL_TSFCNTRRD    0x10        //
+#define TFTCTL_TBTTSYNCEN   0x08        //
+#define TFTCTL_TSFSYNCEN    0x04        //
+#define TFTCTL_TSFCNTRST    0x02        //
+#define TFTCTL_TSFCNTREN    0x01        //
+
+//
+// Bits in the EnhanceCFG_0 register
+//
+#define EnCFG_BBType_a      0x00
+#define EnCFG_BBType_b      0x01
+#define EnCFG_BBType_g      0x02
+#define EnCFG_BBType_MASK   0x03
+#define EnCFG_ProtectMd     0x20
+
+//
+// Bits in the EnhanceCFG_1 register
+//
+#define EnCFG_BcnSusInd     0x01
+#define EnCFG_BcnSusClr     0x02
+
+//
+// Bits in the EnhanceCFG_2 register
+//
+#define EnCFG_NXTBTTCFPSTR  0x01
+#define EnCFG_BarkerPream   0x02
+#define EnCFG_PktBurstMode  0x04
+
+//
+// Bits in the CFG register
+//
+#define CFG_TKIPOPT         0x80
+#define CFG_RXDMAOPT        0x40
+#define CFG_TMOT_SW         0x20
+#define CFG_TMOT_HWLONG     0x10
+#define CFG_TMOT_HW         0x00
+#define CFG_CFPENDOPT       0x08
+#define CFG_BCNSUSEN        0x04
+#define CFG_NOTXTIMEOUT     0x02
+#define CFG_NOBUFOPT        0x01
+
+//
+// Bits in the TEST register
+//
+#define TEST_LBEXT          0x80        //
+#define TEST_LBINT          0x40        //
+#define TEST_LBNONE         0x00        //
+#define TEST_SOFTINT        0x20        //
+#define TEST_CONTTX         0x10        //
+#define TEST_TXPE           0x08        //
+#define TEST_NAVDIS         0x04        //
+#define TEST_NOCTS          0x02        //
+#define TEST_NOACK          0x01        //
+
+//
+// Bits in the HOSTCR register
+//
+#define HOSTCR_TXONST       0x80        //
+#define HOSTCR_RXONST       0x40        //
+#define HOSTCR_ADHOC        0x20        // Network Type 1 = Ad-hoc
+#define HOSTCR_AP           0x10        // Port Type 1 = AP
+#define HOSTCR_TXON         0x08        //0000 1000
+#define HOSTCR_RXON         0x04        //0000 0100
+#define HOSTCR_MACEN        0x02        //0000 0010
+#define HOSTCR_SOFTRST      0x01        //0000 0001
+
+//
+// Bits in the MACCR register
+//
+#define MACCR_SYNCFLUSHOK   0x04        //
+#define MACCR_SYNCFLUSH     0x02        //
+#define MACCR_CLRNAV        0x01        //
+
+//
+// Bits in the RCR register
+//
+#define RCR_SSID            0x80
+#define RCR_RXALLTYPE       0x40        //
+#define RCR_UNICAST         0x20        //
+#define RCR_BROADCAST       0x10        //
+#define RCR_MULTICAST       0x08        //
+#define RCR_WPAERR          0x04        //
+#define RCR_ERRCRC          0x02        //
+#define RCR_BSSID           0x01        //
+
+//
+// Bits in the TCR register
+//
+#define TCR_SYNCDCFOPT      0x02        //
+#define TCR_AUTOBCNTX       0x01        // Beacon automatically transmit enable
+
+
+//ISR1
+#define ISR_GPIO3           0x40
+#define ISR_RXNOBUF         0x08
+#define ISR_MIBNEARFULL     0x04
+#define ISR_SOFTINT         0x02
+#define ISR_FETALERR        0x01
+
+#define LEDSTS_STS          0x06
+#define LEDSTS_TMLEN        0x78
+#define LEDSTS_OFF          0x00
+#define LEDSTS_ON           0x02
+#define LEDSTS_SLOW         0x04
+#define LEDSTS_INTER        0x06
+
+//ISR0
+#define ISR_WATCHDOG        0x80
+#define ISR_SOFTTIMER       0x40
+#define ISR_GPIO0           0x20
+#define ISR_TBTT            0x10
+#define ISR_RXDMA0          0x08
+#define ISR_BNTX            0x04
+#define ISR_ACTX            0x01
+
+//
+// Bits in the PSCFG register
+//
+#define PSCFG_PHILIPMD      0x40        //
+#define PSCFG_WAKECALEN     0x20        //
+#define PSCFG_WAKETMREN     0x10        //
+#define PSCFG_BBPSPROG      0x08        //
+#define PSCFG_WAKESYN       0x04        //
+#define PSCFG_SLEEPSYN      0x02        //
+#define PSCFG_AUTOSLEEP     0x01        //
+
+//
+// Bits in the PSCTL register
+//
+#define PSCTL_WAKEDONE      0x20        //
+#define PSCTL_PS            0x10        //
+#define PSCTL_GO2DOZE       0x08        //
+#define PSCTL_LNBCN         0x04        //
+#define PSCTL_ALBCN         0x02        //
+#define PSCTL_PSEN          0x01        //
+
+//
+// Bits in the PSPWSIG register
+//
+#define PSSIG_WPE3          0x80        //
+#define PSSIG_WPE2          0x40        //
+#define PSSIG_WPE1          0x20        //
+#define PSSIG_WRADIOPE      0x10        //
+#define PSSIG_SPE3          0x08        //
+#define PSSIG_SPE2          0x04        //
+#define PSSIG_SPE1          0x02        //
+#define PSSIG_SRADIOPE      0x01        //
+
+//
+// Bits in the BBREGCTL register
+//
+#define BBREGCTL_DONE       0x04        //
+#define BBREGCTL_REGR       0x02        //
+#define BBREGCTL_REGW       0x01        //
+
+//
+// Bits in the IFREGCTL register
+//
+#define IFREGCTL_DONE       0x04        //
+#define IFREGCTL_IFRF       0x02        //
+#define IFREGCTL_REGW       0x01        //
+
+//
+// Bits in the SOFTPWRCTL register
+//
+#define SOFTPWRCTL_RFLEOPT      0x08  //
+#define SOFTPWRCTL_TXPEINV      0x02  //
+#define SOFTPWRCTL_SWPECTI      0x01  //
+#define SOFTPWRCTL_SWPAPE       0x20  //
+#define SOFTPWRCTL_SWCALEN      0x10  //
+#define SOFTPWRCTL_SWRADIO_PE   0x08  //
+#define SOFTPWRCTL_SWPE2        0x04  //
+#define SOFTPWRCTL_SWPE1        0x02  //
+#define SOFTPWRCTL_SWPE3        0x01  //
+
+//
+// Bits in the GPIOCTL1 register
+//
+#define GPIO3_MD                0x20    //
+#define GPIO3_DATA              0x40    //
+#define GPIO3_INTMD             0x80    //
+
+//
+// Bits in the MISCFFCTL register
+//
+#define MISCFFCTL_WRITE     0x0001      //
+
+
+// Loopback mode
+#define MAC_LB_EXT          0x02        //
+#define MAC_LB_INTERNAL     0x01        //
+#define MAC_LB_NONE         0x00        //
+
+// Ethernet address filter type
+#define PKT_TYPE_NONE           0x00    // turn off receiver
+#define PKT_TYPE_ALL_MULTICAST  0x80
+#define PKT_TYPE_PROMISCUOUS    0x40
+#define PKT_TYPE_DIRECTED       0x20    // obselete, directed address is always accepted
+#define PKT_TYPE_BROADCAST      0x10
+#define PKT_TYPE_MULTICAST      0x08
+#define PKT_TYPE_ERROR_WPA      0x04
+#define PKT_TYPE_ERROR_CRC      0x02
+#define PKT_TYPE_BSSID          0x01
+
+#define Default_BI              0x200
+
+// MiscFIFO Offset
+#define MISCFIFO_KEYETRY0       32
+#define MISCFIFO_KEYENTRYSIZE   22
+
+// max time out delay time
+#define W_MAX_TIMEOUT       0xFFF0U     //
+
+// wait time within loop
+#define CB_DELAY_LOOP_WAIT  10          // 10ms
+
+#define MAC_REVISION_A0     0x00
+#define MAC_REVISION_A1     0x01
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+void MACvSetMultiAddrByHash (PSDevice pDevice, BYTE byHashIdx);
+VOID MACvWriteMultiAddr (PSDevice pDevice, UINT uByteIdx, BYTE byData);
+BOOL MACbShutdown(PSDevice pDevice);;
+void MACvSetBBType(PSDevice pDevice,BYTE byType);
+void MACvSetMISCFifo (PSDevice pDevice, WORD wOffset, DWORD dwData);
+void MACvDisableKeyEntry(PSDevice pDevice, UINT uEntryIdx);
+void MACvSetKeyEntry(PSDevice pDevice, WORD wKeyCtl, UINT uEntryIdx, UINT uKeyIdx, PBYTE pbyAddr, PDWORD pdwKey);
+
+void MACvRegBitsOff(PSDevice pDevice, BYTE byRegOfs, BYTE byBits);
+void MACvRegBitsOn(PSDevice pDevice, BYTE byRegOfs, BYTE byBits);
+void MACvWriteWord(PSDevice pDevice, BYTE byRegOfs, WORD wData);
+
+void MACvWriteBSSIDAddress(PSDevice pDevice, PBYTE pbyEtherAddr);
+void MACvEnableProtectMD(PSDevice pDevice);
+void MACvDisableProtectMD(PSDevice pDevice);
+void MACvEnableBarkerPreambleMd(PSDevice pDevice);
+void MACvDisableBarkerPreambleMd(PSDevice pDevice);
+void MACvWriteBeaconInterval(PSDevice pDevice, WORD wInterval);
+
+#endif // __MAC_H__
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c
new file mode 100644
index 0000000..7f96bca
--- /dev/null
+++ b/drivers/staging/vt6656/main_usb.c
@@ -0,0 +1,2196 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: main_usb.c
+ *
+ * Purpose: driver entry for initial, open, close, tx and rx.
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: Dec 8, 2005
+ *
+ * Functions:
+ *
+ *   vntwusb_found1 - module initial (insmod) driver entry
+ *   device_remove1 - module remove entry
+ *   device_open - allocate dma/descripter resource & initial mac/bbp function
+ *   device_xmit - asynchrous data tx function
+ *   device_set_multi - set mac filter
+ *   device_ioctl - ioctl entry
+ *   device_close - shutdown mac/bbp & free dma/descripter resource
+ *   device_alloc_frag_buf - rx fragement pre-allocated function
+ *   device_free_tx_bufs - free tx buffer function
+ *   device_dma0_tx_80211- tx 802.11 frame via dma0
+ *   device_dma0_xmit- tx PS bufferred frame via dma0
+ *   device_init_registers- initial MAC & BBP & RF internal registers.
+ *   device_init_rings- initial tx/rx ring buffer
+ *   device_init_defrag_cb- initial & allocate de-fragement buffer.
+ *   device_tx_srv- tx interrupt service function
+ *
+ * Revision History:
+ */
+#undef __NO_VERSION__
+
+#include "device.h"
+#include "card.h"
+#include "baseband.h"
+#include "mac.h"
+#include "tether.h"
+#include "wmgr.h"
+#include "wctl.h"
+#include "power.h"
+#include "wcmd.h"
+#include "iocmd.h"
+#include "tcrc.h"
+#include "rxtx.h"
+#include "bssdb.h"
+#include "hostap.h"
+#include "wpactl.h"
+#include "ioctl.h"
+#include "iwctl.h"
+#include "dpc.h"
+#include "iocmd.h"
+#include "datarate.h"
+#include "rf.h"
+#include "firmware.h"
+#include "mac.h"
+#include "rndis.h"
+#include "control.h"
+#include "channel.h"
+#include "int.h"
+#include "iowpa.h"
+
+/*---------------------  Static Definitions -------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+//
+// Define module options
+//
+
+// Version Information
+#define DRIVER_AUTHOR "VIA Networking Technologies, Inc., <lyndonchen@vntek.com.tw>"
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DEVICE_FULL_DRV_NAM);
+
+#define DEVICE_PARAM(N,D) \
+        static int N[MAX_UINTS]=OPTION_DEFAULT;\
+        module_param_array(N, int, NULL, 0);\
+        MODULE_PARM_DESC(N, D);
+
+#define RX_DESC_MIN0     16
+#define RX_DESC_MAX0     128
+#define RX_DESC_DEF0     64
+DEVICE_PARAM(RxDescriptors0,"Number of receive usb desc buffer");
+
+
+#define TX_DESC_MIN0     16
+#define TX_DESC_MAX0     128
+#define TX_DESC_DEF0     64
+DEVICE_PARAM(TxDescriptors0,"Number of transmit usb desc buffer");
+
+
+#define CHANNEL_MIN     1
+#define CHANNEL_MAX     14
+#define CHANNEL_DEF     6
+
+DEVICE_PARAM(Channel, "Channel number");
+
+
+/* PreambleType[] is the preamble length used for transmit.
+   0: indicate allows long preamble type
+   1: indicate allows short preamble type
+*/
+
+#define PREAMBLE_TYPE_DEF     1
+
+DEVICE_PARAM(PreambleType, "Preamble Type");
+
+
+#define RTS_THRESH_MIN     512
+#define RTS_THRESH_MAX     2347
+#define RTS_THRESH_DEF     2347
+
+DEVICE_PARAM(RTSThreshold, "RTS threshold");
+
+
+#define FRAG_THRESH_MIN     256
+#define FRAG_THRESH_MAX     2346
+#define FRAG_THRESH_DEF     2346
+
+DEVICE_PARAM(FragThreshold, "Fragmentation threshold");
+
+
+#define DATA_RATE_MIN     0
+#define DATA_RATE_MAX     13
+#define DATA_RATE_DEF     13
+/* datarate[] index
+   0: indicate 1 Mbps   0x02
+   1: indicate 2 Mbps   0x04
+   2: indicate 5.5 Mbps 0x0B
+   3: indicate 11 Mbps  0x16
+   4: indicate 6 Mbps   0x0c
+   5: indicate 9 Mbps   0x12
+   6: indicate 12 Mbps  0x18
+   7: indicate 18 Mbps  0x24
+   8: indicate 24 Mbps  0x30
+   9: indicate 36 Mbps  0x48
+  10: indicate 48 Mbps  0x60
+  11: indicate 54 Mbps  0x6c
+  12: indicate 72 Mbps  0x90
+  13: indicate auto rate
+*/
+
+DEVICE_PARAM(ConnectionRate, "Connection data rate");
+
+#define OP_MODE_MAX     2
+#define OP_MODE_DEF     0
+#define OP_MODE_MIN     0
+
+DEVICE_PARAM(OPMode, "Infrastruct, adhoc, AP mode ");
+
+/* OpMode[] is used for transmit.
+   0: indicate infrastruct mode used
+   1: indicate adhoc mode used
+   2: indicate AP mode used
+*/
+
+
+/* PSMode[]
+   0: indicate disable power saving mode
+   1: indicate enable power saving mode
+*/
+
+#define PS_MODE_DEF     0
+
+DEVICE_PARAM(PSMode, "Power saving mode");
+
+
+#define SHORT_RETRY_MIN     0
+#define SHORT_RETRY_MAX     31
+#define SHORT_RETRY_DEF     8
+
+
+DEVICE_PARAM(ShortRetryLimit, "Short frame retry limits");
+
+#define LONG_RETRY_MIN     0
+#define LONG_RETRY_MAX     15
+#define LONG_RETRY_DEF     4
+
+
+DEVICE_PARAM(LongRetryLimit, "long frame retry limits");
+
+
+/* BasebandType[] baseband type selected
+   0: indicate 802.11a type
+   1: indicate 802.11b type
+   2: indicate 802.11g type
+*/
+#define BBP_TYPE_MIN     0
+#define BBP_TYPE_MAX     2
+#define BBP_TYPE_DEF     2
+
+DEVICE_PARAM(BasebandType, "baseband type");
+
+
+
+/* 80211hEnable[]
+   0: indicate disable 802.11h
+   1: indicate enable 802.11h
+*/
+
+#define X80211h_MODE_DEF     0
+
+DEVICE_PARAM(b80211hEnable, "802.11h mode");
+
+
+//
+// Static vars definitions
+//
+
+
+
+static struct usb_device_id vntwusb_table[] = {
+	{USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)},
+	{}
+};
+
+
+
+// Frequency list (map channels to frequencies)
+/*
+static const long frequency_list[] = {
+    2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484,
+    4915, 4920, 4925, 4935, 4940, 4945, 4960, 4980,
+    5035, 5040, 5045, 5055, 5060, 5080, 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240,
+    5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680,
+    5700, 5745, 5765, 5785, 5805, 5825
+	};
+
+
+#ifndef IW_ENCODE_NOKEY
+#define IW_ENCODE_NOKEY         0x0800
+#define IW_ENCODE_MODE  (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
+#endif
+
+static const struct iw_handler_def	iwctl_handler_def;
+*/
+
+
+
+/*---------------------  Static Functions  --------------------------*/
+static int vntwusb_found1(struct usb_interface *intf, const struct usb_device_id *id);
+static void vntwusb_disconnect(struct usb_interface *intf);
+#ifdef CONFIG_PM	/* Minimal support for suspend and resume */
+static int vntwusb_suspend(struct usb_interface *intf, pm_message_t message);
+static int vntwusb_resume(struct usb_interface *intf);
+#endif
+static struct net_device_stats *device_get_stats(struct net_device *dev);
+static int  device_open(struct net_device *dev);
+static int  device_xmit(struct sk_buff *skb, struct net_device *dev);
+static void device_set_multi(struct net_device *dev);
+static int  device_close(struct net_device *dev);
+static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+
+static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType);
+static BOOL device_init_defrag_cb(PSDevice pDevice);
+static void device_init_diversity_timer(PSDevice pDevice);
+static int  device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev);
+
+static int  ethtool_ioctl(struct net_device *dev, void *useraddr);
+static void device_free_tx_bufs(PSDevice pDevice);
+static void device_free_rx_bufs(PSDevice pDevice);
+static void device_free_int_bufs(PSDevice pDevice);
+static void device_free_frag_bufs(PSDevice pDevice);
+static BOOL device_alloc_bufs(PSDevice pDevice);
+
+static int Read_config_file(PSDevice pDevice);
+static UCHAR *Config_FileOperation(PSDevice pDevice);
+static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source);
+
+//2008-0714<Add>by Mike Liu
+static BOOL device_release_WPADEV(PSDevice pDevice);
+
+static void usb_device_reset(PSDevice pDevice);
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+static void
+device_set_options(PSDevice pDevice) {
+
+    BYTE    abyBroadcastAddr[U_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    BYTE    abySNAP_RFC1042[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+    BYTE    abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+
+
+    memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, U_ETHER_ADDR_LEN);
+    memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, U_ETHER_ADDR_LEN);
+    memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, U_ETHER_ADDR_LEN);
+
+    pDevice->cbTD = TX_DESC_DEF0;
+    pDevice->cbRD = RX_DESC_DEF0;
+    pDevice->uChannel = CHANNEL_DEF;
+    pDevice->wRTSThreshold = RTS_THRESH_DEF;
+    pDevice->wFragmentationThreshold = FRAG_THRESH_DEF;
+    pDevice->byShortRetryLimit = SHORT_RETRY_DEF;
+    pDevice->byLongRetryLimit = LONG_RETRY_DEF;
+    pDevice->wMaxTransmitMSDULifetime = DEFAULT_MSDU_LIFETIME;
+    pDevice->byShortPreamble = PREAMBLE_TYPE_DEF;
+    pDevice->ePSMode = PS_MODE_DEF;
+    pDevice->b11hEnable = X80211h_MODE_DEF;
+    pDevice->eOPMode = OP_MODE_DEF;
+    pDevice->uConnectionRate = DATA_RATE_DEF;
+    if (pDevice->uConnectionRate < RATE_AUTO) pDevice->bFixRate = TRUE;
+    pDevice->byBBType = BBP_TYPE_DEF;
+    pDevice->byPacketType = pDevice->byBBType;
+    pDevice->byAutoFBCtrl = AUTO_FB_0;
+    pDevice->bUpdateBBVGA = TRUE;
+    pDevice->byFOETuning = 0;
+    pDevice->byAutoPwrTunning = 0;
+    pDevice->wCTSDuration = 0;
+    pDevice->byPreambleType = 0;
+    pDevice->bExistSWNetAddr = FALSE;
+//    pDevice->bDiversityRegCtlON = TRUE;
+    pDevice->bDiversityRegCtlON = FALSE;
+}
+
+
+static VOID device_init_diversity_timer(PSDevice pDevice) {
+
+    init_timer(&pDevice->TimerSQ3Tmax1);
+    pDevice->TimerSQ3Tmax1.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax1.function = (TimerFunction)TimerSQ3CallBack;
+    pDevice->TimerSQ3Tmax1.expires = RUN_AT(HZ);
+
+    init_timer(&pDevice->TimerSQ3Tmax2);
+    pDevice->TimerSQ3Tmax2.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax2.function = (TimerFunction)TimerSQ3CallBack;
+    pDevice->TimerSQ3Tmax2.expires = RUN_AT(HZ);
+
+    init_timer(&pDevice->TimerSQ3Tmax3);
+    pDevice->TimerSQ3Tmax3.data = (ULONG)pDevice;
+    pDevice->TimerSQ3Tmax3.function = (TimerFunction)TimerSQ3Tmax3CallBack;
+    pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ);
+
+    return;
+}
+
+
+//
+// Initialiation of MAC & BBP registers
+//
+
+static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType)
+{
+    BYTE            abyBroadcastAddr[U_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+    BYTE            abySNAP_RFC1042[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+    BYTE            abySNAP_Bridgetunnel[U_ETHER_ADDR_LEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+    BYTE            byAntenna;
+    UINT            ii;
+    CMD_CARD_INIT   sInitCmd;
+    NTSTATUS        ntStatus = STATUS_SUCCESS;
+    RSP_CARD_INIT   sInitRsp;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BYTE            byTmp;
+    BYTE            byCalibTXIQ = 0;
+    BYTE            byCalibTXDC = 0;
+    BYTE            byCalibRXIQ = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---->INIbInitAdapter. [%d][%d]\n", InitType, pDevice->byPacketType);
+	spin_lock_irq(&pDevice->lock);
+    if (InitType == DEVICE_INIT_COLD) {
+        memcpy(pDevice->abyBroadcastAddr, abyBroadcastAddr, U_ETHER_ADDR_LEN);
+        memcpy(pDevice->abySNAP_RFC1042, abySNAP_RFC1042, U_ETHER_ADDR_LEN);
+        memcpy(pDevice->abySNAP_Bridgetunnel, abySNAP_Bridgetunnel, U_ETHER_ADDR_LEN);
+
+        if ( !FIRMWAREbCheckVersion(pDevice) ) {
+            if (FIRMWAREbDownload(pDevice) == TRUE) {
+                if (FIRMWAREbBrach2Sram(pDevice) == FALSE) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbBrach2Sram fail \n");
+                  	spin_unlock_irq(&pDevice->lock);
+                    return FALSE;
+                }
+            } else {
+
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" FIRMWAREbDownload fail \n");
+                spin_unlock_irq(&pDevice->lock);
+                return FALSE;
+            }
+        }
+
+        if ( !BBbVT3184Init(pDevice) ) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" BBbVT3184Init fail \n");
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+    }
+
+    sInitCmd.byInitClass = (BYTE)InitType;
+    sInitCmd.bExistSWNetAddr = (BYTE) pDevice->bExistSWNetAddr;
+    for(ii=0;ii<6;ii++)
+        sInitCmd.bySWNetAddr[ii] = pDevice->abyCurrentNetAddr[ii];
+    sInitCmd.byShortRetryLimit = pDevice->byShortRetryLimit;
+    sInitCmd.byLongRetryLimit = pDevice->byLongRetryLimit;
+
+    //issue Card_init command to device
+    ntStatus = CONTROLnsRequestOut(pDevice,
+                                    MESSAGE_TYPE_CARDINIT,
+                                    0,
+                                    0,
+                                    sizeof(CMD_CARD_INIT),
+                                    (PBYTE) &(sInitCmd));
+
+    if ( ntStatus != STATUS_SUCCESS ) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Issue Card init fail \n");
+        spin_unlock_irq(&pDevice->lock);
+        return FALSE;
+    }
+    if (InitType == DEVICE_INIT_COLD) {
+
+        ntStatus = CONTROLnsRequestIn(pDevice,MESSAGE_TYPE_INIT_RSP,0,0,sizeof(RSP_CARD_INIT), (PBYTE) &(sInitRsp));
+
+        if (ntStatus != STATUS_SUCCESS) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Cardinit request in status fail!\n");
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+
+        //Local ID for AES functions
+        ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    MAC_REG_LOCALID,
+                                    MESSAGE_REQUEST_MACREG,
+                                    1,
+                                    &pDevice->byLocalID);
+
+        if ( ntStatus != STATUS_SUCCESS ) {
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+
+        // Do MACbSoftwareReset in MACvInitialize
+        // force CCK
+        pDevice->bCCK = TRUE;
+        pDevice->bProtectMode = FALSE;          //Only used in 11g type, sync with ERP IE
+        pDevice->bNonERPPresent = FALSE;
+        pDevice->bBarkerPreambleMd = FALSE;
+        if ( pDevice->bFixRate ) {
+            pDevice->wCurrentRate = (WORD) pDevice->uConnectionRate;
+        } else {
+            if ( pDevice->byBBType == BB_TYPE_11B )
+                pDevice->wCurrentRate = RATE_11M;
+            else
+                pDevice->wCurrentRate = RATE_54M;
+        }
+
+        CHvInitChannelTable(pDevice);
+
+        pDevice->byTopOFDMBasicRate = RATE_24M;
+        pDevice->byTopCCKBasicRate = RATE_1M;
+        pDevice->byRevId = 0;                   //Target to IF pin while programming to RF chip.
+        pDevice->byCurPwr = 0xFF;
+
+        pDevice->byCCKPwr = pDevice->abyEEPROM[EEP_OFS_PWR_CCK];
+        pDevice->byOFDMPwrG = pDevice->abyEEPROM[EEP_OFS_PWR_OFDMG];
+        // Load power Table
+        for (ii=0;ii<14;ii++) {
+            pDevice->abyCCKPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_CCK_PWR_TBL];
+            if (pDevice->abyCCKPwrTbl[ii] == 0)
+                pDevice->abyCCKPwrTbl[ii] = pDevice->byCCKPwr;
+            pDevice->abyOFDMPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDM_PWR_TBL];
+            if (pDevice->abyOFDMPwrTbl[ii] == 0)
+                pDevice->abyOFDMPwrTbl[ii] = pDevice->byOFDMPwrG;
+        }
+
+	  //original zonetype is USA,but customize zonetype is europe,
+	  // then need recover 12,13 ,14 channel  with 11 channel
+          if(((pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Japan) ||
+	        (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] == ZoneType_Europe))&&
+	     (pDevice->byOriginalZonetype == ZoneType_USA)) {
+	    for(ii=11;ii<14;ii++) {
+                pDevice->abyCCKPwrTbl[ii] = pDevice->abyCCKPwrTbl[10];
+	       pDevice->abyOFDMPwrTbl[ii] = pDevice->abyOFDMPwrTbl[10];
+	    }
+	  }
+
+        //{{ RobertYu: 20041124
+        pDevice->byOFDMPwrA = 0x34; // same as RFbMA2829SelectChannel
+        // Load OFDM A Power Table
+        for (ii=0;ii<CB_MAX_CHANNEL_5G;ii++) { //RobertYu:20041224, bug using CB_MAX_CHANNEL
+            pDevice->abyOFDMAPwrTbl[ii] = pDevice->abyEEPROM[ii + EEP_OFS_OFDMA_PWR_TBL];
+            if (pDevice->abyOFDMAPwrTbl[ii] == 0)
+                pDevice->abyOFDMAPwrTbl[ii] = pDevice->byOFDMPwrA;
+        }
+        //}} RobertYu
+
+        byAntenna = pDevice->abyEEPROM[EEP_OFS_ANTENNA];
+        if (byAntenna & EEP_ANTINV)
+            pDevice->bTxRxAntInv = TRUE;
+        else
+            pDevice->bTxRxAntInv = FALSE;
+
+        byAntenna &= (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+        if (byAntenna == 0) // if not set default is All
+            byAntenna = (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN);
+
+        if (byAntenna == (EEP_ANTENNA_AUX | EEP_ANTENNA_MAIN)) {
+            pDevice->byAntennaCount = 2;
+            pDevice->byTxAntennaMode = ANT_B;
+            pDevice->dwTxAntennaSel = 1;
+            pDevice->dwRxAntennaSel = 1;
+            if (pDevice->bTxRxAntInv == TRUE)
+                pDevice->byRxAntennaMode = ANT_A;
+            else
+                pDevice->byRxAntennaMode = ANT_B;
+
+            if (pDevice->bDiversityRegCtlON)
+                pDevice->bDiversityEnable = TRUE;
+            else
+                pDevice->bDiversityEnable = FALSE;
+        } else  {
+            pDevice->bDiversityEnable = FALSE;
+            pDevice->byAntennaCount = 1;
+            pDevice->dwTxAntennaSel = 0;
+            pDevice->dwRxAntennaSel = 0;
+            if (byAntenna & EEP_ANTENNA_AUX) {
+                pDevice->byTxAntennaMode = ANT_A;
+                if (pDevice->bTxRxAntInv == TRUE)
+                    pDevice->byRxAntennaMode = ANT_B;
+                else
+                    pDevice->byRxAntennaMode = ANT_A;
+            } else {
+                pDevice->byTxAntennaMode = ANT_B;
+                if (pDevice->bTxRxAntInv == TRUE)
+                    pDevice->byRxAntennaMode = ANT_A;
+                else
+                    pDevice->byRxAntennaMode = ANT_B;
+            }
+        }
+        pDevice->ulDiversityNValue = 100*255;
+        pDevice->ulDiversityMValue = 100*16;
+        pDevice->byTMax = 1;
+        pDevice->byTMax2 = 4;
+        pDevice->ulSQ3TH = 0;
+        pDevice->byTMax3 = 64;
+        // -----------------------------------------------------------------
+
+        //Get Auto Fall Back Type
+        pDevice->byAutoFBCtrl = AUTO_FB_0;
+
+        // Set SCAN Time
+        pDevice->uScanTime = WLAN_SCAN_MINITIME;
+
+        // default Auto Mode
+        //pDevice->NetworkType = Ndis802_11Automode;
+        pDevice->eConfigPHYMode = PHY_TYPE_AUTO;
+        pDevice->byBBType = BB_TYPE_11G;
+
+        // initialize BBP registers
+        pDevice->ulTxPower = 25;
+
+        // Get Channel range
+        pDevice->byMinChannel = 1;
+        pDevice->byMaxChannel = CB_MAX_CHANNEL;
+
+        // Get RFType
+        pDevice->byRFType = sInitRsp.byRFType;
+
+        if ((pDevice->byRFType & RF_EMU) != 0) {
+            // force change RevID for VT3253 emu
+            pDevice->byRevId = 0x80;
+        }
+
+        // Load EEPROM calibrated vt3266 parameters
+        if (pDevice->byRFType == RF_VT3226D0) {
+            if((pDevice->abyEEPROM[EEP_OFS_MAJOR_VER] == 0x1) &&
+                (pDevice->abyEEPROM[EEP_OFS_MINOR_VER] >= 0x4)) {
+                byCalibTXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_IQ];
+                byCalibTXDC = pDevice->abyEEPROM[EEP_OFS_CALIB_TX_DC];
+                byCalibRXIQ = pDevice->abyEEPROM[EEP_OFS_CALIB_RX_IQ];
+                if( (byCalibTXIQ || byCalibTXDC || byCalibRXIQ) ) {
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x03); // CR255, Set BB to support TX/RX IQ and DC compensation Mode
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFB, byCalibTXIQ); // CR251, TX I/Q Imbalance Calibration
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFC, byCalibTXDC); // CR252, TX DC-Offset Calibration
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFD, byCalibRXIQ); // CR253, RX I/Q Imbalance Calibration
+                } else {
+                // turn off BB Calibration compensation
+                    ControlvWriteByte(pDevice, MESSAGE_REQUEST_BBREG, 0xFF, 0x0); // CR255
+                }
+            }
+        }
+        pMgmt->eScanType = WMAC_SCAN_PASSIVE;
+        pMgmt->uCurrChannel = pDevice->uChannel;
+        pMgmt->uIBSSChannel = pDevice->uChannel;
+        CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+
+        // get Permanent network address
+        memcpy(pDevice->abyPermanentNetAddr,&(sInitRsp.byNetAddr[0]),6);
+        memcpy(pDevice->abyCurrentNetAddr, pDevice->abyPermanentNetAddr, U_ETHER_ADDR_LEN);
+
+        // if exist SW network address, use SW network address.
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n",
+            pDevice->abyCurrentNetAddr[0],
+            pDevice->abyCurrentNetAddr[1],
+            pDevice->abyCurrentNetAddr[2],
+            pDevice->abyCurrentNetAddr[3],
+            pDevice->abyCurrentNetAddr[4],
+            pDevice->abyCurrentNetAddr[5]);
+    }
+
+
+
+    // Set BB and packet type at the same time.
+    // Set Short Slot Time, xIFS, and RSPINF.
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        CARDbAddBasicRate(pDevice, RATE_6M);
+        pDevice->bShortSlotTime = TRUE;
+    } else {
+        CARDbAddBasicRate(pDevice, RATE_1M);
+        pDevice->bShortSlotTime = FALSE;
+    }
+    BBvSetShortSlotTime(pDevice);
+    CARDvSetBSSMode(pDevice);
+
+    if (pDevice->bUpdateBBVGA) {
+        pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+        pDevice->byBBVGANew = pDevice->byBBVGACurrent;
+        BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+    }
+
+    pDevice->byRadioCtl = pDevice->abyEEPROM[EEP_OFS_RADIOCTL];
+    pDevice->bHWRadioOff = FALSE;
+    if ( (pDevice->byRadioCtl & EEP_RADIOCTL_ENABLE) != 0 ) {
+        ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    MAC_REG_GPIOCTL1,
+                                    MESSAGE_REQUEST_MACREG,
+                                    1,
+                                    &byTmp);
+
+        if ( ntStatus != STATUS_SUCCESS ) {
+            spin_unlock_irq(&pDevice->lock);
+            return FALSE;
+        }
+        if ( (byTmp & GPIO3_DATA) == 0 ) {
+            pDevice->bHWRadioOff = TRUE;
+            MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+        } else {
+            MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+            pDevice->bHWRadioOff = FALSE;
+        }
+
+    } //EEP_RADIOCTL_ENABLE
+
+    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_TMLEN,0x38);
+    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+    MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL0,0x01);
+
+    if ((pDevice->bHWRadioOff == TRUE) || (pDevice->bRadioControlOff == TRUE)) {
+        CARDbRadioPowerOff(pDevice);
+    } else {
+        CARDbRadioPowerOn(pDevice);
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----INIbInitAdapter Exit\n");
+    return TRUE;
+}
+
+static BOOL device_release_WPADEV(PSDevice pDevice)
+{
+  viawget_wpa_header *wpahdr;
+  int ii=0;
+ // wait_queue_head_t	Set_wait;
+  //send device close to wpa_supplicnat layer
+    if (pDevice->bWPADEVUp==TRUE) {
+                 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                 wpahdr->type = VIAWGET_DEVICECLOSE_MSG;
+                 wpahdr->resp_ie_len = 0;
+                 wpahdr->req_ie_len = 0;
+                 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+                 pDevice->skb->dev = pDevice->wpadev;
+		 skb_reset_mac_header(pDevice->skb);
+                 pDevice->skb->pkt_type = PACKET_HOST;
+                 pDevice->skb->protocol = htons(ETH_P_802_2);
+                 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+                 netif_rx(pDevice->skb);
+                 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+
+ //wait release WPADEV
+              //    init_waitqueue_head(&Set_wait);
+              //    wait_event_timeout(Set_wait, ((pDevice->wpadev==NULL)&&(pDevice->skb == NULL)),5*HZ);    //1s wait
+              while(pDevice->bWPADEVUp==TRUE) {
+	        set_current_state(TASK_UNINTERRUPTIBLE);
+                 schedule_timeout (HZ/20);          //wait 50ms
+                 ii++;
+	        if(ii>20)
+		  break;
+              }
+           };
+    return TRUE;
+}
+
+#ifdef CONFIG_PM	/* Minimal support for suspend and resume */
+static int vntwusb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ PSDevice  pDevice = usb_get_intfdata(intf);
+ struct net_device *dev = pDevice->dev;
+
+ printk("VNTWUSB Suspend Start======>\n");
+if(dev != NULL) {
+  if(pDevice->flags & DEVICE_FLAGS_OPENED)
+     device_close(dev);
+}
+
+ usb_put_dev(interface_to_usbdev(intf));
+ return 0;
+}
+
+static int vntwusb_resume(struct usb_interface *intf)
+{
+ PSDevice  pDevice = usb_get_intfdata(intf);
+ struct net_device *dev = pDevice->dev;
+
+ printk("VNTWUSB Resume Start======>\n");
+ if(dev != NULL) {
+  usb_get_dev(interface_to_usbdev(intf));
+  if(!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+    if(device_open(dev)!=0)
+        printk("VNTWUSB Resume Start======>open fail\n");
+   }
+ }
+ return 0;
+}
+#endif
+
+
+static const struct net_device_ops device_netdev_ops = {
+    .ndo_open               = device_open,
+    .ndo_stop               = device_close,
+    .ndo_do_ioctl           = device_ioctl,
+    .ndo_get_stats          = device_get_stats,
+    .ndo_start_xmit         = device_xmit,
+    .ndo_set_multicast_list = device_set_multi,
+};
+
+
+static int
+vntwusb_found1(struct usb_interface *intf, const struct usb_device_id *id)
+{
+   BYTE            fake_mac[U_ETHER_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x01};//fake MAC address
+	struct usb_device *udev = interface_to_usbdev(intf);
+    int         rc = 0;
+    struct net_device *netdev = NULL;
+    PSDevice    pDevice = NULL;
+
+
+    printk(KERN_NOTICE "%s Ver. %s\n",DEVICE_FULL_DRV_NAM, DEVICE_VERSION);
+    printk(KERN_NOTICE "Copyright (c) 2004 VIA Networking Technologies, Inc.\n");
+
+  udev = usb_get_dev(udev);
+
+    netdev = alloc_etherdev(sizeof(DEVICE_INFO));
+
+    if (netdev == NULL) {
+        printk(KERN_ERR DEVICE_NAME ": allocate net device failed \n");
+        kfree(pDevice);
+	    goto err_nomem;
+    }
+
+    pDevice = netdev_priv(netdev);
+    memset(pDevice, 0, sizeof(DEVICE_INFO));
+
+    pDevice->dev = netdev;
+    pDevice->usb = udev;
+
+    // Set initial settings
+    device_set_options(pDevice);
+    spin_lock_init(&pDevice->lock);
+
+    pDevice->tx_80211 = device_dma0_tx_80211;
+    pDevice->sMgmtObj.pAdapter = (PVOID)pDevice;
+
+    netdev->netdev_ops         = &device_netdev_ops;
+
+	netdev->wireless_handlers = (struct iw_handler_def *)&iwctl_handler_def;
+
+   //2008-0623-01<Remark>by MikeLiu
+  //2007-0821-01<Add>by MikeLiu
+         usb_set_intfdata(intf, pDevice);
+	SET_NETDEV_DEV(netdev, &intf->dev);
+    memcpy(pDevice->dev->dev_addr, fake_mac, U_ETHER_ADDR_LEN); //use fake mac address
+    rc = register_netdev(netdev);
+    if (rc != 0) {
+        printk(KERN_ERR DEVICE_NAME " Failed to register netdev\n");
+		free_netdev(netdev);
+        kfree(pDevice);
+        return -ENODEV;
+    }
+	//2008-0623-02<Remark>by MikeLiu
+        //2007-0821-01<Add>by MikeLiu
+       //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+  	//usb_set_intfdata(intf, pDevice);
+	//SET_NETDEV_DEV(netdev, &intf->dev);
+       //#endif
+
+//2008-07-21-01<Add>by MikeLiu
+//register wpadev
+#if 0
+   if(wpa_set_wpadev(pDevice, 1)!=0) {
+     printk("Fail to Register WPADEV?\n");
+        unregister_netdev(pDevice->dev);
+        free_netdev(netdev);
+        kfree(pDevice);
+   }
+#endif
+         usb_device_reset(pDevice);
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_INSMOD_EVENT_FLAG;
+  wrqu.data.length =IFNAMSIZ;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, pDevice->dev->name);
+}
+#endif
+
+	return 0;
+
+
+err_nomem:
+ //2008-0922-01<Add>by MikeLiu, decrease usb counter.
+    usb_put_dev(udev);
+
+    return -ENOMEM;
+}
+
+
+static VOID device_free_tx_bufs(PSDevice pDevice) {
+    PUSB_SEND_CONTEXT pTxContext;
+    int ii;
+
+    for (ii = 0; ii < pDevice->cbTD; ii++) {
+
+        pTxContext = pDevice->apTD[ii];
+        //de-allocate URBs
+        if (pTxContext->pUrb) {
+            usb_kill_urb(pTxContext->pUrb);
+            usb_free_urb(pTxContext->pUrb);
+        }
+        if (pTxContext)
+            kfree(pTxContext);
+    }
+    return;
+}
+
+
+static VOID device_free_rx_bufs(PSDevice pDevice) {
+    PRCB pRCB;
+    int ii;
+
+    for (ii = 0; ii < pDevice->cbRD; ii++) {
+
+        pRCB = pDevice->apRCB[ii];
+        //de-allocate URBs
+        if (pRCB->pUrb) {
+            usb_kill_urb(pRCB->pUrb);
+            usb_free_urb(pRCB->pUrb);
+        }
+        //de-allocate skb
+        if (pRCB->skb)
+            dev_kfree_skb(pRCB->skb);
+    }
+    if (pDevice->pRCBMem)
+        kfree(pDevice->pRCBMem);
+
+    return;
+}
+
+//2007-1107-02<Add>by MikeLiu
+static void usb_device_reset(PSDevice pDevice)
+{
+ int status;
+ status = usb_reset_device(pDevice->usb);
+	if (status)
+            printk("usb_device_reset fail status=%d\n",status);
+	return ;
+}
+
+static VOID device_free_int_bufs(PSDevice pDevice) {
+
+    if (pDevice->intBuf.pDataBuf != NULL)
+        kfree(pDevice->intBuf.pDataBuf);
+    return;
+}
+
+
+static BOOL device_alloc_bufs(PSDevice pDevice) {
+
+    PUSB_SEND_CONTEXT pTxContext;
+    PRCB pRCB;
+    int ii;
+
+
+    for (ii = 0; ii < pDevice->cbTD; ii++) {
+
+        pTxContext = kmalloc(sizeof(USB_SEND_CONTEXT), GFP_KERNEL);
+        if (pTxContext == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : allocate tx usb context failed\n", pDevice->dev->name);
+            goto free_tx;
+        }
+        pDevice->apTD[ii] = pTxContext;
+        pTxContext->pDevice = (PVOID) pDevice;
+        //allocate URBs
+        pTxContext->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
+        if (pTxContext->pUrb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "alloc tx urb failed\n");
+            goto free_tx;
+        }
+        pTxContext->bBoolInUse = FALSE;
+    }
+
+    // allocate rcb mem
+    pDevice->pRCBMem = kmalloc((sizeof(RCB) * pDevice->cbRD), GFP_KERNEL);
+    if (pDevice->pRCBMem == NULL) {
+        DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s : alloc rx usb context failed\n", pDevice->dev->name);
+        goto free_tx;
+    }
+
+
+    pDevice->FirstRecvFreeList = NULL;
+    pDevice->LastRecvFreeList = NULL;
+    pDevice->FirstRecvMngList = NULL;
+    pDevice->LastRecvMngList = NULL;
+    pDevice->NumRecvFreeList = 0;
+    memset(pDevice->pRCBMem, 0, (sizeof(RCB) * pDevice->cbRD));
+    pRCB = (PRCB) pDevice->pRCBMem;
+
+    for (ii = 0; ii < pDevice->cbRD; ii++) {
+
+        pDevice->apRCB[ii] = pRCB;
+        pRCB->pDevice = (PVOID) pDevice;
+        //allocate URBs
+        pRCB->pUrb = usb_alloc_urb(0, GFP_ATOMIC);
+
+        if (pRCB->pUrb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx urb\n");
+            goto free_rx_tx;
+        }
+        pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+        if (pRCB->skb == NULL) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR" Failed to alloc rx skb\n");
+            goto free_rx_tx;
+        }
+        pRCB->skb->dev = pDevice->dev;
+        pRCB->bBoolInUse = FALSE;
+        EnqueueRCB(pDevice->FirstRecvFreeList, pDevice->LastRecvFreeList, pRCB);
+        pDevice->NumRecvFreeList++;
+        pRCB++;
+    }
+
+
+	pDevice->pControlURB = usb_alloc_urb(0, GFP_ATOMIC);
+	if (pDevice->pControlURB == NULL) {
+	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc control urb\n");
+	    goto free_rx_tx;
+	}
+
+	pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
+	if (pDevice->pInterruptURB == NULL) {
+	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
+   	    usb_kill_urb(pDevice->pControlURB);
+	    usb_free_urb(pDevice->pControlURB);
+	    goto free_rx_tx;
+	}
+
+    pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
+	if (pDevice->intBuf.pDataBuf == NULL) {
+	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
+   	    usb_kill_urb(pDevice->pControlURB);
+   	    usb_kill_urb(pDevice->pInterruptURB);
+	    usb_free_urb(pDevice->pControlURB);
+	    usb_free_urb(pDevice->pInterruptURB);
+	    goto free_rx_tx;
+	}
+
+    return TRUE;
+
+free_rx_tx:
+    device_free_rx_bufs(pDevice);
+
+free_tx:
+    device_free_tx_bufs(pDevice);
+
+	return FALSE;
+}
+
+
+
+
+static BOOL device_init_defrag_cb(PSDevice pDevice) {
+    int i;
+    PSDeFragControlBlock pDeF;
+
+    /* Init the fragment ctl entries */
+    for (i = 0; i < CB_MAX_RX_FRAG; i++) {
+        pDeF = &(pDevice->sRxDFCB[i]);
+        if (!device_alloc_frag_buf(pDevice, pDeF)) {
+            DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
+                pDevice->dev->name);
+            goto free_frag;
+        };
+    }
+    pDevice->cbDFCB = CB_MAX_RX_FRAG;
+    pDevice->cbFreeDFCB = pDevice->cbDFCB;
+    return TRUE;
+
+free_frag:
+    device_free_frag_bufs(pDevice);
+    return FALSE;
+}
+
+
+
+static void device_free_frag_bufs(PSDevice pDevice) {
+    PSDeFragControlBlock pDeF;
+    int i;
+
+    for (i = 0; i < CB_MAX_RX_FRAG; i++) {
+
+        pDeF = &(pDevice->sRxDFCB[i]);
+
+        if (pDeF->skb)
+            dev_kfree_skb(pDeF->skb);
+    }
+}
+
+
+
+BOOL device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) {
+
+    pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+    if (pDeF->skb == NULL)
+        return FALSE;
+    ASSERT(pDeF->skb);
+    pDeF->skb->dev = pDevice->dev;
+
+    return TRUE;
+}
+
+
+/*-----------------------------------------------------------------*/
+
+static int  device_open(struct net_device *dev) {
+    PSDevice    pDevice=(PSDevice) netdev_priv(dev);
+
+#ifdef WPA_SM_Transtatus
+     extern SWPAResult wpa_Result;
+     memset(wpa_Result.ifname,0,sizeof(wpa_Result.ifname));
+     wpa_Result.proto = 0;
+     wpa_Result.key_mgmt = 0;
+     wpa_Result.eap_type = 0;
+     wpa_Result.authenticated = FALSE;
+     pDevice->fWPA_Authened = FALSE;
+#endif
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_open...\n");
+
+
+    pDevice->rx_buf_sz = MAX_TOTAL_SIZE_WITH_ALL_HEADERS;
+
+    if (device_alloc_bufs(pDevice) == FALSE) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " device_alloc_bufs fail... \n");
+        return -ENOMEM;
+    }
+
+    if (device_init_defrag_cb(pDevice)== FALSE) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Initial defragement cb fail \n");
+        goto free_rx_tx;
+    }
+
+    MP_CLEAR_FLAG(pDevice, fMP_DISCONNECTED);
+    MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+    MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+    MP_SET_FLAG(pDevice, fMP_POST_READS);
+    MP_SET_FLAG(pDevice, fMP_POST_WRITES);
+
+   //read config file
+    Read_config_file(pDevice);
+
+    if (device_init_registers(pDevice, DEVICE_INIT_COLD) == FALSE) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " init register fail\n");
+        goto free_all;
+    }
+
+    device_set_multi(pDevice->dev);
+    // Init for Key Management
+
+    KeyvInitTable(pDevice,&pDevice->sKey);
+    memcpy(pDevice->sMgmtObj.abyMACAddr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN);
+    memcpy(pDevice->dev->dev_addr, pDevice->abyCurrentNetAddr, U_ETHER_ADDR_LEN);
+    pDevice->bStopTx0Pkt = FALSE;
+    pDevice->bStopDataPkt = FALSE;
+    pDevice->bRoaming = FALSE;  //DavidWang
+    pDevice->bIsRoaming = FALSE;//DavidWang
+    pDevice->bEnableRoaming = FALSE;
+    if (pDevice->bDiversityRegCtlON) {
+        device_init_diversity_timer(pDevice);
+    }
+
+    vMgrObjectInit(pDevice);
+    tasklet_init(&pDevice->RxMngWorkItem, (void *)RXvMngWorkItem, (unsigned long)pDevice);
+    tasklet_init(&pDevice->ReadWorkItem, (void *)RXvWorkItem, (unsigned long)pDevice);
+    tasklet_init(&pDevice->EventWorkItem, (void *)INTvWorkItem, (unsigned long)pDevice);
+    add_timer(&(pDevice->sMgmtObj.sTimerSecondCallback));
+    pDevice->int_interval = 100;  //Max 100 microframes.
+    pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+
+    pDevice->bIsRxWorkItemQueued = TRUE;
+    pDevice->fKillEventPollingThread = FALSE;
+    pDevice->bEventAvailable = FALSE;
+
+   pDevice->bWPADEVUp = FALSE;
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+     pDevice->bwextstep0 = FALSE;
+     pDevice->bwextstep1 = FALSE;
+     pDevice->bwextstep2 = FALSE;
+     pDevice->bwextstep3 = FALSE;
+     pDevice->bWPASuppWextEnabled = FALSE;
+#endif
+    pDevice->byReAssocCount = 0;
+
+    RXvWorkItem(pDevice);
+    INTvWorkItem(pDevice);
+
+    // Patch: if WEP key already set by iwconfig but device not yet open
+    if ((pDevice->bEncryptionEnable == TRUE) && (pDevice->bTransmitKey == TRUE)) {
+         spin_lock_irq(&pDevice->lock);
+         KeybSetDefaultKey( pDevice,
+                            &(pDevice->sKey),
+                            pDevice->byKeyIndex | (1 << 31),
+                            pDevice->uKeyLength,
+                            NULL,
+                            pDevice->abyKey,
+                            KEY_CTL_WEP
+                          );
+         spin_unlock_irq(&pDevice->lock);
+         pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+    }
+
+    if (pDevice->sMgmtObj.eConfigMode == WMAC_CONFIG_AP) {
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL);
+	}
+	else {
+	//mike:mark@2008-11-10
+            bScheduleCommand((HANDLE)pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+        //bScheduleCommand((HANDLE)pDevice, WLAN_CMD_SSID, NULL);
+    }
+
+
+    netif_stop_queue(pDevice->dev);
+    pDevice->flags |= DEVICE_FLAGS_OPENED;
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_UPDEV_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+#endif
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success.. \n");
+    return 0;
+
+free_all:
+    device_free_frag_bufs(pDevice);
+free_rx_tx:
+    device_free_rx_bufs(pDevice);
+    device_free_tx_bufs(pDevice);
+    device_free_int_bufs(pDevice);
+	usb_kill_urb(pDevice->pControlURB);
+	usb_kill_urb(pDevice->pInterruptURB);
+    usb_free_urb(pDevice->pControlURB);
+    usb_free_urb(pDevice->pInterruptURB);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open fail.. \n");
+    return -ENOMEM;
+}
+
+
+
+static int  device_close(struct net_device *dev) {
+    PSDevice    pDevice=(PSDevice) netdev_priv(dev);
+    PSMgmtObject     pMgmt = &(pDevice->sMgmtObj);
+
+        int uu;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close1 \n");
+    if (pDevice == NULL)
+        return -ENODEV;
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_DOWNDEV_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+#endif
+
+//2007-1121-02<Add>by EinsnLiu
+    if (pDevice->bLinkPass) {
+	bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+        mdelay(30);
+    }
+//End Add
+
+//2008-0714-01<Add>by MikeLiu
+device_release_WPADEV(pDevice);
+
+        memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+        pMgmt->bShareKeyAlgorithm = FALSE;
+        pDevice->bEncryptionEnable = FALSE;
+        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+            spin_lock_irq(&pDevice->lock);
+            for(uu=0;uu<MAX_KEY_TABLE;uu++)
+                MACvDisableKeyEntry(pDevice,uu);
+            spin_unlock_irq(&pDevice->lock);
+
+    if ((pDevice->flags & DEVICE_FLAGS_UNPLUG) == FALSE) {
+        MACbShutdown(pDevice);
+    }
+    netif_stop_queue(pDevice->dev);
+    MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
+    MP_CLEAR_FLAG(pDevice, fMP_POST_WRITES);
+    MP_CLEAR_FLAG(pDevice, fMP_POST_READS);
+    pDevice->fKillEventPollingThread = TRUE;
+    del_timer(&pDevice->sTimerCommand);
+    del_timer(&pMgmt->sTimerSecondCallback);
+
+//2007-0115-02<Add>by MikeLiu
+#ifdef TxInSleep
+    del_timer(&pDevice->sTimerTxData);
+#endif
+
+    if (pDevice->bDiversityRegCtlON) {
+        del_timer(&pDevice->TimerSQ3Tmax1);
+        del_timer(&pDevice->TimerSQ3Tmax2);
+        del_timer(&pDevice->TimerSQ3Tmax3);
+    }
+    tasklet_kill(&pDevice->RxMngWorkItem);
+    tasklet_kill(&pDevice->ReadWorkItem);
+    tasklet_kill(&pDevice->EventWorkItem);
+
+   pDevice->bRoaming = FALSE;  //DavidWang
+   pDevice->bIsRoaming = FALSE;//DavidWang
+   pDevice->bEnableRoaming = FALSE;
+    pDevice->bCmdRunning = FALSE;
+    pDevice->bLinkPass = FALSE;
+    memset(pMgmt->abyCurrBSSID, 0, 6);
+    pMgmt->eCurrState = WMAC_STATE_IDLE;
+
+    device_free_tx_bufs(pDevice);
+    device_free_rx_bufs(pDevice);
+    device_free_int_bufs(pDevice);
+    device_free_frag_bufs(pDevice);
+
+	usb_kill_urb(pDevice->pControlURB);
+	usb_kill_urb(pDevice->pInterruptURB);
+    usb_free_urb(pDevice->pControlURB);
+    usb_free_urb(pDevice->pInterruptURB);
+
+    BSSvClearNodeDBTable(pDevice, 0);
+    pDevice->flags &=(~DEVICE_FLAGS_OPENED);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n");
+
+    return 0;
+}
+
+
+static void vntwusb_disconnect(struct usb_interface *intf)
+
+{
+
+	PSDevice  pDevice = usb_get_intfdata(intf);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect1.. \n");
+    if (pDevice == NULL)
+        return;
+
+#ifdef SndEvt_ToAPI
+{
+  union iwreq_data      wrqu;
+  memset(&wrqu, 0, sizeof(wrqu));
+  wrqu.data.flags = RT_RMMOD_EVENT_FLAG;
+  wireless_send_event(pDevice->dev, IWEVCUSTOM, &wrqu, NULL);
+}
+#endif
+
+//2008-0714-01<Add>by MikeLiu
+device_release_WPADEV(pDevice);
+
+	usb_set_intfdata(intf, NULL);
+//2008-0922-01<Add>by MikeLiu, decrease usb counter.
+     usb_put_dev(interface_to_usbdev(intf));
+
+    pDevice->flags |= DEVICE_FLAGS_UNPLUG;
+    if (pDevice->dev != NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unregister_netdev..\n");
+        unregister_netdev(pDevice->dev);
+
+//2008-07-21-01<Add>by MikeLiu
+//unregister wpadev
+   if(wpa_set_wpadev(pDevice, 0)!=0)
+     printk("unregister wpadev fail?\n");
+
+        free_netdev(pDevice->dev);
+    }
+
+	kfree(pDevice);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_disconnect3.. \n");
+}
+
+
+
+
+static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) {
+    PSDevice        pDevice=netdev_priv(dev);
+    PBYTE           pbMPDU;
+    UINT            cbMPDULen = 0;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n");
+    spin_lock_irq(&pDevice->lock);
+
+    if (pDevice->bStopTx0Pkt == TRUE) {
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    };
+
+
+    cbMPDULen = skb->len;
+    pbMPDU = skb->data;
+
+    vDMA0_tx_80211(pDevice, skb);
+
+    spin_unlock_irq(&pDevice->lock);
+
+    return 0;
+
+}
+
+
+static int  device_xmit(struct sk_buff *skb, struct net_device *dev) {
+    PSDevice    pDevice=netdev_priv(dev);
+    struct net_device_stats* pStats = &pDevice->stats;
+
+
+    spin_lock_irq(&pDevice->lock);
+
+    netif_stop_queue(pDevice->dev);
+
+    if (pDevice->bLinkPass == FALSE) {
+        dev_kfree_skb_irq(skb);
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+    if (pDevice->bStopDataPkt == TRUE) {
+        dev_kfree_skb_irq(skb);
+        pStats->tx_dropped++;
+        spin_unlock_irq(&pDevice->lock);
+        return 0;
+    }
+
+    if(nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) !=0) {  //mike add:xmit fail!
+         if (netif_queue_stopped(pDevice->dev))
+              netif_wake_queue(pDevice->dev);
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+
+    return 0;
+}
+
+
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+    int crc = -1;
+
+    while(--length >= 0) {
+        unsigned char current_octet = *data++;
+        int bit;
+        for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+            crc = (crc << 1) ^
+                ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+        }
+    }
+    return crc;
+}
+
+//find out  the start  position of str2 from str1
+static UCHAR *kstrstr(const UCHAR *str1,const UCHAR *str2) {
+  int str1_len=strlen(str1);
+  int str2_len=strlen(str2);
+
+  while (str1_len >= str2_len) {
+       str1_len--;
+      if(memcmp(str1,str2,str2_len)==0)
+         return (UCHAR *)str1;
+        str1++;
+  }
+  return NULL;
+}
+
+static int Config_FileGetParameter(UCHAR *string, UCHAR *dest,UCHAR *source)
+{
+  UCHAR buf1[100];
+  UCHAR buf2[100];
+  UCHAR *start_p=NULL,*end_p=NULL,*tmp_p=NULL;
+  int ii;
+
+    memset(buf1,0,100);
+    strcat(buf1, string);
+    strcat(buf1, "=");
+    source+=strlen(buf1);
+
+//find target string start point
+    if((start_p = kstrstr(source,buf1))==NULL)
+	return FALSE;
+
+//check if current config line is marked by "#" ??
+for(ii=1;;ii++) {
+  if(memcmp(start_p-ii,"\n",1)==0)
+      break;
+  if(memcmp(start_p-ii,"#",1)==0)
+      return FALSE;
+}
+
+//find target string end point
+     if((end_p = kstrstr(start_p,"\n"))==NULL) {       //cann't find "\n",but don't care
+          end_p=start_p+strlen(start_p);   //no include "\n"
+       }
+
+   memset(buf2,0,100);
+   memcpy(buf2,start_p,end_p-start_p);    //get the tartget line
+   buf2[end_p-start_p]='\0';
+
+   //find value
+   if((start_p = kstrstr(buf2,"="))==NULL)
+      return FALSE;
+   memset(buf1,0,100);
+   strcpy(buf1,start_p+1);
+
+  //except space
+  tmp_p = buf1;
+  while(*tmp_p != 0x00) {
+  	if(*tmp_p==' ')
+	    tmp_p++;
+         else
+	  break;
+  }
+
+   memcpy(dest,tmp_p,strlen(tmp_p));
+ return TRUE;
+}
+
+//if read fail,return NULL,or return data pointer;
+static UCHAR *Config_FileOperation(PSDevice pDevice) {
+    UCHAR    *config_path=CONFIG_PATH;
+    UCHAR    *buffer=NULL;
+    struct file   *filp=NULL;
+    mm_segment_t old_fs = get_fs();
+    //int oldfsuid=0,oldfsgid=0;
+    int result=0;
+
+    set_fs (KERNEL_DS);
+    /* Can't do this anymore, so we rely on correct filesystem permissions:
+    //Make sure a caller can read or write power as root
+    oldfsuid=current->fsuid;
+    oldfsgid=current->fsgid;
+    current->fsuid = 0;
+    current->fsgid = 0;
+    */
+
+    //open file
+      filp = filp_open(config_path, O_RDWR, 0);
+        if (IS_ERR(filp)) {
+	     printk("Config_FileOperation file Not exist\n");
+	     result=-1;
+             goto error2;
+	  }
+
+     if(!(filp->f_op) || !(filp->f_op->read) ||!(filp->f_op->write)) {
+           printk("file %s cann't readable or writable?\n",config_path);
+	  result = -1;
+	  goto error1;
+     	}
+
+    buffer = (UCHAR *)kmalloc(1024, GFP_KERNEL);
+    if(buffer==NULL) {
+      printk("alllocate mem for file fail?\n");
+      result = -1;
+      goto error1;
+    }
+
+    if(filp->f_op->read(filp, buffer, 1024, &filp->f_pos)<0) {
+     printk("read file error?\n");
+     result = -1;
+    }
+
+error1:
+  if(filp_close(filp,NULL))
+       printk("Config_FileOperation:close file fail\n");
+
+error2:
+  set_fs (old_fs);
+
+  /*
+  current->fsuid=oldfsuid;
+  current->fsgid=oldfsgid;
+  */
+
+if(result!=0) {
+    if(buffer)
+  	 kfree(buffer);
+    buffer=NULL;
+}
+  return buffer;
+}
+
+//return --->-1:fail;  >=0:sucessful
+static int Read_config_file(PSDevice pDevice) {
+  int result=0;
+  UCHAR      tmpbuffer[100];
+  UCHAR *buffer=NULL;
+
+  //init config setting
+ pDevice->config_file.ZoneType = -1;
+ pDevice->config_file.eAuthenMode = -1;
+ pDevice->config_file.eEncryptionStatus = -1;
+
+  if((buffer=Config_FileOperation(pDevice)) ==NULL) {
+     result =-1;
+     return result;
+  }
+
+//get zonetype
+{
+    memset(tmpbuffer,0,sizeof(tmpbuffer));
+    if(Config_FileGetParameter("ZONETYPE",tmpbuffer,buffer) ==TRUE) {
+    if(memcmp(tmpbuffer,"USA",3)==0) {
+      pDevice->config_file.ZoneType=ZoneType_USA;
+    }
+    else if(memcmp(tmpbuffer,"JAPAN",5)==0) {
+      pDevice->config_file.ZoneType=ZoneType_Japan;
+    }
+    else if(memcmp(tmpbuffer,"EUROPE",6)==0) {
+     pDevice->config_file.ZoneType=ZoneType_Europe;
+    }
+    else {
+      printk("Unknown Zonetype[%s]?\n",tmpbuffer);
+   }
+ }
+}
+
+#if 1
+//get other parameter
+  {
+	memset(tmpbuffer,0,sizeof(tmpbuffer));
+       if(Config_FileGetParameter("AUTHENMODE",tmpbuffer,buffer)==TRUE) {
+	 pDevice->config_file.eAuthenMode = (int) simple_strtol(tmpbuffer, NULL, 10);
+       }
+
+	memset(tmpbuffer,0,sizeof(tmpbuffer));
+       if(Config_FileGetParameter("ENCRYPTIONMODE",tmpbuffer,buffer)==TRUE) {
+	 pDevice->config_file.eEncryptionStatus= (int) simple_strtol(tmpbuffer, NULL, 10);
+       }
+  }
+#endif
+
+  kfree(buffer);
+  return result;
+}
+
+static void device_set_multi(struct net_device *dev) {
+    PSDevice         pDevice = (PSDevice) netdev_priv(dev);
+    PSMgmtObject     pMgmt = &(pDevice->sMgmtObj);
+    u32              mc_filter[2];
+    int              ii;
+    struct dev_mc_list  *mclist;
+    BYTE             pbyData[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+    BYTE             byTmpMode = 0;
+    int              rc;
+
+
+	spin_lock_irq(&pDevice->lock);
+    rc = CONTROLnsRequestIn(pDevice,
+                            MESSAGE_TYPE_READ,
+                            MAC_REG_RCR,
+                            MESSAGE_REQUEST_MACREG,
+                            1,
+                            &byTmpMode
+                            );
+    if (rc == 0) pDevice->byRxMode = byTmpMode;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode in= %x\n", pDevice->byRxMode);
+
+    if (dev->flags & IFF_PROMISC) {         // Set promiscuous.
+        DBG_PRT(MSG_LEVEL_ERR,KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+        // Unconditionally log net taps.
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST|RCR_UNICAST);
+    }
+    else if ((dev->mc_count > pDevice->multicast_limit) || (dev->flags & IFF_ALLMULTI)) {
+        CONTROLnsRequestOut(pDevice,
+                            MESSAGE_TYPE_WRITE,
+                            MAC_REG_MAR0,
+                            MESSAGE_REQUEST_MACREG,
+                            8,
+                            pbyData
+                            );
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+    }
+    else {
+        memset(mc_filter, 0, sizeof(mc_filter));
+        for (ii = 0, mclist = dev->mc_list; mclist && ii < dev->mc_count;
+             ii++, mclist = mclist->next) {
+            int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+            mc_filter[bit_nr >> 5] |= cpu_to_le32(1 << (bit_nr & 31));
+        }
+        for (ii = 0; ii < 4; ii++) {
+             MACvWriteMultiAddr(pDevice, ii, *((PBYTE)&mc_filter[0] + ii));
+             MACvWriteMultiAddr(pDevice, ii+ 4, *((PBYTE)&mc_filter[1] + ii));
+        }
+        pDevice->byRxMode &= ~(RCR_UNICAST);
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+    }
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        // If AP mode, don't enable RCR_UNICAST. Since hw only compare addr1 with local mac.
+        pDevice->byRxMode |= (RCR_MULTICAST|RCR_BROADCAST);
+        pDevice->byRxMode &= ~(RCR_UNICAST);
+    }
+    ControlvWriteByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_RCR, pDevice->byRxMode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode out= %x\n", pDevice->byRxMode);
+	spin_unlock_irq(&pDevice->lock);
+
+}
+
+
+static struct net_device_stats *device_get_stats(struct net_device *dev) {
+    PSDevice pDevice=(PSDevice) netdev_priv(dev);
+
+    return &pDevice->stats;
+}
+
+
+static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) {
+	PSDevice	        pDevice = (PSDevice)netdev_priv(dev);
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PSCmdRequest        pReq;
+    //BOOL                bCommit = FALSE;
+	struct iwreq *wrq = (struct iwreq *) rq;
+	int                 rc =0;
+
+    if (pMgmt == NULL) {
+        rc = -EFAULT;
+        return rc;
+    }
+
+    switch(cmd) {
+
+	case SIOCGIWNAME:
+		rc = iwctl_giwname(dev, NULL, (char *)&(wrq->u.name), NULL);
+		break;
+
+	case SIOCSIWNWID:
+        rc = -EOPNOTSUPP;
+		break;
+
+	case SIOCGIWNWID:     //0x8b03  support
+	#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+          rc = iwctl_giwnwid(dev, NULL, &(wrq->u.nwid), NULL);
+	#else
+        rc = -EOPNOTSUPP;
+	#endif
+		break;
+
+		// Set frequency/channel
+	case SIOCSIWFREQ:
+	    rc = iwctl_siwfreq(dev, NULL, &(wrq->u.freq), NULL);
+		break;
+
+		// Get frequency/channel
+	case SIOCGIWFREQ:
+		rc = iwctl_giwfreq(dev, NULL, &(wrq->u.freq), NULL);
+		break;
+
+		// Set desired network name (ESSID)
+	case SIOCSIWESSID:
+
+		{
+			char essid[IW_ESSID_MAX_SIZE+1];
+			if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) {
+				rc = -E2BIG;
+				break;
+			}
+			if (copy_from_user(essid, wrq->u.essid.pointer,
+					   wrq->u.essid.length)) {
+				rc = -EFAULT;
+				break;
+			}
+			rc = iwctl_siwessid(dev, NULL,
+					    &(wrq->u.essid), essid);
+		}
+		break;
+
+
+		// Get current network name (ESSID)
+	case SIOCGIWESSID:
+
+		{
+			char essid[IW_ESSID_MAX_SIZE+1];
+			if (wrq->u.essid.pointer)
+				rc = iwctl_giwessid(dev, NULL,
+						    &(wrq->u.essid), essid);
+				if (copy_to_user(wrq->u.essid.pointer,
+						         essid,
+						         wrq->u.essid.length) )
+					rc = -EFAULT;
+		}
+		break;
+
+	case SIOCSIWAP:
+
+		rc = iwctl_siwap(dev, NULL, &(wrq->u.ap_addr), NULL);
+		break;
+
+
+		// Get current Access Point (BSSID)
+	case SIOCGIWAP:
+		rc = iwctl_giwap(dev, NULL, &(wrq->u.ap_addr), NULL);
+		break;
+
+
+		// Set desired station name
+	case SIOCSIWNICKN:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+		// Get current station name
+	case SIOCGIWNICKN:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+		// Set the desired bit-rate
+	case SIOCSIWRATE:
+		rc = iwctl_siwrate(dev, NULL, &(wrq->u.bitrate), NULL);
+		break;
+
+	// Get the current bit-rate
+	case SIOCGIWRATE:
+
+		rc = iwctl_giwrate(dev, NULL, &(wrq->u.bitrate), NULL);
+		break;
+
+	// Set the desired RTS threshold
+	case SIOCSIWRTS:
+
+		rc = iwctl_siwrts(dev, NULL, &(wrq->u.rts), NULL);
+		break;
+
+	// Get the current RTS threshold
+	case SIOCGIWRTS:
+
+		rc = iwctl_giwrts(dev, NULL, &(wrq->u.rts), NULL);
+		break;
+
+		// Set the desired fragmentation threshold
+	case SIOCSIWFRAG:
+
+		rc = iwctl_siwfrag(dev, NULL, &(wrq->u.frag), NULL);
+	    break;
+
+	// Get the current fragmentation threshold
+	case SIOCGIWFRAG:
+
+		rc = iwctl_giwfrag(dev, NULL, &(wrq->u.frag), NULL);
+		break;
+
+		// Set mode of operation
+	case SIOCSIWMODE:
+    	rc = iwctl_siwmode(dev, NULL, &(wrq->u.mode), NULL);
+		break;
+
+		// Get mode of operation
+	case SIOCGIWMODE:
+		rc = iwctl_giwmode(dev, NULL, &(wrq->u.mode), NULL);
+		break;
+
+		// Set WEP keys and mode
+	case SIOCSIWENCODE:
+		{
+            char abyKey[WLAN_WEP232_KEYLEN];
+
+			if (wrq->u.encoding.pointer) {
+
+
+				if (wrq->u.encoding.length > WLAN_WEP232_KEYLEN) {
+					rc = -E2BIG;
+					break;
+				}
+				memset(abyKey, 0, WLAN_WEP232_KEYLEN);
+				if (copy_from_user(abyKey,
+				                  wrq->u.encoding.pointer,
+				                  wrq->u.encoding.length)) {
+					rc = -EFAULT;
+					break;
+				}
+			} else if (wrq->u.encoding.length != 0) {
+				rc = -EINVAL;
+				break;
+			}
+			rc = iwctl_siwencode(dev, NULL, &(wrq->u.encoding), abyKey);
+		}
+		break;
+
+		// Get the WEP keys and mode
+	case SIOCGIWENCODE:
+
+		if (!capable(CAP_NET_ADMIN)) {
+			rc = -EPERM;
+			break;
+		}
+		{
+		    char abyKey[WLAN_WEP232_KEYLEN];
+
+		    rc = iwctl_giwencode(dev, NULL, &(wrq->u.encoding), abyKey);
+		    if (rc != 0) break;
+			if (wrq->u.encoding.pointer) {
+				if (copy_to_user(wrq->u.encoding.pointer,
+						        abyKey,
+						        wrq->u.encoding.length))
+					rc = -EFAULT;
+			}
+		}
+		break;
+
+		// Get the current Tx-Power
+	case SIOCGIWTXPOW:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+	case SIOCSIWTXPOW:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW \n");
+        rc = -EOPNOTSUPP;
+		break;
+
+	case SIOCSIWRETRY:
+
+		rc = iwctl_siwretry(dev, NULL, &(wrq->u.retry), NULL);
+		break;
+
+	case SIOCGIWRETRY:
+
+		rc = iwctl_giwretry(dev, NULL, &(wrq->u.retry), NULL);
+		break;
+
+		// Get range of parameters
+	case SIOCGIWRANGE:
+
+		{
+			struct iw_range range;
+
+			rc = iwctl_giwrange(dev, NULL, &(wrq->u.data), (char *) &range);
+			if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
+				rc = -EFAULT;
+		}
+
+		break;
+
+	case SIOCGIWPOWER:
+
+		rc = iwctl_giwpower(dev, NULL, &(wrq->u.power), NULL);
+		break;
+
+
+	case SIOCSIWPOWER:
+
+		rc = iwctl_siwpower(dev, NULL, &(wrq->u.power), NULL);
+		break;
+
+
+	case SIOCGIWSENS:
+
+	    rc = iwctl_giwsens(dev, NULL, &(wrq->u.sens), NULL);
+		break;
+
+	case SIOCSIWSENS:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS \n");
+		rc = -EOPNOTSUPP;
+		break;
+
+	case SIOCGIWAPLIST:
+	    {
+            char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
+
+		    if (wrq->u.data.pointer) {
+		        rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
+		        if (rc == 0) {
+                    if (copy_to_user(wrq->u.data.pointer,
+					                buffer,
+					               (wrq->u.data.length * (sizeof(struct sockaddr) +  sizeof(struct iw_quality)))
+				        ))
+				    rc = -EFAULT;
+		        }
+            }
+        }
+		break;
+
+
+#ifdef WIRELESS_SPY
+		// Set the spy list
+	case SIOCSIWSPY:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+		rc = -EOPNOTSUPP;
+		break;
+
+		// Get the spy list
+	case SIOCGIWSPY:
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY \n");
+		rc = -EOPNOTSUPP;
+		break;
+
+#endif // WIRELESS_SPY
+
+	case SIOCGIWPRIV:
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV \n");
+		rc = -EOPNOTSUPP;
+/*
+		if(wrq->u.data.pointer) {
+			wrq->u.data.length = sizeof(iwctl_private_args) / sizeof( iwctl_private_args[0]);
+
+			if(copy_to_user(wrq->u.data.pointer,
+					(u_char *) iwctl_private_args,
+					sizeof(iwctl_private_args)))
+				rc = -EFAULT;
+		}
+*/
+		break;
+
+
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	case SIOCSIWAUTH:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH \n");
+		rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL);
+		break;
+
+	case SIOCGIWAUTH:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH \n");
+		rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL);
+		break;
+
+	case SIOCSIWGENIE:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE \n");
+		rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
+		break;
+
+	case SIOCGIWGENIE:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE \n");
+		rc = iwctl_giwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
+		break;
+
+	case SIOCSIWENCODEEXT:
+		{
+			char extra[sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1];
+			DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT \n");
+			if(wrq->u.encoding.pointer){
+				memset(extra, 0, sizeof(struct iw_encode_ext)+MAX_KEY_LEN+1);
+				if(wrq->u.encoding.length > (sizeof(struct iw_encode_ext)+ MAX_KEY_LEN)){
+					rc = -E2BIG;
+					break;
+				}
+				if(copy_from_user(extra, wrq->u.encoding.pointer,wrq->u.encoding.length)){
+					rc = -EFAULT;
+					break;
+				}
+			}else if(wrq->u.encoding.length != 0){
+				rc = -EINVAL;
+				break;
+			}
+			rc = iwctl_siwencodeext(dev, NULL, &(wrq->u.encoding), extra);
+		}
+		break;
+
+	case SIOCGIWENCODEEXT:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT \n");
+		rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL);
+		break;
+
+	case SIOCSIWMLME:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME \n");
+		rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer);
+		break;
+
+#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//End Add -- //2008-0409-07, <Add> by Einsn Liu
+
+    case IOCTL_CMD_TEST:
+
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+        pReq = (PSCmdRequest)rq;
+
+   //20080130-01,<Remark> by Mike Liu
+      // if(pDevice->bLinkPass==TRUE)
+          pReq->wResult = MAGIC_CODE;         //Linking status:0x3142
+   //20080130-02,<Remark> by Mike Liu
+      //  else
+      //	 pReq->wResult = MAGIC_CODE+1;    //disconnect status:0x3143
+        break;
+
+    case IOCTL_CMD_SET:
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED) &&
+		       (((PSCmdRequest)rq)->wCmdCode !=WLAN_CMD_SET_WPA))
+		{
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+
+	    if (test_and_set_bit( 0, (void*)&(pMgmt->uCmdBusy))) {
+		    return -EBUSY;
+	    }
+        rc = private_ioctl(pDevice, rq);
+        clear_bit( 0, (void*)&(pMgmt->uCmdBusy));
+        break;
+
+    case IOCTL_CMD_HOSTAPD:
+
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+
+		rc = hostap_ioctl(pDevice, &wrq->u.data);
+        break;
+
+    case IOCTL_CMD_WPA:
+
+		if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) {
+		    rc = -EFAULT;
+		    break;
+		} else {
+		    rc = 0;
+		}
+
+		rc = wpa_ioctl(pDevice, &wrq->u.data);
+        break;
+
+	case SIOCETHTOOL:
+        return ethtool_ioctl(dev, (void *) rq->ifr_data);
+	// All other calls are currently unsupported
+
+	default:
+		rc = -EOPNOTSUPP;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd);
+
+
+    }
+
+    if (pDevice->bCommit) {
+       if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+           netif_stop_queue(pDevice->dev);
+           spin_lock_irq(&pDevice->lock);
+           bScheduleCommand((HANDLE)pDevice, WLAN_CMD_RUN_AP, NULL);
+           spin_unlock_irq(&pDevice->lock);
+       }
+       else {
+           DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n");
+           spin_lock_irq(&pDevice->lock);
+//2007-1121-01<Modify>by EinsnLiu
+	    if (pDevice->bLinkPass&&
+		  memcmp(pMgmt->abyCurrSSID,pMgmt->abyDesireSSID,WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN)) {
+      		  bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+	     } else {
+           pDevice->bLinkPass = FALSE;
+	   pMgmt->eCurrState = WMAC_STATE_IDLE;
+	   memset(pMgmt->abyCurrBSSID, 0, 6);
+		 }
+           ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+//End Modify
+           netif_stop_queue(pDevice->dev);
+#ifdef  WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+           pMgmt->eScanType = WMAC_SCAN_ACTIVE;
+           if(pDevice->bWPASuppWextEnabled !=TRUE)
+#endif
+           bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+           bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+           spin_unlock_irq(&pDevice->lock);
+      }
+      pDevice->bCommit = FALSE;
+    }
+
+
+    return rc;
+}
+
+
+static int ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	u32 ethcmd;
+
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+	case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strncpy(info.driver, DEVICE_NAME, sizeof(info.driver)-1);
+		strncpy(info.version, DEVICE_VERSION, sizeof(info.version)-1);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+
+	return -EOPNOTSUPP;
+}
+
+
+/*------------------------------------------------------------------*/
+
+
+MODULE_DEVICE_TABLE(usb, vntwusb_table);
+
+
+static struct usb_driver vntwusb_driver = {
+	    .name =		DEVICE_NAME,
+	    .probe =	vntwusb_found1,
+	    .disconnect =	vntwusb_disconnect,
+	    .id_table =	vntwusb_table,
+
+//2008-0920-01<Add>by MikeLiu
+//for supporting S3 & S4 function
+#ifdef CONFIG_PM
+	   .suspend = vntwusb_suspend,
+	   .resume = vntwusb_resume,
+#endif
+};
+
+static int __init vntwusb_init_module(void)
+{
+    printk(KERN_NOTICE DEVICE_FULL_DRV_NAM " " DEVICE_VERSION);
+    return usb_register(&vntwusb_driver);
+}
+
+static void __exit vntwusb_cleanup_module(void)
+{
+	usb_deregister(&vntwusb_driver);
+}
+
+module_init(vntwusb_init_module);
+module_exit(vntwusb_cleanup_module);
+
diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c
new file mode 100644
index 0000000..910e610
--- /dev/null
+++ b/drivers/staging/vt6656/mib.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: mib.c
+ *
+ * Purpose: Implement MIB Data Structure
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *      STAvClearAllCounter - Clear All MIB Counter
+ *      STAvUpdateIstStatCounter - Update ISR statistic counter
+ *      STAvUpdateRDStatCounter - Update Rx statistic counter
+ *      STAvUpdateRDStatCounterEx - Update Rx statistic counter and copy rcv data
+ *      STAvUpdateTDStatCounter - Update Tx statistic counter
+ *      STAvUpdateTDStatCounterEx - Update Tx statistic counter and copy tx data
+ *      STAvUpdate802_11Counter - Update 802.11 mib counter
+ *
+ * Revision History:
+ *
+ */
+
+#include "upc.h"
+#include "mac.h"
+#include "tether.h"
+#include "mib.h"
+#include "wctl.h"
+#include "baseband.h"
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+/*
+ * Description: Clear All Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic  - Pointer to Statistic Counter Data Structure
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void STAvClearAllCounter (PSStatCounter pStatistic)
+{
+    // set memory to zero
+	memset(pStatistic, 0, sizeof(SStatCounter));
+}
+
+
+/*
+ * Description: Update Isr Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic  - Pointer to Statistic Counter Data Structure
+ *      wisr        - Interrupt status
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr1)
+{
+    /**********************/
+    /* ABNORMAL interrupt */
+    /**********************/
+    // not any IMR bit invoke irq
+    if (byIsr0 == 0) {
+        pStatistic->ISRStat.dwIsrUnknown++;
+        return;
+    }
+
+
+    if (byIsr0 & ISR_ACTX)              // ISR, bit0
+        pStatistic->ISRStat.dwIsrTx0OK++;           // TXDMA0 successful
+
+    if (byIsr0 & ISR_BNTX)              // ISR, bit2
+        pStatistic->ISRStat.dwIsrBeaconTxOK++;      // BeaconTx successful
+
+    if (byIsr0 & ISR_RXDMA0)            // ISR, bit3
+        pStatistic->ISRStat.dwIsrRx0OK++;           // Rx0 successful
+
+    if (byIsr0 & ISR_TBTT)              // ISR, bit4
+        pStatistic->ISRStat.dwIsrTBTTInt++;         // TBTT successful
+
+    if (byIsr0 & ISR_SOFTTIMER)         // ISR, bit6
+        pStatistic->ISRStat.dwIsrSTIMERInt++;
+
+    if (byIsr0 & ISR_WATCHDOG)          // ISR, bit7
+        pStatistic->ISRStat.dwIsrWatchDog++;
+
+
+    if (byIsr1 & ISR_FETALERR)              // ISR, bit8
+        pStatistic->ISRStat.dwIsrUnrecoverableError++;
+
+    if (byIsr1 & ISR_SOFTINT)               // ISR, bit9
+        pStatistic->ISRStat.dwIsrSoftInterrupt++;       // software interrupt
+
+    if (byIsr1 & ISR_MIBNEARFULL)           // ISR, bit10
+        pStatistic->ISRStat.dwIsrMIBNearfull++;
+
+    if (byIsr1 & ISR_RXNOBUF)               // ISR, bit11
+        pStatistic->ISRStat.dwIsrRxNoBuf++;             // Rx No Buff
+
+}
+
+
+/*
+ * Description: Update Rx Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      byRSR           - Rx Status
+ *      byNewRSR        - Rx Status
+ *      pbyBuffer       - Rx Buffer
+ *      cbFrameLength   - Rx Length
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void STAvUpdateRDStatCounter (PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength)
+{
+    //need change
+    PS802_11Header pHeader = (PS802_11Header)pbyBuffer;
+
+    if (byRSR & RSR_ADDROK)
+        pStatistic->dwRsrADDROk++;
+    if (byRSR & RSR_CRCOK) {
+        pStatistic->dwRsrCRCOk++;
+
+        pStatistic->ullRsrOK++;
+
+        if (cbFrameLength >= U_ETHER_ADDR_LEN) {
+            // update counters in case that successful transmit
+            if (byRSR & RSR_ADDRBROAD) {
+                pStatistic->ullRxBroadcastFrames++;
+                pStatistic->ullRxBroadcastBytes += (ULONGLONG)cbFrameLength;
+            }
+            else if (byRSR & RSR_ADDRMULTI) {
+                pStatistic->ullRxMulticastFrames++;
+                pStatistic->ullRxMulticastBytes += (ULONGLONG)cbFrameLength;
+            }
+            else {
+                pStatistic->ullRxDirectedFrames++;
+                pStatistic->ullRxDirectedBytes += (ULONGLONG)cbFrameLength;
+            }
+        }
+    }
+
+    if(byRxRate==22) {
+        pStatistic->CustomStat.ullRsr11M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr11MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"11M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr11M, (INT)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR);
+    }
+    else if(byRxRate==11) {
+        pStatistic->CustomStat.ullRsr5M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr5MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 5M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr5M, (INT)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR);
+    }
+    else if(byRxRate==4) {
+        pStatistic->CustomStat.ullRsr2M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr2MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 2M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr2M, (INT)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR);
+    }
+    else if(byRxRate==2){
+        pStatistic->CustomStat.ullRsr1M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr1MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 1M: ALL[%d], OK[%d]:[%02x]\n", (INT)pStatistic->CustomStat.ullRsr1M, (INT)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR);
+    }
+    else if(byRxRate==12){
+        pStatistic->CustomStat.ullRsr6M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr6MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 6M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr6M, (INT)pStatistic->CustomStat.ullRsr6MCRCOk);
+    }
+    else if(byRxRate==18){
+        pStatistic->CustomStat.ullRsr9M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr9MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" 9M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr9M, (INT)pStatistic->CustomStat.ullRsr9MCRCOk);
+    }
+    else if(byRxRate==24){
+        pStatistic->CustomStat.ullRsr12M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr12MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"12M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr12M, (INT)pStatistic->CustomStat.ullRsr12MCRCOk);
+    }
+    else if(byRxRate==36){
+        pStatistic->CustomStat.ullRsr18M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr18MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"18M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr18M, (INT)pStatistic->CustomStat.ullRsr18MCRCOk);
+    }
+    else if(byRxRate==48){
+        pStatistic->CustomStat.ullRsr24M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr24MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"24M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr24M, (INT)pStatistic->CustomStat.ullRsr24MCRCOk);
+    }
+    else if(byRxRate==72){
+        pStatistic->CustomStat.ullRsr36M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr36MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"36M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr36M, (INT)pStatistic->CustomStat.ullRsr36MCRCOk);
+    }
+    else if(byRxRate==96){
+        pStatistic->CustomStat.ullRsr48M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr48MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"48M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr48M, (INT)pStatistic->CustomStat.ullRsr48MCRCOk);
+    }
+    else if(byRxRate==108){
+        pStatistic->CustomStat.ullRsr54M++;
+        if(byRSR & RSR_CRCOK) {
+            pStatistic->CustomStat.ullRsr54MCRCOk++;
+        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"54M: ALL[%d], OK[%d]\n", (INT)pStatistic->CustomStat.ullRsr54M, (INT)pStatistic->CustomStat.ullRsr54MCRCOk);
+    }
+    else {
+    	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown: Total[%d], CRCOK[%d]\n", (INT)pStatistic->dwRsrRxPacket+1, (INT)pStatistic->dwRsrCRCOk);
+    }
+
+    if (byRSR & RSR_BSSIDOK)
+        pStatistic->dwRsrBSSIDOk++;
+
+    if (byRSR & RSR_BCNSSIDOK)
+        pStatistic->dwRsrBCNSSIDOk++;
+    if (byRSR & RSR_IVLDLEN)  //invalid len (> 2312 byte)
+        pStatistic->dwRsrLENErr++;
+    if (byRSR & RSR_IVLDTYP)  //invalid packet type
+        pStatistic->dwRsrTYPErr++;
+    if ((byRSR & (RSR_IVLDTYP | RSR_IVLDLEN)) || !(byRSR & RSR_CRCOK))
+        pStatistic->dwRsrErr++;
+
+    if (byNewRSR & NEWRSR_DECRYPTOK)
+        pStatistic->dwNewRsrDECRYPTOK++;
+    if (byNewRSR & NEWRSR_CFPIND)
+        pStatistic->dwNewRsrCFP++;
+    if (byNewRSR & NEWRSR_HWUTSF)
+        pStatistic->dwNewRsrUTSF++;
+    if (byNewRSR & NEWRSR_BCNHITAID)
+        pStatistic->dwNewRsrHITAID++;
+    if (byNewRSR & NEWRSR_BCNHITAID0)
+        pStatistic->dwNewRsrHITAID0++;
+
+    // increase rx packet count
+    pStatistic->dwRsrRxPacket++;
+    pStatistic->dwRsrRxOctet += cbFrameLength;
+
+
+    if (IS_TYPE_DATA(pbyBuffer)) {
+        pStatistic->dwRsrRxData++;
+    } else if (IS_TYPE_MGMT(pbyBuffer)){
+        pStatistic->dwRsrRxManage++;
+    } else if (IS_TYPE_CONTROL(pbyBuffer)){
+        pStatistic->dwRsrRxControl++;
+    }
+
+    if (byRSR & RSR_ADDRBROAD)
+        pStatistic->dwRsrBroadcast++;
+    else if (byRSR & RSR_ADDRMULTI)
+        pStatistic->dwRsrMulticast++;
+    else
+        pStatistic->dwRsrDirected++;
+
+    if (WLAN_GET_FC_MOREFRAG(pHeader->wFrameCtl))
+        pStatistic->dwRsrRxFragment++;
+
+    if (cbFrameLength < MIN_PACKET_LEN + 4) {
+        pStatistic->dwRsrRunt++;
+    }
+    else if (cbFrameLength == MIN_PACKET_LEN + 4) {
+        pStatistic->dwRsrRxFrmLen64++;
+    }
+    else if ((65 <= cbFrameLength) && (cbFrameLength <= 127)) {
+        pStatistic->dwRsrRxFrmLen65_127++;
+    }
+    else if ((128 <= cbFrameLength) && (cbFrameLength <= 255)) {
+        pStatistic->dwRsrRxFrmLen128_255++;
+    }
+    else if ((256 <= cbFrameLength) && (cbFrameLength <= 511)) {
+        pStatistic->dwRsrRxFrmLen256_511++;
+    }
+    else if ((512 <= cbFrameLength) && (cbFrameLength <= 1023)) {
+        pStatistic->dwRsrRxFrmLen512_1023++;
+    }
+    else if ((1024 <= cbFrameLength) && (cbFrameLength <= MAX_PACKET_LEN + 4)) {
+        pStatistic->dwRsrRxFrmLen1024_1518++;
+    } else if (cbFrameLength > MAX_PACKET_LEN + 4) {
+        pStatistic->dwRsrLong++;
+    }
+
+}
+
+
+
+/*
+ * Description: Update Rx Statistic Counter and copy Rx buffer
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      byRSR           - Rx Status
+ *      byNewRSR        - Rx Status
+ *      pbyBuffer       - Rx Buffer
+ *      cbFrameLength   - Rx Length
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+void
+STAvUpdateRDStatCounterEx (
+    PSStatCounter   pStatistic,
+    BYTE            byRSR,
+    BYTE            byNewRSR,
+    BYTE            byRxSts,
+    BYTE            byRxRate,
+    PBYTE           pbyBuffer,
+    UINT            cbFrameLength
+    )
+{
+    STAvUpdateRDStatCounter(
+                    pStatistic,
+                    byRSR,
+                    byNewRSR,
+                    byRxSts,
+                    byRxRate,
+                    pbyBuffer,
+                    cbFrameLength
+                    );
+
+    // rx length
+    pStatistic->dwCntRxFrmLength = cbFrameLength;
+    // rx pattern, we just see 10 bytes for sample
+    memcpy(pStatistic->abyCntRxPattern, (PBYTE)pbyBuffer, 10);
+}
+
+
+/*
+ * Description: Update Tx Statistic Counter
+ *
+ * Parameters:
+ *  In:
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      byTSR0          - Tx Status
+ *      byTSR1          - Tx Status
+ *      pbyBuffer       - Tx Buffer
+ *      cbFrameLength   - Tx Length
+ *      uIdx            - Index of Tx DMA
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvUpdateTDStatCounter (
+    PSStatCounter   pStatistic,
+    BYTE            byPktNum,
+    BYTE            byRate,
+    BYTE            byTSR
+    )
+{
+    BYTE    byRetyCnt;
+    // increase tx packet count
+    pStatistic->dwTsrTxPacket++;
+
+    byRetyCnt = (byTSR & 0xF0) >> 4;
+    if (byRetyCnt != 0) {
+        pStatistic->dwTsrRetry++;
+        pStatistic->dwTsrTotalRetry += byRetyCnt;
+        pStatistic->dwTxFail[byRate]+= byRetyCnt;
+        pStatistic->dwTxFail[MAX_RATE] += byRetyCnt;
+
+        if ( byRetyCnt == 0x1)
+            pStatistic->dwTsrOnceRetry++;
+        else
+            pStatistic->dwTsrMoreThanOnceRetry++;
+
+        if (byRetyCnt <= 8)
+            pStatistic->dwTxRetryCount[byRetyCnt-1]++;
+
+    }
+    if ( !(byTSR & (TSR_TMO | TSR_RETRYTMO))) {
+
+#ifdef Calcu_LinkQual
+   if (byRetyCnt < 2)
+        pStatistic->TxNoRetryOkCount ++;
+   else
+        pStatistic->TxRetryOkCount ++;
+#endif
+
+        pStatistic->ullTsrOK++;
+        pStatistic->CustomStat.ullTsrAllOK++;
+        // update counters in case that successful transmit
+        pStatistic->dwTxOk[byRate]++;
+        pStatistic->dwTxOk[MAX_RATE]++;
+
+        if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD )  {
+            pStatistic->ullTxBroadcastFrames++;
+            pStatistic->ullTxBroadcastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+        } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) {
+            pStatistic->ullTxMulticastFrames++;
+            pStatistic->ullTxMulticastBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+        } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) {
+            pStatistic->ullTxDirectedFrames++;
+            pStatistic->ullTxDirectedBytes += pStatistic->abyTxPktInfo[byPktNum].wLength;
+        }
+    }
+    else {
+
+#ifdef Calcu_LinkQual
+        pStatistic->TxFailCount ++;
+#endif
+
+        pStatistic->dwTsrErr++;
+        if (byTSR & TSR_RETRYTMO)
+            pStatistic->dwTsrRetryTimeout++;
+        if (byTSR & TSR_TMO)
+            pStatistic->dwTsrTransmitTimeout++;
+    }
+
+    if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_BROAD )  {
+        pStatistic->dwTsrBroadcast++;
+    } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_MULTI ) {
+        pStatistic->dwTsrMulticast++;
+    } else if ( pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni == TX_PKT_UNI ) {
+        pStatistic->dwTsrDirected++;
+    }
+}
+
+
+
+/*
+ * Description: Update 802.11 mib counter
+ *
+ * Parameters:
+ *  In:
+ *      p802_11Counter  - Pointer to 802.11 mib counter
+ *      pStatistic      - Pointer to Statistic Counter Data Structure
+ *      dwCounter       - hardware counter for 802.11 mib
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvUpdate802_11Counter(
+    PSDot11Counters         p802_11Counter,
+    PSStatCounter           pStatistic,
+    BYTE                    byRTSSuccess,
+    BYTE                    byRTSFail,
+    BYTE                    byACKFail,
+    BYTE                    byFCSErr
+    )
+{
+    //p802_11Counter->TransmittedFragmentCount
+    p802_11Counter->MulticastTransmittedFrameCount = (ULONGLONG) (pStatistic->dwTsrBroadcast +
+                                                                  pStatistic->dwTsrMulticast);
+    p802_11Counter->FailedCount = (ULONGLONG) (pStatistic->dwTsrErr);
+    p802_11Counter->RetryCount = (ULONGLONG) (pStatistic->dwTsrRetry);
+    p802_11Counter->MultipleRetryCount = (ULONGLONG) (pStatistic->dwTsrMoreThanOnceRetry);
+    //p802_11Counter->FrameDuplicateCount
+    p802_11Counter->RTSSuccessCount += (ULONGLONG) byRTSSuccess;
+    p802_11Counter->RTSFailureCount += (ULONGLONG) byRTSFail;
+    p802_11Counter->ACKFailureCount += (ULONGLONG) byACKFail;
+    p802_11Counter->FCSErrorCount +=   (ULONGLONG) byFCSErr;
+    //p802_11Counter->ReceivedFragmentCount
+    p802_11Counter->MulticastReceivedFrameCount = (ULONGLONG) (pStatistic->dwRsrBroadcast +
+                                                               pStatistic->dwRsrMulticast);
+}
+
+/*
+ * Description: Clear 802.11 mib counter
+ *
+ * Parameters:
+ *  In:
+ *      p802_11Counter  - Pointer to 802.11 mib counter
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+void
+STAvClear802_11Counter(PSDot11Counters p802_11Counter)
+{
+    // set memory to zero
+	memset(p802_11Counter, 0, sizeof(SDot11Counters));
+}
+
+/*
+ * Description: Clear 802.11 mib counter
+ *
+ * Parameters:
+ *  In:
+ *      pUsbCounter  - Pointer to USB mib counter
+ *      ntStatus - URB status
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+
+void
+STAvUpdateUSBCounter(PSUSBCounter pUsbCounter,
+                     NTSTATUS ntStatus
+                     )
+{
+
+//    if ( ntStatus == USBD_STATUS_CRC ) {
+        pUsbCounter->dwCrc++;
+//    }
+
+}
+
+
diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h
new file mode 100644
index 0000000..b806b4d
--- /dev/null
+++ b/drivers/staging/vt6656/mib.h
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: mib.h
+ *
+ * Purpose: Implement MIB Data Structure
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __MIB_H__
+#define __MIB_H__
+
+#include "ttype.h"
+#include "tether.h"
+#include "desc.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+//
+// USB counter
+//
+typedef struct tagSUSBCounter {
+    DWORD dwCrc;
+
+} SUSBCounter, *PSUSBCounter;
+
+
+
+//
+// 802.11 counter
+//
+
+
+typedef struct tagSDot11Counters {
+//    ULONG       Length;             // Length of structure
+    ULONGLONG   TransmittedFragmentCount;
+    ULONGLONG   MulticastTransmittedFrameCount;
+    ULONGLONG   FailedCount;
+    ULONGLONG   RetryCount;
+    ULONGLONG   MultipleRetryCount;
+    ULONGLONG   RTSSuccessCount;
+    ULONGLONG   RTSFailureCount;
+    ULONGLONG   ACKFailureCount;
+    ULONGLONG   FrameDuplicateCount;
+    ULONGLONG   ReceivedFragmentCount;
+    ULONGLONG   MulticastReceivedFrameCount;
+    ULONGLONG   FCSErrorCount;
+    ULONGLONG   TKIPLocalMICFailures;
+    ULONGLONG   TKIPRemoteMICFailures;
+    ULONGLONG   TKIPICVErrors;
+    ULONGLONG   TKIPCounterMeasuresInvoked;
+    ULONGLONG   TKIPReplays;
+    ULONGLONG   CCMPFormatErrors;
+    ULONGLONG   CCMPReplays;
+    ULONGLONG   CCMPDecryptErrors;
+    ULONGLONG   FourWayHandshakeFailures;
+//    ULONGLONG   WEPUndecryptableCount;
+//    ULONGLONG   WEPICVErrorCount;
+//    ULONGLONG   DecryptSuccessCount;
+//    ULONGLONG   DecryptFailureCount;
+} SDot11Counters, *PSDot11Counters;
+
+
+//
+// MIB2 counter
+//
+typedef struct tagSMib2Counter {
+    LONG    ifIndex;
+    char    ifDescr[256];               // max size 255 plus zero ending
+                                        // e.g. "interface 1"
+    LONG    ifType;
+    LONG    ifMtu;
+    DWORD   ifSpeed;
+    BYTE    ifPhysAddress[U_ETHER_ADDR_LEN];
+    LONG    ifAdminStatus;
+    LONG    ifOperStatus;
+    DWORD   ifLastChange;
+    DWORD   ifInOctets;
+    DWORD   ifInUcastPkts;
+    DWORD   ifInNUcastPkts;
+    DWORD   ifInDiscards;
+    DWORD   ifInErrors;
+    DWORD   ifInUnknownProtos;
+    DWORD   ifOutOctets;
+    DWORD   ifOutUcastPkts;
+    DWORD   ifOutNUcastPkts;
+    DWORD   ifOutDiscards;
+    DWORD   ifOutErrors;
+    DWORD   ifOutQLen;
+    DWORD   ifSpecific;
+} SMib2Counter, *PSMib2Counter;
+
+// Value in the ifType entry
+//#define ETHERNETCSMACD      6           //
+#define WIRELESSLANIEEE80211b      6           //
+
+// Value in the ifAdminStatus/ifOperStatus entry
+#define UP                  1           //
+#define DOWN                2           //
+#define TESTING             3           //
+
+
+//
+// RMON counter
+//
+typedef struct tagSRmonCounter {
+    LONG    etherStatsIndex;
+    DWORD   etherStatsDataSource;
+    DWORD   etherStatsDropEvents;
+    DWORD   etherStatsOctets;
+    DWORD   etherStatsPkts;
+    DWORD   etherStatsBroadcastPkts;
+    DWORD   etherStatsMulticastPkts;
+    DWORD   etherStatsCRCAlignErrors;
+    DWORD   etherStatsUndersizePkts;
+    DWORD   etherStatsOversizePkts;
+    DWORD   etherStatsFragments;
+    DWORD   etherStatsJabbers;
+    DWORD   etherStatsCollisions;
+    DWORD   etherStatsPkt64Octets;
+    DWORD   etherStatsPkt65to127Octets;
+    DWORD   etherStatsPkt128to255Octets;
+    DWORD   etherStatsPkt256to511Octets;
+    DWORD   etherStatsPkt512to1023Octets;
+    DWORD   etherStatsPkt1024to1518Octets;
+    DWORD   etherStatsOwners;
+    DWORD   etherStatsStatus;
+} SRmonCounter, *PSRmonCounter;
+
+//
+// Custom counter
+//
+typedef struct tagSCustomCounters {
+    ULONG       Length;
+
+    ULONGLONG   ullTsrAllOK;
+
+    ULONGLONG   ullRsr11M;
+    ULONGLONG   ullRsr5M;
+    ULONGLONG   ullRsr2M;
+    ULONGLONG   ullRsr1M;
+
+    ULONGLONG   ullRsr11MCRCOk;
+    ULONGLONG   ullRsr5MCRCOk;
+    ULONGLONG   ullRsr2MCRCOk;
+    ULONGLONG   ullRsr1MCRCOk;
+
+    ULONGLONG   ullRsr54M;
+    ULONGLONG   ullRsr48M;
+    ULONGLONG   ullRsr36M;
+    ULONGLONG   ullRsr24M;
+    ULONGLONG   ullRsr18M;
+    ULONGLONG   ullRsr12M;
+    ULONGLONG   ullRsr9M;
+    ULONGLONG   ullRsr6M;
+
+    ULONGLONG   ullRsr54MCRCOk;
+    ULONGLONG   ullRsr48MCRCOk;
+    ULONGLONG   ullRsr36MCRCOk;
+    ULONGLONG   ullRsr24MCRCOk;
+    ULONGLONG   ullRsr18MCRCOk;
+    ULONGLONG   ullRsr12MCRCOk;
+    ULONGLONG   ullRsr9MCRCOk;
+    ULONGLONG   ullRsr6MCRCOk;
+
+} SCustomCounters, *PSCustomCounters;
+
+
+//
+// Custom counter
+//
+typedef struct tagSISRCounters {
+    ULONG   Length;
+
+    DWORD   dwIsrTx0OK;
+    DWORD   dwIsrAC0TxOK;
+    DWORD   dwIsrBeaconTxOK;
+    DWORD   dwIsrRx0OK;
+    DWORD   dwIsrTBTTInt;
+    DWORD   dwIsrSTIMERInt;
+    DWORD   dwIsrWatchDog;
+    DWORD   dwIsrUnrecoverableError;
+    DWORD   dwIsrSoftInterrupt;
+    DWORD   dwIsrMIBNearfull;
+    DWORD   dwIsrRxNoBuf;
+
+    DWORD   dwIsrUnknown;               // unknown interrupt count
+
+    DWORD   dwIsrRx1OK;
+    DWORD   dwIsrATIMTxOK;
+    DWORD   dwIsrSYNCTxOK;
+    DWORD   dwIsrCFPEnd;
+    DWORD   dwIsrATIMEnd;
+    DWORD   dwIsrSYNCFlushOK;
+    DWORD   dwIsrSTIMER1Int;
+    /////////////////////////////////////
+} SISRCounters, *PSISRCounters;
+
+
+// Value in the etherStatsStatus entry
+#define VALID               1           //
+#define CREATE_REQUEST      2           //
+#define UNDER_CREATION      3           //
+#define INVALID             4           //
+
+
+//
+// Tx packet information
+//
+typedef struct tagSTxPktInfo {
+    BYTE    byBroadMultiUni;
+    WORD    wLength;
+    WORD    wFIFOCtl;
+    BYTE    abyDestAddr[U_ETHER_ADDR_LEN];
+} STxPktInfo, *PSTxPktInfo;
+
+
+#define MAX_RATE            12
+//
+// statistic counter
+//
+typedef struct tagSStatCounter {
+    //
+    // ISR status count
+    //
+
+    SISRCounters ISRStat;
+
+    // RSR status count
+    //
+    DWORD   dwRsrFrmAlgnErr;
+    DWORD   dwRsrErr;
+    DWORD   dwRsrCRCErr;
+    DWORD   dwRsrCRCOk;
+    DWORD   dwRsrBSSIDOk;
+    DWORD   dwRsrADDROk;
+    DWORD   dwRsrBCNSSIDOk;
+    DWORD   dwRsrLENErr;
+    DWORD   dwRsrTYPErr;
+
+    DWORD   dwNewRsrDECRYPTOK;
+    DWORD   dwNewRsrCFP;
+    DWORD   dwNewRsrUTSF;
+    DWORD   dwNewRsrHITAID;
+    DWORD   dwNewRsrHITAID0;
+
+    DWORD   dwRsrLong;
+    DWORD   dwRsrRunt;
+
+    DWORD   dwRsrRxControl;
+    DWORD   dwRsrRxData;
+    DWORD   dwRsrRxManage;
+
+    DWORD   dwRsrRxPacket;
+    DWORD   dwRsrRxOctet;
+    DWORD   dwRsrBroadcast;
+    DWORD   dwRsrMulticast;
+    DWORD   dwRsrDirected;
+    // 64-bit OID
+    ULONGLONG   ullRsrOK;
+
+    // for some optional OIDs (64 bits) and DMI support
+    ULONGLONG   ullRxBroadcastBytes;
+    ULONGLONG   ullRxMulticastBytes;
+    ULONGLONG   ullRxDirectedBytes;
+    ULONGLONG   ullRxBroadcastFrames;
+    ULONGLONG   ullRxMulticastFrames;
+    ULONGLONG   ullRxDirectedFrames;
+
+    DWORD   dwRsrRxFragment;
+    DWORD   dwRsrRxFrmLen64;
+    DWORD   dwRsrRxFrmLen65_127;
+    DWORD   dwRsrRxFrmLen128_255;
+    DWORD   dwRsrRxFrmLen256_511;
+    DWORD   dwRsrRxFrmLen512_1023;
+    DWORD   dwRsrRxFrmLen1024_1518;
+
+    // TSR status count
+    //
+    DWORD   dwTsrTotalRetry;        // total collision retry count
+    DWORD   dwTsrOnceRetry;         // this packet only occur one collision
+    DWORD   dwTsrMoreThanOnceRetry; // this packet occur more than one collision
+    DWORD   dwTsrRetry;             // this packet has ever occur collision,
+                                         // that is (dwTsrOnceCollision0 + dwTsrMoreThanOnceCollision0)
+    DWORD   dwTsrACKData;
+    DWORD   dwTsrErr;
+    DWORD   dwAllTsrOK;
+    DWORD   dwTsrRetryTimeout;
+    DWORD   dwTsrTransmitTimeout;
+
+    DWORD   dwTsrTxPacket;
+    DWORD   dwTsrTxOctet;
+    DWORD   dwTsrBroadcast;
+    DWORD   dwTsrMulticast;
+    DWORD   dwTsrDirected;
+
+    // RD/TD count
+    DWORD   dwCntRxFrmLength;
+    DWORD   dwCntTxBufLength;
+
+    BYTE    abyCntRxPattern[16];
+    BYTE    abyCntTxPattern[16];
+
+
+
+    // Software check....
+    DWORD   dwCntRxDataErr;             // rx buffer data software compare CRC err count
+    DWORD   dwCntDecryptErr;            // rx buffer data software compare CRC err count
+    DWORD   dwCntRxICVErr;              // rx buffer data software compare CRC err count
+
+
+    // 64-bit OID
+    ULONGLONG   ullTsrOK;
+
+    // for some optional OIDs (64 bits) and DMI support
+    ULONGLONG   ullTxBroadcastFrames;
+    ULONGLONG   ullTxMulticastFrames;
+    ULONGLONG   ullTxDirectedFrames;
+    ULONGLONG   ullTxBroadcastBytes;
+    ULONGLONG   ullTxMulticastBytes;
+    ULONGLONG   ullTxDirectedBytes;
+
+    // for autorate
+    DWORD   dwTxOk[MAX_RATE+1];
+    DWORD   dwTxFail[MAX_RATE+1];
+    DWORD   dwTxRetryCount[8];
+
+    STxPktInfo  abyTxPktInfo[16];
+
+    SUSBCounter USB_EP0Stat;
+    SUSBCounter USB_BulkInStat;
+    SUSBCounter USB_BulkOutStat;
+    SUSBCounter USB_InterruptStat;
+
+    SCustomCounters CustomStat;
+
+   #ifdef Calcu_LinkQual
+       //Tx count:
+    ULONG TxNoRetryOkCount;         //success tx no retry !
+    ULONG TxRetryOkCount;              //sucess tx but retry !
+    ULONG TxFailCount;                      //fail tx ?
+      //Rx count:
+    ULONG RxOkCnt;                          //sucess rx !
+    ULONG RxFcsErrCnt;                    //fail rx ?
+      //statistic
+    ULONG SignalStren;
+    ULONG LinkQuality;
+   #endif
+
+} SStatCounter, *PSStatCounter;
+
+#define NTSTATUS        int
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+void STAvClearAllCounter(PSStatCounter pStatistic);
+
+void STAvUpdateIsrStatCounter (PSStatCounter pStatistic, BYTE byIsr0, BYTE byIsr1);
+
+void STAvUpdateRDStatCounter(PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength);
+
+void STAvUpdateRDStatCounterEx(PSStatCounter pStatistic,
+                              BYTE byRSR, BYTE byNewRSR, BYTE byRxSts, BYTE byRxRate,
+                              PBYTE pbyBuffer, UINT cbFrameLength);
+
+
+void
+STAvUpdateTDStatCounter (
+    PSStatCounter   pStatistic,
+    BYTE            byPktNum,
+    BYTE            byRate,
+    BYTE            byTSR
+    );
+
+
+void
+STAvUpdate802_11Counter(
+    PSDot11Counters         p802_11Counter,
+    PSStatCounter           pStatistic,
+    BYTE                    byRTSSuccess,
+    BYTE                    byRTSFail,
+    BYTE                    byACKFail,
+    BYTE                    byFCSErr
+    );
+
+void STAvClear802_11Counter(PSDot11Counters p802_11Counter);
+
+void
+STAvUpdateUSBCounter(
+    PSUSBCounter    pUsbCounter,
+    NTSTATUS        ntStatus
+    );
+
+#endif // __MIB_H__
+
+
+
diff --git a/drivers/staging/vt6656/michael.c b/drivers/staging/vt6656/michael.c
new file mode 100644
index 0000000..c930e0c
--- /dev/null
+++ b/drivers/staging/vt6656/michael.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: michael.cpp
+ *
+ * Purpose: The implementation of LIST data structure.
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Sep 4, 2002
+ *
+ * Functions:
+ *      s_dwGetUINT32 - Convert from BYTE[] to DWORD in a portable way
+ *      s_vPutUINT32 - Convert from DWORD to BYTE[] in a portable way
+ *      s_vClear - Reset the state to the empty message.
+ *      s_vSetKey - Set the key.
+ *      MIC_vInit - Set the key.
+ *      s_vAppendByte - Append the byte to our word-sized buffer.
+ *      MIC_vAppend - call s_vAppendByte.
+ *      MIC_vGetMIC - Append the minimum padding and call s_vAppendByte.
+ *
+ * Revision History:
+ *
+ */
+
+#include "tmacro.h"
+#include "michael.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+/*
+static DWORD s_dwGetUINT32(BYTE * p);         // Get DWORD from 4 bytes LSByte first
+static VOID s_vPutUINT32(BYTE* p, DWORD val); // Put DWORD into 4 bytes LSByte first
+*/
+static VOID s_vClear(void);                       // Clear the internal message,
+                                              // resets the object to the state just after construction.
+static VOID s_vSetKey(DWORD dwK0, DWORD dwK1);
+static VOID s_vAppendByte(BYTE b);            // Add a single byte to the internal message
+
+/*---------------------  Export Variables  --------------------------*/
+static DWORD  L, R;           // Current state
+
+static DWORD  K0, K1;         // Key
+static DWORD  M;              // Message accumulator (single word)
+static UINT   nBytesInM;      // # bytes in M
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*
+static DWORD s_dwGetUINT32 (BYTE * p)
+// Convert from BYTE[] to DWORD in a portable way
+{
+    DWORD res = 0;
+    UINT i;
+    for(i=0; i<4; i++ )
+    {
+        res |= (*p++) << (8*i);
+    }
+    return res;
+}
+
+static VOID s_vPutUINT32 (BYTE* p, DWORD val)
+// Convert from DWORD to BYTE[] in a portable way
+{
+    UINT i;
+    for(i=0; i<4; i++ )
+    {
+        *p++ = (BYTE) (val & 0xff);
+        val >>= 8;
+    }
+}
+*/
+
+static VOID s_vClear (void)
+{
+    // Reset the state to the empty message.
+    L = K0;
+    R = K1;
+    nBytesInM = 0;
+    M = 0;
+}
+
+static VOID s_vSetKey (DWORD dwK0, DWORD dwK1)
+{
+    // Set the key
+    K0 = dwK0;
+    K1 = dwK1;
+    // and reset the message
+    s_vClear();
+}
+
+static VOID s_vAppendByte (BYTE b)
+{
+    // Append the byte to our word-sized buffer
+    M |= b << (8*nBytesInM);
+    nBytesInM++;
+    // Process the word if it is full.
+    if( nBytesInM >= 4 )
+    {
+        L ^= M;
+        R ^= ROL32( L, 17 );
+        L += R;
+        R ^= ((L & 0xff00ff00) >> 8) | ((L & 0x00ff00ff) << 8);
+        L += R;
+        R ^= ROL32( L, 3 );
+        L += R;
+        R ^= ROR32( L, 2 );
+        L += R;
+        // Clear the buffer
+        M = 0;
+        nBytesInM = 0;
+    }
+}
+
+VOID MIC_vInit (DWORD dwK0, DWORD dwK1)
+{
+    // Set the key
+    s_vSetKey(dwK0, dwK1);
+}
+
+
+VOID MIC_vUnInit (void)
+{
+    // Wipe the key material
+    K0 = 0;
+    K1 = 0;
+
+    // And the other fields as well.
+    //Note that this sets (L,R) to (K0,K1) which is just fine.
+    s_vClear();
+}
+
+VOID MIC_vAppend (PBYTE src, UINT nBytes)
+{
+    // This is simple
+    while (nBytes > 0)
+    {
+        s_vAppendByte(*src++);
+        nBytes--;
+    }
+}
+
+VOID MIC_vGetMIC (PDWORD pdwL, PDWORD pdwR)
+{
+    // Append the minimum padding
+    s_vAppendByte(0x5a);
+    s_vAppendByte(0);
+    s_vAppendByte(0);
+    s_vAppendByte(0);
+    s_vAppendByte(0);
+    // and then zeroes until the length is a multiple of 4
+    while( nBytesInM != 0 )
+    {
+        s_vAppendByte(0);
+    }
+    // The s_vAppendByte function has already computed the result.
+    *pdwL = L;
+    *pdwR = R;
+    // Reset to the empty message.
+    s_vClear();
+}
+
diff --git a/drivers/staging/vt6656/michael.h b/drivers/staging/vt6656/michael.h
new file mode 100644
index 0000000..3f79b52
--- /dev/null
+++ b/drivers/staging/vt6656/michael.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: Michael.h
+ *
+ * Purpose: Reference implementation for Michael
+ *          written by Niels Ferguson
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Jan 2, 2003
+ *
+ */
+
+#ifndef __MICHAEL_H__
+#define __MICHAEL_H__
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+VOID MIC_vInit(DWORD dwK0, DWORD dwK1);
+
+VOID MIC_vUnInit(void);
+
+// Append bytes to the message to be MICed
+VOID MIC_vAppend(PBYTE src, UINT nBytes);
+
+// Get the MIC result. Destination should accept 8 bytes of result.
+// This also resets the message to empty.
+VOID MIC_vGetMIC(PDWORD pdwL, PDWORD pdwR);
+
+/*---------------------  Export Macros ------------------------------*/
+
+// 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) )
+
+#endif //__MICHAEL_H__
+
+
diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c
new file mode 100644
index 0000000..b5702b0
--- /dev/null
+++ b/drivers/staging/vt6656/power.c
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: power.c
+ *
+ * Purpose: Handles 802.11 power managment  functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ * Functions:
+ *      PSvEnablePowerSaving - Enable Power Saving Mode
+ *      PSvDiasblePowerSaving - Disable Power Saving Mode
+ *      PSbConsiderPowerDown - Decide if we can Power Down
+ *      PSvSendPSPOLL - Send PS-POLL packet
+ *      PSbSendNullPacket - Send Null packet
+ *      PSbIsNextTBTTWakeUp - Decide if we need to wake up at next Beacon
+ *
+ * Revision History:
+ *
+ */
+
+#include "ttype.h"
+#include "mac.h"
+#include "device.h"
+#include "wmgr.h"
+#include "power.h"
+#include "wcmd.h"
+#include "rxtx.h"
+#include "card.h"
+#include "control.h"
+#include "rndis.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Functions  --------------------------*/
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*+
+ *
+ * Routine Description:
+ * Enable hw power saving functions
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+PSvEnablePowerSaving(
+    IN HANDLE hDeviceContext,
+    IN WORD wListenInterval
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    WORD            wAID = pMgmt->wCurrAID | BIT14 | BIT15;
+
+    // set period of power up before TBTT
+    MACvWriteWord(pDevice, MAC_REG_PWBT, C_PWBT);
+
+    if (pDevice->eOPMode != OP_MODE_ADHOC) {
+        // set AID
+        MACvWriteWord(pDevice, MAC_REG_AIDATIM, wAID);
+    } else {
+    	// set ATIM Window
+        //MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
+    }
+
+    //Warren:06-18-2004,the sequence must follow PSEN->AUTOSLEEP->GO2DOZE
+    // enable power saving hw function
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
+    // Set AutoSleep
+    MACvRegBitsOn(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+    //Warren:MUST turn on this once before turn on AUTOSLEEP ,or the AUTOSLEEP doesn't work
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+
+
+    if (wListenInterval >= 2) {
+
+        // clear always listen beacon
+        MACvRegBitsOff(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+        // first time set listen next beacon
+        MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+
+        pMgmt->wCountToWakeUp = wListenInterval;
+
+    }
+    else {
+
+        // always listen beacon
+        MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+        pMgmt->wCountToWakeUp = 0;
+
+    }
+
+    pDevice->bEnablePSMode = TRUE;
+
+    if (pDevice->eOPMode == OP_MODE_ADHOC) {
+//        bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt);
+    }
+    // We don't send null pkt in ad hoc mode since beacon will handle this.
+    else if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
+        PSbSendNullPacket(pDevice);
+    }
+    pDevice->bPWBitOn = TRUE;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable... \n");
+    return;
+}
+
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Disable hw power saving functions
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+PSvDisablePowerSaving(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+//    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+
+    // disable power saving hw function
+    CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_DISABLE_PS,
+                        0,
+                        0,
+                        0,
+                        NULL
+                        );
+
+    //clear AutoSleep
+    MACvRegBitsOff(pDevice, MAC_REG_PSCFG, PSCFG_AUTOSLEEP);
+
+    // set always listen beacon
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_ALBCN);
+
+    pDevice->bEnablePSMode = FALSE;
+
+    if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
+        PSbSendNullPacket(pDevice);
+    }
+    pDevice->bPWBitOn = FALSE;
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ * Consider to power down when no more packets to tx or rx.
+ *
+ * Return Value:
+ *    TRUE, if power down success
+ *    FALSE, if fail
+-*/
+
+
+BOOL
+PSbConsiderPowerDown(
+    IN HANDLE hDeviceContext,
+    IN BOOL bCheckRxDMA,
+    IN BOOL bCheckCountToWakeUp
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BYTE            byData;
+
+
+    // check if already in Doze mode
+    ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData);
+    if ( (byData & PSCTL_PS) != 0 )
+        return TRUE;;
+
+    if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+        // check if in TIM wake period
+        if (pMgmt->bInTIMWake)
+            return FALSE;
+    }
+
+    // check scan state
+    if (pDevice->bCmdRunning)
+        return FALSE;
+
+    //Tx Burst
+    if ( pDevice->bPSModeTxBurst )
+        return FALSE;
+
+    // Froce PSEN on
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_PSEN);
+
+    if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+        if (bCheckCountToWakeUp &&
+            (pMgmt->wCountToWakeUp == 0 || pMgmt->wCountToWakeUp == 1)) {
+             return FALSE;
+        }
+    }
+
+    pDevice->bPSRxBeacon = TRUE;
+    // no Tx, no Rx isr, now go to Doze
+    MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_GO2DOZE);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n");
+    return TRUE;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Send PS-POLL packet
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+
+VOID
+PSvSendPSPOLL(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    PSTxMgmtPacket      pTxPacket = NULL;
+
+
+    memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_HDR_ADDR2_LEN);
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    pTxPacket->p80211Header->sA2.wFrameCtl = cpu_to_le16(
+         (
+         WLAN_SET_FC_FTYPE(WLAN_TYPE_CTL) |
+         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PSPOLL) |
+         WLAN_SET_FC_PWRMGT(0)
+         ));
+    pTxPacket->p80211Header->sA2.wDurationID = pMgmt->wCurrAID | BIT14 | BIT15;
+    memcpy(pTxPacket->p80211Header->sA2.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    memcpy(pTxPacket->p80211Header->sA2.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    pTxPacket->cbMPDULen = WLAN_HDR_ADDR2_LEN;
+    pTxPacket->cbPayloadLen = 0;
+    // send the frame
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n");
+    }
+    else {
+//        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet success..\n");
+    };
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Send NULL packet to AP for notification power state of STA
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+BOOL
+PSbSendNullPacket(
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket      pTxPacket = NULL;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+
+
+
+    if (pDevice->bLinkPass == FALSE) {
+        return FALSE;
+    }
+
+//2007-0115-03<Add>by MikeLiu
+#ifdef TxInSleep
+     if ((pDevice->bEnablePSMode == FALSE) &&
+	  (pDevice->fTxDataInSleep == FALSE)){
+        return FALSE;
+    }
+#else
+    if (pDevice->bEnablePSMode == FALSE) {
+        return FALSE;
+    }
+#endif
+    memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN);
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool;
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+
+    if (pDevice->bEnablePSMode) {
+
+        pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(
+             (
+            WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
+            WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) |
+            WLAN_SET_FC_PWRMGT(1)
+            ));
+    }
+    else {
+        pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(
+             (
+            WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) |
+            WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) |
+            WLAN_SET_FC_PWRMGT(0)
+            ));
+    }
+
+    if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
+        pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1));
+    }
+
+    memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN;
+    pTxPacket->cbPayloadLen = 0;
+    // send the frame
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n");
+        return FALSE;
+    }
+    else {
+//            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n");
+    }
+
+
+    return TRUE ;
+}
+
+/*+
+ *
+ * Routine Description:
+ * Check if Next TBTT must wake up
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+BOOL
+PSbIsNextTBTTWakeUp(
+    IN HANDLE hDeviceContext
+    )
+{
+
+    PSDevice         pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    BOOL                bWakeUp = FALSE;
+
+    if (pMgmt->wListenInterval >= 2) {
+        if (pMgmt->wCountToWakeUp == 0) {
+            pMgmt->wCountToWakeUp = pMgmt->wListenInterval;
+        }
+
+        pMgmt->wCountToWakeUp --;
+
+        if (pMgmt->wCountToWakeUp == 1) {
+
+            // Turn on wake up to listen next beacon
+            MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+            pDevice->bPSRxBeacon = FALSE;
+            bWakeUp = TRUE;
+
+        } else if ( !pDevice->bPSRxBeacon ) {
+            //Listen until RxBeacon
+            MACvRegBitsOn(pDevice, MAC_REG_PSCTL, PSCTL_LNBCN);
+        }
+
+    }
+
+    return bWakeUp;
+}
+
diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h
new file mode 100644
index 0000000..c33c93a
--- /dev/null
+++ b/drivers/staging/vt6656/power.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: power.h
+ *
+ * Purpose: Handles 802.11 power managment  functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 17, 2002
+ *
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+
+/*---------------------  Export Definitions -------------------------*/
+#define     C_PWBT                   1000      // micro sec. power up before TBTT
+#define     PS_FAST_INTERVAL         1         // Fast power saving listen interval
+#define     PS_MAX_INTERVAL          4         // MAX power saving listen interval
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+// IN PSDevice pDevice
+// IN PSDevice hDeviceContext
+
+BOOL
+PSbConsiderPowerDown(
+    IN HANDLE hDeviceContext,
+    IN BOOL bCheckRxDMA,
+    IN BOOL bCheckCountToWakeUp
+    );
+
+VOID
+PSvDisablePowerSaving(
+    IN HANDLE hDeviceContext
+    );
+
+VOID
+PSvEnablePowerSaving(
+    IN HANDLE hDeviceContext,
+    IN WORD wListenInterval
+    );
+
+VOID
+PSvSendPSPOLL(
+    IN HANDLE hDeviceContext
+    );
+
+BOOL
+PSbSendNullPacket(
+    IN HANDLE hDeviceContext
+    );
+
+BOOL
+PSbIsNextTBTTWakeUp(
+    IN HANDLE hDeviceContext
+    );
+
+#endif //__POWER_H__
diff --git a/drivers/staging/vt6656/rc4.c b/drivers/staging/vt6656/rc4.c
new file mode 100644
index 0000000..e6c6131
--- /dev/null
+++ b/drivers/staging/vt6656/rc4.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: rc4.c
+ *
+ * Purpose:
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Sep 4, 2002
+ *
+ */
+
+#include "rc4.h"
+
+VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len)
+{
+    UINT  ust1, ust2;
+    UINT  keyindex;
+    UINT  stateindex;
+    PBYTE pbyst;
+    UINT  idx;
+
+    pbyst = pRC4->abystate;
+    pRC4->ux = 0;
+    pRC4->uy = 0;
+    for (idx = 0; idx < 256; idx++)
+        pbyst[idx] = (BYTE)idx;
+    keyindex = 0;
+    stateindex = 0;
+    for (idx = 0; idx < 256; idx++) {
+        ust1 = pbyst[idx];
+        stateindex = (stateindex + pbyKey[keyindex] + ust1) & 0xff;
+        ust2 = pbyst[stateindex];
+        pbyst[stateindex] = (BYTE)ust1;
+        pbyst[idx] = (BYTE)ust2;
+        if (++keyindex >= cbKey_len)
+            keyindex = 0;
+    }
+}
+
+UINT rc4_byte(PRC4Ext pRC4)
+{
+    UINT ux;
+    UINT uy;
+    UINT ustx, usty;
+    PBYTE pbyst;
+
+    pbyst = pRC4->abystate;
+    ux = (pRC4->ux + 1) & 0xff;
+    ustx = pbyst[ux];
+    uy = (ustx + pRC4->uy) & 0xff;
+    usty = pbyst[uy];
+    pRC4->ux = ux;
+    pRC4->uy = uy;
+    pbyst[uy] = (BYTE)ustx;
+    pbyst[ux] = (BYTE)usty;
+
+    return pbyst[(ustx + usty) & 0xff];
+}
+
+VOID rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest,
+                     PBYTE pbySrc, UINT cbData_len)
+{
+    UINT ii;
+    for (ii = 0; ii < cbData_len; ii++)
+        pbyDest[ii] = (BYTE)(pbySrc[ii] ^ rc4_byte(pRC4));
+}
diff --git a/drivers/staging/vt6656/rc4.h b/drivers/staging/vt6656/rc4.h
new file mode 100644
index 0000000..bf607c9
--- /dev/null
+++ b/drivers/staging/vt6656/rc4.h
@@ -0,0 +1,47 @@
+/*
+ * File: rc4.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Purpose:
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Sep 4, 2002
+ *
+ */
+
+#ifndef __RC4_H__
+#define __RC4_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+/*---------------------  Export Types  ------------------------------*/
+typedef struct {
+    UINT ux;
+    UINT uy;
+    BYTE abystate[256];
+} RC4Ext, *PRC4Ext;
+
+VOID rc4_init(PRC4Ext pRC4, PBYTE pbyKey, UINT cbKey_len);
+UINT rc4_byte(PRC4Ext pRC4);
+void rc4_encrypt(PRC4Ext pRC4, PBYTE pbyDest, PBYTE pbySrc, UINT cbData_len);
+
+#endif //__RC4_H__
diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c
new file mode 100644
index 0000000..405c4f7
--- /dev/null
+++ b/drivers/staging/vt6656/rf.c
@@ -0,0 +1,1151 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: rf.c
+ *
+ * Purpose: rf function code
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Feb. 19, 2004
+ *
+ * Functions:
+ *      IFRFbWriteEmbeded      - Embeded write RF register via MAC
+ *
+ * Revision History:
+ *
+ */
+
+#include "mac.h"
+#include "rf.h"
+#include "baseband.h"
+#include "control.h"
+#include "rndis.h"
+#include "datarate.h"
+
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Definitions -------------------------*/
+#define BY_AL2230_REG_LEN     23 //24bit
+#define CB_AL2230_INIT_SEQ    15
+#define AL2230_PWR_IDX_LEN    64
+
+#define BY_AL7230_REG_LEN     23 //24bit
+#define CB_AL7230_INIT_SEQ    16
+#define AL7230_PWR_IDX_LEN    64
+
+//{{RobertYu:20051111
+#define BY_VT3226_REG_LEN     23
+#define CB_VT3226_INIT_SEQ    11
+#define VT3226_PWR_IDX_LEN    64
+//}}
+
+//{{RobertYu:20060609
+#define BY_VT3342_REG_LEN     23
+#define CB_VT3342_INIT_SEQ    13
+#define VT3342_PWR_IDX_LEN    64
+//}}
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+
+
+
+BYTE abyAL2230InitTable[CB_AL2230_INIT_SEQ][3] = {
+    {0x03, 0xF7, 0x90},
+    {0x03, 0x33, 0x31},
+    {0x01, 0xB8, 0x02},
+    {0x00, 0xFF, 0xF3},
+    {0x00, 0x05, 0xA4},
+    {0x0F, 0x4D, 0xC5},   //RobertYu:20060814
+    {0x08, 0x05, 0xB6},
+    {0x01, 0x47, 0xC7},
+    {0x00, 0x06, 0x88},
+    {0x04, 0x03, 0xB9},
+    {0x00, 0xDB, 0xBA},
+    {0x00, 0x09, 0x9B},
+    {0x0B, 0xDF, 0xFC},
+    {0x00, 0x00, 0x0D},
+    {0x00, 0x58, 0x0F}
+    };
+
+BYTE abyAL2230ChannelTable0[CB_MAX_CHANNEL_24G][3] = {
+    {0x03, 0xF7, 0x90}, // channel = 1, Tf = 2412MHz
+    {0x03, 0xF7, 0x90}, // channel = 2, Tf = 2417MHz
+    {0x03, 0xE7, 0x90}, // channel = 3, Tf = 2422MHz
+    {0x03, 0xE7, 0x90}, // channel = 4, Tf = 2427MHz
+    {0x03, 0xF7, 0xA0}, // channel = 5, Tf = 2432MHz
+    {0x03, 0xF7, 0xA0}, // channel = 6, Tf = 2437MHz
+    {0x03, 0xE7, 0xA0}, // channel = 7, Tf = 2442MHz
+    {0x03, 0xE7, 0xA0}, // channel = 8, Tf = 2447MHz
+    {0x03, 0xF7, 0xB0}, // channel = 9, Tf = 2452MHz
+    {0x03, 0xF7, 0xB0}, // channel = 10, Tf = 2457MHz
+    {0x03, 0xE7, 0xB0}, // channel = 11, Tf = 2462MHz
+    {0x03, 0xE7, 0xB0}, // channel = 12, Tf = 2467MHz
+    {0x03, 0xF7, 0xC0}, // channel = 13, Tf = 2472MHz
+    {0x03, 0xE7, 0xC0}  // channel = 14, Tf = 2412M
+    };
+
+BYTE abyAL2230ChannelTable1[CB_MAX_CHANNEL_24G][3] = {
+    {0x03, 0x33, 0x31}, // channel = 1, Tf = 2412MHz
+    {0x0B, 0x33, 0x31}, // channel = 2, Tf = 2417MHz
+    {0x03, 0x33, 0x31}, // channel = 3, Tf = 2422MHz
+    {0x0B, 0x33, 0x31}, // channel = 4, Tf = 2427MHz
+    {0x03, 0x33, 0x31}, // channel = 5, Tf = 2432MHz
+    {0x0B, 0x33, 0x31}, // channel = 6, Tf = 2437MHz
+    {0x03, 0x33, 0x31}, // channel = 7, Tf = 2442MHz
+    {0x0B, 0x33, 0x31}, // channel = 8, Tf = 2447MHz
+    {0x03, 0x33, 0x31}, // channel = 9, Tf = 2452MHz
+    {0x0B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
+    {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
+    {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
+    {0x03, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
+    {0x06, 0x66, 0x61}  // channel = 14, Tf = 2412M
+    };
+
+// 40MHz reference frequency
+// Need to Pull PLLON(PE3) low when writing channel registers through 3-wire.
+BYTE abyAL7230InitTable[CB_AL7230_INIT_SEQ][3] = {
+    {0x20, 0x37, 0x90}, // Channel1 // Need modify for 11a
+    {0x13, 0x33, 0x31}, // Channel1 // Need modify for 11a
+    {0x84, 0x1F, 0xF2}, // Need modify for 11a: 451FE2
+    {0x3F, 0xDF, 0xA3}, // Need modify for 11a: 5FDFA3
+    {0x7F, 0xD7, 0x84}, // 11b/g    // Need modify for 11a
+    //0x802B4500+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 8D1B45
+    // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
+    {0x80, 0x2B, 0x55}, // Need modify for 11a: 8D1B55
+    {0x56, 0xAF, 0x36},
+    {0xCE, 0x02, 0x07}, // Need modify for 11a: 860207
+    {0x6E, 0xBC, 0x98},
+    {0x22, 0x1B, 0xB9},
+    {0xE0, 0x00, 0x0A}, // Need modify for 11a: E0600A
+    {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
+    //0x00093C00+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW, // Need modify for 11a: 00143C
+    // RoberYu:20050113, Rev0.47 Regsiter Setting Guide
+    {0x00, 0x0A, 0x3C}, // Need modify for 11a: 00143C
+    {0xFF, 0xFF, 0xFD},
+    {0x00, 0x00, 0x0E},
+    {0x1A, 0xBA, 0x8F} // Need modify for 11a: 12BACF
+    };
+
+BYTE abyAL7230InitTableAMode[CB_AL7230_INIT_SEQ][3] = {
+    {0x2F, 0xF5, 0x20}, // Channel184 // Need modify for 11b/g
+    {0x00, 0x00, 0x01}, // Channel184 // Need modify for 11b/g
+    {0x45, 0x1F, 0xE2}, // Need modify for 11b/g
+    {0x5F, 0xDF, 0xA3}, // Need modify for 11b/g
+    {0x6F, 0xD7, 0x84}, // 11a    // Need modify for 11b/g
+    {0x85, 0x3F, 0x55}, // Need modify for 11b/g, RoberYu:20050113
+    {0x56, 0xAF, 0x36},
+    {0xCE, 0x02, 0x07}, // Need modify for 11b/g
+    {0x6E, 0xBC, 0x98},
+    {0x22, 0x1B, 0xB9},
+    {0xE0, 0x60, 0x0A}, // Need modify for 11b/g
+    {0x08, 0x03, 0x1B}, // init 0x080B1B00 => 0x080F1B00 for 3 wire control TxGain(D10)
+    {0x00, 0x14, 0x7C}, // Need modify for 11b/g
+    {0xFF, 0xFF, 0xFD},
+    {0x00, 0x00, 0x0E},
+    {0x12, 0xBA, 0xCF} // Need modify for 11b/g
+    };
+
+BYTE abyAL7230ChannelTable0[CB_MAX_CHANNEL][3] = {
+    {0x20, 0x37, 0x90}, // channel =  1, Tf = 2412MHz
+    {0x20, 0x37, 0x90}, // channel =  2, Tf = 2417MHz
+    {0x20, 0x37, 0x90}, // channel =  3, Tf = 2422MHz
+    {0x20, 0x37, 0x90}, // channel =  4, Tf = 2427MHz
+    {0x20, 0x37, 0xA0}, // channel =  5, Tf = 2432MHz
+    {0x20, 0x37, 0xA0}, // channel =  6, Tf = 2437MHz
+    {0x20, 0x37, 0xA0}, // channel =  7, Tf = 2442MHz
+    {0x20, 0x37, 0xA0}, // channel =  8, Tf = 2447MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel =  9, Tf = 2452MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel = 10, Tf = 2457MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel = 11, Tf = 2462MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xB0}, // channel = 12, Tf = 2467MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xC0}, // channel = 13, Tf = 2472MHz //RobertYu: 20050218, update for APNode 0.49
+    {0x20, 0x37, 0xC0}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x0F, 0xF5, 0x20}, // channel = 183, Tf = 4915MHz (15)
+    {0x2F, 0xF5, 0x20}, // channel = 184, Tf = 4920MHz (16)
+    {0x0F, 0xF5, 0x20}, // channel = 185, Tf = 4925MHz (17)
+    {0x0F, 0xF5, 0x20}, // channel = 187, Tf = 4935MHz (18)
+    {0x2F, 0xF5, 0x20}, // channel = 188, Tf = 4940MHz (19)
+    {0x0F, 0xF5, 0x20}, // channel = 189, Tf = 4945MHz (20)
+    {0x2F, 0xF5, 0x30}, // channel = 192, Tf = 4960MHz (21)
+    {0x2F, 0xF5, 0x30}, // channel = 196, Tf = 4980MHz (22)
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+
+    {0x0F, 0xF5, 0x40}, // channel =   7, Tf = 5035MHz (23)
+    {0x2F, 0xF5, 0x40}, // channel =   8, Tf = 5040MHz (24)
+    {0x0F, 0xF5, 0x40}, // channel =   9, Tf = 5045MHz (25)
+    {0x0F, 0xF5, 0x40}, // channel =  11, Tf = 5055MHz (26)
+    {0x2F, 0xF5, 0x40}, // channel =  12, Tf = 5060MHz (27)
+    {0x2F, 0xF5, 0x50}, // channel =  16, Tf = 5080MHz (28)
+    {0x2F, 0xF5, 0x60}, // channel =  34, Tf = 5170MHz (29)
+    {0x2F, 0xF5, 0x60}, // channel =  36, Tf = 5180MHz (30)
+    {0x2F, 0xF5, 0x70}, // channel =  38, Tf = 5190MHz (31) //RobertYu: 20050218, update for APNode 0.49
+    {0x2F, 0xF5, 0x70}, // channel =  40, Tf = 5200MHz (32)
+    {0x2F, 0xF5, 0x70}, // channel =  42, Tf = 5210MHz (33)
+    {0x2F, 0xF5, 0x70}, // channel =  44, Tf = 5220MHz (34)
+    {0x2F, 0xF5, 0x70}, // channel =  46, Tf = 5230MHz (35)
+    {0x2F, 0xF5, 0x70}, // channel =  48, Tf = 5240MHz (36)
+    {0x2F, 0xF5, 0x80}, // channel =  52, Tf = 5260MHz (37)
+    {0x2F, 0xF5, 0x80}, // channel =  56, Tf = 5280MHz (38)
+    {0x2F, 0xF5, 0x80}, // channel =  60, Tf = 5300MHz (39)
+    {0x2F, 0xF5, 0x90}, // channel =  64, Tf = 5320MHz (40)
+
+    {0x2F, 0xF5, 0xC0}, // channel = 100, Tf = 5500MHz (41)
+    {0x2F, 0xF5, 0xC0}, // channel = 104, Tf = 5520MHz (42)
+    {0x2F, 0xF5, 0xC0}, // channel = 108, Tf = 5540MHz (43)
+    {0x2F, 0xF5, 0xD0}, // channel = 112, Tf = 5560MHz (44)
+    {0x2F, 0xF5, 0xD0}, // channel = 116, Tf = 5580MHz (45)
+    {0x2F, 0xF5, 0xD0}, // channel = 120, Tf = 5600MHz (46)
+    {0x2F, 0xF5, 0xE0}, // channel = 124, Tf = 5620MHz (47)
+    {0x2F, 0xF5, 0xE0}, // channel = 128, Tf = 5640MHz (48)
+    {0x2F, 0xF5, 0xE0}, // channel = 132, Tf = 5660MHz (49)
+    {0x2F, 0xF5, 0xF0}, // channel = 136, Tf = 5680MHz (50)
+    {0x2F, 0xF5, 0xF0}, // channel = 140, Tf = 5700MHz (51)
+    {0x2F, 0xF6, 0x00}, // channel = 149, Tf = 5745MHz (52)
+    {0x2F, 0xF6, 0x00}, // channel = 153, Tf = 5765MHz (53)
+    {0x2F, 0xF6, 0x00}, // channel = 157, Tf = 5785MHz (54)
+    {0x2F, 0xF6, 0x10}, // channel = 161, Tf = 5805MHz (55)
+    {0x2F, 0xF6, 0x10} // channel = 165, Tf = 5825MHz (56)
+    };
+
+BYTE abyAL7230ChannelTable1[CB_MAX_CHANNEL][3] = {
+    {0x13, 0x33, 0x31}, // channel =  1, Tf = 2412MHz
+    {0x1B, 0x33, 0x31}, // channel =  2, Tf = 2417MHz
+    {0x03, 0x33, 0x31}, // channel =  3, Tf = 2422MHz
+    {0x0B, 0x33, 0x31}, // channel =  4, Tf = 2427MHz
+    {0x13, 0x33, 0x31}, // channel =  5, Tf = 2432MHz
+    {0x1B, 0x33, 0x31}, // channel =  6, Tf = 2437MHz
+    {0x03, 0x33, 0x31}, // channel =  7, Tf = 2442MHz
+    {0x0B, 0x33, 0x31}, // channel =  8, Tf = 2447MHz
+    {0x13, 0x33, 0x31}, // channel =  9, Tf = 2452MHz
+    {0x1B, 0x33, 0x31}, // channel = 10, Tf = 2457MHz
+    {0x03, 0x33, 0x31}, // channel = 11, Tf = 2462MHz
+    {0x0B, 0x33, 0x31}, // channel = 12, Tf = 2467MHz
+    {0x13, 0x33, 0x31}, // channel = 13, Tf = 2472MHz
+    {0x06, 0x66, 0x61}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x1D, 0x55, 0x51}, // channel = 183, Tf = 4915MHz (15)
+    {0x00, 0x00, 0x01}, // channel = 184, Tf = 4920MHz (16)
+    {0x02, 0xAA, 0xA1}, // channel = 185, Tf = 4925MHz (17)
+    {0x08, 0x00, 0x01}, // channel = 187, Tf = 4935MHz (18)
+    {0x0A, 0xAA, 0xA1}, // channel = 188, Tf = 4940MHz (19)
+    {0x0D, 0x55, 0x51}, // channel = 189, Tf = 4945MHz (20)
+    {0x15, 0x55, 0x51}, // channel = 192, Tf = 4960MHz (21)
+    {0x00, 0x00, 0x01}, // channel = 196, Tf = 4980MHz (22)
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x1D, 0x55, 0x51}, // channel =   7, Tf = 5035MHz (23)
+    {0x00, 0x00, 0x01}, // channel =   8, Tf = 5040MHz (24)
+    {0x02, 0xAA, 0xA1}, // channel =   9, Tf = 5045MHz (25)
+    {0x08, 0x00, 0x01}, // channel =  11, Tf = 5055MHz (26)
+    {0x0A, 0xAA, 0xA1}, // channel =  12, Tf = 5060MHz (27)
+    {0x15, 0x55, 0x51}, // channel =  16, Tf = 5080MHz (28)
+    {0x05, 0x55, 0x51}, // channel =  34, Tf = 5170MHz (29)
+    {0x0A, 0xAA, 0xA1}, // channel =  36, Tf = 5180MHz (30)
+    {0x10, 0x00, 0x01}, // channel =  38, Tf = 5190MHz (31)
+    {0x15, 0x55, 0x51}, // channel =  40, Tf = 5200MHz (32)
+    {0x1A, 0xAA, 0xA1}, // channel =  42, Tf = 5210MHz (33)
+    {0x00, 0x00, 0x01}, // channel =  44, Tf = 5220MHz (34)
+    {0x05, 0x55, 0x51}, // channel =  46, Tf = 5230MHz (35)
+    {0x0A, 0xAA, 0xA1}, // channel =  48, Tf = 5240MHz (36)
+    {0x15, 0x55, 0x51}, // channel =  52, Tf = 5260MHz (37)
+    {0x00, 0x00, 0x01}, // channel =  56, Tf = 5280MHz (38)
+    {0x0A, 0xAA, 0xA1}, // channel =  60, Tf = 5300MHz (39)
+    {0x15, 0x55, 0x51}, // channel =  64, Tf = 5320MHz (40)
+    {0x15, 0x55, 0x51}, // channel = 100, Tf = 5500MHz (41)
+    {0x00, 0x00, 0x01}, // channel = 104, Tf = 5520MHz (42)
+    {0x0A, 0xAA, 0xA1}, // channel = 108, Tf = 5540MHz (43)
+    {0x15, 0x55, 0x51}, // channel = 112, Tf = 5560MHz (44)
+    {0x00, 0x00, 0x01}, // channel = 116, Tf = 5580MHz (45)
+    {0x0A, 0xAA, 0xA1}, // channel = 120, Tf = 5600MHz (46)
+    {0x15, 0x55, 0x51}, // channel = 124, Tf = 5620MHz (47)
+    {0x00, 0x00, 0x01}, // channel = 128, Tf = 5640MHz (48)
+    {0x0A, 0xAA, 0xA1}, // channel = 132, Tf = 5660MHz (49)
+    {0x15, 0x55, 0x51}, // channel = 136, Tf = 5680MHz (50)
+    {0x00, 0x00, 0x01}, // channel = 140, Tf = 5700MHz (51)
+    {0x18, 0x00, 0x01}, // channel = 149, Tf = 5745MHz (52)
+    {0x02, 0xAA, 0xA1}, // channel = 153, Tf = 5765MHz (53)
+    {0x0D, 0x55, 0x51}, // channel = 157, Tf = 5785MHz (54)
+    {0x18, 0x00, 0x01}, // channel = 161, Tf = 5805MHz (55)
+    {0x02, 0xAA, 0xB1}  // channel = 165, Tf = 5825MHz (56)
+    };
+
+BYTE abyAL7230ChannelTable2[CB_MAX_CHANNEL][3] = {
+    {0x7F, 0xD7, 0x84}, // channel =  1, Tf = 2412MHz
+    {0x7F, 0xD7, 0x84}, // channel =  2, Tf = 2417MHz
+    {0x7F, 0xD7, 0x84}, // channel =  3, Tf = 2422MHz
+    {0x7F, 0xD7, 0x84}, // channel =  4, Tf = 2427MHz
+    {0x7F, 0xD7, 0x84}, // channel =  5, Tf = 2432MHz
+    {0x7F, 0xD7, 0x84}, // channel =  6, Tf = 2437MHz
+    {0x7F, 0xD7, 0x84}, // channel =  7, Tf = 2442MHz
+    {0x7F, 0xD7, 0x84}, // channel =  8, Tf = 2447MHz
+    {0x7F, 0xD7, 0x84}, // channel =  9, Tf = 2452MHz
+    {0x7F, 0xD7, 0x84}, // channel = 10, Tf = 2457MHz
+    {0x7F, 0xD7, 0x84}, // channel = 11, Tf = 2462MHz
+    {0x7F, 0xD7, 0x84}, // channel = 12, Tf = 2467MHz
+    {0x7F, 0xD7, 0x84}, // channel = 13, Tf = 2472MHz
+    {0x7F, 0xD7, 0x84}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x7F, 0xD7, 0x84}, // channel = 183, Tf = 4915MHz (15)
+    {0x6F, 0xD7, 0x84}, // channel = 184, Tf = 4920MHz (16)
+    {0x7F, 0xD7, 0x84}, // channel = 185, Tf = 4925MHz (17)
+    {0x7F, 0xD7, 0x84}, // channel = 187, Tf = 4935MHz (18)
+    {0x7F, 0xD7, 0x84}, // channel = 188, Tf = 4940MHz (19)
+    {0x7F, 0xD7, 0x84}, // channel = 189, Tf = 4945MHz (20)
+    {0x7F, 0xD7, 0x84}, // channel = 192, Tf = 4960MHz (21)
+    {0x6F, 0xD7, 0x84}, // channel = 196, Tf = 4980MHz (22)
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x7F, 0xD7, 0x84}, // channel =   7, Tf = 5035MHz (23)
+    {0x6F, 0xD7, 0x84}, // channel =   8, Tf = 5040MHz (24)
+    {0x7F, 0xD7, 0x84}, // channel =   9, Tf = 5045MHz (25)
+    {0x7F, 0xD7, 0x84}, // channel =  11, Tf = 5055MHz (26)
+    {0x7F, 0xD7, 0x84}, // channel =  12, Tf = 5060MHz (27)
+    {0x7F, 0xD7, 0x84}, // channel =  16, Tf = 5080MHz (28)
+    {0x7F, 0xD7, 0x84}, // channel =  34, Tf = 5170MHz (29)
+    {0x7F, 0xD7, 0x84}, // channel =  36, Tf = 5180MHz (30)
+    {0x7F, 0xD7, 0x84}, // channel =  38, Tf = 5190MHz (31)
+    {0x7F, 0xD7, 0x84}, // channel =  40, Tf = 5200MHz (32)
+    {0x7F, 0xD7, 0x84}, // channel =  42, Tf = 5210MHz (33)
+    {0x6F, 0xD7, 0x84}, // channel =  44, Tf = 5220MHz (34)
+    {0x7F, 0xD7, 0x84}, // channel =  46, Tf = 5230MHz (35)
+    {0x7F, 0xD7, 0x84}, // channel =  48, Tf = 5240MHz (36)
+    {0x7F, 0xD7, 0x84}, // channel =  52, Tf = 5260MHz (37)
+    {0x6F, 0xD7, 0x84}, // channel =  56, Tf = 5280MHz (38)
+    {0x7F, 0xD7, 0x84}, // channel =  60, Tf = 5300MHz (39)
+    {0x7F, 0xD7, 0x84}, // channel =  64, Tf = 5320MHz (40)
+    {0x7F, 0xD7, 0x84}, // channel = 100, Tf = 5500MHz (41)
+    {0x6F, 0xD7, 0x84}, // channel = 104, Tf = 5520MHz (42)
+    {0x7F, 0xD7, 0x84}, // channel = 108, Tf = 5540MHz (43)
+    {0x7F, 0xD7, 0x84}, // channel = 112, Tf = 5560MHz (44)
+    {0x6F, 0xD7, 0x84}, // channel = 116, Tf = 5580MHz (45)
+    {0x7F, 0xD7, 0x84}, // channel = 120, Tf = 5600MHz (46)
+    {0x7F, 0xD7, 0x84}, // channel = 124, Tf = 5620MHz (47)
+    {0x6F, 0xD7, 0x84}, // channel = 128, Tf = 5640MHz (48)
+    {0x7F, 0xD7, 0x84}, // channel = 132, Tf = 5660MHz (49)
+    {0x7F, 0xD7, 0x84}, // channel = 136, Tf = 5680MHz (50)
+    {0x6F, 0xD7, 0x84}, // channel = 140, Tf = 5700MHz (51)
+    {0x7F, 0xD7, 0x84}, // channel = 149, Tf = 5745MHz (52)
+    {0x7F, 0xD7, 0x84}, // channel = 153, Tf = 5765MHz (53)
+    {0x7F, 0xD7, 0x84}, // channel = 157, Tf = 5785MHz (54)
+    {0x7F, 0xD7, 0x84}, // channel = 161, Tf = 5805MHz (55)
+    {0x7F, 0xD7, 0x84}  // channel = 165, Tf = 5825MHz (56)
+    };
+
+///{{RobertYu:20051111
+BYTE abyVT3226_InitTable[CB_VT3226_INIT_SEQ][3] = {
+    {0x03, 0xFF, 0x80},
+    {0x02, 0x82, 0xA1},
+    {0x03, 0xC6, 0xA2},
+    {0x01, 0x97, 0x93},
+    {0x03, 0x66, 0x64},
+    {0x00, 0x61, 0xA5},
+    {0x01, 0x7B, 0xD6},
+    {0x00, 0x80, 0x17},
+    {0x03, 0xF8, 0x08},
+    {0x00, 0x02, 0x39},   //RobertYu:20051116
+    {0x02, 0x00, 0x2A}
+    };
+
+BYTE abyVT3226D0_InitTable[CB_VT3226_INIT_SEQ][3] = {
+    {0x03, 0xFF, 0x80},
+    {0x03, 0x02, 0x21}, //RobertYu:20060327
+    {0x03, 0xC6, 0xA2},
+    {0x01, 0x97, 0x93},
+    {0x03, 0x66, 0x64},
+    {0x00, 0x71, 0xA5}, //RobertYu:20060103
+    {0x01, 0x15, 0xC6}, //RobertYu:20060420
+    {0x01, 0x2E, 0x07}, //RobertYu:20060420
+    {0x00, 0x58, 0x08}, //RobertYu:20060111
+    {0x00, 0x02, 0x79}, //RobertYu:20060420
+    {0x02, 0x01, 0xAA}  //RobertYu:20060523
+    };
+
+
+BYTE abyVT3226_ChannelTable0[CB_MAX_CHANNEL_24G][3] = {
+    {0x01, 0x97, 0x83}, // channel = 1, Tf = 2412MHz
+    {0x01, 0x97, 0x83}, // channel = 2, Tf = 2417MHz
+    {0x01, 0x97, 0x93}, // channel = 3, Tf = 2422MHz
+    {0x01, 0x97, 0x93}, // channel = 4, Tf = 2427MHz
+    {0x01, 0x97, 0x93}, // channel = 5, Tf = 2432MHz
+    {0x01, 0x97, 0x93}, // channel = 6, Tf = 2437MHz
+    {0x01, 0x97, 0xA3}, // channel = 7, Tf = 2442MHz
+    {0x01, 0x97, 0xA3}, // channel = 8, Tf = 2447MHz
+    {0x01, 0x97, 0xA3}, // channel = 9, Tf = 2452MHz
+    {0x01, 0x97, 0xA3}, // channel = 10, Tf = 2457MHz
+    {0x01, 0x97, 0xB3}, // channel = 11, Tf = 2462MHz
+    {0x01, 0x97, 0xB3}, // channel = 12, Tf = 2467MHz
+    {0x01, 0x97, 0xB3}, // channel = 13, Tf = 2472MHz
+    {0x03, 0x37, 0xC3}  // channel = 14, Tf = 2484MHz
+    };
+
+BYTE abyVT3226_ChannelTable1[CB_MAX_CHANNEL_24G][3] = {
+    {0x02, 0x66, 0x64}, // channel = 1, Tf = 2412MHz
+    {0x03, 0x66, 0x64}, // channel = 2, Tf = 2417MHz
+    {0x00, 0x66, 0x64}, // channel = 3, Tf = 2422MHz
+    {0x01, 0x66, 0x64}, // channel = 4, Tf = 2427MHz
+    {0x02, 0x66, 0x64}, // channel = 5, Tf = 2432MHz
+    {0x03, 0x66, 0x64}, // channel = 6, Tf = 2437MHz
+    {0x00, 0x66, 0x64}, // channel = 7, Tf = 2442MHz
+    {0x01, 0x66, 0x64}, // channel = 8, Tf = 2447MHz
+    {0x02, 0x66, 0x64}, // channel = 9, Tf = 2452MHz
+    {0x03, 0x66, 0x64}, // channel = 10, Tf = 2457MHz
+    {0x00, 0x66, 0x64}, // channel = 11, Tf = 2462MHz
+    {0x01, 0x66, 0x64}, // channel = 12, Tf = 2467MHz
+    {0x02, 0x66, 0x64}, // channel = 13, Tf = 2472MHz
+    {0x00, 0xCC, 0xC4}  // channel = 14, Tf = 2484MHz
+    };
+///}}RobertYu
+
+
+//{{RobertYu:20060502, TWIF 1.14, LO Current for 11b mode
+DWORD dwVT3226D0LoCurrentTable[CB_MAX_CHANNEL_24G] = {
+    0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 1, Tf = 2412MHz
+    0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 2, Tf = 2417MHz
+    0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 3, Tf = 2422MHz
+    0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 4, Tf = 2427MHz
+    0x0235C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 5, Tf = 2432MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 6, Tf = 2437MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 7, Tf = 2442MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 8, Tf = 2447MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 9, Tf = 2452MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 10, Tf = 2457MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 11, Tf = 2462MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 12, Tf = 2467MHz
+    0x0335C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW, // channel = 13, Tf = 2472MHz
+    0x0135C600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW  // channel = 14, Tf = 2484MHz
+};
+//}}
+
+
+//{{RobertYu:20060609
+BYTE abyVT3342A0_InitTable[CB_VT3342_INIT_SEQ][3] = { // 11b/g mode
+    {0x03, 0xFF, 0x80}, //update for mode//
+    {0x02, 0x08, 0x81},
+    {0x00, 0xC6, 0x02},
+    {0x03, 0xC5, 0x13}, // channel6
+    {0x00, 0xEE, 0xE4}, // channel6
+    {0x00, 0x71, 0xA5},
+    {0x01, 0x75, 0x46},
+    {0x01, 0x40, 0x27},
+    {0x01, 0x54, 0x08},
+    {0x00, 0x01, 0x69},
+    {0x02, 0x00, 0xAA},
+    {0x00, 0x08, 0xCB},
+    {0x01, 0x70, 0x0C}
+    };
+
+ //11b/g mode: 0x03, 0xFF, 0x80,
+ //11a mode:   0x03, 0xFF, 0xC0,
+
+ // channel44, 5220MHz  0x00C402
+ // channel56, 5280MHz  0x00C402 for disable Frac
+ // other channels 0x00C602
+
+BYTE abyVT3342_ChannelTable0[CB_MAX_CHANNEL][3] = {
+    {0x02, 0x05, 0x03}, // channel = 1, Tf = 2412MHz
+    {0x01, 0x15, 0x03}, // channel = 2, Tf = 2417MHz
+    {0x03, 0xC5, 0x03}, // channel = 3, Tf = 2422MHz
+    {0x02, 0x65, 0x03}, // channel = 4, Tf = 2427MHz
+    {0x01, 0x15, 0x13}, // channel = 5, Tf = 2432MHz
+    {0x03, 0xC5, 0x13}, // channel = 6, Tf = 2437MHz
+    {0x02, 0x05, 0x13}, // channel = 7, Tf = 2442MHz
+    {0x01, 0x15, 0x13}, // channel = 8, Tf = 2447MHz
+    {0x03, 0xC5, 0x13}, // channel = 9, Tf = 2452MHz
+    {0x02, 0x65, 0x13}, // channel = 10, Tf = 2457MHz
+    {0x01, 0x15, 0x23}, // channel = 11, Tf = 2462MHz
+    {0x03, 0xC5, 0x23}, // channel = 12, Tf = 2467MHz
+    {0x02, 0x05, 0x23}, // channel = 13, Tf = 2472MHz
+    {0x00, 0xD5, 0x23}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x01, 0x15, 0x13}, // channel = 183, Tf = 4915MHz (15), TBD
+    {0x01, 0x15, 0x13}, // channel = 184, Tf = 4920MHz (16), TBD
+    {0x01, 0x15, 0x13}, // channel = 185, Tf = 4925MHz (17), TBD
+    {0x01, 0x15, 0x13}, // channel = 187, Tf = 4935MHz (18), TBD
+    {0x01, 0x15, 0x13}, // channel = 188, Tf = 4940MHz (19), TBD
+    {0x01, 0x15, 0x13}, // channel = 189, Tf = 4945MHz (20), TBD
+    {0x01, 0x15, 0x13}, // channel = 192, Tf = 4960MHz (21), TBD
+    {0x01, 0x15, 0x13}, // channel = 196, Tf = 4980MHz (22), TBD
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x01, 0x15, 0x13}, // channel =   7, Tf = 5035MHz (23), TBD
+    {0x01, 0x15, 0x13}, // channel =   8, Tf = 5040MHz (24), TBD
+    {0x01, 0x15, 0x13}, // channel =   9, Tf = 5045MHz (25), TBD
+    {0x01, 0x15, 0x13}, // channel =  11, Tf = 5055MHz (26), TBD
+    {0x01, 0x15, 0x13}, // channel =  12, Tf = 5060MHz (27), TBD
+    {0x01, 0x15, 0x13}, // channel =  16, Tf = 5080MHz (28), TBD
+    {0x01, 0x15, 0x13}, // channel =  34, Tf = 5170MHz (29), TBD
+    {0x01, 0x55, 0x63}, // channel =  36, Tf = 5180MHz (30)
+    {0x01, 0x55, 0x63}, // channel =  38, Tf = 5190MHz (31), TBD
+    {0x02, 0xA5, 0x63}, // channel =  40, Tf = 5200MHz (32)
+    {0x02, 0xA5, 0x63}, // channel =  42, Tf = 5210MHz (33), TBD
+    {0x00, 0x05, 0x73}, // channel =  44, Tf = 5220MHz (34)
+    {0x00, 0x05, 0x73}, // channel =  46, Tf = 5230MHz (35), TBD
+    {0x01, 0x55, 0x73}, // channel =  48, Tf = 5240MHz (36)
+    {0x02, 0xA5, 0x73}, // channel =  52, Tf = 5260MHz (37)
+    {0x00, 0x05, 0x83}, // channel =  56, Tf = 5280MHz (38)
+    {0x01, 0x55, 0x83}, // channel =  60, Tf = 5300MHz (39)
+    {0x02, 0xA5, 0x83}, // channel =  64, Tf = 5320MHz (40)
+
+    {0x02, 0xA5, 0x83}, // channel = 100, Tf = 5500MHz (41), TBD
+    {0x02, 0xA5, 0x83}, // channel = 104, Tf = 5520MHz (42), TBD
+    {0x02, 0xA5, 0x83}, // channel = 108, Tf = 5540MHz (43), TBD
+    {0x02, 0xA5, 0x83}, // channel = 112, Tf = 5560MHz (44), TBD
+    {0x02, 0xA5, 0x83}, // channel = 116, Tf = 5580MHz (45), TBD
+    {0x02, 0xA5, 0x83}, // channel = 120, Tf = 5600MHz (46), TBD
+    {0x02, 0xA5, 0x83}, // channel = 124, Tf = 5620MHz (47), TBD
+    {0x02, 0xA5, 0x83}, // channel = 128, Tf = 5640MHz (48), TBD
+    {0x02, 0xA5, 0x83}, // channel = 132, Tf = 5660MHz (49), TBD
+    {0x02, 0xA5, 0x83}, // channel = 136, Tf = 5680MHz (50), TBD
+    {0x02, 0xA5, 0x83}, // channel = 140, Tf = 5700MHz (51), TBD
+
+    {0x00, 0x05, 0xF3}, // channel = 149, Tf = 5745MHz (52)
+    {0x01, 0x56, 0x03}, // channel = 153, Tf = 5765MHz (53)
+    {0x02, 0xA6, 0x03}, // channel = 157, Tf = 5785MHz (54)
+    {0x00, 0x06, 0x03}, // channel = 161, Tf = 5805MHz (55)
+    {0x00, 0x06, 0x03}  // channel = 165, Tf = 5825MHz (56), TBD
+    };
+
+BYTE abyVT3342_ChannelTable1[CB_MAX_CHANNEL][3] = {
+    {0x01, 0x99, 0x94}, // channel = 1, Tf = 2412MHz
+    {0x02, 0x44, 0x44}, // channel = 2, Tf = 2417MHz
+    {0x02, 0xEE, 0xE4}, // channel = 3, Tf = 2422MHz
+    {0x03, 0x99, 0x94}, // channel = 4, Tf = 2427MHz
+    {0x00, 0x44, 0x44}, // channel = 5, Tf = 2432MHz
+    {0x00, 0xEE, 0xE4}, // channel = 6, Tf = 2437MHz
+    {0x01, 0x99, 0x94}, // channel = 7, Tf = 2442MHz
+    {0x02, 0x44, 0x44}, // channel = 8, Tf = 2447MHz
+    {0x02, 0xEE, 0xE4}, // channel = 9, Tf = 2452MHz
+    {0x03, 0x99, 0x94}, // channel = 10, Tf = 2457MHz
+    {0x00, 0x44, 0x44}, // channel = 11, Tf = 2462MHz
+    {0x00, 0xEE, 0xE4}, // channel = 12, Tf = 2467MHz
+    {0x01, 0x99, 0x94}, // channel = 13, Tf = 2472MHz
+    {0x03, 0x33, 0x34}, // channel = 14, Tf = 2484MHz
+
+    // 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+    {0x00, 0x44, 0x44}, // channel = 183, Tf = 4915MHz (15), TBD
+    {0x00, 0x44, 0x44}, // channel = 184, Tf = 4920MHz (16), TBD
+    {0x00, 0x44, 0x44}, // channel = 185, Tf = 4925MHz (17), TBD
+    {0x00, 0x44, 0x44}, // channel = 187, Tf = 4935MHz (18), TBD
+    {0x00, 0x44, 0x44}, // channel = 188, Tf = 4940MHz (19), TBD
+    {0x00, 0x44, 0x44}, // channel = 189, Tf = 4945MHz (20), TBD
+    {0x00, 0x44, 0x44}, // channel = 192, Tf = 4960MHz (21), TBD
+    {0x00, 0x44, 0x44}, // channel = 196, Tf = 4980MHz (22), TBD
+
+    // 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+    // 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+    {0x00, 0x44, 0x44}, // channel =   7, Tf = 5035MHz (23), TBD
+    {0x00, 0x44, 0x44}, // channel =   8, Tf = 5040MHz (24), TBD
+    {0x00, 0x44, 0x44}, // channel =   9, Tf = 5045MHz (25), TBD
+    {0x00, 0x44, 0x44}, // channel =  11, Tf = 5055MHz (26), TBD
+    {0x00, 0x44, 0x44}, // channel =  12, Tf = 5060MHz (27), TBD
+    {0x00, 0x44, 0x44}, // channel =  16, Tf = 5080MHz (28), TBD
+    {0x00, 0x44, 0x44}, // channel =  34, Tf = 5170MHz (29), TBD
+    {0x01, 0x55, 0x54}, // channel =  36, Tf = 5180MHz (30)
+    {0x01, 0x55, 0x54}, // channel =  38, Tf = 5190MHz (31), TBD
+    {0x02, 0xAA, 0xA4}, // channel =  40, Tf = 5200MHz (32)
+    {0x02, 0xAA, 0xA4}, // channel =  42, Tf = 5210MHz (33), TBD
+    {0x00, 0x00, 0x04}, // channel =  44, Tf = 5220MHz (34)
+    {0x00, 0x00, 0x04}, // channel =  46, Tf = 5230MHz (35), TBD
+    {0x01, 0x55, 0x54}, // channel =  48, Tf = 5240MHz (36)
+    {0x02, 0xAA, 0xA4}, // channel =  52, Tf = 5260MHz (37)
+    {0x00, 0x00, 0x04}, // channel =  56, Tf = 5280MHz (38)
+    {0x01, 0x55, 0x54}, // channel =  60, Tf = 5300MHz (39)
+    {0x02, 0xAA, 0xA4}, // channel =  64, Tf = 5320MHz (40)
+    {0x02, 0xAA, 0xA4}, // channel = 100, Tf = 5500MHz (41), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 104, Tf = 5520MHz (42), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 108, Tf = 5540MHz (43), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 112, Tf = 5560MHz (44), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 116, Tf = 5580MHz (45), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 120, Tf = 5600MHz (46), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 124, Tf = 5620MHz (47), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 128, Tf = 5640MHz (48), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 132, Tf = 5660MHz (49), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 136, Tf = 5680MHz (50), TBD
+    {0x02, 0xAA, 0xA4}, // channel = 140, Tf = 5700MHz (51), TBD
+    {0x03, 0x00, 0x04}, // channel = 149, Tf = 5745MHz (52)
+    {0x00, 0x55, 0x54}, // channel = 153, Tf = 5765MHz (53)
+    {0x01, 0xAA, 0xA4}, // channel = 157, Tf = 5785MHz (54)
+    {0x03, 0x00, 0x04}, // channel = 161, Tf = 5805MHz (55)
+    {0x03, 0x00, 0x04}  // channel = 165, Tf = 5825MHz (56), TBD
+    };
+
+
+/*+
+ *
+ * Power Table
+ *
+-*/
+
+const DWORD dwAL2230PowerTable[AL2230_PWR_IDX_LEN] = {
+    0x04040900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04041900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04042900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04043900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04044900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04045900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04046900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04047900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04048900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04049900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0404F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04050900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04051900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04052900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04053900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04054900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04055900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04056900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04057900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04058900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04059900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0405F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04060900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04061900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04062900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04063900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04064900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04065900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04066900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04067900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04068900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04069900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0406F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04070900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04071900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04072900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04073900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04074900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04075900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04076900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04077900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04078900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x04079900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407A900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407B900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407C900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407D900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407E900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW,
+    0x0407F900+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW
+    };
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+//{{ RobertYu:20050103, Channel 11a Number To Index
+// 4.9G => Ch 183, 184, 185, 187, 188, 189, 192, 196  (Value:15 ~ 22)
+// 5G => Ch 7, 8, 9, 11, 12, 16, 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64,
+// 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165  (Value 23 ~ 56)
+
+const BYTE RFaby11aChannelIndex[200] = {
+  // 1   2   3   4   5   6   7   8   9  10
+    00, 00, 00, 00, 00, 00, 23, 24, 25, 00,  // 10
+    26, 27, 00, 00, 00, 28, 00, 00, 00, 00,  // 20
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  // 30
+    00, 00, 00, 29, 00, 30, 00, 31, 00, 32,  // 40
+    00, 33, 00, 34, 00, 35, 00, 36, 00, 00,  // 50
+    00, 37, 00, 00, 00, 38, 00, 00, 00, 39,  // 60
+    00, 00, 00, 40, 00, 00, 00, 00, 00, 00,  // 70
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  // 80
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  // 90
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 41,  //100
+
+    00, 00, 00, 42, 00, 00, 00, 43, 00, 00,  //110
+    00, 44, 00, 00, 00, 45, 00, 00, 00, 46,  //120
+    00, 00, 00, 47, 00, 00, 00, 48, 00, 00,  //130
+    00, 49, 00, 00, 00, 50, 00, 00, 00, 51,  //140
+    00, 00, 00, 00, 00, 00, 00, 00, 52, 00,  //150
+    00, 00, 53, 00, 00, 00, 54, 00, 00, 00,  //160
+    55, 00, 00, 00, 56, 00, 00, 00, 00, 00,  //170
+    00, 00, 00, 00, 00, 00, 00, 00, 00, 00,  //180
+    00, 00, 15, 16, 17, 00, 18, 19, 20, 00,  //190
+    00, 21, 00, 00, 00, 22, 00, 00, 00, 00   //200
+};
+//}} RobertYu
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*
+ * Description: Write to IF/RF, by embeded programming
+ *
+ * Parameters:
+ *  In:
+ *      dwData      - data to write
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL IFRFbWriteEmbeded (PSDevice pDevice, DWORD dwData)
+{
+    BYTE        pbyData[4];
+
+    pbyData[0] = (BYTE)dwData;
+    pbyData[1] = (BYTE)(dwData>>8);
+    pbyData[2] = (BYTE)(dwData>>16);
+    pbyData[3] = (BYTE)(dwData>>24);
+    CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE_IFRF,
+                    0,
+                    0,
+                    4,
+                    pbyData
+                        );
+
+
+    return TRUE;
+}
+
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase       - I/O base address
+ *      dwRFPowerTable - RF Tx Power Setting
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbSetPower (
+    IN  PSDevice  pDevice,
+    IN  UINT      uRATE,
+    IN  UINT      uCH
+    )
+{
+BOOL    bResult = TRUE;
+BYTE    byPwr = pDevice->byCCKPwr;
+
+    if (pDevice->dwDiagRefCount != 0) {
+        return TRUE;
+    }
+
+    switch (uRATE) {
+    case RATE_1M:
+    case RATE_2M:
+    case RATE_5M:
+    case RATE_11M:
+        byPwr = pDevice->abyCCKPwrTbl[uCH-1];
+        break;
+    case RATE_6M:
+    case RATE_9M:
+    case RATE_18M:
+    case RATE_24M:
+    case RATE_36M:
+    case RATE_48M:
+    case RATE_54M:
+        if (uCH > CB_MAX_CHANNEL_24G) {
+            byPwr = pDevice->abyOFDMAPwrTbl[uCH-15];
+        } else {
+            byPwr = pDevice->abyOFDMPwrTbl[uCH-1];
+        }
+        break;
+    }
+
+    bResult = RFbRawSetPower(pDevice, byPwr, uRATE);
+
+    return bResult;
+}
+
+
+/*
+ * Description: Set Tx power
+ *
+ * Parameters:
+ *  In:
+ *      dwIoBase       - I/O base address
+ *      dwRFPowerTable - RF Tx Power Setting
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if succeeded; FALSE if failed.
+ *
+ */
+BOOL RFbRawSetPower (
+    IN  PSDevice  pDevice,
+    IN  BYTE      byPwr,
+    IN  UINT      uRATE
+    )
+{
+BOOL        bResult = TRUE;
+
+    if (pDevice->byCurPwr == byPwr)
+        return TRUE;
+
+    pDevice->byCurPwr = byPwr;
+
+    switch (pDevice->byRFType) {
+
+        case RF_AL2230 :
+            if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN)
+                return FALSE;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]);
+            if (uRATE <= RATE_11M)
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x0001B400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            else
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            break;
+
+        case RF_AL2230S :
+            if (pDevice->byCurPwr >= AL2230_PWR_IDX_LEN)
+                return FALSE;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwAL2230PowerTable[pDevice->byCurPwr]);
+            if (uRATE <= RATE_11M) {
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x040C1400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00299B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            }else {
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x0005A400+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00099B00+(BY_AL2230_REG_LEN<<3)+IFREGCTL_REGW);
+            }
+            break;
+
+
+        case RF_AIROHA7230:
+            {
+                DWORD       dwMax7230Pwr;
+
+                if (uRATE <= RATE_11M) { //RobertYu:20060426, for better 11b mask
+                    bResult &= IFRFbWriteEmbeded(pDevice, 0x111BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
+                }
+                else {
+                    bResult &= IFRFbWriteEmbeded(pDevice, 0x221BB900+(BY_AL7230_REG_LEN<<3)+IFREGCTL_REGW);
+                }
+
+                if (pDevice->byCurPwr > AL7230_PWR_IDX_LEN) return FALSE;
+
+                //  0x080F1B00 for 3 wire control TxGain(D10) and 0x31 as TX Gain value
+                dwMax7230Pwr = 0x080C0B00 | ( (pDevice->byCurPwr) << 12 ) |
+                                 (BY_AL7230_REG_LEN << 3 )  | IFREGCTL_REGW;
+
+                bResult &= IFRFbWriteEmbeded(pDevice, dwMax7230Pwr);
+                break;
+            }
+            break;
+
+        case RF_VT3226: //RobertYu:20051111, VT3226C0 and before
+        {
+            DWORD       dwVT3226Pwr;
+
+            if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN)
+                return FALSE;
+            dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x17 << 8 ) /* Reg7 */ |
+                           (BY_VT3226_REG_LEN << 3 )  | IFREGCTL_REGW;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr);
+            break;
+        }
+
+        case RF_VT3226D0: //RobertYu:20051228
+        {
+            DWORD       dwVT3226Pwr;
+
+            if (pDevice->byCurPwr >= VT3226_PWR_IDX_LEN)
+                return FALSE;
+
+            if (uRATE <= RATE_11M) {
+
+                dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0xE07 << 8 ) /* Reg7 */ |   //RobertYu:20060420, TWIF 1.10
+                               (BY_VT3226_REG_LEN << 3 )  | IFREGCTL_REGW;
+                bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr);
+
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x03C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW);
+                if (pDevice->sMgmtObj.eScanState != WMAC_NO_SCANNING) {
+                    // scanning, the channel number is pDevice->uScanChannel
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11B mode uCurrChannel[%d]\n", pDevice->sMgmtObj.uScanChannel);
+                    bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uScanChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11B mode uCurrChannel[%d]\n", pDevice->sMgmtObj.uCurrChannel);
+                    bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[pDevice->sMgmtObj.uCurrChannel-1]); //RobertYu:20060420, sometimes didn't change channel just set power with different rate
+                }
+
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x015C0800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060420, ok now, new switching power (mini-pci can have bigger power consumption)
+            } else {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"@@@@ RFbRawSetPower> 11G mode\n");
+                dwVT3226Pwr = ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x7 << 8 ) /* Reg7 */ |   //RobertYu:20060420, TWIF 1.10
+                               (BY_VT3226_REG_LEN << 3 )  | IFREGCTL_REGW;
+                bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226Pwr);
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00C6A200+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060327
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111
+                bResult &= IFRFbWriteEmbeded(pDevice, 0x00900800+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060111
+            }
+            break;
+        }
+
+        //{{RobertYu:20060609
+        case RF_VT3342A0:
+        {
+            DWORD       dwVT3342Pwr;
+
+            if (pDevice->byCurPwr >= VT3342_PWR_IDX_LEN)
+                return FALSE;
+
+            dwVT3342Pwr =  ((0x3F-pDevice->byCurPwr) << 20 ) | ( 0x27 << 8 ) /* Reg7 */ |
+                            (BY_VT3342_REG_LEN << 3 )  | IFREGCTL_REGW;
+            bResult &= IFRFbWriteEmbeded(pDevice, dwVT3342Pwr);
+            break;
+        }
+
+        default :
+            break;
+    }
+    return bResult;
+}
+
+/*+
+ *
+ * Routine Description:
+ *     Translate RSSI to dBm
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - The adapter to be translated
+ *      byCurrRSSI      - RSSI to be translated
+ *  Out:
+ *      pdwdbm          - Translated dbm number
+ *
+ * Return Value: none
+ *
+-*/
+VOID
+RFvRSSITodBm (
+    IN  PSDevice pDevice,
+    IN  BYTE     byCurrRSSI,
+    long *    pldBm
+    )
+{
+    BYTE byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
+    LONG b = (byCurrRSSI & 0x3F);
+    LONG a = 0;
+    BYTE abyAIROHARF[4] = {0, 18, 0, 40};
+
+    switch (pDevice->byRFType) {
+        case RF_AL2230:
+        case RF_AL2230S:
+        case RF_AIROHA7230:
+        case RF_VT3226: //RobertYu:20051111
+        case RF_VT3226D0:
+        case RF_VT3342A0:   //RobertYu:20060609
+            a = abyAIROHARF[byIdx];
+            break;
+        default:
+            break;
+    }
+
+    *pldBm = -1 * (a + b * 2);
+}
+
+
+
+VOID
+RFbRFTableDownload (
+    IN  PSDevice pDevice
+    )
+{
+WORD    wLength1 = 0,wLength2 = 0 ,wLength3 = 0;
+PBYTE   pbyAddr1 = NULL,pbyAddr2 = NULL,pbyAddr3 = NULL;
+WORD    wLength,wValue;
+BYTE    abyArray[256];
+
+    switch ( pDevice->byRFType ) {
+        case RF_AL2230:
+        case RF_AL2230S:
+            wLength1 = CB_AL2230_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL_24G * 3;
+            wLength3 = CB_MAX_CHANNEL_24G * 3;
+            pbyAddr1 = &(abyAL2230InitTable[0][0]);
+            pbyAddr2 = &(abyAL2230ChannelTable0[0][0]);
+            pbyAddr3 = &(abyAL2230ChannelTable1[0][0]);
+            break;
+        case RF_AIROHA7230:
+            wLength1 = CB_AL7230_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL * 3;
+            wLength3 = CB_MAX_CHANNEL * 3;
+            pbyAddr1 = &(abyAL7230InitTable[0][0]);
+            pbyAddr2 = &(abyAL7230ChannelTable0[0][0]);
+            pbyAddr3 = &(abyAL7230ChannelTable1[0][0]);
+            break;
+        case RF_VT3226: //RobertYu:20051111
+            wLength1 = CB_VT3226_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL_24G * 3;
+            wLength3 = CB_MAX_CHANNEL_24G * 3;
+            pbyAddr1 = &(abyVT3226_InitTable[0][0]);
+            pbyAddr2 = &(abyVT3226_ChannelTable0[0][0]);
+            pbyAddr3 = &(abyVT3226_ChannelTable1[0][0]);
+            break;
+        case RF_VT3226D0: //RobertYu:20051114
+            wLength1 = CB_VT3226_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL_24G * 3;
+            wLength3 = CB_MAX_CHANNEL_24G * 3;
+            pbyAddr1 = &(abyVT3226D0_InitTable[0][0]);
+            pbyAddr2 = &(abyVT3226_ChannelTable0[0][0]);
+            pbyAddr3 = &(abyVT3226_ChannelTable1[0][0]);
+            break;
+        case RF_VT3342A0: //RobertYu:20060609
+            wLength1 = CB_VT3342_INIT_SEQ * 3;
+            wLength2 = CB_MAX_CHANNEL * 3;
+            wLength3 = CB_MAX_CHANNEL * 3;
+            pbyAddr1 = &(abyVT3342A0_InitTable[0][0]);
+            pbyAddr2 = &(abyVT3342_ChannelTable0[0][0]);
+            pbyAddr3 = &(abyVT3342_ChannelTable1[0][0]);
+            break;
+
+    }
+    //Init Table
+
+    memcpy(abyArray, pbyAddr1, wLength1);
+    CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_RF_INIT,
+                    wLength1,
+                    abyArray
+                    );
+    //Channle Table 0
+    wValue = 0;
+    while ( wLength2 > 0 ) {
+
+        if ( wLength2 >= 64 ) {
+            wLength = 64;
+        } else {
+            wLength = wLength2;
+        }
+        memcpy(abyArray, pbyAddr2, wLength);
+        CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        wValue,
+                        MESSAGE_REQUEST_RF_CH0,
+                        wLength,
+                        abyArray);
+
+        wLength2 -= wLength;
+        wValue += wLength;
+        pbyAddr2 += wLength;
+    }
+    //Channel table 1
+    wValue = 0;
+    while ( wLength3 > 0 ) {
+
+        if ( wLength3 >= 64 ) {
+            wLength = 64;
+        } else {
+            wLength = wLength3;
+        }
+        memcpy(abyArray, pbyAddr3, wLength);
+        CONTROLnsRequestOut(pDevice,
+                        MESSAGE_TYPE_WRITE,
+                        wValue,
+                        MESSAGE_REQUEST_RF_CH1,
+                        wLength,
+                        abyArray);
+
+        wLength3 -= wLength;
+        wValue += wLength;
+        pbyAddr3 += wLength;
+    }
+
+    //7230 needs 2 InitTable and 3 Channel Table
+    if ( pDevice->byRFType == RF_AIROHA7230 ) {
+        wLength1 = CB_AL7230_INIT_SEQ * 3;
+        wLength2 = CB_MAX_CHANNEL * 3;
+        pbyAddr1 = &(abyAL7230InitTableAMode[0][0]);
+        pbyAddr2 = &(abyAL7230ChannelTable2[0][0]);
+        memcpy(abyArray, pbyAddr1, wLength1);
+        //Init Table 2
+        CONTROLnsRequestOut(pDevice,
+                    MESSAGE_TYPE_WRITE,
+                    0,
+                    MESSAGE_REQUEST_RF_INIT2,
+                    wLength1,
+                    abyArray);
+
+        //Channle Table 0
+        wValue = 0;
+        while ( wLength2 > 0 ) {
+
+            if ( wLength2 >= 64 ) {
+                wLength = 64;
+            } else {
+                wLength = wLength2;
+            }
+            memcpy(abyArray, pbyAddr2, wLength);
+            CONTROLnsRequestOut(pDevice,
+                            MESSAGE_TYPE_WRITE,
+                            wValue,
+                            MESSAGE_REQUEST_RF_CH2,
+                            wLength,
+                            abyArray);
+
+            wLength2 -= wLength;
+            wValue += wLength;
+            pbyAddr2 += wLength;
+        }
+    }
+
+}
+
+// RobertYu:20060412, TWIF1.11 adjust LO Current for 11b mode
+BOOL s_bVT3226D0_11bLoCurrentAdjust(
+    IN  PSDevice    pDevice,
+    IN  BYTE        byChannel,
+    IN  BOOL        b11bMode )
+{
+    BOOL    bResult;
+
+    bResult = TRUE;
+    if( b11bMode )
+        bResult &= IFRFbWriteEmbeded(pDevice, dwVT3226D0LoCurrentTable[byChannel-1]);
+    else
+        bResult &= IFRFbWriteEmbeded(pDevice, 0x016BC600+(BY_VT3226_REG_LEN<<3)+IFREGCTL_REGW); //RobertYu:20060412
+
+    return bResult;
+}
+
+
diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h
new file mode 100644
index 0000000..55d882f
--- /dev/null
+++ b/drivers/staging/vt6656/rf.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: rf.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Feb. 19, 2004
+ *
+ */
+
+#ifndef __RF_H__
+#define __RF_H__
+
+#include "ttype.h"
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+//
+// Baseband RF pair definition in eeprom (Bits 6..0)
+//
+#define RF_RFMD2959         0x01
+#define RF_MAXIMAG          0x02
+#define RF_AL2230           0x03
+#define RF_GCT5103          0x04
+#define RF_UW2451           0x05
+#define RF_MAXIMG           0x06
+#define RF_MAXIM2829        0x07
+#define RF_UW2452           0x08
+#define RF_VT3226           0x09
+#define RF_AIROHA7230       0x0a
+#define RF_UW2453           0x0b
+#define RF_VT3226D0         0x0c //RobertYu:20051114
+#define RF_VT3342A0         0x0d //RobertYu:20060609
+#define RF_AL2230S          0x0e
+
+#define RF_EMU              0x80
+#define RF_MASK             0x7F
+
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+extern const BYTE RFaby11aChannelIndex[200];
+/*---------------------  Export Functions  --------------------------*/
+
+BOOL IFRFbWriteEmbeded(PSDevice pDevice, DWORD dwData);
+BOOL RFbSetPower (
+    IN  PSDevice  pDevice,
+    IN  UINT      uRATE,
+    IN  UINT      uCH
+    );
+
+BOOL RFbRawSetPower(
+    IN  PSDevice  pDevice,
+    IN  BYTE      byPwr,
+    IN  UINT      uRATE
+    );
+
+VOID
+RFvRSSITodBm (
+    IN  PSDevice pDevice,
+    IN  BYTE     byCurrRSSI,
+    long *    pldBm
+    );
+
+VOID
+RFbRFTableDownload (
+    IN  PSDevice pDevice
+    );
+
+BOOL s_bVT3226D0_11bLoCurrentAdjust(
+    IN  PSDevice    pDevice,
+    IN  BYTE        byChannel,
+    IN  BOOL        b11bMode
+    );
+
+#endif // __RF_H__
+
+
+
diff --git a/drivers/staging/vt6656/rndis.h b/drivers/staging/vt6656/rndis.h
new file mode 100644
index 0000000..1d32d81
--- /dev/null
+++ b/drivers/staging/vt6656/rndis.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: rndis.h
+ *
+ * Purpose: Interface between firmware and driver
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Nov 24, 2004
+ *
+ */
+
+
+#ifndef __RNDIS_H__
+#define __RNDIS_H__
+
+/*---------------------  Export Definitions -------------------------*/
+#define MESSAGE_TYPE_READ               0x01
+#define MESSAGE_TYPE_WRITE              0x00
+#define MESSAGE_TYPE_LOCK_OR            0x02
+#define MESSAGE_TYPE_LOCK_AND           0x03
+#define MESSAGE_TYPE_WRITE_MASK         0x04
+#define MESSAGE_TYPE_CARDINIT           0x05
+#define MESSAGE_TYPE_INIT_RSP           0x06
+#define MESSAGE_TYPE_MACSHUTDOWN        0x07
+#define MESSAGE_TYPE_SETKEY             0x08
+#define MESSAGE_TYPE_CLRKEYENTRY        0x09
+#define MESSAGE_TYPE_WRITE_MISCFF       0x0A
+#define MESSAGE_TYPE_SET_ANTMD          0x0B
+#define MESSAGE_TYPE_SELECT_CHANNLE     0x0C
+#define MESSAGE_TYPE_SET_TSFTBTT        0x0D
+#define MESSAGE_TYPE_SET_SSTIFS         0x0E
+#define MESSAGE_TYPE_CHANGE_BBTYPE      0x0F
+#define MESSAGE_TYPE_DISABLE_PS         0x10
+#define MESSAGE_TYPE_WRITE_IFRF         0x11
+
+//used for read/write(index)
+#define MESSAGE_REQUEST_MEM             0x01
+#define MESSAGE_REQUEST_BBREG           0x02
+#define MESSAGE_REQUEST_MACREG          0x03
+#define MESSAGE_REQUEST_EEPROM          0x04
+#define MESSAGE_REQUEST_TSF             0x05
+#define MESSAGE_REQUEST_TBTT            0x06
+#define MESSAGE_REQUEST_BBAGC           0x07
+#define MESSAGE_REQUEST_VERSION         0x08
+#define MESSAGE_REQUEST_RF_INIT         0x09
+#define MESSAGE_REQUEST_RF_INIT2        0x0A
+#define MESSAGE_REQUEST_RF_CH0          0x0B
+#define MESSAGE_REQUEST_RF_CH1          0x0C
+#define MESSAGE_REQUEST_RF_CH2          0x0D
+
+
+#define VIAUSB20_PACKET_HEADER          0x04
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+typedef struct _CMD_MESSAGE
+{
+    BYTE        byData[256];
+} CMD_MESSAGE, *PCMD_MESSAGE;
+
+typedef struct _CMD_WRITE_MASK
+{
+    BYTE        byData;
+    BYTE        byMask;
+} CMD_WRITE_MASK, *PCMD_WRITE_MASK;
+
+typedef struct _CMD_CARD_INIT
+{
+    BYTE        byInitClass;
+    BYTE        bExistSWNetAddr;
+    BYTE        bySWNetAddr[6];
+    BYTE        byShortRetryLimit;
+    BYTE        byLongRetryLimit;
+} CMD_CARD_INIT, *PCMD_CARD_INIT;
+
+typedef struct _RSP_CARD_INIT
+{
+    BYTE        byStatus;
+    BYTE        byNetAddr[6];
+    BYTE        byRFType;
+    BYTE        byMinChannel;
+    BYTE        byMaxChannel;
+} RSP_CARD_INIT, *PRSP_CARD_INIT;
+
+typedef struct _CMD_SET_KEY
+{
+    WORD        wKCTL;
+    BYTE        abyMacAddr[6];
+    BYTE        abyKey[16];
+} CMD_SET_KEY, *PCMD_SET_KEY;
+
+typedef struct _CMD_CLRKEY_ENTRY
+{
+    BYTE        abyKeyEntry[11];
+} CMD_CLRKEY_ENTRY, *PCMD_CLRKEY_ENTRY;
+
+typedef struct _CMD_WRITE_MISCFF
+{
+    DWORD       adwMiscFFData[22][4];  //a key entry has only 22 dwords
+} CMD_WRITE_MISCFF, *PCMD_WRITE_MISCFF;
+
+typedef struct _CMD_SET_TSFTBTT
+{
+    BYTE        abyTSF_TBTT[8];
+} CMD_SET_TSFTBTT, *PCMD_SET_TSFTBTT;
+
+typedef struct _CMD_SET_SSTIFS
+{
+    BYTE        bySIFS;
+    BYTE        byDIFS;
+    BYTE        byEIFS;
+    BYTE        bySlotTime;
+    BYTE        byCwMax_Min;
+    BYTE        byBBCR10;
+} CMD_SET_SSTIFS, *PCMD_SET_SSTIFS;
+
+typedef struct _CMD_CHANGE_BBTYPE
+{
+    BYTE        bySIFS;
+    BYTE        byDIFS;
+    BYTE        byEIFS;
+    BYTE        bySlotTime;
+    BYTE        byCwMax_Min;
+    BYTE        byBBCR10;
+    BYTE        byBB_BBType;    //CR88
+    BYTE        byMAC_BBType;
+    DWORD       dwRSPINF_b_1;
+    DWORD       dwRSPINF_b_2;
+    DWORD       dwRSPINF_b_55;
+    DWORD       dwRSPINF_b_11;
+    WORD        wRSPINF_a[9];
+} CMD_CHANGE_BBTYPE, *PCMD_CHANGE_BBTYPE;
+
+/*---------------------  Export Macros -------------------------*/
+
+#define EXCH_WORD(w)        ( (WORD)((WORD)(w)<<8) | (WORD)((WORD)(w)>>8) )
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+#endif // _RNDIS_H_
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c
new file mode 100644
index 0000000..94ddf8b
--- /dev/null
+++ b/drivers/staging/vt6656/rxtx.c
@@ -0,0 +1,3239 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: rxtx.c
+ *
+ * Purpose: handle WMAC/802.3/802.11 rx & tx functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 20, 2003
+ *
+ * Functions:
+ *      s_vGenerateTxParameter - Generate tx dma requried parameter.
+ *      s_vGenerateMACHeader - Translate 802.3 to 802.11 header
+ *      csBeacon_xmit - beacon tx function
+ *      csMgmt_xmit - management tx function
+ *      s_uGetDataDuration - get tx data required duration
+ *      s_uFillDataHead- fulfill tx data duration header
+ *      s_uGetRTSCTSDuration- get rtx/cts requried duration
+ *      s_uGetRTSCTSRsvTime- get rts/cts reserved time
+ *      s_uGetTxRsvTime- get frame reserved time
+ *      s_vFillCTSHead- fulfill CTS ctl header
+ *      s_vFillFragParameter- Set fragement ctl parameter.
+ *      s_vFillRTSHead- fulfill RTS ctl header
+ *      s_vFillTxKey- fulfill tx encrypt key
+ *      s_vSWencryption- Software encrypt header
+ *      vDMA0_tx_80211- tx 802.11 frame via dma0
+ *      vGenerateFIFOHeader- Generate tx FIFO ctl header
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "rxtx.h"
+#include "tether.h"
+#include "card.h"
+#include "bssdb.h"
+#include "mac.h"
+#include "baseband.h"
+#include "michael.h"
+#include "tkip.h"
+#include "tcrc.h"
+#include "wctl.h"
+#include "hostap.h"
+#include "rf.h"
+#include "datarate.h"
+#include "usbpipe.h"
+
+#ifdef WPA_SM_Transtatus
+#include "iocmd.h"
+#endif
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+#define CRITICAL_PACKET_LEN      256    // if packet size < 256 -> in-direct send
+                                        //    packet size >= 256 -> direct send
+
+const WORD wTimeStampOff[2][MAX_RATE] = {
+        {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, // Long Preamble
+        {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, // Short Preamble
+    };
+
+const WORD wFB_Opt0[2][5] = {
+        {RATE_12M, RATE_18M, RATE_24M, RATE_36M, RATE_48M}, // fallback_rate0
+        {RATE_12M, RATE_12M, RATE_18M, RATE_24M, RATE_36M}, // fallback_rate1
+    };
+const WORD wFB_Opt1[2][5] = {
+        {RATE_12M, RATE_18M, RATE_24M, RATE_24M, RATE_36M}, // fallback_rate0
+        {RATE_6M , RATE_6M,  RATE_12M, RATE_12M, RATE_18M}, // fallback_rate1
+    };
+
+
+#define RTSDUR_BB       0
+#define RTSDUR_BA       1
+#define RTSDUR_AA       2
+#define CTSDUR_BA       3
+#define RTSDUR_BA_F0    4
+#define RTSDUR_AA_F0    5
+#define RTSDUR_BA_F1    6
+#define RTSDUR_AA_F1    7
+#define CTSDUR_BA_F0    8
+#define CTSDUR_BA_F1    9
+#define DATADUR_B       10
+#define DATADUR_A       11
+#define DATADUR_A_F0    12
+#define DATADUR_A_F1    13
+
+/*---------------------  Static Functions  --------------------------*/
+
+static
+VOID
+s_vSaveTxPktInfo(
+    IN PSDevice pDevice,
+    IN BYTE byPktNum,
+    IN PBYTE pbyDestAddr,
+    IN WORD wPktLength,
+    IN WORD wFIFOCtl
+);
+
+static
+PVOID
+s_vGetFreeContext(
+    PSDevice pDevice
+    );
+
+
+static
+VOID
+s_vGenerateTxParameter(
+    IN PSDevice         pDevice,
+    IN BYTE             byPktType,
+    IN WORD             wCurrentRate,
+    IN PVOID            pTxBufHead,
+    IN PVOID            pvRrvTime,
+    IN PVOID            pvRTS,
+    IN PVOID            pvCTS,
+    IN UINT             cbFrameSize,
+    IN BOOL             bNeedACK,
+    IN UINT             uDMAIdx,
+    IN PSEthernetHeader psEthHeader
+    );
+
+
+static
+UINT
+s_uFillDataHead (
+    IN PSDevice pDevice,
+    IN BYTE     byPktType,
+    IN WORD     wCurrentRate,
+    IN PVOID    pTxDataHead,
+    IN UINT     cbFrameLength,
+    IN UINT     uDMAIdx,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption
+    );
+
+
+
+
+static
+VOID
+s_vGenerateMACHeader (
+    IN PSDevice         pDevice,
+    IN PBYTE            pbyBufferAddr,
+    IN WORD             wDuration,
+    IN PSEthernetHeader psEthHeader,
+    IN BOOL             bNeedEncrypt,
+    IN WORD             wFragType,
+    IN UINT             uDMAIdx,
+    IN UINT             uFragIdx
+    );
+
+static
+VOID
+s_vFillTxKey(
+    IN  PSDevice   pDevice,
+    IN  PBYTE      pbyBuf,
+    IN  PBYTE      pbyIVHead,
+    IN  PSKeyItem  pTransmitKey,
+    IN  PBYTE      pbyHdrBuf,
+    IN  WORD       wPayloadLen,
+    OUT PBYTE      pMICHDR
+    );
+
+static
+VOID
+s_vSWencryption (
+    IN  PSDevice         pDevice,
+    IN  PSKeyItem        pTransmitKey,
+    IN  PBYTE            pbyPayloadHead,
+    IN  WORD             wPayloadSize
+    );
+
+static
+UINT
+s_uGetTxRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE     byPktType,
+    IN UINT     cbFrameLength,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck
+    );
+
+
+static
+UINT
+s_uGetRTSCTSRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE byRTSRsvType,
+    IN BYTE byPktType,
+    IN UINT cbFrameLength,
+    IN WORD wCurrentRate
+    );
+
+static
+VOID
+s_vFillCTSHead (
+    IN PSDevice pDevice,
+    IN UINT     uDMAIdx,
+    IN BYTE     byPktType,
+    IN PVOID    pvCTS,
+    IN UINT     cbFrameLength,
+    IN BOOL     bNeedAck,
+    IN BOOL     bDisCRC,
+    IN WORD     wCurrentRate,
+    IN BYTE     byFBOption
+    );
+
+static
+VOID
+s_vFillRTSHead(
+    IN PSDevice         pDevice,
+    IN BYTE             byPktType,
+    IN PVOID            pvRTS,
+    IN UINT             cbFrameLength,
+    IN BOOL             bNeedAck,
+    IN BOOL             bDisCRC,
+    IN PSEthernetHeader psEthHeader,
+    IN WORD             wCurrentRate,
+    IN BYTE             byFBOption
+    );
+
+static
+UINT
+s_uGetDataDuration (
+    IN PSDevice pDevice,
+    IN BYTE     byDurType,
+    IN UINT     cbFrameLength,
+    IN BYTE     byPktType,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption
+    );
+
+
+static
+UINT
+s_uGetRTSCTSDuration (
+    IN PSDevice pDevice,
+    IN BYTE byDurType,
+    IN UINT cbFrameLength,
+    IN BYTE byPktType,
+    IN WORD wRate,
+    IN BOOL bNeedAck,
+    IN BYTE byFBOption
+    );
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+static
+PVOID
+s_vGetFreeContext(
+    PSDevice pDevice
+    )
+{
+    PUSB_SEND_CONTEXT   pContext = NULL;
+    PUSB_SEND_CONTEXT   pReturnContext = NULL;
+    UINT                ii;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"GetFreeContext()\n");
+
+    for (ii = 0; ii < pDevice->cbTD; ii++) {
+        pContext = pDevice->apTD[ii];
+        if (pContext->bBoolInUse == FALSE) {
+            pContext->bBoolInUse = TRUE;
+            pReturnContext = pContext;
+            break;
+        }
+    }
+    if ( ii == pDevice->cbTD ) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Free Tx Context\n");
+    }
+    return ((PVOID) pReturnContext);
+}
+
+
+static
+VOID
+s_vSaveTxPktInfo(PSDevice pDevice, BYTE byPktNum, PBYTE pbyDestAddr, WORD wPktLength, WORD wFIFOCtl)
+{
+    PSStatCounter           pStatistic=&(pDevice->scStatistic);
+
+
+    if (IS_BROADCAST_ADDRESS(pbyDestAddr))
+        pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_BROAD;
+    else if (IS_MULTICAST_ADDRESS(pbyDestAddr))
+        pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_MULTI;
+    else
+        pStatistic->abyTxPktInfo[byPktNum].byBroadMultiUni = TX_PKT_UNI;
+
+    pStatistic->abyTxPktInfo[byPktNum].wLength = wPktLength;
+    pStatistic->abyTxPktInfo[byPktNum].wFIFOCtl = wFIFOCtl;
+    memcpy(pStatistic->abyTxPktInfo[byPktNum].abyDestAddr, pbyDestAddr, U_ETHER_ADDR_LEN);
+}
+
+
+
+
+static
+VOID
+s_vFillTxKey (
+    IN  PSDevice   pDevice,
+    IN  PBYTE      pbyBuf,
+    IN  PBYTE      pbyIVHead,
+    IN  PSKeyItem  pTransmitKey,
+    IN  PBYTE      pbyHdrBuf,
+    IN  WORD       wPayloadLen,
+    OUT PBYTE      pMICHDR
+    )
+{
+    PDWORD          pdwIV = (PDWORD) pbyIVHead;
+    PDWORD          pdwExtIV = (PDWORD) ((PBYTE)pbyIVHead+4);
+    WORD            wValue;
+    PS802_11Header  pMACHeader = (PS802_11Header)pbyHdrBuf;
+    DWORD           dwRevIVCounter;
+
+
+
+    //Fill TXKEY
+    if (pTransmitKey == NULL)
+        return;
+
+    dwRevIVCounter = cpu_to_le32(pDevice->dwIVCounter);
+    *pdwIV = pDevice->dwIVCounter;
+    pDevice->byKeyIndex = pTransmitKey->dwKeyIndex & 0xf;
+
+    if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+        if (pTransmitKey->uKeyLength == WLAN_WEP232_KEYLEN ){
+            memcpy(pDevice->abyPRNG, (PBYTE)&(dwRevIVCounter), 3);
+            memcpy(pDevice->abyPRNG+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+        } else {
+            memcpy(pbyBuf, (PBYTE)&(dwRevIVCounter), 3);
+            memcpy(pbyBuf+3, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+            if(pTransmitKey->uKeyLength == WLAN_WEP40_KEYLEN) {
+                memcpy(pbyBuf+8, (PBYTE)&(dwRevIVCounter), 3);
+                memcpy(pbyBuf+11, pTransmitKey->abyKey, pTransmitKey->uKeyLength);
+            }
+            memcpy(pDevice->abyPRNG, pbyBuf, 16);
+        }
+        // Append IV after Mac Header
+        *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111
+        *pdwIV |= (pDevice->byKeyIndex << 30);
+        *pdwIV = cpu_to_le32(*pdwIV);
+        pDevice->dwIVCounter++;
+        if (pDevice->dwIVCounter > WEP_IV_MASK) {
+            pDevice->dwIVCounter = 0;
+        }
+    } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+        pTransmitKey->wTSC15_0++;
+        if (pTransmitKey->wTSC15_0 == 0) {
+            pTransmitKey->dwTSC47_16++;
+        }
+        TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
+                    pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
+        memcpy(pbyBuf, pDevice->abyPRNG, 16);
+        // Make IV
+        memcpy(pdwIV, pDevice->abyPRNG, 3);
+
+        *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+        // Append IV&ExtIV after Mac Header
+        *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV);
+
+    } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+        pTransmitKey->wTSC15_0++;
+        if (pTransmitKey->wTSC15_0 == 0) {
+            pTransmitKey->dwTSC47_16++;
+        }
+        memcpy(pbyBuf, pTransmitKey->abyKey, 16);
+
+        // Make IV
+        *pdwIV = 0;
+        *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV
+        *pdwIV |= cpu_to_le16((WORD)(pTransmitKey->wTSC15_0));
+        //Append IV&ExtIV after Mac Header
+        *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16);
+
+        //Fill MICHDR0
+        *pMICHDR = 0x59;
+        *((PBYTE)(pMICHDR+1)) = 0; // TxPriority
+        memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6);
+        *((PBYTE)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16));
+        *((PBYTE)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0);
+        *((PBYTE)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0);
+        *((PBYTE)(pMICHDR+14)) = HIBYTE(wPayloadLen);
+        *((PBYTE)(pMICHDR+15)) = LOBYTE(wPayloadLen);
+
+        //Fill MICHDR1
+        *((PBYTE)(pMICHDR+16)) = 0; // HLEN[15:8]
+        if (pDevice->bLongHeader) {
+            *((PBYTE)(pMICHDR+17)) = 28; // HLEN[7:0]
+        } else {
+            *((PBYTE)(pMICHDR+17)) = 22; // HLEN[7:0]
+        }
+        wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F);
+        memcpy(pMICHDR+18, (PBYTE)&wValue, 2); // MSKFRACTL
+        memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6);
+        memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6);
+
+        //Fill MICHDR2
+        memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6);
+        wValue = pMACHeader->wSeqCtl;
+        wValue &= 0x000F;
+        wValue = cpu_to_le16(wValue);
+        memcpy(pMICHDR+38, (PBYTE)&wValue, 2); // MSKSEQCTL
+        if (pDevice->bLongHeader) {
+            memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6);
+        }
+    }
+}
+
+
+static
+VOID
+s_vSWencryption (
+    IN  PSDevice            pDevice,
+    IN  PSKeyItem           pTransmitKey,
+    IN  PBYTE               pbyPayloadHead,
+    IN  WORD                wPayloadSize
+    )
+{
+    UINT   cbICVlen = 4;
+    DWORD  dwICV = 0xFFFFFFFFL;
+    PDWORD pdwICV;
+
+    if (pTransmitKey == NULL)
+        return;
+
+    if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+        //=======================================================================
+        // Append ICV after payload
+        dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
+        pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
+        // finally, we must invert dwCRC to get the correct answer
+        *pdwICV = cpu_to_le32(~dwICV);
+        // RC4 encryption
+        rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength + 3);
+        rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
+        //=======================================================================
+    } else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+        //=======================================================================
+        //Append ICV after payload
+        dwICV = CRCdwGetCrc32Ex(pbyPayloadHead, wPayloadSize, dwICV);//ICV(Payload)
+        pdwICV = (PDWORD)(pbyPayloadHead + wPayloadSize);
+        // finally, we must invert dwCRC to get the correct answer
+        *pdwICV = cpu_to_le32(~dwICV);
+        // RC4 encryption
+        rc4_init(&pDevice->SBox, pDevice->abyPRNG, TKIP_KEY_LEN);
+        rc4_encrypt(&pDevice->SBox, pbyPayloadHead, pbyPayloadHead, wPayloadSize+cbICVlen);
+        //=======================================================================
+    }
+}
+
+
+
+
+/*byPktType : PK_TYPE_11A     0
+             PK_TYPE_11B     1
+             PK_TYPE_11GB    2
+             PK_TYPE_11GA    3
+*/
+static
+UINT
+s_uGetTxRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE     byPktType,
+    IN UINT     cbFrameLength,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck
+    )
+{
+    UINT uDataTime, uAckTime;
+
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wRate);
+    if (byPktType == PK_TYPE_11B) {//llb,CCK mode
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopCCKBasicRate);
+    } else {//11g 2.4G OFDM mode & 11a 5G OFDM mode
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, (WORD)pDevice->byTopOFDMBasicRate);
+    }
+
+    if (bNeedAck) {
+        return (uDataTime + pDevice->uSIFS + uAckTime);
+    }
+    else {
+        return uDataTime;
+    }
+}
+
+//byFreqType: 0=>5GHZ 1=>2.4GHZ
+static
+UINT
+s_uGetRTSCTSRsvTime (
+    IN PSDevice pDevice,
+    IN BYTE byRTSRsvType,
+    IN BYTE byPktType,
+    IN UINT cbFrameLength,
+    IN WORD wCurrentRate
+    )
+{
+    UINT uRrvTime  , uRTSTime, uCTSTime, uAckTime, uDataTime;
+
+    uRrvTime = uRTSTime = uCTSTime = uAckTime = uDataTime = 0;
+
+
+    uDataTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, cbFrameLength, wCurrentRate);
+    if (byRTSRsvType == 0) { //RTSTxRrvTime_bb
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+    }
+    else if (byRTSRsvType == 1){ //RTSTxRrvTime_ba, only in 2.4GHZ
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopCCKBasicRate);
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+    }
+    else if (byRTSRsvType == 2) { //RTSTxRrvTime_aa
+        uRTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 20, pDevice->byTopOFDMBasicRate);
+        uCTSTime = uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+    }
+    else if (byRTSRsvType == 3) { //CTSTxRrvTime_ba, only in 2.4GHZ
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+        uRrvTime = uCTSTime + uAckTime + uDataTime + 2*pDevice->uSIFS;
+        return uRrvTime;
+    }
+
+    //RTSRrvTime
+    uRrvTime = uRTSTime + uCTSTime + uAckTime + uDataTime + 3*pDevice->uSIFS;
+    return uRrvTime;
+}
+
+//byFreqType 0: 5GHz, 1:2.4Ghz
+static
+UINT
+s_uGetDataDuration (
+    IN PSDevice pDevice,
+    IN BYTE     byDurType,
+    IN UINT     cbFrameLength,
+    IN BYTE     byPktType,
+    IN WORD     wRate,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption
+    )
+{
+    BOOL bLastFrag = 0;
+    UINT uAckTime =0, uNextPktTime = 0;
+
+
+    if (uFragIdx == (uMACfragNum-1)) {
+        bLastFrag = 1;
+    }
+
+    switch (byDurType) {
+
+    case DATADUR_B:    //DATADUR_B
+        if (((uMACfragNum == 1)) || (bLastFrag == 1)) {//Non Frag or Last Frag
+            if (bNeedAck) {
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+        else {//First Frag or Mid Frag
+            if (uFragIdx == (uMACfragNum-2)) {
+            	uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
+            } else {
+                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+            }
+            if (bNeedAck) {
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+        }
+        break;
+
+
+    case DATADUR_A:    //DATADUR_A
+        if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+        else {//First Frag or Mid Frag
+            if(uFragIdx == (uMACfragNum-2)){
+            	uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wRate, bNeedAck);
+            } else {
+                uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+            }
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+        }
+        break;
+
+    case DATADUR_A_F0:    //DATADUR_A_F0
+	    if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+	    else { //First Frag or Mid Frag
+	        if (byFBOption == AUTO_FB_0) {
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                }
+	        } else { // (byFBOption == AUTO_FB_1)
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+                }
+	        }
+
+	        if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+	    }
+        break;
+
+    case DATADUR_A_F1:    //DATADUR_A_F1
+        if (((uMACfragNum==1)) || (bLastFrag==1)) {//Non Frag or Last Frag
+            if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime);
+            } else {
+                return 0;
+            }
+        }
+	    else { //First Frag or Mid Frag
+	        if (byFBOption == AUTO_FB_0) {
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                }
+
+	        } else { // (byFBOption == AUTO_FB_1)
+                if (wRate < RATE_18M)
+                    wRate = RATE_18M;
+                else if (wRate > RATE_54M)
+                    wRate = RATE_54M;
+
+	            if(uFragIdx == (uMACfragNum-2)){
+            	    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbLastFragmentSize, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                } else {
+                    uNextPktTime = s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+                }
+	        }
+	        if(bNeedAck){
+            	uAckTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+                return (pDevice->uSIFS + uAckTime + uNextPktTime);
+            } else {
+                return (pDevice->uSIFS + uNextPktTime);
+            }
+	    }
+        break;
+
+    default:
+        break;
+    }
+
+	ASSERT(FALSE);
+	return 0;
+}
+
+
+//byFreqType: 0=>5GHZ 1=>2.4GHZ
+static
+UINT
+s_uGetRTSCTSDuration (
+    IN PSDevice pDevice,
+    IN BYTE byDurType,
+    IN UINT cbFrameLength,
+    IN BYTE byPktType,
+    IN WORD wRate,
+    IN BOOL bNeedAck,
+    IN BYTE byFBOption
+    )
+{
+    UINT uCTSTime = 0, uDurTime = 0;
+
+
+    switch (byDurType) {
+
+    case RTSDUR_BB:    //RTSDuration_bb
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case RTSDUR_BA:    //RTSDuration_ba
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case RTSDUR_AA:    //RTSDuration_aa
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+        uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case CTSDUR_BA:    //CTSDuration_ba
+        uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wRate, bNeedAck);
+        break;
+
+    case RTSDUR_BA_F0: //RTSDuration_ba_f0
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case RTSDUR_AA_F0: //RTSDuration_aa_f0
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case RTSDUR_BA_F1: //RTSDuration_ba_f1
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopCCKBasicRate);
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case RTSDUR_AA_F1: //RTSDuration_aa_f1
+        uCTSTime = BBuGetFrameTime(pDevice->byPreambleType, byPktType, 14, pDevice->byTopOFDMBasicRate);
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = uCTSTime + 2*pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case CTSDUR_BA_F0: //CTSDuration_ba_f0
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE0][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    case CTSDUR_BA_F1: //CTSDuration_ba_f1
+        if ((byFBOption == AUTO_FB_0) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt0[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        } else if ((byFBOption == AUTO_FB_1) && (wRate >= RATE_18M) && (wRate <=RATE_54M)) {
+            uDurTime = pDevice->uSIFS + s_uGetTxRsvTime(pDevice, byPktType, cbFrameLength, wFB_Opt1[FB_RATE1][wRate-RATE_18M], bNeedAck);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return uDurTime;
+
+}
+
+
+
+
+static
+UINT
+s_uFillDataHead (
+    IN PSDevice pDevice,
+    IN BYTE     byPktType,
+    IN WORD     wCurrentRate,
+    IN PVOID    pTxDataHead,
+    IN UINT     cbFrameLength,
+    IN UINT     uDMAIdx,
+    IN BOOL     bNeedAck,
+    IN UINT     uFragIdx,
+    IN UINT     cbLastFragmentSize,
+    IN UINT     uMACfragNum,
+    IN BYTE     byFBOption
+    )
+{
+
+    if (pTxDataHead == NULL) {
+        return 0;
+    }
+
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+        if((uDMAIdx==TYPE_ATIMDMA)||(uDMAIdx==TYPE_BEACONDMA)) {
+            PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+                (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            //Get Duration and TimeStampOff
+            pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+                                                       wCurrentRate, bNeedAck, uFragIdx,
+                                                       cbLastFragmentSize, uMACfragNum,
+                                                       byFBOption); //1: 2.4GHz
+            if(uDMAIdx!=TYPE_ATIMDMA) {
+                pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+            }
+            return (pBuf->wDuration);
+        }
+        else { // DATA & MANAGE Frame
+            if (byFBOption == AUTO_FB_NONE) {
+                PSTxDataHead_g pBuf = (PSTxDataHead_g)pTxDataHead;
+                //Get SignalField,ServiceField,Length
+                BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+                    (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+                );
+                BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                    (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                );
+                //Get Duration and TimeStamp
+                pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength,
+                                                             byPktType, wCurrentRate, bNeedAck, uFragIdx,
+                                                             cbLastFragmentSize, uMACfragNum,
+                                                             byFBOption); //1: 2.4GHz
+                pBuf->wDuration_b = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength,
+                                                             PK_TYPE_11B, pDevice->byTopCCKBasicRate,
+                                                             bNeedAck, uFragIdx, cbLastFragmentSize,
+                                                             uMACfragNum, byFBOption); //1: 2.4GHz
+
+                pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+                pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
+                return (pBuf->wDuration_a);
+             } else {
+                // Auto Fallback
+                PSTxDataHead_g_FB pBuf = (PSTxDataHead_g_FB)pTxDataHead;
+                //Get SignalField,ServiceField,Length
+                BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+                    (PWORD)&(pBuf->wTransmitLength_a), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+                );
+                BBvCaculateParameter(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                    (PWORD)&(pBuf->wTransmitLength_b), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+                );
+                //Get Duration and TimeStamp
+                pBuf->wDuration_a = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+                                             wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+                pBuf->wDuration_b = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B,
+                                             pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+                pBuf->wDuration_a_f0 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+                                             wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+                pBuf->wDuration_a_f1 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+                                             wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //1: 2.4GHz
+                pBuf->wTimeStampOff_a = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+                pBuf->wTimeStampOff_b = wTimeStampOff[pDevice->byPreambleType%2][pDevice->byTopCCKBasicRate%MAX_RATE];
+                return (pBuf->wDuration_a);
+            } //if (byFBOption == AUTO_FB_NONE)
+        }
+    }
+    else if (byPktType == PK_TYPE_11A) {
+        if ((byFBOption != AUTO_FB_NONE) && (uDMAIdx != TYPE_ATIMDMA) && (uDMAIdx != TYPE_BEACONDMA)) {
+            // Auto Fallback
+            PSTxDataHead_a_FB pBuf = (PSTxDataHead_a_FB)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+                (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            //Get Duration and TimeStampOff
+            pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+                                        wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
+            pBuf->wDuration_f0 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType,
+                                        wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
+            pBuf->wDuration_f1 = (WORD)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType,
+                                        wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption); //0: 5GHz
+            if(uDMAIdx!=TYPE_ATIMDMA) {
+                pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+            }
+            return (pBuf->wDuration);
+        } else {
+            PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+                (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            //Get Duration and TimeStampOff
+            pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType,
+                                                       wCurrentRate, bNeedAck, uFragIdx,
+                                                       cbLastFragmentSize, uMACfragNum,
+                                                       byFBOption);
+
+            if(uDMAIdx!=TYPE_ATIMDMA) {
+                pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+            }
+            return (pBuf->wDuration);
+        }
+    }
+    else if (byPktType == PK_TYPE_11B) {
+            PSTxDataHead_ab pBuf = (PSTxDataHead_ab)pTxDataHead;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, cbFrameLength, wCurrentRate, byPktType,
+                (PWORD)&(pBuf->wTransmitLength), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            //Get Duration and TimeStampOff
+            pBuf->wDuration = (WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType,
+                                                       wCurrentRate, bNeedAck, uFragIdx,
+                                                       cbLastFragmentSize, uMACfragNum,
+                                                       byFBOption);
+            if (uDMAIdx != TYPE_ATIMDMA) {
+                pBuf->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+            }
+            return (pBuf->wDuration);
+    }
+    return 0;
+}
+
+
+
+
+static
+VOID
+s_vFillRTSHead (
+    IN PSDevice         pDevice,
+    IN BYTE             byPktType,
+    IN PVOID            pvRTS,
+    IN UINT             cbFrameLength,
+    IN BOOL             bNeedAck,
+    IN BOOL             bDisCRC,
+    IN PSEthernetHeader psEthHeader,
+    IN WORD             wCurrentRate,
+    IN BYTE             byFBOption
+    )
+{
+    UINT uRTSFrameLen = 20;
+    WORD  wLen = 0x0000;
+
+    if (pvRTS == NULL)
+    	return;
+
+    if (bDisCRC) {
+        // When CRCDIS bit is on, H/W forgot to generate FCS for RTS frame,
+        // in this case we need to decrease its length by 4.
+        uRTSFrameLen -= 4;
+    }
+
+    // Note: So far RTSHead dosen't appear in ATIM & Beacom DMA, so we don't need to take them into account.
+    //       Otherwise, we need to modified codes for them.
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+        if (byFBOption == AUTO_FB_NONE) {
+            PSRTS_g pBuf = (PSRTS_g)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+            );
+            pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+            //Get Duration
+            pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3: 2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+
+            pBuf->Data.wDurationID = pBuf->wDuration_aa;
+            //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+        }
+        else {
+           PSRTS_g_FB pBuf = (PSRTS_g_FB)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_a), (PBYTE)&(pBuf->bySignalField_a)
+            );
+            pBuf->wTransmitLength_a = cpu_to_le16(wLen);
+            //Get Duration
+            pBuf->wDuration_bb = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption));    //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+            pBuf->wDuration_aa = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //2:RTSDuration_aa, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //1:RTSDuration_ba, 1:2.4G, 2,3:2.4G OFDMData
+            pBuf->wRTSDuration_ba_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //4:wRTSDuration_ba_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //5:wRTSDuration_aa_f0, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_ba_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //6:wRTSDuration_ba_f1, 1:2.4G, 1:CCKData
+            pBuf->wRTSDuration_aa_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption));    //7:wRTSDuration_aa_f1, 1:2.4G, 1:CCKData
+            pBuf->Data.wDurationID = pBuf->wDuration_aa;
+            //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+
+        } // if (byFBOption == AUTO_FB_NONE)
+    }
+    else if (byPktType == PK_TYPE_11A) {
+        if (byFBOption == AUTO_FB_NONE) {
+            PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            pBuf->wTransmitLength = cpu_to_le16(wLen);
+            //Get Duration
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+    	    pBuf->Data.wDurationID = pBuf->wDuration;
+            //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+
+        }
+        else {
+            PSRTS_a_FB pBuf = (PSRTS_a_FB)pvRTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+            );
+            pBuf->wTransmitLength = cpu_to_le16(wLen);
+            //Get Duration
+            pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_aa, 0:5G, 0: 5G OFDMData
+    	    pBuf->wRTSDuration_f0 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //5:RTSDuration_aa_f0, 0:5G, 0: 5G OFDMData
+    	    pBuf->wRTSDuration_f1 = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //7:RTSDuration_aa_f1, 0:5G, 0:
+    	    pBuf->Data.wDurationID = pBuf->wDuration;
+    	    //Get RTS Frame body
+            pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+            if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+                (pDevice->eOPMode == OP_MODE_AP)) {
+                memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            if (pDevice->eOPMode == OP_MODE_AP) {
+                memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            }
+            else {
+                memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            }
+        }
+    }
+    else if (byPktType == PK_TYPE_11B) {
+        PSRTS_ab pBuf = (PSRTS_ab)pvRTS;
+        //Get SignalField,ServiceField,Length
+        BBvCaculateParameter(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+            (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField), (PBYTE)&(pBuf->bySignalField)
+        );
+        pBuf->wTransmitLength = cpu_to_le16(wLen);
+        //Get Duration
+        pBuf->wDuration = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //0:RTSDuration_bb, 1:2.4G, 1:CCKData
+        pBuf->Data.wDurationID = pBuf->wDuration;
+        //Get RTS Frame body
+        pBuf->Data.wFrameControl = TYPE_CTL_RTS;//0x00B4
+
+
+        if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+            (pDevice->eOPMode == OP_MODE_AP)) {
+            memcpy(&(pBuf->Data.abyRA[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+        }
+        else {
+            memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        }
+
+        if (pDevice->eOPMode == OP_MODE_AP) {
+            memcpy(&(pBuf->Data.abyTA[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        }
+        else {
+            memcpy(&(pBuf->Data.abyTA[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+        }
+    }
+}
+
+static
+VOID
+s_vFillCTSHead (
+    IN PSDevice pDevice,
+    IN UINT     uDMAIdx,
+    IN BYTE     byPktType,
+    IN PVOID    pvCTS,
+    IN UINT     cbFrameLength,
+    IN BOOL     bNeedAck,
+    IN BOOL     bDisCRC,
+    IN WORD     wCurrentRate,
+    IN BYTE     byFBOption
+    )
+{
+    UINT uCTSFrameLen = 14;
+    WORD  wLen = 0x0000;
+
+    if (pvCTS == NULL) {
+        return;
+    }
+
+    if (bDisCRC) {
+        // When CRCDIS bit is on, H/W forgot to generate FCS for CTS frame,
+        // in this case we need to decrease its length by 4.
+        uCTSFrameLen -= 4;
+    }
+
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+        if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) {
+            // Auto Fall back
+            PSCTS_FB pBuf = (PSCTS_FB)pvCTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            pBuf->wDuration_ba = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba += pDevice->wCTSDuration;
+            pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
+            //Get CTSDuration_ba_f0
+            pBuf->wCTSDuration_ba_f0 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //8:CTSDuration_ba_f0, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f0 += pDevice->wCTSDuration;
+            pBuf->wCTSDuration_ba_f0 = cpu_to_le16(pBuf->wCTSDuration_ba_f0);
+            //Get CTSDuration_ba_f1
+            pBuf->wCTSDuration_ba_f1 = (WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); //9:CTSDuration_ba_f1, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wCTSDuration_ba_f1 += pDevice->wCTSDuration;
+            pBuf->wCTSDuration_ba_f1 = cpu_to_le16(pBuf->wCTSDuration_ba_f1);
+            //Get CTS Frame body
+            pBuf->Data.wDurationID = pBuf->wDuration_ba;
+            pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
+            pBuf->Data.wReserved = 0x0000;
+            memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
+        } else { //if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA)
+            PSCTS pBuf = (PSCTS)pvCTS;
+            //Get SignalField,ServiceField,Length
+            BBvCaculateParameter(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B,
+                (PWORD)&(wLen), (PBYTE)&(pBuf->byServiceField_b), (PBYTE)&(pBuf->bySignalField_b)
+            );
+            pBuf->wTransmitLength_b = cpu_to_le16(wLen);
+            //Get CTSDuration_ba
+            pBuf->wDuration_ba = cpu_to_le16((WORD)s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption)); //3:CTSDuration_ba, 1:2.4G, 2,3:2.4G OFDM Data
+            pBuf->wDuration_ba += pDevice->wCTSDuration;
+            pBuf->wDuration_ba = cpu_to_le16(pBuf->wDuration_ba);
+
+            //Get CTS Frame body
+            pBuf->Data.wDurationID = pBuf->wDuration_ba;
+            pBuf->Data.wFrameControl = TYPE_CTL_CTS;//0x00C4
+            pBuf->Data.wReserved = 0x0000;
+            memcpy(&(pBuf->Data.abyRA[0]), &(pDevice->abyCurrentNetAddr[0]), U_ETHER_ADDR_LEN);
+        }
+    }
+}
+
+
+
+
+
+
+/*+
+ *
+ * Description:
+ *      Generate FIFO control for MAC & Baseband controller
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to adpater
+ *      pTxDataHead     - Transmit Data Buffer
+ *      pTxBufHead      - pTxBufHead
+ *      pvRrvTime        - pvRrvTime
+ *      pvRTS            - RTS Buffer
+ *      pCTS            - CTS Buffer
+ *      cbFrameSize     - Transmit Data Length (Hdr+Payload+FCS)
+ *      bNeedACK        - If need ACK
+ *      uDMAIdx         - DMA Index
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+-*/
+// UINT            cbFrameSize,//Hdr+Payload+FCS
+static
+VOID
+s_vGenerateTxParameter (
+    IN PSDevice         pDevice,
+    IN BYTE             byPktType,
+    IN WORD             wCurrentRate,
+    IN PVOID            pTxBufHead,
+    IN PVOID            pvRrvTime,
+    IN PVOID            pvRTS,
+    IN PVOID            pvCTS,
+    IN UINT             cbFrameSize,
+    IN BOOL             bNeedACK,
+    IN UINT             uDMAIdx,
+    IN PSEthernetHeader psEthHeader
+    )
+{
+    UINT cbMACHdLen = WLAN_HDR_ADDR3_LEN; //24
+    WORD wFifoCtl;
+    BOOL bDisCRC = FALSE;
+    BYTE byFBOption = AUTO_FB_NONE;
+//    WORD wCurrentRate = pDevice->wCurrentRate;
+
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter...\n");
+    PSTxBufHead pFifoHead = (PSTxBufHead)pTxBufHead;
+    pFifoHead->wReserved = wCurrentRate;
+    wFifoCtl = pFifoHead->wFIFOCtl;
+
+    if (wFifoCtl & FIFOCTL_CRCDIS) {
+        bDisCRC = TRUE;
+    }
+
+    if (wFifoCtl & FIFOCTL_AUTO_FB_0) {
+        byFBOption = AUTO_FB_0;
+    }
+    else if (wFifoCtl & FIFOCTL_AUTO_FB_1) {
+        byFBOption = AUTO_FB_1;
+    }
+
+    if (pDevice->bLongHeader)
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+
+        if (pvRTS != NULL) { //RTS_need
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_gRTS pBuf = (PSRrvTime_gRTS)pvRrvTime;
+                pBuf->wRTSTxRrvTime_aa = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 1, byPktType, cbFrameSize, wCurrentRate));//1:RTSTxRrvTime_ba, 1:2.4GHz
+                pBuf->wRTSTxRrvTime_bb = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wTxRrvTime_a = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wTxRrvTime_b = cpu_to_le16((WORD) s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+            }
+            //Fill RTS
+            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+        }
+        else {//RTS_needless, PCF mode
+
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_gCTS pBuf = (PSRrvTime_gCTS)pvRrvTime;
+                pBuf->wTxRrvTime_a = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//2.4G OFDM
+                pBuf->wTxRrvTime_b = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, pDevice->byTopCCKBasicRate, bNeedACK));//1:CCK
+                pBuf->wCTSTxRrvTime_ba = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 3, byPktType, cbFrameSize, wCurrentRate));//3:CTSTxRrvTime_Ba, 1:2.4GHz
+            }
+            //Fill CTS
+            s_vFillCTSHead(pDevice, uDMAIdx, byPktType, pvCTS, cbFrameSize, bNeedACK, bDisCRC, wCurrentRate, byFBOption);
+        }
+    }
+    else if (byPktType == PK_TYPE_11A) {
+
+        if (pvRTS != NULL) {//RTS_need, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 2, byPktType, cbFrameSize, wCurrentRate));//2:RTSTxRrvTime_aa, 0:5GHz
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, byPktType, cbFrameSize, wCurrentRate, bNeedACK));//0:OFDM
+            }
+            //Fill RTS
+            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+        }
+        else if (pvRTS == NULL) {//RTS_needless, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11A, cbFrameSize, wCurrentRate, bNeedACK)); //0:OFDM
+            }
+        }
+    }
+    else if (byPktType == PK_TYPE_11B) {
+
+        if ((pvRTS != NULL)) {//RTS_need, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wRTSTxRrvTime = cpu_to_le16((WORD)s_uGetRTSCTSRsvTime(pDevice, 0, byPktType, cbFrameSize, wCurrentRate));//0:RTSTxRrvTime_bb, 1:2.4GHz
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK));//1:CCK
+            }
+            //Fill RTS
+            s_vFillRTSHead(pDevice, byPktType, pvRTS, cbFrameSize, bNeedACK, bDisCRC, psEthHeader, wCurrentRate, byFBOption);
+        }
+        else { //RTS_needless, non PCF mode
+            //Fill RsvTime
+            if (pvRrvTime) {
+                PSRrvTime_ab pBuf = (PSRrvTime_ab)pvRrvTime;
+                pBuf->wTxRrvTime = cpu_to_le16((WORD)s_uGetTxRsvTime(pDevice, PK_TYPE_11B, cbFrameSize, wCurrentRate, bNeedACK)); //1:CCK
+            }
+        }
+    }
+    //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_vGenerateTxParameter END.\n");
+}
+/*
+    PBYTE pbyBuffer,//point to pTxBufHead
+    WORD  wFragType,//00:Non-Frag, 01:Start, 02:Mid, 03:Last
+    UINT  cbFragmentSize,//Hdr+payoad+FCS
+*/
+
+
+BOOL
+s_bPacketToWirelessUsb(
+    IN  PSDevice         pDevice,
+    IN  BYTE             byPktType,
+    IN  PBYTE            usbPacketBuf,
+    IN  BOOL             bNeedEncryption,
+    IN  UINT             uSkbPacketLen,
+    IN  UINT             uDMAIdx,
+    IN  PSEthernetHeader psEthHeader,
+    IN  PBYTE            pPacket,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             uNodeIndex,
+    IN  WORD             wCurrentRate,
+    OUT UINT             *pcbHeaderLen,
+    OUT UINT             *pcbTotalLen
+    )
+{
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    UINT                cbFrameSize,cbFrameBodySize;
+    PTX_BUFFER          pTxBufHead;
+    UINT                cb802_1_H_len;
+    UINT                cbIVlen=0,cbICVlen=0,cbMIClen=0,cbMACHdLen=0,cbFCSlen=4;
+    UINT                cbMICHDR = 0;
+    BOOL                bNeedACK,bRTS;
+    PBYTE               pbyType,pbyMacHdr,pbyIVHead,pbyPayloadHead,pbyTxBufferAddr;
+    BYTE                abySNAP_RFC1042[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+    BYTE                abySNAP_Bridgetunnel[6] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8};
+    UINT                uDuration;
+    UINT                cbHeaderLength= 0,uPadding = 0;
+    PVOID               pvRrvTime;
+    PSMICHDRHead        pMICHDR;
+    PVOID               pvRTS;
+    PVOID               pvCTS;
+    PVOID               pvTxDataHd;
+    BYTE                byFBOption = AUTO_FB_NONE,byFragType;
+    WORD                wTxBufSize;
+    DWORD               dwMICKey0,dwMICKey1,dwMIC_Priority,dwCRC;
+    PDWORD              pdwMIC_L,pdwMIC_R;
+    BOOL                bSoftWEP = FALSE;
+
+
+
+
+    pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
+    if ((bNeedEncryption) && (pTransmitKey != NULL))  {
+        if (((PSKeyTable) (pTransmitKey->pvKeyTable))->bSoftWEP == TRUE) {
+            // WEP 256
+            bSoftWEP = TRUE;
+        }
+    }
+
+    pTxBufHead = (PTX_BUFFER) usbPacketBuf;
+    memset(pTxBufHead, 0, sizeof(TX_BUFFER));
+
+    // Get pkt type
+    if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
+        if (pDevice->dwDiagRefCount == 0) {
+            cb802_1_H_len = 8;
+        } else {
+            cb802_1_H_len = 2;
+        }
+    } else {
+        cb802_1_H_len = 0;
+    }
+
+    cbFrameBodySize = uSkbPacketLen - U_HEADER_LEN + cb802_1_H_len;
+
+    //Set packet type
+    pTxBufHead->wFIFOCtl |= (WORD)(byPktType<<8);
+
+    if (pDevice->dwDiagRefCount != 0) {
+        bNeedACK = FALSE;
+        pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
+    } else { //if (pDevice->dwDiagRefCount != 0) {
+        if ((pDevice->eOPMode == OP_MODE_ADHOC) ||
+            (pDevice->eOPMode == OP_MODE_AP)) {
+            if (IS_MULTICAST_ADDRESS(&(psEthHeader->abyDstAddr[0])) ||
+                IS_BROADCAST_ADDRESS(&(psEthHeader->abyDstAddr[0]))) {
+                bNeedACK = FALSE;
+                pTxBufHead->wFIFOCtl = pTxBufHead->wFIFOCtl & (~FIFOCTL_NEEDACK);
+            }
+            else {
+                bNeedACK = TRUE;
+                pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+            }
+        }
+        else {
+            // MSDUs in Infra mode always need ACK
+            bNeedACK = TRUE;
+            pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+        }
+    } //if (pDevice->dwDiagRefCount != 0) {
+
+    pTxBufHead->wTimeStamp = DEFAULT_MSDU_LIFETIME_RES_64us;
+
+    //Set FIFOCTL_LHEAD
+    if (pDevice->bLongHeader)
+        pTxBufHead->wFIFOCtl |= FIFOCTL_LHEAD;
+
+    if (pDevice->bSoftwareGenCrcErr) {
+        pTxBufHead->wFIFOCtl |= FIFOCTL_CRCDIS; // set tx descriptors to NO hardware CRC
+    }
+
+    //Set FRAGCTL_MACHDCNT
+    if (pDevice->bLongHeader) {
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN + 6;
+    } else {
+        cbMACHdLen = WLAN_HDR_ADDR3_LEN;
+    }
+    pTxBufHead->wFragCtl |= (WORD)(cbMACHdLen << 10);
+
+    //Set FIFOCTL_GrpAckPolicy
+    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+        pTxBufHead->wFIFOCtl |=	FIFOCTL_GRPACK;
+    }
+
+    //Set Auto Fallback Ctl
+    if (wCurrentRate >= RATE_18M) {
+        if (pDevice->byAutoFBCtrl == AUTO_FB_0) {
+            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_0;
+            byFBOption = AUTO_FB_0;
+        } else if (pDevice->byAutoFBCtrl == AUTO_FB_1) {
+            pTxBufHead->wFIFOCtl |= FIFOCTL_AUTO_FB_1;
+            byFBOption = AUTO_FB_1;
+        }
+    }
+
+    if (bSoftWEP != TRUE) {
+        if ((bNeedEncryption) && (pTransmitKey != NULL))  { //WEP enabled
+            if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) { //WEP40 or WEP104
+                pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
+            }
+            if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Tx Set wFragCtl == FRAGCTL_TKIP\n");
+                pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
+            }
+            else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { //CCMP
+                pTxBufHead->wFragCtl |= FRAGCTL_AES;
+            }
+        }
+    }
+
+
+    if ((bNeedEncryption) && (pTransmitKey != NULL))  {
+        if (pTransmitKey->byCipherSuite == KEY_CTL_WEP) {
+            cbIVlen = 4;
+            cbICVlen = 4;
+        }
+        else if (pTransmitKey->byCipherSuite == KEY_CTL_TKIP) {
+            cbIVlen = 8;//IV+ExtIV
+            cbMIClen = 8;
+            cbICVlen = 4;
+        }
+        if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) {
+            cbIVlen = 8;//RSN Header
+            cbICVlen = 8;//MIC
+            cbMICHDR = sizeof(SMICHDRHead);
+        }
+        if (bSoftWEP == FALSE) {
+            //MAC Header should be padding 0 to DW alignment.
+            uPadding = 4 - (cbMACHdLen%4);
+            uPadding %= 4;
+        }
+    }
+
+    cbFrameSize = cbMACHdLen + cbIVlen + (cbFrameBodySize + cbMIClen) + cbICVlen + cbFCSlen;
+
+    if ( (bNeedACK == FALSE) ||(cbFrameSize < pDevice->wRTSThreshold) ) {
+        bRTS = FALSE;
+    } else {
+        bRTS = TRUE;
+        pTxBufHead->wFIFOCtl |= (FIFOCTL_RTS | FIFOCTL_LRETRY);
+    }
+
+    pbyTxBufferAddr = (PBYTE) &(pTxBufHead->adwTxKey[0]);
+    wTxBufSize = sizeof(STxBufHead);
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
+        if (byFBOption == AUTO_FB_NONE) {
+            if (bRTS == TRUE) {//RTS_need
+                pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
+                pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g);
+            }
+            else { //RTS_needless
+                pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+                pvRTS = NULL;
+                pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
+                pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
+            }
+        } else {
+            // Auto Fall Back
+            if (bRTS == TRUE) {//RTS_need
+                pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS));
+                pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB);
+            }
+            else if (bRTS == FALSE) { //RTS_needless
+                pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+                pvRTS = NULL;
+                pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
+                pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB));
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB) + sizeof(STxDataHead_g_FB);
+            }
+        } // Auto Fall Back
+    }
+    else {//802.11a/b packet
+        if (byFBOption == AUTO_FB_NONE) {
+            if (bRTS == TRUE) {//RTS_need
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab));
+                cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab);
+            }
+            else if (bRTS == FALSE) { //RTS_needless, no MICHDR
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = NULL;
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
+            }
+        } else {
+            // Auto Fall Back
+            if (bRTS == TRUE) {//RTS_need
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB));
+                cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB);
+            }
+            else if (bRTS == FALSE) { //RTS_needless
+                pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+                pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+                pvRTS = NULL;
+                pvCTS = NULL;
+                pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+                cbHeaderLength = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_a_FB);
+            }
+        } // Auto Fall Back
+    }
+
+    pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderLength);
+    pbyIVHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding);
+    pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMACHdLen + uPadding + cbIVlen);
+
+
+    //=========================
+    //    No Fragmentation
+    //=========================
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No Fragmentation...\n");
+    byFragType = FRAGCTL_NONFRAG;
+    //uDMAIdx = TYPE_AC0DMA;
+    //pTxBufHead = (PSTxBufHead) &(pTxBufHead->adwTxKey[0]);
+
+
+    //Fill FIFO,RrvTime,RTS,and CTS
+    s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, (PVOID)pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
+                               cbFrameSize, bNeedACK, uDMAIdx, psEthHeader);
+    //Fill DataHead
+    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, uDMAIdx, bNeedACK,
+                                    0, 0, 1/*uMACfragNum*/, byFBOption);
+    // Generate TX MAC Header
+    s_vGenerateMACHeader(pDevice, pbyMacHdr, (WORD)uDuration, psEthHeader, bNeedEncryption,
+                           byFragType, uDMAIdx, 0);
+
+    if (bNeedEncryption == TRUE) {
+        //Fill TXKEY
+        s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+                         pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
+
+        if (pDevice->bEnableHostWEP) {
+            pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
+            pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
+        }
+    }
+
+    // 802.1H
+    if (ntohs(psEthHeader->wType) > MAX_DATA_LEN) {
+        if (pDevice->dwDiagRefCount == 0) {
+            if ( (psEthHeader->wType == TYPE_PKT_IPX) ||
+                 (psEthHeader->wType == cpu_to_le16(0xF380))) {
+                memcpy((PBYTE) (pbyPayloadHead), &abySNAP_Bridgetunnel[0], 6);
+            } else {
+                memcpy((PBYTE) (pbyPayloadHead), &abySNAP_RFC1042[0], 6);
+            }
+            pbyType = (PBYTE) (pbyPayloadHead + 6);
+            memcpy(pbyType, &(psEthHeader->wType), sizeof(WORD));
+        } else {
+            memcpy((PBYTE) (pbyPayloadHead), &(psEthHeader->wType), sizeof(WORD));
+
+        }
+
+    }
+
+
+    if (pPacket != NULL) {
+        // Copy the Packet into a tx Buffer
+        memcpy((pbyPayloadHead + cb802_1_H_len),
+                 (pPacket + U_HEADER_LEN),
+                 uSkbPacketLen - U_HEADER_LEN
+                 );
+
+    } else {
+        // while bRelayPacketSend psEthHeader is point to header+payload
+        memcpy((pbyPayloadHead + cb802_1_H_len), ((PBYTE)psEthHeader)+U_HEADER_LEN, uSkbPacketLen - U_HEADER_LEN);
+    }
+
+    ASSERT(uLength == cbNdisBodySize);
+
+    if ((bNeedEncryption == TRUE) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+
+        ///////////////////////////////////////////////////////////////////
+
+        if (pDevice->sMgmtObj.eAuthenMode == WMAC_AUTH_WPANONE) {
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+        }
+        else if ((pTransmitKey->dwKeyIndex & AUTHENTICATOR_KEY) != 0) {
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+        }
+        else {
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[24]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[28]);
+        }
+        // DO Software Michael
+        MIC_vInit(dwMICKey0, dwMICKey1);
+        MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12);
+        dwMIC_Priority = 0;
+        MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+
+        ///////////////////////////////////////////////////////////////////
+
+        //DBG_PRN_GRP12(("Length:%d, %d\n", cbFrameBodySize, uFromHDtoPLDLength));
+        //for (ii = 0; ii < cbFrameBodySize; ii++) {
+        //    DBG_PRN_GRP12(("%02x ", *((PBYTE)((pbyPayloadHead + cb802_1_H_len) + ii))));
+        //}
+        //DBG_PRN_GRP12(("\n\n\n"));
+
+        MIC_vAppend(pbyPayloadHead, cbFrameBodySize);
+
+        pdwMIC_L = (PDWORD)(pbyPayloadHead + cbFrameBodySize);
+        pdwMIC_R = (PDWORD)(pbyPayloadHead + cbFrameBodySize + 4);
+
+        MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
+        MIC_vUnInit();
+
+        if (pDevice->bTxMICFail == TRUE) {
+            *pdwMIC_L = 0;
+            *pdwMIC_R = 0;
+            pDevice->bTxMICFail = FALSE;
+        }
+        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen);
+        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lX, %lX\n", *pdwMIC_L, *pdwMIC_R);
+    }
+
+
+    if (bSoftWEP == TRUE) {
+
+        s_vSWencryption(pDevice, pTransmitKey, (pbyPayloadHead), (WORD)(cbFrameBodySize + cbMIClen));
+
+    } else if (  ((pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) && (bNeedEncryption == TRUE))  ||
+          ((pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) && (bNeedEncryption == TRUE))   ||
+          ((pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) && (bNeedEncryption == TRUE))      ) {
+        cbFrameSize -= cbICVlen;
+    }
+
+    if (pDevice->bSoftwareGenCrcErr == TRUE) {
+        UINT   cbLen;
+        PDWORD pdwCRC;
+
+        dwCRC = 0xFFFFFFFFL;
+        cbLen = cbFrameSize - cbFCSlen;
+        // calculate CRC, and wrtie CRC value to end of TD
+        dwCRC = CRCdwGetCrc32Ex(pbyMacHdr, cbLen, dwCRC);
+        pdwCRC = (PDWORD)(pbyMacHdr + cbLen);
+        // finally, we must invert dwCRC to get the correct answer
+        *pdwCRC = ~dwCRC;
+        // Force Error
+        *pdwCRC -= 1;
+    } else {
+        cbFrameSize -= cbFCSlen;
+    }
+
+    *pcbHeaderLen = cbHeaderLength;
+    *pcbTotalLen = cbHeaderLength + cbFrameSize ;
+
+
+    //Set FragCtl in TxBufferHead
+    pTxBufHead->wFragCtl |= (WORD)byFragType;
+
+
+    return TRUE;
+
+}
+
+
+/*+
+ *
+ * Description:
+ *      Translate 802.3 to 802.11 header
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to adpater
+ *      dwTxBufferAddr  - Transmit Buffer
+ *      pPacket         - Packet from upper layer
+ *      cbPacketSize    - Transmit Data Length
+ *  Out:
+ *      pcbHeadSize         - Header size of MAC&Baseband control and 802.11 Header
+ *      pcbAppendPayload    - size of append payload for 802.1H translation
+ *
+ * Return Value: none
+ *
+-*/
+
+VOID
+s_vGenerateMACHeader (
+    IN PSDevice         pDevice,
+    IN PBYTE            pbyBufferAddr,
+    IN WORD             wDuration,
+    IN PSEthernetHeader psEthHeader,
+    IN BOOL             bNeedEncrypt,
+    IN WORD             wFragType,
+    IN UINT             uDMAIdx,
+    IN UINT             uFragIdx
+    )
+{
+    PS802_11Header  pMACHeader = (PS802_11Header)pbyBufferAddr;
+
+    memset(pMACHeader, 0, (sizeof(S802_11Header)));  //- sizeof(pMACHeader->dwIV)));
+
+    if (uDMAIdx == TYPE_ATIMDMA) {
+    	pMACHeader->wFrameCtl = TYPE_802_11_ATIM;
+    } else {
+        pMACHeader->wFrameCtl = TYPE_802_11_DATA;
+    }
+
+    if (pDevice->eOPMode == OP_MODE_AP) {
+        memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+        memcpy(&(pMACHeader->abyAddr2[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+        pMACHeader->wFrameCtl |= FC_FROMDS;
+    }
+    else {
+        if (pDevice->eOPMode == OP_MODE_ADHOC) {
+            memcpy(&(pMACHeader->abyAddr1[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr3[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+        }
+        else {
+            memcpy(&(pMACHeader->abyAddr3[0]), &(psEthHeader->abyDstAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr2[0]), &(psEthHeader->abySrcAddr[0]), U_ETHER_ADDR_LEN);
+            memcpy(&(pMACHeader->abyAddr1[0]), &(pDevice->abyBSSID[0]), U_ETHER_ADDR_LEN);
+            pMACHeader->wFrameCtl |= FC_TODS;
+        }
+    }
+
+    if (bNeedEncrypt)
+        pMACHeader->wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_ISWEP(1));
+
+    pMACHeader->wDurationID = cpu_to_le16(wDuration);
+
+    if (pDevice->bLongHeader) {
+        PWLAN_80211HDR_A4 pMACA4Header  = (PWLAN_80211HDR_A4) pbyBufferAddr;
+        pMACHeader->wFrameCtl |= (FC_TODS | FC_FROMDS);
+        memcpy(pMACA4Header->abyAddr4, pDevice->abyBSSID, WLAN_ADDR_LEN);
+    }
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+
+    //Set FragNumber in Sequence Control
+    pMACHeader->wSeqCtl |= cpu_to_le16((WORD)uFragIdx);
+
+    if ((wFragType == FRAGCTL_ENDFRAG) || (wFragType == FRAGCTL_NONFRAG)) {
+        pDevice->wSeqCounter++;
+        if (pDevice->wSeqCounter > 0x0fff)
+            pDevice->wSeqCounter = 0;
+    }
+
+    if ((wFragType == FRAGCTL_STAFRAG) || (wFragType == FRAGCTL_MIDFRAG)) { //StartFrag or MidFrag
+        pMACHeader->wFrameCtl |= FC_MOREFRAG;
+    }
+}
+
+
+
+/*+
+ *
+ * Description:
+ *      Request instructs a MAC to transmit a 802.11 management packet through
+ *      the adapter onto the medium.
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext  - Pointer to the adapter
+ *      pPacket         - A pointer to a descriptor for the packet to transmit
+ *  Out:
+ *      none
+ *
+ * Return Value: CMD_STATUS_PENDING if MAC Tx resource avaliable; otherwise FALSE
+ *
+-*/
+
+CMD_STATUS csMgmt_xmit(
+    IN  PSDevice pDevice,
+    IN  PSTxMgmtPacket pPacket
+    )
+{
+    BYTE            byPktType;
+    PBYTE           pbyTxBufferAddr;
+    PVOID           pvRTS;
+    PSCTS           pCTS;
+    PVOID           pvTxDataHd;
+    UINT            uDuration;
+    UINT            cbReqCount;
+    PS802_11Header  pMACHeader;
+    UINT            cbHeaderSize;
+    UINT            cbFrameBodySize;
+    BOOL            bNeedACK;
+    BOOL            bIsPSPOLL = FALSE;
+    PSTxBufHead     pTxBufHead;
+    UINT            cbFrameSize;
+    UINT            cbIVlen = 0;
+    UINT            cbICVlen = 0;
+    UINT            cbMIClen = 0;
+    UINT            cbFCSlen = 4;
+    UINT            uPadding = 0;
+    WORD            wTxBufSize;
+    UINT            cbMacHdLen;
+    SEthernetHeader sEthHeader;
+    PVOID           pvRrvTime;
+    PVOID           pMICHDR;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    WORD            wCurrentRate = RATE_1M;
+    PTX_BUFFER          pTX_Buffer;
+    PUSB_SEND_CONTEXT   pContext;
+
+
+
+    pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+    if (NULL == pContext) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
+        return CMD_STATUS_RESOURCES;
+    }
+
+    pTX_Buffer = (PTX_BUFFER) (&pContext->Data[0]);
+    pbyTxBufferAddr = (PBYTE)&(pTX_Buffer->adwTxKey[0]);
+    cbFrameBodySize = pPacket->cbPayloadLen;
+    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
+    wTxBufSize = sizeof(STxBufHead);
+    memset(pTxBufHead, 0, wTxBufSize);
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        wCurrentRate = RATE_6M;
+        byPktType = PK_TYPE_11A;
+    } else {
+        wCurrentRate = RATE_1M;
+        byPktType = PK_TYPE_11B;
+    }
+
+    // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
+    // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
+    //                    And cmd timer will wait data pkt TX finish before scanning so it's OK
+    //                    to set power here.
+    if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+        RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
+    } else {
+        RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
+    }
+    pDevice->wCurrentRate = wCurrentRate;
+
+
+    //Set packet type
+    if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
+        pTxBufHead->wFIFOCtl = 0;
+    }
+    else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+    }
+    else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
+    }
+    else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
+    }
+
+    pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
+    pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+
+
+    if (IS_MULTICAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0])) ||
+        IS_BROADCAST_ADDRESS(&(pPacket->p80211Header->sA3.abyAddr1[0]))) {
+        bNeedACK = FALSE;
+    }
+    else {
+        bNeedACK = TRUE;
+        pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+    };
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
+        (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
+
+        pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
+        //Set Preamble type always long
+        //pDevice->byPreambleType = PREAMBLE_LONG;
+        // probe-response don't retry
+        //if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
+        //     bNeedACK = FALSE;
+        //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK);
+        //}
+    }
+
+    pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
+
+    if ((pPacket->p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
+        bIsPSPOLL = TRUE;
+        cbMacHdLen = WLAN_HDR_ADDR2_LEN;
+    } else {
+        cbMacHdLen = WLAN_HDR_ADDR3_LEN;
+    }
+
+    //Set FRAGCTL_MACHDCNT
+    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)(cbMacHdLen << 10));
+
+    // Notes:
+    // Although spec says MMPDU can be fragmented; In most case,
+    // no one will send a MMPDU under fragmentation. With RTS may occur.
+    pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP
+
+    if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
+        if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
+            cbIVlen = 4;
+            cbICVlen = 4;
+    	    pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+            cbIVlen = 8;//IV+ExtIV
+            cbMIClen = 8;
+            cbICVlen = 4;
+    	    pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
+    	    //We need to get seed here for filling TxKey entry.
+            //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
+            //            pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+            cbIVlen = 8;//RSN Header
+            cbICVlen = 8;//MIC
+            pTxBufHead->wFragCtl |= FRAGCTL_AES;
+            pDevice->bAES = TRUE;
+        }
+        //MAC Header should be padding 0 to DW alignment.
+        uPadding = 4 - (cbMacHdLen%4);
+        uPadding %= 4;
+    }
+
+    cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen;
+
+    //Set FIFOCTL_GrpAckPolicy
+    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+        pTxBufHead->wFIFOCtl |=	FIFOCTL_GRPACK;
+    }
+    //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
+
+    //Set RrvTime/RTS/CTS Buffer
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
+
+        pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = NULL;
+        pvRTS = NULL;
+        pCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+        pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS));
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + sizeof(SCTS) + sizeof(STxDataHead_g);
+    }
+    else { // 802.11a/b packet
+        pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = NULL;
+        pvRTS = NULL;
+        pCTS = NULL;
+        pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + sizeof(STxDataHead_ab);
+    }
+
+    memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
+
+    memcpy(&(sEthHeader.abyDstAddr[0]), &(pPacket->p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
+    memcpy(&(sEthHeader.abySrcAddr[0]), &(pPacket->p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
+    //=========================
+    //    No Fragmentation
+    //=========================
+    pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
+
+
+    //Fill FIFO,RrvTime,RTS,and CTS
+    s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate,  pbyTxBufferAddr, pvRrvTime, pvRTS, pCTS,
+                           cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
+
+    //Fill DataHead
+    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+                                0, 0, 1, AUTO_FB_NONE);
+
+    pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
+
+    cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + cbFrameBodySize;
+
+    if (WLAN_GET_FC_ISWEP(pPacket->p80211Header->sA4.wFrameCtl) != 0) {
+        PBYTE           pbyIVHead;
+        PBYTE           pbyPayloadHead;
+        PBYTE           pbyBSSID;
+        PSKeyItem       pTransmitKey = NULL;
+
+        pbyIVHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding);
+        pbyPayloadHead = (PBYTE)(pbyTxBufferAddr + cbHeaderSize + cbMacHdLen + uPadding + cbIVlen);
+        do {
+            if ((pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) &&
+                (pDevice->bLinkPass == TRUE)) {
+                pbyBSSID = pDevice->abyBSSID;
+                // get pairwise key
+                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
+                    // get group key
+                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+                        break;
+                    }
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get PTK.\n");
+                    break;
+                }
+            }
+            // get group key
+            pbyBSSID = pDevice->abyBroadcastAddr;
+            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+                pTransmitKey = NULL;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode);
+            } else {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Get GTK.\n");
+            }
+        } while(FALSE);
+        //Fill TXKEY
+        s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+                     (PBYTE)pMACHeader, (WORD)cbFrameBodySize, NULL);
+
+        memcpy(pMACHeader, pPacket->p80211Header, cbMacHdLen);
+        memcpy(pbyPayloadHead, ((PBYTE)(pPacket->p80211Header) + cbMacHdLen),
+                 cbFrameBodySize);
+    }
+    else {
+        // Copy the Packet into a tx Buffer
+        memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+    }
+
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+    pDevice->wSeqCounter++ ;
+    if (pDevice->wSeqCounter > 0x0fff)
+        pDevice->wSeqCounter = 0;
+
+    if (bIsPSPOLL) {
+        // The MAC will automatically replace the Duration-field of MAC header by Duration-field
+        // of  FIFO control header.
+        // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
+        // in the same place of other packet's Duration-field).
+        // And it will cause Cisco-AP to issue Disassociation-packet
+        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+        } else {
+            ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(pPacket->p80211Header->sA2.wDurationID);
+        }
+    }
+
+
+    pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount));
+    pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+    pTX_Buffer->byType = 0x00;
+
+    pContext->pPacket = NULL;
+    pContext->Type = CONTEXT_MGMT_PACKET;
+    pContext->uBufLen = (WORD)cbReqCount + 4;  //USB header
+
+    if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) {
+        s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
+    }
+    else {
+        s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
+    }
+
+    PIPEnsSendBulkOut(pDevice,pContext);
+    return CMD_STATUS_PENDING;
+}
+
+
+CMD_STATUS
+csBeacon_xmit(
+    IN  PSDevice pDevice,
+    IN  PSTxMgmtPacket pPacket
+    )
+{
+
+    UINT                cbFrameSize = pPacket->cbMPDULen + WLAN_FCS_LEN;
+    UINT                cbHeaderSize = 0;
+    WORD                wTxBufSize = sizeof(STxShortBufHead);
+    PSTxShortBufHead    pTxBufHead;
+    PS802_11Header      pMACHeader;
+    PSTxDataHead_ab     pTxDataHead;
+    WORD                wCurrentRate;
+    UINT                cbFrameBodySize;
+    UINT                cbReqCount;
+    PBEACON_BUFFER      pTX_Buffer;
+    PBYTE               pbyTxBufferAddr;
+    PUSB_SEND_CONTEXT   pContext;
+    CMD_STATUS          status;
+
+
+    pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+    if (NULL == pContext) {
+        status = CMD_STATUS_RESOURCES;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ManagementSend TX...NO CONTEXT!\n");
+        return status ;
+    }
+    pTX_Buffer = (PBEACON_BUFFER) (&pContext->Data[0]);
+    pbyTxBufferAddr = (PBYTE)&(pTX_Buffer->wFIFOCtl);
+
+    cbFrameBodySize = pPacket->cbPayloadLen;
+
+    pTxBufHead = (PSTxShortBufHead) pbyTxBufferAddr;
+    wTxBufSize = sizeof(STxShortBufHead);
+    memset(pTxBufHead, 0, wTxBufSize);
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        wCurrentRate = RATE_6M;
+        pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
+        //Get SignalField,ServiceField,Length
+        BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11A,
+            (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField)
+        );
+        //Get Duration and TimeStampOff
+        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameSize, PK_TYPE_11A,
+                                                          wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
+        pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+        cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
+    } else {
+        wCurrentRate = RATE_1M;
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+        pTxDataHead = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize);
+        //Get SignalField,ServiceField,Length
+        BBvCaculateParameter(pDevice, cbFrameSize, wCurrentRate, PK_TYPE_11B,
+            (PWORD)&(pTxDataHead->wTransmitLength), (PBYTE)&(pTxDataHead->byServiceField), (PBYTE)&(pTxDataHead->bySignalField)
+        );
+        //Get Duration and TimeStampOff
+        pTxDataHead->wDuration = cpu_to_le16((WORD)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameSize, PK_TYPE_11B,
+                                                          wCurrentRate, FALSE, 0, 0, 1, AUTO_FB_NONE));
+        pTxDataHead->wTimeStampOff = wTimeStampOff[pDevice->byPreambleType%2][wCurrentRate%MAX_RATE];
+        cbHeaderSize = wTxBufSize + sizeof(STxDataHead_ab);
+    }
+
+    //Generate Beacon Header
+    pMACHeader = (PS802_11Header)(pbyTxBufferAddr + cbHeaderSize);
+    memcpy(pMACHeader, pPacket->p80211Header, pPacket->cbMPDULen);
+
+    pMACHeader->wDurationID = 0;
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+    pDevice->wSeqCounter++ ;
+    if (pDevice->wSeqCounter > 0x0fff)
+        pDevice->wSeqCounter = 0;
+
+    cbReqCount = cbHeaderSize + WLAN_HDR_ADDR3_LEN + cbFrameBodySize;
+
+    pTX_Buffer->wTxByteCount = (WORD)cbReqCount;
+    pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+    pTX_Buffer->byType = 0x01;
+
+    pContext->pPacket = NULL;
+    pContext->Type = CONTEXT_MGMT_PACKET;
+    pContext->uBufLen = (WORD)cbReqCount + 4;  //USB header
+
+    PIPEnsSendBulkOut(pDevice,pContext);
+    return CMD_STATUS_PENDING;
+
+}
+
+
+
+
+
+VOID
+vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb) {
+
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BYTE            byPktType;
+    PBYTE           pbyTxBufferAddr;
+    PVOID           pvRTS;
+    PVOID           pvCTS;
+    PVOID           pvTxDataHd;
+    UINT            uDuration;
+    UINT            cbReqCount;
+    PS802_11Header  pMACHeader;
+    UINT            cbHeaderSize;
+    UINT            cbFrameBodySize;
+    BOOL            bNeedACK;
+    BOOL            bIsPSPOLL = FALSE;
+    PSTxBufHead     pTxBufHead;
+    UINT            cbFrameSize;
+    UINT            cbIVlen = 0;
+    UINT            cbICVlen = 0;
+    UINT            cbMIClen = 0;
+    UINT            cbFCSlen = 4;
+    UINT            uPadding = 0;
+    UINT            cbMICHDR = 0;
+    UINT            uLength = 0;
+    DWORD           dwMICKey0, dwMICKey1;
+    DWORD           dwMIC_Priority;
+    PDWORD          pdwMIC_L;
+    PDWORD          pdwMIC_R;
+    WORD            wTxBufSize;
+    UINT            cbMacHdLen;
+    SEthernetHeader sEthHeader;
+    PVOID           pvRrvTime;
+    PVOID           pMICHDR;
+    WORD            wCurrentRate = RATE_1M;
+    PUWLAN_80211HDR  p80211Header;
+    UINT             uNodeIndex = 0;
+    BOOL            bNodeExist = FALSE;
+    SKeyItem        STempKey;
+    PSKeyItem       pTransmitKey = NULL;
+    PBYTE           pbyIVHead;
+    PBYTE           pbyPayloadHead;
+    PBYTE           pbyMacHdr;
+    UINT            cbExtSuppRate = 0;
+    PTX_BUFFER          pTX_Buffer;
+    PUSB_SEND_CONTEXT   pContext;
+//    PWLAN_IE        pItem;
+
+
+    pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL;
+
+    if(skb->len <= WLAN_HDR_ADDR3_LEN) {
+       cbFrameBodySize = 0;
+    }
+    else {
+       cbFrameBodySize = skb->len - WLAN_HDR_ADDR3_LEN;
+    }
+    p80211Header = (PUWLAN_80211HDR)skb->data;
+
+    pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+    if (NULL == pContext) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0 TX...NO CONTEXT!\n");
+        dev_kfree_skb_irq(skb);
+        return ;
+    }
+
+    pTX_Buffer = (PTX_BUFFER)(&pContext->Data[0]);
+    pbyTxBufferAddr = (PBYTE)(&pTX_Buffer->adwTxKey[0]);
+    pTxBufHead = (PSTxBufHead) pbyTxBufferAddr;
+    wTxBufSize = sizeof(STxBufHead);
+    memset(pTxBufHead, 0, wTxBufSize);
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        wCurrentRate = RATE_6M;
+        byPktType = PK_TYPE_11A;
+    } else {
+        wCurrentRate = RATE_1M;
+        byPktType = PK_TYPE_11B;
+    }
+
+    // SetPower will cause error power TX state for OFDM Date packet in TX buffer.
+    // 2004.11.11 Kyle -- Using OFDM power to tx MngPkt will decrease the connection capability.
+    //                    And cmd timer will wait data pkt TX finish before scanning so it's OK
+    //                    to set power here.
+    if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+        RFbSetPower(pDevice, wCurrentRate, pDevice->byCurrentCh);
+    } else {
+        RFbSetPower(pDevice, wCurrentRate, pMgmt->uCurrChannel);
+    }
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x \n", p80211Header->sA3.wFrameCtl);
+
+    //Set packet type
+    if (byPktType == PK_TYPE_11A) {//0000 0000 0000 0000
+        pTxBufHead->wFIFOCtl = 0;
+    }
+    else if (byPktType == PK_TYPE_11B) {//0000 0001 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11B;
+    }
+    else if (byPktType == PK_TYPE_11GB) {//0000 0010 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GB;
+    }
+    else if (byPktType == PK_TYPE_11GA) {//0000 0011 0000 0000
+        pTxBufHead->wFIFOCtl |= FIFOCTL_11GA;
+    }
+
+    pTxBufHead->wFIFOCtl |= FIFOCTL_TMOEN;
+    pTxBufHead->wTimeStamp = cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us);
+
+
+    if (IS_MULTICAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0])) ||
+        IS_BROADCAST_ADDRESS(&(p80211Header->sA3.abyAddr1[0]))) {
+        bNeedACK = FALSE;
+        if (pDevice->bEnableHostWEP) {
+            uNodeIndex = 0;
+            bNodeExist = TRUE;
+        };
+    }
+    else {
+        if (pDevice->bEnableHostWEP) {
+            if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p80211Header->sA3.abyAddr1), &uNodeIndex))
+                bNodeExist = TRUE;
+        };
+        bNeedACK = TRUE;
+        pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
+    };
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
+        (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ) {
+
+        pTxBufHead->wFIFOCtl |= FIFOCTL_LRETRY;
+        //Set Preamble type always long
+        //pDevice->byPreambleType = PREAMBLE_LONG;
+
+        // probe-response don't retry
+        //if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_MGMT_PROBE_RSP) {
+        //     bNeedACK = FALSE;
+        //     pTxBufHead->wFIFOCtl  &= (~FIFOCTL_NEEDACK);
+        //}
+    }
+
+    pTxBufHead->wFIFOCtl |= (FIFOCTL_GENINT | FIFOCTL_ISDMA0);
+
+    if ((p80211Header->sA4.wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL) {
+        bIsPSPOLL = TRUE;
+        cbMacHdLen = WLAN_HDR_ADDR2_LEN;
+    } else {
+        cbMacHdLen = WLAN_HDR_ADDR3_LEN;
+    }
+
+    // hostapd deamon ext support rate patch
+    if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
+
+        if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0) {
+            cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN;
+         }
+
+        if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0) {
+            cbExtSuppRate += ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+         }
+
+         if (cbExtSuppRate >0) {
+            cbFrameBodySize = WLAN_ASSOCRESP_OFF_SUPP_RATES;
+         }
+    }
+
+
+    //Set FRAGCTL_MACHDCNT
+    pTxBufHead->wFragCtl |= cpu_to_le16((WORD)cbMacHdLen << 10);
+
+    // Notes:
+    // Although spec says MMPDU can be fragmented; In most case,
+    // no one will send a MMPDU under fragmentation. With RTS may occur.
+    pDevice->bAES = FALSE;  //Set FRAGCTL_WEPTYP
+
+
+    if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
+        if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled) {
+            cbIVlen = 4;
+            cbICVlen = 4;
+    	    pTxBufHead->wFragCtl |= FRAGCTL_LEGACY;
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+            cbIVlen = 8;//IV+ExtIV
+            cbMIClen = 8;
+            cbICVlen = 4;
+    	    pTxBufHead->wFragCtl |= FRAGCTL_TKIP;
+    	    //We need to get seed here for filling TxKey entry.
+            //TKIPvMixKey(pTransmitKey->abyKey, pDevice->abyCurrentNetAddr,
+            //            pTransmitKey->wTSC15_0, pTransmitKey->dwTSC47_16, pDevice->abyPRNG);
+        }
+        else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+            cbIVlen = 8;//RSN Header
+            cbICVlen = 8;//MIC
+            cbMICHDR = sizeof(SMICHDRHead);
+            pTxBufHead->wFragCtl |= FRAGCTL_AES;
+            pDevice->bAES = TRUE;
+        }
+        //MAC Header should be padding 0 to DW alignment.
+        uPadding = 4 - (cbMacHdLen%4);
+        uPadding %= 4;
+    }
+
+    cbFrameSize = cbMacHdLen + cbFrameBodySize + cbIVlen + cbMIClen + cbICVlen + cbFCSlen + cbExtSuppRate;
+
+    //Set FIFOCTL_GrpAckPolicy
+    if (pDevice->bGrpAckPolicy == TRUE) {//0000 0100 0000 0000
+        pTxBufHead->wFIFOCtl |=	FIFOCTL_GRPACK;
+    }
+    //the rest of pTxBufHead->wFragCtl:FragTyp will be set later in s_vFillFragParameter()
+
+
+    if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet
+
+        pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS));
+        pvRTS = NULL;
+        pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR);
+        pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS));
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS) + sizeof(STxDataHead_g);
+
+    }
+    else {//802.11a/b packet
+
+        pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize);
+        pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab));
+        pvRTS = NULL;
+        pvCTS = NULL;
+        pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR);
+        cbHeaderSize = wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR + sizeof(STxDataHead_ab);
+    }
+    memset((PVOID)(pbyTxBufferAddr + wTxBufSize), 0, (cbHeaderSize - wTxBufSize));
+    memcpy(&(sEthHeader.abyDstAddr[0]), &(p80211Header->sA3.abyAddr1[0]), U_ETHER_ADDR_LEN);
+    memcpy(&(sEthHeader.abySrcAddr[0]), &(p80211Header->sA3.abyAddr2[0]), U_ETHER_ADDR_LEN);
+    //=========================
+    //    No Fragmentation
+    //=========================
+    pTxBufHead->wFragCtl |= (WORD)FRAGCTL_NONFRAG;
+
+
+    //Fill FIFO,RrvTime,RTS,and CTS
+    s_vGenerateTxParameter(pDevice, byPktType, wCurrentRate, pbyTxBufferAddr, pvRrvTime, pvRTS, pvCTS,
+                           cbFrameSize, bNeedACK, TYPE_TXDMA0, &sEthHeader);
+
+    //Fill DataHead
+    uDuration = s_uFillDataHead(pDevice, byPktType, wCurrentRate, pvTxDataHd, cbFrameSize, TYPE_TXDMA0, bNeedACK,
+                                0, 0, 1, AUTO_FB_NONE);
+
+    pMACHeader = (PS802_11Header) (pbyTxBufferAddr + cbHeaderSize);
+
+    cbReqCount = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen + (cbFrameBodySize + cbMIClen) + cbExtSuppRate;
+
+    pbyMacHdr = (PBYTE)(pbyTxBufferAddr + cbHeaderSize);
+    pbyPayloadHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding + cbIVlen);
+    pbyIVHead = (PBYTE)(pbyMacHdr + cbMacHdLen + uPadding);
+
+    // Copy the Packet into a tx Buffer
+    memcpy(pbyMacHdr, skb->data, cbMacHdLen);
+
+    // version set to 0, patch for hostapd deamon
+    pMACHeader->wFrameCtl &= cpu_to_le16(0xfffc);
+    memcpy(pbyPayloadHead, (skb->data + cbMacHdLen), cbFrameBodySize);
+
+    // replace support rate, patch for hostapd deamon( only support 11M)
+    if (WLAN_GET_FC_FSTYPE(p80211Header->sA4.wFrameCtl) == WLAN_FSTYPE_ASSOCRESP) {
+        if (cbExtSuppRate != 0) {
+            if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len != 0)
+                memcpy((pbyPayloadHead + cbFrameBodySize),
+                        pMgmt->abyCurrSuppRates,
+                        ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN
+                       );
+             if (((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len != 0)
+                memcpy((pbyPayloadHead + cbFrameBodySize) + ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates)->len + WLAN_IEHDR_LEN,
+                        pMgmt->abyCurrExtSuppRates,
+                        ((PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+                       );
+         }
+    }
+
+    // Set wep
+    if (WLAN_GET_FC_ISWEP(p80211Header->sA4.wFrameCtl) != 0) {
+
+        if (pDevice->bEnableHostWEP) {
+            pTransmitKey = &STempKey;
+            pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
+            pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
+            pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
+            pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
+            pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
+            memcpy(pTransmitKey->abyKey,
+                &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
+                pTransmitKey->uKeyLength
+                );
+        }
+
+        if ((pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) {
+
+            dwMICKey0 = *(PDWORD)(&pTransmitKey->abyKey[16]);
+            dwMICKey1 = *(PDWORD)(&pTransmitKey->abyKey[20]);
+
+            // DO Software Michael
+            MIC_vInit(dwMICKey0, dwMICKey1);
+            MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12);
+            dwMIC_Priority = 0;
+            MIC_vAppend((PBYTE)&dwMIC_Priority, 4);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1);
+
+            uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen;
+
+            MIC_vAppend((pbyTxBufferAddr + uLength), cbFrameBodySize);
+
+            pdwMIC_L = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize);
+            pdwMIC_R = (PDWORD)(pbyTxBufferAddr + uLength + cbFrameBodySize + 4);
+
+            MIC_vGetMIC(pdwMIC_L, pdwMIC_R);
+            MIC_vUnInit();
+
+            if (pDevice->bTxMICFail == TRUE) {
+                *pdwMIC_L = 0;
+                *pdwMIC_R = 0;
+                pDevice->bTxMICFail = FALSE;
+            }
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R);
+
+        }
+
+        s_vFillTxKey(pDevice, (PBYTE)(pTxBufHead->adwTxKey), pbyIVHead, pTransmitKey,
+                     pbyMacHdr, (WORD)cbFrameBodySize, (PBYTE)pMICHDR);
+
+        if (pDevice->bEnableHostWEP) {
+            pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16 = pTransmitKey->dwTSC47_16;
+            pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0 = pTransmitKey->wTSC15_0;
+        }
+
+        if ((pDevice->byLocalID <= REV_ID_VT3253_A1)) {
+            s_vSWencryption(pDevice, pTransmitKey, pbyPayloadHead, (WORD)(cbFrameBodySize + cbMIClen));
+        }
+    }
+
+    pMACHeader->wSeqCtl = cpu_to_le16(pDevice->wSeqCounter << 4);
+    pDevice->wSeqCounter++ ;
+    if (pDevice->wSeqCounter > 0x0fff)
+        pDevice->wSeqCounter = 0;
+
+
+    if (bIsPSPOLL) {
+        // The MAC will automatically replace the Duration-field of MAC header by Duration-field
+        // of  FIFO control header.
+        // This will cause AID-field of PS-POLL packet be incorrect (Because PS-POLL's AID field is
+        // in the same place of other packet's Duration-field).
+        // And it will cause Cisco-AP to issue Disassociation-packet
+        if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_a = cpu_to_le16(p80211Header->sA2.wDurationID);
+            ((PSTxDataHead_g)pvTxDataHd)->wDuration_b = cpu_to_le16(p80211Header->sA2.wDurationID);
+        } else {
+            ((PSTxDataHead_ab)pvTxDataHd)->wDuration = cpu_to_le16(p80211Header->sA2.wDurationID);
+        }
+    }
+
+    pTX_Buffer->wTxByteCount = cpu_to_le16((WORD)(cbReqCount));
+    pTX_Buffer->byPKTNO = (BYTE) (((wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+    pTX_Buffer->byType = 0x00;
+
+    pContext->pPacket = skb;
+    pContext->Type = CONTEXT_MGMT_PACKET;
+    pContext->uBufLen = (WORD)cbReqCount + 4;  //USB header
+
+    if (WLAN_GET_FC_TODS(pMACHeader->wFrameCtl) == 0) {
+        s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr1[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
+    }
+    else {
+        s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pMACHeader->abyAddr3[0]),(WORD)cbFrameSize,pTX_Buffer->wFIFOCtl);
+    }
+    PIPEnsSendBulkOut(pDevice,pContext);
+    return ;
+
+}
+
+
+
+
+//TYPE_AC0DMA data tx
+/*
+ * Description:
+ *      Tx packet via AC0DMA(DMA1)
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      skb             - Pointer to tx skb packet
+ *  Out:
+ *      void
+ *
+ * Return Value: NULL
+ */
+
+
+
+NTSTATUS
+nsDMA_tx_packet(
+    IN  PSDevice pDevice,
+    IN  UINT    uDMAIdx,
+    IN  struct sk_buff *skb
+    )
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            BytesToWrite =0,uHeaderLen = 0;
+    UINT            uNodeIndex = 0;
+    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    WORD            wAID;
+    BYTE            byPktType;
+    BOOL            bNeedEncryption = FALSE;
+    PSKeyItem       pTransmitKey = NULL;
+    SKeyItem        STempKey;
+    UINT            ii;
+    BOOL            bTKIP_UseGTK = FALSE;
+    BOOL            bNeedDeAuth = FALSE;
+    PBYTE           pbyBSSID;
+    BOOL            bNodeExist = FALSE;
+    PUSB_SEND_CONTEXT pContext;
+    BOOL            fConvertedPacket;
+    PTX_BUFFER      pTX_Buffer;
+    UINT            status;
+    WORD            wKeepRate = pDevice->wCurrentRate;
+    struct net_device_stats* pStats = &pDevice->stats;
+//#ifdef WPA_SM_Transtatus
+  //  extern SWPAResult wpa_Result;
+//#endif
+     BOOL            bTxeapol_key = FALSE;
+
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+
+        if (pDevice->uAssocCount == 0) {
+            dev_kfree_skb_irq(skb);
+            return 0;
+        }
+
+        if (IS_MULTICAST_ADDRESS((PBYTE)(skb->data))) {
+            uNodeIndex = 0;
+            bNodeExist = TRUE;
+            if (pMgmt->sNodeDBTable[0].bPSEnable) {
+
+                skb_queue_tail(&(pMgmt->sNodeDBTable[0].sTxPSQueue), skb);
+                pMgmt->sNodeDBTable[0].wEnQueueCnt++;
+                // set tx map
+                pMgmt->abyPSTxMap[0] |= byMask[0];
+                return 0;
+            }
+            // muticast/broadcast data rate
+
+            if (pDevice->byBBType != BB_TYPE_11A)
+                pDevice->wCurrentRate = RATE_2M;
+            else
+                pDevice->wCurrentRate = RATE_24M;
+            // long preamble type
+            pDevice->byPreambleType = PREAMBLE_SHORT;
+
+        }else {
+
+            if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(skb->data), &uNodeIndex)) {
+
+                if (pMgmt->sNodeDBTable[uNodeIndex].bPSEnable) {
+
+                    skb_queue_tail(&pMgmt->sNodeDBTable[uNodeIndex].sTxPSQueue, skb);
+
+                    pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt++;
+                    // set tx map
+                    wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID;
+                    pMgmt->abyPSTxMap[wAID >> 3] |=  byMask[wAID & 7];
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n",
+                             (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]);
+
+                    return 0;
+                }
+                // AP rate decided from node
+                pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+                // tx preamble decided from node
+
+                if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
+                    pDevice->byPreambleType = pDevice->byShortPreamble;
+
+                }else {
+                    pDevice->byPreambleType = PREAMBLE_LONG;
+                }
+                bNodeExist = TRUE;
+            }
+        }
+
+        if (bNodeExist == FALSE) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Unknown STA not found in node DB \n");
+            dev_kfree_skb_irq(skb);
+            return 0;
+        }
+    }
+
+    pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+    if (pContext == NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG" pContext == NULL\n");
+        dev_kfree_skb_irq(skb);
+        return STATUS_RESOURCES;
+    }
+
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)(skb->data), U_HEADER_LEN);
+
+//mike add:station mode check eapol-key challenge--->
+{
+    BYTE  Protocol_Version;    //802.1x Authentication
+    BYTE  Packet_Type;           //802.1x Authentication
+    BYTE  Descriptor_type;
+    WORD Key_info;
+
+    Protocol_Version = skb->data[U_HEADER_LEN];
+    Packet_Type = skb->data[U_HEADER_LEN+1];
+    Descriptor_type = skb->data[U_HEADER_LEN+1+1+2];
+    Key_info = (skb->data[U_HEADER_LEN+1+1+2+1] << 8)|(skb->data[U_HEADER_LEN+1+1+2+2]);
+   if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
+           if(((Protocol_Version==1) ||(Protocol_Version==2)) &&
+	        (Packet_Type==3)) {  //802.1x OR eapol-key challenge frame transfer
+                        bTxeapol_key = TRUE;
+                       if(!(Key_info & BIT3) &&  //WPA or RSN group-key challenge
+			   (Key_info & BIT8) && (Key_info & BIT9)) {    //send 2/2 key
+			  if(Descriptor_type==254) {
+                               pDevice->fWPA_Authened = TRUE;
+			     PRINT_K("WPA ");
+			  }
+			  else {
+                               pDevice->fWPA_Authened = TRUE;
+			     PRINT_K("WPA2(re-keying) ");
+			  }
+			  PRINT_K("Authentication completed!!\n");
+                        }
+		    else if((Key_info & BIT3) && (Descriptor_type==2) &&  //RSN pairse-key challenge
+			       (Key_info & BIT8) && (Key_info & BIT9)) {
+			  pDevice->fWPA_Authened = TRUE;
+                            PRINT_K("WPA2 Authentication completed!!\n");
+		     }
+             }
+   }
+}
+//mike add:station mode check eapol-key challenge<---
+
+    if (pDevice->bEncryptionEnable == TRUE) {
+        bNeedEncryption = TRUE;
+        // get Transmit key
+        do {
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                pbyBSSID = pDevice->abyBSSID;
+                // get pairwise key
+                if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == FALSE) {
+                    // get group key
+                    if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == TRUE) {
+                        bTKIP_UseGTK = TRUE;
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+                        break;
+                    }
+                } else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get PTK.\n");
+                    break;
+                }
+            }else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+
+                pbyBSSID = pDevice->sTxEthHeader.abyDstAddr;  //TO_DS = 0 and FROM_DS = 0 --> 802.11 MAC Address1
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS Serach Key: \n");
+                for (ii = 0; ii< 6; ii++)
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"%x \n", *(pbyBSSID+ii));
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"\n");
+
+                // get pairwise key
+                if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == TRUE)
+                    break;
+            }
+            // get group key
+            pbyBSSID = pDevice->abyBroadcastAddr;
+            if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+                pTransmitKey = NULL;
+                if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
+                }
+                else
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"NOT IBSS and KEY is NULL. [%d]\n", pMgmt->eCurrMode);
+            } else {
+                bTKIP_UseGTK = TRUE;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+            }
+        } while(FALSE);
+    }
+
+    if (pDevice->bEnableHostWEP) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"acdma0: STA index %d\n", uNodeIndex);
+        if (pDevice->bEncryptionEnable == TRUE) {
+            pTransmitKey = &STempKey;
+            pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
+            pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
+            pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
+            pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
+            pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
+            memcpy(pTransmitKey->abyKey,
+                &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
+                pTransmitKey->uKeyLength
+                );
+         }
+    }
+
+    byPktType = (BYTE)pDevice->byPacketType;
+
+    if (pDevice->bFixRate) {
+        if (pDevice->byBBType == BB_TYPE_11B) {
+            if (pDevice->uConnectionRate >= RATE_11M) {
+                pDevice->wCurrentRate = RATE_11M;
+            } else {
+                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        } else {
+            if ((pDevice->byBBType == BB_TYPE_11A) &&
+                (pDevice->uConnectionRate <= RATE_6M)) {
+                pDevice->wCurrentRate = RATE_6M;
+            } else {
+                if (pDevice->uConnectionRate >= RATE_54M)
+                    pDevice->wCurrentRate = RATE_54M;
+                else
+                    pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        }
+    }
+    else {
+        if (pDevice->eOPMode == OP_MODE_ADHOC) {
+            // Adhoc Tx rate decided from node DB
+            if (IS_MULTICAST_ADDRESS(&(pDevice->sTxEthHeader.abyDstAddr[0]))) {
+                // Multicast use highest data rate
+                pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
+                // preamble type
+                pDevice->byPreambleType = pDevice->byShortPreamble;
+            }
+            else {
+                if(BSSbIsSTAInNodeDB(pDevice, &(pDevice->sTxEthHeader.abyDstAddr[0]), &uNodeIndex)) {
+                    pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+                    if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) {
+                        pDevice->byPreambleType = pDevice->byShortPreamble;
+
+                    }
+                    else {
+                        pDevice->byPreambleType = PREAMBLE_LONG;
+                    }
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Found Node Index is [%d]  Tx Data Rate:[%d]\n",uNodeIndex, pDevice->wCurrentRate);
+                }
+                else {
+                    if (pDevice->byBBType != BB_TYPE_11A)
+                       pDevice->wCurrentRate = RATE_2M;
+                    else
+                       pDevice->wCurrentRate = RATE_24M; // refer to vMgrCreateOwnIBSS()'s
+                                                         // abyCurrExtSuppRates[]
+                    pDevice->byPreambleType = PREAMBLE_SHORT;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Not Found Node use highest basic Rate.....\n");
+                }
+            }
+        }
+        if (pDevice->eOPMode == OP_MODE_INFRASTRUCTURE) {
+            // Infra STA rate decided from AP Node, index = 0
+            pDevice->wCurrentRate = pMgmt->sNodeDBTable[0].wTxDataRate;
+        }
+    }
+
+    if (pDevice->sTxEthHeader.wType == TYPE_PKT_802_1x) {
+        if (pDevice->byBBType != BB_TYPE_11A) {
+            pDevice->wCurrentRate = RATE_1M;
+            pDevice->byACKRate = RATE_1M;
+            pDevice->byTopCCKBasicRate = RATE_1M;
+            pDevice->byTopOFDMBasicRate = RATE_6M;
+        } else {
+            pDevice->wCurrentRate = RATE_6M;
+            pDevice->byACKRate = RATE_6M;
+            pDevice->byTopCCKBasicRate = RATE_1M;
+            pDevice->byTopOFDMBasicRate = RATE_6M;
+        }
+    }
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma_tx: pDevice->wCurrentRate = %d \n", pDevice->wCurrentRate);
+
+    if (wKeepRate != pDevice->wCurrentRate) {
+        bScheduleCommand((HANDLE)pDevice, WLAN_CMD_SETPOWER, NULL);
+    }
+
+    if (pDevice->wCurrentRate <= RATE_11M) {
+        byPktType = PK_TYPE_11B;
+    }
+
+    if (bNeedEncryption == TRUE) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType));
+        if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) {
+            bNeedEncryption = FALSE;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType));
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+                if (pTransmitKey == NULL) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Don't Find TX KEY\n");
+                }
+                else {
+                    if (bTKIP_UseGTK == TRUE) {
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n");
+                    }
+                    else {
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+                        bNeedEncryption = TRUE;
+                    }
+                }
+            }
+
+            if (pDevice->byCntMeasure == 2) {
+                bNeedDeAuth = TRUE;
+                pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++;
+            }
+
+            if (pDevice->bEnableHostWEP) {
+                if ((uNodeIndex != 0) &&
+                    (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex);
+                    bNeedEncryption = TRUE;
+                 }
+             }
+        }
+        else {
+
+#if 0
+            if((pDevice->fWPA_Authened == FALSE) &&
+		((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)||(pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK))){
+                  dev_kfree_skb_irq(skb);
+                  pStats->tx_dropped++;
+                  return STATUS_FAILURE;
+            }
+	        else if (pTransmitKey == NULL) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
+                dev_kfree_skb_irq(skb);
+                pStats->tx_dropped++;
+                return STATUS_FAILURE;
+            }
+#else
+            if (pTransmitKey == NULL) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n");
+                dev_kfree_skb_irq(skb);
+                pStats->tx_dropped++;
+                return STATUS_FAILURE;
+            }
+#endif
+
+        }
+    }
+
+    fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
+                        (PBYTE)(&pContext->Data[0]), bNeedEncryption,
+                        skb->len, uDMAIdx, &pDevice->sTxEthHeader,
+                        (PBYTE)skb->data, pTransmitKey, uNodeIndex,
+                        pDevice->wCurrentRate,
+                        &uHeaderLen, &BytesToWrite
+                       );
+
+    if (fConvertedPacket == FALSE) {
+        pContext->bBoolInUse = FALSE;
+        dev_kfree_skb_irq(skb);
+        return STATUS_FAILURE;
+    }
+
+    if ( pDevice->bEnablePSMode == TRUE ) {
+        if ( !pDevice->bPSModeTxBurst ) {
+            bScheduleCommand((HANDLE) pDevice, WLAN_CMD_MAC_DISPOWERSAVING, NULL);
+            pDevice->bPSModeTxBurst = TRUE;
+        }
+    }
+
+    pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
+    pTX_Buffer->byPKTNO = (BYTE) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+    pTX_Buffer->wTxByteCount = (WORD)BytesToWrite;
+
+    pContext->pPacket = skb;
+    pContext->Type = CONTEXT_DATA_PACKET;
+    pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header
+
+    s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl);
+
+    status = PIPEnsSendBulkOut(pDevice,pContext);
+
+    if (bNeedDeAuth == TRUE) {
+        WORD wReason = WLAN_MGMT_REASON_MIC_FAILURE;
+
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_DEAUTH, (PBYTE)&wReason);
+    }
+
+  if(status!=STATUS_PENDING) {
+     pContext->bBoolInUse = FALSE;
+    dev_kfree_skb_irq(skb);
+    return STATUS_FAILURE;
+  }
+  else
+    return 0;
+
+}
+
+
+
+/*
+ * Description:
+ *      Relay packet send (AC1DMA) from rx dpc.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to the adapter
+ *      pPacket         - Pointer to rx packet
+ *      cbPacketSize    - rx ethernet frame size
+ *  Out:
+ *      TURE, FALSE
+ *
+ * Return Value: Return TRUE if packet is copy to dma1; otherwise FALSE
+ */
+
+
+BOOL
+bRelayPacketSend (
+    IN  PSDevice pDevice,
+    IN  PBYTE    pbySkbData,
+    IN  UINT     uDataLen,
+    IN  UINT     uNodeIndex
+    )
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            BytesToWrite =0,uHeaderLen = 0;
+    BYTE            byPktType = PK_TYPE_11B;
+    BOOL            bNeedEncryption = FALSE;
+    SKeyItem        STempKey;
+    PSKeyItem       pTransmitKey = NULL;
+    PBYTE           pbyBSSID;
+    PUSB_SEND_CONTEXT   pContext;
+    BYTE            byPktTyp;
+    BOOL            fConvertedPacket;
+    PTX_BUFFER      pTX_Buffer;
+    UINT            status;
+    WORD            wKeepRate = pDevice->wCurrentRate;
+
+
+
+    pContext = (PUSB_SEND_CONTEXT)s_vGetFreeContext(pDevice);
+
+    if (NULL == pContext) {
+        return FALSE;
+    }
+
+    memcpy(pDevice->sTxEthHeader.abyDstAddr, (PBYTE)pbySkbData, U_HEADER_LEN);
+
+    if (pDevice->bEncryptionEnable == TRUE) {
+        bNeedEncryption = TRUE;
+        // get group key
+        pbyBSSID = pDevice->abyBroadcastAddr;
+        if(KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == FALSE) {
+            pTransmitKey = NULL;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"KEY is NULL. [%d]\n", pMgmt->eCurrMode);
+        } else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG"Get GTK.\n");
+        }
+    }
+
+    if (pDevice->bEnableHostWEP) {
+        if (uNodeIndex >= 0) {
+            pTransmitKey = &STempKey;
+            pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite;
+            pTransmitKey->dwKeyIndex = pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex;
+            pTransmitKey->uKeyLength = pMgmt->sNodeDBTable[uNodeIndex].uWepKeyLength;
+            pTransmitKey->dwTSC47_16 = pMgmt->sNodeDBTable[uNodeIndex].dwTSC47_16;
+            pTransmitKey->wTSC15_0 = pMgmt->sNodeDBTable[uNodeIndex].wTSC15_0;
+            memcpy(pTransmitKey->abyKey,
+                    &pMgmt->sNodeDBTable[uNodeIndex].abyWepKey[0],
+                    pTransmitKey->uKeyLength
+                  );
+        }
+    }
+
+    if ( bNeedEncryption && (pTransmitKey == NULL) ) {
+        pContext->bBoolInUse = FALSE;
+        return FALSE;
+    }
+
+    byPktTyp = (BYTE)pDevice->byPacketType;
+
+    if (pDevice->bFixRate) {
+        if (pDevice->byBBType == BB_TYPE_11B) {
+            if (pDevice->uConnectionRate >= RATE_11M) {
+                pDevice->wCurrentRate = RATE_11M;
+            } else {
+                pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        } else {
+            if ((pDevice->byBBType == BB_TYPE_11A) &&
+                (pDevice->uConnectionRate <= RATE_6M)) {
+                pDevice->wCurrentRate = RATE_6M;
+            } else {
+                if (pDevice->uConnectionRate >= RATE_54M)
+                    pDevice->wCurrentRate = RATE_54M;
+                else
+                    pDevice->wCurrentRate = (WORD)pDevice->uConnectionRate;
+            }
+        }
+    }
+    else {
+        pDevice->wCurrentRate = pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate;
+    }
+
+
+    if (wKeepRate != pDevice->wCurrentRate) {
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SETPOWER, NULL);
+    }
+
+    if (pDevice->wCurrentRate <= RATE_11M)
+        byPktType = PK_TYPE_11B;
+
+    BytesToWrite = uDataLen + U_CRC_LEN;
+    // Convert the packet to an usb frame and copy into our buffer
+    // and send the irp.
+
+    fConvertedPacket = s_bPacketToWirelessUsb(pDevice, byPktType,
+                         (PBYTE)(&pContext->Data[0]), bNeedEncryption,
+                         uDataLen, TYPE_AC0DMA, &pDevice->sTxEthHeader,
+                         pbySkbData, pTransmitKey, uNodeIndex,
+                         pDevice->wCurrentRate,
+                         &uHeaderLen, &BytesToWrite
+                        );
+
+    if (fConvertedPacket == FALSE) {
+        pContext->bBoolInUse = FALSE;
+        return FALSE;
+    }
+
+    pTX_Buffer = (PTX_BUFFER)&(pContext->Data[0]);
+    pTX_Buffer->byPKTNO = (BYTE) (((pDevice->wCurrentRate<<4) &0x00F0) | ((pDevice->wSeqCounter - 1) & 0x000F));
+    pTX_Buffer->wTxByteCount = (WORD)BytesToWrite;
+
+    pContext->pPacket = NULL;
+    pContext->Type = CONTEXT_DATA_PACKET;
+    pContext->uBufLen = (WORD)BytesToWrite + 4 ; //USB header
+
+    s_vSaveTxPktInfo(pDevice, (BYTE) (pTX_Buffer->byPKTNO & 0x0F), &(pContext->sEthHeader.abyDstAddr[0]),(WORD) (BytesToWrite-uHeaderLen),pTX_Buffer->wFIFOCtl);
+
+    status = PIPEnsSendBulkOut(pDevice,pContext);
+
+    return TRUE;
+}
+
diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h
new file mode 100644
index 0000000..6bc22d3
--- /dev/null
+++ b/drivers/staging/vt6656/rxtx.h
@@ -0,0 +1,694 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: rxtx.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __RXTX_H__
+#define __RXTX_H__
+
+#include "ttype.h"
+#include "device.h"
+#include "wcmd.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+//
+// RTS buffer header
+//
+typedef struct tagSRTSDataF {
+    WORD    wFrameControl;
+    WORD    wDurationID;
+    BYTE    abyRA[U_ETHER_ADDR_LEN];
+    BYTE    abyTA[U_ETHER_ADDR_LEN];
+} SRTSDataF, *PSRTSDataF;
+
+//
+// CTS buffer header
+//
+typedef struct tagSCTSDataF {
+    WORD    wFrameControl;
+    WORD    wDurationID;
+    BYTE    abyRA[U_ETHER_ADDR_LEN];
+    WORD    wReserved;
+} SCTSDataF, *PSCTSDataF;
+
+//
+// MICHDR data header
+//
+typedef struct tagSMICHDR {
+    DWORD   adwHDR0[4];
+    DWORD   adwHDR1[4];
+    DWORD   adwHDR2[4];
+} SMICHDR, *PSMICHDR;
+
+
+typedef struct tagSTX_NAF_G_RTS
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_ba;
+    WORD            wRTSTxRrvTime_aa;
+    WORD            wRTSTxRrvTime_bb;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+    //RTS
+    BYTE            byRTSSignalField_b;
+    BYTE            byRTSServiceField_b;
+    WORD            wRTSTransmitLength_b;
+    BYTE            byRTSSignalField_a;
+    BYTE            byRTSServiceField_a;
+    WORD            wRTSTransmitLength_a;
+    WORD            wRTSDuration_ba;
+    WORD            wRTSDuration_aa;
+    WORD            wRTSDuration_bb;
+    WORD            wReserved3;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_NAF_G_RTS, *PTX_NAF_G_RTS;
+
+typedef struct tagSTX_NAF_G_RTS_MIC
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_ba;
+    WORD            wRTSTxRrvTime_aa;
+    WORD            wRTSTxRrvTime_bb;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+    SMICHDR         sMICHDR;
+
+    //RTS
+    BYTE            byRTSSignalField_b;
+    BYTE            byRTSServiceField_b;
+    WORD            wRTSTransmitLength_b;
+    BYTE            byRTSSignalField_a;
+    BYTE            byRTSServiceField_a;
+    WORD            wRTSTransmitLength_a;
+    WORD            wRTSDuration_ba;
+    WORD            wRTSDuration_aa;
+    WORD            wRTSDuration_bb;
+    WORD            wReserved3;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_NAF_G_RTS_MIC, *PTX_NAF_G_RTS_MIC;
+
+typedef struct tagSTX_NAF_G_CTS
+{
+    //RsvTime
+    WORD            wCTSTxRrvTime_ba;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+    //CTS
+    BYTE            byCTSSignalField_b;
+    BYTE            byCTSServiceField_b;
+    WORD            wCTSTransmitLength_b;
+    WORD            wCTSDuration_ba;
+    WORD            wReserved3;
+    SCTSDataF       sCTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_NAF_G_CTS, *PTX_NAF_G_CTS;
+
+
+typedef struct tagSTX_NAF_G_CTS_MIC
+{
+    //RsvTime
+    WORD            wCTSTxRrvTime_ba;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+
+    SMICHDR         sMICHDR;
+
+    //CTS
+    BYTE            byCTSSignalField_b;
+    BYTE            byCTSServiceField_b;
+    WORD            wCTSTransmitLength_b;
+    WORD            wCTSDuration_ba;
+    WORD            wReserved3;
+    SCTSDataF       sCTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_NAF_G_CTS_MIC, *PTX_NAF_G_CTS_MIC;
+
+
+typedef struct tagSTX_NAF_G_BEACON
+{
+    WORD            wFIFOCtl;
+    WORD            wTimeStamp;
+
+    //CTS
+    BYTE            byCTSSignalField_b;
+    BYTE            byCTSServiceField_b;
+    WORD            wCTSTransmitLength_b;
+    WORD            wCTSDuration_ba;
+    WORD            wReserved1;
+    SCTSDataF       sCTS;
+
+    //Data
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_a;
+
+
+} TX_NAF_G_BEACON, *PTX_NAF_G_BEACON;
+
+
+typedef struct tagSTX_NAF_AB_RTS
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_ab;
+    WORD            wTxRrvTime_ab;
+
+    //RTS
+    BYTE            byRTSSignalField_ab;
+    BYTE            byRTSServiceField_ab;
+    WORD            wRTSTransmitLength_ab;
+    WORD            wRTSDuration_ab;
+    WORD            wReserved2;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_ab;
+    BYTE            byServiceField_ab;
+    WORD            wTransmitLength_ab;
+    WORD            wDuration_ab;
+    WORD            wTimeStampOff_ab;
+
+
+} TX_NAF_AB_RTS, *PTX_NAF_AB_RTS;
+
+
+typedef struct tagSTX_NAF_AB_RTS_MIC
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_ab;
+    WORD            wTxRrvTime_ab;
+
+    SMICHDR         sMICHDR;
+
+    //RTS
+    BYTE            byRTSSignalField_ab;
+    BYTE            byRTSServiceField_ab;
+    WORD            wRTSTransmitLength_ab;
+    WORD            wRTSDuration_ab;
+    WORD            wReserved2;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_ab;
+    BYTE            byServiceField_ab;
+    WORD            wTransmitLength_ab;
+    WORD            wDuration_ab;
+    WORD            wTimeStampOff_ab;
+
+
+} TX_NAF_AB_RTS_MIC, *PTX_NAF_AB_RTS_MIC;
+
+
+
+typedef struct tagSTX_NAF_AB_CTS
+{
+    //RsvTime
+    WORD            wReserved2;
+    WORD            wTxRrvTime_ab;
+
+    //Data
+    BYTE            bySignalField_ab;
+    BYTE            byServiceField_ab;
+    WORD            wTransmitLength_ab;
+    WORD            wDuration_ab;
+    WORD            wTimeStampOff_ab;
+
+} TX_NAF_AB_CTS, *PTX_NAF_AB_CTS;
+
+typedef struct tagSTX_NAF_AB_CTS_MIC
+{
+    //RsvTime
+    WORD            wReserved2;
+    WORD            wTxRrvTime_ab;
+
+    SMICHDR         sMICHDR;
+
+    //Data
+    BYTE            bySignalField_ab;
+    BYTE            byServiceField_ab;
+    WORD            wTransmitLength_ab;
+    WORD            wDuration_ab;
+    WORD            wTimeStampOff_ab;
+
+} TX_NAF_AB_CTS_MIC, *PTX_NAF_AB_CTS_MIC;
+
+
+typedef struct tagSTX_NAF_AB_BEACON
+{
+    WORD            wFIFOCtl;
+    WORD            wTimeStamp;
+
+   //Data
+    BYTE            bySignalField_ab;
+    BYTE            byServiceField_ab;
+    WORD            wTransmitLength_ab;
+    WORD            wDuration_ab;
+    WORD            wTimeStampOff_ab;
+
+} TX_NAF_AB_BEACON, *PTX_NAF_AB_BEACON;
+
+typedef struct tagSTX_AF_G_RTS
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_ba;
+    WORD            wRTSTxRrvTime_aa;
+    WORD            wRTSTxRrvTime_bb;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+    //RTS
+    BYTE            byRTSSignalField_b;
+    BYTE            byRTSServiceField_b;
+    WORD            wRTSTransmitLength_b;
+    BYTE            byRTSSignalField_a;
+    BYTE            byRTSServiceField_a;
+    WORD            wRTSTransmitLength_a;
+    WORD            wRTSDuration_ba;
+    WORD            wRTSDuration_aa;
+    WORD            wRTSDuration_bb;
+    WORD            wReserved3;
+    WORD            wRTSDuration_ba_f0;
+    WORD            wRTSDuration_aa_f0;
+    WORD            wRTSDuration_ba_f1;
+    WORD            wRTSDuration_aa_f1;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_AF_G_RTS, *PTX_AF_G_RTS;
+
+
+typedef struct tagSTX_AF_G_RTS_MIC
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_ba;
+    WORD            wRTSTxRrvTime_aa;
+    WORD            wRTSTxRrvTime_bb;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+    SMICHDR         sMICHDR;
+
+    //RTS
+    BYTE            byRTSSignalField_b;
+    BYTE            byRTSServiceField_b;
+    WORD            wRTSTransmitLength_b;
+    BYTE            byRTSSignalField_a;
+    BYTE            byRTSServiceField_a;
+    WORD            wRTSTransmitLength_a;
+    WORD            wRTSDuration_ba;
+    WORD            wRTSDuration_aa;
+    WORD            wRTSDuration_bb;
+    WORD            wReserved3;
+    WORD            wRTSDuration_ba_f0;
+    WORD            wRTSDuration_aa_f0;
+    WORD            wRTSDuration_ba_f1;
+    WORD            wRTSDuration_aa_f1;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_AF_G_RTS_MIC, *PTX_AF_G_RTS_MIC;
+
+
+
+typedef struct tagSTX_AF_G_CTS
+{
+    //RsvTime
+    WORD            wCTSTxRrvTime_ba;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+    //CTS
+    BYTE            byCTSSignalField_b;
+    BYTE            byCTSServiceField_b;
+    WORD            wCTSTransmitLength_b;
+    WORD            wCTSDuration_ba;
+    WORD            wReserved3;
+    WORD            wCTSDuration_ba_f0;
+    WORD            wCTSDuration_ba_f1;
+    SCTSDataF       sCTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_AF_G_CTS, *PTX_AF_G_CTS;
+
+
+typedef struct tagSTX_AF_G_CTS_MIC
+{
+    //RsvTime
+    WORD            wCTSTxRrvTime_ba;
+    WORD            wReserved2;
+    WORD            wTxRrvTime_b;
+    WORD            wTxRrvTime_a;
+
+
+    SMICHDR         sMICHDR;
+
+    //CTS
+    BYTE            byCTSSignalField_b;
+    BYTE            byCTSServiceField_b;
+    WORD            wCTSTransmitLength_b;
+    WORD            wCTSDuration_ba;
+    WORD            wReserved3;
+    WORD            wCTSDuration_ba_f0;
+    WORD            wCTSDuration_ba_f1;
+    SCTSDataF       sCTS;
+
+    //Data
+    BYTE            bySignalField_b;
+    BYTE            byServiceField_b;
+    WORD            wTransmitLength_b;
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_b;
+    WORD            wDuration_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+    WORD            wTimeStampOff_b;
+    WORD            wTimeStampOff_a;
+
+} TX_AF_G_CTS_MIC, *PTX_AF_G_CTS_MIC;
+
+
+
+typedef struct tagSTX_AF_A_RTS
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_a;
+    WORD            wTxRrvTime_a;
+
+    //RTS
+    BYTE            byRTSSignalField_a;
+    BYTE            byRTSServiceField_a;
+    WORD            wRTSTransmitLength_a;
+    WORD            wRTSDuration_a;
+    WORD            wReserved2;
+    WORD            wRTSDuration_a_f0;
+    WORD            wRTSDuration_a_f1;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+
+} TX_AF_A_RTS, *PTX_AF_A_RTS;
+
+
+typedef struct tagSTX_AF_A_RTS_MIC
+{
+    //RsvTime
+    WORD            wRTSTxRrvTime_a;
+    WORD            wTxRrvTime_a;
+
+    SMICHDR         sMICHDR;
+
+    //RTS
+    BYTE            byRTSSignalField_a;
+    BYTE            byRTSServiceField_a;
+    WORD            wRTSTransmitLength_a;
+    WORD            wRTSDuration_a;
+    WORD            wReserved2;
+    WORD            wRTSDuration_a_f0;
+    WORD            wRTSDuration_a_f1;
+    SRTSDataF       sRTS;
+
+    //Data
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+
+} TX_AF_A_RTS_MIC, *PTX_AF_A_RTS_MIC;
+
+
+
+typedef struct tagSTX_AF_A_CTS
+{
+    //RsvTime
+    WORD            wReserved2;
+    WORD            wTxRrvTime_a;
+
+    //Data
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+
+} TX_AF_A_CTS, *PTX_AF_A_CTS;
+
+
+typedef struct tagSTX_AF_A_CTS_MIC
+{
+    //RsvTime
+    WORD            wReserved2;
+    WORD            wTxRrvTime_a;
+
+    SMICHDR         sMICHDR;
+
+    //Data
+    BYTE            bySignalField_a;
+    BYTE            byServiceField_a;
+    WORD            wTransmitLength_a;
+    WORD            wDuration_a;
+    WORD            wTimeStampOff_a;
+    WORD            wDuration_a_f0;
+    WORD            wDuration_a_f1;
+
+} TX_AF_A_CTS_MIC, *PTX_AF_A_CTS_MIC;
+
+
+//
+// union with all of the TX Buffer Type
+//
+typedef union tagUTX_BUFFER_CONTAINER
+{
+    TX_NAF_G_RTS                    RTS_G;
+    TX_NAF_G_RTS_MIC                RTS_G_MIC;
+    TX_NAF_G_CTS                    CTS_G;
+    TX_NAF_G_CTS_MIC                CTS_G_MIC;
+    //TX_NAF_G_BEACON                 Beacon_G;
+    TX_NAF_AB_RTS                   RTS_AB;
+    TX_NAF_AB_RTS_MIC               RTS_AB_MIC;
+    TX_NAF_AB_CTS                   CTS_AB;
+    TX_NAF_AB_CTS_MIC               CTS_AB_MIC;
+    //TX_NAF_AB_BEACON                Beacon_AB;
+    TX_AF_G_RTS                     RTS_G_AutoFB;
+    TX_AF_G_RTS_MIC                 RTS_G_AutoFB_MIC;
+    TX_AF_G_CTS                     CTS_G_AutoFB;
+    TX_AF_G_CTS_MIC                 CTS_G_AutoFB_MIC;
+    TX_AF_A_RTS                     RTS_A_AutoFB;
+    TX_AF_A_RTS_MIC                 RTS_A_AutoFB_MIC;
+    TX_AF_A_CTS                     CTS_A_AutoFB;
+    TX_AF_A_CTS_MIC                 CTS_A_AutoFB_MIC;
+
+} TX_BUFFER_CONTAINER, *PTX_BUFFER_CONTAINER;
+
+
+//
+// Remote NDIS message format
+//
+typedef struct tagSTX_BUFFER
+{
+    BYTE                            byType;
+    BYTE                            byPKTNO;
+    WORD                            wTxByteCount;
+
+    DWORD                           adwTxKey[4];
+    WORD                            wFIFOCtl;
+    WORD                            wTimeStamp;
+    WORD                            wFragCtl;
+    WORD                            wReserved;
+
+
+    // Actual message
+    TX_BUFFER_CONTAINER             BufferHeader;
+
+} TX_BUFFER, *PTX_BUFFER;
+
+
+//
+// Remote NDIS message format
+//
+typedef struct tagSBEACON_BUFFER
+{
+    BYTE                            byType;
+    BYTE                            byPKTNO;
+    WORD                            wTxByteCount;
+
+    WORD                            wFIFOCtl;
+    WORD                            wTimeStamp;
+
+    // Actual message
+    TX_BUFFER_CONTAINER             BufferHeader;
+
+} BEACON_BUFFER, *PBEACON_BUFFER;
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+BOOL
+bPacketToWirelessUsb(
+    IN  PSDevice         pDevice,
+    IN  BYTE             byPktType,
+    IN  PBYTE            usbPacketBuf,
+    IN  BOOL             bNeedEncrypt,
+    IN  UINT             cbPayloadSize,
+    IN  UINT             uDMAIdx,
+    IN  PSEthernetHeader psEthHeader,
+    IN  PBYTE            pPacket,
+    IN  PSKeyItem        pTransmitKey,
+    IN  UINT             uNodeIndex,
+    IN  WORD             wCurrentRate,
+    OUT UINT             *pcbHeaderLen,
+    OUT UINT             *pcbTotalLen
+    );
+
+VOID vDMA0_tx_80211(PSDevice  pDevice, struct sk_buff *skb);
+NTSTATUS nsDMA_tx_packet(PSDevice  pDevice, UINT uDMAIdx, struct sk_buff *skb);
+CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
+CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket);
+BOOL bRelayPacketSend(PSDevice pDevice, PBYTE pbySkbData, UINT uDataLen, UINT uNodeIndex);
+
+#endif // __RXTX_H__
+
+
+
diff --git a/drivers/staging/vt6656/srom.h b/drivers/staging/vt6656/srom.h
new file mode 100644
index 0000000..4c89e7a
--- /dev/null
+++ b/drivers/staging/vt6656/srom.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: srom.h
+ *
+ * Purpose: Implement functions to access eeprom
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jan 29, 2003
+ *
+ */
+
+#ifndef __SROM_H__
+#define __SROM_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define EEP_MAX_CONTEXT_SIZE    256
+
+#define CB_EEPROM_READBYTE_WAIT 900     //us
+
+#define W_MAX_I2CRETRY          0x0fff
+
+//
+// Contents in the EEPROM
+//
+#define EEP_OFS_PAR         0x00        // physical address
+#define EEP_OFS_ANTENNA     0x17
+#define EEP_OFS_RADIOCTL    0x18
+#define EEP_OFS_RFTYPE      0x1B        // for select RF
+#define EEP_OFS_MINCHANNEL  0x1C        // Min Channel #
+#define EEP_OFS_MAXCHANNEL  0x1D        // Max Channel #
+#define EEP_OFS_SIGNATURE   0x1E        //
+#define EEP_OFS_ZONETYPE    0x1F        //
+#define EEP_OFS_RFTABLE     0x20        // RF POWER TABLE
+#define EEP_OFS_PWR_CCK     0x20
+#define EEP_OFS_SETPT_CCK   0x21
+#define EEP_OFS_PWR_OFDMG   0x23
+
+
+#define EEP_OFS_CALIB_TX_IQ 0x24
+#define EEP_OFS_CALIB_TX_DC 0x25
+#define EEP_OFS_CALIB_RX_IQ 0x26
+
+#define EEP_OFS_MAJOR_VER 0x2E
+#define EEP_OFS_MINOR_VER 0x2F
+
+#define EEP_OFS_CCK_PWR_TBL     0x30
+#define EEP_OFS_OFDM_PWR_TBL    0x40
+#define EEP_OFS_OFDMA_PWR_TBL   0x50
+
+//
+// Bits in EEP_OFS_ANTENNA
+//
+#define EEP_ANTENNA_MAIN    0x01
+#define EEP_ANTENNA_AUX     0x02
+#define EEP_ANTINV          0x04
+
+//
+// Bits in EEP_OFS_RADIOCTL
+//
+#define EEP_RADIOCTL_ENABLE 0x80
+
+/*---------------------  Export Types  ------------------------------*/
+
+// AT24C02 eeprom contents
+//      2048 bits = 256 bytes = 128 words
+//
+typedef struct tagSSromReg {
+    BYTE    abyPAR[6];                  // 0x00 (WORD)
+
+    WORD    wSUB_VID;                   // 0x03 (WORD)
+    WORD    wSUB_SID;
+
+    BYTE    byBCFG0;                    // 0x05 (WORD)
+    BYTE    byBCFG1;
+
+    BYTE    byFCR0;                     // 0x06 (WORD)
+    BYTE    byFCR1;
+    BYTE    byPMC0;                     // 0x07 (WORD)
+    BYTE    byPMC1;
+    BYTE    byMAXLAT;                   // 0x08 (WORD)
+    BYTE    byMINGNT;
+    BYTE    byCFG0;                     // 0x09 (WORD)
+    BYTE    byCFG1;
+    WORD    wCISPTR;                    // 0x0A (WORD)
+    WORD    wRsv0;                      // 0x0B (WORD)
+    WORD    wRsv1;                      // 0x0C (WORD)
+    BYTE    byBBPAIR;                   // 0x0D (WORD)
+    BYTE    byRFTYPE;
+    BYTE    byMinChannel;               // 0x0E (WORD)
+    BYTE    byMaxChannel;
+    BYTE    bySignature;                // 0x0F (WORD)
+    BYTE    byCheckSum;
+
+    BYTE    abyReserved0[96];           // 0x10 (WORD)
+    BYTE    abyCIS[128];                // 0x80 (WORD)
+} SSromReg, *PSSromReg;
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+#endif // __EEPROM_H__
diff --git a/drivers/staging/vt6656/tcrc.c b/drivers/staging/vt6656/tcrc.c
new file mode 100644
index 0000000..5f0c747
--- /dev/null
+++ b/drivers/staging/vt6656/tcrc.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2003 VIA Networking, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: tcrc.c
+ *
+ * Purpose: Implement functions to caculate CRC
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *      CRCdwCrc32 -
+ *      CRCdwGetCrc32 -
+ *      CRCdwGetCrc32Ex -
+ *
+ * Revision History:
+ *
+ */
+
+#include "tcrc.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+// 32-bit CRC table
+static const DWORD s_adwCrc32Table[256] = {
+    0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
+    0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
+    0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
+    0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,
+    0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,
+    0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
+    0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,
+    0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L,
+    0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L,
+    0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL,
+    0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L,
+    0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
+    0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L,
+    0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL,
+    0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
+    0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL,
+    0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL,
+    0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
+    0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L,
+    0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L,
+    0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL,
+    0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L,
+    0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL,
+    0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
+    0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L,
+    0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL,
+    0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
+    0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L,
+    0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L,
+    0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
+    0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L,
+    0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL,
+    0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
+    0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L,
+    0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L,
+    0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
+    0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL,
+    0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L,
+    0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
+    0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L,
+    0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L,
+    0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
+    0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L,
+    0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L,
+    0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
+    0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL,
+    0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L,
+    0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
+    0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL,
+    0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L,
+    0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
+    0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L,
+    0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL,
+    0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
+    0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL,
+    0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L,
+    0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
+    0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL,
+    0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L,
+    0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
+    0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L,
+    0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL,
+    0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
+    0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL
+};
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+
+/*+
+ *
+ * Description:
+ *    Generate a CRC-32 from the data stream
+ *
+ * Parameters:
+ *  In:
+ *      pbyData     - the data stream
+ *      cbByte      - the length of the stream
+ *      dwCrcSeed   - Seed for CRC32
+ *  Out:
+ *      none
+ *
+ * Return Value: CRC-32
+ *
+-*/
+DWORD CRCdwCrc32 (PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed)
+{
+    DWORD dwCrc;
+
+    dwCrc = dwCrcSeed;
+    while (cbByte--) {
+        dwCrc = s_adwCrc32Table[(BYTE)((dwCrc ^ (*pbyData)) & 0xFF)] ^ (dwCrc >> 8);
+        pbyData++;
+    }
+
+    return dwCrc;
+}
+
+
+/*+
+ *
+ * Description:
+ * To test CRC generator, input 8 bytes packet
+ *      -- 0xff 0xff 0xff 0xff 0x00 0x00 0x00 0x00
+ * the generated CRC should be
+ *      -- 0xff 0xff 0xff 0xff
+ *
+ * Parameters:
+ *  In:
+ *      pbyData     - the data stream
+ *      cbByte      - the length of the stream
+ *  Out:
+ *      none
+ *
+ * Return Value: CRC-32
+ *
+-*/
+DWORD CRCdwGetCrc32 (PBYTE pbyData, UINT cbByte)
+{
+    return ~CRCdwCrc32(pbyData, cbByte, 0xFFFFFFFFL);
+}
+
+
+/*+
+ *
+ * Description:
+ *
+ * NOTE.... Because CRCdwGetCrc32Ex() is an iteration function,
+ *          this means we will use the output of CRCdwGetCrc32Ex()
+ *          to be a new argument to do next CRCdwGetCrc32Ex() calculation.
+ *          Thus, the final result must be inverted to be the
+ *          correct answer.
+ *
+ * Parameters:
+ *  In:
+ *      pbyData     - the data stream
+ *      cbByte      - the length of the stream
+ *  Out:
+ *      none
+ *
+ * Return Value: CRC-32
+ *
+-*/
+DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC)
+{
+    return CRCdwCrc32(pbyData, cbByte, dwPreCRC);
+}
+
+
diff --git a/drivers/staging/vt6656/tcrc.h b/drivers/staging/vt6656/tcrc.h
new file mode 100644
index 0000000..5faa48b
--- /dev/null
+++ b/drivers/staging/vt6656/tcrc.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003 VIA Networking, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: tcrc.h
+ *
+ * Purpose: Implement functions to caculate CRC
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Jan. 28, 1997
+ *
+ */
+
+#ifndef __TCRC_H__
+#define __TCRC_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+DWORD CRCdwCrc32(PBYTE pbyData, UINT cbByte, DWORD dwCrcSeed);
+DWORD CRCdwGetCrc32(PBYTE pbyData, UINT cbByte);
+DWORD CRCdwGetCrc32Ex(PBYTE pbyData, UINT cbByte, DWORD dwPreCRC);
+
+#endif // __TCRC_H__
+
+
+
diff --git a/drivers/staging/vt6656/tether.c b/drivers/staging/vt6656/tether.c
new file mode 100644
index 0000000..c90b469
--- /dev/null
+++ b/drivers/staging/vt6656/tether.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2003 VIA Networking, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: tether.c
+ *
+ * Purpose:
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ * Functions:
+ *      ETHbyGetHashIndexByCrc32 - Caculate multicast hash value by CRC32
+ *      ETHbIsBufferCrc32Ok - Check CRC value of the buffer if Ok or not
+ *
+ * Revision History:
+ *
+ */
+
+#include "device.h"
+#include "tmacro.h"
+#include "tcrc.h"
+#include "tether.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+/*
+ * Description: Caculate multicast hash value by CRC32
+ *
+ * Parameters:
+ *  In:
+ *		pbyMultiAddr    - Multicast Address
+ *  Out:
+ *      none
+ *
+ * Return Value: Hash value
+ *
+ */
+BYTE ETHbyGetHashIndexByCrc32 (PBYTE pbyMultiAddr)
+{
+    int     ii;
+    BYTE    byTmpHash;
+    BYTE    byHash = 0;
+
+    // get the least 6-bits from CRC generator
+    byTmpHash = (BYTE)(CRCdwCrc32(pbyMultiAddr, U_ETHER_ADDR_LEN,
+            0xFFFFFFFFL) & 0x3F);
+    // reverse most bit to least bit
+    for (ii = 0; ii < (sizeof(byTmpHash) * 8); ii++) {
+        byHash <<= 1;
+        if (byTmpHash & 0x01)
+            byHash |= 1;
+        byTmpHash >>= 1;
+    }
+
+    // adjust 6-bits to the right most
+    return (byHash >> 2);
+}
+
+
+/*
+ * Description: Check CRC value of the buffer if Ok or not
+ *
+ * Parameters:
+ *  In:
+ *		pbyBuffer	    - pointer of buffer (normally is rx buffer)
+ *		cbFrameLength	- length of buffer, including CRC portion
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if ok; FALSE if error.
+ *
+ */
+BOOL ETHbIsBufferCrc32Ok (PBYTE pbyBuffer, UINT cbFrameLength)
+{
+    DWORD dwCRC;
+
+    dwCRC = CRCdwGetCrc32(pbyBuffer, cbFrameLength - 4);
+    if (cpu_to_le32(*((PDWORD)(pbyBuffer + cbFrameLength - 4))) != dwCRC) {
+        return FALSE;
+    }
+    return TRUE;
+}
+
diff --git a/drivers/staging/vt6656/tether.h b/drivers/staging/vt6656/tether.h
new file mode 100644
index 0000000..5a3c326
--- /dev/null
+++ b/drivers/staging/vt6656/tether.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: tether.h
+ *
+ * Purpose:
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Jan. 28, 1997
+ *
+ */
+
+#ifndef __TETHER_H__
+#define __TETHER_H__
+
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+//
+// constants
+//
+#define U_ETHER_ADDR_LEN    6           // Ethernet address length
+#define U_TYPE_LEN          2           //
+#define U_CRC_LEN           4           //
+#define U_HEADER_LEN        (U_ETHER_ADDR_LEN * 2 + U_TYPE_LEN)
+#define U_ETHER_ADDR_STR_LEN (U_ETHER_ADDR_LEN * 2 + 1)
+                                        // Ethernet address string length
+
+#define MIN_DATA_LEN        46          // min data length
+#define MAX_DATA_LEN        1500        // max data length
+
+#define MIN_PACKET_LEN      (MIN_DATA_LEN + U_HEADER_LEN)
+                                        // 60
+                                        // min total packet length (tx)
+#define MAX_PACKET_LEN      (MAX_DATA_LEN + U_HEADER_LEN)
+                                        // 1514
+                                        // max total packet length (tx)
+
+#define MAX_LOOKAHEAD_SIZE  MAX_PACKET_LEN
+
+#define U_MULTI_ADDR_LEN    8           // multicast address length
+
+
+#ifdef __BIG_ENDIAN
+
+#define TYPE_PKT_IP         0x0800      //
+#define TYPE_PKT_ARP        0x0806      //
+#define TYPE_PKT_RARP       0x8035      //
+#define TYPE_PKT_IPX	    0x8137	    //
+#define TYPE_PKT_802_1x     0x888e
+#define TYPE_PKT_PreAuth    0x88C7
+
+#define TYPE_PKT_PING_M_REQ 0x8011      // master reguest
+#define TYPE_PKT_PING_S_GNT 0x8022      // slave grant
+#define TYPE_PKT_PING_M     0x8077      // pingpong master packet
+#define TYPE_PKT_PING_S     0x8088      // pingpong slave packet
+#define TYPE_PKT_WOL_M_REQ  0x8033      // WOL waker request
+#define TYPE_PKT_WOL_S_GNT  0x8044      // WOL sleeper grant
+#define TYPE_MGMT_PROBE_RSP 0x5000
+#define TYPE_PKT_VNT_DIAG   0x8011      // Diag Pkt
+#define TYPE_PKT_VNT_PER    0x8888      // Diag PER Pkt
+//
+// wFrameCtl field in the S802_11Header
+//
+// NOTE....
+//   in network byte order, high byte is going first
+#define FC_TODS             0x0001
+#define FC_FROMDS           0x0002
+#define FC_MOREFRAG         0x0004
+#define FC_RETRY            0x0008
+#define FC_POWERMGT         0x0010
+#define FC_MOREDATA         0x0020
+#define FC_WEP              0x0040
+#define TYPE_802_11_ATIM    0x9000
+
+#define TYPE_802_11_DATA    0x0800
+#define TYPE_802_11_CTL     0x0400
+#define TYPE_802_11_MGMT    0x0000
+#define TYPE_802_11_MASK    0x0C00
+#define TYPE_SUBTYPE_MASK   0xFC00
+#define TYPE_802_11_NODATA  0x4000
+#define TYPE_DATE_NULL      0x4800
+
+#define TYPE_CTL_PSPOLL     0xa400
+#define TYPE_CTL_RTS        0xb400
+#define TYPE_CTL_CTS        0xc400
+#define TYPE_CTL_ACK        0xd400
+
+
+//#define WEP_IV_MASK         0xFFFFFF00
+
+#else //if LITTLE_ENDIAN
+//
+// wType field in the SEthernetHeader
+//
+// NOTE....
+//   in network byte order, high byte is going first
+#define TYPE_PKT_IP         0x0008      //
+#define TYPE_PKT_ARP        0x0608      //
+#define TYPE_PKT_RARP       0x3580      //
+#define TYPE_PKT_IPX	    0x3781	    //
+
+#define TYPE_PKT_802_1x     0x8e88
+#define TYPE_PKT_PreAuth    0xC788
+
+#define TYPE_PKT_PING_M_REQ 0x1180      // master reguest
+#define TYPE_PKT_PING_S_GNT 0x2280      // slave grant
+#define TYPE_PKT_PING_M     0x7780      // pingpong master packet
+#define TYPE_PKT_PING_S     0x8880      // pingpong slave packet
+#define TYPE_PKT_WOL_M_REQ  0x3380      // WOL waker request
+#define TYPE_PKT_WOL_S_GNT  0x4480      // WOL sleeper grant
+#define TYPE_MGMT_PROBE_RSP 0x0050
+#define TYPE_PKT_VNT_DIAG   0x1180      // Diag Pkt
+#define TYPE_PKT_VNT_PER    0x8888      // Diag PER Pkt
+//
+// wFrameCtl field in the S802_11Header
+//
+// NOTE....
+//   in network byte order, high byte is going first
+#define FC_TODS             0x0100
+#define FC_FROMDS           0x0200
+#define FC_MOREFRAG         0x0400
+#define FC_RETRY            0x0800
+#define FC_POWERMGT         0x1000
+#define FC_MOREDATA         0x2000
+#define FC_WEP              0x4000
+#define TYPE_802_11_ATIM    0x0090
+
+#define TYPE_802_11_DATA    0x0008
+#define TYPE_802_11_CTL     0x0004
+#define TYPE_802_11_MGMT    0x0000
+#define TYPE_802_11_MASK    0x000C
+#define TYPE_SUBTYPE_MASK   0x00FC
+#define TYPE_802_11_NODATA  0x0040
+#define TYPE_DATE_NULL      0x0048
+
+#define TYPE_CTL_PSPOLL     0x00a4
+#define TYPE_CTL_RTS        0x00b4
+#define TYPE_CTL_CTS        0x00c4
+#define TYPE_CTL_ACK        0x00d4
+
+
+//#define WEP_IV_MASK         0x00FFFFFF
+
+#endif //#ifdef __BIG_ENDIAN
+
+#define WEP_IV_MASK         0x00FFFFFF
+
+/*---------------------  Export Types  ------------------------------*/
+//
+// Ethernet packet
+//
+typedef struct tagSEthernetHeader {
+    BYTE    abyDstAddr[U_ETHER_ADDR_LEN];
+    BYTE    abySrcAddr[U_ETHER_ADDR_LEN];
+    WORD    wType;
+}__attribute__ ((__packed__))
+SEthernetHeader, *PSEthernetHeader;
+
+
+//
+// 802_3 packet
+//
+typedef struct tagS802_3Header {
+    BYTE    abyDstAddr[U_ETHER_ADDR_LEN];
+    BYTE    abySrcAddr[U_ETHER_ADDR_LEN];
+    WORD    wLen;
+}__attribute__ ((__packed__))
+S802_3Header, *PS802_3Header;
+
+//
+// 802_11 packet
+//
+typedef struct tagS802_11Header {
+    WORD    wFrameCtl;
+    WORD    wDurationID;
+    BYTE    abyAddr1[U_ETHER_ADDR_LEN];
+    BYTE    abyAddr2[U_ETHER_ADDR_LEN];
+    BYTE    abyAddr3[U_ETHER_ADDR_LEN];
+    WORD    wSeqCtl;
+    BYTE    abyAddr4[U_ETHER_ADDR_LEN];
+}__attribute__ ((__packed__))
+S802_11Header, *PS802_11Header;
+
+/*---------------------  Export Macros ------------------------------*/
+// Frame type macro
+
+#define IS_MULTICAST_ADDRESS(pbyEtherAddr)          \
+    ((*(PBYTE)(pbyEtherAddr) & 0x01) == 1)
+
+#define IS_BROADCAST_ADDRESS(pbyEtherAddr) (        \
+    (*(PDWORD)(pbyEtherAddr) == 0xFFFFFFFFL) &&     \
+    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0xFFFF) \
+)
+
+#define IS_NULL_ADDRESS(pbyEtherAddr) (             \
+    (*(PDWORD)(pbyEtherAddr) == 0L) &&              \
+    (*(PWORD)((PBYTE)(pbyEtherAddr) + 4) == 0)      \
+)
+
+#define IS_ETH_ADDRESS_EQUAL(pbyAddr1, pbyAddr2) (  \
+    (*(PDWORD)(pbyAddr1) == *(PDWORD)(pbyAddr2)) && \
+    (*(PWORD)((PBYTE)(pbyAddr1) + 4) ==             \
+    *(PWORD)((PBYTE)(pbyAddr2) + 4))                \
+)
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+BYTE ETHbyGetHashIndexByCrc32(PBYTE pbyMultiAddr);
+//BYTE ETHbyGetHashIndexByCrc(PBYTE pbyMultiAddr);
+BOOL ETHbIsBufferCrc32Ok(PBYTE pbyBuffer, UINT cbFrameLength);
+
+#endif // __TETHER_H__
+
+
+
diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c
new file mode 100644
index 0000000..8ca1540
--- /dev/null
+++ b/drivers/staging/vt6656/tkip.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: tkip.c
+ *
+ * Purpose: Implement functions for 802.11i TKIP
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Mar. 11, 2003
+ *
+ * Functions:
+ *      TKIPvMixKey - Get TKIP RC4 Key from TK,TA, and TSC
+ *
+ * Revision History:
+ *
+ */
+
+#include "tmacro.h"
+#include "tkip.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/* The Sbox is reduced to 2 16-bit wide tables, each with 256 entries. */
+/* The 2nd table is the same as the 1st but with the upper and lower   */
+/* bytes swapped. To allow an endian tolerant implementation, the byte */
+/* halves have been expressed independently here.                      */
+const BYTE 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
+};
+
+const BYTE 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
+};
+
+
+//STKIPKeyManagement  sTKIPKeyTable[MAX_TKIP_KEY];
+
+/*---------------------  Static Functions  --------------------------*/
+unsigned int tkip_sbox(unsigned int index);
+unsigned int rotr1(unsigned int a);
+
+/*---------------------  Export Variables  --------------------------*/
+
+/************************************************************/
+/* tkip_sbox()                                              */
+/* Returns a 16 bit value from a 64K entry table. The Table */
+/* is synthesized from two 256 entry byte wide tables.      */
+/************************************************************/
+unsigned int tkip_sbox(unsigned int index)
+{
+    unsigned int index_low;
+    unsigned int index_high;
+    unsigned int 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);
+};
+
+
+unsigned int rotr1(unsigned int a)
+{
+    unsigned int b;
+
+    if ((a & 0x01) == 0x01) {
+        b = (a >> 1) | 0x8000;
+    } else {
+        b = (a >> 1) & 0x7fff;
+    }
+    b = b % 65536;
+    return b;
+}
+
+
+/*
+ * Description: Caculate RC4Key fom TK, TA, and TSC
+ *
+ * Parameters:
+ *  In:
+ *      pbyTKey         - TKey
+ *      pbyTA           - TA
+ *      dwTSC           - TSC
+ *  Out:
+ *      pbyRC4Key       - RC4Key
+ *
+ * Return Value: none
+ *
+ */
+VOID TKIPvMixKey(
+    PBYTE   pbyTKey,
+    PBYTE   pbyTA,
+    WORD    wTSC15_0,
+    DWORD   dwTSC47_16,
+    PBYTE   pbyRC4Key
+    )
+{
+    unsigned int p1k[5];
+//    unsigned int ttak0, ttak1, ttak2, ttak3, ttak4;
+    unsigned int tsc0, tsc1, tsc2;
+    unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5;
+    unsigned long int pnl,pnh;
+
+    int i, j;
+
+    pnl = wTSC15_0;
+    pnh = dwTSC47_16;
+
+    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] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256));
+    p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256));
+    p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[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*pbyTKey[1+j]) + pbyTKey[j])) % 65536 )) % 65536;
+        p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536 )) % 65536;
+        p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536 )) % 65536;
+        p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536 )) % 65536;
+        p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[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*pbyTKey[1]) + pbyTKey[0])) % 65536);
+    ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536);
+    ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536);
+    ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536);
+    ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536);
+    ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536);
+
+    ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12]));
+    ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14]));
+    ppk2 = ppk2 + rotr1(ppk1);
+    ppk3 = ppk3 + rotr1(ppk2);
+    ppk4 = ppk4 + rotr1(ppk3);
+    ppk5 = ppk5 + rotr1(ppk4);
+
+    /* Phase 2, Step 3 */
+    pbyRC4Key[0] = (tsc2 >> 8) % 256;
+    pbyRC4Key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
+    pbyRC4Key[2] = tsc2 % 256;
+    pbyRC4Key[3] = ((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) >> 1) % 256;
+
+    pbyRC4Key[4] = ppk0 % 256;
+    pbyRC4Key[5] = (ppk0 >> 8) % 256;
+
+    pbyRC4Key[6] = ppk1 % 256;
+    pbyRC4Key[7] = (ppk1 >> 8) % 256;
+
+    pbyRC4Key[8] = ppk2 % 256;
+    pbyRC4Key[9] = (ppk2 >> 8) % 256;
+
+    pbyRC4Key[10] = ppk3 % 256;
+    pbyRC4Key[11] = (ppk3 >> 8) % 256;
+
+    pbyRC4Key[12] = ppk4 % 256;
+    pbyRC4Key[13] = (ppk4 >> 8) % 256;
+
+    pbyRC4Key[14] = ppk5 % 256;
+    pbyRC4Key[15] = (ppk5 >> 8) % 256;
+}
diff --git a/drivers/staging/vt6656/tkip.h b/drivers/staging/vt6656/tkip.h
new file mode 100644
index 0000000..847ecdf
--- /dev/null
+++ b/drivers/staging/vt6656/tkip.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: tkip.h
+ *
+ * Purpose: Implement functions for 802.11i TKIP
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Mar. 11, 2003
+ *
+ */
+
+#ifndef __TKIP_H__
+#define __TKIP_H__
+
+#include "ttype.h"
+#include "tether.h"
+
+/*---------------------  Export Definitions -------------------------*/
+#define TKIP_KEY_LEN        16
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Macros ------------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+VOID TKIPvMixKey(
+    PBYTE   pbyTKey,
+    PBYTE   pbyTA,
+    WORD    wTSC15_0,
+    DWORD   dwTSC47_16,
+    PBYTE   pbyRC4Key
+    );
+
+#endif // __TKIP_H__
+
+
+
diff --git a/drivers/staging/vt6656/tmacro.h b/drivers/staging/vt6656/tmacro.h
new file mode 100644
index 0000000..e96c140
--- /dev/null
+++ b/drivers/staging/vt6656/tmacro.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: tmacro.h
+ *
+ * Purpose: define basic common types and macros
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+#ifndef __TMACRO_H__
+#define __TMACRO_H__
+
+#include "ttype.h"
+
+/****** Common helper macros ***********************************************/
+
+#if !defined(LOBYTE)
+#define LOBYTE(w)           ((BYTE)(w))
+#endif
+#if !defined(HIBYTE)
+#define HIBYTE(w)           ((BYTE)(((WORD)(w) >> 8) & 0xFF))
+#endif
+
+#if !defined(LOWORD)
+#define LOWORD(d)           ((WORD)(d))
+#endif
+#if !defined(HIWORD)
+#define HIWORD(d)           ((WORD)((((DWORD)(d)) >> 16) & 0xFFFF))
+#endif
+
+#define LODWORD(q)          ((q).u.dwLowDword)
+#define HIDWORD(q)          ((q).u.dwHighDword)
+
+#if !defined(MAKEWORD)
+#define MAKEWORD(lb, hb)    ((WORD)(((BYTE)(lb)) | (((WORD)((BYTE)(hb))) << 8)))
+#endif
+#if !defined(MAKEDWORD)
+#define MAKEDWORD(lw, hw)   ((DWORD)(((WORD)(lw)) | (((DWORD)((WORD)(hw))) << 16)))
+#endif
+
+#endif // __TMACRO_H__
+
+
diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h
new file mode 100644
index 0000000..9ee3f43
--- /dev/null
+++ b/drivers/staging/vt6656/ttype.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: ttype.h
+ *
+ * Purpose: define basic common types and macros
+ *
+ * Author: Tevin Chen
+ *
+ * Date: May 21, 1996
+ *
+ */
+
+
+#ifndef __TTYPE_H__
+#define __TTYPE_H__
+
+
+/******* Common definitions and typedefs ***********************************/
+
+#ifndef VOID
+#define VOID            void
+#endif
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+//2007-0115-05<Add>by MikeLiu
+#ifndef TxInSleep
+#define TxInSleep
+#endif
+
+//DavidWang
+
+
+//2007-0814-01<Add>by MikeLiu
+#ifndef Safe_Close
+#define Safe_Close
+#endif
+
+//2008-0131-02<Add>by MikeLiu
+#ifndef Adhoc_STA
+#define Adhoc_STA
+#endif
+
+typedef int             BOOL;
+
+#if !defined(TRUE)
+#define TRUE            1
+#endif
+#if !defined(FALSE)
+#define FALSE           0
+#endif
+
+
+#if !defined(SUCCESS)
+#define SUCCESS         0
+#endif
+
+//2007-0809-01<Add>by MikeLiu
+#ifndef  update_BssList
+#define update_BssList
+#endif
+
+#ifndef WPA_SM_Transtatus
+#define WPA_SM_Transtatus
+#endif
+
+#ifndef Calcu_LinkQual
+#define Calcu_LinkQual
+#endif
+
+/****** Simple typedefs  ***************************************************/
+
+/* These lines assume that your compiler's longs are 32 bits and
+ * shorts are 16 bits. It is already assumed that chars are 8 bits,
+ * but it doesn't matter if they're signed or unsigned.
+ */
+
+typedef signed char             I8;     /* 8-bit signed integer */
+
+typedef unsigned char           U8;     /* 8-bit unsigned integer */
+typedef unsigned short          U16;    /* 16-bit unsigned integer */
+typedef unsigned long           U32;    /* 32-bit unsigned integer */
+
+
+typedef char            CHAR;
+typedef signed short    SHORT;
+typedef signed int      INT;
+typedef signed long     LONG;
+
+typedef unsigned char   UCHAR;
+typedef unsigned short  USHORT;
+typedef unsigned int    UINT;
+typedef unsigned long   ULONG;
+typedef unsigned long long	ULONGLONG; //64 bit
+
+
+
+typedef unsigned char   BYTE;           //  8-bit
+typedef unsigned short  WORD;           // 16-bit
+typedef unsigned long   DWORD;          // 32-bit
+
+// QWORD is for those situation that we want
+// an 8-byte-aligned 8 byte long structure
+// which is NOT really a floating point number.
+typedef union tagUQuadWord {
+    struct {
+        DWORD   dwLowDword;
+        DWORD   dwHighDword;
+    } u;
+    double      DoNotUseThisField;
+} UQuadWord;
+typedef UQuadWord       QWORD;          // 64-bit
+
+
+/****** Common pointer types ***********************************************/
+
+typedef unsigned long   ULONG_PTR;      // 32-bit
+typedef unsigned long   DWORD_PTR;      // 32-bit
+
+// boolean pointer
+typedef unsigned int *   PUINT;
+
+typedef BYTE *           PBYTE;
+
+typedef WORD *           PWORD;
+
+typedef DWORD *          PDWORD;
+
+typedef QWORD *          PQWORD;
+
+typedef void *           PVOID;
+
+// handle declaration
+#ifdef STRICT
+typedef void *HANDLE;
+#else
+typedef PVOID HANDLE;
+#endif
+
+#endif // __TTYPE_H__
diff --git a/drivers/staging/vt6656/upc.h b/drivers/staging/vt6656/upc.h
new file mode 100644
index 0000000..acd1b66
--- /dev/null
+++ b/drivers/staging/vt6656/upc.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: upc.h
+ *
+ * Purpose: Macros to access device
+ *
+ * Author: Tevin Chen
+ *
+ * Date: Mar 17, 1997
+ *
+ */
+
+#ifndef __UPC_H__
+#define __UPC_H__
+
+#include "device.h"
+#include "ttype.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+//
+//  For IO mapped
+//
+
+#ifdef IO_MAP
+
+#define VNSvInPortB(dwIOAddress, pbyData) {                     \
+	*(pbyData) = inb(dwIOAddress);                              \
+}
+
+
+#define VNSvInPortW(dwIOAddress, pwData) {                      \
+	    *(pwData) = inw(dwIOAddress);                           \
+}
+
+#define VNSvInPortD(dwIOAddress, pdwData) {                     \
+	    *(pdwData) = inl(dwIOAddress);                          \
+}
+
+
+#define VNSvOutPortB(dwIOAddress, byData) {                     \
+        outb(byData, dwIOAddress);                              \
+}
+
+
+#define VNSvOutPortW(dwIOAddress, wData) {                      \
+        outw(wData, dwIOAddress);                               \
+}
+
+#define VNSvOutPortD(dwIOAddress, dwData) {                     \
+        outl(dwData, dwIOAddress);                              \
+}
+
+#else
+
+//
+//  For memory mapped IO
+//
+
+
+#define VNSvInPortB(dwIOAddress, pbyData) {                     \
+	volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress));            \
+	*(pbyData) = readb(pbyAddr);                           \
+}
+
+
+#define VNSvInPortW(dwIOAddress, pwData) {                      \
+	volatile WORD* pwAddr = ((PWORD)(dwIOAddress));             \
+	*(pwData) = readw(pwAddr);                             \
+}
+
+#define VNSvInPortD(dwIOAddress, pdwData) {                     \
+	volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress));          \
+	*(pdwData) = readl(pdwAddr);                           \
+}
+
+
+#define VNSvOutPortB(dwIOAddress, byData) {                     \
+    volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress));            \
+    writeb((BYTE)byData, pbyAddr);							\
+}
+
+
+#define VNSvOutPortW(dwIOAddress, wData) {                      \
+    volatile WORD* pwAddr = ((PWORD)(dwIOAddress));             \
+    writew((WORD)wData, pwAddr);							\
+}
+
+#define VNSvOutPortD(dwIOAddress, dwData) {                     \
+    volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress));          \
+    writel((DWORD)dwData, pdwAddr);					    \
+}
+
+#endif
+
+
+//
+// ALWAYS IO-Mapped IO when in 16-bit/32-bit environment
+//
+#define PCBvInPortB(dwIOAddress, pbyData) {     \
+	    *(pbyData) = inb(dwIOAddress);          \
+}
+
+#define PCBvInPortW(dwIOAddress, pwData) {      \
+	    *(pwData) = inw(dwIOAddress);           \
+}
+
+#define PCBvInPortD(dwIOAddress, pdwData) {     \
+	    *(pdwData) = inl(dwIOAddress);          \
+}
+
+#define PCBvOutPortB(dwIOAddress, byData) {     \
+        outb(byData, dwIOAddress);              \
+}
+
+#define PCBvOutPortW(dwIOAddress, wData) {      \
+        outw(wData, dwIOAddress);               \
+}
+
+#define PCBvOutPortD(dwIOAddress, dwData) {     \
+        outl(dwData, dwIOAddress);              \
+}
+
+
+#define PCAvDelayByIO(uDelayUnit) {             \
+    BYTE    byData;                             \
+    ULONG   ii;                                 \
+                                                \
+    if (uDelayUnit <= 50) {                     \
+        udelay(uDelayUnit);                     \
+    }                                           \
+    else {                                      \
+        for (ii = 0; ii < (uDelayUnit); ii++)   \
+		     byData = inb(0x61);				\
+    }                                           \
+}
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+
+#endif // __UPC_H__
+
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
new file mode 100644
index 0000000..65e91a3
--- /dev/null
+++ b/drivers/staging/vt6656/usbpipe.c
@@ -0,0 +1,841 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: usbpipe.c
+ *
+ * Purpose: Handle USB control endpoint
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Mar. 29, 2005
+ *
+ * Functions:
+ *      CONTROLnsRequestOut - Write variable length bytes to MEM/BB/MAC/EEPROM
+ *      CONTROLnsRequestIn - Read variable length bytes from MEM/BB/MAC/EEPROM
+ *      ControlvWriteByte - Write one byte to MEM/BB/MAC/EEPROM
+ *      ControlvReadByte - Read one byte from MEM/BB/MAC/EEPROM
+ *      ControlvMaskByte - Read one byte from MEM/BB/MAC/EEPROM and clear/set some bits in the same address
+ *
+ * Revision History:
+ *      04-05-2004 Jerry Chen:  Initial release
+ *      11-24-2004 Warren Hsu: Add ControlvWriteByte,ControlvReadByte,ControlvMaskByte
+ *
+ */
+
+#include "int.h"
+#include "rxtx.h"
+#include "dpc.h"
+#include "control.h"
+#include "desc.h"
+#include "device.h"
+
+/*---------------------  Static Definitions -------------------------*/
+//endpoint def
+//endpoint 0: control
+//endpoint 1: interrupt
+//endpoint 2: read bulk
+//endpoint 3: write bulk
+
+//RequestType:
+//#define REQUEST_OUT       (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) // 0x40
+//#define REQUEST_IN        (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE )  //0xc0
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+
+#define USB_CTL_WAIT   500 //ms
+
+#ifndef URB_ASYNC_UNLINK
+#define URB_ASYNC_UNLINK    0
+#endif
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+/*---------------------  Static Functions  --------------------------*/
+static
+VOID
+s_nsInterruptUsbIoCompleteRead(
+    IN struct urb *urb
+    );
+
+
+static
+VOID
+s_nsBulkInUsbIoCompleteRead(
+    IN struct urb *urb
+    );
+
+
+static
+VOID
+s_nsBulkOutIoCompleteWrite(
+    IN struct urb *urb
+    );
+
+
+static
+VOID
+s_nsControlInUsbIoCompleteRead(
+    IN struct urb *urb
+    );
+
+static
+VOID
+s_nsControlInUsbIoCompleteWrite(
+    IN struct urb *urb
+    );
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+NTSTATUS
+PIPEnsControlOutAsyn(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN PBYTE        pbyBuffer
+    )
+{
+    NTSTATUS                ntStatus;
+
+
+    if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+        return STATUS_FAILURE;
+
+
+    if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
+        return STATUS_FAILURE;
+    }
+
+    if (in_interrupt()) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"in_interrupt return ..byRequest %x\n", byRequest);
+        return STATUS_FAILURE;
+    }
+
+    ntStatus = usb_control_msg(
+                            pDevice->usb,
+                            usb_sndctrlpipe(pDevice->usb , 0),
+                            byRequest,
+                            0x40, // RequestType
+                            wValue,
+                            wIndex,
+                            (PVOID) pbyBuffer,
+                            wLength,
+                            HZ
+                          );
+    if (ntStatus >= 0) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe ntStatus= %d\n", ntStatus);
+        ntStatus = 0;
+    } else {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"usb_sndctrlpipe fail, ntStatus= %d\n", ntStatus);
+    }
+
+    return ntStatus;
+}
+
+
+
+
+
+NTSTATUS
+PIPEnsControlOut(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN PBYTE        pbyBuffer
+    )
+{
+    NTSTATUS            ntStatus = 0;
+    int ii;
+
+
+    if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+        return STATUS_FAILURE;
+
+    if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES)) {
+        return STATUS_FAILURE;
+    }
+
+	pDevice->sUsbCtlRequest.bRequestType = 0x40;
+	pDevice->sUsbCtlRequest.bRequest = byRequest;
+	pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
+	pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
+	pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
+	pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
+    pDevice->pControlURB->actual_length = 0;
+    // Notice, pbyBuffer limited point to variable buffer, can't be constant.
+  	usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
+			 usb_sndctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
+			 pbyBuffer, wLength, s_nsControlInUsbIoCompleteWrite, pDevice);
+
+	if ((ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC)) != 0) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus);
+		return STATUS_FAILURE;
+	}
+	else {
+	    MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES);
+	}
+	spin_unlock_irq(&pDevice->lock);
+    for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
+        if (MP_TEST_FLAG(pDevice, fMP_CONTROL_WRITES))
+            mdelay(1);
+        else
+            break;
+        if (ii >= USB_CTL_WAIT) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission timeout \n");
+            spin_lock_irq(&pDevice->lock);
+            MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+            return STATUS_FAILURE;
+        }
+    }
+	spin_lock_irq(&pDevice->lock);
+
+    return STATUS_SUCCESS;
+}
+
+
+
+
+NTSTATUS
+PIPEnsControlIn(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN OUT  PBYTE   pbyBuffer
+    )
+{
+    NTSTATUS            ntStatus = 0;
+    int ii;
+
+    if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+        return STATUS_FAILURE;
+
+    if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS)) {
+        return STATUS_FAILURE;
+    }
+	pDevice->sUsbCtlRequest.bRequestType = 0xC0;
+	pDevice->sUsbCtlRequest.bRequest = byRequest;
+	pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue);
+	pDevice->sUsbCtlRequest.wIndex = cpu_to_le16p(&wIndex);
+	pDevice->sUsbCtlRequest.wLength = cpu_to_le16p(&wLength);
+	pDevice->pControlURB->transfer_flags |= URB_ASYNC_UNLINK;
+    pDevice->pControlURB->actual_length = 0;
+	usb_fill_control_urb(pDevice->pControlURB, pDevice->usb,
+			 usb_rcvctrlpipe(pDevice->usb , 0), (char *) &pDevice->sUsbCtlRequest,
+			 pbyBuffer, wLength, s_nsControlInUsbIoCompleteRead, pDevice);
+
+	if ((ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC)) != 0) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus);
+	}else {
+		MP_SET_FLAG(pDevice, fMP_CONTROL_READS);
+    }
+
+	spin_unlock_irq(&pDevice->lock);
+    for (ii = 0; ii <= USB_CTL_WAIT; ii ++) {
+        if (MP_TEST_FLAG(pDevice, fMP_CONTROL_READS))
+            mdelay(1);
+        else {
+            break;
+        }
+        if (ii >= USB_CTL_WAIT) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control rcv request submission timeout \n");
+            spin_lock_irq(&pDevice->lock);
+            MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+            return STATUS_FAILURE;
+        }
+    }
+	spin_lock_irq(&pDevice->lock);
+
+    return ntStatus;
+}
+
+static
+VOID
+s_nsControlInUsbIoCompleteWrite(
+    IN struct urb *urb
+    )
+{
+    PSDevice        pDevice;
+
+	pDevice = urb->context;
+	switch (urb->status) {
+	case 0:
+		break;
+	case -EINPROGRESS:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status EINPROGRESS%d\n", urb->status);
+		break;
+	case -ENOENT:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status ENOENT %d\n", urb->status);
+		break;
+	default:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl write urb status %d\n", urb->status);
+	}
+
+    MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES);
+}
+
+
+
+/*
+ * Description:
+ *      Complete function of usb Control callback
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+static
+VOID
+s_nsControlInUsbIoCompleteRead(
+    IN struct urb *urb
+    )
+{
+    PSDevice        pDevice;
+
+	pDevice = urb->context;
+	switch (urb->status) {
+	case 0:
+		break;
+	case -EINPROGRESS:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status EINPROGRESS%d\n", urb->status);
+		break;
+	case -ENOENT:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status = ENOENT %d\n", urb->status);
+		break;
+	default:
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ctrl read urb status %d\n", urb->status);
+	}
+
+    MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS);
+}
+
+
+
+
+/*
+ * Description:
+ *      Allocates an usb interrupt in irp and calls USBD.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+NTSTATUS
+PIPEnsInterruptRead(
+    IN PSDevice pDevice
+    )
+{
+    NTSTATUS            ntStatus = STATUS_FAILURE;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartInterruptUsbRead()\n");
+
+    if(pDevice->intBuf.bInUse == TRUE){
+        return (STATUS_FAILURE);
+    }
+    pDevice->intBuf.bInUse = TRUE;
+//    pDevice->bEventAvailable = FALSE;
+    pDevice->ulIntInPosted++;
+
+    //
+    // Now that we have created the urb, we will send a
+    // request to the USB device object.
+    //
+#if 0            //reserve int URB submit
+	usb_fill_int_urb(pDevice->pInterruptURB,
+	                 pDevice->usb,
+	                 usb_rcvintpipe(pDevice->usb, 1),
+	                 (PVOID) pDevice->intBuf.pDataBuf,
+	                 MAX_INTERRUPT_SIZE,
+	                 s_nsInterruptUsbIoCompleteRead,
+	                 pDevice,
+	                 pDevice->int_interval
+	                 );
+#else            //replace int URB submit by bulk transfer
+#ifndef Safe_Close
+	usb_fill_int_urb(pDevice->pInterruptURB,
+	                 pDevice->usb,
+	                 usb_rcvintpipe(pDevice->usb, 1),
+	                 (PVOID) pDevice->intBuf.pDataBuf,
+	                 MAX_INTERRUPT_SIZE,
+	                 s_nsInterruptUsbIoCompleteRead,
+	                 pDevice,
+	                 pDevice->int_interval
+	                 );
+#else
+
+    pDevice->pInterruptURB->interval = pDevice->int_interval;
+
+usb_fill_bulk_urb(pDevice->pInterruptURB,
+		pDevice->usb,
+		usb_rcvbulkpipe(pDevice->usb, 1),
+		(PVOID) pDevice->intBuf.pDataBuf,
+		MAX_INTERRUPT_SIZE,
+		s_nsInterruptUsbIoCompleteRead,
+		pDevice);
+#endif
+#endif
+
+	if ((ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC)) != 0) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+    }
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"<----s_nsStartInterruptUsbRead Return(%x)\n",ntStatus);
+    return ntStatus;
+}
+
+
+/*
+ * Description:
+ *      Complete function of usb interrupt in irp.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+static
+VOID
+s_nsInterruptUsbIoCompleteRead(
+    IN struct urb *urb
+    )
+
+{
+    PSDevice        pDevice;
+    NTSTATUS        ntStatus;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsInterruptUsbIoCompleteRead\n");
+    //
+    // The context given to IoSetCompletionRoutine is the receive buffer object
+    //
+    pDevice = (PSDevice)urb->context;
+
+    //
+    // We have a number of cases:
+    //      1) The USB read timed out and we received no data.
+    //      2) The USB read timed out and we received some data.
+    //      3) The USB read was successful and fully filled our irp buffer.
+    //      4) The irp was cancelled.
+    //      5) Some other failure from the USB device object.
+    //
+    ntStatus = urb->status;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsInterruptUsbIoCompleteRead Status %d\n", ntStatus);
+
+    // if we were not successful, we need to free the int buffer for future use right here
+    // otherwise interrupt data handler will free int buffer after it handle it.
+    if (( ntStatus != STATUS_SUCCESS )) {
+        pDevice->ulBulkInError++;
+        pDevice->intBuf.bInUse = FALSE;
+
+//        if (ntStatus == USBD_STATUS_CRC) {
+//            pDevice->ulIntInContCRCError++;
+//        }
+
+//        if (ntStatus == STATUS_NOT_CONNECTED )
+//        {
+            pDevice->fKillEventPollingThread = TRUE;
+//        }
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"IntUSBIoCompleteControl STATUS = %d\n", ntStatus );
+    }
+    else {
+        pDevice->ulIntInBytesRead += (ULONG)urb->actual_length;
+        pDevice->ulIntInContCRCError = 0;
+        pDevice->bEventAvailable = TRUE;
+        INTnsProcessData(pDevice);
+    }
+
+    STAvUpdateUSBCounter(&pDevice->scStatistic.USB_InterruptStat, ntStatus);
+
+
+    if (pDevice->fKillEventPollingThread != TRUE) {
+   #if 0               //reserve int URB submit
+	if ((ntStatus = usb_submit_urb(urb, GFP_ATOMIC)) != 0) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Re-Submit int URB failed %d\n", ntStatus);
+    }
+   #else                                                                                     //replace int URB submit by bulk transfer
+    #ifdef Safe_Close
+       usb_fill_bulk_urb(pDevice->pInterruptURB,
+		      pDevice->usb,
+		      usb_rcvbulkpipe(pDevice->usb, 1),
+		     (PVOID) pDevice->intBuf.pDataBuf,
+		     MAX_INTERRUPT_SIZE,
+		     s_nsInterruptUsbIoCompleteRead,
+		     pDevice);
+
+	if ((ntStatus = usb_submit_urb(pDevice->pInterruptURB, GFP_ATOMIC)) != 0) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit int URB failed %d\n", ntStatus);
+           }
+
+    #else
+        tasklet_schedule(&pDevice->EventWorkItem);
+    #endif
+#endif
+    }
+    //
+    // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
+    // routine (IofCompleteRequest) will stop working on the irp.
+    //
+    return ;
+}
+
+/*
+ * Description:
+ *      Allocates an usb BulkIn  irp and calls USBD.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+NTSTATUS
+PIPEnsBulkInUsbRead(
+    IN PSDevice pDevice,
+    IN PRCB     pRCB
+    )
+{
+    NTSTATUS            ntStatus= 0;
+    struct urb          *pUrb;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsStartBulkInUsbRead\n");
+
+    if (MP_TEST_FLAG(pDevice, fMP_DISCONNECTED))
+        return STATUS_FAILURE;
+
+    pDevice->ulBulkInPosted++;
+
+
+	pUrb = pRCB->pUrb;
+    //
+    // Now that we have created the urb, we will send a
+    // request to the USB device object.
+    //
+    if (pRCB->skb == NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pRCB->skb is null \n");
+        return ntStatus;
+    }
+
+	usb_fill_bulk_urb(pUrb,
+		pDevice->usb,
+		usb_rcvbulkpipe(pDevice->usb, 2),
+		(PVOID) (pRCB->skb->data),
+		MAX_TOTAL_SIZE_WITH_ALL_HEADERS,
+		s_nsBulkInUsbIoCompleteRead,
+		pRCB);
+
+	if((ntStatus = usb_submit_urb(pUrb, GFP_ATOMIC)) != 0){
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Rx URB failed %d\n", ntStatus);
+		return STATUS_FAILURE ;
+	}
+    pRCB->Ref = 1;
+    pRCB->bBoolInUse= TRUE;
+
+    return ntStatus;
+}
+
+
+
+
+/*
+ * Description:
+ *      Complete function of usb BulkIn irp.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+static
+VOID
+s_nsBulkInUsbIoCompleteRead(
+    IN struct urb *urb
+    )
+
+{
+    PRCB    pRCB = (PRCB)urb->context;
+    PSDevice pDevice = (PSDevice)pRCB->pDevice;
+    ULONG   bytesRead;
+    BOOL    bIndicateReceive = FALSE;
+    BOOL    bReAllocSkb = FALSE;
+    NTSTATUS    status;
+
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkInUsbIoCompleteRead\n");
+    status = urb->status;
+    bytesRead = urb->actual_length;
+
+    if (status) {
+        pDevice->ulBulkInError++;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK In failed %d\n", status);
+
+     	#ifdef Calcu_LinkQual
+           pDevice->scStatistic.RxFcsErrCnt ++;
+	#endif
+//todo...xxxxxx
+//        if (status == USBD_STATUS_CRC) {
+//            pDevice->ulBulkInContCRCError++;
+//        }
+//        if (status == STATUS_DEVICE_NOT_CONNECTED )
+//        {
+//            MP_SET_FLAG(pDevice, fMP_DISCONNECTED);
+//        }
+    } else {
+        bIndicateReceive = TRUE;
+        pDevice->ulBulkInContCRCError = 0;
+        pDevice->ulBulkInBytesRead += bytesRead;
+
+	#ifdef Calcu_LinkQual
+           pDevice->scStatistic.RxOkCnt ++;
+	#endif
+    }
+
+
+    STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkInStat, status);
+
+    if (bIndicateReceive) {
+        spin_lock(&pDevice->lock);
+        if (RXbBulkInProcessData(pDevice, pRCB, bytesRead) == TRUE)
+            bReAllocSkb = TRUE;
+        spin_unlock(&pDevice->lock);
+    }
+    pRCB->Ref--;
+    if (pRCB->Ref == 0)
+    {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"RxvFreeNormal %d \n",pDevice->NumRecvFreeList);
+        spin_lock(&pDevice->lock);
+        RXvFreeRCB(pRCB, bReAllocSkb);
+        spin_unlock(&pDevice->lock);
+    }
+
+
+    return;
+}
+
+/*
+ * Description:
+ *      Allocates an usb BulkOut  irp and calls USBD.
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_INSUFFICIENT_RESOURCES or result of IoCallDriver
+ *
+ */
+NDIS_STATUS
+PIPEnsSendBulkOut(
+    IN  PSDevice pDevice,
+    IN  PUSB_SEND_CONTEXT pContext
+    )
+{
+    NTSTATUS            status;
+    struct urb          *pUrb;
+
+
+
+    pDevice->bPWBitOn = FALSE;
+
+/*
+    if (pDevice->pPendingBulkOutContext != NULL) {
+        pDevice->NumContextsQueued++;
+        EnqueueContext(pDevice->FirstTxContextQueue, pDevice->LastTxContextQueue, pContext);
+        status = STATUS_PENDING;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send pending!\n");
+        return status;
+    }
+*/
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"s_nsSendBulkOut\n");
+
+    if(MP_IS_READY(pDevice) && MP_TEST_FLAG(pDevice, fMP_POST_WRITES)) {
+
+        pUrb = pContext->pUrb;
+        pDevice->ulBulkOutPosted++;
+//        pDevice->pPendingBulkOutContext = pContext;
+        usb_fill_bulk_urb(
+        	    pUrb,
+        		pDevice->usb,
+        		usb_sndbulkpipe(pDevice->usb, 3),
+        		(PVOID) &(pContext->Data[0]),
+        		pContext->uBufLen,
+        		s_nsBulkOutIoCompleteWrite,
+        		pContext);
+
+    	if((status = usb_submit_urb(pUrb, GFP_ATOMIC))!=0)
+    	{
+    		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status);
+    		return STATUS_FAILURE;
+    	}
+        return STATUS_PENDING;
+    }
+    else {
+        pContext->bBoolInUse = FALSE;
+        return STATUS_RESOURCES;
+    }
+}
+
+/*
+ * Description: s_nsBulkOutIoCompleteWrite
+ *     1a) Indicate to the protocol the status of the write.
+ *     1b) Return ownership of the packet to the protocol.
+ *
+ *     2)  If any more packets are queue for sending, send another packet
+ *         to USBD.
+ *         If the attempt to send the packet to the driver fails,
+ *         return ownership of the packet to the protocol and
+ *         try another packet (until one succeeds).
+ *
+ * Parameters:
+ *  In:
+ *      pdoUsbDevObj  - pointer to the USB device object which
+ *                      completed the irp
+ *      pIrp          - the irp which was completed by the
+ *                      device object
+ *      pContext      - the context given to IoSetCompletionRoutine
+ *                      before calling IoCallDriver on the irp
+ *                      The pContext is a pointer to the USB device object.
+ *  Out:
+ *      none
+ *
+ * Return Value: STATUS_MORE_PROCESSING_REQUIRED - allows the completion routine
+ *               (IofCompleteRequest) to stop working on the irp.
+ *
+ */
+static
+VOID
+s_nsBulkOutIoCompleteWrite(
+    IN struct urb *urb
+    )
+{
+    PSDevice            pDevice;
+    NTSTATUS            status;
+    CONTEXT_TYPE        ContextType;
+    ULONG               ulBufLen;
+    PUSB_SEND_CONTEXT   pContext;
+
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->s_nsBulkOutIoCompleteWrite\n");
+    //
+    // The context given to IoSetCompletionRoutine is an USB_CONTEXT struct
+    //
+    pContext = (PUSB_SEND_CONTEXT) urb->context;
+    ASSERT( NULL != pContext );
+
+    pDevice = pContext->pDevice;
+    ContextType = pContext->Type;
+    ulBufLen = pContext->uBufLen;
+
+    if (!netif_device_present(pDevice->dev))
+	    return;
+
+   //
+    // Perform various IRP, URB, and buffer 'sanity checks'
+    //
+
+    status = urb->status;
+    //we should have failed, succeeded, or cancelled, but NOT be pending
+    STAvUpdateUSBCounter(&pDevice->scStatistic.USB_BulkOutStat, status);
+
+    if(status == STATUS_SUCCESS) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Write %d bytes\n",(int)ulBufLen);
+        pDevice->ulBulkOutBytesWrite += ulBufLen;
+        pDevice->ulBulkOutContCRCError = 0;
+	//2007-0115-06<Add>by MikeLiu
+           #ifdef TxInSleep
+             pDevice->nTxDataTimeCout = 0;
+           #endif
+
+    } else {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BULK Out failed %d\n", status);
+        pDevice->ulBulkOutError++;
+    }
+
+//    pDevice->ulCheckForHangCount = 0;
+//    pDevice->pPendingBulkOutContext = NULL;
+
+    if ( CONTEXT_DATA_PACKET == ContextType ) {
+        // Indicate to the protocol the status of the sent packet and return
+        // ownership of the packet.
+	    if (pContext->pPacket != NULL) {
+	        dev_kfree_skb_irq(pContext->pPacket);
+	        pContext->pPacket = NULL;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"tx  %d bytes\n",(int)ulBufLen);
+	    }
+
+        pDevice->dev->trans_start = jiffies;
+
+
+        if (status == STATUS_SUCCESS) {
+            pDevice->packetsSent++;
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send USB error! [%08xh]\n", status);
+            pDevice->packetsSentDropped++;
+        }
+
+    }
+    if (pDevice->bLinkPass == TRUE) {
+        if (netif_queue_stopped(pDevice->dev))
+            netif_wake_queue(pDevice->dev);
+    }
+    pContext->bBoolInUse = FALSE;
+
+    return;
+}
diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h
new file mode 100644
index 0000000..c422d1d
--- /dev/null
+++ b/drivers/staging/vt6656/usbpipe.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: usbpipe.h
+ *
+ * Purpose:
+ *
+ * Author: Warren Hsu
+ *
+ * Date: Mar. 30, 2005
+ *
+ */
+
+#ifndef __USBPIPE_H__
+#define __USBPIPE_H__
+
+#include "ttype.h"
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+NTSTATUS
+PIPEnsControlOut(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN PBYTE        pbyBuffer
+    );
+
+
+
+NTSTATUS
+PIPEnsControlOutAsyn(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN PBYTE        pbyBuffer
+    );
+
+NTSTATUS
+PIPEnsControlIn(
+    IN PSDevice     pDevice,
+    IN BYTE         byRequest,
+    IN WORD         wValue,
+    IN WORD         wIndex,
+    IN WORD         wLength,
+    IN OUT  PBYTE   pbyBuffer
+    );
+
+
+
+
+NTSTATUS
+PIPEnsInterruptRead(
+    IN PSDevice pDevice
+    );
+
+NTSTATUS
+PIPEnsBulkInUsbRead(
+    IN PSDevice pDevice,
+    IN PRCB     pRCB
+    );
+
+NTSTATUS
+PIPEnsSendBulkOut(
+    IN  PSDevice pDevice,
+    IN  PUSB_SEND_CONTEXT pContext
+    );
+
+#endif // __USBPIPE_H__
+
+
+
diff --git a/drivers/staging/vt6656/vntconfiguration.dat b/drivers/staging/vt6656/vntconfiguration.dat
new file mode 100644
index 0000000..933774c
--- /dev/null
+++ b/drivers/staging/vt6656/vntconfiguration.dat
@@ -0,0 +1,6 @@
+#VNT Configuration
+[start]
+ZONETYPE=EUROPE
+AUTHENMODE=12
+ENCRYPTIONMODE=34
+[end]
\ No newline at end of file
diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c
new file mode 100644
index 0000000..6912344
--- /dev/null
+++ b/drivers/staging/vt6656/wcmd.c
@@ -0,0 +1,1354 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: wcmd.c
+ *
+ * Purpose: Handles the management command interface functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2003
+ *
+ * Functions:
+ *      s_vProbeChannel - Active scan channel
+ *      s_MgrMakeProbeRequest - Make ProbeRequest packet
+ *      CommandTimer - Timer function to handle command
+ *      s_bCommandComplete - Command Complete function
+ *      bScheduleCommand - Push Command and wait Command Scheduler to do
+ *      vCommandTimer- Command call back functions
+ *      vCommandTimerWait- Call back timer
+ *      s_bClearBSSID_SCAN- Clear BSSID_SCAN cmd in CMD Queue
+ *
+ * Revision History:
+ *
+ */
+
+#include "ttype.h"
+#include "tmacro.h"
+#include "device.h"
+#include "mac.h"
+#include "card.h"
+#include "80211hdr.h"
+#include "wcmd.h"
+#include "wmgr.h"
+#include "power.h"
+#include "wctl.h"
+#include "card.h"
+#include "baseband.h"
+#include "control.h"
+#include "rxtx.h"
+#include "rf.h"
+#include "rndis.h"
+#include "channel.h"
+#include "iowpa.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Functions  --------------------------*/
+
+static
+VOID
+s_vProbeChannel(
+    IN PSDevice pDevice
+    );
+
+
+static
+PSTxMgmtPacket
+s_MgrMakeProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pScanBSSID,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+
+static
+BOOL
+s_bCommandComplete (
+    PSDevice pDevice
+    );
+
+
+static
+BOOL s_bClearBSSID_SCAN (
+    IN HANDLE hDeviceContext
+    );
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+
+/*
+ * Description:
+ *      Stop AdHoc beacon during scan process
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+static
+void
+vAdHocBeaconStop(PSDevice  pDevice)
+{
+
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    BOOL            bStop;
+
+    /*
+     * temporarily stop Beacon packet for AdHoc Server
+     * if all of the following coditions are met:
+     *  (1) STA is in AdHoc mode
+     *  (2) VT3253 is programmed as automatic Beacon Transmitting
+     *  (3) One of the following conditions is met
+     *      (3.1) AdHoc channel is in B/G band and the
+     *      current scan channel is in A band
+     *      or
+     *      (3.2) AdHoc channel is in A mode
+     */
+    bStop = FALSE;
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+    (pMgmt->eCurrState >= WMAC_STATE_STARTED))
+    {
+        if ((pMgmt->uIBSSChannel <=  CB_MAX_CHANNEL_24G) &&
+             (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G))
+        {
+            bStop = TRUE;
+        }
+        if (pMgmt->uIBSSChannel >  CB_MAX_CHANNEL_24G)
+        {
+            bStop = TRUE;
+        }
+    }
+
+    if (bStop)
+    {
+        //PMESG(("STOP_BEACON: IBSSChannel = %u, ScanChannel = %u\n",
+        //        pMgmt->uIBSSChannel, pMgmt->uScanChannel));
+        MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+
+} /* vAdHocBeaconStop */
+
+
+/*
+ * Description:
+ *      Restart AdHoc beacon after scan process complete
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to the adapter
+ *  Out:
+ *      none
+ *
+ * Return Value: none
+ *
+ */
+static
+void
+vAdHocBeaconRestart(PSDevice pDevice)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+
+    /*
+     * Restart Beacon packet for AdHoc Server
+     * if all of the following coditions are met:
+     *  (1) STA is in AdHoc mode
+     *  (2) VT3253 is programmed as automatic Beacon Transmitting
+     */
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+    (pMgmt->eCurrState >= WMAC_STATE_STARTED))
+    {
+        //PMESG(("RESTART_BEACON\n"));
+        MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Prepare and send probe request management frames.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+static
+VOID
+s_vProbeChannel(
+    IN PSDevice pDevice
+    )
+{
+                                                     //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
+    BYTE abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+    BYTE abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+                                                           //6M,   9M,   12M,  48M
+    BYTE abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    BYTE abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+    PBYTE           pbyRate;
+    PSTxMgmtPacket  pTxPacket;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    UINT            ii;
+
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        pbyRate = &abyCurrSuppRatesA[0];
+    } else if (pDevice->byBBType == BB_TYPE_11B) {
+        pbyRate = &abyCurrSuppRatesB[0];
+    } else {
+        pbyRate = &abyCurrSuppRatesG[0];
+    }
+    // build an assocreq frame and send it
+    pTxPacket = s_MgrMakeProbeRequest
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->abyScanBSSID,
+                  (PWLAN_IE_SSID)pMgmt->abyScanSSID,
+                  (PWLAN_IE_SUPP_RATES)pbyRate,
+                  (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRatesG
+                );
+
+    if (pTxPacket != NULL ){
+        for (ii = 0; ii < 1 ; ii++) {
+            if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail.. \n");
+            }
+            else {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending.. \n");
+            }
+        }
+    }
+
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an probe request frame
+ *
+ *
+ * Return Value:
+ *    A ptr to Tx frame or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pScanBSSID,
+    IN PWLAN_IE_SSID pSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_PROBEREQ    sFrame;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBEREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_PROBEREQ_FR_MAXLEN;
+    vMgrEncodeProbeRequest(&sFrame);
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBEREQ)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pScanBSSID, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pScanBSSID, WLAN_BSSID_LEN);
+    // Copy the SSID, pSSID->len=0 indicate broadcast SSID
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pSSID->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID, pSSID, pSSID->len + WLAN_IEHDR_LEN);
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    // Copy the extension rate set
+    if (pDevice->byBBType == BB_TYPE_11G) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+    }
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+
+
+VOID
+vCommandTimerWait(
+    IN HANDLE    hDeviceContext,
+    IN UINT MSecond
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    init_timer(&pDevice->sTimerCommand);
+    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
+    // RUN_AT :1 msec ~= (HZ/1024)
+    pDevice->sTimerCommand.expires = (UINT)RUN_AT((MSecond * HZ) >> 10);
+    add_timer(&pDevice->sTimerCommand);
+    return;
+}
+
+
+
+
+VOID
+vRunCommand(
+    IN  HANDLE      hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PWLAN_IE_SSID   pItemSSID;
+    PWLAN_IE_SSID   pItemSSIDCurr;
+    CMD_STATUS      Status;
+    UINT            ii;
+    BYTE            byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    struct sk_buff  *skb;
+    BYTE            byData;
+
+
+    if (pDevice->dwDiagRefCount != 0)
+        return;
+    if (pDevice->bCmdRunning != TRUE)
+        return;
+
+    spin_lock_irq(&pDevice->lock);
+
+    switch ( pDevice->eCommandState ) {
+
+        case WLAN_CMD_SCAN_START:
+
+		pDevice->byReAssocCount = 0;
+            if (pDevice->bRadioOff == TRUE) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+
+            if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+
+            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyScanSSID;
+
+            if (pMgmt->uScanChannel == 0 ) {
+                pMgmt->uScanChannel = pDevice->byMinChannel;
+            }
+            if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
+                pMgmt->eScanState = WMAC_NO_SCANNING;
+
+                if (pDevice->byBBType != pDevice->byScanBBType) {
+                    pDevice->byBBType = pDevice->byScanBBType;
+                    CARDvSetBSSMode(pDevice);
+                }
+
+                if (pDevice->bUpdateBBVGA) {
+                    BBvSetShortSlotTime(pDevice);
+                    BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+                    BBvUpdatePreEDThreshold(pDevice, FALSE);
+                }
+                // Set channel back
+                vAdHocBeaconRestart(pDevice);
+                // Set channel back
+                CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+                // Set Filter
+                if (pMgmt->bCurrBSSIDFilterOn) {
+                    MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+                    pDevice->byRxMode |= RCR_BSSID;
+                }
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+                pDevice->bStopDataPkt = FALSE;
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+
+            } else {
+                if (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel)) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel);
+                    s_bCommandComplete(pDevice);
+                    spin_unlock_irq(&pDevice->lock);
+                    return;
+                }
+                if (pMgmt->uScanChannel == pDevice->byMinChannel) {
+                   // pMgmt->eScanType = WMAC_SCAN_ACTIVE;          //mike mark
+                    pMgmt->abyScanBSSID[0] = 0xFF;
+                    pMgmt->abyScanBSSID[1] = 0xFF;
+                    pMgmt->abyScanBSSID[2] = 0xFF;
+                    pMgmt->abyScanBSSID[3] = 0xFF;
+                    pMgmt->abyScanBSSID[4] = 0xFF;
+                    pMgmt->abyScanBSSID[5] = 0xFF;
+                    pItemSSID->byElementID = WLAN_EID_SSID;
+                    // clear bssid list
+                    // BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+                    pMgmt->eScanState = WMAC_IS_SCANNING;
+                    pDevice->byScanBBType = pDevice->byBBType;  //lucas
+                    pDevice->bStopDataPkt = TRUE;
+                    // Turn off RCR_BSSID filter everytime
+                    MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_BSSID);
+                    pDevice->byRxMode &= ~RCR_BSSID;
+
+                }
+                //lucas
+                vAdHocBeaconStop(pDevice);
+                if ((pDevice->byBBType != BB_TYPE_11A) && (pMgmt->uScanChannel > CB_MAX_CHANNEL_24G)) {
+                    pDevice->byBBType = BB_TYPE_11A;
+                    CARDvSetBSSMode(pDevice);
+                }
+                else if ((pDevice->byBBType == BB_TYPE_11A) && (pMgmt->uScanChannel <= CB_MAX_CHANNEL_24G)) {
+                    pDevice->byBBType = BB_TYPE_11G;
+                    CARDvSetBSSMode(pDevice);
+                }
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning....  channel: [%d]\n", pMgmt->uScanChannel);
+                // Set channel
+                CARDbSetMediaChannel(pDevice, pMgmt->uScanChannel);
+                // Set Baseband to be more sensitive.
+
+                if (pDevice->bUpdateBBVGA) {
+                    BBvSetShortSlotTime(pDevice);
+                    BBvSetVGAGainOffset(pDevice, pDevice->abyBBVGA[0]);
+                    BBvUpdatePreEDThreshold(pDevice, TRUE);
+                }
+                pMgmt->uScanChannel++;
+
+                while (!ChannelValid(pDevice->byZoneType, pMgmt->uScanChannel) &&
+                        pMgmt->uScanChannel <= pDevice->byMaxChannel ){
+                    pMgmt->uScanChannel++;
+                }
+
+                if (pMgmt->uScanChannel > pDevice->byMaxChannel) {
+                    // Set Baseband to be not sensitive and rescan
+                    pDevice->eCommandState = WLAN_CMD_SCAN_END;
+
+                }
+                if ((pMgmt->b11hEnable == FALSE) ||
+                    (pMgmt->uScanChannel < CB_MAX_CHANNEL_24G)) {
+                    s_vProbeChannel(pDevice);
+                    spin_unlock_irq(&pDevice->lock);
+		     vCommandTimerWait((HANDLE)pDevice, 100);
+                    return;
+                } else {
+                    spin_unlock_irq(&pDevice->lock);
+                    vCommandTimerWait((HANDLE)pDevice, WCMD_PASSIVE_SCAN_TIME);
+                    return;
+                }
+
+            }
+
+            break;
+
+        case WLAN_CMD_SCAN_END:
+
+            // Set Baseband's sensitivity back.
+            if (pDevice->byBBType != pDevice->byScanBBType) {
+                pDevice->byBBType = pDevice->byScanBBType;
+                CARDvSetBSSMode(pDevice);
+            }
+
+            if (pDevice->bUpdateBBVGA) {
+                BBvSetShortSlotTime(pDevice);
+                BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+                BBvUpdatePreEDThreshold(pDevice, FALSE);
+            }
+
+            // Set channel back
+            vAdHocBeaconRestart(pDevice);
+            // Set channel back
+            CARDbSetMediaChannel(pDevice, pMgmt->uCurrChannel);
+            // Set Filter
+            if (pMgmt->bCurrBSSIDFilterOn) {
+                MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+                pDevice->byRxMode |= RCR_BSSID;
+            }
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", pMgmt->uCurrChannel);
+            pMgmt->eScanState = WMAC_NO_SCANNING;
+            pDevice->bStopDataPkt = FALSE;
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	if(pMgmt->eScanType == WMAC_SCAN_PASSIVE)
+		{
+			//send scan event to wpa_Supplicant
+				union iwreq_data wrqu;
+				PRINT_K("wireless_send_event--->SIOCGIWSCAN(scan done)\n");
+				memset(&wrqu, 0, sizeof(wrqu));
+				wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL);
+			}
+#endif
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_DISASSOCIATE_START :
+		pDevice->byReAssocCount = 0;
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+                (pMgmt->eCurrState != WMAC_STATE_ASSOC)) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            } else {
+
+          #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+		      pDevice->bwextstep0 = FALSE;
+                        pDevice->bwextstep1 = FALSE;
+                        pDevice->bwextstep2 = FALSE;
+                        pDevice->bwextstep3 = FALSE;
+		   pDevice->bWPASuppWextEnabled = FALSE;
+	 #endif
+                   pDevice->fWPA_Authened = FALSE;
+
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n");
+                // reason = 8 : disassoc because sta has left
+                vMgrDisassocBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status);
+                pDevice->bLinkPass = FALSE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+                // unlock command busy
+                pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+                pItemSSID->len = 0;
+                memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                pMgmt->sNodeDBTable[0].bActive = FALSE;
+//                pDevice->bBeaconBufReady = FALSE;
+            }
+            netif_stop_queue(pDevice->dev);
+            if (pDevice->bNeedRadioOFF == TRUE)
+                CARDbRadioPowerOff(pDevice);
+            s_bCommandComplete(pDevice);
+            break;
+
+
+        case WLAN_CMD_SSID_START:
+
+		pDevice->byReAssocCount = 0;
+            if (pDevice->bRadioOff == TRUE) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+            }
+
+//20080131-03,<Add> by Mike Liu
+	#ifdef Adhoc_STA
+            memcpy(pMgmt->abyAdHocSSID,pMgmt->abyDesireSSID,
+                              ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN);
+	#endif
+            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+            pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: desire ssid = %s\n", pItemSSID->abySSID);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID);
+
+            if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n");
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSID->len =%d\n",pItemSSID->len);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" pItemSSIDCurr->len = %d\n",pItemSSIDCurr->len);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" desire ssid = %s\n", pItemSSID->abySSID);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" curr ssid = %s\n", pItemSSIDCurr->abySSID);
+            }
+
+            if ((pMgmt->eCurrState == WMAC_STATE_ASSOC) ||
+                ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)&& (pMgmt->eCurrState == WMAC_STATE_JOINTED))) {
+
+                if (pItemSSID->len == pItemSSIDCurr->len) {
+                    if (memcmp(pItemSSID->abySSID, pItemSSIDCurr->abySSID, pItemSSID->len) == 0) {
+                        s_bCommandComplete(pDevice);
+                        spin_unlock_irq(&pDevice->lock);
+                        return;
+                    }
+                }
+                netif_stop_queue(pDevice->dev);
+                pDevice->bLinkPass = FALSE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+            }
+            // set initial state
+            pMgmt->eCurrState = WMAC_STATE_IDLE;
+            pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+            PSvDisablePowerSaving((HANDLE)pDevice);
+            BSSvClearNodeDBTable(pDevice, 0);
+            vMgrJoinBSSBegin((HANDLE)pDevice, &Status);
+            // if Infra mode
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_JOINTED)) {
+                // Call mgr to begin the deauthentication
+                // reason = (3) beacuse sta has left ESS
+                if (pMgmt->eCurrState>= WMAC_STATE_AUTH) {
+                    vMgrDeAuthenBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (3), &Status);
+                }
+                // Call mgr to begin the authentication
+                vMgrAuthenBeginSta((HANDLE)pDevice, pMgmt, &Status);
+                if (Status == CMD_STATUS_SUCCESS) {
+		   pDevice->byLinkWaitCount = 0;
+                    pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT;
+                    vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT);
+                    spin_unlock_irq(&pDevice->lock);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n");
+                    return;
+                }
+            }
+            // if Adhoc mode
+            else if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+                if (pMgmt->eCurrState == WMAC_STATE_JOINTED) {
+                    if (netif_queue_stopped(pDevice->dev)){
+                        netif_wake_queue(pDevice->dev);
+                    }
+                    pDevice->bLinkPass = TRUE;
+                    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+                    pMgmt->sNodeDBTable[0].bActive = TRUE;
+                    pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+                }
+                else {
+                    // start own IBSS
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CreateOwn IBSS by CurrMode = IBSS_STA \n");
+                    vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
+                    if (Status != CMD_STATUS_SUCCESS){
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
+                    };
+                    BSSvAddMulticastNode(pDevice);
+                }
+                s_bClearBSSID_SCAN(pDevice);
+            }
+            // if SSID not found
+            else if (pMgmt->eCurrMode == WMAC_MODE_STANDBY) {
+                if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA ||
+                    pMgmt->eConfigMode == WMAC_CONFIG_AUTO) {
+                    // start own IBSS
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CreateOwn IBSS by CurrMode = STANDBY \n");
+                    vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
+                    if (Status != CMD_STATUS_SUCCESS){
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n");
+                    };
+                    BSSvAddMulticastNode(pDevice);
+                    s_bClearBSSID_SCAN(pDevice);
+/*
+                    pDevice->bLinkPass = TRUE;
+                    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+                    if (netif_queue_stopped(pDevice->dev)){
+                        netif_wake_queue(pDevice->dev);
+                    }
+                    s_bClearBSSID_SCAN(pDevice);
+*/
+                }
+                else {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n");
+                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                        {
+                  	union iwreq_data  wrqu;
+                  	memset(&wrqu, 0, sizeof (wrqu));
+                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                  	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n");
+                  	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+                }
+            }
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_AUTHENTICATE_WAIT :
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_AUTHENTICATE_WAIT\n");
+            if (pMgmt->eCurrState == WMAC_STATE_AUTH) {
+		pDevice->byLinkWaitCount = 0;
+                // Call mgr to begin the association
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_AUTH\n");
+                vMgrAssocBeginSta((HANDLE)pDevice, pMgmt, &Status);
+                if (Status == CMD_STATUS_SUCCESS) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState = WLAN_ASSOCIATE_WAIT\n");
+		  pDevice->byLinkWaitCount = 0;
+                    pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
+                    vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT);
+                    spin_unlock_irq(&pDevice->lock);
+                    return;
+                }
+            }
+	   else if(pMgmt->eCurrState < WMAC_STATE_AUTHPENDING) {
+               printk("WLAN_AUTHENTICATE_WAIT:Authen Fail???\n");
+	   }
+	   else  if(pDevice->byLinkWaitCount <= 4){    //mike add:wait another 2 sec if authenticated_frame delay!
+                pDevice->byLinkWaitCount ++;
+	       printk("WLAN_AUTHENTICATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount);
+	       spin_unlock_irq(&pDevice->lock);
+	       vCommandTimerWait((HANDLE)pDevice, AUTHENTICATE_TIMEOUT/2);
+	       return;
+	   }
+	          pDevice->byLinkWaitCount = 0;
+		 #if 0
+                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                        {
+                  	union iwreq_data  wrqu;
+                  	memset(&wrqu, 0, sizeof (wrqu));
+                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                  	printk("wireless_send_event--->SIOCGIWAP(disassociated:AUTHENTICATE_WAIT_timeout)\n");
+                  	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+	         #endif
+
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_ASSOCIATE_WAIT :
+            if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCurrState == WMAC_STATE_ASSOC\n");
+                if (pDevice->ePSMode != WMAC_POWER_CAM) {
+                    PSvEnablePowerSaving((HANDLE)pDevice, pMgmt->wListenInterval);
+                }
+/*
+                if (pMgmt->eAuthenMode >= WMAC_AUTH_WPA) {
+                    KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
+                }
+*/
+                pDevice->byLinkWaitCount = 0;
+                pDevice->byReAssocCount = 0;
+                pDevice->bLinkPass = TRUE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+                s_bClearBSSID_SCAN(pDevice);
+
+                if (netif_queue_stopped(pDevice->dev)){
+                    netif_wake_queue(pDevice->dev);
+                }
+
+	//2007-0115-07<Add>by MikeLiu
+	     #ifdef TxInSleep
+		 if(pDevice->IsTxDataTrigger != FALSE)   {    //TxDataTimer is not triggered at the first time
+                     // printk("Re-initial TxDataTimer****\n");
+		    del_timer(&pDevice->sTimerTxData);
+                      init_timer(&pDevice->sTimerTxData);
+                      pDevice->sTimerTxData.data = (ULONG)pDevice;
+                      pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
+                      pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+                      pDevice->fTxDataInSleep = FALSE;
+                      pDevice->nTxDataTimeCout = 0;
+		 }
+		 else {
+		   // printk("mike:-->First time triger TimerTxData InSleep\n");
+		 }
+		pDevice->IsTxDataTrigger = TRUE;
+                add_timer(&pDevice->sTimerTxData);
+             #endif
+
+            }
+	   else if(pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) {
+               printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n");
+	   }
+	   else  if(pDevice->byLinkWaitCount <= 4){    //mike add:wait another 2 sec if associated_frame delay!
+                pDevice->byLinkWaitCount ++;
+	       printk("WLAN_ASSOCIATE_WAIT:wait %d times!!\n",pDevice->byLinkWaitCount);
+	       spin_unlock_irq(&pDevice->lock);
+	       vCommandTimerWait((HANDLE)pDevice, ASSOCIATE_TIMEOUT/2);
+	       return;
+	   }
+	          pDevice->byLinkWaitCount = 0;
+		#if 0
+                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                        {
+                  	union iwreq_data  wrqu;
+                  	memset(&wrqu, 0, sizeof (wrqu));
+                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                  	printk("wireless_send_event--->SIOCGIWAP(disassociated:ASSOCIATE_WAIT_timeout)\n");
+                  	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+		#endif
+
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_AP_MODE_START :
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_AP_MODE_START\n");
+
+            if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+                del_timer(&pMgmt->sTimerSecondCallback);
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                pDevice->bLinkPass = FALSE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+                if (pDevice->bEnableHostWEP == TRUE)
+                    BSSvClearNodeDBTable(pDevice, 1);
+                else
+                    BSSvClearNodeDBTable(pDevice, 0);
+                pDevice->uAssocCount = 0;
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                pDevice->bFixRate = FALSE;
+
+                vMgrCreateOwnIBSS((HANDLE)pDevice, &Status);
+                if (Status != CMD_STATUS_SUCCESS){
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n");
+                };
+                // alway turn off unicast bit
+                MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST);
+                pDevice->byRxMode &= ~RCR_UNICAST;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode );
+                BSSvAddMulticastNode(pDevice);
+                if (netif_queue_stopped(pDevice->dev)){
+                    netif_wake_queue(pDevice->dev);
+                }
+                pDevice->bLinkPass = TRUE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+                add_timer(&pMgmt->sTimerSecondCallback);
+            }
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_TX_PSPACKET_START :
+            // DTIM Multicast tx
+            if (pMgmt->sNodeDBTable[0].bRxPSPoll) {
+                while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[0].sTxPSQueue)) != NULL) {
+                    if (skb_queue_empty(&pMgmt->sNodeDBTable[0].sTxPSQueue)) {
+                        pMgmt->abyPSTxMap[0] &= ~byMask[0];
+                        pDevice->bMoreData = FALSE;
+                    }
+                    else {
+                        pDevice->bMoreData = TRUE;
+                    }
+
+                    if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) {
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail \n");
+                    }
+
+                    pMgmt->sNodeDBTable[0].wEnQueueCnt--;
+                }
+            };
+
+            // PS nodes tx
+            for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
+                if (pMgmt->sNodeDBTable[ii].bActive &&
+                    pMgmt->sNodeDBTable[ii].bRxPSPoll) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n",
+                               ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt);
+                    while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) {
+                        if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
+                            // clear tx map
+                            pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
+                                    ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
+                            pDevice->bMoreData = FALSE;
+                        }
+                        else {
+                            pDevice->bMoreData = TRUE;
+                        }
+
+                        if (nsDMA_tx_packet(pDevice, TYPE_AC0DMA, skb) != 0) {
+                            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail \n");
+                        }
+
+                        pMgmt->sNodeDBTable[ii].wEnQueueCnt--;
+                        // check if sta ps enable, wait next pspoll
+                        // if sta ps disable, send all pending buffers.
+                        if (pMgmt->sNodeDBTable[ii].bPSEnable)
+                            break;
+                    }
+                    if (skb_queue_empty(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) {
+                        // clear tx map
+                        pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &=
+                                    ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7];
+                        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear \n", ii);
+                    }
+                    pMgmt->sNodeDBTable[ii].bRxPSPoll = FALSE;
+                }
+            }
+
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_RADIO_START:
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState == WLAN_CMD_RADIO_START\n");
+       //     if (pDevice->bRadioCmd == TRUE)
+       //         CARDbRadioPowerOn(pDevice);
+       //     else
+       //         CARDbRadioPowerOff(pDevice);
+       //2008-09-09<Add> BY Mike:Hot Key for Radio On/Off
+       {
+        NTSTATUS        ntStatus = STATUS_SUCCESS;
+        BYTE            byTmp;
+
+        ntStatus = CONTROLnsRequestIn(pDevice,
+                                    MESSAGE_TYPE_READ,
+                                    MAC_REG_GPIOCTL1,
+                                    MESSAGE_REQUEST_MACREG,
+                                    1,
+                                    &byTmp);
+
+        if ( ntStatus != STATUS_SUCCESS ) {
+                s_bCommandComplete(pDevice);
+                spin_unlock_irq(&pDevice->lock);
+                return;
+        }
+        if ( (byTmp & GPIO3_DATA) == 0 ) {
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_OFF........................\n");
+                // Old commands are useless.
+                // empty command Q
+	       pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+                pDevice->uCmdDequeueIdx = 0;
+                pDevice->uCmdEnqueueIdx = 0;
+                //0415pDevice->bCmdRunning = FALSE;
+                pDevice->bCmdClear = TRUE;
+                pDevice->bStopTx0Pkt = FALSE;
+                pDevice->bStopDataPkt = TRUE;
+
+                pDevice->byKeyIndex = 0;
+                pDevice->bTransmitKey = FALSE;
+	    spin_unlock_irq(&pDevice->lock);
+	    KeyvInitTable(pDevice,&pDevice->sKey);
+	    spin_lock_irq(&pDevice->lock);
+	       pMgmt->byCSSPK = KEY_CTL_NONE;
+                pMgmt->byCSSGK = KEY_CTL_NONE;
+
+	  if (pDevice->bLinkPass == TRUE) {
+                // reason = 8 : disassoc because sta has left
+                       vMgrDisassocBeginSta((HANDLE)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status);
+                       pDevice->bLinkPass = FALSE;
+                // unlock command busy
+                        pMgmt->eCurrState = WMAC_STATE_IDLE;
+                        pMgmt->sNodeDBTable[0].bActive = FALSE;
+                     #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+                    // if(pDevice->bWPASuppWextEnabled == TRUE)
+                        {
+                  	union iwreq_data  wrqu;
+                  	memset(&wrqu, 0, sizeof (wrqu));
+                          wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                  	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+                  	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+                       }
+                    #endif
+	  	}
+	       #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	               pDevice->bwextstep0 = FALSE;
+                        pDevice->bwextstep1 = FALSE;
+                        pDevice->bwextstep2 = FALSE;
+                        pDevice->bwextstep3 = FALSE;
+		      pDevice->bWPASuppWextEnabled = FALSE;
+		#endif
+	                  //clear current SSID
+                  pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+                  pItemSSID->len = 0;
+                  memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+                //clear dessire SSID
+                pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+                pItemSSID->len = 0;
+                memset(pItemSSID->abySSID, 0, WLAN_SSID_MAXLEN);
+
+	    netif_stop_queue(pDevice->dev);
+	    CARDbRadioPowerOff(pDevice);
+             MACvRegBitsOn(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+	    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_OFF);
+	    pDevice->bHWRadioOff = TRUE;
+        } else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_RADIO_START_ON........................\n");
+            pDevice->bHWRadioOff = FALSE;
+                CARDbRadioPowerOn(pDevice);
+            MACvRegBitsOff(pDevice,MAC_REG_GPIOCTL1,GPIO3_INTMD);
+            ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_ON);
+        }
+      }
+
+            s_bCommandComplete(pDevice);
+            break;
+
+
+        case WLAN_CMD_CHANGE_BBSENSITIVITY_START:
+
+            pDevice->bStopDataPkt = TRUE;
+            pDevice->byBBVGACurrent = pDevice->byBBVGANew;
+            BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change sensitivity pDevice->byBBVGACurrent = %x\n", pDevice->byBBVGACurrent);
+            pDevice->bStopDataPkt = FALSE;
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_TBTT_WAKEUP_START:
+            PSbIsNextTBTTWakeUp(pDevice);
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_BECON_SEND_START:
+            bMgrPrepareBeaconToSend(pDevice, pMgmt);
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_SETPOWER_START:
+
+            RFbSetPower(pDevice, pDevice->wCurrentRate, pMgmt->uCurrChannel);
+
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_CHANGE_ANTENNA_START:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Change from Antenna%d to", (int)pDevice->dwRxAntennaSel);
+            if ( pDevice->dwRxAntennaSel == 0) {
+                pDevice->dwRxAntennaSel=1;
+                if (pDevice->bTxRxAntInv == TRUE)
+                    BBvSetAntennaMode(pDevice, ANT_RXA);
+                else
+                    BBvSetAntennaMode(pDevice, ANT_RXB);
+            } else {
+                pDevice->dwRxAntennaSel=0;
+                if (pDevice->bTxRxAntInv == TRUE)
+                    BBvSetAntennaMode(pDevice, ANT_RXB);
+                else
+                    BBvSetAntennaMode(pDevice, ANT_RXA);
+            }
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_REMOVE_ALLKEY_START:
+            KeybRemoveAllKey(pDevice, &(pDevice->sKey), pDevice->abyBSSID);
+            s_bCommandComplete(pDevice);
+            break;
+
+
+        case WLAN_CMD_MAC_DISPOWERSAVING_START:
+            ControlvReadByte (pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData);
+            if ( (byData & PSCTL_PS) != 0 ) {
+                // disable power saving hw function
+                CONTROLnsRequestOut(pDevice,
+                                MESSAGE_TYPE_DISABLE_PS,
+                                0,
+                                0,
+                                0,
+                                NULL
+                                );
+            }
+            s_bCommandComplete(pDevice);
+            break;
+
+        case WLAN_CMD_11H_CHSW_START:
+            CARDbSetMediaChannel(pDevice, pDevice->byNewChannel);
+            pDevice->bChannelSwitch = FALSE;
+            pMgmt->uCurrChannel = pDevice->byNewChannel;
+            pDevice->bStopDataPkt = FALSE;
+            s_bCommandComplete(pDevice);
+            break;
+
+        default:
+            s_bCommandComplete(pDevice);
+            break;
+    } //switch
+
+    spin_unlock_irq(&pDevice->lock);
+    return;
+}
+
+
+static
+BOOL
+s_bCommandComplete (
+    PSDevice pDevice
+    )
+{
+    PWLAN_IE_SSID pSSID;
+    BOOL          bRadioCmd = FALSE;
+    //WORD          wDeAuthenReason = 0;
+    BOOL          bForceSCAN = TRUE;
+    PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
+
+
+    pDevice->eCommandState = WLAN_CMD_IDLE;
+    if (pDevice->cbFreeCmdQueue == CMD_Q_SIZE) {
+        //Command Queue Empty
+        pDevice->bCmdRunning = FALSE;
+        return TRUE;
+    }
+    else {
+        pDevice->eCommand = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].eCmd;
+        pSSID = (PWLAN_IE_SSID)pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].abyCmdDesireSSID;
+        bRadioCmd = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bRadioCmd;
+        bForceSCAN = pDevice->eCmdQueue[pDevice->uCmdDequeueIdx].bForceSCAN;
+        ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdDequeueIdx, CMD_Q_SIZE);
+        pDevice->cbFreeCmdQueue++;
+        pDevice->bCmdRunning = TRUE;
+        switch ( pDevice->eCommand ) {
+            case WLAN_CMD_BSSID_SCAN:
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_BSSID_SCAN\n");
+                pDevice->eCommandState = WLAN_CMD_SCAN_START;
+                pMgmt->uScanChannel = 0;
+                if (pSSID->len != 0) {
+                    memcpy(pMgmt->abyScanSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                } else {
+                    memset(pMgmt->abyScanSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                }
+/*
+                if ((bForceSCAN == FALSE) && (pDevice->bLinkPass == TRUE)) {
+                    if ((pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) &&
+                        ( !memcmp(pSSID->abySSID, ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID, pSSID->len))) {
+                        pDevice->eCommandState = WLAN_CMD_IDLE;
+                    }
+                }
+*/
+                break;
+            case WLAN_CMD_SSID:
+                pDevice->eCommandState = WLAN_CMD_SSID_START;
+                if (pSSID->len > WLAN_SSID_MAXLEN)
+                    pSSID->len = WLAN_SSID_MAXLEN;
+                if (pSSID->len != 0)
+                    memcpy(pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"eCommandState= WLAN_CMD_SSID_START\n");
+                break;
+            case WLAN_CMD_DISASSOCIATE:
+                pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START;
+                break;
+            case WLAN_CMD_RX_PSPOLL:
+                pDevice->eCommandState = WLAN_CMD_TX_PSPACKET_START;
+                break;
+            case WLAN_CMD_RUN_AP:
+                pDevice->eCommandState = WLAN_CMD_AP_MODE_START;
+                break;
+            case WLAN_CMD_RADIO:
+                pDevice->eCommandState = WLAN_CMD_RADIO_START;
+                pDevice->bRadioCmd = bRadioCmd;
+                break;
+            case WLAN_CMD_CHANGE_BBSENSITIVITY:
+                pDevice->eCommandState = WLAN_CMD_CHANGE_BBSENSITIVITY_START;
+                break;
+
+            case WLAN_CMD_TBTT_WAKEUP:
+                pDevice->eCommandState = WLAN_CMD_TBTT_WAKEUP_START;
+                break;
+
+            case WLAN_CMD_BECON_SEND:
+                pDevice->eCommandState = WLAN_CMD_BECON_SEND_START;
+                break;
+
+            case WLAN_CMD_SETPOWER:
+                pDevice->eCommandState = WLAN_CMD_SETPOWER_START;
+                break;
+
+            case WLAN_CMD_CHANGE_ANTENNA:
+                pDevice->eCommandState = WLAN_CMD_CHANGE_ANTENNA_START;
+                break;
+
+            case WLAN_CMD_REMOVE_ALLKEY:
+                pDevice->eCommandState = WLAN_CMD_REMOVE_ALLKEY_START;
+                break;
+
+            case WLAN_CMD_MAC_DISPOWERSAVING:
+                pDevice->eCommandState = WLAN_CMD_MAC_DISPOWERSAVING_START;
+                break;
+
+            case WLAN_CMD_11H_CHSW:
+                pDevice->eCommandState = WLAN_CMD_11H_CHSW_START;
+                break;
+
+            default:
+                break;
+
+        }
+
+        vCommandTimerWait((HANDLE)pDevice, 0);
+    }
+
+    return TRUE;
+}
+
+BOOL bScheduleCommand (
+    IN HANDLE hDeviceContext,
+    IN CMD_CODE    eCommand,
+    IN PBYTE       pbyItem0
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+
+    if (pDevice->cbFreeCmdQueue == 0) {
+        return (FALSE);
+    }
+    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].eCmd = eCommand;
+    pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = TRUE;
+    memset(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID, 0 , WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+    if (pbyItem0 != NULL) {
+        switch (eCommand) {
+            case WLAN_CMD_BSSID_SCAN:
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bForceSCAN = FALSE;
+                memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                         pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                break;
+
+            case WLAN_CMD_SSID:
+                memcpy(pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].abyCmdDesireSSID,
+                         pbyItem0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+                break;
+
+            case WLAN_CMD_DISASSOCIATE:
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bNeedRadioOFF = *((int *)pbyItem0);
+                break;
+/*
+            case WLAN_CMD_DEAUTH:
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].wDeAuthenReason = *((PWORD)pbyItem0);
+                break;
+*/
+
+            case WLAN_CMD_RADIO:
+                pDevice->eCmdQueue[pDevice->uCmdEnqueueIdx].bRadioCmd = *((int *)pbyItem0);
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    ADD_ONE_WITH_WRAP_AROUND(pDevice->uCmdEnqueueIdx, CMD_Q_SIZE);
+    pDevice->cbFreeCmdQueue--;
+
+    if (pDevice->bCmdRunning == FALSE) {
+        s_bCommandComplete(pDevice);
+    }
+    else {
+    }
+    return (TRUE);
+
+}
+
+/*
+ * Description:
+ *      Clear BSSID_SCAN cmd in CMD Queue
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext  - Pointer to the adapter
+ *      eCommand        - Command
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if success; otherwise FALSE
+ *
+ */
+static
+BOOL s_bClearBSSID_SCAN (
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+    UINT            uCmdDequeueIdx = pDevice->uCmdDequeueIdx;
+    UINT            ii;
+
+    if ((pDevice->cbFreeCmdQueue < CMD_Q_SIZE) && (uCmdDequeueIdx != pDevice->uCmdEnqueueIdx)) {
+        for (ii = 0; ii < (CMD_Q_SIZE - pDevice->cbFreeCmdQueue); ii ++) {
+            if (pDevice->eCmdQueue[uCmdDequeueIdx].eCmd == WLAN_CMD_BSSID_SCAN)
+                pDevice->eCmdQueue[uCmdDequeueIdx].eCmd = WLAN_CMD_IDLE;
+            ADD_ONE_WITH_WRAP_AROUND(uCmdDequeueIdx, CMD_Q_SIZE);
+            if (uCmdDequeueIdx == pDevice->uCmdEnqueueIdx)
+                break;
+        }
+    }
+    return TRUE;
+}
+
+
+//mike add:reset command timer
+VOID
+vResetCommandTimer(
+    IN HANDLE      hDeviceContext
+    )
+{
+  PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+  //delete timer
+      del_timer(&pDevice->sTimerCommand);
+  //init timer
+      init_timer(&pDevice->sTimerCommand);
+    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
+    pDevice->sTimerCommand.expires = RUN_AT(HZ);
+    pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+    pDevice->uCmdDequeueIdx = 0;
+    pDevice->uCmdEnqueueIdx = 0;
+    pDevice->eCommandState = WLAN_CMD_IDLE;
+    pDevice->bCmdRunning = FALSE;
+    pDevice->bCmdClear = FALSE;
+}
+
+//2007-0115-08<Add>by MikeLiu
+#ifdef TxInSleep
+VOID
+BSSvSecondTxData(
+    IN  HANDLE      hDeviceContext
+    )
+{
+  PSDevice        pDevice = (PSDevice)hDeviceContext;
+  PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
+
+  pDevice->nTxDataTimeCout++;
+
+  if(pDevice->nTxDataTimeCout<4)     //don't tx data if timer less than 40s
+    {
+     // printk("mike:%s-->no data Tx not exceed the desired Time as %d\n",__FUNCTION__,
+	//  	(int)pDevice->nTxDataTimeCout);
+     pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+     add_timer(&pDevice->sTimerTxData);
+      return;
+    }
+
+  spin_lock_irq(&pDevice->lock);
+  //is wap_supplicant running sucessful OR only open && sharekey mode!
+  #if 1
+  if(((pDevice->bLinkPass ==TRUE)&&(pMgmt->eAuthenMode < WMAC_AUTH_WPA)) ||  //open && sharekey linking
+      (pDevice->fWPA_Authened == TRUE)) {   //wpa linking
+ #else
+  if(pDevice->bLinkPass ==TRUE) {
+ #endif
+        //   printk("mike:%s-->InSleep Tx Data Procedure\n",__FUNCTION__);
+	  pDevice->fTxDataInSleep = TRUE;
+	  PSbSendNullPacket(pDevice);      //send null packet
+	  pDevice->fTxDataInSleep = FALSE;
+  	}
+  spin_unlock_irq(&pDevice->lock);
+
+  pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+  add_timer(&pDevice->sTimerTxData);
+  return;
+}
+#endif
+
diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h
new file mode 100644
index 0000000..90d672b
--- /dev/null
+++ b/drivers/staging/vt6656/wcmd.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: wcmd.h
+ *
+ * Purpose: Handles the management command interface functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ */
+
+#ifndef __WCMD_H__
+#define __WCMD_H__
+
+#include "ttype.h"
+#include "80211hdr.h"
+#include "80211mgr.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+
+#define AUTHENTICATE_TIMEOUT   1000 //ms
+#define ASSOCIATE_TIMEOUT      1000 //ms
+
+
+// Command code
+typedef enum tagCMD_CODE {
+    WLAN_CMD_BSSID_SCAN,
+    WLAN_CMD_SSID,
+    WLAN_CMD_DISASSOCIATE,
+    WLAN_CMD_DEAUTH,
+    WLAN_CMD_RX_PSPOLL,
+    WLAN_CMD_RADIO,
+    WLAN_CMD_CHANGE_BBSENSITIVITY,
+    WLAN_CMD_SETPOWER,
+    WLAN_CMD_TBTT_WAKEUP,
+    WLAN_CMD_BECON_SEND,
+    WLAN_CMD_CHANGE_ANTENNA,
+    WLAN_CMD_REMOVE_ALLKEY,
+    WLAN_CMD_MAC_DISPOWERSAVING,
+    WLAN_CMD_11H_CHSW,
+    WLAN_CMD_RUN_AP
+} CMD_CODE, *PCMD_CODE;
+
+#define CMD_Q_SIZE              32
+
+typedef enum tagCMD_STATUS {
+
+    CMD_STATUS_SUCCESS = 0,
+    CMD_STATUS_FAILURE,
+    CMD_STATUS_RESOURCES,
+    CMD_STATUS_TIMEOUT,
+    CMD_STATUS_PENDING
+
+} CMD_STATUS, *PCMD_STATUS;
+
+typedef struct tagCMD_ITEM {
+    CMD_CODE eCmd;
+    BYTE     abyCmdDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BOOL     bNeedRadioOFF;
+    BOOL     bRadioCmd;
+    BOOL     bForceSCAN;
+    WORD     wDeAuthenReason;
+} CMD_ITEM, *PCMD_ITEM;
+
+// Command state
+typedef enum tagCMD_STATE {
+    WLAN_CMD_SCAN_START,
+    WLAN_CMD_SCAN_END,
+    WLAN_CMD_DISASSOCIATE_START,
+    WLAN_CMD_DEAUTHEN_START,
+    WLAN_CMD_SSID_START,
+    WLAN_AUTHENTICATE_WAIT,
+    WLAN_ASSOCIATE_WAIT,
+    WLAN_DISASSOCIATE_WAIT,
+    WLAN_CMD_TX_PSPACKET_START,
+    WLAN_CMD_RADIO_START,
+    WLAN_CMD_CHANGE_BBSENSITIVITY_START,
+    WLAN_CMD_SETPOWER_START,
+    WLAN_CMD_AP_MODE_START,
+    WLAN_CMD_TBTT_WAKEUP_START,
+    WLAN_CMD_BECON_SEND_START,
+    WLAN_CMD_CHANGE_ANTENNA_START,
+    WLAN_CMD_REMOVE_ALLKEY_START,
+    WLAN_CMD_MAC_DISPOWERSAVING_START,
+    WLAN_CMD_11H_CHSW_START,
+    WLAN_CMD_IDLE
+} CMD_STATE, *PCMD_STATE;
+
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+VOID
+vResetCommandTimer(
+    IN HANDLE      hDeviceContext
+    );
+
+BOOL
+bScheduleCommand(
+    IN HANDLE      hDeviceContext,
+    IN CMD_CODE    eCommand,
+    IN PBYTE       pbyItem0
+    );
+
+VOID
+vRunCommand(
+    IN  HANDLE      hDeviceContext
+    );
+/*
+VOID
+WCMDvCommandThread(
+    PVOID Context
+    );
+*/
+
+//2007-0115-09<Add>by MikeLiu
+#ifdef TxInSleep
+VOID
+BSSvSecondTxData(
+    IN  HANDLE      hDeviceContext
+    );
+#endif
+
+#endif //__WCMD_H__
diff --git a/drivers/staging/vt6656/wctl.c b/drivers/staging/vt6656/wctl.c
new file mode 100644
index 0000000..40986da
--- /dev/null
+++ b/drivers/staging/vt6656/wctl.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: wctl.c
+ *
+ * Purpose: handle WMAC duplicate filter & defragment
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ * Functions:
+ *      WCTLbIsDuplicate - Test if duplicate packet
+ *      WCTLuSearchDFCB - Search DeFragment Control Database
+ *      WCTLuInsertDFCB - Insert DeFragment Control Database
+ *      WCTLbHandleFragment - Handle received fragment packet
+ *
+ * Revision History:
+ *
+ */
+
+#include "wctl.h"
+#include "device.h"
+#include "card.h"
+#include "tmacro.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+// static int          msglevel                =MSG_LEVEL_INFO;
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+
+/*
+ * Description:
+ *      Scan Rx cache.  Return TRUE if packet is duplicate, else
+ *      inserts in receive cache and returns FALSE.
+ *
+ * Parameters:
+ *  In:
+ *      pCache      - Receive packets history
+ *      pMACHeader  - 802.11 MAC Header of received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if packet duplicate; otherwise FALSE
+ *
+ */
+
+BOOL WCTLbIsDuplicate (PSCache pCache, PS802_11Header pMACHeader)
+{
+    UINT            uIndex;
+    UINT            ii;
+    PSCacheEntry    pCacheEntry;
+
+    if (IS_FC_RETRY(pMACHeader)) {
+
+        uIndex = pCache->uInPtr;
+        for (ii = 0; ii < DUPLICATE_RX_CACHE_LENGTH; ii++) {
+            pCacheEntry = &(pCache->asCacheEntry[uIndex]);
+            if ((pCacheEntry->wFmSequence == pMACHeader->wSeqCtl) &&
+                (IS_ETH_ADDRESS_EQUAL (&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]))) &&
+                (LOBYTE(pCacheEntry->wFrameCtl) == LOBYTE(pMACHeader->wFrameCtl))
+                ) {
+                /* Duplicate match */
+                return TRUE;
+            }
+            ADD_ONE_WITH_WRAP_AROUND(uIndex, DUPLICATE_RX_CACHE_LENGTH);
+        }
+    }
+    /* Not fount in cache - insert */
+    pCacheEntry = &pCache->asCacheEntry[pCache->uInPtr];
+    pCacheEntry->wFmSequence = pMACHeader->wSeqCtl;
+    memcpy(&(pCacheEntry->abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN);
+    pCacheEntry->wFrameCtl = pMACHeader->wFrameCtl;
+    ADD_ONE_WITH_WRAP_AROUND(pCache->uInPtr, DUPLICATE_RX_CACHE_LENGTH);
+    return FALSE;
+}
+
+/*
+ * Description:
+ *      Found if sequence number of received fragment packet in Defragment Database
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to adapter
+ *      pMACHeader  - 802.11 MAC Header of received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: index number in Defragment Database
+ *
+ */
+UINT WCTLuSearchDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
+{
+UINT ii;
+
+    for(ii=0;ii<pDevice->cbDFCB;ii++) {
+        if ((pDevice->sRxDFCB[ii].bInUse == TRUE) &&
+            (IS_ETH_ADDRESS_EQUAL (&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0])))
+            ) {
+            //
+            return(ii);
+        }
+    }
+    return(pDevice->cbDFCB);
+}
+
+
+/*
+ * Description:
+ *      Insert received fragment packet in Defragment Database
+ *
+ * Parameters:
+ *  In:
+ *      pDevice     - Pointer to adapter
+ *      pMACHeader  - 802.11 MAC Header of received packet
+ *  Out:
+ *      none
+ *
+ * Return Value: index number in Defragment Database
+ *
+ */
+UINT WCTLuInsertDFCB (PSDevice pDevice, PS802_11Header pMACHeader)
+{
+UINT ii;
+
+    if (pDevice->cbFreeDFCB == 0)
+        return(pDevice->cbDFCB);
+    for(ii=0;ii<pDevice->cbDFCB;ii++) {
+        if (pDevice->sRxDFCB[ii].bInUse == FALSE) {
+            pDevice->cbFreeDFCB--;
+            pDevice->sRxDFCB[ii].uLifetime = pDevice->dwMaxReceiveLifetime;
+            pDevice->sRxDFCB[ii].bInUse = TRUE;
+            pDevice->sRxDFCB[ii].wSequence = (pMACHeader->wSeqCtl >> 4);
+            pDevice->sRxDFCB[ii].wFragNum = (pMACHeader->wSeqCtl & 0x000F);
+            memcpy(&(pDevice->sRxDFCB[ii].abyAddr2[0]), &(pMACHeader->abyAddr2[0]), U_ETHER_ADDR_LEN);
+            return(ii);
+        }
+    }
+    return(pDevice->cbDFCB);
+}
+
+
+/*
+ * Description:
+ *      Handle received fragment packet
+ *
+ * Parameters:
+ *  In:
+ *      pDevice         - Pointer to adapter
+ *      pMACHeader      - 802.11 MAC Header of received packet
+ *      cbFrameLength   - Frame length
+ *      bWEP            - is WEP packet
+ *  Out:
+ *      none
+ *
+ * Return Value: TRUE if it is valid fragment packet and we have resource to defragment; otherwise FALSE
+ *
+ */
+BOOL WCTLbHandleFragment (PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV)
+{
+UINT            uHeaderSize;
+
+
+    if (bWEP == TRUE) {
+        uHeaderSize = 28;
+        if (bExtIV)
+        // ExtIV
+            uHeaderSize +=4;
+    }
+    else {
+        uHeaderSize = 24;
+    }
+
+    if (IS_FIRST_FRAGMENT_PKT(pMACHeader)) {
+        pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader);
+        if (pDevice->uCurrentDFCBIdx < pDevice->cbDFCB) {
+            // duplicate, we must flush previous DCB
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].uLifetime = pDevice->dwMaxReceiveLifetime;
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence = (pMACHeader->wSeqCtl >> 4);
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum = (pMACHeader->wSeqCtl & 0x000F);
+        }
+        else {
+            pDevice->uCurrentDFCBIdx = WCTLuInsertDFCB(pDevice, pMACHeader);
+            if (pDevice->uCurrentDFCBIdx == pDevice->cbDFCB) {
+                return(FALSE);
+            }
+        }
+        // reserve 8 byte to match MAC RX Buffer
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 8);
+//        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer = (PBYTE) (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].skb->data + 4);
+        memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, pMACHeader, cbFrameLength);
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength = cbFrameLength;
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += cbFrameLength;
+        pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
+        //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+        return(FALSE);
+    }
+    else {
+        pDevice->uCurrentDFCBIdx = WCTLuSearchDFCB(pDevice, pMACHeader);
+        if (pDevice->uCurrentDFCBIdx != pDevice->cbDFCB) {
+            if ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wSequence == (pMACHeader->wSeqCtl >> 4)) &&
+                (pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum == (pMACHeader->wSeqCtl & 0x000F)) &&
+                ((pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength + cbFrameLength - uHeaderSize) < 2346)) {
+
+                memcpy(pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer, ((PBYTE) (pMACHeader) + uHeaderSize), (cbFrameLength - uHeaderSize));
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].cbFrameLength += (cbFrameLength - uHeaderSize);
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].pbyRxBuffer += (cbFrameLength - uHeaderSize);
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].wFragNum++;
+                //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Second pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+            }
+            else {
+                // seq error or frag # error flush DFCB
+                pDevice->cbFreeDFCB++;
+                pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = FALSE;
+                return(FALSE);
+            }
+        }
+        else {
+            return(FALSE);
+        }
+        if (IS_LAST_FRAGMENT_PKT(pMACHeader)) {
+            //enq defragcontrolblock
+            pDevice->cbFreeDFCB++;
+            pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx].bInUse = FALSE;
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last pDevice->uCurrentDFCBIdx= %d\n", pDevice->uCurrentDFCBIdx);
+            return(TRUE);
+        }
+        return(FALSE);
+    }
+}
+
+
diff --git a/drivers/staging/vt6656/wctl.h b/drivers/staging/vt6656/wctl.h
new file mode 100644
index 0000000..a1ac479
--- /dev/null
+++ b/drivers/staging/vt6656/wctl.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: wctl.h
+ *
+ * Purpose:
+ *
+ * Author: Jerry Chen
+ *
+ * Date: Jun. 27, 2002
+ *
+ */
+
+#ifndef __WCTL_H__
+#define __WCTL_H__
+
+#include "ttype.h"
+#include "tether.h"
+#include "device.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define IS_TYPE_DATA(pMACHeader)                                                        \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_DATA)
+
+#define IS_TYPE_MGMT(pMACHeader)                                                        \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_MGMT)
+
+#define IS_TYPE_CONTROL(pMACHeader)                                                     \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_802_11_MASK) == TYPE_802_11_CTL)
+
+#define IS_FC_MOREDATA(pMACHeader)                                                      \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREDATA) == FC_MOREDATA)
+
+#define IS_FC_POWERMGT(pMACHeader)                                                      \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_POWERMGT) == FC_POWERMGT)
+
+#define IS_FC_RETRY(pMACHeader)                                                         \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_RETRY) == FC_RETRY)
+
+#define IS_FC_WEP(pMACHeader)                                                           \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_WEP) == FC_WEP)
+
+#ifdef __BIG_ENDIAN
+
+#define IS_FRAGMENT_PKT(pMACHeader)                                                     \
+    (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) |                  \
+     ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) != 0))
+
+#define IS_FIRST_FRAGMENT_PKT(pMACHeader)                                               \
+    ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x0F00) == 0)
+
+#else
+
+#define IS_FRAGMENT_PKT(pMACHeader)                                                     \
+    (((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) != 0) |                  \
+     ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) != 0))
+
+#define IS_FIRST_FRAGMENT_PKT(pMACHeader)                                               \
+    ((((PS802_11Header) pMACHeader)->wSeqCtl & 0x000F) == 0)
+
+#endif//#ifdef __BIG_ENDIAN
+
+#define IS_LAST_FRAGMENT_PKT(pMACHeader)                                                \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & FC_MOREFRAG) == 0)
+
+#define IS_CTL_PSPOLL(pMACHeader)                                                       \
+    ((((PS802_11Header) pMACHeader)->wFrameCtl & TYPE_SUBTYPE_MASK) == TYPE_CTL_PSPOLL)
+
+
+#define ADD_ONE_WITH_WRAP_AROUND(uVar, uModulo) {   \
+    if ((uVar) >= ((uModulo) - 1))                  \
+        (uVar) = 0;                                 \
+    else                                            \
+        (uVar)++;                                   \
+}
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+BOOL WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader);
+BOOL WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, UINT cbFrameLength, BOOL bWEP, BOOL bExtIV);
+UINT WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
+UINT WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader);
+
+#endif // __WCTL_H__
+
+
+
diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c
new file mode 100644
index 0000000..330aea6
--- /dev/null
+++ b/drivers/staging/vt6656/wmgr.c
@@ -0,0 +1,4949 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: wmgr.c
+ *
+ * Purpose: Handles the 802.11 management functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: May 8, 2002
+ *
+ * Functions:
+ *      nsMgrObjectInitial - Initialize Management Objet data structure
+ *      vMgrObjectReset - Reset Management Objet data structure
+ *      vMgrAssocBeginSta - Start associate function
+ *      vMgrReAssocBeginSta - Start reassociate function
+ *      vMgrDisassocBeginSta - Start disassociate function
+ *      s_vMgrRxAssocRequest - Handle Rcv associate_request
+ *      s_vMgrRxAssocResponse - Handle Rcv associate_response
+ *      vMrgAuthenBeginSta - Start authentication function
+ *      vMgrDeAuthenDeginSta - Start deauthentication function
+ *      s_vMgrRxAuthentication - Handle Rcv authentication
+ *      s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1
+ *      s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2
+ *      s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3
+ *      s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4
+ *      s_vMgrRxDisassociation - Handle Rcv disassociation
+ *      s_vMgrRxBeacon - Handle Rcv Beacon
+ *      vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS
+ *      vMgrJoinBSSBegin - Join BSS function
+ *      s_vMgrSynchBSS - Synch & adopt BSS parameters
+ *      s_MgrMakeBeacon - Create Baecon frame
+ *      s_MgrMakeProbeResponse - Create Probe Response frame
+ *      s_MgrMakeAssocRequest - Create Associate Request frame
+ *      s_MgrMakeReAssocRequest - Create ReAssociate Request frame
+ *      s_vMgrRxProbeResponse - Handle Rcv probe_response
+ *      s_vMrgRxProbeRequest - Handle Rcv probe_request
+ *      bMgrPrepareBeaconToSend - Prepare Beacon frame
+ *      s_vMgrLogStatus - Log 802.11 Status
+ *      vMgrRxManagePacket - Rcv management frame dispatch function
+ *      s_vMgrFormatTIM- Assember TIM field of beacon
+ *      vMgrTimerInit- Initial 1-sec and command call back funtions
+ *
+ * Revision History:
+ *
+ */
+
+#include "tmacro.h"
+#include "desc.h"
+#include "device.h"
+#include "card.h"
+#include "80211hdr.h"
+#include "80211mgr.h"
+#include "wmgr.h"
+#include "wcmd.h"
+#include "mac.h"
+#include "bssdb.h"
+#include "power.h"
+#include "datarate.h"
+#include "baseband.h"
+#include "rxtx.h"
+#include "wpa.h"
+#include "rf.h"
+#include "iowpa.h"
+#include "control.h"
+#include "rndis.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+
+
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+
+/*---------------------  Static Functions  --------------------------*/
+//2008-0730-01<Add>by MikeLiu
+static BOOL ChannelExceedZoneType(
+    IN PSDevice pDevice,
+    IN BYTE byCurrChannel
+    );
+
+// Association/diassociation functions
+static
+PSTxMgmtPacket
+s_MgrMakeAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+static
+VOID
+s_vMgrRxAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN UINT  uNodeIndex
+    );
+
+static
+PSTxMgmtPacket
+s_MgrMakeReAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+static
+VOID
+s_vMgrRxAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bReAssocType
+    );
+
+static
+VOID
+s_vMgrRxDisassociation(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+// Authentication/deauthen functions
+static
+VOID
+s_vMgrRxAuthenSequence_1(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthenSequence_2(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthenSequence_3(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthenSequence_4(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    );
+
+static
+VOID
+s_vMgrRxAuthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+static
+VOID
+s_vMgrRxDeauthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+// Scan functions
+// probe request/response functions
+static
+VOID
+s_vMgrRxProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+static
+VOID
+s_vMgrRxProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    );
+
+// beacon functions
+static
+VOID
+s_vMgrRxBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bInScan
+    );
+
+static
+VOID
+s_vMgrFormatTIM(
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_IE_TIM pTIM
+    );
+
+static
+PSTxMgmtPacket
+s_MgrMakeBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+
+// Association response
+static
+PSTxMgmtPacket
+s_MgrMakeAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+// ReAssociation response
+static
+PSTxMgmtPacket
+s_MgrMakeReAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    );
+
+// Probe response
+static
+PSTxMgmtPacket
+s_MgrMakeProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
+    IN BYTE byPHYType
+    );
+
+// received status
+static
+VOID
+s_vMgrLogStatus(
+    IN PSMgmtObject pMgmt,
+    IN WORD wStatus
+    );
+
+
+static
+VOID
+s_vMgrSynchBSS (
+    IN PSDevice      pDevice,
+    IN UINT          uBSSMode,
+    IN PKnownBSS     pCurr,
+    OUT PCMD_STATUS  pStatus
+    );
+
+
+static BOOL
+s_bCipherMatch (
+    IN PKnownBSS                        pBSSNode,
+    IN NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
+    OUT PBYTE                           pbyCCSPK,
+    OUT PBYTE                           pbyCCSGK
+    );
+
+ static VOID  Encyption_Rebuild(
+    IN PSDevice pDevice,
+    IN PKnownBSS pCurr
+ );
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+/*+
+ *
+ * Routine Description:
+ *    Allocates and initializes the Management object.
+ *
+ * Return Value:
+ *    Ndis_staus.
+ *
+-*/
+
+VOID
+vMgrObjectInit(
+    IN  HANDLE hDeviceContext
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    int ii;
+
+
+    pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
+    pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
+    pMgmt->uCurrChannel = pDevice->uChannel;
+    for(ii=0;ii<WLAN_BSSID_LEN;ii++) {
+        pMgmt->abyDesireBSSID[ii] = 0xFF;
+    }
+    pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+    //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1);
+    pMgmt->byCSSPK = KEY_CTL_NONE;
+    pMgmt->byCSSGK = KEY_CTL_NONE;
+    pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
+    BSSvClearBSSList((HANDLE)pDevice, FALSE);
+
+    init_timer(&pMgmt->sTimerSecondCallback);
+    pMgmt->sTimerSecondCallback.data = (ULONG)pDevice;
+    pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
+    pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
+
+    init_timer(&pDevice->sTimerCommand);
+    pDevice->sTimerCommand.data = (ULONG)pDevice;
+    pDevice->sTimerCommand.function = (TimerFunction)vRunCommand;
+    pDevice->sTimerCommand.expires = RUN_AT(HZ);
+
+//2007-0115-10<Add>by MikeLiu
+   #ifdef TxInSleep
+    init_timer(&pDevice->sTimerTxData);
+    pDevice->sTimerTxData.data = (ULONG)pDevice;
+    pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
+    pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
+    pDevice->fTxDataInSleep = FALSE;
+    pDevice->IsTxDataTrigger = FALSE;
+    pDevice->nTxDataTimeCout = 0;
+   #endif
+
+    pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
+    pDevice->uCmdDequeueIdx = 0;
+    pDevice->uCmdEnqueueIdx = 0;
+    pDevice->eCommandState = WLAN_CMD_IDLE;
+    pDevice->bCmdRunning = FALSE;
+    pDevice->bCmdClear = FALSE;
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station association procedure.  Namely, send an
+ *    association request frame to the AP.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+VOID
+vMgrAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice             pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket          pTxPacket;
+
+
+    pMgmt->wCurrCapInfo = 0;
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
+    if (pDevice->bEncryptionEnable) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+    // always allow receive short preamble
+    //if (pDevice->byPreambleType == 1) {
+    //    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    //}
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    if (pMgmt->wListenInterval == 0)
+        pMgmt->wListenInterval = 1;    // at least one.
+
+    // ERP Phy (802.11g) should support short preamble.
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+        if (pDevice->bShortSlotTime == TRUE)
+            pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
+
+    } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
+        if (pDevice->byPreambleType == 1) {
+            pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+        }
+    }
+    if (pMgmt->b11hEnable == TRUE)
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
+
+    // build an assocreq frame and send it
+    pTxPacket = s_MgrMakeAssocRequest
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->abyCurrBSSID,
+                  pMgmt->wCurrCapInfo,
+                  pMgmt->wListenInterval,
+                  (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if (pTxPacket != NULL ){
+        // send the frame
+        *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+        if (*pStatus == CMD_STATUS_PENDING) {
+            pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING;
+            *pStatus = CMD_STATUS_SUCCESS;
+        }
+    }
+    else
+        *pStatus = CMD_STATUS_RESOURCES;
+
+    return ;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station re-association procedure.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrReAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice             pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket          pTxPacket;
+
+
+
+    pMgmt->wCurrCapInfo = 0;
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
+    if (pDevice->bEncryptionEnable) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+
+    //if (pDevice->byPreambleType == 1) {
+    //    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    //}
+    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+
+    if (pMgmt->wListenInterval == 0)
+        pMgmt->wListenInterval = 1;    // at least one.
+
+
+    // ERP Phy (802.11g) should support short preamble.
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+      if (pDevice->bShortSlotTime == TRUE)
+          pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
+
+    } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
+        if (pDevice->byPreambleType == 1) {
+            pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+        }
+    }
+    if (pMgmt->b11hEnable == TRUE)
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
+
+
+    pTxPacket = s_MgrMakeReAssocRequest
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->abyCurrBSSID,
+                  pMgmt->wCurrCapInfo,
+                  pMgmt->wListenInterval,
+                  (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if (pTxPacket != NULL ){
+        // send the frame
+        *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+        if (*pStatus != CMD_STATUS_PENDING) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
+        }
+    }
+
+
+    return ;
+}
+
+/*+
+ *
+ * Routine Description:
+ *    Send an dis-association request frame to the AP.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDisassocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    IN  PBYTE  abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_DISASSOC    sFrame;
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+
+    // Setup the sFrame structure
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
+
+    // format fixed field frame structure
+    vMgrEncodeDisassociation(&sFrame);
+
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC)
+        ));
+
+    memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    // Set reason code
+    *(sFrame.pwReason) = cpu_to_le16(wReason);
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    // send the frame
+    *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+    if (*pStatus == CMD_STATUS_PENDING) {
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+        *pStatus = CMD_STATUS_SUCCESS;
+    };
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:(AP function)
+ *    Handle incoming station association request frames.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN UINT uNodeIndex
+    )
+{
+    WLAN_FR_ASSOCREQ    sFrame;
+    CMD_STATUS          Status;
+    PSTxMgmtPacket      pTxPacket;
+    WORD                wAssocStatus = 0;
+    WORD                wAssocAID = 0;
+    UINT                uRateLen = WLAN_RATES_MAXLEN;
+    BYTE                abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+
+
+    if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
+        return;
+    //  node index not found
+    if (!uNodeIndex)
+        return;
+
+    //check if node is authenticated
+    //decode the frame
+    memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ));
+    memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+
+    vMgrDecodeAssocRequest(&sFrame);
+
+    if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
+        pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
+        pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
+                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? TRUE : FALSE;
+        // Todo: check sta basic rate, if ap can't support, set status code
+        if (pDevice->byBBType == BB_TYPE_11B) {
+            uRateLen = WLAN_RATES_MAXLEN_11B;
+        }
+        abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+        abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                         (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                                         uRateLen);
+        abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
+        if (pDevice->byBBType == BB_TYPE_11G) {
+            abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
+                                                (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                                                uRateLen);
+        } else {
+            abyCurrExtSuppRates[1] = 0;
+        }
+
+
+        RATEvParseMaxRate((PVOID)pDevice,
+                           (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                           (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                           FALSE, // do not change our basic rate
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                          );
+
+        // set max tx rate
+        pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
+                pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+        // Todo: check sta preamble, if ap can't support, set status code
+        pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
+                WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
+                WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex;
+        wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
+        wAssocAID = (WORD)uNodeIndex;
+        // check if ERP support
+        if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
+           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+
+        if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
+            // B only STA join
+            pDevice->bProtectMode = TRUE;
+            pDevice->bNonERPPresent = TRUE;
+        }
+        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == FALSE) {
+            pDevice->bBarkerPreambleMd = TRUE;
+        }
+
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+                   sFrame.pHdr->sA3.abyAddr2[0],
+                   sFrame.pHdr->sA3.abyAddr2[1],
+                   sFrame.pHdr->sA3.abyAddr2[2],
+                   sFrame.pHdr->sA3.abyAddr2[3],
+                   sFrame.pHdr->sA3.abyAddr2[4],
+                   sFrame.pHdr->sA3.abyAddr2[5]
+                  ) ;
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+                   pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+    }
+
+
+    // assoc response reply..
+    pTxPacket = s_MgrMakeAssocResponse
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->wCurrCapInfo,
+                  wAssocStatus,
+                  wAssocAID,
+                  sFrame.pHdr->sA3.abyAddr2,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+    if (pTxPacket != NULL ){
+
+        if (pDevice->bEnableHostapd) {
+            return;
+        }
+        /* send the frame */
+        Status = csMgmt_xmit(pDevice, pTxPacket);
+        if (Status != CMD_STATUS_PENDING) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
+        }
+
+    }
+
+    return;
+}
+
+
+/*+
+ *
+ * Description:(AP function)
+ *      Handle incoming station re-association request frames.
+ *
+ * Parameters:
+ *  In:
+ *      pMgmt           - Management Object structure
+ *      pRxPacket       - Received Packet
+ *  Out:
+ *      none
+ *
+ * Return Value: None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxReAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN UINT uNodeIndex
+    )
+{
+    WLAN_FR_REASSOCREQ    sFrame;
+    CMD_STATUS          Status;
+    PSTxMgmtPacket      pTxPacket;
+    WORD                wAssocStatus = 0;
+    WORD                wAssocAID = 0;
+    UINT                uRateLen = WLAN_RATES_MAXLEN;
+    BYTE                abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+
+    if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
+        return;
+    //  node index not found
+    if (!uNodeIndex)
+        return;
+    //check if node is authenticated
+    //decode the frame
+    memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ));
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    vMgrDecodeReassocRequest(&sFrame);
+
+    if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
+        pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
+        pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
+                WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? TRUE : FALSE;
+        // Todo: check sta basic rate, if ap can't support, set status code
+
+        if (pDevice->byBBType == BB_TYPE_11B) {
+            uRateLen = WLAN_RATES_MAXLEN_11B;
+        }
+
+        abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+        abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                         (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                                         uRateLen);
+        abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
+        if (pDevice->byBBType == BB_TYPE_11G) {
+            abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
+                                                (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                                                uRateLen);
+        } else {
+            abyCurrExtSuppRates[1] = 0;
+        }
+
+
+        RATEvParseMaxRate((PVOID)pDevice,
+                          (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
+                          (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
+                           FALSE, // do not change our basic rate
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                           &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                          );
+
+        // set max tx rate
+        pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
+                pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+        // Todo: check sta preamble, if ap can't support, set status code
+        pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
+                WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
+                WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+        pMgmt->sNodeDBTable[uNodeIndex].wAID = (WORD)uNodeIndex;
+        wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
+        wAssocAID = (WORD)uNodeIndex;
+
+        // if suppurt ERP
+        if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
+           pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+
+        if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
+            // B only STA join
+            pDevice->bProtectMode = TRUE;
+            pDevice->bNonERPPresent = TRUE;
+        }
+        if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == FALSE) {
+            pDevice->bBarkerPreambleMd = TRUE;
+        }
+
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
+                   sFrame.pHdr->sA3.abyAddr2[0],
+                   sFrame.pHdr->sA3.abyAddr2[1],
+                   sFrame.pHdr->sA3.abyAddr2[2],
+                   sFrame.pHdr->sA3.abyAddr2[3],
+                   sFrame.pHdr->sA3.abyAddr2[4],
+                   sFrame.pHdr->sA3.abyAddr2[5]
+                  ) ;
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
+                   pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
+
+    }
+
+
+    // assoc response reply..
+    pTxPacket = s_MgrMakeReAssocResponse
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->wCurrCapInfo,
+                  wAssocStatus,
+                  wAssocAID,
+                  sFrame.pHdr->sA3.abyAddr2,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if (pTxPacket != NULL ){
+        /* send the frame */
+        if (pDevice->bEnableHostapd) {
+            return;
+        }
+        Status = csMgmt_xmit(pDevice, pTxPacket);
+        if (Status != CMD_STATUS_PENDING) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
+        }
+    }
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Handle incoming association response frames.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bReAssocType
+    )
+{
+    WLAN_FR_ASSOCRESP   sFrame;
+    PWLAN_IE_SSID   pItemSSID;
+    PBYTE   pbyIEs;
+    viawget_wpa_header *wpahdr;
+
+
+
+    if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING ||
+         pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        // decode the frame
+        vMgrDecodeAssocResponse(&sFrame);
+        if ((sFrame.pwCapInfo == 0) ||
+            (sFrame.pwStatus == 0) ||
+            (sFrame.pwAid == 0) ||
+            (sFrame.pSuppRates == 0)){
+            DBG_PORT80(0xCC);
+            return;
+        };
+
+        pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
+        pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
+        pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid);
+        pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07;
+
+        pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6;
+        pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+        pbyIEs = pMgmt->sAssocInfo.abyIEs;
+        pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+        memcpy(pbyIEs, (sFrame.pBuf + 24 +6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength);
+
+        // save values and set current BSS state
+        if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+            // set AID
+            pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid)));
+            if ( (pMgmt->wCurrAID >> 14) != (BIT0 | BIT1) )
+            {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
+            };
+            DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
+            pMgmt->eCurrState = WMAC_STATE_ASSOC;
+            BSSvUpdateAPNode((HANDLE)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
+            pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+            DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
+            pDevice->bLinkPass = TRUE;
+            ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+            if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+	       if(skb_tailroom(pDevice->skb) <(sizeof(viawget_wpa_header)+pMgmt->sAssocInfo.AssocInfo.ResponseIELength+
+		   	                                                 pMgmt->sAssocInfo.AssocInfo.RequestIELength)) {    //data room not enough
+                     dev_kfree_skb(pDevice->skb);
+		   pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+	       	}
+                wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                wpahdr->type = VIAWGET_ASSOC_MSG;
+                wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
+                wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+                memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len);
+                memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len,
+                       pbyIEs,
+                       wpahdr->resp_ie_len
+                       );
+                skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len);
+                pDevice->skb->dev = pDevice->wpadev;
+		skb_reset_mac_header(pDevice->skb);
+                pDevice->skb->pkt_type = PACKET_HOST;
+                pDevice->skb->protocol = htons(ETH_P_802_2);
+                memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+                netif_rx(pDevice->skb);
+                pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+            }
+//2008-0409-07, <Add> by Einsn Liu
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	//if(pDevice->bWPASuppWextEnabled == TRUE)
+	   {
+		BYTE buf[512];
+		size_t len;
+		union iwreq_data  wrqu;
+		int we_event;
+
+		memset(buf, 0, 512);
+
+		len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
+		if(len)	{
+			memcpy(buf, pMgmt->sAssocInfo.abyIEs, len);
+			memset(&wrqu, 0, sizeof (wrqu));
+			wrqu.data.length = len;
+			we_event = IWEVASSOCREQIE;
+			PRINT_K("wireless_send_event--->IWEVASSOCREQIE\n");
+			wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
+		}
+
+		memset(buf, 0, 512);
+		len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
+
+		if(len)	{
+			memcpy(buf, pbyIEs, len);
+			memset(&wrqu, 0, sizeof (wrqu));
+			wrqu.data.length = len;
+			we_event = IWEVASSOCRESPIE;
+			PRINT_K("wireless_send_event--->IWEVASSOCRESPIE\n");
+			wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
+		}
+
+	   memset(&wrqu, 0, sizeof (wrqu));
+	memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN);
+        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	   PRINT_K("wireless_send_event--->SIOCGIWAP(associated)\n");
+	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+
+	}
+#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//End Add -- //2008-0409-07, <Add> by Einsn Liu
+        }
+        else {
+            if (bReAssocType) {
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+            }
+            else {
+                // jump back to the auth state and indicate the error
+                pMgmt->eCurrState = WMAC_STATE_AUTH;
+            }
+            s_vMgrLogStatus(pMgmt,cpu_to_le16((*(sFrame.pwStatus))));
+        }
+
+    }
+
+#if 1
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+//need clear flags related to Networkmanager
+              pDevice->bwextstep0 = FALSE;
+              pDevice->bwextstep1 = FALSE;
+              pDevice->bwextstep2 = FALSE;
+              pDevice->bwextstep3 = FALSE;
+              pDevice->bWPASuppWextEnabled = FALSE;
+#endif
+#endif
+
+if(pMgmt->eCurrState == WMAC_STATE_ASSOC)
+      timer_expire(pDevice->sTimerCommand, 0);
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station authentication procedure.  Namely, send an
+ *    authentication frame to the AP.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject  pMgmt,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    WLAN_FR_AUTHEN  sFrame;
+    PSTxMgmtPacket  pTxPacket = NULL;
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+    vMgrEncodeAuthen(&sFrame);
+    /* insert values */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    if (pMgmt->bShareKeyAlgorithm)
+        *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY);
+    else
+        *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM);
+
+    *(sFrame.pwAuthSequence) = cpu_to_le16(1);
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+    if (*pStatus == CMD_STATUS_PENDING){
+        pMgmt->eCurrState = WMAC_STATE_AUTHPENDING;
+        *pStatus = CMD_STATUS_SUCCESS;
+    }
+
+    return ;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *    Start the station(AP) deauthentication procedure.  Namely, send an
+ *    deauthentication frame to the AP or Sta.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrDeAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject  pMgmt,
+    IN  PBYTE  abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    WLAN_FR_DEAUTHEN    sFrame;
+    PSTxMgmtPacket      pTxPacket = NULL;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN;
+    vMgrEncodeDeauthen(&sFrame);
+    /* insert values */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN)
+        ));
+
+    memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    *(sFrame.pwReason) = cpu_to_le16(wReason);       // deauthen. bcs left BSS
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    *pStatus = csMgmt_xmit(pDevice, pTxPacket);
+    if (*pStatus == CMD_STATUS_PENDING){
+        *pStatus = CMD_STATUS_SUCCESS;
+    }
+
+
+    return ;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *    Handle incoming authentication frames.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAuthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_AUTHEN  sFrame;
+
+    // we better be an AP or a STA in AUTHPENDING otherwise ignore
+    if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP ||
+          pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) {
+        return;
+    }
+
+    // decode the frame
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    vMgrDecodeAuthen(&sFrame);
+    switch (cpu_to_le16((*(sFrame.pwAuthSequence )))){
+        case 1:
+            //AP funciton
+            s_vMgrRxAuthenSequence_1(pDevice,pMgmt, &sFrame);
+            break;
+        case 2:
+            s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame);
+            break;
+        case 3:
+            //AP funciton
+            s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame);
+            break;
+        case 4:
+            s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame);
+            break;
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
+                        cpu_to_le16((*(sFrame.pwAuthSequence))));
+            break;
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming authen frames with sequence 1.  Currently
+ *   assumes we're an AP.  So far, no one appears to use authentication
+ *   in Ad-Hoc mode.
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+
+static
+VOID
+s_vMgrRxAuthenSequence_1(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+     )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    UINT                uNodeIndex;
+    WLAN_FR_AUTHEN      sFrame;
+    PSKeyItem           pTransmitKey;
+
+    // Insert a Node entry
+    if (!BSSbIsSTAInNodeDB(pDevice, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
+        BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
+        memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2,
+               WLAN_ADDR_LEN);
+    }
+
+    if (pMgmt->bShareKeyAlgorithm) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN;
+        pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1;
+    }
+    else {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
+    }
+
+    // send auth reply
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+    // format buffer structure
+    vMgrEncodeAuthen(&sFrame);
+    // insert values
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+         (
+         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
+         WLAN_SET_FC_ISWEP(0)
+         ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
+    *(sFrame.pwAuthSequence) = cpu_to_le16(2);
+
+    if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) {
+        if (pMgmt->bShareKeyAlgorithm)
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
+        else
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
+    }
+    else {
+        if (pMgmt->bShareKeyAlgorithm)
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
+        else
+            *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
+    }
+
+    if (pMgmt->bShareKeyAlgorithm &&
+        (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) {
+
+        sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
+        sFrame.len += WLAN_CHALLENGE_IE_LEN;
+        sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
+        sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
+        memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN);
+        // get group key
+        if(KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == TRUE) {
+            rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3);
+            rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN);
+        }
+        memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN);
+    }
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+    // send the frame
+    if (pDevice->bEnableHostapd) {
+        return;
+    }
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming auth frames with sequence number 2.  Currently
+ *   assumes we're a station.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAuthenSequence_2(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    )
+{
+    WLAN_FR_AUTHEN      sFrame;
+    PSTxMgmtPacket      pTxPacket = NULL;
+
+
+    switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm))))
+    {
+        case WLAN_AUTH_ALG_OPENSYSTEM:
+            if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
+                pMgmt->eCurrState = WMAC_STATE_AUTH;
+	       timer_expire(pDevice->sTimerCommand, 0);
+            }
+            else {
+                DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
+                s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+            }
+            if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
+//                spin_unlock_irq(&pDevice->lock);
+//                vCommandTimerWait((HANDLE)pDevice, 0);
+//                spin_lock_irq(&pDevice->lock);
+            }
+
+            break;
+
+        case WLAN_AUTH_ALG_SHAREDKEY:
+
+            if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
+                pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+                memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+                pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+                sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+                sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+                // format buffer structure
+                vMgrEncodeAuthen(&sFrame);
+                // insert values
+                sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+                     (
+                     WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+                     WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
+                     WLAN_SET_FC_ISWEP(1)
+                     ));
+                memcpy( sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+                memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+                memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+                *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
+                *(sFrame.pwAuthSequence) = cpu_to_le16(3);
+                *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
+                sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
+                sFrame.len += WLAN_CHALLENGE_IE_LEN;
+                sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
+                sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
+                memcpy( sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN);
+                // Adjust the length fields
+                pTxPacket->cbMPDULen = sFrame.len;
+                pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+                // send the frame
+                if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
+                }
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
+            }
+            else {
+            	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
+                if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
+//                    spin_unlock_irq(&pDevice->lock);
+//                    vCommandTimerWait((HANDLE)pDevice, 0);
+//                    spin_lock_irq(&pDevice->lock);
+                }
+                s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
+            }
+            break;
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
+            break;
+    }
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming authen frames with sequence 3.  Currently
+ *   assumes we're an AP.  This function assumes the frame has
+ *   already been successfully decrypted.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxAuthenSequence_3(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    UINT                uStatusCode = 0 ;
+    UINT                uNodeIndex = 0;
+    WLAN_FR_AUTHEN      sFrame;
+
+    if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
+        uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
+        goto reply;
+    }
+    if (BSSbIsSTAInNodeDB(pDevice, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
+         if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) {
+            uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ;
+            goto reply;
+         }
+         if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) {
+            uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
+            goto reply;
+         }
+    }
+    else {
+        uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE;
+        goto reply;
+    }
+
+    if (uNodeIndex) {
+        pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
+        pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0;
+    }
+    uStatusCode = WLAN_MGMT_STATUS_SUCCESS;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
+
+reply:
+    // send auth reply
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
+    // format buffer structure
+    vMgrEncodeAuthen(&sFrame);
+    /* insert values */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+         (
+         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
+         WLAN_SET_FC_ISWEP(0)
+         ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
+    *(sFrame.pwAuthSequence) = cpu_to_le16(4);
+    *(sFrame.pwStatus) = cpu_to_le16(uStatusCode);
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+    // send the frame
+    if (pDevice->bEnableHostapd) {
+        return;
+    }
+    if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
+    }
+    return;
+
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming authen frames with sequence 4
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+static
+VOID
+s_vMgrRxAuthenSequence_4(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_FR_AUTHEN pFrame
+    )
+{
+
+    if ( cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS ){
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
+        pMgmt->eCurrState = WMAC_STATE_AUTH;
+        timer_expire(pDevice->sTimerCommand, 0);
+    }
+    else{
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
+        s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))) );
+        pMgmt->eCurrState = WMAC_STATE_IDLE;
+    }
+
+    if ( pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT ) {
+//        spin_unlock_irq(&pDevice->lock);
+//        vCommandTimerWait((HANDLE)pDevice, 0);
+//        spin_lock_irq(&pDevice->lock);
+    }
+
+}
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming disassociation frames
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxDisassociation(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_DISASSOC    sFrame;
+    UINT        uNodeIndex = 0;
+    CMD_STATUS          CmdStatus;
+    viawget_wpa_header *wpahdr;
+
+    if ( pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
+        // if is acting an AP..
+        // a STA is leaving this BSS..
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
+            BSSvRemoveOneNode(pDevice, uNodeIndex);
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
+        }
+    }
+    else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ){
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        vMgrDecodeDisassociation(&sFrame);
+        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
+
+          pDevice->fWPA_Authened = FALSE;
+	if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+             wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+             wpahdr->type = VIAWGET_DISASSOC_MSG;
+             wpahdr->resp_ie_len = 0;
+             wpahdr->req_ie_len = 0;
+             skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+             pDevice->skb->dev = pDevice->wpadev;
+	     skb_reset_mac_header(pDevice->skb);
+             pDevice->skb->pkt_type = PACKET_HOST;
+             pDevice->skb->protocol = htons(ETH_P_802_2);
+             memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+             netif_rx(pDevice->skb);
+             pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+         };
+
+        //TODO: do something let upper layer know or
+        //try to send associate packet again because of inactivity timeout
+        if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
+                pDevice->bLinkPass = FALSE;
+                pMgmt->sNodeDBTable[0].bActive = FALSE;
+	       pDevice->byReAssocCount = 0;
+                pMgmt->eCurrState = WMAC_STATE_AUTH;  // jump back to the auth state!
+                pDevice->eCommandState = WLAN_ASSOCIATE_WAIT;
+            vMgrReAssocBeginSta((PSDevice)pDevice, pMgmt, &CmdStatus);
+              if(CmdStatus == CMD_STATUS_PENDING) {
+		  pDevice->byReAssocCount ++;
+		  return;       //mike add: you'll retry for many times, so it cann't be regarded as disconnected!
+              }
+        };
+
+   #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+  // if(pDevice->bWPASuppWextEnabled == TRUE)
+      {
+	union iwreq_data  wrqu;
+	memset(&wrqu, 0, sizeof (wrqu));
+        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n");
+	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+     }
+  #endif
+    }
+    /* else, ignore it */
+
+    return;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *   Handles incoming deauthentication frames
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxDeauthentication(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_DEAUTHEN    sFrame;
+    UINT        uNodeIndex = 0;
+    viawget_wpa_header *wpahdr;
+
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP ){
+        //Todo:
+        // if is acting an AP..
+        // a STA is leaving this BSS..
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
+            BSSvRemoveOneNode(pDevice, uNodeIndex);
+        }
+        else {
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
+        }
+    }
+    else {
+        if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA ) {
+            sFrame.len = pRxPacket->cbMPDULen;
+            sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+            vMgrDecodeDeauthen(&sFrame);
+	   pDevice->fWPA_Authened = FALSE;
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
+            // TODO: update BSS list for specific BSSID if pre-authentication case
+            if (IS_ETH_ADDRESS_EQUAL(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
+                if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
+                    pMgmt->sNodeDBTable[0].bActive = FALSE;
+                    pMgmt->eCurrMode = WMAC_MODE_STANDBY;
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    netif_stop_queue(pDevice->dev);
+                    pDevice->bLinkPass = FALSE;
+                    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+                }
+            };
+
+            if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
+                 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
+                 wpahdr->type = VIAWGET_DISASSOC_MSG;
+                 wpahdr->resp_ie_len = 0;
+                 wpahdr->req_ie_len = 0;
+                 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
+                 pDevice->skb->dev = pDevice->wpadev;
+		 skb_reset_mac_header(pDevice->skb);
+                 pDevice->skb->pkt_type = PACKET_HOST;
+                 pDevice->skb->protocol = htons(ETH_P_802_2);
+                 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
+                 netif_rx(pDevice->skb);
+                 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+           };
+
+   #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+  // if(pDevice->bWPASuppWextEnabled == TRUE)
+      {
+	union iwreq_data  wrqu;
+	memset(&wrqu, 0, sizeof (wrqu));
+        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
+	wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
+     }
+  #endif
+
+        }
+        /* else, ignore it.  TODO: IBSS authentication service
+            would be implemented here */
+    };
+    return;
+}
+
+//2008-0730-01<Add>by MikeLiu
+/*+
+ *
+ * Routine Description:
+ * check if current channel is match ZoneType.
+ *for USA:1~11;
+ *      Japan:1~13;
+ *      Europe:1~13
+ * Return Value:
+ *               True:exceed;
+ *                False:normal case
+-*/
+static BOOL
+ChannelExceedZoneType(
+    IN PSDevice pDevice,
+    IN BYTE byCurrChannel
+    )
+{
+  BOOL exceed=FALSE;
+
+  switch(pDevice->byZoneType) {
+  	case 0x00:                  //USA:1~11
+                     if((byCurrChannel<1) ||(byCurrChannel>11))
+	                exceed = TRUE;
+	         break;
+	case 0x01:                  //Japan:1~13
+	case 0x02:                  //Europe:1~13
+                     if((byCurrChannel<1) ||(byCurrChannel>13))
+	                exceed = TRUE;
+	         break;
+	default:                    //reserve for other zonetype
+		break;
+  }
+
+  return exceed;
+}
+
+/*+
+ *
+ * Routine Description:
+ *   Handles and analysis incoming beacon frames.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket,
+    IN BOOL bInScan
+    )
+{
+
+    PKnownBSS           pBSSList;
+    WLAN_FR_BEACON      sFrame;
+    QWORD               qwTSFOffset;
+    BOOL                bIsBSSIDEqual = FALSE;
+    BOOL                bIsSSIDEqual = FALSE;
+    BOOL                bTSFLargeDiff = FALSE;
+    BOOL                bTSFOffsetPostive = FALSE;
+    BOOL                bUpdateTSF = FALSE;
+    BOOL                bIsAPBeacon = FALSE;
+    BOOL                bIsChannelEqual = FALSE;
+    UINT                uLocateByteIndex;
+    BYTE                byTIMBitOn = 0;
+    WORD                wAIDNumber = 0;
+    UINT                uNodeIndex;
+    QWORD               qwTimestamp, qwLocalTSF;
+    QWORD               qwCurrTSF;
+    WORD                wStartIndex = 0;
+    WORD                wAIDIndex = 0;
+    BYTE                byCurrChannel = pRxPacket->byRxChannel;
+    ERPObject           sERP;
+    UINT                uRateLen = WLAN_RATES_MAXLEN;
+    BOOL                bChannelHit = FALSE;
+    BYTE                byOldPreambleType;
+
+
+
+     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
+        return;
+
+    memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+
+    // decode the beacon frame
+    vMgrDecodeBeacon(&sFrame);
+
+    if ((sFrame.pwBeaconInterval == 0) ||
+        (sFrame.pwCapInfo == 0) ||
+        (sFrame.pSSID == 0) ||
+        (sFrame.pSuppRates == 0) ) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
+        return;
+    };
+
+
+    if( byCurrChannel > CB_MAX_CHANNEL_24G )
+    {
+        if (sFrame.pDSParms != NULL) {
+            if (byCurrChannel == RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
+                bChannelHit = TRUE;
+            byCurrChannel = RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
+        } else {
+            bChannelHit = TRUE;
+        }
+
+    } else {
+        if (sFrame.pDSParms != NULL) {
+            if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
+                bChannelHit = TRUE;
+            byCurrChannel = sFrame.pDSParms->byCurrChannel;
+        } else {
+            bChannelHit = TRUE;
+        }
+    }
+
+//2008-0730-01<Add>by MikeLiu
+if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
+      return;
+
+    if (sFrame.pERP != NULL) {
+        sERP.byERP = sFrame.pERP->byContext;
+        sERP.bERPExist = TRUE;
+
+    } else {
+        sERP.bERPExist = FALSE;
+        sERP.byERP = 0;
+    }
+
+    pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
+    if (pBSSList == NULL) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel);
+        BSSbInsertToBSSList((HANDLE)pDevice,
+                            sFrame.pHdr->sA3.abyAddr3,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
+                            (HANDLE)pRxPacket
+                           );
+    }
+    else {
+//        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel);
+        BSSbUpdateToBSSList((HANDLE)pDevice,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            bChannelHit,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            pBSSList,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
+                            (HANDLE)pRxPacket
+                           );
+
+    }
+
+    if (bInScan) {
+        return;
+    }
+
+    if(byCurrChannel == (BYTE)pMgmt->uCurrChannel)
+       bIsChannelEqual = TRUE;
+
+    if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
+
+        // if rx beacon without ERP field
+        if (sERP.bERPExist) {
+            if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)){
+                pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
+                pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
+            }
+        }
+        else {
+            pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
+            pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
+        }
+
+        if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+            if(!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo))
+                pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
+            if(!sERP.bERPExist)
+                pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
+        }
+    }
+
+    // check if BSSID the same
+    if (memcmp(sFrame.pHdr->sA3.abyAddr3,
+               pMgmt->abyCurrBSSID,
+               WLAN_BSSID_LEN) == 0) {
+
+        bIsBSSIDEqual = TRUE;
+        pDevice->uCurrRSSI = pRxPacket->uRSSI;
+        pDevice->byCurrSQ = pRxPacket->bySQ;
+        if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
+            pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
+        }
+    }
+    // check if SSID the same
+    if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) {
+        if (memcmp(sFrame.pSSID->abySSID,
+                   ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
+                   sFrame.pSSID->len
+                   ) == 0) {
+            bIsSSIDEqual = TRUE;
+        };
+    }
+
+    if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== TRUE) &&
+        (bIsBSSIDEqual == TRUE) &&
+        (bIsSSIDEqual == TRUE) &&
+        (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
+        (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
+        // add state check to prevent reconnect fail since we'll receive Beacon
+
+        bIsAPBeacon = TRUE;
+        if (pBSSList != NULL) {
+
+                // Sync ERP field
+                if ((pBSSList->sERP.bERPExist == TRUE) && (pDevice->byBBType == BB_TYPE_11G)) {
+                    if ((pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
+                        pDevice->bProtectMode = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+                        if (pDevice->bProtectMode) {
+                            MACvEnableProtectMD(pDevice);
+                        } else {
+                            MACvDisableProtectMD(pDevice);
+                        }
+                        vUpdateIFS(pDevice);
+                    }
+                    if ((pBSSList->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
+                        pDevice->bNonERPPresent = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+                    }
+                    if ((pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
+                        pDevice->bBarkerPreambleMd = (pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
+                        //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
+                        if (pDevice->bBarkerPreambleMd) {
+                            MACvEnableBarkerPreambleMd(pDevice);
+                        } else {
+                            MACvDisableBarkerPreambleMd(pDevice);
+                        }
+                    }
+                }
+                // Sync Short Slot Time
+                if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo) != pDevice->bShortSlotTime) {
+                    BOOL    bShortSlotTime;
+
+                    bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo);
+                    //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
+                    //Kyle check if it is OK to set G.
+                    if (pDevice->byBBType == BB_TYPE_11A) {
+                        bShortSlotTime = TRUE;
+                    }
+                    else if (pDevice->byBBType == BB_TYPE_11B) {
+                        bShortSlotTime = FALSE;
+                    }
+                    if (bShortSlotTime != pDevice->bShortSlotTime) {
+                        pDevice->bShortSlotTime = bShortSlotTime;
+                        BBvSetShortSlotTime(pDevice);
+                        vUpdateIFS(pDevice);
+                    }
+                }
+
+                //
+                // Preamble may change dynamiclly
+                //
+                byOldPreambleType = pDevice->byPreambleType;
+                if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pBSSList->wCapInfo)) {
+                    pDevice->byPreambleType = pDevice->byShortPreamble;
+                }
+                else {
+                    pDevice->byPreambleType = 0;
+                }
+                if (pDevice->byPreambleType != byOldPreambleType)
+                    CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
+            //
+            // Basic Rate Set may change dynamiclly
+            //
+            if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) {
+                uRateLen = WLAN_RATES_MAXLEN_11B;
+            }
+            pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates,
+                                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                    uRateLen);
+            pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates,
+                                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                                                    uRateLen);
+            RATEvParseMaxRate( (PVOID)pDevice,
+                               (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                               (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                               TRUE,
+                               &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
+                               &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
+                               &(pMgmt->sNodeDBTable[0].wSuppRate),
+                               &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
+                               &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
+                              );
+
+        }
+    }
+
+//    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n");
+    // check if CF field exisit
+    if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
+        if (sFrame.pCFParms->wCFPDurRemaining > 0) {
+            // TODO: deal with CFP period to set NAV
+        };
+    };
+
+    HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
+    LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
+    HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF);
+    LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF);
+
+    // check if beacon TSF larger or small than our local TSF
+    if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) {
+        if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) {
+            bTSFOffsetPostive = TRUE;
+        }
+        else {
+            bTSFOffsetPostive = FALSE;
+        }
+    }
+    else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) {
+        bTSFOffsetPostive = TRUE;
+    }
+    else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
+        bTSFOffsetPostive = FALSE;
+    };
+
+    if (bTSFOffsetPostive) {
+        qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
+    }
+    else {
+        qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
+    }
+
+    if (HIDWORD(qwTSFOffset) != 0 ||
+        (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE )) {
+         bTSFLargeDiff = TRUE;
+    }
+
+
+    // if infra mode
+    if (bIsAPBeacon == TRUE) {
+
+        // Infra mode: Local TSF always follow AP's TSF if Difference huge.
+        if (bTSFLargeDiff)
+            bUpdateTSF = TRUE;
+
+        if ((pDevice->bEnablePSMode == TRUE) &&(sFrame.pTIM != 0)) {
+
+            // deal with DTIM, analysis TIM
+            pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? TRUE : FALSE ;
+            pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
+            pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
+            wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
+
+            // check if AID in TIM field bit on
+            // wStartIndex = N1
+            wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1;
+            // AIDIndex = N2
+            wAIDIndex = (wAIDNumber >> 3);
+            if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) {
+                uLocateByteIndex = wAIDIndex - wStartIndex;
+                // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
+                if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
+                    byTIMBitOn  = (0x01) << ((wAIDNumber) % 8);
+                    pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? TRUE : FALSE;
+                }
+                else {
+                    pMgmt->bInTIM = FALSE;
+                };
+            }
+            else {
+                pMgmt->bInTIM = FALSE;
+            };
+
+            if (pMgmt->bInTIM ||
+                (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
+                pMgmt->bInTIMWake = TRUE;
+                // send out ps-poll packet
+//                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
+                if (pMgmt->bInTIM) {
+                    PSvSendPSPOLL((PSDevice)pDevice);
+//                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
+                };
+
+            }
+            else {
+                pMgmt->bInTIMWake = FALSE;
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
+                if (pDevice->bPWBitOn == FALSE) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
+                    if (PSbSendNullPacket(pDevice))
+                        pDevice->bPWBitOn = TRUE;
+                }
+                if(PSbConsiderPowerDown(pDevice, FALSE, FALSE)) {
+                   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
+                };
+            }
+
+        }
+
+    }
+    // if adhoc mode
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) {
+        if (bIsBSSIDEqual) {
+            // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count.
+		    if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
+		 	    pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+
+            // adhoc mode:TSF updated only when beacon larger then local TSF
+            if (bTSFLargeDiff && bTSFOffsetPostive &&
+                (pMgmt->eCurrState == WMAC_STATE_JOINTED))
+                bUpdateTSF = TRUE;
+
+            // During dpc, already in spinlocked.
+            if (BSSbIsSTAInNodeDB(pDevice, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
+
+                // Update the STA, (Techically the Beacons of all the IBSS nodes
+		        // should be identical, but that's not happening in practice.
+                pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                        WLAN_RATES_MAXLEN_11B);
+                RATEvParseMaxRate( (PVOID)pDevice,
+                                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                   NULL,
+                                   TRUE,
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                                  );
+                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+                pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+                pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0;
+            }
+            else {
+                // Todo, initial Node content
+                BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
+
+                pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                                        (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                        WLAN_RATES_MAXLEN_11B);
+                RATEvParseMaxRate( (PVOID)pDevice,
+                                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                   NULL,
+                                   TRUE,
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
+                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
+                                 );
+
+                memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
+                pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
+                pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
+/*
+                pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
+                if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
+                       pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
+*/
+            }
+
+            // if other stations jointed, indicate connect to upper layer..
+            if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
+                pMgmt->eCurrState = WMAC_STATE_JOINTED;
+                pDevice->bLinkPass = TRUE;
+                ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+                if (netif_queue_stopped(pDevice->dev)){
+                    netif_wake_queue(pDevice->dev);
+                }
+                pMgmt->sNodeDBTable[0].bActive = TRUE;
+                pMgmt->sNodeDBTable[0].uInActiveCount = 0;
+
+            };
+        }
+        else if (bIsSSIDEqual) {
+
+            // See other adhoc sta with the same SSID but BSSID is different.
+            // adpot this vars only when TSF larger then us.
+            if (bTSFLargeDiff && bTSFOffsetPostive) {
+                 // we don't support ATIM under adhoc mode
+               // if ( sFrame.pIBSSParms->wATIMWindow == 0) {
+                     // adpot this vars
+                     // TODO: check sFrame cap if privacy on, and support rate syn
+                     memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN);
+                     memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+                     pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow);
+                     pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval);
+                     pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
+                                                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                      WLAN_RATES_MAXLEN_11B);
+                     // set HW beacon interval and re-synchronizing....
+                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
+
+                     MACvWriteBeaconInterval(pDevice, pMgmt->wCurrBeaconPeriod);
+                     CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
+                     CARDvUpdateNextTBTT(pDevice, qwTimestamp, pMgmt->wCurrBeaconPeriod);
+
+                     // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
+                     MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
+
+                    byOldPreambleType = pDevice->byPreambleType;
+                    if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) {
+                        pDevice->byPreambleType = pDevice->byShortPreamble;
+                    }
+                    else {
+                        pDevice->byPreambleType = 0;
+                    }
+                    if (pDevice->byPreambleType != byOldPreambleType)
+                        CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
+
+
+                     // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
+                     // set highest basic rate
+                     // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates);
+                     // Prepare beacon frame
+                     bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt);
+              //  }
+            };
+        }
+    };
+    // endian issue ???
+    // Update TSF
+    if (bUpdateTSF) {
+        CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
+        CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp , pRxPacket->qwLocalTSF);
+        CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
+        CARDvUpdateNextTBTT(pDevice, qwTimestamp, pMgmt->wCurrBeaconPeriod);
+    }
+
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Instructs the hw to create a bss using the supplied
+ *   attributes. Note that this implementation only supports Ad-Hoc
+ *   BSS creation.
+ *
+ *
+ * Return Value:
+ *    CMD_STATUS
+ *
+-*/
+VOID
+vMgrCreateOwnIBSS(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+    WORD                wMaxBasicRate;
+    WORD                wMaxSuppRate;
+    BYTE                byTopCCKBasicRate;
+    BYTE                byTopOFDMBasicRate;
+    QWORD               qwCurrTSF;
+    UINT                ii;
+    BYTE    abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
+    BYTE    abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
+    BYTE    abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    WORD                wSuppRate;
+
+
+
+    HIDWORD(qwCurrTSF) = 0;
+    LODWORD(qwCurrTSF) = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
+            (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) &&
+            (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) {
+            // encryption mode error
+            *pStatus = CMD_STATUS_FAILURE;
+            return;
+        }
+    }
+
+    pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+    pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        pMgmt->eCurrentPHYMode = pMgmt->byAPBBType;
+    } else {
+        if (pDevice->byBBType == BB_TYPE_11G)
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
+        if (pDevice->byBBType == BB_TYPE_11B)
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
+        if (pDevice->byBBType == BB_TYPE_11A)
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
+    }
+
+    if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
+        pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B;
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+        for (ii = 0; ii < 4; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
+    } else {
+        pMgmt->abyCurrSuppRates[1] = 8;
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+        for (ii = 0; ii < 8; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
+    }
+
+
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        pMgmt->abyCurrSuppRates[1] = 8;
+        pMgmt->abyCurrExtSuppRates[1] = 4;
+        for (ii = 0; ii < 4; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] =  abyCCK_RATE[ii];
+        for (ii = 4; ii < 8; ii++)
+            pMgmt->abyCurrSuppRates[2+ii] =  abyOFDM_RATE[ii-4];
+        for (ii = 0; ii < 4; ii++)
+            pMgmt->abyCurrExtSuppRates[2+ii] =  abyOFDM_RATE[ii+4];
+    }
+
+
+    // Disable Protect Mode
+    pDevice->bProtectMode = 0;
+    MACvDisableProtectMD(pDevice);
+
+    pDevice->bBarkerPreambleMd = 0;
+    MACvDisableBarkerPreambleMd(pDevice);
+
+    // Kyle Test 2003.11.04
+
+    // set HW beacon interval
+    if (pMgmt->wIBSSBeaconPeriod == 0)
+        pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
+    MACvWriteBeaconInterval(pDevice, pMgmt->wIBSSBeaconPeriod);
+
+    CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
+    // clear TSF counter
+    CARDbClearCurrentTSF(pDevice);
+
+    // enable TSF counter
+    MACvRegBitsOn(pDevice,MAC_REG_TFTCTL,TFTCTL_TSFCNTREN);
+    // set Next TBTT
+    CARDvSetFirstNextTBTT(pDevice, pMgmt->wIBSSBeaconPeriod);
+
+    pMgmt->uIBSSChannel = pDevice->uChannel;
+
+    if (pMgmt->uIBSSChannel == 0)
+        pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
+
+    // set channel and clear NAV
+    CARDbSetMediaChannel(pDevice, pMgmt->uIBSSChannel);
+    pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
+
+    pDevice->byPreambleType = pDevice->byShortPreamble;
+
+    // set basic rate
+
+    RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE,
+                      &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+                      &byTopCCKBasicRate, &byTopOFDMBasicRate);
+
+
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        pDevice->bShortSlotTime = TRUE;
+    } else {
+        pDevice->bShortSlotTime = FALSE;
+    }
+    BBvSetShortSlotTime(pDevice);
+    // vUpdateIFS() use pDevice->bShortSlotTime as parameter so it must be called
+    // after setting ShortSlotTime.
+    // CARDvSetBSSMode call vUpdateIFS()
+    CARDvSetBSSMode(pDevice);
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
+        MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_AP);
+        pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
+    }
+
+    if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+        MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+        pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
+    }
+
+    // Adopt pre-configured IBSS vars to current vars
+    pMgmt->eCurrState = WMAC_STATE_STARTED;
+    pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod;
+    pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
+    pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow;
+    pDevice->uCurrRSSI = 0;
+    pDevice->byCurrSQ = 0;
+
+//20080131-04,<Add> by Mike Liu
+#ifdef Adhoc_STA
+    memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID,
+                      ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN);
+#endif
+
+    memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+    memcpy(pMgmt->abyCurrSSID,
+           pMgmt->abyDesireSSID,
+           ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN
+          );
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        // AP mode BSSID = MAC addr
+        memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%02x-%02x-%02x-%02x-%02x-%02x \n",
+                      pMgmt->abyCurrBSSID[0],
+                      pMgmt->abyCurrBSSID[1],
+                      pMgmt->abyCurrBSSID[2],
+                      pMgmt->abyCurrBSSID[3],
+                      pMgmt->abyCurrBSSID[4],
+                      pMgmt->abyCurrBSSID[5]
+                    );
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+
+        // BSSID selected must be randomized as spec 11.1.3
+        pMgmt->abyCurrBSSID[5] = (BYTE) (LODWORD(qwCurrTSF)& 0x000000ff);
+        pMgmt->abyCurrBSSID[4] = (BYTE)((LODWORD(qwCurrTSF)& 0x0000ff00) >> 8);
+        pMgmt->abyCurrBSSID[3] = (BYTE)((LODWORD(qwCurrTSF)& 0x00ff0000) >> 16);
+        pMgmt->abyCurrBSSID[2] = (BYTE)((LODWORD(qwCurrTSF)& 0x00000ff0) >> 4);
+        pMgmt->abyCurrBSSID[1] = (BYTE)((LODWORD(qwCurrTSF)& 0x000ff000) >> 12);
+        pMgmt->abyCurrBSSID[0] = (BYTE)((LODWORD(qwCurrTSF)& 0x0ff00000) >> 20);
+        pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
+        pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
+        pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
+        pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3];
+        pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4];
+        pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5];
+        pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP;
+        pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
+
+
+        DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%02x-%02x-%02x-%02x-%02x-%02x \n",
+                      pMgmt->abyCurrBSSID[0],
+                      pMgmt->abyCurrBSSID[1],
+                      pMgmt->abyCurrBSSID[2],
+                      pMgmt->abyCurrBSSID[3],
+                      pMgmt->abyCurrBSSID[4],
+                      pMgmt->abyCurrBSSID[5]
+                    );
+    }
+
+    // set BSSID filter
+    MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
+    memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
+
+    MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+    pDevice->byRxMode |= RCR_BSSID;
+    pMgmt->bCurrBSSIDFilterOn = TRUE;
+
+    // Set Capability Info
+    pMgmt->wCurrCapInfo = 0;
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
+        pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD;
+        pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
+        pDevice->eOPMode = OP_MODE_AP;
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
+        pDevice->eOPMode = OP_MODE_ADHOC;
+    }
+
+    if (pDevice->bEncryptionEnable) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+                pMgmt->byCSSPK = KEY_CTL_CCMP;
+                pMgmt->byCSSGK = KEY_CTL_CCMP;
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+                pMgmt->byCSSPK = KEY_CTL_TKIP;
+                pMgmt->byCSSGK = KEY_CTL_TKIP;
+            } else {
+                pMgmt->byCSSPK = KEY_CTL_NONE;
+                pMgmt->byCSSGK = KEY_CTL_WEP;
+            }
+        } else {
+            pMgmt->byCSSPK = KEY_CTL_WEP;
+            pMgmt->byCSSGK = KEY_CTL_WEP;
+        }
+    };
+
+    pMgmt->byERPContext = 0;
+
+    if (pDevice->byPreambleType == 1) {
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
+    } else {
+        pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
+    }
+
+    pMgmt->eCurrState = WMAC_STATE_STARTED;
+    // Prepare beacon to send
+    if (bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt)) {
+        *pStatus = CMD_STATUS_SUCCESS;
+    }
+    return ;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *   Instructs wmac to join a bss using the supplied attributes.
+ *   The arguments may the BSSID or SSID and the rest of the
+ *   attributes are obtained from the scan result of known bss list.
+ *
+ *
+ * Return Value:
+ *    None.
+ *
+-*/
+
+VOID
+vMgrJoinBSSBegin(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    )
+{
+
+    PSDevice     pDevice = (PSDevice)hDeviceContext;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PKnownBSS       pCurr = NULL;
+    UINT            ii, uu;
+    PWLAN_IE_SUPP_RATES pItemRates = NULL;
+    PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
+    PWLAN_IE_SSID   pItemSSID;
+    UINT            uRateLen = WLAN_RATES_MAXLEN;
+    WORD            wMaxBasicRate = RATE_1M;
+    WORD            wMaxSuppRate = RATE_1M;
+    WORD            wSuppRate;
+    BYTE            byTopCCKBasicRate = RATE_1M;
+    BYTE            byTopOFDMBasicRate = RATE_1M;
+    BOOL            bShortSlotTime = FALSE;
+
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        if (pMgmt->sBSSList[ii].bActive == TRUE)
+            break;
+    }
+
+    if (ii == MAX_BSS_NUM) {
+       *pStatus = CMD_STATUS_RESOURCES;
+        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
+       return;
+    };
+
+    // memset(pMgmt->abyDesireBSSID, 0,  WLAN_BSSID_LEN);
+    // Search known BSS list for prefer BSSID or SSID
+
+    pCurr = BSSpSearchBSSList(pDevice,
+                              pMgmt->abyDesireBSSID,
+                              pMgmt->abyDesireSSID,
+                              pDevice->eConfigPHYMode
+                              );
+
+    if (pCurr == NULL){
+       *pStatus = CMD_STATUS_RESOURCES;
+       pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+       DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
+       return;
+    };
+
+    DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
+
+    if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){
+
+        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA)||(pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
+/*
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+            }
+*/
+        }
+
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+	//if(pDevice->bWPASuppWextEnabled == TRUE)
+            Encyption_Rebuild(pDevice, pCurr);
+#endif
+
+        // Infrastructure BSS
+        s_vMgrSynchBSS(pDevice,
+                       WMAC_MODE_ESS_STA,
+                       pCurr,
+                       pStatus
+                       );
+
+        if (*pStatus == CMD_STATUS_SUCCESS){
+
+            // Adopt this BSS state vars in Mgmt Object
+            pMgmt->uCurrChannel = pCurr->uChannel;
+
+            memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+            memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
+
+            if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
+                uRateLen = WLAN_RATES_MAXLEN_11B;
+            }
+
+            pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates;
+            pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates;
+
+            // Parse Support Rate IE
+            pItemRates->byElementID = WLAN_EID_SUPP_RATES;
+            pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
+                                         pItemRates,
+                                         uRateLen);
+
+            // Parse Extension Support Rate IE
+            pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES;
+            pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates,
+                                            pItemExtRates,
+                                            uRateLen);
+            // Stuffing Rate IE
+            if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
+                for (ii = 0; ii < (UINT)(8 - pItemRates->len); ) {
+                    pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii];
+                    ii ++;
+                    if (pItemExtRates->len <= ii)
+                        break;
+                }
+                pItemRates->len += (BYTE)ii;
+                if (pItemExtRates->len - ii > 0) {
+                    pItemExtRates->len -= (BYTE)ii;
+                    for (uu = 0; uu < pItemExtRates->len; uu ++) {
+                        pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
+                    }
+                } else {
+                    pItemExtRates->len = 0;
+                }
+            }
+
+            RATEvParseMaxRate((PVOID)pDevice, pItemRates, pItemExtRates, TRUE,
+                              &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+                              &byTopCCKBasicRate, &byTopOFDMBasicRate);
+            vUpdateIFS(pDevice);
+            // TODO: deal with if wCapInfo the privacy is on, but station WEP is off
+            // TODO: deal with if wCapInfo the PS-Pollable is on.
+            pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
+            memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+            memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+            memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+
+            pMgmt->eCurrMode = WMAC_MODE_ESS_STA;
+
+            pMgmt->eCurrState = WMAC_STATE_JOINTED;
+            // Adopt BSS state in Adapter Device Object
+            pDevice->eOPMode = OP_MODE_INFRASTRUCTURE;
+            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+
+            // Add current BSS to Candidate list
+            // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
+            if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+                BOOL bResult = bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
+                if (bResult == FALSE) {
+                    vFlush_PMKID_Candidate((HANDLE)pDevice);
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFlush_PMKID_Candidate: 4\n");
+                    bAdd_PMKID_Candidate((HANDLE)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
+                }
+            }
+
+            // Preamble type auto-switch: if AP can receive short-preamble cap,
+            // we can turn on too.
+            if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
+                pDevice->byPreambleType = pDevice->byShortPreamble;
+            }
+            else {
+                pDevice->byPreambleType = 0;
+            }
+            // Change PreambleType must set RSPINF again
+            CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n");
+
+            if (pCurr->eNetworkTypeInUse == PHY_TYPE_11G) {
+
+                if ((pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
+                    pDevice->bProtectMode = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+                    if (pDevice->bProtectMode) {
+                        MACvEnableProtectMD(pDevice);
+                    } else {
+                        MACvDisableProtectMD(pDevice);
+                    }
+                    vUpdateIFS(pDevice);
+                }
+                if ((pCurr->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
+                    pDevice->bNonERPPresent = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
+                }
+                if ((pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
+                    pDevice->bBarkerPreambleMd = (pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
+                    //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
+                    if (pDevice->bBarkerPreambleMd) {
+                        MACvEnableBarkerPreambleMd(pDevice);
+                    } else {
+                        MACvDisableBarkerPreambleMd(pDevice);
+                    }
+                }
+            }
+            //DBG_PRN_WLAN05(("wCapInfo: %X\n", pCurr->wCapInfo));
+            if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo) != pDevice->bShortSlotTime) {
+                if (pDevice->byBBType == BB_TYPE_11A) {
+                    bShortSlotTime = TRUE;
+                }
+                else if (pDevice->byBBType == BB_TYPE_11B) {
+                    bShortSlotTime = FALSE;
+                }
+                else {
+                    bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo);
+                }
+                //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
+                if (bShortSlotTime != pDevice->bShortSlotTime) {
+                    pDevice->bShortSlotTime = bShortSlotTime;
+                    BBvSetShortSlotTime(pDevice);
+                    vUpdateIFS(pDevice);
+                }
+            }
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End of Join AP -- A/B/G Action\n");
+        }
+        else {
+            pMgmt->eCurrState = WMAC_STATE_IDLE;
+        };
+
+
+     }
+     else {
+        // ad-hoc mode BSS
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+/*
+                if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+*/
+            } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+/*
+                if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
+                    // encryption mode error
+                    pMgmt->eCurrState = WMAC_STATE_IDLE;
+                    return;
+                }
+*/
+            } else {
+                // encryption mode error
+                pMgmt->eCurrState = WMAC_STATE_IDLE;
+                return;
+            }
+        }
+
+        s_vMgrSynchBSS(pDevice,
+                       WMAC_MODE_IBSS_STA,
+                       pCurr,
+                       pStatus
+                       );
+
+        if (*pStatus == CMD_STATUS_SUCCESS){
+            // Adopt this BSS state vars in Mgmt Object
+            // TODO: check if CapInfo privacy on, but we don't..
+            pMgmt->uCurrChannel = pCurr->uChannel;
+
+
+            // Parse Support Rate IE
+            pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
+            pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
+                                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                                                    WLAN_RATES_MAXLEN_11B);
+            // set basic rate
+            RATEvParseMaxRate((PVOID)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                              NULL, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
+                              &byTopCCKBasicRate, &byTopOFDMBasicRate);
+            vUpdateIFS(pDevice);
+            pMgmt->wCurrCapInfo = pCurr->wCapInfo;
+            pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
+            memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
+            memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+            memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
+//          pMgmt->wCurrATIMWindow = pCurr->wATIMWindow;
+            pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
+            pMgmt->eCurrState = WMAC_STATE_STARTED;
+            // Adopt BSS state in Adapter Device Object
+            pDevice->eOPMode = OP_MODE_ADHOC;
+            pDevice->bLinkPass = TRUE;
+            ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
+            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n",
+                  pMgmt->abyCurrBSSID[0],
+                  pMgmt->abyCurrBSSID[1],
+                  pMgmt->abyCurrBSSID[2],
+                  pMgmt->abyCurrBSSID[3],
+                  pMgmt->abyCurrBSSID[4],
+                  pMgmt->abyCurrBSSID[5]
+                );
+            // Preamble type auto-switch: if AP can receive short-preamble cap,
+            // and if registry setting is short preamble we can turn on too.
+
+            if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
+                pDevice->byPreambleType = pDevice->byShortPreamble;
+            }
+            else {
+                pDevice->byPreambleType = 0;
+            }
+            // Change PreambleType must set RSPINF again
+            CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
+
+            // Prepare beacon
+            bMgrPrepareBeaconToSend((HANDLE)pDevice, pMgmt);
+        }
+        else {
+            pMgmt->eCurrState = WMAC_STATE_IDLE;
+        };
+     };
+    return;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ * Set HW to synchronize a specific BSS from known BSS list.
+ *
+ *
+ * Return Value:
+ *    PCM_STATUS
+ *
+-*/
+static
+VOID
+s_vMgrSynchBSS (
+    IN PSDevice      pDevice,
+    IN UINT          uBSSMode,
+    IN PKnownBSS     pCurr,
+    OUT PCMD_STATUS  pStatus
+    )
+{
+    PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
+                                                     //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
+    BYTE abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
+    BYTE abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
+                                                           //6M,   9M,   12M,  48M
+    BYTE abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
+    BYTE abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
+
+
+    *pStatus = CMD_STATUS_FAILURE;
+
+    if (s_bCipherMatch(pCurr,
+                       pDevice->eEncryptionStatus,
+                       &(pMgmt->byCSSPK),
+                       &(pMgmt->byCSSGK)) == FALSE) {
+        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "s_bCipherMatch Fail .......\n");
+        return;
+    }
+
+    pMgmt->pCurrBSS = pCurr;
+
+    // if previous mode is IBSS.
+    if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+        MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+    }
+
+    // Init the BSS informations
+    pDevice->bCCK = TRUE;
+    pDevice->bProtectMode = FALSE;
+    MACvDisableProtectMD(pDevice);
+    pDevice->bBarkerPreambleMd = FALSE;
+    MACvDisableBarkerPreambleMd(pDevice);
+    pDevice->bNonERPPresent = FALSE;
+    pDevice->byPreambleType = 0;
+    pDevice->wBasicRate = 0;
+    // Set Basic Rate
+    CARDbAddBasicRate((PVOID)pDevice, RATE_1M);
+
+    // calculate TSF offset
+    // TSF Offset = Received Timestamp TSF - Marked Local's TSF
+    CARDvAdjustTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
+
+    // set HW beacon interval
+    MACvWriteBeaconInterval(pDevice, pCurr->wBeaconInterval);
+
+    // set Next TBTT
+    // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
+    CARDvSetFirstNextTBTT(pDevice, pCurr->wBeaconInterval);
+
+    // set BSSID
+    MACvWriteBSSIDAddress(pDevice, pCurr->abyBSSID);
+
+    memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, 6);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = %02x-%02x-%02x=%02x-%02x-%02x\n",
+        pMgmt->abyCurrBSSID[0],
+        pMgmt->abyCurrBSSID[1],
+        pMgmt->abyCurrBSSID[2],
+        pMgmt->abyCurrBSSID[3],
+        pMgmt->abyCurrBSSID[4],
+        pMgmt->abyCurrBSSID[5]);
+
+    if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
+        if ((pDevice->eConfigPHYMode == PHY_TYPE_11A) ||
+            (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
+            pDevice->byBBType = BB_TYPE_11A;
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
+            pDevice->bShortSlotTime = TRUE;
+            BBvSetShortSlotTime(pDevice);
+            CARDvSetBSSMode(pDevice);
+        } else {
+            return;
+        }
+    } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
+        if ((pDevice->eConfigPHYMode == PHY_TYPE_11B) ||
+            (pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
+            (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
+            pDevice->byBBType = BB_TYPE_11B;
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
+            pDevice->bShortSlotTime = FALSE;
+            BBvSetShortSlotTime(pDevice);
+            CARDvSetBSSMode(pDevice);
+        } else {
+            return;
+        }
+    } else {
+        if ((pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
+            (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
+            pDevice->byBBType = BB_TYPE_11G;
+            pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
+            pDevice->bShortSlotTime = TRUE;
+            BBvSetShortSlotTime(pDevice);
+            CARDvSetBSSMode(pDevice);
+        } else if (pDevice->eConfigPHYMode == PHY_TYPE_11B) {
+            pDevice->byBBType = BB_TYPE_11B;
+            pDevice->bShortSlotTime = FALSE;
+            BBvSetShortSlotTime(pDevice);
+            CARDvSetBSSMode(pDevice);
+        } else {
+            return;
+        }
+    }
+
+    if (uBSSMode == WMAC_MODE_ESS_STA) {
+        MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+        MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+        pDevice->byRxMode |= RCR_BSSID;
+        pMgmt->bCurrBSSIDFilterOn = TRUE;
+    }
+
+    // set channel and clear NAV
+    CARDbSetMediaChannel(pDevice, pCurr->uChannel);
+    pMgmt->uCurrChannel = pCurr->uChannel;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
+
+    if ((pDevice->bUpdateBBVGA) &&
+        (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) {
+        pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
+        BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
+        BBvSetShortSlotTime(pDevice);
+    }
+    //
+    // Notes:
+    // 1. In Ad-hoc mode : check if received others beacon as jointed indication,
+    //    otherwise we will start own IBSS.
+    // 2. In Infra mode : Supposed we already synchronized with AP right now.
+
+    if (uBSSMode == WMAC_MODE_IBSS_STA) {
+        MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
+        MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
+        pDevice->byRxMode |= RCR_BSSID;
+        pMgmt->bCurrBSSIDFilterOn = TRUE;
+    };
+
+    if (pDevice->byBBType == BB_TYPE_11A) {
+        memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+    } else if (pDevice->byBBType == BB_TYPE_11B) {
+        memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
+        pMgmt->abyCurrExtSuppRates[1] = 0;
+    } else {
+        memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
+        memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
+    }
+    pMgmt->byERPContext = pCurr->sERP.byERP;
+
+    *pStatus = CMD_STATUS_SUCCESS;
+
+    return;
+};
+
+
+//mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption
+//                   ,need reset eAuthenMode and eEncryptionStatus
+ static VOID  Encyption_Rebuild(
+    IN PSDevice pDevice,
+    IN PKnownBSS pCurr
+ )
+ {
+  PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
+ // UINT            ii , uSameBssidNum=0;
+
+        //  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+          //   if (pMgmt->sBSSList[ii].bActive &&
+            //      IS_ETH_ADDRESS_EQUAL(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
+             //       uSameBssidNum++;
+               //   }
+           // }
+  //   if( uSameBssidNum>=2) {	 //we only check AP in hidden sssid  mode
+        if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selsection,
+             (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-selsect it according to real pairwise-key info.
+               if(pCurr->bWPAValid == TRUE)  {   //WPA-PSK
+                          pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+		    if(pCurr->abyPKType[0] == WPA_TKIP) {
+     		        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
+     		        PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
+		      }
+     		   else if(pCurr->abyPKType[0] == WPA_AESCCMP) {
+		        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
+                          PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
+     		     }
+               	}
+               else if(pCurr->bWPA2Valid == TRUE) {  //WPA2-PSK
+                         pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
+		       if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
+      		           pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
+                             PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
+		       	}
+      		       else if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
+		           pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
+                            PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
+      		       	}
+               	}
+              }
+        //  }
+      return;
+ }
+
+
+/*+
+ *
+ * Routine Description:
+ *  Format TIM field
+ *
+ *
+ * Return Value:
+ *    VOID
+ *
+-*/
+
+static
+VOID
+s_vMgrFormatTIM(
+    IN PSMgmtObject pMgmt,
+    IN PWLAN_IE_TIM pTIM
+    )
+{
+    BYTE        byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
+    BYTE        byMap;
+    UINT        ii, jj;
+    BOOL        bStartFound = FALSE;
+    BOOL        bMulticast = FALSE;
+    WORD        wStartIndex = 0;
+    WORD        wEndIndex = 0;
+
+
+    // Find size of partial virtual bitmap
+    for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
+        byMap = pMgmt->abyPSTxMap[ii];
+        if (!ii) {
+            // Mask out the broadcast bit which is indicated separately.
+            bMulticast = (byMap & byMask[0]) != 0;
+            if(bMulticast) {
+               pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
+            }
+            byMap = 0;
+        }
+        if (byMap) {
+            if (!bStartFound) {
+                bStartFound = TRUE;
+                wStartIndex = (WORD)ii;
+            }
+            wEndIndex = (WORD)ii;
+        }
+    };
+
+
+    // Round start index down to nearest even number
+    wStartIndex &=  ~BIT0;
+
+    // Round end index up to nearest even number
+    wEndIndex = ((wEndIndex + 1) & ~BIT0);
+
+    // Size of element payload
+
+    pTIM->len =  3 + (wEndIndex - wStartIndex) + 1;
+
+    // Fill in the Fixed parts of the TIM
+    pTIM->byDTIMCount = pMgmt->byDTIMCount;
+    pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod;
+    pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) |
+        (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK);
+
+    // Append variable part of TIM
+
+    for (ii = wStartIndex, jj =0 ; ii <= wEndIndex; ii++, jj++) {
+         pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii];
+    }
+
+    // Aid = 0 don't used.
+    pTIM->byVirtBitMap[0]  &= ~BIT0;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an Beacon frame( Ad-hoc mode)
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+static
+PSTxMgmtPacket
+s_MgrMakeBeacon(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_BEACON      sFrame;
+    BYTE                abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+
+    // prepare beacon frame
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure.
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_BEACON_FR_MAXLEN;
+    vMgrEncodeBeacon(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON)
+        ));
+
+    if (pDevice->bEnablePSMode) {
+        sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_PWRMGT(1));
+    }
+
+    memcpy( sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
+    *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+    // Copy SSID
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID,
+             pCurrSSID,
+             ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
+            );
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+           pCurrSuppRates,
+           ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+          );
+    // DS parameter
+    if (pDevice->byBBType != BB_TYPE_11A) {
+        sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (1) + WLAN_IEHDR_LEN;
+        sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
+        sFrame.pDSParms->len = 1;
+        sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
+    }
+    // TIM field
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len);
+        sFrame.pTIM->byElementID = WLAN_EID_TIM;
+        s_vMgrFormatTIM(pMgmt, sFrame.pTIM);
+        sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len);
+    }
+
+    if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
+
+        // IBSS parameter
+        sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (2) + WLAN_IEHDR_LEN;
+        sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
+        sFrame.pIBSSParms->len = 2;
+        sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+            /* RSN parameter */
+            sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
+            sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
+            sFrame.pRSNWPA->len = 12;
+            sFrame.pRSNWPA->abyOUI[0] = 0x00;
+            sFrame.pRSNWPA->abyOUI[1] = 0x50;
+            sFrame.pRSNWPA->abyOUI[2] = 0xf2;
+            sFrame.pRSNWPA->abyOUI[3] = 0x01;
+            sFrame.pRSNWPA->wVersion = 1;
+            sFrame.pRSNWPA->abyMulticast[0] = 0x00;
+            sFrame.pRSNWPA->abyMulticast[1] = 0x50;
+            sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
+            if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
+                sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES
+            else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
+                sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP
+            else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled)
+                sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40
+            else
+                sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE
+
+            // Pairwise Key Cipher Suite
+            sFrame.pRSNWPA->wPKCount = 0;
+            // Auth Key Management Suite
+            *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+            sFrame.pRSNWPA->len +=2;
+
+            // RSN Capabilites
+            *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
+            sFrame.pRSNWPA->len +=2;
+            sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        }
+    }
+
+
+    if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
+        sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
+        sFrame.len += 1 + WLAN_IEHDR_LEN;
+        sFrame.pERP->byElementID = WLAN_EID_ERP;
+        sFrame.pERP->len = 1;
+        sFrame.pERP->byContext = 0;
+        if (pDevice->bProtectMode == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
+        if (pDevice->bNonERPPresent == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
+        if (pDevice->bBarkerPreambleMd == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
+    }
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+    // hostapd wpa/wpa2 IE
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
+         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+             if (pMgmt->wWPAIELen != 0) {
+                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+                 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
+                 sFrame.len += pMgmt->wWPAIELen;
+             }
+         }
+    }
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an Prob-response frame
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+
+
+
+PSTxMgmtPacket
+s_MgrMakeProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wCurrBeaconPeriod,
+    IN UINT uCurrChannel,
+    IN WORD wCurrATIMWinodw,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PBYTE pCurrBSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
+    IN BYTE byPHYType
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_PROBERESP   sFrame;
+
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure.
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
+    vMgrEncodeProbeResponse(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
+    *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+
+    if (byPHYType == BB_TYPE_11B) {
+        *sFrame.pwCapInfo &= cpu_to_le16((WORD)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
+    }
+
+    // Copy SSID
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID,
+           pCurrSSID,
+           ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
+           );
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+           pCurrSuppRates,
+           ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+          );
+
+    // DS parameter
+    if (pDevice->byBBType != BB_TYPE_11A) {
+        sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (1) + WLAN_IEHDR_LEN;
+        sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
+        sFrame.pDSParms->len = 1;
+        sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
+    }
+
+    if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
+        // IBSS parameter
+        sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
+        sFrame.len += (2) + WLAN_IEHDR_LEN;
+        sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
+        sFrame.pIBSSParms->len = 2;
+        sFrame.pIBSSParms->wATIMWindow = 0;
+    }
+    if (pDevice->byBBType == BB_TYPE_11G) {
+        sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
+        sFrame.len += 1 + WLAN_IEHDR_LEN;
+        sFrame.pERP->byElementID = WLAN_EID_ERP;
+        sFrame.pERP->len = 1;
+        sFrame.pERP->byContext = 0;
+        if (pDevice->bProtectMode == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
+        if (pDevice->bNonERPPresent == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
+        if (pDevice->bBarkerPreambleMd == TRUE)
+            sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
+    }
+
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+
+    // hostapd wpa/wpa2 IE
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
+         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
+             if (pMgmt->wWPAIELen != 0) {
+                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+                 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
+                 sFrame.len += pMgmt->wWPAIELen;
+             }
+         }
+    }
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an association request frame
+ *
+ *
+ * Return Value:
+ *    A ptr to frame or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_ASSOCREQ    sFrame;
+    PBYTE               pbyIEs;
+    PBYTE               pbyRSN;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure.
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
+    // format fixed field frame structure
+    vMgrEncodeAssocRequest(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    // Set the capibility and listen interval
+    *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
+    *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
+
+    // sFrame.len point to end of fixed field
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
+    pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+    pbyIEs = pMgmt->sAssocInfo.abyIEs;
+    memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
+
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    if ((pDevice->byBBType == BB_TYPE_11B) && (pCurrRates->len > 4))
+        sFrame.len += 4 + WLAN_IEHDR_LEN;
+    else
+        sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+
+    // Copy the extension rate set
+    if ((pDevice->byBBType == BB_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+    }
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
+
+
+    if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
+        (pMgmt->pCurrBSS != NULL)) {
+        /* WPA IE */
+        sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
+        sFrame.pRSNWPA->len = 16;
+        sFrame.pRSNWPA->abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->abyOUI[2] = 0xf2;
+        sFrame.pRSNWPA->abyOUI[3] = 0x01;
+        sFrame.pRSNWPA->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSNWPA->abyMulticast[0] = 0x00;
+        sFrame.pRSNWPA->abyMulticast[1] = 0x50;
+        sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
+        }
+        // Pairwise Key Cipher Suite
+        sFrame.pRSNWPA->wPKCount = 1;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
+        }
+        // Auth Key Management Suite
+        pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
+        *pbyRSN++=0x01;
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+
+        *pbyRSN++=0x50;
+        *pbyRSN++=0xf2;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
+            *pbyRSN++=WPA_AUTH_PSK;
+        }
+        else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
+            *pbyRSN++=WPA_AUTH_IEEE802_1X;
+        }
+        else {
+            *pbyRSN++=WPA_NONE;
+        }
+
+        sFrame.pRSNWPA->len +=6;
+
+        // RSN Capabilites
+
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+        sFrame.pRSNWPA->len +=2;
+
+        sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+
+    } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
+               (pMgmt->pCurrBSS != NULL)) {
+        UINT                ii;
+        PWORD               pwPMKID;
+
+        // WPA IE
+        sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSN->byElementID = WLAN_EID_RSN;
+        sFrame.pRSN->len = 6; //Version(2)+GK(4)
+        sFrame.pRSN->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSN->abyRSN[0] = 0x00;
+        sFrame.pRSN->abyRSN[1] = 0x0F;
+        sFrame.pRSN->abyRSN[2] = 0xAC;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
+        } else {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
+        }
+
+        // Pairwise Key Cipher Suite
+        sFrame.pRSN->abyRSN[4] = 1;
+        sFrame.pRSN->abyRSN[5] = 0;
+        sFrame.pRSN->abyRSN[6] = 0x00;
+        sFrame.pRSN->abyRSN[7] = 0x0F;
+        sFrame.pRSN->abyRSN[8] = 0xAC;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
+        } else {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
+        }
+        sFrame.pRSN->len += 6;
+
+        // Auth Key Management Suite
+        sFrame.pRSN->abyRSN[10] = 1;
+        sFrame.pRSN->abyRSN[11] = 0;
+        sFrame.pRSN->abyRSN[12] = 0x00;
+        sFrame.pRSN->abyRSN[13] = 0x0F;
+        sFrame.pRSN->abyRSN[14] = 0xAC;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
+        } else {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
+        }
+        sFrame.pRSN->len +=6;
+
+        // RSN Capabilites
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+            memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+        } else {
+            sFrame.pRSN->abyRSN[16] = 0;
+            sFrame.pRSN->abyRSN[17] = 0;
+        }
+        sFrame.pRSN->len +=2;
+
+        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+            // RSN PMKID
+            pbyRSN = &sFrame.pRSN->abyRSN[18];
+            pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
+            *pwPMKID = 0;            // Initialize PMKID count
+            pbyRSN += 2;             // Point to PMKID list
+            for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
+                if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                    (*pwPMKID) ++;
+                    memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
+                    pbyRSN += 16;
+                }
+            }
+            if (*pwPMKID != 0) {
+                sFrame.pRSN->len += (2 + (*pwPMKID)*16);
+            }
+        }
+
+        sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+    }
+
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+    return pTxPacket;
+}
+
+
+
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an re-association request frame
+ *
+ *
+ * Return Value:
+ *    A ptr to frame or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeReAssocRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PBYTE pDAddr,
+    IN WORD wCurrCapInfo,
+    IN WORD wListenInterval,
+    IN PWLAN_IE_SSID pCurrSSID,
+    IN PWLAN_IE_SUPP_RATES pCurrRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_REASSOCREQ  sFrame;
+    PBYTE               pbyIEs;
+    PBYTE               pbyRSN;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset( pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    /* Setup the sFrame structure. */
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
+
+    // format fixed field frame structure
+    vMgrEncodeReassocRequest(&sFrame);
+
+    /* Setup the header */
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    /* Set the capibility and listen interval */
+    *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
+    *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
+
+    memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+    /* Copy the SSID */
+    /* sFrame.len point to end of fixed field */
+    sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
+    pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+    pbyIEs = pMgmt->sAssocInfo.abyIEs;
+    memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
+
+    /* Copy the rate set */
+    /* sFrame.len point to end of SSID */
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+
+    // Copy the extension rate set
+    if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
+    }
+
+    pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
+    memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
+    pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
+
+    if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
+        (pMgmt->pCurrBSS != NULL)) {
+        /* WPA IE */
+        sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
+        sFrame.pRSNWPA->len = 16;
+        sFrame.pRSNWPA->abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->abyOUI[2] = 0xf2;
+        sFrame.pRSNWPA->abyOUI[3] = 0x01;
+        sFrame.pRSNWPA->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSNWPA->abyMulticast[0] = 0x00;
+        sFrame.pRSNWPA->abyMulticast[1] = 0x50;
+        sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
+        }
+        // Pairwise Key Cipher Suite
+        sFrame.pRSNWPA->wPKCount = 1;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
+        sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
+        } else {
+            sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
+        }
+        // Auth Key Management Suite
+        pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
+        *pbyRSN++=0x01;
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+
+        *pbyRSN++=0x50;
+        *pbyRSN++=0xf2;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
+            *pbyRSN++=WPA_AUTH_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
+            *pbyRSN++=WPA_AUTH_IEEE802_1X;
+        } else {
+            *pbyRSN++=WPA_NONE;
+        }
+
+        sFrame.pRSNWPA->len +=6;
+
+        // RSN Capabilites
+        *pbyRSN++=0x00;
+        *pbyRSN++=0x00;
+        sFrame.pRSNWPA->len +=2;
+
+        sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+        memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
+
+    } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+                (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
+               (pMgmt->pCurrBSS != NULL)) {
+        UINT                ii;
+        PWORD               pwPMKID;
+
+        /* WPA IE */
+        sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
+        sFrame.pRSN->byElementID = WLAN_EID_RSN;
+        sFrame.pRSN->len = 6; //Version(2)+GK(4)
+        sFrame.pRSN->wVersion = 1;
+        //Group Key Cipher Suite
+        sFrame.pRSN->abyRSN[0] = 0x00;
+        sFrame.pRSN->abyRSN[1] = 0x0F;
+        sFrame.pRSN->abyRSN[2] = 0xAC;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
+        } else {
+            sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
+        }
+
+        // Pairwise Key Cipher Suite
+        sFrame.pRSN->abyRSN[4] = 1;
+        sFrame.pRSN->abyRSN[5] = 0;
+        sFrame.pRSN->abyRSN[6] = 0x00;
+        sFrame.pRSN->abyRSN[7] = 0x0F;
+        sFrame.pRSN->abyRSN[8] = 0xAC;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
+        } else {
+            sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
+        }
+        sFrame.pRSN->len += 6;
+
+        // Auth Key Management Suite
+        sFrame.pRSN->abyRSN[10] = 1;
+        sFrame.pRSN->abyRSN[11] = 0;
+        sFrame.pRSN->abyRSN[12] = 0x00;
+        sFrame.pRSN->abyRSN[13] = 0x0F;
+        sFrame.pRSN->abyRSN[14] = 0xAC;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
+        } else {
+            sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
+        }
+        sFrame.pRSN->len +=6;
+
+        // RSN Capabilites
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+            memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+        } else {
+            sFrame.pRSN->abyRSN[16] = 0;
+            sFrame.pRSN->abyRSN[17] = 0;
+        }
+        sFrame.pRSN->len +=2;
+
+        if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+            // RSN PMKID
+            pbyRSN = &sFrame.pRSN->abyRSN[18];
+            pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
+            *pwPMKID = 0;            // Initialize PMKID count
+            pbyRSN += 2;             // Point to PMKID list
+            for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
+                if ( !memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                    (*pwPMKID) ++;
+                    memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
+                    pbyRSN += 16;
+                }
+            }
+            if (*pwPMKID != 0) {
+                sFrame.pRSN->len += (2 + (*pwPMKID)*16);
+            }
+        }
+
+        sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
+        pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+        memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
+        pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
+    }
+
+
+
+    /* Adjust the length fields */
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an assoc-response frame
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_ASSOCRESP   sFrame;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
+    vMgrEncodeAssocResponse(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+    *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
+    *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
+
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+           pCurrSuppRates,
+           ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+          );
+
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Constructs an reassoc-response frame
+ *
+ *
+ * Return Value:
+ *    PTR to frame; or NULL on allocation failue
+ *
+-*/
+
+
+PSTxMgmtPacket
+s_MgrMakeReAssocResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN WORD wCurrCapInfo,
+    IN WORD wAssocStatus,
+    IN WORD wAssocAID,
+    IN PBYTE pDstAddr,
+    IN PWLAN_IE_SUPP_RATES pCurrSuppRates,
+    IN PWLAN_IE_SUPP_RATES pCurrExtSuppRates
+    )
+{
+    PSTxMgmtPacket      pTxPacket = NULL;
+    WLAN_FR_REASSOCRESP   sFrame;
+
+
+    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
+    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
+    pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
+    // Setup the sFrame structure
+    sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
+    sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
+    vMgrEncodeReassocResponse(&sFrame);
+    // Setup the header
+    sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
+        (
+        WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
+        WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)
+        ));
+    memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
+    memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
+
+    *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
+    *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
+    *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
+
+    // Copy the rate set
+    sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+    sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
+    memcpy(sFrame.pSuppRates,
+             pCurrSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
+             );
+
+    if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
+        sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
+        sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
+        memcpy(sFrame.pExtSuppRates,
+             pCurrExtSuppRates,
+             ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
+             );
+    }
+
+    // Adjust the length fields
+    pTxPacket->cbMPDULen = sFrame.len;
+    pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
+
+    return pTxPacket;
+}
+
+
+/*+
+ *
+ * Routine Description:
+ *  Handles probe response management frames.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+static
+VOID
+s_vMgrRxProbeResponse(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    PKnownBSS           pBSSList = NULL;
+    WLAN_FR_PROBERESP   sFrame;
+    BYTE                byCurrChannel = pRxPacket->byRxChannel;
+    ERPObject           sERP;
+    BOOL                bChannelHit = TRUE;
+
+
+    memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
+    // decode the frame
+    sFrame.len = pRxPacket->cbMPDULen;
+    sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+    vMgrDecodeProbeResponse(&sFrame);
+
+    if ((sFrame.pqwTimestamp == 0) ||
+        (sFrame.pwBeaconInterval == 0) ||
+        (sFrame.pwCapInfo == 0) ||
+        (sFrame.pSSID == 0) ||
+        (sFrame.pSuppRates == 0)) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
+        DBG_PORT80(0xCC);
+        return;
+    };
+
+    if(sFrame.pSSID->len == 0)
+       DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
+
+
+    //{{ RobertYu:20050201, 11a  byCurrChannel != sFrame.pDSParms->byCurrChannel mapping
+    if( byCurrChannel > CB_MAX_CHANNEL_24G )
+    {
+        if (sFrame.pDSParms != 0) {
+            if (byCurrChannel == RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
+                bChannelHit = TRUE;
+            byCurrChannel = RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
+        } else {
+            bChannelHit = TRUE;
+        }
+
+    } else {
+        if (sFrame.pDSParms != 0) {
+            if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
+                bChannelHit = TRUE;
+            byCurrChannel = sFrame.pDSParms->byCurrChannel;
+        } else {
+            bChannelHit = TRUE;
+        }
+    }
+    //RobertYu:20050201
+
+//2008-0730-01<Add>by MikeLiu
+if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
+      return;
+
+    if (sFrame.pERP != NULL) {
+        sERP.byERP = sFrame.pERP->byContext;
+        sERP.bERPExist = TRUE;
+    } else {
+        sERP.bERPExist = FALSE;
+        sERP.byERP = 0;
+    }
+
+
+    // update or insert the bss
+    pBSSList = BSSpAddrIsInBSSList((HANDLE)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
+    if (pBSSList) {
+        BSSbUpdateToBSSList((HANDLE)pDevice,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            bChannelHit,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            pBSSList,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
+                            (HANDLE)pRxPacket
+                           );
+    }
+    else {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
+        BSSbInsertToBSSList((HANDLE)pDevice,
+                            sFrame.pHdr->sA3.abyAddr3,
+                            *sFrame.pqwTimestamp,
+                            *sFrame.pwBeaconInterval,
+                            *sFrame.pwCapInfo,
+                            byCurrChannel,
+                            sFrame.pSSID,
+                            sFrame.pSuppRates,
+                            sFrame.pExtSuppRates,
+                            &sERP,
+                            sFrame.pRSN,
+                            sFrame.pRSNWPA,
+                            sFrame.pIE_Country,
+                            sFrame.pIE_Quiet,
+                            sFrame.len - WLAN_HDR_ADDR3_LEN,
+                            sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
+                            (HANDLE)pRxPacket
+                           );
+    }
+    return;
+
+}
+
+/*+
+ *
+ * Routine Description:(AP)or(Ad-hoc STA)
+ *  Handles probe request management frames.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+static
+VOID
+s_vMgrRxProbeRequest(
+    IN PSDevice pDevice,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+    )
+{
+    WLAN_FR_PROBEREQ    sFrame;
+    CMD_STATUS          Status;
+    PSTxMgmtPacket      pTxPacket;
+    BYTE                byPHYType = BB_TYPE_11B;
+
+    // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
+    // STA have to response this request.
+    if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
+        ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) {
+
+        memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
+        // decode the frame
+        sFrame.len = pRxPacket->cbMPDULen;
+        sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
+        vMgrDecodeProbeRequest(&sFrame);
+/*
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n",
+                  sFrame.pHdr->sA3.abyAddr2[0],
+                  sFrame.pHdr->sA3.abyAddr2[1],
+                  sFrame.pHdr->sA3.abyAddr2[2],
+                  sFrame.pHdr->sA3.abyAddr2[3],
+                  sFrame.pHdr->sA3.abyAddr2[4],
+                  sFrame.pHdr->sA3.abyAddr2[5]
+                );
+*/
+        if (sFrame.pSSID->len != 0) {
+            if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)
+                return;
+            if (memcmp(sFrame.pSSID->abySSID,
+                       ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
+                       ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) {
+                       return;
+            }
+        }
+
+        if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) {
+            byPHYType = BB_TYPE_11G;
+        }
+
+        // Probe response reply..
+        pTxPacket = s_MgrMakeProbeResponse
+                    (
+                      pDevice,
+                      pMgmt,
+                      pMgmt->wCurrCapInfo,
+                      pMgmt->wCurrBeaconPeriod,
+                      pMgmt->uCurrChannel,
+                      0,
+                      sFrame.pHdr->sA3.abyAddr2,
+                      (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                      (PBYTE)pMgmt->abyCurrBSSID,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                      (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
+                       byPHYType
+                    );
+        if (pTxPacket != NULL ){
+            /* send the frame */
+            Status = csMgmt_xmit(pDevice, pTxPacket);
+            if (Status != CMD_STATUS_PENDING) {
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
+            }
+            else {
+//                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
+            }
+        }
+    }
+
+    return;
+}
+
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *  Entry point for the reception and handling of 802.11 management
+ *  frames. Makes a determination of the frame type and then calls
+ *  the appropriate function.
+ *
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+
+
+VOID
+vMgrRxManagePacket(
+    IN  HANDLE hDeviceContext,
+    IN PSMgmtObject pMgmt,
+    IN PSRxMgmtPacket pRxPacket
+     )
+{
+    PSDevice    pDevice = (PSDevice)hDeviceContext;
+    BOOL        bInScan = FALSE;
+    UINT        uNodeIndex = 0;
+    NODE_STATE  eNodeState = 0;
+    CMD_STATUS  Status;
+
+
+    if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
+        if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
+            eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState;
+    }
+
+    switch( WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) ){
+
+        case WLAN_FSTYPE_ASSOCREQ:
+            // Frame Clase = 2
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
+                (eNodeState < NODE_AUTH)) {
+                // send deauth notification
+                // reason = (6) class 2 received from nonauth sta
+                vMgrDeAuthenBeginSta(pDevice,
+                                     pMgmt,
+                                     pRxPacket->p80211Header->sA3.abyAddr2,
+                                     (6),
+                                     &Status
+                                     );
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
+            }
+            else {
+                s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
+            }
+            break;
+
+        case WLAN_FSTYPE_ASSOCRESP:
+            // Frame Clase = 2
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
+            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, FALSE);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
+            break;
+
+        case WLAN_FSTYPE_REASSOCREQ:
+            // Frame Clase = 2
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
+            // Todo: reassoc
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
+               (eNodeState < NODE_AUTH)) {
+                // send deauth notification
+                // reason = (6) class 2 received from nonauth sta
+                vMgrDeAuthenBeginSta(pDevice,
+                                     pMgmt,
+                                     pRxPacket->p80211Header->sA3.abyAddr2,
+                                     (6),
+                                     &Status
+                                     );
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
+
+            }
+            s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
+            break;
+
+        case WLAN_FSTYPE_REASSOCRESP:
+            // Frame Clase = 2
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
+            s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, TRUE);
+            break;
+
+        case WLAN_FSTYPE_PROBEREQ:
+            // Frame Clase = 0
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
+            s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_PROBERESP:
+            // Frame Clase = 0
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
+
+            s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_BEACON:
+            // Frame Clase = 0
+            //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
+            if (pMgmt->eScanState != WMAC_NO_SCANNING) {
+                bInScan = TRUE;
+            };
+            s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
+            break;
+
+        case WLAN_FSTYPE_ATIM:
+            // Frame Clase = 1
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
+            break;
+
+        case WLAN_FSTYPE_DISASSOC:
+            // Frame Clase = 2
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
+            if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
+                (eNodeState < NODE_AUTH)) {
+                // send deauth notification
+                // reason = (6) class 2 received from nonauth sta
+                vMgrDeAuthenBeginSta(pDevice,
+                                     pMgmt,
+                                     pRxPacket->p80211Header->sA3.abyAddr2,
+                                     (6),
+                                     &Status
+                                     );
+                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
+            }
+            s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_AUTHEN:
+            // Frame Clase = 1
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO  "rx authen\n");
+            s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
+            break;
+
+        case WLAN_FSTYPE_DEAUTHEN:
+            // Frame Clase = 1
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
+            s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
+            break;
+
+        default:
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
+    }
+
+    return;
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *
+ *  Prepare beacon to send
+ *
+ * Return Value:
+ *    TRUE if success; FALSE if failed.
+ *
+-*/
+BOOL
+bMgrPrepareBeaconToSend(
+    IN HANDLE hDeviceContext,
+    IN PSMgmtObject pMgmt
+    )
+{
+    PSDevice            pDevice = (PSDevice)hDeviceContext;
+    PSTxMgmtPacket      pTxPacket;
+
+//    pDevice->bBeaconBufReady = FALSE;
+    if (pDevice->bEncryptionEnable || pDevice->bEnable8021x){
+        pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+    else {
+        pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1);
+    }
+    pTxPacket = s_MgrMakeBeacon
+                (
+                  pDevice,
+                  pMgmt,
+                  pMgmt->wCurrCapInfo,
+                  pMgmt->wCurrBeaconPeriod,
+                  pMgmt->uCurrChannel,
+                  pMgmt->wCurrATIMWindow, //0,
+                  (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
+                  (PBYTE)pMgmt->abyCurrBSSID,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
+                  (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
+                );
+
+    if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
+        (pMgmt->abyCurrBSSID[0] == 0))
+        return FALSE;
+
+    csBeacon_xmit(pDevice, pTxPacket);
+    MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
+
+    return TRUE;
+}
+
+
+
+
+/*+
+ *
+ * Routine Description:
+ *
+ *  Log a warning message based on the contents of the Status
+ *  Code field of an 802.11 management frame.  Defines are
+ *  derived from 802.11-1997 SPEC.
+ *
+ * Return Value:
+ *    none.
+ *
+-*/
+static
+VOID
+s_vMgrLogStatus(
+    IN PSMgmtObject pMgmt,
+    IN WORD  wStatus
+    )
+{
+    switch( wStatus ){
+        case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
+            break;
+        case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
+            break;
+        case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
+            break;
+        case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
+            break;
+        case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
+            break;
+        case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge  failure.\n");
+            break;
+        case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
+            break;
+        case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
+            break;
+        default:
+            DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
+            break;
+    }
+}
+
+
+/*
+ *
+ * Description:
+ *    Add BSSID in PMKID Candidate list.
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *      pbyBSSID - BSSID address for adding
+ *      wRSNCap - BSS's RSN capability
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+bAdd_PMKID_Candidate (
+    IN HANDLE    hDeviceContext,
+    IN PBYTE          pbyBSSID,
+    IN PSRSNCapObject psRSNCapObj
+    )
+{
+    PSDevice         pDevice = (PSDevice)hDeviceContext;
+    PPMKID_CANDIDATE pCandidateList;
+    UINT             ii = 0;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+
+    if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
+        return FALSE;
+
+    if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
+        return FALSE;
+
+
+
+    // Update Old Candidate
+    for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
+        pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
+        if ( !memcmp(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN)) {
+            if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
+                pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
+            } else {
+                pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
+            }
+            return TRUE;
+        }
+    }
+
+    // New Candidate
+    pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
+    if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
+        pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
+    } else {
+        pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
+    }
+    memcpy(pCandidateList->BSSID, pbyBSSID, U_ETHER_ADDR_LEN);
+    pDevice->gsPMKIDCandidate.NumCandidates++;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
+    return TRUE;
+}
+
+/*
+ *
+ * Description:
+ *    Flush PMKID Candidate list.
+ *
+ * Parameters:
+ *  In:
+ *      hDeviceContext - device structure point
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+vFlush_PMKID_Candidate (
+    IN HANDLE hDeviceContext
+    )
+{
+    PSDevice        pDevice = (PSDevice)hDeviceContext;
+
+    if (pDevice == NULL)
+        return;
+
+    memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
+}
+
+static BOOL
+s_bCipherMatch (
+    IN PKnownBSS                        pBSSNode,
+    IN NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
+    OUT PBYTE                           pbyCCSPK,
+    OUT PBYTE                           pbyCCSGK
+    )
+{
+    BYTE byMulticastCipher = KEY_CTL_INVALID;
+    BYTE byCipherMask = 0x00;
+    int i;
+
+    if (pBSSNode == NULL)
+        return FALSE;
+
+    // check cap. of BSS
+    if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
+         (EncStatus == Ndis802_11Encryption1Enabled)) {
+        // default is WEP only
+        byMulticastCipher = KEY_CTL_WEP;
+    }
+
+    if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
+        (pBSSNode->bWPA2Valid == TRUE) &&
+          //20080123-01,<Add> by Einsn Liu
+        ((EncStatus == Ndis802_11Encryption3Enabled)||(EncStatus == Ndis802_11Encryption2Enabled))) {
+        //WPA2
+        // check Group Key Cipher
+        if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
+            (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) {
+            byMulticastCipher = KEY_CTL_WEP;
+        } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) {
+            byMulticastCipher = KEY_CTL_TKIP;
+        } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
+            byMulticastCipher = KEY_CTL_CCMP;
+        } else {
+            byMulticastCipher = KEY_CTL_INVALID;
+        }
+
+        // check Pairwise Key Cipher
+        for(i=0;i<pBSSNode->wCSSPKCount;i++) {
+            if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
+                (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
+                // this should not happen as defined 802.11i
+                byCipherMask |= 0x01;
+            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
+                byCipherMask |= 0x02;
+            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
+                byCipherMask |= 0x04;
+            } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
+                // use group key only ignore all others
+                byCipherMask = 0;
+                i = pBSSNode->wCSSPKCount;
+            }
+        }
+
+    } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
+                (pBSSNode->bWPAValid == TRUE) &&
+                ((EncStatus == Ndis802_11Encryption2Enabled) || (EncStatus == Ndis802_11Encryption3Enabled))) {
+        //WPA
+        // check Group Key Cipher
+        if ((pBSSNode->byGKType == WPA_WEP40) ||
+            (pBSSNode->byGKType == WPA_WEP104)) {
+            byMulticastCipher = KEY_CTL_WEP;
+        } else if (pBSSNode->byGKType == WPA_TKIP) {
+            byMulticastCipher = KEY_CTL_TKIP;
+        } else if (pBSSNode->byGKType == WPA_AESCCMP) {
+            byMulticastCipher = KEY_CTL_CCMP;
+        } else {
+            byMulticastCipher = KEY_CTL_INVALID;
+        }
+
+        // check Pairwise Key Cipher
+        for(i=0;i<pBSSNode->wPKCount;i++) {
+            if (pBSSNode->abyPKType[i] == WPA_TKIP) {
+                byCipherMask |= 0x02;
+            } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
+                byCipherMask |= 0x04;
+            } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
+                // use group key only ignore all others
+                byCipherMask = 0;
+                i = pBSSNode->wPKCount;
+            }
+        }
+    }
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%d, %d, %d, %d, EncStatus:%d\n",
+        byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
+
+    // mask our cap. with BSS
+    if (EncStatus == Ndis802_11Encryption1Enabled) {
+
+        // For supporting Cisco migration mode, don't care pairwise key cipher
+        //if ((byMulticastCipher == KEY_CTL_WEP) &&
+        //    (byCipherMask == 0)) {
+        if ((byMulticastCipher == KEY_CTL_WEP) &&
+            (byCipherMask == 0)) {
+            *pbyCCSGK = KEY_CTL_WEP;
+            *pbyCCSPK = KEY_CTL_NONE;
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+
+    } else if (EncStatus == Ndis802_11Encryption2Enabled) {
+        if ((byMulticastCipher == KEY_CTL_TKIP) &&
+            (byCipherMask == 0)) {
+            *pbyCCSGK = KEY_CTL_TKIP;
+            *pbyCCSPK = KEY_CTL_NONE;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_WEP) &&
+                   ((byCipherMask & 0x02) != 0)) {
+            *pbyCCSGK = KEY_CTL_WEP;
+            *pbyCCSPK = KEY_CTL_TKIP;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
+                   ((byCipherMask & 0x02) != 0)) {
+            *pbyCCSGK = KEY_CTL_TKIP;
+            *pbyCCSPK = KEY_CTL_TKIP;
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+    } else if (EncStatus == Ndis802_11Encryption3Enabled) {
+        if ((byMulticastCipher == KEY_CTL_CCMP) &&
+            (byCipherMask == 0)) {
+            // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
+            return FALSE;
+        } else if ((byMulticastCipher == KEY_CTL_WEP) &&
+                   ((byCipherMask & 0x04) != 0)) {
+            *pbyCCSGK = KEY_CTL_WEP;
+            *pbyCCSPK = KEY_CTL_CCMP;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
+                   ((byCipherMask & 0x04) != 0)) {
+            *pbyCCSGK = KEY_CTL_TKIP;
+            *pbyCCSPK = KEY_CTL_CCMP;
+            return TRUE;
+        } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
+                   ((byCipherMask & 0x04) != 0)) {
+            *pbyCCSGK = KEY_CTL_CCMP;
+            *pbyCCSPK = KEY_CTL_CCMP;
+            return TRUE;
+        } else {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+
diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h
new file mode 100644
index 0000000..c682a7f
--- /dev/null
+++ b/drivers/staging/vt6656/wmgr.h
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: wmgr.h
+ *
+ * Purpose:
+ *
+ * Author: lyndon chen
+ *
+ * Date: Jan 2, 2003
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#ifndef __WMGR_H__
+#define __WMGR_H__
+
+#include "ttype.h"
+#include "80211mgr.h"
+#include "80211hdr.h"
+#include "wcmd.h"
+#include "bssdb.h"
+#include "wpa2.h"
+#include "card.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+
+// Scan time
+#define PROBE_DELAY                  100  // (us)
+#define SWITCH_CHANNEL_DELAY         200 // (us)
+#define WLAN_SCAN_MINITIME           25   // (ms)
+#define WLAN_SCAN_MAXTIME            100  // (ms)
+#define TRIVIAL_SYNC_DIFFERENCE      0    // (us)
+#define DEFAULT_IBSS_BI              100  // (ms)
+
+#define WCMD_ACTIVE_SCAN_TIME   20 //(ms)
+#define WCMD_PASSIVE_SCAN_TIME  100 //(ms)
+
+
+#define DEFAULT_MSDU_LIFETIME           512  // ms
+#define DEFAULT_MSDU_LIFETIME_RES_64us  8000 // 64us
+
+#define DEFAULT_MGN_LIFETIME            8    // ms
+#define DEFAULT_MGN_LIFETIME_RES_64us   125  // 64us
+
+#define MAKE_BEACON_RESERVED            10  //(us)
+
+
+#define TIM_MULTICAST_MASK           0x01
+#define TIM_BITMAPOFFSET_MASK        0xFE
+#define DEFAULT_DTIM_PERIOD             1
+
+#define AP_LONG_RETRY_LIMIT             4
+
+#define DEFAULT_IBSS_CHANNEL            6  //2.4G
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+//mike define: make timer  to expire after desired times
+#define timer_expire(timer,next_tick)   mod_timer(&timer, RUN_AT(next_tick))
+
+typedef void (*TimerFunction)(ULONG);
+
+
+//+++ NDIS related
+
+typedef UCHAR   NDIS_802_11_MAC_ADDRESS[6];
+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 tagSAssocInfo {
+    NDIS_802_11_ASSOCIATION_INFORMATION     AssocInfo;
+    BYTE                                    abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN];
+    // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION
+    ULONG                                   RequestIELength;
+    BYTE                                    abyReqIEs[WLAN_BEACON_FR_MAXLEN];
+} SAssocInfo, *PSAssocInfo;
+//---
+
+
+
+typedef enum tagWMAC_AUTHENTICATION_MODE {
+
+    WMAC_AUTH_OPEN,
+    WMAC_AUTH_SHAREKEY,
+    WMAC_AUTH_AUTO,
+    WMAC_AUTH_WPA,
+    WMAC_AUTH_WPAPSK,
+    WMAC_AUTH_WPANONE,
+    WMAC_AUTH_WPA2,
+    WMAC_AUTH_WPA2PSK,
+    WMAC_AUTH_MAX       // Not a real mode, defined as upper bound
+} WMAC_AUTHENTICATION_MODE, *PWMAC_AUTHENTICATION_MODE;
+
+
+
+// Pre-configured Mode (from XP)
+
+typedef enum tagWMAC_CONFIG_MODE {
+    WMAC_CONFIG_ESS_STA,
+    WMAC_CONFIG_IBSS_STA,
+    WMAC_CONFIG_AUTO,
+    WMAC_CONFIG_AP
+
+} WMAC_CONFIG_MODE, *PWMAC_CONFIG_MODE;
+
+
+typedef enum tagWMAC_SCAN_TYPE {
+
+    WMAC_SCAN_ACTIVE,
+    WMAC_SCAN_PASSIVE,
+    WMAC_SCAN_HYBRID
+
+} WMAC_SCAN_TYPE, *PWMAC_SCAN_TYPE;
+
+
+typedef enum tagWMAC_SCAN_STATE {
+
+    WMAC_NO_SCANNING,
+    WMAC_IS_SCANNING,
+    WMAC_IS_PROBEPENDING
+
+} WMAC_SCAN_STATE, *PWMAC_SCAN_STATE;
+
+
+
+// Notes:
+// Basic Service Set state explained as following:
+// WMAC_STATE_IDLE          : no BSS is selected (Adhoc or Infra)
+// WMAC_STATE_STARTED       : no BSS is selected, start own IBSS (Adhoc only)
+// WMAC_STATE_JOINTED       : BSS is selected and synchronized (Adhoc or Infra)
+// WMAC_STATE_AUTHPENDING   : Authentication pending (Infra)
+// WMAC_STATE_AUTH          : Authenticated (Infra)
+// WMAC_STATE_ASSOCPENDING  : Association pending (Infra)
+// WMAC_STATE_ASSOC         : Associated (Infra)
+
+typedef enum tagWMAC_BSS_STATE {
+
+    WMAC_STATE_IDLE,
+    WMAC_STATE_STARTED,
+    WMAC_STATE_JOINTED,
+    WMAC_STATE_AUTHPENDING,
+    WMAC_STATE_AUTH,
+    WMAC_STATE_ASSOCPENDING,
+    WMAC_STATE_ASSOC
+
+} WMAC_BSS_STATE, *PWMAC_BSS_STATE;
+
+// WMAC selected running mode
+typedef enum tagWMAC_CURRENT_MODE {
+
+    WMAC_MODE_STANDBY,
+    WMAC_MODE_ESS_STA,
+    WMAC_MODE_IBSS_STA,
+    WMAC_MODE_ESS_AP
+
+} WMAC_CURRENT_MODE, *PWMAC_CURRENT_MODE;
+
+
+typedef enum tagWMAC_POWER_MODE {
+
+    WMAC_POWER_CAM,
+    WMAC_POWER_FAST,
+    WMAC_POWER_MAX
+
+} WMAC_POWER_MODE, *PWMAC_POWER_MODE;
+
+
+
+// Tx Managment Packet descriptor
+typedef struct tagSTxMgmtPacket {
+
+    PUWLAN_80211HDR     p80211Header;
+    UINT                cbMPDULen;
+    UINT                cbPayloadLen;
+
+} STxMgmtPacket, *PSTxMgmtPacket;
+
+
+// Rx Managment Packet descriptor
+typedef struct tagSRxMgmtPacket {
+
+    PUWLAN_80211HDR     p80211Header;
+    QWORD               qwLocalTSF;
+    UINT                cbMPDULen;
+    UINT                cbPayloadLen;
+    UINT                uRSSI;
+    BYTE                bySQ;
+    BYTE                byRxRate;
+    BYTE                byRxChannel;
+
+} SRxMgmtPacket, *PSRxMgmtPacket;
+
+
+
+typedef struct tagSMgmtObject
+{
+
+    PVOID                   pAdapter;
+    // MAC address
+    BYTE                    abyMACAddr[WLAN_ADDR_LEN];
+
+    // Configuration Mode
+    WMAC_CONFIG_MODE        eConfigMode; // MAC pre-configed mode
+
+    CARD_PHY_TYPE           eCurrentPHYMode;
+
+
+    // Operation state variables
+    WMAC_CURRENT_MODE       eCurrMode;   // MAC current connection mode
+    WMAC_BSS_STATE          eCurrState;  // MAC current BSS state
+    #ifdef SndEvt_ToAPI
+    WMAC_BSS_STATE          eLastState;  // MAC last BSS state
+    #endif
+
+    PKnownBSS               pCurrBSS;
+    BYTE                    byCSSGK;
+    BYTE                    byCSSPK;
+
+//    BYTE                    abyNewSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+//    BYTE                    abyNewExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN];
+    BOOL                    bCurrBSSIDFilterOn;
+
+    // Current state vars
+    UINT                    uCurrChannel;
+    BYTE                    abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                    abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                    abyCurrSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE                    abyCurrBSSID[WLAN_BSSID_LEN];
+    WORD                    wCurrCapInfo;
+    WORD                    wCurrAID;
+    UINT                    uRSSITrigger;
+    WORD                    wCurrATIMWindow;
+    WORD                    wCurrBeaconPeriod;
+    BOOL                    bIsDS;
+    BYTE                    byERPContext;
+
+    CMD_STATE               eCommandState;
+    UINT                    uScanChannel;
+
+    // Desire joinning BSS vars
+    BYTE                    abyDesireSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE                    abyDesireBSSID[WLAN_BSSID_LEN];
+
+//restore BSS info for Ad-Hoc mode
+//20080131-05,<Add> by Mike Liu
+#ifdef Adhoc_STA
+     BYTE                    abyAdHocSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+#endif
+
+    // Adhoc or AP configuration vars
+    WORD                    wIBSSBeaconPeriod;
+    WORD                    wIBSSATIMWindow;
+    UINT                    uIBSSChannel;
+    BYTE                    abyIBSSSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
+    BYTE                    byAPBBType;
+    BYTE                    abyWPAIE[MAX_WPA_IE_LEN];
+    WORD                    wWPAIELen;
+
+    UINT                    uAssocCount;
+    BOOL                    bMoreData;
+
+    // Scan state vars
+    WMAC_SCAN_STATE         eScanState;
+    WMAC_SCAN_TYPE          eScanType;
+    UINT                    uScanStartCh;
+    UINT                    uScanEndCh;
+    WORD                    wScanSteps;
+    UINT                    uScanBSSType;
+    // Desire scannig vars
+    BYTE                    abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1];
+    BYTE                    abyScanBSSID[WLAN_BSSID_LEN];
+
+    // Privacy
+    WMAC_AUTHENTICATION_MODE eAuthenMode;
+    BOOL                    bShareKeyAlgorithm;
+    BYTE                    abyChallenge[WLAN_CHALLENGE_LEN];
+    BOOL                    bPrivacyInvoked;
+
+    // Received beacon state vars
+    BOOL                    bInTIM;
+    BOOL                    bMulticastTIM;
+    BYTE                    byDTIMCount;
+    BYTE                    byDTIMPeriod;
+
+    // Power saving state vars
+    WMAC_POWER_MODE         ePSMode;
+    WORD                    wListenInterval;
+    WORD                    wCountToWakeUp;
+    BOOL                    bInTIMWake;
+    PBYTE                   pbyPSPacketPool;
+    BYTE                    byPSPacketPool[sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN];
+    BOOL                    bRxBeaconInTBTTWake;
+    BYTE                    abyPSTxMap[MAX_NODE_NUM + 1];
+
+    // managment command related
+    UINT                    uCmdBusy;
+    UINT                    uCmdHostAPBusy;
+
+    // managment packet pool
+    PBYTE                   pbyMgmtPacketPool;
+    BYTE                    byMgmtPacketPool[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+
+
+    // One second callback timer
+	struct timer_list	    sTimerSecondCallback;
+
+    // Temporarily Rx Mgmt Packet Descriptor
+    SRxMgmtPacket           sRxPacket;
+
+    // link list of known bss's (scan results)
+    KnownBSS                sBSSList[MAX_BSS_NUM];
+   //link list of same bss's  //DavidWang
+    KnownBSS				pSameBSS[6] ;
+    BOOL          Cisco_cckm ;
+    BYTE          Roam_dbm;
+
+    // table list of known node
+    // sNodeDBList[0] is reserved for AP under Infra mode
+    // sNodeDBList[0] is reserved for Multicast under adhoc/AP mode
+    KnownNodeDB             sNodeDBTable[MAX_NODE_NUM + 1];
+
+
+
+    // WPA2 PMKID Cache
+    SPMKIDCache             gsPMKIDCache;
+    BOOL                    bRoaming;
+
+    // rate fall back vars
+
+
+
+    // associate info
+    SAssocInfo              sAssocInfo;
+
+
+    // for 802.11h
+    BOOL                    b11hEnable;
+    BOOL                    bSwitchChannel;
+    BYTE                    byNewChannel;
+    PWLAN_IE_MEASURE_REP    pCurrMeasureEIDRep;
+    UINT                    uLengthOfRepEIDs;
+    BYTE                    abyCurrentMSRReq[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+    BYTE                    abyCurrentMSRRep[sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN];
+    BYTE                    abyIECountry[WLAN_A3FR_MAXLEN];
+    BYTE                    abyIBSSDFSOwner[6];
+    BYTE                    byIBSSDFSRecovery;
+
+    struct sk_buff  skb;
+
+} SMgmtObject, *PSMgmtObject;
+
+
+/*---------------------  Export Macros ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+
+void
+vMgrObjectInit(
+    IN  HANDLE hDeviceContext
+    );
+
+
+void
+vMgrAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrReAssocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrDisassocBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    IN  PBYTE  abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrCreateOwnIBSS(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrJoinBSSBegin(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    );
+
+VOID
+vMgrRxManagePacket(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt,
+    IN  PSRxMgmtPacket pRxPacket
+    );
+
+/*
+VOID
+vMgrScanBegin(
+    IN  HANDLE hDeviceContext,
+    OUT PCMD_STATUS pStatus
+    );
+*/
+
+VOID
+vMgrDeAuthenBeginSta(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject  pMgmt,
+    IN  PBYTE   abyDestAddress,
+    IN  WORD    wReason,
+    OUT PCMD_STATUS pStatus
+    );
+
+BOOL
+bMgrPrepareBeaconToSend(
+    IN  HANDLE hDeviceContext,
+    IN  PSMgmtObject pMgmt
+    );
+
+
+BOOL
+bAdd_PMKID_Candidate (
+    IN HANDLE    hDeviceContext,
+    IN PBYTE          pbyBSSID,
+    IN PSRSNCapObject psRSNCapObj
+    );
+
+VOID
+vFlush_PMKID_Candidate (
+    IN HANDLE hDeviceContext
+    );
+
+#endif // __WMGR_H__
diff --git a/drivers/staging/vt6656/wpa.c b/drivers/staging/vt6656/wpa.c
new file mode 100644
index 0000000..f92d33f
--- /dev/null
+++ b/drivers/staging/vt6656/wpa.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: wpa.c
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Functions:
+ *      WPA_ParseRSN - Parse RSN IE.
+ *
+ * Revision History:
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: July 14, 2003
+ *
+ */
+
+#include "ttype.h"
+#include "tmacro.h"
+#include "tether.h"
+#include "device.h"
+#include "80211hdr.h"
+#include "bssdb.h"
+#include "wmgr.h"
+#include "wpa.h"
+#include "80211mgr.h"
+
+/*---------------------  Static Variables  --------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+
+const BYTE abyOUI00[4] = { 0x00, 0x50, 0xf2, 0x00 };
+const BYTE abyOUI01[4] = { 0x00, 0x50, 0xf2, 0x01 };
+const BYTE abyOUI02[4] = { 0x00, 0x50, 0xf2, 0x02 };
+const BYTE abyOUI03[4] = { 0x00, 0x50, 0xf2, 0x03 };
+const BYTE abyOUI04[4] = { 0x00, 0x50, 0xf2, 0x04 };
+const BYTE abyOUI05[4] = { 0x00, 0x50, 0xf2, 0x05 };
+
+
+/*+
+ *
+ * Description:
+ *    Clear RSN information in BSSList.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSList - BSS list.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+
+VOID
+WPA_ClearRSN (
+    IN PKnownBSS        pBSSList
+    )
+{
+    int ii;
+    pBSSList->byGKType = WPA_TKIP;
+    for (ii=0; ii < 4; ii ++)
+        pBSSList->abyPKType[ii] = WPA_TKIP;
+    pBSSList->wPKCount = 0;
+    for (ii=0; ii < 4; ii ++)
+        pBSSList->abyAuthType[ii] = WPA_AUTH_IEEE802_1X;
+    pBSSList->wAuthCount = 0;
+    pBSSList->byDefaultK_as_PK = 0;
+    pBSSList->byReplayIdx = 0;
+    pBSSList->sRSNCapObj.bRSNCapExist = FALSE;
+    pBSSList->sRSNCapObj.wRSNCap = 0;
+    pBSSList->bWPAValid = FALSE;
+}
+
+
+/*+
+ *
+ * Description:
+ *    Parse RSN IE.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSList - BSS list.
+ *      pRSN - Pointer to the RSN IE.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+WPA_ParseRSN (
+    IN PKnownBSS        pBSSList,
+    IN PWLAN_IE_RSN_EXT pRSN
+    )
+{
+    PWLAN_IE_RSN_AUTH  pIE_RSN_Auth = NULL;
+    int                i, j, m, n = 0;
+    PBYTE              pbyCaps;
+
+    WPA_ClearRSN(pBSSList);
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA_ParseRSN: [%d]\n", pRSN->len);
+
+    // information element header makes sense
+    if ((pRSN->len >= 6) // oui1(4)+ver(2)
+         && (pRSN->byElementID == WLAN_EID_RSN_WPA) &&  !memcmp(pRSN->abyOUI, abyOUI01, 4)
+         && (pRSN->wVersion == 1)) {
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal RSN\n");
+        // update each variable if pRSN is long enough to contain the variable
+        if (pRSN->len >= 10) //oui1(4)+ver(2)+GKSuite(4)
+        {
+            if ( !memcmp(pRSN->abyMulticast, abyOUI01, 4))
+                pBSSList->byGKType = WPA_WEP40;
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI02, 4))
+                pBSSList->byGKType = WPA_TKIP;
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI03, 4))
+                pBSSList->byGKType = WPA_AESWRAP;
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI04, 4))
+                pBSSList->byGKType = WPA_AESCCMP;
+            else if ( !memcmp(pRSN->abyMulticast, abyOUI05, 4))
+                pBSSList->byGKType = WPA_WEP104;
+            else
+                // any vendor checks here
+                pBSSList->byGKType = WPA_NONE;
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byGKType: %x\n", pBSSList->byGKType);
+        }
+
+        if (pRSN->len >= 12) //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)
+        {
+            j = 0;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d, sizeof(pBSSList->abyPKType): %ld\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType));
+            for(i = 0; (i < pRSN->wPKCount) && (j < sizeof(pBSSList->abyPKType)/sizeof(BYTE)); i++) {
+                if(pRSN->len >= 12+i*4+4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*i)
+                    if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI00, 4))
+                        pBSSList->abyPKType[j++] = WPA_NONE;
+                    else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI02, 4))
+                        pBSSList->abyPKType[j++] = WPA_TKIP;
+                    else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI03, 4))
+                        pBSSList->abyPKType[j++] = WPA_AESWRAP;
+                    else if ( !memcmp(pRSN->PKSList[i].abyOUI, abyOUI04, 4))
+                        pBSSList->abyPKType[j++] = WPA_AESCCMP;
+                    else
+                        // any vendor checks here
+                        ;
+                }
+                else
+                    break;
+                //DBG_PRN_GRP14(("abyPKType[%d]: %X\n", j-1, pBSSList->abyPKType[j-1]));
+            } //for
+            pBSSList->wPKCount = (WORD)j;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wPKCount: %d\n", pBSSList->wPKCount);
+        }
+
+        m = pRSN->wPKCount;
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"m: %d\n", m);
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+m*4: %d\n", 14+m*4);
+
+        if (pRSN->len >= 14+m*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)
+            // overlay IE_RSN_Auth structure into correct place
+            pIE_RSN_Auth = (PWLAN_IE_RSN_AUTH) pRSN->PKSList[m].abyOUI;
+            j = 0;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d, sizeof(pBSSList->abyAuthType): %ld\n",
+                          pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType));
+            for(i = 0; (i < pIE_RSN_Auth->wAuthCount) && (j < sizeof(pBSSList->abyAuthType)/sizeof(BYTE)); i++) {
+                if(pRSN->len >= 14+4+(m+i)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*i)
+                    if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI01, 4))
+                        pBSSList->abyAuthType[j++] = WPA_AUTH_IEEE802_1X;
+                    else if ( !memcmp(pIE_RSN_Auth->AuthKSList[i].abyOUI, abyOUI02, 4))
+                        pBSSList->abyAuthType[j++] = WPA_AUTH_PSK;
+                    else
+                    // any vendor checks here
+                    ;
+                }
+                else
+                    break;
+                //DBG_PRN_GRP14(("abyAuthType[%d]: %X\n", j-1, pBSSList->abyAuthType[j-1]));
+            }
+            if(j > 0)
+                pBSSList->wAuthCount = (WORD)j;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAuthCount: %d\n", pBSSList->wAuthCount);
+        }
+
+        if (pIE_RSN_Auth != NULL) {
+
+            n = pIE_RSN_Auth->wAuthCount;
+
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"n: %d\n", n);
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"14+4+(m+n)*4: %d\n", 14+4+(m+n)*4);
+
+            if(pRSN->len+2 >= 14+4+(m+n)*4) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2)+PKS(4*m)+AKC(2)+AKS(4*n)+Cap(2)
+                pbyCaps = (PBYTE)pIE_RSN_Auth->AuthKSList[n].abyOUI;
+                pBSSList->byDefaultK_as_PK = (*pbyCaps) & WPA_GROUPFLAG;
+                pBSSList->byReplayIdx = 2 << ((*pbyCaps >> WPA_REPLAYBITSSHIFT) & WPA_REPLAYBITS);
+                pBSSList->sRSNCapObj.bRSNCapExist = TRUE;
+                pBSSList->sRSNCapObj.wRSNCap = *(PWORD)pbyCaps;
+                //DBG_PRN_GRP14(("pbyCaps: %X\n", *pbyCaps));
+                //DBG_PRN_GRP14(("byDefaultK_as_PK: %X\n", pBSSList->byDefaultK_as_PK));
+                //DBG_PRN_GRP14(("byReplayIdx: %X\n", pBSSList->byReplayIdx));
+            }
+        }
+        pBSSList->bWPAValid = TRUE;
+    }
+}
+
+/*+
+ *
+ * Description:
+ *    Search RSN information in BSSList.
+ *
+ * Parameters:
+ *  In:
+ *      byCmd    - Search type
+ *      byEncrypt- Encrcypt Type
+ *      pBSSList - BSS list
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+WPA_SearchRSN (
+    BYTE                byCmd,
+    BYTE                byEncrypt,
+    IN PKnownBSS        pBSSList
+    )
+{
+    int ii;
+    BYTE byPKType = WPA_NONE;
+
+    if (pBSSList->bWPAValid == FALSE)
+        return FALSE;
+
+    switch(byCmd) {
+    case 0:
+
+        if (byEncrypt != pBSSList->byGKType)
+            return FALSE;
+
+        if (pBSSList->wPKCount > 0) {
+            for (ii = 0; ii < pBSSList->wPKCount; ii ++) {
+                if (pBSSList->abyPKType[ii] == WPA_AESCCMP)
+                    byPKType = WPA_AESCCMP;
+                else if ((pBSSList->abyPKType[ii] == WPA_TKIP) && (byPKType != WPA_AESCCMP))
+                     byPKType = WPA_TKIP;
+                else if ((pBSSList->abyPKType[ii] == WPA_WEP40) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP))
+                     byPKType = WPA_WEP40;
+                else if ((pBSSList->abyPKType[ii] == WPA_WEP104) && (byPKType != WPA_AESCCMP) && (byPKType != WPA_TKIP))
+                     byPKType = WPA_WEP104;
+            }
+            if (byEncrypt != byPKType)
+                return FALSE;
+        }
+        return TRUE;
+//        if (pBSSList->wAuthCount > 0)
+//            for (ii=0; ii < pBSSList->wAuthCount; ii ++)
+//                if (byAuth == pBSSList->abyAuthType[ii])
+//                    break;
+        break;
+
+    default:
+        break;
+    }
+    return FALSE;
+}
+
+/*+
+ *
+ * Description:
+ *    Check if RSN IE makes sense.
+ *
+ * Parameters:
+ *  In:
+ *      pRSN - Pointer to the RSN IE.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+BOOL
+WPAb_Is_RSN (
+    IN PWLAN_IE_RSN_EXT pRSN
+    )
+{
+    if (pRSN == NULL)
+        return FALSE;
+
+    if ((pRSN->len >= 6) && // oui1(4)+ver(2)
+        (pRSN->byElementID == WLAN_EID_RSN_WPA) &&  !memcmp(pRSN->abyOUI, abyOUI01, 4) &&
+        (pRSN->wVersion == 1)) {
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
diff --git a/drivers/staging/vt6656/wpa.h b/drivers/staging/vt6656/wpa.h
new file mode 100644
index 0000000..9d9ce01
--- /dev/null
+++ b/drivers/staging/vt6656/wpa.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: wpa.h
+ *
+ * Purpose: Defines the macros, types, and functions for dealing
+ *          with WPA informations.
+ *
+ * Author: Kyle Hsu
+ *
+ * Date: Jul 14, 2003
+ *
+ */
+
+#ifndef __WPA_H__
+#define __WPA_H__
+
+#include "ttype.h"
+#include "80211hdr.h"
+
+/*---------------------  Export Definitions -------------------------*/
+
+#define WPA_NONE            0
+#define WPA_WEP40           1
+#define WPA_TKIP            2
+#define WPA_AESWRAP         3
+#define WPA_AESCCMP         4
+#define WPA_WEP104          5
+#define WPA_AUTH_IEEE802_1X 1
+#define WPA_AUTH_PSK        2
+
+#define WPA_GROUPFLAG       0x02
+#define WPA_REPLAYBITSSHIFT 2
+#define WPA_REPLAYBITS      0x03
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+
+/*---------------------  Export Functions  --------------------------*/
+
+VOID
+WPA_ClearRSN(
+    IN PKnownBSS        pBSSList
+    );
+
+VOID
+WPA_ParseRSN(
+    IN PKnownBSS        pBSSList,
+    IN PWLAN_IE_RSN_EXT pRSN
+    );
+
+BOOL
+WPA_SearchRSN(
+    BYTE                byCmd,
+    BYTE                byEncrypt,
+    IN PKnownBSS        pBSSList
+    );
+
+BOOL
+WPAb_Is_RSN(
+    IN PWLAN_IE_RSN_EXT pRSN
+    );
+
+#endif // __WPA_H__
diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c
new file mode 100644
index 0000000..fa3aeed
--- /dev/null
+++ b/drivers/staging/vt6656/wpa2.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: wpa2.c
+ *
+ * Purpose: Handles the Basic Service Set & Node Database functions
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ * Author: Yiching Chen
+ *
+ * Date: Oct. 4, 2004
+ *
+ */
+
+#include "wpa2.h"
+#include "device.h"
+
+/*---------------------  Static Definitions -------------------------*/
+static int          msglevel                =MSG_LEVEL_INFO;
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+
+const BYTE abyOUIGK[4]      = { 0x00, 0x0F, 0xAC, 0x00 };
+const BYTE abyOUIWEP40[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+const BYTE abyOUIWEP104[4]  = { 0x00, 0x0F, 0xAC, 0x05 };
+const BYTE abyOUITKIP[4]    = { 0x00, 0x0F, 0xAC, 0x02 };
+const BYTE abyOUICCMP[4]    = { 0x00, 0x0F, 0xAC, 0x04 };
+
+const BYTE abyOUI8021X[4]   = { 0x00, 0x0F, 0xAC, 0x01 };
+const BYTE abyOUIPSK[4]     = { 0x00, 0x0F, 0xAC, 0x02 };
+
+
+/*---------------------  Static Functions  --------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+/*+
+ *
+ * Description:
+ *    Clear RSN information in BSSList.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSNode - BSS list.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+WPA2_ClearRSN (
+    IN PKnownBSS        pBSSNode
+    )
+{
+    int ii;
+
+    pBSSNode->bWPA2Valid = FALSE;
+
+    pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
+    for (ii=0; ii < 4; ii ++)
+        pBSSNode->abyCSSPK[ii] = WLAN_11i_CSS_CCMP;
+    pBSSNode->wCSSPKCount = 1;
+    for (ii=0; ii < 4; ii ++)
+        pBSSNode->abyAKMSSAuthType[ii] = WLAN_11i_AKMSS_802_1X;
+    pBSSNode->wAKMSSAuthCount = 1;
+    pBSSNode->sRSNCapObj.bRSNCapExist = FALSE;
+    pBSSNode->sRSNCapObj.wRSNCap = 0;
+}
+
+/*+
+ *
+ * Description:
+ *    Parse RSN IE.
+ *
+ * Parameters:
+ *  In:
+ *      pBSSNode - BSS list.
+ *      pRSN - Pointer to the RSN IE.
+ *  Out:
+ *      none
+ *
+ * Return Value: none.
+ *
+-*/
+VOID
+WPA2vParseRSN (
+    IN PKnownBSS        pBSSNode,
+    IN PWLAN_IE_RSN     pRSN
+    )
+{
+    int                 i, j;
+    WORD                m = 0, n = 0;
+    PBYTE               pbyOUI;
+    BOOL                bUseGK = FALSE;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"WPA2_ParseRSN: [%d]\n", pRSN->len);
+
+    WPA2_ClearRSN(pBSSNode);
+
+    if (pRSN->len == 2) { // ver(2)
+        if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) {
+            pBSSNode->bWPA2Valid = TRUE;
+        }
+        return;
+    }
+
+    if (pRSN->len < 6) { // ver(2) + GK(4)
+        // invalid CSS, P802.11i/D10.0, p31
+        return;
+    }
+
+    // information element header makes sense
+    if ((pRSN->byElementID == WLAN_EID_RSN) &&
+        (pRSN->wVersion == 1)) {
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Legal 802.11i RSN\n");
+
+        pbyOUI = &(pRSN->abyRSN[0]);
+        if ( !memcmp(pbyOUI, abyOUIWEP40, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_WEP40;
+        else if ( !memcmp(pbyOUI, abyOUITKIP, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_TKIP;
+        else if ( !memcmp(pbyOUI, abyOUICCMP, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_CCMP;
+        else if ( !memcmp(pbyOUI, abyOUIWEP104, 4))
+            pBSSNode->byCSSGK = WLAN_11i_CSS_WEP104;
+        else if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
+            // invalid CSS, P802.11i/D10.0, p32
+            return;
+        } else
+            // any vendor checks here
+            pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN;
+
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"802.11i CSS: %X\n", pBSSNode->byCSSGK);
+
+        if (pRSN->len == 6) {
+            pBSSNode->bWPA2Valid = TRUE;
+            return;
+        }
+
+        if (pRSN->len >= 8) { // ver(2) + GK(4) + PK count(2)
+            pBSSNode->wCSSPKCount = *((PWORD) &(pRSN->abyRSN[4]));
+            j = 0;
+            pbyOUI = &(pRSN->abyRSN[6]);
+
+            for (i = 0; (i < pBSSNode->wCSSPKCount) && (j < sizeof(pBSSNode->abyCSSPK)/sizeof(BYTE)); i++) {
+
+                if (pRSN->len >= 8+i*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*i)
+                    if ( !memcmp(pbyOUI, abyOUIGK, 4)) {
+                        pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_USE_GROUP;
+                        bUseGK = TRUE;
+                    } else if ( !memcmp(pbyOUI, abyOUIWEP40, 4)) {
+                        // Invialid CSS, continue to parsing
+                    } else if ( !memcmp(pbyOUI, abyOUITKIP, 4)) {
+                        if (pBSSNode->byCSSGK != WLAN_11i_CSS_CCMP)
+                            pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_TKIP;
+                        else
+                            ; // Invialid CSS, continue to parsing
+                    } else if ( !memcmp(pbyOUI, abyOUICCMP, 4)) {
+                        pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_CCMP;
+                    } else if ( !memcmp(pbyOUI, abyOUIWEP104, 4)) {
+                        // Invialid CSS, continue to parsing
+                    } else {
+                        // any vendor checks here
+                        pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN;
+                    }
+                    pbyOUI += 4;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]);
+                } else
+                    break;
+            } //for
+
+            if (bUseGK == TRUE) {
+                if (j != 1) {
+                    // invalid CSS, This should be only PK CSS.
+                    return;
+                }
+                if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
+                    // invalid CSS, If CCMP is enable , PK can't be CSSGK.
+                    return;
+                }
+            }
+            if ((pBSSNode->wCSSPKCount != 0) && (j == 0)) {
+                // invalid CSS, No valid PK.
+                return;
+            }
+            pBSSNode->wCSSPKCount = (WORD)j;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wCSSPKCount: %d\n", pBSSNode->wCSSPKCount);
+        }
+
+        m = *((PWORD) &(pRSN->abyRSN[4]));
+
+        if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2)
+            pBSSNode->wAKMSSAuthCount = *((PWORD) &(pRSN->abyRSN[6+4*m]));;
+            j = 0;
+            pbyOUI = &(pRSN->abyRSN[8+4*m]);
+            for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(BYTE)); i++) {
+                if (pRSN->len >= 10+(m+i)*4+4) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSS(2)+AKS(4*i)
+                    if ( !memcmp(pbyOUI, abyOUI8021X, 4))
+                        pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_802_1X;
+                    else if ( !memcmp(pbyOUI, abyOUIPSK, 4))
+                        pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_PSK;
+                    else
+                        // any vendor checks here
+                        pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN;
+                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]);
+                } else
+                    break;
+            }
+            pBSSNode->wAKMSSAuthCount = (WORD)j;
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount);
+
+            n = *((PWORD) &(pRSN->abyRSN[6+4*m]));;
+            if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2)
+                pBSSNode->sRSNCapObj.bRSNCapExist = TRUE;
+                pBSSNode->sRSNCapObj.wRSNCap = *((PWORD) &(pRSN->abyRSN[8+4*m+4*n]));
+            }
+        }
+        //ignore PMKID lists bcs only (Re)Assocrequest has this field
+        pBSSNode->bWPA2Valid = TRUE;
+    }
+}
+
+
+/*+
+ *
+ * Description:
+ *    Set WPA IEs
+ *
+ * Parameters:
+ *  In:
+ *      pMgmtHandle - Pointer to management object
+ *  Out:
+ *      pRSNIEs     - Pointer to the RSN IE to set.
+ *
+ * Return Value: length of IEs.
+ *
+-*/
+UINT
+WPA2uSetIEs(
+    IN PVOID pMgmtHandle,
+    OUT PWLAN_IE_RSN pRSNIEs
+    )
+{
+    PSMgmtObject    pMgmt = (PSMgmtObject) pMgmtHandle;
+    PBYTE           pbyBuffer = NULL;
+    UINT            ii = 0;
+    PWORD           pwPMKID = NULL;
+
+    if (pRSNIEs == NULL) {
+        return(0);
+    }
+    if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
+         (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
+        (pMgmt->pCurrBSS != NULL)) {
+        /* WPA2 IE */
+        pbyBuffer = (PBYTE) pRSNIEs;
+        pRSNIEs->byElementID = WLAN_EID_RSN;
+        pRSNIEs->len = 6; //Version(2)+GK(4)
+        pRSNIEs->wVersion = 1;
+        //Group Key Cipher Suite
+        pRSNIEs->abyRSN[0] = 0x00;
+        pRSNIEs->abyRSN[1] = 0x0F;
+        pRSNIEs->abyRSN[2] = 0xAC;
+        if (pMgmt->byCSSGK == KEY_CTL_WEP) {
+            pRSNIEs->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
+        } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
+            pRSNIEs->abyRSN[3] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
+            pRSNIEs->abyRSN[3] = WLAN_11i_CSS_CCMP;
+        } else {
+            pRSNIEs->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
+        }
+
+        // Pairwise Key Cipher Suite
+        pRSNIEs->abyRSN[4] = 1;
+        pRSNIEs->abyRSN[5] = 0;
+        pRSNIEs->abyRSN[6] = 0x00;
+        pRSNIEs->abyRSN[7] = 0x0F;
+        pRSNIEs->abyRSN[8] = 0xAC;
+        if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_TKIP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_CCMP;
+        } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
+        } else {
+            pRSNIEs->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
+        }
+        pRSNIEs->len += 6;
+
+        // Auth Key Management Suite
+        pRSNIEs->abyRSN[10] = 1;
+        pRSNIEs->abyRSN[11] = 0;
+        pRSNIEs->abyRSN[12] = 0x00;
+        pRSNIEs->abyRSN[13] = 0x0F;
+        pRSNIEs->abyRSN[14] = 0xAC;
+        if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
+            pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_PSK;
+        } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
+            pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
+        } else {
+            pRSNIEs->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
+        }
+        pRSNIEs->len +=6;
+
+        // RSN Capabilites
+        if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
+            memcpy(&pRSNIEs->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
+        } else {
+            pRSNIEs->abyRSN[16] = 0;
+            pRSNIEs->abyRSN[17] = 0;
+        }
+        pRSNIEs->len +=2;
+
+        if ((pMgmt->gsPMKIDCache.BSSIDInfoCount > 0) &&
+            (pMgmt->bRoaming == TRUE) &&
+            (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
+            // RSN PMKID
+            pwPMKID = (PWORD)(&pRSNIEs->abyRSN[18]);  // Point to PMKID count
+            *pwPMKID = 0;                               // Initialize PMKID count
+            pbyBuffer = &pRSNIEs->abyRSN[20];           // Point to PMKID list
+            for (ii = 0; ii < pMgmt->gsPMKIDCache.BSSIDInfoCount; ii++) {
+                if ( !memcmp(&pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyBSSID[0], pMgmt->abyCurrBSSID, U_ETHER_ADDR_LEN)) {
+                    (*pwPMKID) ++;
+                    memcpy(pbyBuffer, pMgmt->gsPMKIDCache.BSSIDInfo[ii].abyPMKID, 16);
+                    pbyBuffer += 16;
+                }
+            }
+            if (*pwPMKID != 0) {
+                pRSNIEs->len += (2 + (*pwPMKID)*16);
+            } else {
+                pbyBuffer = &pRSNIEs->abyRSN[18];
+            }
+        }
+        return(pRSNIEs->len + WLAN_IEHDR_LEN);
+    }
+    return(0);
+}
diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h
new file mode 100644
index 0000000..e553b38
--- /dev/null
+++ b/drivers/staging/vt6656/wpa2.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: wpa2.h
+ *
+ * Purpose: Defines the macros, types, and functions for dealing
+ *          with WPA2 informations.
+ *
+ * Author: Yiching Chen
+ *
+ * Date: Oct. 4, 2004
+ *
+ */
+
+#ifndef __WPA2_H__
+#define __WPA2_H__
+
+#include "ttype.h"
+#include "80211mgr.h"
+#include "80211hdr.h"
+#include "bssdb.h"
+
+/*---------------------  Export Definitions -------------------------*/
+#define MAX_PMKID_CACHE         16
+
+typedef struct tagsPMKIDInfo {
+    BYTE    abyBSSID[6];
+    BYTE    abyPMKID[16];
+} PMKIDInfo, *PPMKIDInfo;
+
+typedef struct tagSPMKIDCache {
+    ULONG       BSSIDInfoCount;
+    PMKIDInfo   BSSIDInfo[MAX_PMKID_CACHE];
+} SPMKIDCache, *PSPMKIDCache;
+
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Types  ------------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+VOID
+WPA2_ClearRSN (
+    IN PKnownBSS        pBSSNode
+    );
+
+VOID
+WPA2vParseRSN (
+    IN PKnownBSS        pBSSNode,
+    IN PWLAN_IE_RSN     pRSN
+    );
+
+UINT
+WPA2uSetIEs(
+    IN PVOID pMgmtHandle,
+    OUT PWLAN_IE_RSN pRSNIEs
+    );
+
+#endif // __WPA2_H__
diff --git a/drivers/staging/vt6656/wpactl.c b/drivers/staging/vt6656/wpactl.c
new file mode 100644
index 0000000..4555bc0
--- /dev/null
+++ b/drivers/staging/vt6656/wpactl.c
@@ -0,0 +1,1008 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *
+ * File: wpactl.c
+ *
+ * Purpose: handle wpa supplicant ioctl input/out functions
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: July 28, 2006
+ *
+ * Functions:
+ *
+ * Revision History:
+ *
+ */
+
+#include "wpactl.h"
+#include "key.h"
+#include "mac.h"
+#include "device.h"
+#include "wmgr.h"
+#include "iocmd.h"
+#include "iowpa.h"
+#include "control.h"
+#include "rndis.h"
+#include "rf.h"
+
+/*---------------------  Static Definitions -------------------------*/
+
+#define VIAWGET_WPA_MAX_BUF_SIZE 1024
+
+
+
+static const int frequency_list[] = {
+	2412, 2417, 2422, 2427, 2432, 2437, 2442,
+	2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+/*---------------------  Static Classes  ----------------------------*/
+
+/*---------------------  Static Variables  --------------------------*/
+//static int          msglevel                =MSG_LEVEL_DEBUG;
+static int          msglevel                =MSG_LEVEL_INFO;
+
+/*---------------------  Static Functions  --------------------------*/
+
+
+
+
+/*---------------------  Export Variables  --------------------------*/
+static void wpadev_setup(struct net_device *dev)
+{
+	dev->type               = ARPHRD_IEEE80211;
+	dev->hard_header_len    = ETH_HLEN;
+	dev->mtu                = 2048;
+	dev->addr_len           = ETH_ALEN;
+	dev->tx_queue_len       = 1000;
+
+	memset(dev->broadcast,0xFF, ETH_ALEN);
+
+	dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
+}
+
+/*
+ * Description:
+ *      register netdev for wpa supplicant deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      enable              -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_init_wpadev(PSDevice pDevice)
+{
+    PSDevice wpadev_priv;
+	struct net_device *dev = pDevice->dev;
+         int ret=0;
+
+	pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", wpadev_setup);
+	if (pDevice->wpadev == NULL)
+		return -ENOMEM;
+
+    wpadev_priv = netdev_priv(pDevice->wpadev);
+    *wpadev_priv = *pDevice;
+	memcpy(pDevice->wpadev->dev_addr, dev->dev_addr, U_ETHER_ADDR_LEN);
+         pDevice->wpadev->base_addr = dev->base_addr;
+	pDevice->wpadev->irq = dev->irq;
+	pDevice->wpadev->mem_start = dev->mem_start;
+	pDevice->wpadev->mem_end = dev->mem_end;
+	ret = register_netdev(pDevice->wpadev);
+	if (ret) {
+		DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n",
+		       dev->name);
+		free_netdev(pDevice->wpadev);
+		return -1;
+	}
+
+	if (pDevice->skb == NULL) {
+        pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
+        if (pDevice->skb == NULL)
+		    return -ENOMEM;
+    }
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n",
+	       dev->name, pDevice->wpadev->name);
+
+	return 0;
+}
+
+
+/*
+ * Description:
+ *      unregister net_device (wpadev)
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_release_wpadev(PSDevice pDevice)
+{
+    if (pDevice->skb) {
+        dev_kfree_skb(pDevice->skb);
+        pDevice->skb = NULL;
+    }
+
+    if (pDevice->wpadev) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
+	       pDevice->dev->name, pDevice->wpadev->name);
+	unregister_netdev(pDevice->wpadev);
+	free_netdev(pDevice->wpadev);
+         pDevice->wpadev = NULL;
+    }
+
+	return 0;
+}
+
+
+
+
+
+/*
+ * Description:
+ *      Set enable/disable dev for wpa supplicant deamon
+ *
+ * Parameters:
+ *  In:
+ *      pDevice             -
+ *      val                 -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int wpa_set_wpadev(PSDevice pDevice, int val)
+{
+	if (val)
+		return wpa_init_wpadev(pDevice);
+	else
+		return wpa_release_wpadev(pDevice);
+}
+
+
+/*
+ * Description:
+ *      Set WPA algorithm & keys
+ *
+ * Parameters:
+ *  In:
+ *      pDevice -
+ *      param -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+ int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel)
+{
+    struct viawget_wpa_param *param=ctx;
+    PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
+    DWORD   dwKeyIndex = 0;
+    BYTE    abyKey[MAX_KEY_LEN];
+    BYTE    abySeq[MAX_KEY_LEN];
+    QWORD   KeyRSC;
+//    NDIS_802_11_KEY_RSC KeyRSC;
+    BYTE    byKeyDecMode = KEY_CTL_WEP;
+	int ret = 0;
+	int uu, ii;
+
+
+	if (param->u.wpa_key.alg_name > WPA_ALG_CCMP)
+		return -EINVAL;
+
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d \n", param->u.wpa_key.alg_name);
+	if (param->u.wpa_key.alg_name == WPA_ALG_NONE) {
+        pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+        pDevice->bEncryptionEnable = FALSE;
+        pDevice->byKeyIndex = 0;
+        pDevice->bTransmitKey = FALSE;
+        for (uu=0; uu<MAX_KEY_TABLE; uu++) {
+            MACvDisableKeyEntry(pDevice, uu);
+        }
+        return ret;
+    }
+
+    spin_unlock_irq(&pDevice->lock);
+    if(param->u.wpa_key.key && fcpfkernel) {
+       memcpy(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len);
+     }
+    else {
+	if (param->u.wpa_key.key &&
+	    copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) {
+	    spin_lock_irq(&pDevice->lock);
+	    return -EINVAL;
+	}
+     }
+    spin_lock_irq(&pDevice->lock);
+
+    dwKeyIndex = (DWORD)(param->u.wpa_key.key_index);
+
+	if (param->u.wpa_key.alg_name == WPA_ALG_WEP) {
+        if (dwKeyIndex > 3) {
+            return -EINVAL;
+        }
+        else {
+            if (param->u.wpa_key.set_tx) {
+                pDevice->byKeyIndex = (BYTE)dwKeyIndex;
+                pDevice->bTransmitKey = TRUE;
+		        dwKeyIndex |= (1 << 31);
+            }
+            KeybSetDefaultKey(  pDevice,
+                                &(pDevice->sKey),
+                                dwKeyIndex & ~(BIT30 | USE_KEYRSC),
+                                param->u.wpa_key.key_len,
+                                NULL,
+                                abyKey,
+                                KEY_CTL_WEP
+                              );
+
+        }
+        pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+        pDevice->bEncryptionEnable = TRUE;
+        return ret;
+	}
+
+    spin_unlock_irq(&pDevice->lock);
+        if(param->u.wpa_key.seq && fcpfkernel) {
+           memcpy(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len);
+        	}
+       else {
+	if (param->u.wpa_key.seq &&
+	    copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) {
+	    spin_lock_irq(&pDevice->lock);
+	    return -EINVAL;
+	}
+	}
+	spin_lock_irq(&pDevice->lock);
+
+	if (param->u.wpa_key.seq_len > 0) {
+		for (ii = 0 ; ii < param->u.wpa_key.seq_len ; ii++) {
+		     if (ii < 4)
+			    LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8));
+			 else
+			    HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8));
+	         //KeyRSC |= (abySeq[ii] << (ii * 8));
+		}
+		dwKeyIndex |= 1 << 29;
+	}
+
+    if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return  dwKeyIndex > 3\n");
+        return -EINVAL;
+    }
+
+	if (param->u.wpa_key.alg_name == WPA_ALG_TKIP) {
+        pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+    }
+
+	if (param->u.wpa_key.alg_name == WPA_ALG_CCMP) {
+        pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+    }
+
+	if (param->u.wpa_key.set_tx)
+		dwKeyIndex |= (1 << 31);
+
+
+    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
+        byKeyDecMode = KEY_CTL_CCMP;
+    else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
+        byKeyDecMode = KEY_CTL_TKIP;
+    else
+        byKeyDecMode = KEY_CTL_WEP;
+
+    // Fix HCT test that set 256 bits KEY and Ndis802_11Encryption3Enabled
+    if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
+        if (param->u.wpa_key.key_len == MAX_KEY_LEN)
+            byKeyDecMode = KEY_CTL_TKIP;
+        else if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+    } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
+        if (param->u.wpa_key.key_len == WLAN_WEP40_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+        else if (param->u.wpa_key.key_len == WLAN_WEP104_KEYLEN)
+            byKeyDecMode = KEY_CTL_WEP;
+    }
+
+    // Check TKIP key length
+    if ((byKeyDecMode == KEY_CTL_TKIP) &&
+        (param->u.wpa_key.key_len != MAX_KEY_LEN)) {
+        // TKIP Key must be 256 bits
+        //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - TKIP Key must be 256 bits\n"));
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n");
+        return -EINVAL;
+    }
+    // Check AES key length
+    if ((byKeyDecMode == KEY_CTL_CCMP) &&
+        (param->u.wpa_key.key_len != AES_KEY_LEN)) {
+        // AES Key must be 128 bits
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return - AES Key must be 128 bits\n");
+        return -EINVAL;
+    }
+
+
+    if (IS_BROADCAST_ADDRESS(&param->addr[0]) || (param->addr == NULL)) {
+        // If IS_BROADCAST_ADDRESS, set the key as every key entry's group key.
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n");
+
+        if ((KeybSetAllGroupKey(pDevice,
+                            &(pDevice->sKey),
+                            dwKeyIndex,
+                            param->u.wpa_key.key_len,
+                            (PQWORD) &(KeyRSC),
+                            (PBYTE)abyKey,
+                            byKeyDecMode
+                            ) == TRUE) &&
+            (KeybSetDefaultKey(pDevice,
+                            &(pDevice->sKey),
+                            dwKeyIndex,
+                            param->u.wpa_key.key_len,
+                            (PQWORD) &(KeyRSC),
+                            (PBYTE)abyKey,
+                            byKeyDecMode
+                            ) == TRUE) ) {
+             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n");
+
+        } else {
+            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -KeybSetDefaultKey Fail.0\n"));
+            return -EINVAL;
+        }
+
+    } else {
+        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n");
+        // BSSID not 0xffffffffffff
+        // Pairwise Key can't be WEP
+        if (byKeyDecMode == KEY_CTL_WEP) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n");
+            return -EINVAL;
+        }
+
+        dwKeyIndex |= (1 << 30); // set pairwise key
+        if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
+            //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA - WMAC_CONFIG_IBSS_STA\n"));
+            return -EINVAL;
+        }
+        if (KeybSetKey(pDevice,
+                       &(pDevice->sKey),
+                       &param->addr[0],
+                       dwKeyIndex,
+                       param->u.wpa_key.key_len,
+                       (PQWORD) &(KeyRSC),
+                       (PBYTE)abyKey,
+                        byKeyDecMode
+                       ) == TRUE) {
+            DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n");
+
+        } else {
+            // Key Table Full
+            if (IS_ETH_ADDRESS_EQUAL(&param->addr[0], pDevice->abyBSSID)) {
+                //DBG_PRN_WLAN03(("return NDIS_STATUS_INVALID_DATA -Key Table Full.2\n"));
+                return -EINVAL;
+
+            } else {
+                // Save Key and configure just before associate/reassociate to BSSID
+                // we do not implement now
+                return -EINVAL;
+            }
+        }
+    } // BSSID not 0xffffffffffff
+    if ((ret == 0) && ((param->u.wpa_key.set_tx) != 0)) {
+        pDevice->byKeyIndex = (BYTE)param->u.wpa_key.key_index;
+        pDevice->bTransmitKey = TRUE;
+    }
+    pDevice->bEncryptionEnable = TRUE;
+
+/*
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " key=%x-%x-%x-%x-%x-xxxxx \n",
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][0],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][1],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][2],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][3],
+               pMgmt->sNodeDBTable[iNodeIndex].abyWepKey[byKeyIndex][4]
+              );
+*/
+
+	return ret;
+
+}
+
+
+/*
+ * Description:
+ *      enable wpa auth & mode
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_wpa(PSDevice pDevice,
+				     struct viawget_wpa_param *param)
+{
+
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	int ret = 0;
+
+    pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+    pMgmt->bShareKeyAlgorithm = FALSE;
+
+    return ret;
+}
+
+
+
+
+ /*
+ * Description:
+ *      set disassociate
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_disassociate(PSDevice pDevice,
+				     struct viawget_wpa_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+	int ret = 0;
+
+    spin_lock_irq(&pDevice->lock);
+    if (pDevice->bLinkPass) {
+        if (!memcmp(param->addr, pMgmt->abyCurrBSSID, 6))
+            bScheduleCommand((HANDLE)pDevice, WLAN_CMD_DISASSOCIATE, NULL);
+    }
+    spin_unlock_irq(&pDevice->lock);
+
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      enable scan process
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_scan(PSDevice pDevice,
+				     struct viawget_wpa_param *param)
+{
+	int ret = 0;
+
+//2007-0919-01<Add>by MikeLiu
+/**set ap_scan=1&&scan_ssid=1 under hidden ssid mode**/
+        PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+        PWLAN_IE_SSID       pItemSSID;
+printk("wpa_set_scan-->desired [ssid=%s,ssid_len=%d]\n",
+	     param->u.scan_req.ssid,param->u.scan_req.ssid_len);
+// Set the SSID
+memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+pItemSSID->byElementID = WLAN_EID_SSID;
+memcpy(pItemSSID->abySSID, param->u.scan_req.ssid, param->u.scan_req.ssid_len);
+pItemSSID->len = param->u.scan_req.ssid_len;
+
+    spin_lock_irq(&pDevice->lock);
+    BSSvClearBSSList((HANDLE)pDevice, pDevice->bLinkPass);
+  //  bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, NULL);
+        bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+    spin_unlock_irq(&pDevice->lock);
+
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      get bssid
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_get_bssid(PSDevice pDevice,
+				     struct viawget_wpa_param *param)
+{
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	int ret = 0;
+	memcpy(param->u.wpa_associate.bssid, pMgmt->abyCurrBSSID , 6);
+
+    return ret;
+
+}
+
+
+/*
+ * Description:
+ *      get bssid
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_get_ssid(PSDevice pDevice,
+				     struct viawget_wpa_param *param)
+{
+    PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
+	PWLAN_IE_SSID       pItemSSID;
+	int ret = 0;
+
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
+
+	memcpy(param->u.wpa_associate.ssid, pItemSSID->abySSID , pItemSSID->len);
+	param->u.wpa_associate.ssid_len = pItemSSID->len;
+
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      get scan results
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_get_scan(PSDevice pDevice,
+				     struct viawget_wpa_param *param)
+{
+	struct viawget_scan_result *scan_buf;
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PWLAN_IE_SSID   pItemSSID;
+    PKnownBSS pBSS;
+	PBYTE  pBuf;
+	int ret = 0;
+	u16 count = 0;
+	u16 ii, jj;
+	long ldBm;//James //add
+
+//******mike:bubble sort by stronger RSSI*****//
+
+    PBYTE ptempBSS;
+
+
+
+    ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);
+
+    if (ptempBSS == NULL) {
+
+       printk("bubble sort kmalloc memory fail@@@\n");
+
+        ret = -ENOMEM;
+
+        return ret;
+
+    }
+
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+
+         for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {
+
+           if((pMgmt->sBSSList[jj].bActive!=TRUE) ||
+
+                ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=FALSE))) {
+
+                 memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));
+
+                 memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS));
+
+                 memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS));
+
+              }
+
+         }
+
+    };
+
+  kfree(ptempBSS);
+
+ // printk("bubble sort result:\n");
+
+	count = 0;
+	pBSS = &(pMgmt->sBSSList[0]);
+    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
+        pBSS = &(pMgmt->sBSSList[ii]);
+        if (!pBSS->bActive)
+            continue;
+        count++;
+    };
+
+    pBuf = kmalloc(sizeof(struct viawget_scan_result) * count, (int)GFP_ATOMIC);
+
+    if (pBuf == NULL) {
+        ret = -ENOMEM;
+        return ret;
+    }
+   	memset(pBuf, 0, sizeof(struct viawget_scan_result) * count);
+    scan_buf = (struct viawget_scan_result *)pBuf;
+	pBSS = &(pMgmt->sBSSList[0]);
+    for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) {
+        pBSS = &(pMgmt->sBSSList[ii]);
+        if (pBSS->bActive) {
+            if (jj >= count)
+                break;
+            memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
+            pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
+   		    memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
+   		    scan_buf->ssid_len = pItemSSID->len;
+            scan_buf->freq = frequency_list[pBSS->uChannel-1];
+            scan_buf->caps = pBSS->wCapInfo;    //DavidWang for sharemode
+//20080717-05,<Add> by James Li
+	        RFvRSSITodBm(pDevice, (BYTE)(pBSS->uRSSI), &ldBm);
+			if(-ldBm<50){
+				scan_buf->qual = 100;
+			}else  if(-ldBm > 90) {
+				 scan_buf->qual = 0;
+			}else {
+				scan_buf->qual=(40-(-ldBm-50))*100/40;
+			}
+
+			//James
+            //scan_buf->caps = pBSS->wCapInfo;
+            //scan_buf->qual =
+            scan_buf->noise = 0;
+            scan_buf->level = ldBm;
+ //20080717-05,<Add> by James Li--End
+            //scan_buf->maxrate =
+            if (pBSS->wWPALen != 0) {
+                scan_buf->wpa_ie_len = pBSS->wWPALen;
+                memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
+            }
+            if (pBSS->wRSNLen != 0) {
+                scan_buf->rsn_ie_len = pBSS->wRSNLen;
+                memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
+            }
+            scan_buf = (struct viawget_scan_result *)((PBYTE)scan_buf + sizeof(struct viawget_scan_result));
+            jj ++;
+        }
+    }
+
+    if (jj < count)
+        count = jj;
+
+    if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
+		ret = -EFAULT;
+	};
+	param->u.scan_results.scan_count = count;
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
+
+    kfree(pBuf);
+    return ret;
+}
+
+
+
+/*
+ * Description:
+ *      set associate with AP
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      param     -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+static int wpa_set_associate(PSDevice pDevice,
+				     struct viawget_wpa_param *param)
+{
+    PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
+    PWLAN_IE_SSID   pItemSSID;
+    BYTE    abyNullAddr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    BYTE    abyWPAIE[64];
+    int ret = 0;
+    BOOL   bwepEnabled=FALSE;
+
+	// set key type & algorithm
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len);
+    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming dBm = %d\n", param->u.wpa_associate.roam_dbm);  //Davidwang
+
+	if (param->u.wpa_associate.wpa_ie &&
+	    copy_from_user(&abyWPAIE[0], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len))
+	    return -EINVAL;
+
+	if (param->u.wpa_associate.mode == 1)
+	    pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA;
+	else
+	    pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA;
+
+	// set bssid
+    if (memcmp(param->u.wpa_associate.bssid, &abyNullAddr[0], 6) != 0)
+        memcpy(pMgmt->abyDesireBSSID, param->u.wpa_associate.bssid, 6);
+    // set ssid
+	memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
+    pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
+    pItemSSID->byElementID = WLAN_EID_SSID;
+	pItemSSID->len = param->u.wpa_associate.ssid_len;
+	memcpy(pItemSSID->abySSID, param->u.wpa_associate.ssid, pItemSSID->len);
+
+    if (param->u.wpa_associate.wpa_ie_len == 0) {
+	    if (param->u.wpa_associate.auth_alg & AUTH_ALG_SHARED_KEY)
+            pMgmt->eAuthenMode = WMAC_AUTH_SHAREKEY;
+	    else
+            pMgmt->eAuthenMode = WMAC_AUTH_OPEN;
+	} else if (abyWPAIE[0] == RSN_INFO_ELEM) {
+		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
+			pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
+		else
+			pMgmt->eAuthenMode = WMAC_AUTH_WPA2;
+	} else {
+		if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_WPA_NONE)
+			pMgmt->eAuthenMode = WMAC_AUTH_WPANONE;
+		else if (param->u.wpa_associate.key_mgmt_suite == KEY_MGMT_PSK)
+		    pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
+		else
+		    pMgmt->eAuthenMode = WMAC_AUTH_WPA;
+	}
+
+	switch (param->u.wpa_associate.pairwise_suite) {
+	case CIPHER_CCMP:
+		pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+		break;
+	case CIPHER_TKIP:
+		pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+		break;
+	case CIPHER_WEP40:
+	case CIPHER_WEP104:
+		pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+		bwepEnabled = TRUE;
+	//	printk("****************wpa_set_associate:set CIPHER_WEP40_104\n");
+		break;
+	case CIPHER_NONE:
+		if (param->u.wpa_associate.group_suite == CIPHER_CCMP)
+			pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;
+		else
+			pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;
+		break;
+	default:
+		pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+	};
+
+           pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm;
+         // if ((pMgmt->Roam_dbm > 40)&&(pMgmt->Roam_dbm<80))
+         //    pDevice->bEnableRoaming = TRUE;
+
+	    if (pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) {   //@wep-sharekey
+            pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+            pMgmt->bShareKeyAlgorithm = TRUE;
+             }
+	    else if (pMgmt->eAuthenMode == WMAC_AUTH_OPEN) {
+	       if(bwepEnabled==TRUE) {                                                         //@open-wep
+                       pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled;
+	   	}
+	      else {                                                                                                 //@only open
+            pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
+	   	}
+           }
+//mike save old encryption status
+	pDevice->eOldEncryptionStatus = pDevice->eEncryptionStatus;
+
+    if (pDevice->eEncryptionStatus !=  Ndis802_11EncryptionDisabled)
+        pDevice->bEncryptionEnable = TRUE;
+    else
+        pDevice->bEncryptionEnable = FALSE;
+
+ if ((pMgmt->eAuthenMode == WMAC_AUTH_SHAREKEY) ||
+      ((pMgmt->eAuthenMode == WMAC_AUTH_OPEN) && (bwepEnabled==TRUE)))  {
+ //mike re-comment:open-wep && sharekey-wep needn't do initial key!!
+
+     }
+ else
+    KeyvInitTable(pDevice,&pDevice->sKey);
+
+    spin_lock_irq(&pDevice->lock);
+    pDevice->bLinkPass = FALSE;
+    ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
+    memset(pMgmt->abyCurrBSSID, 0, 6);
+    pMgmt->eCurrState = WMAC_STATE_IDLE;
+    netif_stop_queue(pDevice->dev);
+
+//20080701-02,<Add> by Mike Liu
+/*******search if ap_scan=2 ,which is associating request in hidden ssid mode ****/
+{
+   PKnownBSS       pCurr = NULL;
+    pCurr = BSSpSearchBSSList(pDevice,
+                              pMgmt->abyDesireBSSID,
+                              pMgmt->abyDesireSSID,
+                              pDevice->eConfigPHYMode
+                              );
+
+    if (pCurr == NULL){
+    printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
+  };
+}
+/****************************************************************/
+
+    bScheduleCommand((HANDLE) pDevice, WLAN_CMD_SSID, NULL);
+    spin_unlock_irq(&pDevice->lock);
+
+    return ret;
+}
+
+
+/*
+ * Description:
+ *      wpa_ioctl main function supported for wpa supplicant
+ *
+ * Parameters:
+ *  In:
+ *      pDevice   -
+ *      iw_point  -
+ *  Out:
+ *
+ * Return Value:
+ *
+ */
+
+int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
+{
+	struct viawget_wpa_param *param;
+	int ret = 0;
+	int wpa_ioctl = 0;
+
+	if (p->length < sizeof(struct viawget_wpa_param) ||
+	    p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
+		return -EINVAL;
+
+	param = (struct viawget_wpa_param *) kmalloc((int)p->length, (int)GFP_KERNEL);
+	if (param == NULL)
+		return -ENOMEM;
+
+	if (copy_from_user(param, p->pointer, p->length)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	switch (param->cmd) {
+	case VIAWGET_SET_WPA:
+        ret = wpa_set_wpa(pDevice, param);
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
+		break;
+
+	case VIAWGET_SET_KEY:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
+	    spin_lock_irq(&pDevice->lock);
+        ret = wpa_set_keys(pDevice, param, FALSE);
+        spin_unlock_irq(&pDevice->lock);
+		break;
+
+	case VIAWGET_SET_SCAN:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
+        ret = wpa_set_scan(pDevice, param);
+		break;
+
+	case VIAWGET_GET_SCAN:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
+        ret = wpa_get_scan(pDevice, param);
+		wpa_ioctl = 1;
+		break;
+
+	case VIAWGET_GET_SSID:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
+        ret = wpa_get_ssid(pDevice, param);
+		wpa_ioctl = 1;
+		break;
+
+	case VIAWGET_GET_BSSID:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
+        ret = wpa_get_bssid(pDevice, param);
+		wpa_ioctl = 1;
+		break;
+
+	case VIAWGET_SET_ASSOCIATE:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
+        ret = wpa_set_associate(pDevice, param);
+		break;
+
+	case VIAWGET_SET_DISASSOCIATE:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
+        ret = wpa_set_disassociate(pDevice, param);
+		break;
+
+	case VIAWGET_SET_DROP_UNENCRYPT:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
+		break;
+
+    case VIAWGET_SET_DEAUTHENTICATE:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
+		break;
+
+	default:
+	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
+		       param->cmd);
+		return -EOPNOTSUPP;
+		break;
+	}
+
+	if ((ret == 0) && wpa_ioctl) {
+		if (copy_to_user(p->pointer, param, p->length)) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+
+out:
+	if (param != NULL)
+		kfree(param);
+
+	return ret;
+}
+
diff --git a/drivers/staging/vt6656/wpactl.h b/drivers/staging/vt6656/wpactl.h
new file mode 100644
index 0000000..56179f0
--- /dev/null
+++ b/drivers/staging/vt6656/wpactl.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1996, 2003 VIA Networking Technologies, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * File: wpactl.h
+ *
+ * Purpose:
+ *
+ * Author: Lyndon Chen
+ *
+ * Date: March 1, 2005
+ *
+ */
+
+#ifndef __WPACTL_H__
+#define __WPACTL_H__
+
+#include "device.h"
+#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
+#include "iowpa.h"
+#endif
+
+/*---------------------  Export Definitions -------------------------*/
+
+
+//WPA related
+
+typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
+typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
+	       CIPHER_WEP104 } wpa_cipher;
+typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
+	       KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE, KEY_MGMT_CCKM } wpa_key_mgmt;//20080717-02,<Modify> by James Li
+
+#define AUTH_ALG_OPEN_SYSTEM	0x01
+#define AUTH_ALG_SHARED_KEY	0x02
+#define AUTH_ALG_LEAP		0x04
+
+#define GENERIC_INFO_ELEM 0xdd
+#define RSN_INFO_ELEM 0x30
+
+
+
+typedef ULONGLONG   NDIS_802_11_KEY_RSC;
+
+/*---------------------  Export Classes  ----------------------------*/
+
+/*---------------------  Export Variables  --------------------------*/
+
+/*---------------------  Export Functions  --------------------------*/
+
+int wpa_set_wpadev(PSDevice pDevice, int val);
+int wpa_ioctl(PSDevice pDevice, struct iw_point *p);
+int wpa_set_keys(PSDevice pDevice, void *ctx, BOOL  fcpfkernel);
+
+#endif // __WPACL_H__
+
+
+
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
index eb4c090..7d4bd5e 100644
--- a/drivers/staging/winbond/core.h
+++ b/drivers/staging/winbond/core.h
@@ -18,9 +18,9 @@ struct wbsoft_priv {
 
 	MLME_FRAME sMlmeFrame;	// connect to peerSTA parameters
 
-	MTO_PARAMETERS sMtoPara;	// MTO_struct ...
+	struct wb35_mto_params sMtoPara;	// MTO_struct ...
 	struct hw_data sHwData;	//For HAL
-	MDS Mds;
+	struct wb35_mds Mds;
 
 	spinlock_t SpinLock;
 
diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h
index 607bb05..5626a76 100644
--- a/drivers/staging/winbond/localpara.h
+++ b/drivers/staging/winbond/localpara.h
@@ -190,7 +190,6 @@ typedef struct LOCAL_PARA
 	u8			Reserved0[2];
 
 	u8			boMsRadioOff;			// Ndis demands to be true when set Disassoc. OID and be false when set SSID OID.
-	u8			boAntennaDiversity;		//TRUE/ON or FALSE/OFF
 	u8			bAntennaNo;				//which antenna
 	u8			bConnectFlag;			//the connect status flag for roaming task
 
diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
index 59d6d67..37e0c18 100644
--- a/drivers/staging/winbond/mds.c
+++ b/drivers/staging/winbond/mds.c
@@ -8,7 +8,7 @@
 unsigned char
 Mds_initial(struct wbsoft_priv * adapter)
 {
-	PMDS pMds = &adapter->Mds;
+	struct wb35_mds *pMds = &adapter->Mds;
 
 	pMds->TxPause = false;
 	pMds->TxRTSThreshold = DEFAULT_RTSThreshold;
@@ -22,7 +22,7 @@ Mds_Destroy(struct wbsoft_priv * adapter)
 {
 }
 
-static void Mds_DurationSet(struct wbsoft_priv *adapter,  PDESCRIPTOR pDes,  u8 *buffer)
+static void Mds_DurationSet(struct wbsoft_priv *adapter,  struct wb35_descriptor *pDes,  u8 *buffer)
 {
 	PT00_DESCRIPTOR	pT00;
 	PT01_DESCRIPTOR	pT01;
@@ -217,10 +217,10 @@ static void Mds_DurationSet(struct wbsoft_priv *adapter,  PDESCRIPTOR pDes,  u8
 }
 
 // The function return the 4n size of usb pk
-static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, PDESCRIPTOR pDes, u8 *TargetBuffer)
+static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, struct wb35_descriptor *pDes, u8 *TargetBuffer)
 {
 	PT00_DESCRIPTOR	pT00;
-	PMDS	pMds = &adapter->Mds;
+	struct wb35_mds *pMds = &adapter->Mds;
 	u8	*buffer;
 	u8	*src_buffer;
 	u8	*pctmp;
@@ -318,9 +318,9 @@ static u16 Mds_BodyCopy(struct wbsoft_priv *adapter, PDESCRIPTOR pDes, u8 *Targe
 	return Size;
 }
 
-static void Mds_HeaderCopy(struct wbsoft_priv * adapter, PDESCRIPTOR pDes, u8 *TargetBuffer)
+static void Mds_HeaderCopy(struct wbsoft_priv * adapter, struct wb35_descriptor *pDes, u8 *TargetBuffer)
 {
-	PMDS	pMds = &adapter->Mds;
+	struct wb35_mds *pMds = &adapter->Mds;
 	u8	*src_buffer = pDes->buffer_address[0];//931130.5.g
 	PT00_DESCRIPTOR	pT00;
 	PT01_DESCRIPTOR	pT01;
@@ -417,9 +417,9 @@ void
 Mds_Tx(struct wbsoft_priv * adapter)
 {
 	struct hw_data *	pHwData = &adapter->sHwData;
-	PMDS		pMds = &adapter->Mds;
-	DESCRIPTOR	TxDes;
-	PDESCRIPTOR	pTxDes = &TxDes;
+	struct wb35_mds *pMds = &adapter->Mds;
+	struct wb35_descriptor	TxDes;
+	struct wb35_descriptor *pTxDes = &TxDes;
 	u8		*XmitBufAddress;
 	u16		XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
 	u8		FillIndex, TxDesIndex, FragmentCount, FillCount;
@@ -470,7 +470,7 @@ Mds_Tx(struct wbsoft_priv * adapter)
 			BufferFilled = true;
 
 			/* Leaves first u8 intact */
-			memset((u8 *)pTxDes + 1, 0, sizeof(DESCRIPTOR) - 1);
+			memset((u8 *)pTxDes + 1, 0, sizeof(struct wb35_descriptor) - 1);
 
 			TxDesIndex = pMds->TxDesIndex;//Get the current ID
 			pTxDes->Descriptor_ID = TxDesIndex;
@@ -552,7 +552,7 @@ Mds_Tx(struct wbsoft_priv * adapter)
 void
 Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02)
 {
-	PMDS	pMds = &adapter->Mds;
+	struct wb35_mds *pMds = &adapter->Mds;
 	struct hw_data *	pHwData = &adapter->sHwData;
 	u8	PacketId = (u8)pT02->T02_Tx_PktID;
 	unsigned char	SendOK = true;
diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h
index ee0f120..ab1ea53 100644
--- a/drivers/staging/winbond/mds_f.h
+++ b/drivers/staging/winbond/mds_f.h
@@ -8,7 +8,7 @@ unsigned char Mds_initial(  struct wbsoft_priv *adapter );
 void Mds_Destroy(  struct wbsoft_priv *adapter );
 void Mds_Tx(  struct wbsoft_priv *adapter );
 void Mds_SendComplete(  struct wbsoft_priv *adapter,  PT02_DESCRIPTOR pT02 );
-void Mds_MpduProcess(  struct wbsoft_priv *adapter,  PDESCRIPTOR pRxDes );
+void Mds_MpduProcess(  struct wbsoft_priv *adapter,  struct wb35_descriptor *pRxDes );
 extern void DataDmp(u8 *pdata, u32 len, u32 offset);
 
 // For Asynchronous indicating. The routine collocates with USB.
@@ -16,8 +16,8 @@ void Mds_MsduProcess(  struct wbsoft_priv *adapter,  PRXLAYER1 pRxLayer1,  u8 Sl
 
 // For data frame sending 20060802
 u16 MDS_GetPacketSize(  struct wbsoft_priv *adapter );
-void MDS_GetNextPacket(  struct wbsoft_priv *adapter,  PDESCRIPTOR pDes );
-void MDS_GetNextPacketComplete(  struct wbsoft_priv *adapter,  PDESCRIPTOR pDes );
+void MDS_GetNextPacket(  struct wbsoft_priv *adapter,  struct wb35_descriptor *pDes );
+void MDS_GetNextPacketComplete(  struct wbsoft_priv *adapter,  struct wb35_descriptor *pDes );
 void MDS_SendResult(  struct wbsoft_priv *adapter,  u8 PacketId,  unsigned char SendOK );
 
 #endif
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
index 9ffec17..e8e13bd 100644
--- a/drivers/staging/winbond/mds_s.h
+++ b/drivers/staging/winbond/mds_s.h
@@ -67,7 +67,6 @@ enum {
 
 #define RX_BUF_SIZE						2352        // 600 	// For 301 must be multiple of 8
 #define MAX_RX_DESCRIPTORS              18         // Rx Layer 2
-#define MAX_BUFFER_QUEUE	8 // The value is always equal 8 due to NDIS_PACKET's MiniportReserved field size
 
 
 // For brand-new rx system
@@ -79,8 +78,7 @@ enum {
 #define PACKET_COME_FROM_MLME					0x80
 #define PACKET_SEND_COMPLETE					0xff
 
-typedef struct _MDS
-{
+struct wb35_mds {
 	// For Tx usage
 	u8	TxOwner[ ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03) ];
 	u8	*pTxBuffer;
@@ -133,16 +131,7 @@ typedef struct _MDS
 	u32	TxTsc; // 20060214
 	u32	TxTsc_2; // 20060214
 
-} MDS, *PMDS;
-
-
-typedef struct _RxBuffer
-{
-    u8 * pBufferAddress;     // Pointer the received data buffer.
-	u16	BufferSize;
-	u8	RESERVED;
-	u8	BufferIndex;// Only 1 byte
-} RXBUFFER, *PRXBUFFER;
+};
 
 //
 // Reveive Layer 1 Format.
@@ -162,8 +151,6 @@ typedef struct _RXLAYER1
 
 	u32	FirstFrameArrivedTime;
 
-	RXBUFFER	BufferQueue[ MAX_BUFFER_QUEUE ];
-
 	u8		LastFrameType; // 20061004 for fix intel 3945 's bug
 	u8		RESERVED[3];  //@@ anson
 
diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c
index 643ceb0..f856b94 100644
--- a/drivers/staging/winbond/mlmetxrx.c
+++ b/drivers/staging/winbond/mlmetxrx.c
@@ -45,7 +45,7 @@ u8 MLMESendFrame(struct wbsoft_priv * adapter, u8 *pMMPDU, u16 len, u8 DataType)
 	return true;
 }
 
-void MLME_GetNextPacket(struct wbsoft_priv *adapter, PDESCRIPTOR desc)
+void MLME_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *desc)
 {
 	desc->InternalUsed = desc->buffer_start_index + desc->buffer_number;
 	desc->InternalUsed %= MAX_DESCRIPTOR_BUFFER_INDEX;
diff --git a/drivers/staging/winbond/mlmetxrx_f.h b/drivers/staging/winbond/mlmetxrx_f.h
index 5f05a6e..6c04e3e 100644
--- a/drivers/staging/winbond/mlmetxrx_f.h
+++ b/drivers/staging/winbond/mlmetxrx_f.h
@@ -10,36 +10,16 @@
 
 #include "core.h"
 
-void
-MLMEProcThread(
-     struct wbsoft_priv *    adapter
-	);
-
-void MLME_GetNextPacket(  struct wbsoft_priv * adapter,  PDESCRIPTOR pDes );
-u8 MLMESendFrame( struct wbsoft_priv * adapter,
-					u8	*pMMPDU,
-					u16	len,
-					 u8	DataType);
-
-void
-MLME_SendComplete(  struct wbsoft_priv * adapter,  u8 PacketID,  unsigned char SendOK );
+void MLME_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *pDes);
+u8 MLMESendFrame(struct wbsoft_priv *adapter,
+		 u8 * pMMPDU, u16 len, u8 DataType);
 
 void
-MLMERcvFrame(
-     struct wbsoft_priv *    adapter,
-     PRXBUFFER        pRxBufferArray,
-     u8            NumOfBuffer,
-     u8            ReturnSlotIndex
-	);
+MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID,
+		  unsigned char SendOK);
 
-void
-MLMEReturnPacket(
-     struct wbsoft_priv *    adapter,
-     u8 *          pRxBufer
-   );
 #ifdef _IBSS_BEACON_SEQ_STICK_
-s8 SendBCNullData(struct wbsoft_priv * adapter, u16 wIdx);
+s8 SendBCNullData(struct wbsoft_priv *adapter, u16 wIdx);
 #endif
 
 #endif
-
diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
index 7deb5c7..5e7fa1c 100644
--- a/drivers/staging/winbond/mto.c
+++ b/drivers/staging/winbond/mto.c
@@ -76,23 +76,6 @@ void hal_get_dto_para(struct wbsoft_priv *adapter, char *buffer);
 void MTO_Init(struct wbsoft_priv *adapter)
 {
     int i;
-	//[WKCHEN]pMTOcore_data = pcore_data;
-// 20040510 Turbo add for global variable
-    MTO_TMR_CNT()       = 0;
-    MTO_TOGGLE_STATE()  = TOGGLE_STATE_IDLE;
-    MTO_TX_RATE_REDUCTION_STATE() = RATE_CHGSTATE_IDLE;
-    MTO_BACKOFF_TMR()   = 0;
-    MTO_LAST_RATE()     = 11;
-    MTO_CO_EFFICENT()   = 0;
-
-    //MTO_TH_FIXANT()     = MTO_DEFAULT_TH_FIXANT;
-    MTO_TH_CNT()        = MTO_DEFAULT_TH_CNT;
-    MTO_TH_SQ3()        = MTO_DEFAULT_TH_SQ3;
-    MTO_TH_IDLE_SLOT()  = MTO_DEFAULT_TH_IDLE_SLOT;
-    MTO_TH_PR_INTERF()  = MTO_DEFAULT_TH_PR_INTERF;
-
-    MTO_TMR_AGING()     = MTO_DEFAULT_TMR_AGING;
-    MTO_TMR_PERIODIC()  = MTO_DEFAULT_TMR_PERIODIC;
 
     //[WKCHEN]MTO_CCA_MODE_SETUP()= (u8) hal_get_cca_mode(MTO_HAL());
     //[WKCHEN]MTO_CCA_MODE()      = MTO_CCA_MODE_SETUP();
@@ -100,17 +83,12 @@ void MTO_Init(struct wbsoft_priv *adapter)
     //MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_LONG;
     MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_SHORT;   // for test
 
-    MTO_ANT_SEL()       = hal_get_antenna_number(MTO_HAL());
-    MTO_ANT_MAC()       = MTO_ANT_SEL();
     MTO_CNT_ANT(0)      = 0;
     MTO_CNT_ANT(1)      = 0;
     MTO_SQ_ANT(0)       = 0;
     MTO_SQ_ANT(1)       = 0;
-    MTO_ANT_DIVERSITY() = MTO_ANTENNA_DIVERSITY_ON;
-    //CardSet_AntennaDiversity(adapter, MTO_ANT_DIVERSITY());
-    //PLMESetAntennaDiversity( adapter, MTO_ANT_DIVERSITY());
 
-    MTO_AGING_TIMEOUT() = 0;//MTO_TMR_AGING() / MTO_TMR_PERIODIC();
+    MTO_AGING_TIMEOUT() = 0;
 
     // The following parameters should be initialized to the values set by user
     //
@@ -128,9 +106,7 @@ void MTO_Init(struct wbsoft_priv *adapter)
     MTO_FRAG_CHANGE_ENABLE()    = 0;          // 1.1.29.1000 Turbo add don't support frag
 	//The default valud of ANTDIV_DEFAULT_ON will be decided by EEPROM
 	//#ifdef ANTDIV_DEFAULT_ON
-    //MTO_ANT_DIVERSITY_ENABLE()  = 1;
 	//#else
-    //MTO_ANT_DIVERSITY_ENABLE()  = 0;
 	//#endif
     MTO_POWER_CHANGE_ENABLE()   = 1;
 	MTO_PREAMBLE_CHANGE_ENABLE()= 1;
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
index 56f2465..4fe24b0 100644
--- a/drivers/staging/winbond/mto.h
+++ b/drivers/staging/winbond/mto.h
@@ -15,52 +15,18 @@
 
 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
-#define MTO_DEFAULT_TH_PR_INTERF        30
-#define MTO_DEFAULT_TMR_AGING           25  // unit: slot time  10 reference JohnXu
-#define MTO_DEFAULT_TMR_PERIODIC        5   // unit: slot time
-
-#define MTO_ANTENNA_DIVERSITY_OFF       0
-#define MTO_ANTENNA_DIVERSITY_ON        1
-
 // LA20040210_DTO kevin
 //#define MTO_PREAMBLE_LONG               0
 //#define MTO_PREAMBLE_SHORT              1
 #define MTO_PREAMBLE_LONG               WLAN_PREAMBLE_TYPE_LONG
 #define MTO_PREAMBLE_SHORT              WLAN_PREAMBLE_TYPE_SHORT
 
-typedef enum {
-    TOGGLE_STATE_IDLE             = 0,
-    TOGGLE_STATE_WAIT0            = 1,
-    TOGGLE_STATE_WAIT1            = 2,
-    TOGGLE_STATE_MAKEDESISION     = 3,
-	TOGGLE_STATE_BKOFF            = 4
-} TOGGLE_STATE;
-
-typedef enum {
-    RATE_CHGSTATE_IDLE         = 0,
-    RATE_CHGSTATE_CALCULATE    = 1,
-    RATE_CHGSTATE_BACKOFF	   = 2
-} TX_RATE_REDUCTION_STATE;
-
 //============================================================================
 // struct _MTOParameters --
 //
 //   Defines the parameters used in the MAC Throughput Optimization algorithm
 //============================================================================
-typedef struct _MTO_PARAMETERS
-{
-	u8      Th_Fixant;
-	u8      Th_Cnt;
-	u8      Th_SQ3;
-	u8      Th_IdleSlot;
-
-	u16     Tmr_Aging;
-	u8      Th_PrInterf;
-	u8      Tmr_Periodic;
-
+struct wb35_mto_params {
 	//---------        wkchen added      -------------
 	u32		TxFlowCount;	//to judge what kind the tx flow(sparse or busy) is
 	//------------------------------------------------
@@ -84,9 +50,6 @@ typedef struct _MTO_PARAMETERS
 
 	u8      PowerChangeEnable;
 	u8      AntDiversityEnable;
-	u8      Ant_mac;
-	u8      Ant_div;
-
 	u8      CCA_Mode;
 	u8      CCA_Mode_Setup;
 	u8      Preamble_Type;
@@ -113,13 +76,6 @@ typedef struct _MTO_PARAMETERS
 	u32     SQ_Ant[2];
 
 // 20040510 remove from globe vairable
-	u32                     TmrCnt;
-	u32                     BackoffTmr;
-	TOGGLE_STATE            ToggleState;
-	TX_RATE_REDUCTION_STATE TxRateReductionState;
-
-	u8                      Last_Rate;
-	u8                      Co_efficent;
 	u8		FallbackRateLevel;
 	u8		OfdmRateLevel;
 
@@ -130,7 +86,7 @@ typedef struct _MTO_PARAMETERS
 	s32		RSSI_high;
 	s32		RSSI_low;
 
-} MTO_PARAMETERS, *PMTO_PARAMETERS;
+};
 
 
 #define MTO_DATA()                  (adapter->sMtoPara)
@@ -141,26 +97,8 @@ typedef struct _MTO_PARAMETERS
 #define LOCAL_ANTENNA_NO()			(adapter->sLocalPara.bAntennaNo)
 #define LOCAL_IS_CONNECTED()		(adapter->sLocalPara.wConnectedSTAindex != 0)
 #define MTO_INITTXRATE_MODE			(adapter->sHwData.SoftwareSet&0x2)	//bit 1
-// 20040510 Turbo add
-#define MTO_TMR_CNT()               MTO_DATA().TmrCnt
-#define MTO_TOGGLE_STATE()          MTO_DATA().ToggleState
-#define MTO_TX_RATE_REDUCTION_STATE() MTO_DATA().TxRateReductionState
-#define MTO_BACKOFF_TMR()           MTO_DATA().BackoffTmr
-#define MTO_LAST_RATE()             MTO_DATA().Last_Rate
-#define MTO_CO_EFFICENT()           MTO_DATA().Co_efficent
-
-#define MTO_TH_CNT()                MTO_DATA().Th_Cnt
-#define MTO_TH_SQ3()                MTO_DATA().Th_SQ3
-#define MTO_TH_IDLE_SLOT()          MTO_DATA().Th_IdleSlot
-#define MTO_TH_PR_INTERF()          MTO_DATA().Th_PrInterf
-
-#define MTO_TMR_AGING()             MTO_DATA().Tmr_Aging
-#define MTO_TMR_PERIODIC()          MTO_DATA().Tmr_Periodic
 
 #define MTO_POWER_CHANGE_ENABLE()   MTO_DATA().PowerChangeEnable
-#define MTO_ANT_DIVERSITY_ENABLE()  adapter->sLocalPara.boAntennaDiversity
-#define MTO_ANT_MAC()               MTO_DATA().Ant_mac
-#define MTO_ANT_DIVERSITY()         MTO_DATA().Ant_div
 #define MTO_CCA_MODE()              MTO_DATA().CCA_Mode
 #define MTO_CCA_MODE_SETUP()        MTO_DATA().CCA_Mode_Setup
 #define MTO_PREAMBLE_TYPE()         MTO_DATA().Preamble_Type
@@ -179,7 +117,6 @@ typedef struct _MTO_PARAMETERS
 #define MTO_PR_INTERF()             MTO_DATA().Pr_Interf
 #define MTO_AVG_GAP_BTWN_INTERF()   MTO_DATA().AvgGapBtwnInterf
 
-#define MTO_ANT_SEL()               MTO_DATA().Ant_sel
 #define MTO_CNT_ANT(x)              MTO_DATA().Cnt_Ant[(x)]
 #define MTO_SQ_ANT(x)               MTO_DATA().SQ_Ant[(x)]
 #define MTO_AGING_TIMEOUT()         MTO_DATA().aging_timeout
@@ -209,55 +146,6 @@ typedef struct {
 	u8 tx_retry_rate;
 } TXRETRY_REC;
 
-typedef struct _STATISTICS_INFO {
-	u32   Rate54M;
-	u32   Rate48M;
-	u32   Rate36M;
-	u32   Rate24M;
-	u32   Rate18M;
-	u32   Rate12M;
-	u32   Rate9M;
-	u32   Rate6M;
-	u32   Rate11MS;
-	u32   Rate11ML;
-	u32   Rate55MS;
-	u32   Rate55ML;
-	u32   Rate2MS;
-	u32   Rate2ML;
-	u32   Rate1M;
-	u32   Rate54MOK;
-	u32   Rate48MOK;
-	u32   Rate36MOK;
-	u32   Rate24MOK;
-	u32   Rate18MOK;
-	u32   Rate12MOK;
-	u32   Rate9MOK;
-	u32   Rate6MOK;
-	u32   Rate11MSOK;
-	u32   Rate11MLOK;
-	u32   Rate55MSOK;
-	u32   Rate55MLOK;
-	u32   Rate2MSOK;
-	u32   Rate2MLOK;
-	u32   Rate1MOK;
-	u32   SQ3;
-	s32   RSSIAVG;
-	s32   RSSIMAX;
-	s32   TXRATE;
-	s32   TxRetryRate;
-	s32   BSS_PK_CNT;
-	s32   NIDLESLOT;
-	s32   SLOT_CNT;
-	s32   INTERF_CNT;
-	s32   GAP_CNT;
-	s32   DS_EVM;
-	s32   RcvBeaconNum;
-	s32   RXRATE;
-	s32   RxBytes;
-	s32   TxBytes;
-	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);
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 3e8cf08..4d41f6c 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -40,10 +40,11 @@ static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int Pac
 	rx_status.phymode = MODE_IEEE80211B;
 */
 
-	ieee80211_rx_irqsafe(hw, skb, &rx_status);
+	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+	ieee80211_rx_irqsafe(hw, skb);
 }
 
-static void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
+static void Wb35Rx_adjust(struct wb35_descriptor *pRxDes)
 {
 	u32 *	pRxBufferAddress;
 	u32	DecryptionMethod;
@@ -83,7 +84,7 @@ static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
 {
 	struct wbsoft_priv *priv = hw->priv;
 	struct hw_data * pHwData = &priv->sHwData;
-	DESCRIPTOR	RxDes;
+	struct wb35_descriptor	RxDes;
 	struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
 	u8 *		pRxBufferAddress;
 	u16		PacketSize;
diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c
index 1e4169d..5869ef4 100644
--- a/drivers/staging/winbond/wb35tx.c
+++ b/drivers/staging/winbond/wb35tx.c
@@ -30,7 +30,7 @@ static void Wb35Tx_complete(struct urb * pUrb)
 	struct wbsoft_priv *adapter = pUrb->context;
 	struct hw_data *	pHwData = &adapter->sHwData;
 	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
-	PMDS		pMds = &adapter->Mds;
+	struct wb35_mds *pMds = &adapter->Mds;
 
 	printk("wb35: tx complete\n");
 	// Variable setting
@@ -67,7 +67,7 @@ static void Wb35Tx(struct wbsoft_priv *adapter)
 	struct hw_data *	pHwData = &adapter->sHwData;
 	struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
 	u8		*pTxBufferAddress;
-	PMDS		pMds = &adapter->Mds;
+	struct wb35_mds *pMds = &adapter->Mds;
 	struct urb *	pUrb = (struct urb *)pWb35Tx->Tx4Urb;
 	int         	retv;
 	u32		SendIndex;
diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h
index bfdf05d..64a008d 100644
--- a/drivers/staging/winbond/wbhal_f.h
+++ b/drivers/staging/winbond/wbhal_f.h
@@ -39,7 +39,7 @@ void hal_set_cwmax(  struct hw_data * pHwData,  u16 cwin_max );
 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_descriptor_indicate(  struct hw_data * pHwData,  PDESCRIPTOR pDes );
+void hal_descriptor_indicate(  struct hw_data * pHwData,  struct wb35_descriptor *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 )
diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h
index 16d0e6f..372a05e 100644
--- a/drivers/staging/winbond/wbhal_s.h
+++ b/drivers/staging/winbond/wbhal_s.h
@@ -314,7 +314,7 @@ typedef struct _T02_DESCRIPTOR
 	};
 } T02_DESCRIPTOR, *PT02_DESCRIPTOR;
 
-typedef struct _DESCRIPTOR {		// Skip length = 8 DWORD
+struct wb35_descriptor {		// Skip length = 8 DWORD
 	// ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition
 	u8	Descriptor_ID;
 	//----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------
@@ -368,7 +368,7 @@ typedef struct _DESCRIPTOR {		// Skip length = 8 DWORD
 	u16	buffer_size[ MAX_DESCRIPTOR_BUFFER_INDEX ];
 	void*	buffer_address[ MAX_DESCRIPTOR_BUFFER_INDEX ];//931130.4.q
 
-} DESCRIPTOR, *PDESCRIPTOR;
+};
 
 
 #define DEFAULT_NULL_PACKET_COUNT		180000	//20060828.1 Add. 180 seconds
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index 745279c..8950724 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -716,11 +716,6 @@ static int wb35_hw_init(struct ieee80211_hw *hw)
 			priv->sLocalPara.region = REGION_USA;	/* default setting */
 	}
 
-	// Get Software setting flag from hal
-	priv->sLocalPara.boAntennaDiversity = false;
-	if (hal_software_set(pHwData) & 0x00000001)
-		priv->sLocalPara.boAntennaDiversity = true;
-
 	Mds_initial(priv);
 
 	/*
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 51d9e52..925678b 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -128,9 +128,6 @@
 
 #define SUBMIT_URB(u,f)  usb_submit_urb(u,f)
 
-/*================================================================*/
-/* Project Includes */
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211mgmt.h"
@@ -160,13 +157,13 @@ 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 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 */
@@ -175,22 +172,22 @@ 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);
+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);
+hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
 
-static void hfa384x_usbin_ctlx(hfa384x_t * hw, hfa384x_usbin_t * usbin,
+static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
 			       int urb_status);
 
 /*---------------------------------------------------*/
 /* 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);
 
@@ -202,9 +199,9 @@ static void hfa384x_usbctlx_completion_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 *);
@@ -212,35 +209,35 @@ 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_complete_sync(hfa384x_t *hw,
+			      hfa384x_usbctlx_t *ctlx,
+			      usbctlx_completor_t *completor);
 
 static int
-unlocked_usbctlx_cancel_async(hfa384x_t * hw, hfa384x_usbctlx_t * ctlx);
+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);
+usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
+		   hfa384x_cmdresult_t *result);
 
 static void
-usbctlx_get_rridresult(const hfa384x_usb_rridresp_t * rridresp,
-		       hfa384x_rridresult_t * result);
+usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
+		       hfa384x_rridresult_t *result);
 
 /*---------------------------------------------------*/
 /* Low level req/resp CTLX formatters and submitters */
 static int
-hfa384x_docmd(hfa384x_t * hw,
+hfa384x_docmd(hfa384x_t *hw,
 	      CMD_MODE mode,
-	      hfa384x_metacmd_t * cmd,
+	      hfa384x_metacmd_t *cmd,
 	      ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dorrid(hfa384x_t * hw,
+hfa384x_dorrid(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 rid,
 	       void *riddata,
@@ -248,7 +245,7 @@ hfa384x_dorrid(hfa384x_t * hw,
 	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dowrid(hfa384x_t * hw,
+hfa384x_dowrid(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 rid,
 	       void *riddata,
@@ -256,7 +253,7 @@ hfa384x_dowrid(hfa384x_t * hw,
 	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dormem(hfa384x_t * hw,
+hfa384x_dormem(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 page,
 	       u16 offset,
@@ -265,7 +262,7 @@ hfa384x_dormem(hfa384x_t * hw,
 	       ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
 
 static int
-hfa384x_dowmem(hfa384x_t * hw,
+hfa384x_dowmem(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 page,
 	       u16 offset,
@@ -334,7 +331,7 @@ void dbprint_urb(struct urb *urb)
 * 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;
@@ -395,7 +392,7 @@ done:
 * 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;
@@ -532,7 +529,7 @@ static void hfa384x_usb_defer(struct work_struct *data)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-void hfa384x_create(hfa384x_t * hw, struct usb_device *usb)
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb)
 {
 	memset(hw, 0, sizeof(hfa384x_t));
 	hw->usb = usb;
@@ -608,7 +605,7 @@ void hfa384x_create(hfa384x_t * hw, struct usb_device *usb)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-void hfa384x_destroy(hfa384x_t * hw)
+void hfa384x_destroy(hfa384x_t *hw)
 {
 	struct sk_buff *skb;
 
@@ -640,8 +637,8 @@ static hfa384x_usbctlx_t *usbctlx_alloc(void)
 }
 
 static int
-usbctlx_get_status(const hfa384x_usb_cmdresp_t * cmdresp,
-		   hfa384x_cmdresult_t * result)
+usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
+		   hfa384x_cmdresult_t *result)
 {
 	result->status = le16_to_cpu(cmdresp->status);
 	result->resp0 = le16_to_cpu(cmdresp->resp0);
@@ -656,8 +653,8 @@ usbctlx_get_status(const hfa384x_usb_cmdresp_t * cmdresp,
 }
 
 static void
-usbctlx_get_rridresult(const hfa384x_usb_rridresp_t * rridresp,
-		       hfa384x_rridresult_t * result)
+usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
+		       hfa384x_rridresult_t *result)
 {
 	result->rid = le16_to_cpu(rridresp->rid);
 	result->riddata = rridresp->data;
@@ -712,7 +709,7 @@ struct usbctlx_rrid_completor {
 };
 typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t;
 
-static int usbctlx_rrid_completor_fn(usbctlx_completor_t * head)
+static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head)
 {
 	usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t *) head;
 	hfa384x_rridresult_t rridresult;
@@ -733,7 +730,7 @@ static int usbctlx_rrid_completor_fn(usbctlx_completor_t * head)
 }
 
 static inline usbctlx_completor_t *init_rrid_completor(usbctlx_rrid_completor_t
-						       * completor,
+						       *completor,
 						       const
 						       hfa384x_usb_rridresp_t *
 						       rridresp, void *riddata,
@@ -773,7 +770,7 @@ struct usbctlx_rmem_completor {
 };
 typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t;
 
-static int usbctlx_rmem_completor_fn(usbctlx_completor_t * head)
+static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head)
 {
 	usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t *) head;
 
@@ -783,9 +780,9 @@ static int usbctlx_rmem_completor_fn(usbctlx_completor_t * head)
 }
 
 static inline usbctlx_completor_t *init_rmem_completor(usbctlx_rmem_completor_t
-						       * completor,
+						       *completor,
 						       hfa384x_usb_rmemresp_t
-						       * rmemresp, void *data,
+						       *rmemresp, void *data,
 						       unsigned int len)
 {
 	completor->head.complete = usbctlx_rmem_completor_fn;
@@ -816,7 +813,7 @@ static inline usbctlx_completor_t *init_rmem_completor(usbctlx_rmem_completor_t
 * 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)
 {
 	if (ctlx->usercb != NULL) {
 		hfa384x_cmdresult_t cmdresult;
@@ -853,7 +850,7 @@ static void hfa384x_cb_status(hfa384x_t * hw, const hfa384x_usbctlx_t * ctlx)
 * 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)
 {
 	if (ctlx->usercb != NULL) {
 		hfa384x_rridresult_t rridresult;
@@ -870,21 +867,21 @@ static void hfa384x_cb_rrid(hfa384x_t * hw, const hfa384x_usbctlx_t * ctlx)
 	}
 }
 
-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,
+hfa384x_docmd_async(hfa384x_t *hw,
+		    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);
 }
 
 static inline int
-hfa384x_dorrid_wait(hfa384x_t * hw, u16 rid, void *riddata,
+hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
 		    unsigned int riddatalen)
 {
 	return hfa384x_dorrid(hw, DOWAIT,
@@ -892,7 +889,7 @@ hfa384x_dorrid_wait(hfa384x_t * hw, u16 rid, void *riddata,
 }
 
 static inline int
-hfa384x_dorrid_async(hfa384x_t * hw,
+hfa384x_dorrid_async(hfa384x_t *hw,
 		     u16 rid, void *riddata, unsigned int riddatalen,
 		     ctlx_cmdcb_t cmdcb,
 		     ctlx_usercb_t usercb, void *usercb_data)
@@ -903,7 +900,7 @@ hfa384x_dorrid_async(hfa384x_t * hw,
 }
 
 static inline int
-hfa384x_dowrid_wait(hfa384x_t * hw, u16 rid, void *riddata,
+hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
 		    unsigned int riddatalen)
 {
 	return hfa384x_dowrid(hw, DOWAIT,
@@ -911,7 +908,7 @@ hfa384x_dowrid_wait(hfa384x_t * hw, u16 rid, void *riddata,
 }
 
 static inline int
-hfa384x_dowrid_async(hfa384x_t * hw,
+hfa384x_dowrid_async(hfa384x_t *hw,
 		     u16 rid, void *riddata, unsigned int riddatalen,
 		     ctlx_cmdcb_t cmdcb,
 		     ctlx_usercb_t usercb, void *usercb_data)
@@ -922,7 +919,7 @@ hfa384x_dowrid_async(hfa384x_t * hw,
 }
 
 static inline int
-hfa384x_dormem_wait(hfa384x_t * hw,
+hfa384x_dormem_wait(hfa384x_t *hw,
 		    u16 page, u16 offset, void *data, unsigned int len)
 {
 	return hfa384x_dormem(hw, DOWAIT,
@@ -930,7 +927,7 @@ hfa384x_dormem_wait(hfa384x_t * hw,
 }
 
 static inline int
-hfa384x_dormem_async(hfa384x_t * hw,
+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)
@@ -941,7 +938,7 @@ hfa384x_dormem_async(hfa384x_t * hw,
 }
 
 static inline int
-hfa384x_dowmem_wait(hfa384x_t * hw,
+hfa384x_dowmem_wait(hfa384x_t *hw,
 		    u16 page, u16 offset, void *data, unsigned int len)
 {
 	return hfa384x_dowmem(hw, DOWAIT,
@@ -949,7 +946,7 @@ hfa384x_dowmem_wait(hfa384x_t * hw,
 }
 
 static inline int
-hfa384x_dowmem_async(hfa384x_t * hw,
+hfa384x_dowmem_async(hfa384x_t *hw,
 		     u16 page,
 		     u16 offset,
 		     void *data,
@@ -981,7 +978,7 @@ hfa384x_dowmem_async(hfa384x_t * hw,
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_cmd_initialize(hfa384x_t * hw)
+int hfa384x_cmd_initialize(hfa384x_t *hw)
 {
 	int result = 0;
 	int i;
@@ -1029,7 +1026,7 @@ int hfa384x_cmd_initialize(hfa384x_t * hw)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_cmd_disable(hfa384x_t * hw, u16 macport)
+int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
 {
 	int result = 0;
 	hfa384x_metacmd_t cmd;
@@ -1065,7 +1062,7 @@ int hfa384x_cmd_disable(hfa384x_t * hw, u16 macport)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_cmd_enable(hfa384x_t * hw, u16 macport)
+int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
 {
 	int result = 0;
 	hfa384x_metacmd_t cmd;
@@ -1110,7 +1107,7 @@ int hfa384x_cmd_enable(hfa384x_t * hw, u16 macport)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_cmd_monitor(hfa384x_t * hw, u16 enable)
+int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
 {
 	int result = 0;
 	hfa384x_metacmd_t cmd;
@@ -1164,7 +1161,7 @@ int hfa384x_cmd_monitor(hfa384x_t * hw, u16 enable)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_cmd_download(hfa384x_t * hw, u16 mode, u16 lowaddr,
+int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
 			 u16 highaddr, u16 codelen)
 {
 	int result = 0;
@@ -1208,7 +1205,7 @@ int hfa384x_cmd_download(hfa384x_t * hw, u16 mode, u16 lowaddr,
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_corereset(hfa384x_t * hw, int holdtime, int settletime, int genesis)
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
 {
 	int result = 0;
 
@@ -1245,9 +1242,9 @@ int hfa384x_corereset(hfa384x_t * hw, int holdtime, int settletime, int genesis)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-static int hfa384x_usbctlx_complete_sync(hfa384x_t * hw,
-					 hfa384x_usbctlx_t * ctlx,
-					 usbctlx_completor_t * completor)
+static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
+					 hfa384x_usbctlx_t *ctlx,
+					 usbctlx_completor_t *completor)
 {
 	unsigned long flags;
 	int result;
@@ -1361,9 +1358,9 @@ cleanup:
 *	process
 ----------------------------------------------------------------*/
 static int
-hfa384x_docmd(hfa384x_t * hw,
+hfa384x_docmd(hfa384x_t *hw,
 	      CMD_MODE mode,
-	      hfa384x_metacmd_t * cmd,
+	      hfa384x_metacmd_t *cmd,
 	      ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
 {
 	int result;
@@ -1450,7 +1447,7 @@ done:
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dorrid(hfa384x_t * hw,
+hfa384x_dorrid(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 rid,
 	       void *riddata,
@@ -1531,7 +1528,7 @@ done:
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dowrid(hfa384x_t * hw,
+hfa384x_dowrid(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 rid,
 	       void *riddata,
@@ -1618,7 +1615,7 @@ done:
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dormem(hfa384x_t * hw,
+hfa384x_dormem(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 page,
 	       u16 offset,
@@ -1709,7 +1706,7 @@ done:
 *	process (DOWAIT or DOASYNC)
 ----------------------------------------------------------------*/
 static int
-hfa384x_dowmem(hfa384x_t * hw,
+hfa384x_dowmem(hfa384x_t *hw,
 	       CMD_MODE mode,
 	       u16 page,
 	       u16 offset,
@@ -1783,7 +1780,7 @@ done:
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_commtallies(hfa384x_t * hw)
+int hfa384x_drvr_commtallies(hfa384x_t *hw)
 {
 	hfa384x_metacmd_t cmd;
 
@@ -1819,7 +1816,7 @@ int hfa384x_drvr_commtallies(hfa384x_t * hw)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_disable(hfa384x_t * hw, u16 macport)
+int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
 {
 	int result = 0;
 
@@ -1857,7 +1854,7 @@ int hfa384x_drvr_disable(hfa384x_t * hw, u16 macport)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_enable(hfa384x_t * hw, u16 macport)
+int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
 {
 	int result = 0;
 
@@ -1894,7 +1891,7 @@ int hfa384x_drvr_enable(hfa384x_t * hw, u16 macport)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_flashdl_enable(hfa384x_t * hw)
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
 {
 	int result = 0;
 	int i;
@@ -1952,7 +1949,7 @@ int hfa384x_drvr_flashdl_enable(hfa384x_t * hw)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_flashdl_disable(hfa384x_t * hw)
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
 {
 	/* Check that we're already in the download state */
 	if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
@@ -1997,7 +1994,7 @@ int hfa384x_drvr_flashdl_disable(hfa384x_t * hw)
 * 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;
@@ -2143,7 +2140,7 @@ exit_proc:
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_getconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len)
+int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
 {
 	int result;
 
@@ -2180,7 +2177,7 @@ int hfa384x_drvr_getconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len)
  *       Any
  ----------------------------------------------------------------*/
 int
-hfa384x_drvr_getconfig_async(hfa384x_t * hw,
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
 			     u16 rid, ctlx_usercb_t usercb, void *usercb_data)
 {
 	return hfa384x_dorrid_async(hw, rid, NULL, 0,
@@ -2211,7 +2208,7 @@ hfa384x_drvr_getconfig_async(hfa384x_t * hw,
  *       process
  ----------------------------------------------------------------*/
 int
-hfa384x_drvr_setconfig_async(hfa384x_t * hw,
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
 			     u16 rid,
 			     void *buf,
 			     u16 len, ctlx_usercb_t usercb, void *usercb_data)
@@ -2238,7 +2235,7 @@ hfa384x_drvr_setconfig_async(hfa384x_t * hw,
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_ramdl_disable(hfa384x_t * hw)
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
 {
 	/* Check that we're already in the download state */
 	if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
@@ -2278,7 +2275,7 @@ int hfa384x_drvr_ramdl_disable(hfa384x_t * hw)
 * 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;
@@ -2346,7 +2343,7 @@ int hfa384x_drvr_ramdl_enable(hfa384x_t * hw, u32 exeaddr)
 * 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;
@@ -2425,7 +2422,7 @@ int hfa384x_drvr_ramdl_write(hfa384x_t * hw, u32 daddr, void *buf, u32 len)
 * Call context:
 *	process or non-card interrupt.
 ----------------------------------------------------------------*/
-int hfa384x_drvr_readpda(hfa384x_t * hw, void *buf, unsigned int len)
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
 {
 	int result = 0;
 	u16 *pda = buf;
@@ -2531,7 +2528,7 @@ int hfa384x_drvr_readpda(hfa384x_t * hw, void *buf, unsigned int len)
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-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)
 {
 	return hfa384x_dowrid_wait(hw, rid, buf, len);
 }
@@ -2556,7 +2553,7 @@ int hfa384x_drvr_setconfig(hfa384x_t * hw, u16 rid, void *buf, u16 len)
 *	process
 ----------------------------------------------------------------*/
 
-int hfa384x_drvr_start(hfa384x_t * hw)
+int hfa384x_drvr_start(hfa384x_t *hw)
 {
 	int result, result1, result2;
 	u16 status;
@@ -2657,7 +2654,7 @@ done:
 * Call context:
 *	process
 ----------------------------------------------------------------*/
-int hfa384x_drvr_stop(hfa384x_t * hw)
+int hfa384x_drvr_stop(hfa384x_t *hw)
 {
 	int result = 0;
 	int i;
@@ -2708,9 +2705,9 @@ int hfa384x_drvr_stop(hfa384x_t * hw)
 * 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;
@@ -2801,7 +2798,7 @@ exit:
 	return result;
 }
 
-void hfa384x_tx_timeout(wlandevice_t * wlandev)
+void hfa384x_tx_timeout(wlandevice_t *wlandev)
 {
 	hfa384x_t *hw = wlandev->priv;
 	unsigned long flags;
@@ -2950,8 +2947,8 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
 * 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;
 
@@ -3000,7 +2997,7 @@ static int unlocked_usbctlx_cancel_async(hfa384x_t * hw,
 * Call context:
 *	Either, assume interrupt
 ----------------------------------------------------------------*/
-static void unlocked_usbctlx_complete(hfa384x_t * hw, hfa384x_usbctlx_t * ctlx)
+static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
 {
 	/* Timers have been stopped, and ctlx should be in
 	 * a terminal state. Retire it from the "active"
@@ -3038,7 +3035,7 @@ static void unlocked_usbctlx_complete(hfa384x_t * hw, hfa384x_usbctlx_t * ctlx)
 * Call context:
 *	any
 ----------------------------------------------------------------*/
-static void hfa384x_usbctlxq_run(hfa384x_t * hw)
+static void hfa384x_usbctlxq_run(hfa384x_t *hw)
 {
 	unsigned long flags;
 
@@ -3318,7 +3315,7 @@ exit:
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void hfa384x_usbin_ctlx(hfa384x_t * hw, hfa384x_usbin_t * usbin,
+static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
 			       int urb_status)
 {
 	hfa384x_usbctlx_t *ctlx;
@@ -3439,8 +3436,8 @@ unlock:
 * 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;
 
@@ -3470,7 +3467,7 @@ static void hfa384x_usbin_txcompl(wlandevice_t * wlandev,
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void hfa384x_usbin_rx(wlandevice_t * wlandev, struct sk_buff *skb)
+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;
@@ -3573,8 +3570,8 @@ done:
 * 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;
@@ -3677,7 +3674,7 @@ static void hfa384x_int_rxmonitor(wlandevice_t * wlandev,
 * 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)
 {
 	usbin->infofrm.info.framelen =
 	    le16_to_cpu(usbin->infofrm.info.framelen);
@@ -4055,7 +4052,7 @@ static void hfa384x_usb_throttlefn(unsigned long data)
 * 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;
@@ -4096,7 +4093,7 @@ static int hfa384x_usbctlx_submit(hfa384x_t * hw, hfa384x_usbctlx_t * ctlx)
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void hfa384x_usbout_tx(wlandevice_t * wlandev, hfa384x_usbout_t * usbout)
+static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
 {
 	prism2sta_ev_alloc(wlandev);
 }
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index 8b4f396..5952c67 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -102,9 +102,9 @@ static u8 oui_8021h[] = { 0x00, 0x00, 0xf8 };
 * 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;
@@ -230,8 +230,8 @@ int skb_ether_to_p80211(wlandevice_t * wlandev, u32 ethconv,
 }
 
 /* jkriegl: from orinoco, modified */
-static void orinoco_spy_gather(wlandevice_t * wlandev, char *mac,
-			       p80211_rxmeta_t * rxmeta)
+static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
+			       p80211_rxmeta_t *rxmeta)
 {
 	int i;
 
@@ -272,7 +272,7 @@ static void orinoco_spy_gather(wlandevice_t * wlandev, char *mac,
 * Call context:
 *	May be called in interrupt or non-interrupt context
 ----------------------------------------------------------------*/
-int skb_p80211_to_ether(wlandevice_t * wlandev, u32 ethconv,
+int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
 			struct sk_buff *skb)
 {
 	netdevice_t *netdev = wlandev->netdev;
diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h
index 1703c92..419de4d 100644
--- a/drivers/staging/wlan-ng/p80211hdr.h
+++ b/drivers/staging/wlan-ng/p80211hdr.h
@@ -60,17 +60,8 @@
 #ifndef _P80211HDR_H
 #define _P80211HDR_H
 
-/*================================================================*/
-/* System Includes */
-
 #include <linux/if_ether.h>
 
-/*================================================================*/
-/* Project Includes */
-
-/*================================================================*/
-/* Constants */
-
 /*--- Sizes -----------------------------------------------*/
 #define WLAN_CRC_LEN			4
 #define WLAN_BSSID_LEN			6
@@ -121,9 +112,6 @@
 #define WLAN_FSTYPE_CFPOLL		0x06
 #define WLAN_FSTYPE_CFACK_CFPOLL	0x07
 
-/*================================================================*/
-/* Macros */
-
 /*--- FC Macros ----------------------------------------------*/
 /* Macros to get/set the bitfields of the Frame Control Field */
 /*  GET_FC_??? - takes the host byte-order value of an FC     */
@@ -157,9 +145,6 @@
 
 #define DOT11_RATE5_ISBASIC_GET(r)     (((u8)(r)) & BIT(7))
 
-/*================================================================*/
-/* Types */
-
 /* Generic 802.11 Header types */
 
 typedef struct p80211_hdr_a3 {
diff --git a/drivers/staging/wlan-ng/p80211meta.h b/drivers/staging/wlan-ng/p80211meta.h
index c1a677b..b9badcf 100644
--- a/drivers/staging/wlan-ng/p80211meta.h
+++ b/drivers/staging/wlan-ng/p80211meta.h
@@ -57,12 +57,6 @@
 #ifndef _P80211META_H
 #define _P80211META_H
 
-/*================================================================*/
-/* Project Includes */
-
-/*================================================================*/
-/* Types */
-
 /*----------------------------------------------------------------*/
 /* The following structure types are used for the metadata */
 /* representation of category list metadata, group list metadata, */
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
index c925a45..14cdc86 100644
--- a/drivers/staging/wlan-ng/p80211mgmt.h
+++ b/drivers/staging/wlan-ng/p80211mgmt.h
@@ -100,16 +100,10 @@
 #ifndef _P80211MGMT_H
 #define _P80211MGMT_H
 
-/*================================================================*/
-/* Project Includes */
-
 #ifndef  _P80211HDR_H
 #include "p80211hdr.h"
 #endif
 
-/*================================================================*/
-/* Constants */
-
 /*-- Information Element IDs --------------------*/
 #define WLAN_EID_SSID		0
 #define WLAN_EID_SUPP_RATES	1
diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h
index 4ac7727..c691d3e 100644
--- a/drivers/staging/wlan-ng/p80211msg.h
+++ b/drivers/staging/wlan-ng/p80211msg.h
@@ -48,14 +48,8 @@
 #ifndef _P80211MSG_H
 #define _P80211MSG_H
 
-/*================================================================*/
-/* Project Includes */
-
 #define WLAN_DEVNAMELEN_MAX	16
 
-/*--------------------------------------------------------------------*/
-/* Prototype msg type */
-
 typedef struct p80211msg {
 	u32 msgcode;
 	u32 msglen;
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 90f499e..22424c8 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -76,9 +76,6 @@
 #include <net/iw_handler.h>
 #include <net/net_namespace.h>
 
-/*================================================================*/
-/* Project Includes */
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211conv.h"
@@ -94,18 +91,18 @@
 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_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,
+					 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_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 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);
 
 int wlan_watchdog = 5000;
 module_param(wlan_watchdog, int, 0644);
@@ -127,7 +124,7 @@ MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
 * Returns:
 *	nothing
 ----------------------------------------------------------------*/
-static int p80211knetdev_init(netdevice_t * netdev)
+static int p80211knetdev_init(netdevice_t *netdev)
 {
 	/* Called in response to register_netdev */
 	/* This is usually the probe function, but the probe has */
@@ -174,7 +171,7 @@ static struct net_device_stats *p80211knetdev_get_stats(netdevice_t * netdev)
 * 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;
@@ -209,7 +206,7 @@ static int p80211knetdev_open(netdevice_t * netdev)
 * 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;
@@ -236,7 +233,7 @@ static int p80211knetdev_stop(netdevice_t * netdev)
 * Side effects:
 *
 ----------------------------------------------------------------*/
-void p80211netdev_rx(wlandevice_t * wlandev, struct sk_buff *skb)
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
 {
 	/* Enqueue for post-irq processing */
 	skb_queue_tail(&wlandev->nsd_rxq, skb);
@@ -345,7 +342,7 @@ static void p80211netdev_rx_bh(unsigned long arg)
 *	zero on success, non-zero on failure.
 ----------------------------------------------------------------*/
 static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
-					 netdevice_t * netdev)
+					 netdevice_t *netdev)
 {
 	int result = 0;
 	int txresult = -1;
@@ -354,7 +351,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
 	p80211_metawep_t p80211_wep;
 
 	if (skb == NULL)
-		return 0;
+		return NETDEV_TX_OK;
 
 	if (wlandev->state != WLAN_DEVICE_OPEN) {
 		result = 1;
@@ -451,7 +448,7 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
 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);
+		kzfree(p80211_wep.data);
 
 	/* we always free the skb here, never in a lower level. */
 	if (!result)
@@ -472,7 +469,7 @@ failed:
 * Returns:
 *	nothing
 ----------------------------------------------------------------*/
-static void p80211knetdev_set_multicast_list(netdevice_t * dev)
+static void p80211knetdev_set_multicast_list(netdevice_t *dev)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
 
@@ -485,7 +482,7 @@ static void p80211knetdev_set_multicast_list(netdevice_t * dev)
 
 #ifdef SIOCETHTOOL
 
-static int p80211netdev_ethtool(wlandevice_t * wlandev, void __user * useraddr)
+static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
 {
 	u32 ethcmd;
 	struct ethtool_drvinfo info;
@@ -557,7 +554,7 @@ static int p80211netdev_ethtool(wlandevice_t * wlandev, void __user * useraddr)
 *	Process thread (ioctl caller).  TODO: SMP support may require
 *	locks.
 ----------------------------------------------------------------*/
-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)
 {
 	int result = 0;
 	p80211ioctl_req_t *req = (p80211ioctl_req_t *) ifr;
@@ -634,7 +631,7 @@ bail:
 *
 * by: Collin R. Mulliner <collin@mulliner.org>
 ----------------------------------------------------------------*/
-static int p80211knetdev_set_mac_address(netdevice_t * dev, void *addr)
+static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
 {
 	struct sockaddr *new_addr = addr;
 	p80211msg_dot11req_mibset_t dot11req;
@@ -694,7 +691,7 @@ static int p80211knetdev_set_mac_address(netdevice_t * dev, void *addr)
 	return result;
 }
 
-static int wlan_change_mtu(netdevice_t * dev, int new_mtu)
+static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
 {
 	/* 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
 	   and another 8 for wep. */
@@ -742,7 +739,7 @@ static const struct net_device_ops p80211_netdev_ops = {
 *	compiled drivers, this function will be called in the
 *	context of the kernel startup code.
 ----------------------------------------------------------------*/
-int wlan_setup(wlandevice_t * wlandev)
+int wlan_setup(wlandevice_t *wlandev)
 {
 	int result = 0;
 	netdevice_t *dev;
@@ -767,9 +764,6 @@ int wlan_setup(wlandevice_t * wlandev)
 		dev->ml_priv = wlandev;
 		dev->netdev_ops = &p80211_netdev_ops;
 
-#if (WIRELESS_EXT < 21)
-		dev->get_wireless_stats = p80211wext_get_wireless_stats;
-#endif
 		dev->wireless_handlers = &p80211wext_handler_def;
 
 		netif_stop_queue(dev);
@@ -800,7 +794,7 @@ int wlan_setup(wlandevice_t * wlandev)
 *	compiled drivers, this function will be called in the
 *	context of the kernel startup code.
 ----------------------------------------------------------------*/
-int wlan_unsetup(wlandevice_t * wlandev)
+int wlan_unsetup(wlandevice_t *wlandev)
 {
 	int result = 0;
 
@@ -836,7 +830,7 @@ int wlan_unsetup(wlandevice_t * wlandev)
 * Call Context:
 *	Can be either interrupt or not.
 ----------------------------------------------------------------*/
-int register_wlandev(wlandevice_t * wlandev)
+int register_wlandev(wlandevice_t *wlandev)
 {
 	int i = 0;
 
@@ -864,7 +858,7 @@ int register_wlandev(wlandevice_t * wlandev)
 * Call Context:
 *	Can be either interrupt or not.
 ----------------------------------------------------------------*/
-int unregister_wlandev(wlandevice_t * wlandev)
+int unregister_wlandev(wlandevice_t *wlandev)
 {
 	struct sk_buff *skb;
 
@@ -907,7 +901,7 @@ int unregister_wlandev(wlandevice_t * wlandev)
 * Call context:
 *	Usually interrupt.
 ----------------------------------------------------------------*/
-void p80211netdev_hwremoved(wlandevice_t * wlandev)
+void p80211netdev_hwremoved(wlandevice_t *wlandev)
 {
 	wlandev->hwremoved = 1;
 	if (wlandev->state == WLAN_DEVICE_OPEN)
@@ -937,7 +931,7 @@ void p80211netdev_hwremoved(wlandevice_t * wlandev)
 * 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;
@@ -1095,7 +1089,7 @@ static int p80211_rx_typedrop(wlandevice_t * wlandev, u16 fc)
 	return drop;
 }
 
-static void p80211knetdev_tx_timeout(netdevice_t * netdev)
+static void p80211knetdev_tx_timeout(netdevice_t *netdev)
 {
 	wlandevice_t *wlandev = netdev->ml_priv;
 
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index f4fcd2b..8bd9dfb 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -57,9 +57,6 @@
 #include <linux/wireless.h>
 #include <linux/netdevice.h>
 
-/*================================================================*/
-/* Constants */
-
 #undef netdevice_t
 typedef struct net_device netdevice_t;
 
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index 584c419..c88156c 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -73,9 +73,9 @@
 #include "p80211metastruct.h"
 #include "p80211req.h"
 
-static void p80211req_handlemsg(wlandevice_t * wlandev, p80211msg_t * msg);
-static int p80211req_mibset_mibget(wlandevice_t * wlandev,
-				   p80211msg_dot11req_mibget_t * mib_msg,
+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);
 
 /*----------------------------------------------------------------
@@ -150,7 +150,7 @@ int p80211req_dorequest(wlandevice_t * wlandev, u8 * msgbuf)
 * Call context:
 *	Process thread
 ----------------------------------------------------------------*/
-static void p80211req_handlemsg(wlandevice_t * wlandev, p80211msg_t * msg)
+static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg)
 {
 	switch (msg->msgcode) {
 
@@ -180,8 +180,8 @@ static void p80211req_handlemsg(wlandevice_t * wlandev, p80211msg_t * msg)
 	return;
 }
 
-static int p80211req_mibset_mibget(wlandevice_t * wlandev,
-				   p80211msg_dot11req_mibget_t * mib_msg,
+static int p80211req_mibset_mibget(wlandevice_t *wlandev,
+				   p80211msg_dot11req_mibget_t *mib_msg,
 				   int isget)
 {
 	p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 043da1e..2b83ab0 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -57,10 +57,6 @@
 #ifndef _P80211TYPES_H
 #define _P80211TYPES_H
 
-/*================================================================*/
-/* Project Includes */
-/*================================================================*/
-
 /*----------------------------------------------------------------*/
 /* The following constants are indexes into the Mib Category List */
 /* and the Message Category List */
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
index f0b4275..ecbb15b 100644
--- a/drivers/staging/wlan-ng/p80211wep.c
+++ b/drivers/staging/wlan-ng/p80211wep.c
@@ -54,10 +54,7 @@
 #include <linux/random.h>
 #include <linux/kernel.h>
 
-// #define WEP_DEBUG
-
-/*================================================================*/
-/* Project Includes */
+/* #define WEP_DEBUG	*/
 
 #include "p80211hdr.h"
 #include "p80211types.h"
@@ -65,14 +62,8 @@
 #include "p80211conv.h"
 #include "p80211netdev.h"
 
-/*================================================================*/
-/* Local Constants */
-
 #define WEP_KEY(x)       (((x) & 0xC0) >> 6)
 
-/*================================================================*/
-/* Local Static Definitions */
-
 static const u32 wep_crc32_table[256] = {
 	0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
 	0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
@@ -128,15 +119,9 @@ static const u32 wep_crc32_table[256] = {
 	0x2d02ef8dL
 };
 
-/*================================================================*/
-/* Local Function Declarations */
-
-/*================================================================*/
-/* Function Definitions */
-
 /* keylen in bytes! */
 
-int wep_change_key(wlandevice_t * wlandev, int keynum, u8 * key, int keylen)
+int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen)
 {
 	if (keylen < 0)
 		return -1;
@@ -166,8 +151,8 @@ int wep_change_key(wlandevice_t * wlandev, int keynum, u8 * key, int keylen)
   4-byte IV at start of buffer, 4-byte ICV at end of buffer.
   if successful, buf start is payload begin, length -= 8;
  */
-int wep_decrypt(wlandevice_t * wlandev, u8 * buf, u32 len, int key_override,
-		u8 * iv, u8 * icv)
+int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
+		u8 *iv, u8 *icv)
 {
 	u32 i, j, k, crc, keylen;
 	u8 s[256], key[64], c_crc[4];
@@ -245,8 +230,8 @@ int wep_decrypt(wlandevice_t * wlandev, u8 * buf, u32 len, int key_override,
 }
 
 /* encrypts in-place. */
-int wep_encrypt(wlandevice_t * wlandev, u8 * buf, u8 * dst, u32 len, int keynum,
-		u8 * iv, u8 * icv)
+int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+		u8 *iv, u8 *icv)
 {
 	u32 i, j, k, crc, keylen;
 	u8 s[256], key[64];
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
index 984e45d..74d8022 100644
--- a/drivers/staging/wlan-ng/p80211wext.c
+++ b/drivers/staging/wlan-ng/p80211wext.c
@@ -52,9 +52,6 @@
 #include <linux/if_ether.h>
 #include <linux/bitops.h>
 
-/*================================================================*/
-/* Project Includes */
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211conv.h"
@@ -66,10 +63,10 @@
 #include "p80211ioctl.h"
 #include "p80211req.h"
 
-static int p80211wext_giwrate(netdevice_t * dev,
+static int p80211wext_giwrate(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_param *rrq, char *extra);
-static int p80211wext_giwessid(netdevice_t * dev,
+static int p80211wext_giwessid(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *essid);
 
@@ -130,7 +127,7 @@ static int qual_as_percent(int snr)
 	return 100;
 }
 
-static int p80211wext_dorequest(wlandevice_t * wlandev, u32 did, u32 data)
+static int p80211wext_dorequest(wlandevice_t *wlandev, u32 did, u32 data)
 {
 	p80211msg_dot11req_mibset_t msg;
 	p80211item_uint32_t mibitem;
@@ -145,7 +142,7 @@ static int p80211wext_dorequest(wlandevice_t * wlandev, u32 did, u32 data)
 	return result;
 }
 
-static int p80211wext_autojoin(wlandevice_t * wlandev)
+static int p80211wext_autojoin(wlandevice_t *wlandev)
 {
 	p80211msg_lnxreq_autojoin_t msg;
 	struct iw_point data;
@@ -191,7 +188,7 @@ exit:
 }
 
 /* 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;
 	wlandevice_t *wlandev = dev->ml_priv;
@@ -232,7 +229,7 @@ struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev)
 	return wstats;
 }
 
-static int p80211wext_giwname(netdevice_t * dev,
+static int p80211wext_giwname(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      char *name, char *extra)
 {
@@ -261,7 +258,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwfreq(netdevice_t * dev,
+static int p80211wext_giwfreq(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_freq *freq, char *extra)
 {
@@ -296,7 +293,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_siwfreq(netdevice_t * dev,
+static int p80211wext_siwfreq(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_freq *freq, char *extra)
 {
@@ -332,9 +329,9 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwmode(netdevice_t * dev,
+static int p80211wext_giwmode(netdevice_t *dev,
 			      struct iw_request_info *info,
-			      __u32 * mode, char *extra)
+			      __u32 *mode, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
 
@@ -356,9 +353,9 @@ static int p80211wext_giwmode(netdevice_t * dev,
 	return 0;
 }
 
-static int p80211wext_siwmode(netdevice_t * dev,
+static int p80211wext_siwmode(netdevice_t *dev,
 			      struct iw_request_info *info,
-			      __u32 * mode, char *extra)
+			      __u32 *mode, char *extra)
 {
 	wlandevice_t *wlandev = dev->ml_priv;
 	p80211item_uint32_t mibitem;
@@ -411,7 +408,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwrange(netdevice_t * dev,
+static int p80211wext_giwrange(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *extra)
 {
@@ -480,7 +477,7 @@ static int p80211wext_giwrange(netdevice_t * dev,
 	return 0;
 }
 
-static int p80211wext_giwap(netdevice_t * dev,
+static int p80211wext_giwap(netdevice_t *dev,
 			    struct iw_request_info *info,
 			    struct sockaddr *ap_addr, char *extra)
 {
@@ -493,7 +490,7 @@ static int p80211wext_giwap(netdevice_t * dev,
 	return 0;
 }
 
-static int p80211wext_giwencode(netdevice_t * dev,
+static int p80211wext_giwencode(netdevice_t *dev,
 				struct iw_request_info *info,
 				struct iw_point *erq, char *key)
 {
@@ -534,7 +531,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_siwencode(netdevice_t * dev,
+static int p80211wext_siwencode(netdevice_t *dev,
 				struct iw_request_info *info,
 				struct iw_point *erq, char *key)
 {
@@ -681,7 +678,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwessid(netdevice_t * dev,
+static int p80211wext_giwessid(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *essid)
 {
@@ -692,9 +689,6 @@ static int p80211wext_giwessid(netdevice_t * dev,
 		data->flags = 1;
 		memcpy(essid, wlandev->ssid.data, data->length);
 		essid[data->length] = 0;
-#if (WIRELESS_EXT < 21)
-		data->length++;
-#endif
 	} else {
 		memset(essid, 0, sizeof(wlandev->ssid.data));
 		data->length = 0;
@@ -704,7 +698,7 @@ static int p80211wext_giwessid(netdevice_t * dev,
 	return 0;
 }
 
-static int p80211wext_siwessid(netdevice_t * dev,
+static int p80211wext_siwessid(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_point *data, char *essid)
 {
@@ -727,11 +721,6 @@ static int p80211wext_siwessid(netdevice_t * dev,
 
 	msg.msgcode = DIDmsg_lnxreq_autojoin;
 
-#if (WIRELESS_EXT < 21)
-	if (length)
-		length--;
-#endif
-
 	/* Trim the last '\0' to fit the SSID format */
 	if (length && essid[length - 1] == '\0')
 		length--;
@@ -752,7 +741,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_siwcommit(netdevice_t * dev,
+static int p80211wext_siwcommit(netdevice_t *dev,
 				struct iw_request_info *info,
 				struct iw_point *data, char *essid)
 {
@@ -771,7 +760,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwrate(netdevice_t * dev,
+static int p80211wext_giwrate(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_param *rrq, char *extra)
 {
@@ -822,7 +811,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwrts(netdevice_t * dev,
+static int p80211wext_giwrts(netdevice_t *dev,
 			     struct iw_request_info *info,
 			     struct iw_param *rts, char *extra)
 {
@@ -852,7 +841,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_siwrts(netdevice_t * dev,
+static int p80211wext_siwrts(netdevice_t *dev,
 			     struct iw_request_info *info,
 			     struct iw_param *rts, char *extra)
 {
@@ -886,7 +875,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwfrag(netdevice_t * dev,
+static int p80211wext_giwfrag(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_param *frag, char *extra)
 {
@@ -917,7 +906,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_siwfrag(netdevice_t * dev,
+static int p80211wext_siwfrag(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_param *frag, char *extra)
 {
@@ -961,7 +950,7 @@ exit:
 #define IW_RETRY_SHORT IW_RETRY_MIN
 #endif
 
-static int p80211wext_giwretry(netdevice_t * dev,
+static int p80211wext_giwretry(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_param *rrq, char *extra)
 {
@@ -1038,7 +1027,7 @@ exit:
 
 }
 
-static int p80211wext_siwretry(netdevice_t * dev,
+static int p80211wext_siwretry(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_param *rrq, char *extra)
 {
@@ -1109,7 +1098,7 @@ exit:
 
 }
 
-static int p80211wext_siwtxpow(netdevice_t * dev,
+static int p80211wext_siwtxpow(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_param *rrq, char *extra)
 {
@@ -1143,7 +1132,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_giwtxpow(netdevice_t * dev,
+static int p80211wext_giwtxpow(netdevice_t *dev,
 			       struct iw_request_info *info,
 			       struct iw_param *rrq, char *extra)
 {
@@ -1178,7 +1167,7 @@ exit:
 	return err;
 }
 
-static int p80211wext_siwspy(netdevice_t * dev,
+static int p80211wext_siwspy(netdevice_t *dev,
 			     struct iw_request_info *info,
 			     struct iw_point *srq, char *extra)
 {
@@ -1213,7 +1202,7 @@ static int p80211wext_siwspy(netdevice_t * dev,
 }
 
 /* jkriegl: from orinoco, modified */
-static int p80211wext_giwspy(netdevice_t * dev,
+static int p80211wext_giwspy(netdevice_t *dev,
 			     struct iw_request_info *info,
 			     struct iw_point *srq, char *extra)
 {
@@ -1273,7 +1262,7 @@ static int prism2_result2err(int prism2_result)
 	return err;
 }
 
-static int p80211wext_siwscan(netdevice_t * dev,
+static int p80211wext_siwscan(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_point *srq, char *extra)
 {
@@ -1320,7 +1309,7 @@ exit:
  */
 static char *wext_translate_bss(struct iw_request_info *info, char *current_ev,
 				char *end_buf,
-				p80211msg_dot11req_scan_results_t * bss)
+				p80211msg_dot11req_scan_results_t *bss)
 {
 	struct iw_event iwe;	/* Temporary buffer */
 
@@ -1404,7 +1393,7 @@ static char *wext_translate_bss(struct iw_request_info *info, char *current_ev,
 	return current_ev;
 }
 
-static int p80211wext_giwscan(netdevice_t * dev,
+static int p80211wext_giwscan(netdevice_t *dev,
 			      struct iw_request_info *info,
 			      struct iw_point *srq, char *extra)
 {
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index 608b234..7d76a7f 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -47,84 +47,28 @@
 
 /*================================================================*/
 /* System Includes */
-#include <linux/sort.h>
-#include <linux/firmware.h>
+#include <linux/ihex.h>
 
 /*================================================================*/
 /* Local Constants */
 
-#define PRISM2_USB_FWFILE	"prism2_ru.hex"
+#define PRISM2_USB_FWFILE	"prism2_ru.fw"
 
 #define S3DATA_MAX		5000
 #define S3PLUG_MAX		200
 #define S3CRC_MAX		200
 #define S3INFO_MAX		50
-#define SREC_LINE_MAX		264
-#define S3LEN_TXTOFFSET		2
-#define S3LEN_TXTLEN		2
-#define S3ADDR_TXTOFFSET	4
-#define S3ADDR_TXTLEN		8
-#define S3DATA_TXTOFFSET	12
-/*S3DATA_TXTLEN			variable, depends on len field */
-/*S3CKSUM_TXTOFFSET		variable, depends on len field */
-#define S3CKSUM_TXTLEN		2
-#define SERNUM_LEN_MAX		12
-
-#define S3PLUG_ITEMCODE_TXTOFFSET	(S3DATA_TXTOFFSET)
-#define S3PLUG_ITEMCODE_TXTLEN		8
-#define S3PLUG_ADDR_TXTOFFSET		(S3DATA_TXTOFFSET+8)
-#define S3PLUG_ADDR_TXTLEN		8
-#define S3PLUG_LEN_TXTOFFSET		(S3DATA_TXTOFFSET+16)
-#define S3PLUG_LEN_TXTLEN		8
-
-#define S3CRC_ADDR_TXTOFFSET		(S3DATA_TXTOFFSET)
-#define S3CRC_ADDR_TXTLEN		8
-#define S3CRC_LEN_TXTOFFSET		(S3DATA_TXTOFFSET+8)
-#define S3CRC_LEN_TXTLEN		8
-#define S3CRC_DOWRITE_TXTOFFSET		(S3DATA_TXTOFFSET+16)
-#define S3CRC_DOWRITE_TXTLEN		8
-
-#define S3INFO_LEN_TXTOFFSET		(S3DATA_TXTOFFSET)
-#define S3INFO_LEN_TXTLEN		4
-#define S3INFO_TYPE_TXTOFFSET		(S3DATA_TXTOFFSET+4)
-#define S3INFO_TYPE_TXTLEN		4
-#define S3INFO_DATA_TXTOFFSET		(S3DATA_TXTOFFSET+8)
-/* S3INFO_DATA_TXTLEN			variable, depends on INFO_LEN field */
 
 #define S3ADDR_PLUG		(0xff000000UL)
 #define S3ADDR_CRC		(0xff100000UL)
 #define S3ADDR_INFO		(0xff200000UL)
-
-#define PDAFILE_LINE_MAX	1024
+#define S3ADDR_START		(0xff400000UL)
 
 #define CHUNKS_MAX		100
 
 #define WRITESIZE_MAX		4096
 
 /*================================================================*/
-/* Local Macros */
-
-#define bswap_16(x) \
-     (__extension__							      \
-      ({ register unsigned short int __v, __x = (x);			      \
-	   __asm__ ("rorw $8, %w0"					      \
-		    : "=r" (__v)					      \
-		    : "0" (__x)						      \
-		    : "cc");						      \
-	 __v; }))
-
-#define bswap_32(x) \
-     (__extension__							      \
-      ({ register unsigned int __v, __x = (x);				      \
-	   __asm__ ("rorw $8, %w0;"					      \
-		    "rorl $16, %0;"					      \
-		    "rorw $8, %w0"					      \
-		    : "=r" (__v)					      \
-		    : "0" (__x)						      \
-		    : "cc");						      \
-	 __v; }))
-
-/*================================================================*/
 /* Local Types */
 
 typedef struct s3datarec {
@@ -177,19 +121,19 @@ typedef struct imgchunk {
 /* s-record image processing */
 
 /* Data records */
-unsigned int ns3data = 0;
+unsigned int ns3data;
 s3datarec_t s3data[S3DATA_MAX];
 
 /* Plug records */
-unsigned int ns3plug = 0;
+unsigned int ns3plug;
 s3plugrec_t s3plug[S3PLUG_MAX];
 
 /* CRC records */
-unsigned int ns3crc = 0;
+unsigned int ns3crc;
 s3crcrec_t s3crc[S3CRC_MAX];
 
 /* Info records */
-unsigned int ns3info = 0;
+unsigned int ns3info;
 s3inforec_t s3info[S3INFO_MAX];
 
 /* S7 record (there _better_ be only one) */
@@ -214,19 +158,18 @@ hfa384x_caplevel_t priid;
 /*================================================================*/
 /* Local Function Declarations */
 
-int prism2_fwapply(char *rfptr, int rfsize, wlandevice_t * wlandev);
-int read_srecfile(char *rfptr, int rfsize);
-int mkimage(imgchunk_t * clist, unsigned int *ccnt);
-int read_cardpda(pda_t * pda, wlandevice_t * wlandev);
-int mkpdrlist(pda_t * pda);
-int s3datarec_compare(const void *p1, const void *p2);
-int plugimage(imgchunk_t * fchunk, unsigned int nfchunks,
-	      s3plugrec_t * s3plug, unsigned int ns3plug, pda_t * pda);
-int crcimage(imgchunk_t * fchunk, unsigned int nfchunks,
-	     s3crcrec_t * s3crc, unsigned int ns3crc);
-int writeimage(wlandevice_t * wlandev, imgchunk_t * fchunk,
+int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev);
+int read_fwfile(const struct ihex_binrec *rfptr);
+int mkimage(imgchunk_t *clist, unsigned int *ccnt);
+int read_cardpda(pda_t *pda, wlandevice_t *wlandev);
+int mkpdrlist(pda_t *pda);
+int plugimage(imgchunk_t *fchunk, unsigned int nfchunks,
+	      s3plugrec_t *s3plug, unsigned int ns3plug, pda_t * pda);
+int crcimage(imgchunk_t *fchunk, unsigned int nfchunks,
+	     s3crcrec_t *s3crc, unsigned int ns3crc);
+int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
 	       unsigned int nfchunks);
-void free_chunks(imgchunk_t * fchunk, unsigned int *nfchunks);
+void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks);
 void free_srecs(void);
 
 int validate_identity(void);
@@ -247,13 +190,13 @@ int validate_identity(void);
 *	0	- success
 *	~0	- failure
 ----------------------------------------------------------------*/
-int prism2_fwtry(struct usb_device *udev, wlandevice_t * wlandev)
+int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev)
 {
 	const struct firmware *fw_entry = NULL;
 
 	printk(KERN_INFO "prism2_usb: Checking for firmware %s\n",
 	       PRISM2_USB_FWFILE);
-	if (request_firmware(&fw_entry, PRISM2_USB_FWFILE, &udev->dev) != 0) {
+	if (request_ihex_firmware(&fw_entry, PRISM2_USB_FWFILE, &udev->dev) != 0) {
 		printk(KERN_INFO
 		       "prism2_usb: Firmware not available, but not essential\n");
 		printk(KERN_INFO
@@ -263,7 +206,7 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t * wlandev)
 
 	printk(KERN_INFO "prism2_usb: %s will be processed, size %d\n",
 	       PRISM2_USB_FWFILE, fw_entry->size);
-	prism2_fwapply((char *)fw_entry->data, fw_entry->size, wlandev);
+	prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev);
 
 	release_firmware(fw_entry);
 	return 0;
@@ -276,14 +219,13 @@ int prism2_fwtry(struct usb_device *udev, wlandevice_t * wlandev)
 *
 * Arguments:
 *	rfptr	firmware image in kernel memory
-*	rfsize	firmware size in kernel memory
 *	wlandev device
 *
 * Returns:
 *	0	- success
 *	~0	- failure
 ----------------------------------------------------------------*/
-int prism2_fwapply(char *rfptr, int rfsize, wlandevice_t * wlandev)
+int prism2_fwapply(const struct ihex_binrec *rfptr, wlandevice_t *wlandev)
 {
 	signed int result = 0;
 	p80211msg_dot11req_mibget_t getmsg;
@@ -356,13 +298,11 @@ int prism2_fwapply(char *rfptr, int rfsize, wlandevice_t * wlandev)
 	priid.top = *data++;
 
 	/* Read the S3 file */
-	result = read_srecfile(rfptr, rfsize);
+	result = read_fwfile(rfptr);
 	if (result) {
 		printk(KERN_ERR "Failed to read the data exiting.\n");
 		return (1);
 	}
-	/* Sort the S3 data records */
-	sort(s3data, ns3data, sizeof(s3datarec_t), s3datarec_compare, NULL);
 
 	result = validate_identity();
 
@@ -425,7 +365,7 @@ int prism2_fwapply(char *rfptr, int rfsize, wlandevice_t * wlandev)
 *	0	success
 *	~0	failure
 ----------------------------------------------------------------*/
-int crcimage(imgchunk_t * fchunk, unsigned int nfchunks, s3crcrec_t * s3crc,
+int crcimage(imgchunk_t *fchunk, unsigned int nfchunks, s3crcrec_t *s3crc,
 	     unsigned int ns3crc)
 {
 	int result = 0;
@@ -490,7 +430,7 @@ int crcimage(imgchunk_t * fchunk, unsigned int nfchunks, s3crcrec_t * s3crc,
 * Returns:
 *	nothing
 ----------------------------------------------------------------*/
-void free_chunks(imgchunk_t * fchunk, unsigned int *nfchunks)
+void free_chunks(imgchunk_t *fchunk, unsigned int *nfchunks)
 {
 	int i;
 	for (i = 0; i < *nfchunks; i++) {
@@ -516,10 +456,6 @@ void free_chunks(imgchunk_t * fchunk, unsigned int *nfchunks)
 ----------------------------------------------------------------*/
 void free_srecs(void)
 {
-	int i;
-	for (i = 0; i < ns3data; i++) {
-		kfree(s3data[i].data);
-	}
 	ns3data = 0;
 	memset(s3data, 0, sizeof(s3data));
 	ns3plug = 0;
@@ -545,7 +481,7 @@ void free_srecs(void)
 *	0	- success
 *	~0	- failure (probably an errno)
 ----------------------------------------------------------------*/
-int mkimage(imgchunk_t * clist, unsigned int *ccnt)
+int mkimage(imgchunk_t *clist, unsigned int *ccnt)
 {
 	int result = 0;
 	int i;
@@ -598,10 +534,6 @@ int mkimage(imgchunk_t * clist, unsigned int *ccnt)
 			return (1);
 		}
 		memset(clist[i].data, 0, clist[i].len);
-	}
-
-	/* Display chunks */
-	for (i = 0; i < *ccnt; i++) {
 		pr_debug("chunk[%d]: addr=0x%06x len=%d\n",
 			 i, clist[i].addr, clist[i].len);
 	}
@@ -644,7 +576,7 @@ int mkimage(imgchunk_t * clist, unsigned int *ccnt)
 *	0	- success
 *	~0	- failure (probably an errno)
 ----------------------------------------------------------------*/
-int mkpdrlist(pda_t * pda)
+int mkpdrlist(pda_t *pda)
 {
 	int result = 0;
 	u16 *pda16 = (u16 *) pda->buf;
@@ -717,8 +649,8 @@ int mkpdrlist(pda_t * pda)
 *	0	success
 *	~0	failure
 ----------------------------------------------------------------*/
-int plugimage(imgchunk_t * fchunk, unsigned int nfchunks,
-	      s3plugrec_t * s3plug, unsigned int ns3plug, pda_t * pda)
+int plugimage(imgchunk_t *fchunk, unsigned int nfchunks,
+	      s3plugrec_t *s3plug, unsigned int ns3plug, pda_t * pda)
 {
 	int result = 0;
 	int i;			/* plug index */
@@ -825,7 +757,7 @@ int plugimage(imgchunk_t * fchunk, unsigned int nfchunks,
 *	0	- success
 *	~0	- failure (probably an errno)
 ----------------------------------------------------------------*/
-int read_cardpda(pda_t * pda, wlandevice_t * wlandev)
+int read_cardpda(pda_t *pda, wlandevice_t *wlandev)
 {
 	int result = 0;
 	p80211msg_p2req_readpda_t msg;
@@ -856,44 +788,20 @@ int read_cardpda(pda_t * pda, wlandevice_t * wlandev)
 }
 
 /*----------------------------------------------------------------
-* copy_line
+* read_fwfile
 *
-* Copies a line of text, up to \n, \0, or SREC_LINE_MAX, or limit of
-* From array
+* Reads the given fw file which should have been compiled from an srec
+* file. Each record in the fw file will either be a plain data record,
+* a start address record, or other records used for plugging.
 *
-* Arguments:
-*	from	From addr
-*	to	To addr
-*	limit	Addr of last character in From array that can be copied
-*
-* Returns:
-*	Num characters copied
-----------------------------------------------------------------*/
-int copyline(char *from, char *to, char *limit)
-{
-	int c = 0;
-
-	while ((c < SREC_LINE_MAX - 1) && (from + c <= limit) &&
-	       (from[c] != '\n') && (from[c] != '\0')) {
-		to[c] = from[c];
-		c++;
-	}
-
-	to[c] = '\0';
-	return (c < SREC_LINE_MAX - 1) ? c + 1 : c;
-}
-
-/*----------------------------------------------------------------
-* read_srecfile
+* Note that data records are expected to be sorted into
+* ascending address order in the fw file.
 *
-* Reads the given srecord file and loads the records into the
-* s3xxx arrays.  This function can be called repeatedly (once for
-* each of a set of files), if necessary.  This function performs
-* no validation of the data except for the grossest of S-record
-* line format checks.  Don't forget that these will be DOS files...
-* CR/LF at the end of each line.
+* Note also that the start address record, originally an S7 record in
+* the srec file, is expected in the fw file to be like a data record but
+* with a certain address to make it identiable.
 *
-* Here's the SREC format we're dealing with:
+* Here's the SREC format that the fw should have come from:
 * S[37]nnaaaaaaaaddd...dddcc
 *
 *       nn - number of bytes starting with the address field
@@ -902,8 +810,9 @@ int copyline(char *from, char *to, char *limit)
 *       cc - checksum
 *
 * The S7 record's (there should be only one) address value gets
-* saved in startaddr.  It's the start execution address used
-* for RAM downloads.
+* converted to an S3 record with address of 0xff400000, with the
+* start address being stored as a 4 byte data word. That address is
+* the start execution address used for RAM downloads.
 *
 * The S3 records have a collection of subformats indicated by the
 * value of aaaaaaaa:
@@ -927,237 +836,124 @@ int copyline(char *from, char *to, char *limit)
 *                d - (s - 1) little endian words giving the contents of
 *                    the given info type.
 *
+*   0xff400000 - Start address record, data field format:
+*                aaaaaaaa
+*                a - Address in load image to plug (little endian)
+*
 * Arguments:
-*	rfptr	firmware image (s-record structure) in kernel memory
-*	rfsize	firmware size in kernel memory
+*	record	firmware image (ihex record structure) in kernel memory
 *
 * Returns:
 *	0	- success
 *	~0	- failure (probably an errno)
 ----------------------------------------------------------------*/
-int read_srecfile(char *rfptr, int rfsize)
+int read_fwfile(const struct ihex_binrec *record)
 {
-	int result = 0;
-	char buf[SREC_LINE_MAX];
-	char tmpbuf[30];
-	s3datarec_t tmprec;
-	int i, c;
-	int line = 0;
-	u16 *tmpinfo;
-	char *endptr = rfptr + rfsize;
-
-	pr_debug("Reading S-record file ...\n");
-
-	while ((c = copyline(rfptr, buf, endptr)) >= 12) {
-		rfptr = rfptr + c;
-		line++;
-		if (buf[0] != 'S') {
-			printk(KERN_ERR "%d warning: No initial \'S\'\n", line);
-			return 1;
-		}
-		if (buf[1] == '7') {	/* S7 record, start address */
-			buf[12] = '\0';
-			startaddr = simple_strtoul(buf + 4, NULL, 16);
-			pr_debug("  S7 start addr, line=%d "
-				 " addr=0x%08x\n", line, startaddr);
-			continue;
-		} else if (buf[1] == '3') {
-			/* Ok, it's an S3, parse and put it in the right array */
-			/* Record Length field (we only want datalen) */
-			memcpy(tmpbuf, buf + S3LEN_TXTOFFSET, S3LEN_TXTLEN);
-			tmpbuf[S3LEN_TXTLEN] = '\0';
-			tmprec.len = simple_strtoul(tmpbuf, NULL, 16) - 4 - 1;	/* 4=addr, 1=cksum */
-			/* Address field */
-			memcpy(tmpbuf, buf + S3ADDR_TXTOFFSET, S3ADDR_TXTLEN);
-			tmpbuf[S3ADDR_TXTLEN] = '\0';
-			tmprec.addr = simple_strtoul(tmpbuf, NULL, 16);
-			/* Checksum field */
-			tmprec.checksum =
-			    simple_strtoul(buf + strlen(buf) - 2, NULL, 16);
-
-			switch (tmprec.addr) {
-			case S3ADDR_PLUG:
-				memcpy(tmpbuf, buf + S3PLUG_ITEMCODE_TXTOFFSET,
-				       S3PLUG_ITEMCODE_TXTLEN);
-				tmpbuf[S3PLUG_ITEMCODE_TXTLEN] = '\0';
-				s3plug[ns3plug].itemcode =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3plug[ns3plug].itemcode =
-				    bswap_32(s3plug[ns3plug].itemcode);
-
-				memcpy(tmpbuf, buf + S3PLUG_ADDR_TXTOFFSET,
-				       S3PLUG_ADDR_TXTLEN);
-				tmpbuf[S3PLUG_ADDR_TXTLEN] = '\0';
-				s3plug[ns3plug].addr =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3plug[ns3plug].addr =
-				    bswap_32(s3plug[ns3plug].addr);
-
-				memcpy(tmpbuf, buf + S3PLUG_LEN_TXTOFFSET,
-				       S3PLUG_LEN_TXTLEN);
-				tmpbuf[S3PLUG_LEN_TXTLEN] = '\0';
-				s3plug[ns3plug].len =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3plug[ns3plug].len =
-				    bswap_32(s3plug[ns3plug].len);
-
-				pr_debug("  S3 plugrec, line=%d "
-					 "itemcode=0x%04x addr=0x%08x len=%d\n",
-					 line,
-					 s3plug[ns3plug].itemcode,
-					 s3plug[ns3plug].addr,
-					 s3plug[ns3plug].len);
-
-				ns3plug++;
-				if (ns3plug == S3PLUG_MAX) {
-					printk(KERN_ERR
-					       "S3 plugrec limit reached - aborting\n");
-					return 1;
-				}
-				break;
-			case S3ADDR_CRC:
-				memcpy(tmpbuf, buf + S3CRC_ADDR_TXTOFFSET,
-				       S3CRC_ADDR_TXTLEN);
-				tmpbuf[S3CRC_ADDR_TXTLEN] = '\0';
-				s3crc[ns3crc].addr =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3crc[ns3crc].addr =
-				    bswap_32(s3crc[ns3crc].addr);
-
-				memcpy(tmpbuf, buf + S3CRC_LEN_TXTOFFSET,
-				       S3CRC_LEN_TXTLEN);
-				tmpbuf[S3CRC_LEN_TXTLEN] = '\0';
-				s3crc[ns3crc].len =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3crc[ns3crc].len = bswap_32(s3crc[ns3crc].len);
-
-				memcpy(tmpbuf, buf + S3CRC_DOWRITE_TXTOFFSET,
-				       S3CRC_DOWRITE_TXTLEN);
-				tmpbuf[S3CRC_DOWRITE_TXTLEN] = '\0';
-				s3crc[ns3crc].dowrite =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3crc[ns3crc].dowrite =
-				    bswap_32(s3crc[ns3crc].dowrite);
-
-				pr_debug("  S3 crcrec, line=%d "
-					 "addr=0x%08x len=%d write=0x%08x\n",
-					 line,
-					 s3crc[ns3crc].addr,
-					 s3crc[ns3crc].len,
-					 s3crc[ns3crc].dowrite);
-				ns3crc++;
-				if (ns3crc == S3CRC_MAX) {
-					printk(KERN_ERR
-					       "S3 crcrec limit reached - aborting\n");
-					return 1;
-				}
-				break;
-			case S3ADDR_INFO:
-				memcpy(tmpbuf, buf + S3INFO_LEN_TXTOFFSET,
-				       S3INFO_LEN_TXTLEN);
-				tmpbuf[S3INFO_LEN_TXTLEN] = '\0';
-				s3info[ns3info].len =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3info[ns3info].len =
-				    bswap_16(s3info[ns3info].len);
-
-				memcpy(tmpbuf, buf + S3INFO_TYPE_TXTOFFSET,
-				       S3INFO_TYPE_TXTLEN);
-				tmpbuf[S3INFO_TYPE_TXTLEN] = '\0';
-				s3info[ns3info].type =
-				    simple_strtoul(tmpbuf, NULL, 16);
-				s3info[ns3info].type =
-				    bswap_16(s3info[ns3info].type);
-
-				pr_debug("  S3 inforec, line=%d "
-					 "len=0x%04x type=0x%04x\n",
-					 line,
-					 s3info[ns3info].len,
-					 s3info[ns3info].type);
-				if (((s3info[ns3info].len - 1) * sizeof(u16)) >
-				    sizeof(s3info[ns3info].info)) {
-					printk(KERN_ERR
-					       " S3 inforec length too long - aborting\n");
-					return 1;
-				}
+	int		i;
+	int		rcnt = 0;
+	u16		*tmpinfo;
+	u16		*ptr16;
+	u32		*ptr32, len, addr;
 
-				tmpinfo =
-				    (u16 *) & (s3info[ns3info].info.version);
-				for (i = 0; i < s3info[ns3info].len - 1; i++) {
-					memcpy(tmpbuf,
-					       buf + S3INFO_DATA_TXTOFFSET +
-					       (i * 4), 4);
-					tmpbuf[4] = '\0';
-					tmpinfo[i] =
-					    simple_strtoul(tmpbuf, NULL, 16);
-					tmpinfo[i] = bswap_16(tmpinfo[i]);
-				}
-				pr_debug("            info=");
-				for (i = 0; i < s3info[ns3info].len - 1; i++) {
-					pr_debug("%04x ", tmpinfo[i]);
-				}
-				pr_debug("\n");
+	pr_debug("Reading fw file ...\n");
 
-				ns3info++;
-				if (ns3info == S3INFO_MAX) {
-					printk(KERN_ERR
-					       "S3 inforec limit reached - aborting\n");
-					return 1;
-				}
-				break;
-			default:	/* Data record */
-				s3data[ns3data].addr = tmprec.addr;
-				s3data[ns3data].len = tmprec.len;
-				s3data[ns3data].checksum = tmprec.checksum;
-				s3data[ns3data].data =
-				    kmalloc(tmprec.len, GFP_KERNEL);
-				for (i = 0; i < tmprec.len; i++) {
-					memcpy(tmpbuf,
-					       buf + S3DATA_TXTOFFSET + (i * 2),
-					       2);
-					tmpbuf[2] = '\0';
-					s3data[ns3data].data[i] =
-					    simple_strtoul(tmpbuf, NULL, 16);
-				}
-				ns3data++;
-				if (ns3data == S3DATA_MAX) {
-					printk(KERN_ERR
-					       "S3 datarec limit reached - aborting\n");
-					return 1;
-				}
-				break;
+	while (record) {
+
+		rcnt++;
+
+		len = be16_to_cpu(record->len);
+		addr = be32_to_cpu(record->addr);
+
+		/* Point into data for different word lengths */
+		ptr32 = (u32 *) record->data;
+		ptr16 = (u16 *) record->data;
+
+		/* parse what was an S3 srec and put it in the right array */
+		switch(addr) {
+		case S3ADDR_START:
+			startaddr = *ptr32;
+			pr_debug("  S7 start addr, record=%d "
+				      " addr=0x%08x\n",
+				      rcnt,
+				      startaddr);
+			break;
+		case S3ADDR_PLUG:
+			s3plug[ns3plug].itemcode = *ptr32;
+			s3plug[ns3plug].addr = *(ptr32 + 1);
+			s3plug[ns3plug].len = *(ptr32 + 2);
+
+			pr_debug("  S3 plugrec, record=%d "
+				      "itemcode=0x%08x addr=0x%08x len=%d\n",
+				      rcnt,
+				      s3plug[ns3plug].itemcode,
+				      s3plug[ns3plug].addr,
+				      s3plug[ns3plug].len);
+
+			ns3plug++;
+			if ( ns3plug == S3PLUG_MAX ) {
+				printk(KERN_ERR "S3 plugrec limit reached - aborting\n");
+				return 1;
 			}
-		} else {
-			printk(KERN_WARNING
-			       "%d warning: Unknown S-record detected.\n",
-			       line);
+			break;
+		case S3ADDR_CRC:
+			s3crc[ns3crc].addr = *ptr32;
+			s3crc[ns3crc].len = *(ptr32 + 1);
+			s3crc[ns3crc].dowrite = *(ptr32 + 2);
+
+			pr_debug("  S3 crcrec, record=%d "
+				      "addr=0x%08x len=%d write=0x%08x\n",
+				      rcnt,
+				      s3crc[ns3crc].addr,
+				      s3crc[ns3crc].len,
+				      s3crc[ns3crc].dowrite);
+			ns3crc++;
+			if ( ns3crc == S3CRC_MAX ) {
+				printk(KERN_ERR "S3 crcrec limit reached - aborting\n");
+				return 1;
+			}
+			break;
+		case S3ADDR_INFO:
+			s3info[ns3info].len = *ptr16;
+			s3info[ns3info].type = *(ptr16 + 1);
+
+			pr_debug("  S3 inforec, record=%d "
+			      "len=0x%04x type=0x%04x\n",
+				      rcnt,
+				      s3info[ns3info].len,
+				      s3info[ns3info].type);
+			if ( ((s3info[ns3info].len - 1) * sizeof(u16)) > sizeof(s3info[ns3info].info) ) {
+				printk(KERN_ERR " S3 inforec length too long - aborting\n");
+				return 1;
+			}
+
+			tmpinfo = (u16*)&(s3info[ns3info].info.version);
+			pr_debug("            info=");
+			for (i = 0; i < s3info[ns3info].len - 1; i++) {
+				tmpinfo[i] = *(ptr16 + 2 + i);
+				pr_debug("%04x ", tmpinfo[i]);
+			}
+			pr_debug("\n");
+
+			ns3info++;
+			if ( ns3info == S3INFO_MAX ) {
+				printk(KERN_ERR "S3 inforec limit reached - aborting\n");
+				return 1;
+			}
+			break;
+		default:	/* Data record */
+			s3data[ns3data].addr = addr;
+			s3data[ns3data].len = len;
+			s3data[ns3data].data = (uint8_t *) record->data;
+			ns3data++;
+			if ( ns3data == S3DATA_MAX ) {
+				printk(KERN_ERR "S3 datarec limit reached - aborting\n");
+				return 1;
+			}
+			break;
 		}
+		record = ihex_next_binrec(record);
 	}
-	return result;
-}
-
-/*----------------------------------------------------------------
-* s3datarec_compare
-*
-* Comparison function for sort().
-*
-* Arguments:
-*	p1	ptr to the first item
-*	p2	ptr to the second item
-* Returns:
-*	0	items are equal
-*	<0	p1 < p2
-*	>0	p1 > p2
-----------------------------------------------------------------*/
-int s3datarec_compare(const void *p1, const void *p2)
-{
-	const s3datarec_t *s1 = p1;
-	const s3datarec_t *s2 = p2;
-	if (s1->addr == s2->addr)
-		return 0;
-	if (s1->addr < s2->addr)
-		return -1;
-	return 1;
+	return 0;
 }
 
 /*----------------------------------------------------------------
@@ -1175,7 +971,7 @@ int s3datarec_compare(const void *p1, const void *p2)
 *	0	success
 *	~0	failure
 ----------------------------------------------------------------*/
-int writeimage(wlandevice_t * wlandev, imgchunk_t * fchunk,
+int writeimage(wlandevice_t *wlandev, imgchunk_t *fchunk,
 	       unsigned int nfchunks)
 {
 	int result = 0;
@@ -1316,6 +1112,7 @@ int validate_identity(void)
 {
 	int i;
 	int result = 1;
+	int trump = 0;
 
 	pr_debug("NIC ID: %#x v%d.%d.%d\n",
 		 nicid.id, nicid.major, nicid.minor, nicid.variant);
@@ -1389,8 +1186,7 @@ int validate_identity(void)
 			    (nicid.id != 0x8008))
 				continue;
 
-			if (result != 2)
-				result = 0;
+			trump = 1;
 			break;
 		case 0x8001:
 			pr_debug("name inforec len %d\n", s3info[i].len);
@@ -1402,5 +1198,6 @@ int validate_identity(void)
 	}
 	// walk through
 
+	if (trump && (result != 2)) result = 0;
 	return result;
 }
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index 4654576..9f7d96c 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -73,9 +73,6 @@
 #include <linux/usb.h>
 #include <linux/bitops.h>
 
-/*================================================================*/
-/* Project Includes */
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211mgmt.h"
@@ -117,7 +114,7 @@
 *	process thread  (usually)
 *	interrupt
 ----------------------------------------------------------------*/
-int prism2mgmt_scan(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
 {
 	int result = 0;
 	hfa384x_t *hw = wlandev->priv;
@@ -362,7 +359,7 @@ exit:
 *	process thread  (usually)
 *	interrupt
 ----------------------------------------------------------------*/
-int prism2mgmt_scan_results(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
 {
 	int result = 0;
 	p80211msg_dot11req_scan_results_t *req;
@@ -511,7 +508,7 @@ exit:
 *	process thread  (usually)
 *	interrupt
 ----------------------------------------------------------------*/
-int prism2mgmt_start(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
 {
 	int result = 0;
 	hfa384x_t *hw = wlandev->priv;
@@ -688,7 +685,7 @@ done:
 * Call context:
 *	process thread  (usually)
 ----------------------------------------------------------------*/
-int prism2mgmt_readpda(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
 {
 	hfa384x_t *hw = wlandev->priv;
 	p80211msg_p2req_readpda_t *msg = msgp;
@@ -754,7 +751,7 @@ int prism2mgmt_readpda(wlandevice_t * wlandev, void *msgp)
 * Call context:
 *	process thread  (usually)
 ----------------------------------------------------------------*/
-int prism2mgmt_ramdl_state(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
 {
 	hfa384x_t *hw = wlandev->priv;
 	p80211msg_p2req_ramdl_state_t *msg = msgp;
@@ -810,7 +807,7 @@ int prism2mgmt_ramdl_state(wlandevice_t * wlandev, void *msgp)
 * Call context:
 *	process thread  (usually)
 ----------------------------------------------------------------*/
-int prism2mgmt_ramdl_write(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
 {
 	hfa384x_t *hw = wlandev->priv;
 	p80211msg_p2req_ramdl_write_t *msg = msgp;
@@ -872,7 +869,7 @@ int prism2mgmt_ramdl_write(wlandevice_t * wlandev, void *msgp)
 * Call context:
 *	process thread  (usually)
 ----------------------------------------------------------------*/
-int prism2mgmt_flashdl_state(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
 {
 	int result = 0;
 	hfa384x_t *hw = wlandev->priv;
@@ -943,7 +940,7 @@ int prism2mgmt_flashdl_state(wlandevice_t * wlandev, void *msgp)
 * Call context:
 *	process thread  (usually)
 ----------------------------------------------------------------*/
-int prism2mgmt_flashdl_write(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
 {
 	hfa384x_t *hw = wlandev->priv;
 	p80211msg_p2req_flashdl_write_t *msg = msgp;
@@ -1004,7 +1001,7 @@ int prism2mgmt_flashdl_write(wlandevice_t * wlandev, void *msgp)
 *	process thread  (usually)
 *	interrupt
 ----------------------------------------------------------------*/
-int prism2mgmt_autojoin(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
 {
 	hfa384x_t *hw = wlandev->priv;
 	int result = 0;
@@ -1075,7 +1072,7 @@ int prism2mgmt_autojoin(wlandevice_t * wlandev, void *msgp)
 *	process thread  (usually)
 *	interrupt
 ----------------------------------------------------------------*/
-int prism2mgmt_wlansniff(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
 {
 	int result = 0;
 	p80211msg_lnxreq_wlansniff_t *msg = msgp;
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
index f930254..2fff0a1 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -86,65 +86,65 @@ typedef struct mibrec {
 	u16 parm1;
 	u16 parm2;
 	u16 parm3;
-	int (*func) (struct mibrec * mib,
+	int (*func) (struct mibrec *mib,
 		     int isget,
-		     wlandevice_t * wlandev,
-		     hfa384x_t * hw,
-		     p80211msg_dot11req_mibset_t * msg, void *data);
+		     wlandevice_t *wlandev,
+		     hfa384x_t *hw,
+		     p80211msg_dot11req_mibset_t *msg, void *data);
 } mibrec_t;
 
-static int prism2mib_bytearea2pstr(mibrec_t * mib,
+static int prism2mib_bytearea2pstr(mibrec_t *mib,
 				   int isget,
-				   wlandevice_t * wlandev,
-				   hfa384x_t * hw,
-				   p80211msg_dot11req_mibset_t * msg,
+				   wlandevice_t *wlandev,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
 				   void *data);
 
-static int prism2mib_uint32(mibrec_t * mib,
+static int prism2mib_uint32(mibrec_t *mib,
 			    int isget,
-			    wlandevice_t * wlandev,
-			    hfa384x_t * hw,
-			    p80211msg_dot11req_mibset_t * msg, void *data);
+			    wlandevice_t *wlandev,
+			    hfa384x_t *hw,
+			    p80211msg_dot11req_mibset_t *msg, void *data);
 
-static int prism2mib_flag(mibrec_t * mib,
+static int prism2mib_flag(mibrec_t *mib,
 			  int isget,
-			  wlandevice_t * wlandev,
-			  hfa384x_t * hw,
-			  p80211msg_dot11req_mibset_t * msg, void *data);
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data);
 
-static int prism2mib_wepdefaultkey(mibrec_t * mib,
+static int prism2mib_wepdefaultkey(mibrec_t *mib,
 				   int isget,
 				   wlandevice_t * wlandev,
-				   hfa384x_t * hw,
-				   p80211msg_dot11req_mibset_t * msg,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
 				   void *data);
 
-static int prism2mib_privacyinvoked(mibrec_t * mib,
+static int prism2mib_privacyinvoked(mibrec_t *mib,
 				    int isget,
-				    wlandevice_t * wlandev,
-				    hfa384x_t * hw,
-				    p80211msg_dot11req_mibset_t * msg,
+				    wlandevice_t *wlandev,
+				    hfa384x_t *hw,
+				    p80211msg_dot11req_mibset_t *msg,
 				    void *data);
 
-static int prism2mib_excludeunencrypted(mibrec_t * mib,
+static int prism2mib_excludeunencrypted(mibrec_t *mib,
 					int isget,
-					wlandevice_t * wlandev,
-					hfa384x_t * hw,
-					p80211msg_dot11req_mibset_t * msg,
+					wlandevice_t *wlandev,
+					hfa384x_t *hw,
+					p80211msg_dot11req_mibset_t *msg,
 					void *data);
 
-static int prism2mib_fragmentationthreshold(mibrec_t * mib,
+static int prism2mib_fragmentationthreshold(mibrec_t *mib,
 					    int isget,
-					    wlandevice_t * wlandev,
-					    hfa384x_t * hw,
-					    p80211msg_dot11req_mibset_t * msg,
+					    wlandevice_t *wlandev,
+					    hfa384x_t *hw,
+					    p80211msg_dot11req_mibset_t *msg,
 					    void *data);
 
-static int prism2mib_priv(mibrec_t * mib,
+static int prism2mib_priv(mibrec_t *mib,
 			  int isget,
-			  wlandevice_t * wlandev,
-			  hfa384x_t * hw,
-			  p80211msg_dot11req_mibset_t * msg, void *data);
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data);
 
 static mibrec_t mibtab[] = {
 
@@ -258,7 +258,7 @@ static mibrec_t mibtab[] = {
 *	interrupt
 ----------------------------------------------------------------*/
 
-int prism2mgmt_mibset_mibget(wlandevice_t * wlandev, void *msgp)
+int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
 {
 	hfa384x_t *hw = wlandev->priv;
 	int result, isget;
@@ -372,11 +372,11 @@ done:
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_bytearea2pstr(mibrec_t * mib,
+static int prism2mib_bytearea2pstr(mibrec_t *mib,
 				   int isget,
-				   wlandevice_t * wlandev,
-				   hfa384x_t * hw,
-				   p80211msg_dot11req_mibset_t * msg,
+				   wlandevice_t *wlandev,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
 				   void *data)
 {
 	int result;
@@ -422,11 +422,11 @@ static int prism2mib_bytearea2pstr(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_uint32(mibrec_t * mib,
+static int prism2mib_uint32(mibrec_t *mib,
 			    int isget,
-			    wlandevice_t * wlandev,
-			    hfa384x_t * hw,
-			    p80211msg_dot11req_mibset_t * msg, void *data)
+			    wlandevice_t *wlandev,
+			    hfa384x_t *hw,
+			    p80211msg_dot11req_mibset_t *msg, void *data)
 {
 	int result;
 	u32 *uint32 = (u32 *) data;
@@ -469,11 +469,11 @@ static int prism2mib_uint32(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_flag(mibrec_t * mib,
+static int prism2mib_flag(mibrec_t *mib,
 			  int isget,
-			  wlandevice_t * wlandev,
-			  hfa384x_t * hw,
-			  p80211msg_dot11req_mibset_t * msg, void *data)
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data)
 {
 	int result;
 	u32 *uint32 = (u32 *) data;
@@ -526,11 +526,11 @@ static int prism2mib_flag(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_wepdefaultkey(mibrec_t * mib,
+static int prism2mib_wepdefaultkey(mibrec_t *mib,
 				   int isget,
-				   wlandevice_t * wlandev,
-				   hfa384x_t * hw,
-				   p80211msg_dot11req_mibset_t * msg,
+				   wlandevice_t *wlandev,
+				   hfa384x_t *hw,
+				   p80211msg_dot11req_mibset_t *msg,
 				   void *data)
 {
 	int result;
@@ -576,11 +576,11 @@ static int prism2mib_wepdefaultkey(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_privacyinvoked(mibrec_t * mib,
+static int prism2mib_privacyinvoked(mibrec_t *mib,
 				    int isget,
-				    wlandevice_t * wlandev,
-				    hfa384x_t * hw,
-				    p80211msg_dot11req_mibset_t * msg,
+				    wlandevice_t *wlandev,
+				    hfa384x_t *hw,
+				    p80211msg_dot11req_mibset_t *msg,
 				    void *data)
 {
 	int result;
@@ -622,11 +622,11 @@ static int prism2mib_privacyinvoked(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_excludeunencrypted(mibrec_t * mib,
+static int prism2mib_excludeunencrypted(mibrec_t *mib,
 					int isget,
-					wlandevice_t * wlandev,
-					hfa384x_t * hw,
-					p80211msg_dot11req_mibset_t * msg,
+					wlandevice_t *wlandev,
+					hfa384x_t *hw,
+					p80211msg_dot11req_mibset_t *msg,
 					void *data)
 {
 	int result;
@@ -661,11 +661,11 @@ static int prism2mib_excludeunencrypted(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_fragmentationthreshold(mibrec_t * mib,
+static int prism2mib_fragmentationthreshold(mibrec_t *mib,
 					    int isget,
-					    wlandevice_t * wlandev,
-					    hfa384x_t * hw,
-					    p80211msg_dot11req_mibset_t * msg,
+					    wlandevice_t *wlandev,
+					    hfa384x_t *hw,
+					    p80211msg_dot11req_mibset_t *msg,
 					    void *data)
 {
 	int result;
@@ -710,11 +710,11 @@ static int prism2mib_fragmentationthreshold(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-static int prism2mib_priv(mibrec_t * mib,
+static int prism2mib_priv(mibrec_t *mib,
 			  int isget,
-			  wlandevice_t * wlandev,
-			  hfa384x_t * hw,
-			  p80211msg_dot11req_mibset_t * msg, void *data)
+			  wlandevice_t *wlandev,
+			  hfa384x_t *hw,
+			  p80211msg_dot11req_mibset_t *msg, void *data)
 {
 	p80211pstrd_t *pstr = (p80211pstrd_t *) data;
 
@@ -764,7 +764,7 @@ static int prism2mib_priv(mibrec_t * mib,
 *
 ----------------------------------------------------------------*/
 
-void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr)
+void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
 {
 	bytestr->len = cpu_to_le16((u16) (pstr->len));
 	memcpy(bytestr->data, pstr->data, pstr->len);
@@ -785,7 +785,7 @@ void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr)
 *
 ----------------------------------------------------------------*/
 
-void prism2mgmt_pstr2bytearea(u8 * bytearea, p80211pstrd_t * pstr)
+void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr)
 {
 	memcpy(bytearea, pstr->data, pstr->len);
 }
@@ -805,7 +805,7 @@ void prism2mgmt_pstr2bytearea(u8 * bytearea, p80211pstrd_t * pstr)
 *
 ----------------------------------------------------------------*/
 
-void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr)
+void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
 {
 	pstr->len = (u8) (le16_to_cpu((u16) (bytestr->len)));
 	memcpy(pstr->data, bytestr->data, pstr->len);
@@ -826,7 +826,7 @@ void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t * bytestr, p80211pstrd_t * pstr)
 *
 ----------------------------------------------------------------*/
 
-void prism2mgmt_bytearea2pstr(u8 * bytearea, p80211pstrd_t * pstr, int len)
+void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len)
 {
 	pstr->len = (u8) len;
 	memcpy(pstr->data, bytearea, len);
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index f493cf4..50f301d 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -71,9 +71,6 @@
 #include <linux/if_ether.h>
 #include <linux/bitops.h>
 
-/*================================================================*/
-/* Project Includes */
-
 #include "p80211types.h"
 #include "p80211hdr.h"
 #include "p80211mgmt.h"
@@ -115,7 +112,7 @@ static wlandevice_t *create_wlan(void);
 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;	/* Do a reset at init? */
 
 module_param(prism2_doreset, int, 0644);
 MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
@@ -127,37 +124,37 @@ MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
 
 MODULE_LICENSE("Dual MPL/GPL");
 
-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);
+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);
 
 /*----------------------------------------------------------------
 * prism2sta_open
@@ -180,7 +177,7 @@ static void prism2sta_inf_psusercnt(wlandevice_t * wlandev,
 * Call context:
 *	process thread
 ----------------------------------------------------------------*/
-static int prism2sta_open(wlandevice_t * wlandev)
+static int prism2sta_open(wlandevice_t *wlandev)
 {
 	/* We don't currently have to do anything else.
 	 * The setup of the MAC should be subsequently completed via
@@ -214,7 +211,7 @@ static int prism2sta_open(wlandevice_t * wlandev)
 * Call context:
 *	process thread
 ----------------------------------------------------------------*/
-static int prism2sta_close(wlandevice_t * wlandev)
+static int prism2sta_close(wlandevice_t *wlandev)
 {
 	/* We don't currently have to do anything else.
 	 * Higher layers know we're not ready from dev->start==0 and
@@ -242,7 +239,7 @@ static int prism2sta_close(wlandevice_t * wlandev)
 * Call context:
 *	process thread
 ----------------------------------------------------------------*/
-static void prism2sta_reset(wlandevice_t * wlandev)
+static void prism2sta_reset(wlandevice_t *wlandev)
 {
 	return;
 }
@@ -268,9 +265,9 @@ static void prism2sta_reset(wlandevice_t * wlandev)
 * Call context:
 *	process thread
 ----------------------------------------------------------------*/
-static int prism2sta_txframe(wlandevice_t * wlandev, struct sk_buff *skb,
-			     p80211_hdr_t * p80211_hdr,
-			     p80211_metawep_t * p80211_wep)
+static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
+			     p80211_hdr_t *p80211_hdr,
+			     p80211_metawep_t *p80211_wep)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 	int result;
@@ -310,7 +307,7 @@ static int prism2sta_txframe(wlandevice_t * wlandev, struct sk_buff *skb,
 * Call context:
 *	process thread
 ----------------------------------------------------------------*/
-static int prism2sta_mlmerequest(wlandevice_t * wlandev, p80211msg_t * msg)
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
@@ -437,7 +434,7 @@ static int prism2sta_mlmerequest(wlandevice_t * wlandev, p80211msg_t * msg)
 *	process thread  (usually)
 *	interrupt
 ----------------------------------------------------------------*/
-u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate)
+u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 	u32 result;
@@ -455,7 +452,8 @@ u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate)
 			 * Initialize the device+driver sufficiently
 			 * for firmware loading.
 			 */
-			if ((result = hfa384x_drvr_start(hw))) {
+			result = hfa384x_drvr_start(hw);
+			if (result) {
 				printk(KERN_ERR
 				       "hfa384x_drvr_start() failed,"
 				       "result=%d\n", (int)result);
@@ -499,7 +497,8 @@ u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate)
 			 * can't make any assumptions about the state
 			 * of the hardware or a previous firmware load.
 			 */
-			if ((result = hfa384x_drvr_start(hw))) {
+			result = hfa384x_drvr_start(hw);
+			if (result) {
 				printk(KERN_ERR
 				       "hfa384x_drvr_start() failed,"
 				       "result=%d\n", (int)result);
@@ -509,7 +508,8 @@ u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate)
 				break;
 			}
 
-			if ((result = prism2sta_getcardinfo(wlandev))) {
+			result = prism2sta_getcardinfo(wlandev);
+			if (result) {
 				printk(KERN_ERR
 				       "prism2sta_getcardinfo() failed,"
 				       "result=%d\n", (int)result);
@@ -519,7 +519,8 @@ u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate)
 				wlandev->msdstate = WLAN_MSD_HWPRESENT;
 				break;
 			}
-			if ((result = prism2sta_globalsetup(wlandev))) {
+			result = prism2sta_globalsetup(wlandev);
+			if (result) {
 				printk(KERN_ERR
 				       "prism2sta_globalsetup() failed,"
 				       "result=%d\n", (int)result);
@@ -607,7 +608,7 @@ u32 prism2sta_ifstate(wlandevice_t * wlandev, u32 ifstate)
 * Call context:
 *	Either.
 ----------------------------------------------------------------*/
-static int prism2sta_getcardinfo(wlandevice_t * wlandev)
+static int prism2sta_getcardinfo(wlandevice_t *wlandev)
 {
 	int result = 0;
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
@@ -931,7 +932,7 @@ done:
 * Call context:
 *	process thread
 ----------------------------------------------------------------*/
-static int prism2sta_globalsetup(wlandevice_t * wlandev)
+static int prism2sta_globalsetup(wlandevice_t *wlandev)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
@@ -940,7 +941,7 @@ static int prism2sta_globalsetup(wlandevice_t * wlandev)
 					WLAN_DATA_MAXLEN);
 }
 
-static int prism2sta_setmulticast(wlandevice_t * wlandev, netdevice_t * dev)
+static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
 {
 	int result = 0;
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
@@ -981,8 +982,8 @@ exit:
 * 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)
 {
 	pr_debug("received infoframe:HANDOVER (unhandled)\n");
 	return;
@@ -1005,8 +1006,8 @@ static void prism2sta_inf_handover(wlandevice_t * wlandev,
 * 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;
@@ -1053,8 +1054,8 @@ static void prism2sta_inf_tallies(wlandevice_t * wlandev,
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_scanresults(wlandevice_t * wlandev,
-				      hfa384x_InfFrame_t * inf)
+static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
+				      hfa384x_InfFrame_t *inf)
 {
 
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
@@ -1111,8 +1112,8 @@ static void prism2sta_inf_scanresults(wlandevice_t * wlandev,
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_hostscanresults(wlandevice_t * wlandev,
-					  hfa384x_InfFrame_t * inf)
+static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
+					  hfa384x_InfFrame_t *inf)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 	int nbss;
@@ -1153,8 +1154,8 @@ static void prism2sta_inf_hostscanresults(wlandevice_t * wlandev,
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_chinforesults(wlandevice_t * wlandev,
-					hfa384x_InfFrame_t * inf)
+static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
+					hfa384x_InfFrame_t *inf)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 	unsigned int i, n;
@@ -1443,9 +1444,7 @@ void prism2sta_processing_defer(struct work_struct *data)
 	}
 
 	wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
-#ifdef WIRELESS_EXT
 	p80211wext_event_associated(wlandev, wlandev->linkstatus);
-#endif
 
 failed:
 	return;
@@ -1468,8 +1467,8 @@ failed:
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_linkstatus(wlandevice_t * wlandev,
-				     hfa384x_InfFrame_t * inf)
+static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
+				     hfa384x_InfFrame_t *inf)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
@@ -1498,8 +1497,8 @@ static void prism2sta_inf_linkstatus(wlandevice_t * wlandev,
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_assocstatus(wlandevice_t * wlandev,
-				      hfa384x_InfFrame_t * inf)
+static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
+				      hfa384x_InfFrame_t *inf)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 	hfa384x_AssocStatus_t rec;
@@ -1560,8 +1559,8 @@ static void prism2sta_inf_assocstatus(wlandevice_t * wlandev,
 *	interrupt
 *
 ----------------------------------------------------------------*/
-static void prism2sta_inf_authreq(wlandevice_t * wlandev,
-				  hfa384x_InfFrame_t * inf)
+static void prism2sta_inf_authreq(wlandevice_t *wlandev,
+				  hfa384x_InfFrame_t *inf)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 	struct sk_buff *skb;
@@ -1575,8 +1574,8 @@ static void prism2sta_inf_authreq(wlandevice_t * wlandev,
 	}
 }
 
-static void prism2sta_inf_authreq_defer(wlandevice_t * wlandev,
-					hfa384x_InfFrame_t * inf)
+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;
@@ -1749,8 +1748,8 @@ static void prism2sta_inf_authreq_defer(wlandevice_t * wlandev,
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-static void prism2sta_inf_psusercnt(wlandevice_t * wlandev,
-				    hfa384x_InfFrame_t * inf)
+static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
+				    hfa384x_InfFrame_t *inf)
 {
 	hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
 
@@ -1776,7 +1775,7 @@ static void prism2sta_inf_psusercnt(wlandevice_t * wlandev,
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-void prism2sta_ev_info(wlandevice_t * wlandev, hfa384x_InfFrame_t * inf)
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
 {
 	inf->infotype = le16_to_cpu(inf->infotype);
 	/* Dispatch */
@@ -1844,7 +1843,7 @@ void prism2sta_ev_info(wlandevice_t * wlandev, hfa384x_InfFrame_t * inf)
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-void prism2sta_ev_txexc(wlandevice_t * wlandev, u16 status)
+void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
 {
 	pr_debug("TxExc status=0x%x.\n", status);
 
@@ -1867,7 +1866,7 @@ void prism2sta_ev_txexc(wlandevice_t * wlandev, u16 status)
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-void prism2sta_ev_tx(wlandevice_t * wlandev, u16 status)
+void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
 {
 	pr_debug("Tx Complete, status=0x%04x\n", status);
 	/* update linux network stats */
@@ -1891,7 +1890,7 @@ void prism2sta_ev_tx(wlandevice_t * wlandev, u16 status)
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-void prism2sta_ev_rx(wlandevice_t * wlandev, struct sk_buff *skb)
+void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
 {
 	p80211netdev_rx(wlandev, skb);
 	return;
@@ -1913,7 +1912,7 @@ void prism2sta_ev_rx(wlandevice_t * wlandev, struct sk_buff *skb)
 * Call context:
 *	interrupt
 ----------------------------------------------------------------*/
-void prism2sta_ev_alloc(wlandevice_t * wlandev)
+void prism2sta_ev_alloc(wlandevice_t *wlandev)
 {
 	netif_wake_queue(wlandev->netdev);
 	return;
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index 7aa703c..9dde68b 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -4,9 +4,9 @@
 #include "prism2sta.c"
 #include "prism2fw.c"
 
-#define PRISM_USB_DEVICE(vid, pid, name) \
-           USB_DEVICE(vid, pid),  \
-           .driver_info = (unsigned long) name
+#define PRISM_USB_DEVICE(vid, pid, name)	\
+	USB_DEVICE(vid, pid),			\
+	.driver_info = (unsigned long) name
 
 static struct usb_device_id usb_prism_tbl[] = {
 	{PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")},
@@ -111,8 +111,8 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
 	int result = 0;
 
 	dev = interface_to_usbdev(interface);
-
-	if ((wlandev = create_wlan()) == NULL) {
+	wlandev = create_wlan();
+	if (wlandev == NULL) {
 		printk(KERN_ERR "%s: Memory allocation failure.\n", dev_info);
 		result = -EIO;
 		goto failed;
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 7f86534..8aa1955 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -1,7 +1,6 @@
 menuconfig UIO
 	tristate "Userspace I/O drivers"
 	depends on !S390
-	default n
 	help
 	  Enable this to allow the userspace driver core code to be
 	  built.  This code allows userspace programs easy access to
@@ -16,7 +15,6 @@ if UIO
 config UIO_CIF
 	tristate "generic Hilscher CIF Card driver"
 	depends on PCI
-	default n
 	help
 	  Driver for Hilscher CIF DeviceNet and Profibus cards.  This
 	  driver requires a userspace component that handles all of the
@@ -48,7 +46,6 @@ config UIO_PDRV_GENIRQ
 
 config UIO_SMX
 	tristate "SMX cryptengine UIO interface"
-	default n
 	help
 	  Userspace IO interface to the Cryptography engine found on the
 	  Nias Digital SMX boards.  These will be available from Q4 2008
@@ -61,7 +58,6 @@ config UIO_SMX
 config UIO_AEC
 	tristate "AEC video timestamp device"
 	depends on PCI
-	default n
 	help
 
 	  UIO driver for the Adrienne Electronics Corporation PCI time
@@ -78,7 +74,6 @@ config UIO_AEC
 
 config UIO_SERCOS3
 	tristate "Automata Sercos III PCI card driver"
-	default n
 	help
 	  Userspace I/O interface for the Sercos III PCI card from
 	  Automata GmbH. The userspace part of this driver will be
@@ -89,4 +84,14 @@ config UIO_SERCOS3
 
 	  If you compile this as a module, it will be called uio_sercos3.
 
+config UIO_PCI_GENERIC
+	tristate "Generic driver for PCI 2.3 and PCI Express cards"
+	depends on PCI
+	default n
+	help
+	  Generic driver that you can bind, dynamically, to any
+	  PCI 2.3 compliant and PCI Express card. It is useful,
+	  primarily, for virtualization scenarios.
+	  If you compile this as a module, it will be called uio_pci_generic.
+
 endif
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 5c2586d..73b2e75 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_UIO_PDRV_GENIRQ)	+= uio_pdrv_genirq.o
 obj-$(CONFIG_UIO_SMX)	+= uio_smx.o
 obj-$(CONFIG_UIO_AEC)	+= uio_aec.o
 obj-$(CONFIG_UIO_SERCOS3)	+= uio_sercos3.o
+obj-$(CONFIG_UIO_PCI_GENERIC)	+= uio_pci_generic.o
diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c
new file mode 100644
index 0000000..313da35
--- /dev/null
+++ b/drivers/uio/uio_pci_generic.c
@@ -0,0 +1,207 @@
+/* uio_pci_generic - generic UIO driver for PCI 2.3 devices
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ * Since the driver does not declare any device ids, you must allocate
+ * id and bind the device to the driver yourself.  For example:
+ *
+ * # echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id
+ * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind
+ * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind
+ * # ls -l /sys/bus/pci/devices/0000:00:19.0/driver
+ * .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic
+ *
+ * Driver won't bind to devices which do not support the Interrupt Disable Bit
+ * in the command register. All devices compliant to PCI 2.3 (circa 2002) and
+ * all compliant PCI Express devices should support this bit.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/uio_driver.h>
+#include <linux/spinlock.h>
+
+#define DRIVER_VERSION	"0.01.0"
+#define DRIVER_AUTHOR	"Michael S. Tsirkin <mst@redhat.com>"
+#define DRIVER_DESC	"Generic UIO driver for PCI 2.3 devices"
+
+struct uio_pci_generic_dev {
+	struct uio_info info;
+	struct pci_dev *pdev;
+	spinlock_t lock; /* guards command register accesses */
+};
+
+static inline struct uio_pci_generic_dev *
+to_uio_pci_generic_dev(struct uio_info *info)
+{
+	return container_of(info, struct uio_pci_generic_dev, info);
+}
+
+/* Interrupt handler. Read/modify/write the command register to disable
+ * the interrupt. */
+static irqreturn_t irqhandler(int irq, struct uio_info *info)
+{
+	struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
+	struct pci_dev *pdev = gdev->pdev;
+	irqreturn_t ret = IRQ_NONE;
+	u32 cmd_status_dword;
+	u16 origcmd, newcmd, status;
+
+	/* We do a single dword read to retrieve both command and status.
+	 * Document assumptions that make this possible. */
+	BUILD_BUG_ON(PCI_COMMAND % 4);
+	BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
+
+	spin_lock_irq(&gdev->lock);
+	pci_block_user_cfg_access(pdev);
+
+	/* Read both command and status registers in a single 32-bit operation.
+	 * Note: we could cache the value for command and move the status read
+	 * out of the lock if there was a way to get notified of user changes
+	 * to command register through sysfs. Should be good for shared irqs. */
+	pci_read_config_dword(pdev, PCI_COMMAND, &cmd_status_dword);
+	origcmd = cmd_status_dword;
+	status = cmd_status_dword >> 16;
+
+	/* Check interrupt status register to see whether our device
+	 * triggered the interrupt. */
+	if (!(status & PCI_STATUS_INTERRUPT))
+		goto done;
+
+	/* We triggered the interrupt, disable it. */
+	newcmd = origcmd | PCI_COMMAND_INTX_DISABLE;
+	if (newcmd != origcmd)
+		pci_write_config_word(pdev, PCI_COMMAND, newcmd);
+
+	/* UIO core will signal the user process. */
+	ret = IRQ_HANDLED;
+done:
+
+	pci_unblock_user_cfg_access(pdev);
+	spin_unlock_irq(&gdev->lock);
+	return ret;
+}
+
+/* Verify that the device supports Interrupt Disable bit in command register,
+ * per PCI 2.3, by flipping this bit and reading it back: this bit was readonly
+ * in PCI 2.2. */
+static int __devinit verify_pci_2_3(struct pci_dev *pdev)
+{
+	u16 orig, new;
+	int err = 0;
+
+	pci_block_user_cfg_access(pdev);
+	pci_read_config_word(pdev, PCI_COMMAND, &orig);
+	pci_write_config_word(pdev, PCI_COMMAND,
+			      orig ^ PCI_COMMAND_INTX_DISABLE);
+	pci_read_config_word(pdev, PCI_COMMAND, &new);
+	/* There's no way to protect against
+	 * hardware bugs or detect them reliably, but as long as we know
+	 * what the value should be, let's go ahead and check it. */
+	if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
+		err = -EBUSY;
+		dev_err(&pdev->dev, "Command changed from 0x%x to 0x%x: "
+			"driver or HW bug?\n", orig, new);
+		goto err;
+	}
+	if (!((new ^ orig) & PCI_COMMAND_INTX_DISABLE)) {
+		dev_warn(&pdev->dev, "Device does not support "
+			 "disabling interrupts: unable to bind.\n");
+		err = -ENODEV;
+		goto err;
+	}
+	/* Now restore the original value. */
+	pci_write_config_word(pdev, PCI_COMMAND, orig);
+err:
+	pci_unblock_user_cfg_access(pdev);
+	return err;
+}
+
+static int __devinit probe(struct pci_dev *pdev,
+			   const struct pci_device_id *id)
+{
+	struct uio_pci_generic_dev *gdev;
+	int err;
+
+	if (!pdev->irq) {
+		dev_warn(&pdev->dev, "No IRQ assigned to device: "
+			 "no support for interrupts?\n");
+		return -ENODEV;
+	}
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
+			__func__, err);
+		return err;
+	}
+
+	err = verify_pci_2_3(pdev);
+	if (err)
+		goto err_verify;
+
+	gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
+	if (!gdev) {
+		err = -ENOMEM;
+		goto err_alloc;
+	}
+
+	gdev->info.name = "uio_pci_generic";
+	gdev->info.version = DRIVER_VERSION;
+	gdev->info.irq = pdev->irq;
+	gdev->info.irq_flags = IRQF_SHARED;
+	gdev->info.handler = irqhandler;
+	gdev->pdev = pdev;
+	spin_lock_init(&gdev->lock);
+
+	if (uio_register_device(&pdev->dev, &gdev->info))
+		goto err_register;
+	pci_set_drvdata(pdev, gdev);
+
+	return 0;
+err_register:
+	kfree(gdev);
+err_alloc:
+err_verify:
+	pci_disable_device(pdev);
+	return err;
+}
+
+static void remove(struct pci_dev *pdev)
+{
+	struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
+
+	uio_unregister_device(&gdev->info);
+	pci_disable_device(pdev);
+	kfree(gdev);
+}
+
+static struct pci_driver driver = {
+	.name = "uio_pci_generic",
+	.id_table = NULL, /* only dynamic id's */
+	.probe = probe,
+	.remove = remove,
+};
+
+static int __init init(void)
+{
+	pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+	return pci_register_driver(&driver);
+}
+
+static void __exit cleanup(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(init);
+module_exit(cleanup);
+
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index 3f06818..02347c5 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -20,6 +20,7 @@
 #include <linux/bitops.h>
 #include <linux/interrupt.h>
 #include <linux/stringify.h>
+#include <linux/pm_runtime.h>
 
 #define DRIVER_NAME "uio_pdrv_genirq"
 
@@ -27,8 +28,27 @@ struct uio_pdrv_genirq_platdata {
 	struct uio_info *uioinfo;
 	spinlock_t lock;
 	unsigned long flags;
+	struct platform_device *pdev;
 };
 
+static int uio_pdrv_genirq_open(struct uio_info *info, struct inode *inode)
+{
+	struct uio_pdrv_genirq_platdata *priv = info->priv;
+
+	/* Wait until the Runtime PM code has woken up the device */
+	pm_runtime_get_sync(&priv->pdev->dev);
+	return 0;
+}
+
+static int uio_pdrv_genirq_release(struct uio_info *info, struct inode *inode)
+{
+	struct uio_pdrv_genirq_platdata *priv = info->priv;
+
+	/* Tell the Runtime PM code that the device has become idle */
+	pm_runtime_put_sync(&priv->pdev->dev);
+	return 0;
+}
+
 static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info)
 {
 	struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
@@ -97,6 +117,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
 	priv->uioinfo = uioinfo;
 	spin_lock_init(&priv->lock);
 	priv->flags = 0; /* interrupt is enabled to begin with */
+	priv->pdev = pdev;
 
 	uiomem = &uioinfo->mem[0];
 
@@ -136,8 +157,17 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
 	uioinfo->irq_flags |= IRQF_DISABLED;
 	uioinfo->handler = uio_pdrv_genirq_handler;
 	uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
+	uioinfo->open = uio_pdrv_genirq_open;
+	uioinfo->release = uio_pdrv_genirq_release;
 	uioinfo->priv = priv;
 
+	/* Enable Runtime PM for this device:
+	 * The device starts in suspended state to allow the hardware to be
+	 * turned off by default. The Runtime PM bus code should power on the
+	 * hardware and enable clocks at open().
+	 */
+	pm_runtime_enable(&pdev->dev);
+
 	ret = uio_register_device(&pdev->dev, priv->uioinfo);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to register uio device\n");
@@ -157,16 +187,40 @@ static int uio_pdrv_genirq_remove(struct platform_device *pdev)
 	struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev);
 
 	uio_unregister_device(priv->uioinfo);
+	pm_runtime_disable(&pdev->dev);
 	kfree(priv);
 	return 0;
 }
 
+static int uio_pdrv_genirq_runtime_nop(struct device *dev)
+{
+	/* Runtime PM callback shared between ->runtime_suspend()
+	 * and ->runtime_resume(). Simply returns success.
+	 *
+	 * In this driver pm_runtime_get_sync() and pm_runtime_put_sync()
+	 * are used at open() and release() time. This allows the
+	 * Runtime PM code to turn off power to the device while the
+	 * device is unused, ie before open() and after release().
+	 *
+	 * This Runtime PM callback does not need to save or restore
+	 * any registers since user space is responsbile for hardware
+	 * register reinitialization after open().
+	 */
+	return 0;
+}
+
+static struct dev_pm_ops uio_pdrv_genirq_dev_pm_ops = {
+	.runtime_suspend = uio_pdrv_genirq_runtime_nop,
+	.runtime_resume = uio_pdrv_genirq_runtime_nop,
+};
+
 static struct platform_driver uio_pdrv_genirq = {
 	.probe = uio_pdrv_genirq_probe,
 	.remove = uio_pdrv_genirq_remove,
 	.driver = {
 		.name = DRIVER_NAME,
 		.owner = THIS_MODULE,
+		.pm = &uio_pdrv_genirq_dev_pm_ops,
 	},
 };
 
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 2bfc41e..85a1a55 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -858,10 +858,7 @@ static void acm_tty_set_termios(struct tty_struct *tty,
 	if (!ACM_READY(acm))
 		return;
 
-	/* FIXME: Needs to support the tty_baud interface */
-	/* FIXME: Broken on sparc */
-	newline.dwDTERate = cpu_to_le32p(acm_tty_speed +
-		(termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0));
+	newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
 	newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
 	newline.bParityType = termios->c_cflag & PARENB ?
 				(termios->c_cflag & PARODD ? 1 : 2) +
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 26c09f0..9bc112e 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -1057,14 +1057,14 @@ static const struct file_operations usblp_fops = {
 	.release =	usblp_release,
 };
 
-static char *usblp_nodename(struct device *dev)
+static char *usblp_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
 }
 
 static struct usb_class_driver usblp_class = {
 	.name =		"lp%d",
-	.nodename =	usblp_nodename,
+	.devnode =	usblp_devnode,
 	.fops =		&usblp_fops,
 	.minor_base =	USBLP_MINOR_BASE,
 };
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index bc39fc4..fdfaa78 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -154,7 +154,7 @@ static struct attribute *ep_dev_attrs[] = {
 static struct attribute_group ep_dev_attr_grp = {
 	.attrs = ep_dev_attrs,
 };
-static struct attribute_group *ep_dev_groups[] = {
+static const struct attribute_group *ep_dev_groups[] = {
 	&ep_dev_attr_grp,
 	NULL
 };
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 5cef889..222ee07 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -67,14 +67,14 @@ static struct usb_class {
 	struct class *class;
 } *usb_class;
 
-static char *usb_nodename(struct device *dev)
+static char *usb_devnode(struct device *dev, mode_t *mode)
 {
 	struct usb_class_driver *drv;
 
 	drv = dev_get_drvdata(dev);
-	if (!drv || !drv->nodename)
+	if (!drv || !drv->devnode)
 		return NULL;
-	return drv->nodename(dev);
+	return drv->devnode(dev, mode);
 }
 
 static int init_usb_class(void)
@@ -100,7 +100,7 @@ static int init_usb_class(void)
 		kfree(usb_class);
 		usb_class = NULL;
 	}
-	usb_class->class->nodename = usb_nodename;
+	usb_class->class->devnode = usb_devnode;
 
 exit:
 	return result;
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index b5c72e4..7ec3041 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -573,7 +573,7 @@ static struct attribute_group dev_string_attr_grp = {
 	.is_visible =	dev_string_attrs_are_visible,
 };
 
-struct attribute_group *usb_device_groups[] = {
+const struct attribute_group *usb_device_groups[] = {
 	&dev_attr_grp,
 	&dev_string_attr_grp,
 	NULL
@@ -799,7 +799,7 @@ static struct attribute_group intf_assoc_attr_grp = {
 	.is_visible =	intf_assoc_attrs_are_visible,
 };
 
-struct attribute_group *usb_interface_groups[] = {
+const struct attribute_group *usb_interface_groups[] = {
 	&intf_attr_grp,
 	&intf_assoc_attr_grp,
 	NULL
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index a26f738..43ee943 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -311,7 +311,7 @@ static struct dev_pm_ops usb_device_pm_ops = {
 #endif	/* CONFIG_PM */
 
 
-static char *usb_nodename(struct device *dev)
+static char *usb_devnode(struct device *dev, mode_t *mode)
 {
 	struct usb_device *usb_dev;
 
@@ -324,7 +324,7 @@ struct device_type usb_device_type = {
 	.name =		"usb_device",
 	.release =	usb_release_dev,
 	.uevent =	usb_dev_uevent,
-	.nodename = 	usb_nodename,
+	.devnode = 	usb_devnode,
 	.pm =		&usb_device_pm_ops,
 };
 
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index e2a8cfa..c0e0ae2 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -152,8 +152,8 @@ static inline int is_active(const struct usb_interface *f)
 extern const char *usbcore_name;
 
 /* sysfs stuff */
-extern struct attribute_group *usb_device_groups[];
-extern struct attribute_group *usb_interface_groups[];
+extern const struct attribute_group *usb_device_groups[];
+extern const struct attribute_group *usb_interface_groups[];
 
 /* usbfs stuff */
 extern struct mutex usbfs_mutex;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 7f8e83a..9f986b4 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -251,6 +251,24 @@ config USB_PXA25X_SMALL
 	default y if USB_ETH
 	default y if USB_G_SERIAL
 
+config USB_GADGET_R8A66597
+	boolean "Renesas R8A66597 USB Peripheral Controller"
+	select USB_GADGET_DUALSPEED
+	help
+	   R8A66597 is a discrete USB host and peripheral controller chip that
+	   supports both full and high speed USB 2.0 data transfers.
+	   It has nine configurable endpoints, and endpoint zero.
+
+	   Say "y" to link the driver statically, or "m" to build a
+	   dynamically linked module called "r8a66597_udc" and force all
+	   gadget drivers to also be dynamically linked.
+
+config USB_R8A66597
+	tristate
+	depends on USB_GADGET_R8A66597
+	default USB_GADGET
+	select USB_GADGET_SELECTED
+
 config USB_GADGET_PXA27X
 	boolean "PXA 27x"
 	depends on ARCH_PXA && (PXA27x || PXA3xx)
@@ -360,16 +378,6 @@ config USB_M66592
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
-config SUPERH_BUILT_IN_M66592
-	boolean "Enable SuperH built-in USB like the M66592"
-	depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
-	help
-	   SH7722 has USB like the M66592.
-
-	   The transfer rate is very slow when use "Ethernet Gadget".
-	   However, this problem is improved if change a value of
-	   NET_IP_ALIGN to 4.
-
 #
 # Controllers available only in discrete form (and all PCI controllers)
 #
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index e6017e6..9d7b87c 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -23,6 +23,7 @@ ifeq ($(CONFIG_ARCH_MXC),y)
 fsl_usb2_udc-objs		+= fsl_mx3_udc.o
 endif
 obj-$(CONFIG_USB_M66592)	+= m66592-udc.o
+obj-$(CONFIG_USB_R8A66597)	+= r8a66597-udc.o
 obj-$(CONFIG_USB_FSL_QE)	+= fsl_qe_udc.o
 obj-$(CONFIG_USB_CI13XXX)	+= ci13xxx_udc.o
 obj-$(CONFIG_USB_S3C_HSOTG)	+= s3c-hsotg.o
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c
index 96fb118..d2de10b 100644
--- a/drivers/usb/gadget/f_phonet.c
+++ b/drivers/usb/gadget/f_phonet.c
@@ -35,6 +35,10 @@
 #include "u_phonet.h"
 
 #define PN_MEDIA_USB	0x1B
+#define MAXPACKET	512
+#if (PAGE_SIZE % MAXPACKET)
+#error MAXPACKET must divide PAGE_SIZE!
+#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -45,6 +49,10 @@ struct phonet_port {
 
 struct f_phonet {
 	struct usb_function		function;
+	struct {
+		struct sk_buff		*skb;
+		spinlock_t		lock;
+	} rx;
 	struct net_device		*dev;
 	struct usb_ep			*in_ep, *out_ep;
 
@@ -52,7 +60,7 @@ struct f_phonet {
 	struct usb_request		*out_reqv[0];
 };
 
-static int phonet_rxq_size = 2;
+static int phonet_rxq_size = 17;
 
 static inline struct f_phonet *func_to_pn(struct usb_function *f)
 {
@@ -138,7 +146,7 @@ pn_hs_sink_desc = {
 
 	.bEndpointAddress =	USB_DIR_OUT,
 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
-	.wMaxPacketSize =	cpu_to_le16(512),
+	.wMaxPacketSize =	cpu_to_le16(MAXPACKET),
 };
 
 static struct usb_endpoint_descriptor
@@ -256,25 +264,15 @@ out:
 		dev_kfree_skb(skb);
 		dev->stats.tx_dropped++;
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int pn_net_mtu(struct net_device *dev, int new_mtu)
 {
-	struct phonet_port *port = netdev_priv(dev);
-	unsigned long flags;
-	int err = -EBUSY;
-
 	if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU))
 		return -EINVAL;
-
-	spin_lock_irqsave(&port->lock, flags);
-	if (!netif_carrier_ok(dev)) {
-		dev->mtu = new_mtu;
-		err = 0;
-	}
-	spin_unlock_irqrestore(&port->lock, flags);
-	return err;
+	dev->mtu = new_mtu;
+	return 0;
 }
 
 static const struct net_device_ops pn_netdev_ops = {
@@ -308,21 +306,21 @@ static void pn_net_setup(struct net_device *dev)
 static int
 pn_rx_submit(struct f_phonet *fp, struct usb_request *req, gfp_t gfp_flags)
 {
-	struct sk_buff *skb;
-	const size_t size = fp->dev->mtu;
+	struct net_device *dev = fp->dev;
+	struct page *page;
 	int err;
 
-	skb = alloc_skb(size, gfp_flags);
-	if (!skb)
+	page = __netdev_alloc_page(dev, gfp_flags);
+	if (!page)
 		return -ENOMEM;
 
-	req->buf = skb->data;
-	req->length = size;
-	req->context = skb;
+	req->buf = page_address(page);
+	req->length = PAGE_SIZE;
+	req->context = page;
 
 	err = usb_ep_queue(fp->out_ep, req, gfp_flags);
 	if (unlikely(err))
-		dev_kfree_skb_any(skb);
+		netdev_free_page(dev, page);
 	return err;
 }
 
@@ -330,25 +328,37 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
 {
 	struct f_phonet *fp = ep->driver_data;
 	struct net_device *dev = fp->dev;
-	struct sk_buff *skb = req->context;
+	struct page *page = req->context;
+	struct sk_buff *skb;
+	unsigned long flags;
 	int status = req->status;
 
 	switch (status) {
 	case 0:
-		if (unlikely(!netif_running(dev)))
-			break;
-		if (unlikely(req->actual < 1))
+		spin_lock_irqsave(&fp->rx.lock, flags);
+		skb = fp->rx.skb;
+		if (!skb)
+			skb = fp->rx.skb = netdev_alloc_skb(dev, 12);
+		if (req->actual < req->length) /* Last fragment */
+			fp->rx.skb = NULL;
+		spin_unlock_irqrestore(&fp->rx.lock, flags);
+
+		if (unlikely(!skb))
 			break;
-		skb_put(skb, req->actual);
-		skb->protocol = htons(ETH_P_PHONET);
-		skb_reset_mac_header(skb);
-		__skb_pull(skb, 1);
-		skb->dev = dev;
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += skb->len;
-
-		netif_rx(skb);
-		skb = NULL;
+		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, 0,
+				req->actual);
+		page = NULL;
+
+		if (req->actual < req->length) { /* Last fragment */
+			skb->protocol = htons(ETH_P_PHONET);
+			skb_reset_mac_header(skb);
+			pskb_pull(skb, 1);
+			skb->dev = dev;
+			dev->stats.rx_packets++;
+			dev->stats.rx_bytes += skb->len;
+
+			netif_rx(skb);
+		}
 		break;
 
 	/* Do not resubmit in these cases: */
@@ -366,8 +376,8 @@ static void pn_rx_complete(struct usb_ep *ep, struct usb_request *req)
 		break;
 	}
 
-	if (skb)
-		dev_kfree_skb_any(skb);
+	if (page)
+		netdev_free_page(dev, page);
 	if (req)
 		pn_rx_submit(fp, req, GFP_ATOMIC);
 }
@@ -385,6 +395,10 @@ static void __pn_reset(struct usb_function *f)
 
 	usb_ep_disable(fp->out_ep);
 	usb_ep_disable(fp->in_ep);
+	if (fp->rx.skb) {
+		dev_kfree_skb_irq(fp->rx.skb);
+		fp->rx.skb = NULL;
+	}
 }
 
 static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
@@ -583,6 +597,7 @@ int __init phonet_bind_config(struct usb_configuration *c)
 	fp->function.set_alt = pn_set_alt;
 	fp->function.get_alt = pn_get_alt;
 	fp->function.disable = pn_disconnect;
+	spin_lock_init(&fp->rx.lock);
 
 	err = usb_add_function(c, &fp->function);
 	if (err)
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 8e0e9a0..f2d270b 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -173,6 +173,12 @@
 // CONFIG_USB_GADGET_AU1X00
 // ...
 
+#ifdef CONFIG_USB_GADGET_R8A66597
+#define	gadget_is_r8a66597(g)	!strcmp("r8a66597_udc", (g)->name)
+#else
+#define	gadget_is_r8a66597(g)	0
+#endif
+
 
 /**
  * usb_gadget_controller_number - support bcdDevice id convention
@@ -239,6 +245,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
 		return 0x23;
 	else if (gadget_is_langwell(gadget))
 		return 0x24;
+	else if (gadget_is_r8a66597(gadget))
+		return 0x25;
 	return -ENOENT;
 }
 
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c
index 43dcf9e..a8c8543 100644
--- a/drivers/usb/gadget/m66592-udc.c
+++ b/drivers/usb/gadget/m66592-udc.c
@@ -25,44 +25,18 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
-
+#include <linux/err.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 
 #include "m66592-udc.h"
 
-
 MODULE_DESCRIPTION("M66592 USB gadget driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yoshihiro Shimoda");
 MODULE_ALIAS("platform:m66592_udc");
 
-#define DRIVER_VERSION	"18 Oct 2007"
-
-/* module parameters */
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-static unsigned short endian = M66592_LITTLE;
-module_param(endian, ushort, 0644);
-MODULE_PARM_DESC(endian, "data endian: big=0, little=0 (default=0)");
-#else
-static unsigned short clock = M66592_XTAL24;
-module_param(clock, ushort, 0644);
-MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 "
-		"(default=16384)");
-
-static unsigned short vif = M66592_LDRV;
-module_param(vif, ushort, 0644);
-MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)");
-
-static unsigned short endian;
-module_param(endian, ushort, 0644);
-MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
-
-static unsigned short irq_sense = M66592_INTL;
-module_param(irq_sense, ushort, 0644);
-MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 "
-		"(default=2)");
-#endif
+#define DRIVER_VERSION	"21 July 2009"
 
 static const char udc_name[] = "m66592_udc";
 static const char *m66592_ep_name[] = {
@@ -244,6 +218,7 @@ static inline int get_buffer_size(struct m66592 *m66592, u16 pipenum)
 static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
 {
 	struct m66592_ep *ep = m66592->pipenum2ep[pipenum];
+	unsigned short mbw;
 
 	if (ep->use_dma)
 		return;
@@ -252,7 +227,12 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum)
 
 	ndelay(450);
 
-	m66592_bset(m66592, M66592_MBW, ep->fifosel);
+	if (m66592->pdata->on_chip)
+		mbw = M66592_MBW_32;
+	else
+		mbw = M66592_MBW_16;
+
+	m66592_bset(m66592, mbw, ep->fifosel);
 }
 
 static int pipe_buffer_setting(struct m66592 *m66592,
@@ -276,24 +256,27 @@ static int pipe_buffer_setting(struct m66592 *m66592,
 		buf_bsize = 0;
 		break;
 	case M66592_BULK:
-		bufnum = m66592->bi_bufnum +
-			 (info->pipe - M66592_BASE_PIPENUM_BULK) * 16;
-		m66592->bi_bufnum += 16;
+		/* isochronous pipes may be used as bulk pipes */
+		if (info->pipe > M66592_BASE_PIPENUM_BULK)
+			bufnum = info->pipe - M66592_BASE_PIPENUM_BULK;
+		else
+			bufnum = info->pipe - M66592_BASE_PIPENUM_ISOC;
+
+		bufnum = M66592_BASE_BUFNUM + (bufnum * 16);
 		buf_bsize = 7;
 		pipecfg |= M66592_DBLB;
 		if (!info->dir_in)
 			pipecfg |= M66592_SHTNAK;
 		break;
 	case M66592_ISO:
-		bufnum = m66592->bi_bufnum +
+		bufnum = M66592_BASE_BUFNUM +
 			 (info->pipe - M66592_BASE_PIPENUM_ISOC) * 16;
-		m66592->bi_bufnum += 16;
 		buf_bsize = 7;
 		break;
 	}
-	if (m66592->bi_bufnum > M66592_MAX_BUFNUM) {
-		pr_err("m66592 pipe memory is insufficient(%d)\n",
-				m66592->bi_bufnum);
+
+	if (buf_bsize && ((bufnum + 16) >= M66592_MAX_BUFNUM)) {
+		pr_err("m66592 pipe memory is insufficient\n");
 		return -ENOMEM;
 	}
 
@@ -313,17 +296,6 @@ static void pipe_buffer_release(struct m66592 *m66592,
 	if (info->pipe == 0)
 		return;
 
-	switch (info->type) {
-	case M66592_BULK:
-		if (is_bulk_pipe(info->pipe))
-			m66592->bi_bufnum -= 16;
-		break;
-	case M66592_ISO:
-		if (is_isoc_pipe(info->pipe))
-			m66592->bi_bufnum -= 16;
-		break;
-	}
-
 	if (is_bulk_pipe(info->pipe)) {
 		m66592->bulk--;
 	} else if (is_interrupt_pipe(info->pipe))
@@ -340,6 +312,7 @@ static void pipe_buffer_release(struct m66592 *m66592,
 static void pipe_initialize(struct m66592_ep *ep)
 {
 	struct m66592 *m66592 = ep->m66592;
+	unsigned short mbw;
 
 	m66592_mdfy(m66592, 0, M66592_CURPIPE, ep->fifosel);
 
@@ -351,7 +324,12 @@ static void pipe_initialize(struct m66592_ep *ep)
 
 		ndelay(450);
 
-		m66592_bset(m66592, M66592_MBW, ep->fifosel);
+		if (m66592->pdata->on_chip)
+			mbw = M66592_MBW_32;
+		else
+			mbw = M66592_MBW_16;
+
+		m66592_bset(m66592, mbw, ep->fifosel);
 	}
 }
 
@@ -367,15 +345,13 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep,
 			ep->fifosel = M66592_D0FIFOSEL;
 			ep->fifoctr = M66592_D0FIFOCTR;
 			ep->fifotrn = M66592_D0FIFOTRN;
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
-		} else if (m66592->num_dma == 1) {
+		} else if (!m66592->pdata->on_chip && m66592->num_dma == 1) {
 			m66592->num_dma++;
 			ep->use_dma = 1;
 			ep->fifoaddr = M66592_D1FIFO;
 			ep->fifosel = M66592_D1FIFOSEL;
 			ep->fifoctr = M66592_D1FIFOCTR;
 			ep->fifotrn = M66592_D1FIFOTRN;
-#endif
 		} else {
 			ep->use_dma = 0;
 			ep->fifoaddr = M66592_CFIFO;
@@ -620,76 +596,120 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req)
 	}
 }
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
 static void init_controller(struct m66592 *m66592)
 {
-	m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);		/* High spd */
-	m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
-	m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
-	m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+	unsigned int endian;
 
-	/* This is a workaound for SH7722 2nd cut */
-	m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
-	m66592_bset(m66592, 0x1000, M66592_TESTMODE);
-	m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
+	if (m66592->pdata->on_chip) {
+		if (m66592->pdata->endian)
+			endian = 0; /* big endian */
+		else
+			endian = M66592_LITTLE; /* little endian */
 
-	m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
+		m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);	/* High spd */
+		m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
+		m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+		m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
 
-	m66592_write(m66592, 0, M66592_CFBCFG);
-	m66592_write(m66592, 0, M66592_D0FBCFG);
-	m66592_bset(m66592, endian, M66592_CFBCFG);
-	m66592_bset(m66592, endian, M66592_D0FBCFG);
-}
-#else	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
-static void init_controller(struct m66592 *m66592)
-{
-	m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND),
-			M66592_PINCFG);
-	m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);		/* High spd */
-	m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG);
+		/* This is a workaound for SH7722 2nd cut */
+		m66592_bset(m66592, 0x8000, M66592_DVSTCTR);
+		m66592_bset(m66592, 0x1000, M66592_TESTMODE);
+		m66592_bclr(m66592, 0x8000, M66592_DVSTCTR);
 
-	m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
-	m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
-	m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+		m66592_bset(m66592, M66592_INTL, M66592_INTENB1);
+
+		m66592_write(m66592, 0, M66592_CFBCFG);
+		m66592_write(m66592, 0, M66592_D0FBCFG);
+		m66592_bset(m66592, endian, M66592_CFBCFG);
+		m66592_bset(m66592, endian, M66592_D0FBCFG);
+	} else {
+		unsigned int clock, vif, irq_sense;
+
+		if (m66592->pdata->endian)
+			endian = M66592_BIGEND; /* big endian */
+		else
+			endian = 0; /* little endian */
+
+		if (m66592->pdata->vif)
+			vif = M66592_LDRV; /* 3.3v */
+		else
+			vif = 0; /* 1.5v */
+
+		switch (m66592->pdata->xtal) {
+		case M66592_PLATDATA_XTAL_12MHZ:
+			clock = M66592_XTAL12;
+			break;
+		case M66592_PLATDATA_XTAL_24MHZ:
+			clock = M66592_XTAL24;
+			break;
+		case M66592_PLATDATA_XTAL_48MHZ:
+			clock = M66592_XTAL48;
+			break;
+		default:
+			pr_warning("m66592-udc: xtal configuration error\n");
+			clock = 0;
+		}
+
+		switch (m66592->irq_trigger) {
+		case IRQF_TRIGGER_LOW:
+			irq_sense = M66592_INTL;
+			break;
+		case IRQF_TRIGGER_FALLING:
+			irq_sense = 0;
+			break;
+		default:
+			pr_warning("m66592-udc: irq trigger config error\n");
+			irq_sense = 0;
+		}
 
-	m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+		m66592_bset(m66592,
+			    (vif & M66592_LDRV) | (endian & M66592_BIGEND),
+			    M66592_PINCFG);
+		m66592_bset(m66592, M66592_HSE, M66592_SYSCFG);	/* High spd */
+		m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL,
+			    M66592_SYSCFG);
+		m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG);
+		m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG);
+		m66592_bset(m66592, M66592_USBE, M66592_SYSCFG);
+
+		m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
 
-	msleep(3);
+		msleep(3);
 
-	m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
+		m66592_bset(m66592, M66592_RCKE | M66592_PLLC, M66592_SYSCFG);
 
-	msleep(1);
+		msleep(1);
 
-	m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
+		m66592_bset(m66592, M66592_SCKE, M66592_SYSCFG);
 
-	m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
-	m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
-			M66592_DMA0CFG);
+		m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1);
+		m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR,
+			     M66592_DMA0CFG);
+	}
 }
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 
 static void disable_controller(struct m66592 *m66592)
 {
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
-	udelay(1);
-	m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
-	udelay(1);
-	m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
-	udelay(1);
-	m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
-#endif
+	if (!m66592->pdata->on_chip) {
+		m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG);
+		udelay(1);
+		m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG);
+		udelay(1);
+		m66592_bclr(m66592, M66592_RCKE, M66592_SYSCFG);
+		udelay(1);
+		m66592_bclr(m66592, M66592_XCKE, M66592_SYSCFG);
+	}
 }
 
 static void m66592_start_xclock(struct m66592 *m66592)
 {
-#if !defined(CONFIG_SUPERH_BUILT_IN_M66592)
 	u16 tmp;
 
-	tmp = m66592_read(m66592, M66592_SYSCFG);
-	if (!(tmp & M66592_XCKE))
-		m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
-#endif
+	if (!m66592->pdata->on_chip) {
+		tmp = m66592_read(m66592, M66592_SYSCFG);
+		if (!(tmp & M66592_XCKE))
+			m66592_bset(m66592, M66592_XCKE, M66592_SYSCFG);
+	}
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1177,8 +1197,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
 	intsts0 = m66592_read(m66592, M66592_INTSTS0);
 	intenb0 = m66592_read(m66592, M66592_INTENB0);
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	if (!intsts0 && !intenb0) {
+	if (m66592->pdata->on_chip && !intsts0 && !intenb0) {
 		/*
 		 * When USB clock stops, it cannot read register. Even if a
 		 * clock stops, the interrupt occurs. So this driver turn on
@@ -1188,7 +1207,6 @@ static irqreturn_t m66592_irq(int irq, void *_m66592)
 		intsts0 = m66592_read(m66592, M66592_INTSTS0);
 		intenb0 = m66592_read(m66592, M66592_INTENB0);
 	}
-#endif
 
 	savepipe = m66592_read(m66592, M66592_CFIFOSEL);
 
@@ -1534,9 +1552,11 @@ static int __exit m66592_remove(struct platform_device *pdev)
 	iounmap(m66592->reg);
 	free_irq(platform_get_irq(pdev, 0), m66592);
 	m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req);
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-	clk_disable(m66592->clk);
-	clk_put(m66592->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (m66592->pdata->on_chip) {
+		clk_disable(m66592->clk);
+		clk_put(m66592->clk);
+	}
 #endif
 	kfree(m66592);
 	return 0;
@@ -1548,11 +1568,10 @@ static void nop_completion(struct usb_ep *ep, struct usb_request *r)
 
 static int __init m66592_probe(struct platform_device *pdev)
 {
-	struct resource *res;
-	int irq;
+	struct resource *res, *ires;
 	void __iomem *reg = NULL;
 	struct m66592 *m66592 = NULL;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	char clk_name[8];
 #endif
 	int ret = 0;
@@ -1565,10 +1584,11 @@ static int __init m66592_probe(struct platform_device *pdev)
 		goto clean_up;
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!ires) {
 		ret = -ENODEV;
-		pr_err("platform_get_irq error.\n");
+		dev_err(&pdev->dev,
+			"platform_get_resource IORESOURCE_IRQ error.\n");
 		goto clean_up;
 	}
 
@@ -1579,6 +1599,12 @@ static int __init m66592_probe(struct platform_device *pdev)
 		goto clean_up;
 	}
 
+	if (pdev->dev.platform_data == NULL) {
+		dev_err(&pdev->dev, "no platform data\n");
+		ret = -ENODEV;
+		goto clean_up;
+	}
+
 	/* initialize ucd */
 	m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL);
 	if (m66592 == NULL) {
@@ -1586,6 +1612,9 @@ static int __init m66592_probe(struct platform_device *pdev)
 		goto clean_up;
 	}
 
+	m66592->pdata = pdev->dev.platform_data;
+	m66592->irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
 	spin_lock_init(&m66592->lock);
 	dev_set_drvdata(&pdev->dev, m66592);
 
@@ -1603,24 +1632,25 @@ static int __init m66592_probe(struct platform_device *pdev)
 	m66592->timer.data = (unsigned long)m66592;
 	m66592->reg = reg;
 
-	m66592->bi_bufnum = M66592_BASE_BUFNUM;
-
-	ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
+	ret = request_irq(ires->start, m66592_irq, IRQF_DISABLED | IRQF_SHARED,
 			udc_name, m66592);
 	if (ret < 0) {
 		pr_err("request_irq error (%d)\n", ret);
 		goto clean_up;
 	}
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-	snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
-	m66592->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(m66592->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		ret = PTR_ERR(m66592->clk);
-		goto clean_up2;
+#ifdef CONFIG_HAVE_CLK
+	if (m66592->pdata->on_chip) {
+		snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id);
+		m66592->clk = clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(m66592->clk)) {
+			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+				clk_name);
+			ret = PTR_ERR(m66592->clk);
+			goto clean_up2;
+		}
+		clk_enable(m66592->clk);
 	}
-	clk_enable(m66592->clk);
 #endif
 	INIT_LIST_HEAD(&m66592->gadget.ep_list);
 	m66592->gadget.ep0 = &m66592->ep[0].ep;
@@ -1662,12 +1692,14 @@ static int __init m66592_probe(struct platform_device *pdev)
 	return 0;
 
 clean_up3:
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
-	clk_disable(m66592->clk);
-	clk_put(m66592->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (m66592->pdata->on_chip) {
+		clk_disable(m66592->clk);
+		clk_put(m66592->clk);
+	}
 clean_up2:
 #endif
-	free_irq(irq, m66592);
+	free_irq(ires->start, m66592);
 clean_up:
 	if (m66592) {
 		if (m66592->ep0_req)
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h
index 286ce07..8b960de 100644
--- a/drivers/usb/gadget/m66592-udc.h
+++ b/drivers/usb/gadget/m66592-udc.h
@@ -23,10 +23,12 @@
 #ifndef __M66592_UDC_H__
 #define __M66592_UDC_H__
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 #include <linux/clk.h>
 #endif
 
+#include <linux/usb/m66592.h>
+
 #define M66592_SYSCFG		0x00
 #define M66592_XTAL		0xC000	/* b15-14: Crystal selection */
 #define   M66592_XTAL48		 0x8000		/* 48MHz */
@@ -76,11 +78,11 @@
 #define   M66592_P_TST_J	 0x0001		/* PERI TEST J */
 #define   M66592_P_TST_NORMAL	 0x0000		/* PERI Normal Mode */
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
+/* built-in registers */
 #define M66592_CFBCFG		0x0A
 #define M66592_D0FBCFG		0x0C
 #define M66592_LITTLE		0x0100	/* b8: Little endian mode */
-#else
+/* external chip case */
 #define M66592_PINCFG		0x0A
 #define M66592_LDRV		0x8000	/* b15: Drive Current Adjust */
 #define M66592_BIGEND		0x0100	/* b8: Big endian mode */
@@ -100,8 +102,8 @@
 #define M66592_PKTM		0x0020	/* b5: Packet mode */
 #define M66592_DENDE		0x0010	/* b4: Dend enable */
 #define M66592_OBUS		0x0004	/* b2: OUTbus mode */
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 
+/* common case */
 #define M66592_CFIFO		0x10
 #define M66592_D0FIFO		0x14
 #define M66592_D1FIFO		0x18
@@ -113,13 +115,9 @@
 #define M66592_REW		0x4000	/* b14: Buffer rewind */
 #define M66592_DCLRM		0x2000	/* b13: DMA buffer clear mode */
 #define M66592_DREQE		0x1000	/* b12: DREQ output enable */
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-#define M66592_MBW		0x0800	/* b11: Maximum bit width for FIFO */
-#else
-#define M66592_MBW		0x0400	/* b10: Maximum bit width for FIFO */
-#define   M66592_MBW_8		 0x0000   /*  8bit */
-#define   M66592_MBW_16		 0x0400   /* 16bit */
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
+#define M66592_MBW_8		0x0000   /*  8bit */
+#define M66592_MBW_16		0x0400   /* 16bit */
+#define M66592_MBW_32		0x0800   /* 32bit */
 #define M66592_TRENB		0x0200	/* b9: Transaction counter enable */
 #define M66592_TRCLR		0x0100	/* b8: Transaction counter clear */
 #define M66592_DEZPM		0x0080	/* b7: Zero-length packet mode */
@@ -480,9 +478,11 @@ struct m66592_ep {
 struct m66592 {
 	spinlock_t		lock;
 	void __iomem		*reg;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	struct clk *clk;
 #endif
+	struct m66592_platdata	*pdata;
+	unsigned long		irq_trigger;
 
 	struct usb_gadget		gadget;
 	struct usb_gadget_driver	*driver;
@@ -506,7 +506,6 @@ struct m66592 {
 	int interrupt;
 	int isochronous;
 	int num_dma;
-	int bi_bufnum;	/* bulk and isochronous's bufnum */
 };
 
 #define gadget_to_m66592(_gadget) container_of(_gadget, struct m66592, gadget)
@@ -547,13 +546,13 @@ static inline void m66592_read_fifo(struct m66592 *m66592,
 {
 	unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
 
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	len = (len + 3) / 4;
-	insl(fifoaddr, buf, len);
-#else
-	len = (len + 1) / 2;
-	insw(fifoaddr, buf, len);
-#endif
+	if (m66592->pdata->on_chip) {
+		len = (len + 3) / 4;
+		insl(fifoaddr, buf, len);
+	} else {
+		len = (len + 1) / 2;
+		insw(fifoaddr, buf, len);
+	}
 }
 
 static inline void m66592_write(struct m66592 *m66592, u16 val,
@@ -567,33 +566,34 @@ static inline void m66592_write_fifo(struct m66592 *m66592,
 		void *buf, unsigned long len)
 {
 	unsigned long fifoaddr = (unsigned long)m66592->reg + offset;
-#if defined(CONFIG_SUPERH_BUILT_IN_M66592)
-	unsigned long count;
-	unsigned char *pb;
-	int i;
-
-	count = len / 4;
-	outsl(fifoaddr, buf, count);
-
-	if (len & 0x00000003) {
-		pb = buf + count * 4;
-		for (i = 0; i < (len & 0x00000003); i++) {
-			if (m66592_read(m66592, M66592_CFBCFG))	/* little */
-				outb(pb[i], fifoaddr + (3 - i));
-			else
-				outb(pb[i], fifoaddr + i);
+
+	if (m66592->pdata->on_chip) {
+		unsigned long count;
+		unsigned char *pb;
+		int i;
+
+		count = len / 4;
+		outsl(fifoaddr, buf, count);
+
+		if (len & 0x00000003) {
+			pb = buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++) {
+				if (m66592_read(m66592, M66592_CFBCFG))	/* le */
+					outb(pb[i], fifoaddr + (3 - i));
+				else
+					outb(pb[i], fifoaddr + i);
+			}
+		}
+	} else {
+		unsigned long odd = len & 0x0001;
+
+		len = len / 2;
+		outsw(fifoaddr, buf, len);
+		if (odd) {
+			unsigned char *p = buf + len*2;
+			outb(*p, fifoaddr);
 		}
 	}
-#else
-	unsigned long odd = len & 0x0001;
-
-	len = len / 2;
-	outsw(fifoaddr, buf, len);
-	if (odd) {
-		unsigned char *p = buf + len*2;
-		outb(*p, fifoaddr);
-	}
-#endif	/* #if defined(CONFIG_SUPERH_BUILT_IN_M66592) */
 }
 
 static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat,
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
new file mode 100644
index 0000000..e220fb8
--- /dev/null
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -0,0 +1,1689 @@
+/*
+ * R8A66597 UDC (USB gadget)
+ *
+ * Copyright (C) 2006-2009 Renesas Solutions Corp.
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+
+#include "r8a66597-udc.h"
+
+#define DRIVER_VERSION	"2009-08-18"
+
+static const char udc_name[] = "r8a66597_udc";
+static const char *r8a66597_ep_name[] = {
+	"ep0", "ep1", "ep2", "ep3", "ep4", "ep5", "ep6", "ep7",
+	"ep8", "ep9",
+};
+
+static void disable_controller(struct r8a66597 *r8a66597);
+static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req);
+static void irq_packet_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req);
+static int r8a66597_queue(struct usb_ep *_ep, struct usb_request *_req,
+			gfp_t gfp_flags);
+
+static void transfer_complete(struct r8a66597_ep *ep,
+		struct r8a66597_request *req, int status);
+
+/*-------------------------------------------------------------------------*/
+static inline u16 get_usb_speed(struct r8a66597 *r8a66597)
+{
+	return r8a66597_read(r8a66597, DVSTCTR0) & RHST;
+}
+
+static void enable_pipe_irq(struct r8a66597 *r8a66597, u16 pipenum,
+		unsigned long reg)
+{
+	u16 tmp;
+
+	tmp = r8a66597_read(r8a66597, INTENB0);
+	r8a66597_bclr(r8a66597, BEMPE | NRDYE | BRDYE,
+			INTENB0);
+	r8a66597_bset(r8a66597, (1 << pipenum), reg);
+	r8a66597_write(r8a66597, tmp, INTENB0);
+}
+
+static void disable_pipe_irq(struct r8a66597 *r8a66597, u16 pipenum,
+		unsigned long reg)
+{
+	u16 tmp;
+
+	tmp = r8a66597_read(r8a66597, INTENB0);
+	r8a66597_bclr(r8a66597, BEMPE | NRDYE | BRDYE,
+			INTENB0);
+	r8a66597_bclr(r8a66597, (1 << pipenum), reg);
+	r8a66597_write(r8a66597, tmp, INTENB0);
+}
+
+static void r8a66597_usb_connect(struct r8a66597 *r8a66597)
+{
+	r8a66597_bset(r8a66597, CTRE, INTENB0);
+	r8a66597_bset(r8a66597, BEMPE | BRDYE, INTENB0);
+
+	r8a66597_bset(r8a66597, DPRPU, SYSCFG0);
+}
+
+static void r8a66597_usb_disconnect(struct r8a66597 *r8a66597)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	r8a66597_bclr(r8a66597, CTRE, INTENB0);
+	r8a66597_bclr(r8a66597, BEMPE | BRDYE, INTENB0);
+	r8a66597_bclr(r8a66597, DPRPU, SYSCFG0);
+
+	r8a66597->gadget.speed = USB_SPEED_UNKNOWN;
+	spin_unlock(&r8a66597->lock);
+	r8a66597->driver->disconnect(&r8a66597->gadget);
+	spin_lock(&r8a66597->lock);
+
+	disable_controller(r8a66597);
+	INIT_LIST_HEAD(&r8a66597->ep[0].queue);
+}
+
+static inline u16 control_reg_get_pid(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	u16 pid = 0;
+	unsigned long offset;
+
+	if (pipenum == 0)
+		pid = r8a66597_read(r8a66597, DCPCTR) & PID;
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		pid = r8a66597_read(r8a66597, offset) & PID;
+	} else
+		printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+
+	return pid;
+}
+
+static inline void control_reg_set_pid(struct r8a66597 *r8a66597, u16 pipenum,
+		u16 pid)
+{
+	unsigned long offset;
+
+	if (pipenum == 0)
+		r8a66597_mdfy(r8a66597, pid, PID, DCPCTR);
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		r8a66597_mdfy(r8a66597, pid, PID, offset);
+	} else
+		printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+}
+
+static inline void pipe_start(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	control_reg_set_pid(r8a66597, pipenum, PID_BUF);
+}
+
+static inline void pipe_stop(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	control_reg_set_pid(r8a66597, pipenum, PID_NAK);
+}
+
+static inline void pipe_stall(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	control_reg_set_pid(r8a66597, pipenum, PID_STALL);
+}
+
+static inline u16 control_reg_get(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	u16 ret = 0;
+	unsigned long offset;
+
+	if (pipenum == 0)
+		ret = r8a66597_read(r8a66597, DCPCTR);
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		ret = r8a66597_read(r8a66597, offset);
+	} else
+		printk(KERN_ERR "unexpect pipe num (%d)\n", pipenum);
+
+	return ret;
+}
+
+static inline void control_reg_sqclr(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	unsigned long offset;
+
+	pipe_stop(r8a66597, pipenum);
+
+	if (pipenum == 0)
+		r8a66597_bset(r8a66597, SQCLR, DCPCTR);
+	else if (pipenum < R8A66597_MAX_NUM_PIPE) {
+		offset = get_pipectr_addr(pipenum);
+		r8a66597_bset(r8a66597, SQCLR, offset);
+	} else
+		printk(KERN_ERR "unexpect pipe num(%d)\n", pipenum);
+}
+
+static inline int get_buffer_size(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	u16 tmp;
+	int size;
+
+	if (pipenum == 0) {
+		tmp = r8a66597_read(r8a66597, DCPCFG);
+		if ((tmp & R8A66597_CNTMD) != 0)
+			size = 256;
+		else {
+			tmp = r8a66597_read(r8a66597, DCPMAXP);
+			size = tmp & MAXP;
+		}
+	} else {
+		r8a66597_write(r8a66597, pipenum, PIPESEL);
+		tmp = r8a66597_read(r8a66597, PIPECFG);
+		if ((tmp & R8A66597_CNTMD) != 0) {
+			tmp = r8a66597_read(r8a66597, PIPEBUF);
+			size = ((tmp >> 10) + 1) * 64;
+		} else {
+			tmp = r8a66597_read(r8a66597, PIPEMAXP);
+			size = tmp & MXPS;
+		}
+	}
+
+	return size;
+}
+
+static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
+{
+	if (r8a66597->pdata->on_chip)
+		return MBW_32;
+	else
+		return MBW_16;
+}
+
+static inline void pipe_change(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	struct r8a66597_ep *ep = r8a66597->pipenum2ep[pipenum];
+
+	if (ep->use_dma)
+		return;
+
+	r8a66597_mdfy(r8a66597, pipenum, CURPIPE, ep->fifosel);
+
+	ndelay(450);
+
+	r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel);
+}
+
+static int pipe_buffer_setting(struct r8a66597 *r8a66597,
+		struct r8a66597_pipe_info *info)
+{
+	u16 bufnum = 0, buf_bsize = 0;
+	u16 pipecfg = 0;
+
+	if (info->pipe == 0)
+		return -EINVAL;
+
+	r8a66597_write(r8a66597, info->pipe, PIPESEL);
+
+	if (info->dir_in)
+		pipecfg |= R8A66597_DIR;
+	pipecfg |= info->type;
+	pipecfg |= info->epnum;
+	switch (info->type) {
+	case R8A66597_INT:
+		bufnum = 4 + (info->pipe - R8A66597_BASE_PIPENUM_INT);
+		buf_bsize = 0;
+		break;
+	case R8A66597_BULK:
+		/* isochronous pipes may be used as bulk pipes */
+		if (info->pipe > R8A66597_BASE_PIPENUM_BULK)
+			bufnum = info->pipe - R8A66597_BASE_PIPENUM_BULK;
+		else
+			bufnum = info->pipe - R8A66597_BASE_PIPENUM_ISOC;
+
+		bufnum = R8A66597_BASE_BUFNUM + (bufnum * 16);
+		buf_bsize = 7;
+		pipecfg |= R8A66597_DBLB;
+		if (!info->dir_in)
+			pipecfg |= R8A66597_SHTNAK;
+		break;
+	case R8A66597_ISO:
+		bufnum = R8A66597_BASE_BUFNUM +
+			 (info->pipe - R8A66597_BASE_PIPENUM_ISOC) * 16;
+		buf_bsize = 7;
+		break;
+	}
+
+	if (buf_bsize && ((bufnum + 16) >= R8A66597_MAX_BUFNUM)) {
+		pr_err(KERN_ERR "r8a66597 pipe memory is insufficient\n");
+		return -ENOMEM;
+	}
+
+	r8a66597_write(r8a66597, pipecfg, PIPECFG);
+	r8a66597_write(r8a66597, (buf_bsize << 10) | (bufnum), PIPEBUF);
+	r8a66597_write(r8a66597, info->maxpacket, PIPEMAXP);
+	if (info->interval)
+		info->interval--;
+	r8a66597_write(r8a66597, info->interval, PIPEPERI);
+
+	return 0;
+}
+
+static void pipe_buffer_release(struct r8a66597 *r8a66597,
+				struct r8a66597_pipe_info *info)
+{
+	if (info->pipe == 0)
+		return;
+
+	if (is_bulk_pipe(info->pipe))
+		r8a66597->bulk--;
+	else if (is_interrupt_pipe(info->pipe))
+		r8a66597->interrupt--;
+	else if (is_isoc_pipe(info->pipe)) {
+		r8a66597->isochronous--;
+		if (info->type == R8A66597_BULK)
+			r8a66597->bulk--;
+	} else
+		printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n",
+				info->pipe);
+}
+
+static void pipe_initialize(struct r8a66597_ep *ep)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	r8a66597_mdfy(r8a66597, 0, CURPIPE, ep->fifosel);
+
+	r8a66597_write(r8a66597, ACLRM, ep->pipectr);
+	r8a66597_write(r8a66597, 0, ep->pipectr);
+	r8a66597_write(r8a66597, SQCLR, ep->pipectr);
+	if (ep->use_dma) {
+		r8a66597_mdfy(r8a66597, ep->pipenum, CURPIPE, ep->fifosel);
+
+		ndelay(450);
+
+		r8a66597_bset(r8a66597, mbw_value(r8a66597), ep->fifosel);
+	}
+}
+
+static void r8a66597_ep_setting(struct r8a66597 *r8a66597,
+				struct r8a66597_ep *ep,
+				const struct usb_endpoint_descriptor *desc,
+				u16 pipenum, int dma)
+{
+	ep->use_dma = 0;
+	ep->fifoaddr = CFIFO;
+	ep->fifosel = CFIFOSEL;
+	ep->fifoctr = CFIFOCTR;
+	ep->fifotrn = 0;
+
+	ep->pipectr = get_pipectr_addr(pipenum);
+	ep->pipenum = pipenum;
+	ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+	r8a66597->pipenum2ep[pipenum] = ep;
+	r8a66597->epaddr2ep[desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK]
+		= ep;
+	INIT_LIST_HEAD(&ep->queue);
+}
+
+static void r8a66597_ep_release(struct r8a66597_ep *ep)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	u16 pipenum = ep->pipenum;
+
+	if (pipenum == 0)
+		return;
+
+	if (ep->use_dma)
+		r8a66597->num_dma--;
+	ep->pipenum = 0;
+	ep->busy = 0;
+	ep->use_dma = 0;
+}
+
+static int alloc_pipe_config(struct r8a66597_ep *ep,
+		const struct usb_endpoint_descriptor *desc)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	struct r8a66597_pipe_info info;
+	int dma = 0;
+	unsigned char *counter;
+	int ret;
+
+	ep->desc = desc;
+
+	if (ep->pipenum)	/* already allocated pipe  */
+		return 0;
+
+	switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+	case USB_ENDPOINT_XFER_BULK:
+		if (r8a66597->bulk >= R8A66597_MAX_NUM_BULK) {
+			if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) {
+				printk(KERN_ERR "bulk pipe is insufficient\n");
+				return -ENODEV;
+			} else {
+				info.pipe = R8A66597_BASE_PIPENUM_ISOC
+						+ r8a66597->isochronous;
+				counter = &r8a66597->isochronous;
+			}
+		} else {
+			info.pipe = R8A66597_BASE_PIPENUM_BULK + r8a66597->bulk;
+			counter = &r8a66597->bulk;
+		}
+		info.type = R8A66597_BULK;
+		dma = 1;
+		break;
+	case USB_ENDPOINT_XFER_INT:
+		if (r8a66597->interrupt >= R8A66597_MAX_NUM_INT) {
+			printk(KERN_ERR "interrupt pipe is insufficient\n");
+			return -ENODEV;
+		}
+		info.pipe = R8A66597_BASE_PIPENUM_INT + r8a66597->interrupt;
+		info.type = R8A66597_INT;
+		counter = &r8a66597->interrupt;
+		break;
+	case USB_ENDPOINT_XFER_ISOC:
+		if (r8a66597->isochronous >= R8A66597_MAX_NUM_ISOC) {
+			printk(KERN_ERR "isochronous pipe is insufficient\n");
+			return -ENODEV;
+		}
+		info.pipe = R8A66597_BASE_PIPENUM_ISOC + r8a66597->isochronous;
+		info.type = R8A66597_ISO;
+		counter = &r8a66597->isochronous;
+		break;
+	default:
+		printk(KERN_ERR "unexpect xfer type\n");
+		return -EINVAL;
+	}
+	ep->type = info.type;
+
+	info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+	info.maxpacket = le16_to_cpu(desc->wMaxPacketSize);
+	info.interval = desc->bInterval;
+	if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+		info.dir_in = 1;
+	else
+		info.dir_in = 0;
+
+	ret = pipe_buffer_setting(r8a66597, &info);
+	if (ret < 0) {
+		printk(KERN_ERR "pipe_buffer_setting fail\n");
+		return ret;
+	}
+
+	(*counter)++;
+	if ((counter == &r8a66597->isochronous) && info.type == R8A66597_BULK)
+		r8a66597->bulk++;
+
+	r8a66597_ep_setting(r8a66597, ep, desc, info.pipe, dma);
+	pipe_initialize(ep);
+
+	return 0;
+}
+
+static int free_pipe_config(struct r8a66597_ep *ep)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	struct r8a66597_pipe_info info;
+
+	info.pipe = ep->pipenum;
+	info.type = ep->type;
+	pipe_buffer_release(r8a66597, &info);
+	r8a66597_ep_release(ep);
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static void pipe_irq_enable(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	enable_irq_ready(r8a66597, pipenum);
+	enable_irq_nrdy(r8a66597, pipenum);
+}
+
+static void pipe_irq_disable(struct r8a66597 *r8a66597, u16 pipenum)
+{
+	disable_irq_ready(r8a66597, pipenum);
+	disable_irq_nrdy(r8a66597, pipenum);
+}
+
+/* if complete is true, gadget driver complete function is not call */
+static void control_end(struct r8a66597 *r8a66597, unsigned ccpl)
+{
+	r8a66597->ep[0].internal_ccpl = ccpl;
+	pipe_start(r8a66597, 0);
+	r8a66597_bset(r8a66597, CCPL, DCPCTR);
+}
+
+static void start_ep0_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	pipe_change(r8a66597, ep->pipenum);
+	r8a66597_mdfy(r8a66597, ISEL, (ISEL | CURPIPE), CFIFOSEL);
+	r8a66597_write(r8a66597, BCLR, ep->fifoctr);
+	if (req->req.length == 0) {
+		r8a66597_bset(r8a66597, BVAL, ep->fifoctr);
+		pipe_start(r8a66597, 0);
+		transfer_complete(ep, req, 0);
+	} else {
+		r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
+		irq_ep0_write(ep, req);
+	}
+}
+
+static void start_packet_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	u16 tmp;
+
+	pipe_change(r8a66597, ep->pipenum);
+	disable_irq_empty(r8a66597, ep->pipenum);
+	pipe_start(r8a66597, ep->pipenum);
+
+	tmp = r8a66597_read(r8a66597, ep->fifoctr);
+	if (unlikely((tmp & FRDY) == 0))
+		pipe_irq_enable(r8a66597, ep->pipenum);
+	else
+		irq_packet_write(ep, req);
+}
+
+static void start_packet_read(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	u16 pipenum = ep->pipenum;
+
+	if (ep->pipenum == 0) {
+		r8a66597_mdfy(r8a66597, 0, (ISEL | CURPIPE), CFIFOSEL);
+		r8a66597_write(r8a66597, BCLR, ep->fifoctr);
+		pipe_start(r8a66597, pipenum);
+		pipe_irq_enable(r8a66597, pipenum);
+	} else {
+		if (ep->use_dma) {
+			r8a66597_bset(r8a66597, TRCLR, ep->fifosel);
+			pipe_change(r8a66597, pipenum);
+			r8a66597_bset(r8a66597, TRENB, ep->fifosel);
+			r8a66597_write(r8a66597,
+				(req->req.length + ep->ep.maxpacket - 1)
+					/ ep->ep.maxpacket,
+				ep->fifotrn);
+		}
+		pipe_start(r8a66597, pipenum);	/* trigger once */
+		pipe_irq_enable(r8a66597, pipenum);
+	}
+}
+
+static void start_packet(struct r8a66597_ep *ep, struct r8a66597_request *req)
+{
+	if (ep->desc->bEndpointAddress & USB_DIR_IN)
+		start_packet_write(ep, req);
+	else
+		start_packet_read(ep, req);
+}
+
+static void start_ep0(struct r8a66597_ep *ep, struct r8a66597_request *req)
+{
+	u16 ctsq;
+
+	ctsq = r8a66597_read(ep->r8a66597, INTSTS0) & CTSQ;
+
+	switch (ctsq) {
+	case CS_RDDS:
+		start_ep0_write(ep, req);
+		break;
+	case CS_WRDS:
+		start_packet_read(ep, req);
+		break;
+
+	case CS_WRND:
+		control_end(ep->r8a66597, 0);
+		break;
+	default:
+		printk(KERN_ERR "start_ep0: unexpect ctsq(%x)\n", ctsq);
+		break;
+	}
+}
+
+static void init_controller(struct r8a66597 *r8a66597)
+{
+	u16 vif = r8a66597->pdata->vif ? LDRV : 0;
+	u16 irq_sense = r8a66597->irq_sense_low ? INTL : 0;
+	u16 endian = r8a66597->pdata->endian ? BIGEND : 0;
+
+	if (r8a66597->pdata->on_chip) {
+		r8a66597_bset(r8a66597, 0x04, SYSCFG1);
+		r8a66597_bset(r8a66597, HSE, SYSCFG0);
+
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_bclr(r8a66597, DPRPU, SYSCFG0);
+		r8a66597_bset(r8a66597, USBE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, SCKE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, irq_sense, INTENB1);
+		r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR,
+				DMA0CFG);
+	} else {
+		r8a66597_bset(r8a66597, vif | endian, PINCFG);
+		r8a66597_bset(r8a66597, HSE, SYSCFG0);		/* High spd */
+		r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
+				XTAL, SYSCFG0);
+
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_bclr(r8a66597, DPRPU, SYSCFG0);
+		r8a66597_bset(r8a66597, USBE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+
+		msleep(3);
+
+		r8a66597_bset(r8a66597, PLLC, SYSCFG0);
+
+		msleep(1);
+
+		r8a66597_bset(r8a66597, SCKE, SYSCFG0);
+
+		r8a66597_bset(r8a66597, irq_sense, INTENB1);
+		r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR,
+			       DMA0CFG);
+	}
+}
+
+static void disable_controller(struct r8a66597 *r8a66597)
+{
+	if (r8a66597->pdata->on_chip) {
+		r8a66597_bset(r8a66597, SCKE, SYSCFG0);
+
+		/* disable interrupts */
+		r8a66597_write(r8a66597, 0, INTENB0);
+		r8a66597_write(r8a66597, 0, INTENB1);
+		r8a66597_write(r8a66597, 0, BRDYENB);
+		r8a66597_write(r8a66597, 0, BEMPENB);
+		r8a66597_write(r8a66597, 0, NRDYENB);
+
+		/* clear status */
+		r8a66597_write(r8a66597, 0, BRDYSTS);
+		r8a66597_write(r8a66597, 0, NRDYSTS);
+		r8a66597_write(r8a66597, 0, BEMPSTS);
+
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
+
+	} else {
+		r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
+		udelay(1);
+		r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
+		udelay(1);
+		udelay(1);
+		r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
+	}
+}
+
+static void r8a66597_start_xclock(struct r8a66597 *r8a66597)
+{
+	u16 tmp;
+
+	if (!r8a66597->pdata->on_chip) {
+		tmp = r8a66597_read(r8a66597, SYSCFG0);
+		if (!(tmp & XCKE))
+			r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+	}
+}
+
+static struct r8a66597_request *get_request_from_ep(struct r8a66597_ep *ep)
+{
+	return list_entry(ep->queue.next, struct r8a66597_request, queue);
+}
+
+/*-------------------------------------------------------------------------*/
+static void transfer_complete(struct r8a66597_ep *ep,
+		struct r8a66597_request *req, int status)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	int restart = 0;
+
+	if (unlikely(ep->pipenum == 0)) {
+		if (ep->internal_ccpl) {
+			ep->internal_ccpl = 0;
+			return;
+		}
+	}
+
+	list_del_init(&req->queue);
+	if (ep->r8a66597->gadget.speed == USB_SPEED_UNKNOWN)
+		req->req.status = -ESHUTDOWN;
+	else
+		req->req.status = status;
+
+	if (!list_empty(&ep->queue))
+		restart = 1;
+
+	spin_unlock(&ep->r8a66597->lock);
+	req->req.complete(&ep->ep, &req->req);
+	spin_lock(&ep->r8a66597->lock);
+
+	if (restart) {
+		req = get_request_from_ep(ep);
+		if (ep->desc)
+			start_packet(ep, req);
+	}
+}
+
+static void irq_ep0_write(struct r8a66597_ep *ep, struct r8a66597_request *req)
+{
+	int i;
+	u16 tmp;
+	unsigned bufsize;
+	size_t size;
+	void *buf;
+	u16 pipenum = ep->pipenum;
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	pipe_change(r8a66597, pipenum);
+	r8a66597_bset(r8a66597, ISEL, ep->fifosel);
+
+	i = 0;
+	do {
+		tmp = r8a66597_read(r8a66597, ep->fifoctr);
+		if (i++ > 100000) {
+			printk(KERN_ERR "pipe0 is busy. maybe cpu i/o bus"
+				"conflict. please power off this controller.");
+			return;
+		}
+		ndelay(1);
+	} while ((tmp & FRDY) == 0);
+
+	/* prepare parameters */
+	bufsize = get_buffer_size(r8a66597, pipenum);
+	buf = req->req.buf + req->req.actual;
+	size = min(bufsize, req->req.length - req->req.actual);
+
+	/* write fifo */
+	if (req->req.buf) {
+		if (size > 0)
+			r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size);
+		if ((size == 0) || ((size % ep->ep.maxpacket) != 0))
+			r8a66597_bset(r8a66597, BVAL, ep->fifoctr);
+	}
+
+	/* update parameters */
+	req->req.actual += size;
+
+	/* check transfer finish */
+	if ((!req->req.zero && (req->req.actual == req->req.length))
+			|| (size % ep->ep.maxpacket)
+			|| (size == 0)) {
+		disable_irq_ready(r8a66597, pipenum);
+		disable_irq_empty(r8a66597, pipenum);
+	} else {
+		disable_irq_ready(r8a66597, pipenum);
+		enable_irq_empty(r8a66597, pipenum);
+	}
+	pipe_start(r8a66597, pipenum);
+}
+
+static void irq_packet_write(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	u16 tmp;
+	unsigned bufsize;
+	size_t size;
+	void *buf;
+	u16 pipenum = ep->pipenum;
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+
+	pipe_change(r8a66597, pipenum);
+	tmp = r8a66597_read(r8a66597, ep->fifoctr);
+	if (unlikely((tmp & FRDY) == 0)) {
+		pipe_stop(r8a66597, pipenum);
+		pipe_irq_disable(r8a66597, pipenum);
+		printk(KERN_ERR "write fifo not ready. pipnum=%d\n", pipenum);
+		return;
+	}
+
+	/* prepare parameters */
+	bufsize = get_buffer_size(r8a66597, pipenum);
+	buf = req->req.buf + req->req.actual;
+	size = min(bufsize, req->req.length - req->req.actual);
+
+	/* write fifo */
+	if (req->req.buf) {
+		r8a66597_write_fifo(r8a66597, ep->fifoaddr, buf, size);
+		if ((size == 0)
+				|| ((size % ep->ep.maxpacket) != 0)
+				|| ((bufsize != ep->ep.maxpacket)
+					&& (bufsize > size)))
+			r8a66597_bset(r8a66597, BVAL, ep->fifoctr);
+	}
+
+	/* update parameters */
+	req->req.actual += size;
+	/* check transfer finish */
+	if ((!req->req.zero && (req->req.actual == req->req.length))
+			|| (size % ep->ep.maxpacket)
+			|| (size == 0)) {
+		disable_irq_ready(r8a66597, pipenum);
+		enable_irq_empty(r8a66597, pipenum);
+	} else {
+		disable_irq_empty(r8a66597, pipenum);
+		pipe_irq_enable(r8a66597, pipenum);
+	}
+}
+
+static void irq_packet_read(struct r8a66597_ep *ep,
+				struct r8a66597_request *req)
+{
+	u16 tmp;
+	int rcv_len, bufsize, req_len;
+	int size;
+	void *buf;
+	u16 pipenum = ep->pipenum;
+	struct r8a66597 *r8a66597 = ep->r8a66597;
+	int finish = 0;
+
+	pipe_change(r8a66597, pipenum);
+	tmp = r8a66597_read(r8a66597, ep->fifoctr);
+	if (unlikely((tmp & FRDY) == 0)) {
+		req->req.status = -EPIPE;
+		pipe_stop(r8a66597, pipenum);
+		pipe_irq_disable(r8a66597, pipenum);
+		printk(KERN_ERR "read fifo not ready");
+		return;
+	}
+
+	/* prepare parameters */
+	rcv_len = tmp & DTLN;
+	bufsize = get_buffer_size(r8a66597, pipenum);
+
+	buf = req->req.buf + req->req.actual;
+	req_len = req->req.length - req->req.actual;
+	if (rcv_len < bufsize)
+		size = min(rcv_len, req_len);
+	else
+		size = min(bufsize, req_len);
+
+	/* update parameters */
+	req->req.actual += size;
+
+	/* check transfer finish */
+	if ((!req->req.zero && (req->req.actual == req->req.length))
+			|| (size % ep->ep.maxpacket)
+			|| (size == 0)) {
+		pipe_stop(r8a66597, pipenum);
+		pipe_irq_disable(r8a66597, pipenum);
+		finish = 1;
+	}
+
+	/* read fifo */
+	if (req->req.buf) {
+		if (size == 0)
+			r8a66597_write(r8a66597, BCLR, ep->fifoctr);
+		else
+			r8a66597_read_fifo(r8a66597, ep->fifoaddr, buf, size);
+
+	}
+
+	if ((ep->pipenum != 0) && finish)
+		transfer_complete(ep, req, 0);
+}
+
+static void irq_pipe_ready(struct r8a66597 *r8a66597, u16 status, u16 enb)
+{
+	u16 check;
+	u16 pipenum;
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+
+	if ((status & BRDY0) && (enb & BRDY0)) {
+		r8a66597_write(r8a66597, ~BRDY0, BRDYSTS);
+		r8a66597_mdfy(r8a66597, 0, CURPIPE, CFIFOSEL);
+
+		ep = &r8a66597->ep[0];
+		req = get_request_from_ep(ep);
+		irq_packet_read(ep, req);
+	} else {
+		for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+			check = 1 << pipenum;
+			if ((status & check) && (enb & check)) {
+				r8a66597_write(r8a66597, ~check, BRDYSTS);
+				ep = r8a66597->pipenum2ep[pipenum];
+				req = get_request_from_ep(ep);
+				if (ep->desc->bEndpointAddress & USB_DIR_IN)
+					irq_packet_write(ep, req);
+				else
+					irq_packet_read(ep, req);
+			}
+		}
+	}
+}
+
+static void irq_pipe_empty(struct r8a66597 *r8a66597, u16 status, u16 enb)
+{
+	u16 tmp;
+	u16 check;
+	u16 pipenum;
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+
+	if ((status & BEMP0) && (enb & BEMP0)) {
+		r8a66597_write(r8a66597, ~BEMP0, BEMPSTS);
+
+		ep = &r8a66597->ep[0];
+		req = get_request_from_ep(ep);
+		irq_ep0_write(ep, req);
+	} else {
+		for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) {
+			check = 1 << pipenum;
+			if ((status & check) && (enb & check)) {
+				r8a66597_write(r8a66597, ~check, BEMPSTS);
+				tmp = control_reg_get(r8a66597, pipenum);
+				if ((tmp & INBUFM) == 0) {
+					disable_irq_empty(r8a66597, pipenum);
+					pipe_irq_disable(r8a66597, pipenum);
+					pipe_stop(r8a66597, pipenum);
+					ep = r8a66597->pipenum2ep[pipenum];
+					req = get_request_from_ep(ep);
+					if (!list_empty(&ep->queue))
+						transfer_complete(ep, req, 0);
+				}
+			}
+		}
+	}
+}
+
+static void get_status(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	struct r8a66597_ep *ep;
+	u16 pid;
+	u16 status = 0;
+	u16 w_index = le16_to_cpu(ctrl->wIndex);
+
+	switch (ctrl->bRequestType & USB_RECIP_MASK) {
+	case USB_RECIP_DEVICE:
+		status = 1 << USB_DEVICE_SELF_POWERED;
+		break;
+	case USB_RECIP_INTERFACE:
+		status = 0;
+		break;
+	case USB_RECIP_ENDPOINT:
+		ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
+		pid = control_reg_get_pid(r8a66597, ep->pipenum);
+		if (pid == PID_STALL)
+			status = 1 << USB_ENDPOINT_HALT;
+		else
+			status = 0;
+		break;
+	default:
+		pipe_stall(r8a66597, 0);
+		return;		/* exit */
+	}
+
+	r8a66597->ep0_data = cpu_to_le16(status);
+	r8a66597->ep0_req->buf = &r8a66597->ep0_data;
+	r8a66597->ep0_req->length = 2;
+	/* AV: what happens if we get called again before that gets through? */
+	spin_unlock(&r8a66597->lock);
+	r8a66597_queue(r8a66597->gadget.ep0, r8a66597->ep0_req, GFP_KERNEL);
+	spin_lock(&r8a66597->lock);
+}
+
+static void clear_feature(struct r8a66597 *r8a66597,
+				struct usb_ctrlrequest *ctrl)
+{
+	switch (ctrl->bRequestType & USB_RECIP_MASK) {
+	case USB_RECIP_DEVICE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_INTERFACE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_ENDPOINT: {
+		struct r8a66597_ep *ep;
+		struct r8a66597_request *req;
+		u16 w_index = le16_to_cpu(ctrl->wIndex);
+
+		ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
+		if (!ep->wedge) {
+			pipe_stop(r8a66597, ep->pipenum);
+			control_reg_sqclr(r8a66597, ep->pipenum);
+			spin_unlock(&r8a66597->lock);
+			usb_ep_clear_halt(&ep->ep);
+			spin_lock(&r8a66597->lock);
+		}
+
+		control_end(r8a66597, 1);
+
+		req = get_request_from_ep(ep);
+		if (ep->busy) {
+			ep->busy = 0;
+			if (list_empty(&ep->queue))
+				break;
+			start_packet(ep, req);
+		} else if (!list_empty(&ep->queue))
+			pipe_start(r8a66597, ep->pipenum);
+		}
+		break;
+	default:
+		pipe_stall(r8a66597, 0);
+		break;
+	}
+}
+
+static void set_feature(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl)
+{
+
+	switch (ctrl->bRequestType & USB_RECIP_MASK) {
+	case USB_RECIP_DEVICE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_INTERFACE:
+		control_end(r8a66597, 1);
+		break;
+	case USB_RECIP_ENDPOINT: {
+		struct r8a66597_ep *ep;
+		u16 w_index = le16_to_cpu(ctrl->wIndex);
+
+		ep = r8a66597->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK];
+		pipe_stall(r8a66597, ep->pipenum);
+
+		control_end(r8a66597, 1);
+		}
+		break;
+	default:
+		pipe_stall(r8a66597, 0);
+		break;
+	}
+}
+
+/* if return value is true, call class driver's setup() */
+static int setup_packet(struct r8a66597 *r8a66597, struct usb_ctrlrequest *ctrl)
+{
+	u16 *p = (u16 *)ctrl;
+	unsigned long offset = USBREQ;
+	int i, ret = 0;
+
+	/* read fifo */
+	r8a66597_write(r8a66597, ~VALID, INTSTS0);
+
+	for (i = 0; i < 4; i++)
+		p[i] = r8a66597_read(r8a66597, offset + i*2);
+
+	/* check request */
+	if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+		switch (ctrl->bRequest) {
+		case USB_REQ_GET_STATUS:
+			get_status(r8a66597, ctrl);
+			break;
+		case USB_REQ_CLEAR_FEATURE:
+			clear_feature(r8a66597, ctrl);
+			break;
+		case USB_REQ_SET_FEATURE:
+			set_feature(r8a66597, ctrl);
+			break;
+		default:
+			ret = 1;
+			break;
+		}
+	} else
+		ret = 1;
+	return ret;
+}
+
+static void r8a66597_update_usb_speed(struct r8a66597 *r8a66597)
+{
+	u16 speed = get_usb_speed(r8a66597);
+
+	switch (speed) {
+	case HSMODE:
+		r8a66597->gadget.speed = USB_SPEED_HIGH;
+		break;
+	case FSMODE:
+		r8a66597->gadget.speed = USB_SPEED_FULL;
+		break;
+	default:
+		r8a66597->gadget.speed = USB_SPEED_UNKNOWN;
+		printk(KERN_ERR "USB speed unknown\n");
+	}
+}
+
+static void irq_device_state(struct r8a66597 *r8a66597)
+{
+	u16 dvsq;
+
+	dvsq = r8a66597_read(r8a66597, INTSTS0) & DVSQ;
+	r8a66597_write(r8a66597, ~DVST, INTSTS0);
+
+	if (dvsq == DS_DFLT) {
+		/* bus reset */
+		r8a66597->driver->disconnect(&r8a66597->gadget);
+		r8a66597_update_usb_speed(r8a66597);
+	}
+	if (r8a66597->old_dvsq == DS_CNFG && dvsq != DS_CNFG)
+		r8a66597_update_usb_speed(r8a66597);
+	if ((dvsq == DS_CNFG || dvsq == DS_ADDS)
+			&& r8a66597->gadget.speed == USB_SPEED_UNKNOWN)
+		r8a66597_update_usb_speed(r8a66597);
+
+	r8a66597->old_dvsq = dvsq;
+}
+
+static void irq_control_stage(struct r8a66597 *r8a66597)
+__releases(r8a66597->lock)
+__acquires(r8a66597->lock)
+{
+	struct usb_ctrlrequest ctrl;
+	u16 ctsq;
+
+	ctsq = r8a66597_read(r8a66597, INTSTS0) & CTSQ;
+	r8a66597_write(r8a66597, ~CTRT, INTSTS0);
+
+	switch (ctsq) {
+	case CS_IDST: {
+		struct r8a66597_ep *ep;
+		struct r8a66597_request *req;
+		ep = &r8a66597->ep[0];
+		req = get_request_from_ep(ep);
+		transfer_complete(ep, req, 0);
+		}
+		break;
+
+	case CS_RDDS:
+	case CS_WRDS:
+	case CS_WRND:
+		if (setup_packet(r8a66597, &ctrl)) {
+			spin_unlock(&r8a66597->lock);
+			if (r8a66597->driver->setup(&r8a66597->gadget, &ctrl)
+				< 0)
+				pipe_stall(r8a66597, 0);
+			spin_lock(&r8a66597->lock);
+		}
+		break;
+	case CS_RDSS:
+	case CS_WRSS:
+		control_end(r8a66597, 0);
+		break;
+	default:
+		printk(KERN_ERR "ctrl_stage: unexpect ctsq(%x)\n", ctsq);
+		break;
+	}
+}
+
+static irqreturn_t r8a66597_irq(int irq, void *_r8a66597)
+{
+	struct r8a66597 *r8a66597 = _r8a66597;
+	u16 intsts0;
+	u16 intenb0;
+	u16 brdysts, nrdysts, bempsts;
+	u16 brdyenb, nrdyenb, bempenb;
+	u16 savepipe;
+	u16 mask0;
+
+	spin_lock(&r8a66597->lock);
+
+	intsts0 = r8a66597_read(r8a66597, INTSTS0);
+	intenb0 = r8a66597_read(r8a66597, INTENB0);
+
+	savepipe = r8a66597_read(r8a66597, CFIFOSEL);
+
+	mask0 = intsts0 & intenb0;
+	if (mask0) {
+		brdysts = r8a66597_read(r8a66597, BRDYSTS);
+		nrdysts = r8a66597_read(r8a66597, NRDYSTS);
+		bempsts = r8a66597_read(r8a66597, BEMPSTS);
+		brdyenb = r8a66597_read(r8a66597, BRDYENB);
+		nrdyenb = r8a66597_read(r8a66597, NRDYENB);
+		bempenb = r8a66597_read(r8a66597, BEMPENB);
+
+		if (mask0 & VBINT) {
+			r8a66597_write(r8a66597,  0xffff & ~VBINT,
+					INTSTS0);
+			r8a66597_start_xclock(r8a66597);
+
+			/* start vbus sampling */
+			r8a66597->old_vbus = r8a66597_read(r8a66597, INTSTS0)
+					& VBSTS;
+			r8a66597->scount = R8A66597_MAX_SAMPLING;
+
+			mod_timer(&r8a66597->timer,
+					jiffies + msecs_to_jiffies(50));
+		}
+		if (intsts0 & DVSQ)
+			irq_device_state(r8a66597);
+
+		if ((intsts0 & BRDY) && (intenb0 & BRDYE)
+				&& (brdysts & brdyenb))
+			irq_pipe_ready(r8a66597, brdysts, brdyenb);
+		if ((intsts0 & BEMP) && (intenb0 & BEMPE)
+				&& (bempsts & bempenb))
+			irq_pipe_empty(r8a66597, bempsts, bempenb);
+
+		if (intsts0 & CTRT)
+			irq_control_stage(r8a66597);
+	}
+
+	r8a66597_write(r8a66597, savepipe, CFIFOSEL);
+
+	spin_unlock(&r8a66597->lock);
+	return IRQ_HANDLED;
+}
+
+static void r8a66597_timer(unsigned long _r8a66597)
+{
+	struct r8a66597 *r8a66597 = (struct r8a66597 *)_r8a66597;
+	unsigned long flags;
+	u16 tmp;
+
+	spin_lock_irqsave(&r8a66597->lock, flags);
+	tmp = r8a66597_read(r8a66597, SYSCFG0);
+	if (r8a66597->scount > 0) {
+		tmp = r8a66597_read(r8a66597, INTSTS0) & VBSTS;
+		if (tmp == r8a66597->old_vbus) {
+			r8a66597->scount--;
+			if (r8a66597->scount == 0) {
+				if (tmp == VBSTS)
+					r8a66597_usb_connect(r8a66597);
+				else
+					r8a66597_usb_disconnect(r8a66597);
+			} else {
+				mod_timer(&r8a66597->timer,
+					jiffies + msecs_to_jiffies(50));
+			}
+		} else {
+			r8a66597->scount = R8A66597_MAX_SAMPLING;
+			r8a66597->old_vbus = tmp;
+			mod_timer(&r8a66597->timer,
+					jiffies + msecs_to_jiffies(50));
+		}
+	}
+	spin_unlock_irqrestore(&r8a66597->lock, flags);
+}
+
+/*-------------------------------------------------------------------------*/
+static int r8a66597_enable(struct usb_ep *_ep,
+			 const struct usb_endpoint_descriptor *desc)
+{
+	struct r8a66597_ep *ep;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	return alloc_pipe_config(ep, desc);
+}
+
+static int r8a66597_disable(struct usb_ep *_ep)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	BUG_ON(!ep);
+
+	while (!list_empty(&ep->queue)) {
+		req = get_request_from_ep(ep);
+		spin_lock_irqsave(&ep->r8a66597->lock, flags);
+		transfer_complete(ep, req, -ECONNRESET);
+		spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+	}
+
+	pipe_irq_disable(ep->r8a66597, ep->pipenum);
+	return free_pipe_config(ep);
+}
+
+static struct usb_request *r8a66597_alloc_request(struct usb_ep *_ep,
+						gfp_t gfp_flags)
+{
+	struct r8a66597_request *req;
+
+	req = kzalloc(sizeof(struct r8a66597_request), gfp_flags);
+	if (!req)
+		return NULL;
+
+	INIT_LIST_HEAD(&req->queue);
+
+	return &req->req;
+}
+
+static void r8a66597_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct r8a66597_request *req;
+
+	req = container_of(_req, struct r8a66597_request, req);
+	kfree(req);
+}
+
+static int r8a66597_queue(struct usb_ep *_ep, struct usb_request *_req,
+			gfp_t gfp_flags)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+	int request = 0;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	req = container_of(_req, struct r8a66597_request, req);
+
+	if (ep->r8a66597->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+
+	if (list_empty(&ep->queue))
+		request = 1;
+
+	list_add_tail(&req->queue, &ep->queue);
+	req->req.actual = 0;
+	req->req.status = -EINPROGRESS;
+
+	if (ep->desc == NULL)	/* control */
+		start_ep0(ep, req);
+	else {
+		if (request && !ep->busy)
+			start_packet(ep, req);
+	}
+
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+	return 0;
+}
+
+static int r8a66597_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	req = container_of(_req, struct r8a66597_request, req);
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	if (!list_empty(&ep->queue))
+		transfer_complete(ep, req, -ECONNRESET);
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+	return 0;
+}
+
+static int r8a66597_set_halt(struct usb_ep *_ep, int value)
+{
+	struct r8a66597_ep *ep;
+	struct r8a66597_request *req;
+	unsigned long flags;
+	int ret = 0;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	req = get_request_from_ep(ep);
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	if (!list_empty(&ep->queue)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+	if (value) {
+		ep->busy = 1;
+		pipe_stall(ep->r8a66597, ep->pipenum);
+	} else {
+		ep->busy = 0;
+		ep->wedge = 0;
+		pipe_stop(ep->r8a66597, ep->pipenum);
+	}
+
+out:
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+	return ret;
+}
+
+static int r8a66597_set_wedge(struct usb_ep *_ep)
+{
+	struct r8a66597_ep *ep;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+
+	if (!ep || !ep->desc)
+		return -EINVAL;
+
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	ep->wedge = 1;
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+
+	return usb_ep_set_halt(_ep);
+}
+
+static void r8a66597_fifo_flush(struct usb_ep *_ep)
+{
+	struct r8a66597_ep *ep;
+	unsigned long flags;
+
+	ep = container_of(_ep, struct r8a66597_ep, ep);
+	spin_lock_irqsave(&ep->r8a66597->lock, flags);
+	if (list_empty(&ep->queue) && !ep->busy) {
+		pipe_stop(ep->r8a66597, ep->pipenum);
+		r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr);
+	}
+	spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
+}
+
+static struct usb_ep_ops r8a66597_ep_ops = {
+	.enable		= r8a66597_enable,
+	.disable	= r8a66597_disable,
+
+	.alloc_request	= r8a66597_alloc_request,
+	.free_request	= r8a66597_free_request,
+
+	.queue		= r8a66597_queue,
+	.dequeue	= r8a66597_dequeue,
+
+	.set_halt	= r8a66597_set_halt,
+	.set_wedge	= r8a66597_set_wedge,
+	.fifo_flush	= r8a66597_fifo_flush,
+};
+
+/*-------------------------------------------------------------------------*/
+static struct r8a66597 *the_controller;
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+	struct r8a66597 *r8a66597 = the_controller;
+	int retval;
+
+	if (!driver
+			|| driver->speed != USB_SPEED_HIGH
+			|| !driver->bind
+			|| !driver->setup)
+		return -EINVAL;
+	if (!r8a66597)
+		return -ENODEV;
+	if (r8a66597->driver)
+		return -EBUSY;
+
+	/* hook up the driver */
+	driver->driver.bus = NULL;
+	r8a66597->driver = driver;
+	r8a66597->gadget.dev.driver = &driver->driver;
+
+	retval = device_add(&r8a66597->gadget.dev);
+	if (retval) {
+		printk(KERN_ERR "device_add error (%d)\n", retval);
+		goto error;
+	}
+
+	retval = driver->bind(&r8a66597->gadget);
+	if (retval) {
+		printk(KERN_ERR "bind to driver error (%d)\n", retval);
+		device_del(&r8a66597->gadget.dev);
+		goto error;
+	}
+
+	r8a66597_bset(r8a66597, VBSE, INTENB0);
+	if (r8a66597_read(r8a66597, INTSTS0) & VBSTS) {
+		r8a66597_start_xclock(r8a66597);
+		/* start vbus sampling */
+		r8a66597->old_vbus = r8a66597_read(r8a66597,
+					 INTSTS0) & VBSTS;
+		r8a66597->scount = R8A66597_MAX_SAMPLING;
+		mod_timer(&r8a66597->timer, jiffies + msecs_to_jiffies(50));
+	}
+
+	return 0;
+
+error:
+	r8a66597->driver = NULL;
+	r8a66597->gadget.dev.driver = NULL;
+
+	return retval;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+	struct r8a66597 *r8a66597 = the_controller;
+	unsigned long flags;
+
+	if (driver != r8a66597->driver || !driver->unbind)
+		return -EINVAL;
+
+	spin_lock_irqsave(&r8a66597->lock, flags);
+	if (r8a66597->gadget.speed != USB_SPEED_UNKNOWN)
+		r8a66597_usb_disconnect(r8a66597);
+	spin_unlock_irqrestore(&r8a66597->lock, flags);
+
+	r8a66597_bclr(r8a66597, VBSE, INTENB0);
+
+	driver->unbind(&r8a66597->gadget);
+
+	init_controller(r8a66597);
+	disable_controller(r8a66597);
+
+	device_del(&r8a66597->gadget.dev);
+	r8a66597->driver = NULL;
+	return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+/*-------------------------------------------------------------------------*/
+static int r8a66597_get_frame(struct usb_gadget *_gadget)
+{
+	struct r8a66597 *r8a66597 = gadget_to_r8a66597(_gadget);
+	return r8a66597_read(r8a66597, FRMNUM) & 0x03FF;
+}
+
+static struct usb_gadget_ops r8a66597_gadget_ops = {
+	.get_frame		= r8a66597_get_frame,
+};
+
+static int __exit r8a66597_remove(struct platform_device *pdev)
+{
+	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
+
+	del_timer_sync(&r8a66597->timer);
+	iounmap((void *)r8a66597->reg);
+	free_irq(platform_get_irq(pdev, 0), r8a66597);
+	r8a66597_free_request(&r8a66597->ep[0].ep, r8a66597->ep0_req);
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip) {
+		clk_disable(r8a66597->clk);
+		clk_put(r8a66597->clk);
+	}
+#endif
+	kfree(r8a66597);
+	return 0;
+}
+
+static void nop_completion(struct usb_ep *ep, struct usb_request *r)
+{
+}
+
+static int __init r8a66597_probe(struct platform_device *pdev)
+{
+#ifdef CONFIG_HAVE_CLK
+	char clk_name[8];
+#endif
+	struct resource *res, *ires;
+	int irq;
+	void __iomem *reg = NULL;
+	struct r8a66597 *r8a66597 = NULL;
+	int ret = 0;
+	int i;
+	unsigned long irq_trigger;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENODEV;
+		printk(KERN_ERR "platform_get_resource error.\n");
+		goto clean_up;
+	}
+
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	irq = ires->start;
+	irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
+	if (irq < 0) {
+		ret = -ENODEV;
+		printk(KERN_ERR "platform_get_irq error.\n");
+		goto clean_up;
+	}
+
+	reg = ioremap(res->start, resource_size(res));
+	if (reg == NULL) {
+		ret = -ENOMEM;
+		printk(KERN_ERR "ioremap error.\n");
+		goto clean_up;
+	}
+
+	/* initialize ucd */
+	r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL);
+	if (r8a66597 == NULL) {
+		printk(KERN_ERR "kzalloc error\n");
+		goto clean_up;
+	}
+
+	spin_lock_init(&r8a66597->lock);
+	dev_set_drvdata(&pdev->dev, r8a66597);
+	r8a66597->pdata = pdev->dev.platform_data;
+	r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
+
+	r8a66597->gadget.ops = &r8a66597_gadget_ops;
+	device_initialize(&r8a66597->gadget.dev);
+	dev_set_name(&r8a66597->gadget.dev, "gadget");
+	r8a66597->gadget.is_dualspeed = 1;
+	r8a66597->gadget.dev.parent = &pdev->dev;
+	r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;
+	r8a66597->gadget.dev.release = pdev->dev.release;
+	r8a66597->gadget.name = udc_name;
+
+	init_timer(&r8a66597->timer);
+	r8a66597->timer.function = r8a66597_timer;
+	r8a66597->timer.data = (unsigned long)r8a66597;
+	r8a66597->reg = (unsigned long)reg;
+
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip) {
+		snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
+		r8a66597->clk = clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(r8a66597->clk)) {
+			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+				clk_name);
+			ret = PTR_ERR(r8a66597->clk);
+			goto clean_up;
+		}
+		clk_enable(r8a66597->clk);
+	}
+#endif
+
+	disable_controller(r8a66597); /* make sure controller is disabled */
+
+	ret = request_irq(irq, r8a66597_irq, IRQF_DISABLED | IRQF_SHARED,
+			udc_name, r8a66597);
+	if (ret < 0) {
+		printk(KERN_ERR "request_irq error (%d)\n", ret);
+		goto clean_up2;
+	}
+
+	INIT_LIST_HEAD(&r8a66597->gadget.ep_list);
+	r8a66597->gadget.ep0 = &r8a66597->ep[0].ep;
+	INIT_LIST_HEAD(&r8a66597->gadget.ep0->ep_list);
+	for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) {
+		struct r8a66597_ep *ep = &r8a66597->ep[i];
+
+		if (i != 0) {
+			INIT_LIST_HEAD(&r8a66597->ep[i].ep.ep_list);
+			list_add_tail(&r8a66597->ep[i].ep.ep_list,
+					&r8a66597->gadget.ep_list);
+		}
+		ep->r8a66597 = r8a66597;
+		INIT_LIST_HEAD(&ep->queue);
+		ep->ep.name = r8a66597_ep_name[i];
+		ep->ep.ops = &r8a66597_ep_ops;
+		ep->ep.maxpacket = 512;
+	}
+	r8a66597->ep[0].ep.maxpacket = 64;
+	r8a66597->ep[0].pipenum = 0;
+	r8a66597->ep[0].fifoaddr = CFIFO;
+	r8a66597->ep[0].fifosel = CFIFOSEL;
+	r8a66597->ep[0].fifoctr = CFIFOCTR;
+	r8a66597->ep[0].fifotrn = 0;
+	r8a66597->ep[0].pipectr = get_pipectr_addr(0);
+	r8a66597->pipenum2ep[0] = &r8a66597->ep[0];
+	r8a66597->epaddr2ep[0] = &r8a66597->ep[0];
+
+	the_controller = r8a66597;
+
+	r8a66597->ep0_req = r8a66597_alloc_request(&r8a66597->ep[0].ep,
+							GFP_KERNEL);
+	if (r8a66597->ep0_req == NULL)
+		goto clean_up3;
+	r8a66597->ep0_req->complete = nop_completion;
+
+	init_controller(r8a66597);
+
+	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
+	return 0;
+
+clean_up3:
+	free_irq(irq, r8a66597);
+clean_up2:
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip) {
+		clk_disable(r8a66597->clk);
+		clk_put(r8a66597->clk);
+	}
+#endif
+clean_up:
+	if (r8a66597) {
+		if (r8a66597->ep0_req)
+			r8a66597_free_request(&r8a66597->ep[0].ep,
+						r8a66597->ep0_req);
+		kfree(r8a66597);
+	}
+	if (reg)
+		iounmap(reg);
+
+	return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+static struct platform_driver r8a66597_driver = {
+	.remove =	__exit_p(r8a66597_remove),
+	.driver		= {
+		.name =	(char *) udc_name,
+	},
+};
+
+static int __init r8a66597_udc_init(void)
+{
+	return platform_driver_probe(&r8a66597_driver, r8a66597_probe);
+}
+module_init(r8a66597_udc_init);
+
+static void __exit r8a66597_udc_cleanup(void)
+{
+	platform_driver_unregister(&r8a66597_driver);
+}
+module_exit(r8a66597_udc_cleanup);
+
+MODULE_DESCRIPTION("R8A66597 USB gadget driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yoshihiro Shimoda");
+
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
new file mode 100644
index 0000000..03087e7
--- /dev/null
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -0,0 +1,256 @@
+/*
+ * R8A66597 UDC
+ *
+ * Copyright (C) 2007-2009 Renesas Solutions Corp.
+ *
+ * Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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
+ *
+ */
+
+#ifndef __R8A66597_H__
+#define __R8A66597_H__
+
+#ifdef CONFIG_HAVE_CLK
+#include <linux/clk.h>
+#endif
+
+#include <linux/usb/r8a66597.h>
+
+#define R8A66597_MAX_SAMPLING	10
+
+#define R8A66597_MAX_NUM_PIPE	8
+#define R8A66597_MAX_NUM_BULK	3
+#define R8A66597_MAX_NUM_ISOC	2
+#define R8A66597_MAX_NUM_INT	2
+
+#define R8A66597_BASE_PIPENUM_BULK	3
+#define R8A66597_BASE_PIPENUM_ISOC	1
+#define R8A66597_BASE_PIPENUM_INT	6
+
+#define R8A66597_BASE_BUFNUM	6
+#define R8A66597_MAX_BUFNUM	0x4F
+
+#define is_bulk_pipe(pipenum)	\
+	((pipenum >= R8A66597_BASE_PIPENUM_BULK) && \
+	 (pipenum < (R8A66597_BASE_PIPENUM_BULK + R8A66597_MAX_NUM_BULK)))
+#define is_interrupt_pipe(pipenum)	\
+	((pipenum >= R8A66597_BASE_PIPENUM_INT) && \
+	 (pipenum < (R8A66597_BASE_PIPENUM_INT + R8A66597_MAX_NUM_INT)))
+#define is_isoc_pipe(pipenum)	\
+	((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \
+	 (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC)))
+
+struct r8a66597_pipe_info {
+	u16	pipe;
+	u16	epnum;
+	u16	maxpacket;
+	u16	type;
+	u16	interval;
+	u16	dir_in;
+};
+
+struct r8a66597_request {
+	struct usb_request	req;
+	struct list_head	queue;
+};
+
+struct r8a66597_ep {
+	struct usb_ep		ep;
+	struct r8a66597		*r8a66597;
+
+	struct list_head	queue;
+	unsigned		busy:1;
+	unsigned		wedge:1;
+	unsigned		internal_ccpl:1;	/* use only control */
+
+	/* this member can able to after r8a66597_enable */
+	unsigned		use_dma:1;
+	u16			pipenum;
+	u16			type;
+	const struct usb_endpoint_descriptor	*desc;
+	/* register address */
+	unsigned char		fifoaddr;
+	unsigned char		fifosel;
+	unsigned char		fifoctr;
+	unsigned char		fifotrn;
+	unsigned char		pipectr;
+};
+
+struct r8a66597 {
+	spinlock_t		lock;
+	unsigned long		reg;
+
+#ifdef CONFIG_HAVE_CLK
+	struct clk *clk;
+#endif
+	struct r8a66597_platdata	*pdata;
+
+	struct usb_gadget		gadget;
+	struct usb_gadget_driver	*driver;
+
+	struct r8a66597_ep	ep[R8A66597_MAX_NUM_PIPE];
+	struct r8a66597_ep	*pipenum2ep[R8A66597_MAX_NUM_PIPE];
+	struct r8a66597_ep	*epaddr2ep[16];
+
+	struct timer_list	timer;
+	struct usb_request	*ep0_req;	/* for internal request */
+	u16			ep0_data;	/* for internal request */
+	u16			old_vbus;
+	u16			scount;
+	u16			old_dvsq;
+
+	/* pipe config */
+	unsigned char bulk;
+	unsigned char interrupt;
+	unsigned char isochronous;
+	unsigned char num_dma;
+
+	unsigned irq_sense_low:1;
+};
+
+#define gadget_to_r8a66597(_gadget)	\
+		container_of(_gadget, struct r8a66597, gadget)
+#define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget)
+
+static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
+{
+	return inw(r8a66597->reg + offset);
+}
+
+static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
+				      unsigned long offset, u16 *buf,
+				      int len)
+{
+	if (r8a66597->pdata->on_chip) {
+		unsigned long fifoaddr = r8a66597->reg + offset;
+		unsigned long count;
+		union {
+			unsigned long dword;
+			unsigned char byte[4];
+		} data;
+		unsigned char *pb;
+		int i;
+
+		count = len / 4;
+		insl(fifoaddr, buf, count);
+
+		if (len & 0x00000003) {
+			data.dword = inl(fifoaddr);
+			pb = (unsigned char *)buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++)
+				pb[i] = data.byte[i];
+		}
+	} else {
+		len = (len + 1) / 2;
+		insw(r8a66597->reg + offset, buf, len);
+	}
+}
+
+static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
+				  unsigned long offset)
+{
+	outw(val, r8a66597->reg + offset);
+}
+
+static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
+				       unsigned long offset, u16 *buf,
+				       int len)
+{
+	unsigned long fifoaddr = r8a66597->reg + offset;
+
+	if (r8a66597->pdata->on_chip) {
+		unsigned long count;
+		unsigned char *pb;
+		int i;
+
+		count = len / 4;
+		outsl(fifoaddr, buf, count);
+
+		if (len & 0x00000003) {
+			pb = (unsigned char *)buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++) {
+				if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
+					outb(pb[i], fifoaddr + i);
+				else
+					outb(pb[i], fifoaddr + 3 - i);
+			}
+		}
+	} else {
+		int odd = len & 0x0001;
+
+		len = len / 2;
+		outsw(fifoaddr, buf, len);
+		if (unlikely(odd)) {
+			buf = &buf[len];
+			outb((unsigned char)*buf, fifoaddr);
+		}
+	}
+}
+
+static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
+				 u16 val, u16 pat, unsigned long offset)
+{
+	u16 tmp;
+	tmp = r8a66597_read(r8a66597, offset);
+	tmp = tmp & (~pat);
+	tmp = tmp | val;
+	r8a66597_write(r8a66597, tmp, offset);
+}
+
+static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
+{
+	u16 clock = 0;
+
+	switch (pdata->xtal) {
+	case R8A66597_PLATDATA_XTAL_12MHZ:
+		clock = XTAL12;
+		break;
+	case R8A66597_PLATDATA_XTAL_24MHZ:
+		clock = XTAL24;
+		break;
+	case R8A66597_PLATDATA_XTAL_48MHZ:
+		clock = XTAL48;
+		break;
+	default:
+		printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
+		break;
+	}
+
+	return clock;
+}
+
+#define r8a66597_bclr(r8a66597, val, offset)	\
+			r8a66597_mdfy(r8a66597, 0, val, offset)
+#define r8a66597_bset(r8a66597, val, offset)	\
+			r8a66597_mdfy(r8a66597, val, 0, offset)
+
+#define get_pipectr_addr(pipenum)	(PIPE1CTR + (pipenum - 1) * 2)
+
+#define enable_irq_ready(r8a66597, pipenum)	\
+	enable_pipe_irq(r8a66597, pipenum, BRDYENB)
+#define disable_irq_ready(r8a66597, pipenum)	\
+	disable_pipe_irq(r8a66597, pipenum, BRDYENB)
+#define enable_irq_empty(r8a66597, pipenum)	\
+	enable_pipe_irq(r8a66597, pipenum, BEMPENB)
+#define disable_irq_empty(r8a66597, pipenum)	\
+	disable_pipe_irq(r8a66597, pipenum, BEMPENB)
+#define enable_irq_nrdy(r8a66597, pipenum)	\
+	enable_pipe_irq(r8a66597, pipenum, NRDYENB)
+#define disable_irq_nrdy(r8a66597, pipenum)	\
+	disable_pipe_irq(r8a66597, pipenum, NRDYENB)
+
+#endif	/* __R8A66597_H__ */
+
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 016f63b..c665219 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -181,7 +181,7 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
  *   - ... probably more ethtool ops
  */
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
 	.get_drvinfo = eth_get_drvinfo,
 	.get_link = ethtool_op_get_link,
 };
@@ -465,7 +465,8 @@ static inline int is_promisc(u16 cdc_filter)
 	return cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS;
 }
 
-static int eth_start_xmit(struct sk_buff *skb, struct net_device *net)
+static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
+					struct net_device *net)
 {
 	struct eth_dev		*dev = netdev_priv(net);
 	int			length = skb->len;
@@ -487,7 +488,7 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net)
 
 	if (!in) {
 		dev_kfree_skb_any(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	/* apply outgoing CDC or RNDIS filters */
@@ -506,7 +507,7 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net)
 				type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
 			if (!(cdc_filter & type)) {
 				dev_kfree_skb_any(skb);
-				return 0;
+				return NETDEV_TX_OK;
 			}
 		}
 		/* ignores USB_CDC_PACKET_TYPE_DIRECTED */
@@ -586,7 +587,7 @@ drop:
 		list_add(&req->list, &dev->tx_reqs);
 		spin_unlock_irqrestore(&dev->req_lock, flags);
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1a920c7..f21ca7d 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -336,13 +336,6 @@ config USB_R8A66597_HCD
 	  To compile this driver as a module, choose M here: the
 	  module will be called r8a66597-hcd.
 
-config SUPERH_ON_CHIP_R8A66597
-	boolean "Enable SuperH on-chip R8A66597 USB"
-	depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
-	help
-	   This driver enables support for the on-chip R8A66597 in the
-	   SH7366, SH7723 and SH7724 processors.
-
 config USB_WHCI_HCD
 	tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index e18f749..749b537 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -91,43 +91,43 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
 	u16 tmp;
 	int i = 0;
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#if defined(CONFIG_HAVE_CLK)
-	clk_enable(r8a66597->clk);
+	if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+		clk_enable(r8a66597->clk);
 #endif
-	do {
-		r8a66597_write(r8a66597, SCKE, SYSCFG0);
-		tmp = r8a66597_read(r8a66597, SYSCFG0);
-		if (i++ > 1000) {
-			printk(KERN_ERR "r8a66597: register access fail.\n");
-			return -ENXIO;
-		}
-	} while ((tmp & SCKE) != SCKE);
-	r8a66597_write(r8a66597, 0x04, 0x02);
-#else
-	do {
-		r8a66597_write(r8a66597, USBE, SYSCFG0);
-		tmp = r8a66597_read(r8a66597, SYSCFG0);
-		if (i++ > 1000) {
-			printk(KERN_ERR "r8a66597: register access fail.\n");
-			return -ENXIO;
-		}
-	} while ((tmp & USBE) != USBE);
-	r8a66597_bclr(r8a66597, USBE, SYSCFG0);
-	r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata), XTAL,
-			SYSCFG0);
+		do {
+			r8a66597_write(r8a66597, SCKE, SYSCFG0);
+			tmp = r8a66597_read(r8a66597, SYSCFG0);
+			if (i++ > 1000) {
+				printk(KERN_ERR "r8a66597: reg access fail.\n");
+				return -ENXIO;
+			}
+		} while ((tmp & SCKE) != SCKE);
+		r8a66597_write(r8a66597, 0x04, 0x02);
+	} else {
+		do {
+			r8a66597_write(r8a66597, USBE, SYSCFG0);
+			tmp = r8a66597_read(r8a66597, SYSCFG0);
+			if (i++ > 1000) {
+				printk(KERN_ERR "r8a66597: reg access fail.\n");
+				return -ENXIO;
+			}
+		} while ((tmp & USBE) != USBE);
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+		r8a66597_mdfy(r8a66597, get_xtal_from_pdata(r8a66597->pdata),
+			      XTAL, SYSCFG0);
 
-	i = 0;
-	r8a66597_bset(r8a66597, XCKE, SYSCFG0);
-	do {
-		msleep(1);
-		tmp = r8a66597_read(r8a66597, SYSCFG0);
-		if (i++ > 500) {
-			printk(KERN_ERR "r8a66597: register access fail.\n");
-			return -ENXIO;
-		}
-	} while ((tmp & SCKE) != SCKE);
-#endif	/* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
+		i = 0;
+		r8a66597_bset(r8a66597, XCKE, SYSCFG0);
+		do {
+			msleep(1);
+			tmp = r8a66597_read(r8a66597, SYSCFG0);
+			if (i++ > 500) {
+				printk(KERN_ERR "r8a66597: reg access fail.\n");
+				return -ENXIO;
+			}
+		} while ((tmp & SCKE) != SCKE);
+	}
 
 	return 0;
 }
@@ -136,15 +136,16 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597)
 {
 	r8a66597_bclr(r8a66597, SCKE, SYSCFG0);
 	udelay(1);
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#if defined(CONFIG_HAVE_CLK)
-	clk_disable(r8a66597->clk);
-#endif
-#else
-	r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
-	r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
-	r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+
+	if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+		clk_disable(r8a66597->clk);
 #endif
+	} else {
+		r8a66597_bclr(r8a66597, PLLC, SYSCFG0);
+		r8a66597_bclr(r8a66597, XCKE, SYSCFG0);
+		r8a66597_bclr(r8a66597, USBE, SYSCFG0);
+	}
 }
 
 static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port)
@@ -205,7 +206,7 @@ static int enable_controller(struct r8a66597 *r8a66597)
 
 	r8a66597_bset(r8a66597, SIGNE | SACKE, INTENB1);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+	for (port = 0; port < r8a66597->max_root_hub; port++)
 		r8a66597_enable_port(r8a66597, port);
 
 	return 0;
@@ -218,7 +219,7 @@ static void disable_controller(struct r8a66597 *r8a66597)
 	r8a66597_write(r8a66597, 0, INTENB0);
 	r8a66597_write(r8a66597, 0, INTSTS0);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+	for (port = 0; port < r8a66597->max_root_hub; port++)
 		r8a66597_disable_port(r8a66597, port);
 
 	r8a66597_clock_disable(r8a66597);
@@ -249,11 +250,12 @@ static int is_hub_limit(char *devpath)
 	return ((strlen(devpath) >= 4) ? 1 : 0);
 }
 
-static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
+static void get_port_number(struct r8a66597 *r8a66597,
+			    char *devpath, u16 *root_port, u16 *hub_port)
 {
 	if (root_port) {
 		*root_port = (devpath[0] & 0x0F) - 1;
-		if (*root_port >= R8A66597_MAX_ROOT_HUB)
+		if (*root_port >= r8a66597->max_root_hub)
 			printk(KERN_ERR "r8a66597: Illegal root port number.\n");
 	}
 	if (hub_port)
@@ -355,7 +357,8 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597,
 	INIT_LIST_HEAD(&dev->device_list);
 	list_add_tail(&dev->device_list, &r8a66597->child_device);
 
-	get_port_number(urb->dev->devpath, &dev->root_port, &dev->hub_port);
+	get_port_number(r8a66597, urb->dev->devpath,
+			&dev->root_port, &dev->hub_port);
 	if (!is_child_device(urb->dev->devpath))
 		r8a66597->root_hub[dev->root_port].dev = dev;
 
@@ -420,7 +423,7 @@ static void free_usb_address(struct r8a66597 *r8a66597,
 	list_del(&dev->device_list);
 	kfree(dev);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		if (r8a66597->root_hub[port].dev == dev) {
 			r8a66597->root_hub[port].dev = NULL;
 			break;
@@ -495,10 +498,20 @@ static void r8a66597_pipe_toggle(struct r8a66597 *r8a66597,
 		r8a66597_bset(r8a66597, SQCLR, pipe->pipectr);
 }
 
+static inline unsigned short mbw_value(struct r8a66597 *r8a66597)
+{
+	if (r8a66597->pdata->on_chip)
+		return MBW_32;
+	else
+		return MBW_16;
+}
+
 /* this function must be called with interrupt disabled */
 static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
 {
-	r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL);
+	unsigned short mbw = mbw_value(r8a66597);
+
+	r8a66597_mdfy(r8a66597, mbw | pipenum, mbw | CURPIPE, CFIFOSEL);
 	r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum);
 }
 
@@ -506,11 +519,13 @@ static inline void cfifo_change(struct r8a66597 *r8a66597, u16 pipenum)
 static inline void fifo_change_from_pipe(struct r8a66597 *r8a66597,
 					 struct r8a66597_pipe *pipe)
 {
+	unsigned short mbw = mbw_value(r8a66597);
+
 	cfifo_change(r8a66597, 0);
-	r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D0FIFOSEL);
-	r8a66597_mdfy(r8a66597, MBW | 0, MBW | CURPIPE, D1FIFOSEL);
+	r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D0FIFOSEL);
+	r8a66597_mdfy(r8a66597, mbw | 0, mbw | CURPIPE, D1FIFOSEL);
 
-	r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum, MBW | CURPIPE,
+	r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum, mbw | CURPIPE,
 		      pipe->fifosel);
 	r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE, pipe->info.pipenum);
 }
@@ -742,9 +757,13 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
 				     struct r8a66597_pipe *pipe,
 				     struct urb *urb)
 {
-#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
 	int i;
 	struct r8a66597_pipe_info *info = &pipe->info;
+	unsigned short mbw = mbw_value(r8a66597);
+
+	/* pipe dma is only for external controlles */
+	if (r8a66597->pdata->on_chip)
+		return;
 
 	if ((pipe->info.pipenum != 0) && (info->type != R8A66597_INT)) {
 		for (i = 0; i < R8A66597_MAX_DMA_CHANNEL; i++) {
@@ -763,8 +782,8 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
 			set_pipe_reg_addr(pipe, i);
 
 			cfifo_change(r8a66597, 0);
-			r8a66597_mdfy(r8a66597, MBW | pipe->info.pipenum,
-				      MBW | CURPIPE, pipe->fifosel);
+			r8a66597_mdfy(r8a66597, mbw | pipe->info.pipenum,
+				      mbw | CURPIPE, pipe->fifosel);
 
 			r8a66597_reg_wait(r8a66597, pipe->fifosel, CURPIPE,
 					  pipe->info.pipenum);
@@ -772,7 +791,6 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
 			break;
 		}
 	}
-#endif	/* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */
 }
 
 /* this function must be called with interrupt disabled */
@@ -1769,7 +1787,7 @@ static void r8a66597_timer(unsigned long _r8a66597)
 
 	spin_lock_irqsave(&r8a66597->lock, flags);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++)
+	for (port = 0; port < r8a66597->max_root_hub; port++)
 		r8a66597_root_hub_control(r8a66597, port);
 
 	spin_unlock_irqrestore(&r8a66597->lock, flags);
@@ -1807,7 +1825,7 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb)
 	u16 root_port, hub_port;
 
 	if (usb_address == 0) {
-		get_port_number(urb->dev->devpath,
+		get_port_number(r8a66597, urb->dev->devpath,
 				&root_port, &hub_port);
 		set_devadd_reg(r8a66597, 0,
 			       get_r8a66597_usb_speed(urb->dev->speed),
@@ -2082,7 +2100,7 @@ static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf)
 
 	*buf = 0;	/* initialize (no change) */
 
-	for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) {
+	for (i = 0; i < r8a66597->max_root_hub; i++) {
 		if (r8a66597->root_hub[i].port & 0xffff0000)
 			*buf |= 1 << (i + 1);
 	}
@@ -2097,11 +2115,11 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
 {
 	desc->bDescriptorType = 0x29;
 	desc->bHubContrCurrent = 0;
-	desc->bNbrPorts = R8A66597_MAX_ROOT_HUB;
+	desc->bNbrPorts = r8a66597->max_root_hub;
 	desc->bDescLength = 9;
 	desc->bPwrOn2PwrGood = 0;
 	desc->wHubCharacteristics = cpu_to_le16(0x0011);
-	desc->bitmap[0] = ((1 << R8A66597_MAX_ROOT_HUB) - 1) << 1;
+	desc->bitmap[0] = ((1 << r8a66597->max_root_hub) - 1) << 1;
 	desc->bitmap[1] = ~0;
 }
 
@@ -2129,7 +2147,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		}
 		break;
 	case ClearPortFeature:
-		if (wIndex > R8A66597_MAX_ROOT_HUB)
+		if (wIndex > r8a66597->max_root_hub)
 			goto error;
 		if (wLength != 0)
 			goto error;
@@ -2162,12 +2180,12 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 		*buf = 0x00;
 		break;
 	case GetPortStatus:
-		if (wIndex > R8A66597_MAX_ROOT_HUB)
+		if (wIndex > r8a66597->max_root_hub)
 			goto error;
 		*(__le32 *)buf = cpu_to_le32(rh->port);
 		break;
 	case SetPortFeature:
-		if (wIndex > R8A66597_MAX_ROOT_HUB)
+		if (wIndex > r8a66597->max_root_hub)
 			goto error;
 		if (wLength != 0)
 			goto error;
@@ -2216,7 +2234,7 @@ static int r8a66597_bus_suspend(struct usb_hcd *hcd)
 
 	dbg("%s", __func__);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 		unsigned long dvstctr_reg = get_dvstctr_reg(port);
 
@@ -2247,7 +2265,7 @@ static int r8a66597_bus_resume(struct usb_hcd *hcd)
 
 	dbg("%s", __func__);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 		unsigned long dvstctr_reg = get_dvstctr_reg(port);
 
@@ -2305,16 +2323,16 @@ static struct hc_driver r8a66597_hc_driver = {
 };
 
 #if defined(CONFIG_PM)
-static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
+static int r8a66597_suspend(struct device *dev)
 {
-	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
+	struct r8a66597		*r8a66597 = dev_get_drvdata(dev);
 	int port;
 
 	dbg("%s", __func__);
 
 	disable_controller(r8a66597);
 
-	for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) {
+	for (port = 0; port < r8a66597->max_root_hub; port++) {
 		struct r8a66597_root_hub *rh = &r8a66597->root_hub[port];
 
 		rh->port = 0x00000000;
@@ -2323,9 +2341,9 @@ static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state)
 	return 0;
 }
 
-static int r8a66597_resume(struct platform_device *pdev)
+static int r8a66597_resume(struct device *dev)
 {
-	struct r8a66597		*r8a66597 = dev_get_drvdata(&pdev->dev);
+	struct r8a66597		*r8a66597 = dev_get_drvdata(dev);
 	struct usb_hcd		*hcd = r8a66597_to_hcd(r8a66597);
 
 	dbg("%s", __func__);
@@ -2335,9 +2353,17 @@ static int r8a66597_resume(struct platform_device *pdev)
 
 	return 0;
 }
+
+static struct dev_pm_ops r8a66597_dev_pm_ops = {
+	.suspend = r8a66597_suspend,
+	.resume = r8a66597_resume,
+	.poweroff = r8a66597_suspend,
+	.restore = r8a66597_resume,
+};
+
+#define R8A66597_DEV_PM_OPS	(&r8a66597_dev_pm_ops)
 #else	/* if defined(CONFIG_PM) */
-#define r8a66597_suspend	NULL
-#define r8a66597_resume		NULL
+#define R8A66597_DEV_PM_OPS	NULL
 #endif
 
 static int __init_or_module r8a66597_remove(struct platform_device *pdev)
@@ -2348,8 +2374,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
 	del_timer_sync(&r8a66597->rh_timer);
 	usb_remove_hcd(hcd);
 	iounmap((void *)r8a66597->reg);
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-	clk_put(r8a66597->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip)
+		clk_put(r8a66597->clk);
 #endif
 	usb_put_hcd(hcd);
 	return 0;
@@ -2357,7 +2384,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
 
 static int __devinit r8a66597_probe(struct platform_device *pdev)
 {
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	char clk_name[8];
 #endif
 	struct resource *res = NULL, *ires;
@@ -2419,15 +2446,20 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
 	r8a66597->pdata = pdev->dev.platform_data;
 	r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-	snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
-	r8a66597->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(r8a66597->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		ret = PTR_ERR(r8a66597->clk);
-		goto clean_up2;
-	}
+	if (r8a66597->pdata->on_chip) {
+#ifdef CONFIG_HAVE_CLK
+		snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id);
+		r8a66597->clk = clk_get(&pdev->dev, clk_name);
+		if (IS_ERR(r8a66597->clk)) {
+			dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
+				clk_name);
+			ret = PTR_ERR(r8a66597->clk);
+			goto clean_up2;
+		}
 #endif
+		r8a66597->max_root_hub = 1;
+	} else
+		r8a66597->max_root_hub = 2;
 
 	spin_lock_init(&r8a66597->lock);
 	init_timer(&r8a66597->rh_timer);
@@ -2457,8 +2489,9 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
 	return 0;
 
 clean_up3:
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
-	clk_put(r8a66597->clk);
+#ifdef CONFIG_HAVE_CLK
+	if (r8a66597->pdata->on_chip)
+		clk_put(r8a66597->clk);
 clean_up2:
 #endif
 	usb_put_hcd(hcd);
@@ -2473,11 +2506,10 @@ clean_up:
 static struct platform_driver r8a66597_driver = {
 	.probe =	r8a66597_probe,
 	.remove =	r8a66597_remove,
-	.suspend =	r8a66597_suspend,
-	.resume =	r8a66597_resume,
 	.driver		= {
 		.name = (char *) hcd_name,
 		.owner	= THIS_MODULE,
+		.pm	= R8A66597_DEV_PM_OPS,
 	},
 };
 
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h
index d72680b..228e3fb 100644
--- a/drivers/usb/host/r8a66597.h
+++ b/drivers/usb/host/r8a66597.h
@@ -26,390 +26,16 @@
 #ifndef __R8A66597_H__
 #define __R8A66597_H__
 
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 #include <linux/clk.h>
 #endif
 
 #include <linux/usb/r8a66597.h>
 
-#define SYSCFG0		0x00
-#define SYSCFG1		0x02
-#define SYSSTS0		0x04
-#define SYSSTS1		0x06
-#define DVSTCTR0	0x08
-#define DVSTCTR1	0x0A
-#define TESTMODE	0x0C
-#define PINCFG		0x0E
-#define DMA0CFG		0x10
-#define DMA1CFG		0x12
-#define CFIFO		0x14
-#define D0FIFO		0x18
-#define D1FIFO		0x1C
-#define CFIFOSEL	0x20
-#define CFIFOCTR	0x22
-#define CFIFOSIE	0x24
-#define D0FIFOSEL	0x28
-#define D0FIFOCTR	0x2A
-#define D1FIFOSEL	0x2C
-#define D1FIFOCTR	0x2E
-#define INTENB0		0x30
-#define INTENB1		0x32
-#define INTENB2		0x34
-#define BRDYENB		0x36
-#define NRDYENB		0x38
-#define BEMPENB		0x3A
-#define SOFCFG		0x3C
-#define INTSTS0		0x40
-#define INTSTS1		0x42
-#define INTSTS2		0x44
-#define BRDYSTS		0x46
-#define NRDYSTS		0x48
-#define BEMPSTS		0x4A
-#define FRMNUM		0x4C
-#define UFRMNUM		0x4E
-#define USBADDR		0x50
-#define USBREQ		0x54
-#define USBVAL		0x56
-#define USBINDX		0x58
-#define USBLENG		0x5A
-#define DCPCFG		0x5C
-#define DCPMAXP		0x5E
-#define DCPCTR		0x60
-#define PIPESEL		0x64
-#define PIPECFG		0x68
-#define PIPEBUF		0x6A
-#define PIPEMAXP	0x6C
-#define PIPEPERI	0x6E
-#define PIPE1CTR	0x70
-#define PIPE2CTR	0x72
-#define PIPE3CTR	0x74
-#define PIPE4CTR	0x76
-#define PIPE5CTR	0x78
-#define PIPE6CTR	0x7A
-#define PIPE7CTR	0x7C
-#define PIPE8CTR	0x7E
-#define PIPE9CTR	0x80
-#define PIPE1TRE	0x90
-#define PIPE1TRN	0x92
-#define PIPE2TRE	0x94
-#define PIPE2TRN	0x96
-#define PIPE3TRE	0x98
-#define PIPE3TRN	0x9A
-#define PIPE4TRE	0x9C
-#define	PIPE4TRN	0x9E
-#define	PIPE5TRE	0xA0
-#define	PIPE5TRN	0xA2
-#define DEVADD0		0xD0
-#define DEVADD1		0xD2
-#define DEVADD2		0xD4
-#define DEVADD3		0xD6
-#define DEVADD4		0xD8
-#define DEVADD5		0xDA
-#define DEVADD6		0xDC
-#define DEVADD7		0xDE
-#define DEVADD8		0xE0
-#define DEVADD9		0xE2
-#define DEVADDA		0xE4
-
-/* System Configuration Control Register */
-#define	XTAL		0xC000	/* b15-14: Crystal selection */
-#define	  XTAL48	 0x8000	  /* 48MHz */
-#define	  XTAL24	 0x4000	  /* 24MHz */
-#define	  XTAL12	 0x0000	  /* 12MHz */
-#define	XCKE		0x2000	/* b13: External clock enable */
-#define	PLLC		0x0800	/* b11: PLL control */
-#define	SCKE		0x0400	/* b10: USB clock enable */
-#define	PCSDIS		0x0200	/* b9: not CS wakeup */
-#define	LPSME		0x0100	/* b8: Low power sleep mode */
-#define	HSE		0x0080	/* b7: Hi-speed enable */
-#define	DCFM		0x0040	/* b6: Controller function select  */
-#define	DRPD		0x0020	/* b5: D+/- pull down control */
-#define	DPRPU		0x0010	/* b4: D+ pull up control */
-#define	USBE		0x0001	/* b0: USB module operation enable */
-
-/* System Configuration Status Register */
-#define	OVCBIT		0x8000	/* b15-14: Over-current bit */
-#define	OVCMON		0xC000	/* b15-14: Over-current monitor */
-#define	SOFEA		0x0020	/* b5: SOF monitor */
-#define	IDMON		0x0004	/* b3: ID-pin monitor */
-#define	LNST		0x0003	/* b1-0: D+, D- line status */
-#define	  SE1		 0x0003	  /* SE1 */
-#define	  FS_KSTS	 0x0002	  /* Full-Speed K State */
-#define	  FS_JSTS	 0x0001	  /* Full-Speed J State */
-#define	  LS_JSTS	 0x0002	  /* Low-Speed J State */
-#define	  LS_KSTS	 0x0001	  /* Low-Speed K State */
-#define	  SE0		 0x0000	  /* SE0 */
-
-/* Device State Control Register */
-#define	EXTLP0		0x0400	/* b10: External port */
-#define	VBOUT		0x0200	/* b9: VBUS output */
-#define	WKUP		0x0100	/* b8: Remote wakeup */
-#define	RWUPE		0x0080	/* b7: Remote wakeup sense */
-#define	USBRST		0x0040	/* b6: USB reset enable */
-#define	RESUME		0x0020	/* b5: Resume enable */
-#define	UACT		0x0010	/* b4: USB bus enable */
-#define	RHST		0x0007	/* b1-0: Reset handshake status */
-#define	  HSPROC	 0x0004	  /* HS handshake is processing */
-#define	  HSMODE	 0x0003	  /* Hi-Speed mode */
-#define	  FSMODE	 0x0002	  /* Full-Speed mode */
-#define	  LSMODE	 0x0001	  /* Low-Speed mode */
-#define	  UNDECID	 0x0000	  /* Undecided */
-
-/* Test Mode Register */
-#define	UTST			0x000F	/* b3-0: Test select */
-#define	  H_TST_PACKET		 0x000C	  /* HOST TEST Packet */
-#define	  H_TST_SE0_NAK		 0x000B	  /* HOST TEST SE0 NAK */
-#define	  H_TST_K		 0x000A	  /* HOST TEST K */
-#define	  H_TST_J		 0x0009	  /* HOST TEST J */
-#define	  H_TST_NORMAL		 0x0000	  /* HOST Normal Mode */
-#define	  P_TST_PACKET		 0x0004	  /* PERI TEST Packet */
-#define	  P_TST_SE0_NAK		 0x0003	  /* PERI TEST SE0 NAK */
-#define	  P_TST_K		 0x0002	  /* PERI TEST K */
-#define	  P_TST_J		 0x0001	  /* PERI TEST J */
-#define	  P_TST_NORMAL		 0x0000	  /* PERI Normal Mode */
-
-/* Data Pin Configuration Register */
-#define	LDRV			0x8000	/* b15: Drive Current Adjust */
-#define	  VIF1			  0x0000		/* VIF = 1.8V */
-#define	  VIF3			  0x8000		/* VIF = 3.3V */
-#define	INTA			0x0001	/* b1: USB INT-pin active */
-
-/* DMAx Pin Configuration Register */
-#define	DREQA			0x4000	/* b14: Dreq active select */
-#define	BURST			0x2000	/* b13: Burst mode */
-#define	DACKA			0x0400	/* b10: Dack active select */
-#define	DFORM			0x0380	/* b9-7: DMA mode select */
-#define	  CPU_ADR_RD_WR		 0x0000	  /* Address + RD/WR mode (CPU bus) */
-#define	  CPU_DACK_RD_WR	 0x0100	  /* DACK + RD/WR mode (CPU bus) */
-#define	  CPU_DACK_ONLY		 0x0180	  /* DACK only mode (CPU bus) */
-#define	  SPLIT_DACK_ONLY	 0x0200	  /* DACK only mode (SPLIT bus) */
-#define	DENDA			0x0040	/* b6: Dend active select */
-#define	PKTM			0x0020	/* b5: Packet mode */
-#define	DENDE			0x0010	/* b4: Dend enable */
-#define	OBUS			0x0004	/* b2: OUTbus mode */
-
-/* CFIFO/DxFIFO Port Select Register */
-#define	RCNT		0x8000	/* b15: Read count mode */
-#define	REW		0x4000	/* b14: Buffer rewind */
-#define	DCLRM		0x2000	/* b13: DMA buffer clear mode */
-#define	DREQE		0x1000	/* b12: DREQ output enable */
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#define	MBW		0x0800
-#else
-#define	MBW		0x0400	/* b10: Maximum bit width for FIFO access */
-#endif
-#define	  MBW_8		 0x0000	  /*  8bit */
-#define	  MBW_16	 0x0400	  /* 16bit */
-#define	BIGEND		0x0100	/* b8: Big endian mode */
-#define	  BYTE_LITTLE	 0x0000		/* little dendian */
-#define	  BYTE_BIG	 0x0100		/* big endifan */
-#define	ISEL		0x0020	/* b5: DCP FIFO port direction select */
-#define	CURPIPE		0x000F	/* b2-0: PIPE select */
-
-/* CFIFO/DxFIFO Port Control Register */
-#define	BVAL		0x8000	/* b15: Buffer valid flag */
-#define	BCLR		0x4000	/* b14: Buffer clear */
-#define	FRDY		0x2000	/* b13: FIFO ready */
-#define	DTLN		0x0FFF	/* b11-0: FIFO received data length */
-
-/* Interrupt Enable Register 0 */
-#define	VBSE	0x8000	/* b15: VBUS interrupt */
-#define	RSME	0x4000	/* b14: Resume interrupt */
-#define	SOFE	0x2000	/* b13: Frame update interrupt */
-#define	DVSE	0x1000	/* b12: Device state transition interrupt */
-#define	CTRE	0x0800	/* b11: Control transfer stage transition interrupt */
-#define	BEMPE	0x0400	/* b10: Buffer empty interrupt */
-#define	NRDYE	0x0200	/* b9: Buffer not ready interrupt */
-#define	BRDYE	0x0100	/* b8: Buffer ready interrupt */
-
-/* Interrupt Enable Register 1 */
-#define	OVRCRE		0x8000	/* b15: Over-current interrupt */
-#define	BCHGE		0x4000	/* b14: USB us chenge interrupt */
-#define	DTCHE		0x1000	/* b12: Detach sense interrupt */
-#define	ATTCHE		0x0800	/* b11: Attach sense interrupt */
-#define	EOFERRE		0x0040	/* b6: EOF error interrupt */
-#define	SIGNE		0x0020	/* b5: SETUP IGNORE interrupt */
-#define	SACKE		0x0010	/* b4: SETUP ACK interrupt */
-
-/* BRDY Interrupt Enable/Status Register */
-#define	BRDY9		0x0200	/* b9: PIPE9 */
-#define	BRDY8		0x0100	/* b8: PIPE8 */
-#define	BRDY7		0x0080	/* b7: PIPE7 */
-#define	BRDY6		0x0040	/* b6: PIPE6 */
-#define	BRDY5		0x0020	/* b5: PIPE5 */
-#define	BRDY4		0x0010	/* b4: PIPE4 */
-#define	BRDY3		0x0008	/* b3: PIPE3 */
-#define	BRDY2		0x0004	/* b2: PIPE2 */
-#define	BRDY1		0x0002	/* b1: PIPE1 */
-#define	BRDY0		0x0001	/* b1: PIPE0 */
-
-/* NRDY Interrupt Enable/Status Register */
-#define	NRDY9		0x0200	/* b9: PIPE9 */
-#define	NRDY8		0x0100	/* b8: PIPE8 */
-#define	NRDY7		0x0080	/* b7: PIPE7 */
-#define	NRDY6		0x0040	/* b6: PIPE6 */
-#define	NRDY5		0x0020	/* b5: PIPE5 */
-#define	NRDY4		0x0010	/* b4: PIPE4 */
-#define	NRDY3		0x0008	/* b3: PIPE3 */
-#define	NRDY2		0x0004	/* b2: PIPE2 */
-#define	NRDY1		0x0002	/* b1: PIPE1 */
-#define	NRDY0		0x0001	/* b1: PIPE0 */
-
-/* BEMP Interrupt Enable/Status Register */
-#define	BEMP9		0x0200	/* b9: PIPE9 */
-#define	BEMP8		0x0100	/* b8: PIPE8 */
-#define	BEMP7		0x0080	/* b7: PIPE7 */
-#define	BEMP6		0x0040	/* b6: PIPE6 */
-#define	BEMP5		0x0020	/* b5: PIPE5 */
-#define	BEMP4		0x0010	/* b4: PIPE4 */
-#define	BEMP3		0x0008	/* b3: PIPE3 */
-#define	BEMP2		0x0004	/* b2: PIPE2 */
-#define	BEMP1		0x0002	/* b1: PIPE1 */
-#define	BEMP0		0x0001	/* b0: PIPE0 */
-
-/* SOF Pin Configuration Register */
-#define	TRNENSEL	0x0100	/* b8: Select transaction enable period */
-#define	BRDYM		0x0040	/* b6: BRDY clear timing */
-#define	INTL		0x0020	/* b5: Interrupt sense select */
-#define	EDGESTS		0x0010	/* b4:  */
-#define	SOFMODE		0x000C	/* b3-2: SOF pin select */
-#define	  SOF_125US	 0x0008	  /* SOF OUT 125us Frame Signal */
-#define	  SOF_1MS	 0x0004	  /* SOF OUT 1ms Frame Signal */
-#define	  SOF_DISABLE	 0x0000	  /* SOF OUT Disable */
-
-/* Interrupt Status Register 0 */
-#define	VBINT	0x8000	/* b15: VBUS interrupt */
-#define	RESM	0x4000	/* b14: Resume interrupt */
-#define	SOFR	0x2000	/* b13: SOF frame update interrupt */
-#define	DVST	0x1000	/* b12: Device state transition interrupt */
-#define	CTRT	0x0800	/* b11: Control transfer stage transition interrupt */
-#define	BEMP	0x0400	/* b10: Buffer empty interrupt */
-#define	NRDY	0x0200	/* b9: Buffer not ready interrupt */
-#define	BRDY	0x0100	/* b8: Buffer ready interrupt */
-#define	VBSTS	0x0080	/* b7: VBUS input port */
-#define	DVSQ	0x0070	/* b6-4: Device state */
-#define	  DS_SPD_CNFG	 0x0070	  /* Suspend Configured */
-#define	  DS_SPD_ADDR	 0x0060	  /* Suspend Address */
-#define	  DS_SPD_DFLT	 0x0050	  /* Suspend Default */
-#define	  DS_SPD_POWR	 0x0040	  /* Suspend Powered */
-#define	  DS_SUSP	 0x0040	  /* Suspend */
-#define	  DS_CNFG	 0x0030	  /* Configured */
-#define	  DS_ADDS	 0x0020	  /* Address */
-#define	  DS_DFLT	 0x0010	  /* Default */
-#define	  DS_POWR	 0x0000	  /* Powered */
-#define	DVSQS		0x0030	/* b5-4: Device state */
-#define	VALID		0x0008	/* b3: Setup packet detected flag */
-#define	CTSQ		0x0007	/* b2-0: Control transfer stage */
-#define	  CS_SQER	 0x0006	  /* Sequence error */
-#define	  CS_WRND	 0x0005	  /* Control write nodata status stage */
-#define	  CS_WRSS	 0x0004	  /* Control write status stage */
-#define	  CS_WRDS	 0x0003	  /* Control write data stage */
-#define	  CS_RDSS	 0x0002	  /* Control read status stage */
-#define	  CS_RDDS	 0x0001	  /* Control read data stage */
-#define	  CS_IDST	 0x0000	  /* Idle or setup stage */
-
-/* Interrupt Status Register 1 */
-#define	OVRCR		0x8000	/* b15: Over-current interrupt */
-#define	BCHG		0x4000	/* b14: USB bus chenge interrupt */
-#define	DTCH		0x1000	/* b12: Detach sense interrupt */
-#define	ATTCH		0x0800	/* b11: Attach sense interrupt */
-#define	EOFERR		0x0040	/* b6: EOF-error interrupt */
-#define	SIGN		0x0020	/* b5: Setup ignore interrupt */
-#define	SACK		0x0010	/* b4: Setup acknowledge interrupt */
-
-/* Frame Number Register */
-#define	OVRN		0x8000	/* b15: Overrun error */
-#define	CRCE		0x4000	/* b14: Received data error */
-#define	FRNM		0x07FF	/* b10-0: Frame number */
-
-/* Micro Frame Number Register */
-#define	UFRNM		0x0007	/* b2-0: Micro frame number */
-
-/* Default Control Pipe Maxpacket Size Register */
-/* Pipe Maxpacket Size Register */
-#define	DEVSEL	0xF000	/* b15-14: Device address select */
-#define	MAXP	0x007F	/* b6-0: Maxpacket size of default control pipe */
-
-/* Default Control Pipe Control Register */
-#define	BSTS		0x8000	/* b15: Buffer status */
-#define	SUREQ		0x4000	/* b14: Send USB request  */
-#define	CSCLR		0x2000	/* b13: complete-split status clear */
-#define	CSSTS		0x1000	/* b12: complete-split status */
-#define	SUREQCLR	0x0800	/* b11: stop setup request */
-#define	SQCLR		0x0100	/* b8: Sequence toggle bit clear */
-#define	SQSET		0x0080	/* b7: Sequence toggle bit set */
-#define	SQMON		0x0040	/* b6: Sequence toggle bit monitor */
-#define	PBUSY		0x0020	/* b5: pipe busy */
-#define	PINGE		0x0010	/* b4: ping enable */
-#define	CCPL		0x0004	/* b2: Enable control transfer complete */
-#define	PID		0x0003	/* b1-0: Response PID */
-#define	  PID_STALL11	 0x0003	  /* STALL */
-#define	  PID_STALL	 0x0002	  /* STALL */
-#define	  PID_BUF	 0x0001	  /* BUF */
-#define	  PID_NAK	 0x0000	  /* NAK */
-
-/* Pipe Window Select Register */
-#define	PIPENM		0x0007	/* b2-0: Pipe select */
-
-/* Pipe Configuration Register */
-#define	R8A66597_TYP	0xC000	/* b15-14: Transfer type */
-#define	  R8A66597_ISO	 0xC000		  /* Isochronous */
-#define	  R8A66597_INT	 0x8000		  /* Interrupt */
-#define	  R8A66597_BULK	 0x4000		  /* Bulk */
-#define	R8A66597_BFRE	0x0400	/* b10: Buffer ready interrupt mode select */
-#define	R8A66597_DBLB	0x0200	/* b9: Double buffer mode select */
-#define	R8A66597_CNTMD	0x0100	/* b8: Continuous transfer mode select */
-#define	R8A66597_SHTNAK	0x0080	/* b7: Transfer end NAK */
-#define	R8A66597_DIR	0x0010	/* b4: Transfer direction select */
-#define	R8A66597_EPNUM	0x000F	/* b3-0: Eendpoint number select */
-
-/* Pipe Buffer Configuration Register */
-#define	BUFSIZE		0x7C00	/* b14-10: Pipe buffer size */
-#define	BUFNMB		0x007F	/* b6-0: Pipe buffer number */
-#define	PIPE0BUF	256
-#define	PIPExBUF	64
-
-/* Pipe Maxpacket Size Register */
-#define	MXPS		0x07FF	/* b10-0: Maxpacket size */
-
-/* Pipe Cycle Configuration Register */
-#define	IFIS	0x1000	/* b12: Isochronous in-buffer flush mode select */
-#define	IITV	0x0007	/* b2-0: Isochronous interval */
-
-/* Pipex Control Register */
-#define	BSTS	0x8000	/* b15: Buffer status */
-#define	INBUFM	0x4000	/* b14: IN buffer monitor (Only for PIPE1 to 5) */
-#define	CSCLR	0x2000	/* b13: complete-split status clear */
-#define	CSSTS	0x1000	/* b12: complete-split status */
-#define	ATREPM	0x0400	/* b10: Auto repeat mode */
-#define	ACLRM	0x0200	/* b9: Out buffer auto clear mode */
-#define	SQCLR	0x0100	/* b8: Sequence toggle bit clear */
-#define	SQSET	0x0080	/* b7: Sequence toggle bit set */
-#define	SQMON	0x0040	/* b6: Sequence toggle bit monitor */
-#define	PBUSY	0x0020	/* b5: pipe busy */
-#define	PID	0x0003	/* b1-0: Response PID */
-
-/* PIPExTRE */
-#define	TRENB		0x0200	/* b9: Transaction counter enable */
-#define	TRCLR		0x0100	/* b8: Transaction counter clear */
-
-/* PIPExTRN */
-#define	TRNCNT		0xFFFF	/* b15-0: Transaction counter */
-
-/* DEVADDx */
-#define	UPPHUB		0x7800
-#define	HUBPORT		0x0700
-#define	USBSPD		0x00C0
-#define	RTPORT		0x0001
-
 #define R8A66597_MAX_NUM_PIPE		10
 #define R8A66597_BUF_BSIZE		8
 #define R8A66597_MAX_DEVICE		10
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
-#define R8A66597_MAX_ROOT_HUB		1
-#else
 #define R8A66597_MAX_ROOT_HUB		2
-#endif
 #define R8A66597_MAX_SAMPLING		5
 #define R8A66597_RH_POLL_TIME		10
 #define R8A66597_MAX_DMA_CHANNEL	2
@@ -487,7 +113,7 @@ struct r8a66597_root_hub {
 struct r8a66597 {
 	spinlock_t lock;
 	unsigned long reg;
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK)
+#ifdef CONFIG_HAVE_CLK
 	struct clk *clk;
 #endif
 	struct r8a66597_platdata	*pdata;
@@ -504,6 +130,7 @@ struct r8a66597 {
 	unsigned short interval_map;
 	unsigned char pipe_cnt[R8A66597_MAX_NUM_PIPE];
 	unsigned char dma_map;
+	unsigned int max_root_hub;
 
 	struct list_head child_device;
 	unsigned long child_connect_map[4];
@@ -550,21 +177,22 @@ static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
 				      unsigned long offset, u16 *buf,
 				      int len)
 {
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
 	unsigned long fifoaddr = r8a66597->reg + offset;
 	unsigned long count;
 
-	count = len / 4;
-	insl(fifoaddr, buf, count);
+	if (r8a66597->pdata->on_chip) {
+		count = len / 4;
+		insl(fifoaddr, buf, count);
 
-	if (len & 0x00000003) {
-		unsigned long tmp = inl(fifoaddr);
-		memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03);
+		if (len & 0x00000003) {
+			unsigned long tmp = inl(fifoaddr);
+			memcpy((unsigned char *)buf + count * 4, &tmp,
+			       len & 0x03);
+		}
+	} else {
+		len = (len + 1) / 2;
+		insw(fifoaddr, buf, len);
 	}
-#else
-	len = (len + 1) / 2;
-	insw(r8a66597->reg + offset, buf, len);
-#endif
 }
 
 static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
@@ -578,33 +206,33 @@ static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
 				       int len)
 {
 	unsigned long fifoaddr = r8a66597->reg + offset;
-#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597)
 	unsigned long count;
 	unsigned char *pb;
 	int i;
 
-	count = len / 4;
-	outsl(fifoaddr, buf, count);
+	if (r8a66597->pdata->on_chip) {
+		count = len / 4;
+		outsl(fifoaddr, buf, count);
+
+		if (len & 0x00000003) {
+			pb = (unsigned char *)buf + count * 4;
+			for (i = 0; i < (len & 0x00000003); i++) {
+				if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
+					outb(pb[i], fifoaddr + i);
+				else
+					outb(pb[i], fifoaddr + 3 - i);
+			}
+		}
+	} else {
+		int odd = len & 0x0001;
 
-	if (len & 0x00000003) {
-		pb = (unsigned char *)buf + count * 4;
-		for (i = 0; i < (len & 0x00000003); i++) {
-			if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
-				outb(pb[i], fifoaddr + i);
-			else
-				outb(pb[i], fifoaddr + 3 - i);
+		len = len / 2;
+		outsw(fifoaddr, buf, len);
+		if (unlikely(odd)) {
+			buf = &buf[len];
+			outb((unsigned char)*buf, fifoaddr);
 		}
 	}
-#else
-	int odd = len & 0x0001;
-
-	len = len / 2;
-	outsw(fifoaddr, buf, len);
-	if (unlikely(odd)) {
-		buf = &buf[len];
-		outb((unsigned char)*buf, fifoaddr);
-	}
-#endif
 }
 
 static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 274751b..5cd0e48 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -67,7 +67,7 @@ MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");
  * debug = 0, no debugging messages
  * debug = 1, dump failed URBs except for stalls
  * debug = 2, dump all failed URBs (including stalls)
- *            show all queues in /debug/uhci/[pci_addr]
+ *            show all queues in /sys/kernel/debug/uhci/[pci_addr]
  * debug = 3, show all TDs in URBs when dumping
  */
 #ifdef DEBUG
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 90e1a8d..e75bb87 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -727,7 +727,7 @@ static const struct file_operations iowarrior_fops = {
 	.poll = iowarrior_poll,
 };
 
-static char *iowarrior_nodename(struct device *dev)
+static char *iowarrior_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
 }
@@ -738,7 +738,7 @@ static char *iowarrior_nodename(struct device *dev)
  */
 static struct usb_class_driver iowarrior_class = {
 	.name = "iowarrior%d",
-	.nodename = iowarrior_nodename,
+	.devnode = iowarrior_devnode,
 	.fops = &iowarrior_fops,
 	.minor_base = IOWARRIOR_MINOR_BASE,
 };
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index c1e2433..97efeae 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -266,7 +266,7 @@ static const struct file_operations tower_fops = {
 	.llseek =	tower_llseek,
 };
 
-static char *legousbtower_nodename(struct device *dev)
+static char *legousbtower_devnode(struct device *dev, mode_t *mode)
 {
 	return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
 }
@@ -277,7 +277,7 @@ static char *legousbtower_nodename(struct device *dev)
  */
 static struct usb_class_driver tower_class = {
 	.name =		"legousbtower%d",
-	.nodename = 	legousbtower_nodename,
+	.devnode = 	legousbtower_devnode,
 	.fops =		&tower_fops,
 	.minor_base =	LEGO_USB_TOWER_MINOR_BASE,
 };
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index c7c1ca0..1d26bed 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2167,8 +2167,9 @@ static int __devexit musb_remove(struct platform_device *pdev)
 
 #ifdef	CONFIG_PM
 
-static int musb_suspend(struct platform_device *pdev, pm_message_t message)
+static int musb_suspend(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	unsigned long	flags;
 	struct musb	*musb = dev_to_musb(&pdev->dev);
 
@@ -2195,8 +2196,9 @@ static int musb_suspend(struct platform_device *pdev, pm_message_t message)
 	return 0;
 }
 
-static int musb_resume_early(struct platform_device *pdev)
+static int musb_resume_noirq(struct device *dev)
 {
+	struct platform_device *pdev = to_platform_device(dev);
 	struct musb	*musb = dev_to_musb(&pdev->dev);
 
 	if (!musb->clock)
@@ -2214,9 +2216,14 @@ static int musb_resume_early(struct platform_device *pdev)
 	return 0;
 }
 
+static struct dev_pm_ops musb_dev_pm_ops = {
+	.suspend	= musb_suspend,
+	.resume_noirq	= musb_resume_noirq,
+};
+
+#define MUSB_DEV_PM_OPS (&musb_dev_pm_ops)
 #else
-#define	musb_suspend	NULL
-#define	musb_resume_early	NULL
+#define	MUSB_DEV_PM_OPS	NULL
 #endif
 
 static struct platform_driver musb_driver = {
@@ -2224,11 +2231,10 @@ static struct platform_driver musb_driver = {
 		.name		= (char *)musb_driver_name,
 		.bus		= &platform_bus_type,
 		.owner		= THIS_MODULE,
+		.pm		= MUSB_DEV_PM_OPS,
 	},
 	.remove		= __devexit_p(musb_remove),
 	.shutdown	= musb_shutdown,
-	.suspend	= musb_suspend,
-	.resume_early	= musb_resume_early,
 };
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index aec6188..5d25d3e 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -35,11 +35,6 @@ static struct usb_device_id id_table [] = {
 };
 MODULE_DEVICE_TABLE(usb, id_table);
 
-struct ark3116_private {
-	spinlock_t lock;
-	u8 termios_initialized;
-};
-
 static inline void ARK3116_SND(struct usb_serial *serial, int seq,
 			       __u8 request, __u8 requesttype,
 			       __u16 value, __u16 index)
@@ -82,22 +77,11 @@ static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
 static int ark3116_attach(struct usb_serial *serial)
 {
 	char *buf;
-	struct ark3116_private *priv;
-	int i;
-
-	for (i = 0; i < serial->num_ports; ++i) {
-		priv = kzalloc(sizeof(struct ark3116_private), GFP_KERNEL);
-		if (!priv)
-			goto cleanup;
-		spin_lock_init(&priv->lock);
-
-		usb_set_serial_port_data(serial->port[i], priv);
-	}
 
 	buf = kmalloc(1, GFP_KERNEL);
 	if (!buf) {
 		dbg("error kmalloc -> out of mem?");
-		goto cleanup;
+		return -ENOMEM;
 	}
 
 	/* 3 */
@@ -149,13 +133,16 @@ static int ark3116_attach(struct usb_serial *serial)
 
 	kfree(buf);
 	return 0;
+}
 
-cleanup:
-	for (--i; i >= 0; --i) {
-		kfree(usb_get_serial_port_data(serial->port[i]));
-		usb_set_serial_port_data(serial->port[i], NULL);
-	}
-	return -ENOMEM;
+static void ark3116_init_termios(struct tty_struct *tty)
+{
+	struct ktermios *termios = tty->termios;
+	*termios = tty_std_termios;
+	termios->c_cflag = B9600 | CS8
+				      | CREAD | HUPCL | CLOCAL;
+	termios->c_ispeed = 9600;
+	termios->c_ospeed = 9600;
 }
 
 static void ark3116_set_termios(struct tty_struct *tty,
@@ -163,10 +150,8 @@ static void ark3116_set_termios(struct tty_struct *tty,
 				struct ktermios *old_termios)
 {
 	struct usb_serial *serial = port->serial;
-	struct ark3116_private *priv = usb_get_serial_port_data(port);
 	struct ktermios *termios = tty->termios;
 	unsigned int cflag = termios->c_cflag;
-	unsigned long flags;
 	int baud;
 	int ark3116_baud;
 	char *buf;
@@ -176,16 +161,6 @@ static void ark3116_set_termios(struct tty_struct *tty,
 
 	dbg("%s - port %d", __func__, port->number);
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (!priv->termios_initialized) {
-		*termios = tty_std_termios;
-		termios->c_cflag = B9600 | CS8
-					      | CREAD | HUPCL | CLOCAL;
-		termios->c_ispeed = 9600;
-		termios->c_ospeed = 9600;
-		priv->termios_initialized = 1;
-	}
-	spin_unlock_irqrestore(&priv->lock, flags);
 
 	cflag = termios->c_cflag;
 	termios->c_cflag &= ~(CMSPAR|CRTSCTS);
@@ -318,8 +293,7 @@ static void ark3116_set_termios(struct tty_struct *tty,
 	return;
 }
 
-static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port,
-					struct file *filp)
+static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
@@ -334,7 +308,7 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port,
 		return -ENOMEM;
 	}
 
-	result = usb_serial_generic_open(tty, port, filp);
+	result = usb_serial_generic_open(tty, port);
 	if (result)
 		goto err_out;
 
@@ -455,6 +429,7 @@ static struct usb_serial_driver ark3116_device = {
 	.num_ports =		1,
 	.attach =		ark3116_attach,
 	.set_termios =		ark3116_set_termios,
+	.init_termios =		ark3116_init_termios,
 	.ioctl =		ark3116_ioctl,
 	.tiocmget =		ark3116_tiocmget,
 	.open =			ark3116_open,
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 7033b03..a0467bc 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -92,7 +92,7 @@ static int debug;
 static int  belkin_sa_startup(struct usb_serial *serial);
 static void belkin_sa_release(struct usb_serial *serial);
 static int  belkin_sa_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+			struct usb_serial_port *port);
 static void belkin_sa_close(struct usb_serial_port *port);
 static void belkin_sa_read_int_callback(struct urb *urb);
 static void belkin_sa_set_termios(struct tty_struct *tty,
@@ -213,7 +213,7 @@ static void belkin_sa_release(struct usb_serial *serial)
 
 
 static int  belkin_sa_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+					struct usb_serial_port *port)
 {
 	int retval = 0;
 
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 2830766..8c894a7 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -300,8 +300,7 @@ static void ch341_close(struct usb_serial_port *port)
 
 
 /* open this device, set default parameters */
-static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
-				struct file *filp)
+static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
@@ -333,7 +332,7 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port,
 		return -EPROTO;
 	}
 
-	r = usb_serial_generic_open(tty, port, filp);
+	r = usb_serial_generic_open(tty, port);
 
 out:	return r;
 }
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 0e4f2e4..b22ac32 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/serial.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -63,7 +64,7 @@ static int usb_console_setup(struct console *co, char *options)
 	char *s;
 	struct usb_serial *serial;
 	struct usb_serial_port *port;
-	int retval = 0;
+	int retval;
 	struct tty_struct *tty = NULL;
 	struct ktermios *termios = NULL, dummy;
 
@@ -116,13 +117,17 @@ static int usb_console_setup(struct console *co, char *options)
 		return -ENODEV;
 	}
 
-	port = serial->port[0];
+	retval = usb_autopm_get_interface(serial->interface);
+	if (retval)
+		goto error_get_interface;
+
+	port = serial->port[co->index - serial->minor];
 	tty_port_tty_set(&port->port, NULL);
 
 	info->port = port;
 
 	++port->port.count;
-	if (port->port.count == 1) {
+	if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
 		if (serial->type->set_termios) {
 			/*
 			 * allocate a fake tty so the driver can initialize
@@ -150,9 +155,9 @@ static int usb_console_setup(struct console *co, char *options)
 		/* only call the device specific open if this
 		 * is the first time the port is opened */
 		if (serial->type->open)
-			retval = serial->type->open(NULL, port, NULL);
+			retval = serial->type->open(NULL, port);
 		else
-			retval = usb_serial_generic_open(NULL, port, NULL);
+			retval = usb_serial_generic_open(NULL, port);
 
 		if (retval) {
 			err("could not open USB console port");
@@ -168,6 +173,7 @@ static int usb_console_setup(struct console *co, char *options)
 			kfree(termios);
 			kfree(tty);
 		}
+		set_bit(ASYNCB_INITIALIZED, &port->port.flags);
 	}
 	/* Now that any required fake tty operations are completed restore
 	 * the tty port count */
@@ -175,18 +181,22 @@ static int usb_console_setup(struct console *co, char *options)
 	/* The console is special in terms of closing the device so
 	 * indicate this port is now acting as a system console. */
 	port->console = 1;
-	retval = 0;
 
-out:
+	mutex_unlock(&serial->disc_mutex);
 	return retval;
-free_termios:
+
+ free_termios:
 	kfree(termios);
 	tty_port_tty_set(&port->port, NULL);
-free_tty:
+ free_tty:
 	kfree(tty);
-reset_open_count:
+ reset_open_count:
 	port->port.count = 0;
-	goto out;
+	usb_autopm_put_interface(serial->interface);
+ error_get_interface:
+	usb_serial_put(serial);
+	mutex_unlock(&serial->disc_mutex);
+	return retval;
 }
 
 static void usb_console_write(struct console *co,
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 985cbcf..4a208fe 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -33,8 +33,7 @@
 /*
  * Function Prototypes
  */
-static int cp210x_open(struct tty_struct *, struct usb_serial_port *,
-							struct file *);
+static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
 static void cp210x_cleanup(struct usb_serial_port *);
 static void cp210x_close(struct usb_serial_port *);
 static void cp210x_get_termios(struct tty_struct *,
@@ -368,8 +367,7 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
 	return baud;
 }
 
-static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port,
-				struct file *filp)
+static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	int result;
@@ -399,12 +397,6 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port,
 
 	/* Configure the termios structure */
 	cp210x_get_termios(tty, port);
-
-	/* Set the DTR and RTS pins low */
-	cp210x_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data
-			: port,
-		NULL, TIOCM_DTR | TIOCM_RTS, 0);
-
 	return 0;
 }
 
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 336523f..b0f6402 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -61,7 +61,7 @@ static int cyberjack_startup(struct usb_serial *serial);
 static void cyberjack_disconnect(struct usb_serial *serial);
 static void cyberjack_release(struct usb_serial *serial);
 static int  cyberjack_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+	struct usb_serial_port *port);
 static void cyberjack_close(struct usb_serial_port *port);
 static int cyberjack_write(struct tty_struct *tty,
 	struct usb_serial_port *port, const unsigned char *buf, int count);
@@ -173,7 +173,7 @@ static void cyberjack_release(struct usb_serial *serial)
 }
 
 static int  cyberjack_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+					struct usb_serial_port *port)
 {
 	struct cyberjack_private *priv;
 	unsigned long flags;
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 59adfe1..e0a8b71 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -172,8 +172,7 @@ static int  cypress_earthmate_startup(struct usb_serial *serial);
 static int  cypress_hidcom_startup(struct usb_serial *serial);
 static int  cypress_ca42v2_startup(struct usb_serial *serial);
 static void cypress_release(struct usb_serial *serial);
-static int  cypress_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+static int  cypress_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void cypress_close(struct usb_serial_port *port);
 static void cypress_dtr_rts(struct usb_serial_port *port, int on);
 static int  cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -633,8 +632,7 @@ static void cypress_release(struct usb_serial *serial)
 }
 
 
-static int cypress_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct cypress_private *priv = usb_get_serial_port_data(port);
 	struct usb_serial *serial = port->serial;
@@ -659,15 +657,7 @@ static int cypress_open(struct tty_struct *tty,
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* Set termios */
-	result = cypress_write(tty, port, NULL, 0);
-
-	if (result) {
-		dev_err(&port->dev,
-			"%s - failed setting the control lines - error %d\n",
-							__func__, result);
-		return result;
-	} else
-		dbg("%s - success setting the control lines", __func__);
+	cypress_send(port);
 
 	if (tty)
 		cypress_set_termios(tty, port, &priv->tmp_termios);
@@ -1005,6 +995,8 @@ static void cypress_set_termios(struct tty_struct *tty,
 	dbg("%s - port %d", __func__, port->number);
 
 	spin_lock_irqsave(&priv->lock, flags);
+	/* We can't clean this one up as we don't know the device type
+	   early enough */
 	if (!priv->termios_initialized) {
 		if (priv->chiptype == CT_EARTHMATE) {
 			*(tty->termios) = tty_std_termios;
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index f480809..ab3dd99 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -453,8 +453,7 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
 static void digi_write_bulk_callback(struct urb *urb);
 static int digi_write_room(struct tty_struct *tty);
 static int digi_chars_in_buffer(struct tty_struct *tty);
-static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
-	struct file *filp);
+static int digi_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void digi_close(struct usb_serial_port *port);
 static int digi_carrier_raised(struct usb_serial_port *port);
 static void digi_dtr_rts(struct usb_serial_port *port, int on);
@@ -1347,8 +1346,7 @@ static int digi_carrier_raised(struct usb_serial_port *port)
 	return 0;
 }
 
-static int digi_open(struct tty_struct *tty, struct usb_serial_port *port,
-				struct file *filp)
+static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int ret;
 	unsigned char buf[32];
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 80cb347..33c9e9c 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -79,8 +79,7 @@ static int debug;
 #define EMPEG_PRODUCT_ID		0x0001
 
 /* function prototypes for an empeg-car player */
-static int  empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
-						struct file *filp);
+static int  empeg_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void empeg_close(struct usb_serial_port *port);
 static int  empeg_write(struct tty_struct *tty, struct usb_serial_port *port,
 						const unsigned char *buf,
@@ -90,8 +89,7 @@ static int  empeg_chars_in_buffer(struct tty_struct *tty);
 static void empeg_throttle(struct tty_struct *tty);
 static void empeg_unthrottle(struct tty_struct *tty);
 static int  empeg_startup(struct usb_serial *serial);
-static void empeg_set_termios(struct tty_struct *tty,
-		struct usb_serial_port *port, struct ktermios *old_termios);
+static void empeg_init_termios(struct tty_struct *tty);
 static void empeg_write_bulk_callback(struct urb *urb);
 static void empeg_read_bulk_callback(struct urb *urb);
 
@@ -123,7 +121,7 @@ static struct usb_serial_driver empeg_device = {
 	.throttle =		empeg_throttle,
 	.unthrottle =		empeg_unthrottle,
 	.attach =		empeg_startup,
-	.set_termios =		empeg_set_termios,
+	.init_termios =		empeg_init_termios,
 	.write =		empeg_write,
 	.write_room =		empeg_write_room,
 	.chars_in_buffer =	empeg_chars_in_buffer,
@@ -142,17 +140,13 @@ static int		bytes_out;
 /******************************************************************************
  * Empeg specific driver functions
  ******************************************************************************/
-static int empeg_open(struct tty_struct *tty, struct usb_serial_port *port,
-				struct file *filp)
+static int empeg_open(struct tty_struct *tty,struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	int result = 0;
 
 	dbg("%s - port %d", __func__, port->number);
 
-	/* Force default termio settings */
-	empeg_set_termios(tty, port, NULL) ;
-
 	bytes_in = 0;
 	bytes_out = 0;
 
@@ -425,11 +419,9 @@ static int  empeg_startup(struct usb_serial *serial)
 }
 
 
-static void empeg_set_termios(struct tty_struct *tty,
-		struct usb_serial_port *port, struct ktermios *old_termios)
+static void empeg_init_termios(struct tty_struct *tty)
 {
 	struct ktermios *termios = tty->termios;
-	dbg("%s - port %d", __func__, port->number);
 
 	/*
 	 * The empeg-car player wants these particular tty settings.
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 8fec5d4..76a17f9 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -747,8 +747,7 @@ static int  ftdi_sio_probe(struct usb_serial *serial,
 					const struct usb_device_id *id);
 static int  ftdi_sio_port_probe(struct usb_serial_port *port);
 static int  ftdi_sio_port_remove(struct usb_serial_port *port);
-static int  ftdi_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+static int  ftdi_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void ftdi_close(struct usb_serial_port *port);
 static void ftdi_dtr_rts(struct usb_serial_port *port, int on);
 static int  ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -1680,8 +1679,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
 	return 0;
 }
 
-static int ftdi_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
 { /* ftdi_open */
 	struct usb_device *dev = port->serial->dev;
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 8839f1c..20432d3 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -933,8 +933,7 @@ static int garmin_init_session(struct usb_serial_port *port)
 
 
 
-static int garmin_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int garmin_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	unsigned long flags;
 	int status = 0;
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index ce57f6a..d9398e9 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -114,8 +114,7 @@ void usb_serial_generic_deregister(void)
 #endif
 }
 
-int usb_serial_generic_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	int result = 0;
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 0191693..dc0f832 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -205,8 +205,7 @@ static void edge_bulk_out_data_callback(struct urb *urb);
 static void edge_bulk_out_cmd_callback(struct urb *urb);
 
 /* function prototypes for the usbserial callbacks */
-static int edge_open(struct tty_struct *tty, struct usb_serial_port *port,
-					struct file *filp);
+static int edge_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void edge_close(struct usb_serial_port *port);
 static int edge_write(struct tty_struct *tty, struct usb_serial_port *port,
 					const unsigned char *buf, int count);
@@ -852,8 +851,7 @@ static void edge_bulk_out_cmd_callback(struct urb *urb)
  *	If successful, we return 0
  *	Otherwise we return a negative error number.
  *****************************************************************************/
-static int edge_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
 	struct usb_serial *serial;
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index e8bc42f..d4cc0f7 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -1831,8 +1831,7 @@ static void edge_bulk_out_callback(struct urb *urb)
 	tty_kref_put(tty);
 }
 
-static int edge_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct edgeport_port *edge_port = usb_get_serial_port_data(port);
 	struct edgeport_serial *edge_serial;
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 2545d45..24fcc64 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -75,7 +75,7 @@ static int initial_wait;
 
 /* Function prototypes for an ipaq */
 static int  ipaq_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+			struct usb_serial_port *port);
 static void ipaq_close(struct usb_serial_port *port);
 static int  ipaq_calc_num_ports(struct usb_serial *serial);
 static int  ipaq_startup(struct usb_serial *serial);
@@ -587,7 +587,7 @@ static int		bytes_in;
 static int		bytes_out;
 
 static int ipaq_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+			struct usb_serial_port *port)
 {
 	struct usb_serial	*serial = port->serial;
 	struct ipaq_private	*priv;
@@ -628,11 +628,6 @@ static int ipaq_open(struct tty_struct *tty,
 		priv->free_len += PACKET_SIZE;
 	}
 
-	if (tty) {
-		/* FIXME: These two are bogus */
-		tty->raw = 1;
-		tty->real_raw = 1;
-	}
 	/*
 	 * Lose the small buffers usbserial provides. Make larger ones.
 	 */
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 29ad038..727d323 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -193,8 +193,7 @@ static void ipw_read_bulk_callback(struct urb *urb)
 	return;
 }
 
-static int ipw_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_device *dev = port->serial->dev;
 	u8 buf_flow_static[16] = IPW_BYTES_FLOWINIT;
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 66009b6..95d8d26 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -86,8 +86,7 @@ static int buffer_size;
 static int xbof = -1;
 
 static int  ir_startup (struct usb_serial *serial);
-static int  ir_open(struct tty_struct *tty, struct usb_serial_port *port,
-					struct file *filep);
+static int  ir_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void ir_close(struct usb_serial_port *port);
 static int  ir_write(struct tty_struct *tty, struct usb_serial_port *port,
 					const unsigned char *buf, int count);
@@ -296,8 +295,7 @@ static int ir_startup(struct usb_serial *serial)
 	return 0;
 }
 
-static int ir_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int ir_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	char *buffer;
 	int result = 0;
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 96873a7..6138c1c 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -71,7 +71,6 @@ struct iuu_private {
 	spinlock_t lock;	/* store irq state */
 	wait_queue_head_t delta_msr_wait;
 	u8 line_status;
-	u8 termios_initialized;
 	int tiostatus;		/* store IUART SIGNAL for tiocmget call */
 	u8 reset;		/* if 1 reset is needed */
 	int poll;		/* number of poll */
@@ -1018,14 +1017,24 @@ static void iuu_close(struct usb_serial_port *port)
 	}
 }
 
-static int iuu_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static void iuu_init_termios(struct tty_struct *tty)
+{
+	*(tty->termios) = tty_std_termios;
+	tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
+				| TIOCM_CTS | CSTOPB | PARENB;
+	tty->termios->c_ispeed = 9600;
+	tty->termios->c_ospeed = 9600;
+	tty->termios->c_lflag = 0;
+	tty->termios->c_oflag = 0;
+	tty->termios->c_iflag = 0;
+}
+
+static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	u8 *buf;
 	int result;
 	u32 actual;
-	unsigned long flags;
 	struct iuu_private *priv = usb_get_serial_port_data(port);
 
 	dbg("%s -  port %d", __func__, port->number);
@@ -1064,21 +1073,7 @@ static int iuu_open(struct tty_struct *tty,
 			  port->bulk_in_buffer, 512,
 			  NULL, NULL);
 
-	/* set the termios structure */
-	spin_lock_irqsave(&priv->lock, flags);
-	if (tty && !priv->termios_initialized) {
-		*(tty->termios) = tty_std_termios;
-		tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
-					| TIOCM_CTS | CSTOPB | PARENB;
-		tty->termios->c_ispeed = 9600;
-		tty->termios->c_ospeed = 9600;
-		tty->termios->c_lflag = 0;
-		tty->termios->c_oflag = 0;
-		tty->termios->c_iflag = 0;
-		priv->termios_initialized = 1;
-		priv->poll = 0;
-	 }
-	spin_unlock_irqrestore(&priv->lock, flags);
+	priv->poll = 0;
 
 	/* initialize writebuf */
 #define FISH(a, b, c, d) do { \
@@ -1201,6 +1196,7 @@ static struct usb_serial_driver iuu_device = {
 	.tiocmget = iuu_tiocmget,
 	.tiocmset = iuu_tiocmset,
 	.set_termios = iuu_set_termios,
+	.init_termios = iuu_init_termios,
 	.attach = iuu_startup,
 	.release = iuu_release,
 };
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 2594b87..f8c4b07 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1209,8 +1209,7 @@ static int keyspan_write_room(struct tty_struct *tty)
 }
 
 
-static int keyspan_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct keyspan_port_private 	*p_priv;
 	struct keyspan_serial_private 	*s_priv;
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 3107ed1..30771e5 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -36,8 +36,7 @@
 
 /* Function prototypes for Keyspan serial converter */
 static int  keyspan_open		(struct tty_struct *tty,
-					 struct usb_serial_port *port,
-					 struct file *filp);
+					 struct usb_serial_port *port);
 static void keyspan_close		(struct usb_serial_port *port);
 static void keyspan_dtr_rts		(struct usb_serial_port *port, int on);
 static int  keyspan_startup		(struct usb_serial *serial);
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index d0b12e4..257c16c 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -681,7 +681,7 @@ static int keyspan_pda_carrier_raised(struct usb_serial_port *port)
 
 
 static int keyspan_pda_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+					struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	unsigned char room;
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 0f44bb8..a616731 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -75,8 +75,7 @@ static int debug;
 static int  klsi_105_startup(struct usb_serial *serial);
 static void klsi_105_disconnect(struct usb_serial *serial);
 static void klsi_105_release(struct usb_serial *serial);
-static int  klsi_105_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void klsi_105_close(struct usb_serial_port *port);
 static int  klsi_105_write(struct tty_struct *tty,
 	struct usb_serial_port *port, const unsigned char *buf, int count);
@@ -358,8 +357,7 @@ static void klsi_105_release(struct usb_serial *serial)
 	}
 } /* klsi_105_release */
 
-static int  klsi_105_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct klsi_105_private *priv = usb_get_serial_port_data(port);
 	int retval = 0;
@@ -371,10 +369,6 @@ static int  klsi_105_open(struct tty_struct *tty,
 
 	dbg("%s port %d", __func__, port->number);
 
-	/* force low_latency on so that our tty_push actually forces
-	 * the data through
-	 * tty->low_latency = 1; */
-
 	/* Do a defined restart:
 	 * Set up sane default baud rate and send the 'READ_ON'
 	 * vendor command.
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 6db0e56..45ea694 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -70,8 +70,7 @@ static int debug;
 /* Function prototypes */
 static int  kobil_startup(struct usb_serial *serial);
 static void kobil_release(struct usb_serial *serial);
-static int  kobil_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+static int  kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void kobil_close(struct usb_serial_port *port);
 static int  kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
 			 const unsigned char *buf, int count);
@@ -85,7 +84,7 @@ static void kobil_read_int_callback(struct urb *urb);
 static void kobil_write_callback(struct urb *purb);
 static void kobil_set_termios(struct tty_struct *tty,
 			struct usb_serial_port *port, struct ktermios *old);
-
+static void kobil_init_termios(struct tty_struct *tty);
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(KOBIL_VENDOR_ID, KOBIL_ADAPTER_B_PRODUCT_ID) },
@@ -120,6 +119,7 @@ static struct usb_serial_driver kobil_device = {
 	.release =		kobil_release,
 	.ioctl =		kobil_ioctl,
 	.set_termios =		kobil_set_termios,
+	.init_termios =		kobil_init_termios,
 	.tiocmget =		kobil_tiocmget,
 	.tiocmset =		kobil_tiocmset,
 	.open =			kobil_open,
@@ -210,9 +210,17 @@ static void kobil_release(struct usb_serial *serial)
 		kfree(usb_get_serial_port_data(serial->port[i]));
 }
 
+static void kobil_init_termios(struct tty_struct *tty)
+{
+	/* Default to echo off and other sane device settings */
+	tty->termios->c_lflag = 0;
+	tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
+	tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
+	/* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
+	tty->termios->c_oflag &= ~ONLCR;
+}
 
-static int kobil_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int result = 0;
 	struct kobil_private *priv;
@@ -226,16 +234,6 @@ static int kobil_open(struct tty_struct *tty,
 	/* someone sets the dev to 0 if the close method has been called */
 	port->interrupt_in_urb->dev = port->serial->dev;
 
-	if (tty) {
-
-		/* Default to echo off and other sane device settings */
-		tty->termios->c_lflag = 0;
-		tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN |
-								 XCASE);
-		tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
-		/* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
-		tty->termios->c_oflag &= ~ONLCR;
-	}
 	/* allocate memory for transfer buffer */
 	transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
 	if (!transfer_buffer)
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index d8825e1..ad4998b 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -93,8 +93,7 @@ static int debug;
  */
 static int  mct_u232_startup(struct usb_serial *serial);
 static void mct_u232_release(struct usb_serial *serial);
-static int  mct_u232_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void mct_u232_close(struct usb_serial_port *port);
 static void mct_u232_dtr_rts(struct usb_serial_port *port, int on);
 static void mct_u232_read_int_callback(struct urb *urb);
@@ -421,8 +420,7 @@ static void mct_u232_release(struct usb_serial *serial)
 	}
 } /* mct_u232_release */
 
-static int  mct_u232_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	struct mct_u232_private *priv = usb_get_serial_port_data(port);
@@ -568,10 +566,13 @@ static void mct_u232_read_int_callback(struct urb *urb)
 	 * Work-a-round: handle the 'usual' bulk-in pipe here
 	 */
 	if (urb->transfer_buffer_length > 2) {
-		tty = tty_port_tty_get(&port->port);
 		if (urb->actual_length) {
-			tty_insert_flip_string(tty, data, urb->actual_length);
-			tty_flip_buffer_push(tty);
+			tty = tty_port_tty_get(&port->port);
+			if (tty) {
+				tty_insert_flip_string(tty, data,
+						urb->actual_length);
+				tty_flip_buffer_push(tty);
+			}
 			tty_kref_put(tty);
 		}
 		goto exit;
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index ccd4dd3..763e32a 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -85,7 +85,7 @@ static int debug;
 #define MOSCHIP_DEVICE_ID_7720		0x7720
 #define MOSCHIP_DEVICE_ID_7715		0x7715
 
-static struct usb_device_id moschip_port_id_table [] = {
+static struct usb_device_id moschip_port_id_table[] = {
 	{ USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7720) },
 	{ } /* terminating entry */
 };
@@ -319,8 +319,7 @@ static int send_mos_cmd(struct usb_serial *serial, __u8 request, __u16 value,
 	return status;
 }
 
-static int mos7720_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial;
 	struct usb_serial_port *port0;
@@ -378,10 +377,14 @@ static int mos7720_open(struct tty_struct *tty,
 	 /* Initialize MCS7720 -- Write Init values to corresponding Registers
 	  *
 	  * Register Index
+	  * 0 : THR/RHR
 	  * 1 : IER
 	  * 2 : FCR
 	  * 3 : LCR
 	  * 4 : MCR
+	  * 5 : LSR
+	  * 6 : MSR
+	  * 7 : SPR
 	  *
 	  * 0x08 : SP1/2 Control Reg
 	  */
@@ -1250,20 +1253,88 @@ static void mos7720_set_termios(struct tty_struct *tty,
 static int get_lsr_info(struct tty_struct *tty,
 		struct moschip_port *mos7720_port, unsigned int __user *value)
 {
-	int count;
+	struct usb_serial_port *port = tty->driver_data;
 	unsigned int result = 0;
+	unsigned char data = 0;
+	int port_number = port->number - port->serial->minor;
+	int count;
 
 	count = mos7720_chars_in_buffer(tty);
 	if (count == 0) {
-		dbg("%s -- Empty", __func__);
-		result = TIOCSER_TEMT;
+		send_mos_cmd(port->serial, MOS_READ, port_number,
+							UART_LSR, &data);
+		if ((data & (UART_LSR_TEMT | UART_LSR_THRE))
+					== (UART_LSR_TEMT | UART_LSR_THRE)) {
+			dbg("%s -- Empty", __func__);
+			result = TIOCSER_TEMT;
+		}
 	}
-
 	if (copy_to_user(value, &result, sizeof(int)))
 		return -EFAULT;
 	return 0;
 }
 
+static int mos7720_tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
+	unsigned int result = 0;
+	unsigned int mcr ;
+	unsigned int msr ;
+
+	dbg("%s - port %d", __func__, port->number);
+
+	mcr = mos7720_port->shadowMCR;
+	msr = mos7720_port->shadowMSR;
+
+	result = ((mcr & UART_MCR_DTR)  ? TIOCM_DTR : 0)   /* 0x002 */
+	  | ((mcr & UART_MCR_RTS)   ? TIOCM_RTS : 0)   /* 0x004 */
+	  | ((msr & UART_MSR_CTS)   ? TIOCM_CTS : 0)   /* 0x020 */
+	  | ((msr & UART_MSR_DCD)   ? TIOCM_CAR : 0)   /* 0x040 */
+	  | ((msr & UART_MSR_RI)    ? TIOCM_RI :  0)   /* 0x080 */
+	  | ((msr & UART_MSR_DSR)   ? TIOCM_DSR : 0);  /* 0x100 */
+
+	dbg("%s -- %x", __func__, result);
+
+	return result;
+}
+
+static int mos7720_tiocmset(struct tty_struct *tty, struct file *file,
+					unsigned int set, unsigned int clear)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct moschip_port *mos7720_port = usb_get_serial_port_data(port);
+	unsigned int mcr ;
+	unsigned char lmcr;
+
+	dbg("%s - port %d", __func__, port->number);
+	dbg("he was at tiocmget");
+
+	mcr = mos7720_port->shadowMCR;
+
+	if (set & TIOCM_RTS)
+		mcr |= UART_MCR_RTS;
+	if (set & TIOCM_DTR)
+		mcr |= UART_MCR_DTR;
+	if (set & TIOCM_LOOP)
+		mcr |= UART_MCR_LOOP;
+
+	if (clear & TIOCM_RTS)
+		mcr &= ~UART_MCR_RTS;
+	if (clear & TIOCM_DTR)
+		mcr &= ~UART_MCR_DTR;
+	if (clear & TIOCM_LOOP)
+		mcr &= ~UART_MCR_LOOP;
+
+	mos7720_port->shadowMCR = mcr;
+	lmcr = mos7720_port->shadowMCR;
+
+	send_mos_cmd(port->serial, MOS_WRITE,
+		port->number - port->serial->minor, UART_MCR, &lmcr);
+
+	return 0;
+}
+
 static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
 			  unsigned int __user *value)
 {
@@ -1301,14 +1372,6 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
 			mcr &= ~UART_MCR_LOOP;
 		break;
 
-	case TIOCMSET:
-		/* turn off the RTS and DTR and LOOPBACK
-		 * and then only turn on what was asked to */
-		mcr &=  ~(UART_MCR_RTS | UART_MCR_DTR | UART_MCR_LOOP);
-		mcr |= ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0);
-		mcr |= ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0);
-		mcr |= ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0);
-		break;
 	}
 
 	mos7720_port->shadowMCR = mcr;
@@ -1320,28 +1383,6 @@ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
 	return 0;
 }
 
-static int get_modem_info(struct moschip_port *mos7720_port,
-			  unsigned int __user *value)
-{
-	unsigned int result = 0;
-	unsigned int msr = mos7720_port->shadowMSR;
-	unsigned int mcr = mos7720_port->shadowMCR;
-
-	result = ((mcr & UART_MCR_DTR)	? TIOCM_DTR: 0)	  /* 0x002 */
-		  | ((mcr & UART_MCR_RTS)	? TIOCM_RTS: 0)   /* 0x004 */
-		  | ((msr & UART_MSR_CTS)	? TIOCM_CTS: 0)   /* 0x020 */
-		  | ((msr & UART_MSR_DCD)	? TIOCM_CAR: 0)   /* 0x040 */
-		  | ((msr & UART_MSR_RI)	? TIOCM_RI:  0)   /* 0x080 */
-		  | ((msr & UART_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 moschip_port *mos7720_port,
 			   struct serial_struct __user *retinfo)
 {
@@ -1392,17 +1433,11 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
 	/* FIXME: These should be using the mode methods */
 	case TIOCMBIS:
 	case TIOCMBIC:
-	case TIOCMSET:
 		dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET",
 					__func__, port->number);
 		return set_modem_info(mos7720_port, cmd,
 				      (unsigned int __user *)arg);
 
-	case TIOCMGET:
-		dbg("%s (%d) TIOCMGET", __func__,  port->number);
-		return get_modem_info(mos7720_port,
-				      (unsigned int __user *)arg);
-
 	case TIOCGSERIAL:
 		dbg("%s (%d) TIOCGSERIAL", __func__,  port->number);
 		return get_serial_info(mos7720_port,
@@ -1557,6 +1592,8 @@ static struct usb_serial_driver moschip7720_2port_driver = {
 	.attach			= mos7720_startup,
 	.release		= mos7720_release,
 	.ioctl			= mos7720_ioctl,
+	.tiocmget		= mos7720_tiocmget,
+	.tiocmset		= mos7720_tiocmset,
 	.set_termios		= mos7720_set_termios,
 	.write			= mos7720_write,
 	.write_room		= mos7720_write_room,
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 270009a..f11abf5 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -824,8 +824,7 @@ static int mos7840_serial_probe(struct usb_serial *serial,
  *	Otherwise we return a negative error number.
  *****************************************************************************/
 
-static int mos7840_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int mos7840_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int response;
 	int j;
@@ -2134,106 +2133,6 @@ static int mos7840_get_lsr_info(struct tty_struct *tty,
 }
 
 /*****************************************************************************
- * mos7840_set_modem_info
- *      function to set modem info
- *****************************************************************************/
-
-/* FIXME: Should be using the model control hooks */
-
-static int mos7840_set_modem_info(struct moschip_port *mos7840_port,
-				  unsigned int cmd, unsigned int __user *value)
-{
-	unsigned int mcr;
-	unsigned int arg;
-	__u16 Data;
-	int status;
-	struct usb_serial_port *port;
-
-	if (mos7840_port == NULL)
-		return -1;
-
-	port = (struct usb_serial_port *)mos7840_port->port;
-	if (mos7840_port_paranoia_check(port, __func__)) {
-		dbg("%s", "Invalid port");
-		return -1;
-	}
-
-	mcr = mos7840_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;
-	}
-
-	lock_kernel();
-	mos7840_port->shadowMCR = mcr;
-
-	Data = mos7840_port->shadowMCR;
-	status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
-	unlock_kernel();
-	if (status < 0) {
-		dbg("setting MODEM_CONTROL_REGISTER Failed");
-		return -1;
-	}
-
-	return 0;
-}
-
-/*****************************************************************************
- * mos7840_get_modem_info
- *      function to get modem info
- *****************************************************************************/
-
-static int mos7840_get_modem_info(struct moschip_port *mos7840_port,
-				  unsigned int __user *value)
-{
-	unsigned int result = 0;
-	__u16 msr;
-	unsigned int mcr = mos7840_port->shadowMCR;
-        mos7840_get_uart_reg(mos7840_port->port,
-						MODEM_STATUS_REGISTER, &msr);
-	result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)	/* 0x002 */
-	    |((mcr & MCR_RTS) ? TIOCM_RTS : 0)	/* 0x004 */
-	    |((msr & MOS7840_MSR_CTS) ? TIOCM_CTS : 0)	/* 0x020 */
-	    |((msr & MOS7840_MSR_CD) ? TIOCM_CAR : 0)	/* 0x040 */
-	    |((msr & MOS7840_MSR_RI) ? TIOCM_RI : 0)	/* 0x080 */
-	    |((msr & MOS7840_MSR_DSR) ? TIOCM_DSR : 0);	/* 0x100 */
-
-	dbg("%s -- %x", __func__, result);
-
-	if (copy_to_user(value, &result, sizeof(int)))
-		return -EFAULT;
-	return 0;
-}
-
-/*****************************************************************************
  * mos7840_get_serial_info
  *      function to get information about serial port
  *****************************************************************************/
@@ -2281,7 +2180,6 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
 	struct async_icount cnow;
 	struct async_icount cprev;
 	struct serial_icounter_struct icount;
-	int mosret = 0;
 
 	if (mos7840_port_paranoia_check(port, __func__)) {
 		dbg("%s", "Invalid port");
@@ -2303,20 +2201,6 @@ static int mos7840_ioctl(struct tty_struct *tty, struct file *file,
 		return mos7840_get_lsr_info(tty, argp);
 		return 0;
 
-	/* FIXME: use the modem hooks and remove this */
-	case TIOCMBIS:
-	case TIOCMBIC:
-	case TIOCMSET:
-		dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__,
-		    port->number);
-		mosret =
-		    mos7840_set_modem_info(mos7840_port, cmd, argp);
-		return mosret;
-
-	case TIOCMGET:
-		dbg("%s (%d) TIOCMGET", __func__, port->number);
-		return mos7840_get_modem_info(mos7840_port, argp);
-
 	case TIOCGSERIAL:
 		dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
 		return mos7840_get_serial_info(mos7840_port, argp);
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index f5f3751..5ceaa4c 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -80,8 +80,7 @@ exit:
 			__func__, result);
 }
 
-static int navman_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int navman_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int result = 0;
 
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 56857dd..0622650 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -64,8 +64,7 @@ static int debug;
 #define BT_IGNITIONPRO_ID	0x2000
 
 /* function prototypes */
-static int  omninet_open(struct tty_struct *tty, struct usb_serial_port *port,
-							struct file *filp);
+static int  omninet_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void omninet_close(struct usb_serial_port *port);
 static void omninet_read_bulk_callback(struct urb *urb);
 static void omninet_write_bulk_callback(struct urb *urb);
@@ -163,8 +162,7 @@ static int omninet_attach(struct usb_serial *serial)
 	return 0;
 }
 
-static int omninet_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial	*serial = port->serial;
 	struct usb_serial_port	*wport;
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 336bba7..1085a57 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -144,8 +144,7 @@ exit:
 	spin_unlock(&priv->lock);
 }
 
-static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port,
-			struct file *filp)
+static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct opticon_private *priv = usb_get_serial_data(port->serial);
 	unsigned long flags;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index c784ddb..fe47051 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -45,8 +45,7 @@
 /* Function prototypes */
 static int  option_probe(struct usb_serial *serial,
 			const struct usb_device_id *id);
-static int  option_open(struct tty_struct *tty, struct usb_serial_port *port,
-							struct file *filp);
+static int  option_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void option_close(struct usb_serial_port *port);
 static void option_dtr_rts(struct usb_serial_port *port, int on);
 
@@ -961,8 +960,7 @@ static int option_chars_in_buffer(struct tty_struct *tty)
 	return data_len;
 }
 
-static int option_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int option_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct option_port_private *portdata;
 	int i, err;
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 3cece27..0f4a70c 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -141,11 +141,11 @@ struct oti6858_control_pkt {
 	  && ((a)->frame_fmt == (priv)->pending_setup.frame_fmt))
 
 /* function prototypes */
-static int oti6858_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void oti6858_close(struct usb_serial_port *port);
 static void oti6858_set_termios(struct tty_struct *tty,
 			struct usb_serial_port *port, struct ktermios *old);
+static void oti6858_init_termios(struct tty_struct *tty);
 static int oti6858_ioctl(struct tty_struct *tty, struct file *file,
 			unsigned int cmd, unsigned long arg);
 static void oti6858_read_int_callback(struct urb *urb);
@@ -186,6 +186,7 @@ static struct usb_serial_driver oti6858_device = {
 	.write =		oti6858_write,
 	.ioctl =		oti6858_ioctl,
 	.set_termios =		oti6858_set_termios,
+	.init_termios = 	oti6858_init_termios,
 	.tiocmget =		oti6858_tiocmget,
 	.tiocmset =		oti6858_tiocmset,
 	.read_bulk_callback =	oti6858_read_bulk_callback,
@@ -206,7 +207,6 @@ struct oti6858_private {
 	struct {
 		u8 read_urb_in_use;
 		u8 write_urb_in_use;
-		u8 termios_initialized;
 	} flags;
 	struct delayed_work delayed_write_work;
 
@@ -447,6 +447,14 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty)
 	return chars;
 }
 
+static void oti6858_init_termios(struct tty_struct *tty)
+{
+	*(tty->termios) = tty_std_termios;
+	tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+	tty->termios->c_ispeed = 38400;
+	tty->termios->c_ospeed = 38400;
+}
+
 static void oti6858_set_termios(struct tty_struct *tty,
 		struct usb_serial_port *port, struct ktermios *old_termios)
 {
@@ -464,16 +472,6 @@ static void oti6858_set_termios(struct tty_struct *tty,
 		return;
 	}
 
-	spin_lock_irqsave(&priv->lock, flags);
-	if (!priv->flags.termios_initialized) {
-		*(tty->termios) = tty_std_termios;
-		tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
-		tty->termios->c_ispeed = 38400;
-		tty->termios->c_ospeed = 38400;
-		priv->flags.termios_initialized = 1;
-	}
-	spin_unlock_irqrestore(&priv->lock, flags);
-
 	cflag = tty->termios->c_cflag;
 
 	spin_lock_irqsave(&priv->lock, flags);
@@ -566,8 +564,7 @@ static void oti6858_set_termios(struct tty_struct *tty,
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static int oti6858_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct oti6858_private *priv = usb_get_serial_port_data(port);
 	struct ktermios tmp_termios;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 3e86815..a63ea99 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -691,8 +691,7 @@ static void pl2303_close(struct usb_serial_port *port)
 
 }
 
-static int pl2303_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
@@ -714,8 +713,6 @@ static int pl2303_open(struct tty_struct *tty,
 	if (tty)
 		pl2303_set_termios(tty, port, &tmp_termios);
 
-	/* FIXME: need to assert RTS and DTR if CRTSCTS off */
-
 	dbg("%s - submitting read urb", __func__);
 	port->read_urb->dev = serial->dev;
 	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index f48d05e..55391bb 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -734,8 +734,7 @@ static void sierra_close(struct usb_serial_port *port)
 	}
 }
 
-static int sierra_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct sierra_port_private *portdata;
 	struct usb_serial *serial = port->serial;
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 3c249d8..61e7c40 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -299,7 +299,6 @@ struct spcp8x5_private {
 	wait_queue_head_t	delta_msr_wait;
 	u8 			line_control;
 	u8 			line_status;
-	u8 			termios_initialized;
 };
 
 /* desc : when device plug in,this function would be called.
@@ -498,6 +497,15 @@ static void spcp8x5_close(struct usb_serial_port *port)
 		dev_dbg(&port->dev, "usb_unlink_urb(read_urb) = %d\n", result);
 }
 
+static void spcp8x5_init_termios(struct tty_struct *tty)
+{
+	/* for the 1st time call this function */
+	*(tty->termios) = tty_std_termios;
+	tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+	tty->termios->c_ispeed = 115200;
+	tty->termios->c_ospeed = 115200;
+}
+
 /* set the serial param for transfer. we should check if we really need to
  * transfer. if we set flow control we should do this too. */
 static void spcp8x5_set_termios(struct tty_struct *tty,
@@ -514,16 +522,6 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
 	int i;
 	u8 control;
 
-	/* for the 1st time call this function */
-	spin_lock_irqsave(&priv->lock, flags);
-	if (!priv->termios_initialized) {
-		*(tty->termios) = tty_std_termios;
-		tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
-		tty->termios->c_ispeed = 115200;
-		tty->termios->c_ospeed = 115200;
-		priv->termios_initialized = 1;
-	}
-	spin_unlock_irqrestore(&priv->lock, flags);
 
 	/* check that they really want us to change something */
 	if (!tty_termios_hw_change(tty->termios, old_termios))
@@ -623,8 +621,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
 
 /* open the serial port. do some usb system call. set termios and get the line
  * status of the device. then submit the read urb */
-static int spcp8x5_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int spcp8x5_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct ktermios tmp_termios;
 	struct usb_serial *serial = port->serial;
@@ -658,8 +655,6 @@ static int spcp8x5_open(struct tty_struct *tty,
 	priv->line_status = status & 0xf0 ;
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* FIXME: need to assert RTS and DTR if CRTSCTS off */
-
 	dbg("%s - submitting read urb", __func__);
 	port->read_urb->dev = serial->dev;
 	ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
@@ -1011,6 +1006,7 @@ static struct usb_serial_driver spcp8x5_device = {
 	.carrier_raised		= spcp8x5_carrier_raised,
 	.write 			= spcp8x5_write,
 	.set_termios 		= spcp8x5_set_termios,
+	.init_termios		= spcp8x5_init_termios,
 	.ioctl 			= spcp8x5_ioctl,
 	.tiocmget 		= spcp8x5_tiocmget,
 	.tiocmset 		= spcp8x5_tiocmset,
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 6157fac..cb7e95f 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -124,8 +124,7 @@ exit:
 	spin_unlock(&priv->lock);
 }
 
-static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port,
-			struct file *filp)
+static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct symbol_private *priv = usb_get_serial_data(port->serial);
 	unsigned long flags;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 3bc609f..1e9dc88 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -98,8 +98,7 @@ struct ti_device {
 
 static int ti_startup(struct usb_serial *serial);
 static void ti_release(struct usb_serial *serial);
-static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
-		struct file *file);
+static int ti_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void ti_close(struct usb_serial_port *port);
 static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
 		const unsigned char *data, int count);
@@ -492,8 +491,7 @@ static void ti_release(struct usb_serial *serial)
 }
 
 
-static int ti_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *file)
+static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct ti_port *tport = usb_get_serial_port_data(port);
 	struct ti_device *tdev;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 99188c9..9d7ca48 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -43,8 +43,6 @@
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
 #define DRIVER_DESC "USB Serial Driver core"
 
-static void port_free(struct usb_serial_port *port);
-
 /* Driver structure we register with the USB core */
 static struct usb_driver usb_serial_driver = {
 	.name =		"usbserial",
@@ -68,6 +66,11 @@ static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
 static DEFINE_MUTEX(table_lock);
 static LIST_HEAD(usb_serial_driver_list);
 
+/*
+ * Look up the serial structure.  If it is found and it hasn't been
+ * disconnected, return with its disc_mutex held and its refcount
+ * incremented.  Otherwise return NULL.
+ */
 struct usb_serial *usb_serial_get_by_index(unsigned index)
 {
 	struct usb_serial *serial;
@@ -75,8 +78,15 @@ struct usb_serial *usb_serial_get_by_index(unsigned index)
 	mutex_lock(&table_lock);
 	serial = serial_table[index];
 
-	if (serial)
-		kref_get(&serial->kref);
+	if (serial) {
+		mutex_lock(&serial->disc_mutex);
+		if (serial->disconnected) {
+			mutex_unlock(&serial->disc_mutex);
+			serial = NULL;
+		} else {
+			kref_get(&serial->kref);
+		}
+	}
 	mutex_unlock(&table_lock);
 	return serial;
 }
@@ -125,8 +135,10 @@ static void return_serial(struct usb_serial *serial)
 
 	dbg("%s", __func__);
 
+	mutex_lock(&table_lock);
 	for (i = 0; i < serial->num_ports; ++i)
 		serial_table[serial->minor + i] = NULL;
+	mutex_unlock(&table_lock);
 }
 
 static void destroy_serial(struct kref *kref)
@@ -145,161 +157,157 @@ static void destroy_serial(struct kref *kref)
 
 	serial->type->release(serial);
 
-	for (i = 0; i < serial->num_ports; ++i) {
+	/* Now that nothing is using the ports, they can be freed */
+	for (i = 0; i < serial->num_port_pointers; ++i) {
 		port = serial->port[i];
-		if (port)
+		if (port) {
+			port->serial = NULL;
 			put_device(&port->dev);
-	}
-
-	/* If this is a "fake" port, we have to clean it up here, as it will
-	 * not get cleaned up in port_release() as it was never registered with
-	 * the driver core */
-	if (serial->num_ports < serial->num_port_pointers) {
-		for (i = serial->num_ports;
-					i < serial->num_port_pointers; ++i) {
-			port = serial->port[i];
-			if (port)
-				port_free(port);
 		}
 	}
 
 	usb_put_dev(serial->dev);
-
-	/* free up any memory that we allocated */
 	kfree(serial);
 }
 
 void usb_serial_put(struct usb_serial *serial)
 {
-	mutex_lock(&table_lock);
 	kref_put(&serial->kref, destroy_serial);
-	mutex_unlock(&table_lock);
 }
 
 /*****************************************************************************
  * Driver tty interface functions
  *****************************************************************************/
-static int serial_open (struct tty_struct *tty, struct file *filp)
+
+/**
+ * serial_install - install tty
+ * @driver: the driver (USB in our case)
+ * @tty: the tty being created
+ *
+ * Create the termios objects for this tty.  We use the default
+ * USB serial settings but permit them to be overridden by
+ * serial->type->init_termios.
+ *
+ * This is the first place a new tty gets used.  Hence this is where we
+ * acquire references to the usb_serial structure and the driver module,
+ * where we store a pointer to the port, and where we do an autoresume.
+ * All these actions are reversed in serial_release().
+ */
+static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
 {
+	int idx = tty->index;
 	struct usb_serial *serial;
 	struct usb_serial_port *port;
-	unsigned int portNumber;
-	int retval = 0;
-	int first = 0;
+	int retval = -ENODEV;
 
 	dbg("%s", __func__);
 
-	/* get the serial object associated with this tty pointer */
-	serial = usb_serial_get_by_index(tty->index);
-	if (!serial) {
-		tty->driver_data = NULL;
-		return -ENODEV;
-	}
+	serial = usb_serial_get_by_index(idx);
+	if (!serial)
+		return retval;
 
-	mutex_lock(&serial->disc_mutex);
-	portNumber = tty->index - serial->minor;
-	port = serial->port[portNumber];
-	if (!port || serial->disconnected)
-		retval = -ENODEV;
-	else
-		get_device(&port->dev);
-	/*
-	 * Note: Our locking order requirement does not allow port->mutex
-	 * to be acquired while serial->disc_mutex is held.
-	 */
-	mutex_unlock(&serial->disc_mutex);
+	port = serial->port[idx - serial->minor];
+	if (!port)
+		goto error_no_port;
+	if (!try_module_get(serial->type->driver.owner))
+		goto error_module_get;
+
+	/* perform the standard setup */
+	retval = tty_init_termios(tty);
 	if (retval)
-		goto bailout_serial_put;
+		goto error_init_termios;
 
-	if (mutex_lock_interruptible(&port->mutex)) {
-		retval = -ERESTARTSYS;
-		goto bailout_port_put;
-	}
+	retval = usb_autopm_get_interface(serial->interface);
+	if (retval)
+		goto error_get_interface;
+
+	mutex_unlock(&serial->disc_mutex);
 
-	++port->port.count;
+	/* allow the driver to update the settings */
+	if (serial->type->init_termios)
+		serial->type->init_termios(tty);
 
-	/* set up our port structure making the tty driver
-	 * remember our port object, and us it */
 	tty->driver_data = port;
-	tty_port_tty_set(&port->port, tty);
 
-	/* If the console is attached, the device is already open */
-	if (port->port.count == 1 && !port->console) {
-		first = 1;
-		/* lock this module before we call it
-		 * this may fail, which means we must bail out,
-		 * safe because we are called with BKL held */
-		if (!try_module_get(serial->type->driver.owner)) {
-			retval = -ENODEV;
-			goto bailout_mutex_unlock;
-		}
+	/* Final install (we use the default method) */
+	tty_driver_kref_get(driver);
+	tty->count++;
+	driver->ttys[idx] = tty;
+	return retval;
 
+ error_get_interface:
+ error_init_termios:
+	module_put(serial->type->driver.owner);
+ error_module_get:
+ error_no_port:
+	usb_serial_put(serial);
+	mutex_unlock(&serial->disc_mutex);
+	return retval;
+}
+
+static int serial_open(struct tty_struct *tty, struct file *filp)
+{
+	struct usb_serial_port *port = tty->driver_data;
+	struct usb_serial *serial = port->serial;
+	int retval;
+
+	dbg("%s - port %d", __func__, port->number);
+
+	spin_lock_irq(&port->port.lock);
+	if (!tty_hung_up_p(filp))
+		++port->port.count;
+	spin_unlock_irq(&port->port.lock);
+	tty_port_tty_set(&port->port, tty);
+
+	/* Do the device-specific open only if the hardware isn't
+	 * already initialized.
+	 */
+	if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags)) {
+		if (mutex_lock_interruptible(&port->mutex))
+			return -ERESTARTSYS;
 		mutex_lock(&serial->disc_mutex);
 		if (serial->disconnected)
 			retval = -ENODEV;
 		else
-			retval = usb_autopm_get_interface(serial->interface);
-		if (retval)
-			goto bailout_module_put;
-
-		/* only call the device specific open if this
-		 * is the first time the port is opened */
-		retval = serial->type->open(tty, port, filp);
-		if (retval)
-			goto bailout_interface_put;
+			retval = port->serial->type->open(tty, port);
 		mutex_unlock(&serial->disc_mutex);
+		mutex_unlock(&port->mutex);
+		if (retval)
+			return retval;
 		set_bit(ASYNCB_INITIALIZED, &port->port.flags);
 	}
-	mutex_unlock(&port->mutex);
+
 	/* Now do the correct tty layer semantics */
 	retval = tty_port_block_til_ready(&port->port, tty, filp);
-	if (retval == 0) {
-		if (!first)
-			usb_serial_put(serial);
-		return 0;
-	}
-	mutex_lock(&port->mutex);
-	if (first == 0)
-		goto bailout_mutex_unlock;
-	/* Undo the initial port actions */
-	mutex_lock(&serial->disc_mutex);
-bailout_interface_put:
-	usb_autopm_put_interface(serial->interface);
-bailout_module_put:
-	mutex_unlock(&serial->disc_mutex);
-	module_put(serial->type->driver.owner);
-bailout_mutex_unlock:
-	port->port.count = 0;
-	tty->driver_data = NULL;
-	tty_port_tty_set(&port->port, NULL);
-	mutex_unlock(&port->mutex);
-bailout_port_put:
-	put_device(&port->dev);
-bailout_serial_put:
-	usb_serial_put(serial);
 	return retval;
 }
 
 /**
- *	serial_do_down		-	shut down hardware
- *	@port: port to shut down
- *
- *	Shut down a USB port unless it is the console. We never shut down the
- *	console hardware as it will always be in use.
+ * serial_down - shut down hardware
+ * @port: port to shut down
  *
- *	Don't free any resources at this point
+ * Shut down a USB serial port unless it is the console.  We never
+ * shut down the console hardware as it will always be in use.
  */
-static void serial_do_down(struct usb_serial_port *port)
+static void serial_down(struct usb_serial_port *port)
 {
 	struct usb_serial_driver *drv = port->serial->type;
 	struct usb_serial *serial;
 	struct module *owner;
 
-	/* The console is magical, do not hang up the console hardware
-	   or there will be tears */
+	/*
+	 * The console is magical.  Do not hang up the console hardware
+	 * or there will be tears.
+	 */
 	if (port->console)
 		return;
 
+	/* Don't call the close method if the hardware hasn't been
+	 * initialized.
+	 */
+	if (!test_and_clear_bit(ASYNCB_INITIALIZED, &port->port.flags))
+		return;
+
 	mutex_lock(&port->mutex);
 	serial = port->serial;
 	owner = serial->type->driver.owner;
@@ -310,79 +318,69 @@ static void serial_do_down(struct usb_serial_port *port)
 	mutex_unlock(&port->mutex);
 }
 
-/**
- *	serial_do_free		-	free resources post close/hangup
- *	@port: port to free up
- *
- *	Do the resource freeing and refcount dropping for the port. We must
- *	be careful about ordering and we must avoid freeing up the console.
- */
-
-static void serial_do_free(struct usb_serial_port *port)
+static void serial_hangup(struct tty_struct *tty)
 {
-	struct usb_serial *serial;
-	struct module *owner;
+	struct usb_serial_port *port = tty->driver_data;
 
-	/* The console is magical, do not hang up the console hardware
-	   or there will be tears */
-	if (port->console)
-		return;
+	dbg("%s - port %d", __func__, port->number);
 
-	serial = port->serial;
-	owner = serial->type->driver.owner;
-	put_device(&port->dev);
-	/* Mustn't dereference port any more */
-	mutex_lock(&serial->disc_mutex);
-	if (!serial->disconnected)
-		usb_autopm_put_interface(serial->interface);
-	mutex_unlock(&serial->disc_mutex);
-	usb_serial_put(serial);
-	/* Mustn't dereference serial any more */
-	module_put(owner);
+	serial_down(port);
+	tty_port_hangup(&port->port);
 }
 
 static void serial_close(struct tty_struct *tty, struct file *filp)
 {
 	struct usb_serial_port *port = tty->driver_data;
 
-	if (!port)
-		return;
-
 	dbg("%s - port %d", __func__, port->number);
 
-	/* FIXME:
-	   This leaves a very narrow race. Really we should do the
-	   serial_do_free() on tty->shutdown(), but tty->shutdown can
-	   be called from IRQ context and serial_do_free can sleep.
-
-	   The right fix is probably to make the tty free (which is rare)
-	   and thus tty->shutdown() occur via a work queue and simplify all
-	   the drivers that use it.
-	*/
-	if (tty_hung_up_p(filp)) {
-		/* serial_hangup already called serial_down at this point.
-		   Another user may have already reopened the port but
-		   serial_do_free is refcounted */
-		serial_do_free(port);
+	if (tty_hung_up_p(filp))
 		return;
-	}
-
 	if (tty_port_close_start(&port->port, tty, filp) == 0)
 		return;
-
-	serial_do_down(port);		
+	serial_down(port);
 	tty_port_close_end(&port->port, tty);
 	tty_port_tty_set(&port->port, NULL);
-	serial_do_free(port);
 }
 
-static void serial_hangup(struct tty_struct *tty)
+/**
+ * serial_release - free resources post close/hangup
+ * @port: port to free up
+ *
+ * Do the resource freeing and refcount dropping for the port.
+ * Avoid freeing the console.
+ *
+ * Called when the last tty kref is dropped.
+ */
+static void serial_release(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
-	serial_do_down(port);
-	tty_port_hangup(&port->port);
-	/* We must not free port yet - the USB serial layer depends on it's
-	   continued existence */
+	struct usb_serial *serial;
+	struct module *owner;
+
+	/* The console is magical.  Do not hang up the console hardware
+	 * or there will be tears.
+	 */
+	if (port->console)
+		return;
+
+	dbg("%s - port %d", __func__, port->number);
+
+	/* Standard shutdown processing */
+	tty_shutdown(tty);
+
+	tty->driver_data = NULL;
+
+	serial = port->serial;
+	owner = serial->type->driver.owner;
+
+	mutex_lock(&serial->disc_mutex);
+	if (!serial->disconnected)
+		usb_autopm_put_interface(serial->interface);
+	mutex_unlock(&serial->disc_mutex);
+
+	usb_serial_put(serial);
+	module_put(owner);
 }
 
 static int serial_write(struct tty_struct *tty, const unsigned char *buf,
@@ -527,6 +525,7 @@ static int serial_proc_show(struct seq_file *m, void *v)
 
 		seq_putc(m, '\n');
 		usb_serial_put(serial);
+		mutex_unlock(&serial->disc_mutex);
 	}
 	return 0;
 }
@@ -596,14 +595,6 @@ static void usb_serial_port_work(struct work_struct *work)
 	tty_kref_put(tty);
 }
 
-static void port_release(struct device *dev)
-{
-	struct usb_serial_port *port = to_usb_serial_port(dev);
-
-	dbg ("%s - %s", __func__, dev_name(dev));
-	port_free(port);
-}
-
 static void kill_traffic(struct usb_serial_port *port)
 {
 	usb_kill_urb(port->read_urb);
@@ -623,8 +614,12 @@ static void kill_traffic(struct usb_serial_port *port)
 	usb_kill_urb(port->interrupt_out_urb);
 }
 
-static void port_free(struct usb_serial_port *port)
+static void port_release(struct device *dev)
 {
+	struct usb_serial_port *port = to_usb_serial_port(dev);
+
+	dbg ("%s - %s", __func__, dev_name(dev));
+
 	/*
 	 * Stop all the traffic before cancelling the work, so that
 	 * nobody will restart it by calling usb_serial_port_softint.
@@ -935,6 +930,11 @@ int usb_serial_probe(struct usb_interface *interface,
 		mutex_init(&port->mutex);
 		INIT_WORK(&port->work, usb_serial_port_work);
 		serial->port[i] = port;
+		port->dev.parent = &interface->dev;
+		port->dev.driver = NULL;
+		port->dev.bus = &usb_serial_bus_type;
+		port->dev.release = &port_release;
+		device_initialize(&port->dev);
 	}
 
 	/* set up the endpoint information */
@@ -1077,15 +1077,10 @@ int usb_serial_probe(struct usb_interface *interface,
 	/* register all of the individual ports with the driver core */
 	for (i = 0; i < num_ports; ++i) {
 		port = serial->port[i];
-		port->dev.parent = &interface->dev;
-		port->dev.driver = NULL;
-		port->dev.bus = &usb_serial_bus_type;
-		port->dev.release = &port_release;
-
 		dev_set_name(&port->dev, "ttyUSB%d", port->number);
 		dbg ("%s - registering %s", __func__, dev_name(&port->dev));
 		port->dev_state = PORT_REGISTERING;
-		retval = device_register(&port->dev);
+		retval = device_add(&port->dev);
 		if (retval) {
 			dev_err(&port->dev, "Error registering port device, "
 				"continuing\n");
@@ -1103,39 +1098,7 @@ exit:
 	return 0;
 
 probe_error:
-	for (i = 0; i < num_bulk_in; ++i) {
-		port = serial->port[i];
-		if (!port)
-			continue;
-		usb_free_urb(port->read_urb);
-		kfree(port->bulk_in_buffer);
-	}
-	for (i = 0; i < num_bulk_out; ++i) {
-		port = serial->port[i];
-		if (!port)
-			continue;
-		usb_free_urb(port->write_urb);
-		kfree(port->bulk_out_buffer);
-	}
-	for (i = 0; i < num_interrupt_in; ++i) {
-		port = serial->port[i];
-		if (!port)
-			continue;
-		usb_free_urb(port->interrupt_in_urb);
-		kfree(port->interrupt_in_buffer);
-	}
-	for (i = 0; i < num_interrupt_out; ++i) {
-		port = serial->port[i];
-		if (!port)
-			continue;
-		usb_free_urb(port->interrupt_out_urb);
-		kfree(port->interrupt_out_buffer);
-	}
-
-	/* free up any memory that we allocated */
-	for (i = 0; i < serial->num_port_pointers; ++i)
-		kfree(serial->port[i]);
-	kfree(serial);
+	usb_serial_put(serial);
 	return -EIO;
 }
 EXPORT_SYMBOL_GPL(usb_serial_probe);
@@ -1161,10 +1124,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
 		if (port) {
 			struct tty_struct *tty = tty_port_tty_get(&port->port);
 			if (tty) {
-				/* The hangup will occur asynchronously but
-				   the object refcounts will sort out all the
-				   cleanup */
-				tty_hangup(tty);
+				tty_vhangup(tty);
 				tty_kref_put(tty);
 			}
 			kill_traffic(port);
@@ -1189,8 +1149,7 @@ void usb_serial_disconnect(struct usb_interface *interface)
 	}
 	serial->type->disconnect(serial);
 
-	/* let the last holder of this object
-	 * cause it to be cleaned up */
+	/* let the last holder of this object cause it to be cleaned up */
 	usb_serial_put(serial);
 	dev_info(dev, "device disconnected\n");
 }
@@ -1246,6 +1205,8 @@ static const struct tty_operations serial_ops = {
 	.chars_in_buffer =	serial_chars_in_buffer,
 	.tiocmget =		serial_tiocmget,
 	.tiocmset =		serial_tiocmset,
+	.shutdown = 		serial_release,
+	.install = 		serial_install,
 	.proc_fops =		&serial_proc_fops,
 };
 
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index 6148009..7b5bfc4 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -43,11 +43,10 @@ static struct usb_driver debug_driver = {
 	.no_dynamic_id = 	1,
 };
 
-static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port,
-							struct file *filp)
+static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE;
-	return usb_serial_generic_open(tty, port, filp);
+	return usb_serial_generic_open(tty, port);
 }
 
 /* This HW really does not support a serial break, so one will be
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index f5d0f64..1aa5d20 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -36,8 +36,7 @@
 #define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"
 
 /* function prototypes for a handspring visor */
-static int  visor_open(struct tty_struct *tty, struct usb_serial_port *port,
-					struct file *filp);
+static int  visor_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void visor_close(struct usb_serial_port *port);
 static int  visor_write(struct tty_struct *tty, struct usb_serial_port *port,
 					const unsigned char *buf, int count);
@@ -273,8 +272,7 @@ static int stats;
 /******************************************************************************
  * Handspring Visor specific driver functions
  ******************************************************************************/
-static int visor_open(struct tty_struct *tty, struct usb_serial_port *port,
-							struct file *filp)
+static int visor_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	struct visor_private *priv = usb_get_serial_port_data(port);
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 8d126dd..62424ee 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -146,7 +146,7 @@ static int  whiteheat_firmware_attach(struct usb_serial *serial);
 static int  whiteheat_attach(struct usb_serial *serial);
 static void whiteheat_release(struct usb_serial *serial);
 static int  whiteheat_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+			struct usb_serial_port *port);
 static void whiteheat_close(struct usb_serial_port *port);
 static int  whiteheat_write(struct tty_struct *tty,
 			struct usb_serial_port *port,
@@ -259,7 +259,7 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command,
 						__u8 *data, __u8 datasize);
 static int firm_open(struct usb_serial_port *port);
 static int firm_close(struct usb_serial_port *port);
-static int firm_setup_port(struct tty_struct *tty);
+static void firm_setup_port(struct tty_struct *tty);
 static int firm_set_rts(struct usb_serial_port *port, __u8 onoff);
 static int firm_set_dtr(struct usb_serial_port *port, __u8 onoff);
 static int firm_set_break(struct usb_serial_port *port, __u8 onoff);
@@ -659,8 +659,7 @@ static void whiteheat_release(struct usb_serial *serial)
 	return;
 }
 
-static int whiteheat_open(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp)
+static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
 	int		retval = 0;
 
@@ -1211,7 +1210,7 @@ static int firm_close(struct usb_serial_port *port)
 }
 
 
-static int firm_setup_port(struct tty_struct *tty)
+static void firm_setup_port(struct tty_struct *tty)
 {
 	struct usb_serial_port *port = tty->driver_data;
 	struct whiteheat_port_settings port_settings;
@@ -1286,7 +1285,7 @@ static int firm_setup_port(struct tty_struct *tty)
 	port_settings.lloop = 0;
 
 	/* now send the message to the device */
-	return firm_send_command(port, WHITEHEAT_SETUP_PORT,
+	firm_send_command(port, WHITEHEAT_SETUP_PORT,
 			(__u8 *)&port_settings, sizeof(port_settings));
 }
 
diff --git a/drivers/uwb/hwa-rc.c b/drivers/uwb/hwa-rc.c
index 9052bcb..e7eeb63 100644
--- a/drivers/uwb/hwa-rc.c
+++ b/drivers/uwb/hwa-rc.c
@@ -887,8 +887,7 @@ static int hwarc_post_reset(struct usb_interface *iface)
 	struct hwarc *hwarc = usb_get_intfdata(iface);
 	struct uwb_rc *uwb_rc = hwarc->uwb_rc;
 
-	uwb_rc_post_reset(uwb_rc);
-	return 0;
+	return uwb_rc_post_reset(uwb_rc);
 }
 
 /** USB device ID's that we handle */
diff --git a/drivers/uwb/i1480/i1480u-wlp/i1480u-wlp.h b/drivers/uwb/i1480/i1480u-wlp/i1480u-wlp.h
index 3421d33..2e31f53 100644
--- a/drivers/uwb/i1480/i1480u-wlp/i1480u-wlp.h
+++ b/drivers/uwb/i1480/i1480u-wlp/i1480u-wlp.h
@@ -267,7 +267,8 @@ extern void i1480u_sysfs_release(struct i1480u *);
 /* netdev interface */
 extern int i1480u_open(struct net_device *);
 extern int i1480u_stop(struct net_device *);
-extern int i1480u_hard_start_xmit(struct sk_buff *, struct net_device *);
+extern netdev_tx_t i1480u_hard_start_xmit(struct sk_buff *,
+						struct net_device *);
 extern void i1480u_tx_timeout(struct net_device *);
 extern int i1480u_set_config(struct net_device *, struct ifmap *);
 extern int i1480u_change_mtu(struct net_device *, int);
diff --git a/drivers/uwb/i1480/i1480u-wlp/tx.c b/drivers/uwb/i1480/i1480u-wlp/tx.c
index 26bacc0..3db3449 100644
--- a/drivers/uwb/i1480/i1480u-wlp/tx.c
+++ b/drivers/uwb/i1480/i1480u-wlp/tx.c
@@ -503,7 +503,8 @@ out:
  *
  * @net_dev->xmit_lock is held
  */
-int i1480u_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
+netdev_tx_t i1480u_hard_start_xmit(struct sk_buff *skb,
+					 struct net_device *net_dev)
 {
 	int result;
 	struct i1480u *i1480u = netdev_priv(net_dev);
diff --git a/drivers/uwb/lc-dev.c b/drivers/uwb/lc-dev.c
index e9fe1bb..1097e81 100644
--- a/drivers/uwb/lc-dev.c
+++ b/drivers/uwb/lc-dev.c
@@ -255,7 +255,7 @@ static struct attribute_group dev_attr_group = {
 	.attrs = dev_attrs,
 };
 
-static struct attribute_group *groups[] = {
+static const struct attribute_group *groups[] = {
 	&dev_attr_group,
 	NULL,
 };
diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c
index 9cf21e6..9611ef3 100644
--- a/drivers/uwb/lc-rc.c
+++ b/drivers/uwb/lc-rc.c
@@ -288,8 +288,8 @@ error_sys_add:
 error_dev_add:
 error_rc_setup:
 	rc->stop(rc);
-	uwbd_stop(rc);
 error_rc_start:
+	uwbd_stop(rc);
 	return result;
 }
 EXPORT_SYMBOL_GPL(uwb_rc_add);
diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c
index 70f8050..7f0512e 100644
--- a/drivers/uwb/reset.c
+++ b/drivers/uwb/reset.c
@@ -30,6 +30,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 
 #include "uwb-internal.h"
 
@@ -323,13 +324,15 @@ int uwbd_msg_handle_reset(struct uwb_event *evt)
 
 	dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
 	ret = rc->reset(rc);
-	if (ret) {
+	if (ret < 0) {
 		dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);
 		goto error;
 	}
 	return 0;
 error:
-	/* Nothing can be done except try the reset again. */
+	/* Nothing can be done except try the reset again. Wait a bit
+	   to avoid reset loops during probe() or remove(). */
+	msleep(1000);
 	uwb_rc_reset_all(rc);
 	return ret;
 }
@@ -368,22 +371,20 @@ void uwb_rc_pre_reset(struct uwb_rc *rc)
 }
 EXPORT_SYMBOL_GPL(uwb_rc_pre_reset);
 
-void uwb_rc_post_reset(struct uwb_rc *rc)
+int uwb_rc_post_reset(struct uwb_rc *rc)
 {
 	int ret;
 
 	ret = rc->start(rc);
 	if (ret)
-		goto error;
+		goto out;
 	ret = uwb_rc_mac_addr_set(rc, &rc->uwb_dev.mac_addr);
 	if (ret)
-		goto error;
+		goto out;
 	ret = uwb_rc_dev_addr_set(rc, &rc->uwb_dev.dev_addr);
 	if (ret)
-		goto error;
-	return;
-error:
-	/* Nothing can be done except try the reset again. */
-	uwb_rc_reset_all(rc);
+		goto out;
+out:
+	return ret;
 }
 EXPORT_SYMBOL_GPL(uwb_rc_post_reset);
diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c
index 5ad3616..cdd6c8e 100644
--- a/drivers/uwb/umc-bus.c
+++ b/drivers/uwb/umc-bus.c
@@ -66,7 +66,7 @@ int umc_controller_reset(struct umc_dev *umc)
 		return -EAGAIN;
 	ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
 	if (ret >= 0)
-		device_for_each_child(parent, parent, umc_bus_post_reset_helper);
+		ret = device_for_each_child(parent, parent, umc_bus_post_reset_helper);
 	up(&parent->sem);
 
 	return ret;
diff --git a/drivers/uwb/uwbd.c b/drivers/uwb/uwbd.c
index 57bd6bf..5a777d8 100644
--- a/drivers/uwb/uwbd.c
+++ b/drivers/uwb/uwbd.c
@@ -187,12 +187,12 @@ int uwbd_event_handle_urc(struct uwb_event *evt)
 	event = le16_to_cpu(evt->notif.rceb->wEvent);
 	context = evt->notif.rceb->bEventContext;
 
-	if (type > ARRAY_SIZE(uwbd_urc_evt_type_handlers))
+	if (type >= ARRAY_SIZE(uwbd_urc_evt_type_handlers))
 		goto out;
 	type_table = &uwbd_urc_evt_type_handlers[type];
 	if (type_table->uwbd_events == NULL)
 		goto out;
-	if (event > type_table->size)
+	if (event >= type_table->size)
 		goto out;
 	handler = type_table->uwbd_events[event].handler;
 	if (handler == NULL)
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c
index 19a1dd1..1d9a6f5 100644
--- a/drivers/uwb/whc-rc.c
+++ b/drivers/uwb/whc-rc.c
@@ -443,8 +443,7 @@ static int whcrc_post_reset(struct umc_dev *umc)
 	struct whcrc *whcrc = umc_get_drvdata(umc);
 	struct uwb_rc *uwb_rc = whcrc->uwb_rc;
 
-	uwb_rc_post_reset(uwb_rc);
-	return 0;
+	return uwb_rc_post_reset(uwb_rc);
 }
 
 /* PCI device ID's that we handle [so it gets loaded] */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3b54b39..11af4cb 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -7,6 +7,8 @@ menu "Graphics support"
 
 source "drivers/char/agp/Kconfig"
 
+source "drivers/gpu/vga/Kconfig"
+
 source "drivers/gpu/drm/Kconfig"
 
 config VGASTATE
@@ -935,7 +937,7 @@ config FB_S1D13XXX
 
 config FB_ATMEL
 	tristate "AT91/AT32 LCD Controller support"
-	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32)
+	depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9G10 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
@@ -951,7 +953,7 @@ config FB_INTSRAM
 
 config FB_ATMEL_STN
 	bool "Use a STN display with AT91/AT32 LCD Controller"
-	depends on FB_ATMEL && MACH_AT91SAM9261EK
+	depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
 	default n
 	help
 	  Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
@@ -1867,7 +1869,7 @@ config FB_W100
 
 config FB_SH_MOBILE_LCDC
 	tristate "SuperH Mobile LCDC framebuffer support"
-	depends on FB && SUPERH
+	depends on FB && SUPERH && HAVE_CLK
 	select FB_SYS_FILLRECT
 	select FB_SYS_COPYAREA
 	select FB_SYS_IMAGEBLIT
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index da05f08..2830ffd 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -182,7 +182,8 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
 {
 	unsigned long value;
 
-	if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000()))
+	if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10()
+		|| cpu_is_at32ap7000()))
 		return xres;
 
 	value = xres;
@@ -824,7 +825,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 	info->fix = atmel_lcdfb_fix;
 
 	/* Enable LCDC Clocks */
-	if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) {
+	if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()
+	 || cpu_is_at32ap7000()) {
 		sinfo->bus_clk = clk_get(dev, "hck1");
 		if (IS_ERR(sinfo->bus_clk)) {
 			ret = PTR_ERR(sinfo->bus_clk);
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index f9d19be..90861cd 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -110,7 +110,7 @@ config BACKLIGHT_CLASS_DEVICE
 config BACKLIGHT_ATMEL_LCDC
 	bool "Atmel LCDC Contrast-as-Backlight control"
 	depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL
-	default y if MACH_SAM9261EK || MACH_SAM9263EK
+	default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK
 	help
 	  This provides a backlight control internal to the Atmel LCDC
 	  driver.  If the LCD "contrast control" on your board is wired
diff --git a/drivers/video/console/.gitignore b/drivers/video/console/.gitignore
deleted file mode 100644
index 0c258b4..0000000
--- a/drivers/video/console/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# conmakehash generated file
-promcon_tbl.c
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 2f50a80..fc7d9bb 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -67,16 +67,9 @@ config SGI_NEWPORT_CONSOLE
 
 #  bool 'IODC console' CONFIG_IODC_CONSOLE
 
-config PROM_CONSOLE
-	bool "PROM console"
-	depends on SPARC
-	help
-	  Say Y to build a console driver for Sun machines that uses the
-	  terminal emulation built into their console PROMS.
-
 config DUMMY_CONSOLE
 	bool
-	depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
+	depends on VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y 
 	default y
 
 config DUMMY_CONSOLE_COLUMNS
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index ac46cc3..a862e91 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -22,7 +22,6 @@ font-objs += $(font-objs-y)
 
 obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
 obj-$(CONFIG_SGI_NEWPORT_CONSOLE) += newport_con.o font.o
-obj-$(CONFIG_PROM_CONSOLE)        += promcon.o promcon_tbl.o
 obj-$(CONFIG_STI_CONSOLE)         += sticon.o sticore.o font.o
 obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
 obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
@@ -40,14 +39,3 @@ obj-$(CONFIG_FB_STI)              += sticore.o font.o
 ifeq ($(CONFIG_USB_SISUSBVGA_CON),y)
 obj-$(CONFIG_USB_SISUSBVGA)           += font.o
 endif
-
-# Targets that kbuild needs to know about
-targets := promcon_tbl.c
-
-quiet_cmd_conmakehash = CNMKHSH $@
-      cmd_conmakehash = scripts/conmakehash $< | \
-		sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \
-		-e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@
-
-$(obj)/promcon_tbl.c: $(src)/prom.uni
-	$(call cmd,conmakehash)
diff --git a/drivers/video/console/prom.uni b/drivers/video/console/prom.uni
deleted file mode 100644
index 58f9c04..0000000
--- a/drivers/video/console/prom.uni
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Unicode mapping table for font in Sun PROM
-# 
-#
-0x20-0x7e	idem
-0xa0-0xff	idem
-#
-0x7c		U+2502
-0x2d		U+2500
-0x2b		U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c
-0xa4		U+fffd
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
deleted file mode 100644
index ae02e4e..0000000
--- a/drivers/video/console/promcon.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/* $Id: promcon.c,v 1.17 2000/07/26 23:02:52 davem Exp $
- * Console driver utilizing PROM sun terminal emulation
- *
- * Copyright (C) 1998  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 1998  Jakub Jelinek  (jj@ultra.linux.cz)
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/console.h>
-#include <linux/vt_kern.h>
-#include <linux/selection.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/kd.h>
-
-#include <asm/oplib.h>
-#include <asm/uaccess.h>
-
-static short pw = 80 - 1, ph = 34 - 1;
-static short px, py;
-static unsigned long promcon_uni_pagedir[2];
-
-extern u8 promfont_unicount[];
-extern u16 promfont_unitable[];
-
-#define PROMCON_COLOR 0
-
-#if PROMCON_COLOR
-#define inverted(s)	((((s) & 0x7700) == 0x0700) ? 0 : 1)
-#else
-#define inverted(s)	(((s) & 0x0800) ? 1 : 0)
-#endif
-
-static __inline__ void
-promcon_puts(char *buf, int cnt)
-{
-	prom_printf("%*.*s", cnt, cnt, buf);
-}
-
-static int
-promcon_start(struct vc_data *conp, char *b)
-{
-	unsigned short *s = (unsigned short *)
-			(conp->vc_origin + py * conp->vc_size_row + (px << 1));
-	u16 cs;
-
-	cs = scr_readw(s);
-	if (px == pw) {
-		unsigned short *t = s - 1;
-		u16 ct = scr_readw(t);
-
-		if (inverted(cs) && inverted(ct))
-			return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs,
-				       ct);
-		else if (inverted(cs))
-			return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs,
-				       ct);
-		else if (inverted(ct))
-			return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs,
-				       ct);
-		else
-			return sprintf(b, "\b%c\b\033[@%c", cs, ct);
-	}
-
-	if (inverted(cs))
-		return sprintf(b, "\033[7m%c\033[m\b", cs);
-	else
-		return sprintf(b, "%c\b", cs);
-}
-
-static int
-promcon_end(struct vc_data *conp, char *b)
-{
-	unsigned short *s = (unsigned short *)
-			(conp->vc_origin + py * conp->vc_size_row + (px << 1));
-	char *p = b;
-	u16 cs;
-
-	b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
-
-	cs = scr_readw(s);
-	if (px == pw) {
-		unsigned short *t = s - 1;
-		u16 ct = scr_readw(t);
-
-		if (inverted(cs) && inverted(ct))
-			b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", cs, ct);
-		else if (inverted(cs))
-			b += sprintf(b, "\b%c\b\033[@%c", cs, ct);
-		else if (inverted(ct))
-			b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", cs, ct);
-		else
-			b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", cs, ct);
-		return b - p;
-	}
-
-	if (inverted(cs))
-		b += sprintf(b, "%c\b", cs);
-	else
-		b += sprintf(b, "\033[7m%c\033[m\b", cs);
-	return b - p;
-}
-
-const char *promcon_startup(void)
-{
-	const char *display_desc = "PROM";
-	int node;
-	char buf[40];
-	
-	node = prom_getchild(prom_root_node);
-	node = prom_searchsiblings(node, "options");
-	if (prom_getproperty(node,  "screen-#columns", buf, 40) != -1) {
-		pw = simple_strtoul(buf, NULL, 0);
-		if (pw < 10 || pw > 256)
-			pw = 80;
-		pw--;
-	}
-	if (prom_getproperty(node,  "screen-#rows", buf, 40) != -1) {
-		ph = simple_strtoul(buf, NULL, 0);
-		if (ph < 10 || ph > 256)
-			ph = 34;
-		ph--;
-	}
-	promcon_puts("\033[H\033[J", 6);
-	return display_desc;
-}
-
-static void
-promcon_init_unimap(struct vc_data *conp)
-{
-	mm_segment_t old_fs = get_fs();
-	struct unipair *p, *p1;
-	u16 *q;
-	int i, j, k;
-	
-	p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);
-	if (!p) return;
-	
-	q = promfont_unitable;
-	p1 = p;
-	k = 0;
-	for (i = 0; i < 256; i++)
-		for (j = promfont_unicount[i]; j; j--) {
-			p1->unicode = *q++;
-			p1->fontpos = i;
-			p1++;
-			k++;
-		}
-	set_fs(KERNEL_DS);
-	con_clear_unimap(conp, NULL);
-	con_set_unimap(conp, k, p);
-	con_protect_unimap(conp, 1);
-	set_fs(old_fs);
-	kfree(p);
-}
-
-static void
-promcon_init(struct vc_data *conp, int init)
-{
-	unsigned long p;
-	
-	conp->vc_can_do_color = PROMCON_COLOR;
-	if (init) {
-		conp->vc_cols = pw + 1;
-		conp->vc_rows = ph + 1;
-	}
-	p = *conp->vc_uni_pagedir_loc;
-	if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||
-	    !--conp->vc_uni_pagedir_loc[1])
-		con_free_unimap(conp);
-	conp->vc_uni_pagedir_loc = promcon_uni_pagedir;
-	promcon_uni_pagedir[1]++;
-	if (!promcon_uni_pagedir[0] && p) {
-		promcon_init_unimap(conp);
-	}
-	if (!init) {
-		if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
-			vc_resize(conp, pw + 1, ph + 1);
-	}
-}
-
-static void
-promcon_deinit(struct vc_data *conp)
-{
-	/* When closing the last console, reset video origin */
-	if (!--promcon_uni_pagedir[1])
-		con_free_unimap(conp);
-	conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;
-	con_set_default_unimap(conp);
-}
-
-static int
-promcon_switch(struct vc_data *conp)
-{
-	return 1;
-}
-
-static unsigned short *
-promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
-{
-	int cnt = pw + 1;
-	int attr = -1;
-	unsigned char *b = *bp;
-
-	while (cnt--) {
-		u16 c = scr_readw(s);
-		if (attr != inverted(c)) {
-			attr = inverted(c);
-			if (attr) {
-				strcpy (b, "\033[7m");
-				b += 4;
-			} else {
-				strcpy (b, "\033[m");
-				b += 3;
-			}
-		}
-		*b++ = c;
-		s++;
-		if (b - buf >= 224) {
-			promcon_puts(buf, b - buf);
-			b = buf;
-		}
-	}
-	*bp = b;
-	return s;
-}
-
-static void
-promcon_putcs(struct vc_data *conp, const unsigned short *s,
-	      int count, int y, int x)
-{
-	unsigned char buf[256], *b = buf;
-	unsigned short attr = scr_readw(s);
-	unsigned char save;
-	int i, last = 0;
-
-	if (console_blanked)
-		return;
-	
-	if (count <= 0)
-		return;
-
-	b += promcon_start(conp, b);
-
-	if (x + count >= pw + 1) {
-		if (count == 1) {
-			x -= 1;
-			save = scr_readw((unsigned short *)(conp->vc_origin
-						   + y * conp->vc_size_row
-						   + (x << 1)));
-
-			if (px != x || py != y) {
-				b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
-				px = x;
-				py = y;
-			}
-
-			if (inverted(attr))
-				b += sprintf(b, "\033[7m%c\033[m", scr_readw(s++));
-			else
-				b += sprintf(b, "%c", scr_readw(s++));
-
-			strcpy(b, "\b\033[@");
-			b += 4;
-
-			if (inverted(save))
-				b += sprintf(b, "\033[7m%c\033[m", save);
-			else
-				b += sprintf(b, "%c", save);
-
-			px++;
-
-			b += promcon_end(conp, b);
-			promcon_puts(buf, b - buf);
-			return;
-		} else {
-			last = 1;
-			count = pw - x - 1;
-		}
-	}
-
-	if (inverted(attr)) {
-		strcpy(b, "\033[7m");
-		b += 4;
-	}
-
-	if (px != x || py != y) {
-		b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
-		px = x;
-		py = y;
-	}
-
-	for (i = 0; i < count; i++) {
-		if (b - buf >= 224) {
-			promcon_puts(buf, b - buf);
-			b = buf;
-		}
-		*b++ = scr_readw(s++);
-	}
-
-	px += count;
-
-	if (last) {
-		save = scr_readw(s++);
-		b += sprintf(b, "%c\b\033[@%c", scr_readw(s++), save);
-		px++;
-	}
-
-	if (inverted(attr)) {
-		strcpy(b, "\033[m");
-		b += 3;
-	}
-
-	b += promcon_end(conp, b);
-	promcon_puts(buf, b - buf);
-}
-
-static void
-promcon_putc(struct vc_data *conp, int c, int y, int x)
-{
-	unsigned short s;
-
-	if (console_blanked)
-		return;
-	
-	scr_writew(c, &s);
-	promcon_putcs(conp, &s, 1, y, x);
-}
-
-static void
-promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
-{
-	unsigned char buf[256], *b = buf;
-	int i, j;
-
-	if (console_blanked)
-		return;
-	
-	b += promcon_start(conp, b);
-
-	if (!sx && width == pw + 1) {
-
-		if (!sy && height == ph + 1) {
-			strcpy(b, "\033[H\033[J");
-			b += 6;
-			b += promcon_end(conp, b);
-			promcon_puts(buf, b - buf);
-			return;
-		} else if (sy + height == ph + 1) {
-			b += sprintf(b, "\033[%dH\033[J", sy + 1);
-			b += promcon_end(conp, b);
-			promcon_puts(buf, b - buf);
-			return;
-		}
-
-		b += sprintf(b, "\033[%dH", sy + 1);
-		for (i = 1; i < height; i++) {
-			strcpy(b, "\033[K\n");
-			b += 4;
-		}
-
-		strcpy(b, "\033[K");
-		b += 3;
-
-		b += promcon_end(conp, b);
-		promcon_puts(buf, b - buf);
-		return;
-
-	} else if (sx + width == pw + 1) {
-
-		b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
-		for (i = 1; i < height; i++) {
-			strcpy(b, "\033[K\n");
-			b += 4;
-		}
-
-		strcpy(b, "\033[K");
-		b += 3;
-
-		b += promcon_end(conp, b);
-		promcon_puts(buf, b - buf);
-		return;
-	}
-
-	for (i = sy + 1; i <= sy + height; i++) {
-		b += sprintf(b, "\033[%d;%dH", i, sx + 1);
-		for (j = 0; j < width; j++)
-			*b++ = ' ';
-		if (b - buf + width >= 224) {
-			promcon_puts(buf, b - buf);
-			b = buf;
-		}
-	}
-
-	b += promcon_end(conp, b);
-	promcon_puts(buf, b - buf);
-}
-                        
-static void
-promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
-	      int height, int width)
-{
-	char buf[256], *b = buf;
-
-	if (console_blanked)
-		return;
-	
-	b += promcon_start(conp, b);
-	if (sy == dy && height == 1) {
-		if (dx > sx && dx + width == conp->vc_cols)
-			b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
-				     sy + 1, sx + 1, dx - sx, py + 1, px + 1);
-		else if (dx < sx && sx + width == conp->vc_cols)
-			b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
-				     dy + 1, dx + 1, sx - dx, py + 1, px + 1);
-
-		b += promcon_end(conp, b);
-		promcon_puts(buf, b - buf);
-		return;
-	}
-
-	/*
-	 * FIXME: What to do here???
-	 * Current console.c should not call it like that ever.
-	 */
-	prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
-}
-
-static void
-promcon_cursor(struct vc_data *conp, int mode)
-{
-	char buf[32], *b = buf;
-
-	switch (mode) {
-	case CM_ERASE:
-		break;
-
-	case CM_MOVE:
-	case CM_DRAW:
-		b += promcon_start(conp, b);
-		if (px != conp->vc_x || py != conp->vc_y) {
-			px = conp->vc_x;
-			py = conp->vc_y;
-			b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
-		}
-		promcon_puts(buf, b - buf);
-		break;
-	}
-}
-
-static int
-promcon_blank(struct vc_data *conp, int blank, int mode_switch)
-{
-	if (blank) {
-		promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
-		return 0;
-	} else {
-		/* Let console.c redraw */
-		return 1;
-	}
-}
-
-static int
-promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
-{
-	unsigned char buf[256], *p = buf;
-	unsigned short *s;
-	int i;
-
-	if (console_blanked)
-		return 0;
-	
-	p += promcon_start(conp, p);
-
-	switch (dir) {
-	case SM_UP:
-		if (b == ph + 1) {
-			p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
-			px = 0;
-			py = t;
-			p += promcon_end(conp, p);
-			promcon_puts(buf, p - buf);
-			break;
-		}
-
-		s = (unsigned short *)(conp->vc_origin
-				       + (t + count) * conp->vc_size_row);
-
-		p += sprintf(p, "\033[%dH", t + 1);
-
-		for (i = t; i < b - count; i++)
-			s = promcon_repaint_line(s, buf, &p);
-
-		for (; i < b - 1; i++) {
-			strcpy(p, "\033[K\n");
-			p += 4;
-			if (p - buf >= 224) {
-				promcon_puts(buf, p - buf);
-				p = buf;
-			}
-		}
-
-		strcpy(p, "\033[K");
-		p += 3;
-
-		p += promcon_end(conp, p);
-		promcon_puts(buf, p - buf);
-		break;
-
-	case SM_DOWN:
-		if (b == ph + 1) {
-			p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
-			px = 0;
-			py = t;
-			p += promcon_end(conp, p);
-			promcon_puts(buf, p - buf);
-			break;
-		}
-
-		s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
-
-		p += sprintf(p, "\033[%dH", t + 1);
-
-		for (i = t; i < t + count; i++) {
-			strcpy(p, "\033[K\n");
-			p += 4;
-			if (p - buf >= 224) {
-				promcon_puts(buf, p - buf);
-				p = buf;
-			}
-		}
-
-		for (; i < b; i++)
-			s = promcon_repaint_line(s, buf, &p);
-
-		p += promcon_end(conp, p);
-		promcon_puts(buf, p - buf);
-		break;
-	}
-
-	return 0;
-}
-
-#if !(PROMCON_COLOR)
-static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
-    u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
-{
-	return (_reverse) ? 0xf : 0x7;
-}
-#endif
-
-/*
- *  The console 'switch' structure for the VGA based console
- */
-
-static int promcon_dummy(void)
-{
-        return 0;
-}
-
-#define DUMMY (void *) promcon_dummy
-
-const struct consw prom_con = {
-	.owner =		THIS_MODULE,
-	.con_startup =		promcon_startup,
-	.con_init =		promcon_init,
-	.con_deinit =		promcon_deinit,
-	.con_clear =		promcon_clear,
-	.con_putc =		promcon_putc,
-	.con_putcs =		promcon_putcs,
-	.con_cursor =		promcon_cursor,
-	.con_scroll =		promcon_scroll,
-	.con_bmove =		promcon_bmove,
-	.con_switch =		promcon_switch,
-	.con_blank =		promcon_blank,
-	.con_set_palette =	DUMMY,
-	.con_scrolldelta =	DUMMY,
-#if !(PROMCON_COLOR)
-	.con_build_attr =	promcon_build_attr,
-#endif
-};
-
-void __init prom_con_init(void)
-{
-#ifdef CONFIG_DUMMY_CONSOLE
-	if (conswitchp == &dummy_con)
-		take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
-	else
-#endif
-	if (conswitchp == &prom_con)
-		promcon_init_unimap(vc_cons[fg_console].d);
-}
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 59d7d5e..74e96cf 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -180,7 +180,6 @@ static inline void vga_set_mem_top(struct vc_data *c)
 }
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
-#include <linux/slab.h>
 /* software scrollback */
 static void *vgacon_scrollback;
 static int vgacon_scrollback_tail;
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 15a0ee6..30ae302 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -33,6 +33,7 @@
 #include <linux/math64.h>
 
 #include <mach/imxfb.h>
+#include <mach/hardware.h>
 
 /*
  * Complain if VAR is out of range.
@@ -129,6 +130,10 @@
 #define LCDISR_EOF	(1<<1)
 #define LCDISR_BOF	(1<<0)
 
+/* Used fb-mode. Can be set on kernel command line, therefore file-static. */
+static const char *fb_mode;
+
+
 /*
  * These are the bitfields for each
  * display depth that we support.
@@ -145,10 +150,6 @@ struct imxfb_info {
 	void __iomem		*regs;
 	struct clk		*clk;
 
-	u_int			max_bpp;
-	u_int			max_xres;
-	u_int			max_yres;
-
 	/*
 	 * These are the addresses we mapped
 	 * the framebuffer memory region to.
@@ -172,6 +173,9 @@ struct imxfb_info {
 				cmap_static:1,
 				unused:30;
 
+	struct imx_fb_videomode *mode;
+	int			num_modes;
+
 	void (*lcd_power)(int);
 	void (*backlight_power)(int);
 };
@@ -298,6 +302,18 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 	return ret;
 }
 
+static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi)
+{
+	struct imx_fb_videomode *m;
+	int i;
+
+	for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) {
+		if (!strcmp(m->mode.name, fb_mode))
+			return m;
+	}
+	return NULL;
+}
+
 /*
  *  imxfb_check_var():
  *    Round up in the following order: bits_per_pixel, xres,
@@ -308,35 +324,81 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
 	struct imxfb_info *fbi = info->par;
 	struct imxfb_rgb *rgb;
+	const struct imx_fb_videomode *imxfb_mode;
+	unsigned long lcd_clk;
+	unsigned long long tmp;
+	u32 pcr = 0;
 
 	if (var->xres < MIN_XRES)
 		var->xres = MIN_XRES;
 	if (var->yres < MIN_YRES)
 		var->yres = MIN_YRES;
-	if (var->xres > fbi->max_xres)
-		var->xres = fbi->max_xres;
-	if (var->yres > fbi->max_yres)
-		var->yres = fbi->max_yres;
-	var->xres_virtual = max(var->xres_virtual, var->xres);
-	var->yres_virtual = max(var->yres_virtual, var->yres);
+
+	imxfb_mode = imxfb_find_mode(fbi);
+	if (!imxfb_mode)
+		return -EINVAL;
+
+	var->xres		= imxfb_mode->mode.xres;
+	var->yres		= imxfb_mode->mode.yres;
+	var->bits_per_pixel	= imxfb_mode->bpp;
+	var->pixclock		= imxfb_mode->mode.pixclock;
+	var->hsync_len		= imxfb_mode->mode.hsync_len;
+	var->left_margin	= imxfb_mode->mode.left_margin;
+	var->right_margin	= imxfb_mode->mode.right_margin;
+	var->vsync_len		= imxfb_mode->mode.vsync_len;
+	var->upper_margin	= imxfb_mode->mode.upper_margin;
+	var->lower_margin	= imxfb_mode->mode.lower_margin;
+	var->sync		= imxfb_mode->mode.sync;
+	var->xres_virtual	= max(var->xres_virtual, var->xres);
+	var->yres_virtual	= max(var->yres_virtual, var->yres);
 
 	pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel);
+
+	lcd_clk = clk_get_rate(fbi->clk);
+
+	tmp = var->pixclock * (unsigned long long)lcd_clk;
+
+	do_div(tmp, 1000000);
+
+	if (do_div(tmp, 1000000) > 500000)
+		tmp++;
+
+	pcr = (unsigned int)tmp;
+
+	if (--pcr > 0x3F) {
+		pcr = 0x3F;
+		printk(KERN_WARNING "Must limit pixel clock to %luHz\n",
+				lcd_clk / pcr);
+	}
+
 	switch (var->bits_per_pixel) {
 	case 32:
+		pcr |= PCR_BPIX_18;
 		rgb = &def_rgb_18;
 		break;
 	case 16:
 	default:
-		if (fbi->pcr & PCR_TFT)
+		if (cpu_is_mx1())
+			pcr |= PCR_BPIX_12;
+		else
+			pcr |= PCR_BPIX_16;
+
+		if (imxfb_mode->pcr & PCR_TFT)
 			rgb = &def_rgb_16_tft;
 		else
 			rgb = &def_rgb_16_stn;
 		break;
 	case 8:
+		pcr |= PCR_BPIX_8;
 		rgb = &def_rgb_8;
 		break;
 	}
 
+	/* add sync polarities */
+	pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25));
+
+	fbi->pcr = pcr;
+
 	/*
 	 * Copy the RGB parameters for this display
 	 * from the machine specific parameters.
@@ -393,10 +455,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)
 
 	writel(fbi->screen_dma, fbi->regs + LCDC_SSA);
 
-	/* physical screen start address	    */
-	writel(VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4),
-		fbi->regs + LCDC_VPW);
-
 	/* panning offset 0 (0 pixel offset)        */
 	writel(0x00000000, fbi->regs + LCDC_POS);
 
@@ -468,8 +526,6 @@ static struct fb_ops imxfb_ops = {
 static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
 	struct imxfb_info *fbi = info->par;
-	unsigned int pcr, lcd_clk;
-	unsigned long long tmp;
 
 	pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
 		var->xres, var->hsync_len,
@@ -505,6 +561,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
 			info->fix.id, var->lower_margin);
 #endif
 
+	/* physical screen start address	    */
+	writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4),
+		fbi->regs + LCDC_VPW);
+
 	writel(HCR_H_WIDTH(var->hsync_len - 1) |
 		HCR_H_WAIT_1(var->right_margin - 1) |
 		HCR_H_WAIT_2(var->left_margin - 3),
@@ -518,22 +578,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
 	writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
 			fbi->regs + LCDC_SIZE);
 
-	lcd_clk = clk_get_rate(fbi->clk);
-	tmp = var->pixclock * (unsigned long long)lcd_clk;
-	do_div(tmp, 1000000);
-	if (do_div(tmp, 1000000) > 500000)
-		tmp++;
-	pcr = (unsigned int)tmp;
-	if (--pcr > 0x3F) {
-		pcr = 0x3F;
-		printk(KERN_WARNING "Must limit pixel clock to %uHz\n",
-				lcd_clk / pcr);
-	}
-
-	/* add sync polarities */
-	pcr |= fbi->pcr & ~0x3F;
-
-	writel(pcr, fbi->regs + LCDC_PCR);
+	writel(fbi->pcr, fbi->regs + LCDC_PCR);
 	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
 	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
 	writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
@@ -575,6 +620,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
 	struct imx_fb_platform_data *pdata = pdev->dev.platform_data;
 	struct fb_info *info = dev_get_drvdata(&pdev->dev);
 	struct imxfb_info *fbi = info->par;
+	struct imx_fb_videomode *m;
+	int i;
 
 	pr_debug("%s\n",__func__);
 
@@ -603,35 +650,18 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev)
 	info->fbops			= &imxfb_ops;
 	info->flags			= FBINFO_FLAG_DEFAULT |
 					  FBINFO_READS_FAST;
-
-	fbi->max_xres			= pdata->xres;
-	info->var.xres			= pdata->xres;
-	info->var.xres_virtual		= pdata->xres;
-	fbi->max_yres			= pdata->yres;
-	info->var.yres			= pdata->yres;
-	info->var.yres_virtual		= pdata->yres;
-	fbi->max_bpp			= pdata->bpp;
-	info->var.bits_per_pixel	= pdata->bpp;
-	info->var.nonstd		= pdata->nonstd;
-	info->var.pixclock		= pdata->pixclock;
-	info->var.hsync_len		= pdata->hsync_len;
-	info->var.left_margin		= pdata->left_margin;
-	info->var.right_margin		= pdata->right_margin;
-	info->var.vsync_len		= pdata->vsync_len;
-	info->var.upper_margin		= pdata->upper_margin;
-	info->var.lower_margin		= pdata->lower_margin;
-	info->var.sync			= pdata->sync;
 	info->var.grayscale		= pdata->cmap_greyscale;
 	fbi->cmap_inverse		= pdata->cmap_inverse;
 	fbi->cmap_static		= pdata->cmap_static;
-	fbi->pcr			= pdata->pcr;
 	fbi->lscr1			= pdata->lscr1;
 	fbi->dmacr			= pdata->dmacr;
 	fbi->pwmr			= pdata->pwmr;
 	fbi->lcd_power			= pdata->lcd_power;
 	fbi->backlight_power		= pdata->backlight_power;
-	info->fix.smem_len		= fbi->max_xres * fbi->max_yres *
-					  fbi->max_bpp / 8;
+
+	for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++)
+		info->fix.smem_len = max_t(size_t, info->fix.smem_len,
+				m->mode.xres * m->mode.yres * m->bpp / 8);
 
 	return 0;
 }
@@ -642,9 +672,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
 	struct fb_info *info;
 	struct imx_fb_platform_data *pdata;
 	struct resource *res;
-	int ret;
+	int ret, i;
 
-	printk("i.MX Framebuffer driver\n");
+	dev_info(&pdev->dev, "i.MX Framebuffer driver\n");
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
@@ -662,6 +692,9 @@ static int __init imxfb_probe(struct platform_device *pdev)
 
 	fbi = info->par;
 
+	if (!fb_mode)
+		fb_mode = pdata->mode[0].mode.name;
+
 	platform_set_drvdata(pdev, info);
 
 	ret = imxfb_init_fbinfo(pdev);
@@ -684,7 +717,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
 
 	fbi->regs = ioremap(res->start, resource_size(res));
 	if (fbi->regs == NULL) {
-		printk(KERN_ERR"Cannot map frame buffer registers\n");
+		dev_err(&pdev->dev, "Cannot map frame buffer registers\n");
 		goto failed_ioremap;
 	}
 
@@ -719,6 +752,13 @@ static int __init imxfb_probe(struct platform_device *pdev)
 			goto failed_platform_init;
 	}
 
+	fbi->mode = pdata->mode;
+	fbi->num_modes = pdata->num_modes;
+
+	INIT_LIST_HEAD(&info->modelist);
+	for (i = 0; i < pdata->num_modes; i++)
+		fb_add_videomode(&pdata->mode[i].mode, &info->modelist);
+
 	/*
 	 * This makes sure that our colour bitfield
 	 * descriptors are correctly initialised.
@@ -754,7 +794,7 @@ failed_map:
 failed_getclock:
 	iounmap(fbi->regs);
 failed_ioremap:
-	release_mem_region(res->start, res->end - res->start);
+	release_mem_region(res->start, resource_size(res));
 failed_req:
 	kfree(info->pseudo_palette);
 failed_init:
@@ -785,7 +825,7 @@ static int __devexit imxfb_remove(struct platform_device *pdev)
 	framebuffer_release(info);
 
 	iounmap(fbi->regs);
-	release_mem_region(res->start, res->end - res->start + 1);
+	release_mem_region(res->start, resource_size(res));
 	clk_disable(fbi->clk);
 	clk_put(fbi->clk);
 
@@ -811,8 +851,34 @@ static struct platform_driver imxfb_driver = {
 	},
 };
 
+static int imxfb_setup(void)
+{
+#ifndef MODULE
+	char *opt, *options = NULL;
+
+	if (fb_get_options("imxfb", &options))
+		return -ENODEV;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+		else
+			fb_mode = opt;
+	}
+#endif
+	return 0;
+}
+
 int __init imxfb_init(void)
 {
+	int ret = imxfb_setup();
+
+	if (ret < 0)
+		return ret;
+
 	return platform_driver_probe(&imxfb_driver, imxfb_probe);
 }
 
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 148cbcc..915439d 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -212,9 +212,9 @@ static void enable_rfbi_mode(int enable)
 	dispc_write_reg(DISPC_CONTROL, l);
 
 	/* Set bypass mode in RFBI module */
-	l = __raw_readl(IO_ADDRESS(RFBI_CONTROL));
+	l = __raw_readl(OMAP2_IO_ADDRESS(RFBI_CONTROL));
 	l |= enable ? 0 : (1 << 1);
-	__raw_writel(l, IO_ADDRESS(RFBI_CONTROL));
+	__raw_writel(l, OMAP2_IO_ADDRESS(RFBI_CONTROL));
 }
 
 static void set_lcd_data_lines(int data_lines)
@@ -1421,7 +1421,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
 	}
 
 	/* L3 firewall setting: enable access to OCM RAM */
-	__raw_writel(0x402000b0, IO_ADDRESS(0x680050a0));
+	__raw_writel(0x402000b0, OMAP2_IO_ADDRESS(0x680050a0));
 
 	if ((r = alloc_palette_ram()) < 0)
 		goto fail2;
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index c0af638..9c0144e 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -32,7 +32,7 @@
 #include <linux/init.h>
 
 #include <asm/abs_addr.h>
-#include <asm/iommu.h>
+#include <asm/cell-regs.h>
 #include <asm/lv1call.h>
 #include <asm/ps3av.h>
 #include <asm/ps3fb.h>
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 10ddad8..cdaa873 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -66,7 +66,7 @@
  *	- FrameBuffer memory is now allocated at run-time when the
  *	  driver is initialized.    
  *
- * 2000/04/10: Nicolas Pitre <nico@cam.org>
+ * 2000/04/10: Nicolas Pitre <nico@fluxnic.net>
  *	- Big cleanup for dynamic selection of machine type at run time.
  *
  * 2000/07/19: Jamey Hicks <jamey@crl.dec.com>
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 07f22b6..3ad5157 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -14,6 +14,7 @@
 #include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
@@ -22,35 +23,8 @@
 #include <asm/atomic.h>
 
 #define PALETTE_NR 16
-
-struct sh_mobile_lcdc_priv;
-struct sh_mobile_lcdc_chan {
-	struct sh_mobile_lcdc_priv *lcdc;
-	unsigned long *reg_offs;
-	unsigned long ldmt1r_value;
-	unsigned long enabled; /* ME and SE in LDCNT2R */
-	struct sh_mobile_lcdc_chan_cfg cfg;
-	u32 pseudo_palette[PALETTE_NR];
-	struct fb_info *info;
-	dma_addr_t dma_handle;
-	struct fb_deferred_io defio;
-	struct scatterlist *sglist;
-	unsigned long frame_end;
-	wait_queue_head_t frame_end_wait;
-};
-
-struct sh_mobile_lcdc_priv {
-	void __iomem *base;
-	int irq;
-#ifdef CONFIG_HAVE_CLK
-	atomic_t clk_usecnt;
-	struct clk *dot_clk;
-	struct clk *clk;
-#endif
-	unsigned long lddckr;
-	struct sh_mobile_lcdc_chan ch[2];
-	int started;
-};
+#define SIDE_B_OFFSET 0x1000
+#define MIRROR_OFFSET 0x2000
 
 /* shared registers */
 #define _LDDCKR 0x410
@@ -59,17 +33,30 @@ struct sh_mobile_lcdc_priv {
 #define _LDSR 0x46c
 #define _LDCNT1R 0x470
 #define _LDCNT2R 0x474
+#define _LDRCNTR 0x478
 #define _LDDDSR 0x47c
 #define _LDDWD0R 0x800
 #define _LDDRDR 0x840
 #define _LDDWAR 0x900
 #define _LDDRAR 0x904
 
+/* shared registers and their order for context save/restore */
+static int lcdc_shared_regs[] = {
+	_LDDCKR,
+	_LDDCKSTPR,
+	_LDINTR,
+	_LDDDSR,
+	_LDCNT1R,
+	_LDCNT2R,
+};
+#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
+
 /* per-channel registers */
 enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
-       LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR };
+       LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR,
+       NR_CH_REGS };
 
-static unsigned long lcdc_offs_mainlcd[] = {
+static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = {
 	[LDDCKPAT1R] = 0x400,
 	[LDDCKPAT2R] = 0x404,
 	[LDMT1R] = 0x418,
@@ -87,7 +74,7 @@ static unsigned long lcdc_offs_mainlcd[] = {
 	[LDPMR] = 0x460,
 };
 
-static unsigned long lcdc_offs_sublcd[] = {
+static unsigned long lcdc_offs_sublcd[NR_CH_REGS] = {
 	[LDDCKPAT1R] = 0x408,
 	[LDDCKPAT2R] = 0x40c,
 	[LDMT1R] = 0x600,
@@ -110,12 +97,80 @@ static unsigned long lcdc_offs_sublcd[] = {
 #define DISPLAY_BEU	0x00000008
 #define LCDC_ENABLE	0x00000001
 #define LDINTR_FE	0x00000400
+#define LDINTR_VSE	0x00000200
+#define LDINTR_VEE	0x00000100
 #define LDINTR_FS	0x00000004
+#define LDINTR_VSS	0x00000002
+#define LDINTR_VES	0x00000001
+#define LDRCNTR_SRS	0x00020000
+#define LDRCNTR_SRC	0x00010000
+#define LDRCNTR_MRS	0x00000002
+#define LDRCNTR_MRC	0x00000001
+
+struct sh_mobile_lcdc_priv;
+struct sh_mobile_lcdc_chan {
+	struct sh_mobile_lcdc_priv *lcdc;
+	unsigned long *reg_offs;
+	unsigned long ldmt1r_value;
+	unsigned long enabled; /* ME and SE in LDCNT2R */
+	struct sh_mobile_lcdc_chan_cfg cfg;
+	u32 pseudo_palette[PALETTE_NR];
+	unsigned long saved_ch_regs[NR_CH_REGS];
+	struct fb_info *info;
+	dma_addr_t dma_handle;
+	struct fb_deferred_io defio;
+	struct scatterlist *sglist;
+	unsigned long frame_end;
+	unsigned long pan_offset;
+	unsigned long new_pan_offset;
+	wait_queue_head_t frame_end_wait;
+};
+
+struct sh_mobile_lcdc_priv {
+	void __iomem *base;
+	int irq;
+	atomic_t hw_usecnt;
+	struct device *dev;
+	struct clk *dot_clk;
+	unsigned long lddckr;
+	struct sh_mobile_lcdc_chan ch[2];
+	unsigned long saved_shared_regs[NR_SHARED_REGS];
+	int started;
+};
+
+static bool banked(int reg_nr)
+{
+	switch (reg_nr) {
+	case LDMT1R:
+	case LDMT2R:
+	case LDMT3R:
+	case LDDFR:
+	case LDSM1R:
+	case LDSA1R:
+	case LDMLSR:
+	case LDHCNR:
+	case LDHSYNR:
+	case LDVLNR:
+	case LDVSYNR:
+		return true;
+	}
+	return false;
+}
 
 static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
 			    int reg_nr, unsigned long data)
 {
 	iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
+	if (banked(reg_nr))
+		iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
+			  SIDE_B_OFFSET);
+}
+
+static void lcdc_write_chan_mirror(struct sh_mobile_lcdc_chan *chan,
+			    int reg_nr, unsigned long data)
+{
+	iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr] +
+		  MIRROR_OFFSET);
 }
 
 static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
@@ -156,6 +211,7 @@ static void lcdc_sys_write_index(void *handle, unsigned long data)
 	lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000);
 	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 	lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
+	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 }
 
 static void lcdc_sys_write_data(void *handle, unsigned long data)
@@ -165,6 +221,7 @@ static void lcdc_sys_write_data(void *handle, unsigned long data)
 	lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000);
 	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 	lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
+	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 }
 
 static unsigned long lcdc_sys_read_data(void *handle)
@@ -175,8 +232,9 @@ static unsigned long lcdc_sys_read_data(void *handle)
 	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 	lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
 	udelay(1);
+	lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
 
-	return lcdc_read(ch->lcdc, _LDDRDR) & 0xffff;
+	return lcdc_read(ch->lcdc, _LDDRDR) & 0x3ffff;
 }
 
 struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
@@ -185,11 +243,10 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
 	lcdc_sys_read_data,
 };
 
-#ifdef CONFIG_HAVE_CLK
 static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 {
-	if (atomic_inc_and_test(&priv->clk_usecnt)) {
-		clk_enable(priv->clk);
+	if (atomic_inc_and_test(&priv->hw_usecnt)) {
+		pm_runtime_get_sync(priv->dev);
 		if (priv->dot_clk)
 			clk_enable(priv->dot_clk);
 	}
@@ -197,16 +254,12 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
 
 static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)
 {
-	if (atomic_sub_return(1, &priv->clk_usecnt) == -1) {
+	if (atomic_sub_return(1, &priv->hw_usecnt) == -1) {
 		if (priv->dot_clk)
 			clk_disable(priv->dot_clk);
-		clk_disable(priv->clk);
+		pm_runtime_put(priv->dev);
 	}
 }
-#else
-static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {}
-static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {}
-#endif
 
 static int sh_mobile_lcdc_sginit(struct fb_info *info,
 				  struct list_head *pagelist)
@@ -255,30 +308,52 @@ static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data)
 	struct sh_mobile_lcdc_priv *priv = data;
 	struct sh_mobile_lcdc_chan *ch;
 	unsigned long tmp;
+	unsigned long ldintr;
 	int is_sub;
 	int k;
 
 	/* acknowledge interrupt */
-	tmp = lcdc_read(priv, _LDINTR);
-	tmp &= 0xffffff00; /* mask in high 24 bits */
-	tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */
+	ldintr = tmp = lcdc_read(priv, _LDINTR);
+	/*
+	 * disable further VSYNC End IRQs, preserve all other enabled IRQs,
+	 * write 0 to bits 0-6 to ack all triggered IRQs.
+	 */
+	tmp &= 0xffffff00 & ~LDINTR_VEE;
 	lcdc_write(priv, _LDINTR, tmp);
 
 	/* figure out if this interrupt is for main or sub lcd */
 	is_sub = (lcdc_read(priv, _LDSR) & (1 << 10)) ? 1 : 0;
 
-	/* wake up channel and disable clocks*/
+	/* wake up channel and disable clocks */
 	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
 		ch = &priv->ch[k];
 
 		if (!ch->enabled)
 			continue;
 
-		if (is_sub == lcdc_chan_is_sublcd(ch)) {
-			ch->frame_end = 1;
-			wake_up(&ch->frame_end_wait);
+		/* Frame Start */
+		if (ldintr & LDINTR_FS) {
+			if (is_sub == lcdc_chan_is_sublcd(ch)) {
+				ch->frame_end = 1;
+				wake_up(&ch->frame_end_wait);
 
-			sh_mobile_lcdc_clk_off(priv);
+				sh_mobile_lcdc_clk_off(priv);
+			}
+		}
+
+		/* VSYNC End */
+		if (ldintr & LDINTR_VES) {
+			unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR);
+			/* Set the source address for the next refresh */
+			lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
+					       ch->new_pan_offset);
+			if (lcdc_chan_is_sublcd(ch))
+				lcdc_write(ch->lcdc, _LDRCNTR,
+					   ldrcntr ^ LDRCNTR_SRS);
+			else
+				lcdc_write(ch->lcdc, _LDRCNTR,
+					   ldrcntr ^ LDRCNTR_MRS);
+			ch->pan_offset = ch->new_pan_offset;
 		}
 	}
 
@@ -520,7 +595,6 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
 		board_cfg = &ch->cfg.board_cfg;
 		if (board_cfg->display_off)
 			board_cfg->display_off(board_cfg->board_data);
-
 	}
 
 	/* stop the lcdc */
@@ -579,9 +653,6 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
 				       int clock_source,
 				       struct sh_mobile_lcdc_priv *priv)
 {
-#ifdef CONFIG_HAVE_CLK
-	char clk_name[8];
-#endif
 	char *str;
 	int icksel;
 
@@ -595,25 +666,21 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev,
 
 	priv->lddckr = icksel << 16;
 
-#ifdef CONFIG_HAVE_CLK
-	atomic_set(&priv->clk_usecnt, -1);
-	snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id);
-	priv->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(priv->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		return PTR_ERR(priv->clk);
-	}
-	
 	if (str) {
 		priv->dot_clk = clk_get(&pdev->dev, str);
 		if (IS_ERR(priv->dot_clk)) {
 			dev_err(&pdev->dev, "cannot get dot clock %s\n", str);
-			clk_put(priv->clk);
 			return PTR_ERR(priv->dot_clk);
 		}
 	}
-#endif
-
+	atomic_set(&priv->hw_usecnt, -1);
+
+	/* Runtime PM support involves two step for this driver:
+	 * 1) Enable Runtime PM
+	 * 2) Force Runtime PM Resume since hardware is accessed from probe()
+	 */
+	pm_runtime_enable(priv->dev);
+	pm_runtime_resume(priv->dev);
 	return 0;
 }
 
@@ -646,6 +713,9 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix  = {
 	.type =		FB_TYPE_PACKED_PIXELS,
 	.visual =	FB_VISUAL_TRUECOLOR,
 	.accel =	FB_ACCEL_NONE,
+	.xpanstep =	0,
+	.ypanstep =	1,
+	.ywrapstep =	0,
 };
 
 static void sh_mobile_lcdc_fillrect(struct fb_info *info,
@@ -669,13 +739,38 @@ static void sh_mobile_lcdc_imageblit(struct fb_info *info,
 	sh_mobile_lcdc_deferred_io_touch(info);
 }
 
+static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
+				     struct fb_info *info)
+{
+	struct sh_mobile_lcdc_chan *ch = info->par;
+
+	if (info->var.xoffset == var->xoffset &&
+	    info->var.yoffset == var->yoffset)
+		return 0;	/* No change, do nothing */
+
+	ch->new_pan_offset = (var->yoffset * info->fix.line_length) +
+		(var->xoffset * (info->var.bits_per_pixel / 8));
+
+	if (ch->new_pan_offset != ch->pan_offset) {
+		unsigned long ldintr;
+		ldintr = lcdc_read(ch->lcdc, _LDINTR);
+		ldintr |= LDINTR_VEE;
+		lcdc_write(ch->lcdc, _LDINTR, ldintr);
+		sh_mobile_lcdc_deferred_io_touch(info);
+	}
+
+	return 0;
+}
+
 static struct fb_ops sh_mobile_lcdc_ops = {
+	.owner          = THIS_MODULE,
 	.fb_setcolreg	= sh_mobile_lcdc_setcolreg,
 	.fb_read        = fb_sys_read,
 	.fb_write       = fb_sys_write,
 	.fb_fillrect	= sh_mobile_lcdc_fillrect,
 	.fb_copyarea	= sh_mobile_lcdc_copyarea,
 	.fb_imageblit	= sh_mobile_lcdc_imageblit,
+	.fb_pan_display = sh_mobile_fb_pan_display,
 };
 
 static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
@@ -731,9 +826,59 @@ static int sh_mobile_lcdc_resume(struct device *dev)
 	return sh_mobile_lcdc_start(platform_get_drvdata(pdev));
 }
 
+static int sh_mobile_lcdc_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
+	struct sh_mobile_lcdc_chan *ch;
+	int k, n;
+
+	/* save per-channel registers */
+	for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
+		ch = &p->ch[k];
+		if (!ch->enabled)
+			continue;
+		for (n = 0; n < NR_CH_REGS; n++)
+			ch->saved_ch_regs[n] = lcdc_read_chan(ch, n);
+	}
+
+	/* save shared registers */
+	for (n = 0; n < NR_SHARED_REGS; n++)
+		p->saved_shared_regs[n] = lcdc_read(p, lcdc_shared_regs[n]);
+
+	/* turn off LCDC hardware */
+	lcdc_write(p, _LDCNT1R, 0);
+	return 0;
+}
+
+static int sh_mobile_lcdc_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
+	struct sh_mobile_lcdc_chan *ch;
+	int k, n;
+
+	/* restore per-channel registers */
+	for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
+		ch = &p->ch[k];
+		if (!ch->enabled)
+			continue;
+		for (n = 0; n < NR_CH_REGS; n++)
+			lcdc_write_chan(ch, n, ch->saved_ch_regs[n]);
+	}
+
+	/* restore shared registers */
+	for (n = 0; n < NR_SHARED_REGS; n++)
+		lcdc_write(p, lcdc_shared_regs[n], p->saved_shared_regs[n]);
+
+	return 0;
+}
+
 static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = {
 	.suspend = sh_mobile_lcdc_suspend,
 	.resume = sh_mobile_lcdc_resume,
+	.runtime_suspend = sh_mobile_lcdc_runtime_suspend,
+	.runtime_resume = sh_mobile_lcdc_runtime_resume,
 };
 
 static int sh_mobile_lcdc_remove(struct platform_device *pdev);
@@ -778,6 +923,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
 	}
 
 	priv->irq = i;
+	priv->dev = &pdev->dev;
 	platform_set_drvdata(pdev, priv);
 	pdata = pdev->dev.platform_data;
 
@@ -792,6 +938,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
 			goto err1;
 		}
 		init_waitqueue_head(&priv->ch[i].frame_end_wait);
+		priv->ch[j].pan_offset = 0;
+		priv->ch[j].new_pan_offset = 0;
 
 		switch (pdata->ch[i].chan) {
 		case LCDC_CHAN_MAINLCD:
@@ -834,7 +982,9 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
 		info = priv->ch[i].info;
 		info->fbops = &sh_mobile_lcdc_ops;
 		info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
-		info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
+		info->var.yres = cfg->lcd_cfg.yres;
+		/* Default Y virtual resolution is 2x panel size */
+		info->var.yres_virtual = info->var.yres * 2;
 		info->var.width = cfg->lcd_size_cfg.width;
 		info->var.height = cfg->lcd_size_cfg.height;
 		info->var.activate = FB_ACTIVATE_NOW;
@@ -844,7 +994,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
 
 		info->fix = sh_mobile_lcdc_fix;
 		info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8);
-		info->fix.smem_len = info->fix.line_length * cfg->lcd_cfg.yres;
+		info->fix.smem_len = info->fix.line_length *
+			info->var.yres_virtual;
 
 		buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
 					 &priv->ch[i].dma_handle, GFP_KERNEL);
@@ -947,11 +1098,10 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
 		framebuffer_release(info);
 	}
 
-#ifdef CONFIG_HAVE_CLK
 	if (priv->dot_clk)
 		clk_put(priv->dot_clk);
-	clk_put(priv->clk);
-#endif
+
+	pm_runtime_disable(priv->dev);
 
 	if (priv->base)
 		iounmap(priv->base);
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index ca5b464..e98baf6 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -67,9 +67,8 @@ static DEFINE_MUTEX(uvfb_lock);
  * find the kernel part of the task struct, copy the registers and
  * the buffer contents and then complete the task.
  */
-static void uvesafb_cn_callback(void *data)
+static void uvesafb_cn_callback(struct cn_msg *msg)
 {
-	struct cn_msg *msg = data;
 	struct uvesafb_task *utask;
 	struct uvesafb_ktask *task;
 
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index fdf7285..52ccb3d 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -306,9 +306,8 @@ static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rm
 	return error;
 }
 
-static void w1_cn_callback(void *data)
+static void w1_cn_callback(struct cn_msg *msg)
 {
-	struct cn_msg *msg = data;
 	struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1);
 	struct w1_netlink_cmd *cmd;
 	struct w1_slave *sl;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index b1ccc04..ff3eb8f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -55,6 +55,13 @@ config SOFT_WATCHDOG
 	  To compile this driver as a module, choose M here: the
 	  module will be called softdog.
 
+config WM831X_WATCHDOG
+	tristate "WM831x watchdog"
+	depends on MFD_WM831X
+	help
+	  Support for the watchdog in the WM831x AudioPlus PMICs.  When
+	  the watchdog triggers the system will be reset.
+
 config WM8350_WATCHDOG
 	tristate "WM8350 watchdog"
 	depends on MFD_WM8350
@@ -266,6 +273,15 @@ config STMP3XXX_WATCHDOG
 	  To compile this driver as a module, choose M here: the
 	  module will be called stmp3xxx_wdt.
 
+config NUC900_WATCHDOG
+	tristate "Nuvoton NUC900 watchdog"
+	depends on ARCH_W90X900
+	help
+	  Say Y here if to include support for the watchdog timer
+	  for the Nuvoton NUC900 series SoCs.
+	  To compile this driver as a module, choose M here: the
+	  module will be called nuc900_wdt.
+
 # AVR32 Architecture
 
 config AT32AP700X_WDT
@@ -369,6 +385,28 @@ config SC520_WDT
 	  You can compile this driver directly into the kernel, or use
 	  it as a module.  The module will be called sc520_wdt.
 
+config SBC_FITPC2_WATCHDOG
+	tristate "Compulab SBC-FITPC2 watchdog"
+	depends on X86
+	---help---
+	  This is the driver for the built-in watchdog timer on the fit-PC2
+	  Single-board computer made by Compulab.
+
+	  It`s possible to enable watchdog timer either from BIOS (F2) or from booted Linux.
+	  When "Watchdog Timer Value" enabled one can set 31-255 s operational range.
+
+	  Entering BIOS setup temporary disables watchdog operation regardless to current state,
+	  so system will not be restarted while user in BIOS setup.
+
+	  Once watchdog was enabled the system will be restarted every
+	  "Watchdog Timer Value" period, so to prevent it user can restart or
+	  disable the watchdog.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called sbc_fitpc2_wdt.
+
+	  Most people will say N.
+
 config EUROTECH_WDT
 	tristate "Eurotech CPU-1220/1410 Watchdog Timer"
 	depends on X86
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 3d77429..348b3b8 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
 obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o
 obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
 obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o
+obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
 
 # AVR32 Architecture
 obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
@@ -64,6 +65,7 @@ obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o
 obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o
 obj-$(CONFIG_GEODE_WDT) += geodewdt.o
 obj-$(CONFIG_SC520_WDT) += sc520_wdt.o
+obj-$(CONFIG_SBC_FITPC2_WATCHDOG) += sbc_fitpc2_wdt.o
 obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o
 obj-$(CONFIG_IB700_WDT) += ib700wdt.o
 obj-$(CONFIG_IBMASR) += ibmasr.o
@@ -139,5 +141,6 @@ obj-$(CONFIG_WATCHDOG_CP1XXX)		+= cpwd.o
 # XTENSA Architecture
 
 # Architecture Independant
+obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
 obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
 obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c
index 2f8643e..2e94b71 100644
--- a/drivers/watchdog/ar7_wdt.c
+++ b/drivers/watchdog/ar7_wdt.c
@@ -28,9 +28,8 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
+#include <linux/platform_device.h>
 #include <linux/watchdog.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
 #include <linux/fs.h>
 #include <linux/ioport.h>
 #include <linux/io.h>
@@ -76,24 +75,10 @@ static unsigned expect_close;
 /* XXX currently fixed, allows max margin ~68.72 secs */
 #define prescale_value 0xffff
 
-/* Offset of the WDT registers */
-static unsigned long ar7_regs_wdt;
+/* Resource of the WDT registers */
+static struct resource *ar7_regs_wdt;
 /* Pointer to the remapped WDT IO space */
 static struct ar7_wdt *ar7_wdt;
-static void ar7_wdt_get_regs(void)
-{
-	u16 chip_id = ar7_chip_id();
-	switch (chip_id) {
-	case AR7_CHIP_7100:
-	case AR7_CHIP_7200:
-		ar7_regs_wdt = AR7_REGS_WDT;
-		break;
-	default:
-		ar7_regs_wdt = UR8_REGS_WDT;
-		break;
-	}
-}
-
 
 static void ar7_wdt_kick(u32 value)
 {
@@ -202,20 +187,6 @@ static int ar7_wdt_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
-static int ar7_wdt_notify_sys(struct notifier_block *this,
-			      unsigned long code, void *unused)
-{
-	if (code == SYS_HALT || code == SYS_POWER_OFF)
-		if (!nowayout)
-			ar7_wdt_disable_wdt();
-
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block ar7_wdt_notifier = {
-	.notifier_call = ar7_wdt_notify_sys,
-};
-
 static ssize_t ar7_wdt_write(struct file *file, const char *data,
 			     size_t len, loff_t *ppos)
 {
@@ -299,56 +270,86 @@ static struct miscdevice ar7_wdt_miscdev = {
 	.fops		= &ar7_wdt_fops,
 };
 
-static int __init ar7_wdt_init(void)
+static int __devinit ar7_wdt_probe(struct platform_device *pdev)
 {
 	int rc;
 
 	spin_lock_init(&wdt_lock);
 
-	ar7_wdt_get_regs();
+	ar7_regs_wdt =
+		platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+	if (!ar7_regs_wdt) {
+		printk(KERN_ERR DRVNAME ": could not get registers resource\n");
+		rc = -ENODEV;
+		goto out;
+	}
 
-	if (!request_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt),
-							LONGNAME)) {
+	if (!request_mem_region(ar7_regs_wdt->start,
+				resource_size(ar7_regs_wdt), LONGNAME)) {
 		printk(KERN_WARNING DRVNAME ": watchdog I/O region busy\n");
-		return -EBUSY;
+		rc = -EBUSY;
+		goto out;
 	}
 
-	ar7_wdt = (struct ar7_wdt *)
-			ioremap(ar7_regs_wdt, sizeof(struct ar7_wdt));
+	ar7_wdt = ioremap(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
+	if (!ar7_wdt) {
+		printk(KERN_ERR DRVNAME ": could not ioremap registers\n");
+		rc = -ENXIO;
+		goto out_mem_region;
+	}
 
 	ar7_wdt_disable_wdt();
 	ar7_wdt_prescale(prescale_value);
 	ar7_wdt_update_margin(margin);
 
-	rc = register_reboot_notifier(&ar7_wdt_notifier);
-	if (rc) {
-		printk(KERN_ERR DRVNAME
-			": unable to register reboot notifier\n");
-		goto out_alloc;
-	}
-
 	rc = misc_register(&ar7_wdt_miscdev);
 	if (rc) {
 		printk(KERN_ERR DRVNAME ": unable to register misc device\n");
-		goto out_register;
+		goto out_alloc;
 	}
 	goto out;
 
-out_register:
-	unregister_reboot_notifier(&ar7_wdt_notifier);
 out_alloc:
 	iounmap(ar7_wdt);
-	release_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt));
+out_mem_region:
+	release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
 out:
 	return rc;
 }
 
-static void __exit ar7_wdt_cleanup(void)
+static int __devexit ar7_wdt_remove(struct platform_device *pdev)
 {
 	misc_deregister(&ar7_wdt_miscdev);
-	unregister_reboot_notifier(&ar7_wdt_notifier);
 	iounmap(ar7_wdt);
-	release_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt));
+	release_mem_region(ar7_regs_wdt->start, resource_size(ar7_regs_wdt));
+
+	return 0;
+}
+
+static void ar7_wdt_shutdown(struct platform_device *pdev)
+{
+	if (!nowayout)
+		ar7_wdt_disable_wdt();
+}
+
+static struct platform_driver ar7_wdt_driver = {
+	.probe = ar7_wdt_probe,
+	.remove = __devexit_p(ar7_wdt_remove),
+	.shutdown = ar7_wdt_shutdown,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "ar7_wdt",
+	},
+};
+
+static int __init ar7_wdt_init(void)
+{
+	return platform_driver_register(&ar7_wdt_driver);
+}
+
+static void __exit ar7_wdt_cleanup(void)
+{
+	platform_driver_unregister(&ar7_wdt_driver);
 }
 
 module_init(ar7_wdt_init);
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index 225398f..e8380ef 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -22,6 +22,8 @@
 
 #include <asm/reg_booke.h>
 #include <asm/system.h>
+#include <asm/time.h>
+#include <asm/div64.h>
 
 /* If the kernel parameter wdt=1, the watchdog will be enabled at boot.
  * Also, the wdt_period sets the watchdog timer period timeout.
@@ -32,7 +34,7 @@
  */
 
 #ifdef	CONFIG_FSL_BOOKE
-#define WDT_PERIOD_DEFAULT 63	/* Ex. wdt_period=28 bus=333Mhz,reset=~40sec */
+#define WDT_PERIOD_DEFAULT 38	/* Ex. wdt_period=28 bus=333Mhz,reset=~40sec */
 #else
 #define WDT_PERIOD_DEFAULT 3	/* Refer to the PPC40x and PPC4xx manuals */
 #endif				/* for timing information */
@@ -41,7 +43,7 @@ u32 booke_wdt_enabled;
 u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
 
 #ifdef	CONFIG_FSL_BOOKE
-#define WDTP(x)		((((63-x)&0x3)<<30)|(((63-x)&0x3c)<<15))
+#define WDTP(x)		((((x)&0x3)<<30)|(((x)&0x3c)<<15))
 #define WDTP_MASK	(WDTP(0))
 #else
 #define WDTP(x)		(TCR_WP(x))
@@ -50,6 +52,45 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
 
 static DEFINE_SPINLOCK(booke_wdt_lock);
 
+/* For the specified period, determine the number of seconds
+ * corresponding to the reset time.  There will be a watchdog
+ * exception at approximately 3/5 of this time.
+ *
+ * The formula to calculate this is given by:
+ * 2.5 * (2^(63-period+1)) / timebase_freq
+ *
+ * In order to simplify things, we assume that period is
+ * at least 1.  This will still result in a very long timeout.
+ */
+static unsigned long long period_to_sec(unsigned int period)
+{
+	unsigned long long tmp = 1ULL << (64 - period);
+	unsigned long tmp2 = ppc_tb_freq;
+
+	/* tmp may be a very large number and we don't want to overflow,
+	 * so divide the timebase freq instead of multiplying tmp
+	 */
+	tmp2 = tmp2 / 5 * 2;
+
+	do_div(tmp, tmp2);
+	return tmp;
+}
+
+/*
+ * This procedure will find the highest period which will give a timeout
+ * greater than the one required. e.g. for a bus speed of 66666666 and
+ * and a parameter of 2 secs, then this procedure will return a value of 38.
+ */
+static unsigned int sec_to_period(unsigned int secs)
+{
+	unsigned int period;
+	for (period = 63; period > 0; period--) {
+		if (period_to_sec(period) >= secs)
+			return period;
+	}
+	return 0;
+}
+
 static void __booke_wdt_ping(void *data)
 {
 	mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
@@ -93,7 +134,7 @@ static long booke_wdt_ioctl(struct file *file,
 
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		if (copy_to_user(arg, &ident, sizeof(struct watchdog_info)))
+		if (copy_to_user((void *)arg, &ident, sizeof(ident)))
 			return -EFAULT;
 	case WDIOC_GETSTATUS:
 		return put_user(ident.options, p);
@@ -115,8 +156,16 @@ static long booke_wdt_ioctl(struct file *file,
 		booke_wdt_ping();
 		return 0;
 	case WDIOC_SETTIMEOUT:
-		if (get_user(booke_wdt_period, p))
+		if (get_user(tmp, p))
 			return -EFAULT;
+#ifdef	CONFIG_FSL_BOOKE
+		/* period of 1 gives the largest possible timeout */
+		if (tmp > period_to_sec(1))
+			return -EINVAL;
+		booke_wdt_period = sec_to_period(tmp);
+#else
+		booke_wdt_period = tmp;
+#endif
 		mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP_MASK) |
 						WDTP(booke_wdt_period));
 		return 0;
diff --git a/drivers/watchdog/coh901327_wdt.c b/drivers/watchdog/coh901327_wdt.c
index aec7cef..381026c 100644
--- a/drivers/watchdog/coh901327_wdt.c
+++ b/drivers/watchdog/coh901327_wdt.c
@@ -110,7 +110,7 @@ static void coh901327_enable(u16 timeout)
 	 * Wait 3 32 kHz cycles for it to take effect
 	 */
 	freq = clk_get_rate(clk);
-	delay_ns = (1000000000 + freq - 1) / freq; /* Freq to ns and round up */
+	delay_ns = DIV_ROUND_UP(1000000000, freq); /* Freq to ns and round up */
 	delay_ns = 3 * delay_ns; /* Wait 3 cycles */
 	ndelay(delay_ns);
 	/* Enable the watchdog interrupt */
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 83e22e7..9d7520f 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -25,6 +25,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/device.h>
+#include <linux/clk.h>
 
 #define MODULE_NAME "DAVINCI-WDT: "
 
@@ -69,6 +70,7 @@ static unsigned long wdt_status;
 
 static struct resource	*wdt_mem;
 static void __iomem	*wdt_base;
+struct clk		*wdt_clk;
 
 static void wdt_service(void)
 {
@@ -86,6 +88,9 @@ static void wdt_enable(void)
 {
 	u32 tgcr;
 	u32 timer_margin;
+	unsigned long wdt_freq;
+
+	wdt_freq = clk_get_rate(wdt_clk);
 
 	spin_lock(&io_lock);
 
@@ -99,9 +104,9 @@ static void wdt_enable(void)
 	iowrite32(0, wdt_base + TIM12);
 	iowrite32(0, wdt_base + TIM34);
 	/* set timeout period */
-	timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) & 0xffffffff);
+	timer_margin = (((u64)heartbeat * wdt_freq) & 0xffffffff);
 	iowrite32(timer_margin, wdt_base + PRD12);
-	timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) >> 32);
+	timer_margin = (((u64)heartbeat * wdt_freq) >> 32);
 	iowrite32(timer_margin, wdt_base + PRD34);
 	/* enable run continuously */
 	iowrite32(ENAMODE12_PERIODIC, wdt_base + TCR);
@@ -199,6 +204,12 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct device *dev = &pdev->dev;
 
+	wdt_clk = clk_get(dev, NULL);
+	if (WARN_ON(IS_ERR(wdt_clk)))
+		return PTR_ERR(wdt_clk);
+
+	clk_enable(wdt_clk);
+
 	if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
 		heartbeat = DEFAULT_HEARTBEAT;
 
@@ -245,6 +256,10 @@ static int __devexit davinci_wdt_remove(struct platform_device *pdev)
 		kfree(wdt_mem);
 		wdt_mem = NULL;
 	}
+
+	clk_disable(wdt_clk);
+	clk_put(wdt_clk);
+
 	return 0;
 }
 
diff --git a/drivers/watchdog/iop_wdt.c b/drivers/watchdog/iop_wdt.c
index 0c90596..aef9478 100644
--- a/drivers/watchdog/iop_wdt.c
+++ b/drivers/watchdog/iop_wdt.c
@@ -139,7 +139,7 @@ static long iop_wdt_ioctl(struct file *file,
 
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		if (copy_to_user(argp, &ident, sizeof ident))
+		if (copy_to_user(argp, &ident, sizeof(ident)))
 			ret = -EFAULT;
 		else
 			ret = 0;
diff --git a/drivers/watchdog/nuc900_wdt.c b/drivers/watchdog/nuc900_wdt.c
new file mode 100644
index 0000000..adefe3a
--- /dev/null
+++ b/drivers/watchdog/nuc900_wdt.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@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 of the License.
+ *
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <linux/uaccess.h>
+
+#define REG_WTCR		0x1c
+#define WTCLK			(0x01 << 10)
+#define WTE			(0x01 << 7)	/*wdt enable*/
+#define WTIS			(0x03 << 4)
+#define WTIF			(0x01 << 3)
+#define WTRF			(0x01 << 2)
+#define WTRE			(0x01 << 1)
+#define WTR			(0x01 << 0)
+/*
+ * The watchdog time interval can be calculated via following formula:
+ * WTIS		real time interval (formula)
+ * 0x00		((2^ 14 ) * ((external crystal freq) / 256))seconds
+ * 0x01		((2^ 16 ) * ((external crystal freq) / 256))seconds
+ * 0x02		((2^ 18 ) * ((external crystal freq) / 256))seconds
+ * 0x03		((2^ 20 ) * ((external crystal freq) / 256))seconds
+ *
+ * The external crystal freq is 15Mhz in the nuc900 evaluation board.
+ * So 0x00 = +-0.28 seconds, 0x01 = +-1.12 seconds, 0x02 = +-4.48 seconds,
+ * 0x03 = +- 16.92 seconds..
+ */
+#define WDT_HW_TIMEOUT		0x02
+#define WDT_TIMEOUT		(HZ/2)
+#define WDT_HEARTBEAT		15
+
+static int heartbeat = WDT_HEARTBEAT;
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. "
+	"(default = " __MODULE_STRING(WDT_HEARTBEAT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+	"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+struct nuc900_wdt {
+	struct resource  *res;
+	struct clk	 *wdt_clock;
+	struct platform_device *pdev;
+	void __iomem	 *wdt_base;
+	char		 expect_close;
+	struct timer_list timer;
+	spinlock_t       wdt_lock;
+	unsigned long next_heartbeat;
+};
+
+static unsigned long nuc900wdt_busy;
+struct nuc900_wdt *nuc900_wdt;
+
+static inline void nuc900_wdt_keepalive(void)
+{
+	unsigned int val;
+
+	spin_lock(&nuc900_wdt->wdt_lock);
+
+	val = __raw_readl(nuc900_wdt->wdt_base + REG_WTCR);
+	val |= (WTR | WTIF);
+	__raw_writel(val, nuc900_wdt->wdt_base + REG_WTCR);
+
+	spin_unlock(&nuc900_wdt->wdt_lock);
+}
+
+static inline void nuc900_wdt_start(void)
+{
+	unsigned int val;
+
+	spin_lock(&nuc900_wdt->wdt_lock);
+
+	val = __raw_readl(nuc900_wdt->wdt_base + REG_WTCR);
+	val |= (WTRE | WTE | WTR | WTCLK | WTIF);
+	val &= ~WTIS;
+	val |= (WDT_HW_TIMEOUT << 0x04);
+	__raw_writel(val, nuc900_wdt->wdt_base + REG_WTCR);
+
+	spin_unlock(&nuc900_wdt->wdt_lock);
+
+	nuc900_wdt->next_heartbeat = jiffies + heartbeat * HZ;
+	mod_timer(&nuc900_wdt->timer, jiffies + WDT_TIMEOUT);
+}
+
+static inline void nuc900_wdt_stop(void)
+{
+	unsigned int val;
+
+	del_timer(&nuc900_wdt->timer);
+
+	spin_lock(&nuc900_wdt->wdt_lock);
+
+	val = __raw_readl(nuc900_wdt->wdt_base + REG_WTCR);
+	val &= ~WTE;
+	__raw_writel(val, nuc900_wdt->wdt_base + REG_WTCR);
+
+	spin_unlock(&nuc900_wdt->wdt_lock);
+}
+
+static inline void nuc900_wdt_ping(void)
+{
+	nuc900_wdt->next_heartbeat = jiffies + heartbeat * HZ;
+}
+
+static int nuc900_wdt_open(struct inode *inode, struct file *file)
+{
+
+	if (test_and_set_bit(0, &nuc900wdt_busy))
+		return -EBUSY;
+
+	nuc900_wdt_start();
+
+	return nonseekable_open(inode, file);
+}
+
+static int nuc900_wdt_close(struct inode *inode, struct file *file)
+{
+	if (nuc900_wdt->expect_close == 42)
+		nuc900_wdt_stop();
+	else {
+		dev_crit(&nuc900_wdt->pdev->dev,
+			"Unexpected close, not stopping watchdog!\n");
+		nuc900_wdt_ping();
+	}
+
+	nuc900_wdt->expect_close = 0;
+	clear_bit(0, &nuc900wdt_busy);
+	return 0;
+}
+
+static const struct watchdog_info nuc900_wdt_info = {
+	.identity	= "nuc900 watchdog",
+	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+						WDIOF_MAGICCLOSE,
+};
+
+static long nuc900_wdt_ioctl(struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	int new_value;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		return copy_to_user(argp, &nuc900_wdt_info,
+				sizeof(nuc900_wdt_info)) ? -EFAULT : 0;
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		return put_user(0, p);
+
+	case WDIOC_KEEPALIVE:
+		nuc900_wdt_ping();
+		return 0;
+
+	case WDIOC_SETTIMEOUT:
+		if (get_user(new_value, p))
+			return -EFAULT;
+
+		heartbeat = new_value;
+		nuc900_wdt_ping();
+
+		return put_user(new_value, p);
+	case WDIOC_GETTIMEOUT:
+		return put_user(heartbeat, p);
+	default:
+		return -ENOTTY;
+	}
+}
+
+static ssize_t nuc900_wdt_write(struct file *file, const char __user *data,
+						size_t len, loff_t *ppos)
+{
+	if (!len)
+		return 0;
+
+	/* Scan for magic character */
+	if (!nowayout) {
+		size_t i;
+
+		nuc900_wdt->expect_close = 0;
+
+		for (i = 0; i < len; i++) {
+			char c;
+			if (get_user(c, data + i))
+				return -EFAULT;
+			if (c == 'V') {
+				nuc900_wdt->expect_close = 42;
+				break;
+			}
+		}
+	}
+
+	nuc900_wdt_ping();
+	return len;
+}
+
+static void nuc900_wdt_timer_ping(unsigned long data)
+{
+	if (time_before(jiffies, nuc900_wdt->next_heartbeat)) {
+		nuc900_wdt_keepalive();
+		mod_timer(&nuc900_wdt->timer, jiffies + WDT_TIMEOUT);
+	} else
+		dev_warn(&nuc900_wdt->pdev->dev, "Will reset the machine !\n");
+}
+
+static const struct file_operations nuc900wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.unlocked_ioctl	= nuc900_wdt_ioctl,
+	.open		= nuc900_wdt_open,
+	.release	= nuc900_wdt_close,
+	.write		= nuc900_wdt_write,
+};
+
+static struct miscdevice nuc900wdt_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &nuc900wdt_fops,
+};
+
+static int __devinit nuc900wdt_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+
+	nuc900_wdt = kzalloc(sizeof(struct nuc900_wdt), GFP_KERNEL);
+	if (!nuc900_wdt)
+		return -ENOMEM;
+
+	nuc900_wdt->pdev = pdev;
+
+	spin_lock_init(&nuc900_wdt->wdt_lock);
+
+	nuc900_wdt->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (nuc900_wdt->res == NULL) {
+		dev_err(&pdev->dev, "no memory resource specified\n");
+		ret = -ENOENT;
+		goto err_get;
+	}
+
+	if (!request_mem_region(nuc900_wdt->res->start,
+				resource_size(nuc900_wdt->res), pdev->name)) {
+		dev_err(&pdev->dev, "failed to get memory region\n");
+		ret = -ENOENT;
+		goto err_get;
+	}
+
+	nuc900_wdt->wdt_base = ioremap(nuc900_wdt->res->start,
+					resource_size(nuc900_wdt->res));
+	if (nuc900_wdt->wdt_base == NULL) {
+		dev_err(&pdev->dev, "failed to ioremap() region\n");
+		ret = -EINVAL;
+		goto err_req;
+	}
+
+	nuc900_wdt->wdt_clock = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(nuc900_wdt->wdt_clock)) {
+		dev_err(&pdev->dev, "failed to find watchdog clock source\n");
+		ret = PTR_ERR(nuc900_wdt->wdt_clock);
+		goto err_map;
+	}
+
+	clk_enable(nuc900_wdt->wdt_clock);
+
+	setup_timer(&nuc900_wdt->timer, nuc900_wdt_timer_ping, 0);
+
+	if (misc_register(&nuc900wdt_miscdev)) {
+		dev_err(&pdev->dev, "err register miscdev on minor=%d (%d)\n",
+			WATCHDOG_MINOR, ret);
+		goto err_clk;
+	}
+
+	return 0;
+
+err_clk:
+	clk_disable(nuc900_wdt->wdt_clock);
+	clk_put(nuc900_wdt->wdt_clock);
+err_map:
+	iounmap(nuc900_wdt->wdt_base);
+err_req:
+	release_mem_region(nuc900_wdt->res->start,
+					resource_size(nuc900_wdt->res));
+err_get:
+	kfree(nuc900_wdt);
+	return ret;
+}
+
+static int __devexit nuc900wdt_remove(struct platform_device *pdev)
+{
+	misc_deregister(&nuc900wdt_miscdev);
+
+	clk_disable(nuc900_wdt->wdt_clock);
+	clk_put(nuc900_wdt->wdt_clock);
+
+	iounmap(nuc900_wdt->wdt_base);
+
+	release_mem_region(nuc900_wdt->res->start,
+					resource_size(nuc900_wdt->res));
+
+	kfree(nuc900_wdt);
+
+	return 0;
+}
+
+static struct platform_driver nuc900wdt_driver = {
+	.probe		= nuc900wdt_probe,
+	.remove		= __devexit_p(nuc900wdt_remove),
+	.driver		= {
+		.name	= "nuc900-wdt",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init nuc900_wdt_init(void)
+{
+	return platform_driver_register(&nuc900wdt_driver);
+}
+
+static void __exit nuc900_wdt_exit(void)
+{
+	platform_driver_unregister(&nuc900wdt_driver);
+}
+
+module_init(nuc900_wdt_init);
+module_exit(nuc900_wdt_exit);
+
+MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
+MODULE_DESCRIPTION("Watchdog driver for NUC900");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:nuc900-wdt");
diff --git a/drivers/watchdog/rm9k_wdt.c b/drivers/watchdog/rm9k_wdt.c
index 2e44426..bb66958 100644
--- a/drivers/watchdog/rm9k_wdt.c
+++ b/drivers/watchdog/rm9k_wdt.c
@@ -340,7 +340,7 @@ static const struct resource *wdt_gpi_get_resource(struct platform_device *pdv,
 					const char *name, unsigned int type)
 {
 	char buf[80];
-	if (snprintf(buf, sizeof buf, "%s_0", name) >= sizeof buf)
+	if (snprintf(buf, sizeof(buf), "%s_0", name) >= sizeof(buf))
 		return NULL;
 	return platform_get_resource_byname(pdv, type, buf);
 }
diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c
new file mode 100644
index 0000000..852ca19
--- /dev/null
+++ b/drivers/watchdog/sbc_fitpc2_wdt.c
@@ -0,0 +1,267 @@
+/*
+ * Watchdog driver for SBC-FITPC2 board
+ *
+ * Author: Denis Turischev <denis@compulab.co.il>
+ *
+ * Adapted from the IXP2000 watchdog driver by Deepak Saxena.
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME " WATCHDOG: " fmt
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/dmi.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <asm/system.h>
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+static unsigned int margin = 60;	/* (secs) Default is 1 minute */
+static unsigned long wdt_status;
+static DEFINE_SPINLOCK(wdt_lock);
+
+#define WDT_IN_USE		0
+#define WDT_OK_TO_CLOSE		1
+
+#define COMMAND_PORT		0x4c
+#define DATA_PORT		0x48
+
+#define IFACE_ON_COMMAND	1
+#define REBOOT_COMMAND		2
+
+#define WATCHDOG_NAME 		"SBC-FITPC2 Watchdog"
+
+static void wdt_send_data(unsigned char command, unsigned char data)
+{
+	outb(command, COMMAND_PORT);
+	mdelay(100);
+	outb(data, DATA_PORT);
+	mdelay(200);
+}
+
+static void wdt_enable(void)
+{
+	spin_lock(&wdt_lock);
+	wdt_send_data(IFACE_ON_COMMAND, 1);
+	wdt_send_data(REBOOT_COMMAND, margin);
+	spin_unlock(&wdt_lock);
+}
+
+static void wdt_disable(void)
+{
+	spin_lock(&wdt_lock);
+	wdt_send_data(IFACE_ON_COMMAND, 0);
+	wdt_send_data(REBOOT_COMMAND, 0);
+	spin_unlock(&wdt_lock);
+}
+
+static int fitpc2_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(WDT_IN_USE, &wdt_status))
+		return -EBUSY;
+
+	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+	wdt_enable();
+
+	return nonseekable_open(inode, file);
+}
+
+static ssize_t fitpc2_wdt_write(struct file *file, const char *data,
+						size_t len, loff_t *ppos)
+{
+	size_t i;
+
+	if (!len)
+		return 0;
+
+	if (nowayout) {
+		len = 0;
+		goto out;
+	}
+
+	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+	for (i = 0; i != len; i++) {
+		char c;
+
+		if (get_user(c, data + i))
+			return -EFAULT;
+
+		if (c == 'V')
+			set_bit(WDT_OK_TO_CLOSE, &wdt_status);
+	}
+
+out:
+	wdt_enable();
+
+	return len;
+}
+
+
+static struct watchdog_info ident = {
+	.options	= WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT |
+				WDIOF_KEEPALIVEPING,
+	.identity	= WATCHDOG_NAME,
+};
+
+
+static long fitpc2_wdt_ioctl(struct file *file, unsigned int cmd,
+							unsigned long arg)
+{
+	int ret = -ENOTTY;
+	int time;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		ret = copy_to_user((struct watchdog_info *)arg, &ident,
+				   sizeof(ident)) ? -EFAULT : 0;
+		break;
+
+	case WDIOC_GETSTATUS:
+		ret = put_user(0, (int *)arg);
+		break;
+
+	case WDIOC_GETBOOTSTATUS:
+		ret = put_user(0, (int *)arg);
+		break;
+
+	case WDIOC_KEEPALIVE:
+		wdt_enable();
+		ret = 0;
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		ret = get_user(time, (int *)arg);
+		if (ret)
+			break;
+
+		if (time < 31 || time > 255) {
+			ret = -EINVAL;
+			break;
+		}
+
+		margin = time;
+		wdt_enable();
+		/* Fall through */
+
+	case WDIOC_GETTIMEOUT:
+		ret = put_user(margin, (int *)arg);
+		break;
+	}
+
+	return ret;
+}
+
+static int fitpc2_wdt_release(struct inode *inode, struct file *file)
+{
+	if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) {
+		wdt_disable();
+		pr_info("Device disabled\n");
+	} else {
+		pr_warning("Device closed unexpectedly -"
+			" timer will not stop\n");
+		wdt_enable();
+	}
+
+	clear_bit(WDT_IN_USE, &wdt_status);
+	clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
+
+	return 0;
+}
+
+
+static const struct file_operations fitpc2_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= fitpc2_wdt_write,
+	.unlocked_ioctl	= fitpc2_wdt_ioctl,
+	.open		= fitpc2_wdt_open,
+	.release	= fitpc2_wdt_release,
+};
+
+static struct miscdevice fitpc2_wdt_miscdev = {
+	.minor		= WATCHDOG_MINOR,
+	.name		= "watchdog",
+	.fops		= &fitpc2_wdt_fops,
+};
+
+static int __init fitpc2_wdt_init(void)
+{
+	int err;
+
+	if (strcmp("SBC-FITPC2", dmi_get_system_info(DMI_BOARD_NAME))) {
+		pr_info("board name is: %s. Should be SBC-FITPC2\n",
+			dmi_get_system_info(DMI_BOARD_NAME));
+		return -ENODEV;
+	}
+
+	if (!request_region(COMMAND_PORT, 1, WATCHDOG_NAME)) {
+		pr_err("I/O address 0x%04x already in use\n", COMMAND_PORT);
+		return -EIO;
+	}
+
+	if (!request_region(DATA_PORT, 1, WATCHDOG_NAME)) {
+		pr_err("I/O address 0x%04x already in use\n", DATA_PORT);
+		err = -EIO;
+		goto err_data_port;
+	}
+
+	if (margin < 31 || margin > 255) {
+		pr_err("margin must be in range 31 - 255"
+		       " seconds, you tried to set %d\n", margin);
+		err = -EINVAL;
+		goto err_margin;
+	}
+
+	err = misc_register(&fitpc2_wdt_miscdev);
+	if (!err) {
+		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
+							WATCHDOG_MINOR, err);
+		goto err_margin;
+	}
+
+	return 0;
+
+err_margin:
+	release_region(DATA_PORT, 1);
+err_data_port:
+	release_region(COMMAND_PORT, 1);
+
+	return err;
+}
+
+static void __exit fitpc2_wdt_exit(void)
+{
+	misc_deregister(&fitpc2_wdt_miscdev);
+	release_region(DATA_PORT, 1);
+	release_region(COMMAND_PORT, 1);
+}
+
+module_init(fitpc2_wdt_init);
+module_exit(fitpc2_wdt_exit);
+
+MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
+MODULE_DESCRIPTION("SBC-FITPC2 Watchdog");
+
+module_param(margin, int, 0);
+MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)");
+
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c
index b5e19c1..c01daca 100644
--- a/drivers/watchdog/sc1200wdt.c
+++ b/drivers/watchdog/sc1200wdt.c
@@ -197,7 +197,7 @@ static long sc1200wdt_ioctl(struct file *file, unsigned int cmd,
 
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		if (copy_to_user(argp, &ident, sizeof ident))
+		if (copy_to_user(argp, &ident, sizeof(ident)))
 			return -EFAULT;
 		return 0;
 
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index 7a1bdc7..f368dd8 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -80,7 +80,7 @@ static unsigned long open_lock;
 static DEFINE_SPINLOCK(wdtpci_lock);
 static char expect_close;
 
-static int io;
+static resource_size_t io;
 static int irq;
 
 /* Default timeout */
@@ -647,14 +647,15 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev,
 		goto out_pci;
 	}
 
-	irq = dev->irq;
-	io = pci_resource_start(dev, 2);
-
-	if (request_region(io, 16, "wdt_pci") == NULL) {
-		printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", io);
+	if (pci_request_region(dev, 2, "wdt_pci")) {
+		printk(KERN_ERR PFX "I/O address 0x%llx already in use\n",
+			(unsigned long long)pci_resource_start(dev, 2));
 		goto out_pci;
 	}
 
+	irq = dev->irq;
+	io = pci_resource_start(dev, 2);
+
 	if (request_irq(irq, wdtpci_interrupt, IRQF_DISABLED | IRQF_SHARED,
 			 "wdt_pci", &wdtpci_miscdev)) {
 		printk(KERN_ERR PFX "IRQ %d is not free\n", irq);
@@ -662,8 +663,8 @@ static int __devinit wdtpci_init_one(struct pci_dev *dev,
 	}
 
 	printk(KERN_INFO
-	 "PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n",
-								io, irq);
+	 "PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%llx (Interrupt %d)\n",
+					(unsigned long long)io, irq);
 
 	/* Check that the heartbeat value is within its range;
 	   if not reset to the default */
@@ -717,7 +718,7 @@ out_rbt:
 out_irq:
 	free_irq(irq, &wdtpci_miscdev);
 out_reg:
-	release_region(io, 16);
+	pci_release_region(dev, 2);
 out_pci:
 	pci_disable_device(dev);
 	goto out;
@@ -733,7 +734,7 @@ static void __devexit wdtpci_remove_one(struct pci_dev *pdev)
 		misc_deregister(&temp_miscdev);
 	unregister_reboot_notifier(&wdtpci_notifier);
 	free_irq(irq, &wdtpci_miscdev);
-	release_region(io, 16);
+	pci_release_region(pdev, 2);
 	pci_disable_device(pdev);
 	dev_count--;
 }
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
new file mode 100644
index 0000000..775bcd8
--- /dev/null
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -0,0 +1,441 @@
+/*
+ * Watchdog driver for the wm831x PMICs
+ *
+ * Copyright (C) 2009 Wolfson Microelectronics
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+#include <linux/uaccess.h>
+#include <linux/gpio.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/watchdog.h>
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+		 "Watchdog cannot be stopped once started (default="
+		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static unsigned long wm831x_wdt_users;
+static struct miscdevice wm831x_wdt_miscdev;
+static int wm831x_wdt_expect_close;
+static DEFINE_MUTEX(wdt_mutex);
+static struct wm831x *wm831x;
+static unsigned int update_gpio;
+static unsigned int update_state;
+
+/* We can't use the sub-second values here but they're included
+ * for completeness.  */
+static struct {
+	int time;  /* Seconds */
+	u16 val;   /* WDOG_TO value */
+} wm831x_wdt_cfgs[] = {
+	{  1, 2 },
+	{  2, 3 },
+	{  4, 4 },
+	{  8, 5 },
+	{ 16, 6 },
+	{ 32, 7 },
+	{ 33, 7 },  /* Actually 32.768s so include both, others round down */
+};
+
+static int wm831x_wdt_set_timeout(struct wm831x *wm831x, u16 value)
+{
+	int ret;
+
+	mutex_lock(&wdt_mutex);
+
+	ret = wm831x_reg_unlock(wm831x);
+	if (ret == 0) {
+		ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG,
+				      WM831X_WDOG_TO_MASK, value);
+		wm831x_reg_lock(wm831x);
+	} else {
+		dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
+			ret);
+	}
+
+	mutex_unlock(&wdt_mutex);
+
+	return ret;
+}
+
+static int wm831x_wdt_start(struct wm831x *wm831x)
+{
+	int ret;
+
+	mutex_lock(&wdt_mutex);
+
+	ret = wm831x_reg_unlock(wm831x);
+	if (ret == 0) {
+		ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG,
+				      WM831X_WDOG_ENA, WM831X_WDOG_ENA);
+		wm831x_reg_lock(wm831x);
+	} else {
+		dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
+			ret);
+	}
+
+	mutex_unlock(&wdt_mutex);
+
+	return ret;
+}
+
+static int wm831x_wdt_stop(struct wm831x *wm831x)
+{
+	int ret;
+
+	mutex_lock(&wdt_mutex);
+
+	ret = wm831x_reg_unlock(wm831x);
+	if (ret == 0) {
+		ret = wm831x_set_bits(wm831x, WM831X_WATCHDOG,
+				      WM831X_WDOG_ENA, 0);
+		wm831x_reg_lock(wm831x);
+	} else {
+		dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
+			ret);
+	}
+
+	mutex_unlock(&wdt_mutex);
+
+	return ret;
+}
+
+static int wm831x_wdt_kick(struct wm831x *wm831x)
+{
+	int ret;
+	u16 reg;
+
+	mutex_lock(&wdt_mutex);
+
+	if (update_gpio) {
+		gpio_set_value_cansleep(update_gpio, update_state);
+		update_state = !update_state;
+		ret = 0;
+		goto out;
+	}
+
+
+	reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
+
+	if (!(reg & WM831X_WDOG_RST_SRC)) {
+		dev_err(wm831x->dev, "Hardware watchdog update unsupported\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	reg |= WM831X_WDOG_RESET;
+
+	ret = wm831x_reg_unlock(wm831x);
+	if (ret == 0) {
+		ret = wm831x_reg_write(wm831x, WM831X_WATCHDOG, reg);
+		wm831x_reg_lock(wm831x);
+	} else {
+		dev_err(wm831x->dev, "Failed to unlock security key: %d\n",
+			ret);
+	}
+
+out:
+	mutex_unlock(&wdt_mutex);
+
+	return ret;
+}
+
+static int wm831x_wdt_open(struct inode *inode, struct file *file)
+{
+	int ret;
+
+	if (!wm831x)
+		return -ENODEV;
+
+	if (test_and_set_bit(0, &wm831x_wdt_users))
+		return -EBUSY;
+
+	ret = wm831x_wdt_start(wm831x);
+	if (ret != 0)
+		return ret;
+
+	return nonseekable_open(inode, file);
+}
+
+static int wm831x_wdt_release(struct inode *inode, struct file *file)
+{
+	if (wm831x_wdt_expect_close)
+		wm831x_wdt_stop(wm831x);
+	else {
+		dev_warn(wm831x->dev, "Watchdog device closed uncleanly\n");
+		wm831x_wdt_kick(wm831x);
+	}
+
+	clear_bit(0, &wm831x_wdt_users);
+
+	return 0;
+}
+
+static ssize_t wm831x_wdt_write(struct file *file,
+				const char __user *data, size_t count,
+				loff_t *ppos)
+{
+	size_t i;
+
+	if (count) {
+		wm831x_wdt_kick(wm831x);
+
+		if (!nowayout) {
+			/* In case it was set long ago */
+			wm831x_wdt_expect_close = 0;
+
+			/* scan to see whether or not we got the magic
+			   character */
+			for (i = 0; i != count; i++) {
+				char c;
+				if (get_user(c, data + i))
+					return -EFAULT;
+				if (c == 'V')
+					wm831x_wdt_expect_close = 42;
+			}
+		}
+	}
+	return count;
+}
+
+static struct watchdog_info ident = {
+	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+	.identity = "WM831x Watchdog",
+};
+
+static long wm831x_wdt_ioctl(struct file *file, unsigned int cmd,
+			     unsigned long arg)
+{
+	int ret = -ENOTTY, time, i;
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+	u16 reg;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		ret = copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
+		break;
+
+	case WDIOC_GETSTATUS:
+	case WDIOC_GETBOOTSTATUS:
+		ret = put_user(0, p);
+		break;
+
+	case WDIOC_SETOPTIONS:
+	{
+		int options;
+
+		if (get_user(options, p))
+			return -EFAULT;
+
+		ret = -EINVAL;
+
+		/* Setting both simultaneously means at least one must fail */
+		if (options == WDIOS_DISABLECARD)
+			ret = wm831x_wdt_start(wm831x);
+
+		if (options == WDIOS_ENABLECARD)
+			ret = wm831x_wdt_stop(wm831x);
+		break;
+	}
+
+	case WDIOC_KEEPALIVE:
+		ret = wm831x_wdt_kick(wm831x);
+		break;
+
+	case WDIOC_SETTIMEOUT:
+		ret = get_user(time, p);
+		if (ret)
+			break;
+
+		if (time == 0) {
+			if (nowayout)
+				ret = -EINVAL;
+			else
+				wm831x_wdt_stop(wm831x);
+			break;
+		}
+
+		for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
+			if (wm831x_wdt_cfgs[i].time == time)
+				break;
+		if (i == ARRAY_SIZE(wm831x_wdt_cfgs))
+			ret = -EINVAL;
+		else
+			ret = wm831x_wdt_set_timeout(wm831x,
+						     wm831x_wdt_cfgs[i].val);
+		break;
+
+	case WDIOC_GETTIMEOUT:
+		reg = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
+		reg &= WM831X_WDOG_TO_MASK;
+		for (i = 0; i < ARRAY_SIZE(wm831x_wdt_cfgs); i++)
+			if (wm831x_wdt_cfgs[i].val == reg)
+				break;
+		if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) {
+			dev_warn(wm831x->dev,
+				 "Unknown watchdog configuration: %x\n", reg);
+			ret = -EINVAL;
+		} else
+			ret = put_user(wm831x_wdt_cfgs[i].time, p);
+
+	}
+
+	return ret;
+}
+
+static const struct file_operations wm831x_wdt_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.write = wm831x_wdt_write,
+	.unlocked_ioctl = wm831x_wdt_ioctl,
+	.open = wm831x_wdt_open,
+	.release = wm831x_wdt_release,
+};
+
+static struct miscdevice wm831x_wdt_miscdev = {
+	.minor = WATCHDOG_MINOR,
+	.name = "watchdog",
+	.fops = &wm831x_wdt_fops,
+};
+
+static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
+{
+	struct wm831x_pdata *chip_pdata;
+	struct wm831x_watchdog_pdata *pdata;
+	int reg, ret;
+
+	wm831x = dev_get_drvdata(pdev->dev.parent);
+
+	ret = wm831x_reg_read(wm831x, WM831X_WATCHDOG);
+	if (ret < 0) {
+		dev_err(wm831x->dev, "Failed to read watchdog status: %d\n",
+			ret);
+		goto err;
+	}
+	reg = ret;
+
+	if (reg & WM831X_WDOG_DEBUG)
+		dev_warn(wm831x->dev, "Watchdog is paused\n");
+
+	/* Apply any configuration */
+	if (pdev->dev.parent->platform_data) {
+		chip_pdata = pdev->dev.parent->platform_data;
+		pdata = chip_pdata->watchdog;
+	} else {
+		pdata = NULL;
+	}
+
+	if (pdata) {
+		reg &= ~(WM831X_WDOG_SECACT_MASK | WM831X_WDOG_PRIMACT_MASK |
+			 WM831X_WDOG_RST_SRC);
+
+		reg |= pdata->primary << WM831X_WDOG_PRIMACT_SHIFT;
+		reg |= pdata->secondary << WM831X_WDOG_SECACT_SHIFT;
+		reg |= pdata->software << WM831X_WDOG_RST_SRC_SHIFT;
+
+		if (pdata->update_gpio) {
+			ret = gpio_request(pdata->update_gpio,
+					   "Watchdog update");
+			if (ret < 0) {
+				dev_err(wm831x->dev,
+					"Failed to request update GPIO: %d\n",
+					ret);
+				goto err;
+			}
+
+			ret = gpio_direction_output(pdata->update_gpio, 0);
+			if (ret != 0) {
+				dev_err(wm831x->dev,
+					"gpio_direction_output returned: %d\n",
+					ret);
+				goto err_gpio;
+			}
+
+			update_gpio = pdata->update_gpio;
+
+			/* Make sure the watchdog takes hardware updates */
+			reg |= WM831X_WDOG_RST_SRC;
+		}
+
+		ret = wm831x_reg_unlock(wm831x);
+		if (ret == 0) {
+			ret = wm831x_reg_write(wm831x, WM831X_WATCHDOG, reg);
+			wm831x_reg_lock(wm831x);
+		} else {
+			dev_err(wm831x->dev,
+				"Failed to unlock security key: %d\n", ret);
+			goto err_gpio;
+		}
+	}
+
+	wm831x_wdt_miscdev.parent = &pdev->dev;
+
+	ret = misc_register(&wm831x_wdt_miscdev);
+	if (ret != 0) {
+		dev_err(wm831x->dev, "Failed to register miscdev: %d\n", ret);
+		goto err_gpio;
+	}
+
+	return 0;
+
+err_gpio:
+	if (update_gpio) {
+		gpio_free(update_gpio);
+		update_gpio = 0;
+	}
+err:
+	return ret;
+}
+
+static int __devexit wm831x_wdt_remove(struct platform_device *pdev)
+{
+	if (update_gpio) {
+		gpio_free(update_gpio);
+		update_gpio = 0;
+	}
+
+	misc_deregister(&wm831x_wdt_miscdev);
+
+	return 0;
+}
+
+static struct platform_driver wm831x_wdt_driver = {
+	.probe = wm831x_wdt_probe,
+	.remove = __devexit_p(wm831x_wdt_remove),
+	.driver = {
+		.name = "wm831x-watchdog",
+	},
+};
+
+static int __init wm831x_wdt_init(void)
+{
+	return platform_driver_register(&wm831x_wdt_driver);
+}
+module_init(wm831x_wdt_init);
+
+static void __exit wm831x_wdt_exit(void)
+{
+	platform_driver_unregister(&wm831x_wdt_driver);
+}
+module_exit(wm831x_wdt_exit);
+
+MODULE_AUTHOR("Mark Brown");
+MODULE_DESCRIPTION("WM831x Watchdog");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm831x-watchdog");
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index ec2a39b..7c28434 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -1,6 +1,9 @@
 obj-y	+= grant-table.o features.o events.o manage.o
 obj-y	+= xenbus/
 
+nostackp := $(call cc-option, -fno-stack-protector)
+CFLAGS_features.o			:= $(nostackp)
+
 obj-$(CONFIG_HOTPLUG_CPU)	+= cpu_hotplug.o
 obj-$(CONFIG_XEN_XENCOMM)	+= xencomm.o
 obj-$(CONFIG_XEN_BALLOON)	+= balloon.o
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index abad71b..2f57276 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -47,10 +47,10 @@
 static DEFINE_SPINLOCK(irq_mapping_update_lock);
 
 /* IRQ <-> VIRQ mapping. */
-static DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
+static DEFINE_PER_CPU(int [NR_VIRQS], virq_to_irq) = {[0 ... NR_VIRQS-1] = -1};
 
 /* IRQ <-> IPI mapping */
-static DEFINE_PER_CPU(int, ipi_to_irq[XEN_NR_IPIS]) = {[0 ... XEN_NR_IPIS-1] = -1};
+static DEFINE_PER_CPU(int [XEN_NR_IPIS], ipi_to_irq) = {[0 ... XEN_NR_IPIS-1] = -1};
 
 /* Interrupt types. */
 enum xen_irq_type {
@@ -602,6 +602,8 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static DEFINE_PER_CPU(unsigned, xed_nesting_count);
+
 /*
  * Search the CPUs pending events bitmasks.  For each one found, map
  * the event number to an irq, and feed it into do_IRQ() for
@@ -617,7 +619,6 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
 	struct pt_regs *old_regs = set_irq_regs(regs);
 	struct shared_info *s = HYPERVISOR_shared_info;
 	struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
-	static DEFINE_PER_CPU(unsigned, nesting_count);
  	unsigned count;
 
 	exit_idle();
@@ -628,7 +629,7 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
 
 		vcpu_info->evtchn_upcall_pending = 0;
 
-		if (__get_cpu_var(nesting_count)++)
+		if (__get_cpu_var(xed_nesting_count)++)
 			goto out;
 
 #ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
@@ -653,8 +654,8 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
 
 		BUG_ON(!irqs_disabled());
 
-		count = __get_cpu_var(nesting_count);
-		__get_cpu_var(nesting_count) = 0;
+		count = __get_cpu_var(xed_nesting_count);
+		__get_cpu_var(xed_nesting_count) = 0;
 	} while(count != 1);
 
 out:
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c
index af03195..79bedba 100644
--- a/drivers/xen/evtchn.c
+++ b/drivers/xen/evtchn.c
@@ -38,7 +38,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
-#include <linux/errno.h>
 #include <linux/miscdevice.h>
 #include <linux/major.h>
 #include <linux/proc_fs.h>
diff --git a/firmware/Makefile b/firmware/Makefile
index 621de8e..5ea80b1 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,24 +32,45 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
 					 adaptec/starfire_tx.bin
 fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
 fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
-fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-4.8.53.0.fw bnx2x-e1h-4.8.53.0.fw
-fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-4.6.17.fw \
-			     bnx2/bnx2-rv2p-09-4.6.15.fw \
-			     bnx2/bnx2-mips-06-4.6.16.fw \
-			     bnx2/bnx2-rv2p-06-4.6.16.fw
+fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.0.21.0.fw bnx2x-e1h-5.0.21.0.fw
+fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j3.fw \
+			     bnx2/bnx2-rv2p-09-5.0.0.j3.fw \
+			     bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw \
+			     bnx2/bnx2-mips-06-5.0.0.j3.fw \
+			     bnx2/bnx2-rv2p-06-5.0.0.j3.fw
 fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin
 fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin
 fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \
 				   cxgb3/t3c_psram-1.1.0.bin \
-				   cxgb3/t3fw-7.4.0.bin
+				   cxgb3/t3fw-7.4.0.bin \
+				   cxgb3/ael2005_opt_edc.bin \
+				   cxgb3/ael2005_twx_edc.bin \
+				   cxgb3/ael2020_twx_edc.bin
+fw-shipped-$(CONFIG_DRM_MGA) += matrox/g200_warp.fw matrox/g400_warp.fw
+fw-shipped-$(CONFIG_DRM_R128) += r128/r128_cce.bin
+fw-shipped-$(CONFIG_DRM_RADEON) += radeon/R100_cp.bin radeon/R200_cp.bin \
+				   radeon/R300_cp.bin radeon/R420_cp.bin \
+				   radeon/RS690_cp.bin radeon/RS600_cp.bin \
+				   radeon/R520_cp.bin \
+				   radeon/R600_pfp.bin radeon/R600_me.bin \
+				   radeon/RV610_pfp.bin radeon/RV610_me.bin \
+				   radeon/RV630_pfp.bin radeon/RV630_me.bin \
+				   radeon/RV620_pfp.bin radeon/RV620_me.bin \
+				   radeon/RV635_pfp.bin radeon/RV635_me.bin \
+				   radeon/RV670_pfp.bin radeon/RV670_me.bin \
+				   radeon/RS780_pfp.bin radeon/RS780_me.bin \
+				   radeon/RV770_pfp.bin radeon/RV770_me.bin \
+				   radeon/RV730_pfp.bin radeon/RV730_me.bin \
+				   radeon/RV710_pfp.bin radeon/RV710_me.bin
 fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin
 fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
 fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
 			     e100/d102e_ucode.bin
 fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
-fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis
+fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis
 fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
 fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
+fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis
 fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
 fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
 				      advansys/3550.bin advansys/38C0800.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 0f5649a..3f8c4f6 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -418,6 +418,23 @@ License: GPLv2 or OpenIB.org BSD license, no source visible
 
 --------------------------------------------------------------------------
 
+Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter
+
+File: cxgb3/ael2005_opt_edc.bin.ihex
+File: cxgb3/ael2005_twx_edc.bin.ihex
+File: cxgb3/ael2020_twx_edc.bin.ihex
+
+Licence:
+ *	Copyright (c) 2007-2009 NetLogic Microsystems, Inc.
+ *
+ *	Permission is hereby granted for the distribution of this firmware
+ *	data in hexadecimal or equivalent format, provided this copyright
+ *	notice is accompanying it.
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
 Driver: e100 -- Intel PRO/100 Ethernet NIC
 
 File: e100/d101m_ucode.bin
@@ -579,6 +596,7 @@ Found in hex form in kernel source.
 Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter
 
 File: cis/LA-PCM.cis
+      cis/PCMLM28.cis
 
 Licence: GPL
 
@@ -606,6 +624,17 @@ Originally developed by the pcmcia-cs project
 
 --------------------------------------------------------------------------
 
+Driver: SERIAL_8250_CS - Serial PCMCIA adapter
+
+File: cis/MT5634ZLX.cis
+      cis/RS-COM-2P.cis
+
+Licence: GPL
+
+Originally developed by the pcmcia-cs project
+
+--------------------------------------------------------------------------
+
 Driver: PCMCIA_SMC91C92 - SMC 91Cxx PCMCIA
 
 File: ositech/Xilinx7OD.bin
@@ -698,3 +727,124 @@ Found in hex form in kernel source, with the following comment:
    Copyright (c) 1998-2002 by Paul Davis <pbd@op.net>
 
 --------------------------------------------------------------------------
+
+Driver: mga - Matrox G200/G400/G550
+
+File: matrox/g200_warp.fw
+File: matrox/g400_warp.fw
+
+Licence:
+
+Copyright 1999 Matrox Graphics Inc.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: r128 - ATI Rage 128
+
+File: r128/r128_cce.bin
+
+Licence:
+
+Copyright 2000 Advanced Micro Devices, Inc.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+
+Found in decimal form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: radeon - ATI Radeon
+
+File: radeon/R100_cp.bin
+File: radeon/R200_cp.bin
+File: radeon/R300_cp.bin
+File: radeon/R420_cp.bin
+File: radeon/RS600_cp.bin
+File: radeon/RS690_cp.bin
+File: radeon/R520_cp.bin
+File: radeon/R600_pfp.bin
+File: radeon/R600_me.bin
+File: radeon/RV610_pfp.bin
+File: radeon/RV610_me.bin
+File: radeon/RV630_pfp.bin
+File: radeon/RV630_me.bin
+File: radeon/RV620_pfp.bin
+File: radeon/RV620_me.bin
+File: radeon/RV635_pfp.bin
+File: radeon/RV635_me.bin
+File: radeon/RV670_pfp.bin
+File: radeon/RV670_me.bin
+File: radeon/RS780_pfp.bin
+File: radeon/RS780_me.bin
+File: radeon/RV770_pfp.bin
+File: radeon/RV770_me.bin
+File: radeon/RV730_pfp.bin
+File: radeon/RV730_me.bin
+File: radeon/RV710_pfp.bin
+File: radeon/RV710_me.bin
+
+Licence:
+
+ * Copyright 2007-2009 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
diff --git a/firmware/bnx2/bnx2-mips-06-4.6.16.fw.ihex b/firmware/bnx2/bnx2-mips-06-4.6.16.fw.ihex
deleted file mode 100644
index 0df10b5..0000000
--- a/firmware/bnx2/bnx2-mips-06-4.6.16.fw.ihex
+++ /dev/null
@@ -1,5805 +0,0 @@
-:10000000080000F80800000000004DA4000000C82F
-:1000100000000000000000000000000008004DA4E7
-:100020000000001400004E6C080000800800000072
-:10003000000056CC00004E800800582000000084CC
-:100040000000A54C080056CC000001340000A5D0EB
-:10005000080031D808000000000070DC0000A70490
-:10006000000000000000000000000000080070DC3C
-:1000700000000024000117E00800048808000400C4
-:100080000000175C000118040000000000000000E0
-:100090000000000000000000000000000000000060
-:1000A000080000980800000000003A7400012F606A
-:1000B0000000000000000000000000000000000040
-:0800C000000000000000000038
-:0800C8000A00003E00000000E8
-:1000D000000000000000000D636F6D342E362E31DD
-:1000E00036000000040610020000000000000003BB
-:1000F00000000014000000320000000300000000B7
-:1001000000000000000000000000000000000000EF
-:1001100000000010000001360000EA60000000014D
-:1001200000000000000000000000000000000008C7
-:1001300000000000000000000000000000000000BF
-:1001400000000000000000000000000000000000AF
-:10015000000000000000000000000000000000009F
-:10016000000000020000000000000000000000008D
-:10017000000000000000000000000000000000007F
-:10018000000000000000000000000010000000005F
-:10019000000000000000000000000000000000005F
-:1001A000000000000000000000000000000000004F
-:1001B000000000000000000000000000000000003F
-:1001C0000000000010000003000000000000000D0F
-:1001D0000000000D3C02080024424DE03C030800F2
-:1001E00024634ED4AC4000000043202B1480FFFD5C
-:1001F000244200043C1D080037BD7FFC03A0F02111
-:100200003C100800261000F83C1C0800279C4DE01C
-:100210000E0002AA000000000000000D3C03601068
-:100220008C6450002402FF7F3C1A8000008220244E
-:100230003484380C24020037AC645000AF4200080C
-:1002400024020C80AF4200243C1B80083C060800BE
-:1002500024C6079C3C02080024424E182404001BBC
-:100260002484FFFFAC4600000481FFFD244200040B
-:100270003C020800244203803C010800AC224E20CE
-:100280003C020800244206803C010800AC224E24B7
-:100290003C02080024420D803C010800AC224E6064
-:1002A0003C02080024420A103C03080024630908A9
-:1002B0003C040800248409443C05080024A53C248F
-:1002C0003C010800AC224E683C0208002442057044
-:1002D0003C010800AC264E643C010800AC254E747D
-:1002E0003C010800AC234E7C3C010800AC224E804F
-:1002F0003C010800AC244E843C010800AC234E1C99
-:100300003C010800AC204E283C010800AC204E2CDB
-:100310003C010800AC204E303C010800AC204E34BB
-:100320003C010800AC204E383C010800AC204E3C9B
-:100330003C010800AC204E403C010800AC244E4477
-:100340003C010800AC204E483C010800AC204E4C5B
-:100350003C010800AC204E503C010800AC204E543B
-:100360003C010800AC204E583C010800AC264E5C15
-:100370003C010800AC204E6C3C010800AC254E70DE
-:100380003C010800AC234E780A0006F4000000008F
-:100390003C0308008C6300208F8200081043000398
-:1003A000000000000A00052CAF83000803E00008ED
-:1003B0000000000027BDFFE8AFB00010AFBF001481
-:1003C00027500100920200091040001A2403000186
-:1003D0003C0208008C42002010400016000018214A
-:1003E0000E00056400000000960300083C060800AB
-:1003F00094C64E968E0400188F8200209605000C3D
-:1004000000031C0000661825AC440000AC45000445
-:1004100024040001AC400008AC40000CAC400010CB
-:10042000AC400014AC4000180E000589AC43001C21
-:10043000000018218FBF00148FB000100060102141
-:1004400003E0000827BD001827BDFFE8AFBF00107C
-:100450009742010830437000240220001062000A15
-:1004600028642001548000128FBF00102402400035
-:1004700010620008240260001062000A8FBF0010A2
-:100480000A0000FB000010218FBF00100A0000BB13
-:1004900027BD00180E0003F6000000000A0000FA55
-:1004A0008FBF00100E000FB6000000008FBF0010BD
-:1004B0000000102103E0000827BD00183C020800DE
-:1004C0008C42002027BDFFE810400027AFBF00107E
-:1004D0000E00056400000000974201089743010CDC
-:1004E0008F8500203042003E3063FFFF0002140081
-:1004F00000431025ACA200008F4201003C0608001A
-:1005000094C64E968FBF0010ACA20004974301160C
-:100510009744010E3C02200000031C003084FFFFC2
-:1005200000641825ACA3000800C2302597420110D2
-:100530009743011224040001000214003063FFFFFE
-:1005400000431025ACA2000C9742011427BD0018EF
-:100550003042FFFFACA20010ACA00014ACA0001809
-:100560000A000589ACA6001C8FBF001003E000083C
-:1005700027BD00183C0208008C42002027BDFFE880
-:100580001040002AAFBF00100E00056400000000FC
-:10059000974201089743010C8F8500203042003EAE
-:1005A0003063FFFF0002140000431025ACA20000DE
-:1005B0008F4201003C06080094C64E968FBF001083
-:1005C000ACA20004974301169744010E3C022000A0
-:1005D00000031C003084FFFF00641825ACA3000852
-:1005E00000C23025974201109743011224040001F4
-:1005F000000214003063FFFF00431025ACA2000C82
-:100600009742011427BD00183042FFFFACA2001032
-:100610008F420118ACA200149342010B304200FF3C
-:10062000ACA200180A000589ACA6001C8FBF001000
-:1006300003E0000827BD001827BDFFE0AFB00010A1
-:10064000AFBF0018AFB10014275001009203000B98
-:100650002402001A961100081462003500002021BF
-:100660003222000110400009000000008E0200004C
-:1006700096030014000211C200021040005A10211B
-:10068000A44300800A000179322200020E00012BEF
-:10069000000000003C0208008C420040244200019F
-:1006A0003C010800AC220040322200020002202B54
-:1006B0003C0208008C420044322300042442000122
-:1006C0003C010800AC2200441060001A8FBF0018E3
-:1006D0008F4202B804410008240400013C020800D3
-:1006E0008C420060244200013C010800AC22006002
-:1006F0000A00019C8FB100148E02002096030016A0
-:1007000000002021AF4202808E020004A743028431
-:10071000AF4202883C021000AF4202B83C0208001F
-:100720008C42005C244200013C010800AC22005CC9
-:100730008FBF00188FB100148FB0001000801021FF
-:1007400003E0000827BD002027BDFFE0AFB0001088
-:10075000AFBF0018AFB10014275001009203000B87
-:1007600024020003961100081462003500002021C5
-:100770003222000110400009000000008E0200003B
-:1007800096030014000211C200021040005A10210A
-:10079000A44300800A0001BD322200020E0000FDC9
-:1007A000000000003C0208008C420040244200018E
-:1007B0003C010800AC220040322200020002202B43
-:1007C0003C0208008C420044322300042442000111
-:1007D0003C010800AC2200441060001A8FBF0018D2
-:1007E0008F4202B804410008240400013C020800C2
-:1007F0008C420060244200013C010800AC220060F1
-:100800000A0001E08FB100148E020020960300164A
-:1008100000002021AF4202808E020004A743028420
-:10082000AF4202883C021000AF4202B83C0208000E
-:100830008C42005C244200013C010800AC22005CB8
-:100840008FBF00188FB100148FB0001000801021EE
-:1008500003E0000827BD00209362000003E00008C9
-:10086000AF80000403E000080000102127BDFFE86E
-:10087000AFBF0014AFB000108F420100AF420020A4
-:100880008F420104AF4200A89350010B0E0001E417
-:10089000321000FF3C02080024424E18001018805D
-:1008A0002E10001C16000004006210210E0001E74B
-:1008B0000A0001FF000000008C4200000040F8091F
-:1008C00000000000104000053C0240008F4301047E
-:1008D0003C026020AC4300143C024000AF420138AF
-:1008E0003C0208008C4200348FBF00148FB000100F
-:1008F000244200013C010800AC22003403E000085F
-:1009000027BD001827BDFFE8AFBF00108F42014090
-:100910000E0001E4AF4200200E0003800000000042
-:100920003C024000AF4201783C03080024630038D9
-:100930008C6200008FBF001027BD00182442000108
-:1009400003E00008AC62000027BDFFE8AFBF001065
-:100950008F4201800E0001E4AF4200208F430180EE
-:1009600024020F0014620005000000008F4201887D
-:10097000A742009C0A0002393C024000936200003A
-:1009800024030050304200FF144300083C024000A2
-:100990000E00036400000000144000043C0240000C
-:1009A0000E000E42000000003C024000AF4201B8C1
-:1009B0003C0208008C42003C8FBF00102442000122
-:1009C0003C010800AC22003C03E0000827BD0018F1
-:1009D00003E00008000010218F4301048F82001003
-:1009E00010430008000000003C0208008C42008414
-:1009F000244200013C010800AC2200848F42010423
-:100A0000AF82001003E000080000000027BDFFE8EF
-:100A1000AFBF001027440100948200083043000259
-:100A2000304200041040001B000000008F4202B85A
-:100A300004410008240500013C0208008C420060CB
-:100A4000244200013C010800AC2200600A0002813F
-:100A50008FBF00108C820020948300160000282194
-:100A6000AF4202808C820004A7430284AF42028816
-:100A70003C021000AF4202B83C0208008C42005C0D
-:100A8000244200013C010800AC22005C0A00028103
-:100A90008FBF001010600008240500013C02080010
-:100AA0008C420084244200013C010800AC220084F6
-:100AB0000A0002818FBF00108F4401000E00024423
-:100AC00000000000000028218FBF001000A01021AE
-:100AD00003E0000827BD00183C0208008C42008893
-:100AE000274301009465000C244200013C010800EA
-:100AF000AC2200888C64001803451021904540000A
-:100B0000AF4400388C62001C2403FFF800052E005F
-:100B10000043102434420004AF42003C3C02000574
-:100B2000AF420030000000000000000000000000A4
-:100B3000AF450404000000000000000000000000B9
-:100B40003C02000634420001AF42003000000000C9
-:100B500000000000000000008F4200003042001042
-:100B60001040FFFD0000102103E00008000000001D
-:100B700027BDFFE0AFBF0018AFB100140E00005555
-:100B8000AFB000103C028000344200708C42000084
-:100B9000AF8200140E0000B2000000003C02800092
-:100BA000344600703C0308008C6300A03C0208003F
-:100BB0008C4200A4104300048F8400143C01080000
-:100BC000AC2300A4A743009E8CCA00003C0308008D
-:100BD0008C6300BC3C0208008C4200B80144202316
-:100BE00000641821000040210064202B00481021DF
-:100BF000004410213C010800AC2300BC3C0108006B
-:100C0000AC2200B88F510000322200071040FFE1F3
-:100C1000AF8A00148CC600003C0508008CA500BCFF
-:100C20003C0408008C8400B800CA302300A62821A8
-:100C30000000102100A6302B0082202100862021F8
-:100C4000322700013C010800AC2500BC3C01080033
-:100C5000AC2400B810E00021322200028F420100D3
-:100C6000AF4200208F420104AF4200A89342010B23
-:100C70000E0001E4305000FF2E02001C544000041E
-:100C8000001010800E0001E70A0002F800000000CA
-:100C90003C03080024634E18004310218C420000DE
-:100CA0000040F80900000000104000053C02400030
-:100CB0008F4301043C026020AC4300143C0240001E
-:100CC000AF4201383C0208008C420034244200014B
-:100CD0003C010800AC220034322200021040000E19
-:100CE000322200048F4201400E0001E4AF42002096
-:100CF0000E000380000000003C024000AF4201787B
-:100D00003C0208008C420038244200013C010800EB
-:100D1000AC220038322200041040FF9B3C028000CD
-:100D20008F4201800E0001E4AF4200208F4301801A
-:100D300024020F0014620005000000008F420188A9
-:100D4000A742009C0A00032D3C0240009362000071
-:100D500024030050304200FF144300083C024000CE
-:100D60000E00036400000000544000043C024000F8
-:100D70000E000E42000000003C024000AF4201B8ED
-:100D80003C0208008C42003C244200013C01080067
-:100D9000AC22003C0A0002B03C0280003C02900001
-:100DA0003442000100822025AF4400208F42002001
-:100DB0000440FFFE0000000003E000080000000007
-:100DC0003C028000344200010082202503E000083C
-:100DD000AF44002027BDFFE0AFB10014AFB000105A
-:100DE00000808821AFBF00180E00033530B000FF2F
-:100DF0009362007D0220202102028025A370007DE5
-:100E00008F7000743C0280000E00033E02028024BA
-:100E1000160000098FBF00188F4201F80440FFFE42
-:100E200024020002AF5101C0A34201C43C021000E1
-:100E3000AF4201F88FBF00188FB100148FB00010BF
-:100E400003E0000827BD002027BDFFD000001021CF
-:100E500003E0000827BD003027BDFFE8AFBF00104A
-:100E6000974201843042020010400005000020211A
-:100E70000E001079000000000A000378240400012D
-:100E80008F420188044000098FBF00108F42018803
-:100E90003C03FF00004310243C0304001443000300
-:100EA000240400019362003E8FBF001000801021D7
-:100EB00003E0000827BD0018A36000228F44014012
-:100EC0000A0003432405000127BDFFE8AFBF00145B
-:100ED000AFB000109362000024030020304200FFF6
-:100EE0001043000B00000000936200002403003058
-:100EF000304200FF10430006000000009362000033
-:100F000024030050304200FF144300628FBF0014DE
-:100F100093420148304200FF2443FFFF2C6200054A
-:100F20001040005C8FBF0014000310803C030800D9
-:100F300024634DA4004310218C42000000400008AF
-:100F4000000000000E0003358F4401408F70000C3C
-:100F50008F4201441602000224020001AF62000C1D
-:100F60000E00033E8F4401408F42014414500004A0
-:100F70008FBF00148FB000100A000FED27BD0018BE
-:100F80008F62000C0A0003EC000000009762001062
-:100F90008F4301443042FFFF14620009000000004B
-:100FA00024020001A76200108F420140AF420200FC
-:100FB0003C021000AF4202380A0003F38FBF001456
-:100FC000976200100A0003EC000000000E000335D9
-:100FD0008F440140976200128F4301443050FFFF5D
-:100FE0001603000224020001A76200120E00033E55
-:100FF0008F4401408F420144160200048FBF001449
-:101000008FB000100A00037C27BD00189762001201
-:101010000A0003EC00000000976200148F430144B3
-:101020003042FFFF146200068FBF0014240200014B
-:101030008FB00010A76200140A00131927BD001812
-:10104000976200140A0003EC00000000976200168B
-:101050008F4301443042FFFF146200062402000166
-:101060008FBF00148FB00010A76200160A000BE0BB
-:1010700027BD001897620016144000068FBF0014A9
-:101080003C0208008C420070244200013C01080030
-:10109000AC2200708FB0001003E0000827BD0018DC
-:1010A00027BDFFE8AFBF0014AFB0001093430109A4
-:1010B0002402001F8F500100106200A5286200204A
-:1010C00010400018240200382862000A1040000C6A
-:1010D0002402000B286200081040002C00000000D1
-:1010E000046000E728620002144000282402000681
-:1010F000106200268FBF00140A0004F08FB00010A9
-:101100001062005E2862000B144000DE8FBF0014E6
-:101110002402000E106200738FB000100A0004F069
-:1011200000000000106200C2286200391040000A6E
-:101130002402008024020036106200CC28620037AE
-:10114000104000B624020035106200C38FBF0014A7
-:101150000A0004F08FB000101062002B286200819A
-:1011600010400006240200C824020039106200B6B4
-:101170008FBF00140A0004F08FB0001010620099B5
-:101180008FBF00140A0004F08FB000103C0208006A
-:101190008C420020104000BB8FBF00140E0005647D
-:1011A000000000008F4201008F8300209745010C52
-:1011B00097460108AC6200008F4201043C0408001D
-:1011C00094844E9600052C00AC6200048F420118F6
-:1011D0000006340000C43025AC6200088F42011CB8
-:1011E00024040001AC62000C9342010A00A22825ED
-:1011F000AC650010AC600014AC600018AC66001C5C
-:101200000A0004C48FBF00143C0208008C42002076
-:101210001040009C8FBF00140E0005640000000009
-:10122000974401083C03080094634E969745010CCF
-:10123000000422029746010E8F820020000426003F
-:101240000083202500052C003C03008000A62825F3
-:1012500000832025AC400000AC400004AC400008F6
-:10126000AC40000CAC450010AC400014AC40001881
-:10127000AC44001C0A0004C3240400019742010C82
-:101280001440001500000000936200053042001079
-:1012900014400011000000000E0003350200202160
-:1012A0009362000502002021344200100E00033E2C
-:1012B000A36200059362000024030020304200FF77
-:1012C0001043006F020020218FBF00148FB0001068
-:1012D0000A00108F27BD00180000000D0A0004EF5F
-:1012E0008FBF00143C0208008C42002010400065B3
-:1012F0008FBF00140E000564000000008F4201043F
-:101300008F8300209744010C3C05080094A54E965D
-:10131000AC6200009762002C000424003042FFFF02
-:10132000008220253C02400E00A22825AC64000467
-:10133000AC600008AC60000CAC600010AC60001445
-:10134000AC600018AC65001C0A0004C32404000152
-:101350000E00033502002021A76000080E00033EA6
-:1013600002002021020020210E0003432405000179
-:101370003C0208008C420020104000428FBF001445
-:101380000E000564000000009742010C8F830020CE
-:101390003C05080094A54E9600021400AC700000B5
-:1013A000AC620004AC6000088F64004C3C02401F3B
-:1013B00000A22825AC64000C8F62005024040001B8
-:1013C000AC6200108F620054AC620014AC60001874
-:1013D000AC65001C8FBF00148FB000100A00058997
-:1013E00027BD00189362000024030020304200FF54
-:1013F000104300248FBF00140E000FD702002021DD
-:10140000104000208FBF0014020020218FB0001078
-:10141000000028210A00034327BD001802002021F4
-:101420008FBF00148FB000100A00065127BD0018AE
-:101430009745010C020020218FBF00148FB00010CF
-:101440000A00067127BD0018020020218FB000108D
-:101450000A00069627BD00189345010D02002021C1
-:101460008FB000100A0006E027BD001802002021FE
-:101470008FBF00148FB000100A0006BC27BD0018F3
-:101480008FBF00148FB0001003E0000827BD0018C4
-:101490008F4202780440FFFE34820080AF42024057
-:1014A00024020002A34202443C02100003E00008B0
-:1014B000AF4202783C04080094844EA23C0208002B
-:1014C0008C424EAC3083FFFF000318C00043102154
-:1014D000AF42003C3C0208008C424EA8AF420038AC
-:1014E0003C02005034420008AF42003000000000CF
-:1014F00000000000000000008F4200003042002089
-:101500001040FFFD000000008F4204003C01080075
-:10151000AC224E988F4204043C010800AC224E9C41
-:101520003C020020AF420030000000003C020800F6
-:1015300094424EA03C03080094634EA43C0508006E
-:1015400094A54EA624840001004310213083FFFFA0
-:101550003C010800A4224EA03C010800A4244EA295
-:1015600014650003000000003C010800A4204EA206
-:1015700003E00008000000003C05000A27BDFFE86A
-:10158000034528213C04080024844E88AFBF001086
-:101590000E0005EE2406000A3C02080094424E8A22
-:1015A0003C03080094634EA63042000F244200031F
-:1015B0000043180424027FFF0043102B1040000258
-:1015C000AF83001C0000000D0E0004FB00000000B3
-:1015D0003C02080094424E928FBF001027BD0018B5
-:1015E00003E00008A74200A23C02000A03421021C7
-:1015F000944300063C02080094424E923C010800CD
-:10160000A4234E8E004310238F83001C000214007D
-:10161000000214030043102B03E0000838420001CD
-:1016200027BDFFE8AFBF00103C02000A03421021B3
-:10163000944200063C010800A4224E8E0E0005488C
-:10164000000000005440FFF93C02000A8FBF001068
-:1016500003E0000827BD001827BDFFE8AFBF00105A
-:101660000E000548000000001040000300000000CC
-:101670000E000556000000003C0208008C424E9807
-:101680008FBF001027430400AF4200383C0208001F
-:101690008C424E9C27BD0018AF830020AF42003C17
-:1016A0003C020005AF42003003E00008AF800018A4
-:1016B0008F8200183C0300060002114000431025F1
-:1016C000AF420030000000000000000000000000F9
-:1016D0008F420000304200101040FFFD27420400FE
-:1016E000AF82002003E00008AF8000183C0608002D
-:1016F0008CC64E9C8F8500188F8300203C0208000A
-:1017000094424E9227BDFFE024A5000124630020EF
-:101710002442000124C70020AFB10014AFB0001074
-:10172000AFBF0018AF850018AF8300203C01080050
-:10173000A4224E92309000FF3C010800AC274E9C42
-:1017400004C100080000882104E000060000000039
-:101750003C0208008C424E98244200013C010800E3
-:10176000AC224E983C02080094424E923C03080082
-:1017700094634EA00010202B004310262C42000141
-:1017800000441025144000048F8300182402001028
-:101790001462000F000000000E00057A2411000101
-:1017A0003C03080094634E923C02080094424EA011
-:1017B00014620003000000000E0004FB00000000A3
-:1017C00016000003000000000E0005640000000089
-:1017D0003C03080094634E963C02080094424E94E9
-:1017E000246300013064FFFF3C010800A4234E96EF
-:1017F00014820003000000003C010800A4204E9663
-:1018000012000006000000003C02080094424E92C4
-:10181000A74200A20A0005DC022010210E000548A4
-:101820000000000010400004022010210E000556A8
-:1018300000000000022010218FBF00188FB100149B
-:101840008FB0001003E0000827BD00203084FFFFA8
-:1018500030A5FFFF000018211080000700000000E5
-:10186000308200011040000200042042006518216F
-:101870000A0005E40005284003E00008006010218C
-:1018800010C0000624C6FFFF8CA2000024A500049F
-:10189000AC8200000A0005EE2484000403E0000886
-:1018A0000000000010A0000824A3FFFFAC86000089
-:1018B00000000000000000002402FFFF2463FFFF7F
-:1018C0001462FFFA2484000403E000080000000012
-:1018D00024020001AF62000CA7620010A762001290
-:1018E000A762001403E00008A76200163082007FA0
-:1018F000034210213C08000E004818213C02080059
-:101900008C42002027BDFFD82407FF80AFB3001C06
-:10191000AFB20018AFB10014AFB00010AFBF0020DD
-:101920000080802130B100FF0087202430D200FFEA
-:101930001040002F00009821AF44002C906200005E
-:1019400024030050304200FF1443000E000000004A
-:101950003C0208008C4200E00202102100471024E3
-:10196000AF42002C3C0208008C4200E00202102131
-:101970003042007F0342102100481021944200D4DD
-:101980003053FFFF0E000564000000003C02080019
-:1019900094424E968F8300200011340000C23025FF
-:1019A00000122C003C02400000C2302534A500018A
-:1019B000AC7000008FBF0020AC6000048FB2001834
-:1019C000AC7300088FB10014AC60000C8FB3001C26
-:1019D000AC6500108FB00010AC600014240400014E
-:1019E000AC60001827BD00280A000589AC66001C01
-:1019F0008FBF00208FB3001C8FB200188FB100146E
-:101A00008FB0001003E0000827BD00289343010FAA
-:101A1000240200101062000E2865001110A00007BB
-:101A200024020012240200082405003A1062000675
-:101A30000000302103E0000800000000240500350C
-:101A40001462FFFC000030210A00060900000000BB
-:101A50008F42007424420FA003E00008AF62000C24
-:101A600027BDFFE8AFBF00100E00034324050001AF
-:101A70008FBF001024020001A762001227BD0018CA
-:101A80002402000103E00008A360002227BDFFE05C
-:101A9000AFB10014AFB00010AFBF001830B1FFFFFE
-:101AA0000E000335008080219362003F2403000470
-:101AB000304200FF1443000C0200202112200008D5
-:101AC0002402000A0E0006020000000093620005D6
-:101AD0002403FFFE00431024A36200052402001229
-:101AE000A362003F020020210E00033EA36000819C
-:101AF00016200003020020210E00066600000000F0
-:101B000002002021322600FF8FBF00188FB1001481
-:101B10008FB00010240500380A00060927BD0020F8
-:101B200027BDFFE0AFBF001CAFB20018AFB100147B
-:101B3000AFB000100E000335008080210E000602B9
-:101B4000000000009362003F24120018305100FF93
-:101B5000123200030200202124020012A362003F7F
-:101B6000936200052403FFFE004310240E00033E91
-:101B7000A362000502002021240500201632000780
-:101B8000000030218FBF001C8FB200188FB10014ED
-:101B90008FB000100A00034327BD00208FBF001C38
-:101BA0008FB200188FB100148FB0001024050039D7
-:101BB0000A00060927BD002027BDFFE8AFB00010CE
-:101BC000AFBF00149742010C24050036008080212D
-:101BD00014400010304600FF0E00033500000000E6
-:101BE00024020012A362003F9362000534420010F9
-:101BF0000E000602A36200050E00033E0200202133
-:101C0000020020210E000343240500200A0006D50F
-:101C1000000000000E000609000000000E00033561
-:101C200002002021936200232403FF9F0200202151
-:101C3000004310248FBF00148FB00010A362002354
-:101C40000A00033E27BD001827BDFFE0AFBF001804
-:101C5000AFB10014AFB0001030B100FF0E0003357B
-:101C600000808021240200120E000602A362003FC1
-:101C70000E00033E0200202102002021022030211C
-:101C80008FBF00188FB100148FB0001024050035ED
-:101C90000A00060927BD0020A380002C03E00008ED
-:101CA000A380002D8F4202780440FFFE8F82003413
-:101CB000AF42024024020002A34202443C02100050
-:101CC00003E00008AF4202783C0360008C625400DD
-:101CD000304200081440FFFD000000008C625408F0
-:101CE000AF82000024020052AC605408AC6454304F
-:101CF000AC6254342402000803E00008AC625400D3
-:101D00003C0260008C425400304200081040000544
-:101D10003C0360008C625400304200081440FFFD18
-:101D2000000000008F8300003C02600003E0000818
-:101D3000AC43540890A30000240200050080402119
-:101D40003063003F0000482114620005000050216C
-:101D500090A2001C94A3001E304900FF306AFFFFD0
-:101D6000AD00000CAD000010AD0000249502001481
-:101D70008D05001C8D0400183042FFFF0049102320
-:101D800000021100000237C30040382100862023E2
-:101D900000A2102B0082202300A72823AD05001CE1
-:101DA000AD040018A5090014A5090020A50A001615
-:101DB00003E00008A50A00228F4201F80440FFFE5C
-:101DC00024020002AF4401C0A34201C43C0210003F
-:101DD00003E00008AF4201F83C0208008C4200B466
-:101DE00027BDFFE8AFBF001424420001AFB00010D0
-:101DF0003C010800AC2200B48F4300243C02001FC9
-:101E000030AA00FF3442FF8030D800FF00628024F7
-:101E10000080F82130EF00FF1158003B01405821AD
-:101E2000240CFF803C19000A3163007F000310C0BE
-:101E300000031940006218213C0208008C4200DCBB
-:101E400025680001310D007F03E2102100431021BD
-:101E50003043007F03431821004C102400794821AF
-:101E6000AF4200248D220024016C1824006C7026DF
-:101E7000AD22000C8D220024310800FFAD2200109D
-:101E800095220014952300208D27001C3042FFFF6F
-:101E90003063FFFF8D26001800431023000211005D
-:101EA000000227C30040282100C4302300E2102B89
-:101EB00000C2302300E53823AD27001CAD260018F2
-:101EC00095220020A522001495220022154B000A1D
-:101ED000A52200168D2300248D220008254600012E
-:101EE000314500801462000430C4007F108F00026E
-:101EF00038AA008000C0502151AF000131C800FF56
-:101F00001518FFC9010058218F8400343082007FEA
-:101F1000034218213C02000A006218212402FF80BB
-:101F200000822024AF440024A06A0079A06A0083C4
-:101F30008C6200508F840034AC6200708C65007439
-:101F40003C027FFF3442FFFF00A228240E00073C22
-:101F5000AC650074AF5000248FBF00148FB0001028
-:101F600003E0000827BD001827BDFFC0AFBE003842
-:101F7000AFB70034AFB5002CAFB20020AFB1001C3A
-:101F8000AFB00018AFBF003CAFB60030AFB4002810
-:101F9000AFB300248F4500248F4600288F43002CC8
-:101FA0003C02001F3442FF800062182400C230242B
-:101FB0000080A821AFA3001400A2F0240E000700A7
-:101FC000AFA600103C0208008C4200E02410FF8005
-:101FD0000360882102A2102100501024AF42002487
-:101FE0003C0208008C4200E002A210213042007F37
-:101FF000034218213C02000A00629021924200D262
-:1020000093630084305700FF306300FF2402000117
-:1020100010620034036020212402000214620036A2
-:10202000000000000E0012E50240282192230083E8
-:10203000922200833063007F3042007F000210C094
-:1020400000031940006218213C0208008C4200DCA9
-:1020500002A210210043382100F01024AF420028D2
-:10206000922500789224008330E2007F03421821F9
-:102070003C02000C14850007006280212402FFFF4F
-:10208000A24200F12402FFFFA64200F20A0007F874
-:102090002402FFFF96020020A24200F196020022D5
-:1020A000A64200F28E020024AE4200F49222008387
-:1020B000A24200F08E4200C8AE4200FC8E4200C434
-:1020C000AE4200F88E220050AE4201008E4200CC9B
-:1020D000AE420104922200853042003F0A000853BC
-:1020E000344200400E00130802402821922200854D
-:1020F0000A0008533042003F936200852403FFDF4B
-:102100003042003FA36200859362008500431024A3
-:10211000A36200859363008393620078307400FFAC
-:10212000304200FF10540036240AFF803C0C000CA3
-:102130003283007F000310C00003194000621821A1
-:102140003C0208008C4200DC268800013109007F37
-:1021500002A210210043382130E2007F03421821FF
-:1021600000EA1024AF420028006C80218E02002477
-:10217000028A1824006A5826AE02000C8E0200243F
-:10218000310800FFAE0200109602001496030020F2
-:102190008E07001C3042FFFF3063FFFF8E060018E1
-:1021A0000043102300021100000227C30040282131
-:1021B00000C4302300E2102B00C2302300E5382396
-:1021C000AE07001CAE06001896020020A6020014FE
-:1021D00096020022A602001692220079304200FFE9
-:1021E000105400070000000051370001316800FF63
-:1021F00092220078304200FF1448FFCD0100A02158
-:1022000092220083A22200798E2200500A0008B395
-:10221000AE220070A22200858E22004C2405FF8091
-:10222000AE42010C9222008534420020A222008599
-:10223000924200D13C0308008C6300DC305400FF64
-:102240003C0208008C4200E400143140001420C01D
-:1022500002A3182100C4202102A210210064382109
-:10226000004610210045182400E52824AF45002829
-:10227000AF43002C3042007F924400D030E3007F17
-:1022800003422821034318213C02000C00628021F4
-:102290003C02000E309600FF00A298211296002A00
-:1022A000000000008E02000C0200202102602821A4
-:1022B00010400025261000280E00071B000000001B
-:1022C0009262000D26830001307400FF3042007FCF
-:1022D000A262000D2404FF801697FFF026730020F1
-:1022E0003C0208008C4200DC0000A02102A2102168
-:1022F00000441024AF4200283C0208008C4200E455
-:102300003C0308008C6300DC02A21021004410246E
-:10231000AF42002C3C0208008C4200E402A31821CA
-:102320003063007F02A210213042007F034220214F
-:10233000034318213C02000C006280213C02000E85
-:102340000A000875008298218E4200D8AE22005003
-:102350008E4200D8AE22007092250083924600D1B2
-:1023600092230083924400D12402FF8000A22824FB
-:102370003063007F308400FF00A628250064182AFF
-:102380001060000230A500FF38A50080A225008360
-:10239000A22500790E00070E000000009222007EA8
-:1023A00002A02021A222007A8E2300743C027FFF2B
-:1023B0003442FFFF006218240E00073CAE23007475
-:1023C0008FA20010AF5E00248FBF003CAF420028F8
-:1023D0008FBE00388FA200148FB700348FB6003044
-:1023E0008FB5002C8FB400288FB300248FB200204B
-:1023F0008FB1001C8FB0001827BD004003E000081B
-:10240000AF42002C90A2000024420001A0A20000D4
-:102410003C0308008C6300F4304200FF1443000FBB
-:1024200000803021A0A000003C0208008C4200E4A3
-:102430008F840034008220213082007F03421821E3
-:102440003C02000C006218212402FF80008220243C
-:10245000ACC3000003E00008AF4400288C820000F9
-:102460002442002003E00008AC82000094C2000077
-:102470003C080800950800CA30E7FFFF00804821AB
-:1024800001021021A4C2000094C200003042FFFFEC
-:1024900000E2102B54400001A4C7000094A20000E9
-:1024A0003C0308008C6300CC24420001A4A200007D
-:1024B00094A200003042FFFF544300078F8600289B
-:1024C0000107102BA4A00000544000010100382196
-:1024D000A4C700008F8600288CC4001CAF44003CB9
-:1024E00094A200008F43003C3042FFFF000210C066
-:1024F00000621821AF43003C8F42003C0082202341
-:1025000018800004000000008CC200180A000914A2
-:10251000244200018CC20018AF4200383C02005037
-:1025200034420010AF420030000000000000000004
-:10253000000000008F420000304200201040FFFDEC
-:10254000000000008F420404AD2200048F4204000A
-:10255000AD2200003C020020AF42003003E0000842
-:102560000000000027BDFFE0AFB20018AFB10014BB
-:10257000AFB00010AFBF001C94C2000000C08021AB
-:102580003C120800965200C624420001A602000038
-:102590009603000094E2000000E03021144300059F
-:1025A0008FB100300E0008E9024038210A000946C8
-:1025B000000000008C8300048C8200042442004050
-:1025C00004610007AC8200048C8200040440000413
-:1025D000000000008C82000024420001AC82000058
-:1025E000960200003042FFFF50520001A60000009A
-:1025F0009622000024420001A62200008F820028BB
-:102600009623000094420016144300048FBF001C60
-:1026100024020001A62200008FBF001C8FB2001808
-:102620008FB100148FB0001003E0000827BD002018
-:102630008F89002827BDFFE0AFBF00188D2200283A
-:102640002748040030E700FFAF4200388D22002CFD
-:10265000AF880030AF42003C3C020005AF42003082
-:10266000000000000000000000000000000000006A
-:1026700000000000000000008C82000C8C82000C26
-:10268000AD0200008C820010AD0200048C820018A4
-:10269000AD0200088C82001CAD02000C8CA200145C
-:1026A000AD0200108C820020AD0200149082000563
-:1026B000304200FF00021200AD0200188CA2001888
-:1026C000AD02001C8CA2000CAD0200208CA20010F8
-:1026D000AD0200248CA2001CAD0200288CA20020B8
-:1026E000AD02002CAD060030AD000034978300260B
-:1026F0003402FFFF14620002006020213404FFFF57
-:1027000010E00011AD040038952300369524003602
-:10271000240200013063FFFF000318C20069182182
-:1027200090650040308400070082100400451025A9
-:10273000A06200408F820028944200563042FFFF82
-:102740000A0009ADAD02003C952300369524003601
-:10275000240200013063FFFF000318C20069182142
-:1027600090650040308400070082100400021027AA
-:1027700000451024A0620040AD00003C00000000B5
-:1027800000000000000000003C020006344200404F
-:10279000AF42003000000000000000000000000018
-:1027A0008F420000304200101040FFFD8F8600284D
-:1027B000AF88003024C2005624C7003C24C400283F
-:1027C00024C5003224C600360E000927AFA200102F
-:1027D0008FBF001803E0000827BD00208F8300246E
-:1027E0003C0508008CA500E88F82003430633FFF71
-:1027F0000003198000451021004310212403FF80AD
-:102800003045007F00431024AF42002803451821C3
-:102810003C02000C0062302190C2000D0000382103
-:1028200034420010A0C2000D8F8900288F8A002436
-:1028300095230036000A1382304800032402000169
-:10284000A4C3000E1102000B290200021040000573
-:10285000240200021100000C240300010A0009F008
-:102860000000182111020006000000000A0009F013
-:10287000000018218CC2002C0A0009F0244300013A
-:102880008CC20014244300018CC200180043102B9A
-:1028900014400003000000000A0009F924070001A9
-:1028A0009522003E24420001A522003E000A138228
-:1028B000304300032C6200021040000900802821F0
-:1028C000146000040000000094C200360A000A09E7
-:1028D0003046FFFF8CC600380A000A090080282114
-:1028E000000030213C04080024844EB00A00095A3C
-:1028F00000000000274901008D22000C95230006EE
-:1029000001202021000216023045003F3063FFFF06
-:102910002402002728A6002810A2000EAF8300245E
-:1029200010C00008240200312402002110A2000976
-:102930002402002510A200079382002D0A000A2716
-:102940000000000010A200059382002D0A000A2753
-:10295000000000000A0009C5000000000A0006F798
-:102960000000000095230006912400058D25000C31
-:102970008D2600108D2700188D28001C8D29002021
-:10298000244200013C010800A4234EB63C0108008B
-:10299000A0244EB53C010800AC254EBC3C0108000B
-:1029A000AC264EC03C010800AC274EC83C010800D4
-:1029B000AC284ECC3C010800AC294ED003E0000806
-:1029C000A382002D8F87002827BDFFC0AFB300343E
-:1029D000AFB20030AFB1002CAFB00028AFBF0038AD
-:1029E0003C0208008C4200D094E3003030B0FFFF7E
-:1029F000005010073045FFFF3063FFFF00C09821F3
-:102A0000A7A200103C110800963100C614A30006CE
-:102A10003092FFFF8CE2002424420030AF42003CA1
-:102A20000A000A608CE2002094E200323042FFFF8C
-:102A300054A2000827A400188CE2002C2442003085
-:102A4000AF42003C8CE20028AF4200380A000A6E18
-:102A50008F84002827A5001027A6002002203821F7
-:102A60000E0008E9A7A000208FA200182442003021
-:102A7000AF4200388FA2001CAF42003C8F84002878
-:102A80003C020005AF42003094820034274304002A
-:102A90003042FFFF0202102B14400007AF830030CA
-:102AA00094820054948300340202102100431023C6
-:102AB0000A000A823043FFFF94830054948200345A
-:102AC0000223182100501023006218233063FFFFF7
-:102AD000948200163042FFFF144300030000000000
-:102AE0000A000A9024030001948200163042FFFF7E
-:102AF0000043102B104000058F8200309482001696
-:102B0000006210233043FFFF8F820030AC5300007F
-:102B1000AC400004AC520008AC43000C3C02000680
-:102B200034420010AF4200300000000000000000FE
-:102B3000000000008F420000304200101040FFFDF6
-:102B4000001018C20064182190650040320400078C
-:102B5000240200018FBF00388FB300348FB20030E1
-:102B60008FB1002C8FB00028008210040045102582
-:102B700027BD004003E00008A062004027BDFFA879
-:102B8000AFB60050AFB5004CAFB40048AFB300448F
-:102B9000AFB1003CAFBF0054AFB20040AFB000389F
-:102BA0008C9000003C0208008C4200E88F860034C4
-:102BB000960300022413FF8000C2302130633FFFE0
-:102BC0000003198000C3382100F3102490B20000E4
-:102BD000AF42002C9203000230E2007F034230211A
-:102BE0003C02000E00C28821306300C02402004075
-:102BF0000080A82100A0B021146200260000A021BE
-:102C00008E3400388E220018144000022402000185
-:102C1000AE2200189202000D304200201440001530
-:102C20008F8200343C0308008C6300DC001238C043
-:102C3000001231400043102100C7302100463821E6
-:102C400030E300073C02008030E6007800C2302507
-:102C50000343182100F31024AF4208002463090045
-:102C6000AF4608108E2200188C6300080043102124
-:102C7000AE2200188E22002C8E2300182442000160
-:102C80000062182B1060003D000000000A000B4499
-:102C900000000000920300022402FFC00043102441
-:102CA000304200FF1440000524020001AE2200184B
-:102CB000962200360A000B2D3054FFFF8E2200149E
-:102CC00024420001AE220018920200000002160009
-:102CD00000021603044100290000000096020002D1
-:102CE00027A4001000802821A7A200169602000247
-:102CF00024070001000030213042FFFFAF82002492
-:102D00000E00095AAFA0001C960300023C04080004
-:102D10008C8400E88F82003430633FFF0003198009
-:102D200000441021004310213043007F3C05000C7B
-:102D30000053102403431821AF42002800651821D6
-:102D40009062000D001221403042007FA062000D11
-:102D50003C0308008C6300E48F82003400431021A0
-:102D60000044382130E2007F034210210045102149
-:102D700000F31824AF430028AEA200009222000DF9
-:102D8000304200101040001302A020218F83002841
-:102D90008EA40000028030219462003E2442FFFF96
-:102DA000A462003E948400029625000E3084FFFF4A
-:102DB0000E000A3F30A5FFFF8F82002894430034A5
-:102DC0009622000E1443000302A0202124020001D9
-:102DD000A382002C02C028210E0008CF00000000B2
-:102DE0008FBF00548FB600508FB5004C8FB4004891
-:102DF0008FB300448FB200408FB1003C8FB00038D9
-:102E000003E0000827BD00588F85002827BDFFD0AC
-:102E1000AFB40028AFB20020AFBF002CAFB3002486
-:102E2000AFB1001CAFB0001890A800D090A600D1A0
-:102E30003C0208008C4200E48F83003430C700FF5E
-:102E4000A3A600100062182100071140006218219B
-:102E50003062007F034220213C02000C00822021CE
-:102E60002402FF8000621824311200FF8CB100D8C8
-:102E7000AFA400148CB300DC0000A021AF430028F5
-:102E800010F2001F240200018FA6001427A40014D2
-:102E900027A500108CC2000402228021027010239A
-:102EA000044000172402000190C3000D2402FF809B
-:102EB00000431024304200FF144000070200882124
-:102EC00090C2000D344200400E0008CFA0C2000D99
-:102ED0000A000B8B93A200100E000AAD241400010F
-:102EE0008F830028AC7000D893A20010A06200D19C
-:102EF00093A200101452FFE58FA6001424020001D3
-:102F0000168200048FBF002C0E0006F700000000A0
-:102F10008FBF002C8FB400288FB300248FB2002005
-:102F20008FB1001C8FB0001803E0000827BD0030EF
-:102F300027BDFFD8AFB3001CAFB20018AFB100146B
-:102F4000AFB00010AFBF00200080982100E08021CA
-:102F500030B1FFFF0E00056430D200FF000000001A
-:102F600000000000000000008F820020AC51000033
-:102F7000AC520004AC530008AC40000CAC40001054
-:102F8000AC400014AC4000183C03080094634E961B
-:102F900002038025AC50001C00000000000000006F
-:102FA00000000000240400018FBF00208FB3001C2C
-:102FB0008FB200188FB100148FB000100A0005897D
-:102FC00027BD002827BDFFE8AFB00010AFBF001439
-:102FD00030A5FFFF30C600FF0080802124020C8056
-:102FE000AF420024000000000000000000000000CC
-:102FF00000000000000000000E000B9A000000001E
-:103000003C040800248400E08C8200002403FF803C
-:103010008FBF00140202102100431024AF4200248D
-:103020008C8200003C03000A020280213210007FE3
-:10303000035010218FB000100043102127BD00184D
-:1030400003E00008AF82002827BDFFE8AFBF0010F3
-:103050008F4401403C0308008C6300E02402FF80A1
-:10306000AF8400340083182100621024AF42002492
-:103070003C02000803424021950500023063007FB6
-:103080003C02000A034318210062182130A5FFFF0B
-:103090003402FFFF000030213C07602010A2000630
-:1030A000AF8300282402FFFFA5020002946500D42C
-:1030B0000E000BBF30A5FFFF8FBF001024020C8055
-:1030C00027BD001803E00008AF4200243C020008BE
-:1030D00003424021950200023C0A0800954A00C6BE
-:1030E0003046FFFF14C000073402FFFF8F82002824
-:1030F0008F8400343C076020944500D40A000C28DB
-:1031000030A5FFFF10C200248F87002894E20054EE
-:1031100094E400163045FFFF00A6102300A6182BEC
-:103120003089FFFF106000043044FFFF00C510230A
-:10313000012210233044FFFF008A102B1040000CA6
-:10314000012A102324020001A50200162402FFFF19
-:10315000A502000294E500D48F84003400003021E1
-:1031600030A5FFFF3C0760200A000BBF00000000F5
-:103170000044102A104000080000000095020016CC
-:103180003042000110400004000000009742007E21
-:1031900024420014A502001603E00008000000000D
-:1031A0008F84002827BDFFE0AFBF00189482003451
-:1031B0009483003E1060001A3048FFFF9383002C78
-:1031C00024020001146200278FBF00188F8200289C
-:1031D000000818C231080007006218212447003A8D
-:1031E000244900542444002024450030244600345F
-:1031F00090620040304200FF01021007304200019F
-:10320000104000168FBF00180E000927AFA900104C
-:103210008F820028944200340A000C413048FFFF9E
-:1032200094830036948200341043000E8FBF001840
-:1032300094820036A482003494820056A482005402
-:103240008C82002CAC82002494820032A482003054
-:103250009482003CA482003A8FBF00180A000C013F
-:1032600027BD002003E0000827BD002027BDFFE8A0
-:10327000AFBF00108F4A01003C0508008CA500E09C
-:103280003C02080090424EBC3C0C0800958C4EB6A7
-:1032900001452821304B003F30A2007F03424021EE
-:1032A000396900323C02000A3963003F2C63000197
-:1032B000010240212D2900012402FF8000A22824C0
-:1032C00001234825AF8A003400801821AF4500242F
-:1032D000000030210080282124070001AF88002849
-:1032E0003C04080024844EB0AF8C00241520000656
-:1032F000A380002D240200201562000E3402FFFF7F
-:103300001582000C00000000240200201562000558
-:10331000000000008C6300142402FFFF106200070D
-:10332000000000000E00095A000000000A000C9D79
-:10333000000000000E0009C5006020210E000C36C0
-:10334000000000008FBF001024020C8027BD001871
-:1033500003E00008AF4200243C0208008C4200E079
-:1033600027BDFFA0AFB1003C008210212411FF80D7
-:10337000AFBE0058AFB70054AFB20040AFB0003896
-:10338000AFBF005CAFB60050AFB5004CAFB4004863
-:10339000AFB30044005110248F4800248F49002807
-:1033A0008F470028AF4200243C0208008C4200E016
-:1033B0000080902124060006008210213042007F08
-:1033C000034218213C02000A006280213C02001FD7
-:1033D0003442FF8000E2382427A40010260500F0C4
-:1033E0000122F0240102B8240E0005EEAFA7003040
-:1033F0008FA20018AE0200C48FA2001CAE0200C84B
-:103400008FA20024AE0200CC93A40010920300D13E
-:103410002402FF800082102400431025304900FF61
-:103420003083007F3122007F0062102A10400004A8
-:10343000000310C001311026304900FF000310C006
-:1034400000031940006218213C0208008C4200DC95
-:10345000920400D202421021004310210051102496
-:10346000AF42002893A300103063007F000310C018
-:1034700000031940006218213C0208008C4200DC65
-:1034800002421021004310213042007F03421821E4
-:103490003C02000C006240218FA300142402FFFFB5
-:1034A00010620030309500FF93A2001195030014C4
-:1034B000304400FF3063FFFF0064182B1060000DE4
-:1034C00000000000950400148D07001C8D060018F4
-:1034D0003084FFFF0044202300042100000010215D
-:1034E00000E4382100E4202B00C230210A000D172F
-:1034F00000C43021950400148D07001C8D060018AF
-:103500003084FFFF008220230004210000001021EE
-:103510000080182100C2302300E4202B00C4302397
-:1035200000E33823AD07001CAD06001893A200117C
-:10353000A502001497A20012A50200168FA2001483
-:10354000AD0200108FA20014AD02000C93A2001176
-:10355000A502002097A20012A50200228FA200144B
-:10356000AD0200242406FF80024610243256007F5C
-:10357000AF420024035618213C02000A0062802159
-:103580008E02004C8FA200203124007F000428C04E
-:10359000AE0200508FA200200004214000852821A7
-:1035A000AE02007093A2001001208821A2020083C5
-:1035B00093A20010A2020079920200853042003FDF
-:1035C000A20200853C0208008C4200DC024210216D
-:1035D0000045102100461024AF42002C3C02080098
-:1035E0008C4200E43C0308008C6300DC02421021A2
-:1035F0000044102100461024AF4200283C0208007D
-:103600008C4200E402431821006518210242102177
-:10361000004410213042007F3063007F93A50010EA
-:1036200003422021034318213C02000E0062402186
-:103630003C02000C10B1008C008248213233007F24
-:10364000166000192404FF803C0208008C4200DC54
-:103650000242102100441024AF42002C3C0208001A
-:103660008C4200E43C0308008C6300DC0242102121
-:1036700000441024AF4200283C0208008C4200E4C1
-:10368000024318213063007F024210213042007F44
-:1036900003422021034318213C02000E0062402116
-:1036A0003C02000C008248219124000D2414FF806C
-:1036B0000000102100942025A124000D9504000293
-:1036C000950500148D07001C3084FFFF30A5FFFF17
-:1036D0008D060018008520230004210000E4382115
-:1036E00000C2302100E4202B00C43021AD07001CB3
-:1036F000AD06001895020002A5020014A5000016F0
-:103700008D020008AD0200108D020008AD02000C11
-:1037100095020002A5020020A50000228D020008EB
-:10372000AD0200249122000D3042004010400042C2
-:10373000262200013C0208008C4200E0A3B30028CE
-:103740003C10000A0242102100541024AF42002411
-:103750003C0208008C4200E0A380002C27A4002C2F
-:10376000024210213042007F0342182100701821CC
-:103770008C6200D88D26000427A50028AFA9002C54
-:1037800000461021AC6200D80E000AADAF830028BD
-:1037900093A300288F8200280E0006F7A04300D1D3
-:1037A0000E000C360000000002541024AF4200242A
-:1037B0003C0208008C4200DC00132940001320C0AA
-:1037C00000A42021024210210044102100541024A2
-:1037D000AF42002C3C0208008C4200E43C0308008D
-:1037E0008C6300DC03563021024210210045102179
-:1037F00000541024AF4200283C0208008C4200E430
-:1038000002431821006418210242102100451021B2
-:103810003042007F3063007F0342202103431821A0
-:103820003C02000E006240213C02000C00D08021CE
-:1038300000824821262200013043007F14750005D4
-:10384000304400FF2403FF8002231024004310268D
-:10385000304400FF93A20010008088212508002832
-:103860001444FF762529002093A400108FA3001490
-:103870002402FFFF1062000A308900FF2482000149
-:10388000248300013042007F14550005306900FF99
-:103890002403FF800083102400431026304900FFDA
-:1038A00092020078305300FF11330032012088214A
-:1038B0003C0208008C4200DC3225007F000520C05D
-:1038C0000005294000A42021024210212406FF8087
-:1038D0000044102100461024AF42002C3C03080095
-:1038E0008C6300DC3C0208008C4200E40243182197
-:1038F00002421021004510210064182100461024C6
-:103900003063007FAF420028034318213C02000EC1
-:10391000006240213C0208008C4200E48D06000C4D
-:103920000100202102421021004510213042007F79
-:10393000034218213C02000C0062482110C0000D17
-:10394000012028210E00071B000000002402FF8038
-:103950000222182426240001006228263082007FDB
-:1039600014550002308300FF30A300FF1473FFD012
-:10397000006088218E0300743C027FFF3442FFFF09
-:1039800000621824AE0300740E00073C02402021A0
-:10399000AF5700248FA20030AF5E00288FBF005CBD
-:1039A0008FBE00588FB700548FB600508FB5004CB3
-:1039B0008FB400488FB300448FB200408FB1003CF9
-:1039C0008FB0003827BD006003E00008AF42002C34
-:1039D00027BDFFD8AFB1001CAFBF0020AFB00018AB
-:1039E00027510188922200032408FF803C03000A2B
-:1039F0003047007FA3A700108F4601803C020800DB
-:103A00008C4200E0AF86003400C2282100A81024B8
-:103A1000AF4200249224000030A2007F0342102114
-:103A200000431021AF8200283084007F240200026E
-:103A300014820025000719403C0208008C4200E473
-:103A400000C210210043282130A2007F0342182128
-:103A500000A81024AF4200283C02000C006218218C
-:103A60009062000DAFA3001400481025A062000D65
-:103A70008FA300149062000D304200405040006A55
-:103A80008FBF00208F860028A380002C27A400145D
-:103A90008CC200D88C63000427A5001000431021BD
-:103AA0000E000AADACC200D893A300108F8200288C
-:103AB0000E0006F7A04300D10E000C3600000000F7
-:103AC0000A000ED88FBF00200E00070000C0202182
-:103AD0000E00070E000000003C0200080342802197
-:103AE000922300019202007B1443004F8FBF0020FD
-:103AF000922200003044007F24020004108200174C
-:103B0000288200051040000624020005240200035C
-:103B1000108200078FB1001C0A000ED900000000BF
-:103B2000108200128FBF00200A000ED98FB1001C36
-:103B300092050083920600788E0700748F8400340B
-:103B400030A500FF00073E0230C600FF0E0007440C
-:103B500030E7007F0A000ED88FBF00200E000CA4B3
-:103B60008F8400340A000ED88FBF002024020C80FE
-:103B7000AF4200249202003E30420040104000203C
-:103B8000000000009202003E000216000002160330
-:103B900004410006000000008F8400340E0006710E
-:103BA000240500930A000ED88FBF00209202003F28
-:103BB00024030018304200FF1443000C8F840034AB
-:103BC000240500390E000609000030210E000335DF
-:103BD0008F84003424020012A202003F0E00033E34
-:103BE0008F8400340A000ED88FBF002024050036D1
-:103BF0000E000609000030210A000ED88FBF0020F9
-:103C00000E0003358F8400349202000534420020F8
-:103C1000A20200050E00033E8F8400340E00108FB8
-:103C20008F8400348FBF00208FB1001C8FB000182C
-:103C300024020C8027BD002803E00008AF420024C6
-:103C400027BDFFE8AFB00010AFBF0014274301004D
-:103C500094620008000214000002140304410002F0
-:103C6000000080212410000194620008304200808E
-:103C70001040001A02001021946200083042200017
-:103C800010400016020010218C6300183C021C2D0D
-:103C9000344219ED240600061062000F3C07602133
-:103CA0003C0208008C4200D4104000078F8200289C
-:103CB0008F830028906200623042000F344200403F
-:103CC000A06200628F8200288F840034944500D463
-:103CD0000E000BBF30A5FFFF020010218FBF0014A4
-:103CE0008FB0001003E0000827BD001827BDFFE0DB
-:103CF000AFB10014AFB00010A380002CAFBF00180C
-:103D00008F4501003C0308008C6300E02402FF8023
-:103D1000AF85003400A318213064007F03442021C4
-:103D2000006218243C02000A00822021AF430024D4
-:103D3000275001008E0200148C8300DCAF84002821
-:103D40000043102318400004000088218E02001454
-:103D50000E000B50AC8200DC9202000B2403000228
-:103D6000304200FF1443002F0000000096020008BC
-:103D7000304300FF24020082146200052402008404
-:103D80000E000A0B000000000A000F640000000093
-:103D900014620009240200818F8200288F8400347D
-:103DA0003C076021944500D49206000530A5FFFF32
-:103DB0000A000F5330C600FF146200270000000005
-:103DC0009202000A304300FF3062002010400004DD
-:103DD000306200408F8400340A000F4F24060040F8
-:103DE00010400004000316008F8400340A000F4FB7
-:103DF0002406004100021603044100178F8400349A
-:103E0000240600428F8200283C076019944500D4A4
-:103E100030A5FFFF0E000BBF000000000A000F647A
-:103E2000000000009202000B24030016304200FF45
-:103E300010430006000000009202000B240300174C
-:103E4000304200FF14430004000000000E000EDEAC
-:103E500000000000004088210E000C360000000029
-:103E60009202000A304200081040000624020C8032
-:103E70008F8500283C0400080E0012BD0344202159
-:103E800024020C80AF4200248FBF001802201021B2
-:103E90008FB000108FB1001403E0000827BD002090
-:103EA00027BDFFE8AFBF0014AFB000108F50002453
-:103EB0003C0308008C6300E08F4501002402FF8072
-:103EC00000A318213064007F0344202100621824DD
-:103ED0003C02000A00822021AF850034AF43002459
-:103EE00090820062AF8400283042000F34420050BC
-:103EF000A08200623C02001F3442FF800E0006F7E1
-:103F000002028024AF5000248FBF00148FB0001035
-:103F100003E0000827BD00183C0208008C42002086
-:103F20001040001D2745010090A300093C02000835
-:103F30000342202124020018546200033C020008BE
-:103F40000A000FA5240200080342202124020016C3
-:103F5000146200052402001724020012A082003F10
-:103F60000A000FAF94A700085462000694A7000847
-:103F7000936200052403FFFE00431024A3620005A2
-:103F800094A7000890A6001B8CA4000094A500062E
-:103F90000A000B9A00073C0003E000080000000044
-:103FA0002744010094820008304500FF38A30082B6
-:103FB00038A200842C6300012C4200010062182505
-:103FC00010600006240200839382002D1040000D33
-:103FD000000000000A000C690000000014A20005A7
-:103FE00024A2FF808F4301043C02602003E000080C
-:103FF000AC430014304200FF2C420002104000038A
-:10400000240200220A000F090000000014A200038D
-:10401000000000000A000F76000000000A000F9464
-:10402000000000009363007E9362007A144300094D
-:10403000000020219362000024030050304200FF62
-:1040400014430004240400019362007E2442000112
-:10405000A362007E03E00008008010218F4201F877
-:104060000440FFFE24020002AF4401C0A34201C489
-:104070003C02100003E00008AF4201F827BDFFE852
-:10408000AFBF00109362003F2403000A304200FFDC
-:1040900014430046000000008F6300548F62004C00
-:1040A0001062007F036030219362000024030050FF
-:1040B000304200FF1443002F000000008F440140F5
-:1040C0003C0208008C4200E02403FF8000821021A3
-:1040D00000431024AF4200243C0208008C4200E060
-:1040E0008F6500543C03000A008220213084007F49
-:1040F0000344102100431021AC4501089762003CA5
-:104100008F63004C3042FFFF000210400062182114
-:10411000AF63005C8F6300548F64004C9762003C77
-:10412000006418233042FFFF0003184300021040D0
-:104130000043102A10400006000000008F62005467
-:104140008F63004C004310230A0010250002104327
-:104150009762003C3042FFFF00021040ACC2006496
-:1041600024020001A0C0007CA0C2008424020C80B4
-:10417000AF4200240E000FD78F4401401040004989
-:104180008FBF00108F4301408F4201F80440FFFEB3
-:1041900024020002AF4301C0A34201C43C0210004C
-:1041A000AF4201F80A0010778FBF00109362003F02
-:1041B00024030010304200FF1443000400000000FC
-:1041C0008F4401400A001063000028219362003FE1
-:1041D00024030016304200FF14430004240200149C
-:1041E000A362003F0A001071000000008F62004CC3
-:1041F0008F630050004310230441002A8FBF00103A
-:104200009362008124420001A362008193620081D5
-:104210003C0308008C6300C0304200FF14430010D0
-:10422000000000009362003F24030004304200FFBE
-:1042300014430006000000008F4401408FBF0010AF
-:10424000240500930A00067127BD00188F44014021
-:10425000240500938FBF00100A0006E027BD001858
-:104260008F4401400E000335000000008F620054AF
-:104270002442FFFFAF6200548F6200502442FFFFD0
-:10428000AF6200500E00033E8F4401408F44014056
-:104290008FBF0010240500040A00034327BD001847
-:1042A0008FBF001003E0000827BD00188F4201886F
-:1042B0009363007E00021402304400FF306300FF6D
-:1042C0001464000D0000000093620080304200FF83
-:1042D0001044000900000000A36400809362000005
-:1042E00024030050304200FF14430004000000008B
-:1042F0000A0007A88F440180A364008003E000083F
-:104300000000000027BDFFE8AFB00010AFBF0014F1
-:1043100093620005240300303042003014430089CA
-:10432000008080213C0208008C4200201040008068
-:10433000020020210E000564000000008F8500208F
-:10434000ACB000009362003E9363003F304200FF38
-:1043500000021200306300FF00431025ACA20004ED
-:104360009362008200021600000216030441000559
-:10437000000000003C0308008C6300480A0010B5F0
-:10438000000000009362003E3042004014400003F1
-:104390000000182193620081304300FF9362008285
-:1043A00000031E00304200FF0002140000621825C6
-:1043B000ACA300088F620040ACA2000C8F620048E2
-:1043C000ACA200108F62004CACA200148F620050AF
-:1043D0008F63004C004310230441000300000000E1
-:1043E0000A0010C98F62004C8F620050ACA2001806
-:1043F0003C02080094424E963C03C00B0000202172
-:10440000004310250E000589ACA2001C8F620054E9
-:104410008F840020AC8200008F620058AC820004C0
-:104420008F62005CAC8200088F6200608F43007472
-:1044300000431021AC82000C8F620064AC8200103B
-:10444000976300689762006A00031C003042FFFF18
-:1044500000621825AC83001493620082240300805C
-:10446000304200FF14430003000000000A0010FD6A
-:10447000AC8000188F63000C240200011062000E53
-:104480002402FFFF9362003E304200401440000AC5
-:104490002402FFFF8F63000C8F4200740062182318
-:1044A0003C02080000621024144000020000282191
-:1044B0000060282100051043AC8200183C0208006F
-:1044C00094424E963C03C00C00002021004310256E
-:1044D0008F8300200E000589AC62001C8F620018DB
-:1044E0008F8300203C05080094A54E96240400010B
-:1044F000AC620000AC6000048F66006C3C02400DB2
-:1045000000A22825AC6600088F6200DCAC62000CBB
-:10451000AC6000109362000500021600AC6200144B
-:10452000AC6000180E000589AC65001C020020215B
-:104530008FBF00148FB00010A36000050A0004F2C2
-:1045400027BD00188FBF00148FB0001003E00008D3
-:1045500027BD00189742007C30C600FFA08600846B
-:104560003047FFFF2402000514C2000B24E346502D
-:1045700090A201122C4200071040000724E30A0019
-:1045800090A30112240200140062100400E2102122
-:104590000A0011353047FFFF3067FFFF03E00008D6
-:1045A000A4870014AC87004C8CA201080080402135
-:1045B00000A0482100E2102330C600FF184000038D
-:1045C00093AA001324E2FFFCACA2010830C2000150
-:1045D00010400008000000008D02005000E210238F
-:1045E00004410013240600058D02005410E200105F
-:1045F000000000008D02005414E2001A00000000C8
-:104600003C0208008C4200D8304200201040000AD2
-:1046100024020001910300789102008314430006F4
-:104620002402000101002021012028212406000489
-:104630000A00112300000000A100008411400009BD
-:10464000A50200148F4301008F4201F80440FFFED1
-:1046500024020002AF4301C0A34201C43C02100087
-:10466000AF4201F803E000080000000027BDFFE8AA
-:104670008FA90028AFBF00100080402100E9182357
-:104680001860007330C600FFA080007CA08000810D
-:104690008CA2010800E210230440004D000000003D
-:1046A0008C8200509483003C8C8400640047482333
-:1046B0003063FFFF012318210083202B10800004AA
-:1046C000000000008D0200640A00118600E2102143
-:1046D0009502003C3042FFFF0122102100E2102130
-:1046E000AD02005C9502003C8D03005C3042FFFF90
-:1046F0000002104000E210210043102B1040000384
-:10470000000000000A0011958D02005C9502003C3B
-:104710003042FFFF0002104000E21021AD02005CB9
-:10472000A1000084AD07004C8CA2010800E2102318
-:104730001840000224E2FFFCACA2010830C20001D4
-:104740001040000A000000008D02005000E210231B
-:1047500004410004010020218D02005414E20003F2
-:10476000000000000A0011B7240600058D02005465
-:1047700014E200478FBF00103C0208008C4200D8B2
-:10478000304200201040000A24020001910300780A
-:10479000910200831443000624020001010020213D
-:1047A000240600048FBF00100A00112327BD001843
-:1047B000A1000084A50200148F4301008F4201F87C
-:1047C0000440FFFE240200020A0011DC0000000089
-:1047D0008C82005C004910230043102B54400001E0
-:1047E000AC87005C9502003C3042FFFF0062102B5A
-:1047F00014400007240200029502003C8D03005C77
-:104800003042FFFF00621821AD03005C2402000269
-:10481000AD07004CA10200840E000FD78F440100A9
-:104820001040001B8FBF00108F4301008F4201F822
-:104830000440FFFE24020002AF4301C0A34201C4B2
-:104840003C021000AF4201F80A0011F28FBF0010C5
-:1048500030C200101040000E8FBF00108C83005C2F
-:104860009482003C006918233042FFFF0062182147
-:104870003C023FFF3444FFFF0083102B54400001F3
-:104880000080182101231021AD02005C8FBF0010B1
-:1048900003E0000827BD001827BDFFE88FAA002805
-:1048A000AFBF00100080402100EA482319200021FA
-:1048B00030C600FF8C83005C8C820064006A182381
-:1048C0000043102B504000100069182194A20110E1
-:1048D00001221021A4A2011094A201103042FFFF76
-:1048E0000043102B1440000A3C023FFF94A2011029
-:1048F00000431023A4A201109482003C3042FFFF29
-:104900000A00121100621821A4A001103C023FFF0E
-:104910003444FFFF0083102B544000010080182115
-:1049200000671021AD02005CA100007C0A00125952
-:10493000A100008130C200101040003C00000000C7
-:104940008C820050004A10231840003800000000FC
-:104950009082007C24420001A082007C9082007C36
-:104960003C0308008C630024304200FF0043102BFE
-:104970001440005C8FBF00108CA2010800E21023DD
-:1049800018400058000000008C8300549482003CC2
-:10499000006A18233042FFFF000318430002104052
-:1049A0000043102A10400005000000008C820054D3
-:1049B000004A10230A001240000210439482003C77
-:1049C0003042FFFF00021040AD0200649502003C3F
-:1049D0008D0400649503003C3042FFFF000210404C
-:1049E000008220213063FFFF008318210143102142
-:1049F000AD02005C8D020054ACA20108240200024A
-:104A0000A10200840E000FD78F4401001040003532
-:104A10008FBF00108F4301008F4201F80440FFFE5A
-:104A2000240200020A00128200000000AD07004CC0
-:104A30008CA2010800E210231840000224E2FFFCCF
-:104A4000ACA2010830C200011040000A00000000C2
-:104A50008D02005000E210230441000401002021D7
-:104A60008D02005414E20003000000000A001279D5
-:104A7000240600058D02005414E2001A8FBF0010B6
-:104A80003C0208008C4200D8304200201040000A4E
-:104A90002402000191030078910200831443000670
-:104AA0002402000101002021240600048FBF001011
-:104AB0000A00112327BD0018A1000084A5020014DC
-:104AC0008F4301008F4201F80440FFFE24020002E0
-:104AD000AF4301C0A34201C43C021000AF4201F841
-:104AE0008FBF001003E0000827BD00188FAA001038
-:104AF0008C8200500080402130C600FF004A102305
-:104B000000A048211840000700E0182124020001FD
-:104B1000A0800084A0A00112A48200140A0011F455
-:104B2000AFAA0010A0800081AD07004C8CA2010844
-:104B300000E210231840000224E2FFFCACA20108AE
-:104B400030C2000110400008000000008D0200503B
-:104B50000062102304410013240600058D02005456
-:104B600010620010000000008D0200541462001159
-:104B7000000000003C0208008C4200D830420020B7
-:104B80001040000A24020001910300789102008382
-:104B900014430006240200010100202101202821E5
-:104BA000240600040A00112300000000A100008474
-:104BB000A502001403E000080000000027BDFFE08C
-:104BC000AFBF0018274201009046000A8C4800142D
-:104BD0008C8B004C9082008430C900FF0168182340
-:104BE000304A00FF1C60001A2D4600062402000116
-:104BF0000142100410C00016304300030120302190
-:104C00000100382114600007304C000C15800009A9
-:104C1000304200301440000B8FBF00180A0012E32E
-:104C2000000000000E0011F4AFAB00100A0012E308
-:104C30008FBF00180E001169AFAB00100A0012E31D
-:104C40008FBF0018AFAB00100E001289AFAA00147E
-:104C50008FBF001803E0000827BD002024020003D6
-:104C6000A08200848C82005403E00008ACA20108FA
-:104C70003C02000803421821906200812406004390
-:104C80003C07601924420001A0620081906300810A
-:104C90003C0208008C4200C0306300FF1462001028
-:104CA0002403FF803C0208008C4200E000821021B7
-:104CB00000431024AF4200243C0208008C4200E074
-:104CC0003C03000A008210213042007F0342102181
-:104CD00000431021944500D40A000BBF30A5FFFF0C
-:104CE00003E000080000000027BDFFE0AFBF001890
-:104CF000AFB10014AFB000108F420180008080215E
-:104D000000A088210E0012EA00402021A2000084A9
-:104D10008E0200548FBF00188FB00010AE22010821
-:104D20008FB1001403E0000827BD002027BDFFE07D
-:104D30003C020008AFB00010AFBF0018AFB10014C4
-:104D4000034280218F510140920300848E04005061
-:104D50008E02004C14820040306600FF3C020800C6
-:104D60008C4200E02403FF80022210210043102423
-:104D7000AF4200243C0208008C4200E09744007CD3
-:104D800092050081022210213042007F0342182147
-:104D90003C02000A0062182114A0000B3084FFFFBF
-:104DA0002402000554C20014248205DC9062011222
-:104DB00024420001A062011224020C80AF420024B0
-:104DC0000A00134224020005A0600112240200051B
-:104DD00014C20009248205DC920200812C420007E3
-:104DE0005040000524820A0092030081240200142E
-:104DF00000621004008210213044FFFFA60400145A
-:104E00000E0012EA022020219602003C8E03004C84
-:104E1000022020213042FFFF0002104000621821D2
-:104E20000E000335AE03005C9202007D02202021BB
-:104E3000344200400E00033EA202007D8F4201F882
-:104E40000440FFFE24020002AF5101C0A34201C48E
-:104E50003C021000AF4201F88FBF00188FB1001460
-:0C4E60008FB0001003E0000827BD002008
-:044E6C0008000E7CB0
-:104E700008000EC408000F0408000F5008000F843B
-:104E80000A00002000000000000000000000000DEB
-:104E90006370342E362E31360000000004061004F4
-:104EA0000000000000000000000000000000000002
-:104EB00000000000000000000000000000000000F2
-:104EC00000000000000000000000002000000000C2
-:104ED00000000000000000000000000000000000D2
-:104EE00000000000000000000000000000000000C2
-:104EF0000000000000000000000000010000002B86
-:104F00000000000010000003000000000000000D81
-:104F10000000000D3C020800244258A43C03080095
-:104F200024635F70AC4000000043202B1480FFFD21
-:104F3000244200043C1D080037BD7FFC03A0F02183
-:104F40003C100800261000803C1C0800279C58A438
-:104F50000E00019C000000000000000D27BDFFE8CE
-:104F60003C096018AFBF00108D2C5000240DFF7F4E
-:104F700024080031018D5824356A380C24070C00B0
-:104F80003C1A8000AD2A50003C04800AAF4800085B
-:104F90003C1B8008AF4700240E000924AF8400109A
-:104FA0000E0008E7000000000E00083400000000BA
-:104FB0000E00125E000000003C0460168C850000AC
-:104FC0003C06FFFF3C02535300A618241062003F2A
-:104FD00034867C0094C201F2A780002C10400003AC
-:104FE000A78000CC38581E1EA798002C94C201F848
-:104FF00010400004978300CC38591E1EA79900CC9E
-:10500000978300CC2C7F006753E0000124030066E7
-:105010009784002C2C820401144000020060282197
-:10502000240404003C0760008CE904382403103C8D
-:105030003128FFFF1103001730B9FFFF5720000C84
-:10504000A38000CE24020050A38200CE939F00CE06
-:1050500013E0000A8FBF001027BD0018A78000CC06
-:10506000A780002CA780003403E00008A78000E69A
-:10507000939F00CE17E0FFF88FBF001027BD0018E8
-:10508000A78500CCA784002CA780003403E000088B
-:10509000A78000E6A38000CE8CCB003C316A0001E3
-:1050A0001140000E0000000030A7FFFF10E0FFE6F7
-:1050B000240200508CCC00C83186000114C0FFE4EB
-:1050C000939F00CE0A000072240200518C8F0004CE
-:1050D0003C0E60000A00005501EE30218CEF0808FC
-:1050E000240D5708000F740211CD000430B8FFFFE3
-:1050F000240500660A000073240404001700FFD48E
-:10510000939F00CE0A000072240200508F86001088
-:105110003089FFFF000939408CC300103C08005063
-:1051200000E82025AF4300388CC500142742040056
-:10513000AF82001CAF45003CAF44003000000000CF
-:10514000000000000000000000000000000000005F
-:105150000000000000000000000000008F4B000075
-:10516000316A00201140FFFD0000000003E000084C
-:10517000000000008F840010948A001A8C8700249D
-:105180003149FFFF000940C000E83021AF46003C34
-:105190008C8500248F43003C00A310231840002975
-:1051A000000000008C8B0020256200013C0D0050A7
-:1051B00035AC0008AF420038AF4C003000000000B2
-:1051C00000000000000000000000000000000000DF
-:1051D0000000000000000000000000008F4F0000F1
-:1051E00031EE002011C0FFFD000000008F4A0400D6
-:1051F0003C080020AC8A00108F490404AC890014DC
-:10520000AF48003000000000948600189487001C0E
-:1052100000C71821A48300189485001A24A2000155
-:10522000A482001A9498001A9499001E133800035F
-:105230000000000003E000080000000003E0000898
-:10524000A480001A8C8200200A0000CC3C0D005083
-:105250000A0000BD000000003C0308008C63002031
-:105260008F82001827BDFFE810620008AFBF001052
-:105270000E0000F4AF8300183C0308008C6300208C
-:1052800024040001106400048F8900108FBF0010F7
-:1052900003E0000827BD00188FBF00103C07601214
-:1052A000A520000A9528000A34E5001027BD001843
-:1052B0003106FFFF03E00008ACA600903C020800A6
-:1052C0008C42002027BDFFC8AFBF0034AFBE003006
-:1052D000AFB7002CAFB60028AFB50024AFB40020A4
-:1052E000AFB3001CAFB20018AFB1001410400050B3
-:1052F000AFB000108F840010948600069483000ADB
-:1053000000C3282330B6FFFF12C0004A8FBF00340D
-:1053100094890018948A000A012A40233102FFFF71
-:1053200002C2382B14E0000202C0202100402021DC
-:105330002C8C0005158000020080A021241400049C
-:105340000E0000A3028020218F8700100280982188
-:10535000AF80001494ED000A028088211280004E74
-:1053600031B2FFFF3C1770003C1540003C1E60004E
-:105370008F8F001C8DEE000001D71824507500504F
-:105380000220202102A3802B160000353C182000AB
-:105390005078004702202021241000018F83001440
-:1053A00014600039029158230230F8230250C821BA
-:1053B00033F1FFFF1620FFEE3332FFFF8F8700101F
-:1053C0003C110020AF5100300000000094E6000ABC
-:1053D0003C1E601237D5001002662821A4E5000AA1
-:1053E00094E2000A94F2000A94F400183057FFFF88
-:1053F0001292003BAEB700908CED00148CE40010CC
-:105400000013714001AE4021000E5FC3010E502B0E
-:10541000008B4821012A1821ACE80014ACE30010ED
-:1054200002D3382330F6FFFF16C0FFB98F84001077
-:105430008FBF00348FBE00308FB7002C8FB600288E
-:105440008FB500248FB400208FB3001C8FB20018DA
-:105450008FB100148FB0001003E0000827BD0038A2
-:10546000107E001B000000001477FFCC2410000108
-:105470000E0015A9000000008F8300141060FFCB00
-:105480000230F823029158238F87001001702021E9
-:105490000A0001873093FFFF8F8300141460FFCB55
-:1054A0003C110020AF5100300A0001530000000001
-:1054B0000E00079B024028210A000147004080217E
-:1054C0000E000341024028210A00014700408021CC
-:1054D0000E001471022020210A00014700408021A3
-:1054E0000E0000BD000000000A00016902D338234D
-:1054F00027BDFFE8AFB00010AFBF00140E000037AB
-:10550000000000003C028000345000700A0001AA34
-:105510008E0600008F4F000039EE000131C20001FD
-:10552000104000248F8600A88E0700003C0C080065
-:105530008D8C003C3C0908008D29003800E668236A
-:10554000018D28210000502100AD302B012A40217F
-:10555000010620213C010800AC25003CAF8700A8D3
-:105560003C010800AC2400380E0000F600000000EA
-:105570003C0308008C6300701060FFE6006020218F
-:105580003C0508008CA500683C0608008CC6006C31
-:105590000E001538000000003C010800AC2000702F
-:1055A0008F4F000039EE000131C200011440FFDED0
-:1055B0008F8600A88E0A00008F8B00A83C0508008B
-:1055C0008CA5003C3C0408008C840038014B482327
-:1055D00000A938210082182100E9402B0068102121
-:1055E0003C010800AC27003C3C010800AC2200381C
-:1055F0008F5F01002419FF0024180C0003F92024F8
-:1056000010980012AF840000AF440020936D00009A
-:10561000240C002031A600FF10CC0012240E0050F4
-:1056200010CE00043C194000AF5901380A0001A314
-:10563000000000000E0011D4000000003C194000E2
-:10564000AF5901380A0001A3000000000E00010F4D
-:10565000000000003C194000AF5901380A0001A3C6
-:10566000000000008F58010000802821330F00FF48
-:1056700001E020210E0002EEAF8F00043C19400033
-:10568000AF5901380A0001A30000000000A4102B4C
-:1056900024030001104000090000302100052840CB
-:1056A00000A4102B04A00003000318405440FFFC8A
-:1056B000000528405060000A0004182B0085382B94
-:1056C00054E000040003184200C330250085202365
-:1056D000000318421460FFF9000528420004182B4B
-:1056E00003E0000800C310213084FFFF30A5FFFF56
-:1056F0008F4201B80440FFFE3C0740800087302500
-:105700003C031000AF400180AF450184AF460188E3
-:1057100003E00008AF4301B83084FFFF8F4201B8B7
-:105720000440FFFE3C0740388CA600000087282577
-:105730003C031000AF460180AF45018803E000083C
-:10574000AF4301B88F8300388F8600301066000B9E
-:10575000008040213C07080024E75A18000328C0B5
-:1057600000A710218C44000024630001108800056C
-:105770003063000F5466FFFA000328C003E00008FE
-:10578000000010213C07080024E75A1C00A7302124
-:1057900003E000088CC200003C039000346200016A
-:1057A00000822025AF4400208F45002004A0FFFE8A
-:1057B0000000000003E00008000000003C0380003F
-:1057C000346200010082202503E00008AF4400207D
-:1057D00027BDFFE0AFB100143091FFFFAFB0001064
-:1057E000AFBF00181220001500A080218CA500007A
-:1057F00010A00013240400020E000C6B24060140CC
-:10580000AE0000008F4201B80440000D00002821C6
-:105810003C064000022620258FBF00188FB10014DF
-:105820008FB000103C03100027BD0020AF45018061
-:10583000AF44018803E00008AF4301B88CA5000025
-:105840008F4201B80440FFFE3C064000022620259E
-:105850008FBF00188FB100148FB000103C031000F0
-:1058600027BD0020AF450180AF44018803E0000858
-:10587000AF4301B83086FFFF8F4201B80440FFFEFE
-:105880003C0940068CA8000000C93825AF480180BB
-:105890008CA400043C031000AF440184AF4701888E
-:1058A00003E00008AF4301B827BDFFE0AFB0001030
-:1058B000AFBF0018AFB100149363003E0080802199
-:1058C0000080282130620040000020211040000F9D
-:1058D0008E1100000E000860022020219367000056
-:1058E0002404005030E500FF50A400128E0F000089
-:1058F000022020218FBF00188FB100148FB000103C
-:10590000A762013C0A00092027BD00200E00027D8D
-:10591000000000000E0008600220202193670000B4
-:105920002404005030E500FF14A4FFF202202021DF
-:105930008E0F00003C1008008E1000503C0D000C33
-:10594000240BFF8001F05021314E007F01DA6021ED
-:10595000018D4021014B4824AF490028022020211D
-:105960008FBF00188FB100148FB00010A50200D6B1
-:1059700027BD00200A000920AF8800D027BDFFE026
-:10598000AFBF0018AFB10014AFB0001093660001B4
-:10599000008080210E00024630D10004936400058F
-:1059A000001029C2A765000034830040A3630005EE
-:1059B0000E00024F020020210E00092202002021C9
-:1059C00024020001AF62000C02002821A76200102F
-:1059D00024040002A762001224060140A7620014FA
-:1059E0000E000C6BA76200161620000F8FBF001868
-:1059F000978C00343C0B08008D6B00782588FFFFE6
-:105A00003109FFFF256A0001012A382B10E000064A
-:105A1000A78800343C0F6006240E001635ED0010F8
-:105A2000ADAE00508FBF00188FB100148FB00010C2
-:105A300003E0000827BD002027BDFFE0AFB1001440
-:105A4000AFBF0018AFB0001000A088211080000A7E
-:105A50003C0360002402008010820012000000005D
-:105A60000000000D8FBF00188FB100148FB0001020
-:105A700003E0000827BD00208C682BF80500FFFE1E
-:105A800000000000AC712BC08FBF00188FB1001454
-:105A90008FB000103C09100027BD002003E0000873
-:105AA000AC692BF80E00024600A02021936500058A
-:105AB000022020210E00024F30B000FF2403003EE0
-:105AC0001603FFE7000000008F4401780480FFFE0A
-:105AD000240700073C061000AF510140022020219E
-:105AE000A34701448FBF00188FB100148FB000107E
-:105AF000AF4601780A0002BF27BD002027BDFFE89E
-:105B0000AFBF0014AFB000108F50002000000000A5
-:105B10000E000922AF440020AF5000208FBF0014B8
-:105B20008FB0001003E0000827BD00183084FFFF8D
-:105B30008F4201B80440FFFE3C0740350087302506
-:105B40003C031000AF450180AF400184AF4601889F
-:105B500003E00008AF4301B83084FFFF8F4201B873
-:105B60000440FFFE3C074036008730253C03100010
-:105B7000AF450180AF400184AF46018803E00008D3
-:105B8000AF4301B827BDFFD0AFB3001C3093FFFF78
-:105B9000AFB50024AFB20018AFBF0028AFB40020EB
-:105BA000AFB10014AFB0001030B5FFFF1260002796
-:105BB000000090218F90001C8E0300003C068000A6
-:105BC0002402004000033E0200032C0230E4007F68
-:105BD000006688241482001D30A500FF8F830028F2
-:105BE0002C68000A510000108F91001400035880A7
-:105BF0003C0C0800258C56CC016C50218D490000CE
-:105C0000012000080000000002B218213065FFFFEB
-:105C10000E00021A24040084162000028F90001C3B
-:105C2000AF8000288F910014260C0020264B000125
-:105C3000018080213172FFFF16200004AF8C001C10
-:105C40000253402B1500FFDC000000000240102131
-:105C50008FBF00288FB500248FB400208FB3001CA5
-:105C60008FB200188FB100148FB0001003E000084D
-:105C700027BD0030240D003414AD00F600000000F4
-:105C8000920B000E240A16803C07000CA36B002127
-:105C90009203000D0347F8213C066000A363002037
-:105CA000961100123C087FFF350CFFFFA771003CE6
-:105CB00096020010240B00053054FFFFAF740084DF
-:105CC0008E19001CAF4A00288FF800008CCF444882
-:105CD0000319702601EE3021AF66004C8F69004C2D
-:105CE00024CD00013C197F00AF6900508F64005043
-:105CF000AF640054AF660070AF6D00588F650058F8
-:105D000024040050AF65005CA3600023AF6C006406
-:105D1000A36B00378E030014AF6300488F710048F7
-:105D2000AF7100248E020018AF62006C9214000C58
-:105D3000A3740036936A003E355F0020A37F003EC7
-:105D40008F7800740319782435EE4000AF6E00742C
-:105D500093700000320900FF112402332418FF80E1
-:105D60003C04080024845A980E00028A00000000B7
-:105D700024060004240700013C0408008C845A987F
-:105D8000A366007DA36700058F4A01780540FFFEEA
-:105D900024020002AF440140A34201448F90001C42
-:105DA0003C141000AF5401780A000369AF8000284A
-:105DB0002CAD003751A0FF9C8F9100140005A080EE
-:105DC0003C180800271856F4029878218DEE000040
-:105DD00001C00008000000002406000614A60011FF
-:105DE000000000003C1F08008FFF5A9824040005A3
-:105DF000AF5F00208E190018AF7900188F78004C23
-:105E0000AF78001C8F6F0050122000C2AF6F00707F
-:105E10000A000369AF840028240A000710AA00843E
-:105E2000240300063C05080024A55A980E000254DD
-:105E3000240400818F90001C0011102B0A000369BC
-:105E4000AF820028240A000414AAFFF6240300509D
-:105E50003C0E08008DCE5A98AF4E00208E090008E7
-:105E6000AF6900408E060008AF6600448E07000C44
-:105E7000AF6700488E040010AF64004C8E0D001018
-:105E8000AF6D00848E080014AF6800508E050018B6
-:105E9000AF6500548E0C001CAF6C0058936B000073
-:105EA000317400FF128301F5000000008F64004888
-:105EB0008F6600400086382304E000042404008C30
-:105EC0001620FFDE24020003240400823C050800A3
-:105ED00024A55A980E00027D000000008F90001C3F
-:105EE000000010210A000369AF8200282409000580
-:105EF00014A9FFCC240520003C0A08008D4A5A98BA
-:105F0000AF4A00208E1F0004AF7F005C921900088A
-:105F100024100008A37900218F98001C930F00091A
-:105F2000A36F00208F86001C90CE000A31C400FFB2
-:105F300010900010288300091460006C24020002F5
-:105F4000240800201088000B3405800028850021DB
-:105F500014A0000824054000240D0040108D000509
-:105F60003C05000124070080108700023C05000268
-:105F7000240540008F6E00743C0FFF0001CF802489
-:105F800002054825AF69007490C4000BA36400812A
-:105F90008F84001C9486000C10C0019B0000000040
-:105FA000948E000C241FFFBF24060004A76E003C43
-:105FB0009090000EA370003E8F89001C9124000F6A
-:105FC000A364003F8F94001C8E8D00108F470074D7
-:105FD00001A72823AF6500608E880014AF680064B5
-:105FE000968C0018A76C0068968B001AA76B006A45
-:105FF0008E82001CAF62006C96830002A763013E94
-:10600000928A000EA36A003E9379003E033FC024AB
-:106010001220016AA378003E8F90001C0A000369D9
-:10602000AF8600282414002214B4FF7E2403000746
-:106030003C0208008C425A981220000CAF4200200B
-:106040000A000369AF830028240C003310AC00144D
-:10605000240800283C05080024A55A980E000226B2
-:10606000240400810A0003EE8F90001C3C04080009
-:1060700024845A980E00028A00000000936B0000EE
-:1060800024110050316300FF107101540000000022
-:106090008F90001C000018210A000369AF830028BC
-:1060A0003C0508008CA55A9824040081AF450020C7
-:1060B000A36800343C05080024A55A980E00022667
-:1060C000000000008F90001C240200090A000369F0
-:1060D000AF82002802B288213225FFFF0E00021A8B
-:1060E000240400840A0003698F90001C1082FFA121
-:1060F000240504002894000312800176240C000477
-:10610000240B0001548BFF9B240540000A00043D32
-:10611000240501003C04080024845A988F62004C36
-:106120000E00028A8F6300508F90001C0000202117
-:106130000A000369AF8400288E1000042404008A3A
-:10614000AF500020936E000531C900021520016593
-:10615000020028219378002302002821330F002019
-:1061600015E001602404008D9362003F24190012A1
-:10617000305F00FF13F9015B240400810E0002462A
-:106180000200202193740023240A0004020020212D
-:1061900036830042A36300230E00024FA36A007DF2
-:1061A0008F4B01780560FFFE24050002AF500140CF
-:1061B000A34501448F90001C3C0C1000AF4C0178AB
-:1061C0000A0003EF0011102B8E1000042404008A33
-:1061D000AF500020936D000531A800021500001992
-:1061E000020028219367003F2414001230E400FFCE
-:1061F0001094010100000000936E003F240600048B
-:1062000031C900FF112600FC000000000E0002460C
-:1062100002002021936200232419FFFE02002021A6
-:10622000345F0020A37F0023A374003F9378000510
-:10623000031978240E00024FA36F000502002821E5
-:10624000000020210E000336000000000A0003EECB
-:106250008F90001C8E0500043C0F0008034F402166
-:10626000AF450020910E00002406005031C900FF08
-:106270001126017A240400888F5901B80720FFFEF7
-:106280003C0C400E008C58253C031000AF450180AB
-:10629000AF400184AF4B0188AF4301B891020000C9
-:1062A000240AFF8024040004004AF825A11F0000EE
-:1062B0000E000C6B240600300A0003EE8F90001CC9
-:1062C0008E04001C0E000231000000001040014C42
-:1062D000004048218F90001C240500898F4D01B893
-:1062E00005A0FFFE00000000AF4901808E0F001CDA
-:1062F0003C1440010011702B00B448253C111000E3
-:10630000AF4F0184AF8E0028AF490188AF5101B86B
-:106310000A00036A8F910014961900023C140800C9
-:1063200026945A9833380004130000F23C026000AF
-:106330008E1F001C3C010800AC3F5A98AF5F002044
-:10634000920C0010240B0014318400FF148B011CEC
-:106350000000000096090002312D000115A001B2D5
-:10636000000000008E020004AE8200083C0E08000F
-:106370008DCE5AA011C001A8000000008F690074E2
-:106380003C0E800024040001012E6825AF6D0074CE
-:10639000A3600005AF64000C3C0C08008D8C5AA073
-:1063A0008F88001CA7640010000C59C2A76400125B
-:1063B000A7640014A7640016A76B00088D030008EB
-:1063C00024040002AF63002C8D0A000CAF6A003079
-:1063D00091070010A36700348F82001C90450011C4
-:1063E000A36500358F86001C90D00012A370003684
-:1063F0008F9F001C93F90013A37900378F90001C26
-:1064000096180014A778003896140016A774003A5E
-:106410008E0F0018AF6F00245620FE02AF840028B4
-:106420003C05080024A55A980E00025400002021C3
-:106430008F90001C0A0004AC000020218E0F000485
-:106440003C14080026945A983C010800AC2F5A9836
-:10645000AF4F0020920E000331C90004112000024A
-:106460002402001224020006A362003F9203001BD4
-:10647000240AFFC03062003F004AF825A37F003E97
-:106480009219000333380001170000C1000000001A
-:106490008E020008AE8200083C0208008C425AA01E
-:1064A000104000C000000000000221C2A7640008E4
-:1064B0008E0D000C240B000124140014AF6D002C71
-:1064C0008E080010AF68003096050016A7650038EA
-:1064D000960C0014A76C003AAF6B000CA76B001071
-:1064E000A76B0012A76B0014A76B0016122000EB1D
-:1064F000A37400349206000330C700022CF00001A0
-:10650000260200088F90001C0A000369AF82002851
-:106510008E14000424030081AF54002093680023EC
-:106520003105001010A000AC000000008F4401B83D
-:106530000480FFFE3C06401F0011382B006610252A
-:106540003C111000AF540180AF870028AF40018498
-:10655000AF420188AF5101B80A00036A8F9100145D
-:106560008E0600043C19000803592021AF46002084
-:106570008E07000890980000240F0050331400FF8D
-:10658000128F00A7240500888F4401B80480FFFE05
-:106590003C0D40090011602B00AD10253C1110008E
-:1065A000AF460180AF8C0028AF470184AF4201881D
-:1065B000AF5101B80A00036A8F9100143C0508002E
-:1065C00024A55A980E00027D240400828F90001C9E
-:1065D000000030210A000369AF8600283C0408004F
-:1065E0008C845A980E0014F6000000008F90001C56
-:1065F0000A000486000018210E00033624040081DE
-:106600000A0003EE8F90001C3C05080024A55A9850
-:106610000E00027D2404008B8F90001C0011302B93
-:106620000A000369AF8600283C1908008F395A9880
-:106630003C1F08008FFF005024CCFFFE033F782151
-:1066400001F87024AF4E00283C0408008C845A984E
-:106650003C0908008D2900500089682131A5007F80
-:1066600000BA402101078021AE0600D8AF9000D0CB
-:10667000AE0000DC0A0003B8AE0C0108AF60008475
-:106680003C0808008D085A983C0D08008DAD00505C
-:106690002405FF803C02000C010D58210165602497
-:1066A000AF4C00288E0A00143174007F029A182122
-:1066B00000627821ADEA00D88E1F0014AF8F00D0A1
-:1066C000ADFF00DC8E1900102738FFFE0A00040B16
-:1066D000ADF80108548CFE27240540000A00043D53
-:1066E000240510000E00032B000000000A0003EE3A
-:1066F0008F90001C8C46442C3C056C6234B0797041
-:106700003C010800AC205A9814D000082404000270
-:1067100097880034978A002C02802821010A382BA0
-:1067200010E0001124040092240400020E000C89E1
-:10673000240501403C010800AC225A98AF420020D9
-:106740003C0308008C635A98106000052404008301
-:106750000E000854000000001040000924040083CB
-:106760003C05080024A55A980E00025400000000C1
-:106770008F90001C0011202B0A000369AF840028B1
-:106780000E000858000000000A0005308F90001C21
-:106790008E0400080E000231000000000A00058689
-:1067A000AE8200083C05080024A55A980E00022677
-:1067B000240400878F90001C0A0005A20011102BF2
-:1067C0000E00085C000000003C05080024A55A9853
-:1067D0000A00063A2404008B0E00024602802021A3
-:1067E0009370002302802021360D00100E00024F0E
-:1067F000A36D00238F90001C0A0005AB0000182138
-:10680000240400040E000C89240500301440002AE2
-:10681000004048218F90001C0A00051724050083C2
-:106820009205000C30BF000113E0000300000000DF
-:106830009602000EA482002C920A000C314800023D
-:106840001100FF5100002821960B00128E03001446
-:10685000A48B001A0A0005C2AC83001C8F83003889
-:106860008F8700301067FE84000020213C0908005B
-:1068700025295A1C000320C0008930218CD4000037
-:106880001285005E247800013303000F5467FFFA7D
-:10689000000320C00A0004FE000020213C0508007F
-:1068A00024A55A980E00027D240400828F90001CBB
-:1068B0000A0005A2000010213C0B0008034B202118
-:1068C00024030050240A0001AF420020A0830000EE
-:1068D000A08A00018F88001C91070004A08700187F
-:1068E0008F82001C90450005A08500198F86001C32
-:1068F00090DF0006A09F001A8F99001C93380007B4
-:10690000A098001B8F94001C928F0008A08F001C81
-:106910008F90001C920E0009A08E001D8F8D001C10
-:1069200091AC000AA08C001E8F8B001C3C0C080050
-:10693000258C5A1C9163000B3C0B0800256B5A18E0
-:10694000A083001F8F8A001C9148000CA0880020A3
-:106950008F87001C90E5000DA08500218F82001C10
-:10696000240546469046000EA08600228F9F001CFC
-:1069700093F9000FA09900238F98001C9314001026
-:10698000A09400248F8F001C91F00011A09000258E
-:106990008F90001C8F8E00308F990038960D001458
-:1069A000000E18C025C80001A48D0028960A001604
-:1069B000006C3021006BF821A48A002A9607001889
-:1069C0003108000FA487002CA485002E8E02001C25
-:1069D000ACC90000AF88003011190003AFE200001D
-:1069E0000A00051700002821250C00013184000F42
-:1069F000000028210A000517AF8400383C07080072
-:106A000024E75A180087802100002021ACC0000034
-:106A10000A0004FEAE0000003C05080024A55A98B8
-:106A20000A00063A240400878E0400040E00023196
-:106A3000000000000A00053BAE8200083084FFFF22
-:106A400030C600FF8F4201B80440FFFE000644003C
-:106A5000010430253C07200000C720253C0310001E
-:106A6000AF400180AF450184AF44018803E00008D6
-:106A7000AF4301B827BDFFE8AFB00010AFBF0014AF
-:106A80003C076000240600021080000600A0802160
-:106A90000010102B8FBF00148FB0001003E000080F
-:106AA00027BD00183C09600EAD2000348CE5201C89
-:106AB0008F82001C2408FFFC00A81824ACE3201CD3
-:106AC0000E0006EF8C45000C0010102B8FBF001439
-:106AD0008FB0001003E0000827BD00183C02600ED4
-:106AE0003447010024090018274A04000000000070
-:106AF00000000000000000003C06005034C302000B
-:106B0000AF440038AF45003CAF430030014018218E
-:106B10008F4B0000316800201100FFFD2406007F2C
-:106B20002408FFFF8C6C000024C6FFFF24630004D0
-:106B3000ACEC000014C8FFFB24E7000400000000D8
-:106B400000000000000000003C0F0020AF4F0030AC
-:106B50000000000024AD020001A5702B2529FFFFD5
-:106B6000008E20211520FFE101A0282103E000086C
-:106B70000000000027BDFFE0AFB10014AFBF001858
-:106B8000AFB000103C05600E8CA20034008088215C
-:106B9000144000063C0460008C87201C2408FFFC85
-:106BA00000E8302434C30001AC83201C8F8B001C10
-:106BB00024090001ACA90034956900028D65001418
-:106BC0008D70000C2D2400818D6700048D660008F7
-:106BD000108000078D6A00102D2C00041580000E17
-:106BE00030CE0007312D000311A0000B0000000083
-:106BF0002404008B020028210E0006EF2406000367
-:106C00000011102B8FBF00188FB100148FB000102F
-:106C100003E0000827BD002015C0FFF62404008B08
-:106C20003C030020AF4300300000000024020001BC
-:106C3000AF8200140000000000000000000000000F
-:106C40003C1F0150013FC825253800033C0F600E52
-:106C5000AF47003800181882AF46003C35E8003CCA
-:106C6000AF590030274704008F44000030860020D1
-:106C700010C0FFFD00000000106000082466FFFF48
-:106C80002403FFFF8CEB000024C6FFFF24E7000471
-:106C9000AD0B000014C3FFFB250800043C08600E88
-:106CA000AD090038000000000000000000000000F6
-:106CB0003C070020AF470030000000000E0007171F
-:106CC0000140202102002821000020210E0006EFB3
-:106CD000240600030011102B8FBF00188FB1001481
-:106CE0008FB0001003E0000827BD002027BDFFD8AB
-:106CF000AFB200183092FFFFAFB10014AFBF002059
-:106D0000AFB3001CAFB000101240002C000088216F
-:106D10000A0007AF2413000150B3003C8CE5000CBF
-:106D20000000000D262D000131B1FFFF24EC0020F2
-:106D30000232382B10E00021AF8C001C8F8200142F
-:106D40001440001E8F87001C3C0670003C0320008E
-:106D50008CE400000086282414A300188F85003CD2
-:106D6000000444023C0980000089802414A0FFEA4A
-:106D7000310600FF2404000210C4001F28CA0003CB
-:106D800011400016240B000314D3FFE7262D000149
-:106D9000020028210E0006FD240400018F87001C3C
-:106DA000AF82003C262D000131B1FFFF24EC002012
-:106DB0000232382B14E0FFE1AF8C001C02201021BE
-:106DC0008FBF00208FB3001C8FB200188FB100144A
-:106DD0008FB0001003E0000827BD002814CBFFD2BD
-:106DE000262D00010E00073D020020218F87001C88
-:106DF0000A0007C9AF82003C020028210E0006FDF0
-:106E0000000020210A0007C88F87001C0E0006EF33
-:106E1000240400841600FFC38F87001C0A0007A902
-:106E2000AF80003C3082FFFF1440000300001821B7
-:106E30000004240224030010308500FF14A0000584
-:106E40003087000F246600080004220230C300FFD0
-:106E50003087000F14E00005308900032468000427
-:106E600000042102310300FF3089000315200005D2
-:106E7000388B0001246A000200042082314300FFA5
-:106E8000388B00013164000110800002246C000185
-:106E9000318300FF03E0000800601021308BFFFF0A
-:106EA000000B394230E600FF3C09080025295998BB
-:106EB00000064080010960218D8700003164001FB9
-:106EC000240A0001008A180430A500FF00E32025F1
-:106ED00014A000020003102700E22024240F000168
-:106EE00000CF700401096821000E282714800005D6
-:106EF000ADA400008F86000C00A6102403E000085B
-:106F0000AF82000C8F88000C01C8102503E0000838
-:106F1000AF82000C3C06001F3C0360003084FFFF82
-:106F200034C5FF8024020020AC602008AC60200C37
-:106F3000AC602010AC652014AC642018AC6220005A
-:106F4000000000000000000003E000080000000056
-:106F500027BDFFE82402FFFFAFBF0010AF82000C87
-:106F6000000020213C06080024C659982405FFFF94
-:106F700024890001000440803124FFFF010618210C
-:106F80002C87002014E0FFFAAC6500000E000825F5
-:106F900000002021240200013C04600024050020A0
-:106FA000AC822018AC85200000000000000000002A
-:106FB00000000000244A00013142FFFF2C4604007B
-:106FC00014C0FFF78FBF001003E0000827BD0018B2
-:106FD0008F8300082C62040003E00008384200019F
-:106FE0008F8300082462000103E00008AF820008DC
-:106FF0008F8300082462FFFF03E00008AF820008CF
-:1070000027BDFFE0AFB10014AFBF0018AFB0001054
-:107010008F6B00303C06600000808821ACCB2008DC
-:107020008F6A002C3C02800024030008ACCA200CAC
-:107030009769003A9768003800092C003107FFFF74
-:1070400000A72025ACC42010ACC22014ACC3200083
-:107050000000000000000000000000003C03600091
-:107060008C6D200031AC00081580FFF90000000095
-:107070008C6E201405C00020000000000E0007E9FF
-:107080008F84000C000240803C0908002529599893
-:10709000010938218CE400000E0007E9000281405C
-:1070A000020220213090FFFF020020210E0008077D
-:1070B000000028213C0C8000022C58253210FFFFD4
-:1070C0003C116000240A0020AE2B2014AE302018A2
-:1070D000AE2A2000000000000000000000000000B8
-:1070E000020010218FBF00188FB100148FB0001064
-:1070F00003E0000827BD00208C6620143C02001F1E
-:107100003443FF803C1FFFE800C3C02437F9080068
-:1071100003198021001079C23C0C8000022C5825F4
-:1071200031F0FFFF3C116000240A0020AE2B201438
-:10713000AE302018AE2A2000000000000000000041
-:1071400000000000020010218FBF00188FB1001452
-:107150008FB0001003E0000827BD002027BDFFE826
-:10716000AFB000103402FFFF3090FFFFAFBF00143C
-:1071700012020006020020210E0008250000000077
-:10718000020020210E000807240500018F8400085A
-:107190008FBF00148FB000102483FFFF27BD00189D
-:1071A00003E00008AF830008000439C230E6003F66
-:1071B00000043B4200071840240210002CC40020A9
-:1071C00024C8FFE0AF42002C2463000114800003B8
-:1071D00030A900FF00071840310600FF000360805F
-:1071E00024080001019A58213C0A000E00C8280416
-:1071F000016A382111200005000530278CE90000C4
-:107200000125302503E00008ACE600008CEE00000C
-:1072100001C6682403E00008ACED000027BDFFE8CC
-:10722000AFBF0014AFB000103C0460008C850808AC
-:107230003403F00030A2F0005043000624020001A5
-:107240008C8708083404E00030E6F00010C4001E0B
-:1072500024020002AF8200403C1060003C0A0200A1
-:10726000AE0A0814240910003C08000E8E034400E6
-:1072700003482021AF49002C240501200E000CCF2B
-:10728000000030218F830040106000043C02169102
-:10729000240B0001106B000E3C023D6C344F00903B
-:1072A000AE0F44088FBF00148FB000103C0C60007C
-:1072B000240E10003C0D020027BD0018AD8E4420A6
-:1072C00003E00008AD8D08100A0008F6AF8000400A
-:1072D0003C0218DA344F0090AE0F44088FBF001400
-:1072E0008FB000103C0C6000240E10003C0D02001A
-:1072F00027BD0018AD8E442003E00008AD8D0810B6
-:107300000A0008CA240500010A0008CA0000282152
-:107310003C08080025085DA42404FFFF0100182193
-:107320002402001E2442FFFFAC6400000441FFFD64
-:10733000246300043C07080024E75E208CE5FFFC82
-:107340002404001C24060001308A001F0146480462
-:1073500024840001000910272C8300201460FFFA08
-:1073600000A22824ACE5FFFC3C05666634A4616EEF
-:107370003C06080024C65EE0AF840058AF88009C3D
-:107380002404FFFF00C018212402001F2442FFFF35
-:10739000AC6400000441FFFD246300043C07666602
-:1073A0003C05080024A55EA0AF86004834E6616E67
-:1073B000AF8600982404FFFF00A018212402000FCC
-:1073C0002442FFFFAC6400000441FFFD246300047D
-:1073D0003C0B66663C06080024C65E203568616E7C
-:1073E000AF8500A4AF8800702404FFFF00C01821FF
-:1073F0002402001F2442FFFFAC6400000441FFFD93
-:10740000246300043C0D66663C0A0800254A5F6060
-:1074100035AC616EAF860090AF8C005C2404FFFF3A
-:1074200001401821240200032442FFFFAC64000045
-:107430000441FFFD246300043C09080025295F7016
-:107440008D27FFFC24040006240500013099001F4D
-:107450000325C00424840001001878272C8E002006
-:1074600015C0FFFA00EF3824AD27FFFC3C09666623
-:1074700024030400240403DC24050200240600661F
-:107480003522616E3C08080025085AA4AF820074BA
-:10749000AF830044AF83006CAF830050AF830084A0
-:1074A000AF8A008CAF840064AF85004CAF86005477
-:1074B000AF840078AF850060AF860080010018219E
-:1074C000240200022442FFFFAC6000000441FFFDE3
-:1074D00024630004240400032403000C3C0A080075
-:1074E000254A5AB0AF8A00680A00099D2405FFFFAB
-:1074F0000004188024840001006858212C8700C0F3
-:1075000014E0FFFBAD6500003C0E666635CD616E94
-:10751000240C17A024081800AF8D0088AF8C0094AD
-:1075200003E00008AF88007C2484007F000421C2AF
-:1075300000004021000030210000382100002821F7
-:107540000A0009B4AF8400A01060000624E700011F
-:1075500000C4302124A500012CC20BF51440FFFA11
-:107560002CA300663C09080025295F600120182132
-:10757000240200032442FFFFAC6000000441FFFD31
-:107580002463000410E0001A24E3FFFF00032942F3
-:1075900010A0000A000020212406FFFF3C03080081
-:1075A00024635F60248400010085502BAC660000DA
-:1075B000250800011540FFFB2463000430E2001F92
-:1075C0001040000800086880240C0001004C3804BA
-:1075D000000858800169282124E6FFFF03E0000825
-:1075E000ACA6000001A940212409FFFFAD0900005D
-:1075F00003E0000800000000AF4400283C04000C39
-:1076000003442021000528820A000CCF000030210D
-:10761000000421803C036000AC64100800000000FE
-:1076200000052980AC65100C0000000003E0000894
-:107630008C62100C27BDFFE800802821240400384C
-:10764000AFBF00140E0009E4AFB0001024040E0018
-:10765000AF4400283C10000C0350202124050010EA
-:107660000E000CCF0000302103501021AC40000070
-:10767000AC400004240400388FBF00148FB0001009
-:1076800024053FFF27BD00180A0009E48C430000D1
-:10769000000421803C036000AC641008000000007E
-:1076A0008C62100C03E000080002118227BDFFC8A5
-:1076B000AFB400208F940068AFBE0030AFB7002C8D
-:1076C000AFB600280000B8210080B021241E00C001
-:1076D000AFBF0034AFB50024AFB3001CAFB2001889
-:1076E000AFB10014AFB000100A000A21AFA5003CF2
-:1076F000504000018F94006827DEFFFF13C0002870
-:10770000269400048E9200003C03080024635DA0D0
-:107710001240FFF70283102B3C04080024845AA473
-:10772000028410230002A8C0000098210A000A3039
-:1077300024110001001188401220002600000000E2
-:1077400002B38021025128240200202110A0FFF959
-:10775000267300010E0009ED0000000000166840CD
-:1077600032EC000101AC20210E0009E402002821C6
-:107770008F89009426F700018FA6003C3AEB0001A8
-:10778000316A00012528FFFF0011382702CAB02105
-:10779000AF88009416E6FFE702479024AE920000FF
-:1077A00002E010218FBF00348FBE00308FB7002C55
-:1077B0008FB600288FB500248FB400208FB3001C33
-:1077C0008FB200188FB100148FB0001003E00008D2
-:1077D00027BD00383C0E080025CE5DA0028E102B80
-:1077E0000A000A1CAE92000027BDFFD8AFB10014FA
-:1077F000AFB00010AFBF0020AFB3001CAFB2001895
-:1078000000A0882110A0001F000480403C13080045
-:1078100026735AA40A000A692412000112200019D2
-:10782000261000010E000A0402002021000231424D
-:107830002444FFA0000618803045001F2C8217A1A9
-:10784000007318212631FFFF1040FFF400B230040E
-:107850008C6900000200202124053FFF01264024FE
-:107860001500FFEE012638250E0009E4AC67000084
-:107870008F8A009426100001254700011620FFE999
-:10788000AF8700948FBF00208FB3001C8FB2001809
-:107890008FB100148FB0001003E0000827BD00284E
-:1078A0008F85009C00805821000040210000482165
-:1078B000240A001F3C0C0800258C5E1C3C0D0800AF
-:1078C00025AD5DA48CA6000050C00014000040212E
-:1078D00000AD1023000238C0240300010A000AA2F0
-:1078E000000020211500000300E41021244820247A
-:1078F0000000482125290001512B00132506DFDC5B
-:10790000106000062484000100C3702415C0FFF538
-:10791000000318400A000AA00000402110AC002615
-:1079200024A3000400602821254AFFFF1540FFE53D
-:10793000AF85009C512B00042506DFDC00004021B0
-:1079400003E00008010010210006614230C5001F5D
-:10795000000C50803C07080024E75DA424040001CB
-:10796000014730211120000F00A420043C0508002D
-:1079700024A55E20148000052529FFFF24C60004ED
-:1079800010C5001100000000240400018CCF00008D
-:107990000004C0270004204001F868241520FFF5EA
-:1079A000ACCD00008F99007801001021032B4823F3
-:1079B00003E00008AF8900783C05080024A55DA419
-:1079C0000A000AAA000040213C06080024C65DA463
-:1079D0000A000AC324040001308800FF24020002C8
-:1079E0001102000A240300031103005C8F8900A424
-:1079F000240400041104005F24050005110500673C
-:107A00000000182103E00008006010218F89004861
-:107A10003C0C0800258C5EE03C04080024845F6078
-:107A2000240300201060000F00005821240D0002E4
-:107A3000240E00033C0F080025EF5EE08D270000B8
-:107A400014E0000B30F9FFFF252900040124C02BAE
-:107A500053000001018048212463FFFF5460FFF8B8
-:107A60008D2700000160182103E00008006010214C
-:107A7000132000323C0500FF30E200FF00403021BF
-:107A80001040004200005021240500010000202188
-:107A90000005C84000A6C02417000003332500FFDE
-:107AA00014A0FFFB24840001012CC023001828C06F
-:107AB00000AA6021008C50213144001F240C0001D9
-:107AC000008C18040003102700E23024110D00413F
-:107AD000AD260000110E004C000A1840110D0036B2
-:107AE0008F87006C510E00568F8C0060240D0004AF
-:107AF000110D005A8F8E0084240E0005150EFFDA3A
-:107B000001601821240B14301140000600001821D8
-:107B10008F8400A024630001006A402B1500FFFD44
-:107B2000016458218F8A0080AF89008C0160182180
-:107B30002549FFFF0A000AFAAF89008000E52024EA
-:107B4000000736021080FFD0240A001800075402F4
-:107B5000314600FF0A000B02240A00103C0C08000A
-:107B6000258C5EA03C04080024845EE00A000AE93B
-:107B7000240300103C0C0800258C5E203C04080007
-:107B800024845EA00A000AE88F89009000071A0288
-:107B9000306600FF0A000B02240A00088F89008C5F
-:107BA0003C0C0800258C5F603C04080024845F7056
-:107BB0000A000AE924030004000A4080250B003073
-:107BC00024E6FFFF01601821AF8900480A000AFA85
-:107BD000AF86006C000AC982001978803C07080053
-:107BE00024E75EA001E72021000A18428C8F0000E4
-:107BF0003079001F032C38040007C02701F86024E7
-:107C00000A000B17AC8C00000003314200062880EC
-:107C100000AF28213062001F8CB8000024630001EF
-:107C2000004CC804000321420019382700041080CA
-:107C300003073024004F20210A000B5BACA6000094
-:107C4000000A68C025AB0032258AFFFF01601821B9
-:107C5000AF8900A40A000AFAAF8A0060254B1030F1
-:107C6000AF8900900160182125C9FFFF0A000AFAB8
-:107C7000AF890084308600072CC200061040001433
-:107C800000000000000640803C030800246357D039
-:107C9000010338218CE4000000800008000000008F
-:107CA0002409000310A9000E00000000240A0005AA
-:107CB00010AA000B00000000240B000110AB00080C
-:107CC000000000008F8C00A010AC00050000000038
-:107CD00003E00008000010210A000A8800A020210B
-:107CE0000A000AD600C0202127BDFFE8308400FF2B
-:107CF000240300021083000BAFBF00102406000312
-:107D00001086003A2408000410880068240E00053C
-:107D1000108E007F2CAF14308FBF001003E00008DE
-:107D200027BD00182CA200301440FFFC8FBF0010AC
-:107D300024A5FFD0000531C2000668803C0708007A
-:107D400024E75EE001A730218CC9000000052882ED
-:107D500030AC001F240B0001018B50048F840048BD
-:107D6000012A4025ACC800008C830000506000014F
-:107D7000AF8600488F98006C30AE000124A6FFFF4C
-:107D8000270F000115C00002AF8F006C24A6000170
-:107D90000006414200082080008718218C790000ED
-:107DA00030C2001F240600010046F804033F3824B7
-:107DB00010E0FFDA8FBF00100005C182001870804C
-:107DC0003C0F080025EF5EA001CF48218D2B00005D
-:107DD0000005684231A5001F00A66004016C502513
-:107DE00027BD001803E00008AD2A00002CA70030D2
-:107DF00014E0FFCA8FBF001030B900071723FFC778
-:107E000024A8FFCE00086A02000D60803C0B080029
-:107E1000256B5EA0018B30218CC40000000828C2B5
-:107E200030AA001F24080001014848048F8200A4E2
-:107E300000891825ACC300008C5F000053E00001EE
-:107E4000AF8600A400057040000E7942000F288024
-:107E50003C04080024845EE000A418218C6B000020
-:107E600025DF000131CD001F001F514201A8600431
-:107E7000016C4825000A1080AC69000000442821EC
-:107E80008CA600008F98006033F9001F8FBF001090
-:107E90000328380400C77825270E000127BD0018E5
-:107EA000ACAF000003E00008AF8E006024A5EFD067
-:107EB0002CB804001300FF998FBF00100005314259
-:107EC000000658803C0A0800254A5E20016A3021DD
-:107ED0008CC4000030A3001F2409000100691004B5
-:107EE0008F9900900082F825ACDF00008F270000FA
-:107EF00050E00001AF8600908F8D00848FBF00108E
-:107F000027BD001825AC000103E00008AF8C0084F9
-:107F100015E0FF828FBF00108F8600A00006104082
-:107F20000046F821001F210003E4C8210019384051
-:107F300024F8143000B8402B1100FF788FBF0010D8
-:107F400024A4EBD00E00020300C0282100027942D5
-:107F5000000F70803C0D080025AD5F6001CD202131
-:107F60008C8B0000304C001F240600010186180491
-:107F70008F89008C01635025AC8A00008D2500009C
-:107F800050A00001AF84008C8F9800808FBF00103C
-:107F900027BD00182708000103E00008AF88008013
-:107FA00030A500072403000310A3001028A200043A
-:107FB00014400008240700022403000410A3001545
-:107FC0002408000510A8000F8F8500A003E000081A
-:107FD0000000000014A7FFFD0080282114C3FFFB50
-:107FE000240400020A000B9A000000002409000586
-:107FF0000080282110C9FFFB2404000303E00008CF
-:108000000000000014C5FFF1008028210A000B9A2F
-:1080100024040005240A00010080282110CAFFF171
-:108020002404000403E000080000000027BDFFE076
-:10803000AFB00010000581C22603FFD024C5003F69
-:108040002C6223D024C6007FAFB20018AFB1001459
-:10805000AFBF001C309100FF000691C200052982CD
-:1080600002002021104000082403FFFF0E000A5ADE
-:108070000000000002002021022028210E000C48F0
-:1080800002403021000018218FBF001C8FB2001861
-:108090008FB100148FB000100060102103E00008C1
-:1080A00027BD002027BDFFD824A2007FAFB3001C4E
-:1080B000AFB20018000299C2309200FF24A3003F23
-:1080C0000240202102602821AFB10014AFB000109F
-:1080D000AFBF00200E000B7D00038982004080218D
-:1080E000004020210220282114400009000018210E
-:1080F0008FBF00208FB3001C8FB200188FB1001407
-:108100008FB000100060102103E0000827BD002898
-:108110000E000A0B00000000004028210200202170
-:108120001051FFF3001019C00E000A5A00000000A1
-:1081300002002021024028210E000C48026030215C
-:108140008FBF00208FB3001C8FB200188FB10014B6
-:108150008FB00010000018210060102103E000081B
-:1081600027BD00283084FFFF30A5FFFF10800007E7
-:10817000000018213082000110400002000420425B
-:10818000006518211480FFFB0005284003E000086B
-:108190000060102110C00007000000008CA2000049
-:1081A00024C6FFFF24A50004AC82000014C0FFFB1E
-:1081B0002484000403E000080000000010A0000870
-:1081C00024A3FFFFAC8600000000000000000000B8
-:1081D0002402FFFF2463FFFF1462FFFA24840004DB
-:1081E00003E000080000000030A5FFFF8F4201B847
-:1081F0000440FFFE3C07601500A730253C0310003B
-:10820000AF440180AF400184AF46018803E000081D
-:10821000AF4301B88F8500D02C8640000080182124
-:108220008CA700840087102B144000100000000071
-:108230008CA800842D06400050C0000F240340008D
-:108240008CAA0084008A482B512000018CA3008452
-:1082500000035A42000B20803C05080024A558204A
-:108260000085182103E000088C62000014C0FFF4B0
-:10827000000000002403400000035A42000B20804D
-:108280003C05080024A558200085182103E00008BB
-:108290008C6200008F8300D0906600D024C500015E
-:1082A000A06500D08F8500D0906400D090A200D24D
-:1082B0001044001700000000936C00788F8B00BC06
-:1082C000318A00FFA16A000C25490001938700C490
-:1082D000312200FF3048007F1107000B00026827A1
-:1082E000A36200788F4E017805C0FFFE8F9900B021
-:1082F000241800023C0F1000AF590140A35801445C
-:1083000003E00008AF4F01780A000D1831A2008089
-:10831000A0A000D00A000D0E000000008F8700D042
-:1083200027BDFFC8AFBF0030AFB7002CAFB60028E5
-:10833000AFB50024AFB40020AFB3001CAFB200183B
-:10834000AFB10014AFB0001094E300E094E200E29B
-:10835000104300D72405FFFF3C047FFF3497FFFF45
-:108360002415FF800A000DFF3C16000E108A00D174
-:108370008FBF00308F9100B03C1808008F18005C50
-:10838000001230C0001291400311702101D57824F1
-:10839000AF4F002C94EC00E231CD007F01BA5821A0
-:1083A000318A7FFF01764821000A804002091021AE
-:1083B000945300003C0808008D0800580246C02174
-:1083C00032733FFF0013198001032021022428216A
-:1083D00030BF007F03FAC82100B5A024AF54002CA1
-:1083E0000336A0218E8700108E8F0030037858212D
-:1083F000256D008800EF7023240C0002AE8E001063
-:10840000AF8D00ACA16C0088976A003C8E84003070
-:108410008F9100AC0E000CE53150FFFF00024B8045
-:10842000020940253C02420001022025AE2400043E
-:108430008E8300048F8D00AC8E860000240E000811
-:10844000ADA3001CADA60018ADA0000CADA000109F
-:10845000929F000A33F900FFA5B900149685000821
-:108460003C1F000CA5A500169298000A331100FFCE
-:10847000A5B100209690000824180005A5B00022A0
-:10848000ADA00024928F000B2410C00031E700FF44
-:10849000A5A70002A1AE00018E8C00308F8B00AC2E
-:1084A0008F8400B0AD6C00083C0A08008D4A00546F
-:1084B0000144482101354024AF4800283C0208000F
-:1084C0008C4200540044302130C3007F007AC82120
-:1084D000033F282102458821AF9100BCAF8500C031
-:1084E000A23800008F8A00BC2403FFBF2418FFDFDE
-:1084F000954F000201F0382400F37025A54E0002CC
-:10850000914D000231AC003F358B0040A14B000281
-:108510008F8600BC8F8900D0ACC000048D28007C01
-:108520003C098000ACC8000890C4000D3082007F78
-:10853000A0C2000D8F8500BC90BF000D03E3C824CE
-:10854000A0B9000D8F9100BC9233000D02789024E9
-:10855000A232000D8E9000348F8B00BCAD700010E5
-:108560008E87002C8E8F003000EF7023AD6E0014CC
-:10857000916D001831AC007FA16C00188F9F00BC7A
-:108580008E8A00308FE8001801572024010930241A
-:1085900000C41025AFE200189283000AA3E3001C78
-:1085A000969900088F8500BC8F9800D0A4B9001E52
-:1085B0008E9000308E8400300E0002038F05008400
-:1085C0008F8500D0000291400002990090AF00BC5E
-:1085D000025388210040302131E7000210E00003FF
-:1085E00002118021000290800212802190B900BC0B
-:1085F0003327000410E000020006F880021F8021EB
-:108600008E9800308F8B00BC24068000330F00034F
-:10861000000F702331CD0003020D6021AD6C00040A
-:1086200094A400E294AA00E294B000E231497FFFF2
-:108630002522000130537FFF0206182400734025D5
-:10864000A4A800E294A400E23C1408008E94006008
-:1086500030917FFF12340022000000000E000D0553
-:10866000000000008F8700D00000282194F300E074
-:1086700094F000E21213000F8FBF003090E900D099
-:1086800090E800D1313200FF310400FF0244302B6A
-:1086900014C0FF36264A000190EE00D2264B00019E
-:1086A00031CD00FF008D6021158BFF338F9100B01D
-:1086B0008FBF00308FB7002C8FB600288FB50024F5
-:1086C0008FB400208FB3001C8FB200188FB100143C
-:1086D0008FB0001000A0102103E0000827BD003873
-:1086E00094A300E200664024A4A800E290A400E263
-:1086F00090B900E2309100FF0011A1C20014F827E8
-:10870000001F39C03332007F024730250A000DF7C1
-:10871000A0A600E23084FFFF30A5FFFFAF440018A1
-:10872000AF45001C03E000088F42001427BDFFB8CE
-:10873000AFB000208F9000D03084FFFFAFA40010B6
-:10874000AFBF0044AFBE0040AFB7003CAFB600388B
-:10875000AFB50034AFB40030AFB3002CAFB20028D7
-:10876000AFB10024A7A00018920600D1920500D056
-:1087700030C400FF30A300FF0064102B1040012222
-:10878000AFA00014920900D08FB50010312800FF6F
-:108790000088382324F4FFFF0014882B0015982B41
-:1087A00002339024524001268FB40014961E00120A
-:1087B000961F00108FB7001003DFC82300171400A6
-:1087C0000019C400000224030018140302E2B02AB6
-:1087D00052C00001004020210284282B10A000027A
-:1087E000008018210280182100033C0000071C03B0
-:1087F0003064FFFF2C86000914C000020060B8211D
-:10880000241700088E0A0008001769808E09000CE2
-:1088100031ABFFFF3C0C0010016C402527520400D7
-:10882000AF4A0038AF9200B8AF49003CAF480030C3
-:108830000000000000000000000000000000000038
-:108840000000000000000000000000000000000028
-:108850008F4F000031EE002011C0FFFD0017982A55
-:10886000027110240A000E920000B02155E00101AF
-:108870009258000131130080126001CF01202021A5
-:108880009655001232A5FFFF0E000CDAA7B50018AE
-:108890008F9000D00291A02326C800018F9100B8CC
-:1088A0000008B4000016B403262C004002D7782A32
-:1088B0000014882B240B00010180902101F1102469
-:1088C000AF8C00B8AFAB0014104001BC8F8900B072
-:1088D0003C0C08008D8C0054240BFF80921E00D0AD
-:1088E00001895021014B2824921900D0AF4500285E
-:1088F0008E4700103C0808008D0800583C180800FE
-:108900008F18005430E33FFF000321800104302121
-:10891000012658212402FF800162F824920C00D025
-:10892000AF5F002C9248000033D100FF333500FFC9
-:108930000309982100117140001578C0326D007F45
-:1089400001CF382101BA2821318300FF3164007F33
-:108950003C0A000C00AA88210367F0210003314083
-:10896000009A10213108003F3C1F000E00D1C021A9
-:10897000005F982127D900882D150008AF9100C00D
-:10898000AF9900ACAF9800BCAF9300B412A0018ABD
-:1089900000008821240E0001010E4004310D005D0D
-:1089A00011A0FFB2310F00028E4A00283C03008064
-:1089B0003C04FFEFAE6A00008E450024A260000A6E
-:1089C0003488FFFFAE6500049247002C3C1FFF9FD8
-:1089D00037FEFFFFA267000C8E62000C3C180040BF
-:1089E000A267000B0043302500C8C824033E88243A
-:1089F0000238A825AE75000C8E490004AE60001840
-:108A00003C0F00FFAE6900148E4D002C35EEFFFFC9
-:108A10008F8B00B001AE6024AE6C00108E47000852
-:108A2000A660000896450012AE6700208E42000C3A
-:108A300030B03FFF00105180AE6200248E5E001403
-:108A4000014B182130A40001AE7E00288E59001879
-:108A5000000331C200044380AE79002C8E51001C0B
-:108A600000C8F821A67F001CAE71003096580002A5
-:108A70008E550020A678001EAE7500349249003352
-:108A80003130000456000005925000008F8C00D059
-:108A90008D8B007CAE6B0030925000008F8F00BC3D
-:108AA000A1F00000924E003331CD000251A000072A
-:108AB000925E00018F8900BC2418FF809131000074
-:108AC0000311A825A1350000925E00018F9900BC1A
-:108AD0002409FFBF240BFFDFA33E00018F9500BCDC
-:108AE00092B8000D3311007FA2B1000D8F8E00BC33
-:108AF00091D0000D02097824A1CF000D8F8800BC11
-:108B00008E6D0014910A000D2DAC0001000C29405F
-:108B1000014B382400E51825A103000D96420012F0
-:108B20008F8800BC8F8700D0A50200028E4500040C
-:108B300090FF00BC30A400030004302330DE0003AB
-:108B400000BE102133F90002172000022444003433
-:108B50002444003090E200BC00A2302430DF000446
-:108B600017E0000224830004008018218F8F00ACDE
-:108B700024090002AD030004A1E90000924E003F69
-:108B80008F8D00ACA1AE00018F9500AC924C003FE0
-:108B90008E440004A6AC0002976B003C0E000CE56E
-:108BA0003170FFFF00025380020A38253C05420065
-:108BB00000E51825AEA300048F8600AC8E4800386F
-:108BC000ACC800188E440034ACC4001CACC0000C0F
-:108BD000ACC00010A4C00014A4C00016A4C00020A3
-:108BE000A4C00022ACC000248E6400145080000198
-:108BF00024040001ACC400080E000D05241100017E
-:108C00000A000E858F9000D0920F00D2920E00D0F5
-:108C10008FB5001031EB00FF31CD00FF008D6023D8
-:108C2000016C50212554FFFF0014882B0015982B50
-:108C3000023390241640FEDD000000008FB40014C3
-:108C40008FBF00448FBE00403A8200018FB7003CC6
-:108C50008FB600388FB500348FB400308FB3002C3E
-:108C60008FB200288FB100248FB0002003E00008ED
-:108C700027BD004833110020122000EE241500010A
-:108C8000921E00BC241F00010000A82133D900015E
-:108C90001320000DAFBF001C8E4400148E0800840A
-:108CA0000088102B14400002008030218E060084C2
-:108CB0008E03006400C3A82B16A0000200C0202170
-:108CC0008E0400640080A8218E4700148E05006485
-:108CD00000E5302B14C0000200E020218E04006467
-:108CE0000095F02313C000048FAC001C240A00027E
-:108CF000AFAA001C8FAC001C028C582B156000A87A
-:108D0000000018218E4F00388E6D000C3C0E008044
-:108D1000AE6F00008E4A00343C10FF9F01AE582514
-:108D2000AE6A00049246003F360CFFFF016C382407
-:108D30003C0500203C03FFEFA266000B00E5102578
-:108D40003468FFFF8F8700B80048F8243C0400080F
-:108D500003E4C825AE79000C8CF80014AE6000184E
-:108D600002BE7821AE7800148CF10018AE71001CA0
-:108D70008CE90008AE6900248CEE000CAE6F002C6C
-:108D8000AE600028AE6E0020A6600038A660003AF3
-:108D90008CED001401B58023021E902312400011B7
-:108DA000AE72001090EA003D8E6500048E640000F3
-:108DB000000A310000A6C821000010210326402B24
-:108DC0000082F82103E8C021AE790004AE780000EB
-:108DD00090F1003DA271000A8F8900B8953200061B
-:108DE000A67200088F9800AC2419000202A020216E
-:108DF000A31900009769003C8F9200AC0E000CE5AF
-:108E00003131FFFF00027B808F8500B8022F68257B
-:108E10003C0E420001AE8025AE5000048F8400ACB1
-:108E20008CAC0038AC8C00188CAB0034AC8B001CC4
-:108E3000AC80000CAC800010A4800014A48000164C
-:108E4000A4800020A4800022AC80002490A7003FD2
-:108E5000A487000212A001342403000153C00002C1
-:108E600090A2003D90A2003E24480001A08800018D
-:108E70008F9F00ACAFF500088F8300D0240700342B
-:108E8000906600BC30C5000250A0000124070030ED
-:108E90008F9200B88F8A00BC906D00BC924B00008E
-:108EA0002412C00032A50003A14B00008F8600B839
-:108EB0008F8800BC2402000490C4000100451823E0
-:108EC00030790003A10400018F8A00BC8F9F00B895
-:108ED00000F538219558000297E9001200F9382171
-:108EE00003128824312F3FFF022F7025A54E000268
-:108EF0009150000231A80004320C003F358B004035
-:108F0000A14B000212A000028F8500BC00E83821AE
-:108F10008F8E00D0ACA70004240BFFBF8DCD007C4A
-:108F20002EA400012403FFDFACAD000890B0000DBB
-:108F300000044140320C007FA0AC000D8F8600BCC5
-:108F400090CA000D014B1024A0C2000D8F8700BCF9
-:108F500090E5000D00A3F82403E8C825A0F9000D52
-:108F60008F9100B88F8D00BC8E380020ADB80010F6
-:108F70008E290024ADA900148E2F0028ADAF001853
-:108F80008E2E002C0E000D05ADAE001C8FB0001C07
-:108F9000240C0002120C00ED8F9000D08FA3001C57
-:108FA00000608821146000020060A8210000A02158
-:108FB00056A0FE390291A0230014882B8FAE00101A
-:108FC000960700103C0A002001D6F02302C7C021FA
-:108FD00033D2FFFFA6180010AFB20010AF4A003026
-:108FE0000000000096170010961300121277008EF2
-:108FF000001641808E16000C8E0F0008000817C363
-:1090000002C8282100A8582B01E2A82102AB182190
-:10901000AE05000CAE0300088FB300100013B82B90
-:10902000023780241200FF058F9000D00A000E4BFB
-:10903000000000008E480038A6600008240F0003DE
-:10904000AE6800008E4C0034A260000A8F9000B819
-:10905000AE6C00043C050080920B003FA26F000C38
-:109060008E62000C3C11FF9FA26B000B004568252F
-:109070003623FFFF3C04FFEF8F8C00B801A33024A0
-:10908000349FFFFF00DFC824AE79000C8D890014E7
-:10909000959E00128F9800B0AE6900108D8E00145E
-:1090A000AE600018AE600020AE6E0014AE6000240A
-:1090B0008D87001833CE3FFF000E5180AE67002829
-:1090C0008D8800080158902133D00001AE6800302F
-:1090D0008D91000C8F8D00AC001259C200107B8066
-:1090E000016F282124020002A665001CA66000363C
-:1090F000AE71002CA1A200009763003C8F9800ACD9
-:109100003C044200307FFFFF03E43025AF0600043B
-:109110008F9900B824070001240BC0008F3300385A
-:1091200024060034AF1300188F290034AF09001C47
-:10913000AF00000CAF000010A7000014A70000163D
-:10914000A7000020A7000022AF000024A7150002FE
-:10915000A30700018F8A00AC8F9E00B88F8C00BCE3
-:10916000AD55000893C80000A18800008F9200B898
-:109170008F8F00BC92500001A1F000018F8400BCD1
-:1091800094910002022B282400AE1025A482000234
-:10919000908D000231A3003FA08300028F8300D096
-:1091A0008F8400BC907F00BC33F30002526000014A
-:1091B00024060030AC8600048C65007C240DFFBFC3
-:1091C00002A08821AC8500089082000D3043007F0A
-:1091D000A083000D8F8600BC90C4000D008DF82484
-:1091E000A0DF000D8F8E00BC91D9000D3729002023
-:1091F000A1C9000D8F9E00B88F9300BC8FC70020BF
-:10920000AE6700108FD80024AE7800148FCA0028F3
-:10921000AE6A00188FD2002C0E000D05AE72001C35
-:109220000A00104C8F9000D0960200148E040004A7
-:109230003043FFFF000368C0008DF821AF5F003CA2
-:109240008E1900048F46003C032648231920003C59
-:10925000000000008E05000024A200013C0B00105D
-:1092600035750008AF420038AF55003000000000EF
-:1092700000000000000000000000000000000000EE
-:109280000000000000000000000000008F4C000003
-:10929000318F002011E0FFFD000000008F5304001B
-:1092A0003C080020AE1300088F570404AE17000CD2
-:1092B000AF480030000000003C0608008CC60044A7
-:1092C0002416000110D600BB000000009619001201
-:1092D0003C0508008CA5004000B94821A6090012F1
-:1092E000960E001425C70001A60700149618001456
-:1092F0003304FFFF5486FF498FB30010A60000140B
-:109300000E000E2530A5FFFF3C0408008C840024CD
-:10931000961F00120044682303ED3023A6060012B6
-:109320000A0010678FB30010A08300018F8200AC89
-:1093300024040001AC4400080A000FFF8F8300D012
-:109340008E0200000A0010F83C0B00108F9F00C036
-:109350008FB8001C920F00D0920B00D0920D00D05D
-:1093600031F100FF316E00FF000E28C000111140E6
-:109370000045182131A600FF036350210006C940B3
-:10938000033F382125490088AF8900ACAF8700BC76
-:10939000A15800889768003C03C020218F9100AC41
-:1093A0000E000CE53110FFFF00026380020C7825EF
-:1093B0003C0442008F8C00B801E45825AE2B000419
-:1093C0008D9100388F8B00AC00006821000D1100DA
-:1093D000AD7100188D8E00343C087FFF3504FFFF0F
-:1093E000AD6E001C9183003E8D65001C8D790018C8
-:1093F000000331000003870200A6C0210050F825B9
-:109400000306482B033F382100E95021AD78001CAA
-:10941000AD6A0018AD60000CAD600010918F003E89
-:109420002405000503C45024A56F00149591000481
-:1094300003C02021A5710016918E003EA56E00206C
-:10944000958D0004A56D0022AD6000249190003F31
-:10945000A57000029182003D24430001A163000138
-:109460008F8600AC8F9F00BCACDE0008A3E5000037
-:109470008F9000BC8F9900B82405FFBF96070002AB
-:10948000973800120247782433093FFF01E9882505
-:10949000A6110002921200022418FFDF324E003F94
-:1094A00035CD0040A20D00028F8600BC8F8C00D00D
-:1094B0002412FFFFACC000048D8B007C3C0C8000AC
-:1094C000ACCB000890C2000D3043007FA0C3000D5C
-:1094D0008F8700BC90FF000D03E5C824A0F9000DA4
-:1094E0008F9100BC9229000D01387824A22F000D25
-:1094F0008F9000BCAE120010AE150014920E001832
-:109500002415FF8002AE6825A20D00188F8500BCCF
-:109510008F8300B88CAB0018016C1024004A3025F2
-:10952000ACA600189068003EA0A8001C8F9F00B851
-:109530008F8700BC8F9800D097F90004A4F9001E13
-:109540000E0002038F0500848F8600D00002794050
-:109550000002490090D200BC01E988210040282186
-:109560003255000212A0000303D120210002A8807E
-:109570000095202190CC00BC3192000412400003E1
-:1095800033C900030005408000882021241900040D
-:109590008F9E00BC0329382330F800030098502127
-:1095A000AFCA00040E000D05A66500380A0010477A
-:1095B0008F9000D0960A00123C1E08008FDE002417
-:1095C00003CA9021A61200120A0010678FB3001080
-:1095D00027BDFFE03C1808008F180050AFB0001006
-:1095E000AFBF0018AFB10014AF8400B09371007426
-:1095F000030478212410FF8031EE007F3225007FA4
-:1096000001F0582401DA68213C0C000AA38500C44B
-:1096100001AC2821AF4B002494A9001097680006E4
-:1096200090A6006200803821240200300109202326
-:1096300030C300F0AF8500D0106200193090FFFFFA
-:1096400090AE0062240DFFF0240A005001AE6024A9
-:10965000318B00FF116A002F000000001600000788
-:10966000241F0C00AF5F00248FB100148FBF0018BF
-:109670008FB0001003E0000827BD00200E000E2B65
-:1096800002002021241F0C00AF5F00248FB10014C2
-:109690008FBF00188FB0001003E0000827BD002026
-:1096A00094A200E094A400E290BF01130082182667
-:1096B0003079FFFF33E700C014E000092F310001CB
-:1096C00016000038000000005620FFE6241F0C00A2
-:1096D0000E000D27000000000A0011F9241F0C00E5
-:1096E0001620FFDE000000000E000D270000000025
-:1096F0001440FFDC241F0C00160000228F8300D0D2
-:10970000906901133122003FA06201130A0011F990
-:10971000241F0C0094AF00D48F8600D400E02821D1
-:10972000240400050E000C6B31F0FFFF144000050F
-:1097300024030003979100E6000018212625FFFF6F
-:10974000A78500E68F5801B80700FFFE3C1960139B
-:10975000AF400180241F0C00AF50018400793825F0
-:109760003C101000AF4701888FB10014AF5001B812
-:10977000AF5F00248FB000108FBF001803E0000817
-:1097800027BD00200E000E2B020020215040FFB507
-:10979000241F0C008F8300D0906901130A0012224D
-:1097A0003122003F0E000E2B020020211440FFAD9D
-:1097B000241F0C00122000078F8300D09068011333
-:1097C0003106003F34C20040A06201130A0011F9C3
-:1097D000241F0C000E000D27000000005040FFA1C8
-:1097E000241F0C008F8300D0906801133106003FC6
-:1097F0000A00125234C20040AF9B00C803E00008C8
-:10980000AF8000EC3089FFFF000940422D0200418B
-:10981000000929801440000200095040240800403B
-:10982000000879400008C0C001F85821256701A848
-:1098300000EF702125CC007F240DFF80018D1824BE
-:109840000065302100CA282125640088240A008888
-:109850003C010800AC2A004C3C010800AC2400503C
-:10986000AF8500D43C010800AC2900603C01080031
-:10987000AC2800643C010800AC2700543C010800FF
-:10988000AC2300583C010800AC26005C03E0000853
-:1098900000000000308300FF30C6FFFF30E400FF0F
-:1098A0008F4201B80440FFFE00034C00012438251C
-:1098B0003C08600000E820253C031000AF45018013
-:1098C000AF460184AF44018803E00008AF4301B80C
-:1098D0008F86001C3C096012352700108CCB0004D9
-:1098E0003C0C600E35850010316A00062D480001E1
-:1098F000ACE800C48CC40004ACA431808CC2000865
-:1099000094C30002ACA2318403E00008A78300E402
-:109910003C0308008C6300508F8400E88F86001C95
-:109920002402FF800064C0210302C824AF5900282C
-:109930008CCD00043305007F00BA78213C0E000C6A
-:1099400001EE2821ACAD00588CC80008AF8500D0CE
-:109950003C076012ACA8005C8CCC001034E800100E
-:10996000ACAC000C8CCB000CACAB000894AA00147F
-:109970003C0208008C42004425490001A4A90014BF
-:1099800094A400143083FFFF106200178F8400D06E
-:109990003C0A08008D4A0040A4AA00128CCE001890
-:1099A000AC8E00248CCD0014AC8D00208CC7001828
-:1099B000AC87002C8CCC001424060001AC8C002851
-:1099C0008D0B00BC5166001A8D0200B48D0200B8E8
-:1099D000A482003A948F003AA48F003C948800D46B
-:1099E00003E000083102FFFF3C0908008D29002434
-:1099F000A4A000148F8400D0A4A900128CCE00185B
-:109A0000AC8E00248CCD0014AC8D00208CC70018C7
-:109A1000AC87002C8CCC001424060001AC8C0028F0
-:109A20008D0B00BC5566FFEA8D0200B88D0200B4B4
-:109A3000A482003A948F003AA48F003C948800D40A
-:109A400003E000083102FFFF8F86001C3C0C080079
-:109A50008D8C0050240BFF808CCD00083C03000C43
-:109A6000000D51C0018A4021010B4824AF8A00E853
-:109A7000AF49002890C700073105007F00BA1021C8
-:109A80000043282130E400041080002FAF8500D06F
-:109A900090CF000731EE000811C0003C000000002C
-:109AA0008CD9000C8CC400140324C02B1300002696
-:109AB000000000008CC2000CACA200648CCD001829
-:109AC0002402FFF8ACAD00688CCC0010ACAC008078
-:109AD0008CCB000CACAB00848CCA001CACAA007C04
-:109AE00090A900BC01224024A0A800BC90C300079C
-:109AF0003067000810E000048F8500D090AF00BCF4
-:109B000035EE0001A0AE00BC90D90007333800014B
-:109B10001300000F8F8400D024070020908200BC27
-:109B200034490002A08900BC8F8400D09088006274
-:109B3000310300F014670006240A0034AC8A00C028
-:109B40000A001334000000000A00130E8CC2001437
-:109B500090CB00073166000210C000050000000035
-:109B6000908D00BC35AC0004A08C00BC8F8400D06C
-:109B700090980113330F003FA08F01138F8E00D0F8
-:109B800095C500D403E0000830A2FFFFACA000643C
-:109B90000A00130F0000000027BDFFD8AFB000106F
-:109BA0008F90001CAFBF0024AFB40020AFB20018EC
-:109BB000AFB10014AFB3001C9613000E3C07600A4F
-:109BC0003C1460063264FFFF369300100E001261F1
-:109BD00034F404108F8400D43C11600E0E0009AAE6
-:109BE00036310010920E00153C0708008CE700602B
-:109BF0003C12601231CD000FA38D00F08E0E0004D8
-:109C00008E0D000896080012961F00109619001A73
-:109C10009618001E960F001C310CFFFF33EBFFFF60
-:109C2000332AFFFF3309FFFF31E6FFFF3C01080045
-:109C3000AC2B00403C010800AC2C00243C01080087
-:109C4000AC2A0044AE293178AE26317C9202001550
-:109C50009603001636520010304400FF3065FFFFB7
-:109C60003C0608008CC60064AE243188AE4500B4C2
-:109C70009208001496190018241F0001011FC00447
-:109C8000332FFFFF3C0508008CA50058AE5800B8E4
-:109C9000AE4F00BC920C0014AF8E00D8AF8D00DC2C
-:109CA000318B00FFAE4B00C0920A0015AE67004832
-:109CB000AE66004C314900FFAE4900C8AE65007C7D
-:109CC0003C0308008C6300503C0408008C84004C6A
-:109CD0003C0808008D0800543C0208008C42005CDF
-:109CE0008FBF0024AE6300808FB00010AE8300747D
-:109CF0008FB3001CAE22319CAE4200DCAE2731A0F7
-:109D0000AE2631A4AE24318CAE233190AE283194EE
-:109D1000AE253198AE870050AE860054AE850070F7
-:109D20008FB10014AE4700E0AE4600E4AE4400CC74
-:109D3000AE4300D0AE4800D4AE4500D88FB400206A
-:109D40008FB2001803E0000827BD002827BDFFE000
-:109D5000AFB10014AFBF0018241100010E00085469
-:109D6000AFB0001010510005978400E6978300CC37
-:109D70000083102B144000088F8500D424070002B4
-:109D80008FBF00188FB100148FB0001000E01021B9
-:109D900003E0000827BD00200E000C892404000504
-:109DA000AF8200E81040FFF6240700020E000858BA
-:109DB0008F90001C979F00E68F9900E88F8D00C858
-:109DC00027EF0001240E0050AF590020A78F00E6B6
-:109DD000A1AE00003C0C08008D8C00648F8600C88A
-:109DE000240A8000000C5E00ACCB0074A4C0000606
-:109DF00094C9000A241FFF803C0D000C012AC024D6
-:109E0000A4D8000A90C8000A24182000011F1825B1
-:109E1000A0C3000A8F8700C8A0E000788F8500C823
-:109E200000003821A0A000833C0208008C420050B2
-:109E30008F8400E80044782101FFC824AF5900282E
-:109E4000960B000231EE007F01DA6021018D302196
-:109E5000A4CB00D4960A0002AF8600D03C0E0004CA
-:109E600025492401A4C900E68E080004ACC80004FA
-:109E70008E030008ACC30000A4C00010A4C00014EE
-:109E8000A0C000D08F8500D02403FFBFA0A000D1C8
-:109E90003C0408008C8400648F8200D0A04400D26F
-:109EA0008E1F000C8F8A00D0978F00E4AD5F001CDE
-:109EB0008E19001024100030AD590018A540003054
-:109EC000A5510054A5510056A54F0016AD4E00688F
-:109ED000AD580080AD580084914D006231AC000F48
-:109EE000358B0010A14B00628F8600D090C90063B3
-:109EF0003128007FA0C800638F8400D02406FFFFB4
-:109F00009085006300A31024A08200638F9100D08D
-:109F100000E01021923F00BC37F90001A23900BCDB
-:109F20008F8A00D0938F00F0AD580064AD5000C010
-:109F3000914E00D3000F690031CC000F018D5825E0
-:109F4000A14B00D38F8500D08F8900DCACA900E83D
-:109F50008F8800D88FBF00188FB100148FB0001009
-:109F600027BD0020ACA800ECA4A600D6A4A000E069
-:109F7000A4A000E203E000080000000027BDFFE00D
-:109F8000AFB000108F90001CAFB10014AFBF00182D
-:109F90008E1900043C1808008F180050240FFF8011
-:109FA000001989C00238702131CD007F01CF6024B3
-:109FB00001BA50213C0B000CAF4C0028014B402152
-:109FC000950900D4950400D68E0700043131FFFFB7
-:109FD000AF8800D00E000922000721C08E060004C1
-:109FE0008F8300C8000629C0AF4500209064003E62
-:109FF00030820040144000068F8400D0341FFFFFE1
-:10A00000948300D63062FFFF145F0004000000005C
-:10A01000948400D60E0008B73084FFFF8E0500043C
-:10A02000022030218FBF00188FB100148FB00010B4
-:10A030002404002200003821000529C00A001285EE
-:10A0400027BD002027BDFFE0AFB100143091FFFF16
-:10A05000AFB00010AFBF00181220001D000080211B
-:10A060008F86001C8CC500002403000600053F02FB
-:10A070000005140230E4000714830015304500FF8A
-:10A080002CA800061100004D000558803C0C08006B
-:10A09000258C57E8016C50218D49000001200008F3
-:10A0A000000000008F8E00EC240D000111CD00593E
-:10A0B00000000000260B00013170FFFF24CA0020C1
-:10A0C0000211202B014030211480FFE6AF8A001CD2
-:10A0D000020010218FBF00188FB100148FB0001044
-:10A0E00003E0000827BD0020938700CE14E000386D
-:10A0F000240400140E001346000000008F86001C8C
-:10A10000240200010A00148DAF8200EC8F8900EC5C
-:10A11000240800021128003B240400130000282119
-:10A1200000003021240700010E001285000000000D
-:10A130000A00148D8F86001C8F8700EC2405000216
-:10A1400014E5FFF6240400120E0012F200000000D5
-:10A150008F8500E800403021240400120E00128593
-:10A16000000038210A00148D8F86001C8F8300ECBC
-:10A17000241F0003147FFFD0260B00010E0012A441
-:10A18000000000008F8500E800403021240200021A
-:10A190002404001000003821AF8200EC0E0012856C
-:10A1A000000000000A00148D8F86001C8F8F00ECC9
-:10A1B0002406000211E6000B000000002404001039
-:10A1C00000002821000030210A0014AA2407000101
-:10A1D000000028210E001285000030210A00148D95
-:10A1E0008F86001C0E0013B3000000001440001204
-:10A1F0008F99001C8F86001C240200030A00148D16
-:10A20000AF8200EC0E00143F000000000A00148D25
-:10A210008F86001C0E001294000000002402000231
-:10A2200024040014000028210000302100003821FF
-:10A230000A0014C7AF8200EC00403821240400104B
-:10A2400097380002000028210E0012853306FFFF18
-:10A250000A00148D8F86001C8F8400C83C077FFF86
-:10A2600034E6FFFF8C8500742402000100A6182448
-:10A27000AC83007403E00008A082000510A0003643
-:10A280002CA20080274A04003C0B00052409008012
-:10A29000104000072408008030A6000F00C54021B0
-:10A2A0002D0300811460000200A0482124080080D2
-:10A2B000AF4B003000000000000000000000000074
-:10A2C0001100000900003821014030218C8D000070
-:10A2D00024E7000400E8602BACCD000024840004D7
-:10A2E0001580FFFA24C600040000000000000000F2
-:10A2F000000000003C0E0006010E3825AF4700307C
-:10A300000000000000000000000000008F4F00006F
-:10A3100031E800101100FFFD000000008F42003CFA
-:10A320008F43003C0049C8210323C02B13000004C5
-:10A33000000000008F4C003825860001AF46003831
-:10A340008F47003C00A9282300E96821AF4D003C5D
-:10A3500014A0FFCE2CA2008003E000080000000043
-:10A3600027BDFFD03C020002AFB100143C11000C2D
-:10A37000AF450038AFB3001CAF46003C00809821C9
-:10A38000AF42003024050088AF440028035120214B
-:10A39000AFBF0028AFB50024AFB40020AFB20018A3
-:10A3A0000E0014FFAFB000103C1F08008FFF004CE0
-:10A3B0003C1808008F1800642410FF8003F3A821C4
-:10A3C00032B9007F02B078240018A0C0033A70218F
-:10A3D0000018914001D12021AF4F00280E0014FF3A
-:10A3E000025428213C0D08008DAD005024050120A9
-:10A3F00001B35821316C007F01705024019A48212B
-:10A40000013120210E0014FFAF4A00283C0808004B
-:10A410008D0800543C0508008CA500640113382108
-:10A4200030E6007F00F0182400DA2021009120217E
-:10A43000AF4300280E0014FF000529403C0208002D
-:10A440008C4200583C1008008E1000601200001C66
-:10A45000005388212415FF800A0015823C14000C4B
-:10A460003226007F0235182400DA202102402821FC
-:10A47000AF430028009420210E0014FF2610FFC0D7
-:10A480001200000F023288212E05004110A0FFF4B7
-:10A49000241210003226007F00109180023518240B
-:10A4A00000DA202102402821AF4300280094202117
-:10A4B0000E0014FF000080211600FFF302328821F5
-:10A4C0003C0B08008D6B005C240AFF802405000211
-:10A4D00001734021010A4824AF4900283C040800C8
-:10A4E000948400623110007F021A88213C07000C1E
-:10A4F0000E000CB90227982100402821026020217B
-:10A500008FBF00288FB500248FB400208FB3001CAC
-:10A510008FB200188FB100148FB000100A0014FF22
-:10A5200027BD00308F83001C8C62000410400003A4
-:10A530000000000003E00008000000008C64001030
-:0CA540008C6500080A0015388C66000CC1
-:04A54C00000000000B
-:10A550000000001B0000000F0000000A00000008BF
-:10A5600000000006000000050000000500000004D7
-:10A5700000000004000000030000000300000003CE
-:10A5800000000003000000030000000200000002C1
-:10A5900000000002000000020000000200000002B3
-:10A5A00000000002000000020000000200000002A3
-:10A5B0000000000200000002000000020000000293
-:10A5C0000000000200000001000000010000000186
-:10A5D00008000F3008000D8808000FC40800106C38
-:10A5E00008000F5808000F98080011A408000DA4D7
-:10A5F000080011C808000DF4080014980800144061
-:10A6000008000DA408000DA408000DA408001254B1
-:10A610000800125408000DA408000DA4080016E05C
-:10A6200008000DA408000DA408000DA408000DA446
-:10A63000080013D408000DA408000DA408000DA400
-:10A6400008000DA408000DA408000DA408000DA426
-:10A6500008000DA408000DA408000DA408000DA416
-:10A6600008000DA408000DA408000DA408000FB8F0
-:10A6700008000DA408000DA40800169008000DA401
-:10A6800008000DA408000DA408000DA408000DA4E6
-:10A6900008000DA408000DA408000DA408000DA4D6
-:10A6A00008000DA408000DA408000DA408000DA4C6
-:10A6B00008000DA408000DA408000DA408000DA4B6
-:10A6C000080015BC08000DA408000DA408001348DC
-:10A6D000080012B808002E5008002E5808002E203E
-:10A6E00008002E2C08002E3808002E440800532C99
-:10A6F000080052EC080052B80800528C080052685A
-:04A7000008005224D7
-:0CA704000A000C760000000000000000BD
-:10A710000000000D727870342E362E3136000000A5
-:10A72000040610030000000000000001000000000B
-:10A730000000000000000000000000000000000019
-:10A740000000000000000000000000000000000009
-:10A7500000000000000000000000000000000000F9
-:10A7600000000000000000000000000000000000E9
-:10A7700000000000000000000000000000000000D9
-:10A7800000000000000000000000000000000000C9
-:10A7900000000000000000000000000000000000B9
-:10A7A00000000000000000000000000000000000A9
-:10A7B0000000000000000000000000000000000099
-:10A7C0000000000000000000000000000000000089
-:10A7D0000000000000000000000000000000000079
-:10A7E0000000000000000000000000000000000069
-:10A7F0000000000000000000000000000000000059
-:10A800000000000000000000000000000000000048
-:10A810000000000000000000000000000000000038
-:10A820000000000000000000000000000000000028
-:10A830000000000000000000000000000000000018
-:10A840000000000000000000000000000000000008
-:10A8500000000000000000000000000000000000F8
-:10A8600000000000000000000000000000000000E8
-:10A8700000000000000000000000000000000000D8
-:10A8800000000000000000000000000000000000C8
-:10A8900000000000000000000000000000000000B8
-:10A8A00000000000000000000000000000000000A8
-:10A8B0000000000000000000000000000000000098
-:10A8C0000000000000000000000000000000000088
-:10A8D0000000000000000000000000000000000078
-:10A8E0000000000000000000000000000000000068
-:10A8F0000000000000000000000000000000000058
-:10A900000000000000000000000000000000000047
-:10A910000000000000000000000000000000000037
-:10A920000000000000000000000000000000000027
-:10A930000000000000000000000000000000000017
-:10A940000000000000000000000000000000000007
-:10A9500000000000000000000000000000000000F7
-:10A9600000000000000000000000000000000000E7
-:10A9700000000000000000000000000000000000D7
-:10A9800000000000000000000000000000000000C7
-:10A9900000000000000000000000000000000000B7
-:10A9A00000000000000000000000000000000000A7
-:10A9B0000000000000000000000000000000000097
-:10A9C0000000000000000000000000000000000087
-:10A9D0000000000000000000000000000000000077
-:10A9E0000000000000000000000000000000000067
-:10A9F0000000000000000000000000000000000057
-:10AA00000000000000000000000000000000000046
-:10AA10000000000000000000000000000000000036
-:10AA20000000000000000000000000000000000026
-:10AA30000000000000000000000000000000000016
-:10AA40000000000000000000000000000000000006
-:10AA500000000000000000000000000000000000F6
-:10AA600000000000000000000000000000000000E6
-:10AA700000000000000000000000000000000000D6
-:10AA800000000000000000000000000000000000C6
-:10AA900000000000000000000000000000000000B6
-:10AAA00000000000000000000000000000000000A6
-:10AAB0000000000000000000000000000000000096
-:10AAC0000000000000000000000000000000000086
-:10AAD0000000000000000000000000000000000076
-:10AAE0000000000000000000000000000000000066
-:10AAF0000000000000000000000000000000000056
-:10AB00000000000000000000000000000000000045
-:10AB10000000000000000000000000000000000035
-:10AB20000000000000000000000000000000000025
-:10AB30000000000000000000000000000000000015
-:10AB40000000000000000000000000000000000005
-:10AB500000000000000000000000000000000000F5
-:10AB600000000000000000000000000000000000E5
-:10AB700000000000000000000000000000000000D5
-:10AB800000000000000000000000000000000000C5
-:10AB900000000000000000000000000000000000B5
-:10ABA00000000000000000000000000000000000A5
-:10ABB0000000000000000000000000000000000095
-:10ABC0000000000000000000000000000000000085
-:10ABD0000000000000000000000000000000000075
-:10ABE0000000000000000000000000000000000065
-:10ABF0000000000000000000000000000000000055
-:10AC00000000000000000000000000000000000044
-:10AC10000000000000000000000000000000000034
-:10AC20000000000000000000000000000000000024
-:10AC30000000000000000000000000000000000014
-:10AC40000000000000000000000000000000000004
-:10AC500000000000000000000000000000000000F4
-:10AC600000000000000000000000000000000000E4
-:10AC700000000000000000000000000000000000D4
-:10AC800000000000000000000000000000000000C4
-:10AC900000000000000000000000000000000000B4
-:10ACA00000000000000000000000000000000000A4
-:10ACB0000000000000000000000000000000000094
-:10ACC0000000000000000000000000000000000084
-:10ACD0000000000000000000000000000000000074
-:10ACE0000000000000000000000000000000000064
-:10ACF0000000000000000000000000000000000054
-:10AD00000000000000000000000000000000000043
-:10AD10000000000000000000000000000000000033
-:10AD20000000000000000000000000000000000023
-:10AD30000000000000000000000000000000000013
-:10AD40000000000000000000000000000000000003
-:10AD500000000000000000000000000000000000F3
-:10AD600000000000000000000000000000000000E3
-:10AD700000000000000000000000000000000000D3
-:10AD800000000000000000000000000000000000C3
-:10AD900000000000000000000000000000000000B3
-:10ADA00000000000000000000000000000000000A3
-:10ADB0000000000000000000000000000000000093
-:10ADC0000000000000000000000000000000000083
-:10ADD0000000000000000000000000000000000073
-:10ADE0000000000000000000000000000000000063
-:10ADF0000000000000000000000000000000000053
-:10AE00000000000000000000000000000000000042
-:10AE10000000000000000000000000000000000032
-:10AE20000000000000000000000000000000000022
-:10AE30000000000000000000000000000000000012
-:10AE40000000000000000000000000000000000002
-:10AE500000000000000000000000000000000000F2
-:10AE600000000000000000000000000000000000E2
-:10AE700000000000000000000000000000000000D2
-:10AE800000000000000000000000000000000000C2
-:10AE900000000000000000000000000000000000B2
-:10AEA00000000000000000000000000000000000A2
-:10AEB0000000000000000000000000000000000092
-:10AEC0000000000000000000000000000000000082
-:10AED0000000000000000000000000000000000072
-:10AEE0000000000000000000000000000000000062
-:10AEF0000000000000000000000000000000000052
-:10AF00000000000000000000000000000000000041
-:10AF10000000000000000000000000000000000031
-:10AF20000000000000000000000000000000000021
-:10AF30000000000000000000000000000000000011
-:10AF40000000000000000000000000000000000001
-:10AF500000000000000000000000000000000000F1
-:10AF600000000000000000000000000000000000E1
-:10AF700000000000000000000000000000000000D1
-:10AF800000000000000000000000000000000000C1
-:10AF900000000000000000000000000000000000B1
-:10AFA00000000000000000000000000000000000A1
-:10AFB0000000000000000000000000000000000091
-:10AFC0000000000000000000000000000000000081
-:10AFD0000000000000000000000000000000000071
-:10AFE0000000000000000000000000000000000061
-:10AFF0000000000000000000000000000000000051
-:10B000000000000000000000000000000000000040
-:10B010000000000000000000000000000000000030
-:10B020000000000000000000000000000000000020
-:10B030000000000000000000000000000000000010
-:10B040000000000000000000000000000000000000
-:10B0500000000000000000000000000000000000F0
-:10B0600000000000000000000000000000000000E0
-:10B0700000000000000000000000000000000000D0
-:10B0800000000000000000000000000000000000C0
-:10B0900000000000000000000000000000000000B0
-:10B0A00000000000000000000000000000000000A0
-:10B0B0000000000000000000000000000000000090
-:10B0C0000000000000000000000000000000000080
-:10B0D0000000000000000000000000000000000070
-:10B0E0000000000000000000000000000000000060
-:10B0F0000000000000000000000000000000000050
-:10B10000000000000000000000000000000000003F
-:10B11000000000000000000000000000000000002F
-:10B12000000000000000000000000000000000001F
-:10B13000000000000000000000000000000000000F
-:10B1400000000000000000000000000000000000FF
-:10B1500000000000000000000000000000000000EF
-:10B1600000000000000000000000000000000000DF
-:10B1700000000000000000000000000000000000CF
-:10B1800000000000000000000000000000000000BF
-:10B1900000000000000000000000000000000000AF
-:10B1A000000000000000000000000000000000009F
-:10B1B000000000000000000000000000000000008F
-:10B1C000000000000000000000000000000000007F
-:10B1D000000000000000000000000000000000006F
-:10B1E000000000000000000000000000000000005F
-:10B1F000000000000000000000000000000000004F
-:10B20000000000000000000000000000000000003E
-:10B21000000000000000000000000000000000002E
-:10B22000000000000000000000000000000000001E
-:10B23000000000000000000000000000000000000E
-:10B2400000000000000000000000000000000000FE
-:10B2500000000000000000000000000000000000EE
-:10B2600000000000000000000000000000000000DE
-:10B2700000000000000000000000000000000000CE
-:10B2800000000000000000000000000000000000BE
-:10B2900000000000000000000000000000000000AE
-:10B2A000000000000000000000000000000000009E
-:10B2B000000000000000000000000000000000008E
-:10B2C000000000000000000000000000000000007E
-:10B2D000000000000000000000000000000000006E
-:10B2E000000000000000000000000000000000005E
-:10B2F000000000000000000000000000000000004E
-:10B30000000000000000000000000000000000003D
-:10B31000000000000000000000000000000000002D
-:10B32000000000000000000000000000000000001D
-:10B33000000000000000000000000000000000000D
-:10B3400000000000000000000000000000000000FD
-:10B3500000000000000000000000000000000000ED
-:10B3600000000000000000000000000000000000DD
-:10B3700000000000000000000000000000000000CD
-:10B3800000000000000000000000000000000000BD
-:10B3900000000000000000000000000000000000AD
-:10B3A000000000000000000000000000000000009D
-:10B3B000000000000000000000000000000000008D
-:10B3C000000000000000000000000000000000007D
-:10B3D000000000000000000000000000000000006D
-:10B3E000000000000000000000000000000000005D
-:10B3F000000000000000000000000000000000004D
-:10B40000000000000000000000000000000000003C
-:10B41000000000000000000000000000000000002C
-:10B42000000000000000000000000000000000001C
-:10B43000000000000000000000000000000000000C
-:10B4400000000000000000000000000000000000FC
-:10B4500000000000000000000000000000000000EC
-:10B4600000000000000000000000000000000000DC
-:10B4700000000000000000000000000000000000CC
-:10B4800000000000000000000000000000000000BC
-:10B4900000000000000000000000000000000000AC
-:10B4A000000000000000000000000000000000009C
-:10B4B000000000000000000000000000000000008C
-:10B4C000000000000000000000000000000000007C
-:10B4D000000000000000000000000000000000006C
-:10B4E000000000000000000000000000000000005C
-:10B4F000000000000000000000000000000000004C
-:10B50000000000000000000000000000000000003B
-:10B51000000000000000000000000000000000002B
-:10B52000000000000000000000000000000000001B
-:10B53000000000000000000000000000000000000B
-:10B5400000000000000000000000000000000000FB
-:10B5500000000000000000000000000000000000EB
-:10B5600000000000000000000000000000000000DB
-:10B5700000000000000000000000000000000000CB
-:10B5800000000000000000000000000000000000BB
-:10B5900000000000000000000000000000000000AB
-:10B5A000000000000000000000000000000000009B
-:10B5B000000000000000000000000000000000008B
-:10B5C000000000000000000000000000000000007B
-:10B5D000000000000000000000000000000000006B
-:10B5E000000000000000000000000000000000005B
-:10B5F000000000000000000000000000000000004B
-:10B60000000000000000000000000000000000003A
-:10B61000000000000000000000000000000000002A
-:10B62000000000000000000000000000000000001A
-:10B63000000000000000000000000000000000000A
-:10B6400000000000000000000000000000000000FA
-:10B6500000000000000000000000000000000000EA
-:10B6600000000000000000000000000000000000DA
-:10B6700000000000000000000000000000000000CA
-:10B6800000000000000000000000000000000000BA
-:10B6900000000000000000000000000000000000AA
-:10B6A000000000000000000000000000000000009A
-:10B6B000000000000000000000000000000000008A
-:10B6C000000000000000000000000000000000007A
-:10B6D000000000000000000000000000000000006A
-:10B6E000000000000000000000000000000000005A
-:10B6F000000000000000000000000000000000004A
-:10B700000000000000000000000000000000000039
-:10B710000000000000000000000000000000000029
-:10B720000000000000000000000000000000000019
-:10B730000000000000000000000000000000000009
-:10B7400000000000000000000000000000000000F9
-:10B7500000000000000000000000000000000000E9
-:10B7600000000000000000000000000000000000D9
-:10B7700000000000000000000000000000000000C9
-:10B7800000000000000000000000000000000000B9
-:10B7900000000000000000000000000000000000A9
-:10B7A0000000000000000000000000000000000099
-:10B7B0000000000000000000000000000000000089
-:10B7C0000000000000000000000000000000000079
-:10B7D0000000000000000000000000000000000069
-:10B7E0000000000000000000000000000000000059
-:10B7F0000000000000000000000000000000000049
-:10B800000000000000000000000000000000000038
-:10B810000000000000000000000000000000000028
-:10B820000000000000000000000000000000000018
-:10B830000000000000000000000000000000000008
-:10B8400000000000000000000000000000000000F8
-:10B8500000000000000000000000000000000000E8
-:10B8600000000000000000000000000000000000D8
-:10B8700000000000000000000000000000000000C8
-:10B8800000000000000000000000000000000000B8
-:10B8900000000000000000000000000000000000A8
-:10B8A0000000000000000000000000000000000098
-:10B8B0000000000000000000000000000000000088
-:10B8C0000000000000000000000000000000000078
-:10B8D0000000000000000000000000000000000068
-:10B8E0000000000000000000000000000000000058
-:10B8F0000000000000000000000000000000000048
-:10B900000000000000000000000000000000000037
-:10B910000000000000000000000000000000000027
-:10B920000000000000000000000000000000000017
-:10B930000000000000000000000000000000000007
-:10B9400000000000000000000000000000000000F7
-:10B9500000000000000000000000000000000000E7
-:10B9600000000000000000000000000000000000D7
-:10B9700000000000000000000000000000000000C7
-:10B9800000000000000000000000000000000000B7
-:10B9900000000000000000000000000000000000A7
-:10B9A0000000000000000000000000000000000097
-:10B9B0000000000000000000000000000000000087
-:10B9C0000000000000000000000000000000000077
-:10B9D0000000000000000000000000000000000067
-:10B9E0000000000000000000000000000000000057
-:10B9F0000000000000000000000000000000000047
-:10BA00000000000000000000000000000000000036
-:10BA10000000000000000000000000000000000026
-:10BA20000000000000000000000000000000000016
-:10BA30000000000000000000000000000000000006
-:10BA400000000000000000000000000000000000F6
-:10BA500000000000000000000000000000000000E6
-:10BA600000000000000000000000000000000000D6
-:10BA700000000000000000000000000000000000C6
-:10BA800000000000000000000000000000000000B6
-:10BA900000000000000000000000000000000000A6
-:10BAA0000000000000000000000000000000000096
-:10BAB0000000000000000000000000000000000086
-:10BAC0000000000000000000000000000000000076
-:10BAD0000000000000000000000000000000000066
-:10BAE0000000000000000000000000000000000056
-:10BAF0000000000000000000000000000000000046
-:10BB00000000000000000000000000000000000035
-:10BB10000000000000000000000000000000000025
-:10BB20000000000000000000000000000000000015
-:10BB30000000000000000000000000000000000005
-:10BB400000000000000000000000000000000000F5
-:10BB500000000000000000000000000000000000E5
-:10BB600000000000000000000000000000000000D5
-:10BB700000000000000000000000000000000000C5
-:10BB800000000000000000000000000000000000B5
-:10BB900000000000000000000000000000000000A5
-:10BBA0000000000000000000000000000000000095
-:10BBB0000000000000000000000000000000000085
-:10BBC0000000000000000000000000000000000075
-:10BBD0000000000000000000000000000000000065
-:10BBE0000000000000000000000000000000000055
-:10BBF0000000000000000000000000000000000045
-:10BC00000000000000000000000000000000000034
-:10BC10000000000000000000000000000000000024
-:10BC20000000000000000000000000000000000014
-:10BC30000000000000000000000000000000000004
-:10BC400000000000000000000000000000000000F4
-:10BC500000000000000000000000000000000000E4
-:10BC600000000000000000000000000000000000D4
-:10BC700000000000000000000000000000000000C4
-:10BC800000000000000000000000000000000000B4
-:10BC900000000000000000000000000000000000A4
-:10BCA0000000000000000000000000000000000094
-:10BCB0000000000000000000000000000000000084
-:10BCC0000000000000000000000000000000000074
-:10BCD0000000000000000000000000000000000064
-:10BCE0000000000000000000000000000000000054
-:10BCF0000000000000000000000000000000000044
-:10BD00000000000000000000000000000000000033
-:10BD10000000000000000000000000000000000023
-:10BD20000000000000000000000000000000000013
-:10BD30000000000000000000000000000000000003
-:10BD400000000000000000000000000000000000F3
-:10BD500000000000000000000000000000000000E3
-:10BD600000000000000000000000000000000000D3
-:10BD700000000000000000000000000000000000C3
-:10BD800000000000000000000000000000000000B3
-:10BD900000000000000000000000000000000000A3
-:10BDA0000000000000000000000000000000000093
-:10BDB0000000000000000000000000000000000083
-:10BDC0000000000000000000000000000000000073
-:10BDD0000000000000000000000000000000000063
-:10BDE0000000000000000000000000000000000053
-:10BDF0000000000000000000000000000000000043
-:10BE00000000000000000000000000000000000032
-:10BE10000000000000000000000000000000000022
-:10BE20000000000000000000000000000000000012
-:10BE30000000000000000000000000000000000002
-:10BE400000000000000000000000000000000000F2
-:10BE500000000000000000000000000000000000E2
-:10BE600000000000000000000000000000000000D2
-:10BE700000000000000000000000000000000000C2
-:10BE800000000000000000000000000000000000B2
-:10BE900000000000000000000000000000000000A2
-:10BEA0000000000000000000000000000000000092
-:10BEB0000000000000000000000000000000000082
-:10BEC0000000000000000000000000000000000072
-:10BED0000000000000000000000000000000000062
-:10BEE0000000000000000000000000000000000052
-:10BEF0000000000000000000000000000000000042
-:10BF00000000000000000000000000000000000031
-:10BF10000000000000000000000000000000000021
-:10BF20000000000000000000000000000000000011
-:10BF30000000000000000000000000000000000001
-:10BF400000000000000000000000000000000000F1
-:10BF500000000000000000000000000000000000E1
-:10BF600000000000000000000000000000000000D1
-:10BF700000000000000000000000000000000000C1
-:10BF800000000000000000000000000000000000B1
-:10BF900000000000000000000000000000000000A1
-:10BFA0000000000000000000000000000000000091
-:10BFB0000000000000000000000000000000000081
-:10BFC0000000000000000000000000000000000071
-:10BFD0000000000000000000000000000000000061
-:10BFE0000000000000000000000000000000000051
-:10BFF0000000000000000000000000000000000041
-:10C000000000000000000000000000000000000030
-:10C010000000000000000000000000000000000020
-:10C020000000000000000000000000000000000010
-:10C030000000000000000000000000000000000000
-:10C0400000000000000000000000000000000000F0
-:10C0500000000000000000000000000000000000E0
-:10C0600000000000000000000000000000000000D0
-:10C0700000000000000000000000000000000000C0
-:10C0800000000000000000000000000000000000B0
-:10C0900000000000000000000000000000000000A0
-:10C0A0000000000000000000000000000000000090
-:10C0B0000000000000000000000000000000000080
-:10C0C0000000000000000000000000000000000070
-:10C0D0000000000000000000000000000000000060
-:10C0E0000000000000000000000000000000000050
-:10C0F0000000000000000000000000000000000040
-:10C10000000000000000000000000000000000002F
-:10C11000000000000000000000000000000000001F
-:10C12000000000000000000000000000000000000F
-:10C1300000000000000000000000000000000000FF
-:10C1400000000000000000000000000000000000EF
-:10C1500000000000000000000000000000000000DF
-:10C1600000000000000000000000000000000000CF
-:10C1700000000000000000000000000000000000BF
-:10C1800000000000000000000000000000000000AF
-:10C19000000000000000000000000000000000009F
-:10C1A000000000000000000000000000000000008F
-:10C1B000000000000000000000000000000000007F
-:10C1C000000000000000000000000000000000006F
-:10C1D000000000000000000000000000000000005F
-:10C1E000000000000000000000000000000000004F
-:10C1F000000000000000000000000000000000003F
-:10C20000000000000000000000000000000000002E
-:10C21000000000000000000000000000000000001E
-:10C22000000000000000000000000000000000000E
-:10C2300000000000000000000000000000000000FE
-:10C2400000000000000000000000000000000000EE
-:10C2500000000000000000000000000000000000DE
-:10C2600000000000000000000000000000000000CE
-:10C2700000000000000000000000000000000000BE
-:10C2800000000000000000000000000000000000AE
-:10C29000000000000000000000000000000000009E
-:10C2A000000000000000000000000000000000008E
-:10C2B000000000000000000000000000000000007E
-:10C2C000000000000000000000000000000000006E
-:10C2D000000000000000000000000000000000005E
-:10C2E000000000000000000000000000000000004E
-:10C2F000000000000000000000000000000000003E
-:10C30000000000000000000000000000000000002D
-:10C31000000000000000000000000000000000001D
-:10C32000000000000000000000000000000000000D
-:10C3300000000000000000000000000000000000FD
-:10C3400000000000000000000000000000000000ED
-:10C3500000000000000000000000000000000000DD
-:10C3600000000000000000000000000000000000CD
-:10C3700000000000000000000000000000000000BD
-:10C3800000000000000000000000000000000000AD
-:10C39000000000000000000000000000000000009D
-:10C3A000000000000000000000000000000000008D
-:10C3B000000000000000000000000000000000007D
-:10C3C000000000000000000000000000000000006D
-:10C3D000000000000000000000000000000000005D
-:10C3E000000000000000000000000000000000004D
-:10C3F000000000000000000000000000000000003D
-:10C40000000000000000000000000000000000002C
-:10C41000000000000000000000000000000000001C
-:10C42000000000000000000000000000000000000C
-:10C4300000000000000000000000000000000000FC
-:10C4400000000000000000000000000000000000EC
-:10C4500000000000000000000000000000000000DC
-:10C4600000000000000000000000000000000000CC
-:10C4700000000000000000000000000000000000BC
-:10C4800000000000000000000000000000000000AC
-:10C49000000000000000000000000000000000009C
-:10C4A000000000000000000000000000000000008C
-:10C4B000000000000000000000000000000000007C
-:10C4C000000000000000000000000000000000006C
-:10C4D000000000000000000000000000000000005C
-:10C4E000000000000000000000000000000000004C
-:10C4F000000000000000000000000000000000003C
-:10C50000000000000000000000000000000000002B
-:10C51000000000000000000000000000000000001B
-:10C52000000000000000000000000000000000000B
-:10C5300000000000000000000000000000000000FB
-:10C5400000000000000000000000000000000000EB
-:10C5500000000000000000000000000000000000DB
-:10C5600000000000000000000000000000000000CB
-:10C5700000000000000000000000000000000000BB
-:10C5800000000000000000000000000000000000AB
-:10C59000000000000000000000000000000000009B
-:10C5A000000000000000000000000000000000008B
-:10C5B000000000000000000000000000000000007B
-:10C5C000000000000000000000000000000000006B
-:10C5D000000000000000000000000000000000005B
-:10C5E000000000000000000000000000000000004B
-:10C5F000000000000000000000000000000000003B
-:10C60000000000000000000000000000000000002A
-:10C61000000000000000000000000000000000001A
-:10C62000000000000000000000000000000000000A
-:10C6300000000000000000000000000000000000FA
-:10C6400000000000000000000000000000000000EA
-:10C6500000000000000000000000000000000000DA
-:10C6600000000000000000000000000000000000CA
-:10C6700000000000000000000000000000000000BA
-:10C6800000000000000000000000000000000000AA
-:10C69000000000000000000000000000000000009A
-:10C6A000000000000000000000000000000000008A
-:10C6B000000000000000000000000000000000007A
-:10C6C000000000000000000000000000000000006A
-:10C6D000000000000000000000000000000000005A
-:10C6E000000000000000000000000000000000004A
-:10C6F000000000000000000000000000000000003A
-:10C700000000000000000000000000000000000029
-:10C710000000000000000000000000000000000019
-:10C720000000000000000000000000000000000009
-:10C7300000000000000000000000000000000000F9
-:10C7400000000000000000000000000000000000E9
-:10C7500000000000000000000000000000000000D9
-:10C7600000000000000000000000000000000000C9
-:10C7700000000000000000000000000000000000B9
-:10C7800000000000000000000000000000000000A9
-:10C790000000000000000000000000000000000099
-:10C7A0000000000000000000000000000000000089
-:10C7B0000000000000000000000000000000000079
-:10C7C0000000000000000000000000000000000069
-:10C7D0000000000000000000000000000000000059
-:10C7E0000000000000000000000000000000000049
-:10C7F0000000000000000000000000000000000039
-:10C800000000000000000000000000000000000028
-:10C810000000000000000000000000000000000018
-:10C820000000000000000000000000000000000008
-:10C8300000000000000000000000000000000000F8
-:10C8400000000000000000000000000000000000E8
-:10C8500000000000000000000000000000000000D8
-:10C8600000000000000000000000000000000000C8
-:10C8700000000000000000000000000000000000B8
-:10C8800000000000000000000000000000000000A8
-:10C890000000000000000000000000000000000098
-:10C8A0000000000000000000000000000000000088
-:10C8B0000000000000000000000000000000000078
-:10C8C0000000000000000000000000000000000068
-:10C8D0000000000000000000000000000000000058
-:10C8E0000000000000000000000000000000000048
-:10C8F0000000000000000000000000000000000038
-:10C900000000000000000000000000000000000027
-:10C910000000000000000000000000000000000017
-:10C920000000000000000000000000000000000007
-:10C9300000000000000000000000000000000000F7
-:10C9400000000000000000000000000000000000E7
-:10C9500000000000000000000000000000000000D7
-:10C9600000000000000000000000000000000000C7
-:10C9700000000000000000000000000000000000B7
-:10C9800000000000000000000000000000000000A7
-:10C990000000000000000000000000000000000097
-:10C9A0000000000000000000000000000000000087
-:10C9B0000000000000000000000000000000000077
-:10C9C0000000000000000000000000000000000067
-:10C9D0000000000000000000000000000000000057
-:10C9E0000000000000000000000000000000000047
-:10C9F0000000000000000000000000000000000037
-:10CA00000000000000000000000000000000000026
-:10CA10000000000000000000000000000000000016
-:10CA20000000000000000000000000000000000006
-:10CA300000000000000000000000000000000000F6
-:10CA400000000000000000000000000000000000E6
-:10CA500000000000000000000000000000000000D6
-:10CA600000000000000000000000000000000000C6
-:10CA700000000000000000000000000000000000B6
-:10CA800000000000000000000000000000000000A6
-:10CA90000000000000000000000000000000000096
-:10CAA0000000000000000000000000000000000086
-:10CAB0000000000000000000000000000000000076
-:10CAC0000000000000000000000000000000000066
-:10CAD0000000000000000000000000000000000056
-:10CAE0000000000000000000000000000000000046
-:10CAF0000000000000000000000000000000000036
-:10CB00000000000000000000000000000000000025
-:10CB10000000000000000000000000000000000015
-:10CB20000000000000000000000000000000000005
-:10CB300000000000000000000000000000000000F5
-:10CB400000000000000000000000000000000000E5
-:10CB500000000000000000000000000000000000D5
-:10CB600000000000000000000000000000000000C5
-:10CB700000000000000000000000000000000000B5
-:10CB800000000000000000000000000000000000A5
-:10CB90000000000000000000000000000000000095
-:10CBA0000000000000000000000000000000000085
-:10CBB0000000000000000000000000000000000075
-:10CBC0000000000000000000000000000000000065
-:10CBD0000000000000000000000000000000000055
-:10CBE0000000000000000000000000000000000045
-:10CBF0000000000000000000000000000000000035
-:10CC00000000000000000000000000000000000024
-:10CC10000000000000000000000000000000000014
-:10CC20000000000000000000000000000000000004
-:10CC300000000000000000000000000000000000F4
-:10CC400000000000000000000000000000000000E4
-:10CC500000000000000000000000000000000000D4
-:10CC600000000000000000000000000000000000C4
-:10CC700000000000000000000000000000000000B4
-:10CC800000000000000000000000000000000000A4
-:10CC90000000000000000000000000000000000094
-:10CCA0000000000000000000000000000000000084
-:10CCB0000000000000000000000000000000000074
-:10CCC0000000000000000000000000000000000064
-:10CCD0000000000000000000000000000000000054
-:10CCE0000000000000000000000000000000000044
-:10CCF0000000000000000000000000000000000034
-:10CD00000000000000000000000000000000000023
-:10CD10000000000000000000000000000000000013
-:10CD20000000000000000000000000000000000003
-:10CD300000000000000000000000000000000000F3
-:10CD400000000000000000000000000000000000E3
-:10CD500000000000000000000000000000000000D3
-:10CD600000000000000000000000000000000000C3
-:10CD700000000000000000000000000000000000B3
-:10CD800000000000000000000000000000000000A3
-:10CD90000000000000000000000000000000000093
-:10CDA0000000000000000000000000000000000083
-:10CDB0000000000000000000000000000000000073
-:10CDC0000000000000000000000000000000000063
-:10CDD0000000000000000000000000000000000053
-:10CDE0000000000000000000000000000000000043
-:10CDF0000000000000000000000000000000000033
-:10CE00000000000000000000000000000000000022
-:10CE10000000000000000000000000000000000012
-:10CE20000000000000000000000000000000000002
-:10CE300000000000000000000000000000000000F2
-:10CE400000000000000000000000000000000000E2
-:10CE500000000000000000000000000000000000D2
-:10CE600000000000000000000000000000000000C2
-:10CE700000000000000000000000000000000000B2
-:10CE800000000000000000000000000000000000A2
-:10CE90000000000000000000000000000000000092
-:10CEA0000000000000000000000000000000000082
-:10CEB0000000000000000000000000000000000072
-:10CEC0000000000000000000000000000000000062
-:10CED0000000000000000000000000000000000052
-:10CEE0000000000000000000000000000000000042
-:10CEF0000000000000000000000000000000000032
-:10CF00000000000000000000000000000000000021
-:10CF10000000000000000000000000000000000011
-:10CF20000000000000000000000000000000000001
-:10CF300000000000000000000000000000000000F1
-:10CF400000000000000000000000000000000000E1
-:10CF500000000000000000000000000000000000D1
-:10CF600000000000000000000000000000000000C1
-:10CF700000000000000000000000000000000000B1
-:10CF800000000000000000000000000000000000A1
-:10CF90000000000000000000000000000000000091
-:10CFA0000000000000000000000000000000000081
-:10CFB0000000000000000000000000000000000071
-:10CFC0000000000000000000000000000000000061
-:10CFD0000000000000000000000000000000000051
-:10CFE0000000000000000000000000000000000041
-:10CFF0000000000000000000000000000000000031
-:10D000000000000000000000000000000000000020
-:10D010000000000000000000000000000000000010
-:10D020000000000000000000000000000000000000
-:10D0300000000000000000000000000000000000F0
-:10D0400000000000000000000000000000000000E0
-:10D0500000000000000000000000000000000000D0
-:10D0600000000000000000000000000000000000C0
-:10D0700000000000000000000000000000000000B0
-:10D0800000000000000000000000000000000000A0
-:10D090000000000000000000000000000000000090
-:10D0A0000000000000000000000000000000000080
-:10D0B0000000000000000000000000000000000070
-:10D0C0000000000000000000000000000000000060
-:10D0D0000000000000000000000000000000000050
-:10D0E0000000000000000000000000000000000040
-:10D0F0000000000000000000000000000000000030
-:10D10000000000000000000000000000000000001F
-:10D11000000000000000000000000000000000000F
-:10D1200000000000000000000000000000000000FF
-:10D1300000000000000000000000000000000000EF
-:10D1400000000000000000000000000000000000DF
-:10D1500000000000000000000000000000000000CF
-:10D1600000000000000000000000000000000000BF
-:10D1700000000000000000000000000000000000AF
-:10D18000000000000000000000000000000000009F
-:10D19000000000000000000000000000000000008F
-:10D1A000000000000000000000000000000000007F
-:10D1B000000000000000000000000000000000006F
-:10D1C000000000000000000000000000000000005F
-:10D1D000000000000000000000000000000000004F
-:10D1E000000000000000000000000000000000003F
-:10D1F000000000000000000000000000000000002F
-:10D20000000000000000000000000000000000001E
-:10D21000000000000000000000000000000000000E
-:10D2200000000000000000000000000000000000FE
-:10D2300000000000000000000000000000000000EE
-:10D2400000000000000000000000000000000000DE
-:10D2500000000000000000000000000000000000CE
-:10D2600000000000000000000000000000000000BE
-:10D2700000000000000000000000000000000000AE
-:10D28000000000000000000000000000000000009E
-:10D29000000000000000000000000000000000008E
-:10D2A000000000000000000000000000000000007E
-:10D2B000000000000000000000000000000000006E
-:10D2C000000000000000000000000000000000005E
-:10D2D000000000000000000000000000000000004E
-:10D2E000000000000000000000000000000000003E
-:10D2F000000000000000000000000000000000002E
-:10D30000000000000000000000000000000000001D
-:10D31000000000000000000000000000000000000D
-:10D3200000000000000000000000000000000000FD
-:10D3300000000000000000000000000000000000ED
-:10D3400000000000000000000000000000000000DD
-:10D3500000000000000000000000000000000000CD
-:10D3600000000000000000000000000000000000BD
-:10D3700000000000000000000000000000000000AD
-:10D38000000000000000000000000000000000009D
-:10D39000000000000000000000000000000000008D
-:10D3A000000000000000000000000000000000007D
-:10D3B000000000000000000000000000000000006D
-:10D3C000000000000000000000000000000000005D
-:10D3D000000000000000000000000000000000004D
-:10D3E000000000000000000000000000000000003D
-:10D3F000000000000000000000000000000000002D
-:10D40000000000000000000000000000000000001C
-:10D41000000000000000000000000000000000000C
-:10D4200000000000000000000000000000000000FC
-:10D4300000000000000000000000000000000000EC
-:10D4400000000000000000000000000000000000DC
-:10D4500000000000000000000000000000000000CC
-:10D4600000000000000000000000000000000000BC
-:10D4700000000000000000000000000000000000AC
-:10D48000000000000000000000000000000000009C
-:10D49000000000000000000000000000000000008C
-:10D4A000000000000000000000000000000000007C
-:10D4B000000000000000000000000000000000006C
-:10D4C000000000000000000000000000000000005C
-:10D4D000000000000000000000000000000000004C
-:10D4E000000000000000000000000000000000003C
-:10D4F000000000000000000000000000000000002C
-:10D50000000000000000000000000000000000001B
-:10D51000000000000000000000000000000000000B
-:10D5200000000000000000000000000000000000FB
-:10D5300000000000000000000000000000000000EB
-:10D5400000000000000000000000000000000000DB
-:10D5500000000000000000000000000000000000CB
-:10D5600000000000000000000000000000000000BB
-:10D5700000000000000000000000000000000000AB
-:10D58000000000000000000000000000000000009B
-:10D59000000000000000000000000000000000008B
-:10D5A000000000000000000000000000000000007B
-:10D5B000000000000000000000000000000000006B
-:10D5C000000000000000000000000000000000005B
-:10D5D000000000000000000000000000000000004B
-:10D5E000000000000000000000000000000000003B
-:10D5F000000000000000000000000000000000002B
-:10D60000000000000000000000000000000000001A
-:10D61000000000000000000000000000000000000A
-:10D6200000000000000000000000000000000000FA
-:10D6300000000000000000000000000000000000EA
-:10D6400000000000000000000000000000000000DA
-:10D6500000000000000000000000000000000000CA
-:10D6600000000000000000000000000000000000BA
-:10D6700000000000000000000000000000000000AA
-:10D68000000000000000000000000000000000009A
-:10D69000000000000000000000000000000000008A
-:10D6A000000000000000000000000000000000007A
-:10D6B000000000000000000000000000000000006A
-:10D6C000000000000000000000000000000000005A
-:10D6D000000000000000000000000000000000004A
-:10D6E000000000000000000000000000000000003A
-:10D6F000000000000000000000000000000000002A
-:10D700000000000000000000000000000000000019
-:10D710000000000000000000000000000000000009
-:10D7200000000000000000000000000000000000F9
-:10D7300000000000000000000000000000000000E9
-:10D7400000000000000000000000000000000000D9
-:10D7500000000000000000000000000000000000C9
-:10D7600000000000000000000000000000000000B9
-:10D7700000000000000000000000000000000000A9
-:10D780000000000000000000000000000000000099
-:10D790000000000000000000000000000000000089
-:10D7A0000000000000000000000000000000000079
-:10D7B0000000000000000000000000000000000069
-:10D7C0000000000000000000000000000000000059
-:10D7D0000000000000000000000000000000000049
-:10D7E0000000000000000000000000000000000039
-:10D7F0000000000000000000000000000000000029
-:10D800000000000000000000000000000000000018
-:10D810000000000000000000000000000000000008
-:10D8200000000000000000000000000000000000F8
-:10D8300000000000000000000000000000000000E8
-:10D8400000000000000000000000000000000000D8
-:10D8500000000000000000000000000000000000C8
-:10D8600000000000000000000000000000000000B8
-:10D8700000000000000000000000000000000000A8
-:10D880000000000000000000000000000000000098
-:10D890000000000000000000000000000000000088
-:10D8A0000000000000000000000000000000000078
-:10D8B0000000000000000000000000000000000068
-:10D8C0000000000000000000000000000000000058
-:10D8D0000000000000000000000000000000000048
-:10D8E00010000003000000000000000D0000000D0B
-:10D8F0003C020800244271203C030800246375C8E0
-:10D90000AC4000000043202B1480FFFD24420004A3
-:10D910003C1D080037BD7FFC03A0F0213C1008002F
-:10D92000261031D83C1C0800279C71200E00116481
-:10D93000000000000000000D30A5FFFF30C600FF12
-:10D94000274301808F4201B80440FFFE24020002F9
-:10D95000AC640000A4650008A066000AA062000B89
-:10D960003C021000AC67001803E00008AF4201B8A9
-:10D970003C0360008C624FF80440FFFE3C02020052
-:10D98000AC644FC0AC624FC43C02100003E000081E
-:10D99000AC624FF827BDFFE8AFBF0014AFB0001076
-:10D9A0000E0011B300808021936200052403FFFE66
-:10D9B00002002021004310248FBF00148FB00010FC
-:10D9C000A36200050A0011BC27BD001827BDFFE8AF
-:10D9D000AFB00010AFBF00140E000EA40080802175
-:10D9E0009362000024030050304200FF14430004FF
-:10D9F00024020100AF4201800A000CC10200202174
-:10DA0000AF400180020020218FBF00148FB00010B2
-:10DA10000A000F7D27BD001827BDFF98AFBE00602C
-:10DA2000AFB7005CAFB20048AFBF0064AFB60058FC
-:10DA3000AFB50054AFB40050AFB3004CAFB1004429
-:10DA4000AFB000408F5001289363003F9362000500
-:10DA50000000F021307200FF000210273042000168
-:10DA60000000B82114400066AFA0003893420116B0
-:10DA700093430112304200FF306300FF0342202134
-:10DA800003431021244540008F82000010400018FD
-:10DA9000248840008F4201043C030001004310240D
-:10DAA00010400013000000008CA3000C8F620030B7
-:10DAB000146201A2240200018CA300108F62002CCA
-:10DAC0001462019E240200019762003A9483400090
-:10DAD0003042FFFF1462019924020001976200386E
-:10DAE000950300023042FFFF1462019424020001FA
-:10DAF00093620000304300FF240200201062000502
-:10DB00002402005010620006000000000A000D0B05
-:10DB1000000000000000000D0A000D14AFA000304E
-:10DB20003C1E080027DE71880A000D14AFA00030EB
-:10DB30003C0208008C4200DC244200013C01080049
-:10DB4000AC2200DC0E00127D000000000A000E8FE7
-:10DB50008FBF00648F4201043C0300209113000D2D
-:10DB6000004310240002202B00042140AFA4003009
-:10DB70008F4301043C02004000621824146000023C
-:10DB8000348700400080382132620020AFA7003087
-:10DB90001440000234E6008000E0302110C0000B89
-:10DBA000AFA6003093C500088F67004C020020210B
-:10DBB00000052B0034A5008130A5F0810E000C8DEE
-:10DBC00030C600FF0A000E8C000000009362003E89
-:10DBD000304200401040000E24020004564200066D
-:10DBE00024020012020020210E0013DA010030216D
-:10DBF0000A000E8F8FBF006416420005000000006F
-:10DC00000E000CB2000020210A000E8F8FBF0064AE
-:10DC10009742011A9504000E9363003532650004A3
-:10DC20003055FFFF00642004AFA4003C8D110004B8
-:10DC300010A000158D1400089362003E3042004091
-:10DC400010400007000000000E00133B02202021BE
-:10DC50001040000D000000000A000E8C00000000C3
-:10DC60008F620044022210230440013200000000B1
-:10DC70008F620048022210230441012E2404001662
-:10DC80000A000DA28FC200048F62004802221023F6
-:10DC900004400008000000003C0208008C423100F3
-:10DCA000244200013C010800AC2231000A000E8130
-:10DCB000000000008F62004002221023184000097B
-:10DCC0002402000C3C0208008C423100327300FC3C
-:10DCD0000000A821244200013C010800AC223100D0
-:10DCE0002402000CAFA200308F62004000511823C4
-:10DCF0001860000D02A3102A144001030000000068
-:10DD00001475000602A310233A620001304200019C
-:10DD1000144000FD0000000002A31023022388210C
-:10DD20000A000D8A3055FFFF000018213262000200
-:10DD30001040001A326200109362003E30420040F0
-:10DD4000504000118FC200040E0011B302002021C8
-:10DD500024020018A362003F936200052403FFFE23
-:10DD600002002021004310240E0011BCA362000514
-:10DD700024040039000028210E0013242406001872
-:10DD80000A000E8E24020001240400170040F80946
-:10DD9000000000000A000E8E24020001104000E581
-:10DDA000000000008F64004C8F6200540282102338
-:10DDB0001C4000E002841023044200010080A021E6
-:10DDC000AFA30018AFB10010AFB50014934201200B
-:10DDD0008F6600409764003C304200FF03422821D8
-:10DDE0008FA2003C00A328218FA300303084FFFFC6
-:10DDF0000044202B8FC200000064182524A5400099
-:10DE0000AFA50020AFA60028AFA30030AFA6002426
-:10DE1000AFA0002CAFB400340040F80927A40010D4
-:10DE20008FA200303042000254400001327300FEE5
-:10DE30009362003E30420040104000378FA3001430
-:10DE40008F6200541682001A32620001240200140C
-:10DE5000124200102A42001510400006240200164B
-:10DE60002402000C12420007326200010A000DEB8E
-:10DE70000000000012420005326200010A000DEBB2
-:10DE8000000000000A000DE62417000E0A000DE64F
-:10DE9000241700100A000DEA2417001293620023D1
-:10DEA0002403FFBD00431024A3620023326200015B
-:10DEB000104000198FA300142402000C1242000E1F
-:10DEC0002A42000D104000062402000E2402000A1F
-:10DED000124200078FA200240A000E032442000110
-:10DEE000124200088FA200240A000E0324420001FF
-:10DEF0000A000E01241700082402000E16E2000298
-:10DF000024170016241700108FA2002424420001B9
-:10DF1000AFA200248FA300148FA200248F760040AC
-:10DF200000431021AF6200408FA2003C9364003692
-:10DF30008F630040028290213402FFFF00821004B0
-:10DF400000621821AF6300488FA6003030C200087D
-:10DF50001040000E000000008F62005816420004BE
-:10DF600030C600FF9742011A5040000134C600102D
-:10DF700093C500088FA700340200202100052B0064
-:10DF800034A500800E000C8D30A5F0808F6200401B
-:10DF900000561023184000178FA200183C020800FA
-:10DFA0008C423198304200101040000924020001D8
-:10DFB000976200681440000624020001A76200680E
-:10DFC0009742007A2442000A0A000E47A762001214
-:10DFD000A76200120E0011B3020020219362007D9F
-:10DFE0002403000102002021344200010A000E45F2
-:10DFF000AFA300381840000A000000000E0011B363
-:10E00000020020219362007D2403000102002021F0
-:10E01000AFA30038344200040E0011BCA362007D9F
-:10E020009362003E304200401440000C3262000116
-:10E030001040000A000000008F6300408FC20004FF
-:10E0400024040018246300010040F809AF63004075
-:10E050008FA200300A000E8E304200048F620058FA
-:10E0600010520010000000008F62001802221023DE
-:10E070001C400008240200018F62001816220009CB
-:10E08000000000008F62001C028210230440000583
-:10E0900024020001AF720058AFA20038AF7100181F
-:10E0A000AF74001C12E0000B8FA300380E0011B3F8
-:10E0B00002002021A377003F0E0011BC02002021A6
-:10E0C00002E03021240400370E0013240000282130
-:10E0D0008FA3003810600003000000000E000C9BAE
-:10E0E0000200202112A00005000018218FA200309C
-:10E0F0003042000450400011006010212403000150
-:10E100000A000E8E006010210E0011B302002021C3
-:10E110009362007D02002021344200040E0011BCF5
-:10E12000A362007D0E000C9B020020210A000E8ECF
-:10E1300024020001AF400044240200018FBF0064AC
-:10E140008FBE00608FB7005C8FB600588FB500544B
-:10E150008FB400508FB3004C8FB200488FB1004491
-:10E160008FB0004003E0000827BD00688C870004E2
-:10E170008C8600000000102100E5382100E5282BE6
-:10E1800000C2302100C53021AC87000403E0000844
-:10E19000AC8600008F4201B80440FFFE2402080054
-:10E1A000AF4201B803E00008000000003C02000894
-:10E1B0000342282194A200483084FFFF1040001B36
-:10E1C0002484001294A200483042FFFF0044102A29
-:10E1D00010400017240200032402001A9343012078
-:10E1E000A342018B8F820008306300FF3042400061
-:10E1F000104000092463FFFE94A200483042FFFF54
-:10E200000043102B144000058F820014A743019493
-:10E210000A000EC8344200018F8200142403FFFE5E
-:10E220000043102403E00008AF820014240200031E
-:10E2300003E00008A342018B27BDFFE0AFB2001846
-:10E24000AFB10014AFB00010AFBF001C30B1FFFF82
-:10E2500030D0FFFF30F2FFFF8F4201B80440FFFED5
-:10E2600000000000AF440180AF4400200E000EAA61
-:10E27000020020218F8300088F840014A751018C95
-:10E28000A750018EA74301908F8300043082800045
-:10E29000AF4301A8A75201881040000E8F820014DE
-:10E2A00093420116304200FC24420004005A10211F
-:10E2B0008C4240003042FFFF144000068F82001461
-:10E2C0003C02FFFF34427FFF00821024AF82001423
-:10E2D0008F8200142403BFFF00431024A74201A62D
-:10E2E0009743010C8F42010400031C003042FFFFE2
-:10E2F00000621825AF4301AC3C021000AF4201B8E8
-:10E300008FBF001C8FB200188FB100148FB00010A7
-:10E3100003E0000827BD002027BDFFE0AFB20018D2
-:10E3200030D2FFFFAF440180AF44002002402021E3
-:10E33000AFB10014AFB0001030F1FFFFAFBF001C51
-:10E340000E000EAA30B0FFFF8F8300142402BFFF1F
-:10E35000A750018C006218248F820008A752018EFA
-:10E36000A7510188A74301A6A74201903C021000D3
-:10E37000AF4201B88FBF001C8FB200188FB10014DC
-:10E380008FB0001003E0000827BD00202743018064
-:10E390008F4201B80440FFFE24022000A46200085E
-:10E3A00024020002A062000BA46000103C021000D6
-:10E3B000AF4201B803E00008000000008F47007082
-:10E3C000934201128F83000827BDFFF0304200FF07
-:10E3D000000228823062010000003021104000431A
-:10E3E00024A400033062400010400010306220007E
-:10E3F00000041080005A10218C43400024A4000423
-:10E4000000041080AFA30000005A10218C4240008D
-:10E41000AFA2000493420116304200FC005A1021C2
-:10E420008C4240000A000F56AFA200081040002F97
-:10E430000000302100041080005A10218C4340005D
-:10E4400024A4000400041080AFA30000005A10218F
-:10E450008C424000AFA00008AFA200048FA80008C3
-:10E460000000302100002021240A00083C09080097
-:10E470002529010003A41021148A000300042A00A6
-:10E480001100000A000000009042000024840001F6
-:10E490002C83000C00A210210002108000491021E2
-:10E4A0008C4200001460FFF300C230263C040800D8
-:10E4B0008C8431048F4200702C830020106000098E
-:10E4C000004738233C03080024633108000410800F
-:10E4D0000043102124830001AC4700003C010800E8
-:10E4E000AC233104AF8600042406000100C01021D3
-:10E4F00003E0000827BD00103C0208008C420038F1
-:10E5000027BDFFD0AFB50024AFB3001CAFBF0028BC
-:10E51000AFB40020AFB20018AFB10014AFB000101C
-:10E520003C15080026B50038144000022453FFFFB4
-:10E53000000098218F840008308240001040000ABB
-:10E54000308280003C0200200082102450400006EF
-:10E55000308280008F8200142403BFFF00831824C0
-:10E560000A000FA2344210001040000A3C020020B2
-:10E5700000821024104000078F8200143C03FFFF2C
-:10E5800034637FFF0083182434428000AF8200147C
-:10E59000AF8300080E000F2E00000000144000089A
-:10E5A0008F8400089743011E9742011C3063FFFFD0
-:10E5B0000002140000621825AF8300048F84000855
-:10E5C0009742010C30831000106000113046FFFFAD
-:10E5D000308200201440000F241200053C0210007D
-:10E5E000008210241040000B241200013C030E0096
-:10E5F0003C020DFF008318243442FFFF0043102B20
-:10E6000010400004000000000A000FC4241200059E
-:10E61000241200013C0508008CA5003454A0001908
-:10E620008F8400088F82001C544000168F840008DD
-:10E630008F82001430424000544000128F84000842
-:10E640003C021F01008210243C0310001443000D03
-:10E650008F84000830C202001440000B3C0200010D
-:10E660009746010E364700020000202124C6000410
-:10E6700030C6FFFF0E000F05240500020A00108DB2
-:10E680008FBF00283C020001008210241040000CC3
-:10E690008F8300143C0208008C4200D89746010E7C
-:10E6A000240400802442000130C6FFFF240500023C
-:10E6B0003C010800AC2200D80A00108A240700039D
-:10E6C00030624000104000063C0210003C020F0087
-:10E6D0000082102450400001934201163C021000B9
-:10E6E0000082102410400044000000003C0208009A
-:10E6F0008C4200301040000C306240001040000A94
-:10E700003C030F00008318243C0201000043102B3F
-:10E7100014400005000000009746010E3647000235
-:10E720000A0010872404008010A0000D3082010030
-:10E730001040000B3C020F00008210243C0302003A
-:10E74000104300078F82000400531024005510214D
-:10E7500090420004244200040A00103A000221C042
-:10E76000000000008F8600083C0508008CA500D042
-:10E77000000616023050000F38A200012C420001A2
-:10E780002E03000C0043102414400018001021C078
-:10E790002602FFFC2C4200045440001400002021FB
-:10E7A00038A200022C420001004310241040000354
-:10E7B000000612420A00103A000020210010182B17
-:10E7C0000043102450400009001021C09746010E5C
-:10E7D000000020212405000224C6000430C6FFFFEB
-:10E7E0000E000ECD3247FFFB001021C09746010EF0
-:10E7F0000A001087364700028F4240003C11080093
-:10E800008E310024304201001040004032220001CD
-:10E810000220802110A00017325400043082010031
-:10E8200010400015240200013C020F000082102459
-:10E830003C0302001043000F8F8200049746010E34
-:10E840000240382100531024005510219044000448
-:10E8500024C6000430C6FFFF24840004000421C045
-:10E860000E000ECD240500022402FFFE02228024A9
-:10E870003252FFFB2402000116020007320200019F
-:10E880003242000450400001365200029746010E09
-:10E890000A001086024038211040000A32020004AB
-:10E8A0009746010E024038210000202124C60004B2
-:10E8B00030C6FFFF0E000ECD240500023252FFFBD2
-:10E8C000320200041040000B8F8200083042080022
-:10E8D00010400008000000009746010E0240382159
-:10E8E0002404010024C6000430C6FFFF0E000ECD34
-:10E8F00024050002568000108FBF00280E000F2252
-:10E90000000000000A00108D8FBF00281040000A90
-:10E910008FBF00289746010E3647000200002021D5
-:10E9200024C6000430C6FFFF240500020E000ECDF1
-:10E93000000000008FBF00288FB500248FB4002096
-:10E940008FB3001C8FB200188FB100148FB000106D
-:10E950000000102103E0000827BD0030274301809C
-:10E960008F4201B80440FFFE000000008F420148C2
-:10E9700000021402A462000824020002A062000B3C
-:10E980008F420148A46200108F420144AC6200240F
-:10E990003C02100003E00008AF4201B827BDFFE8C9
-:10E9A000AFB000103C04600CAFBF00148C8250006C
-:10E9B0002403FF7F3C1A8000004310243442380CAB
-:10E9C000AC825000240200033C106000AF420008FB
-:10E9D0008E0208083C1B80083C010800AC20002087
-:10E9E0003042FFF0384200102C4200010E001B396B
-:10E9F000AF8200003C04FFFF3C02040034830806A1
-:10EA00003442000CAE021948AE03194C3C056016A6
-:10EA10008E0219808CA30000344202000064182486
-:10EA2000AE0219803C0253531462000334A47C00EC
-:10EA30008CA20004005020218C82007C8C83007802
-:10EA40008FBF00148FB0001027BD0018AF820018D0
-:10EA500003E00008AF83001027BDFFE8AFBF001040
-:10EA60008F4340003402FFFF3C040800248400F080
-:10EA700010620007000000008F4240003C040800C4
-:10EA8000248400E83042010010400009000000002A
-:10EA90009745010E0E000E9A30A5FFFF9745010E17
-:10EAA0003C040800248431C80A0010FC8FBF001009
-:10EAB0008F4340008F8200103C040800248400E053
-:10EAC0001462000A000000008F4340048F82001887
-:10EAD00014620006000000009745010E3C04080087
-:10EAE000248431B80A0010FC8FBF00109745010E36
-:10EAF0008FBF001030A5FFFF0A000E9A27BD001837
-:10EB000027BDFFE8AFBF00108F420128AF420020B1
-:10EB10008F4201048F430100AF8200080E000EA453
-:10EB2000AF8300140E0010D5000000003C02080066
-:10EB30008C4200C0104000088F8400083C0208008E
-:10EB40008C4200C4244200013C010800AC2200C4F5
-:10EB50000A001135000000003C0200100082102461
-:10EB60001440000A8F8300143C0208008C420020ED
-:10EB7000244200013C010800AC2200200E000F7D61
-:10EB8000000020210A001133000000002402BFFF12
-:10EB9000006210241040000800000000240287FFDB
-:10EBA00000621024144000083C020060008210241F
-:10EBB00010400005000000000E000CC50000000021
-:10EBC0000A001133000000000E00119D000000003B
-:10EBD000104000063C0240008F4301243C026020AC
-:10EBE000AC430014000000003C024000AF4201387A
-:10EBF000000000008FBF001003E0000827BD0018D0
-:10EC000027BDFFE8AFBF00108F4201403C04400029
-:10EC1000AF4200208F4301483C027000006218247C
-:10EC2000106400100083102B144000063C026000AA
-:10EC30003C02200010620007000000000A00115F83
-:10EC40003C0240001062000B3C0240000A00115FD1
-:10EC5000000000000E001096000000000A00115F86
-:10EC60003C0240000E0011C1000000000A00115FCC
-:10EC70003C0240000E001B46000000003C02400029
-:10EC8000AF420178000000008FBF001003E00008D1
-:10EC900027BD001827BDFFE8AFBF00140E0010A667
-:10ECA000AFB000103C028000344200708C43000082
-:10ECB00000403821AF830020006030218CE8000044
-:10ECC0003C0508008CA500FC3C0408008C8400F87E
-:10ECD000010630230000102100A6282100A6302BB9
-:10ECE00000822021008620213C010800AC2500FC88
-:10ECF0003C010800AC2400F88F50000032020003F1
-:10ED00001040FFEE010030218CE600003C050800B9
-:10ED10008CA500FC3C0408008C8400F800C830235B
-:10ED200000A628210000102100A6302B00822021FF
-:10ED300000862021320700013C010800AC2500FCC0
-:10ED4000AF8800203C010800AC2400F810E000046B
-:10ED5000320200020E0010FF00000000320200022A
-:10ED60005040FFD13C0280000E00113F0000000027
-:10ED70000A0011693C0280008F4201003042003ECF
-:10ED80001440001124020001AF4000488F420100EE
-:10ED9000304207C01040000500000000AF40004CAA
-:10EDA000AF40005003E0000824020001AF400054CF
-:10EDB000AF4000408F420100304238005440000113
-:10EDC000AF4000442402000103E0000800000000FE
-:10EDD0003C0290003442000100822025AF44002014
-:10EDE0008F4200200440FFFE0000000003E0000806
-:10EDF000000000003C028000344200010082202517
-:10EE000003E00008AF44002027BDFFE0AFB20018C8
-:10EE1000AFBF001CAFB10014AFB000108F50014065
-:10EE20008F5101483C0280000011940202222024EC
-:10EE3000324300FF2402000E1062008A2862000F95
-:10EE40001040001228620037240200061062003BC6
-:10EE50002862000710400007240200091060001A11
-:10EE60002402000110620025000000000A00127652
-:10EE7000000000001062007B2402000B1062005BA7
-:10EE80003222FFFF0A001276000000001040000846
-:10EE90002402003828620035104000802402001F40
-:10EEA0001062007E000000000A00127600000000E0
-:10EEB0001062007A2402008010620042000000000C
-:10EEC0000A001276000000008F4201B80440FFFEE5
-:10EED00024020001AF500180AF400184A752018895
-:10EEE000A342018A24020002A342018BA751019090
-:10EEF0008F4201440A001271AF4201A41080000A3F
-:10EF0000240200023C010800A02271783C010800A4
-:10EF1000AC3071808F4201443C010800AC22717C0E
-:10EF20000A0012788FBF001C8F4201B80440FFFE18
-:10EF3000240200020A00125B000000008F4201B8A8
-:10EF40000440FFFE00000000AF5001803C020800BA
-:10EF50009042717810400003000018213C03080023
-:10EF60008C637180AF430184A75201883C02080082
-:10EF7000904271780000182134420001A342018AB6
-:10EF800024020002A342018BA75101908F42014449
-:10EF9000AF4201A43C020800904271781040000387
-:10EFA0003C0210003C0308008C63717CAF4301A855
-:10EFB000AF4201B83C010800A02071780A00127825
-:10EFC0008FBF001C8F4201B80440FFFE24020002E4
-:10EFD000A342018BA7520188A75101908F4201449F
-:10EFE000A74201920A0012733C0210001440001D57
-:10EFF0000000000093620005304200041440003716
-:10F00000000000000E0011B30200202193620005F1
-:10F0100002002021344200040E0011BCA36200054E
-:10F02000936200053042000414400002000000001A
-:10F030000000000D9362000024030020304200FF16
-:10F0400014430008000000008F4201B80440FFFE96
-:10F0500024020005AF500180A342018B3C02100046
-:10F06000AF4201B88F4201B80440FFFE2402000203
-:10F07000AF400180AF500184A7520188A342018AAA
-:10F08000A342018BA7510190AF4001A48F420144DC
-:10F09000AF4201A80A0012733C0210008F4201B86F
-:10F0A0000440FFFE24020001AF500180AF40018404
-:10F0B000A7520188A342018A24020002A342018BC5
-:10F0C000A7510190AF4001A4AF4001A83C0210003D
-:10F0D000AF4201B80A0012788FBF001C0000000D7B
-:10F0E0008FBF001C8FB200188FB100148FB00010BA
-:10F0F00003E0000827BD002027BDFFE8AFBF0010D8
-:10F100000E000EA400000000AF4001808FBF001071
-:10F11000000020210A000F7D27BD00183084FFFF6A
-:10F1200030A5FFFF0000182110800007000000003C
-:10F1300030820001104000020004204200651821C6
-:10F140000A0012890005284003E000080060102131
-:10F1500010C0000624C6FFFF8CA2000024A50004F6
-:10F16000AC8200000A0012932484000403E000082B
-:10F170000000000010A0000824A3FFFFAC860000E0
-:10F1800000000000000000002402FFFF2463FFFFD6
-:10F190001462FFFA2484000403E000080000000069
-:10F1A00027BDFFE0AFB20018AFB10014AFB0001040
-:10F1B000AFBF001C9482000C00A088212490001492
-:10F1C0000002130200021080008290210000302112
-:10F1D00000A020210E00129C240500050212102B15
-:10F1E0001040005700001021920300002C6200091B
-:10F1F0005040005192020001000310803C030800BF
-:10F20000246370DC004310218C42000000400008A1
-:10F2100000000000920300012402000C1462004868
-:10F2200024020001025010232C42000A1440003630
-:10F23000261000028E22000034420100AE2200009F
-:10F240009202000092030001920400029205000362
-:10F2500000031C00000216000043102500042200D9
-:10F26000004410250045102526100004AE2200049D
-:10F270009202000092030001920400029205000332
-:10F280000002160000031C000043102500042200A9
-:10F290000044102500451025261000040A0012B66F
-:10F2A000AE2200089203000124020004146200163A
-:10F2B0002610000292020000920400018E2300003A
-:10F2C00000021200004410253463000426100002DE
-:10F2D000AE22000C0A0012B6AE2300009203000119
-:10F2E0002402000314620008261000028E2200008F
-:10F2F000920300002610000134420008A2230010EF
-:10F300000A0012B6AE2200000A00130F2402000108
-:10F31000920300012402000210620002260400028F
-:10F32000024020210A0012B6008080210A0012B695
-:10F3300026100001920200010A0012B6020280218A
-:10F340008FBF001C8FB200188FB100148FB0001057
-:10F3500003E0000827BD002027BDFFE8AFBF001471
-:10F36000AFB000100E0011B3008080219362007DC9
-:10F3700002002021344200200E0011BCA362007D57
-:10F38000020020218FBF00148FB000100A000C9BD8
-:10F3900027BD0018308300FF30A500FF30C600FFF6
-:10F3A000274701808F4201B80440FFFE00000000A3
-:10F3B0008F42012834634000ACE2000024020001C7
-:10F3C000ACE00004A4E30008A0E2000A240200026A
-:10F3D000A0E2000B3C021000A4E50010ACE0002409
-:10F3E000ACE00028A4E6001203E00008AF4201B838
-:10F3F00027BDFFE8AFBF00109362003F2403001257
-:10F40000304200FF1043000D008030218F62004425
-:10F41000008210230440000A8FBF00108F62004852
-:10F42000240400390000282100C2102304410004F4
-:10F43000240600120E001324000000008FBF0010ED
-:10F440002402000103E0000827BD001827BDFFC803
-:10F45000AFB1002C00A08821AFB2003027A500106A
-:10F460000080902102202021AFBF00340E0012A79F
-:10F47000AFB0002810400009024020218E22000871
-:10F48000AF6200840E001315AF6000402404003802
-:10F490002405008D0A0013D1240600129362003463
-:10F4A000936300378F640084304200FF306300FFB5
-:10F4B0000043282100A4202B1080000B0000000036
-:10F4C0009763003C8F6200843063FFFF0045102388
-:10F4D0000062182B14600004000000008F6200849A
-:10F4E0000A00137B004580239762003C3050FFFFE9
-:10F4F0008FA3001030620004504000032E02021857
-:10F500008FA2001C0202102B1440000502002021D3
-:10F510003062000410400002240402188FA4001C72
-:10F520002C82008010400002008080212410008086
-:10F530000E0011B30240202124020001AF62000C32
-:10F540009362003E001020403042007FA362003EE4
-:10F550008E22000424420001AF620040A770003CEC
-:10F560008F6200509623000E00431021AF620058B6
-:10F570008F62005000441021AF62005C8E220004B4
-:10F58000AF6200188E220008AF62001C8FA200102C
-:10F59000304200085440000A93A20020A3600036C5
-:10F5A000936200362403FFDFA36200359362003EBE
-:10F5B00000431024A362003E0A0013B18E2200080B
-:10F5C000A36200358E220008AF62004C8F620024D7
-:10F5D0008F63004000431021AF6200489362000037
-:10F5E00024030050304200FF144300122403FF8024
-:10F5F0003C0208008C4231A002421021004310243A
-:10F60000AF4200283C0208008C4231A08E24000842
-:10F610003C03000C024210213042007F03421021C3
-:10F6200000431021AC4400D88E230008AF8200288C
-:10F63000AC4300DC0E0011BC024020212404003841
-:10F64000000028212406000A0E00132400000000F8
-:10F650008FBF00348FB200308FB1002C8FB00028E4
-:10F660002402000103E0000827BD003827BDFFE8A1
-:10F67000AFBF001090C7000D00C0282130E6001079
-:10F6800010C0000A30E200048CA300088F6200540E
-:10F690001062000630E20004144000178FBF001013
-:10F6A000000020210A000CB227BD00181040000DF8
-:10F6B00030E3001210C000108FBF00108CA30008B0
-:10F6C0008F6200541462000D2402000124040038EB
-:10F6D0002405008D0E001324240600120A0013FDD9
-:10F6E0008FBF001024020012146200038FBF0010AD
-:10F6F0000A00135227BD00182402000103E000088D
-:10F7000027BD001827BDFFF827420180AFA20000E7
-:10F71000308A00FF8F4201B80440FFFE0000000065
-:10F720008F4601283C0208008C4231A02403FF8050
-:10F73000AF86005000C2102100431024AF420024C5
-:10F740003C0208008C4231A08FA900008FA8000065
-:10F7500000C210213042007F034218213C02000AFF
-:10F7600000621821946400D48FA700008FA50000C8
-:10F7700024020002AF830028A0A2000B8FA3000088
-:10F78000354260003084FFFFA4E200083C02100014
-:10F79000AD260000AD040004AC60002427BD0008C5
-:10F7A000AF4201B803E00008240200018C8200048B
-:10F7B0008F83002800451023AC8200049062006310
-:10F7C0003042007FA06200638C820020938300306F
-:10F7D0008F85002834420002AF830044A780004296
-:10F7E000AC820020A4A000E490A200632403FFBF29
-:10F7F0000043102403E00008A0A200632743018017
-:10F800008F4201B80440FFFE8F820050AC620000BE
-:10F810008F420124AC62000424026083A4620008C9
-:10F8200024020002A062000B3C02100003E000086A
-:10F83000AF4201B88F880044938200308F83002844
-:10F840003C07080024E7759400481023304200FF6D
-:10F85000304900FC246500888F860048304A000348
-:10F860001120000900002021248200048CA3000044
-:10F87000304400FF0089102AACE3000024A50004F6
-:10F880001440FFF924E70004114000090000202182
-:10F890002482000190A30000304400FF008A102B56
-:10F8A000A0E3000024A500011440FFF924E70001B3
-:10F8B00030C20003144000048F850044310200036D
-:10F8C0001040000D0000000010A0000900002021E1
-:10F8D0002482000190C30000304400FF0085102BFB
-:10F8E000A0E3000024C600011440FFF924E7000152
-:10F8F00003E00008000000001100FFFD00002021CF
-:10F90000248200048CC30000304400FF0088102BC8
-:10F91000ACE3000024C600041440FFF924E700040F
-:10F9200003E00008000000008F8300449382003051
-:10F9300030C600FF30A500FF00431023304300FF16
-:10F940008F820028008038210043102114C000025B
-:10F95000244800880083382130E200031440000569
-:10F9600030A2000314400003306200031040000D79
-:10F970000000000010A000090000202124820001E6
-:10F9800090E30000304400FF0085102BA10300002D
-:10F9900024E700011440FFF92508000103E00008F6
-:10F9A0000000000010A0FFFD0000202124820004C0
-:10F9B0008CE30000304400FF0085102BAD030000F5
-:10F9C00024E700041440FFF92508000403E00008C0
-:10F9D0000000000027BDFFF82402FFFFAFA20000D7
-:10F9E000008038212405002F3C0908002529719446
-:10F9F000240800FF2406FFFF90E2000024A3FFFF7D
-:10FA00000006220200C21026304200FF00021080D1
-:10FA1000004910218C420000306500FF24E70001FE
-:10FA200014A8FFF50082302600061027AFA20004BC
-:10FA3000AFA200000000282127A6000400C5102363
-:10FA40009044000324A2000100BD1821304500FFAE
-:10FA50002CA200041440FFF9A06400008FA2000053
-:10FA600003E0000827BD00080080482130AAFFFFFE
-:10FA700030C600FF30E7FFFF274801808F4201B802
-:10FA80000440FFFE8F820050AD0200008F4201242F
-:10FA9000AD0200048D220020A5070008A102000A83
-:10FAA00024020016A102000B934301208D220008BE
-:10FAB0008D240004306300FF00431021978300422F
-:10FAC000004410218D250024004310233C0308002E
-:10FAD0008C6331A08F840028A502000C246300E809
-:10FAE0002402FFFFA50A000EA5030010A5060012C0
-:10FAF000AD050018AD020024948201142403FFF721
-:10FB00003042FFFFAD0200288C820118AD02002CAC
-:10FB10003C021000AD000030AF4201B88D22002041
-:10FB20000043102403E00008AD2200208F8200284B
-:10FB300030E7FFFF00804821904200D330A5FFFF4F
-:10FB400030C600FF0002110030420F0000E23825ED
-:10FB5000274801808F4201B80440FFFE8F82005089
-:10FB6000AD0200008F420124AD0200048D2200206E
-:10FB7000A5070008A102000A24020017A102000B39
-:10FB8000934301208D2200088D240004306300FF80
-:10FB90000043102197830042004410218F840028E5
-:10FBA000004310233C0308008C6331A0A502000C25
-:10FBB000A505000E246300E8A5030010A5060012A9
-:10FBC000AD0000148D220024AD0200188C82005C70
-:10FBD000AD02001C8C820058AD0200202402FFFF01
-:10FBE000AD020024948200E63042FFFFAD020028FF
-:10FBF00094820060948300BE30427FFF3063FFFF39
-:10FC00000002120000431021AD02002C3C02100043
-:10FC1000AD000030AF4201B8948200BE2403FFF76C
-:10FC200000A21021A48200BE8D22002000431024D7
-:10FC300003E00008AD220020274301808F4201B875
-:10FC40000440FFFE24020018AC640000A062000B18
-:10FC50008F820028944200E6A46200103C0210004B
-:10FC6000AC60003003E00008AF4201B827430180D8
-:10FC70008F4201B80440FFFE8F82002C9442001C8A
-:10FC80003042FFFF000211C0AC62000024020019E4
-:10FC9000A062000B3C021000AC60003003E00008E2
-:10FCA000AF4201B88F87003430C300FF8F4201B8E4
-:10FCB0000440FFFE8F82005034636000ACA200005D
-:10FCC0009382004CA0A200058CE20010A4A20006C2
-:10FCD000A4A300088C8200202403FFF7A0A2000A3E
-:10FCE00024020002A0A2000B8CE20000ACA20010D3
-:10FCF0008CE20004ACA200148CE2001CACA2002434
-:10FD00008CE20020ACA200288CE2002CACA2002CDB
-:10FD10008C820024ACA200183C021000AF4201B853
-:10FD20008C8200200043102403E00008AC820020F5
-:10FD30009382004C2403000127BDFFE800433004F8
-:10FD40002C420020AFB00010AFBF00142410FFFE03
-:10FD500010400005274501803C0208008C4231908C
-:10FD60000A00159C004610243C0208008C42319485
-:10FD70000046102414400007240600848F830028C6
-:10FD80002410FFFF906200623042000F34420040B6
-:10FD9000A06200620E001568000000000200102141
-:10FDA0008FBF00148FB0001003E0000827BD0018BB
-:10FDB0008F83002C27BDFFE0AFB20018AFB1001455
-:10FDC000AFB00010AFBF001C9062000D00A09021EA
-:10FDD00030D100FF3042007FA062000D8F850028E7
-:10FDE0008E430018008080218CA2007C14620005E4
-:10FDF0002402000E90A20063344200200A0015C5C0
-:10FE0000A0A200630E00158BA382004C2403FFFF09
-:10FE1000104300472404FFFF52200045000020212A
-:10FE20008E4300003C020010006210245040000489
-:10FE30003C020008020020210A0015D4240200150B
-:10FE400000621024504000098E450000020020216D
-:10FE5000240200140E00158BA382004C2403FFFF24
-:10FE6000104300332404FFFF8E4500003C020002D3
-:10FE700000A21024104000163C0200048F86002CC3
-:10FE80008CC200148CC300108CC4001400431023D7
-:10FE90000044102B50400005020020218E43002C0E
-:10FEA0008CC2001010620003020020210A00160517
-:10FEB000240200123C02000400A210245040001C46
-:10FEC00000002021020020210A0016052402001350
-:10FED00000A21024104000068F83002C8C620010BA
-:10FEE00050400013000020210A0015FF02002021CD
-:10FEF0008C620010504000048E42002C0200202131
-:10FF00000A001605240200115040000900002021BB
-:10FF100002002021240200170E00158BA382004C42
-:10FF20002403FFFF104300022404FFFF00002021F0
-:10FF30008FBF001C8FB200188FB100148FB000105B
-:10FF40000080102103E0000827BD002093830030CB
-:10FF500027BDFFE024020034AFB20018AFB1001497
-:10FF6000AFBF001CAFB00010008088211462000CED
-:10FF700000A090218F8400340E0014B48C900030C7
-:10FF80001202000724020005022020210E00158B1A
-:10FF9000A382004C2403FFFF1043005F2404FFFFF3
-:10FFA00092420004104000098F8200280220202184
-:10FFB0002402000C0E00158BA382004C2403FFFFCB
-:10FFC000104300552404FFFF8F820028A3800024E3
-:10FFD0008E4300048C4400803C0200FF3442FFFF4B
-:10FFE000006218240083202B10800008AF83003C9F
-:10FFF00002202021240200190E00158BA382004C40
-:020000040001F9
-:100000002403FFFF104300442404FFFF97820042B3
-:100010008F8700448F88003C00471023110000396F
-:10002000A78200428F8600283045FFFF8F84005052
-:1000300090C300BC3C0208008C4231A0000318822F
-:100040003070000100822021001010800102102178
-:1000500000A2282B10A00010248200888F84003476
-:100060001082000D3C033F018E420000004310242B
-:100070003C0325001443000630E500FF8C8200009D
-:10008000ACC200888C8200100A001665ACC20098D1
-:100090000E001489000030218F85003C93830024DA
-:1000A0008F86002830A20003000210233042000394
-:1000B00000433821A387002494C400E400A228212F
-:1000C0008F8300448F82004834841000A4C400E46D
-:1000D00000431021AF8200481200000EAF8500449B
-:1000E00024E20004A382002494C200E424A30004B8
-:1000F000AF83004434422000A4C200E40A00168505
-:10010000000020218F820048AF800044004710216A
-:10011000AF820048000020218FBF001C8FB2001862
-:100120008FB100148FB000100080102103E0000890
-:1001300027BD00208F86002827BDFFE8AFBF001431
-:10014000AFB0001090C200633042002010400008A1
-:1001500030A500FF8CC2007C2403FFDF2442000195
-:10016000ACC2007C90C2006300431024A0C20063B4
-:1001700010A000238F83002827500180020028212F
-:100180000E001568240600828F82002890420063CA
-:100190003042004050400019A380004C8F8300344F
-:1001A0008F4201B80440FFFE8F820050AE02000073
-:1001B00024026082A602000824020002A202000BB0
-:1001C0008C620008AE0200108C62000CAE020014BB
-:1001D0008C620014AE0200188C620018AE0200247B
-:1001E0008C620024AE0200288C620028AE02002C33
-:1001F0003C021000AF4201B8A380004C8F8300285E
-:100200008FBF00148FB000109062006327BD0018EC
-:100210003042007FA0620063978200428F860044D4
-:100220008F8500289383003000461023A782004268
-:10023000A4A000E490A400638F820048AF83004430
-:100240002403FFBF0046102100832024AF82004812
-:10025000A0A400638F820028A04000BD8F820028E8
-:1002600003E00008A44000BE8F8A002827BDFFE0FD
-:10027000AFB10014AFB000108F880044AFBF0018BA
-:1002800093890024954200E430D100FF0109182B26
-:100290000080802130AC00FF3047FFFF0000582174
-:1002A00014600003310600FF0120302101095823AA
-:1002B000978300420068102B1440003200000000B9
-:1002C00014680007240200018E0200202403FFFBB3
-:1002D00034E7800000431024AE0200202402000115
-:1002E00034E70880158200053165FFFF0E0014D940
-:1002F000020020210A00171A020020210E00150A10
-:10030000020020210E00154D8F8400508F8400289C
-:100310009482006024420001A48200609482006004
-:100320003C0308008C63318830427FFF5443000F48
-:1003300002002021948200602403800000431024E6
-:10034000A48200609082006090830060304200FFD1
-:10035000000211C200021027000211C03063007FAA
-:1003600000621825A08300600200202102202821BD
-:100370008FBF00188FB100148FB000100A00168CC8
-:1003800027BD0020914200632403FF800043102515
-:10039000A1420063978200423048FFFF1100002015
-:1003A000938300248F840028004B1023304600FFE5
-:1003B000948300E42402EFFF0168282B00621824D4
-:1003C000A48300E414A000038E0200200100582141
-:1003D000000030212403FFFB34E780000043102499
-:1003E000AE02002024020001158200053165FFFFE6
-:1003F0000E0014D9020020210A0017429783004200
-:100400000E00150A02002021978300428F820044CB
-:10041000A780004200431023AF820044938300244E
-:100420008F8200288FBF00188FB100148FB000108A
-:1004300027BD002003E00008A04300BD8F820028F4
-:1004400090430088904500BD244900883063003FF8
-:100450002463FFE024020001006238042C630020C2
-:1004600030E80019A385002410600010AF89003423
-:100470003C028000344200022405000124060001F1
-:100480001500000800E2182400002821146000056F
-:1004900030E20020104000052405000191260001F3
-:1004A00030C600010A0016D90000000003E0000871
-:1004B0000000000027BDFFD8AFB000108F900034BF
-:1004C000AFB40020AFB10014AFBF0024AFB3001C25
-:1004D000AFB200188E0500103C0208008C4231B00B
-:1004E0008F86003830A33FFF0062182B8CD3001496
-:1004F000008088218CD20020106000780000A021AC
-:1005000090C3000D2402FF8000431024304200FFFE
-:100510005040007302202021000513823042000366
-:100520005440006F0220202194C3001C8F820028B9
-:100530008E050028A44301148CC200100262182307
-:10054000146500072402001F8F82003C0062102106
-:100550000262102B104000088F83002C2402001828
-:100560000E00158BA382004C2403FFFF1043006F85
-:100570002404FFFF8F83002C8F84003C8C620010CA
-:100580000244902100441023AC6200108F820028A6
-:10059000AC7200208C4200680052102B1040000901
-:1005A0008F830038022020212402001D0E00158BAD
-:1005B000A382004C2403FFFF1043005C2404FFFFD0
-:1005C0008F8300388E0200248C63002410430007C0
-:1005D000022020212402001C0E00158BA382004C57
-:1005E0002403FFFF104300512404FFFF8F84002CDD
-:1005F0008C82002424420001AC82002412530004A7
-:100600008F8200288C4200685642000E8E02000045
-:100610008E0200003C030080004310241440000DB3
-:100620002402001A022020210E00158BA382004C08
-:100630002403FFFF1043003D2404FFFF0A0017D6E8
-:100640008E0200143C03008000431024504000033D
-:100650008E020014AC8000208E0200142412FFFFD2
-:10066000105200062402001B022020210E00158BD0
-:10067000A382004C1052002D2404FFFF8E030000C3
-:100680003C020001006210241040001F3C02008068
-:100690000062102414400008022020212402001AC5
-:1006A0000E00158BA382004C2403FFFF1043001F94
-:1006B0002404FFFF02202021020028210E0015AB98
-:1006C000240600012403FFFF2404FFFF1443000E4F
-:1006D000241400010A00180B8FBF002402202021DF
-:1006E0002402000D8FBF00248FB400208FB3001CA4
-:1006F0008FB200188FB100148FB0001027BD0028F2
-:100700000A00158BA382004C8F83002C022020212D
-:100710000280302194620036240500012442000149
-:100720000E0016D9A4620036000020218FBF0024DD
-:100730008FB400208FB3001C8FB200188FB100144B
-:100740008FB000100080102103E0000827BD0028B2
-:100750008F83002827BDFFD8AFB40020AFB3001CA3
-:10076000AFB20018AFB10014AFB00010AFBF00249B
-:10077000906200638F9100342412FFFF34420040E6
-:1007800092250000A06200638E2200100080982154
-:1007900030B0003F105200060360A0212402000D7B
-:1007A0000E00158BA382004C105200522404FFFF50
-:1007B0008F8300288E2200188C63007C1043000772
-:1007C000026020212402000E0E00158BA382004C33
-:1007D0002403FFFF104300472404FFFF24040020EC
-:1007E000120400048F8300289062006334420020CA
-:1007F000A06200638F85003C10A0001E0000000076
-:10080000560400048F820028026020210A00185537
-:100810002402000A9683000A2404FFFD944200602B
-:100820003042FFFF104300348FBF00243C02080019
-:100830008C42318C0045102B1440000602602021B0
-:10084000000028210E0016D9240600010A00187C99
-:10085000000020212402002D0E00158BA382004CE5
-:100860002403FFFF104300232404FFFF0A00187C29
-:1008700000002021160400058F8400288E23001418
-:100880002402FFFF50620018026020219482006061
-:1008900024420001A4820060948200603C030800AE
-:1008A0008C63318830427FFF5443000F0260202167
-:1008B000948200602403800000431024A48200601E
-:1008C0009082006090830060304200FF000211C2FD
-:1008D00000021027000211C03063007F006218255B
-:1008E000A0830060026020210E00168C2405000108
-:1008F000000020218FBF00248FB400208FB3001C84
-:100900008FB200188FB100148FB00010008010213A
-:1009100003E0000827BD00288F83002827BDFFE8DB
-:10092000AFB00010AFBF0014906200638F87003437
-:1009300000808021344200408CE60010A0620063F9
-:100940003C0308008C6331B030C23FFF0043102BE2
-:100950001040004E8F8500382402FF8090A3000DC8
-:1009600000431024304200FF504000490200202183
-:10097000000613823048000324020002550200449E
-:100980000200202194A2001C8F850028240300234C
-:10099000A4A201148CE60000000616023042003FBB
-:1009A000104300103C0300838CE300188CA2007CF1
-:1009B000106200062402000E0E00158BA382004C6C
-:1009C0002403FFFF104300382404FFFF8F83002817
-:1009D0009062006334420020A06200630A0018C1E4
-:1009E0008F83002C00C31024144300078F83002C36
-:1009F00090A200623042000F34420020A0A20062A8
-:100A0000A38800408F83002C9062000D3042007F4D
-:100A1000A062000D8F83003C1060001802002021AE
-:100A20008F8400388C8200100043102B1040000986
-:100A300024020018020020210E00158BA382004C16
-:100A40002403FFFF104300182404FFFF0A0018E9E5
-:100A5000000020218C8200102405000102002021CA
-:100A6000004310238F83002C240600010E0016D9AA
-:100A7000AC6200100A0018E9000020210E00168C5C
-:100A8000240500010A0018E90000202102002021AD
-:100A90002402000D8FBF00148FB0001027BD001876
-:100AA0000A00158BA382004C8FBF00148FB000107A
-:100AB0000080102103E0000827BD001827BDFFD8E3
-:100AC000AFB000108F900034AFB3001CAFBF002058
-:100AD000AFB20018AFB100148E1200103C03080032
-:100AE0008C6331B032423FFF0043102B1040007C3A
-:100AF000008098218F8500382402FF8090A3000D8C
-:100B000000431024304200FF504000760260202154
-:100B10000012138230420003240300015443007189
-:100B20000260202190A2000D3042000854400003D2
-:100B30008F82003C0A00191924020024504000034F
-:100B40008E03000C0A001919240200278CA2002031
-:100B500014620005240200208E0300088CA20024E9
-:100B600010620008240200200E00158BA382004CA6
-:100B70002403FFFF1043006A2404FFFF0A00194406
-:100B80008F84002C8E0200142411FFFF14510003E7
-:100B90008F8700280A00193F240200258E030018C1
-:100BA0008CE2007C146200162402000E8E030024E6
-:100BB0008CA2002814620012240200218E06002854
-:100BC0008CA2002C14C2000E2402001F8E03002CE5
-:100BD0001060000B240200238CE200680043102BFD
-:100BE00014400007240200268CA20014006618217D
-:100BF0000043102B504000078F84002C2402002259
-:100C00000E00158BA382004C105100452404FFFFF9
-:100C10008F84002C2403FFF79082000D00431024E2
-:100C2000A082000D8F8600283C0308008C6331AC45
-:100C30008F82005094C400E08F85002C0043102167
-:100C400030847FFF00042040004410213043007FA7
-:100C5000034320213C03000E008320212403FF8056
-:100C600000431024AF42002CA49200008CA2002864
-:100C700024420001ACA200288CA2002C8E03002C80
-:100C800000431021ACA2002C8E02002CACA200303C
-:100C90008E020014ACA2003494A2003A2442000157
-:100CA000A4A2003A94C600E03C0208008C4231B095
-:100CB00024C4000130837FFF1462001300803021C0
-:100CC000240280000082302430C2FFFF000213C2E1
-:100CD000304200FF000210270A001981000233C0D1
-:100CE000026020212402000D8FBF00208FB3001C62
-:100CF0008FB200188FB100148FB0001027BD0028EC
-:100D00000A00158BA382004C8F82002802602021EC
-:100D1000240500010E00168CA44600E000002021EE
-:100D20008FBF00208FB3001C8FB200188FB100144A
-:100D30008FB000100080102103E0000827BD0028BC
-:100D400027BDFFE0AFB100148F910034AFB00010A9
-:100D5000AFBF00188E2600103C0308008C6331B032
-:100D600030C23FFF0043102B1040005E0080802106
-:100D70008F8500382402FF8090A3000D00431024CB
-:100D8000304200FF50400058020020218F82003C7A
-:100D900010400008000613828F8200289763000A23
-:100DA0002404FFFD944200603042FFFF10430055D1
-:100DB00000061382304200031440000E00000000C1
-:100DC00092220002104000058E230024506000157E
-:100DD000922300030A0019BA020020218CA20024E9
-:100DE0005062001092230003020020210A0019C261
-:100DF0002402000F90A2000D304200085440000968
-:100E00009223000302002021240200100E00158B03
-:100E1000A382004C2403FFFF1043003A2404FFFF89
-:100E200092230003240200025462000C9222000369
-:100E30008F82003C544000099222000302002021CE
-:100E40002402002C0E00158BA382004C2403FFFF0C
-:100E50001043002C2404FFFF9222000302202821CB
-:100E600002002021384600102CC600012C4200014F
-:100E70000E0015AB004630252411FFFF1051002154
-:100E80002404FFFF8F83003C106000120200202129
-:100E90003C0208008C42318C0043102B14400006A9
-:100EA00000000000000028210E0016D924060001D1
-:100EB0000A001A00000020212402002D0E00158BCC
-:100EC000A382004C1051000F2404FFFF0A001A00F7
-:100ED000000020210E00168C240500010A001A00D3
-:100EE00000002021020020212402000D8FBF0018E5
-:100EF0008FB100148FB0001027BD00200A00158BA1
-:100F0000A382004C8FBF00188FB100148FB0001067
-:100F10000080102103E0000827BD002093830040DB
-:100F200027BDFFE024020002AFB10014AFB00010F3
-:100F300000808821AFBF0018000080211062008C63
-:100F40002404FFFD978500428F83004430A2FFFFF9
-:100F50000043102B5440007D8F8400480E00144C39
-:100F6000000000003C020800244275940220202169
-:100F7000004028210E001612AF8200342409FFFF22
-:100F80001049007B2404FFFF3C0808008D0875A46D
-:100F90003C0208008C4231B03C0308009063759419
-:100FA00031043FFF0082102B1040001B3067003FD0
-:100FB0003C0208008C4231A88F830050000421803D
-:100FC00000621821006418213062007F034228214A
-:100FD0003C02000C00A228213C02008034420001A7
-:100FE0003066007800C230252402FF8000621024A1
-:100FF000AF42002830640007AF4208048F82002807
-:101000000344202124840940AF460814AF85002CF6
-:10101000AF840038AC4301189383004024020003DE
-:101020001462003B240200012402002610E2003D6D
-:1010300028E200271040001324020032240200227C
-:1010400010E2003828E200231040000824020024A7
-:101050002402002010E200242402002110E2001EDD
-:10106000022020210A001A7F2402000B10E2002D2A
-:101070002402002510E20010022020210A001A7F1D
-:101080002402000B10E2001A28E200331040000690
-:101090002402003F2402003110E2000B0220202134
-:1010A0000A001A7F2402000B10E200110220202106
-:1010B0000A001A7F2402000B0E00176C0220202168
-:1010C0000A001A9A004080210E0018EE022020210A
-:1010D0000A001A9A004080210E00198F0220202158
-:1010E0000A001A9A004080211509000E0000000035
-:1010F0000E001813022020210A001A9A00408021B5
-:101100000E00158BA382004C0A001A9A0040802121
-:1011100014620017020020212402002314E20005BB
-:101120002402000B0E001885022020210A001A9AC2
-:101130000040802102202021A382004C0E00158B4C
-:101140002410FFFF0A001A9B0200202130A500FF97
-:101150000E00148924060001978300428F82004408
-:10116000A780004200431023AF82004402002021E8
-:101170008FBF00188FB100148FB0001000801021B5
-:1011800003E0000827BD002027BDFFE0AFB1001439
-:10119000AFBF0018AFB000108F4601283C03080015
-:1011A0008C6331A02402FF80AF86005000C3182159
-:1011B0003065007F03452821006218243C02000AA4
-:1011C000AF43002400A2282190A200620080882161
-:1011D000AF850028304200FF00021102A3820040C8
-:1011E00090A200BC304200021440000224030034EC
-:1011F000240300308F820028A383003093830040B3
-:101200008C4200C0A380004CAF8200442402000442
-:10121000106200308F8400448E2400045080002D22
-:101220008F8400448E2200103083FFFFA784004289
-:101230001060001FAF8200488F8300282405FF80C4
-:10124000022020219062006300A21024304200FF9F
-:101250001440000D000000000E001A069790004296
-:1012600010400010004018212402FFFD54620011BC
-:101270008E230020020028210E00142A02202021A3
-:101280000A001AEC8E2300209062006300A2102452
-:10129000304200FF10400003022020210E00174EB4
-:1012A00000000000978200421440FFE48F83002872
-:1012B0008E23002030620004104000068F8400441A
-:1012C0002402FFFB006210240E00143EAE22002018
-:1012D0008F8400448F8300288FBF00188FB10014C3
-:1012E0008FB000102402000127BD002003E0000899
-:1012F000AC6400C030A500FF2403000124A9000154
-:101300000069102B1040000C00004021240A00014D
-:1013100000A31023004A3804246300013082000136
-:101320000069302B104000020004204201074025D4
-:1013300054C0FFF800A3102303E0000801001021AF
-:1013400027BDFFE03C021EDCAFB20018AFB10014B5
-:10135000AFBF001CAFB0001034526F4100008821B5
-:10136000240500080E001AFC0220202100118080B4
-:101370003C07080024E771940002160002071821B8
-:10138000AC6200000000282124A200013045FFFFCC
-:101390008C6200002CA600080441000200022040DC
-:1013A0000092202614C0FFF8AC64000002078021E0
-:1013B0008E0400000E001AFC2405002026230001E4
-:1013C0003071FFFF2E2301001460FFE5AE02000024
-:1013D0008FBF001C8FB200188FB100148FB00010A7
-:1013E00003E0000827BD00203C02080024426A8474
-:1013F0003C010800AC2271883C02080024425000E5
-:101400003C010800AC22718C240200063C0108005B
-:10141000A02271900A001B0F0000000027BDFFD81A
-:10142000AFB3001CAFB20018AFBF0020AFB10014C3
-:10143000AFB000108F5101408F480148000894025E
-:10144000324300FF311300FF8F4201B80440FFFE1A
-:1014500027500180AE1100008F420144AE0200040B
-:1014600024020002A6120008A202000B24020014AB
-:10147000AE130024106200252862001510400008F9
-:101480002402001524020010106200302402001211
-:10149000106200098FBF00200A001C308FB3001CAF
-:1014A0001062006724020022106200378FBF002004
-:1014B0000A001C308FB3001C3C0208008C4231A093
-:1014C0002403FF800222102100431024AF42002495
-:1014D0003C0208008C4231A0022210213042007FE1
-:1014E000034218213C02000A00621821166000B372
-:1014F000AF830028906200623042000F3442003017
-:10150000A06200620A001C2F8FBF00203C04600014
-:101510008C832C083C02F0033442FFFF0062182445
-:10152000AC832C083C0208008C4231A08C832C0830
-:101530002442007400021082000214800062182508
-:10154000AC832C080A001C2F8FBF00203C0208002F
-:101550008C4231A02403FF8002221021004310247A
-:10156000AF4200243C0208008C4231A03C03000A38
-:10157000022210213042007F03421021004310213B
-:101580000A001C2EAF8200283C0208008C4231A0C9
-:101590002404FF800222102100441024AF420024C2
-:1015A0003C0208008C4231A0022210213042007F10
-:1015B000034218213C02000A006218219062006375
-:1015C00000821024304200FF1040007CAF830028CE
-:1015D00024620088944300123C0208008C4231A827
-:1015E00030633FFF000319800222102100431021C5
-:1015F0003043007F03431821004410243C04000CB6
-:1016000000641821AF4200280E00155AAF83002C49
-:101610008F4201B80440FFFE00000000AE11000040
-:101620008F420144AE02000424020002A612000808
-:10163000A202000BAE1300240A001C2F8FBF002053
-:101640002406FF8002261024AF4200203C0208003E
-:101650008C4231A031043FFF00042180022210217E
-:1016600000461024AF4200243C0308008C6331A8DC
-:101670003C0208008C4231A03227007F022318214F
-:1016800002221021006418213042007F3064007F64
-:10169000034228213C02000A0066182400A22821E7
-:1016A000034420213C02000C00822021AF4300288B
-:1016B0003C0200080347182100629021AF850028F2
-:1016C000AF84002C0E00155A010080218F4201B812
-:1016D0000440FFFE8F82002C8F8400282745018064
-:1016E0009042000DACB10000A4B00006000216004C
-:1016F0000002160300021027000237C214C00016B1
-:10170000248200889442001232033FFF30423FFFA0
-:101710001443001224026082908300632402FF803D
-:1017200000431024304200FF5040000C240260822D
-:10173000908200623042000F34420040A08200627A
-:1017400024026084A4A200082402000DA0A20005C7
-:101750000A001C193C02270024026082A4A200088F
-:10176000A0A000053C02270000061C00006218250E
-:1017700024020002A0A2000BACA30010ACA0001435
-:10178000ACA00024ACA00028ACA0002C8E42004CE1
-:101790008F84002CACA200189083000D2402FF80DF
-:1017A00000431024304200FF104000058FBF00208E
-:1017B0009082000D3042007FA082000D8FBF00207C
-:1017C0008FB3001C8FB200188FB100148FB00010BF
-:1017D0003C02100027BD002803E00008AF4201B81A
-:1017E00008004C2808004C2808004BA008004BD8E3
-:1017F00008004C0C08004C3008004C3008004C30FD
-:0418000008004B1081
-:0C1804000A0001220000000000000000AB
-:101810000000000D747061342E362E313600000049
-:10182000040610010000000000000000000000009D
-:1018300000000000000000000000000000000000A8
-:101840000000000000000000000000000000000098
-:101850000000000000000000000000000000000088
-:101860000000000000000000000000000000000078
-:101870000000000000000000000000000000000068
-:101880000000000000000000000000000000000058
-:1018900010000003000000000000000D0000000D1B
-:1018A0003C02080024421B803C03080024632014EF
-:1018B000AC4000000043202B1480FFFD24420004B4
-:1018C0003C1D080037BD2FFC03A0F0213C10080090
-:1018D000261004883C1C0800279C1B800E00015A1F
-:1018E000000000000000000D3084FFFF3082000780
-:1018F0008F85001810400002248300073064FFF831
-:101900000085302130C41FFF03441821247B400090
-:10191000AF85001CAF84001803E00008AF440084CA
-:101920003084FFFF308200078F8500208F860028DB
-:1019300010400002248300073064FFF80085202156
-:101940000086182B14600002AF8500240086202337
-:101950000344282134068000AF840020AF44008077
-:1019600000A6202103E00008AF84003827BDFFD87F
-:10197000AFB3001CAFB20018AFB00010AFBF00246F
-:10198000AFB40020AFB100143C0860088D145000C3
-:101990002418FF7F3C1A8000029898243672380C75
-:1019A000AD1250008F5100083C07601C3C086000DD
-:1019B00036300001AF500008AF800018AF40008003
-:1019C000AF4000848CE600088D0F08083C076016C5
-:1019D0008CEC000031EEFFF039CA00103C0DFFFF27
-:1019E000340B80003C030080034B48212D44000150
-:1019F000018D28243C0253533C010800AC230420F1
-:101A0000AF890038AF860028AF840010275B400004
-:101A100014A2000334E37C008CF90004032818218D
-:101A20008C7F007C8C6500783C0280003452007012
-:101A3000AF85003CAF9F00403C13080026731BC4D9
-:101A40000240A0218E4800008F46000038C30001EC
-:101A50003064000110800017AF88003402804821F4
-:101A60008D2D00003C1908008F39045C3C110800E2
-:101A70008E31045801A8F823033F7821000040214B
-:101A80000228382101FF802B00F070213C01080062
-:101A9000AC2F045C3C010800AC2E04588F4C0000B5
-:101AA000398B0001316A00011540FFED01A0402192
-:101AB000AF8D00348E4E00003C0C08008D8C045C11
-:101AC0003C0A08008D4A045801C86823018D28216A
-:101AD0000000582100AD302B014B20210086102141
-:101AE0003C010800AC25045C3C010800AC22045811
-:101AF0008F4501088F44010030A92000AF85000008
-:101B0000AF84000C1120000A00A030213C0708001F
-:101B10008CE7042C24EF00013C010800AC2F042CBE
-:101B20003C104000AF5001380A0001900000000056
-:101B300030B002001600001424110F0010910012A2
-:101B400024070D001087023330B000065200FFF565
-:101B50003C104000936D0000240C001031A600F0F2
-:101B600010CC0269240E007010CE02DD8F8B0014A1
-:101B700025670001AF8700143C104000AF500138CA
-:101B80000A00019000000000974801041100FFE5E1
-:101B90003C10400030B84000170000A200000000D8
-:101BA0008F5901780720FFFE8F870038240900082D
-:101BB000240508008CE30008AF450178A7490140DF
-:101BC000A7400142974201048F8600003049FFFF81
-:101BD00030DF000113E002D5012040212524FFFE63
-:101BE000240A0002A74A01463088FFFFA7440148A3
-:101BF0003C0B08008D6B043C156002C48F8F000CF9
-:101C000030C30020146000022404000924040001F1
-:101C100030CD0C00240C040051AC000134840004CD
-:101C2000A744014A3C0508008CA504203C0200485A
-:101C30003C19000100A2F82530D8000203F928253C
-:101C400013000004000018213C04010000A4282512
-:101C50002403000130CA000451400005AF8300088E
-:101C60003C06001000A6282524030001AF830008CD
-:101C7000AF45100000000000000000000000000060
-:101C8000000000008F8300081060002300000000A7
-:101C90008F4B10000561FFFE000000001060001E69
-:101CA000000000008F4D10003C03002001A36024C1
-:101CB000118000198F8F000031EE000211C0001654
-:101CC00000000000975010141600001300000000E0
-:101CD0009745100830BFFFFF27F800060018C8829C
-:101CE0000019308000C7282133110001330300039D
-:101CF000122003208CA200000000000D00C7F82174
-:101D0000AFE200003C1908008F390430272600019B
-:101D10003C010800AC2604308F6A00003405FFFF48
-:101D2000AF8A00048CE200001045029A00002021D6
-:101D30008CE5000030BF010013E0027E010020218D
-:101D40003C0708008CE704743C1008008E10044C1B
-:101D500000E858213C1808008F1804700168882B8F
-:101D60003C0808008D080448000078210204602126
-:101D7000030F18210184702B010F6821007150217D
-:101D800001AE10213C010800AC2C044C3C010800C1
-:101D9000AC2204483C010800AC2B04743C01080050
-:101DA000AC2A04708F8D00180120302131290007E2
-:101DB00025AE000831C21FFF03426021AF8D001C19
-:101DC000AF820018259B4000AF4200841120000321
-:101DD0008F90002024C800073106FFF88F84002868
-:101DE00000D0282100A4782B15E00002AF90002439
-:101DF00000A4282303452021340380000083102100
-:101E00003C061000AF850020AF820038AF4500804F
-:101E1000AF4601788F8B0014256700010A0001DDB1
-:101E2000AF8700148F6200088F6700002411003014
-:101E30000007C602330300F0107100A2241900400D
-:101E40001479FF4B8F8B00148F4A01780540FFFEF9
-:101E500030A7020014E00003000512820000000D0C
-:101E6000000512823050000300104900013070213B
-:101E7000000E688001B06021000C58800173802141
-:101E80008E08000015000002000000000000000D98
-:101E90008F6F000405E202B192030006920700056D
-:101EA000920F00043C0200010007288000B060216E
-:101EB0008D8900182771000825EE00050122682190
-:101EC000000E3082AD8D0018022020210E0005800A
-:101ED00026050014920B00068F7F00043C087FFF4C
-:101EE000000B2080009130218CC30004350AFFFFD5
-:101EF00003EAC8240079C021ACD800049207000589
-:101F000092090004960D00080007288000B1F8210E
-:101F10008FEF0000974201043C07FFFF01E75024C8
-:101F2000304EFFFF01C96021018D58233168FFFF4A
-:101F300001482025AFE400009203000724190001A6
-:101F4000107902692406000310660279000000007F
-:101F50008E190010241F000AA75F0140A7590142F3
-:101F6000920300048F86000024070001A743014468
-:101F7000A74001469758010430D100023C050041BA
-:101F8000A758014800001821A747014A1220000362
-:101F900030CA00043C050141240300015140000502
-:101FA000AF8300083C08001000A828252403000186
-:101FB000AF830008AF4510000000000000000000E3
-:101FC00000000000000000008F8B0008116000047A
-:101FD000000000008F4410000481FFFE000000009C
-:101FE0008F6A0000920700043C0508008CA5044499
-:101FF000AF8A0004975F01043C0F08008DEF044096
-:1020000030E300FF33F9FFFF0079C02100B86821F9
-:102010000000102124E6000A30C8FFFF01B8482B59
-:1020200001E2702101C96021311000073C01080064
-:10203000AC2D04443C010800AC2C04401200000309
-:102040008F8D0018250B00073168FFF8010D7021F6
-:1020500031CC1FFFAF8D001CAF8C0018AF4C00843B
-:1020600097440104034C80213084FFFF308800072F
-:1020700011000003261B4000248900073124FFF8CB
-:102080008F8200208F850028008220210085782BF8
-:1020900015E00002AF82002400852023034488213C
-:1020A00034058000022510213C061000AF8400207A
-:1020B000AF820038AF440080AF4601780A00028545
-:1020C0008F8B00148F5F017807E0FFFE30AA0200BB
-:1020D00015400003000542820000000D0005428209
-:1020E000310200030002710001C26821000D60800E
-:1020F000018248210009288000B380218E0B000056
-:1021000011600002000000000000000D8F6F000C45
-:1021100005E001F38F87003824190001AE19000093
-:102120008CE30008A20000078F78000400181C024E
-:10213000306600FF24D10005001130832CC400411B
-:1021400014800002A20300040000000D8F6B000445
-:102150003C0EFFFF00E028213164FFFF248F000BBD
-:10216000000F408200081080004748218D2D00009C
-:1021700026040014A60B000801AE60240E000580A2
-:10218000AD2C00008F5F01083C0A100003EA3824E0
-:1021900010E001A30000000097460104920300072D
-:1021A00024D1FFEC346500023224FFFFA2050007B2
-:1021B000960600082CC7001354E0000592030007A0
-:1021C000920A0007355F0001A21F00079203000773
-:1021D000240B0001106B01BA24090003106901CD22
-:1021E0008F88003830CFFFFF25E400020004C88349
-:1021F000333F00FF001F2880A219000500A85821C6
-:102200008D780000975101043C03FFFF0303602415
-:102210003222FFFF004F702325CDFFFE018D4825A0
-:10222000AD690000920600053C02FFF6344EFFFF48
-:1022300030CA00FF000A388000F020219099001475
-:102240003C1FFF7F37E7FFFF3323000F0066782135
-:1022500031F800FF0018288000B088218E2D002062
-:1022600000A86021A20F000601AE4824AE0D000CAC
-:10227000AD89000C920B00068E04000C0127F82497
-:10228000000B50800150C821972600260148C0212C
-:1022900000874024AF260024AE08000CAF3F00208A
-:1022A000AF0600108F860000240C001024090002E5
-:1022B000A74C0140A7400142A7400144A74901465D
-:1022C000974B01042407000130C80002256AFFFE75
-:1022D000A74A01483C050009A747014A110000032D
-:1022E000000018213C0501092403000130CD000441
-:1022F00051A00005AF8300083C06001000A6282569
-:1023000024030001AF830008AF4510000000000067
-:10231000000000000000000000000000921800040F
-:1023200027110002322F0007000F1023304E000744
-:10233000AE0E00108F900008120000040000000094
-:102340008F4310000461FFFE000000008F78000042
-:102350008F8F00183C1008008E100444AF980004C2
-:102360009751010425E6001030CA1FFF3222FFFFFB
-:10237000AF8F001CAF8A0018AF4A00842449FFFECB
-:102380003C0B08008D6B0440974E0104012068212E
-:10239000000967C3020D282131C9FFFF00AD402BA2
-:1023A000016C382100E82021034AF8213139000767
-:1023B0003C010800AC2504443C010800AC24044066
-:1023C0001320000327FB4000252300073069FFF896
-:1023D0008F9F00208F840028013F382100E4C82B04
-:1023E00017200002AF9F002400E438230347202178
-:1023F00034058000008510213C061000AF870020C6
-:10240000AF820038AF470080AF4601780A000285EE
-:102410008F8B0014975801041300FDC23C1040003C
-:102420008F4301780460FFFE30B9400013200003A1
-:102430003C0400080000000D3C040008AF440140CB
-:1024400024080800AF4801788F8B0000974A0104E8
-:10245000317F000113E000E93146FFFF24D0FFFE89
-:10246000240C0002A74C0146A75001488F8F00188A
-:102470002405000DA745014A8F71000025E20008E0
-:1024800030491FFF0349702130CD0007AF91000490
-:10249000AF8F001CAF89001800C03821AF490084FD
-:1024A00011A0000325DB400024C6000730C7FFF859
-:1024B0008F9800208F84002800F8302100C4382B2A
-:1024C00014E00002AF98002400C430238F8A001467
-:1024D00003465821340880000168F821255900017D
-:1024E0003C0310003C104000AF860020AF9F003836
-:1024F000AF460080AF430178AF990014AF50013868
-:102500000A000190000000008F6900009744010458
-:102510003127FFFF3088FFFF8F4F017805E0FFFE76
-:1025200030FF0007001F18233078000724E6FFFE65
-:102530002419000AA7590140A7580142A74601449F
-:10254000A7400146A74801488F42010830510020AA
-:1025500016200002240300092403000130AA00020F
-:10256000A743014A3C040041114000030000182128
-:102570003C0401412403000130AB0004516000051C
-:10258000AF8300083C0500100085202524030001CE
-:10259000AF830008AF4410000000000000000000FE
-:1025A00000000000000000008F90000812000004EE
-:1025B000000000008F4C10000581FFFE00000000AD
-:1025C0008F780000276200088F8D003CAF980004D0
-:1025D000944600089451000A944F000C30CEFFFF3F
-:1025E0000011240031E9FFFF11CD00A20089202550
-:1025F0003C0308008C6304443C1808008F18044016
-:1026000000E85021255FFFFE007F782100001021A7
-:1026100001FF302B03028821022648213C010800DB
-:10262000AC2F04443C010800AC29044024EB000812
-:102630003162FFFF3047000710E000038F8500186C
-:10264000245000073202FFF83106FFFF30C80007B0
-:102650000045702131CD1FFF034D6021AF85001C67
-:10266000AF8D0018259B4000AF4D00841100000382
-:102670008F8F002024C400073086FFF88F84002845
-:1026800000CF282100A4482B15200002AF8F002482
-:1026900000A42823AF850020AF4500803C1108002E
-:1026A0008E3104340345C0213402800003023021FE
-:1026B00012200005AF860038938300172419000EFE
-:1026C0001079000D241F043F3C0A1000AF4A017826
-:1026D0008F8B0014256700010A0001DDAF8700140D
-:1026E0000E0005A63C1040008F8B001425670001EA
-:1026F0000A0001DEAF8700143C0A1000A75F014802
-:10270000AF4A01780A0004B48F8B0014240E0F0026
-:1027100011EE003D30D100201620000224030009F4
-:10272000240300010A000208A743014A0A0001FB32
-:10273000A740014694E5000894E2000A94EB000CDF
-:102740008F86003C0002FC00316AFFFF30B9FFFFBA
-:102750001326003703EA20253C0508008CA5044415
-:102760003C1F08008FFF04400000502100A83821C2
-:1027700000E8302B03EAC8210326C0213C010800F1
-:10278000AC2704443C010800AC3804400A0002694C
-:102790008F8D00183C1908008F39047C3C03080019
-:1027A0008C6304543C0608008CC604783C0F080077
-:1027B0008DEF0450032838210068682100E8C02B01
-:1027C00000C4882101A8402B01E47021023858215F
-:1027D00001C860213C010800AC2D04543C010800F4
-:1027E000AC2C04503C010800AC27047C3C010800E0
-:1027F000AC2B04780A0002698F8D0018A7400146AF
-:102800000A00041B8F8F001830D000201600FFC56F
-:102810002403000D240300050A000208A743014A0F
-:10282000975901042738FFF00A00036B3304FFFFB8
-:102830008F8C0040148CFFC8000080213C110800E0
-:102840008E31046C3C0408008C84046802287021DA
-:1028500001C8782B00904021010F68213C0108003D
-:10286000AC2E046C3C010800AC2D04680A0002691F
-:102870008F8D00188F9900401499FF5D0000602132
-:102880003C0508008CA5046C3C1008008E10046800
-:1028900000E82021248EFFFE00AEF82103EE582B25
-:1028A000020C5021014B18213C010800AC3F046C84
-:1028B0003C010800AC2304680A00048B24EB0008E8
-:1028C0008F8800383C02FFFF8D0E000C01C2682487
-:1028D00001A46025AD0C000C0A00037930CFFFFF86
-:1028E0000A0003A9AE000000974B01049204000403
-:1028F0008E2A000C01644021251FFFF20147182495
-:1029000033F9FFFF0079C025AE38000C0A0002D46D
-:102910008E1900103C03FFFF8D11001002232824A4
-:1029200000A47825AD0F00100A00037930CFFFFF17
-:1029300097450104920600048E2F001000A6102176
-:102940002449FFEE01E76824312EFFFF01AE602528
-:10295000AE2C00100A0002D48E1900108E06000C56
-:10296000AE0000000003C080031088210A0002A608
-:10297000AE2600201460000D3050FFFF3C04FFFF26
-:102980000044602401846826000D582B000C502B55
-:10299000014B102410400002000000000000000D58
-:1029A0008CA300000A00023E006410253A11FFFFCC
-:1029B0000011782B0010702B01CF20241080000212
-:1029C000000000000000000D8CB800000A00023E6C
-:1029D0003702FFFF3084FFFF30A5FFFF10800007A4
-:1029E0000000182130820001104000020004204243
-:1029F000006518211480FFFB0005284003E0000853
-:102A00000060102110C00007000000008CA2000030
-:102A100024C6FFFF24A50004AC82000014C0FFFB05
-:102A20002484000403E000080000000010A0000857
-:102A300024A3FFFFAC86000000000000000000009F
-:102A40002402FFFF2463FFFF1462FFFA24840004C2
-:102A500003E0000800000000308EFFFF30D8FFFFC9
-:102A600000057C0001F8602539CDFFFF01AC502145
-:102A7000014C582B014B4821000944023127FFFF2C
-:102A800000E830210006240230C5FFFF00A4182111
-:102A90003862FFFF03E000083042FFFF3C0C0800F3
-:102AA0008D8C0484240BFF8027BDFFD0018450212E
-:102AB000014B4824AF4900203C0808008D080484DD
-:102AC000AFB20020AFB00018AFBF0028AFB30024F2
-:102AD000AFB1001C936600040104382130E4007F8C
-:102AE000009A10213C0300080043902130C50020CB
-:102AF000036080213C080111277B000814A000021C
-:102B0000264600702646006C92130004975101047B
-:102B1000920F00043267000F322EFFFF31ED0040AC
-:102B200001C7282311A0000500004821925900BCCC
-:102B3000333800041700009000000000924300BCEE
-:102B4000307F000413E0000F0000000010A0000D13
-:102B500000000000960E0002240AFF8000A76021FA
-:102B600025CDFFFEA74D1016920B0004014B20242B
-:102B7000308200FF10400085010C40253C0F04000E
-:102B8000010F40258F5301780660FFFE2404000AE0
-:102B9000A7440140960D00022404000931AC00074F
-:102BA000000C5823316A0007A74A0142960200022E
-:102BB0002443FFFEA7430144A7400146975F010459
-:102BC000A75F01488F5901083338002053000001E6
-:102BD00024040001920F000431EE001015C0000221
-:102BE0003483001000801821A743014A0000000030
-:102BF000000000000000000000000000AF481000CE
-:102C000000000000000000000000000000000000C4
-:102C10008F5110000621FFFE3113FFFF12600003E9
-:102C2000000000008F481018ACC800009603000692
-:102C3000307FFFFF27F90002001998820013888077
-:102C4000023B30218CD800001520005700183402B8
-:102C5000920300042405FF8000A3F82433F100FF51
-:102C60001220002C00000000924700BC30F200024D
-:102C70001240002800000000974B100C2562FFFE58
-:102C8000A7421016000000003C0A0400354900303D
-:102C9000AF4910000000000000000000000000002C
-:102CA000000000008F4C10000581FFFE00000000B6
-:102CB0009749100C8F51101C00C020213127FFFFB5
-:102CC00024F20030001218820003288000BBF82193
-:102CD0003226FFFFAFF100000E00059500112C0217
-:102CE0000013C880033B98218E7800000002740016
-:102CF000AFB800108FA80010310FFFFFAFAF00106A
-:102D00008FA4001001C46825AFAD00108FA600107D
-:102D1000AE66000097730008976D000A9766000C76
-:102D20008F8A003C000D5C0030CCFFFF3262FFFF59
-:102D3000104A0036016C2025960600023C10100057
-:102D400024D300080E0001393264FFFF974C0104C0
-:102D50000E0001473184FFFFAF5001788FBF00287C
-:102D60008FB300248FB200208FB1001C8FB00018E9
-:102D700003E0000827BD003010A0FF700000000035
-:102D800024A5FFFC0A0005CE240900048CD1000014
-:102D9000AF5110188F5301780660FF7A2404000A9F
-:102DA0000A0005E30000000000A7C8218F88003852
-:102DB0008F4E101C0019C0820018788001E8202175
-:102DC000AC8E0000000E2C0200C020210E000595E4
-:102DD00031C6FFFF023B28218CAD000000025400E9
-:102DE00000403021AFAD00108FAC0010318BFFFFE1
-:102DF000AFAB00108FA2001001424825AFA9001010
-:102E00008FA700100A000613ACA700008F8F0040A8
-:102E1000148FFFC90000000097420104960B0002C6
-:102E20003C0508008CA5046C3049FFFF316AFFFFA8
-:102E30003C1108008E310468012A382124F2FFFE7B
-:102E400000B240210012FFC30112C82B023FC02173
-:102E5000031920213C010800AC28046C3C01080047
-:102E6000AC2404680A00064D0000000000A4102BEA
-:102E700010400009240300010005284000A4102B85
-:102E800004A00003000318405440FFFC0005284044
-:102E900010600007000000000085302B14C0000205
-:102EA00000031842008520231460FFFB0005284220
-:102EB00003E00008008010218F85002C27BDFFE86B
-:102EC000000530272CC300012CA40002008310252C
-:102ED00010400003AFBF00102405007FAF85002C19
-:102EE0000005282730A5FFFF0E000574240426F5F1
-:102EF0008F830030240402BD004030210083382B32
-:102F000010E0000924050001000420400083102B7C
-:102F100004800003000528405440FFFC00042040CA
-:102F200010A0000800C350210064402B15000002CF
-:102F3000000528420064182314A0FFFB000420426F
-:102F400000C350218FBF0010000A4C02312200FF45
-:102F500027BD0018AF8A002C03E00008AF890030BD
-:102F60000A00002600000000000000000000000D24
-:102F7000747870342E362E313600000004061000AE
-:102F80000000000A000001360000EA6000000000B6
-:102F90000000000000000000000000000000000031
-:102FA0000000000000000000000000000000000021
-:102FB0000000000000000000000000000000000011
-:102FC0000000001D000000000000000000000000E4
-:102FD00000000000000000000000000000000000F1
-:102FE00000000000000000000000000000000000E1
-:102FF00000000000000000000000000010000003BE
-:10300000000000000000000D0000000D3C02080060
-:1030100024423AA03C03080024633C54AC40000026
-:103020000043202B1480FFFD244200043C1D0800B7
-:1030300037BD7FFC03A0F0213C100800261000984B
-:103040003C1C0800279C3AA00E000305000000006D
-:103050000000000D8F8300383C08800035070070A9
-:103060008CE50000008330253C02900000C2202542
-:10307000AF850030AF4400208F4900200520FFFEBF
-:103080003C038000346200708C4500008F86003065
-:103090003C1908008F39007C3C0E08008DCE00786A
-:1030A00000A6202303245821000078210164682B06
-:1030B00001CF6021018D50213C010800AC2B007C28
-:1030C0003C010800AC2A007803E000080000000082
-:1030D0000A00003D240400018F8400383C05800074
-:1030E00034A200010082182503E00008AF4300204D
-:1030F00003E00008000010213084FFFF30A5FFFF2F
-:1031000010800007000018213082000110400002EA
-:1031100000042042006518211480FFFB00052840B0
-:1031200003E000080060102110C00007000000004C
-:103130008CA2000024C6FFFF24A50004AC8200007E
-:1031400014C0FFFB2484000403E00008000000001A
-:1031500010A0000824A3FFFFAC86000000000000C0
-:10316000000000002402FFFF2463FFFF1462FFFA47
-:103170002484000403E0000800000000308AFFFF00
-:1031800093A80013A74A014497490E1630C600FFC2
-:103190003C021000A7490146AF450148A346015231
-:1031A000A748015AAF4701608FA400188FA30014ED
-:1031B000A7440158AF43015403E00008AF4201782F
-:1031C00003E00008000000003C038000346200704F
-:1031D0008C4900008F88003C2484000727BDFFF83D
-:1031E0003084FFF8AF890030974D008A31ACFFFF83
-:1031F000AFAC00008FAB0000016850232547FFFFF4
-:1032000030E61FFF00C4282B14A0FFF73C0C800001
-:10321000358B00708D6A00003C0708008CE7008445
-:103220003C0608008CC60080000810820149182363
-:103230000002788000E370210000202101C3C82B28
-:1032400000C4C02101FA4021031948212502400091
-:1032500027BD00083C010800AC2E00843C0108009A
-:10326000AC29008003E00008000000008F82003CD1
-:103270002486000730C5FFF800A2182130641FFF24
-:1032800003E00008AF84003C3C0E20FF27BDFFE0B8
-:103290003C1A80003C0F800835CDFFFDAFBF001801
-:1032A000AFB10014AFB00010AF8F0044AF4D0E00AF
-:1032B000000000000000000000000000000000000E
-:1032C000000000003C0C00FF358BFFFDAF4B0E00F3
-:1032D0003C0660048CC95000240AFF7F3C1160004A
-:1032E000012A40243507380CACC750008E2404381E
-:1032F00024050009AF4500083083FFFF38622F71B5
-:103300002450C0B3AF80004C0E000064AF80003C7E
-:1033100052000001AE20442C0E00046000000000AA
-:103320008FBF00188FB100148FB000100A000E7705
-:1033300027BD002027BDFFD0AFB20028AFB10024C9
-:10334000AFBF002CAFB00020936200080080902136
-:1033500000A088211440002D240400100E00009AC3
-:10336000000000008F8E004C3C10320031C600FF80
-:1033700000067C0001F0602525CD0001AF8D004CDA
-:10338000AC4C0000936B00099369000A316A00FF9E
-:10339000000A3C00312800FF00E82025AC4400046E
-:1033A0008F83004C06400043AC430008AC40000C47
-:1033B000979800403305000814A000022628000654
-:1033C0002628000297420E148F450E1C8F670004BA
-:1033D000937F00023044FFFF33F900FFAFB90010C4
-:1033E0008F710014AFA800180E000087AFB1001451
-:1033F0008FBF002C8FB200288FB100248FB0002027
-:10340000240400100A0000C327BD0030936900099E
-:103410009368000B312300FF310200FF006280211E
-:10342000261F000A33F0FFFF0E00009A0200202141
-:103430008F86004C3C0D410024D90001AF99004C0F
-:103440009378000930C600FF00067400330500FFC2
-:1034500024AF000201CF6025018D5825AC4B000040
-:103460008F6A000C97440E1401523825AC470004B3
-:103470008F450E1C8F670004936900023084FFFFA4
-:10348000312800FFAFA800108F630014AFB10018FF
-:103490000E000087AFA30014020020218FBF002C74
-:1034A0008FB200288FB100248FB000200A0000C323
-:1034B00027BD00303C1280000A000114AC52000C01
-:1034C00027BDFFD8AFB3001CAFBF0020AFB20018BC
-:1034D000AFB10014AFB00010936200081440008137
-:1034E00000809821AF60000C9785004030A4400018
-:1034F0001080008B2403001624104007A363000AE9
-:10350000AF700014938F00428F6C001431EE0007EF
-:10351000000E6A40018D5825AF6B0014978A004059
-:103520008F6800143149001001093825AF67001475
-:103530009786004030C300085060008D00002821AD
-:103540008F6600143C0310003C02810000C3282554
-:10355000AF65001497440E0A2418000E3405FFFCD2
-:10356000309FFFFF03E2C825AF790004A378000273
-:103570009372000A26510004A371000A9783004049
-:103580009364000A30661F00000611830044F8218E
-:1035900027F90028A379000997580E0CA778001086
-:1035A0009372000926510002323000070010782380
-:1035B00031EE0007A36E000B936D0009976C0010AD
-:1035C0008F9000349789004031AB00FF016C50218F
-:1035D000014540213127004010E000053105FFFF83
-:1035E00000B0382B3C06800010E000140000882159
-:1035F0000205402B15000033000020218F4A0E14D5
-:10360000AF4A0E108F490E1CAF490E18AF450E0081
-:103610008F4C0000318B00081160FFFD000000009E
-:10362000974D0E0800A0802100003021A78D00409A
-:103630008F450E0424110001AF850034976E0010F1
-:1036400031D2FFFF8E640000009010231440000967
-:10365000AE6200008F6A00148F8700483549004031
-:10366000AF6900148F480E10ACE800208F430E188D
-:10367000ACE3002400C020210E0000F50200282148
-:103680008E66000014C00005000000008F6B00145F
-:10369000240CFFBF016C9824AF7300148F6D000CD5
-:1036A00001B22821AF65000C937200081640000398
-:1036B000000000001620003100000000A371000887
-:1036C000020020218FBF00208FB3001C8FB2001892
-:1036D0008FB100148FB000100080102103E00008AB
-:1036E00027BD00288F900034979100403C06800051
-:1036F00002009021322F004015E0FFD20000882107
-:10370000977F00108F98003433F9FFFF1738FFEDD3
-:1037100000002021000030210A0001B9241100011D
-:103720002403000E24104007A363000AAF700014A6
-:10373000938F00428F6C001431EE0007000E6A4038
-:10374000018D5825AF6B0014978A00408F680014D4
-:103750003149001001093825AF67001497860040F1
-:1037600030C300081460FF7600000000000028212C
-:10377000AF6000040A000187A36000028F6F00148D
-:103780003C19EFFF3738FFFE01F870240A0001D71B
-:10379000AF6E00148F8700388F8A004427BDFFE08A
-:1037A0008F860048AFB00018AFBF001C8F450104E2
-:1037B0008D4900ACAF4700808CC8002000A9382399
-:1037C00000008021AF480E108F440E1000004821E9
-:1037D000AF440E148CC20024AF420E188F430E1853
-:1037E000AF430E1C10E000362D390001936B00082A
-:1037F0001160004F00000000976E001031CDFFFFF8
-:1038000000ED602B1580004A000000009778001042
-:10381000330FFFFFAF4F0E008F5F000033F900083A
-:103820001320FFFD0000000097420E088F460E0493
-:103830003045FFFF30A300011060008A0000000047
-:103840000000000D30A8A040240400401104003BFB
-:1038500030A9A0001120008500000000936C000832
-:103860005180000927A40010976F001031EEFFFF70
-:1038700000CE682B11A0000427A4001030B800402F
-:103880001300007A00000000AFA70010A7850040D9
-:10389000AF8600340E0001580000000000404821AF
-:1038A0001440FFD08FA700108F420E148F84004861
-:1038B000AC8200208F470E1CAC8700242D390001FC
-:1038C0000330302510C000178FBF001C8F840038D4
-:1038D00024100F0010900085000000008F4F017829
-:1038E00005E0FFFE24180F001098006F0000000094
-:1038F0008F470E14240202403C101000AF470144D1
-:103900008F490E1CAF490148A3400152A740015AFC
-:10391000AF400160A7400158AF420154AF50017859
-:103920008FBF001C8FB0001803E0000827BD0020E7
-:10393000AF470E000A00022E000000008F490178F8
-:103940000520FFFE240A08008F84003CAF4A01785E
-:103950009758008A330FFFFF01E4702325CDFFFF46
-:1039600031AC1FFF2D8B00081560FFF9000000002F
-:103970008F83004C8F9F003800C0482103442021D2
-:103980002466000124190F00AF86004C306A00FF46
-:1039900000E938232486400013F9000524080001BB
-:1039A000938B004231680007000812403448000140
-:1039B000000A7C003C18010001F87025AC8E400024
-:1039C0008F8D004C30AC003630A40008ACCD000424
-:1039D0001080002E010C3025974D0E0A8F8C003C74
-:1039E0003C02810031A4FFFF258B000800824025A6
-:1039F0003C03100031651FFF25390006241F000E0F
-:103A0000AF48016000C33025A75F015AAF85003C75
-:103A1000A759015814E0000A8F9F003824050F00B1
-:103A200053E500022410000134C600408F430E10FD
-:103A30008F880048AD0300208F4B0E18AD0B00247B
-:103A40008F420E14AF4201448F440E1CAF44014814
-:103A5000A34A01523C0A1000AF4601540A00022159
-:103A6000AF4A017814C0FF7830A8A0408F420E14EE
-:103A70008F84004800004821AC8200208F470E1C34
-:103A8000AC8700240A0002582D3900018F98003CB1
-:103A900025390002A7590158270F000831EE1FFFF2
-:103AA0000A0002ADAF8E003CAF40014C1120002C4B
-:103AB000000000008F460E10AF4601448F430E18E1
-:103AC000240200403C101000AF430148A3400152C3
-:103AD000A740015AAF400160A7400158AF420154CE
-:103AE000AF5001780A0002718FBF001C1120000640
-:103AF00000000000975F0E0833E5004014A00002AC
-:103B0000000000000000000D8F4801780500FFFE56
-:103B100000000000974E0E103C0D0500240320000D
-:103B200031CCFFFF018D1025AF42014C8F440E14A4
-:103B30003C0B1000AF4401448F4A0E1CAF4A0148B1
-:103B4000A34001528F840038A740015AAF40016062
-:103B5000A7400158AF4301540A00025FAF4B017800
-:103B60008F590E14AF5901448F430E1C0A0002D91D
-:103B70002402004027BDFFE0AFB20018AFB100142F
-:103B8000AFB00010AFBF001C0E0000CA0000000064
-:103B90003C0280008F8A0044345000703C120800C0
-:103BA00026523B70020088218E0800008F450000DD
-:103BB00038A400013083000110600017AF88003086
-:103BC000022048218D2C00003C0208008C42006C31
-:103BD0003C1808008F1800680188182300436821EA
-:103BE0000000C82101A3782B0319702101CF4021C7
-:103BF0003C010800AC2D006C3C010800AC280068BA
-:103C00008F4B00003967000130E6000114C0FFED62
-:103C100001804021AF8C00308E1800003C0E08005F
-:103C20008DCE006C3C0C08008D8C00680308782356
-:103C300001CF28210000402100AF302B01885821FE
-:103C4000016620213C010800AC25006C3C01080005
-:103C5000AC2400688F49010025470088AF870048E1
-:103C6000AF890038AF4900208E070000AF870030D1
-:103C70008F5901780720FFFE000000008E0F000022
-:103C80003C0D08008DAD00743C0C08008D8C00705C
-:103C900001E7702301AE28210000302100AE582B2F
-:103CA00001862021008B3821240908003C010800EE
-:103CB000AC2500743C010800AC270070AF490178C6
-:103CC00093430108A383004293820042305F0001C6
-:103CD00017E000158F830038241F0D00107F001996
-:103CE00024020F001062001D000000009147000038
-:103CF0002403005030E900FF112300043C0540007C
-:103D0000AF4501380A000312000000000E0008DA77
-:103D1000000000008F8A00443C054000AF45013898
-:103D20000A00031200000000939900423338000695
-:103D3000001851000E00020D0152D8210A00036E36
-:103D40008F8A00443C1B0800277B3BF00E00020DCD
-:103D5000000000000A00036E8F8A00443C1B08002C
-:103D6000277B3C100E00020D000000000A00036ECD
-:103D70008F8A004490AA00018FAB00108CAC001019
-:103D80003C0300FF8D680004AD6C00208CAD001476
-:103D900000E060213462FFFFAD6D00248CA70018A5
-:103DA0003C09FF000109C024AD6700288CAE001C4F
-:103DB0000182C82403197825AD6F0004AD6E002C74
-:103DC0008CAD0008314A00FFAD6D001C94A90002C3
-:103DD0003128FFFFAD68001090A70000A560000229
-:103DE000A1600004A167000090A30002306200FF00
-:103DF0000002198210600005240500011065000E04
-:103E00000000000003E00008A16A00018CD800282F
-:103E1000354A0080AD7800188CCF0014AD6F0014C7
-:103E20008CCE0030AD6E00088CC4002CA16A00015D
-:103E300003E00008AD64000C8CCD001CAD6D0018D3
-:103E40008CC90014AD6900148CC80024AD6800084A
-:103E50008CC70020AD67000C8CC200148C830064FA
-:103E60000043C82B13200007000000008CC2001480
-:103E7000144CFFE400000000354A008003E0000815
-:103E8000A16A00018C8200640A0003C400000000E3
-:103E900090AA000027BDFFF88FA9001CA3AA00006C
-:103EA0008FAE00003C0FFF808FA8001835E2FFFFA7
-:103EB0008CCD002C01C26024AFAC0000A120000416
-:103EC00000E06021A7A000028FB800008D27000449
-:103ED0000188182100A0582100C05021006D28261B
-:103EE0003C06FF7F3C0F00FF2CAD000135EEFFFFCD
-:103EF00034D9FFFF3C02FF0003193024000D1DC020
-:103F0000010EC82400E2C02400C3702503197825DF
-:103F1000AD2E0000AD2F00048D450024AFAE000093
-:103F2000AD2500088D4D00202405FFFFAD2D000CB0
-:103F3000956800023107FFFFAD2700109166001859
-:103F400030C200FF000219C2506000018D450034EC
-:103F5000AD2500148D67000827BD0008AD27001CA3
-:103F60008C8B00CCAD2C0028AD20002CAD2B002478
-:103F7000AD20001803E00008AD20002027BDFFE0C1
-:103F8000AFB20018AFB10014AFB00010AFBF001C4B
-:103F90009098000000C088213C0D00FF330F007F87
-:103FA000A0CF0000908E000135ACFFFF3C0AFF005F
-:103FB000A0CE000194A6001EA22000048CAB001429
-:103FC0008E29000400A08021016C2824012A4024AD
-:103FD0000080902101052025A6260002AE240004C1
-:103FE00026050020262400080E0000722406000288
-:103FF00092470000260500282624001400071E0012
-:104000000003160324060004044000032403FFFFFA
-:10401000965900023323FFFF0E000072AE230010FA
-:10402000262400248FBF001C8FB200188FB100140B
-:104030008FB0001024050003000030210A00007C2E
-:1040400027BD002027BDFFD8AFB1001CAFB00018BE
-:10405000AFBF002090A80000240200018FB0003CF8
-:104060003103003F00808821106200148FAA0038BD
-:10407000240B0005506B0016AFAA001000A02021F1
-:1040800000C028210E00040702003021922400BC49
-:10409000308300021060000326060030ACC0000030
-:1040A00024C600048FBF00208FB1001C8FB0001801
-:1040B00000C0102103E0000827BD0028014038217E
-:1040C0000E000385AFB000100A00044B0000000092
-:1040D0000E0003CCAFB000140A00044B0000000037
-:1040E0003C02000A034218213C04080024843B08D7
-:1040F0002405001A000030210A00007CAF83002C48
-:104100003C038000346200708C48000000A05821FD
-:1041100000C04821308A00FFAF8800308F4401780A
-:104120000480FFFE3C0C8000358600708CC50000CA
-:104130003C0308008C6300743C1808008F18007062
-:1041400000A82023006468210000C82101A4782B66
-:104150000319702101CF60213C010800AC2D0074CF
-:104160003C010800AC2C00708F480E14AF4801448D
-:10417000AF47014CA34A0152A74B0158934601088F
-:1041800030C5000854A0000135291000934B0900E8
-:1041900024070050316A00FF1147000700000000AB
-:1041A0008F450E1CAF450148AF4901543C09100032
-:1041B00003E00008AF490178934D010831A80008D9
-:1041C0001100001000000000934F010831EE0010B4
-:1041D00051C00001352900083C04080090843B6C64
-:1041E000A34401508F4309A4AF4301488F4209A063
-:1041F000AF420144AF4901543C09100003E00008FC
-:10420000AF4901783C1908008F393B283338000842
-:104210005700FFF1352900080A00049E0000000045
-:1042200024070040AF470814AF4008108F420944EC
-:104230008F4309508F4409548F45095C8F46094CC0
-:10424000AF820064AF830054AF840050AF85005C40
-:1042500003E00008AF8600609346010930C5007F87
-:10426000000518C0000521400083102103E000086C
-:10427000244200883C0A0800914A3B2D3C09080072
-:1042800095293B263C051100000A3C002528000228
-:1042900000E8302500C5182524820008AC83000002
-:1042A00003E00008AC8000048F4A002C974D0908F9
-:1042B0003C0E000E034E382131ACFFFF000C41C014
-:1042C000AF48002C9743090894EB001A0080402166
-:1042D000240200013169FFFFAC8900008CE6001C5C
-:1042E00000A05821AC8600048CE40020AD04000836
-:1042F00090E30019306300031062003E00000000EC
-:104300002865000214A00071240F0002106F004CF9
-:104310000000000024180003107800550000000081
-:104320003C09080095293B1C93430934934F09210C
-:104330003C05080094A53B22306400FF94EE002A5F
-:104340000004688231EC00FF978F0058000DC60012
-:10435000000CCC003127FFFF0319102500A73021E6
-:104360000046202501CF68213C03400000836025E2
-:10437000000D4C00AD090004AD0C0000935909205C
-:104380003C1800062509001400193E0000F82825F5
-:10439000AD0500088F4E092C25E6000130C27FFFD5
-:1043A000AD0E000C8F440930A7820058250200286A
-:1043B000AD0400108F4D0938AD0D0014AD2B000475
-:1043C0008F4C0940AD2C0008934309373C19080075
-:1043D00093393B2CAD200010000347000019C400A6
-:1043E000011858253567FFFFAD27000C03E00008D2
-:1043F000AF4A002C3C09080095293B1C3C0D0800E5
-:1044000095AD3B263C0C0800958C3B1894E40024A9
-:10441000312EFFFF01AE302100CC18230004CC0068
-:104420002462FFF20322C025240F0800AD18000CFF
-:10443000AD0F0014AD0000100A0004F225080018AA
-:1044400094E5002494EE00283C09080095293B1CC3
-:1044500000056C00000E640035A68100358408005C
-:10446000AD06000CAD0400100A0004F2250800148B
-:104470003C09080095293B1C3C0F080095EF3B26A2
-:104480003C06080094C63B1894E400243125FFFF45
-:1044900094ED002801E5702101C660230004CC00E2
-:1044A000000D1C002582FFEE006278253738810060
-:1044B00024050800AD18000CAD0F0010AD05001864
-:1044C000AD0000140A0004F22508001C1460FF94DB
-:1044D0000000000094E300243C09080095293B1CDF
-:1044E0000003140034590800AD19000C0A0004F24E
-:1044F0002508001003E00008240201F427BDFFE8AE
-:10450000AFB00010AFBF00140E00005C008080212F
-:1045100024050040AF4508148F8300548F84005059
-:104520008F85005C0070182100641023184000047F
-:10453000AF830054AF6300548F660054AF860050C1
-:104540001200000C000000008F440074936800818A
-:104550003409FA002D07000710E00005008910213A
-:10456000936C0081240B01F4018B50040144102151
-:10457000AF62000C8F4E095C01C5682319A00004CE
-:104580008FBF00148F4F095CAF8F005C8FBF00148A
-:104590008FB000100A00005E27BD00188F840064F1
-:1045A0008F8300548F820050AF640044AF6300508B
-:1045B00003E00008AF6200543C03800034620070E6
-:1045C0008C43000027BDFFF8308700FF30A900FFB3
-:1045D00030C800FFAF8300308F4401780480FFFEB5
-:1045E0003C028000345900708F380000A3A70003FC
-:1045F0003C0708008CE700748FAC00003C06080004
-:104600008CC60070030378233C0E7FFF00EFC821A7
-:1046100035CDFFFF00005021018D282400CA18214C
-:10462000000847C0032F202B00A810250064C021DC
-:10463000AFA200003C010800AC3900743C01080046
-:10464000AC380070934F010AA3A000023C0E80FF1B
-:10465000A3AF00018FAC0000312B007F35CDFFFFF1
-:10466000018D4824000B5600012A40252407300004
-:104670002406FF803C05100027BD0008AF48014C10
-:10468000AF470154A7400158A346015203E0000878
-:10469000AF45017827BDFFE8AFBF0014AFB00010F1
-:1046A0008F6500743C068000309000FF00A6202536
-:1046B0000E00005CAF640074936300053462000870
-:1046C0000E00005EA3620005020020218FBF0014CF
-:1046D0008FB0001024050005240600010A0005968D
-:1046E00027BD001827BDFFE03C038000AFB00010DD
-:1046F000AFBF0018AFB10014346200708C470000E7
-:10470000309000FF30A800FFAF8700308F44017861
-:104710000480FFFE3C188000371100708E2F0000CF
-:104720003C0D08008DAD00743C0A08008D4A0070F5
-:1047300001E7702301AE28210000582100AE302B84
-:10474000014B4821012638213C010800AC250074AA
-:10475000000088213C010800AC2700701100000F08
-:10476000000000008F6200742619FFFF3208007FEE
-:104770000002FE0233E5007F15000006332200FF31
-:104780002407FF800207202624A3FFFF0083802543
-:10479000320200FF00408021241110080E00005C4E
-:1047A000000000008F4908183125000414A0FFFD07
-:1047B0003218007F001878C00018714001CF6821BE
-:1047C00025AC0088AF4C0818274A09808D4B002083
-:1047D000AF4B01448D460024AF460148A350015021
-:1047E0000E00005EA7400158022010218FBF001864
-:1047F0008FB100148FB0001003E0000827BD002027
-:1048000027BDFFE8308400FFAFBF00100E0005E1B8
-:1048100030A500FF8F8300548FBF00103445004047
-:104820002404FF903C02100027BD0018AF43014C48
-:10483000A3440152AF45015403E00008AF420178A0
-:1048400027BDFFE8AFBF0014AFB000109345093F8C
-:10485000240200063C08080095083B2230A300FF14
-:104860002487FFD8240500041062003624060002C5
-:10487000974E093C3C0D02040006340031CCFFFF8A
-:10488000018D5825AC8B0000934A093E3149002028
-:104890001120000800000000935F09363C19010355
-:1048A0003738030033F000FF02187825240500088C
-:1048B000AC8F000493580934934D09213C104000FB
-:1048C000330E00FF000E608231AB00FF000C56007B
-:1048D000000B1400014218250068F82503F0C825D4
-:1048E000AC99FFD8935809378F4C09488F4D094030
-:1048F00000057882330E00FF01CF5821018D282357
-:10490000000B57000146102530A3FFFF0043402550
-:10491000000F488001273021ACE800200E00005C29
-:1049200024D00028240400040E00005EA364003F8D
-:10493000020010218FBF00148FB0001003E00008A8
-:1049400027BD00180A0006442406001227BDFFD028
-:1049500024090010AFB50024AFB40020AFB3001C91
-:10496000AFB10014AFB000103C010800A0293B2CEF
-:10497000AFBF0028AFB2001897480908309400FF75
-:104980003C02000E3107FFFF000731C0AF46002C8C
-:10499000974409089344010B30B300FF0342802180
-:1049A000308300300000A821106000E4000088215E
-:1049B000240C00043C010800A02C3B2C934B093E26
-:1049C000000B5600000A2E0304A001310000000075
-:1049D000AF4000489352010B324F002011E0000617
-:1049E00000000000935F093E001FCE000019C603BF
-:1049F00007000148000000009346010B30C2004050
-:104A0000104000038F9200548F87005424F2FFFF60
-:104A1000960A002C9345093493490937A78A005810
-:104A200030A600FF312700FF00071080004620213C
-:104A30000091F8213C010800A43F3B22920300189A
-:104A40003C010800A4203B1C3C010800A4203B18AA
-:104A5000307000FF03F04021250B000A3170FFFF8A
-:104A60003C010800A4283B243C010800A4283B2664
-:104A70000E00009A020020210E0004C500402021F3
-:104A80008F4B002C975809083C19000E0359402100
-:104A9000330FFFFF000F71C0AF4E002C9743090882
-:104AA000950D001A241100010040382131ACFFFFA0
-:104AB000AC4C00008D0A001CAC4A00048D0500209F
-:104AC000AC4500089109001931230003107100BDA5
-:104AD0002871000216200103240C0002106C00F55E
-:104AE000240D0003106D00CA000000003C090800FE
-:104AF00095293B1C93430934935809213C0A08002B
-:104B0000954A3B22306400FF950C002A0004F8828D
-:104B1000331900FF97980058001F760000197C0099
-:104B20003126FFFF01CF402501466821010D882570
-:104B3000019828213C0840000228102500054C005F
-:104B4000ACE90004ACE20000934309203C040006F9
-:104B500024E900140003FE0003E4C825ACF90008B2
-:104B60008F4E092C270F000131E67FFFACEE000CC1
-:104B70008F4D0930A786005824E60028ACED0010C0
-:104B80008F4C0938ACEC0014AD3200048F51094051
-:104B9000AD310008934209373C05080090A53B2C35
-:104BA000AD2000100002270000051C000083F8253E
-:104BB00037F2FFFFAD32000CAF4B002C12A00033D8
-:104BC000000000009352093F24150006240500044C
-:104BD000324B00FF117500CD24090002974F093CAC
-:104BE0003C0E020431EDFFFF01AE6025ACEC002865
-:104BF0009351093E322200201040000800000000BE
-:104C0000934409363C180103371F0300309900FF15
-:104C1000033F2825ACC5000424050008935209343D
-:104C20009343092100056082324B00FF000BA882EC
-:104C3000306400FF0015FE000004C40003F8C8251E
-:104C4000032A782501E87025ACCEFFD8934D0937AB
-:104C50008F5209488F42094031B100FF022C582180
-:104C600002423023000B1F000009AC0000754825EC
-:104C700030C8FFFF012850250E00005CACEA002080
-:104C8000240700040E00005EA367003F0E0000C36F
-:104C9000020020213C05080090A53B2C30B0000309
-:104CA0001200000F028020218F8800542509000186
-:104CB000AF890054AF6900508F6A0054014938230E
-:104CC00018E00002012020218F640054AF640054DA
-:104CD0008F420074244601F4AF66000C028020214C
-:104CE00002602821A76000680E0005E13C13100057
-:104CF0008F8E005434540006AF4E014C8F8D004C03
-:104D00008FBF00288FB5002431B100FF25AC000112
-:104D1000AF8C004C8FB20018A35101528FB000101D
-:104D2000AF5401548FB10014AF5301788FB40020F9
-:104D30008FB3001C03E0000827BD00309359093EE3
-:104D40000019C6000018960306420048241100020C
-:104D500093420923304400021080FF1E8F870060B9
-:104D60008F86005414E6FF1B000000000E00005C5C
-:104D7000000000009365003F2408001630A900FFE2
-:104D80001128000C240A00083C0D080091AD3B2CB2
-:104D900035AC00013C010800A02C3B2C936B003F7C
-:104DA000316300FF106A0065240E000A106E005E79
-:104DB0002402000C0E00005E000000000A00069DA8
-:104DC000000000003C09080095293B1C3C19080024
-:104DD00097393B263C18080097183B18950E00247D
-:104DE000313FFFFF033F782101F86823000E8C005C
-:104DF00025ACFFF2022C502524050800244700189A
-:104E0000AC4A000CAC4500140A0006E5AC400010AA
-:104E10003C09080095293B1C3C18080097183B26C4
-:104E20003C0F080095EF3B18950D00243139FFFF2A
-:104E3000950C00280319702101CF8823000D2C0048
-:104E4000000C54002622FFEE0142302534A48100DC
-:104E500024030800ACE4000CACE60010ACE300183E
-:104E6000ACE000140A0006E524E7001C3C01080041
-:104E7000A0313B2C9343093E24150001307F0020D4
-:104E800017E0FED4241100080A00069D2411000436
-:104E90008F6E00848F4D094011A0FECDAF8E00545F
-:104EA000240F00143C010800A02F3B2C0A00069C94
-:104EB0000000000095020024950600283C09080027
-:104EC00095293B1C0002240000061C00349F810031
-:104ED00034790800ACFF000CACF900100A0006E5BC
-:104EE00024E700141460FF0100000000951800245E
-:104EF0003C09080095293B1C2447001000187C0041
-:104F000035EE08000A0006E5AC4E000C0A00071F4B
-:104F1000240900128F64004CAF6400548F63005466
-:104F20000A0006A6AF630050A362003F0E00005EB9
-:104F3000000000000A00069D00000000240200148A
-:104F40000A0007F3A362003F27BDFFE8308400FF9B
-:104F5000AFBF00100E0005E130A500FF9378007E82
-:104F60009379007F936E00809368007A332F00FF5F
-:104F700000186600000F6C0031CB00FF018D482542
-:104F8000000B52008FBF0010012A3825310600FFA8
-:104F90003444700000E628252402FF813C03100001
-:104FA00027BD0018AF45014CAF440154A342015244
-:104FB00003E00008AF43017827BDFFD8AFB2001867
-:104FC000AFB10014AFB00010AFBF0020AFB3001CF2
-:104FD00093420109308600FF30B000FF000618C27E
-:104FE000320400023071000114800005305200FFCD
-:104FF0009367000530E5000810A0000D30C80010D0
-:10500000024020210E0005CD0220282124040001A9
-:105010008FBF00208FB3001C8FB200188FB1001417
-:105020008FB000100080102103E0000827BD002889
-:105030001500003200000000934301090000282100
-:105040003062007F000220C00002F94003E4982192
-:1050500026790088033B98218E7800248E6F000803
-:10506000130F0046000000008F6400842418000223
-:105070000004FD8233F900031338007C00000000B7
-:1050800093660083934A0109514600043205007C6F
-:1050900010A00060000000003205007C14A0005346
-:1050A0000240202116200006320400018E7F0024D9
-:1050B0008F59010417F9FFD60000202132040001A6
-:1050C0001080000A024020218F4209408F93006423
-:1050D00010530006000000000E00067B022028216D
-:1050E0008F430940AF630044024020210E00062890
-:1050F000022028210A00082C240400013C09080091
-:105100008D290064252600013C010800AC260064BE
-:1051100016000012000000008F6D00843C0E00C0DD
-:1051200001AE602415800005024020210E0007FA20
-:10513000022028210A00082C240400012405000470
-:105140000E00059624060001024020210E0007FAF9
-:10515000022028210A00082C240400010E00003D32
-:1051600024040001936B007D020B50250E00005EAD
-:10517000A36A007D0A00086F8F6D00848F6600743B
-:105180008F4801048E67002400064E021507FFB603
-:105190003126007F936B008326440001308A007F14
-:1051A00011460043316300FF5464FFB08F640084F4
-:1051B0002645000130B1007F30A200FF1226000416
-:1051C00024050001004090210A000842241100013A
-:1051D000240FFF80024F702401CF9026324200FF3F
-:1051E000004090210A000842241100010E00067BB5
-:1051F00002202821321800301300FFAA321000824A
-:10520000024020210E0005CD022028210A00082C92
-:10521000240400018F6E00743C0F800024050003FD
-:1052200001CF9025AF7200749371008324060001B2
-:105230000E000596322400FF0E00003D24040001FC
-:10524000936D007D020D60250E00005EA36C007D55
-:105250003C0B08008D6B0054257000013C010800D8
-:10526000AC3000540A00082C240400018F6800743C
-:105270003C0980002405000401093825AF6700744B
-:1052800093630083240600010E000596306400FF3E
-:105290000E00003D240400019362007D0202982567
-:1052A0000E00005EA373007D0A00082C2404000198
-:1052B000324D008039AC0080546CFF6C8F640084E8
-:1052C0000A0008952645000127BDFFD03C0A0008CA
-:1052D000AFBF002CAFB40028AFB30024AFB20020A2
-:1052E000AFB1001CAFB00018034AD8212409004018
-:1052F000AF490814AF4008108F4209448F4309504A
-:105300008F4609548F47095C8F48094C9344010824
-:105310009345010BAF820064308400FF30A500FF8D
-:10532000AF830054AF860050AF87005C0E000816B4
-:10533000AF8800601440015A8FBF002CA76000683E
-:10534000934D0900240B00503C14080026943C3077
-:1053500031AC00FF3C12080026523C40118B000388
-:10536000000000000000A02100009021934F0109DF
-:105370008F8800542402001031F1007F001170C0AA
-:105380000011694001AE282124B80088AF580818E0
-:105390008F4A01048F4B09A43C0C000E034CC8211A
-:1053A000014B48233C010800AC293B088F440958B5
-:1053B0003C010800A0223B2C9746090800881823CE
-:1053C0003C010800AC233B0C30C7FFFF0007F9C0CD
-:1053D0003C010800AC283B30AF5F002C9742090825
-:1053E0009730002C8E910000932F0018037898219D
-:1053F000A7900058AF9300480220F80931F000FF51
-:10540000304E000215C0018E30530001126001427F
-:10541000000000008F4F09A4241300013C01080084
-:10542000AC2F3B3493510934934E0937322500FF9A
-:1054300031CD00FF000D60800185502101505821C1
-:105440003C010800A42B3B243C010800A42A3B2279
-:1054500093490934312200FF0202202124900010D8
-:105460003C010800A4303B20240800068F9900541A
-:105470003C010800AC283B288F9F005C8F580958DE
-:105480000000802103F9282304A0013C03192023F4
-:105490000480013A00A4382B10E0013C0000000019
-:1054A0003C010800AC253B0C8E4200000040F8098E
-:1054B000000000003046000214C000DD00408821DA
-:1054C00030430001546000108E4200043C04080088
-:1054D0008C843B103C09C00000898025AF500E0031
-:1054E0008F4B0000316A00081140FFFD00000000F2
-:1054F00097450E0824100001A78500408F4C0E042C
-:10550000AF8C00348E4200040040F8090000000017
-:1055100002228825322D000215A00159000000004A
-:105520003C09080095293B183C06080094C63B241A
-:105530003C04080094843B1A3C1908008F393B1046
-:10554000012658213C1808008F183B343C1F0800E6
-:1055500097FF3B2E016418218F4E09400329282113
-:10556000246F00020319682100BF60213C0108007C
-:10557000A42B3B26AF8E00643C010800AC2D3B34CD
-:105580003C010800A42C3B1C0E00009A31E4FFFFF4
-:105590008F87004C004020213C010800A0273B2DB4
-:1055A0008E42000824E80001AF88004C0040F80952
-:1055B000000000008F4B002C974909083C0A000EA0
-:1055C000034A38213124FFFF000419C08F8A005498
-:1055D000AF43002C9743090894E6001A004040218D
-:1055E00030DFFFFFAC5F00008CF9001CAC590004F9
-:1055F0008CF80020AC58000890EF001931E300034C
-:10560000107300E60000000028620002144001024E
-:10561000240C0002106C00F4240D0003106D00A790
-:10562000000000003C09080095293B1C9345093403
-:10563000934C09213C0F080095EF3B2230BF00FF3F
-:1056400094EE002A001F6882319900FF978C005861
-:10565000000D16000019C4003124FFFF01E43021C1
-:10566000005848250126382501CC28213C0340005C
-:1056700000E3F82500056C00AD0D0004AD1F00002F
-:10568000935909203C180006250D001400197E00CE
-:1056900001F87025AD0E00088F42092C2586000107
-:1056A0008E4C000CAD02000C8F44093030C97FFFD6
-:1056B000A7890058AD0400108F4709382504002839
-:1056C000AD070014ADAA00048F450940ADA5000840
-:1056D000934309373C1F080093FF3B2CADA00010FB
-:1056E0000003C700001FCC000319782535EEFFFF2B
-:1056F000ADAE000CAF4B002C0180F809000000009B
-:105700003C06080094C63B263C02080094423B1A23
-:1057100000C24821252B00020E0000C33164FFFFA8
-:105720003C0808008D083B083C0708008CE73B104C
-:10573000010750233C010800AC2A3B081540000635
-:10574000000000003C0808008D083B28350A004096
-:105750003C010800AC2A3B28120000848F830048DB
-:105760008F470E108F900048AE0700208F4B0E1809
-:10577000AE0B00243C10080096103B1C0E00005C91
-:1057800000000000240F0040AF4F08148F86005423
-:105790008F89005000D018210069702319C00004BF
-:1057A000AF830054AF6300548F640054AF84005043
-:1057B0001200000C000000008F44007493780081F8
-:1057C0003419FA002F020007104000050099182133
-:1057D000937F0081240C01F403EC680401A41821D8
-:1057E000AF63000C8F4A095C8F88005C0148282356
-:1057F00018A00003000000008F50095CAF90005C0F
-:105800000E00005E000000008F8300548E470010E1
-:105810003C010800AC233B3000E0F8090000000028
-:105820003C0B08008D6B3B081560FF102408000638
-:105830008F590024975F09088F8900648F8E005468
-:105840003C0C001F978400588F8F002C8F930050C2
-:1058500033F8FFFF358DFF80032D3024001811C071
-:1058600032320010AF420024A5E4002CAF460024E1
-:10587000AF690044AF6E0050AF7300545640007CD7
-:105880008E850004322A0040554000318E91000878
-:105890008E88000C0100F809000000008FBF002C6A
-:1058A0008FB400288FB300248FB200208FB1001C6A
-:1058B0008FB0001803E0000827BD00303C09080045
-:1058C00095293B1C3C03080094633B263C040800DC
-:1058D00094843B1894F900243125FFFF94F80028A4
-:1058E0000065F82103E478230019640000186C00B7
-:1058F00025EEFFEE01AE302535828100240308003D
-:10590000AD02000CAD060010AD030018AD00001490
-:105910000A0009B32508001C934301098F8600384B
-:1059200000033E0000E64025AF4800808F5F09A0DD
-:105930008F5809A4AFBF0010AF5F0E148FB90010CD
-:10594000AF590E10AF580E1C0A00092DAF580E1893
-:105950000220F809000000008E88000C0100F80900
-:10596000000000000A000A508FBF002CA460002035
-:10597000A47300220A000A05AC7300243C0108004D
-:10598000AC203B0C0A0009538E4200003C01080089
-:10599000AC243B0C0A0009538E4200003C0908006D
-:1059A00095293B1C3C1F080097FF3B263C0508003F
-:1059B00094A53B1894F800243124FFFF03E4C82188
-:1059C0000325782300186C0025EEFFF201AE602558
-:1059D000AC4C000C24020800AD020014AD00001015
-:1059E0000A0009B32508001894E6002494E300286F
-:1059F0003C09080095293B1C000624000003FC001C
-:105A00003485810037F90800AD05000CAD19001090
-:105A10000A0009B3250800141460FF02000000000A
-:105A200094F800243C09080095293B1C00187C00D0
-:105A300035EE0800AD0E000C0A0009B32508001071
-:105A400093520109000028210E000628324400FF6D
-:105A50008FBF002C8FB400288FB300248FB200209A
-:105A60008FB1001C8FB0001803E0000827BD003084
-:105A700000A0F809000000000A000A4A322A00408B
-:105A80001200FF6B000000008F4E0E148F92004832
-:105A9000AE4E00208F530E1C0A000A34AE53002471
-:105AA0008F820018008040213C040100904700854F
-:105AB00030E3002010600009000000003C070800EF
-:105AC0008CE73B308F83001400E320230480000820
-:105AD0009389000014E300030100202103E0000883
-:105AE000008010213C04010003E000080080102128
-:105AF0001120000B006738238F8C001C2409003410
-:105B0000918B00BC316A0002514000012409003031
-:105B100000E9682B15A0FFF10100202100E93823DE
-:105B20002419FFFC00B9C02400F9782400F8702B78
-:105B300015C0FFEA01E8202130C20003000218234B
-:105B400014C00012306900030000302100A9702148
-:105B500001C6682100ED602B1180FFE03C040100CC
-:105B60002D2F00010006482B0105382101E93024C2
-:105B700014C0FFDA24E4FFFC2419FFFC00B9C024A0
-:105B80000308202103E00008008010218F8B001CF7
-:105B900024060004916A00BC314400041480FFEC28
-:105BA00000A970210A000AFC0000302127BDFFE88F
-:105BB000AFBF00108F460100934A01093C1F080047
-:105BC0008FFF00902407FF80314F00FF31E8007FF6
-:105BD0000008614003E6C821032CC02127090120E9
-:105BE000012770243C010800A02F3B6CAF4E080C2D
-:105BF0003C0D08008DAD00903C0400803482000311
-:105C000001A65821016C18212465012030AA0078D2
-:105C100001424025AF48081C3C1F08008FFF009040
-:105C20008F88004403E6C021331900070307482486
-:105C3000033A7821AF49002825E909C0952E0002D2
-:105C40003C0D08008DAD008C3C0A08008D4A009088
-:105C500031CC3FFF01A61821000C5980006B282190
-:105C600000A72024AF44002C952200023C1F08000E
-:105C70008FFF008C9107008530593FFF03E67821A4
-:105C80000019C1800146702101F8682131CC007FE4
-:105C900031AB007F019A2821017A50213C03000C8E
-:105CA0003C04000E00A328210144102130E600200E
-:105CB00027470980AF820028AF880018AF890020ED
-:105CC000AF85001C10C00006AF8700248D02005075
-:105CD0008CA4010C0044302318C0007700000000A1
-:105CE000910C0085240DFFDF018D3824A10700856C
-:105CF0008F8B00188F8900208F8700248D65004CC2
-:105D0000AF850014912F000D31EE002011C0001757
-:105D10000000000024090001A3890000AF800008F2
-:105D20008CE400248F850008240A0008AF8000045A
-:105D3000AF80000C3C010800A42A3B1A3C0108007B
-:105D4000A4203B2E0E000AD0000030218F850020B9
-:105D50008FBF0010AF82001090A8000D27BD001863
-:105D60000008394203E0000830E20001913F0002E0
-:105D70002418000133F900FF00192182109800391E
-:105D8000240800021088005B8F8600288CE5002420
-:105D900014A0001B8F9F001C91220000240A000504
-:105DA0003046003F10CA0047240400018F860004DB
-:105DB000A3840000AF86000CAF8600088CE40024AA
-:105DC0008F850008240A00083C010800A42A3B1A19
-:105DD0003C010800A4203B2E0E000AD00000000069
-:105DE0008F8500208FBF0010AF82001090A8000D9B
-:105DF00027BD00180008394203E0000830E2000126
-:105E00008CF800088CF900248FEE00C4A3800000F9
-:105E10008CE40024AF8E00088F8500088F86000474
-:105E200003197823240A0008AF8F000C3C010800F6
-:105E3000A42A3B1A3C010800A4203B2E0E000AD0E5
-:105E4000000000008F8500208FBF0010AF8200107F
-:105E500090A8000D27BD00180008394203E0000893
-:105E600030E20001912300003062003F104400271F
-:105E70008F85001C8CE400241480002100000000A9
-:105E80008D2E00183C187FFF8F85001C370FFFFFF9
-:105E900001CF1824AF8300048F9F00048CA80084D6
-:105EA00003E8C82B1720000203E020218CA4008403
-:105EB0000A000B8BAF8400048CA3010C0A000B6951
-:105EC000AF8300148D2C00188F8600043C0D7FFFDB
-:105ED0008F89001C35A3FFFF01835824240400018F
-:105EE000AF8B000CAD2000CCA38400000A000B9700
-:105EF000AF8600088CCA00140A000B8BAF8A00041E
-:105F00008CA300C80A000BCEAF8300048F84002846
-:105F10008CAC00648C8D0014018D582B1160000432
-:105F2000000000008CA200640A000BCEAF820004C7
-:105F30008C8200140A000BCEAF8200048F8500080B
-:105F400027BDFFE0AFBF0018AFB1001414A00007D9
-:105F5000AFB000108F8600202402000590C400001E
-:105F60003083003F106200B68F84001C8F910004C4
-:105F700000A080218F8C00243C0508008CA53B0CE0
-:105F80008D8B000431663FFF00C5502B554000014A
-:105F900000C02821938D000011A0007300B0F82BE1
-:105FA0008F98001C24040034930F00BC31EE0002D3
-:105FB00051C000012404003000A4C82B172000D1D8
-:105FC0000000000000A4282300B0F82B3C010800CA
-:105FD000A4243B1817E00068020020213C030800BD
-:105FE0008C633B080083102B544000010080182173
-:105FF0008F8800203C010800AC233B1000004821A2
-:106000009104000D30830020506000018F490E186C
-:106010008F8300100123382B10E00059000000008E
-:106020003C0408008C843B1000895821006B502BE5
-:10603000114000560090602B0069302300C02021E1
-:106040003C010800AC263B1012000003241FFFFC9B
-:106050001090008A32270003009FC8243C010800EA
-:10606000AC393B103C010800A4203B2E8F84000873
-:10607000120400078F83001CAF910004020020214E
-:106080008C7100CCAF90000826300001AC7000CCC1
-:106090003C0208008C423B108F8A000C2407001839
-:1060A0000082202301422823AF84000810800002D0
-:1060B000AF85000C240700108F8600183C010800F3
-:1060C000A0273B2C2407004090CC0085318B00C0DA
-:1060D000116700408F8D001014A0001500002021D2
-:1060E000934A01098F420974314500FF00022602DC
-:1060F00024A300013090007F3071007F1230007ABD
-:106100002407FF80A0C300833C0908008D293B2899
-:106110008F880020240D0002352C00083C01080067
-:10612000A02D3B6D3C010800AC2C3B282404001042
-:10613000910E000D31C6002010C00005008018210E
-:10614000240800013C010800AC283B103483000106
-:106150008FBF00188FB100148FB0001000601021A5
-:1061600003E0000827BD00203C010800A4203B18E4
-:1061700013E0FF9A020020210A000C1F00A020213A
-:106180003C0408008C843B100090602B1180FFAE13
-:10619000000000003C0F080095EF3B1801E470215F
-:1061A00001C6682B11A000072C8200043C1F600070
-:1061B0008FF954043338003F1700FFE524030042F1
-:1061C0002C8200041040FFA0240300420A000C7D32
-:1061D0008FBF0018152DFFC0000000008CDF007479
-:1061E0003C0380002405FF8003E3C825ACD900747C
-:1061F00090D80085240E000424040010330F003FC3
-:1062000001E54025A0C800858F8800203C010800DA
-:10621000A02E3B6D240300019106000D30C9002023
-:1062200015200003000000003C0308008C633B10B5
-:106230003C010800AC233B080A000C74000000007D
-:106240008F87000C8C88008400E8282B14A00002A3
-:1062500000E088218C91008424090001A3890000BA
-:106260008F440E18022028210E000AD0022030216F
-:10627000022080210A000C05AF82001000071823BD
-:10628000306600033C010800A4263B2E12200005C6
-:106290008F8C001C918B00BC316A000415400015E6
-:1062A00024CD00043C0F080095EF3B2E01E4702143
-:1062B00000AE302B50C0FF6E8F8400082C85000587
-:1062C00014A0FFA32403004230980003170000022B
-:1062D000009818232483FFFC3C010800AC233B10EA
-:1062E0000A000C410000000000A758240A000C69B5
-:1062F000016718263C010800A42D3B2E0A000CD192
-:10630000000000003C010800AC203B100A000C7C9F
-:10631000240300428F83000C14600007000010214A
-:106320008F880020240500059106000030C400FF7E
-:10633000108500030000000003E0000800000000DA
-:10634000910A0018314900FF000939C214E0FFFA30
-:106350008F8500183C04080094843B183C03080017
-:106360008C633B303C1908008F393B103C0F080010
-:1063700095EF3B2E0064C0218CAD005403197021B1
-:1063800001CF6021018D58231960001D000000001D
-:10639000910E001C8F8C0028974B0E1031CD00FF02
-:1063A0008D850004016D30238D88000030CEFFFF05
-:1063B000000E510000AAC821000038210107202149
-:1063C000032A182B0083C021AD990004AD9800006A
-:1063D000918F000A01CF6821A18D000A8F880028C3
-:1063E000974B0E12A50B0008950A003825490001AD
-:1063F000A50900389107000D34E60008A106000D3C
-:1064000003E000080000000027BDFFE093870000C4
-:106410008F8F00208FAD00143C0E7FFF8F89000806
-:1064200035C8FFFFAFBF001CAFB0001801A818248B
-:1064300091EA000D000717C03C1FBFFF00625825FE
-:106440002D2E00018F90001437F9FFFF3C18080033
-:106450008F183B303C0F080095EF3B2601796824EC
-:10646000000E47803C07EFFF3C05F0FF01A8182510
-:106470003149002034E2FFFF34ACFFFF0310582302
-:1064800027A500102406000225EA00020062182455
-:106490000080802115200002000040218F480E1C42
-:1064A000A7AA0012056000372407000030FF00FF94
-:1064B000001FCF008F8B001800793825AFA700147C
-:1064C000916F00853C08080091083B2D3C18DFFFC8
-:1064D00031EE00C0370AFFFF000E182B3C1F0800EA
-:1064E00097FF3B2000EA6824A3A80011000317408F
-:1064F00001A248258FB90010AFA900143C0A08007A
-:10650000914A3B2FA7BF00168FA80014032CC0246C
-:106510003C0B01003C0F0FFF030B18253147000314
-:1065200035EEFFFF010C682400071600006EF8240A
-:106530003C09700001A2C82503E95825AFB9001431
-:10654000AFAB00100E000072A3A000158F8C0020CE
-:10655000260200089186000D30C40020108000063D
-:106560008FBF001C3C05080094A53B1C24B0FFFF16
-:106570003C010800A4303B1C8FB0001803E0000869
-:1065800027BD00208F9800100118502B5540FFC7E1
-:10659000240700010A000D5430FF00FF9382000021
-:1065A00027BDFFE0AFBF00181040000F0080502152
-:1065B0008F880020240B00058F89000491070000BC
-:1065C0008F84001C0100282130E3003F8F860028C3
-:1065D000106B000800003821AFA900100E0004392C
-:1065E000AFAA0014A38000008FBF001803E00008CA
-:1065F00027BD00208D1900183C0F08008DEF3B10BF
-:106600008F98000C3C027FFF8D080014345FFFFF61
-:10661000033F682401F8702101AE6023018838210E
-:10662000AFA900100E000439AFAA00140A000DA291
-:10663000A38000008F8700203C05080094A53B2E16
-:106640003C0208008C423B2890E6000D0005240027
-:1066500030C300201060002C004440258F850018B6
-:1066600000006021240B000190A300850000482158
-:10667000240A00013C0F800035EE00708DC7000039
-:10668000AF8700308F5801780700FFFE3C03800081
-:10669000347900708F3800003C0508008CA5007428
-:1066A0003C0D08008DAD00700307782300AF382142
-:1066B0000000102100EF302B01A2202100861821BC
-:1066C0003C010800AC2700743C010800AC230070BA
-:1066D000AF4B01483C1908008F393B30A7490144B2
-:1066E000A74A0146AF59014C3C0B0800916B3B2D6A
-:1066F000A34B0152AF4801543C081000A74C01586D
-:1067000003E00008AF4801788F4B0E1C3C0A0800DC
-:106710008D4A3B1097490E16974D0E140145602186
-:10672000312AFFFF0A000DC531A9FFFF8F8300202A
-:106730009064000D3082002010400029000000000D
-:106740000000482100005021000040213C0780004B
-:1067500034EB00708D670000AF8700308F4C0178FC
-:106760000580FFFE3C0D800035AC00708D8B000075
-:106770003C0508008CA500743C0408008C84007063
-:106780000167302300A678210000102101E6C82B04
-:106790000082C021031970213C010800AC2F007455
-:1067A0003C010800AC2E0070AF4901483C0D0800C8
-:1067B0008DAD3B30A748014424090040A74A01465B
-:1067C0003C081000240AFF91AF4D014CA34A01522E
-:1067D000AF490154A740015803E00008AF480178D1
-:1067E0008F490E1897460E1297450E1030CAFFFFBC
-:1067F0000A000DFB30A8FFFF8F83002027BDFFF8A4
-:106800009064000D308200201040003A000000002B
-:10681000240B000100004821240A00013C088000EC
-:10682000350700708CE30000AF8300308F4C017897
-:106830000580FFFE3C0E80003C04080090843B6C09
-:1068400035C700708CEC00003C0508008CA5007476
-:10685000A3A400033C1908008F3900708FAD00001D
-:106860000183302300A63821000010210322782163
-:1068700000E6C02B01F8602101AE4025AFA8000062
-:106880003C010800AC2700743C010800AC2C0070EF
-:106890009346010A3C04080090843B6DA3A00002CB
-:1068A000A3A600018FA300003C0580FF3099007F64
-:1068B00034A2FFFF006278240019C60001F8702599
-:1068C000240D3000AF4E014C27BD0008AF4D0154E0
-:1068D000A7400158AF4B0148A7490144A74A0146C8
-:1068E0003C091000240AFF80A34A015203E000087B
-:1068F000AF4901788F4B0E1897460E1297450E1030
-:1069000030CAFFFF0A000E2F30A9FFFF8F85001845
-:106910002402008090A40085308300C0106200052E
-:106920008F86001C8F8800048F870008ACC800C8C1
-:10693000ACC700C403E00008000000003C0A0800E7
-:10694000254A37CC3C090800252938983C0808001E
-:1069500025082C4C3C07080024E739AC3C0608000D
-:1069600024C6363C3C05080024A533B43C0408008A
-:1069700024842FDC3C030800246336D43C02080046
-:10698000244234A83C010800AC2A3C383C010800F1
-:10699000AC293C343C010800AC283C303C010800E8
-:1069A000AC273C3C3C010800AC263C4C3C010800B8
-:1069B000AC253C443C010800AC243C403C010800B0
-:1069C000AC233C503C010800AC223C4803E00008EA
-:0469D00000000000C3
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-mips-06-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-mips-06-5.0.0.j3.fw.ihex
new file mode 100644
index 0000000..652e6c8
--- /dev/null
+++ b/firmware/bnx2/bnx2-mips-06-5.0.0.j3.fw.ihex
@@ -0,0 +1,5841 @@
+:10000000080001100800000000004CC8000000C8F3
+:1000100000000000000000000000000008004CC8C4
+:100020000000001400004D90080000880800000047
+:10003000000058D000004DA408005A400000008481
+:100040000000A674080058D0000001540000A6F873
+:10005000080031D808000000000070F00000A84C33
+:10006000000000000000000000000000080070F028
+:10007000000000240001193C080004880800040066
+:100080000000175C00011960000000000000000083
+:100090000000000000000000000000000000000060
+:1000A000080000A80800000000003B38000130BC38
+:1000B0000000000000000000000000000000000040
+:0800C000000000000000000038
+:0800C8000A00004400000000E2
+:1000D000000000000000000D636F6D352E302E30E3
+:1000E0006A33000005000002000000000000000369
+:1000F00000000014000000320000000300000000B7
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA600000000549
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C000000000000000000000000000000000002F
+:1001D000000000000000000000000000100000030C
+:1001E000000000000000000D0000000D3C020800AF
+:1001F00024424D003C03080024634DFCAC40000049
+:100200000043202B1480FFFD244200043C1D080005
+:1002100037BD7FFC03A0F0213C1008002610011020
+:100220003C1C0800279C4D000E000214000000003A
+:100230000000000D27BDFFE8AFBF0014AFB00010F5
+:100240009742010830437000240220001062000B26
+:10025000286220011440002F0000102124024000D9
+:1002600010620025000000002402600010620026D9
+:10027000000010210A0000948FBF001427500100D5
+:10028000920200091040001A240300013C020800F9
+:100290008C42002010400016000018210E00052B93
+:1002A00000000000960300083C06080094C64DBEFE
+:1002B0008E0400188F8200209605000C00031C009D
+:1002C00000661825AC440000AC450004240400017D
+:1002D000AC400008AC40000CAC400010AC40001436
+:1002E000AC4000180E000550AC43001C0000182163
+:1002F0000A000093006010210E0003BD0000000002
+:100300000A000093000010210E000F810000000081
+:10031000000010218FBF00148FB0001003E0000810
+:1003200027BD001827BDFFE0AFB00010AFBF001819
+:10033000AFB10014275001009203000B2402001AF1
+:10034000961100081462005B00002821322200018F
+:1003500010400008000000008E0200009603001408
+:10036000000211C200021040005A10210A0000DBF6
+:10037000A44300803C0208008C420020104000286A
+:10038000000000000E00052B00000000974201084D
+:100390009743010C8F8500203042003E3063FFFF01
+:1003A0000002140000431025ACA200008F4201009F
+:1003B0003C06080094C64DBEACA20004974301164B
+:1003C0009744010E3C02200000031C003084FFFF14
+:1003D00000641825ACA3000800C230259742011024
+:1003E0009743011224040001000214003063FFFF50
+:1003F00000431025ACA2000C974201143042FFFFCD
+:10040000ACA200108F420118ACA200149342010B61
+:10041000304200FFACA200180E000550ACA6001C34
+:100420003C0208008C420040244200013C010800CC
+:10043000AC2200403C0308008C63004432220002DE
+:1004400032240004246300013C010800AC23004472
+:10045000108000180002282B8F4202B804430008C5
+:100460008E0200203C0208008C4200602442000101
+:100470003C010800AC2200600A0000FB24050001DA
+:100480009603001600002821AF4202808E0200046D
+:10049000A7430284AF4202883C021000AF4202B878
+:1004A0003C0208008C42005C244200013C01080030
+:1004B000AC22005C8FBF00188FB100148FB0001009
+:1004C00000A0102103E0000827BD002027BDFFE0A9
+:1004D000AFB00010AFBF0018AFB10014275001003B
+:1004E0009203000B24020003961100081462006DB1
+:1004F000000020213222000110400008000000000E
+:100500008E02000096030014000211C20002104087
+:10051000005A10210A000142A44300803C02080056
+:100520008C42002010400025000000000E00052B2A
+:1005300000000000974201089743010C8F850020BE
+:100540003042003E3063FFFF0002140000431025DC
+:10055000ACA200008F4201003C06080094C64DBECC
+:10056000ACA20004974301169744010E3C02200000
+:1005700000031C003084FFFF00641825ACA30008B2
+:1005800000C2302597420110974301122404000154
+:10059000000214003063FFFF00431025ACA2000CE2
+:1005A000974201143042FFFFACA20010ACA000142F
+:1005B000ACA000180E000550ACA6001C3C020800C0
+:1005C0008C420040244200013C010800AC22004063
+:1005D0003C0208008C420044322300042442000103
+:1005E0003C010800AC2200441060001A32220002D4
+:1005F0008F4202B8044300088E0200203C0208002B
+:100600008C420060244200013C010800AC220060E2
+:100610000A0001772404000196030016000020213F
+:10062000AF4202808E020004A7430284AF420288D8
+:100630003C021000AF4202B83C0208008C42005C51
+:10064000244200013C010800AC22005C0A00017851
+:100650008FBF001810400013000020218F430104B9
+:100660003C026020AC4300148C420004240301FED1
+:10067000304203FF1443000B000020218F42010091
+:10068000000211C02442FFFC2C420008104000026E
+:100690002403000200031F403C026000AC436914C5
+:1006A000000020218FBF00188FB100148FB0001000
+:1006B0000080102103E0000827BD00208F430100C7
+:1006C0002402010050620003000311C20000000D6B
+:1006D000000311C200021040005A1021A440008003
+:1006E00003E00008000010219362000003E000080E
+:1006F000AF80000003E000080000102103E00008C4
+:1007000000001021240201001482000800000000F3
+:100710003C0208008C4200FC244200013C0108001D
+:10072000AC2200FC0A00019F30A200203C0208001D
+:100730008C420084244200013C010800AC22008469
+:1007400030A200201040000830A300103C02080036
+:100750008C420108244200013C010800AC2201083F
+:1007600003E0000800000000106000080000000026
+:100770003C0208008C420104244200013C010800B4
+:10078000AC22010403E00008000000003C02080065
+:100790008C420100244200013C010800AC2201000F
+:1007A00003E000080000000027BDFFE8AFBF001015
+:1007B0002744010094830008306200041040001BAD
+:1007C000306600028F4202B804410008240500018F
+:1007D0003C0208008C420060244200013C010800F9
+:1007E000AC2200600A0001EB8FBF00108C82002059
+:1007F0009483001600002821AF4202808C820004FE
+:10080000A7430284AF4202883C021000AF4202B804
+:100810003C0208008C42005C244200013C010800BC
+:10082000AC22005C0A0001EB8FBF001010C0000674
+:10083000006028218F4401000E00018F000000009D
+:100840000A0001EA240500018F8200088F43010499
+:1008500050430007000028218F4401000E00018F43
+:10086000000000008F420104AF8200080000282130
+:100870008FBF001000A0102103E0000827BD001862
+:100880003C0208008C420088274301009465000C5C
+:10089000244200013C010800AC2200888C6400184E
+:1008A0000345102190454000AF4400388C62001C85
+:1008B0002403FFF800052E000043102434420004F6
+:1008C000AF42003C3C020005AF4200300000000097
+:1008D0000000000000000000AF450404000000001C
+:1008E00000000000000000003C020006344200014D
+:1008F000AF420030000000000000000000000000D7
+:100900008F420000304200101040FFFD0000102117
+:1009100003E000080000000027BDFFE0AFB20018B0
+:100920003C036010AFBF001CAFB10014AFB00010AB
+:100930008C6450002402FF7F3C1A80000082202437
+:100940003484380C24020037AC6450003C12080098
+:1009500026524D38AF42000824020C80AF420024DA
+:100960003C1B80083C06080024C6062C02401021CF
+:100970002404001C2484FFFFAC4600000481FFFD1A
+:10098000244200043C0208002442016C3C0108009F
+:10099000AC224D403C020800244204043C01080003
+:1009A000AC224D443C020800244207B83C01080038
+:1009B000AC224D883C0208002442025C3C03080043
+:1009C000246306343C040800248406E03C05080047
+:1009D00024A53B503C010800AC224DA03C0208007D
+:1009E000244205F43C010800AC264D843C0108007B
+:1009F000AC254D943C010800AC234D9C3C01080003
+:100A0000AC244DA43C010800AC224DA83C010800D8
+:100A1000AC234D3C3C010800AC204D483C01080093
+:100A2000AC204D4C3C010800AC204D503C0108006E
+:100A3000AC204D543C010800AC204D583C0108004E
+:100A4000AC204D5C3C010800AC204D603C0108002E
+:100A5000AC244D643C010800AC204D683C0108000A
+:100A6000AC204D6C3C010800AC204D703C010800EE
+:100A7000AC204D743C010800AC204D783C010800CE
+:100A8000AC264D7C3C010800AC264D803C010800A2
+:100A9000AC204D8C3C010800AC254D903C01080079
+:100AA000AC234D980E0006BB000000003C02800005
+:100AB000344200708C420000AF8200143C030800F6
+:100AC0008C6300208F820004104300043C028000ED
+:100AD0000E0004F3AF8300043C0280003446007033
+:100AE0003C0308008C6300A03C0208008C4200A478
+:100AF000104300048F8400143C010800AC2300A4C0
+:100B0000A743009E8CCA00003C0308008C6300BC15
+:100B10003C0208008C4200B80144202300641821E4
+:100B2000000040210064202B0048102100441021C7
+:100B30003C010800AC2300BC3C010800AC2200B81A
+:100B40008F510000322200071040FFDCAF8A0014F2
+:100B50008CC600003C0508008CA500BC3C040800C5
+:100B60008C8400B800CA302300A628210000102180
+:100B700000A6302B00822021008620213227000190
+:100B80003C010800AC2500BC3C010800AC2400B8C6
+:100B900010E0001F322200028F420100AF4200200D
+:100BA0008F420104AF4200A89342010B0E0001885E
+:100BB000305000FF2E02001D544000040010108031
+:100BC0000E00018B0A0002C5000000000052102137
+:100BD0008C4200000040F8090000000010400005B1
+:100BE0003C0240008F4301043C026020AC430014EF
+:100BF0003C024000AF4201383C0208008C42003405
+:100C0000244200013C010800AC22003432220002E0
+:100C10001040000E322200048F4201400E00018875
+:100C2000AF4200200E00034B000000003C024000D9
+:100C3000AF4201783C0208008C4200382442000197
+:100C40003C010800AC220038322200041040FF981A
+:100C50003C0280008F4201800E000188AF420020DC
+:100C60008F43018024020F00146200050000000081
+:100C70008F420188A742009C0A0002FA3C02400011
+:100C80009362000024030050304200FF1443000828
+:100C90003C0240000E00032D000000005440000400
+:100CA0003C0240000E000E0D000000003C0240001F
+:100CB000AF4201B83C0208008C42003C24420001D3
+:100CC0003C010800AC22003C0A00027A3C02800091
+:100CD0003C0290003442000100822025AF440020F5
+:100CE0008F4200200440FFFE0000000003E00008E7
+:100CF000000000003C0280003442000100822025F8
+:100D000003E00008AF44002027BDFFE0AFB10014AE
+:100D1000AFB0001000808821AFBF00180E000302A2
+:100D200030B000FF9362007D022020210202802566
+:100D3000A370007D8F7000743C0280000E00030BD6
+:100D400002028024160000098FBF00188F4201F8AC
+:100D50000440FFFE24020002AF5101C0A34201C4BF
+:100D60003C021000AF4201F88FBF00188FB1001491
+:100D70008FB0001003E0000827BD002027BDFFE86A
+:100D8000AFBF0010974201843042020010400005BE
+:100D9000000020210E001042000000000A00034164
+:100DA000240400018F420188044000098FBF001015
+:100DB0008F4201883C03FF00004310243C030400E1
+:100DC00014430003240400019362003E8FBF00100F
+:100DD0000080102103E0000827BD00182402000154
+:100DE000A3600022A76200168F4401400A0003108E
+:100DF0002405000127BDFFE8AFBF0014AFB000100D
+:100E000093620000304400FF3883002038820030B5
+:100E10000003182B0002102B00621824106000033E
+:100E200024020050148200628FBF001493420148D4
+:100E3000304200FF2443FFFF2C6200051040005C9D
+:100E40008FBF0014000310803C03080024634CC8CB
+:100E5000004310218C420000004000080000000008
+:100E60000E0003028F4401408F70000C8F4201443A
+:100E70001602000224020001AF62000C0E00030BF8
+:100E80008F4401408F420144145000048FBF00146E
+:100E90008FB000100A000FB827BD00188F62000C39
+:100EA0000A0003B300000000976200108F43014462
+:100EB0003042FFFF1462000900000000240200011C
+:100EC000A76200108F420140AF4202003C021000B6
+:100ED000AF4202380A0003BA8FBF001497620010B5
+:100EE0000A0003B3000000000E0003028F4401401B
+:100EF000976200128F4301443050FFFF1603000237
+:100F000024020001A76200120E00030B8F4401406F
+:100F10008F420144160200048FBF00148FB00010EE
+:100F20000A00034527BD0018976200120A0003B3A8
+:100F300000000000976200148F4301443042FFFF1D
+:100F4000146200068FBF0014240200018FB000104D
+:100F5000A76200140A0012E227BD0018976200146D
+:100F60000A0003B300000000976200168F4301449B
+:100F70003042FFFF14620006240200018FBF0014FC
+:100F80008FB00010A76200160A000BAA27BD001838
+:100F900097620016144000068FBF00143C02080040
+:100FA0008C420070244200013C010800AC22007019
+:100FB0008FB0001003E0000827BD001827BDFFE830
+:100FC000AFBF0014AFB000108F500100936200005B
+:100FD00093430109304400FF2402001F106200A562
+:100FE0002862002010400018240200382862000AFD
+:100FF0001040000C2402000B286200081040002C56
+:1010000000000000046000E528620002144000288F
+:1010100024020006106200268FBF00140A0004B7E5
+:101020008FB000101062005E2862000B144000DCDC
+:101030008FBF00142402000E106200738FB00010E6
+:101040000A0004B700000000106200C028620039E6
+:101050001040000A2402008024020036106200CAF8
+:1010600028620037104000B424020035106200C12D
+:101070008FBF00140A0004B78FB000101062002B5D
+:101080002862008110400006240200C824020039B2
+:10109000106200B48FBF00140A0004B78FB00010B4
+:1010A000106200998FBF00140A0004B78FB00010BF
+:1010B0003C0208008C420020104000B98FBF001491
+:1010C0000E00052B000000008F4201008F830020DE
+:1010D0009745010C97460108AC6200008F4201045D
+:1010E0003C04080094844DBE00052C00AC62000452
+:1010F0008F4201180006340000C43025AC6200089D
+:101100008F42011C24040001AC62000C9342010ACE
+:1011100000A22825AC650010AC600014AC6000187B
+:10112000AC66001C0A00048D8FBF00143C0208004E
+:101130008C4200201040009A8FBF00140E00052B37
+:1011400000000000974401083C03080094634DBE72
+:101150009745010C000422029746010E8F82002061
+:10116000000426000083202500052C003C0300809D
+:1011700000A6282500832025AC400000AC400004D8
+:10118000AC400008AC40000CAC450010AC40001472
+:10119000AC400018AC44001C0A00048C240400017C
+:1011A0009742010C144000150000000093620005F6
+:1011B0003042001014400011000000000E00030235
+:1011C0000200202193620005020020213442001019
+:1011D0000E00030BA36200059362000024030020AD
+:1011E000304200FF1043006D020020218FBF001429
+:1011F0008FB000100A00105827BD00180000000D25
+:101200000A0004B68FBF00143C0208008C42002084
+:10121000104000638FBF00140E00052B000000007B
+:101220008F4201048F8300209744010C3C05080085
+:1012300094A54DBEAC6200009762002C000424000F
+:101240003042FFFF008220253C02400E00A22825EC
+:10125000AC640004AC600008AC60000CAC60001032
+:10126000AC600014AC600018AC65001C0A00048C73
+:10127000240400010E00030202002021A7600008E0
+:101280000E00030B02002021020020210E0003109B
+:10129000240500013C0208008C4200201040004060
+:1012A0008FBF00140E00052B000000009742010CB8
+:1012B0008F8300203C05080094A54DBE0002140059
+:1012C000AC700000AC620004AC6000088F64004C9D
+:1012D0003C02401F00A22825AC64000C8F62005025
+:1012E00024040001AC6200108F620054AC62001450
+:1012F000AC600018AC65001C8FBF00148FB00010EC
+:101300000A00055027BD0018240200205082002545
+:101310008FB000100E000FA202002021104000200C
+:101320008FBF0014020020218FB000100000282180
+:101330000A00031027BD0018020020218FBF0014EF
+:101340008FB000100A00061827BD00189745010C41
+:10135000020020218FBF00148FB000100A00063851
+:1013600027BD0018020020218FB000100A00065D82
+:1013700027BD00189345010D020020218FB00010F9
+:101380000A0006A727BD0018020020218FBF001405
+:101390008FB000100A00068327BD00188FBF00140D
+:1013A0008FB0001003E0000827BD00188F420278BC
+:1013B0000440FFFE2402000234840080AF44024057
+:1013C000A34202443C02100003E00008AF4202784E
+:1013D0003C04080094844DCA3C0208008C424DD461
+:1013E0003083FFFF000318C000431021AF42003CD0
+:1013F0003C0208008C424DD0AF4200383C02005005
+:1014000034420008AF42003000000000000000003D
+:10141000000000008F420000304200201040FFFD1D
+:10142000000000008F4204003C010800AC224DC0C7
+:101430008F4204043C010800AC224DC43C02002051
+:10144000AF420030000000003C02080094424DC84A
+:101450003C03080094634DCC3C05080094A54DCE98
+:1014600024840001004310213083FFFF3C01080069
+:10147000A4224DC83C010800A4244DCA14650003F1
+:10148000000000003C010800A4204DCA03E0000851
+:10149000000000003C05000A27BDFFE803452821A5
+:1014A0003C04080024844DB0AFBF00100E0005B509
+:1014B0002406000A3C02080094424DB23C03080096
+:1014C00094634DCE3042000F2442000300431804C1
+:1014D00024027FFF0043102B10400002AF83001C4A
+:1014E0000000000D0E0004C2000000003C020800D5
+:1014F00094424DBA8FBF001027BD001803E00008CA
+:10150000A74200A23C02000A0342102194430006B5
+:101510003C02080094424DBA3C010800A4234DB699
+:10152000004310238F83001C0002140000021403E8
+:101530000043102B03E000083842000127BDFFE8FC
+:10154000AFBF00103C02000A034210219442000683
+:101550003C010800A4224DB60E00050F000000005B
+:101560005440FFF93C02000A8FBF001003E000085E
+:1015700027BD001827BDFFE8AFBF00100E00050F04
+:101580000000000010400003000000000E00051DD8
+:10159000000000003C0208008C424DC08FBF0010CC
+:1015A00027430400AF4200383C0208008C424DC47F
+:1015B00027BD0018AF830020AF42003C3C0200056D
+:1015C000AF42003003E00008AF8000188F8200189F
+:1015D0003C0300060002114000431025AF420030DA
+:1015E0000000000000000000000000008F4200002A
+:1015F000304200101040FFFD27420400AF8200205F
+:1016000003E00008AF8000183C0608008CC64DC4FB
+:101610008F8500188F8300203C02080094424DBA49
+:1016200027BDFFE024A5000124630020244200011F
+:1016300024C70020AFB10014AFB00010AFBF001836
+:10164000AF850018AF8300203C010800A4224DBAEA
+:10165000309000FF3C010800AC274DC404C10008D5
+:101660000000882104E00006000000003C020800A1
+:101670008C424DC0244200013C010800AC224DC008
+:101680003C02080094424DBA3C03080094634DC8E4
+:101690000010202B004310262C420001004410258E
+:1016A000144000048F830018240200101462000FFD
+:1016B000000000000E000541241100013C03080059
+:1016C00094634DBA3C02080094424DC81462000372
+:1016D000000000000E0004C200000000160000031D
+:1016E000000000000E00052B000000003C03080075
+:1016F00094634DBE3C02080094424DBC246300013B
+:101700003064FFFF3C010800A4234DBE1482000397
+:10171000000000003C010800A4204DBE120000069D
+:10172000000000003C02080094424DBAA74200A20B
+:101730000A0005A3022010210E00050F0000000082
+:1017400010400004022010210E00051D00000000C2
+:10175000022010218FBF00188FB100148FB000102D
+:1017600003E0000827BD00203084FFFF30A5FFFF05
+:1017700000001821108000070000000030820001E6
+:101780001040000200042042006518210A0005AB49
+:101790000005284003E000080060102110C000068A
+:1017A00024C6FFFF8CA2000024A50004AC82000028
+:1017B0000A0005B52484000403E0000800000000CE
+:1017C00010A0000824A3FFFFAC860000000000006A
+:1017D000000000002402FFFF2463FFFF1462FFFAF1
+:1017E0002484000403E0000800000000240200013B
+:1017F000AF62000CA7620010A7620012A76200147B
+:1018000003E00008A76200163082007F0342102127
+:101810003C08000E004818213C0208008C420020C1
+:1018200027BDFFD82407FF80AFB3001CAFB200185C
+:10183000AFB10014AFB00010AFBF00200080802116
+:1018400030B100FF0087202430D200FF1040002F6D
+:1018500000009821AF44002C906200002403005047
+:10186000304200FF1443000E000000003C0208005C
+:101870008C4200E00202102100471024AF42002CED
+:101880003C0208008C4200E0020210213042007F3E
+:101890000342102100481021944200D43053FFFF2E
+:1018A0000E00052B000000003C02080094424DBED3
+:1018B0008F8300200011340000C2302500122C005C
+:1018C0003C02400000C2302534A50001AC7000008D
+:1018D0008FBF0020AC6000048FB20018AC7300080A
+:1018E0008FB10014AC60000C8FB3001CAC6500100D
+:1018F0008FB00010AC60001424040001AC6000182C
+:1019000027BD00280A000550AC66001C8FBF0020D0
+:101910008FB3001C8FB200188FB100148FB000106D
+:1019200003E0000827BD00289343010F24020010A4
+:101930001062000E2865001110A00007240200129A
+:10194000240200082405003A10620006000030213D
+:1019500003E0000800000000240500351462FFFCCD
+:10196000000030210A0005D0000000008F42007402
+:1019700024420FA003E00008AF62000C27BDFFE87F
+:10198000AFBF00100E000310240500018FBF001030
+:1019900024020001A762001227BD001824020001E2
+:1019A00003E00008A360002227BDFFE0AFB10014F0
+:1019B000AFB00010AFBF001830B1FFFF0E00030240
+:1019C000008080219362003F24030004304200FF26
+:1019D0001443000C02002021122000082402000AF7
+:1019E0000E0005C900000000936200052403FFFEFD
+:1019F00000431024A362000524020012A362003FEA
+:101A0000020020210E00030BA360008116200003BA
+:101A1000020020210E00062D0000000002002021FF
+:101A2000322600FF8FBF00188FB100148FB0001056
+:101A3000240500380A0005D027BD002027BDFFE09F
+:101A4000AFBF001CAFB20018AFB10014AFB00010B0
+:101A50000E000302008080210E0005C90000000076
+:101A60009362003F24120018305100FF123200032D
+:101A70000200202124020012A362003F93620005AD
+:101A80002403FFFE004310240E00030BA362000595
+:101A9000020020212405002016320007000030211A
+:101AA0008FBF001C8FB200188FB100148FB00010D0
+:101AB0000A00031027BD00208FBF001C8FB2001842
+:101AC0008FB100148FB00010240500390A0005D032
+:101AD00027BD002027BDFFE8AFB00010AFBF001446
+:101AE0009742010C2405003600808021144000102C
+:101AF000304600FF0E000302000000002402001226
+:101B0000A362003F93620005344200100E0005C935
+:101B1000A36200050E00030B020020210200202119
+:101B20000E000310240500200A00069C000000009F
+:101B30000E0005D0000000000E000302020020216C
+:101B4000936200232403FF9F0200202100431024FE
+:101B50008FBF00148FB00010A36200230A00030B94
+:101B600027BD001827BDFFE0AFBF0018AFB10014BC
+:101B7000AFB0001030B100FF0E00030200808021E2
+:101B8000240200120E0005C9A362003F0E00030BE1
+:101B90000200202102002021022030218FBF0018E6
+:101BA0008FB100148FB00010240500350A0005D055
+:101BB00027BD0020A380002C03E00008A380002D97
+:101BC0008F4202780440FFFE8F820034AF42024011
+:101BD00024020002A34202443C02100003E0000879
+:101BE000AF4202783C0360008C625400304200082F
+:101BF0001440FFFD000000008C625408AF82000C0E
+:101C000024020052AC605408AC645430AC625434CA
+:101C10002402000803E00008AC6254003C026000AB
+:101C20008C42540030420008104000053C03600024
+:101C30008C625400304200081440FFFD0000000098
+:101C40008F83000C3C02600003E00008AC435408A2
+:101C500090A3000024020005008040213063003F73
+:101C600000004821146200050000502190A2001CD1
+:101C700094A3001E304900FF306AFFFFAD00000C46
+:101C8000AD000010AD000024950200148D05001C6D
+:101C90008D0400183042FFFF00491023000211009C
+:101CA000000237C3004038210086202300A2102BF9
+:101CB0000082202300A72823AD05001CAD040018D6
+:101CC000A5090014A5090020A50A001603E00008D4
+:101CD000A50A00228F4201F80440FFFE2402000200
+:101CE000AF4401C0A34201C43C02100003E000085D
+:101CF000AF4201F83C0208008C4200B427BDFFE867
+:101D0000AFBF001424420001AFB000103C01080036
+:101D1000AC2200B48F4300243C02001F30AA00FF15
+:101D20003442FF8030D800FF006280240080F82118
+:101D300030EF00FF1158003B01405821240CFF8078
+:101D40003C19000A3163007F000310C000031940F2
+:101D5000006218213C0208008C4200DC256800016A
+:101D6000310D007F03E21021004310213043007F3A
+:101D700003431821004C102400794821AF4200246D
+:101D80008D220024016C1824006C7026AD22000CFA
+:101D90008D220024310800FFAD220010952200148E
+:101DA000952300208D27001C3042FFFF3063FFFF8A
+:101DB0008D2600180043102300021100000227C3E3
+:101DC0000040282100C4302300E2102B00C2302341
+:101DD00000E53823AD27001CAD2600189522002011
+:101DE000A522001495220022154B000AA5220016F8
+:101DF0008D2300248D2200082546000131450080F6
+:101E00001462000430C4007F108F000238AA0080E2
+:101E100000C0502151AF000131C800FF1518FFC9A3
+:101E2000010058218F8400343082007F0342182142
+:101E30003C02000A006218212402FF800082202454
+:101E4000AF440024A06A0079A06A00838C6200502D
+:101E50008F840034AC6200708C6500743C027FFF9C
+:101E60003442FFFF00A228240E000703AC65007473
+:101E7000AF5000248FBF00148FB0001003E00008A3
+:101E800027BD001827BDFFC0AFBE0038AFB7003474
+:101E9000AFB5002CAFB20020AFB1001CAFB000183E
+:101EA000AFBF003CAFB60030AFB40028AFB30024E2
+:101EB0008F4500248F4600288F43002C3C02001FD2
+:101EC0003442FF800062182400C230240080A82120
+:101ED000AFA3001400A2F0240E0006C7AFA60010A6
+:101EE0003C0208008C4200E02410FF80036088213F
+:101EF00002A2102100501024AF4200243C0208002E
+:101F00008C4200E002A210213042007F03421821DF
+:101F10003C02000A00629021924200D29363008446
+:101F2000305700FF306300FF2402000110620034CC
+:101F30000360202124020002146200360000000029
+:101F40000E0012AE024028219223008392220083C9
+:101F50003063007F3042007F000210C00003194050
+:101F6000006218213C0208008C4200DC02A2102111
+:101F70000043382100F01024AF4200289225007859
+:101F80009224008330E2007F034218213C02000CBF
+:101F900014850007006280212402FFFFA24200F1A5
+:101FA0002402FFFFA64200F20A0007BF2402FFFF3F
+:101FB00096020020A24200F196020022A64200F200
+:101FC0008E020024AE4200F492220083A24200F06E
+:101FD0008E4200C8AE4200FC8E4200C4AE4200F801
+:101FE0008E220050AE4201008E4200CCAE4201046F
+:101FF000922200853042003F0A00081A3442004015
+:102000000E0012D102402821922200850A00081AEF
+:102010003042003F936200852403FFDF3042003FDF
+:10202000A36200859362008500431024A3620085AB
+:102030009363008393620078307400FF304200FFA6
+:1020400010540036240AFF803C0C000C3283007FC1
+:10205000000310C000031940006218213C02080070
+:102060008C4200DC268800013109007F02A2102189
+:102070000043382130E2007F0342182100EA102497
+:10208000AF420028006C80218E020024028A1824AE
+:10209000006A5826AE02000C8E020024310800FFB0
+:1020A000AE02001096020014960300208E07001C5A
+:1020B0003042FFFF3063FFFF8E06001800431023FD
+:1020C00000021100000227C30040282100C4302371
+:1020D00000E2102B00C2302300E53823AE07001CBD
+:1020E000AE06001896020020A602001496020022F6
+:1020F000A602001692220079304200FF1054000719
+:102100000000000051370001316800FF9222007882
+:10211000304200FF1448FFCD0100A021922200832D
+:10212000A22200798E2200500A00087AAE220070A6
+:10213000A22200858E22004C2405FF80AE42010CB5
+:102140009222008534420020A2220085924200D1D2
+:102150003C0308008C6300DC305400FF3C020800A4
+:102160008C4200E400143140001420C002A3182166
+:1021700000C4202102A21021006438210046102151
+:102180000045182400E52824AF450028AF43002C63
+:102190003042007F924400D030E3007F0342282188
+:1021A000034318213C02000C006280213C02000E17
+:1021B000309600FF00A298211296002A000000002D
+:1021C0008E02000C02002021026028211040002510
+:1021D000261000280E0006E2000000009262000DAA
+:1021E00026830001307400FF3042007FA262000DA0
+:1021F0002404FF801697FFF0267300203C0208009D
+:102200008C4200DC0000A02102A210210044102416
+:10221000AF4200283C0208008C4200E43C03080066
+:102220008C6300DC02A2102100441024AF42002C79
+:102230003C0208008C4200E402A318213063007FB6
+:1022400002A210213042007F0342202103431821C3
+:102250003C02000C006280213C02000E0A00083C97
+:10226000008298218E4200D8AE2200508E4200D8C3
+:10227000AE22007092250083924600D19223008303
+:10228000924400D12402FF8000A228243063007F02
+:10229000308400FF00A628250064182A1060000280
+:1022A00030A500FF38A50080A2250083A225007973
+:1022B0000E0006D5000000009222007E02A0202120
+:1022C000A222007A8E2300743C027FFF3442FFFF7B
+:1022D000006218240E000703AE2300748FA20010C2
+:1022E000AF5E00248FBF003CAF4200288FBE003895
+:1022F0008FA200148FB700348FB600308FB5002C3A
+:102300008FB400288FB300248FB200208FB1001C3F
+:102310008FB0001827BD004003E00008AF42002C3A
+:1023200090A2000024420001A0A200003C0308008B
+:102330008C6300F4304200FF1443000F0080302112
+:10234000A0A000003C0208008C4200E48F8400340E
+:10235000008220213082007F034218213C02000CC1
+:10236000006218212402FF8000822024ACC30000F8
+:1023700003E00008AF4400288C82000024420020C3
+:1023800003E00008AC82000094C200003C08080092
+:10239000950800CA30E7FFFF0080482101021021A4
+:1023A000A4C2000094C200003042FFFF00E2102BE4
+:1023B00054400001A4C7000094A200003C030800A0
+:1023C0008C6300CC24420001A4A2000094A200006F
+:1023D0003042FFFF544300078F8600280107102B6F
+:1023E000A4A000005440000101003821A4C700004F
+:1023F0008F8600288CC4001CAF44003C94A20000CF
+:102400008F43003C3042FFFF000210C000621821E1
+:10241000AF43003C8F42003C008220231880000420
+:10242000000000008CC200180A0008DB24420001F2
+:102430008CC20018AF4200383C02005034420010F9
+:10244000AF4200300000000000000000000000006B
+:102450008F420000304200201040FFFD00000000CD
+:102460008F420404AD2200048F420400AD2200001C
+:102470003C020020AF42003003E0000800000000F2
+:1024800027BDFFE0AFB20018AFB10014AFB000102D
+:10249000AFBF001C94C2000000C080213C120800A5
+:1024A000965200C624420001A602000096030000D6
+:1024B00094E2000000E03021144300058FB10030A9
+:1024C0000E0008B0024038210A00090D000000008B
+:1024D0008C8300048C8200042442004004610007C5
+:1024E000AC8200048C820004044000040000000060
+:1024F0008C82000024420001AC82000096020000A1
+:102500003042FFFF50520001A6000000962200005A
+:1025100024420001A62200008F820028962300009A
+:1025200094420016144300048FBF001C24020001D3
+:10253000A62200008FBF001C8FB200188FB10014BC
+:102540008FB0001003E0000827BD00208F8900280D
+:1025500027BDFFE0AFBF00188D22002827480400E8
+:1025600030E700FFAF4200388D22002CAF880030EA
+:10257000AF42003C3C020005AF42003000000000CA
+:10258000000000000000000000000000000000004B
+:10259000000000008C82000C8C82000CAD02000058
+:1025A0008C820010AD0200048C820018AD0200087D
+:1025B0008C82001CAD02000C8CA20014AD02001035
+:1025C0008C820020AD02001490820005304200FF92
+:1025D00000021200AD0200188CA20018AD02001C0F
+:1025E0008CA2000CAD0200208CA20010AD020024D1
+:1025F0008CA2001CAD0200288CA20020AD02002C91
+:10260000AD060030AD000034978300263402FFFF92
+:1026100014620002006020213404FFFF10E000116A
+:10262000AD040038952300369524003624020001BD
+:102630003063FFFF000318C2006918219065004055
+:10264000308400070082100400451025A06200407D
+:102650008F820028944200563042FFFF0A0009741E
+:10266000AD02003C9523003695240036240200017B
+:102670003063FFFF000318C2006918219065004015
+:102680003084000700821004000210270045102447
+:10269000A0620040AD00003C00000000000000000F
+:1026A000000000003C02000634420040AF4200300F
+:1026B0000000000000000000000000008F42000049
+:1026C000304200101040FFFD8F860028AF88003098
+:1026D00024C2005624C7003C24C4002824C500326C
+:1026E00024C600360E0008EEAFA200108FBF0018FF
+:1026F00003E0000827BD00208F8300243C0608006B
+:102700008CC600E88F82003430633FFF00031980DD
+:1027100000461021004310212403FF803046007F33
+:1027200000431024AF420028034618213C02000C4D
+:102730000062302190C2000D30A500FF000038215A
+:1027400034420010A0C2000D8F8900288F8A002417
+:1027500095230036000A138230480003240200014A
+:10276000A4C3000E1102000B290200021040000554
+:10277000240200021100000C240300010A0009B821
+:102780000000182111020006000000000A0009B82C
+:10279000000018218CC2002C0A0009B82443000153
+:1027A0008CC20014244300018CC200180043102B7B
+:1027B00050400009240700012402002714A200034E
+:1027C000000000000A0009C4240700019522003E11
+:1027D00024420001A522003E000A13823043000378
+:1027E0002C620002104000090080282114600004BF
+:1027F0000000000094C200360A0009D43046FFFFF2
+:102800008CC600380A0009D400802821000030213D
+:102810003C04080024844DD80A000921000000006F
+:10282000274901008D22000C95230006012020215C
+:10283000000216023046003F3063FFFF24020027EB
+:1028400000C0282128C7002810C2000EAF83002432
+:1028500010E00008240200312402002110C2000907
+:102860002402002510C200079382002D0A0009F3FC
+:102870000000000010C200059382002D0A0009F339
+:10288000000000000A00098C000000000A0006BEDB
+:102890000000000095230006912400058D25000C02
+:1028A0008D2600108D2700188D28001C8D290020F2
+:1028B000244200013C010800A4234DDE3C01080035
+:1028C000A0244DDD3C010800AC254DE43C0108008E
+:1028D000AC264DE83C010800AC274DF03C01080057
+:1028E000AC284DF43C010800AC294DF803E0000889
+:1028F000A382002D8F87002827BDFFC0AFB300340F
+:10290000AFB20030AFB1002CAFB00028AFBF00387D
+:102910003C0208008C4200D094E3003030B0FFFF4E
+:10292000005010073045FFFF3063FFFF00C09821C3
+:10293000A7A200103C110800963100C614A300069F
+:102940003092FFFF8CE2002424420030AF42003C72
+:102950000A000A2C8CE2002094E200323042FFFF91
+:1029600054A2000827A400188CE2002C2442003056
+:10297000AF42003C8CE20028AF4200380A000A3A1D
+:102980008F84002827A5001027A6002002203821C8
+:102990000E0008B0A7A000208FA20018244200302B
+:1029A000AF4200388FA2001CAF42003C8F84002849
+:1029B0003C020005AF4200309482003427430400FB
+:1029C0003042FFFF0202102B14400007AF8300309B
+:1029D0009482005494830034020210210043102397
+:1029E0000A000A4E3043FFFF94830054948200345F
+:1029F0000223182100501023006218233063FFFFC8
+:102A0000948200163042FFFF1443000300000000D0
+:102A10000A000A5C24030001948200163042FFFF82
+:102A20000043102B104000058F8200309482001666
+:102A3000006210233043FFFF8F820030AC53000050
+:102A4000AC400004AC520008AC43000C3C02000651
+:102A500034420010AF4200300000000000000000CF
+:102A6000000000008F420000304200101040FFFDC7
+:102A7000001018C20064182190650040320400075D
+:102A8000240200018FBF00388FB300348FB20030B2
+:102A90008FB1002C8FB00028008210040045102553
+:102AA00027BD004003E00008A062004027BDFFA84A
+:102AB000AFB60050AFB5004CAFB40048AFB3004460
+:102AC000AFB1003CAFBF0054AFB20040AFB0003870
+:102AD0008C9000003C0208008C4200E88F86003495
+:102AE000960300022413FF8000C2302130633FFFB1
+:102AF0000003198000C3382100F3102490B20000B5
+:102B0000AF42002C9203000230E2007F03423021EA
+:102B10003C02000E00C28821306300C02402004045
+:102B20000080A82100A0B021146200260000A0218E
+:102B30008E3400388E220018144000022402000156
+:102B4000AE2200189202000D304200201440001501
+:102B50008F8200343C0308008C6300DC001238C014
+:102B6000001231400043102100C7302100463821B7
+:102B700030E300073C02008030E6007800C23025D8
+:102B80000343182100F31024AF4208002463090016
+:102B9000AF4608108E2200188C63000800431021F5
+:102BA000AE2200188E22002C8E2300182442000131
+:102BB0000062182B1060003D000000000A000B109E
+:102BC00000000000920300022402FFC00043102412
+:102BD000304200FF1440000524020001AE2200181C
+:102BE000962200360A000AF93054FFFF8E220014A4
+:102BF00024420001AE2200189202000000021600DA
+:102C000000021603044100290000000096020002A1
+:102C100027A4001000802821A7A200169602000217
+:102C200024070001000030213042FFFFAF82002462
+:102C30000E000921AFA0001C960300023C0408000E
+:102C40008C8400E88F82003430633FFF00031980DA
+:102C500000441021004310213043007F3C05000C4C
+:102C60000053102403431821AF42002800651821A7
+:102C70009062000D001221403042007FA062000DE2
+:102C80003C0308008C6300E48F8200340043102171
+:102C90000044382130E2007F03421021004510211A
+:102CA00000F31824AF430028AEA200009222000DCA
+:102CB000304200101040001302A020218F83002812
+:102CC0008EA40000028030219462003E2442FFFF67
+:102CD000A462003E948400029625000E3084FFFF1B
+:102CE0000E000A0B30A5FFFF8F82002894430034AA
+:102CF0009622000E1443000302A0202124020001AA
+:102D0000A382002C02C028210E00089600000000BB
+:102D10008FBF00548FB600508FB5004C8FB4004861
+:102D20008FB300448FB200408FB1003C8FB00038A9
+:102D300003E0000827BD00588F82002827BDFFD080
+:102D4000AFB40028AFB20020AFBF002CAFB3002457
+:102D5000AFB1001CAFB00018904400D0904300D138
+:102D60000000A021309200FFA3A30010306300FFF9
+:102D70008C5100D88C5300DC1072002B240200010F
+:102D80003C0308008C6300E493A400108F8200349D
+:102D90002406FF800004214000431021004410213C
+:102DA0003043007F00461024AF420028034318211F
+:102DB0003C02000C006218218C62000427A400145D
+:102DC00027A5001002228021027010230440001564
+:102DD000AFA300149062000D00C21024304200FF27
+:102DE00014400007020088219062000D3442004028
+:102DF0000E000896A062000D0A000B5593A2001069
+:102E00000E000A79241400018F830028AC7000D8CA
+:102E100093A20010A06200D193A200101452FFD818
+:102E20000000000024020001168200048FBF002C65
+:102E30000E0006BE000000008FBF002C8FB40028DB
+:102E40008FB300248FB200208FB1001C8FB0001808
+:102E500003E0000827BD003027BDFFD8AFB3001C3A
+:102E6000AFB20018AFB10014AFB00010AFBF002078
+:102E70000080982100E0802130B1FFFF0E00052B7B
+:102E800030D200FF00000000000000000000000041
+:102E90008F820020AC510000AC520004AC530008FB
+:102EA000AC40000CAC400010AC400014AC4000182A
+:102EB0003C03080094634DBE02038025AC50001C07
+:102EC00000000000000000000000000024040001D9
+:102ED0008FBF00208FB3001C8FB200188FB1001479
+:102EE0008FB000100A00055027BD002827BDFFE85D
+:102EF000AFB00010AFBF001430A5FFFF30C600FF19
+:102F00000080802124020C80AF42002400000000D9
+:102F100000000000000000000000000000000000B1
+:102F20000E000B64000000003C040800248400E054
+:102F30008C8200002403FF808FBF00140202102146
+:102F400000431024AF4200248C8200003C03000A9E
+:102F5000020280213210007F035010218FB0001038
+:102F60000043102127BD001803E00008AF820028AD
+:102F700027BDFFE8AFBF00108F4401403C030800AD
+:102F80008C6300E02402FF80AF84003400831821AA
+:102F900000621024AF4200243C020008034240219A
+:102FA000950500023063007F3C02000A03431821AC
+:102FB0000062182130A5FFFF3402FFFF000030211E
+:102FC0003C07602010A20006AF8300282402FFFF08
+:102FD000A5020002946500D40E000B8930A5FFFF06
+:102FE0008FBF001024020C8027BD001803E00008EA
+:102FF000AF4200243C020008034240219502000237
+:103000003C0A0800954A00C63046FFFF14C000077E
+:103010003402FFFF8F8200288F8400343C07602039
+:10302000944500D40A000BF230A5FFFF10C2002423
+:103030008F87002894E2005494E400163045FFFF87
+:1030400000A6102300A6182B3089FFFF1060000493
+:103050003044FFFF00C51023012210233044FFFF3E
+:10306000008A102B1040000C012A102324020001BA
+:10307000A50200162402FFFFA502000294E500D479
+:103080008F8400340000302130A5FFFF3C07602012
+:103090000A000B89000000000044102A10400008BC
+:1030A00000000000950200163042000110400004AC
+:1030B000000000009742007E24420014A502001682
+:1030C00003E00008000000008F84002827BDFFE017
+:1030D000AFBF0018948200349483003E1060001A41
+:1030E0003048FFFF9383002C240200011462002764
+:1030F0008FBF00188F820028000818C2310800070F
+:10310000006218212447003A244900542444002036
+:10311000244500302446003490620040304200FFD5
+:103120000102100730420001104000168FBF001846
+:103130000E0008EEAFA900108F82002894420034E0
+:103140000A000C0B3048FFFF948300369482003451
+:103150001043000E8FBF001894820036A482003402
+:1031600094820056A48200548C82002CAC820024ED
+:1031700094820032A48200309482003CA482003AFF
+:103180008FBF00180A000BCB27BD002003E000080A
+:1031900027BD002027BDFFE8AFBF00108F4A010008
+:1031A0003C0508008CA500E03C02080090424DE47C
+:1031B0003C0C0800958C4DDE01452821304B003F2A
+:1031C00030A2007F03424021396900323C02000AEC
+:1031D0003963003F2C630001010240212D290001C9
+:1031E0002402FF8000A2282401234825AF8A00344E
+:1031F00000801821AF4500240000302100802821E4
+:1032000024070001AF8800283C04080024844DD81E
+:10321000AF8C002415200007A380002D240200207D
+:103220005562000F006020213402FFFF5582000C20
+:10323000006020212402002015620005000000002B
+:103240008C6300142402FFFF1062000700000000DE
+:103250000E000921000000000A000C6800000000B8
+:103260000E00098C016028210E000C0000000000F7
+:103270008FBF001024020C8027BD001803E0000857
+:10328000AF4200243C0208008C4200E027BDFFA0B2
+:10329000AFB1003C008210212411FF80AFBE005866
+:1032A000AFB70054AFB20040AFB00038AFBF005C62
+:1032B000AFB60050AFB5004CAFB40048AFB3004458
+:1032C000005110248F4800248F4900288F47002880
+:1032D000AF4200243C0208008C4200E000809021B4
+:1032E00024060006008210213042007F034218218C
+:1032F0003C02000A006280213C02001F3442FF8031
+:1033000000E2382427A40010260500F00122F02452
+:103310000102B8240E0005B5AFA700308FA2001837
+:10332000AE0200C48FA2001CAE0200C88FA200240F
+:10333000AE0200CC93A40010920300D12402FF80BF
+:103340000082102400431025304900FF3083007FA5
+:103350003122007F0062102A10400004000310C0D8
+:1033600001311026304900FF000310C0000319404E
+:10337000006218213C0208008C4200DC920400D25A
+:10338000024210210043102100511024AF420028B6
+:1033900093A300103063007F000310C000031940A6
+:1033A000006218213C0208008C4200DC024210211D
+:1033B000004310213042007F034218213C02000CE0
+:1033C000006240218FA300142402FFFF106200302E
+:1033D000309500FF93A2001195030014304400FFC4
+:1033E0003063FFFF0064182B1060000D0000000028
+:1033F000950400148D07001C8D0600183084FFFF13
+:1034000000442023000421000000102100E43821A2
+:1034100000E4202B00C230210A000CE200C430215D
+:10342000950400148D07001C8D0600183084FFFFE2
+:1034300000822023000421000000102100801821B8
+:1034400000C2302300E4202B00C4302300E33823E3
+:10345000AD07001CAD06001893A20011A5020014D0
+:1034600097A20012A50200168FA20014AD02001050
+:103470008FA20014AD02000C93A20011A50200203F
+:1034800097A20012A50200228FA20014AD02002410
+:103490002406FF80024610243256007FAF420024EB
+:1034A000035618213C02000A006280218E02004C63
+:1034B0008FA200203124007F000428C0AE020050FB
+:1034C0008FA200200004214000852821AE02007058
+:1034D00093A2001001208821A202008393A2001071
+:1034E000A2020079920200853042003FA2020085CC
+:1034F0003C0208008C4200DC0242102100451021F1
+:1035000000461024AF42002C3C0208008C4200E42C
+:103510003C0308008C6300DC0242102100441021AF
+:1035200000461024AF4200283C0208008C4200E410
+:103530000243182100651821024210210044102185
+:103540003042007F3063007F93A5001003422021AA
+:10355000034318213C02000E006240213C02000C93
+:1035600010B1008C008248213233007F16600019B0
+:103570002404FF803C0208008C4200DC024210213F
+:1035800000441024AF42002C3C0208008C4200E4AE
+:103590003C0308008C6300DC02421021004410242C
+:1035A000AF4200283C0208008C4200E4024318218C
+:1035B0003063007F024210213042007F034220210D
+:1035C000034318213C02000E006240213C02000C23
+:1035D000008248219124000D2414FF800000102156
+:1035E00000942025A124000D9504000295050014E7
+:1035F0008D07001C3084FFFF30A5FFFF8D060018EB
+:10360000008520230004210000E4382100C230217D
+:1036100000E4202B00C43021AD07001CAD060018CB
+:1036200095020002A5020014A50000168D020008F4
+:10363000AD0200108D020008AD02000C95020002E0
+:10364000A5020020A50000228D020008AD02002482
+:103650009122000D3042004010400042262200011D
+:103660003C0208008C4200E0A3B300283C10000A92
+:103670000242102100541024AF4200243C020800F2
+:103680008C4200E0A380002C27A4002C02421021D1
+:103690003042007F03421821007018218C6200D84C
+:1036A0008D26000427A50028AFA9002C0046102174
+:1036B000AC6200D80E000A79AF83002893A30028DB
+:1036C0008F8200280E0006BEA04300D10E000C0021
+:1036D0000000000002541024AF4200243C02080005
+:1036E0008C4200DC00132940001320C000A42021DC
+:1036F000024210210044102100541024AF42002C3B
+:103700003C0208008C4200E43C0308008C6300DCAF
+:10371000035630210242102100451021005410248C
+:10372000AF4200283C0208008C4200E4024318210A
+:103730000064182102421021004510213042007F10
+:103740003063007F03422021034318213C02000E16
+:10375000006240213C02000C00D080210082482100
+:10376000262200013043007F14750005304400FF1D
+:103770002403FF800223102400431026304400FF5E
+:1037800093A2001000808821250800281444FF76A9
+:103790002529002093A400108FA300142402FFFF0A
+:1037A0001062000A308900FF248200012483000196
+:1037B0003042007F14550005306900FF2403FF806C
+:1037C0000083102400431026304900FF9202007845
+:1037D000305300FF11330032012088213C020800E1
+:1037E0008C4200DC3225007F000520C00005294006
+:1037F00000A42021024210212406FF800044102151
+:1038000000461024AF42002C3C0308008C6300DC0F
+:103810003C0208008C4200E40243182102421021BD
+:103820000045102100641821004610243063007FF9
+:10383000AF420028034318213C02000E00624021E1
+:103840003C0208008C4200E48D06000C010020219F
+:1038500002421021004510213042007F034218210E
+:103860003C02000C0062482110C0000D01202821FC
+:103870000E0006E2000000002402FF80022218244D
+:1038800026240001006228263082007F14550002A1
+:10389000308300FF30A300FF1473FFD00060882145
+:1038A0008E0300743C027FFF3442FFFF0062182445
+:1038B000AE0300740E00070302402021AF5700241E
+:1038C0008FA20030AF5E00288FBF005C8FBE005813
+:1038D0008FB700548FB600508FB5004C8FB400489E
+:1038E0008FB300448FB200408FB1003C8FB00038DE
+:1038F00027BD006003E00008AF42002C27BDFFD8C1
+:10390000AFB1001CAFBF0020AFB000182751018835
+:10391000922200032408FF803C03000A3047007F06
+:10392000A3A700108F4601803C0208008C4200E0F3
+:10393000AF86003400C2282100A81024AF42002422
+:103940009224000030A2007F034210210043102186
+:10395000AF8200283084007F2402000214820025F8
+:10396000000719403C0208008C4200E400C210210C
+:103970000043282130A2007F0342182100A8102410
+:10398000AF4200283C02000C006218219062000D3A
+:10399000AFA3001400481025A062000D8FA30014EF
+:1039A0009062000D304200405040006A8FBF0020FE
+:1039B0008F860028A380002C27A400148CC200D876
+:1039C0008C63000427A50010004310210E000A7923
+:1039D000ACC200D893A300108F8200280E0006BE50
+:1039E000A04300D10E000C00000000000A000EA34E
+:1039F0008FBF00200E0006C700C020210E0006D594
+:103A0000000000003C0200080342802192230001D4
+:103A10009202007B1443004F8FBF002092220000CF
+:103A20003044007F24020004108200172882000521
+:103A30001040000624020005240200031082000743
+:103A40008FB1001C0A000EA40000000010820012BA
+:103A50008FBF00200A000EA48FB1001C92050083C6
+:103A6000920600788E0700748F84003430A500FF22
+:103A700000073E0230C600FF0E00070B30E7007F54
+:103A80000A000EA38FBF00200E000C6F8F8400343D
+:103A90000A000EA38FBF002024020C80AF42002436
+:103AA0009202003E30420040104000200000000022
+:103AB0009202003E000216000002160304410006B6
+:103AC000000000008F8400340E00063824050093A7
+:103AD0000A000EA38FBF00209202003F24030018AB
+:103AE000304200FF1443000C8F8400342405003959
+:103AF0000E0005D0000030210E0003028F84003438
+:103B000024020012A202003F0E00030B8F84003437
+:103B10000A000EA38FBF0020240500360E0005D03A
+:103B2000000030210A000EA38FBF00200E00030208
+:103B30008F8400349202000534420020A202000566
+:103B40000E00030B8F8400340E0010588F84003455
+:103B50008FBF00208FB1001C8FB0001824020C8092
+:103B600027BD002803E00008AF42002427BDFFE87E
+:103B7000AFB00010AFBF00142743010094620008EB
+:103B8000000214000002140304410002000080211E
+:103B90002410000194620008304200801040001A96
+:103BA00002001021946200083042200010400016EC
+:103BB000020010218C6300183C021C2D344219EDC8
+:103BC000240600061062000F3C0760213C0208003A
+:103BD0008C4200D4104000078F8200288F83002879
+:103BE000906200623042000F34420040A0620062E6
+:103BF0008F8200288F840034944500D40E000B89F6
+:103C000030A5FFFF020010218FBF00148FB00010FD
+:103C100003E0000827BD001827BDFFE0AFB1001486
+:103C2000AFB00010A380002CAFBF00188F4501007B
+:103C30003C0308008C6300E02402FF80AF85003461
+:103C400000A318213064007F03442021006218245F
+:103C50003C02000A00822021AF43002427500100CB
+:103C60008E0200148C8300DCAF84002800431023F4
+:103C700018400004000088218E0200140E000B1C66
+:103C8000AC8200DC9202000B24030002304200FFF1
+:103C90001443002F0000000096020008304300FF8C
+:103CA0002402008214620005240200840E0009D65A
+:103CB000000000000A000F2F00000000146200093D
+:103CC000240200818F8200288F8400343C07602109
+:103CD000944500D49206000530A5FFFF0A000F1E90
+:103CE00030C600FF14620027000000009202000AA4
+:103CF000304300FF3062002010400004306200407A
+:103D00008F8400340A000F1A24060040104000047B
+:103D1000000316008F8400340A000F1A24060041A5
+:103D200000021603044100178F8400342406004269
+:103D30008F8200283C076019944500D430A5FFFF0E
+:103D40000E000B89000000000A000F2F0000000089
+:103D50009202000B24030016304200FF10430006BD
+:103D6000000000009202000B24030017304200FF05
+:103D700014430004000000000E000EA90000000023
+:103D8000004088210E000C00000000009202000A92
+:103D9000304200081040000624020C808F85002865
+:103DA0003C0400080E0012860344202124020C80EB
+:103DB000AF4200248FBF0018022010218FB00010E6
+:103DC0008FB1001403E0000827BD002027BDFFE8E5
+:103DD000AFBF0014AFB000108F5000243C030800A8
+:103DE0008C6300E08F4501002402FF8000A31821AE
+:103DF0003064007F03442021006218243C02000A42
+:103E000000822021AF850034AF43002490820062FD
+:103E1000AF8400283042000F34420050A08200627C
+:103E20003C02001F3442FF800E0006BE02028024C6
+:103E3000AF5000248FBF00148FB0001003E00008C3
+:103E400027BD00183C0208008C4200201040001DD5
+:103E50002745010090A300093C02000803422021ED
+:103E600024020018546200033C0200080A000F708C
+:103E700024020008034220212402001614620005D7
+:103E80002402001724020012A082003F0A000F7AC9
+:103E900094A700085462000694A7000893620005E6
+:103EA0002403FFFE00431024A362000594A700082A
+:103EB00090A6001B8CA4000094A500060A000B64C9
+:103EC00000073C0003E00008000000002744010058
+:103ED00094820008304500FF38A3008238A2008495
+:103EE0002C6300012C4200010062182510600006BE
+:103EF000240200839382002D1040000D000000007A
+:103F00000A000C330000000014A2000524A2FF8068
+:103F10008F4301043C02602003E00008AC4300141E
+:103F2000304200FF2C420002104000032402002215
+:103F30000A000ED40000000014A2000300000000DC
+:103F40000A000F41000000000A000F5F000000009F
+:103F50009363007E9362007A1443000900002021DD
+:103F60009362000024030050304200FF1443000419
+:103F7000240400019362007E24420001A362007EBB
+:103F800003E00008008010218F4201F80440FFFE8A
+:103F900024020002AF4401C0A34201C43C0210004D
+:103FA00003E00008AF4201F827BDFFE8AFBF0010F3
+:103FB0009362003F2403000A304200FF144300468E
+:103FC000000000008F6300548F62004C1062007D7F
+:103FD000036030219362000024030050304200FF50
+:103FE0001443002F000000008F4401403C020800F1
+:103FF0008C4200E02403FF80008210210043102443
+:10400000AF4200243C0208008C4200E08F6500545F
+:104010003C03000A008220213084007F03441021E9
+:1040200000431021AC4501089762003C8F63004CAF
+:104030003042FFFF0002104000621821AF63005CB5
+:104040008F6300548F64004C9762003C0064182317
+:104050003042FFFF00031843000210400043102AC3
+:1040600010400006000000008F6200548F63004C77
+:10407000004310230A000FF0000210439762003C37
+:104080003042FFFF00021040ACC200642402000175
+:10409000A0C0007CA0C2008424020C80AF42002497
+:1040A0000E000FA28F440140104000478FBF001048
+:1040B0008F4301408F4201F80440FFFE24020002BA
+:1040C000AF4301C0A34201C43C021000AF4201F85B
+:1040D0000A0010408FBF00109362003F24030010BD
+:1040E000304200FF14430004000000008F440140F0
+:1040F0000A00102C000028219362003F24030016C0
+:10410000304200FF1443000424020014A362003F65
+:104110000A00103A000000008F62004C8F630050CC
+:1041200000431023044100288FBF001093620081D8
+:1041300024420001A3620081936200812C420004AA
+:1041400014400010000000009362003F24030004AC
+:10415000304200FF14430006000000008F4401407D
+:104160008FBF0010240500930A00063827BD0018F1
+:104170008F440140240500938FBF00100A0006A75A
+:1041800027BD00188F4401400E000302000000000C
+:104190008F6200542442FFFFAF6200548F620050D0
+:1041A0002442FFFFAF6200500E00030B8F4401401A
+:1041B0008F4401408FBF0010240500040A00031043
+:1041C00027BD00188FBF001003E0000827BD0018AE
+:1041D0008F4201889363007E00021402304400FF86
+:1041E000306300FF1464000D000000009362008043
+:1041F000304200FF1044000900000000A36400806A
+:104200009362000024030050304200FF1443000476
+:10421000000000000A00076F8F440180A364008043
+:1042200003E000080000000027BDFFE8AFB0001069
+:10423000AFBF001493620005240300303042003009
+:1042400014430089008080213C0208008C42002039
+:1042500010400080020020210E00052B000000000D
+:104260008F850020ACB000009362003E9363003F56
+:10427000304200FF00021200306300FF00431025AF
+:10428000ACA2000493620082000216000002160332
+:1042900004410005000000003C0308008C63004856
+:1042A0000A00107E000000009362003E3042004091
+:1042B000144000030000182193620081304300FF86
+:1042C0009362008200031E00304200FF00021400CF
+:1042D00000621825ACA300088F620040ACA2000C5D
+:1042E0008F620048ACA200108F62004CACA2001498
+:1042F0008F6200508F63004C004310230441000381
+:10430000000000000A0010928F62004C8F62005083
+:10431000ACA200183C02080094424DBE3C03C00B06
+:1043200000002021004310250E000550ACA2001C07
+:104330008F6200548F840020AC8200008F6200588E
+:10434000AC8200048F62005CAC8200088F62006067
+:104350008F43007400431021AC82000C8F62006414
+:10436000AC820010976300689762006A00031C002B
+:104370003042FFFF00621825AC8300149362008274
+:1043800024030080304200FF1443000300000000BB
+:104390000A0010C6AC8000188F63000C24020001D4
+:1043A0001062000E2402FFFF9362003E3042004084
+:1043B0001440000A2402FFFF8F63000C8F42007438
+:1043C000006218233C02080000621024144000021E
+:1043D000000028210060282100051043AC8200184D
+:1043E0003C02080094424DBE3C03C00C000020215A
+:1043F000004310258F8300200E000550AC62001C86
+:104400008F6200188F8300203C05080094A54DBEE4
+:1044100024040001AC620000AC6000048F66006CF4
+:104420003C02400D00A22825AC6600088F6200DC2B
+:10443000AC62000CAC600010936200050002160034
+:10444000AC620014AC6000180E000550AC65001C96
+:10445000020020218FBF00148FB00010A360000560
+:104460000A0004B927BD00188FBF00148FB00010D8
+:1044700003E0000827BD00189742007C30C600FF0B
+:10448000A08600843047FFFF2402000514C2000B01
+:1044900024E3465090A201122C420007104000076E
+:1044A00024E30A0090A30112240200140062100405
+:1044B00000E210210A0010FE3047FFFF3067FFFFC7
+:1044C00003E00008A4870014AC87004C8CA201080C
+:1044D0000080402100A0482100E2102330C600FFE8
+:1044E0001840000393AA001324E2FFFCACA20108C9
+:1044F00030C2000110400008000000008D02005092
+:1045000000E2102304410013240600058D0200542C
+:1045100010E20010000000008D02005414E2001AA6
+:10452000000000003C0208008C4200D8304200200D
+:104530001040000A240200019103007891020083D8
+:10454000144300062402000101002021012028213B
+:10455000240600040A0010EC00000000A100008402
+:1045600011400009A50200148F4301008F4201F899
+:104570000440FFFE24020002AF4301C0A34201C475
+:104580003C021000AF4201F803E000080000000008
+:1045900027BDFFE88FA90028AFBF00100080402191
+:1045A00000E918231860007330C600FFA080007C6B
+:1045B000A08000818CA2010800E210230440004D7D
+:1045C000000000008C8200509483003C8C840064C6
+:1045D000004748233063FFFF012318210083202B6D
+:1045E00010800004000000008D0200640A00114FDA
+:1045F00000E210219502003C3042FFFF0122102111
+:1046000000E21021AD02005C9502003C8D03005CCD
+:104610003042FFFF0002104000E210210043102B47
+:1046200010400003000000000A00115E8D02005CD3
+:104630009502003C3042FFFF0002104000E21021D2
+:10464000AD02005CA1000084AD07004C8CA2010803
+:1046500000E210231840000224E2FFFCACA2010893
+:1046600030C200011040000A000000008D0200501E
+:1046700000E2102304410004010020218D020054B7
+:1046800014E20003000000000A0011802406000567
+:104690008D02005414E200478FBF00103C02080056
+:1046A0008C4200D8304200201040000A2402000151
+:1046B0009103007891020083144300062402000154
+:1046C00001002021240600048FBF00100A0010EC16
+:1046D00027BD0018A1000084A50200148F4301002B
+:1046E0008F4201F80440FFFE240200020A0011A5D7
+:1046F000000000008C82005C004910230043102B56
+:1047000054400001AC87005C9502003C3042FFFF42
+:104710000062102B14400007240200029502003CA6
+:104720008D03005C3042FFFF00621821AD03005C86
+:1047300024020002AD07004CA10200840E000FA26B
+:104740008F4401001040001B8FBF00108F430100F9
+:104750008F4201F80440FFFE24020002AF4301C073
+:10476000A34201C43C021000AF4201F80A0011BB91
+:104770008FBF001030C200101040000E8FBF00101D
+:104780008C83005C9482003C006918233042FFFF58
+:10479000006218213C023FFF3444FFFF0083102BCE
+:1047A000544000010080182101231021AD02005C5B
+:1047B0008FBF001003E0000827BD001827BDFFE8E9
+:1047C0008FAA0028AFBF00100080402100EA4823D4
+:1047D0001920002130C600FF8C83005C8C820064AD
+:1047E000006A18230043102B504000100069182164
+:1047F00094A2011001221021A4A2011094A2011080
+:104800003042FFFF0043102B1440000A3C023FFFE0
+:1048100094A2011000431023A4A201109482003C32
+:104820003042FFFF0A0011DA00621821A4A0011033
+:104830003C023FFF3444FFFF0083102B5440000133
+:104840000080182100671021AD02005CA100007CEF
+:104850000A001222A100008130C200101040003C6A
+:10486000000000008C820050004A102318400038DD
+:10487000000000009082007C24420001A082007CA5
+:104880009082007C3C0308008C630024304200FFCF
+:104890000043102B1440005C8FBF00108CA2010855
+:1048A00000E2102318400058000000008C830054E0
+:1048B0009482003C006A18233042FFFF0003184333
+:1048C000000210400043102A1040000500000000C4
+:1048D0008C820054004A10230A001209000210437F
+:1048E0009482003C3042FFFF00021040AD020064A1
+:1048F0009502003C8D0400649503003C3042FFFFAC
+:1049000000021040008220213063FFFF0083182145
+:1049100001431021AD02005C8D020054ACA20108DD
+:1049200024020002A10200840E000FA28F440100A5
+:10493000104000358FBF00108F4301008F4201F8F7
+:104940000440FFFE240200020A00124B0000000097
+:10495000AD07004C8CA2010800E2102318400002B1
+:1049600024E2FFFCACA2010830C200011040000AA2
+:10497000000000008D02005000E2102304410004FA
+:10498000010020218D02005414E200030000000009
+:104990000A001242240600058D02005414E2001A97
+:1049A0008FBF00103C0208008C4200D8304200202B
+:1049B0001040000A24020001910300789102008354
+:1049C00014430006240200010100202124060004F3
+:1049D0008FBF00100A0010EC27BD0018A100008452
+:1049E000A50200148F4301008F4201F80440FFFE2E
+:1049F00024020002AF4301C0A34201C43C021000E4
+:104A0000AF4201F88FBF001003E0000827BD001877
+:104A10008FAA00108C8200500080402130C600FF19
+:104A2000004A102300A048211840000700E0182188
+:104A300024020001A0800084A0A00112A48200141E
+:104A40000A0011BDAFAA0010A0800081AD07004C84
+:104A50008CA2010800E210231840000224E2FFFCAF
+:104A6000ACA2010830C200011040000800000000A4
+:104A70008D0200500062102304410013240600053B
+:104A80008D02005410620010000000008D020054DE
+:104A900014620011000000003C0208008C4200D8A3
+:104AA000304200201040000A2402000191030078E7
+:104AB000910200831443000624020001010020211A
+:104AC00001202821240600040A0010EC0000000048
+:104AD000A1000084A502001403E00008000000000B
+:104AE00027BDFFE0AFBF0018274201009046000A33
+:104AF0008C4800148C8B004C9082008430C900FFDD
+:104B000001681823304A00FF1C60001A2D46000679
+:104B1000240200010142100410C0001630430003BB
+:104B2000012030210100382114600007304C000CB6
+:104B300015800009304200301440000B8FBF001870
+:104B40000A0012AC000000000E0011BDAFAB001057
+:104B50000A0012AC8FBF00180E001132AFAB00106C
+:104B60000A0012AC8FBF0018AFAB00100E0012523B
+:104B7000AFAA00148FBF001803E0000827BD002073
+:104B800024020003A08200848C82005403E0000809
+:104B9000ACA201083C020008034218219062008187
+:104BA000240600433C07601924420001A0620081F2
+:104BB000906300813C0208008C4200C0306300FF1B
+:104BC000146200102403FF803C0208008C4200E0C5
+:104BD0000082102100431024AF4200243C02080050
+:104BE0008C4200E03C03000A008210213042007F2A
+:104BF0000342102100431021944500D40A000B8980
+:104C000030A5FFFF03E000080000000027BDFFE023
+:104C1000AFBF0018AFB10014AFB000108F420180D9
+:104C20000080802100A088210E0012B300402021C6
+:104C3000A20000848E0200548FBF00188FB00010B5
+:104C4000AE2201088FB1001403E0000827BD002048
+:104C500027BDFFE03C020008AFB00010AFBF001856
+:104C6000AFB10014034280218F51014092030084B0
+:104C70008E0400508E02004C14820040306600FF0B
+:104C80003C0208008C4200E02403FF800222102135
+:104C900000431024AF4200243C0208008C4200E094
+:104CA0009744007C92050081022210213042007F4F
+:104CB000034218213C02000A0062182114A0000BD4
+:104CC0003084FFFF2402000554C20014248205DC56
+:104CD0009062011224420001A062011224020C80A1
+:104CE000AF4200240A00130B24020005A060011249
+:104CF0002402000514C20009248205DC920200810E
+:104D00002C4200075040000524820A0092030081D3
+:104D10002402001400621004008210213044FFFFBE
+:104D2000A60400140E0012B3022020219602003CBB
+:104D30008E03004C022020213042FFFF0002104071
+:104D4000006218210E000302AE03005C9202007D97
+:104D500002202021344200400E00030BA202007DFD
+:104D60008F4201F80440FFFE24020002AF5101C04F
+:104D7000A34201C43C021000AF4201F88FBF0018EB
+:104D80008FB100148FB0001003E0000827BD002091
+:104D900008000D9808000DE008000E2008000E6CB9
+:044DA00008000EA059
+:0C4DA4000A0000220000000000000000D7
+:104DB0000000000D6370352E302E306A3300000085
+:104DC00005000004000000000000000000000000DA
+:104DD00000000000000000000000000000000000D3
+:104DE00000000000000000000000000000000020A3
+:104DF00000000000000000000000000000000000B3
+:104E000000000000000000000000000000000000A2
+:104E10000000000000000000000000000000000191
+:104E20000000002B00000000000000000000000057
+:104E300010000003000000000000000D0000000D45
+:104E40003C02080024425AC43C03080024636190D9
+:104E5000AC4000000043202B1480FFFD24420004DE
+:104E60003C1D080037BD7FFC03A0F0213C1008006A
+:104E7000261000883C1C0800279C5AC40E0001A67E
+:104E8000000000000000000D27BDFFE83C0960188D
+:104E9000AFBF00108D2C5000240DFF7F240800317F
+:104EA000018D5824356A380C24070C003C1A800008
+:104EB000AD2A50003C04800AAF4800083C1B800823
+:104EC000AF4700240E000938AF8400100E0008FB25
+:104ED000000000000E000848000000000E0012DF75
+:104EE000000000003C0460168C8500003C06FFFFBB
+:104EF0003C02535300A618241062004734867C00FD
+:104F000094C201F2A780002C10400003A78000CCBF
+:104F100038581E1EA798002C94C201F810400004B7
+:104F2000978300CC38591E1EA79900CC978300CCDC
+:104F30002C7F006753E00001240300669784002C57
+:104F40002C82040114400002006028212404040083
+:104F50003C0760008CE904382403103C3128FFFF33
+:104F60001103001F30B9FFFF57200010A38000CEAF
+:104F700024020050A38200CE939F00CE53E0000F86
+:104F8000A78500CCA78000CC978500CC8FBF0010F0
+:104F9000A780002CA7800034A78000E63C01080011
+:104FA000AC25008003E0000827BD0018939F00CEC9
+:104FB00057E0FFF5A78000CCA78500CC978500CCF3
+:104FC0008FBF0010A784002CA7800034A78000E6C4
+:104FD0003C010800AC25008003E0000827BD001854
+:104FE000A38000CE8CCB003C316A00011140000E42
+:104FF0000000000030A7FFFF10E0FFDE2402005099
+:105000008CCC00C83186000114C0FFDC939F00CE19
+:105010000A000074240200518C8F00043C0E6000D2
+:105020000A00005701EE30218CEF0808240D5708C4
+:10503000000F740211CD000430B8FFFF2405006694
+:105040000A000075240404001700FFCC939F00CED3
+:105050000A000074240200508F8600103089FFFF80
+:10506000000939408CC300103C08005000E820259E
+:10507000AF4300388CC5001427420400AF82001CE7
+:10508000AF45003CAF4400300000000000000000CD
+:105090000000000000000000000000000000000010
+:1050A00000000000000000008F4B0000316A00206B
+:1050B0001140FFFD0000000003E0000800000000B8
+:1050C0008F840010948A001A8C8700243149FFFFD6
+:1050D000000940C000E83021AF46003C8C85002428
+:1050E0008F43003C00A3102318400029000000005B
+:1050F0008C8B0020256200013C0D005035AC00086F
+:10510000AF420038AF4C003000000000000000004B
+:10511000000000000000000000000000000000008F
+:1051200000000000000000008F4F000031EE002062
+:1051300011C0FFFD000000008F4A04003C08002061
+:10514000AC8A00108F490404AC890014AF480030C9
+:1051500000000000948600189487001C00C71821E6
+:10516000A48300189485001A24A20001A482001AC6
+:105170009498001A9499001E133800030000000050
+:1051800003E000080000000003E00008A480001A0B
+:105190008C8200200A0000D63C0D00500A0000C797
+:1051A000000000003C0308008C6300208F82001880
+:1051B00027BDFFE810620008AFBF00100E0000FE20
+:1051C000AF8300183C0308008C6300202404000116
+:1051D000106400048F8900108FBF001003E00008E6
+:1051E00027BD00188FBF00103C076012A520000AE1
+:1051F0009528000A34E5001027BD00183106FFFF8E
+:1052000003E00008ACA600903C0208008C4200209D
+:1052100027BDFFC8AFBF0034AFBE0030AFB7002C12
+:10522000AFB60028AFB50024AFB40020AFB3001C68
+:10523000AFB20018AFB1001410400050AFB0001072
+:105240008F840010948600069483000A00C32823EC
+:1052500030B6FFFF12C0004A8FBF00349489001897
+:10526000948A000A012A40233102FFFF02C2382B30
+:1052700014E0000202C02021004020212C8C0005F7
+:10528000158000020080A021241400040E0000AD4F
+:10529000028020218F87001002809821AF800014A7
+:1052A00094ED000A028088211280004E31B2FFFF87
+:1052B0003C1770003C1540003C1E60008F8F001CA6
+:1052C0008DEE000001D718245075005002202021D7
+:1052D00002A3802B160000353C18200050780047B0
+:1052E00002202021241000018F8300141460003953
+:1052F000029158230230F8230250C82133F1FFFFF6
+:105300001620FFEE3332FFFF8F8700103C11002084
+:10531000AF5100300000000094E6000A3C1E60120D
+:1053200037D5001002662821A4E5000A94E2000A9D
+:1053300094F2000A94F400183057FFFF1292003BD9
+:10534000AEB700908CED00148CE400100013714097
+:1053500001AE4021000E5FC3010E502B008B48218F
+:10536000012A1821ACE80014ACE3001002D3382362
+:1053700030F6FFFF16C0FFB98F8400108FBF0034D6
+:105380008FBE00308FB7002C8FB600288FB5002459
+:105390008FB400208FB3001C8FB200188FB100149F
+:1053A0008FB0001003E0000827BD0038107E001BFE
+:1053B000000000001477FFCC241000010E00162A14
+:1053C000000000008F8300141060FFCB0230F82330
+:1053D000029158238F870010017020210A0001914B
+:1053E0003093FFFF8F8300141460FFCB3C1100202B
+:1053F000AF5100300A00015D000000000E0007A15F
+:10540000024028210A000151004080210E00034B78
+:10541000024028210A000151004080210E0014F2B0
+:10542000022020210A000151004080210E0000C707
+:10543000000000000A00017302D3382327BDFFE8F3
+:10544000AFB00010AFBF00140E0000390000000024
+:105450003C028000345000700A0001B48E06000047
+:105460008F4F000039EE000131C2000110400024CE
+:105470008F8600A88E0700003C0C08008D8C003C35
+:105480003C0908008D29003800E66823018D282199
+:105490000000502100AD302B012A402101062021BF
+:1054A0003C010800AC25003CAF8700A83C01080087
+:1054B000AC2400380E000100000000003C0308008E
+:1054C0008C6300701060FFE6006020213C0508003E
+:1054D0008CA500683C0608008CC6006C0E0015B94F
+:1054E000000000003C010800AC2000708F4F00005D
+:1054F00039EE000131C200011440FFDE8F8600A8A2
+:105500008E0A00008F8B00A83C0508008CA5003C8B
+:105510003C0408008C840038014B482300A9382142
+:105520000082182100E9402B006810213C0108008E
+:10553000AC27003C3C010800AC2200388F5F010022
+:105540002419FF0024180C0003F9202410980012DD
+:10555000AF840000AF440020936D0000240C0020B5
+:1055600031A600FF10CC0012240E005010CE000413
+:105570003C194000AF5901380A0001AD000000009D
+:105580000E001255000000003C194000AF590138D0
+:105590000A0001AD000000000E000119000000002B
+:1055A0003C194000AF5901380A0001AD000000006D
+:1055B0008F58010000802821330F00FF01E02021D7
+:1055C0000E0002F8AF8F00043C194000AF590138BB
+:1055D0000A0001AD0000000000A4102B240300010C
+:1055E00010400009000030210005284000A4102BC5
+:1055F00004A00003000318405440FFFC00052840AD
+:105600005060000A0004182B0085382B54E0000479
+:105610000003184200C330250085202300031842F0
+:105620001460FFF9000528420004182B03E000086D
+:1056300000C310213084FFFF30A5FFFF8F4201B867
+:105640000440FFFE3C074080008730253C031000EB
+:10565000AF400180AF450184AF46018803E00008F8
+:10566000AF4301B83084FFFF8F4201B80440FFFE12
+:105670003C0740388CA60000008728253C0310001A
+:10568000AF460180AF45018803E00008AF4301B891
+:105690008F8300388F8600301066000B0080402119
+:1056A0003C07080024E75C38000328C000A710214D
+:1056B0008C44000024630001108800053063000F53
+:1056C0005466FFFA000328C003E000080000102120
+:1056D0003C07080024E75C3C00A7302103E00008F9
+:1056E0008CC200003C03900034620001008220253F
+:1056F000AF4400208F45002004A0FFFE0000000002
+:1057000003E00008000000003C0380003462000158
+:105710000082202503E00008AF44002027BDFFE001
+:10572000AFB100143091FFFFAFB00010AFBF001851
+:105730001220001500A080218CA5000010A00013ED
+:10574000240400020E000C7F24060140AE0000007D
+:105750008F4201B80440000D000028213C064000A3
+:10576000022620258FBF00188FB100148FB00010C3
+:105770003C03100027BD0020AF450180AF440188E5
+:1057800003E00008AF4301B88CA500008F4201B8C8
+:105790000440FFFE3C064000022620258FBF001873
+:1057A0008FB100148FB000103C03100027BD002003
+:1057B000AF450180AF44018803E00008AF4301B862
+:1057C0003086FFFF8F4201B80440FFFE3C094006CF
+:1057D0008CA8000000C93825AF4801808CA40004C3
+:1057E0003C031000AF440184AF47018803E0000888
+:1057F000AF4301B827BDFFE0AFB00010AFBF001846
+:10580000AFB100149363003E008080210080282106
+:1058100030620040000020211040000F8E11000077
+:105820000E00087402202021936700002404005019
+:1058300030E500FF50A400128E0F0000022020214E
+:105840008FBF00188FB100148FB00010A762013C09
+:105850000A00093427BD00200E0002870000000066
+:105860000E000874022020219367000024040050D9
+:1058700030E500FF14A4FFF2022020218E0F00006B
+:105880003C1008008E1000503C0D000C240BFF80D3
+:1058900001F05021314E007F01DA6021018D40215D
+:1058A000014B4824AF490028022020218FBF001857
+:1058B0008FB100148FB00010A50200D627BD0020C4
+:1058C0000A000934AF8800D027BDFFE0AFBF001841
+:1058D000AFB10014AFB000109366000100808021CA
+:1058E0000E00025030D1000493640005001029C25C
+:1058F000A765000034830040A36300050E00025931
+:10590000020020210E00093602002021240200019D
+:10591000AF62000C02002821A762001024040002DC
+:10592000A762001224060140A76200140E000C7F3B
+:10593000A76200161620000F8FBF0018978C003446
+:105940003C0B08008D6B00782588FFFF3109FFFFB5
+:10595000256A0001012A382B10E00006A7880034D0
+:105960003C0F6006240E001635ED0010ADAE005061
+:105970008FBF00188FB100148FB0001003E0000833
+:1059800027BD002027BDFFE0AFB10014AFBF001856
+:10599000AFB0001000A088211080000A3C03600016
+:1059A0002402008010820012000000000000000DA0
+:1059B0008FBF00188FB100148FB0001003E00008F3
+:1059C00027BD00208C682BF80500FFFE00000000BA
+:1059D000AC712BC08FBF00188FB100148FB00010B6
+:1059E0003C09100027BD002003E00008AC692BF83B
+:1059F0000E00025000A02021936500050220202106
+:105A00000E00025930B000FF2403003E1603FFE7EA
+:105A1000000000008F4401780480FFFE2407000787
+:105A20003C061000AF51014002202021A347014451
+:105A30008FBF00188FB100148FB00010AF460178EF
+:105A40000A0002C927BD002027BDFFE8AFBF001430
+:105A5000AFB000108F500020000000000E0009368B
+:105A6000AF440020AF5000208FBF00148FB0001053
+:105A700003E0000827BD00183084FFFF8F4201B803
+:105A80000440FFFE3C074035008730253C031000F2
+:105A9000AF450180AF400184AF46018803E00008B4
+:105AA000AF4301B83084FFFF8F4201B80440FFFECE
+:105AB0003C074036008730253C031000AF4501808D
+:105AC000AF400184AF46018803E00008AF4301B84E
+:105AD00027BDFFD0AFB3001C3093FFFFAFB500244C
+:105AE000AFB20018AFBF0028AFB40020AFB10014B0
+:105AF000AFB0001030B5FFFF12600027000090210A
+:105B00008F90001C8E0300003C06800024020040A1
+:105B100000033E0200032C0230E4007F006688246C
+:105B20001482001D30A500FF8F8300282C68000A16
+:105B3000510000108F910014000358803C0C0800A5
+:105B4000258C58D0016C50218D490000012000089F
+:105B50000000000002B218213065FFFF0E00022491
+:105B600024040084162000028F90001CAF800028BF
+:105B70008F910014260C0020264B0001018080210B
+:105B80003172FFFF16200004AF8C001C0253282B3B
+:105B900014A0FFDC00000000024010218FBF00288D
+:105BA0008FB500248FB400208FB3001C8FB2001873
+:105BB0008FB100148FB0001003E0000827BD003043
+:105BC000240D003414AD00F600000000920B000E0E
+:105BD000240A16803C07000CA36B00219203000DE1
+:105BE0000347F8213C066000A363002096110012D1
+:105BF0003C057FFF34ACFFFFA771003C960200100C
+:105C0000240B00053054FFFFAF7400848E19001C74
+:105C1000AF4A00288FF800008CCF44480319702643
+:105C200001EE3021AF66004C8F69004C24CD00019D
+:105C30003C197F00AF6900508F640050AF6400547E
+:105C4000AF660070AF6D00588F6800582404005094
+:105C5000AF68005CA3600023AF6C0064A36B0037E7
+:105C60008E030014AF6300488F710048AF710024A9
+:105C70008E020018AF62006C9214000CA374003600
+:105C8000936A003E355F0020A37F003E8F7800744A
+:105C90000319782435EE4000AF6E0074936900005C
+:105CA000313000FF1204022B2418FF803C0408004E
+:105CB00024845CB80E000294000000002406000456
+:105CC000240700013C0408008C845CB8A366007DB6
+:105CD000A36700058F4A01780540FFFE24020002F9
+:105CE000AF440140A34201448F90001C3C141000BB
+:105CF000AF5401780A000373AF8000282CAD003741
+:105D000051A0FF9C8F9100140005A0803C18080052
+:105D1000271858F8029878218DEE000001C000087D
+:105D2000000000002406000614A600110000000078
+:105D30003C1F08008FFF5CB824040005AF5F002003
+:105D40008E190018AF7900188F78004CAF78001CBE
+:105D50008F6F0050122000C2AF6F00700A000373F3
+:105D6000AF840028240A000710AA00842403000638
+:105D70003C05080024A55CB80E00025E24040081E6
+:105D80008F90001C0011102B0A000373AF820028B3
+:105D90002402000414A2FFF6240A00503C09080063
+:105DA0008D295CB8AF4900208E040008AF64004024
+:105DB0008E060008AF6600448E07000CAF670048EF
+:105DC0008E0D0010AF6D004C8E080010AF6800847F
+:105DD0008E050014AF6500508E0C0018AF6C005497
+:105DE0008E0B001CAF6B005893740000328300FFD1
+:105DF000106A01ED000000008F6700488F660040C8
+:105E000000E6682305A000042404008C1620FFDEB1
+:105E100024020003240400823C05080024A55CB889
+:105E20000E000287000000008F90001C000010216F
+:105E30000A000373AF8200282404000514A4FFCCD9
+:105E4000240520003C1F08008FFF5CB8AF5F0020D6
+:105E50008E190004AF79005C921800082410000825
+:105E6000A37800218F8F001C91EE0009A36E002003
+:105E70008F86001C90C9000A312400FF109000108A
+:105E8000288A00091540006C24020002240C00201E
+:105E9000108C000B340580002885002114A0000818
+:105EA0002405400024080040108800053C0500013E
+:105EB000240D0080108D00023C05000224054000E6
+:105EC0008F6E00743C0FFF0001CF48240125802510
+:105ED000AF70007490C4000BA36400818F84001C19
+:105EE0009487000C10E0019300000000948E000CD9
+:105EF000241FFFBF24060004A76E003C9089000EFB
+:105F0000A369003E8F90001C9204000FA364003F21
+:105F10008F94001C8E8D00108F47007401A74023C2
+:105F2000AF6800608E850014AF650064968C001821
+:105F3000A76C0068968B001AA76B006A8E83001C02
+:105F4000AF63006C96820002A762013E928A000E47
+:105F5000A36A003E9379003E033FC02412200166ED
+:105F6000A378003E8F90001C0A000373AF860028C0
+:105F70002414002214B4FF7E240300073C0208000E
+:105F80008C425CB81220000CAF4200200A00037360
+:105F9000AF830028240C003310AC00142405002823
+:105FA0003C05080024A55CB80E00023024040081E2
+:105FB0000A0003F88F90001C3C04080024845CB89D
+:105FC0000E00029400000000936B000024110050AA
+:105FD000316300FF10710150000000008F90001C21
+:105FE000000018210A000373AF8300283C08080052
+:105FF0008D085CB824040081AF480020A3650034FC
+:106000003C05080024A55CB80E000230000000002A
+:106010008F90001C240200090A000373AF8200283D
+:1060200002B288213225FFFF0E00022424040084DE
+:106030000A0003738F90001C1082FFA12405040046
+:10604000288300031060016E240B00042414000157
+:106050005494FF9B240540000A00044724050100D6
+:106060003C04080024845CB88F62004C0E0002944B
+:106070008F6300508F90001C000020210A000373E2
+:10608000AF8400288E1000042404008AAF50002042
+:10609000936E000531C900021520015D0200282120
+:1060A0009378002302002821330F002015E00158C7
+:1060B0002404008D9362003F24190012305F00FF1A
+:1060C00013F90153240400810E0002500200202124
+:1060D00093740023240A0004020020213683004226
+:1060E000A36300230E000259A36A007D8F4B017841
+:1060F0000560FFFE24050002AF500140A3450144A6
+:106100008F90001C3C0C1000AF4C01780A0003F982
+:106110000011102B8E100004AF500020936D00056D
+:1061200031A80002550001782404008A9364003FDE
+:106130002407000402002821308600FF10C7001049
+:10614000240400810E00025002002021937F0023CE
+:1061500024180012240FFFFE37F90020A379002332
+:10616000A378003F936E00050200202101CF482450
+:106170000E000259A3690005020028210000202119
+:106180000E000340000000000A0003F88F90001C7E
+:106190008E0500043C0F0008034F4021AF4500204E
+:1061A000910E00002406005031C900FF1126017A2B
+:1061B000240400888F5901B80720FFFE3C0C400ED4
+:1061C000008C58253C031000AF450180AF4001848E
+:1061D000AF4B0188AF4301B891020000240AFF8051
+:1061E00024040004004AF825A11F00000E000C7FC3
+:1061F000240600300A0003F88F90001C8E0F000464
+:106200003C14080026945CB83C010800AC2F5CB834
+:10621000AF4F0020920E000331C90004112000028C
+:106220002402001224020006A362003F9203001B16
+:10623000240AFFC03062003F004AF825A37F003ED9
+:1062400092190003333800011700012200000000FA
+:106250008E020008AE8200083C0208008C425CC03E
+:106260001040012D00000000000221C2A7640008B8
+:106270008E0D000C240B000124140014AF6D002CB3
+:106280008E080010AF68003096050016A76500382C
+:10629000960C0014A76C003AAF6B000CA76B0010B3
+:1062A000A76B0012A76B0014A76B00161220014AFF
+:1062B000A37400349206000330C700022CF00001E2
+:1062C000260200088F90001C0A000373AF8200288A
+:1062D0008E14000424030081AF540020936800232F
+:1062E0003105001010A00113000000008F4401B818
+:1062F0000480FFFE3C06401F0011382B006610256D
+:106300003C111000AF540180AF870028AF400184DA
+:10631000AF420188AF5101B80A0003748F91001495
+:106320008E0600043C19000803592021AF460020C6
+:106330008E07000890980000240F0050331400FFCF
+:10634000128F0106240500888F4401B80480FFFEE7
+:106350003C0D40090011602B00AD10253C111000D0
+:10636000AF460180AF8C0028AF470184AF4201885F
+:10637000AF5101B80A0003748F9100148E04001C01
+:106380000E00023B00000000104000D700404821F2
+:106390008F90001C240500898F4D01B805A0FFFED9
+:1063A00000000000AF4901808E0F001C3C1440012A
+:1063B0000011702B00B448253C111000AF4F018430
+:1063C000AF8E0028AF490188AF5101B80A000374AD
+:1063D0008F910014961900023C14080026945CB8B2
+:1063E000333800041300008E3C0260008E1F001C36
+:1063F0003C010800AC3F5CB8AF5F0020920C00107D
+:10640000240B0014318400FF148B00AC000000004A
+:1064100096090002312D000115A001520000000074
+:106420008E020004AE8200083C0E08008DCE5CC0D7
+:1064300011C00148000000008F6900743C0E80000C
+:1064400024040001012E6825AF6D0074A3600005CF
+:10645000AF64000C3C0C08008D8C5CC08F88001C65
+:10646000A7640010000C59C2A7640012A7640014AE
+:10647000A7640016A76B00088D030008240400021F
+:10648000AF63002C8D0A000CAF6A0030910700103A
+:10649000A36700348F82001C90450011A36500356E
+:1064A0008F86001C90D00012A37000368F9F001CB6
+:1064B00093F90013A37900378F90001C96180014ED
+:1064C000A778003896140016A774003A8E0F0018AB
+:1064D000AF6F00245620FDA6AF8400283C050800BD
+:1064E00024A55CB80E00025E000020218F90001CE5
+:1064F0000A0004B6000020213C05080024A55CB871
+:106500000E000287240400828F90001C00003021BE
+:106510000A000373AF8600283C0408008C845CB832
+:106520000E001577000000008F90001C0A000490F8
+:10653000000018213C05080024A55CB80E00028765
+:106540002404008B8F90001C0011302B0A00037371
+:10655000AF8600283C1908008F395CB83C1F080042
+:106560008FFF005024CCFFFE033F782101F87024F8
+:10657000AF4E00283C0408008C845CB83C0908003D
+:106580008D2900500089682131A8007F011A282137
+:1065900000A78021AE0600D8AF9000D0AE0000DC8E
+:1065A0000A0003C2AE0C0108AF6000843C0508007D
+:1065B0008CA55CB83C0808008D080050240CFF80B6
+:1065C0003C02000C00A8A021028C5824AF4B0028EC
+:1065D0008E1F00143283007F007A50210142702107
+:1065E000ADDF00D88E190014AF8E00D0ADD900DC1D
+:1065F0008E180010270FFFFE0A000415ADCF01080A
+:10660000548BFE2F240540000A0004472405100087
+:106610000E000335000000000A0003F88F90001CF4
+:106620008C46442C3C056C6234B079703C01080007
+:10663000AC205CB814D00008240400029788003411
+:10664000978A002C02802821010A382B10E00011C3
+:1066500024040092240400020E000C9D2405014035
+:106660003C010800AC225CB8AF4200203C030800AB
+:106670008C635CB810600005240400830E00086879
+:106680000000000010400009240400833C050800BD
+:1066900024A55CB80E00025E000000008F90001C74
+:1066A0000011202B0A000373AF8400280E00086C31
+:1066B000000000000A0005968F90001C0E00087074
+:1066C000000000003C05080024A55CB80A00063C58
+:1066D0002404008B8E0400080E00023B0000000022
+:1066E0000A00052DAE820008240400040E000C9D53
+:1066F000240500301440003F004048218F90001CCA
+:106700000A00057D240500830E00034002002821B5
+:106710000A0004E2000000003C05080024A55CB863
+:106720000E000230240400878F90001C0A000549E7
+:106730000011102B0E0002500280202193700023C4
+:1067400002802021360D00100E000259A36D002397
+:106750008F90001C0A000552000018219205000CC1
+:1067600030BF000113E00003000000009602000E9D
+:10677000A482002C920A000C314800021100FEF2A3
+:1067800000002821960B00128E030014A48B001A1F
+:106790000A000569AC83001C8F8300388F870030A6
+:1067A0001067FE84000020213C09080025295C3C7C
+:1067B000000320C0008930218CD400001285005EC7
+:1067C000247800013303000F5467FFFA000320C050
+:1067D0000A000504000020213C05080024A55CB83F
+:1067E0000E000287240400828F90001C0A000549D5
+:1067F000000010213C0B0008034B20212403005013
+:10680000240A0001AF420020A0830000A08A0001FA
+:106810008F88001C91070004A08700188F82001C3D
+:1068200090450005A08500198F86001C90DF0006AA
+:10683000A09F001A8F99001C93380007A098001B96
+:106840008F94001C928F0008A08F001C8F90001C5A
+:10685000920E0009A08E001D8F8D001C91AC000AC5
+:10686000A08C001E8F8B001C3C0C0800258C5C3C0F
+:106870009163000B3C0B0800256B5C38A083001F64
+:106880008F8A001C9148000CA08800208F87001C74
+:1068900090E5000DA08500218F82001C240546464E
+:1068A0009046000EA08600228F9F001C93F9000FD7
+:1068B000A09900238F98001C93140010A09400242A
+:1068C0008F8F001C91F00011A09000258F90001C6C
+:1068D0008F8E00308F990038960D0014000E18C06E
+:1068E00025C80001A48D0028960A0016006C3021EE
+:1068F000006BF821A48A002A960700183108000FBF
+:10690000A487002CA485002E8E02001CACC90000B8
+:10691000AF88003011190003AFE200000A00057DC6
+:1069200000002821250C00013184000F00002821DF
+:106930000A00057DAF8400383C07080024E75C3876
+:106940000087802100002021ACC000000A0005045F
+:10695000AE0000003C05080024A55CB80A00063C17
+:10696000240400878E0400040E00023B0000000097
+:106970000A0005A1AE8200083084FFFF30C600FF88
+:106980008F4201B80440FFFE000644000104302598
+:106990003C07200000C720253C031000AF400180C9
+:1069A000AF450184AF44018803E00008AF4301B85C
+:1069B00027BDFFE8AFB00010AFBF00143C07600078
+:1069C000240600021080000600A080210010102B79
+:1069D0008FBF00148FB0001003E0000827BD00181F
+:1069E0003C09600EAD2000348CE5201C8F82001C19
+:1069F0002408FFFC00A81824ACE3201C0E0006F5B8
+:106A00008C45000C0010102B8FBF00148FB00010AD
+:106A100003E0000827BD00183C02600E3447010067
+:106A200024090018274A04000000000000000000AC
+:106A3000000000003C06005034C30200AF440038A0
+:106A4000AF45003CAF430030014018218F4B0000A0
+:106A5000316800201100FFFD2406007F2408FFFF9D
+:106A60008C6C000024C6FFFF24630004ACEC000023
+:106A700014C8FFFB24E70004000000000000000031
+:106A8000000000003C0F0020AF4F0030000000006D
+:106A900024AD020001A5702B2529FFFF008E2021C7
+:106AA0001520FFE101A0282103E0000800000000FC
+:106AB00027BDFFE0AFB10014AFBF0018AFB00010AA
+:106AC0003C05600E8CA20034008088211440000632
+:106AD0003C0460008C87201C2408FFFC00E8302464
+:106AE00034C30001AC83201C8F8B001C24090001DF
+:106AF000ACA90034956900028D6500148D70000CFE
+:106B00002D2400818D6700048D6600081080000729
+:106B10008D6A00102D2C00041580000E30CE000769
+:106B2000312D000311A0000B000000002404008B95
+:106B3000020028210E0006F5240600030011102B88
+:106B40008FBF00188FB100148FB0001003E0000851
+:106B500027BD002015C0FFF62404008B3C03002055
+:106B6000AF4300300000000024020001AF82001497
+:106B70000000000000000000000000003C1F015069
+:106B8000013FC825253800033C0F600EAF47003891
+:106B900000181882AF46003C35E8003CAF59003081
+:106BA000274704008F4400003086002010C0FFFDFE
+:106BB00000000000106000082466FFFF2403FFFFB0
+:106BC0008CEB000024C6FFFF24E70004AD0B00009F
+:106BD00014C3FFFB250800043C08600EAD09003813
+:106BE0000000000000000000000000003C07002042
+:106BF000AF470030000000000E00071D01402021BB
+:106C000002002821000020210E0006F524060003C2
+:106C10000011102B8FBF00188FB100148FB000101F
+:106C200003E0000827BD002027BDFFD8AFB2001841
+:106C30003092FFFFAFB10014AFBF0020AFB3001C14
+:106C4000AFB000101240002C000088210A0007B5E8
+:106C50002413000150B300408CE5000C0000000D2F
+:106C6000263900013331FFFF24F800200232382B8F
+:106C700010E00021AF98001C8F8200141440001E09
+:106C80008F87001C3C0670003C0320008CE4000051
+:106C90000086282414A300188F85003C00044402B9
+:106CA0003C0980000089802414A0FFEA310600FF1F
+:106CB000240A000210CA002E28CB0003116000161F
+:106CC000240C000314D3FFE7263900010200282119
+:106CD0000E000703240400018F87001CAF82003CD4
+:106CE000263900013331FFFF24F800200232382B0F
+:106CF00014E0FFE1AF98001C022010218FBF00209C
+:106D00008FB3001C8FB200188FB100148FB0001029
+:106D100003E0000827BD002810CC001A240D000451
+:106D200014CDFFD026390001308EFFFF000E19C0B0
+:106D30008F4401B80480FFFE3C0F10003C1020047B
+:106D4000AF430180AF400184AF500188AF4F01B81D
+:106D50000A0007B0263900010E0006F5240400845D
+:106D60001600FFBF8F87001C0A0007AFAF80003CF2
+:106D7000020028210E000703000020210A0007CE90
+:106D80008F87001C0E000743020020218F87001C04
+:106D90000A0007CFAF82003C3082FFFF144000039F
+:106DA000000018210004240224030010308500FF95
+:106DB00014A000053087000F24660008000422029A
+:106DC00030C300FF3087000F14E000053089000356
+:106DD0002468000400042102310300FF308900030D
+:106DE00015200005388B0001246A0002000420826F
+:106DF000314300FF388B0001316400011080000234
+:106E0000246C0001318300FF03E0000800601021C2
+:106E1000308BFFFF000B394230E600FF3C090800D1
+:106E200025295BB800064080010960218D8700009C
+:106E30003164001F240A0001008A180430A500FFF5
+:106E400000E3202514A000020003102700E2202404
+:106E5000240F000100CF700401096821000E2827CB
+:106E600014800005ADA400008F86000C00A610243D
+:106E700003E00008AF82000C8F88000C01C81025C9
+:106E800003E00008AF82000C3C06001F3C036000DA
+:106E90003084FFFF34C5FF8024020020AC6020084E
+:106EA000AC60200CAC602010AC652014AC642018E1
+:106EB000AC622000000000000000000003E00008B9
+:106EC0000000000027BDFFE82402FFFFAFBF001055
+:106ED000AF82000C000020213C06080024C65BB8ED
+:106EE0002405FFFF24890001000440803124FFFFB6
+:106EF000010618212C87002014E0FFFAAC65000081
+:106F00000E00083900002021240200013C0460002A
+:106F100024050020AC822018AC8520000000000071
+:106F20000000000000000000244A00013142FFFF81
+:106F30002C46040014C0FFF78FBF001003E00008C8
+:106F400027BD00188F8300082C62040003E00008AE
+:106F5000384200018F8300082462000103E000082A
+:106F6000AF8200088F8300082462FFFF03E000085F
+:106F7000AF82000827BDFFE0AFB10014AFBF00181B
+:106F8000AFB000108F6B00303C066000008088219D
+:106F9000ACCB20088F6A002C3C0280002403000840
+:106FA000ACCA200C9769003A9768003800092C0099
+:106FB0003107FFFF00A72025ACC42010ACC220146D
+:106FC000ACC3200000000000000000000000000032
+:106FD0003C0360008C6D200031AC00081580FFF987
+:106FE000000000008C6E201405C00020000000008E
+:106FF0000E0007FD8F84000C000240803C09080051
+:1070000025295BB8010938218CE400000E0007FD3A
+:1070100000028140020220213090FFFF0200202167
+:107020000E00081B000028213C0C8000022C582573
+:107030003210FFFF3C116000240A0020AE2B201408
+:10704000AE302018AE2A2000000000000000000032
+:1070500000000000020010218FBF00188FB1001443
+:107060008FB0001003E0000827BD00208C662014BC
+:107070003C02001F3443FF803C1FFFE800C3C024D4
+:1070800037F9080003198021001079C23C0C8000F8
+:10709000022C582531F0FFFF3C116000240A00202B
+:1070A000AE2B2014AE302018AE2A200000000000C5
+:1070B0000000000000000000020010218FBF001837
+:1070C0008FB100148FB0001003E0000827BD00202E
+:1070D00027BDFFE8AFB000103402FFFF3090FFFF84
+:1070E000AFBF001412020006020020210E00083972
+:1070F00000000000020020210E00081B24050001F2
+:107100008F8400088FBF00148FB000102483FFFF0E
+:1071100027BD001803E00008AF830008000439C24F
+:1071200030E6003F00043B420007184024021000F4
+:107130002CC4002024C8FFE0AF42002C24630001CF
+:107140001480000330A900FF00071840310600FF3B
+:107150000003608024080001019A58213C0A000EB7
+:1071600000C82804016A38211120000500053027D5
+:107170008CE900000125302503E00008ACE60000A2
+:107180008CEE000001C6682403E00008ACED0000AE
+:1071900027BDFFE8AFBF0014AFB000103C04600093
+:1071A0008C8508083403F00030A2F000504300063C
+:1071B000240200018C8708083404E00030E6F00067
+:1071C00010C4001E24020002AF8200403C10600088
+:1071D0003C0A0200AE0A0814240910003C08000E04
+:1071E0008E03440003482021AF49002C24050120D0
+:1071F0000E000CE3000030218F830040106000047B
+:107200003C021691240B0001106B000E3C023D6CF9
+:10721000344F0090AE0F44088FBF00148FB00010A1
+:107220003C0C6000240E10003C0D020027BD00182D
+:10723000AD8E442003E00008AD8D08100A00090A55
+:10724000AF8000403C0218DA344F0090AE0F440883
+:107250008FBF00148FB000103C0C6000240E100093
+:107260003C0D020027BD0018AD8E442003E000084D
+:10727000AD8D08100A0008DE240500010A0008DEB2
+:10728000000028213C08080025085FC42404FFFFF3
+:10729000010018212402001E2442FFFFAC640000FC
+:1072A0000441FFFD246300043C07080024E760401C
+:1072B0008CE5FFFC2404001C24060001308A001F1A
+:1072C0000146480424840001000910272C83002073
+:1072D0001460FFFA00A22824ACE5FFFC3C056666BA
+:1072E00034A4616E3C06080024C66100AF840058D7
+:1072F000AF88009C2404FFFF00C018212402001F57
+:107300002442FFFFAC6400000441FFFD246300043D
+:107310003C0766663C05080024A560C0AF860048AF
+:1073200034E6616EAF8600982404FFFF00A01821A8
+:107330002402000F2442FFFFAC6400000441FFFD63
+:10734000246300043C0B66663C06080024C66040CB
+:107350003568616EAF8500A4AF8800702404FFFF1C
+:1073600000C018212402001F2442FFFFAC6400006B
+:107370000441FFFD246300043C0D66663C0A0800DE
+:10738000254A618035AC616EAF860090AF8C005CA1
+:107390002404FFFF01401821240200032442FFFFC0
+:1073A000AC6400000441FFFD246300043C090800B4
+:1073B000252961908D27FFFC240400062405000187
+:1073C0003099001F0325C004248400010018782789
+:1073D0002C8E002015C0FFFA00EF3824AD27FFFCEB
+:1073E0003C09666624030400240403DC240502002F
+:1073F000240600663522616E3C08080025085CC43E
+:10740000AF820074AF830044AF83006CAF83005041
+:10741000AF830084AF8A008CAF840064AF85004CDA
+:10742000AF860054AF840078AF850060AF860080DF
+:1074300001001821240200022442FFFFAC6000007A
+:107440000441FFFD24630004240400032403000C12
+:107450003C0A0800254A5CD0AF8A00680A0009B1DE
+:107460002405FFFF000418802484000100685821CF
+:107470002C8700C014E0FFFBAD6500003C0E666683
+:1074800035CD616E240C17A024081800AF8D00883C
+:10749000AF8C009403E00008AF88007C2484007F58
+:1074A000000421C2000040210000302100003821EA
+:1074B000000028210A0009C8AF8400A0106000065F
+:1074C00024E7000100C4302124A500012CC20BF5E3
+:1074D0001440FFFA2CA300663C09080025296180AE
+:1074E00001201821240200032442FFFFAC600000A9
+:1074F0000441FFFD2463000410E0001A24E3FFFFB1
+:107500000003294210A0000A000020212406FFFFEA
+:107510003C03080024636180248400010085502B13
+:10752000AC660000250800011540FFFB2463000441
+:1075300030E2001F1040000800086880240C0001A1
+:10754000004C3804000858800169282124E6FFFF18
+:1075500003E00008ACA6000001A940212409FFFFB8
+:10756000AD09000003E0000800000000AF4400285F
+:107570003C04000C03442021000528820A000CE38F
+:1075800000003021000421803C036000AC6410083E
+:107590000000000000052980AC65100C0000000010
+:1075A00003E000088C62100C27BDFFE80080282152
+:1075B00024040038AFBF00140E0009F8AFB000106B
+:1075C00024040E00AF4400283C10000C035020217E
+:1075D000240500100E000CE30000302103501021A0
+:1075E000AC400000AC400004240400388FBF0014FD
+:1075F0008FB0001024053FFF27BD00180A0009F8CE
+:107600008C430000000421803C036000AC6410083F
+:10761000000000008C62100C03E0000800021182E0
+:1076200027BDFFC8AFB400208F940068AFBE003004
+:10763000AFB7002CAFB600280000B8210080B02101
+:10764000241E00C0AFBF0034AFB50024AFB3001C90
+:10765000AFB20018AFB10014AFB000100A000A3585
+:10766000AFA5003C504000018F94006827DEFFFF6B
+:1076700013C00028269400048E9200003C030800EA
+:1076800024635FC01240FFF70283102B3C04080004
+:1076900024845CC4028410230002A8C00000982146
+:1076A0000A000A442411000100118840122000261B
+:1076B0000000000002B38021025128240200202192
+:1076C00010A0FFF9267300010E000A01000000005F
+:1076D0000016684032EC000101AC20210E0009F8D0
+:1076E000020028218F89009426F700018FA6003C14
+:1076F0003AEB0001316A00012528FFFF001138270D
+:1077000002CAB021AF88009416E6FFE70247902432
+:10771000AE92000002E010218FBF00348FBE003017
+:107720008FB7002C8FB600288FB500248FB40020AF
+:107730008FB3001C8FB200188FB100148FB00010EF
+:1077400003E0000827BD00383C0E080025CE5FC0CE
+:10775000028E102B0A000A30AE92000027BDFFD81F
+:10776000AFB10014AFB00010AFBF0020AFB3001C2A
+:10777000AFB2001800A0882110A0001F00048040B4
+:107780003C13080026735CC40A000A7D2412000121
+:1077900012200019261000010E000A1802002021F4
+:1077A000000231422444FFA0000618803045001F2B
+:1077B0002C8217A1007318212631FFFF1040FFF41F
+:1077C00000B230048C6900000200202124053FFF34
+:1077D000012640241500FFEE012638250E0009F889
+:1077E000AC6700008F8A0094261000012547000135
+:1077F0001620FFE9AF8700948FBF00208FB3001CD5
+:107800008FB200188FB100148FB0001003E0000891
+:1078100027BD00288F85009C008058210000402152
+:1078200000004821240A001F3C0C0800258C603C05
+:107830003C0D080025AD5FC48CA6000050C00014AC
+:107840000000402100AD1023000238C024030001D5
+:107850000A000AB6000020211500000300E41021F0
+:10786000244820240000482125290001512B001321
+:107870002506DFDC106000062484000100C37024AC
+:1078800015C0FFF5000318400A000AB400004021AB
+:1078900010AC002624A3000400602821254AFFFF25
+:1078A0001540FFE5AF85009C512B00042506DFDC69
+:1078B0000000402103E000080100102100066142A1
+:1078C00030C5001F000C50803C07080024E75FC44F
+:1078D00024040001014730211120000F00A42004DE
+:1078E0003C05080024A56040148000052529FFFF01
+:1078F00024C6000410C5001100000000240400018B
+:107900008CCF00000004C0270004204001F8682448
+:107910001520FFF5ACCD00008F99007801001021F3
+:10792000032B482303E00008AF8900783C050800DA
+:1079300024A55FC40A000ABE000040213C060800DE
+:1079400024C65FC40A000AD724040001308800FF5F
+:10795000240200021102000A240300031103005C48
+:107960008F8900A4240400041104005F240500058D
+:10797000110500670000182103E0000800601021D5
+:107980008F8900483C0C0800258C61003C040800ED
+:1079900024846180240300201060000F000058211F
+:1079A000240D0002240E00033C0F080025EF6100A7
+:1079B0008D27000014E0000B30F9FFFF252900049B
+:1079C0000124C02B53000001018048212463FFFFE4
+:1079D0005460FFF88D2700000160182103E00008C3
+:1079E00000601021132000323C0500FF30E200FF50
+:1079F00000403021104000420000502124050001C9
+:107A0000000020210005C84000A6C0241700000384
+:107A1000332500FF14A0FFFB24840001012CC023A8
+:107A2000001828C000AA6021008C50213144001F9A
+:107A3000240C0001008C18040003102700E23024FD
+:107A4000110D0041AD260000110E004C000A184037
+:107A5000110D00368F87006C510E00568F8C006020
+:107A6000240D0004110D005A8F8E0084240E000591
+:107A7000150EFFDA01601821240B143011400006A6
+:107A8000000018218F8400A024630001006A402BAD
+:107A90001500FFFD016458218F8A0080AF89008C9A
+:107AA000016018212549FFFF0A000B0EAF890080F5
+:107AB00000E52024000736021080FFD0240A0018B9
+:107AC00000075402314600FF0A000B16240A00107A
+:107AD0003C0C0800258C60C03C0408002484610034
+:107AE0000A000AFD240300103C0C0800258C6040AD
+:107AF0003C040800248460C00A000AFC8F890090BE
+:107B000000071A02306600FF0A000B16240A00085C
+:107B10008F89008C3C0C0800258C61803C04080097
+:107B2000248461900A000AFD24030004000A4080B6
+:107B3000250B003024E6FFFF01601821AF890048C3
+:107B40000A000B0EAF86006C000AC982001978800B
+:107B50003C07080024E760C001E72021000A184222
+:107B60008C8F00003079001F032C38040007C027D9
+:107B700001F860240A000B2BAC8C0000000331429A
+:107B80000006288000AF28213062001F8CB800005A
+:107B900024630001004CC804000321420019382767
+:107BA0000004108003073024004F20210A000B6FCF
+:107BB000ACA60000000A68C025AB0032258AFFFF92
+:107BC00001601821AF8900A40A000B0EAF8A006083
+:107BD000254B1030AF8900900160182125C9FFFFA7
+:107BE0000A000B0EAF890084308600072CC2000605
+:107BF0001040001400000000000640803C03080014
+:107C0000246359D4010338218CE40000008000086B
+:107C1000000000002409000310A9000E000000006D
+:107C2000240A000510AA000B00000000240B00012C
+:107C300010AB0008000000008F8C00A010AC000505
+:107C40000000000003E00008000010210A000A9C68
+:107C500000A020210A000AEA00C0202127BDFFE879
+:107C6000308400FF240300021083000BAFBF00101C
+:107C7000240600031086003A2408000410880068D7
+:107C8000240E0005108E007F2CAF14308FBF001023
+:107C900003E0000827BD00182CA200301440FFFCB0
+:107CA0008FBF001024A5FFD0000531C200066880F8
+:107CB0003C07080024E7610001A730218CC90000BF
+:107CC0000005288230AC001F240B0001018B5004FA
+:107CD0008F840048012A4025ACC800008C83000036
+:107CE00050600001AF8600488F98006C30AE0001F4
+:107CF00024A6FFFF270F000115C00002AF8F006C04
+:107D000024A60001000641420008208000871821B7
+:107D10008C79000030C2001F240600010046F804E0
+:107D2000033F382410E0FFDA8FBF00100005C18246
+:107D3000001870803C0F080025EF60C001CF48217B
+:107D40008D2B00000005684231A5001F00A66004CD
+:107D5000016C502527BD001803E00008AD2A000083
+:107D60002CA7003014E0FFCA8FBF001030B9000705
+:107D70001723FFC724A8FFCE00086A02000D608009
+:107D80003C0B0800256B60C0018B30218CC40000C7
+:107D9000000828C230AA001F240800010148480436
+:107DA0008F8200A400891825ACC300008C5F0000FE
+:107DB00053E00001AF8600A400057040000E794238
+:107DC000000F28803C0408002484610000A41821CE
+:107DD0008C6B000025DF000131CD001F001F5142D8
+:107DE00001A86004016C4825000A1080AC690000FD
+:107DF000004428218CA600008F98006033F9001FF2
+:107E00008FBF00100328380400C77825270E000113
+:107E100027BD0018ACAF000003E00008AF8E006083
+:107E200024A5EFD02CB804001300FF998FBF0010D9
+:107E300000053142000658803C0A0800254A60408F
+:107E4000016A30218CC4000030A3001F2409000106
+:107E5000006910048F9900900082F825ACDF0000C3
+:107E60008F27000050E00001AF8600908F8D0084C6
+:107E70008FBF001027BD001825AC000103E00008EB
+:107E8000AF8C008415E0FF828FBF00108F8600A0AA
+:107E9000000610400046F821001F210003E4C8211D
+:107EA0000019384024F8143000B8402B1100FF7836
+:107EB0008FBF001024A4EBD00E00020D00C02821BB
+:107EC00000027942000F70803C0D080025AD6180F2
+:107ED00001CD20218C8B0000304C001F24060001B6
+:107EE000018618048F89008C01635025AC8A00003C
+:107EF0008D25000050A00001AF84008C8F98008079
+:107F00008FBF001027BD00182708000103E00008FC
+:107F1000AF88008030A500072403000310A30010E1
+:107F200028A20004144000082407000224030004CF
+:107F300010A300152408000510A8000F8F8500A0CD
+:107F400003E000080000000014A7FFFD00802821C6
+:107F500014C3FFFB240400020A000BAE0000000063
+:107F6000240900050080282110C9FFFB2404000318
+:107F700003E000080000000014C5FFF10080282184
+:107F80000A000BAE24040005240A00010080282109
+:107F900010CAFFF12404000403E000080000000000
+:107FA00027BDFFE0AFB00010000581C22603FFD05F
+:107FB00024C5003F2C6223D024C6007FAFB2001836
+:107FC000AFB10014AFBF001C309100FF000691C29A
+:107FD0000005298202002021104000082403FFFF31
+:107FE0000E000A6E0000000002002021022028215D
+:107FF0000E000C5C02403021000018218FBF001CD5
+:108000008FB200188FB100148FB0001000601021E3
+:1080100003E0000827BD002027BDFFD824A2007F71
+:10802000AFB3001CAFB20018000299C2309200FF3B
+:1080300024A3003F0240202102602821AFB1001498
+:10804000AFB00010AFBF00200E000B91000389827B
+:1080500000408021004020210220282114400009F6
+:10806000000018218FBF00208FB3001C8FB20018B2
+:108070008FB100148FB000100060102103E00008E1
+:1080800027BD00280E000A1F000000000040282124
+:10809000020020211051FFF3001019C00E000A6EDB
+:1080A0000000000002002021024028210E000C5C8C
+:1080B000026030218FBF00208FB3001C8FB20018E8
+:1080C0008FB100148FB00010000018210060102143
+:1080D00003E0000827BD00283084FFFF30A5FFFF24
+:1080E00010800007000018213082000110400002BB
+:1080F00000042042006518211480FFFB0005284081
+:1081000003E000080060102110C00007000000001C
+:108110008CA2000024C6FFFF24A50004AC8200004E
+:1081200014C0FFFB2484000403E0000800000000EA
+:1081300010A0000824A3FFFFAC8600000000000090
+:10814000000000002402FFFF2463FFFF1462FFFA17
+:108150002484000403E000080000000030A5FFFFB5
+:108160008F4201B80440FFFE3C07601500A7302590
+:108170003C031000AF440180AF400184AF4601884A
+:1081800003E00008AF4301B88F8500D02C86400083
+:10819000008018218CA700840087102B1440001049
+:1081A000000000008CA800842D06400050C0000F85
+:1081B000240340008CAA0084008A482B512000012F
+:1081C0008CA3008400035A42000B20803C05080069
+:1081D00024A55A400085182103E000088C620000A5
+:1081E00014C0FFF4000000002403400000035A42C2
+:1081F000000B20803C05080024A55A40008518216A
+:1082000003E000088C6200008F8300D0906600D0ED
+:1082100024C50001A06500D08F8500D0906400D0F7
+:1082200090A200D21044001700000000936C007868
+:108230008F8B00BC318A00FFA16A000C2549000128
+:10824000938700C4312200FF3048007F1107000BE4
+:1082500000026827A36200788F4E017805C0FFFEF8
+:108260008F9900B0241800023C0F1000AF59014054
+:10827000A358014403E00008AF4F01780A000D2C19
+:1082800031A20080A0A000D00A000D220000000052
+:1082900027BDFFD8AFB200188F9200B8AFBF002043
+:1082A000AFB3001CAFB00010AFB100148F9300B497
+:1082B0008E5900283C1000803C0EFFEFAE79000084
+:1082C0008E580024A260000A35CDFFFFAE7800046E
+:1082D0009251002C3C0BFF9F356AFFFFA271000CEE
+:1082E0008E6F000C3C080040A271000B01F060256D
+:1082F000018D4824012A382400E83025AE66000CA0
+:108300008E450004AE6000183C0400FFAE6500140A
+:108310008E43002C3482FFFFA66000080062F82420
+:10832000AE7F00108E5900088F9000B0964E00125C
+:10833000AE7900208E51000C31D83FFF00187980B3
+:10834000AE7100248E4D001401F0602131CB00018C
+:10835000AE6D00288E4A0018000C41C2000B4B8005
+:10836000AE6A002C8E46001C01093821A667001C4D
+:10837000AE660030964500028E440020A665001EC1
+:10838000AE64003492430033306200045440000570
+:10839000924600008F8300D08C7F007CAE7F00303F
+:1083A000924600008F8500BCA0A6000092440033D6
+:1083B0003082000250400007924E00018F8700BCBF
+:1083C000240AFF8090E90000012A4025A0E800006F
+:1083D000924E00018F8D00BC2409FFBF2404FFDFF3
+:1083E000A1AE00018F8A00BC914C000D318B007F43
+:1083F000A14B000D8F8600BC90C8000D01093824E8
+:10840000A0C7000D8F9100BC8E6500149223000D53
+:108410002CA200010002F9400064C824033FC025DB
+:10842000A238000D8F8800BC965000128F8700D0B4
+:10843000A51000028E45000490ED00BC30AF000393
+:10844000000F702331CC000300AC102131AB0002CF
+:1084500015600002244400342444003090F100BC34
+:1084600000B18024320F000415E0000224830004D0
+:10847000008018218F8900AC240A0002AD0300049B
+:10848000A12A00009248003F8F8700ACA0E80001BD
+:108490008F9100AC9246003F8E440004A626000255
+:1084A0009765003C0E000CF930B0FFFF000213800E
+:1084B000005020253C0342000083F825AE3F000415
+:1084C0008F8500AC8E590038ACB900188E58003436
+:1084D000ACB8001CACA0000CACA00010A4A0001410
+:1084E000A4A00016A4A00020A4A00022ACA00024F8
+:1084F0008E62001450400001240200018FBF002052
+:108500008FB3001C8FB200188FB100148FB0001011
+:10851000ACA200080A000D1927BD00288F8600D0E4
+:1085200027BDFFD0AFBF002CAFB60028AFB50024E9
+:10853000AFB40020AFB3001CAFB20018AFB100144D
+:10854000AFB0001094C300E094C200E210430041B9
+:108550002405FFFF3C16000E90C400D090C800D147
+:10856000309200FF310400FF0244382B10E0004439
+:1085700026490001108900378F9800B03C0508009B
+:108580008CA5005C2414FF8000B86021019468244D
+:10859000AF4D002C94CA00E2318B007F017A482154
+:1085A00031447FFF01364021000410400048A821DB
+:1085B00096A700003C1F08008FFF005830F53FFFD2
+:1085C0000015198003E3C821031988213233007F85
+:1085D000027A782102348024AF50002C01F69821D1
+:1085E000926E000D31C5000410A00048000000008C
+:1085F00094C300E294C300E294D800E22404800013
+:10860000307F7FFF27F9000133317FFF030480248F
+:1086100002117825A4CF00E294CE00E23C120800BB
+:108620008E52006031D47FFF129200DF0000000004
+:108630008E720018000028212646FFFFAE66002C2F
+:108640008F8600D094C800E094C900E21528FFC2CC
+:10865000000000008FBF002C8FB600288FB50024CB
+:108660008FB400208FB3001C8FB200188FB100149C
+:108670008FB0001000A0102103E0000827BD0030DB
+:1086800090CD00D2264A000131AC00FF008C582169
+:10869000116AFFF08F9800B03C0508008CA5005CC3
+:1086A0002414FF8000B8602101946824AF4D002C91
+:1086B00094CA00E2318B007F017A482131447FFF68
+:1086C00001364021000410400048A82196A7000070
+:1086D0003C1F08008FFF005830F53FFF0015198040
+:1086E00003E3C821031988213233007F027A7821FD
+:1086F00002348024AF50002C01F69821926E000DB8
+:1087000031C5000414A0FFBA000000008E660010FE
+:108710000012C0C08E6E00300012914002587821C5
+:10872000036F582100CE6823256C008824020002C4
+:10873000AE6D0010AF8C00ACA1620088976A003C5F
+:108740008E6400308F9100AC0E000CF93150FFFFA9
+:1087500000022380009048253C034200012340256D
+:10876000AE2800048E6700048F8C00AC8E7F000062
+:10877000240D0008AD87001CAD9F0018AD80000CD3
+:10878000AD8000109265000A30B900FFA599001471
+:10879000967800083C05000CA59800169271000A16
+:1087A000322F00FFA58F00209670000824110005CD
+:1087B000A5900022AD800024926E000B2410C00012
+:1087C00031C600FFA5860002A18D00018E6B00302E
+:1087D0008F8200AC8F8800B0AC4B00083C0A0800C8
+:1087E0008D4A00540148202100944824AF490028B4
+:1087F0003C0308008C6300540068382130FF007F80
+:1088000003FAC8210325C02102587821AF8F00BC8C
+:10881000AF9800C0A1F100008F8B00BC2403FFBF04
+:108820002405FFDF956E000201D0A024029590255B
+:10883000A57200029166000230CD003F35AC0040C9
+:10884000A16C00028F8800BC8F8200D03C0C7FFF9F
+:10885000AD0000048C4A007C358BFFFF3C02800099
+:10886000AD0A00089104000D3089007FA109000DB8
+:108870008F9F00BC93F5000D02A33824A3E7000DE1
+:108880008F9100BC9239000D0325C024A238000D41
+:108890008E6F00348F8D00BCADAF00108E6E002C3B
+:1088A0008E70003001D0A023ADB4001491B2001836
+:1088B0003246007FA1A600188F8700BC8E6A003068
+:1088C0008CE40018014B4824008240240109A825AB
+:1088D000ACF500189263000AA0E3001C967F000824
+:1088E0008F8500BC8F9900D0A4BF001E8E70003011
+:1088F0008E6400300E00020D8F2500848F8500D01D
+:10890000000289400002C10090AE00BC023878210C
+:108910000040302131D4000212800003020F802178
+:108920000002A8800215802190B200BC32540004DD
+:10893000128000020006C880021980218E6F00306C
+:108940008F8B00BC2406800031EE0003000E6823EC
+:1089500031AC0003020C1021AD62000494A400E2CB
+:1089600094AA00E294A300E231507FFF26040001A4
+:1089700030897FFF0066402401098825A4B100E208
+:1089800094A700E23C1308008E73006030FF7FFF65
+:1089900013F30012000000000E000D19000000008B
+:1089A0000A000E270000282194CD00E201A46024D3
+:1089B000A4CC00E290CB00E290C200E2316A00FF5A
+:1089C000000A49C200092027000441C03055007F39
+:1089D00002A838250A000E23A0C700E294B100E2E5
+:1089E00002263824A4A700E290BF00E290B400E27F
+:1089F00033F300FF0013C9C2001990273298007F9B
+:108A00000012A9C0031530250E000D19A0A600E222
+:108A10000A000E27000028213084FFFF30A5FFFF49
+:108A2000AF440018AF45001C03E000088F4200145B
+:108A300027BDFFB0AFB000288F9000D0AFB4003892
+:108A4000AFBF004CAFBE0048AFB70044AFB6004068
+:108A5000AFB5003CAFB30034AFB20030AFB1002CC3
+:108A6000A7A00014920600D1920500D03094FFFF19
+:108A700030C400FF30A300FF0064102BA7A0001E2D
+:108A800010400071AFA00010920900D00014982B84
+:108A9000312800FF0088382324F2FFFF0012882BC2
+:108AA0000233782451E000758FB20010961800123E
+:108AB000961900100014F4000319B8230017B4002D
+:108AC000001614030282A82A16A00002001E240326
+:108AD000004020210244F82B13E0000200801821FE
+:108AE000024018210003340000061C033065FFFF1C
+:108AF0002CA20009144000020060982124130008F1
+:108B00008E090008001359808E08000C3164FFFFA5
+:108B10003C0A0010008A3825274A0400AF49003873
+:108B2000AF8A00B8AF48003CAF47003000000000FB
+:108B30000000000000000000000000000000000035
+:108B40000000000000000000000000008F4D000049
+:108B500031AC00201180FFFD0013702A01D11024D8
+:108B60000000A821104001C0000000008F9800B054
+:108B70003C0B08008D6B00542411FF80921E00D026
+:108B80000178202100911024921900D0AF420028D2
+:108B90008D4500103C0608008CC600583C170800A4
+:108BA0008EF7005430A73FFF0007198000C3402113
+:108BB000030820210091F824920B00D0AF5F002C15
+:108BC0009148000033D600FF332F00FF02F87021D8
+:108BD00000166140000F68C031C9007F018D382147
+:108BE000013A2821316300FF3086007F3C02000CEF
+:108BF00000A2B021000389400367C82100DAF821F0
+:108C00003108003F3C1E000E0236B821273800888C
+:108C100003FE88212D0F0008AF9800ACAF9700BC71
+:108C2000AF9600C011E0018FAF9100B400086880DA
+:108C30003C0E080025CE59EC01AE60218D89000064
+:108C40000120000800000000920E00D2920D00D01A
+:108C50000014982B31CA00FF31AC00FF008C582360
+:108C6000014B20212492FFFF0012882B023378242D
+:108C700015E0FF8E000000008FB200108FBF004C87
+:108C80008FBE00483A4200018FB700448FB60040C3
+:108C90008FB5003C8FB400388FB300348FB20030F2
+:108CA0008FB1002C8FB0002803E0000827BD0050D2
+:108CB000915800013317002012E00204241600012D
+:108CC000921F00BC0000B02133F900011320000DF9
+:108CD000241E00018D4800148E0300840103B02B74
+:108CE00016C00002010030218E0600848E0500644B
+:108CF00000C5382B14E0000200C020218E0400645F
+:108D00000080B0218D4200148E0B0064004B302B8C
+:108D100014C00002004020218E0400640096B82395
+:108D200056E00001241E0002025E202B1480014840
+:108D3000000018218D5900388E2F000C3C1800803F
+:108D4000AE3900008D5000343C0EFF9F01F86025C5
+:108D5000AE3000049149003F35CDFFFF018D202446
+:108D60003C0A00203C0BFFEFA229000B008A3825AB
+:108D70003562FFFF00E228243C0600088F8700B818
+:108D800000A6C825AE39000C8CE30014AE200018F4
+:108D90003C08FFFBAE2300148CF80018351FFFFFC2
+:108DA000033F7024AE38001C8CEF000802D78021EE
+:108DB000AE2F00248CED000CAE30002CAE2E000C3B
+:108DC000AE2D0020AE200028A6200038A620003AB4
+:108DD0008CEC0014019648230137502311400011F8
+:108DE000AE2A001090EE003D8E2C00048E24000070
+:108DF000000E6900018D28210000502100AD302BAC
+:108E0000008A582101661021AE250004AE22000020
+:108E100090E3003DA223000A8F8800B8951F00064A
+:108E2000A63F00088F8B00AC2406000202C0202160
+:108E3000A16600009765003C8F9000AC30A2FFFF58
+:108E40000E000CF9AFA200208FA300200002438087
+:108E50008F8500B80103C8253C1F4200033FC02591
+:108E6000AE1800048F8400AC8CAF0038AC8F0018B3
+:108E70008CB00034AC90001CAC80000CAC800010B6
+:108E8000A4800014A4800016A4800020A4800022E6
+:108E9000AC80002490A7003FA487000212C00210FB
+:108EA000240D000152E0000290A2003D90A2003E7D
+:108EB000244A0001A08A00018F8400ACAC9600080F
+:108EC0008F8300D024070034906F00BC31EE000285
+:108ED00051C00001240700308F8200B88F9900BC78
+:108EE000906800BC905F00002410000432CF0003A3
+:108EF000A33F00008F9800B88F8C00BC020F702336
+:108F0000930D00012405C00031CA0003A18D0001AA
+:108F10008F9000BC8F8900B800F6382196040002BB
+:108F20009526001200EA38210085582430C33FFFFF
+:108F300001631025A6020002921F000231080004FE
+:108F400033F9003F37380040A218000212C0000277
+:108F50008F8500BC00E838218F8600D0ACA70004C4
+:108F6000241FFFBF8CC3007C2ECB0001240FFFDF2A
+:108F7000ACA3000890A8000D000B69403102007FEF
+:108F8000A0A2000D8F9000BC9219000D033FC024D9
+:108F9000A218000D8F8A00BC914E000D01CF6024F5
+:108FA000018D4825A149000D8F8600B88F8B00BC2C
+:108FB0008CC70020AD6700108CC50024AD6500147F
+:108FC0008CC40028AD6400188CC3002C0E000D1951
+:108FD000AD63001C2408000257C8009C8F9000D08D
+:108FE0008F8F00D08F8A00C002E0202191E800D04E
+:108FF00091EB00D091E700D0311000FF316E00FFFF
+:1090000000106940000E28C001A5182130E900FFBA
+:109010000363C8210009314000CAF82127220088D3
+:10902000AF8200ACAF9F00BCA33E00880E000CF9DD
+:109030008F9000AC8FB80020000263803C0F42008C
+:10904000019840258F8C00B8010F5825AE0B000405
+:109050008D8400388F8B00AC00002821000539007A
+:10906000AD6400188D8E00343C0F7FFF35E8FFFFA4
+:10907000AD6E001C9183003E8D69001C8D6600184A
+:109080000003510000036F02012AC02100ED1025EA
+:10909000030AF82B00C2C821033F8021AD78001CD1
+:1090A000AD700018AD60000CAD6000109184003E02
+:1090B000241F00052410C000A5640014958E000430
+:1090C00002E8402402E02021A56E00169185003EB2
+:1090D000A5650020958D0004A56D0022AD600024DB
+:1090E0009187003FA56700029183003E9189003D72
+:1090F0000123502325460001A16600018F8200ACA8
+:109100008F9900BCAC570008A33F00008F8A00BCB9
+:109110008F9800B8954F0002970E00122418FFBFD9
+:10912000020F682431C53FFF01A53825A54700027D
+:10913000914C00022405FFDF3189003F35230040B8
+:10914000A14300028F9900BC8F8600D02409FFFF45
+:10915000AF2000048CCB007C2403FF80AF2B0008E1
+:109160009322000D3C0B8000305F007FA33F000D79
+:109170008F8E00BC91D0000D02187824A1CF000D75
+:109180008F8C00BC918D000D01A53824A187000DA6
+:109190008F8600BCACC90010ACD6001490CA001871
+:1091A0000143B025A0D600188F8F00BC8F9800B85F
+:1091B0008DE20018004BF82403E8C825ADF900182B
+:1091C0009310003EA1F0001C8F8E00B88F8D00BC64
+:1091D0008F8700D095C50004A5A5001E0E00020DC6
+:1091E0008CE500848F8700D00002614000022100DE
+:1091F00090EA00BC01844821004028213156000239
+:1092000012C0000302E930210002B08000D63021F4
+:1092100090EC00BC318400041080000332EA0003AB
+:109220000005C08000D83021240900048F9700BCBD
+:10923000012A1023305F000300DFC821AEF90004CB
+:109240000E000D19A62500388F9000D003C01821FC
+:10925000146000020060B0210000902156C000861A
+:109260008F9700B80012882B9609001002955023A2
+:109270003C14002002A91021A6020010AF540030B7
+:109280003154FFFF0000000096130010961F0012DB
+:1092900013F30011000000008E17000C8E0C000864
+:1092A0000015C98002F94021001927C30119B02B0C
+:1092B0000184782101F65821AE08000CAE0B00089D
+:1092C0000014A82B023580241200FE6B8F9000D072
+:1092D0000A000F4200000000960B00148E050004E7
+:1092E0003163FFFF000370C000AE3821AF47003C80
+:1092F0008E0600048F4D003C00CDF0231BC00036CD
+:10930000000000008E080000250200013C1600103D
+:1093100036CF0008AF420038AF4F003000000000E9
+:10932000000000000000000000000000000000003D
+:109330000000000000000000000000008F4400005A
+:10934000308C00201180FFFD000000008F590400C8
+:109350003C170020AE1900088F550404AE15000C10
+:10936000AF570030000000003C0608008CC60044E7
+:109370002418000110D800D3000000009607001246
+:109380003C0508008CA5004000A76821A60D00122E
+:10939000961E001427C90001A609001496020014A5
+:1093A0003044FFFF5486FFC70014A82B30A5FFFFF1
+:1093B0000E000F1DA60000143C0308008C6300245F
+:1093C000960500120043702300AE3023A60600125B
+:1093D0000A0011480014A82B8E0200000A00115B3D
+:1093E0003C1600109156000124100001001678422E
+:1093F00015F0001C97A8001E8D5F00142411C000FA
+:1094000033FE3FFF0111C8243C1808008F1800608C
+:10941000033EB82532E53FFF00B8502B1140001144
+:10942000A7B7001E3C1008008E1000588F8F00B0A8
+:1094300000057180240CFF80020F682101AE4821D5
+:109440003124007F012C5824009A28213C02000E70
+:10945000AF4B002C00A2302190C7000D34E3000474
+:10946000A0C3000D0E000D3B000000008F9000D047
+:10947000240300018F9700B826B900010019AC0041
+:10948000024390230015AC0326F8004002B3202AC3
+:109490000012882B240C000103005021009110249D
+:1094A000AF9800B80A000F70AFAC001095560012CC
+:1094B0008F8400B032C5FFFF0E000CEEA7B600147B
+:1094C0008F9000D00A0011B4000018218D59003887
+:1094D000A620000824040003AE3900008D57003494
+:1094E000A220000A8F9800B8AE3700043C0F00801D
+:1094F000930C003FA224000C8E28000C3C0BFF9F15
+:10950000A22C000B010F1825356EFFFF3C05FFEF65
+:109510008F9700B8006E682434A7FFFF01A730249E
+:10952000AE26000C8EFE001496FF00128F8200B053
+:10953000AE3E00108EF00014AE200018AE200020C9
+:10954000AE300014AE2000248EE9001833F03FFF47
+:1095500000105180AE2900288EF900080142C02178
+:1095600033EC0001AE3900308EEB000C8F8500AC7F
+:10957000001879C2000C238001E44021240E00026F
+:10958000A628001CA6200036AE2B002CA0AE0000A2
+:109590009767003C8F8A00AC3C03420030EDFFFF30
+:1095A00001A33025AD4600048F9E00B824020001BF
+:1095B0002408C0008FD1003824060034AD510018B3
+:1095C0008FC90034AD49001CAD40000CAD40001007
+:1095D000A5400014A5400016A5400020A54000228B
+:1095E000AD400024A5560002A14200018F9F00ACAF
+:1095F0008F9900B88F9800BCAFF600089337000031
+:10960000A31700008F8C00B88F8F00BC91840001DD
+:10961000A1E400018F8D00BC95AB000201687024AD
+:1096200001D02825A5A5000291A7000230E3003F44
+:10963000A1A300028F8300D08F8400BC907100BC76
+:10964000323E000253C0000124060030AC86000404
+:109650008C6F007C2403FFBFAC8F00089088000D46
+:10966000310B007FA08B000D8F8700BC90EE000DAA
+:1096700001C32824A0E5000D8F9E00BC93CD000DF2
+:1096800035A60020A3C6000D8F8A00B88F9100BCBC
+:109690008D500020AE3000108D490024AE290014FA
+:1096A0008D420028AE2200188D5F002CAE3F001CBA
+:1096B0000E000D19000000008F9000D00A00112E3E
+:1096C00002C01821960A00123C1F08008FFF0024D8
+:1096D00003EA9821A61300120A0011480014A82BCF
+:1096E000A08D00018F8900AC240C0001AD2C000876
+:1096F0000A0010488F8300D027BDFFE03C18080007
+:109700008F180050AFB00010AFBF0018AFB10014F9
+:10971000AF8400B093710074030478212410FF809B
+:1097200031EE007F3225007F01F0582401DA6821F4
+:109730003C0C000AA38500C401AC2821AF4B0024D7
+:1097400094A900109768000690A600620080382156
+:10975000240200300109202330C300F0AF8500D07F
+:10976000106200193090FFFF90AE0062240DFFF0F0
+:10977000240A005001AE6024318B00FF116A002FD3
+:109780000000000016000007241F0C00AF5F00243B
+:109790008FB100148FBF00188FB0001003E00008D5
+:1097A00027BD00200E000F2302002021241F0C00E3
+:1097B000AF5F00248FB100148FBF00188FB000106E
+:1097C00003E0000827BD002094A200E094A400E27A
+:1097D00090BF0113008218263079FFFF33E700C0E5
+:1097E00014E000092F3100011600003800000000CD
+:1097F0005620FFE6241F0C000E000DDE00000000C6
+:109800000A00127A241F0C001620FFDE0000000060
+:109810000E000DDE000000001440FFDC241F0C00D1
+:10982000160000228F8300D0906901133122003F7F
+:10983000A06201130A00127A241F0C0094AF00D416
+:109840008F8600D400E02821240400050E000C7F40
+:1098500031F0FFFF1440000524030003979100E658
+:10986000000018212625FFFFA78500E68F5801B8C4
+:109870000700FFFE3C196013AF400180241F0C005D
+:10988000AF500184007938253C101000AF470188A3
+:109890008FB10014AF5001B8AF5F00248FB000103B
+:1098A0008FBF001803E0000827BD00200E000F2323
+:1098B000020020215040FFB5241F0C008F8300D0F0
+:1098C000906901130A0012A33122003F0E000F23FA
+:1098D000020020211440FFAD241F0C0012200007BD
+:1098E0008F8300D0906801133106003F34C20040DE
+:1098F000A06201130A00127A241F0C000E000DDE74
+:10990000000000005040FFA1241F0C008F8300D0F6
+:10991000906801133106003F0A0012D334C20040A0
+:10992000AF9B00C803E00008AF8000EC3089FFFF68
+:10993000000940422D020041000929801440000224
+:109940000009504024080040000879400008C0C0C9
+:1099500001F85821256701A800EF702125CC007F70
+:10996000240DFF80018D18240065302100CA2821B4
+:1099700025640088240A00883C010800AC2A004CB9
+:109980003C010800AC240050AF8500D43C01080025
+:10999000AC2900603C010800AC2800643C010800D0
+:1099A000AC2700543C010800AC2300583C010800DF
+:1099B000AC26005C03E0000800000000308300FFDC
+:1099C00030C6FFFF30E400FF8F4201B80440FFFEC5
+:1099D00000034C00012438253C08600000E82025E5
+:1099E0003C031000AF450180AF460184AF440188BD
+:1099F00003E00008AF4301B88F86001C3C096012E9
+:109A0000352700108CCB00043C0C600E358500100F
+:109A1000316A00062D480001ACE800C48CC4000483
+:109A2000ACA431808CC2000894C30002ACA2318483
+:109A300003E00008A78300E43C0308008C630050A7
+:109A40008F8400E88F86001C2402FF800064C02100
+:109A50000302C824AF5900288CCD00043305007FD1
+:109A600000BA78213C0E000C01EE2821ACAD005864
+:109A70008CC80008AF8500D03C076012ACA8005C21
+:109A80008CCC001034E80010ACAC000C8CCB000C7B
+:109A9000ACAB000894AA00143C0208008C420044BD
+:109AA00025490001A4A9001494A400143083FFFFE9
+:109AB000106200178F8400D03C0A08008D4A0040D5
+:109AC000A4AA00128CCE0018AC8E00248CCD0014F9
+:109AD000AC8D00208CC70018AC87002C8CCC0014F7
+:109AE00024060001AC8C00288D0B00BC5166001AC6
+:109AF0008D0200B48D0200B8A482003A948F003A1F
+:109B0000A48F003C948800D403E000083102FFFFDA
+:109B10003C0908008D290024A4A000148F8400D0E3
+:109B2000A4A900128CCE0018AC8E00248CCD001499
+:109B3000AC8D00208CC70018AC87002C8CCC001496
+:109B400024060001AC8C00288D0B00BC5566FFEA92
+:109B50008D0200B88D0200B4A482003A948F003ABE
+:109B6000A48F003C948800D403E000083102FFFF7A
+:109B70008F86001C3C0C08008D8C0050240BFF804D
+:109B80008CCD00083C03000C000D51C0018A40211F
+:109B9000010B4824AF8A00E8AF49002890C70007AE
+:109BA0003105007F00BA10210043282130E4000471
+:109BB0001080002FAF8500D090CF000731EE000855
+:109BC00011C0003C000000008CD9000C8CC40014B3
+:109BD0000324C02B13000026000000008CC2000CE0
+:109BE000ACA200648CCD00182402FFF8ACAD006874
+:109BF0008CCC0010ACAC00808CCB000CACAB0084E7
+:109C00008CCA001CACAA007C90A900BC0122402494
+:109C1000A0A800BC90C300073067000810E0000453
+:109C20008F8500D090AF00BC35EE0001A0AE00BC27
+:109C300090D90007333800011300000F8F8400D043
+:109C400024070020908200BC34490002A08900BC97
+:109C50008F8400D090880062310300F01467000602
+:109C6000240A0034AC8A00C00A0013B500000000CA
+:109C70000A00138F8CC2001490CB000731660002DB
+:109C800010C0000500000000908D00BC35AC000441
+:109C9000A08C00BC8F8400D090980113330F003F3C
+:109CA000A08F01138F8E00D095C500D403E000086B
+:109CB00030A2FFFFACA000640A0013900000000077
+:109CC00027BDFFD8AFB000108F90001CAFBF00249D
+:109CD000AFB40020AFB20018AFB10014AFB3001C96
+:109CE0009613000E3C07600A3C1460063264FFFFC6
+:109CF000369300100E0012E234F404108F8400D466
+:109D00003C11600E0E0009BE36310010920E001597
+:109D10003C0708008CE700603C12601231CD000F58
+:109D2000A38D00F08E0E00048E0D00089608001220
+:109D3000961F00109619001A9618001E960F001C08
+:109D4000310CFFFF33EBFFFF332AFFFF3309FFFF27
+:109D500031E6FFFF3C010800AC2B00403C0108004D
+:109D6000AC2C00243C010800AC2A0044AE29317818
+:109D7000AE26317C92020015960300163652001072
+:109D8000304400FF3065FFFF3C0608008CC60064CD
+:109D9000AE243188AE4500B492080014961900181C
+:109DA000241F0001011FC004332FFFFF3C050800E2
+:109DB0008CA50058AE5800B8AE4F00BC920C0014F1
+:109DC000AF8E00D8AF8D00DC318B00FFAE4B00C0F2
+:109DD000920A0015AE670048AE66004C314900FF9C
+:109DE000AE4900C8AE65007C3C0308008C6300509F
+:109DF0003C0408008C84004C3C0808008D0800548A
+:109E00003C0208008C42005C8FBF0024AE630080DF
+:109E10008FB00010AE8300748FB3001CAE22319C53
+:109E2000AE4200DCAE2731A0AE2631A4AE24318C88
+:109E3000AE233190AE283194AE253198AE870050D4
+:109E4000AE860054AE8500708FB10014AE4700E0BE
+:109E5000AE4600E4AE4400CCAE4300D0AE4800D4E1
+:109E6000AE4500D88FB400208FB2001803E0000880
+:109E700027BD002827BDFFE0AFB10014AFBF001819
+:109E8000241100010E000868AFB000101051000549
+:109E9000978400E6978300CC0083102B14400008C1
+:109EA0008F8500D4240700028FBF00188FB10014E3
+:109EB0008FB0001000E0102103E0000827BD002053
+:109EC0000E000C9D24040005AF8200E81040FFF650
+:109ED000240700020E00086C8F90001C979F00E67C
+:109EE0008F9900E88F8D00C827EF0001240E0050E5
+:109EF000AF590020A78F00E6A1AE00003C0C08007F
+:109F00008D8C00648F8600C8240A8000000C5E00DF
+:109F1000ACCB0074A4C0000694C9000A241FFF80C3
+:109F20003C0D000C012AC024A4D8000A90C8000AE5
+:109F300024182000011F1825A0C3000A8F8700C81D
+:109F4000A0E000788F8500C800003821A0A0008321
+:109F50003C0208008C4200508F8400E800447821C5
+:109F600001FFC824AF590028960B000231EE007F94
+:109F700001DA6021018D3021A4CB00D4960A0002C1
+:109F8000AF8600D03C0E000425492401A4C900E698
+:109F90008E080004ACC800048E030008ACC30000A7
+:109FA000A4C00010A4C00014A0C000D08F8500D0B1
+:109FB0002403FFBFA0A000D13C0408008C840064EF
+:109FC0008F8200D0A04400D28E1F000C8F8A00D058
+:109FD000978F00E4AD5F001C8E1900102410003034
+:109FE000AD590018A5400030A5510054A5510056A8
+:109FF000A54F0016AD4E0068AD580080AD580084E6
+:10A00000914D006231AC000F358B0010A14B006206
+:10A010008F8600D090C900633128007FA0C80063FC
+:10A020008F8400D02406FFFF9085006300A31024D6
+:10A03000A08200638F9100D000E01021923F00BC0D
+:10A0400037F90001A23900BC8F8A00D0938F00F04D
+:10A05000AD580064AD5000C0914E00D3000F6900B0
+:10A0600031CC000F018D5825A14B00D38F8500D036
+:10A070008F8900DCACA900E88F8800D88FBF00185A
+:10A080008FB100148FB0001027BD0020ACA800ECE9
+:10A09000A4A600D6A4A000E0A4A000E203E000086B
+:10A0A0000000000027BDFFE0AFB000108F90001C43
+:10A0B000AFB10014AFBF00188E1900043C1808009F
+:10A0C0008F180050240FFF80001989C002387021BA
+:10A0D00031CD007F01CF602401BA50213C0B000C30
+:10A0E000AF4C0028014B4021950900D4950400D6BF
+:10A0F0008E0700043131FFFFAF8800D00E00093613
+:10A10000000721C08E0600048F8300C8000629C006
+:10A11000AF4500209064003E3082004014400006AD
+:10A120008F8400D0341FFFFF948300D63062FFFF7E
+:10A13000145F000400000000948400D60E0008CBD9
+:10A140003084FFFF8E050004022030218FBF0018ED
+:10A150008FB100148FB000102404002200003821B9
+:10A16000000529C00A00130627BD002027BDFFE017
+:10A17000AFB100143091FFFFAFB00010AFBF0018B7
+:10A180001220001D000080218F86001C8CC500005D
+:10A190002403000600053F020005140230E4000716
+:10A1A00014830015304500FF2CA800061100004D57
+:10A1B000000558803C0C0800258C5A0C016C50217D
+:10A1C0008D49000001200008000000008F8E00EC87
+:10A1D000240D000111CD005900000000260B0001E4
+:10A1E0003170FFFF24CA00200211202B01403021D2
+:10A1F0001480FFE6AF8A001C020010218FBF0018F8
+:10A200008FB100148FB0001003E0000827BD0020BC
+:10A21000938700CE14E00038240400140E0013C706
+:10A22000000000008F86001C240200010A00150EA9
+:10A23000AF8200EC8F8900EC240800021128003B5B
+:10A24000240400130000282100003021240700010D
+:10A250000E001306000000000A00150E8F86001C79
+:10A260008F8700EC2405000214E5FFF62404001299
+:10A270000E001373000000008F8500E800403021BD
+:10A28000240400120E001306000038210A00150EE7
+:10A290008F86001C8F8300EC241F0003147FFFD0E7
+:10A2A000260B00010E001325000000008F8500E83A
+:10A2B0000040302124020002240400100000382154
+:10A2C000AF8200EC0E001306000000000A00150E1D
+:10A2D0008F86001C8F8F00EC2406000211E6000B15
+:10A2E000000000002404001000002821000030219C
+:10A2F0000A00152B24070001000028210E00130678
+:10A30000000030210A00150E8F86001C0E00143448
+:10A3100000000000144000128F99001C8F86001C62
+:10A32000240200030A00150EAF8200EC0E0014C0D8
+:10A33000000000000A00150E8F86001C0E00131589
+:10A340000000000024020002240400140000282160
+:10A3500000003021000038210A001548AF8200ECCF
+:10A360000040382124040010973800020000282102
+:10A370000E0013063306FFFF0A00150E8F86001C21
+:10A380008F8400C83C077FFF34E6FFFF8C85007494
+:10A390002402000100A61824AC83007403E0000826
+:10A3A000A082000510A000362CA20080274A0400DD
+:10A3B0003C0B0005240900801040000724080080A1
+:10A3C00030A6000F00C540212D030081146000025B
+:10A3D00000A0482124080080AF4B0030000000009E
+:10A3E00000000000000000001100000900003821FA
+:10A3F000014030218C8D000024E7000400E8602B30
+:10A40000ACCD0000248400041580FFFA24C60004AB
+:10A410000000000000000000000000003C0E0006EC
+:10A42000010E3825AF47003000000000000000009A
+:10A43000000000008F4F000031E800101100FFFD08
+:10A44000000000008F42003C8F43003C0049C821BF
+:10A450000323C02B13000004000000008F4C0038C1
+:10A4600025860001AF4600388F47003C00A928230D
+:10A4700000E96821AF4D003C14A0FFCE2CA2008063
+:10A4800003E000080000000027BDFFD03C020002EE
+:10A49000AFB100143C11000CAF450038AFB3001C45
+:10A4A000AF46003C00809821AF4200302405008870
+:10A4B000AF44002803512021AFBF0028AFB50024CE
+:10A4C000AFB40020AFB200180E001580AFB000107E
+:10A4D0003C1F08008FFF004C3C1808008F180064D8
+:10A4E0002410FF8003F3A82132B9007F02B0782442
+:10A4F0000018A0C0033A70210018914001D120211A
+:10A50000AF4F00280E001580025428213C0D080092
+:10A510008DAD00502405012001B35821316C007F1E
+:10A5200001705024019A4821013120210E0015802C
+:10A53000AF4A00283C0808008D0800543C0508007C
+:10A540008CA500640113382130E6007F00F0182448
+:10A5500000DA202100912021AF4300280E00158051
+:10A56000000529403C0208008C4200583C100800BD
+:10A570008E1000601200001C005388212415FF80FB
+:10A580000A0016033C14000C3226007F0235182402
+:10A5900000DA202102402821AF4300280094202126
+:10A5A0000E0015802610FFC01200000F0232882115
+:10A5B0002E05004110A0FFF4241210003226007F67
+:10A5C000001091800235182400DA20210240282151
+:10A5D000AF430028009420210E0015800000802148
+:10A5E0001600FFF3023288213C0B08008D6B005CE3
+:10A5F000240AFF802405000201734021010A482437
+:10A60000AF4900283C040800948400623110007FA8
+:10A61000021A88213C07000C0E000CCD022798215D
+:10A6200000402821026020218FBF00288FB5002420
+:10A630008FB400208FB3001C8FB200188FB10014AC
+:10A640008FB000100A00158027BD00308F83001CDA
+:10A650008C620004104000030000000003E00008CA
+:10A66000000000008C6400108C6500080A0015B919
+:04A670008C66000CE8
+:0CA67400000000000000001B0000000FB0
+:10A680000000000A000000080000000600000005AD
+:10A6900000000005000000040000000400000003AA
+:10A6A000000000030000000300000003000000039E
+:10A6B0000000000200000002000000020000000292
+:10A6C0000000000200000002000000020000000282
+:10A6D0000000000200000002000000020000000272
+:10A6E0000000000200000002000000020000000163
+:08A6F000000000010000000160
+:08A6F80008000F5808000DB026
+:10A7000008000FEC0800109408000F8008000FC02C
+:10A71000080011CC08000DCC080011F008000E1C38
+:10A7200008001630080015D808000DCC08000DCC24
+:10A7300008000DCC0800127C0800127C08000DCC2B
+:10A7400008000DCC0800157C08000DCC08000DCCCD
+:10A7500008000DCC08000DCC080013EC08000DCC4F
+:10A7600008000DCC08000DCC08000DCC08000DCC65
+:10A7700008000DCC08000DCC08000DCC08000DCC55
+:10A7800008000DCC08000DCC08000DCC08000DCC45
+:10A7900008000DCC08000FE008000DCC08000DCC1F
+:10A7A0000800152C08000DCC08000DCC08000DCCBD
+:10A7B00008000DCC08000DCC08000DCC08000DCC15
+:10A7C00008000DCC08000DCC08000DCC08000DCC05
+:10A7D00008000DCC08000DCC08000DCC08000DCCF5
+:10A7E00008000DCC08000DCC0800145808000DCC52
+:10A7F00008000DCC08001370080012E008002EA01D
+:10A8000008002EA808002E7008002E7C08002E8854
+:10A8100008002E94080046C008003F0C080046407F
+:10A82000080046C0080046C0080044C0080046C0F2
+:10A830000800470808005530080054F0080054BCD0
+:0CA84000080054900800546C08005428D4
+:04A84C000A000C767C
+:10A8500000000000000000000000000D727870355C
+:10A860002E302E306A330000050000030000000087
+:10A8700000000001000000000000000000000000D7
+:10A8800000000000000000000000000000000000C8
+:10A8900000000000000000000000000000000000B8
+:10A8A00000000000000000000000000000000000A8
+:10A8B0000000000000000000000000000000000098
+:10A8C0000000000000000000000000000000000088
+:10A8D0000000000000000000000000000000000078
+:10A8E0000000000000000000000000000000000068
+:10A8F0000000000000000000000000000000000058
+:10A900000000000000000000000000000000000047
+:10A910000000000000000000000000000000000037
+:10A920000000000000000000000000000000000027
+:10A930000000000000000000000000000000000017
+:10A940000000000000000000000000000000000007
+:10A9500000000000000000000000000000000000F7
+:10A9600000000000000000000000000000000000E7
+:10A9700000000000000000000000000000000000D7
+:10A9800000000000000000000000000000000000C7
+:10A9900000000000000000000000000000000000B7
+:10A9A00000000000000000000000000000000000A7
+:10A9B0000000000000000000000000000000000097
+:10A9C0000000000000000000000000000000000087
+:10A9D0000000000000000000000000000000000077
+:10A9E0000000000000000000000000000000000067
+:10A9F0000000000000000000000000000000000057
+:10AA00000000000000000000000000000000000046
+:10AA10000000000000000000000000000000000036
+:10AA20000000000000000000000000000000000026
+:10AA30000000000000000000000000000000000016
+:10AA40000000000000000000000000000000000006
+:10AA500000000000000000000000000000000000F6
+:10AA600000000000000000000000000000000000E6
+:10AA700000000000000000000000000000000000D6
+:10AA800000000000000000000000000000000000C6
+:10AA900000000000000000000000000000000000B6
+:10AAA00000000000000000000000000000000000A6
+:10AAB0000000000000000000000000000000000096
+:10AAC0000000000000000000000000000000000086
+:10AAD0000000000000000000000000000000000076
+:10AAE0000000000000000000000000000000000066
+:10AAF0000000000000000000000000000000000056
+:10AB00000000000000000000000000000000000045
+:10AB10000000000000000000000000000000000035
+:10AB20000000000000000000000000000000000025
+:10AB30000000000000000000000000000000000015
+:10AB40000000000000000000000000000000000005
+:10AB500000000000000000000000000000000000F5
+:10AB600000000000000000000000000000000000E5
+:10AB700000000000000000000000000000000000D5
+:10AB800000000000000000000000000000000000C5
+:10AB900000000000000000000000000000000000B5
+:10ABA00000000000000000000000000000000000A5
+:10ABB0000000000000000000000000000000000095
+:10ABC0000000000000000000000000000000000085
+:10ABD0000000000000000000000000000000000075
+:10ABE0000000000000000000000000000000000065
+:10ABF0000000000000000000000000000000000055
+:10AC00000000000000000000000000000000000044
+:10AC10000000000000000000000000000000000034
+:10AC20000000000000000000000000000000000024
+:10AC30000000000000000000000000000000000014
+:10AC40000000000000000000000000000000000004
+:10AC500000000000000000000000000000000000F4
+:10AC600000000000000000000000000000000000E4
+:10AC700000000000000000000000000000000000D4
+:10AC800000000000000000000000000000000000C4
+:10AC900000000000000000000000000000000000B4
+:10ACA00000000000000000000000000000000000A4
+:10ACB0000000000000000000000000000000000094
+:10ACC0000000000000000000000000000000000084
+:10ACD0000000000000000000000000000000000074
+:10ACE0000000000000000000000000000000000064
+:10ACF0000000000000000000000000000000000054
+:10AD00000000000000000000000000000000000043
+:10AD10000000000000000000000000000000000033
+:10AD20000000000000000000000000000000000023
+:10AD30000000000000000000000000000000000013
+:10AD40000000000000000000000000000000000003
+:10AD500000000000000000000000000000000000F3
+:10AD600000000000000000000000000000000000E3
+:10AD700000000000000000000000000000000000D3
+:10AD800000000000000000000000000000000000C3
+:10AD900000000000000000000000000000000000B3
+:10ADA00000000000000000000000000000000000A3
+:10ADB0000000000000000000000000000000000093
+:10ADC0000000000000000000000000000000000083
+:10ADD0000000000000000000000000000000000073
+:10ADE0000000000000000000000000000000000063
+:10ADF0000000000000000000000000000000000053
+:10AE00000000000000000000000000000000000042
+:10AE10000000000000000000000000000000000032
+:10AE20000000000000000000000000000000000022
+:10AE30000000000000000000000000000000000012
+:10AE40000000000000000000000000000000000002
+:10AE500000000000000000000000000000000000F2
+:10AE600000000000000000000000000000000000E2
+:10AE700000000000000000000000000000000000D2
+:10AE800000000000000000000000000000000000C2
+:10AE900000000000000000000000000000000000B2
+:10AEA00000000000000000000000000000000000A2
+:10AEB0000000000000000000000000000000000092
+:10AEC0000000000000000000000000000000000082
+:10AED0000000000000000000000000000000000072
+:10AEE0000000000000000000000000000000000062
+:10AEF0000000000000000000000000000000000052
+:10AF00000000000000000000000000000000000041
+:10AF10000000000000000000000000000000000031
+:10AF20000000000000000000000000000000000021
+:10AF30000000000000000000000000000000000011
+:10AF40000000000000000000000000000000000001
+:10AF500000000000000000000000000000000000F1
+:10AF600000000000000000000000000000000000E1
+:10AF700000000000000000000000000000000000D1
+:10AF800000000000000000000000000000000000C1
+:10AF900000000000000000000000000000000000B1
+:10AFA00000000000000000000000000000000000A1
+:10AFB0000000000000000000000000000000000091
+:10AFC0000000000000000000000000000000000081
+:10AFD0000000000000000000000000000000000071
+:10AFE0000000000000000000000000000000000061
+:10AFF0000000000000000000000000000000000051
+:10B000000000000000000000000000000000000040
+:10B010000000000000000000000000000000000030
+:10B020000000000000000000000000000000000020
+:10B030000000000000000000000000000000000010
+:10B040000000000000000000000000000000000000
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D3300000000000000000000000000000000000ED
+:10D3400000000000000000000000000000000000DD
+:10D3500000000000000000000000000000000000CD
+:10D3600000000000000000000000000000000000BD
+:10D3700000000000000000000000000000000000AD
+:10D38000000000000000000000000000000000009D
+:10D39000000000000000000000000000000000008D
+:10D3A000000000000000000000000000000000007D
+:10D3B000000000000000000000000000000000006D
+:10D3C000000000000000000000000000000000005D
+:10D3D000000000000000000000000000000000004D
+:10D3E000000000000000000000000000000000003D
+:10D3F000000000000000000000000000000000002D
+:10D40000000000000000000000000000000000001C
+:10D41000000000000000000000000000000000000C
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D4400000000000000000000000000000000000DC
+:10D4500000000000000000000000000000000000CC
+:10D4600000000000000000000000000000000000BC
+:10D4700000000000000000000000000000000000AC
+:10D48000000000000000000000000000000000009C
+:10D49000000000000000000000000000000000008C
+:10D4A000000000000000000000000000000000007C
+:10D4B000000000000000000000000000000000006C
+:10D4C000000000000000000000000000000000005C
+:10D4D000000000000000000000000000000000004C
+:10D4E000000000000000000000000000000000003C
+:10D4F000000000000000000000000000000000002C
+:10D50000000000000000000000000000000000001B
+:10D51000000000000000000000000000000000000B
+:10D5200000000000000000000000000000000000FB
+:10D5300000000000000000000000000000000000EB
+:10D5400000000000000000000000000000000000DB
+:10D5500000000000000000000000000000000000CB
+:10D5600000000000000000000000000000000000BB
+:10D5700000000000000000000000000000000000AB
+:10D58000000000000000000000000000000000009B
+:10D59000000000000000000000000000000000008B
+:10D5A000000000000000000000000000000000007B
+:10D5B000000000000000000000000000000000006B
+:10D5C000000000000000000000000000000000005B
+:10D5D000000000000000000000000000000000004B
+:10D5E000000000000000000000000000000000003B
+:10D5F000000000000000000000000000000000002B
+:10D60000000000000000000000000000000000001A
+:10D61000000000000000000000000000000000000A
+:10D6200000000000000000000000000000000000FA
+:10D6300000000000000000000000000000000000EA
+:10D6400000000000000000000000000000000000DA
+:10D6500000000000000000000000000000000000CA
+:10D6600000000000000000000000000000000000BA
+:10D6700000000000000000000000000000000000AA
+:10D68000000000000000000000000000000000009A
+:10D69000000000000000000000000000000000008A
+:10D6A000000000000000000000000000000000007A
+:10D6B000000000000000000000000000000000006A
+:10D6C000000000000000000000000000000000005A
+:10D6D000000000000000000000000000000000004A
+:10D6E000000000000000000000000000000000003A
+:10D6F000000000000000000000000000000000002A
+:10D700000000000000000000000000000000000019
+:10D710000000000000000000000000000000000009
+:10D7200000000000000000000000000000000000F9
+:10D7300000000000000000000000000000000000E9
+:10D7400000000000000000000000000000000000D9
+:10D7500000000000000000000000000000000000C9
+:10D7600000000000000000000000000000000000B9
+:10D7700000000000000000000000000000000000A9
+:10D780000000000000000000000000000000000099
+:10D790000000000000000000000000000000000089
+:10D7A0000000000000000000000000000000000079
+:10D7B0000000000000000000000000000000000069
+:10D7C0000000000000000000000000000000000059
+:10D7D0000000000000000000000000000000000049
+:10D7E0000000000000000000000000000000000039
+:10D7F0000000000000000000000000000000000029
+:10D800000000000000000000000000000000000018
+:10D810000000000000000000000000000000000008
+:10D8200000000000000000000000000000000000F8
+:10D8300000000000000000000000000000000000E8
+:10D8400000000000000000000000000000000000D8
+:10D8500000000000000000000000000000000000C8
+:10D8600000000000000000000000000000000000B8
+:10D8700000000000000000000000000000000000A8
+:10D880000000000000000000000000000000000098
+:10D890000000000000000000000000000000000088
+:10D8A0000000000000000000000000000000000078
+:10D8B0000000000000000000000000000000000068
+:10D8C0000000000000000000000000000000000058
+:10D8D0000000000000000000000000000000000048
+:10D8E0000000000000000000000000000000000038
+:10D8F0000000000000000000000000000000000028
+:10D900000000000000000000000000000000000017
+:10D910000000000000000000000000000000000007
+:10D9200000000000000000000000000000000000F7
+:10D9300000000000000000000000000000000000E7
+:10D9400000000000000000000000000000000000D7
+:10D9500000000000000000000000000000000000C7
+:10D9600000000000000000000000000000000000B7
+:10D9700000000000000000000000000000000000A7
+:10D980000000000000000000000000000000000097
+:10D990000000000000000000000000000000000087
+:10D9A0000000000000000000000000000000000077
+:10D9B0000000000000000000000000000000000067
+:10D9C0000000000000000000000000000000000057
+:10D9D0000000000000000000000000000000000047
+:10D9E0000000000000000000000000000000000037
+:10D9F0000000000000000000000000000000000027
+:10DA00000000000000000000000000000000000016
+:10DA10000000000000000000000000000000000006
+:10DA200000000000000000001000000300000000E3
+:10DA30000000000D0000000D3C020800244271406F
+:10DA40003C030800246375E0AC4000000043202B39
+:10DA50001480FFFD244200043C1D080037BD7FFCFC
+:10DA600003A0F0213C100800261031D83C1C08000F
+:10DA7000279C71400E0010ED000000000000000D1A
+:10DA800030A5FFFF30C600FF274301808F4201B859
+:10DA90000440FFFE24020002AC640000A4650008FC
+:10DAA000A066000AA062000B3C021000AC670018E0
+:10DAB00003E00008AF4201B83C0360008C624FF8FD
+:10DAC0000440FFFE3C020200AC644FC0AC624FC495
+:10DAD0003C02100003E00008AC624FF89482000C96
+:10DAE0002486001400A038210002130200021080D6
+:10DAF0000082402100C8102B104000570000000099
+:10DB000090C300002C6200095040005190C20001F7
+:10DB1000000310803C030800246370F000431021D0
+:10DB20008C420000004000080000000090C300018B
+:10DB30002402000A1462003A0000000001061023CB
+:10DB40002C42000A1440003624C600028CE2000079
+:10DB500034420100ACE2000090C2000090C300011A
+:10DB600090C4000290C5000300031C0000021600D0
+:10DB70000043102500042200004410250045102514
+:10DB800024C60004ACE2000490C2000090C300016F
+:10DB900090C4000290C500030002160000031C00A0
+:10DBA00000431025000422000044102500451025E4
+:10DBB00024C600040A000CAAACE2000890C30001CD
+:10DBC000240200041462001624C6000290C2000061
+:10DBD00090C400018CE300000002120000441025F4
+:10DBE0003463000424C60002ACE2000C0A000CAA54
+:10DBF000ACE3000090C3000124020003146200089B
+:10DC000024C600028CE2000090C3000024C600017C
+:10DC100034420008A0E300100A000CAAACE20000A5
+:10DC200003E000082402000190C300012402000266
+:10DC30001062000224C40002010020210A000CAA84
+:10DC4000008030210A000CAA24C6000190C2000105
+:10DC50000A000CAA00C2302103E0000800001021D5
+:10DC600027BDFFE8AFBF0014AFB000100E0011FEDB
+:10DC700000808021936200052403FFFE0200202122
+:10DC8000004310248FBF00148FB00010A362000562
+:10DC90000A00120727BD001827BDFFE8AFB000102B
+:10DCA000AFBF00140E000F180080802193620000A7
+:10DCB00024030050304200FF1443000424020100FA
+:10DCC000AF4201800A000D2202002021AF400180F6
+:10DCD000020020218FBF00148FB000100A000F79BE
+:10DCE00027BD001827BDFF80AFBE0078AFB7007416
+:10DCF000AFB30064AFBF007CAFB60070AFB5006CCF
+:10DD0000AFB40068AFB20060AFB1005CAFB0005814
+:10DD10008F5001289363003F936200050000F021BB
+:10DD2000307300FF00021027304200010000B821CC
+:10DD300014400066AFA000509342011693430112B5
+:10DD4000304200FF306300FF0342202103431021D3
+:10DD5000244540008F820018104000182491400094
+:10DD60008F4201043C0300010043102410400013C3
+:10DD7000000000008CA3000C8F620030146201B51B
+:10DD8000240200018CA300108F62002C146201B1E8
+:10DD9000240200019762003A948340003042FFFF62
+:10DDA000146201AC2402000197620038962300023D
+:10DDB0003042FFFF146201A72402000193620000B9
+:10DDC000304300FF240200201062000524020050AE
+:10DDD00010620006000000000A000D6C0000000048
+:10DDE0000000000D0A000D75AFA000303C1E0800B9
+:10DDF00027DE71A00A000D75AFA000303C020800BC
+:10DE00008C4200DC244200013C010800AC2200DC12
+:10DE10000E0012C8000000000A000F038FBF007C34
+:10DE20008F4201043C0300209234000D0043102473
+:10DE30000002202B00042140AFA400308F430104D6
+:10DE40003C02004000621824146000023487004045
+:10DE50000080382132820020AFA700301440000239
+:10DE600034E6008000E0302110C0000BAFA6003087
+:10DE700093C500088F67004C0200202100052B008D
+:10DE800034A5008130A5F0810E000C8D30C600FF56
+:10DE90000A000F00000000009362003E3042004084
+:10DEA0001040000E240200045662000624020012F4
+:10DEB000020020210E0013D6022030210A000F0399
+:10DEC0008FBF007C16620005000000000E000D13DD
+:10DED000000020210A000F038FBF007C9743011A26
+:10DEE0009624000E93620035328500043076FFFFE1
+:10DEF00000442004AFA400548E32000410A000158A
+:10DF00008E3500089362003E30420040104000070A
+:10DF1000000000000E001318024020211040000DE8
+:10DF2000000000000A000F00000000008F620044A3
+:10DF30000242102304400145000000008F620048A7
+:10DF40000242102304410141240400160A000E037A
+:10DF50008FC200048F620048024210230440000870
+:10DF6000000000003C0208008C4231002442000105
+:10DF70003C010800AC2231000A000EF50000000050
+:10DF80008F62004002421023184000092402000C56
+:10DF90003C0208008C423100329400FC0000B021A9
+:10DFA000244200013C010800AC2231002402000C94
+:10DFB000AFA200308F620040005220231880000D75
+:10DFC00002C4102A14400116000000001496000636
+:10DFD00002C410233A8200013042000114400110B3
+:10DFE0000000000002C41023024490210A000DEB3F
+:10DFF0003056FFFF00002021328200021040001A3C
+:10E00000328200109362003E3042004050400011C6
+:10E010008FC200040E0011FE02002021240200180D
+:10E02000A362003F936200052403FFFE020020214B
+:10E03000004310240E001207A362000524040039D7
+:10E04000000028210E001301240600180A000F0208
+:10E0500024020001240400170040F8090000000019
+:10E060000A000F0224020001104000F80000000026
+:10E070008F63004C8F62005402A210231C4000F3F7
+:10E0800002A31023044200010060A821AFA40018DD
+:10E09000AFB20010AFB60014934201208F6500406C
+:10E0A0009763003C304200FF0342102100441021DE
+:10E0B0008FA400543063FFFF244240000083182BDC
+:10E0C0008FA40030AFA20020AFA500280083202538
+:10E0D000AFA40030AFA50024AFA0002CAFB5003432
+:10E0E0009362003E30420008504000118FC2000091
+:10E0F0000220202127A500380E000CA4AFA0003874
+:10E100005440000B8FC200008FA200383042010043
+:10E11000504000078FC200008FA3003C8F62006058
+:10E120000062102304430001AF6300608FC200004F
+:10E130000040F80927A400108FA2003030420002EE
+:10E1400054400001329400FE9362003E3042004091
+:10E15000104000378FA300148F62005416A2001ADB
+:10E160003282000124020014126200102A6200159B
+:10E1700010400006240200162402000C1262000760
+:10E18000328200010A000E5F0000000012620005EA
+:10E19000328200010A000E5F000000000A000E5AE1
+:10E1A0002417000E0A000E5A241700100A000E5EF3
+:10E1B00024170012936200232403FFBD00431024A0
+:10E1C000A362002332820001104000198FA30014C3
+:10E1D0002402000C1262000E2A62000D104000069C
+:10E1E0002402000E2402000A126200078FA20024FB
+:10E1F0000A000E7724420001126200088FA2002458
+:10E200000A000E77244200010A000E752417000848
+:10E210002402000E16E20002241700162417001034
+:10E220008FA2002424420001AFA200248FA3001477
+:10E230008FA200248F73004000431021AF62004082
+:10E240008FA20054936400368F63004002A288219D
+:10E250003402FFFF0082100400621821AF630048FF
+:10E260008FA6003030C200081040000E00000000F1
+:10E270008F6200581622000430C600FF9742011A30
+:10E280005040000134C6001093C500088FA7003429
+:10E290000200202100052B0034A500800E000C8D0B
+:10E2A00030A5F0808F620040005310231840001703
+:10E2B0008FA200183C0208008C42319830420010B6
+:10E2C0001040000924020001976200681440000613
+:10E2D00024020001A76200689742007A2442000AE3
+:10E2E0000A000EBBA7620012A76200120E0011FE08
+:10E2F000020020219362007D2403000102002021FE
+:10E30000344200010A000EB9AFA300501840000AC1
+:10E31000000000000E0011FE020020219362007D2B
+:10E320002403000102002021AFA300503442000466
+:10E330000E001207A362007D9362003E304200404F
+:10E340001440000C328200011040000A000000005E
+:10E350008F6300408FC2000424040018246300016E
+:10E360000040F809AF6300408FA200300A000F029E
+:10E37000304200048F62005810510010000000006D
+:10E380008F620018024210231C4000082404000180
+:10E390008F62001816420009000000008F62001C06
+:10E3A00002A210230440000500000000AF710058D5
+:10E3B000AFA40050AF720018AF75001C12E0000B44
+:10E3C0008FA200500E0011FE02002021A377003F13
+:10E3D0000E0012070200202102E030212404003741
+:10E3E0000E001301000028218FA2005010400003EE
+:10E3F000000000000E000C9B0200202112C000054E
+:10E40000000018218FA2003030420004504000115B
+:10E4100000601021240300010A000F020060102197
+:10E420000E0011FE020020219362007D02002021D7
+:10E43000344200040E001207A362007D0E000C9B04
+:10E44000020020210A000F0224020001AF40004414
+:10E45000240200018FBF007C8FBE00788FB700744C
+:10E460008FB600708FB5006C8FB400688FB30064F6
+:10E470008FB200608FB1005C8FB0005803E00008DD
+:10E4800027BD00808C8700048C86000000001021CE
+:10E4900000E5382100E5282B00C2302100C53021DD
+:10E4A000AC87000403E00008AC8600008F4201B88E
+:10E4B0000440FFFE24020800AF4201B803E0000858
+:10E4C000000000003C0200080342282194A20048FA
+:10E4D0003084FFFF1040001B2484001294A20048E7
+:10E4E0003042FFFF0044102A1040001724020003AE
+:10E4F0002402001A93430120A342018B8F82000063
+:10E50000306300FF30424000104000092463FFFEEA
+:10E5100094A200483042FFFF0043102B1440000536
+:10E520008F820004A74301940A000F3C344200018B
+:10E530008F8200042403FFFE0043102403E0000840
+:10E54000AF8200042402000303E00008A342018B11
+:10E5500027BDFFE0AFB20018AFB10014AFB000109C
+:10E56000AFBF001C30B1FFFF30D0FFFF30F2FFFF24
+:10E570008F4201B80440FFFE00000000AF4401805C
+:10E58000AF4400200E000F1E020020218F830000E8
+:10E590008F840004A751018CA750018EA7430190DE
+:10E5A0008F83000830828000AF4301A8A752018802
+:10E5B0001040000E8F82000493420116304200FC8E
+:10E5C00024420004005A10218C4240003042FFFFD8
+:10E5D000144000068F8200043C02FFFF34427FFF9C
+:10E5E00000821024AF8200048F8200042403BFFF46
+:10E5F00000431024A74201A69743010C8F42010457
+:10E6000000031C003042FFFF00621825AF4301AC3D
+:10E610003C021000AF4201B88FBF001C8FB200183F
+:10E620008FB100148FB0001003E0000827BD002058
+:10E630003C0208008C42003827BDFFC8AFB200285A
+:10E64000AFBF0030AFB3002CAFB10024AFB000209B
+:10E65000000090213C0E080025CE00381440000236
+:10E66000244DFFFF000068218F84000030824000AD
+:10E670001040000A308280003C02002000821024FA
+:10E6800050400006308280008F8200042403BFFFC8
+:10E69000008318240A000F9D344210001040000A25
+:10E6A0003C02002000821024104000078F820004EA
+:10E6B0003C03FFFF34637FFF008318243442800053
+:10E6C000AF820004AF8300008F48007093420112B4
+:10E6D0008F860000304200FF0002288230C2010015
+:10E6E0001040004324A4000330C24000104000103A
+:10E6F00030C2200000041080005A10218C434000DA
+:10E7000024A4000400041080AFA30010005A1021BC
+:10E710008C424000AFA2001493420116304200FC2C
+:10E72000005A10218C4240000A000FC4AFA200180A
+:10E730001040002F00041080005A10218C4340002C
+:10E7400024A4000400041080AFA30010005A10217C
+:10E750008C424000AFA00018AFA200148FA900188F
+:10E760000000382100002021240C000827AB0010F5
+:10E770003C0A0800254A010001641021148C0003A2
+:10E7800000042A001120000A00000000904200004E
+:10E79000248400012C83000C00A2102100021080B0
+:10E7A000004A10218C4200001460FFF300E238267A
+:10E7B0003C0408008C8431048F4200702C830020BC
+:10E7C00010600009004840233C030800246331081E
+:10E7D000000410800043102124830001AC48000095
+:10E7E0003C010800AC2331040A000FEFAF8700089A
+:10E7F0009743011E9742011C3063FFFF0002140083
+:10E8000000621825AF8300089742010C8F43400037
+:10E810003044FFFF3402FFFF1462000300000000D9
+:10E820000A000FFB241200208F42400030420100FA
+:10E83000544000012412001030C210005040001457
+:10E840003652000130C200201440000B3C02100080
+:10E8500000C210245040000E365200013C030E004E
+:10E860003C020DFF00C318243442FFFF0043102B6D
+:10E8700050400007365200013C0208008C42002C38
+:10E88000244200013C010800AC22002C3652000555
+:10E890003C0508008CA5003454A000248F8400009F
+:10E8A0008F82000C544000218F8400008F8200046E
+:10E8B000304240005440001D8F8400003C021F0184
+:10E8C00000C288243C021000562200188F840000E9
+:10E8D00030820200144000158F8400009750010E12
+:10E8E000AF400180AF400020261000043210FFFF2F
+:10E8F0000E000F1E020020218F8300042402BFFFA0
+:10E90000364400020062182424020002A742018C4F
+:10E910008F820000A750018EA7440188A74301A65B
+:10E92000A7420190AF5101B80A0010D93C02000182
+:10E93000008210241040000C3C0210003C02080031
+:10E940008C4200D89746010E240400802442000126
+:10E9500030C6FFFF240500023C010800AC2200D8AD
+:10E960000A0010E324070003008210241040004531
+:10E97000000000003C0208008C4200301040000DF6
+:10E980008F820004304240001040000A3C030F0018
+:10E99000008318243C0201000043102B14400005A2
+:10E9A000000000009746010E364700020A0010E002
+:10E9B0002404008010A0000D308201001040000BE4
+:10E9C0003C020F00008210243C03020010430007A9
+:10E9D0008F820008004D1024004E10219042000448
+:10E9E000244200040A00108B000221C00000000035
+:10E9F0008F8600003C0508008CA500D0000616029A
+:10EA00003050000F38A200012C4200012E03000CF0
+:10EA10000043102414400018001021C02602FFFCFF
+:10EA20002C420004544000140000202138A20002AF
+:10EA30002C42000100431024104000030006124243
+:10EA40000A00108B000020210010182B0043102416
+:10EA500050400009001021C09746010E00002021FF
+:10EA60002405000224C6000430C6FFFF0E000F413B
+:10EA70003247FFFB001021C09746010E0A0010E04C
+:10EA8000364700028F4240003C1108008E310024BE
+:10EA90003042010010400048322200010220802153
+:10EAA00010A00017325300043082010010400015FE
+:10EAB000240200013C020F00008210243C030200EB
+:10EAC0001043000F8F8200089746010E0240382144
+:10EAD000004D1024004E10219044000424C6000470
+:10EAE00030C6FFFF24840004000421C00E000F4143
+:10EAF000240500022402FFFE022280243252FFFB82
+:10EB00002402000116020007320200013242000412
+:10EB100050400001365200029746010E0A0010DFF5
+:10EB2000024038211040000A320200049746010ECC
+:10EB3000024038210000202124C6000430C6FFFF17
+:10EB40000E000F41240500023252FFFB3202000486
+:10EB50001040000B8F820000304208001040000877
+:10EB6000000000009746010E0240382124040100F5
+:10EB700024C6000430C6FFFF0E000F41240500022A
+:10EB8000166000188FBF0030274301808F4201B804
+:10EB90000440FFFE24022000A462000824020002B8
+:10EBA000A062000BA46000103C021000AF4201B84C
+:10EBB0000A0010E68FBF00301040000A8FBF0030FF
+:10EBC0009746010E364700020000202124C60004AB
+:10EBD00030C6FFFF240500020E000F4100000000B8
+:10EBE0008FBF00308FB3002C8FB200288FB100246C
+:10EBF0008FB000200000102103E0000827BD00387E
+:10EC000027BDFFE8AFB000103C04600CAFBF00149C
+:10EC10008C8250002403FF7F3C1A800000431024A4
+:10EC20003442380CAC825000240200033C106000D7
+:10EC3000AF4200088E0208083C1B80083C01080017
+:10EC4000AC2000203042FFF0384200102C4200017E
+:10EC50000E001B35AF8200183C04FFFF3C0204008D
+:10EC6000348308063442000CAE021948AE03194C36
+:10EC70003C0560168E0219808CA30000344202000D
+:10EC800000641824AE0219803C025353146200033E
+:10EC900034A47C008CA20004005020218C82007CD3
+:10ECA0008C830078AF820014AF8300103C02800098
+:10ECB000344200708C43000000403821AF83001CB8
+:10ECC000006030218CE800003C0508008CA500FCA9
+:10ECD0003C0408008C8400F8010630230000102159
+:10ECE00000A6282100A6302B0082202100862021AA
+:10ECF0003C010800AC2500FC3C010800AC2400F8F5
+:10ED00008F500000320200031040FFEE010030215E
+:10ED10008CE600003C0508008CA500FC3C040800C3
+:10ED20008C8400F800C8302300A6282100001021A0
+:10ED300000A6302B0082202100862021320700010E
+:10ED40003C010800AC2500FCAF88001C3C01080019
+:10ED5000AC2400F810E00064320200028F42012867
+:10ED6000AF4200208F4201048F430100AF820000B8
+:10ED70000E000F18AF8300048F4340003402FFFFE2
+:10ED800014620006000000009745010E3C040800D4
+:10ED9000248400F00A00115B000000008F42400054
+:10EDA000304201001040000B000000009745010EAA
+:10EDB0003C040800248400E80E000F0E30A5FFFF7D
+:10EDC0009745010E3C040800248431C80A001172E2
+:10EDD000000000008F4340008F8200101462000A80
+:10EDE000000000008F4340048F820014146200066C
+:10EDF000000000009745010E3C040800248431B84F
+:10EE00000A001172000000009745010E3C04080042
+:10EE1000248400E00E000F0E30A5FFFF3C02080026
+:10EE20008C4200C0104000088F8400003C020800A3
+:10EE30008C4200C4244200013C010800AC2200C402
+:10EE40000A00119F000000003C0200100082102404
+:10EE50001440000A8F8300043C0208008C4200200A
+:10EE6000244200013C010800AC2200200E000F7972
+:10EE7000000020210A00119D000000002402BFFFB5
+:10EE8000006210241040000800000000240287FFE8
+:10EE900000621024144000083C020060008210242C
+:10EEA00010400005000000000E000D2600000000CC
+:10EEB0000A00119D000000000E0011E80000000093
+:10EEC000104000063C0240008F4301243C026020B9
+:10EED000AC430014000000003C024000AF42013887
+:10EEE00000000000320200021040FF713C0280006E
+:10EEF0008F4201403C044000AF4200208F43014854
+:10EF00003C027000006218241064002D0000000014
+:10EF10000083102B144000063C0260003C022000DD
+:10EF2000106200073C0240000A0011E400000000EB
+:10EF300010620027000000000A0011E43C024000BB
+:10EF40008F4201482403000400021402304200FFF3
+:10EF50001443000B274401808F4301408F4201B8C6
+:10EF60000440FFFE2402001CAC830000A082000BC2
+:10EF70003C021000AF4201B80A0011E43C0240001C
+:10EF80008F4201B80440FFFE000000008F4201489C
+:10EF900000021402A482000824020002A082000BD6
+:10EFA0008F420148A48200108F420144AC820024A9
+:10EFB0003C021000AF4201B80A0011E43C024000DC
+:10EFC0000E00120C000000000A0011E43C02400098
+:10EFD0000E001B42000000003C024000AF420178DE
+:10EFE000000000000A0011193C0280008F4201005D
+:10EFF0003042003E1440001124020001AF4000489E
+:10F000008F420100304207C01040000500000000A0
+:10F01000AF40004CAF40005003E000082402000164
+:10F02000AF400054AF4000408F42010030423800F2
+:10F0300054400001AF4000442402000103E00008F6
+:10F04000000000003C0290003442000100822025B4
+:10F05000AF4400208F4200200440FFFE000000006B
+:10F0600003E00008000000003C0280003442000180
+:10F070000082202503E00008AF44002027BDFFE008
+:10F08000AFB20018AFBF001CAFB10014AFB000109A
+:10F090008F5001408F5101483C02800000119402C2
+:10F0A00002222024324300FF2402000E1062008A54
+:10F0B0002862000F10400012286200372402000668
+:10F0C0001062003B2862000710400007240200097C
+:10F0D0001060001A240200011062002500000000E8
+:10F0E0000A0012C1000000001062007B2402000B25
+:10F0F0001062005B3222FFFF0A0012C10000000014
+:10F1000010400008240200382862003510400080BA
+:10F110002402001F1062007E000000000A0012C1DD
+:10F12000000000001062007A240200801062004299
+:10F13000000000000A0012C1000000008F4201B868
+:10F140000440FFFE24020001AF500180AF40018463
+:10F15000A7520188A342018A24020002A342018B24
+:10F16000A75101908F4201440A0012BCAF4201A492
+:10F170001080000A240200023C010800A0227190C5
+:10F180003C010800AC3071988F4201443C010800FA
+:10F19000AC2271940A0012C38FBF001C8F4201B8C9
+:10F1A0000440FFFE240200020A0012A60000000034
+:10F1B0008F4201B80440FFFE00000000AF50018004
+:10F1C0003C0208009042719010400003000018219A
+:10F1D0003C0308008C637198AF430184A7520188F7
+:10F1E0003C02080090427190000018213442000156
+:10F1F000A342018A24020002A342018BA75101907D
+:10F200008F420144AF4201A43C0208009042719039
+:10F21000104000033C0210003C0308008C63719412
+:10F22000AF4301A8AF4201B83C010800A020719093
+:10F230000A0012C38FBF001C8F4201B80440FFFEBA
+:10F2400024020002A342018BA7520188A75101901A
+:10F250008F420144A74201920A0012BE3C021000F4
+:10F260001440001D000000009362000530420004BD
+:10F2700014400037000000000E0011FE02002021A3
+:10F280009362000502002021344200040E001207A0
+:10F29000A36200059362000530420004144000029E
+:10F2A000000000000000000D936200002403002015
+:10F2B000304200FF14430008000000008F4201B8F4
+:10F2C0000440FFFE24020005AF500180A342018BE1
+:10F2D0003C021000AF4201B88F4201B80440FFFE6B
+:10F2E00024020002AF400180AF500184A752018880
+:10F2F000A342018AA342018BA7510190AF4001A410
+:10F300008F420144AF4201A80A0012BE3C02100025
+:10F310008F4201B80440FFFE24020001AF5001807B
+:10F32000AF400184A7520188A342018A240200024F
+:10F33000A342018BA7510190AF4001A4AF4001A8A7
+:10F340003C021000AF4201B80A0012C38FBF001C7C
+:10F350000000000D8FBF001C8FB200188FB1001489
+:10F360008FB0001003E0000827BD002027BDFFE894
+:10F37000AFBF00100E000F1800000000AF4001806A
+:10F380008FBF0010000020210A000F7927BD001850
+:10F390003084FFFF30A5FFFF000018211080000718
+:10F3A00000000000308200011040000200042042F2
+:10F3B000006518210A0012D40005284003E0000867
+:10F3C0000060102110C0000624C6FFFF8CA20000C0
+:10F3D00024A50004AC8200000A0012DE248400048C
+:10F3E00003E000080000000010A0000824A3FFFFB5
+:10F3F000AC86000000000000000000002402FFFFB7
+:10F400002463FFFF1462FFFA2484000403E0000871
+:10F410000000000027BDFFE8AFBF0014AFB0001030
+:10F420000E0011FE008080219362007D02002021E9
+:10F43000344200200E001207A362007D020020214A
+:10F440008FBF00148FB000100A000C9B27BD00185E
+:10F45000308300FF30A500FF30C600FF2747018042
+:10F460008F4201B80440FFFE000000008F420128D7
+:10F4700034634000ACE2000024020001ACE0000470
+:10F48000A4E30008A0E2000A24020002A0E2000BAC
+:10F490003C021000A4E50010ACE00024ACE0002821
+:10F4A000A4E6001203E00008AF4201B827BDFFE860
+:10F4B000AFBF00109362003F24030012304200FFF0
+:10F4C0001043000D008030218F6200440082102321
+:10F4D0000440000A8FBF00108F62004824040039E6
+:10F4E0000000282100C21023044100042406001259
+:10F4F0000E001301000000008FBF00102402000165
+:10F5000003E0000827BD001827BDFFC8AFB1002CDD
+:10F5100000A08821AFB2003027A500100080902104
+:10F5200002202021AFBF0034AFB000280E000CA491
+:10F53000AFA0001010400009024020218E220008D8
+:10F54000AF6200840E0012F2AF6000402404003865
+:10F550002405008D0A0013CD240600129362003E9C
+:10F56000304200081040000F8FA20010304201000E
+:10F57000104000078FA300148F6200600062102308
+:10F5800004430008AF6300600A0013560000000047
+:10F59000AF6000609362003E2403FFF70043102435
+:10F5A000A362003E9362003E304200081440000215
+:10F5B0002406000300003021936200349363003777
+:10F5C0008F640084304200FF306300FF0066182122
+:10F5D000000318800043282100A4202B1080000B7A
+:10F5E000000000009763003C8F6200843063FFFFDF
+:10F5F000004510230062182B146000040000000076
+:10F600008F6200840A001372004580239762003CD9
+:10F610003050FFFF8FA30010306200041040000440
+:10F62000000628808FA2001C0A00137A0202102B09
+:10F630002E02021850400003240202180A0013830D
+:10F6400002051023306300041060000300451023FE
+:10F650008FA2001C00451023004080212C42008016
+:10F6600054400001241000800E0011FE02402021B1
+:10F6700024020001AF62000C9362003E00102040A3
+:10F680003042007FA362003E8E220004244200012B
+:10F69000AF620040A770003C8F6200509623000EBE
+:10F6A00000431021AF6200588F62005000441021C7
+:10F6B000AF62005C8E220004AF6200188E22000848
+:10F6C000AF62001C8FA20010304200085440000AB4
+:10F6D00093A20020A3600036936200362403FFDF6C
+:10F6E000A36200359362003E00431024A362003EF3
+:10F6F0000A0013AD8E220008A36200358E22000896
+:10F70000AF62004C8F6200248F63004000431021E1
+:10F71000AF6200489362000024030050304200FFB3
+:10F72000144300122403FF803C0208008C4231A0E5
+:10F730000242102100431024AF4200283C0208007E
+:10F740008C4231A08E2400083C03000C02421021A0
+:10F750003042007F0342102100431021AC4400D806
+:10F760008E230008AF820024AC4300DC0E00120799
+:10F770000240202124040038000028212406000A29
+:10F780000E001301000000008FBF00348FB2003064
+:10F790008FB1002C8FB000282402000103E0000884
+:10F7A00027BD003827BDFFE8AFBF001090C7000D90
+:10F7B00000C0282130E6001010C0000A30E200042A
+:10F7C0008CA300088F6200541062000630E200042F
+:10F7D000144000178FBF0010000020210A000D13F5
+:10F7E00027BD00181040000D30E3001210C00010BB
+:10F7F0008FBF00108CA300088F6200541462000DAC
+:10F8000024020001240400382405008D0E00130199
+:10F81000240600120A0013F98FBF00102402001200
+:10F82000146200038FBF00100A00132F27BD0018B9
+:10F830002402000103E0000827BD001827BDFFF8DF
+:10F8400027420180AFA20000308A00FF8F4201B83A
+:10F850000440FFFE000000008F4601283C02080023
+:10F860008C4231A02403FF80AF86004C00C21021DF
+:10F8700000431024AF4200243C0208008C4231A017
+:10F880008FA900008FA8000000C210213042007F25
+:10F89000034218213C02000A00621821946400D43B
+:10F8A0008FA700008FA5000024020002AF83002470
+:10F8B000A0A2000B8FA30000354260003084FFFF40
+:10F8C000A4E200083C021000AD260000AD040004D4
+:10F8D000AC60002427BD0008AF4201B803E0000877
+:10F8E000240200018C8200048F8300240045102331
+:10F8F000AC820004906200633042007FA06200632B
+:10F900008C8200209383002C8F85002434420002D7
+:10F91000AF830040A780003EAC820020A4A000E49A
+:10F9200090A200632403FFBF0043102403E00008FB
+:10F93000A0A20063274301808F4201B80440FFFE6C
+:10F940008F82004CAC6200008F420124AC62000444
+:10F9500024026083A462000824020002A062000B5B
+:10F960003C02100003E00008AF4201B88F8800405D
+:10F970009382002C8F8300243C07080024E775AC99
+:10F9800000481023304200FF304900FC2465008805
+:10F990008F860044304A0003112000090000202116
+:10F9A000248200048CA30000304400FF0089102A48
+:10F9B000ACE3000024A500041440FFF924E7000490
+:10F9C00011400009000020212482000190A30000C2
+:10F9D000304400FF008A102BA0E3000024A50001A2
+:10F9E0001440FFF924E7000130C200031440000472
+:10F9F0008F850040310200031040000D0000000020
+:10FA000010A00009000020212482000190C3000002
+:10FA1000304400FF0085102BA0E3000024C6000145
+:10FA20001440FFF924E7000103E000080000000093
+:10FA30001100FFFD00002021248200048CC300007F
+:10FA4000304400FF0088102BACE3000024C6000403
+:10FA50001440FFF924E7000403E000080000000060
+:10FA60008F8300409382002C30C600FF30A500FF3A
+:10FA700000431023304300FF8F8200240080382190
+:10FA80000043102114C0000224480088008338215C
+:10FA900030E200031440000530A2000314400003CC
+:10FAA000306200031040000D0000000010A00009AB
+:10FAB000000020212482000190E30000304400FF78
+:10FAC0000085102BA103000024E700011440FFF97A
+:10FAD0002508000103E000080000000010A0FFFD61
+:10FAE00000002021248200048CE30000304400FF49
+:10FAF0000085102BAD03000024E700041440FFF93B
+:10FB00002508000403E000080000000027BDFFF8FE
+:10FB10002402FFFFAFA20000008038212405002F3F
+:10FB20003C090800252971AC240800FF2406FFFFCA
+:10FB300090E2000024A3FFFF0006220200C210266C
+:10FB4000304200FF00021080004910218C4200006A
+:10FB5000306500FF24E7000114A8FFF5008230267D
+:10FB600000061027AFA20004AFA200000000282169
+:10FB700027A6000400C510239044000324A200011E
+:10FB800000BD1821304500FF2CA200041440FFF9ED
+:10FB9000A06400008FA2000003E0000827BD000859
+:10FBA0000080482130AAFFFF30C600FF30E7FFFF8A
+:10FBB000274801808F4201B80440FFFE8F82004C2D
+:10FBC000AD0200008F420124AD0200048D2200200E
+:10FBD000A5070008A102000A24020016A102000BDA
+:10FBE000934301208D2200088D240004306300FF20
+:10FBF000004310219783003E004410218D250024EE
+:10FC0000004310233C0308008C6331A08F84002440
+:10FC1000A502000C246300E82402FFFFA50A000EE1
+:10FC2000A5030010A5060012AD050018AD020024C2
+:10FC3000948201142403FFF73042FFFFAD02002835
+:10FC40008C820118AD02002C3C021000AD00003087
+:10FC5000AF4201B88D2200200043102403E00008C9
+:10FC6000AD2200208F82002430E7FFFF0080482172
+:10FC7000904200D330A5FFFF30C600FF0002110004
+:10FC800030420F0000E23825274801808F4201B83A
+:10FC90000440FFFE8F82004CAD0200008F42012421
+:10FCA000AD0200048D220020A5070008A102000A71
+:10FCB00024020017A102000B934301208D220008AB
+:10FCC0008D240004306300FF004310219783003E21
+:10FCD000004410218F840024004310233C030800BB
+:10FCE0008C6331A0A502000CA505000E246300E87A
+:10FCF000A5030010A5060012AD0000148D220024FB
+:10FD0000AD0200188C82005CAD02001C8C82005891
+:10FD1000AD0200202402FFFFAD020024948200E621
+:10FD20003042FFFFAD02002894820060948300BE41
+:10FD300030427FFF3063FFFF0002120000431021BA
+:10FD4000AD02002C3C021000AD000030AF4201B803
+:10FD5000948200BE2403FFF700A21021A48200BEFB
+:10FD60008D2200200043102403E00008AD22002073
+:10FD7000274301808F4201B80440FFFE240200188F
+:10FD8000AC640000A062000B8F820024944200E665
+:10FD9000A46200103C021000AC60003003E00008D8
+:10FDA000AF4201B8274301808F4201B80440FFFEF3
+:10FDB0008F8200289442001C3042FFFF000211C0D5
+:10FDC000AC62000024020019A062000B3C0210008B
+:10FDD000AC60003003E00008AF4201B88F8700300C
+:10FDE00030C300FF8F4201B80440FFFE8F82004CF9
+:10FDF00034636000ACA2000093820048A0A200051A
+:10FE00008CE20010A4A20006A4A300088C820020AB
+:10FE10002403FFF7A0A2000A24020002A0A2000B04
+:10FE20008CE20000ACA200108CE20004ACA2001432
+:10FE30008CE2001CACA200248CE20020ACA20028C2
+:10FE40008CE2002CACA2002C8C820024ACA2001806
+:10FE50003C021000AF4201B88C8200200043102405
+:10FE600003E00008AC8200209382004824030001D4
+:10FE700027BDFFE8004330042C420020AFB0001043
+:10FE8000AFBF00142410FFFE10400005274501807D
+:10FE90003C0208008C4231900A001598004610245C
+:10FEA0003C0208008C4231940046102414400007A4
+:10FEB000240600848F8300242410FFFF90620062D8
+:10FEC0003042000F34420040A06200620E00156410
+:10FED00000000000020010218FBF00148FB000103E
+:10FEE00003E0000827BD00188F83002827BDFFE02E
+:10FEF000AFB20018AFB10014AFB00010AFBF001C1C
+:10FF00009062000D00A0902130D100FF3042007FB0
+:10FF1000A062000D8F8500248E4300180080802190
+:10FF20008CA2007C146200052402000E90A20063E3
+:10FF3000344200200A0015C1A0A200630E001587FC
+:10FF4000A38200482403FFFF104300472404FFFF5F
+:10FF500052200045000020218E4300003C0200108A
+:10FF600000621024504000043C02000802002021DE
+:10FF70000A0015D024020015006210245040000928
+:10FF80008E45000002002021240200140E00158777
+:10FF9000A38200482403FFFF104300332404FFFF23
+:10FFA0008E4500003C02000200A210241040001602
+:10FFB0003C0200048F8600288CC200148CC3001001
+:10FFC0008CC40014004310230044102B5040000543
+:10FFD000020020218E43002C8CC20010106200030E
+:10FFE000020020210A001601240200123C02000433
+:10FFF00000A210245040001C0000202102002021FB
+:020000040001F9
+:100000000A0016012402001300A21024104000066A
+:100010008F8300288C6200105040001300002021C4
+:100020000A0015FB020020218C62001050400004E1
+:100030008E42002C020020210A0016012402001129
+:100040005040000900002021020020212402001756
+:100050000E001587A38200482403FFFF104300020F
+:100060002404FFFF000020218FBF001C8FB2001866
+:100070008FB100148FB000100080102103E0000841
+:1000800027BD00209383002C27BDFFE0240200340D
+:10009000AFB20018AFB10014AFBF001CAFB000107A
+:1000A000008088211462000C00A090218F84003011
+:1000B0000E0014B08C9000301202000724020005DC
+:1000C000022020210E001587A38200482403FFFF91
+:1000D0001043005F2404FFFF924200041040000917
+:1000E0008F820024022020212402000C0E0015879C
+:1000F000A38200482403FFFF104300552404FFFFA0
+:100100008F820024A38000208E4300048C44008052
+:100110003C0200FF3442FFFF006218240083202BC2
+:1001200010800008AF83003802202021240200192B
+:100130000E001587A38200482403FFFF10430044EC
+:100140002404FFFF9782003E8F8700408F8800388D
+:100150000047102311000039A782003E8F8600243B
+:100160003045FFFF8F84004C90C300BC3C02080068
+:100170008C4231A0000318823070000100822021DF
+:10018000001010800102102100A2282B10A00010E6
+:10019000248200888F8400301082000D3C033F01D0
+:1001A0008E420000004310243C0325001443000647
+:1001B00030E500FF8C820000ACC200888C82001009
+:1001C0000A001661ACC200980E00148500003021B0
+:1001D0008F850038938300208F86002430A200038F
+:1001E000000210233042000300433821A38700207F
+:1001F00094C400E400A228218F8300408F82004431
+:1002000034841000A4C400E400431021AF820044F1
+:100210001200000EAF85004024E20004A3820020FB
+:1002200094C200E424A30004AF83004034422000C1
+:10023000A4C200E40A001681000020218F8200443D
+:10024000AF80004000471021AF8200440000202111
+:100250008FBF001C8FB200188FB100148FB0001038
+:100260000080102103E0000827BD00208F860024B5
+:1002700027BDFFE8AFBF0014AFB0001090C200630D
+:10028000304200201040000830A500FF8CC2007CE6
+:100290002403FFDF24420001ACC2007C90C2006353
+:1002A00000431024A0C2006310A000238F83002409
+:1002B00027500180020028210E00156424060082C8
+:1002C0008F82002490420063304200405040001969
+:1002D000A38000488F8300308F4201B80440FFFEA6
+:1002E0008F82004CAE02000024026082A602000849
+:1002F00024020002A202000B8C620008AE02001071
+:100300008C62000CAE0200148C620014AE02001865
+:100310008C620018AE0200248C620024AE02002819
+:100320008C620028AE02002C3C021000AF4201B8E3
+:10033000A38000488F8300248FBF00148FB000106B
+:100340009062006327BD00183042007FA062006306
+:100350009782003E8F8600408F8500249383002C77
+:1003600000461023A782003EA4A000E490A40063EE
+:100370008F820044AF8300402403FFBF004610215A
+:1003800000832024AF820044A0A400638F82002455
+:10039000A04000BD8F82002403E00008A44000BEFE
+:1003A0008F8A002427BDFFE0AFB10014AFB000106A
+:1003B0008F880040AFBF001893890020954200E469
+:1003C00030D100FF0109182B0080802130AC00FFE4
+:1003D0003047FFFF0000582114600003310600FF82
+:1003E00001203021010958239783003E0068102B1B
+:1003F00014400032000000001468000724020001CD
+:100400008E0200202403FFFB34E780000043102409
+:10041000AE0200202402000134E7088015820005A6
+:100420003165FFFF0E0014D5020020210A001716C7
+:10043000020020210E001506020020210E001549A1
+:100440008F84004C8F840024948200602442000139
+:10045000A4820060948200603C0308008C633188B1
+:1004600030427FFF5443000F02002021948200603D
+:100470002403800000431024A48200609082006066
+:1004800090830060304200FF000211C2000210277A
+:10049000000211C03063007F00621825A083006055
+:1004A00002002021022028218FBF00188FB10014E4
+:1004B0008FB000100A00168827BD0020914200630B
+:1004C0002403FF8000431025A14200639782003E71
+:1004D0003048FFFF11000020938300208F84002408
+:1004E000004B1023304600FF948300E42402EFFF0A
+:1004F0000168282B00621824A48300E414A00003E0
+:100500008E02002001005821000030212403FFFB4F
+:1005100034E7800000431024AE02002024020001D2
+:10052000158200053165FFFF0E0014D50200202161
+:100530000A00173E9783003E0E0015060200202198
+:100540009783003E8F820040A780003E0043102327
+:10055000AF820040938300208F8200248FBF001859
+:100560008FB100148FB0001027BD002003E00008F9
+:10057000A04300BD8F82002490430088904500BDB9
+:10058000244900883063003F2463FFE02402000117
+:10059000006238042C63002030E80019A385002095
+:1005A00010600010AF8900303C028000344200022D
+:1005B00024050001240600011500000800E21824AB
+:1005C000000028211460000530E2002010400005E2
+:1005D000240500019126000130C600010A0016D54D
+:1005E0000000000003E000080000000027BDFFD865
+:1005F000AFB000108F900030AFB40020AFB1001446
+:10060000AFBF0024AFB3001CAFB200188E050010BE
+:100610003C0208008C4231B08F86003430A33FFF8B
+:100620000062182B8CD30014008088218CD200200B
+:10063000106000780000A02190C3000D2402FF800C
+:1006400000431024304200FF50400073022020215C
+:1006500000051382304200035440006F0220202125
+:1006600094C3001C8F8200248E050028A44301142B
+:100670008CC2001002621823146500072402001FB8
+:100680008F820038006210210262102B1040000897
+:100690008F830028240200180E001587A3820048CB
+:1006A0002403FFFF1043006F2404FFFF8F83002803
+:1006B0008F8400388C620010024490210044102383
+:1006C000AC6200108F820024AC7200208C42006863
+:1006D0000052102B104000098F830034022020218B
+:1006E0002402001D0E001587A38200482403FFFF8B
+:1006F0001043005C2404FFFF8F8300348E0200242B
+:100700008C63002410430007022020212402001CD7
+:100710000E001587A38200482403FFFF10430051F9
+:100720002404FFFF8F8400288C82002424420001CF
+:10073000AC820024125300048F8200248C42006893
+:100740005642000E8E0200008E0200003C03008024
+:10075000004310241440000D2402001A022020211E
+:100760000E001587A38200482403FFFF1043003DBD
+:100770002404FFFF0A0017D28E0200143C030080FD
+:1007800000431024504000038E020014AC8000206F
+:100790008E0200142412FFFF105200062402001BD8
+:1007A000022020210E001587A38200481052002D40
+:1007B0002404FFFF8E0300003C02000100621024AD
+:1007C0001040001F3C02008000621024144000080A
+:1007D000022020212402001A0E001587A38200485F
+:1007E0002403FFFF1043001F2404FFFF02202021E9
+:1007F000020028210E0015A7240600012403FFFF94
+:100800002404FFFF1443000E241400010A001807FB
+:100810008FBF0024022020212402000D8FBF00245E
+:100820008FB400208FB3001C8FB200188FB100145A
+:100830008FB0001027BD00280A001587A38200484A
+:100840008F8300280220202102803021946200360C
+:1008500024050001244200010E0016D5A4620036D2
+:10086000000020218FBF00248FB400208FB3001C14
+:100870008FB200188FB100148FB0001000801021CB
+:1008800003E0000827BD00288F83002427BDFFD880
+:10089000AFB40020AFB3001CAFB20018AFB100146A
+:1008A000AFB00010AFBF0024906200638F910030A2
+:1008B0002412FFFF3442004092250000A062006332
+:1008C0008E2200100080982130B0003F10520006A8
+:1008D0000360A0212402000D0E001587A3820048AA
+:1008E000105200522404FFFF8F8300248E22001830
+:1008F0008C63007C10430007026020212402000E5C
+:100900000E001587A38200482403FFFF1043004711
+:100910002404FFFF24040020120400048F83002419
+:100920009062006334420020A06200638F8500382B
+:1009300010A0001E00000000560400048F82002456
+:10094000026020210A0018512402000A9683000A3E
+:100950002404FFFD944200603042FFFF1043003446
+:100960008FBF00243C0208008C42318C0045102BC4
+:100970001440000602602021000028210E0016D538
+:10098000240600010A001878000020212402002D0E
+:100990000E001587A38200482403FFFF10430023A5
+:1009A0002404FFFF0A001878000020211604000527
+:1009B0008F8400248E2300142402FFFF506200184D
+:1009C000026020219482006024420001A482006021
+:1009D000948200603C0308008C63318830427FFFC2
+:1009E0005443000F026020219482006024038000A1
+:1009F00000431024A4820060908200609083006015
+:100A0000304200FF000211C200021027000211C094
+:100A10003063007F00621825A083006002602021FF
+:100A20000E00168824050001000020218FBF00243D
+:100A30008FB400208FB3001C8FB200188FB1001448
+:100A40008FB000100080102103E0000827BD0028AF
+:100A50008F83002427BDFFE8AFB00010AFBF0014A4
+:100A6000906200638F870030008080213442004014
+:100A70008CE60010A06200633C0308008C6331B078
+:100A800030C23FFF0043102B1040004E8F850034D2
+:100A90002402FF8090A3000D00431024304200FF89
+:100AA0005040004902002021000613823048000314
+:100AB00024020002550200440200202194A2001CDE
+:100AC0008F85002424030023A4A201148CE60000D7
+:100AD000000616023042003F104300103C03008322
+:100AE0008CE300188CA2007C106200062402000E29
+:100AF0000E001587A38200482403FFFF104300382F
+:100B00002404FFFF8F83002490620063344200209E
+:100B1000A06200630A0018BD8F83002800C3102460
+:100B2000144300078F83002890A200623042000F18
+:100B300034420020A0A20062A388003C8F830028DA
+:100B40009062000D3042007FA062000D8F8300385C
+:100B500010600018020020218F8400348C82001065
+:100B60000043102B1040000924020018020020212D
+:100B70000E001587A38200482403FFFF10430018CE
+:100B80002404FFFF0A0018E5000020218C820010D9
+:100B90002405000102002021004310238F83002838
+:100BA000240600010E0016D5AC6200100A0018E5FC
+:100BB000000020210E001688240500010A0018E517
+:100BC00000002021020020212402000D8FBF00140C
+:100BD0008FB0001027BD00180A001587A3820048B7
+:100BE0008FBF00148FB000100080102103E00008B8
+:100BF00027BD001827BDFFD8AFB000108F90003080
+:100C0000AFB3001CAFBF0020AFB20018AFB10014EB
+:100C10008E1200103C0308008C6331B032423FFF5B
+:100C20000043102B1040007C008098218F850034F9
+:100C30002402FF8090A3000D00431024304200FFE7
+:100C400050400076026020210012138230420003DF
+:100C500024030001544300710260202190A2000D82
+:100C600030420008544000038F8200380A001915F2
+:100C700024020024504000038E03000C0A001915C2
+:100C8000240200278CA20020146200052402002008
+:100C90008E0300088CA200241062000824020020A9
+:100CA0000E001587A38200482403FFFF1043006A4B
+:100CB0002404FFFF0A0019408F8400288E020014CC
+:100CC0002411FFFF145100038F8700240A00193BF1
+:100CD000240200258E0300188CE2007C14620016AA
+:100CE0002402000E8E0300248CA20028146200123D
+:100CF000240200218E0600288CA2002C14C2000EB3
+:100D00002402001F8E03002C1060000B240200231D
+:100D10008CE200680043102B1440000724020026D8
+:100D20008CA20014006618210043102B50400007CD
+:100D30008F840028240200220E001587A382004819
+:100D4000105100452404FFFF8F8400282403FFF77F
+:100D50009082000D00431024A082000D8F86002495
+:100D60003C0308008C6331AC8F82004C94C400E0DB
+:100D70008F8500280043102130847FFF000420402D
+:100D8000004410213043007F034320213C03000E28
+:100D9000008320212403FF8000431024AF42002C55
+:100DA000A49200008CA2002824420001ACA20028DA
+:100DB0008CA2002C8E03002C00431021ACA2002C2E
+:100DC0008E02002CACA200308E020014ACA20034C3
+:100DD00094A2003A24420001A4A2003A94C600E082
+:100DE0003C0208008C4231B024C4000130837FFFF4
+:100DF000146200130080302124028000008230241D
+:100E000030C2FFFF000213C2304200FF0002102771
+:100E10000A00197D000233C0026020212402000D67
+:100E20008FBF00208FB3001C8FB200188FB1001449
+:100E30008FB0001027BD00280A001587A382004844
+:100E40008F82002402602021240500010E001688F4
+:100E5000A44600E0000020218FBF00208FB3001CBB
+:100E60008FB200188FB100148FB0001000801021D5
+:100E700003E0000827BD002827BDFFE0AFB1001444
+:100E80008F910030AFB00010AFBF00188E26001059
+:100E90003C0308008C6331B030C23FFF0043102B8D
+:100EA0001040005E008080218F8500342402FF8086
+:100EB00090A3000D00431024304200FF5040005822
+:100EC000020020218F8200381040000800061382A3
+:100ED0008F8200249763000A2404FFFD944200607F
+:100EE0003042FFFF104300550006138230420003DA
+:100EF0001440000E00000000922200021040000585
+:100F00008E23002450600015922300030A0019B6B6
+:100F1000020020218CA200245062001092230003C2
+:100F2000020020210A0019BE2402000F90A2000D29
+:100F3000304200085440000992230003020020219F
+:100F4000240200100E001587A38200482403FFFF2F
+:100F50001043003A2404FFFF9223000324020002FE
+:100F60005462000C922200038F8200385440000922
+:100F700092220003020020212402002C0E0015877B
+:100F8000A38200482403FFFF1043002C2404FFFF2A
+:100F9000922200030220282102002021384600105E
+:100FA0002CC600012C4200010E0015A7004630257A
+:100FB0002411FFFF105100212404FFFF8F8300380C
+:100FC00010600012020020213C0208008C42318C8B
+:100FD0000043102B144000060000000000002821F0
+:100FE0000E0016D5240600010A0019FC000020217D
+:100FF0002402002D0E001587A38200481051000F17
+:101000002404FFFF0A0019FC000020210E001688AE
+:10101000240500010A0019FC000020210200202103
+:101020002402000D8FBF00188FB100148FB0001084
+:1010300027BD00200A001587A38200488FBF001833
+:101040008FB100148FB000100080102103E0000861
+:1010500027BD00209383003C27BDFFE0240200024F
+:10106000AFB10014AFB0001000808821AFBF0018EE
+:10107000000080211062008C2404FFFD9785003E53
+:101080008F83004030A2FFFF0043102B5440007DAF
+:101090008F8400440E001448000000003C02080049
+:1010A000244275AC02202021004028210E00160E9B
+:1010B000AF8200302409FFFF1049007B2404FFFFAA
+:1010C0003C0808008D0875BC3C0208008C4231B019
+:1010D0003C030800906375AC31043FFF0082102B85
+:1010E0001040001B3067003F3C0208008C4231A8D2
+:1010F0008F83004C000421800062182100641821B5
+:101100003062007F034228213C02000C00A228210B
+:101110003C020080344200013066007800C2302575
+:101120002402FF8000621024AF42002830640007D0
+:10113000AF4208048F820024034420212484094004
+:10114000AF460814AF850028AF840034AC430118C3
+:101150009383003C240200031462003B240200013C
+:101160002402002610E2003D28E200271040001370
+:10117000240200322402002210E2003828E2002378
+:1011800010400008240200242402002010E2002461
+:101190002402002110E2001E022020210A001A7BF6
+:1011A0002402000B10E2002D2402002510E20010A2
+:1011B000022020210A001A7B2402000B10E2001AF0
+:1011C00028E20033104000062402003F24020031D0
+:1011D00010E2000B022020210A001A7B2402000BDF
+:1011E00010E20011022020210A001A7B2402000BC9
+:1011F0000E001768022020210A001A960040802164
+:101200000E0018EA022020210A001A9600408021D0
+:101210000E00198B022020210A001A96004080211E
+:101220001509000E000000000E00180F02202021FA
+:101230000A001A96004080210E001587A3820048FC
+:101240000A001A9600408021146200170200202133
+:101250002402002314E200052402000B0E00188172
+:10126000022020210A001A9600408021022020211D
+:10127000A38200480E0015872410FFFF0A001A976A
+:101280000200202130A500FF0E0014852406000175
+:101290009783003E8F820040A780003E00431023CA
+:1012A000AF820040020020218FBF00188FB10014D0
+:1012B0008FB000100080102103E0000827BD00203F
+:1012C00027BDFFE0AFB10014AFBF0018AFB00010F2
+:1012D0008F4601283C0308008C6331A02402FF8064
+:1012E000AF86004C00C318213065007F03452821DC
+:1012F000006218243C02000AAF43002400A2282107
+:1013000090A2006200808821AF850024304200FF57
+:1013100000021102A382003C90A200BC30420002F5
+:101320001440000224030034240300308F82002480
+:10133000A383002C9383003C8C4200C0A380004810
+:10134000AF82004024020004106200308F8400400D
+:101350008E2400045080002D8F8400408E220010C7
+:101360003083FFFFA784003E1060001FAF8200445F
+:101370008F8300242405FF800220202190620063D7
+:1013800000A21024304200FF1440000D00000000B5
+:101390000E001A029790003E1040001000401821E5
+:1013A0002402FFFD546200118E2300200200282138
+:1013B0000E001426022020210A001AE88E230020A5
+:1013C0009062006300A21024304200FF104000032E
+:1013D000022020210E00174A000000009782003EE4
+:1013E0001440FFE48F8300248E2300203062000429
+:1013F000104000068F8400402402FFFB006210248E
+:101400000E00143AAE2200208F8400408F83002407
+:101410008FBF00188FB100148FB00010240200019C
+:1014200027BD002003E00008AC6400C030A500FF29
+:101430002403000124A900010069102B1040000CB6
+:1014400000004021240A000100A31023004A3804B0
+:1014500024630001308200010069302B104000023B
+:10146000000420420107402554C0FFF800A31023C8
+:1014700003E000080100102127BDFFE03C021EDC54
+:10148000AFB20018AFB10014AFBF001CAFB0001076
+:1014900034526F4100008821240500080E001AF81C
+:1014A00002202021001180803C07080024E771AC55
+:1014B0000002160002071821AC620000000028217B
+:1014C00024A200013045FFFF8C6200002CA600081A
+:1014D00004410002000220400092202614C0FFF8C0
+:1014E000AC640000020780218E0400000E001AF890
+:1014F00024050020262300013071FFFF2E23010068
+:101500001460FFE5AE0200008FBF001C8FB2001810
+:101510008FB100148FB0001003E0000827BD002039
+:101520003C02080024426A743C010800AC2271A00D
+:101530003C02080024424FF03C010800AC2271A498
+:10154000240200063C010800A02271A80A001B0B1F
+:101550000000000027BDFFD8AFB3001CAFB20018D9
+:10156000AFBF0020AFB10014AFB000108F510140E9
+:101570008F48014800089402324300FF311300FFF6
+:101580008F4201B80440FFFE27500180AE110000D9
+:101590008F420144AE02000424020002A612000899
+:1015A000A202000B24020014AE13002410620025D6
+:1015B00028620015104000082402001524020010C3
+:1015C0001062003024020012106200098FBF002058
+:1015D0000A001C358FB3001C106200702402002228
+:1015E000106200378FBF00200A001C358FB3001C2B
+:1015F0003C0208008C4231A02403FF80022210210B
+:1016000000431024AF4200243C0208008C4231A069
+:10161000022210213042007F034218213C02000ABE
+:1016200000621821166000BCAF8300249062006243
+:101630003042000F34420030A06200620A001C34C5
+:101640008FBF00203C0460008C832C083C02F00318
+:101650003442FFFF00621824AC832C083C020800CF
+:101660008C4231A08C832C0824420074000210822A
+:101670000002148000621825AC832C080A001C3478
+:101680008FBF00203C0208008C4231A02403FF8061
+:101690000222102100431024AF4200243C02080023
+:1016A0008C4231A03C03000A022210213042007F0C
+:1016B00003421021004310210A001C33AF82002492
+:1016C0003C0208008C4231A02405FF800222102138
+:1016D00000451024AF4200243C0208008C4231A097
+:1016E000022210213042007F034218213C02000AEE
+:1016F000006218219062006300A21024304200FFB3
+:1017000010400085AF8300242462008894430012B7
+:101710003C0208008C4231A830633FFF000319806F
+:1017200002221021004310213043007F0343202177
+:10173000004510243C03000C00832021AF42002808
+:101740009082000D00A21024304200FF1040007271
+:10175000AF8400289082000D304200101440006FCA
+:101760008FBF00200E001556000000008F4201B808
+:101770000440FFFE00000000AE1100008F42014453
+:10178000AE02000424020002A6120008A202000B0E
+:10179000AE1300240A001C348FBF00202406FF80F3
+:1017A00002261024AF4200203C0208008C4231A0E7
+:1017B00031043FFF00042180022210210046102442
+:1017C000AF4200243C0308008C6331A83C020800AF
+:1017D0008C4231A03227007F0223182102221021DF
+:1017E000006418213042007F3064007F03422821CA
+:1017F0003C02000A0066182400A22821034420218C
+:101800003C02000C00822021AF4300283C0200086B
+:101810000347182100629021AF850024AF8400287F
+:101820000E001556010080218F4201B80440FFFED2
+:101830008F8200288F840024274501809042000D6C
+:10184000ACB10000A4B000060002160000021603AE
+:1018500000021027000237C214C00016248200883C
+:101860009442001232033FFF30423FFF1443001204
+:1018700024026082908300632402FF8000431024CE
+:10188000304200FF5040000C2402608290820062CF
+:101890003042000F34420040A08200622402608483
+:1018A000A4A200082402000DA0A200050A001C1E2C
+:1018B0003C02270024026082A4A20008A0A0000528
+:1018C0003C02270000061C000062182524020002CA
+:1018D000A0A2000BACA30010ACA00014ACA000248C
+:1018E000ACA00028ACA0002C8E42004C8F840028B5
+:1018F000ACA200189083000D2402FF800043102446
+:10190000304200FF104000058FBF00209082000D84
+:101910003042007FA082000D8FBF00208FB3001CDB
+:101920008FB200188FB100148FB000103C0210006D
+:0C19300027BD002803E00008AF4201B80A
+:04193C00080033F874
+:10194000080033F808003370080033A8080033DCBF
+:10195000080034000800340008003400080032E0B9
+:101960000A00012200000000000000000000000D3D
+:10197000747061352E302E306A330000050000018E
+:101980000000000000000000000000000000000057
+:101990000000000000000000000000000000000047
+:1019A0000000000000000000000000000000000037
+:1019B0000000000000000000000000000000000027
+:1019C0000000000000000000000000000000000017
+:1019D0000000000000000000000000000000000007
+:1019E00000000000000000000000000010000003E4
+:1019F000000000000000000D0000000D3C02080087
+:101A000024421B803C03080024632014AC400000E7
+:101A10000043202B1480FFFD244200043C1D0800DD
+:101A200037BD2FFC03A0F0213C10080026100488CD
+:101A30003C1C0800279C1B800E00015A000000007F
+:101A40000000000D3084FFFF308200078F850018F2
+:101A500010400002248300073064FFF80085302125
+:101A600030C41FFF03441821247B4000AF85001CB5
+:101A7000AF84001803E00008AF4400843084FFFF07
+:101A8000308200078F8500208F86002810400002DA
+:101A9000248300073064FFF8008520210086182B7E
+:101AA00014600002AF85002400862023034428210F
+:101AB00034068000AF840020AF44008000A62021BF
+:101AC00003E00008AF84003827BDFFD8AFB3001C87
+:101AD000AFB20018AFB00010AFBF0024AFB4002009
+:101AE000AFB100143C0860088D1450002418FF7F2B
+:101AF0003C1A8000029898243672380CAD125000BF
+:101B00008F5100083C07601C3C0860003630000123
+:101B1000AF500008AF800018AF400080AF40008495
+:101B20008CE600088D0F08083C0760168CEC00005E
+:101B300031EEFFF039CA00103C0DFFFF340B80007E
+:101B40003C030080034B48212D440001018D2824D3
+:101B50003C0253533C010800AC230420AF890038F9
+:101B6000AF860028AF840010275B400014A200035A
+:101B700034E37C008CF90004032818218C7F007C5E
+:101B80008C6500783C02800034520070AF85003CC8
+:101B9000AF9F00403C13080026731BC40240A021E5
+:101BA0008E4800008F46000038C3000130640001F9
+:101BB00010800017AF880034028048218D2D00006E
+:101BC0003C1908008F39045C3C1108008E31045820
+:101BD00001A8F823033F7821000040210228382182
+:101BE00001FF802B00F070213C010800AC2F045C49
+:101BF0003C010800AC2E04588F4C0000398B0001CA
+:101C0000316A00011540FFED01A04021AF8D003485
+:101C10008E4E00003C0C08008D8C045C3C0A0800D1
+:101C20008D4A045801C86823018D282100005821DD
+:101C300000AD302B014B2021008610213C01080013
+:101C4000AC25045C3C010800AC2204588F45010817
+:101C50008F44010030A92000AF850000AF84000C44
+:101C60001120000A00A030213C0708008CE7042C5A
+:101C700024EF00013C010800AC2F042C3C10400074
+:101C8000AF5001380A0001900000000030B002009F
+:101C90001600001424110F001091001224070D00EB
+:101CA0001087023330B000065200FFF53C104000B0
+:101CB000936D0000240C001031A600F010CC0269D6
+:101CC000240E007010CE02DD8F8B001425670001FA
+:101CD000AF8700143C104000AF5001380A0001905B
+:101CE00000000000974801041100FFE53C1040008F
+:101CF00030B84000170000A2000000008F590178A2
+:101D00000720FFFE8F8700382409000824050800FB
+:101D10008CE30008AF450178A7490140A740014284
+:101D2000974201048F8600003049FFFF30DF000139
+:101D300013E002D5012040212524FFFE240A0002E1
+:101D4000A74A01463088FFFFA74401483C0B080022
+:101D50008D6B043C156002C48F8F000C30C30020D3
+:101D600014600002240400092404000130CD0C009A
+:101D7000240C040051AC000134840004A744014A3F
+:101D80003C0508008CA504203C0200483C190001D9
+:101D900000A2F82530D8000203F92825130000041A
+:101DA000000018213C04010000A4282524030001A0
+:101DB00030CA000451400005AF8300083C06001003
+:101DC00000A6282524030001AF830008AF451000BA
+:101DD0000000000000000000000000000000000003
+:101DE0008F83000810600023000000008F4B10005C
+:101DF0000561FFFE000000001060001E00000000F2
+:101E00008F4D10003C03002001A3602411800019B5
+:101E10008F8F000031EE000211C00016000000009C
+:101E2000975010141600001300000000974510088A
+:101E300030BFFFFF27F800060018C8820019308065
+:101E400000C72821331100013303000312200320AF
+:101E50008CA200000000000D00C7F821AFE20000D6
+:101E60003C1908008F390430272600013C01080086
+:101E7000AC2604308F6A00003405FFFFAF8A0004EF
+:101E80008CE200001045029A000020218CE5000041
+:101E900030BF010013E0027E010020213C07080052
+:101EA0008CE704743C1008008E10044C00E85821A4
+:101EB0003C1808008F1804700168882B3C08080043
+:101EC0008D0804480000782102046021030F1821C6
+:101ED0000184702B010F68210071502101AE102187
+:101EE0003C010800AC2C044C3C010800AC22044826
+:101EF0003C010800AC2B04743C010800AC2A0470BF
+:101F00008F8D0018012030213129000725AE0008EF
+:101F100031C21FFF03426021AF8D001CAF82001849
+:101F2000259B4000AF420084112000038F900020C9
+:101F300024C800073106FFF88F84002800D028212C
+:101F400000A4782B15E00002AF90002400A4282301
+:101F50000345202134038000008310213C0610003B
+:101F6000AF850020AF820038AF450080AF460178D2
+:101F70008F8B0014256700010A0001DDAF87001474
+:101F80008F6200088F670000241100300007C6022E
+:101F9000330300F0107100A2241900401479FF4BA4
+:101FA0008F8B00148F4A01780540FFFE30A7020096
+:101FB00014E00003000512820000000D00051282EB
+:101FC000305000030010490001307021000E68807D
+:101FD00001B06021000C5880017380218E08000040
+:101FE00015000002000000000000000D8F6F0004CB
+:101FF00005E202B19203000692070005920F000469
+:102000003C0200010007288000B060218D89001883
+:102010002771000825EE000501226821000E30829C
+:10202000AD8D0018022020210E0005802605001429
+:10203000920B00068F7F00043C087FFF000B20807E
+:10204000009130218CC30004350AFFFF03EAC82445
+:102050000079C021ACD80004920700059209000461
+:10206000960D00080007288000B1F8218FEF0000CE
+:10207000974201043C07FFFF01E75024304EFFFF69
+:1020800001C96021018D58233168FFFF01482025D7
+:10209000AFE40000920300072419000110790269DF
+:1020A0002406000310660279000000008E1900105B
+:1020B000241F000AA75F0140A759014292030004B0
+:1020C0008F86000024070001A7430144A740014672
+:1020D0009758010430D100023C050041A75801483F
+:1020E00000001821A747014A1220000330CA00044B
+:1020F0003C0501412403000151400005AF83000865
+:102100003C08001000A8282524030001AF83000824
+:10211000AF451000000000000000000000000000BB
+:10212000000000008F8B0008116000040000000018
+:102130008F4410000481FFFE000000008F6A000041
+:10214000920700043C0508008CA50444AF8A0004F3
+:10215000975F01043C0F08008DEF044030E300FF5F
+:1021600033F9FFFF0079C02100B868210000102179
+:1021700024E6000A30C8FFFF01B8482B01E27021B5
+:1021800001C96021311000073C010800AC2D044456
+:102190003C010800AC2C0440120000038F8D001895
+:1021A000250B00073168FFF8010D702131CC1FFFAE
+:1021B000AF8D001CAF8C0018AF4C00849744010415
+:1021C000034C80213084FFFF30880007110000039A
+:1021D000261B4000248900073124FFF88F8200204D
+:1021E0008F850028008220210085782B15E00002D1
+:1021F000AF82002400852023034488213405800019
+:10220000022510213C061000AF840020AF82003868
+:10221000AF440080AF4601780A0002858F8B00141E
+:102220008F5F017807E0FFFE30AA0200154000032F
+:10223000000542820000000D0005428231020003C9
+:102240000002710001C26821000D608001824821F6
+:102250000009288000B380218E0B0000116000026D
+:10226000000000000000000D8F6F000C05E001F37E
+:102270008F87003824190001AE1900008CE3000894
+:10228000A20000078F78000400181C02306600FFCF
+:1022900024D10005001130822CC4004114800002BA
+:1022A000A20300040000000D8F6B00043C0EFFFF32
+:1022B00000E028213164FFFF248F000B000F4082D3
+:1022C00000081080004748218D2D000026040014CE
+:1022D000A60B000801AE60240E000580AD2C0000A6
+:1022E0008F5F01083C0A100003EA382410E001A3C4
+:1022F00000000000974601049203000724D1FFEC80
+:10230000346500023224FFFFA2050007960600088C
+:102310002CC7001354E0000592030007920A00073F
+:10232000355F0001A21F000792030007240B000184
+:10233000106B01BA24090003106901CD8F880038A1
+:1023400030CFFFFF25E400020004C883333F00FFC5
+:10235000001F2880A219000500A858218D780000D0
+:10236000975101043C03FFFF030360243222FFFF67
+:10237000004F702325CDFFFE018D4825AD6900007B
+:10238000920600053C02FFF6344EFFFF30CA00FF04
+:10239000000A388000F02021909900143C1FFF7F34
+:1023A00037E7FFFF3323000F0066782131F800FF85
+:1023B0000018288000B088218E2D002000A8602100
+:1023C000A20F000601AE4824AE0D000CAD89000C32
+:1023D000920B00068E04000C0127F824000B50809D
+:1023E0000150C821972600260148C02100874024BB
+:1023F000AF260024AE08000CAF3F0020AF0600104F
+:102400008F860000240C001024090002A74C014014
+:10241000A7400142A7400144A7490146974B010448
+:102420002407000130C80002256AFFFEA74A0148C0
+:102430003C050009A747014A1100000300001821CC
+:102440003C0501092403000130CD000451A0000522
+:10245000AF8300083C06001000A6282524030001D5
+:10246000AF830008AF45100000000000000000002E
+:102470000000000000000000921800042711000274
+:10248000322F0007000F1023304E0007AE0E001051
+:102490008F90000812000004000000008F4310001D
+:1024A0000461FFFE000000008F7800008F8F00188D
+:1024B0003C1008008E100444AF98000497510104AA
+:1024C00025E6001030CA1FFF3222FFFFAF8F001C2D
+:1024D000AF8A0018AF4A00842449FFFE3C0B080075
+:1024E0008D6B0440974E010401206821000967C3E9
+:1024F000020D282131C9FFFF00AD402B016C3821AE
+:1025000000E82021034AF821313900073C01080086
+:10251000AC2504443C010800AC2404401320000313
+:1025200027FB4000252300073069FFF88F9F00201C
+:102530008F840028013F382100E4C82B17200002B7
+:10254000AF9F002400E43823034720213405800096
+:10255000008510213C061000AF870020AF820038B4
+:10256000AF470080AF4601780A0002858F8B0014C8
+:10257000975801041300FDC23C1040008F430178BE
+:102580000460FFFE30B94000132000033C04000843
+:102590000000000D3C040008AF440140240808007E
+:1025A000AF4801788F8B0000974A0104317F00010A
+:1025B00013E000E93146FFFF24D0FFFE240C0002A7
+:1025C000A74C0146A75001488F8F00182405000D25
+:1025D000A745014A8F71000025E2000830491FFF1E
+:1025E0000349702130CD0007AF910004AF8F001C6C
+:1025F000AF89001800C03821AF49008411A0000342
+:1026000025DB400024C6000730C7FFF88F98002064
+:102610008F84002800F8302100C4382B14E0000219
+:10262000AF98002400C430238F8A00140346582139
+:10263000340880000168F821255900013C0310008E
+:102640003C104000AF860020AF9F0038AF460080AE
+:10265000AF430178AF990014AF5001380A000190E0
+:10266000000000008F690000974401043127FFFF3C
+:102670003088FFFF8F4F017805E0FFFE30FF000735
+:10268000001F18233078000724E6FFFE2419000AF3
+:10269000A7590140A7580142A7460144A740014657
+:1026A000A74801488F42010830510020162000023F
+:1026B000240300092403000130AA0002A743014AB1
+:1026C0003C04004111400003000018213C0401417A
+:1026D0002403000130AB000451600005AF83000803
+:1026E0003C0500100085202524030001AF8300086D
+:1026F000AF441000000000000000000000000000D7
+:10270000000000008F90000812000004000000008C
+:102710008F4C10000581FFFE000000008F78000044
+:10272000276200088F8D003CAF9800049446000893
+:102730009451000A944F000C30CEFFFF001124008A
+:1027400031E9FFFF11CD00A2008920253C030800DC
+:102750008C6304443C1808008F18044000E85021A2
+:10276000255FFFFE007F78210000102101FF302B44
+:1027700003028821022648213C010800AC2F0444B2
+:102780003C010800AC29044024EB00083162FFFF43
+:102790003047000710E000038F8500182450000721
+:1027A0003202FFF83106FFFF30C8000700457021F4
+:1027B00031CD1FFF034D6021AF85001CAF8D001888
+:1027C000259B4000AF4D0084110000038F8F002037
+:1027D00024C400073086FFF88F84002800CF28210A
+:1027E00000A4482B15200002AF8F002400A428234A
+:1027F000AF850020AF4500803C1108008E310434C5
+:102800000345C0213402800003023021122000055C
+:10281000AF860038938300172419000E1079000D3D
+:10282000241F043F3C0A1000AF4A01788F8B00142C
+:10283000256700010A0001DDAF8700140E0005A620
+:102840003C1040008F8B0014256700010A0001DE58
+:10285000AF8700143C0A1000A75F0148AF4A017817
+:102860000A0004B48F8B0014240E0F0011EE003DFB
+:1028700030D10020162000022403000924030001A7
+:102880000A000208A743014A0A0001FBA7400146CB
+:1028900094E5000894E2000A94EB000C8F86003C5B
+:1028A0000002FC00316AFFFF30B9FFFF132600373A
+:1028B00003EA20253C0508008CA504443C1F0800C1
+:1028C0008FFF04400000502100A8382100E8302B81
+:1028D00003EAC8210326C0213C010800AC270444B8
+:1028E0003C010800AC3804400A0002698F8D0018D2
+:1028F0003C1908008F39047C3C0308008C630454A5
+:102900003C0608008CC604783C0F08008DEF04508C
+:10291000032838210068682100E8C02B00C4882102
+:1029200001A8402B01E470210238582101C8602120
+:102930003C010800AC2D04543C010800AC2C0450B0
+:102940003C010800AC27047C3C010800AC2B047857
+:102950000A0002698F8D0018A74001460A00041B77
+:102960008F8F001830D000201600FFC52403000D03
+:10297000240300050A000208A743014A97590104ED
+:102980002738FFF00A00036B3304FFFF8F8C0040F1
+:10299000148CFFC8000080213C1108008E31046CAB
+:1029A0003C0408008C8404680228702101C8782B3C
+:1029B00000904021010F68213C010800AC2E046CFE
+:1029C0003C010800AC2D04680A0002698F8D0018D4
+:1029D0008F9900401499FF5D000060213C050800BC
+:1029E0008CA5046C3C1008008E10046800E82021BF
+:1029F000248EFFFE00AEF82103EE582B020C50216E
+:102A0000014B18213C010800AC3F046C3C0108005C
+:102A1000AC2304680A00048B24EB00088F8800387C
+:102A20003C02FFFF8D0E000C01C2682401A460254A
+:102A3000AD0C000C0A00037930CFFFFF0A0003A998
+:102A4000AE000000974B0104920400048E2A000C93
+:102A500001644021251FFFF20147182433F9FFFFCD
+:102A60000079C025AE38000C0A0002D48E1900107F
+:102A70003C03FFFF8D1100100223282400A47825B9
+:102A8000AD0F00100A00037930CFFFFF9745010416
+:102A9000920600048E2F001000A610212449FFEE9C
+:102AA00001E76824312EFFFF01AE6025AE2C001037
+:102AB0000A0002D48E1900108E06000CAE00000031
+:102AC0000003C080031088210A0002A6AE26002061
+:102AD0001460000D3050FFFF3C04FFFF00446024F1
+:102AE00001846826000D582B000C502B014B10243C
+:102AF00010400002000000000000000D8CA3000048
+:102B00000A00023E006410253A11FFFF0011782BE5
+:102B10000010702B01CF2024108000020000000064
+:102B20000000000D8CB800000A00023E3702FFFFD3
+:102B30003084FFFF30A5FFFF108000070000182140
+:102B4000308200011040000200042042006518217C
+:102B50001480FFFB0005284003E0000800601021FE
+:102B600010C00007000000008CA2000024C6FFFF78
+:102B700024A50004AC82000014C0FFFB24840004E0
+:102B800003E000080000000010A0000824A3FFFFDD
+:102B9000AC86000000000000000000002402FFFFDF
+:102BA0002463FFFF1462FFFA2484000403E000089A
+:102BB00000000000308EFFFF30D8FFFF00057C00D2
+:102BC00001F8602539CDFFFF01AC5021014C582B95
+:102BD000014B4821000944023127FFFF00E8302162
+:102BE0000006240230C5FFFF00A418213862FFFF51
+:102BF00003E000083042FFFF3C0C08008D8C048489
+:102C0000240BFF8027BDFFD001845021014B4824B5
+:102C1000AF4900203C0808008D080484AFB20020B2
+:102C2000AFB00018AFBF0028AFB30024AFB1001C95
+:102C3000936600040104382130E4007F009A1021DB
+:102C40003C0300080043902130C500200360802130
+:102C50003C080111277B000814A0000226460070E2
+:102C60002646006C9213000497510104920F000451
+:102C70003267000F322EFFFF31ED004001C72823DD
+:102C800011A0000500004821925900BC333800040F
+:102C90001700009000000000924300BC307F000449
+:102CA00013E0000F0000000010A0000D0000000065
+:102CB000960E0002240AFF8000A7602125CDFFFEAA
+:102CC000A74D1016920B0004014B2024308200FF08
+:102CD00010400085010C40253C0F0400010F4025E9
+:102CE0008F5301780660FFFE2404000AA7440140C8
+:102CF000960D00022404000931AC0007000C582393
+:102D0000316A0007A74A0142960200022443FFFEEF
+:102D1000A7430144A7400146975F0104A75F01480C
+:102D20008F590108333800205300000124040001AA
+:102D3000920F000431EE001015C000023483001021
+:102D400000801821A743014A000000000000000095
+:102D50000000000000000000AF481000000000006C
+:102D60000000000000000000000000008F51100073
+:102D70000621FFFE3113FFFF126000030000000078
+:102D80008F481018ACC8000096030006307FFFFF84
+:102D900027F900020019988200138880023B302135
+:102DA0008CD800001520005700183402920300044C
+:102DB0002405FF8000A3F82433F100FF1220002C2B
+:102DC00000000000924700BC30F2000212400028D0
+:102DD00000000000974B100C2562FFFEA742101662
+:102DE000000000003C0A040035490030AF491000E3
+:102DF00000000000000000000000000000000000D3
+:102E00008F4C10000581FFFE000000009749100C58
+:102E10008F51101C00C020213127FFFF24F2003009
+:102E2000001218820003288000BBF8213226FFFF21
+:102E3000AFF100000E00059500112C020013C880B0
+:102E4000033B98218E78000000027400AFB8001098
+:102E50008FA80010310FFFFFAFAF00108FA400103C
+:102E600001C46825AFAD00108FA60010AE6600004B
+:102E700097730008976D000A9766000C8F8A003CD4
+:102E8000000D5C0030CCFFFF3262FFFF104A0036BD
+:102E9000016C2025960600023C10100024D3000887
+:102EA0000E0001393264FFFF974C01040E00014708
+:102EB0003184FFFFAF5001788FBF00288FB300240B
+:102EC0008FB200208FB1001C8FB0001803E0000803
+:102ED00027BD003010A0FF700000000024A5FFFCFB
+:102EE0000A0005CE240900048CD10000AF5110184F
+:102EF0008F5301780660FF7A2404000A0A0005E374
+:102F00000000000000A7C8218F8800388F4E101CD9
+:102F10000019C0820018788001E82021AC8E0000E2
+:102F2000000E2C0200C020210E00059531C6FFFFC7
+:102F3000023B28218CAD00000002540000403021EB
+:102F4000AFAD00108FAC0010318BFFFFAFAB0010A6
+:102F50008FA2001001424825AFA900108FA70010D2
+:102F60000A000613ACA700008F8F0040148FFFC922
+:102F70000000000097420104960B00023C05080087
+:102F80008CA5046C3049FFFF316AFFFF3C1108003B
+:102F90008E310468012A382124F2FFFE00B240215C
+:102FA0000012FFC30112C82B023FC02103192021C8
+:102FB0003C010800AC28046C3C010800AC24046807
+:102FC0000A00064D0000000000A4102B104000096C
+:102FD000240300010005284000A4102B04A00003D6
+:102FE000000318405440FFFC000528401060000713
+:102FF000000000000085302B14C0000200031842BE
+:10300000008520231460FFFB0005284203E0000830
+:10301000008010218F85002C27BDFFE80005302798
+:103020002CC300012CA400020083102510400003D3
+:10303000AFBF00102405007FAF85002C00052827B6
+:1030400030A5FFFF0E000574240426F58F830030A1
+:10305000240402BD004030210083382B10E0000919
+:1030600024050001000420400083102B048000038D
+:10307000000528405440FFFC0004204010A0000838
+:1030800000C350210064402B1500000200052842B7
+:103090000064182314A0FFFB0004204200C3502149
+:1030A0008FBF0010000A4C02312200FF27BD00181C
+:0C30B000AF8A002C03E00008AF8900305C
+:0430BC000A00002ADC
+:1030C00000000000000000000000000D7478703562
+:1030D0002E302E306A330000050000000000000A88
+:1030E000000001360000EA6000000000000000005F
+:1030F00000000000000000000000000000000000D0
+:1031000000000000000000000000000000000000BF
+:103110000000000000000000000000000000001699
+:10312000000000000000000000000000000000009F
+:10313000000000000000000000000000000000008F
+:10314000000000000000000000000000000000007F
+:10315000000000000000138800000000000005DCF3
+:10316000000000000000000010000003000000004C
+:103170000000000D0000000D3C02080024423B60EE
+:103180003C03080024633D14AC4000000043202BA6
+:103190001480FFFD244200043C1D080037BD7FFC65
+:1031A00003A0F0213C100800261000A83C1C0800D9
+:1031B000279C3B600E0002BA000000000000000DDA
+:1031C0008F8300383C088000350700708CE50000D4
+:1031D000008330253C02900000C22025AF850030DE
+:1031E000AF4400208F4900200520FFFE3C038000F3
+:1031F000346200708C4500008F8600303C19080056
+:103200008F39007C3C0E08008DCE007800A620236C
+:1032100003245821000078210164682B01CF60212C
+:10322000018D50213C010800AC2B007C3C010800C2
+:10323000AC2A007803E00008000000000A0000410A
+:10324000240400018F8400383C05800034A2000172
+:103250000082182503E00008AF43002003E00008C7
+:10326000000010213084FFFF30A5FFFF1080000711
+:1032700000001821308200011040000200042042AA
+:10328000006518211480FFFB0005284003E00008BA
+:103290000060102110C00007000000008CA2000098
+:1032A00024C6FFFF24A50004AC82000014C0FFFB6D
+:1032B0002484000403E000080000000010A00008BF
+:1032C00024A3FFFFAC860000000000000000000007
+:1032D0002402FFFF2463FFFF1462FFFA248400042A
+:1032E00003E0000800000000308AFFFF93A80013ED
+:1032F000A74A014497490E1630C600FF3C02100051
+:10330000A7490146AF450148A3460152A748015AC3
+:10331000AF4701608FA400188FA30014A744015881
+:10332000AF43015403E00008AF42017803E0000816
+:10333000000000003C038000346200708C490000F3
+:103340008F8800002484000727BDFFF83084FFF831
+:10335000AF890030974D008A31ACFFFFAFAC000061
+:103360008FAB0000016850232547FFFF30E61FFFA9
+:1033700000C4282B14A0FFF73C0C8000358B007094
+:103380008D6A00003C0708008CE700843C060800BA
+:103390008CC6008000081082014918230002788042
+:1033A00000E370210000202101C3C82B00C4C0210C
+:1033B00001FA4021031948212502400027BD0008D9
+:1033C0003C010800AC2E00843C010800AC290080C0
+:1033D00003E00008000000008F8200002486000740
+:1033E00030C5FFF800A2182130641FFF03E0000879
+:1033F000AF8400008F8700388F8A004027BDFFB858
+:103400008F860044AFB60040AFBF0044AFB5003C6C
+:10341000AFB40038AFB30034AFB20030AFB1002C5E
+:10342000AFB000288F4501048D4900ACAF47008044
+:103430008CC8002000A938230000B021AF480E102E
+:103440008F440E1000004821AF440E148CC200249B
+:10345000AF420E188F430E18AF430E1C10E001252B
+:103460002D230001936B0008116000D400000000C0
+:10347000976E001031CDFFFF00ED602B158000CF5F
+:103480000000000097700010320FFFFFAF4F0E00DA
+:103490008F520000325100081220FFFD0000000092
+:1034A00097540E088F460E043285FFFF30B300019B
+:1034B00012600132000000000000000D30B8A04092
+:1034C00024150040131500C030A9A0001120012DC3
+:1034D00000000000937F000813E0000800000000D7
+:1034E00097630010306BFFFF00CB402B11000003EF
+:1034F00030AC00401180012300000000A785003C93
+:10350000AF8600349366000800E02821AFA70020B2
+:1035100014C0012427B30020AF60000C9782003C48
+:103520003047400014E00002240300162403000E7C
+:1035300024194007A363000AAF790014938A003E60
+:103540008F740014315800070018AA400295902586
+:10355000AF7200149784003C8F70001430910010FB
+:1035600002117825AF6F0014978E003C31CD000812
+:1035700011A00147000028218F6700143C021000B1
+:103580003C0C810000E22825AF65001497460E0A26
+:103590002408000E3405FFFC30C3FFFF006C5825E3
+:1035A000AF6B0004A3680002937F000A27E90004C0
+:1035B000A369000A9786003C9363000A30CC1F0081
+:1035C000000C598301634021251F0028A37F0009B7
+:1035D00097490E0CA769001093790009272A000269
+:1035E000315800070018A82332B10007A371000B5F
+:1035F00093740009976400108F910034978F003CFA
+:10360000329200FF024480210205702131ED00401A
+:1036100011A0000531C4FFFF0091282B3C1280004F
+:1036200010A000140000A0210224382B14E0011B7C
+:103630008FA500208F4D0E14AF4D0E108F420E1C23
+:10364000AF420E18AF440E008F4F000031EE00085D
+:1036500011C0FFFD0000000097540E080080882173
+:1036600000009021A794003C8F500E042414000108
+:10367000AF900034976400103095FFFF8E68000013
+:103680000111F82317E00009AE7F00008F650014D8
+:103690008F8B004434A60040AF6600148F4C0E1090
+:1036A000AD6C00208F430E18AD63002493670008B3
+:1036B00014E000D2000000000E00009E2404001060
+:1036C0008F8900483C08320000402821312600FF45
+:1036D0000006FC0003E8502525390001AF99004899
+:1036E000AC4A0000937800099370000A330400FF8D
+:1036F00000047400320F00FF01CF6825AC4D0004B8
+:103700008F820048064000EAACA20008ACA0000C82
+:103710009783003C306B00081560000226280006E5
+:1037200026280002974E0E148F450E1C8F6700044A
+:10373000936D000231C4FFFF31A200FFAFA2001061
+:103740008F6C0014AFA800180E00008BAFAC0014F3
+:10375000240400100E0000C7000000008E7200005C
+:1037600016400005000000008F6400142405FFBF10
+:1037700000859824AF7300148F79000C033538212D
+:10378000AF67000C9375000816A000080000000049
+:1037900012800006000000008F7F00143C0BEFFF3A
+:1037A0003568FFFE03E84824AF690014A3740008DD
+:1037B0008FA500200A00024602202021AF470E00FC
+:1037C0000A0000F5000000008F5901780720FFFE75
+:1037D000241F08008F840000AF5F0178974B008A98
+:1037E000316AFFFF014448232528FFFF31021FFFF4
+:1037F0002C4300081460FFF9000000008F8E004881
+:103800008F8D003800C048210344202125C60001C7
+:10381000240C0F00AF86004800E9382324864000BE
+:1038200031CA00FF11AC0005240800019391003E4D
+:103830003230000700107A4035E80001000AAC0081
+:103840003C18010002B8A025AC9440008F930048BA
+:1038500030B2003630A40008ACD3000410800097CA
+:1038600001123025974E0E0A8F8D00003C02810018
+:1038700031CCFFFF25AB0008018240253C0310003E
+:1038800031651FFF25390006241F000EAF48016077
+:1038900000C33025A75F015AAF850000A759015822
+:1038A00014E0000A8F93003824120F0052720002B5
+:1038B0002416000134C600408F580E108F94004427
+:1038C000AE9800208F550E18AE9500248F450E142B
+:1038D000AF4501448F590E1CAF590148A34A01520C
+:1038E0003C0A1000AF460154AF4A017814E0FEDDF7
+:1038F0002D2300010076A025128000178FBF004401
+:103900008F84003824160F001096008400000000F9
+:103910008F45017804A0FFFE24150F001095006E5E
+:10392000000000008F470E14240202403C1F1000CC
+:10393000AF4701448F440E1CAF440148A3400152DD
+:10394000A740015AAF400160A7400158AF4201545F
+:10395000AF5F01788FBF00448FB600408FB5003C49
+:103960008FB400388FB300348FB200308FB1002C89
+:103970008FB0002803E0000827BD004814C0FED027
+:1039800030B8A0408F420E148F84004400004821BC
+:10399000AC8200208F510E1CAC9100240A00020E54
+:1039A0002D2300018F910034978A003C3C12800047
+:1039B0000220A821315800401700FF300000A0214C
+:1039C000976900108F9200343139FFFF13320035B0
+:1039D00000002021008048211480FEA000A0382192
+:1039E0008F420E148F840044AC8200208F510E1C35
+:1039F000AC9100240A00020E2D230001936A0009F5
+:103A00009378000B315000FF330F00FF020F70213D
+:103A100025C2000A3050FFFF0E00009E0200202148
+:103A20008F8600483C1F410024CD0001AF8D004827
+:103A3000936C000930C600FF00064400318300FF8C
+:103A4000246B0002010B4825013FC825AC5900003A
+:103A50008F67000C97440E1400F22825AC45000433
+:103A60008F450E1C8F670004936A00023084FFFFAD
+:103A7000315800FFAFB800108F6F0014AFB10018BD
+:103A80000E00008BAFAF00140A0001A60200202137
+:103A9000AF6000040A00013EA36000020A00024673
+:103AA00000002021000090210A0001702414000170
+:103AB0003C1280000A000195ACB2000C8F9100000E
+:103AC00025240002A744015826300008320F1FFFAA
+:103AD0000A0001F9AF8F0000AF40014C1120002C0B
+:103AE000000000008F590E10AF5901448F430E188B
+:103AF000240200403C1F1000AF430148A340015284
+:103B0000A740015AAF400160A7400158AF4201549D
+:103B1000AF5F01780A0002278FBF00441120000622
+:103B20000000000097460E0830CC004015800002CF
+:103B3000000000000000000D8F4D017805A0FFFE81
+:103B40000000000097530E103C120500240E2000C8
+:103B5000326AFFFF0152C025AF58014C8F4F0E143F
+:103B60003C021000AF4F01448F500E1CAF50014873
+:103B7000A34001528F840038A740015AAF40016032
+:103B8000A7400158AF4E01540A000215AF42017818
+:103B90008F490E14AF4901448F430E1C0A00028E58
+:103BA000240200403C0E20FF27BDFFE03C1A8000AD
+:103BB0003C0F800835CDFFFDAFBF001CAFB2001831
+:103BC000AFB10014AFB00010AF8F0040AF4D0E008A
+:103BD00000000000000000000000000000000000E5
+:103BE000000000003C0C00FF358BFFFDAF4B0E00CA
+:103BF0003C0660048CC95000240AFF7F3C11600021
+:103C0000012A40243507380CACC750008E240438F4
+:103C100024050009AF4500083083FFFF38622F718B
+:103C20002450C0B3AF8000480E000068AF80000091
+:103C300052000001AE20442C0E0004353C118000DF
+:103C40000E000EA8363000708F8A00403C1208002B
+:103C500026523BC8020088218E0800008F5F0000BA
+:103C60003BF900013338000113000017AF88003022
+:103C7000022048218D2700003C0F08008DEF006CCA
+:103C80003C0C08008D8C006800E8C02301F8282156
+:103C90000000682100B8302B018D582101664021B9
+:103CA0003C010800AC25006C3C010800AC28006811
+:103CB0008F44000038830001306200011440FFEDA2
+:103CC00000E04021AF8700308E0C00003C0508006A
+:103CD0008CA5006C3C0408008C84006801883023AB
+:103CE00000A638210000102100E6402B0082182198
+:103CF0000068F8213C010800AC27006C3C0108007A
+:103D0000AC3F00688F49010025590088AF990044F5
+:103D1000AF890038AF4900208E070000AF87003020
+:103D20008F4D017805A0FFFE000000008E06000008
+:103D30003C0B08008D6B00743C0408008C84007000
+:103D400000C728230165F8210000102103E5402B5E
+:103D50000082382100E8C821240908003C0108003D
+:103D6000AC3F00743C010800AC390070AF490178E9
+:103D700093580108A398003E938F003E31EE000156
+:103D800015C000158F830038240E0D00106E001929
+:103D9000240F0F00106F001D00000000915900005B
+:103DA00024180050332900FF113800043C1F400044
+:103DB000AF5F01380A0002E7000000000E0008EEC5
+:103DC000000000008F8A00403C1F4000AF5F0138B8
+:103DD0000A0002E700000000938D003E31AC0006AF
+:103DE000000C51000E0000CE0152D8210A000343FE
+:103DF0008F8A00403C1B0800277B3C480E0000CE09
+:103E0000000000000A0003438F8A00403C1B0800AA
+:103E1000277B3C680E0000CE000000000A00034330
+:103E20008F8A004090AA00018FAB00108CAC00106C
+:103E30003C0300FF8D680004AD6C00208CAD0014C5
+:103E400000E060213462FFFFAD6D00248CA70018F4
+:103E50003C09FF000109C024AD6700288CAE001C9E
+:103E60000182C82403197825AD6F0004AD6E002CC3
+:103E70008CAD0008314A00FFAD6D001C94A9000212
+:103E80003128FFFFAD68001090A70000A560000278
+:103E9000A1600004A167000090A30002306200FF4F
+:103EA0000002198210600005240500011065000E53
+:103EB0000000000003E00008A16A00018CD800287F
+:103EC000354A0080AD7800188CCF0014AD6F001417
+:103ED0008CCE0030AD6E00088CC4002CA16A0001AD
+:103EE00003E00008AD64000C8CCD001CAD6D001823
+:103EF0008CC90014AD6900148CC80024AD6800089A
+:103F00008CC70020AD67000C8CC200148C83006449
+:103F10000043C82B13200007000000008CC20014CF
+:103F2000144CFFE400000000354A008003E0000864
+:103F3000A16A00018C8200640A000399000000005D
+:103F400090AA000027BDFFF88FA9001CA3AA0000BB
+:103F50008FAE00003C0FFF808FA8001835E2FFFFF6
+:103F60008CCD002C01C26024AFAC0000A120000465
+:103F700000E06021A7A000028FB800008D27000498
+:103F80000188182100A0582100C05021006D28266A
+:103F90003C06FF7F3C0F00FF2CAD000135EEFFFF1C
+:103FA00034D9FFFF3C02FF0003193024000D1DC06F
+:103FB000010EC82400E2C02400C37025031978252F
+:103FC000AD2E0000AD2F00048D450024AFAE0000E3
+:103FD000AD2500088D4D00202405FFFFAD2D000C00
+:103FE000956800023107FFFFAD27001091660018A9
+:103FF00030C200FF000219C2506000018D4500343C
+:10400000AD2500148D67000827BD0008AD27001CF2
+:104010008C8B00CCAD2C0028AD20002CAD2B0024C7
+:10402000AD20001803E00008AD20002027BDFFE010
+:10403000AFB20018AFB10014AFB00010AFBF001C9A
+:104040009098000000C088213C0D00FF330F007FD6
+:10405000A0CF0000908E000135ACFFFF3C0AFF00AE
+:10406000A0CE000194A6001EA22000048CAB001478
+:104070008E29000400A08021016C2824012A4024FC
+:104080000080902101052025A6260002AE24000410
+:1040900026050020262400080E00007624060002D3
+:1040A00092470000260500282624001400071E0061
+:1040B0000003160324060004044000032403FFFF4A
+:1040C000965900023323FFFF0E000076AE23001046
+:1040D000262400248FBF001C8FB200188FB100145B
+:1040E0008FB0001024050003000030210A0000807A
+:1040F00027BD002027BDFFD8AFB1001CAFB000180E
+:10410000AFBF002090A80000240200018FB0003C47
+:104110003103003F00808821106200148FAA00380C
+:10412000240B0005506B0016AFAA001000A0202140
+:1041300000C028210E0003DC02003021922400BCC4
+:10414000308300021060000326060030ACC000007F
+:1041500024C600048FBF00208FB1001C8FB0001850
+:1041600000C0102103E0000827BD002801403821CD
+:104170000E00035AAFB000100A0004200000000037
+:104180000E0003A1AFB000140A00042000000000DC
+:104190003C02000A034218213C04080024843CAC81
+:1041A0002405001A000030210A000080AF8300546B
+:1041B0003C038000346200708C48000000A058214D
+:1041C00000C04821308A00FFAF8800308F4401785A
+:1041D0000480FFFE3C0C8000358600708CC500001A
+:1041E0003C0308008C6300743C1808008F180070B2
+:1041F00000A82023006468210000C82101A4782BB6
+:104200000319702101CF60213C010800AC2D00741E
+:104210003C010800AC2C00708F480E14AF480144DC
+:10422000AF47014CA34A0152A74B015893460108DE
+:1042300030C5000854A0000135291000934B090037
+:1042400024070050316A00FF1147000700000000FA
+:104250008F450E1CAF450148AF4901543C09100081
+:1042600003E00008AF490178934D010831A8000828
+:104270001100001000000000934F010831EE001003
+:1042800051C00001352900083C04080090843D100D
+:10429000A34401508F4309A4AF4301488F4209A0B2
+:1042A000AF420144AF4901543C09100003E000084B
+:1042B000AF4901783C1908008F393CCC33380008ED
+:1042C0005700FFF1352900080A00047300000000C0
+:1042D00024070040AF470814AF4008108F4209443C
+:1042E0008F4309508F4409548F45095C8F46094C10
+:1042F000AF820064AF830050AF84004CAF85005C98
+:1043000003E00008AF8600609346010930C5007FD6
+:10431000000518C0000521400083102103E00008BB
+:10432000244200883C0A0800914A3CD13C0908001C
+:1043300095293CCA3C051100000A3C0025280002D2
+:1043400000E8302500C5182524820008AC83000051
+:1043500003E00008AC8000048F4A002C974E090847
+:104360003C0F000E034F382131CDFFFF000D41C03F
+:10437000AF48002C9743090894EC001A00804021B4
+:1043800024020001318BFFFFAC8B00008CE9001C84
+:1043900000A0582100C06021AC8900048CE40020FA
+:1043A000AD04000890E30019306300031062004080
+:1043B000000000002865000214A00073240600021B
+:1043C0001066004E0000000024180003107800570B
+:1043D000000000003C09080095293CC093450934C1
+:1043E000934609213C0E080095CE3CC630A200FF42
+:1043F0000002C88294E5002A30C400FF9787005865
+:104400000019C60000041C00312FFFFF0303102514
+:1044100001CF6821004DC82500A720213C0640009F
+:104420000326C02500044C00AD090004AD180000AF
+:10443000934F09203C03000625090014000F760065
+:1044400001C36825AD0D00088F42092C24E5000149
+:1044500030A67FFFAD02000C8F59093025020028DD
+:10446000A7860058AD1900108F440938AD04001418
+:10447000AD2B00048F580940AD380008934F093721
+:104480003C0D080091AD3CD0AD20001031EE00FF96
+:1044900001CC182100036700000D44000188582555
+:1044A0003567FFFFAD27000C03E00008AF4A002C82
+:1044B0003C09080095293CC03C05080094A53CCA6D
+:1044C0003C0F080095EF3CBC94E400243126FFFF2C
+:1044D00000A6702101CF682300041C0025A2FFF272
+:1044E0000062C82524180800AD19000CAD1800148E
+:1044F000AD0000100A0004C82508001894E6002446
+:1045000094E500283C09080095293CC000067C0081
+:104510000005740035ED810035C40800AD0D000CB8
+:10452000AD0400100A0004C8250800143C09080066
+:1045300095293CC03C02080094423CCA3C06080055
+:1045400094C63CBC94E400243125FFFF94F8002875
+:104550000045C8210326782300181C0000046C00C5
+:1045600025EEFFEE006EC82535A281002418080054
+:10457000AD02000CAD190010AD180018AD0000140C
+:104580000A0004C82508001C1460FF920000000007
+:1045900094E300243C09080095293CC00003140062
+:1045A00034590800AD19000C0A0004C82508001091
+:1045B00003E00008240201F427BDFFE8AFB00010BB
+:1045C000AFBF00140E000060008080212405004071
+:1045D000AF4508148F8300508F84004C8F85005C9A
+:1045E000007018210064102318400004AF830050AD
+:1045F000AF6300548F660054AF86004C1200000C6D
+:10460000000000008F440074936800813409FA00B0
+:104610002D07000710E0000500891021936C008130
+:10462000240B01F4018B500401441021AF62000CF3
+:104630008F4E095C01C5682319A000048FBF0014C8
+:104640008F4F095CAF8F005C8FBF00148FB00010DC
+:104650000A00006227BD00188F8400648F83005019
+:104660008F82004CAF640044AF63005003E0000849
+:10467000AF6200543C038000346200708C43000041
+:1046800027BDFFF8308700FF30A900FF30C800FFCA
+:10469000AF8300308F4401780480FFFE3C0280002D
+:1046A000345900708F380000A3A700033C070800AE
+:1046B0008CE700748FAC00003C0608008CC60070CC
+:1046C000030378233C0E7FFF00EFC82135CDFFFFA9
+:1046D00000005021018D282400CA1821000847C07D
+:1046E000032F202B00A810250064C021AFA20000DA
+:1046F0003C010800AC3900743C010800AC38007083
+:10470000934F010AA3A000023C0E80FFA3AF00015B
+:104710008FAC0000312B007F35CDFFFF018D482489
+:10472000000B5600012A4025240730002406FF8094
+:104730003C05100027BD0008AF48014CAF470154AD
+:10474000A7400158A346015203E00008AF45017895
+:1047500027BDFFE8AFBF0014AFB000108F65007435
+:104760003C068000309000FF00A620250E0000606F
+:10477000AF64007493630005346200080E000062A9
+:10478000A3620005020020218FBF00148FB000102B
+:1047900024050005240600010A00056E27BD001847
+:1047A00027BDFFE03C038000AFB00010AFBF001892
+:1047B000AFB10014346200708C470000309000FFED
+:1047C00030A800FFAF8700308F4401780480FFFEDF
+:1047D0003C188000371100708E2F00003C0D08003F
+:1047E0008DAD00743C0A08008D4A007001E770230B
+:1047F00001AE28210000582100AE302B014B48218A
+:10480000012638213C010800AC25007400008821F5
+:104810003C010800AC2700701100000F00000000F0
+:104820008F6200742619FFFF3208007F0002FE022B
+:1048300033E5007F15000006332200FF2407FF80C8
+:104840000207202624A3FFFF00838025320200FFF9
+:1048500000408021241110080E00006000000000BC
+:104860008F4908183125000414A0FFFD3218007F7D
+:10487000001878C00018714001CF682125AC00886D
+:10488000AF4C0818274A09808D4B0020AF4B0144DC
+:104890008D460024AF460148A35001500E0000622F
+:1048A000A7400158022010218FBF00188FB10014BB
+:1048B0008FB0001003E0000827BD002027BDFFE8EF
+:1048C000308400FFAFBF00100E0005B930A500FF17
+:1048D0008F8300508FBF0010344500402404FF90A8
+:1048E0003C02100027BD0018AF43014CA344015205
+:1048F000AF45015403E00008AF4201789343093EFD
+:10490000306200081040000D3C0901013528080AFA
+:10491000AC8800008F470074AC8700043C06080098
+:1049200090C63CD030C5001050A00006AC800008F6
+:104930008F6A0060AC8A00082484000C03E0000841
+:10494000008010210A0006202484000C27BDFFE807
+:10495000AFBF0014AFB000109346093F00A0502134
+:10496000000528800085382330C200FF240300069C
+:104970003C09080095293CC624E8FFD8240500041A
+:1049800010430037240600029750093C3C0F0204F4
+:1049900000063400320EFFFF01CF6825AC8D000009
+:1049A000934C093E318B002011600008000000008C
+:1049B000934309363C020103345F0300307900FF62
+:1049C000033FC02524050008AC9800049343093434
+:1049D000935909210005F882306200FF0002C0826D
+:1049E000332F00FF00186E00000F740001AE602529
+:1049F000018920253C09400000898025ACF0FFD8C2
+:104A0000934309378F4F09488F580940306200FFA0
+:104A1000004AC821033F702101F86023000E6F0097
+:104A200001A650253185FFFF001F5880014548250C
+:104A300001683821AD0900200E00006024F0002834
+:104A4000240400040E000062A364003F0200102151
+:104A50008FBF00148FB0001003E0000827BD0018BE
+:104A60000A0006332406001227BDFFD024090010D7
+:104A7000AFB60028AFB50024AFB40020AFB100142A
+:104A8000AFB000103C010800A0293CD0AFBF002C03
+:104A9000AFB3001CAFB2001897480908309500FF6B
+:104AA0003C02000E3107FFFF000731C0AF46002C6B
+:104AB000974409089344010B30B400FF034280215E
+:104AC000308300300000B021106001070000882111
+:104AD000240C00043C010800A02C3CD0934B093E60
+:104AE000000B5600000A2E0304A0014B000000003A
+:104AF000AF400048934F010B31EE002011C000067B
+:104B0000000000009358093E00189E000013960311
+:104B10000640016B000000009344010B308300400D
+:104B2000106000038F9300508F8200502453FFFFCA
+:104B30009347093E30E6000814C000022412000327
+:104B4000000090219619002C93580934934F09378F
+:104B5000A7990058330C00FF31EE00FF024E682188
+:104B6000000D5880016C5021015140213C0108008A
+:104B7000A4283CC69205001830A900FF010918219D
+:104B80003C010800A4233CC8921100181620000321
+:104B90002467000A0000000D2467000A30F0FFFFC0
+:104BA0003C010800A4233CCA3C010800A4203CC0EE
+:104BB0003C010800A4203CBC0E00009E0200202105
+:104BC0000E00049A004020218F4B002C974A0908C0
+:104BD0003C0C000E034C38213145FFFF000549C055
+:104BE000AF49002C9743090894F1001A0040402176
+:104BF000241F00013226FFFFAC4600008CE2001C9F
+:104C0000AD0200048CE40020AD04000890E300191C
+:104C100030630003107F00D6286D000215A0011C30
+:104C2000240E0002106E010E240F0003106F00E32B
+:104C3000000000003C09080095293CC0934E09344F
+:104C4000935109213C0A0800954A3CC631CD00FF2A
+:104C500094F9002A000D188297870058322C00FF23
+:104C600000032E00000C24003126FFFF3142FFFF1D
+:104C700000A4F8250046482103E978250327702180
+:104C80003C18400001F86825000E8C00AD0D0000B6
+:104C9000AD110004934C09203C03000625110014BB
+:104CA000000C2E0000A31025AD0200088F49092C2E
+:104CB00024E40001309F7FFFAD09000C8F460930CE
+:104CC00025090028A79F0058AD0600108F59093804
+:104CD00001203021AD190014AE3300048F58094073
+:104CE000AE380008934F09373C0C0800918C3CD03B
+:104CF000AE20001031EE00FF01D26821000D2F0020
+:104D0000000C1C0000A310253447FFFFAE27000C49
+:104D1000AF4B002C934B093E317300081260000D1D
+:104D20003C0F010135E7080AAD0700288F4B0074DE
+:104D3000AD2B00043C13080092733CD03268001085
+:104D400051000003AD2000088F780060AD380008E6
+:104D50002526000C12C0003800000000935F093FB8
+:104D6000241600062407000433F900FF133600D28E
+:104D7000240800029743093C3C0C02043064FFFF06
+:104D8000008C2825ACC500009342093E3049002024
+:104D90001120000800000000934B09363C1301036A
+:104DA000366E0300316D00FF01AE8825ACD10004E2
+:104DB000240700089349093493590921314BFFFF17
+:104DC000313F00FF001FB082333800FF001656004D
+:104DD00000187C00014F982500122880026B68257E
+:104DE0003C0E400000C5502301AE8825AD51FFD8D0
+:104DF000934309378F5F09488F490940306C00FFA2
+:104E000001921021000720820044C82103E9782381
+:104E10000019C7000008B4000316402531E7FFFF62
+:104E2000010730250E000060AD46FFF82412000493
+:104E30000E000062A372003F0E0000C70200202196
+:104E40003C12080092523CD0325000031200000F76
+:104E500002A020218F82005024470001AF8700501C
+:104E6000AF6700508F6800540107302318C000025C
+:104E700000E020218F640054AF6400548F4C007414
+:104E8000258401F4AF64000C02A0202102802821B7
+:104E9000A76000680E0005B93C1410008F8D00500B
+:104EA00034550006AF4D014C8F9100488FBF002C48
+:104EB0008FB6002826230001AF8300488FB3001C63
+:104EC000A35101528FB20018AF5501548FB1001495
+:104ED000AF5401788FB500248FB400208FB000103C
+:104EE00003E0000827BD00309358093E00189E00DB
+:104EF0000013960306420051241100029344092333
+:104F0000308300021060FEFB8F8600608F820050AD
+:104F100014C2FEF8000000000E0000600000000057
+:104F20009369003F24070016312800FF1107000C89
+:104F3000240500083C0C0800918C3CD0358B000106
+:104F40003C010800A02B3CD0936A003F314300FF96
+:104F500010650065240D000A106D005E2402000C2F
+:104F60000E000062000000000A00068E0000000033
+:104F70003C09080095293CC03C04080094843CCAC4
+:104F80003C1F080097FF3CBC94F800243123FFFF2E
+:104F90000083C821033F782300186C0025EEFFF240
+:104FA00001AE6025240A0800AD0C000CAD0A001407
+:104FB000AD0000100A0006E0250800183C090800B2
+:104FC00095293CC03C1F080097FF3CCA3C190800CB
+:104FD00097393CBC94EF00243124FFFF94EE002865
+:104FE00003E4C02103196823000F2C00000E5400B5
+:104FF00025ACFFEE014C882534A281002406080070
+:10500000AD02000CAD110010AD060018AD0000148B
+:105010000A0006E02508001C8F6E00848F4D0940B1
+:1050200011A0FEB3AF8E0050240F00143C01080005
+:10503000A02F3CD00A00068D000000003C010800B3
+:10504000A0313CD0935F093E2416000133F90020C3
+:105050001720FEA8241100080A00068E241100045F
+:1050600094E5002494F100283C09080095293CC0EF
+:1050700000051400001134003444810034C30800DA
+:10508000AD04000CAD0300100A0006E02508001472
+:105090001460FEE80000000094FF00243C090800B2
+:1050A00095293CC0001FCC0037380800AD18000C13
+:1050B0000A0006E0250800100A00072E2408001246
+:1050C0008F7F004CAF7F00548F7900540A00069701
+:1050D000AF790050A362003F0E00006200000000A4
+:1050E0000A00068E00000000240200140A000807CF
+:1050F000A362003F27BDFFE8308400FFAFBF001070
+:105100000E0005B930A500FF9378007E9379007FEB
+:10511000936E00809368007A332F00FF00186600BA
+:10512000000F6C0031CB00FF018D4825000B5200B1
+:105130008FBF0010012A3825310600FF344470006B
+:1051400000E628252402FF813C03100027BD00183B
+:10515000AF45014CAF440154A342015203E00008A3
+:10516000AF43017827BDFFD8AFB20018AFB100142C
+:10517000AFB00010AFBF0020AFB3001C93420109D5
+:10518000308600FF30B000FF000618C23204000273
+:105190003071000114800005305200FF9367000554
+:1051A00030E5000810A0000D30C80010024020219A
+:1051B0000E0005A502202821240400018FBF002035
+:1051C0008FB3001C8FB200188FB100148FB0001085
+:1051D0000080102103E0000827BD002815000032E0
+:1051E0000000000093430109000028213062007F85
+:1051F000000220C00002F94003E4982126790088CB
+:10520000033B98218E7800248E6F0008130F004610
+:10521000000000008F640084241800020004FD8256
+:1052200033F900031338007C00000000936600830C
+:10523000934A0109514600043205007C10A0006029
+:10524000000000003205007C14A000530240202121
+:1052500016200006320400018E7F00248F590104BD
+:1052600017F9FFD600002021320400011080000A47
+:10527000024020218F4209408F93006410530006A2
+:10528000000000000E00066B022028218F43094019
+:10529000AF630044024020210E00060002202821B6
+:1052A0000A000840240400013C0908008D2900641C
+:1052B000252600013C010800AC26006416000012FF
+:1052C000000000008F6D00843C0E00C001AE602421
+:1052D00015800005024020210E00080E0220282122
+:1052E0000A00084024040001240500040E00056E95
+:1052F00024060001024020210E00080E0220282171
+:105300000A000840240400010E00004124040001AA
+:10531000936B007D020B50250E000062A36A007D96
+:105320000A0008838F6D00848F6600748F48010423
+:105330008E67002400064E021507FFB63126007F57
+:10534000936B008326440001308A007F114600439E
+:10535000316300FF5464FFB08F6400842645000170
+:1053600030B1007F30A200FF1226000424050001A6
+:10537000004090210A00085624110001240FFF80EC
+:10538000024F702401CF9026324200FF004090214E
+:105390000A000856241100010E00066B0220282185
+:1053A000321800301300FFAA321000820240202180
+:1053B0000E0005A5022028210A000840240400014F
+:1053C0008F6E00743C0F80002405000301CF9025F0
+:1053D000AF72007493710083240600010E00056E05
+:1053E000322400FF0E00004124040001936D007D73
+:1053F000020D60250E000062A36C007D3C0B0800CE
+:105400008D6B0054257000013C010800AC30005445
+:105410000A000840240400018F6800743C098000E1
+:105420002405000401093825AF67007493630083E5
+:10543000240600010E00056E306400FF0E000041DE
+:10544000240400019362007D020298250E00006290
+:10545000A373007D0A00084024040001324D00803F
+:1054600039AC0080546CFF6C8F6400840A0008A97A
+:105470002645000127BDFFC83C0A0008AFBF003029
+:10548000AFB5002CAFB40028AFB30024AFB20020FA
+:10549000AFB1001CAFB00018034AD8212409004066
+:1054A000AF490814AF4008108F4209448F43095098
+:1054B0008F4609548F47095C8F48094C9344010873
+:1054C0009345010BAF820064308400FF30A500FFDC
+:1054D000AF830050AF86004CAF87005C0E00082AF7
+:1054E000AF880060144001748FBF0030A76000686F
+:1054F000934D0900240B00503C15080026B53C884C
+:1055000031AC00FF3C12080026523C98118B00037E
+:10551000000000000000A821000090219351010923
+:105520008F9F005024040010322E007F000E68C0B0
+:10553000000E6140018D282124B40088AF54081862
+:105540008F4901048F4A09A43C0B000E034BC02174
+:10555000012A10233C010800AC223CAC8F430958BF
+:105560003C010800A0243CD097470908007F302365
+:105570003C010800AC263CB030E8FFFF0008C9C081
+:105580003C010800AC3F3CD4AF59002C97420908BD
+:105590009710002C8EB10000930F0018037498210F
+:1055A000A7900058AF9300440220F80931F000FFA3
+:1055B000304E000215C001A9304F000111E0015D1D
+:1055C000000000009343093E3066000814C000024A
+:1055D000241400030000A0218F5809A42413000103
+:1055E0003C010800AC383CD8934F0934935109373B
+:1055F00031EC00FF322E00FF028E6821000D288062
+:1056000000AC5021015058213C010800A42B3CC89B
+:105610003C010800A42A3CC693490934312200FF0A
+:1056200002022021249000103C010800A4303CC458
+:10563000240700068F9F00503C010800AC273CCC9B
+:105640008F88005C8F59095800008021011F282392
+:1056500004A00151033F20230480014F00A4302BFC
+:1056600010C00151000000003C010800AC253CB016
+:105670008E4200000040F8090000000030430002A4
+:10568000146000F100408821304400015480001073
+:105690008E4200043C0908008D293CB43C0AC0003D
+:1056A000012A8025AF500E008F45000030AB000866
+:1056B0001160FFFD00000000974D0E08241000014E
+:1056C000A78D003C8F4C0E04AF8C00348E4200043A
+:1056D0000040F8090000000002228825322E000256
+:1056E00015C0016F000000003C09080095293CBC72
+:1056F0003C06080094C63CC83C04080094843CBEA8
+:105700003C1808008F183CB4012658213C0F0800B3
+:105710008DEF3CD83C1F080097FF3CD20164182154
+:105720008F4D09400309C821246E0002033F282140
+:1057300001F860213C010800A42B3CCAAF8D006435
+:105740003C010800AC2C3CD83C010800A4253CC01E
+:105750000E00009E31C4FFFF8F87004800402021CB
+:105760003C010800A0273CD18E42000824E800013B
+:10577000AF8800480040F809000000008F4B002C63
+:10578000974909083C0A000E034A38213124FFFFDB
+:10579000000419C08F8A0050AF43002C97430908BA
+:1057A00094E6001A0040402130DFFFFFAC5F0000AC
+:1057B0008CF9001CAC5900048CF80020AC5800088F
+:1057C00090EF001931E30003107300FB00000000AC
+:1057D0002862000214400117240500021065010927
+:1057E000240C0003106C00BC000000003C09080001
+:1057F00095293CC0935F0934934C09213C0D080066
+:1058000095AD3CC633F900FF94E5002A0019C0822B
+:10581000318F00FF978C005800181600000F74009D
+:105820003124FFFF004E382501A4302100E6F82581
+:1058300000ACC8213C03400003E3C02500194C0024
+:10584000AD180000AD090004934F09203C0E00067E
+:1058500025090014000F6E0001AE2825AD050008D3
+:105860008F46092C2582000130477FFFAD06000CD2
+:105870008F440930A787005825060028AD04001082
+:105880008F43093800C02021AD030014AD2A000465
+:105890008F5F0940AD3F0008935909373C0E08005F
+:1058A00091CE3CD0AD200010333800FF0314782196
+:1058B000000F6700000E6C00018D282534A2FFFF49
+:1058C000AD22000CAF4B002C9347093E30EA000894
+:1058D0005140000F8E58000C3C0301013469080A46
+:1058E000AD0900288F4A0074ACCA00043C0B0800C4
+:1058F000916B3CD03168001051000003ACC000082F
+:105900008F650060ACC5000824C4000C8E58000CE4
+:105910000300F809000000003C0F080095EF3CCAA6
+:105920003C02080094423CBE01E2702125C4000202
+:105930000E0000C73084FFFF3C0608008CC63CAC5C
+:105940003C0D08008DAD3CB400CD38233C0108006F
+:10595000AC273CAC14E00006000000003C19080035
+:105960008F393CCC372C00403C010800AC2C3CCC9F
+:10597000120000858F8B00448F480E108F900044DA
+:10598000AE0800208F5F0E18AE1F00243C100800E8
+:1059900096103CC00E00006000000000240500408E
+:1059A000AF4508148F8300508F89004C0070182178
+:1059B0000069502319400004AF830050AF630054C6
+:1059C0008F670054AF87004C1200000C00000000ED
+:1059D0008F440074936D0081340EFA002DA60007E9
+:1059E00010C00005008E182193780081240201F474
+:1059F0000302780401E41821AF63000C8F4C095CAA
+:105A00008F99005C0199202318800003000000009A
+:105A10008F50095CAF90005C0E0000620000000037
+:105A20008F8B00508E4800103C010800AC2B3CD4FA
+:105A30000100F809000000003C1F08008FFF3CAC8B
+:105A400017E0FEFC240700068F4500249742090852
+:105A50008F8A00648F9400503C0F001F9787005876
+:105A60008F8300548F93004C304DFFFF35EEFF8045
+:105A700000AE4824000D31C032320010AF46002481
+:105A8000A467002CAF490024AF6A0044AF740050F3
+:105A9000AF7300545640007E8EB80004322400409C
+:105AA000548000328EB100088EAC000C0180F809E1
+:105AB000000000008FBF00308FB5002C8FB400288D
+:105AC0008FB300248FB200208FB1001C8FB000185C
+:105AD00003E0000827BD00383C09080095293CC0B8
+:105AE0003C04080094843CCA3C1F080097FF3CBC5F
+:105AF00094F800243123FFFF94EF00280083C8218D
+:105B0000033F702300182C00000F640025CDFFEE2A
+:105B1000018D302534A2810024030800AD02000C61
+:105B2000AD060010AD030018AD0000140A0009CE48
+:105B30002508001C934701098F8800380007FE00E4
+:105B400003E8C825AF5900808F5809A08F5309A4D6
+:105B5000AFB80010AF580E148FB40010AF540E1031
+:105B6000AF530E1C0A000942AF530E180220F80969
+:105B7000000000008EAC000C0180F809000000005D
+:105B80000A000A7F8FBF0030A5600020A5730022A5
+:105B90000A000A34AD7300243C010800AC203CB07C
+:105BA0000A00096E8E4200003C010800AC243CB0A3
+:105BB0000A00096E8E4200003C09080095293CC08D
+:105BC0003C1F080097FF3CCA3C19080097393CBCB1
+:105BD00094EF00243124FFFF03E4C0210319702354
+:105BE000000F640025CDFFF2018D2825AC45000C87
+:105BF00024020800AD020014AD0000100A0009CE16
+:105C00002508001894E6002494E300283C090800C5
+:105C100095293CC0000624000003FC003499810053
+:105C200037F80800AD19000CAD1800100A0009CEB5
+:105C3000250800141460FEED0000000094EF00241D
+:105C40003C09080095293CC0000F740035CD0800C0
+:105C5000AD0D000C0A0009CE250800109352010971
+:105C6000000028210E000600324400FF8FBF0030E4
+:105C70008FB5002C8FB400288FB300248FB2002082
+:105C80008FB1001C8FB0001803E0000827BD00385A
+:105C90000300F809000000000A000A7932240040DD
+:105CA0001200FF69000000008F540E148F92004410
+:105CB000AE5400208F530E1C0A000A63AE5300241A
+:105CC0008F82001C008040213C0401009047008529
+:105CD00030E3002010600009000000003C070800CD
+:105CE0008CE73CD48F83001800E320230480000855
+:105CF0009389000414E300030100202103E000085D
+:105D0000008010213C04010003E000080080102105
+:105D10001120000B006738238F8C002024090034E9
+:105D2000918B00BC316A000251400001240900300F
+:105D300000E9682B15A0FFF10100202100E93823BC
+:105D40002419FFFC00B9C02400F9782400F8702B56
+:105D500015C0FFEA01E8202130C200030002182329
+:105D600014C00012306900030000302100A9702126
+:105D700001C6682100ED602B1180FFE03C040100AA
+:105D80002D2F00010006482B0105382101E93024A0
+:105D900014C0FFDA24E4FFFC2419FFFC00B9C0247E
+:105DA0000308202103E00008008010218F8B0020D1
+:105DB00024060004916A00BC314400041480FFEC06
+:105DC00000A970210A000B2D0000302127BDFFE83B
+:105DD000AFBF00108F460100934A01093C1F080025
+:105DE0008FFF00902407FF80314F00FF31E8007FD4
+:105DF0000008614003E6C821032CC02127090120C7
+:105E0000012770243C010800A02F3D10AF4E080C64
+:105E10003C0D08008DAD00903C04008034820003EE
+:105E200001A65821016C18212465012030AA0078B0
+:105E300001424025AF48081C3C1F08008FFF00901E
+:105E40008F88004003E6C021331900070307482468
+:105E5000033A7821AF49002825E909C0952E0002B0
+:105E60003C0D08008DAD008C3C0A08008D4A009066
+:105E700031CC3FFF01A61821000C5980006B28216E
+:105E800000A72024AF44002C952200023C1F0800EC
+:105E90008FFF008C9107008530593FFF03E6782182
+:105EA0000019C1800146702101F8682131CC007FC2
+:105EB00031AB007F019A2821017A50213C03000C6C
+:105EC0003C04000E00A328210144102130E60020EC
+:105ED00027470980AF82002CAF88001CAF890024BF
+:105EE000AF85002010C00006AF8700288D0200504B
+:105EF0008CA4010C0044302318C00077000000007F
+:105F0000910C0085240DFFDF018D3824A107008549
+:105F10008F8B001C8F8900248F8700288D65004C93
+:105F2000AF850018912F000D31EE002011C0001731
+:105F30000000000024090001A3890004AF80000CC8
+:105F40008CE400248F85000C240A0008AF80000830
+:105F5000AF8000103C010800A42A3CBE3C010800B0
+:105F6000A4203CD20E000B01000030218F850024BC
+:105F70008FBF0010AF82001490A8000D27BD00183D
+:105F80000008394203E0000830E20001913F0002BE
+:105F90002418000133F900FF0019218210980039FC
+:105FA000240800021088005B8F86002C8CE50024FA
+:105FB00014A0001B8F9F002091220000240A0005DE
+:105FC0003046003F10CA0047240400018F860008B5
+:105FD000A3840004AF860010AF86000C8CE400247C
+:105FE0008F85000C240A00083C010800A42A3CBE4E
+:105FF0003C010800A4203CD20E000B010000000070
+:106000008F8500248FBF0010AF82001490A8000D70
+:1060100027BD00180008394203E0000830E2000103
+:106020008CF800088CF900248FEE00C4A3800004D3
+:106030008CE40024AF8E000C8F85000C8F86000846
+:1060400003197823240A0008AF8F00103C010800D0
+:10605000A42A3CBE3C010800A4203CD20E000B0147
+:10606000000000008F8500248FBF0010AF82001455
+:1060700090A8000D27BD00180008394203E0000871
+:1060800030E20001912300003062003F10440027FD
+:106090008F8500208CE40024148000210000000083
+:1060A0008D2E00183C187FFF8F850020370FFFFFD3
+:1060B00001CF1824AF8300088F9F00088CA80084AC
+:1060C00003E8C82B1720000203E020218CA40084E1
+:1060D0000A000BBCAF8400088CA3010C0A000B9AC9
+:1060E000AF8300188D2C00188F8600083C0D7FFFB1
+:1060F0008F89002035A3FFFF018358242404000169
+:10610000AF8B0010AD2000CCA38400040A000BC8A4
+:10611000AF86000C8CCA00140A000BBCAF8A0008C2
+:106120008CA300C80A000BFFAF8300088F84002CEB
+:106130008CAC00648C8D0014018D582B1160000410
+:10614000000000008CA200640A000BFFAF82000870
+:106150008C8200140A000BFFAF8200088F85000CB0
+:1061600027BDFFE0AFBF0018AFB1001414A00007B7
+:10617000AFB000108F8600242402000590C40000F8
+:106180003083003F106200B68F8400208F9100089A
+:1061900000A080218F8C00283C0508008CA53CB015
+:1061A0008D8B000431663FFF00C5502B5540000128
+:1061B00000C02821938D000411A0007300B0F82BBB
+:1061C0008F98002024040034930F00BC31EE0002AD
+:1061D00051C000012404003000A4C82B172000D1B6
+:1061E0000000000000A4282300B0F82B3C010800A8
+:1061F000A4243CBC17E00068020020213C030800F6
+:106200008C633CAC0083102B5440000100801821AB
+:106210008F8800243C010800AC233CB400004821D6
+:106220009104000D30830020506000018F490E184A
+:106230008F8300140123382B10E000590000000068
+:106240003C0408008C843CB400895821006B502B1E
+:10625000114000560090602B0069302300C02021BF
+:106260003C010800AC263CB412000003241FFFFCD4
+:106270001090008A32270003009FC8243C010800C8
+:10628000AC393CB43C010800A4203CD28F84000C03
+:10629000120400078F830020AF9100080200202124
+:1062A0008C7100CCAF90000C26300001AC7000CC9B
+:1062B0003C0208008C423CB48F8A0010240700186E
+:1062C0000082202301422823AF84000C10800002AA
+:1062D000AF850010240700108F86001C3C010800C9
+:1062E000A0273CD02407004090CC0085318B00C013
+:1062F000116700408F8D001414A0001500002021AC
+:10630000934A01098F420974314500FF00022602B9
+:1063100024A300013090007F3071007F1230007A9A
+:106320002407FF80A0C300833C0908008D293CCCD2
+:106330008F880024240D0002352C00083C01080041
+:10634000A02D3D113C010800AC2C3CCC24040010D5
+:10635000910E000D31C6002010C0000500801821EC
+:10636000240800013C010800AC283CB4348300013F
+:106370008FBF00188FB100148FB000100060102183
+:1063800003E0000827BD00203C010800A4203CBC1D
+:1063900013E0FF9A020020210A000C5000A02021E7
+:1063A0003C0408008C843CB40090602B1180FFAE4C
+:1063B000000000003C0F080095EF3CBC01E4702198
+:1063C00001C6682B11A000072C8200043C1F60004E
+:1063D0008FF954043338003F1700FFE524030042CF
+:1063E0002C8200041040FFA0240300420A000CAEDF
+:1063F0008FBF0018152DFFC0000000008CDF007457
+:106400003C0380002405FF8003E3C825ACD9007459
+:1064100090D80085240E000424040010330F003FA0
+:1064200001E54025A0C800858F8800243C010800B4
+:10643000A02E3D11240300019106000D30C900205B
+:1064400015200003000000003C0308008C633CB4EE
+:106450003C010800AC233CAC0A000CA50000000085
+:106460008F8700108C88008400E8282B14A000027D
+:1064700000E088218C91008424090001A389000494
+:106480008F440E18022028210E000B01022030211B
+:10649000022080210A000C36AF8200140007182366
+:1064A000306600033C010800A4263CD212200005FF
+:1064B0008F8C0020918B00BC316A000415400015C0
+:1064C00024CD00043C0F080095EF3CD201E470217C
+:1064D00000AE302B50C0FF6E8F84000C2C85000561
+:1064E00014A0FFA324030042309800031700000209
+:1064F000009818232483FFFC3C010800AC233CB423
+:106500000A000C720000000000A758240A000C9A30
+:10651000016718263C010800A42D3CD20A000D0298
+:10652000000000003C010800AC203CB40A000CADA7
+:10653000240300428F830010146000070000102124
+:106540008F880024240500059106000030C400FF58
+:10655000108500030000000003E0000800000000B8
+:10656000910A0018314900FF000939C214E0FFFA0E
+:106570008F85001C3C04080094843CBC3C0308004C
+:106580008C633CD43C1908008F393CB43C0F0800A4
+:1065900095EF3CD20064C0218CAD005403197021EA
+:1065A00001CF6021018D58231960001D00000000FB
+:1065B000910E001C8F8C002C974B0E1031CD00FFDC
+:1065C0008D850004016D30238D88000030CEFFFFE3
+:1065D000000E510000AAC821000038210107202127
+:1065E000032A182B0083C021AD990004AD98000048
+:1065F000918F000A01CF6821A18D000A8F88002C9D
+:10660000974B0E12A50B0008950A0038254900018A
+:10661000A50900389107000D34E60008A106000D19
+:1066200003E000080000000027BDFFE0938700049E
+:106630008F8F00248FAD00143C0E7FFF8F89000CDC
+:1066400035C8FFFFAFBF001CAFB0001801A8182469
+:1066500091EA000D000717C03C1FBFFF00625825DC
+:106660002D2E00018F90001837F9FFFF3C1808000D
+:106670008F183CD43C0F080095EF3CCA0179682480
+:10668000000E47803C07EFFF3C05F0FF01A81825EE
+:106690003149002034E2FFFF34ACFFFF03105823E0
+:1066A00027A500102406000225EA00020062182433
+:1066B0000080802115200002000040218F480E1C20
+:1066C000A7AA0012056000372407000030FF00FF72
+:1066D000001FCF008F8B001C00793825AFA7001456
+:1066E000916F00853C08080091083CD13C18DFFF01
+:1066F00031EE00C0370AFFFF000E182B3C1F0800C8
+:1067000097FF3CC400EA6824A3A8001100031740C7
+:1067100001A248258FB90010AFA900143C0A080057
+:10672000914A3CD3A7BF00168FA80014032CC024A5
+:106730003C0B01003C0F0FFF030B182531470003F2
+:1067400035EEFFFF010C682400071600006EF824E8
+:106750003C09700001A2C82503E95825AFB900140F
+:10676000AFAB00100E000076A3A000158F8C0024A4
+:10677000260200089186000D30C40020108000061B
+:106780008FBF001C3C05080094A53CC024B0FFFF4F
+:106790003C010800A4303CC08FB0001803E00008A2
+:1067A00027BD00208F9800140118502B5540FFC7BB
+:1067B000240700010A000D8530FF00FF93820004CA
+:1067C00027BDFFE0AFBF00181040000F0080502130
+:1067D0008F880024240B00058F8900089107000092
+:1067E0008F8400200100282130E3003F8F86002C99
+:1067F000106B000800003821AFA900100E00040E35
+:10680000AFAA0014A38000048FBF001803E00008A3
+:1068100027BD00208D1900183C0F08008DEF3CB4F7
+:106820008F9800103C027FFF8D080014345FFFFF3B
+:10683000033F682401F8702101AE602301883821EC
+:10684000AFA900100E00040EAFAA00140A000DD369
+:10685000A38000048F8700243C05080094A53CD247
+:106860003C0208008C423CCC90E6000D0005240060
+:1068700030C300201060002C004440258F85001C90
+:1068800000006021240B000190A300850000482136
+:10689000240A00013C0F800035EE00708DC7000017
+:1068A000AF8700308F5801780700FFFE3C0380005F
+:1068B000347900708F3800003C0508008CA5007406
+:1068C0003C0D08008DAD00700307782300AF382120
+:1068D0000000102100EF302B01A22021008618219A
+:1068E0003C010800AC2700743C010800AC23007098
+:1068F000AF4B01483C1908008F393CD4A7490144EB
+:10690000A74A0146AF59014C3C0B0800916B3CD1A2
+:10691000A34B0152AF4801543C081000A74C01584A
+:1069200003E00008AF4801788F4B0E1C3C0A0800BA
+:106930008D4A3CB497490E16974D0E1401456021BF
+:10694000312AFFFF0A000DF631A9FFFF8F830024D3
+:106950009064000D308200201040002900000000EB
+:106960000000482100005021000040213C07800029
+:1069700034EB00708D670000AF8700308F4C0178DA
+:106980000580FFFE3C0D800035AC00708D8B000053
+:106990003C0508008CA500743C0408008C84007041
+:1069A0000167302300A678210000102101E6C82BE2
+:1069B0000082C021031970213C010800AC2F007433
+:1069C0003C010800AC2E0070AF4901483C0D0800A6
+:1069D0008DAD3CD4A748014424090040A74A014694
+:1069E0003C081000240AFF91AF4D014CA34A01520C
+:1069F000AF490154A740015803E00008AF480178AF
+:106A00008F490E1897460E1297450E1030CAFFFF99
+:106A10000A000E2C30A8FFFF8F83002427BDFFF84B
+:106A20009064000D308200201040003A0000000009
+:106A3000240B000100004821240A00013C088000CA
+:106A4000350700708CE30000AF8300308F4C017875
+:106A50000580FFFE3C0E80003C04080090843D1041
+:106A600035C700708CEC00003C0508008CA5007454
+:106A7000A3A400033C1908008F3900708FAD0000FB
+:106A80000183302300A63821000010210322782141
+:106A900000E6C02B01F8602101AE4025AFA8000040
+:106AA0003C010800AC2700743C010800AC2C0070CD
+:106AB0009346010A3C04080090843D11A3A0000203
+:106AC000A3A600018FA300003C0580FF3099007F42
+:106AD00034A2FFFF006278240019C60001F8702577
+:106AE000240D3000AF4E014C27BD0008AF4D0154BE
+:106AF000A7400158AF4B0148A7490144A74A0146A6
+:106B00003C091000240AFF80A34A015203E0000858
+:106B1000AF4901788F4B0E1897460E1297450E100D
+:106B200030CAFFFF0A000E6030A9FFFF8F85001CEE
+:106B30002402008090A40085308300C0106200050C
+:106B40008F8600208F8800088F87000CACC800C893
+:106B5000ACC700C403E00008000000003C0A0800C5
+:106B6000254A38903C0908002529395C3C08080072
+:106B700025082D103C07080024E73A703C06080061
+:106B800024C637003C05080024A534783C040800DE
+:106B9000248430A03C030800246337983C0208009A
+:106BA0002442356C3C010800AC2A3C903C010800B2
+:106BB000AC293C8C3C010800AC283C883C01080016
+:106BC000AC273C943C010800AC263CA43C010800E6
+:106BD000AC253C9C3C010800AC243C983C010800DE
+:106BE000AC233CA83C010800AC223CA003E0000818
+:046BF00000000000A1
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-mips-09-4.6.17.fw.ihex b/firmware/bnx2/bnx2-mips-09-4.6.17.fw.ihex
deleted file mode 100644
index 7667c66..0000000
--- a/firmware/bnx2/bnx2-mips-09-4.6.17.fw.ihex
+++ /dev/null
@@ -1,5816 +0,0 @@
-:10000000080000F80800000000004AC8000000C80E
-:1000100000000000000000000000000008004AC8C6
-:100020000000003000004B90080000800800000035
-:10003000000053A800004BC0080055400000008499
-:1000400000009F68080053A80000016C00009FECAE
-:10005000080031D808000000000079080000A1580D
-:100060000000000000000000000000000800790807
-:100070000000012400011A60080004880800040040
-:10008000000013A400011B84000000000000000019
-:1000900000000000080017A40000000400012F2841
-:1000A000080000980800000000003AFC00012F2C16
-:1000B00000000000000000000000000008003AFC02
-:0800C0000000003000016A2875
-:0800C8000A00003E00000000E8
-:1000D000000000000000000D636F6D342E362E31DD
-:1000E00036000000040610020000000000000003BB
-:1000F00000000014000000320000000300000000B7
-:1001000000000000000000000000000000000000EF
-:1001100000000010000001360000EA60000000014D
-:1001200000000000000000000000000000000008C7
-:1001300000000000000000000000000000000000BF
-:1001400000000000000000000000000000000000AF
-:10015000000000000000000000000000000000009F
-:10016000000000020000000000000000000000008D
-:10017000000000000000000000000000000000007F
-:10018000000000000000000000000010000000005F
-:10019000000000000000000000000000000000005F
-:1001A000000000000000000000000000000000004F
-:1001B000000000000000000000000000000000003F
-:1001C0000000000010000003000000000000000D0F
-:1001D0000000000D3C02080024424B203C030800B4
-:1001E00024634C18AC4000000043202B1480FFFD1A
-:1001F000244200043C1D080037BD9FFC03A0F021F1
-:100200003C100800261000F83C1C0800279C4B20DE
-:100210000E000273000000000000000D27BDFFE883
-:100220003C028000AFB00010AFBF0014345001009A
-:10023000920200091040001A240300013C02080049
-:100240008C42002010400016000018210E000D7195
-:1002500000000000960300083C06080094C64BFE10
-:100260008E0400188F82002C9605000C00031C00E1
-:1002700000661825AC440000AC45000424040001CD
-:10028000AC400008AC40000CAC400010AC40001486
-:10029000AC4000180E000D98AC43001C0000182163
-:1002A0008FBF00148FB000100060102103E0000821
-:1002B00027BD001827BDFFE8AFBF00103C0280003B
-:1002C0009442010830437000240220001062000AAA
-:1002D00028642001548000128FBF001024024000C7
-:1002E00010620008240260001062000A8FBF001034
-:1002F0000A000097000010218FBF00100A0000556F
-:1003000027BD00180E000433000000000A0000960C
-:100310008FBF00100E000C81000000008FBF001086
-:100320000000102103E0000827BD00183C0208006F
-:100330008C42002027BDFFE810400028AFBF00100E
-:100340000E000D71000000003C05800094A2010821
-:1003500094A3010C8F86002C3042003E3063FFFFD7
-:100360000002140000431025ACC200008CA2010062
-:100370003C07080094E74BFE8FBF0010ACC200049E
-:1003800094A3011694A4010E3C02200000031C005B
-:100390003084FFFF00641825ACC3000800E2382554
-:1003A00094A2011094A3011224040001000214007D
-:1003B0003063FFFF00431025ACC2000C94A201146F
-:1003C00027BD00183042FFFFACC20010ACC00014C3
-:1003D000ACC000180A000D98ACC7001C8FBF0010FD
-:1003E00003E0000827BD00183C0680008CC202B85C
-:1003F0002403000104410008008028213C02080079
-:100400008C420060244200013C010800AC220060E4
-:1004100003E00008006010218C8300209482001605
-:10042000ACC302802442FFFCA4C202843C02080048
-:100430008C42005C8C84000494A3000E24420001D2
-:100440003C010800AC22005C3C021000A4C3028600
-:10045000ACC4028800001821ACC202B803E0000856
-:10046000006010213C0208008C42002027BDFFE8FC
-:100470001040002BAFBF00100E000D7100000000F7
-:100480003C05800094A2010894A3010C8F86002CE7
-:100490003042003E3063FFFF00021400004310258D
-:1004A000ACC200008CA201003C07080094E74BFEA0
-:1004B0008FBF0010ACC2000494A3011694A4010ED7
-:1004C0003C02200000031C003084FFFF006418255C
-:1004D000ACC3000800E2382594A2011094A30112D5
-:1004E00024040001000214003063FFFF00431025C4
-:1004F000ACC2000C94A2011427BD00183042FFFFCB
-:10050000ACC200108CA20118ACC2001490A2010B66
-:10051000304200FFACC200180A000D98ACC7001CA6
-:100520008FBF001003E0000827BD001827BDFFE0C3
-:10053000AFB000103C108000AFB20018AFBF001C7D
-:10054000AFB10014361201009243000B2402001ACE
-:10055000965100081462005B00002821322200013D
-:1005600010400018000000008E42000000022340EE
-:100570003C02003F3442FFFF0044102B10400004B7
-:100580003C030040964200140A00013B00832021F6
-:100590008E030100240201005462000696420014FA
-:1005A0003C028008944200043042000F0002250003
-:1005B0009642001400821025AE0200800A00016FEE
-:1005C000000000003C0208008C420020104000287F
-:1005D000000000000E000D710000000096020108EE
-:1005E0009603010C8F85002C3042003E3063FFFFE4
-:1005F0000002140000431025ACA200008E0201008E
-:100600003C06080094C64BFEACA2000496030116FB
-:100610009604010E3C02200000031C003084FFFF02
-:1006200000641825ACA3000800C230259602011012
-:100630009603011224040001000214003063FFFF3E
-:1006400000431025ACA2000C960201143042FFFFBB
-:10065000ACA200108E020118ACA200149202010B91
-:10066000304200FFACA200180E000D98ACA6001C92
-:100670003C0208008C420040244200013C0108007A
-:10068000AC2200403C0308008C630044322200028C
-:1006900032240004246300013C010800AC23004420
-:1006A000108000080002282B024020218FBF001C70
-:1006B0008FB200188FB100148FB000100A0000C86C
-:1006C00027BD00208FBF001C8FB200188FB100140F
-:1006D0008FB0001000A0102103E0000827BD00200B
-:1006E00027BDFFE03C058000AFB10014AFBF00188C
-:1006F000AFB0001034B101009223000B24020003BC
-:1007000014620043963000083202000110400016C7
-:100710003C02003F8E2300003442FFFF00032340D1
-:100720000044102B504000052402010096220014C2
-:100730003C0300400A0001A400832021546200060B
-:10074000962200143C028008944200043042000FBC
-:10075000000225009622001400821025ACA2008021
-:100760000A0001AF000000000E0000990000000028
-:100770003C0208008C420040244200013C01080079
-:10078000AC2200403C0208008C42004432030004CA
-:10079000244200013C010800AC2200441060000724
-:1007A00032020002022020218FBF00188FB10014F6
-:1007B0008FB000100A0000C827BD002010400015AF
-:1007C0008FBF00183C0480008C8301043C02602031
-:1007D000AC4300148C420004240301FE304203FFAA
-:1007E0001443000C8FBF00188C820100000219C254
-:1007F0002462FFFC2C420008104000032404000285
-:100800002462FFFD004420043C026000AC446914F3
-:100810008FBF00188FB100148FB00010000010219E
-:1008200003E0000827BD00203C0480008C83010009
-:1008300024020100506200033C0280080000000D09
-:100840003C02800894430004000010213063000F34
-:1008500000031D0003E00008AC8300803C02800818
-:10086000344200809042000003E00008AF800000A6
-:1008700003E000080000102127BDFFE83C028000D3
-:10088000AFBF0014AFB000108C430100AC43002098
-:100890008C430104AC4300A89050010B0E0001E50D
-:1008A000321000FF3C02080024424B580010188010
-:1008B0002E10001D16000005006210210E0001EA36
-:1008C000004018210A000205000000008C420000D0
-:1008D0000040F80900000000004018213C02080018
-:1008E0008C42003410600005244400013C0280006A
-:1008F0008C4301043C026020AC4300148FBF001401
-:100900008FB000103C0340003C02800027BD00185F
-:10091000AC4301383C010800AC24003403E000087B
-:100920000000000027BDFFE8AFBF0014AFB000100B
-:100930003C1080008E0201400E0001E5AE02002056
-:100940000E000399000000003C04080024840038D5
-:100950008C8200003C034000AE0301788FBF00147E
-:100960008FB000102442000127BD001803E00008EA
-:10097000AC82000027BDFFE8AFB00010AFBF00148D
-:100980003C1080008E0201800E0001E5AE020020C6
-:100990008E03018024020F00546200083C0280088C
-:1009A0008E0201883C0300E03042FFFF0043102527
-:1009B000AE0200800A00024A3C02800034420080FD
-:1009C0009042000024030050304200FF144300080E
-:1009D0003C0280000E000379000000001440000477
-:1009E0003C0280000E000967000000003C0280000D
-:1009F0003C034000AC4301B83C0208008C42003C80
-:100A00008FBF00148FB00010244200013C01080089
-:100A1000AC22003C03E0000827BD001803E00008FA
-:100A2000000010213C05800034A4010094820008DD
-:100A30003043000230420004104000030000000078
-:100A40000A0000C800000000106000052404000136
-:100A50003C0208008C4200840A00026F244200011C
-:100A60008CA301048F82000C104300080000202199
-:100A70008CA301043C0208008C420084AF83000C6C
-:100A8000244200013C010800AC22008403E000087D
-:100A90000080102127BDFFE83C036010AFBF0014A9
-:100AA000AFB000108C6550002402FF7F3C04800032
-:100AB00000A2282434A5380C24020037AC6550006D
-:100AC000AC82000824020C80AC8200243C060800A2
-:100AD00024C607A83C02080024424B582405001CE9
-:100AE00024A5FFFFAC46000004A1FFFD2442000442
-:100AF0003C020800244201EC3C010800AC224B609F
-:100B00003C020800244206183C010800AC224B6459
-:100B10003C02080024420D103C010800AC224BA00E
-:100B20003C020800244204643C0308002463095486
-:100B30003C0408002484095C3C05080024A52C948E
-:100B40003C010800AC224BC03C0208002442076074
-:100B50003C010800AC264BA83C010800AC254BB476
-:100B60003C010800AC234BBC3C010800AC244BC446
-:100B70003C010800AC224BC83C010800AC234B5C94
-:100B80003C010800AC204B683C010800AC204B6CD9
-:100B90003C010800AC204B703C010800AC204B74B9
-:100BA0003C010800AC204B783C010800AC204B7C99
-:100BB0003C010800AC204B803C010800AC244B8475
-:100BC0003C010800AC204B883C010800AC204B8C59
-:100BD0003C010800AC204B903C010800AC204B9439
-:100BE0003C010800AC204B983C010800AC264B9C13
-:100BF0003C010800AC264BA43C010800AC204BACE7
-:100C00003C010800AC254BB03C010800AC234BB8BC
-:100C10000E00055A000000003C02800034420070C3
-:100C20008C420000AF8200103C0308008C6300205F
-:100C30008F820004104300043C0580000E000D3735
-:100C4000AF8300043C05800034A900708D280000AB
-:100C50008F8400103C0708008CE700BC3C060800AD
-:100C60008CC600B8010420230000102100E43821C4
-:100C700000C2302100E4202B00C430213C010800D8
-:100C8000AC2700BC3C010800AC2600B88CB00000CA
-:100C9000320200071040FFE4AF8800108D260000EC
-:100CA0003C0508008CA500BC3C0408008C8400B8FE
-:100CB00000C8302300A628210000102100A6302BF8
-:100CC0000082202100862021320700013C0108001B
-:100CD000AC2500BC3C010800AC2400B810E00004C6
-:100CE000320200020E0001EC00000000320200029D
-:100CF00010400004320200040E0002170000000041
-:100D0000320200045040FFC53C0280000E00022B5E
-:100D1000000000000A0002D53C0280003C02900066
-:100D200034420001008220253C028000AC440020B7
-:100D30003C0380008C6200200440FFFE00000000A5
-:100D400003E00008000000003C0280003443000182
-:100D50000083202503E00008AC44002027BDFFE00D
-:100D6000AFB10014AFB0001000808821AFBF0018F1
-:100D70000E00031530B000FF8F83FFAC022020214E
-:100D80009062002502028025A07000258C7000185A
-:100D90003C0280000E000320020280241600000A9C
-:100DA0008FBF00183C0380008C6201F80440FFFEF6
-:100DB00024020002AC7101C0A06201C43C02100018
-:100DC000AC6201F88FBF00188FB100148FB0001013
-:100DD00003E0000827BD002027BDFFB8AFBF0044D7
-:100DE000AFB000403C0780008CE601048F82FFA872
-:100DF000AFA600288C450020AFA5002C8C44003CF9
-:100E0000AFA400308C430040AFA300348C42004CB0
-:100E1000AFA60010AFA50014AFA20020AFA200380B
-:100E20003C0208008C420020AFA40018AFA3001CB5
-:100E30008CF00100104000198FBF00440E000D71AE
-:100E4000000000008F83002C3C05080094A54BFE99
-:100E50003C024018AC70000000A228258FA20010B0
-:100E600024040001AC6200048FA20014AC620008EC
-:100E70008FA20018AC62000C8FA2001CAC620010A4
-:100E80008FA20020AC6200148FA20024AC62001874
-:100E90000E000D98AC65001C8FBF00448FB0004061
-:100EA0000000102103E0000827BD004827BDFFE82F
-:100EB000AFBF00103C038000946201843042020006
-:100EC00010400005000020210E000FE3000000008C
-:100ED0000A00038F240400018C6201880440000A88
-:100EE0008FBF00108C6201883C03FF000043102478
-:100EF0003C03040014430004240400018F82FFAC6F
-:100F0000904200088FBF00100080102103E000080D
-:100F100027BD00188F82FFB024050001A040001AF1
-:100F20003C0280000A0003258C44014027BDFFE0FD
-:100F3000AFB100148F91FFACAFBF001CAFB200186F
-:100F4000AFB000109222000024030020304200FFC6
-:100F50001043000C3C028000922200002403003069
-:100F6000304200FF104300073C0280009222000044
-:100F700024030050304200FF144300818FBF001C47
-:100F80003C02800090420148304200FF2443FFFFB2
-:100F90002C6200051040007A8FBF001C00031080F7
-:100FA0003C03080024634AD8004310218C4200000F
-:100FB00000400008000000003C1180008E24014029
-:100FC0000E0003158F92FFAC8E50000C8E22014450
-:100FD0001602000224020001AE42000C0E000320A3
-:100FE0008E2401408E220144145000068FBF001C45
-:100FF0008FB200188FB100148FB000100A000F518B
-:1010000027BD00208E42000C0A00042700000000CB
-:10101000962200103C0480008C8301443042FFFF84
-:10102000146200090000000024020001A622001042
-:101030008C820140AC8202003C021000AC8202387B
-:101040000A00042E8FBF001C962200100A000427FD
-:10105000000000009222000024030020304200FF24
-:101060001443000B3C128000962200123C038000C7
-:101070008C6301443042FFFF14620018000000003E
-:1010800024020001A62200120A0004008FBF001CE7
-:101090008E4401400E00031500000000962200124D
-:1010A0008E4301443050FFFF16030002240200016A
-:1010B000A62200120E0003208E4401408E420144FD
-:1010C000160200068FBF001C8FB200188FB10014EB
-:1010D0008FB000100A00039327BD00209622001253
-:1010E0000A00042700000000962200143C03800040
-:1010F0008C6301443042FFFF1462000900000000CD
-:1011000024020001A62200148FBF001C8FB2001819
-:101110008FB100148FB000100A00126827BD0020A4
-:10112000962200140A0004270000000096220016F0
-:101130003C0380008C6301443042FFFF14620008CE
-:1011400024020001A62200168FBF001C8FB20018D7
-:101150008FB100148FB000100A000B0B27BD0020C8
-:1011600096220016144000068FBF001C3C020800A7
-:101170008C420070244200013C010800AC22007047
-:101180008FB200188FB100148FB0001003E0000878
-:1011900027BD002027BDFFE03C028000AFB1001456
-:1011A000AFBF001CAFB20018AFB000103451010047
-:1011B000922300098C5001002402001F106200AA33
-:1011C0002862002010400018240200382862000A1B
-:1011D0001040000C2402000B286200081040002C74
-:1011E0000000000004600100286200021440002892
-:1011F00024020006106200268FBF001C0A00054A68
-:101200008FB20018106200602862000B144000F7D3
-:101210008FBF001C2402000E106200778FB20018EE
-:101220000A00054A00000000106200D3286200395D
-:101230001040000A2402008024020036106200E3FD
-:1012400028620037104000C524020035106200D823
-:101250008FBF001C0A00054A8FB200181062002DD3
-:101260002862008110400006240200C824020039D0
-:10127000106200C98FBF001C0A00054A8FB2001817
-:10128000106200A28FBF001C0A00054A8FB200182E
-:101290003C0208008C420020104000D48FBF001C8C
-:1012A0000E000D71000000003C028000344201007D
-:1012B0008C4400008F83002C944700083C050800F4
-:1012C00094A54BFEAC6400008C44000400073C0075
-:1012D00000E53825AC6400048C4400189446000CEA
-:1012E000AC6400088C45001C000634002404000196
-:1012F000AC65000C9042000A00C23025AC660010BC
-:10130000AC600014AC600018AC67001C0A00050C4F
-:101310008FBF001C3C0208008C420020104000B32C
-:101320008FBF001C0E000D71000000009624000805
-:101330003C03080094634BFE9625000C0004220237
-:101340009626000E8F82002C0004260000832025A4
-:1013500000052C003C03008000A6282500832025E2
-:10136000AC400000AC400004AC400008AC40000CB5
-:10137000AC450010AC400014AC400018AC44001C5C
-:101380000A00050B240400019622000C14400017EB
-:101390008F91FFAC922200053042001014400013E0
-:1013A000000000000E00031502002021922200051B
-:1013B00002002021344200100E000320A22200056A
-:1013C0009222000024030020304200FF10430086D8
-:1013D000020020218FBF001C8FB200188FB10014B3
-:1013E0008FB000100A00104C27BD00200000000D37
-:1013F0000A0005498FBF001C3C0208008C420020F7
-:101400001040007A8FBF001C0E000D71000000001C
-:101410008E2200048F83002C9624000C3C050800CB
-:1014200094A54BFEAC6200003C0280089442002C64
-:10143000000424003042FFFF008220253C02400EC1
-:1014400000A22825AC640004AC600008AC60000C6D
-:10145000AC600010AC600014AC600018AC65001CFF
-:101460000A00050B240400010E00031502002021D0
-:101470008F92FFB0020020210E000320A640000C36
-:10148000020020210E000325240500013C02080073
-:101490008C420020104000558FBF001C0E000D71C3
-:1014A000000000009622000C8F83002C8F84FFAC7C
-:1014B00000021400AC700000AC620004AC600008D4
-:1014C0008C8200383C05080094A54BFEAC62000CF1
-:1014D0008C86003C3C02401F00A22825AC66001010
-:1014E0008E42000424040001AC620014AC600018B9
-:1014F000AC65001C8FBF001C8FB200188FB10014A8
-:101500008FB000100A000D9827BD00208F82FFAC1D
-:101510002403002090420000304200FF10430033BB
-:101520008FBF001C0E000F37000000001040002F7E
-:101530008FBF001C3C0380008C6201F80440FFFE5A
-:1015400024020002AC7001C0A06201C43C02100081
-:10155000AC6201F80A0005498FBF001C020020217F
-:101560008FBF001C8FB200188FB100148FB0001015
-:101570000A000E8027BD00209625000C02002021C5
-:101580008FBF001C8FB200188FB100148FB00010F5
-:101590000A000EA527BD0020020020218FB20018EE
-:1015A0008FB100148FB000100A000ED027BD0020AC
-:1015B0009225000D020020218FB200188FB1001477
-:1015C0008FB000100A000F2127BD0020020020214B
-:1015D0008FBF001C8FB200188FB100148FB00010A5
-:1015E0000A000EF827BD00208FBF001C8FB2001824
-:1015F0008FB100148FB0001003E0000827BD002059
-:101600003C0380008C6202780440FFFE240200024A
-:10161000AC640240A06202443C02100003E00008F7
-:10162000AC620278000411C003E0000824420240CA
-:10163000A380001803E00008A38000193C03800089
-:101640008C6202780440FFFE8F82001CAC62024074
-:1016500024020002A06202443C02100003E00008E1
-:10166000AC62027803E000080000000090830030C4
-:1016700024020005008040213063003F0000482123
-:1016800014620005000050219082004C9483004EAB
-:10169000304900FF306AFFFFAD00000CAD000010C4
-:1016A000AD000024950200148D05001C8D04001867
-:1016B0003042FFFF0049102300021100000237C32F
-:1016C000004038210086202300A2102B0082202316
-:1016D00000A72823AD05001CAD040018A5090014BF
-:1016E000A5090020A50A001603E00008A50A0022AB
-:1016F00003E000080000000027BDFFD8AFB20018CB
-:101700003C128008AFB40020AFB3001CAFB100148E
-:10171000AFBF0024AFB00010365101009222000C80
-:101720003C140800929400F7304300FF24020001AB
-:1017300010620031008098212402000214620034FB
-:10174000365000800E001242000000009204004C4F
-:101750000E0005573084007F026210212403FF80B1
-:10176000004318243C048000AC8300949245000898
-:101770009204004C3042007F3C0380061485000731
-:10178000004380212402FFFFA22200112402FFFF58
-:10179000A62200120A0005BA2402FFFF96020020CA
-:1017A000A222001196020022A62200128E0200241C
-:1017B0003C048008AE2200143485008090A2004CC6
-:1017C00034830100A06200108CA2003CAC620018BF
-:1017D0008C820068AC6200E48C820064AC6200E041
-:1017E0008C82006CAC6200E824020001A0A20068B8
-:1017F0000A0005D63C0480080E00125B00000000C1
-:1018000036420080A04000680A0005D63C048008EB
-:10181000A2000068A20000690A0006123C028008CB
-:10182000348300808C62003834850100AC62006C27
-:1018300024020001A062006990A200C59083000804
-:10184000305100FF3072007F1232001B3C088008CC
-:101850000E00055702202021026210212403FF8080
-:10186000004318243C048000AC8300943042007F85
-:101870003C038006004380218E02000C1040000DC6
-:10188000020020210E000569000000002622000150
-:10189000305100FF9203003C023410260002102B4E
-:1018A000000210233063007F022288240A0005E032
-:1018B000A203003C3C088008350401008C8200D063
-:1018C00035070080ACE2003C8C8200D0AD02000005
-:1018D00090E5004C908600C590E3004C908400C5D4
-:1018E0002402FF8000A228243063007F308400FFA0
-:1018F00000A628250064182A1060000230A500FF09
-:1019000038A50080A0E5004CA10500093C02800834
-:101910009043000E344400803C058000A043000A40
-:101920008C8300183C027FFF3442FFFF00621824C2
-:10193000AC8300188CA201F80440FFFE00000000F8
-:10194000ACB301C08FBF00248FB400208FB3001C44
-:101950008FB200188FB100148FB000102402000263
-:10196000A0A201C427BD00283C02100003E000082B
-:10197000ACA201F890A2000027BDFFE0AFB20018B2
-:1019800024420001A0A200003C0308008C6300F484
-:10199000304200FFAFB10014AFBF001CAFB0001069
-:1019A00000A088211443000200809021A0A0000024
-:1019B0000E000557922400008F90001C2403FF8026
-:1019C00002021021004310243C038000AC6200247A
-:1019D0000E00055792240000020280213210007F81
-:1019E0003C02800A02028021AE5000008FBF001C22
-:1019F0008FB200188FB100148FB0001003E0000800
-:101A000027BD002094820006908300058C85000C81
-:101A10008C8600108C8700188C88001C8C84002019
-:101A20003C010800A4224BD23C010800A0234BD16A
-:101A30003C010800AC254BD83C010800AC264BDC2F
-:101A40003C010800AC274BE43C010800AC284BE803
-:101A50003C010800AC244BEC03E00008000000004F
-:101A60003C028008344201008C4400343C03800076
-:101A700034650400AC6400388C420038AF85003017
-:101A8000AC62003C3C020005AC620030000000008B
-:101A90000000000003E00008000000003C02000617
-:101AA000308400FF008220253C028000AC440030DE
-:101AB0000000000000000000000000003C03800067
-:101AC0008C620000304200101040FFFD34620400C0
-:101AD00003E00008AF82003094C200003C08080018
-:101AE000950800CA30E7FFFF00804821010210215D
-:101AF000A4C2000094C200003042FFFF00E2102B9D
-:101B000054400001A4C7000094A200003C03080058
-:101B10008C6300CC24420001A4A2000094A2000027
-:101B20003042FFFF144300073C0280080107102BDE
-:101B3000A4A000005440000101003821A4C7000007
-:101B40003C028008344601008CC3002894A20000A7
-:101B50003C0480003042FFFE000210C000621021F1
-:101B6000AC82003C8C82003C0062182318600004A8
-:101B7000000000008CC200240A0006AF24420001CD
-:101B80008CC20024AC8200383C0200503442001069
-:101B90003C038000AC620030000000000000000048
-:101BA000000000008C620000304200201040FFFD69
-:101BB0000000000094A200003C04800030420001BC
-:101BC000000210C0004410218C430400AD2300002B
-:101BD0008C420404AD2200043C02002003E0000813
-:101BE000AC82003027BDFFE0AFB20018AFB10014E7
-:101BF000AFB00010AFBF001C94C2000000C0802135
-:101C00003C120800965200C624420001A6020000C1
-:101C10009603000094E2000000E030211443000528
-:101C20008FB100300E000684024038210A0006E61B
-:101C3000000000008C8300048C82000424420040D9
-:101C400004610007AC8200048C820004044000049C
-:101C5000000000008C82000024420001AC820000E1
-:101C6000960200003042FFFF50520001A600000023
-:101C70009622000024420001A62200003C028008B7
-:101C800034420100962300009442003C14430004B7
-:101C90008FBF001C24020001A62200008FBF001C81
-:101CA0008FB200188FB100148FB0001003E000084D
-:101CB00027BD002027BDFFE03C028008AFBF001811
-:101CC000344201008C4800343C0380003469040035
-:101CD000AC6800388C42003830E700FFAF89003034
-:101CE000AC62003C3C020005AC6200300000000029
-:101CF00000000000000000000000000000000000E4
-:101D0000000000008C82000C8C82000C978300166F
-:101D1000AD2200008C82001000604021AD22000442
-:101D20008C820018AD2200088C82001CAD22000CB1
-:101D30008CA20014AD2200108C820020AD22001471
-:101D400090820005304200FF00021200AD22001810
-:101D50008CA20018AD22001C8CA2000CAD22002029
-:101D60008CA20010AD2200248CA2001CAD22002801
-:101D70008CA20020AD22002C3402FFFFAD260030E3
-:101D8000AD200034506200013408FFFFAD28003858
-:101D900050E000113C0280083C04800834840100BB
-:101DA000948200503042FFFFAD22003C94830044F7
-:101DB00094850044240200013063FFFF000318C231
-:101DC000006418219064005430A5000700A210049C
-:101DD0000A0007510044102534420100AD20003CA8
-:101DE00094430044944400443063FFFF000318C24E
-:101DF000006218213084000790650054240200011D
-:101E0000008210040002102700451024A062005434
-:101E10000000000000000000000000003C0200067E
-:101E2000344200403C038000AC62003000000000FF
-:101E300000000000000000008C6200003042001032
-:101E40001040FFFD3C06800834C20150346304009A
-:101E500034C7014A34C4013434C5014034C6014496
-:101E6000AFA200100E0006C7AF8300308FBF00186E
-:101E700003E0000827BD00208F8300143C05080004
-:101E80008CA500E88F82001C30633FFF000319809F
-:101E900000451021004310212403FF800043182433
-:101EA0003C058000ACA300283042007F3C03800C3E
-:101EB0000043302190C2000D000038213442001050
-:101EC000A0C2000D8F8900143C028008344201003A
-:101ED00094430044000913823048000324020001A7
-:101EE000A4C3000E1102000B2902000210400005DD
-:101EF000240200021100000C240300010A000798CC
-:101F00000000182111020006000000000A000798D6
-:101F1000000018218CC2002C0A00079824430001FD
-:101F20008CC20014244300018CC200180043102B03
-:101F3000144000033C0380080A0007A224070001A4
-:101F4000346301009462004C24420001A462004CFE
-:101F500000091382304300032C6200021040000984
-:101F600000802821146000040000000094C20034A6
-:101F70000A0007B23046FFFF8CC600380A0007B2DD
-:101F800000802821000030213C04080024844BCC30
-:101F90000A0006FB0000000027BDFF90AFB60068F6
-:101FA000AFB50064AFB40060AFB3005CAFB200582F
-:101FB000AFB10054AFBF006CAFB000508C900000C8
-:101FC0000080B0213C0208008C4200E896040032F8
-:101FD0008F83001C2414FF8030843FFF006218218F
-:101FE0000004218000641821007410243C13800038
-:101FF00000A0902190A50000AE620028920400325B
-:102000003C02800C3063007F00628821308400C075
-:10201000240200401482002D0000A8218E350038D3
-:102020008E2200181440000224020001AE22001883
-:102030009202003C304200201440000F00000000DB
-:102040000E00055700A020218F83001C006218217C
-:10205000306400783C02008000822025007418243F
-:10206000AE630800AE6408108E2200188E030008CC
-:1020700000431021AE2200188E22002C8E2300185F
-:10208000244200010062182B1060003D0000000097
-:102090009242000024420001A24200003C030800DA
-:1020A0008C6300F4304200FF50430001A240000066
-:1020B0000E000557924400008F90001C0202102170
-:1020C000005410240A0008B8AE62002492030032C3
-:1020D0002402FFC000431024304200FF14400005DA
-:1020E00024020001AE220018962200340A00082EB5
-:1020F0003055FFFF8E22001424420001AE2200184A
-:102100009202003000021600000216030441001C77
-:10211000000000009602003227A400100080282151
-:10212000A7A2001696020032000030212407000109
-:102130003042FFFFAF8200140E0006FBAFA0001C70
-:10214000960200328F83001C3C0408008C8400E857
-:1021500030423FFF00021180006418210062182104
-:1021600000741024AE62002C3063007F3C02800EAD
-:10217000006218219062000D3042007FA062000DC5
-:102180009222000D30420010504000789242000030
-:102190003C028008344401009482004C8EC300004D
-:1021A0003C130800967300C62442FFFFA482004C33
-:1021B000946200329623000E3054FFFF3070FFFF10
-:1021C0003C0308008C6300D000701807A7A30038F8
-:1021D0009482003E3063FFFF3042FFFF146200072D
-:1021E000000000008C8200303C038000244200305C
-:1021F000AC62003C0A0008568C82002C948200409D
-:102200003042FFFF5462000927A400408C8200384E
-:102210003C03800024420030AC62003C8C820034DD
-:10222000AC6200380A0008653C03800027A500382E
-:1022300027A60048026038210E000684A7A00048A7
-:102240008FA300403C02800024630030AC43003880
-:102250008FA30044AC43003C3C0380003C020005DB
-:10226000AC6200303C028008344401009482004299
-:10227000346304003042FFFF0202102B14400007B9
-:10228000AF8300309482004E9483004202021021FA
-:10229000004310230A00087B3043FFFF9483004E65
-:1022A0009482004202631821005010230062182318
-:1022B0003063FFFF3C028008344401009482003CFC
-:1022C0003042FFFF14430003000000000A00088BA7
-:1022D000240300019482003C3042FFFF0062102B77
-:1022E000144000058F8200309482003C006210236D
-:1022F0003043FFFF8F820030AC550000AC4000043B
-:10230000AC540008AC43000C3C0200063442001000
-:102310003C038000AC6200300000000000000000C0
-:10232000000000008C620000304200101040FFFDF1
-:102330003C04800834840100001018C20064182195
-:102340009065005432020007240600010046100484
-:1023500000451025A0620054948300429622000E8E
-:1023600050430001A386001892420000244200015D
-:10237000A24200003C0308008C6300F4304200FFDE
-:1023800050430001A24000000E0005579244000097
-:102390008F90001C2403FF800202102100431024B0
-:1023A0003C038000AC6200240E00055792440000FC
-:1023B000020280213210007F3C02800A020280214A
-:1023C000AED000008FBF006C8FB600688FB5006480
-:1023D0008FB400608FB3005C8FB200588FB100548F
-:1023E0008FB0005003E0000827BD007027BDFFD864
-:1023F000AFB3001CAFB20018AFB10014AFB0001003
-:10240000AFBF00200080982100E0802130B1FFFFA5
-:102410000E000D7130D200FF00000000000000002F
-:10242000000000008F82002CAC510000AC52000470
-:10243000AC530008AC40000CAC400010AC400014A1
-:10244000AC4000183C03080094634BFE0203802557
-:10245000AC50001C00000000000000000000000064
-:10246000240400018FBF00208FB3001C8FB200181E
-:102470008FB100148FB000100A000D9827BD0028FE
-:1024800030A5FFFF30C600FF24030C803C02800013
-:10249000AC43002400000000000000000000000029
-:1024A00000000000000000000A0008C90000000051
-:1024B0003C028008344301009462000E3C0808008E
-:1024C000950800C63046FFFF14C000043402FFFF29
-:1024D000946500DA0A00091F8F84001C10C20027CF
-:1024E000000000009462004E9464003C3045FFFF01
-:1024F00000A6102300A6182B3087FFFF10600004F1
-:102500003044FFFF00C5102300E210233044FFFFDA
-:102510000088102B1040000E00E810233C028008B9
-:10252000344401002403000134420080A443001617
-:102530002402FFFFA482000E948500DA8F84001C21
-:102540000000302130A5FFFF0A0008EE3C076020A4
-:102550000044102A104000093C02800834430080E7
-:102560009462001630420001104000043C028000DA
-:102570009442007E24420014A462001603E0000886
-:102580000000000027BDFFE03C028008AFBF001C38
-:10259000AFB0001834420100944300429442004C12
-:1025A000104000193068FFFF9383001824020001D7
-:1025B000146200298FBF001C3C06800834D0010043
-:1025C000000810C20050102190420054310300074F
-:1025D00034C70148304200FF00621007304200015A
-:1025E00034C9014E34C4012C34C5013E10400016DC
-:1025F00034C601420E0006C7AFA900109602004281
-:102600000A00093C3048FFFF3C02800834440100C6
-:1026100094830044948200421043000F8FBF001C3B
-:1026200094820044A482004294820050A482004E0E
-:102630008C820038AC82003094820040A482003E3C
-:102640009482004AA48200488FBF001C8FB00018FB
-:102650000A0008FA27BD00208FB0001803E0000828
-:1026600027BD002027BDFFA0AFB1004C3C1180006A
-:10267000AFBF0058AFB30054AFB20050AFB0004886
-:102680003626018890C200033044007FA3A40010C6
-:102690008E32018090C200003043007F240200038C
-:1026A0001062003BAF92001C28620004104000063C
-:1026B0002402000424020002106200098FBF0058A7
-:1026C0000A000B038FB300541062004B2402000574
-:1026D0001062014C8FBF00580A000B038FB30054E7
-:1026E000000411C0024210212404FF802442024051
-:1026F0000044102426430040AE2200243063007FB3
-:102700003C02800A006218219062003CAFA3003CAA
-:1027100000441025A062003C8FA3003C9062003C66
-:10272000304200401040016A8FBF00583C108008C2
-:10273000A3800018361001008E0200D08C63003494
-:1027400027A4003C27A50010004310210E0007B469
-:10275000AE0200D093A200103C038000A20200C58C
-:102760008C6202780440FFFE8F82001CAC62024043
-:1027700024020002A06202443C021000AC62027813
-:102780000E00092F000000000A000B028FBF005846
-:102790003C05800890C3000190A2000B1443014C3B
-:1027A0008FBF005834A400808C8200189082004CA7
-:1027B00090A200088C8300183C027FFF3442FFFF88
-:1027C000006218243C0208008C4200B4AC8300185C
-:1027D0003C038000244200013C010800AC2200B40C
-:1027E0008C6201F80440FFFE8F82001CAC6201C0C5
-:1027F0000A000ACA240200023C10800890C30001AB
-:102800009202000B144301328FBF005836050110AD
-:1028100027A400180E000E202406000327A4002879
-:10282000360501E00E000E20240600038FA20028CA
-:1028300036030100AE0200648FA2002CAE020068D5
-:102840008FA20030AE02006C93A40018906300C504
-:102850002402FF800082102400431025305000FF26
-:102860003084007F3202007F0082102A5440000131
-:102870003A1000800E0005570000000002421021AF
-:102880002403FF8000431024AE22009493A4001878
-:102890003C130800927300F70E0005573084007F48
-:1028A000024210213042007F3C0380060043402159
-:1028B0008FA3001C2402FFFF10620034AFA8004069
-:1028C00093A2001995030014304400FF3063FFFF0A
-:1028D0000064182B10600010000000009504001424
-:1028E0008D07001C8D0600183084FFFF0044202354
-:1028F0000004210000E438210000102100E4202B16
-:1029000000C2302100C43021AD07001CAD06001804
-:102910000A000A2393A20019950400148D07001CD5
-:102920008D0600183084FFFF008220230004210060
-:10293000000010210080182100C2302300E4202B69
-:1029400000C4302300E33823AD07001CAD06001897
-:1029500093A200198FA30040A462001497A2001A4A
-:10296000A46200168FA2001CAC6200108FA2001C93
-:10297000AC62000C93A20019A462002097A2001A76
-:10298000A46200228FA2001CAC6200243C048008D8
-:10299000348300808C6200388FA2002002008821DE
-:1029A000AC62003C8FA20020AC82000093A2001811
-:1029B000A062004C93A20018A0820009A0600068E9
-:1029C00093A200181051005293A400183230007FD7
-:1029D0000E00055702002021024210212407FF802B
-:1029E0003046007F3C03800000471024AC62009416
-:1029F0003C02800600C2302190C2003CAFA60040DD
-:102A00000000202100471025A0C2003C8FA80040F4
-:102A100095020002950300148D07001C3042FFFF51
-:102A20003063FFFF8D0600180043102300021100E1
-:102A300000E2382100E2102B00C4302100C2302116
-:102A4000AD07001CAD06001895020002A502001497
-:102A5000A50000168D020008AD0200108D020008CE
-:102A6000AD02000C95020002A5020020A500002284
-:102A70008D020008AD0200249102003C304200406B
-:102A80001040001A26220001A3B000383C10800834
-:102A9000A3800018361001008E0200D08D03003490
-:102AA00027A4004027A50038004310210E0007B4DA
-:102AB000AE0200D093A200383C038000A20200C501
-:102AC0008C6202780440FFFE8F82001CAC620240E0
-:102AD00024020002A06202443C021000AC620278B0
-:102AE0000E00092F00000000262200013043007F65
-:102AF00014730004004020212403FF8002231024CB
-:102B00000043202693A200180A000A3F309100FFDC
-:102B10008FA3001C2402FFFF1062000A309000FF08
-:102B200024820001248300013042007F14530005F9
-:102B3000307000FF2403FF80008310240043102620
-:102B4000305000FF3C0280089042000802008821BB
-:102B5000305000FF123000193222007F000211C0F5
-:102B600002421021244202402403FF800043182423
-:102B70003C048000AC8300943042007F3C0380061C
-:102B8000004310218C43000C004020211060000BFA
-:102B9000AFA200400E0005690000000026230001DE
-:102BA0002405FF803062007F145300020225202498
-:102BB000008518260A000AA3307100FF3C04800833
-:102BC000348400808C8300183C027FFF3442FFFF76
-:102BD00000621824AC8300183C0380008C6201F86A
-:102BE0000440FFFE00000000AC7201C0240200029D
-:102BF000A06201C43C021000AC6201F80A000B02A2
-:102C00008FBF00583C04800890C300019082000BE5
-:102C10001443002F8FBF00583490008092020008A8
-:102C200030420040104000200000000092020008E6
-:102C30000002160000021603044100050240202194
-:102C40000E000EA5240500930A000B028FBF00584A
-:102C50009202000924030018304200FF1443000DC3
-:102C600002402021240500390E000E3D00003021D5
-:102C70000E0003158F84001C8F82FFAC240300120A
-:102C8000A04300090E0003208F84001C0A000B02E1
-:102C90008FBF0058240500360E000E3D0000302185
-:102CA0000A000B028FBF00580E00031502402021BE
-:102CB000920200058F84001C344200200E00032085
-:102CC000A20200050E00104C8F84001C8FBF00581C
-:102CD0008FB300548FB200508FB1004C8FB00048BA
-:102CE00024030C803C02800027BD006003E0000844
-:102CF000AC43002427BDFFE83C028008AFB00010C1
-:102D0000AFBF0014344501003C1080008E0201402A
-:102D100094A3000E0000302100402021AF82001C4F
-:102D20003063FFFF3402FFFF106200063C076020A3
-:102D30002402FFFFA4A2000E94A500DA0E0008EE04
-:102D400030A5FFFF24020C80AE0200248FBF0014C8
-:102D50008FB0001003E0000827BD001827BDFFC09A
-:102D60003C0980003C058008AFB70034AFB20020BA
-:102D7000AFBF0038AFB60030AFB5002CAFB40028FD
-:102D8000AFB30024AFB1001CAFB000183532010062
-:102D900034A801008D2701008E4200148D0300D459
-:102DA0000000B821A38000180043102318400055EC
-:102DB000AF87001C8E4200142403FF8024E40040EF
-:102DC000AD0200D490A60008910500C53084007FB4
-:102DD00030D3007F30A200FF000211C000E21021BA
-:102DE00024420240A3A50010004310248D1400D0FB
-:102DF0008D1500D4AD22002493A300103C02800A5C
-:102E000000822021AFA40014107300330000B02111
-:102E10008FA3001427A4001427A500108C6200348F
-:102E20000282802102B010230440002B2411FF8075
-:102E30009062003C02221024304200FF1440001B2C
-:102E40000200A0219062003C34420040A062003C9D
-:102E500093A2001024420001304300FFA3A20010FF
-:102E60003C0208008C4200F450620001A3A0001054
-:102E70000E00055793A400108F90001C3C038000A7
-:102E80000202102100511024AC6200240E000557EC
-:102E900093A40010020280213210007F3C02800ABD
-:102EA000020280210A000B81AFB000140E0007B4AB
-:102EB000000000003C02800834420100AC5000D009
-:102EC00093A3001024160001A04300C593A2001094
-:102ED0001453FFD08FA300142402000116C200096E
-:102EE0003C0380008C6202780440FFFE8F82001C4D
-:102EF000AC62024024020002A06202443C021000C4
-:102F0000AC6202789242000B24030002304200FFC0
-:102F1000144300720000000096420008304300FF96
-:102F20002402008214620040240200843C028000DB
-:102F3000344901008D22000C952300060002160280
-:102F40003063FFFF3044003F240200271082000F4F
-:102F5000AF830014288200281040000824020031AA
-:102F6000240200211082000924020025108200079B
-:102F7000938200190A000BC00000000010820007B5
-:102F8000938200190A000BC0000000000E00076CBD
-:102F9000012020210A000C40000000003C038000BA
-:102FA0008C6202780440FFFE8F82001CAC620240FB
-:102FB00024020002A06202443C021000AC620278CB
-:102FC0000A000C4000000000952300069124000533
-:102FD0008D25000C8D2600108D2700188D28001CD3
-:102FE0008D290020244200013C010800A4234BD27B
-:102FF0003C010800A0244BD13C010800AC254BD873
-:103000003C010800AC264BDC3C010800AC274BE43B
-:103010003C010800AC284BE83C010800AC294BEC13
-:103020000A000C40A38200191462000A24020081E5
-:103030003C02800834420100944500DA92460005C3
-:103040008F84001C30A5FFFF30C600FF0A000C0172
-:103050003C0760211462005C000000009242000AFC
-:10306000304300FF30620020104000073062004013
-:103070003C02800834420100944500DA8F84001C31
-:103080000A000BFF24060040104000070003160052
-:103090003C02800834420100944500DA8F84001C11
-:1030A0000A000BFF240600410002160304410046FB
-:1030B0003C02800834420100944500DA8F84001CF1
-:1030C0002406004230A5FFFF3C0760190E0008EE01
-:1030D000000000000A000C40000000009242000BBB
-:1030E00024040016304200FF104400063C06800015
-:1030F0009242000B24030017304200FF14430032B9
-:103100000000000034C5010090A2000B304200FF17
-:103110001444000B000080218CA200208CA400200D
-:103120002403FF8000431024000211403084007FFC
-:10313000004410253C03200000431025ACC2083099
-:1031400094A20008000214000002140304420001CB
-:103150002410000194A20008304200805040001A60
-:103160000200B82194A2000830422000504000160E
-:103170000200B8218CA300183C021C2D344219ED2A
-:10318000106200110200B8213C0208008C4200D4F9
-:10319000104000053C028008240300043442010072
-:1031A000A04300EC3C02800834420100944500DA60
-:1031B0008F84001C2406000630A5FFFF0E0008EED9
-:1031C0003C0760210200B8210E00092F000000001A
-:1031D0009242000A30420008104000043C02800085
-:1031E0000E00121F000000003C02800024030C802F
-:1031F000AC4300248FBF003802E010218FB60030AE
-:103200008FB700348FB5002C8FB400288FB3002403
-:103210008FB200208FB1001C8FB0001803E00008AF
-:1032200027BD00402402FF80008220243C02900041
-:1032300034420007008220253C028000AC4400207C
-:103240003C0380008C6200200440FFFE0000000070
-:1032500003E00008000000003C0380002402FF801F
-:10326000008220243462000700822025AC64002004
-:103270008C6200200440FFFE0000000003E0000814
-:10328000000000003C0280082403000534420100D5
-:10329000A04300EC3C0280008C4201003C03800013
-:1032A000AF82001C8C6202780440FFFE8F82001CFB
-:1032B000AC62024024020002A06202443C02100000
-:1032C000AC62027803E000080000000027BDFFE8C0
-:1032D0003C068000AFBF001034C5010094A2000876
-:1032E000304400FF38830082388200842C63000160
-:1032F0002C42000100621825106000302402008377
-:1033000093820019504000398FBF00103C02080022
-:1033100090424BD88CC401003C07080094E74BD284
-:103320003046003F38C3003238C2003F2C630001F2
-:103330002C42000100621825AF84001CAF870014E6
-:10334000A38000191460000600A0202124020020A0
-:1033500014C200113402FFFF14E2000F000000004D
-:103360002402002014C20005000000008CA30014F9
-:103370002402FFFF1062000A000000003C04080065
-:1033800024844BCC000030210E0006FB24070001F2
-:103390000A000CB6000000000E00076C00000000E0
-:1033A0000E00092F0000000024030C803C02800066
-:1033B000AC4300240A000CEF8FBF001014820006FB
-:1033C0002482FF808CC301043C026020AC430014C3
-:1033D0000A000CEF8FBF0010304200FF2C420002A9
-:1033E00010400004240200228FBF00100A000B25A9
-:1033F00027BD0018148200038FBF00100A000C6F55
-:1034000027BD00183C0208008C4200201040001D1F
-:103410002402001890A3000914620003240200167D
-:103420000A000CDB240300081462000724020017C2
-:10343000240300123C02800834420080A0430009AB
-:103440000A000CE894A700085462000794A700083B
-:103450008F82FFAC2404FFFE904300050064182413
-:10346000A043000594A7000890A6001B8CA40000B0
-:1034700094A500068FBF001000073C000A0008C991
-:1034800027BD001803E0000827BD00183C05080010
-:1034900094A54C0A3C0308008C634C143C04800047
-:1034A00030A2FFFF000230C02402FFF000C210244F
-:1034B00000621821AC83003C3C0208008C424C1096
-:1034C0003C038000AC8200383C02005034420010C3
-:1034D000AC620030000000000000000000000000AE
-:1034E0008C620000304200201040FFFD30C2000816
-:1034F000104000093C0280008C6204088C63040CBC
-:103500003C010800AC224C003C010800AC234C04F8
-:103510000A000D1B3C0300208C4304008C42040471
-:103520003C010800AC234C003C010800AC224C04D8
-:103530003C0300203C028000AC4300303C0780008C
-:103540008CE20030004310241440FFFD0000000016
-:103550003C03080094634C083C02080094424C0C65
-:103560003C06080094C64C0E24A5000100621821F8
-:1035700030A4FFFF3C020040ACE200303C010800F8
-:10358000A4234C083C010800A4254C0A148600031F
-:10359000000000003C010800A4204C0A03E00008E1
-:1035A0000000000027BDFFE83C04080024844BF025
-:1035B0003C05800AAFBF00100E000E202406000A52
-:1035C0003C02080094424BF23C03080094634C0E0A
-:1035D0003042000F244200030043180424027FFFFE
-:1035E0000043102B10400002AF8300280000000DA4
-:1035F0000E000CF1000000003C02080094424BF465
-:103600003C03080094634BFA8FBF00103042000F58
-:10361000000215000062182527BD00183C0280003A
-:1036200003E00008AC4300A03C02800A944300067B
-:103630003C02080094424BFA3C010800A4234BF6DC
-:10364000004310238F8300283042FFFF0043102BDC
-:1036500003E000083842000127BDFFE8AFBF0010BB
-:103660003C02800A944200063C010800A4224BF66A
-:103670000E000D58000000005440FFFA3C02800A82
-:103680008FBF001003E0000827BD001827BDFFE82A
-:10369000AFBF00100E000D580000000010400003E6
-:1036A000000000000E000D64000000003C02080055
-:1036B0008C424C003C0380008FBF0010AC6200388D
-:1036C0003C0208008C424C043464040027BD0018FE
-:1036D000AC62003C3C020005AC620030AF84002CC0
-:1036E00003E00008AF8000248F8200243C03000622
-:1036F00000021140004310253C038000AC62003002
-:103700000000000000000000000000008C620000CB
-:10371000304200101040FFFD34620400AF82002CE4
-:1037200003E00008AF8000243C0608008CC64C046F
-:103730008F8500248F83002C3C02080094424BFAB2
-:1037400027BDFFE024A500012463002024420001DE
-:1037500024C70020AFB10014AFB00010AFBF0018F5
-:10376000AF850024AF83002C3C010800A4224BFA53
-:10377000309000FF3C010800AC274C0404C1000855
-:103780000000882104E00006000000003C02080060
-:103790008C424C00244200013C010800AC224C0049
-:1037A0003C04080094844C083C02080094424BFA04
-:1037B0002E030001004410262C440001008318242D
-:1037C000106000040010102B24020001AF820020C2
-:1037D0000010102B00821025144000068F8200205C
-:1037E000144000048F830024240200101462000F90
-:1037F000000000000E000D88241100013C030800A9
-:1038000094634BFA3C02080094424C081462000393
-:10381000000000000E000CF1000000001600000384
-:10382000000000000E000D71000000003C030800C5
-:1038300094634BFE3C02080094424BFC246300015D
-:103840003064FFFF3C010800A4234BFE14820003F8
-:10385000000000003C010800A4204BFE1200000BF9
-:10386000000000003C02080094424BF43C030800B6
-:1038700094634BFA00021500006218253C02800098
-:10388000AC4300A00A000DF7AF8000200E000D58D9
-:103890000000000010400004022010210E000D6402
-:1038A00000000000022010218FBF00188FB100140B
-:1038B0008FB0001003E0000827BD002003E00008DF
-:1038C000000000008F8200343C030006000211401B
-:1038D000004310253C038000AC6200300000000073
-:1038E00000000000000000008C6200003042001068
-:1038F0001040FFFD34620400AF82003003E0000896
-:10390000AF80003403E000080000102103E000084D
-:10391000000000003084FFFF30A5FFFF00001821E9
-:1039200010800007000000003082000110400002FB
-:1039300000042042006518210A000E1600052840E8
-:1039400003E000080060102110C0000624C6FFFF3D
-:103950008CA2000024A50004AC8200000A000E2006
-:103960002484000403E000080000000010A0000808
-:1039700024A3FFFFAC860000000000000000000050
-:103980002402FFFF2463FFFF1462FFFA2484000473
-:1039900003E00008000000003C0280083442008080
-:1039A00024030001AC43000CA4430010A443001204
-:1039B000A443001403E00008A443001627BDFFD869
-:1039C000248200802407FF803043007FAFB00010C6
-:1039D00000808021004720243C0208008C42002007
-:1039E0003C08800EAFB3001CAFB20018AFB100149A
-:1039F000AFBF00203C0980000068182130B100FFF3
-:103A000030D200FF1040002900009821260201005A
-:103A1000AD24002C004728243042007F004820219C
-:103A20009062000024030050304200FF1443000461
-:103A300000000000AD25002C948200DA3053FFFF17
-:103A40000E000D71000000003C03080094634BFE63
-:103A50008F82002C00112C0000A3282500122400C6
-:103A60003C0340003484000100A32825AC50000032
-:103A70008FBF0020AC4000048FB20018AC53000888
-:103A80008FB10014AC40000C8FB3001CAC4400108C
-:103A90008FB00010AC40001424040001AC400018AA
-:103AA00027BD00280A000D98AC45001C8FBF0020E0
-:103AB0008FB3001C8FB200188FB100148FB00010AC
-:103AC00003E0000827BD00283C06800034C2010046
-:103AD0009043000F240200101062000E28650011B0
-:103AE00010A0000724020012240200082405003A56
-:103AF000106200060000302103E000080000000012
-:103B0000240500351462FFFC000030210A000E3D40
-:103B1000000000008CC200748F83FFAC24420FA011
-:103B200003E00008AC62000C27BDFFE8AFBF001047
-:103B30000E000325240500013C0480088FBF0010FF
-:103B40002402000134830080A462001227BD001803
-:103B50002402000103E00008A080001A27BDFFE056
-:103B6000AFB20018AFB10014AFB00010AFBF001C6F
-:103B700030B2FFFF0E000315008088213C02800850
-:103B8000345000809202000924030004304200FFF8
-:103B90001443000C3C028008124000082402000A72
-:103BA0000E000E3400000000920200052403FFFE08
-:103BB00000431024A202000524020012A202000900
-:103BC0003C02800834420080022020210E000320A5
-:103BD000A040002716400003022020210E000E986E
-:103BE0000000000002202021324600FF8FBF001C91
-:103BF0008FB200188FB100148FB000102405003868
-:103C00000A000E3D27BD002027BDFFE0AFBF001C0E
-:103C1000AFB20018AFB10014AFB000100E00031522
-:103C2000008080210E000E34000000003C0280085D
-:103C30003445008090A2000924120018305100FF82
-:103C4000123200030200202124020012A0A2000967
-:103C500090A200052403FFFE004310240E00032061
-:103C6000A0A2000502002021240500201632000732
-:103C7000000030218FBF001C8FB200188FB10014DC
-:103C80008FB000100A00032527BD00208FBF001C45
-:103C90008FB200188FB100148FB0001024050039C6
-:103CA0000A000E3D27BD002027BDFFE83C02800032
-:103CB000AFB00010AFBF0014344201009442000CBA
-:103CC000240500360080802114400012304600FF99
-:103CD0000E000315000000003C0280083442008002
-:103CE00024030012A0430009904300053463001030
-:103CF0000E000E34A04300050E0003200200202118
-:103D0000020020210E000325240500200A000F15C3
-:103D1000000000000E000E3D000000000E00031524
-:103D2000020020213C0280089043001B2405FF9FD5
-:103D300002002021006518248FBF00148FB00010EE
-:103D4000A043001B0A00032027BD001827BDFFE089
-:103D5000AFBF0018AFB10014AFB0001030B100FF1A
-:103D60000E000315008080213C028008240300120D
-:103D7000344200800E000E34A04300090E000320E0
-:103D80000200202102002021022030218FBF0018D4
-:103D90008FB100148FB00010240500350A000E3DCD
-:103DA00027BD00203C0480089083000E9082000A0A
-:103DB0001443000B000028218F82FFAC2403005025
-:103DC0002405000190420000304200FF144300042B
-:103DD000000000009082000E24420001A082000E2C
-:103DE00003E0000800A010213C0380008C6201F871
-:103DF0000440FFFE24020002AC6401C0A06201C4C2
-:103E00003C02100003E00008AC6201F827BDFFE0AF
-:103E1000AFB200183C128008AFB10014AFBF001C55
-:103E2000AFB0001036510080922200092403000A2E
-:103E3000304200FF1443003A000000008E430004AB
-:103E40008E2200385062007E8FBF001C922200003C
-:103E500024030050304200FF144300253C02800040
-:103E60008C4201408E43000436420100022028218A
-:103E7000AC43001C9622005C8E2300383042FFFFCA
-:103E80000002104000621821AE23001C8E43000483
-:103E90008E2400389622005C006418233042FFFF15
-:103EA00000031843000210400043102A104000068F
-:103EB000000000008E4200048E23003800431023CF
-:103EC0000A000F83000220439622005C3042FFFF6D
-:103ED000000220403C02800834430100344200804C
-:103EE000ACA4002CA040002424020001A062000C1D
-:103EF0000E000F3700000000104000518FBF001C63
-:103F00003C0280008C4401408FBF001C8FB200181F
-:103F10008FB100148FB000100A000F4827BD002099
-:103F20009222000924030010304200FF14430004D1
-:103F30003C0280008C4401400A000FC5000028218B
-:103F40009222000924030016304200FF14430006A9
-:103F500024020014A22200093C0280008C4401408B
-:103F60000A000FD88FBF001C8E2200388E23003C21
-:103F700000431023044100328FBF001C922200270F
-:103F800024420001A2220027922200273C030800BD
-:103F90008C630048304200FF144300163C10800040
-:103FA0009222000924030004304200FF1443000958
-:103FB0003C0280008C4401408FBF001C8FB200186F
-:103FC0008FB100148FB00010240500930A000EA5D5
-:103FD00027BD00208C440140240500938FBF001CA6
-:103FE0008FB200188FB100148FB000100A000F219B
-:103FF00027BD00208E0401400E00031500000000C4
-:104000008E4200042442FFFFAE4200048E22003C98
-:104010002442FFFFAE22003C0E0003208E0401402C
-:104020008E0401408FBF001C8FB200188FB10014A6
-:104030008FB00010240500040A00032527BD0020CE
-:104040008FB200188FB100148FB0001003E0000889
-:1040500027BD00203C0680008CC201883C038008FC
-:10406000346500809063000E00021402304400FFAB
-:10407000306300FF1464000E3C02800890A200260A
-:10408000304200FF104400098F82FFACA0A400263C
-:104090002403005090420000304200FF1443000609
-:1040A000000000000A00058C8CC401803C028008DE
-:1040B00034420080A044002603E000080000000015
-:1040C00027BDFFE030E700FFAFB20018AFBF001C14
-:1040D000AFB10014AFB000100080902114E00006D2
-:1040E00030C600FF000000000000000D00000000CE
-:1040F0000A001037240001173C0380089062000E6C
-:10410000304200FF144600233462008090420026B3
-:10411000304200FF1446001F000000009062000FB4
-:10412000304200FF1446001B000000009062000AAD
-:10413000304200FF144600038F90FFAC0000000DDA
-:104140008F90FFAC8F82FFB03C118000AE05003C29
-:10415000AC450000A066000A0E0003158E24010085
-:10416000A20000240E0003208E2401003C038000E6
-:104170008C6201F80440FFFE24020002AC7201C010
-:10418000A06201C43C021000AC6201F80A001038C1
-:104190008FBF001C000000000000000D00000000A8
-:1041A000240001408FBF001C8FB200188FB1001493
-:1041B0008FB0001003E0000827BD00208F83FFAC04
-:1041C0003C0280008C440100344201008C65003CBC
-:1041D0009046001B0A000FFE240700013C028008E5
-:1041E0009043000E9042000A00431026304200FF28
-:1041F00003E000080002102B27BDFFE03C0280080E
-:10420000AFB10014AFB00010AFBF00183450008041
-:104210009202000524030030304200301443008431
-:10422000008088213C0208008C4200201040008160
-:104230008FBF00180E000D71000000008F86002C4B
-:10424000ACD100009202000892030009304200FF46
-:1042500000021200306300FF00431025ACC20004CE
-:104260009202004D000216000002160304410005F0
-:10427000000000003C0308008C6300480A00107630
-:104280003C108008920200083042004014400003B5
-:104290000000182192020027304300FF3C108008E4
-:1042A000361100809222004D00031E003C050800DC
-:1042B00094A54BFE304200FF000214000062182556
-:1042C000ACC300088E2300303C02C00B00A228259E
-:1042D000ACC3000C8E22003400002021ACC20010C0
-:1042E0008E220038ACC200148E22003CACC20018F2
-:1042F0000E000D98ACC5001C8E0200048F84002CAB
-:104300003C058000AC8200008E220020AC820004BC
-:104310008E22001CAC8200088E2200588CA30074F0
-:1043200000431021AC82000C8E22002CAC820010C5
-:104330008E2200408E23004400021400004310250A
-:10434000AC8200149222004D24030080304200FF12
-:1043500014430003000000000A0010B8AC800018ED
-:104360008E23000C240200011062000E2402FFFFC5
-:1043700092220008304200401440000A2402FFFF4D
-:104380008E23000C8CA20074006218233C020800EB
-:10439000006210241440000200002821006028213F
-:1043A00000051043AC8200183C02080094424BFE0A
-:1043B0003C03C00C00002021004310258F83002CFB
-:1043C0000E000D98AC62001C3C0480083482010091
-:1043D0008C4200008F83002C348400803C0608004F
-:1043E00094C64BFEAC620000AC6000048C850048B3
-:1043F0003C02400D00C23025AC650008AC60000CEA
-:10440000AC600010908200058FBF00188FB10014BF
-:1044100000021600AC6200148FB00010AC600018EF
-:1044200024040001AC66001C0A000D9827BD002082
-:104430008FBF00188FB100148FB0001003E0000888
-:1044400027BD00203C0280009443007C3C02800891
-:1044500034460100308400FF3065FFFF2402000570
-:1044600024A34650A0C4000C5482000C3065FFFF0A
-:1044700090C2000D2C4200071040000724A30A0040
-:1044800090C3000D240200140062100400A2102149
-:104490000A0010F53045FFFF3065FFFF3C02800841
-:1044A0003442008003E00008A44500143C03800867
-:1044B00034680080AD050038346701008CE2001CD0
-:1044C000308400FF00A210231840000330C600FF14
-:1044D00024A2FFFCACE2001C308200015040000826
-:1044E0003C0380088D02003C00A21023044100120E
-:1044F000240400058C62000410A2000F3C03800815
-:104500008C62000414A20018000000003C020800A5
-:104510008C4200D830420020104000093C02800844
-:1045200034620080906300089042004C1443000401
-:104530003C028008240400040A0010DF0000000090
-:104540003443008034420100A040000C24020001EA
-:10455000A462001410C000043C0280008C440100DE
-:104560000A000F480000000003E0000800000000FF
-:1045700027BDFFE800A61823AFBF00101860004E4B
-:10458000308800FF3C02800834470080A0E000240F
-:1045900034440100A0E000278C82001C00A21023FC
-:1045A0000440002B000000008CE2003C94E3005C1F
-:1045B0008CE4002C004530233063FFFF00C318213A
-:1045C0000083202B1080000400E018218CE2002CD6
-:1045D0000A00114800A2102194E2005C3042FFFF63
-:1045E00000C2102100A21021AC62001C3C02800815
-:1045F0003447008094E2005C8CE3001C3042FFFFF3
-:104600000002104000A210210043102B10400003B4
-:10461000000000000A0011598CE2001C94E2005CCA
-:104620003042FFFF0002104000A21021ACE2001C4B
-:104630003C028008344201008FBF0010010020219D
-:1046400024060001A040000C0A0010F927BD001844
-:104650008CE2001C004610230043102B5440000144
-:10466000ACE5001C94E2005C3042FFFF0062102BBE
-:10467000144000072402000294E2005C8CE3001C5A
-:104680003042FFFF00621821ACE3001C240200024C
-:10469000ACE500380E000F37A082000C1040001867
-:1046A0008FBF00103C0280008C4401008FBF0010BF
-:1046B0000A000F4827BD00183102001010400010FA
-:1046C0008FBF00103C028008344500808CA3001C82
-:1046D00094A2005C006618233042FFFF006218219C
-:1046E0003C023FFF3444FFFF0083102B5440000185
-:1046F0000080182100C31021ACA2001C8FBF001045
-:1047000003E0000827BD001827BDFFE800C04021D6
-:1047100000A63023AFBF001018C00026308A00FF6B
-:104720003C028008344900808D24001C8D23002C1D
-:10473000008820230064182B1060000F344701000C
-:104740008CE2002000461021ACE200208CE2002028
-:104750000044102B1440000B3C023FFF8CE2002071
-:1047600000441023ACE200209522005C3042FFFFA1
-:104770000A0011AE00822021ACE00020008620213A
-:104780003C023FFF3443FFFF0064102B5440000104
-:10479000006020213C0280083442008000851821FE
-:1047A000AC43001CA0400024A04000270A0011FDDB
-:1047B0008FBF001031420010104000408FBF00102A
-:1047C0003C06800834C400808C82003C00481023E2
-:1047D0005840003B014020219082002424420001E7
-:1047E000A0820024908200243C0308008C630024F3
-:1047F000304200FF0043102B544000348FBF0010A4
-:1048000034C201008C42001C00A210231840002F6B
-:104810008FBF00108CC300049482005C00681823D2
-:104820003042FFFF00031843000210400043102AEB
-:1048300010400005000000008CC200040048102356
-:104840000A0011E3000210439482005C3042FFFF33
-:10485000000210403C068008AC82002C34C5008069
-:1048600094A2005C8CA4002C94A3005C3042FFFF57
-:1048700000021040008220213063FFFF00832021CE
-:1048800001041021ACA2001C8CC2000434C601003B
-:10489000ACC2001C240200020E000F37A0C2000CA4
-:1048A0001040000A8FBF00103C0280008C440100C1
-:1048B0008FBF00100A000F4827BD001801402021BB
-:1048C000240600010A0010F927BD001803E00008C3
-:1048D00027BD00183C098008352A00808D42003C25
-:1048E000308300FF352B01000046102330E700FF26
-:1048F000184000060060202124020001A160000C85
-:10490000A160000D0A001190A542001424020005C8
-:10491000352901000000302114E20008A1400027E1
-:104920009122000D2C4200061040000400000000FF
-:104930009122000D24420001A122000D0A0010F96D
-:10494000000000003C0380083C028000344201006B
-:1049500034640080346301009045000A8C480014E0
-:104960008C8900389062000C30AA00FF01281823BF
-:10497000304700FF1C60000E2CE4000624020001FA
-:1049800000E210041080000A30430003014020219F
-:10499000010028210120302114600007304B000C59
-:1049A000156000073042003014400007000000008E
-:1049B00003E00008000000000A0011900000000061
-:1049C0000A00112A000000000A0012030000000083
-:1049D0003C0380083464010024020003A082000C20
-:1049E0008C62000403E00008AC82001C3C058008D7
-:1049F00034A300809062002734A501002406004300
-:104A000024420001A0620027906300273C020800B6
-:104A10008C420048306300FF146200043C076021B0
-:104A200094A500DA0A0008EE30A5FFFF03E00008B5
-:104A30000000000027BDFFE8AFBF00103C0280006F
-:104A40000E0012498C4401803C028008344301006E
-:104A5000A060000C8C4200048FBF001027BD00181E
-:104A600003E00008AC62001C27BDFFE03C028008A8
-:104A7000AFBF0018AFB10014AFB0001034450080D4
-:104A8000344601003C0880008D09014090C3000CB1
-:104A90008CA4003C8CA2003814820038306700FFE0
-:104AA0009502007C90A30027146000093045FFFFA9
-:104AB0002402000554E200083C04800890C2000D66
-:104AC00024420001A0C2000D0A0012843C048008A8
-:104AD000A0C0000D3C048008348201009042000C0C
-:104AE00024030005304200FF1443000A24A205DC21
-:104AF00034830080906200272C420007504000055C
-:104B000024A20A009063002724020014006210040B
-:104B100000A210213C108008361000803045FFFFB5
-:104B2000012020210E001249A60500149602005C07
-:104B30008E0300383C1180003042FFFF000210401D
-:104B400000621821AE03001C0E0003158E240140E4
-:104B50009202002534420040A20200250E000320EC
-:104B60008E2401408E2401408FBF00188FB10014A5
-:104B70008FB000100A000F4827BD00208FBF00181B
-:104B80008FB100148FB0001003E0000827BD002093
-:104B90008008010080080080800800008008024032
-:104BA00008000EF008000F4808000F8C08001020C5
-:104BB0000800106480080100800800808008000060
-:104BC0000A00002000000000000000000000000DAE
-:104BD0006370342E362E31370000000004061104B5
-:104BE00000000000000000000000000000000000C5
-:104BF0000000000038003C00000000000000000041
-:104C00000000000000000000000000200000000084
-:104C10000000000000000000000000000000000094
-:104C20000000000000000000000000000000000084
-:104C30000000000021003800000000010000002BEF
-:104C40000000000010000003000000000000000D44
-:104C50000000000D3C020800244255C43C0308003B
-:104C6000246357F4AC4000000043202B1480FFFD68
-:104C7000244200043C1D080037BD9FFC03A0F02126
-:104C80003C100800261000803C1C0800279C55C4DE
-:104C90000E00026A000000000000000D00A01821B4
-:104CA00000801021008028213C0460003C07600047
-:104CB0002406000810600006348420788C4200002E
-:104CC000ACE220088C63000003E00008ACE3200C99
-:104CD0000A000E1C00000000240300403C0260009B
-:104CE00003E00008AC4320003C0760008F86000012
-:104CF0008CE520740086102100A2182B1460000798
-:104D0000000028218F8AFDEC24050001A144001336
-:104D10008F89000001244021AF88000003E00008D3
-:104D200000A010218F84FDEC8F8500009086001379
-:104D300030C300FF00A31023AF82000003E000088F
-:104D4000A08000138F84FDEC27BDFFE8AFB00010FA
-:104D5000AFBF001490890011908700112402002831
-:104D6000312800FF3906002830E300FF2485002C9D
-:104D70002CD00001106200162484001C0E000037A5
-:104D8000000000008F8FFDEC3C056000240202044F
-:104D900095EE003E95ED003C000E5C0031ACFFFF4F
-:104DA000016C5025ACAA201052000001240200041E
-:104DB000ACA2200000000000000000000000000085
-:104DC0008FBF00148FB0001003E0000827BD00184B
-:104DD0000A00006F000028218F85FDEC27BDFFD859
-:104DE000AFBF0020AFB3001CAFB20018AFB10014CA
-:104DF000AFB000100080982190A4001124B0001CD6
-:104E000024B1002C308300FF386200280E000059C6
-:104E10002C5200010E000061000000000200202161
-:104E20001240000202202821000028210E00003735
-:104E3000000000008F8DFDEC3C0880003C05600008
-:104E400095AC003E95AB003C02683025000C4C0050
-:104E5000316AFFFF012A3825ACA720102402020284
-:104E6000ACA6201452400001240200028FBF002093
-:104E70008FB3001C8FB200188FB100148FB00010D8
-:104E800027BD002803E00008ACA2200027BDFFE0FA
-:104E9000AFB20018AFB10014AFB00010AFBF001C2C
-:104EA0003C1160008E2320748F82000030D0FFFF01
-:104EB00030F2FFFF1062000C2406008F0E00003756
-:104EC000000000003C06801F0010440034C5FF00B5
-:104ED0000112382524040002AE27201000003021E2
-:104EE000AE252014AE2420008FBF001C8FB2001806
-:104EF0008FB100148FB0001000C0102103E0000833
-:104F000027BD002027BDFFE0AFB0001030D0FFFF6D
-:104F1000AFBF0018AFB100140E00003730F1FFFF33
-:104F200000102400009180253C036000AC7020102C
-:104F30008FBF00188FB100148FB00010240200043E
-:104F4000AC62200027BD002003E000080000102113
-:104F500027BDFFE83C0C6018AFBF00108D985000D3
-:104F60002419FF7F3C0880000319782435EE380CA3
-:104F7000340D8071240A003124090C00AD8E5000DC
-:104F80003C0B800AAD8D53BCAD0A0008AD0900246E
-:104F90000E00048DAF8B002C0E00044B00000000AF
-:104FA0000E000046000000003C0760008CE5080889
-:104FB0002406FFF03C03570900A620243462F000C9
-:104FC00010820048241F0001AF8000380E000BAE95
-:104FD000000000003C0660168CC700003C0860140E
-:104FE0008D0500A03C03FFFF00E320243C02535347
-:104FF00000051FC21082003534C57C0094A201F266
-:10500000A780005010400003A7800060384C1E1E8F
-:10501000A78C005094A201F8104000048F8E003835
-:10502000384D1E1EA78D00608F8E003811C0000401
-:1050300097840060240F0020A78F005097840060A1
-:105040002C980081530000012404008097850050B3
-:105050002CB9040153200001240504003C03600026
-:105060008C670438241F103C30E2FFFF105F000300
-:105070003088FFFF5100000B24060050A38000621F
-:10508000938900621120000B8FBF001027BD00180C
-:10509000A7800060A7800050A780005803E00008A8
-:1050A000A7800076A3860062938900621520FFF72F
-:1050B0008FBF001027BD0018A7840060A78500508F
-:1050C000A780005803E00008A780007600035880FE
-:1050D000016650218D4900043C0660000A00010F62
-:1050E000012628210A000103AF9F00383083FFFF0B
-:1050F0008F88002C8F870028000321403C0580000A
-:105100003C020050008248253C0660003C0A010039
-:1051100034AC04008CCD08E001AA582411600005CD
-:10512000000000008CCF08E024E7000101EA7025B0
-:10513000ACCE08E08D19001001805821ACB90038C0
-:105140008D180014ACB8003CACA900300000000081
-:10515000000000000000000000000000000000004F
-:105160000000000000000000000000003C03800080
-:105170008C640000308200201040FFFD3C0F600076
-:105180008DED08E03C0E010001AE18241460FFE133
-:1051900000000000AF87002803E00008AF8B003C50
-:1051A0008F85002C240BFFF03C06800094A7001A8A
-:1051B0008CA9002430ECFFFF000C38C000EB502419
-:1051C000012A4021ACC8003C8CA400248CC3003CC4
-:1051D0000083102318400033000000008CAD002035
-:1051E00025A200013C0F0050ACC2003835EE001083
-:1051F0003C068000ACCE0030000000000000000043
-:10520000000000000000000000000000000000009E
-:1052100000000000000000003C0480008C990000A9
-:10522000333800201300FFFD30E200081040001763
-:105230003C0980008C880408ACA800108C83040C06
-:10524000ACA300143C1900203C188000AF190030BA
-:1052500094AE001894AF001C01CF3021A4A6001812
-:1052600094AD001A25A70001A4A7001A94AB001A58
-:1052700094AC001E118B00030000000003E0000846
-:105280000000000003E00008A4A0001A8D2A04001A
-:10529000ACAA00108D240404ACA400140A0001A2DE
-:1052A0003C1900208CA200200A00018A3C0F00500B
-:1052B0000A000178000000003C0308008C63002015
-:1052C0008F82003427BDFFE810620008AFBF0010D6
-:1052D0000E0001BCAF8300343C0308008C63002047
-:1052E00024040001106400048F8C002C8FBF001078
-:1052F00003E0000827BD00188FBF00103C058000A8
-:10530000A580000A958B000A958A000427BD001825
-:105310003167FFFF3149000F0009450000E83025E3
-:1053200003E00008ACA600803C0208008C4200208C
-:1053300027BDFFC8AFBF0034AFBE0030AFB7002CF1
-:10534000AFB60028AFB50024AFB40020AFB3001C47
-:10535000AFB20018AFB1001410400053AFB000104E
-:105360008F84002C948600069483000A00C32823AF
-:1053700030B6FFFF12C0004D8FBF00349489001873
-:10538000948A000A012A40233102FFFF02C2382B0F
-:1053900014E0000202C02021004020212C8C0005D6
-:1053A000158000020080A021241400040E00014B8F
-:1053B000028020218F87002C02809821AF8000304E
-:1053C00094ED000A028088211280005131B2FFFF63
-:1053D0003C1770003C1540003C1E60008F8F003C65
-:1053E0008DEE000001D718245075005302202021B3
-:1053F00002A3802B160000383C1820001078004AC9
-:1054000000000000241000018F8300301460003C75
-:10541000029158230230F8230250C82133F1FFFFD4
-:105420001620FFEE3332FFFF8F87002C3C12002046
-:105430003C118000AE32003094EA000A3C17800034
-:10544000026A4821A4E9000A94E3000A94E80004EF
-:105450003065FFFF3106000F0006150000A2F025A1
-:10546000AEFE008094F4000A94F5001812B4003ADD
-:105470000013C9408CF800148CEE00100319582159
-:10548000000078210179682B01CF6021018D202156
-:10549000ACEB0014ACE4001002D3382330F6FFFF6D
-:1054A00016C0FFB68F84002C8FBF00348FBE003033
-:1054B0008FB7002C8FB600288FB500248FB4002042
-:1054C0008FB3001C8FB200188FB100148FB0001082
-:1054D00003E0000827BD0038107E001B000000001C
-:1054E0001477FFC9241000010E0014E00000000032
-:1054F0008F8300301060FFC80230F82302915823D8
-:105500008F87002C017020210A0002553093FFFF85
-:105510008F8300301460FFC83C1200203C118000D3
-:105520000A00021EAE3200300E0003CE02202021FF
-:105530000A000212004080210E0007C60240282106
-:105540000A000212004080210E000D7D0220202161
-:105550000A000212004080210E00017800000000C5
-:105560000A00023702D3382327BDFFD0AFB500248D
-:10557000AFB40020AFB3001CAFB20018AFB100143D
-:10558000AFB00010AFBF00280E0000E43C14800054
-:105590003C0280083C0320003C010800AC20007065
-:1055A00034550080347200032413000136900070DB
-:1055B0002411FF800A0002858E0600003C1980003D
-:1055C0008F3800003B0F000131E200011040002540
-:1055D0008F8600848E0700003C0D08008DAD003CD6
-:1055E0003C0A08008D4A003800E6702301AE4021D5
-:1055F00000005821010E302B014B482101262021AB
-:105600003C010800AC28003CAF8700843C01080046
-:10561000AC2400380E0001BE000000003C0508006C
-:105620008CA5007010A0FFE500A020213C0508001B
-:105630008CA500683C0608008CC6006C0E00148324
-:10564000000000003C010800AC2000703C19800004
-:105650008F3800003B0F000131E200011440FFDDF4
-:105660008F8600848E0C00008F8D00843C0708001C
-:105670008CE7003C3C0608008CC60038018D58239E
-:1056800000EB282100AB202B00C24821012410216F
-:105690003C010800AC25003C3C0880003C010800AF
-:1056A000AC2200388D030100241F0C00107F00265F
-:1056B000000000008D180100240E0020AD1800200D
-:1056C00092AF000031E300FF106E00232419005058
-:1056D00010790026000000003C0480008C88010046
-:1056E0001500000300000000566000143C04400058
-:1056F0008C9901008C8F0100000098210331C02497
-:105700000018694031EE007F01AE602501925825F6
-:10571000AC8B08308C8701008C89010024EA0100E1
-:1057200001513024000629403123007F00A31025B9
-:105730000052F825AC9F08303C044000AE8401388C
-:105740000A00027D000000000E0001DA00000000E7
-:105750000A0002C73C0480008D0401000E00077F90
-:10576000000000000A0002C73C0480008D04010014
-:105770000E00139B000000000A0002C73C048000DA
-:1057800000A4102B24030001104000090000302168
-:105790000005284000A4102B04A0000300031840BB
-:1057A0005440FFFC000528405060000A0004182BFC
-:1057B0000085382B54E000040003184200C3302554
-:1057C00000852023000318421460FFF900052842D9
-:1057D0000004182B03E0000800C310213084FFFFF1
-:1057E00030C600FF3C0780008CE201B80440FFFE99
-:1057F00000064C00012430253C08200000C820256C
-:105800003C031000ACE00180ACE50184ACE401880D
-:1058100003E00008ACE301B83C0660008CC5201C26
-:105820002402FFF030830200308601001060000E79
-:1058300000A2282434A500013087300010E00005C4
-:1058400030830C0034A500043C04600003E0000831
-:10585000AC85201C1060FFFD3C04600034A50008EE
-:1058600003E00008AC85201C54C0FFF334A50002FF
-:105870000A00031F3087300027BDFFE8AFB00010DB
-:10588000AFBF00143C076000240600021080001126
-:1058900000A080218F83003C0E0003168C6400184A
-:1058A0008F82003C00002021240600018C45000C62
-:1058B0000E0003070000000016000002240200038F
-:1058C000000010218FBF00148FB0001003E000080B
-:1058D00027BD00188CE8201C2409FFF001092824AA
-:1058E000ACE5201C8F87003C0A00033C8CE5000CD3
-:1058F0003C02600E0080402134460100240900185B
-:105900000000000000000000000000003C0A005001
-:105910003C03800035470200AC6800383464040062
-:10592000AC65003CAC6700308C6C0000318B002013
-:105930001160FFFD2407FFFF2403007F8C8D000012
-:105940002463FFFF24840004ACCD00001467FFFB38
-:1059500024C6000400000000000000000000000059
-:1059600024A402000085282B3C0300203C0E80006C
-:105970002529FFFF01054021ADC300301520FFE0C0
-:105980000080282103E00008000000008F82003C16
-:1059900027BDFFD8AFB3001CAFBF0020AFB20018C7
-:1059A000AFB10014AFB000109446000200809821FF
-:1059B0008C5200182CC300818C4800048C470008CE
-:1059C0008C51000C8C490010106000078C4A0014A8
-:1059D0002CC400041480001330EB000730C5000312
-:1059E00010A00010000000002410008B02002021F5
-:1059F000022028210E00030724060003166000027F
-:105A000024020003000010218FBF00208FB3001C70
-:105A10008FB200188FB100148FB0001003E000089F
-:105A200027BD00281560FFF12410008B3C0C80007E
-:105A30003C030020241F0001AD830030AF9F0030E5
-:105A40000000000000000000000000002419FFF02A
-:105A500024D8000F031978243C1000D0AD880038FA
-:105A600001F0702524CD00033C08600EAD87003C9A
-:105A700035850400AD8E0030000D38823504003CC1
-:105A80003C0380008C6B0000316200201040FFFD61
-:105A90000000000010E0000824E3FFFF2407FFFFE0
-:105AA0008CA800002463FFFF24A50004AC8800003C
-:105AB0001467FFFB248400043C04600EAC860038AD
-:105AC0000000000000000000000000003C07002073
-:105AD0003C0680000120202101402821ACC7003075
-:105AE0000E00034C000080210E000316024020210E
-:105AF0000A00038C0200202127BDFFD8AFB2001896
-:105B00003092FFFFAFB10014AFBF0020AFB3001C55
-:105B1000AFB000101240002D000088210A0003E2FF
-:105B20002413000350B300428CE5000C0000000D6C
-:105B3000263900013331FFFF24F800200232382BD0
-:105B400010E00022AF98003C8F8200301440001F0C
-:105B50008F87003C3C0670003C0320008CE4000072
-:105B60000086282414A300198F85004400044402F1
-:105B70003C0980000089802414A0FFEA310600FF60
-:105B8000240A000210CA003028CB0003116000175D
-:105B9000000000002404000114C4FFE626390001BF
-:105BA000020028210E00032E240400018F87003CF0
-:105BB000AF820044263900013331FFFF24F8002072
-:105BC0000232382B14E0FFE0AF98003C0220102195
-:105BD0008FBF00208FB3001C8FB200188FB100144C
-:105BE0008FB0001003E0000827BD002810D3001B71
-:105BF000240C000414CCFFCF26390001308DFFFFA8
-:105C0000000D19C03C0480008C8E01B805C0FFFE59
-:105C10003C0F10003C102004AC830180AC80018458
-:105C2000AC900188AC8F01B80A0003DD2639000171
-:105C30000E000307240400841600FFBD8F87003C7C
-:105C40000A0003DCAF800044020028210E00032E6E
-:105C5000000020210A0003FC8F87003C0E00037324
-:105C6000020020218F87003C0A0003FDAF82004420
-:105C7000000449C23127003F000443423C02800037
-:105C800000082040240316802CE60020AC43002CA2
-:105C900024EAFFE02482000114C0000330A900FFC1
-:105CA00000801021314700FF000260803C0D800021
-:105CB000240A0001018D20213C0B000E00EA28047B
-:105CC000008B302111200005000538278CCE000004
-:105CD00001C5382503E00008ACC700008CD80000DF
-:105CE0000307782403E00008ACCF000027BDFFE0E5
-:105CF000AFB10014AFB00010AFBF00183C07600098
-:105D00008CE408083402F0003C1160003083F0009D
-:105D1000240501C03C04800E000030211062000602
-:105D2000241000018CEA08083149F0003928E0000D
-:105D30000008382B000780403C0D0200AE2D0814EF
-:105D4000240C16803C0B80008E2744000E000E268B
-:105D5000AD6C002C120000043C02169124050001D9
-:105D6000120500103C023D6C345800E0AE38440887
-:105D70003C1108008E31007C8FBF00183C0660008B
-:105D800000118540360F16808FB100148FB00010BF
-:105D90003C0E020027BD0020ACCF442003E00008E9
-:105DA000ACCE08103C0218DA345800E0AE38440893
-:105DB0003C1108008E31007C8FBF00183C0660004B
-:105DC00000118540360F16808FB100148FB000107F
-:105DD0003C0E020027BD0020ACCF442003E00008A9
-:105DE000ACCE08100A00042C240500010A00042C83
-:105DF0000000282124020400A782000CA7800004D0
-:105E0000000020213C06080024C656582405FFFF48
-:105E100024890001000440803124FFFF010618217D
-:105E20002C87002014E0FFFAAC6500002404040075
-:105E3000A784000EA7800006000020213C06080071
-:105E400024C656D82405FFFF248D0001000460807D
-:105E500031A4FFFF018658212C8A00201540FFFA4B
-:105E6000AD650000A7800010A7800008A780000A89
-:105E7000000020213C06080024C657582405FFFFD7
-:105E8000249900010004C0803324FFFF0306782119
-:105E90002C8E000415C0FFFAADE500003C05600043
-:105EA0008CA73D002403E08F00E31024344601401A
-:105EB00003E00008ACA63D002487007F000731C244
-:105EC00024C5FFFF000518C2246400013082FFFFD3
-:105ED000000238C0A78400183C010800AC2700303D
-:105EE000AF80001400002821000020210000302194
-:105EF0002489000100A728213124FFFF2CA81701C5
-:105F0000110000032C8300801460FFF924C60001F7
-:105F100000C02821AF86001410C0001DA786001203
-:105F200024CAFFFF000A11423C0808002508575800
-:105F30001040000A00002021004030212407FFFF0C
-:105F4000248E00010004688031C4FFFF01A8602195
-:105F50000086582B1560FFFAAD87000030A2001FA5
-:105F60005040000800043080240300010043C804AE
-:105F700000041080004878212738FFFF03E0000864
-:105F8000ADF8000000C820212405FFFFAC8500000B
-:105F900003E000080000000030A5FFFF30C6FFFF4F
-:105FA00030A8001F0080602130E700FF0005294273
-:105FB0000000502110C0001D24090001240B000125
-:105FC00025180001010B2004330800FF0126782664
-:105FD000390E00202DED00012DC2000101A218256F
-:105FE0001060000D014450250005C880032C40219D
-:105FF0000100182110E0000F000A20278D04000086
-:10600000008A1825AD03000024AD000100004021E6
-:106010000000502131A5FFFF252E000131C9FFFFEF
-:1060200000C9102B1040FFE72518000103E000080D
-:10603000000000008D0A0000014440240A000512FF
-:10604000AC68000027BDFFE830A5FFFF30C6FFFFAA
-:10605000AFB00010AFBF001430E7FFFF00005021C9
-:106060003410FFFF0000602124AF001F00C0482152
-:10607000241800012419002005E0001601E0102179
-:106080000002F943019F682A0009702B01AE4024E9
-:1060900011000017000C18800064102110E00005AA
-:1060A0008C4B000000F84004000838230167582496
-:1060B00000003821154000410000402155600016C5
-:1060C0003169FFFF258B0001316CFFFF05E1FFEC1B
-:1060D00001E0102124A2003E0002F943019F682A3A
-:1060E0000009702B01AE40241500FFEB000C188056
-:1060F000154600053402FFFF020028210E0004F6B9
-:1061000000003821020010218FBF00148FB0001052
-:1061100003E0000827BD00181520000301601821C6
-:10612000000B1C0224080010306A00FF1540000517
-:10613000306E000F250D000800031A0231A800FF81
-:10614000306E000F15C00005307F000325100004DD
-:1061500000031902320800FF307F000317E000053A
-:10616000386900012502000200031882304800FF50
-:10617000386900013123000110600004310300FF81
-:10618000250A0001314800FF310300FF000C69407F
-:1061900001A34021240A000110CAFFD53110FFFFDE
-:1061A000246E000131C800FF1119FFC638C9000173
-:1061B0002D1F002053E0001C258B0001240D000141
-:1061C0000A000589240E002051460017258B000186
-:1061D00025090001312800FF2D090020512000125F
-:1061E000258B000125430001010D5004014B1024B3
-:1061F000250900011440FFF4306AFFFF3127FFFF3B
-:1062000010EE000C2582FFFF304CFFFF00005021F4
-:106210003410FFFF312800FF2D0900205520FFF228
-:1062200025430001258B0001014648260A0005434D
-:10623000316CFFFF00003821000050210A00059555
-:106240003410FFFF27BDFFD8AFB0001030F0FFFFC4
-:10625000AFB10014001039423211FFE00007108086
-:10626000AFB3001C00B1282330D3FFFFAFB200183A
-:1062700030A5FFFF008090210260302100442021E2
-:10628000AFBF00200E0005213207001F0222882127
-:106290003403FFFF02402021020028210260302148
-:1062A00000003821104300093231FFFF0220102185
-:1062B0008FBF00208FB3001C8FB200188FB1001465
-:1062C0008FB0001003E0000827BD00280E00052154
-:1062D0000000000000408821022010218FBF002014
-:1062E0008FB3001C8FB200188FB100148FB0001054
-:1062F00003E0000827BD0028000424003C036000E0
-:10630000AC603D0810A000023482100634821016E2
-:1063100003E00008AC623D0427BDFFE0AFB0001011
-:10632000309000FF2E020006AFBF0018104000089A
-:10633000AFB10014001030803C030800246353B454
-:1063400000C328218CA40000008000080000000089
-:10635000000020218FBF00188FB100148FB00010F3
-:106360000080102103E0000827BD00209791001253
-:1063700016200051000020213C020800904200330A
-:106380000A0005FC00000000978D000E15A00031EA
-:10639000000020210A0005FC240200089787000C59
-:1063A00014E0001A000018210060202124020001DE
-:1063B0001080FFE98FBF0018000429C2004530217A
-:1063C00000A6582B1160FFE43C0880003C07200029
-:1063D000000569C001A76025AD0C00203C038008C2
-:1063E0002402001F2442FFFFAC6000000441FFFDB7
-:1063F0002463000424A5000100A6702B15C0FFF53E
-:10640000000569C00A0005E68FBF001897870004E1
-:106410003C04080024845658240504000E0005A1FD
-:1064200024060001978B000C24440001308AFFFFF2
-:106430002569FFFF2D480400004028211500004079
-:10644000A789000C24AC3800000C19C00A0005FA1A
-:10645000A7800004978700063C040800248456D8CF
-:10646000240504000E0005A1240600019799000EE2
-:10647000244400013098FFFF272FFFFF2F0E040058
-:106480000040882115C0002CA78F000EA7800006B1
-:106490003A020003262401003084FFFF0E0005CEDF
-:1064A0002C4500010011F8C027F00100001021C0A8
-:1064B0000A0005FC24020008978500169787000A49
-:1064C0003C040800248457580E0005A1240600014E
-:1064D000978700128F8900142445000130A8FFFF20
-:1064E00024E3FFFF0109302B0040802114C0001875
-:1064F000A7830012A780000A978500180E000E10CF
-:1065000002002021244A05003144FFFF0E0005CE81
-:10651000240500013C05080094A500320E000E1071
-:1065200002002021244521003C0208009042003353
-:106530000A0005FC000521C00A000634A7840006F5
-:1065400024AC3800000C19C00A0005FAA784000426
-:106550000A00064EA785000A308400FF27BDFFE829
-:106560002C820006AFBF0014AFB000101040001521
-:1065700000A03821000440803C030800246353CC71
-:10658000010328218CA40000008000080000000006
-:1065900024CC007F000751C2000C59C23170FFFFAC
-:1065A0002547C40030E5FFFF2784000402003021A6
-:1065B0000E0004F624070001978600100206202131
-:1065C000A78400108FBF00148FB0001003E00008F4
-:1065D00027BD00183C0508008CA50030000779C2D3
-:1065E0000E0002F025E4DF003045FFFF3C04080008
-:1065F00024845758240600010E0004F624070001E5
-:10660000978E00128FBF00148FB0001025CD0001AF
-:1066100027BD001803E00008A78D00120007C9C2BB
-:106620002738FF00001878C231F0FFFF3C04080053
-:10663000248456D802002821240600010E0004F606
-:1066400024070001978D000E260E0100000E840025
-:1066500025AC00013C0B6000A78C000EAD603D082E
-:1066600036040006000030213C0760008CE23D0447
-:10667000305F000617E0FFFD24C9000100061B0083
-:10668000312600FF006440252CC50004ACE83D0421
-:1066900014A0FFF68FBF00148FB0001003E00008B5
-:1066A00027BD0018000751C22549C8002406000173
-:1066B000240700013C040800248456580E0004F608
-:1066C0003125FFFF9787000C8FBF00148FB000109B
-:1066D00024E6000127BD001803E00008A786000C8F
-:1066E0003084FFFF30A5FFFF3C0680008CC201B85C
-:1066F0000440FFFE3C084080008838253C03100021
-:10670000ACC00180ACC50184ACC7018803E00008BF
-:10671000ACC301B83084FFFF3C0680008CC201B8D6
-:106720000440FFFE3C0840388CA700000088282564
-:106730003C031000ACC70180ACC5018803E0000831
-:10674000ACC301B88F83005C8F8600541066000BC9
-:10675000008040213C07080024E75768000328C058
-:1067600000A710218C44000024630001108800055C
-:106770003063000F5466FFFA000328C003E00008EE
-:10678000000010213C07080024E7576C00A73021C7
-:1067900003E000088CC200003C039000346200015A
-:1067A000008220253C038000AC6400208C65002022
-:1067B00004A0FFFE0000000003E00008000000004D
-:1067C0003C028000344300010083202503E00008E0
-:1067D000AC44002027BDFFE0AFB100143091FFFFB3
-:1067E000AFB00010AFBF00181220001200A080212F
-:1067F0008CA5000014A00011240400023C068000B7
-:106800008CC201B80440FFFE3C074000022720254F
-:106810008FBF00188FB100148FB000103C03100020
-:1068200027BD0020ACC50180ACC4018803E000088E
-:10683000ACC301B80A00070F8CA500000E00066665
-:1068400024060200000028210A00070FAE00000005
-:106850003087FFFF3C0680008CC201B80440FFFE79
-:106860003C0A40068CA9000000EA4025ACC9018022
-:106870008CA400043C031000ACC40184ACC80188A3
-:1068800003E00008ACC301B88F83FDE827BDFFE833
-:10689000AFBF0014AFB00010906700080080102157
-:1068A0000080282130E600400000202110C00008B0
-:1068B0008C5000000E0000860200202102002021E2
-:1068C0008FBF00148FB000100A00048927BD001884
-:1068D0000E000724000000000E00008602002021A8
-:1068E000020020218FBF00148FB000100A0004891D
-:1068F00027BD001827BDFFE0AFB000108F90FDE866
-:10690000AFBF001CAFB20018AFB100149206000177
-:10691000008088210E0006F630D2000492040005A3
-:10692000001129C2A605000034830040A20300051F
-:106930000E000700022020210E00048B02202021DF
-:1069400024020001AE02000C02202821A602001041
-:1069500024040002A602001224060200A60200146B
-:106960000E000666A60200161640000F8FBF001C20
-:10697000978C00583C0B08008D6B00782588FFFF32
-:106980003109FFFF256A0001012A382B10E00006BB
-:10699000A78800583C0F6006240E001635ED001045
-:1069A000ADAE00508FBF001C8FB200188FB1001425
-:1069B0008FB0001003E0000827BD002027BDFFE0D6
-:1069C000AFBF0018AFB10014AFB000100E0006F654
-:1069D000008088218F85FDE80220202190A30005FA
-:1069E0000E000700307000FF2402003E1202000576
-:1069F0008FBF00188FB100148FB0001003E00008A3
-:106A000027BD00203C0580008CA401780480FFFE97
-:106A1000240700073C061000ACB1014002202021F1
-:106A2000A0A701448FBF00188FB100148FB00010D1
-:106A3000ACA601780A00074D27BD002027BDFFE066
-:106A4000AFB00010AFBF0018AFB100143C10800011
-:106A50008E110020000000000E00048BAE04002008
-:106A6000AE1100208FBF00188FB100148FB000103E
-:106A700003E0000827BD00203084FFFF3C068000B3
-:106A80008CC201B80440FFFE3C0840350088382520
-:106A90003C031000ACC50180ACC00184ACC70188C8
-:106AA00003E00008ACC301B83084FFFF3C0680005F
-:106AB0008CC201B80440FFFE3C08403600883825EF
-:106AC0003C031000ACC50180ACC00184ACC7018898
-:106AD00003E00008ACC301B827BDFFD0AFB5002468
-:106AE0003095FFFFAFB60028AFB40020AFBF002C39
-:106AF000AFB3001CAFB20018AFB10014AFB00010BC
-:106B000030B6FFFF12A000270000A0218F92003CAA
-:106B10008E4300003C0680002402004000033E0239
-:106B200000032C0230E4007F006698241482001DCC
-:106B300030A500FF8F83004C2C68000A5100001024
-:106B40008F860030000358803C0C0800258C53E8E9
-:106B5000016C50218D490000012000080000000058
-:106B600002D448213125FFFF0E0006C8240400840A
-:106B7000166000028F92003CAF80004C8F86003080
-:106B800026580020268F00010300902131F4FFFFDA
-:106B900014C00004AF98003C0295282B14A0FFDC21
-:106BA00000000000028010218FBF002C8FB600284B
-:106BB0008FB500248FB400208FB3001C8FB2001853
-:106BC0008FB100148FB0001003E0000827BD003023
-:106BD0002407003414A70146000000009247000E6D
-:106BE0008F99FDEC8F90FDE824181600A32700195B
-:106BF000924A000D3C0880003C07800CA32A001834
-:106C0000964400123C0F60003C117FFFA604005C1C
-:106C1000965F00103622FFFF240A000533E5FFFFD0
-:106C2000AE0500548E46001CAD1800288CE900000B
-:106C30008DEE44480126682601CD3021AE0600388D
-:106C40008E03003824CB00013C0E7F00AE03003CD5
-:106C50008E0C003CAF2C0004AE0B00208E130020E5
-:106C6000AE13001CA320001BAE02002CA32A0012AE
-:106C70008E44001424130050AE0400348E1F0034E0
-:106C8000AF3F00148E450018AE0500489258000C26
-:106C9000A218004E920F000835E90020A209000852
-:106CA0008E0D001801AE1824346C4000AE0C001894
-:106CB000920B0000317200FF125302AD2413FF80CB
-:106CC0003C040800248457E80E000732000000004E
-:106CD00024030004240800013C0508008CA557E8A3
-:106CE0003C048000A2030025A20800058C900178D6
-:106CF0000600FFFE8F92003C240E00023C0D1000A7
-:106D0000AC850140A08E0144AC8D01780A0007EFEC
-:106D1000AF80004C2CAD003711A0FF998F8600305A
-:106D2000000580803C1108002631541002117821A2
-:106D30008DEE000001C000080000000024100004D7
-:106D400014B0008E3C0780003C0C08008D8C57E886
-:106D50008F86FDE8ACEC00208E4B00088F98FDEC90
-:106D600024090050ACCB00308E430008ACC3005067
-:106D70008E42000CACC200348E4A0010ACCA0038FF
-:106D80008E440010ACC400548E5F0014ACDF003C95
-:106D90008E590018AF1900048E4F001CACCF002094
-:106DA00090D10000322500FF10A9027D00000000F4
-:106DB0008CD100348CCF0030022F302304C000F37C
-:106DC0002404008C126000F0240200030A0007EF84
-:106DD000AF82004C2418000514B800683C0B8000FA
-:106DE0003C0C08008D8C57E88F86FDE8AD6C0020C8
-:106DF0008E4300048F9FFDEC24072000ACC3001CD1
-:106E00009242000824120008A3E200198F8A003C75
-:106E100091440009A3E400188F85003C90B9000A52
-:106E2000332400FF1092001028880009150000BCD0
-:106E3000240D0002240900201089000B3407800073
-:106E4000289100211620000824074000240F00404C
-:106E5000108F00053C0700012418008010980002E4
-:106E60003C070002240740008CC400183C0AFF00C5
-:106E7000008AF82403E7C825ACD9001890B2000BAB
-:106E8000A0D200278F83003C9465000C10A0023133
-:106E9000000000009467000C3C1F8000A4C7005C49
-:106EA0009062000E2403FFBF24070004A0C2000864
-:106EB0008F8A003C9144000FA0C400098F88003CD9
-:106EC0008D1200108FF9007402592823ACC50058A8
-:106ED0008D180014ACD8002C950F001831F1FFFF6D
-:106EE000ACD100409509001A3130FFFFACD000440E
-:106EF0008D0E001CACCE0048950D0002A4CD00788C
-:106F0000910C000EA0CC000890CB00080163102467
-:106F1000126001D7A0C200088F92003C0A0007EF60
-:106F2000AF87004C2406000614A600143C0E800017
-:106F30003C1008008E1057E88F8CFDE4ADD0002087
-:106F40008E4D00188F86FDE88F8BFDECAD8D000017
-:106F50008CC8003824040005AD8800048CC3003CB4
-:106F600012600081AD6300000A0007EFAF84004C9F
-:106F70002409000710A9004B240400063C05080062
-:106F800024A557E80E000705240400818F92003CD9
-:106F90000013102B0A0007EFAF82004C241F0023C0
-:106FA00014BFFFF63C0C80003C0308008C6357E8DC
-:106FB0008F8BFDECAD8300208F91FDE88E460004A1
-:106FC0002564002026450014AE2600282406000370
-:106FD0000E000E1C257000308F87003C020020211F
-:106FE000240600030E000E1C24E500083C040800E3
-:106FF000248457E80E0007320000000092220000AF
-:1070000024040050304A00FF5544FFE18F92003CB9
-:107010000E000E07000000000A0008F48F92003CEA
-:107020002408003314A800323C0280003C11080000
-:107030008E3157E88F89FDECAC5100208E4A000854
-:10704000240F00288F8DFDE8AD2A00308E44000CFF
-:1070500024060009AD2400348E5F0010AD3F0038D7
-:107060008E590014AD3900208E450018AD2500243E
-:107070008E58001CAD380028A12F00118E4E000440
-:1070800012600031ADAE00288F92003C0A0007EF7D
-:10709000AF86004C2411002214B1FFB8000000009C
-:1070A000240400073C1808008F1857E83C0F8000A4
-:1070B000ADF800205660FEB1AF84004C3C040800DF
-:1070C000248457E80E000732241300508F99FDE8FE
-:1070D00093320000324500FF10B3016C0000000045
-:1070E0008F92003C000020210A0007EFAF84004C83
-:1070F0003C05080024A557E80E0006D524040081AD
-:107100000A0008F48F92003C02D498213265FFFFF8
-:107110000E0006C8240400840A0007EF8F92003C8A
-:10712000108DFF51240704002887000310E001AAF6
-:1071300024100004240E0001548EFF4B240740004D
-:107140000A0008AA240701003C05080024A557E806
-:107150000E000724240400828F92003C000030219E
-:107160000A0007EFAF86004C3C040800248457E86F
-:107170008CC200380E0007328CC3003C8F92003C5A
-:107180000A00094A00002021240400823C0508006E
-:1071900024A557E80E000724000000008F92003C51
-:1071A000000010210A0007EFAF82004C8E5000044F
-:1071B0008F91FDE83C0A8000AD500020922200052E
-:1071C000020028213046000214C001872404008AEE
-:1071D0008F92FDEC020028212404008D924B001BAD
-:1071E000316300201460018000000000922D00092E
-:1071F000240C001231A800FF110C017B2404008133
-:107200000E0006F6020020219245001B240E000409
-:107210000200202134A90042A249001B0E000700F1
-:10722000A22E00253C0480008C9101780620FFFEF0
-:1072300024180002AC900140A09801448F92003CB9
-:107240003C0F1000AC8F01780A0008F50013102BDA
-:107250008E5000048F91FDE83C1F8000AFF00020AD
-:1072600092390005020028213327000214E0001A99
-:107270002404008A922600092412001230C400FF60
-:10728000109201110000000092230009240A00045A
-:10729000306200FF104A010C000000000E0006F6EC
-:1072A000020020218F88FDEC240CFFFE020020212B
-:1072B000910E001B35CD0020A10D001BA23200094C
-:1072C000922B0005016C90240E000700A2320005ED
-:1072D00002002821000020210E0007BA0000000053
-:1072E0000A0008F48F92003C8E5100043C0280009A
-:1072F0003C100800261057E8AC5100203C01080063
-:10730000AC3157E89246000330C400041080016994
-:107310008F84FDE824020006A0820009924D001B24
-:107320002408FFC031AC003F01885825A08B00081D
-:1073300092430003306A0001154001600000000024
-:107340008E420008AE0200083C0208008C4257F052
-:107350001040015F8F8EFDEC000281C28F85FDE839
-:10736000A5D0000C8E5F000C240F0001240900142E
-:10737000ADDF002C8E590010ADD9001C96470016C9
-:10738000A5C7003C96580014A5D8003EACAF000C31
-:10739000A4AF0010A4AF0012A4AF0014A4AF001655
-:1073A00012600163A1C900119244000330920002EF
-:1073B0002E5300018F92003C266200080A0007EF5E
-:1073C000AF82004C8E4600043C0580003C048008DF
-:1073D000ACA600208E4700089089000024110050C0
-:1073E000312200FF105100BC240500883C048000BD
-:1073F0008C8F01B805E0FFFE0013802B3C1840097C
-:1074000000B81025AF90004C3C101000AC860180F5
-:10741000AC870184AC820188AC9001B80A0007F007
-:107420008F8600308E4500043C0680003C098008B1
-:10743000ACC50020913F00002404005033F900FF48
-:10744000132400B4240600883C0480008C8A01B810
-:107450000540FFFE3C0E400E00CE68253C081000A3
-:10746000AC850180AC800184AC8D0188AC8801B80A
-:10747000912B0000240CFF8024040004016C1825CB
-:10748000240600300E000666A12300000A0008F45E
-:107490008F92003C8E5000048F91FDEC3C0F8000D9
-:1074A000ADF000209225001B30A900101120007CB7
-:1074B000240300813C0480008C8701B804E0FFFEB7
-:1074C0003C1F401FAC900180007F10250013C82B8B
-:1074D0003C101000AC800184AF99004CAC82018854
-:1074E000AC9001B80A0007F08F8600308E44001C73
-:1074F0000E0006E100000000104000FC00403821B2
-:107500008F92003C240600893C0580008CAE01B8B7
-:1075100005C0FFFE00000000ACA701808E50001CDB
-:107520003C1140010013782B00D138253C1310008A
-:10753000ACB00184AF8F004CACA70188ACB301B8EC
-:107540000A0007F08F860030965900023C100800B0
-:10755000261057E833380004130000A73C046000ED
-:107560008E5F001C3C068000ACDF00203C01080060
-:10757000AC3F57E8964F000231E7000114E000E706
-:10758000000000008E420004AE0200083C1008001B
-:107590008E1057F0120000DD3C0680008F85FDE85C
-:1075A000241000018CBF00188F91FDEC8F89FDE441
-:1075B00003E6C825ACB90018A0A00005ACB0000CCB
-:1075C0003C1808008F1857F08F87003CA4B00010BB
-:1075D000001879C2A4B00012A4B00014A4B0001620
-:1075E000A62F000C8CEE00088F8D003C8F8C003C89
-:1075F000AE2E002C8DA8000C24070002AE28001C23
-:10760000918B0010A22B00118F83003C906A001117
-:10761000A12A00088F82003C90440012A0A4004ED2
-:107620008F92003C92460013A22600128F92003CDB
-:10763000965F0014A63F003C96590016A639003EFE
-:107640008E580018AE3800145660FD4CAF87004CC1
-:107650003C05080024A557E80E000705000020217E
-:107660008F92003C000038210A0007EFAF87004CE2
-:107670003C05080024A557E80E00072424040082D6
-:107680008F92003C0A0008D7000038210E000E0738
-:10769000000000008F92003C0A00094A00002021EF
-:1076A0000E0006F6020020219232001B020020216B
-:1076B000365800100E000700A238001B8F92003CC5
-:1076C0000A000A3D000018210E0007BA24040081B8
-:1076D0000A0008F48F92003C9243000C306A0001CB
-:1076E0001140000300000000964B000EA48B002CFC
-:1076F0009248000C310C00021180FF3C0000282150
-:10770000964E00128E4D0014A48E001A0A000A0B29
-:10771000AC8D001C8F83005C8F8700541067FF4A7C
-:10772000000030213C0808002508576C000320C0E9
-:10773000008830218CD10000122500C8246200018D
-:107740003043000F1467FFFA000320C00A000A222A
-:10775000000030213C05080024A557E80E0007244E
-:107760002404008B8F92003C0A0008D70013382BAA
-:107770003C0C08008D8C57E824D9FFFE25910100B0
-:10778000322B007F0167902102331024AD020028C4
-:10779000AE4600D0AE4000D40A000840AE59001CEE
-:1077A000ACC000543C0908008D2957E83C05800C0A
-:1077B00034A80100ACE900288E500014AD1000D0B0
-:1077C0008E4E0014AD0E00D48E4D001025A7FFFE86
-:1077D0000A00087CAD07001C5490FDA3240740005C
-:1077E0000A0008AA240710000E0007AE00000000DF
-:1077F0000A0008F48F92003C8C83442C3C05DEADDB
-:1078000034B2BEEF3C010800AC2057E81072004FC4
-:10781000000000003C046C6234827970146200083D
-:1078200024040002978A0058978300500200282100
-:107830000143482B11200019240400922404000263
-:107840000E0005D6240502003C0B8000AD6200202E
-:107850003C010800AC2257E81040000D8F8E003C20
-:10786000240C00282404000391CD001031A800FF4F
-:10787000550C0001240400010E00004A0000000025
-:1078800010400004240400830A000A6D8F92003C1B
-:10789000240400833C05080024A557E80E000705D2
-:1078A000000000008F92003C0013382B0A0007EF05
-:1078B000AF87004C0A0009D6240200128E4400084B
-:1078C0000E0006E1000000000A0009E2AE02000816
-:1078D0003C05080024A557E80E0006D524040087BF
-:1078E0008F92003C0A0009FF0013102B24040004AF
-:1078F0000E0005D624050030144000170040382142
-:107900008F92003C0A000A52240600833C050800BE
-:1079100024A557E80A000B37240400878E4400048E
-:107920000E0006E1000000000A000A73AE02000823
-:107930003C05080024A557E80E0007242404008213
-:107940008F92003C0A0009FF000010218C83442C18
-:107950000A000B163C046C628F92003C3C088008C5
-:107960003C0C8000240B0050240A0001AD82002052
-:10797000A10B0000A10A000192490004A10900180E
-:1079800092440005A1040019924300063C0408003B
-:107990002484576CA103001A924200073C0308009C
-:1079A00024635768A102001B92450008A105001C32
-:1079B00092460009A106001D925F000AA11F001E49
-:1079C0009259000BA119001F9258000CA118002019
-:1079D0009251000DA11100219250000EA110002221
-:1079E000924F000FA10F0023924E0010A10E002411
-:1079F000924D0011A10D0025964C0014A50C0028F5
-:107A0000964B00168F8A00548F98005CA50B002AB5
-:107A100096490018000A10C025450001A509002C50
-:107A20008E46001C0044C8210043F82130A5000FF9
-:107A3000AFE60000AF27000010B80003AF85005488
-:107A40000A000A520000302124AD000131A8000FC5
-:107A5000000030210A000A52AF88005C3C07080091
-:107A600024E7576800879021ACC000000000302157
-:107A70000A000A22AE4000003C0482013C03600080
-:107A800034820E02AC603D68AF80007C03E00008E9
-:107A9000AC623D6C27BDFFE8AFB000103090FFFF37
-:107AA000001018422C620041AFBF001414400002C5
-:107AB00024040080240300403C010800AC30006036
-:107AC0003C010800AC2300640E000E100060282169
-:107AD000244802BF2409FF800109282400103980AE
-:107AE000001030408FBF00148FB0001000A720217D
-:107AF00000861821AF8300643C010800AC250058C3
-:107B00003C010800AC24005C03E0000827BD00181D
-:107B1000308300FF30C6FFFF30E400FF3C088000E8
-:107B20008D0201B80440FFFE0003540001443825D3
-:107B30003C09600000E920253C031000AD050180F0
-:107B4000AD060184AD04018803E00008AD0301B86F
-:107B50008F86003C3C096012352700108CCB000456
-:107B60003C0C600E35850010316A00062D4800017E
-:107B7000ACE800C48CC40004ACA431808CC2000802
-:107B800094C30002ACA2318403E00008A783007410
-:107B90008F85003C8F87FF408F86FF488CAE0004A6
-:107BA0003C0F601235E80010ACEE00688CAD0008A8
-:107BB000ACED006C8CAC0010ACCC004C8CAB000C71
-:107BC000ACCB004894CA00543C0208008C420044EC
-:107BD00025490001A4C9005494C400543083FFFF18
-:107BE00010620017000000003C0208008C420040B8
-:107BF000A4C200528CA30018ACE300308CA2001485
-:107C0000ACE2002C8CB90018ACF900388CB8001428
-:107C100024050001ACF800348D0600BC50C50019E5
-:107C20008D0200B48D0200B8A4E2004894E400483C
-:107C3000A4E4004A94E800DA03E000083102FFFF00
-:107C40003C0208008C420024A4C00054A4C200528C
-:107C50008CA30018ACE300308CA20014ACE2002C22
-:107C60008CB90018ACF900388CB800142405000158
-:107C7000ACF800348D0600BC54C5FFEB8D0200B893
-:107C80008D0200B4A4E2004894E40048A4E4004A51
-:107C900094E800DA03E000083102FFFF8F86003C21
-:107CA0003C0480008CC900088CC80008000929C069
-:107CB000000839C0AC87002090C300073062000480
-:107CC0001040003AAF85007890CB0007316A000879
-:107CD000114000398F87FF448CCD000C8CCE0014EE
-:107CE00001AE602B11800032000000008CC2000C3D
-:107CF000ACE200708CCB00188F85FF408F88FF4866
-:107D0000ACEB00748CCA00102402FFF8ACAA00C8C7
-:107D10008CC9000CAD0900608CC4001CACA400C070
-:107D200090E3007C0062C824A0F9007C90D8000792
-:107D3000330F000811E000040000000090ED007C0B
-:107D400035AC0001A0EC007C90CF000731EE0001C3
-:107D500011C000090000000090E4007C241800021B
-:107D600034820002A0E2007C90A300EC307900FF96
-:107D7000133800132408003490C90007312600028C
-:107D800010C000040000000090EB007C356A000485
-:107D9000A0EA007C90ED007D31AC003FA0EC007DBE
-:107DA00094A700DA03E0000830E2FFFF8F87FF446A
-:107DB0000A000C4C8CC200140A000C4DACE00070A0
-:107DC0000A000C6EACA800CC8F8C003C27BDFFD8FD
-:107DD000AFB3001CAFB20018AFB00010AFBF0020AF
-:107DE000AFB10014918F00153C13600E3673001074
-:107DF00031EB000FA38B00808D8F00048D8B00086A
-:107E0000959F0012959900109584001A9598001E70
-:107E1000958E001C33EDFFFF332AFFFF3089FFFFF3
-:107E20003308FFFF31C7FFFF3C010800AC2D0024E1
-:107E30003C010800AC2900443C010800AC2A004089
-:107E4000AE683178AE67317C91850015959100164A
-:107E50003C1260123652001030A200FF3230FFFF99
-:107E6000AE623188AE5000B491830014959F001823
-:107E7000240600010066C80433F8FFFFAE5900B8BD
-:107E8000AE5800BC918E0014AF8F00683C086006AD
-:107E900031CD00FFAE4D00C0918A00159584000ED3
-:107EA0003C07600A314900FFAF8B006C3084FFFF54
-:107EB000AE4900C8351100100E000BB534F00410A7
-:107EC0003C0208008C4200603C0308008C630064A4
-:107ED0003C0608008CC600583C0508008CA5005CD8
-:107EE0008F8400648FBF0020AE23004CAE65319CB0
-:107EF000AE030054AE4500DCAE6231A0AE6331A4E7
-:107F0000AE663198AE2200488FB3001CAE0200501E
-:107F10008FB10014AE4200E0AE4300E4AE4600D89C
-:107F20008FB000108FB200180A0004BE27BD0028D1
-:107F3000978500769783006027BDFFE8AFB00010FB
-:107F400000A3102BAFBF0014240400058F90003C49
-:107F500010400055240900020E0005D68F850064EC
-:107F6000AF820078240400031040004F240900026F
-:107F70003C0680000E00004AACC20020240700012D
-:107F8000240820001040004D24040005978E007640
-:107F90008F8AFF442409005025C50001A78500767B
-:107FA000A14900003C0D08008DAD00642403800051
-:107FB0008F84FF40000D6600AD4C0018A540000600
-:107FC000954B000A8F85FF482402FF80016330240F
-:107FD000A546000A915F000A0000482103E2C82577
-:107FE000A159000AA0A00008A140004CA08000C533
-:107FF00096180002978300743C020004A49800DAEB
-:10800000960F00022418FFBF25EE2401A48E00AEB7
-:108010008E0D0004ACAD00448E0C0008ACAC0040EA
-:10802000A4A00050A4A000548E0B000C240C00301F
-:10803000AC8B00288E060010AC860024A480003E85
-:10804000A487004EA4870050A483003CAD42007476
-:10805000AC8800C8ACA80060A08700EC909F00C46A
-:1080600033F9007FA09900C4909000C402187824CE
-:10807000A08F00C4914E007C35CD0001A14D007C45
-:10808000938B0080AD480070AC8C00CCA08B00C6F8
-:108090008F88006C8F870068AC8800B4AC8700B80C
-:1080A000A5400078A540007A8FBF00148FB0001063
-:1080B0000120102103E0000827BD00188F850078FB
-:1080C0000E0006668F8600640A000D3A240900023D
-:1080D00027BDFFE0AFB000108F90003CAFB100149F
-:1080E000AFBF00188E0900040E00048B000921C0E8
-:1080F0008E0800048F84FF408F82FF48000839C03B
-:108100003C068000ACC70020948500DA9043001341
-:108110001460001C30B1FFFF8F8CFF44918B00086E
-:10812000316A00401540000B000000008E0D000475
-:10813000022030218FBF00188FB100148FB00010C3
-:108140002404002200003821000D29C00A000BD4AD
-:1081500027BD00200E000061000000008E0D00040D
-:10816000022030218FBF00188FB100148FB0001093
-:108170002404002200003821000D29C00A000BD47D
-:1081800027BD00200E000059000000008E0D0004E5
-:10819000022030218FBF00188FB100148FB0001063
-:1081A0002404002200003821000D29C00A000BD44D
-:1081B00027BD002027BDFFE0AFB200183092FFFFBF
-:1081C000AFB00010AFBF001CAFB100141240001ED2
-:1081D000000080218F86003C8CC50000240300062F
-:1081E00000053F020005140230E400071483001666
-:1081F000304500FF2CA80006110000400005588003
-:108200003C0C0800258C54EC016C50218D49000079
-:1082100001200008000000008F8E007C240D00016A
-:1082200011CD005024020002AF82007C260900011B
-:108230003130FFFF24C800200212202B0100302122
-:108240001480FFE5AF88003C020010218FBF001CA6
-:108250008FB200188FB100148FB0001003E0000837
-:1082600027BD00209387006254E0003400003021D5
-:108270000E000C82000000008F86003C0A000D9A60
-:10828000240200018F87007C2405000210E50031E4
-:1082900024040013000028210000302124070001DD
-:1082A0000E000BD4000000000A000D9B8F86003CDE
-:1082B0008F83007C240200021462FFF62404001263
-:1082C0000E000C37000000008F8500780040302140
-:1082D000240400120E000BD4000038210A000D9B6C
-:1082E0008F86003C8F83007C2411000310710029CD
-:1082F000241F0002107FFFCE260900012404001075
-:1083000000002821000030210A000DB824070001D8
-:108310008F91007C240600021626FFF92404001029
-:108320000E000CDC00000000144000238F98003C7D
-:108330008F86003C0A000D9A2402000324040014D6
-:108340000E000BD4000028218F86003C0A000D9AF5
-:10835000240200020E000D44000000000A000D9BE4
-:108360008F86003C0E000BE4000000002419000280
-:1083700024040014000028210000302100003821CE
-:10838000AF99007C0E000BD4000000000A000D9B8A
-:108390008F86003C0E000BF4000000008F850078F3
-:1083A000241900020040302124040010000038216C
-:1083B0000A000DF1AF99007C004038212404001020
-:1083C000970F0002000028210E000BD431E6FFFFBA
-:1083D0008F86003C0A000D9BAF91007C8F84FF4488
-:1083E0003C077FFF34E6FFFF8C8500182402000164
-:1083F00000A61824AC83001803E00008A082000542
-:108400003084FFFF30A5FFFF108000070000182117
-:108410003082000110400002000420420065182153
-:108420001480FFFB0005284003E0000800601021D5
-:1084300010C00007000000008CA2000024C6FFFF4F
-:1084400024A50004AC82000014C0FFFB24840004B7
-:1084500003E000080000000010A0000824A3FFFFB4
-:10846000AC86000000000000000000002402FFFFB6
-:108470002463FFFF1462FFFA2484000403E0000871
-:1084800000000000000411C003E000082442024084
-:1084900027BDFFE8AFB0001000808021AFBF0014FF
-:1084A0000E000E3100A0202100504821240AFF8038
-:1084B0008FBF00148FB00010012A30243127007FB5
-:1084C0003C08800A3C04210000E8102100C4282553
-:1084D0003C03800027BD0018AC650024AF8200205B
-:1084E000AC400000AC65002403E00008AC40004054
-:1084F0003C0D08008DAD005800056180240AFF8006
-:1085000001A45821016C4821012A30243127007F21
-:108510003C08800C3C04210000E8102100C4282500
-:108520003C038000AC650028AF82001C03E000081B
-:10853000AC40002430A5FFFF3C0680008CC201B88F
-:108540000440FFFE3C08601500A838253C031000DD
-:10855000ACC40180ACC00184ACC7018803E0000852
-:10856000ACC301B83C0D08008DAD0058000561801A
-:10857000240AFF8001A45821016C4021010A4824EB
-:10858000000931403107007F00C728253C04200046
-:1085900000A418253C028000AC43083003E000082A
-:1085A000AF80001C27BDFFE8AFB000100080802125
-:1085B000AFBF00140E000E3100A020210050482152
-:1085C000240BFF80012B5024000A39403128007F02
-:1085D0003C0620008FBF00148FB0001000E8282553
-:1085E00034C2000100A218253C04800027BD0018F9
-:1085F000AC83083003E00008AF8000203C05800811
-:108600008CA700603C0680080087102B14400011E6
-:108610002C8340008CA800602D0340001060000FE8
-:10862000240340008CC900600089282B14A000029C
-:10863000008018218CC3006000035A42000B308078
-:108640003C0A0800254A554000CA202103E00008E2
-:108650008C8200001460FFF32403400000035A42A0
-:10866000000B30803C0A0800254A554000CA2021F2
-:1086700003E000088C8200003C05800890A60008FA
-:108680009384009024C20001304200FF3043007FF9
-:108690001064000C00023827A0A200083C048000EF
-:1086A0008C85017804A0FFFE8F8A008824090002CF
-:1086B0003C081000AC8A0140A089014403E0000896
-:1086C000AC8801780A000EB630E2008027BDFFC8F2
-:1086D0003C05800834A40080AFBF0034AFBE00303A
-:1086E000AFB7002CAFB60028AFB50024AFB4002060
-:1086F000AFB3001CAFB20018AFB10014AFB00010A0
-:10870000948300789482007A104300CD2405FFFF03
-:108710003C1E80080080B8210A000F923C168000A1
-:10872000108A00C88FBF00348F8400883C0B08007B
-:108730008D6B005C240AFF803C07800E01644021A1
-:10874000010A4824AEC9002C96E6007A3102007F67
-:108750000047182130C57FFF000580400203A82193
-:1087600096BF00003C1908008F390058240FFF8085
-:1087700033F53FFF032488210015C1800238902182
-:10878000024F58243C0C0100016C5025324E007FF2
-:108790003C0D800C01CD9021028028210E000E346A
-:1087A000AECA00288E4800108E4900308F86002007
-:1087B0002402000201093823AE470010A0C20000C5
-:1087C00096E3005C8E4400308F9100200E000E8FE7
-:1087D0003070FFFF00022B800205C8253C1F4200BD
-:1087E000033FC025AE3800048E5100048F8700205F
-:1087F0008E4F000024080008ACF1001CACEF0018FC
-:10880000ACE0000CACE000109250000A2406000519
-:108810002405C000320E00FFA4EE0014964D00089F
-:1088200002E09821A4ED0016924C000A3C0D80084D
-:10883000318B00FFA4EB00209644000835AC01000A
-:10884000A4E40022ACE00024924A000B314900FF6E
-:10885000A4E90002A0E800018E4200308F830020CE
-:108860002408FFBFAC620008A06600308F8E002095
-:108870002403FFDF95DF003203E5C8240335C0255C
-:10888000A5D8003291D10032322F003F35F00040A0
-:10889000A1D000328F890020AD2000348D8B00C024
-:1088A000AD2B00389124003C3C0B7FFF308A007FC9
-:1088B000A12A003C8F8600203564FFFF90C7003C52
-:1088C00000E81024A0C2003C8F9900209325003CB2
-:1088D00000A3F824A33F003C8E5800348F8C002066
-:1088E000AD9800408E4F002C8E51003001F1802356
-:1088F000AD900044918E004831CD007FA18D00489D
-:108900008F8500208E4A00308CA900480144402405
-:108910000136382400E83025ACA600489242000A0F
-:10892000A0A2004C964300088F9F0020A7E3004EB2
-:108930008E5000308E4400300E0002F08FC5006073
-:1089400092F1007C0002C1400002C90003197821A5
-:10895000322E00020040282111C00003020F8021A6
-:108960000002208002048021926D007C31AC000462
-:108970001180000200057080020E80218E440030BC
-:108980008F87002024058000308B0003000B5023CC
-:108990003149000302094021ACE800349664007AB2
-:1089A0009662007A9670007A30467FFF24C30001F9
-:1089B000307F7FFF0205C824033FC025A678007AD8
-:1089C0009671007A3C1208008E520060322F7FFFB1
-:1089D00011F20028000000008F8400880E000E694C
-:1089E00002A028218F8400880E000E7902802821A1
-:1089F0000E000EAE0000000096F3007896F4007AA8
-:108A00001293000F000028213C0980083524010042
-:108A100093C80008908700C53114007F30E400FF40
-:108A20000284302B14C0FF3E268A0001938D0090F3
-:108A3000268B0001008D6021158BFF3C8F84008800
-:108A40008FBF00348FBE00308FB7002C8FB6002848
-:108A50008FB500248FB400208FB3001C8FB2001894
-:108A60008FB100148FB0001000A0102103E00008A7
-:108A700027BD0038967F007A03E5C824A679007ADE
-:108A80009278007A926E007A331100FF001179C259
-:108A9000000F9027001269C031CC007F018D28257E
-:108AA000A265007A0A000F878F8400883C0380004B
-:108AB0003084FFFF30A5FFFFAC640018AC65001CDC
-:108AC00003E000088C62001427BDFFA83C06800864
-:108AD000AFBF0054AFBE0050AFB7004CAFB60048B8
-:108AE000AFB50044AFB40040AFB3003CAFB2003804
-:108AF000AFB10034AFB0003034C80100910500C5FB
-:108B000090C700083084FFFF30A500FF30E2007FEF
-:108B10000045182AAFA40010A7A000181060009C00
-:108B2000AFA0001490CA00083149007F00A930238B
-:108B300024D4FFFF0014882B8FB300100013902B58
-:108B400002328024520000858FB400143C03800858
-:108B500094790052947E00508FB60010033EC023DB
-:108B60000018BC00001714030016FC0002C2A82A5B
-:108B700016A00002001F2C030040282100143C0016
-:108B80000007240300A4102A5440000100A0202163
-:108B90002885000914A000020080B02124160008D6
-:108BA0003C0C80088D860048001659808D88004C4A
-:108BB0003C0380003169FFFF3C0A0010012A202598
-:108BC00034700400AC660038AF90008CAC68003C98
-:108BD000AC64003000000000000000000000000055
-:108BE0000000000000000000000000000000000085
-:108BF000000000008C6E000031CD002011A0FFFDB0
-:108C00000016902A0251782411E000360000B821A5
-:108C10003C1580003C118008922200088EA40100BF
-:108C200000008821305E007F0E000E3403C0282132
-:108C30008E1F00108EA4010033F93FFF032028216E
-:108C40000E000E4CAFB9001C921800003302003F1A
-:108C50002C5300085260000D000080212405000103
-:108C6000004518043067005D14E000B18F92008C5D
-:108C7000306400021480014D8F86008C30680080C3
-:108C80005500004A96180012000080218EA40100B1
-:108C90000E000E698FA5001C8EA401000E000E7937
-:108CA00003C028211200004F3C07800826E4000181
-:108CB0008F8C008C0004BC000291A0230017BC0321
-:108CC00002F6302A0014882B259F00402412000150
-:108CD00000D1F02403E08021AF9F008C17C0FFCDAE
-:108CE000AFB200143C07800894E800508FB3001026
-:108CF0003C05800002E810213C0D0020A4E2005059
-:108D0000ACAD003094F5005094F600520277502339
-:108D10003149FFFF12D50041AFA900108CF6004C7D
-:108D2000001749808CF7004802C9F8210000202173
-:108D300003E9302B02E4602101868021ACFF004C66
-:108D4000ACF000488FB300100013902B0232802447
-:108D50001600FF7F3C0380088FB400148FBF0054BF
-:108D60008FBE00503A8200018FB7004C8FB600488A
-:108D70008FB500448FB400408FB3003C8FB20038F1
-:108D80008FB100348FB0003003E0000827BD0058D9
-:108D900090CF0008938C009031EE007F00AE6823E6
-:108DA000018D58210A000FDD2574FFFF8F84008894
-:108DB00024100001A7B800180E000E5D97A500183A
-:108DC0008EA401000E000E698FA5001C8EA4010068
-:108DD0000E000E7903C028211600FFB526E400011D
-:108DE0003C07800894E800508FB300103C058000D9
-:108DF00002E810213C0D0020A4E20050ACAD003090
-:108E000094F5005094F60052027750233149FFFF49
-:108E10000014882B16D5FFC1AFA9001094FE005492
-:108E20008CF0004433D8FFFE001878C0020F702188
-:108E3000ACAE003C8CF900448CA3003C03235823C7
-:108E4000196002EA000000008CF200402642000196
-:108E5000ACA200383C05005034A700103C03800051
-:108E6000AC670030000000000000000000000000BF
-:108E700000000000000000000000000000000000F2
-:108E8000000000008C7F000033E6002010C0FFFDD2
-:108E90003C108008960D00543C1780003C0680086A
-:108EA00031B30001001350C00157B0218EC9040036
-:108EB0003C0708008CE700443C040020ACC9004893
-:108EC0008ED50404240C0001ACD5004C10EC02D06B
-:108ED000AEE40030961800523C0508008CA5004016
-:108EE00000B87821A60F0052960E005425C3000149
-:108EF000A6030054961900543324FFFF5487FF0F34
-:108F00008FB3001030A5FFFF0E000FBBA60000546A
-:108F10003C0508008CA50024961200520045382319
-:108F20000247F023A61E00520A000FDF8FB3001085
-:108F30008F93001C3C0700808E4400283C1FFFEFED
-:108F400037F9FFFFAE6400008E420024A260000AE1
-:108F50003C0FFF9FAE6200049245002C35EEFFFFF0
-:108F60003C0C0040A265000C8E71000CA265000B49
-:108F70003C0600FF0227C0250319682401AE5824CF
-:108F8000016C5025AE6A000C8E490004AE600018DA
-:108F900034D0FFFFAE6900148E48002C8F82008809
-:108FA000A660000801102024AE6400108E51000855
-:108FB00096470012AE7100208E58000C30E33FFF40
-:108FC00000032980AE7800248E4C001400A2F82102
-:108FD00030F90001AE6C00288E4B0018001F71C2E2
-:108FE00000197B80AE6B002C8E49001C01CF6821DC
-:108FF000A66D001CAE690030964A00028E46002025
-:10900000A66A001EAE66003492430033307000043E
-:1090100056000006924B00003C06800834D0010048
-:109020008E0800C0AE680030924B00008F8A00208E
-:10903000A14B0030924900333123000250600007F9
-:10904000924400018F8C0020240FFF80918E00300D
-:1090500001CF6825A18D0030924400018F8200204D
-:109060002418FFBF240AFFDFA04400318F9900209D
-:109070003C088008350400809331003C323F007F7B
-:10908000A33F003C8F8D002091AF003C01F870247D
-:10909000A1AE003C8F8700208E6C001490E3003C52
-:1090A0002D8B0001000B4940006A302400C9802547
-:1090B000A0F0003C964500128F870020A4E5003206
-:1090C0008E450004909F007C30A20003000288239C
-:1090D0003239000300B9102133F8000217000002F2
-:1090E00024440034244400303C038008346600806B
-:1090F00090C9007C00A980243208000415000002F9
-:1091000024830004008018218F840020240800029A
-:10911000ACE30034A08800009242003F8F9F002003
-:109120003C188008370F0080A3E200018F910020D7
-:109130009259003F8E440004A639000295EE005C6F
-:109140000E000E8F31D0FFFF00026B80020D5825FC
-:109150003C0C4200016C2825AE2500048E4A0038E4
-:109160008F850020ACAA00188E470034ACA7001CE5
-:10917000ACA0000CACA00010A4A00014A4A0001689
-:10918000A4A00020A4A00022ACA000248E620014A1
-:109190005040000124020001ACA200080E000EAEF7
-:1091A000241100010A0010332410000190D30001A3
-:1091B000327200201240018A241000013C0A80080B
-:1091C0003547008090E3007C8F93001CAFA0002403
-:1091D0003069000111200011AFB000203C0580086B
-:1091E0008CCB00148CAC0060016C882B1620000323
-:1091F000016028213C1080088E0500603C0F80082B
-:1092000035E300808C6E007000AE682B15A0000264
-:1092100000A020218C640070AFA400248F82FF4C3A
-:109220008CC400148C5900700099C02B53000001AD
-:109230008C4400708FA200240082F82313E0000306
-:10924000AFBF002824040002AFA400208FB200208A
-:109250000292402B1500015B000018218CC50038DC
-:109260008E6B000C3C0C0080AE6500008CC9003495
-:109270003C11FF9F016C5025AE69000490C8003F6F
-:109280003623FFFF014310243C1200203C04FFEF73
-:10929000A268000B00523825349FFFFF00FFC02456
-:1092A0003C1900088F87008C03197825AE6F000CDD
-:1092B0008CED0014AE6000188FB10024AE6D001468
-:1092C0008CF000188FAE0028AE70001C8CE50008F2
-:1092D000022E6021AE6500248CEB000CA6600038E5
-:1092E000A660003AAE6C002CAE600028AE6B002089
-:1092F0008CEA00148FA30028015148230123302356
-:1093000010C00011AE66001090E9003D8E620004AE
-:109310008E7F00000009910000527821000020217A
-:1093200001F2C82B03E4C02103197021AE6F0004C1
-:10933000AE6E000090ED003DA26D000A8F90008C93
-:1093400096060006A66600088F98002024190002E1
-:109350003C0F80088FA4002435EE0080A319000084
-:1093600095CD005C8F9200200E000E8F31B0FFFF74
-:1093700000022B80020560253C0642008F85008C90
-:1093800001865825AE4B00048F8400208CB1003834
-:10939000AC9100188CA30034AC83001CAC80000C92
-:1093A000AC800010A4800014A4800016A4800020CB
-:1093B000A4800022AC80002490AA003F8FA7002444
-:1093C000A48A000210E0000C240900018FBF0028CD
-:1093D00053E0018890A2003D90A2003E2448000185
-:1093E000A08800018F8500208FA40024ACA4000871
-:1093F0000A0012133C118008A08900018F8500200B
-:1094000024020001ACA200083C1180083623008031
-:10941000906A007C3147000214E000022406003408
-:10942000240600308F8D008C3C0F800835EE0080C4
-:1094300091AC000091C8007C8FB00024A0AC00303B
-:109440008F91008C8F8200208FAA00249227000128
-:1094500032120003240B0004A047003101721823CC
-:109460008F84008C8F8B0020241FC00094980012E2
-:109470009579003230690003330F3FFF033F7024BA
-:1094800001CF6825A56D00329165003200CA3021F8
-:1094900000C9302130B0003F360C0040A16C0032D2
-:1094A0008FB2002431070004124000028F85002093
-:1094B00000C730213C048008ACA600343488010089
-:1094C0008D1900C08FBF0024240DFFBFACB9003838
-:1094D00090AF003C2FF800012412FFDF31EE007F37
-:1094E000A0AE003C8F8B0020001889409170003C9A
-:1094F000020D6024A16C003C8F87002090E3003CAB
-:109500000072502401511025A0E2003C8F88008C8D
-:109510008F9900208D090020AF2900408D0600247E
-:10952000AF2600448D040028AF2400488D1F002C76
-:10953000AF3F004C0E000EAE000000008FB80020C0
-:10954000240500025705009F8FA300203C1F8000C8
-:109550003C1280088FE40100925800088F92FF4C63
-:109560000E000E343305007F8F8E00208FAF002059
-:109570008FA40028A1CF00009659005C8F91002095
-:109580000E000E8F3330FFFF00025B80020B682558
-:109590003C0842008F8B008C01A83025AE260004C9
-:1095A0008D7000388F8600200000282100051100F2
-:1095B000ACD000188D6C00343C047FFF3488FFFF72
-:1095C000ACCC001C9171003E8CCA001C8CDF0018D2
-:1095D0000011390000111F02014770210043482586
-:1095E00001C7C02B03E9782101F8C821ACCE001CCB
-:1095F000ACD90018ACC0000CACC00010916D003E9E
-:109600008FAA002824070005A4CD0014957000043B
-:109610002418C0000148C824A4D00016916C003E54
-:1096200001402021A4CC002095650004A4C500229F
-:10963000ACC000249163003FA4C300029171003DBF
-:1096400026220001A0C200018F8900203C02800870
-:1096500034460100AD2A0008A12700308F91002078
-:109660008F9F008C2402FF80962F003297EE00120D
-:10967000030F802431CD3FFF020D6025A62C003260
-:10968000922500322418FFBF2410FFDF30AB003FCB
-:1096900035630040A22300328F9F00202403FFFF88
-:1096A000AFE000348CCA00C0AFEA003893E7003C5A
-:1096B00030E9007FA3E9003C8F8D00203C09800049
-:1096C00091AF003C01F87024A1AE003C8F8B0020CC
-:1096D000916C003C01902824A165003C8F870020FC
-:1096E000ACE300408FB100243C038008ACF100449F
-:1096F00090EA004801423025A0E600488F90002003
-:109700008F8E008C8E1F004803E9C0240319782532
-:10971000AE0F004891CD003EA20D004C8F8C008C06
-:109720008F8B002095850004A565004E0E0002F089
-:109730008C650060924A007C004028218FA600289A
-:109740000002114000058900005138213149000212
-:109750001120000300C71821000520800064182193
-:109760003C028008344A00809147007C30E90004C4
-:10977000112000038FB9002800056080006C1821BB
-:10978000240B00048F91002033300003017040232C
-:10979000310D0003006D3021AE2600343C038008FB
-:1097A000A66500383C0580008CA401009073000879
-:1097B0000E000E793265007F0E000EAE0000000034
-:1097C0008FA300200003782B000F80230290A02499
-:1097D00000608021006088210A0010330010802B77
-:1097E0008F91001C8CD8003824190003A620000893
-:1097F000AE3800008CCF0034A220000A8F8E008C7F
-:10980000AE2F00043C05008091CB003FA239000C34
-:109810008E28000C3C0DFF9FA22B000B010510258C
-:1098200035A3FFFF3C13FFEF8F8E008C00433824DD
-:10983000366AFFFF00EA4824AE29000C8DC40014EC
-:1098400095D800128F860088AE2400108DCC0014AD
-:10985000AE200018AE200020AE2C0014AE20002454
-:109860008DDF0018330C3FFF000C9180AE3F0028C5
-:109870008DCF00080246C821330B0001AE2F003007
-:109880008DC3000C8F930020001941C2000B2B8068
-:1098900001056821240200023C0A8008A62D001C54
-:1098A000A6200034AE23002C35470080A2620000C1
-:1098B00094E9005C8F9900203C044200313FFFFF97
-:1098C00003E43025AF2600048F98008C240E00019D
-:1098D0002402C0008F12003824060034AF32001872
-:1098E0008F0F00343C12800836580080AF2F001CC8
-:1098F000AF20000CAF200010A7200014A7200016F6
-:10990000A7200020A7200022AF200024A7300002BB
-:10991000A32E00018F8D00208F8B008CADB000082E
-:1099200091680000A1A800308F91008C8F830020E7
-:1099300092250001A06500318F9F002097F300322F
-:1099400002625024014C3825A7E7003293E9003227
-:109950003124003FA3E40032930F007C31EE00027B
-:1099600015C000028F840020240600303C0E8008C1
-:10997000AC86003435D101008E3900C02403FFBF0E
-:1099800002008821AC990038908B003C0010802B9D
-:109990003165007FA085003C8F8D002091A8003CA0
-:1099A00001031024A1A2003C8F87002090F3003C0B
-:1099B000366A0020A0EA003C8F9F008C8F92002026
-:1099C0008FE90020AE4900408FE40024AE440044FB
-:1099D0008FEC0028AE4C00488FE6002C0E000EAE37
-:1099E000AE46004C0A001033000000000A0010A42C
-:1099F0008CE2004024480001A08800018F850020EF
-:109A00008FA40024ACA400080A0012133C118008A3
-:109A100094CB00523C0808008D080024010B102153
-:109A2000A4C200520A000FDF8FB3001027BDFFE071
-:109A30003C0D8008AFB20018AFB00010AFBF001CE3
-:109A4000AFB1001435B200808E4C001835A801006B
-:109A5000964B000695A70050910900EC000C5602A9
-:109A6000016728233143007F312600FF24020003D1
-:109A7000A3830090AF84008810C2001B30B0FFFFAA
-:109A8000910600EC2412000530C200FF1052003392
-:109A900000000000160000098FBF001C8FB20018E4
-:109AA0008FB100148FB00010240D0C003C0C80000E
-:109AB00027BD002003E00008AD8D00240E000FC27A
-:109AC000020020218FBF001C8FB200188FB100143C
-:109AD0008FB00010240D0C003C0C800027BD00202E
-:109AE00003E00008AD8D0024965800789651007A66
-:109AF000924E007D0238782631E8FFFF31C400C065
-:109B0000148000092D11000116000037000000002C
-:109B10005620FFE28FBF001C0E000EC300000000A5
-:109B20000A0013B78FBF001C1620FFDA00000000E8
-:109B30000E000EC3000000001440FFD88FBF001CB1
-:109B40001600002200000000925F007D33E2003F1B
-:109B5000A242007D0A0013B78FBF001C950900DAEE
-:109B60008F86006400802821240400050E0006660C
-:109B70003130FFFF978300763C0480002465FFFFAF
-:109B8000A78500768C8A01B80540FFFE0000000022
-:109B9000AC8001808FBF001CAC9001848FB2001894
-:109BA0008FB100148FB000103C0760133C0B100005
-:109BB000240D0C003C0C800027BD0020AC870188E0
-:109BC000AC8B01B803E00008AD8D00240E000FC27D
-:109BD000020020215040FFB18FBF001C925F007D2A
-:109BE0000A0013E433E2003F0E000FC202002021FE
-:109BF0001440FFAA8FBF001C1220000700000000C5
-:109C00009259007D3330003F36020040A242007D71
-:109C10000A0013B78FBF001C0E000EC30000000027
-:109C20005040FF9E8FBF001C9259007D3330003F93
-:109C30000A00141336020040000411C003E00008BB
-:109C4000244202403C050006008510253C038000AC
-:109C5000AC620030000000000000000000000000C6
-:109C60003C0580008CA7000030E6001010C0FFFD0E
-:109C7000000000008CAB003C8CAA003C0164482131
-:109C8000012A402B110000043C0680008CAD0038F6
-:109C900025AC0001ACAC00388CCF003C01E4702155
-:109CA00003E00008ACCE003C27BDFFD0AFB20018E7
-:109CB000AFB00010AFBF0028AFB50024AFB4002094
-:109CC000AFB3001CAFB1001400A0902114A000128B
-:109CD000008080218F8200240002188014600037E9
-:109CE000240400100E001421000000008FBF002883
-:109CF0008FB500248FB400208FB3001C8FB20018E2
-:109D00008FB100148FB000100000102127BD00306B
-:109D100003E00008AF80002410A0001E000088218E
-:109D20003C138000241400200A0014603C15000538
-:109D3000263100040232502B11400017024010213E
-:109D40008F8800248E0700002404008000084880CB
-:109D50000133182125060001AC6704002610000419
-:109D600014D4FFF3AF8600240E001421000000007D
-:109D7000AE75003000000000000000000000000090
-:109D800000000000263100040232502B1540FFEC89
-:109D9000AF800024024010218FBF00288FB500241F
-:109DA0008FB400208FB3001C8FB200188FB1001445
-:109DB0008FB0001003E0000827BD0030000320230F
-:109DC0003085000F0A0014490065202127BDFFD807
-:109DD0003C03800000A03821AC670038AFB100140C
-:109DE000AC66003C008088213C060022AC66003056
-:109DF000AFB00010AC7100283C10800C3C04800C0B
-:109E000024050070AFBF0024AFB40020AFB3001C26
-:109E10000E00143AAFB20018260400800E00143A67
-:109E200024050080260401000E00143A240500F0E9
-:109E30003C0208008C4200641040001300008021A6
-:109E40003C1480002413FF803C12800C0E00141E72
-:109E50000200202100514821312A007F0133402493
-:109E60000152202124050050AE8800280E00143A2B
-:109E7000261000013C0508008CA500640205202B7B
-:109E80001480FFF2000000003C0608008CC6006051
-:109E900010C00015000080213C1480002413FF80B6
-:109EA0003C12800C3C1908008F3900580010C1800A
-:109EB000240500400331782101F8682131AE007F8C
-:109EC00001B3602401D22021AE8C00280E00143A88
-:109ED000261000013C0608008CC600600206582BC4
-:109EE0001560FFF0000000003C1008008E10005CC0
-:109EF0002414FF803C1F800C0211982102749024CE
-:109F00003262007F3C118000005F2021AE320028C9
-:109F10000E00143A000628408FBF00248FB40020A2
-:109F20008FB3001C8FB200188FB100148FB00010D7
-:109F300000002021000028210A00143A27BD002833
-:109F40008F83003C8C62000410400003000000007E
-:109F500003E00008000000008C6400108C6500081D
-:089F60000A0014838C66000C5A
-:089F6800000000000000001BD6
-:109F70000000000F0000000A0000000800000006BA
-:109F800000000005000000050000000400000004BF
-:109F900000000003000000030000000300000003B5
-:109FA00000000003000000020000000200000002A8
-:109FB0000000000200000002000000020000000299
-:109FC0000000000200000002000000020000000289
-:109FD0000000000200000002000000020000000279
-:0C9FE00000000001000000010000000172
-:049FEC0080080100E8
-:109FF0008008008080080000080017900800179073
-:10A00000080017C8080017C8080017DC080017ACBC
-:10A0100008001A04080019D008001A5C08001A5C2D
-:10A0200008001AE408001A148008024008002154AD
-:10A0300008001FA00800217C0800221408002364E7
-:10A04000080023B0080024D4080023DC08002460A2
-:10A0500008002010080029880800292C08001FBCCF
-:10A0600008001FBC08001FBC080025480800254840
-:10A0700008001FBC08001FBC0800280408001FBC03
-:10A0800008001FBC08001FBC08001FBC0800286493
-:10A0900008001FBC08001FBC08001FBC08001FBC34
-:10A0A00008001FBC08001FBC08001FBC08001FBC24
-:10A0B00008001FBC08001FBC08001FBC08001FBC14
-:10A0C00008001FBC08001FBC080023D008001FBCEC
-:10A0D00008001FBC080028D408001FBC08001FBCD3
-:10A0E00008001FBC08001FBC08001FBC08001FBCE4
-:10A0F00008001FBC08001FBC08001FBC08001FBCD4
-:10A1000008001FBC08001FBC08001FBC08001FBCC3
-:10A1100008001FBC08001FBC08001FBC080027283F
-:10A1200008001FBC08001FBC08002690080025EC92
-:10A130000800375008003724080036F0080036C4FD
-:10A14000080036A408003658800801008008008006
-:08A15000800800008008008077
-:08A158000A000C760000000073
-:10A16000000000000000000D727870342E362E3191
-:10A17000360000000406100300000000000000018B
-:10A1800000000000000000000000000000000000CF
-:10A1900000000000000000000000000000000000BF
-:10A1A00000000000000000000000000000000000AF
-:10A1B000000000000000000000000000000000009F
-:10A1C000000000000000000000000000000000008F
-:10A1D000000000000000000000000000000000007F
-:10A1E000000000000000000000000000000000006F
-:10A1F000000000000000000000000000000000005F
-:10A20000000000000000000000000000000000004E
-:10A21000000000000000000000000000000000003E
-:10A22000000000000000000000000000000000002E
-:10A23000000000000000000000000000000000001E
-:10A24000000000000000000000000000000000000E
-:10A2500000000000000000000000000000000000FE
-:10A2600000000000000000000000000000000000EE
-:10A2700000000000000000000000000000000000DE
-:10A2800000000000000000000000000000000000CE
-:10A2900000000000000000000000000000000000BE
-:10A2A00000000000000000000000000000000000AE
-:10A2B000000000000000000000000000000000009E
-:10A2C000000000000000000000000000000000008E
-:10A2D000000000000000000000000000000000007E
-:10A2E000000000000000000000000000000000006E
-:10A2F000000000000000000000000000000000005E
-:10A30000000000000000000000000000000000004D
-:10A31000000000000000000000000000000000003D
-:10A32000000000000000000000000000000000002D
-:10A33000000000000000000000000000000000001D
-:10A34000000000000000000000000000000000000D
-:10A3500000000000000000000000000000000000FD
-:10A3600000000000000000000000000000000000ED
-:10A3700000000000000000000000000000000000DD
-:10A3800000000000000000000000000000000000CD
-:10A3900000000000000000000000000000000000BD
-:10A3A00000000000000000000000000000000000AD
-:10A3B000000000000000000000000000000000009D
-:10A3C000000000000000000000000000000000008D
-:10A3D000000000000000000000000000000000007D
-:10A3E000000000000000000000000000000000006D
-:10A3F000000000000000000000000000000000005D
-:10A40000000000000000000000000000000000004C
-:10A41000000000000000000000000000000000003C
-:10A42000000000000000000000000000000000002C
-:10A43000000000000000000000000000000000001C
-:10A44000000000000000000000000000000000000C
-:10A4500000000000000000000000000000000000FC
-:10A4600000000000000000000000000000000000EC
-:10A4700000000000000000000000000000000000DC
-:10A4800000000000000000000000000000000000CC
-:10A4900000000000000000000000000000000000BC
-:10A4A00000000000000000000000000000000000AC
-:10A4B000000000000000000000000000000000009C
-:10A4C000000000000000000000000000000000008C
-:10A4D000000000000000000000000000000000007C
-:10A4E000000000000000000000000000000000006C
-:10A4F000000000000000000000000000000000005C
-:10A50000000000000000000000000000000000004B
-:10A51000000000000000000000000000000000003B
-:10A52000000000000000000000000000000000002B
-:10A53000000000000000000000000000000000001B
-:10A54000000000000000000000000000000000000B
-:10A5500000000000000000000000000000000000FB
-:10A5600000000000000000000000000000000000EB
-:10A5700000000000000000000000000000000000DB
-:10A5800000000000000000000000000000000000CB
-:10A5900000000000000000000000000000000000BB
-:10A5A00000000000000000000000000000000000AB
-:10A5B000000000000000000000000000000000009B
-:10A5C000000000000000000000000000000000008B
-:10A5D000000000000000000000000000000000007B
-:10A5E000000000000000000000000000000000006B
-:10A5F000000000000000000000000000000000005B
-:10A60000000000000000000000000000000000004A
-:10A61000000000000000000000000000000000003A
-:10A62000000000000000000000000000000000002A
-:10A63000000000000000000000000000000000001A
-:10A64000000000000000000000000000000000000A
-:10A6500000000000000000000000000000000000FA
-:10A6600000000000000000000000000000000000EA
-:10A6700000000000000000000000000000000000DA
-:10A6800000000000000000000000000000000000CA
-:10A6900000000000000000000000000000000000BA
-:10A6A00000000000000000000000000000000000AA
-:10A6B000000000000000000000000000000000009A
-:10A6C000000000000000000000000000000000008A
-:10A6D000000000000000000000000000000000007A
-:10A6E000000000000000000000000000000000006A
-:10A6F000000000000000000000000000000000005A
-:10A700000000000000000000000000000000000049
-:10A710000000000000000000000000000000000039
-:10A720000000000000000000000000000000000029
-:10A730000000000000000000000000000000000019
-:10A740000000000000000000000000000000000009
-:10A7500000000000000000000000000000000000F9
-:10A7600000000000000000000000000000000000E9
-:10A7700000000000000000000000000000000000D9
-:10A7800000000000000000000000000000000000C9
-:10A7900000000000000000000000000000000000B9
-:10A7A00000000000000000000000000000000000A9
-:10A7B0000000000000000000000000000000000099
-:10A7C0000000000000000000000000000000000089
-:10A7D0000000000000000000000000000000000079
-:10A7E0000000000000000000000000000000000069
-:10A7F0000000000000000000000000000000000059
-:10A800000000000000000000000000000000000048
-:10A810000000000000000000000000000000000038
-:10A820000000000000000000000000000000000028
-:10A830000000000000000000000000000000000018
-:10A840000000000000000000000000000000000008
-:10A8500000000000000000000000000000000000F8
-:10A8600000000000000000000000000000000000E8
-:10A8700000000000000000000000000000000000D8
-:10A8800000000000000000000000000000000000C8
-:10A8900000000000000000000000000000000000B8
-:10A8A00000000000000000000000000000000000A8
-:10A8B0000000000000000000000000000000000098
-:10A8C0000000000000000000000000000000000088
-:10A8D0000000000000000000000000000000000078
-:10A8E0000000000000000000000000000000000068
-:10A8F0000000000000000000000000000000000058
-:10A900000000000000000000000000000000000047
-:10A910000000000000000000000000000000000037
-:10A920000000000000000000000000000000000027
-:10A930000000000000000000000000000000000017
-:10A940000000000000000000000000000000000007
-:10A9500000000000000000000000000000000000F7
-:10A9600000000000000000000000000000000000E7
-:10A9700000000000000000000000000000000000D7
-:10A9800000000000000000000000000000000000C7
-:10A9900000000000000000000000000000000000B7
-:10A9A00000000000000000000000000000000000A7
-:10A9B0000000000000000000000000000000000097
-:10A9C0000000000000000000000000000000000087
-:10A9D0000000000000000000000000000000000077
-:10A9E0000000000000000000000000000000000067
-:10A9F0000000000000000000000000000000000057
-:10AA00000000000000000000000000000000000046
-:10AA10000000000000000000000000000000000036
-:10AA20000000000000000000000000000000000026
-:10AA30000000000000000000000000000000000016
-:10AA40000000000000000000000000000000000006
-:10AA500000000000000000000000000000000000F6
-:10AA600000000000000000000000000000000000E6
-:10AA700000000000000000000000000000000000D6
-:10AA800000000000000000000000000000000000C6
-:10AA900000000000000000000000000000000000B6
-:10AAA00000000000000000000000000000000000A6
-:10AAB0000000000000000000000000000000000096
-:10AAC0000000000000000000000000000000000086
-:10AAD0000000000000000000000000000000000076
-:10AAE0000000000000000000000000000000000066
-:10AAF0000000000000000000000000000000000056
-:10AB00000000000000000000000000000000000045
-:10AB10000000000000000000000000000000000035
-:10AB20000000000000000000000000000000000025
-:10AB30000000000000000000000000000000000015
-:10AB40000000000000000000000000000000000005
-:10AB500000000000000000000000000000000000F5
-:10AB600000000000000000000000000000000000E5
-:10AB700000000000000000000000000000000000D5
-:10AB800000000000000000000000000000000000C5
-:10AB900000000000000000000000000000000000B5
-:10ABA00000000000000000000000000000000000A5
-:10ABB0000000000000000000000000000000000095
-:10ABC0000000000000000000000000000000000085
-:10ABD0000000000000000000000000000000000075
-:10ABE0000000000000000000000000000000000065
-:10ABF0000000000000000000000000000000000055
-:10AC00000000000000000000000000000000000044
-:10AC10000000000000000000000000000000000034
-:10AC20000000000000000000000000000000000024
-:10AC30000000000000000000000000000000000014
-:10AC40000000000000000000000000000000000004
-:10AC500000000000000000000000000000000000F4
-:10AC600000000000000000000000000000000000E4
-:10AC700000000000000000000000000000000000D4
-:10AC800000000000000000000000000000000000C4
-:10AC900000000000000000000000000000000000B4
-:10ACA00000000000000000000000000000000000A4
-:10ACB0000000000000000000000000000000000094
-:10ACC0000000000000000000000000000000000084
-:10ACD0000000000000000000000000000000000074
-:10ACE0000000000000000000000000000000000064
-:10ACF0000000000000000000000000000000000054
-:10AD00000000000000000000000000000000000043
-:10AD10000000000000000000000000000000000033
-:10AD20000000000000000000000000000000000023
-:10AD30000000000000000000000000000000000013
-:10AD40000000000000000000000000000000000003
-:10AD500000000000000000000000000000000000F3
-:10AD600000000000000000000000000000000000E3
-:10AD700000000000000000000000000000000000D3
-:10AD800000000000000000000000000000000000C3
-:10AD900000000000000000000000000000000000B3
-:10ADA00000000000000000000000000000000000A3
-:10ADB0000000000000000000000000000000000093
-:10ADC0000000000000000000000000000000000083
-:10ADD0000000000000000000000000000000000073
-:10ADE0000000000000000000000000000000000063
-:10ADF0000000000000000000000000000000000053
-:10AE00000000000000000000000000000000000042
-:10AE10000000000000000000000000000000000032
-:10AE20000000000000000000000000000000000022
-:10AE30000000000000000000000000000000000012
-:10AE40000000000000000000000000000000000002
-:10AE500000000000000000000000000000000000F2
-:10AE600000000000000000000000000000000000E2
-:10AE700000000000000000000000000000000000D2
-:10AE800000000000000000000000000000000000C2
-:10AE900000000000000000000000000000000000B2
-:10AEA00000000000000000000000000000000000A2
-:10AEB0000000000000000000000000000000000092
-:10AEC0000000000000000000000000000000000082
-:10AED0000000000000000000000000000000000072
-:10AEE0000000000000000000000000000000000062
-:10AEF0000000000000000000000000000000000052
-:10AF00000000000000000000000000000000000041
-:10AF10000000000000000000000000000000000031
-:10AF20000000000000000000000000000000000021
-:10AF30000000000000000000000000000000000011
-:10AF40000000000000000000000000000000000001
-:10AF500000000000000000000000000000000000F1
-:10AF600000000000000000000000000000000000E1
-:10AF700000000000000000000000000000000000D1
-:10AF800000000000000000000000000000000000C1
-:10AF900000000000000000000000000000000000B1
-:10AFA00000000000000000000000000000000000A1
-:10AFB0000000000000000000000000000000000091
-:10AFC0000000000000000000000000000000000081
-:10AFD0000000000000000000000000000000000071
-:10AFE0000000000000000000000000000000000061
-:10AFF0000000000000000000000000000000000051
-:10B000000000000000000000000000000000000040
-:10B010000000000000000000000000000000000030
-:10B020000000000000000000000000000000000020
-:10B030000000000000000000000000000000000010
-:10B040000000000000000000000000000000000000
-:10B0500000000000000000000000000000000000F0
-:10B0600000000000000000000000000000000000E0
-:10B0700000000000000000000000000000000000D0
-:10B0800000000000000000000000000000000000C0
-:10B0900000000000000000000000000000000000B0
-:10B0A00000000000000000000000000000000000A0
-:10B0B0000000000000000000000000000000000090
-:10B0C0000000000000000000000000000000000080
-:10B0D0000000000000000000000000000000000070
-:10B0E0000000000000000000000000000000000060
-:10B0F0000000000000000000000000000000000050
-:10B10000000000000000000000000000000000003F
-:10B11000000000000000000000000000000000002F
-:10B12000000000000000000000000000000000001F
-:10B13000000000000000000000000000000000000F
-:10B1400000000000000000000000000000000000FF
-:10B1500000000000000000000000000000000000EF
-:10B1600000000000000000000000000000000000DF
-:10B1700000000000000000000000000000000000CF
-:10B1800000000000000000000000000000000000BF
-:10B1900000000000000000000000000000000000AF
-:10B1A000000000000000000000000000000000009F
-:10B1B000000000000000000000000000000000008F
-:10B1C000000000000000000000000000000000007F
-:10B1D000000000000000000000000000000000006F
-:10B1E000000000000000000000000000000000005F
-:10B1F000000000000000000000000000000000004F
-:10B20000000000000000000000000000000000003E
-:10B21000000000000000000000000000000000002E
-:10B22000000000000000000000000000000000001E
-:10B23000000000000000000000000000000000000E
-:10B2400000000000000000000000000000000000FE
-:10B2500000000000000000000000000000000000EE
-:10B2600000000000000000000000000000000000DE
-:10B2700000000000000000000000000000000000CE
-:10B2800000000000000000000000000000000000BE
-:10B2900000000000000000000000000000000000AE
-:10B2A000000000000000000000000000000000009E
-:10B2B000000000000000000000000000000000008E
-:10B2C000000000000000000000000000000000007E
-:10B2D000000000000000000000000000000000006E
-:10B2E000000000000000000000000000000000005E
-:10B2F000000000000000000000000000000000004E
-:10B30000000000000000000000000000000000003D
-:10B31000000000000000000000000000000000002D
-:10B32000000000000000000000000000000000001D
-:10B33000000000000000000000000000000000000D
-:10B3400000000000000000000000000000000000FD
-:10B3500000000000000000000000000000000000ED
-:10B3600000000000000000000000000000000000DD
-:10B3700000000000000000000000000000000000CD
-:10B3800000000000000000000000000000000000BD
-:10B3900000000000000000000000000000000000AD
-:10B3A000000000000000000000000000000000009D
-:10B3B000000000000000000000000000000000008D
-:10B3C000000000000000000000000000000000007D
-:10B3D000000000000000000000000000000000006D
-:10B3E000000000000000000000000000000000005D
-:10B3F000000000000000000000000000000000004D
-:10B40000000000000000000000000000000000003C
-:10B41000000000000000000000000000000000002C
-:10B42000000000000000000000000000000000001C
-:10B43000000000000000000000000000000000000C
-:10B4400000000000000000000000000000000000FC
-:10B4500000000000000000000000000000000000EC
-:10B4600000000000000000000000000000000000DC
-:10B4700000000000000000000000000000000000CC
-:10B4800000000000000000000000000000000000BC
-:10B4900000000000000000000000000000000000AC
-:10B4A000000000000000000000000000000000009C
-:10B4B000000000000000000000000000000000008C
-:10B4C000000000000000000000000000000000007C
-:10B4D000000000000000000000000000000000006C
-:10B4E000000000000000000000000000000000005C
-:10B4F000000000000000000000000000000000004C
-:10B50000000000000000000000000000000000003B
-:10B51000000000000000000000000000000000002B
-:10B52000000000000000000000000000000000001B
-:10B53000000000000000000000000000000000000B
-:10B5400000000000000000000000000000000000FB
-:10B5500000000000000000000000000000000000EB
-:10B5600000000000000000000000000000000000DB
-:10B5700000000000000000000000000000000000CB
-:10B5800000000000000000000000000000000000BB
-:10B5900000000000000000000000000000000000AB
-:10B5A000000000000000000000000000000000009B
-:10B5B000000000000000000000000000000000008B
-:10B5C000000000000000000000000000000000007B
-:10B5D000000000000000000000000000000000006B
-:10B5E000000000000000000000000000000000005B
-:10B5F000000000000000000000000000000000004B
-:10B60000000000000000000000000000000000003A
-:10B61000000000000000000000000000000000002A
-:10B62000000000000000000000000000000000001A
-:10B63000000000000000000000000000000000000A
-:10B6400000000000000000000000000000000000FA
-:10B6500000000000000000000000000000000000EA
-:10B6600000000000000000000000000000000000DA
-:10B6700000000000000000000000000000000000CA
-:10B6800000000000000000000000000000000000BA
-:10B6900000000000000000000000000000000000AA
-:10B6A000000000000000000000000000000000009A
-:10B6B000000000000000000000000000000000008A
-:10B6C000000000000000000000000000000000007A
-:10B6D000000000000000000000000000000000006A
-:10B6E000000000000000000000000000000000005A
-:10B6F000000000000000000000000000000000004A
-:10B700000000000000000000000000000000000039
-:10B710000000000000000000000000000000000029
-:10B720000000000000000000000000000000000019
-:10B730000000000000000000000000000000000009
-:10B7400000000000000000000000000000000000F9
-:10B7500000000000000000000000000000000000E9
-:10B7600000000000000000000000000000000000D9
-:10B7700000000000000000000000000000000000C9
-:10B7800000000000000000000000000000000000B9
-:10B7900000000000000000000000000000000000A9
-:10B7A0000000000000000000000000000000000099
-:10B7B0000000000000000000000000000000000089
-:10B7C0000000000000000000000000000000000079
-:10B7D0000000000000000000000000000000000069
-:10B7E0000000000000000000000000000000000059
-:10B7F0000000000000000000000000000000000049
-:10B800000000000000000000000000000000000038
-:10B810000000000000000000000000000000000028
-:10B820000000000000000000000000000000000018
-:10B830000000000000000000000000000000000008
-:10B8400000000000000000000000000000000000F8
-:10B8500000000000000000000000000000000000E8
-:10B8600000000000000000000000000000000000D8
-:10B8700000000000000000000000000000000000C8
-:10B8800000000000000000000000000000000000B8
-:10B8900000000000000000000000000000000000A8
-:10B8A0000000000000000000000000000000000098
-:10B8B0000000000000000000000000000000000088
-:10B8C0000000000000000000000000000000000078
-:10B8D0000000000000000000000000000000000068
-:10B8E0000000000000000000000000000000000058
-:10B8F0000000000000000000000000000000000048
-:10B900000000000000000000000000000000000037
-:10B910000000000000000000000000000000000027
-:10B920000000000000000000000000000000000017
-:10B930000000000000000000000000000000000007
-:10B9400000000000000000000000000000000000F7
-:10B9500000000000000000000000000000000000E7
-:10B9600000000000000000000000000000000000D7
-:10B9700000000000000000000000000000000000C7
-:10B9800000000000000000000000000000000000B7
-:10B9900000000000000000000000000000000000A7
-:10B9A0000000000000000000000000000000000097
-:10B9B0000000000000000000000000000000000087
-:10B9C0000000000000000000000000000000000077
-:10B9D0000000000000000000000000000000000067
-:10B9E0000000000000000000000000000000000057
-:10B9F0000000000000000000000000000000000047
-:10BA00000000000000000000000000000000000036
-:10BA10000000000000000000000000000000000026
-:10BA20000000000000000000000000000000000016
-:10BA30000000000000000000000000000000000006
-:10BA400000000000000000000000000000000000F6
-:10BA500000000000000000000000000000000000E6
-:10BA600000000000000000000000000000000000D6
-:10BA700000000000000000000000000000000000C6
-:10BA800000000000000000000000000000000000B6
-:10BA900000000000000000000000000000000000A6
-:10BAA0000000000000000000000000000000000096
-:10BAB0000000000000000000000000000000000086
-:10BAC0000000000000000000000000000000000076
-:10BAD0000000000000000000000000000000000066
-:10BAE0000000000000000000000000000000000056
-:10BAF0000000000000000000000000000000000046
-:10BB00000000000000000000000000000000000035
-:10BB10000000000000000000000000000000000025
-:10BB20000000000000000000000000000000000015
-:10BB30000000000000000000000000000000000005
-:10BB400000000000000000000000000000000000F5
-:10BB500000000000000000000000000000000000E5
-:10BB600000000000000000000000000000000000D5
-:10BB700000000000000000000000000000000000C5
-:10BB800000000000000000000000000000000000B5
-:10BB900000000000000000000000000000000000A5
-:10BBA0000000000000000000000000000000000095
-:10BBB0000000000000000000000000000000000085
-:10BBC0000000000000000000000000000000000075
-:10BBD0000000000000000000000000000000000065
-:10BBE0000000000000000000000000000000000055
-:10BBF0000000000000000000000000000000000045
-:10BC00000000000000000000000000000000000034
-:10BC10000000000000000000000000000000000024
-:10BC20000000000000000000000000000000000014
-:10BC30000000000000000000000000000000000004
-:10BC400000000000000000000000000000000000F4
-:10BC500000000000000000000000000000000000E4
-:10BC600000000000000000000000000000000000D4
-:10BC700000000000000000000000000000000000C4
-:10BC800000000000000000000000000000000000B4
-:10BC900000000000000000000000000000000000A4
-:10BCA0000000000000000000000000000000000094
-:10BCB0000000000000000000000000000000000084
-:10BCC0000000000000000000000000000000000074
-:10BCD0000000000000000000000000000000000064
-:10BCE0000000000000000000000000000000000054
-:10BCF0000000000000000000000000000000000044
-:10BD00000000000000000000000000000000000033
-:10BD10000000000000000000000000000000000023
-:10BD20000000000000000000000000000000000013
-:10BD30000000000000000000000000000000000003
-:10BD400000000000000000000000000000000000F3
-:10BD500000000000000000000000000000000000E3
-:10BD600000000000000000000000000000000000D3
-:10BD700000000000000000000000000000000000C3
-:10BD800000000000000000000000000000000000B3
-:10BD900000000000000000000000000000000000A3
-:10BDA0000000000000000000000000000000000093
-:10BDB0000000000000000000000000000000000083
-:10BDC0000000000000000000000000000000000073
-:10BDD0000000000000000000000000000000000063
-:10BDE0000000000000000000000000000000000053
-:10BDF0000000000000000000000000000000000043
-:10BE00000000000000000000000000000000000032
-:10BE10000000000000000000000000000000000022
-:10BE20000000000000000000000000000000000012
-:10BE30000000000000000000000000000000000002
-:10BE400000000000000000000000000000000000F2
-:10BE500000000000000000000000000000000000E2
-:10BE600000000000000000000000000000000000D2
-:10BE700000000000000000000000000000000000C2
-:10BE800000000000000000000000000000000000B2
-:10BE900000000000000000000000000000000000A2
-:10BEA0000000000000000000000000000000000092
-:10BEB0000000000000000000000000000000000082
-:10BEC0000000000000000000000000000000000072
-:10BED0000000000000000000000000000000000062
-:10BEE0000000000000000000000000000000000052
-:10BEF0000000000000000000000000000000000042
-:10BF00000000000000000000000000000000000031
-:10BF10000000000000000000000000000000000021
-:10BF20000000000000000000000000000000000011
-:10BF30000000000000000000000000000000000001
-:10BF400000000000000000000000000000000000F1
-:10BF500000000000000000000000000000000000E1
-:10BF600000000000000000000000000000000000D1
-:10BF700000000000000000000000000000000000C1
-:10BF800000000000000000000000000000000000B1
-:10BF900000000000000000000000000000000000A1
-:10BFA0000000000000000000000000000000000091
-:10BFB0000000000000000000000000000000000081
-:10BFC0000000000000000000000000000000000071
-:10BFD0000000000000000000000000000000000061
-:10BFE0000000000000000000000000000000000051
-:10BFF0000000000000000000000000000000000041
-:10C000000000000000000000000000000000000030
-:10C010000000000000000000000000000000000020
-:10C020000000000000000000000000000000000010
-:10C030000000000000000000000000000000000000
-:10C0400000000000000000000000000000000000F0
-:10C0500000000000000000000000000000000000E0
-:10C0600000000000000000000000000000000000D0
-:10C0700000000000000000000000000000000000C0
-:10C0800000000000000000000000000000000000B0
-:10C0900000000000000000000000000000000000A0
-:10C0A0000000000000000000000000000000000090
-:10C0B0000000000000000000000000000000000080
-:10C0C0000000000000000000000000000000000070
-:10C0D0000000000000000000000000000000000060
-:10C0E0000000000000000000000000000000000050
-:10C0F0000000000000000000000000000000000040
-:10C10000000000000000000000000000000000002F
-:10C11000000000000000000000000000000000001F
-:10C12000000000000000000000000000000000000F
-:10C1300000000000000000000000000000000000FF
-:10C1400000000000000000000000000000000000EF
-:10C1500000000000000000000000000000000000DF
-:10C1600000000000000000000000000000000000CF
-:10C1700000000000000000000000000000000000BF
-:10C1800000000000000000000000000000000000AF
-:10C19000000000000000000000000000000000009F
-:10C1A000000000000000000000000000000000008F
-:10C1B000000000000000000000000000000000007F
-:10C1C000000000000000000000000000000000006F
-:10C1D000000000000000000000000000000000005F
-:10C1E000000000000000000000000000000000004F
-:10C1F000000000000000000000000000000000003F
-:10C20000000000000000000000000000000000002E
-:10C21000000000000000000000000000000000001E
-:10C22000000000000000000000000000000000000E
-:10C2300000000000000000000000000000000000FE
-:10C2400000000000000000000000000000000000EE
-:10C2500000000000000000000000000000000000DE
-:10C2600000000000000000000000000000000000CE
-:10C2700000000000000000000000000000000000BE
-:10C2800000000000000000000000000000000000AE
-:10C29000000000000000000000000000000000009E
-:10C2A000000000000000000000000000000000008E
-:10C2B000000000000000000000000000000000007E
-:10C2C000000000000000000000000000000000006E
-:10C2D000000000000000000000000000000000005E
-:10C2E000000000000000000000000000000000004E
-:10C2F000000000000000000000000000000000003E
-:10C30000000000000000000000000000000000002D
-:10C31000000000000000000000000000000000001D
-:10C32000000000000000000000000000000000000D
-:10C3300000000000000000000000000000000000FD
-:10C3400000000000000000000000000000000000ED
-:10C3500000000000000000000000000000000000DD
-:10C3600000000000000000000000000000000000CD
-:10C3700000000000000000000000000000000000BD
-:10C3800000000000000000000000000000000000AD
-:10C39000000000000000000000000000000000009D
-:10C3A000000000000000000000000000000000008D
-:10C3B000000000000000000000000000000000007D
-:10C3C000000000000000000000000000000000006D
-:10C3D000000000000000000000000000000000005D
-:10C3E000000000000000000000000000000000004D
-:10C3F000000000000000000000000000000000003D
-:10C40000000000000000000000000000000000002C
-:10C41000000000000000000000000000000000001C
-:10C42000000000000000000000000000000000000C
-:10C4300000000000000000000000000000000000FC
-:10C4400000000000000000000000000000000000EC
-:10C4500000000000000000000000000000000000DC
-:10C4600000000000000000000000000000000000CC
-:10C4700000000000000000000000000000000000BC
-:10C4800000000000000000000000000000000000AC
-:10C49000000000000000000000000000000000009C
-:10C4A000000000000000000000000000000000008C
-:10C4B000000000000000000000000000000000007C
-:10C4C000000000000000000000000000000000006C
-:10C4D000000000000000000000000000000000005C
-:10C4E000000000000000000000000000000000004C
-:10C4F000000000000000000000000000000000003C
-:10C50000000000000000000000000000000000002B
-:10C51000000000000000000000000000000000001B
-:10C52000000000000000000000000000000000000B
-:10C5300000000000000000000000000000000000FB
-:10C5400000000000000000000000000000000000EB
-:10C5500000000000000000000000000000000000DB
-:10C5600000000000000000000000000000000000CB
-:10C5700000000000000000000000000000000000BB
-:10C5800000000000000000000000000000000000AB
-:10C59000000000000000000000000000000000009B
-:10C5A000000000000000000000000000000000008B
-:10C5B000000000000000000000000000000000007B
-:10C5C000000000000000000000000000000000006B
-:10C5D000000000000000000000000000000000005B
-:10C5E000000000000000000000000000000000004B
-:10C5F000000000000000000000000000000000003B
-:10C60000000000000000000000000000000000002A
-:10C61000000000000000000000000000000000001A
-:10C62000000000000000000000000000000000000A
-:10C6300000000000000000000000000000000000FA
-:10C6400000000000000000000000000000000000EA
-:10C6500000000000000000000000000000000000DA
-:10C6600000000000000000000000000000000000CA
-:10C6700000000000000000000000000000000000BA
-:10C6800000000000000000000000000000000000AA
-:10C69000000000000000000000000000000000009A
-:10C6A000000000000000000000000000000000008A
-:10C6B000000000000000000000000000000000007A
-:10C6C000000000000000000000000000000000006A
-:10C6D000000000000000000000000000000000005A
-:10C6E000000000000000000000000000000000004A
-:10C6F000000000000000000000000000000000003A
-:10C700000000000000000000000000000000000029
-:10C710000000000000000000000000000000000019
-:10C720000000000000000000000000000000000009
-:10C7300000000000000000000000000000000000F9
-:10C7400000000000000000000000000000000000E9
-:10C7500000000000000000000000000000000000D9
-:10C7600000000000000000000000000000000000C9
-:10C7700000000000000000000000000000000000B9
-:10C7800000000000000000000000000000000000A9
-:10C790000000000000000000000000000000000099
-:10C7A0000000000000000000000000000000000089
-:10C7B0000000000000000000000000000000000079
-:10C7C0000000000000000000000000000000000069
-:10C7D0000000000000000000000000000000000059
-:10C7E0000000000000000000000000000000000049
-:10C7F0000000000000000000000000000000000039
-:10C800000000000000000000000000000000000028
-:10C810000000000000000000000000000000000018
-:10C820000000000000000000000000000000000008
-:10C8300000000000000000000000000000000000F8
-:10C8400000000000000000000000000000000000E8
-:10C8500000000000000000000000000000000000D8
-:10C8600000000000000000000000000000000000C8
-:10C8700000000000000000000000000000000000B8
-:10C8800000000000000000000000000000000000A8
-:10C890000000000000000000000000000000000098
-:10C8A0000000000000000000000000000000000088
-:10C8B0000000000000000000000000000000000078
-:10C8C0000000000000000000000000000000000068
-:10C8D0000000000000000000000000000000000058
-:10C8E0000000000000000000000000000000000048
-:10C8F0000000000000000000000000000000000038
-:10C900000000000000000000000000000000000027
-:10C910000000000000000000000000000000000017
-:10C920000000000000000000000000000000000007
-:10C9300000000000000000000000000000000000F7
-:10C9400000000000000000000000000000000000E7
-:10C9500000000000000000000000000000000000D7
-:10C9600000000000000000000000000000000000C7
-:10C9700000000000000000000000000000000000B7
-:10C9800000000000000000000000000000000000A7
-:10C990000000000000000000000000000000000097
-:10C9A0000000000000000000000000000000000087
-:10C9B0000000000000000000000000000000000077
-:10C9C0000000000000000000000000000000000067
-:10C9D0000000000000000000000000000000000057
-:10C9E0000000000000000000000000000000000047
-:10C9F0000000000000000000000000000000000037
-:10CA00000000000000000000000000000000000026
-:10CA10000000000000000000000000000000000016
-:10CA20000000000000000000000000000000000006
-:10CA300000000000000000000000000000000000F6
-:10CA400000000000000000000000000000000000E6
-:10CA500000000000000000000000000000000000D6
-:10CA600000000000000000000000000000000000C6
-:10CA700000000000000000000000000000000000B6
-:10CA800000000000000000000000000000000000A6
-:10CA90000000000000000000000000000000000096
-:10CAA0000000000000000000000000000000000086
-:10CAB0000000000000000000000000000000000076
-:10CAC0000000000000000000000000000000000066
-:10CAD0000000000000000000000000000000000056
-:10CAE0000000000000000000000000000000000046
-:10CAF0000000000000000000000000000000000036
-:10CB00000000000000000000000000000000000025
-:10CB10000000000000000000000000000000000015
-:10CB20000000000000000000000000000000000005
-:10CB300000000000000000000000000000000000F5
-:10CB400000000000000000000000000000000000E5
-:10CB500000000000000000000000000000000000D5
-:10CB600000000000000000000000000000000000C5
-:10CB700000000000000000000000000000000000B5
-:10CB800000000000000000000000000000000000A5
-:10CB90000000000000000000000000000000000095
-:10CBA0000000000000000000000000000000000085
-:10CBB0000000000000000000000000000000000075
-:10CBC0000000000000000000000000000000000065
-:10CBD0000000000000000000000000000000000055
-:10CBE0000000000000000000000000000000000045
-:10CBF0000000000000000000000000000000000035
-:10CC00000000000000000000000000000000000024
-:10CC10000000000000000000000000000000000014
-:10CC20000000000000000000000000000000000004
-:10CC300000000000000000000000000000000000F4
-:10CC400000000000000000000000000000000000E4
-:10CC500000000000000000000000000000000000D4
-:10CC600000000000000000000000000000000000C4
-:10CC700000000000000000000000000000000000B4
-:10CC800000000000000000000000000000000000A4
-:10CC90000000000000000000000000000000000094
-:10CCA0000000000000000000000000000000000084
-:10CCB0000000000000000000000000000000000074
-:10CCC0000000000000000000000000000000000064
-:10CCD0000000000000000000000000000000000054
-:10CCE0000000000000000000000000000000000044
-:10CCF0000000000000000000000000000000000034
-:10CD00000000000000000000000000000000000023
-:10CD10000000000000000000000000000000000013
-:10CD20000000000000000000000000000000000003
-:10CD300000000000000000000000000000000000F3
-:10CD400000000000000000000000000000000000E3
-:10CD500000000000000000000000000000000000D3
-:10CD600000000000000000000000000000000000C3
-:10CD700000000000000000000000000000000000B3
-:10CD800000000000000000000000000000000000A3
-:10CD90000000000000000000000000000000000093
-:10CDA0000000000000000000000000000000000083
-:10CDB0000000000000000000000000000000000073
-:10CDC0000000000000000000000000000000000063
-:10CDD0000000000000000000000000000000000053
-:10CDE0000000000000000000000000000000000043
-:10CDF0000000000000000000000000000000000033
-:10CE00000000000000000000000000000000000022
-:10CE10000000000000000000000000000000000012
-:10CE20000000000000000000000000000000000002
-:10CE300000000000000000000000000000000000F2
-:10CE400000000000000000000000000000000000E2
-:10CE500000000000000000000000000000000000D2
-:10CE600000000000000000000000000000000000C2
-:10CE700000000000000000000000000000000000B2
-:10CE800000000000000000000000000000000000A2
-:10CE90000000000000000000000000000000000092
-:10CEA0000000000000000000000000000000000082
-:10CEB0000000000000000000000000000000000072
-:10CEC0000000000000000000000000000000000062
-:10CED0000000000000000000000000000000000052
-:10CEE0000000000000000000000000000000000042
-:10CEF0000000000000000000000000000000000032
-:10CF00000000000000000000000000000000000021
-:10CF10000000000000000000000000000000000011
-:10CF20000000000000000000000000000000000001
-:10CF300000000000000000000000000000000000F1
-:10CF400000000000000000000000000000000000E1
-:10CF500000000000000000000000000000000000D1
-:10CF600000000000000000000000000000000000C1
-:10CF700000000000000000000000000000000000B1
-:10CF800000000000000000000000000000000000A1
-:10CF90000000000000000000000000000000000091
-:10CFA0000000000000000000000000000000000081
-:10CFB0000000000000000000000000000000000071
-:10CFC0000000000000000000000000000000000061
-:10CFD0000000000000000000000000000000000051
-:10CFE0000000000000000000000000000000000041
-:10CFF0000000000000000000000000000000000031
-:10D000000000000000000000000000000000000020
-:10D010000000000000000000000000000000000010
-:10D020000000000000000000000000000000000000
-:10D0300000000000000000000000000000000000F0
-:10D0400000000000000000000000000000000000E0
-:10D0500000000000000000000000000000000000D0
-:10D0600000000000000000000000000000000000C0
-:10D0700000000000000000000000000000000000B0
-:10D0800000000000000000000000000000000000A0
-:10D090000000000000000000000000000000000090
-:10D0A0000000000000000000000000000000000080
-:10D0B0000000000000000000000000000000000070
-:10D0C0000000000000000000000000000000000060
-:10D0D0000000000000000000000000000000000050
-:10D0E0000000000000000000000000000000000040
-:10D0F0000000000000000000000000000000000030
-:10D10000000000000000000000000000000000001F
-:10D11000000000000000000000000000000000000F
-:10D1200000000000000000000000000000000000FF
-:10D1300000000000000000000000000000000000EF
-:10D1400000000000000000000000000000000000DF
-:10D1500000000000000000000000000000000000CF
-:10D1600000000000000000000000000000000000BF
-:10D1700000000000000000000000000000000000AF
-:10D18000000000000000000000000000000000009F
-:10D19000000000000000000000000000000000008F
-:10D1A000000000000000000000000000000000007F
-:10D1B000000000000000000000000000000000006F
-:10D1C000000000000000000000000000000000005F
-:10D1D000000000000000000000000000000000004F
-:10D1E000000000000000000000000000000000003F
-:10D1F000000000000000000000000000000000002F
-:10D20000000000000000000000000000000000001E
-:10D21000000000000000000000000000000000000E
-:10D2200000000000000000000000000000000000FE
-:10D2300000000000000000000000000000000000EE
-:10D2400000000000000000000000000000000000DE
-:10D2500000000000000000000000000000000000CE
-:10D2600000000000000000000000000000000000BE
-:10D2700000000000000000000000000000000000AE
-:10D28000000000000000000000000000000000009E
-:10D29000000000000000000000000000000000008E
-:10D2A000000000000000000000000000000000007E
-:10D2B000000000000000000000000000000000006E
-:10D2C000000000000000000000000000000000005E
-:10D2D000000000000000000000000000000000004E
-:10D2E000000000000000000000000000000000003E
-:10D2F000000000000000000000000000000000002E
-:10D30000000000000000000000000000000000001D
-:10D31000000000000000000000000000000000000D
-:10D3200000000000000000000000000000000000FD
-:10D330000000000010000003000000000000000DCD
-:10D340000000000D3C02080024427A603C03080003
-:10D3500024637AD8AC4000000043202B1480FFFDEA
-:10D36000244200043C1D080037BD9FFC03A0F021AF
-:10D370003C100800261031D83C1C0800279C7A601D
-:10D380000E001253000000000000000D3C0280005F
-:10D3900030A5FFFF30C600FF344301803C08800009
-:10D3A0008D0901B80520FFFE00000000AC640000FC
-:10D3B00024040002A4650008A066000AA064000B13
-:10D3C000AC6700183C03100003E00008AD0301B88F
-:10D3D0003C0560008CA24FF80440FFFE00000000F6
-:10D3E000ACA44FC03C0310003C040200ACA44FC4EA
-:10D3F00003E00008ACA34FF827BDFFE8AFBF00145F
-:10D40000AFB000100E0012A5008080213C048008FF
-:10D410003485008090A600052403FFFE0200202131
-:10D4200000C310248FBF00148FB00010A0A200050D
-:10D430000A0012AF27BD001827BDFFE8AFB00010EB
-:10D44000AFBF00140E000ED6008080213C0680087D
-:10D4500034C5008090A4000024020050308300FFF7
-:10D46000106200073C098000020020218FBF0014D9
-:10D470008FB00010AD2001800A000FC527BD001835
-:10D48000240801003C078000020020218FBF001407
-:10D490008FB00010ACE801800A000FC527BD00184E
-:10D4A00027BDFF883C088008AFBE0070AFB600689B
-:10D4B000AFB40060AFB00050AFBF0074AFB7006C46
-:10D4C000AFB50064AFB3005CAFB20058AFB1005469
-:10D4D000350500803C0780008CF1012890A40009EC
-:10D4E000ACE0008490A60005309000FF0000A02171
-:10D4F00000061827306200010000B02114400067C8
-:10D500000000F02190A9000024050020312400FF34
-:10D5100010850016240A0050108A008D00000000BB
-:10D520003C0C08008D8C00DC258B00013C010800C0
-:10D53000AC2B00DC0E00139B000000008FBF0074BA
-:10D540008FBE00708FB7006C8FB600688FB5006417
-:10D550008FB400608FB3005C8FB200588FB100545D
-:10D560008FB0005003E0000827BD00780000000DD8
-:10D570003C158000AFA0003096A201168EB90104C0
-:10D580003C1F002036B20C00033FC0240018B82B0B
-:10D5900000173140AFA600308EAE01043053FFFFBC
-:10D5A0003C0F00400272382101CF682490F2000D38
-:10D5B00011A0004834C4004032430020146000022F
-:10D5C000348600800080302114C00094AFA6003063
-:10D5D0003C0980083525008090A8000831060040ED
-:10D5E00050C000063C088008240A0004120A00A368
-:10D5F000240B0012120B00293C088008351501008D
-:10D600003C17800096F3011A94EE000E92AF0008CA
-:10D61000324C00043275FFFF01EE6804AFAD003CF0
-:10D620008CF30004118000318CF700083503008072
-:10D63000907800083307004014E000280000000044
-:10D640008C72005002728823062000063C0680007F
-:10D650008C7F0034027FC823072200848E8200085A
-:10D660003C068000ACC00044240200018FBF00745F
-:10D670008FBE00708FB7006C8FB600688FB50064E6
-:10D680008FB400608FB3005C8FB200588FB100542C
-:10D690008FB0005003E0000827BD00780E000CB8E2
-:10D6A000000020218FBF00748FBE00708FB7006C08
-:10D6B0008FB600688FB500648FB400608FB3005CD4
-:10D6C0008FB200588FB100548FB0005003E00008B3
-:10D6D00027BD00780A000D1800C020210E00146C30
-:10D6E000026020211440FFDF3C0680003C038008DC
-:10D6F000346300808C6400340264102304400018FA
-:10D70000000000003C1408008E94310026900001B7
-:10D710003C010800AC3031000E0012A5022020218F
-:10D720003C048008349F008093FE002502202021C5
-:10D7300037C90004A3E900250E0012AF0000000065
-:10D740000E000C9E022020210A000D45240200013B
-:10D750003C14080026947AC80A000D073C15800086
-:10D760008C6800300268302318C00008240B000CBD
-:10D770003C0908008D293100325200FC0000A8212C
-:10D78000252500013C010800AC253100AFAB00307D
-:10D790008C6A003001534023190000E002A8602A7F
-:10D7A0001580FFDD0000000012A8002A02A87823DF
-:10D7B0000268982131F5FFFF3247000210E0003483
-:10D7C000325900103C13800836700080921E000809
-:10D7D00033D6004052C000D38E82000802202021A0
-:10D7E0000E0012A524120018A212000992170005BB
-:10D7F0002418FFFE0220202102F8A8240E0012AFF8
-:10D80000A215000524040039000028210E00144749
-:10D81000240600180A000D45240200019296000C0F
-:10D820003C048008349E00808FC700380016A30097
-:10D830003690008130C600FF022020210E000C8DA2
-:10D840003205F0813C068000ACC000440A000D4562
-:10D85000240200013A4E000131CD000115A0FFAEB7
-:10D86000026898210A000D97000000000040F809A6
-:10D87000240400160A000D45240200010220202184
-:10D880000E00152900E028210A000CFA8FBF007451
-:10D890001320FF733C048008348900808D230038F6
-:10D8A0008C82000402E2F8231FE0FF6E3C06800039
-:10D8B00002E3302304C200010060B821AFA80018C1
-:10D8C0003C198000AFB30010AFB5001497260120BB
-:10D8D0008D2A00309524005C8FB8003C8FAD00305D
-:10D8E0003087FFFF30DFFFFF03E87021372F400054
-:10D8F0000307282B8E82000401CF602101A5582543
-:10D90000AFA90048AFAC0020AFAA0028AFAB0030F1
-:10D91000AFAA0024AFA0002CAFB700340040F80934
-:10D9200027A400108FA8003031030002106000020D
-:10D930008FA90048325200FE912300083069004050
-:10D94000512000138FA400243C0280088C4800045E
-:10D95000111700A4240A0014325800015300000CCF
-:10D960008FA400242419000C121900C02A1F000DD6
-:10D9700013E000BA2406000E2404000A5204000139
-:10D98000241600088FA9002425240001AFA4002438
-:10D990003C188008370500808FA700148CAF00303A
-:10D9A000340CFFFF00877021ACAE0030AFAF003801
-:10D9B00090AD004E8CAB00308FA8003C01AC100441
-:10D9C00001625021ACAA00348FA6003002E8202169
-:10D9D00030C300081060000BAFA400408CB90020D9
-:10D9E0001324008F30C600FF9289000C8FA70034EB
-:10D9F00000098300360400803085F0800E000C8D15
-:10DA0000022020213C0A8008355000808E0300301F
-:10DA10008FA800380068302318C00065262F0080CA
-:10DA20003C0E08008DCE31982407FF8001E7682462
-:10DA300031EC007F3C0680003C02800431CB0010BA
-:10DA4000ACCD00901160003B0182282190B8006BA2
-:10DA5000570000393C048008241F0001A0BF006B60
-:10DA600094C5007A24B9000AA61900123C0A80085D
-:10DA70003545008090A800083110004016000004D1
-:10DA80003C038008324B00011560006B0000000071
-:10DA9000346400808C8C00208FB200401192000909
-:10DAA000346301008C6D0000026D102318400012D9
-:10DAB0008FB80040241E0001AC980020AC73000019
-:10DAC000AC77000416C0002D0000000017C000272E
-:10DAD0000000000012A00005000018218FA50030F2
-:10DAE00030B5000452A0FE9500601021240300010F
-:10DAF0000A000CF9006010218C6E000015D3FFF1B4
-:10DB0000000000008C67000402E7782305E1FFE9CC
-:10DB10008FB800400A000E5B000000000A000D985C
-:10DB2000000040210040F809240400170A000D45B8
-:10DB3000240200013C04800834900080241E00016F
-:10DB4000022020210E0012A5A61E00129209002517
-:10DB500002202021241E0001352200010E0012AFF8
-:10DB6000A20200250A000E463C0A80080E000C9E08
-:10DB7000022020210A000E5F000000000E0012A506
-:10DB8000022020213C198008373700800220202104
-:10DB90000E0012AFA2F6000902C0302124040037A3
-:10DBA0000E001447000028210A000E5D000000004E
-:10DBB0008FA6001858C0FFAE3C0A80080E0012A5C0
-:10DBC000022020219203002502202021241E000192
-:10DBD000346200040E0012AFA20200250A000E46B5
-:10DBE0003C0A8008120A00302A0B0015116000243C
-:10DBF000240D0016240C000C560CFF58325800015E
-:10DC00003C05800890AF001B2407FFBD2416000EC2
-:10DC100001E77024A0AE001B0A000E01325800017B
-:10DC20003C1F800097E5011A50A0FF6F34C600101A
-:10DC30000A000E259289000C8CB300308E960008E5
-:10DC4000240400182674000102C0F809ACB40030A6
-:10DC50008FB100300A000CF9322200041606FF4A88
-:10DC60008FA900240A000E0C241600102410000EA8
-:10DC700052D0FF44241600100A000E0B2416001682
-:10DC8000560DFF36325800013C05800890AF001B4E
-:10DC90002407FFBD2416001001E77024A0AE001B6E
-:10DCA0000A000E01325800010A000E00241600126C
-:10DCB0003C0380008C6201B80440FFFE240408008D
-:10DCC000AC6401B803E00008000000003C058008D7
-:10DCD00094A200483084FFFF1040001924840012F1
-:10DCE00094A900483C0380003128FFFF0104382A32
-:10DCF00010E0001334660180946D01208F8C0004C5
-:10DD0000240B001A31AAFFFF31834000A0CB000B87
-:10DD1000106000102544FFFE94AF004831EEFFFF75
-:10DD200001C4282B14A0000C8F98000CA4C400146C
-:10DD30008F86000C34C2000103E00008AF82000CA3
-:10DD40003C0780002404000334E2018003E0000863
-:10DD5000A044000B8F98000C2419FFFE0319102417
-:10DD600003E00008AF82000C27BDFFD8AFB400204D
-:10DD7000AFB3001CAFB20018AFB10014AFBF0024A6
-:10DD8000AFB000100080182130B3FFFF30D2FFFF8A
-:10DD900030F4FFFF3C1180008E2201B80440FFFEEA
-:10DDA00036300180AE030000024020210E000EDD5F
-:10DDB000AE2300208F86000C8F8500048F83000027
-:10DDC00030C48000A613000CA612000EA605001099
-:10DDD000AE030028A61400081080000E3C0F80003F
-:10DDE000962C0116318BFFFC256A00040151482155
-:10DDF0008D2840003107FFFF14E000072414BFFF07
-:10DE00003C0EFFFF35CD7FFF00CD3024AF86000CE8
-:10DE10003C0F80002414BFFF35F1018000D498240A
-:10DE2000A63300268DF20104AE32002C3C06100011
-:10DE3000ADE601B88FBF00248FB400208FB3001C63
-:10DE40008FB200188FB100148FB0001003E00008EB
-:10DE500027BD002827BDFFD8AFB100143C118000BA
-:10DE600000804021AFB40020AFB0001030D4FFFFDD
-:10DE70003630018002802021AE080000AE2800204C
-:10DE8000AFB3001CAFB2001830F3FFFFAFBF0024E8
-:10DE90000E000EDD30B2FFFF8F85000C8F83000473
-:10DEA0002406BFFF00A62024A612000CA614000E14
-:10DEB000A6130008A6040026A60300103C021000CA
-:10DEC000AE2201B88FBF00248FB400208FB3001C96
-:10DED0008FB200188FB100148FB0001003E000085B
-:10DEE00027BD00283C028000344501803C048000AE
-:10DEF0008C8301B80460FFFE240720002406000282
-:10DF0000A4A70008A0A6000BA4A000103C051000C8
-:10DF1000AC8501B803E00008000000003C0580006B
-:10DF200034A400708C8A000090A601128F84000433
-:10DF300027BDFFF030C300FF0003188230820100CC
-:10DF4000000038211040003924660003308740006B
-:10DF500050E0003930882000000610800045C821BC
-:10DF60008F2F40002478000400187080AFAF0000AD
-:10DF700001C568218DAC4000AFAC000494AB011624
-:10DF80003169FFFC012540218D054000AFA5000847
-:10DF90008FA9000800003021000028213C0708005C
-:10DFA00024E701000A000F9E2408000890420000A8
-:10DFB00024A500012CAD000C0062C8210019C0800E
-:10DFC000030778218DEE000011A0000600CE302658
-:10DFD00003A5102114A8FFF500051A005520FFF431
-:10DFE000904200003C048000348700703C0508002B
-:10DFF0008CA531048CE300002CA80020110000093E
-:10E00000006A3823000558803C0C0800258C310834
-:10E01000016C482124AA0001AD2700003C01080042
-:10E02000AC2A3104AF8600002407000100E0102173
-:10E0300003E0000827BD00101100FFFC000038219C
-:10E0400000066080018558218D6440002469000429
-:10E0500000093880AFA4000000E518218C6640005C
-:10E06000AFA000080A000F8EAFA600043C02080013
-:10E070008C42003827BDFFD8AFB40020AFB20018E3
-:10E08000AFBF0024AFB3001CAFB10014AFB000109D
-:10E090003C14080026940038144000022452FFFF6C
-:10E0A000000090218F85000430A340001060000F15
-:10E0B00030A980003C06002000A620241080000B20
-:10E0C0008F87000C2408BFFF00A8282434E3100029
-:10E0D000AF85000430AF200015E0000A3C110004B9
-:10E0E0002413FFBF0A000FEF0073102415200062F5
-:10E0F0003C0B002030AF200011E0FFF98F83000CB3
-:10E100003C11000400B180241200FFF62413FFBF6D
-:10E110003462004030B801001300000FAF82000CE1
-:10E120003C1F002000BFC824132000053C0A8000CB
-:10E130003C03000400A31024104000C800000000AD
-:10E140009549011E9548011C3126FFFF00083C003F
-:10E1500000C72025AF8400003C0D800095AC010C69
-:10E1600030AB1000116000083186FFFF30AE002098
-:10E1700015C00006241100053C10100000B07824E2
-:10E1800015E000733C1F0C002411000130A20100B7
-:10E19000544000093C0C00018F83001454600006B9
-:10E1A0003C0C00018F87000C30E440001080009A86
-:10E1B0003C0A1F013C0C000100AC302414C0006C70
-:10E1C0003C1080008F84000C3093400012600006E9
-:10E1D0003C0310003C190F0000B9C0241300008B51
-:10E1E0003C1F80003C03100000A310241040002CB2
-:10E1F0003C0680003C0708008CE7003014E0007308
-:10E200003088400030A6010010C000983C0E0F007E
-:10E2100000AE68243C0C020011AC00948F93000007
-:10E22000027280240214782191F4000426920004E2
-:10E23000001221C03C0E800095C6010E3627000258
-:10E2400024D400043286FFFF240500020E000F04D0
-:10E25000000000008FBF00248FB400208FB3001C8B
-:10E260008FB200188FB100148FB000100000102181
-:10E2700003E0000827BD002800AB50241140FF9E9A
-:10E2800030AF20008F8C000C3C0EFFFF35CD7FFFA0
-:10E2900000AD2824358380000A000FDFAF8500041D
-:10E2A0008CD04000320F010011E0003C30B801007A
-:10E2B0003C1008008E1000241300001432330004B8
-:10E2C0003C020F0000A2F8243C19020013F9000FD1
-:10E2D0008F83000094C9010E022038210072582457
-:10E2E0000174502191480004252400043086FFFF6A
-:10E2F00025140004001421C0240500020E000F04A0
-:10E300002412FFFE021280243231FFFB2407000199
-:10E310001207006F3206000114C000903C0E80000E
-:10E32000320F000411E000048F980004331008003D
-:10E33000160000783C1F80005660FFC78FBF002486
-:10E340000E000F63000000000A0010408FBF002481
-:10E350003C190BFF00BFC0243733FFFF0278882B26
-:10E360005220FF8A241100010A00100D241100051B
-:10E370003C0E08008DCE00D8960F010E24040080BC
-:10E3800025CD000131E6FFFF240500023C01080015
-:10E39000AC2D00D80A00103D240700033C120800F1
-:10E3A0008E520024324200011040FFAB8FBF002488
-:10E3B00094C6010E362700020000202124D4000458
-:10E3C0003286FFFF0A00103D240500021100FF8E77
-:10E3D00030A601003C0B0F0000AB50243C090100AB
-:10E3E000012A202B1480FF88000000003C058000DB
-:10E3F00094A6010E362700022404008024D40004D1
-:10E400003286FFFF0A00103D2405000297E3011643
-:10E410000A0010243C03100000AA48243C08100005
-:10E420001528FF653C0C000130CB02001560FF632E
-:10E4300000AC30243C1480009692010E3627000276
-:10E44000000020212645000430A6FFFF0E000F3FEC
-:10E45000240500020A0010408FBF00240E000F7137
-:10E46000000000000A0010008F850004000000007A
-:10E470003C0608008CC600D0000516023050000F84
-:10E4800038DF00012FF900012E03000C0323C02404
-:10E490001700FF68001021C02608FFFC2D070004AC
-:10E4A00014E000073C0E800038CA00022D4900012C
-:10E4B000012320245080000E000532423C0E8000D3
-:10E4C00095C6010E000020210A00103A36270002EE
-:10E4D0003233000452600001363100023C0C8000EF
-:10E4E0009586010E022038210A0010990000202193
-:10E4F0000010182B00C358241560000F3C05800045
-:10E50000001021C03C0E800095C6010E0A00103A92
-:10E510003627000297F9010E022038212404010059
-:10E52000273100043226FFFF0E000F0424050002ED
-:10E530000A0010780000000094AD010E00002021B8
-:10E540002405000225AC00043186FFFF0E000F04F5
-:10E550003227FFFB0A0010EB001021C095C5010E09
-:10E56000022038210000202124AD000431A6FFFF45
-:10E570000E000F04240500020A0010723231FFFB66
-:10E580003C0580008CA701482403000434A60180C8
-:10E5900000072402308200FF104300103C0480007A
-:10E5A0008C8901B80520FFFE000000008C8F014817
-:10E5B000240D00023C0A1000000F7402A4CE0008D3
-:10E5C000A0CD000B8C8C0148A4CC00108C8B014496
-:10E5D000ACCB002403E00008AC8A01B88CA4014055
-:10E5E0003C03800000C028218C6601B804C0FFFEF7
-:10E5F0002408001CACA40000A0A8000B3C051000DF
-:10E60000AC6501B803E000080000000027BDFFE88A
-:10E61000AFB00010AFBF00143C10600C8E0D500066
-:10E62000240EFF7F2406000301AE60243588380CD9
-:10E630003C058000AE085000ACA600083C01080074
-:10E64000AC2000200E001555000000003C086016AC
-:10E650008D0A00003C0BFFFF3C0900103523805160
-:10E660003C046000014B38243C025353AE03537CFE
-:10E67000348420203C05080024A579082406000ADB
-:10E6800010E2000935037C008C7F007C8C790078D7
-:10E690008FB00010AF9F00108FBF001427BD00186F
-:10E6A0000A0013B1AF9900088D0F00043C186000F8
-:10E6B0008FB0001001F818218C7F007C8C790078D5
-:10E6C000AF9F00108FBF001427BD00180A0013B1C0
-:10E6D000AF9900083C0480008C8340003402FFFFA7
-:10E6E0001062003A000000008C87400030E5010015
-:10E6F00010A00021000000009487010E3C020800D9
-:10E700008C4200EC9485010E3C0D08008DAD31CC9F
-:10E7100030E3FFFF3C1808008F1800E83C090800B0
-:10E720008D2931C80043602130ABFFFF0183782B76
-:10E730000000C82101AB18210000502103197021ED
-:10E74000006B302B012A402101CF2021010610212E
-:10E750003C010800AC2C00EC3C010800AC2400E8B3
-:10E760003C010800AC2331CC3C010800AC2231C88C
-:10E7700003E00008000000008C8840008F8C000837
-:10E78000110C00323C0D800095AB010E3C0A0800D4
-:10E790008D4A00E43C0808008D0800E03169FFFF65
-:10E7A000014928210000302100A9602B01063821F1
-:10E7B00000EC10213C010800AC2500E43C010800FD
-:10E7C000AC2200E003E00008000000009483010E8A
-:10E7D0009482010E3C1908008F3900F43C090800AE
-:10E7E0008D2931CC3C0E08008DCE00F03C0808008D
-:10E7F0008D0831C83078FFFF304BFFFF03382821E8
-:10E80000012B1821000078210000502100B8682B4E
-:10E8100001CF6021006B302B010A3821018D2021AE
-:10E8200000E610213C010800AC2500F43C01080082
-:10E83000AC2400F03C010800AC2331CC3C010800C2
-:10E84000AC2231C803E00008000000008C894004BD
-:10E850008F8600101526FFCC3C0D80009483010E9E
-:10E860003C1908008F3931BC3C0E08008DCE31B800
-:10E870003078FFFF03385821000078210178202BE1
-:10E8800001CF682101A450213C010800AC2B31BC10
-:10E890003C010800AC2A31B803E000080000000089
-:10E8A00027BDFFE83C058000AFBF0014AFB00010EB
-:10E8B0008CB00128ACB000208CA301048CA4010012
-:10E8C000AF8300040E000ED6AF84000C0E00115F63
-:10E8D000000000003C0208008C4200C010400026EE
-:10E8E0008F8400043C0708008CE700C424E6000184
-:10E8F0003C010800AC2600C43C0280008C4401248A
-:10E900003C1F6020AFE40014000000003C068000C3
-:10E910003C034000ACC301380000000012000013AB
-:10E920008FBF0014260F0140261900802404FF80A9
-:10E9300001E4C0240324F824001F6940332E007F23
-:10E940000018594031EC007F3C0A20003548000295
-:10E9500001AE3825016C48250128802500E82825CE
-:10E96000ACC50830ACD008308FBF00148FB0001099
-:10E9700003E0000827BD00183C090010008940246E
-:10E980001100000F8F83000C240DBFFF006D602469
-:10E9900011800007240F87FF006F702415C000133B
-:10E9A0003C1900600099C024130000100000000012
-:10E9B0000E000CD2000000000A001221000000002E
-:10E9C0003C0B08008D6B0020256A00013C0108000B
-:10E9D000AC2A00200E000FC5000020211040FFCC03
-:10E9E0003C0680000A0011E93C0280000E00128EF5
-:10E9F000000000000A0012210000000027BDFFE80F
-:10EA00003C028000AFBF00108C4601403C03700008
-:10EA10003C054000AC4600208C4401480083202483
-:10EA20001085001300A4102B1040000B3C072000A1
-:10EA30003C08600010880017000000003C0A4000FD
-:10EA40003C098000AD2A0178000000008FBF001053
-:10EA500003E0000827BD00185487FFF93C0A400076
-:10EA60000E00110A000000000A00123A3C0A4000A1
-:10EA70000E0012B4000000003C0A40003C09800077
-:10EA8000AD2A0178000000008FBF001003E00008ED
-:10EA900027BD00180E001D6F000000000A00123A8A
-:10EAA0003C0A400027BDFFE0AFB200183C128000D6
-:10EAB000AFB10014AFBF001CAFB000100E00112D9D
-:10EAC000365100708E260000AF8600188E28000098
-:10EAD0003C0B08008D6B00FC3C0708008CE700F83D
-:10EAE00001066023016C28210000482100AC302B76
-:10EAF00000E91821006620213C010800AC2500FC3B
-:10EB00003C010800AC2400F88E50000032020003E3
-:10EB10001040FFEE010030218E2600003C05080069
-:10EB20008CA500FC3C1F08008FFF00F800C81823CC
-:10EB300000A378210000102101E3C82B03E2C021CB
-:10EB400003197021320D00013C010800AC2F00FCBC
-:10EB5000AF8800183C010800AC2E00F815A0000892
-:10EB600000000000320800021100FFD60000000083
-:10EB70000E001229000000000A00125B00000000D5
-:10EB80000E0011D2000000000A00128432080002B8
-:10EB90003C0380008C6401003082003E1440000879
-:10EBA00000000000AC6000488C66010030C507C062
-:10EBB00010A0000500000000AC60004CAC600050EC
-:10EBC00003E0000824020001AC600054AC60004087
-:10EBD0008C6801003107380010E0FFF900000000E8
-:10EBE0002402000103E00008AC6000443C039000F4
-:10EBF00034620001008220253C038000AC640020C8
-:10EC00008C65002004A0FFFE0000000003E0000867
-:10EC1000000000003C0280003443000100832025F6
-:10EC200003E00008AC44002027BDFFD8AFB10014BA
-:10EC30003C048000AFBF0020AFB3001CAFB200188F
-:10EC4000AFB000108C9201408C9001482402000E5D
-:10EC500000108C02322300FF1062005902042824A5
-:10EC60002866000F10C00013286A0037240700062A
-:10EC70001067008E286800075100002D2404000949
-:10EC8000106000783C06800024090001106900B083
-:10EC9000000000000000000D8FBF00208FB3001C9B
-:10ECA0008FB200188FB100148FB0001003E000087D
-:10ECB00027BD002811400059240D0038286B00356D
-:10ECC000116000053C058000240C001F146CFFF14E
-:10ECD000000000003C0580008CB801B80700FFFE72
-:10ECE00034B90180AF320000241F00012412000259
-:10ECF0003C021000AF200004A7310008A33F000A27
-:10ED0000A332000BA7300010AF200024AF20002852
-:10ED1000ACA201B88FBF00208FB3001C8FB20018C7
-:10ED20008FB100148FB0001003E0000827BD002849
-:10ED3000106400232405000B1465FFD63218FFFF72
-:10ED4000170000203C0580008F93FED4927F0005C1
-:10ED500033F900041720FFCF000000000E0012A5B9
-:10ED6000024020219269000502402021352800043C
-:10ED70000E0012AFA26800059267000530E20004A1
-:10ED800014400002000000000000000D926B000023
-:10ED900024060020316A00FF1546000A3C05800069
-:10EDA0008CA401B80480FFFE34AD0180240E000560
-:10EDB0003C0C1000ADB20000A1AE000BACAC01B831
-:10EDC0003C0580008CA301B80460FFFE34AF0180D5
-:10EDD00024130002ADE00000ADF20004A5F100082C
-:10EDE000A1F3000AA1F3000BA5F00010ADE0002490
-:10EDF0008CB101443C101000ADF10028ACB001B85A
-:10EE00008FBF00208FB3001C8FB200188FB1001489
-:10EE10008FB0001003E0000827BD0028106DFFAD83
-:10EE2000240E0080146EFF9B000000003C05800053
-:10EE30008CA301B80460FFFE34AF018024120002ED
-:10EE4000A1F2000BA5F10008A5F000108CB301445D
-:10EE50003C021000A5F30012ACA201B80A0012F0A7
-:10EE60008FBF00208CC301B80460FFFE34D3018043
-:10EE7000AE720000AE60000424120001A67100080A
-:10EE800024110002A272000AA271000BA6700010E9
-:10EE90008CD001443C0F1000AE700024AE600028FE
-:10EEA000ACCF01B80A00132B8FBF00203C038000B9
-:10EEB0008C6601B804C0FFFE346201803C06080085
-:10EEC00090C67AB8AC52000010C000030000382190
-:10EED0003C0708008CE77AC03C05800034AA01801A
-:10EEE0002404000234CC0001AC470004A551000802
-:10EEF000A14C000AA144000BA55000108CAB0144AA
-:10EF00000000202101402821AD4B002410C0000347
-:10EF10008FBF00203C0408008C847ABC8FB3001C97
-:10EF20008FB200188FB100148FB000103C0E10008B
-:10EF30003C0D800027BD0028ACA40028ADAE01B870
-:10EF40003C010800A0207AB803E00008000000009F
-:10EF500010A0000B3C0680008C980144241900028C
-:10EF60003C010800A0397AB83C010800AC327AC0F4
-:10EF70003C010800AC387ABC0A00132B8FBF00207C
-:10EF80008CDF01B807E0FFFE34C7018024090002CE
-:10EF9000ACE00000ACF20004A4F10008A0E9000A13
-:10EFA000A0E9000BA4F00010ACE000248CC80144E0
-:10EFB0003C021000ACE80028ACC201B80A00132BD8
-:10EFC0008FBF002027BDFFE8AFBF00100E000ED698
-:10EFD000000000003C0280008FBF001000002021D4
-:10EFE000AC4001800A000FC527BD00183084FFFF28
-:10EFF00030A5FFFF108000070000182130820001BB
-:10F000001040000200042042006518211480FFFB1C
-:10F010000005284003E000080060102110C0000730
-:10F02000000000008CA2000024C6FFFF24A50004FD
-:10F03000AC82000014C0FFFB2484000403E000083D
-:10F040000000000010A0000824A3FFFFAC86000011
-:10F0500000000000000000002402FFFF2463FFFF07
-:10F060001462FFFA2484000403E00008000000009A
-:10F0700027BDFFE0AFB20018AFB10014AFB0001071
-:10F08000AFBF001C9486000C00A0902124900014B7
-:10F0900000061B020003108000448821000030217C
-:10F0A00000A020210E0013BB240500050211202B17
-:10F0B0001080001200001021920300002C6500094E
-:10F0C00050A0000992020001000348803C0A080099
-:10F0D000254A793C012A40218D07000000E0000804
-:10F0E0000000000092020001020280210211202B88
-:10F0F0005480FFF292030000000010218FBF001C1B
-:10F100008FB200188FB100148FB0001003E0000818
-:10F1100027BD00200A0013D526100001920C000123
-:10F12000240B000C158B0040023070232DCD000AFB
-:10F1300015A0003D260800068E43000026020002AE
-:10F1400034640100AE440000921F00029059000197
-:10F15000904E0002904B0003001F7E000019C40077
-:10F1600001F86025000E6A00018D5025014B4825ED
-:10F17000AE490004920700069105000191040002C7
-:10F180009119000300071E00000534000066F825F1
-:10F190000004120003E2C025031978252610000A96
-:10F1A0000A0013D5AE4F0008921F0001260400028A
-:10F1B0002410000257F00001022020210A0013D57C
-:10F1C00000808021920E0001240D000315CDFFCB9D
-:10F1D000240200018E59000092180002261000033C
-:10F1E000372F0008A25800100A0013D5AE4F0000B8
-:10F1F000920500012406000414A6FFC024020001A9
-:10F20000920C0002920B00038E490000000C520089
-:10F21000014B40253527000426100004AE48000CA1
-:10F220000A0013D5AE4700000A0013E924020001CA
-:10F2300027BDFFE8AFBF0014AFB000100E0012A54D
-:10F24000008080213C048008348300809065002584
-:10F250000200202134A200200E0012AFA06200257F
-:10F26000020020218FBF00148FB000100A000C9EF6
-:10F2700027BD00183C03800027BDFFF834620180E1
-:10F28000AFA20000308C00FF30AD00FF30CE00FF99
-:10F290003C0B80008D6401B80480FFFE000000007C
-:10F2A0008FA900008D6801288FAA00008FA7000099
-:10F2B0008FA400002405000124020002A085000A9A
-:10F2C0008FA30000359940003C051000A062000BA0
-:10F2D0008FB800008FAC00008FA600008FAF000039
-:10F2E00027BD0008AD280000AD400004AD8000241B
-:10F2F000ACC00028A4F90008A70D0010A5EE00126C
-:10F3000003E00008AD6501B83C06800827BDFFE8B2
-:10F3100034C50080AFBF001090A70009240200127E
-:10F3200030E300FF1062000B008030218CA80050F9
-:10F3300000882023048000088FBF00108CAA0034AE
-:10F34000240400390000282100CA482305200005B4
-:10F35000240600128FBF00102402000103E0000801
-:10F3600027BD00180E001447000000008FBF0010DA
-:10F370002402000103E0000827BD001827BDFFC8D4
-:10F38000AFB1002C00A08821AFB2003027A500103B
-:10F390000080902102202021AFBF00340E0013C650
-:10F3A000AFB00028144000813C0C8008918B001104
-:10F3B000918A0012358600808CC80054316500FFA8
-:10F3C000314900FF00A9282100A8382B14E0004F84
-:10F3D0008FA3001094DF005C3066000410C000565C
-:10F3E00033E4FFFF8FA2001C0082102B5440000565
-:10F3F0002C8300803067000414E0007E240402188F
-:10F400002C83008010600002008080212410008086
-:10F410000E0012A5024020213C03800834660080C3
-:10F4200024070001ACC7000C90C200080010604027
-:10F4300034670100305F007FA0DF00088E390004D0
-:10F4400027380001ACD80030A4D0005C8CCE003C42
-:10F45000962F000E01CF6821ACCD00208CCB003C54
-:10F46000016C5021ACCA001C8E290004ACE90000DC
-:10F470008E250008ACE500048FA8001031040008B8
-:10F480005480002F93A60020A0C0004E90C5004ECF
-:10F490002408FFDF3C188008A0E5000890C400089D
-:10F4A000370C00802409005000888024A0D0000878
-:10F4B0008E390008AD9900388F0E00148D8F003002
-:10F4C00001CF6821AD8D0034918B0000316A00FFBF
-:10F4D00011490029264801000E0012AF02402021E8
-:10F4E00024040038000028210E0014472406000AD6
-:10F4F0008FBF00348FB200308FB1002C8FB0002846
-:10F500002402000103E0000827BD003894D8005C05
-:10F510008CD00054330EFFFF0205782301CF682BF7
-:10F5200015A0FFAC8FA300108CD9005430660004E6
-:10F5300014C0FFAC032520230A0014A52C82021856
-:10F540003C188008370C0080A0E600088E390008BF
-:10F5500024090050AD9900388F0E00148D8F0030B3
-:10F5600001CF6821AD8D0034918B0000316A00FF1E
-:10F570001549FFD9264801002406FF8001062824EA
-:10F580003C048000AC8500288E2700083103007FF2
-:10F590003C10800C0070F821AFE700D08E220008EC
-:10F5A000AF9F00240A0014E0AFE200D48E230008CD
-:10F5B0003C04800834820080AC4300540240202187
-:10F5C0000E001436AC400030240400382405008DB1
-:10F5D0000E001447240600128FBF00348FB2003093
-:10F5E0008FB1002C8FB000282402000103E0000836
-:10F5F00027BD00380A0014AA8FA4001C27BDFFE80D
-:10F60000AFBF001090A6000D30C7001010E0000C36
-:10F61000008040213C0280088C4400048CA3000838
-:10F620001064000830C9000430C5000410A0001C9C
-:10F630008FBF00102402000103E0000827BD00185E
-:10F6400030C900041120001030CB001210E0FFF987
-:10F650008FBF00103C0880088CA700088D060004AE
-:10F6600014E6FFF524020001240400382405008D6F
-:10F670000E001447240600128FBF00102402000160
-:10F6800003E0000827BD0018240A0012156AFFE9EC
-:10F690008FBF0010010020210A00148927BD001827
-:10F6A000000020210A000CB827BD00183C05080006
-:10F6B00024A555983C040800248473583C02080093
-:10F6C000244255A0240300063C010800AC257AC85A
-:10F6D0003C010800AC247ACC3C010800AC227AD072
-:10F6E0003C010800A0237AD403E0000800000000D9
-:10F6F00003E00008240200013C028000308800FF83
-:10F70000344701803C0680008CC301B80460FFFED2
-:10F71000000000008CC501282418FF803C0D800AE1
-:10F7200024AF010001F8702431EC007FACCE00243E
-:10F73000018D2021ACE50000948B00DA35096000D2
-:10F7400024080002316AFFFFACEA00042402000131
-:10F75000A4E90008A0E8000BACE000243C0710007E
-:10F76000ACC701B8AF84002403E00008AF850054A3
-:10F770008C9900048F8D00242409FFBF0325C0232A
-:10F78000AC98000491AF00C42403FFEF31EE007F7A
-:10F79000A1AE00C48C8C0020938B00308F86002497
-:10F7A000358A0002AF8B0048A7800044AC8A002055
-:10F7B000A4C000AC90C800C401093824A0C700C48C
-:10F7C0008F840024AC8000DC908500C400A310244A
-:10F7D00003E00008A08200C43C02800034450180A0
-:10F7E0003C0480008C8301B80460FFFE8F890054C4
-:10F7F0002407608324060002ACA900008C88012441
-:10F80000ACA80004A4A70008A0A6000B3C051000AB
-:10F8100003E00008AC8501B8938800308F89004868
-:10F820008F82002430C600FF0109382330E900FF31
-:10F830000122182130A500FF2468007810C00002C2
-:10F84000012438210080382130E4000314800003B3
-:10F8500030AA00031140000D312B000310A0000955
-:10F860000000102190ED0000244E000131C200FF85
-:10F870000045602BA10D000024E700011580FFF971
-:10F880002508000103E00008000000001560FFF3F8
-:10F890000000000010A0FFFB000010218CF8000009
-:10F8A00024590004332200FF0045782BAD180000D6
-:10F8B00024E7000415E0FFF92508000403E0000830
-:10F8C0000000000093850030938800408F87004837
-:10F8D000000432003103007F00E5102B30C47F00AC
-:10F8E0001040000F006428258F8400243C0980000C
-:10F8F0008C8A00DCAD2A00A43C03800000A35825BC
-:10F90000AC6B00A08C6C00A00580FFFE0000000026
-:10F910008C6D00ACAC8D00DC03E000088C6200A8AC
-:10F920000A0015E88F840024938800413C0280007F
-:10F9300000805021310300FEA383004130ABFFFF64
-:10F9400030CC00FF30E7FFFF344801803C098000E5
-:10F950008D2401B80480FFFE8F8D005424180016FA
-:10F96000AD0D00008D2201248F8D0024AD02000416
-:10F970008D590020A5070008240201B4A119000A2E
-:10F98000A118000B952F01208D4E00088D47000413
-:10F99000978300448D59002401CF302100C72821CE
-:10F9A00000A320232418FFFFA504000CA50B000EC4
-:10F9B000A5020010A50C0012AD190018AD18002406
-:10F9C00095AF00D83C0B10002407FFF731EEFFFF86
-:10F9D000AD0E00288DAC0074AD0C002CAD2B01B821
-:10F9E0008D46002000C7282403E00008AD45002014
-:10F9F0008F8800240080582130E7FFFF910900C65E
-:10FA00003C02800030A5FFFF312400FF00041A00F3
-:10FA10000067502530C600FF344701803C09800054
-:10FA20008D2C01B80580FFFE8F820054240F001733
-:10FA3000ACE200008D390124ACF900048D7800207F
-:10FA4000A4EA0008241901B4A0F8000AA0EF000BF2
-:10FA5000952301208D6E00088D6D0004978400446D
-:10FA600001C35021014D602101841023A4E2000C48
-:10FA7000A4E5000EA4F90010A4E60012ACE0001406
-:10FA80008D780024240DFFFFACF800188D0F006C5A
-:10FA9000ACEF001C8D0E00683C0F1000ACEE002097
-:10FAA000ACED0024950A00AE240DFFF73146FFFFB0
-:10FAB000ACE60028950C00709504007231837FFF3E
-:10FAC0000003CA003082FFFF0322C021ACF8002CE3
-:10FAD000AD2F01B8950E00728D6A002000AE302166
-:10FAE000014D2824A506007203E00008AD65002042
-:10FAF0003C028000344601803C0580008CA301B8A4
-:10FB00000460FFFE24090018ACC40000A0C9000B6B
-:10FB10008F8800243C041000950700AEA4C7001095
-:10FB2000ACC0003003E00008ACA401B83C02800087
-:10FB3000344501803C0480008C8301B80460FFFEE2
-:10FB40008F8A002C240600199549001C3128FFFFDC
-:10FB5000000839C0ACA70000A0A6000B3C051000AF
-:10FB600003E00008AC8501B88F8700340080402195
-:10FB700030C400FF3C0680008CC201B80440FFFE88
-:10FB80008F8900549383005034996000ACA9000021
-:10FB9000A0A300058CE20010240F00022403FFF74D
-:10FBA000A4A20006A4B900088D180020A0B8000A7D
-:10FBB000A0AF000B8CEE0000ACAE00108CED00048A
-:10FBC000ACAD00148CEC001CACAC00248CEB002021
-:10FBD000ACAB00288CEA002C3C071000ACAA002C2F
-:10FBE0008D090024ACA90018ACC701B88D05002010
-:10FBF00000A3202403E00008AD04002093850050FA
-:10FC00002403000127BDFFE800A330042CA200203C
-:10FC1000AFB00010AFBF001400C018211040001397
-:10FC20002410FFFE3C0708008CE7319000E610240A
-:10FC30003C0880003505018014400005240600843E
-:10FC40008F890024240A00042410FFFFA12A00EC5D
-:10FC50000E00168400000000020010218FBF001467
-:10FC60008FB0001003E0000827BD00183C06080014
-:10FC70008CC631940A0016B600C310248F87002C5E
-:10FC800027BDFFE0AFB20018AFB10014AFB0001055
-:10FC9000AFBF001C30D000FF90E6000D00A088210F
-:10FCA0000080902130C5007FA0E5000D8F850024E5
-:10FCB0008E2300188CA200C01062002E240A000EB1
-:10FCC0000E0016A9A38A00502409FFFF1049002244
-:10FCD0002404FFFF52000020000020218E26000097
-:10FCE0003C0C001000CC5824156000393C0E000874
-:10FCF00000CE682455A0003F024020213C1800029D
-:10FD000000D880241200001F3C0A00048F87002CBA
-:10FD10008CE200148CE300108CE500140043F823FF
-:10FD200003E5C82B13200005024020218E24002C5F
-:10FD30008CF10010109100310240202124020012A9
-:10FD4000A38200500E0016A92412FFFF10520002D9
-:10FD50002404FFFF000020218FBF001C8FB2001879
-:10FD60008FB100148FB000100080102103E0000854
-:10FD700027BD002090A800C4350400200A0016DF2B
-:10FD8000A0A400C400CA48241520000B8F8B002CAF
-:10FD90008F8D002C8DAC00101580000B02402021AF
-:10FDA0008E2E002C51C0FFEC0000202102402021AB
-:10FDB0000A0016FA240200178D66001050C0FFE6F4
-:10FDC00000002021024020210A0016FA240200111E
-:10FDD00002402021240200150E0016A9A382005023
-:10FDE000240FFFFF104FFFDC2404FFFF0A0016E979
-:10FDF0008E2600000A001720240200143C0800048C
-:10FE000000C8382450E0FFD4000020210240202107
-:10FE10000A0016FA240200138F86002427BDFFE093
-:10FE2000AFB10014AFBF0018AFB0001090C300C452
-:10FE300030A500FF306200201040000800808821BB
-:10FE40008CCB00C02409FFDF256A0001ACCA00C0CA
-:10FE500090C800C401093824A0C700C414A0004001
-:10FE60003C0C80008F840024908700C42418FFBFBE
-:10FE70002406FFEF30E3007FA08300C4979F004477
-:10FE80008F8200488F8D002403E2C823A799004485
-:10FE9000A5A000AC91AF00C401F87024A1AE00C4CD
-:10FEA0008F8C0024A18000C78F8A0024A540007297
-:10FEB000AD4000DC914500C400A65824A14B00C40D
-:10FEC0008F9000208F8400489786004402042821E8
-:10FED00010C0000FAF850020A38000403C078000C9
-:10FEE0008E2C000894ED01208E2B0004018D5021F2
-:10FEF000014B8021020620233086FFFF30C8000F0F
-:10FF0000390900013131000116200009A3880040A1
-:10FF1000938600308FBF00188FB100148FB000108F
-:10FF200027BD0020AF85004C03E00008AF860048E5
-:10FF300000C870238FBF0018938600308FB1001463
-:10FF40008FB0001034EF0C00010F282127BD0020D6
-:10FF5000ACEE0084AF85004C03E00008AF8600489B
-:10FF600035900180020028210E00168424060082AC
-:10FF70008F840024908600C430C5004050A0FFBA92
-:10FF8000A38000508F8500343C0680008CCD01B8E2
-:10FF900005A0FFFE8F890054240860822407000218
-:10FFA000AE090000A6080008A207000B8CA30008F9
-:10FFB0003C0E1000AE0300108CA2000CAE02001428
-:10FFC0008CBF0014AE1F00188CB90018AE190024A5
-:10FFD0008CB80024AE1800288CAF0028AE0F002C7F
-:10FFE000ACCE01B80A001744A38000508F8A0024C9
-:10FFF00027BDFFE0AFB10014AFB000108F880048FC
-:020000040001F9
-:10000000AFBF001893890028954200AC30D100FFA3
-:100010000109182B0080802130AC00FF3047FFFF22
-:100020000000582114600003310600FF0120302138
-:1000300001095823978300440068202B1480001B7B
-:100040000000000010680043240A0001118A0048E3
-:1000500034E708803165FFFF0E00162602002021DC
-:100060000E0016668F8400548F840024948D0070D7
-:1000700025AC0001A48C0070948B00703C06080035
-:100080008CC6318831677FFF10E6004F000000000A
-:1000900002002021022028218FBF00188FB10014F8
-:1000A0008FB000100A00173027BD0020914400C413
-:1000B0002406FF8000868825A15100C4978400444F
-:1000C0003088FFFF1100001C938900288F8E0024C8
-:1000D0002419EFFF008BF82395D800AC0168682B3A
-:1000E00033E900FF03197824A5CF00AC51A0002A02
-:1000F000010058218E0500202408FFFB2403000185
-:1001000000A81024AE0200201183002534E78000EF
-:10011000020020213165FFFF0E001626012030214C
-:10012000978B00448F870048A780004400EB802312
-:10013000AF900048938900288F8C00248FBF00184F
-:100140008FB100148FB0001027BD002003E000081D
-:10015000A18900C78E0800202409FFFB34E7800036
-:1001600001092824AE050020158AFFBA34E708806B
-:10017000020020210E0015F43165FFFF020020214E
-:10018000022028218FBF00188FB100148FB00010FB
-:100190000A00173027BD00200A0017E70000482199
-:1001A000020020213165FFFF0E0015F401203021EF
-:1001B000978B00448F870048A780004400EB802382
-:1001C0000A0017F7AF90004894890070240A800055
-:1001D000012A4024A48800709085007090990070D6
-:1001E00030A200FF000219C20003F827001FC1C09F
-:1001F000332F007F01F87025A08E00700A0017CF02
-:10020000020020218F88002424030001910A007835
-:10021000910500C7250900783147003F24E6FFE03B
-:1002200000C318042CC2002030670019A3850028E1
-:100230001040001AAF8900343C0A8000354B0002A0
-:10024000240500012406000114E00016006B1024B0
-:10025000000028211440000F306300201060000FC0
-:10026000240500018D0600748D1900742403FF809D
-:1002700000C31024000279403338007F01F868255C
-:100280003C0E100001AE6025AD4C083091280001F5
-:10029000310600010A0017A50000000003E0000875
-:1002A000000000008D0F00748D0D00742418FF8075
-:1002B00001F87024000E414031AC007F010C502544
-:1002C0003C0B1000014B38253C0980000A0017A5A3
-:1002D000AD27083027BDFFD8AFB000108F90003495
-:1002E000AFB40020AFB10014AFBF0024AFB3001C07
-:1002F000AFB200188E0500103C0208008C4231B0ED
-:100300008F86003830A73FFF00E2182B8CD20014F4
-:10031000008088218CD30020106000070000A021FD
-:1003200090CB000D240AFF80014B4824312800FFA8
-:100330001500000C00056382022020212411000D0D
-:10034000A39100508FBF00248FB400208FB3001CF6
-:100350008FB200188FB100148FB000100A0016A9D8
-:1003600027BD00283185000354A0FFF4022020217E
-:1003700094CF001C8F8E00248E070028A5CF00D8B4
-:100380008CCD0010024D302310E6005C2402001FCB
-:100390000E0016A9A3820050241FFFFF105F004E1D
-:1003A0002404FFFF8F83003C8F88002C0263982178
-:1003B0008D090010012310238F83001CAD02001053
-:1003C000AD1300208C67007400F3202B14800062B2
-:1003D000022020218F8600388E0C00248CC500243A
-:1003E0001185000702202021240E001C0E0016A9F2
-:1003F000A38E0050240DFFFF104D00372404FFFF93
-:100400008F84002C8C980024270F0001AC8F0024CF
-:10041000127200448F99001C8F32007412530041F5
-:100420003C0A00808E090000012A10241440003A82
-:10043000000000008E0400142412FFFF109200063A
-:10044000240B001B022020210E0016A9A38B0050B4
-:10045000105200212404FFFF8E0300003C0C000119
-:10046000006C282410A000133C0600800066A02425
-:10047000168000090200282102202021240E001AE3
-:100480000E0016A9A38E0050240DFFFF104D001280
-:100490002404FFFF02002821022020210E0016C99B
-:1004A000240600012410FFFF2404FFFF1050000A5F
-:1004B000241400018F8F002C022020210280302183
-:1004C00095F2003424050001265800010E0017A5FE
-:1004D000A5F80034000020218FBF00248FB4002035
-:1004E0008FB3001C8FB200188FB100148FB00010B2
-:1004F0000080102103E0000827BD00288F83003C06
-:1005000000E3C8210259C02B1300FFA88F88002CDC
-:100510000A00188E24020018AC8000200A0018B8C7
-:100520008E0400148E1F00003C07008003E798240F
-:100530001660FFF92408001A022020210E0016A9D7
-:10054000A38800502403FFFF1443FFBA2404FFFFD5
-:100550000A0018E18FBF0024240B001D0E0016A90D
-:10056000A38B0050240AFFFF144AFF9A2404FFFFC4
-:100570000A0018E18FBF00248F85002427BDFFD813
-:10058000AFB3001CAFB20018AFB10014AFB0001091
-:10059000AFBF002090A700C48F9000342412FFFF4B
-:1005A00034E2004092060000A0A200C48E030010B6
-:1005B000008098211072000630D1003F2408000D01
-:1005C0000E0016A9A3880050105200262406FFFF33
-:1005D0008F8A00248E0900188D4400C01124000762
-:1005E000240C000E026020210E0016A9A38C0050DE
-:1005F000240BFFFF104B001B2406FFFF24040020E8
-:10060000122400048F8D002491AF00C435EE002029
-:10061000A1AE00C48F85003C10A0001A00000000AD
-:100620001224004B8F9800248F92FED42406FFFDE5
-:10063000971000709651000A1230000B8FBF0020F7
-:100640003C1F08008FFF318C03E5C82B1720001ECC
-:1006500002602021000028210E0017A524060001B9
-:10066000000030218FBF00208FB3001C8FB2001814
-:100670008FB100148FB0001000C0102103E00008FB
-:1006800027BD00285224002A8E0300148F840024E2
-:100690009489007025280001A48800709487007058
-:1006A0003C0508008CA5318830E27FFF1045000E24
-:1006B00000000000026020210E0017302405000118
-:1006C0000A001943000030212402002DA3820050AB
-:1006D0000E0016A92413FFFF1453FFE12406FFFFA9
-:1006E0000A0019448FBF00209498007024198000DC
-:1006F0002405000103199024A492007090910070C9
-:10070000908D0070323000FF001079C2000F70270A
-:10071000000E61C031AB007F016C5025A08A0070D3
-:100720000E001730026020210A001943000030211A
-:100730002406FFFF1466FFD68F8400240260202168
-:100740000E001730240500010A0019430000302173
-:10075000026020210A00195D2402000A8F8800240B
-:1007600027BDFFE8AFB00010AFBF0014910A00C46E
-:100770008F87003400808021354900408CE60010CE
-:10078000A10900C43C0208008C4231B030C53FFFD3
-:1007900000A2182B106000078F850038240DFF8001
-:1007A00090AE000D01AE6024318B00FF1560000893
-:1007B0000006C382020020212403000D8FBF001415
-:1007C0008FB0001027BD00180A0016A9A38300509F
-:1007D00033060003240F000254CFFFF7020020214C
-:1007E00094A2001C8F85002424190023A4A200D801
-:1007F0008CE8000000081E02307F003F13F900352E
-:100800003C0A00838CE800188CA600C01106000882
-:10081000000000002405000E0E0016A9A38500505C
-:100820002407FFFF104700182404FFFF8F850024D2
-:1008300090A900C435240020A0A400C48F8C002CF3
-:10084000918E000D31CD007FA18D000D8F83003C76
-:100850001060001C020020218F8400388C9800104A
-:100860000303782B11E0000D241900180200202149
-:10087000A39900500E0016A92410FFFF105000028B
-:100880002404FFFF000020218FBF00148FB0001050
-:100890000080102103E0000827BD00188C8600109E
-:1008A0008F9F002C0200202100C31023AFE2001014
-:1008B000240500010E0017A5240600010A0019CC2A
-:1008C000000020210E001730240500010A0019CC79
-:1008D00000002021010A5824156AFFD98F8C002CB2
-:1008E000A0A600EC0A0019B9A386004227BDFFD8D4
-:1008F000AFB000108F900034AFB20018AFBF00202F
-:10090000AFB3001CAFB100148E1100103C030800FF
-:100910008C6331B032253FFF00A3102B104000083C
-:10092000008090218F8600382409FF8090CA000D36
-:10093000012A4024310700FF14E0000B00116B82F4
-:10094000024020212412000DA39200508FBF0020EE
-:100950008FB3001C8FB200188FB100148FB000103D
-:100960000A0016A927BD002831AC0003240B0001A2
-:10097000558BFFF40240202190CF000D31EE00088E
-:1009800011C000608F93003C16600009240200270C
-:100990008E19000C8CD80020173800052402002086
-:1009A0008E0200088CDF0024105F0040240200202B
-:1009B0000E0016A9A38200502406FFFF1046003344
-:1009C0002404FFFF8F99002C240AFFF73C13800EAC
-:1009D0009329000D2404FF803C0D8000012AF82497
-:1009E000A33F000D8F99001C3C0808008D0831AC16
-:1009F0008F830054972700788F9F002C01031021CC
-:100A000030E57FFF000530400046782131F8007F57
-:100A10000313602101E47024ADAE002CA591000009
-:100A20008FEB0028256A0001AFEA00288FE3002C35
-:100A30008E09002C00694021AFE8002C8E07002CA5
-:100A4000AFE700308E050014AFE5003497E6003ABA
-:100A500024C20001A7E2003A973300783C10080056
-:100A60008E1031B02663000130717FFF12300027F5
-:100A7000006030218F8F001C0240202124050001DE
-:100A80000E001730A5E60078000020218FBF00205F
-:100A90008FB3001C8FB200188FB100148FB00010FC
-:100AA0000080102103E0000827BD00288E050014F7
-:100AB0002413FFFF10B3001D8F8300248E0800183D
-:100AC0008C6700C0150700092402000E8E0A00245E
-:100AD0008CC9002815490005240200218E07002832
-:100AE0008CCB002C10EB00132402001F0E0016A963
-:100AF000A38200501453FFB32404FFFF0A001A4ED0
-:100B00008FBF00200A001A1624020024240E800041
-:100B1000006E682431ACFFFF000C5BC2317100FF36
-:100B2000001180270A001A47001033C00A001A6516
-:100B3000240200258E05002C10A0FFEC24020023C7
-:100B40008F8E001C8DCD007401A5602B1580FFE7F2
-:100B5000240200268CCF001400A7C02101F8202B0E
-:100B60001080FF998F99002C024020210A001A65FD
-:100B70002402002227BDFFE0AFB000108F900034A8
-:100B8000AFB10014AFBF00188E0500103C03080081
-:100B90008C6331B00080882130A43FFF0083102B8C
-:100BA000104000078F8600382409FF8090CA000D8E
-:100BB000012A4024310700FF14E000098F8B003C1C
-:100BC0002410000D02202021A39000508FBF001898
-:100BD0008FB100148FB000100A0016A927BD0020A5
-:100BE000116000080005C3828F8F00248F8EFED411
-:100BF0002407FFFD95EC007095CD000A11AC00387C
-:100C00008FBF00183305000314A00010000000007F
-:100C10009219000213200041000000008E060024FB
-:100C200050C0000F92040003022020212402000F74
-:100C30000E0016A9A38200502408FFFF14480007E5
-:100C40002407FFFF0A001AE28FBF001890C3000DAF
-:100C50003064000810800037022020219204000335
-:100C600024070002308900FF15270005308F00FFA0
-:100C70008F8A003C11400031240C002C308F00FF83
-:100C800039E500102CAD00012DEE000102002821F5
-:100C900001CD30250E0016C9022020212410FFFFAF
-:100CA0001050000E2407FFFF8F83003C10600017D8
-:100CB000022020213C1908008F39318C0323C02BDE
-:100CC0005700000C2411002D0220202100002821B3
-:100CD0000E0017A524060001000038218FBF001860
-:100CE0008FB100148FB0001000E0102103E0000865
-:100CF00027BD00200E0016A9A39100501450FFF646
-:100D00002407FFFF0A001AE28FBF00180E001730F9
-:100D1000240500010A001AE1000038218CDF0024BC
-:100D20008E020024545FFFC1022020210A001AC253
-:100D3000920400030A001AB62402001002202021A7
-:100D40000E0016A9A38C0050240BFFFF104BFFE3ED
-:100D50002407FFFF0A001AC99204000330A500FF10
-:100D60002406000124A9000100C9102B1040000C2A
-:100D700000004021240A000100A61823308B000146
-:100D800024C60001006A38040004204211600002F9
-:100D900000C9182B010740251460FFF800A618238E
-:100DA00003E000080100102127BDFFD8AFB00018F4
-:100DB0008F900034AFB1001CAFBF00202403FFFFB1
-:100DC0002411002FAFA30010920600002405000894
-:100DD00026100001006620260E001B01308400FF53
-:100DE00000021E003C021EDC34466F410A001B2933
-:100DF0000000102110A000090080182124450001E6
-:100E000030A2FFFF2C4500080461FFFA00032040D8
-:100E10000086202614A0FFF9008018210E001B0177
-:100E2000240500208FA300102629FFFF313100FF89
-:100E300000034202240700FF1627FFE201021826E2
-:100E400000035027AFAA0014AFAA00100000302101
-:100E500027A8001027A7001400E6782391ED0003CF
-:100E600024CE000100C8602131C600FF2CCB000455
-:100E70001560FFF9A18D00008FA200108FBF002028
-:100E80008FB1001C8FB0001803E0000827BD0028B8
-:100E90009383003027BDFFE024020034AFB100147B
-:100EA000AFB00010AFBF001CAFB2001800808821A7
-:100EB0001062006200A080219204000414800045AA
-:100EC0008F880024A38000288E0500048D0600C8AA
-:100ED0003C0700FF34E3FFFF00A3282400C5102BCC
-:100EE0001440004DAF85003C978A00448F8700482E
-:100EF0000147102310A00032A78200448F98001CE5
-:100F0000304CFFFF9312007C0012788231F1000117
-:100F10000011708001C56821018D582B116000619E
-:100F20008F8600248F8900208F84004C1089005EFA
-:100F30003C023F018E1F00003C10250003E2C82444
-:100F40001730007A8F8400348F8700348F86002416
-:100F50008CE30000ACC300788CE50010ACC50088C1
-:100F60008F8700488F85003C938D002830AE0003AA
-:100F7000000E4023310A0003014D4021A3880028C0
-:100F800094CB00AC01276021AF8C002035691000A4
-:100F9000A4C900AC1620005101452021AF840048AF
-:100FA000000020218FBF001C8FB200188FB10014E9
-:100FB0008FB000100080102103E0000827BD002042
-:100FC0008F840020AF800048008730210A001B92E8
-:100FD000AF860020241F000CA39F00500E0016A90E
-:100FE000022020212419FFFF1059FFEE2404FFFFE7
-:100FF0008F880024A38000288E0500048D0600C879
-:101000003C0700FF34E3FFFF00A3282400C5102B9A
-:101010001040FFB5AF85003C0220202124090019B3
-:10102000A38900500E0016A92411FFFF1051FFDD07
-:101030002404FFFF0A001B648F85003C8F8400247A
-:101040008F8700348CF20030908600C430C50010C9
-:1010500014A000108F8300482C680005150000289C
-:1010600000000000908A00C4246BFFFC314900108E
-:1010700015200008316400FF8F8D004C8F8C0020FC
-:1010800011AC0004388F000131EE000115C0002FB3
-:10109000000000000E001B14000000000A001BEB03
-:1010A000000000008F890020938D002830AE0003DF
-:1010B000000E4023310A0003014D4021A38800287F
-:1010C00094CB00AC01276021AF8C00203569100063
-:1010D000A4C900AC1220FFB101452021251800044D
-:1010E000A398002894CF00AC24920004AF9200484B
-:1010F00035F12000A4D100AC0A001B930000202190
-:101100008C8200DC1242FF6C022020212418000592
-:10111000A39800500E0016A92412FFFF1452FF6678
-:101120002404FFFF0A001B948FBF001C30E500FF62
-:101130000E0015B0000030218F8600248F870048F4
-:101140008F8900200A001B848F85003C0E0015DB70
-:10115000000000000A001BEB000000009383004227
-:1011600027BDFFE024020002AFB20018AFB10014A7
-:10117000AFBF001C00808821AFB00010000090219C
-:10118000106200552404FFFD978300448F850048BA
-:101190003066FFFF00C5202B1480005B9387003072
-:1011A0003C0880009504012010E500528F8A002041
-:1011B0008F84004C30A500FF0E0015B024060001FE
-:1011C0008F9F00543C0580003C19408027ED01783A
-:1011D00031B00078240EFF800219582534AF090081
-:1011E00031B8000701AE6024ACAC0800030F8021C9
-:1011F000ACAB081002202021020028210E001B4E5B
-:10120000AF9000342403FFFF104300332404FFFF9A
-:101210008E0C00103C0708008CE731B092060000ED
-:1012200031843FFF0087102B1040002330CD003F5A
-:101230008F980054000471803C0408008C8431A80D
-:101240002409FF809390004100984021010E202145
-:1012500000897024000E51403C0980003099007FC5
-:101260003C0F00808F8800243525094035E20001BD
-:1012700001593825308B0078308600073C03100078
-:101280003C1F800C00C5C0210162582500E3502599
-:10129000033F782136050001AD2E0804AF980038D1
-:1012A000AD2B0814AF8F002CAD2E0028AD040074B8
-:1012B000AD2A0830A3850041938300422410000327
-:1012C0005070002725A3FFE0240C0001106C001CC7
-:1012D00024060023024020218FBF001C8FB200187B
-:1012E0008FB100148FB000100080102103E00008BF
-:1012F00027BD0020314900035520FFAE8F84004CEC
-:101300000A001C278F90004C8F84004C306500FF32
-:101310000E0015B024060001938B00302405003424
-:1013200011650018978300448F8500483062FFFFE5
-:1013300000A25823AF8B00480A001C5FA78000441E
-:1013400011A6003700000000022020212411000B0C
-:101350000E0016A9A39100500A001C5F00409021C6
-:101360002C7200201240FFF80003F8803C070800B0
-:1013700024E7796003E7C8218F2D000001A0000851
-:10138000000000008F8500482CA200055440001D7D
-:10139000A7800044978A00443148FFFF00A84823F3
-:1013A0002D2F000511E00003314400FF24AEFFFCA7
-:1013B00031C400FF8F90004C8F9800201218000459
-:1013C00038990001332D000115A00029000000000C
-:1013D0008F910024922500C434A30010A22300C4DE
-:1013E000978300448F8500488F8400243062FFFF7C
-:1013F00000A25823AC8000DCA78000440A001C5FD8
-:10140000AF8B00483062FFFF00A258230A001C5F28
-:10141000AF8B00482403FFFF11830005000000008C
-:101420000E001981022020210A001C5F004090213B
-:101430000E001908022020210A001C5F00409021A4
-:101440000E0019E5022020210A001C5F00409021B7
-:101450000E00185F022020210A001C5F004090212E
-:101460000E001A87022020210A001C5F00409021F4
-:101470000E0015DB00000000978300448F850048B4
-:10148000306CFFFF00AC38232CFF000553E0FFA8B1
-:101490003062FFFF8F860024A7800044ACC200DCCE
-:1014A0003062FFFF00A258230A001C5FAF8B004888
-:1014B00027BDFFD0AFB20018AFB00010AFBF0028FB
-:1014C000AFB50024AFB40020AFB3001CAFB100141F
-:1014D0003C0C80008D880128240FFF803C07800A87
-:1014E00025100100250B0080020F68243205007FC3
-:1014F000016F7024AD8E009000A72821AD8D0024CF
-:1015000090A700EC3169007F3C0A8004012A182171
-:10151000A38700429066007C00809021AF83001C6E
-:1015200030C20002AF880054AF85002400A018210B
-:10153000144000022404003424040030A38400304A
-:101540008C6600CC30F100FF24040004AF86004814
-:1015500012240004A38000508E5300041660001D66
-:101560003C0880009387004130F200011240000FD8
-:101570008FBF00288CB800748CA400742419FF80DD
-:101580000319882400117140308F007F01CF60253E
-:101590003C0D2000018D582530F500FE3C0A8000EE
-:1015A000AD4B0830A39500418FBF00288FB50024B4
-:1015B0008FB400208FB3001C8FB200188FB10014BD
-:1015C0008FB000102402000127BD003003E00008A6
-:1015D000ACA600CC8E590008951F01208E46001045
-:1015E000033FC0213307FFFF30F5000F32B4000185
-:1015F000AF8600201680003BA395004035060C0006
-:1016000002A6102100F51823AD030084AF82004C20
-:101610008E4900043128FFFF1100002BA7890044E8
-:101620002410FF803C1580003C1420000A001D4D52
-:101630002413FFFE90AE00C4020E682431AC00FFFC
-:101640001580002A0240202193840041978600449F
-:10165000308F000111E0000B026428248F890024E0
-:101660008D2300748D280074A38500410070102420
-:101670000002C940311F007F033FC02503148825A5
-:10168000AEB1083010C000108F85002490A700C4B0
-:1016900002075824316A00FF1540FFE6024020216E
-:1016A0000E001C01979100441040FFE89384004114
-:1016B0002405FFFD544500058E430020022028210B
-:1016C0000E001586024020218E4300203070000459
-:1016D0001600000A2414FFFB8F8500240A001D0356
-:1016E0008F8600480A001D2EAF86004C0E00182B76
-:1016F000000000000A001D3D9384004100749824FE
-:101700000E0015A0AE5300208F8500240A001D0393
-:101710008F86004827BDFFD8AFB3001CAFB10014BF
-:10172000AFBF0020AFB20018AFB000103C02800085
-:101730008C5201408C4B01483C048000000B8C0211
-:10174000322300FF317300FF8C8501B804A0FFFE37
-:1017500034900180AE1200008C8701442464FFF0B5
-:10176000240600022C830013AE070004A611000813
-:10177000A206000BAE1300241060004F8FBF0020A4
-:10178000000448803C0A0800254A79E0012A4021EB
-:101790008D04000000800008000000003C100800DC
-:1017A0008E1031A831733FFF001389800212282167
-:1017B000240CFF8000B12021264D01002647008027
-:1017C0003C0F80003C03800431A8007F30E9007F9B
-:1017D000308A007F3C0E800A3C02800C008CC024C2
-:1017E00001AC302400ECC82401239821014280215F
-:1017F000ADE60024010EF821ADF90090ADF8002807
-:10180000AF90002CAF9F0024AF93001C0E00167504
-:10181000016080213C0380008C6B01B80560FFFEF5
-:101820008F87002C8F8600243465018090F9000D8D
-:10183000ACB2000024C200780019C60000187E0374
-:10184000000F9027001227C2A4B00006108000707D
-:10185000240E6082A4AE0008A0A00005240F0002A0
-:10186000A0AF000B0004C4008F8B001C3C192700A4
-:1018700003199025ACB20010ACA00014ACA0002459
-:10188000ACA00028ACA0002C8D7300382411FF8080
-:10189000ACB3001890F0000D0230282430A400FFF3
-:1018A000108000058FBF002090EC000D319F007F5D
-:1018B000A0FF000D8FBF00208FB3001C8FB2001857
-:1018C0008FB100148FB000103C0A10003C0D800056
-:1018D00027BD002803E00008ADAA01B8265F01007B
-:1018E0002405FF8033F8007F3C06800003E5782460
-:1018F0003C19800A03192021ACCF0024908E00C42B
-:1019000000AE682431AC00FF1180FFEAAF840024F0
-:10191000248E007895CD00123C0C08008D8C31A8E7
-:101920003C03800C31AB3FFF01924821000B5180FA
-:10193000012A40213104007F010510240083382151
-:10194000ACC200280E001675AF87002C3C03800047
-:101950008C6501B804A0FFFE00000000AE1200007C
-:101960008C720144AE120004A6110008241100027A
-:10197000A211000BAE1300240A001DD88FBF002057
-:101980003C1260008E452C083C03F0033462FFFFDC
-:1019900000A2F824AE5F2C088E582C083C1901B028
-:1019A00003199825AE532C080A001DD88FBF0020BC
-:1019B000264D010031AF007F3C10800A240EFF80CD
-:1019C00001F0282101AE60243C0B8000AD6C0024A6
-:1019D0001660FFB8AF85002424110003A0B100EC0D
-:1019E0000A001DD88FBF002026480100310A007F61
-:1019F0003C0B800A2409FF80014B3021010920247F
-:101A00003C078000ACE400240A001DD7AF86002408
-:101A1000944D0012321F3FFF31AC3FFF159FFF8DE9
-:101A2000240E608290C300C42409FF800123102487
-:101A3000304A00FF1140FF87000000002407000427
-:101A4000A0C700EC8F87002C240860842406000DBA
-:101A5000A4A80008A0A600050A001DC2240F0002C9
-:101A60005F865437E4AC62CC50103A453662198533
-:101A7000BF14C0E81BC27A1E84F4B556094EA6FEF8
-:101A80007DDA01E7C04D7481800801008008008084
-:101A90008008000008004FBC08004FBC08005098A8
-:101AA0000800506C0800505008004F8C08004F8C04
-:101AB00008004F8C08004FC4080072BC080073086F
-:101AC000080072C8080071F0080072C8080072F8B7
-:101AD000080072C8080071F0080071F0080071F089
-:101AE000080071F0080071F0080071F0080071F052
-:101AF000080071F0080071F0080071F0080072E849
-:101B0000080072D8080071F0080071F0080071F048
-:101B1000080071F0080071F0080071F0080071F021
-:101B2000080071F0080071F0080071F0080071F011
-:101B3000080071F0080072D8080078900800775CFF
-:101B4000080078580800775C080078280800764478
-:101B50000800775C0800775C0800775C0800775C19
-:101B60000800775C0800775C0800775C0800775C09
-:101B70000800775C0800775C0800775C0800775CF9
-:041B8000080077845E
-:0C1B84000A000122000000000000000028
-:101B90000000000D747061342E362E3135000000C7
-:101BA00004060F010000000000000000000000001B
-:101BB0000000000000000000000000000000000025
-:101BC0000000000000000000000000000000000015
-:101BD0000000000000000000000000000000000005
-:101BE00000000000000000000000000000000000F5
-:101BF00000000000000000000000000000000000E5
-:101C000000000000000000000000000000000000D4
-:101C100010000003000000000000000D0000000D97
-:101C20003C020800244217C03C03080024632AB485
-:101C3000AC4000000043202B1480FFFD2442000430
-:101C40003C1D080037BD2FFC03A0F0213C1008000C
-:101C5000261004883C1C0800279C17C00E00025E5A
-:101C6000000000000000000D2402FF8027BDFFE0FF
-:101C700000821024AFB00010AF420020AFBF0018A8
-:101C8000AFB10014936500043084007F0344182131
-:101C90003C0200080062182130A50020036080216A
-:101CA0003C080111277B000814A000022466005C98
-:101CB0002466005892020004974301049204000431
-:101CC0003047000F3063FFFF308400400067282357
-:101CD00010800009000048219202000530420004F3
-:101CE000104000050000000010A0000300000000EC
-:101CF00024A5FFFC240900049202000530420004E0
-:101D0000104000120000000010A0001000000000B1
-:101D10009602000200A72021010440252442FFFE74
-:101D2000A7421016920300042402FF8000431024EF
-:101D3000304200FF104000033C0204000A00017220
-:101D4000010240258CC20000AF4210188F4201787A
-:101D50000440FFFE2402000AA7420140960200024E
-:101D6000240400093042000700021023304200071B
-:101D7000A7420142960200022442FFFEA74201440C
-:101D8000A740014697420104A74201488F4201083B
-:101D9000304200205040000124040001920200045F
-:101DA00030420010144000023483001000801821DB
-:101DB000A743014A000000000000000000000000EE
-:101DC00000000000AF48100000000000000000000C
-:101DD00000000000000000008F4210000441FFFEE0
-:101DE0003102FFFF104000070000000092020004D3
-:101DF0003042004014400003000000008F421018E1
-:101E0000ACC20000960200063042FFFF24420002EE
-:101E10000002104300021040036288219622000055
-:101E20001120000D3044FFFF00A710218F83003CDC
-:101E30008F45101C00021082000210800043102108
-:101E4000AC45000030A6FFFF0E0005B700052C02D0
-:101E500000402021A6220000920300042402FF80FB
-:101E600000431024304200FF1040001F000000001B
-:101E700092020005304200021040001B00000000EA
-:101E80009742100C2442FFFEA742101600000000EB
-:101E90003C02040034420030AF4210000000000059
-:101EA0000000000000000000000000008F42100051
-:101EB0000441FFFE000000009742100C8F45101CEB
-:101EC0003042FFFF244200300002108200021080E6
-:101ED000005B1021AC45000030A6FFFF0E0005B7E7
-:101EE00000052C02A62200009604000224840008AB
-:101EF0000E0001E73084FFFF974401040E0001F556
-:101F00003084FFFF8FBF00188FB100148FB0001016
-:101F10003C02100027BD002003E00008AF4201781A
-:101F20003084FFFF308200078F85002410400002BC
-:101F3000248300073064FFF800A4102130421FFF03
-:101F400003421821247B4000AF850028AF82002483
-:101F500003E00008AF4200843084FFFF3082000FAE
-:101F60008F85002C8F860034104000022483000FE0
-:101F70003064FFF000A410210046182BAF8500301C
-:101F80000046202314600002AF82002CAF84002C96
-:101F90008F82002C34048000034218210064182131
-:101FA000AF83003C03E00008AF4200808F82001442
-:101FB000104000088F8200048F82FFE41440000567
-:101FC0008F8200043C02FFBF3442FFFF00822024C6
-:101FD0008F82000430430006240200021062000FCA
-:101FE0003C0201012C620003504000052402000461
-:101FF0001060000F3C0200010A00022E00000000E9
-:1020000010620005240200061462000C3C0201115B
-:102010000A000227008210253C02001100821025D0
-:10202000AF421000240200010A00022EAF82000C11
-:1020300000821025AF421000AF80000C00000000AD
-:10204000000000000000000003E0000800000000A5
-:102050008F82000C10400004000000008F4210002E
-:102060000441FFFE0000000003E000080000000043
-:102070008F820010000229C224A3FFF0000318423F
-:102080002444F80000031140004310210002108096
-:1020900000431021000210803C0308002463180054
-:1020A0002C84030114800013004330218F84001816
-:1020B00000A4102B1440000F0000302100A41023B6
-:1020C00000021940006218210003188000621821E4
-:1020D0008F82001C008210212442FFFF0045102B3C
-:1020E00014400004000318803C02080024421A1423
-:1020F0000062302103E0000800C0102127BDFFE08E
-:10210000AFBF0018AFB10014AFB000103C046008BE
-:102110008C8250002403FF7F3C06600000431024A3
-:102120003442380CAC8250008CC24C1C3C1A8000EB
-:10213000000216023042000F10400007AF82001C60
-:102140008CC34C1C3C02001F3442FC00006218246B
-:10215000000319C2AF8300188F420008275B4000BC
-:1021600034420001AF420008AF8000243C02601CF2
-:10217000AF400080AF4000848C4500088CC3080845
-:1021800034028000034220212402FFF00062182460
-:102190003C0200803C010800AC2204203C025709AC
-:1021A000AF84003C14620004AF85003424020001B7
-:1021B0000A00028EAF820014AF8000143C0280003F
-:1021C000344400708C8300008F42000038420001CC
-:1021D0003042000110400018AF83003800804021D9
-:1021E000006030218D0700003C0508008CA5045CD0
-:1021F0003C0408008C84045800E6302300001021C1
-:1022000000A6282100A6302B008220210086202154
-:102210003C010800AC25045C3C010800AC240458D7
-:102220008F42000038420001304200011440FFEDAF
-:1022300000E03021AF8700383C028000344200705B
-:102240008C4700008F8600383C0508008CA5045C94
-:102250003C0408008C84045800E638230000102158
-:1022600000A72821008220218F82001400A7302B94
-:10227000008620213C010800AC25045C3C010800DC
-:10228000AC240458104000160000000097420104DE
-:10229000104000058F830000146000072462FFFFD8
-:1022A0000A0002D02C62000A2C6200105040000488
-:1022B0008F83000024620001AF8200008F83000042
-:1022C0002C62000A144000032C6200070A0002D7A7
-:1022D000AF80FFE41040000224020001AF82FFE45F
-:1022E0008F4301088F44010030622000AF83000457
-:1022F00010400008AF8400103C0208008C42042CFF
-:10230000244200013C010800AC22042C0A0005B361
-:102310003C0240003065020014A0000324020F00BC
-:102320001482026024020D0097420104104002C88A
-:102330003C02400030624000144000AD8F82003CFF
-:102340008C4400088F4201780440FFFE24020800FC
-:10235000AF42017824020008A7420140A740014291
-:10236000974201048F8400043051FFFF3082000146
-:1023700010400007022080212623FFFE24020002D5
-:102380003070FFFFA74201460A000304A74301483B
-:10239000A74001463C0208008C42043C1440000D5A
-:1023A0008F830010308200201440000224030009B3
-:1023B00024030001006020218F8300102402090003
-:1023C0005062000134840004A744014A0A00031F3C
-:1023D0000000000024020F0014620005308200207B
-:1023E000144000062403000D0A00031E2403000508
-:1023F000144000022403000924030001A743014AFA
-:102400003C0208008C4204203C0400480E00020AF2
-:10241000004420250E000233000000008F82000CD3
-:102420001040003E000000008F4210003C030020DE
-:1024300000431024104000398F8200043042000213
-:102440001040003600000000974210141440003382
-:1024500000000000974210088F88003C3042FFFFC8
-:1024600024420006000218820003388000E8302170
-:10247000304300018CC400001060000430420003AF
-:102480000000000D0A00036000E810215440001015
-:102490003084FFFF3C05FFFF0085202400851826BF
-:1024A0000003182B0004102B0043102410400005DB
-:1024B00000000000000000000000000D000000000F
-:1024C000240001CB8CC200000A00035F00452025D8
-:1024D0003883FFFF0003182B0004102B0043102447
-:1024E0001040000500000000000000000000000D8A
-:1024F00000000000240001D48CC200003444FFFF1F
-:1025000000E81021AC4400003C0208008C4204307A
-:10251000244200013C010800AC2204308F6200001C
-:102520008F84003CAF8200088C8300003402FFFFE0
-:102530001462000F000010213C0508008CA5045413
-:102540003C0408008C84045000B0282100B0302BDB
-:1025500000822021008620213C010800AC25045483
-:102560003C010800AC2404500A0005A9240400081A
-:102570008C820000304201001040000F000010214A
-:102580003C0508008CA5044C3C0408008C840448DD
-:1025900000B0282100B0302B0082202100862021AD
-:1025A0003C010800AC25044C3C010800AC24044864
-:1025B0000A0005A9240400083C0508008CA5044471
-:1025C0003C0408008C84044000B0282100B0302B6B
-:1025D00000822021008620213C010800AC25044413
-:1025E0003C010800AC2404400A0005A924040008AA
-:1025F0008F6200088F62000000021602304300F074
-:10260000240200301062000524020040106200E045
-:102610008F8200200A0005B12442000114A00005A9
-:1026200000000000000000000000000D000000009D
-:10263000240001FE8F4201780440FFFE00000000EC
-:102640000E00023B00000000144000050040802105
-:10265000000000000000000D000000002400020542
-:102660008E02000010400005000000000000000085
-:102670000000000D00000000240002088F62000C22
-:1026800004430003240200010A000457AE000000C6
-:10269000AE0200008F82003C8C480008A2000007B8
-:1026A0008F65000C8F64000430A3FFFF0004240238
-:1026B00000852023308200FF0043102124420005C2
-:1026C000000230832CC20081A605000A14400005D8
-:1026D000A2040004000000000000000D0000000043
-:1026E000240002208F85003C0E0005D5260400142E
-:1026F0008F6200048F430108A60200083C0210000C
-:1027000000621824106000080000000097420104D5
-:10271000920300072442FFEC346300023045FFFFC0
-:102720000A0003ECA2030007974201042442FFF0D1
-:102730003045FFFF960600082CC2001354400005E8
-:10274000920300079202000734420001A202000730
-:102750009203000724020001106200052402000316
-:102760001062000B8F82003C0A00040930C6FFFF94
-:102770008F82003C3C04FFFF8C43000C0064182453
-:1027800000651825AC43000C0A00040930C6FFFFA1
-:102790003C04FFFF8C4300100064182400651825DA
-:1027A000AC43001030C6FFFF24C2000200021083B9
-:1027B000A20200058F83003C304200FF000210801F
-:1027C000004328218CA800008CA2000024030004F0
-:1027D0000002170214430012000000009742010497
-:1027E0003C03FFFF010318243042FFFF0046102383
-:1027F0002442FFFE00624025ACA8000092030005C1
-:10280000306200FF0002108000501021904200143E
-:102810003042000F004310210A00043EA2020006CD
-:102820008CA40004974201049603000A3088FFFF3D
-:102830003042FFFF004610232442FFD6000214005E
-:1028400001024025ACA80004920200079204000592
-:102850002463002800031883006418213442000414
-:10286000A2030006A20200078F8200042403FFFBDC
-:102870003442000200431024AF8200049203000699
-:102880008F87003C00031880007010218C440020CA
-:102890003C02FFF63442FFFF00824024006718210B
-:1028A000AE04000CAC68000C920500063C03FF7FF0
-:1028B0008E02000C0005288000B020213463FFFF49
-:1028C000010330249488002600A728210043102407
-:1028D000AE02000CAC860020AC880024ACA800102E
-:1028E00024020010A742014024020002A740014236
-:1028F000A7400144A7420146974201043C04000856
-:102900002442FFFEA7420148240200010E00020AF1
-:10291000A742014A9603000A9202000400431021D4
-:102920002442000230420007000210233042000718
-:102930000E000233AE0200108F6200003C0308005C
-:102940008C63044424040010AF8200089742010401
-:102950003042FFFF2442FFFE00403821000237C30F
-:102960003C0208008C420440006718210067282BB5
-:1029700000461021004510213C010800AC2304440E
-:102980003C010800AC2204400A00053E00000000A3
-:1029900014A0000500000000000000000000000D71
-:1029A000000000002400029E8F4201780440FFFED8
-:1029B000000000000E00023B000000001440000573
-:1029C00000408021000000000000000D0000000019
-:1029D000240002A58E020000544000069202000767
-:1029E000000000000000000D00000000240002A80C
-:1029F0009202000730420004104000058F8200045C
-:102A00002403FFFB3442000200431024AF82000481
-:102A10008F6200040443000892020007920200063D
-:102A20008E03000CAE000000000210800050102148
-:102A3000AC430020920200073042000454400009D9
-:102A40009602000A920200053C0300010002108079
-:102A5000005010218C46001800C33021AC460018ED
-:102A60009602000A92060004277100080220202125
-:102A700000C2302124C60005260500140E0005D52D
-:102A800000063082920400068F6500043C027FFF3E
-:102A900000042080009120218C8300043442FFFF39
-:102AA00000A2282400651821AC83000492020007CC
-:102AB0009204000592030004304200041040001408
-:102AC00096070008308400FF000420800091202138
-:102AD0008C860004974201049605000A306300FFCB
-:102AE0003042FFFF004310210045102130E3FFFF7B
-:102AF000004310232442FFD830C6FFFF0002140019
-:102B000000C23025AC8600040A0004F292030007DC
-:102B1000308500FF0005288000B128218CA400002A
-:102B200097420104306300FF3042FFFF0043102151
-:102B3000004710233C03FFFF008320243042FFFFA7
-:102B400000822025ACA400009203000724020001AB
-:102B50001062000600000000240200031062001151
-:102B6000000000000A0005158E03001097420104C2
-:102B7000920300049605000A8E24000C00431021E5
-:102B8000004510212442FFF23C03FFFF0083202474
-:102B90003042FFFF00822025AE24000C0A000515FC
-:102BA0008E03001097420104920300049605000A68
-:102BB0008E24001000431021004510212442FFEE16
-:102BC0003C03FFFF008320243042FFFF00822025CA
-:102BD000AE2400108E0300102402000AA742014018
-:102BE000A74301429603000A920200043C040040FD
-:102BF00000431021A7420144A74001469742010427
-:102C0000A7420148240200010E00020AA742014A1D
-:102C10000E000233000000008F62000092030004E7
-:102C200000002021AF820008974201049606000AA6
-:102C30003042FFFF00621821006028213C03080099
-:102C40008C6304443C0208008C4204400065182157
-:102C5000004410210065382B004710213C0108007A
-:102C6000AC2304443C010800AC220440920400045C
-:102C7000008620212484000A3084FFFF0E0001E733
-:102C800000000000974401043084FFFF0E0001F5AE
-:102C9000000000003C021000AF4201780A0005B0BD
-:102CA0008F820020148200273062000697420104C0
-:102CB000104000673C0240003062400010400005B8
-:102CC00000000000000000000000000D00000000F7
-:102CD000240003968F4201780440FFFE240208007E
-:102CE000AF42017824020008A7420140A7400142F8
-:102CF0008F82000497430104304200011040000716
-:102D00003070FFFF2603FFFE24020002A7420146A7
-:102D1000A74301480A0005682402000DA7400146A8
-:102D20002402000DA742014A8F620000240400081B
-:102D3000AF8200080E0001E7000000000A00054213
-:102D400002002021104000423C024000936200003B
-:102D5000304300F0240200101062000524020070CD
-:102D600010620035000000000A0005B08F820020CC
-:102D70008F620000974301043050FFFF3071FFFF66
-:102D80008F4201780440FFFE320200070002102348
-:102D9000304200072403000A2604FFFEA743014037
-:102DA000A7420142A7440144A7400146A751014858
-:102DB0008F42010830420020144000022403000921
-:102DC00024030001A743014A0E00020A3C0400400C
-:102DD0000E000233000000003C0708008CE70444AA
-:102DE000021110212442FFFE3C0608008CC604405C
-:102DF0000040182100E33821000010218F650000F9
-:102E000000E3402B00C230212604000800C8302116
-:102E10003084FFFFAF8500083C010800AC27044464
-:102E20003C010800AC2604400E0001E70000000051
-:102E30000A000542022020210E0001390000000096
-:102E40008F82002024420001AF8200203C0240001B
-:102E5000AF420138000000000A00028F3C028000EF
-:102E60003084FFFF30C6FFFF00052C0000A6282598
-:102E70003882FFFF004510210045282B0045102116
-:102E800000021C023042FFFF0043102100021C021E
-:102E90003042FFFF004310213842FFFF03E00008EB
-:102EA0003042FFFF3084FFFF30A5FFFF00001821F4
-:102EB0001080000700000000308200011040000276
-:102EC00000042042006518210A0005CB00052840B7
-:102ED00003E000080060102110C0000624C6FFFFB8
-:102EE0008CA2000024A50004AC8200000A0005D5D5
-:102EF0002484000403E000080000000010A0000883
-:102F000024A3FFFFAC8600000000000000000000CA
-:102F10002402FFFF2463FFFF1462FFFA24840004ED
-:082F200003E0000800000000BE
-:042F280000000001A4
-:042F2C000A00002671
-:102F300000000000000000000000000D74787034F4
-:102F40002E362E3136000000040610000000000A64
-:102F5000000001360000EA600000000000000000F0
-:102F60000000000000000000000000000000000061
-:102F70000000000000000000000000000000000051
-:102F80000000000000000000000000000000001D24
-:102F90000000000000000000000000000000000031
-:102FA0000000000000000000000000000000000021
-:102FB0000000000000000000000000000000000011
-:102FC00000000000000000001000000300000000EE
-:102FD0000000000D0000000D3C02080024423B6090
-:102FE0003C03080024633E18AC4000000043202B43
-:102FF0001480FFFD244200043C1D080037BD7FFC07
-:1030000003A0F0213C100800261000983C1C08008A
-:10301000279C3B600E0004AE000000000000000D85
-:103020003C0580008F83003034A800708D070000BD
-:10303000008330253C02900000C22025ACA4002073
-:10304000AF8700243C0480008C8900200520FFFE0F
-:1030500000000000348400708C8500003C180800DB
-:103060008F18007C3C0D08008DAD007800A7C823A8
-:1030700003195021000070210159602B01AE582125
-:10308000016C38213C010800AC2A007C3C0108009E
-:10309000AC27007803E00008000000000A00003DB3
-:1030A000240400018F8500303C048000348300013B
-:1030B00000A3102503E00008AC82002003E0000814
-:1030C000000010213084FFFF30A5FFFF10800007B3
-:1030D000000018213082000110400002000420424C
-:1030E000006518211480FFFB0005284003E000085C
-:1030F0000060102110C00007000000008CA200003A
-:1031000024C6FFFF24A50004AC82000014C0FFFB0E
-:103110002484000403E000080000000010A0000860
-:1031200024A3FFFFAC8600000000000000000000A8
-:103130002402FFFF2463FFFF1462FFFA24840004CB
-:1031400003E000080000000090AA00318FAB0010DF
-:103150008CAC00403C0300FF8D680004AD6C002087
-:103160008CAD004400E060213462FFFFAD6D0024AF
-:103170008CA700483C09FF000109C024AD67002866
-:103180008CAE004C0182C82403197825AD6F000471
-:10319000AD6E002C8CAD0038314A00FFAD6D001CC7
-:1031A00094A900323128FFFFAD68001090A70030CD
-:1031B000A5600002A1600004A167000090A3003296
-:1031C000306200FF00021982106000052405000132
-:1031D0001065000E0000000003E00008A16A000175
-:1031E0008CD80028354A0080AD7800188CCF0014A8
-:1031F000AD6F00148CCE0030AD6E00088CC4002C76
-:10320000A16A000103E00008AD64000C8CCD001C35
-:10321000AD6D00188CC90014AD6900148CC8002471
-:10322000AD6800088CC70020AD67000C8CC200148C
-:103230008C8300700043C82B13200007000000009F
-:103240008CC20014144CFFE400000000354A0080DA
-:1032500003E00008A16A00018C8200700A0000C629
-:10326000000000009089003027BDFFF88FA8001CE7
-:10327000A3A900008FA300003C0DFF8035A2FFFF33
-:103280008CAC002C00625824AFAB0000A1000004FD
-:1032900000C05821A7A000028D06000400A048210C
-:1032A0000167C8218FA50000008050213C18FF7FD6
-:1032B000032C20263C0E00FF2C8C0001370FFFFF53
-:1032C00035CDFFFF3C02FF0000AFC82400EDC02455
-:1032D00000C27824000C1DC00323682501F8702566
-:1032E000AD0D0000AD0E00048D240024AFAD000034
-:1032F000AD0400088D2C00202404FFFFAD0C000C51
-:103300009547003230E6FFFFAD06001091450048BA
-:1033100030A200FF000219C2506000018D24003469
-:10332000AD0400148D4700388FAA001827BD00088F
-:10333000AD0B0028AD0A0024AD07001CAD00002C29
-:10334000AD00001803E00008AD00002027BDFFE03D
-:10335000AFB20018AFB10014AFB00010AFBF001C87
-:103360009098003000C088213C0D00FF330F007F93
-:10337000A0CF0000908E003135ACFFFF3C0AFF006B
-:10338000A0CE000194A6001EA22000048CAB001465
-:103390008E29000400A08021016C2824012A4024E9
-:1033A0000080902101052025A6260002AE240004FD
-:1033B00026050020262400080E00007224060002C4
-:1033C00092470030260500282624001400071E001E
-:1033D0000003160324060004044000032403FFFF37
-:1033E000965900323323FFFF0E000072AE23001007
-:1033F000262400248FBF001C8FB200188FB1001448
-:103400008FB0001024050003000030210A00007C6A
-:1034100027BD002027BDFFD8AFB1001CAFB00018FA
-:10342000AFBF002090A900302402000100E050212D
-:103430003123003F00A040218FB000400080882150
-:1034400000C04821106200148FA70038240B00052B
-:1034500000A0202100C02821106B001302003021A1
-:103460000E000108000000009225007C30A400023C
-:103470001080000326030030AE0000302603003425
-:103480008FBF00208FB1001C8FB00018006010218A
-:1034900003E0000827BD00280E000087AFB0001031
-:1034A0000A00014F000000008FA3003C0100202112
-:1034B0000120282101403021AFA300100E0000CED2
-:1034C000AFB000140A00014F000000008F820050CE
-:1034D00024430001304200FFAF83005003E00008A6
-:1034E000000000003C0580008CA30E108F84004477
-:1034F000AC8300208CA20E1803E00008AC820024EC
-:103500003C0580008CA30E148F840044AC83002003
-:103510008CA20E1C03E00008AC82002493820038C9
-:103520001040001B2483000F2404FFF000643824A3
-:1035300010E00019978B002C9784004C9389002E83
-:103540003C0A601C0A0001900164402301037021C1
-:10355000006428231126000231C2FFFF30A2FFFFC2
-:103560000047302B50C0000E00E448218D4D000C68
-:1035700031A3FFFF00036400000C2C0304A1FFF340
-:103580000000302130637FFF0A000188240600011B
-:1035900003E00008000000009784004C00E448218C
-:1035A0003123FFFF3168FFFF0068382B54E0FFF83C
-:1035B000A783004C938A002E11400005240F0001C0
-:1035C000006BC023A380002E03E00008A798004CE6
-:1035D000006BC023A38F002E03E00008A798004CC7
-:1035E00003E000080000000027BDFFE8AFB00010B6
-:1035F0003084FFFF3C10800093A8002BAFBF001465
-:10360000A6040144960A0E1630C600FF8FA90030AA
-:10361000A60A0146AE050148A2060152A608015AB3
-:10362000AE0701608FA3002CA609015801202021BC
-:103630000E00017CAE0301543C021000AE02017882
-:103640008FBF00148FB0001003E0000827BD0018E2
-:103650003C038000346200708C4900008F87003C7E
-:103660002484000727BDFFF83084FFF8AF890024C9
-:103670003C088000950E008A31CDFFFFAFAD000001
-:103680008FAC000001875823256AFFFF31461FFFDA
-:1036900000C4282B14A0FFF7350D00708DAC00007E
-:1036A0003C0508008CA500843C0A08008D4A008077
-:1036B000018958230000102100ABC0210007C882F7
-:1036C00001422021030B302B0019388035094000BE
-:1036D0000086782100E9102127BD00083C01080080
-:1036E000AC3800843C010800AC2F008003E00008E7
-:1036F000000000008F82003C2486000730C5FFF8E0
-:1037000000A2182130641FFF03E00008AF84003CD2
-:103710003C0320FF27BDFFE83C0760003C08800019
-:10372000240500103464FFFDACE53008AFBF001085
-:10373000AD040E00000000000000000000000000CA
-:1037400000000000000000003C0200FF345FFFFDAD
-:10375000AD1F0E003C0B60048D7850002419FF7FD4
-:103760003C0E00020319782435EC380C35CD0109E4
-:10377000ACED4C1824060009AD6C50008CEA0438FE
-:10378000AD060008AD0000148CE94C1C3145FFFF6C
-:103790003C06570900091E0238A42F713062000F41
-:1037A00034C80010AF820048104000072485C0B321
-:1037B0008CEB4C1C3C0D001F35ACFC00016C502404
-:1037C000000A49C2AF8900348CF90808241FF000B0
-:1037D000033FC02403087026030678262DE8000165
-:1037E0002DC600010106382550E00009A3800038ED
-:1037F0003C09601C8D24000824030001A3830038C9
-:1038000030827C00A780004CA380002EA782002C71
-:10381000AF80005014A00003AF80003C3C05600066
-:10382000ACA0442C0E000559000000008FBF001012
-:103830000A000E9927BD001827BDFFC8AFB3002CA2
-:10384000AFB20028AFBF0030AFB10024AFB000204E
-:10385000936200080080982100A090211440003558
-:10386000240400100E0001C9000000000E000168D1
-:10387000004080210002C4003C1932000319882551
-:10388000AE110000936F0009976E0012936A000A50
-:1038900031EC00FF31CDFFFF018D5821000B4400BA
-:1038A000314900FF01093825AE0700048F8500501B
-:1038B0009784004000403021308320001460004D88
-:1038C000AE050008AE00000C3C0580009784004067
-:1038D0000662004F8E03000C3090000816000002B4
-:1038E000264800062648000294A40E148CA50E1C3F
-:1038F0008F670004936A00023084FFFF314900FFA4
-:10390000AFA900108F720014AFA800180E0001AF0D
-:10391000AFB200148FBF00308FB3002C8FB20028DD
-:103920008FB100248FB00020240400100A0001F29F
-:1039300027BD00389365000997710012936C000B46
-:1039400030AD00FF01B13021318B00FF00CB802171
-:103950002602000A3050FFFF0E0001C9020020219C
-:103960000E000168004088219368000997640012E6
-:103970000002FC00310900FF308AFFFF012A3821D4
-:1039800024E3000203E3C0253C1941000319782514
-:10399000AE2F00008F6E000C3C0D800095AC0E1415
-:1039A00001D32825AE2500048DA50E1C8F670004C9
-:1039B000936B00023184FFFF316600FFAFA6001059
-:1039C0008F68001400403021AFB200180E0001AF24
-:1039D000AFA80014020020218FBF00308FB3002C4D
-:1039E0008FB200288FB100248FB000200A0001F2AE
-:1039F00027BD0038976200123C0580009784004084
-:103A0000305FFFFF0661FFB4AE1F000C8E03000C99
-:103A10003C078000006798250A00026BAE13000C7B
-:103A200027BDFFD8AFB40020AFBF0024AFB3001C48
-:103A3000AFB20018AFB10014AFB00010936200082D
-:103A4000144000940080A021AF60000C97850040D6
-:103A500030A440001080009E24030016241040076C
-:103A6000A363000AAF700014938F00428F6C0014A0
-:103A700031EE0001000E6A40018D5825AF6B001435
-:103A8000978A00408F6800143149001001093825D9
-:103A9000AF6700149786004030C300081060009F95
-:103AA000000000008F6600143C0310003C048000FE
-:103AB00000C32825AF65001494820E0A3C1F8100C4
-:103AC0002413000E3059FFFF033FC025AF780004D8
-:103AD000A37300029372000A3406FFFC265100040F
-:103AE000A371000A978800403107200010E0009180
-:103AF000000000003C0B80009789004095680E0C88
-:103B000097840040000918423107C0003065000367
-:103B100000071303309F100000A2C025001FCA0336
-:103B200003199825001390C0A772001297910040C6
-:103B3000936F000A00118182320E003C01CF682190
-:103B400025AC003CA36C0009956A0E0C31493FFF7F
-:103B5000A7690010976D0012936C0009018D582120
-:103B6000256A00023149000700094023310300079C
-:103B7000A363000B93670009976400129765001018
-:103B800030E200FF8F900028979800400044F82111
-:103B900003E5C82103269821331200401240000596
-:103BA0003266FFFF00D0702B3C11800011C0001660
-:103BB000000090210206782B15E0002D0000202146
-:103BC0003C1080008E120E143C058000AE120E10C8
-:103BD0008E110E1CAE110E18AE060E008CB8000031
-:103BE000331300081260FFFD0000000094B90E08B6
-:103BF00000C0802100008821A79900408CA60E04F7
-:103C000024120001AF860028977F001033F3FFFFD6
-:103C10008E8900000130202310800058AE840000FF
-:103C2000022020210E000243020028218E8C000079
-:103C300015800005000000008F6D0014240EFFBFEA
-:103C400001AEA024AF7400148F78000C03138821F8
-:103C5000AF71000C936F000815E000030000000036
-:103C60001640004000000000A3720008020020215E
-:103C70008FBF00248FB400208FB3001C8FB20018B8
-:103C80008FB100148FB000100080102103E00008F5
-:103C900027BD00288F900028978200403C118000AB
-:103CA000020098213045004014A0FFD90000902167
-:103CB000976800108F8700283103FFFF1467FFEC1F
-:103CC00000002021000088210A000339241200018D
-:103CD0002403000E24104007A363000AAF700014F1
-:103CE000938F00428F6C001431EE0001000E6A4089
-:103CF000018D5825AF6B0014978A00408F6800141F
-:103D00003149001001093825AF670014978600403B
-:103D100030C300081460FF6300000000AF600004BF
-:103D2000A3600002978800403107200014E0FF7173
-:103D300000003021A760001297910040936F000AA5
-:103D40003C0B800032301F000010718301CF6821CE
-:103D500025AC0028A36C0009956A0E0C0A00030A22
-:103D6000A76A00108F6600143C1FEFFF37F9FFFEB3
-:103D700000D998240A00034FAF7300148F6B00140E
-:103D8000356A00400E00016EAF6A00140A00033E5F
-:103D9000022020218F8500448F8A003027BDFFC07C
-:103DA0003C048000AFB70034AFB40028AFB1001CB2
-:103DB000AFBF0038AFB60030AFB5002CAFB30024B2
-:103DC000AFB20020AFB000188C8701048CA900248A
-:103DD000AC8A00808CA8002000E988230000B8216C
-:103DE000AC880E108CA600240000A021AC860E1812
-:103DF0008C820E10AC820E148C830E18AC830E1CB9
-:103E0000122000333C168000936B000811600054B0
-:103E100000000000976E001031CDFFFF022D602BD7
-:103E20001580004F0000000097700010320FFFFF58
-:103E3000AECF0E003C0580008CB30000327200084B
-:103E40001240FFFD0000000094B50E088CA50E0482
-:103E500032B0FFFF32140001128000440000000065
-:103E60000000000D3219A04024180040133800450E
-:103E70003214A0001280003F00000000937300087D
-:103E80001260000927A4001097620010305FFFFF46
-:103E900000BFC82B53200005AFB10010320800400E
-:103EA0001100003400000000AFB10010A7900040E6
-:103EB000AF8500280E0002BD000000000040A021D8
-:103EC000104000BE8FB100101620FFCF0000000090
-:103ED0002E96000102D78825122000178FBF0038C8
-:103EE0008F85003024170F0010B700713C0480004C
-:103EF0008C8F017805E0FFFE24180F0050B8008F6A
-:103F00003C0480008C990E14241402403C051000DF
-:103F1000AC9901448C930E1CAC930148A0800152D3
-:103F2000A480015AAC800160A4800158AC94015473
-:103F3000AC8501788FBF00388FB700348FB6003062
-:103F40008FB5002C8FB400288FB300248FB20020CF
-:103F50008FB1001C8FB0001803E0000827BD00409F
-:103F6000AED10E000A0003C33C05800014A0FFBEC2
-:103F70003219A0400E0001750000A0210A0003EADA
-:103F80002E9600013C0380008C7F017807E0FFFE45
-:103F9000240208008F84003CAC6201783C0380005E
-:103FA000946B008A316AFFFF0144382324E9FFFF44
-:103FB00031281FFF2D06000814C0FFF9346C4000A3
-:103FC00000A0A0210E000168008C90218F8300309A
-:103FD00024040F000040A821023488233C068000FE
-:103FE0001064000524050001938E004231C50001D4
-:103FF00000056A4035A500010015FC003C020100E7
-:1040000003E2C825AE5900008F93005032180036E5
-:10401000320F0008AE53000411E0004100B89825AB
-:1040200094C30E0A8F84003C3C0B8100306AFFFF72
-:104030002492000832481FFF014B48253C0710001E
-:10404000269200062410000EACC901600267982574
-:10405000A4D0015AAF88003CA4D201581620000811
-:104060003C1080008F8E003024050F0051C50002E7
-:1040700024170001367300400E00016E3C108000D2
-:104080008E180E1402402021AE1801448E0F0E1C13
-:10409000AE0F0148A2150152AE1301540E00017C6F
-:1040A0003C151000AE1501780A0003E7000000007F
-:1040B000128000053C07800094F20E08324900404F
-:1040C00011200042000000008C8A01780540FFFEAC
-:1040D0000000000094950E103C1005002403200001
-:1040E00032AEFFFF01D06825AC8D014C8C8C0E14D4
-:1040F0003C0B1000AC8C01448C860E1CAC86014835
-:10410000A0800152A480015AAC800160A4800158B3
-:10411000AC830154AC8B01780A0003F13C048000AD
-:104120008F8D003C26920002A4D2015825AC0008D5
-:1041300031861FFF0A00044CAF86003CAC80014C66
-:1041400012800019000000008C9F0E10AC9F0144EB
-:104150008C830E183C08800024110040AC83014879
-:104160008FBF0038A10001528FB70034A500015A5B
-:104170008FB60030AD0001608FB5002CA50001584E
-:104180008FB40028AD1101548FB300248FB20020EA
-:104190008FB1001C8FB000183C04100027BD0040F8
-:1041A00003E00008AD0401788C820E14AC82014457
-:1041B0008C830E1C0A00048B3C0880000E000175E5
-:1041C0002E9600010A0003EB02D7882500000000AC
-:1041D0000000000D000000002400033A0A000467FC
-:1041E0003C04800027BDFFD8AFB100143C11800013
-:1041F000AFB00010AFB40020AFB3001CAFB20018D6
-:10420000AFBF00243C13080026733C340E0001F9B4
-:10421000363000703C14080026943CB40200902113
-:104220008E0800008E2400003883000130620001F7
-:10423000104000163C0A8000024048218D270000F3
-:104240003C1F08008FFF006C3C0F08008DEF0068DA
-:1042500000E8102303E260210000C0210182702BDE
-:1042600001F8682101AE40213C010800AC2C006C33
-:104270003C010800AC2800688D4B00003966000145
-:1042800030C5000114A0FFED00E040218E1F0000AA
-:104290003C1808008F18006C3C0D08008DAD0068BC
-:1042A00003E8C823031938210000702100F9602BAE
-:1042B00001AE4021010C58213C010800AC27006CE4
-:1042C0003C010800AC2B00688E2801002406FF800A
-:1042D0003C04800A2505024000A64824AE280020A0
-:1042E000AE2900248E09000030A3007F0064502115
-:1042F0003C078000AF8A0044AF880030AF890024BB
-:104300008CE201780440FFFE000000008E1F0000D8
-:104310003C1808008F1800743C0D08008DAD00702B
-:1043200003E9C82303195821000070210179302BBB
-:1043300001AE602101864821240508003C010800E7
-:10434000AC2B00743C010800AC290070ACE501788E
-:1043500090E40108A384004293830042306A000184
-:104360001140000F240E0D002502F8002C47030118
-:1043700010E0001C000819C22464FFF00004504241
-:10438000000A41400E00039A0113D8213C0A400064
-:104390003C088000AD0A01380A0004BD000000009E
-:1043A000110E0026240F0F00110F002A3C02800876
-:1043B0003447008090FF00002418005033F900FFBC
-:1043C0001738FFF33C0A40000E0009A3000000006C
-:1043D0003C0A40003C088000AD0A01380A0004BDD8
-:1043E000000000008F8400340064282B14A0000B10
-:1043F0008F86004800866021258BFFFF0163482BD4
-:104400001520000600646823000D19400E00039A71
-:104410000074D8210A0005193C0A40000000000081
-:104420000000000D00000000240003AD0E00039A00
-:10443000000000000A0005193C0A40003C1B08006F
-:10444000277B3DB40E00039A000000000A00051906
-:104450003C0A40003C1B0800277B3DD40E00039A19
-:10446000000000000A0005193C0A40008F8200503D
-:1044700024430001304200FFAF83005003E00008F6
-:1044800000000000000411C003E0000824420240C4
-:104490003C04080024843BCC2405001A0A00007C5C
-:1044A0000000302127BDFFE0AFBF001CAFB20018F5
-:1044B000AFB10014AFB000103C108000920B0109A6
-:1044C0002412FF800E0005563164007F8F9100306A
-:1044D0000051502101524024AE08002492030109EA
-:1044E0000E0005563064007F24060080240700C0BB
-:1044F00024040040AE000810AE040814AE060818EC
-:10450000AE07081C920C01090051F82133F8007F16
-:104510003C19800A031910213184007F0E000556D2
-:10452000AF8200448E1101003C0C008035850001F3
-:104530000222782101F24824AE0908048E0E0100FF
-:10454000359800023609090001C2682131AB0078B4
-:1045500001655025AE0A08208E0501008E08010075
-:10456000360509800102182124640040009230249D
-:10457000AE0608088E07010000E2F82127F9004086
-:104580003332007802588825AE1108248E040100C9
-:10459000952F000C8FBF001C8FB2001831EEFFFF6B
-:1045A000000E69C0AE0D0800AE0C0828952B000C5B
-:1045B0008FB10014316AFFFF000A41C0AE08002C21
-:1045C0008CA300508FB000108CA2003C8D240004FE
-:1045D0008CA6001C8CA7003827BD0020AF83006884
-:1045E000AF820058AF840054AF86006003E000083B
-:1045F000AF8700643C0A0800914A3BF13C0908007F
-:1046000095293BEA3C051100000A3C0025280002E0
-:1046100000E8302500C5182524820008AC8300007E
-:1046200003E00008AC8000043C0880003507090066
-:1046300090E60011240200280080502130C300FFC2
-:1046400000A0602110620002340B86DD240B0800FC
-:104650003C07800034E20A9A9459000034EF0A9C27
-:1046600034ED0AA03338FFFFAD5800008DEE000096
-:1046700034E80A8024040001AD4E00048DA9000036
-:10468000AD4900089105001930A3000310640043F0
-:104690002866000214C000B0240400021064008BDD
-:1046A000240500031065009634E60AA43C090800BE
-:1046B00095293BE0240208005162004D3C0E800029
-:1046C0003C0E800035C5090090A6001290B9001973
-:1046D00035CB09808D68002830C700FF000778803F
-:1046E0003138FFFF332300FF01F8102100032500BC
-:1046F0000088702500025C003C0D600001CD302573
-:10470000356906FFAD490004AD4600008CA7002CBA
-:1047100025490028AD4700088CB90030AD59000C80
-:104720008CB80034AD5800108CAF0038AD4F001479
-:104730008CA3001CAD4300188CA800203C03800013
-:104740003462093CAD48001C8CA40024346F09007D
-:10475000AD4400208CAD0028AD4D00248C590000E4
-:10476000AD2C000425220014AD3900008C78010C1A
-:10477000AD38000891E800123C04080090843BF03A
-:10478000AD20001000082F0000046C0000AD602573
-:10479000358AFFFF03E00008AD2A000C3C09080041
-:1047A00095293BE03C0F080095EF3BEA34F90AA459
-:1047B0003C0E080095CE3BDC972800003138FFFF07
-:1047C00001F8682101AE382300082C0024E3FFF231
-:1047D00000A3202524020800AD44000CAD400010C9
-:1047E000AD4B00141562FFB6254A00183C0E800040
-:1047F00035CD090091A2001191A700193C050800D0
-:1048000094A53BE6304600FF35CB0A80956E002A22
-:104810000006C88230F800FF9787005C00191E0070
-:1048200000187C003128FFFF00A82021006F4825D8
-:104830000124102501C730213C0B4000004BC82546
-:104840000006C400AD590000AD58000491AF001837
-:104850003C03000624E90001000F46000103702517
-:10486000AD4E00088DA5002C3C0380003462093C4D
-:10487000AD45000C8DAB001C31247FFF2549001491
-:10488000AD4B00108C590000AD2C0004346F0900B2
-:10489000AD3900008C78010CA784005C252200143F
-:1048A000AD38000891E800123C04080090843BF009
-:1048B000AD20001000082F0000046C0000AD602542
-:1048C000358AFFFF03E00008AD2A000C34E20AA499
-:1048D00094460000951900283C09080095293BE002
-:1048E0000006C40000197C00370E810001EB68252A
-:1048F000AD4E000CAD4D00100A0005E2254A001433
-:104900003C09080095293BE03C18080097183BEA51
-:104910003C0F080095EF3BDC94CE00003139FFFFDF
-:10492000950D002803194021010F3823000E2400A3
-:10493000000D2C0024E3FFEE00A33025348281001B
-:10494000AD42000CAD460010AD400014AD4B001858
-:104950000A0005E2254A001C1460FF5434E90AA449
-:10496000952800003C09080095293BE000083C0020
-:1049700000EB1825AD43000C0A0005E2254A0010A3
-:1049800003E00008240207D027BDFFE0AFB2001803
-:10499000AFB10014AFB00010AFBF001C0E00005C40
-:1049A000008088218F8800588F8700543C0580083C
-:1049B00034B20080011128213C10800024020080C4
-:1049C000240300C000A72023AE0208183C0680087C
-:1049D000AE03081C18800004AF850058ACC5000465
-:1049E0008CC90004AF8900541220000936040980E4
-:1049F0000E00069500000000924C00278E0B0074FC
-:104A000001825004014B3021AE46000C360409806F
-:104A10008C8E001C8F8F006001CF682319A00004CA
-:104A20008FBF001C8C90001CAF9000608FBF001CDB
-:104A30008FB200188FB100148FB000100A00005E12
-:104A400027BD00208F8600688F8300588F82005416
-:104A50003C05800834A40080AC860050AC83003C48
-:104A600003E00008ACA200043C038000346700703F
-:104A70008CE30000308700FF3C0408008C84005465
-:104A800027BDFFF830AA00FF248200013C01080086
-:104A9000AC22005430C800FFAF8300243C098000E2
-:104AA0008D25017804A0FFFE352B00708D65000078
-:104AB000A3A700033C1808008F1800748FB90000EA
-:104AC0003C0D08008DAD007000A338233C047FFF2F
-:104AD00000E078213482FFFF0307382100007021B5
-:104AE0000322582401AE302100EF602B000847C09C
-:104AF00000CC182101682825AFA500003C01080062
-:104B0000AC2700743C010800AC2300709124010A1A
-:104B1000A3A000023C0280FFA3A400018FB8000004
-:104B2000314F007F3459FFFF03196824000F7600CE
-:104B30003C0B002001AE6025356A20002408FF8070
-:104B40003C06100027BD0008AD2C014CAD2A0154D5
-:104B5000A5200158A128015203E00008AD260178E4
-:104B60003C038000346200708C480000308A00FFF3
-:104B700030A900FFAF8800243C0480008C850178B8
-:104B800004A0FFFE348700708CEB00003C05080099
-:104B90008CA500743C1908008F390070016820232F
-:104BA00000A470210000102101C4C02B0322782131
-:104BB0003C07800001F868213C010800AC2E00741D
-:104BC00034E60A003C010800AC2D00708CCC0020BB
-:104BD0000009582B34E80980ACEC01448CC900244E
-:104BE000000B1540ACE90148A0EA01509104004CCB
-:104BF000A0E4016D03E00008A4E0015827BDFFE830
-:104C0000308400FFAFBF00100E00070D30A500FF7D
-:104C10008F8300588FBF00103C0580003446004051
-:104C20002404FF903C02100027BD0018ACA3014CE7
-:104C3000A0A40152ACA6015403E00008ACA2017884
-:104C400027BDFFE03C088008AFBF001CAFB20018D2
-:104C5000AFB10014AFB00010351000808E06001800
-:104C60003C078000309200FF00C72025AE040018EA
-:104C70000E00005C30B100FF9203000534620008B2
-:104C80000E00005EA2020005024020210E00073443
-:104C900002202821024020218FBF001C8FB2001863
-:104CA0008FB100148FB00010240500052406000108
-:104CB0000A0006CF27BD00203C08800027BDFFE882
-:104CC000AFB0001035050980AFBF001490A70009F0
-:104CD000240200063506090030E300FF241000041A
-:104CE000106200722408000294AE005C3C0D0204C5
-:104CF00031CCFFFF018D5825AC8B000090AA000835
-:104D000031490020112000080000000090BF004E33
-:104D10003C1901033738030033EF00FF01F8282561
-:104D200024100008AC85000490CC001190C900113B
-:104D3000318A00FF000A5882312700FF256A0005EA
-:104D4000000A108038E300281460002900824823FC
-:104D500090CF00123C1980003722090031E500FF96
-:104D60000005708001D06821000D340034C406FFB6
-:104D7000AD240004904C001190580012373F098078
-:104D80008FE400348F2F010C00105882330500FF90
-:104D900000AB702100083400008F1823000E6F0054
-:104DA00001A61025319F00FC3067FFFF03E9C021F9
-:104DB0000047C825014B7821000F2880AF19000C4F
-:104DC0000E00005C012580213C0A800824090004B3
-:104DD000354800800E00005EA10900090200102184
-:104DE0008FBF00148FB0001003E0000827BD00182B
-:104DF00090CE001190CD00193C07080094E73BE6E7
-:104E000031C600FF0006208231AC00FF00045E00C6
-:104E1000000C1C00016310250047C8253C1F400002
-:104E2000033FC0253C198000AD380000372209003F
-:104E3000904C001190580012373F09808FE40034E5
-:104E40008F2F010C00105882330500FF00AB70213A
-:104E500000083400008F1823000E6F0001A61025F3
-:104E6000319F00FC3067FFFF03E9C0210047C825E0
-:104E7000014B7821000F2880AF19000C0E00005C58
-:104E8000012580213C0A800824090004354800805F
-:104E90000E00005EA1090009020010218FBF00145E
-:104EA0008FB0001003E0000827BD00180A00076F4C
-:104EB0002408001227BDFFD8AFB40020AFB3001CF8
-:104EC000AFB20018AFB10014AFBF0024AFB00010F4
-:104ED0003C06800090C3010B309200FF30B300FF0E
-:104EE000306200300000A0211040007000008821D6
-:104EF00034C409809088000800083E0000072E0393
-:104F000004A00097240400048F8800583C01080086
-:104F1000A0243BF03C0C8000AD8000483C038000A6
-:104F2000906E010B31C5002010A000073C028000EC
-:104F300034790980933800080018860000107E0339
-:104F400005E2009C3C0280083450090034470A8086
-:104F5000904D010B94EB002C92030011921F001254
-:104F600090E50018307800FF33F900FF00197880D1
-:104F700001F8702101D1502130B100FF01514821C9
-:104F80002524000A31AC00403091FFFF000C302B8B
-:104F900002202021A78B005C3C010800A42A3BE6EC
-:104FA0003C010800A4293BE83C010800A4293BEA95
-:104FB0003C010800A4203BE03C010800A4203BDCAD
-:104FC0000E0001C9010680230E0005B20040202119
-:104FD000004020210E0005BF020028211680005C41
-:104FE000000000000E0001F2022020213C08080011
-:104FF00091083BF031140003128000163C1F80081A
-:105000008F8400583C0C800835860080248B00017A
-:10501000ACCB003C3C0580088CAA00040160202138
-:10502000014B482319200002AF8B00588CA40004C8
-:105030000E000695ACA400043C0F80008DEE0074B9
-:105040003C05800834AD0080004E8821ADB1000CD5
-:105050003C1F800837F9008002402021026028218F
-:10506000A320006B0E00070D3C1280008F980058A3
-:1050700034500006AE58014C0E0005503C13100091
-:10508000A24201528FBF0024AE5001548FB40020C1
-:10509000AE5301788FB100148FB3001C8FB200188B
-:1050A0008FB0001003E0000827BD002834C309803A
-:1050B000906F0008000F7600000E6E0305A000330D
-:1050C00034C209009059001B241F00103C01080045
-:1050D000A03F3BF0333800021300FF908F88005848
-:1050E0008F8300641468FF8E3C0380000E00005C18
-:1050F000000000003C0980083525008090A40009CC
-:1051000024070016308800FF1107000D0000000082
-:1051100090A600093C0C0800918C3BF0240A000882
-:1051200030C400FF358B00013C010800A02B3BF090
-:10513000108A002F240D000A108D00282402000C74
-:105140000E00005E000000000A0007FC8F88005877
-:105150000E000763004020210A00082E0000000016
-:105160003C0B8008356A00808D4800548CC9010CC6
-:105170001120FF66AF880058240600143C01080087
-:10518000A0263BF00A0007FB3C0C80009071000851
-:10519000241400023C010800A0343BF0323000200F
-:1051A0001200000B241400018F8800580A0007FC2D
-:1051B00024110008345F00808FE70038AC470004FA
-:1051C0008C430004AFE3003C0A0008073C02800067
-:1051D0008F8800580A0007FC24110004A0A20009CF
-:1051E0000E00005E000000000A0007FC8F880058D7
-:1051F000240200140A0008ADA0A2000927BDFFE8A0
-:10520000AFBF0014AFB000103C1080009202010943
-:10521000240500010E00070D304400FF3C1F8008EC
-:1052200093F8000E37E3008093F9000F906E00268C
-:1052300093E9000A332F00FF00186600000F6C008E
-:1052400031CB00FF018D5025000B3200014638257F
-:10525000312800FF3445600000E820252402FF814A
-:105260003C031000AE04014C8FBF0014AE05015486
-:10527000A2020152AE0301788FB0001003E00008D3
-:1052800027BD001827BDFFE8308400FFAFBF001026
-:105290000E00070D30A500FF344600403C0480009E
-:1052A0002405FF92AC860154A08501528F830058DB
-:1052B0008FBF00103C02100027BD0018AC83014CCA
-:1052C00003E00008AC82017827BDFFD8AFB2001818
-:1052D000AFB10014AFB00010AFBF0020AFB3001CDF
-:1052E0003C07800090E20109308600FF30B000FFEB
-:1052F000000618C232040002307100011480000759
-:10530000305200FF3C098008353300809268000568
-:105310003105000810A0000C30CA00100240202106
-:105320000E00074502202821240200018FBF002023
-:105330008FB3001C8FB200188FB100148FB0001013
-:1053400003E0000827BD00281540003034E50A00BE
-:105350008CB900248CB800081338004700004021A5
-:105360003C0E800835D30080926D0068240B00024B
-:1053700031AC00FF118B00803C068000927F004C16
-:1053800090C40109509F00043213007C1100006793
-:10539000000000003213007C1660005A02402021F9
-:1053A00016200008320C00013C07800034EB0A0094
-:1053B0008D6500248CE8010414A8FFDC0000102196
-:1053C000320C00011180000D024020213C108000B1
-:1053D0008E0E010C8F8D006811CD000800000000BA
-:1053E0000E0007E2022028218E0F010C3C188008D5
-:1053F00037100080AE0F0050024020210E0007340D
-:10540000022028210A000900240200013C070800AC
-:105410008CE7006424E600013C010800AC2600642F
-:105420001600000D00000000022028210E000734A5
-:1054300002402021926F0068240D000231EE00FF2F
-:1054400011CD0022024020210E0008B4000000000F
-:105450000A000900240200010E00003D240400019E
-:10546000926C0025020C58250E00005EA26B0025F0
-:105470000A000940022028218E6300188CE40104F0
-:105480008CBF002400031602149FFFB53045007F37
-:105490009269004C264400013093007F1265004061
-:1054A000312300FF1464FFAF3C0E80082648000142
-:1054B0003111007F310200FF1225000B240800018A
-:1054C000004090210A00090D241100012405000468
-:1054D0000E0006CF240600010E0008B400000000F4
-:1054E0000A000900240200012407FF800247282443
-:1054F00000A79026324200FF004090210A00090DCB
-:10550000241100010E0007E202202821320600309B
-:1055100010C0FFA332100082024020210E00074578
-:10552000022028210A000900240200018E630018CD
-:105530000240202102202821006610250E0008D6F6
-:10554000AE6200189264004C24050003240600019A
-:105550000E0006CF308400FF0E00003D2404000141
-:10556000926A0025020A48250E00005EA269002505
-:105570000A000900240200018E7800183C198000FE
-:105580000240202103197825022028210E0007342B
-:10559000AE6F00189264004C0A00098824050004CC
-:1055A0003246008038CA0080146AFF6E3C0E8008C4
-:1055B0000A0009612648000127BDFFC0AFB00018EE
-:1055C0003C108000AFBF0038AFB70034AFB600303A
-:1055D000AFB5002CAFB40028AFB30024AFB20020A9
-:1055E0000E00055EAFB1001C920401089205010B8C
-:1055F000308400FF0E0008E730A500FF144000D6FD
-:105600008FBF00383C09800835280080A100006B5E
-:105610003607098090E60000240200503C1708007D
-:1056200026F73DF430C300FF3C14080026943E04E6
-:10563000106200033C1080000000B8210000A0218F
-:10564000241F001036110A00361309808E1601043B
-:105650008F8D00588E38002436190A808E720020F3
-:105660003C010800A03F3BF0972C002C8EF5000079
-:10567000932B0018024D702302D878233C010800B8
-:10568000AC2F3BCC3C010800AC2E3BD03C010800C9
-:10569000AC2D3BF4A78C005C02A0F809317200FF2E
-:1056A000304A0002154000DA3045000110A000B475
-:1056B00000000000360509008E2B002490BF001169
-:1056C00090B9001290B6001133EF00FF333800FF9D
-:1056D00032CD00FF0018708001CF8021024D602183
-:1056E0000212A821258A00103C010800A4353BE8DD
-:1056F0003C010800AC2B3BF83C010800A42A3BE429
-:105700003C010800A4303BE60260B0213C1580005B
-:105710008F9200588F8400608ED3002024110006E1
-:1057200000923023027228233C010800AC313BEC8C
-:1057300004C000AF0000982104A000AD00C5102BEC
-:10574000104000AF000000003C010800AC263BD038
-:105750008E9000000200F8090000000030430002B3
-:105760001460006F004088213046000154C00011D1
-:105770008E9200043C0808008D083BD43C09C00010
-:105780003C04800001093825AEA70E008C8B000078
-:10579000316A00081140FFFD00000000948D0E08E2
-:1057A00024130001A78D00408C8C0E04AF8C0028C0
-:1057B0008E9200040240F8090000000002228825B1
-:1057C000322E000215C000A5000000003C180800A1
-:1057D00097183BDC3C12080096523BE83C19080045
-:1057E00097393BDE3C0708008CE73BD4031240218D
-:1057F0003C0B08008D6B3BF83C0E080095CE3BF24D
-:105800003C128000011978218E46010C00F86821B5
-:1058100025EC000201AE482101675021AF860068E7
-:105820003C010800AC2A3BF83C010800A4293BE0FD
-:105830003C010800A4283BEA0E0001C93184FFFFA7
-:105840000E000550004080213C010800A0223BF1E1
-:105850008E8200080040F809020020218F85005840
-:105860000E0005BF004020218E90000C0200F809B8
-:10587000004020213C03080094633BEA3C020800FE
-:1058800094423BDE00622021248500020E0001F2DA
-:1058900030A4FFFF3C1908008F393BCC3C1F0800A7
-:1058A0008FFF3BD4033FC0233C010800AC383BCC06
-:1058B00017000006000000003C0508008CA53BEC2A
-:1058C00034BF00403C010800AC3F3BEC126000429A
-:1058D0008F8200448E430E108F930044AE630020ED
-:1058E0008E440E18AE6400243C04080094843BE00F
-:1058F0000E000697000000008F8600588E8A001068
-:105900003C010800AC263BF40140F809000000000F
-:105910003C0908008D293BCC1520FF7E8F92005852
-:105920009796005C3C14800E323500100E0006C6BF
-:10593000A696002C56A000458EEB000432270040AE
-:1059400054E0001E8EF100088EEC000C0180F80976
-:10595000000000008FBF00388FB700348FB60030D2
-:105960008FB5002C8FB400288FB300248FB2002095
-:105970008FB1001C8FB0001803E0000827BD004065
-:10598000920901098F88003000093E0000E83025A7
-:10599000AE0600808E2300208E240024AFA30010CA
-:1059A000AE030E148FA20010AE020E10AE040E1C39
-:1059B000AE040E180A0009E3360509000220F809B2
-:1059C000000000008EEC000C0180F80900000000CF
-:1059D0000A000A8B8FBF0038240800012410000140
-:1059E000A4400020A44800220A000A6FAC50002402
-:1059F0003C010800AC203BD00A000A0A8E9000004F
-:105A00003C010800AC253BD00A000A0A8E90000039
-:105A100092110109000028210E000734322400FFF2
-:105A20008FBF00388FB700348FB600308FB5002C91
-:105A30008FB400288FB300248FB200208FB1001CD8
-:105A40008FB0001803E0000827BD00400160F8098E
-:105A5000000000000A000A85322700405260FFB1B2
-:105A60009796005C8EB60E148F940044AE9600207C
-:105A70008EAF0E1CAE8F00240A000A7E9796005C43
-:105A80008F8200000004218003E0000800821021C2
-:105A90003C07800834E20080904300690080402188
-:105AA000106000093C0401003C0708008CE73BF44F
-:105AB0008F83001C00E320230480000893890008E2
-:105AC00014E300030100202103E0000800801021FE
-:105AD0003C04010003E00008008010211120000BAD
-:105AE000006738233C0D800035AC0980918B007C29
-:105AF000316A0002114000202409003400E9702BB3
-:105B000015C0FFF10100202100E938232403FFFC28
-:105B100000A3C82400E3C02400F9782B15E0FFEAB5
-:105B20000308202130C400030004102314C0001413
-:105B3000304900030000302100A9782101E67021DE
-:105B400000EE682B11A0FFE03C0401002D3800019D
-:105B50000006C82B010548210319382414E0FFDA98
-:105B60002524FFFC2402FFFC00A218240068202149
-:105B700003E00008008010210A000AF42409003024
-:105B80003C0C80003586098090CB007C316A000493
-:105B90001540FFE9240600040A000B030000302131
-:105BA0003C0308008C63005C8F82000427BDFFE883
-:105BB000AFBF001410620005AFB00010000329C091
-:105BC00024A40280AF840000AF8300043C10800056
-:105BD00036030A00946500320E000AD530A43FFF58
-:105BE0008E0401003C180080370F00030082C8219A
-:105BF0002402FF80032260243329007F000CF94037
-:105C000003E94025332E00783C0D1000010D50258E
-:105C100001CF5825AE0C002836080980AE0C080CC0
-:105C2000AE0B082CAE0A0830910300693C06800CCC
-:105C30000126382110600006AF8700208D09003C46
-:105C40008D06006C0126382318E0007F000000005C
-:105C50003C0C8008358B00803C0A8000A160006904
-:105C6000355009808E0200383C06800034C50A0099
-:105C700090AD003C31A8002011000019AF82001C3B
-:105C8000240E00013C19800037300A00A38E000862
-:105C9000AF8000108E0400248F85001024180008A7
-:105CA000AF80000CAF8000143C010800A4383BDE3C
-:105CB0003C010800A4203BF20E000AD9000030216C
-:105CC000920F003C8FBF00148FB00010000F714284
-:105CD000AF82001827BD001803E0000831C20001A0
-:105CE00090B90032240F0001333800FF00182182E0
-:105CF000108F003F241F0002109F006234C20AC0B0
-:105D00003C03800034640A008C9900241720001D95
-:105D10003466090090830030241F00053062003F84
-:105D2000105F004C240500018F86000CA38500083D
-:105D3000AF860014AF8600103C19800037300A008F
-:105D40008E0400248F850010241800083C010800F0
-:105D5000A4383BDE3C010800A4203BF20E000AD927
-:105D600000000000920F003C8FBF00148FB00010A5
-:105D7000000F7142AF82001827BD001803E0000831
-:105D800031C200018C8800088C8D00248CCB00640B
-:105D90003C19800037300A00AF8B0010A380000848
-:105DA0008E0400248F86000C8F850010010D602367
-:105DB00024180008AF8C00143C010800A4383BDE16
-:105DC0003C010800A4203BF20E000AD900000000AC
-:105DD000920F003C8FBF00148FB00010000F714273
-:105DE000AF82001827BD001803E0000831C200018F
-:105DF00090A7003030E3003F5064002834C50AC04B
-:105E00008CAA00241540002234C809008CAB00483D
-:105E10003C0C7FFF3585FFFF016510243C18800096
-:105E2000AF82000C370509008F8E000C8CAF00602C
-:105E300001CF682B15A0000201C020218CA40060B6
-:105E40000A000B75AF84000C8D02006C0A000B5029
-:105E50003C0680008C8900488F86000C3C0A7FFF3E
-:105E60003550FFFF013038243C0480082405000130
-:105E7000AF870014AC80006CA38500080A000B8378
-:105E8000AF8600108C4400140A000B75AF84000C20
-:105E90008D0200680A000BBD3C18800034C40980E4
-:105EA0008C8600708CB0001400D0482B11200004A8
-:105EB000000000008C8200700A000BBD3C188000BE
-:105EC0008CA200140A000BBD3C1880008F850010C6
-:105ED00027BDFFE0AFBF0018AFB1001414A0000849
-:105EE000AFB000103C04800034870A0090E6003018
-:105EF0002402000530C3003F106200B7348409005B
-:105F00008F91000C00A080213C048000348E0A0098
-:105F10008DCD00043C0608008CC63BD031A73FFF66
-:105F200000E6602B5580000100E03021938F0008CF
-:105F300011E0007600D0102B349909809338007C52
-:105F400033040002108000772403003400C3F82BD0
-:105F500017E000D600C3302300D0102B3C0108000E
-:105F6000A4233BDC1440006D020018213C0408000F
-:105F70008C843BCC0064282B54A0000100602021BD
-:105F80003C05800034A90A009128003C3C0108002F
-:105F9000AC243BD4310300201460000200004821EF
-:105FA0008CA90E188F8800180128502B1140005F13
-:105FB000000000003C0508008CA53BD400A960212E
-:105FC000010C582B1160005C00B0682B01093823CC
-:105FD00000E028213C010800AC273BD4120000035C
-:105FE0002402FFFC10B0008C322A000300A2F82427
-:105FF0003C010800A4203BF23C010800AC3F3BD42C
-:1060000003E028218F840010120400063C0380085E
-:106010008C6A006C02002021AF91000C2550000119
-:10602000AC70006C8F8B001400858823AF9100103A
-:1060300001652023AF8400141220000224070018F9
-:10604000240700103C0E800835C6008090CD006803
-:10605000240C00013C010800A0273BF031A700FF01
-:1060600010EC0047000000001480001800002821F8
-:106070003C0B800091650109357109808E23001861
-:1060800030A500FF0003560224A300013146007F23
-:106090003070007F1206007E240CFF803C0F8008C9
-:1060A00035E90080A123004C3C0808008D083BEC3A
-:1060B000240E00023C010800A02E3C31350D0008E2
-:1060C0003C010800AC2D3BEC240500103C1F800077
-:1060D00037E40A009099003C333800201300000593
-:1060E00000A02021240200013C010800AC223BD486
-:1060F00034A400018FBF00188FB100148FB00010BE
-:106100000080102103E0000827BD00203C010800AA
-:10611000A4203BDC1040FF95020018210A000C105F
-:1061200000C018210A000C08240300303C050800B8
-:106130008CA53BD400B0682B11A0FFA80000000084
-:106140003C04080094843BDC0085782101E7702B37
-:1061500011C000072CA200043C1F60008FF95404FA
-:106160003338003F1700FFE3240400422CA2000450
-:106170001040FF9A240400420A000C738FBF0018DD
-:106180001528FFB9000000008CC200183C188000E0
-:10619000241900020058F825ACDF001837040A0063
-:1061A000A0D900689089003C240F000400A01021B1
-:1061B000312800203C010800A02F3C3111000002D2
-:1061C00024050010240200013C010800AC223BCC55
-:1061D0000A000C693C1F80008F8800148C890060C5
-:1061E0000109282B14A00002010088218C91006075
-:1061F0003C0B80008D640E18240A00010220282127
-:1062000002203021A38A00080E000AD90220802132
-:106210000A000BF7AF820018000A182312200007AB
-:10622000306400033C0D800035A7098090EC007CB1
-:10623000318B000415600019248E00043C01080015
-:10624000A4243BF23C18080097183BF203052021D8
-:1062500000C4782B11E0FF6C8F8400102CA6000581
-:1062600014C0FFA42404004230B900031720000228
-:1062700000B9182324A3FFFC3C010800AC233BD445
-:106280003C010800A4203BF20A000C3600602821E3
-:1062900000AC38240A000C5C00EC18263C01080015
-:1062A000A42E3BF20A000CC6000000003C010800CE
-:1062B000AC203BD40A000C72240400428F830014EB
-:1062C0003C0B8000356A0A001460000600001021B3
-:1062D000914600302405000530C400FF10850003FE
-:1062E0000000000003E000080000000091490048A1
-:1062F000312800FF000839C214E0FFFA3C0480088E
-:106300003C06080094C63BDC3C0308008C633BF46D
-:106310003C0508008CA53BD43C18080097183BF2BC
-:106320000066C8218C8E00040325782101F86821BD
-:1063300001AE60231980001D000000009158004C40
-:106340008F8D0020956E0E10330F00FF8DA9000475
-:1063500001CF30238DAA000030CFFFFF000F610076
-:10636000012C2821000038210147202100AC182BE6
-:106370000083C821ADA50004ADB9000091B8000AA2
-:1063800001F87021A1AE000A956C0E128F8A0020D0
-:10639000A54C00089549003825280001A54800387B
-:1063A0009147000D34EB0008A14B000D03E00008FD
-:1063B0000000000027BDFFD8AFB00018938F000881
-:1063C0008FB000143C087FFF8F8700103C0C8000CA
-:1063D0003518FFFFAFBF0020AFB1001C35990A0090
-:1063E00002181824932A003C000F5FC03C02BFFF34
-:1063F0002CF000013449FFFF006BF8253C08080031
-:106400008D083BF48F99001C3C18080097183BEA54
-:1064100003E9582400107F803C07EFFF3C05F0FFA4
-:10642000016F18253C1180003149002034E2FFFF44
-:1064300034ADFFFF362E098027A500102406000288
-:1064400001194023270A00020062182400808021DD
-:1064500015200002000058218D8B0E1CA7AA0012E7
-:106460000500003A2407000030EF00FF000F3F0056
-:10647000006740253C028008AFA80014344B008020
-:10648000916A00683C0F080091EF3BF13C09DFFF87
-:10649000353FFFFF000A602B3C02080094423BE4BA
-:1064A000A3AF0011011FC024000CCF400319182511
-:1064B0008FA70010AFA300143C1F080093FF3BF30D
-:1064C000A7A200168FA8001400ED48243C0B010081
-:1064D0003C0A0FFF012BC82533F80003354CFFFFA2
-:1064E000010D78243C027000032C382400181E0093
-:1064F00000E2482501E35825AFAB0014AFA9001016
-:1065000091DF007CA3BF00150E00007200000000A8
-:10651000362D0A0091A6003C30C4002010800006F1
-:10652000260200083C11080096313BE0262EFFFFB2
-:106530003C010800A42E3BE08FBF00208FB1001C5F
-:106540008FB0001803E0000827BD00288F8A0018CC
-:10655000016A602B5580FFC4240700010A000D501A
-:1065600030EF00FF938300083C02800027BDFFD876
-:1065700034480A0000805021AFBF002034460AC0D2
-:10658000010028211060000E34440980910700307A
-:10659000240B00058F89000C30EC003F118B000BA1
-:1065A00000003821AFA900103C0B80088D69006CF9
-:1065B000AFAA00180E00013AAFA90014A38000088A
-:1065C0008FBF002003E0000827BD00288D1F004872
-:1065D0003C1808008F183BD48F9900143C027FFFB1
-:1065E0008D0800443443FFFFAFA900103C0B800826
-:1065F0008D69006C03E370240319782101CF6823AF
-:1066000001A83821AFAA00180E00013AAFA9001462
-:106610000A000DA5A38000083C05800034A60A00EE
-:1066200090C7003C3C06080094C63BF23C020800C0
-:106630008C423BEC30E30020000624001060003167
-:10664000004448253C0880083505008090A3006878
-:1066500000006821240C000100005021240B0001DF
-:106660003C188000370F00708DE800003C07800068
-:10667000AF8800248CF901780720FFFE34E5007014
-:106680008CA200003C0308008C6300743C0F0800DF
-:106690008DEF007000482023006428210000C021F5
-:1066A00000A4302B01F8702101C640213C010800F4
-:1066B000AC2500743C010800AC280070ACEC01482B
-:1066C0003C0208008C423BF4A4EA0144A4EB0146DE
-:1066D000ACE2014C3C04080090843BF13C03800890
-:1066E000A0E40152ACE90154A4ED0158346D0080DE
-:1066F00091AC004C3C091000A0EC016D03E00008D7
-:10670000ACE901788CAC0E1C3C0B08008D6B3BD4C3
-:1067100094AA0E1694AE0E1401666821314BFFFF49
-:106720000A000DCD31CAFFFF3C04800034830A000B
-:106730009065003C30A200201040002B00000000BB
-:106740000000582100005021000048213C08800032
-:10675000350400708C8800003C078000AF8800245E
-:106760008CEC01780580FFFE34EE00708DCD0000CA
-:106770003C0508008CA500743C0408008C84007063
-:1067800001A8602300ACC02100001021030C302BB5
-:106790000082C821032678213C010800AC3800742F
-:1067A0003C010800AC2F0070ACEB01483C0E080027
-:1067B0008DCE3BF4240DFF91240B0040A4E901444D
-:1067C000A4EA0146ACEE014CA0ED0152ACEB015441
-:1067D000A4E0015890EA01093C091000A0EA016D0B
-:1067E00003E00008ACE901788C8B0E1894870E1238
-:1067F00094860E1030EAFFFF0A000E0830C9FFFF32
-:106800003C04800034830A009065003C30A20020E4
-:106810001040003927BDFFF8240C00010000502172
-:10682000240B00013C088000350400708C890000B6
-:106830003C088000AF8900248D0D017805A0FFFE83
-:10684000350E00708DC700003C0508008CA5007453
-:106850003C0408008C84007000E9682300ADC0216E
-:1068600000001021030D302B0082C821032678215F
-:106870003C010800AC3800743C010800AC2F0070EB
-:10688000910901093C0E080091CE3C313C0380FF88
-:10689000A3A900038FAD000031C7007F3462FFFF62
-:1068A00001A82025AFA400009106010AA3A00002C0
-:1068B0000007CE00A3A600018FA50000240E300023
-:1068C0003C09100000A2C02403197825AD0F014C2B
-:1068D00027BD0008AD0E0154A5000158AD0C0148BC
-:1068E000A50A0144240AFF80A50B0146A10A015212
-:1068F00003E00008AD0901788C8C0E1894870E1205
-:1069000094860E1030EBFFFF0A000E3E30CAFFFFE8
-:1069100027BDFFE8AFB000103C108000AFBF0014EF
-:1069200036180A00970F00320E000AD531E43FFFF7
-:106930008E0E0100240DFF803C04200001C258216E
-:10694000016D6024000C4940316A007F012A402516
-:10695000010438253C048008AE07083034860080E6
-:1069600090C500682403000230A200FF1043000419
-:106970008F9F000C8F990010AC9F0068AC99006449
-:106980008FBF00148FB0001003E0000827BD00186F
-:106990003C0A0800254A37FC3C090800252938D460
-:1069A0003C08080025082C743C07080024E739E45B
-:1069B0003C06080024C636383C05080024A5339060
-:1069C0003C04080024842FA03C030800246336EC18
-:1069D0003C020800244234883C010800AC2A3DFCFB
-:1069E0003C010800AC293DF83C010800AC283DF40E
-:1069F0003C010800AC273E003C010800AC263E10DC
-:106A00003C010800AC253E083C010800AC243E04D3
-:106A10003C010800AC233E143C010800AC223E0CB3
-:086A200003E000080000000083
-:086A2800800009408000090014
-:106A3000800801008008008080080000800E0000AF
-:106A4000800800808008000080000A8080000A0022
-:086A50008000098080000900AC
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-mips-09-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-mips-09-5.0.0.j3.fw.ihex
new file mode 100644
index 0000000..92e2204
--- /dev/null
+++ b/firmware/bnx2/bnx2-mips-09-5.0.0.j3.fw.ihex
@@ -0,0 +1,6051 @@
+:100000000800011008000000000051C4000000C8F2
+:10001000000000000000000000000000080051C4C3
+:10002000000000380000528C080000880800000022
+:10003000000051B4000052C4080053A00000008426
+:100040000000A478080051B4000001C00000A4FC26
+:10005000080031D808000000000080E40000A6BCC1
+:10006000000000000000000000000000080080E424
+:1000700000000124000127A00800048808000400F3
+:10008000000017EC000128C4000000000000000080
+:100090000000000008001BEC00000004000140B05C
+:1000A000080000A80800000000003814000140B457
+:1000B00000000000000000000000000008003814EC
+:0800C00000000030000178C8C7
+:0800C8000A00004400000000E2
+:1000D000000000000000000D636F6D352E302E30E3
+:1000E0006A33000005000002000000000000000369
+:1000F00000000014000000320000000300000000B7
+:1001000000000000000000000000000000000000EF
+:1001100000000010000001360000EA600000000549
+:1001200000000000000000000000000000000008C7
+:1001300000000000000000000000000000000000BF
+:1001400000000000000000000000000000000000AF
+:10015000000000000000000000000000000000009F
+:10016000000000020000000000000000000000008D
+:10017000000000000000000000000000000000007F
+:10018000000000000000000000000010000000005F
+:10019000000000000000000000000000000000005F
+:1001A000000000000000000000000000000000004F
+:1001B000000000000000000000000000000000003F
+:1001C000000000000000000000000000000000002F
+:1001D000000000000000000000000000100000030C
+:1001E000000000000000000D0000000D3C020800AF
+:1001F000244252203C03080024635354AC400000C6
+:100200000043202B1480FFFD244200043C1D080005
+:1002100037BD9FFC03A0F0213C1008002610011000
+:100220003C1C0800279C52200E00025F00000000CA
+:100230000000000D27BDFFE0AFBF0018AFB10014F4
+:10024000AFB000103C04800094820108304370007D
+:10025000240220001062000B2862200114400036A6
+:1002600000001021240240001062002C0000000059
+:10027000240260001062002D000010210A00009D81
+:100280008FBF001834910100922400098E300018AD
+:1002900010800020240300012402000914820006BB
+:1002A0008F82001C3C0280089442001A0002140055
+:1002B000020280258F82001C8C42000C1040001529
+:1002C000000018210E000D45000000008F83001C67
+:1002D000962400088F8200189463001E9625000C57
+:1002E0000004240000832025AC500000AC4500042D
+:1002F000AC400008AC40000CAC400010AC40001416
+:10030000AC400018AC44001C0E000D792404000120
+:10031000000018210A00009C006010210E00042E2D
+:10032000000000000A00009C000010210E000C6577
+:1003300000000000000010218FBF00188FB10014D2
+:100340008FB0001003E0000827BD00208F82001C42
+:1003500027BDFFE0AFB00010AFBF0018AFB1001471
+:100360008C42000C3C1080008E11010010400034C3
+:100370008FBF00180E000D45000000008F8500188B
+:1003800024047FFF0091202BACB100008E030104F8
+:100390009602010800031C003042FFFF006218258E
+:1003A000ACA300049202010A96030114304200FF3C
+:1003B0003063FFFF0002140000431025ACA20008C8
+:1003C0009603010C9602010E00031C003042FFFF51
+:1003D00000621825ACA3000C9603011096020112CE
+:1003E00000031C003042FFFF00621825ACA3001080
+:1003F0008E020118ACA200148E02011CACA20018DF
+:10040000148000088F82001C978200003C042005A5
+:100410000044182524420001ACA3001C0A0000DBA4
+:10042000A78200003C0340189442001E00431025A0
+:10043000ACA2001C0E000D79240400018FBF00182F
+:100440008FB100148FB000100000102103E00008ED
+:1004500027BD00203C0680008CC202B824030001A6
+:1004600004410008008028213C0208008C42006002
+:10047000244200013C010800AC22006003E00008B7
+:10048000006010218C83002094820016ACC302808F
+:100490002442FFFCA4C202843C0208008C42005C9F
+:1004A0008C84000494A3000E244200013C01080047
+:1004B000AC22005C3C021000A4C30286ACC40288DB
+:1004C00000001821ACC202B803E00008006010214F
+:1004D00027BDFFE0AFB000103C108000AFB20018A5
+:1004E000AFBF001CAFB10014361201009243000BE5
+:1004F0002402001A965100081462005A00002821B4
+:1005000032220001104000188F82001C8E42000031
+:10051000000223403C02003F3442FFFF0044102B06
+:10052000104000043C030040964200140A000124DD
+:10053000008320218E030100240201005462000682
+:10054000964200143C028008904200043042000FA2
+:10055000000225009642001400821025AE020080A1
+:100560000A000157000000008C42000C10400028D7
+:10057000000000000E000D4500000000960201087A
+:100580009603010C8F8500183042003E3063FFFF58
+:100590000002140000431025ACA200008E020100EE
+:1005A000ACA20004960301169604010E8F82001C73
+:1005B00000031C003084FFFF00641825ACA3000872
+:1005C00096030110960401129446001E00031C00BD
+:1005D0003084FFFF00641825ACA3000C3C0220000F
+:1005E00000C2302596020114240400013042FFFFAE
+:1005F000ACA200108E020118ACA200149202010BF2
+:10060000304200FFACA200180E000D79ACA6001C11
+:100610003C0208008C420040244200013C010800DA
+:10062000AC2200403C0308008C63004432220002EC
+:1006300032240004246300013C010800AC23004480
+:10064000108000080002282B024020218FBF001CD0
+:100650008FB200188FB100148FB000100A0000E3B1
+:1006600027BD00208FBF001C8FB200188FB100146F
+:100670008FB0001000A0102103E0000827BD00206B
+:1006800027BDFFE0AFB000103C108000AFB20018F3
+:10069000AFBF001CAFB10014361201009243000B33
+:1006A000240200031462006A9651000832220001FD
+:1006B000104000178F82001C8E4300003C02003F58
+:1006C0003442FFFF000323400044102B504000053C
+:1006D00024020100964200143C0300400A00018EEF
+:1006E0000083202154620006964200143C028008D8
+:1006F000904200043042000F000225009642001490
+:1007000000821025AE0200800A0001BE0000000039
+:100710008C42000C10400025000000000E000D452A
+:1007200000000000960201089603010C8F85001856
+:100730003042003E3063FFFF0002140000431025EA
+:10074000ACA200008E020100ACA2000496030116C8
+:100750009604010E8F82001C00031C003084FFFFF2
+:1007600000641825ACA3000896030110960401123A
+:100770009446001E00031C003084FFFF006418250F
+:10078000ACA3000C3C02200000C2302596020114EC
+:10079000240400013042FFFFACA20010ACA0001402
+:1007A000ACA000180E000D79ACA6001C3C0208009D
+:1007B0008C420040244200013C010800AC22004071
+:1007C0003C0208008C420044322300042442000111
+:1007D0003C010800AC2200441060000832220002F4
+:1007E000024020218FBF001C8FB200188FB100146F
+:1007F0008FB000100A0000E327BD00201040001554
+:100800008FBF001C3C0480008C8301043C026020EC
+:10081000AC4300148C420004240301FE304203FF69
+:100820001443000C8FBF001C8C820100000219C20F
+:100830002462FFFC2C420008104000032404000244
+:100840002462FFFD004420043C026000AC446914B3
+:100850008FBF001C8FB200188FB100148FB0001032
+:100860000000102103E0000827BD00203C048000A8
+:100870008C83010024020100506200033C028008C6
+:100880000000000D3C02800890430004000010218D
+:100890003063000F00031D0003E00008AC830080FC
+:1008A0002C8407811080000A000028213C0280006F
+:1008B00094420108240320003042700014430005D4
+:1008C0002783FFB03C02800890420005304500FFBE
+:1008D0002783FFB00005208000832021000510C081
+:1008E000004510238C8400003C030800246352E47C
+:1008F000000210C0004310213C038000AC64009053
+:1009000003E00008AF82001C03E000080000102193
+:1009100003E00008000010212402010014820008F6
+:10092000000000003C0208008C4200FC2442000150
+:100930003C010800AC2200FC0A00022430A2002086
+:100940003C0208008C420084244200013C01080063
+:10095000AC22008430A200201040000830A3001018
+:100960003C0208008C420108244200013C010800BE
+:10097000AC22010803E0000800000000106000083D
+:10098000000000003C0208008C42010424420001E7
+:100990003C010800AC22010403E000080000000054
+:1009A0003C0208008C420100244200013C01080086
+:1009B000AC22010003E000080000000027BDFFE8B2
+:1009C000AFB000103C108000AFBF0014360401002F
+:1009D0009483000830620004104000053066000275
+:1009E0008FBF00148FB000100A0000E327BD00186D
+:1009F00010C00006006028218E0401000E000214C1
+:100A0000000000000A00025B240200018F8200083F
+:100A10008E03010410430007000010218E04010022
+:100A20000E000214000000008E020104AF820008D4
+:100A3000000010218FBF00148FB0001003E00008E9
+:100A400027BD001827BDFFD83C036010AFB3001CC2
+:100A5000AFBF0020AFB20018AFB10014AFB00010AC
+:100A60008C6450002402FF7F3C1308002673524818
+:100A7000008220243484380CAC6450003C02800096
+:100A800024030037AC4300083C06080024C6084095
+:100A9000026010212404001C2484FFFFAC460000E7
+:100AA0000481FFFD244200043C0208002442016C42
+:100AB0003C010800AC2252503C020800244205B818
+:100AC0003C010800AC2252543C020800244202843B
+:100AD0003C010800AC2252903C0208002442040869
+:100AE0003C030800246308483C040800248408F4FC
+:100AF0003C05080024A52C4C3C010800AC2252B057
+:100B00003C020800244207A43C010800AC2652988D
+:100B10003C010800AC2552A43C010800AC2352ACB7
+:100B20003C010800AC2452B43C010800AC2252B88D
+:100B30003C010800AC23524C3C010800AC20525848
+:100B40003C010800AC20525C3C010800AC20526023
+:100B50003C010800AC2052643C010800AC20526803
+:100B60003C010800AC20526C3C010800AC205270E3
+:100B70003C010800AC2452743C010800AC205278BF
+:100B80003C010800AC20527C3C010800AC205280A3
+:100B90003C010800AC2052843C010800AC20528883
+:100BA0003C010800AC26528C3C010800AC26529453
+:100BB0003C010800AC20529C3C010800AC2552A02E
+:100BC0003C010800AC2352A80E00055A00000000AA
+:100BD0008F8300043C0208008C4200201062001F3A
+:100BE000000088212792FFB03C100800261052E434
+:100BF0003C0208008C420020240500010225180454
+:100C0000004320248F820004004310245044000C31
+:100C10002631000110800008AF90001C8E430000B8
+:100C20003C028000AC4300900E000D0CAE05000CA1
+:100C30000A0002DE26310001AE00000C2631000160
+:100C40002E220002261000381440FFE9265200042C
+:100C50003C0208008C420020AF8200043C1080005F
+:100C60008E110000322200071040FFDA8F8300044B
+:100C70003222000110400021322200028E020100C7
+:100C8000AE0200208E020104AE0200A80E0001F6A2
+:100C90008E0401009202010B304300FF2C62001D04
+:100CA00054400004000310800E0002100A0002FFEE
+:100CB00000000000005310218C4200000040F809A1
+:100CC00000000000104000043C0280008C4301043E
+:100CD0003C026020AC4300143C0208008C4200340B
+:100CE0003C0440003C03800024420001AC64013815
+:100CF0003C010800AC2200343222000210400010F7
+:100D0000322200043C1080008E020140AE0200201E
+:100D10000E0001F68E0401400E0003970000000053
+:100D20003C024000AE0201783C0208008C420038D0
+:100D3000244200013C010800AC22003832220004A9
+:100D40001040FFA48F8300043C1080008E020180BD
+:100D5000AE0200200E0001F68E0401808E03018099
+:100D600024020F00146200073C0280088E020188F2
+:100D70003C0300E03042FFFF004310250A00033B24
+:100D8000AE020080344200809042000024030050F4
+:100D9000304200FF14430007000000000E000374FF
+:100DA0000000000014400003000000000E00095D78
+:100DB000000000003C0208008C42003C3C04400063
+:100DC0003C03800024420001AC6401B83C010800EF
+:100DD000AC22003C0A0002C38F8300043C02900056
+:100DE00034420001008220253C028000AC440020F7
+:100DF0003C0380008C6200200440FFFE00000000E5
+:100E000003E00008000000003C02800034430001C1
+:100E10000083202503E00008AC44002027BDFFE04C
+:100E2000AFB10014AFB0001000808821AFBF001830
+:100E30000E00034530B000FF8F83FFA80220202161
+:100E40009062002502028025A07000258C70001899
+:100E50003C0280000E000350020280241600000AAB
+:100E60008FBF00183C0380008C6201F80440FFFE35
+:100E700024020002AC7101C0A06201C43C02100057
+:100E8000AC6201F88FBF00188FB100148FB0001052
+:100E900003E0000827BD002027BDFFE8AFBF00101A
+:100EA0003C0380009462018430420200104000053F
+:100EB000000020210E000FCD000000000A00038A70
+:100EC000240400018C6201880440000A8FBF0010D6
+:100ED0008C6201883C03FF00004310243C030400A3
+:100EE00014430004240400018F82FFA890420008EC
+:100EF0008FBF00100080102103E0000827BD0018FC
+:100F00008F82FFAC2403000124050001A040001AD9
+:100F10008F82FFA8A44300163C0280000A000355FC
+:100F20008C4401408F85FFA827BDFFE0AFBF001CA8
+:100F3000AFB20018AFB10014AFB0001090A2000023
+:100F4000304400FF38830020388200300003182B23
+:100F50000002102B00621824106000053C02800083
+:100F600024020050148200818FBF001C3C028000CC
+:100F700090420148304200FF2443FFFF2C620005ED
+:100F80001040007A8FBF001C000310803C03080053
+:100F9000246351DC004310218C4200000040000813
+:100FA000000000003C1180008E2401400E0003452B
+:100FB0008F92FFA88E50000C8E2201441602000270
+:100FC00024020001AE42000C0E0003508E240140AA
+:100FD0008E220144145000068FBF001C8FB20018EF
+:100FE0008FB100148FB000100A000F3927BD002008
+:100FF0008E42000C0A0004220000000094A200109F
+:101000003C0480008C8301443042FFFF14620009DD
+:101010000000000024020001A4A200108C82014004
+:10102000AC8202003C021000AC8202380A000429A3
+:101030008FBF001C94A200100A00042200000000D0
+:10104000240200201482000E3C11800094A20012A1
+:101050003C0380008C6301443042FFFF14620005B2
+:101060000000000024020001A4A200120A0003FCF8
+:101070008FBF001C94A200120A000422000000008E
+:101080008E2401400E0003458F92FFA89642001265
+:101090008E2301443050FFFF16030002240200019A
+:1010A000A64200120E0003508E2401408E220144FD
+:1010B000160200068FBF001C8FB200188FB10014FB
+:1010C0008FB000100A00038E27BD00209642001248
+:1010D0000A0004220000000094A200143C038000D7
+:1010E0008C6301443042FFFF146200088FBF001C74
+:1010F000240200018FB200188FB100148FB00010CD
+:10110000A4A200140A00142427BD002094A20014F5
+:101110000A0004220000000094A200163C03800094
+:101120008C6301443042FFFF146200082402000176
+:101130008FBF001C8FB200188FB100148FB0001049
+:10114000A4A200160A000B0027BD002094A20016DE
+:10115000144000068FBF001C3C0208008C42007047
+:10116000244200013C010800AC2200708FB200183C
+:101170008FB100148FB0001003E0000827BD0020DD
+:1011800027BDFFD8AFB200188F92FFA8AFB10014EF
+:10119000AFBF0020AFB3001CAFB000103C02800016
+:1011A000345101008C50010092420000922300094A
+:1011B000304400FF2402001F106200AB28620020B0
+:1011C00010400019240200382862000A1040000D67
+:1011D0002402000B286200081040002E8F82001CA1
+:1011E00004600103286200021440002A8F82001C60
+:1011F00024020006106200268FBF00200A00054C62
+:101200008FB3001C106200602862000B144000F9CC
+:101210008FBF00202402000E106200788F82001C15
+:101220000A00054C8FB3001C106200D128620039FF
+:101230001040000A2402008024020036106200E4FC
+:1012400028620037104000C224020035106200D826
+:101250008FBF00200A00054C8FB3001C1062002DC8
+:101260002862008110400006240200C824020039D0
+:10127000106200C88FBF00200A00054C8FB3001C0D
+:10128000106200A28FBF00200A00054C8FB3001C23
+:101290008F82001C8C42000C104000D68FBF0020B3
+:1012A0000E000D45000000003C0380003463010087
+:1012B0008C6200008F850018946700089466000C0B
+:1012C000ACA200008C6400048F82001C0006340075
+:1012D000ACA400049448001E8C62001800073C0077
+:1012E00000E83825ACA200088C62001C2404000130
+:1012F000ACA2000C9062000A00C23025ACA600101F
+:10130000ACA00014ACA00018ACA7001C0A00050B90
+:101310008FBF00208F82001C8C42000C104000B553
+:101320008FBF00200E000D45000000008F82001CC2
+:10133000962400089625000C9443001E0004220207
+:101340009626000E8F8200180004260000832025B8
+:1013500000052C003C03008000A6282500832025E2
+:10136000AC400000AC400004AC400008AC40000CB5
+:10137000AC450010AC400014AC400018AC44001C5C
+:101380000A00050A240400019622000C14400018EB
+:10139000000000009242000530420010144000148A
+:1013A000000000000E0003450200202192420005CB
+:1013B00002002021344200100E000350A24200051A
+:1013C0009242000024030020304200FF10430088B6
+:1013D000020020218FBF00208FB3001C8FB20018A5
+:1013E0008FB100148FB000100A00103627BD0028FE
+:1013F0000000000D0A00054B8FBF00208C42000C3E
+:101400001040007C8FBF00200E000D450000000042
+:101410008E2200048F8400189623000CAC820000FA
+:101420003C0280089445002C8F82001C00031C00A5
+:1014300030A5FFFF9446001E3C02400E00651825B3
+:1014400000C23025AC830004AC800008AC80000CE6
+:10145000AC800010AC800014AC800018AC86001C7E
+:101460000A00050A240400010E00034502002021A1
+:101470008F93FFAC020020210E000350A660000CE9
+:10148000020020210E000355240500018F82001C5C
+:101490008C42000C104000578FBF00200E000D45FD
+:1014A000000000009622000C8F8300180002140038
+:1014B000AC700000AC620004AC6000088E440038E0
+:1014C0008F82001CAC64000C8E46003C9445001ECC
+:1014D0003C02401FAC66001000A228258E6200046A
+:1014E00024040001AC620014AC600018AC65001C60
+:1014F0008FBF00208FB3001C8FB200188FB1001473
+:101500008FB000100A000D7927BD002824020020AA
+:10151000108200398FB3001C0E000F1F0000000066
+:10152000104000348FBF00203C0380008C6201F823
+:101530000440FFFE24020002AC7001C0A06201C49E
+:101540003C021000AC6201F80A00054B8FBF00207E
+:10155000020020218FBF00208FB3001C8FB2001823
+:101560008FB100148FB000100A000E6827BD00284C
+:101570009625000C020020218FBF00208FB3001C95
+:101580008FB200188FB100148FB000100A000E8DBA
+:1015900027BD0028020020218FB3001C8FB2001845
+:1015A0008FB100148FB000100A000EB827BD0028BC
+:1015B0009225000D020020218FB3001C8FB200186D
+:1015C0008FB100148FB000100A000F0927BD00284A
+:1015D000020020218FBF00208FB3001C8FB20018A3
+:1015E0008FB100148FB000100A000EE027BD002854
+:1015F0008FBF00208FB3001C8FB200188FB1001472
+:101600008FB0001003E0000827BD00283C038000D5
+:101610008C6202780440FFFE24020002AC640240A7
+:10162000A06202443C02100003E00008AC620278B1
+:10163000A380001003E00008A38000113C03800099
+:101640008C6202780440FFFE8F820014AC6202407C
+:1016500024020002A06202443C02100003E00008E1
+:10166000AC6202783C02600003E000088C42540443
+:101670009083003024020005008040213063003F49
+:101680000000482114620005000050219082004CA7
+:101690009483004E304900FF306AFFFFAD00000C1C
+:1016A000AD000010AD000024950200148D05001C53
+:1016B0008D0400183042FFFF004910230002110082
+:1016C000000237C3004038210086202300A2102BDF
+:1016D0000082202300A72823AD05001CAD040018BC
+:1016E000A5090014A5090020A50A001603E00008BA
+:1016F000A50A002203E000080000000027BDFFD873
+:10170000AFB200183C128008AFB40020AFB3001C89
+:10171000AFB10014AFBF0024AFB0001036510100CC
+:101720003C0260008C4254049222000C3C140800DD
+:10173000929400F7304300FF24020001106200324F
+:101740000080982124020002146200353650008087
+:101750000E0013FE000000009202004C2403FF80E4
+:101760003C0480003042007F000211C0244202404D
+:101770000262102100431824AC83009492450008B3
+:101780009204004C3042007F3C0380061485000721
+:10179000004380212402FFFFA22200112402FFFF48
+:1017A000A62200120A0005BE2402FFFF96020020B6
+:1017B000A222001196020022A62200128E0200240C
+:1017C0003C048008AE2200143485008090A2004CB6
+:1017D00034830100A06200108CA2003CAC620018AF
+:1017E0008C820068AC6200E48C820064AC6200E031
+:1017F0008C82006CAC6200E824020001A0A20068A8
+:101800000A0005DA3C0480080E00141700000000EE
+:1018100036420080A04000680A0005DA3C048008D7
+:10182000A2000068A20000690A0006153C028008B8
+:10183000348300808C62003834850100AC62006C17
+:1018400024020001A062006990A200C590830008F4
+:10185000305100FF3072007F12320019001111C0A8
+:1018600024420240026210212403FF800043182416
+:101870003C048000AC8300943042007F3C0380062F
+:10188000004380218E02000C1040000D0200202138
+:101890000E00056A0000000026220001305100FF02
+:1018A0009203003C023410260002102B0002102389
+:1018B0003063007F022288240A0005E4A203003C72
+:1018C0003C088008350401008C8200D03507008078
+:1018D000ACE2003C8C8200D0AD02000090E5004CF0
+:1018E000908600C590E3004C908400C52402FF80E0
+:1018F00000A228243063007F308400FF00A6282542
+:101900000064182A1060000230A500FF38A500808E
+:10191000A0E5004CA10500093C0280089043000EA0
+:10192000344400803C058000A043000A8C830018EA
+:101930003C027FFF3442FFFF00621824AC83001892
+:101940008CA201F80440FFFE00000000ACB301C00F
+:101950008FBF00248FB400208FB3001C8FB20018FB
+:101960008FB100148FB0001024020002A0A201C4A5
+:1019700027BD00283C02100003E00008ACA201F8DB
+:1019800090A2000024420001A0A200003C03080035
+:101990008C6300F4304200FF1443000200803021C9
+:1019A000A0A0000090A200008F840014000211C0CB
+:1019B0002442024024830040008220212402FF8030
+:1019C000008220243063007F3C02800A00621821DC
+:1019D0003C028000AC44002403E00008ACC30000DB
+:1019E00094820006908300058C85000C8C86001084
+:1019F0008C8700188C88001C8C8400203C01080017
+:101A0000A42252C63C010800A02352C53C01080094
+:101A1000AC2552CC3C010800AC2652D03C01080059
+:101A2000AC2752D83C010800AC2852DC3C0108002D
+:101A3000AC2452E003E00008000000003C028008F3
+:101A4000344201008C4400343C03800034650400BF
+:101A5000AC6400388C420038AF850020AC62003C9A
+:101A60003C020005AC6200300000000000000000F5
+:101A700003E00008000000003C020006308400FF84
+:101A8000008220253C028000AC44003000000000B1
+:101A900000000000000000003C0380008C62000099
+:101AA000304200101040FFFD3462040003E00008E3
+:101AB000AF82002094C200003C080800950800CACC
+:101AC00030E7FFFF0080482101021021A4C200007E
+:101AD00094C200003042FFFF00E2102B544000018E
+:101AE000A4C7000094A200003C0308008C6300CC53
+:101AF00024420001A4A2000094A200003042FFFF93
+:101B0000144300073C0280080107102BA4A000002A
+:101B10005440000101003821A4C700003C028008A5
+:101B2000344601008CC3002894A200003C048000CD
+:101B30003042FFFE000210C000621021AC82003C67
+:101B40008C82003C00621823186000040000000032
+:101B50008CC200240A0006A6244200018CC2002484
+:101B6000AC8200383C020050344200103C0380003C
+:101B7000AC62003000000000000000000000000027
+:101B80008C620000304200201040FFFD0000000089
+:101B900094A200003C04800030420001000210C00A
+:101BA000004410218C430400AD2300008C42040447
+:101BB000AD2200043C02002003E00008AC820030AB
+:101BC00027BDFFE0AFB20018AFB10014AFB00010F6
+:101BD000AFBF001C94C2000000C080213C1208006E
+:101BE000965200C624420001A6020000960300009F
+:101BF00094E2000000E03021144300058FB1003072
+:101C00000E00067B024038210A0006DD00000000BD
+:101C10008C8300048C82000424420040046100078D
+:101C2000AC8200048C820004044000040000000028
+:101C30008C82000024420001AC8200009602000069
+:101C40003042FFFF50520001A60000009622000023
+:101C500024420001A62200003C0280083442010018
+:101C6000962300009442003C144300048FBF001CE4
+:101C700024020001A62200008FBF001C8FB20018B2
+:101C80008FB100148FB0001003E0000827BD0020C2
+:101C900027BDFFE03C028008AFBF001834420100BE
+:101CA0008C4800343C03800034690400AC68003880
+:101CB0008C42003830E700FFAF890020AC62003C66
+:101CC0003C020005AC620030000000000000000093
+:101CD0000000000000000000000000000000000004
+:101CE0008C82000C8C82000C9783000EAD220000C9
+:101CF0008C82001000604021AD2200048C8200180C
+:101D0000AD2200088C82001CAD22000C8CA20014B5
+:101D1000AD2200108C820020AD22001490820005BC
+:101D2000304200FF00021200AD2200188CA2001801
+:101D3000AD22001C8CA2000CAD2200208CA2001051
+:101D4000AD2200248CA2001CAD2200288CA2002011
+:101D5000AD22002C3402FFFFAD260030AD20003450
+:101D6000506200013408FFFFAD28003850E0001138
+:101D70003C0280083C0480083484010094820050B6
+:101D80003042FFFFAD22003C948300449485004420
+:101D9000240200013063FFFF000318C20064182111
+:101DA0009064005430A5000700A210040A00074800
+:101DB0000044102534420100AD20003C944300440F
+:101DC000944400443063FFFF000318C200621821EE
+:101DD0003084000790650054240200010082100442
+:101DE0000002102700451024A062005400000000EB
+:101DF00000000000000000003C02000634420040E9
+:101E00003C038000AC6200300000000000000000D5
+:101E1000000000008C620000304200101040FFFD06
+:101E20003C06800834C201503463040034C7014AC0
+:101E300034C4013434C5014034C60144AFA200109B
+:101E40000E0006BEAF8300208FBF001803E000081D
+:101E500027BD00208F83000C3C0608008CC600E8DC
+:101E60008F82001430633FFF000319800046102169
+:101E7000004310212403FF80004318243C06800007
+:101E8000ACC300283042007F3C03800C004330216B
+:101E900090C2000D30A500FF000038213442001030
+:101EA000A0C2000D8F89000C3C0280083442010062
+:101EB00094430044000913823048000324020001C7
+:101EC000A4C3000E1102000B2902000210400005FD
+:101ED000240200021100000C240300010A000790F4
+:101EE0000000182111020006000000000A000790FF
+:101EF000000018218CC2002C0A0007902443000126
+:101F00008CC20014244300018CC200180043102B23
+:101F10005040000A240700012402002714A20003F5
+:101F20003C0380080A00079D240700013463010078
+:101F30009462004C24420001A462004C0009138208
+:101F4000304300032C620002104000090080282169
+:101F5000146000040000000094C200340A0007ADC1
+:101F60003046FFFF8CC600380A0007AD00802821EC
+:101F7000000030213C040800248452C00A0006F20C
+:101F80000000000027BDFF90AFB60068AFB5006449
+:101F9000AFB40060AFB3005CAFB20058AFB1005453
+:101FA000AFBF006CAFB000508C9000000080B0213B
+:101FB0003C0208008C4200E8960400328F83001433
+:101FC0002414FF8030843FFF006218210004218028
+:101FD00000641821007410243C13800000A090219C
+:101FE00090A50000AE620028920400323C02800CF2
+:101FF0003063007F00628821308400C024020040EA
+:10200000148200320000A8218E3500388E2200187C
+:102010001440000224020001AE2200189202003C8B
+:10202000304200201440000E8F830014000511C0C0
+:102030002442024000621821306400783C02008093
+:102040000082202500741824AE630800AE640810D6
+:102050008E2200188E03000800431021AE220018C3
+:102060008E22002C8E230018244200010062182BBF
+:102070001060004300000000924200002442000172
+:10208000A24200003C0308008C6300F4304200FFD1
+:1020900050430001A2400000924200008F840014CF
+:1020A000000211C024420240248300403063007FBC
+:1020B000008220213C02800A009420240062182122
+:1020C000AE6400240A0008BEAEC3000092030032D2
+:1020D0002402FFC000431024304200FF14400005DA
+:1020E00024020001AE220018962200340A00082EB5
+:1020F0003055FFFF8E22001424420001AE2200184A
+:102100009202003000021600000216030441001C77
+:10211000000000009602003227A400100080282151
+:10212000A7A2001696020032000030212407000109
+:102130003042FFFFAF82000C0E0006F2AFA0001C81
+:10214000960200328F8300143C0408008C8400E85F
+:1021500030423FFF00021180006418210062182104
+:1021600000741024AE62002C3063007F3C02800EAD
+:10217000006218219062000D3042007FA062000DC5
+:102180009222000D30420010504000789242000030
+:102190003C028008344401009482004C8EC300004D
+:1021A0003C130800967300C62442FFFFA482004C33
+:1021B000946200329623000E3054FFFF3070FFFF10
+:1021C0003C0308008C6300D000701807A7A30038F8
+:1021D0009482003E3063FFFF3042FFFF146200072D
+:1021E000000000008C8200303C038000244200305C
+:1021F000AC62003C0A0008568C82002C948200409D
+:102200003042FFFF5462000927A400408C8200384E
+:102210003C03800024420030AC62003C8C820034DD
+:10222000AC6200380A0008653C03800027A500382E
+:1022300027A60048026038210E00067BA7A00048B0
+:102240008FA300403C02800024630030AC43003880
+:102250008FA30044AC43003C3C0380003C020005DB
+:10226000AC6200303C028008344401009482004299
+:10227000346304003042FFFF0202102B14400007B9
+:10228000AF8300209482004E94830042020210210A
+:10229000004310230A00087B3043FFFF9483004E65
+:1022A0009482004202631821005010230062182318
+:1022B0003063FFFF3C028008344401009482003CFC
+:1022C0003042FFFF14430003000000000A00088BA7
+:1022D000240300019482003C3042FFFF0062102B77
+:1022E000144000058F8200209482003C006210237D
+:1022F0003043FFFF8F820020AC550000AC4000044B
+:10230000AC540008AC43000C3C0200063442001000
+:102310003C038000AC6200300000000000000000C0
+:10232000000000008C620000304200101040FFFDF1
+:102330003C04800834840100001018C20064182195
+:102340009065005432020007240600010046100484
+:1023500000451025A0620054948300429622000E8E
+:1023600050430001A3860010924200002442000165
+:10237000A24200003C0308008C6300F4304200FFDE
+:1023800050430001A2400000924200008F840014DC
+:10239000000211C024420240248300400082202118
+:1023A0002402FF80008220243063007F3C02800AE8
+:1023B000006218213C028000AC440024AEC300003F
+:1023C0008FBF006C8FB600688FB500648FB400605B
+:1023D0008FB3005C8FB200588FB100548FB00050A3
+:1023E00003E0000827BD007027BDFFD8AFB3001C75
+:1023F000AFB20018AFB10014AFB00010AFBF0020F3
+:102400000080982100E0802130B1FFFF0E000D45D3
+:1024100030D200FF000000000000000000000000BB
+:102420008F8200188F83001CAC510000AC52000456
+:10243000AC530008AC40000CAC400010AC400014A1
+:10244000AC4000189463001E02038025AC50001CB1
+:102450000000000000000000000000002404000153
+:102460008FBF00208FB3001C8FB200188FB10014F3
+:102470008FB000100A000D7927BD002830A5FFFF9E
+:102480000A0008C830C600FF3C028008344301003F
+:102490009462000E3C080800950800C63046FFFF15
+:1024A00014C000043402FFFF946500DA0A00091525
+:1024B0008F84001410C20027000000009462004EB8
+:1024C0009464003C3045FFFF00A6102300A6182BA3
+:1024D0003087FFFF106000043044FFFF00C5102369
+:1024E00000E210233044FFFF0088102B1040000E44
+:1024F00000E810233C02800834440100240300015A
+:1025000034420080A44300162402FFFFA482000E80
+:10251000948500DA8F8400140000302130A5FFFF7D
+:102520000A0008ED3C0760200044102A1040000912
+:102530003C0280083443008094620016304200015F
+:10254000104000043C0280009442007E24420014AB
+:10255000A462001603E000080000000027BDFFE0B1
+:102560003C028008AFBF001CAFB00018344201002D
+:10257000944300429442004C104000193068FFFF21
+:102580009383001024020001146200298FBF001CF5
+:102590003C06800834D00100000810C20050102111
+:1025A000904200543103000734C70148304200FF15
+:1025B000006210073042000134C9014E34C4012CBE
+:1025C00034C5013E1040001634C601420E0006BE5E
+:1025D000AFA90010960200420A0009323048FFFFFE
+:1025E0003C028008344401009483004494820042F9
+:1025F0001043000F8FBF001C94820044A48200424D
+:1026000094820050A482004E8C820038AC8200304C
+:1026100094820040A482003E9482004AA482004832
+:102620008FBF001C8FB000180A0008F027BD0020E3
+:102630008FB0001803E0000827BD002027BDFFA0D1
+:10264000AFB1004C3C118000AFBF0058AFB3005495
+:10265000AFB20050AFB000483626018890C20003E8
+:102660003044007FA3A400108E32018090C200008D
+:102670003043007F240200031062003BAF9200143D
+:102680002862000410400006240200042402000214
+:10269000106200098FBF00580A000AFB8FB3005474
+:1026A0001062004D240200051062014E8FBF0058D9
+:1026B0000A000AFB8FB30054000411C0024210212B
+:1026C0002404FF802442024000441024264300409A
+:1026D000AE2200243063007F3C02800A0062182191
+:1026E0009062003CAFA3003C00441025A062003C77
+:1026F0008FA3003C9062003C304200401040016CCF
+:102700008FBF00583C108008A380001036100100D5
+:102710008E0200D08C63003427A4003C27A5001053
+:10272000004310210E0007AFAE0200D093A20010AC
+:102730003C038000A20200C58C6202780440FFFEC8
+:102740008F820014AC62024024020002A0620244A4
+:102750003C021000AC6202780E0009250000000067
+:102760000A000AFA8FBF00583C05800890C3000198
+:1027700090A2000B1443014E8FBF005834A4008078
+:102780008C8200189082004C90A200083C026000ED
+:102790008C4254048C8300183C027FFF3442FFFFBC
+:1027A000006218243C0208008C4200B4AC8300187C
+:1027B0003C038000244200013C010800AC2200B42C
+:1027C0008C6201F80440FFFE8F820014AC6201C0ED
+:1027D0000A000AC2240200023C10800890C30001D3
+:1027E0009202000B144301328FBF005827A4001837
+:1027F00036050110240600033C0260008C4254049C
+:102800000E000E080000000027A40028360501E095
+:102810000E000E08240600038FA2002836030100D4
+:10282000AE0200648FA2002CAE0200688FA20030BE
+:10283000AE02006C93A40018906300C52402FF80D0
+:102840000082102400431025304900FF3084007FAF
+:102850003122007F0082102A544000013929008073
+:10286000000411C0244202402403FF8002421021D0
+:1028700000431024AE220094264200403042007FE4
+:102880003C038006004340218FA3001C2402FFFF6D
+:10289000AFA800403C130800927300F710620033A9
+:1028A00093A2001995030014304400FF3063FFFF2A
+:1028B0000064182B10600010000000009504001444
+:1028C0008D07001C8D0600183084FFFF0044202374
+:1028D0000004210000E438210000102100E4202B36
+:1028E00000C2302100C43021AD07001CAD06001825
+:1028F0000A000A1B93A20019950400148D07001CFE
+:102900008D0600183084FFFF008220230004210080
+:10291000000010210080182100C2302300E4202B89
+:1029200000C4302300E33823AD07001CAD060018B7
+:1029300093A200198FA30040A462001497A2001A6A
+:10294000A46200168FA2001CAC6200108FA2001CB3
+:10295000AC62000C93A20019A462002097A2001A96
+:10296000A46200228FA2001CAC6200243C048008F8
+:10297000348300808C6200388FA2002001208821DF
+:10298000AC62003C8FA20020AC82000093A2001831
+:10299000A062004C93A20018A0820009A060006809
+:1029A00093A20018105100512407FF803229007FA4
+:1029B000000911C024420240024210213046007F2B
+:1029C0003C03800000471024AC6200943C02800667
+:1029D00000C2302190C2003CAFA600400000202180
+:1029E00000471025A0C2003C8FA8004095020002BD
+:1029F000950300148D07001C3042FFFF3063FFFF7A
+:102A00008D060018004310230002110000E2382157
+:102A100000E2102B00C4302100C23021AD07001CA1
+:102A2000AD06001895020002A5020014A5000016CC
+:102A30008D020008AD0200108D020008AD02000CEE
+:102A400095020002A5020020A50000228D020008C8
+:102A5000AD0200249102003C304200401040001AB8
+:102A6000262200013C108008A3A90038A380001092
+:102A7000361001008E0200D08D03003427A40040E0
+:102A800027A50038004310210E0007AFAE0200D08A
+:102A900093A200383C038000A20200C58C62027839
+:102AA0000440FFFE8F820014AC6202402402000248
+:102AB000A06202443C021000AC6202780E000925BC
+:102AC00000000000262200013043007F1473000440
+:102AD000004020212403FF800223102400432026ED
+:102AE00093A200180A000A37309100FF93A400183F
+:102AF0008FA3001C2402FFFF1062000A308900FF30
+:102B000024820001248300013042007F1453000519
+:102B1000306900FF2403FF80008310240043102647
+:102B2000304900FF3C0280089042000801208821C3
+:102B3000305000FF123000193222007F000211C015
+:102B400002421021244202402403FF800043182443
+:102B50003C048000AC8300943042007F3C0380063C
+:102B6000004310218C43000C004020211060000B1A
+:102B7000AFA200400E00056A0000000026230001FD
+:102B80002405FF803062007F1453000202252024B8
+:102B9000008518260A000A9B307100FF3C0480085B
+:102BA000348400808C8300183C027FFF3442FFFF96
+:102BB00000621824AC8300183C0380008C6201F88A
+:102BC0000440FFFE00000000AC7201C024020002BD
+:102BD000A06201C43C021000AC6201F80A000AFACB
+:102BE0008FBF00583C04800890C300019082000B06
+:102BF0001443002F8FBF00583490008092020008C9
+:102C00003042004010400020000000009202000806
+:102C100000021600000216030441000502402021B4
+:102C20000E000E8D240500930A000AFA8FBF00588B
+:102C30009202000924030018304200FF1443000DE3
+:102C400002402021240500390E000E25000030210D
+:102C50000E0003458F8400148F82FFA82403001206
+:102C6000A04300090E0003508F8400140A000AFAE2
+:102C70008FBF0058240500360E000E2500003021BD
+:102C80000A000AFA8FBF00580E00034502402021B7
+:102C9000920200058F840014344200200E0003507D
+:102CA000A20200050E0010368F8400148FBF00585A
+:102CB0008FB300548FB200508FB1004C8FB00048DA
+:102CC00003E0000827BD00603C0280083445010095
+:102CD0003C0280008C42014094A3000E0000302191
+:102CE00000402021AF8200143063FFFF3402FFFF59
+:102CF000106200063C0760202402FFFFA4A2000E21
+:102D000094A500DA0A0008ED30A5FFFF03E00008F3
+:102D10000000000027BDFFC83C0280003C06800880
+:102D2000AFB5002CAFB1001CAFBF0030AFB400286E
+:102D3000AFB30024AFB20020AFB00018345101008F
+:102D400034C501008C4301008E2200148CA400D4F1
+:102D50000000A821AF830014004410231840005243
+:102D6000A38000108E22001400005021ACA200D4D9
+:102D700090C3000890A200C53073007FA3A200108A
+:102D80008CB200D08CB400D4304200FF1053003B12
+:102D900093A200108F8300142407FF80000211C04B
+:102DA00000621021244202402463004000471024A6
+:102DB0003063007F3C0980003C08800A00681821CD
+:102DC000AD2200248C62003427A4001427A5001033
+:102DD000024280210290102304400028AFA3001477
+:102DE0009062003C00E21024304200FF14400019C1
+:102DF000020090219062003C34420040A062003CFE
+:102E00008F86001493A3001024C200403042007F3C
+:102E1000004828213C0208008C4200F42463000191
+:102E2000306400FF14820002A3A30010A3A00010CE
+:102E300093A20010AFA50014000211C0244202406A
+:102E400000C2102100471024AD2200240A000B31DB
+:102E500093A200100E0007AF000000003C028008A3
+:102E600034420100AC5000D093A30010240A0001AA
+:102E7000A04300C50A000B3193A2001024020001F8
+:102E8000154200093C0380008C6202780440FFFE7A
+:102E90008F820014AC62024024020002A06202444D
+:102EA0003C021000AC6202789222000B2403000264
+:102EB000304200FF14430072000000009622000818
+:102EC000304300FF24020082146200402402008488
+:102ED0003C028000344901008D22000C952300063D
+:102EE000000216023063FFFF3045003F2402002736
+:102EF00010A2000FAF83000C28A200281040000889
+:102F0000240200312402002110A20009240200251D
+:102F100010A20007938200110A000BA90000000014
+:102F200010A20007938200110A000BA90000000004
+:102F30000E000763012020210A000C290000000078
+:102F40003C0380008C6202780440FFFE8F820014F4
+:102F5000AC62024024020002A06202443C02100063
+:102F6000AC6202780A000C290000000095230006DC
+:102F7000912400058D25000C8D2600108D2700184A
+:102F80008D28001C8D290020244200013C010800EE
+:102F9000A42352C63C010800A02452C53C010800ED
+:102FA000AC2552CC3C010800AC2652D03C010800B4
+:102FB000AC2752D83C010800AC2852DC3C01080088
+:102FC000AC2952E00A000C29A38200111462000A05
+:102FD000240200813C02800834420100944500DA5A
+:102FE000922600058F84001430A5FFFF30C600FF35
+:102FF0000A000BEA3C0760211462005C000000003C
+:103000009222000A304300FF306200201040000787
+:10301000306200403C02800834420100944500DAEE
+:103020008F8400140A000BE82406004010400007BB
+:10303000000316003C02800834420100944500DA87
+:103040008F8400140A000BE82406004100021603D6
+:10305000044100463C02800834420100944500DAF5
+:103060008F8400142406004230A5FFFF3C0760193E
+:103070000E0008ED000000000A000C29000000000E
+:103080009222000B24040016304200FF1044000678
+:103090003C0680009222000B24030017304200FF00
+:1030A000144300320000000034C5010090A2000B60
+:1030B000304200FF1444000B000080218CA200204D
+:1030C0008CA400202403FF80004310240002114040
+:1030D0003084007F004410253C032000004310256D
+:1030E000ACC2083094A200080002140000021403CD
+:1030F000044200012410000194A200083042008024
+:103100005040001A0200A82194A20008304220007A
+:10311000504000160200A8218CA300183C021C2D70
+:10312000344219ED106200110200A8213C0208008F
+:103130008C4200D4104000053C02800824030004A7
+:1031400034420100A04300EC3C02800834420100FC
+:10315000944500DA8F8400142406000630A5FFFF92
+:103160000E0008ED3C0760210200A8210E00092591
+:10317000000000009222000A3042000810400004C3
+:1031800002A010210E00133A0000000002A010213E
+:103190008FBF00308FB5002C8FB400288FB3002470
+:1031A0008FB200208FB1001C8FB0001803E0000820
+:1031B00027BD00382402FF80008220243C029000BA
+:1031C00034420007008220253C028000AC440020ED
+:1031D0003C0380008C6200200440FFFE00000000E1
+:1031E00003E00008000000003C0380002402FF8090
+:1031F000008220243462000700822025AC64002075
+:103200008C6200200440FFFE0000000003E0000884
+:10321000000000003C028008240300053442010045
+:10322000A04300EC3C0280008C4201003C03800083
+:10323000AF8200148C6202780440FFFE8F8200147B
+:10324000AC62024024020002A06202443C02100070
+:10325000AC62027803E000080000000027BDFFE830
+:103260003C068000AFBF001034C7010094E20008A4
+:10327000304400FF38830082388200842C630001D0
+:103280002C420001006218251060002D24020083EA
+:1032900093820011504000368FBF00103C0208009E
+:1032A000904252CC8CC401003C06080094C652C621
+:1032B0003045003F38A3003238A2003F2C630001A4
+:1032C0002C42000100621825AF840014AF86000C68
+:1032D000A38000111460000700E0202124020020D8
+:1032E00014A20012000000003402FFFF14C2000FFD
+:1032F000000000002402002014A2000500E02821A4
+:103300008CE300142402FFFF5062000B8FBF0010FB
+:103310003C040800248452C0000030210E0006F254
+:10332000240700010A000C9C8FBF00100E000763E9
+:10333000000000008FBF00100A00092527BD0018FB
+:10334000148200062482FF808CC301043C026020AA
+:10335000AC4300140A000CD28FBF0010304200FFB3
+:103360002C42000210400004240200228FBF0010F3
+:103370000A000B1327BD0018148200048F82001C62
+:103380008FBF00100A000C5327BD00188C42000CA0
+:103390001040001E00E0282190E3000924020018DC
+:1033A00014620003240200160A000CBD2403000866
+:1033B0001462000724020017240300123C02800854
+:1033C00034420080A04300090A000CCA94A70008F8
+:1033D0005462000794A700088F82FFA82404FFFE10
+:1033E0009043000500641824A043000594A700083A
+:1033F00090A6001B8CA4000094A500068FBF0010AF
+:1034000000073C000A0008C827BD00188FBF001045
+:1034100003E0000827BD00188F85001C3C048000D5
+:1034200094A2002A8CA30034000230C02402FFF0D2
+:1034300000C2102400621821AC83003C8CA2003032
+:103440003C038000AC8200383C0200503442001043
+:10345000AC6200300000000000000000000000002E
+:103460008C620000304200201040FFFD30C2000896
+:10347000104000063C0280008C620408ACA20020D0
+:103480008C62040C0A000CF5ACA200248C430400EE
+:10349000ACA300208C420404ACA200243C03002016
+:1034A0003C028000AC4300303C0480008C82003041
+:1034B000004310241440FFFD8F86001C3C02004096
+:1034C000AC82003094C3002A94C2002894C4002C1B
+:1034D00094C5002E24630001004410213064FFFFD6
+:1034E000A4C2002814850002A4C3002AA4C0002A94
+:1034F00003E00008000000008F84001C27BDFFE8E7
+:103500003C05800424840010AFBF00100E000E089C
+:103510002406000A8F84001C948200129483002EDB
+:103520003042000F244200030043180424027FFFAE
+:103530000043102B10400002AC8300000000000D7F
+:103540000E000CD4000000008F83001C8FBF001001
+:1035500027BD0018946200149463001A3042000FD3
+:1035600000021500006218253C02800003E00008FC
+:10357000AC4300A08F83001C3C02800494440006EE
+:103580009462001A8C650000A464001600441023A5
+:103590003042FFFF0045102B03E0000838420001D5
+:1035A0008F84001C3C0780049486001A8C850000E0
+:1035B00094E20006A482001694E3000600C31023E0
+:1035C0003042FFFF0045102B384200011440FFF845
+:1035D000A483001603E00008000000008F84001C94
+:1035E0003C028004944200069483001A8C850000FB
+:1035F000A4820016006210233042FFFF0045102B0A
+:10360000384200015040000D8F85001C00603021C1
+:103610003C07800494E20006A482001694E30006AE
+:1036200000C310233042FFFF0045102B3842000139
+:103630001440FFF8A48300168F85001C3C03800013
+:10364000346204008CA40020AF820018AC640038FF
+:103650008CA20024AC62003C3C020005AC6200304D
+:1036600003E00008ACA000048F84001C3C030006AB
+:103670008C82000400021140004310253C038000AE
+:10368000AC620030000000000000000000000000FC
+:103690008C620000304200101040FFFD34620400D4
+:1036A000AC80000403E00008AF8200188F86001C85
+:1036B00027BDFFE0AFB10014AFB00010AFBF0018DE
+:1036C0008CC300048CC500248F820018309000FF4A
+:1036D00094C4001A246300012442002024840001C1
+:1036E00024A70020ACC30004AF820018A4C4001AB1
+:1036F000ACC7002404A100060000882104E20005F4
+:1037000094C2001A8CC2002024420001ACC20020E6
+:1037100094C2001A94C300282E040001004310260E
+:103720002C420001004410245040000594C2001AAD
+:1037300024020001ACC2000894C2001A94C30028FD
+:103740000010202B004310262C42000100441025BD
+:1037500014400007000000008CC200081440000460
+:10376000240200108CC300041462000F8F85001C1B
+:103770000E000D68241100018F82001C9443002864
+:103780009442001A14430003000000000E000CD401
+:1037900000000000160000048F85001C0E000D457F
+:1037A000000000008F85001C94A2001E94A4001C41
+:1037B000244200013043FFFF14640002A4A2001E53
+:1037C000A4A0001E1200000A3C02800494A200146F
+:1037D00094A3001A3042000F000215000062182561
+:1037E0003C028000AC4300A00A000DDFACA0000842
+:1037F0009442000694A3001A8CA40000A4A2001610
+:10380000006210233042FFFF0044102B38420001B9
+:103810001040000D02201021006030213C07800480
+:1038200094E20006A4A2001694E3000600C310234D
+:103830003042FFFF0044102B384200011440FFF8D3
+:10384000A4A30016022010218FBF00188FB100140E
+:103850008FB0001003E0000827BD002003E000083F
+:10386000000000008F8200243C030006000211408B
+:10387000004310253C038000AC62003000000000D3
+:1038800000000000000000008C62000030420010C8
+:103890001040FFFD34620400AF82002003E0000806
+:1038A000AF80002403E000080000102103E00008BE
+:1038B000000000003084FFFF30A5FFFF000018214A
+:1038C000108000070000000030820001104000025C
+:1038D00000042042006518210A000DFE0005284062
+:1038E00003E000080060102110C0000624C6FFFF9E
+:1038F0008CA2000024A50004AC8200000A000E087F
+:103900002484000403E000080000000010A0000868
+:1039100024A3FFFFAC8600000000000000000000B0
+:103920002402FFFF2463FFFF1462FFFA24840004D3
+:1039300003E00008000000003C02800834420080E0
+:1039400024030001AC43000CA4430010A443001264
+:10395000A443001403E00008A44300168F82001C57
+:1039600027BDFFD8AFB3001CAFB20018AFB1001431
+:10397000AFB00010AFBF00208C47000C2482008045
+:103980002409FF803C08800E3043007F00808021A6
+:103990003C0A8000004920240068182130B100FF53
+:1039A00030D200FF10E0002900009821260201001B
+:1039B000AD44002C004928243042007F00482021DB
+:1039C0009062000024030050304200FF14430004C2
+:1039D00000000000AD45002C948200DA3053FFFF58
+:1039E0000E000D45000000008F82001C8F83001820
+:1039F00000112C009442001E0012240034840001A7
+:103A000000A228253C02400000A22825AC7000003E
+:103A10008FBF0020AC6000048FB20018AC730008A8
+:103A20008FB10014AC60000C8FB3001CAC640010AC
+:103A30008FB00010AC60001424040001AC600018CA
+:103A400027BD00280A000D79AC65001C8FBF00203F
+:103A50008FB3001C8FB200188FB100148FB000100C
+:103A600003E0000827BD00283C06800034C20100A6
+:103A70009043000F240200101062000E2865001110
+:103A800010A0000724020012240200082405003AB6
+:103A9000106200060000302103E000080000000072
+:103AA000240500351462FFFC000030210A000E25B9
+:103AB000000000008CC200748F83FFA824420FA076
+:103AC00003E00008AC62000C27BDFFE8AFBF0010A8
+:103AD0000E000355240500013C0480088FBF001030
+:103AE0002402000134830080A462001227BD001864
+:103AF0002402000103E00008A080001A27BDFFE0B7
+:103B0000AFB20018AFB10014AFB00010AFBF001CCF
+:103B100030B2FFFF0E000345008088213C02800880
+:103B2000345000809202000924030004304200FF58
+:103B30001443000C3C028008124000082402000AD2
+:103B40000E000E1C00000000920200052403FFFE80
+:103B500000431024A202000524020012A202000960
+:103B60003C02800834420080022020210E000350D5
+:103B7000A040002716400003022020210E000E80E6
+:103B80000000000002202021324600FF8FBF001CF1
+:103B90008FB200188FB100148FB0001024050038C8
+:103BA0000A000E2527BD002027BDFFE0AFBF001C87
+:103BB000AFB20018AFB10014AFB000100E00034553
+:103BC000008080210E000E1C000000003C028008D6
+:103BD0003445008090A2000924120018305100FFE3
+:103BE000123200030200202124020012A0A20009C8
+:103BF00090A200052403FFFE004310240E00035092
+:103C0000A0A2000502002021240500201632000792
+:103C1000000030218FBF001C8FB200188FB100143C
+:103C20008FB000100A00035527BD00208FBF001C75
+:103C30008FB200188FB100148FB000102405003926
+:103C40000A000E2527BD002027BDFFE83C028000AA
+:103C5000AFB00010AFBF0014344201009442000C1A
+:103C6000240500360080802114400012304600FFF9
+:103C70000E000345000000003C0280083442008032
+:103C800024030012A0430009904300053463001090
+:103C90000E000E1CA04300050E0003500200202160
+:103CA000020020210E000355240500200A000EFD0D
+:103CB000000000000E000E25000000000E0003456D
+:103CC000020020213C0280089043001B2405FF9F36
+:103CD00002002021006518248FBF00148FB000104F
+:103CE000A043001B0A00035027BD001827BDFFE0BA
+:103CF000AFBF0018AFB10014AFB0001030B100FF7B
+:103D00000E000345008080213C028008240300123D
+:103D1000344200800E000E1CA04300090E00035028
+:103D20000200202102002021022030218FBF001834
+:103D30008FB100148FB00010240500350A000E2545
+:103D400027BD00203C0480089083000E9082000A6A
+:103D50001443000B000028218F82FFA82403005089
+:103D60002405000190420000304200FF144300048B
+:103D7000000000009082000E24420001A082000E8C
+:103D800003E0000800A010213C0380008C6201F8D1
+:103D90000440FFFE24020002AC6401C0A06201C422
+:103DA0003C02100003E00008AC6201F827BDFFE010
+:103DB000AFB200183C128008AFB10014AFBF001CB6
+:103DC000AFB0001036510080922200092403000A8F
+:103DD000304200FF1443003E000000008E43000408
+:103DE0008E220038506200808FBF001C922200009B
+:103DF00024030050304200FF144300253C028000A1
+:103E00008C4201408E4300043642010002202821EA
+:103E1000AC43001C9622005C8E2300383042FFFF2A
+:103E20000002104000621821AE23001C8E430004E3
+:103E30008E2400389622005C006418233042FFFF75
+:103E400000031843000210400043102A10400006EF
+:103E5000000000008E4200048E230038004310232F
+:103E60000A000F6B000220439622005C3042FFFFE5
+:103E7000000220403C0280083443010034420080AC
+:103E8000ACA4002CA040002424020001A062000C7D
+:103E90000E000F1F00000000104000538FBF001CD9
+:103EA0003C0280008C4401403C0380008C6201F89D
+:103EB0000440FFFE24020002AC6401C0A06201C401
+:103EC0003C021000AC6201F80A000FC88FBF001C52
+:103ED0009222000924030010304200FF1443000422
+:103EE0003C0280008C4401400A000FAF00002821F2
+:103EF0009222000924030016304200FF14430006FA
+:103F000024020014A22200093C0280008C440140DB
+:103F10000A000FC28FBF001C8E2200388E23003C87
+:103F200000431023044100308FBF001C9222002761
+:103F300024420001A2220027922200272C420004E2
+:103F4000144000163C108000922200092403000453
+:103F5000304200FF144300093C0280008C440140C1
+:103F60008FBF001C8FB200188FB100148FB00010EB
+:103F7000240500930A000E8D27BD00208C440140CB
+:103F8000240500938FBF001C8FB200188FB100145E
+:103F90008FB000100A000F0927BD00208E040140D9
+:103FA0000E000345000000008E4200042442FFFF83
+:103FB000AE4200048E22003C2442FFFFAE22003CB1
+:103FC0000E0003508E0401408E0401408FBF001C80
+:103FD0008FB200188FB100148FB0001024050004B8
+:103FE0000A00035527BD00208FB200188FB10014BE
+:103FF0008FB0001003E0000827BD00203C068000C1
+:104000008CC201883C038008346500809063000EF8
+:1040100000021402304400FF306300FF1464000EFD
+:104020003C02800890A20026304200FF10440009A4
+:104030008F82FFA8A0A40026240300509042000015
+:10404000304200FF14430006000000000A00058D06
+:104050008CC401803C02800834420080A0440026C9
+:1040600003E000080000000027BDFFE030E700FF8C
+:10407000AFB20018AFBF001CAFB10014AFB000105A
+:104080000080902114E0000630C600FF0000000010
+:104090000000000D000000000A0010212400010EA5
+:1040A0003C0380089062000E304200FF144600235B
+:1040B0003462008090420026304200FF1446001F08
+:1040C000000000009062000F304200FF1446001B09
+:1040D000000000009062000A304200FF1446000316
+:1040E0008F90FFA80000000D8F90FFA88F82FFAC7B
+:1040F0003C118000AE05003CAC450000A066000A03
+:104100000E0003458E240100A20000240E0003507F
+:104110008E2401003C0380008C6201F80440FFFE05
+:1041200024020002AC7201C0A06201C43C02100073
+:10413000AC6201F80A0010228FBF001C00000000D2
+:104140000000000D00000000240001378FBF001C9C
+:104150008FB200188FB100148FB0001003E0000878
+:1041600027BD00208F83FFA83C0280008C44010003
+:10417000344201008C65003C9046001B0A000FE8A9
+:10418000240700013C0280089043000E9042000A80
+:1041900000431026304200FF03E000080002102B0D
+:1041A00027BDFFE03C028008AFB10014AFB00010A3
+:1041B000AFBF001834500080920200052403003085
+:1041C0003042003014430085008088218F82001C1B
+:1041D0008C42000C104000828FBF00180E000D456D
+:1041E000000000008F860018ACD100009202000889
+:1041F00092030009304200FF00021200306300FF0A
+:1042000000431025ACC200049202004D00021600CB
+:104210000002160304410005000000003C030800F2
+:104220008C6300480A0010603C108008920200086D
+:104230003042004014400003000018219202002781
+:10424000304300FF3C108008361100809222004D60
+:1042500000031E00304200FF000214000062182517
+:10426000ACC300088E2400308F82001CACC4000C4C
+:104270008E2500349443001E3C02C00BACC50010D8
+:10428000006218258E22003800002021ACC20014E4
+:104290008E22003CACC200180E000D79ACC3001C8D
+:1042A0008E0200048F8400183C058000AC82000060
+:1042B0008E220020AC8200048E22001CAC820008FA
+:1042C0008E2200588CA3007400431021AC82000C95
+:1042D0008E22002CAC8200108E2200408E230044DF
+:1042E0000002140000431025AC8200149222004DFD
+:1042F00024030080304200FF14430004000000004B
+:10430000AC8000180A0010A48F82001C8E23000CC1
+:10431000240200011062000E2402FFFF9222000816
+:10432000304200401440000A2402FFFF8E23000C9C
+:104330008CA20074006218233C0208000062102462
+:1043400014400002000028210060282100051043CD
+:10435000AC8200188F82001C000020219443001EB4
+:104360003C02C00C006218258F8200180E000D79E7
+:10437000AC43001C3C038008346201008C42000006
+:104380008F850018346300808FBF0018ACA2000036
+:10439000ACA000048C6400488F82001C8FB1001414
+:1043A000ACA40008ACA0000CACA000109063000509
+:1043B0009446001E3C02400D00031E0000C2302542
+:1043C000ACA300148FB00010ACA0001824040001AE
+:1043D000ACA6001C0A000D7927BD00208FBF001875
+:1043E0008FB100148FB0001003E0000827BD00203B
+:1043F0003C0280009443007C3C028008344601006B
+:10440000308400FF3065FFFF2402000524A34650DE
+:10441000A0C4000C5482000C3065FFFF90C2000D58
+:104420002C4200071040000724A30A0090C3000D8F
+:10443000240200140062100400A210210A0010E0FF
+:104440003045FFFF3065FFFF3C02800834420080AA
+:1044500003E00008A44500143C0380083468008091
+:10446000AD050038346701008CE2001C308400FF89
+:1044700000A210231840000330C600FF24A2FFFC56
+:10448000ACE2001C30820001504000083C03800870
+:104490008D02003C00A210230441001224040005F8
+:1044A0008C62000410A2000F3C0380088C620004A0
+:1044B00014A2001E000000003C0208008C4200D83C
+:1044C00030420020104000093C0280083462008025
+:1044D000906300089042004C144300043C028008A2
+:1044E000240400040A0010CA0000000034430080C5
+:1044F00034420100A040000C24020001A462001418
+:1045000010C0000A3C0280008C4401003C03800083
+:104510008C6201F80440FFFE24020002AC6401C07A
+:10452000A06201C43C021000AC6201F803E0000884
+:104530000000000027BDFFE800A61823AFBF001051
+:1045400018600080308800FF3C02800834470080FB
+:10455000A0E0002434440100A0E000278C82001C6D
+:1045600000A2102304400056000000008CE2003C32
+:1045700094E3005C8CE4002C004530233063FFFFA3
+:1045800000C318210083202B1080000400E01821B4
+:104590008CE2002C0A00113900A2102194E2005C88
+:1045A0003042FFFF00C2102100A21021AC62001CAB
+:1045B0003C028008344400809482005C8C83001CA0
+:1045C0003042FFFF0002104000A210210043102BD8
+:1045D00010400004000000008C82001C0A00114CF6
+:1045E0003C0680089482005C3042FFFF00021040CD
+:1045F00000A210213C06800834C3010034C70080AB
+:10460000AC82001CA060000CACE500388C62001C81
+:1046100000A210231840000224A2FFFCAC62001C80
+:1046200031020001104000083C0380088CE2003C8D
+:1046300000A2102304410012240400058CC20004CF
+:1046400010A200108FBF00108C62000414A2004F53
+:104650008FBF00103C0208008C4200D8304200207E
+:104660001040000A3C028008346200809063000819
+:104670009042004C144300053C02800824040004CE
+:104680008FBF00100A0010CA27BD001834430080F5
+:1046900034420100A040000C24020001A462001476
+:1046A0003C0280008C4401003C0380008C6201F8D5
+:1046B0000440FFFE240200020A00119900000000DD
+:1046C0008CE2001C004610230043102B54400001D4
+:1046D000ACE5001C94E2005C3042FFFF0062102B4E
+:1046E000144000072402000294E2005C8CE3001CEA
+:1046F0003042FFFF00621821ACE3001C24020002DC
+:10470000ACE500380E000F1FA082000C1040001F07
+:104710008FBF00103C0280008C4401003C038000ED
+:104720008C6201F80440FFFE24020002AC6401C068
+:10473000A06201C43C021000AC6201F80A0011B191
+:104740008FBF001031020010104000108FBF00100A
+:104750003C028008344500808CA3001C94A2005CBD
+:10476000006618233042FFFF006218213C023FFF21
+:104770003444FFFF0083102B5440000100801821B7
+:1047800000C31021ACA2001C8FBF001003E0000882
+:1047900027BD001827BDFFE800C0402100A6302338
+:1047A000AFBF001018C00026308A00FF3C0280080E
+:1047B000344900808D24001C8D23002C0088202388
+:1047C0000064182B1060000F344701008CE20020B9
+:1047D00000461021ACE200208CE200200044102BA7
+:1047E0001440000B3C023FFF8CE2002000441023E9
+:1047F000ACE200209522005C3042FFFF0A0011D19C
+:1048000000822021ACE00020008620213C023FFFF6
+:104810003443FFFF0064102B54400001006020214E
+:104820003C0280083442008000851821AC43001C03
+:10483000A0400024A04000270A0012233C03800867
+:1048400031420010104000433C0380083C068008C1
+:1048500034C400808C82003C004810235840003E45
+:10486000346600809082002424420001A08200244B
+:10487000908200243C0308008C630024304200FF37
+:104880000043102B144000688FBF001034C2010099
+:104890008C42001C00A2102318400063000000009E
+:1048A0008CC300049482005C006818233042FFFF30
+:1048B00000031843000210400043102A1040000576
+:1048C000000000008CC20004004810230A001206F9
+:1048D000000210439482005C3042FFFF000210404F
+:1048E0003C068008AC82002C34C5008094A2005C99
+:1048F0008CA4002C94A3005C3042FFFF0002104007
+:10490000008220213063FFFF008320210104102159
+:10491000ACA2001C8CC2000434C60100ACC2001C56
+:10492000240200020E000F1FA0C2000C1040003E27
+:104930008FBF00103C0280008C4401003C038000CB
+:104940008C6201F80440FFFE240200020A001253A8
+:104950000000000034660080ACC5003834640100FB
+:104960008C82001C00A210231840000224A2FFFC2D
+:10497000AC82001C314200015040000A3C03800818
+:104980008CC2003C00A21023044300142404000540
+:104990008C62000414A200033C0380080A00124544
+:1049A000240400058C62000414A2001F8FBF0010B5
+:1049B0003C0208008C4200D8304200201040000A1F
+:1049C0003C02800834620080906300089042004CF2
+:1049D000144300053C028008240400048FBF00102B
+:1049E0000A0010CA27BD0018344300803442010079
+:1049F000A040000C24020001A46200143C028000CC
+:104A00008C4401003C0380008C6201F80440FFFEEE
+:104A100024020002AC6401C0A06201C43C02100088
+:104A2000AC6201F88FBF001003E0000827BD00183A
+:104A300027BDFFE83C0A8008AFBF00103549008061
+:104A40008D22003C00C04021308400FF004610232E
+:104A50001840009D30E700FF3547010024020001A7
+:104A600000A63023A0E0000CA0E0000DA522001459
+:104A700018C00024308200108D23001C8D22002CD1
+:104A8000006818230043102B1040000F00000000A6
+:104A90008CE2002000461021ACE200208CE20020D5
+:104AA0000043102B1440000B3C023FFF8CE200201F
+:104AB00000431023ACE200209522005C3042FFFF4F
+:104AC0000A00128200621821ACE000200066182162
+:104AD0003C023FFF3446FFFF00C3102B544000014F
+:104AE00000C018213C028008344200800065182173
+:104AF000AC43001CA0400024A04000270A0012D0B4
+:104B00003C038008104000403C0380088D22003C9C
+:104B1000004810235840003D346700809122002453
+:104B200024420001A1220024912200243C03080019
+:104B30008C630024304200FF0043102B1440009A85
+:104B40008FBF00108CE2001C00A2102318400096BA
+:104B5000000000008D4300049522005C00681823CB
+:104B60003042FFFF00031843000210400043102AA8
+:104B700010400005012020218D4200040048102330
+:104B80000A0012B3000210439522005C3042FFFF7E
+:104B9000000210403C068008AC82002C34C5008026
+:104BA00094A2005C8CA4002C94A3005C3042FFFF14
+:104BB00000021040008220213063FFFF0083182193
+:104BC00001031021ACA2001C8CC2000434C60100F9
+:104BD000ACC2001C240200020E000F1FA0C2000C79
+:104BE000104000718FBF00103C0280008C44010017
+:104BF0003C0380008C6201F80440FFFE24020002A6
+:104C00000A0012FA0000000034670080ACE50038AA
+:104C1000346601008CC2001C00A210231840000260
+:104C200024A2FFFCACC2001C3082000150400008EE
+:104C30003C0380088CE2003C00A210230443005196
+:104C4000240400058C62000410A2003E3C0380088E
+:104C50008C62000454A200548FBF00103C02080074
+:104C60008C4200D830420020104000063C028008F0
+:104C700034620080906300089042004C1043004072
+:104C80003C0280083443008034420100A040000C04
+:104C900024020001A46200143C0280008C44010044
+:104CA0003C0380008C6201F80440FFFE24020002F5
+:104CB000AC6401C0A06201C43C021000AC6201F807
+:104CC0000A0013388FBF001024020005A12000271E
+:104CD00014E2000A3C038008354301009062000D95
+:104CE0002C420006504000053C0380089062000DF5
+:104CF00024420001A062000D3C038008346700805C
+:104D0000ACE50038346601008CC2001C00A2102300
+:104D10001840000224A2FFFCACC2001C308200013B
+:104D20005040000A3C0380088CE2003C00A21023A3
+:104D300004410014240400058C62000414A2000342
+:104D40003C0380080A00132F240400058C62000431
+:104D500014A200158FBF00103C0208008C4200D83E
+:104D6000304200201040000A3C028008346200807B
+:104D7000906300089042004C144300053C028008F8
+:104D8000240400048FBF00100A0010CA27BD0018B9
+:104D90003443008034420100A040000C2402000192
+:104DA000A46200148FBF001003E0000827BD0018A4
+:104DB0003C0B800827BDFFE83C028000AFBF00101D
+:104DC00034420100356A00809044000A35690100D0
+:104DD0008C4500148D4800389123000C308400FF6E
+:104DE000010510231C4000B3306700FF2CE20006D1
+:104DF000504000B18FBF00102402000100E23004D7
+:104E000030C200035440000800A8302330C2000C18
+:104E1000144000A130C20030144000A38FBF001026
+:104E20000A0013FC0000000018C0002430820010AB
+:104E30008D43001C8D42002C006818230043102B6A
+:104E40001040000F000000008D22002000461021BD
+:104E5000AD2200208D2200200043102B1440000BB7
+:104E60003C023FFF8D22002000431023AD22002092
+:104E70009542005C3042FFFF0A0013700062182167
+:104E8000AD200020006618213C023FFF3446FFFFA2
+:104E900000C3102B5440000100C018213C028008C0
+:104EA0003442008000651821AC43001CA04000245F
+:104EB000A04000270A0013BE3C03800810400040B9
+:104EC0003C0380088D42003C004810231840003D00
+:104ED000346700809142002424420001A142002452
+:104EE000914200243C0308008C630024304200FF00
+:104EF0000043102B144000708FBF00108D22001C47
+:104F000000A210231840006C000000008D63000414
+:104F10009542005C006818233042FFFF00031843ED
+:104F2000000210400043102A1040000501402021DB
+:104F30008D620004004810230A0013A100021043F0
+:104F40009542005C3042FFFF000210403C068008A2
+:104F5000AC82002C34C5008094A2005C8CA4002C90
+:104F600094A3005C3042FFFF000210400082202129
+:104F70003063FFFF0083182101031021ACA2001C45
+:104F80008CC2000434C60100ACC2001C2402000222
+:104F90000E000F1FA0C2000C104000478FBF001072
+:104FA0003C0280008C4401003C0380008C6201F8CC
+:104FB0000440FFFE240200020A0013EE000000007D
+:104FC00034670080ACE50038346601008CC2001CF8
+:104FD00000A210231840000224A2FFFCACC2001C57
+:104FE000308200015040000A3C0380088CE2003C03
+:104FF00000A2102304430014240400058C62000462
+:1050000014A200033C0380080A0013E024040005F6
+:105010008C62000414A200288FBF00103C0208001C
+:105020008C4200D8304200201040000A3C02800828
+:1050300034620080906300089042004C14430005E5
+:105040003C028008240400048FBF00100A0010CA2C
+:1050500027BD00183443008034420100A040000CFA
+:1050600024020001A46200143C0280008C44010070
+:105070003C0380008C6201F80440FFFE2402000221
+:10508000AC6401C0A06201C43C021000AC6201F833
+:105090000A0013FC8FBF00108FBF001001003021E9
+:1050A0000A00111B27BD0018010030210A00125A06
+:1050B00027BD00188FBF001003E0000827BD0018AF
+:1050C0003C0380083464010024020003A082000C29
+:1050D0008C62000403E00008AC82001C3C058008E0
+:1050E00034A300809062002734A501002406004309
+:1050F00024420001A0620027906300273C020800C0
+:105100008C420048306300FF146200043C076021B9
+:1051100094A500DA0A0008ED30A5FFFF03E00008BF
+:105120000000000027BDFFE8AFBF00103C02800078
+:105130000E0014058C4401803C02800834430100B9
+:10514000A060000C8C4200048FBF001027BD001827
+:1051500003E00008AC62001C27BDFFE03C028008B1
+:10516000AFBF0018AFB10014AFB0001034450080DD
+:10517000344601003C0880008D09014090C3000CBA
+:105180008CA4003C8CA200381482003B306700FFE6
+:105190009502007C90A30027146000093045FFFFB2
+:1051A0002402000554E200083C04800890C2000D6F
+:1051B00024420001A0C2000D0A0014403C048008F3
+:1051C000A0C0000D3C048008348201009042000C15
+:1051D00024030005304200FF1443000A24A205DC2A
+:1051E00034830080906200272C4200075040000565
+:1051F00024A20A0090630027240200140062100415
+:1052000000A210213C108008361000803045FFFFBE
+:10521000012020210E001405A60500149602005C52
+:105220008E0300383C1180003042FFFF0002104026
+:1052300000621821AE03001C0E0003458E240140BD
+:105240009202002534420040A20200250E000350C5
+:105250008E2401408E2401403C0380008C6201F8C2
+:105260000440FFFE24020002AC6401C0A06201C43D
+:105270003C021000AC6201F88FBF00188FB100141F
+:0C5280008FB0001003E0000827BD0020E4
+:04528C008008010095
+:10529000800800808008000000000C8000003200C0
+:1052A0008008024008000EDC08000F3408000F7868
+:1052B00008001010080010508008010080080080CD
+:0452C0008008000062
+:0C52C4000A0000220000000000000000B2
+:1052D0000000000D6370352E302E306A3300000060
+:1052E00005000004000000000000000000000000B5
+:1052F000000000000000000038003C00000000003A
+:10530000000000000000000000000000000000207D
+:10531000000000000000000000000000000000008D
+:10532000000000000000000000000000000000007D
+:105330000000000000000000210038000000000113
+:105340000000002B00000000000000000000000032
+:1053500010000003000000000000000D0000000D20
+:105360003C020800244254243C0308002463564CA9
+:10537000AC4000000043202B1480FFFD24420004B9
+:105380003C1D080037BD9FFC03A0F0213C10080025
+:10539000261000883C1C0800279C54240E0002881C
+:1053A000000000000000000D00A018210080102166
+:1053B000008028213C0460003C07600024060008AF
+:1053C00010600006348420788C420000ACE2200893
+:1053D0008C63000003E00008ACE3200C0A000E2AF6
+:1053E00000000000240300403C02600003E00008CD
+:1053F000AC4320003C0760008F8600008CE52074E1
+:105400000086102100A2182B14600007000028213C
+:105410008F8AFD9824050001A14400138F890000A4
+:1054200001244021AF88000003E0000800A0102103
+:105430008F84FD988F8500009086001330C300FF95
+:1054400000A31023AF82000003E00008A080001337
+:105450008F84FD9827BDFFE8AFB00010AFBF0014E8
+:10546000908900119087001124020028312800FF44
+:105470003906002830E300FF2485002C2CD00001E1
+:10548000106200162484001C0E0000390000000089
+:105490008F8FFD983C0560002402020495EE003ECB
+:1054A00095ED003C000E5C0031ACFFFF016C502517
+:1054B000ACAA20105200000124020004ACA220007B
+:1054C0000000000000000000000000008FBF00147A
+:1054D0008FB0001003E0000827BD00180A0000711B
+:1054E000000028218F85FD9827BDFFD8AFBF002081
+:1054F000AFB3001CAFB20018AFB10014AFB00010D2
+:105500000080982190A4001124B0001C24B1002C2C
+:10551000308300FF386200280E00005B2C5200012F
+:105520000E00006300000000020020211240000273
+:1055300002202821000028210E0000390000000070
+:105540008F8DFD983C0880003C05600095AC003EC6
+:1055500095AB003C02683025000C4C00316AFFFF1F
+:10556000012A3825ACA7201024020202ACA6201480
+:1055700052400001240200028FBF00208FB3001CA4
+:105580008FB200188FB100148FB0001027BD002813
+:1055900003E00008ACA2200027BDFFE0AFB2001876
+:1055A000AFB10014AFB00010AFBF001C3C116000E1
+:1055B0008E2320748F82000030D0FFFF30F2FFFF77
+:1055C0001062000C2406008F0E000039000000005D
+:1055D0003C06801F0010440034C5FF00011238252E
+:1055E00024040002AE27201000003021AE25201434
+:1055F000AE2420008FBF001C8FB200188FB10014A2
+:105600008FB0001000C0102103E0000827BD00206B
+:1056100027BDFFE0AFB0001030D0FFFFAFBF0018D4
+:10562000AFB100140E00003930F1FFFF001024006C
+:10563000009180253C036000AC7020108FBF0018E3
+:105640008FB100148FB0001024020004AC6220005F
+:1056500027BD002003E000080000102127BDFFE85F
+:105660003C0B6018AFBF00108D6F50002418FF7FF7
+:10567000340C807101F8702435CD380C240A0031C7
+:105680003C098000AD6D50003C08800AAD6C53BCF5
+:10569000AD2A00080E00049BAF88002C0E000459B0
+:1056A000000000000E000048000000003C07600001
+:1056B0008CE508082406FFF03C03570900A62024C7
+:1056C0003462F0001082005024190001AF800034D1
+:1056D0000E000BBC000000003C0660168CC40000ED
+:1056E0003C0760148CE500A03C03FFFF00831024FE
+:1056F0003C1F535300051FC2105F003D34C57C00A2
+:1057000094A201F2A780004C10400003A780005C27
+:10571000384B1E1EA78B004C94A201F810400004C9
+:105720008F8D0034384C1E1EA78C005C8F8D00348A
+:1057300011A000049784005C240E0020A78E004C6A
+:105740009784005C2C8F008151E0000124040080CC
+:105750009785004C2CB80401530000012405040077
+:105760003C0260008C4304382419103C307FFFFF5A
+:1057700013F900033087FFFF50E0000F24060050AC
+:10578000A380005E9388005E51000010A784005C37
+:10579000A780005C9785005C8FBF0010A780004C3D
+:1057A000A7800054A78000723C010800AC2500804F
+:1057B00003E0000827BD0018A386005E9388005E02
+:1057C0005500FFF4A780005CA784005CA785004C0F
+:1057D0008FBF00109785005CA7800054A7800072DF
+:1057E0003C010800AC25008003E0000827BD00183C
+:1057F00000035080014648218D2800043C066000CB
+:105800000A00010F010628210A000103AF990034A4
+:105810003083FFFF8F88002C8F87002800032140F2
+:105820003C0580003C020050008248253C06600098
+:105830003C0A010034AC04008CCD08E001AA5824D5
+:1058400011600005000000008CCF08E024E7000193
+:1058500001EA7025ACCE08E08D19001001805821B6
+:10586000ACB900388D180014ACB8003CACA90030BD
+:105870000000000000000000000000000000000028
+:105880000000000000000000000000000000000018
+:105890003C0380008C640000308200201040FFFD3B
+:1058A0003C0F60008DED08E03C0E010001AE1824B5
+:1058B0001460FFE100000000AF87002803E000084B
+:1058C000AF8B00388F85002C240BFFF03C06800046
+:1058D00094A7001A8CA9002430ECFFFF000C38C0FC
+:1058E00000EB5024012A4021ACC8003C8CA40024C9
+:1058F0008CC3003C008310231840003300000000DC
+:105900008CAD002025A200013C0F0050ACC2003835
+:1059100035EE00103C068000ACCE003000000000E8
+:105920000000000000000000000000000000000077
+:105930000000000000000000000000003C048000A7
+:105940008C990000333800201300FFFD30E200087E
+:10595000104000173C0980008C880408ACA8001097
+:105960008C83040CACA300143C1900203C1880006C
+:10597000AF19003094AE001894AF001C01CF302155
+:10598000A4A6001894AD001A25A70001A4A7001A28
+:1059900094AB001A94AC001E118B000300000000B1
+:1059A00003E000080000000003E00008A4A0001AC3
+:1059B0008D2A0400ACAA00108D240404ACA40014A9
+:1059C0000A0001AA3C1900208CA200200A000192C2
+:1059D0003C0F00500A0001800000000027BDFFE8D6
+:1059E000AFBF00100E0001C4000000008F89002C22
+:1059F0008FBF00103C038000A520000A9528000AF4
+:105A00009527000427BD00183105FFFF30E6000F81
+:105A10000006150000A2202503E00008AC64008009
+:105A20003C0508008CA500208F83000427BDFFE8FB
+:105A3000AFB00010AFBF001410A300100000802111
+:105A4000240400010204300400A6202400C3102412
+:105A50005044000626100001001018802787FD9C86
+:105A60001480000A00671821261000012E09000288
+:105A70005520FFF38F830004AF8500048FBF00140F
+:105A80008FB0001003E0000827BD00188C680000EC
+:105A90003C058000ACA800240E0001C626100001C1
+:105AA0003C0508008CA500200A0001EB2E0900022D
+:105AB00024050001008518043C0408008C840020A3
+:105AC00027BDFFC8AFBF003400831024AFBE003035
+:105AD000AFB7002CAFB60028AFB50024AFB400209C
+:105AE000AFB3001CAFB20018AFB1001410400051AA
+:105AF000AFB000108F84002C948700069488000AB1
+:105B000000E8302330D5FFFF12A0004B8FBF0034D8
+:105B1000948B0018948C000A016C50233142FFFFD3
+:105B200002A2482B1520000202A0202100402021C3
+:105B30002C8F000515E0000200809821241300043A
+:105B40000E000153026020218F87002C02609021FB
+:105B5000AF80003094F4000A026080211260004E91
+:105B60003291FFFF3C1670003C1440003C1E2000A8
+:105B70003C1760008F9900388F38000003161824F6
+:105B80001074004F0283F82B17E00036000000006D
+:105B9000107E00478F86003014C0003A24030001B5
+:105BA00002031023022320213050FFFF1600FFF1D3
+:105BB0003091FFFF8F87002C3C1100203C108000AB
+:105BC000AE11003094EB000A3C178000024B5021CC
+:105BD000A4EA000A94E9000A94E800043123FFFFD4
+:105BE0003106000F00062D000065F025AEFE008096
+:105BF00094F3000A94F6001812D3003600122140E4
+:105C00008CFF00148CF4001003E468210000C02114
+:105C100001A4782B0298702101CF6021ACED001413
+:105C2000ACEC001002B2382330F5FFFF16A0FFB82D
+:105C30008F84002C8FBF00348FBE00308FB7002CB4
+:105C40008FB600288FB500248FB400208FB3001CBE
+:105C50008FB200188FB100148FB0001003E000085D
+:105C600027BD00381477FFCC8F8600300E000D8BD7
+:105C700002002021004018218F86003010C0FFC98B
+:105C800002031023027070238F87002C01C3682148
+:105C90000A00027631B2FFFF8F86003014C0FFC9C0
+:105CA0003C1100203C1080000A000240AE11003080
+:105CB0000E0003C4020020210A00026D00401821DA
+:105CC000020020210E0007DB022028210A00026DBD
+:105CD000004018210E000180000000000A00025957
+:105CE00002B2382327BDFFD8AFB40020AFB3001CE9
+:105CF000AFB20018AFB10014AFB00010AFBF0024B6
+:105D00000E0000E6241300013C0280083C03200042
+:105D10003C010800AC200070345400803472000351
+:105D20003C1080002411FF800E0001D7000000000D
+:105D30008E06000038C5000130A400011480FFFA6F
+:105D4000000000008E07010024030C0010E300098E
+:105D50003C0580008E0901002D2830805500001080
+:105D60003C0480008E0B01002D6A31811140000C33
+:105D70003C0480008CAC0100118300040000202151
+:105D80008CAE010025CDFF8131A400FF8E0F0100F4
+:105D90000E0001FBAE0F00240A0002C13C0480008B
+:105DA0008C9F010024180020AC9F002092990000D5
+:105DB000332300FF1078001F2402005010620022DD
+:105DC000000000003C0480008C830100146000038C
+:105DD00000000000566000143C0440008C8201006A
+:105DE0008C990100000098210051F824001F79408F
+:105DF0003338007F01F8702501D26825AC8D08305A
+:105E00008C8C01008C890100258B010001715024CC
+:105E1000000A39403128007F00E8302500D22825CB
+:105E2000AC8508303C044000AE0401380A000299F9
+:105E3000000000008C8501000E00078D2404008006
+:105E40000A0002C13C0480008C8401000E0013EAA9
+:105E5000000000000A0002C13C04800000A4102BD6
+:105E600024030001104000090000302100052840F3
+:105E700000A4102B04A00003000318405440FFFCB2
+:105E8000000528405060000A0004182B0085382BBC
+:105E900054E000040003184200C33025008520238D
+:105EA000000318421460FFF9000528420004182B73
+:105EB00003E0000800C310213084FFFF30C600FF5C
+:105EC0003C0780008CE201B80440FFFE00064C0055
+:105ED000012430253C08200000C820253C03100088
+:105EE000ACE00180ACE50184ACE4018803E000088B
+:105EF000ACE301B83C0660008CC5201C2402FFF016
+:105F000030830200308601001060000E00A22824B9
+:105F100034A500013087300010E0000530830C000C
+:105F200034A500043C04600003E00008AC85201C9C
+:105F30001060FFFD3C04600034A5000803E0000889
+:105F4000AC85201C54C0FFF334A500020A000315E1
+:105F50003087300027BDFFE8AFB00010AFBF00149E
+:105F60003C076000240600021080001100A0802180
+:105F70008F8300380E00030C8C6400188F82003869
+:105F800000002021240600018C45000C0E0002FDBB
+:105F9000000000001600000224020003000010218F
+:105FA0008FBF00148FB0001003E0000827BD001859
+:105FB0008CE8201C2409FFF001092824ACE5201CF2
+:105FC0008F8700380A0003328CE5000C3C02600E1B
+:105FD0000080402134460100240900180000000020
+:105FE00000000000000000003C0A00503C0380005C
+:105FF00035470200AC68003834640400AC65003CEE
+:10600000AC6700308C6C0000318B00201160FFFD0C
+:106010002407FFFF2403007F8C8D00002463FFFF13
+:1060200024840004ACCD00001467FFFB24C60004E8
+:1060300000000000000000000000000024A4020096
+:106040000085282B3C0300203C0E80002529FFFF03
+:1060500001054021ADC300301520FFE0008028215C
+:1060600003E00008000000008F82003827BDFFD841
+:10607000AFB3001CAFBF0020AFB20018AFB1001427
+:10608000AFB0001094460002008098218C52001896
+:106090002CC300818C4800048C4700088C51000CF4
+:1060A0008C490010106000078C4A00142CC40004B6
+:1060B0001480001330EB000730C5000310A000105F
+:1060C000000000002410008B020020210220282163
+:1060D0000E0002FD240600031660000224020003E5
+:1060E000000010218FBF00208FB3001C8FB200185A
+:1060F0008FB100148FB0001003E0000827BD002806
+:106100001560FFF12410008B3C0C80003C03002044
+:10611000241F0001AD830030AF9F0030000000005D
+:1061200000000000000000002419FFF024D8000F38
+:10613000031978243C1000D0AD88003801F0702598
+:1061400024CD00033C08600EAD87003C358504007B
+:10615000AD8E0030000D38823504003C3C038000D9
+:106160008C6B0000316200201040FFFD0000000039
+:1061700010E0000824E3FFFF2407FFFF8CA80000C5
+:106180002463FFFF24A50004AC8800001467FFFB14
+:10619000248400043C04600EAC860038000000003B
+:1061A00000000000000000003C0700203C068000CA
+:1061B0000120202101402821ACC700300E000342FD
+:1061C000000080210E00030C024020210A000382FF
+:1061D0000200202127BDFFE0AFB200183092FFFF80
+:1061E000AFB10014AFBF001CAFB000101640000DDF
+:1061F000000088210A0003F1022010212405000379
+:10620000508500278CE5000C0000000D262C0001B5
+:106210003191FFFF24EB00200232502B1140001976
+:10622000AF8B00388F820030144000168F87003803
+:106230003C0670003C0320008CE5000000A62024F2
+:10624000148300108F840040000544023C09800044
+:1062500000A980241480FFE9310600FF2CCA000B3E
+:106260001140FFEB262C0001000668803C0E080060
+:1062700025CE51C801AE60218D8B00000160000861
+:1062800000000000022010218FBF001C8FB20018F8
+:106290008FB100148FB0001003E0000827BD00206C
+:1062A0000E0002FD240400841600FFD88F870038FA
+:1062B0000A0003D2AF800040020028210E00032410
+:1062C000240400018F8700380A0003D2AF82004007
+:1062D000020028210E000324000020210A000401EE
+:1062E0008F8700380E000369020020218F87003855
+:1062F0000A0003D2AF82004030AFFFFF000F19C089
+:106300003C0480008C9001B80600FFFE3C1920047C
+:106310003C181000AC830180AC800184AC990188EA
+:10632000AC9801B80A0003D3262C000190E20002C9
+:1063300090FF00030000202100023A0000FF282502
+:10634000240600080E0002FD000000001600FFDD1C
+:10635000240200038F870038000010210A0003D2B6
+:10636000AF82004090E50002000020210A000420D6
+:106370002406000994E5000490E9000390E300027C
+:10638000000534000009420000C8202500832825AC
+:106390002406000A0A0004200000202190E50002E3
+:1063A000000020210A0004202406000B000449C23A
+:1063B0003127003F000443423C0280000008204097
+:1063C000240316802CE60020AC43002C24EAFFE0D6
+:1063D0002482000114C0000330A900FF00801021B6
+:1063E000314700FF000260803C0D8000240A00015C
+:1063F000018D20213C0B000E00EA2804008B302187
+:1064000011200005000538278CCE000001C5382575
+:1064100003E00008ACC700008CD800000307782414
+:1064200003E00008ACCF000027BDFFE0AFB10014CF
+:10643000AFB00010AFBF00183C0760008CE4080844
+:106440003402F0003C1160003083F000240501C0EC
+:106450003C04800E00003021106200062410000170
+:106460008CEA08083149F0003928E0000008382B90
+:10647000000780403C0D0200AE2D0814240C16804D
+:106480003C0B80008E2744000E000E34AD6C002CB7
+:10649000120000043C0216912405000112050010B0
+:1064A0003C023D6C345800E0AE3844083C11080012
+:1064B0008E31007C8FBF00183C06600000118540C3
+:1064C000360F16808FB100148FB000103C0E020002
+:1064D00027BD0020ACCF442003E00008ACCE08105C
+:1064E0003C0218DA345800E0AE3844083C11080089
+:1064F0008E31007C8FBF00183C0660000011854083
+:10650000360F16808FB100148FB000103C0E0200C1
+:1065100027BD0020ACCF442003E00008ACCE08101B
+:106520000A00043A240500010A00043A0000282168
+:1065300024020400A7820010A78000080000202188
+:106540003C06080024C654B02405FFFF248900013E
+:10655000000440803124FFFF010618212C87002011
+:1065600014E0FFFAAC65000024040400A7840012C4
+:10657000A780000A000020213C06080024C65530F0
+:106580002405FFFF248D00010004608031A4FFFF7B
+:10659000018658212C8A00201540FFFAAD650000C5
+:1065A000A7800014A780000CA780000E0000202107
+:1065B0003C06080024C655B02405FFFF24990001BD
+:1065C0000004C0803324FFFF030678212C8E0004D2
+:1065D00015C0FFFAADE500003C0560008CA73D004A
+:1065E0002403E08F00E310243446014003E0000858
+:1065F000ACA63D002487007F000731C224C5FFFF01
+:10660000000518C2246400013082FFFF000238C078
+:10661000A784001C3C010800AC270030AF800018A4
+:1066200000002821000020210000302124890001E1
+:1066300000A728213124FFFF2CA817011100000317
+:106640002C8300801460FFF924C6000100C02821BB
+:10665000AF86001810C0001DA786001624CAFFFFD1
+:10666000000A11423C080800250855B01040000AF5
+:1066700000002021004030212407FFFF248E00016C
+:106680000004688031C4FFFF01A860210086582BF8
+:106690001560FFFAAD87000030A2001F50400008CF
+:1066A00000043080240300010043C804000410806B
+:1066B000004878212738FFFF03E00008ADF800000C
+:1066C00000C820212405FFFFAC85000003E000087E
+:1066D0000000000030A5FFFF30C6FFFF30A8001FFC
+:1066E0000080602130E700FF0005294200005021B2
+:1066F00010C0001D24090001240B00012518000111
+:10670000010B2004330800FF01267826390E0020F3
+:106710002DED00012DC2000101A218251060000D11
+:10672000014450250005C880032C40210100182198
+:1067300010E0000F000A20278D040000008A1825B1
+:10674000AD03000024AD00010000402100005021F5
+:1067500031A5FFFF252E000131C9FFFF00C9102B15
+:106760001040FFE72518000103E0000800000000CA
+:106770008D0A0000014440240A000520AC68000096
+:1067800027BDFFE830A5FFFF30C6FFFFAFB0001008
+:10679000AFBF001430E7FFFF000050213410FFFFAF
+:1067A0000000602124AF001F00C048212418000110
+:1067B0002419002005E0001601E010210002F94331
+:1067C000019F682A0009702B01AE402411000017B8
+:1067D000000C18800064102110E000058C4B0000B4
+:1067E00000F84004000838230167582400003821CD
+:1067F0001540004100004021556000163169FFFF3F
+:10680000258B0001316CFFFF05E1FFEC01E0102159
+:1068100024A2003E0002F943019F682A0009702B60
+:1068200001AE40241500FFEB000C18801546000552
+:106830003402FFFF020028210E0005040000382169
+:10684000020010218FBF00148FB0001003E0000879
+:1068500027BD00181520000301601821000B1C0241
+:1068600024080010306A00FF15400005306E000F4C
+:10687000250D000800031A0231A800FF306E000F3A
+:1068800015C00005307F0003251000040003190225
+:10689000320800FF307F000317E00005386900016F
+:1068A0002502000200031882304800FF3869000109
+:1068B0003123000110600004310300FF250A0001AC
+:1068C000314800FF310300FF000C694001A3402163
+:1068D000240A000110CAFFD53110FFFF246E000109
+:1068E00031C800FF1119FFC638C900012D1F002053
+:1068F00053E0001C258B0001240D00010A000597C0
+:10690000240E002051460017258B000125090001A7
+:10691000312800FF2D09002051200012258B000195
+:1069200025430001010D5004014B102425090001ED
+:106930001440FFF4306AFFFF3127FFFF10EE000C18
+:106940002582FFFF304CFFFF000050213410FFFF75
+:10695000312800FF2D0900205520FFF225430001BA
+:10696000258B0001014648260A000551316CFFFFC6
+:1069700000003821000050210A0005A33410FFFF59
+:1069800027BDFFD8AFB0001030F0FFFFAFB100144B
+:10699000001039423211FFE000071080AFB3001C35
+:1069A00000B1282330D3FFFFAFB2001830A5FFFF9E
+:1069B000008090210260302100442021AFBF0020E0
+:1069C0000E00052F3207001F022288213403FFFF2B
+:1069D00002402021020028210260302100003821DD
+:1069E000104300093231FFFF022010218FBF002029
+:1069F0008FB3001C8FB200188FB100148FB000103D
+:106A000003E0000827BD00280E00052F000000004D
+:106A100000408821022010218FBF00208FB3001C6E
+:106A20008FB200188FB100148FB0001003E000087F
+:106A300027BD0028000424003C036000AC603D0832
+:106A400010A00002348210063482101603E0000801
+:106A5000AC623D0427BDFFE0AFB00010309000FFF6
+:106A60002E020006AFBF001810400008AFB100149E
+:106A7000001030803C030800246351F400C3282137
+:106A80008CA400000080000800000000000020210D
+:106A90008FBF00188FB100148FB00010008010213C
+:106AA00003E0000827BD0020979100161620005132
+:106AB000000020213C020800904200330A00060A30
+:106AC00000000000978D001215A000310000202169
+:106AD0000A00060A240200089787001014E0001A32
+:106AE0000000182100602021240200011080FFE92D
+:106AF0008FBF0018000429C20045302100A6582B82
+:106B00001160FFE43C0880003C072000000569C0DC
+:106B100001A76025AD0C00203C0380082402001F63
+:106B20002442FFFFAC6000000441FFFD2463000429
+:106B300024A5000100A6702B15C0FFF5000569C053
+:106B40000A0005F48FBF0018978700083C0408006E
+:106B5000248454B0240504000E0005AF240600016F
+:106B6000978B001024440001308AFFFF2569FFFF46
+:106B70002D4804000040282115000040A78900107E
+:106B800024AC3800000C19C00A000608A7800008D1
+:106B90009787000A3C04080024845530240504002B
+:106BA0000E0005AF2406000197990012244400014D
+:106BB0003098FFFF272FFFFF2F0E04000040882191
+:106BC00015C0002CA78F0012A780000A3A0200030C
+:106BD000262401003084FFFF0E0005DC2C45000157
+:106BE0000011F8C027F00100001021C00A00060AB9
+:106BF000240200089785001A9787000E3C040800BD
+:106C0000248455B00E0005AF2406000197870016B6
+:106C10008F8900182445000130A8FFFF24E3FFFFFF
+:106C20000109302B0040802114C00018A7830016F2
+:106C3000A780000E9785001C0E000E1E020020216A
+:106C4000244A05003144FFFF0E0005DC2405000145
+:106C50003C05080094A500320E000E1E0200202103
+:106C6000244521003C020800904200330A00060A35
+:106C7000000521C00A000642A784000A24AC38009F
+:106C8000000C19C00A000608A78400080A00065C68
+:106C9000A785000E308400FF27BDFFE82C82000688
+:106CA000AFBF0014AFB000101040001500A0382195
+:106CB000000440803C0308002463520C0103282197
+:106CC0008CA40000008000080000000024CC007F9D
+:106CD000000751C2000C59C23170FFFF2547C400A4
+:106CE00030E5FFFF27840008020030210E00050474
+:106CF000240700019786001402062021A7840014AF
+:106D00008FBF00148FB0001003E0000827BD0018EB
+:106D10003C0508008CA50030000779C20E0002E691
+:106D200025E4DF003045FFFF3C040800248455B013
+:106D3000240600010E00050424070001978E0016AA
+:106D40008FBF00148FB0001025CD000127BD0018A3
+:106D500003E00008A78D00160007C9C22738FF000E
+:106D6000001878C231F0FFFF3C040800248455303D
+:106D700002002821240600010E000504240700015A
+:106D8000978D0012260E0100000E840025AC000134
+:106D90003C0B6000A78C0012AD603D083604000675
+:106DA000000030213C0760008CE23D04305F0006AB
+:106DB00017E0FFFD24C9000100061B00312600FF7B
+:106DC000006440252CC50004ACE83D0414A0FFF687
+:106DD0008FBF00148FB0001003E0000827BD00181B
+:106DE000000751C22549C8002406000124070001FC
+:106DF0003C040800248454B00E0005043125FFFF34
+:106E0000978700108FBF00148FB0001024E6000198
+:106E100027BD001803E00008A78600103084FFFF9C
+:106E200030A5FFFF3C0680008CC201B80440FFFE85
+:106E30003C084080008838253C031000ACC001802D
+:106E4000ACC50184ACC7018803E00008ACC301B83D
+:106E50003084FFFF3C0680008CC201B80440FFFE76
+:106E60003C0840388CA70000008828253C0310000F
+:106E7000ACC70180ACC5018803E00008ACC301B811
+:106E80008F8300588F8600501066000B00804021D1
+:106E90003C07080024E755C0000328C000A71021C4
+:106EA0008C44000024630001108800053063000F4B
+:106EB0005466FFFA000328C003E000080000102118
+:106EC0003C07080024E755C400A7302103E0000870
+:106ED0008CC200003C039000346200010082202537
+:106EE0003C038000AC6400208C65002004A0FFFE01
+:106EF0000000000003E00008000000003C028000E9
+:106F0000344300010083202503E00008AC44002046
+:106F100027BDFFE0AFB100143091FFFFAFB000100C
+:106F2000AFBF00181220001200A080218CA5000025
+:106F300014A00011240400023C0680008CC201B899
+:106F40000440FFFE3C074000022720258FBF0018A9
+:106F50008FB100148FB000103C03100027BD00203B
+:106F6000ACC50180ACC4018803E00008ACC301B823
+:106F70000A00071D8CA500000E00067424060200FE
+:106F8000000028210A00071DAE0000003087FFFF27
+:106F90003C0680008CC201B80440FFFE3C0A40065B
+:106FA0008CA9000000EA4025ACC901808CA4000433
+:106FB0003C031000ACC40184ACC8018803E00008A5
+:106FC000ACC301B88F83FD9427BDFFE8AFBF0014A9
+:106FD000AFB00010906700080080102100802821C9
+:106FE00030E600400000202110C000088C50000056
+:106FF0000E00008802002021020020218FBF001413
+:107000008FB000100A00049727BD00180E00073249
+:10701000000000000E000088020020210200202154
+:107020008FBF00148FB000100A00049727BD00180E
+:1070300027BDFFE0AFB000108F90FD94AFBF001CE4
+:10704000AFB20018AFB10014920600010080882191
+:107050000E00070430D2000492040005001129C27A
+:10706000A605000034830040A20300050E00070EB1
+:10707000022020210E000499022020212402000178
+:10708000AE02000C02202821A602001024040002F7
+:10709000A602001224060200A60200140E000674C6
+:1070A000A60200161640000F8FBF001C978C0054DC
+:1070B0003C0B08008D6B00782588FFFF3109FFFF2E
+:1070C000256A0001012A382B10E00006A788005429
+:1070D0003C0F6006240E001635ED0010ADAE0050DA
+:1070E0008FBF001C8FB200188FB100148FB000103A
+:1070F00003E0000827BD002027BDFFE0AFB100146A
+:10710000AFBF0018AFB000101080000400A08821AD
+:107110002402008010820007000000000000000D23
+:107120008FBF00188FB100148FB0001003E000086B
+:1071300027BD00200E00070400A020218F86FD94AB
+:107140000220202190C500050E00070E30B000FF80
+:107150002403003E1603FFF1000000003C05800000
+:107160008CA401780480FFFE240800073C0710006F
+:10717000ACB1014002202021A0A801448FBF00181B
+:107180008FB100148FB00010ACA701780A00075B24
+:1071900027BD002027BDFFE0AFB00010AFBF001833
+:1071A000AFB100143C1080008E11002000000000E0
+:1071B0000E000499AE040020AE1100208FBF00180D
+:1071C0008FB100148FB0001003E0000827BD00202D
+:1071D0003084FFFF3C0680008CC201B80440FFFEF3
+:1071E0003C084035008838253C031000ACC50180C0
+:1071F000ACC00184ACC7018803E00008ACC301B88F
+:107200003084FFFF3C0680008CC201B80440FFFEC2
+:107210003C084036008838253C031000ACC501808E
+:10722000ACC00184ACC7018803E00008ACC301B85E
+:1072300027BDFFD0AFB500243095FFFFAFB60028C3
+:10724000AFB40020AFBF002CAFB3001CAFB200182A
+:10725000AFB10014AFB0001030B6FFFF12A000278E
+:107260000000A0218F9200388E4300003C06800071
+:107270002402004000033E0200032C0230E4007FA1
+:10728000006698241482001D30A500FF8F830048FB
+:107290002C68000A510000108F86003000035880CF
+:1072A0003C0C0800258C5228016C50218D490000AF
+:1072B000012000080000000002D4702131C5FFFF4A
+:1072C0000E0006D624040084166000028F92003857
+:1072D000AF8000488F860030264F002026890001AD
+:1072E00001E090213134FFFF14C00004AF8F00385B
+:1072F0000295282B14A0FFDC000000000280102162
+:107300008FBF002C8FB600288FB500248FB40020CB
+:107310008FB3001C8FB200188FB100148FB0001013
+:1073200003E0000827BD00302407003414A70146FD
+:10733000000000009247000E8F98FD988F90FD94FA
+:10734000240F1600A30700199244000D3C0880008A
+:107350003C07800CA3040018965F00123C096000F3
+:107360003C117FFFA61F005C965900103622FFFFDC
+:10737000240400053325FFFFAE0500548E46001C93
+:10738000AD0F00288CEE00008D2D444801C6182654
+:1073900001A33021AE0600388E0C003824CA00014B
+:1073A0003C0D7F00AE0C003C8E0B003CAF0B00048C
+:1073B000AE0A00208E130020AE13001CA300001B99
+:1073C000AE02002CA30400128E5F001424130050A0
+:1073D000AE1F00348E190034AF1900148E4500180A
+:1073E000AE050048924F000CA20F004E9209000813
+:1073F000352E0020A20E00088E030018006D6024B8
+:10740000358B4000AE0B0018920A0000315200FF8D
+:10741000125302A62413FF803C0408002484564023
+:107420000E00074000000000240C000424080001A6
+:107430003C0508008CA556403C048000A20C0025A9
+:10744000A20800058C9001780600FFFE8F9200389C
+:10745000240D00023C031000AC850140A08D0144C6
+:10746000AC8301780A000804AF8000482CAD0037D7
+:1074700011A0FF998F860030000580803C11080024
+:1074800026315250021178218DEE000001C0000813
+:10749000000000002410000414B0008E3C0780009F
+:1074A0003C0B08008D6B56408F86FD94ACEB0020A2
+:1074B0008E4300088F8FFD98240E0050ACC300301F
+:1074C0008E4A0008ACCA00508E42000CACC2003498
+:1074D0008E440010ACC400388E5F0010ACDF005446
+:1074E0008E590014ACD9003C8E580018ADF8000439
+:1074F0008E51001CACD1002090C5000030A900FFC7
+:10750000112E0276000000008CC500348CD10030B2
+:1075100000B1302304C000F32404008C126000F09A
+:10752000240200030A000804AF820048240F00056B
+:1075300014AF00683C0B80003C0308008C6356408D
+:107540008F86FD94AD6300208E4A00048F99FD98CC
+:1075500024072000ACCA001C924200082412000834
+:10756000A32200198F840038909F0009A33F0018C0
+:107570008F85003890B8000A330400FF1092001085
+:10758000288C0009158000BC24080002240E00206D
+:10759000108E000B34078000288900211520000878
+:1075A0002407400024110040109100053C07000111
+:1075B000240F0080108F00023C07000224074000C7
+:1075C0008CDF00183C04FF0003E4C8240327C02517
+:1075D000ACD8001890B2000BA0D200278F830038DF
+:1075E0009465000C10A0022A000000009467000CB3
+:1075F0003C198000240BFFBFA4C7005C9062000E02
+:1076000024070004A0C200088F840038909F000F58
+:10761000A0DF00098F8C00388D9200108F38007425
+:1076200002582823ACC500588D8F0014ACCF002C15
+:10763000959100183229FFFFACC90040958E001AC1
+:1076400031D0FFFFACD000448D8D001CACCD004884
+:1076500095880002A4C800789183000EA0C300089A
+:1076600090CA0008014B1024126001D4A0C2000887
+:107670008F9200380A000804AF87004824060006ED
+:1076800014A600143C0D80003C1008008E105640DB
+:107690008F8CFD90ADB000208E4800188F86FD9431
+:1076A0008F8AFD98AD8800008CC300382404000543
+:1076B000AD8300048CCB003C12600081AD4B000018
+:1076C0000A000804AF840048240E000710AE004BE7
+:1076D000240400063C05080024A556400E000713AC
+:1076E000240400818F9200380013102B0A00080434
+:1076F000AF8200482419002314B9FFF63C0B800028
+:107700003C0C08008D8C56408F8AFD98AD6C002093
+:107710008F91FD948E4600042544002026450014D8
+:10772000AE260028240600030E000E2A2550003045
+:107730008F87003802002021240600030E000E2A45
+:1077400024E500083C040800248456400E0007404D
+:107750000000000092220000241F0050304400FF6F
+:10776000549FFFE18F9200380E000E1500000000BC
+:107770000A0009098F9200382403003314A3003251
+:107780003C0280003C1108008E3156408F8EFD98DF
+:10779000AC5100208E440008240900288F88FD94F5
+:1077A000ADC400308E5F000C24060009ADDF00344C
+:1077B0008E590010ADD900388E580014ADD8002075
+:1077C0008E450018ADC500248E4F001CADCF00289B
+:1077D000A1C900118E4D000412600031AD0D0028CA
+:1077E0008F9200380A000804AF860048240900225E
+:1077F00014A9FFB800000000240400073C0F080093
+:107800008DEF56403C118000AE2F00205660FEB137
+:10781000AF8400483C040800248456400E00074012
+:10782000241300508F98FD9493120000324500FFFE
+:1078300010B30169000000008F9200380000202181
+:107840000A000804AF8400483C05080024A55640FF
+:107850000E0006E3240400810A0009098F92003813
+:1078600002D498213265FFFF0E0006D6240400845E
+:107870000A0008048F9200381088FF512407040082
+:107880002887000310E001A324100004240D000148
+:10789000548DFF4B240740000A0008BF2407010055
+:1078A0003C05080024A556400E000732240400823F
+:1078B0008F920038000030210A000804AF8600488B
+:1078C0003C040800248456408CC200380E00074057
+:1078D0008CC3003C8F9200380A00095F0000202111
+:1078E000240400823C05080024A556400E000732FF
+:1078F000000000008F920038000010210A000804E8
+:10790000AF8200488E5000048F91FD943C0A8000A5
+:10791000AD500020922200050200282130460002CE
+:1079200014C001802404008A8F92FD98020028214F
+:107930002404008D924B001B3163002014600179F8
+:1079400000000000922D0009240C001231A800FF55
+:10795000110C0174240400810E0007040200202190
+:107960009245001B240E00040200202134A900428D
+:10797000A249001B0E00070EA22E00253C04800029
+:107980008C9101780620FFFE24180002AC90014083
+:10799000A09801448F9200383C0F1000AC8F017802
+:1079A0000A00090A0013102B8E5000048F91FD94D9
+:1079B0003C1F8000AFF00020923900050200282112
+:1079C0003327000214E000172404008A92240009DF
+:1079D0002412000402002821308600FF10D200117A
+:1079E000240400810E000704020020218F8CFD98E2
+:1079F000240B00122403FFFE918D001B02002021A6
+:107A000035A80020A188001BA22B0009922A00059E
+:107A1000014310240E00070EA222000502002821B7
+:107A2000000020210E0007CF000000000A00090915
+:107A30008F9200388E5100043C0280003C100800F8
+:107A400026105640AC5100203C010800AC31564095
+:107A50009246000330C40004108001658F84FD94B9
+:107A600024020006A0820009924D001B2408FFC0DA
+:107A700031AC003F01885825A08B000892430003D9
+:107A8000306A00011540015C000000008E420008D1
+:107A9000AE0200083C0208008C4256481040015BD0
+:107AA0008F8EFD98000281C28F85FD94A5D0000CB9
+:107AB0008E5F000C240F000124090014ADDF002CA0
+:107AC0008E590010ADD9001C96470016A5C7003C82
+:107AD00096580014A5D8003EACAF000CA4AF00101F
+:107AE000A4AF0012A4AF0014A4AF00161260015F8F
+:107AF000A1C9001192440003309200022E530001EC
+:107B00008F920038266200080A000804AF820048FD
+:107B10008E4600043C0580003C048008ACA6002092
+:107B20008E4700089089000024110050312200FF88
+:107B3000105100B8240500883C0480008C8F01B8E7
+:107B400005E0FFFE0013802B3C18400900B810250B
+:107B5000AF9000483C101000AC860180AC870184D7
+:107B6000AC820188AC9001B80A0008058F8600300D
+:107B70008E4500043C0680003C098008ACC500200E
+:107B8000913F00002404005033F900FF132400B09B
+:107B9000240600883C0480008C8A01B80540FFFE62
+:107BA0003C0E400E00CE68253C081000AC850180DC
+:107BB000AC800184AC8D0188AC8801B8912B0000A9
+:107BC000240CFF8024040004016C182524060030D6
+:107BD0000E000674A12300000A0009098F920038E4
+:107BE0008E5000048F91FD983C0F8000ADF0002076
+:107BF0009225001B30A900101120007C2403008175
+:107C00003C0480008C8701B804E0FFFE3C1F401F4D
+:107C1000AC900180007F10250013C82B3C10100091
+:107C2000AC800184AF990048AC820188AC9001B867
+:107C30000A0008058F8600308E44001C0E0006EFF7
+:107C400000000000104000F8004038218F920038FA
+:107C5000240600893C0580008CAE01B805C0FFFEFB
+:107C600000000000ACA701808E50001C3C114001B8
+:107C70000013782B00D138253C131000ACB00184E0
+:107C8000AF8F0048ACA70188ACB301B80A00080563
+:107C90008F860030965900023C100800261056408E
+:107CA00033380004130000A33C0460008E5F001C06
+:107CB0003C068000ACDF00203C010800AC3F564091
+:107CC000964F000231E7000114E000E300000000DD
+:107CD0008E420004AE0200083C1008008E10564888
+:107CE000120000D93C0680008F85FD94241000010D
+:107CF0008CBF00188F91FD988F89FD9003E6C825F1
+:107D0000ACB90018A0A00005ACB0000C3C180800ED
+:107D10008F1856488F870038A4B00010001879C219
+:107D2000A4B00012A4B00014A4B00016A62F000C3A
+:107D30008CEE00088F8D00388F8C0038AE2E002C12
+:107D40008DA8000C24070002AE28001C918B0010A7
+:107D5000A22B00118F830038906A0011A12A00081D
+:107D60008F82003890440012A0A4004E8F920038F9
+:107D700092460013A22600128F920038965F0014DC
+:107D8000A63F003C96590016A639003E8E580018B2
+:107D9000AE3800145660FD4FAF8700483C05080020
+:107DA00024A556400E000713000020218F920038B2
+:107DB000000038210A000804AF8700483C0508008D
+:107DC00024A556400E000732240400828F9200380A
+:107DD0000A0008EC000038210E000E15000000001B
+:107DE0008F9200380A00095F000020210E0007046E
+:107DF000020020219232001B020020213658001080
+:107E00000E00070EA238001B8F9200380A000A4F9E
+:107E1000000018219243000C306A00011140000359
+:107E200000000000964B000EA48B002C9248000C22
+:107E3000310C00021180FF4000002821964E0012F4
+:107E40008E4D0014A48E001A0A000A1DAC8D001C71
+:107E50008F8300588F8700501067FF4E000030213D
+:107E60003C080800250855C4000320C000883021C4
+:107E70008CD10000122500C8246200013043000F9D
+:107E80001467FFFA000320C00A000A340000302102
+:107E90003C05080024A556400E0007322404008B40
+:107EA0008F9200380A0008EC0013382B3C0B0800B6
+:107EB0008D6B564024D8FFFE25710100322A007FC9
+:107EC0000147902102331024AD020028AE4600D0B5
+:107ED000AE4000D40A000855AE58001CACC0005497
+:107EE0003C0E08008DCE56403C09800C352C01001C
+:107EF000ACEE00288E500014AD9000D08E4D0014D2
+:107F0000AD8D00D48E4800102507FFFE0A000891B1
+:107F1000AD87001C5490FDAA240740000A0008BF4A
+:107F2000240710000E0007C3000000000A00090922
+:107F30008F9200388C83442C3C05DEAD34B2BEEF0A
+:107F40003C010800AC205640107200900000000078
+:107F50003C046C62348279701462000824040002CC
+:107F6000978A00549783004C020028210143482B34
+:107F70001120001924040092240400020E0005E4DC
+:107F8000240502003C0B8000AD6200203C0108008B
+:107F9000AC2256401040000D8F8E0038240C002873
+:107FA0002404000391CD001031A800FF550C0001FE
+:107FB000240400010E00004C0000000010400004EA
+:107FC000240400830A000A7F8F920038240400836F
+:107FD0003C05080024A556400E00071300000000D1
+:107FE0008F9200380013382B0A000804AF8700482E
+:107FF0000A0009E8240200128E4400080E0006EF71
+:10800000000000000A0009F4AE0200083C05080068
+:1080100024A556400E0006E3240400878F92003802
+:108020000A000A110013102B240400040E0005E4BA
+:108030002405003014400014004038218F9200388D
+:108040000A000A64240600833C05080024A5564063
+:108050000A000B45240400878E4400040E0006EF3E
+:10806000000000000A000A85AE0200083C05080076
+:1080700024A556400E000732240400828F92003857
+:108080000A000A11000010218F9200383C08800875
+:108090003C0C8000240B0050240A0001AD8200201B
+:1080A000A10B0000A10A000192490004A1090018D7
+:1080B00092440005A1040019924300063C04080004
+:1080C000248455C4A103001A924200073C0308000F
+:1080D000246355C0A102001B92450008A105001CA5
+:1080E00092460009A106001D925F000AA11F001E12
+:1080F0009259000BA119001F9258000CA1180020E2
+:108100009251000DA11100219250000EA1100022E9
+:10811000924F000FA10F0023924E0010A10E0024D9
+:10812000924D0011A10D0025964C0014A50C0028BD
+:10813000964B00168F8A00508F980058A50B002A86
+:1081400096490018000A10C025450001A509002C19
+:108150008E46001C0044C8210043F82130A5000FC2
+:10816000AFE60000AF27000010B80003AF85005055
+:108170000A000A640000302124AD000131A8000F7C
+:10818000000030210A000A64AF8800588C83442C18
+:108190000A000B243C046C623C07080024E755C02D
+:1081A00000879021ACC00000000030210A000A3492
+:1081B000AE4000003C0482013C03600034820E02A9
+:1081C000AC603D68AF80007803E00008AC623D6CB5
+:1081D00027BDFFE8AFB000103090FFFF001018423D
+:1081E0002C620041AFBF0014144000022404008040
+:1081F000240300403C010800AC3000603C01080052
+:10820000AC2300640E000E1E00602821244802BF2B
+:108210002409FF8001092824001039800010304013
+:108220008FBF00148FB0001000A7202100861821F6
+:10823000AF8300603C010800AC2500583C010800F9
+:10824000AC24005C03E0000827BD0018308300FF69
+:1082500030C6FFFF30E400FF3C0880008D0201B80B
+:108260000440FFFE00035400014438253C0960002F
+:1082700000E920253C031000AD050180AD06018416
+:10828000AD04018803E00008AD0301B88F86003813
+:108290003C096012352700108CCB00043C0C600EAA
+:1082A00035850010316A00062D480001ACE800C495
+:1082B0008CC40004ACA431808CC2000894C30002BA
+:1082C000ACA2318403E00008A78300708F850038DA
+:1082D0008F87FF208F86FF288CAE00043C0F601232
+:1082E00035E80010ACEE00688CAD0008ACED006C19
+:1082F0008CAC0010ACCC004C8CAB000CACCB004870
+:1083000094CA00543C0208008C42004425490001F4
+:10831000A4C9005494C400543083FFFF10620017B6
+:10832000000000003C0208008C420040A4C2005241
+:108330008CA30018ACE300308CA20014ACE2002C3B
+:108340008CB90018ACF900388CB800142405000171
+:10835000ACF800348D0600BC50C500198D0200B485
+:108360008D0200B8A4E2004894E40048A4E4004A66
+:1083700094E800DA03E000083102FFFF3C02080045
+:108380008C420024A4C00054A4C200528CA3001844
+:10839000ACE300308CA20014ACE2002C8CB90018C5
+:1083A000ACF900388CB8001424050001ACF8003496
+:1083B0008D0600BC54C5FFEB8D0200B88D0200B4E1
+:1083C000A4E2004894E40048A4E4004A94E800DAF7
+:1083D00003E000083102FFFF8F8600383C04800074
+:1083E0008CC900088CC80008000929C0000839C0E1
+:1083F000AC87002090C30007306200041040003AB0
+:10840000AF85007490CB0007316A00081140003935
+:108410008F87FF248CCD000C8CCE001401AE602B16
+:1084200011800032000000008CC2000CACE2007031
+:108430008CCB00188F85FF208F88FF28ACEB007451
+:108440008CCA00102402FFF8ACAA00C88CC9000C2A
+:10845000AD0900608CC4001CACA400C090E3007C9B
+:108460000062C824A0F9007C90D80007330F0008F0
+:1084700011E000040000000090ED007C35AC00012C
+:10848000A0EC007C90CF000731EE000111C0000984
+:108490000000000090E4007C2418000234820002F6
+:1084A000A0E2007C90A300EC307900FF13380013A9
+:1084B0002408003490C900073126000210C00004CF
+:1084C0000000000090EB007C356A0004A0EA007C0C
+:1084D00090ED007D31AC003FA0EC007D94A700DA68
+:1084E00003E0000830E2FFFF8F87FF240A000C5AE8
+:1084F0008CC200140A000C5BACE000700A000C7C1B
+:10850000ACA800CC8F8C003827BDFFD8AFB3001CBF
+:10851000AFB20018AFB00010AFBF0020AFB1001471
+:10852000918F00153C13600E3673001031EB000F75
+:10853000A38B007C8D8F00048D8B0008959F00120B
+:10854000959900109584001A9598001E958E001C30
+:1085500033EDFFFF332AFFFF3089FFFF3308FFFFB2
+:1085600031C7FFFF3C010800AC2D00243C0108008E
+:10857000AC2900443C010800AC2A0040AE683178C8
+:10858000AE67317C91850015959100163C12601202
+:108590003652001030A200FF3230FFFFAE62318849
+:1085A000AE5000B491830014959F0018240600017A
+:1085B0000066C80433F8FFFFAE5900B8AE5800BCDF
+:1085C000918E0014AF8F00643C08600631CD00FF2F
+:1085D000AE4D00C0918A00159584000E3C07600ADC
+:1085E000314900FFAF8B00683084FFFFAE4900C8FF
+:1085F000351100100E000BC334F004103C020800CB
+:108600008C4200603C0308008C6300643C06080058
+:108610008CC600583C0508008CA5005C8F84006067
+:108620008FBF0020AE23004CAE65319CAE030054DA
+:10863000AE4500DCAE6231A0AE6331A4AE663198C7
+:10864000AE2200488FB3001CAE0200508FB1001460
+:10865000AE4200E0AE4300E4AE4600D88FB000105A
+:108660008FB200180A0004CC27BD0028978500723D
+:108670009783005C27BDFFE8AFB0001000A3102B6C
+:10868000AFBF0014240400058F900038104000553F
+:10869000240900020E0005E48F850060AF8200749B
+:1086A000240400031040004F240900023C0680000F
+:1086B0000E00004CACC2002024070001240820005A
+:1086C0001040004D24040005978E00728F8AFF240D
+:1086D0002409005025C50001A7850072A1490000AA
+:1086E0003C0D08008DAD0064240380008F84FF20C2
+:1086F000000D6600AD4C0018A5400006954B000A21
+:108700008F85FF282402FF8001633024A546000ADC
+:10871000915F000A0000482103E2C825A159000A20
+:10872000A0A00008A140004CA08000C5961800023F
+:10873000978300703C020004A49800DA960F0002B0
+:108740002418FFBF25EE2401A48E00AE8E0D000478
+:10875000ACAD00448E0C0008ACAC0040A4A00050AE
+:10876000A4A000548E0B000C240C0030AC8B00280D
+:108770008E060010AC860024A480003EA487004E24
+:10878000A4870050A483003CAD420074AC8800C8AC
+:10879000ACA80060A08700EC909F00C433F9007F74
+:1087A000A09900C4909000C402187824A08F00C43F
+:1087B000914E007C35CD0001A14D007C938B007C57
+:1087C000AD480070AC8C00CCA08B00C68F880068D0
+:1087D0008F870064AC8800B4AC8700B8A5400078EF
+:1087E000A540007A8FBF00148FB000100120102127
+:1087F00003E0000827BD00188F8500740E00067482
+:108800008F8600600A000D482409000227BDFFE0A2
+:10881000AFB000108F900038AFB10014AFBF001898
+:108820008E0900040E000499000921C08E0800047E
+:108830008F84FF208F82FF28000839C03C0680000B
+:10884000ACC70020948500DA904300131460001C2C
+:1088500030B1FFFF8F8CFF24918B0008316A0040FC
+:108860001540000B000000008E0D00040220302196
+:108870008FBF00188FB100148FB0001024040022A5
+:1088800000003821000D29C00A000BE227BD00209E
+:108890000E000063000000008E0D00040220302155
+:1088A0008FBF00188FB100148FB000102404002275
+:1088B00000003821000D29C00A000BE227BD00206E
+:1088C0000E00005B000000008E0D0004022030212D
+:1088D0008FBF00188FB100148FB000102404002245
+:1088E00000003821000D29C00A000BE227BD00203E
+:1088F00027BDFFE0AFB200183092FFFFAFB000100D
+:10890000AFBF001CAFB100141240001E0000802158
+:108910008F8600388CC500002403000600053F0246
+:108920000005140230E4000714830016304500FFF0
+:108930002CA8000611000040000558803C0C0800DF
+:10894000258C532C016C50218D490000012000081A
+:10895000000000008F8E0078240D000111CD005022
+:1089600024020002AF820078260900013130FFFFA7
+:1089700024C800200212202B010030211480FFE5C2
+:10898000AF880038020010218FBF001C8FB2001882
+:108990008FB100148FB0001003E0000827BD002045
+:1089A0009387005E54E00034000030210E000C90EC
+:1089B000000000008F8600380A000DA82402000184
+:1089C0008F8700782405000210E50031240400138D
+:1089D0000000282100003021240700010E000BE2D6
+:1089E000000000000A000DA98F8600388F830078F0
+:1089F000240200021462FFF6240400120E000C454B
+:108A0000000000008F850074004030212404001213
+:108A10000E000BE2000038210A000DA98F860038F5
+:108A20008F8300782411000310710029241F000295
+:108A3000107FFFCE26090001240400100000282129
+:108A4000000030210A000DC6240700018F91007834
+:108A5000240600021626FFF9240400100E000CEA7A
+:108A600000000000144000238F9800388F860038E3
+:108A70000A000DA824020003240400140E000BE2D7
+:108A8000000028218F8600380A000DA82402000269
+:108A90000E000D52000000000A000DA98F8600385C
+:108AA0000E000BF200000000241900022404001440
+:108AB000000028210000302100003821AF99007803
+:108AC0000E000BE2000000000A000DA98F8600389E
+:108AD0000E000C02000000008F85007424190002B3
+:108AE0000040302124040010000038210A000DFF4E
+:108AF000AF9900780040382124040010970F00023D
+:108B0000000028210E000BE231E6FFFF8F860038BF
+:108B10000A000DA9AF9100788F84FF243C077FFFE6
+:108B200034E6FFFF8C8500182402000100A61824FB
+:108B3000AC83001803E00008A08200053084FFFF2A
+:108B400030A5FFFF108000070000182130820001CF
+:108B50001040000200042042006518211480FFFB31
+:108B60000005284003E000080060102110C0000745
+:108B7000000000008CA2000024C6FFFF24A5000412
+:108B8000AC82000014C0FFFB2484000403E0000852
+:108B90000000000010A0000824A3FFFFAC86000026
+:108BA00000000000000000002402FFFF2463FFFF1C
+:108BB0001462FFFA2484000403E0000800000000AF
+:108BC000000411C003E000082442024027BDFFE872
+:108BD000AFB0001000808021AFBF00140E000E3F28
+:108BE00000A0202100504821240AFF808FBF0014DC
+:108BF0008FB00010012A30243127007F3C08800A02
+:108C00003C04210000E8102100C428253C0380001A
+:108C100027BD0018AC650024AF820024AC400000E2
+:108C2000AC65002403E00008AC4000403C0D0800A7
+:108C30008DAD005800056180240AFF8001A45821F1
+:108C4000016C4821012A30243127007F3C08800C28
+:108C50003C04210000E8102100C428253C038000CA
+:108C6000AC650028AF82002003E00008AC4000247F
+:108C700030A5FFFF3C0680008CC201B80440FFFE17
+:108C80003C08601500A838253C031000ACC40180E6
+:108C9000ACC00184ACC7018803E00008ACC301B8D4
+:108CA0003C0D08008DAD005800056180240AFF804E
+:108CB00001A45821016C4021010A482400093140D7
+:108CC0003107007F00C728253C04200000A4182598
+:108CD0003C028000AC43083003E00008AF80002075
+:108CE00027BDFFE8AFB0001000808021AFBF0014A7
+:108CF0000E000E3F00A0202100504821240BFF80D1
+:108D0000012B5024000A39403128007F3C06200006
+:108D10008FBF00148FB0001000E8282534C2000176
+:108D200000A218253C04800027BD0018AC83083041
+:108D300003E00008AF8000243C0580088CA7006099
+:108D40003C0680080087102B144000112C83400043
+:108D50008CA800602D0340001060000F2403400029
+:108D60008CC900600089282B14A000020080182103
+:108D70008CC3006000035A42000B30803C0A08009C
+:108D8000254A53A000CA202103E000088C8200007D
+:108D90001460FFF32403400000035A42000B3080AC
+:108DA0003C0A0800254A53A000CA202103E000081D
+:108DB0008C8200003C05800890A6000893840088FF
+:108DC00024C20001304200FF3043007F1064000CD9
+:108DD00000023827A0A200083C0480008C8501789E
+:108DE00004A0FFFE8F8A0080240900023C081000C6
+:108DF000AC8A0140A089014403E00008AC880178F6
+:108E00000A000EC430E2008027BDFFD8AFB20018C0
+:108E10008F920084AFBF0020AFB3001CAFB0001032
+:108E2000AFB100148F9300208E5900283C100080B1
+:108E30003C0EFFEFAE7900008E580024A260000ABD
+:108E400035CDFFFFAE7800049251002C3C0BFF9F04
+:108E5000356AFFFFA271000C8E6F000C3C080040C9
+:108E6000A271000B01F06025018D4824012A3824ED
+:108E700000E83025AE66000C8E450004AE60001898
+:108E80003C0400FFAE6500148E43002C3482FFFFCB
+:108E9000A66000080062F824AE7F00108E5900081A
+:108EA0008F900080964E0012AE7900208E51000CFB
+:108EB00031D83FFF00187980AE7100248E4D001428
+:108EC00001F0602131CB0001AE6D00288E4A001800
+:108ED000000C41C2000B4B80AE6A002C8E46001C79
+:108EE00001093821A667001CAE66003096450002D5
+:108EF0008E440020A665001EAE6400349243003309
+:108F00003062000454400006924700003C02800892
+:108F1000344301008C7F00C0AE7F003092470000D8
+:108F20008F860024A0C700309245003330A4000291
+:108F300050800007925100018F880024240BFF808D
+:108F4000910A0030014B4825A109003092510001DF
+:108F50008F900024240CFFBF2404FFDFA2110031F6
+:108F60008F8D00243C1880083711008091AF003CA1
+:108F700031EE007FA1AE003C8F890024912B003C94
+:108F8000016C5024A12A003C8F9F00248E6800149D
+:108F900093E6003C2D0700010007114000C428247F
+:108FA00000A21825A3E3003C8F87002496590012E5
+:108FB000A4F900328E450004922E007C30B00003EC
+:108FC0000010782331ED000300AD102131CC0002F8
+:108FD0001580000224460034244600303C028008FC
+:108FE00034430080907F007C00BFC82433380004E5
+:108FF0001700000224C2000400C010218F98002432
+:1090000024190002ACE20034A3190000924F003F83
+:109010008F8E00243C0C8008358B0080A1CF00018E
+:109020008F910024924D003F8E440004A62D000233
+:10903000956A005C0E000E9D3150FFFF00024B80D0
+:10904000013038253C08420000E82825AE25000400
+:109050008E4400388F850024ACA400188E4600345E
+:10906000ACA6001CACA0000CACA00010A4A0001486
+:10907000A4A00016A4A00020A4A00022ACA000245C
+:109080008E62001450400001240200018FBF0020B6
+:109090008FB3001C8FB200188FB100148FB0001076
+:1090A000ACA200080A000EBC27BD002827BDFFC8DF
+:1090B0003C05800834A40080AFBF0034AFBE003050
+:1090C000AFB7002CAFB60028AFB50024AFB4002076
+:1090D000AFB3001CAFB20018AFB10014AFB00010B6
+:1090E000948300789482007A104300512405FFFF96
+:1090F0000080F0210A000FCC0080B821108B004DB9
+:109100008FBF00348F8600803C1808008F18005CE9
+:109110002411FF803C1680000306782101F1802491
+:10912000AED0002C96EE007A31EC007F3C0D800E24
+:1091300031CB7FFF018D5021000B4840012AA8212F
+:1091400096A400003C0808008D0800582405FF8004
+:1091500030953FFF01061821001539800067C821AE
+:109160000325F8243C02010003E290253338007FF8
+:109170003C11800CAED20028031190219250000DBA
+:10918000320F000411E0003702E0982196E3007AE4
+:1091900096E8007A96E5007A2404800031077FFF84
+:1091A00024E3000130627FFF00A4F82403E2C82515
+:1091B000A6F9007A96E6007A3C1408008E940060C6
+:1091C00030D67FFF12D400C1000000008E58001876
+:1091D0008F84008002A028212713FFFF0E000E7746
+:1091E000AE53002C97D5007897D4007A12950010D2
+:1091F000000028213C098008352401003C0A800831
+:1092000091480008908700C53114007F30E400FFCA
+:109210000284302B14C0FFB9268B0001938E008886
+:10922000268C0001008E682115ACFFB78F86008068
+:109230008FBF00348FBE00308FB7002C8FB6002850
+:109240008FB500248FB400208FB3001C8FB200189C
+:109250008FB100148FB0001000A0102103E00008AF
+:1092600027BD003800C020210E000E4202802821B8
+:109270008E4B00108E4C00308F8400242409000295
+:10928000016C5023AE4A0010A089000096E3005CF8
+:109290008E4400308F9100240E000E9D3070FFFF31
+:1092A00000024380011028253C07420000A710253A
+:1092B000AE2200048E5F00048F8A00248E590000C5
+:1092C000240B0008AD5F001CAD590018AD40000C28
+:1092D000AD4000109246000A240400052408C00096
+:1092E00030D000FFA550001496580008A55800166D
+:1092F0009251000A3C188008322F00FFA54F002031
+:10930000964E000837110100A54E0022AD40002402
+:10931000924D000B31AC00FFA54C0002A14B0001A7
+:109320008E4900308F830024240BFFBFAC690008F6
+:10933000A06400308F9000242403FFDF96070032E2
+:1093400000E8282400B51025A6020032921F003242
+:1093500033F9003F37260040A20600328F8C0024EC
+:10936000AD8000348E2F00C0AD8F0038918E003C50
+:109370003C0F7FFF31CD007FA18D003C8F84002406
+:1093800035EEFFFF908A003C014B4824A089003C49
+:109390008F85002490A8003C01033824A0A7003C3E
+:1093A0008E4200348F9100243C038008AE2200409E
+:1093B0008E59002C8E5F0030033F3023AE260044D0
+:1093C000923000483218007FA23800488F8800246D
+:1093D0008E4D00308D0C004801AE5824019650246B
+:1093E000014B4825AD0900489244000AA104004CF5
+:1093F000964700088F850024A4A7004E8E500030A9
+:109400008E4400300E0002E68C65006092F9007C0C
+:109410000002F940004028210002110003E230213F
+:109420003336000212C00003020680210005B0801E
+:1094300002168021926D007C31B30004126000029C
+:1094400000057080020E80218E4B003024058000C4
+:10945000316A0003000A4823312400030204182162
+:109460008F900024AE03003496E4007A96E8007AE8
+:1094700096F1007A31077FFF24E20001305F7FFF21
+:109480000225C824033F3025A6E6007A96F8007A24
+:109490003C1208008E520060330F7FFF11F200185B
+:1094A000000000008F8400800E000E7702A02821AB
+:1094B0008F8400800E000E87028028210E000EBCD3
+:1094C000000000000A000FC80000000096F1007ABA
+:1094D00002248024A6F0007A92EF007A92EB007AC0
+:1094E00031EE00FF000E69C2000D6027000C51C074
+:1094F0003169007F012A20250A000FC2A2E4007A08
+:1095000096E6007A00C5C024A6F8007A92EF007AA9
+:1095100092F3007A31F200FF001271C2000E682748
+:10952000000DB1C0326C007F01962825A2E5007ABB
+:109530000A0010798F8400803C0380003084FFFF94
+:1095400030A5FFFFAC640018AC65001C03E0000808
+:109550008C62001427BDFFA83C068008AFBE0050F7
+:10956000AFBF0054AFB7004CAFB60048AFB5004432
+:10957000AFB40040AFB3003CAFB20038AFB100347D
+:10958000AFB0003034C80100910500C590C7000895
+:10959000309EFFFF30A500FF30E2007F0045182A13
+:1095A000A7A00014A7A0001E10600053AFA00010D9
+:1095B00090C900083126007F00A620232493FFFFD6
+:1095C0000013802B001E882B0211782451E00084A8
+:1095D0008FB300103C19800897360052973700501F
+:1095E000001EC40002D7A8230015A4000014140311
+:1095F00003C2902A1640000200182C0300402821C4
+:10960000001314000002240300A4F82A57E000010C
+:1096100000A0202128830009146000020080A021FE
+:10962000241400083C0A80088D4500480014498035
+:109630008D48004C3C0380003124FFFF3C060010A5
+:109640000086382534710400AC650038AF91008481
+:10965000AC68003CAC670030000000000000000077
+:1096600000000000000000000000000000000000FA
+:1096700000000000000000008C6C0000318B002016
+:109680001160FFFD0014682A01B010241040003959
+:109690000000A8213C16800892D700083C128000E8
+:1096A0008E44010032F6007F0E000E4202C02821D7
+:1096B0008E2F00108E4401000000902131F73FFFF3
+:1096C0000E000E5A02E02821922E000031C2003F07
+:1096D0002C50000852000010000088210002F88081
+:1096E0003C0308002463535403E3C8218F3800006F
+:1096F000030000080000000090CE0008938B008853
+:1097000031CD007F00AD6023016C50210A0010BFF5
+:109710002553FFFF000088213C1080008E040100CB
+:109720000E000E7702E028218E0401000E000E8745
+:1097300002C028211220000F0013802B8F8A008482
+:1097400026A900010009AC00027298230015AC03A1
+:109750002545004002B4B02A0013802B24170001D5
+:1097600000A0882102D01024AF8500841440FFC9D6
+:10977000AFB700103C07800894F100503C05800012
+:109780003C06002002B1C821A4F90050ACA600306C
+:1097900094F4005094E3005203D560231074001D2C
+:1097A000319EFFFF8CE5004C8CE90048001561807C
+:1097B00000ACB0210000A02102CCA82B0134502124
+:1097C0000155B821ACF6004CACF70048001E882BC0
+:1097D0000211782415E0FF803C1980088FB3001037
+:1097E0008FBF00548FBE00503A6200018FB7004C0B
+:1097F0008FB600488FB500448FB400408FB3003C53
+:109800008FB200388FB100348FB0003003E0000811
+:1098100027BD005894F200548CEF0044325FFFFEE5
+:10982000001FC0C001F87021ACAE003C8CEB0044BE
+:109830008CAD003C016D40231900003B000000008E
+:109840008CE20040244200013C07005034E4001048
+:109850003C038000ACA20038AC6400300000000083
+:1098600000000000000000000000000000000000F8
+:109870000000000000000000000000008C760000E6
+:1098800032D7002012E0FFFD3C11800896280054DA
+:109890003C0A80003C06800831190001001960C0B4
+:1098A000018AA0218E8304003C0708008CE7004455
+:1098B0003C150020ACC300488E8904042405000137
+:1098C000ACC9004C10E50259AD550030963F00522E
+:1098D0003C0508008CA5004000BFC021A6380052FE
+:1098E000962F005425EE0001A62E00549626005413
+:1098F00030C4FFFF5487FF34001E882B30A5FFFFC4
+:109900000E00109DA62000543C0408008C84002406
+:10991000962700520044102300E29023A632005202
+:109920000A0010C1001E882B8CE200400A00116260
+:109930003C07005092280001240700013102007FFB
+:109940001447001C97AC001E8E2A0014240BC00084
+:1099500031443FFF018B48243C0608008CC6006060
+:109960000124282530A43FFF0086882B12200011F7
+:10997000A7A5001E3C1108008E3100588F82008080
+:10998000000441802407FF80022218210068F8218A
+:1099900003E7C82433EF007F3C1880003C12800EA0
+:1099A000AF19002C01F2682191AE000D35D00004F2
+:1099B000A1B0000D0E000ED12412000124110001EF
+:1099C0003C1080008E0401000E000E7702E028217A
+:1099D0008E0401000E000E8702C028211620FF58B9
+:1099E0008F8A00840A00112C0013802B8F8600843C
+:1099F00090C900013125002010A0018A2410000127
+:109A00003C048008348C0080918B007C8F91002076
+:109A100000009021316A00011140000FAFB000201A
+:109A20008CD000148C8E0060020E682B15A00003F1
+:109A3000020038218C8700603C0480083483008059
+:109A40008C72007000F2782B15E0000200E02021FB
+:109A50008C640070008090213C07800834E5008011
+:109A60008CD900148CBF0070033FC02B170000027C
+:109A7000032020218CA400700092182310600003A2
+:109A8000AFA3002824080002AFA800208FA5002063
+:109A90000265102B144000B5000018218CC400385A
+:109AA0008E2F000C3C180080AE2400008CCE0034B9
+:109AB0003C10FF9F01F86025AE2E000490CB003FC4
+:109AC000360DFFFF018D48243C0A00203C06FFEFC5
+:109AD000A22B000B012A382534C5FFFF00E54024E6
+:109AE0003C0200088F87008401022025AE24000C70
+:109AF0008CE30014AE2000188FAF0028AE230014B2
+:109B00008CF800183C1FFFFB37F9FFFFAE38001C34
+:109B10008CEE000800996824024F8021AE2E0024AC
+:109B20008CEC000CAE2D000CA6200038A620003ACC
+:109B3000AE30002CAE2C0020AE2000288CEB0014A0
+:109B40008FAA002801724823012A302310C0001177
+:109B5000AE26001090F0003D8E2C00048E2A0000EE
+:109B600000106900018D28210000102100AD302B6C
+:109B70000142482101264021AE250004AE28000004
+:109B800090E3003DA223000A8F9F008497F900060E
+:109B9000A63900088F8A0024240200023C068008AF
+:109BA000A142000034C900809525005C02402021BC
+:109BB0008F90002430A8FFFF0E000E9DAFA8002458
+:109BC0008FA300240002FB808F8500843C044200A8
+:109BD00003E3C8250324C025AE1800048F840024A5
+:109BE0008CAF0038AC8F00188CAE0034AC8E001CEB
+:109BF000AC80000CAC800010A4800014A48000167F
+:109C0000A4800020A4800022AC80002490A7003F04
+:109C1000A48700025240018C240700018FAB00286A
+:109C20005160000290A2003D90A2003E244C000131
+:109C3000A08C00018F840024AC9200083C1880089E
+:109C400037100080920F007C31EE000215C0000238
+:109C500024070034240700308F8500843C088008E6
+:109C60003509008090A300009128007C3259000340
+:109C7000A08300308F9F00848F9000242404000470
+:109C800093F8000100997823240DC000A218003138
+:109C90008F9900248F8E008431E50003972C0032C9
+:109CA00095CB001200F24821018D502431623FFF14
+:109CB00001423025A72600329323003201253821A6
+:109CC00031080004307F003F37E40040A324003215
+:109CD000124000028F85002400E838213C0C8008E7
+:109CE000ACA70034358B01008D6200C02E4400010A
+:109CF0002403FFDFACA2003890AA003C0004C94056
+:109D00003146007FA0A6003C8F8900242405FFBFB8
+:109D10009127003C00E54024A128003C8F8F0024BF
+:109D200091FF003C03E3C02403198025A1F0003C0F
+:109D30008F8B00848F8A00248D6E0020AD4E0040F2
+:109D40008D6D0024AD4D00448D6C0028AD4C004855
+:109D50008D62002C0E000EBCAD42004C8FA6002080
+:109D60002407000210C700118FA300200003202B3E
+:109D700000048023027098240060802100609021FC
+:109D80000A0011150010882B962700128F8400807E
+:109D90000000902130E5FFFFA7A700140E000E6B16
+:109DA000241100010A0011C03C1080003C19800001
+:109DB0003C0280088F240100905800080E000E42DB
+:109DC0003305007F8F8E00248FAF00208FA40028E2
+:109DD000A1CF00000E000E9D8F9000248FAD0024B7
+:109DE00000023B803C0B420000ED40258F87008441
+:109DF000010B2025AE0400048CE500388F90002470
+:109E000000005021000A1900AE0500188CEC003447
+:109E10003C087FFF3504FFFFAE0C001C90E9003EBC
+:109E20008E1F001C8E1800180009C9000009370297
+:109E300003F968210066102501B9782B030270210F
+:109E400001CF5821AE0D001CAE0B0018AE00000C67
+:109E5000AE00001090E5003E8FAF0028240E0005F4
+:109E6000A605001494EC00042405C00001E4582465
+:109E7000A60C001690EA003E01E02021A60A002070
+:109E800094E60004A6060022AE00002490E3003F02
+:109E9000A603000290E9003E90FF003D03E9C823BD
+:109EA00027380001A21800018F8D00243C10800883
+:109EB000ADAF0008A1AE00308F9800248F820084DF
+:109EC000360F0100970C0032944A00122410FF80D4
+:109ED00000AC382431463FFF00E61825A7030032C6
+:109EE000930900322405FFBF2403FFDF313F003F09
+:109EF00037F90040A31900328F8C00242418FFFF8B
+:109F0000AD8000348DEE00C0AD8E0038918D003CE8
+:109F100031A2007FA182003C8F87002490EA003CA0
+:109F200001453024A0E6003C8F9900249329003C91
+:109F30000123F824A33F003C8F8D00243C1F8008A0
+:109F4000ADB80040ADB2004491AF00483C12800073
+:109F500001F07025A1AE00488F8700248F86008411
+:109F60008CEC004801921024004B5025ACEA0048CC
+:109F700090C5003EA0E5004C8F8800848F830024AC
+:109F800095090004A469004E8FE500600E0002E60A
+:109F9000000000008F99FF2C8FAE00280002814046
+:109FA000932F007C0002C1000218682131F20002E8
+:109FB00000402821164000AA01CD30213C0A80082B
+:109FC000354300809069007C313F000413E00003BA
+:109FD0008FAE00280005608000CC3021240D0004E5
+:109FE0008F90002431C7000301A758233168000374
+:109FF00000C82021AE0400343C068008A6250038A5
+:10A000003C0580008CA4010090D100080E000E8752
+:10A010003225007F0E000EBC000000000A0012AACC
+:10A020008FA300208F8500208CC2003824180003E5
+:10A03000A4A00008ACA200008CDF0034A0A0000A9D
+:10A040008F920084ACBF00043C040080924F003F1C
+:10A05000A0B8000C8CAE000C3C0DFF9FA0AF000B15
+:10A0600001C4402535ABFFFF3C11FFEF8F98008402
+:10A07000010B30243639FFFF00D96024ACAC000C52
+:10A080008F030014971F00128F870080ACA300106D
+:10A090008F090014ACA00018ACA00020ACA90014DB
+:10A0A000ACA000248F0A001833E93FFF000911809B
+:10A0B000ACAA00288F1200080047782133EE000177
+:10A0C000ACB200308F08000C8F990024000F69C2D9
+:10A0D000000E238001A45821241100023C068008B0
+:10A0E000A4AB001CA4A00034ACA8002CA331000039
+:10A0F00034D90080972C005C8F8F00243C034200F1
+:10A10000318AFFFF01433825ADE700048F820084C8
+:10A11000241800012411C0008C5F0038240700348B
+:10A12000ADFF00188C520034ADF2001CADE0000C05
+:10A13000ADE00010A5E00014A5E00016A5E00020A9
+:10A14000A5E00022ADE00024A5F00002A1F8000186
+:10A150008F8B00248F8E0084AD70000891CD00009D
+:10A16000A16D00308F8800848F8400249105000148
+:10A17000A08500318F920024964C0032019150242A
+:10A1800001491825A6430032925F003233E2003FB6
+:10A19000A24200329338007C330F000215E0000227
+:10A1A0008F840024240700303C028008AC870034F0
+:10A1B000345201008E5F00C0240EFFBF02009021C8
+:10A1C000AC9F00389098003C330F007FA08F003C7C
+:10A1D0008F880024910D003C01AE5824A10B003C57
+:10A1E0008F86002490D1003C36390020A0D9003C55
+:10A1F0008F8A00848F8500240010882B8D4C0020CE
+:10A20000ACAC00408D430024ACA300448D49002831
+:10A21000ACA900488D47002CACA7004C0E000EBC2A
+:10A220003C1080000A0011160000000094CD00527E
+:10A230003C0B08008D6B0024016D8821A4D10052D5
+:10A240000A0010C1001E882BA08700018F84002403
+:10A25000240D0001AC8D00080A00125F3C18800834
+:10A26000000290800A00133E00D2302127BDFFE09B
+:10A270003C0D8008AFB20018AFB00010AFBF001C9B
+:10A28000AFB1001435B200808E4C001835A8010023
+:10A29000964B000695A70050910900EC000C560261
+:10A2A000016728233143007F312600FF2402000389
+:10A2B000A3830088AF84008010C2001B30B0FFFF72
+:10A2C000910600EC2412000530C200FF105200334A
+:10A2D00000000000160000098FBF001C8FB200189C
+:10A2E0008FB100148FB00010240D0C003C0C8000C6
+:10A2F00027BD002003E00008AD8D00240E0010A44F
+:10A30000020020218FBF001C8FB200188FB10014F3
+:10A310008FB00010240D0C003C0C800027BD0020E5
+:10A3200003E00008AD8D0024965800789651007A1D
+:10A33000924E007D0238782631E8FFFF31C400C01C
+:10A34000148000092D1100011600003700000000E4
+:10A350005620FFE28FBF001C0E000F7A00000000A5
+:10A360000A0014068FBF001C1620FFDA0000000050
+:10A370000E000F7A000000001440FFD88FBF001CB1
+:10A380001600002200000000925F007D33E2003FD3
+:10A39000A242007D0A0014068FBF001C950900DA56
+:10A3A0008F86006000802821240400050E000674BA
+:10A3B0003130FFFF978300723C0480002465FFFF6B
+:10A3C000A78500728C8A01B80540FFFE00000000DE
+:10A3D000AC8001808FBF001CAC9001848FB200184C
+:10A3E0008FB100148FB000103C0760133C0B1000BD
+:10A3F000240D0C003C0C800027BD0020AC87018898
+:10A40000AC8B01B803E00008AD8D00240E0010A451
+:10A41000020020215040FFB18FBF001C925F007DE1
+:10A420000A00143333E2003F0E0010A40200202182
+:10A430001440FFAA8FBF001C12200007000000007C
+:10A440009259007D3330003F36020040A242007D29
+:10A450000A0014068FBF001C0E000F7A00000000D7
+:10A460005040FF9E8FBF001C9259007D3330003F4B
+:08A470000A00146236020040EC
+:08A47800000000000000001BC1
+:10A480000000000F0000000A0000000800000006A5
+:10A4900000000005000000050000000400000004AA
+:10A4A00000000003000000030000000300000003A0
+:10A4B0000000000300000002000000020000000293
+:10A4C0000000000200000002000000020000000284
+:10A4D0000000000200000002000000020000000274
+:10A4E0000000000200000002000000020000000264
+:0CA4F0000000000100000001000000015D
+:04A4FC0080080100D3
+:10A50000800800808008000000000C0000003080FF
+:10A5100008000F4808000FF40800100C0800102075
+:10A520000800103408000F4808000F4808001068A1
+:10A53000080010A0080010B0080010D8080017C8C4
+:10A54000080017C8080018000800180008001814B0
+:10A55000080017E408001A3C08001A0808001A94BA
+:10A5600008001A9408001B1C08001A4C80080240BE
+:10A57000080021A808001FF4080021D00800226864
+:10A58000080023B808002404080025280800243007
+:10A59000080024B408002064080029D008002974A9
+:10A5A0000800201008002010080020100800259C3A
+:10A5B0000800259C08002010080020100800284CE6
+:10A5C00008002010080020100800201008002010AB
+:10A5D000080028AC080020100800201008002010F7
+:10A5E000080020100800201008002010080020108B
+:10A5F000080020100800201008002010080020107B
+:10A600000800201008002010080020100800242452
+:10A6100008002010080020100800291C0800201045
+:10A62000080020100800201008002010080020104A
+:10A63000080020100800201008002010080020103A
+:10A64000080020100800201008002010080020102A
+:10A65000080020100800201008002010080020101A
+:10A66000080027700800201008002010080026E4C9
+:10A6700008002640080037880800375C08003728A3
+:10A68000080036FC080036DC08003690800801001F
+:10A69000800800808008000080080080080046F0E4
+:10A6A0000800472808004670080046F0080046F0F9
+:0CA6B00008004450080046F008004AC4AE
+:04A6BC000A000C760E
+:10A6C00000000000000000000000000D72787035EE
+:10A6D0002E302E306A330000050000030000000019
+:10A6E0000000000100000000000000000000000069
+:10A6F000000000000000000000000000000000005A
+:10A700000000000000000000000000000000000049
+:10A710000000000000000000000000000000000039
+:10A720000000000000000000000000000000000029
+:10A730000000000000000000000000000000000019
+:10A740000000000000000000000000000000000009
+:10A7500000000000000000000000000000000000F9
+:10A7600000000000000000000000000000000000E9
+:10A7700000000000000000000000000000000000D9
+:10A7800000000000000000000000000000000000C9
+:10A7900000000000000000000000000000000000B9
+:10A7A00000000000000000000000000000000000A9
+:10A7B0000000000000000000000000000000000099
+:10A7C0000000000000000000000000000000000089
+:10A7D0000000000000000000000000000000000079
+:10A7E0000000000000000000000000000000000069
+:10A7F0000000000000000000000000000000000059
+:10A800000000000000000000000000000000000048
+:10A810000000000000000000000000000000000038
+:10A820000000000000000000000000000000000028
+:10A830000000000000000000000000000000000018
+:10A840000000000000000000000000000000000008
+:10A8500000000000000000000000000000000000F8
+:10A8600000000000000000000000000000000000E8
+:10A8700000000000000000000000000000000000D8
+:10A8800000000000000000000000000000000000C8
+:10A8900000000000000000000000000000000000B8
+:10A8A00000000000000000000000000000000000A8
+:10A8B0000000000000000000000000000000000098
+:10A8C0000000000000000000000000000000000088
+:10A8D0000000000000000000000000000000000078
+:10A8E0000000000000000000000000000000000068
+:10A8F0000000000000000000000000000000000058
+:10A900000000000000000000000000000000000047
+:10A910000000000000000000000000000000000037
+:10A920000000000000000000000000000000000027
+:10A930000000000000000000000000000000000017
+:10A940000000000000000000000000000000000007
+:10A9500000000000000000000000000000000000F7
+:10A9600000000000000000000000000000000000E7
+:10A9700000000000000000000000000000000000D7
+:10A9800000000000000000000000000000000000C7
+:10A9900000000000000000000000000000000000B7
+:10A9A00000000000000000000000000000000000A7
+:10A9B0000000000000000000000000000000000097
+:10A9C0000000000000000000000000000000000087
+:10A9D0000000000000000000000000000000000077
+:10A9E0000000000000000000000000000000000067
+:10A9F0000000000000000000000000000000000057
+:10AA00000000000000000000000000000000000046
+:10AA10000000000000000000000000000000000036
+:10AA20000000000000000000000000000000000026
+:10AA30000000000000000000000000000000000016
+:10AA40000000000000000000000000000000000006
+:10AA500000000000000000000000000000000000F6
+:10AA600000000000000000000000000000000000E6
+:10AA700000000000000000000000000000000000D6
+:10AA800000000000000000000000000000000000C6
+:10AA900000000000000000000000000000000000B6
+:10AAA00000000000000000000000000000000000A6
+:10AAB0000000000000000000000000000000000096
+:10AAC0000000000000000000000000000000000086
+:10AAD0000000000000000000000000000000000076
+:10AAE0000000000000000000000000000000000066
+:10AAF0000000000000000000000000000000000056
+:10AB00000000000000000000000000000000000045
+:10AB10000000000000000000000000000000000035
+:10AB20000000000000000000000000000000000025
+:10AB30000000000000000000000000000000000015
+:10AB40000000000000000000000000000000000005
+:10AB500000000000000000000000000000000000F5
+:10AB600000000000000000000000000000000000E5
+:10AB700000000000000000000000000000000000D5
+:10AB800000000000000000000000000000000000C5
+:10AB900000000000000000000000000000000000B5
+:10ABA00000000000000000000000000000000000A5
+:10ABB0000000000000000000000000000000000095
+:10ABC0000000000000000000000000000000000085
+:10ABD0000000000000000000000000000000000075
+:10ABE0000000000000000000000000000000000065
+:10ABF0000000000000000000000000000000000055
+:10AC00000000000000000000000000000000000044
+:10AC10000000000000000000000000000000000034
+:10AC20000000000000000000000000000000000024
+:10AC30000000000000000000000000000000000014
+:10AC40000000000000000000000000000000000004
+:10AC500000000000000000000000000000000000F4
+:10AC600000000000000000000000000000000000E4
+:10AC700000000000000000000000000000000000D4
+:10AC800000000000000000000000000000000000C4
+:10AC900000000000000000000000000000000000B4
+:10ACA00000000000000000000000000000000000A4
+:10ACB0000000000000000000000000000000000094
+:10ACC0000000000000000000000000000000000084
+:10ACD0000000000000000000000000000000000074
+:10ACE0000000000000000000000000000000000064
+:10ACF0000000000000000000000000000000000054
+:10AD00000000000000000000000000000000000043
+:10AD10000000000000000000000000000000000033
+:10AD20000000000000000000000000000000000023
+:10AD30000000000000000000000000000000000013
+:10AD40000000000000000000000000000000000003
+:10AD500000000000000000000000000000000000F3
+:10AD600000000000000000000000000000000000E3
+:10AD700000000000000000000000000000000000D3
+:10AD800000000000000000000000000000000000C3
+:10AD900000000000000000000000000000000000B3
+:10ADA00000000000000000000000000000000000A3
+:10ADB0000000000000000000000000000000000093
+:10ADC0000000000000000000000000000000000083
+:10ADD0000000000000000000000000000000000073
+:10ADE0000000000000000000000000000000000063
+:10ADF0000000000000000000000000000000000053
+:10AE00000000000000000000000000000000000042
+:10AE10000000000000000000000000000000000032
+:10AE20000000000000000000000000000000000022
+:10AE30000000000000000000000000000000000012
+:10AE40000000000000000000000000000000000002
+:10AE500000000000000000000000000000000000F2
+:10AE600000000000000000000000000000000000E2
+:10AE700000000000000000000000000000000000D2
+:10AE800000000000000000000000000000000000C2
+:10AE900000000000000000000000000000000000B2
+:10AEA00000000000000000000000000000000000A2
+:10AEB0000000000000000000000000000000000092
+:10AEC0000000000000000000000000000000000082
+:10AED0000000000000000000000000000000000072
+:10AEE0000000000000000000000000000000000062
+:10AEF0000000000000000000000000000000000052
+:10AF00000000000000000000000000000000000041
+:10AF10000000000000000000000000000000000031
+:10AF20000000000000000000000000000000000021
+:10AF30000000000000000000000000000000000011
+:10AF40000000000000000000000000000000000001
+:10AF500000000000000000000000000000000000F1
+:10AF600000000000000000000000000000000000E1
+:10AF700000000000000000000000000000000000D1
+:10AF800000000000000000000000000000000000C1
+:10AF900000000000000000000000000000000000B1
+:10AFA00000000000000000000000000000000000A1
+:10AFB0000000000000000000000000000000000091
+:10AFC0000000000000000000000000000000000081
+:10AFD0000000000000000000000000000000000071
+:10AFE0000000000000000000000000000000000061
+:10AFF0000000000000000000000000000000000051
+:10B000000000000000000000000000000000000040
+:10B010000000000000000000000000000000000030
+:10B020000000000000000000000000000000000020
+:10B030000000000000000000000000000000000010
+:10B040000000000000000000000000000000000000
+:10B0500000000000000000000000000000000000F0
+:10B0600000000000000000000000000000000000E0
+:10B0700000000000000000000000000000000000D0
+:10B0800000000000000000000000000000000000C0
+:10B0900000000000000000000000000000000000B0
+:10B0A00000000000000000000000000000000000A0
+:10B0B0000000000000000000000000000000000090
+:10B0C0000000000000000000000000000000000080
+:10B0D0000000000000000000000000000000000070
+:10B0E0000000000000000000000000000000000060
+:10B0F0000000000000000000000000000000000050
+:10B10000000000000000000000000000000000003F
+:10B11000000000000000000000000000000000002F
+:10B12000000000000000000000000000000000001F
+:10B13000000000000000000000000000000000000F
+:10B1400000000000000000000000000000000000FF
+:10B1500000000000000000000000000000000000EF
+:10B1600000000000000000000000000000000000DF
+:10B1700000000000000000000000000000000000CF
+:10B1800000000000000000000000000000000000BF
+:10B1900000000000000000000000000000000000AF
+:10B1A000000000000000000000000000000000009F
+:10B1B000000000000000000000000000000000008F
+:10B1C000000000000000000000000000000000007F
+:10B1D000000000000000000000000000000000006F
+:10B1E000000000000000000000000000000000005F
+:10B1F000000000000000000000000000000000004F
+:10B20000000000000000000000000000000000003E
+:10B21000000000000000000000000000000000002E
+:10B22000000000000000000000000000000000001E
+:10B23000000000000000000000000000000000000E
+:10B2400000000000000000000000000000000000FE
+:10B2500000000000000000000000000000000000EE
+:10B2600000000000000000000000000000000000DE
+:10B2700000000000000000000000000000000000CE
+:10B2800000000000000000000000000000000000BE
+:10B2900000000000000000000000000000000000AE
+:10B2A000000000000000000000000000000000009E
+:10B2B000000000000000000000000000000000008E
+:10B2C000000000000000000000000000000000007E
+:10B2D000000000000000000000000000000000006E
+:10B2E000000000000000000000000000000000005E
+:10B2F000000000000000000000000000000000004E
+:10B30000000000000000000000000000000000003D
+:10B31000000000000000000000000000000000002D
+:10B32000000000000000000000000000000000001D
+:10B33000000000000000000000000000000000000D
+:10B3400000000000000000000000000000000000FD
+:10B3500000000000000000000000000000000000ED
+:10B3600000000000000000000000000000000000DD
+:10B3700000000000000000000000000000000000CD
+:10B3800000000000000000000000000000000000BD
+:10B3900000000000000000000000000000000000AD
+:10B3A000000000000000000000000000000000009D
+:10B3B000000000000000000000000000000000008D
+:10B3C000000000000000000000000000000000007D
+:10B3D000000000000000000000000000000000006D
+:10B3E000000000000000000000000000000000005D
+:10B3F000000000000000000000000000000000004D
+:10B40000000000000000000000000000000000003C
+:10B41000000000000000000000000000000000002C
+:10B42000000000000000000000000000000000001C
+:10B43000000000000000000000000000000000000C
+:10B4400000000000000000000000000000000000FC
+:10B4500000000000000000000000000000000000EC
+:10B4600000000000000000000000000000000000DC
+:10B4700000000000000000000000000000000000CC
+:10B4800000000000000000000000000000000000BC
+:10B4900000000000000000000000000000000000AC
+:10B4A000000000000000000000000000000000009C
+:10B4B000000000000000000000000000000000008C
+:10B4C000000000000000000000000000000000007C
+:10B4D000000000000000000000000000000000006C
+:10B4E000000000000000000000000000000000005C
+:10B4F000000000000000000000000000000000004C
+:10B50000000000000000000000000000000000003B
+:10B51000000000000000000000000000000000002B
+:10B52000000000000000000000000000000000001B
+:10B53000000000000000000000000000000000000B
+:10B5400000000000000000000000000000000000FB
+:10B5500000000000000000000000000000000000EB
+:10B5600000000000000000000000000000000000DB
+:10B5700000000000000000000000000000000000CB
+:10B5800000000000000000000000000000000000BB
+:10B5900000000000000000000000000000000000AB
+:10B5A000000000000000000000000000000000009B
+:10B5B000000000000000000000000000000000008B
+:10B5C000000000000000000000000000000000007B
+:10B5D000000000000000000000000000000000006B
+:10B5E000000000000000000000000000000000005B
+:10B5F000000000000000000000000000000000004B
+:10B60000000000000000000000000000000000003A
+:10B61000000000000000000000000000000000002A
+:10B62000000000000000000000000000000000001A
+:10B63000000000000000000000000000000000000A
+:10B6400000000000000000000000000000000000FA
+:10B6500000000000000000000000000000000000EA
+:10B6600000000000000000000000000000000000DA
+:10B6700000000000000000000000000000000000CA
+:10B6800000000000000000000000000000000000BA
+:10B6900000000000000000000000000000000000AA
+:10B6A000000000000000000000000000000000009A
+:10B6B000000000000000000000000000000000008A
+:10B6C000000000000000000000000000000000007A
+:10B6D000000000000000000000000000000000006A
+:10B6E000000000000000000000000000000000005A
+:10B6F000000000000000000000000000000000004A
+:10B700000000000000000000000000000000000039
+:10B710000000000000000000000000000000000029
+:10B720000000000000000000000000000000000019
+:10B730000000000000000000000000000000000009
+:10B7400000000000000000000000000000000000F9
+:10B7500000000000000000000000000000000000E9
+:10B7600000000000000000000000000000000000D9
+:10B7700000000000000000000000000000000000C9
+:10B7800000000000000000000000000000000000B9
+:10B7900000000000000000000000000000000000A9
+:10B7A0000000000000000000000000000000000099
+:10B7B0000000000000000000000000000000000089
+:10B7C0000000000000000000000000000000000079
+:10B7D0000000000000000000000000000000000069
+:10B7E0000000000000000000000000000000000059
+:10B7F0000000000000000000000000000000000049
+:10B800000000000000000000000000000000000038
+:10B810000000000000000000000000000000000028
+:10B820000000000000000000000000000000000018
+:10B830000000000000000000000000000000000008
+:10B8400000000000000000000000000000000000F8
+:10B8500000000000000000000000000000000000E8
+:10B8600000000000000000000000000000000000D8
+:10B8700000000000000000000000000000000000C8
+:10B8800000000000000000000000000000000000B8
+:10B8900000000000000000000000000000000000A8
+:10B8A0000000000000000000000000000000000098
+:10B8B0000000000000000000000000000000000088
+:10B8C0000000000000000000000000000000000078
+:10B8D0000000000000000000000000000000000068
+:10B8E0000000000000000000000000000000000058
+:10B8F0000000000000000000000000000000000048
+:10B900000000000000000000000000000000000037
+:10B910000000000000000000000000000000000027
+:10B920000000000000000000000000000000000017
+:10B930000000000000000000000000000000000007
+:10B9400000000000000000000000000000000000F7
+:10B9500000000000000000000000000000000000E7
+:10B9600000000000000000000000000000000000D7
+:10B9700000000000000000000000000000000000C7
+:10B9800000000000000000000000000000000000B7
+:10B9900000000000000000000000000000000000A7
+:10B9A0000000000000000000000000000000000097
+:10B9B0000000000000000000000000000000000087
+:10B9C0000000000000000000000000000000000077
+:10B9D0000000000000000000000000000000000067
+:10B9E0000000000000000000000000000000000057
+:10B9F0000000000000000000000000000000000047
+:10BA00000000000000000000000000000000000036
+:10BA10000000000000000000000000000000000026
+:10BA20000000000000000000000000000000000016
+:10BA30000000000000000000000000000000000006
+:10BA400000000000000000000000000000000000F6
+:10BA500000000000000000000000000000000000E6
+:10BA600000000000000000000000000000000000D6
+:10BA700000000000000000000000000000000000C6
+:10BA800000000000000000000000000000000000B6
+:10BA900000000000000000000000000000000000A6
+:10BAA0000000000000000000000000000000000096
+:10BAB0000000000000000000000000000000000086
+:10BAC0000000000000000000000000000000000076
+:10BAD0000000000000000000000000000000000066
+:10BAE0000000000000000000000000000000000056
+:10BAF0000000000000000000000000000000000046
+:10BB00000000000000000000000000000000000035
+:10BB10000000000000000000000000000000000025
+:10BB20000000000000000000000000000000000015
+:10BB30000000000000000000000000000000000005
+:10BB400000000000000000000000000000000000F5
+:10BB500000000000000000000000000000000000E5
+:10BB600000000000000000000000000000000000D5
+:10BB700000000000000000000000000000000000C5
+:10BB800000000000000000000000000000000000B5
+:10BB900000000000000000000000000000000000A5
+:10BBA0000000000000000000000000000000000095
+:10BBB0000000000000000000000000000000000085
+:10BBC0000000000000000000000000000000000075
+:10BBD0000000000000000000000000000000000065
+:10BBE0000000000000000000000000000000000055
+:10BBF0000000000000000000000000000000000045
+:10BC00000000000000000000000000000000000034
+:10BC10000000000000000000000000000000000024
+:10BC20000000000000000000000000000000000014
+:10BC30000000000000000000000000000000000004
+:10BC400000000000000000000000000000000000F4
+:10BC500000000000000000000000000000000000E4
+:10BC600000000000000000000000000000000000D4
+:10BC700000000000000000000000000000000000C4
+:10BC800000000000000000000000000000000000B4
+:10BC900000000000000000000000000000000000A4
+:10BCA0000000000000000000000000000000000094
+:10BCB0000000000000000000000000000000000084
+:10BCC0000000000000000000000000000000000074
+:10BCD0000000000000000000000000000000000064
+:10BCE0000000000000000000000000000000000054
+:10BCF0000000000000000000000000000000000044
+:10BD00000000000000000000000000000000000033
+:10BD10000000000000000000000000000000000023
+:10BD20000000000000000000000000000000000013
+:10BD30000000000000000000000000000000000003
+:10BD400000000000000000000000000000000000F3
+:10BD500000000000000000000000000000000000E3
+:10BD600000000000000000000000000000000000D3
+:10BD700000000000000000000000000000000000C3
+:10BD800000000000000000000000000000000000B3
+:10BD900000000000000000000000000000000000A3
+:10BDA0000000000000000000000000000000000093
+:10BDB0000000000000000000000000000000000083
+:10BDC0000000000000000000000000000000000073
+:10BDD0000000000000000000000000000000000063
+:10BDE0000000000000000000000000000000000053
+:10BDF0000000000000000000000000000000000043
+:10BE00000000000000000000000000000000000032
+:10BE10000000000000000000000000000000000022
+:10BE20000000000000000000000000000000000012
+:10BE30000000000000000000000000000000000002
+:10BE400000000000000000000000000000000000F2
+:10BE500000000000000000000000000000000000E2
+:10BE600000000000000000000000000000000000D2
+:10BE700000000000000000000000000000000000C2
+:10BE800000000000000000000000000000000000B2
+:10BE900000000000000000000000000000000000A2
+:10BEA0000000000000000000000000000000000092
+:10BEB0000000000000000000000000000000000082
+:10BEC0000000000000000000000000000000000072
+:10BED0000000000000000000000000000000000062
+:10BEE0000000000000000000000000000000000052
+:10BEF0000000000000000000000000000000000042
+:10BF00000000000000000000000000000000000031
+:10BF10000000000000000000000000000000000021
+:10BF20000000000000000000000000000000000011
+:10BF30000000000000000000000000000000000001
+:10BF400000000000000000000000000000000000F1
+:10BF500000000000000000000000000000000000E1
+:10BF600000000000000000000000000000000000D1
+:10BF700000000000000000000000000000000000C1
+:10BF800000000000000000000000000000000000B1
+:10BF900000000000000000000000000000000000A1
+:10BFA0000000000000000000000000000000000091
+:10BFB0000000000000000000000000000000000081
+:10BFC0000000000000000000000000000000000071
+:10BFD0000000000000000000000000000000000061
+:10BFE0000000000000000000000000000000000051
+:10BFF0000000000000000000000000000000000041
+:10C000000000000000000000000000000000000030
+:10C010000000000000000000000000000000000020
+:10C020000000000000000000000000000000000010
+:10C030000000000000000000000000000000000000
+:10C0400000000000000000000000000000000000F0
+:10C0500000000000000000000000000000000000E0
+:10C0600000000000000000000000000000000000D0
+:10C0700000000000000000000000000000000000C0
+:10C0800000000000000000000000000000000000B0
+:10C0900000000000000000000000000000000000A0
+:10C0A0000000000000000000000000000000000090
+:10C0B0000000000000000000000000000000000080
+:10C0C0000000000000000000000000000000000070
+:10C0D0000000000000000000000000000000000060
+:10C0E0000000000000000000000000000000000050
+:10C0F0000000000000000000000000000000000040
+:10C10000000000000000000000000000000000002F
+:10C11000000000000000000000000000000000001F
+:10C12000000000000000000000000000000000000F
+:10C1300000000000000000000000000000000000FF
+:10C1400000000000000000000000000000000000EF
+:10C1500000000000000000000000000000000000DF
+:10C1600000000000000000000000000000000000CF
+:10C1700000000000000000000000000000000000BF
+:10C1800000000000000000000000000000000000AF
+:10C19000000000000000000000000000000000009F
+:10C1A000000000000000000000000000000000008F
+:10C1B000000000000000000000000000000000007F
+:10C1C000000000000000000000000000000000006F
+:10C1D000000000000000000000000000000000005F
+:10C1E000000000000000000000000000000000004F
+:10C1F000000000000000000000000000000000003F
+:10C20000000000000000000000000000000000002E
+:10C21000000000000000000000000000000000001E
+:10C22000000000000000000000000000000000000E
+:10C2300000000000000000000000000000000000FE
+:10C2400000000000000000000000000000000000EE
+:10C2500000000000000000000000000000000000DE
+:10C2600000000000000000000000000000000000CE
+:10C2700000000000000000000000000000000000BE
+:10C2800000000000000000000000000000000000AE
+:10C29000000000000000000000000000000000009E
+:10C2A000000000000000000000000000000000008E
+:10C2B000000000000000000000000000000000007E
+:10C2C000000000000000000000000000000000006E
+:10C2D000000000000000000000000000000000005E
+:10C2E000000000000000000000000000000000004E
+:10C2F000000000000000000000000000000000003E
+:10C30000000000000000000000000000000000002D
+:10C31000000000000000000000000000000000001D
+:10C32000000000000000000000000000000000000D
+:10C3300000000000000000000000000000000000FD
+:10C3400000000000000000000000000000000000ED
+:10C3500000000000000000000000000000000000DD
+:10C3600000000000000000000000000000000000CD
+:10C3700000000000000000000000000000000000BD
+:10C3800000000000000000000000000000000000AD
+:10C39000000000000000000000000000000000009D
+:10C3A000000000000000000000000000000000008D
+:10C3B000000000000000000000000000000000007D
+:10C3C000000000000000000000000000000000006D
+:10C3D000000000000000000000000000000000005D
+:10C3E000000000000000000000000000000000004D
+:10C3F000000000000000000000000000000000003D
+:10C40000000000000000000000000000000000002C
+:10C41000000000000000000000000000000000001C
+:10C42000000000000000000000000000000000000C
+:10C4300000000000000000000000000000000000FC
+:10C4400000000000000000000000000000000000EC
+:10C4500000000000000000000000000000000000DC
+:10C4600000000000000000000000000000000000CC
+:10C4700000000000000000000000000000000000BC
+:10C4800000000000000000000000000000000000AC
+:10C49000000000000000000000000000000000009C
+:10C4A000000000000000000000000000000000008C
+:10C4B000000000000000000000000000000000007C
+:10C4C000000000000000000000000000000000006C
+:10C4D000000000000000000000000000000000005C
+:10C4E000000000000000000000000000000000004C
+:10C4F000000000000000000000000000000000003C
+:10C50000000000000000000000000000000000002B
+:10C51000000000000000000000000000000000001B
+:10C52000000000000000000000000000000000000B
+:10C5300000000000000000000000000000000000FB
+:10C5400000000000000000000000000000000000EB
+:10C5500000000000000000000000000000000000DB
+:10C5600000000000000000000000000000000000CB
+:10C5700000000000000000000000000000000000BB
+:10C5800000000000000000000000000000000000AB
+:10C59000000000000000000000000000000000009B
+:10C5A000000000000000000000000000000000008B
+:10C5B000000000000000000000000000000000007B
+:10C5C000000000000000000000000000000000006B
+:10C5D000000000000000000000000000000000005B
+:10C5E000000000000000000000000000000000004B
+:10C5F000000000000000000000000000000000003B
+:10C60000000000000000000000000000000000002A
+:10C61000000000000000000000000000000000001A
+:10C62000000000000000000000000000000000000A
+:10C6300000000000000000000000000000000000FA
+:10C6400000000000000000000000000000000000EA
+:10C6500000000000000000000000000000000000DA
+:10C6600000000000000000000000000000000000CA
+:10C6700000000000000000000000000000000000BA
+:10C6800000000000000000000000000000000000AA
+:10C69000000000000000000000000000000000009A
+:10C6A000000000000000000000000000000000008A
+:10C6B000000000000000000000000000000000007A
+:10C6C000000000000000000000000000000000006A
+:10C6D000000000000000000000000000000000005A
+:10C6E000000000000000000000000000000000004A
+:10C6F000000000000000000000000000000000003A
+:10C700000000000000000000000000000000000029
+:10C710000000000000000000000000000000000019
+:10C720000000000000000000000000000000000009
+:10C7300000000000000000000000000000000000F9
+:10C7400000000000000000000000000000000000E9
+:10C7500000000000000000000000000000000000D9
+:10C7600000000000000000000000000000000000C9
+:10C7700000000000000000000000000000000000B9
+:10C7800000000000000000000000000000000000A9
+:10C790000000000000000000000000000000000099
+:10C7A0000000000000000000000000000000000089
+:10C7B0000000000000000000000000000000000079
+:10C7C0000000000000000000000000000000000069
+:10C7D0000000000000000000000000000000000059
+:10C7E0000000000000000000000000000000000049
+:10C7F0000000000000000000000000000000000039
+:10C800000000000000000000000000000000000028
+:10C810000000000000000000000000000000000018
+:10C820000000000000000000000000000000000008
+:10C8300000000000000000000000000000000000F8
+:10C8400000000000000000000000000000000000E8
+:10C8500000000000000000000000000000000000D8
+:10C8600000000000000000000000000000000000C8
+:10C8700000000000000000000000000000000000B8
+:10C8800000000000000000000000000000000000A8
+:10C890000000000000000000000000000000000098
+:10C8A0000000000000000000000000000000000088
+:10C8B0000000000000000000000000000000000078
+:10C8C0000000000000000000000000000000000068
+:10C8D0000000000000000000000000000000000058
+:10C8E0000000000000000000000000000000000048
+:10C8F0000000000000000000000000000000000038
+:10C900000000000000000000000000000000000027
+:10C910000000000000000000000000000000000017
+:10C920000000000000000000000000000000000007
+:10C9300000000000000000000000000000000000F7
+:10C9400000000000000000000000000000000000E7
+:10C9500000000000000000000000000000000000D7
+:10C9600000000000000000000000000000000000C7
+:10C9700000000000000000000000000000000000B7
+:10C9800000000000000000000000000000000000A7
+:10C990000000000000000000000000000000000097
+:10C9A0000000000000000000000000000000000087
+:10C9B0000000000000000000000000000000000077
+:10C9C0000000000000000000000000000000000067
+:10C9D0000000000000000000000000000000000057
+:10C9E0000000000000000000000000000000000047
+:10C9F0000000000000000000000000000000000037
+:10CA00000000000000000000000000000000000026
+:10CA10000000000000000000000000000000000016
+:10CA20000000000000000000000000000000000006
+:10CA300000000000000000000000000000000000F6
+:10CA400000000000000000000000000000000000E6
+:10CA500000000000000000000000000000000000D6
+:10CA600000000000000000000000000000000000C6
+:10CA700000000000000000000000000000000000B6
+:10CA800000000000000000000000000000000000A6
+:10CA90000000000000000000000000000000000096
+:10CAA0000000000000000000000000000000000086
+:10CAB0000000000000000000000000000000000076
+:10CAC0000000000000000000000000000000000066
+:10CAD0000000000000000000000000000000000056
+:10CAE0000000000000000000000000000000000046
+:10CAF0000000000000000000000000000000000036
+:10CB00000000000000000000000000000000000025
+:10CB10000000000000000000000000000000000015
+:10CB20000000000000000000000000000000000005
+:10CB300000000000000000000000000000000000F5
+:10CB400000000000000000000000000000000000E5
+:10CB500000000000000000000000000000000000D5
+:10CB600000000000000000000000000000000000C5
+:10CB700000000000000000000000000000000000B5
+:10CB800000000000000000000000000000000000A5
+:10CB90000000000000000000000000000000000095
+:10CBA0000000000000000000000000000000000085
+:10CBB0000000000000000000000000000000000075
+:10CBC0000000000000000000000000000000000065
+:10CBD0000000000000000000000000000000000055
+:10CBE0000000000000000000000000000000000045
+:10CBF0000000000000000000000000000000000035
+:10CC00000000000000000000000000000000000024
+:10CC10000000000000000000000000000000000014
+:10CC20000000000000000000000000000000000004
+:10CC300000000000000000000000000000000000F4
+:10CC400000000000000000000000000000000000E4
+:10CC500000000000000000000000000000000000D4
+:10CC600000000000000000000000000000000000C4
+:10CC700000000000000000000000000000000000B4
+:10CC800000000000000000000000000000000000A4
+:10CC90000000000000000000000000000000000094
+:10CCA0000000000000000000000000000000000084
+:10CCB0000000000000000000000000000000000074
+:10CCC0000000000000000000000000000000000064
+:10CCD0000000000000000000000000000000000054
+:10CCE0000000000000000000000000000000000044
+:10CCF0000000000000000000000000000000000034
+:10CD00000000000000000000000000000000000023
+:10CD10000000000000000000000000000000000013
+:10CD20000000000000000000000000000000000003
+:10CD300000000000000000000000000000000000F3
+:10CD400000000000000000000000000000000000E3
+:10CD500000000000000000000000000000000000D3
+:10CD600000000000000000000000000000000000C3
+:10CD700000000000000000000000000000000000B3
+:10CD800000000000000000000000000000000000A3
+:10CD90000000000000000000000000000000000093
+:10CDA0000000000000000000000000000000000083
+:10CDB0000000000000000000000000000000000073
+:10CDC0000000000000000000000000000000000063
+:10CDD0000000000000000000000000000000000053
+:10CDE0000000000000000000000000000000000043
+:10CDF0000000000000000000000000000000000033
+:10CE00000000000000000000000000000000000022
+:10CE10000000000000000000000000000000000012
+:10CE20000000000000000000000000000000000002
+:10CE300000000000000000000000000000000000F2
+:10CE400000000000000000000000000000000000E2
+:10CE500000000000000000000000000000000000D2
+:10CE600000000000000000000000000000000000C2
+:10CE700000000000000000000000000000000000B2
+:10CE800000000000000000000000000000000000A2
+:10CE90000000000000000000000000000000000092
+:10CEA0000000000000000000000000000000000082
+:10CEB0000000000000000000000000000000000072
+:10CEC0000000000000000000000000000000000062
+:10CED0000000000000000000000000000000000052
+:10CEE0000000000000000000000000000000000042
+:10CEF0000000000000000000000000000000000032
+:10CF00000000000000000000000000000000000021
+:10CF10000000000000000000000000000000000011
+:10CF20000000000000000000000000000000000001
+:10CF300000000000000000000000000000000000F1
+:10CF400000000000000000000000000000000000E1
+:10CF500000000000000000000000000000000000D1
+:10CF600000000000000000000000000000000000C1
+:10CF700000000000000000000000000000000000B1
+:10CF800000000000000000000000000000000000A1
+:10CF90000000000000000000000000000000000091
+:10CFA0000000000000000000000000000000000081
+:10CFB0000000000000000000000000000000000071
+:10CFC0000000000000000000000000000000000061
+:10CFD0000000000000000000000000000000000051
+:10CFE0000000000000000000000000000000000041
+:10CFF0000000000000000000000000000000000031
+:10D000000000000000000000000000000000000020
+:10D010000000000000000000000000000000000010
+:10D020000000000000000000000000000000000000
+:10D0300000000000000000000000000000000000F0
+:10D0400000000000000000000000000000000000E0
+:10D0500000000000000000000000000000000000D0
+:10D0600000000000000000000000000000000000C0
+:10D0700000000000000000000000000000000000B0
+:10D0800000000000000000000000000000000000A0
+:10D090000000000000000000000000000000000090
+:10D0A0000000000000000000000000000000000080
+:10D0B0000000000000000000000000000000000070
+:10D0C0000000000000000000000000000000000060
+:10D0D0000000000000000000000000000000000050
+:10D0E0000000000000000000000000000000000040
+:10D0F0000000000000000000000000000000000030
+:10D10000000000000000000000000000000000001F
+:10D11000000000000000000000000000000000000F
+:10D1200000000000000000000000000000000000FF
+:10D1300000000000000000000000000000000000EF
+:10D1400000000000000000000000000000000000DF
+:10D1500000000000000000000000000000000000CF
+:10D1600000000000000000000000000000000000BF
+:10D1700000000000000000000000000000000000AF
+:10D18000000000000000000000000000000000009F
+:10D19000000000000000000000000000000000008F
+:10D1A000000000000000000000000000000000007F
+:10D1B000000000000000000000000000000000006F
+:10D1C000000000000000000000000000000000005F
+:10D1D000000000000000000000000000000000004F
+:10D1E000000000000000000000000000000000003F
+:10D1F000000000000000000000000000000000002F
+:10D20000000000000000000000000000000000001E
+:10D21000000000000000000000000000000000000E
+:10D2200000000000000000000000000000000000FE
+:10D2300000000000000000000000000000000000EE
+:10D2400000000000000000000000000000000000DE
+:10D2500000000000000000000000000000000000CE
+:10D2600000000000000000000000000000000000BE
+:10D2700000000000000000000000000000000000AE
+:10D28000000000000000000000000000000000009E
+:10D29000000000000000000000000000000000008E
+:10D2A000000000000000000000000000000000007E
+:10D2B000000000000000000000000000000000006E
+:10D2C000000000000000000000000000000000005E
+:10D2D000000000000000000000000000000000004E
+:10D2E000000000000000000000000000000000003E
+:10D2F000000000000000000000000000000000002E
+:10D30000000000000000000000000000000000001D
+:10D31000000000000000000000000000000000000D
+:10D3200000000000000000000000000000000000FD
+:10D3300000000000000000000000000000000000ED
+:10D3400000000000000000000000000000000000DD
+:10D3500000000000000000000000000000000000CD
+:10D3600000000000000000000000000000000000BD
+:10D3700000000000000000000000000000000000AD
+:10D38000000000000000000000000000000000009D
+:10D39000000000000000000000000000000000008D
+:10D3A000000000000000000000000000000000007D
+:10D3B000000000000000000000000000000000006D
+:10D3C000000000000000000000000000000000005D
+:10D3D000000000000000000000000000000000004D
+:10D3E000000000000000000000000000000000003D
+:10D3F000000000000000000000000000000000002D
+:10D40000000000000000000000000000000000001C
+:10D41000000000000000000000000000000000000C
+:10D4200000000000000000000000000000000000FC
+:10D4300000000000000000000000000000000000EC
+:10D4400000000000000000000000000000000000DC
+:10D4500000000000000000000000000000000000CC
+:10D4600000000000000000000000000000000000BC
+:10D4700000000000000000000000000000000000AC
+:10D48000000000000000000000000000000000009C
+:10D49000000000000000000000000000000000008C
+:10D4A000000000000000000000000000000000007C
+:10D4B000000000000000000000000000000000006C
+:10D4C000000000000000000000000000000000005C
+:10D4D000000000000000000000000000000000004C
+:10D4E000000000000000000000000000000000003C
+:10D4F000000000000000000000000000000000002C
+:10D50000000000000000000000000000000000001B
+:10D51000000000000000000000000000000000000B
+:10D5200000000000000000000000000000000000FB
+:10D5300000000000000000000000000000000000EB
+:10D5400000000000000000000000000000000000DB
+:10D5500000000000000000000000000000000000CB
+:10D5600000000000000000000000000000000000BB
+:10D5700000000000000000000000000000000000AB
+:10D58000000000000000000000000000000000009B
+:10D59000000000000000000000000000000000008B
+:10D5A000000000000000000000000000000000007B
+:10D5B000000000000000000000000000000000006B
+:10D5C000000000000000000000000000000000005B
+:10D5D000000000000000000000000000000000004B
+:10D5E000000000000000000000000000000000003B
+:10D5F000000000000000000000000000000000002B
+:10D60000000000000000000000000000000000001A
+:10D61000000000000000000000000000000000000A
+:10D6200000000000000000000000000000000000FA
+:10D6300000000000000000000000000000000000EA
+:10D6400000000000000000000000000000000000DA
+:10D6500000000000000000000000000000000000CA
+:10D6600000000000000000000000000000000000BA
+:10D6700000000000000000000000000000000000AA
+:10D68000000000000000000000000000000000009A
+:10D69000000000000000000000000000000000008A
+:10D6A000000000000000000000000000000000007A
+:10D6B000000000000000000000000000000000006A
+:10D6C000000000000000000000000000000000005A
+:10D6D000000000000000000000000000000000004A
+:10D6E000000000000000000000000000000000003A
+:10D6F000000000000000000000000000000000002A
+:10D700000000000000000000000000000000000019
+:10D710000000000000000000000000000000000009
+:10D7200000000000000000000000000000000000F9
+:10D7300000000000000000000000000000000000E9
+:10D7400000000000000000000000000000000000D9
+:10D7500000000000000000000000000000000000C9
+:10D7600000000000000000000000000000000000B9
+:10D7700000000000000000000000000000000000A9
+:10D780000000000000000000000000000000000099
+:10D790000000000000000000000000000000000089
+:10D7A0000000000000000000000000000000000079
+:10D7B0000000000000000000000000000000000069
+:10D7C0000000000000000000000000000000000059
+:10D7D0000000000000000000000000000000000049
+:10D7E0000000000000000000000000000000000039
+:10D7F0000000000000000000000000000000000029
+:10D800000000000000000000000000000000000018
+:10D810000000000000000000000000000000000008
+:10D8200000000000000000000000000000000000F8
+:10D8300000000000000000000000000000000000E8
+:10D8400000000000000000000000000000000000D8
+:10D8500000000000000000000000000000000000C8
+:10D8600000000000000000000000000000000000B8
+:10D8700000000000000000000000000000000000A8
+:10D880000000000000000000000000000000000098
+:10D890000000000000000000100000030000000075
+:10D8A0000000000D0000000D3C020801244282200F
+:10D8B0003C030801246382E0AC4000000043202BBD
+:10D8C0001480FFFD244200043C1D080037BD9FFC6E
+:10D8D00003A0F0213C100800261031D83C1C0801A0
+:10D8E000279C82200E0011EA000000000000000DBD
+:10D8F0003C02800030A5FFFF30C600FF34430180AA
+:10D900003C0880008D0901B80520FFFE00000000E2
+:10D91000AC64000024040002A4650008A066000AAC
+:10D92000A064000BAC6700183C03100003E0000883
+:10D93000AD0301B83C0560008CA24FF80440FFFE27
+:10D9400000000000ACA44FC03C0310003C040200E7
+:10D95000ACA44FC403E00008ACA34FF89486000CBD
+:10D9600000A050212488001400062B02000510801E
+:10D97000004448210109182B10600011000000002C
+:10D98000910300002C6400095080000991190001E6
+:10D99000000360803C0D080125AD80E4018D582115
+:10D9A0008D67000000E000080000000091190001F0
+:10D9B000011940210109302B54C0FFF291030000EE
+:10D9C00003E00008000010210A000CBE2508000139
+:10D9D000910F0001240E000A15EE00400128C82313
+:10D9E0002F38000A1700003D250D00028D58000059
+:10D9F000250F0006370E0100AD4E0000910C00020D
+:10DA000091AB000191A4000291A60003000C2E002E
+:10DA1000000B3C0000A7102500041A000043C82595
+:10DA20000326C025AD580004910E000691ED0001BB
+:10DA300091E7000291E50003000E5E00000D640016
+:10DA4000016C30250007220000C410250045182570
+:10DA50002508000A0A000CBEAD430008910F000122
+:10DA6000250400022408000255E8000101202021BD
+:10DA70000A000CBE00804021910C0001240B000321
+:10DA8000158B0016000000008D580000910E00025A
+:10DA900025080003370D0008A14E00100A000CBE37
+:10DAA000AD4D000091190001240F0004172F000B49
+:10DAB0000000000091070002910400038D43000064
+:10DAC00000072A0000A4102534660004250800047D
+:10DAD000AD42000C0A000CBEAD46000003E0000899
+:10DAE0002402000127BDFFE8AFBF0014AFB0001053
+:10DAF0000E0014E0008080213C0480083485008002
+:10DB000090A600052403FFFE0200202100C310247C
+:10DB10008FBF00148FB00010A0A200050A0014EA05
+:10DB200027BD001827BDFFE8AFB00010AFBF00143D
+:10DB30000E000F4E008080213C06800834C5008016
+:10DB400090A4000024020050308300FF1062000700
+:10DB50003C098000020020218FBF00148FB000100C
+:10DB6000AD2001800A00101027BD00182408010014
+:10DB70003C078000020020218FBF00148FB00010EE
+:10DB8000ACE801800A00101027BD001827BDFF7007
+:10DB90003C088008AFB60080AFB5007CAFB1006C28
+:10DBA000AFBF008CAFBE0088AFB70084AFB40078C1
+:10DBB000AFB30074AFB20070AFB00068350500803D
+:10DBC0003C0780008CF2012890A40009ACE000849E
+:10DBD00090A60005309100FF0000A821000618273C
+:10DBE000306200010000B02114400067AFA0005077
+:10DBF00090A9000024050020312400FF10850016A4
+:10DC0000240A0050108A008C000000003C0C080020
+:10DC10008D8C00DC258B00013C010800AC2B00DC66
+:10DC20000E0015D6000000008FBF008C8FBE00884C
+:10DC30008FB700848FB600808FB5007C8FB40078DA
+:10DC40008FB300748FB200708FB1006C8FB000681A
+:10DC500003E0000827BD00900000000D3C1080008C
+:10DC6000AFA00030961F01168E1901043C1E002043
+:10DC700036130C00033EC0240018B82B00173140A7
+:10DC8000AFA600308E0E010433F4FFFF3C0F0040BE
+:10DC90000293802101CF68249213000D11A0004847
+:10DCA00034C40040326200201440000234860080F8
+:10DCB0000080302114C00093AFA600303C058008DE
+:10DCC00034A800809107000830E6004050C00006EC
+:10DCD0003C06800824090004122900A2240A00122C
+:10DCE000122A00293C06800834D401003C17800029
+:10DCF00096EF011A960D000E928E0008326B00040A
+:10DD000031F7FFFF01CD6004AFAC00548E14000466
+:10DD1000116000318E1E000834C300809079000825
+:10DD20003338004017000028000000008C730050BA
+:10DD300002939023064000063C0C80008C7E003449
+:10DD4000029E8023060200838EA200083C0C800005
+:10DD5000AD800044240200018FBF008C8FBE00887C
+:10DD60008FB700848FB600808FB5007C8FB40078A9
+:10DD70008FB300748FB200708FB1006C8FB00068E9
+:10DD800003E0000827BD00900E000D1A00002021BE
+:10DD90008FBF008C8FBE00888FB700848FB6008045
+:10DDA0008FB5007C8FB400788FB300748FB2007091
+:10DDB0008FB1006C8FB0006803E0000827BD0090B1
+:10DDC0000A000D7A00C020210E00163702802021A3
+:10DDD0001440FFDF3C0C80003C038008346300806B
+:10DDE0008C6200340282F82307E000170000000074
+:10DDF0003C1508008EB5310026B100013C01080039
+:10DE0000AC3131000E0014E0024020213C0B8008B0
+:10DE100035700080920A002502402021354200041E
+:10DE20000E0014EAA20200250E000C9E02402021E2
+:10DE30000A000DA7240200013C15080126B582D076
+:10DE40000A000D693C1080008C6600300286202399
+:10DE5000188000082409000C3C0808008D083100D7
+:10DE6000327300FC0000B821250700013C010800C6
+:10DE7000AC273100AFA900308C65003000B43823E6
+:10DE800018E000DB02E7502A1540FFDE000000002A
+:10DE900012E7002A02E768230287A02131B7FFFFBB
+:10DEA000326E000211C00034327F00103C14800832
+:10DEB00036900080920F000831F6004052C000CE2C
+:10DEC0008EA20008024020210E0014E02413001846
+:10DED000A2130009921800052419FFFE0240202118
+:10DEE0000319B8240E0014EAA2170005240400390F
+:10DEF000000028210E001612240600180A000DA7A3
+:10DF00002402000192B6000C3C0480083483008097
+:10DF10008C6700380016AB0036B10081024020212A
+:10DF20003225F0810E000C8D30C600FF3C0C8000C5
+:10DF3000AD8000440A000DA7240200013A6C0001E4
+:10DF4000318B00011560FFAF0287A0210A000DF898
+:10DF5000000000000040F809240400160A000DA784
+:10DF600024020001024020210E0017170200282180
+:10DF70000A000D5C8FBF008C13E0FF743C03800827
+:10DF8000346800808D0400388C66000403C61023BA
+:10DF90001C40FF6F3C0C800003C4282304A2000136
+:10DFA0000080F021AFB40010AFB70014AFA7001885
+:10DFB0003C1F800097E301208D0900309506005C2E
+:10DFC0008FB900548FAC00303062FFFF30D8FFFFB4
+:10DFD0000047702137EF40000338682B01CF5821EC
+:10DFE000018D5025AFAB0020AFA90028AFAA0030AB
+:10DFF000AFA90024AFA0002CAFBE003491070008E9
+:10E0000030E400081480008F020020218EA200045A
+:10E010000040F80927A400108FA900303128000221
+:10E0200055000001327300FE3C048008348C0080EF
+:10E03000918B0008316A0040514000128FA40024E7
+:10E040008C8D000411BE00BE240E00143265000148
+:10E0500010A0000C8FA400242404000C122400D46F
+:10E060002A27000D10E000CE2409000E2408000A23
+:10E0700052280001241600088FA200242444000125
+:10E08000AFA400248FA600143C03800834650080F0
+:10E090000086F8218CB10030ACBF003090B9004E42
+:10E0A0008CAE00303418FFFF0338780401CF6821AC
+:10E0B000ACAD00348FA600308FAC005430CA0008DD
+:10E0C00003CC58211140000CAFAB00588CA40020A9
+:10E0D0008FB000581090009430C600FF92A2000C40
+:10E0E0008FA700340240202100024B003528008019
+:10E0F0000E000C8D3105F0803C0C800835900080BE
+:10E100008E0B003001715023194000702659008099
+:10E110003C1808008F183198241FFF80033F782493
+:10E12000332D007F3C0680003C0E8004331100102C
+:10E13000ACCF00901220003401AE282190A3006BD8
+:10E14000546000323C10800824070001A0A7006B37
+:10E1500094C4007A2486000AA60600123C0D8008AA
+:10E1600035A5008090B10008322C004015800004D5
+:10E170003C038008326E000115C000620000000000
+:10E18000346400808C8F00208FB3005811F3000A94
+:10E19000346301008C7900000299C0231B000077D2
+:10E1A0008FA80058AC880020AC7400002414000133
+:10E1B000AC7E0004AFB4005016C000370000000071
+:10E1C0008FA40050148000300000000012E0000511
+:10E1D000000018218FA900303137000452E0FE9270
+:10E1E00000601021240300010A000D5B0060102173
+:10E1F0000A000DF9000038210040F8092404001736
+:10E200000A000DA7240200013C108008361000808F
+:10E2100024090001024020210E0014E0A60900128A
+:10E220009208002524050001AFA500503502000129
+:10E23000024020210E0014EAA20200250A000EA9C5
+:10E240003C0D800827A50038AFA800600E000CA880
+:10E25000AFA000381440FF6D8FA800608FA5003874
+:10E2600030B001005200FF6A8EA200048FA3003C70
+:10E270008D070058006720230483FF64AD03005816
+:10E280000A000E558EA200040E000C9E02402021B2
+:10E290000A000EC4000000000E0014E0024020211D
+:10E2A0003C05800834A30080024020210E0014EABF
+:10E2B000A076000902C03021240400370E00161297
+:10E2C000000028210A000EC28FA400508FA200185F
+:10E2D0005840FFA33C0D80080E0014E002402021AE
+:10E2E000920A0025240B0001AFAB00503542000418
+:10E2F000024020210E0014EAA20200250A000EA905
+:10E300003C0D80088CB600308EBE00082404001836
+:10E3100026D5000103C0F809ACB500308FB200303B
+:10E320000A000D5B324200043C07800094E5011AAC
+:10E3300050A0FF6A34C600100A000E8992A2000C99
+:10E34000122E002A2A2F001511E0001E2419001693
+:10E350002418000C5638FF3E326500013C1F80082F
+:10E3600093E3001B2410FFBD2416000E0070302420
+:10E37000A3E6001B0A000E65326500018C7F0000D9
+:10E3800017F4FF8D000000008C67000403C73023E2
+:10E3900004C1FF848FA800580A000EBF00000000CF
+:10E3A0001629FF368FA200240A000E7024160010D2
+:10E3B0002411000E52D1FF30241600100A000E6FF7
+:10E3C000241600165639FF22326500013C1F8008D2
+:10E3D00093E3001B2410FFBD2416001000703024AE
+:10E3E000A3E6001B0A000E65326500010A000E64F8
+:10E3F000241600123C0380008C6201B80440FFFE2A
+:10E4000024040800AC6401B803E000080000000028
+:10E4100030A5FFFF30C6FFFF3C0780008CE201B84B
+:10E420000440FFFE34E80180AD040000ACE40020AD
+:10E430003C048008948300483063FFFF1060001D97
+:10E440003C0B800024AA0012006A482B5120001ABD
+:10E45000240A000394F901208F890000240C001A7B
+:10E460003338FFFF2707FFFE0067782B39EE0001E6
+:10E4700000096B8201AE5824A10C000B116000470B
+:10E480008F830004A50700148F880004350700015E
+:10E49000AF87000430CC00405580000F3C0880005E
+:10E4A0003C0C800035840180A485000E0A000F9882
+:10E4B0008F8F000C240A00033564018030CC0040AB
+:10E4C0008F8900008F870004A08A000B5180FFF520
+:10E4D0003C0C80003C088000950301203C0880082B
+:10E4E000951800403079FFFF272EFFFE330FFFFF06
+:10E4F00001CF682B11A0000301C02021950200402C
+:10E500003044FFFF3C0B800000A4502335650180A0
+:10E51000A4A4000EA4AA00248F8F000C3C05800048
+:10E5200034AE01802418000230ED8000A5D8000C24
+:10E53000A5C90010ADCF0028A5C6000811A0000E87
+:10E540003C04800094AA01163142FFFC24480004D8
+:10E55000010518218C7940003326FFFF14C0000705
+:10E56000240EBFFF3C0BFFFF35657FFF00E538241D
+:10E57000AF8700043C048000240EBFFF348C018070
+:10E5800000EE6824A58D0026AD89002C3C07100004
+:10E59000AC8701B803E00008000000002402FFFE81
+:10E5A000006238240A000F76AF8700043C05800023
+:10E5B00034A400708C8A000090A601128F840000A1
+:10E5C00027BDFFF030C300FF000318823082010036
+:10E5D00000003821104000392466000330874000D5
+:10E5E00050E0003930882000000610800045C82126
+:10E5F0008F2F40002478000400187080AFAF000017
+:10E6000001C568218DAC4000AFAC000494AB01168D
+:10E610003169FFFC012540218D054000AFA50008B0
+:10E620008FA9000800003021000028213C070800C5
+:10E6300024E701000A000FE92408000890420000C6
+:10E6400024A500012CAD000C0062C8210019C08077
+:10E65000030778218DEE000011A0000600CE3026C1
+:10E6600003A5102114A8FFF500051A005520FFF49A
+:10E67000904200003C048000348700703C05080094
+:10E680008CA531048CE300002CA8002011000009A7
+:10E69000006A3823000558803C0C0800258C31089E
+:10E6A000016C482124AA0001AD2700003C010800AC
+:10E6B000AC2A3104AF86000C2407000100E01021D1
+:10E6C00003E0000827BD00101100FFFC0000382106
+:10E6D00000066080018558218D6440002469000493
+:10E6E00000093880AFA4000000E518218C664000C6
+:10E6F000AFA000080A000FD9AFA6000427BDFFD8BD
+:10E70000AFB20018AFB00010AFBF0024AFB400200C
+:10E71000AFB3001CAFB100148F8700003C04800031
+:10E720009483010E30E24000000080211040001070
+:10E730003072FFFF3C06002000E6282410A0000DE8
+:10E7400030EA80008F8800042409BFFF00E93824E4
+:10E7500035031000AF87000030F120001620000BB9
+:10E760003C1400042418FFBF0A001038007810245D
+:10E7700030EA8000154000863C0C002030F120007B
+:10E780001220FFF88F8300043C14000400F4982446
+:10E790001260FFF52418FFBF3462004030F9010019
+:10E7A0001320000FAF8200043C02002000E2F82496
+:10E7B00013E000053C0B80003C04000400E4182436
+:10E7C000106000CF00000000956A011E9569011CD1
+:10E7D0003146FFFF0009440000C82825AF85000C22
+:10E7E0003C0E800095CD010C8DC44000340CFFFF21
+:10E7F000108C00B031A5FFFF308F010055E0000103
+:10E800002410001030F110005220000836110001D1
+:10E8100030F300201660009F3C18100000F8A02480
+:10E82000168000963C040C003611000130E801000F
+:10E830001500000B3C0A00018F88000431094000DC
+:10E840001520000800EA30243C0C1F0100EC58247D
+:10E850003C0A1000516A00AE30AD02003C0A0001D3
+:10E8600000EA302414C000953C05100000E5202487
+:10E8700000004021108000070000902100079E0248
+:10E880003272000F001278803C0E080125CE828083
+:10E8900001EE40218F940018128000470220802151
+:10E8A00010800091000000003C0980009539010EA5
+:10E8B00091030000022030213338FFFF27050004B8
+:10E8C000106000080000A021241F0003107F013AFF
+:10E8D00024040002910C00011184011830EA004068
+:10E8E0000012A1C08F92001C524000013626004049
+:10E8F0003C1380008E6F400031F10100122000CBEC
+:10E9000030D1FFFB3C1808008F18002430D20004DF
+:10E910003306000414C000CC30B0FFFF56400001A5
+:10E920003631000402802021020028210E000F55FC
+:10E93000022030211640000D0000202136650180A4
+:10E940003C0480008C9301B80660FFFE241920006F
+:10E9500024140002A4B90008A0B4000BA4A0001065
+:10E960003C051000AC8501B8000020218FBF0024B9
+:10E970008FB400208FB3001C8FB200188FB1001429
+:10E980008FB000100080102103E0000827BD002890
+:10E9900000EC58241160FF7A30F120008F8D0004C4
+:10E9A0003C0FFFFF35EE7FFF00EE382435A38000DB
+:10E9B0000A001027AF8700003C0208008C42003894
+:10E9C0003C040800248400381040004B2449FFFF19
+:10E9D0003C038000946C010E318BFFFF110000A0FE
+:10E9E000257300043C1008008E1000301200000A4D
+:10E9F00030E601008F8A00043143400010600006B9
+:10EA00003C0F0F0000EF70243C0D010001AE402BC5
+:10EA1000110000DF3265FFFF10C000693C140F00D9
+:10EA200000F428243C18020010B800658F99000CEF
+:10EA30003270FFFF03299824026490219249000458
+:10EA400025270004000721C00200282136260002E5
+:10EA50000E000F55000000008FBF00248FB400206F
+:10EA60008FB3001C8FB200188FB100148FB000104C
+:10EA70000000102103E0000827BD00283C020BFF26
+:10EA800000E41824345FFFFF03E3C82B5320FF6723
+:10EA9000361100013C0608008CC6002C361100051A
+:10EAA00024D000013C010800AC30002C0A00105DAD
+:10EAB00030E801000A0010522410002002402821F2
+:10EAC0003C1208008E5200D824040080264D00011C
+:10EAD0003C010800AC2D00D80E000F5524060003A1
+:10EAE0000A0010E88FBF00243C0808012508828036
+:10EAF0000A00107C3C0980000A0010C50000482173
+:10EB00000E000FBC000000000A0010498F870000B3
+:10EB100015A0FF533C0A00012645000430AAFFFF60
+:10EB2000362600023C0380008C7201B80640FFFECE
+:10EB30008F85000834690180AD20000010A000AF6F
+:10EB40003C048000254F001200AF702B51C000AC78
+:10EB500024030003947801202414001A30F14000AB
+:10EB60003313FFFFA134000B122000B62663FFFE13
+:10EB700000A3C82B572000B4241FFFFE3508000156
+:10EB8000A5230014AF8800043C108000240CBFFFB4
+:10EB9000010C4824240B000236080180A50B000C50
+:10EBA000A50A000EA5060008A5090026A507001065
+:10EBB0003C071000AE0701B80A0010E88FBF002420
+:10EBC0003C0308008C6300D02E45000C001221C0CD
+:10EBD000386B00012D6200010045F82417E0FF9A10
+:10EBE0003270FFFF264CFFFC2D840004548000503F
+:10EBF00000002021386A00022D43000100658024B6
+:10EC00001600004A3270FFFF00076A420012702BA4
+:10EC100001AE40245500006300002021001221C0F5
+:10EC2000020028210A0010E53626000234DF000227
+:10EC30000280202133E6FFFF0E000F5530A5FFFFB5
+:10EC40000A0010AC00002021240401000200282149
+:10EC50000E000F55022030210A001098000000001D
+:10EC60008C66400030CF010011E0003D30F801001B
+:10EC70003C1208008E5200241300001132340004AC
+:10EC80003C1F0F0000FFC8243C0502001325000CA8
+:10EC90008F8C000C022030213265FFFF018958243F
+:10ECA00001641021904900043230FFFB2411FFFE63
+:10ECB000252700040E000F55000721C002519024A3
+:10ECC0002404000112440052324300011460005831
+:10ECD00002003021324A0004114000048F8D0000F0
+:10ECE00031A808001500005A3265FFFF1680FF5B4F
+:10ECF0008FBF00243C138000366501803C048000F7
+:10ED00008C9001B80600FFFE24062000240F0002AC
+:10ED1000A4A60008A0AF000BA4A000103C0E100099
+:10ED2000AC8E01B80A0010E88FBF0024000020213B
+:10ED3000020028210A0010E5362600021140FEE9F3
+:10ED40000000A021952E0110950D000231C8FFFF93
+:10ED500051A8FEE40012A1C00A00108B8F92001C83
+:10ED60003C0508008CA5002430B800015300FF3B8F
+:10ED70008FBF00243265FFFF3626000200002021ED
+:10ED80000E000F55000000000A0010E88FBF00249D
+:10ED9000362600020E000F55240400800A0010E8F9
+:10EDA0008FBF0024020028210E000F553226FFFBE2
+:10EDB0000A001159001221C0910300012402000130
+:10EDC0001062FEEA24040001241000021470FEC543
+:10EDD0000000A02130E300401060FEC38F92001CB1
+:10EDE000952B0110950900023167FFFF1127FEE006
+:10EDF0008FBF00240A00108B0000000024030003D2
+:10EE000034820180A043000B0A0011343C108000C2
+:10EE100032140004168000033265FFFF3612000230
+:10EE20003250FFFF020030210A0011B10000202102
+:10EE3000000020210E000F553265FFFF0A001186E9
+:10EE40003210FFFB241FFFFE0A001132011F402475
+:10EE5000020030210E000F55240401000A00118C1D
+:10EE60000000000027BDFFC8AFB00010AFBF0034E6
+:10EE70003C10600CAFBE0030AFB7002CAFB600281E
+:10EE8000AFB50024AFB40020AFB3001CAFB2001880
+:10EE9000AFB100148E0C5000240DFF7F3C058000A4
+:10EEA000018D5824356A380C24090003AE0A50003D
+:10EEB000ACA900083C010800AC2000200E0017435C
+:10EEC000000000003C0560168CA700003C08FFFF16
+:10EED0003C06001034C3805100E820243C02535308
+:10EEE000AE03537C1082026134A37C008C74007CDE
+:10EEF0008C7500783C116000362420203C05080108
+:10EF000024A581142406000A3C1180003C13000251
+:10EF10003C12600CAF950010AF9400140E0015EC7D
+:10EF2000363E0180AE5353FC8E3000003216000393
+:10EF300012C0FFFD3217000116E000583206000231
+:10EF400010C0FFF93C0480008C8F01402410004069
+:10EF5000AC8F00208C9201480012760231C3007001
+:10EF60001070013D2C67004150E00008240400604F
+:10EF7000241500201075000E3C0340003C07800063
+:10EF8000ACE301780A00121B000000001464FFFBD0
+:10EF90003C0340000E001F5D000000003C034000E9
+:10EFA0003C078000ACE301780A00121B000000005F
+:10EFB0008C830148241400043487018000034C0230
+:10EFC000312500FF8C83014010B4017124BFFFFA8A
+:10EFD0002FF90006532000123C0580008C86014466
+:10EFE000241600FF30A500FF30CB00FF30CA00FF21
+:10EFF000115601BC256800042402000910A201AAD0
+:10F0000028AC000A118001962413000A240D000880
+:10F0100010AD00148F850018000819C03C05800051
+:10F020008CA801B80500FFFE24170002ACE3000025
+:10F03000A4E90008A0F7000B8CB401483C091000BB
+:10F040003C034000A4F400108CA40144ACE4002470
+:10F050003C078000ACA901B8ACE301780A00121BA0
+:10F060000000000000067A020008A8803C040801A5
+:10F070002484828024AE000102A4902131E500FFA7
+:10F0800024100001A24F000014B0FFE3AF8E00185F
+:10F09000000819C00A001258AF85001C8E340128E0
+:10F0A0003C028008AE3400208E2401048E2301002F
+:10F0B000945F0048AF840000AF83000433F9FFFF82
+:10F0C0000E000F4EAF9900083C1808008F1800C0C2
+:10F0D000130000248F8700003C0708008CE700C461
+:10F0E00024E600013C010800AC2600C43C0380007B
+:10F0F0008C6401243C076020ACE400140000000094
+:10F100003C0680003C154000ACD5013800000000F2
+:10F110005280FF8B32060002268C0140268D008033
+:10F120002409FF800189282401A99824001359404B
+:10F1300031A2007F0005B140318A007F3C1F2000D2
+:10F1400037E800020162C02502CAC8250328A025AD
+:10F150000308B825ACD70830ACD408300A00122117
+:10F16000320600023C05001000E54024150000A610
+:10F170008F8300043C0C08008D8C00203C0D800027
+:10F1800095AA010E258B000130E940003C010800E2
+:10F19000AC2B00203155FFFF112000B6000090215C
+:10F1A0003C0F002000EF702411C000B330F7800046
+:10F1B0008F9300042416BFFF00F638243663100036
+:10F1C000AF87000030E22000104000B62405FFBFEA
+:10F1D0003C08000400E8302410C000020065102440
+:10F1E0003462004030E901001120000EAF820004BB
+:10F1F0003C0B002000EB5024114000043C0D0004A7
+:10F2000000ED602411800139000000009637011ED6
+:10F210009636011C32EFFFFF00169C0001F37025AB
+:10F22000AF8E000C9639010C8E2440003418FFFF7D
+:10F23000109800CA3325FFFF309F010057E00001FE
+:10F240002412001030E31000106000133653000148
+:10F2500030E400201480000A3C06100000E6102470
+:10F260001040000D3C0C0C003C0B0BFF00EC50243C
+:10F270003569FFFF012A402B1100000830EE010024
+:10F280003C0D08008DAD002C3653000525B2000161
+:10F290003C010800AC32002C30EE010015C0000B20
+:10F2A0003C0600018F880004310F400055E0000843
+:10F2B00000E628243C181F0100F8B8243C16100072
+:10F2C00052F6010E30B902003C06000100E6282487
+:10F2D00014A000A43C1F100000FF202400004021C7
+:10F2E000108000070000A82100075E023175000FA2
+:10F2F000001550803C0208012442828001424021D6
+:10F300008F8C001811800069026090211480000326
+:10F310003C0980003C080801250882809532010ED6
+:10F3200091030000026030213244FFFF2485000475
+:10F33000106000080000B821240D0003106D0122A8
+:10F34000241600029117000112F6002630F8004042
+:10F350000015B9C08F82001C504000013666004085
+:10F360003C1680008ECA400031530100126000C775
+:10F3700030D500043C0B08008D6B002430D3FFFB1C
+:10F380003166000414C0010A30B2FFFF56A000012C
+:10F390003673000402E02021024028210E000F55A0
+:10F3A0000260302116A0000D0000202136C501802A
+:10F3B0003C0480008C8C01B80580FFFE240D2000E9
+:10F3C00024120002A4AD0008A0B2000BA4A00010FB
+:10F3D0003C051000AC8501B8000020210A00135F35
+:10F3E000008010211300FFDB0000B821953F0110C1
+:10F3F0009519000233E8FFFF5328FFD60015B9C066
+:10F400000A0013278F82001C2413BFFF0073682497
+:10F4100011A00007240E87FF006E48241520000A63
+:10F420003C0F006000EF9024124000070000000035
+:10F430000E000D34000000001040FF323C0680003A
+:10F440000A00128D3C0380000E0014C90000000069
+:10F450000A00135F000000000E0014EF000000001F
+:10F460003C0340003C078000ACE301780A00121B1B
+:10F470000000000030F7800012E0FF528F8300048C
+:10F480003C19002000F9C0241300FF4E8F9F000498
+:10F490003C04FFFF34837FFF00E338240A0012C1DD
+:10F4A00037E380000A0012CA006510243C040800FB
+:10F4B0008C840038148000022489FFFF000048215A
+:10F4C0003C038000946F010E31EEFFFF110000EB52
+:10F4D00025D600043C0308008C6300301060000A4D
+:10F4E00030EA01008F9800043317400012E0000654
+:10F4F0003C020F0000E2F8243C190100033F402BBE
+:10F50000110000D532C5FFFF114000303C0C0F0048
+:10F5100000EC58243C0602001166002C000000009C
+:10F520008F95000C3C0D080025AD003832D2FFFF4E
+:10F5300002A9282400ADB02192C7000424E90004E8
+:10F54000000921C002402821366600020E000F5536
+:10F55000000000000A00135F000010210A0012E200
+:10F56000241200203C1908008F3900D802A028215D
+:10F5700024040080273800013C010800AC3800D882
+:10F580000E000F55240600030A00135F000010212F
+:10F590008C84014000E028213C0380008C7701B876
+:10F5A00006E0FFFE2408001CACA40000A0A8000B8D
+:10F5B0003C181000AC7801B83C0340003C078000C8
+:10F5C000ACE301780A00121B000000003C030800B5
+:10F5D0008C6300D02EA5000C001521C0386F0001EF
+:10F5E0002DF200010245702415C0FFD632D2FFFF74
+:10F5F00026B7FFFC2EE40004148000080000202140
+:10F60000386800022D180001030518241060000658
+:10F610000007FA4232D2FFFF0000202102402821D9
+:10F620000A0013A4366600020015102B03E2C8245A
+:10F630001720000532D2FFFF001521C0024028210B
+:10F640000A0013A43666000200002021024028218F
+:10F650000E000F553266FFFB0A0013E0001521C0B3
+:10F6600010B3006A000860802406000B14A6FE6B2D
+:10F67000000819C0000828803C15080126B58280C2
+:10F6800000B530210A001258A0C0000134D5000294
+:10F6900002E0202130A5FFFF0E000F5532A6FFFF2C
+:10F6A0000A001348000020210008B8803C0308012C
+:10F6B0002463828002E31021905400001280FE57E0
+:10F6C000000819C0A04000008F9900182738FFFFDC
+:10F6D0001700FE52AF980018000819C00A0012580F
+:10F6E000AF80001C0A00124F240800030E000FBC5C
+:10F6F000000000000A0012DA8F8700001720FEF3D6
+:10F700003C06000126BF000433E5FFFF3666000219
+:10F710003C0380008C7501B806A0FFFE8F890008AD
+:10F720003C04800034930180AE60000011200099F9
+:10F73000240F000324AA0012012A102B1040009568
+:10F7400000000000946D01203C1280002403001A88
+:10F7500031ACFFFF364A018030EB4000A143000B83
+:10F760001160008F2583FFFE0123702B15C0008DD3
+:10F770002409FFFE35080001A5430014AF880004EA
+:10F780002417BFFF0117B02424080002A7C8000CEB
+:10F79000A7C5000EA7C60008A7D60026A7C7001059
+:10F7A0003C071000AE2701B80A00135F00001021CB
+:10F7B00024040100024028210E000F550260302170
+:10F7C0000A00133400000000910300012415000119
+:10F7D0001075FF0224040001240E0002146EFEDDE9
+:10F7E0000000B82130E300401060FEDB8F82001C77
+:10F7F00095270110950F000230E9FFFF11E9FF0E78
+:10F80000008010210A0013278F82001C3C0F080182
+:10F8100025EF8280018F702100069202A1D20001A3
+:10F820003C1F60008FED1820241000010110980487
+:10F830003C0208012442828201B3B025018250219A
+:10F8400000065C02000819C0A54B0000AFF61820A6
+:10F850000A0012593C058000366600020E000F5562
+:10F86000240400800A00135F000010218CAE000405
+:10F870003C0F60000A00120C01CF18218C6640007A
+:10F8800030CA01001140003730EB01003C15080080
+:10F890008EB5002411600013327700043C0D0F0078
+:10F8A00000ED28243C0C020010AC000E8F84000CEC
+:10F8B0003C0F080025EF00380260302100899024B9
+:10F8C000024F702191C7000432C5FFFF3272FFFB67
+:10F8D00024E90004000921C00E000F552413FFFE87
+:10F8E00002B3A8242403000112A3003032B800019F
+:10F8F0001300000732A8000402403021000020213C
+:10F900000E000F5532C5FFFF3252FFFB32A8000434
+:10F91000110000048F9F000033F908005720002BCE
+:10F9200032C5FFFF16E0FEC4000010213C16800027
+:10F9300036C401803C0580008CA201B80440FFFE63
+:10F94000240B200024060002A48B0008A086000BD4
+:10F95000A48000103C0A1000ACAA01B80A00135F92
+:10F96000000010213C0508008CA5002430AC0001EB
+:10F970005180FEB10000102132C5FFFF3666000243
+:10F98000000020210E000F55000000000A00135F48
+:10F9900000001021A3CF000B0A0014322417BFFF70
+:10F9A0002409FFFE0A0014300109402432550004E6
+:10F9B00016A0000332C5FFFF3657000232F2FFFFE8
+:10F9C000024030210A0014B2000020210240302100
+:10F9D0000E000F55240401000A00149A00000000D4
+:10F9E0003C0380008C6401003082003E144000081B
+:10F9F00000000000AC6000488C66010030C507C004
+:10FA000010A0000500000000AC60004CAC6000508D
+:10FA100003E0000824020001AC600054AC60004028
+:10FA20008C6801003107380010E0FFF90000000089
+:10FA30002402000103E00008AC6000443C03900095
+:10FA400034620001008220253C038000AC64002069
+:10FA50008C65002004A0FFFE0000000003E0000809
+:10FA6000000000003C028000344300010083202598
+:10FA700003E00008AC44002027BDFFD8AFB100145C
+:10FA80003C048000AFBF0020AFB3001CAFB2001831
+:10FA9000AFB000108C9201408C9001482402000EFF
+:10FAA00000108C02322300FF106200590204282447
+:10FAB0002866000F10C00013286A003724070006CC
+:10FAC0001067008E286800075100002D24040009EB
+:10FAD000106000783C06800024090001106900B025
+:10FAE000000000000000000D8FBF00208FB3001C3D
+:10FAF0008FB200188FB100148FB0001003E000081F
+:10FB000027BD002811400059240D0038286B00350E
+:10FB1000116000053C058000240C001F146CFFF1EF
+:10FB2000000000003C0580008CB801B80700FFFE13
+:10FB300034B90180AF320000241F000124120002FA
+:10FB40003C021000AF200004A7310008A33F000AC8
+:10FB5000A332000BA7300010AF200024AF200028F4
+:10FB6000ACA201B88FBF00208FB3001C8FB2001869
+:10FB70008FB100148FB0001003E0000827BD0028EB
+:10FB8000106400232405000B1465FFD63218FFFF14
+:10FB9000170000203C0580008F93FEEC927F00054B
+:10FBA00033F900041720FFCF000000000E0014E01E
+:10FBB00002402021926900050240202135280004DE
+:10FBC0000E0014EAA26800059267000530E2000406
+:10FBD00014400002000000000000000D926B0000C5
+:10FBE00024060020316A00FF1546000A3C0580000B
+:10FBF0008CA401B80480FFFE34AD0180240E000502
+:10FC00003C0C1000ADB20000A1AE000BACAC01B8D2
+:10FC10003C0580008CA301B80460FFFE34AF018076
+:10FC200024130002ADF20000ADF20004A5F10008BB
+:10FC3000A1F3000AA1F3000BA5F00010ADE0002431
+:10FC40008CB101443C101000ADF10028ACB001B8FB
+:10FC50008FBF00208FB3001C8FB200188FB100142B
+:10FC60008FB0001003E0000827BD0028106DFFAD25
+:10FC7000240E0080146EFF9B000000003C058000F5
+:10FC80008CA301B80460FFFE34AF0180241200028F
+:10FC9000A1F2000BA5F10008A5F000108CB30144FF
+:10FCA0003C021000A5F30012ACA201B80A00152B0B
+:10FCB0008FBF00208CC301B80460FFFE34D30180E5
+:10FCC000AE720000AE60000424120001A6710008AC
+:10FCD00024110002A272000AA271000BA67000108B
+:10FCE0008CD001443C0F1000AE700024AE600028A0
+:10FCF000ACCF01B80A0015668FBF00203C0380001E
+:10FD00008C6601B804C0FFFE346201803C06080125
+:10FD100090C682C0AC52000010C000030000382121
+:10FD20003C0708018CE782C83C05800034AA0180AA
+:10FD30002404000234CC0001AC470004A5510008A3
+:10FD4000A14C000AA144000BA55000108CAB01444B
+:10FD50000000202101402821AD4B002410C00003E9
+:10FD60008FBF00203C0408018C8482C48FB3001C28
+:10FD70008FB200188FB100148FB000103C0E10002D
+:10FD80003C0D800027BD0028ACA40028ADAE01B812
+:10FD90003C010801A02082C003E000080000000030
+:10FDA00010A0000B3C0680008C980144241900022E
+:10FDB0003C010801A03982C03C010801AC3282C874
+:10FDC0003C010801AC3882C40A0015668FBF0020D0
+:10FDD0008CDF01B807E0FFFE34C701802409000270
+:10FDE000ACF20000ACF20004A4F10008A0E9000AA3
+:10FDF000A0E9000BA4F00010ACE000248CC8014482
+:10FE00003C021000ACE80028ACC201B80A0015663C
+:10FE10008FBF002027BDFFE8AFBF00100E000F4EC0
+:10FE2000000000003C0280008FBF00100000202175
+:10FE3000AC4001800A00101027BD00183084FFFF7D
+:10FE400030A5FFFF1080000700001821308200015C
+:10FE50001040000200042042006518211480FFFBBE
+:10FE60000005284003E000080060102110C00007D2
+:10FE7000000000008CA2000024C6FFFF24A500049F
+:10FE8000AC82000014C0FFFB2484000403E00008DF
+:10FE90000000000010A0000824A3FFFFAC860000B3
+:10FEA00000000000000000002402FFFF2463FFFFA9
+:10FEB0001462FFFA2484000403E00008000000003C
+:10FEC00027BDFFE8AFBF0014AFB000100E0014E074
+:10FED000008080213C0480083483008090650025E8
+:10FEE0000200202134A200200E0014EAA0620025A6
+:10FEF000020020218FBF00148FB000100A000C9E5A
+:10FF000027BD00183C03800027BDFFF83462018044
+:10FF1000AFA20000308C00FF30AD00FF30CE00FFFC
+:10FF20003C0B80008D6401B80480FFFE00000000DF
+:10FF30008FA900008D6801288FAA00008FA70000FC
+:10FF40008FA400002405000124020002A085000AFD
+:10FF50008FA30000359940003C051000A062000B03
+:10FF60008FB800008FAC00008FA600008FAF00009C
+:10FF700027BD0008AD280000AD400004AD8000247E
+:10FF8000ACC00028A4F90008A70D0010A5EE0012CF
+:10FF900003E00008AD6501B83C06800827BDFFE816
+:10FFA00034C50080AFBF001090A7000924020012E2
+:10FFB00030E300FF1062000B008030218CA800505D
+:10FFC00000882023048000088FBF00108CAA003412
+:10FFD000240400390000282100CA48230520000518
+:10FFE000240600128FBF00102402000103E0000865
+:10FFF00027BD00180E001612000000008FBF001071
+:020000040001F9
+:100000002402000103E0000827BD001827BDFFC837
+:10001000AFB1002C00A08821AFB2003027A500109E
+:100020000080902102202021AFBF0034AFB0002813
+:100030000E000CA8AFA000101440009B3C078008E5
+:1000400034E400809086000830C5000814A00069E0
+:100050008FA700103C18800837100080920F00080E
+:1000600031EE000815C00002240800030000402102
+:100070003C0B800891650011916A00123566008082
+:100080008CDF0054314900FF0128202130A300FFFC
+:10009000000410800062282100BFC82B1320000834
+:1000A0000000000094D0005C8CCF0054320DFFFFA4
+:1000B00001E5702301AE602B118000940000000068
+:1000C00094D9005C3323FFFF30FF000413E0007479
+:1000D000000830808FA8001C0068102B5040004F93
+:1000E00030E30004006610232C46008010C000029C
+:1000F00000408021241000800E0014E002402021E6
+:100100003C0380083466008024070001ACC7000C63
+:1001100090C800080010684034670100311F007F5C
+:10012000A0DF00088E39000427380001ACD8003069
+:10013000A4D0005C8CCF003C9630000E01F0702102
+:10014000ACCE00208CCC003C018D5821ACCB001CE7
+:100150008E2A0004ACEA00008E290008ACE90004F5
+:100160008FA5001030A400085480003293A6002010
+:10017000A0C0004E90C9004E2402FFDF3C1880084A
+:10018000A0E9000890C50008370D0080240A00503F
+:1001900000A22024A0C400088E390008ADB90038A0
+:1001A0008F0F00148DB0003001F07021ADAE00341F
+:1001B00091AC0000318B00FF116A002C2645010034
+:1001C0000E0014EA024020212404003800002821F7
+:1001D0000E0016122406000A8FBF00348FB20030C2
+:1001E0008FB1002C8FB000282402000103E000082A
+:1001F00027BD003830E801001100003D8FA3001436
+:100200008C8A0058006A48230520FF933C18800818
+:10021000AC8300580A0016668FA700102407021846
+:100220001060FFB100E610238FA2001C0A00168B9D
+:10023000004610233C188008370D0080A0E6000817
+:100240008E390008240A0050ADB900388F0F001411
+:100250008DB0003001F07021ADAE003491AC0000E3
+:10026000318B00FF156AFFD6264501002406FF806A
+:1002700000A610243C098000AD2200288E2700082B
+:1002800030A3007F3C04800C0064F821AFE700D06D
+:100290008E280008AF9F00280A0016C1AFE800D4DE
+:1002A0000A0016882C6202188E2300083C0480087D
+:1002B00034820080AC430054024020210E0016011D
+:1002C000AC400030240400382405008D0E001612C6
+:1002D000240600128FBF00348FB200308FB1002C83
+:1002E0008FB000282402000103E0000827BD003879
+:1002F000AC800058908C0008240DFFF7018D582425
+:10030000A08B00080A0016668FA700108CD8005436
+:100310000A0016830305182327BDFFE8AFBF0010AE
+:1003200090A6000D30C7001010E0000C00804021A6
+:100330003C0280088C4400048CA300081064000870
+:1003400030C9000430C5000410A0001C8FBF00108D
+:100350002402000103E0000827BD001830C9000492
+:100360001120001030CB001210E0FFF98FBF0010F9
+:100370003C0880088CA700088D06000414E6FFF5F1
+:1003800024020001240400382405008D0E001612FA
+:10039000240600128FBF00102402000103E00008B1
+:1003A00027BD0018240A0012156AFFE98FBF00104C
+:1003B000010020210A00165427BD0018000020214A
+:1003C0000A000D1A27BD00183C05080024A55D5041
+:1003D0003C04080024847B103C02080024425D5841
+:1003E000240300063C010801AC2582D03C01080131
+:1003F000AC2482D43C010801AC2282D83C01080123
+:10040000A02382DC03E000080000000003E00008F5
+:10041000240200013C028000308800FF3447018044
+:100420003C0680008CC301B80460FFFE00000000A1
+:100430008CC501282418FF803C0D800A24AF0100E0
+:1004400001F8702431EC007FACCE0024018D202116
+:10045000ACE50000948B00DA350960002408000246
+:10046000316AFFFFACEA000424020001A4E900089D
+:10047000A0E8000BACE000243C071000ACC701B8BA
+:10048000AF84002803E00008AF8500588C99000471
+:100490008F8D00282409FFBF0325C023AC980004DA
+:1004A00091AF00C42403FFEF31EE007FA1AE00C482
+:1004B0008C8C0020938B00348F860028358A0002B4
+:1004C000AF8B004CA7800048AC8A0020A4C000ACD1
+:1004D00090C800C401093824A0C700C48F84002834
+:1004E000AC8000DC908500C400A3102403E0000869
+:1004F000A08200C43C028000344501803C0480009E
+:100500008C8301B80460FFFE8F8900582407608344
+:1005100024060002ACA900008C880124ACA80004C9
+:10052000A4A70008A0A6000B3C05100003E00008EB
+:10053000AC8501B8938800348F89004C8F820028E5
+:1005400030C600FF0109382330E900FF01221821DD
+:1005500030A500FF2468007810C000020124382173
+:100560000080382130E400031480000330AA000327
+:100570001140000D312B000310A0000900001021D4
+:1005800090ED0000244E000131C200FF0045602BB9
+:10059000A10D000024E700011580FFF925080001E6
+:1005A00003E00008000000001560FFF300000000F9
+:1005B00010A0FFFB000010218CF80000245900045B
+:1005C000332200FF0045782BAD18000024E700041B
+:1005D00015E0FFF92508000403E000080000000012
+:1005E00093850034938800448F87004C00043200C8
+:1005F0003103007F00E5102B30C47F001040000F56
+:10060000006428258F8400283C0980008C8A00DC47
+:10061000AD2A00A43C03800000A35825AC6B00A0C9
+:100620008C6C00A00580FFFE000000008C6D00AC0B
+:10063000AC8D00DC03E000088C6200A80A0017D62D
+:100640008F840028938800453C0280000080502160
+:10065000310300FEA383004530ABFFFF30CC00FF29
+:1006600030E7FFFF344801803C0980008D2401B849
+:100670000480FFFE8F8D005824180016AD0D000079
+:100680008D2201248F8D0028AD0200048D59002099
+:10069000A5070008240201B4A119000AA118000B43
+:1006A000952F01208D4E00088D4700049783004848
+:1006B0008D59002401CF302100C7282100A3202319
+:1006C0002418FFFFA504000CA50B000EA5020010C6
+:1006D000A50C0012AD190018AD18002495AF00D874
+:1006E0003C0B10002407FFF731EEFFFFAD0E002892
+:1006F0008DAC0074AD0C002CAD2B01B88D460020E4
+:1007000000C7282403E00008AD4500208F8800289A
+:100710000080582130E7FFFF910900C63C028000AD
+:1007200030A5FFFF312400FF00041A0000675025A8
+:1007300030C600FF344701803C0980008D2C01B891
+:100740000580FFFE8F820058240F0017ACE20000E6
+:100750008D390124ACF900048D780020A4EA00084A
+:10076000241901B4A0F8000AA0EF000B9523012082
+:100770008D6E00088D6D00049784004801C35021E0
+:10078000014D602101841023A4E2000CA4E5000EB9
+:10079000A4F90010A4E60012ACE000148D78002447
+:1007A000240DFFFFACF800188D0F006CACEF001C9F
+:1007B0008D0E00683C0F1000ACEE0020ACED002464
+:1007C000950A00AE240DFFF73146FFFFACE6002886
+:1007D000950C00709504007231837FFF0003CA00FE
+:1007E0003082FFFF0322C021ACF8002CAD2F01B8EE
+:1007F000950E00728D6A002000AE3021014D282434
+:10080000A506007203E00008AD6500203C028000F0
+:10081000344601803C0580008CA301B80460FFFED3
+:1008200024090018ACC40000A0C9000B8F88002860
+:100830003C041000950700AEA4C70010ACC0003007
+:1008400003E00008ACA401B83C02800034450180FC
+:100850003C0480008C8301B80460FFFE8F8A003066
+:10086000240600199549001C3128FFFF000839C0F3
+:10087000ACA70000A0A6000B3C05100003E0000898
+:10088000AC8501B88F8700380080402130C400FF5C
+:100890003C0680008CC201B80440FFFE8F890058DE
+:1008A0009383005434996000ACA90000A0A3000514
+:1008B0008CE20010240F00022403FFF7A4A200061C
+:1008C000A4B900088D180020A0B8000AA0AF000B42
+:1008D0008CEE0000ACAE00108CED0004ACAD00144A
+:1008E0008CEC001CACAC00248CEB0020ACAB0028E2
+:1008F0008CEA002C3C071000ACAA002C8D090024C7
+:10090000ACA90018ACC701B88D05002000A32024B5
+:1009100003E00008AD040020938500542403000187
+:1009200027BDFFE800A330042CA20020AFB00010C8
+:10093000AFBF001400C01821104000132410FFFEA8
+:100940003C0708008CE7319000E610243C0880004A
+:100950003505018014400005240600848F89002895
+:10096000240A00042410FFFFA12A00EC0E001872D4
+:1009700000000000020010218FBF00148FB0001093
+:1009800003E0000827BD00183C0608008CC631941F
+:100990000A0018A400C310248F87003027BDFFE091
+:1009A000AFB20018AFB10014AFB00010AFBF001C61
+:1009B00030D000FF90E6000D00A08821008090213B
+:1009C00030C5007FA0E5000D8F8500288E2300181C
+:1009D0008CA200C01062002E240A000E0E00189790
+:1009E000A38A00542409FFFF104900222404FFFFBA
+:1009F00052000020000020218E2600003C0C001038
+:100A000000CC5824156000393C0E000800CE682444
+:100A100055A0003F024020213C18000200D880244D
+:100A20001200001F3C0A00048F8700308CE2001483
+:100A30008CE300108CE500140043F82303E5C82B79
+:100A400013200005024020218E24002C8CF1001080
+:100A5000109100310240202124020012A382005490
+:100A60000E0018972412FFFF105200022404FFFF0B
+:100A7000000020218FBF001C8FB200188FB100141E
+:100A80008FB000100080102103E0000827BD002077
+:100A900090A800C4350400200A0018CDA0A400C40A
+:100AA00000CA48241520000B8F8B00308F8D00303A
+:100AB0008DAC00101580000B024020218E2E002CE2
+:100AC00051C0FFEC00002021024020210A0018E85C
+:100AD000240200178D66001050C0FFE600002021A0
+:100AE000024020210A0018E82402001102402021BF
+:100AF000240200150E001897A3820054240FFFFF54
+:100B0000104FFFDC2404FFFF0A0018D78E260000D8
+:100B10000A00190E240200143C08000400C83824FE
+:100B200050E0FFD400002021024020210A0018E8F4
+:100B3000240200138F86002827BDFFE0AFB1001408
+:100B4000AFBF0018AFB0001090C300C430A500FFC5
+:100B50003062002010400008008088218CCB00C04B
+:100B60002409FFDF256A0001ACCA00C090C800C498
+:100B700001093824A0C700C414A000403C0C800028
+:100B80008F840028908700C42418FFBF2406FFEF3D
+:100B900030E3007FA08300C4979F00488F82004C01
+:100BA0008F8D002803E2C823A7990048A5A000ACB8
+:100BB00091AF00C401F87024A1AE00C48F8C00284E
+:100BC000A18000C78F8A0028A5400072AD4000DCDC
+:100BD000914500C400A65824A14B00C48F90002466
+:100BE0008F84004C978600480204282110C0000F13
+:100BF000AF850024A38000443C0780008E2C0008B1
+:100C000094ED01208E2B0004018D5021014B802199
+:100C1000020620233086FFFF30C8000F390900018B
+:100C20003131000116200009A38800449386003466
+:100C30008FBF00188FB100148FB0001027BD0020A7
+:100C4000AF85005003E00008AF86004C00C8702359
+:100C50008FBF0018938600348FB100148FB000103E
+:100C600034EF0C00010F282127BD0020ACEE0084DA
+:100C7000AF85005003E00008AF86004C359001803E
+:100C8000020028210E001872240600828F8400289A
+:100C9000908600C430C5004050A0FFBAA380005425
+:100CA0008F8500383C0680008CCD01B805A0FFFE82
+:100CB0008F8900582408608224070002AE090000D2
+:100CC000A6080008A207000B8CA300083C0E100029
+:100CD000AE0300108CA2000CAE0200148CBF0014F6
+:100CE000AE1F00188CB90018AE1900248CB800246F
+:100CF000AE1800288CAF0028AE0F002CACCE01B887
+:100D00000A001932A38000548F8A002827BDFFE013
+:100D1000AFB10014AFB000108F88004CAFBF001807
+:100D20009389002C954200AC30D100FF0109182BAB
+:100D30000080802130AC00FF3047FFFF00005821C9
+:100D400014600003310600FF0120302101095823FF
+:100D5000978300480068202B1480001B00000000CF
+:100D600010680043240A0001118A004834E7088013
+:100D70003165FFFF0E001814020020210E001854E8
+:100D80008F8400588F840028948D007025AC00015A
+:100D9000A48C0070948B00703C0608008CC63188CF
+:100DA00031677FFF10E6004F0000000002002021A5
+:100DB000022028218FBF00188FB100148FB00010BF
+:100DC0000A00191E27BD0020914400C42406FF809C
+:100DD00000868825A15100C4978400483088FFFF11
+:100DE0001100001C9389002C8F8E00282419EFFF1E
+:100DF000008BF82395D800AC0168682B33E900FF1D
+:100E000003197824A5CF00AC51A0002A0100582175
+:100E10008E0500202408FFFB2403000100A81024F5
+:100E2000AE0200201183002534E78000020020215B
+:100E30003165FFFF0E00181401203021978B004808
+:100E40008F87004CA780004800EB8023AF90004CB8
+:100E50009389002C8F8C00288FBF00188FB100144D
+:100E60008FB0001027BD002003E00008A18900C753
+:100E70008E0800202409FFFB34E7800001092824A4
+:100E8000AE050020158AFFBA34E708800200202151
+:100E90000E0017E23165FFFF020020210220282109
+:100EA0008FBF00188FB100148FB000100A00191EF8
+:100EB00027BD00200A0019D500004821020020218A
+:100EC0003165FFFF0E0017E201203021978B0048AB
+:100ED0008F87004CA780004800EB80230A0019E5AB
+:100EE000AF90004C94890070240A8000012A4024AD
+:100EF000A4880070908500709099007030A200FF67
+:100F0000000219C20003F827001FC1C0332F007F61
+:100F100001F87025A08E00700A0019BD0200202182
+:100F20008F88002824030001910A0078910500C7EA
+:100F3000250900783147003F24E6FFE000C318048C
+:100F40002CC2002030670019A385002C1040001A25
+:100F5000AF8900383C0A8000354B000224050001AF
+:100F60002406000114E00016006B10240000282164
+:100F70001440000F306300201060000F24050001B2
+:100F80008D0600748D1900742403FF8000C31024A3
+:100F9000000279403338007F01F868253C0E1000CC
+:100FA00001AE6025AD4C08309128000131060001EA
+:100FB0000A0019930000000003E000080000000090
+:100FC0008D0F00748D0D00742418FF8001F87024BB
+:100FD000000E414031AC007F010C50253C0B10004D
+:100FE000014B38253C0980000A001993AD270830D1
+:100FF00027BDFFD8AFB000108F900038AFB40020ED
+:10100000AFB10014AFBF0024AFB3001CAFB20018E3
+:101010008E0500103C0208008C4231B08F86003CE7
+:1010200030A73FFF00E2182B8CD2001400808821EB
+:101030008CD30020106000070000A02190CB000D91
+:10104000240AFF80014B4824312800FF1500000CC2
+:1010500000056382022020212411000DA391005479
+:101060008FBF00248FB400208FB3001C8FB20018F4
+:101070008FB100148FB000100A00189727BD002808
+:101080003185000354A0FFF40220202194CF001CDE
+:101090008F8E00288E070028A5CF00D88CCD001099
+:1010A000024D302310E6005C2402001F0E0018974A
+:1010B000A3820054241FFFFF105F004E2404FFFF93
+:1010C0008F8300408F880030026398218D090010C3
+:1010D000012310238F830020AD020010AD130020E8
+:1010E0008C67007400F3202B148000620220202102
+:1010F0008F86003C8E0C00248CC5002411850007CF
+:1011000002202021240E001C0E001897A38E0054EC
+:10111000240DFFFF104D00372404FFFF8F840030A3
+:101120008C980024270F0001AC8F00241272004419
+:101130008F9900208F320074125300413C0A0080C6
+:101140008E090000012A10241440003A000000001B
+:101150008E0400142412FFFF10920006240B001BC3
+:10116000022020210E001897A38B0054105200215A
+:101170002404FFFF8E0300003C0C0001006C2824B7
+:1011800010A000133C0600800066A0241680000911
+:101190000200282102202021240E001A0E00189798
+:1011A000A38E0054240DFFFF104D00122404FFFFF6
+:1011B00002002821022020210E0018B72406000179
+:1011C0002410FFFF2404FFFF1050000A2414000124
+:1011D0008F8F0030022020210280302195F20034D0
+:1011E00024050001265800010E001993A5F80034CB
+:1011F000000020218FBF00248FB400208FB3001C7B
+:101200008FB200188FB100148FB000100080102131
+:1012100003E0000827BD00288F83004000E3C821B9
+:101220000259C02B1300FFA88F8800300A001A7CD7
+:1012300024020018AC8000200A001AA68E040014B4
+:101240008E1F00003C07008003E798241660FFF91A
+:101250002408001A022020210E001897A3880054A9
+:101260002403FFFF1443FFBA2404FFFF0A001ACF30
+:101270008FBF0024240B001D0E001897A38B005471
+:10128000240AFFFF144AFF9A2404FFFF0A001ACF22
+:101290008FBF00248F85002827BDFFD8AFB3001C67
+:1012A000AFB20018AFB10014AFB00010AFBF002054
+:1012B00090A700C48F9000382412FFFF34E2004052
+:1012C00092060000A0A200C48E03001000809821A6
+:1012D0001072000630D1003F2408000D0E00189750
+:1012E000A3880054105200262406FFFF8F8A00288E
+:1012F0008E0900188D4400C011240007240C000E34
+:10130000026020210E001897A38C0054240BFFFFCD
+:10131000104B001B2406FFFF2404002012240004AD
+:101320008F8D002891AF00C435EE0020A1AE00C41F
+:101330008F85004010A0001A000000001224004B0E
+:101340008F9800288F92FEEC2406FFFD9710007006
+:101350009651000A1230000B8FBF00203C1F08007E
+:101360008FFF318C03E5C82B1720001E026020215F
+:10137000000028210E0019932406000100003021EE
+:101380008FBF00208FB3001C8FB200188FB10014E4
+:101390008FB0001000C0102103E0000827BD002816
+:1013A0005224002A8E0300148F8400289489007030
+:1013B00025280001A4880070948700703C0508006F
+:1013C0008CA5318830E27FFF1045000E0000000040
+:1013D000026020210E00191E240500010A001B31A5
+:1013E000000030212402002DA38200540E00189723
+:1013F0002413FFFF1453FFE12406FFFF0A001B32F2
+:101400008FBF0020949800702419800024050001EB
+:1014100003199024A492007090910070908D007038
+:10142000323000FF001079C2000F7027000E61C03B
+:1014300031AB007F016C5025A08A00700E00191E90
+:10144000026020210A001B31000030212406FFFF2A
+:101450001466FFD68F840028026020210E00191E1A
+:10146000240500010A001B31000030210260202108
+:101470000A001B4B2402000A8F88002827BDFFE8C2
+:10148000AFB00010AFBF0014910A00C48F870038BE
+:1014900000808021354900408CE60010A10900C47D
+:1014A0003C0208008C4231B030C53FFF00A2182B2F
+:1014B000106000078F85003C240DFF8090AE000D6A
+:1014C00001AE6024318B00FF156000080006C38266
+:1014D000020020212403000D8FBF00148FB00010E4
+:1014E00027BD00180A001897A38300543306000391
+:1014F000240F000254CFFFF70200202194A2001C09
+:101500008F85002824190023A4A200D88CE80000AD
+:1015100000081E02307F003F13F900353C0A0083AB
+:101520008CE800188CA600C011060008000000001E
+:101530002405000E0E001897A38500542407FFFF12
+:10154000104700182404FFFF8F85002890A900C4CD
+:1015500035240020A0A400C48F8C0030918E000D93
+:1015600031CD007FA18D000D8F8300401060001CE5
+:10157000020020218F84003C8C9800100303782BFC
+:1015800011E0000D2419001802002021A399005435
+:101590000E0018972410FFFF105000022404FFFFD4
+:1015A000000020218FBF00148FB000100080102198
+:1015B00003E0000827BD00188C8600108F9F0030C4
+:1015C0000200202100C31023AFE200102405000117
+:1015D0000E001993240600010A001BBA0000202106
+:1015E0000E00191E240500010A001BBA000020216C
+:1015F000010A5824156AFFD98F8C0030A0A600EC90
+:101600000A001BA7A386004627BDFFD8AFB0001075
+:101610008F900038AFB20018AFBF0020AFB3001CEE
+:10162000AFB100148E1100103C0308008C6331B080
+:1016300032253FFF00A3102B1040000800809021AE
+:101640008F86003C2409FF8090CA000D012A4024A7
+:10165000310700FF14E0000B00116B8202402021D3
+:101660002412000DA39200548FBF00208FB3001CE2
+:101670008FB200188FB100148FB000100A001897B5
+:1016800027BD002831AC0003240B0001558BFFF46B
+:101690000240202190CF000D31EE000811C0006003
+:1016A0008F93004016600009240200278E19000C59
+:1016B0008CD8002017380005240200208E02000874
+:1016C0008CDF0024105F0040240200200E001897D9
+:1016D000A38200542406FFFF104600332404FFFFBA
+:1016E0008F990030240AFFF73C13800E9329000DD8
+:1016F0002404FF803C0D8000012AF824A33F000D44
+:101700008F9900203C0808008D0831AC8F83005869
+:10171000972700788F9F00300103102130E57FFF6D
+:10172000000530400046782131F8007F0313602126
+:1017300001E47024ADAE002CA59100008FEB0028D1
+:10174000256A0001AFEA00288FE3002C8E09002CE7
+:1017500000694021AFE8002C8E07002CAFE7003075
+:101760008E050014AFE5003497E6003A24C200016C
+:10177000A7E2003A973300783C1008008E1031B091
+:101780002663000130717FFF123000270060302196
+:101790008F8F002002402021240500010E00191E19
+:1017A000A5E60078000020218FBF00208FB3001C29
+:1017B0008FB200188FB100148FB00010008010217C
+:1017C00003E0000827BD00288E0500142413FFFF46
+:1017D00010B3001D8F8300288E0800188C6700C08E
+:1017E000150700092402000E8E0A00248CC9002867
+:1017F00015490005240200218E0700288CCB002CFF
+:1018000010EB00132402001F0E001897A38200544F
+:101810001453FFB32404FFFF0A001C3C8FBF0020B9
+:101820000A001C0424020024240E8000006E682498
+:1018300031ACFFFF000C5BC2317100FF001180274B
+:101840000A001C35001033C00A001C532402002576
+:101850008E05002C10A0FFEC240200238F8E0020A8
+:101860008DCD007401A5602B1580FFE724020026B2
+:101870008CCF001400A7C02101F8202B1080FF9905
+:101880008F990030024020210A001C5324020022BC
+:1018900027BDFFE0AFB000108F900038AFB100144B
+:1018A000AFBF00188E0500103C0308008C6331B0F8
+:1018B0000080882130A43FFF0083102B10400007D8
+:1018C0008F86003C2409FF8090CA000D012A402425
+:1018D000310700FF14E000098F8B00402410000D39
+:1018E00002202021A39000548FBF00188FB1001454
+:1018F0008FB000100A00189727BD00201160000863
+:101900000005C3828F8F00288F8EFEEC2407FFFD19
+:1019100095EC007095CD000A11AC00388FBF00180F
+:101920003305000314A0001000000000921900020B
+:1019300013200041000000008E06002450C0000F5C
+:1019400092040003022020212402000F0E001897A9
+:10195000A38200542408FFFF144800072407FFFF58
+:101960000A001CD08FBF001890C3000D306400081F
+:101970001080003702202021920400032407000277
+:10198000308900FF15270005308F00FF8F8A004047
+:1019900011400031240C002C308F00FF39E500107D
+:1019A0002CAD00012DEE00010200282101CD3025D3
+:1019B0000E0018B7022020212410FFFF1050000E47
+:1019C0002407FFFF8F8300401060001702202021B2
+:1019D0003C1908008F39318C0323C02B5700000CB1
+:1019E0002411002D02202021000028210E0019932F
+:1019F00024060001000038218FBF00188FB10014A9
+:101A00008FB0001000E0102103E0000827BD002087
+:101A10000E001897A39100541450FFF62407FFFFFF
+:101A20000A001CD08FBF00180E00191E24050001EB
+:101A30000A001CCF000038218CDF00248E02002415
+:101A4000545FFFC1022020210A001CB09204000351
+:101A50000A001CA424020010022020210E00189766
+:101A6000A38C0054240BFFFF104BFFE32407FFFF60
+:101A70000A001CB79204000330A500FF24060001F1
+:101A800024A9000100C9102B1040000C00004021C7
+:101A9000240A000100A61823308B000124C600018F
+:101AA000006A3804000420421160000200C9182BAB
+:101AB000010740251460FFF800A6182303E0000882
+:101AC0000100102127BDFFD8AFB000188F9000385B
+:101AD000AFB1001CAFBF00202403FFFF2411002F73
+:101AE000AFA3001092060000240500082610000194
+:101AF000006620260E001CEF308400FF00021E004E
+:101B00003C021EDC34466F410A001D170000102104
+:101B100010A00009008018212445000130A2FFFF19
+:101B20002C4500080461FFFA0003204000862026AF
+:101B300014A0FFF9008018210E001CEF24050020DE
+:101B40008FA300102629FFFF313100FF000342025E
+:101B5000240700FF1627FFE2010218260003502782
+:101B6000AFAA0014AFAA00100000302127A800106F
+:101B700027A7001400E6782391ED000324CE00018E
+:101B800000C8602131C600FF2CCB00041560FFF9AE
+:101B9000A18D00008FA200108FBF00208FB1001C0C
+:101BA0008FB0001803E0000827BD0028938300349D
+:101BB00027BDFFE024020034AFB10014AFB0001025
+:101BC000AFBF001CAFB20018008088211062006215
+:101BD00000A0802192040004148000458F88002812
+:101BE000A380002C8E0500048D0600C83C0700FF72
+:101BF00034E3FFFF00A3282400C5102B1440004D40
+:101C0000AF850040978A00488F87004C014710231A
+:101C100010A00032A78200488F980020304CFFFFB0
+:101C20009312007C0012788231F100010011708063
+:101C300001C56821018D582B116000618F86002835
+:101C40008F8900248F8400501089005E3C023F0180
+:101C50008E1F00003C10250003E2C8241730007AD4
+:101C60008F8400388F8700388F8600288CE300002F
+:101C7000ACC300788CE50010ACC500888F87004CA1
+:101C80008F850040938D002C30AE0003000E402362
+:101C9000310A0003014D4021A388002C94CB00ACF5
+:101CA00001276021AF8C002435691000A4C900AC65
+:101CB0001620005101452021AF84004C0000202156
+:101CC0008FBF001C8FB200188FB100148FB00010AE
+:101CD0000080102103E0000827BD00208F8400242D
+:101CE000AF80004C008730210A001D80AF860024A1
+:101CF000241F000CA39F00540E00189702202021DF
+:101D00002419FFFF1059FFEE2404FFFF8F880028DD
+:101D1000A380002C8E0500048D0600C83C0700FF40
+:101D200034E3FFFF00A3282400C5102B1040FFB5AB
+:101D3000AF8500400220202124090019A389005406
+:101D40000E0018972411FFFF1051FFDD2404FFFF40
+:101D50000A001D528F8500408F8400288F8700382D
+:101D60008CF20030908600C430C5001014A0001022
+:101D70008F83004C2C68000515000028000000002F
+:101D8000908A00C4246BFFFC314900101520000824
+:101D9000316400FF8F8D00508F8C002411AC000443
+:101DA000388F000131EE000115C0002F0000000047
+:101DB0000E001D02000000000A001DD900000000F6
+:101DC0008F890024938D002C30AE0003000E402339
+:101DD000310A0003014D4021A388002C94CB00ACB4
+:101DE00001276021AF8C002435691000A4C900AC24
+:101DF0001220FFB10145202125180004A398002CD2
+:101E000094CF00AC24920004AF92004C35F1200036
+:101E1000A4D100AC0A001D81000020218C8200DCCE
+:101E20001242FF6C0220202124180005A3980054C0
+:101E30000E0018972412FFFF1452FF662404FFFFC0
+:101E40000A001D828FBF001C30E500FF0E00179EA8
+:101E5000000030218F8600288F87004C8F89002456
+:101E60000A001D728F8500400E0017C90000000097
+:101E70000A001DD9000000009383004627BDFFE043
+:101E800024020002AFB20018AFB10014AFBF001CB3
+:101E900000808821AFB00010000090211062005532
+:101EA0002404FFFD978300488F85004C3066FFFFB8
+:101EB00000C5202B1480005B938700343C08800011
+:101EC0009504012010E500528F8A00248F84005071
+:101ED00030A500FF0E00179E240600018F9F0058BA
+:101EE0003C0580003C19408027ED017831B0007836
+:101EF000240EFF800219582534AF090031B80007BD
+:101F000001AE6024ACAC0800030F8021ACAB08101C
+:101F100002202021020028210E001D3CAF90003835
+:101F20002403FFFF104300332404FFFF8E0C001036
+:101F30003C0708008CE731B09206000031843FFF77
+:101F40000087102B1040002330CD003F8F980058A1
+:101F5000000471803C0408008C8431A82409FF80AF
+:101F60009390004500984021010E202100897024A3
+:101F7000000E51403C0980003099007F3C0F0080EA
+:101F80008F8800283525094035E2000101593825A0
+:101F9000308B0078308600073C0310003C1F800C1B
+:101FA00000C5C0210162582500E35025033F782178
+:101FB00036050001AD2E0804AF98003CAD2B081487
+:101FC000AF8F0030AD2E0028AD040074AD2A08306C
+:101FD000A38500459383004624100003507000271A
+:101FE00025A3FFE0240C0001106C001C2406002334
+:101FF000024020218FBF001C8FB200188FB1001447
+:102000008FB000100080102103E0000827BD0020E1
+:10201000314900035520FFAE8F8400500A001E1581
+:102020008F9000508F840050306500FF0E00179E87
+:1020300024060001938B0034240500341165001838
+:10204000978300488F85004C3062FFFF00A2582321
+:10205000AF8B004C0A001E4DA780004811A6003728
+:1020600000000000022020212411000B0E00189710
+:10207000A39100540A001E4D004090212C720020B4
+:102080001240FFF80003F8803C07080124E7813C78
+:1020900003E7C8218F2D000001A000080000000008
+:1020A0008F85004C2CA200055440001DA7800048DD
+:1020B000978A00483148FFFF00A848232D2F0005CC
+:1020C00011E00003314400FF24AEFFFC31C400FFE7
+:1020D0008F9000508F980024121800043899000146
+:1020E000332D000115A00029000000008F91002869
+:1020F000922500C434A30010A22300C49783004893
+:102100008F85004C8F8400283062FFFF00A2582387
+:10211000AC8000DCA78000480A001E4DAF8B004C4D
+:102120003062FFFF00A258230A001E4DAF8B004C07
+:102130002403FFFF11830005000000000E001B6F49
+:10214000022020210A001E4D004090210E001AF6A8
+:10215000022020210A001E4D004090210E001BD3BA
+:10216000022020210A001E4D004090210E001A4D31
+:10217000022020210A001E4D004090210E001C75F7
+:10218000022020210A001E4D004090210E0017C998
+:1021900000000000978300488F85004C306CFFFFE3
+:1021A00000AC38232CFF000553E0FFA83062FFFF8E
+:1021B0008F860028A7800048ACC200DC3062FFFF99
+:1021C00000A258230A001E4DAF8B004C27BDFFD044
+:1021D000AFB20018AFB00010AFBF0028AFB50024F9
+:1021E000AFB40020AFB3001CAFB100143C0C8000B2
+:1021F0008D880128240FFF803C07800A25100100EC
+:10220000250B0080020F68243205007F016F7024C7
+:10221000AD8E009000A72821AD8D002490A700EC82
+:102220003169007F3C0A8004012A1821A3870046F7
+:102230009066007C00809021AF83002030C20002B5
+:10224000AF880058AF85002800A018211440000274
+:102250002404003424040030A38400348C6600CCB1
+:1022600030F100FF24040004AF86004C1224000467
+:10227000A38000548E5300041660001D3C088000AB
+:102280009387004530F200011240000F8FBF0028F5
+:102290008CB800748CA400742419FF80031988245E
+:1022A00000117140308F007F01CF60253C0D200070
+:1022B000018D582530F500FE3C0A8000AD4B0830FA
+:1022C000A39500458FBF00288FB500248FB4002050
+:1022D0008FB3001C8FB200188FB100148FB00010A4
+:1022E0002402000127BD003003E00008ACA600CCAA
+:1022F0008E590008951F01208E460010033FC02113
+:102300003307FFFF30F5000F32B40001AF86002421
+:102310001680003BA395004435060C0002A6102150
+:1023200000F51823AD030084AF8200508E490004ED
+:102330003128FFFF1100002BA78900482410FF80DF
+:102340003C1580003C1420000A001F3B2413FFFEB4
+:1023500090AE00C4020E682431AC00FF1580002A44
+:10236000024020219384004597860048308F000169
+:1023700011E0000B026428248F8900288D2300744B
+:102380008D280074A3850045007010240002C94008
+:10239000311F007F033FC02503148825AEB10830EC
+:1023A00010C000108F85002890A700C40207582491
+:1023B000316A00FF1540FFE6024020210E001DEFAC
+:1023C000979100481040FFE8938400452405FFFDE5
+:1023D000544500058E430020022028210E0017746A
+:1023E000024020218E430020307000041600000AB5
+:1023F0002414FFFB8F8500280A001EF18F86004CF5
+:102400000A001F1CAF8600500E001A1900000000C1
+:102410000A001F2B93840045007498240E00178E29
+:10242000AE5300208F8500280A001EF18F86004CD5
+:1024300027BDFFD8AFB3001CAFB10014AFBF002061
+:10244000AFB20018AFB000103C0280008C520140C7
+:102450008C4B01483C048000000B8C02322300FFAF
+:10246000317300FF8C8501B804A0FFFE3490018019
+:10247000AE1200008C8701442464FFF024060002A1
+:102480002C830013AE070004A6110008A206000B5F
+:10249000AE1300241060004F8FBF0020000448805E
+:1024A0003C0A0801254A81BC012A40218D04000014
+:1024B00000800008000000003C1008008E1031A8C9
+:1024C00031733FFF001389800212C8212405FF8069
+:1024D00003312021264C0100264700803C1F80004C
+:1024E00000E51824318F007F30E9007F308A007FBB
+:1024F0003C18800A3C0E80043C0D800C00851024A2
+:1025000001853024014D8021AFE6002401F84021EF
+:10251000AFE30090012E9821AFE20028AF90003089
+:10252000AF880028AF9300200E001863016080215F
+:102530003C0380008C6B01B80560FFFE8F87003084
+:10254000346501808F86002890E3000DACB2000056
+:10255000A4B00006000316000002FE03001F90272F
+:10256000001227C21080007A24C2007824196082E9
+:10257000A4B90008A0A00005241F0002A0BF000B02
+:1025800000041C008F8B00203C0227000062902575
+:10259000ACB20010ACA00014ACA00024ACA0002889
+:1025A000ACA0002C8D7300382410FF80ACB3001851
+:1025B00090E4000D02048824322500FF10A00005DD
+:1025C0008FBF002090EC000D3188007FA0E8000D47
+:1025D0008FBF00208FB3001C8FB200188FB1001482
+:1025E0008FB000103C0D10003C0A800027BD002871
+:1025F00003E00008AD4D01B8265F01002405FF800F
+:1026000033F8007F3C06800003E578243C19800AFB
+:1026100003192021ACCF0024908E00C400AE6824A2
+:1026200031AC00FF1180FFEAAF840028248E0078CF
+:1026300095CD00123C0C08008D8C31A831AB3FFFCA
+:1026400001924821000B5180012A402101052024DC
+:10265000ACC400283107007F3C06800C00E6202136
+:102660009083000D00A31024304500FF10A0FFD878
+:10267000AF8400309098000D330F001015E0FFD5A7
+:102680008FBF00200E001863000000003C03800094
+:102690008C7901B80720FFFE00000000AE12000098
+:1026A0008C720144AE120004A6110008241100022D
+:1026B000A211000BAE1300240A001FC68FBF00201A
+:1026C0003C1260008E452C083C03F0033462FFFF8F
+:1026D00000A2F824AE5F2C088E582C083C1901B0DB
+:1026E00003199825AE532C080A001FC68FBF00207F
+:1026F000264D010031AF007F3C10800A240EFF8080
+:1027000001F0282101AE60243C0B8000AD6C002458
+:102710001660FFAFAF85002824110003A0B100ECC4
+:102720000A001FC68FBF002026480100310A007F23
+:102730003C0B800A2409FF80014B30210109202431
+:102740003C078000ACE400240A001FC5AF860028C7
+:10275000944A001232083FFF314C3FFF1588FF8436
+:102760002419608290CF00C4240EFF8001CF48243A
+:10277000312D00FF11A0FF7E00000000240700049F
+:10278000A0C700EC8F870030241860842406000D59
+:10279000A4B80008A0A600050A001FB0241F00026C
+:1027A0000800330C0800330C080033E8080033BC81
+:1027B000080033A0080032F0080032F0080032F0C0
+:1027C00008003314800801008008008080080000A1
+:1027D0005F865437E4AC62CC50103A4536621985B6
+:1027E000BF14C0E81BC27A1E84F4B556094EA6FE7B
+:1027F0007DDA01E7C04D748108007A7408007AC060
+:1028000008007A80080079A808007A8008007AB069
+:1028100008007A80080079A8080079A8080079A83B
+:10282000080079A8080079A8080079A8080079A804
+:10283000080079A8080079A8080079A808007AA0FB
+:1028400008007A90080079A8080079A8080079A8FB
+:10285000080079A8080079A8080079A8080079A8D4
+:10286000080079A8080079A8080079A8080079A8C4
+:10287000080079A808007A900800806C08007F148E
+:102880000800803408007F140800800408007DFCE4
+:1028900008007F1408007F1408007F1408007F14CC
+:1028A00008007F1408007F1408007F1408007F14BC
+:1028B00008007F1408007F1408007F1408007F14AC
+:0428C00008007F3C51
+:0C28C4000A0001220000000000000000DB
+:1028D0000000000D747061352E302E306A33000018
+:1028E00005000001000000000000000000000000E2
+:1028F00000000000000000000000000000000000D8
+:1029000000000000000000000000000000000000C7
+:1029100000000000000000000000000000000000B7
+:1029200000000000000000000000000000000000A7
+:102930000000000000000000000000000000000097
+:102940000000000000000000000000000000000087
+:1029500010000003000000000000000D0000000D4A
+:102960003C02080024421C203C03080024631FA0F2
+:10297000AC4000000043202B1480FFFD24420004E3
+:102980003C1D080037BD2FFC03A0F0213C100800BF
+:10299000261004883C1C0800279C1C200E0002E224
+:1029A000000000000000000D2402FF8027BDFFE0B2
+:1029B00000821024AFB00010AF420020AFBF00185B
+:1029C000AFB10014936500043084007F03441821E4
+:1029D0003C0200080062182130A50020036080211D
+:1029E0003C080111277B000814A000022466005C4B
+:1029F00024660058920200049743010492040004E4
+:102A00003047000F3063FFFF308400400067282309
+:102A100010800009000048219202000530420004A5
+:102A2000104000050000000010A00003000000009E
+:102A300024A5FFFC24090004920200053042000492
+:102A4000104000120000000010A000100000000064
+:102A50009602000200A72021010440252442FFFE27
+:102A6000A7421016920300042402FF8000431024A2
+:102A7000304200FF104000033C0204000A000172D3
+:102A8000010240258CC20000AF4210188F4201782D
+:102A90000440FFFE2402000AA74201409602000201
+:102AA00024040009304200070002102330420007CE
+:102AB000A7420142960200022442FFFEA7420144BF
+:102AC000A740014697420104A74201488F420108EE
+:102AD0003042002050400001240400019202000412
+:102AE000304200101440000234830010008018218E
+:102AF000A743014A000000000000000000000000A1
+:102B000000000000AF4810000000000000000000BE
+:102B100000000000000000008F4210000441FFFE92
+:102B20003102FFFF10400007000000009202000485
+:102B30003042004014400003000000008F42101893
+:102B4000ACC20000960200063042FFFF24420002A1
+:102B50000002104300021040036288219622000008
+:102B60001120000D3044FFFF00A710218F83003893
+:102B70008F45101C000210820002108000431021BB
+:102B8000AC45000030A6FFFF0E0002D100052C026C
+:102B900000402021A6220000920300042402FF80AE
+:102BA00000431024304200FF1040001F00000000CE
+:102BB00092020005304200021040001B000000009D
+:102BC0009742100C2442FFFEA7421016000000009E
+:102BD0003C02040034420030AF421000000000000C
+:102BE0000000000000000000000000008F42100004
+:102BF0000441FFFE000000009742100C8F45101C9E
+:102C00003042FFFF24420030000210820002108098
+:102C1000005B1021AC45000030A6FFFF0E0002D182
+:102C200000052C02A622000096040002248400085D
+:102C30000E0001E73084FFFF974401040E0001F508
+:102C40003084FFFF8FBF00188FB100148FB00010C9
+:102C50003C02100027BD002003E00008AF420178CD
+:102C60003084FFFF308200078F850024104000026F
+:102C7000248300073064FFF800A4102130421FFFB6
+:102C800003421821247B4000AF850028AF82002436
+:102C900003E00008AF4200843084FFFF3082000F61
+:102CA0008F85002C8F860034104000022483000F93
+:102CB0003064FFF000A410210046182BAF850030CF
+:102CC0000046202314600002AF82002CAF84002C49
+:102CD0008F82002C340480000342182100641821E4
+:102CE000AF83003803E00008AF4200808F820014F9
+:102CF000104000088F8200048F82FFCC1440000532
+:102D00008F8200043C02FFBF3442FFFF0082202478
+:102D10008F82000430430006240200021062000F7C
+:102D20003C0201012C620003504000052402000413
+:102D30001060000F3C0200010A00022E000000009B
+:102D400010620005240200061462000C3C0201110E
+:102D50000A000227008210253C0200110082102583
+:102D6000AF421000240200010A00022EAF82000CC4
+:102D700000821025AF421000AF80000C0000000060
+:102D8000000000000000000003E000080000000058
+:102D90008F82000C10400004000000008F421000E1
+:102DA0000441FFFE0000000003E0000800000000F6
+:102DB0008F8200102443F800000229C224A2FFF0F1
+:102DC0002C63030110600003000210420A00025548
+:102DD000AC8200008F83001800A3102B1440000B5E
+:102DE0000000382100A31023244600018F82001C1C
+:102DF000006210212442FFFF0045102B54400004C4
+:102E00002402FFFF0A000255AC8600002402FFFFE7
+:102E10000A00025AAC8200008C8200003C030800C9
+:102E200024631C5C000211400043382103E00008C9
+:102E300000E010213C0908008D291D80000451404C
+:102E40003C19080027391C5C00C0782100806021F3
+:102E5000240EFFFF000038210159402111200036C7
+:102E6000000030213C18080027181D983C0D080070
+:102E700025AD1D9C000F582B000611800046102127
+:102E8000000218C0007810218C420000158200203A
+:102E9000006D20218CA20000544000098D02001812
+:102EA0003C0208008C421D8424420001AC820000D8
+:102EB0003C010800AC221D840A0002CF0000202142
+:102EC0008F47002000003021000211C01160004A2D
+:102ED000AF4200208D08001C3C0900088CA30000B4
+:102EE0000066182100031880007A10210049102183
+:102EF0008C44000024C600010068182100CF102B6C
+:102F00001440FFF6AC6400000A0002CD000000008F
+:102F10008C840000008E102B5040000424C6000159
+:102F20000080702100C0382124C6000100C9102B88
+:102F30001440FFD20006118024020001ACA2000060
+:102F40003C0208008C421D7C3C0308008C631D8001
+:102F50000043102B1440002A2404FFFE01591021C5
+:102F60008C420018104000262404FFFF0007218037
+:102F70003C0508008CA51D84008720218D060018C3
+:102F8000000420C03C02080024421D980082102149
+:102F90003C03080024631D9CAC4C000024A50001E8
+:102FA000008318213C02080024421DA0AC650000EB
+:102FB000000631C03C010800AC251D8400822021A0
+:102FC0008F470020AD04001CAF46002011E0000A2E
+:102FD000000030213C020008034228218CA200009E
+:102FE00024C6000100CF182BAC82000024A50004E9
+:102FF0001460FFFA24840004AF4700200000202161
+:1030000003E00008008010213084FFFF30C6FFFF7E
+:1030100000052C0000A628253882FFFF004510215E
+:103020000045282B0045102100021C023042FFFF02
+:103030000043102100021C023042FFFF0043102118
+:103040003842FFFF03E000083042FFFF27BDFFC802
+:10305000AFBF0030AFB3002CAFB20028AFB1002437
+:10306000AFB000203C0460088C8250002403FF7F36
+:103070003C066000004310243442380CAC825000FF
+:103080008CC24C1C3C1A8000000216023042000F19
+:1030900010400007AF82001C8CC34C1C3C02001F78
+:1030A0003442FC0000621824000319C2AF830018E8
+:1030B0008F420008275B400034420001AF42000805
+:1030C000AF8000243C02601CAF400080AF40008411
+:1030D0008C4500088CC3080834028000034220217C
+:1030E0002402FFF0006218243C0200803C0108002A
+:1030F000AC2204203C025709AF840038146200045B
+:10310000AF850034240200010A000314AF820014CA
+:10311000AF8000142403003D240200043C01080099
+:10312000AC221D943C010800AC231D903C0108001A
+:10313000AC231D8C3C010800AC231D883C13080007
+:1031400026731C5C240400043C02080024421C7406
+:10315000240300082463FFFFAC400004AC400000DF
+:103160000461FFFC24420020000410C00044102130
+:103170002442003D3C010800AC221D9024020001C5
+:103180003C010800AC221D7C2402FFFF3C0108002A
+:10319000AC221D983C010800AC201D848F42000029
+:1031A00038420001304200011440FFFC8F820014BD
+:1031B0001040001600000000974201041040000576
+:1031C0008F830000146000072462FFFF0A00034B96
+:1031D0002C62000A2C620010504000048F83000013
+:1031E00024620001AF8200008F8300002C62000A7D
+:1031F000144000032C6200070A000352AF80FFCC8A
+:103200001040000224020001AF82FFCC8F4301086E
+:103210008F44010030622000AF830004104000089A
+:10322000AF8400103C0208008C42042C24420001B0
+:103230003C010800AC22042C0A0006D73C024000E6
+:103240003065020014A0000324020F001482030959
+:1032500024020D0097420104104003713C0240001B
+:1032600030624000144000AD8F8200388C4400086A
+:103270008F4201780440FFFE24020800AF4201782B
+:1032800024020008A7420140A740014297420104DE
+:103290008F8400043051FFFF30820001104000078E
+:1032A000022080212623FFFE240200023070FFFF4F
+:1032B000A74201460A00037FA7430148A7400146F1
+:1032C0003C0208008C42043C1440000D8F83001027
+:1032D000308200201440000224030009240300016E
+:1032E000006020218F830010240209005062000139
+:1032F00034840004A744014A0A00039A0000000035
+:1033000024020F00146200053082002014400006E1
+:103310002403000D0A000399240300051440000251
+:103320002403000924030001A743014A3C020800CA
+:103330008C4204203C0400480E00020A0044202570
+:103340000E000233000000008F82000C1040003E8F
+:10335000000000008F4210003C03002000431024B6
+:10336000104000398F8200043042000210400036C5
+:1033700000000000974210141440003300000000C9
+:10338000974210088F8800383042FFFF2442000621
+:10339000000218820003388000E830213043000129
+:1033A0008CC4000010600004304200030000000DD7
+:1033B0000A0003DB00E81021544000103084FFFFB6
+:1033C0003C05FFFF00852024008518260003182BEC
+:1033D0000004102B004310241040000500000000E2
+:1033E000000000000000000D000000002400021C8E
+:1033F0008CC200000A0003DA004520253883FFFF55
+:103400000003182B0004102B00431024104000056B
+:1034100000000000000000000000000D000000009F
+:10342000240002258CC200003444FFFF00E8102174
+:10343000AC4400003C0208008C42043024420001ED
+:103440003C010800AC2204308F6200008F840038F9
+:10345000AF8200088C8300003402FFFF1462000F6B
+:10346000000010213C0508008CA504543C04080011
+:103470008C84045000B0282100B0302B0082202121
+:10348000008620213C010800AC2504543C010800C2
+:10349000AC2404500A0006CD240400088C820000ED
+:1034A000304201001040000F000010213C050800D0
+:1034B0008CA5044C3C0408008C84044800B02821EE
+:1034C00000B0302B00822021008620213C01080022
+:1034D000AC25044C3C010800AC2404480A0006CD8D
+:1034E000240400083C0508008CA504443C040800A2
+:1034F0008C84044000B0282100B0302B00822021B1
+:10350000008620213C010800AC2504443C01080051
+:10351000AC2404400A0006CD240400088F62000891
+:103520008F62000000021602304300F024020030D7
+:1035300010620005240200401062016B8F8200209F
+:103540000A0006D52442000114A000050000000076
+:10355000000000000000000D0000000024000250E8
+:103560008F4201780440FFFE000000000E00023B85
+:1035700027A4001014400005004080210000000036
+:103580000000000D00000000240002578E02000021
+:103590001040000500000000000000000000000DC9
+:1035A000000000002400025A8F62000C0443000354
+:1035B000240200010A00055DAE000000AE0200001A
+:1035C0008F8200388C450008A20000078F65000C30
+:1035D0008F64000430A3FFFF000424020085202331
+:1035E000308200FF0043102124420005000288833E
+:1035F0002E220081A605000A14400005A204000442
+:10360000000000000000000D000000002400027215
+:103610003C0708008CE71D808FA800102409FFFFDD
+:103620000000502110E00013000030213C0C080085
+:10363000258C1D9C01802821000018218CA2FFFCF4
+:103640005102002F006C18218CA400002463020892
+:103650000089102B1040000324A502080080482197
+:1036600000C0502124C6000100C7102B5440FFF4B5
+:103670008CA2FFFC3C0508008CA51D803C020800C4
+:103680008C421D7C3C09080025291C603C03080075
+:1036900024631D9800A2102B3C0C0800258C1D9C57
+:1036A0003C0408008C841D843C0B0800256B1DA085
+:1036B0001040001A0008314000051180004510211B
+:1036C000000210C000C9382124840001004B3021C1
+:1036D0000043182124A50001004C1021AC68000013
+:1036E000ACE600183C010800AC241D84AC4400008A
+:1036F0003C010800AC251D800A0004A88E04001CB3
+:103700003C0208008C421D84244200013C01080058
+:10371000AC221D840A0004A7AC620000000A1180DC
+:10372000004A1021000210C0004328218CA3000091
+:10373000004C3821248400010003194000C93021C5
+:1037400000691821004B1021ACA80000AC600018E3
+:103750003C010800AC241D84ACC20018ACE400009D
+:103760008E04001C8F8500380E0006E702203021F1
+:103770008F6200048F430108A60200083C0210007B
+:103780000062182410600008000000009742010445
+:10379000920300072442FFEC346300023045FFFF30
+:1037A0000A0004BCA2030007974201042442FFF070
+:1037B0003045FFFF960600082CC200135440000558
+:1037C000920300079202000734420001A2020007A0
+:1037D0009203000724020001106200052402000386
+:1037E0001062000B30C7FFFF0A0004DB24E2000276
+:1037F0008F8200383C04FFFF8C43000C00641824C7
+:1038000000651825AC43000C0A0004DA30C7FFFF3E
+:103810008F8200383C04FFFF8C43001000641824A2
+:1038200000651825AC43001030C7FFFF24E20002FA
+:1038300000021083A20200058F830038304200FF8F
+:1038400000021080004330218CC500008CC20000B3
+:1038500024030004000217021443001300000000B8
+:10386000974201043C03FFFF00A318243042FFFFEE
+:10387000004710232442FFFE00622825ACC500004B
+:10388000920400058E03001C308200FF00021080AD
+:1038900000431021904200003042000F00441021EC
+:1038A0000A000510A20200068CC40004974201041D
+:1038B0009603000A3085FFFF3042FFFF00471023C8
+:1038C0002442FFD60002140000A22825ACC5000443
+:1038D0009202000792040005246300280003188365
+:1038E0000064182134420004A2030006A20200076B
+:1038F0008F8200042403FFFB3442000200431024A3
+:10390000AF820004920300068E07001C8F860038E9
+:1039100000031880006710218C44000C3C02FFF665
+:103920003442FFFF0082282400661821AE04000CF8
+:10393000AC65000C920300068E04000C3C02FF7F75
+:103940003442FFFF0003188000A2282400822024B4
+:1039500000671821AE04000CAC65000C9202000652
+:10396000000210800047102194450012AC45001061
+:10397000920200060002108000461021AC450010A3
+:103980008FA200109203000500021140000318806E
+:1039900000671821005320218C6200048C830018DA
+:1039A0001460000EAE0200143C0308008C631D8CF2
+:1039B000AC8300183C0208008C421D900062102B62
+:1039C00010400019000000003C0208008C421D94C9
+:1039D000006210213C010800AC221D8C8E020018F0
+:1039E0008F48002000003021000211C01220000B7F
+:1039F000AF4200203C0200080342282100E02021C1
+:103A00008C82000024C6000100D1182BACA200005B
+:103A1000248400041460FFFA24A50004AF480020A9
+:103A20000A00055E24020010000000000000000DE6
+:103A300000000000240002D424020010A74201402C
+:103A400024020002A7400142A7400144A7420146C8
+:103A5000974201043C0400082442FFFEA7420148AB
+:103A6000240200010E00020AA742014A9603000A3E
+:103A70009202000400431021244200023042000759
+:103A800000021023304200070E000233AE02001085
+:103A90008F6200003C0308008C630444240400107F
+:103AA000AF820008974201043042FFFF2442FFFE2C
+:103AB00000403821000237C33C0208008C42044019
+:103AC000006718210067282B0046102100451021AF
+:103AD0003C010800AC2304443C010800AC22044033
+:103AE0000A0006620000000014A0000500000000AB
+:103AF000000000000000000D00000000240003048E
+:103B00008F4201780440FFFE000000000E00023BDF
+:103B100027A400141440000500408021000000008C
+:103B20000000000D000000002400030B92060004BA
+:103B30008FA4001427A50018000630820E00025C36
+:103B4000AFA00018504000068E02000000000000E8
+:103B50000000000D00000000240003118E02000090
+:103B60005440000692020007000000000000000D13
+:103B700000000000240003169202000730420004F7
+:103B8000104000058F8200042403FFFB3442000232
+:103B900000431024AF8200048F6200040443000934
+:103BA00092020007920200068E03001C8E04000C95
+:103BB0000002108000431021AC44000CAE00000055
+:103BC00092020007304200045440000B92030004AC
+:103BD000920300058E0400148E05001C000318805B
+:103BE0003C0200010082202100651821AE0400146F
+:103BF000AC640004920300049602000A00621021E3
+:103C000024420005000290838FA200181040000D8E
+:103C1000277100088FA40014000310820242302391
+:103C200027A500180E00025CAFA200185040000645
+:103C30008E05001C000000000000000D00000000C8
+:103C40002400033F8E05001C022020210E0006E701
+:103C500002403021920400068F6500043C027FFF81
+:103C600000042080009120218C8300043442FFFF57
+:103C700000A2282400651821AC83000492020007EA
+:103C80009203000492050005304200041040001425
+:103C90009607000830A500FF0005288000B1282104
+:103CA0008CA40004974201049606000A306300FFCA
+:103CB0003042FFFF004310210046102130E3FFFF98
+:103CC000004310232442FFD83084FFFF0002140079
+:103CD00000822025ACA400040A0006169203000707
+:103CE00030A500FF0005288000B128218CA4000029
+:103CF00097420104306300FF3042FFFF0043102170
+:103D0000004710233C03FFFF008320243042FFFFC5
+:103D100000822025ACA400009203000724020001C9
+:103D2000106200060000000024020003106200116F
+:103D3000000000000A0006398E03001097420104BB
+:103D4000920300049605000A8E24000C0043102103
+:103D5000004510212442FFF23C03FFFF0083202492
+:103D60003042FFFF00822025AE24000C0A000639F5
+:103D70008E03001097420104920300049605000A86
+:103D80008E24001000431021004510212442FFEE34
+:103D90003C03FFFF008320243042FFFF00822025E8
+:103DA000AE2400108E0300102402000AA742014036
+:103DB000A74301429603000A920200043C0400401B
+:103DC00000431021A7420144A74001469742010445
+:103DD000A7420148240200010E00020AA742014A3C
+:103DE0000E000233000000008F6200009203000406
+:103DF00000002021AF820008974201049606000AC5
+:103E00003042FFFF00621821006028213C030800B7
+:103E10008C6304443C0208008C4204400065182175
+:103E2000004410210065382B004710213C01080098
+:103E3000AC2304443C010800AC220440920400047A
+:103E4000008620212484000A3084FFFF0E0001E751
+:103E500000000000974401043084FFFF0E0001F5CC
+:103E6000000000003C021000AF4201780A0006D4B6
+:103E70008F820020148200273062000697420104DE
+:103E8000104000673C0240003062400010400005D6
+:103E900000000000000000000000000D0000000015
+:103EA0002400041A8F4201780440FFFE2402080017
+:103EB000AF42017824020008A7420140A740014216
+:103EC0008F82000497430104304200011040000734
+:103ED0003070FFFF2603FFFE24020002A7420146C6
+:103EE000A74301480A00068C2402000DA7400146A2
+:103EF0002402000DA742014A8F620000240400083A
+:103F0000AF8200080E0001E7000000000A0006660C
+:103F100002002021104000423C0240009362000059
+:103F2000304300F0240200101062000524020070EB
+:103F3000106200358F8200200A0006D5244200015D
+:103F40008F620000974301043050FFFF3071FFFF84
+:103F50008F4201780440FFFE320200070002102366
+:103F6000304200072403000A2604FFFEA743014055
+:103F7000A7420142A7440144A7400146A751014876
+:103F80008F4201083042002014400002240300093F
+:103F900024030001A743014A0E00020A3C0400402A
+:103FA0000E000233000000003C0708008CE70444C8
+:103FB000021110212442FFFE3C0608008CC604407A
+:103FC0000040182100E33821000010218F65000017
+:103FD00000E3402B00C230212604000800C8302135
+:103FE0003084FFFFAF8500083C010800AC27044483
+:103FF0003C010800AC2604400E0001E70000000070
+:104000000A000666022020210E000139000000008F
+:104010008F82002024420001AF8200203C02400039
+:10402000AF4201380A000336000000003084FFFF71
+:1040300030A5FFFF000018211080000700000000DD
+:104040003082000110400002000420420065182167
+:104050000A0006DD0005284003E00008006010218A
+:1040600010C0000624C6FFFF8CA2000024A5000497
+:10407000AC8200000A0006E72484000403E0000884
+:104080000000000010A0000824A3FFFFAC86000081
+:1040900000000000000000002402FFFF2463FFFF77
+:1040A0001462FFFA2484000403E00008000000000A
+:0440B000000000010B
+:0C40B4000A00002A0000000000000000CC
+:1040C0000000000D747870352E302E306A330000F9
+:1040D000050000000000000A000001360000EA6050
+:1040E00000000000000000000000000000000000D0
+:1040F00000000000000000000000000000000000C0
+:1041000000000000000000000000000000000000AF
+:104110000000000000000016000000000000000089
+:10412000000000000000000000000000000000008F
+:10413000000000000000000000000000000000007F
+:1041400000000000000000000000000000001388D4
+:1041500000000000000005DC00000000000000007E
+:1041600010000003000000000000000D0000000D22
+:104170003C020800244238603C03080024633B14DE
+:10418000AC4000000043202B1480FFFD24420004BB
+:104190003C1D080037BD7FFC03A0F0213C10080047
+:1041A000261000A83C1C0800279C38600E0004075D
+:1041B000000000000000000D8F86003C3C039000D2
+:1041C0003C0280000086282500A32025AC44002066
+:1041D0003C0380008C67002004E0FFFE000000002C
+:1041E00003E00008000000000A0000412404000170
+:1041F0008F85003C3C0480003483000100A310251F
+:1042000003E00008AC82002003E000080000102159
+:104210003084FFFF30A5FFFF108000070000182149
+:104220003082000110400002000420420065182185
+:104230001480FFFB0005284003E000080060102107
+:1042400010C00007000000008CA2000024C6FFFF81
+:1042500024A50004AC82000014C0FFFB24840004E9
+:1042600003E000080000000010A0000824A3FFFFE6
+:10427000AC86000000000000000000002402FFFFE8
+:104280002463FFFF1462FFFA2484000403E00008A3
+:104290000000000090AA00318FAB00108CAC0040F1
+:1042A0003C0300FF8D680004AD6C00208CAD004421
+:1042B00000E060213462FFFFAD6D00248CA7004850
+:1042C0003C09FF000109C024AD6700288CAE004CFA
+:1042D0000182C82403197825AD6F0004AD6E002C4F
+:1042E0008CAD0038314A00FFAD6D001C94A900323E
+:1042F0003128FFFFAD68001090A70030A5600002D4
+:10430000A1600004A167000090A30032306200FFAA
+:104310000002198210600005240500011065000EDE
+:104320000000000003E00008A16A00018CD800280A
+:10433000354A0080AD7800188CCF0014AD6F0014A2
+:104340008CCE0030AD6E00088CC4002CA16A000138
+:1043500003E00008AD64000C8CCD001CAD6D0018AE
+:104360008CC90014AD6900148CC80024AD68000825
+:104370008CC70020AD67000C8CC200148C830070C9
+:104380000043C82B13200007000000008CC200145B
+:10439000144CFFE400000000354A008003E00008F0
+:1043A000A16A00018C8200700A0000B700000000C2
+:1043B0009089003027BDFFF88FA8001CA3A900003A
+:1043C0008FA300003C0DFF8035A2FFFF8CAC002CBA
+:1043D00000625824AFAB0000A100000400C05821C7
+:1043E000A7A000028D06000400A048210167C82193
+:1043F0008FA50000008050213C18FF7F032C202651
+:104400003C0E00FF2C8C0001370FFFFF35CDFFFF66
+:104410003C02FF0000AFC82400EDC02400C2782495
+:10442000000C1DC00323682501F87025AD0D0000A8
+:10443000AD0E00048D240024AFAD0000AD040008D3
+:104440008D2C00202404FFFFAD0C000C954700329A
+:1044500030E6FFFFAD0600109145004830A200FF96
+:10446000000219C2506000018D240034AD04001414
+:104470008D4700388FAA001827BD0008AD0B002813
+:10448000AD0A0024AD07001CAD00002CAD000018E3
+:1044900003E00008AD00002027BDFFE0AFB2001828
+:1044A000AFB10014AFB00010AFBF001C9098003047
+:1044B00000C088213C0D00FF330F007FA0CF00001B
+:1044C000908E003135ACFFFF3C0AFF00A0CE00010A
+:1044D00094A6001EA22000048CAB00148E290004B8
+:1044E00000A08021016C2824012A40240080902112
+:1044F00001052025A6260002AE2400042605002082
+:10450000262400080E0000632406000292470030B3
+:10451000260500282624001400071E0000031603A9
+:1045200024060004044000032403FFFF96590032D0
+:104530003323FFFF0E000063AE2300102624002467
+:104540008FBF001C8FB200188FB100148FB0001005
+:1045500024050003000030210A00006D27BD002063
+:1045600027BDFFD8AFB1001CAFB00018AFBF00200F
+:1045700090A900302402000100E050213123003FC7
+:1045800000A040218FB000400080882100C0482159
+:10459000106200148FA70038240B000500A0202112
+:1045A00000C02821106B0013020030210E0000F91A
+:1045B000000000009225007C30A40002108000035F
+:1045C00026030030AE000030260300348FBF0020E9
+:1045D0008FB1001C8FB000180060102103E00008AC
+:1045E00027BD00280E000078AFB000100A0001407F
+:1045F000000000008FA3003C0100202101202821A1
+:1046000001403021AFA300100E0000BFAFB0001476
+:104610000A000140000000003C0580008CA30E1041
+:104620008F840044AC8300208CA20E1803E00008A5
+:10463000AC8200243C0580008CA30E148F840044BF
+:10464000AC8300208CA20E1C03E00008AC82002486
+:104650009382000C1040001B2483000F2404FFF001
+:104660000064382410E00019978B00109784000E26
+:104670009389000D3C0A601C0A00017B0164402301
+:1046800001037021006428231126000231C2FFFFBC
+:1046900030A2FFFF0047302B50C0000E00E448213D
+:1046A0008D4D000C31A3FFFF00036400000C2C03B0
+:1046B00004A1FFF30000302130637FFF0A00017383
+:1046C0002406000103E00008000000009784000EAB
+:1046D00000E448213123FFFF3168FFFF0068382BD9
+:1046E00054E0FFF8A783000E938A000D11400005E7
+:1046F000240F0001006BC023A380000D03E000081D
+:10470000A798000E006BC023A38F000D03E00008E4
+:10471000A798000E03E000080000000027BDFFE896
+:10472000AFB000103084FFFF3C10800093A8002B36
+:10473000AFBF0014A6040144960A0E1630C600FF4F
+:104740008FA90030A60A0146AE050148A206015213
+:10475000A608015AAE0701608FA3002CA6090158D4
+:10476000012020210E000167AE0301543C0210001D
+:10477000AE0201788FBF00148FB0001003E0000874
+:1047800027BD00188F8500002484000727BDFFF88F
+:104790003084FFF83C06800094CB008A316AFFFF2A
+:1047A000AFAA00008FA90000012540232507FFFFC5
+:1047B00030E31FFF0064102B1440FFF700056882F0
+:1047C000000D288034CC400000AC102103E000082C
+:1047D00027BD00088F8200002486000730C5FFF83F
+:1047E00000A2182130641FFF03E00008AF8400001E
+:1047F0008F8500448F8A003C27BDFFB03C048000B9
+:10480000AFB70044AFB40038AFB1002CAFBF004821
+:10481000AFB60040AFB5003CAFB30034AFB200302C
+:10482000AFB000288C8701048CA90024AC8A0080DA
+:104830008CA8002000E988230000B821AC880E1065
+:104840008CA600240000A021AC860E188C820E10CD
+:10485000AC820E148C830E18AC830E1C122000FB4D
+:104860003C168000936B0008116000F1000000000E
+:10487000976E001031CDFFFF022D602B158000ECEC
+:104880000000000097700010320FFFFFAECF0E0047
+:104890003C0580008CB30000327200081240FFFD1E
+:1048A0000000000094B50E088CA70E0432A5FFFF8F
+:1048B00030B40001128000E1000000000000000D93
+:1048C00030B9A040241800401338011730B4A000BC
+:1048D000128000DC000000009373000812600008E2
+:1048E00000000000976900103122FFFF00E2202B3A
+:1048F0001080000330A6004010C000D2000000006D
+:10490000A7850040AF870038936A0008022038214D
+:10491000AFB10020154000F127B40020AF60000CBB
+:104920009785004030B14000162000022403001695
+:104930002403000E24154007A363000AAF7500147A
+:10494000939000428F6F0014321900010019C24089
+:1049500001F84025AF680014978700408F6300146A
+:1049600030EE0010006E6825AF6D0014978C00408B
+:10497000318B000811600165000000008F65001494
+:104980003C0B10003C0A800000AB8825AF7100147E
+:1049900095460E0A3C0981002413000E30C2FFFF29
+:1049A00000492025AF640004A3730002937F000A2E
+:1049B0003406FFFC27F20004A372000A978D004022
+:1049C00031AC200011800157000000003C0780003E
+:1049D000978D004094EC0E0C97910040000D5842CA
+:1049E0003185C000316A000300051303322910002D
+:1049F00001429825000922030264F825001F90C097
+:104A0000A7720012979500409379000A00158182E1
+:104A10003218003C0319782125E8003CA3680009FE
+:104A200094EE0E0C31C33FFFA76300109763001292
+:104A30009367000900E3702125CD000231AC000727
+:104A4000000C582331650007A365000B9371000922
+:104A500097640012976A0010322200FF8F9100388D
+:104A6000979F004000444821012A98210266902126
+:104A700033F5004012A000053246FFFF00D1402B65
+:104A80003C12800011000016000098210226782BAD
+:104A900015E001368FA700203C1880008F100E14FF
+:104AA0003C058000AF100E108F190E1CAF190E18A8
+:104AB000AF060E008CB200003255000812A0FFFDB8
+:104AC0000000000094BF0E0800C088210000902163
+:104AD000A79F00408CA60E0424130001AF86003867
+:104AE000976900103135FFFF8E8C00000191202363
+:104AF00010800118AE8400009367000814E000D80D
+:104B0000000000000E0001B4240400108F8E004845
+:104B10003C0332000040282131C600FF00063C0063
+:104B200000E3602525CD0001AF8D0048AC4C0000AE
+:104B30009362000997640012937F000A304A00FFD5
+:104B4000308BFFFF014B48210009CC0033F000FF00
+:104B50000330C025ACB800048F8F00489788004010
+:104B60003103200010600103ACAF0008976F001202
+:104B700031E8FFFF06400101ACA8000C979000400F
+:104B80003205000814A0000226280006262800028C
+:104B90003C048000948B0E148C850E1C8F670004DF
+:104BA000936A00023164FFFF314900FFAFA9001092
+:104BB0008F7F0014AFA80018AFBF00140E00019A39
+:104BC00000000000240400100E0001C800000000D6
+:104BD0008E92000016400005000000008F7900143E
+:104BE0002405FFBF0325A024AF7400148F69000CB7
+:104BF0000135F821AF7F000C9375000816A000085E
+:104C00000000000012600006000000008F6B00141E
+:104C10003C0CEFFF3584FFFE01645024AF6A0014A2
+:104C2000A37300088FA700200A000316022020218A
+:104C3000AED10E000A0001F83C05800014E0FF210F
+:104C400030B9A0400E0001600000A0212E910001AB
+:104C50000237B02512C000178FBF00488F85003C77
+:104C600024170F0010B700CD3C0480008C99017808
+:104C70000720FFFE24150F0050B500EB3C04800018
+:104C80008C890E14240502403C141000AC890144A8
+:104C90008C9F0E1CAC9F0148A0800152A480015A39
+:104CA000AC800160A4800158AC850154AC940178BB
+:104CB0008FBF00488FB700448FB600408FB5003CCF
+:104CC0008FB400388FB300348FB200308FB1002C16
+:104CD0008FB0002803E0000827BD00508F910038F6
+:104CE000979300403C1280000220A821326A0040C5
+:104CF0001540FF7D00009821976B00108F850038CC
+:104D00003162FFFF104500A2000020210080A02199
+:104D1000108000E500E088211620FED2000000008F
+:104D20000A0002E72E9100013C0380008C7F01788D
+:104D300007E0FFFE240408008F860000AC640178C1
+:104D40003C038000946C008A318BFFFF0166502386
+:104D50002549FFFF31281FFF2D0200081440FFF9ED
+:104D6000000000008F8E0048346F40008F83003CAD
+:104D700000E0A021240D0F0025C70001AF870048E7
+:104D800000CF3021023488233C08800031D500FF59
+:104D9000106D000524070001939300423272000158
+:104DA0000012824036070001001514003C09010082
+:104DB00000492025ACC400008F9F004830B9003660
+:104DC00030B80008ACDF00041300009000F998250B
+:104DD00095070E0A8F8E00003C03810030EDFFFF27
+:104DE00025CB000801A328253C0C1000316A1FFFC9
+:104DF000269200062406000EAD050160026C98257F
+:104E0000A506015AAF8A0000A51201581620000815
+:104E10003C1080008F99003C24180F00533800028A
+:104E200024170001367300400E0001593C10800029
+:104E30008E1F0E1402402021AE1F01448E120E1C44
+:104E4000AE120148A2150152AE1301540E000167C3
+:104E50003C151000AE1501780A000319000000008F
+:104E600093780009976300129368000B330F00FFDB
+:104E700001E33821310200FF00E2702125D0000A51
+:104E80003210FFFF0E0001B4020020218F8600487F
+:104E90003C1941003C07800024CD0001AF8D004843
+:104EA000936C00099764001230C600FF318A00FF3E
+:104EB000308BFFFF014B482100062C00253F0002EC
+:104EC00000BFC02503197825AC4F00008F68000C87
+:104ED00094EE0E1401121825AC4300048CE50E1C50
+:104EE0008F670004936D000231C4FFFF31AC00FFF7
+:104EF000AFAC00108F620014AFB100180E00019A21
+:104F0000AFA200140A0002C502002021AF60000415
+:104F1000A3600002978D004031AC20001580FEABED
+:104F200000003021A7600012979000409378000A9B
+:104F30003C03800032191F000019798301F84021D9
+:104F400025070028A3670009946E0E0C0A00025E74
+:104F5000A76E00108F6E001435CD00400E00015971
+:104F6000AF6D00140A000291000000000A00031651
+:104F7000000020210641FF01ACA0000C8CB8000C01
+:104F80003C198000031990250A0002B2ACB2000C53
+:104F9000000090210A00028D2413000112800005F8
+:104FA0003C0D800095A60E0830D3004012600042F0
+:104FB000000000008C9001780600FFFE0000000059
+:104FC00094920E103C030500240720003258FFFF86
+:104FD00003037825AC8F014C8C880E143C0E100016
+:104FE000AC8801448C820E1CAC820148A080015226
+:104FF000A480015AAC800160A4800158AC870154A0
+:10500000AC8E01780A0002EE3C0480008F90000014
+:1050100026920002A5120158260F000831E81FFF52
+:105020000A000356AF880000AC80014C12800019C2
+:10503000000000008C8A0E10AC8A01448C830E188C
+:105040003C0C800024160040AC8301488FBF004810
+:10505000A18001528FB70044A580015A8FB5003C52
+:10506000AD8001608FB40038A58001588FB3003443
+:10507000AD9601548FB200308FB600408FB1002C36
+:105080008FB000283C04100027BD005003E000084A
+:10509000AD8401788C8B0E14AC8B01448C830E1C78
+:1050A0000A0003E43C0C80000E0001602E91000118
+:1050B0000A0002E80237B025000000000000000DE1
+:1050C000000000002400033A0A0003C03C048000F2
+:1050D00027BDFFE0AFBF001C3C1F20FF3C07600066
+:1050E0003C0980002402001037F9FFFDACE23008D3
+:1050F000AFB20018AFB10014AFB00010AD390E0060
+:10510000000000000000000000000000000000009F
+:10511000000000003C1800FF3712FFFDAD320E000A
+:105120003C0B60048D7050002411FF7F3C0E000288
+:105130000211782435EC380C35CD0109ACED4C1852
+:10514000240A0009AD6C50008CE80438AD2A000830
+:10515000AD2000148CE54C1C3106FFFF38C42F71C4
+:1051600000051E023062000F2486C0B31040000705
+:10517000AF8200088CE54C1C3C09001F3528FC0060
+:1051800000A81824000321C2AF8400048CF1080891
+:105190003C0F57092412F0000232702435F0001041
+:1051A00001D0602601CF68262DAA00012D8B0001B9
+:1051B000014B382550E00009A380000C3C02601C24
+:1051C0008C590008241F0001A39F000C33387C0079
+:1051D000A7980010A780000EA380000DAF800048A4
+:1051E00014C00003AF8000003C066000ACC0442C3B
+:1051F0000E0004B63C1080000E000DDF0000000021
+:105200003C110800263138C83C12080026523948A3
+:105210008E05000038A30001306400011480FFFCFB
+:10522000000000008E0601003C0C800A240AFF806A
+:1052300024C7024030EB007F016C482100EA402483
+:10524000AE060020AF890044AE0800243C03800075
+:10525000AF86003C8C6D017805A0FFFE2419080084
+:10526000AC79017890780108A3980042938F0042AE
+:1052700031EE000111C0000F240D0D0024C2F80012
+:105280002C5F030113E0001C000629C224A3FFF0D9
+:1052900000032042000431400E0001CF00D1D8218C
+:1052A0003C0440003C068000ACC401380A000457AE
+:1052B0000000000010CD0026240E0F0010CE002AA2
+:1052C0003C028008345F008093F90000240F0050F6
+:1052D000333800FF170FFFF33C0440000E000912A3
+:1052E000000000003C0440003C068000ACC40138D3
+:1052F0000A000457000000008F83000400A3402B25
+:105300001500000B8F8B0008006B50212547FFFF15
+:1053100000E5482B1520000600A36023000C29405F
+:105320000E0001CF00B2D8210A00047C3C044000EA
+:10533000000000000000000D00000000240003AD8C
+:105340000E0001CF000000000A00047C3C04400075
+:105350003C1B0800277B3A480E0001CF00000000EC
+:105360000A00047C3C0440003C1B0800277B3A6890
+:105370000E0001CF000000000A00047C3C04400045
+:10538000000411C003E00008244202403C0408006D
+:1053900024843AAC2405001A0A00006D0000302174
+:1053A00027BDFFE0AFBF001CAFB20018AFB10014C3
+:1053B000AFB000103C108000920B01092412FF8056
+:1053C0000E0004B33164007F8F91003C00515021E6
+:1053D00001524024AE080024920301090E0004B3D8
+:1053E0003064007F24060080240700C024040040AD
+:1053F000AE000810AE040814AE060818AE07081C6C
+:10540000920C01090051F82133F8007F3C19800A01
+:10541000031910213184007F0E0004B3AF820044D1
+:105420008E1101003C0C008035850001022278219C
+:1054300001F24824AE0908048E0E010035980002DE
+:105440003609090001C2682131AB00780165502599
+:10545000AE0A08208E0501008E080100360509807D
+:10546000010218212464004000923024AE0608088E
+:105470008E07010000E2F82127F90040333200785E
+:1054800002588825AE1108248E040100952F000CC7
+:105490008FBF001C8FB2001831EEFFFF000E69C0F5
+:1054A000AE0D0800AE0C0828952B000C8FB100142F
+:1054B000316AFFFF000A41C0AE08002C8CA30050E7
+:1054C0008FB000108CA2003C8D2400048CA6001C20
+:1054D0008CA7003827BD0020AF830060AF8200504A
+:1054E000AF84004CAF86005803E00008AF87005C33
+:1054F0003C0A0800914A3AD13C09080095293ACA69
+:105500003C051100000A3C002528000200E8302577
+:1055100000C5182524820008AC83000003E00008C1
+:10552000AC8000043C098000352809009107001177
+:10553000240200280080502130E300FF00A06821F1
+:1055400000C0602110620002340B86DD240B0800CD
+:105550003C07800034E20A9A9443000034F80A9C25
+:1055600034E60AA03079FFFFAD5900008F0F00002C
+:1055700034E80A8024040001AD4F00048CCE000002
+:10558000AD4E00089105001930A3000310640046D9
+:1055900028690002152000B5240400021064009060
+:1055A000240500031065009B34E40AA43C090800AC
+:1055B00095293AC024070800516700503C18800024
+:1055C0003C0280003459090093280012932E0019E0
+:1055D00034580980310F00FF8F06002801EC182194
+:1055E000000338803124FFFF31CB00FF00E410219D
+:1055F000000B2D0000A6C02500027C003C086000C6
+:105600000308182535E906FFAD430000AD49000445
+:105610008F2E002C3C0380003478093CAD4E0008EE
+:105620008F27003025490028346E0900AD47000C53
+:105630008F2B0034AD4B00108F240038AD44001484
+:105640008F25001CAD4500188F220020AD42001CA4
+:105650008F26002425220014AD4600208F28002824
+:10566000AD4800248F0F0000AD2D0004AD2F0000C9
+:105670008C64010CAD24000891C700123C050800A1
+:1056800090A53AD0AD20001030EB00FF016C302126
+:1056900000066F000005CC0001B96025358AFFFFC8
+:1056A00003E00008AD2A000C3C09080095293AC027
+:1056B0003C19080097393ACA34E20AA43C060800AB
+:1056C00094C63ABC944F00003123FFFF0323C0214E
+:1056D00003067023000F3C0025C8FFF200E82825D0
+:1056E00024070800AD45000CAD400010AD4B001480
+:1056F0001567FFB3254A00183C18800037080900D9
+:10570000910F00119107001937030A8031EE00FF55
+:105710003C19080097393AC6946F002A000E588247
+:1057200030E400FF97870054000B160000042C00A3
+:105730003126FFFF0326C02100454825013870258A
+:1057400001E758213C03400001C32025000B2C0039
+:10575000AD440000AD450004910200183C0600066F
+:105760003C0380000002CE000326C025AD5800088F
+:105770008D0F002C3478093C24E90001AD4F000C5A
+:105780008D0B001C312E7FFF25490014AD4B0010FE
+:105790008F0F0000AD2D0004A78E0054AD2F000028
+:1057A0008C64010C346E090025220014AD2400081D
+:1057B00091C700123C05080090A53AD0AD2000101A
+:1057C00030EB00FF016C302100066F000005CC00BB
+:1057D00001B96025358AFFFF03E00008AD2A000CFF
+:1057E00034E90AA495240000950200283C09080029
+:1057F00095293AC000041C000002CC0034788100D6
+:10580000032B7825AD58000CAD4F00100A00054061
+:10581000254A00143C09080095293AC03C050800B7
+:1058200094A53ACA3C06080094C63ABC9499000074
+:105830003123FFFF9518002800A31021004678238C
+:1058400000193C000018440025EEFFEE010E28254B
+:1058500034E48100AD44000CAD450010AD400014AF
+:10586000AD4B00180A000540254A001C1460FF4F8C
+:1058700034E60AA494CE00003C09080095293AC0F9
+:10588000000E4400010B3825AD47000C0A0005400E
+:10589000254A001003E00008240207D027BDFFE0DE
+:1058A000AFB20018AFB10014AFB00010AFBF001C12
+:1058B0000E00004D008088218F8800508F87004C9B
+:1058C0003C05800834B20080011128213C10800082
+:1058D00024020080240300C000A72023AE02081881
+:1058E0003C068008AE03081C18800004AF850050F9
+:1058F000ACC500048CC90004AF89004C122000091B
+:10590000360409800E0005F800000000924C0027C4
+:105910008E0B007401825004014B3021AE46000C06
+:10592000360409808C8E001C8F8F005801CF6823AD
+:1059300019A000048FBF001C8C90001CAF90005871
+:105940008FBF001C8FB200188FB100148FB00010F1
+:105950000A00004F27BD00208F8600608F83005013
+:105960008F82004C3C05800834A40080AC86005037
+:10597000AC83003C03E00008ACA200043C03080038
+:105980008C63005427BDFFF8308400FF24620001BF
+:1059900030A500FF3C010800AC22005430C600FFD7
+:1059A0003C0780008CE801780500FFFE3C0A7FFF81
+:1059B000A3A400038FA400003549FFFF0089182429
+:1059C000000647C000681025AFA2000090F9010A48
+:1059D000A3A000023C1880FFA3B900018FAE000015
+:1059E00030AD007F370FFFFF01CF5824000D660058
+:1059F0003C090020016C5025352620002405FF803D
+:105A00003C04100027BD0008ACEA014CACE6015490
+:105A1000A4E00158A0E5015203E00008ACE40178DD
+:105A2000308800FF3C03800030A400FF8C620178C6
+:105A30000440FFFE000000003C03800034660A00C2
+:105A40008CCA0020346709800004482BAC6A0144EA
+:105A50008CC5002400091540AC650148A0680150C0
+:105A600090E4004CA064016D03E00008A4600158BC
+:105A700027BDFFE8308400FFAFBF00100E00065BBB
+:105A800030A500FF8F8300508FBF00103C058000C1
+:105A9000344600402404FF903C02100027BD00184B
+:105AA000ACA3014CA0A40152ACA6015403E0000831
+:105AB000ACA2017827BDFFE03C088008AFBF001C06
+:105AC000AFB20018AFB10014AFB0001035100080B5
+:105AD0008E0600183C078000309200FF00C720258A
+:105AE000AE0400180E00004D30B100FF9203000517
+:105AF000346200080E00004FA2020005024020217F
+:105B00000E00066F02202821024020218FBF001CBA
+:105B10008FB200188FB100148FB00010240500055B
+:105B2000240600010A00063227BD00203C05800043
+:105B300034A309809066000830C200081040000FAE
+:105B40003C0A01013549080AAC8900008CA80074A0
+:105B5000AC8800043C07080090E73AD030E500101C
+:105B600050A00008AC8000083C0D800835AC0080D7
+:105B70008D8B0058AC8B00082484000C03E00008D7
+:105B8000008010210A0006B22484000C27BDFFE823
+:105B90003C088000AFB00010AFBF0014350609808C
+:105BA00090C70009240200063509090030E300FF10
+:105BB0000080802100A06021240B00041062007985
+:105BC0002407000294CF005C3C0E020431EDFFFF7D
+:105BD00001AE5025AE0A000090C5000830A4002098
+:105BE000108000080000000090C2004E3C1F01031E
+:105BF00037F90300305800FF03193025240B000843
+:105C0000AE06000491390011912600129124001172
+:105C1000333800FF0018708230CF00FF01CF5021D1
+:105C2000014C6821308800FF31AAFFFF39030028AA
+:105C3000000A28801460002B0205402391240012E2
+:105C40003C0E800035D90980308500FF00AC18215A
+:105C500000031080004BF821001F8400360906FF66
+:105C6000AD09000435C9090091260011912F0012D9
+:105C7000000BC0828F2B003431ED00FF8DC4010C6E
+:105C800001AC282100B810210164F823000784002A
+:105C900000021F000070C82533E9FFFF30CF00FC71
+:105CA000032970250158202101E868210004508053
+:105CB000ADAE000C0E00004D010A80213C078008AB
+:105CC000240C000434EB00800E00004FA16C00098E
+:105CD000020010218FBF00148FB0001003E00008F5
+:105CE00027BD001891250011912300193C180800C8
+:105CF00097183AC630A200FF0002F882307000FF09
+:105D0000001FCE0000104C000329302500D870255C
+:105D10003C0F400001CF68253C0E8000AD0D000017
+:105D200035C9090091260011912F001235D909803B
+:105D3000000BC08231ED00FF8F2B00348DC4010CAD
+:105D400001AC282100B810210164F8230007840069
+:105D500000021F000070C82533E9FFFF30CF00FCB0
+:105D6000032970250158202101E868210004508092
+:105D7000ADAE000C0E00004D010A80213C078008EA
+:105D8000240C000434EB00800E00004FA16C0009CD
+:105D9000020010218FBF00148FB0001003E0000834
+:105DA00027BD00180A0006C42407001227BDFFD033
+:105DB000AFB50024AFB40020AFB3001CAFB00010EB
+:105DC000AFBF0028AFB20018AFB100143C0680008E
+:105DD00090C3010B309300FF30B400FF30620030FD
+:105DE0000000A821104000820000802134C40980F6
+:105DF0009088000800083E0000072E0304A000A9B8
+:105E0000240400048F8700503C010800A0243AD0ED
+:105E10003C0C8000AD8000483C038000906E010B7C
+:105E200031C5002010A000073C0C800034780980A8
+:105E30009312000800128E0000117E0305E000AEF0
+:105E40003C028008918B010B3586098090C40008C4
+:105E5000316A0040000A482B3088000824110003F2
+:105E60001500000200E99023000088213C03800017
+:105E700034780A80346A09009707002C9144001195
+:105E80009149001293050018309F00FF312800FF50
+:105E9000022810210002C880930D0018033F7821CA
+:105EA00001F0702130B000FF01D01821A787005405
+:105EB0003C010800A42E3AC63C010800A4233AC8BD
+:105EC00015A00003246B000A0000000D246B000ADB
+:105ED0003170FFFF3C010800A4233ACA3C010800CE
+:105EE000A4203AC03C010800A4203ABC0E0001B432
+:105EF000020020210E00050F00402021004020213B
+:105F0000024028210E00051C022030210E00069EB2
+:105F10000040202116A0005F004020210E0001C893
+:105F2000020020213C11080092313AD032350003A2
+:105F300012A000163C0A80088F8700503C0E800893
+:105F400035CD008024EC0001ADAC003C3C05800860
+:105F50008CA600040180202100CC90231A4000026E
+:105F6000AF8C00508CA400040E0005F8ACA4000413
+:105F70003C1980008F3800743C0F800835F0008099
+:105F800000582821AE05000C3C0A800835420080EC
+:105F90000260202102802821A040006B0E00065BD9
+:105FA0003C1380008F840050345F0006AE64014CC7
+:105FB0008F8800483C1410008FB50024250900018B
+:105FC000AF8900488FB20018A26801528FB1001447
+:105FD000AE7F01548FB00010AE7401788FBF0028DF
+:105FE0008FB400208FB3001C03E0000827BD0030F1
+:105FF00034C30980906F0008000F7600000E6E0316
+:1060000005A0003334C209009059001B241F001062
+:106010003C010800A03F3AD0333800021300FF7E55
+:106020008F8700508F83005C1467FF7C3C038000E7
+:106030000E00004D000000003C098008352500805E
+:1060400090A4000924070016308800FF1107000DF6
+:106050000000000090A600093C0C0800918C3AD08A
+:10606000240A000830C400FF358B00013C01080001
+:10607000A02B3AD0108A002F240D000A108D002882
+:106080002402000C0E00004F000000000A00075917
+:106090008F8700500E0006B6022028210A00079ABA
+:1060A000000000003C0B8008356A00808D470054DA
+:1060B0008CC9010C1120FF54AF8700502406001436
+:1060C0003C010800A0263AD00A0007583C0C80008A
+:1060D00090710008241200023C010800A0323AD05E
+:1060E000323000201200000B241500018F87005071
+:1060F0000A00075924100008345900808F23003803
+:10610000AC4300048C5F0004AF3F003C0A0007640E
+:106110003C0C80008F8700500A00075924100004AF
+:10612000A0A200090E00004F000000000A0007595D
+:106130008F870050240200140A00081CA0A2000946
+:1061400027BDFFE8AFBF0014AFB000103C108000C7
+:1061500092020109240500010E00065B304400FF95
+:106160003C1F800893F8000E37E3008093F9000F7E
+:10617000906E002693E9000A332F00FF0018660096
+:10618000000F6C0031CB00FF018D5025000B320059
+:1061900001463825312800FF3445600000E82025FD
+:1061A0002402FF813C031000AE04014C8FBF001499
+:1061B000AE050154A2020152AE0301788FB0001067
+:1061C00003E0000827BD001827BDFFE8308400FF6A
+:1061D000AFBF00100E00065B30A500FF3446004044
+:1061E0003C0480002405FF92AC860154A085015236
+:1061F0008F8300508FBF00103C02100027BD001895
+:10620000AC83014C03E00008AC82017827BDFFD8C5
+:10621000AFB20018AFB10014AFB00010AFBF002094
+:10622000AFB3001C3C07800090E20109308600FFFC
+:1062300030B000FF000618C23204000230710001C5
+:1062400014800007305200FF3C098008353300807D
+:10625000926800053105000810A0000C30CA00103B
+:10626000024020210E000680022028212402000185
+:106270008FBF00208FB3001C8FB200188FB10014A5
+:106280008FB0001003E0000827BD00281540003043
+:1062900034E50A008CB900248CB800081338004794
+:1062A000000040213C0E800835D30080926D0068CC
+:1062B000240B000231AC00FF118B00803C068000F3
+:1062C000927F004C90C40109509F00043213007C5F
+:1062D00011000067000000003213007C1660005AB5
+:1062E0000240202116200008320C00013C078000EB
+:1062F00034EB0A008D6500248CE8010414A8FFDC4F
+:1063000000001021320C00011180000D02402021FC
+:106310003C1080008E0E010C8F8D006011CD0008A6
+:10632000000000000E00073E022028218E0F010C05
+:106330003C18800837100080AE0F0050024020212A
+:106340000E00066F022028210A00086F24020001B7
+:106350003C0708008CE7006424E600013C010800CB
+:10636000AC2600641600000D000000000220282169
+:106370000E00066F02402021926F0068240D00027B
+:1063800031EE00FF11CD0022024020210E00082333
+:10639000000000000A00086F240200010E00004106
+:1063A00024040001926C0025020C58250E00004FB9
+:1063B000A26B00250A0008AF022028218E63001876
+:1063C0008CE401048CBF002400031602149FFFB567
+:1063D0003045007F9269004C264400013093007FD5
+:1063E00012650040312300FF1464FFAF3C0E8008AB
+:1063F000264800013111007F310200FF1225000BF9
+:1064000024080001004090210A00087C24110001AA
+:10641000240500040E000632240600010E000823A5
+:10642000000000000A00086F240200012407FF801A
+:106430000247282400A79026324200FF0040902106
+:106440000A00087C241100010E00073E02202821CA
+:106450003206003010C0FFA332100082024020211B
+:106460000E000680022028210A00086F2402000185
+:106470008E6300180240202102202821006610258A
+:106480000E000845AE6200189264004C240500031B
+:10649000240600010E000632308400FF0E00004189
+:1064A00024040001926A0025020A48250E00004FCC
+:1064B000A26900250A00086F240200018E780018E6
+:1064C0003C19800002402021031978250220282150
+:1064D0000E00066FAE6F00189264004C0A0008F7B9
+:1064E000240500043246008038CA0080146AFF6E1A
+:1064F0003C0E80080A0008D02648000127BDFFC0D6
+:10650000AFB000183C108000AFBF0038AFB7003408
+:10651000AFB60030AFB5002CAFB40028AFB3002445
+:10652000AFB200200E0004BBAFB1001C9204010802
+:106530009205010B308400FF0E00085630A500FFC5
+:10654000144000E38FBF00383C09800835280080E4
+:10655000A100006B3607098090E60000240200507D
+:106560003C17080026F73A8830C300FF3C130800A8
+:1065700026733A98106200033C1080000000B82196
+:1065800000009821241F001036110A0036140980DB
+:106590008E1601048F8D00508E38002436190A8023
+:1065A0008E9200203C010800A03F3AD0972C002C8E
+:1065B0008EF50000932B0018024D702302D878232B
+:1065C0003C010800AC2F3AAC3C010800AC2E3AB0BC
+:1065D0003C010800AC2D3AD4A78C005402A0F80965
+:1065E000317200FF304A0002154000E630450001DC
+:1065F00010A000C100000000928A0008315000087D
+:1066000016000002241400030000A0213C068000B4
+:1066100034C4090034C30A008C6E00249085001134
+:10662000908200129099001130B800FF305100FFA5
+:106630000291F821001FB080332F00FF02D85821AB
+:10664000024FA82126AC0010017268213C15800081
+:106650003C010800AC2E3AD83C010800A42D3AC8F1
+:106660003C010800A42C3AC43C010800A42B3AC603
+:1066700036B609808F8700508F8900588ED200204F
+:106680002408000601273023024728233C01080084
+:10669000AC283ACC04C000B30000902104A000B1A3
+:1066A00000C5802B120000B3000000003C01080070
+:1066B000AC263AB08E7100000220F80900000000FC
+:1066C000304A00021540007400408021304B000128
+:1066D000556000118E7100043C0D08008DAD3AB478
+:1066E0003C0EC0003C04800001AE6025AEAC0E0044
+:1066F0008C980000330F000811E0FFFD000000003F
+:10670000949F0E0824120001A79F00408C990E044C
+:10671000AF9900388E7100040220F80900000000D3
+:106720000202802532020002144000A9000000008D
+:106730003C08080095083ABC3C11080096313AC85C
+:106740003C09080095293ABE3C0308008C633AB422
+:10675000011168213C1F08008FFF3AD83C07080050
+:1067600094E73AD23C11800001A920218E38010C17
+:10677000006828212499000200A7702103E37821F2
+:10678000AF9800603C010800AC2F3AD83C010800EB
+:10679000A42E3AC03C010800A42D3ACA0E0001B450
+:1067A0003324FFFF8F8C0048004020213C0108006B
+:1067B000A02C3AD18E620008258B0001AF8B0048D7
+:1067C0000040F809000000008F8500500280302151
+:1067D0000E00051C004020210E00069E00402021D6
+:1067E0008E6A000C0140F809004020213C08080096
+:1067F00095083ACA3C09080095293ABE0109382192
+:1068000024E600020E0001C830C4FFFF3C0408006B
+:106810008C843AAC3C0308008C633AB40083282390
+:106820003C010800AC253AAC14A0000600000000B2
+:106830003C0A08008D4A3ACC354600403C0108002D
+:10684000AC263ACC124000418F8C00448E2B0E10A7
+:106850008F920044AE4B00208E220E18AE420024D0
+:106860003C04080094843AC00E0005FA00000000C1
+:106870008F9900508E7800103C010800AC393AD452
+:106880000300F809000000003C0F08008DEF3AAC4F
+:1068900015E0FF798F870050979400543C13800EC9
+:1068A000321500100E000629A674002C56A00044D4
+:1068B0008EF60004321F004057E0001D8EF00008E5
+:1068C0008EE3000C0060F809000000008FBF003864
+:1068D0008FB700348FB600308FB5002C8FB40028EE
+:1068E0008FB300248FB200208FB1001C8FB000182E
+:1068F00003E0000827BD0040920901098F88003C91
+:1069000000093E0000E83025AE0600808E230020FE
+:106910008E240024AFA30010AE030E148FA200102B
+:10692000AE020E10AE040E1C0A000951AE040E1881
+:106930000200F809000000008EE3000C0060F80976
+:10694000000000000A000A078FBF0038240E000173
+:10695000240D0001A5800020A58E00220A0009EB6D
+:10696000AD8D00243C010800AC203AB00A0009813A
+:106970008E7100003C010800AC253AB00A00098184
+:106980008E71000092110109000028210E00066F8F
+:10699000322400FF8FBF00388FB700348FB600302D
+:1069A0008FB5002C8FB400288FB300248FB2002045
+:1069B0008FB1001C8FB0001803E0000827BD004015
+:1069C00002C0F809000000000A000A01321F00405E
+:1069D0005240FFB2979400548EB60E148F93004429
+:1069E000AE7600208EB40E1CAE7400240A0009FAA4
+:1069F000979400548F8200140004218003E0000863
+:106A0000008210213C07800834E200809043006936
+:106A100000804021106000093C0401003C07080090
+:106A20008CE73AD48F83003000E3202304800008F1
+:106A30009389001C14E300030100202103E00008F7
+:106A4000008010213C04010003E0000800801021B8
+:106A50001120000B006738233C0D800035AC098005
+:106A6000918B007C316A000211400020240900341F
+:106A700000E9702B15C0FFF10100202100E9382347
+:106A80002403FFFC00A3C82400E3C02400F9782BF2
+:106A900015E0FFEA0308202130C40003000410239E
+:106AA00014C00014304900030000302100A97821EF
+:106AB00001E6702100EE682B11A0FFE03C0401000C
+:106AC0002D3800010006C82B010548210319382480
+:106AD00014E0FFDA2524FFFC2402FFFC00A21824A6
+:106AE0000068202103E00008008010210A000A6FDE
+:106AF000240900303C0C80003586098090CB007C56
+:106B0000316A00041540FFE9240600040A000A7EE9
+:106B1000000030213C0308008C63005C8F82001869
+:106B200027BDFFE8AFBF001410620005AFB0001032
+:106B3000000329C024A40280AF840014AF8300188E
+:106B40003C10800036030A00946500320E000A50A3
+:106B500030A43FFF8E0401003C180080370F000373
+:106B60000082C8212402FF80032260243329007F91
+:106B7000000CF94003E94025332E00783C0D10004D
+:106B8000010D502501CF5825AE0C0028360809808C
+:106B9000AE0C080CAE0B082CAE0A0830910300694D
+:106BA0003C06800C0126382110600006AF870034B7
+:106BB0008D09003C8D06006C0126382318E0007F0B
+:106BC000000000003C0C8008358B00803C0A8000EF
+:106BD000A1600069355009808E0200383C068000B3
+:106BE00034C50A0090AD003C31A800201100001906
+:106BF000AF820030240E00013C19800037300A00BB
+:106C0000A38E001CAF8000248E0400248F850024F6
+:106C100024180008AF800020AF8000283C01080045
+:106C2000A4383ABE3C010800A4203AD20E000A540F
+:106C300000003021920F003C8FBF00148FB0001075
+:106C4000000F7142AF82002C27BD001803E000083E
+:106C500031C2000190B90032240F0001333800FF27
+:106C600000182182108F003F241F0002109F006235
+:106C700034C20AC03C03800034640A008C990024AA
+:106C80001720001D3466090090830030241F000582
+:106C90003062003F105F004C240500018F86002009
+:106CA000A385001CAF860028AF8600243C19800015
+:106CB00037300A008E0400248F8500242418000831
+:106CC0003C010800A4383ABE3C010800A4203AD296
+:106CD0000E000A5400000000920F003C8FBF001409
+:106CE0008FB00010000F7142AF82002C27BD00183A
+:106CF00003E0000831C200018C8800088C8D00245C
+:106D00008CCB00643C19800037300A00AF8B002424
+:106D1000A380001C8E0400248F8600208F85002411
+:106D2000010D602324180008AF8C00283C010800E6
+:106D3000A4383ABE3C010800A4203AD20E000A54FE
+:106D400000000000920F003C8FBF00148FB00010B5
+:106D5000000F7142AF82002C27BD001803E000082D
+:106D600031C2000190A7003030E3003F506400289A
+:106D700034C50AC08CAA00241540002234C809007A
+:106D80008CAB00483C0C7FFF3585FFFF016510246C
+:106D90003C188000AF820020370509008F8E00204C
+:106DA0008CAF006001CF682B15A0000201C020212C
+:106DB0008CA400600A000AF0AF8400208D02006CF1
+:106DC0000A000ACB3C0680008C8900488F86002090
+:106DD0003C0A7FFF3550FFFF013038243C04800817
+:106DE00024050001AF870028AC80006CA385001C3F
+:106DF0000A000AFEAF8600248C4400140A000AF040
+:106E0000AF8400208D0200680A000B383C18800017
+:106E100034C409808C8600708CB0001400D0482BDC
+:106E200011200004000000008C8200700A000B3862
+:106E30003C1880008CA200140A000B383C1880001B
+:106E40008F85002427BDFFE0AFBF0018AFB100144D
+:106E500014A00008AFB000103C04800034870A0082
+:106E600090E600302402000530C3003F106200B7F6
+:106E7000348409008F91002000A080213C04800010
+:106E8000348E0A008DCD00043C0608008CC63AB052
+:106E900031A73FFF00E6602B5580000100E0302164
+:106EA000938F001C11E0007600D0102B34990980DC
+:106EB0009338007C330400021080007724030034F0
+:106EC00000C3F82B17E000D600C3302300D0102BEE
+:106ED0003C010800A4233ABC1440006D02001821B4
+:106EE0003C0408008C843AAC0064282B54A00001B8
+:106EF000006020213C05800034A90A009128003C54
+:106F00003C010800AC243AB43103002014600002B4
+:106F1000000048218CA90E188F88002C0128502BC6
+:106F20001140005F000000003C0508008CA53AB449
+:106F300000A96021010C582B1160005C00B0682B87
+:106F40000109382300E028213C010800AC273AB4AD
+:106F5000120000032402FFFC10B0008C322A000350
+:106F600000A2F8243C010800A4203AD23C01080009
+:106F7000AC3F3AB403E028218F84002412040006B9
+:106F80003C0380088C6A006C02002021AF91002035
+:106F900025500001AC70006C8F8B00280085882381
+:106FA000AF91002401652023AF8400281220000245
+:106FB00024070018240700103C0E800835C6008006
+:106FC00090CD0068240C00013C010800A0273AD0B5
+:106FD00031A700FF10EC00470000000014800018EB
+:106FE000000028213C0B8000916501093571098062
+:106FF0008E23001830A500FF0003560224A30001D1
+:107000003146007F3070007F1206007E240CFF8026
+:107010003C0F800835E90080A123004C3C080800A3
+:107020008D083ACC240E00023C010800A02E3B1132
+:10703000350D00083C010800AC2D3ACC24050010A9
+:107040003C1F800037E40A009099003C3338002050
+:107050001300000500A02021240200013C010800CB
+:10706000AC223AB434A400018FBF00188FB10014D1
+:107070008FB000100080102103E0000827BD002021
+:107080003C010800A4203ABC1040FF9502001821E2
+:107090000A000B8B00C018210A000B832403003068
+:1070A0003C0508008CA53AB400B0682B11A0FFA8DD
+:1070B000000000003C04080094843ABC008578215C
+:1070C00001E7702B11C000072CA200043C1F6000D8
+:1070D0008FF954043338003F1700FFE324040042C3
+:1070E0002CA200041040FF9A240400420A000BEE78
+:1070F0008FBF00181528FFB9000000008CC20018CF
+:107100003C188000241900020058F825ACDF001854
+:1071100037040A00A0D900689089003C240F0004BD
+:1071200000A01021312800203C010800A02F3B11B5
+:107130001100000224050010240200013C01080097
+:10714000AC223AAC0A000BE43C1F80008F88002878
+:107150008C8900600109282B14A0000201008821FD
+:107160008C9100603C0B80008D640E18240A000195
+:107170000220282102203021A38A001C0E000A547C
+:10718000022080210A000B72AF82002C000A182313
+:1071900012200007306400033C0D800035A70980F1
+:1071A00090EC007C318B000415600019248E0004E3
+:1071B0003C010800A4243AD23C18080097183AD29F
+:1071C0000305202100C4782B11E0FF6C8F8400247C
+:1071D0002CA6000514C0FFA42404004230B900030B
+:1071E0001720000200B9182324A3FFFC3C0108006B
+:1071F000AC233AB43C010800A4203AD20A000BB1F7
+:107200000060282100AC38240A000BD700EC1826B7
+:107210003C010800A42E3AD20A000C4100000000F4
+:107220003C010800AC203AB40A000BED24040042F3
+:107230008F8300283C0B8000356A0A00146000062A
+:1072400000001021914600302405000530C400FFE5
+:10725000108500030000000003E0000800000000AB
+:1072600091490048312800FF000839C214E0FFFAB4
+:107270003C0480083C06080094C63ABC3C03080065
+:107280008C633AD43C0508008CA53AB43C1808003D
+:1072900097183AD20066C8218C8E00040325782105
+:1072A00001F8682101AE60231980001D0000000074
+:1072B0009158004C8F8D0034956E0E10330F00FFE7
+:1072C0008DA9000401CF30238DAA000030CFFFFF2D
+:1072D000000F6100012C28210000382101472021E6
+:1072E00000AC182B0083C821ADA50004ADB9000087
+:1072F00091B8000A01F87021A1AE000A956C0E1237
+:107300008F8A0034A54C00089549003825280001D3
+:10731000A54800389147000D34EB0008A14B000D43
+:1073200003E000080000000027BDFFD8AFB0001840
+:10733000938F001C8FB000143C087FFF8F870024C0
+:107340003C0C80003518FFFFAFBF0020AFB1001C20
+:1073500035990A0002181824932A003C000F5FC0D8
+:107360003C02BFFF2CF000013449FFFF006BF82501
+:107370003C0808008D083AD48F9900303C1808006A
+:1073800097183ACA03E9582400107F803C07EFFFA2
+:107390003C05F0FF016F18253C11800031490020A9
+:1073A00034E2FFFF34ADFFFF362E098027A5001021
+:1073B0002406000201194023270A00020062182453
+:1073C0000080802115200002000058218D8B0E1CAA
+:1073D000A7AA00120500003A2407000030EF00FFC2
+:1073E000000F3F00006740253C028008AFA8001452
+:1073F000344B0080916A00683C0F080091EF3AD14D
+:107400003C09DFFF353FFFFF000A602B3C0208000C
+:1074100094423AC4A3AF0011011FC024000CCF4016
+:10742000031918258FA70010AFA300143C1F0800F4
+:1074300093FF3AD3A7A200168FA8001400ED4824AA
+:107440003C0B01003C0A0FFF012BC82533F8000359
+:10745000354CFFFF010D78243C027000032C3824CA
+:1074600000181E0000E2482501E35825AFAB0014C8
+:10747000AFA9001091DF007CA3BF00150E000063D0
+:1074800000000000362D0A0091A6003C30C4002008
+:1074900010800006260200083C11080096313AC010
+:1074A000262EFFFF3C010800A42E3AC08FBF00200B
+:1074B0008FB1001C8FB0001803E0000827BD002822
+:1074C0008F8A002C016A602B5580FFC424070001BD
+:1074D0000A000CCB30EF00FF9383001C3C028000BD
+:1074E00027BDFFD834480A0000805021AFBF0020DC
+:1074F00034460AC0010028211060000E344409807F
+:1075000091070030240B00058F89002030EC003FEC
+:10751000118B000B00003821AFA900103C0B800834
+:107520008D69006CAFAA00180E00012BAFA90014E2
+:10753000A380001C8FBF002003E0000827BD0028A7
+:107540008D1F00483C1808008F183AB48F99002806
+:107550003C027FFF8D0800443443FFFFAFA90010B9
+:107560003C0B80088D69006C03E3702403197821BB
+:1075700001CF682301A83821AFAA00180E00012B03
+:10758000AFA900140A000D20A380001C3C05800058
+:1075900034A60A0090C7003C3C06080094C63AD2C4
+:1075A0003C0208008C423ACC30E300200006240064
+:1075B0001060001E004438253C0880083505008016
+:1075C00090A3006800003021240800010000202161
+:1075D000240300013C0580008CAC01780580FFFE8F
+:1075E00000000000ACA80148A4A40144A4A30146E3
+:1075F0003C0308008C633AD43C188008370F0080A5
+:10760000ACA3014C3C19080093393AD13C0D100051
+:10761000A0B90152ACA70154A4A6015891EE004CA8
+:10762000A0AE016D03E00008ACAD01788CA80E1C83
+:107630003C0B08008D6B3AB494AA0E1694A90E1454
+:10764000016630213143FFFF0A000D483124FFFF5E
+:107650003C04800034830A009065003C30A2002086
+:107660001040001C0000000000003021000020211C
+:10767000000018213C0580008CA901780520FFFE40
+:1076800000000000ACA601483C0E08008DCE3AD4A4
+:10769000240DFF91240C00403C0B8008A4A301445E
+:1076A000356A0080A4A40146ACAE014CA0AD0152E5
+:1076B000ACAC0154A4A0015890A301099144004C22
+:1076C00090A601093C041000A0A6016D03E000088B
+:1076D000ACA401788C860E1894880E1294870E1034
+:1076E0003104FFFF0A000D7030E3FFFF3C0480000F
+:1076F00034830A009065003C30A200201040002630
+:1077000027BDFFF8240900010000382124080001EA
+:107710003C0680008CC401780480FFFE000000005D
+:1077200090CA01093C04080090843B113C1880FF7A
+:10773000A3AA00038FA300003085007F370FFFFF4F
+:1077400000661025AFA2000090D9010AA3A0000294
+:1077500000056E00A3B900018FAE0000240A3000BE
+:1077600027BD000801CF6024018D5825ACCB014C0A
+:10777000ACCA0154A4C00158ACC90148A4C7014413
+:107780002409FF80A4C801463C081000A0C901528A
+:1077900003E00008ACC801788C890E1894870E129B
+:1077A00094860E1030E8FFFF0A000D9730C7FFFFE8
+:1077B00027BDFFE8AFB000103C108000AFBF001441
+:1077C00036180A00970F00320E000A5031E43FFFCE
+:1077D0008E0E0100240DFF803C04200001C25821C0
+:1077E000016D6024000C4940316A007F012A402568
+:1077F000010438253C048008AE0708303486008038
+:1078000090C500682403000230A200FF104300046A
+:107810008F9F00208F990024AC9F0068AC99006472
+:107820008FBF00148FB0001003E0000827BD0018C0
+:107830003C0A0800254A359C3C09080025293638B1
+:107840003C08080025082A603C07080024E736FCAD
+:107850003C06080024C634243C05080024A5317CDD
+:107860003C04080024842D8C3C030800246334D895
+:107870003C020800244232743C010800AC2A3A90D1
+:107880003C010800AC293A8C3C010800AC283A883D
+:107890003C010800AC273A943C010800AC263AA40D
+:1078A0003C010800AC253A9C3C010800AC243A9805
+:1078B0003C010800AC233AA83C010800AC223AA0E5
+:0878C00003E0000800000000D5
+:0878C800800009408000090066
+:1078D000800801008008008080080000800E000001
+:1078E000800800808008000080000A8080000A0074
+:0878F0008000098080000900FE
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-06-4.6.16.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-4.6.16.fw.ihex
deleted file mode 100644
index 871de9e..0000000
--- a/firmware/bnx2/bnx2-rv2p-06-4.6.16.fw.ihex
+++ /dev/null
@@ -1,441 +0,0 @@
-:100000000000000000000CA00000005800000000EC
-:1000100000000000000000000000000000000000E0
-:1000200000000000000000000000000000000000D0
-:1000300000000DE000000CF80000000500000000CA
-:1000400000000000000000000000000000000000B0
-:080050000000000000000000A8
-:0800580000000010B18000025D
-:100060000000001F0103010000000008AC000001B7
-:1000700000000000050000000000000C2F800001BF
-:10008000000000002B000000000000002B8000009A
-:1000900000000010203F006300000010213F00031B
-:1000A0000000001020BF0032000000188000FFFD9B
-:1000B00000000010B1B8B00D0000000B2FDF0002EF
-:1000C0000000000003D80000000000002C380000F1
-:1000D0000000001091D400000000000806005555F3
-:1000E0000000001880000075000000188000010B5F
-:1000F00000000008020000020000000F42E0001CA7
-:100100000000001091840A11000000102C62000B06
-:10011000000000188000001E00000008020000021D
-:100120000000000F42E0001C0000001091840A183B
-:10013000000000082C8000B1000000082D0000091C
-:100140000000001091D40000000000082D8001077D
-:10015000000000188000006F0000001880000015EB
-:1001600000000008B1000001000000082C8000B071
-:10017000000000082D000008000000082D8000018C
-:1001800000000018800000690000000B2FDF000253
-:100190000000000C1F800002000000002C0700007F
-:1001A0000000001091DE00000000000005000000CB
-:1001B000000000188000FFDC0000000B2FDF0002B1
-:1001C0000000000C1F800000000000002C07000051
-:1001D0000000001091DE000000000000050000009B
-:1001E000000000188000FFD60000000C1F800002F5
-:1001F0000000000005000000000000188000FFD390
-:100200000000000C298000020000000C1F8000028A
-:10021000000000002ADF0000000000082A0000059E
-:100220000000000805005555000000188000FFCDB3
-:10023000000000080224003C000000180004000038
-:10024000000000188000001C000000188000001E44
-:100250000000001880000052000000188000009E7E
-:10026000000000188000009D0000001880000000C1
-:10027000000000188000000000000018800000004E
-:10028000000000188000000000000018800000003E
-:10029000000000188000000000000018800000002E
-:1002A000000000188000000000000018800000DF3F
-:1002B000000000188000000000000018800000000E
-:1002C0000000001880000015000000188000001BCE
-:1002D000000000188000000000000018800000B43A
-:1002E000000000188000002E00000018800000DFD1
-:1002F000000000188000010A00000018800000D5EE
-:10030000000000188000012E000000188000003B53
-:10031000000000188000000000000018800000713C
-:100320000000000C1F80000100000000050000001C
-:10033000000000188000FFAC0000001091D4000005
-:100340000000000C298000010000000C1F8000014B
-:10035000000000082A000002000000000500000064
-:10036000000000188000FFA60000001091D40000DB
-:100370000000000C298000010000000C1F8000011B
-:100380000000000029420000000000082A000002CE
-:100390000000000005000000000000188000FF9F22
-:1003A000000000188000FF9E00000010B1BCB00AE1
-:1003B0000000000B2FDF00020000000003D8000047
-:1003C000000000002C3C00000000001091D4000050
-:1003D00000000008060055550000001880000016B7
-:1003E00000000018800000AC000000102C6201BA70
-:1003F0000000001880000005000000082C8000B1FB
-:10040000000000082D0000090000001091D4000039
-:10041000000000082D8001070000000C298000006A
-:100420000000000C1F8000000000001091DE0000A2
-:10043000000000002ADF0000000000082A0000067B
-:100440000000000805005555000000188000FF89D5
-:100450000000001091D400000000000C2980000171
-:100460000000000C1F800001000000082A00000BA3
-:100470000000000005000000000000188000FF835D
-:1004800000000018000200000000000006820000CA
-:1004900000000010B18A000600000000860C140065
-:1004A00000000010B18C00040000000005000000F6
-:1004B000000000082A0000010000001091D4000094
-:1004C00000000018000D0000000000000502000000
-:1004D0000000001091DE000000000018000A00007B
-:1004E00000000010B1A0B0130000000B2FDF0002CD
-:1004F000000000002C200000000000082C800000FC
-:10050000000000082D0000000000001091D4000041
-:100510000000000806005555000000188000FFEE9E
-:10052000000000082D80011C00000010001F0000CA
-:100530000000001091DE00000000000F476000087E
-:100540000000000F060E0001000000000F58000020
-:10055000000000000A640000000000000AE500003E
-:10056000000000090B66FFFF000000000D610000A5
-:1005700000000018800000130000000F4760000812
-:100580000000000B2FDF0002000000082C8000009C
-:10059000000000082D0000000000001091D40000B1
-:1005A000000000082D80011C0000000F060E000155
-:1005B00000000010001F0000000000000F580000A5
-:1005C0000000001091DE0000000000000A6400003E
-:1005D000000000000AE50000000000090B66FFFFB4
-:1005E000000000000D610000000000000262000039
-:1005F0000000000B2FDF00020000000031040000AB
-:1006000000000000309A0000000000000C96180066
-:10061000000000090C99FFFF00000004CC99340091
-:1006200000000010B1963202000000080F800000A8
-:100630000000000C298000010000001000220002D0
-:100640000000000C295200010000000C295200009B
-:10065000000000080200000E000000080280001ADE
-:1006600000000010B1C40A020000000802000003EC
-:1006700000000008220000010000000C1F800001A3
-:10068000000000002ADF0000000000002A0008002F
-:100690000000000805005555000000188000FF3FCD
-:1006A0000000000B2FDF00020000001091D40000BA
-:1006B000000000082A000001000000002C200000BB
-:1006C000000000082C800000000000082D00000041
-:1006D000000000082D80011C0000001091D40000D3
-:1006E0000000001091DE0000000000082C800006D1
-:1006F000000000082D00000600000000308000000F
-:100700000000000031000000000000082D800006FD
-:100710000000000C298000010000000C1F80000177
-:100720000000001091DE0000000000002ADF000041
-:10073000000000082A000010000000000500000072
-:10074000000000188000FF2A0000001091A0B009EE
-:10075000000000082C8000B1000000082D000009F6
-:100760000000001091D40000000000082D80010757
-:10077000000000188000FFAB00000018800000108F
-:1007800000000008AC000001000000188000000B11
-:10079000000000000380B0000000000B2FDF00020B
-:1007A000000000002C0040000000001091D4000068
-:1007B0000000000806005555000000188000FF9A50
-:1007C00000000018800000300000001880000006C3
-:1007D0000000000B2FDF0002000000002C000E00C4
-:1007E000000000082A000007000000080500555519
-:1007F000000000188000FF140000000006820000C6
-:100800000000000C298000010000000C1F80000186
-:10081000000000100CE70007000000090562FFFF60
-:1008200000000010BA6C1405000000002ADF000070
-:100830000000000021000000000000082A00000560
-:100840000000001091D40000000000082C8000B0CF
-:10085000000000082D0000080000000C31620018A4
-:10086000000000082D800001000000188000FF8CAF
-:1008700000000018000D000000000010B1A0B00E34
-:100880000000000B2FDF00020000000003D8000072
-:10089000000000002C2000000000001091D4000097
-:1008A0000000001880000014000000102C620002FC
-:1008B000000000188000000B0000000B2FDF00027A
-:1008C000000000002C0700000000000C1F80000149
-:1008D0000000001091DE0000000000000500000094
-:1008E000000000188000FEF6000000082C8000B117
-:1008F000000000082D0000090000001091D4000045
-:10090000000000082D8001070000000C2980000174
-:100910000000000C1F8000010000001091DE0000AC
-:10092000000000002ADF0000000000082A00000A82
-:100930000000000005000000000000188000FEEB31
-:100940000000000005020000000000082C8000B03C
-:10095000000000082D000008000000082D80015054
-:10096000000000000000000000000010205F0000F8
-:10097000000000082C800000000000082D0000008E
-:10098000000000082D8001080000000000000000A9
-:100990000000001091DE000000000018000A0000B6
-:1009A0000000001091D40000000000080600AAAA70
-:1009B000000000188000FF5B0000000C298000018F
-:1009C0000000000C1F800001000000082A00000940
-:1009D000000000080500AAAA000000188000FED749
-:1009E0000000001091D400000000000806005555DA
-:1009F000000000188000FF530000001091A03C028E
-:100A000000000010B1E662070000000B2FDF0002BB
-:100A1000000000002C310000000000092CB1007F14
-:100A2000000000082CD90000000000082D00000084
-:100A3000000000082D80010D00000010B1A8000684
-:100A400000000010205F0000000000002C200000CB
-:100A5000000000002CA70000000000082D0000107E
-:100A6000000000082D800108000000188000FF4CE5
-:100A700000000010B1A6001000000010001F0000D0
-:100A80000000000F0F300007000000000A600000A7
-:100A9000000000000AE100000000000F4B620008A7
-:100AA000000000090B1600FF000000000D620000AE
-:100AB000000000090D1A00FF0000001007300003BD
-:100AC0000000000C0D1A00080000000C0B160008B6
-:100AD0000000000F4CE30018000000000C992C00EF
-:100AE00000000004CC993400000000080F800000D2
-:100AF0000000000C298000010000000033310000DC
-:100B00000000000822000016000000002ADF00009C
-:100B1000000000082A00000C00000010009F0000E8
-:100B2000000000000F2000000000000C1F800001EA
-:100B30000000000805005555000000188000FEABBD
-:100B40000000001091D40000000000080600AAAACE
-:100B5000000000188000FF270000000F4722000857
-:100B600000000009070E000F00000008070E000833
-:100B700000000008028000010000000702851C0040
-:100B800000000008828500010000000002854C0082
-:100B90000000000742851C0000000003C3AA5200A9
-:100BA0000000000003B10E00000000074B071C000E
-:100BB0000000000F0F3000070000000F0A9600032E
-:100BC000000000000A955C00000000004A005A0086
-:100BD000000000000C960A00000000090C99FFFFBD
-:100BE000000000080D00FFFF00000010B196320267
-:100BF000000000080F80000500000010B1A80008E8
-:100C000000000010205F00000000000B2FDF00023A
-:100C1000000000002C200000000000002CA70000B5
-:100C2000000000082D000010000000082D800108C1
-:100C3000000000188000FF130000000C2980000154
-:100C400000000010001F00000000000C1F800001C9
-:100C5000000000002ADF0000000000082A00000D4C
-:100C6000000000080500AAAA000000188000FE8508
-:100C70000000001091D40000000000080600555547
-:100C8000000000188000FF010000000C2980000116
-:100C90000000000C1F800001000000082A0000076F
-:100CA0000000000805005555000000188000FE7D7A
-:100CB00000000008030500040000000683040C0087
-:100CC00000000008028502000000000086050C00FC
-:100CD00000000001860C0E00000000080204000461
-:100CE00000000000020418000000000083871800C4
-:080CF0000000001800020000E2
-:080CF80000000010B1800004AF
-:100D00000000001F0103010000000008050000FFB3
-:100D10000000001800020000000000002A0000008F
-:100D200000000010B1D400000000000C2980000178
-:100D30000000000802540008000000180004000031
-:100D40000000001880000010000000188000001152
-:100D5000000000188000003A000000188000010424
-:100D6000000000188000010300000018800001024C
-:100D70000000001880000102000000188000000040
-:100D8000000000188000011400000018800000FE20
-:100D9000000000188000000C0000001880000118FE
-:100DA000000000188000016A000000188000006741
-:100DB00000000018800000DA00000018800000E742
-:100DC000000000002A000000000000188000FFEB77
-:100DD000000000002A0000000000000C2980000034
-:100DE0000000001020530000000000188000FFE702
-:100DF000000000002A000000000000188000FFE54D
-:100E000000000018000200000000000005020000C1
-:100E1000000000109196342100000010205F0000B7
-:100E2000000000002C1E0000000000082C800006BE
-:100E3000000000082D000006000000082D800102BF
-:100E400000000000000000000000001091DE000023
-:100E5000000000000D61000000000018000A000002
-:100E600000000000050200000000001091963416FA
-:100E700000000010205F00000000000009D8000002
-:100E8000000000002C1E0000000000082C8000B2B2
-:100E9000000000082D00000A000000082D8001025B
-:100EA00000000000000000000000001091DE0000C3
-:100EB000000000000D620000000000002C13000084
-:100EC00000000018000A00000000000005020000F9
-:100ED000000000109196340900000010205F00000F
-:100EE000000000002C1E0000000000082C800006FE
-:100EF000000000082D00006A000000082D8001029B
-:100F000000000000000000000000001091DE000062
-:100F1000000000000D7A000000000018000A000028
-:100F20000000001091DE000000000010001F000013
-:100F3000000000002F80AA00000000002A0000002E
-:100F4000000000000D6100000000000003620000CE
-:100F5000000000002C4000000000000002638C0034
-:100F600000000000264600000000000802040012F5
-:100F700000000010B9060827000000000F5800000C
-:100F8000000000000A640000000000000AE5000004
-:100F9000000000090B66FFFF000000000C000000CD
-:100FA000000000000B800000000000080CC60012CA
-:100FB000000000188000FFCB000000080F80000335
-:100FC000000000000000000000000010009F000072
-:100FD00000000008271100120000000066900000C9
-:100FE00000000008A31B001200000010B1980003CD
-:100FF00000000010001F0000000000080F80000427
-:101000000000000822000003000000082C80000CF3
-:10101000000000082D00000C00000010009F0000E0
-:1010200000000000259600000000000C2980000050
-:101030000000000006660000000000008661180045
-:10104000000000090260000F0000000F020400020F
-:1010500000000010B60C08030000000C1FBF0000C9
-:101060000000000C33660010000000003214000085
-:1010700000000000329500000000000573662C009F
-:101080000000000031E32E00000000082D80001059
-:1010900000000010205300000000001091DE00004E
-:1010A000000000188000FF900000000023000000F6
-:1010B0000000000925E6FFFF000000082200000BE9
-:1010C0000000000C695200000000000C29800000A4
-:1010D0000000001020530000000000188000FF896D
-:1010E0000000001091DE000000000010001F000052
-:1010F000000000002F80AA00000000002A0000006D
-:10110000000000002C400000000000082C8000407F
-:10111000000000082D000020000000082D80011CA8
-:1011200000000000000000000000001091DE000040
-:101130000000000F42EA001000000010004F000401
-:1011400000000010B746920000000008024900129B
-:1011500000000010B5840A00000000000D610000CE
-:1011600000000010BA66345A00000000036200005C
-:1011700000000010B8630C5800000008830500123E
-:1011800000000010004F00020000000003490000B2
-:101190000000000183068C000000000083C60C00E4
-:1011A00000000010B1870010000000000B6E00006E
-:1011B000000000188000FF6B0000000106691400A9
-:1011C00000000010918C000200000008B4E900014A
-:1011D00000000010B1E92C4C0000000086692C00D2
-:1011E00000000000020000000000000902EAFFFF0A
-:1011F00000000010000C00020000000002040A00C1
-:101200000000000F460C00010000000F02850001E5
-:1012100000000010918C01FC00000010B7040E4388
-:10122000000000002C400000000000000F40000003
-:10123000000000000D610000000000000A640000D2
-:10124000000000000AE50000000000090B66FFFF37
-:10125000000000000C000000000000000B800000F7
-:10126000000000080C860012000000080F80000338
-:101270000000000C2952000000000010009F000038
-:101280000000000827110012000000006690000016
-:1012900000000000264600000000000023060000B9
-:1012A00000000010B198000500000010001F0000B1
-:1012B000000000080F800004000000000000000093
-:1012C00000000010001F00000000000032140000A9
-:1012D00000000000329500000000000031E32E0005
-:1012E0000000000573662C00000000002596000039
-:1012F00000000010B18700160000000C29800000DB
-:101300000000000F0F6B0007000000000D690000D7
-:10131000000000000A6C0000000000000AED000060
-:10132000000000000B6E0000000000000B800000B9
-:10133000000000000C870000000000080F80000380
-:1013400000000010205300000000000C6952000152
-:1013500000000010001F00000000000022C58C00EB
-:1013600000000000231B0000000000002711000007
-:10137000000000002690000000000010B8170E03C7
-:101380000000000C29800000000000188000FFF61B
-:1013900000000010B1980002000000080F80000457
-:1013A000000000082200001A000000082C80000C39
-:1013B000000000082D00000C000000082D80001027
-:1013C00000000010001F0000000000000D6E000073
-:1013D00000000003E7CF34000000000C298000006B
-:1013E0000000001091DE000000000010B18700072F
-:1013F00000000000361400000000000036950000D8
-:101400000000000037160000000000082C8000508B
-:10141000000000082D000030000000082D80000CA6
-:101420000000001020530000000000188000FF1F83
-:10143000000000002646000000000000230000001D
-:101440000000000925E6FFFF000000000B6E000011
-:1014500000000003E7CF2C00000000082200001B62
-:101460000000000C695200000000000C2980000000
-:101470000000001020530000000000188000FF153D
-:10148000000000002FD50000000000002A0000002E
-:1014900000000010003F000B000000000666000086
-:1014A000000000008661180000000009026000F0E2
-:1014B00000000010B70C08070000000C7366001055
-:1014C000000000082C800018000000082D00001803
-:1014D000000000082D8000020000000C5FBF00002B
-:1014E0000000001091DE0000000000188000FF07DF
-:1014F000000000002FD50000000000002A000000BE
-:10150000000000002C4000000000000C29800000BA
-:101510000000001091DE0000000000082C80001A7E
-:10152000000000082D00001A000000003300000039
-:10153000000000082D800002000000003180000043
-:101540000000001091DE0000000000082C80000C5C
-:10155000000000082D00000C000000082D80000491
-:1015600000000010205300000000001091DE000079
-:10157000000000188000FEF6000000188000FEF554
-:10158000000000002A00000000000010001F000002
-:10159000000000000F008000000000080F8000071E
-:1015A0000000001880000014000000000502000088
-:1015B000000000082200000900000000286D000063
-:1015C00000000000290000000000000F6568001006
-:1015D00000000003F66C940000000010B972A00433
-:1015E0000000000C73E700190000000C2142000409
-:1015F000000000003BF600000000000C2980000005
-:101600000000001020530000000000082200000825
-:101610000000000C6142000400000018000A0000F5
-:10162000000000002A00000000000010001F000061
-:101630000000000F0F470007000000080F8000089F
-:101640000000000C29800000000000102053000062
-:10165000000000188000FEDA0000001091DE00009B
-:10166000000000002FD5000000000010001F000047
-:101670000000000033510000000000002A000000BC
-:1016800000000010B1C600230000000F0F5000073B
-:10169000000000000A600000000000000AE10000F5
-:1016A0000000000F4B620008000000090B1600FF4D
-:1016B0000000000F4C620010000000000D620000EE
-:1016C000000000090D1A00FF000000100750000381
-:1016D0000000000C0D1A00080000000C0B1600089A
-:1016E000000000000CC60000000000000B8000009D
-:1016F0000000000006980000000000080F800003B2
-:101700000000001006C200040000000C29000002C6
-:1017100000000010264200020000000C29520003C5
-:10172000000000082200000100000010009F0000DF
-:1017300000000000231B00000000000027111A0019
-:1017400000000000669000000000000C295200001C
-:1017500000000010B19732090000000C2980000041
-:101760000000000006980000000000102053000058
-:101770000000000C295200030000000022C58C006C
-:1017800000000010001F0000000000080F80000390
-:10179000000000188000FFF300000010B1C8001323
-:1017A00000000010B1C600030000000C29800000FA
-:1017B00000000010205300000000000C295200001F
-:1017C0000000000C295200030000001006C20002B5
-:1017D0000000000C295200020000000022C58C000D
-:1017E00000000000276500000000000026E4000063
-:1017F000000000082200001600000010B1C600031F
-:10180000000000002348000000000010B180000527
-:1018100000000000234800000000000C29800000A8
-:101820000000000F0F500007000000188000001299
-:1018300000000008220000160000000C29800000B3
-:10184000000000003014000000000000309500008F
-:101850000000001007500003000000090B1600FFF5
-:10186000000000090D1A00FF0000000F31160008EB
-:10187000000000003162340000000003F16230001B
-:1018800000000010205F0000000000002C5100004C
-:10189000000000092CD1007F000000082CD90000B6
-:1018A000000000082D000000000000082D80000C42
-:1018B00000000000000000000000001091DE0000A9
-:1018C0000000001005C2000300000000330000000B
-:1018D000000000080F8000070000001020530000E7
-:1018E00000000010009F0000000000188000FE872C
-:1018F000000000002FD50000000000002A000000BA
-:101900000000000F0F50000700000010B1C6002DAE
-:101910000000000F4742000800000009070E000FFA
-:1019200000000008070E000800000010001F000063
-:1019300000000008090000010000000709121C0057
-:1019400000000003CBCA9200000000000B97A20029
-:101950000000000742171C00000000000B040000FC
-:101960000000000F0A840003000000000A959C009C
-:10197000000000004A009A000000000882120001E6
-:10198000000000010C170800000000000C978C00FC
-:101990000000000002180000000000080D00FFFF1A
-:1019A000000000080F8000060000000C2900000065
-:1019B0000000001006C200040000000C29520002C2
-:1019C00000000010264200020000000C2952000313
-:1019D000000000082200000100000010009F00002D
-:1019E00000000010B197320C00000000231B000023
-:1019F00000000000271108000000000066900000B1
-:101A00000000000C29800000000000000218000007
-:101A100000000010205300000000000C29520003B9
-:101A20000000000022C5360000000010001F00006A
-:101A3000000000080F800006000000188000FFF47E
-:101A400000000000231B0000000000002711080018
-:101A5000000000006690000000000010B1C8000BFC
-:101A60000000000C2980000000000010205300003E
-:101A70000000000C295200000000000C2952000355
-:101A80000000001006C200020000000C29520002F3
-:101A90000000000022C58C00000000002765000047
-:101AA0000000000026E400000000000023480000C1
-:101AB00000000008220000170000000C2980000030
-:101AC00000000010001F0000000000102053000064
-:081AD000000000188000FE4A2E
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex
new file mode 100644
index 0000000..52c4963
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex
@@ -0,0 +1,424 @@
+:100000000000000000000C900000005800000009F3
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000000CE000000CE80000000500000000DB
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B180000659
+:100060000000001F01030300000000080500FFFF5F
+:10007000000000180002000000000008050000FF5A
+:10008000000000180002000000000008AC000001A1
+:1000900000000000050000000000000C2F8000019F
+:1000A000000000002B000000000000002B8000007A
+:1000B0000000001091E0000200000008AC00000108
+:1000C00000000010203F004D00000010213F000301
+:1000D0000000001020BF001C000000188000FFFD81
+:1000E00000000008B1000001000000082C8000B0F2
+:1000F000000000082D000008000000082D8000010D
+:10010000000000188000006C0000000B2FDF0002D0
+:100110000000000C1F800002000000002C070000FF
+:100120000000001091DE0000000000080500555599
+:10013000000000188000FFF00000000B2FDF00021D
+:100140000000000C1F800000000000002C070000D1
+:100150000000001091DE0000000000080500555569
+:10016000000000188000FFEA0000000C1F80000261
+:100170000000000805005555000000188000FFE74A
+:100180000000000C298000020000000C1F8000020B
+:10019000000000002ADF0000000000082A0000051F
+:1001A0000000000805005555000000188000FFE120
+:1001B000000000080224002C0000001800040000C9
+:1001C000000000188000001C000000188000001EC5
+:1001D000000000188000006500000018800000B0DA
+:1001E00000000018800000AF000000188000000030
+:1001F00000000018800000000000001880000000CF
+:1002000000000018800000000000001880000000BE
+:1002100000000018800000000000001880000000AE
+:10022000000000188000000000000018800000F6A8
+:10023000000000188000000000000018800000008E
+:100240000000001880000015000000188000001B4E
+:10025000000000188000000000000018800000C6A8
+:10026000000000188000002F00000018800000F639
+:10027000000000188000012100000018800000EC40
+:100280000000001880000145000000188000004EAA
+:1002900000000018800000000000001880000083AB
+:1002A0000000000C1F80000100000000050000009D
+:1002B000000000188000FFC00000001091D4000072
+:1002C0000000000C298000010000000C1F800001CC
+:1002D000000000082A0000020000000005000000E5
+:1002E000000000188000FFBA0000001091D4000048
+:1002F0000000000C298000010000000C1F8000019C
+:100300000000000029420000000000082A0000024E
+:100310000000000005000000000000188000FFB38E
+:10032000000000188000FFB200000010B1BCB00A4D
+:100330000000000B2FDF00020000000003D80000C7
+:10034000000000002C3C00000000001091D40000D0
+:100350000000000806005555000000188000001736
+:1003600000000018800000BF000000102C6201BADD
+:100370000000001880000006000000082C8000B17A
+:10038000000000082D0000090000001091D40000BA
+:10039000000000082D8001070000001880000024E4
+:1003A0000000000C298000000000000C1F800000ED
+:1003B0000000001091DE0000000000002ADF0000B5
+:1003C000000000082A00000600000008050055553E
+:1003D000000000188000FF9C0000001091D4000075
+:1003E0000000000C298000010000000C1F800001AB
+:1003F000000000082A00000B0000000005000000BB
+:10040000000000188000FF960000001800020000A5
+:10041000000000000682000000000010B18A000801
+:1004200000000010B18C14070000000B050AFFFF4C
+:1004300000000010B18A000300000000860A1800C6
+:1004400000000010918C0000000000082A0000014C
+:100450000000001091D4000000000018000D000002
+:1004600000000000050200000000001091DE000006
+:1004700000000018000A00000000000006820000D2
+:100480000000001091DE000000000010BEE1000539
+:10049000000000188000FF7D0000000105611400CD
+:1004A00000000010918A000200000008B0E1000185
+:1004B00000000018000D000000000000068200008F
+:1004C0000000001091DE000000000010BEE20005F8
+:1004D000000000188000FF75000000010562140094
+:1004E00000000010918A000200000008B1620001C3
+:1004F00000000018000D000000000010B1A0B013B3
+:100500000000000B2FDF0002000000002C20000084
+:10051000000000082C800000000000082D000000F2
+:100520000000001091D4000000000008060055559E
+:10053000000000188000FFDC000000082D80011C76
+:1005400000000010001F0000000000188000FFE6FF
+:100550000000000F476000080000000F060E0001B9
+:10056000000000000F580000000000000A640000B6
+:10057000000000000AE50000000000090B66FFFF14
+:10058000000000000D610000000000188000001352
+:100590000000000F476000080000000B2FDF000282
+:1005A000000000082C800000000000082D00000062
+:1005B0000000001091D40000000000082D80011CF4
+:1005C0000000000F060E000100000010001F0000D8
+:1005D000000000000F580000000000188000FFD449
+:1005E000000000000A640000000000000AE50000AE
+:1005F000000000090B66FFFF000000000D61000015
+:1006000000000000026200000000000B2FDF00026B
+:10061000000000003104000000000000309A0000DB
+:10062000000000000C961800000000090C99FFFF64
+:1006300000000004CC99340000000010B196320292
+:10064000000000080F8000000000000C298000015D
+:100650000000000C295200010000000C295200008B
+:10066000000000080200000E000000080280001ACE
+:1006700000000010B1C40A020000000802000003DC
+:1006800000000008220000010000000C1F80000193
+:10069000000000002ADF0000000000002A0008001F
+:1006A0000000000805005555000000188000FF41BB
+:1006B0000000000B2FDF00020000001091D40000AA
+:1006C000000000082A000001000000002C200000AB
+:1006D0000000001091D40000000000082C800000F1
+:1006E000000000082D000000000000082D80011C03
+:1006F000000000188000FFAE000000082C800006FB
+:10070000000000082D0000060000000030800000FE
+:100710000000000031000000000000082D800006ED
+:100720000000000C298000010000000C1F80000167
+:100730000000001091DE0000000000002ADF000031
+:10074000000000082A000010000000000500000062
+:10075000000000188000FF2C0000001091A0B009DC
+:10076000000000082C8000B1000000082D000009E6
+:100770000000001091D40000000000082D80010747
+:10078000000000188000FFA7000000188000001083
+:1007900000000008AC000001000000188000000B01
+:1007A000000000000380B0000000000B2FDF0002FB
+:1007B000000000002C0040000000001091D4000058
+:1007C0000000000806005555000000188000FF8951
+:1007D00000000018800000310000001880000006B2
+:1007E0000000000B2FDF0002000000002C000E00B4
+:1007F000000000082A000007000000080500555509
+:10080000000000188000FF160000000006820000B3
+:100810000000000C298000010000000C1F80000176
+:10082000000000100CE70007000000090562FFFF50
+:1008300000000010BA6C1405000000002ADF000060
+:100840000000000021000000000000082A00000550
+:100850000000001091D40000000000082C8000B0BF
+:10086000000000082D0000080000000C3162001894
+:10087000000000082D800001000000188000FF7DAE
+:1008800000000018000D000000000010B1A0B00E24
+:100890000000000B2FDF00020000000003D8000062
+:1008A000000000002C2000000000001091D4000087
+:1008B0000000001880000015000000102C620002EB
+:1008C000000000188000000C0000000B2FDF000269
+:1008D000000000002C0700000000000C1F80000139
+:1008E0000000001091DE0000000000080500FFFF7E
+:1008F000000000188000FEF8000000082C8000B105
+:10090000000000082D0000090000001091D4000034
+:10091000000000082D800107000000188000FF740F
+:100920000000000C298000010000000C1F80000165
+:100930000000001091DE0000000000002ADF00002F
+:10094000000000082A00000A000000000500000066
+:10095000000000188000FEEC00000000068200008D
+:10096000000000082C8000B0000000082D000008E6
+:10097000000000082D800150000000000000000071
+:100980000000001091DE0000000000082C80000034
+:10099000000000082D000000000000082D80010567
+:1009A00000000010BEE20005000000188000FEDA22
+:1009B000000000010562140000000010918A00028E
+:1009C00000000008B16200010000001091DE00008C
+:1009D00000000018000D00000000001091D400007D
+:1009E000000000080600AAAA000000188000FF45C9
+:1009F0000000000C298000010000000C1F80000195
+:100A0000000000082A000009000000080500AAAA4A
+:100A1000000000188000FED40000001091D40000F7
+:100A20000000000806005555000000188000FF3D3A
+:100A30000000001091A03C0200000010B1E6620727
+:100A40000000000B2FDF0002000000002C3100002E
+:100A5000000000092CB1007F000000082CD9000024
+:100A6000000000082D000000000000082D80010D8E
+:100A700000000010B1A8000600000010205F000078
+:100A8000000000002C200000000000002CA7000047
+:100A9000000000082D000010000000082D80010853
+:100AA000000000188000FF3800000010B1A6001000
+:100AB00000000010001F00000000000F0F300007B2
+:100AC000000000000A600000000000000AE10000D1
+:100AD0000000000F4B620008000000090B1600FF29
+:100AE000000000000D620000000000090D1A00FF68
+:100AF00000000010073000030000000C0D1A000871
+:100B00000000000C0B1600080000000F4CE300185A
+:100B1000000000000C992C0000000004CC99340067
+:100B2000000000080F8000000000000C2980000178
+:100B30000000000033310000000000082200001611
+:100B4000000000002ADF0000000000082A00000C5E
+:100B500000000010009F0000000000000F200000B7
+:100B60000000000C1F800001000000080500555522
+:100B7000000000188000FEA80000001091D40000C2
+:100B8000000000080600AAAA000000188000FF115B
+:100B90000000000F4722000800000009070E000FA8
+:100BA00000000008070E0008000000080280000195
+:100BB0000000000702851C0000000008828500017B
+:100BC0000000000002854C000000000742851C0068
+:100BD00000000003C3AA52000000000003B10E0091
+:100BE000000000074B071C000000000F0F3000073B
+:100BF0000000000F0A960003000000000A955C0048
+:100C0000000000004A005A00000000000C960A0094
+:100C1000000000090C99FFFF000000080D00FFFF15
+:100C200000000010B1963202000000080F8000059D
+:100C300000000010B1A8000800000010205F0000B4
+:100C40000000000B2FDF0002000000002C2000003D
+:100C5000000000002CA70000000000082D0000107C
+:100C6000000000082D800108000000188000FEFF31
+:100C70000000000C2980000100000010001F00008F
+:100C80000000000C1F800001000000002ADF0000AF
+:100C9000000000082A00000D000000080500AAAAB4
+:100CA000000000188000FE820000001091D40000B7
+:100CB0000000000806005555000000188000FEEBFB
+:100CC0000000000C298000010000000C1F800001C2
+:100CD000000000082A000007000000080500555524
+:080CE000000000188000FE7AFC
+:080CE80000000010B1800004BF
+:100CF0000000001F0103030000000008050000FFC2
+:100D00000000001800020000000000002A0000009F
+:100D100000000010B1D400000000001091DE0000BF
+:100D2000000000102053000000000010001F000011
+:100D3000000000002F80AA000000000C29800001A4
+:100D4000000000080254000D000000002C400000CC
+:100D500000000018000400000000001880000010CF
+:100D60000000001880000011000000188000003909
+:100D700000000018800000DF00000018800000DE86
+:100D800000000018800000DD00000018800000DD79
+:100D9000000000188000000000000018800000F52E
+:100DA00000000018800000D9000000188000000B2F
+:100DB00000000018800000F90000001880000147C2
+:100DC000000000188000005900000018800000C4D6
+:100DD00000000018800000C5000000002A0000008C
+:100DE000000000188000FFE6000000002A0000005C
+:100DF0000000000C29800000000000188000FFE3C4
+:100E0000000000002A000000000000188000FFE140
+:100E100000000018000200000000000005020000B1
+:100E2000000000109196342100000010205F0000A7
+:100E3000000000002C1E0000000000082C800006AE
+:100E4000000000082D000006000000082D800102AF
+:100E500000000000000000000000001091DE000013
+:100E6000000000000D61000000000018000A0000F2
+:100E700000000000050200000000001091963416EA
+:100E800000000010205F00000000000009D80000F2
+:100E9000000000002C1E0000000000082C8000B2A2
+:100EA000000000082D00000A000000082D8001024B
+:100EB00000000000000000000000001091DE0000B3
+:100EC000000000000D620000000000002C13000074
+:100ED00000000018000A00000000000005020000E9
+:100EE000000000109196340900000010205F0000FF
+:100EF000000000002C1E0000000000082C800006EE
+:100F0000000000082D00006A000000082D8001028A
+:100F100000000000000000000000001091DE000052
+:100F2000000000000D7A000000000018000A000018
+:100F3000000000002A000000000000000D61000019
+:100F4000000000000362000000000010234200A324
+:100F50000000000002638C00000000002646000034
+:100F6000000000080204001200000010B906081E6C
+:100F7000000000000F580000000000000A6400009C
+:100F8000000000000AE50000000000090B66FFFFFA
+:100F9000000000000C000000000000000B800000BA
+:100FA000000000080CC60012000000188000FFCEF0
+:100FB000000000080F800003000000000000000097
+:100FC00000000010009F0000000000082711001220
+:100FD000000000006690000000000008A31B001243
+:100FE00000000010B198000300000010001F000076
+:100FF000000000080F800004000000082200000329
+:10100000000000082C80000C000000082D00000CDF
+:1010100000000010009F0000000000002596000066
+:101020000000000C298000000000000032140000C5
+:1010300000000000329500000000000573662C00DF
+:101040000000000031E32E00000000082D80001099
+:10105000000000188000FF9800000000230000003E
+:101060000000000925E6FFFF000000082200000B39
+:101070000000000C695200000000000C29800000F4
+:10108000000000188000FF92000000002A0000000D
+:10109000000000082C800040000000082D00002007
+:1010A000000000082D80011C00000000000000006E
+:1010B0000000001091DE00000000000F42EA001066
+:1010C00000000010004F000400000010B74692001E
+:1010D000000000080249001200000010B5840A0058
+:1010E000000000000D61000000000010BA663457D7
+:1010F000000000088305001200000010004F0002ED
+:1011000000000000034900000000000183068C007D
+:101110000000000083C60C0000000010B187001121
+:10112000000000000B6E000000000010BEE900058A
+:10113000000000188000FF7900000001056914001C
+:1011400000000010918A000200000008B4E90001CC
+:1011500000000010B1E92C4A0000000086692C0054
+:1011600000000000020000000000000902EAFFFF8A
+:1011700000000010000C00020000000002040A0041
+:101180000000000F460C00010000000F0285000166
+:1011900000000010918C01FC00000010B7040E410B
+:1011A000000000000F400000000000000D61000082
+:1011B000000000000A640000000000000AE50000D2
+:1011C000000000090B66FFFF000000000C0000009B
+:1011D000000000000B800000000000080C860012D8
+:1011E000000000080F8000030000000C29520000DE
+:1011F00000000010009F00000000000827110012EE
+:10120000000000006690000000000000264600007C
+:10121000000000002306000000000010B198000547
+:1012200000000010001F0000000000080F800004F4
+:10123000000000000000000000000010001F00007F
+:101240000000000032140000000000003295000091
+:101250000000000031E32E000000000573662C0042
+:10126000000000002596000000000010B187001665
+:101270000000000C298000000000000F0F6B000729
+:10128000000000000D690000000000000A6C000072
+:10129000000000000AED0000000000000B6E0000DE
+:1012A000000000000B800000000000000C87000020
+:1012B000000000080F800003000000102053000011
+:1012C0000000000C6952000100000010001F000027
+:1012D0000000000022C58C0000000000231B00005D
+:1012E0000000000027110000000000002690000010
+:1012F00000000010B8170E030000000C2980000049
+:10130000000000188000FFF600000010B1980002F5
+:10131000000000080F800004000000082200001AEE
+:10132000000000082C80000C000000082D00000CBC
+:10133000000000082D80001000000010001F0000B9
+:10134000000000000D6E000000000003E7CF340035
+:101350000000000C298000000000001091DE000059
+:1013600000000010B18700070000000036140000E4
+:101370000000000036950000000000003716000055
+:10138000000000082C800050000000082D000030F4
+:10139000000000082D80000C000000188000FF2FC6
+:1013A00000000000264600000000000023000000AE
+:1013B0000000000925E6FFFF000000000B6E0000A2
+:1013C00000000003E7CF2C00000000082200001BF3
+:1013D0000000000C695200000000000C2980000091
+:1013E000000000188000FF26000000002A00000016
+:1013F000000000188000FF24000000002A00000008
+:101400000000000C298000000000001091DE0000A8
+:10141000000000082C80001A000000082D00001AAF
+:101420000000000573660000000000082D80000227
+:1014300000000000318000000000001091DE00007C
+:10144000000000082C80000C000000082D00000C9B
+:10145000000000082D800004000000188000FF1725
+:101460000000001800020000000000188000FF15B6
+:10147000000000002A00000000000010001F000013
+:10148000000000000F008000000000080F8000072F
+:10149000000000188000001A00000000280A000068
+:1014A0000000000005020000000000082200000902
+:1014B00000000000290000000000000F6568001017
+:1014C00000000003F66C940000000010B972A00444
+:1014D0000000000C73E700190000000C214200041A
+:1014E000000000003CF800000000000C2980000013
+:1014F0000000001020530000000000082200000837
+:101500000000000C6142000400000018000A000006
+:1015100000000000050200000000000C6142000015
+:1015200000000010014200030000000C33E7001D22
+:101530000000000C6142000200000018000A0000D8
+:10154000000000002A00000000000010001F000042
+:101550000000000F0F470007000000080F80000880
+:101560000000000C2980000000000010009F000017
+:10157000000000188000FEF400000000335100005D
+:10158000000000002A00000000000010B1C6002387
+:101590000000000F0F500007000000000A6000006C
+:1015A000000000000AE100000000000F4B6200088C
+:1015B000000000090B1600FF0000000F4C62001035
+:1015C000000000000D620000000000090D1A00FF7D
+:1015D00000000010075000030000000C0D1A000866
+:1015E0000000000C0B160008000000000CC60000F4
+:1015F000000000000B8000000000000006980000C2
+:10160000000000080F8000030000001006C2000464
+:101610000000000C29000002000000102642000219
+:101620000000000C29520003000000082200000105
+:1016300000000010009F000000000000231B0000BD
+:101640000000000027111A00000000006690000052
+:101650000000000C2952000000000010B197320970
+:101660000000000C29800000000000000698000027
+:1016700000000010205300000000000C295200035D
+:101680000000000022C58C0000000010001F0000B8
+:10169000000000080F800003000000188000FFF326
+:1016A00000000010B1C8001300000010B1C6000314
+:1016B0000000000C298000000000001020530000F2
+:1016C0000000000C295200000000000C2952000309
+:1016D0000000001006C200020000000C29520002A7
+:1016E0000000000022C58C000000000027650000FB
+:1016F0000000000026E400000000000822000016A0
+:1017000000000010B1C600030000000023480000E4
+:1017100000000010B1800005000000002348000018
+:101720000000000C298000000000000F0F5000078F
+:1017300000000018800000120000000822000016BF
+:101740000000000C298000000000000030140000A0
+:10175000000000003095000000000010075000035A
+:10176000000000090B1600FF000000090D1A00FF21
+:101770000000000F31160008000000003162340044
+:1017800000000003F162300000000010205F000044
+:10179000000000002C510000000000092CD1007F47
+:1017A000000000082CD90000000000082D000000F7
+:1017B000000000082D80000C000000000000000068
+:1017C0000000001091DE00000000001005C20004BF
+:1017D000000000080F800007000000003300000038
+:1017E00000000010009F0000000000188000FEA50F
+:1017F000000000002A0000000000000F0F5000074A
+:1018000000000010B1C6002D0000000F4742000884
+:1018100000000009070E000F00000008070E000876
+:1018200000000010001F0000000000080900000177
+:101830000000000709121C0000000003CBCA920040
+:10184000000000000B97A2000000000742171C00D8
+:10185000000000000B0400000000000F0A840003D9
+:10186000000000000A959C00000000004A009A0059
+:101870000000000882120001000000010C1708009F
+:10188000000000000C978C0000000000021800000F
+:10189000000000080D00FFFF000000080F80000698
+:1018A0000000000C290000000000001006C2000427
+:1018B0000000000C29520002000000102642000225
+:1018C0000000000C29520003000000082200000163
+:1018D00000000010009F000000000010B197320CC3
+:1018E00000000000231B000000000000271108007A
+:1018F00000000000669000000000000C298000003D
+:10190000000000000218000000000010205300003A
+:101910000000000C295200030000000022C5360020
+:1019200000000010001F0000000000080F800006EB
+:10193000000000188000FFF400000000231B0000DE
+:101940000000000027110800000000006690000061
+:1019500000000010B1C8000B0000000C298000003E
+:1019600000000010205300000000000C295200006D
+:101970000000000C295200030000001006C2000203
+:101980000000000C295200020000000022C58C005B
+:1019900000000000276500000000000026E40000B1
+:1019A000000000002348000000000008220000178B
+:1019B0000000000C2980000000000010001F000043
+:0819C000000000188000FE6A1F
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-09-4.6.15.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-4.6.15.fw.ihex
deleted file mode 100644
index 63995bb..0000000
--- a/firmware/bnx2/bnx2-rv2p-09-4.6.15.fw.ihex
+++ /dev/null
@@ -1,490 +0,0 @@
-:100000000000000000000D88000000580000000003
-:1000100000000000000000000000000000000000E0
-:1000200000000000000000000000000000000000D0
-:100030000000101800000DE00000000500000000A6
-:1000400000000000000000000000000000000000B0
-:080050000000000000000000A8
-:0800580000000010B18000025D
-:100060000000001F0303010000000008AC000001B5
-:1000700000000000050000000000000C2F800001BF
-:10008000000000002B000000000000002B8000009A
-:1000900000000010203F006C00000010213F000312
-:1000A0000000001020BF003B000000188000FFFD92
-:1000B00000000010B1B8B0150000000B2FDF0002E7
-:1000C0000000000003D80000000000002C380000F1
-:1000D000000000082C800000000000082D00000037
-:1000E0000000001091D400000000000806005555E3
-:1000F000000000188000008F000000082D80011C07
-:1001000000000008020000010000001091DE000065
-:100110000000000F42E0001C0000001091840A174C
-:1001200000000010086600160000000C2980000284
-:100130000000000C1F800002000000002ADF000009
-:10014000000000082A00000F0000000805005555B7
-:10015000000000188000FFE8000000080200000115
-:100160000000000F42E0001C0000001091840A19FA
-:10017000000000082C800006000000082D0000068A
-:100180000000001091D40000000000082D8001063E
-:1001900000000018800000830000001008660013B3
-:1001A000000000188000FFF100000008B10000010D
-:1001B000000000082C80010C000000082D00000841
-:1001C000000000082D800001000000188000007C65
-:1001D0000000000B2FDF00020000000C1F80000257
-:1001E000000000002C0700000000001091DE00005D
-:1001F0000000000005000000000000188000FFD390
-:100200000000000B2FDF00020000000C1F80000028
-:10021000000000002C0700000000001091DE00002C
-:100220000000000005000000000000188000FFCD65
-:100230000000000C1F80000200000000050000000C
-:10024000000000188000FFCA0000000C2980000296
-:100250000000000C1F800002000000002ADF0000E8
-:10026000000000082A0000050000000805005555A0
-:10027000000000188000FFC40000000802240045B0
-:100280000000001800040000000000188000001C9E
-:10029000000000188000001E0000001880000065AB
-:1002A00000000018800000AD00000018800000ACC5
-:1002B000000000188000000000000018800000000E
-:1002C00000000018800000000000001880000000FE
-:1002D00000000018800000000000001880000000EE
-:1002E00000000018800000000000001880000000DE
-:1002F00000000018800000F30000001880000000DB
-:1003000000000018800000000000001880000015A8
-:10031000000000188000001B000000188000000092
-:1003200000000018800000C3000000188000002EAC
-:1003300000000018800000F3000000188000011E7B
-:1003400000000018800000E9000000188000014251
-:10035000000000188000004E00000018800000001F
-:1003600000000018800000800000000C1F800001C9
-:100370000000000005000000000000188000FFA33E
-:100380000000001091D400000000000C2980000142
-:100390000000000C1F800001000000082A0000027D
-:1003A0000000000005000000000000188000FF9D14
-:1003B0000000001091D400000000000C2980000112
-:1003C0000000000C1F800001000000002942000016
-:1003D000000000082A0000020000000005000000E4
-:1003E000000000188000FF96000000188000FF95B4
-:1003F00000000010B1BCB00A0000000B2FDF0002AB
-:100400000000000003D80000000000002C3C0000A9
-:100410000000001091D400000000000806005555AF
-:10042000000000188000002900000018800000BBB8
-:10043000000000102C6201BA0000001880000005C6
-:10044000000000082C80010D000000082D000009AC
-:100450000000001091D40000000000082D8001076A
-:100460000000000C298000000000000C1F8000002C
-:100470000000001091DE0000000000002ADF0000F4
-:10048000000000082A00000600000008050055557D
-:10049000000000188000FF800000001091D40000D0
-:1004A0000000000C298000010000000C1F800001EA
-:1004B000000000082A00000B0000000005000000FA
-:1004C000000000188000FF7A000000000202000017
-:1004D00000000000029A000000000000060C2C0042
-:1004E00000000004C60C340000000010001F0000D3
-:1004F00000000010B196180C0000000806960004D9
-:1005000000000009068DFFFC00000004CD051A0064
-:1005100000000004CC9A18000000001020D7000052
-:100520000000000C2B56000000000000000000003E
-:1005300000000000000000000000001020D70000B4
-:10054000000000080F80000100000010B18001F4DD
-:1005500000000010001F00000000000C6B5600009F
-:1005600000000018000400000000000006820000E7
-:1005700000000010B18A000600000000860C140084
-:1005800000000010B18C0004000000000500000015
-:10059000000000082A0000010000001091D40000B3
-:1005A00000000018000D000000000000050200001F
-:1005B0000000001091DE000000000018000A00009A
-:1005C00000000010B1A0B0130000000B2FDF0002EC
-:1005D000000000002C200000000000082C8000001B
-:1005E000000000082D0000000000001091D4000061
-:1005F0000000000806005555000000188000FFEEBE
-:10060000000000082D80011C00000010001F0000E9
-:100610000000001091DE00000000000F476000089D
-:100620000000000F060E0001000000000F5800003F
-:10063000000000000A640000000000000AE500005D
-:10064000000000090B66FFFF000000000D610000C4
-:1006500000000018800000130000000F4760000831
-:100660000000000B2FDF0002000000082C800000BB
-:10067000000000082D0000000000001091D40000D0
-:10068000000000082D80011C0000000F060E000174
-:1006900000000010001F0000000000000F580000C4
-:1006A0000000001091DE0000000000000A6400005D
-:1006B000000000000AE50000000000090B66FFFFD3
-:1006C000000000000D610000000000000262000058
-:1006D0000000000B2FDF00020000000031040000CA
-:1006E00000000000309A0000000000188000FFBCED
-:1006F0000000000C29800001000000100022000210
-:100700000000000C295200010000000C29520000DA
-:10071000000000080200000E000000080280001A1D
-:1007200000000010B1C40A0200000008020000032B
-:1007300000000008220000010000000C1F800001E2
-:10074000000000002ADF0000000000002A0008006E
-:100750000000000805005555000000188000FF2724
-:100760000000000B2FDF00020000001091D40000F9
-:10077000000000082A000001000000002C200000FA
-:10078000000000082C800000000000082D00000080
-:10079000000000082D80011C0000001091D4000012
-:1007A0000000001091DE0000000000082C80000610
-:1007B000000000082D00000600000000308000004E
-:1007C0000000000031000000000000082D8000063D
-:1007D0000000000C298000010000000C1F800001B7
-:1007E0000000001091DE0000000000002ADF000081
-:1007F000000000082A0000100000000005000000B2
-:10080000000000188000FF120000001091A0B00945
-:10081000000000082C80010D000000082D000009D8
-:100820000000001091D40000000000082D80010796
-:10083000000000188000FFAF0000001880000010CA
-:1008400000000008AC000001000000188000000B50
-:10085000000000000380B0000000000B2FDF00024A
-:10086000000000002C0040000000001091D40000A7
-:100870000000000806005555000000188000FF9E8B
-:100880000000001880000030000000188000000602
-:100890000000000B2FDF0002000000002C000E0003
-:1008A000000000082A000007000000080500555558
-:1008B000000000188000FEFC00000000068200001E
-:1008C0000000000C298000010000000C1F800001C6
-:1008D000000000100CE70007000000090562FFFFA0
-:1008E00000000010BA6C1405000000002ADF0000B0
-:1008F0000000000021000000000000082A000005A0
-:100900000000001091D40000000000082C80010CB1
-:10091000000000082D0000080000000C31620018E3
-:10092000000000082D800001000000188000FF90EA
-:1009300000000018000D000000000010B1A0B00E73
-:100940000000000B2FDF00020000000003D80000B1
-:10095000000000002C2000000000001091D40000D6
-:100960000000001880000014000000102C6200023B
-:10097000000000188000000B0000000B2FDF0002B9
-:10098000000000002C0700000000000C1F80000188
-:100990000000001091DE00000000000005000000D3
-:1009A000000000188000FEDE000000082C80010D11
-:1009B000000000082D0000090000001091D4000084
-:1009C000000000082D8001070000000C29800001B4
-:1009D0000000000C1F8000010000001091DE0000EC
-:1009E000000000002ADF0000000000082A00000AC2
-:1009F0000000000005000000000000188000FED389
-:100A00000000000005020000000000082C80010C1E
-:100A1000000000082D000008000000082D800134AF
-:100A2000000000000000000000000010205F000037
-:100A3000000000082C800140000000082D00003C50
-:100A4000000000082D80011C0000000000000000D4
-:100A500000000010205F0000000000082C800080D3
-:100A6000000000082D000000000000082D80010893
-:100A700000000000000000000000001091DE0000F7
-:100A800000000018000A00000000001091D40000CF
-:100A9000000000080600AAAA000000188000FF5A03
-:100AA0000000000C298000010000000C1F800001E4
-:100AB000000000082A000009000000080500AAAA9A
-:100AC000000000188000FEBA0000001091D4000061
-:100AD0000000000806005555000000188000FF5275
-:100AE0000000001091A03C0200000010B1E6620777
-:100AF0000000000B2FDF0002000000002C3100007E
-:100B0000000000092CB1007F000000082CD9000073
-:100B1000000000082D000000000000082D80010DDD
-:100B200000000010B1A8000600000010205F0000C7
-:100B3000000000002C200000000000002CA7000096
-:100B4000000000082D000010000000082D800108A2
-:100B5000000000188000FF4B00000010B1A600103C
-:100B600000000010001F00000000000F0F30000701
-:100B7000000000000A600000000000000AE1000020
-:100B80000000000F4B620008000000090B1600FF78
-:100B9000000000000D620000000000090D1A00FFB7
-:100BA00000000010073000030000000C0D1A0008C0
-:100BB0000000000C0B1600080000000F4CE30018AA
-:100BC000000000000C992C0000000004CC993400B7
-:100BD000000000080F8000000000000C29800001C8
-:100BE0000000000033310000000000082200001661
-:100BF000000000002ADF0000000000082A00000CAE
-:100C000000000010009F0000000000000F20000006
-:100C10000000000C1F800001000000080500555571
-:100C2000000000188000FE8E0000001091D400002B
-:100C3000000000080600AAAA000000188000FF2695
-:100C40000000000F4722000800000009070E000FF7
-:100C500000000008070E00080000000802800001E4
-:100C60000000000702851C000000000882850001CA
-:100C70000000000002854C000000000742851C00B7
-:100C800000000003C3AA52000000000003B10E00E0
-:100C9000000000074B071C000000000F0F3000078A
-:100CA0000000000F0A960003000000000A955C0097
-:100CB000000000004A005A00000000000C960A00E4
-:100CC000000000090C99FFFF000000080D00FFFF65
-:100CD00000000010B1963202000000080F800005ED
-:100CE00000000010B1A8000800000010205F000004
-:100CF0000000000B2FDF0002000000002C2000008D
-:100D0000000000002CA70000000000082D000010CB
-:100D1000000000082D800108000000188000FF126C
-:100D20000000000C2980000100000010001F0000DE
-:100D30000000000C1F800001000000002ADF0000FE
-:100D4000000000082A00000D000000080500AAAA03
-:100D5000000000188000FE680000001091D4000020
-:100D60000000000806005555000000188000FF0034
-:100D70000000000C298000010000000C1F80000111
-:100D8000000000082A000007000000080500555573
-:100D9000000000188000FE60000000080305000449
-:100DA0000000000683040C00000000080285020019
-:100DB0000000000086050C0000000001860C0E00FB
-:100DC00000000008020400040000000002041800F3
-:100DD00000000000838718000000001800020000D7
-:100DE00000000010B18000040000001F0303010098
-:100DF00000000008050000FF0000001800020000CD
-:100E0000000000002A00000000000010B1D4000023
-:100E10000000000C298000010000000802540009B5
-:100E2000000000092952003F0000001800040000E3
-:100E30000000001880000010000000188000001161
-:100E4000000000188000004B000000188000013CEA
-:100E5000000000188000013B000000188000013AEB
-:100E6000000000188000013A000000188000000017
-:100E7000000000188000014D0000001880000136BD
-:100E8000000000188000000C0000001880000152D3
-:100E900000000018800001AC0000001880000080F5
-:100EA00000000018800001070000001880000115F4
-:100EB000000000002A000000000000188000FFEA87
-:100EC000000000002A0000000000000C2980000043
-:100ED0000000001020530000000000188000FFE612
-:100EE000000000002A000000000000188000FFE45D
-:100EF0000000000003820000000000188000FFDFF7
-:100F0000000000010C161400000000008C181400F2
-:100F10000000001091980003000000080C960002E9
-:100F200000000010B1800003000000080C960001D2
-:100F3000000000000C000000000000000D1900007F
-:100F400000000010205600000000000C2BD700010C
-:100F5000000000080F8000010000000000000000F9
-:100F600000000010001F00000000000C6BD7000103
-:100F700000000010011301F100000018000700003C
-:100F800000000000050200000000001091963421CE
-:100F900000000010205F0000000000002C1E000078
-:100FA000000000082C800006000000082D0000064C
-:100FB000000000082D800102000000000000000079
-:100FC0000000001091DE0000000000000D61000034
-:100FD00000000018000A00000000000005020000E8
-:100FE000000000109196341600000010205F0000F1
-:100FF0000000000009D80000000000002C1E0000C6
-:10100000000000082C80010E000000082D00000ADE
-:10101000000000082D800102000000000000000018
-:101020000000001091DE0000000000000D620000D2
-:10103000000000002C13000000000018000A00004F
-:101040000000000005020000000000109196340925
-:1010500000000010205F0000000000002C1E0000B7
-:10106000000000082C800006000000082D00006A27
-:10107000000000082D8001020000000000000000B8
-:101080000000001091DE0000000000000D7A00005A
-:1010900000000018000A00000000001091DE0000AF
-:1010A00000000010001F00000000000C6BD70001C2
-:1010B000000000002F80AA00000000002A000000AD
-:1010C000000000000D61000000000000036200004D
-:1010D000000000002C4000000000000002638C00B3
-:1010E0000000000026460000000000080204001274
-:1010F00000000010B906082E000000000F58000084
-:10110000000000000A640000000000000AE5000082
-:10111000000000090B66FFFF000000000C0000004B
-:10112000000000000B800000000000080CC6001248
-:10113000000000188000FFCA0000001020560000C8
-:101140000000000C2BD70001000000080F800003F6
-:10115000000000000000000000000010001F000060
-:101160000000000C6BD700010000000827110012DE
-:10117000000000006690000000000008A31B0012A1
-:1011800000000010B198000600000010001F0000D1
-:101190000000000C6BD7000100000010205600007A
-:1011A0000000000C2BD70001000000080F80000495
-:1011B0000000000822000003000000082C80000C42
-:1011C000000000082D00000C00000010001F0000AF
-:1011D0000000000C6BD70001000000002596000005
-:1011E0000000000C298000000000000006660000DE
-:1011F0000000000086611800000000090260000F76
-:101200000000000F0204000200000010B60C0803EA
-:101210000000000C1FBF00000000000C336600102F
-:1012200000000000321400000000000032950000B1
-:101230000000000573662C000000000031E32E0062
-:10124000000000082D800010000000102053000056
-:101250000000001091DE0000000000188000FF7602
-:1012600000000000230000000000000925E6FFFF49
-:10127000000000082200000B0000000C6952000072
-:101280000000000C29800000000000102053000026
-:10129000000000188000FF6F0000001091DE0000C9
-:1012A00000000010001F00000000000C6BD70001C0
-:1012B000000000002F80AA00000000002A000000AB
-:1012C000000000002C400000000000082C800040BE
-:1012D000000000082D000020000000082D80011CE7
-:1012E00000000000000000000000001091DE00007F
-:1012F0000000000F42EA001000000010004F000440
-:1013000000000010B74692000000000802490012D9
-:1013100000000010B5840A00000000000D6100000C
-:1013200000000010BA66346D000000000362000087
-:1013300000000010B8630C6B000000088305001269
-:1013400000000010004F00020000000003490000F0
-:101350000000000183068C000000000083C60C0022
-:1013600000000010B1870010000000000B6E0000AC
-:10137000000000188000FF50000000010669140002
-:1013800000000010918C000200000008B4E9000188
-:1013900000000010B1E92C5F0000000086692C00FD
-:1013A00000000000020000000000000902EAFFFF48
-:1013B00000000010000C00020000000002040A00FF
-:1013C0000000000F460C00010000000F0285000124
-:1013D00000000010918C01FC00000010B7040E56B4
-:1013E000000000002C400000000000000F40000042
-:1013F000000000000D610000000000000A64000011
-:10140000000000000AE50000000000090B66FFFF75
-:10141000000000000C000000000000000B80000035
-:10142000000000080C86001200000010205600008A
-:101430000000000C2BD70001000000080F80000303
-:101440000000000C2952000000000010001F0000E6
-:101450000000000C6BD700010000000827110012EB
-:10146000000000006690000000000000264600001A
-:10147000000000002306000000000010B1980009E1
-:1014800000000010001F00000000000C6BD70001DE
-:1014900000000010205600000000000C2BD70001B7
-:1014A000000000080F8000040000000000000000A1
-:1014B00000000010001F00000000000C6BD70001AE
-:1014C000000000003214000000000000329500000F
-:1014D0000000000031E32E000000000573662C00C0
-:1014E000000000002596000000000010B1870021D8
-:1014F0000000000C298000000000000F0F6B0007A7
-:10150000000000000D690000000000000A6C0000EF
-:10151000000000000AED0000000000000B6E00005B
-:10152000000000000B800000000000000C8700009D
-:10153000000000188000FF18000000010C161400C5
-:10154000000000008C181400000000080C96000138
-:101550000000001091980002000000080C990001A2
-:10156000000000000D190000000000000C00000049
-:1015700000000010205600000000000C2BD70001D6
-:10158000000000080F800001000000102053000040
-:101590000000000C6952000100000010001F000054
-:1015A0000000000C6BD700010000000022C58C0079
-:1015B00000000000231200000000000027110000BE
-:1015C000000000002690000000000010B8170E0375
-:1015D0000000000C29800000000000188000FFEBD4
-:1015E0000000000082970E0000000000A3120A0015
-:1015F000000000082200001A000000082C80000CE7
-:10160000000000082D00000C000000082D800010D4
-:1016100000000010001F00000000000C6BD700014C
-:10162000000000000D6E000000000003E7CF340052
-:101630000000000C298000000000001091DE000076
-:1016400000000010B1870007000000003614000001
-:101650000000000036950000000000003716000072
-:10166000000000082C800050000000082D00003011
-:10167000000000082D80000C000000102053000026
-:10168000000000188000FEF1000000002646000067
-:1016900000000000230000000000000925E6FFFF15
-:1016A000000000000B6E000000000003E7CF2C00DC
-:1016B000000000082200001B0000000C695200001E
-:1016C0000000000C298000000000001020530000E2
-:1016D000000000188000FEE7000000002FD5000089
-:1016E000000000002A00000000000010003F000C75
-:1016F000000000000666000000000000866118007F
-:1017000000000009026000F000000010B70C08089B
-:10171000000000002C4000000000000C7366001068
-:10172000000000082C800018000000082D000018A0
-:10173000000000082D8000020000000C5FBF0000C8
-:101740000000001091DE0000000000188000FED8AC
-:10175000000000002FD50000000000002A0000005B
-:10176000000000002C4000000000000C7366001018
-:10177000000000082C800018000000082D00001850
-:10178000000000082D8000020000000C5FBF000078
-:101790000000001091DE0000000000082C80000313
-:1017A000000000082D000003000000093060FFF079
-:1017B000000000082D8000010000000C29800000BE
-:1017C0000000001091DE0000000000082C80001ACC
-:1017D000000000082D00001A000000003300000087
-:1017E000000000082D800002000000003180000091
-:1017F0000000001091DE0000000000082C80000CAA
-:10180000000000082D00000C000000082D800004DE
-:1018100000000010205300000000001091DE0000C6
-:10182000000000188000FEBD000000188000FEBC13
-:10183000000000002A00000000000010001F00004F
-:101840000000000C6BD70001000000000F008000BA
-:10185000000000080F80000700000018800000153D
-:10186000000000000502000000000008220000093E
-:1018700000000000286D00000000000029000000AA
-:101880000000000F6568001000000003F66C940073
-:1018900000000010B972A0040000000C73E70019EA
-:1018A0000000000C21420004000000003BF6000094
-:1018B0000000000C298000000000001020530000F0
-:1018C00000000008220000080000000C6142000433
-:1018D00000000018000A0000000000002A000000BC
-:1018E00000000010001F00000000000C6BD700017A
-:1018F0000000000F0F470007000000080F800008DD
-:101900000000000C2980000000000010205300009F
-:10191000000000188000FE9F0000001091DE000013
-:10192000000000002FD5000000000010001F000084
-:101930000000000C6BD700010000000033510000D4
-:10194000000000002A00000000000010B1C60029BD
-:101950000000000F0F500007000000000A600000A8
-:10196000000000000AE100000000000F4B620008C8
-:10197000000000090B1600FF0000000F4C62001071
-:10198000000000000D620000000000090D1A00FFB9
-:1019900000000010075000030000000C0D1A0008A2
-:1019A0000000000C0B160008000000000CC6000030
-:1019B000000000000B8000000000000006980000FE
-:1019C00000000010205600000000000C2BD7000182
-:1019D000000000080F8000030000001006C2000491
-:1019E0000000000C29000002000000102642000246
-:1019F0000000000C29520003000000082200000132
-:101A000000000010001F00000000000C6BD7000158
-:101A100000000000231B00000000000027111A0036
-:101A200000000000669000000000000C2952000039
-:101A300000000010B197320C0000000C298000005B
-:101A40000000000006980000000000102053000075
-:101A50000000000C295200030000000022C58C0089
-:101A600000000010001F00000000000C6BD70001F8
-:101A700000000010205600000000000C2BD70001D1
-:101A8000000000080F800003000000188000FFEF36
-:101A900000000010B1C8001300000010B1C6000320
-:101AA0000000000C298000000000001020530000FE
-:101AB0000000000C295200000000000C2952000315
-:101AC0000000001006C200020000000C29520002B3
-:101AD0000000000022C58C00000000002765000007
-:101AE0000000000026E400000000000822000016AC
-:101AF00000000010B1C600030000000023480000F1
-:101B000000000010B1800005000000002348000024
-:101B10000000000C298000000000000F0F5000079B
-:101B200000000018800000120000000822000016CB
-:101B30000000000C298000000000000030140000AC
-:101B40000000000030950000000000100750000366
-:101B5000000000090B1600FF000000090D1A00FF2D
-:101B60000000000F31160008000000003162340050
-:101B700000000003F162300000000010205F000050
-:101B8000000000002C510000000000092CD1007F53
-:101B9000000000082CD90000000000082D00000003
-:101BA000000000082D80000C000000000000000074
-:101BB0000000001091DE00000000001005C20003CC
-:101BC0000000000033000000000000080F80000744
-:101BD000000000102053000000000010001F000053
-:101BE0000000000C6BD70001000000188000FE44CC
-:101BF000000000002FD50000000000002A000000B7
-:101C00000000000F0F50000700000010B1C60030A8
-:101C10000000000F4742000800000009070E000FF7
-:101C200000000008070E000800000010001F000060
-:101C30000000000C6BD70001000000080900000143
-:101C40000000000709121C0000000003CBCA92002C
-:101C5000000000000B97A2000000000742171C00C4
-:101C6000000000000B0400000000000F0A840003C5
-:101C7000000000000A959C00000000004A009A0045
-:101C80000000000882120001000000010C1708008B
-:101C9000000000000C978C000000000002180000FB
-:101CA000000000080D00FFFF000000080F80000684
-:101CB0000000000C290000000000001006C2000413
-:101CC0000000000C29520002000000102642000211
-:101CD0000000000C2952000300000008220000014F
-:101CE00000000010001F00000000000C6BD7000176
-:101CF00000000010B197320D00000000231B00000F
-:101D0000000000002711080000000000669000009D
-:101D10000000000C298000000000000002180000F4
-:101D200000000010205300000000000C29520003A6
-:101D30000000000022C5360000000010001F000057
-:101D40000000000C6BD70001000000080F800006A7
-:101D5000000000188000FFF200000000231B0000BC
-:101D6000000000002711080000000000669000003D
-:101D700000000010B1C8000B0000000C298000001A
-:101D800000000010205300000000000C2952000049
-:101D90000000000C295200030000001006C20002DF
-:101DA0000000000C295200020000000022C58C0037
-:101DB00000000000276500000000000026E400008D
-:101DC0000000000023480000000000082200001767
-:101DD0000000000C2980000000000010001F00001F
-:101DE0000000000C6BD70001000000102053000021
-:081DF000000000188000FE0352
-:00000001FF
-/*
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- */
diff --git a/firmware/bnx2/bnx2-rv2p-09-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-5.0.0.j3.fw.ihex
new file mode 100644
index 0000000..69f5e95
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-09-5.0.0.j3.fw.ihex
@@ -0,0 +1,462 @@
+:100000000000000000000E00000000580000000981
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000000DD800000E58000000050000000070
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B180000659
+:100060000000001F05030300000000080500FFFF5B
+:10007000000000180002000000000008050000FF5A
+:10008000000000180002000000000008AC000001A1
+:1000900000000000050000000000000C2F8000019F
+:1000A000000000002B000000000000002B8000007A
+:1000B0000000001091E0000200000008AC00000108
+:1000C00000000010203F006B00000010213F0003E3
+:1000D0000000001020BF003A000000188000FFFD63
+:1000E00000000010B1B8B0150000000B2FDF0002B7
+:1000F0000000000003D80000000000002C380000C1
+:10010000000000082C800000000000082D00000006
+:100110000000001091D400000000000806005555B2
+:10012000000000188000007C000000082D80011CE9
+:1001300000000008020000010000001091DE000035
+:100140000000000F42E0001C0000001091840A161D
+:1001500000000018800000830000000C29800002CD
+:100160000000000C1F800002000000002ADF0000D9
+:10017000000000082A00000F000000000500000039
+:10018000000000188000FFE60000000802000001E7
+:100190000000000F42E0001C0000001091840A18CB
+:1001A000000000082C800006000000082D0000065A
+:1001B0000000001091D40000000000082D8001060E
+:1001C0000000001880000072000000188000FFF19D
+:1001D00000000008B1000001000000082C80010CA4
+:1001E000000000082D000008000000082D8000011C
+:1001F000000000188000006C0000000B2FDF0002E0
+:100200000000000C1F800002000000002C0700000E
+:100210000000001091DE00000000000805005555A8
+:10022000000000188000FFD20000000B2FDF00024A
+:100230000000000C1F800000000000002C070000E0
+:100240000000001091DE0000000000080500555578
+:10025000000000188000FFCC0000000C1F8000028E
+:100260000000000805005555000000188000FFC977
+:100270000000000C298000020000000C1F8000021A
+:10028000000000002ADF0000000000082A0000052E
+:100290000000000805005555000000188000FFC34D
+:1002A000000000080224004A0000001800040000BA
+:1002B000000000188000001C000000188000001ED4
+:1002C000000000188000006500000018800000BBDE
+:1002D00000000018800000BA000000188000000034
+:1002E00000000018800000000000001880000000DE
+:1002F00000000018800000000000001880000000CE
+:1003000000000018800000000000001880000000BD
+:1003100000000018800000000000001880000106A6
+:10032000000000188000000000000018800000009D
+:100330000000001880000015000000188000001B5D
+:10034000000000188000000000000018800000D1AC
+:10035000000000188000002F000000188000010637
+:10036000000000188000013100000018800000FC2F
+:100370000000001880000155000000188000004EA9
+:100380000000001880000000000000188000008EAF
+:100390000000000C1F8000010000000005000000AC
+:1003A000000000188000FFA20000001091D400009F
+:1003B0000000000C298000010000000C1F800001DB
+:1003C000000000082A0000020000000005000000F4
+:1003D000000000188000FF9C0000001091D4000075
+:1003E0000000000C298000010000000C1F800001AB
+:1003F0000000000029420000000000082A0000025E
+:100400000000000005000000000000188000FF95BB
+:10041000000000188000FF9400000010B1BCB00A7A
+:100420000000000B2FDF00020000000003D80000D6
+:10043000000000002C3C00000000001091D40000DF
+:100440000000000806005555000000188000001745
+:1004500000000018800000CA000000102C6201BAE1
+:100460000000001880000006000000082C80010D2C
+:10047000000000082D0000090000001091D40000C9
+:10048000000000082D8001070000001880000024F3
+:100490000000000C298000000000000C1F800000FC
+:1004A0000000001091DE0000000000002ADF0000C4
+:1004B000000000082A00000600000008050055554D
+:1004C000000000188000FF7E0000001091D40000A2
+:1004D0000000000C298000010000000C1F800001BA
+:1004E000000000082A00000B0000000005000000CA
+:1004F000000000188000FF780000001800020000D3
+:10050000000000000682000000000010B18A000810
+:1005100000000010B18C14070000000B050AFFFF5B
+:1005200000000010B18A000300000000860A1800D5
+:1005300000000010918C0000000000082A0000015B
+:100540000000001091D4000000000018000D000011
+:1005500000000000050200000000001091DE000015
+:1005600000000018000A00000000000006820000E1
+:100570000000001091DE000000000010BEE1000548
+:10058000000000188000FF5F0000000105611400FA
+:1005900000000010918A000200000008B0E1000194
+:1005A00000000018000D000000000000068200009E
+:1005B0000000001091DE000000000010BEE2000507
+:1005C000000000188000FF570000000105621400C1
+:1005D00000000010918A000200000008B1620001D2
+:1005E00000000018000D000000000010B1A0B013C2
+:1005F0000000000B2FDF0002000000002C20000094
+:10060000000000082C800000000000082D00000001
+:100610000000001091D400000000000806005555AD
+:10062000000000188000FFDC000000082D80011C85
+:1006300000000010001F0000000000188000FFE60E
+:100640000000000F476000080000000F060E0001C8
+:10065000000000000F580000000000000A640000C5
+:10066000000000000AE50000000000090B66FFFF23
+:10067000000000000D610000000000188000001361
+:100680000000000F476000080000000B2FDF000291
+:10069000000000082C800000000000082D00000071
+:1006A0000000001091D40000000000082D80011C03
+:1006B0000000000F060E000100000010001F0000E7
+:1006C000000000000F580000000000188000FFD458
+:1006D000000000000A640000000000000AE50000BD
+:1006E000000000090B66FFFF000000000D61000024
+:1006F00000000000026200000000000B2FDF00027B
+:10070000000000003104000000000000309A0000EA
+:10071000000000090560000F00000010B18A000A07
+:100720000000000005634C0000000008050A0012EC
+:1007300000000010B9621403000000000300000074
+:100740000000001880000005000000188000FF2451
+:1007500000000010B60614030000000803060001A4
+:10076000000000188000FF2A000000000C9618000E
+:10077000000000090C99FFFF00000004CC99340030
+:1007800000000010B1963202000000080F80000047
+:100790000000000C298000010000000C295200011B
+:1007A0000000000C29520000000000080200000EAA
+:1007B000000000080280001A00000010B1C40A0204
+:1007C00000000008020000030000000822000001F1
+:1007D0000000000C1F800001000000002ADF000064
+:1007E000000000002A000800000000080500555520
+:1007F000000000188000FF180000000B2FDF00022F
+:100800000000001091D40000000000082A00000140
+:10081000000000002C2000000000001091D4000017
+:10082000000000082C800000000000082D000000DF
+:10083000000000082D80011C000000188000FFA3AC
+:10084000000000082C800006000000082D000006B3
+:1008500000000000308000000000000031000000B7
+:10086000000000082D8000060000000C2980000117
+:100870000000000C1F8000010000001091DE00004D
+:10088000000000002ADF0000000000082A0000101D
+:100890000000000005000000000000188000FF03B9
+:1008A0000000001091A0B009000000082C80010D8C
+:1008B000000000082D0000090000001091D4000085
+:1008C000000000082D800107000000188000FF9C38
+:1008D000000000188000001000000008AC000001BB
+:1008E000000000188000000B000000000380B00032
+:1008F0000000000B2FDF0002000000002C00400071
+:100900000000001091D400000000000806005555BA
+:10091000000000188000FF7E0000001880000031F9
+:1009200000000018800000060000000B2FDF00020E
+:10093000000000002C000E00000000082A00000744
+:100940000000000805005555000000188000FEED6D
+:1009500000000000068200000000000C2980000159
+:100960000000000C1F800001000000100CE70007D1
+:10097000000000090562FFFF00000010BA6C1405BA
+:10098000000000002ADF000000000000210000003D
+:10099000000000082A0000050000001091D40000AB
+:1009A000000000082C80010C000000082D00000849
+:1009B0000000000C31620018000000082D800001CA
+:1009C000000000188000FF7200000018000D0000F9
+:1009D00000000010B1A0B00E0000000B2FDF0002DD
+:1009E0000000000003D80000000000002C200000E0
+:1009F0000000001091D400000000001880000015D5
+:100A0000000000102C620002000000188000000CA2
+:100A10000000000B2FDF0002000000002C07000088
+:100A20000000000C1F8000010000001091DE00009B
+:100A3000000000080500FFFF000000188000FECF46
+:100A4000000000082C80010D000000082D000009A6
+:100A50000000001091D40000000000082D80010764
+:100A6000000000188000FF690000000C29800001D0
+:100A70000000000C1F8000010000001091DE00004B
+:100A8000000000002ADF0000000000082A00000A21
+:100A90000000000005000000000000188000FEC3F8
+:100AA0000000000006820000000000082C80010CFD
+:100AB000000000082D000008000000082D8001340F
+:100AC000000000000000000000000010205F000097
+:100AD000000000082C800140000000082D00003CB0
+:100AE000000000082D80012400000000000000002C
+:100AF0000000001091DE0000000000082C80008043
+:100B0000000000082D000000000000082D800105F5
+:100B100000000010BEE20005000000188000FEACDE
+:100B2000000000010562140000000010918A00021C
+:100B300000000008B16200010000001091DE00001A
+:100B400000000018000D00000000001091D400000B
+:100B5000000000080600AAAA000000188000FF3567
+:100B60000000000C298000010000000C1F80000123
+:100B7000000000082A000009000000080500AAAAD9
+:100B8000000000188000FEA60000001091D40000B4
+:100B90000000000806005555000000188000FF2DD9
+:100BA0000000001091A03C0200000010B1E66207B6
+:100BB0000000000B2FDF0002000000002C310000BD
+:100BC000000000092CB1007F000000082CD90000B3
+:100BD000000000082D000000000000082D80010D1D
+:100BE00000000010B1A8000600000010205F000007
+:100BF000000000002C200000000000002CA70000D6
+:100C0000000000082D000010000000082D800108E1
+:100C1000000000188000FF2800000010B1A600109E
+:100C200000000010001F00000000000F0F30000740
+:100C3000000000000A600000000000000AE100005F
+:100C40000000000F4B620008000000090B1600FFB7
+:100C5000000000000D620000000000090D1A00FFF6
+:100C600000000010073000030000000C0D1A0008FF
+:100C70000000000C0B1600080000000F4CE30018E9
+:100C8000000000000C992C0000000004CC993400F6
+:100C9000000000080F8000000000000C2980000107
+:100CA00000000000333100000000000822000016A0
+:100CB000000000002ADF0000000000082A00000CED
+:100CC00000000010009F0000000000000F20000046
+:100CD0000000000C1F8000010000000805005555B1
+:100CE000000000188000FE7A0000001091D400007F
+:100CF000000000080600AAAA000000188000FF01FA
+:100D00000000000F4722000800000009070E000F36
+:100D100000000008070E0008000000080280000123
+:100D20000000000702851C00000000088285000109
+:100D30000000000002854C000000000742851C00F6
+:100D400000000003C3AA52000000000003B10E001F
+:100D5000000000074B071C000000000F0F300007C9
+:100D60000000000F0A960003000000000A955C00D6
+:100D7000000000004A005A00000000000C960A0023
+:100D8000000000090C99FFFF000000080D00FFFFA4
+:100D900000000010B1963202000000080F8000052C
+:100DA00000000010B1A8000800000010205F000043
+:100DB0000000000B2FDF0002000000002C200000CC
+:100DC000000000002CA70000000000082D0000100B
+:100DD000000000082D800108000000188000FEEFD0
+:100DE0000000000C2980000100000010001F00001E
+:100DF0000000000C1F800001000000002ADF00003E
+:100E0000000000082A00000D000000080500AAAA42
+:100E1000000000188000FE540000001091D4000073
+:100E20000000000806005555000000188000FEDB99
+:100E30000000000C298000010000000C1F80000150
+:100E4000000000082A0000070000000805005555B2
+:080E5000000000188000FE4CB8
+:080E580000000010B18000044D
+:100E60000000001F0503030000000008050000FF4C
+:100E70000000001800020000000000002A0000002E
+:100E800000000010B1D400000000001091DE00004E
+:100E9000000000102053000000000010001F0000A0
+:100EA000000000002F80AA000000000C2980000133
+:100EB000000000080254000E000000002C4000005A
+:100EC000000000092952003F000000180004000043
+:100ED00000000018800000100000001880000011C1
+:100EE000000000188000003900000018800000FD9C
+:100EF00000000018800000FC00000018800000FBCB
+:100F000000000018800000FB0000001880000000B6
+:100F1000000000188000011300000018800000F796
+:100F2000000000188000000B00000018800001176E
+:100F300000000018800001650000001880000063B8
+:100F400000000018800000CE00000018800000DEC5
+:100F5000000000002A000000000000188000FFE5EB
+:100F6000000000002A0000000000000C29800000A2
+:100F7000000000188000FFE2000000002A000000CE
+:100F8000000000188000FFE00000001800020000D0
+:100F900000000000050200000000001091963421BE
+:100FA00000000010205F0000000000002C1E000068
+:100FB000000000082C800006000000082D0000063C
+:100FC000000000082D800102000000000000000069
+:100FD0000000001091DE0000000000000D61000024
+:100FE00000000018000A00000000000005020000D8
+:100FF000000000109196341600000010205F0000E1
+:101000000000000009D80000000000002C1E0000B5
+:10101000000000082C80010E000000082D00000ACE
+:10102000000000082D800102000000000000000008
+:101030000000001091DE0000000000000D620000C2
+:10104000000000002C13000000000018000A00003F
+:101050000000000005020000000000109196340915
+:1010600000000010205F0000000000002C1E0000A7
+:10107000000000082C800006000000082D00006A17
+:10108000000000082D8001020000000000000000A8
+:101090000000001091DE0000000000000D7A00004A
+:1010A00000000018000A0000000000002A000000F4
+:1010B000000000000D61000000000000036200005D
+:1010C00000000010234200C10000000002638C00F9
+:1010D0000000000026460000000000080204001284
+:1010E00000000010B9060827000000000F5800009B
+:1010F000000000000A640000000000000AE5000093
+:10110000000000090B66FFFF000000000C0000005B
+:10111000000000000B800000000000080CC6001258
+:10112000000000188000FFCE000000080F800003C0
+:10113000000000000000000000000010009F000000
+:101140000000000827110012000000006690000057
+:1011500000000008A31B001200000010B19800035B
+:1011600000000010001F0000000000080F800004B5
+:101170000000000822000003000000082C80000C82
+:10118000000000082D00000C00000010009F00006F
+:1011900000000000259600000000000C29800000DF
+:1011A00000000000066600000000000086611800D4
+:1011B000000000090260000F0000000F020400029E
+:1011C00000000010B60C08050000000C1FBF000056
+:1011D000000000102866000300000008078F0001CF
+:1011E0000000000C33660010000000003214000004
+:1011F00000000000329500000000000573662C001E
+:101200000000000031E32E00000000082D800010D7
+:10121000000000188000FF8E000000002300000086
+:101220000000000925E6FFFF000000082200000B77
+:101230000000000C695200000000000C2980000032
+:101240000000001028660075000000188000FF876D
+:10125000000000002A000000000000082C80004070
+:10126000000000082D000020000000082D80011C57
+:1012700000000000000000000000001091DE0000EF
+:101280000000000F42EA001000000010004F0004B0
+:1012900000000010B746920000000008024900124A
+:1012A00000000010B5840A00000000000D6100007D
+:1012B00000000010BA6634570000000883050012D1
+:1012C00000000010004F0002000000000349000071
+:1012D0000000000183068C000000000083C60C00A3
+:1012E00000000010B1870011000000000B6E00002C
+:1012F00000000010BEE90005000000188000FF6E2D
+:10130000000000010569140000000010918A00022D
+:1013100000000008B4E9000100000010B1E92C4A07
+:101320000000000086692C000000000002000000A0
+:101330000000000902EAFFFF00000010000C00029C
+:101340000000000002040A000000000F460C00012B
+:101350000000000F0285000100000010918C01FCCC
+:1013600000000010B7040E41000000000F40000014
+:10137000000000000D610000000000000A64000091
+:10138000000000000AE50000000000090B66FFFFF6
+:10139000000000000C000000000000000B800000B6
+:1013A000000000080C860012000000080F800003F7
+:1013B0000000000C2952000000000010009F0000F7
+:1013C00000000008271100120000000066900000D5
+:1013D0000000000026460000000000002306000078
+:1013E00000000010B198000500000010001F000070
+:1013F000000000080F800004000000000000000052
+:1014000000000010001F0000000000003214000067
+:1014100000000000329500000000000031E32E00C3
+:101420000000000573662C000000000025960000F7
+:1014300000000010B18700160000000C2980000099
+:101440000000000F0F6B0007000000000D69000096
+:10145000000000000A6C0000000000000AED00001F
+:10146000000000000B6E0000000000000B80000078
+:10147000000000000C870000000000080F8000033F
+:1014800000000010205300000000000C6952000111
+:1014900000000010001F00000000000022C58C00AA
+:1014A00000000000231B00000000000027110000C6
+:1014B000000000002690000000000010B8170E0386
+:1014C0000000000C29800000000000188000FFF6DA
+:1014D00000000010B1980002000000080F80000416
+:1014E000000000082200001A000000082C80000CF8
+:1014F000000000082D00000C000000082D800010E6
+:1015000000000010001F0000000000000D6E000031
+:1015100000000003E7CF34000000000C2980000029
+:101520000000001091DE000000000010B1870007ED
+:101530000000000036140000000000003695000096
+:101540000000000037160000000000082C8000504A
+:10155000000000082D000030000000082D80000C65
+:10156000000000188000FF24000000002646000054
+:1015700000000000230000000000000925E6FFFF36
+:10158000000000000B6E000000000003E7CF2C00FD
+:10159000000000082200001B0000000C695200003F
+:1015A0000000000C29800000000000188000FF1BD4
+:1015B000000000002A00000000000010086600057E
+:1015C00000000000066600000000000086611800B0
+:1015D00000000009026000F000000010B60C0802D4
+:1015E000000000188000FF140000000006820000C8
+:1015F00000000010B18F000000000008878F00017C
+:101600000000000C73660010000000082C80001819
+:10161000000000082D000018000000082D800002C6
+:101620000000000C5FBF00000000001091DE000011
+:1016300000000018000D0000000000002A0000005B
+:1016400000000010286601F5000000082C8000034F
+:10165000000000082D000003000000093060FFF0CA
+:10166000000000082D8000010000000C298000000F
+:101670000000001091DE0000000000082C80001A1D
+:10168000000000082D00001A00000005736600002D
+:10169000000000082D8000020000000031800000E2
+:1016A0000000001091DE0000000000082C80000CFB
+:1016B000000000082D00000C000000082D80000430
+:1016C000000000188000FEF8000000180002000072
+:1016D000000000188000FEF6000000002A00000054
+:1016E00000000010001F0000000000000F0080003C
+:1016F000000000080F800007000000188000001A9A
+:1017000000000000280A00000000000005020000A0
+:10171000000000082200000900000000290000006D
+:101720000000000F6568001000000003F66C9400D4
+:1017300000000010B972A0040000000C73E700194B
+:101740000000000C21420004000000003CF80000F2
+:101750000000000C29800000000000102053000051
+:1017600000000008220000080000000C6142000494
+:1017700000000018000A0000000000000502000040
+:101780000000000C61420000000000100142000354
+:101790000000000C33E7001D0000000C6142000255
+:1017A00000000018000A0000000000002A000000ED
+:1017B00000000010001F00000000000F0F4700078E
+:1017C000000000080F8000080000000C29800000C5
+:1017D00000000010009F0000000000188000FED5EF
+:1017E0000000000033510000000000002A0000004B
+:1017F00000000010B1C600230000000F0F500007CA
+:10180000000000000A600000000000000AE1000083
+:101810000000000F4B620008000000090B1600FFDB
+:101820000000000F4C620010000000000D6200007C
+:10183000000000090D1A00FF00000010075000030F
+:101840000000000C0D1A00080000000C0B16000828
+:10185000000000000CC60000000000000B8000002B
+:101860000000000006980000000000080F80000340
+:101870000000001006C200040000000C2900000255
+:1018800000000010264200020000000C2952000354
+:10189000000000082200000100000010009F00006E
+:1018A00000000000231B00000000000027111A00A8
+:1018B00000000000669000000000000C29520000AB
+:1018C00000000010B19732090000000C29800000D0
+:1018D00000000000069800000000001020530000E7
+:1018E0000000000C295200030000000022C58C00FB
+:1018F00000000010001F0000000000080F8000031F
+:10190000000000188000FFF300000010B1C80013B1
+:1019100000000010B1C600030000000C2980000088
+:1019200000000010205300000000000C29520000AD
+:101930000000000C295200030000001006C2000243
+:101940000000000C295200020000000022C58C009B
+:1019500000000000276500000000000026E40000F1
+:10196000000000082200001600000010B1C60003AD
+:10197000000000002348000000000010B1800005B6
+:1019800000000000234800000000000C2980000037
+:101990000000000F0F500007000000188000001228
+:1019A00000000008220000160000000C2980000042
+:1019B000000000003014000000000000309500001E
+:1019C0000000001007500003000000090B1600FF84
+:1019D000000000090D1A00FF0000000F311600087A
+:1019E000000000003162340000000003F1623000AA
+:1019F00000000010205F0000000000002C510000DB
+:101A0000000000092CD1007F000000082CD9000044
+:101A1000000000082D000000000000082D80000CD0
+:101A200000000000000000000000001091DE000037
+:101A30000000001005C20004000000080F8000072D
+:101A4000000000003300000000000010009F0000B4
+:101A5000000000188000FE86000000002A00000040
+:101A60000000000F0F50000700000010B1C6002D4D
+:101A70000000000F4742000800000009070E000F99
+:101A800000000008070E000800000010001F000002
+:101A900000000008090000010000000709121C00F6
+:101AA00000000003CBCA9200000000000B97A200C8
+:101AB0000000000742171C00000000000B0400009B
+:101AC0000000000F0A840003000000000A959C003B
+:101AD000000000004A009A00000000088212000185
+:101AE000000000010C170800000000000C978C009B
+:101AF0000000000002180000000000080D00FFFFB9
+:101B0000000000080F8000060000000C2900000003
+:101B10000000001006C200040000000C2952000260
+:101B200000000010264200020000000C29520003B1
+:101B3000000000082200000100000010009F0000CB
+:101B400000000010B197320C00000000231B0000C1
+:101B5000000000002711080000000000669000004F
+:101B60000000000C298000000000000002180000A6
+:101B700000000010205300000000000C2952000358
+:101B80000000000022C5360000000010001F000009
+:101B9000000000080F800006000000188000FFF41D
+:101BA00000000000231B00000000000027110800B7
+:101BB000000000006690000000000010B1C8000B9B
+:101BC0000000000C298000000000001020530000DD
+:101BD0000000000C295200000000000C29520003F4
+:101BE0000000001006C200020000000C2952000292
+:101BF0000000000022C58C000000000027650000E6
+:101C00000000000026E4000000000000234800005F
+:101C100000000008220000170000000C29800000CE
+:101C200000000010001F0000000000188000FE4BA4
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw.ihex
new file mode 100644
index 0000000..533dbea
--- /dev/null
+++ b/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j3.fw.ihex
@@ -0,0 +1,498 @@
+:100000000000000000000E78000000580000000909
+:1000100000000000000000000000000000000000E0
+:1000200000000000000000000000000000000000D0
+:1000300000000FA800000ED0000000050000000026
+:1000400000000000000000000000000000000000B0
+:080050000000000000000000A8
+:0800580000000010B180000659
+:100060000000001F03030300000000080500FFFF5D
+:10007000000000180002000000000008050000FF5A
+:10008000000000180002000000000008AC000001A1
+:1000900000000000050000000000000C2F8000019F
+:1000A000000000002B000000000000002B8000007A
+:1000B0000000001091E0000200000008AC00000108
+:1000C00000000010203F006B00000010213F0003E3
+:1000D0000000001020BF003A000000188000FFFD63
+:1000E00000000010B1B8B0150000000B2FDF0002B7
+:1000F0000000000003D80000000000002C380000C1
+:10010000000000082C800000000000082D00000006
+:100110000000001091D400000000000806005555B2
+:10012000000000188000008F000000082D80011CD6
+:1001300000000008020000010000001091DE000035
+:100140000000000F42E0001C0000001091840A161D
+:1001500000000018800000960000000C29800002BA
+:100160000000000C1F800002000000002ADF0000D9
+:10017000000000082A00000F000000000500000039
+:10018000000000188000FFE60000000802000001E7
+:100190000000000F42E0001C0000001091840A18CB
+:1001A000000000082C800006000000082D0000065A
+:1001B0000000001091D40000000000082D8001060E
+:1001C0000000001880000085000000188000FFF18A
+:1001D00000000008B1000001000000082C80010CA4
+:1001E000000000082D000008000000082D8000011C
+:1001F000000000188000007F0000000B2FDF0002CD
+:100200000000000C1F800002000000002C0700000E
+:100210000000001091DE00000000000805005555A8
+:10022000000000188000FFD20000000B2FDF00024A
+:100230000000000C1F800000000000002C070000E0
+:100240000000001091DE0000000000080500555578
+:10025000000000188000FFCC0000000C1F8000028E
+:100260000000000805005555000000188000FFC977
+:100270000000000C298000020000000C1F8000021A
+:10028000000000002ADF0000000000082A0000052E
+:100290000000000805005555000000188000FFC34D
+:1002A000000000080224004A0000001800040000BA
+:1002B000000000188000001C000000188000001ED4
+:1002C000000000188000007800000018800000CABC
+:1002D00000000018800000C9000000188000000025
+:1002E00000000018800000000000001880000000DE
+:1002F00000000018800000000000001880000000CE
+:1003000000000018800000000000001880000000BD
+:100310000000001880000000000000188000011597
+:10032000000000188000000000000018800000009D
+:100330000000001880000015000000188000001B5D
+:10034000000000188000000000000018800000E09D
+:10035000000000188000002F000000188000011528
+:100360000000001880000140000000188000010B10
+:100370000000001880000164000000188000006187
+:100380000000001880000000000000188000009DA0
+:100390000000000C1F8000010000000005000000AC
+:1003A000000000188000FFA20000001091D400009F
+:1003B0000000000C298000010000000C1F800001DB
+:1003C000000000082A0000020000000005000000F4
+:1003D000000000188000FF9C0000001091D4000075
+:1003E0000000000C298000010000000C1F800001AB
+:1003F0000000000029420000000000082A0000025E
+:100400000000000005000000000000188000FF95BB
+:10041000000000188000FF9400000010B1BCB00A7A
+:100420000000000B2FDF00020000000003D80000D6
+:10043000000000002C3C00000000001091D40000DF
+:100440000000000806005555000000188000002A32
+:1004500000000018800000D9000000102C6201BAD2
+:100460000000001880000006000000082C80010D2C
+:10047000000000082D0000090000001091D40000C9
+:10048000000000082D8001070000001880000037E0
+:100490000000000C298000000000000C1F800000FC
+:1004A0000000001091DE0000000000002ADF0000C4
+:1004B000000000082A00000600000008050055554D
+:1004C000000000188000FF7E0000001091D40000A2
+:1004D0000000000C298000010000000C1F800001BA
+:1004E000000000082A00000B0000000005000000CA
+:1004F000000000188000FF780000000002020000E9
+:1005000000000000029A000000000000060C2C0011
+:1005100000000004C60C340000000010001F0000A2
+:1005200000000010B196180C0000000806960004A8
+:1005300000000009068DFFFC00000004CD051A0034
+:1005400000000004CC9A18000000001020D7000022
+:100550000000000C2B56000000000000000000000E
+:1005600000000000000000000000001020D7000084
+:10057000000000080F80000100000010B18001F4AD
+:1005800000000010001F00000000000C6B5600006F
+:1005900000000018000400000000000006820000B7
+:1005A00000000010B18A000800000010B18C140790
+:1005B0000000000B050AFFFF00000010B18A0003D5
+:1005C00000000000860A180000000010918C000056
+:1005D000000000082A0000010000001091D4000073
+:1005E00000000018000D00000000000005020000DF
+:1005F0000000001091DE000000000018000A00005A
+:1006000000000000068200000000001091DE0000E3
+:1006100000000010BEE10005000000188000FF4C43
+:10062000000000010561140000000010918A000222
+:1006300000000008B0E1000100000018000D0000FB
+:1006400000000000068200000000001091DE0000A3
+:1006500000000010BEE20005000000188000FF440A
+:10066000000000010562140000000010918A0002E1
+:1006700000000008B162000100000018000D000039
+:1006800000000010B1A0B0130000000B2FDF00022B
+:10069000000000002C200000000000082C8000005A
+:1006A000000000082D0000000000001091D40000A0
+:1006B0000000000806005555000000188000FFDC0F
+:1006C000000000082D80011C00000010001F000029
+:1006D000000000188000FFE60000000F47600008DF
+:1006E0000000000F060E0001000000000F5800007F
+:1006F000000000000A640000000000000AE500009D
+:10070000000000090B66FFFF000000000D61000003
+:1007100000000018800000130000000F4760000870
+:100720000000000B2FDF0002000000082C800000FA
+:10073000000000082D0000000000001091D400000F
+:10074000000000082D80011C0000000F060E0001B3
+:1007500000000010001F0000000000000F58000003
+:10076000000000188000FFD4000000000A640000B0
+:10077000000000000AE50000000000090B66FFFF12
+:10078000000000000D610000000000000262000097
+:100790000000000B2FDF0002000000003104000009
+:1007A00000000000309A0000000000090560000F02
+:1007B00000000010B18A000A0000000005634C0030
+:1007C00000000008050A001200000010B9621403BE
+:1007D0000000000003000000000000188000000579
+:1007E000000000188000FF1100000010B60614037E
+:1007F0000000000803060001000000188000FF1739
+:10080000000000188000FF9F0000000C29800001FC
+:100810000000000C295200010000000C29520000C9
+:10082000000000080200000E000000080280001A0C
+:1008300000000010B1C40A0200000008020000031A
+:1008400000000008220000010000000C1F800001D1
+:10085000000000002ADF0000000000002A0008005D
+:100860000000000805005555000000188000FF0931
+:100870000000000B2FDF00020000001091D40000E8
+:10088000000000082A000001000000002C200000E9
+:100890000000001091D40000000000082C8000002F
+:1008A000000000082D000000000000082D80011C41
+:1008B000000000188000FFA7000000082C80000640
+:1008C000000000082D00000600000000308000003D
+:1008D0000000000031000000000000082D8000062C
+:1008E0000000000C298000010000000C1F800001A6
+:1008F0000000001091DE0000000000002ADF000070
+:10090000000000082A0000100000000005000000A0
+:10091000000000188000FEF40000001091A0B00953
+:10092000000000082C80010D000000082D000009C7
+:100930000000001091D40000000000082D80010785
+:10094000000000188000FFA00000001880000010C8
+:1009500000000008AC000001000000188000000B3F
+:10096000000000000380B0000000000B2FDF000239
+:10097000000000002C0040000000001091D4000096
+:100980000000000806005555000000188000FF8296
+:1009900000000018800000310000001880000006F0
+:1009A0000000000B2FDF0002000000002C000E00F2
+:1009B000000000082A000007000000080500555547
+:1009C000000000188000FEDE00000000068200002B
+:1009D0000000000C298000010000000C1F800001B5
+:1009E000000000100CE70007000000090562FFFF8F
+:1009F00000000010BA6C1405000000002ADF00009F
+:100A00000000000021000000000000082A0000058E
+:100A10000000001091D40000000000082C80010CA0
+:100A2000000000082D0000080000000C31620018D2
+:100A3000000000082D800001000000188000FF76F3
+:100A400000000018000D000000000010B1A0B00E62
+:100A50000000000B2FDF00020000000003D80000A0
+:100A6000000000002C2000000000001091D40000C5
+:100A70000000001880000015000000102C62000229
+:100A8000000000188000000C0000000B2FDF0002A7
+:100A9000000000002C0700000000000C1F80000177
+:100AA0000000001091DE0000000000080500FFFFBC
+:100AB000000000188000FEC0000000082C80010D1E
+:100AC000000000082D0000090000001091D4000073
+:100AD000000000082D800107000000188000FF6D55
+:100AE0000000000C298000010000000C1F800001A4
+:100AF0000000001091DE0000000000002ADF00006E
+:100B0000000000082A00000A0000000005000000A4
+:100B1000000000188000FEB4000000000682000003
+:100B2000000000082C80010C000000082D000008C7
+:100B3000000000082D8001340000000000000000CB
+:100B400000000010205F0000000000082C80014021
+:100B5000000000082D00003C000000082D80011C52
+:100B600000000000000000000000001091DE000006
+:100B7000000000082C800080000000082D0000000C
+:100B8000000000082D80010500000010BEE20005F5
+:100B9000000000188000FE9D0000000105621400A6
+:100BA00000000010918A000200000008B1620001FC
+:100BB0000000001091DE000000000018000D000091
+:100BC0000000001091D40000000000080600AAAA4E
+:100BD000000000188000FF390000000C298000018F
+:100BE0000000000C1F800001000000082A0000091E
+:100BF000000000080500AAAA000000188000FE9767
+:100C00000000001091D400000000000806005555B7
+:100C1000000000188000FF310000001091A03C028D
+:100C200000000010B1E662070000000B2FDF000299
+:100C3000000000002C310000000000092CB1007FF2
+:100C4000000000082CD90000000000082D00000062
+:100C5000000000082D80010D00000010B1A8000662
+:100C600000000010205F0000000000002C200000A9
+:100C7000000000002CA70000000000082D0000105C
+:100C8000000000082D800108000000188000FF2CE3
+:100C900000000010B1A6001000000010001F0000AE
+:100CA0000000000F0F300007000000000A60000085
+:100CB000000000000AE100000000000F4B62000885
+:100CC000000000090B1600FF000000000D6200008C
+:100CD000000000090D1A00FF00000010073000039B
+:100CE0000000000C0D1A00080000000C0B16000894
+:100CF0000000000F4CE30018000000000C992C00CD
+:100D000000000004CC993400000000080F800000AF
+:100D10000000000C298000010000000033310000B9
+:100D20000000000822000016000000002ADF00007A
+:100D3000000000082A00000C00000010009F0000C6
+:100D4000000000000F2000000000000C1F800001C8
+:100D50000000000805005555000000188000FE6BDB
+:100D60000000001091D40000000000080600AAAAAC
+:100D7000000000188000FF050000000F4722000857
+:100D800000000009070E000F00000008070E000811
+:100D900000000008028000010000000702851C001E
+:100DA00000000008828500010000000002854C0060
+:100DB0000000000742851C0000000003C3AA520087
+:100DC0000000000003B10E00000000074B071C00EC
+:100DD0000000000F0F3000070000000F0A9600030C
+:100DE000000000000A955C00000000004A005A0064
+:100DF000000000000C960A00000000090C99FFFF9B
+:100E0000000000080D00FFFF00000010B196320244
+:100E1000000000080F80000500000010B1A80008C5
+:100E200000000010205F00000000000B2FDF000218
+:100E3000000000002C200000000000002CA7000093
+:100E4000000000082D000010000000082D8001089F
+:100E5000000000188000FEF30000000C2980000153
+:100E600000000010001F00000000000C1F800001A7
+:100E7000000000002ADF0000000000082A00000D2A
+:100E8000000000080500AAAA000000188000FE4526
+:100E90000000001091D40000000000080600555525
+:100EA000000000188000FEDF0000000C2980000117
+:100EB0000000000C1F800001000000082A0000074D
+:100EC0000000000805005555000000188000FE3D98
+:100ED00000000010B18000040000001F03030300A5
+:100EE00000000008050000FF0000001800020000DC
+:100EF000000000002A00000000000010B1D4000033
+:100F00000000001091DE00000000001020530000DF
+:100F100000000010001F00000000000C6BD7000153
+:100F2000000000002F80AA000000000C29800001B2
+:100F3000000000080254000F000000002C400000D8
+:100F4000000000092952003F0000001800040000C2
+:100F50000000001880000010000000188000001140
+:100F6000000000188000004A0000001880000128DE
+:100F700000000018800001270000001880000126F2
+:100F8000000000188000012600000018800000000A
+:100F9000000000188000013F0000001880000122BE
+:100FA000000000188000000B0000001880000145C0
+:100FB000000000188000019A000000188000007BEB
+:100FC00000000018800000F90000001880000109EE
+:100FD000000000002A000000000000188000FFE46C
+:100FE000000000002A0000000000000C2980000022
+:100FF000000000188000FFE1000000002A0000004F
+:10100000000000188000FFDF0000000003820000E5
+:10101000000000188000FFDA000000010C16140028
+:10102000000000008C1814000000001091980003CC
+:10103000000000080C96000200000010B1800003C0
+:10104000000000080C960001000000000C000000E9
+:10105000000000000D1900000000001020560000E4
+:101060000000000C2BD70001000000080F800001D9
+:10107000000000000000000000000010001F000041
+:101080000000000C6BD7000100000010011301F1FB
+:10109000000000180007000000000000050200002A
+:1010A000000000109196342100000010205F000025
+:1010B000000000002C1E0000000000082C8000062C
+:1010C000000000082D000006000000082D8001022D
+:1010D00000000000000000000000001091DE000091
+:1010E000000000000D61000000000018000A000070
+:1010F0000000000005020000000000109196341668
+:1011000000000010205F00000000000009D800006F
+:10111000000000002C1E0000000000082C80010EC2
+:10112000000000082D00000A000000082D800102C8
+:1011300000000000000000000000001091DE000030
+:10114000000000000D620000000000002C130000F1
+:1011500000000018000A0000000000000502000066
+:10116000000000109196340900000010205F00007C
+:10117000000000002C1E0000000000082C8000066B
+:10118000000000082D00006A000000082D80010208
+:1011900000000000000000000000001091DE0000D0
+:1011A000000000000D7A000000000018000A000096
+:1011B000000000002A000000000000000D61000097
+:1011C000000000000362000000000010234200DB6A
+:1011D0000000000002638C000000000026460000B2
+:1011E000000000080204001200000010B906082EDA
+:1011F000000000000F580000000000000A6400001A
+:10120000000000000AE50000000000090B66FFFF77
+:10121000000000000C000000000000000B80000037
+:10122000000000080CC60012000000188000FFCE6D
+:1012300000000010205600000000000C2BD7000119
+:10124000000000080F800003000000000000000004
+:1012500000000010001F00000000000C6BD7000110
+:101260000000000827110012000000006690000036
+:1012700000000008A31B001200000010B198000637
+:1012800000000010001F00000000000C6BD70001E0
+:1012900000000010205600000000000C2BD70001B9
+:1012A000000000080F800004000000082200000376
+:1012B000000000082C80000C000000082D00000C2D
+:1012C00000000010001F00000000000C6BD70001A0
+:1012D00000000000259600000000000C298000009E
+:1012E0000000000006660000000000008661180093
+:1012F000000000090260000F0000000F020400025D
+:1013000000000010B60C08050000000C1FBF000014
+:10131000000000102866000300000008078F00018D
+:101320000000000C336600100000000032140000C2
+:1013300000000000329500000000000573662C00DC
+:101340000000000031E32E00000000082D80001096
+:10135000000000188000FF7500000000230000005E
+:101360000000000925E6FFFF000000082200000B36
+:101370000000000C695200000000000C29800000F1
+:101380000000001028660088000000188000FF6E32
+:10139000000000002A000000000000082C8000402F
+:1013A000000000082D000020000000082D80011C16
+:1013B00000000000000000000000001091DE0000AE
+:1013C0000000000F42EA001000000010004F00046F
+:1013D00000000010B7469200000000080249001209
+:1013E00000000010B5840A00000000000D6100003C
+:1013F00000000010BA66346A00000008830500127D
+:1014000000000010004F000200000000034900002F
+:101410000000000183068C000000000083C60C0061
+:1014200000000010B1870011000000000B6E0000EA
+:1014300000000010BEE90005000000188000FF5504
+:10144000000000010569140000000010918A0002EC
+:1014500000000008B4E9000100000010B1E92C5DB3
+:101460000000000086692C0000000000020000005F
+:101470000000000902EAFFFF00000010000C00025B
+:101480000000000002040A000000000F460C0001EA
+:101490000000000F0285000100000010918C01FC8B
+:1014A00000000010B7040E54000000000F400000C0
+:1014B000000000000D610000000000000A64000050
+:1014C000000000000AE50000000000090B66FFFFB5
+:1014D000000000000C000000000000000B80000075
+:1014E000000000080C8600120000001020560000CA
+:1014F0000000000C2BD70001000000080F80000343
+:101500000000000C2952000000000010001F000025
+:101510000000000C6BD7000100000008271100122A
+:101520000000000066900000000000002646000059
+:10153000000000002306000000000010B198000920
+:1015400000000010001F00000000000C6BD700011D
+:1015500000000010205600000000000C2BD70001F6
+:10156000000000080F8000040000000000000000E0
+:1015700000000010001F00000000000C6BD70001ED
+:10158000000000003214000000000000329500004E
+:101590000000000031E32E000000000573662C00FF
+:1015A000000000002596000000000010B187002117
+:1015B0000000000C298000000000000F0F6B0007E6
+:1015C000000000000D690000000000000A6C00002F
+:1015D000000000000AED0000000000000B6E00009B
+:1015E000000000000B800000000000000C870000DD
+:1015F000000000188000FF1E000000010C161400FF
+:10160000000000008C181400000000080C96000177
+:101610000000001091980002000000080C990001E1
+:10162000000000000D190000000000000C00000088
+:1016300000000010205600000000000C2BD7000115
+:10164000000000080F80000100000010205300007F
+:101650000000000C6952000100000010001F000093
+:101660000000000C6BD700010000000022C58C00B8
+:1016700000000000231200000000000027110000FD
+:10168000000000002690000000000010B8170E03B4
+:101690000000000C29800000000000188000FFEB13
+:1016A0000000000082970E0000000000A3120A0054
+:1016B000000000082200001A000000082C80000C26
+:1016C000000000082D00000C000000082D80001014
+:1016D00000000010001F00000000000C6BD700018C
+:1016E000000000000D6E000000000003E7CF340092
+:1016F0000000000C298000000000001091DE0000B6
+:1017000000000010B1870007000000003614000040
+:1017100000000000369500000000000037160000B1
+:10172000000000082C800050000000082D00003050
+:10173000000000082D80000C000000188000FEF85A
+:10174000000000002646000000000000230000000A
+:101750000000000925E6FFFF000000000B6E0000FE
+:1017600000000003E7CF2C00000000082200001B4F
+:101770000000000C695200000000000C29800000ED
+:10178000000000188000FEEF000000002A000000AA
+:10179000000000100866000500000000066600005A
+:1017A000000000008661180000000009026000F0DF
+:1017B00000000010B60C0802000000188000FEE8CF
+:1017C000000000000682000000000010B18F000041
+:1017D00000000008878F00010000000C73660010F5
+:1017E000000000082C800018000000082D000018E0
+:1017F000000000082D8000020000000C5FBF000008
+:101800000000001091DE000000000018000D000034
+:10181000000000002A00000000000010286601F50A
+:10182000000000082C800003000000082D000003C9
+:10183000000000093060FFF0000000082D8000016A
+:101840000000000C298000000000001091DE000064
+:10185000000000082C80001A000000082D00001A6B
+:101860000000000573660000000000082D800002E3
+:1018700000000000318000000000001091DE000038
+:10188000000000082C80000C000000082D00000C57
+:10189000000000082D800004000000188000FECC2D
+:1018A0000000001800020000000000188000FECABE
+:1018B000000000002A00000000000010001F0000CF
+:1018C0000000000C6BD70001000000000F0080003A
+:1018D000000000080F800007000000188000001BB7
+:1018E00000000000280A00000000000005020000BF
+:1018F000000000082200000900000000290000008C
+:101900000000000F6568001000000003F66C9400F2
+:1019100000000010B972A0040000000C73E7001969
+:101920000000000C21420004000000003CF8000010
+:101930000000000C2980000000000010205300006F
+:1019400000000008220000080000000C61420004B2
+:1019500000000018000A000000000000050200005E
+:101960000000000C61420000000000100142000372
+:101970000000000C33E7001D0000000C6142000273
+:1019800000000018000A0000000000002A0000000B
+:1019900000000010001F00000000000C6BD70001C9
+:1019A0000000000F0F470007000000080F8000082C
+:1019B0000000000C2980000000000010001F000043
+:1019C0000000000C6BD70001000000188000FEA68C
+:1019D0000000000033510000000000002A00000059
+:1019E00000000010B1C600290000000F0F500007D2
+:1019F000000000000A600000000000000AE1000092
+:101A00000000000F4B620008000000090B1600FFE9
+:101A10000000000F4C620010000000000D6200008A
+:101A2000000000090D1A00FF00000010075000031D
+:101A30000000000C0D1A00080000000C0B16000836
+:101A4000000000000CC60000000000000B80000039
+:101A50000000000006980000000000102056000062
+:101A60000000000C2BD70001000000080F800003CD
+:101A70000000001006C200040000000C2900000253
+:101A800000000010264200020000000C2952000352
+:101A9000000000082200000100000010001F0000EC
+:101AA0000000000C6BD7000100000000231B0000A9
+:101AB0000000000027111A000000000066900000DE
+:101AC0000000000C2952000000000010B197320CF9
+:101AD0000000000C298000000000000006980000B3
+:101AE00000000010205300000000000C29520003E9
+:101AF0000000000022C58C0000000010001F000044
+:101B00000000000C6BD70001000000102056000000
+:101B10000000000C2BD70001000000080F8000031C
+:101B2000000000188000FFEF00000010B1C8001393
+:101B300000000010B1C600030000000C2980000066
+:101B400000000010205300000000000C295200008B
+:101B50000000000C295200030000001006C2000221
+:101B60000000000C295200020000000022C58C0079
+:101B700000000000276500000000000026E40000CF
+:101B8000000000082200001600000010B1C600038B
+:101B9000000000002348000000000010B180000594
+:101BA00000000000234800000000000C2980000015
+:101BB0000000000F0F500007000000188000001206
+:101BC00000000008220000160000000C2980000020
+:101BD00000000000301400000000000030950000FC
+:101BE0000000001007500003000000090B1600FF62
+:101BF000000000090D1A00FF0000000F3116000858
+:101C0000000000003162340000000003F162300087
+:101C100000000010205F0000000000002C510000B8
+:101C2000000000092CD1007F000000082CD9000022
+:101C3000000000082D000000000000082D80000CAE
+:101C400000000000000000000000001091DE000015
+:101C50000000001005C20005000000080F8000070A
+:101C6000000000003300000000000010001F000012
+:101C70000000000C6BD70001000000188000FE502F
+:101C8000000000002A0000000000000F0F500007B5
+:101C900000000010B1C600300000000F47420008ED
+:101CA00000000009070E000F00000008070E0008E2
+:101CB00000000010001F00000000000C6BD70001A6
+:101CC00000000008090000010000000709121C00C4
+:101CD00000000003CBCA9200000000000B97A20096
+:101CE0000000000742171C00000000000B04000069
+:101CF0000000000F0A840003000000000A959C0009
+:101D0000000000004A009A00000000088212000152
+:101D1000000000010C170800000000000C978C0068
+:101D20000000000002180000000000080D00FFFF86
+:101D3000000000080F8000060000000C29000000D1
+:101D40000000001006C200040000000C295200022E
+:101D500000000010264200020000000C295200037F
+:101D6000000000082200000100000010001F000019
+:101D70000000000C6BD7000100000010B197320D7D
+:101D800000000000231B00000000000027110800D5
+:101D900000000000669000000000000C2980000098
+:101DA0000000000002180000000000102053000096
+:101DB0000000000C295200030000000022C536007C
+:101DC00000000010001F00000000000C6BD7000195
+:101DD000000000080F800006000000188000FFF2DD
+:101DE00000000000231B0000000000002711080075
+:101DF000000000006690000000000010B1C8000B59
+:101E00000000000C2980000000000010205300009A
+:101E10000000000C295200000000000C29520003B1
+:101E20000000001006C200020000000C295200024F
+:101E30000000000022C58C000000000027650000A3
+:101E40000000000026E4000000000000234800001D
+:101E500000000008220000170000000C298000008C
+:101E600000000010001F00000000000C6BD70001F4
+:081E7000000000188000FE11C3
+:00000001FF
+/*
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004 - 2009 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
diff --git a/firmware/bnx2x-e1-4.8.53.0.fw.ihex b/firmware/bnx2x-e1-4.8.53.0.fw.ihex
deleted file mode 100644
index f1edb1e..0000000
--- a/firmware/bnx2x-e1-4.8.53.0.fw.ihex
+++ /dev/null
@@ -1,10364 +0,0 @@
-:10000000000028600000006000000630000028C8E2
-:100010000000160800002F000000009400004510AA
-:10002000000073C8000045A8000000C40000B978B3
-:100030000000A4680000BA400000007400015EB037
-:100040000000559000015F28000000B80001B4C016
-:100050000000D1F80001B580000000040002878094
-:10006000020400480000000F020400540000004594
-:1000700002040058000000840204005C0000000636
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000060400CC0000000418
-:10010000020400DC00100000020400E012140000F1
-:10011000020400E422140000020400E8321400008B
-:10012000060400EC000000040104012400000000AB
-:1001300001040128000000000104012C000000005F
-:10014000010401300000000002040004000000FF70
-:1001500002040008000000FF0204000C000000FF81
-:1001600002040010000000FF02040014000000FF61
-:1001700002040018000000FF0204001C000000FF41
-:1001800002040020000000FF020400240000003EE2
-:1001900002040028000000000204002C0000003FC0
-:1001A000020400300000003F020400340000003F61
-:1001B00002040038000000000204003C0000003F80
-:1001C000020400400000003F020400440000003F21
-:1001D00002042008000004110204200C00000400A6
-:1001E000020420100000040402042014000004197A
-:1001F0000204201C0000FFFF020420200000FFFF7B
-:10020000020420240000FFFF020420280000FFFF5A
-:1002100006042038000000020204204000000034E0
-:100220000204204400000035060420480000007C41
-:100230000204223807FFFFFF0204223C0000003FB7
-:100240000204224007FFFFFF020422440000000FC7
-:1002500001042248000000000104224C00000000BC
-:10026000010422500000000001042254000000009C
-:1002700001042258000000000104225C000000007C
-:10028000010422600000000001042264000000005C
-:1002900001042268000000000104226C000000003C
-:1002A000010422700000000001042274000000001C
-:1002B00001042278000000000104227C00000000FC
-:1002C000020424BC000000010C042000000003E82C
-:1002D0000A042000000000010B0420000000000AB6
-:1002E0000205004400000020020500480000003222
-:1002F000020500900215002002050094021500205E
-:1003000002050098000000300205009C0810000063
-:10031000020500A000000033020500A40000003028
-:10032000020500A800000031020500AC0000000238
-:10033000020500B000000005020500B40000000640
-:10034000020500B800000002020500BC0000000227
-:10035000020500C000000000020500C40000000506
-:10036000020500C800000002020500CC00000002E7
-:10037000020500D000000002020500D400000001C8
-:1003800002050114000000010205011C000000012B
-:100390000205012000000002020502040000000125
-:1003A0000205020C0000004002050210000000409F
-:1003B0000205021C000000200205022000000013BC
-:1003C0000205022400000020060502400000000A89
-:1003D0000405028000200000020500500000000714
-:1003E0000205005400000007020500580000000844
-:1003F0000205005C00000008060500600000000423
-:10040000020500D800000006020500E00000000D13
-:10041000020500E40000002D020500E800000007CE
-:10042000020500EC00000027020500F000000007B4
-:10043000020500F400000027020500F80000000794
-:10044000020500FC00000027020500040000000176
-:1004500002050008000000010205000C0000000178
-:100460000205001000000001020500140000000158
-:1004700002050018000000010205001C0000000138
-:100480000205002000000001020500240000000118
-:1004900002050028000000010205002C00000001F8
-:1004A00002050030000000010205003400000001D8
-:1004B00002050038000000010205003C00000001B8
-:1004C00002050040000000010406100002000020A8
-:1004D000020600DC00000001010600D80000000058
-:1004E0000406020000030220020600DC00000000F7
-:1004F00002060068000000B802060078000001143F
-:10050000010600B800000000010600C8000000005D
-:100510000206006C000000B80206007C0000011416
-:10052000010600BC00000000010600CC0000000035
-:100530000718040000930000081807600014022345
-:10054000071C0000324F0000071C800033250C946C
-:10055000071D00000E4D195E081D1E005C4002259F
-:100560000118000000000000011800040000000055
-:1005700001180008000000000118000C0000000035
-:100580000118001000000000011800140000000015
-:1005900002180020000000010218002400000002E0
-:1005A00002180028000000030218002C00000000C0
-:1005B000021800300000000402180034000000019E
-:1005C00002180038000000000218003C0000000182
-:1005D000021800400000000402180044000000005F
-:1005E00002180048000000010218004C000000033F
-:1005F0000218005000000000021800540000000122
-:1006000002180058000000040218005C00000000FE
-:1006100002180060000000010218006400000003DE
-:1006200002180068000000000218006C00000001C1
-:10063000021800700000000402180074000000009E
-:1006400002180078000000040218007C000000037B
-:100650000618008000000002021800A400003FFFFE
-:10066000021800A8000003FF021802240000000086
-:1006700002180234000000000218024C00000000C2
-:10068000021802E4000000FF061810000000040039
-:10069000021B8BC000000001021B80000000003420
-:1006A000021B804000000018021B80800000000C2C
-:1006B000021B80C0000000200C1B83000007A1204B
-:1006C0000A1B8300000001380B1B83000000138805
-:1006D000021B83C0000001F4061A2000000000B2D3
-:1006E000061A23C8000000C1041A26CC0001022704
-:1006F000061A1020000000C8061A100000000002B0
-:10070000061A1C1800000004061A1C100000000243
-:10071000061A080000000002061A0808000000027D
-:10072000061A081000000004041A1FB00004022872
-:10073000041A4CB00008022C061A22C8000000203F
-:10074000061A40000000016C021A4B600000000015
-:10075000061A14000000000A061A145000000006D1
-:10076000061A150000000002041A150800050234DC
-:10077000061A151C00000007061A1570000000126A
-:10078000061A09C00000004C061A0800000000020A
-:10079000061A08200000000E041A1FB000020239D9
-:1007A000061A290800000002061A2348000000204B
-:1007B000061A45B00000016C021A4B6400000000EC
-:1007C000061A14280000000A061A14680000000621
-:1007D000061A153800000002041A15400005023BF5
-:1007E000061A155400000007061A15B8000000127A
-:1007F000061A0AF00000004C061A08080000000261
-:10080000061A08580000000E041A1FB80002024021
-:10081000061A2910000000020200A2800000000158
-:100820000200A294071D29110200A29800000000F6
-:100830000200A29C009C04240200A2A00000000070
-:100840000200A2A4000002090200A4FCFF000000B4
-:10085000020100B400000001020100B80000000124
-:10086000020100DC000000010201010000000001A3
-:1008700002010104000000010201007C00300000C0
-:1008800002010084000000280201008C000000002A
-:1008900002010130000000040201025C00000001BE
-:1008A000020103280000000002010554000000308E
-:1008B000020100C400000001020100CC00000001A0
-:1008C000020100F800000001020100F00000000138
-:1008D00002010080003000000201008800000028B2
-:1008E0000201009000000000020101340000000439
-:1008F000020102DC000000010201032C00000000E4
-:100900000201056400000030020100C8000000017F
-:10091000020100D000000001020100FC0000000103
-:10092000020100F400000001020C10000000002091
-:10093000020C200800000A11020C200C00000A0022
-:10094000020C201000000A04020C201C0000FFFF13
-:10095000020C20200000FFFF020C20240000FFFFFB
-:10096000020C20280000FFFF020C2038000000C607
-:10097000020C203C00000000020C2040000000346B
-:10098000020C204400000035060C20480000001C2A
-:10099000020C20B800000001060C20BC0000005F23
-:1009A000020C223807FFFFFF020C223C0000003F30
-:1009B000020C224007FFFFFF020C22440000000F40
-:1009C000010C224800000000010C224C0000000035
-:1009D000010C225000000000010C22540000000015
-:1009E000010C225800000000010C225C00000000F5
-:1009F000010C226000000000010C226400000000D5
-:100A0000010C226800000000010C226C00000000B4
-:100A1000010C227000000000010C22740000000094
-:100A2000010C227800000000010C227C0000000074
-:100A3000020C24BC000000010C0C2000000003E8A4
-:100A40000A0C2000000000010B0C20000000000A2E
-:100A5000020C400800000A11020C400C00000A00C1
-:100A6000020C401000000A04020C401400000A218D
-:100A7000020C401C0000FFFF020C40200000FFFFA2
-:100A8000020C40240000FFFF020C40280000FFFF82
-:100A9000020C403800000046020C403C00000005FB
-:100AA000020C404000000034020C404400000035BD
-:100AB000060C40480000005C020C41B80000000138
-:100AC000060C41BC0000001F020C423807FFFFFF6C
-:100AD000020C423C0000003F020C424007FFFFFFB7
-:100AE000020C42440000000F010C424800000000CC
-:100AF000010C424C00000000010C425000000000BC
-:100B0000010C425400000000010C4258000000009B
-:100B1000010C425C00000000010C4260000000007B
-:100B2000010C426400000000010C4268000000005B
-:100B3000010C426C00000000010C4270000000003B
-:100B4000010C427400000000010C4278000000001B
-:100B5000010C427C00000000010C428000000000FB
-:100B6000020C44C0000000010C0C4000000003E82F
-:100B70000A0C4000000000010B0C40000000000ABD
-:100B8000020D004400000032020D008C021500200E
-:100B9000020D009002150020020D009408100000C4
-:100BA000020D009800000033020D009C00000002BE
-:100BB000020D00A000000000020D00A400000005CE
-:100BC000020D00A800000005060D00AC00000002A8
-:100BD000020D00B400000002020D00B80000000386
-:100BE000020D00BC00000002020D00C00000000168
-:100BF000020D00C800000002020D00CC000000023F
-:100C0000020D010800000001020D015C000000015E
-:100C1000020D016400000001020D016800000002E5
-:100C2000020D020400000001020D020C0000002071
-:100C3000020D021000000040020D021400000040EE
-:100C4000020D022000000003020D02240000001823
-:100C5000060D028000000012040D03000024024271
-:100C6000020D004C00000001020D005000000002C7
-:100C7000020D005400000008020D0058000000089A
-:100C8000060D005C00000004020D00C4000000041A
-:100C9000020D011400000009020D011800000029D6
-:100CA000020D011C0000000A020D01200000002AB4
-:100CB000020D012400000007020D0128000000279A
-:100CC000020D012C00000007020D0130000000277A
-:100CD000020D01340000000C020D01380000002C50
-:100CE000020D013C0000000C020D01400000002C30
-:100CF000020D01440000000C020D01480000002C10
-:100D0000020D000400000001020D000800000001B7
-:100D1000020D000C00000001020D00100000000197
-:100D2000020D001400000001020D00180000000177
-:100D3000020D001C00000001020D00200000000157
-:100D4000020D002400000001020D00280000000137
-:100D5000020D002C00000001020D00300000000117
-:100D6000020D003400000001020D003800000001F7
-:100D7000020D003C00000001020E004C0000003299
-:100D8000020E009402150020020E009802150020A9
-:100D9000020E009C00000030020E00A008100000AF
-:100DA000020E00A400000033020E00A80000003074
-:100DB000020E00AC00000031020E00B00000000284
-:100DC000020E00B400000004020E00B80000000093
-:100DD000020E00BC00000002020E00C00000000273
-:100DE000020E00C400000000020E00C80000000255
-:100DF000020E00CC00000007020E00D0000000022E
-:100E0000020E00D400000002020E00D80000000113
-:100E1000020E00E400000001020E01440000000187
-:100E2000020E014C00000001020E01500000000201
-:100E3000020E020400000001020E020C000000403D
-:100E4000020E021000000040020E021C000000040E
-:100E5000020E022000000020020E02240000000EFC
-:100E6000020E02280000001B060E03000000001204
-:100E7000040E0280001B0266020E005400000010E7
-:100E8000020E005800000007020E005C0000000F78
-:100E9000020E006000000010060E00640000000456
-:100EA000020E00DC00000003020E01100000000F23
-:100EB000020E01140000002F020E01180000000EA7
-:100EC000020E011C0000002E020E000400000001B2
-:100ED000020E000800000001020E000C00000001DC
-:100EE000020E001000000001020E001400000001BC
-:100EF000020E001800000001020E001C000000019C
-:100F0000020E002000000001020E0024000000017B
-:100F1000020E002800000001020E002C000000015B
-:100F2000020E003000000001020E0034000000013B
-:100F3000020E003800000001020E003C000000011B
-:100F4000020E004000000001020E004400000001FB
-:100F50000730040000C30000083007680013028156
-:100F600007340000314C00000734800035EF0C548A
-:100F700007350000361319D00735800007112755B3
-:100F800008358EE04E24028301300000000000008E
-:100F900001300004000000000130000800000000E3
-:100FA0000130000C000000000130001000000000C3
-:100FB0000130001400000000023000200000000199
-:100FC000023000240000000202300028000000036C
-:100FD0000230002C0000000002300030000000044D
-:100FE0000230003400000001023000380000000030
-:100FF0000230003C0000000102300040000000040C
-:1010000002300044000000000230004800000001EF
-:101010000230004C000000030230005000000000CD
-:1010200002300054000000010230005800000004AB
-:101030000230005C0000000002300060000000018F
-:10104000023000640000000302300068000000006D
-:101050000230006C0000000102300070000000044B
-:10106000023000740000000002300078000000042C
-:101070000230007C00000003063000800000000207
-:10108000023000A400003FFF023000A8000003FF70
-:101090000230022400000000023002340000000090
-:1010A0000230024C00000000023002E40000FFFFAA
-:1010B000063020000000080002338BC00000000151
-:1010C000023380000000001A023380400000004E0E
-:1010D0000233808000000010023380C00000002036
-:1010E0000C3383000007A1200A338300000001387D
-:1010F0000B33830000001388023383C0000001F427
-:101100000C3383801DCD65000A3383800004C4B492
-:101110000B338380004C4B4006325000000000C26D
-:1011200006321020000000C8063210000000000245
-:101130000632464000000040063257F0000000042E
-:10114000063257D800000005043257EC0001028532
-:1011500006321C60000000200432283000020286A3
-:10116000023308000100000004330C000010028864
-:10117000023308000000000004330C400010029805
-:1011800006321400000000A0063219000000001012
-:10119000063219800000003006324740000000B4DB
-:1011A00002321D900000000006321B4000000004C7
-:1011B00006321B6000000020063253180000009821
-:1011C00006321680000000A0063219400000001010
-:1011D00006321A400000003006324A10000000B407
-:1011E00002321D940000000006321B500000000473
-:1011F00006321BE0000000200632557800000098FF
-:10120000072004000071000008200780001002A8D9
-:1012100007240000322900000724800023630C8B80
-:101220000824C930654002AA012000000000000027
-:101230000120000400000000012000080000000060
-:101240000120000C00000000012000100000000040
-:101250000120001400000000022000200000000116
-:1012600002200024000000020220002800000003E9
-:101270000220002C000000000220003000000004CA
-:1012800002200034000000010220003800000000AD
-:101290000220003C00000001022000400000000489
-:1012A000022000440000000002200048000000016D
-:1012B0000220004C0000000302200050000000004B
-:1012C0000220005400000001022000580000000429
-:1012D0000220005C0000000002200060000000010D
-:1012E00002200064000000030220006800000000EB
-:1012F0000220006C000000010220007000000004C9
-:1013000002200074000000000220007800000004A9
-:101310000220007C00000003062000800000000284
-:10132000022000A400003FFF022000A8000003FFED
-:10133000022002240000000002200234000000000D
-:101340000220024C00000000022002E40000FFFF27
-:10135000062020000000080002238BC000000001CE
-:1013600002238000000000100223804000000012D1
-:101370000223808000000030022380C00000000EA5
-:10138000022383C0000001F4062250000000004246
-:1013900006221020000000C80622100000000002F3
-:1013A00006222000000000C00622307000000080ED
-:1013B0000622428000000004062225C000000240F0
-:1013C00004222EC8000802AC02230800013FFFFFE0
-:1013D00004230C00001002B40223080000000000E7
-:1013E00004230C40001002C406221400000000A0D8
-:1013F00006221900000000100622198000000030AB
-:101400000222511800000000062223000000000EF6
-:1014100006223040000000060622241000000030A2
-:1014200006221680000000A00622194000000010CD
-:1014300006221A40000000300222511C0000000069
-:10144000062223380000000E062230580000000655
-:10145000062224D0000000300216100000000020F8
-:1014600002170008000000020217002C0000000311
-:101470000217003C000000040217004400000008AE
-:1014800002170048000000020217004C0000009004
-:1014900002170050000000900217005400800090D6
-:1014A0000217005808140000021700600000008AAC
-:1014B000021700640000008002170068000000901E
-:1014C0000217006C00000080021700700000000688
-:1014D00002170078000007D00217007C0000076C9C
-:1014E00002170038007C1004021700040000000FEF
-:1014F0000616402400000002021640700000001C86
-:10150000021642080000000102164210000000010D
-:1015100002164220000000010216422800000001CD
-:10152000021642300000000102164238000000019D
-:1015300002164260000000010C16401C0003D0900F
-:101540000A16401C0000009C0B16401C000009C439
-:101550000216403000000008021640340000000C63
-:10156000021640380000001002164044000000201F
-:101570000216400000000001021640D800000001E1
-:1015800002164008000000010216400C0000000195
-:101590000216401000000001021642400000000048
-:1015A00002164248000000000616427000000002C9
-:1015B00002164250000000000216425800000000CF
-:1015C00006164280000000020216600800000614A1
-:1015D0000216600C000006000216601000000604EF
-:1015E0000216601C0000FFFF021660200000FFFFD3
-:1015F000021660240000FFFF021660280000FFFFB3
-:1016000002166038000000200216603C0000002036
-:1016100002166040000000340216604400000035ED
-:1016200002166048000000230216604C00000024EF
-:1016300002166050000000250216605400000026CB
-:1016400002166058000000270216605C00000029A6
-:10165000021660600000002A021660640000002B81
-:10166000021660680000002C0216606C0000002D5D
-:101670000616607000000052021661B800000001FA
-:10168000061661BC0000001F0216623807FFFFFF4C
-:101690000216623C0000003F0216624007FFFFFF97
-:1016A000021662440000000F0116624800000000AC
-:1016B0000116624C0000000001166250000000009C
-:1016C000011662540000000001166258000000007C
-:1016D0000116625C0000000001166260000000005C
-:1016E000011662640000000001166268000000003C
-:1016F0000116626C0000000001166270000000001C
-:1017000001166274000000000116627800000000FB
-:101710000116627C00000000021664BC000000019B
-:101720000C166000000003E80A16600000000001CB
-:101730000B1660000000000A021680400000000640
-:101740000216804400000005021680480000000ACE
-:101750000216804C000000050216805400000002B2
-:10176000021680CC00000004021680D000000004A5
-:10177000021680D400000004021680D80000000485
-:10178000021680DC00000004021680E00000000465
-:10179000021680E400000004021680E80000000445
-:1017A0000216880400000004021680300000007C4D
-:1017B000021680340000003D021680380000003F11
-:1017C0000216803C0000009C021680F0000000071A
-:1017D000061680F4000000050216880C01010101C4
-:1017E00002168108000000000216810C00000004AF
-:1017F000021681100000000402168114000000028D
-:101800000216881008012004021681180000000545
-:101810000216811C00000005021681200000000550
-:1018200002168124000000050216882C20081001F1
-:1018300002168128000000080216812C0000000614
-:1018400002168130000000070216813400000000FB
-:1018500002168830010101200616813800000004BC
-:1018600002168834010101010616814800000004B7
-:101870000216883801010101061681580000000493
-:101880000216883C01010101061681680000000370
-:101890000216817400000001021688400101010156
-:1018A00002168178000000010216817C0000000110
-:1018B00002168180000000010216818400000001F0
-:1018C000021688440101010102168188000000010E
-:1018D0000216818C000000040216819000000004B2
-:1018E00002168194000000020216884808012004B4
-:1018F00002168198000000050216819C0000000578
-:10190000021681A000000005021681A40000000557
-:101910000216881420081001021681A80000000891
-:10192000021681AC00000006021681B0000000071C
-:10193000021681B40000000102168818010101207E
-:10194000021681B800000001021681BC00000001EF
-:10195000021681C000000001021681C400000001CF
-:101960000216881C01010101021681C80000000155
-:10197000021681CC00000001021681D00000000197
-:10198000021681D400000001021688200101010125
-:10199000021681D800000001021681DC000000015F
-:1019A000021681E000000001021681E4000000013F
-:1019B0000216882401010101021681E800000001DD
-:1019C000021681EC00000001021681F00000000107
-:1019D000021688280101010102168240FFFF003F24
-:1019E00006168244000000020216824CFFFF003FF0
-:1019F000021682500000010002168254000001000D
-:101A0000061682580000000202168260000000C024
-:101A100002168264000000C00216826800001E00E8
-:101A20000216826C00001E00021682700000400048
-:101A300002168274000040000216827800008000C6
-:101A40000216827C000080000216828000002000C6
-:101A5000021682840000200006168288000000071B
-:101A6000021682A400000001061682A80000000AE7
-:101A7000021681F400000C08021681F800000040F4
-:101A8000021681FC00000100021682000000002006
-:101A9000021682040000001702168208000000806F
-:101AA0000216820C000002000216821000000000E4
-:101AB00002168218FFFF01FF02168214FFFF01FFCA
-:101AC0000216823C00000013021680900000013FC5
-:101AD0000216806000000140021680640000014090
-:101AE000061680680000000202168070000000C028
-:101AF00006168074000000070216809C0000004853
-:101B0000021680A000000048061680A40000000213
-:101B1000021680AC00000048061680B000000007E6
-:101B2000021682380000800002168234000025E48C
-:101B30000216809400007FFF02168220000000073A
-:101B40000216821C00000007021682280000000016
-:101B500002168224FFFFFFFF021682300000000001
-:101B60000216822CFFFFFFFF021680EC000000FF30
-:101B700002140000000000010214000C000000012B
-:101B800002140040000000010214004400007FFF26
-:101B90000214000C0000000002140000000000000D
-:101BA0000214006C00000000021400040000000198
-:101BB00002140030000000010214000400000000C4
-:101BC0000214005C00000000021400080000000184
-:101BD000021400340000000102140008000000009C
-:101BE00002140060000000000202005800000032F1
-:101BF000020200A003150020020200A40315002029
-:101C0000020200A801000030020200AC081000002F
-:101C1000020200B000000033020200B400000030F5
-:101C2000020200B800000031020200BC0000000304
-:101C3000020200C000000006020200C4000000030F
-:101C4000020200C800000003020200CC00000002F3
-:101C5000020200D000000000020200D400000002D6
-:101C6000020200DC00000000020200E000000006AA
-:101C7000020200E400000004020200E8000000028A
-:101C8000020200EC00000002020200F0000000016D
-:101C9000020200FC00000006020201200000000019
-:101CA0000202013400000002020201B00000000143
-:101CB0000202020C000000010202021400000001F6
-:101CC00002020218000000020202040400000001E7
-:101CD0000202040C00000040020204100000004058
-:101CE0000202041C00000004020204200000002084
-:101CF0000202042400000002020204280000001F67
-:101D0000060205000000001204020480001F02D435
-:101D1000020200600000000F0202006400000007E1
-:101D2000020200680000000B0202006C0000000EBE
-:101D30000602007000000004020200F4000000042B
-:101D4000020200040000000102020008000000017D
-:101D50000202000C0000000102020010000000015D
-:101D6000020200140000000102020018000000013D
-:101D70000202001C0000000102020020000000011D
-:101D800002020024000000010202002800000001FD
-:101D90000202002C000000010202003000000001DD
-:101DA00002020034000000010202003800000001BD
-:101DB0000202003C0000000102020040000000019D
-:101DC000020200440000000102020048000000017D
-:101DD0000202004C0000000102020050000000015D
-:101DE00002020108000000C80202011800000002FF
-:101DF000020201C400000000020201CC0000000049
-:101E0000020201D400000002020201DC0000000214
-:101E1000020201E4000000FF020201EC000000FFEA
-:101E20000202010C000000C80202011C00000002B6
-:101E3000020201C800000000020201D00000000000
-:101E4000020201D800000002020201E000000002CC
-:101E5000020201E8000000FF020201F0000000FFA2
-:101E60000728040000B5000008280768001302F3E3
-:101E7000072C000033660000072C800038B30CDA12
-:101E8000072D00003BB11B07072D80002A2629F4EF
-:101E9000082DD6C0452802F50128000000000000EA
-:101EA00001280004000000000128000800000000D4
-:101EB0000128000C000000000128001000000000B4
-:101EC000012800140000000002280020000000018A
-:101ED000022800240000000202280028000000035D
-:101EE0000228002C0000000002280030000000043E
-:101EF0000228003400000001022800380000000021
-:101F00000228003C000000010228004000000004FC
-:101F100002280044000000000228004800000001E0
-:101F20000228004C000000030228005000000000BE
-:101F3000022800540000000102280058000000049C
-:101F40000228005C00000000022800600000000180
-:101F5000022800640000000302280068000000005E
-:101F60000228006C0000000102280070000000043C
-:101F7000022800740000000002280078000000041D
-:101F80000228007C000000030628008000000002F8
-:101F9000022800A400003FFF022800A8000003FF61
-:101FA0000228022400000000022802340000000081
-:101FB0000228024C00000000022802E40000FFFF9B
-:101FC0000628200000000800022B8BC00000000142
-:101FD000022B800000000000022B8040000000184F
-:101FE000022B80800000000C022B80C000000066E5
-:101FF0000C2B83000007A1200A2B8300000001386E
-:102000000B2B830000001388022B83C0000001F417
-:102010000C2B8340000001F40A2B834000000000D9
-:102020000B2B8340000000050A2B83800004C4B4FE
-:102030000C2B83801DCD65000B2B8380004C4B4007
-:10204000062A3D6000000004042A3D70000202F7E9
-:10205000062A300000000048062A1020000000C8B0
-:10206000062A100000000002062A31280000008E17
-:10207000022A336800000000042A3370000202F9CB
-:10208000042A3B90000402FB042A3E20000202FFC7
-:10209000022A151800000001022A18300000000072
-:1020A000022A183800000000042A18200002030148
-:1020B000062A4AC000000002062A4B000000000465
-:1020C000042A1F4800020303022B0800000000003E
-:1020D000042B0C0000100305022B08000100000077
-:1020E000042B0C4000080315022B0800020000001E
-:1020F000042B0C600008031D062A3BA000000014FE
-:10210000062A3C4000000024062A14000000000AB1
-:10211000062A145000000006062A3378000000FC4E
-:10212000022A3B5800000000042A3D7800020325E3
-:10213000042A3D8800100327022A15000000000031
-:10214000022A150800000001062A502000000002A3
-:10215000062A503000000002062A5000000000024B
-:10216000062A501000000002022A50400000000021
-:10217000062A50480000000E022A50B80000000154
-:10218000042A4AC800020337062A4B100000004206
-:10219000062A4D2000000004062A3BF0000000142F
-:1021A000062A3CD000000024062A14280000000A59
-:1021B000062A146800000006062A3768000000FCA2
-:1021C000022A3B5C00000000042A3D800002033923
-:1021D000042A3DC80010033B022A15040000000039
-:1021E000022A150C00000001062A502800000002F7
-:1021F000062A503800000002062A5008000000029B
-:10220000062A501800000002022A50440000000074
-:10221000062A50800000000E022A50BC0000000177
-:10222000042A4AD00002034B062A4C180000004240
-:10223000062A4D30000000040210100800000001C2
-:10224000021010000003D000021010040000003D36
-:10225000091018000200034D091011000020054D5F
-:102260000610118000000002091011880006056D9B
-:10227000061011A00000001806102400000000E065
-:102280000210201C000000000210202000000001AD
-:10229000021020C000000001021020040000000114
-:1022A000021020080000000109103C000005057321
-:1022B00009103C2000050578091038000005057D4F
-:1022C00002104028000000100210404400003FFFB0
-:1022D0000210405800280000021040840084924AF6
-:1022E0000210405800000000061080680000000442
-:1022F00002108000000010800610802800000002FC
-:102300000210803800000010021080400000FFFF23
-:10231000021080440000FFFF021080500000000007
-:102320000210810000000000061081200000000261
-:1023300002108008000002B50210801000000000AA
-:10234000061082000000004A021081080001FFFF11
-:1023500006108140000000020210800000001A8078
-:102360000610900000000024061091200000004A92
-:10237000061093700000004A061095C00000004A45
-:10238000021080040000108006108030000000025F
-:102390000210803C00000010021080480000FFFF87
-:1023A0000210804C0000FFFF02108054000000006B
-:1023B00002108104000000000610812800000002C5
-:1023C0000210800C000002B5021080140000000012
-:1023D000061084000000004A0210810C0001FFFF7B
-:1023E00006108148000000020210800400001A80DC
-:1023F0000610909000000024061092480000004A49
-:10240000061094980000004A061096E80000004A62
-:102410000212049000E383400212051400003C10F5
-:1024200002120494FFFFFFFF02120498FFFFFFFF58
-:102430000212049CFFFFFFFF021204A0FFFFFFFF38
-:10244000021204A4FFFFFFFF021204A8FFFFFFFF18
-:10245000021204ACFFFFFFFF021204B0FFFFFFFFF8
-:10246000021204B8FFFFFFFF021204BCFFFFFFFFD0
-:10247000021204C0FFFFFFFF021204C4FFFFFFFFB0
-:10248000021204C8FFFFFFFF021204CCFFFFFFFF90
-:10249000021204D0FFFFFFFF021204DCFFFFFFFF68
-:1024A000021204E0FFFFFFFF021204E4FFFFFFFF40
-:1024B000021204E8FFFFFFFF021204ECFFFFFFFF20
-:1024C000021204F0FFFFFFFF021204F4FFFFFFFF00
-:1024D000021204F8FFFFFFFF021204FCFFFFFFFFE0
-:1024E00002120500FFFFFFFF02120504FFFFFFFFBE
-:1024F00002120508FFFFFFFF0212050CFFFFFFFF9E
-:1025000002120510FFFFFFFF021204D4FFFF333059
-:10251000021204D8FFFF3340021204B4F00030006E
-:1025200002120390000000080212039C0000000841
-:10253000021203A000000008021203A4000000021F
-:10254000021203BC00000004021203C000000005D8
-:10255000021203C400000004021203D000000000B5
-:102560000212036C00000001021203680000003F29
-:10257000021201BC00000040021201C00000180855
-:10258000021201C400000803021201C8000008037F
-:10259000021201CC00000040021201D00000000332
-:1025A000021201D400000803021201D8000008033F
-:1025B000021201DC00000803021201E00001000326
-:1025C000021201E400000803021201E800000803FF
-:1025D000021201EC00000003021201F000000003EF
-:1025E000021201F400000003021201F800000003CF
-:1025F000021201FC000000030212020000000003AE
-:10260000021202040000000302120208000000038C
-:102610000212020C0000000302120210000000036C
-:10262000021202140000000302120218000000034C
-:102630000212021C0000000302120220000000032C
-:1026400002120224000000030212022800002403E8
-:102650000212022C0000002F0212023000000009BA
-:102660000212023400000019021202380000018434
-:102670000212023C00000183021202400000030625
-:102680000212024400000019021202480000000673
-:102690000212024C00000306021202500000030660
-:1026A00002120254000003060212025800000C86B7
-:1026B0000212025C00000306021202600000030620
-:1026C0000212026400000006021202680000000606
-:1026D0000212026C000000060212027000000006E6
-:1026E00002120274000000060212027800000006C6
-:1026F0000212027C000000060212028000000006A6
-:102700000212028400000006021202880000000685
-:102710000212028C00000006021202900000000665
-:102720000212029400000006021202980000000645
-:102730000212029C00000006021202A00000030622
-:10274000021202A400000013021202A800000006F8
-:10275000021202B000001004021202B400001004C1
-:102760000212032400106440021203280010644087
-:10277000021201B0000000010600A00000000016D7
-:102780000200A06CBF5C00000200A070FFF51FEF0C
-:102790000200A0740000FFFF0200A078500003E0D8
-:1027A0000200A07C000000000200A0800000A00049
-:1027B0000600A084000000050200A0980FE00000C1
-:1027C0000600A09C000000140200A0EC555400007C
-:1027D0000200A0F0555555550200A0F400005555D3
-:1027E0000200A0F8000000000200A0FC5554000008
-:1027F0000200A100555555550200A1040000555591
-:102800000200A108000000000200A22C000000004D
-:102810000600A230000000030200A06000000007D4
-:102820000200A10CBF5C00000200A110FFF51FEF29
-:102830000200A1140000FFFF0200A118500003E0F5
-:102840000200A11C000000000200A1200000A00066
-:102850000600A124000000050200A1380FE00000DE
-:102860000600A13C000000140200A18C5554000099
-:102870000200A190555555550200A19400005555F0
-:102880000200A198000000000200A19C5554000025
-:102890000200A1A0555555550200A1A400005555B0
-:1028A0000200A1A8000000000200A23C00000000FD
-:1028B0000600A240000000030200A0640000000720
-:1028C00000000000000000000000002E00000000DA
-:1028D00000000000000000000000000000000000F8
-:1028E00000000000000000000000000000000000E8
-:1028F00000000000000000000000000000000000D8
-:1029000000000000000000000000000000000000C7
-:1029100000000000000000000000000000000000B7
-:10292000002E005000000000000000000000000029
-:102930000000000000000000000000000000000097
-:102940000000000000000000000000000050008DAA
-:102950000000000000000000000000000000000077
-:102960000000000000000000000000000000000067
-:102970000000000000000000008D00920092009610
-:102980000096009A00000000000000000000000017
-:102990000000000000000000000000000000000037
-:1029A00000000000009A00DB00DB00E900E900F70E
-:1029B0000000000000000000000000000000000017
-:1029C0000000000000000000000000000000000007
-:1029D00000000000000000000000000000000000F7
-:1029E00000000000000000000000000000000000E7
-:1029F00000000000000000000000000000000000D7
-:102A000000000000000000000000000000000000C6
-:102A100000000000000000000000000000000000B6
-:102A200000000000000000000000000000000000A6
-:102A30000000000000000000000000000000000096
-:102A40000000000000000000000000000000000086
-:102A50000000000000000000000000000000000076
-:102A60000000000000000000000000000000000066
-:102A70000000000000000000000000000000000056
-:102A800000F700FE00000000000000000000000051
-:102A90000000000000000000000000000000000036
-:102AA0000000000000000000000000000000000026
-:102AB0000000000000000000000000000000000016
-:102AC0000000000000000000000000000000000006
-:102AD000000000000000000000FE01030103010EE1
-:102AE000010E0119000000000000000000000000BD
-:102AF00000000000000000000000000000000000D6
-:102B000000000000000000000000000000000000C5
-:102B100000000000000000000000000000000000B5
-:102B200000000000000000000000000000000000A5
-:102B30000119011A00000000000000000000000060
-:102B40000000000000000000000000000000000085
-:102B5000000000000000000000000000011A013E1B
-:102B60000000000000000000000000000000000065
-:102B70000000000000000000000000000000000055
-:102B80000000000000000000013E016400000000A1
-:102B90000000000000000000000000000000000035
-:102BA0000000000000000000000000000000000025
-:102BB00000000000016401A300000000000000000C
-:102BC0000000000000000000000000000000000005
-:102BD00000000000000000000000000000000000F5
-:102BE00001A301DE00000000000000000000000062
-:102BF00000000000000000000000000000000000D5
-:102C000000000000000000000000000001DE0224BF
-:102C10000224022C022C02340000000000000000FC
-:102C200000000000000000000000000000000000A4
-:102C300000000000000000000234027102710278FE
-:102C40000278027F00000000000000000000000089
-:102C50000000000000000000000000000000000074
-:102C600000000000027F0280000000000000000061
-:102C70000000000000000000000000000000000054
-:102C80000000000000000000000000000000000044
-:102C9000028002920000000000000000000000001E
-:102CA0000000000000000000000000000000000024
-:102CB000000000000000000000000000029202A7D7
-:102CC00002A702AA02AA02AD000000000000000054
-:102CD00000000000000000000000000000000000F4
-:102CE000000000000000000002AD02DB0000000058
-:102CF00000000000000000000000000000000000D4
-:102D000000000000000000000000000000000000C3
-:102D10000000000002DB0362000000000000000071
-:102D200000000000000000000000000000000000A3
-:102D30000000000000000000000000000000000093
-:102D4000036203690369036D036D037100000000F2
-:102D50000000000000000000000000000000000073
-:102D6000000000000000000000000000037103B03C
-:102D700003B003B803B803C0000000000000000067
-:102D80000000000000000000000000000000000043
-:102D9000000000000000000003C004130413042717
-:102DA0000427043B000000000000000000000000B9
-:102DB0000000000000000000000000000000000013
-:102DC00000000000043B044300000000000000007D
-:102DD00000000000000000000000000000000000F3
-:102DE00000000000000000000000000000000000E3
-:102DF000044304490000000000000000000000003F
-:102E000000000000000000000000000000000000C2
-:102E10000000000000000000000000000449044C15
-:102E200000000000000000000000000000000000A2
-:102E30000000000000000000000000000000000092
-:102E40000000000000000000044C045100000000DD
-:102E50000000000000000000000000000000000072
-:102E60000000000000000000000000000000000062
-:102E70000000000004510452045204640464047607
-:102E80000000000000000000000000000000000042
-:102E90000000000000000000000000000000000032
-:102EA000047604E3000000000000000000000000C1
-:102EB0000000000000000000000000000000000012
-:102EC00000000000000000000000000004E304E433
-:102ED00004E404F804F8050C000000000000000001
-:102EE00000000000000000000000000000000000E2
-:102EF00000000000000000000000000000000000D2
-:102F000000010000000204C00003098000040E401C
-:102F100000051300000617C000071C8000082140B0
-:102F200000092600000A2AC0000B2F80000C344044
-:102F3000000D3900000E3DC0000F428000104740D8
-:102F400000114C00001250C00013558000145A406C
-:102F500000155F00001663C00017688000186D4000
-:102F600000197200001A76C0001B7B80001C804094
-:102F7000001D8500001E89C0001F8E800020934028
-:102F80000000200000004000000060000000800001
-:102F90000000A0000000C0000000E00000010000F0
-:102FA00000012000000140000001600000018000DD
-:102FB0000001A0000001C0000001E00000020000CC
-:102FC00000022000000240000002600000028000B9
-:102FD0000002A0000002C0000002E00000030000A8
-:102FE0000003200000034000000360000003800095
-:102FF0000003A0000003C0000003E0000004000084
-:103000000004200000044000000460000004800070
-:103010000004A0000004C0000004E000000500005F
-:10302000000520000005400000056000000580004C
-:103030000005A0000005C0000005E000000600003B
-:103040000006200000064000000660000006800028
-:103050000006A0000006C0000006E0000007000017
-:103060000007200000074000000760000007800004
-:103070000007A0000007C0000007E00000080000F3
-:1030800000082000000840000008600000088000E0
-:103090000008A0000008C0000008E00000090000CF
-:1030A00000092000000940000009600000098000BC
-:1030B0000009A0000009C0000009E000000A0000AB
-:1030C000000A2000000A4000000A6000000A800098
-:1030D000000AA000000AC000000AE000000B000087
-:1030E000000B2000000B4000000B6000000B800074
-:1030F000000BA000000BC000000BE000000C000063
-:10310000000C2000000C4000000C6000000C80004F
-:10311000000CA000000CC000000CE000000D00003E
-:10312000000D2000000D4000000D6000000D80002B
-:10313000000DA000000DC000000DE000000E00001A
-:10314000000E2000000E4000000E6000000E800007
-:10315000000EA000000EC000000EE000000F0000F6
-:10316000000F2000000F4000000F6000000F8000E3
-:10317000000FA000000FC000000FE00000100000D2
-:1031800000102000001040000010600000108000BF
-:103190000010A0000010C0000010E00000110000AE
-:1031A000001120000011400000116000001180009B
-:1031B0000011A0000011C0000011E000001200008A
-:1031C0000012200000124000001260000012800077
-:1031D0000012A0000012C0000012E0000013000066
-:1031E0000013200000134000001360000013800053
-:1031F0000013A0000013C0000013E0000014000042
-:10320000001420000014400000146000001480002E
-:103210000014A0000014C0000014E000001500001D
-:10322000001520000015400000156000001580000A
-:103230000015A0000015C0000015E00000160000F9
-:1032400000162000001640000016600000168000E6
-:103250000016A0000016C0000016E00000170000D5
-:1032600000172000001740000017600000178000C2
-:103270000017A0000017C0000017E00000180000B1
-:10328000001820000018400000186000001880009E
-:103290000018A0000018C0000018E000001900008D
-:1032A000001920000019400000196000001980007A
-:1032B0000019A0000019C0000019E000001A000069
-:1032C000001A2000001A4000001A6000001A800056
-:1032D000001AA000001AC000001AE000001B000045
-:1032E000001B2000001B4000001B6000001B800032
-:1032F000001BA000001BC000001BE000001C000021
-:10330000001C2000001C4000001C6000001C80000D
-:10331000001CA000001CC000001CE000001D0000FC
-:10332000001D2000001D4000001D6000001D8000E9
-:10333000001DA000001DC000001DE000001E0000D8
-:10334000001E2000001E4000001E6000001E8000C5
-:10335000001EA000001EC000001EE000001F0000B4
-:10336000001F2000001F4000001F6000001F8000A1
-:10337000001FA000001FC000001FE0000020000090
-:10338000002020000020400000206000002080007D
-:103390000020A0000020C0000020E000002100006C
-:1033A0000021200000214000002160000021800059
-:1033B0000021A0000021C0000021E0000022000048
-:1033C0000022200000224000002260000022800035
-:1033D0000022A0000022C0000022E0000023000024
-:1033E0000023200000234000002360000023800011
-:1033F0000023A0000023C0000023E0000024000000
-:1034000000242000002440000024600000248000EC
-:103410000024A0000024C0000024E00000250000DB
-:1034200000252000002540000025600000258000C8
-:103430000025A0000025C0000025E00000260000B7
-:1034400000262000002640000026600000268000A4
-:103450000026A0000026C0000026E0000027000093
-:103460000027200000274000002760000027800080
-:103470000027A0000027C0000027E000002800006F
-:10348000002820000028400000286000002880005C
-:103490000028A0000028C0000028E000002900004B
-:1034A0000029200000294000002960000029800038
-:1034B0000029A0000029C0000029E000002A000027
-:1034C000002A2000002A4000002A6000002A800014
-:1034D000002AA000002AC000002AE000002B000003
-:1034E000002B2000002B4000002B6000002B8000F0
-:1034F000002BA000002BC000002BE000002C0000DF
-:10350000002C2000002C4000002C6000002C8000CB
-:10351000002CA000002CC000002CE000002D0000BA
-:10352000002D2000002D4000002D6000002D8000A7
-:10353000002DA000002DC000002DE000002E000096
-:10354000002E2000002E4000002E6000002E800083
-:10355000002EA000002EC000002EE000002F000072
-:10356000002F2000002F4000002F6000002F80005F
-:10357000002FA000002FC000002FE000003000004E
-:10358000003020000030400000306000003080003B
-:103590000030A0000030C0000030E000003100002A
-:1035A0000031200000314000003160000031800017
-:1035B0000031A0000031C0000031E0000032000006
-:1035C00000322000003240000032600000328000F3
-:1035D0000032A0000032C0000032E00000330000E2
-:1035E00000332000003340000033600000338000CF
-:1035F0000033A0000033C0000033E00000340000BE
-:1036000000342000003440000034600000348000AA
-:103610000034A0000034C0000034E0000035000099
-:103620000035200000354000003560000035800086
-:103630000035A0000035C0000035E0000036000075
-:103640000036200000364000003660000036800062
-:103650000036A0000036C0000036E0000037000051
-:10366000003720000037400000376000003780003E
-:103670000037A0000037C0000037E000003800002D
-:10368000003820000038400000386000003880001A
-:103690000038A0000038C0000038E0000039000009
-:1036A00000392000003940000039600000398000F6
-:1036B0000039A0000039C0000039E000003A0000E5
-:1036C000003A2000003A4000003A6000003A8000D2
-:1036D000003AA000003AC000003AE000003B0000C1
-:1036E000003B2000003B4000003B6000003B8000AE
-:1036F000003BA000003BC000003BE000003C00009D
-:10370000003C2000003C4000003C6000003C800089
-:10371000003CA000003CC000003CE000003D000078
-:10372000003D2000003D4000003D6000003D800065
-:10373000003DA000003DC000003DE000003E000054
-:10374000003E2000003E4000003E6000003E800041
-:10375000003EA000003EC000003EE000003F000030
-:10376000003F2000003F4000003F6000003F80001D
-:10377000003FA000003FC000003FE000003FE0012C
-:1037800000000000000001FF0000020000007FF8C0
-:1037900000007FF8000002920000350000000001E8
-:1037A0000000000300BEBC200000000300BEBC20DF
-:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
-:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
-:1037D000FFFFFFFF00000000FFFFFFFF00000000F1
-:1037E000FFFFFFFF0000000300BEBC20FFFFFFFF44
-:1037F00000000000FFFFFFFF00000000FFFFFFFFD1
-:103800000000000300BEBC2000002000000040C0FB
-:1038100000006180000082400000A3000000C3C0DF
-:103820000000E4800001054000012600000146C0C0
-:1038300000016780000188400001A9000001C9C0A3
-:103840000001EA8000020B4000022C0000024CC084
-:1038500000026D8000028E400002AF000002CFC067
-:103860000002F0800003114000033200000352C048
-:1038700000037380000394400003B5000003D5C02B
-:103880000003F6800004174000043800000458C00C
-:103890000004798000049A40000080000001038049
-:1038A0000001870000020A8000028E0000031180E0
-:1038B000000395000004188000049C0000051F8090
-:1038C0000005A300000626800006AA0000072D8040
-:1038D0000007B100000834800008B80000093B80F0
-:1038E0000009BF00000A4280000AC600000B4980A0
-:1038F000000BCD00000C5080000CD400000D578050
-:10390000000DDB0000007FF800007FF8000003E5F9
-:10391000000015000000190000000000FFFFFFFF7D
-:103920004000000040000000400000004000000097
-:103930004000000040000000400000004000000087
-:103940004000000040000000400000004000000077
-:103950004000000040000000400000004000000067
-:103960004000000040000000400000004000000057
-:103970004000000040000000400000004000000047
-:103980004000000040000000400000004000000037
-:103990004000000040000000400000004000000027
-:1039A00000007FF800007FF8000003C80000150049
-:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
-:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
-:1039D00040000000400000004000000040000000E7
-:1039E00040000000400000004000000040000000D7
-:1039F00040000000400000004000000040000000C7
-:103A000040000000400000004000000040000000B6
-:103A100040000000400000004000000040000000A6
-:103A20004000000040000000400000004000000096
-:103A30004000000040000000400000004000000086
-:103A40004000000040000000400000004000000076
-:103A500000001000000020800000310000004180C4
-:103A600000005200000062800000730000008380AC
-:103A7000000094000000A4800000B5000000C58094
-:103A80000000D6000000E6800000F700000107807B
-:103A90000001180000012880000139000001498060
-:103AA00000015A0000016A8000017B0000018B8048
-:103AB00000019C000001AC800001BD000001CD8030
-:103AC0000001DE000001EE800001FF0000007FF831
-:103AD00000007FF800000207000035001000000021
-:103AE000000028AD000000000001000100350804BE
-:103AF000CCCCCCC1FFFFFFFFFFFFFFFF7058103C95
-:103B000000000000CCCC0201CCCCCCCC00000000EA
-:103B1000FFFFFFFF400000004000000040000000E9
-:103B20004000000040000000400000004000000095
-:103B30004000000040000000400000004000000085
-:103B40004000000040000000400000004000000075
-:103B50004000000040000000400000004000000065
-:103B60004000000040000000400000004000000055
-:103B70004000000040000000400000004000000045
-:103B80004000000040000000400000004000000035
-:103B900040000000000E01B7011600D60000FFFF34
-:103BA000000000000000FFFF000000000000FFFF19
-:103BB000000000000000FFFF000000000000FFFF09
-:103BC000000000000000FFFF000000000000FFFFF9
-:103BD000000000000000FFFF0000000000100000D7
-:103BE00000000000007201BB012300F30000FFFF92
-:103BF000000000000000FFFF000000000000FFFFC9
-:103C0000000000000000FFFF000000000000FFFFB8
-:103C1000000000000000FFFF000000000000FFFFA8
-:103C2000000000000000FFFF000000000010000086
-:103C300000000000FFFFFFF3320FFFFF0C30C30C4A
-:103C4000C30C30C3CF3CF300F3CF3CF30000CF3CB8
-:103C5000CDCDCDCDFFFFFFF130EFFFFF0C30C30C1A
-:103C6000C30C30C3CF3CF300F3CF3CF30001CF3C97
-:103C7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C85
-:103C8000C30C30C3CF3CF300F3CF3CF30002CF3C76
-:103C9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051B
-:103CA000C30C30C3CF300014F3CF3CF30004CF3C3F
-:103CB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C59
-:103CC000C30C30C3CF3CF300F3CF3CF30008CF3C30
-:103CD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C51
-:103CE000C30C30C3CF3CF300F3CF3CF30010CF3C08
-:103CF000CDCDCDCDFFFFFFF731EFFFFF0C30C30C73
-:103D0000C30C30C3CF3CF300F3CF3CF30020CF3CD7
-:103D1000CDCDCDCDFFFFFFF5302FFFFF0C30C30C15
-:103D2000C30C30C3CF3CF300F3CF3CF30040CF3C97
-:103D3000CDCDCDCDFFFFFFF3310FFFFF0C30C30C16
-:103D4000C30C30C3CF3CF300F3CF3CF30000CF3CB7
-:103D5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF8
-:103D6000C30C30C3CF3CF300F3CF3CF30001CF3C96
-:103D7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C84
-:103D8000C30C30C3CF3CF300F3CF3CF30002CF3C75
-:103D9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051A
-:103DA000C30C30C3CF300014F3CF3CF30004CF3C3E
-:103DB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C58
-:103DC000C30C30C3CF3CF300F3CF3CF30008CF3C2F
-:103DD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C50
-:103DE000C30C30C3CF3CF300F3CF3CF30010CF3C07
-:103DF000CDCDCDCDFFFFFFF730EFFFFF0C30C30C73
-:103E0000C30C30C3CF3CF300F3CF3CF30020CF3CD6
-:103E1000CDCDCDCDFFFFFFF5304FFFFF0C30C30CF4
-:103E2000C30C30C3CF3CF300F3CF3CF30040CF3C96
-:103E3000CDCDCDCDFFFFFFF331EFFFFF0C30C30C35
-:103E4000C30C30C3CF3CF300F3CF3CF30000CF3CB6
-:103E5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF7
-:103E6000C30C30C3CF3CF300F3CF3CF30001CF3C95
-:103E7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C83
-:103E8000C30C30C3CF3CF300F3CF3CF30002CF3C74
-:103E9000CDCDCDCDFFFFF4061CBFFFFF0C30C30519
-:103EA000C30C30C3CF300014F3CF3CF30004CF3C3D
-:103EB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C57
-:103EC000C30C30C3CF3CF300F3CF3CF30008CF3C2E
-:103ED000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4F
-:103EE000C30C30C3CF3CF300F3CF3CF30010CF3C06
-:103EF000CDCDCDCDFFFFFF97056FFFFF0C30C30C7D
-:103F0000C30C30C3CF3CC000F3CF3CF30020CF3C08
-:103F1000CDCDCDCDFFFFFFF5310FFFFF0C30C30C32
-:103F2000C30C30C3CF3CF300F3CF3CF30040CF3C95
-:103F3000CDCDCDCDFFFFFFF3320FFFFF0C30C30C13
-:103F4000C30C30C3CF3CF300F3CF3CF30000CF3CB5
-:103F5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF6
-:103F6000C30C30C3CF3CF300F3CF3CF30001CF3C94
-:103F7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C82
-:103F8000C30C30C3CF3CF300F3CF3CF30002CF3C73
-:103F9000CDCDCDCDFFFFF4061CBFFFFF0C30C30518
-:103FA000C30C30C3CF300014F3CF3CF30004CF3C3C
-:103FB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C56
-:103FC000C30C30C3CF3CF300F3CF3CF30008CF3C2D
-:103FD000CDCDCDCDFFFFFF8A042FFFFF0C30C30CEA
-:103FE000C30C30C3CF3CC000F3CF3CF30010CF3C38
-:103FF000CDCDCDCDFFFFFF9705CFFFFF0C30C30C1C
-:10400000C30C30C3CF3CC000F3CF3CF30020CF3C07
-:10401000CDCDCDCDFFFFFFF5310FFFFF0C30C30C31
-:10402000C30C30C3CF3CF300F3CF3CF30040CF3C94
-:10403000CDCDCDCDFFFFFFF3300FFFFF0C30C30C14
-:10404000C30C30C3CF3CF300F3CF3CF30000CF3CB4
-:10405000CDCDCDCDFFFFFFF1300FFFFF0C30C30CF6
-:10406000C30C30C3CF3CF300F3CF3CF30001CF3C93
-:10407000CDCDCDCDFFFFFFF6305FFFFF0C30C30C81
-:10408000C30C30C3CF3CF300F3CF3CF30002CF3C72
-:10409000CDCDCDCDFFFFF4061CBFFFFF0C30C30517
-:1040A000C30C30C3CF300014F3CF3CF30004CF3C3B
-:1040B000CDCDCDCDFFFFFFF2304FFFFF0C30C30C55
-:1040C000C30C30C3CF3CF300F3CF3CF30008CF3C2C
-:1040D000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4D
-:1040E000C30C30C3CF3CF300F3CF3CF30010CF3C04
-:1040F000CDCDCDCDFFFFFF97040FFFFF0C30C30CDC
-:10410000C30C30C3CF3CC000F3CF3CF30020CF3C06
-:10411000CDCDCDCDFFFFFFF5300FFFFF0C30C30C31
-:10412000C30C30C3CF3CF300F3CF3CF30040CF3C93
-:10413000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C47
-:10414000C30C30C3CF3CF3CCF3CF3CF30000CF3CE7
-:10415000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C27
-:10416000C30C30C3CF3CF3CCF3CF3CF30001CF3CC6
-:10417000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C07
-:10418000C30C30C3CF3CF3CCF3CF3CF30002CF3CA5
-:10419000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE7
-:1041A000C30C30C3CF3CF3CCF3CF3CF30004CF3C83
-:1041B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC7
-:1041C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5F
-:1041D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA7
-:1041E000C30C30C3CF3CF3CCF3CF3CF30010CF3C37
-:1041F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C87
-:10420000C30C30C3CF3CF3CCF3CF3CF30020CF3C06
-:10421000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C66
-:10422000C30C30C3CF3CF3CCF3CF3CF30040CF3CC6
-:10423000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C46
-:10424000C30C30C3CF3CF3CCF3CF3CF30000CF3CE6
-:10425000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C26
-:10426000C30C30C3CF3CF3CCF3CF3CF30001CF3CC5
-:10427000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C06
-:10428000C30C30C3CF3CF3CCF3CF3CF30002CF3CA4
-:10429000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE6
-:1042A000C30C30C3CF3CF3CCF3CF3CF30004CF3C82
-:1042B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC6
-:1042C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5E
-:1042D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA6
-:1042E000C30C30C3CF3CF3CCF3CF3CF30010CF3C36
-:1042F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C86
-:10430000C30C30C3CF3CF3CCF3CF3CF30020CF3C05
-:10431000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C65
-:10432000C30C30C3CF3CF3CCF3CF3CF30040CF3CC5
-:10433000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C45
-:10434000C30C30C3CF3CF3CCF3CF3CF30000CF3CE5
-:10435000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C25
-:10436000C30C30C3CF3CF3CCF3CF3CF30001CF3CC4
-:10437000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C05
-:10438000C30C30C3CF3CF3CCF3CF3CF30002CF3CA3
-:10439000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE5
-:1043A000C30C30C3CF3CF3CCF3CF3CF30004CF3C81
-:1043B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC5
-:1043C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5D
-:1043D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA5
-:1043E000C30C30C3CF3CF3CCF3CF3CF30010CF3C35
-:1043F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C85
-:10440000C30C30C3CF3CF3CCF3CF3CF30020CF3C04
-:10441000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C64
-:10442000C30C30C3CF3CF3CCF3CF3CF30040CF3CC4
-:10443000CDCDCDCD0010000000070100000281703D
-:10444000000B81980002025000010270000F0280F0
-:1044500000010370000800000008008000028100D5
-:10446000000B8128000201E0000102000007021099
-:1044700000020280000F0000000800F000028170BE
-:10448000000B81980002025000010270000B828034
-:1044900000080338001000000008010000028180BD
-:1044A000000B81A80002026000018280000E829849
-:1044B0000008038000028000000B8028000200E05A
-:1044C000000101000000811000000118CCCCCCCC10
-:1044D000CCCCCCCCCCCCCCCCCCCCCCCC000020002C
-:1044E000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0C
-:1044F00000002000CCCCCCCCCCCCCCCCCCCCCCCC0C
-:10450000CCCCCCCC0000200000000000000000005B
-:104510001F8B08000000000000FFFB51CFC0F0031C
-:104520008A45D91918FC3811FCA18059981918D856
-:10453000809803883D80B8819181A1919178FDDABE
-:10454000620876BF3003C36E20E611029A23821000
-:104550009F0254F306C85F0F15B312656038263A00
-:10456000F07EA706DE2A8D29364512C1DE86451E5D
-:10457000196F4793FF2289CADF4140FF40632965D5
-:1045800054BE9D22845EA604A1A5D1E4EDA1F2D77C
-:10459000A1FE9251C66EEE0DA83C00F85C49656024
-:1045A00003000000000000001F8B08000000000056
-:1045B00000FFED7D0B7854D5B5F03E73CE9C994944
-:1045C000CE4C4E4212F2224C1288A0210CAF808AAF
-:1045D0007F270122F539202858D40142087983D455
-:1045E0004BAFEDCD8424101135F447058B76885000
-:1045F000D1A20D34D260C10E20147B6D6FF0FAC0D1
-:10460000EAF50B4841312FB1207EC5CBBFD6DAE7A2
-:1046100064E64C2680D8DBAFFFFFFDB4B8D9E7ECE9
-:10462000B3F7DAEBB5D75A7BED3D92750293BFC76E
-:10463000D845FC03E54F4D8CB109C1F26766F680A1
-:104640002787B1C9BDFE3A473C63556D193BA29D12
-:104650008C25EC9921142850FED5232C5082DFBFE5
-:1046600065C397F0FFB619423E7C97D0E911E6C3C7
-:10467000FBE4D5026B873A939C310CEA8CB9194B59
-:10468000642C6B12A33F224B8D82FFE07325398F80
-:10469000B134FC2774754661AEC078C6321E535CD7
-:1046A000D4D0A93815783F847FC6D2BC25B731074E
-:1046B00063CF03BCC971F0BC5A3ADE61E5EF2EC28C
-:1046C000DFA1F33A6ACD58AE303E7732A789654113
-:1046D000BF3EE3F3AC46633D9BD9E34F46C33FEC9B
-:1046E000CC7E518C308F13B18C013CCB540E2F6398
-:1046F000BDB26754101F9B6A58A2322C580F2F85E9
-:1047000065873356035E97ED165C16F8FE396C2FFD
-:1047100031E6D7BE6BD6EA153E5962A3A10404B5B3
-:10472000E4F4EF6711CBBF11F1FE302BA0B24AEADF
-:10473000955580AFAA5A76FB95FEED673389E8540C
-:1047400029B9F65B61FCDE5AE66A86F19799D502D3
-:10475000AC2FFB91D3E5837A6663472183FAD03689
-:10476000818919C1EFAF009EDB917F001E2A2BA526
-:10477000DE420674ECDD2BB0E60C1C87F7BB6C77D1
-:1047800006F3650C0CE758662638E732413A89741F
-:10479000713007D2C1BC24F38942A8CE54DCF3B0F7
-:1047A0007F9FE29D87EDF4E7490BE638BD0057F2A5
-:1047B0005066A057B1B53A9D653256EA692944BEA4
-:1047C00038B5EC8D5558029E1324C0F77C8BA70892
-:1047D000FBA998579DCD80A7E659188D3FB42DFFB2
-:1047E0003309F80CBAF3C5C4213F31763C844FF04D
-:1047F000CFF1115A5D1C98DE972B8BB01F09F10584
-:104800007217011F3F42A026E0284D543A57FC2959
-:104810006BD8A0D0FA5B59C3C66900E511BC0C3F48
-:1048200061AC4308E54BBD1CBA3BFFB0943B303C48
-:10483000FFD3F30474127EAB00B7C81F1576D9BF3F
-:1048400012F861CAABE6C0F7803F2A360B7E0BD464
-:104850004DAFDBE87DF7265E0FD86537F24FD716F0
-:10486000A80BF0BDA5FDF11B91BF5E155933763B3A
-:1048700022CA84FAE5A4063B1B0F75C047B18D57C9
-:104880002B36EFBB1FBF2F69B3301BF457B17BF141
-:104890001D37427DF16133C326155B6BE514A82FEC
-:1048A000F10B2D58EF29E0F0F97689FEADD0BEC7A7
-:1048B000D19E381BE873BAC6CA9C326375F6F6C43B
-:1048C00059C067A5FE1D85F85DE976C185689FF230
-:1048D000EAD643C938AF17B97C976D8B664E1D7FFA
-:1048E000F0F764AB18F81EBC5F06F364D0EF62D635
-:1048F00054887AB062EB3AD9690FE2EB748D4AE3DF
-:10490000F4C9DF8B300E7C57F98AE0C229569A9899
-:1049100017E5B07BB76DCEF30ACEAF56CEB6E3BC8B
-:1049200056CBD86EB17FFE2E54CDA5FECD7221BCE4
-:104930002FDDB4592E0E91DBB26D838C706DC81AC9
-:10494000EC8D20D7417880D7B283F552D403A80FDD
-:1049500025BF3C2384CF2A8558E2CBB26D22731A3F
-:10496000F888D3DDF72EFC13F0E5DB6B27BCEA7487
-:10497000EBD3A71ADDCEA81A1DA5DEBC1911F8F8D5
-:1049800071A403C0D384788272AD069F6332CB9743
-:10499000A07F879BA902BB3C5F3699D97C0663F553
-:1049A000B007DDD2F55097D952E682F550FAB17BC7
-:1049B0002AD49304EF67389F7AC15BC2D7AB9624A1
-:1049C0000FE07995C0E6E0FC8F21D030AF55C9C02B
-:1049D0009F80F7A66979CF8B82067B3CD68B7FB10F
-:1049E0002683FA3943FD98A19FACCBF7A3164E322C
-:1049F000F4A31696E8FDFC8DFAB15D593F4D85375D
-:104A000018E1292CD5FB910468576FBFB279A937FB
-:104A10004F36C2737339F5133BD5C5BC0AAEE71ADE
-:104A20003FB076B708EF95EDB163D7B050BE2850D0
-:104A30000580DB0E5212CA173193A20C7C18EB8E44
-:104A400033D4A127F5E47541FD138895697C394578
-:104A500026BD909F62A5FA43290AE985876EF05E1C
-:104A600083EB208ECD92A12E7B47AB11F81AE01478
-:104A7000581296601724F57FBFDACCF150907A2156
-:104A8000FB187C5F65EACD8E85FA35A6FC6B116F4D
-:104A90002E81EBE528915563BB280B23FDB43A2307
-:104AA000EF795F089E1A8700FD8560BF8D666F12E3
-:104AB000F2D7F8DA677C12C0B76A08CC2705BA12B9
-:104AC0009E09F8603D5A3DA43809F1699141BE4301
-:104AD000C79761FC1C1AFF06C4A31BC74FE83FBE63
-:104AE000257392617C6B7A89617CAB0CE303BF4FC9
-:104AF000AD6DD6C607FCDDC0D834A199C6B7A49762
-:104B0000D0F8AB655662183FAA6FFC5B70FE9E81C1
-:104B1000E69F798371FEE9A5C6F9CB7CFEB36A5F97
-:104B2000D2C68FA2F9CF165EE2F34F2FE5F3B7F0AE
-:104B30007EFBC677F4E1FF5E9CBF7780F12D599331
-:104B40008DF31F5A6E9CBF858F5F54BB531B5FA1B3
-:104B5000F117093BF9FC8796D3F8B2C5EB423E92B8
-:104B600053A3AAFD684FA481400C261DE5A672043C
-:104B70001805A01F860A9904C743519CEFCE450132
-:104B8000BF29417DC7FC2051A0CF2A359E2FDB9E37
-:104B90002FA39EA5F7896837F13F456D22AD376C8D
-:104BA000BDC53F1CE0ED6E137D582F5A7F935FA467
-:104BB000F58EDBE560C605F0F95F9E1CD51C3AAFAB
-:104BC000F0725193F96487418E383CBE0236A21AC6
-:104BD000E06B47269810AC9F043D0AC62F3B0E7A27
-:104BE00014CB53666E8F9C003DCBE450B9A9E5F61B
-:104BF000888FBD9303F3BA5B83FFA4C4F17D72B9C0
-:104C0000E047FC9F5BB75446FDB4A8098CE91079D6
-:104C1000AFD2E8D4BBDBE26F16089F4EC4CF3D2471
-:104C20008A8CFD9766D72FDE30C8F0DD3CE66F48F2
-:104C300082F60BD7CE1FA2C2FC7F30C73216ED53CF
-:104C400090845413C9314B35816F31A7759D391547
-:104C50002AF7CC311BECFAB95E63FD0725C67AB79B
-:104C6000D96F36A1BDB144609BA1DFFBAA8DEFF5E2
-:104C7000713609719CAEDA7877277278EFC3722C9F
-:104C80003E5689AEF7ABFC5B1D9EAA87CD2C40EB50
-:104C9000654702433AFA12C85EF3AA7CDEE1F0DE11
-:104CA0006FB6BA3D00CFFD3F12099FE1F077BC1E01
-:104CB000ED36811DD7B1E14B33DAB7E1F30987FF58
-:104CC0008115E1F35165D4F7F37DE1CF399F84F38A
-:104CD00053555BFEA01321ED2A5ABE3FE844087FDE
-:104CE000956D9B61A82FF1CF35B45FBC61BEE1FD2E
-:104CF000A2A62586F70B1B971AEAF37D3F32B47FF5
-:104D00006045ADE1FD7DD58F18DEFFA0649DA13E1D
-:104D1000D7BBD1D0FE9E399B0DEF4DAF8FBC13E5B5
-:104D2000A8EE5D91E1BA715639F938DA836715C991
-:104D300085F4F8B42689E4E0748D93CAEEB6715612
-:104D40002FD783C50C4C9C5EE19CAF7132EA65465F
-:104D5000FAF3AFC2059F0FEA7F139C843F7183CCA7
-:104D600002C0C2028BEBE3E35E31E47DC765DE6F18
-:104D700000411FD7FFBDD811F97955F3FCA16A0492
-:104D8000FF2128B72C15D7B91E6D7D0F7F5F2E3000
-:104D90004FE873C656929CD769EB4CB9CCF541F9F4
-:104DA000CEE402F4BFCBE54076F5A5C66B01A4A224
-:104DB0009E44EB3C01F901A4C0C02F5906F9EEDC7A
-:104DC00027125C95A81340AFAE639EC126D43381F1
-:104DD00003E9778D4238DC49546F4BA075BDB3664B
-:104DE000FAA01312D2C743E5A73573A83C59E3A52F
-:104DF000F2444D0995C76BAAA9ECA85941E5C735FE
-:104E00003E2A3FAA69A4F2CF354D541EADD940E5E4
-:104E10007B357E2ABB6BDC54F6F92BBAFE8DD7ECC2
-:104E200055CDAF809587EA67B4B9D443DB769273EA
-:104E30005712CAF919E55C36DAE3678E8263993155
-:104E400030BEC2F96D603ABAC95E29F603FDC7F5F6
-:104E50007F6F8BE274B299D87470A6D923C37FE1B7
-:104E60005A9043750959061624D70C7B847E61ED50
-:104E7000437A5D8E4ECCDD9B3B13E871F299BFE522
-:104E800061BF75DAFA177540A47598059E7721BD44
-:104E900042F046EB5AEFAB9ABEBF0CFEBAFAF0D71F
-:104EA0009E8EFEFB4141A5FECFB45A988478DC1358
-:104EB000ED07E667670E3FEF40795C9664524F441A
-:104EC000C0835E56B464A84AE8FAD366AC9F691200
-:104ED000A6B7D07AEC8C99350AF94A554F0C43FAAB
-:104EE0002751A9F7B32C49564F80BC9EDE9615C3B7
-:104EF000D76F3F5F07B7C712BF825F48EDFFDEF095
-:104F00000CD48F0E0F63ADEC132BEA037897F5EDFD
-:104F1000FD7226FD95E2576C8FF91CDA0B16F87BB3
-:104F200091E20712D5F57EAB5A449F65343EDF6EA1
-:104F3000180FBE73EA3EF7C5CC4BF1ADC44E86C424
-:104F400011D669F1C6B26D36D5B8AEC41AEA556D40
-:104F5000C9AA619DC17F80FCB36A4142BE29D7B80E
-:104F6000A847521A0580AFDCE4A47EAB04DEAEC2D3
-:104F7000DA217BE151572BA7DB40F09DAE39EC9451
-:104F800040DE4BACE001027C252D23A7A29EEB6AFC
-:104F9000AD4B447BB04C3CF39027C2F73B4D028DA8
-:104FA000B7C46FEE35AEA31A7F30E8577F4E7E163A
-:104FB000534E86D43B4DDCCE0EEFF780D6EFE5F0B6
-:104FC00053B9FD48E18DCEFE78AA6CFB42F6921CE7
-:104FD000C1FFF28278D2F1576EF21C407D5ABAEDD1
-:104FE00018D9A39F9A7DD90F5F423FF59F9F9244A6
-:104FF00071527D5E3E3029619C055A7C17F8F79E00
-:105000000F613DFDECDFCD6C0DC0C72E402B786FDE
-:10501000D65F331333417DA1565BD05A4671DDCF45
-:105020004CDC8E2A621E07D18135E5A11DD9C54C05
-:10503000D3114F5DEC6DC7B8103A9C32C9A4671606
-:10504000361AED18B07F0DF5C51B8CF5623633119D
-:10505000F549F17A33F30B343FC3FBF74D2AE17F77
-:1050600031AB5E85EBAAA4F9230B5426A5027C156F
-:10507000BF79366F3EC65F4CDC0FD1E3234BE2387D
-:10508000FCA5F17ED90DEF3F691D77F78D48068BA2
-:105090007F15C689580C736D65FDF1FB6DE10F87B7
-:1050A000575FAFFBC5693438C46D82DB1F817F2F2A
-:1050B000687CA6EBEB5B44D5E017DC8DF510BF21D7
-:1050C00046D4E2B2221391EE5DAAD5678AA1F71405
-:1050D000B7F7EDB4B8EA80DE3F3779068913C84EDA
-:1050E000C86521ED7E6EF2D2F34EE1AD62B45B99FC
-:1050F00014C8453B14D618E25359E30731CA918BC3
-:10510000F1663B837514E86F41F8A09F55F692DB7A
-:10511000582EC6BB41DEA1BFC71C858705A8DB94FE
-:105120005686FD59928CF17C9BD358AFC27F201DCF
-:1051300046308A3F458F90C2F01860A80FED2EE3ED
-:10514000F351E88491DD1F203E76108B43695502B0
-:10515000228CCF26499D7DFE5626FA7B1C7E8A2F07
-:1051600040FBE52A6F5FA9C5CF977F503038EE121C
-:10517000FAA8EA3C68904121753DBE7F5E62FE71EF
-:10518000DF416F3A61550DD19B734DDE69480FD4F5
-:1051900093089F00E3780D76609A1A2AE70BC2F80D
-:1051A000E3AAE1886706FD5D6EF2DE2D26F487E353
-:1051B000AAFB4FEAD7FF8248F3BCEAFE87F5EBBFB4
-:1051C0003252FF15BF7979970FF8A9F4574F3A80FB
-:1051D00099D9675253A20BE85EBEB5C18172F9A995
-:1051E000E473205D3FF38BD323C9E71651974FB784
-:1051F00022E411FF101F9D7EE9D13BD0AE3AB7D516
-:10520000AC527C609B256001A6AC6C5DC2E5639BE3
-:10521000E518AFAFFE02F9B3AACDA82F4A5F7832E6
-:1052200011E3CD4049CD7F0E907F50B9E52F8568C1
-:105230007755B15ED27BE1DFE1F8E7E3C81E982F36
-:10524000C7F47FAFEFF3556978A96A7DF40B9184B9
-:10525000A583FCCDF0F6259ABDFFA4688FA738DFA3
-:10526000443611F94CC707F3737BBFEEC5A7738FA4
-:10527000013C9D5BFEDD21E484F227D77B675A1653
-:10528000FEFC35E7C0F2D40D7A31D4AED6D76767CD
-:105290009BE6A7ECE165B939E0403FB07CB3D9E5C6
-:1052A00043BABEFCFC2F9EC1B8CC0716D770E8BF2E
-:1052B000ECE583EFDD00F5B21DE6F8DBF8341421F0
-:1052C0003148972AF8BB626C900EA5BF3E283B4739
-:1052D000F1E73F8E0BD2A36CC73E998DEA8F8F29E1
-:1052E0002DFBE40E25025D5A8E15A23F51F7E257C1
-:1052F00032EAAFCF5E17D8E08C08F8DC7C90EC6225
-:10530000C413D151A3531FDDC2DA57015D50BFEA68
-:10531000740A7FFF2F9AFEC7FE9C39C4CFAFBC86AC
-:10532000FB287FB6B870FE25AF3CE8C0799C92AAF6
-:10533000395F3FDB90E886714BCCBE44954AFEBC9A
-:10534000E4B91F12BF2D3EF2C3448A7F3077B28981
-:105350006C055F32CE6FD1A6D934BF62E625BE2B75
-:105360007956F4E0FEE059894DDF11412E5224AE0A
-:105370008F4F355B704D65A770E1C07D85B745FFE8
-:10538000568AFF2DA5F8CA0FF5FD20B68CEA67AD49
-:105390009C4E5F88FABE1AAC3CA1FCBA65753BD244
-:1053A000E7F410F7608C1B5731C9A7E143B808FD3B
-:1053B0008A47A60DE6F4614E294FFB0EF4FD147CDE
-:1053C0008EEDDBCD6E5BAEE13B76312338FE726D48
-:1053D0007C803B0AEDD5538960FF45985FA1A4AF5F
-:1053E00037605785F057887C7379DFF208976F5DD7
-:1053F000DEFD33A6E3FBBFBEC3E507BF437B05E08D
-:105400000A0CA6F7FB6609A40F2C2C1049AEB7981E
-:1054100035B936BED7F904E09670DDEDE317EC3F01
-:105420008EF04F766CF17AF82E445F56E1788EFE5E
-:10543000FDE972BB5893FF04C928FF6C1397FB81E9
-:10544000FD091F8F4B98FDBF7806E515E413F7AFF4
-:10545000CB5F367B70DE9F6F3FF0DEBD20A79FB72E
-:10546000E8726AD49FE1725AB273028B24A79F63D9
-:105470001A42243985E711E554E9203EFE47E94FF9
-:105480001D7F3785E14FD78703E1315C1FFE5974DB
-:1054900046D487F0E71D96D79FFF74BED3F9ADF4CD
-:1054A000971543293EA6F3A5CE777D7CA9F35DBF72
-:1054B00078A3017FE1EF2D188301B83CBBCD1447E1
-:1054C00028DFC3F77FE1BB43A9E3094F6E5AC658F3
-:1054D000D3A1D4F8D0BA3FACDE12D6DE1D56F78485
-:1054E000B5F786D5AB0DEDCBDB0EC83CAF256068BC
-:1054F00027AE78867D322812BFFAB95FDAFA85ECDA
-:1055000043BE507AE97BF34AE6B3633C7CAF48F193
-:10551000911EC0F12A18A7677B861FF3241A6C3CE2
-:10552000EED4A3F63AD05E6C88E5F5DE047915EA90
-:105530003DFD79AF8DC7F57A3CBD8ED810FBEDD817
-:105540001E91F476879F4D8FE467C28A4272D4C160
-:10555000067ACFE3FDD344257D05C65F9A441786BE
-:10556000748A6AEF71609E41CF9EAC3BE7C0F34501
-:105570006F8AB48DD883767B0C92C72D2587F877F8
-:105580009F32DF5393317EBF87FB79456BC3EC11AC
-:10559000B696F8A958592EA33E05BFECB871FF8204
-:1055A000CB45A9D65FC926E37BFD7BDCC145FBBDAE
-:1055B000748BF1BD578B0734EB7232868DD1FC7141
-:1055C0001E8FD2F4F23431E7CE39408F9EC322C30E
-:1055D000FDFB337B44A2C799ED7CBF9EE2F6D72347
-:1055E0007FF7923ED4F1D489F2240FACAF3A5FFD3D
-:1055F000AFBC87916F767D98FB33283B777D90FD1C
-:105600005BACFFE6FDF40F59FFF6535EB7D13E49A0
-:10561000CFEB76E2F79EBD7F4C7F18EBBB2D149F3E
-:10562000EE79FDAB5CE49F9E959612D4773D438066
-:10563000FE681FECFD2AB783D6D77AA2DB1F259917
-:10564000DB477BFEF6B1108F25CC0AED86D7A34948
-:105650009EAA5EB3513CAD67EF5779A176FF779D67
-:105660004FA5B67FD963677376227CB17CDFA7EA4A
-:10567000B7D73F5F8BF917ADFBE485F07ECAEFBE6D
-:10568000C9453DDAB393DB43DDE68EE7707FEE6814
-:10569000FDDC9566C073370A550AAC9B0DCF14A08C
-:1056A000DCF4C7CB371427BC527CF4FC5F830FC1FA
-:1056B000CDF59DDD6F1570DE5F7FFC21EA85D72D6E
-:1056C000C497FA7C3F6FA9257BE572F37698799CA5
-:1056D000E4FF9D790B812B99F728F33F37BD7F2D90
-:1056E00039892EE172D09FCFF73E44F597ED2E8297
-:1056F000F70AF9FDF67FF2F97F6BBAEF04BA3B2E99
-:105700003FEFF27FF2790F4CF737EFD7E8AE627ECA
-:105710004BD5EFBE21F8BEAD9E5BFB4F2EEF03CD08
-:105720005FB7EBD7985C4D99189F43AF01D669C519
-:105730003EB311C3856B46CC54D1CE14C3F62BF5C2
-:1057400072AF99FB4D22EE5B629C6F088FF331CDF7
-:105750008FA22D3D185A528AC98E959455DCBE965B
-:105760005CED6EC0CB9A6B17B82877888D3DEAC583
-:105770007ADA6417C5AFC3FCC97A81B905B06FA5E1
-:105780006B6F398CFE8D79842960C9A5F21896ABB0
-:10579000B5B8A459950D7E8F9263ACDB9CC6BA4513
-:1057A000EBCFCA38FCD624E6C7F8B43872BF8A7982
-:1057B0006DE218890950B7B1261FFA179624E3F74E
-:1057C0001B31C01E12CFBD5A3CF6F6E1716CBB1BFB
-:1057D000F138D244716B4A2E25BCB8FC6B789E8D93
-:1057E000D588D755ED884F09FD5F6E7F91DFCC34AA
-:1057F0007F59D2BA904698DC36633BCD4FBE2C9D84
-:10580000385DD2CB353A2D33D045A74304FA18E89A
-:10581000A2E3F9DBD2279C2EE1F8DF6F7612FE07B8
-:10582000A2974E9734C5CD505ECD9ABF3015FD4935
-:10583000ACA77918ED336BFE8214EF663EA493EAB1
-:1058400062482FF4DB02E0B7FD7EFBF31427EA7A0F
-:10585000E9D81D084FD96F456605FC756FB7B300D1
-:105860007E2FF965F4434B5B458AFB3329907757CC
-:10587000C8BEAF6EF797FDCA4EF329DD69F1DF06AA
-:10588000DF97EEFA2497ECB095BDE4D7F85E1238B6
-:10589000DD7D1DB9B8AF5B2A71FF239C5F62659EF9
-:1058A00027D0B93B7A0EC66D846D3CDFB6B4E51ED9
-:1058B000B3C5907F66D6DB915EF0BD2850BE13C2A3
-:1058C000179AE7A9FB1D9D2F0A1CBE36B31FF3765E
-:1058D0004BB7EDE8C6F853E9518B0BC3D255DBBE8D
-:1058E000A0FD8D29BF7AD9D141FEB668883FF4F377
-:1058F000FBB789C41F95AD15E487409DF8A2B2257A
-:1059000072FCEB72FE69D9AFF6EEF2010ACB7EFDB6
-:105910008203E35BA7DBB73AC8FFDF76E9B85B3FFA
-:105920003FBFE5914BFAF9A7F11FE0BFDC2087C527
-:1059300049B60D227F04E0CB8B94EFADF35BD9CB5E
-:10594000679FC33874E7CECF9F4378CBFFFBCBE78D
-:10595000D09F60AFDBD4AD889797DEA5389EFEDD83
-:105960002C99C79DBB5F7C81E29FDD1F80DF017F9B
-:10597000BAF79E4A477FB27BC7D789182F59BE779F
-:10598000DA609CEFF257A70C6611F4885E22DFFA0A
-:10599000AF20FE1A4EAF03AD07C8EFE9027AA3DFCE
-:1059A000D917B769A9E07130A716AFD91E39CEDD76
-:1059B0002F3ED37AD79D378DC7D2EC72B22B88D3C6
-:1059C000BC03741C7D05F4DBFE88E67F46A65F17EA
-:1059D000FE03E8B42C8C7E675B17FDFC197CD73A7C
-:1059E00068C0384DE00AF0A6C7D1BF27BB7F22A30D
-:1059F0007CEDFC25C5C5906EB7C144BB5F3E9B8E58
-:105A0000FB0F9F9A7BEFE7E7322C2AC61B4AF7BEB3
-:105A10004FF2D3FDEA118A53332D9EDDCDFAFEF00D
-:105A2000F8A3965359B5C5CEE33B1AFE31FEE37495
-:105A3000D0732DCEC3F9588FFF0C14F7699579DE1A
-:105A4000881EDFAFD8F2A1164F09D24B9884743A62
-:105A500076C9FD081D0F2AE26162681C33727CADB5
-:105A60002FDEADD10BE987F1CBBE3825D4D3306E14
-:105A7000E517DE6711F441F7661EFFEC3647CEA34B
-:105A8000D2E39ABF0A9753FF95C5332F07FFB7C5D7
-:105A90008F5F7652BFE178EABC10598FBF2DF37546
-:105AA000FFAAF7C5CA0543BE41B9C97B04F9B1A233
-:105AB000F598CCCFA5F0F352FA7C3BB5BCD1CE978C
-:105AC000448A77AD6A39407A3C5C5FE8FBA6E1F036
-:105AD0009ED0E0AD6CE3EB44E74EBB5F817E3AF7CE
-:105AE000EF267EAEDC7E8CE26D87B6FD5AEE08595D
-:105AF00057719DF087C0DFF9CABE5C1EB7E579EC2F
-:105B0000E1E39CD1F461D59EC8E3546DFFC2304EF1
-:105B100099AF45E6EBFDA5C73B2DB9EFC1FE4EB7EA
-:105B20009B19E6799E6E11A7473A17F5AEB66EEA55
-:105B3000E77E70BDA47CFD23FC5CCCF8B7A3281FD6
-:105B40007EF991E91FC6C463098487FE5A6B399FA9
-:105B5000B6FEC49D8AF46E3D72AF88EBD42EC46F3E
-:105B6000889D9FF74EF5143BE885BC8F3CE3915D23
-:105B7000C3F5CDC4A32603FC30CE605C07EAA11FA9
-:105B80003CA782F96E088FE8289C8EF088AA49B558
-:105B900009FDE761563C745E40EFD7AC1ACF03B005
-:105BA0000BE39CD84FD24C1E474CBE8B973EFD3C1E
-:105BB0004E7194BF0EE659A078D32CF07D927D7D76
-:105BC000C64186E7BF2651DE7696C5786EAC4B554A
-:105BD0007C26D0DFCFE46C5937D949F907D7584232
-:105BE000F30F582017F9516FD7EF7D587E421A7E78
-:105BF00002FD881A7C595A7EC210D621A07DBDC9EB
-:105C0000CECF270E55E24DF8FDF39ABDA99F3FEC8C
-:105C1000775E31EC9CE2E5CE27C64FC95F3AD405EA
-:105C2000FCB47ACF14CC5F8FBF277F47AA8A791242
-:105C30007F9E82E757E25FC81F930CF513AB1F9C52
-:105C40004AF5FFC81F930EF56F1AFF8DD7CB04CA14
-:105C5000572D583D7A2AF2EB55CBF92CC08851CEFE
-:105C6000EF40BC75793EBA7B9113F31F7A658E5F66
-:105C7000E6C176432671BCA5291FED403C0D357564
-:105C8000D4227FFE7CEF57B1A8179C4C25FCA8AC12
-:105C90005E45FAC1A349172F9147179E4FA6EB9374
-:105CA000CD8AF70184E391F923E85CE0332533AD35
-:105CB0003C5FCF98C7C0D478A26791464F84D31A6F
-:105CC000928FBF58F4C9FC5C4C93A6AFA6AA389E2D
-:105CD000E02B172F5EF7EDE17A50E74BED5C69C8DA
-:105CE00079C687105E9FE27DC892D0FF3CE31D1607
-:105CF000CF0A7C9F5C7C3E1DF95B3F9F187ECE9156
-:105D000049BDA648F65FB376CE7120783D56EF2A9E
-:105D10001C37F377CE9D8741BE4617C92E4CCD1C4C
-:105D2000BD627C82C4CF15529E439546BF24139713
-:105D300043F610A37DD61E8BE046BFB9E74195F42C
-:105D4000775AD16DE457F54467B4603E50CFC3FC39
-:105D50005C29664CA31C0DD9131340BF0FE4E05C13
-:105D6000981C9C33AE73C6717B2E3ADB3AA83F5524
-:105D7000EB0F0CB0C4E0B9E01E91EBE59E1A27C111
-:105D80003184F9F6E1FA7EA5E36DB518CFFD02DEA8
-:105D90005F40BCE878FFE5C0F47B45A3DF2B91E8CA
-:105DA000177EFE74BEC5FB6B6C7FAAF8D02A7415F3
-:105DB000C3CF9D86D3B54A6ADA88AE78E29E2F6853
-:105DC0009DD1E9367A852B411A64A0E3EBD8EFE840
-:105DD0003D5F98105E9D7E4F0F90EFFD070B5FCFEC
-:105DE000C2C74B9CD391E28DB4FE60102E2158CFD8
-:105DF000B5E6D1F8834D3CDED3BFBD10713ED07FF8
-:105E0000E6A5F2307355DE2FE0FFFD50BEFF10F126
-:105E10003F2222FE3F46BC03FE3FC6F65780FF4F9F
-:105E20002E857FDDAE2FD3F44219EE2B01FFFCC58A
-:105E300039333113C62D1415E2FF255B456D1FD292
-:105E40007D5B7262508F2CB9BE7A9F19F870C9B30E
-:105E500002F16991765EFD73ED5C4B785E5FF11C3B
-:105E60001FE9C9CBE7F7F9490F956D333EBF10E441
-:105E7000DB74CAC7F5F1F393A22617E1F83FA368D4
-:105E8000FAA228D6D02E9C0E43AA4D863CF0E429D7
-:105E90007DFD909F976472BE4FF1B53F9819C6077C
-:105EA000DC52FCF800E263BC3015FBCDD7E456EFC2
-:105EB0006FE80AE33A9FE1339EFBCB6A349EFB1BFB
-:105EC000DE9462687FCD864CC3FB91FE6B0DEFAF15
-:105ED000DB36D6501FD57283A1FDE8B602437D4C58
-:105EE000E01643FB7187671AEA13DAEF35B49F783F
-:105EF0007481E1FDF51DA586F7377EBACC50BFA9A8
-:105F0000F75F0DED038BB85EDC5F939486E70A7450
-:105F1000BCEC5F2A9B547CBE34DBA4E6863E4F7407
-:105F20003B73B1CC73A37F3590BC4CB126A785AE33
-:105F3000CFF9CC6CD06B53ACC67A8155E39774E043
-:105F40001720FECD56A35CA556CF6B02B39BA52CA4
-:105F50001946F9D2205FB758B97EBBC57A65FAED0C
-:105F60004E6C7FAA3240E7ECC3E54B44F9CAA2D29B
-:105F700047FBA9CC45F9961B6D463E4D1A40AFCC68
-:105F8000B31ACFC38BEA619B649013FDF9F9A8D0D3
-:105F9000E7C2E2DB286F67A07EE5A405B76E017D4E
-:105FA00029277BA9D49FAF9A638A9897F790F53BEE
-:105FB000FA491BFAD94F0F217EBB92DE7E0AF3CC41
-:105FC0002AE7F592BF946C31E22558770DE67954B3
-:105FD0004E7E8E50E5FFDC54D3782BAEF7FA3C179B
-:105FE0007D303311F303D206F09F5ED5E6F15C4DB0
-:105FF000C9AD45C3B03FD5147ABF457AA0AA10FDFC
-:1060000098A15A1EF453A6C8F94A3FD5FA198C0A2A
-:1060100014ED035521FBA0ABF8238704F3F8779325
-:10602000F7A7C8170B46B7E7F173CB6ED74CB2ABE7
-:1060300054825FD743E98AE729D42BE94912736672
-:10604000F48767F03C6F6306BCAF8F33B914AAF7CF
-:106050000A389EE5C78C0D82F1EAFF5B24F8EAF767
-:106060005F4FF93C16A59AE2A7FA3C99B6DFAFC795
-:106070008BCF26CD8A413CD65FDB776E8761FDAC46
-:10608000E26DC77ECFAE37D3B8F50582E1BD3E6F76
-:1060900069C31D741E2B5DE1F32E867923DC9634D3
-:1060A0000E57FD73024B23B8FEF7D243E8BFEC8ACC
-:1060B0007661BC0DF0B189E8EDCE3867D2270FF3D9
-:1060C000AA18A434AF21FB25B21FFA9695AFDB4C7A
-:1060D0009D9588F654F23546B8C5F566F20717C5A2
-:1060E0002A94AFE0AF59A1D1D538EF554933EF9C91
-:1060F0000BF0D4BD23324CFD7176342D3D04DF15F9
-:10610000B746BBFCCEFE78EF72723801EEB7106E68
-:10611000714321CD9BDA21DC3F17D83319C877DED4
-:10612000E944FF1413C37D9770F8FFD3CAE3C4EFAB
-:1061300058559A879C547CEB9641581691DC1DB5B6
-:106140000EB8CE7F68E5EBFC87D608EBFCE5EEFDEC
-:10615000289FD37E084BD16DD2ECDAEAEC507B1944
-:10616000F4D649EC57AF8B313FCEC57E07B6CB3C5A
-:106170004DD91997B7CBD01E43FED3EDB1BF5A8D81
-:106180007664889EFD4AD3B35F5DA19EBD80ED4ECF
-:10619000DD1B8868C724C891F5DC381BC77F952AAA
-:1061A00033CAE31B209E9F6D8B6C1F0EB40E5DCE19
-:1061B000CFC88CD6F954D7EFDCDF60C532ED2F9C09
-:1061C000D9E07F241BF729E38751DEED40FDA4AE23
-:1061D000F8830DF1ABE36D88CD884FC0A3D3C6F92A
-:1061E000C4698B640F96031E4D063C0EC7F603D997
-:1061F0008357ADDF4B8CE76EBA357C839E9771BCBD
-:10620000AEBB3ECEC3B845E5EC73A4E7AF7A9C398C
-:10621000C67544F7BF611C01E7DF7DD77F6B71B79F
-:106220000E8A17D5BD7A4D0CC6A72A0AFAF48695B0
-:10623000DB8599A407BB7659DC0867571CCFE7ECD0
-:10624000DA35F110C6393EAF399C2985D82D5DAFBE
-:106250001CC933437F5D3B8FE4499420E7277ED1FF
-:10626000DF575CFCCF3C8F123C27D0C76F56BE0E69
-:10627000ADB7F1F8C9D398C7369AB1F7A363F9FA65
-:1062800091687A1C9F47BFE3F3A17E7F5470E5C7F6
-:10629000002B26DD554C66ABE58DA600968F0A6E69
-:1062A00011E355BE91FC3C4D52161B9101FD284750
-:1062B000DB03088EA3A3D78DDB29EAA7EA3E2C0BCC
-:1062C00014EF02C47B5CAF2B097DFC37878DB3A133
-:1062D0005F214DE17AB7777E941FEF294A34B98F59
-:1062E00080AA67670E2F8CC5F77F8BE6F2F258D233
-:1062F00089265C8E7039A038D49B665ADF960D7162
-:10630000272F82EF974D88E77EE905987DC839965B
-:10631000C7E367091407B9007881E714FA023EB5AC
-:106320004BCC173316F4B089B955F00BEC9342EE11
-:10633000D9C1FF6876FC604DFFF6384D3E33E0452D
-:106340007619DBD509EE0C5C4F7781FC0D03FAB4AE
-:10635000D558A97CAD464D1806F2B8A72689EAAFF4
-:10636000D738A90CD48CA0E7FB6B5C548F36B5A74B
-:10637000D37A2C55AF9B87FEF5FD120BBDB723BC1E
-:10638000C47B568E87C8F9972EE69300AE2F353D15
-:1063900052FBD638E2AFA7C600D431FDBFFFD98A81
-:1063A0003F644D053D98FAA3C35953418E9F12781F
-:1063B000FE021E188E742E552F9F32B7C4A2A9F06C
-:1063C0006B1BF34D4DC2BCC8DE3F158E61CCF6E8A9
-:1063D0009FA64E1D09F3C7FDFE14C6F6DADEABC755
-:1063E00073D8A9FB3FAB8B81F9C86DFC3E9F8982B6
-:1063F000A756407D339BF30B933CB598CFD97337A9
-:1064000073E2FEBE3ECE5E1BB71376DBB89D3951FC
-:10641000E0FCC1E6CA5A1E416F6EE8BA11DE3EEFDB
-:10642000C0D7748F0F8CB72FD5305E2FC51107FAE8
-:106430002E75FFD7B48E5CE9773D1F49FC7C84C480
-:10644000F32BBAE6266EA6FD78681FBA8FDA2347CB
-:10645000B6D7DED2D68106EDBEB79F65F07283A6B1
-:106460005724C6F5FF6BD105BF47B961DE38DA5F47
-:10647000AAD3E209933A7AE5F9767E2F5C3ED413EB
-:106480004E78043C0FD7A5D13355601ECCFF486031
-:1064900033840228DD36CFDBD84FD2C24DBE97D130
-:1064A0005ED86571A2D9A3E3ABEE03D98AFA216164
-:1064B000CF31DA8FAA133A64A4F7978F7C4D71CB52
-:1064C0003A737532D56D171BB0FEB4BD7A23D699D9
-:1064D000EFEBA96F003F0CD6CEE1E313D463BB9082
-:1064E000E829583B57EF067ED865E6F52F1F394B54
-:1064F000FCB1CB5C3D9F8DE1F57A98EFAE586FAA69
-:1065000009549052FB65FDE19BB0AEB7FF92DA777C
-:10651000DB546E3F2ADE0CA47F5F5D85BA3DA42E5E
-:10652000F13AB3F2529F5FC581AF297FB8720FE78E
-:1065300047C41BCE13EFCDC375E98C7AD451EBA4BD
-:10654000B87336D7D701039FE9E753B798BC2C2A15
-:1065500044CF5E085BFF42CED9B1A88490FEB43828
-:10656000763A03BB342B186FCD642E2A87310F95F2
-:10657000D9DB96EE47B42DBBAFD5897A2B3ED7FA3F
-:106580008097E868F41F9ED0F4E2FAE8FC1BA301B0
-:106590009EF582778D887AF165B34AE72F3A24B267
-:1065A000373BB5358CAD3053BD5C3BF76D5EE95D77
-:1065B0003312F5EE2293AB19D7B30C4FBE19BE2F91
-:1065C000DB9DE1AA65C1BCE7B2D896C4B14A30EF01
-:1065D00059AF3FAAF1D946B5C986F7D2E8FB439532
-:1065E0006DEBD2717FFBB37D1F903CBD1F95417C4D
-:1065F0005CD17A44F6DA69BF4CC6F3299FD9FAD642
-:106600003F5AF7BE6C19740BEAF52FEB4D74B8794D
-:10661000203DF406E83F3738C8876AAC54FEC25DB7
-:106620007D2D9ADE055129D36C60B4BF90E9569157
-:106630008FE6ADB9A6C10A7CF482AC8E443E9B17AE
-:10664000954B7C5B162B72BE64B907DD92B6CF0DFD
-:10665000F5D43565D3BE533CBEC8686F546D5288BF
-:106660000FC00EC8473EA8DC60F2E17EA2C9DA4E38
-:10667000E77DE74531CD8F369E4F5CAFE93BDF6C60
-:106680001EDFBDDC39C592F351741E51AFBF1FE54B
-:1066900024BE28917CB4FF5572DE41E718BFFB3859
-:1066A00056C379C8FEE32804873E4E79701CD25742
-:1066B000E51FEC273FF88D6B757BD64D71ACE53B44
-:1066C000B4FC059B7B30F6F3B4A62718FAB18077AB
-:1066D00029A3AFEE9340CF1CECD333F90D53D390E5
-:1066E000BEC1F76C92410FB925A0D3C128ADEEFB16
-:1066F0007EE4F65161ED33F5FACC86A993FBC3F342
-:10670000B42D58B7427BE91B4B5F1DE1A373F5A184
-:10671000FDC5E9E3DF4BFDE9FC971AB5F0A00FF8E2
-:10672000EF60AC271FF37C7A673327CAE166498D97
-:106730007285D021358AAF3725E7AF35E03F88F73E
-:106740005C03FD4FD5380DFB8A8B8B96D17998541D
-:106750009D5ECCC7CF776DCA32EC27FE7F38AE1670
-:106760000EF700704CFD07C331C2305E108E1C0363
-:106770007C570B87183B6B7A06DA6B8F98280F28AB
-:10678000D1E4B366A25DF66F268AA70C673C0F883A
-:1067900029E30DFBB4997B2CF331FE9E29B1C3D2C2
-:1067A000589427B7B316D7A99F48645FC173AB3914
-:1067B0000E876E72E3FD4F2095D45F66B9B7821FD6
-:1067C000F2E6FB82FA3ED37095E5E3BDA09BA3E71A
-:1067D000DF188DFB66731EAAC23C98E795F12F3532
-:1067E0003083BC921DD2202C253BE3ABA8871B70C5
-:1067F000BF767014B75B04F670C3E1E448EFB9BC30
-:106800009E5BF3F0348C1B34AF745E8BFE53B3CDC0
-:10681000DFB21FF3761E53E8DED6AC47FD8D9950EC
-:1068200017D79968BD1463FDDB9A71DFFDC96C173A
-:10683000DA11CD68BF60FB4714F26B56D538D3F040
-:106840007E923A6D1DD8B276B28A79C1F58A1487E4
-:10685000EBDD2A73F55C3C7731EED18D0DD6EB5133
-:106860008FB91A07A9BC9E948CEB9A33D33A467B16
-:106870000FC868AE75A6A8B1C1FAF06FC0FA203D86
-:10688000B3B1C19D86FD2E2BD5FA3B88718A17E2E4
-:1068900034BC68EF33FBF4D2C606CCCB126B83F565
-:1068A000A930DFADCF723D3518FA47FB0BE6E3C3E5
-:1068B0007B057B874B744ECA06633B607EB691991D
-:1068C000B4DFD70C7A11EF2BEE1DC9DFEBFB34F2EE
-:1068D0007013EDD3607B5C6F6CC9BCBD3C83DF572C
-:1068E00020DB158A37C07A3015F39E14A6FF71F3AA
-:1068F000B8A4B68F1185F70184F0A375ED323AF78D
-:10690000691D66DC9F97D38C75897916A0BF27AA6D
-:10691000C6E737466BF94183580ADA6DC34D3E131B
-:10692000B61BC9FC545EC702648F8D621D541F8D57
-:106930005E63161E5B72D241AB71CC2DF238AA4752
-:10694000443B3171AE1E47F24E41BE74476B7661D7
-:106950000AEF3F7EC62CCAF7F569EFCD33863D318D
-:106960000DE6B57EC6DDCE50FB4E5F2F75FBAD4804
-:1069700083F9CB6821A2BDA0DB7545365E4F98E553
-:106980007E7A14C611DBCD26BC9FAD588B63166F83
-:10699000C84F44BBAC68DF5CB287D74473BB6CD1D3
-:1069A000FA19B277149EF79A4F767FFEBA0931181A
-:1069B000A76FB0B962AE47FEFD23BFDFF54AEDB168
-:1069C000E6C46B0A501E9BC1AFC6FB8F0E9ADDCA90
-:1069D00018E48B75C3C8CE6C8EF2D6C742BFCDFF0C
-:1069E000EA74D541FD6736F7F823384E43147F8F9C
-:1069F000F726216FF6EDF73F2F5C8C1E78FCF0FD3B
-:106A0000FE83B191EFF1BD43C35FD0FEF090DDD9BD
-:106A100060F6C4DC87F0BDCBE779D6EA89512F1147
-:106A200067FBB486E70376D6B85840E6F7D162BD77
-:106A3000A4683FDDAF5CD22250DC7C096B223D3A7A
-:106A40004C89D5EEA731E6C59616BD4DED4B5B7969
-:106A5000FB32D642ED757AE1BDB501831D3ACEF029
-:106A6000FD1DD1DC6FDDAC781F43FBFF9119D9C44C
-:106A70004FC06711F32DE207D877B9319AAF1F37AE
-:106A800062DBC8F628F163B87DB85CE0E7B307C203
-:106A900053D57993613D0ADE9F21D37AD4ADF9496C
-:106AA00087937CEB6F84F97F9FF54A24A7DABD2397
-:106AB00075825F42F9FABE33ECDE1B2D0F68BAA671
-:106AC00025FE43CBEFF93E6B79C30DFDDCCE02F41E
-:106AD000DD61ED9E1214A4487919D0AF411FDC3A54
-:106AE000C258BFDD65ACDF3929F23D7D6B6BD4B494
-:106AF000D07BAAD60E708EF32D8D5E577FDF120BE2
-:106B0000CFEB7B0BE95E81F994B47FC1F3FA141BE0
-:106B1000F3A01ED9BFCF46FB21558ABC1943165599
-:106B2000E0EFE2BDF08A9D9F3740FF17E3058A99A9
-:106B3000B70FDE97C4F751123C495A3CC3953463F2
-:106B4000D4B7871BFD2ACA0B96D846DC770DE627FB
-:106B50001AEFEDE88AFE380FFD6398CF6C8C4FE892
-:106B6000715A7D3EFF287F2C5ABBCF399C6E6B3407
-:106B7000F9A80BA3733DD23907DF73B9F952BB876C
-:106B8000FF29C143796889261E17ACB3B98E529C80
-:106B900044F30FEAB4B806F37D5DEF56C2EC9510EE
-:106BA000FF227DEDD7F5F539E477F338882D6A15A6
-:106BB000AEC30D36BD6EA6FAD3E6A600F9FDAF5AF8
-:106BC0009C181F83EFDD1867F3CD1D417E5D5D06C8
-:106BD0004BC17B0EDEB0CBB4FED6BD6A69C6F5D81C
-:106BE0006DF376DB42F249BAECEFD1F9A608FDF974
-:106BF0000CFD0DF976FDC1F8AD8877FDFD1BF6A7FC
-:106C00000222FFCE49F91B69ED1F7BA19EB8CB4242
-:106C1000714FFDF70FCACFE7D1FD8C7A7F13144E69
-:106C200087CE1AD5908F5D8E7A3707E5A09DF467E1
-:106C300045CB2083DED4F569C5F91B68BF2C4857C6
-:106C40002D2E21B5935EAA38FFBF68BC3B909E34C1
-:106C50004E12E9F781C74935E8E3E038930C70F745
-:106C60001F6732C1A18FC3DAA20CE79FEBCC3CAE09
-:106C7000726698332636821ED14B7183C970FF60CD
-:106C80009DE4B262FF75CA4E35347F287C5F00EF09
-:106C9000C56421F0D5C17A86C1720BF3525E403DC6
-:106CA000F6132207A2D9A562BF62C2F8E9F92EC67F
-:106CB000FE45B9BD107D7233F22DD88B3F583B7E17
-:106CC000950FEC49C9EC6947BA4A769313F3686BA0
-:106CD0001513C545EB92AC64FFAD12CA559473BD54
-:106CE0005FA9432238F47D8F81E6299F77D03CC38A
-:106CF000EF3BFB9F1B4FA176FDEE573B30D7930F29
-:106D0000FD5B54930B455D4E53D82721F40FEF479D
-:106D1000DA2045EC27BC9D8EFF01E96CEE70203D2A
-:106D2000BAE3A58879101B95EF9807312F4C1F27E0
-:106D30001CCD0EE0F74287232383F4E54605F5A535
-:106D4000FDCC9FDC4ED2CBB4EFADAF7FE684A9562D
-:106D50009E4F6CBC576F20FED3F1627DF341C6F3AA
-:106D600053BD947F72393C4882CB43FB007629E2C5
-:106D7000BE36584286FC384931E64F35481EE2633C
-:106D8000F34DD556DA27495B69C57D92D592330616
-:106D9000FDD8DE37C1FE83F9353A79BE6A78FF6BDC
-:106DA000F01E66B4731553C4FB79A306B0AFBA34B2
-:106DB000FAACD97769FE01F5E1C175372A4E5271F7
-:106DC000DD359B39BC03AD4B7ABF03E1EBD17DFCD4
-:106DD000F71B2C39563FAEFFE1E3354A1E4F3EBC50
-:106DE0006F047870DFAC31CD4DF86D542515FDD5AD
-:106DF000E81151CC1AEA6F65CCA2F767E2E3F1CC57
-:106E0000226B8C8F9C97A3E369B7F21DED1D6F1861
-:106E10005F0E7F8FE2E8217CD9A94CE8CF97BB9128
-:106E2000171338FCA1F7A65A338645BC7FB21F7FE3
-:106E300086F14DDE6446E7F70643B919FA6ED5EEE2
-:106E400043AAC0B50BFCF4F27B14A6C2FAE677E4C1
-:106E50005F4039C96BDFCFCFD1B426F07B1EB5EFD1
-:106E6000C3C75D62E7FEC812BB4A65CC51F72FF17C
-:106E7000F7375ADBA39C785EB1352EB21F9363D7E8
-:106E8000F3689AB473081DB44FA1B7CF9BC7DCCD8C
-:106E90000AC53D1BADE07F25F4B5FFA9B63F0282D0
-:106EA0000BE3DCF9DBEB9AF9F9513E7F8CAB62FB2B
-:106EB000C4C48E5C41FC0E74DBC60CF7DB55583B3A
-:106EC000B251CEE79ABC997618A7EA684722D65BFA
-:106ED000DF3E9D4E7E6F1DB7377B774753DCA03F6B
-:106EE0007D6AF979F2F329CC37A83FDDCAA500AD58
-:106EF000ABE5E7D3996F1CCDDB678D0BBEBFD3C26B
-:106F0000D8A4B1C8001C4F889F48F430DB4D067AE6
-:106F1000803C5E67D7E88178EAA3B776EF4BA77627
-:106F2000BFE071CD5F612AF7D7F5FBA58E67F7E566
-:106F30005BD07D5BE536F713784F0B3B2252BEE604
-:106F4000C229FCFEC48516770CDA570BFF53146A6E
-:106F5000697F93F3FD220D7F9DCC45F70EF8D6DABD
-:106F6000F8BE4E987F96F154FEB83FC2F78BDA44D4
-:106F7000CA1B5F3045F161BF79ED05BFC4FDF9E281
-:106F8000C6683A77BEF07BAE9368D72D7CC2E6C464
-:106F9000DF7B59FE41667E32F4BBFCC90CD507DFAE
-:106FA00045AFF024595DA0271FDB53887E45833011
-:106FB0007FBE3006FCCAC70EACC2B898F4CD94CFE1
-:106FC0006D507FF4B1775661BCE9B718E7263BF600
-:106FD000DD42B4635F42D0F4FD3FC0C14B874D5AE0
-:106FE000FDC4AAA9A0F2AF4D6835292AFA65275633
-:106FF000E139D9C438F718138CF78EFDB342EC6F22
-:10700000C113A3CE6D80F7E7ED17C8BE003A69DF64
-:107010000B374F01BBBB78B25E972D588F8F6686BA
-:1070200038BE3933383EDAD9AD7A7C8B45DD8C7188
-:10703000F7E305D55324E83FC3A1AECE19C9D8C4A0
-:10704000F5F9AA1BC6CF76C4DD8CF198D6BE7D8338
-:10705000F8D5181F6B65DE0366787FD3E3436EB601
-:107060000262E30779C6A830FF41D629ABA7DFF457
-:107070001DE46344BFF3590DF60492934388D2F4A0
-:1070800015FCDEC23EF94EE37CDB571FD1C1CFC3F6
-:10709000E8F5245E6F5D19595FDC12C3F9BA352A31
-:1070A000F2FB664D3F00BE03147F6D8BF60FCF08D9
-:1070B000EA0F901FEB2492A7755C7F801CCDB493E0
-:1070C000DC46ECEFDBCA6BAB76AF79ABE48EC6F88F
-:1070D00082AEC7308286E3CCB53B0DFA39AF7D0175
-:1070E000E9D751312A87C7C9F19330C5A84798B568
-:1070F0003D3B74DFFE77DA3C33AED3E33F013974B6
-:10710000DF69F98EFC4B9E9F2DC7387F88BD1D9C83
-:10711000C7548A67F4EB17FA736AFDBB72AE045F5B
-:10712000EA65F0154FF8BADC3C83FD19E32FFDFB4F
-:1071300093B57DC126E33A224786F3A4CE27807F0C
-:107140005388FE2CD6F4A99E07D1BD6B24E54F06CB
-:10715000C7E5E73181BEBFC4DF5DF2813E453D96A4
-:1071600027B96FC5F679ED712ADAEFC06FF51ABF4E
-:1071700049C86F3A9D5BE3AAF369BEEB04B24BFAD0
-:10718000D941DA3A9AD724D0EF990D9EE715E787CF
-:10719000C0A7EB7BE8BF55EB7F3CE7E767FBF8F95F
-:1071A0003E941FCD9F67AE0EBA5F3D1CFE852873CF
-:1071B0000921EBD5AB368AEBEB78BB5AFED7ED85D0
-:1071C000F201D725077D37F868C0E184768B511E20
-:1071D000505FB57C42F764B6B6890C7FB200E78D8C
-:1071E0007A234FD793BE95870A24B25B827AD94916
-:1071F000F68BAE3703566BB0FDB9B52B0BEB51AF29
-:107200006AF7ECC78BA0C5C706E1487370BB7792DD
-:107210009745FCDDB81CBB5DD723348F8D2B0AE866
-:107220005E852A6D3D9DD4E1A3785334E27142100E
-:107230001FFA7A7DA7A5E315EDBC97811FF53AD813
-:107240002595A6AC60FFF87E6608DFE739381F8415
-:10725000D3E7BBEA27C0830FF1F0430DEF0950C716
-:107260007B2D9804EB17E6FDCC505C6B3242E05668
-:10727000B83E4E104D5C8F5D462EE20731EDF7585B
-:10728000EC24CF417C70BBE5018716E7D5EE293FA2
-:10729000680239A17D363ECFEE5DC9D4EF6CADDD1D
-:1072A000DF4B2F6FD6F296747BB1E2B5D4CD46F8A2
-:1072B000797FBB1C1C2F7947DD63D08E19EE515CA2
-:1072C000E81FE4B5CFDC8FF924D97BF00704827C7A
-:1072D0009EDDC2E514B84BC3CB9BDB43FBAD74D83A
-:1072E0007539FBBBCC23FB28E757A4CB7D21725A11
-:1072F000E35038BE607E16C4A764D4A37AF9F7833E
-:10730000C3B31FCF2595033E506DEB786B6D99BFCE
-:10731000D286727C94B9508EBB5BE69B46215D3170
-:1073200011CC19A21FD6F379E87628F0650BF2E5A7
-:107330003AC7101A6FF85177740EBC1F8E7613C6B9
-:107340007D5BEC7EF423FC0EEF2E07E27356EF1408
-:10735000DC4FAD8CAEAEB5853CEF6BDF06ED898FB3
-:10736000BD22EE1F953FC0F8BDF1DA7CA0A9CF0287
-:10737000E355C820A759540F20DE5A65DEBEF73EFC
-:10738000FAA5115629F27BF960FDBE95F8F36D530D
-:107390001CD217FD24B493CB454F1AEE7BB2C11615
-:1073A00017AE03E07710BF1FB431C906FDFF1E4AB8
-:1073B000D4D3D3C4A5748E6B5A9640FB44BA7F8F46
-:1073C0007A0BFDA43BBF174DFCC82E3C380CE3D311
-:1073D00009D19C4ED08F55EBC76A1D1B94BFFF4847
-:1073E0001F49FE8EBEBE1D1404EAE7E04DD735D717
-:1073F00085F841D81FEAFF83C28CB4A5C8FF9A1F45
-:1074000047F6617C70DD457B65AC21CEE6D3E0EBD1
-:1074100048473E0AB547D13EEDB3677DF357DF0CD1
-:107420007A76E2F496005E715FCB8A6EFE17E86FA3
-:107430001AD8B336C0C33E8D2F0E66F844DC4F3DDC
-:10744000385CA0FBDC0F457973AA95E038895A5C5B
-:107450002051CB334F8CE2E50F62B81EFC3C86AF67
-:10746000D737A8BC9EE8881C4798ADBDFFA989EB1B
-:10747000F735F991F3D14F68FAF5AAEDDE1C21FC3E
-:10748000BEEE138E09DA7DDD946FC7E3FD0B34FE8B
-:10749000063B87E814B4ABF87E9D6E879E6D9F4DCA
-:1074A000F51382F7BD7B042C3D4F909FF4AE48F15D
-:1074B000A1E2586F22E6A55544458ECB0CD2F0F4DC
-:1074C000590DA338EF29DCCFCBE6BFB785F5251BD7
-:1074D0009EA47B1D4A999FE2BD451B1A68BFAEC89A
-:1074E0002F30A780FE9987C781353A946E110D71B0
-:1074F000E7C552B51C9B13E45BFC1DAED0F7259B82
-:10750000C619EA576F971618F23B827AA790ECBF1C
-:10751000F07E753E0FB74F8FD7380DF1EE051B8605
-:1075200017F2CD78DE7E2173D17C17366619EF1104
-:107530006E4CB8B27B82C11EF545845326FDA83F30
-:107540003F0EF8F785C4F7177C3A8CE0F88BC37BC5
-:107550005D8C018E68E633C4CF26F3DF29B4F1F8E1
-:1075600023F08FEF5276407ECC77F507AE1DC01F1B
-:10757000C8FD87FA037993B9FE654D02E5E04C9C9E
-:107580006AB4CF66C7F0756E764CB4C13E2B9A676D
-:107590006C37576B37576B77B9384AA85D2664A1AB
-:1075A0003EE3FDE9BF1F9571FA6DCAFFDC10C3ED24
-:1075B000D79FAA6E6F0CF4BB563B77D06FDEDAEF25
-:1075C0004AAD35F7E585525EE0E66F1EACC3DF09D4
-:1075D000E9DD01F63FE8C1FC67DFA07BBAF4EF6E9E
-:1075E0005FD132B408F054A9C973B98BCFAFDC15A1
-:1075F0009087413F29E51CAEB4967D8214F25D5A16
-:10760000096FB722C66CF02F7FA2D5FF35C649653A
-:107610005A49401806ED52366D1124EC0F7F570B76
-:10762000E049A966FED0DF934A19CFED9ADBC76F18
-:107630001616E604F1D0689A91A3625C3531DA85BA
-:10764000EBCC47AAB70EF150FE5180CE494CFCA8B6
-:107650005D42BBBD5B75D7237FEB78708A6A0AAE4B
-:10766000A3D11F71389BFAFC62BEBE30F6A86647F4
-:1076700037EB76E961C6ED425AA712578E30FC3ED1
-:1076800061629CB64E2432EF4E85DA3732A227A3D0
-:10769000F924AECC6EE6762CA7F7B42CCF167C3E40
-:1076A0006DF0C8B178DF47D6DA8084BF3BFEDA26BA
-:1076B00053C4FB519A35FCC33C9EC5F9E9F3B89C11
-:1076C0005ED0DB9907884FE8F2103D3DB2DFC1D8AC
-:1076D000E3F43EFFD9F87BE9FECA7A997E4F4EC7A4
-:1076E0007FB7EA6941BCA6B46C160837DA787ADC51
-:1076F0000E9FA35C1E978DE73A0794FB153B8716F8
-:1077000085CA7DBD4CF4D91C96E7AFDBF77F88E1D5
-:10771000EBEA9058CF3EC44B65DB3A8AEF2CD9C2D6
-:107720007FF76740FC5C21FE8412EE0794CFE1FBFB
-:107730005EF9CF4A44FFB27AFEFBACE5DB77F0B8E6
-:10774000CE8F990BF54379CB0EA128077F0773875E
-:10775000B028049FA9E57ECA83BFC6AECB1FD75B06
-:10776000E1FC8E7162B4530ED9B87EE8CC577CB878
-:107770001FDC69F69663BBCEE46817E677E9F8FF8D
-:10778000FD8E9BE9DCB57DA7258065A3A939C98A53
-:10779000FB0ED7CA2EE4AB6ED57B12E91327795ABC
-:1077A000F1FBD878BBAB16BE755AD85855B9723CA8
-:1077B0004C0CE38F893FE67293A43AF4BC86B12463
-:1077C00037AA9DEB2D13D76787CC7C1E3B1987F713
-:1077D0000731EEB3248787E368DC94F2009D1FCA6B
-:1077E00038BDD370CE30C85FEEBF7D1B7EFF3F2C0F
-:1077F000A14B2800800000001F8B08000000000043
-:1078000000FFD57D7B7C54C5F5F8DCBDFB0AD90DA6
-:107810009BF73BDC100C28246C9E0401D924848740
-:10782000206E0228C86B7947926C02D2FED0FA6DA6
-:10783000168331E56B6BD41645A92E8896B65A830C
-:10784000A2060DB82822D64723A58A2DDAA5202224
-:1078500084641BFBC056CB6FCE9999ECDE9B0D0F59
-:107860006BFBF97CE18FC9DC799F73E69C33E79C65
-:10787000991D33B5CDA88C22A4A69A38BC342DFD11
-:10788000E90EE98485900BF06F2221836C3221F19F
-:1078900084A43CBD4D522C58BE7F5A1CD6272605C9
-:1078A000BE4BD8AE8696AFA0A95B22848C25E4A0FF
-:1078B0008178CC3184B4E82A47D968FD9684487B26
-:1078C000132D3B667345DB687F96639D07ACB4EA76
-:1078D00098633EA38BF64BDAE9C76442DE3012129E
-:1078E00041DB1D8C60EDD36D74902242261B89070D
-:1078F000BF1B3D2314DADFC1A183B0BF97B7EAA64F
-:107900007A697BC320B2D81932EF749B0EDBA56C69
-:10791000DD21E9E8F7B8485A1E323F51EF015B59C3
-:1079200026CC67CCD44E8443DD563DAEA7C2E81CBE
-:10793000B66654B0DE68E88FD67BEDE64F8C7EFAF3
-:10794000FDC72FBD6F2450BF5572B4C1FC5BDF373C
-:10795000CEC9A1A9E7E7324920643A61FF36BFF0FA
-:10796000BE51A1DFA7EFA670A2F5EA76EFD22FA352
-:107970006957A9C5238D2624F3CC6B8B4821FDDEE6
-:10798000662211746EDD3657918DCEFBCD5D530EA0
-:10799000495184589F33F92015F021C49FE1B40662
-:1079A000E725523A30CE2F722AFDB310B246EF557A
-:1079B00099F0DD955945EBB7C630F8CC1FCCE042C5
-:1079C0002CEC7B155F97800B1D7F0A8C5F91E5DCAB
-:1079D00001FD542446D89B32619EF9AF9929DCEB16
-:1079E000EC923D82568D2B67F00C9D57654EB87911
-:1079F0006DC0F1E263D9F844EFCF807109F1B2EFC5
-:107A0000326921F9C1F67338BEE9771FFB4E863A19
-:107A10007382F3D7E26F834DC2FA61E86C11ACA3B5
-:107A2000F698CFC7E8AC530F749679E630E243D0AE
-:107A3000CDCFB6EA3115FDD5D98CD85F9D4D8F706D
-:107A4000D90C781A4C53032C9AA61BCC5E0F85C711
-:107A50009BF3261F9272297E6E31FA207D43B7B4C4
-:107A600016CADF4861E3B7E8746B21DF729785348B
-:107A7000215E1D6E98CF6B3747217E6AE71ABD26BF
-:107A8000DACF8F9F9758DE63F112FA67AD6BF6720B
-:107A90006847E222EC4F02FE5C078C73ACFDE94ABA
-:107AA000796EBF51A1DFA7B7B1FD27F050DBC6E863
-:107AB0004BEC0701D7203CBDAAFD24F0317FB08DEF
-:107AC000D105A5178077CDCE08DB49331BEB02012A
-:107AD000FA8C56E5EBDB936D274704F335F007D0BE
-:107AE000C10E628179D6F279CED3B9EE83FD5567A6
-:107AF000F61F3450D4161F0DE07E1F887E6BD6FF14
-:107B00003AFB640121AB930E612AF6AD61A87A7F3E
-:107B10006FE5786F8294B67B82D34D4D611BEECBBF
-:107B20009A930DB89F2D53195FB31C238E503C13AD
-:107B3000F243BEDE7BB17D4564DB6499C2BDE27178
-:107B4000C9D644FACF4FA4AB24E26CA3FD7DB6F5B1
-:107B5000F5A82500DFAF2EC8A498AE3782AD7737E1
-:107B6000E73B5D3B29C091DE1B8C24CC7A2FB73FCD
-:107B7000E23B22013C6B38ECBB9E2E1FFB29A51774
-:107B8000CFCEC1F6ABE892CF3E3DEBF64FE9BCBBA2
-:107B9000764CB4CB40364D4EA49F407C847D3BA5B3
-:107BA0009F38994C9528DE37B4BD1E358EB6FBFC48
-:107BB00097A3F3816FBFCDF7FD99E7E5F50097BB7C
-:107BC0007EF6EC75505EE395624D30CECEC7FF95E4
-:107BD00042FBA9DE510F10264DBF7CD5E8A7F574F6
-:107BE000DE6DECFBCEC136A8F7F913F75F07F06E38
-:107BF0006A6BC2F2334F6CC3FC6B3F7B76DF3F682E
-:107C0000BD5A67941DEA9D797E3FE2A5D6A577C04F
-:107C10007A07A2EBCDBBF6337ED926E17E2373191A
-:107C20001F13742DE8F7F39F2D1E1B2A37C4F71678
-:107C300023973B83981C39CBF76F4D99A505D2B399
-:107C4000CF44CC85F5BA8DFEEC6898CF2846171F37
-:107C50007178D4B6AD31B82DD81EFBF980EE7B48D3
-:107C600073287D9EA2F44E6BEDB85000E3FD0AEB45
-:107C7000D37A251114BE372F382EC17C22473518F0
-:107C80006A709EBF64E574D5A1E5C5EB183D6AE94D
-:107C9000E00B9B05EB8B7D90B2BB324D413E60B259
-:107CA000333ECED69752ED6AB2D2EFD7AF73D965D5
-:107CB0008AC7974F1F9E9C4AF33F1B211520FE65E4
-:107CC00089C9398F05C7A95B5F464ED0F9EAA2D9A9
-:107CD0007E49B011FDB5C807B631BAD713BD05F25C
-:107CE000FA00F289BA162E0777B0791273206396DC
-:107CF00015DB59AE8D09CE83B6B358301FC8B829ED
-:107D000007E48E672ECA1DC588F33D23F801F1E410
-:107D10002ECC09EEB7041D7101FE138C34B5307EF4
-:107D20005349FB4F8F2E4D8A2E0AA6098358B91648
-:107D30004EB7F0F21F453B92A2015E3B6355F260E5
-:107D400020BEF2DACDDD4C6EBF721CE9D00D740896
-:107D5000E3BB4EAAE4F67264AE940EF71C473A5C9D
-:107D6000DECEF8ABBBBDD4B88CA69B253217E6EFB0
-:107D7000E6F4047464A7F99BA2A3717DEEEBFCD931
-:107D8000C0A7BA39DD75EF61F4F6864EE701F8BC9D
-:107D9000B17DE43690075AF928553B11DF6E8A6FA2
-:107DA00093047AD6BAC3A067D555133BEC57F76E48
-:107DB000BE1F1A08EE07777BE572E82F356E9A5DD5
-:107DC00096502F999C4AF3EE5A5204FB2D656BD9BD
-:107DD0001EA00BD22E91AB205FEDDC0DEDAF8FAB73
-:107DE000B3CB9920F7B6279969FDEB471463FBCD18
-:107DF000E94A29F4E7A920B627216F70A13CDB9C52
-:107E00003CD20EF2CEEDDA887A175106D9A19CB891
-:107E1000F46BA1BEDBB3806C92C2ECE33D9203CB6A
-:107E2000BD91DE08DA7E7A3BD37FDCED6C1F9F13B9
-:107E3000F011A9A173118CD7FD828978A4209DBD72
-:107E4000B9670A93B32F9A50CE9E6D749013543431
-:107E50008F8C5610AF028E35AD993AA05B42669971
-:107E6000601ECBF83C5A0D4C6E44733990752F9BB5
-:107E7000C772BE1F9647EB786AE4FBAF95C9059BB6
-:107E80002717E4E0393E1E924502977374E8BAE57D
-:107E90003EDC27B54FB3FEE24C8EBCDB42E855E832
-:107EA000475A7A6CE2E3A66C3D20013349D95AA5C2
-:107EB000DAE7D757135F3D5DE7F55B75BE89B9A873
-:107EC00037DD82FC7C83916C97FAF7774F34E35B64
-:107ED00015B1CE3C09E4D7CD16D43FFAF6E9208798
-:107EE0002E02F4B87CC9DE84AB7016EA68BDD309F3
-:107EF000563BE0ED471C8E5A7DABAFBD460F9CD183
-:107F0000EAC9254369E9864173019E545FB798A188
-:107F10009D8DB6A7F512B68F7B6213F2AB26ECF7F8
-:107F2000F6681BEB27D659D8002C2ECBB98EC92763
-:107F3000AB3DDC7AD2A3859EBD284F07F433DB82AC
-:107F4000FBE1C7AF484B19BD514128013DB2FD418E
-:107F5000E8FE7852417A443DCADDE0F486A747B690
-:107F60005FDC54AF023D9BD2E35AA6275B08DB4F90
-:107F70008C2E23A73279007C2B549F15FB54BBEF2A
-:107F800005FDF6EDFBCBDCEFDD06B61FBB291C8043
-:107F9000DEFBE8FC6546E79B36D0FD48CB37D1FDDC
-:107FA000D814C2FFB5E71F98279C0704BF3D66732E
-:107FB00076005F746F7FAB19C996F347F7CB3FC864
-:107FC000BE98DE6586CAB45F33DDAFA1F463A6E078
-:107FD000B6E663EA013911B95EAD4789F4836826D4
-:107FE000BFBEB1DE3842D2A3DEC3F155AB737D0014
-:107FF0007C1EF4464A1124633DD31B1340E600DE89
-:10800000B6477A413F4E4820AEE7C2CC673FDF67B4
-:10801000029FE2FC9010C5EAF7F27DFF29AFF74F0F
-:108020009E869C4B703F283AD771220F2C8F443B81
-:108030003A2F2C17F3E93BD798D97C13EECADEBE52
-:1080400029048FC17D75753EE037EB5E9F7EA925C3
-:10805000388E908B5ABA81F983FC81F5548E1AB808
-:108060005EEB7E7E3ED3D07104DF5F7BA8B882B426
-:10807000D5E0FB2BEEC7355602FA222507472C9D8B
-:1080800057FDBEE16C1F8D086443FBEA58D74D31A4
-:10809000B4DF3193F8FEA0DFABE09CA0271E530CA9
-:1080A000E0DDE0F587E0F9D318D67F8FD5EC91E9D4
-:1080B000FEB823D6150DED3D65C4EE03397307E513
-:1080C00027B06F89AF08F84D3DF147019CC7585D57
-:1080D000F13140BF726736C9A2FC57F2E7C2F763BD
-:1080E0001151B984F6F371FB6F9F7985B65AF8CABE
-:1080F000B985DF03FA7A312203E8E218D5973B51BC
-:10810000DF560683BEDD4B94C1B630FC57A40BCCC2
-:108110003AB3BE20983F66559F2F447A4D0CC36FEB
-:10812000FDF914E28985FE099EBF7B6214F65D1F8E
-:108130003082EA567F3E8378687F1FEB48755B98F4
-:108140007137C5307ADB4DC8D470E5F7F171760F21
-:1081500065FB30B04DF2027FAC5EBFE1CF32E50788
-:10816000D5EBAC3E4C6931E86FD5368F4F47F3C73E
-:108170000C8C1FD17FB3CDC541B947EBE9C7030EC6
-:108180003CF4204BF9E0522EB79635BCF925D813B4
-:10819000AAF5C43C9EF6B3DCEC3C984A8B3EB32C6B
-:1081A0008F02B6BFF23BB725805C4A5CD0CAEC3286
-:1081B00064920DF45EC93143BE1079313D4B8FFAA4
-:1081C00031E29FE2EB8B18E74CC0F782C104F580E7
-:1081D00005B7457A3D217CD0CCE1A1A59B4FB87E67
-:1081E000A5ED7F766C1981FE3AA29C73813E16DC68
-:1081F000764EC5CFBA25FF538F025DADB1DA9F64CD
-:10820000DD653843E8FE3B62BCF33AC4534F5E671A
-:10821000F6FA4CA0DF40C68760CFEA30D93C0A941A
-:108220001B11CFA2DD9F1A29E3CB0EE6979E1E36C7
-:1082300019E86B19B13703DE97B544124F083F03B5
-:108240000518E8C37D9E603F4B3BDE3C0AFCDCAD7D
-:10825000F7239D2C355B108FEEF37A9C0769317400
-:10826000F9457B8AFB23518EDB607D9E7BC6479F51
-:108270001A493F26D2EFB87ED7EDF0FDA1C828E21B
-:1082800000FA784BF60EA7F3EF352B836328BCEA90
-:108290008D940E4663374E7388FE43D2AC6AFC77EA
-:1082A000BCF525CC67B9D9650439BEC241CFA73228
-:1082B000E0C957641B158AEFF1F28591978FEF455E
-:1082C0007CBF7F6CA4F41F661FDDC7E1DF23EAA536
-:1082D000B07DF27106A97E0ED26B684ADB7D3C94BC
-:1082E000E7F3793E9BD74B60F91D7C9F7C9CCBEAE2
-:1082F00069C7F1C530FE363BD6B115E045DBF98CD8
-:108300004017FB22BCA8B716527E07FC6D6D3AEAF7
-:10831000AD94AFEDC07AD9C4178DF54C28574803FA
-:10832000E57BB0CF8B1484CFA6524A27B43CB0D79C
-:1083300064DBAE04F12AF0A9C5637B8CF4EFC9C3FA
-:1083400051923ED48E42E5617B0CB3A318617FD27B
-:108350009918999E360CF18574225F3EBE6E8C6032
-:1083600078A0FBF4B518D47B7D39A1FBE504C79751
-:10837000E0671F0F52E3B58AE3E16D5E6F518C8DAC
-:10838000C94F7B00F7DDC731AC7E5C169343420FCB
-:10839000FF0387CB4D9A54C8953153D5FAC54D1C70
-:1083A0009F37C54409BC7E08F315F288F2175F3485
-:1083B000DD0F0B5E35217F211B03D9B0FF68BD6344
-:1083C000586E0A2C8AA572E426AADF18F3B1DD22C2
-:1083D00068DFEF3C3F4AD08595809C3E25D65318F8
-:1083E000407E4FE51DAE6B29A17C43BA34FE37D0E9
-:1083F0003AC994D6870C56D8F94EA60302ED8F20C1
-:108400000AF447E1FEE750B86BC73BC6E9E09F318D
-:10841000921EF19647F2709FBDFF857521EDF29C8B
-:10842000CDECD151BEFFB8CE7501FAE9BAFD2DD41D
-:10843000CB8F197DD9AD9630E546DF630F49C1F288
-:10844000C53F973D46CA2F767776FDE466BAEEA51E
-:108450009DB21D865C7AE75FDF1D037A75A7C10EAA
-:10846000E7462ADFEFD5C3BC1B981E794CA7A6832D
-:10847000B3DF559F73D26219BEA8DE83FA9CE03B3E
-:10848000427EDF4A7C57815C5F461C4648FFB466EB
-:10849000D50C42E1B7C2B20EF9D1E76BA7A11EBC61
-:1084A0009278B07C598BE14FA1F26145AB3ABFEABB
-:1084B0006175FE56AF3ADF677F2E0F2FDFA7C732F9
-:1084C0003A3E4BD93EE03FB0C1E4053D485BAF9832
-:1084D000D7CBA43CB113F82495FB60475817E1486B
-:1084E00004BEBE6E6F69E2C5EC7CF5E7AF21DE101D
-:1084F0007D23A837E4126F6CFF7ECB63158423F4D1
-:10850000ABF071E0BC71B62CFC3A26C60A3D651092
-:10851000F627BE8B7E82E345E13CEACF9B07988F2E
-:1085200005DB9F5D197E9C1BFAC6B1A9E464B07D92
-:108530001C936BFC1C2DE8A3FE7C127E1779A1070F
-:1085400007DBA531FD8AA4D94E4506F994B0638BAB
-:10855000FD704222E664B43BDDCFCFEBF65CB05F4A
-:108560009F003D08F6E314659F9F4E71D9F7C666DC
-:10857000EB8706F78B761D94AECEF843F8EEB25833
-:108580006B1C8E6B27761857D0FBA2DB2B06BBE843
-:108590007CFF786779A26B54283FF530BF8951E89A
-:1085A0005F16959C251A39BCACFD2DD4BBA8BE9591
-:1085B0000D4CE7D3BDB723BDAF24CE04A0F39EBDC1
-:1085C000C3335CFF86FC15F399E559622098A79B9D
-:1085D00098EEBF2A3E9F591D4CEFD3991D061CC72C
-:1085E00041145B021EA5D97C29F3D4D3FC84BEF9C7
-:1085F00083918E90F17CFE12B4A7F09DC053B2D44B
-:108600009504F336C1B874BC08E24D82B469AC5D20
-:108610008174A2E4D4B379303C4F260D69505F6772
-:10862000F6CB6C9D740609D0BE0F5E98B7F2FCC6FF
-:10863000D9BD8B56C0778B15F98891CF63472CE550
-:108640008766E42F6658B7C9E2FB1CFD643CF594CD
-:1086500029B88F3D4309DA3B06913602E35A2CE7ED
-:108660003CB0581BB149908FB0F5FAE0FC70CE6673
-:10867000F1E846239FDC190B7C527A6725E085F2EE
-:108680006566FF19A85CEFC373B7E073317C7E4D5C
-:108690009CCF2513068758E2C0F11EB0AE9C414026
-:1086A0008459D649D07E4BD454F4EF2500E0697943
-:1086B000EC54BD8A6FC53BD5F9C4B9EA7CB24B9D79
-:1086C00037D3933FE88B92CF99742116CF5923C0AB
-:1086D000DE62E0FCA299CFEB08A4743DEF713EFD91
-:1086E0008DF513BBFABCEE8E3112B4E32598CDD0D4
-:1086F0003FD557DE8B65FACA271E289703C8CFF3EC
-:1087000026B6F9C0AED37C8364BF8B7E6FB62A1BBE
-:10871000F494543DD32466C7D1DB4AF5B47C5B8620
-:10872000CDBE89E6EBC17E1D0BF3B7D53C8DF64976
-:1087300013AB4702CDE08FDCB6C966837A71E58161
-:10874000C946D08B5710DB761286BEBFA2FB86CE01
-:10875000F709C853BC489C5E220F29F3710DBC7CFD
-:1087600007FC9DC5F2138BE15CCAFE6575E4753AA2
-:10877000C0EEE090512ED677E4BD6EA1E365CDCE7C
-:10878000433BBCB39CF97309DFF76334FB6A5C902D
-:10879000CEB13C8FE7877570BB6E9C89F96B6D74A9
-:1087A00088626636C0FA718CFEED44FC63FBF25AB7
-:1087B00012FC07FD9507FB473E3429581CDC677403
-:1087C000A87CB3BDA996D61BA3F7ED877D3C8EA7E9
-:1087D000793C7DA3F40694BF9D3A8B62D4B17D6D44
-:1087E000CE0213865306B814DB7ED004FD4C907C79
-:1087F00098664CBDBF09A65FC5ED47D14946EF0657
-:10880000BA8EA6128A67B477FCF920D8A5E5074985
-:1088100001E0E98841C839079ED3157A1CFB1A3A52
-:10882000986C40FDFC2F932AF03B01D58CCEBBD237
-:10883000C61621BE0F2C5F75283F6AE364E437B388
-:10884000A632BF6AFD5CB3579240CE10E677D2BB2A
-:10885000326F0AB197083FC4FB0632775798F3444A
-:108860006D1CD34FAB66303B6FFD46A3CA7F531DD3
-:10887000C7EC5E33E3268F8C4379C4FCA779715C27
-:108880006F1B4146009F0AE1234550AFABF4ED81D9
-:10889000F88CBA9CF399398E0203EAFD9CDF08BE7E
-:1088A000EE1CC4F6F33C42D281AE679306E4FF8728
-:1088B0004B6F457E7313F118006F1F95B17802312D
-:1088C000EF5953D57AD21CA73A7FF35CAD1EC5F0A1
-:1088D00021C69DE7529757093D78AA5A0F5EF0FFCF
-:1088E000BE8A46B99AF854DD8521E0E760F600C0FB
-:1088F0000BF373E8916EDC1B993FBCBE3DEF8D38E6
-:10890000D8677712BECF7649CBD1FFB24B5A1182CE
-:10891000FFD45AAF047264B855D87D98DEE4347938
-:10892000F783DFC359831291BCCEE3490E403C4923
-:108930007E90BEAD65561657411CB5309F345BA482
-:108940001DF4FE165D3EDA655BA2AC2A3BFAA60D6D
-:108950004A05D413F658C544F26D9C6EC29D77D774
-:10896000C531FEBA59627671CF3C339E2BE3B39C7E
-:108970002A3F41BC4C8E829D70649C22EAA3FD6319
-:10898000B3C1955C4053AF44971117D25E261BD1FB
-:10899000AEA8E14FF1B176B4EBC70FCE413BFD9CE1
-:1089A0008E3CB42F124B84FD2A29D8FF9CD9DBF4CE
-:1089B00010A753DFB14DBFDC12A4BB7BE2B85C8DC6
-:1089C000249140AF7D76BAE74C68A77B5CE7FC5FFB
-:1089D000A0CB5AA30FED7121F48ADF07928BAB383D
-:1089E000BD18CA9CF356D0F9F5BC6BB4C3F9191D78
-:1089F0006DB4FFE7F744A39D515F45503E6D2C6574
-:108A00007CA407EC5F741D9F4557E3F960A3D48AEB
-:108A1000F2A33B6632D2F16ACB013C07576FA574D3
-:108A200018229F56EF50E76B48279EDF6B9FEE475B
-:108A3000CFC817051F76EF56B723C3D47C378FCB2B
-:108A40008B7CA77D56054C7DAE3D8B9DC3E9418651
-:108A5000AEA3E81D23B7EF2EB09D8A0056FB947499
-:108A600031FDADC77A5A66FB9FC983223E8E566E92
-:108A70001571BDED3ACABFE0FC2AF4B022C2F2077C
-:108A8000741D72922E38DF42DE4EE87F424E087C23
-:108A90009596105242F743A7E04F43C950C037EDB7
-:108AA0001FF78904914331D8BF07CE7DE3F878944E
-:108AB0001E3C20B73D3AB317E8AB596A4039690606
-:108AC0003D9FA69B2417CA8397AA3D32C07B2C6981
-:108AD000983583D61B6FEE8C0438513A39124A3FD1
-:108AE0004DC497B14B52D111967745BF1D968E84D8
-:108AF0003CF37DC4F498E974C5D04F05387E687A9C
-:108B00004062E7C829961FEBA1FDDBBA69482753ED
-:108B100089570FF3ABB0A9F13F25499D9FA6F4A358
-:108B20000F8CC37070784E1FA12E77087E47D4FC3F
-:108B30002E937C857A18F9C1C1EF805D21723D19B1
-:108B400001FA0DD544711F6AE9E0EBB86FDD6FF2F1
-:108B5000755C18BF490FB7135F4BFC2B9F96FAD378
-:108B600059F71BEBE5A4107A14FBE265038B7F90A9
-:108B70005E65FEA9123319E503FA2A647645B13F12
-:108B8000AE05FA8C09D25D31FF9E11CFE96C081950
-:108B9000027436A13DC22753BCE4F1FEAE05BACB48
-:108BA0000FEA23E25CD154D28FBE32A52CD45F7081
-:108BB000DF097DA4406A6BD267021FB9A709E61BD3
-:108BC000424F43E38B802F517AC27DDA4FCEAACB3E
-:108BD00035F426F02EF4E552D28074365BA760EAB5
-:108BE000AB5C85F2B5DC325B0FEDDFAC62F43609CD
-:108BF000E8310BEAABE9A5DCACCE6BE9918EA80BB2
-:108C00001D574B9F03D1DB10A037215F632F4D6FA2
-:108C1000D3E3BF757A9B1E7F117AD3D299E05FBBF5
-:108C2000226CE5A03FD7574B280F0ADE1DD604F96A
-:108C3000E17599A84FEF8AB6A37E5DDFC0CA0B3BF2
-:108C40001D32C4BD64ADE3E599CE72C8D7AFA7E5C8
-:108C5000B4EBA2232C2E66D89DAC3CEFAE86D7ADEC
-:108C6000A0677858FB973F6F96A368B9B799B72F5D
-:108C70006D2D877C7D0B6BFF19F8A946437C9AB755
-:108C800009BE5F7D6FA69D1DAB99FE3E91AF7797A4
-:108C9000F4DCEBD8AE95B55B75D03C88E0F99FE984
-:108CA000E5D7F1754EDCCAD61977E2FAA90AA58B89
-:108CB00015010FEA6FA774B5C5C8DF06383F974A9C
-:108CC000AD69904EA1EC175287D9DE220F657ECC9C
-:108CD000ED74887BE299FD45F8FF20CEA032449FD9
-:108CE000B8279ED96345BD84188A01A08747ACA8E0
-:108CF0005F0BFFA4EF212281BC8735723D24ACBFFE
-:108D0000724A5603EA115386083FA55FBF948E9BB3
-:108D100077E18BC9E1EC433FE2E39EE671137D7A94
-:108D2000B237530774B10B88240580F4DEAF417F5E
-:108D3000DB057E4826A43CA404F0CAF25BE37FBDB9
-:108D4000A9653C85AFAE41EF01A1962161DCC9CC9C
-:108D50004EE21B1CD57FFE53F4C467C4382636FF91
-:108D6000954D541E23D1317E3687E38F8CBF0AE99F
-:108D70007736C7D3CF057F2A2005C09FE670BCDDBC
-:108D800064A67A34F2C35683866F3C130F726ACBA3
-:108D900080FABBBA5CC357AAF9B82BB9DE7E2B099F
-:108DA000A07E724AF2627A7A0BD3DB6B2C4750BFFB
-:108DB000E97984E9EDB5C48FFA8FD6BE59B3539DD6
-:108DC000AF6B53E7EBDBD5F99E1C0F8ED3B3A5AE8B
-:108DD00018EC8AD50FBF8B76EC6AC15FBC6AFE4285
-:108DE0001571C65F1EBA06ED51DF986F3C4D4F6F8F
-:108DF000C5AAB8D0DF029CFAEC352FB2F81437615F
-:108E000076821EEB88F9704E251A79A4E527799CA5
-:108E10009F08FB86E02F7984C9237A8E7DD7418213
-:108E20007C5CABD7F5C473BD979FD384FE9307FAE0
-:108E30000FD0D3350D48644139647FDB2487C89F48
-:108E4000798566C073BE99EE6780976CC971595475
-:108E5000F4F005CA9981CF7BEA720DBD88F3D62D57
-:108E60009C5E668127858EFF7BC981E7BAC3B732D6
-:108E70007A99635987F4FAD16A462FE2DC77E5E7FD
-:108E80003C87FC4DCE797D741241F55E9A1E4917E0
-:108E9000E77CE68FAF97181DD4557DF818E8CF8290
-:108EA0002F1C6E24F1FA103ED134CD64063B4A9358
-:108EB000819D83AAA67F5CBC3484CF38224A1313D9
-:108EC0004059EE8847FB6C5DA47A9C66A9F3BB7F92
-:108ED00080F3D24F23D14ED4FB304195A477EB7071
-:108EE0008CDB3E6B607E52319F550777EEF3C37E7D
-:108EF0005CFFEB083D959F3592F7C55A5AB6C4E41E
-:108F0000CA86716A743E23B36376A25F578C3BB006
-:108F10005DD683F2D5F81A93C3016910C6E1D2EF8A
-:108F2000D9A1FEB5D1898C4FDF11EB2A48880FCA31
-:108F30004B613FA45296A4C604FD26C1F8066637CD
-:108F4000F90B715C32BE6163887D9EB60F1B8F5634
-:108F500096C0F8F5F729CE61DE07A31DE5309FD353
-:108F6000DC8F7B9AFBFD4E47313FE0CCBEFA2C757F
-:108F7000F1F434F7139E8E51FB8744BDA509CC8EC6
-:108F800072B2D16CDEA807BF3A316F1C4649EC21A2
-:108F90005303C6932C6078EAD913BD6D5388FFA59F
-:108FA0002EA1F4FB309F7FD89C3743BABCF5B83173
-:108FB000D40EDF23B1F3770FA7979E08968A71EB43
-:108FC000122ABF0F78EC99E7473CF6E5C78ABC1335
-:108FD000FBEF99C0F86B5FFE3B2C4FB8DD43D8F533
-:108FE00007F2F769FD7B54D0B0734004B3CF6BFD3B
-:108FF000F30B053FE3FEF9059C1F2DEC607E8245D7
-:1090000066D29C4ACB177724B2736E94275BE59F98
-:10901000F7445E513C86A0CB9EF4CE3E7FF62321E2
-:10902000FEEC3AEECFAC13EBDBAD5EDF0309DFBA4B
-:109030003FFB818430FE6C6DDCC38BA0470C0BE2E0
-:1090400061AD8DC1AD42AE2D077B6FEF728271E8CD
-:109050006BDF5AD604F6E0B53F000B2AF231D4A7F5
-:10906000EB389C075A57BC534714959D7D105142CD
-:10907000E69FEC8A51E551430F89034DAD4E51B542
-:109080004F6F18AAAA3F64FD35AAF24C4FBE2A9F23
-:10909000D572ADAAFE55AD65AAFCF087AF57D5CF06
-:1090A000234307A3FDEC900CB62172B5B74A553E99
-:1090B00072E72DAAF69F9186CDE369BDDD42FE7968
-:1090C0001C9DA38A8371CE396D4B55ED9BA4B6626E
-:1090D0001FF0469FE49368BD151C5FCB3B99FF6270
-:1090E00074FB6A55FF67A3D83D18AD5F96762EA333
-:1090F0001ED62E9147A4FE7EDAEA8EFB9B21EEA8B7
-:10910000BFBF96F24DDA6E353DBF80FEA6D56F8E9D
-:1091100026703F5D0A496174ADA50B0BEA7FBD5B0C
-:1091200065B427E691EC87C623BC0CC4ABF4C75FDB
-:109130002F6176AEDEA7AD7688FF59F5D632A4470B
-:1091400053929A2E2214355D448E50D385D5AEA607
-:1091500083C1256A3AD0C23DDAA1A60BE2A7FF433C
-:10916000E02DE02AE01E3B554D375A78E79300DAB0
-:10917000D9DD5EC9EE2361FCE2EDDB705D97D21FA5
-:10918000F5896AF8161C703459106E2CBE4CE861D3
-:1091900026AEFF68FD1342AF894BE47A15EF47F81E
-:1091A000179A250FEA517DFEC2125F862F13F4A78E
-:1091B00006C2EC44CEA4C4F07646FC3E909D51C05D
-:1091C00075F620262F6B8803EDE12B880BF9DDC99E
-:1091D000CA5BD13EB4CAF263F4BB9EAD627A52352B
-:1091E000F1229FBFE2B802AA879210FBAB168E5203
-:1091F00087E4B302BFE1F22085740879E0C27813F6
-:109200004A86E662951F47ADE782DF30847F09BD5D
-:10921000578C27E029F89A18CF441AE424D8171A53
-:109220003E474668FD486A3B8DB0F3E06021FE2270
-:10923000AD5D26440F6E91E938F290CC2642F1578D
-:109240006073A0DDAF8874CE87EF25E6B626BDC279
-:10925000ED1357933EFBC480F2EA12FEE8591EC993
-:10926000FF68667F3FB4F06BD3E59FF8036D3C5E0B
-:109270005210EF552F0F8F077AEA6FA7B41F7D8525
-:10928000F623EB02B1A1F6C3BEFB06921FD7731300
-:1092900071DC4D42F41037699B3C3F13ECC4544ED3
-:1092A0004641CAEC58A45DAB07EBD18EACA32B01B1
-:1092B000BAAF21217EDACC6039E6E5FE7911377448
-:1092C000297DE242A28DC73FB07827C2F9A0385F5E
-:1092D0000E749E13711470CF16FC21224EA8399182
-:1092E0009F8373492EF44FF7DBA644B41FD0FD29AA
-:1092F00085EEC7BEB8222CEFB71F35EB177114B23D
-:10930000B510ED42CB42D77B19F0107ACB6FA83E57
-:1093100080F7341215A6D70D3AF681038A0B3B5518
-:10932000719EF5467A80017BC18B3C8EAF4DADAF0F
-:109330003F9BC8E393F839E752F01A181F3CEE4EF2
-:10934000E0E332F530117727E0F8427FB8EF51C102
-:10935000B5EFBCD807F73DE1E02EE072AEA8F329E7
-:10936000C0976C3D9200F0EE8872EE83FAE947FDFB
-:10937000A7245D705E157217C6CBF6B6CB783FCFCB
-:109380003D81C55BB9F7C8C81ABA3B4CE837AD6E2A
-:109390007F1DF5C2AE46CA68A91E76A6910EA9BF6A
-:1093A00088BD4003EF81CE47623D1F68D62FE2752E
-:1093B000E83A7F7F0938FC3E1C1C2AE45183E19E79
-:1093C000575F9C913E905115421FDA756CE6F4B0E0
-:1093D00056EF3C01FD1DEF4CDB0CFD55C81D07533E
-:1093E000003EEB24BC7F35D1C4EECB26F3FB7425C5
-:1093F000FE063BDC374E4AB3E0FDA9E1DF919DE07C
-:1094000017FE78DD6D31704F4CF43F5CD2E1FD4EBC
-:10941000429EFBE48E42F0572EB06FA2B98526160D
-:109420009791F9DD485F16E523AF1A8919F6A36114
-:109430006803DE6B0944CB68B78C93C924A03B3129
-:109440006F711F567C87FBFA70EF527C9FD81428EF
-:10945000584BD30E4E0F62DD13CB03050D9620FC47
-:10946000455CA6163E5B383CDCF1C666D017BBCD2A
-:10947000E2FCC95262D3239F596766FBE6D855E2E6
-:10948000FCEDB3C2B9D41DE1183C06F6DFFB32791E
-:1094900092267FB1390647E3FA15D4C7D7D958BB0E
-:1094A0006E1E07BFEEA3B244885F8E6F0A1F6FA6C1
-:1094B00024B1735C2DF7EF8BEFB57A1FC68DD542C3
-:1094C000BC7641F0FB95C66B8B78FC01E110AD27B3
-:1094D000FAD178EFDC79B17AAFFC4B0E7BBEBE3EA1
-:1094E0004927E20FD1EF4DCF5B61E30B4B93D8F9E6
-:1094F0002A1807E8C77BC37DF1857B4A13C945CE8F
-:10950000FBEEF30E55DC9F8837779F9F84717EFDBD
-:10951000FAA5FD2996605CE140F0DF92C8E6E58699
-:1095200078BF82D0EF0AFBDE374E1C8FDFF347C1D6
-:109530003EFD45BB8CF7EA7F714837757B9879D73C
-:109540002731B85D13AFC77D33D2471CDBC28C2FE8
-:10955000EA89FB35E29EAA767EBBCBFC8B60FE10CF
-:10956000471C6EBCA59C8EC4BC77C7307CB8F799ED
-:10957000F09E05ED17E3BD77C7F857E2BEB0A9F13D
-:109580007C3BB7D7ECBEDE9F81F7BCA6313BC34026
-:10959000F4E08D72FD04F5D89B69654A3FC5FA0673
-:1095A000C916B2FF2E450F41B8EB5478ED0F772363
-:1095B000E257F4FBF961BE4F89C302E7B7255CBEF1
-:1095C0002DD95183FAAF381F7DFEB08CF1179F1350
-:1095D000E627F9BC55C2F3CF521721EB291F5AF9E0
-:1095E00064413388B92549845C17C3BEDF09E94665
-:1095F000B59F7CF9BDFDEC872454AEAE200D2857F5
-:1096000056FE58DDAE9ADCFB67D09FB4FEFBE1DC72
-:109610002E27D6B139899E4740EF2926C5201FD66F
-:109620003EF985314A19781F9CA67C77981EF8AFC1
-:1096300019D3AE461BA6BF48723C9644F1B727C962
-:10964000B50DD29EF759FFBDB5BD4C7E6C8D43B9AB
-:10965000D564FD2EF2757908E3EBF7C03B09141EC3
-:109660002613D39712740D7214EA2D5EA487E3F1CA
-:109670006BAA6662DE9E04741FF7CB295331CEEFCE
-:1096800097910E80F7A652471ED8253655B27B9982
-:109690006613F3B37B7F31F63570830C6BBBBF0C65
-:1096A000CEC1B68EFD3EB0F7B4E8FE7C10E2575A4C
-:1096B000AE63F18B093AFFFED490F1E223BD49E09D
-:1096C000878F1F69C4388F38B934AF21245ECACD63
-:1096D00071D1DB9E8576C21E83B01BB645E0BDA866
-:1096E000DAA183818F5C43189E45DC1BCC2154DFBB
-:1096F000EDA27084A04B91BFA64DF219A2F0FD120D
-:10970000F4E3D4DEE54B980F72EAE77AF48389F943
-:10971000C5BD9A5C06FE2E219FE64B366647E3FAEE
-:10972000FC3C22FE317FD95C4E27F3B81E3F3F92AE
-:10973000C17B29B16740BB5BCC244A47B7D4FCF25C
-:10974000B6225C678D211AF405E1F71958CF086F2E
-:10975000FF723F6565F78DA54036747286C2E76279
-:10976000FB30C0F9B23B9BDDBB23C38803FC8CEE0E
-:109770007DC3B7817DC23488F9AF297F3297E4A3D6
-:109780005E6D8673D4ADAF44F0F8222FBF4FECC8A6
-:1097900083F89CFAAAB47C8C13391AC07737BA0DB7
-:1097A000FE0CDCC794EF4854360EDAF2FD197AB895
-:1097B000AF9942F5359A2FD9722FCB0FF5AFD4D18F
-:1097C000FC922D4FCDD0D3FDE1BEC67F0AF2355BB2
-:1097D00076B17CBE7FA54CF3CD5B5E65F5E160495B
-:1097E00009ECC12D07677868FF67A2B9BCB7FBF128
-:1097F0009EB5FBE5E1BA503B6B6332E35B67B89D16
-:10980000F84C26595C05F01E11BEFEB2641D0F5ABD
-:1098100069C554AC57B42749E1DB25F3716EE5F710
-:10982000A32746929608E6B7F344513C1CE8188EED
-:109830007EC7AF9362989E6EF3E3FB38A21F014F81
-:10984000D19F187735C867E0CB9A78ACEC64863F37
-:109850003ACE461C679883DD2BAE4ACB03FC51BC45
-:10986000E939DEF4ECFCBB8DCD8FF61B9D8B72A02D
-:1098700000ECF807BEA2F53383F3D6D24941329308
-:109880002FB736317F6B203A0BE96962247F67A5D9
-:1098900050BD8E660E87C6E4687E6F46C02B51C2EF
-:1098A000719A381CD3FC78CFF24AD75DF11F5A77F2
-:1098B00008BE1CF05ECA81F6ABB7B3F5C4F07BCD31
-:1098C000FE8C18D4F7EE57F5776683A67D09C1B8EC
-:1098D00036774C16B6BF278298F13BD9DED72E33A8
-:1098E00097E9ADA0CF8A772C88E73A12EA47EC7B5C
-:1098F000AFA28DC56706D739A390AFD3C6D769632A
-:10990000EBF4AAE8951C0964CCB6F6A7E33EF8F799
-:10991000F5372A9FF7A7DAE7E1FA837D3D105ED697
-:10992000733AF9D6F022E6A981671F9C35F313F04C
-:1099300084FD8DED46A9E952CCB326599C9335FBA5
-:109940003BF31B8E57CADAD5DDCEE2B989A2A6EB6E
-:10995000BADD993A882B10ED6AC127101FB4FF3D7C
-:109960009ACCED8969246D80F8C4C7938BC2DA0D57
-:10997000F1BBF69CD813CDE2D5B5F68A9E787B274D
-:10998000DCAFF49C63EF0A8CD3D86FC0CFF49C2576
-:10999000D82E285FD4F9739C3FF6B73F0532607E1E
-:1099A00085A6B2E7153BD547B61C437E5D38B8ECBB
-:1099B000B64C9A7F35F98FC8CF0B53CBBEC8A4FCE9
-:1099C0007C7FB29FE547967D3114F25BFCACFE4490
-:1099D000C7F3C0EF89C73F63527250AF782D59412A
-:1099E000B8C9E53A027464022586AEC7F4AA09E351
-:1099F000F6045C074A0B4DBA8670F76FDFEEA307DB
-:109A0000E65729813F15B0F3713B805FAFB203F495
-:109A100044B17BDF3D7BFF8EF75D3E487675021ECD
-:109A2000EA23BB1665D2FC5D919FA01F4F72D03D0B
-:109A300001F615C54616D0F94A5D9B9CA03F91D50D
-:109A400076B31EE1CAED5E748D1728FC5ED9F7F37C
-:109A5000EFA5B2619C308FB19C0FD4EFFBF26FE0A9
-:109A6000F7AD3F63B183F97A6CC796DB40FF1ADB31
-:109A7000F1F6974C0EB3FB3962DE63C1AE49BF9776
-:109A8000B49B70FE633BAE5E01F5C7FDB6230BE8E9
-:109A900064C2315F13B0859EBD2FA5AAEEE590CFBD
-:109AA0002E1AD739A0DF4DC0E353AA540D4678F4DF
-:109AB00032787C85F167DDF1879BFD68FC54DF7FA0
-:109AC000A2FA3AFA917BC9203BF833C47D7AADBD46
-:109AD000F468255D1FFD3E21406710A24F4F3C6F8B
-:109AE000A68C24982F25D1AA7CB9395955BFC29686
-:109AF000A92A9F9274B5AA7C9A92A7CA4F1F315681
-:109B000055FF067BA92A7F63C93455FD4A47A52A1C
-:109B10009FE76B53D52F38D4AE2E3F4264C043FE2F
-:109B200051FBEB90169D74A0D9B5F874C3EB908EE1
-:109B3000FD0B0387D65E7CEDF9B6D7E1BBB0176BA2
-:109B4000EF3309FBF1CDB2C56B0C6F274ED2670521
-:109B5000DF1F9075EC3ED318ABEBEA94A2E07DA634
-:109B600089602FA648A8587CEE47E3004F0B983D2C
-:109B7000ED282006E3BEAD68873C6A6878E60F2CC6
-:109B80000E201DF8DE84C05CD5BA279E77A9D65D6D
-:109B90004A6ED5E0698D2A5F61BB5D557F4AD2066A
-:109BA00055F934E5071A3CDDAFCADF60DFA2C1D347
-:109BB000360D9E7EAE2A17F4DDC1ED5AFBC01E4560
-:109BC000D3F1FECE72C0C375A703888F92CED67232
-:109BD000C0D3B547DB105F853E6739B0CBE2430D9C
-:109BE000AF43EAA3E73168F75A6312A6071A15B420
-:109BF0006B1D6C1C81E9A1463B7EFF756309A6EFD6
-:109C0000343A307DAF712AA69D8D4E4CDB1ADBB005
-:109C1000FE738DEDCC2E16DBF7DE453AD807BA750C
-:109C20007E377882173F927703F0CBEE41FE6EC805
-:109C3000DF45EC374CA2F925C044E8BEFC294F377C
-:109C4000A43A028057371CCA8A82F1186D3A471E1F
-:109C5000E8E177A44CF8A13E9D90BB3738936CD1D6
-:109C60002C6FA6794436C6B34DF8A18312D73320A2
-:109C70004AD0A933E106C8F744B07277CA841B40C2
-:109C80000FFFC6FE73473FFFF91D2961FCE7CF9C1C
-:109C900056AC60D739FCD5702BC0E330B76F39486C
-:109CA0009E61094D4BF5790690B34707B8B7F08030
-:109CB000AEB409E0D0A6B3CFC178EFEB0D04E8B79E
-:109CC0004A62E75F51CF95CAE441CF0D263C4F1D54
-:109CD000D13956605C9914780CE0BC3DA512E1DEE8
-:109CE000630D6400FCBC294E968F0F3C26D943F2CD
-:109CF00006069F07526EFCB6E1F35838F83C9162B5
-:109D000063FAB6CF910E7A80C81FA974D4C17E3E83
-:109D100052EAB80AEFCF384D6CFF3AADDEABD03E19
-:109D2000E4289A1362E719926A60F7D1E16222D8B7
-:109D30003B6F91719F6BE1392195E97B482770CE8C
-:109D40009C1789E782233AF69E81B6FE020ED7B3AE
-:109D500083C2DBE316A632BDA26C56DD332FD0FEE4
-:109D60007AD64560D73DCEE1A88FF53450E82A3445
-:109D70003DDD708E959BEC1C24E8BF9D0F7FD1F2DA
-:109D8000673A6EFBEBEF68FD4FD645DA5186D8AEE9
-:109D900041F8DDC22B2F8C35A3FEB4B02ABD0CE4F4
-:109DA000E27CEE075C64D527A03B501F6D8427172B
-:109DB000975BF29A2904C9CAB84A233C25559DB637
-:109DC000A619D2D5C3EE37C21329B5A37635831AA7
-:109DD0005B47B77011F23FFFBB8D745E8BD7CB0A28
-:109DE0003BCF89FBAE355714CF22E8F7088F3BA253
-:109DF00040C0F3EA220E6FD16E1187D78914AE3FAF
-:109E0000E6909C0B6A3FD66740EF5D0BDFCD1EC02E
-:109E1000CFA02EE7FAE3074636AEF6FD1231EEE2AA
-:109E20005476FE3A62A49409FAE42D4C0EE4CEFD79
-:109E3000E2AE22BAFEDC0E9B0EE31516D7BD00780B
-:109E4000E86DE778349076D84FB33C4B3EF91D224D
-:109E5000264E758FF752F2D2DE692B0F9597857ECD
-:109E60006779A8BC2C09B496835C14F251F84F7D35
-:109E70008DD59C2F37203F3DD0B81EF3071B3D9852
-:109E80001E6A6CE17CB915CBDF697C98F3652FE71E
-:109E9000CB3BF17B47E35C4CF735BA583ECA19958A
-:109EA0000AFBC4ECC2F8C437B69808F8E77A3B4C12
-:109EB000189F4177C4638FC641FC9109EF716AE333
-:109EC00090B47CBE8F1E76F77B372505C6E98B1FC5
-:109ED000027D71C8C0F474982856E04BF98FFEE4F7
-:109EE00006D0AF0F2B8A15F4E982D4CD2CEF50ACFD
-:109EF000069A2F7C94E75D8AD504AC22F521E45BB9
-:109F0000873D8A3582E68B1F7D88957B093AF3C7AA
-:109F10003DBAF5060FF059221D80FD516ECE9C44CE
-:109F2000C50595D7A507605F4C495A3209F6C5CEDD
-:109F30001405E9639AB2E100E4A78FD8A687ABFACB
-:109F40000E4BDE4668571657A9877693D2D66C8497
-:109F5000769387DDAF0F6D3775D4AE8D909F61DF3F
-:109F6000A607FD7427F0B1F8603F222FCA059F169F
-:109F70007172A33B9C280F72DB9D280F045CCA669C
-:109F800057DE0DF6CFFA76C926C13C664B7D410AF5
-:109F90001093E886F74929BFBE3EF597D60DB45D0C
-:109FA0003DE4AFC5FC0F377CBBFCFBA6D430FCFB0B
-:109FB00043BEDF41DE43DCFB8746F60ECC331C2E6E
-:109FC000F51D4BACF88E2A715941CF7A9ECBF39791
-:109FD00020A5E59FF1B48B7F7F40E770C138AB527D
-:109FE000B91FB23F7FA84965FB5F738F648072CE53
-:109FF0001FEA526DAAF73CEA08BBBF76A9383B6D51
-:10A000009CB836EE6435693BE8C8EC1F6F520BF71D
-:10A01000DCB2FAC77F8B786A6D1C78DFB96A10E30F
-:10A02000A77381D750BA6E491D904FDE7B0938DC8B
-:10A030001B0E0EFDD643589C7BBF38241EEFAE5D31
-:10A040001771C5B3778D79FCBB767D822EFAAFAFE1
-:10A0500095C15FCFE04FF5BBC7607E158BAD04ECBB
-:10A0600056A1FCE77717E13F5A7EF66DF1C99B17C1
-:10A07000D7E1BB6561F8D8F3E1F898B8CFAF4D856B
-:10A080009E0AF7F3201E12DE3982737E65A26B1FD3
-:10A09000F4D35316F89B0ECEA171ECDDF083D1AE54
-:10A0A000FDF05D32B2B80611977C5AE7F915E86DFC
-:10A0B000EF3DFA19F2B36E1016748FBC41F3A097FE
-:10A0C000FDC3E67C13E04746F88DA1EF8F0F147FA8
-:10A0D000FB1B2EFFFAA76CDF8938D49E6D5F66A04C
-:10A0E000FDEE12FB62207854C8E3FD703FA4B72454
-:10A0F00012E56797447CF0DE71576902EA2D5DE94D
-:10A10000463DA4DFF6B9B82B3D1BFBD79E8FBB9213
-:10A110004BCC6CDCC953217D2FF95421C8BDDFF035
-:10A12000F8CB76A3A7E03DB00F8F8D40FFFE8D9258
-:10A13000BF10E0A03D5777BDB5A04CC9ED7FBEA6CE
-:10A14000EB9B04EBAB3DAEBB1BBE5DE979BB76FD83
-:10A15000DF08C4B98F5BFF1581F7EFAEFCFCDD199A
-:10A1600093AB805EE16A021219D345F5099ABF5498
-:10A17000FCD639899ED33343CEE5256FB3382E9E66
-:10A180006ACFE7FDDE095CED51C70D96FA8A305EB5
-:10A1900045F647E1BD601D7B6F43C473BDC9CFF376
-:10A1A000F4BC3E240DED709D19AAF3FA1D1F2DFA83
-:10A1B0001EF281088CEF78A6FD443CCCF58F9DF112
-:10A1C0003F794509D277BDED6F24F49DC0DAF5BD26
-:10A1D000AA7CD786E0FB56701FABF65F32CA252AF1
-:10A1E000C75A104FE435E3DA10F94ADAFEDC07EF1C
-:10A1F000D194DF5502C050BE36CF74D07695FC3C6A
-:10A200004448E48D0EDAAE929F1F8967252B8FE7B5
-:10A21000F53D9FB07CBA28FFE34CAC7F95E86F1CFE
-:10A220002B4F1679DEDFD5229F782396678AF62595
-:10A230002C9F23C6AF64EDADACFEE4ADFF9C097A64
-:10A240008DE0F733D2B89CE0EF5251FEEF4C2BBAC1
-:10A2500068BC8EBA9CCB07F10E55C51DD322DF8595
-:10A260007DDC2661EC61ED9D06B4E79F8D69CB0D29
-:10A27000BD2F2FE27A9CE5568CF3AA7B71F8769974
-:10A28000C73B811EB39CFBE92B640BFA617AEF6537
-:10A290007C7E203D70E5FA9755F8EC57CEDFD3462B
-:10A2A00047251DEFDC0F13F17E0219D689F102EE6E
-:10A2B0003449C427E0BD6A11571797451C707E8E3C
-:10A2C0007B2982BDA77AB213F9EFCA97987DBB6E3E
-:10A2D000CBEB28EF96CA0ADA97BE1EEA5A07F0E9D6
-:10A2E000B6B2772F57AEDF87FBF431C5C6FD60816C
-:10A2F00051A1F0BCB33FFC3D69F11785BFBAFC3FEB
-:10A300000C7FAD5D5DDCD75F7D85F17FDD56E607B7
-:10A31000B6733CFD49A71473783D02F03AB7A233F7
-:10A320003B5A8620EE4E8C77AB90DF2982F3566F36
-:10A33000839500DEBBA5CEDC0FC3E05F7BAE389F0C
-:10A34000415471693BFBC3F7E94BD0F7D3FF4DFA9A
-:10A350004ED4FB8D76F01B1F65EFE51577FEC9180F
-:10A360001A1FF44E1A3B070F6E677E311117172C18
-:10A37000B7323C71FF535DD53BE3C1FF24F6C3C444
-:10A3800048D206FE044AD7764ED776A06B41BF412D
-:10A390003F146D1706BE41FA252C2E91C3E9B7FD77
-:10A3A000E1FAE125E0FAE17F13AEBBA93E8CFEDBCA
-:10A3B0001722D04EA385F33F385C05BC23D32F0E64
-:10A3C000E7C8F4FF0C9C23D315959D43C07B20F96F
-:10A3D000A4C58F9877987D5AF44DF6E923199C4FC0
-:10A3E000E9FD188FABC57B4C7A3FBC27A45F1CEFFF
-:10A3F000EAF2FF30DEB570D3A6B5DC9FABFD5E9808
-:10A400003E20BFFB56E0F87FCD4FB0B061BFAA7CC5
-:10A41000F1FAB754E54B3CEF5F965F41D8FBFF5B29
-:10A42000FE05E15798F9FC2A1DF81FB5F24137C423
-:10A43000F923A0C71B5FFE7AD48730F9EA6C8CB78A
-:10A44000BA8DAFE58BF17FFFE47B94BEBE6860F60A
-:10A45000D663FB3F372839FDE965E1791D7184D06A
-:10A46000D9C2F5EF1B40CF5A48D8FB54DAFA0FA6F1
-:10A47000337B30C64951BE30D74C0C71941FCC9DF4
-:10A48000CBEE4BCF0507630CA63E172D9FA9273EA9
-:10A49000788FBBD2A2F799D0EFA9BEFF6EE2EF751D
-:10A4A00093B858D53D78D921639CDF9C12E62FBD27
-:10A4B000C5D286F787E71DBAEBDCF7602F6FF4147F
-:10A4C000B1B87771FFF0F7BA2BF1833E087A2A9C76
-:10A4D000FB24EE5F5F6340FFBAB6DD2ABE9F66CA0B
-:10A4E000128BA3D9C3E233C5FEA4EB3B64CA67F762
-:10A4F00060E0F7482A1B0CBEE1B9A067EF473DBBFF
-:10A50000BE64432EE0AF7E9274DC941B3CEFD4AF6C
-:10A51000FF0BB6D7F2676D7AB9F6D54F1A0F21BD8A
-:10A520008873D1B1461FE6B5F6D60513FF17FD9324
-:10A5300063FFE26D8274DC578E0FC7D075FB1B3B47
-:10A54000FF2D7B82B02308BB82D64E21F88878BFCE
-:10A55000D2976EE3EFB296A2DF83E8592AF8EDC1F5
-:10A56000FEFCF9D7E917D727D5E5FF61FE7CB9F4E2
-:10A570005F9BC4E4AA96EE8F56FD0CEDCF82BEB56C
-:10A58000F4BF006252E8F80BEA25BC273E7755ABD2
-:10A59000619CF4CDE97DB5E56406839B462E5CB1F4
-:10A5A0003C50783C878CE70B93BCC60E760F8187B6
-:10A5B000AFD3D5EF0353BC48191797ABEAF2FFFAB4
-:10A5C00039E0E4A26F2617894A9F48CBE8B76EE5C9
-:10A5D00012EB56FE9BEB0EB9A7B448D605EFE3404D
-:10A5E000FC35C481F678D9FDD4EACC56FCDD0352A3
-:10A5F0001288027E77EB5E99FD9E8EDEA14F0E796A
-:10A600003FAD8BF83E007A5C359EBD3BA48D9B76BA
-:10A61000F378EAD596DD78BF51FB0E9A88CB76F3B6
-:10A62000FEB4EFA189F6E29D03ED7B685332781CFE
-:10A63000763EC967712917E7A3DD20CF43FC35DDDE
-:10A640005F35A25DE1C6C74AEEF3A405F13227A348
-:10A650001FDF99977171BEA32EFF2FD3AF6CDD81E1
-:10A66000F7D8AE947E47643ADC407F822FF7F19BA7
-:10A67000574CC86FC43BF33D6B9EC1F7877ABE242D
-:10A68000E897BDD43BE313BBD835C40927BD4D566D
-:10A690008AD771C73C68AF1B7BC485F776C7BCE31C
-:10A6A00080887F9277C029C3BC853E23F49B20FF1E
-:10A6B000E2F7D9789CD5E5F2B92BF537FEA7FC8CEB
-:10A6C000E25E5DB7C15704BFE7E0D91381BF03A1C4
-:10A6D0009DFF9319BA8BBE93DC11E57A12F0348B8F
-:10A6E000CB09F15E7285CCDE49EFED94D15EB8EE18
-:10A6F0007F7EFBAB47954BDB15EA6DBD61CF6522D5
-:10A70000ADD7B17B2DF9E50AC649C2790DEC87C2F8
-:10A710009EA8AD7F4A297B2903ED5BE3F13DDADE9C
-:10A7200087D97C06C257FDFA008E3F60391FBF7E75
-:10A730006F912DF49D95F3197DE743DB297310DFAD
-:10A74000974B17FFD7CE2D3365E291A87CCD91BCF6
-:10A750004CEF254CFF5D403A315D440298BA08BB8E
-:10A76000CFB094D8315D4E9C98AE555C5D191837CA
-:10A770001448C0F8D317FF390AE8E6DC75E35A211C
-:10A7800046F1DBF22369F5BE9E3C85BD97F4C23FDE
-:10A790007F07F4D9F33F86CBE21B47A21C6448181D
-:10A7A0003FD37BA532BBD754F25DDC17E2FD5D32AF
-:10A7B00089F9E1962766E2FE09F2CDC46D826F82C7
-:10A7C0003F39E7B88EC5C3DC2AE17BC6ED7E1D6E3E
-:10A7D000B19C15995EF8DDB9F6DDAC3CA72EDA2BFD
-:10A7E000D17CCED80856BE26DA0BF74F16123FEEB4
-:10A7F000CBC570FB4486FB4B8C2F8ADF0BA02782D6
-:10A80000A1126DBFA2C3CCEE5110FF30E0FFB970B2
-:10A810007E0A174F3384F1F1D14319BF1F5DA6B6ED
-:10A82000870CE5E5F72965DF0778B40C71640D81C5
-:10A83000FA319D9B1E2C043B908E809FE6B3B1B7EE
-:10A84000A35F53B47B51291B01F59F9558BCBF678B
-:10A850002FBF6F4C0209A1FEB1B54A792ED42B1A35
-:10A86000C2F8D3407085DF517486392F8AF8D1D170
-:10A87000706643BB3CC177D29E95587EF2E35B6F16
-:10A88000DC68415F8207F4E31715D744186FB49171
-:10A89000100BCCFFA7FC7E1B69C800BBE8AAC74C05
-:10A8A0003AD02F3EA2E218EEF7FC819EB721FD9828
-:10A8B0009E9B21FD233D37437A9C9E9B213D41CFAA
-:10A8C000CD90AE386F87C7CCC989218EB9D0BFF083
-:10A8D000F769E75B3984F1D7BEF1F71A71FCFB1415
-:10A8E00017C2B70FDF7B08FEDEEDB3D18194988BE2
-:10A8F000D05BCFDEBFA39F7420B808FFA3B67C0A4D
-:10A90000C76BEE6E3DCAFFDC767FD4CA907A2B8788
-:10A9100018B17DCE0B27A3A0FF6E5B1F7C1D125DBF
-:10A92000F24C1DCBAF7CFCB91B378E82F93BBE0FBE
-:10A930007441F7F96A4873DB7FFB00FC5E2AED1F68
-:10A94000E3247AA4C0663C2F68D6A1858358D7B388
-:10A95000D19D9BA0FDB32F0C859550BE43D8BE0161
-:10A960003A92C2AD7703AEE74653A010EE0BDD7806
-:10A97000410E1BA77D9F528A704E067A43FEDDCAA8
-:10A9800053465F026FDF747F6BFB23E2FD15E0A58A
-:10A990000AC8A5AFA2402FACE4F104EDBB87FD06C9
-:10A9A000D6E9392413F8BDDAD131EAFDB78BE34992
-:10A9B000A4397B8D4EC0D7B37B4F0D83F789297E99
-:10A9C00086C17BC5DB865C45427FEF3167EC978FA4
-:10A9D0003C1887F5F1F769E7916D15103733DFBC47
-:10A9E000FF0D58D242DBF10A889B599C241D8474C8
-:10A9F00089923919E265C47D8365234A0FC2969A0C
-:10AA000061AF447DAE14984C887C283747F247D814
-:10AA1000853C8A55E5A724A5AAEA4F53B254E5D34D
-:10AA2000478C54958B7167D80B54F546C70486C282
-:10AA3000798EAE83BD03FFA48CF186392F1CB97EBD
-:10AA400024CDCF7C6A0EBE43F92C2F9FF95CB91739
-:10AA5000F0D143E169A40AD5E9921F6C7E103AD384
-:10AA60009C176AF73E71D0A15CC679E112E7848138
-:10AA7000DE4F16EDB5E704CA371F00BE39FAC5D957
-:10AA800036F0DB3E3BF6CB148847FDCD10FEAE0C16
-:10AA90003F3F0C44377DFB435218DDBC259327C351
-:10AAA000D00D44F2323A64E9CCC3EC7EDE95F2B5C7
-:10AAB0004F81AFA1BDC043427F7F576BDF1B6DB499
-:10AAC000FFE636B047BD2BC30DA5BE7B932BE16FD0
-:10AAD0003948EF64F9B6BB93E3F0BB07F46137B7CD
-:10AAE000F70D52B83E55BBFFEEE4C2603959775CB2
-:10AAF000559FDC2935ABF21B33D5F97B4B9B43DBF0
-:10AB00000FA48FAD7C7889D19503F76EA5B0BF37C0
-:10AB10002CE6F3FF010980D5200080000000000032
-:10AB20001F8B08000000000000FFB5190B5454658E
-:10AB3000FABBF7CE0B1960782810427798440A8444
-:10AB4000895728B08DA01ED7DA1A4C8F545693E53A
-:10AB500003794DE0B6F4D8E318AD8FB6076D5B69A5
-:10AB60006B355696E7E439B144462536AE5B49EB82
-:10AB7000D654A266E499D8424C70267A6D9D5AF755
-:10AB8000FBFEFF5E672E605B9DD64EE79FEFFFFFEB
-:10AB9000FB7FEF279014CA70CE0008F6ACCC7099FA
-:10ABA0000106F7D61AE41880D3F4EFE2F0DAB8F928
-:10ABB0007A8303CF5700383ACCE3CF01D601140390
-:10ABC0005C29817BA2F3145960E760FF65F1BD2F1A
-:10ABD000010849009E178DDEED5684E35C06676E22
-:10ABE000F89E8DF04E0618D972FFEFBF2AC2F525E8
-:10ABF000B0E30E8CC4430DBD9BD7755C1471CD9F23
-:10AC000004D7D17779968098806B7055B407E200AD
-:10AC10009A6A633C623E9E67860E992E04C8F1A62E
-:10AC2000B59B52018E8A22C039440778A014EFE305
-:10AC30001B045F24A739EFA4DFB9C867CC2FC7E78F
-:10AC40004532B035BF3294E9C67BD77E87E71CBF5B
-:10AC500003A291CE3F804A8F034C5C2E04BBBD19EA
-:10AC6000FE3F233F4DBD1218909F61F01DBA5A6000
-:10AC7000D7CCA925002BE9A74CFB1D0690D86F194E
-:10AC8000707F95B2BFB27CE5A5108BF056FD4020D9
-:10AC90009BBD0FA7F1FFD57F6F3798F17CF553DA95
-:10ACA0007D420F53902FE5FB3AF0B377EB77E23D0F
-:10ACB00053F85E23DCFD9984EF367669BF5F24C7C5
-:10ACC000240DE6E08F0228382DB16D91DE6B36F150
-:10ACD000F7E64ADFBD7B09EAB1E925C96EC4ADD10B
-:10ACE000DDD3E200F98339A8E4D4F1F26BDA8C7A8F
-:10ACF0002A0CC3A7764BF3BD745F17CAA89E315EBA
-:10AD0000CE60C9E2F82C1C5F73C5D70B01F135F793
-:10AD1000E8D0D07E00CF4611E4083CCFED31AEF252
-:10AD20009AC3F4072D9CC7FC9E2F1366E7F2751D8E
-:10AD3000D101ED1C2F70BF9821803E09F141B56013
-:10AD4000DF8E4B5F4F7225C9BF4F009F5CC09E587E
-:10AD50006442FD5CC19FA37D3324E08F946C1DE1B0
-:10AD600059A8C8FD8AD27F7C23E0778B7B164F439E
-:10AD70000AE050D7B23ED40C6C906D0CDF12F0E8B4
-:10AD8000492F7DF1CEF416A4F3324960F6DF171F88
-:10AD90001A16107F5F45B4D026B0F7EFA4F755BE62
-:10ADA000FAF4CE7437E36B8E6510F526382E904E8C
-:10ADB000478F974758AE3A1854F52B7177217F9CEF
-:10ADC0002BDD3EFB12F4DBD1A5603122BD974B6831
-:10ADD0003808C3ABDC8FAB49D63351AE823F81E834
-:10ADE0006C96176E91F1BBE4D67B41971821371D05
-:10ADF000F733552FAA1CC7D3A1E22DF73B90BFD143
-:10AE00001D02B39F46BBCCECB3B1FCE4834B107F77
-:10AE1000A35FB20B48CFB2EEBD47487E1D6B3B40EF
-:10AE2000771E40E7DA6EB62E33997D521EE38BD93A
-:10AE3000AD8846417CAD5660C6A7357C1EE67B0CCE
-:10AE4000BC513F7C06CE043818EB7C9EF85BF3FBCC
-:10AE5000CFFB9610B51BCAE3991F90AD9D1BA63F73
-:10AE6000DF006046FA43DBA3BD4F303C68AF25618D
-:10AE70007B3DB127EB700B9E9F7853CFCC755FC5A0
-:10AE8000C3A76E4178CDF66826E71309E049A5F31C
-:10AE900027A67B3D7861A518EA6F21B977C6D8B798
-:10AEA000E3F9F147A73FBB13E1DA67A7D9894CF271
-:10AEB0001F19E57D3C1D01DA7F3E957D07291CEFBA
-:10AEC0000AC52FA56766DC574EE7CF24DA098FAA9B
-:10AED000BFA147A31C80F2FA127C791634BD93827D
-:10AEE0006750C487EBC49DC704B4CBDB0CAE83C4EE
-:10AEF000F7EA47FE7AA80CF9A97AE6370FCF44FAA9
-:10AF00006ADF9B0CF44E58AFE3E2406C2097FCDF05
-:10AF1000C6FD5F914FDD8E28CBC71171A6A1235EC0
-:10AF2000033775A75A3E8E883775C0650CF5828E3B
-:10AF3000F8A957FCAA5E741D25BA1A20C0E3228422
-:10AF40000C64570592E0A07810BAC7C8E43FD6CE8B
-:10AF5000466591D1512F828BE27941229852C86F78
-:10AF60005D5C7EC17BA63F7117CA66923541F5FBD9
-:10AF7000AC853322EDB3BFF115B2CFCD46669FC38A
-:10AF8000513C2F8DC5F31F399E7DBFC2F405F38759
-:10AF900033F9A4F5DF5A38171C14EF0ADAE4C29B20
-:10AFA000706D51F4722CC5295849EE1DF7EF3AC067
-:10AFB000E4B9F5E6A38477BF99E90F0E70B90705E8
-:10AFC0009E27D5F7569842A02B247AB7317AD5FD23
-:10AFD000C12D87F35CF8FEE00B397980F6BC4CF2AA
-:10AFE0000FFE05E5732AC67FEC365C3BF7BF3B8559
-:10AFF000F2E0587AEB5B47D97B2A3C2CF038544F6F
-:10B000007CE0FEF799CE64A213C3088B0F0377CDC3
-:10B0100060F29B2BE5C691FE8327B4F48DA5537D8A
-:10B020005FA54F7D5FBD37CD2A32398E18FC7994EC
-:10B03000F75FCC90357C8DC4FAF3E2CDB46FE17547
-:10B040004402C211F656433F51BF35268CDB485FA0
-:10B050004D8D606F03B6EFA1B889ABCF85E7F529B9
-:10B060002F2B7203A709ED78B162679094C8EC6E3C
-:10B070001170BB5EACC4EDABA0430FE82F47C475A5
-:10B08000BF35A0FD0D773CA07745C65DCF51F1746B
-:10B09000CE4F8FBB9E4AC8A6F83D6231B3BA669EBA
-:10B0A00055D0B17BE9904EF7F0DCEE433BF0741ADB
-:10B0B000ED6D48CFE3A2738115E5536FF0E5911F65
-:10B0C000A8DF3D2EBAD8FEB0706005E91B74BE3C07
-:10B0D00056EFC41B40C03A2338D9EE77505DF625B1
-:10B0E000B0B812D4434D27E22DAA12DD9DE6703C84
-:10B0F00054E367510EEEA35C2B685FF557B49BA237
-:10B100007CEDFD303F5AF8B895FB5D51A2E8EE9812
-:10B11000C05F6E57F4DC061D12F7679E47CB14B96B
-:10B1200063DD2245D62D8D4A9C0FC69A3C12F25300
-:10B13000B61BF5827099CEB797568C02D08AFA9DCD
-:10B14000053EFE5EB7369E530E59CAF2720ECBCB49
-:10B15000B31475AF17DC407A3551FEC2F52EC12FFE
-:10B16000D1FA2B08B1D501161DADA806B6CE012720
-:10B170005BE7819BADF3A19DAD0BA083AD97829F53
-:10B18000AD7081AF0D583EB8DD3288F9187EBD52E2
-:10B19000A4BC5CB464E27AFC71455E67970746F92B
-:10B1A000929F2F8F79E04A61749D4D2E53B399DDA4
-:10B1B000AB7231927DE27751E04DA1B50202EC9D78
-:10B1C0008BC990F19DD920EB08AE020783E7FE48BA
-:10B1D0007994065C3A57EE0472A99AD84E7628768E
-:10B1E000524C365D1CD6D787561E1754BD01D24926
-:10B1F000F960BC3E2183E82C8AAEFC5CC690F1DA93
-:10B20000B6F79D3A8CA34585952D36840F593FE5B9
-:10B210007059E5F399081FD976D2A99B49765E59F2
-:10B22000A8B76315BA6ED83907CF4D18FCA3504E96
-:10B23000924D82525C5D51B179807E6794ACEB7423
-:10B24000E857C6DB80C5195714809FD5B36865E4FD
-:10B250002735BC7E5D63E17ADB6B70BD4A7EDA60C8
-:10B26000F2C5CAC8D39A757393295F6E30F0F73F61
-:10B270009A2CE7BC827232223E5341984F3CF744ED
-:10B28000211C10E496566B18FF8FC0F7CF1FC277B2
-:10B290006B8AEB5D16CF4D5940FA4F53F2796767D1
-:10B2A000598A5D24FC16863F1093D5D28A470752EF
-:10B2B0009C1FD27BC1186E771F5AB95ECEB69A32E8
-:10B2C0001D1F5827D80FAEFB7A978FE2D02748086A
-:10B2D000BEF399D53540743489818C42D4D71DD1C1
-:10B2E000C70C6427AA1D0BA8BCA5C87F9B03BC067E
-:10B2F000E61FE59633F5982DEC07C1E5F81ECAA5C3
-:10B30000C8E9ACD2E371498D7B1FADA5AEF62A3CEE
-:10B31000213C41A2A7490AAD20BB3815FF9EE1138D
-:10B32000E6A753B93D2AF1AB674FEF6D691C744234
-:10B33000841F36EDF9E6AB0F50DF4DA3663B5D0F82
-:10B34000FBDF9616EA0BB01AD4C417D52F67751B0E
-:10B350007DD45F95ED3E7F39DDAB78AFDF4671FA86
-:10B36000E2FE401B95CBC19EC369DC2FD43AFE6B35
-:10B37000E1E7E493B9120575ACCB5E90BC46E4AB53
-:10B3800099EA0B05F6207CDC84761347F779BFA990
-:10B39000F6950DBDAF19A82FC1673CC46FAD42FF34
-:10B3A000AAAD375C4AF562AD57DB2FD6F57BD713D4
-:10B3B000DD753BB4FB6ABFD9A47C5F4FF59A8DEA7B
-:10B3C0003EEDBD26EA37F3A8FED3EE67662AFDA65A
-:10B3D00092FF40A933572A77883F33EBFF0C5E2357
-:10B3E000F2D6FC688BDD4270BAD9CEE26DFD0666FE
-:10B3F000C7EA7DD89AC86C44F5DBDA8DC0EA675598
-:10B400008EF94F1B1DA48FFCA793595D8CF53CABA7
-:10B4100047309EF0FE1E6522A0DD3D171FCA1411A5
-:10B42000CF733DD976AAB75F5EEB807F9D17A64F9D
-:10B43000ADF7E74A3BAB0CD447DD887D146E35F79A
-:10B440003ED96642B87913D00D242D3B8EEAA6E290
-:10B45000FD1278E91DF03E508E6B971A4F52B0BE28
-:10B460008F9047943C09E409FA79A3A2B7E8EC0469
-:10B47000CD798CFD1CCDF771A599DAEF3D0E7F6E6D
-:10B4800009C573FE7DBCE302CDFD36C16DF791CDDC
-:10B4900004F03FBC57AE88B1C2BF82CD1D12E71782
-:10B4A00068EE6F889DB79FECBBFC0BDD183B704BC3
-:10B4B000647765018047502FB386B5E7C507DB2168
-:10B4C00016F1471DD48D99577880EA16A3ACDD5F3D
-:10B4D000AEDAC55498AA99439C913BB7FBD1219110
-:10B4E000D945099CF7707911C9590F5E79BCDC46C2
-:10B4F00069A5FB6603F38B59BD2D768A47939D5A48
-:10B50000F927D768E59FEAD2CA3B6D9556DEE96E0A
-:10B51000ADBCCF6DD5CAD7EAD1CACFB67196E6FE1B
-:10B52000B4F64A0D3C7DF302CDFDF3BD0B3570CE74
-:10B530008EAB34F767742CD39CE777AFD69CAB7691
-:10B5400036D60E2EF4358FB13311C408FDAB7A56C2
-:10B55000EDA070FFAD1A3CFF6FFD6F1FA3FFA7C8E2
-:10B56000D731DEBD153B7437B9EB65D13CAE9D9943
-:10B570002794EB59BFF6B69C5815437795FCE654D3
-:10B58000F21B94FF91C3160EDBFDF67D14CF0A8EDD
-:10B5900038AB88AEA2807B1F85F392A1F6AA38BA99
-:10B5A000EF00D932858F9CE8FEE5A502E8347E8560
-:10B5B000F094B03CAFF0AC93E2F072D977DE36167F
-:10B5C0006EC9E94BC2F320A194E7856A4714E822CB
-:10B5D000E452A1EC0325E92961F9ABF323EC07C0A0
-:10B5E00040FD8068F2B65927AA77EC9B25568FB9A3
-:10B5F000587DF686E06273A545267F06C5F7DF25F0
-:10B60000BBDECEC4B8764AB4CBAC9E13026DC45434
-:10B610009018A3A4E5A9AF76501F87ED2CCD2BFF82
-:10B6200074476DB52797916F0994F0B699FEF56749
-:10B63000BA8E64A2FC0704CBFA42FCF6AD5927335C
-:10B64000287F1925944401CD4F1C47E9FCCCDC240C
-:10B6500019F9C3781B10650F89C273ABC0FA9093B8
-:10B66000F4D8CC08FFDDA867790B94BEEC1A455ED0
-:10B670006A5FB654C13F804FACC2787E4DF71B4C19
-:10B680002E7529C3CA1CCA6DB7E0FB374C3517505D
-:10B690005F0A8E423BEFE7D53E2D4DFA297955EDF5
-:10B6A0006BCF76BF2E6548D32FC3CEC409E7916315
-:10B6B000E75E61BEF9FB039BA2591E1AD894CEE641
-:10B6C0008BE1F74FB1F7AF71BFA3B193EB5ADFD75F
-:10B6D000D8DFF59E8F34E781A4903E0DF90FEC4A38
-:10B6E0009D7735CA6FE4056309F5ABA8B7385B7180
-:10B6F000F8FDC03DD3E710BEFFCDE7A74CBEFD6B04
-:10B70000FD6CEEA6F2796CED110607D606D83A96D6
-:10B710004FB5BF5557C3DF209BEAE59030C93ED1F6
-:10B72000BCE6311BEF83FA674FA9A47CDC9F6ED087
-:10B73000F1358BC3A9A5260ECF9B4F6B506FDE480A
-:10B74000FD6DBF000E01ED61A9E07CEC7AE4BB3A2F
-:10B75000D9956BA37A7275284F87FED0941FB8567F
-:10B76000407DBE1EEFCA27FE052C065313189D59B7
-:10B77000D4370C899E3C0163C14D4F765753FD3F32
-:10B7800034C9738A3276ADADAB9AFA832103F78F51
-:10B790005B9E7C84F9C3B716D74C7AE71341F2312C
-:10B7A0007B7E49F06E67F616302C8CF8BB823AAF80
-:10B7B000A17E9BFA9B60145F67DBF8DF5F2AC7AC52
-:10B7C0004B6D3CAEDD426B31E9E5EE2CFA7BCAE80D
-:10B7D0006623905F203E8748F87AF85C760AF2404C
-:10B7E000750D566FAC5F2878D5E8A3F8A1CE751615
-:10B7F000DBACECBD241B9FD724DD67F4B6B1FCEEB7
-:10B80000CFA8463ADBF558EF50DF7010D81C6D8496
-:10B81000E661117A596CE3FD17DC08C0CF93B7D10C
-:10B820007943EFC0318A27DF67BAAE24390C8872BA
-:10B8300009C59386D8BDACDE6BB6C9EC3BA497F1C5
-:10B840008F71E14ED2CF2F380F5C45FA6D300578FD
-:10B85000DDAACC03CF26B791E5FE8772D9FCCB9E3B
-:10B8600041F4A9F422FDCDB688B99D4A7FF89D1F09
-:10B87000F60B75AEA5C2835B3664919FA15EF8BCE2
-:10B880005112AE5B38C1F70F2AFA3E96E2F410FE71
-:10B89000D56E3EF70BDB4DFBCD4749CFBD66162776
-:10B8A000CFF6FD583E1BF6F43279209FD7127F1158
-:10B8B0007CDE1BC9E748CFE18772E59FCF5F309DF3
-:10B8C000FF1D29B8ED9B0C19BF6FD8FDC611B2BB87
-:10B8D00006751EDFA59D33182761FF9A30D11C1D08
-:10B8E000B34F445D6654BF9FAAD37E8F0539CDA95F
-:10B8F000BBC9DFA97E71F0BF8BA9F9B84BE96B8496
-:10B90000C0EB2C1F103EF287F58287E545758ED17E
-:10B910002660DE23DDBA5A589E90CE35DBC99EBB29
-:10B92000D006FDE4073A47349B5F8FE9A3BF35B8E3
-:10B930007691FCD6BC53994C7D76E79B0B947E8D1B
-:10B94000E7A962C52E8B093FD19F1BC7ECB548A163
-:10B95000AFC484F55026857C8FC4E715CAFC63D339
-:10B96000EB9A3EEFBF32596853001E000000000002
-:10B9700000000000000000001F8B08000000000015
-:10B9800000FFFB51CFC0F0038AC515191844D41924
-:10B99000184C341818566820C46989B5B829D39F43
-:10B9A000C9C2C0900DC4B9409C0FC47C4C0C0CFCA7
-:10B9B0004CC4EB171445B0F50419188480FC6F02D1
-:10B9C0000C0CD7851818BE8B30300803F92E40F1C7
-:10B9D0000420CE01626FA0580B905E04C4DD402CA1
-:10B9E000228ADF7C5102F26B8551F937D1F87B84D2
-:10B9F000F0EB5710C12FAF47401E1B16D1223F3E20
-:10BA00002229D03B10585F01955F26C7C0D0270F71
-:10BA10008C7FA8B80192FC4B20BB5C0EC2F69660EE
-:10BA2000602806F20D15B09BEB03942F01CA7D85AB
-:10BA3000CA0300CCCCBA8C680300000000000000F0
-:10BA40001F8B08000000000000FFE57D0B78144507
-:10BA5000B670F574F7CC2499994C12F2E03D490088
-:10BA600011030E2144C0709924C0A2460D021A147D
-:10BA7000750292849097887EECAEFE330189A0A86F
-:10BA8000F1B9AC17DD416137B2E8060C1835E0605A
-:10BA900000B32EBAC145C0E72680BC362443F0B9B6
-:10BAA000CB5E6F9D53D533DD9D09C4C7DE7FEFFFAD
-:10BAB0008F9F5FA5BAAAEB71DEE7D4E942328F27E8
-:10BAC000640A21DFC18F969F8B8490F850596F20B4
-:10BAD0002E924188D766F46D4CA6CF88237AE6680B
-:10BAE0005A981DD1375843EFE9CBD59EA434691835
-:10BAF000210F791C5812E223844EB55A2005F51601
-:10BB0000A83B93E07D3A3E21FDE8F80F46E2F8308D
-:10BB10002D99181A671031E07B53ADF989B01E4298
-:10BB20006A47E6C3FC163B21FD7B9F9F8E88EBA7EF
-:10BB3000EF0DC1F724FA9EB5EFEF2965570EFD13FF
-:10BB4000F6DF6DF66D1408F1EFFCC77158EF9986BA
-:10BB5000390E135D6F76B7D93F05EABE6C9F89B683
-:10BB6000E76EFBC026D1FEE5DB4409DA0D3B23F08E
-:10BB7000FDCE75820FEA95A6D647AEA4F5C03691E4
-:10BB80003C0FD3F82D069240C87133613F8715EB07
-:10BB90004511AC5ABE7ED76D305F49A38944D0F7BA
-:10BBA0008F37882EA82FD928F8089DAFFCB5078CB1
-:10BBB00003E878C53EA13EC241EB1B1F333AE83E85
-:10BBC00097EFFCD8D646E17CDA63260E23EEA3A4D9
-:10BBD0003E8D9052DF96E903E8FBA59B052780BECA
-:10BBE00074DDD94E585F69833C5CA4E32DAE8B2293
-:10BBF0008E916CEEEF08CCD77C14E7DB260F83F92F
-:10BC00004ACEDF650424E56E93912ECAE93A60DFDF
-:10BC1000CABCA73D6B713E059EE52FD2F968BF8A6D
-:10BC20009705276CB1C240DCB08ECED7220A5EB039
-:10BC3000C0FEAA8D23ACEA7D146E877D94FAD61BD4
-:10BC4000A75B607DEB8D4569A1F116D7FDA7767DD9
-:10BC50006B5313DD69BDE3F3B487827444A85E4A75
-:10BC6000880BE94FF219818E95E7E78518C4F7E252
-:10BC70003A9138CCA1F1153AF07EC0E9748795F17C
-:10BC800001C7DB123BE02C84B76E3BC7A314C8543A
-:10BC90008FAF948F003EE87A6A3D762C1FF72461BF
-:10BCA000F9A4C781707BDA3312CBB51E273E7FC65D
-:10BCB0003301CB751E1796CF796660E9F3E463BF55
-:10BCC000E73D05586EF0B8F1F96F3D2558D679AAD1
-:10BCD000F0F926CF322C377BBCF8FC65CF2A2CEB51
-:10BCE0003DB5586E057CD1B2C1E3C37EDB3D7558CE
-:10BCF000367AEAF1F9EB9E462CD77038DAB248B6BC
-:10BD000044E16073113B453B89CD7365CBB41E9B09
-:10BD1000CFEA09F3BCD9465A4F70D33A85CB80326B
-:10BD20007FB689D60754B1F621F7921C33AD0FF1D7
-:10BD3000B2F69435AE9C085A4FA965ED23D67973B7
-:10BD400022697D848FB58FDAECCF89A2F551F5ACED
-:10BD50007D4C13C9B5D0FA183FABA7EF73E55A690C
-:10BD60003DBD95D5333FF1E6DA683DB38DBD3FA9C2
-:10BD7000C3273A2C3DF1B055762C2014574DDEB92F
-:10BD80002E89CA9BAD46C75DC449C87BDEF92E89A2
-:10BD9000CA8706D985ED6DDEC5AC6E74617BB77759
-:10BDA00029F6DF2EBBB15DAABE0FDBB71BDDD89E27
-:10BDB000505D83ED8DB217DB47563F8AED8D462FE0
-:10BDC000B64FAA5E8BF5D7651FB6E755AFC7FEAF76
-:10BDD0001B7DD8FEF8FD9B5C5369FD05C1BD1DE4CC
-:10BDE000DE0AC15D4252819EEA9340EED570F9F9B8
-:10BDF0001C101D6DAFE96F443EDCFA6EE60BC0BF50
-:10BE0000F8EB07F5A2DF3E988CE3BC89E3C8741C0D
-:10BE1000F1E2E3A4BF3741334EFA7B25CA382D380F
-:10BE20004E44DFC6D9FADE24ED7ADE2B55C6D90F93
-:10BE3000FCB4C2DAB77DA5FF394BBB9E3F9729E31F
-:10BE40007C84EB89E9DB7A1A3ED0C2A7E183207CAF
-:10BE50008EE238F17D5B4FC6412D7C320E06E1D378
-:10BE600081E3F4EFDB380D07B5F069381884CF971C
-:10BE7000089FC17DDB57C6212D7C320E05E1F35FA3
-:10BE8000B89EE4BE8DB3FD532D7CB67F1A848F49D6
-:10BE900080F50CEFDBBE323FD3C227F3B3207CEC3E
-:10BEA00038CEA57D1B67FB675AF86CFF2C089FFEF8
-:10BEB00038CEE8BEED2BF3AF5AF864FE35089F1478
-:10BEC00001E033B66FEB69FC5C0B9FC6CF83F0B922
-:10BED0000CC719DFB7F54C38AE85CF84E341F86461
-:10BEE000E0BE26F66D9CC6E35AF8341E0FC26732D8
-:10BEF0008E33B96FFB9A70420B9F092782F0998E9F
-:10BF0000E364BBEB985146C7B1F63ECEEB67B4F0A5
-:10BF100079FD4C103ED7E338D3E838A9171F675294
-:10BF2000A7163E933A83F029C071AEEADB38AF77AB
-:10BF30006AE1F37A67103E8538CEB57DDBD7A42E53
-:10BF40002D7C267531F88C3B50956BA3ED54173A38
-:10BF500045FACA951D2E9740EBA29DD545BB93800F
-:10BF60005D222AF606697589F47DCBE698F4078987
-:10BF7000DAEEC8B913E8C74AAD31B5DD113D21523B
-:10BF800063E7C4B86235F5B8190334FDE3F35334FD
-:10BF9000ED8905A334EDFDDDE99AFAC092499AFED8
-:10BFA00083AB7234F5A1CBAED6F44FF6DEA0A9A7D1
-:10BFB000AEBA59D37F78ED7C4DFB256B4B35ED97B1
-:10BFC000FA9668EA97D5FD42D37F74FD724DFBE582
-:10BFD0008D0F6ADAC7FA1FD7D4C7B53CA3E93FBEB5
-:10BFE000F5794DFB15873769DA27B66DD5D4AF3CA7
-:10BFF000F9BACECEB3D88F5FC6EB22D03D61767F43
-:10C000007FE6F7F8AD46AC1B0758D08EDF652D7282
-:10C010001CA3F835BEB5C0D18FE217700A7E45F675
-:10C0200080924BDAE8F37B26B92FB1D3E7F718DD1E
-:10C0300097DBC3D8A7941E049204A5C300A5BEFD38
-:10C040000199D163CEC0F323DAE9FB9586C0881845
-:10C050005ACF12B31B817E770ACC2F8A144915F46C
-:10C060008B3411F40B1E48CE7CC1ABA2D75583296B
-:10C070001F0AA17157C9EE24B033DEAA6EF7821DE4
-:10C08000523398EE6B0021CD42BBDF4BFDB4070667
-:10C090001725B9E9782623B5D3D5F31BE9FC693810
-:10C0A0007F0BD0EB7B307F7CCFF94D291334F39B92
-:10C0B000879468E6371BE9FC7642DEAF3EC5E7A70A
-:10C0C000489844C85F845338BF694809CEFF8091BF
-:10C0D000FA2BEAF92383F31F86FD7FD6DBFE532676
-:10C0E00069F73FA454BB7F23DBFF91EAB37CFE4892
-:10C0F000DCFF51E12CDBFF9052B67F131B3738BFBA
-:10C100002D08FF93307F672FF39B52B3B4FB1F5A68
-:10C11000A6DDBF89CDDF5DFD2D9FDF82F39F13BEBE
-:10C1200065FB1F5A86F31B4D6E27D08F7160649597
-:10C130008FCE4F1D6107490472A1F340393216FDBD
-:10C14000E49784145CC73D918CDEBE8AA4F486F229
-:10C15000C6CBFC581F956C99D4EFE2B4BE7873B689
-:10C1600011E412B6537F65215FEA1D8D22D2377923
-:10C17000D2E41B4ED7DBD9287AA17EC793937D20CA
-:10C18000FF2A4DE4F67C784F227E78FEF953A39F78
-:10C1900057EF4B5F2EAC958FB7A9F82DE847E59088
-:10C1A00091551698D7AEA91FA17E10A1FEC527D420
-:10C1B000CF2094248FCA6CBECFA8BF04F536EA2FD7
-:10C1C000413B21D5B85FE2757D308CAE3F9F283F63
-:10C1D00017EEF32664293A9EC4F8F7C81AC107F887
-:10C1E000B87D5914057E683D85DE384D9DEE0FFB08
-:10C1F00007AE127CCF0B38861BE033938F4760BDB0
-:10C20000B45E6067EF1CA2E8EF4F51B060D5408A82
-:10C210008BD038B3884B4EA4EFCF595A2843E8A2AD
-:10C220005510062F01FA5920539711E0E78D276921
-:10C230009C38E87A6FB6B3F167BAE4636DAAF51477
-:10C24000C866573E5D4F41A188EB9F3543DBFED169
-:10C25000CE2897610C2D573D81F3CCC9D7B6DF545A
-:10C26000A0ADCF756BEB54EFC9A0F76E29D13FA7F6
-:10C2700060A1FB9C17842B5D285DE7AD1C0EB756B3
-:10C28000C95E0D5EC16D55DA21A0E026B82F7C5F36
-:10C29000ECD9FFF665DA7AA1575B5FB04A373EA763
-:10C2A0009BE31CFF47803E687902E883C2F318A72E
-:10C2B0008F905CD5D2C78DC16D30FA50F6715C623B
-:10C2C0002838BE8ED1C7C2DAA8F0F45018A4079758
-:10C2D0009ABE147AB88DD3C3A79C1E8AD76AE96A1E
-:10C2E0002EF1AD4CA2EFDFB26617E2E9A050C8E82C
-:10C2F000E1970A3DB469E8C1CDE9418FBFDB383D24
-:10C30000DCF673460F7A7CB6717A685B7B4E262921
-:10C310003DF14AF1A0A9533CE8F06E37023D507C54
-:10C3200084A587F9C17DD38DD3FA02DED6035F9C45
-:10C330001EB03D05C04E104EF87E6ACFFE544E68CA
-:10C34000EAC56BC3E3BFB2313BEE986A5DE5F557D2
-:10C35000C51D53F55B5C3753535FE49BABE95FBC92
-:10C36000B650D3BEB07691A67DC1AA3B35F542EF5B
-:10C37000CF35FD6F5F56AD69BFB56AB5A6FD969224
-:10C38000C734F5B9EE5F6BFADF54B05ED33E27FFDA
-:10C39000454DFBAC195B34F599AED734FD0D3B2F01
-:10C3A000BD1EE831EBA048C0FE38E67120DD1FF766
-:10C3B0008CC4F2A4C7897C71DA3301CB7D8DCD4F5B
-:10C3C0005C49BB7C192888264C7F16911842F62CB4
-:10C3D0007757AFCA027D4E50EFFE717951B5771095
-:10C3E00095530607C2396FAD91F8C711228052E20A
-:10C3F000F307C4507B561B6D8FEBBD3D6FAD14B67C
-:10C400003DAB4D0A3B6EE5E38543ED61E233217EB2
-:10C410002603C13EEAE2F6B9BEBD4C20F9EAE78444
-:10C420002C47FE8F3130FD5C666472A26C6BFF1C82
-:10C430006283BA7F44D585E6ABA7CC9508F491AA70
-:10C44000E1E3E2B59769E43C81E86D3CD0D938CDB1
-:10C45000F3C575576ADEEBD825E2BA2B4086507DCE
-:10C460003D8CE4070CA097FDCD43668D8675BACE52
-:10C470001A405E35C6A3FDD8E19911774C023CE61F
-:10C480006379D25380E5718F1BCB639E122C8F781A
-:10C49000AAB06CF32CC3F2338F17CB4F3CABB0FC7C
-:10C4A000C8538BE561CF5A2C0F7A7C581EF0D461AB
-:10C4B000F9BEA71ECB564F23969D1E17960ABF297D
-:10C4C000F0D0D3DD49AEA74F03FD5D80CEE2C407B7
-:10C4D000AA570D0AD159E28A87ABBD59A171F3D68B
-:10C4E0009A389D2468E86108F864E3815E4C9C5E9C
-:10C4F000C2B7E7AD952FD89ED526871DBFF2F97F2D
-:10C500000DBDCDF991F416A2A7813A7A4ABD183D26
-:10C510004D12C787E8698EC1CEF41FA7A787601F99
-:10C5200061FC8F6230EAC6ABEC3A57148B67F37349
-:10C53000076AD1B278369F7B051DAE15ED3FDF4807
-:10C54000C073F7C8BF8F80787DF761AA28937BDF1F
-:10C550009F9E5E7A87BB0BFDA0221F55A2E37AB691
-:10C56000474432B84618C80C924EC8EAE1BF75CEAF
-:10C570004FC3BA4462E17D9F736698F32802674F08
-:10C58000891787EB0AEB576360BCE3CFFC2313CA20
-:10C59000398614E6DF348B68DF13FF0B4E806F5053
-:10C5A0001F999C4910070F0C37DAD13EF059B4F0AF
-:10C5B000F3D27A66087EAB298C5A51DFD72621FC4C
-:10C5C000867D35A27F1FE07731397F3178CEF70D38
-:10C5D000F897C0F362F2F1627291B81C2F37D2FD66
-:10C5E00077ED1C9DFEA003E4E085E1AD9C5FE9D7FB
-:10C5F000F3BC287D2F3AEE4A50E8B87508A1F388BD
-:10C60000A21DC7EF6EB884C92FC5EEDB66F2F50533
-:10C61000AF6792B5E33DC5F94F19AFBBE5051BF810
-:10C620005B4B920CF66361F0A094E5F5C9768BDA6A
-:10C63000FE6CD4D6BB6B8519F568273AA2678F06C6
-:10C640003D61B71F1B06723B094B659C254946FBA4
-:10C65000312AF74ED7A546333FCFC7E4C1E6189439
-:10C6600017A73D66ECFF53AFA7B77194F510D24002
-:10C670008E9A411ED3B6D4DEFBF74ACFD217463C82
-:10C68000F76D92BF02FBD04CFFFF0EFC0D22615DE7
-:10C6900019B7B25EF49A2E87E79B35F3D1F71CCA1F
-:10C6A00019EB772917E21B891C57E896EA8B635C24
-:10C6B0009F2CAE8BB06BEDCF184DBDB2B1BF5D639B
-:10C6C0008FC21F54FE922A4102FA29E3E4D325596E
-:10C6D0005609747D6F429010E85660FDCACD6D46D4
-:10C6E000B703CE9519DE7A5B1FC5DF4C89927C8932
-:10C6F000B916CF614BEA2F9D0A7AE64CC38A0488AB
-:10C700001B2C16BBEFC90FF3BE2C3179BFC827070E
-:10C71000B4F63DA70F42C7559E635C94588EABEAB2
-:10C720001D06168FD18F9B00E3C65F1C3E159BF73D
-:10C730004F073B410FA78AC6B34637CA45FA5F6623
-:10C74000084E0AFCDE14F313243A7E695D3BC62DC5
-:10C750004ECADE11BFBC80BCECB93F4BD2F128D52C
-:10C76000BEBCA415E6993F814F441C377D4CE5F8CB
-:10C77000A93FC904E410394F7B65624886FB3B063C
-:10C7800062C80CF93BF31B16E701BC4F81BF47E5BC
-:10C79000E61D24DF867820B599E0DF9C218619000C
-:10C7A000A733E47DDB38151E7225238733958294E9
-:10C7B0001E4CC1F1DDFDC1EF3215D4B48A63E0B97E
-:10C7C000A4F83FC2771847720B98B750C09E7B8978
-:10C7D000B91AE897FA511A3F8DFA519A3AF5A334EB
-:10C7E000F522724302E425143D29139F8070D2B4D0
-:10C7F0008F92EC88C762525503F6D1AF79FC6DBEBB
-:10C800009D4803E93ECB5F7D36B390EEE76A89C56C
-:10C81000FD9473F545B10C0EA5253EA3CBD2737FD5
-:10C82000471BC6DD48253F8CC7CECF6F36621E053D
-:10C83000B44A99DCF449E97DFF890DA22BC206FDBB
-:10C84000E87365BDC9DF7FFFFAFD12F238EEA3B4CD
-:10C850006E2601FAEB9127C0F723D7092E5F187EC9
-:10C860002AE474AFE8A73B017EE343F1ACFB74F527
-:10C87000D51CBE4AFD295DFB0F962FFD8846BEBC28
-:10C8800029BAEF93C6337902F017A400F2D70F1E2E
-:10C890003FA9C7F8AB811F7FB2F10769F99E8EFFF0
-:10C8A000D44FBAFE613DD6BF3EDCFACB5F7D69BB9B
-:10C8B00097EA97D23F3C652394DF4E49B5094E8AEB
-:10C8C000F7B28D2B6D2E903B92D7067C71CA27CE86
-:10C8D00008470F87B87CA506884580782BFC49C798
-:10C8E0003FBDE9A1EBC09EF86AA36CC7386A9DC939
-:10C8F0006FA2F45CD1B0288F8CC17A3BAB3F70162D
-:10C90000E8BFB2513EA2A6D3D2DF3D95007935945F
-:10C9100052061A92A0F4A37F52B1E1F3E9606F547A
-:10C920009200F2ABFE3D98FF9B58D48785C6E89EE7
-:10C93000ED18984980F7D9AFB2E1A1B3A20DFE6A14
-:10C94000C33890BE7F09F7375A246B3F3C27B98222
-:10C950005C01F2548107F1317F63C58BBF1AD34E5E
-:10C96000D7D3B1E14F36410527C54FEAAE5FF09B03
-:10C97000D71DBDCBEF4ECA876ABB56D14F8E46EE50
-:10C980002735B1B24CF6DBAEA4F2A46CBDECF4D208
-:10C99000C7652FBDF0DB67207EFDA1C9399C8EBF26
-:10C9A000F8A53D0727D1FAE22D72BF3CB60D8B905A
-:10C9B00010C24B25FD7F597A080FA5AFEC313A46DE
-:10C9C000B3E7F7C686F0B178CB2E2319DD131EB975
-:10C9D000F5BB8C6D963078A96F9F0E76DF8A17BFF6
-:10C9E0003682BC3BB5532089C961E0B97E0FDA8538
-:10C9F0000027C423C753106FBAFE95142FA05F14ED
-:10CA00003CE9DB37717902E339D2909E5F7E9DCE9F
-:10CA10005FF291C909FB2F79F92E1BECE38454C511
-:10CA2000E8FAD9950920DF4A646F821D4BF6BCE411
-:10CA3000B9BB91DE8AF7DF9DC0E292AEFE06D495C7
-:10CA4000DEFEB0BF85EBE6E0FE8A881BE9AEE45966
-:10CA500031DF47CB2F2532634B18BEB8566672F2D2
-:10CA6000C4F35423D0FD9D50F4C0FB22D70377625A
-:10CA7000DCF36EBE176A3162FD4B33C3D330D9C0CD
-:10CA8000E52CD32B417ADDF000EA8BD3835D8970EE
-:10CA9000BE5619D20FA837C4FDD312197E989EC175
-:10CAA000F7A89EC985E7D0BF5576458CD1BC877A5B
-:10CAB00045997F299F9FAE3B12ECB51309E1FD8F8D
-:10CAC0009FCB0ADF53BB42455F2AFE66FCBE613541
-:10CAD000E36F85DF7D336740FB170718FFC07BA03E
-:10CAE00067E9BAFC89D8BE6BB680F2C044FCE1F8B5
-:10CAF0007A83CCF95ADBAED0095DB72444ABE805A4
-:10CB0000C68F45F8A35E2F7A92BEA7929795309F65
-:10CB1000ADE7780ADF1673FE9F216BF99FAC8BEFB0
-:10CB2000533E6599ECFBED33C0AF943FBD0EE0572B
-:10CB3000391FF6FDB7CDCD076FA67CFAB77A854FC2
-:10CB4000B5F253CFA7255BEF26409F7A3EFDDBA0D1
-:10CB50002A12964FE9F3B07C3AA8ED7F547E2AF072
-:10CB6000AB02F84585E0A7C8C3DEE0A8978756D991
-:10CB700011561ED2DF0192D993FE14BA53E8ADF4D8
-:10CB8000F7E54341EE04E952A1BB205D2A74A7DF1B
-:10CB9000AF167EFAF64932C175E5BF26A3FF5CD613
-:10CBA000C4F242E97B7B0766209C5CA8C648EDDEA8
-:10CBB00081FDD4759FAE5EAFEBEFD2D5F375FDDD91
-:10CBC000BA7A95A67F5963B39120FEFD9A7EE2B2B0
-:10CBD00067C8D1B870F4EA637E59C359A317E8C295
-:10CBE00012C0F7E5E5C40B7986811D22C605BA2877
-:10CBF0008C6B207EB139D9E7A5726365048B3F74D5
-:10CC0000D903B6585AAE8C61F540BCB106E49EF229
-:10CC10003C10C1E28A5DF9015B8CCA9F6A6F1251B8
-:10CC20006EB7F9C88C707E16D528C8476DA4B77644
-:10CC300076EE354DB40C590671A55AD10936F81D5A
-:10CC4000D537D9E0DCA9AB29F5FA02FA7CE11F451A
-:10CC50004C7BE98AB48D817511AF4BEAAFF26F4E10
-:10CC600012EFD359747F0B9A989F73C71A9D3D4258
-:10CC7000D6203D1559961A419E527FE288F6BC8611
-:10CC8000F145291FAF649DB65D799FD201FAF3A5E6
-:10CC90001BB4ED6EEE0F7FA0F0C9583296FBA32CAB
-:10CCA0000EC3E5F23431EDFA028A8FAE1691986820
-:10CCB000BDBB49447C746F167C104F23DE78E4B70B
-:10CCC0000A124079A8C0A903F8C9D8BBBCEAD8F6B3
-:10CCD00069E62F816EB67F3CE63F69D9B1FDC3118D
-:10CCE0006F40FDD543433E263DFBE7EE8CC073FF0E
-:10CCF000AE9D56A4F7AE1DEF0EF925D45F33396112
-:10CD00009D5D3BBF1E03F4D3B5DC5402F2AE6B3025
-:10CD10008BC7AED8F1F59836D4AFF733FD6164FE1A
-:10CD20006177D33F3E13FA4149770576C3CE28E4B5
-:10CD3000A7CAD72330DFBB6BC7D7996ECB4FB79F3E
-:10CD40000A9EE7D16525055B617D312C8FA1F28DAF
-:10CD5000892F54D3F9CB1B761917D0F6DC37FF395E
-:10CD600006E468D756660F75CA6DCF411E4394F12D
-:10CD7000DC7299E2AB13988A3ACDBF3366E402DFE6
-:10CD8000F484CB3F313ED65778A4FCAF8187E06274
-:10CD9000F2CEEA330BB0EF6F3FFB18E39A26A44BB9
-:10CDA00065BF7FABAF467BE562FBCEFE7F6EDF8269
-:10CDB000BF2FFB76FF9BEFFB38D7BB7A3EE849E7F6
-:10CDC0003BEEC1FA4B5627AEB78FF4EE85FDC7FF99
-:10CDD000FBEEFF7BE37D2BC5BBEDE2FBFECDFF5AF7
-:10CDE000BCFFF1368E773B7ED7F3E63F717DDF5790
-:10CDF000CEBDF96F8EF7DEF6AFD8F5AD862A7B068D
-:10CE00005D5F01A9B582613137BEDB92E1806CD7ED
-:10CE100073FD308F0ECE4BC3F84D0123F30B4D90B5
-:10CE200047077EFB1C41890BA21F751DB71FAE1B58
-:10CE3000548276C875AE8799DD2055B566D3FEADB0
-:10CE4000390B9C987349D20FBBA13E7B32AF6BFD6F
-:10CE5000C9F704E212A81D7F5DCE352D60D75EEFC5
-:10CE600012D1EEA525DABB1F0C99CE9E4FD0FA3D0C
-:10CE700073DDDAFA4D05DAFA1C3EDE8D84ADFFC6AD
-:10CE80007CC107715553F613F11067352D948990C5
-:10CE90000CF942552BC1BF9893AF7D7F1FF8C1E3BA
-:10CEA0007F3C1C534D0A1C97205C48B6E8DC48FACE
-:10CEB0000047BEEED6D9637D90CF4C242783E38D07
-:10CEC000E54E8C83737F5BE6EFCB9655ADC0CFB25A
-:10CED000CECF56FCE5DEE04DB8FF8DE3A484E02F15
-:10CEE000BB44F4BF659DFFADE0E5FBE243C1E38FCA
-:10CEF000C5CB973ABC0CB2B808F0ABCCFD85A916EF
-:10CF000027AB0FCA2778DEC8FD05A99F8B78D342CF
-:10CF100079DF8BCCE66C385F338F1430DE71FD1A0D
-:10CF200011F583394DC075E54F90318FF873437E0D
-:10CF300026E03B6FDC1515BF60CB70023C1771B863
-:10CF400017912AB45FC9F9EFBECBCA84730682F683
-:10CF5000EF221721D752BFAD284BF0475278154B1F
-:10CF6000C41B9D0E716F811CD1C4BDB575F8FD4702
-:10CF700042689C8BF5EF4DBEFCD4E55FA93C3B328B
-:10CF80008CFA411E9EBB4958DC56F1AF6F6F627040
-:10CF9000AC2C137C2948777E395F75EEF81CE7834B
-:10CFA000BFDE3B0EE564F6A3A3A3D1EF7739D06FC4
-:10CFB000A8E47E43B7D7110D71AEEEA6547E3E9B1A
-:10CFC0006B53CB55A5DCCFFDEEBF407E212DBBA61C
-:10CFD0000AB522F8712480F15CEFD408B2314CFE1E
-:10CFE000EBFF311938FD54611C007E6226E091FD93
-:10CFF0008AE9ABD1B12ABCADB9F69434A6271EE0BC
-:10D000007744750EF963E10B7E3EC0757F44DBF417
-:10D01000FC30FBAD35B13856DE5BDFE2779C373450
-:10D0200025CB00971BA68A9A73FB5526EE978D2376
-:10D03000E3605D796F5D659B087869119DF0DD6641
-:10D0400065D359A33BCC79B01E9E303EC4D58FCA60
-:10D05000CE2280E7D1872308F8D1EFF273C634F8E7
-:10D060006E220D433A2E882BFE9AC3B5D364C77245
-:10D07000565EB61C4FE74D6BB08F85A3D401BC7FC5
-:10D08000271821E3218987BDA7F41B50C6FAB51BD9
-:10D09000ED15E1F63F3C82EDBF9838EF9920FCFB9F
-:10D0A000E12DFB51AB3F07EC83A93CAED283AE0927
-:10D0B000F247F70CC107FA1BFC61ACE7B1EF84DF64
-:10D0C00055BEB3BE81E95985EEF570DECBE1ACCC3F
-:10D0D0007FDCC4E2AF7FE2FCA5C05981AF7EBD4AD0
-:10D0E0007F2AAFA6A8E351D7378E7D19EC9B8A26FD
-:10D0F000C16EA04355486D46E0C3CAC6C764386FC9
-:10D1000099EB60E312297F8C3A9FA0D3C4F23B9A3B
-:10D11000D3AFBC0DE8E4DC1A13E842E2BAE3AC0D8D
-:10D12000E4F0BB06E79FE17B6AEF7B22D9780179C7
-:10D13000F5B1A7CE3555528F9B8CEB9C55962D4360
-:10D14000F8EC96B25D72A28A9E3A4DB1D8AE3C1F01
-:10D1500050E64887E7743E5C87F7111381EF42D2AF
-:10D16000EA5BF1FBD45BAA62181D96D4EF32623DF4
-:10D1700019FB2BF329F3E8F969769E36EF78416EB7
-:10D18000DB20804B9EC9BFD419864E1F332BE78E00
-:10D19000DF534FB828DD8EF9FF484F2C55F4441B60
-:10D1A000E6B92BEFCF35333E57E989C4707A62492F
-:10D1B000B52311F0B064476A2230C9923F4E4B0844
-:10D1C000A7273EF0B073E343FCBBEEAED9544F5CEF
-:10D1D000AED213B323904EF4EFE59A95738D8BE89E
-:10D1E00009056FFFC3F2E603D01361F8FB46B3569F
-:10D1F0004FDCD854887AE2C6D9A2E6FBAA6BCD17D9
-:10D20000D313D90973B12E3BA3C2D0CF07DCBF39EA
-:10D21000C4F3FB611ED0176BCC76849B5E6FF42643
-:10D22000D7C7F655AEFF5F82B322D797CC61F743DD
-:10D23000F4A44382F4BC642E95EB02D02393EB4B11
-:10D240006EE5714E9D9CCD07399BA196B3ECFD0A0E
-:10D2500037D30B958DC9BF9A47DB6FAE959D66DAC4
-:10D26000FFE690DCCD54CBDD356609E1DC43EE967C
-:10D2700030B97BAE691CDA4FBDEDEF532E6FA93C80
-:10D280001BE60C431F05F3A234DFDF1D1DFB76DA1E
-:10D290002BC02FEF8A787EFB39B703F68D7D3B03D9
-:10D2A000ECE9537C3DDBB8FCEBF4F85C53A91CC8FB
-:10D2B000BD83D9D3E59B45845F4503E3FF8A619134
-:10D2C0003E07AD4F4FFF16CF6117EF60E7B0740711
-:10D2D00079D92AFC2F7EB7AD06CE0516AF17F01C04
-:10D2E00019BE5F0078167378163917E3394AF1DAF8
-:10D2F000F0E73FE5BCDFA2A6F5180F5FE4D3F62BFD
-:10D300001F76F529F047F24C0C0F79AF08BEF5C92E
-:10D3100090CFA0EBE75C8DE747E5F5DAE707F97E0C
-:10D32000178AFEB457E8FBE4CFCCBFD3C3FBA01EE3
-:10D330002E253F122EFB295C32FEF570E90D0ED42E
-:10D34000BEC7F3013D3C0E2B72259D64001F7E6E0F
-:10D3500070A15CF1BE43E142E7BBE3B1E19AFB405F
-:10D360008E73B8BC6B70D7F4877E1502F62B5EB750
-:10D37000654F02ADCFAB2763E178A178AD560F07BB
-:10D38000F57E8303F5FABCAA2D02E4C72EE4DFFB89
-:10D3900095F81EC37B546E5D46F53CEDBF20DDE481
-:10D3A0008673F0FD1101949B0ADDC64730FB258E84
-:10D3B000CBA1A3030253513F350A76E4477F04D340
-:10D3C00057144F70BF4BF3C4AFA773BCB0B8522310
-:10D3D000C36325C51BF0F3F4265EAF6376E02D4AE8
-:10D3E000BD5EF0390490ABBB64765F8C40E2048E86
-:10D3F00004957E84F3D5EC04159E77B433FADF28C8
-:10D4000038F1818FFEF743F0DC2BDD333BA6AFF420
-:10D41000AEC0293E428BE7FD11AD79E3FAC1F99B1D
-:10D42000E0C47B739A62F09CE8582DBBFF2595BF42
-:10D43000A7E70BF03BD4F7D1CC8485437EF38C086F
-:10D44000CC0FC57953985DA6964FFA7B80BE6FFED0
-:10D45000512569457B2C94C7E87EDE04E3CD10346A
-:10D46000F94E1009033AFF09C6BFD57C81F14992F4
-:10D470001DF396EFB22BCFEDECBB2C5E6F1E9C79AB
-:10D48000681E85EFB955A2135CA89B0C8E835920AA
-:10D490006F1E9409F0CBB97DB28BE98128D43B850E
-:10D4A000EF1EC5EFD90A590E1A29BC8FE997A37C44
-:10D4B0003D1F51BDED82580AA91F0FF7E0CC76EE53
-:10D4C0009AE680784BC6FE9570CE392BD77EF02039
-:10D4D000E07335BB07E9C8AA5CF4D3EEBA53407ECB
-:10D4E0003B4CF106EFCF999D7CF0209DF7D655F18E
-:10D4F000786E39CF157F239C63CEDB273A1DB4DFCE
-:10D5000082EBAD1638C7BC66A448DC2AF8DC4A5A60
-:10D5100031BE33AFEACE39B0EE12AA0FC56428F798
-:10D520004F4B84FA3A01DFAFF4BA8DF0BD66EBDA07
-:10D53000B3C60C3A7F11ED0760AF5CC7FA556E10A9
-:10D540009C90FA5DD4F418CACBA20D025E34D34A83
-:10D55000ED5F331BD767A6E3B6AEA3EFD37A31BC3A
-:10D560000FE36E88B911CE272BE93AF1FD09D57882
-:10D570002E5D44DFA3CDA475C39D38DEA275028164
-:10D58000EF034B26243F3201C6DB273BA1FDD0AE83
-:10D590005F1B61DDB7D1F9FAD3F117886DD3A03FD6
-:10D5A000F9A560C7FB87EA4660DCAD0B360C2F544B
-:10D5B0000DC73AE6133B100C923A1F654704FB4E29
-:10D5C000B86859750DECABCD1B9F6C40BA3A6B0433
-:10D5D0003D7E8CC2DB4D873C6A64792ECDDEA3C6CE
-:10D5E00036951CFD282215DFBFA3311BF3261692AA
-:10D5F0007CCC9B7057337BA47D65840FE26AEDB2CF
-:10D600007D083C6F5E69C2E79D2F31FDD339B80DAF
-:10D61000E3DB27D6C904BE5F5CB12EF569C0E389A0
-:10D62000CD32D29BF82CCB1B287E89C5C99AD7B1A5
-:10D63000714F2C35B27BB5A09DD68B5F54F20AB4E6
-:10D6400072ACC8518A724A2F97F4726BD193D54647
-:10D6500020D91EF26AE9749457A554EF00A1F59001
-:10D6600057836A306EAA975795C4A2C8A974885F79
-:10D6700016960FBE6D2DD0F1ADEC838156FF6B5F1A
-:10D680003E057AB7CC4AE04985647F5A6074418090
-:10D690005FE6356DF912F8A0645E04DEC7751CF014
-:10D6A000007CB3260ECFAF8B7C85086F252FB77813
-:10D6B000AD96CE95F8E35CB7485C6AFD5512455CC3
-:10D6C000AA7E87EEA3F44AE7B9BD51F081A83C7465
-:10D6D0005FFBDEBB33B06EC7752DE3F6C11A2BD2EC
-:10D6E000F3A19F9F5D09F47ADBBD02017B9D78DD8C
-:10D6F00035A00F2BD60A0E880F17DFCBDE2FA6EF33
-:10D70000C3BA0FFD9AD115A56F07D07FC5BAC7F66A
-:10D7100062FF0D8203C63FB4BE10ED8912AF48B060
-:10D720007D433BFA0F544F619E59B3574C00FAAFFB
-:10D73000B8DF64075349A123852EDBF97D08C4ECCB
-:10D740001C338BBEB70A1615DF931EC50221A84FE6
-:10D75000814E2ABD8CCEDA5F929D403617A74BF6DC
-:10D760001DFC09AE5FC567E74C87EF748AA97E048C
-:10D770003A6D5E976B043BE2844FC0FC8A9E74490D
-:10D780002C6A3B4AA1CB670526AF7BD0A38E0E7BCC
-:10D79000D01DA74B85FE2851A35F59B64F26F0FD3B
-:10D7A000BD9E1EDD72FD8D90FF51F832DD0F5D6F65
-:10D7B0006ECDCFD15E57E048EB09502F9258DE8FE7
-:10D7C000C20FE512CB0FFBDEEBD3CDBF2982E7877B
-:10D7D000013F882C7FC94FE77D7BF30B982F79663B
-:10D7E00053FB7568DFBC41E900E0BFD94AFCE87F24
-:10D7F000F8500E953688986F4D247FE62C95DFAE55
-:10D80000E4BF2CFE8315E15DBAD5E4CBA3EF976EA0
-:10D810003F3A06F311960730BFC7BB4960E71FDEEA
-:10D82000B631F0FD50A9C4F270F476C1F04816E7A5
-:10D83000EA782DAA00EC36A18EDDB3575A7F936C9F
-:10D8400052C5750745CA382FED87E7635E8A67B80A
-:10D850001F01D6A7BEDF4DC9BFE97891D15F69A38B
-:10D860008CF65C69DD964EC8C32C3D6C423FB7B266
-:10D87000EEAC11FCD8DC3FBC84F7F355368A9A3CF9
-:10D88000BC1EF96F75A2DF04F95B0DE5787E43EBF2
-:10D89000ED58AF0F9F077AB13CADC57FD8B1DD4BD6
-:10D8A00041B8F895DFD9F0BEBED68D36FCEEA9EEB4
-:10D8B000C2F9A73DF2DDEA575F30DFED34FC4109E4
-:10D8C000EBBA485DBE601D936B747D99F961E2C44B
-:10D8D000417BEBA52F9F837CEC8EAD7F7B0ED65BCF
-:10D8E000F65FE79E83BC1AB233C20EF648E5A60F78
-:10D8F000309F5579AF2492D97F9D2FFE0EF3803B48
-:10D900003F343961B4CE1D278680BDD1B9E5DB0433
-:10D91000C8EF5DBA631AC673966ECB4D2461E205FB
-:10D920004A0974EBEB431EB21E5FCD0DCD98FF7319
-:10D9300086E21BE443307FB1BE9CE5833A78DEE2A9
-:10D94000E6F0F9DE3DF2141B665D3F19E46203B3B5
-:10D950000B2E9AAF7880E2F1F23EE06FF36A2E4F21
-:10D96000C2E3EF0CFC41F15413A9CD57FCB261E1C5
-:10D970006F9E81B686B85EF315FD7D809B924F3E0B
-:10D980002BD2F55824F0CDD6DF637E28E02DCF01D1
-:10D99000F2F9CB2110173E290730FE10D861C2EFF3
-:10D9A0002C4B771C42FEE9DCB61FF3B509CFEBEE3A
-:10D9B00024C11FCBC3E5B19ECA0D5696E7C8E10F3F
-:10D9C00079900E1B3EE7F98E8C8E953CC8DEF21FD7
-:10D9D0005B2253F87D2A2C4FB37CC3C73CAF308405
-:10D9E0002F6102E0A9FD8279A50A1CEC00872BD4E7
-:10D9F000F9BCE1F34C8379DF1C5F803F90D3C17C9D
-:10DA00005D5A1F04F99B3EE11009230F3AD7B33C3E
-:10DA1000E04E39FCF7CC4A7E6FB39E4F7D7DCBEB59
-:10DA2000BDD8FABF2F7C1A221D38AE1E4E1DE7C38B
-:10DA3000CBF1E39CEF7FF0F7216582FEFB93CF8172
-:10DA40001ECB1BDA8D789F89E23FF1FD76F0785A84
-:10DA5000C72611F33E6BEA9B518EEBE545053F2748
-:10DA6000D1AFF71BBEDE8A46A6273AB65A7D163AD4
-:10DA70004EC75BAF213D576C6EC7BCD3BD75AF18A9
-:10DA8000DB54E7CBA0277CAAF577BCBC6B0CCA6D36
-:10DA90007EBF987E1E63149BA7B229FC3C959BCF4A
-:10DAA0006AE659ECAD37DA2D179FEFB4E4BA09C630
-:10DAB0003BDDCAECA5D3F5E20C5F98F94F71BD4987
-:10DAC000482D3B0FA5FA12EF59B3B27BD5445B2426
-:10DAD000DA5F4BAD130E47F783D288792F2BAA79E3
-:10DAE0009ECC7DCE24C0F70AEBD504D6BB12E0ABAA
-:10DAF000F2E365BB9B80DD2627E567A8CF5994F547
-:10DB00001BFB19884F85FFA5D61989E07F12C93BF9
-:10DB100008D6715DCAD712E8BF560F8BDF93F34763
-:10DB200087C1F356C9BE278E8EDB3A557042E8B5E1
-:10DB300027DDFB347186992EED7DB1F80D1CDD5F7C
-:10DB4000B7D380F6A0D5E0B7D32EC41AD19A840EED
-:10DB5000AC8338A404FC1402F3211EF49867C1FDC1
-:10DB6000C83642CD53E8E79434F79F444F9074F79A
-:10DB7000A19003C328BD5A38BD2A71392BFB9B8E57
-:10DB8000DB86F7ACC4A4916A20DF355637DA0D4F37
-:10DB9000F0FB69E86F24E441C49248A7FAFE263AF4
-:10DBA000AFE6FB383AAFA61EE3D2D6E36648C7C25B
-:10DBB000E99738BE8EE9A205E11033CDA0F86B7964
-:10DBC000C31342EB8E89274E3FB45F6BC1EF012830
-:10DBD0007B79D5FBB058B4EBA6EBD3C889E8B43653
-:10DBE000AF81AD53F3DC4E1C02EEDFA57D4ED7AB0B
-:10DBF000A917467179271109E49DC5DC4A38FCBB99
-:10DC000035F0BE5FDA373801F043B85FED2590CFCD
-:10DC100012CDF741E7D7F4B7437480CDAF1D870C21
-:10DC2000B2ABBF43BD9CEBBF5196FC2551949E32D5
-:10DC30008756616276561249C3EFA59BFAA17C4ACA
-:10DC40005996837927422DA3AB616B08F2CDB000C2
-:10DC5000CF9BBA3F12ED5193997823D2E17B36E204
-:10DC600095D361161FCF43702C37D0A1A45594D6FD
-:10DC7000E87B4D811CC3428A847A68A2E35746B987
-:10DC8000AAA3289FD6CC742719C6C2F6DE5EB93B7C
-:10DC90000BB9F65288081AAAF7EE69198C2204EF1C
-:10DCA000F120DEBD7B80C66B953A15ECF09D7F6D53
-:10DCB00064B0EE3253795F9BC2EA8F3EB47725DCC5
-:10DCC00037936ECF7F14F649CCF65178DEE58FD5C9
-:10DCD000DCF3DD9B7E51D63972833F17EE05BE3AE9
-:10DCE000C0EEF51D6E0D7E778F7A78A345A9FBD126
-:10DCF0008FC86FD88F72ADBC7E3FB61BA04ECBA134
-:10DD000071FEDC81749F2F471D9A9674291DAFA167
-:10DD100030093ED97F35EAD01EF8EE3004878F57A0
-:10DD2000EE1E148283B4FCC33D2D93D570F8700FA2
-:10DD3000D8217D85C3AB0F7D8870E8EBBE295D6C73
-:10DD400007BC5C936DC0FBD6AE386CC1F80AFD45CC
-:10DD5000A03EE2E3ACEFE5BB6CC51FA1E3EC54D3FE
-:10DD600097F29E4257BDD14D2AB18F62F76C6AE996
-:10DD7000A72BCAF536ACAB25CA758F351EF78FF7C2
-:10DD8000005CE3763BA78E0BD135B1B8C7C1FDEE81
-:10DD9000A32CF35BA354F2F29AEC25620AC4C98166
-:10DDA00017E243FB895FE68D1841F719EF3260DE19
-:10DDB000FC288BFB20CC632B08F82177EC0AE21EB1
-:10DDC000278821BE50E6ABD9C1FCF59A42836F3952
-:10DDD0003BEF1560BC107DB4E9E823C0E8A3B11D9A
-:10DDE000E9A3A2A99DD14763754E64063B37033F63
-:10DDF000BF9604C602DE3BA2BE9A2651FA1F1A1530
-:10DE0000A801BA91BDE7A6E55D8A703D1D163F7C6D
-:10DE10007DCABE7AC36F6D4BCA4369E04FEE33E0F3
-:10DE200079970237A55F8C85E5C5B658DD5F03FCA1
-:10DE30002A27B4ED85ED6F6D791FF3366CFB6ED834
-:10DE400005EFDB66530C3942F3D6EE5B8EF767D7EE
-:10DE500006D87DD8D124E005BDDE3B3C18FF04E1A7
-:10DE600001764F1AC0A31DF96513FF5E2CAB5170EC
-:10DE7000819E1F1AC5EE0D89B4B0F3EB211611D7A0
-:10DE800039C4C2CE59E2F7BD2582BF9575BF01FBEB
-:10DE9000C74399A6DEFFFDBCBFA489AF2BF854E8A9
-:10DEA000894AD228B87FE44C8C3BD1A2A19FD8A844
-:10DEB00014D578CA7B8F7888F30EAA47AFD83DFF78
-:10DEC0002ED0AB947EBE00FC04FB8D9623006E4AE0
-:10DED0007FA0CF70F8A1EF0D87F9601EB017B6ECE8
-:10DEE0005E22E23D1A7DC46B26DC1B49FB6746912E
-:10DEF000AAADF4FDCC685A423D8ED713797D202B14
-:10DF0000533F711A04FA7C3D8FBB4EB6F0FC31C909
-:10DF10003EEA86D15067765C565224EA05856FE169
-:10DF20000E0838B796F8F9754A20C5007853F858A6
-:10DF30000A18FC56AAB452248701F218DEF1D07DEB
-:10DF40004BBDCB9DAB2F65DF71EA9FCFE4EBF9C1F1
-:10DF5000F6F5173DBEEF9E09F02D37B73D7203ADC4
-:10DF6000575C7A0ECF079747555C79A17B2FF4EB6E
-:10DF70007FE7FCDB5140874DDF98C27E0F55C3E140
-:10DF8000D6E229C0F732F9BD2E2451C93356E5B186
-:10DF9000421BB7CB109529F81CEDACFF401108F8D7
-:10DFA000F44AB1F07E54329E1F4ED1E5ADFE879FFC
-:10DFB000C5F932C130002571C92836CF37CC4E3271
-:10DFC000D3FFE09C691A3F177B4772AFB0D2F1DEF6
-:10DFD00021EC7C3533AEAA19EAC4C4C6CF26DAFBDD
-:10DFE0000A32136BA7C6C2B8D1C918DFCA35EBDA3B
-:10DFF00053BD12C869929A8C7989D388CA3E637AD4
-:10E0000003EDEE08BA2E90E3D78C2C744EE5EDE7C5
-:10E01000E8FF434DE4F6992A7FE32AC75CE7548D75
-:10E02000FD528BF701FDE99FE2EDE1F22C3EE3FCAE
-:10E03000DFE2C977C2F9B31E9E390EE17EABA3279A
-:10E04000DCF570D4C35D81AB1E8ED99F38A7C68620
-:10E0500081931E2ED348ED48D0630ADCF57079C752
-:10E06000CCE8E29D3413DEABF88EC4E0F80E352325
-:10E07000A11EA49B6811EF01CE8CE2F53747B0BA20
-:10E0800082EFA864C4B71EAE7A3866C6F1F7E358CB
-:10E09000FFBD002F09E502E247A19BCCD4AADD31E8
-:10E0A0002A7A50ECEB691C2ED4BE46FB3937DE8A47
-:10E0B0007126B0AFA72584E0965BCED6953BDCF207
-:10E0C0003CF8A9F475BCBF720AE13FFF143C2FCAAB
-:10E0D000E45505CE53BED1DAC9D39AA69F8238C380
-:10E0E0005093FB7EA0CF801083E77514EE477470C9
-:10E0F000D7BE67D7D6F570F803FC31B127BC143A08
-:10E10000FBC0C2E34E03C820B097C7BC96110DF206
-:10E110009B34C5868D4B5C71383F380EA757A4637E
-:10E1200081B883CFEDA93F428EEDA35A5225C73661
-:10E130008BEED396F89E724CC1D3648E87C9C4BB54
-:10E140000BE24B9389F445D01F480EEDBF5BD9E736
-:10E15000403210F67983C5C1E43FDF6770DFD4BC7D
-:10E1600084F9B3F8FC59660B7E5F4302524710CE28
-:10E170002978DF91D7181B5A8792BF4F86541166B2
-:10E18000CFCDC37BAE295CC87751A17598AC828492
-:10E19000F7FDF0759CA9337B218FAD5B7447819DA2
-:10E1A000D721EC1B83FB93FC2340FFE9DBCF35EE4B
-:10E1B000AE8076DAAF08FBF1F52F1659FC21B0C31B
-:10E1C000E47B3EB9773B95B235EA09857EB3E0FB47
-:10E1D000D4CB81DEFD0361DD5340D5D172E759F622
-:10E1E0001D437663BA04F3ECE96679FF39C42581EF
-:10E1F0007DABA7DFEF4BA7A178456008F8298A5DC2
-:10E2000036D5EA1E69A5CF57F3EF669BCE8E18056B
-:10E2100078F9C1F474404B4F0A1D51BA1A0FF0EC53
-:10E22000CAF8FC6930C7DFCD3897007A51B1DF43B7
-:10E23000768A6B02ACA7373B7E89D53DC57A013B18
-:10E240005EB1672EE68790DDD441A674741BC7CB00
-:10E250003C73ABCCEECD0F60FEFDEA48E55E3B477C
-:10E2600024D891B7AD4ED95407E786D52CFE7E6BE6
-:10E2700095ACF183DD90DD86EFB3FB666F5FA66D35
-:10E28000FF4C60FE7EA157FB9C581234F7EDF69CC4
-:10E29000D7E035C0BCC323313F413FAF7E7FFA7921
-:10E2A000F5F3ADE67ED56A63ED48A7CA2E596065E1
-:10E2B000F650F7AAC7EBE0CABADEE0E7360F48939C
-:10E2C00054F7ABB5AD8E2C08776F8C329E02EF7988
-:10E2D000C4CFE20055F2DFC3DD839BE566F181DE4A
-:10E2E000E61D16988A76A0E149BF08F6FCB0004109
-:10E2F000FB3B2BE0322CD0F801CC4FEEE107C0BD48
-:10E3000026B45ED6B08BF901F5D5E84F94517F0263
-:10E31000F4CC7A389B1EC0179486FE41D0DF85FC72
-:10E32000A92CB8CF92FBC312A597D45AD67FA3F5D8
-:10E330005DE36A09FC5577924C2963E3C3EFD798F4
-:10E34000A95F55934C2208F5AB5E78F8FDE96BC0E8
-:10E350005F8E7509707F28ADD758FAF7DDBFDEF8FC
-:10E36000F0FE1AB86F94FA65EBAC2A7FB737FE78E7
-:10E37000048C910BF047BA3D7F23F0A112AF688A5D
-:10E38000E07C1F11A4BB6880974227572F9B8F7E8C
-:10E3900045C425E787409E5816C7FF162B8FC346F6
-:10E3A000B1F79F12DD5B90BFDF3A3F02E2CBEF8C0B
-:10E3B0003C8AFE5C9395C5E7F7794AD07E52F0B966
-:10E3C000CB2A703FC93F10F8EDDAF1CD71E09764C8
-:10E3D000C902DE43DA24FB9E4CCF007934DBBE82D7
-:10E3E0006E296BA211BF136B8AF00FBC5B65A7355A
-:10E3F000F1FB4C9BCEEE1DA8CE631E66CDDD6545C0
-:10E40000FAF38B307E56C6EEC3A0EF7BD32F21FDEF
-:10E41000E112407F90F3FB13F0FCA8618F0DE24204
-:10E420001DFC7E82330DCD09F36959BEE52F36F010
-:10E43000D7DEE7703823B5E23D4A65DB44BCFF8395
-:10E44000CE9B700BC4A71B1664B2EFF7D877678A10
-:10E45000FE4CFF67F3C07C1634C4EFC8147B72B265
-:10E46000D9EB83F535558B182F9EACBB376C0ABFA3
-:10E47000374C6F5F9EB42A71E904CC875A6A67F300
-:10E48000F4C64F59DFC4129F8ADFB224BF08EBCF16
-:10E49000FA2681C01597675A529EC8033F9EC8CE80
-:10E4A000E130AC4476A3FDCACF9FE86F37DC43BEB2
-:10E4B0009357DE6C3837EB4A2466FBFD970960778B
-:10E4C000B9FBB1E022D3078A7D37E51B6D7C556F20
-:10E4D000E7E6348DBD7F204178B37FA722C0EE559B
-:10E4E000EB61FF06A687B57B09790CE190BE2DF59F
-:10E4F0001AB84729FD8F063BCCDB027C110FF83C94
-:10E5000087F7FC5410FF8DD05ED120DAFDB07E92EB
-:10E510007119F09562372870693CDF6C1E43D79102
-:10E5200075D6605F4E877833F005FACFE3FEBC2FD7
-:10E530000EF4575340C27382ACB3BBA316A8E46079
-:10E54000D379033E7FF3FC5BDAE781D8CBE0BD2DC6
-:10E5500006E617EFDEFBF728904B6F9EEFC6F182C1
-:10E5600076434FBB18E1916B15837167B55D4CC461
-:10E57000AC0390B7352D9AAA31A177BB37FB137244
-:10E58000BF95F4B41F72C01E11C3D8111CCE743EC7
-:10E5900009F8486F575C6EE3F1E6C1241DEEA36CE9
-:10E5A0003C1FB718BF1F6E8AB22F477DCCECA5AEBB
-:10E5B000DDA71FBF069EEF13D9FD11E745E4A7B7FE
-:10E5C000762E1EDAA6E25B2A39114F5FF53FDBF9A2
-:10E5D00006EDFFD59E481647979C97A9BF7708F58B
-:10E5E000F77178F907B0F338EF00B8D7E907DB2FF8
-:10E5F0001D3DFCFA3C1BDAC381E9A01E46AC6B371B
-:10E6000002FE5BACF9D7D990DFEAA3002E5E92330D
-:10E61000904C80F37A92037415A82676F027B6B54D
-:10E62000180C80978C8DC998A7B3899F572EAAAFD5
-:10E630003526ABE862113FEF3A297B87C4AA9E1FBB
-:10E64000B031F972724FE96F304FE34313191EC6B0
-:10E65000DE6CB0317DFB8AD17BCD66E877C480DF8C
-:10E660000DEDDEFBFA5EB8CF78D161C75888FF3D6B
-:10E67000627360BFC67D9B6A20CFB7F113D052543E
-:10E68000AF6C28140D74DE378883C5EF0E18D01FC9
-:10E690000FC63D892B0EF6F9105FCF1B2D06CDF965
-:10E6A000D81BFCDEDD7B6D32B62FB18988C7AD2D5E
-:10E6B0003971A0375AACEEBB6DA02F8EB5D5C01204
-:10E6C00094789F62AF4D3CB0F59AD1F4CF891D0686
-:10E6D0003BA0DB71E07911F6EB3849488C407AD8E1
-:10E6E0006F743C8F7ABC373AD878741D6F01BF2A9B
-:10E6F000F0A79AFFA1345A7FA3558A85FC2E05FE08
-:10E70000CA3E94F91DF5C4B5DE82ACE4DA7A81B86C
-:10E71000B3925F3ACE4E947F2F01E9D268733D6A7F
-:10E7200063F60EDAD727F730BBE815AE474952E15A
-:10E7300050809F82A77A1B8B332AEBE96DFEDFDBCB
-:10E74000989E54CAEF4BD79B648717E9661BCB0F83
-:10E750007778FDE654C8236B4CC57FCF499567FB9E
-:10E760007BA4E793DA7B051BDB0C06F80EAC628713
-:10E770001083E66D1FEDEB209D49F5487F8D8709DD
-:10E78000F27169DD9D2CEE48E50DBF7F0DCFD18183
-:10E790007FF8797A7F8196139BD6AF1888F0F5DBE6
-:10E7A00080AF4270A27C036555AD11E875D1525619
-:10E7B00016F373E9456BDDC89F45EB587EE11E5BA0
-:10E7C00032AEE70CA75762881C00F9272E0E7F6532
-:10E7D000DD799C6E4F353CD10CF352FAFA13E0739D
-:10E7E00052E3634FC372157A3DB541C6714A22B5F3
-:10E7F000E7F6AD7CBC6D0718BD4FDC20E7C0FD5FC0
-:10E8000013BDC40E71EC37366C14417EBF01F49C0D
-:10E81000CCF81CF4EDC93D0F46FD02F45CBB814011
-:10E82000BCFC152329D9A2E28BDDEB5FD5F06F6923
-:10E830005DF53518976F8B1540CE2B7CABC0FD1561
-:10E84000A3F32AE4FFEB74FC3F95BD2F473BB0DFF9
-:10E85000139CFF9F9841F99F3E8AD91023C038AF7F
-:10E8600018C3DF07F7F50FA4BFA05C6DEB2157BFFE
-:10E870006672B5CD964AE7AFB8B61BE30CC1F57129
-:10E88000BA7962AA4237C902C0BF96627018C08BBB
-:10E89000C215E899DACDB7DF90865CD922E1390F4D
-:10E8A0003F47E2F91FCA77020ABF86E499C2B76EF2
-:10E8B0007334D8D553AB56805D1F97E745FA3C2596
-:10E8C000B887C6527D760AF8388C3C38C1E5C75700
-:10E8D000B2FB62F7EE0F007A2EA11E22EC87AC137A
-:10E8E000EC8017A5DDB18EDDC33A3C5AD09CBF2B1E
-:10E8F000F51F0CEF408FFB418747637C3A60843CF7
-:10E90000D5113EA6C7889083FC400C570F003E5B94
-:10E9100044F5D7CD2AFD754AAE453A55E0707934B5
-:10E92000935F5FC5B07DFF95D38515E285AA732FF0
-:10E93000EA904802E36751607C2EC2F8A7F64CBA11
-:10E940000AE9FDDAF0F46E07FF2A16FE3DA7F54846
-:10E950009F3133ECF81DCB1392332246631FF9B07D
-:10E96000DCBDF157E8D701FD02BFF746FF2540FFA8
-:10E97000240CDDFB28DDABF0A7D001A58B6BA255E5
-:10E98000F2414F17CA79A302975774E7954F47335F
-:10E9900079B080978E5EF26694FDFC603C9FEC81BE
-:10E9A000E7F90CCF21BE027C2BF2E16717E1AF3D06
-:10E9B000D1766CAFF97401E6A9D4F273AB7A3E9FBD
-:10E9C000B2EEA5D182E67C4B7FEE34CAE2BE2B5A72
-:10E9D000773EEA480BD1C7346ECF2ED968C273FF99
-:10E9E0002DD00278DBCDFEBD6CE53DBB440D4F0A5A
-:10E9F000EA15D14C8E2BF4E1586624C3A8FFF255DA
-:10EA000072E16EC8FFF959AB376F34DDC716A377D3
-:10EA1000F6B5E80738AF82F1AFCA33D8211F24C654
-:10EA2000651720DE81240A7CB88FCD332ED5791965
-:10EA3000FAC90EE73890070F737C29F855E0D09B90
-:10EA40009EEB0DAF7B387CE279BB5E8E1473FE9E2D
-:10EA5000C2FB5D5C8E7845E0271B712F1761FD5965
-:10EA60004CFE05E54816C173C9977572E4E59F5ED3
-:10EA70008EBCAC912313DAC2CA11FA0BCBFFF11B87
-:10EA800016A21D4B0E87B7637746333D1C0FFA93D2
-:10EA9000F68BF7B2F3DE8739DD528AC4BCC9DA0DD2
-:10EAA00026CC1357E4906D36C9817FAFD906FA168C
-:10EAB0007ACD761F9E0CE7C54946079C5F9F92035F
-:10EAC00088F753D401AF45FAC8C7FBC7C3C82302B0
-:10EAD000F112EF4783D0EF9C2636219F2C994650A8
-:10EAE0007FEEDE7805D255495E8A00745B5A1723A3
-:10EAF000407BEC54BB01E494B28F2B9619C8B071E3
-:10EB0000C80707D472E40A6F15FEBBCD43E3DC49A6
-:10EB1000720C21471F3DFB3375BCA88DD6D5F12261
-:10EB20005A7FE0FBC48B8E46071E8078D13F6CAEC7
-:10EB30007698779425FF28EAB7C42A91A8E4D6C529
-:10EB4000ECB71F4A2F953C2E455AA9344ED0C481AC
-:10EB50006FAB73601CF82B584FC580E34FC37078C0
-:10EB6000AF46587B9BADA31F970BE41382F8E89741
-:10EB70005F2542FC45913B067BACE22F0B9097A1B1
-:10EB8000F0DB7F031C7DB5D7008000000000000093
-:10EB90001F8B08000000000000FFCD7D097894D590
-:10EBA000D5F07DE79D2DCB2493C9427626ECBB039F
-:10EBB00009ABB14E086090040710448D380990B03D
-:10EBC000640391D2D6968120068A182BB554B10ED3
-:10EBD00014FA51451BB61ADBA013401A143456AD73
-:10EBE000D8AFA561911D8980FDD38AE53BE7DC7B29
-:10EBF00033F34E26026A9FE70F0FCFCD5DDE7BCF4A
-:10EC00003DFB3D77492D63793B22199B90B350ED35
-:10EC100006A9C9CC3C161B831F2F6343793E7A0893
-:10EC2000E659986B20636BF27579DE018C5DC79FA6
-:10EC30003BFD69A2153E8E676CFED630EB4933B5BD
-:10EC400067D7E17F795D8C265F599F643DD9C79F67
-:10EC50009F8FBF24C1FF334CCF12182B63E2A7E173
-:10EC6000CBDFFF7018B4C7DF55C6DE54DD89568090
-:10EC7000A7DCDC12D5DDCED833F9C713DC91D45232
-:10EC800087DF3D22C67871B9E3BDDE718C79DE5530
-:10EC9000D916C80F36193D4A34FCE264766B82E817
-:10ECA0000F7E9406C5671904F97F43552C6397FEC0
-:10ECB000ADA3F4C59FB8F232E0FB8A7A9D6339B404
-:10ECC000AB685018CB62CCD19579CD198CD58547DE
-:10ECD0000D62D05FCEBE48A701CA2F2966AF298337
-:10ECE000D100088741C23FA2357D1BD4573798D841
-:10ECF0006AC85ECA61AC19E1D53BA2D9003F7E0764
-:10ED00001D7EA60FCC00CA6B1D2E0B639BC278FF25
-:10ED10009BC2647B7B3483B4DB92D1EC04C0A7D765
-:10ED200033160DF481C48369F6926E03F499301F93
-:10ED30003DF318804ED9AD3E15F1D2ADD5AE6391FD
-:10ED4000FE71F4AD8CE6DB4D6FD73960FC3A81F78C
-:10ED50009D4D3B543DE073D898DA6A15D2D228F71E
-:10ED600058C4F3A8ECAA6A2C8FCDF7A86E689FA5AB
-:10ED700054EDB3005ED878E6D802E5CC07838F84E3
-:10ED8000FA16D61805D998232DCE28281F75C6D96E
-:10ED90003800E61DED620AF6C7D8321ABF5FA4CB71
-:10EDA00085FDB238A75200FD0CFB0723BCC87E7658
-:10EDB000368D56EC006F5CF318C51EC05F304DE217
-:10EDC000ABF5CCFE53ECD77348E740BADAEB987357
-:10EDD00023B4EFFA72BF312CCADFBED2AAD078B703
-:10EDE000BBDDB94646F379D80ADF8F9CEEDD6700BC
-:10EDF0007886CFF1EC33DA03E63397517F292D1E65
-:10EE00009A47D211770EA68B2D31D4CFA833BEC628
-:10EE100001D0AE4B15CC07CAD39A3F5410AF6955F9
-:10EE2000CD0AD27167D35E8237B5793F4F8111EA3F
-:10EE300020DD01725517308FC5161DCD63B145A178
-:10EE400074E5C599892EA87FC4EA5E6C19EA9FC74C
-:10EE5000CA1C776215F4BFBEA95BFB7C7B02BCB702
-:10EE6000C1678827D9DF72AB91FA69B2B87F84F3A2
-:10EE7000AB9CDE7200796F47D39FA3482E1AE288BD
-:10EE8000BE09878E133D129600CEA078FDA1850A9B
-:10EE900083AAF5854033A5239E27B8DD8E31998856
-:10EEA0006F809FF8C71A3109F8F2628CBB06C791D0
-:10EEB000ED2714D922505FB4E7C577CF2E658E5960
-:10EEC0003D00CFFB8B77B26E4877F712A47B7BBBFC
-:10EED000818F87213F318BB316FBBBA4B0E938CEBD
-:10EEE0004B9842F94B069E97F8FAAB95E3EB11EB82
-:10EEF000A4C596788E272BF0F14B61BC5DB01E7ACD
-:10EF0000D7CABFB30B7E61CD9C5F701EA8BF64BB28
-:10EF1000DDA2DFDB9DEE5C3DE793CD08E7C811DEA7
-:10EF20007DC8B7C3F33CFB90FFD398E0933CCE275A
-:10EF3000C1FCBECF6AA37E469D696588F72C85B962
-:10EF400002E92ED3D710AEA1C8DFA3897F401EB639
-:10EF5000E378C352AA54038012C7AC135877C6DEB5
-:10EF6000B6DAA95DE608E73EE437ABD345F27C208C
-:10EF7000C24AE52B33387FC0F77F40FC05CBD32E48
-:10EF800094A3017E398A437E8CECC88FBF13F0BCFA
-:10EF90002DE4A563FFEE3F61FF71CD3AA7029D0C02
-:10EFA0003F12E965D074F8A22A15E18F63C0FF0013
-:10EFB000A06D8E3507E52CA5CCA1205D9B225C873A
-:10EFC000ADD40F23BDB93247E7AD86EFE6463B89A6
-:10EFD0007EDFD83EEC676636CC6F1FC01EFC15E1A5
-:10EFE000037BB0B608F5F46FFF69443D6A97F2D72A
-:10EFF0003424A238803FAE48BDE0A7F771D20B4160
-:10F00000F40ED673C1F4F6EB05AD9E037C5DE0F41F
-:10F010007067229FC5352F52B97ED0EAB5CEE8D1B0
-:10F02000413F083A5C8A707E81F85C0C3288E37A52
-:10F0300046B33E58DE991D0E8B89A476FF453B1CD6
-:10F040001613DFD10EEBCCAD0715C04779836A5795
-:10F05000610AD58FD99C48FF17EB148709E5A441B5
-:10F06000257E78716538D94B09EF67BBA307B1DB03
-:10F070002015F2CFDCDDC98E56C688F1ED9087F100
-:10F080002F5979D6687527C504E893171BBE084326
-:10F090003CF74F64034EC6620BA7D60E830829F0D7
-:10F0A000BD097F5310AF836B5414AC69EE9D269558
-:10F0B000E8D61DFB1BCE5AFE9C0D70BDBC6DB4CEB8
-:10F0C0001DC837F55767EC05F82B23B85DBEB4F7BC
-:10F0D0005A2FE433597FF79262D27B3F072B1913E3
-:10F0E000A01FDFEE7382EB6156683DD51F87762A3D
-:10F0F000D723008551E63E7AF427D47087AAF527F6
-:10F100008839AA7B027E107F8DE184BFEA9E20773A
-:10F110001904E748EC7FBFC5C892A0FC0AC823B613
-:10F1200093707F03784707E2D10F6FAAF55484E00C
-:10F130000BD50F5F3B5D900ED0BF6AD1D33C2EB193
-:10F140007007D2B3CEE864487FCF51E11F08BA55AB
-:10F15000089EBBD430F4881BE6F7E29154077E7F0B
-:10F16000A9FE4A982E12FD46F7149C979AD61A8546
-:10F17000F6705FC395BE2D0348BF4DC5F22B874E79
-:10F18000D8DC03BED1FC6684A687767E95FAC89A41
-:10F1900040FF50617C7EC17CA43434FE4B1944F2A4
-:10F1A000C7501F7AD299B71AE6BD72A0E0A77B9923
-:10F1B0001DE53E98DE46ABAB2226406EFF15EDAA5C
-:10F1C00042B8709C942134CF85981F747866A6410C
-:10F1D00087F31BC3D06E4A7F0FFDEFB0217EFF4E39
-:10F1E000CEAF7DFE3DAF0D3AC468BE3FC67100F89C
-:10F1F000E53A80AF128CC1EA8CC079FB881EE562CB
-:10F200007EE5E6489F0AF361BB0C175AA41EE8D6B8
-:10F21000117EA04F0DC2E719ED38E246FAFE35D255
-:10F22000518DF8D1375BD15F85F9ACC67A36A2280B
-:10F2300011E7DF2FD2B905F5FC4BCB18F1F3A55739
-:10F240009877134C76FB7E1DF1CB46D68FF8BE9F88
-:10F25000EEF20C5724C9F33A843BABB956877AB720
-:10F26000A7D7AE437DDAB7B94EA7233E70FF2286FB
-:10F27000FCE49957F4005FFF6D55EA37E4076F68C7
-:10F280007EEF40AFCD81F49278CB167C908D7843A1
-:10F2900083D0AABFD062F6E30DE8C3526C1DFB63B6
-:10F2A000AC251DF1D4F8FAE95E2DD05FC51BA76728
-:10F2B000205E2AFE60222618F387BED1C8EF9FE5A4
-:10F2C00084F6672E2CAD72E8C19F7A25A61BD985DE
-:10F2D00032D66C443FA1BC6E81431FA0CFA5FF7600
-:10F2E000C8D09C8FFD1F1AAAB26580E72B8EE15D06
-:10F2F00058083BD1EE2FA1BF06B02F47D811CFAF92
-:10F30000674573FFD146F620B8FDA1A5731C637A4B
-:10F3100074DEDFA1C161D3BDF07D7E901F743486A1
-:10F32000DBB5B6186E8741213B11CE8BBFB7783D58
-:10F33000507471C847510CFDCC5D1F647A808F2ECC
-:10F34000B2E647FE8872763592D671F9833FCA5C81
-:10F3500066F1CBE51D23F8DCEF78ED70941DDAE75C
-:10F360006FDF17E709C0DF1D4C7FB59DAF33705CC1
-:10F3700046E3337D4B2FA407FBE3D9043BA4F9AF4D
-:10F38000BF15C7F9204187745E24F4DBEFB028C0B5
-:10F39000DFCE5F52417C24F3E56D66E68D0DC8EB50
-:10F3A0009B8DB8042E6F8B645E68B737C612477AA0
-:10F3B000269925A39EE9145F3789CFE07289CF4350
-:10F3C00083CFA6A35FF15927FE706F1B6FD7CEF7CF
-:10F3D0004BC14FD7FBF3EF7CA53EEC0AF15D848D6A
-:10F3E000D3E98A636417F4F7F28DBE1ED610EDE4FC
-:10F3F000FA32184F6F5F2B8DC07E7FDF66CA0B0518
-:10F4000097DEA6FB767ECA21802AC01FDCA6BA53EF
-:10F410006DC21F9C0CF98ABE57C6D1BA5AF28BD066
-:10F420007B77304F23CA6F307F487AF7B001DDFA1F
-:10F43000A372662948B78B3176CE37421EA47C046E
-:10F44000E331389D6064EE50EB80AF62245EC39878
-:10F4500007F4E1231B0D64DF0F5FFBF8DE4CE0F7E0
-:10F46000D31B0CD6E530E49C17F6A53E03F57306D6
-:10F470009BAC0AE44FDB7D3D50EE4B5F505DC80F07
-:10F48000A7373C923013D2F320BF650047E946030B
-:10F4900095CFD9F828959F15725DFA427C7FD49755
-:10F4A00087F7AF4E403ACEF9EA89694897ED466B47
-:10F4B000FFC190966D531C6302F03D6F739826BF99
-:10F4C0005DC7E6E03C245D99E26EAF47133FD5A6E9
-:10F4D000FB76711F9FD6DF04FF72AAA0E3C4293018
-:10F4E000EF8AA157C8AFDF77209CECC99B912AF91E
-:10F4F0008FBEC1FFEF9DDB209FFB95DE41BE9DA02F
-:10F50000F3584167B05CA4B74BCC3C9FFBBA9EFC60
-:10F51000CF5C8B4AF886F69163A1FE7BA2BD0FF407
-:10F520002CCA2153B3D78D847663A30D0CEDD0F78D
-:10F530007CF3F219D8C93BDBF4C75B02E6339AD5FA
-:10F54000F6417F38871982CA9D7A2CCF356BCBC79D
-:10F55000F6B8FB2CFA0F63ADDA72C9778FD8B4FA1C
-:10F5600062DF81733F9B00F32B39A492FF7C237DE4
-:10F57000FC2EC2AF473ABF5DB80DBE3B2CB072F84F
-:10F58000DAE91549C857231486F1ACD3D742CBE347
-:10F590001FA45E6640DF3E7EFA1638E6B6E751DC11
-:10F5A000EF19B1A03D8FF0DFBC1EFB7A3D759B8D3E
-:10F5B000C73382ED46B0DCFCB7EC46FEE0B7D23D87
-:10F5C000164A7F83E985ED5CEF06EB89603B21E11C
-:10F5D0000A86B7BC4DA7B10F5FA11E191A68278C08
-:10F5E0006427BEC3F570836D68C7F530F831842F8A
-:10F5F000CF303DADC3C1DF6AC4760322EDB139001F
-:10F60000D20A6BB708B27F16F77E5B401CAAFFB622
-:10F610005A1DEA8DF6F88C411BA791EBD577849D96
-:10F62000A813FA1CD6ABB4CEDF18EE4ED4E3B8C99B
-:10F6300046C7968C8EF8F948B4EFCCCF957EACBE19
-:10F6400086FBB18F585D9A3819EB93A889FBA25FAE
-:10F650008EF2EDD91B4EF3FC54710D4239D433E7D1
-:10F66000DF6D01F4A93670F883E1898FE576923178
-:10F6700017F907B27CF6E8D07A5C89D553FB9C6712
-:10F68000EF4F47FFEDD3C607D251BF7E1A14E7ED07
-:10F690004C1E9E16F2FAA4B02331222EF014CA1189
-:10F6A000E441DA9DDBE1FB554B5D24573F5D3A9D1C
-:10F6B000D267962EA1FA13B60C1ADF9AF367577722
-:10F6C000C0D3C9352AD989D94657AF18F8EEA459FD
-:10F6D00047F18513559179BB22B19CD17A72F6B36B
-:10F6E00013B67802E27E276C7AA24367F38C8FFD13
-:10F6F00066FABD9CB544A1BD6AE7D7231DECB52DC4
-:10F7000016E37FAC2501DB552ACDBDB6291DC7B751
-:10F7100032677C2CF29791F547B9A90BE7F628B828
-:10F720005D4A2CE7C3BFA11F0BFD7E8A762B849E0A
-:10F73000B10B3A2FB438EDB1A4EF22C95F27B881DD
-:10F740005FBE8C727647B8605DD613D3615D787CFE
-:10F750006EB1C52AF8C3A9F0758EAB5F6C88F85BF3
-:10F7600067F19E6038DE11780D8E03C954C681861C
-:10F77000C6F2F9BC6DB36AE24218FF0E15FFF979C3
-:10F780002CD7A31BC35B3C2ACAC3037C3DDE25DB0D
-:10F79000A3607C2B25BF3607E35F77C5F2B8A52DA4
-:10F7A000CF9D88EBF6E444A303E336372B8F03EABF
-:10F7B0009C7C5FC0AD2338D6377BC27A015C09CD13
-:10F7C000EE1C23A45371310DF8EDC2AA9621DDA0E1
-:10F7D0001D21236B7FB857918B6C689229F42840C8
-:10F7E0001A8672678C724F45BA0C9B55558D71FA0B
-:10F7F0009432BEFF70567177B5019F9C7D2B3CA45F
-:10F800003F5C22E8CF94D1C968FAB3361B08AEAC8E
-:10F81000CD3F9F817C9FB5F92EBD12A08796C71A58
-:10F8200068FE67DF9AD795E2169F9858CF107AEA5C
-:10F8300087825F1E1074D8690CCD7F8B45BB6FAC7F
-:10F84000CF5B405569F5F9E2D880385B45F965D260
-:10F85000E79363ED34CEF3FABA03C980CFE767319B
-:10F8600087078AE66DDD48F1D79DC6BAF1B8EFE4A7
-:10F87000A9D031A4FBFE037F38908C7EE42CFB6082
-:10F88000F423DABF3FF4D24A2C7F7E0E1B8CF84F54
-:10F89000F23EAD603CE69F61B584AF7F6E31B165ED
-:10F8A00018B77DBF6EFC0F21BFBE4CC750BF04CF41
-:10F8B0001B4632E81231F519742338FD510F4ABA4C
-:10F8C000030319911E926E88BFED90EEDFF21AC10C
-:10F8D0002FE19A2AE2DEF3B66E1F8F7C925C6653AC
-:10F8E000304E20E1BA913D7931F6DBD993EFD00E5D
-:10F8F000BF121B222E1DC20EEF880D618783ED2FD4
-:10F90000B3387763BB1BD9E1E182FF36C606ED7FD2
-:10F91000E07E5908BA0D8DED100FDF1F1B62FFE36B
-:10F9200046F1F0DEB172FF431B0F7FC9C8F56FAD22
-:10F930008D3D3C2984BC7413E3EBD6B51AD17EC649
-:10F94000352821F5D9628B51EE1F7E1C1BB05F124A
-:10F95000AC8F43E0F728B6EFBBCDB7175B0D89E955
-:10F960001181EE5BBFEBB0DE0D31CE29813FFB2272
-:10F9700046FBA6F62A46FA0AF25E1E14F42914374C
-:10F98000B0384F93DDBAC1BED59DD61CF283E43E9C
-:10F99000D554ABD64F8C8B93ED9C9F239C699DD8FF
-:10F9A000897F093CC1FCDB70DCB8454CB31F23F7F1
-:10F9B00061E2AA3C8A310BCD11A3F86AD758F7321D
-:10F9C00003B46B1DC91C9B201F5D68CD417D6A9BE4
-:10F9D000E368C4FD9A9517793C7EE502E65D4EFD2D
-:10F9E000F0F93277372FCA17D22D302E1011C7E118
-:10F9F0008888E3720676D21CC7E10A8F0BB0939217
-:10FA00001EBA753E95E8DA1ADA4E05D0D546DF778C
-:10FA100042D7EF502EED7137E71FF78CBB05BE19AB
-:10FA20001877737CF3144C4BECDF048F9789F30F3A
-:10FA30001E0FF82C2BEE26F8ECEA2DEE8F1E8850C8
-:10FA4000BE5DDCA5235E27C485D0776BF2757D484B
-:10FA50005FB3704728BB3A232EF2BF7D5E6486A059
-:10FA6000F72D9D1779F1272D46A4B3DCF790F0060A
-:10FA70009F1391E5150D4A26AE3F73F65DA375C041
-:10FA8000A5C67FD33AA0E3790F3EEE42E403806738
-:10FA9000AC3AA0CE07F277799B9156EA2AB3FF22BF
-:10FAA0001BE3F64D06E6B5537B33B6EFC778FB7E16
-:10FAB000DB563663DCAA1FD37BC47A54B9CEFDA8CB
-:10FAC0006894E37E4D2A5B8DF9ADBCBE8A9997613F
-:10FAD0005C3A7A848ED903F019E30C67F6007CC691
-:10FAE000E6D93479B94E9E2FC68D77256BBEEF329D
-:10FAF000BD9BA67D92BB9FA63E65CE104D3EAD6AD6
-:10FB000094A67D57B0CF81F90CCFDD9AF6DD6B2638
-:10FB10006BF23D6B1FD0B43FCDAA9ECDC6797A9CC7
-:10FB2000CD3D00CE5902CEDEEB8B35DFF5D7D50DBE
-:10FB3000F3A120F9141FEEFFCD166C324BC473FAFB
-:10FB40007AE769FA3DFF6A5E9302F89D5D6B3819AA
-:10FB5000189F217C007E4BEA15F61C8C5BBA5E5B1D
-:10FB60003FA7E1E9952990CEF56ACBE7E1BE9C82FB
-:10FB7000FCAD2DDFAD733D82EB9DED7122CE28E211
-:10FB80003DAC037F44D2B89737F07897EAE91DC4BB
-:10FB90001F5A3AB16FC92F76C12FA6442DBF84D901
-:10FBA000B5FC527A70E7301FEB88FF883E417CE459
-:10FBB000817F017897F895F8B738B47CF55DE19DC1
-:10FBC00031AF91DB0D6DF93FE2B4F1B57E91EEE31B
-:10FBD000A8B7AED42F5271BF8DE5F17DFB2BF55741
-:10FBE000071DB26BF6D73ADB4F3A1717185717FBBA
-:10FBF0004997703FF1367613FB89FBFE85F800D9F3
-:10FC0000771B801FD80887B97DFF30CCBF7F14AC2D
-:10FC100037650A76E3CB38B227FE7DD76AF87A5883
-:10FC2000F45F5C08AFDC8793E772E4F92116C9E75B
-:10FC300029FB013CA8F143F1FC9F2D02D7ADDBF776
-:10FC40002FA4F5963C3FC4C4B9BF107E3FE9EF3AFC
-:10FC5000FC3589FC81F0786ECF23316DF707C4F94C
-:10FC60002E69CF3BEB47EEB775962A7B55DA3F6C92
-:10FC700055C21D9B42D8935EF1DF72FD75A6431CF1
-:10FC8000BA577CE0FAEBD12B07D0AE00DEFB62B9AD
-:10FC9000C502F65AF1DBEB5F444411BFB61E54BDFA
-:10FCA000BDA1E0B2D91E6D033C368469ED884CAB32
-:10FCB000CCC903F4B158AF3DE727F71183DB676385
-:10FCC000FB80FD27F84EE38FAC1CC2FDB5EC786ECF
-:10FCD000DFBF88E4FEC11491AF0C5A1755D670BF30
-:10FCE0006C23F8E90D01FD4C89B750FBA511395380
-:10FCF000E2298EC0D7BB2B3314F227562A0AF921EA
-:10FD000067A24753FDB5B89CC9C43F629C29E8BBB4
-:10FD1000C1FFDA6E1C1EBB388F23FB37C7F3F6E634
-:10FD2000F8D1944E89B78AB8B3B51FF2476584936A
-:10FD3000FA35AAA1F7A5A6C7F379ADB530E9276AC8
-:10FD4000E2FEE384DEC438BF89FBA3F96313FC71D0
-:10FD50007EA6667F688C13F17D853E77A29EBA539E
-:10FD6000D0BDB378BFB38F753F6E27758CF7FB128C
-:10FD700043C6FB1DE328DE0F5FEA715EC1717FA4FD
-:10FD80004384CD2F3F8FC4B7DB8354D44FF54677E0
-:10FD900035AEBB5A7783FF0EC57DBC2DB41F30F046
-:10FDA000507707AEAF5666B0BD16E4B7658CA17F3D
-:10FDB0005FDFA25B1E06F56B3CCC8AF52337F0753E
-:10FDC0005BE97ABB03A7698075B065885F1FAC8B60
-:10FDD0008F21BCD7B74C6EC4FD8135F7321B9AA179
-:10FDE0005A569B1B85FED0061672DDF89490B30917
-:10FDF000397B55D417F1E8DF87A0D353824EA00F8B
-:10FE0000D6229D87B7BAAFF0FD38AE4F4825E2FA4B
-:10FE100074BFCE1B6A3D3F373A771DF2C1406FE891
-:10FE2000F5C35A0BE7B77511AEE7A8DD2E7EEEB528
-:10FE300054EADF593AA607BA4F11749DB2819FDF89
-:10FE400060D7AE5F57A59FC8A87F867AA5F45E8B62
-:10FE500017E343A50D191E82CBA5387AA2BE687898
-:10FE6000DF85F9D2AC2C2BC6239C7F65CAA93EE462
-:10FE70006232AEBFF4EC94D42764C7E368DF69B2A2
-:10FE8000E0B7B5163B3F470D288E00FC976E58B67D
-:10FE900017CFEF7CF46B46FB4B47D4D661D8D954CF
-:10FEA00040CE922198EA5921C52BF8FED5BDA21F5C
-:10FEB000CFBF615CB37FDCA90D07693E470CCC6303
-:10FEC000063EBAB4E73E3BFADB2BE3CD14C793FB07
-:10FED000B24755F7E36484F4AD1508DAFD0D115609
-:10FEE0008C7FFC43F05D46827B1FD2C7BD7C7C05C6
-:10FEF000DAC19665A674C4A37B79921A0770BAD743
-:10FF00002A34EFD1CB938C787E61E68AC1E3504FDF
-:10FF10000D61CE9518DF7928968594D3F3F17C9DF9
-:10FF2000585C6560C6689A8411E32F176B148ABF0A
-:10FF3000E0FE5B01D0678E985FF9AAF7A3883FECDB
-:10FF4000F06F181ECBE53F73AA4A491EC1CE6BE481
-:10FF5000A78CD51993A09F796B6039DB8DECFDF1EF
-:10FF60000EFE43C079EFF23A6D7D255BF3399D7F3C
-:10FF700061E0EF5BD02E68EB3F95F2E8600EA4AB3A
-:10FF80007BB1C58CE784460BBC14AD51ACA85F6651
-:10FF9000AE688CBF0FF2339B5407F2B4C40BEBE88E
-:10FFA000EFD3398FCB4D3D693D70D96EEF82EDDCDB
-:10FFB000515CFF2B7AF7702C7F28D63D1CD7F1AD12
-:10FFC0009F58189E9B39D606FE18C61ECD6C10C5CC
-:10FFD0001FAC6CD0A4003B5A64B02660BCDFC316D3
-:10FFE0002632BEB7650E9C77A5790DF98195E80795
-:10FFF000F2F9911FF8502C67D5D6D7153A9FC3EA6E
-:020000021000EC
-:100000000DE4079A851F78D65E9B00AE17733D6E90
-:1000100020392DDE16437E68F18A5C23F26FF1AE43
-:1000200018D243E0077ED863989F8EC756641E4857
-:10003000847E8BEB321CAA967E5AFFB8E698A45BAE
-:1000400047BF4F4BB793A1E806F4D294A72408FF0B
-:100050004ED08B3D164B7E47E182B77A9A019ECBFC
-:10006000556174EEA833FF83A5C6D1BE9E5C17E62A
-:1000700025B7AFDF68DFFCCA9AA144B7607AE5FD17
-:1000800067E670B427ECAF16867AECA1EEECE1C916
-:1000900050FEB0C2E5EBA1EAF17928A759095C6FDF
-:1000A000BEB714666864ECFDA566E6ECC5D8074BE0
-:1000B000AD94FF686922E53F5E6AA7F493A57D28A9
-:1000C0003D29E26852CE8001885F472570F91A9574
-:1000D00020E2DE6C5122AA8CBCFF7C305467C5A1A3
-:1000E000D2278C4D63EC1E272023C0DF997E6F043E
-:1000F00012B93DDF62B08E4B44FF719542FABED813
-:1001000075BBA63DF825463CFFCDFA64FACBE99CC9
-:1001100098DD3819F8F0FEFC584DFB6935299AFC3A
-:10012000E4043BCD7B525E774DF90385FD35F9A2A2
-:100130003640029E2F30DBF8FEAAD8B767CCC6D770
-:10014000EB56DEF66AD5F02EDF0778AF1E32507D13
-:10015000303D245D67ADD731378036733DCC0DFA25
-:100160003D593B93E4EAFC110BD9FD95DB32DF1DD1
-:1001700001F963DB0CB4BF7E6C45EC5ADC3F3EB644
-:100180002D3E8A41EA5EA9321FFAC17AAB9105E899
-:10019000B7DC15CBE8FC5691D7E440F92FDAEFF93C
-:1001A00095CCDBD11F4420513E3E54BD3E85E8E74F
-:1001B00024FCBE14E6DD02F933A0AFF1C8F8CC167A
-:1001C0000ED71985ADC0FCD9B0BFF5FA3EC071B1EC
-:1001D000A0B64487EB01F5503CE9CB1D2A43BE2D68
-:1001E0005C60A0FDBBB91FA91B31CF9421299CDE07
-:1001F0002A9D47642F99A87FD60A1C02ED16FDD6CA
-:10020000B489D6774CE4770FF4AE16FC897C74265B
-:10021000863963085885E03DF77EFC46ACF7E3D3AA
-:100220003B08E7FDA5DEB53201F8EB5C897710E904
-:10023000B5C7E249AE82F17ED2C8F59607E540F136
-:10024000EB4BBF9C2D273E9D69702438485F652588
-:10025000A1BE3AB9C640E79899DE193589D63F3B29
-:10026000888FE53827F5F67108DFC99A0C86FB966A
-:10027000C56B54F20790FF787B2FE7FFA755371B1C
-:100280000EFDD6286ED6A523DF3CB260389D639A5A
-:1002900021D641C17AE0339055772F7F7EDE1E7ED6
-:1002A000CE8665B5E8EF1D18388F157CBC44DEBFDF
-:1002B0003C0750D6ED4F47D1E5BEDCD43D1AEDF0FA
-:1002C000D90F55E2B3B3DD6A8725023D2FE8F60E5C
-:1002D000FB3EE4CF17784EE921FF54B87B6702AEAE
-:1002E00057746BD2956E783EF6C4DADBE1BB73AF20
-:1002F000181C24E64BE2497FCC7B696ED7C0F38E95
-:100300001DF5972F99EFBF389314C0E77C7BDD383C
-:10031000EB005C77BB841DE2F8B1E3E62AE0C5BAE6
-:100320004EC143C3ECC450CB6A3C773D13C4243068
-:100330004E7842EC8F1F107A45FA09115D787EA63F
-:100340008EF3377B5521BF0D7E34FABF529C4F94FC
-:100350007A5FEAEB32564BFBC14712F839C6B98ACD
-:1003600097DA55E0CE2EA8A8122B0F42976D35795B
-:10037000BD19D49735D00F48EE62E7FB43C6579EB0
-:1003800045B62D65CD7C7E41EDCE19BC25CD191D20
-:10039000ED4D8975E30A1BF56F7060FCA454C869C4
-:1003A00079ADE2F5F17990DD94F18AD9C26E06DB80
-:1003B000A70EF628C80ECD0EB2B3AC566B5701DEB1
-:1003C000481C47C21B0CA72BC24278980770A1BDDE
-:1003D0002D717B0F4C24B8150750B2033CA5CC35CA
-:1003E0002606E701F53E7B47F882E7D5015E31CF6F
-:1003F00060B84B1C9FFB70FF18CF8751BC29681E4B
-:10040000921EC1FE9AA44B8987E3B7A441217A7E4C
-:10041000DAEE07328A1B497E8105509DF67BD74470
-:10042000D467A5EB40FF66F8F947F2D33C56178531
-:10043000FC52C17C2B9350BE7C75D346A2DFBEE13B
-:100440007D23CA49A1CDD7531783285CFBD3BCB405
-:1004500080F544109E6F44D76F8A379C955EC6BD69
-:10046000004FB337ABCEB0419A76E21C9187E4607F
-:100470008EC763C4F8C61CB1EEBF119C957A7E6E20
-:10048000FC86F076E2277D5BB8F3BA68FD62BF9F19
-:10049000D5333A949E6AF7AF82ECFADF0C3C7E21AA
-:1004A000F5F155BD93E225502EFCAE2A2B8F9B070C
-:1004B000E9F1B42CD2E325C2AECB714EADDF49F1E8
-:1004C000B7D968F703CA3F5DB793E2FEC6576647E0
-:1004D000A1FF7D6AFDCCB578BEEBD4B69964E74B3D
-:1004E0009F9376DE6D0CF41F72D717BDF863E4DFBF
-:1004F000AD61149F2FD9EF16EB1ED0ABD0CEBE9EB0
-:10050000EB51B68EEBD552B48703C81EF6C6768B78
-:100510004BDCBD510E02CAC94E2E9EE9FEDD1EE81F
-:1005200077F1CB110E0FA1C2EAD391DF6EF5A13D99
-:100530002C5FF8F1513CE70EF6FFA31F48FB0FD9E3
-:100540008D7AF7922E286FC2EE97AB1BD3ADE827BA
-:10055000083BF15FC0BF3934FE8710FE8B11FF01ED
-:10056000FB20C76B389E6706E1FFC41A4E9795DBE8
-:10057000BA47E1FAF1784D77F2B38E6FEB49F89F05
-:10058000B51AF0CFE35F5A3FAB06F08FEB08C43FDC
-:10059000C05BBCDF2EF0EFE0F8AFE178676B783A34
-:1005A000AB039E3D748E61F1AF4D0EF41BCE84F90A
-:1005B000C89F3AB35D65D5017E98F483BE60B5BF30
-:1005C000427F4DE27F6EAFE641A87F0A9FFE531443
-:1005D000D261EE761EA4EF807FE6EC82FEB87FFC4F
-:1005E00076BFE9952EF1017ED34DD2A982B918D9F3
-:1005F000C5863F1DC17583E2844F6D788F46DCD779
-:10060000A8D7DED7C0331985368C2F38CC6684271F
-:1006100035F81E8A9B611CF99F3D3F9FB190E4BC59
-:100620005573BE6D22F319BAA0FF58A7D0FDC6F2CC
-:10063000453951390CE3D45504C7E92E8AE6FC78D4
-:10064000B9AA23FFB1CCC8FD48B93FF9AEF00FDE1F
-:10065000EDC2D725EF75B1D27797C218D9814B1665
-:10066000A317EF23C07A2A11C7F7EC3111DD8E22D0
-:100670004C807FD528E2366002914F1F649C4F1F4B
-:100680008C6CA23839AC545E40BBF8D0129383FC1A
-:10069000DAB8688AD73E20F4DD83912B5D681F1E8F
-:1006A0008A343A31857E3D7888CE301A8687F10DBE
-:1006B000C946BAAF53686E790597BE0F279E78D4A6
-:1006C0000CA0DE06EE37C655E0D75DD7633BD2C53A
-:1006D0004F1F6D9CA7323C74DCA355E04B713A2947
-:1006E0009E6382BEC3018E2B682FB1DC6EE5F19D47
-:1006F0000D40278B9FBEC1E5CCC3F703CAF05CE376
-:1007000028C6196404E15F932F33F2FAF0C4AF26D0
-:10071000ACCB66ECCFCC3E10E956863A04D7F74511
-:10072000D15E8C97DF83F1251BA67AE297C97AE622
-:10073000D1F1B42612CFCC8978D34481CFA92398A4
-:100740002F1AF0EE3BA88D77DDE7D3F97A037EEF21
-:10075000D1FB1A913F7566BBC10AE3B8F29421B888
-:100760002E295B7E73F0A6259AF3D7A5425EC7CFEC
-:1007700085B5FE80C7211E046145BCCDD0B3FDEA1E
-:1007800010CE0788974A9BDD43ED1628140F95710C
-:100790003649FFC1D07D201D1F14F0413F3551F86F
-:1007A000BD3134BDFA26CAF5731DADABE70BB99B5D
-:1007B0002FE56D9B56DEC627DAA9BD827E30E0EDBF
-:1007C0004191762617E344FFE312B95C64DDE278D9
-:1007D0002CB2359DCEB708792937F1FEE5F8F788B8
-:1007E000744CA28DFA95F000BF1EC77E74A00190D4
-:1007F0005F4FD656937F348705C4B533FCED245F35
-:1008000077CCB7EB11DD754C8DADB310F5CAF7C2DF
-:100810001CA8471F34D6F5AC8AECD84EEEDB14B2D8
-:100820006603233D29E261C2FE8C5523E97C40A189
-:10083000C2EF0F5ECAB17874D118A73110690B638B
-:10084000143A3FF137B17FF250F4E28928D785514D
-:10085000463DA633582BF5FB776BB7E8FB18DE3324
-:100860005631760E038FC877C2B8D5A877787E8DBB
-:10087000339BA24A227FC72127E0E1DE6B407FCA7B
-:100880007F2FDF09FD5F7A4BD4B33BE9FB4B8F0B26
-:100890003EF6E4F2FCCF657D1ECFAF92F5F93CFF4A
-:1008A000A4EC5FE49F0EAA5F1654FF4B9E5FBC3E14
-:1008B0003FDF837EEB68CED285A314D2537B84BE08
-:1008C000285CEE23FC16EAF6F27434F3E9B26EDC2F
-:1008D0006E53A26B0FDA1FD572D282F6F7D564275A
-:1008E000E59F4F702F4BC475D424C563447DFBA195
-:1008F00097ECC1C44ECE1FEDE9C2E3F89B92A0BFB6
-:10090000A17EFB05FDAC4E8CBFF57E1C491CAE8064
-:100910007E9EF926F0FCA7233C1BBE493FB392B54F
-:10092000FD487F484975BE86F36327E334E745E613
-:10093000FFC4118DF12786E74500F5F397D7A5672A
-:1009400042FFF35F7D3DBD04FD2561E72BDA74CCEA
-:1009500089F734DB18A5E71B3F31E27DB38A5D8D53
-:10096000C671D0AE12D2DC00B8CA049C60E7F49322
-:1009700003EC7383D01B8C3DCDF7375F3DAB477ADB
-:10098000CED7D59D7A0EEDF62825E43ECD66F1DD75
-:10099000D14ECE17EF157AE86A9AB311E7F96B8C4E
-:1009A00021403EB7BA93FB60491C5F85C2EECD1C67
-:1009B0006631DB01CF433FE4FB54251B3286603CAC
-:1009C000F8CD84D1EF247E6D3CB595C7531B783CA0
-:1009D000B5D0D6BC089437332695AD31DFC1D88465
-:1009E0005F48390391856FF34C325F9D3F269BC76B
-:1009F000BB307F76FD636B506E9AC2B91FFBD0F09F
-:100A000081E1A8175A3222745690E737E38B8C495C
-:100A100043B1FC8E71589E63B2F42A22FC32E28B01
-:100A200037E35DC7905FB03DC641DC465FFC7D307B
-:100A30000FF7DB2A9DA7750F8A7087DA77FA87C0D0
-:100A4000AB31C94A69139019FD1709871C1FFCF9BE
-:100A500045CDD0DFC9E5498357DB719F25C7903469
-:100A6000D43F7E4682FB72E0F82775AC172E296EC4
-:100A7000168E4B020E03EE5D03BE5DD92A7306ACE3
-:100A8000F3268F89D0E4EFCD8F65CEC038EDBD2938
-:100A90009AFCF4C2EE9AF60FCCEAAFA92F30356774
-:100AA0005505F8B19DFB491E82A7D26209477FEE2A
-:100AB000EF0D5FFCE541F4FF36AB0EF455E7EED9E0
-:100AC000F297DBA1D5653C4E45F1473BC5CBCEC97E
-:100AD000F3287AA73E705FE8226BA6F33E9DED03F4
-:100AE000C975EE7CEB7E3A77F65DEF03F54A12EBC3
-:100AF000DD216C08DAC3CB551F51BCAE2292CFEF7B
-:100B0000E2EBC78CB80F8AFB8AD781DFEFC20FD127
-:100B10003F6CF3503C3BB7FE18ED9B1D48E47ABA9E
-:100B20002275811EEF1D55428A76681CE8AB68E08D
-:100B300097E646367017EEBB6658B81FDE3699B199
-:100B400058E42B1EDF694A88A17BD7F36BF2A8BC5F
-:100B5000A22D9CFA7F4F6D1E47E7095F5368FFA1E6
-:100B600020E5A1E5787EB829DC33E01118B7E077FD
-:100B700077E521DE2A76F1F3B505EA9FB316405AF0
-:100B8000569B47DF17A8AC49017F61422EB7BF05CE
-:100B900068F321AF0EB3AC46BBAB1A7DBD9E473D9B
-:100BA00063B4909E896E7B80C6AF6C33D3F7F72415
-:100BB000717FD7D0C2E11ADBE6A272C90F5393BA94
-:100BC00069D60F86F8CD7A7C97C3D0C2A8FDDD6DBB
-:100BD000FD2895F37DBBCFAFE93EAE21FEEAB81408
-:100BE00098F7DB718A95DC90203D7CA56A78340B00
-:100BF000A1A7DAC769E3E7F44C6DFCDC5E618A7398
-:100C00007E12C031F1B1163DEE07B148B315F13592
-:100C100071C4607B49807CA97BEF37227D0CEBDEC1
-:100C200037A29D36419A1B505F2ECE3304EBE90567
-:100C300049524F2FA354DA1D767506F9A933AC82B9
-:100C40000185FCCC10FA547EDF4C6B1AA0E36E1EBB
-:100C5000C77F34C5BD02F545730E9BBE83F4667332
-:100C60003AEEC37C57F0039DCD0AF9892D741E75A9
-:100C7000E208BB0EE3FFAB045C528E6F348FC5A25B
-:100C8000FD7B2A5B82FDBE77E79DCD4EE8AFF14745
-:100C90009999680FE4B8CF25F17B29CCDA7A0DD782
-:100CA00083956F44D851DE0B703186FB9D7B4CB42D
-:100CB0004E8172DACFA87CC3B409EF895446C17A59
-:100CC00015C6CF7D33CC877CDCF866981EED46EFE9
-:100CD00074F77348CFDC377B8FC1F5A1B3C1A4672C
-:100CE000E4F7389F273DDB09BC37D25BC17C26E5A2
-:100CF000D35DC3E5A548F069B1903FB790A32B55EC
-:100D00005D480EAF3C0640E33EE963CAC05DE8279C
-:100D1000D82DF47E9394CB025C0F417941FF183AB1
-:100D2000FF2BFD8D60392C6BB352BFE56D7621EF43
-:100D300036CA4BB92B167263127EC62CC1E7BB5361
-:100D4000DCEF205E0AAA41EEA3681F3F0BE5C9CF86
-:100D500037462BF217F04D624980FC5437DECFD076
-:100D60003F31C5B9886F66411AE89FCC6EF74FAC2A
-:100D7000E31200FE892B327478DFA99D7FDBF9E650
-:100D8000E6F87F8F9097E2485F4FF4670D55610E4C
-:100D90003C877E398EEFF72C5CC5F1B8D0E0CA45B0
-:100DA000FF62E12F158A97A1DF817A69D8912A63C2
-:100DB000601CE5FEB641CC0E7898D2D683D23713AC
-:100DC000DC47110F456DD304BE067DA3FDC5A14EC2
-:100DD0001E4732784D8E8D19184772AB48E733693C
-:100DE000CCFA4CE07EDE7A1DC5C3E4BEA38C2B9901
-:100DF000F0BC7C801DFD425F9B4EEF3704C79972AB
-:100E0000B8DDBFB0D94076BFACF1CFC374507F2EF0
-:100E1000C3D905EDC9977A771BF2F5BCC9DE570D2A
-:100E2000909FFFE4CEA891763F3EEBF4BE9E6847CC
-:100E3000EB008F18EFAA5BA3E679B9BF13C1F7C91E
-:100E4000387F4B7E0EE6F3796DDD889FAE5499C8EE
-:100E50000E5D01BE65017648DA1DA9E7A5FD917C0E
-:100E60005DAEE7FAAB3C32DAEBC908B43B935C39D0
-:100E7000C8777DF8791ABFDDD9B47614CAC1A53810
-:100E80003AB728ED46B01CBCB6141CD35E1DED8EDF
-:100E9000D4EB52CF4BBB35FAE52F77FE15CD558AF3
-:100EA0007B4032E0EB6E3DB75F77EB2DC43F63E3F1
-:100EB00026E9916F6E5E8F1E137AF498468F5674F2
-:100EC00062070627DF9A1C7415EDF34CDC7F443D66
-:100ED0001FD8DFA329A3C7E03CC627733BFB5DC136
-:100EE000DD99FE1F9F7C6BFA7F58B288F7DD40FFCB
-:100EF000172673FD1FACEF9995BFA773694F5F2F3E
-:100F0000DA83A30CEC03DAC18608FB16610FC85E16
-:100F100084477BBFCE1E5C4D9B5988780A610F1EAB
-:100F20004AFE16F640F2A1941B2927522E82E5486C
-:100F3000CAC5849FC23A11E9F41EBF5750AEF76C80
-:100F4000A3FD467BC46094CF763F6E9742F2D6C134
-:100F50004E08F9F1CB8BD66E48B990F222E5A75C2A
-:100F6000C8C5EC20B9D8A7D63D330AF7CB92DD6BC4
-:100F700093E3FD7252B623D83E74CA57185964B32E
-:100F8000E3AA18F25539A4817C65EA441E9E49BE45
-:100F900035BF68D94DF2D36FFEFBFCF49B4EF8E9E8
-:100FA0007FBE0D3F75F4633FCEB2033C57B240DFC6
-:100FB00066F8F96DC23B8CFB0FDDF97A00D6970419
-:100FC0007793318DE23E13AEB32A8A2F0ABE947412
-:100FD00096FEC06C11773893E27A07E1C5F5C082BE
-:100FE0009BD37B4467535CB311D727B3210DF40324
-:100FF0003AF37F9B6F51EFBD7193743E96FC9DFB5E
-:101000008DC79243FB8DC7B1FC9BD2B5209789F861
-:10101000DE8F0B30DE38E1299167CB0A108FD34683
-:10102000C8FA9F3CE9EC81FA81C9B838C539DE536A
-:1010300045DEB3F4F018683FE119E68F9B43FDD815
-:10104000ECE8F6B888C2FCED95E71F3BBC86E8519A
-:10105000CBE5CCDDA2E7FB3F229F05794B407E44E8
-:10106000507E036F1FA56F6181E745909F94219C7F
-:10107000CEAE00FF0186DF7F05ED85556118D7A84C
-:101080008CDBF8D615D46BF50AED45B5E381D514A4
-:101090003853C5FBB9945F73D8093EC203BB78BE11
-:1010A0004F4AED931EBDE837E0DCBDA14E71D2B9C9
-:1010B00083118AB75B46477CF749D1DA27FCD16BAD
-:1010C000BF67781EEF56BE6FBFCFD68DBEF7996E45
-:1010D00061FCFBB2439F7FFE5E0AE7EF3159D121ED
-:1010E000EBC7A5A8BC1F1137A0F1A1684A5DE87B3A
-:1010F000B013C5B8CDB85F42F8DCF624E2B7D92802
-:10110000F1FDF293C8776319D3C4CF607CCADF9F27
-:10111000F272418D9E4FD71984AFAF9BEF8014A917
-:10112000BFFDF8F204D1CBF435F87684C0B75DFB8F
-:10113000BDEFEBE835ACC3F7826FE7483E766AF85F
-:101140003D5AEF22FE8C8E53ACE84757B8C2D6E02A
-:101150007AC12F9FBF27BE6C96FB031DE4EFB5023B
-:1011600094BF0A8947CFEB4FA2FCBA74EDEDB93CAE
-:10117000B6F33573F601BC52C80FBE7FE4F9FA2707
-:10118000312E097C41F594D707C01D2C8F7541F98C
-:10119000EC20F915F247FA03ED01E0A927EAB7B808
-:1011A00063467B009FFC4CD0E9A2B827DA3C9AFB4F
-:1011B00093CDDD78BA2385FB8FCF097C6E12ED9B32
-:1011C000C303F090AAE11F1FAE5B02E64D78BA3F61
-:1011D0004ECEFB93827CD063CD365EBF2DE5A32738
-:1011E0003DD9FE7C707FAFA67C528078F1F7FFF18D
-:1011F00061F423EE1778DB9172E4B02752D039C145
-:10120000FF4E21F007BD63518EFCA174E48F1F7661
-:10121000E44F4FD0F7F44E7767DF7B3A7EEF0CFA5E
-:101220009EE13DEA9BFF5ED02D3F88AE7941741D63
-:1012300013942F9479AF46FF4ABD5C5CFFF4E30939
-:101240007118DF54E838BF9F9F4F93BD996F95FC8D
-:101250007BE630F2AB9F9FCF129E27D709BA79CE9B
-:101260003D897A7812EAE151FEFC14D443943F5F41
-:1012700080FB617E7B7581EAEFAB91ED2F92FD7A69
-:101280006085ECEF33CA4B3A32CF25B277F70BBD0E
-:10129000C33CADA4F7E735F0EF3F7DFEF3C35F2B12
-:1012A0000FB54178D91094F704B55F7703FBB622E8
-:1012B000E8FBC782EAD704E5D707E56BB4DF17CDB3
-:1012C00052480E8B46F0FDC960B90CE68F2F52DAFA
-:1012D000E363EDF65C8924FF4E235713AA79FEFAE7
-:1012E000F3FF29A8890CC8A7B0891EB2EF305AC0F5
-:1012F000FD41D0B91E15F8C1D089DEBCD899DEEC0D
-:10130000136CEF79FD3FF0D724DA2FD2F825FB5488
-:101310006DBE51957047BDBB2832605F955926E27E
-:10132000BABAF3FD9B8889635203FC224FF84467E5
-:10133000C03C65FB715F5D5771BCF8D4F0899B714F
-:101340007F68B4D8D7B4F114ECA58AF6BA52C46F4A
-:10135000C6E1395D6C17EEEBB930D00F6275BD7028
-:101360009E8D3F52F9BB50D5401FC05311B3D37966
-:10137000D39978EABE3BD447472FF90D7CB7EF47A6
-:10138000EA12B4D34797C4D239A645A9DCEFDC17DB
-:10139000DD356136E41B231E267DDBF8C4584AF791
-:1013A000AACE95AD56E83A357962645FAC8F263C9B
-:1013B0003936C44F5C06FC9D996A2738DC366B428F
-:1013C0003DFADBAB0DB45F082D7E45FCF3A469301C
-:1013D000AEB78B96F5A7FDB0E29F4F1A87F7B08A9C
-:1013E0001F37D03E498BCE4A7122F7EAB1742E6A7C
-:1013F000D60A917AEEA2F4CDFFFCBA1AEF69B5BE17
-:10140000A0D0FB0E775CAD7B67109E9BACE94EF7DE
-:101410002EDE8075009EFB3EBEBEB717CF219F0813
-:10142000ABA273A4D09EEE8B955EB3BF3B310BDBBA
-:10143000ABD6E5D0FE1494A3FF7C6A95BA09EF41C0
-:10144000154559C2F1FCF6A9AF18C5754E3D6EA2FF
-:1014500077228E47BA67AC8FA3FBB8E8E9B3538A0B
-:101460003D4A013C4CDAD067626212969B047DFBD8
-:101470004415011E8A74EDFC43F6A42486E727A5D3
-:10148000F699B805E671EA97BDE97CD8C154E7E45E
-:1014900054C0D72FD29C5352E3115E6EB7DEFC0FBF
-:1014A000DF8FFCE385E204E4AF8752395FBFD1569A
-:1014B0009C10F8BE77C9453DF1C19B46FB227A27B7
-:1014C000303C4DC17536F0412CC6CD6789750BF0A7
-:1014D000F3929D21FCABE1A92AD1ABF1A7F1D94848
-:1014E0005F3F5F0F7F17F519AD37205FB121732D77
-:1014F000DAB993A625EC440FD67EFE91ED0B233C82
-:1015000019B68579C332307EEA1C87FCCD12EB7A9E
-:101510004DB604C8A168FF770F3FE7FB77688FEBF4
-:10152000BEBF7BFED712B89F21DB9746593CE85CD3
-:101530009CB658F4488FA3FAA5A7F03C5AC90B06ED
-:10154000B203252FC43FD68AFA07F806E36BC1F32E
-:10155000FA63AA81C7313A934BCF18AD5CB231130D
-:1015600071BE9DC965CD86DC899B233B97CB522BF1
-:10157000D74FE35EE0EF51960EB5E8717F73F40B41
-:101580006F6DA17B740BC286E0BD89D2174C44AF4E
-:10159000168BC563BD0DEF1358F431903E9BCAED19
-:1015A00069BD909F5C95E9CD4328A57B1272DFF061
-:1015B000EC92679EC5E397E79877DA70C0DF6527FE
-:1015C000E7D3CBBB548A3F06EF23961FDC69CC617F
-:1015D00037B18F7883FDC332D622DEDF0DFD7DF07B
-:1015E000FEE1ABA9C1FB8706BA4F5E2AF60F73373F
-:1015F000280477E9127ECF3F3796C78D4F2E05FA24
-:101600001B69DE1EEB103C0FCDED4E2953BC66F876
-:10161000F5AE0D0B288ED913F184716EF16EE2894F
-:1016200030473AAEF34B5E0823FC96FE6AEE5F7ECF
-:101630009985F7FA0AE202D7D5FB912F387E19DE99
-:101640001F94FD9C5EF6637AA731F745581FC37C53
-:101650004A63D8ABF76720BD92D2719F53B62B5D1A
-:10166000FEA35EBC1DACAF611D5DB44AE5EFC7ECE7
-:1016700036911D04594F6401F72C67AD38683472F8
-:101680003BC6128709FFDAEEBF9F761CEAF1EA6ECD
-:10169000A5B88726F127EF5115E9F8FB74853A853F
-:1016A000EE578126A37B499753B95F7B3A959F6795
-:1016B000284A77D0FD9CF2B526C7F20CDE4FFB7DA1
-:1016C0004F58DF95EB9A4B683FF3F7268AAB54AE41
-:1016D00008738645F1F3173B06D0F96ABD11F05146
-:1016E00066E7FAE2B2986FA57DD25D749F41CF8E16
-:1016F000E8A1BEDCC2F563790CE03D92338A6E1836
-:10170000BE67C7E8DC24F69B3428607C4594433FE1
-:10171000F6287FBF4D3A5683711B6CDF7710E2319C
-:1017200076DA7484EF1595E41990B47604FA7DAFF7
-:10173000A899B8DE2E5AB56F1CEADFF9DB07E38DF6
-:101740000956F4EA07643FE60BFAB7887367C59059
-:10175000C777B622D2B83CB9551E2F8A485334EF0A
-:1017600010C9FAF255061EBF073D8F8AA57CD9C75E
-:10177000D46FB9A53901F56FF96EC330D4D351696F
-:101780005C2E8B97A5651F01BE2A3644D3BB8365AB
-:101790009E0223E6CB6A15CAFBBF8B4F473E3DBF77
-:1017A000E2B528E49F1361BE9E68975A178439E812
-:1017B000DEA195C7EBCEAFE849F79566599B2DF8AA
-:1017C0009EC1AC45DD6DA8BF8F5A7D46AC3F5A9790
-:1017D000A1C3BCD36ACDC6BC537F1BE5CF8BF32D11
-:1017E000F4837CA5703A976DDB67C4BF4F3244CC5D
-:1017F000F7E22B1FF4C2F84F797A732FB42BC0078E
-:10180000BD5210CF2F2964972BB6F1F3EE920F2A19
-:10181000900F40EEE6093EA8D8F5DAF7511E2A905F
-:10182000FE433AF211F0F37E2ADFB1711CE3DFEFE1
-:10183000473E91760CF22B0C368CDFF17C661AA7B2
-:101840003F948FE1E59E01FC1C5DFB39048D1C7407
-:10185000465F571AB787C5CB4CA46F5D695C1E5AAB
-:1018600056ED8E42FA5D7C65DF01DC6729DF0156AB
-:10187000DA1E421E043E2A71FE51043FF9179538C4
-:10188000DF28FFFCDBF95EC86125E3F393F3ADD4F9
-:101890008BF9CB7AF1FD24C12F654CE06B576F2E8D
-:1018A0007742CE508EE9BD0E313FB74DFB0EE5F7C6
-:1018B000C5FCDC2265D6BA28C40FD217F50F3E103E
-:1018C0006994FA049A5CDCBE91CEF14B7A49F857E0
-:1018D000093840DF39636C7E3AB674F24E6495E0A5
-:1018E0009B638F7749AF07FC9DDF4ACF6C11BFEA3E
-:1018F00003C6937C23C7CB7D79D2DD386FE8DF87C1
-:10190000FDCB718F7A22F4D8CF51C6E543C22FE5C3
-:1019100032B7FAA1BB074761BB8B96EE0370DE9C22
-:101920008EABD2ACF4BD13FD05F8DE59AF50DCFA36
-:101930009858E71F7BFCB5A8E2017E7E7F427C279A
-:10194000F90C7F303E26E16DB2F1387030DC520F79
-:1019500049B8739FB8EF6E2C97F0E3BE51209F4AB1
-:101960003C4A7E95F7F582F996784EDA4FB573FECC
-:10197000AE4C3D46E7773A9407F727FCA213E25CAA
-:10198000796B3CE371FF1589FB35F78A188B0CB432
-:101990003FD28EC0CF1A7D80FD69BFA716E73C8B72
-:1019A00074BB90D68DFA3FC7EA8C39D06FD999E6CF
-:1019B00071F8CE9DF443EFB8EA53A3315EB58B9F27
-:1019C0007793FC5276613FC941B9B8FF54B4EA83BA
-:1019D00082E1C8EFBF35D0BE4ED1E3638DE8DFCFE3
-:1019E000DD327318A201EF41A05E3FBB796826BFCC
-:1019F00059604D9886F721363F33ED01289F55AF4A
-:101A0000D2BB0DD80FCA6FD1A399145F3D11D65226
-:101A1000300AFDF81FA856F4E36FDF32F4316C7F13
-:101A2000BBA56B0C3DB6B13996F24E7D34D907E9B2
-:101A3000F7CA7380D5E2DEC75F84DE3FDC9E2AE210
-:101A4000FC5F752FDC8F6FDD1846EFAC141AED7557
-:101A50003E1C6F4F175A67541AF1EA23DD5B25BF0E
-:101A60006C8E9199938650B93909CA0F1A9A1F45FD
-:101A70003B72F051CB607C3F92A9D78615737F9A59
-:101A8000EF3BC66ADF2D91707C24C60FEE4F7EDFE0
-:101A900084EB081BDD4FA4EFCFAEF8ED34B48367C1
-:101AA000B7F6B4E1BC4FEF09A3FB03A70DDA77CF7C
-:101AB0006EF5DE57F07D29796FF5749AD68F93FC19
-:101AC0007EC37B377FD39E83BCD1B9A50B4B19DD79
-:101AD000FB7E398DD1F76322BEDA89E7084B6A4D68
-:101AE00056BC077312F91EF7B376ABFCFEA599CB73
-:101AF000C1C9DD9974BFB7E46F3C5F52A778F13E6E
-:101B0000F2FEA79FA0F30AB3C1CFC4AB09EDFEF369
-:101B1000BAA7A7A1385C76B857E27DFECB5BF9F98E
-:101B20008A0EEF321CDC7920C9DEB9DFFC5DFBCB0D
-:101B3000320E119FAEBDCF2FF12CD74F6F023F8CCD
-:101B400018E2C7DB674BE790BF7C61A99BD24BCA09
-:101B5000B1B5B7231F5BA2E9BEC01FEB9F51F1BD1A
-:101B6000A8F25D83AFE13A78546434BD93F2D9D2E0
-:101B700025B48F7A616915A592DE320E77C7AE461D
-:101B8000FAEEB3FACC06BC9FFB4664B4B003B69041
-:101B900074EDECDEB19CD7B91F70FA4AB8CF6D9DD9
-:101BA0001985F36A7C3EB66124D23522DA8A7E5FDB
-:101BB000A93847726A3DF7ABCF98A37F930FF43DE6
-:101BC000B3614A02BE3737BBF1DE69585EB247B136
-:101BD000E27AC0B1675214AEDB3ED5B744E1FDA84E
-:101BE0004FD7CB7B555EFA3B54A3F2D8146C3FCA57
-:101BF000A767F60CBE758D7C32F2829EEEBF9E8783
-:101C0000728A935C0BA73809FCC4E2B991D9AFF38F
-:101C1000F84AFB3A57ACF36E17F37E34DD26F73102
-:101C2000A83C77042F3FBD61E744ECEFEC668315D9
-:101C3000E1FE6CB381FA9F07EB331DC07B662B5F1F
-:101C4000F7601ED7CB67B7F2F5CDBC3ABEBE295FB1
-:101C50006070F2FBA25A7ECC0D6847EFFB74F25E17
-:101C6000C83C279FDF3CB09738DF60BE8D6175743C
-:101C70008FEC9B9E170DE6DBF9925F857E68E7D7B8
-:101C8000CEF844E013E51DF955F2C3BCF57CDFDE68
-:101C900056373807F94EF247F03B59D546C6DF575D
-:101CA000D485D37BB89322ED06B40F53E25AC620F5
-:101CB0005A3E4EE77E809AAB73E2BD37566D0AF905
-:101CC000CECE8A74EE57457465C4EFDE742B3FCFD9
-:101CD00029EE7FC914269286767B5284ED0B3B3425
-:101CE000793AFDAE7BF4C0CF936EB73DDADDC1D853
-:101CF0002FD30BEED1C37C2665DA767783FCF3BF56
-:101D00009AC0F3B7D9861A20BF4C9978CF18C8D794
-:101D1000A73B9F4A0F18E7EC962E69383F28FF191A
-:101D200096D7C5BB7F8E69A5B80F7649691DB424C7
-:101D3000C3DFFEFD3D96A37FB4FBF32D0696EE18A0
-:101D40008079097FE8B425DDF9ABF4F88EE5C58C20
-:101D50003D4EE7F53CFC1E0EFCB8CC09784F8AF3EB
-:101D60005BB1BC975313742FC7C1EF9FC9FB52F2ED
-:101D70003E545FFF7DB20DB7729FEC9281FF1D2A2A
-:101D8000C5A9BD0FA634FC89DEF9A9F6B09630A22C
-:101D900083F69E4D39BE53771BDD0BA2FB874C6F3C
-:101DA000277D3357FA3B68AC87F9DF296089FCFC53
-:101DB000C1A3821F4F2F653D7A80E89F7FB739CA44
-:101DC0000E705C98E8EB85FA2032DCFD27C4D7E979
-:101DD0000DD5A90BE3F01EAAC9910FEDCF78F97DBF
-:101DE000CE32E1B7B2CDF1422FA8BE3BA15D534642
-:101DF000DF4D6887DE177C7521C397FE23D42B192E
-:101E00007C9D04EDE83C5DDEF2BBE2B1DD85ED4F8B
-:101E1000F4980D709B0006BCA7351EFA1C61A3F751
-:101E2000AA984AFBCF5EFE7E929E79A26CF8EED510
-:101E300033E9E23E11DD13947492F8EF4017181A5B
-:101E4000FD599D991910EEBE6C03FDFD2F491FF938
-:101E5000CEE2C2DD3CFE427724451EE348A7CDE238
-:101E6000EF9F75B08B6F91BF0A62E9D1E89F0D3388
-:101E700043DBC9111B8DD8F5776D2FFF9D2EFC928A
-:101E8000C16C70E03B92A5A2CD58B5D08EEF5B2D12
-:101E90008C37D37B250B5FE84EFCC196FC9005B6D2
-:101EA000631B62895F5666A884FFB9F58CDE1D2A24
-:101EB000A84FA6F394F9F5364AA3DA12A9FCEC6F01
-:101EC000DEC9E27A89D3A7E07FBA8CA6734BFFD331
-:101ED0009B52D6D97BA79166BACFBBF020B76B0BCC
-:101EE000A7CABFC7C2EFAFBB0438AEC81A8A0BB9C6
-:101EF0003ADC53E7EF57BAF0BE007EE734507D6717
-:101F0000EF574AFC9A04DD82DFB39C7A303391DECE
-:101F10007F14EF594E17ED9AC5BDB3CEDEB5BC4F59
-:101F2000B47B226A5C13F2DD746769C8772DF59E75
-:101F30003007FACF86D4487A47E13E37F8979AF5CA
-:101F40004C8B1EF1302D9BBF733975BAB6DE90FDF8
-:101F500039E97343768777920CA88F4D2E6DFBEC91
-:101F6000AEC20EF5657DBFF65DD15423D94F3DBE9F
-:101F70003B0BF969E25D51F40FD1FFBFECB410FFE8
-:101F80009BC43BB8CD2C2B11F5C2ADBE27FBFFDBAC
-:101F9000FBB1C1EFC406BF03DB7FEB424D7E60DDCA
-:101FA0000F35ED6FAB5FAEA91FEC5BADA9CF6CFA3F
-:101FB00099263FB4F9394DFBE1473669EA47B6BC8B
-:101FC000A4A9BFFDCC0E4DFE8ED63F68DADFD9B690
-:101FD0005793CF61EF68DAE79A3FD0E4C75AFF57CB
-:101FE000D3FEAEC4139AFAF1F6F39AFA097DAE68FD
-:101FF000F2058E2F35ED3F37BA577745BF22EA0CF1
-:10200000F1AD3A4361F844F9E5A62966D4076BBA05
-:102010000A7D24F86FB9B0D3AC07A37BAC63D56C51
-:102020001FF15F3DFFBBA0C1764F7FDEE5C4F81F07
-:102030007B8DDF6B8B067F521F307E8CD3CC02FFF3
-:10204000EE5D6C9E55938F77256ADA77996ED7D4BB
-:1020500027B9FB68EA53E63834F9B4AA119AF65D59
-:10206000973835F90C4F9EA67DF71A9726DFB37681
-:10207000BAA67DEFF56E4D7D5FEF1C4D7DFFAD5532
-:102080009AFCC0BA259AF6B7D57B34F5837D359A8C
-:10209000FACCA65A4D7E68F37A4DFBE147BC9AFA1A
-:1020A000912D5B35F5B79FA9D3E4EF68ADD7B4BFE9
-:1020B000B3CDA7C9E7B0839AF6B9E6F735F9B1D63B
-:1020C0004F34EDEF4A3CA6A91F6F3FABA9977ECED8
-:1020D000843E9F6BCB85DF53E0F897E6FBF6F76E07
-:1020E0007728741FEA5CD76EF27DC5963015FD2403
-:1020F00017C5996C781011F515DE27B7F1F33985FE
-:1021000014AF8A237F884C941DCF0B81DF1085ABE1
-:10211000B68C0CF4AB23FCFE5BEAF5CC9BF7DFDA64
-:1021200084FFDCD5EEBE88F231AF6EFB387A9F9823
-:102130007956221CF2FDBF7783DE6D95E978F3199D
-:10214000A60FF0170F86D5A60EF99A38C178F305B9
-:1021500086EFC1B6F72BE222F8C7BD1706F4BF160B
-:10216000D617F8F7236B979AE96FC7FF6CA995F21A
-:10217000EB962652FEFF003A29BF47008000000080
-:102180001F8B08000000000000FFED7D0B78544518
-:102190009670DDEEDB8F249DD07975779EDC3C490F
-:1021A00048089DF0D8003E3A216040C0E635044919
-:1021B000A4C1A84143BA81F84F7475BB311002B273
-:1021C000B391D11095C1860164199D092EA3D1093F
-:1021D0009AF09AE03A4C601CC5D91937A0A3E28E58
-:1021E000101EE3CFEE8FC37FCEA97B93BE9D0E382A
-:1021F000FE3AFFF73FFAFBB4385575AB4E559D7369
-:10220000EA3CAA2AAD5E898922636DDE1C4A9FF3EF
-:10221000DA9998C9D8366F31C1DBBD0E82FDDE7206
-:102220004A777A9D94BFCB5B41F01EAF8BD2BDDE67
-:102230001A4AF7793D54FE92B781E09F7A7D94B6B1
-:102240007B9B29FF156F0BC107BC6D04BFEAF553DB
-:10225000DAE1DD4BE91BDE762AEFF47610FCA6B757
-:102260008BE02E6F0FC187BCBD041FF19E26F8982E
-:10227000B78FD21EEF6794BEEDEDA7F277BC57097A
-:10228000BE8EBFDB19FC2ACD9FE431263097E67A5B
-:102290001EC2CCC92632F600FE4B82FFE24688CC35
-:1022A000C2D8FD8CFF3ED7B09A76139477FEF23FEA
-:1022B0008502C674A58C8D1F0F6962F6CEC634C622
-:1022C00026B075E64F7218D34057D76307FB094E07
-:1022D000191319D6C3DF752DFEDFC7583CFCBF9418
-:1022E000E5784C836953091442FBBE55827F771A07
-:1022F00055D7203EAB8D1CBF695A1395573E2CF81D
-:102300000D02635522F3E98B18FB7D5854011BC164
-:10231000D8258F2E47C47221DC0E8304F88F3A44EF
-:102320000E7E5D2C8EB1A59D861D9BD206F1AA84E2
-:10233000EF35F0FD2B561A0CAB643D3AC403F21D89
-:10234000DA18C69EB7B8A64B90FF608AC6A787F674
-:1023500099C99FED8C64EC2D8B6B06E65FF2DC7700
-:102360000C1B7FC06CCFC67E661BBAE21741FFFD17
-:10237000C7B5F69DD2F0F3E16E29676CDC0DCADFBC
-:102380003C97EC023CCAFFA275E1FC9FD04556F891
-:10239000F3012F49E0784A1A553ADBEA5A82F87C71
-:1023A00019E9B9470353F8E56DABF6AC812155AE99
-:1023B000CA1AE182EFEE822563198CCD65928E41B7
-:1023C000F97CE6389A064D2D642E8217311FA56FD1
-:1023D000C5BBAAB19DC5CC4FB06BB22135D4B88274
-:1023E000F172CB78B9657C94F471ABAB8EE3E520E8
-:1023F000BC4E4CBA231BC7A5E0F59655A27A73587C
-:10240000FF76C4EFCB83173F113286D2C7774017D0
-:1024100026681EEB313DAC73A38ED1F78D8F087EFD
-:10242000A46B852E2A9991B7FB18E40B817402F4F2
-:102430005184FCD29F3A3792E8E449091A7C7092A1
-:10244000D6A71F0BE3D4F8B3052DD1875E00FC1E81
-:102450008803FA481F9E0EEA9A210DE01FA0AF677D
-:10246000B0BDF3AFFF5D0ECE97FBCD4912CE57A3A3
-:1024700006D601E8D8F7B6D6BE5B92991460ED9403
-:10248000317EA46B26DAED73C7E07AB1A54EA8DFE2
-:10249000AD650DFBF387F6FB2AAE17B47FC2A62B02
-:1024A000F753BB9CCF95F29FE2FAC563CAEBAD5ED2
-:1024B000F569AD16F03F71E89C5E1A13621C0D6F52
-:1024C000E76606E0EFEE3833DD6142E4FAF2E74515
-:1024D0000EE69F94E944A11FAD3ED2B5C314881700
-:1024E000EF17E8F9E74437D140CF1944CF9FF8E020
-:1024F000D3390669C42248FB606ABA2075BD60D62C
-:1025000023DD2C67764AAB9993D20760F9917E9DC3
-:10251000BEA7F438EF0FB276CAAF2BBED782F47CD9
-:10252000BFC6958A702DEBA57C37EB2FB3C1FC2D70
-:102530006C5E7BD40658CF6F796A5A02CCEF3CFFB1
-:10254000B2A398CEDD257CE293883F7A10AF3EC1DE
-:10255000B33E11FABFFBA592F549903F47CBD78513
-:10256000FD2B5F17457E048F1BF8A1978FCB41E3AE
-:10257000D24695ABF8A1F209E610A09DFE8306FFB6
-:10258000CEB400FE287EE8DF93508E89FDF7E07A16
-:10259000BBDF34C4E07A3F08E21BC72938186B80E0
-:1025A000FE90D62A63882A88DE1F62E176ACF7B9EE
-:1025B0004CDF9FA730A2EFCF05E66040BF1774A69F
-:1025C0006601E55AAACB5604F8AC60BE2606E56E55
-:1025D000CD4B05384F2325D7A744D71FB53715A6B0
-:1025E000A1FCF7A70A28FFF719EC8D69AAFD845D05
-:1025F0008F4021E361389F3FC076C70EC54B283E10
-:10260000F69F421463063DF3198B88BFD944E4EB6F
-:10261000443DF157234E6D06F6E3943CA6A1ED9F91
-:1026200090F1EDF94A4B74EF83F1EC1642F5C3F7E4
-:102630002B43F8603F243F2C8CFAD1A7713E56FA09
-:1026400063A6BE6427D0756A844B978682C116C77D
-:10265000E58B99CB979EB44F33717DE64CDEA8C8CD
-:10266000656A8FDDC6E5D1099DE443F844499A1DAA
-:1026700024D7809CBDABF897A7118FBB8CA62E2DBD
-:10268000A4EC16DD9FFA947D307D70FFBD4BD97FA1
-:102690006FE1FBEF1C99B5EF12BBBAF17BC6EC3AC8
-:1026A000C42F97FD5E998F6DB8DF2AF271C87E0B3B
-:1026B00003EBC5F913252B8374B5C0C7BF3A25DCDE
-:1026C0008F7CC436E7D2F8F4B2FC0CFEDE5AC15857
-:1026D000A651C613FE4B70195966CE209C54635602
-:1026E000C1291E9BAAFEC80649559EE6CB51956797
-:1026F00034DB5570564BB1AAFEA836870ACEF59743
-:10270000ABEAE7ED75AAE031ED15AAFA633B5CAAE6
-:10271000F2C2AE1A55F9B81E8F0A9ED0DBA0AAFFEE
-:1027200077A77DAAF2497DCDAAF2299FB5A8E05BE3
-:10273000FBDB54F56FBFEA579597B07F56954F3541
-:10274000EE57C1D3CCAFABEABF80FB16F0CF1DB6BE
-:102750006E55FE0CE9B8EABB3B734EAAE017E47570
-:10276000F62D0E27BE682DE7FBD16CFB07AA765825
-:10277000E768BEFE613C6F7BCF1F0B514E6ED7F4F6
-:10278000A721DD4A5A7322F27166F1DC4340662CC0
-:10279000DBB1AA14C55B4EF95387301DEDDC5F8AAF
-:1027A0006C925F71F210A605AE8BA5D01CB3D74416
-:1027B0001FC6B4C85338D58AA834CC3D8CE944DF51
-:1027C000AAA928575F785C3F1AF9282A46A14F0723
-:1027D000D1677D8286F8B97EB1C98FF2C732C52430
-:1027E000329013961F5AD6B1024C8B9A316DF61A5D
-:1027F000995F0FFA809751BAC96B66FE6C2067AF7C
-:102800008DE0FA93F795A7433B23AB4433AA99E6AF
-:10281000518F2548D0BEF5E5969C5D76C6D6EDB0C5
-:10282000CFD7E542FF199EC53BA2014E638E05300E
-:102830007F1698233699B1253BDF76FAF287C29747
-:10284000339D4D2417C4F65CD4FF947637967E6E84
-:10285000D79821DFF74BE71198F7ADF1E1F41DC2EE
-:1028600025995FA75D470BB60BF99EF6107CFC4CD3
-:102870001ADF7F97A4737D0A8784EB66E5CBC6AC2D
-:10288000A0A78C80B9DC3AA9E10CEAF0A2D927A074
-:102890007C62D7E07B902B89582983E0DBC3014E13
-:1028A0004058626C7F96EBC7D8AFD5C5D8D900FA2F
-:1028B00049A851C35B619ECF660EE2A35BAAF18972
-:1028C0003006DD8F9D763BF4B3AD0AC60BF0563D66
-:1028D000D737947AA3348CF6F72FD3F87ECEAECDCB
-:1028E000B7A39EF4A53C9EE7BCFD8B3ECE447BEB9C
-:1028F0002AA589351EC105F2CD5AE9B4FBA09EAECA
-:1029000011E62384DEF28B3491BED71D7E4490A065
-:10291000DEA76912C189957E1A77520DB41B80BF5C
-:102920004DF40966C8B73DE613103F9BD96967F0BF
-:102930001D335A88FED7C83C616BF8CBA28F410F7C
-:10294000D3799D76ACA7BB13E8331F27D46366B851
-:102950004EC9E347B010EBA3A4863E0D73DC409F45
-:102960008F4A7DD443FBC5DD26290BE8FB85C5A630
-:102970008A1D21DAFB549E9F0D31EAFE2D5A3E1F1F
-:102980008ADCBE6CE6EBA8F0F19A68A692E36B5283
-:10299000C65B6F84AFB5CDC85C01F86E857ECCD0C8
-:1029A000BEE1AB55661C3FE8D04EEA4FE4F264C787
-:1029B0008F72C86E0A5EC721F408943FA208E9A38B
-:1029C000CFDF087C68A8D2DB516FB2FE4393807BD7
-:1029D00073226B1150BE5853CA7A44DCD74457AEA9
-:1029E00033843E7933BA54D64FD99F83D74B773D42
-:1029F000E3FD129CEF7FD531D4C7561F8F8F710531
-:102A0000D0534C3AA7CB62D6A245FE98CCDA29BD6A
-:102A100085F5527A1BEBA7D4C1CC22A6A5CC4E6972
-:102A20001973523A9D79282D672D94CE64ED94CE7A
-:102A300062BD94823D43A99399C9EE9A07FB37A6DC
-:102A40000B9893D2EF310FA599E99C7E2B580BC1BF
-:102A500077B3764A3B80EF243DFA018C9476829CD2
-:102A6000C3F44D9073987679252665A31F2087D2ED
-:102A7000235E3BA5C7BCC594F6781D54EF6D6F3936
-:102A8000A5EF789D949EF05650DAEB7551BD53DE5C
-:102A90001A4ADFF57A287DCFDB40E969AF8FD2DFB4
-:102AA000799B291DA5077EC6F9CDE92B447D3EF50E
-:102AB00023BD4302F9EC91E5D26187E699DCF1B8D8
-:102AC0006E1A66403A285B2320FD5973340E3FA4EA
-:102AD0009B72560BF742BAE104D7DF0CD648D20FEF
-:102AE000AD6DF58204ED76087DDA0858CBE9E9A9E9
-:102AF000738D209F4B3AD9BA083BC2194F1981EE0A
-:102B000076E83CFD3BA0BC64A734D7087BD6E4C87C
-:102B100053FFB18FC3543EE9086B34033C2B3DFB9C
-:102B2000A93881E381C2EF7B3B73E6AECD443C25FF
-:102B3000C2F3C534302C51BF7EC444FA7561DBD971
-:102B4000420DC0931A4C45681706D4EB42BA1FAE2B
-:102B50005E70B9F2DDB65596469C870D9F805A0E81
-:102B600059A9197D85ABF3D5ED6ABE5EFF4C7B8319
-:102B7000FE03EB0937686F7F96A3327DC2FF7E3A72
-:102B80000FA66FDDF58FF66BC80F648EC1FD74570D
-:102B9000349733FDA09FEE04BC77C5C8F0C64C1A2D
-:102BA00017CA435CB70D9BD2FD3E80778539571F0E
-:102BB000C7F27FD4D87742D1AE70D7A65C8233C932
-:102BC0003FB121C69313938FFA3CDF975A931F0DA1
-:102BD0009302F8BF399DCBAFADB75CE9DD81764498
-:102BE000B38665C1773B9B976FCC81767EBC19F429
-:102BF000078047DC5ABD310BCAD3376A266A65198C
-:102C00008778FC7873F59E4DA85F258F8EC98676F0
-:102C1000336479991ADB57B806E8BC55AFB6A79567
-:102C2000F49F647EA98666CE826C4D95EDF41D3AC4
-:102C30005611B8DFFD4CC6EF57593CD5DDCEFD57D8
-:102C40008691E1FE2760FC2523B9BFC3B2CE48FEC2
-:102C50000E4BF27F9DBC03CA2DDB347654E9446BE6
-:102C6000ED5A1DEAFB8B593BF2E30E817FEF4BE1FE
-:102C70007A21280AE97303ECF2ADDED38B3203FC30
-:102C800084B60A9F80F67BC9C85AA10FF79FE40754
-:102C900005B4FB2D152EC11589F68187CACF65B9FC
-:102CA0007E920EF8D92AE1FB40FD92B912705DA127
-:102CB000DF8A76D2F35851607FA7B3F83CAC073B6C
-:102CC00099F4D5757AC22B78BE4E65971EC0F695DD
-:102CD000750C2EFF7E06B7AB773D015D201F4CE2E1
-:102CE00076F389DD89A43FCE690D77A0FD74E2A952
-:102CF000D165046F99EC403DF2C4EEC9D3319DB368
-:102D00006526D53B21B01EB487E76CB95BC4FCD403
-:102D10000CC00BDB3BA3277A9CB3E541F9FB47CB07
-:102D2000B0BC58E3FB09DA91C58DFB22D04E9E1C46
-:102D3000F94A12A627347DF5DDD0FF5D66F62BDC5F
-:102D40009E9D1BE3FEB11CFE31F7A9741DEAD7BF9F
-:102D50004B4FA7F59CCF1CC4075083ECBA5BF6F62B
-:102D60001E064D8ADDD6DE3F15CC5CE6E8301FC17D
-:102D7000B4B4CB5E86D357D6E33C82E9F45E4F19F8
-:102D8000AA2FE5A75B8E60BA24D7F53B9C9F17FF5F
-:102D9000E17BAFBC08F0C8C7EBCDA807653ED137D3
-:102DA0006327F9EB740CF9216B92A7458B046C74C3
-:102DB000C6A07C78F6695183FBB921AD250C61C3AF
-:102DC0007DE91AB40B7745B7D4D0B8B3C219CEE3B6
-:102DD000DBB00F215D64453B63909F802F691D3EF2
-:102DE00093E9D310ED3147637E18CF1FA817CEE1CA
-:102DF000F303F55AC204EA274620FB13D406DCBFCE
-:102E00006DF2FEDDC63C09381FD648CF0EF4EB64E8
-:102E10009570FE67919C2EB07AD344FA849CCD962F
-:102E200016CF9DB80E5697E8EB0BA43BD80607F4D7
-:102E300091748219DAD75B050E839C21BCF0877EE2
-:102E40000C8BC9427A8D82BFB502DA0BD033701C6D
-:102E5000F34C83DF2974179BC1C73542A6BFAC650D
-:102E6000BC3D05DFB80C2E9F016F4983F868657C77
-:102E7000601C9A007C02EAD1F806F066761BD20547
-:102E8000487A81A74C1203C75FAD7184A15D647A53
-:102E9000F5FBE84F8942390278FE53F72423F269A3
-:102EA000F0387232D208DF46D087516F9FE9E2FCDA
-:102EB000DB58E911C83E4218C79F2C3AD01F68352D
-:102EC000AD167401E3B526F37D7A66A5A71BE5CAA6
-:102ED000CCE2083BD2F79DAC7D9D99F3F7914CC0B5
-:102EE0006F141BF899D8C441BDF0474FBF7B1297B0
-:102EF0003499B597E4E2FEF9F8FDB370FDB63E3AB9
-:102F0000B307F14FCC79AA3B061A745E94D77D19AA
-:102F1000F7EBA46C133F0E1C479207E040BF448DB3
-:102F2000BA1CE841052B7465131AA271BFD144E4A1
-:102F3000CF9C817A4A9486E43BC829614148FD339D
-:102F400088AEE4F957D6E7AE8C4C5A37AB89AF035D
-:102F5000EBB71B1746CA8355D609FA6D04361F0115
-:102F600074DF58A6F50B68D762FD28ACCFE29D91BF
-:102F700043D769874E9A3903E5F4C31AF36E367462
-:102F80005E81DC7E4B7AEDC371540EF9A291FC7D1B
-:102F900001F86A43C1EAF5B859FD6DAC6BEE8CB42B
-:102FA000A1F989C90B66E23E9B58CB68FD83CB47EC
-:102FB0003DA65E57B237C7A3FF88F9BBBEC17ACE24
-:102FC0004CDE5586FA7CF0BA2A74971A1B7A5F1089
-:102FD00033395FA646D84F95935E21929EE04C11FF
-:102FE000E303EDA20D197C1FBAFD3513ED43EC236D
-:102FF000A31FB75C7B57EF93B9B00EA5573468AEEB
-:10300000B0A3EF1CFAE14C48A7FDEADDD5FF0AF5B5
-:10301000A67D651A87F96FB0BE19E810F1F5809D9D
-:1030200001F0DA2FF6B4A0A3A4B192D971DF55FA5A
-:10303000D923F7F30B9DDF49F23557643B490E82E4
-:10304000651E402F0069897E78197356B690DD6839
-:10305000CDCC07598D6EBDF625B45FFE49CFD0EFBC
-:1030600038AF42D295C0F8E7554ABA65E8C7175954
-:1030700039EA11F32BEC943FBFD2CEF38D3C7F4164
-:103080008583F217543A78BE09F2613E1656F87BF2
-:10309000BDD0EE42538CA4413F78A593975F355045
-:1030A000F93B600F6402C98787F949DEB77CA6E166
-:1030B000F1124FB85F005C0D91453D12CEDF7D1AD5
-:1030C0007B162486149199017EB6C2E9D742F9F3A2
-:1030D000CC9F8013F946F56A6736E4BF912C9A714C
-:1030E0007C6F38C06EC6F9AB1569DEE907F01B3599
-:1030F000C914CFD821FBAD7D2B8CE467055D87FC1F
-:10310000AC6C45A2ACC7F0F26DCBCD7ED4C7400EFF
-:10311000D23AF6DF27921E00F2F0ED1CD48B5ECA85
-:10312000B4874948B76A7EB3542F2FA1F62A99195C
-:10313000EDF25995BCBDC697347E0DEA55A679339C
-:10314000910E1AF7323BDAAFCF569F2A8B45789B08
-:10315000DDCEE5875A2E34566F392EE1783C1A734E
-:1031600016D5E77EAD464FE92EAD30C8CFB4DED2DE
-:10317000A0FC182A6FEC3DD84E4255A97D13D4B35C
-:10318000C038D18FBD4DCFF37DF7881467B0548B15
-:103190005DE68241FE4E91A7D0827C1845F245C57E
-:1031A0005FA35F52C33F92F914F85DC471F97631A1
-:1031B0003BC9955DEA7A20273528AF52DAD4F96702
-:1031C000B204C52FA59A87E079B67AB8DC0B1EE762
-:1031D000E0B8BAC246D1B8347C5C28D7203FD77457
-:1031E00088F2732B45BB24A1BC6B3F85E31FF5928E
-:1031F000C8BA009E555D3413E969D6660DB94366B9
-:10320000B35E920B371BB7E2DF081E67F0F8366437
-:103210006869DF1CD007D71B491F6C7DC4A4C1B8E7
-:1032200022E85BE1E8573897551A9E09F33022539C
-:10323000D6D7AF6BB93C6934119DEAAC8FE504FA7F
-:103240001F84D1A523B0BEEE7AECBC728A1BE9685C
-:10325000DCC172AC58966393FA607C2AFF73389392
-:1032600002E6F7D6FE18157CFBD54455FD12102E4C
-:1032700081E5538D79AAF269E6712AF80EDB1455BF
-:10328000FD19D254157C67CE9DAAFAB3EDF355F023
-:103290005DC54B54F5E73AEE5595CF2F7F4855BEA7
-:1032A000D0B946052FAAF87B55FDC5AE4655F99213
-:1032B0009A2755E5C1F693929666723FCF569BE7E3
-:1032C000A483E48B4B70460EAD67A914FB03D73D76
-:1032D0002A82EB53C1F51AE5F57841E0FDB1FE48CD
-:1032E0000DF29DE27F63ED912AFF5CD7E4C9C63EF3
-:1032F00013FA72ECEF23DDB213DC1FC5FCFC3BC5F7
-:103300007FD5FD04D483F65647A65B71BF43BFABA0
-:103310004B0FFDF935E4BFB736D70BB40F6EAEE7F0
-:103320007E95AB7AE68A0DC08385F37EE5788E8242
-:1033300027734470FF6018CFDF26FB959E43BF5272
-:1033400036633FB0287E7817B59B50ACF7A17F4617
-:10335000A8F6087A945B2E66364828079753FF979D
-:103360002BEC2358887956D256AF8D39A07D5BBDA2
-:103370006FAD1EC656973969CBB3D0BCCDC3C81F3D
-:10338000F368E6942D6B81E7FF2153A2754910F98C
-:103390003C3F5FF7C6B93DD05F6B95A508E56A7005
-:1033A0007992BBF3E2B11B943FBFF2D50FEEBFD1D0
-:1033B000F7751D679A02CA87F58B56243247001DA0
-:1033C0004886D07EF91FC874E59EAC273FD6335A95
-:1033D000D793C8CF1726FFD7C4BDF0DD79E9CA3D22
-:1033E000A8A743FE0F301FEAD1BC9ECFBC44E729FB
-:1033F00052F340BF47FD3B2C34DD1E94DB17AD95E7
-:10340000FDE8075A1DA997D0CE4F327E467EEA0EC0
-:103410001DB7AB83EDF7E707ECED76B2BFF7CBED69
-:10342000EC9653AD997FCF8C3E265AE4F84088F94C
-:10343000D046B50928AF12ABC54F02F9A23B524F97
-:103440007E048B49F63B986A547E01C56FD01D7986
-:10345000BF80746FE95A417E7AF417607B07E57587
-:1034600009F6172419FFB4E8E3D81BB5CF06F223F9
-:103470008410FD04E1A1F82782FBF1A33E81FBCC7F
-:10348000CA70D22782C77D39B3E450663CF248FF48
-:10349000C93B507E9FD2D17E381CBD8449E1CC1FF0
-:1034A000D07E6F26B7EF23726254F991F644E60F8F
-:1034B000F45FB364F32711320C5BCC487DDFC65157
-:1034C000D8DFDBBCBF133ABB8DF441D8F6D0FE7B0E
-:1034D0004FE6E7EE5C4669AB6C97B7011F63FA9C59
-:1034E000D74CFAD936E03F84B77B254AFDDE1C4A2B
-:1034F000777AED54BECB5B4CF01EAF83E0BDDE723D
-:103500004AF7799D94FF92B782E09F7A5D94B67BEB
-:103510006B28FF15AF87E003DE06825F457D5044D0
-:103520003F7533A56F785BA8BCD3DB46F09B5E3F4D
-:10353000A55DDEBD947FC8DB4EF0116F07C1C7BC2F
-:103540005D04F7787B287DDBDB4BF9EF784F13DCEC
-:103550002B8F93B1E65E2FFA2B5CA284FADDB3AE1B
-:103560006A33EAD7B6651A338AF336976605FA39AD
-:10357000B655F2789F6D9586FC40A087FA519FB3AF
-:103580002D7BFAF8342A5F40E55BB149304AACAB99
-:10359000B8FECA56EAA99E150F02C177DB6A2BFD59
-:1035A0005A805BB2C3A9DCBA4A24BBED798D273AB5
-:1035B0009BEB5D24BFAD3AAE3F28741021FBE9229E
-:1035C000B2444A976573FCA33242EF2319594AFC6F
-:1035D000A4B907C767AB82F121BE55F5468C5F5A87
-:1035E000EF83F149A43FAE3A047824C378117FC039
-:1035F00087FCC26C19D797AD55EB08AFE465F3941F
-:10360000786734DAE96D9EFAB9846FA5487ECD36C5
-:10361000D7A1E8FB504ECAE77CACF1E14E7FFE50EB
-:103620007C3282F0DFC6B8DD900CFAD2FE10E300E7
-:103630008B47A9C7FD788F1943FAF126CB7A62B27E
-:10364000C0F98F3D2C12FF6D67A0F7C177CF817E47
-:10365000E7433950BA6F15FAAB1ECD724DCC023C20
-:103660007E248D3F24021C53CEDB4FAF17F7A01EE4
-:103670000DEB7DAE09F2373EB8D989B671EC6669BB
-:103680002DB25BDBB25713D0FF952CA8D74749CB9F
-:10369000653CB63B787BCFD58BE44FB6AE3A90769F
-:1036A00084F75B86FD268EFA7D18BA613216481AB9
-:1036B0001419C955E245EC2FECA1CDE5D85FFC66A5
-:1036C00087D25F21F6F775E769E4E365565708BCD2
-:1036D0008693273793238BB322E3488E24B1249417
-:1036E00023CFEBB8DCF29DE4FA241D869934B41F95
-:1036F000257EAEC4D383E3E835323D241942C76149
-:10370000570DE8FD3EAAB7DDB1C949E74B303E0B86
-:1037100045AB756C05AEF3EA9270F3DA10F4A0A431
-:103720005B508E01DFDF8B4623B5B3B99CB7A3E1B5
-:10373000EDDCCA56115C6232FB42C86B257D5A6EC5
-:10374000E7812C4EB7490FBEB4F118AEEFDB3A3A21
-:1037500013F49CC6BF11ED04DF092DC9D7446DFBDE
-:103760008E3D017835CBE3794EEFCFB523FF407B1B
-:10377000F92857915FF2C97FC16605CCBBF2DD5ACB
-:10378000D98FFDA36B1BA229BE5CB52E0CF5A33609
-:1037900066247AB0EA3CD18501F46045BA0C411F39
-:1037A000FBB2F44A3CD5543211E3327C5F9E8A72FC
-:1037B00009F03E581D45FBE1D465EFDE3916E05BAC
-:1037C000AE8876D4CB9EABE5E71327FD5143E726C1
-:1037D000DE7C9CDB7DB7FDB7B21EF47B27C8E9B366
-:1037E00068E7417A4B33B377C1BADC526D22FFCD23
-:1037F000AD57C5B381761AB9A4C7A37DC1FD3553B2
-:10380000FAA13C80FE267DA6AE0F33AA453D23A13A
-:103810004F9D6FAB3A70661AF4D356CB3F6EBBF632
-:10382000FE71847DF51AF29300F529F49340FE4D64
-:10383000D19780E716371A19C973EB32A319E541FE
-:10384000B7259CE45FDB6213E9A11B325787A19E79
-:103850006CA8AA8FC674A4DEB7037DA7DDBBFF7D6D
-:103860009E2D81E42D3F7F8184590CFAC0BD7AAE34
-:10387000E4F8FAB64CCB4479A9A1F2C3BBFF7D8B27
-:103880000F7D07AC85F090342C910F7E00BE9BE23B
-:10389000D402DF2F40674E44F874AEAB07E54342D5
-:1038A0009CAF1B8BB69ACE56D2F9E2CA38E2335D92
-:1038B000B587E931BFB2C818C8E70A9FFCB5FCFF5D
-:1038C000B41CE7BB991CB859BB37E3F79FA573BE7F
-:1038D00019CE9E360C234F15FB18CF9A638A6C4B7A
-:1038E000FBEA597D48FDEAF66CCE67C57A7E3E64F8
-:1038F0004EC5F4728AC3F8FA443CC79693CDF9A931
-:10390000CD124971E2B674D6857103DF720DF7F7F7
-:10391000C4F1FFDA2AD3C93FD42A78A27D19783EB0
-:10392000C29586EBD706731409FDB7A672B9CEFC13
-:103930001E33C6ABA19D9A40FCC1DEF3A9E9989164
-:103940003E4CFE0B2DF19EA40FF0B7A35F1CFD179C
-:10395000C1DFDDDAAF866FBFAA864B984E054F35C3
-:10396000AAE16966356CC9E67AFA1D3675FE0C491E
-:103970000D27A71C09D3F073EDA6017FB344F0BB5C
-:1039800099017EA00D9A7601E725A5AF96FCB2AD10
-:10399000A9DCDF935CAFF67324B296B53102F96D02
-:1039A00054F9B6FC5502FA736CD5EA7C9807158C6D
-:1039B000CB8AF4BF24D7959F8D71E9027EEE3A4BF6
-:1039C000EBE9CDC575688B233E4A93CF050DDD1F0E
-:1039D000B7D0B89576900F7C01E345FA0F842FE6B7
-:1039E000BA2667C7733EF005EE97F97D3AE403A562
-:1039F000BFE1F841E1C762396EA29CABB922B7A51D
-:103A00009CABA997CFC775049DC7B9925C46E78167
-:103A1000AEF4AE090FC577C867BE6CCE77986E94CA
-:103A2000CFD720DFF9F49CEF30DFF0D52A6728FDEF
-:103A3000F0BCBCAF3CB437CCFC71C0F856B647AB59
-:103A40006077478239F0BCD343F80F74BA37333A02
-:103A5000475A2B0FE78B33BFDBD308E95B5A970B31
-:103A6000D76765D6593D8F33F5EB51FE9E97F7DF4B
-:103A70000D82DD385AC094DBA58D66BB11FDBDCC2F
-:103A80009FA1F257287E87D52BD2AC3180FF8801C9
-:103A90003F82D34CE74DE333C98F1135D571372BB6
-:103AA000043CF7CC986F04A2DC854E5590C78F6517
-:103AB00097FDD0973C385E03FAAB02CE2319440F32
-:103AC00023B97335954901E7CA5B65FFC5001F9BA4
-:103AD0009697607F3FCC96783C8679D672FF9FDAC6
-:103AE0005F66B86A53B533D87EB2AADF56D92F7253
-:103AF000F3F6D5FE37C3D5F461DACF0E6ADF1CB218
-:103B0000FDC176D57EBCAF111F6F433E18CEFFB509
-:103B10005F96A71B6C9E5EF47FE918D89514070684
-:103B2000FA98886A23FF69C3F979535DB2DA0FA660
-:103B3000637E921FCF47D690FC48603E8ADF59983B
-:103B400087F2D7474DE7F1BB60B9711379C1988708
-:103B5000A1DE00FDA9F2573FC2F7D346C1EE423CB9
-:103B600083C7F3FF8ADDAB891CDF4BFA734AB86465
-:103B7000B881DEDBEA7525E3F71BC23D3518EBFEA5
-:103B80003CBB2E763DE83D1B30C6087C7635BB71CC
-:103B9000BECF84FB24A78FF5711AA227CBDD961D1B
-:103BA000DA007AB2E85D69A8F75A34F2392FFCA13D
-:103BB000BF6CBD65E7A610FD2BFA9B025B2B008F47
-:103BC00000BA6D95F5E681FE9624EED006B4633119
-:103BD000B80AA93FE55CA3D25FD337EB6FABECF734
-:103BE00052FAB3DEA31E9F55EFA1F159E5FD47E957
-:103BF0006F2B8E2F045FDDB43FD98E1EE86FA97A3C
-:103C00007C568387C667D572FFE1407F4DDFACBF2E
-:103C100036F91E934DE6D3E1CEFD370E9CAB761AF6
-:103C200051AEB429FE40797FBB14B4BFAD96F737CF
-:103C3000E5FB4B71E9E4DFBDD433DF186A5FC3FDF8
-:103C40008CC97A2493F54826EB9108CF997AA63E41
-:103C50001EE8B0F0C5B6F922ECE3731E3A333E1508
-:103C6000E0192FF6CF17615F9AF3E2990349F0C983
-:103C7000CB2FBECCCB7F78E64A32949B7CEFCD2F06
-:103C800003382A96EFC70ADE4ABFB78DE27AA3BB94
-:103C9000E173EEBF04F98AFB5663AA87A17FF14264
-:103CA000727FD432A8EF4EE9B72C0F312F4AEA6E5B
-:103CB000384F7E46147928FFE6E1BF40B4CF53EE7B
-:103CC0006794ABEF6744456D22FD2F8CF9CD28EF4B
-:103CD000228C0EBA4FF8D628BE1F2C64F60A6E3717
-:103CE0004859F2390DBACF31BF586ED77CCBCFB11E
-:103CF0007CA1C6B11EEDD9DF4EAA8A47F558391707
-:103D00009737787F72D7F51B9C1F0EBE3F39E7238C
-:103D100081EBC223B8BFA53B57E2F7B902FC86A8E6
-:103D2000F70E379FB5A3B87D3F389F0E3E9F310EEB
-:103D30003E9FE6FEA8B5B0FEEEE87ECB13C49F5DC5
-:103D400021E76BC8BC06CD5FFD28A6D8795AA4B779
-:103D50009BCDB732AFCAF9C14641CAA2FDEA4F793D
-:103D60002AFD8331BB142A8E83F419B8BFEA6D4E45
-:103D700086FE195D9C3D07CF9537FE451BF25CDE44
-:103D80006E793ED64685D3B9CEC6283DD9DBDD5106
-:103D90003319FA9745D3749A97B2A8723A6FA98DDE
-:103DA00065ED688F069F23D78EB89BCE0169AD68FD
-:103DB00041403A702ED961A4F889B9E886E7C8C5B0
-:103DC0009B9D238F99C9CF9147E9257459B445EA42
-:103DD000439E237F6C14DFF7BB713C71883F8C27B7
-:103DE0006D701CA299C7D1313F02F2F56617237F8F
-:103DF000BA3CDEC7E47550EA1BCC1E86F240ABB776
-:103E00004BA8A768C3F93E61B069584E08BFC8F710
-:103E100047E9E8FB4F72CD34AF1A23D7CBE7FC5A02
-:103E200008E94F7A7594E24F0A4D67C3D1C93C0D3A
-:103E30003F47A7F0E102939ECEF72D30D94AD10F2C
-:103E4000B20008EFB39880FAB72DE2F78145BB0DB9
-:103E5000E9E737536EFFF96F18BAF9B97C3E35437D
-:103E600047F7E34E09CC618F197A7ED5E98C9E869F
-:103E70006E9ABB669D5987ECF7E2F2EF15617B867F
-:103E8000E353751689EC9F7746A15CA84E5B1F0F24
-:103E9000F0A2CA421DDDDF94E344EE082EC79FD195
-:103EA000BA4E8EA278D1E751A54847627F2AE2A395
-:103EB000C48902EABD372A9EEACDE1D7C5A0DE1843
-:103EC00094D3677FEF62B41EB6507A12DA4F2C306B
-:103ED0006E23CB07B4A302F3D17E6201EB272C2F14
-:103EE000B6F68590174A9A60DB92520D7C9E90D070
-:103EF00042A992FFAC435BEE0FB1AE57E575FDC62C
-:103F0000764C1B603B71D08E01FBE52ACEDB17D5CA
-:103F1000A72CE36148756517C98EB1E9153E9388F2
-:103F2000BF06611EAF04FB4575DEB0D5EB4BA1FBB0
-:103F3000FEF2386D2BD646A31D03551C489FDBBCF3
-:103F40006D29659983E3C8CE91E9138DB689A817C9
-:103F5000F35F725CCB0CF497249B34743E012653C0
-:103F6000752F616E59F4B4383445DDCC6E92D02E85
-:103F7000EF253D3FE1BA96F820E1F0628671ABA4EF
-:103F8000B87601EF030DF423DF6FAE97E3B9575C0A
-:103F900065348E04EBC0FECEC80E8DF3CD4579742A
-:103FA000E5698E51C28FD5E5C971FCDCC2FDD5E152
-:103FB0007E09E83AA9B6574038010C38F4C5275CA9
-:103FC0006F4C6B4279F25A04F98BB56D99CC07F2BC
-:103FD00027557445E5E03CFBA5FFA6C990070BDF1C
-:103FE000AD7C209CF4B336A16506D925F769582825
-:103FF0003FCF981CEEC728C8E1FC9F606B4DA91EFF
-:1040000087E9D344375F97CF6790B31DF4D9119FE9
-:104010002DFA581CD47B9A75A1E9739BDCEFC07E06
-:1040200021CF5F187319917FB582933B39F7EEDB8F
-:10403000B7CF82CE1346E75536C97A8DD24E444E5D
-:104040003B1546D81D0CCF450A6607DF07CC3E9BC3
-:104050000FD6ABF92B6D487BEBC11C791F496BB2B6
-:1040600061FDB24CBB0DFD94C1F7551AD326DA7031
-:104070007D1A670CD0A931705FE84ECB7E1FCF53FD
-:10408000997A742CF01C5970AAC77321B1372897FC
-:10409000CF97371DE2E7429B4C45BD780EA1C9146E
-:1040A0005744C7FE4CFC9CA952DF643A46F2DE64DA
-:1040B000E7F15613EE0F02A2C7E7A13BED18CD833F
-:1040C000526F5A0E97AB267B17C3FB5BE1763FD549
-:1040D0000B139D3E0DE01F16C7E8FE4F9891F35558
-:1040E00004AC8F3180EF957E6FCBD1D1BC352517D5
-:1040F000F596107E22DE04674DB6221BEDDB38DF1D
-:10410000D06F63B442DF9CAF1F97E75B69A7513E56
-:10411000FF7A4F43CEFCB258F41339D7E460BBA604
-:10412000E546B483B491E36FD8DE8661DB6B5E282D
-:10413000B7F738F28536B2C88CEDE9505E84A0C37B
-:1041400067E476FE57E3ED30B374DF97605A309F33
-:104150002D94DEA3A4468CA38F1BFADD3796BFEB0C
-:10416000D47E2490BF7B71FC2B93CF1E2BA11CEE21
-:104170003FDA2EDB278A9D6191DBDE2EF07BE83E65
-:1041800021DC4EEF36C87687254C3D0F83F741F989
-:104190003A5CAEE0E7E62EC7318A6B04F3F3E577CD
-:1041A0003E8A0EB44F50EF736473BB0453B44B1C80
-:1041B000B29F0D61F41BA09DA2F0FD805FB742FA93
-:1041C000A75B003F03C86F0DB42B247B88BE0DC9CD
-:1041D0007D69C8E7A9F23B0543F6D75C2EA7854762
-:1041E0003F4B43FE2E8BEB4FC0EF82F9FC8547AE71
-:1041F00026E0785E983170CE86E243AB17A7F37B5A
-:10420000D9C7FF1CED0AD1FECDEE7F459DDDB486FA
-:10421000F4C0E55C0FFC5BDF07DBBE8CEB9D1D8211
-:10422000DAEFA4CDE57AE75FE47DCC7A55A4F72DEB
-:10423000CE65B92E201FB60AE6E5287F531FE1E7B9
-:10424000E6563F5EFFD90321F84118EDFA734E8020
-:104250003D5CDCAC273F5AA3297DC48DE21CC3AF73
-:10426000B387CB71797D4B1E35F2F3242EAE175BED
-:104270005CF7D33995E0F323C3D53B24CB3DA5BEF2
-:1042800001DB4779629A47FE804B6823A0BF4D96B9
-:104290007BC17876E264C8F36304B9127568451887
-:1042A000B6AB93EDB1ED8A3FA3A2C8E808F85EB7BC
-:1042B000B8C8581A402F8D8C9FDF0D6EFFCEDC01E1
-:1042C0007D5AA5AFE8709F45DF509CF8A7013943A0
-:1042D0008A65B8CA8E51FA0F3E3F16705E2C8CF379
-:1042E00029B7675AF1DC18E8B76B2B968FC4F96DC4
-:1042F000155D2F58611EFA3F30D039E70F65BEECCF
-:1043000093F972B8F5F3B143A08C31F6043B829770
-:10431000D6804EC68F40FE68CCD494FB438CB35CF1
-:104320001E6708FDFAD6DCAFA75F97E686D0AF51CF
-:104330007F7604C51F0261D49B1D21F4EB1382EC30
-:104340000F90CFED9CD0491D7D300F276E1D616F02
-:1043500094E89E91C35E04F6C38B6732516F9F232E
-:104360000CBCC723DB318C60B02316225E739967C7
-:10437000DF0302C5515AEE48A3EE045C8F9BADA744
-:1043800024FB1137C23A61DCA1F5DAB219A1E20CC3
-:10439000FF38402728BA02EF07C02A04C49586C414
-:1043A000CB82E263184E1938FFAB1D5AFFAE62751F
-:1043B000FC6AE335EEBF30AC60FE27043C1FAA2E3A
-:1043C0009F5FAE0B8ECFA9E25A0B9DBA607C7C88B2
-:1043D0006FB28C6FCAB607290E3E2D45E4FDAC6462
-:1043E00064CF07C7BD0C85BD0E2DEAC3158CF4F74D
-:1043F000603F369E1725FF5E0563CF0974DE5A7D48
-:10440000DFE4E959E7F8FB1C2DE5D88F2D53C350A5
-:104410003F0EBEAFA0C49BF0984CE07D69E5DD2265
-:10442000CB620DE1C77CB753B9E29787FAA6124B6E
-:10443000C0B9EE556CA03EDDA3F2851EF7D6D65965
-:1044400014EF4F1CEF29EC82A2243BA37948AA6603
-:104450006407C03CA8E2FA86945D34CE4B358CC527
-:10446000F238A0AA3C017670A44F18BF2ACE0FE301
-:1044700054C1C176E7CDEC4D434AE60DE5F9CDFCDC
-:104480008D06395EF8466E641CE93B63D818D47714
-:104490002C8B9FA6F5B804EB817E59348442C5036A
-:1044A0003743FB6807BA905FE2D1DFC454EFCA30EC
-:1044B0008748F7C984628EB310EBE4F1E17C46FCD7
-:1044C0006D0807950BF859986C70E0BC1B0C00C385
-:1044D00090053D332640BE56F637AF1598883033E9
-:1044E000DB8DDC4FA8BC6BE3A7776D86EB0774FF11
-:1044F000BE30ECCFC7BF53FA19F28EDB0DBE27FBDF
-:10450000CD1CFC7D19F91D95FE879BFFE1DE6DFB3F
-:10451000C3D4772770BF6732D16BE520BD12BC4C86
-:10452000A647FC1EE5C2BD4AB1AD770CDE373CFBA9
-:1045300070841DFDE003E3F0DDA9E5EFD1FD75ED2D
-:104540000DE0619348BE0F8C4B6EEFAF1D17FD025F
-:10455000E4DA06BC3484E74F2A199D27B0B84ACF65
-:1045600089740E00C6A0921301EF13407B1B0EF15D
-:1045700073AF5BF19D0B71B05FD42BD06EB0554221
-:104580007E083B4849AB19BF1FACE0D5A8073D1AD0
-:10459000E952C3F5E8D9A63E11CF35E9E2FA45E480
-:1045A0001FE7682EC707E8379ED1F90B6D927CCEC6
-:1045B00071A4C4DF4DCBE4FB9BD2CF84D11A59FE4A
-:1045C000F7D2FB47B3234ED54B76C6F2F6C52F4440
-:1045D000FFFCEC11A7EAD3002ED867E170D2A92B1B
-:1045E0006966C6ECFBAC0BD19F3F3BEFD495748062
-:1045F0008BF6D978F9144646CEF87D090BD19F3158
-:1046000061B459D5FE5B38D7F1DF3CD51A3421CFE0
-:1046100063DF365A394FC9E83EADB3F397A7312E61
-:10462000E954F647872E48DF81220BDE23937F7102
-:1046300051140F9D29D3D99DF8EE5214FA2DBB6861
-:104640007E470DFAE99FFE6BFCF482437997CACC52
-:104650002A81FF1B1B982B2C2380EE9943739D9F6F
-:1046600003A6B881828FD2FF10BC6069C59840BC98
-:10467000B6513B0A5E170A0DA48705C7872E08FDB1
-:10468000DBF19C54C4CFD62FC275BA10D99F2A0033
-:104690001C9EB79ED6ED427CFF76C11E00EBF83A19
-:1046A00056EF2BA275FCA3D6513D7A02BEDBC5DFC7
-:1046B0006F6896E3504FC6BB7C689F01DDD1B9326D
-:1046C0005F8A9EFC4865E30547A03FB06E34F7CB98
-:1046D0005C92D3698616CF49A04BF70181AD85FA6C
-:1046E000EE6B97F5A89FCCEE3CA3473DBAEEC01900
-:1046F0003DDE4BAD4318DAA9DBA67784D2FFFE324C
-:104700005AABF2972976D7D194ECF5E877ABAB1694
-:10471000E81EDEEAD7B91F6EF5321C256377DFB2DB
-:104720009FFCB855CEEEF5982E657D47F1DD88C526
-:104730002EADEADCC0929A08553CBECA13AB8297F4
-:10474000B6C0EAC03EBBB42149F51DC35DCF82EFC0
-:10475000280EFED0FEAF90D771B16D732FFABB1645
-:10476000BBD47ACCECCEB5620CE2ED11EC1ACEFEE5
-:10477000127EB7848F10D200BD0AE67D5A07D7A3F8
-:10478000EA2A8C649F54220CF35A59ABF5E39373D5
-:104790004753F454EEEE10A8DC2D97BB6B046E5714
-:1047A000CBF275A98CE3928327A7D175529FA337CB
-:1047B0003300DFA515E5E7881E657D43195785C4DD
-:1047C000F58D0D29EFE9B0DDA5DF17586C1A8D4B7B
-:1047D000A5472DA951C3551E5D909ED5A743F9BD90
-:1047E000B4419DFFF3D1F2BE9EC7F2909FDE182D1B
-:1047F000889F1807E13FA5BC7702EF815DD23A0F91
-:10480000227DD6EABB0A70DFBBA47511AC94437E4F
-:104810001DDFAFB8BEA201CEC3EF1B750E33DEA7FE
-:10482000F5AD14886E97B000BD276DB03EC1DAA11A
-:1048300070BF2277C39CF5E40F3D2898516F281371
-:104840001D22DE836F1CC68F7E51E68313AC2F1FA3
-:10485000F1CA46228575CA9E3F82F699ECB796F951
-:10486000308E943D4E20BFC49D80714311A622C955
-:104870009139B03784419AAD6DAF20F93E566FE65D
-:10488000EF62DA58A0BC70FC331370BE1075B20B27
-:10489000937BE8FDBD396D9B2FA25CCCCC70143DA1
-:1048A00005F83D19C6FB7FF275C1BF16DAA9CB3FEB
-:1048B00046F2D30AE481FDD6D96439DAA1F6CF5A9B
-:1048C00051AE21C1CCCAA77E1394F832D015EDC3E6
-:1048D0005DA5A49F58E57E9F2D94B8DDFCA07C2E9D
-:1048E0008DF9D6E2F9FABED18CF295F41BFBABCA76
-:1048F0000431285E50371AE679A5AD4F75DEE95BC5
-:104900006CBF01E92CB87D18BE2A5E394D7B2D8A1B
-:10491000EE771DCCB0DEE8FE94D6A83EB7A4338770
-:1049200007DDBB53CB9FD9F6A4A07B771941F7EEE7
-:10493000F282EEDDA9EFF92D744E09BA77A7BEE732
-:1049400067B0CD54D50F93E6A9E0889CBB55F523FD
-:10495000EDCBD5E7AE8EFFBC4248C777067D7D2EF6
-:10496000988766E08DE298C17D242F0A2A431A3E7B
-:104970002ECC846973A1A10BE9A43991DBE786E30E
-:104980000FDBBAA01DE388978CE86FFC89E02F4508
-:10499000FBC4289F5319FD1853ED33AF1570BE5259
-:1049A000D2DBF25CB3F3617DF2F74A49FC1DE0DE35
-:1049B000D1B83E467C6C03F9E6557EAF78AC6C47C7
-:1049C00028ED3C5F5832350FBECF7FCC3183E2EC0F
-:1049D0001DFC7EF04E3D8FA7F85EE5E75BF33BFAEA
-:1049E000348E00FE3E99C7F590679CA5141FA9EB75
-:1049F000845D16F9A9EDAC1EEF65D4757647E17EAE
-:104A000056E03CAB47BFC960BEBCCF89FDE168AF93
-:104A1000FFAC3D743C6D6D9E9EF8E3982CD7AB1EA9
-:104A2000D672BB913966E1B971455E57EDE7E3ABEC
-:104A30005AA8E7E760311A1D426E839C3EAB96C3CD
-:104A40000EF57E708B7F3DCA0E90DFAA7A4B174C15
-:104A500027BBB712E436F231C87375797213C917E0
-:104A600090E7AA7C77DE803CCFBF0EDF9D766A425E
-:104A70008EF3708148F378DA3595E6FF199847F49C
-:104A8000A73D3364DEF87CDE6CBE5EC6B50F58B75A
-:104A9000E07ABF2EE0EBF6F230F2FA7D795D770A2C
-:104AA000BD45284CDDCE70A2DB254663099E7B38D0
-:104AB00096F26513C6E1AA7E2ED03DFD7FEB3E6ED9
-:104AC00041FD5FBFFFA805FD61EEF6A316B04D598D
-:104AD000AD4E5A8B7A3CD0851DF59EBA8E2EC27F84
-:104AE00065FBB86ECC5FD921D0FB3DEE0317A7D391
-:104AF00038595F13C60B770E83D78FF2B8FEBE37D7
-:104B00004FE27E3017F489FBFD0183DF2F201D80EB
-:104B10005C42BC5E17F0E535B673A3B122941EF576
-:104B20006FF27C1FD9A867E8AFAF85EF711CC75241
-:104B30008EE98D4847FB05B2B5DDED27174660FBD2
-:104B4000F53A86FA8582DF1729BD1FE2F83FA8D61D
-:104B5000A1A78035566B69BE3FA8D7523BDAFB74DC
-:104B6000042F5EC1CF551CAEFEA82909DAFDA05660
-:104B7000A07B0C53EFFBF3318417AFE0FA5A303DC2
-:104B80002BF41A4C9FC1F43B844E6BBE199D1EC979
-:104B900093EFD5E4B102DCE761DDA759917E1EE118
-:104BA000F7E32BAE1DD6A17F33BDC96C7F02E03188
-:104BB0005AFF7A0BCA89C3BCBCB07687C0E58D7436
-:104BC00037F26152B39EA1BDFB7E1E974BEFE37A95
-:104BD000C5E3D0FA058CAF31B1371DE5529A1C4FB1
-:104BE0007A45C72AF6535C90CB9B31AFD954EF96E8
-:104BF00037E571BD43918340E6AEFDE4976D4FC448
-:104C00007B142FCBE74153E5F6B232FAA7CF85F4F8
-:104C1000AA4C2F67643C14F8B24CFF6CDBCF681FC2
-:104C20009F2DC759663674D179CC3C83EB5394875A
-:104C3000B352DFABC57DAE39FDED7C3A678D3725CC
-:104C400026E2FBC9FC7778D2A7DBD660DC2F379C45
-:104C5000D631ECE053741E382C6BBC35549C434960
-:104C6000DD57257A8FB0EE6A3AA50A3CF7D0397D38
-:104C70001FD90117A7139F5CB5A9DE2DFC54C67B75
-:104C80008CF23E5D27F7F3809C168B8B06EB29F3A5
-:104C9000809E651C6F58D62E5AAF35AB5821A9752A
-:104CA000EC29FECE66ED4901DFBD58A473E84C3017
-:104CB000DFEF8D60251F8BFC1D245736C64D8C748D
-:104CC0002FFB84D74C70AFD746F029AF44E9AD61D4
-:104CD000CE887C6867E1114F16CEDBE1945627DE63
-:104CE00057BCF08E4EA66B33BF2F2ED3DAE54E2D78
-:104CF00033629CEB00E8E3C220FEF75C4DA4FBDDD1
-:104D0000BFC3FEA09F950DBF217967AFB9381DEDD8
-:104D1000A2C2DA334D08BB1BFE3C1DF5890F61FFB3
-:104D200020BD1EF47B9B8072E424BDD35D79358663
-:104D3000DA7959D33F1DF9CBF7A640F76F3EECB8AF
-:104D4000A8B7F2FD89DC73782F1CFDF2B3F2A3B98A
-:104D50001CE92CD4D0FA3A24D53BEBDDA3FF2B0A77
-:104D6000D7C3D820FD7A0A7EDFA365C8BF9B4AFB64
-:104D7000A3CC21E4EF69F4DF65F371B0ECA1E51594
-:104D80007A5F169E93AC90E938B8BC3C7FC03FA1D7
-:104D900073CAEFEB0801FEA12AC6DF3F05BBA72BB4
-:104DA0001CF8B8AA732AF967AA3CC20DFD33C3D117
-:104DB000E1D74DEB18F7CF2830DA8D817E4DB41B4B
-:104DC00099AA7F1F7F072B25F386F774DC7D891452
-:104DD000CFAF6B6614EF5A797534A5E75FDF2021FA
-:104DE000FF18C3FB5BE97E6BB686EC8C953EB5FE87
-:104DF00033A580CB8529057CDE5CF9602FE5B00109
-:104E00007B09ECA27BF3B95D147588A9ECA5E07C65
-:104E1000B2978CF23D1D1013AE5742E07D474169B9
-:104E20000D7E97CA5A88CED93BFCFE72F038D7E483
-:104E3000733E55F87A31F235D26F07E7EBE076E74B
-:104E40001594AC413EDA384C7CAB5CE6FB956D8C3E
-:104E5000E6CBDD1643F3F4056B7396025D7E0178B5
-:104E6000E03DD20B4E6744347C7FC1E58CC0F33DFE
-:104E70008A1CA86B0BA7EF3666CE8BC573A3CD48F3
-:104E8000F7D0DEF98EA9469CE77BDA38FF29FD7D55
-:104E9000D8B53816F96982AE5F6F87F2E4CE335128
-:104EA000A8F74D787D7E2CF2E17078FEFD1819CFC1
-:104EB00086C4121E9787BD70A26C4F007EEE27BA83
-:104EC000E89DFA871A18D16FF7ABFF56877C7CBE36
-:104ED00033C28CFBE6170723E8BDCA0B6F1AE83D07
-:104EE0009A5AF97DD52F747D7348BF7C5D4BF722AC
-:104EF000DD6FFE472BF2A3FB55039D3B7CA873C3DC
-:104F000045DCF76A3B679CC377566B5FFADBF2C3FD
-:104F1000CA8654D28B14F83FBC4627BEF37B5EE4AE
-:104F200072E2A18E7F217DF7A16B970BF07CCA17EF
-:104F300007FFC744946BEEB72E4F4479E6FEC5E5F4
-:104F40008958EE7E2DC2134A5FB95EC0FD3ECA7E0F
-:104F500099F6AEA8F20FAD90E9236D5D0BBD073D4C
-:104F6000E1E4027BE0BB0F13B2344EAC3FE1B76526
-:104F7000B1F7057CB7AE57A438E3F8936511D501B6
-:104F800074794F814EF12F7E23BF0E93DFC719F046
-:104F9000E3F4F2777F36F68AFC7DA31A81EEA183D3
-:104FA000FE32E45E1AADFF8A587ADF8889CE3BC7AD
-:104FB0008C47388BDE05623EE3D1CC003D6971AF92
-:104FC000A6CB007454D169E822FDBE573C43B0AC77
-:104FD0003FDD73F1D3C83421847F26E7D43494E3D2
-:104FE000C17E1AF84522DE8ABE55E971A520FEC1B0
-:104FF000FE9BA51577907F28D87F93D62B6A668F66
-:10500000C7F7DFE93A2F8CF76923F28BA287E2FA20
-:105010001D08C1FF6BC67039A6F0D5BA5E1EFF5DD4
-:10502000D75B6ACC84B456E6AB03B09DFAA0FD759D
-:105030009DF377A31F61DDB545116360BED6BD3B0F
-:105040008F3D81FC6F2E3566E177D7EE302ECC1F79
-:10505000A497E0FEA68CE1F272404F1866DFCB9772
-:10506000F1FA5BED7F3963E4F36CFF87EF7F6087D4
-:105070008F1DC3EDF025DC4FC2EDF0E07D4391C7FD
-:105080004ABB2E799D87CA63FE7748C05E2679ECBD
-:105090001A2351BDE4CEB9B16447BFBB2056320DCF
-:1050A0006D3F43B46B62F287B6AFE8716E9FE3A8C1
-:1050B00011ED1C8796FB491708F4BE99A2F7B99D1C
-:1050C00002E9E3EE4A9D1FEB2978F52EE07ED585B7
-:1050D0000E9D3F4C18D40F15FD71A0DC2E50B9A2C7
-:1050E0004F2A7A63AF93FB71178CE7E5B786B91641
-:1050F000E17C7DD81546F91326F17CC69C479300C8
-:105100005EF43D8111FFCBFAA442A7C1FAE6A5CE19
-:105110008C1BBED7B34DA64F85CF5283F843D9BF62
-:105120009AF339DDD7E1FE1D8BFBF77FAAF4F2E09D
-:105130007661FF7E08F16F461D12BE1FFF5BD1191D
-:10514000CA3EFF4AD60BFE5E59BFDE232588AF72EA
-:105150004E76B87DB54ED66F862B6FCEFF7AFCBCEF
-:10516000471EDFDF8A9F778EF9BF439F1DD00BF567
-:10517000A1C7794741C94FC6C0BC866B3D749E73B9
-:10518000B8F7CD1E95F555B07355747C3445AF41D5
-:10519000BBC85DC3FD03CDD1D2AFC97E39AEA5F783
-:1051A000571E92EF733E78D54C692DEAC9902ED9DF
-:1051B0007B92DED95D52A3C6BF197DB7F8FDAA3434
-:1051C0008AEB57B132F22B5575469BF1BC7F737C4D
-:1051D000FB31E42BDF6EADB43BB0FEC6D1727D2354
-:1051E000F7B7D544D3DF8F61417A40952758DF5711
-:1051F000EB0553643FD170FAC12FBAC3B85CE9D153
-:10520000129FD739F9DF55D07772B9E06E0823BF06
-:1052100009DA6B88D7670D821FDF3D5F29D7FB4C0A
-:10522000EC25FF13C5D3A0CAB9CEA72C0EB2DFD48C
-:10523000F1A395BB7E4B7233388E1473408E0B0DE9
-:10524000C48D26D2799095604FE29FBC724BD25D9F
-:1052500038FF801FF393DC71A8FC30977A3E22FB65
-:1052600073C9EB3CFE33247ED43C93C78FF0DD95AD
-:10527000107EC8A5238F1DC5BFA374B3B8515DC7E9
-:1052800049BA473244FF08D23BAE8D51FB19478AD9
-:10529000DC8F3BB25330A37F6AA43C8F7FB7319C35
-:1052A000F4EAE97FA88E4579A0ACD3F9B97C5ECF4A
-:1052B0007F70A504BF9BF807D11C06E3FAC507F56C
-:1052C000BF49E2B06494F0BBFA08B463CEFF6175E5
-:1052D00004CEEB2F20C5BF2FF1DA6931A43FD22BCA
-:1052E000CB2DD80FA30BC8BF2CFBA545D80F230788
-:1052F000FD39C1DF6D97BF6B063385FC98AFF3F8BE
-:105300007E73826B26C1CFA633FE1EA683FCCEFF22
-:1053100002748DFEA23C182CC69F7F1ACED661BCAB
-:10532000A839DEF536F1D1B31A09F908BEA73893CA
-:105330006FBF44FB234E19C6730AF4FC5D46EA0CAA
-:10534000D66BB4BC8E0960C7623C09B05980F1E6E7
-:105350003C39AE5310CE446CFF499D6B13BE97F998
-:1053600064B7685F4B4C608FC577BF83E34B828324
-:10537000C7C5953893121F1F2ECE24603F059CEEA3
-:10538000F8B91587807173259EC4BEE7A4205763C2
-:10539000B187CEF73F53C848AE7F8B719E25F92168
-:1053A000E24835C86324CFD571C54D39AF109DFE95
-:1053B000B5F1C43D63D8B71CFFE2F3138CF7F8E8EE
-:1053C0004B16B2B7BEFAEF51B4CF765EA6FDF042EF
-:1053D000BF41BE8FD0C7FDEC9D3AF22F5C00BB2DC4
-:1053E0003E609F3D9ACFDB3DD43995E8FF406F5931
-:1053F00004D63F2FE76F7C77C1FCD94897BD22BD0B
-:10540000078BE7E3D00E3BD02B4E40BDE55B5C97AE
-:10541000EF8F09B12EC6F0D0EF4CE4CB7C945FC087
-:10542000E963EA07DCFE72D7F3388A59960BEE720D
-:105430003DC9C163291641F19F5B43C5595EEFA782
-:105440007DA36A8540F71CBE719CA5A35BDEB78275
-:10545000FCD3E5D3496E0EE7B70E889BABCAB715F0
-:105460000C9C8723FF75548199C61DE3292CC1B379
-:1054700087CAF8BFC575B8736C083AFB16DB5F695D
-:10548000FF6EDB9F92F7DDB6BFE63B6E7F6DDE778A
-:105490001BE7DEF11DE37FF53B6EFFCC773C3FAFB2
-:1054A000E5FFFF73000370709C3FF85C4070BCDF49
-:1054B00070FC3E1F966D1036F777416A8C7AB542C4
-:1054C00000512D46EFA27708664DE271B08D65461A
-:1054D000FF0E61F07C80325F4B0BB91D61CEBFE8DF
-:1054E0008B85794E75F496C5A29F6C127F87FD82DD
-:1054F000FCCE2A13CDF4CE18D44CC0FBF1CD61A163
-:10550000E3AA61727BC3ED23CF1796DC31369EFE92
-:105510006C43C8FB1D2FC8FE47730723BF2413A588
-:105520008479D4AF9480FAD088233C3FAA8B397613
-:10553000105E52DA3CB207A534C46F8B1CEF8D9914
-:10554000999D86FEE818D00B311EF814C605298EE9
-:1055500065A67A4A7F1F8CE5FD6DD13181EE5BE552
-:10556000F2F34CACF9A02A9EF78EAEEBE36502C5D0
-:10557000F39623FEBFD274E5EF4C938918E637FF0C
-:105580008099E28C2726BD487F775689EFAD31F3AD
-:105590002A87D16E063CD61C1C47F4BBE4D0A4F786
-:1055A000F1E93377A6680F754F51F1179C96FD1DF1
-:1055B0008ABF40896BFD5EF6937C88FE17BA1F2276
-:1055C00051EA1DABF9B6F727EFD810FCBF45E0FE56
-:1055D00021DFAFB87F689CDE9E11786E72B33CAF5E
-:1055E000CBBA78DC42F1F7EC93C733EE116D97013B
-:1055F000F6D2714D63F4B8CF8F6B4A09C7B4C0E1DE
-:10560000D7E07DF0C5D5FB35CAFA85A2A3D6B1B2E5
-:105610001FA3A79FE27AFF1214E7FF602C3FBF3061
-:10562000AF90E3F101D82408AFC9121B517D1C7162
-:105630008B591B2A9E54057631E2B9AC99E3ADCC67
-:105640007755973415FB3973B4BF09D3A29AB4A91F
-:10565000E46FAFBDD884FA9BFBDAE563B793BF4C28
-:105660002FA13D714F9FDAEFB60AA3A5F18427FD64
-:105670009D5ADF0C91ECE3713344A29F98AA30B29B
-:105680005F63744C6B42782ED78B8ACAE3A622CC18
-:105690001644933E58D42345DF973FE8078B995132
-:1056A0001F8FF374B3F8AAE24FBB35CCF11AAEE703
-:1056B0005F1B5F5DF9CEBB74AE541997322F4A9CC5
-:1056C00074B8F8AA72CEC15D7E45752EC32DF64F13
-:1056D00047FFE3B88367F4F2394B33FE1D6125FEC3
-:1056E0003AEEF58B147755E2AC6ECF45D2ABE13B89
-:1056F0003D7E3F0E963F2106DF17E2F1D757F19E20
-:10570000941EEFFF99E9BED41BF2FDC54E183FE68B
-:10571000BFE9CDA1B4CB6BA7F490B7985277E7451A
-:105720008AD77E38561DEF53E27997B4CE3363D5CE
-:10573000E723090E8EF769C3B9BFC6DDA3A3BF97E0
-:10574000E17EC748F2BBA47319DDEBFAF2A46B2427
-:10575000E25D87F1B600BA38EFB087E13B61E79DC3
-:10576000F6308CB38DEB3EA7C7F32F7562AF1EFDED
-:10577000618071121E4D741FB8C8CFF77696D0DFC6
-:10578000E3BA695CACE36F1317FB9FE541012100AD
-:10579000800000001F8B08000000000000FFB5170C
-:1057A0005D4C5367F47CB7B7E596DF0B2A3F227256
-:1057B000C16298A2DCC240A7311674AC135C8A4A5D
-:1057C0000201B5662E92092DD9CCC2CBD23A8901FD
-:1057D000DDC3B2B864F3A92683E8B687FA93AD6E49
-:1057E000550B0B84252EE2C39C71C9520D3333BA7D
-:1057F0008162DCD85CD839DFBDB5BDD8BD2CDAA458
-:10580000393D3FDF39DFF9FF0A003007DAE756B9E3
-:1058100006E74CF8A5CFC6FF0F3DA44F8CE3DDBDD6
-:105820004BEB2617C4F1BB3EC9356903F85D9CCE2E
-:10583000942B00F687CE5A1C041FCFAC7621FCEDCA
-:10584000C2DFB54A3A80F7D24C2D20EEFD66A6960F
-:10585000F8DEAFD27A02E94FDB7BD78E975E047019
-:1058600096416B10F9552EC17182E0B8C3FA4645D6
-:105870005C6EC02538E9FC80AD349BE8C75CA5D9D7
-:105880007B13F4F539456700E939AFDAAC89F409DF
-:10589000BB19A006E90C5CC124F66B5581DBDF7FE8
-:1058A000D22A4F4A7A1CF1DB1DCC36E0DE50813C17
-:1058B000591EC7F7D38F02FC6E6622D40274E9B971
-:1058C000B86472D7AAA8AF3B3F6A8152A24C5B5C16
-:1058D000AB305EDF4BFDAC1260F8FCBEE268051732
-:1058E000952017A04D3F37E0DC5B9CB110C07F3D99
-:1058F00005CA98461391DF4A3F148E2A22DA69A717
-:105900005F78E5B6FCF7274CAB11BACDFE68C2BD97
-:10591000DA9D82C39AC9ED2E6DCE207931CE2F212A
-:10592000A5D34BB7AD22CC5128E413F417C25A02C9
-:10593000D2A8AD366EEF06047EB0A17C9B5388A43E
-:10594000A09DD6704A04506F955304DF8B087BCD21
-:105950008112467CF126E72B6F3611BF4FAE2A0429
-:10596000F4E3E7CB16794109BFDF6434218EAAF353
-:10597000D3FE523CAF763195DC6AEF34F2F19341BD
-:105980007EEED6E3B23334FC7221F75F36019ECB54
-:105990001D03388E7677F618CFED6E75DE61743F95
-:1059A000F8A07F33CA814D900789DE6B94A33A3B00
-:1059B0008DF11F007026D64337D5410D41C6E1E772
-:1059C000E813D54515062A58113F37BF7E4674F9AE
-:1059D000F9FA62F00CF117517D560DD828BF4D022F
-:1059E0009401E1F5922D419F5F15B99E0F6501FC71
-:1059F00028D717DE3EC8307E7D8F5F915A506E4AA1
-:105A0000AE97CAD2E3B8F732D6531640F5F06C031E
-:105A1000C5FB589881154D79F3F1BE28577DB16EBD
-:105A20009CAD4EBCA7E6DF31CCF9443AD5819A0D46
-:105A30009A5F2061BCFC17586010ED55353D1C493C
-:105A4000A3F8B9B2D53285ECD80EA523EE6D126B52
-:105A500018E12E3C40F80E1690F0E7F62B9D5B0007
-:105A6000ED54B7D8AF52DC5B3ACCAA1588DEDA40E9
-:105A7000F46B5950372912FFC47BA9C42F67AA556C
-:105A800021BEB39EF88D5F4444AAE7AD14A56578A6
-:105A9000B7CB288D7DB3C1EA0E501F5537A311F443
-:105AA0006F47873540FEB5849BCD90CEEB41A0BEBD
-:105AB0007B5BCFEDB7458F32A3489F095767915F56
-:105AC0000BCCD316156135EA2EC84178E1BE05B07E
-:105AD0001FBCE2B44546B9733E4CAC05E04B9FC4D5
-:105AE00061C827836339C0D7BE7C0EC33E85D32FE0
-:105AF000FACA398CF8540E477C6B35A8CA3C9E957F
-:105B0000E1FB02DD27A75970259B6F7EBD3E62F940
-:105B1000AA0BEF29A67B3EBAEA2E9693C8C7205A55
-:105B20002C14D66AFDC930675EE7C306B2E381E88C
-:105B3000613AA760BE610D46218430EFBFEB6FAACA
-:105B4000529B6FD902B893F167F4FA048722D03CD4
-:105B50007A4BD2FA7F78C55F3C9E5248B9B21EF3A9
-:105B6000E61937410AD28FD46B737FBE9EEB184F74
-:105B7000C0B8DDC078129CCF6FB5F8CB281FAD74CC
-:105B80008F24E7A7F4FAC40A30BB32B49C32BC4F6E
-:105B9000476C0E6020B2308F1D211649C53EDF19BB
-:105BA000DE744724D8C3E096717E3CD77DD8E646A4
-:105BB000A589F3B6338D26F9135C4AD5E22C593406
-:105BC000D86FD5F65A935D8B730C6EB56B75719467
-:105BD0009A05EBFBE879163888FDE7A918BB4E73E8
-:105BE0002CCF01D08BC3C7939F1E31D13C0F99EFAF
-:105BF0003D99E3D81F798A0C1D3994370C26F6415C
-:105C0000817E0724C06D9463911C616E25CA2D1995
-:105C10009F257D9FD8156E2F77579001BA5004FEAF
-:105C200083345F462D50771AED779D637090FA3B71
-:105C3000E00205F7FDE8F11B874F21DD738EC9B443
-:105C40008EBA8357F99EEF162778FF78C2772DBC5E
-:105C50001E8337357A88390249F23A40FB1DED6ED2
-:105C6000467F686E741F300552D06EC339ADAFBD2C
-:105C70000E4B40417CACE81D91F09DE719E4D11C2E
-:105C8000532616A511FF80190225DCAFA6BA84FDA4
-:105C9000845F85FC8EEDCFD8FEF1C0F45821D56B22
-:105CA0002753230ADF3FB78CFB052F921BDF2FED15
-:105CB000A16133CD1BDC4306B9DD8E863B343F71D9
-:105CC000CF18E94B0EDFE7F98028AF53DC2F067EB3
-:105CD0008D3D63E16D2C095809157338CF3655CACF
-:105CE0003CDFAD6EC6DC181F497075919F7091C97D
-:105CF000346FE7C7ABD1AEF541A39F412FE677C81C
-:105D0000A2D5C7D03A16F0A37C23A294F7A18B7B2F
-:105D1000FC0CFD1CAA62AA40F120218CC7163D3E56
-:105D20002F801F6E4BFCA9706CAE1AE035AC612B56
-:105D3000D653A35E0F00016EA7F9E3D408BD238EEE
-:105D40009A83F92A7F97F8F97D6755E0FCD414E827
-:105D500049D6AF6BEC75B36A0DC93DF3F7D32E7B13
-:105D600092F7D347F876223B7BED4C24BF30BE2B15
-:105D7000A9BFEF155DCB1C41F481C9B58FCE755914
-:105D800022ABA9BE1F98DC1C8FF191EEA1FD828B86
-:105D9000EF16F591008CCF8723E567CC949776A218
-:105DA000C7EE5B1297E3B8E969FCA10ACFDAEFA16D
-:105DB000CA9AA7FD7E86FA17ABCF577F6EB2BC1D7D
-:105DC000A2F997A47E7ED2E71FC01299F7CB933831
-:105DD00083B68764E0753CAAEFF57EA6FC487BC8D5
-:105DE000FF9D190695F85CEDCFD0F47FA6EB8BC133
-:105DF000511DF69B35B9F9F627F439FC8BC9718A28
-:105E0000EEBDF2A4004A82DFAB82A9A024F85D199E
-:105E1000CA31E0F6C862837CF578A9815F33B1C2EC
-:105E2000C05F73BDCA80BF145D67905FFF6BBD012B
-:105E3000DF30BDC520BFF1CF6D063CD6BF7558B968
-:105E400089E73649AF1BE40A3B8D7E15F518FD2A1C
-:105E5000EE35FA15D35BE237FAB7ACDFE85F4EF602
-:105E6000835C85DEA1FFFC9149FB60203CC3F334D9
-:105E7000359D02133447C4A8B61FC266BE17A6F0EC
-:105E8000FFE2A2843C2CA7D73FDA19092FB3D2B97D
-:105E90000F9D362BBDDB2E510D603EFE05D7762EB5
-:105EA00017E00E00000000000000000000000000ED
-:105EB0001F8B08000000000000FFE3E36660F8515C
-:105EC0000FC1D3B81818367221F84301B7334368AD
-:105ED0003E16060601207EC7C8C0F09E91043338E6
-:105EE00010EC7E20BB0A88277150CF7D43112FE52F
-:105EF000A19F5D5FA0763D1518787F83B083100366
-:105F0000839B300383B40884BF5F0455DE5108C10E
-:105F10007E2E41995D9F81FA018DEBBB318003009C
-:105F200000000000000000001F8B080000000000BF
-:105F300000FFE57D0B7C54D5B5F73E731E33939976
-:105F40004C260F4242004F08202A842140088838FE
-:105F50000990068D9A080888CA000142483211A9A2
-:105F6000975E6D672214D16A1B2D6DA397DA0141EC
-:105F7000A3450D18E840031D4C41BC5A8D0A4A5BED
-:105F8000B541313C0A4978E8C5D65BEF5E6BEF332B
-:105F900099736642A2B6DFFDBEDF177FFE36FBECCB
-:105FA00073F65E7BADFF5A7BEDB51F2359C613D345
-:105FB00015847C057FD71372482484F4EB4E3B0B89
-:105FC000683A8E107F8E39B0552024B4EFEFED245F
-:105FD0008590B34DB355732621FBC79843D7D3F2B1
-:105FE000B381FC8099964FDD79C421D17CD54E5187
-:105FF0008272D33E2B7EDFB1510840DE6B6EFDF125
-:10600000B534DFB553249B69D5246437915442DA03
-:106010002D84FDA9F1985F6A65D9AA4DFBEF82F640
-:10602000CA836662A5DFB737896EC8AFDC2A040869
-:106030006DAF6AF783CA005ADFB280D06855697EB7
-:10604000EB638A1A4FC803FBFEEC68B31372DA677E
-:1060500021AA82FD286F1C494845607BE100FA7D3A
-:10606000C536C165A2F5576C3CD701F45534C9C398
-:10607000445ADF8A061B5147B0B6BF22D05ECB0719
-:10608000D8DE4E7928B457FEE53D0A11A19FB21B18
-:10609000BEABA27440BFB5764FFBEAB13D8D9F55B4
-:1060A000CFD1F6E87BD52F0A2EE862B58978808EAD
-:1060B0008EDDD6B94FDBA17FB5CAF0F8C87E2CDCE7
-:1060C00005FDA8086C520AED40DF2665E9C8EEFA26
-:1060D0005634FC879EBEFAACFE9E8872637ADA471D
-:1060E000593ABC3B5F4188BB91D64BA480523AAA37
-:1060F000FBF907422221E3A17E91A896EEFAA9E4DA
-:106100001107FE23F49F940FFEBDF181AD99DD725E
-:106110005BE9049975CBEDBC93CB51EACA8DAC5FBA
-:106120004B7F0CF2A0F4D4F99C983EEE4BC37483E1
-:106130004F45BEFDDC3702D37A9F0B9F3FE9CBC3AF
-:1061400074A3CF8DE953BE224C03BE127C6FB36F94
-:106150002EA65B7C1E7CFE8CAF1CD3065F0D3E7FA3
-:10616000DEB71AD36D3E3F3E7FD1B71ED3465F1DCB
-:10617000A63B405E346DF205F0BD5DBE064C83BEAD
-:10618000467CBEC717C4F411CE47C764922F513E58
-:1061900038DCC449C54E928ADDF932CD2795B07CF2
-:1061A000EA1DFE7C85E6533D344FF932A032946FF0
-:1061B000A6F90135AC7CF0FDA4C042F383FDAC7CB4
-:1061C000C823EE022BCD0FA963E5C337FA0BE268B3
-:1061D0007E7880955FBD2D5460A3F9AB1B5979760D
-:1061E00033996AA7F9EC10CBE7BCE19E1A4FF3395B
-:1061F000AD2C9FFB817FAA83E673DBD8F793CE0497
-:1062000044D51E2D871DB2BA9850596DF4CF704BEE
-:1062100013695E51EF212ECA1FFFAD6E299DF24317
-:10622000766379C83F1FCB9B143796BFE32FC3FC1F
-:106230002ED983E5C7FD552CAF78B0FC73FFBD9810
-:106240000FCA7E2CB7D4FA585EF163F980DAF5589C
-:10625000FF1E3980E5236B1FC3F23D4A00CB1F5F51
-:10626000FBA47B1ACDAF113C3F073CD2B49C640128
-:106270009E1AD34A289ED609642EE0F707003A8A70
-:10628000CB75E90AEAE18E3FE43E0DFA8B7F299057
-:106290005FFACCC399F8FDAFB01E99D623F65E4FD6
-:1062A000CE9B79BA7A72DE2CD7EA6980F7D658FB92
-:1062B00056CF8E3727E9E979B342AB673BD213DF7C
-:1062C000B77EE5BC35594FCF5B955A3D7B909EC458
-:1062D000BED1D37444CF9FA62361FEB4203DFDFA06
-:1062E00046CFB8F7F4FC19F75E983F6F603DE97D43
-:1062F000ABA7E93D3D7F9ADE0BF3E708F66B50DF75
-:10630000FA35EE7D3D7FC6BD1FE6CF47484F66DFBD
-:10631000EAD9F5A19E3FBB3E0CF3E704D633AC6F40
-:10632000FDCAFD48CF9FDC8FC2FCE9C27AAEEA5BB2
-:106330003DBB3ED2F367D74761FE7C81F58CEA5BBB
-:10634000BF72FFA2E74FEE5FC2FC310950CF98BE8B
-:10635000D113FC54CF9FE0A761FED8B09EF17DA37E
-:1063600027AF5DCF9FBCF6307F520490FBC4BED5F3
-:10637000136CD7F327D81EE6CF20ACE7BABEF52BB7
-:10638000EF849E3F7927C2FC198EFDCAA77A0FF4CD
-:10639000105A4F7CCFF5EC39ABE7CF9EB361FE8C42
-:1063A000C67AA6D37AB27AAF6752879E3F933AC233
-:1063B000FCC9C37A66F4AD9E3D1D7AFEECE908F394
-:1063C000271FF97353DFFA35A953CF9F499D8C3F9F
-:1063D000630FD74C75D0723A16BA44FAC9B567DC68
-:1063E0006E81E64527CB8B4E1701BF44D4FC0DD2FE
-:1063F000EA16E9F7F66D89390F9348BFA3A014FA9E
-:10640000154FBDB148BF23212F4EE7E724BA93743F
-:10641000F9E4A201BAF7FB950CD195F79F7BB5AED5
-:106420003CDD93A3CB67944FD2BD3FA8A64097BF56
-:1064300062F50DBAF733FDB7EAF259EB6FD7BD3FFE
-:10644000AC6E91AEFCCAFA0A5DF9558195BAFC357D
-:106450000DFFAE7B7F54E303BAF2D1C18775E563CC
-:10646000428FEBF2630F3DA97B7F7CEB665DF98485
-:10647000A3CFEBCA27B6EDD0E5AF3DB9C7E0E7D96A
-:106480009DEDD7F0BC08B827CCEF4F57D0DF0BC538
-:106490002B985706D8D18FDF1FBF543D4EE5ABBCBC
-:1064A000B2584DA1F20599123AAEE70F28BFB28D4E
-:1064B0003EBF7792E74A277D7EAFE219ED8CE19FE0
-:1064C000523C08240D52D504A9B1FC4199E1B120F8
-:1064D000E3CBE1C7E8F75E53D7F0449AEF2FE6D756
-:1064E000035E9E124C88D33891D4C07B716682F3D0
-:1064F000820733739FF647E075FD20AA874277BD78
-:10650000EB654F1AF8199B6BDFF6831FB26E10ED27
-:10651000D700429E16DE0EF987D2EF072D4DF3D03D
-:10652000FACC0AF5D323DB5768FB23B1FD0668FFDD
-:10653000C51EDA370FC9D3B56F195CAE6BDFA2D0B9
-:10654000F69DD41FA8FD236F9F0A6112212F0B7F98
-:10655000C4F6CD83CBB1FD07153A5F896C3F2EDCC5
-:106560007E10F4771FB43F3E46FF874CD2F77F7012
-:1065700085BEFF0AEBFF2BB5C778FB71D8FF16E18C
-:1065800018EBFFE00AD67F33AB37DCBE23CCFF43EA
-:10659000D0FF377BEA7FD6647DFFAFA8D4F7DFCC8E
-:1065A000DA7FA7F6146FDF8EEDBF2B9C62FDBFA2D2
-:1065B00012DB57CC1E17E047C988AB09D0F6C9409B
-:1065C0006A98FA035C683B908E48A2A026E4516169
-:1065D00008D2716F1CC3DBE771146F686FFCF89C05
-:1065E00004A865CBA5F32E8EF515DBF215B04B583C
-:1065F0004EE72B4B38A9654111F14D369803C3285E
-:10660000BD1D41D10FF9B20DD705C0FE79CD644152
-:10661000097C2791103CFFF467A33647F6CB982EF0
-:10662000A993DBDB22F42D3C8F2A20236A287DD31B
-:106630000104E3BBF31FD37910A1F38B0FE83C8374
-:1066400050487E22B3F63EA2F325C8B7D1F9129482
-:1066500013528BDFD1EA0EA751FA4B38FD1F4B4C7A
-:106660005F3FBE4308F8A97E7EFEBD31384F5DB066
-:10667000DA4699DE4DC7427FB22E4FFBE5073975EA
-:10668000ED3607360BC85F15F8558AAA49C8E2F5FA
-:106690001994D7DDEFBF4FC59E4E597F1B71CBFDBF
-:1066A000E9FB77AE12063969BBB3DDE61C364EB89E
-:1066B000334CA8D724C39447C8AD4D63645A03290B
-:1066C00075CB1FB745B43BB3489F9F5DA2CF77C83A
-:1066D0006ED944E9EA2815C8265AEF9CB9FA72AD7A
-:1066E0001DBB2989C999B75792CAE89B03690E3C1B
-:1066F00076A29CE73AD9B71A3DDEC5329DC2823CEC
-:10670000FDFD08C8D59F82EFDDEE64FD36D23B5714
-:10671000B6B84B683FE72E1403806F23FD7FDA671E
-:10672000739BB269BAFEA7323145F7C748FF3C8F69
-:10673000B13F8D328CC3F3CB8DCF196EDAB9FC3FEC
-:10674000067CD0F404E083D27F9CE3A3DBAE327CF2
-:1067500078CD9E9B010F5D4F8804E5CAF1721BC77F
-:10676000CB923A3D2E08F1C820C76573859C8723DC
-:10677000703087E36059BD1E377712BF9C1E432ED1
-:10678000F3366CFA619A1ADDBF0F396EE63FB21F1D
-:10679000F913DD4F26A7BBB89CEEACD197DFC6E559
-:1067A0007A2797EBDCFAC70E50F3416E570332E8B5
-:1067B000BBF73E4D9E6D3A797AB83C8D74DEC5E5E7
-:1067C00079D7F7983C8DF4B67179B6D55F90C990BA
-:1067D000687A8DF42D581DD51F05E4B9D01F5B9E36
-:1067E000DE607EF2F188E7558D33928F47E8D98AD3
-:1067F00086525D7E79609EEEFD65F50B75E54BEA90
-:1068000096EBCA17AFBF5B975FE8FF9EEEFD05AB47
-:106810006B75E577D63CA42B9F5FFE982E3FCFF398
-:1068200084EEFD397337E9CA67973CA72B9F59B4AB
-:106830005D972F75EFD6BD6FDA77D52D80CF378E68
-:106840008804FC89CF5C27302EF8994B76C13BC772
-:106850007D2AE2BADD3702D3933E17E2FEB42F0F52
-:10686000D38E608B1DC6093A2E2E2589D4CC9B6E03
-:10687000AE5D3F10C66982E3E916D3AC5AFF6442AD
-:106880007E6D5291DFC5F50A098D254480C186D3FE
-:10689000D1254694B7F5525E4F0D7F727479715BC6
-:1068A000ECE7DEC7175EE18C1177E9D65392017EE3
-:1068B0004F27F7BB8DE5950229897C4EC803A8D7E1
-:1068C000E7F8B85BA930FDAFDC915E401C900F0D7E
-:1068D000AFB95C7B8D14E4FD0127593A3D5E567FCC
-:1068E0008DCEBE1388CAF603BC8DD53D5FD170AD89
-:1068F000EEBB33FB45A4BB1A6CC54418164B5E3780
-:10690000811D0EB50C9E390AE874BF6182712AD8C8
-:106910000FFDC233BEA2E4E312C8AF04D393BEB9E5
-:1069200098B6FB3C981EF79563FAB1AF06D336DFF5
-:106930006A4C3FF2F931FDC0B71ED33FF9EA303D52
-:10694000EAABC7F43D5F00D3C3BE064CDFF135624E
-:10695000DAEA0B62DAE17363AAE95D6FB83BC9C793
-:10696000E1D380BF1838EB786055EDFAC9DD383BCC
-:106970006FBAAFD63FB09BCFC5F5668E87541D1E4C
-:10698000BE806033E2AC97F27A99E3B0A7EF6397E9
-:106990007B37FF6BF036DEC4FCCC6F8AB76E3C658C
-:1069A00018F094D51B9EFA89E3BBF134DEE4647ED3
-:1069B0000FC7D38FA01F31E61505E084F48BF0D705
-:1069C000DC3616A7E6EB09D45365716ADEF61AFACF
-:1069D0006E2BFA758111306E9C1FF1B7E110873F65
-:1069E0007FD44C277D3DF7CF88939EF9EEC6F9CD35
-:1069F000D2001DBCC646975BE3185FAD265244E843
-:106A0000B8F6D0B0675C8B46625E2249F07DC05517
-:106A10001A1FA35EEA2B037F7BE3EB9AF8CFB3A1A7
-:106A2000BEF627FF9E0BE97813F397E35A44F4DB95
-:106A300049E86917F0373C2E995D6910DFEE1AA618
-:106A400038D16F08D8F5FCF3D37C6E37FF1EA23C1B
-:106A50006AC571B72E0DF937F4F3E1E97DE05F6F98
-:106A6000F6BD377E2E0A0CF897F0B337FBD89B5D46
-:106A7000246EF5C520ED7FE7BE51390FAB60078767
-:106A8000B0795A0FFCD6D6A58CF47CFF6BE2B833F4
-:106A900055C371EB6042DBF988EBCBF9A62B1340B1
-:106AA0002EB41E9C1F74EDE47E7E2F723D9BA9AF19
-:106AB000CF6BAC2F4121C268DA6EBCA29004426A4F
-:106AC00044CFA322CE6F5C6D7E881BECB3B9D6A8F1
-:106AD000306F3CFD6648851AF5F185F3879E76C0D8
-:106AE0003C6C659AC9793C861CB5B4AA31D3698FD0
-:106AF0009CAF04F5F9F375425123CEE7D48459A332
-:106B0000609C713A8F0F05BB9F86A956CFCA34C5CA
-:106B1000799CDADDD30D59096CFE1760F6645B22AF
-:106B2000DA9BD33E0BBEFFCFA6A7A77A347A0869BB
-:106B3000229F58C09ED3B2AC9EDFEF511FA48B0A98
-:106B4000C43749B3FC39CC37ADF4FFAF8640BD1232
-:106B5000E6B57ABD8DA2DF3C1A9E6FD3B547BF5311
-:106B6000B5B557F8AE67BD9348BB867B2ABF57F9CA
-:106B7000FAF08A06AB53EFC726EAF2DE60BA53E7B3
-:106B8000D7C23FC071AF1124C05F25875FA7645F84
-:106B90000F78DA0CC14398BF08ECBD2A4B9BE25139
-:106BA000515D5A019F8BF234FCAB73FE4CEDD4A9BE
-:106BB000D765027A46BEA454E5F2A920E2CD444C42
-:106BC00034BF98BFBDA86945318C5BA74C6CFE50A3
-:106BD000464A1C303F2E2775B9104F3D4B4C45A0FF
-:106BE0009F67C93B8EB111FA784E54B0D2C5EBF510
-:106BF0007E3C9DDFEBF2CBEAF5F9A5E4D6545807CD
-:106C00005FBA41260101EC86BEFC98E8C47A9791F0
-:106C10009A75306EFF9CC7BB1639899441E9ABFA6F
-:106C2000CD2F7317523A2E896CFCD5D67197273128
-:106C3000FA2B660514377DFF93A6B1B7510B44BFFD
-:106C40000FAC83756D7F29716D25D1F2FBBAF41BF2
-:106C5000E9D5FC81A8F5644E474A83E00EC4B063D1
-:106C60008A24303DE3F6EE6AC9A98B83E4423E22D2
-:106C70000EF28DF194427478DA2C7A064BE3197E89
-:106C8000000F82D4A578BE4DFD6951F55F2DF5FB4F
-:106C900027D63F90D69FABAB3FF79F4AFFD028FA4D
-:106CA0000B62D55FF59B1776F9A93DA978E9670EC8
-:106CB00042C7C953525DAA8BCAB572EB0F1D6E9ABB
-:106CC0009E94FC0EC0EBA98058144BDEABC3F27649
-:106CD000DB0588BBC13F69FDA79FFF11C6233EDFCF
-:106CE0002A3B319ED6600E99A93E56372D2F26D9C4
-:106CF000983FC6F20F9E13211FD4E3AFE2D99FA5A0
-:106D0000C2FE0A8A141E5F0AA13F5BBDE5D3421C86
-:106D10009F4817EA91F13B68FF5212DABF854A4259
-:106D20007439A513E3045ECE176FD38FCE890EF8A6
-:106D3000571BCEDF8DEF9773FF74B9149FD26EA3EC
-:106D4000FF9E4026803DD4F84102CC3F5DF3DC2F0E
-:106D5000B28F517ACE6C79DD2144F049D3A3F38D03
-:106D60008B7FB547EDD9DE76503D8BF483B4F14A85
-:106D70000D72BFBA99A59572C8712DD5FBCA4DB2D7
-:106D8000CB4F1F57BEF0F4334F421CF38F66D73002
-:106D90005AFF8A170EBC3789E6576C97538A5937C2
-:106DA000EC426AB75CBCF4FFD539DD72A878F98093
-:106DB000A28E62CFEF4FEA96C78AEDFB15322A9A70
-:106DC0001F531BF72B6DF61872693C56087EC29A4A
-:106DD000E7FE4B81F8E2A97D02E99F19839F9B0E94
-:106DE000A01F007C4239723985E56678DF4BE502E9
-:106DF000F65A9393B1FC466E4FA03E7524E2F9C556
-:106E00003DB4FDF23F995DD0FFF217EF71403F4E68
-:106E100048350CD7BFFC612AD8AF72D99FEAC49419
-:106E20003D2F7FEABB88B7656F7F3715E349C49D67
-:106E30006EC2B1C79F0EFD5BB27136F66F29F120AD
-:106E4000EECA7F29960468FA99448AB6C7D08B0E99
-:106E5000AE17273653478CF6EF04CC1FC15EBF2315
-:106E6000E2BE2A42EE26A0FFDFE57DA11E02E63F3C
-:106E7000B330391D904C5CAFA8B71989D72D0FB628
-:106E8000827C4E0F72F78775162F91FC9C1FC2579C
-:106E9000B45EF1EDE9FD997C882AE5F2EFE8383F30
-:106EA000159EC3FBADB2DB9AADFB8E7C95D9DDFEA2
-:106EB0002ADE3EA53B0EC6E713A9B1FDD501B2A659
-:106EC000F7749C8EC057847E337DDFF210D36F4DF4
-:106ED000DF03A545507EF130D31FF80EC63F4A5759
-:106EE000A83F96EF9F25A03DA0F3E6587ABD45E662
-:106EF0007AAD2FD77042E996848408BC40FD49C81A
-:106F00007F5C5F59BA817E17612FBDD09E23BA3E48
-:106F10004D6F9771FD3F05FA7F4DB7FE938D4CEF96
-:106F20007BF69FFC2C6E23079E7912F495EAA75FEF
-:106F3000057D954BA0DF7FDDD6F2DEED544FFFDA05
-:106F4000A8E9A9DE7E1AF5B47CC778124B4FFF6A18
-:106F50007791987A4A9FC7D4537B1BE2F8FF94FD40
-:106F6000D4F89728EBF9A7D9C39EF868B4872F4ABD
-:106F70002AF2D3680FE9DF61921B8D3F0D771ADE8D
-:106F80002A7E5D7505D89D302E35DC8571A9E12EF0
-:106F90002A7EABE39FB1FCCF106BA274CDB7D44F68
-:106FA000817984A58BE0BC2B7F9688EBA6968B0419
-:106FB000F5BE80C8B86FF07D53CD78F043A7FCFDD7
-:106FC000B6B3F7527AE713BFCCD6E5EB64F4EBBF68
-:106FD000FCEAABC9B43FB773FECEA7ECBE89CA6367
-:106FE000AE2484E2289DF324E24F4882F8AC403E70
-:106FF0008EA0637EB93E0F7F5352BBEBE9EDFDAF30
-:107000003B0FF9A6E9DB3EB676F52EA443B179290C
-:10701000124FA52057CA3FEF38213004ED529B5440
-:107020001231AF7A9CDB9DB7A7CD1C0FFE4BFE9CA7
-:1070300051090CE783717EEBE5F6EBBC5F4D00BBBD
-:107040007EBE390BE7AFE70F2D8E8FB56FB285E3AC
-:10705000EC005F57E9B40B7522C57D27E942FFC5F7
-:107060006FB792AD31D6FDBE2F9BF8E483CB8DFE7A
-:1070700089546E73390EE7D14F137222E436EBA6B2
-:107080005392235A0EF0F771C43CEBDBF217700DEC
-:10709000FC6DB1B61596C488D7FD84F36FCA2B5F1B
-:1070A000E0FED569CDF912F0719A5DD4C5391ED4D0
-:1070B000F475241909744D7965F9A3E3298EBD8708
-:1070C0004417EC57F5369F533C31E6BB467E42FDF4
-:1070D000E0471E909DC8AF2372C912E0EB91D956CC
-:1070E00002EB96EF2AAEAA58744E37B378C83C52DA
-:1070F000F2D938E1FF3EFEE6CF890F15507E9CB7EE
-:10710000B3FDC0D1F8637A7FDE29046A05C0A1C847
-:10711000F2294200E26485C4F3E86401F5FDFA480F
-:10712000FB951F2C7D01F6D554370B4E132DAF96D2
-:10713000DA14C0B137B85D02FFFC4695B831DE20E5
-:10714000D58C9A1511D73A204BC8AF96BFDD7E2754
-:10715000F0F7C22C3301BADC23CF3960DCBFD03C5E
-:1071600016F5A0A77EFDC147A64C93A01E82F8305D
-:10717000E2A130C5A6CBCF9E4A06BAA8DCA698DB12
-:10718000EE71C590DF3285E1ACCFF6CDF2FF997D8F
-:107190009B4CED1BC3B51C69DF462B51F6AD7F2C14
-:1071A000FBB6B256ED0FB858B937AB3FC875E56BB3
-:1071B0004BFAC5B26FAFFAD8FCFD35BE0FBB7320DA
-:1071C000B56FA323ECDB406ADF62C46DD315CDFF3E
-:1071D000ECC5BE59FE77F4EF55B06F31FA3B52D192
-:1071E000DBB7A2E65AB46F450345DD7EA82C85CFF8
-:1071F000E77AB46F0B7F361BF3B2CB16033FC05751
-:10720000B06FAF713B07ED809D5BA438B1FDBEDA76
-:10721000B9D2BEDAB9FF253E6B766EE520769E23A5
-:107220001A87CCCEADCC64766EE55E66E7560E630B
-:1072300076CE68DF0AA2EC1BFBBE7A04FD1EE78B4C
-:1072400099BFB8839617CF955D16FA7EB1AA9D5F58
-:10725000A8191F69EF162912F239CADEB9CEE13931
-:1072600090DEECDD5B60EF86A21D1B0A7A64C4C76A
-:107270000D436DBAFD7247BE68FFF54BA02F7F101E
-:10728000719EFDBE89CD8BF67DD13E16F46E37A77B
-:10729000E75185C9B3C3E7477B3A7524D3F7AA43BF
-:1072A00071384E543709ACBFF70B0115C681BF5D6D
-:1072B000C2F9F29D7BD97C798E99F183FC9BC8CE73
-:1072C0005D50162C8CC0C3DC4B1518D79C2B110BB2
-:1072D000F8AF0B0EDD700AFCD60597D6A3BFBB0036
-:1072E0009EC3BE89ED6DEB3268BB772E1770DEA1B1
-:1072F000EDEF9817B6977A3F767E73EC7D1A533888
-:107300003D53EE1302B02FA7B77D102F72FD9B23C4
-:10731000B621BFC85B62CCF8A4F65E984F2EC69724
-:10732000AA55CC6F0EF389F24D15A2F944255DBC28
-:1073300030B59B2F77EEA4FD4DE9B9BF1ADFA2F758
-:10734000E1B8713EB380BFD7131F343E47F59FF3BA
-:107350009DFAA9B89FC7C88F46CDCE5C4346815ED3
-:10736000BE6FF23C3A1E70F49F942F94CEDBE60D74
-:10737000D39DE7D9C5F97293E7D8B45415F8486A94
-:107380000067B7976F3F904AFB778B3B330742E626
-:10739000B3FFA67820FED062ED423BA8E130CDCC11
-:1073A00070F8578EC323039CD370BC090A4ED4AF28
-:1073B00090C1CEF17D645ECA67D05F6F908F4F142D
-:1073C0009FA09F85DA780572A1FFBCA999C9C55B0A
-:1073D00023A05C6E265D0781EFD529822B44AB2A62
-:1073E0000C6EFF21ECB77AD54A9F839E970BAECDEA
-:1073F0008C1DF6F4D498389662E1183709468C9BB8
-:107400000BE0BD24D8B768C6F6EFFC1EB347463F75
-:10741000658AB9F508D033E5DF64B2091E06E87F56
-:10742000113830FA31517AF035F7FDA472FBFD2A9C
-:10743000C8C10EFCEE52C01FF286D8F8A3957B257A
-:10744000751AF24D9343908E2FE3981C60A9DFC804
-:10745000E75BB43CE01FDE6F1664F87E06954F32A2
-:107460002D9A6AFAE2A08677B31ACD2F8827A4470F
-:10747000D80DB06F91EB96D5C1B7914F37ACA2EE56
-:10748000991ACD274D3E60072FC7AF28FD09EE8F13
-:10749000B97FEA9BEA4F9A59AF3FFBAC5DAF8F864D
-:1074A00038DA5E01ED0A694ED4C50FF2CC6C5ED6B7
-:1074B00062F520CEBB5E935D9BD568FB7315970B81
-:1074C000CC5722CFEF4D850EC1BAB1D34A3ED1FA87
-:1074D0003D84E12C723C78D5EA41F9F554FF045E15
-:1074E0007F4FFE9896FF0EB407FB16557D7BC6F1C5
-:1074F000488B27F5D6AF6966663FBE69BFB476BED6
-:10750000EEBA8397B462FC4D5B7FD82C7A7E2EC393
-:10751000FCB848D0AD7350CA71FDF29F50FF58E5DA
-:1075200032F543FC2844F9FCEAB6A7315E7DF6F952
-:10753000633783FEACF8AD482C549F3AB6C5931020
-:10754000DB07A2809F50D124E27A169142B93323FF
-:10755000FC0C42D6307EBC148F76A7628739504C23
-:10756000BFAFD8F54936C4DD3A1E60F6CFFF3CC741
-:10757000A3BF2D1BD6FB2B24B68E6F94CFBD1C9FB3
-:107580006776DBE682FD161AD879D78AC639B23912
-:1075900022CE506596595C7BB70DF759FB9F13704F
-:1075A0009F32D01779CE52DBFF79E63966972B826E
-:1075B0007200CECD56346CEF803878C55133FAAFB7
-:1075C000DE86730AF8A7535F7A01FD236F50D4C596
-:1075D00041A3E28F0D62C80CF1B3A62AB403347F35
-:1075E0000CF38DB1E3F0BDC5C956BCB477979FB21B
-:1075F00070C5CBCF3AF0DC6CEB5607C6211B2E1FB3
-:10760000FF8F8A37363E74D978E3698E8F5F99F59C
-:10761000EB35A42119E39094BEDC9218718B30EE07
-:107620005FF8EC29580F3BB3E3AF4F01BD95FFB8AE
-:10763000F0D47DE08FEDB33A61BCF63E7F04D71302
-:10764000B4EF76733DEF78EE595C87E9F8A3D9057E
-:10765000B575EC3D3118D6233AB67F910A71DB55EA
-:107660007BA7E33C6DD5CEA9FD498C798096026E4F
-:10767000037D580732CAABA5A96530D07996CA1BDD
-:107680005CB670FCB8B18AC5E3551E37DE167BBD0B
-:107690002D2A4EDC34F396EB60FC6E925D2AE943B2
-:1076A000BCF83095E3E83EC86FDB439ABD8F29BF35
-:1076B000B3F00F2AA7F70DF2FBAC69C9AF9E84B2F5
-:1076C000A6E41EE3C5A13EF04D5BCFDB62767F6C86
-:1076D00006BDD9F16B8CCF83DCE85C8374BCF0D938
-:1076E0006088B39C94BBEEC2FD337BCDB82FAA62F9
-:1076F000EFFBA83F1D3BDFC6F532C2D7D53A48F8AD
-:107700008FAD83F0399C774B3C8B3373FE431C5A0F
-:1077100075E0731E6F6638D6E2D03DC59FD32D6CE1
-:107720003F91B6CE58B5E5CF0A31C4F5853C90D32C
-:10773000B1CBAE8B6A7C70021F2644AEA7C48EF319
-:1077400087D7DDB8BC407EE07F85D74B687E20C4FC
-:10775000CF03C2FB24863DE8D8C4D6613AE4D8FB07
-:107760000FB5F595148B414F037D5B57E98DFEAF47
-:10777000CB1F19269BE3A3F974E6CBD8767C824510
-:10778000F876FB612A85A8F57F0BACCF371D5360D7
-:10779000FEA18D635A7FCFF079F299E7453CEFB1B6
-:1077A000AEB105EDB8D15E5413161F34D23B83D36E
-:1077B0005B1D64E3C4991DF1013BADE7CC2BBB110C
-:1077C000CFD5DB8E297E5ADFC1869795B688FD52CC
-:1077D000304E0422E83FF3E2FE6CB67EC4E6E5C616
-:1077E00076E6F076BCCDB1DBF16E3BA76B6785BF6B
-:1077F0005161E7772EDFDE69C93D07EA3BDD2A13D9
-:10780000D8BF7FBA512C0AC4687F9245D6E2F24CA9
-:107810006FE87889E71DE3D9F946314941FF7A5588
-:107820007CDED18414481515E2146B6AD9FED2357A
-:10783000DF77A581BCD724DE86EB6D7506FE3A5353
-:107840009CF910BF704E2B19077035DA9B44B7496D
-:1078500047FFAAF8A2FE701E7F2DF7C788E4C2F387
-:1078600097A2A3B008FA233A4D4E6B8CF505D95E6A
-:10787000423C117C919DFAF392E4CBB12AD4A3ED62
-:10788000A3A9B4B41EC442A71BB70A4B79ECDDFC14
-:10789000594EEC77E7363E4F7013D599CAF683C13F
-:1078A000B8D1B923219B8CC60F899BE2D1C69F0B0F
-:1078B000DBF6EF077BB4D641DC8954CF285755312E
-:1078C0000BCE8D8EB1085980D3736FFE96D66B6D3B
-:1078D0001671FED069D7F685BA1341CF6CE411DC7E
-:1078E000FF0750FE2AB99B4EE3BE4002AFA476DFED
-:1078F0002B315DB4E3BCE7FC46160710C9D5BF9831
-:10790000CCE2702400F4F3F16405A7F33CA4F07E0C
-:107910009982E73A96BDF6726E88303944F22BB9F7
-:10792000487FBEB4DEEAC8867579E277B7C2399976
-:10793000325E5FBF12FDB953AA7E7ED0D3255C4F65
-:10794000FFBAB4F010D8BF32CF52B4EBFDE7EACFA4
-:10795000A51AF75921BDB02F8CEADD9342F4BEABD6
-:10796000F2E6C7D6C17C397AFF151901FBC92A484E
-:107970009C0BCEE7AC68D097EF03BB7915B093D8DA
-:107980002F17EFEB95BF6DC37F3179DC65F9EB0AFB
-:10799000C1FBDBE231AEB2ECB5C5689FCC697AFEC3
-:1079A0005A553D7F6D238C7CD4F339DEA5E79B3699
-:1079B000FFEC89CF0979FAF3BE463E4B84C71B0220
-:1079C0002C0E11B5BF2DB809E936F2D9C8D7760B00
-:1079D0005FF7E27CA57F25965466B281EE74298418
-:1079E0007A61D4A30C7B48807F0F4A09D4E257AE5A
-:1079F00078B4EF69BC3F4219FBCE067A2402BD2E53
-:107A0000D42338D10776DE463E70B65B41589F904E
-:107A1000AFAEE9599EF794FEFED822FAD546C0EFE4
-:107A200068D42B766E378904D664829EBA9C306EF9
-:107A300037FA2C6A9904F79F10B56C28DC7BE2C4F6
-:107A4000F4C77C1F4AE74882FB821B431753C13EA1
-:107A5000FD38A7EB66B07BDE25A404ECE0CD716CAD
-:107A60009EB298A77FB72ADCAE4E7BED7AF8BE595E
-:107A700056E15C7867F356CB30C80745BC7FC49BA2
-:107A8000587715B4DFD12C33BACA2C816110BFD816
-:107A90002B63BB1D6593F17C65D86F6B66FB403A29
-:107AA0009B3F712C8EB0E71DC19F5E05F1AC274C4A
-:107AB000B1F79F0CB79AF8FD35DF70FC6D8CDA7F5B
-:107AC00037DCCAF6C7FD7808ED4775E9793E0E3315
-:107AD0007DB896CBF9F74B6FC0FEEF6C1654184784
-:107AE0000AC53B6E1C45FB39F188C4E3302C2E39A6
-:107AF0008EBFBF9BB8D2801F13AF2302E8F3C43FF1
-:107B000012DCB735AE6629CEAB7EEBA038CF8675DA
-:107B1000528A5BB07367ECE8BF8F6F9574B84C9C6A
-:107B2000E6698179E684A304EDED84A3FAF23C12C0
-:107B300010B19D36FDF36B4FEAF305568E6F074982
-:107B4000057C6FF85244BA3ABB88EB015A6F67D98B
-:107B500000BCEFA6F3229CDAA5E9976251AC717ED6
-:107B600026E081F2EB0985E0F8F2C4523BC6EF5FF4
-:107B7000595A71058CEB9F7FCF7345AC73E011763A
-:107B80002981EDAF722750E229AED70A8CDF75E963
-:107B90002531F6EB6B38D670ADE1397D699C27D67F
-:107BA000BEC40FADCC0F29583A4250605EB64F208C
-:107BB000C0D78E073C973D37E3270F64003DDEE0DA
-:107BC00005F4B32DCD823B969FB1CAEA60F3BE07A0
-:107BD000FCB5B01FEF5EAA94601F7BAE7703CEABFF
-:107BE0006E87A02B7C67A95B88E7709758C866886A
-:107BF000674B75E9B7C603EEA7CE5847E97DB2C417
-:107C000084727E427621FDFE2A4230BEC0E3B50377
-:107C10006F269B22CF23FFC09AFFB095D6FBB0D52D
-:107C2000897249F6B804A0DFF5DFFFE500BDEEBCC0
-:107C30006446390EE0F31FEDBBAD9C4FA3E3DC6B54
-:107C400001FFA43C05F5C3E571A865C9702F01E5E6
-:107C50007B8C7554CD2F4DF250DB46E949B29BF039
-:107C60007E2EE276AB4E6DDF19E1EF45E8030909A0
-:107C700004F6A569F654681642F114FFE32CF610D9
-:107C8000CC3392CA69BF2909566261F5B54A67C209
-:107C9000E7AA719F3BC5652E1C6E22B8AF0D36D288
-:107CA00042FD9A9DD5ECF3DA4482F666ED635260AC
-:107CB0000DAD67A3D46685F849A65B2D80AD444918
-:107CC000928AE7BD0795337DB465FD3231ECAF5044
-:107CD000651FF30F7141ACF5BA8FC3FCF2BC00FC19
-:107CE000CA3ED4F50AB8352E2B6BCF75C082FE790B
-:107CF000D86E703FAC908FBB133F35B1FD02A1EB46
-:107D000071BF9DB68E66B41B540FDE1541AF3E9514
-:107D1000089ECF75D3FF72B52D7711F6838F93B977
-:107D2000C19A16F4DDC4912D80C76B5FC7BB38A222
-:107D3000ECC884373C6B80DE6F6A3F8C781813A2E6
-:107D4000FAC8E53352857B2A9CE13C94B75AF9FC8A
-:107D50008EDB9B94D271FDD1AFE53833F257D36BF4
-:107D6000A3BEE7AC76B598B1D60032C1D80E11BA31
-:107D7000E950B3C01EBD21827FDF994FF142E9BABD
-:107D800017F40EFCF38B8119809B0DCDDFB1827E41
-:107D90007CE3F1A3997E1DB1BFFA27A2A7C3CAF65F
-:107DA000873B800FD5FB2FF2F12384720ECB95EA2F
-:107DB00047643C44C3BD11E79A5EAC810B33B2F01B
-:107DC0007C1C01F98842230AD64C363A81AF9A7F4F
-:107DD000BD26ECCF26E2B99E554ED6DE1A59F3CB1E
-:107DE0005D16E8EFAAF882FE975B17F55EA2F3979F
-:107DF00088F3305EA90BE767DE4B0A09247F0B7E10
-:107E00000569EBB93A7EA5C4C5E05707E8D1F8FF8C
-:107E100027FB936DECCF836A777FAE259EDFB6514B
-:107E2000BB907B4F7D3AC305399C16890BBE5ED94A
-:107E3000937EE751FD06D72D4A9F0D7A3CB199EA12
-:107E4000B1295A8F5D7209DE5BE7DA6B437B67D439
-:107E5000EB8BBC5F5E1BE37B8DE8991107F37153DD
-:107E6000D760C05DB64A928B29B1D94191ADAFB60A
-:107E700026EBC691E8F1DD8F7652F32F35BFD2F8AD
-:107E80005ED8AFE4E38616CF148214FFB4DFF7C7E1
-:107E900079E6015FD738D9FC130E9A82BFFC03AB99
-:107EA000E70EA0CF46FB1007EB1A2342992C5E1277
-:107EB000D2E95B4FFA6533E84F6348C271CC4FC7D4
-:107EC000B16142CFF4F48B4B64F452AB027ECAC072
-:107ED0005CC21AAB26B8AF7B6036BB4766600EBB90
-:107EE000F7F1DFE3D87ACC7D716CDCD0D21F584B30
-:107EF000EE817EC912F19B73BE39DD402AC40FEFBB
-:107F00008F73DF0DFCB014B9B11F194EE21228DED9
-:107F100032A44601F6372455AA028B1B1236EE40D6
-:107F20004AEBCB2856F361DCCAA0B616E22019CD85
-:107F3000B1CFF56C8893BF5DBCAB29EA3CCA8638EB
-:107F4000E66F1F54687F938BD9799470DC86920F0B
-:107F5000FCED88BF0D3BDBF1195B0FF527323E1BB3
-:107F6000E75F2030E897C4F33F5488644DC2F9912D
-:107F7000DF04DF992C383FB2115723D8CF97E2584E
-:107F80005C759DE05A0FF99F485D16B86F47C3FFB7
-:107F90008F27DFEA92E82B8EEBCE67C39C95EAC36E
-:107FA000F320AF8EC9E787AFC51E740D6678738B5B
-:107FB000BAFDEF9ADC82B24E6E56888744DAEB78CF
-:107FC00005E7F71D429C0BE6431DCB0546A760E184
-:107FD000E703247D9C86DB436D1C78272E13E9B7CD
-:107FE00011FF18BC1FCCE2B2003D1AFDE173A4865C
-:107FF000739EC673A06959E1B84D3AEE932D51E0D6
-:108000008E2F72BED986FE97D7C1F4DF8887FE60B7
-:108010003C2E736E92F2AB15E4DB5FAE49047BDB62
-:10802000FFCEE30E90AF910F9D827FCC4158DFFAD7
-:10803000831C739F8896A6A50D28057F342D3D0DC2
-:1080400053ED79BD5D8A19073CCDF5EE1BE3B59E76
-:10805000580CF3C3D3D09FB39E77DE73A3BA776176
-:108060007CBC3E8EF1BB5ED1F8A826809E75E75D94
-:1080700009EC7E924476FF9093C97383CF522A49CC
-:1080800091EFB9D11FE947DC33E68111D82093ADD8
-:10809000886B16BFD1CE655043C7E497C8E8FAB9DC
-:1080A0006F4C29EC9F916DCC2E5DDC301DDB4B2598
-:1080B0000F588753BE2E2D31B920AE7376D19F1C39
-:1080C00070147C51466B2EE0FD88E8916DE331D44D
-:1080D0008DF3B76573954088422AA59E1A2426978A
-:1080E00019B8EEB8D01473FFB3DDC6E6DFCD714E1C
-:1080F0004CD3D20697968D8DCC0F44396978A47AEB
-:10810000985E36AEFB9C30C5470AB46FD4A74E9933
-:108110000461DD40B387299CFF9A3DD6F42105F424
-:108120000CD6014BA87DD4E43984BF9A8AF14AFC6D
-:10813000139A5FFD02E6038EEB0AD0DE51FD5F8FDE
-:10814000FA3282D96F2BD8D3883865E7DEF707C1BA
-:10815000FADF87DFBF100FEB407F91BAE2C17E9E4E
-:10816000BCFFDD783837F4E1FD2C5E7197611E3578
-:10817000C1C6ECFAA3B6926CE8D702DF7FE77A2299
-:10818000704956B3758DE501D1709E5C7F2F4F55B8
-:1081900063B2E19E1E3FD65BC5EFE732CAA192CB28
-:1081A00061F9B64D4A860AED7BDCB67E706E8FA013
-:1081B000BD3CD9148FF3118D9E45DBC6283077FA6C
-:1081C0004BB399AF7FB7CA6C5C7017C37A9687F3CD
-:1081D000CD48E7C17D36AC6FC9CFD8FE9485B4AD2C
-:1081E000D5D4BE7A9AD9790B633F967CA816F6A7A8
-:1081F000C25BF29080F36278FF7E3A4E79563F88F8
-:10820000EB5EC67E1AEFCD319E5FD5E653CBB8FC50
-:10821000CB8807F52FEA5C6B335B9F36C6FFCE1F1A
-:10822000CAB261FF6D3CFE914B26C079E81D87867E
-:10823000245CEE3EE533FC1E26B8571AD2933E82EC
-:1082400069B64D65F76434BF7D2FE0AA3AB81DEFDB
-:1082500019FBBAF6A6AAF99403F6306B7687FA9161
-:10826000AB013FA44CD0F997D59B2E286CBECBF820
-:1082700070077F7E07F4371BF659AB3F9A4CE57CBD
-:1082800047A57C31F21E32BF4D7FEEA6AFFDD5FA79
-:10829000A9F55B2BAFE2FBD18CDF69F8CFE6782C38
-:1082A000DB52BA6E0065D19ABD2706F3F368784EAB
-:1082B00047C397113FCB484961BA108193E647B154
-:1082C0005F9A3CCBEA16F2FEFBD3F8BA5E1AC48F73
-:1082D0007AC38D111F1D72DB60D067233E3A7AB8D6
-:1082E0005FE42736E62794A9EE4288675137769DEA
-:1082F00033C24F3929D51DBC0FF46C0BC379C4F8B8
-:10830000CB9CB9D7651CCF57C6ABFDE13E3D94DB96
-:1083100044D81760F6C37B5A3BED3EB76BA8047C8C
-:108320002FC2F4B4AFC435746877F9D2272E38C0A1
-:108330008FEE1C41308ED311AFA7F7773611E9F9D4
-:108340001D9743A5D4FA8F3F838DDAD28AFB1DDABD
-:10835000BFE471A02FCD45B1FAF927FE1DE1F786E4
-:10836000DDC5F54C9B972CE072BBAB99AD672FDA5E
-:10837000588AF230EED77A43701666D0AA3C8D63E5
-:108380001490BF513E4B5CDFC17D605172228FF073
-:108390007D011EDCA753562F62DCC328BF7CBB9334
-:1083A0009DA3576B701EB7428ABD0E79A5DDF4B54B
-:1083B000FA63ECC7C22601EDA491FE655B6AD70D96
-:1083C00020D07FD6BFE87E8406A25DE2FDD4FA55B8
-:1083D000465C78FF40D4FA50DBF524723FF5F2E6B4
-:1083E000C5B82FBF9AF69FB03812C68534FA357AD1
-:1083F0008DFD2814CFC81688E3AE165C609FA3EFEE
-:108400002773EBEE3F5CD8B07F20C8AF5D62FB66A0
-:10841000DBFD02CE0B3B3F206C7D60BD80EB693DF8
-:10842000CAAF99ED07EA598E350ADCE757B651888D
-:1084300029C765F5F9AEA111766A7960866BA88EB9
-:10844000DE46DC1FB2A2A154F77C809DC793B8FD25
-:10845000EE4DDF484D62CC3893A65F9ABE69FA971D
-:108460006F57D93C470A1CCCC804BBFE18CE4BA89A
-:108470005DBEDACED707E6D157AA9FB8A05B1F58DA
-:1084800092C7E4B3442CC6E73DD957CA079D7D1E69
-:1084900067D7EF7FF8B6FDD1FAA1E985D63FA35E95
-:1084A00018F9AFC5D58C7230F21FE882F9C11B7B79
-:1084B0006D810704D07746A77FAF15E9EC482B7094
-:1084C000C139C83FC00794CEEAF4DB315F239694EC
-:1084D000DA715EC7E74DE3FA163FC8E17ED64EABD0
-:1084E0007B2C3B4754920CB89852DB36D3E2A4F86D
-:1084F0007C647421DC2B3AE5B1B69910FA5EF2C8BF
-:108500009842B85F7ECAD6B6772D2EEAD7D58E2D83
-:1085100084FBE55780DD80F60796DB10573DE58943
-:10852000E7F27995BD3FCE5C329FDDCBCCCA2B29DB
-:108530008F2D743CAB3C3CFCF7A09F95ADC545101E
-:10854000B7A98488371DCFAADC8E902D9B8DE79329
-:10855000E87BDB6C9E5576F0EB2EADC5F1ADF2B04D
-:1085600084FA440EB1B8A844FB6AA5DFAD8DA37EA2
-:108570002FE5EFDA248B0BE6AFF4B91FE6B56B936A
-:10858000DCAA1AF15C931F7C0774AC35B175FBFD56
-:10859000AF0D4F68BBCC78BFDF4726C33CA4C5678F
-:1085A000C1D4589EAF38F17C44BE89C5358CE5BF37
-:1085B000D2EC2C51330017D5871416AFA67FE04FAD
-:1085C0005611A617D5849DEBAA3A4CF01C4BF5A189
-:1085D000423CC702FBFC3FD6E1F05F738EA51B5700
-:1085E0008C4F059230598AC0F534BB559717FB9BC9
-:1085F00046407F8818E78273186286A96607EDBF38
-:1086000078054D293F24A74B84FB5AEAA64E11E179
-:10861000BEA93532DF3F6262E7CCB5F69A387FB447
-:10862000F4B4BD6407C8FDEC5BADB936B67E81F32A
-:1086300061ADBF6B04371160DE7580E0F9809C147A
-:10864000D202FCB311771EE0ED3D7B12E7375B37BA
-:10865000A67F1990BACCA697558AF7571F5984FA66
-:10866000E04A30DD9349F36FD997B17C86E9422621
-:1086700085F0DBF67296BFC6746108CDBF6B5FCE26
-:10868000F2B0C04907B623F68A42FF486887E37D07
-:108690009BFB1AC0B76462F117E91505D753B47D87
-:1086A000216BE9440BF0F81ED84D88A7D416FCDAEC
-:1086B00006F1EA02B70AFB3D36F37B83BE69AAF1F5
-:1086C00055B49970FE0329F0FF43CE4F4D2EA4C937
-:1086D0007D0DEC8B258DEE6B601DEDB4DDD306F6C4
-:1086E00066EC1BAD53C07E37BDF3A75CBC9FFC0A94
-:1086F00056CFD837E89C90F6E7EC6F066D8A5C8F12
-:108700003E6DCFFF14BEA36240FF54509DE40EAAFD
-:10871000876BDC4455B260BEAC9F2F3611669FB6A6
-:10872000D94ACE825CC9C0108E5B45F6924EC86BAA
-:10873000F69CB426F5695F9B92BD5A847139292352
-:10874000787411D8FFDFB17B3D04B71BF773BE14FB
-:10875000BED78CED0FB1C1FE10D07F1749F3A7F241
-:10876000F8178B2F9394DC887930EF07FD7E1AEC95
-:10877000379F6063FB0768BF44B0AB63888AE958E2
-:1087800088676581283D98DF431A8FDE47EB7FDCE1
-:10879000CAE2499606A28B0F66C7B338CB4C078B4B
-:1087A0000FC6C98DB782FF10778E38C17FE8FCA550
-:1087B00022E1FE22C97923AE8F1D3411A0F7593969
-:1087C000E084F599AEAB247533E9AEAF93CB5BABE8
-:1087D000F77145BD0AE272731DCC3F7D369FE07E86
-:1087E000E8AE534A00D64D93322C3591F19F2BF9C8
-:1087F000770F390B32E321FEBC378E40FB13F6C5F1
-:1088000099400EBFDE9663053CBC043CA27C483216
-:108810003BEF86FA922E507A33F139DB272FA9638A
-:1088200012287F27DD6057E1BEA967AD8D37E07E56
-:10883000D0174C78BFEE4B8AAB14F22F9D579D603A
-:108840007F9FCD6C8CC3FEBC60C2FEBC14D775F597
-:108850004A4AF7C323587C4AB21109ECB2642A5041
-:10886000EFA6CF73E3D93C49B3D3CBE399FE3C2EBB
-:10887000103C0F2099F2517FB4FD3A9D5D04F7EB57
-:10888000F49BD52A028EE34AB5B851488478CFE4E8
-:1088900012827EDB64BB8CE772607F309C1B9BC2C4
-:1088A000EDEF940F2A713D814AE030DC7FD962E719
-:1088B000F768F175C5EB394EAE236D22F891D75D9F
-:1088C000222E88075D7F498AE9474EE7F53E23104F
-:1088D0002981BE977F51950077F944EFE74DAF2F7F
-:1088E0003C05E3E0548BE139F889488F1BCFF74F03
-:1088F000771AEE4F8EE7F3D6C16470E43E316D1DFA
-:1089000068BA38F209F4538B1417F065BBDDFD3EED
-:10891000AC7BFA5B6572B938E2333EB69F6FC4A593
-:10892000385CFFA1F8B4032EAEAEAFF35B69BFAF06
-:108930001ECAEA071C825DB9F29729C960E7CDF12A
-:10894000CCDE68A9863BC0973381E1CB39BA5B3F67
-:1089500057C567E27B9ABE01EEA09E3D72607EAC79
-:1089600075658AD75580D7ED7682F3B31FA55BE690
-:10897000829E69EDEC8967F837A6EB6A57EE87753A
-:108980001DFF676CBC9836E0921239DE7FE86438D0
-:10899000F3AA75336FA6FDF3DA655CBF49E5E78B93
-:1089A00022F1921E81170D771D7616EFD1F03375E7
-:1089B000F7BB223C9FFA1921CE4C129E8768F8998A
-:1089C000E267389C72888D13BDE1C7DDE59C06E641
-:1089D000310A3787186E0A283EF0F7B77AC08F1130
-:1089E000374FF58A9B2FF13CFCAABD532FBB6E1865
-:1089F000F4E9F77D1AD389B6D8FB828F727EEF56E1
-:108A0000EA6ECC067B7193899D7F9348C6AD14E7CF
-:108A1000BBE3B47BE56BB220BF5D62F6677BB31945
-:108A2000EDCF76BBC78371D7340B9ECB2692A70DB3
-:108A3000F6F5BB0658D4C8DFD1F82EC761A31C9A3F
-:108A40007802FCEFD798FCF36ECA811BEC487A19C8
-:108A500093C3B893CA2611E2428EFCFD80AF4FE06B
-:108A60004E2DC0C37105EF25AA3EAEA05DFCCDBE64
-:108A7000B70B21BEA9ED1F9EB0E7EDC28291F03E7B
-:108A8000C3D96BDCAE6A793C4A0176D2702FFDC443
-:108A9000F07926FDBDF225809FECEE72E37DEB734D
-:108AA000E084171D776E6D734D07B360BC6F7D4E0C
-:108AB000889D1F9B7DD43D1D4C65D47DEB1C0FB75D
-:108AC00091D65D7162F4FDDF747C3E160FF1FBD729
-:108AD000430AC4C11B959A6BD87CA2260BEC8FA6C7
-:108AE00077F847F9D6F8E108DD7DFFC3F8F8F38899
-:108AF0004B62F738B529B84EF82861DF35F271EBD3
-:108B00002BAEF739AB5E9C0FF6706CB91BD76D5767
-:108B100039457CFE1312B26481BC5C12AE7734CA54
-:108B2000EAD41342F77B442A1961A7E57BFAC58D85
-:108B300085F6EF70784C0EF02BA4AE43F0DD84493F
-:108B40003963C16EDBC7AC4D86714CA39BD255B463
-:108B5000D5DE4D87465727C7C91D8E8526C778F6AF
-:108B60001DD8A1E0B1760B7CAFE1A071EF3926FFF3
-:108B7000083C80FCBBF1202C80BCC6071B4FB5FC19
-:108B80003F1F0FA181209F1EF1007108C7B7C2438C
-:108B900016F055C303F5D7AE02FE68FE5AA3C2F61F
-:108BA0001D6A790D0745F67C7CCFA510DC3F44F6A5
-:108BB00059D9396D4F22AE57BCEC646D747ED83EE6
-:108BC00098BA9864B283F9EBDAEF898C0909E8570F
-:108BD0008EA106E10EF4E306A23D74717E9176410A
-:108BE000807B37716F7906F897A164D08B31E6E20C
-:108BF00010E07F876D4A06F88739B6C95980AF5DA6
-:108C00002356BD0E43D6AE01E52F6F51BBFD27CDD8
-:108C1000EEB5F06AB5F66F7430FB74BD9B9D0F0224
-:108C2000BB1D498766FF412C4087109A63FACA86AC
-:108C3000F6BAB90DEC39D041F9BA5F204DE01FE426
-:108C40009BDC2953C1CFEB179280CECEBD5F0C8643
-:108C5000386571F3AB4781DE626D3DD4A55F0F359A
-:108C6000FAD19ABFA3CD2B347F489BCF82DF04E596
-:108C7000D9FCB9D3CCD6AD26872C786EF9F1F3EABE
-:108C8000556EAEBF12ED4731EFC72DA415E9D2EEF8
-:108C90001DB999F3A3F8109D876643392137513EDA
-:108CA000DCC4EF1DB9C9A5BF57E196BCD8F78E68E3
-:108CB000F5F4F6BE717CB8D6B06EF46DD3433E7653
-:108CC000CFC87FFAD83C77D210D12FC1809A97CEE7
-:108CD000EE6970323E1C52628F57FBB9FE4E32B5C0
-:108CE00065C3B9E5FD7BFE8EE3E32B7BFEFE1EF83C
-:108CF00089134F4904F6B54E3A352E01D7E7F3D222
-:108D0000703D59ABD7FB69938DB0E7881FED77575E
-:108D10000E527ADC0AD067C1F4B7671EFF29D477F8
-:108D2000F1B84422CF4D142A9EA110C72DE4BFBF35
-:108D3000735060FE92567E90FFEEC5F31CB7B021D3
-:108D400042BB8FC41C21E79BF83D199A5C6F3A59CE
-:108D5000744ACA8E960FFCFD33E20B5A5CA199F35C
-:108D60008FB4FC11CFB77CA7E96E09FCF3EFA4899F
-:108D7000C41DD1EE0C95CEE023E21C2F3B0C7E4AA5
-:108D8000CB733FBD998E2BDE3744DC4AE86DDEFEA7
-:108D90007A36E45BC598F78F18F9FB9DE6BBF1FEC8
-:108DA0009121092AD2D35BFB93AEA638190D722705
-:108DB000CCCFCB65F77718E5FBCA9EFF486E1BD971
-:108DC00033BF7B92BF510EBF3D5380EB4EBDC9C335
-:108DD00088DB7DB49F7EDABF10EDA79FFA63AFF802
-:108DE0009C98FFBD2F0DF31A5EBD7B9F4E067F4EF4
-:108DF000C3E9F464869B89BB7F9A4CECDDF232F2C6
-:108E0000ED7307F36BE610D7EC9BE93F770AAE787A
-:108E1000B4177ED20AFBB34A388D730E17A2FF41F6
-:108E2000F87910E33836471C89E7DE7BFDDD9BA12E
-:108E3000F932985BE37805BFC702B8368E53456FA9
-:108E4000D449E0B2154AAB981DE37EBA469751CE9D
-:108E5000474809F6A3273A8D3830D2ABF9E7DAEF65
-:108E6000C0507E4C4FA2F5DDAAE663FFA2C661CEDC
-:108E7000979EC6DF9EFA959CC0E3DE1CFF174E4E00
-:108E80007B0BD8DB93BE19E5662CD7EC47213490D9
-:108E900083A91FFC912109A9A80F859714E2A6E3D5
-:108EA0000C19A83FFF4E8AAF40BCDDE364CF7AC205
-:108EB0005BF52513F12477E34E0E3E6603DCED9659
-:108EC000EA6C101FBDCE5EBA06546FDAA705B3F088
-:108ED0009E8736138190D9F4E6732D1047F01E2536
-:108EE000783EA0A079FF54C0E9EFA5569C47755E77
-:108EF00024E4B1083F33D8BCC6067E5830859D6F48
-:108F00003B984874FB90F72730BC068F9FBFD91D54
-:108F1000A3FC122F9F49DC29D9382EC763FCA3700C
-:108F2000BD09FB3F4D701D4801BF659E80F385CE96
-:108F3000BD130EA4507A3BEE4C443B333DF8E0DDCC
-:108F40004E2A88C6FF1E8BCFBB160A78CF40A1EAF7
-:108F5000C27C615926EEDF98F08FE499C5503E43FC
-:108F6000C6F9CD74B1528278D4D9342107E68B7B0F
-:108F700084B65AF81D5C7F296B8738FDC930FF7CA9
-:108F8000A738790CFE769CAAE587E1EF0312C33C73
-:108F90006DD5CE0BFBCDB47CD56C01F7EF4E77666B
-:108FA000107F047E0AD753798EA5B86CEE5F00B8A7
-:108FB0009E59A43F3738BBC4460291EB168213EF8B
-:108FC000213BC8F7697709FC5E7CAEE73770BCCF00
-:108FD000999BACFBAE94303FD3BB5364F771E4B3C1
-:108FE000DFA1D6F4EB46AE8737F0F9F13C4F868E21
-:108FF0008E6288D288403F5B47BEE5621B0ECFA5DC
-:10900000E20787E7D3F66E1C6198D78A956B111734
-:10901000696C1D6F36EC8213C16EEADFBB254F9F72
-:109020008FA1C797B5139A3D98BD57C475C3D9F999
-:1090300094CF0289F2D3BFAEBD9860721D8078D004
-:10904000AD97DC788F4E94BDF8A0E81BD98BDF502C
-:109050001DCCA37AFD64021F370791416037A68BB0
-:10906000DB7E0A38EAA4E3A639068EB471479BEF8B
-:1090700017523D06DC90336C9D65FAA534DCEFA4F5
-:10908000CDF7C37684FA25AE18FED26F12B274F70C
-:109090007A84ED4A845F22E77E7BBF643AF5479588
-:1090A0001CA06F20F18F457B8671C942D81805F14D
-:1090B000C1B47318E7F14A74FE8AE3F3D3882FB082
-:1090C0007F4252B77E18FD152DCE3CD6A9F9537AB2
-:1090D0009C84E38DB3D87DA51A4E0A819FA0FFB36F
-:1090E000448CEBF4861BADFDDEF012A2F6084C5664
-:1090F0008F78E1FAF775F1F2176D7C194A86F6055B
-:10910000271A3E34BC18C79BFF34C4837A1A6FBA3F
-:109110007A196F0E8C90D1AEF7E6D77CEAE4F3EAC9
-:109120000427A6375C351B7F97682CD811F037F9D8
-:10913000B8158E6BD5339C1C685B24C1FA9117EC73
-:109140004766B71CB478F0FF00C6C481D500800024
-:10915000000000001F8B08000000000000FFBD7C25
-:109160000B7C54D5B9EFB767EF7924334966924940
-:10917000323C841D082121090E21BC1137490811F8
-:10918000A20CA8888FD6011F6020094DADD5536F62
-:10919000332181526C3D58BDD67BF4F43758ED41F4
-:1091A0000D75080183277026A098F0D020F8C07AAA
-:1091B000DA6829451B92185A0F6ACFF57CDFB7F69B
-:1091C0004E662683A5F7DE73879F2ED65E6BAFF5BE
-:1091D000ADEFF95FDF5A9B4AC09F0A50B315209844
-:1091E0000650F9E1864A4806E83B20011403D4966C
-:1091F000C9411BFEB5B4FDB1C745DD0C5689DF5131
-:109200006126C0F5207E0B950EC5E60658E695BC96
-:10921000721680D62EDEBFE19225A862FD7AAFF9E4
-:10922000E31E9BE8FB35FF5F03C800B8517F7F1941
-:10923000FD0FFB2FD3A460185F5D363BBAFF8D97FF
-:10924000CA3F91A6022CD7629EC34F3E93A7F2223B
-:10925000CCBE24AC5744B78F7326B9CFD9F12FE3D6
-:1092600061FCD732C0C5F3656F51F7AFE977EDC840
-:10927000F2483D526601E8ACB77119DB5E6E017FC2
-:10928000C881254D50C4650052010A9DB8981958EF
-:10929000BF64010DF9086313E0F7B93A1D1386DFC7
-:1092A0003F88E30770DC308E1FC8013854EFE4FAC2
-:1092B0006BF51EAE5F93822FA4E37F87BFB0A8B883
-:1092C0009EC5EDDF51FC38DFE24B0A8F3B9BD69306
-:1092D0004F0B8371B49E3FF716FDE30D30DCBFB634
-:1092E000FD338BBFF0F2EBF95BF3E7A7A83C3FCD72
-:1092F000AB150CCFBB44011883EB5C9A1BCD5F63AD
-:109300009E58F9C6CA6FB9FE7EACFC56C4ACC79075
-:109310000FF4A2328D8AC3FF4B26D0A65F5E7E4338
-:10932000F2B1F8B3BD0523DB017EC9721A1E4F9757
-:1093300017742BBE42419719F5BA52B70BD4EF40C0
-:109340000ACAB9B213C28948D8F5E72B3E51A8F42E
-:109350004AF071943E037C6CC85B1E1E7FD125E4ED
-:109360006BDAF0BC8B146477113D1F0B8138EBA8CE
-:10937000A17114EA1F60396CD9615A15C2755C631A
-:10938000813B7D54268A32E094B87D93D3C4E3F6C2
-:10939000FFC56682AB015E3E985902489FD7EA3C02
-:1093A0000613014266E0F7BF4E52B9DFE6240824F7
-:1093B000E0FCA074DBC85E9412805CB43B65B4250D
-:1093C000D88843362B611FD961BF578106B4DB2F84
-:1093D0008DF70E056E0714C9E68F734C8D59F47E18
-:1093E000B87B1EF69B55A4A8DBB08BCBAA7E87DA90
-:1093F000FB0E589DF45EFFFEEF7798699CBF8017C7
-:109400002984D70E5881DAE73BCC41F21F8BE4E385
-:10941000B209EBFD030056EC3F7F55B814506ED7F0
-:109420004077A313CBB924C738F27B8DD69BCEFEF1
-:10943000C3310AE5B44097D302DD6F951E90D98FF2
-:109440009426C941C81AF653D7EA325A806C253A95
-:1094500016B4E17AB1FDDA4B4A5CBFB4481F77E13C
-:109460009F4121935C08D17ABBA84DF8A312D01478
-:10947000C0294B6D31EDE497909E45CEE8E773C966
-:1094800077A25EEF8EF14BF833D1BCF73BC5BC8BB6
-:10949000E4BF26F7E0FA5FB668EFCD437A074E9A4D
-:1094A000E1597C0EE7B13267245FDAD0AE83399799
-:1094B000B78BFD07133515E97999F4C741F5D19AB2
-:1094C0003AF5F2FDA7F60C94607778B97985021326
-:1094D000581D4F7B3286F93D82AF3AFF63F9D9229E
-:1094E00041931DF9BCB0DD5B46AE65041F3B918F17
-:1094F000F85EC980C6F35C291F0DFB78F95CA246B3
-:10950000FAFEF2B9D11ACDFF2AE96BFAB0FEEF3FAD
-:109510003B9848FE13F9A82AA817032E9BF759D6A3
-:109520005FA1F7A15139C16D586FD1F5FCE5C48138
-:10953000A3F9C4EFEB4DDE67691A65E3C41585E452
-:1095400037B7969CC577240DA407D17E24D509771B
-:10955000601940FB217D0BA402EB93194240F336C6
-:109560006AF034950BE6AB29C4EF411CB3DB41E351
-:10957000A929A4E7F0D78B337D8523F9DE528F0A22
-:1095800085F3B4D6DB34251B605FBD93EB6DF51E10
-:109590002E5FAD57B9DC742CF9C1208E53AB593412
-:1095A000256DF87D57AAB08F05E86788AE052005C0
-:1095B00003A8730B1ED6F55E91829B249213AE27EF
-:1095C000829F2897C19EDC08FE36294D9366B235EE
-:1095D000B0BC8BF24DFC3E06FFE0F35923FBA3DC4D
-:1095E000A3EAAA4B627EE6BAB42417963F74F852F7
-:1095F000A86C916E397C01B8EE12F55BE50B38FE74
-:10960000F4F0427810E3C374140CF1157FB713FD26
-:10961000333A2C40F2C180CA7659A4D3A37D2E4997
-:10962000E7703E329DAFC7E07BD6CA30E9D13EE855
-:109630004923BE17DB7C76B428A443C855936EF645
-:109640004838DE9C748B5726D226FAA66F44FE75E6
-:10965000A4E384D8BFA32363AC8AF6A6296FBC4FCA
-:1096600076ADD91C61812BCCBD3D11713C139E712F
-:1096700052BC229FF635F2BDF377C901F66B8873B1
-:10968000C88F759E4AF686719E6B2ED9BC56D27FC6
-:109690007A11EDF56062F254F2CFD05DC6EBB8D628
-:1096A00026D6916FF617BBD89F850F9FC0F7FE6D2A
-:1096B0001080FCE935DD1FCA80F4949AF2327B9069
-:1096C000CEC3D2E4142A9FFC5D720197A7927B89D6
-:1096D0003F074D7695E67DA75E2DCE467DD1DE72A5
-:1096E00098001DD682B71C0A9527EAA1381BF5E51C
-:1096F000AD7A1B9727EB9D5C9EAAF7707918DB4922
-:109700009F5EC776D2B737B09DEA5DD84EE5311C73
-:1097100097CAA2DB9378BC96DB922CB48E83C9D017
-:109720006CCC4FFA144E0CB78217E03F1EFB6AABAD
-:10973000ED2A8C97567FA1340DF9F4B3AF2A14ACFF
-:109740001F5B3CEEA1BF60BBF967A61FDB90DE9BF1
-:109750004E395A8F63DD9EAAFCD841FA792C119DAF
-:109760002399B5B94B433AA6936F1CCD6CD760369D
-:10977000D6D3F47AC07C5DD97C8095A53DF9E042D2
-:10978000257159AFB3217F57DAFDDFA3BA25B0ABFE
-:10979000A2EC2AAA6388247B97CC41B6F7B1927BCE
-:1097A00005C6BB950EFF7F12BF0D7BD1A43FA491D0
-:1097B0007F98A949E072B3BC8393A4E1E746BF95C3
-:1097C0008E45FF49FABADE25B37DCD982F6941C792
-:1097D00048FB35FACD38AB9691FC669E2F6FA2728E
-:1097E00059858BEBBE55B39AC8FECB1C977BBF94B3
-:1097F000DF7FD06566BD2D51B05F9C3868F49B8ECD
-:109800004A46B87BA02B31F82CE9F5697F6312D664
-:109810001779B28A64DD3703D75D3BB6517BE5EB40
-:10982000AD6C57DE242FE1F299A89069D8BED02103
-:1098300079C3642AF33F6A4AA376A7E425B62DD4F8
-:10984000A69D28A6F66CD9BB90EAA7D5320A51A7E7
-:109850009485F32E60BFC5B9295E1BBE772AFCD064
-:1098600045D2DF85B949DE04F2F34AF0E91AAA7B52
-:10987000ADDE0695D6F15869328DA34A5E13D65BEC
-:109880006E28FD1F4447892F052489DA5D0AE1D738
-:10989000277FF7C33227F66B192701D9CFA970DECE
-:1098A0009F88FE859D896A02F9698BB38CDE6BB156
-:1098B00048CE4D5CF79552FF408E597D1EC73D7EC8
-:1098C0009B9DE341E55B058C838EDF3686E342E5B5
-:1098D0005BF34BA83C6E1278BDF2ADCA0A6E3741FD
-:1098E000989C4AE5EDDFE2F7B697FEB0CC8DE31F1A
-:1098F0001BEF62DF82722A5622FC24F60789DEBF44
-:10990000BD9AFB7748990F9DC5FE170B528AAC385C
-:109910007FB93B21AA7FC55857547D49F6A86225D7
-:10992000C24F56166445D56F28968AB323FAFBE6D4
-:109930002744D55794B98AB323FADF54392AAABEEB
-:10994000F2A6ACA8FA42D31CE13FEA617E99B0F3DB
-:10995000F965D9208C89FCA953F47D03DBEF263B04
-:10996000EF12F8A9C885F809E552D655CC71B9D8D7
-:10997000AEFBAF00747B6692FF17BF2E1C8FDE8399
-:1099800020FE99497848FC1676231E207CA460DCD2
-:109990008EA0A7CC111DC72B40CD27FF5BD1B9846A
-:1099A000F154B96779199A31F231FABD0AF9618136
-:1099B0004362E82EEA32C7A5B7626CF4FB06AEAB91
-:1099C000D0E96B31F99B52098B05B46EC235C67A6A
-:1099D0000C3A2EB79E0AF98E3214FFDF5C572CFD2D
-:1099E000001B797F114BD7A04BC78188A71807763A
-:1099F000A6323EC49F3B1E3E30704F25FA3757A417
-:109A00007F7348EEE58597F76FC6B897C37BC6B8F6
-:109A1000C6FBD02CF3FCC6FB43CF5529FEF39DD8E3
-:109A20003F29CE73B714FFF973D1FD17286AA3033A
-:109A3000EDF82848DE00F1FBB8AA10242B3DAD3527
-:109A400051B9E843BF427874F1D9401395F37A8352
-:109A5000C7ADB8FEEB726595F20D061E8A5DD78C18
-:109A600054B14F3A7A49B5ABD8DE1250EDB4BF6865
-:109A70007958B5D33EAA45830ADA2F6A134D1B697C
-:109A8000BFA1E56389F59C54E1E7F352058E31CA25
-:109A900067657F5E2A96D5B69E47098BD47C316078
-:109AA00021307094705EC1489C7754093A68BEA317
-:109AB0000F071DBE083F7EA5386F14295B3AE9A742
-:109AC000A445FA91525B8216E93716395D51F5AF1C
-:109AD0009CAAD8C77B4645BD779D9A15D50FF16BDB
-:109AE0002EE1A0460BE42AE4474D895EC277B17CA3
-:109AF000FC177DFD5E8793E01398DDAAEC8F13972A
-:109B0000BCA5827FB1CF57A48A7DEA6F683D586EAD
-:109B10004F15F435C93E01E21037933EC4D6714F5C
-:109B2000BA8AC6C3913DA4775EBBE922426FF84E64
-:109B3000EAD5D729A8CFDEE9A6EF4EC4FA23A98B30
-:109B4000447D9E69CF04ACFF34B55CD4AF364D374D
-:109B50007B017E058BAF2BC37ABADBE74FC579FB60
-:109B6000CD8EAD12E219C52441917B78FFFB8805AB
-:109B7000E3290A16954C7321AD76ABD82FD724A0D4
-:109B8000FFA3FE259A4AFCAA4930E4DC9341711DEB
-:109B9000EECE3491BF30F66F760BBE87EFE7D8FC80
-:109BA000B5425FC2C92AFAA5FBF72FCA24BDD89EC9
-:109BB000EAE4F5E7EF99E7217F85747D97FAFD7F69
-:109BC000A46B533CBA9ACC629EDE96FC528ABBF9D7
-:109BD000E3511CD2B0BC70BBCFCF1342A82B8CCBAF
-:109BE000358F84F54697C54B387DFB907CAFAC6CC8
-:109BF000D4F313B25DE88D9C62DAB81BCB9FEBFA0D
-:109C0000F214CD3B83E61918B71CF5019C03E3560B
-:109C1000148A3AE9832C170D10DE1EF8569297F736
-:109C2000C763077EFB03ACBF7747BE9770F4078915
-:109C3000823FAB82131A7BB03ECD1ABC2A8C743E95
-:109C400094E67F96F4E0366B7012EB9B6363128DA3
-:109C50002F69C0FB10637F87FB38D5327124EE1F5C
-:109C6000392FD888CFB7CC117C36E6459EDA28EE5E
-:109C7000BC375B3C37E8C0F95B88FF063D4374C0E6
-:109C80005827C7031079A445B243E461FF60E2BCE2
-:109C9000492D191FD6F79C35F1BEAECFD85780E6B7
-:109CA000583D939B789E392736C94C6C00FFCCD425
-:109CB0005948AFB6ADE77DFA8CEEE87DFAAC4E7F41
-:109CC000A903DF9BF57EFC7CC83C7DDCD910942980
-:109CD0005ECFE989EE374FDFA7CF3B1FFDFCCD54A8
-:109CE0003DBE8D86D191798E3A7DFF33787C420AD4
-:109CF000E929F93A19F96E5165989D3AEC375AEB12
-:109D0000B15F0EF9471B9785A79D7711FD6DF5A8EB
-:109D1000D016F2931E2E0D7B2A3C0D77C2D4887983
-:109D200074BD37F838F8BEE0E3B49EDC9FCFC7BA05
-:109D3000B9D30C4175789D73753E0D82E0F3A0D3C5
-:109D4000C27C9ED9F5CBE9617C64F598408D585F63
-:109D5000829A086A843FB5E7A646D565433E3ACE67
-:109D600098AE8F9FE41D1D358E81370CF9BD9A5A30
-:109D7000DE493864BA631DE38E94D913A2C62D3E22
-:109D80001E2B27641CE17624F29F08D79F56A270F1
-:109D9000C62C77803800B33F546270C97699EC685E
-:109DA000EED9E8E7E6B4CBC8ED72FC84A93F9FEF9B
-:109DB000FEFBF9E9D2A2F9995611CDCF745F343F79
-:109DC000335745F36D943F9A2F63D64D896ABF6A26
-:109DD0006351547DFC8373A3FA6761008CAC4FDC44
-:109DE000BA24AAFFA4ED2BA2EA939FBA2DAA7F5E04
-:109DF000704D547BFECEAA2B927F61A82EAA1FB174
-:109E0000D7F40DF2BFBAED1FA2E6F9EF96FFA23428
-:109E10003D2FAFCB7F998E435C1AFAC7A2E138453C
-:109E2000E915F293AEF637BEA0FC4BA044E5BC5357
-:109E30006009781BB1ED09D927915F1B83AC36A16E
-:109E4000DF6832C13AF2F78F9A4C9C8734ECBC2A17
-:109E50004DE08BAA34E1F79F469BA6F866F0CFEC65
-:109E6000DE9E4478433699A09BE29AE265BF71C6B4
-:109E700001E16B713E7934705EAB3479F6B299A82A
-:109E800087F29B32EF1FE5D17E50717D8DC71F3F5A
-:109E900041F99F8B0E9B4AFA2AA7FA0314B7707DEB
-:109EA000A1E761245E79AF3E3C89F649467D95671E
-:109EB000E366EABFEA8E859368FF3AF4FC8E8E492A
-:109EC000651172885CDF8A38F8E87B69223F67C4D5
-:109ED00087DBAC6A630FCA6B9A2CFC3FC685EFA583
-:109EE000E1FA3F901E360B9C1530D3BA314E72DE2C
-:109EF000DF8580BA0ECB94E178A47E8D4AF5C184CB
-:109F000068DCF9261144FB085B2AC7FF5B0D7FBBA9
-:109F10002E8FF936E888EE3F78F744C1CF6F23D70C
-:109F200090DF672C621D06DDE7753FFCA9EE877B9D
-:109F3000C9FF46E49BD7ED783C89F0F5995C81A791
-:109F40008DE7CFE8727D264DE0E9F53B139C9179D2
-:109F5000C7EA902BAA5EDB36CA7936420FD71BEBD5
-:109F6000F04B0AAD63836E3FD59D3DC9B701E3F168
-:109F7000A7D370DC9A1D17BFBD8FDE370D648838FC
-:109F80001AE0F96E790F18D7DFF21544E1D297D2B3
-:109F9000447EE525A20BCB95583851DF56626C778D
-:109FA00051F9C6FC72B23B7C1E96B0BEAC13CC8499
-:109FB000D396FBB3CCC4F453E07D672F2E6D5F9A2C
-:109FC000CAF3DC043E33C5C577BF5D9D44FD86C63C
-:109FD00033C61943B959D42B57C09C41F99A6B2405
-:109FE000C60D389F8D9EFBEE18B399E2AF31DFBBF3
-:109FF000E0BFF00EEAC50AF0F2B8C6F800A9517E3B
-:10A00000F803CB901CED24BFBA2E5398F239756734
-:10A01000AC7CFED1DF30F0EB0790CEDF557DB15741
-:10A0200042BA7FBB7AE057FBF0F9AD4FA1DFC5B56F
-:10A0300066DBFD87D322CEC3CEDC7D91ED0CF1C86B
-:10A04000F34F92337AC9EA25FBF8A0EAA59C48BCF5
-:10A050007F226D6127BD07B3D3E29E47C4EE2BABD1
-:10A06000483FD96E55C699865EDEA7EB65DD0B933A
-:10A07000F9795DD2D07A44FD7999F3577507ACBC74
-:10A08000BF7F47D787AA17BF9819999F6B41BD54C7
-:10A0900073A8747249E79C2AF266CFF1C1A9D46F04
-:10A0A000A3ECEF213D3978E9E364AAEF79F34B5E45
-:10A0B0000FDC7465F4F723F322F95C9B34F02EF97E
-:10A0C00093EA7D5695F250A5FBF28EDD8EF59A4E01
-:10A0D000F43BB89E0BAE9E234FD37E6ABF04949789
-:10A0E000AA0927B073AF69958294C7AA6ADBBD65D8
-:10A0F0000CD6AB9A971793BAD6260B3F56D32205A8
-:10A10000693CF0A7317F8A74DB287D35EF1F0BB0E7
-:10A11000BDEFA818FF5C7D78EA59F44F7D2D9F9D17
-:10A12000233A36B459393F762E296C1983F35ED819
-:10A130002D8502EAB0DDF6B9C43E6A5DE8310BCD8B
-:10A14000BBEEB9E5D9040FFBF69DB4907F5CD7FA5E
-:10A1500058B9FEBC5884FB20DBC5FA9D1D9322F341
-:10A1600049F721FC83C8F881F40508F78290E309D8
-:10A170005D3EABDA273612BBD0AFED7D5A62BFE64B
-:10A180007493DF3BB8EBDFFF95E6DDFF2F9398FF7D
-:10A19000C557C67FF005184FD4E8F3C0F95316DA57
-:10A1A0001FD6B49ACFC53B17FABEDB77957BC6F0B6
-:10A1B000FE3616576FB18038B79900C1E7291E38AF
-:10A1C000062CAB919E1F5107A447710E58D660DD37
-:10A1D00046764671C2E308C6DB17D7B9159E0FF75E
-:10A1E000081BE39D57D6EAEDA56A8F85F270359E70
-:10A1F0005E0BE9754DF813715EDFF651B91667BF56
-:10A200005CED167ED3D003C3DEEBD2A7B05D98879A
-:10A21000E260C8C6765FB86680E253DD7ED40EDAAF
-:10A2200017B8FC034477606F824AEB2BDDF7C9CC8B
-:10A230009E8879FEA4DB8751AF79F9A3A966E2E78E
-:10A240009E8FA62A49C3CFFB321CEBE2E555AADD5F
-:10A25000224E6F4EF69D8FB683046F18E7AD69B737
-:10A26000F3F907DAC1968EE2483BB875DD0ED2F3FA
-:10A2700076D98B1601356DCBFD0DDC3FC94BE291D4
-:10A28000DB1606480F65A78FF513FE8AF3CDD4CFF2
-:10A290007D2652AEDB7F1BE991E2084F8ACC6BD45E
-:10A2A000987A7ED121915CB76B269AAF08D86FC996
-:10A2B0000E5F0FEF9F8A3354DAC71E9E510EC4A75C
-:10A2C0009F1E90385F6B4EF56FCD22F91E95B9BF7A
-:10A2D000E5F00B013A97EE9B06C5449FB1DE9F4E19
-:10A2E0000B838CE36C2E042F4DBB79FF2D1ED2DF28
-:10A2F0009FA61F617C61F78680FC4A23E206CAE7BD
-:10A30000D80B42611A2721D7572CE33C796E27F3EB
-:10A31000CB62F57B291F944D755C874DF1AD23FA17
-:10A320006CEE44B19F1E7B6579BA3EB27F85CE1B31
-:10A33000FD9C2FE9330B3DEDBB0A185FF31D9D39E2
-:10A34000D4A409BEC1762E6BDB3AA646C6DB44F028
-:10A35000DBE879DFFE5BBC44BF3951D7F78C44B6EC
-:10A360008BD8F9FF99F499E46E5AB3358BF84C7C8D
-:10A370005347F67B5AEF67F003147F2ED92B92AA2E
-:10A38000C5CB0F8D77973C4E72DD9CEACB7515F0EF
-:10A39000F1AC00C39EC4B87687FDFF5764FF1FE988
-:10A3A000FCDCA2F86DC4DF4D7ADD6CF1A94EB67FFE
-:10A3B0009F4AF30FAD6F74FCF5B5E9F6BA6582FFFD
-:10A3C0001BD7B74F5F9F3915F58DC64B06EE674E0D
-:10A3D0000E0648FF9A92A078133E3EEC2AF790DDD5
-:10A3E0006D39F4C538B2F7A624AF0728AF7560D62B
-:10A3F0002AB2FB2DA36F63FDFFF485BC2239629E58
-:10A40000136925ADE4BF7E69ACCBE2CFA575FC42F4
-:10A41000D723635DE96EDFABEE88BC118C755F916D
-:10A42000FE80BE9FF3EAF117F7739CFFEB87442F82
-:10A430009D27EED671B7023ED61B3B7855C6551AFE
-:10A440001CA37B1F8D1D26D846CBA6E454C4395DC2
-:10A45000B26C32367D9A0DB7E6746C4CED6FBAEB88
-:10A46000963421BDFB21200B7C169DAF004DD2A45C
-:10A47000C83CC56B55F1F314CFF81BC92EFF569E8F
-:10A48000624ED8B4DA92F2F7E72BCEBAA3F73D9F2B
-:10A49000BA55262A942BF431144E0C8ABC174CA7BB
-:10A4A0007D5333F112FF7B06D7CAF62DF5E5DA5C52
-:10A4B000684FEEFBB76D1D8B76972DD64FF546FA9C
-:10A4C0007BA7C03D43F98FD7A630EE463F27F3FE6A
-:10A4D000DFA9D31223B762C46BC0F78852A3F22757
-:10A4E000E1235F26937EED4A55DF22B90C74C97CC7
-:10A4F0004F2441E9B1B8E2D8D93EC203E8F78BD383
-:10A50000C53EC4D626CE176DAAC67E31C1E99C26AB
-:10A5100047D8C579B7C89F571FF9609C0531DC053E
-:10A52000D3F1E4021C7FC3DE96644AC3AD3FF3F669
-:10A530004CBA9253A2F81DE9B8FE4FA51D3936C298
-:10A54000A95B8353893FA1F08414F293850A049494
-:10A55000A238F1F1A922DE14D73CC587FF50D83EBE
-:10A560007D2DE1E5DAB0582FCD61C6A6BC36E07A84
-:10A570005F5B632A8D57FB6F074693BF7A295DE0C7
-:10A580009A172F4D11EF2BA050FFAC7497AEE741F7
-:10A5900013E50B5FD2F38C7D974CDCCF98BFB06D89
-:10A5A000A1EC443D28086F3FC479CD76AB4AF24D0B
-:10A5B000780E043FDA131877D61E5C0C14E7FA5DA8
-:10A5C000E095B07D57E2C06F491F060E58553A77A7
-:10A5D0004D706E87541C7F977E4F2B0F15B2C5317F
-:10A5E000FCDC982FA1FDE7941324BDE0F3DF0465A4
-:10A5F0003B5CE388E47712D35DA2EBD5AEC4B089AF
-:10A60000CE450626E15E87E91AA613785E83CE3C26
-:10A61000F6FBBB2C03E77EE066BA9CA4077920E832
-:10A6200084F6C92AF9D104A7C6EB4870AADE8034A3
-:10A6300092AEDAA908FCD06E1E25E73577D8AE6B4E
-:10A640001387EB36B4855D13403F8FFFD5363A8FC5
-:10A650001FAA9383993DFCFE2DE92F6C6B1ACBF951
-:10A66000BD808CA2B66399944AEB54797DE845B5D8
-:10A67000F422C107BAAF67B789F6A1FEA8E70EAA10
-:10A680003B443FAFD5695F92C5F64287D74378F028
-:10A690007E297CEE5AB4D7DEC77C2905B8AE5ED3DE
-:10A6A000A1079AB1DF9F568772E83EE97356FF1AF9
-:10A6B000D2CF573E5CF34821F9DB5D666F25F99DEB
-:10A6C0009EC0CF1887BF6856B745D81D8C1DC8E0FF
-:10A6D000FB8031F3D49ED9F433C2D7FDFB2595CE50
-:10A6E000BDFBCD03E388EE9AF63F5AE8BE64EDFE6B
-:10A6F0008F184F4B19FE1A9A6F765B03DF6B9B0323
-:10A70000DBF95E1BFA43BE9F18F2087F32783AE706
-:10A71000D98608393C912EEC0D06FCE3295EB5EB99
-:10A72000F67A90F6DD58EEEDB875228DBF57CF075B
-:10A7300018EF35C0A131C4F74DF01A97C6F3FEA04B
-:10A7400052417A96FFAEED4E2DA2FFA3E902BF3D26
-:10A750009A2E70667686BF89E85DDFF1B12599D6BD
-:10A760007936348EF6B921454D71C6F12343F61B77
-:10A77000634FB5CA8085FAD79E07F62B28EFA6143B
-:10A7800094DF4BEFB64D598DCFF7A24C5228AEE275
-:10A79000FE94E2EF5EB36F0CF56F78E7F3A9E4C7C0
-:10A7A0001E484FE7F57F7E60FD78E21BEA7F492275
-:10A7B000D9D96E60BF66D86901D929BE5F40FA5FFA
-:10A7C0004CF53CF6CBBB2CDD4BD82EF79A80EC1227
-:10A7D000F59FED01F5DF49F8AEC089F6C0EF4F6691
-:10A7E0003BDFD56DD21827A35F9FC4F5921BA9BE8E
-:10A7F000ABBBCCC9764EF7058AC85EC387789C1080
-:10A80000C024129D04BEA8FC883B99E936FCE5E70C
-:10A810006ED0E3869AE2C575D86539CA3E22E2A4B5
-:10A82000A81B71F4C933DB9E407B81EED428DC0F7A
-:10A83000EF0BBFFF5D3D56D5BD3E775933AEB3EE4E
-:10A8400084CCED07F57D5E58D793437A7E86E28609
-:10A850003A5DDCEFA5E733B04EF75D676A1B4B0945
-:10A8600063CDAED87E98CAB9BE502941C8F9ABBAFB
-:10A870000F9B8599E793FEB51EBA2E9FEECDF59FEF
-:10A88000B1420292D8FAE5C06F5FC4B53D7010F9CD
-:10A890001F274EE17258FF106F8D01CFC8F67EC999
-:10A8A000F023BD4B481FFB5AE5E13A1252838A4D13
-:10A8B000F577D23FDD16C0BA3F437B9F54E2C7997C
-:10A8C000FEF7493FFB4F7E994166B9F7B4D8C7B749
-:10A8D0005AB47CD29FD609B8B58DA3A7AFA58B3C3F
-:10A8E0004FB115E29E4B7EA5C7C19C003C22F1FEF4
-:10A8F0005C760651EE175A65CD82F8E73C0456CED9
-:10A90000237FA3E76FEF01FDA7E11F94CFBD7AF589
-:10A910001EC22B18B7EE7D62C4B9BF89F4696DBB46
-:10A9200004FF846B5FF74CFC7B09465EEBBEB61DF3
-:10A9300047C6A03CAB9E8BEEB761E89E7B88F7BD17
-:10A940001B9AA3EF1B7C95AEE396893091700BEABE
-:10A9500013FB07B3029D56D4DF5732FD9F105E7E76
-:10A96000C924F8847E95EDF213B71E674A843F1A16
-:10A97000B8007C8F286F67E830DDD799DB9CE5A5B0
-:10A9800039E62AA27D6E5B16C719508232DD3798F0
-:10A99000ADF9CB195F07B4D3742F649DEE27C1893D
-:10A9A0007F28BFA3AF6B9D8EE7EE0B46D33D07829A
-:10A9B0008D34CFDA9DE2FED1FA9DF1BF13A8D5C741
-:10A9C000D9F0D4C923940EAC0E45F7ABD5F953DBBF
-:10A9D00016FDBC057812189F117DCFFC4AEF43FC91
-:10A9E000C92CF0C5DBFA3846FBB519C27FD62079F1
-:10A9F00024DF0D4139487AB34E0A240B7C0B8ED5E7
-:10AA000048F75D86BEE8F765EFD6F97397AE2FBCC1
-:10AA10002E7CBFFA192948E78077FF249AFE7B42F3
-:10AA2000ABCB491F62F56A5DB399F16D156CB4103B
-:10AA3000BE8DD5ABAA217DD96EA13816AB4F357E20
-:10AA4000E932740B5CFE7F4BF77A7398F34CEBFFA3
-:10AA5000A7E4A53CD4BDADDFB1505E74A47D08F978
-:10AA600056197AA2AFEBEF5DCFED867CA7C01496A6
-:10AA70006F45DA15EE83A2F1F46ECB509E92F37C13
-:10AA8000839D13383F6EE851EC38E53A2E5FFC1495
-:10AA90007079A1ADD44EF8A2FFB8C92BA99C7F4C08
-:10AAA0002E443E4C3F2003E18DFEF6898F0790FE39
-:10AAB000A213C53752BE7CFA098C3FD8BEA7B3F8A3
-:10AAC00057E45F11E1A4917D2FECCA4EFBBD83C713
-:10AAD000E1F8DD7FBCE8F14AF2C3C7CB8A695C09C3
-:10AAE000DBE97E78911E871A8E17D97B22E2D1FD91
-:10AAF0001922DFBEC5F3FB47695FB078B7D94BF9C0
-:10AB00008EC566FFA604A4AFE805C9DB80B31DE9C6
-:10AB10003EF4248D8BF6A452BE66F1EEEF1DA2F634
-:10AB2000DA5D12D3DFDFBE287F17C5C7A0ECA5B85A
-:10AB3000D7DF7E57C1BD84730EDC537057C47C478A
-:10AB400052855F597C9599E371EF68FB2F2B29CFD4
-:10AB5000A9ED60FFD0FBEA1E0B7F57B04B020FAE92
-:10AB6000F388E7F0AF890FBDFB4E5A08E497B69E15
-:10AB7000B4F4C4F1CF467901B77161CEBF6EB7F0BE
-:10AB80003DCABD7FB0D07A6B9EFB88F369556D12CC
-:10AB9000FBA7AA67E4A04A799E03AF58483F6B9A87
-:10ABA00025C8CC8A6C37733BF951AAFFB159F865B7
-:10ABB00043EFD7E87A6EE8BD61076B74FF75D7D6AF
-:10ABC000683DBF17B42DA3F1FD7B9A57F33DA07BE1
-:10ABD000B6C7F75F861F5C4BFB528C2B6B9F8AEED0
-:10ABE00077DF907E07D8BFC7FAC95732F4F3D83C55
-:10ABF000C823FD1E0CAF19AFA03D7D7EB26A3CC4D8
-:10AC0000C93B1ED7F180118F07C3268E67B1FDFAAD
-:10AC1000DA2E5A288ED676FE99F16B79FB672C874F
-:10AC2000CAF60EBEAF7A3DF837101FAF6FB73B09BB
-:10AC30004757F608BB5FD26E0D06256A0F35917C2B
-:10AC4000FB0F8AEF3B02AF4A8CA340F77F6B757E08
-:10AC5000AED5F9B716F76763E8DE8ABEFFBE2F7779
-:10AC6000C711BAE251A33FDFD0753899F8B8048410
-:10AC70007F5A1212FEC99087115F46C6D1816F9329
-:10AC80003CD7B75BF9BEF852DD3F2D6D16DF93C59B
-:10AC9000FA8BFE517691FFDD2BE88D8DA735ADD176
-:10ACA000FDBB32D2D9DF0FEA78F813C3DFE8F2A890
-:10ACB0001C003BE5E797A8B237C86F752B347FE7D8
-:10ACC0005489CF633BD58929F1EE4B19E59B3ACEE8
-:10ACD00037EACB284F86FD43CEED8EC87DFC8D999B
-:10ACE00002AF54CD910324CF887DCFB2A2ACB8FB84
-:10ACF0001EC844BADF187BD74FA645EE7BB41D397A
-:10AD0000A4673FF23C5E49F78C6A9B857FE89B8D88
-:10AD1000E3A6108E07C6C5B5CDD620ED4F6A514FBC
-:10AD2000F87B30D20FB2BF766911E907EE1B1C9990
-:10AD300048CF723AAAC4F52F6FC3388EC32F2FFBAA
-:10AD40008CF5AA2B5BAC1BF996196F1F61EC1F6A7F
-:10AD50002E099C6A3CAF517A781F51D32EEE49B729
-:10AD60001EFA625C16D2DB7FE03FC6ADC67241A61A
-:10AD700088BFAD25A18FE9BECFE7BB6C71F1E8902C
-:10AD8000BF979AD80E6ACC3D198C57F6232E9C8516
-:10AD90007EF3ED4F79DFD17A28E14ECAC7F5ADF1E8
-:10ADA0008F777E839C1A6013E3DA4DD0C425E19E31
-:10ADB000481CB8D629EE0FDDABC749AA3F8C7A7D77
-:10ADC0002FF65D5014CFEE035BE64923EDDDF01B5B
-:10ADD000D5BABEAF2FD8B1858EE063F151B56E47BD
-:10ADE00088FC392EC6E2A21B33A3F5B4E1ED44C6BC
-:10ADF000B9FD5DB29372C4C8D75F8C26DC87F87E3C
-:10AE0000429C3CEBA7BA5EF6EAE7BE0DB365E69B53
-:10AE1000698E280D1C85FC637DE93FE908521CCB37
-:10AE20003FF8CA0492FFFA9DD1E745243F3FDFDF98
-:10AE30000AB2FCAA43763E4332DA5F3AF8CA14D229
-:10AE4000B386B7BFCC1172F922C7E2BE3C7D46295A
-:10AE50004962FF6B92C4FE77AFD2934CFBAEDAFD32
-:10AE6000B22FF2FEBC21E7BB75FD0145ECF3D765BF
-:10AE7000AA5C6F68177A613A204A9C7FA5C8F3984C
-:10AE800079FE11ED25A82FDF10B780E842D9D79AB7
-:10AE90000758EF6A4F9A989EDA938319D911EF05F4
-:10AEA00068DC4CF27B0D1B80FD881DC8BF2EA5EF12
-:10AEB0000FB1BEF4FD04C65947263C5229CEAD64FD
-:10AEC00020BFF5C0DB559323FDFF053DEE03F1C127
-:10AED0004328E70931BFCE874DB042CF13083DAEBE
-:10AEE000D2712CEEAF9AC88E63F757578A931B0E18
-:10AEF0005881F2C7B51F58F93ED0E707D6F2FE1DBC
-:10AF00002EF927939F01BFFF6A2A1F38B876323D7A
-:10AF1000FFFCE07D5773DE53DA1495AF08107D1EF9
-:10AF2000C2517F79F776C2975D0AE390A2AED3EF64
-:10AF3000D2F9EA9E56337F9B59BD77C6E38124C27E
-:10AF40004F454BE9BB9D3D9D0AEB1FE22A0347D9C4
-:10AF500019479D28661C85E3F8825C161FABA47117
-:10AF60004F9414533709DBC99F4D271CE518C6556C
-:10AF7000063DFF9C29F8D9DF91C0F9130926083D49
-:10AF800083EC28BA37B4BECE3864439B1CF5BD862B
-:10AF9000F1DEEE4C71AEB0D7D0B390A4B11EED1679
-:10AFA000E586B63D19B48EF5E610EB4943B359B4C6
-:10AFB000EF1225D0F9CD0CFED83840FC39468F5021
-:10AFC0002E4B2CC1B184DB770F9D07EAF73982E263
-:10AFD0005E5D63E744FE6E68B0738F3B5EFC394E86
-:10AFE000E73348DAD12CB1CF896DAFF3887CC6D175
-:10AFF00033C22F1E5DE89F1CCF3F06A044ECFB250B
-:10B000005D7EADE68A78E7861B3D22DFB4736CE097
-:10B0100028E971EFEE043E37EC7589FC6C694B97BB
-:10B0200042DF9FAC6F9566503C5A9FFB1E7F9F820C
-:10B03000F562F683E1FD7C6E5ADDBCBB5C8B43C7D9
-:10B04000B51E111F97E8DF018FD057BDFD1478D3CF
-:10B05000F57DDA23745E73AAD2EC14DF9989EF4A86
-:10B060006FD0FDF98DD79B19379D02D52CCE3FC4EB
-:10B0700039C532DD2FDFA0FBF911DF3B3F039BE930
-:10B080009C22F67B67C3AFDFAC8FBF02341E37F65E
-:10B09000BBF59B753C78B32FFAF9A54C1D07E6402C
-:10B0A0000EF9F310C617BE1F9197C0717A69E1A41B
-:10B0B000B83883BE0357F5EFC0A934E4DE90F71E1D
-:10B0C000C7BFA31D677ECDDF139C49800971CEC524
-:10B0D00086E39FE13F6E12F2D6CF2DAA9D824643B2
-:10B0E000EE17700716991F33E43E46E7FFFFF13D68
-:10B0F000A05C5022F325CFCAFE311E3A9FB0F53234
-:10B10000FEC615701CC4758DD3D735CE1A11DF2E2F
-:10B110008C5A1D577F87D7971A1071C4CD65479EEB
-:10B120009571627548E2EFFBAAC3625F5B5D26F62C
-:10B13000B539AD02A7AEBC490A6A12BBC3D3449F5E
-:10B14000A13FCB6C020F187A32C42F5D7FA89DF00F
-:10B15000C10D3A3E88D5A3C9D05D4EF9E65B34C92E
-:10B160004BF72A477C3FBF6ADAEBE4EE2FA73FA8F4
-:10B170006FFCEF22C4EAD1F73DFE120FE5D3BA0708
-:10B180005716E2B847F3FE388EF4A6E63276F32D72
-:10B190008F88133B1D81A37CDFA4453FEF6FC96BF4
-:10B1A000EB217E7402E3C75E57F7963A81ABF9BC98
-:10B1B000BF3A9CC0DF4356B7DBF9BBB0EAD686C4C2
-:10B1C00029E47FDB65AF1DEB95AD27CB889F95C547
-:10B1D000E23E4AAD5DDC8BB3B9FDB7107DD77B3B5A
-:10B1E000A2CFF92D3DBFA8FB063D8FF56B1B09A330
-:10B1F000A5FFF7F99B8D3A5FEABA2E664CC1A9FE0E
-:10B2000090E6AF267DEC7FFD450B1DD7D54E79A589
-:10B210009CAE886DF4A8DCEFFAE68E264AF31AF4A9
-:10B2200077643AF9F95173702CE3D2822BBB0FD3B8
-:10B23000B0FF8DA914A7FA3ABAA65A22F4BBB70EEA
-:10B24000FD731CF9358049B75B854B495AA1E3254D
-:10B2500061C7B5070E67503EA297ECB780CA7792D8
-:10B26000B3B1ACDE7D2A7912E196BDA21CC219ED04
-:10B2700032F703A527E7E6A448FA36337D17426282
-:10B280001C809E9C1B0B23DB1BFF5FDBFFD3A427D3
-:10B29000D5B69E28FB37F884BB7CFE3E3770D0CAFB
-:10B2A000F708E8BCC61521C757747F340B374B64C9
-:10B2B000A773E87C7A22413B05EEA0BA026125958E
-:10B2C000CE8BC3B2B87F3796FDF74C7DFE594AB896
-:10B2D00083EEE9CED1CF37E74237F75B00035C6AF4
-:10B2E000E0E4EF8B4BC0CBE56C5B7829C1F1825079
-:10B2F00088BF9F096728AE7336FD3BE638F21EE62D
-:10B300009B02E70C7EC8740E26EE1BC5AEA75BD76A
-:10B31000C7599AF03B041DE87EEE6C08F1B9FB3585
-:10B32000D0A39FBFC75FC73CDCF7D1B9DB35683B13
-:10B3300089CC8F20F79F4FEB91E3ADA767298B193D
-:10B34000CA9C449F14CE307D6DBFF275F4D36D4D11
-:10B35000CA57DF35D0F783E2E1734B6FFB1BEFD3A6
-:10B360007D6249D3F8BEB197BEC7A67D4E58E91D90
-:10B37000F2631300FEDDB3E637646FC6F71AE00729
-:10B38000BEE711FBBD062DF77CC6F03D35E3FEEDB3
-:10B39000CEE00A95EE6FAC72DBF8DFAD29B28D9B83
-:10B3A0004E79CA87D2FCBF21BDFA406A9EC4832869
-:10B3B000C1198C6375BDB283369BD62F69C6F7223F
-:10B3C000C0FA32F4EF0164007FB763B78AEF691EF9
-:10B3D000413DB4A5B2F6AB740F1A1E2E55092F6F5E
-:10B3E00071D9BCF45DAE95E8B50FD3DB6813F72FC8
-:10B3F0008CFB6BB17C6CB419794AAF8D7176CC77CC
-:10B400003E77DAFCFF9BE8BF3FA924937060FECB38
-:10B41000F33D7C3F29C15877898DEBC3F71A193763
-:10B4200036D17D6AA4AB311DF81EE2E1A49C14BAAA
-:10B430001FD5D825EE5337A607D87F9BFD12FBF307
-:10B44000C6CED24E8A07830E0BDFAB6E74F934AAD8
-:10B4500007D22144FE9FF83EDFE0BB6998EF21FD53
-:10B460005E5091EDD75751DE7F9A1B4AE9BD696165
-:10B470006D12F1C0F81E06E5E019954ECFA3EF7BE3
-:10B4800081E2E4FB17861C503158999DBA7C0DB9B6
-:10B49000388DEFF83525EA3B7E435E8F240AB99854
-:10B4A000E926CC447E57A57163E561F0FDBF008FAE
-:10B4B00040AEB13049000000000000000000000074
-:10B4C0001F8B08000000000000FF3B24C3C0F0A356
-:10B4D0001E81EF4A313030F1A28AD112EFE364606D
-:10B4E00010E062603005E2FB3C0C0C3380F44C2031
-:10B4F00016E566601003E21A20DE0DC47B80F819A1
-:10B5000050FC3910EF00E21B3C10FDBE4C0C0CFE51
-:10B51000401C08C4C140FC958181E11B03F1F67316
-:10B520000A33304C1547F02F03D99F24E9E7FFC1B8
-:10B5300086430CE96BDF71A07DF3AC107C46207B69
-:10B54000BE15AA9A0556F8CD588826BF088DBF1893
-:10B550008FFE720354FE5A4D34B3B581E90949CDCB
-:10B560003A4DFC6E41C7AA40FFA9013100ADF15F21
-:10B57000CA68030000000000000000000000000096
-:10B580001F8B08000000000000FFE57D097894D5BE
-:10B59000D5F07DE75D66269999BC816CAC4ED844A8
-:10B5A0000B7442421A10DB618B6811834B051798AC
-:10B5B00008644F2620F5C7DAEFCF40005151438B86
-:10B5C000355AB40304051B34D88041020EE0822DA5
-:10B5D000D5D86A5DDAD2A0C81A93801BFE5DFCCE76
-:10B5E00039F7BEC9FB4E2682B5FFFFF5FBFEF8F822
-:10B5F0005CEE7BF7B3DD73CE3DF78EE218C7948B1C
-:10B6000018FB12FFBEC798DDC6181BD79D32562304
-:10B61000D24A2DCFCD58D003FFCC62ACDCAD85979C
-:10B62000A7333665871AF95E12E43748613BE46D4B
-:10B630007B9D54DEBE9EE7236ECDCFA0FCA33AC80F
-:10B640004BD0DEDEF2C06550DEB943661BB1DB9144
-:10B65000713696C2D83107E37F5990CF66ACC0C926
-:10B66000B3E51BF6CDC5F6454D76E684FECA7715E3
-:10B67000CEBC0CF28507558655CA372FD3FA43BE88
-:10B68000382C3560BE63329F5F68A71CDE0CF53B2B
-:10B690003C2D2937B8183B55E5605E8DB16A774B74
-:10B6A000CAF5A3182B096FCFC57625F5920F973AE7
-:10B6B00065C7E697FBE1BAB64A3EBB97B1D22DF11A
-:10B6C000CC3B92CFE14BF8FF58A31CF91E942F8678
-:10B6D0007532E8B790D5E43219C75FAB79DDDDF09C
-:10B6E0003B55A5D33846BE7C2B8C03ED2A9E967C19
-:10B6F000B8C40A1B0B34C0F8EDBB9CB337B9707DDE
-:10B70000CBB4116E5CD7DD1AD62B0CE7EF747A71CF
-:10B710007E1BB45C282F59BF412B18D5DD5FE996FD
-:10B72000BED679D50E4D0D98CAA3D353558C794703
-:10B7300074E74B18F33740BF4C096BB346777FFF74
-:10B74000802532968CFDCBCCEBE8EE1F2049DF4301
-:10B750006FC13F015EA13D6E82AB81B7C53AFCDB94
-:10B76000DB8DB7B3BAC0A3D2996DEEDF481F403C62
-:10B77000C07C6A104E90AE11F3F34C649314E8DF72
-:10B78000E367BAC47A5F8F91D6A82C9FC1580B4249
-:10B79000A3FDCA78C86B6C11F331F69315D9FEA9D5
-:10B7A00090BF9F05E6E2BC57488122C413630D6930
-:10B7B00048BFAB24361BD7FF039C3494AFEA07F491
-:10B7C0000970AF9996BD4996C4DC93305FF0C4BD53
-:10B7D000E9D44F21F5A3423F43CFDF8F9E9B63E91E
-:10B7E00047CF2D32FAA9A47E9C17D64F4DEE04EB1D
-:10B7F0007C724B8C7EEEA47EDC17B62EFD8A89D639
-:10B80000F95C5146FD244EF5B100D4970D7A602DB8
-:10B810007E19CA5DF58963EF6566BA98BC12F9DFD7
-:10B820000D5C62A68B849C380B1D26FAFB58F2D067
-:10B83000937EEC5B220F834412351A5FEBAF915C71
-:10B8400098D4DF41F93BFABB482EDC312170B10EB0
-:10B85000F3C0B1593FC86B816FEB31E81AE629B1EB
-:10B86000344CBD364CA3CBEF56391C260FF8DB8881
-:10B8700023D03E68EB1C9108F9F5D2A45F205C361A
-:10B88000331BC1274E6695582FCECE483EDD9D9E78
-:10B89000BD296482D3EA41807FA9BBDFD56A200D30
-:10B8A000E96B2BBB2184F4B66A10ACA73F634F85CC
-:10B8B000AE8F8414683FA8200DE169D780BFCDE327
-:10B8C0006B30FE281AFF191C77078E3FAEE7F8F69B
-:10B8D000213996F11D838B2CE33B34181FE87D172B
-:10B8E000BB558C0FF09BC0D8F3A15B687CFBE022BA
-:10B8F0001AFF6E8D1559C68FEB1AFF051CF7A5DED2
-:10B90000D63F648275FD834BACEBD7F8FA5F650BCD
-:10B91000C5F871B4FE5F8716F0F50F2EE1EBB7F3B3
-:10B920007EBBC6F774C1FF751CF7ADDED63F74A2AF
-:10B9300075FD179559D76FE7E3BFCBCAC5F82E1A27
-:10B94000FFBD50195FFF456534BE660FF8908EB499
-:10B9500001719561189F0D0486482519E5A7746447
-:10B960001FC6A0FD3A3684E070471CA7BBCFE2801B
-:10B97000DE5CDDF28E8581A3409E55089A2FAD9F37
-:10B98000A4A19CA572907B0BC5541734C9B4DFB039
-:10B9900075F6F070986F7B931CC2FC827597876573
-:10B9A000DAEFD8BC3C6CA7B0087EFFF0A1D11BCD6C
-:10B9B000EB8A4E17D6A8C75A2D7CC4E7139ACC46FB
-:10B9C00056C2FCA621118CEBCE1F0339CA407EBEA5
-:10B9D0000F7214D3E32A8C07DF8F829C659A996FCC
-:10B9E00096F17D3CC4DE1C99827282FF1D5338BCE7
-:10B9F0008F2D91C208FFCFD62ED2503E2DAC890795
-:10BA0000A077CF2328F0D4B9CB1EDE28113CBD0887
-:10BA10009F1B891519FB33A0B51F80B6B0B6AFA523
-:10BA2000DD2D2CBC320DEACF5F933F4887F5DF3C1C
-:10BA3000DB3E56C6FD83F907D8888FD9005B0E63BD
-:10BA4000B31BD7AA032073E36CF5FD5653FB3901F2
-:10BA50006BFEE6226BBE5D0DAB36D4378A25B60190
-:10BA6000FABDB5D25A6E8C9328F5E17815E3FD2026
-:10BA700085CFF7564CC7E2679DF03A57E76D8DF9D1
-:10BA800004EF525984F6CBD66446F84FA67A019D4E
-:10BA9000AF3B7ABE7355873F0FE633F74E99E019F7
-:10BAA0003DFFD6BDF17EDB18486B3F569104A3D70E
-:10BAB000133DFF794BA3D7A3931E961F8AFECEE9B1
-:10BAC000249A9E824D93FA1E35D52B6FB8B2EF5152
-:10BAD000137D956E9965C91787E758EA17D6E65B17
-:10BAE000CA17D6145BCAE7AF5E64C9E787EEB4D461
-:10BAF0009FB77499A5FCD6CA7B2CE53717ADB5E482
-:10BB0000E7041EB1D4BF71F6064BB96DEF25D720FF
-:10BB10001F55BF2533DC373E751D7B00F5C14F5DDA
-:10BB20008A0FF171A22A8DF8E0549597D2F6A64CAF
-:10BB30004780CBC1025471162E6B08AD9E88729956
-:10BB400091FC2C5EB633141A08DAADE425F8C9B5B9
-:10BB50001A8B00094BAC4F171D77CAA6F2D6F39487
-:10BB6000D702A367F62C975B637F0F6ECCBF08E507
-:10BB70004E6FF200FE06E03ED721F6F7E8F232897A
-:10BB8000E599BF33B69CF8FC9C90B3651A9707659E
-:10BB9000CFF69BCC3C988F8CA8FCAAF11A00A82861
-:10BBA00027513B4F467A002EB0D0CB500B7FB7EDDC
-:10BBB00093695E152813C6A3C8C95B23A19C891C81
-:10BBC000187CDD689C87FF7E09F9AE2999F6F5B6E9
-:10BBD000AAE97D8F2A889F3C4A4F54CDA6F4585538
-:10BBE00080D2A3554594BE5F5549696BD5524A0F23
-:10BBF000578528FD53D56A4ADFABAAA1F49DAA5AFE
-:10BC00004AFF5015A6B4BDCA4FA9C10F5DF237490E
-:10BC1000E8ABC2AE809D87F267C55A5640DD16E29A
-:10BC2000735F1AF2F959D76723501F3FFB8E9DA10E
-:10BC3000BEDF1BBCA2E9AD773CFA495F290803FED1
-:10BC4000337B963BE3389E9C36369D813CBA67F841
-:10BC500013BEDB46515E4192810DC937CB1DA3DF78
-:10BC6000618CF0753E3C317FE7986B011FC71EFD6C
-:10BC70006B36F67B4EEC7F710764DA875964930F5D
-:10BC8000F165821BED6B9D3B84BC3F0FFC3EEA825D
-:10BC90005FCB6006E9044927FA3BDB68670AC2B15B
-:10BCA000393E0CC4CFCE1EDCE4417E5C9C66D38F53
-:10BCB000C68083919637A4EB2EF3FED364CD9FAD5F
-:10BCC00091A637903CF6265C3F1AE94AD78F0E437F
-:10BCD000FCA7516AF4B3384DD38F02BF9EDA3234D9
-:10BCE00081EFDF61BE0FD62712BD825D48F5FFD51B
-:10BCF000F3E9AD1F633E8C35B20F1C280FA06CE832
-:10BD0000F9ED9D1E78573ED1F2105FCDEA67A82F5E
-:10BD1000C4C1FF5F0EC17E15CA1BFD061BE490FD6A
-:10BD2000DBF8BDDE321EB4F31A3637B6EB9D6E1566
-:10BD300076CCA02B90571A1ACB64273A75EBBE929B
-:10BD400068C9079BFAE9967D06FF01FC0F82524104
-:10BD5000BA291354D4A1B8564B30BF23283F012F22
-:10BD60004189D72B77B46A012F91630BEA19B7E5A4
-:10BD70001874E7BDF18F20EF4FFE4665F762F9DFDB
-:10BD8000605650AE1AC520F76C909F2F72B735964B
-:10BD9000CE40B977D2C6F7F9052CCF83464F11AB09
-:10BDA000C9463DE723669B8EF4FF11FB9D27D364B4
-:10BDB0006FF86C1AAD73FE6AEB3E0BFA99255F586B
-:10BDC0006BCD17B06B5390DE0BD6A92C2C215F5A8C
-:10BDD000CBBD369DFA2D6495ABC8DE417B05C6BD53
-:10BDE0004D67CA00985FF9738F65E743FE3B36AE37
-:10BDF000A71BF67B711F3EFF92A4B0E687F20F1AD5
-:10BE0000337F7019C3F6E15528A7426EE6DBCC7A82
-:10BE1000E2EFEBCE3F7ABEC67ED2C38F20E6216F23
-:10BE200091FCE11876DA349B24F4AD10A537E0BA22
-:10BE30004D7A6BBE8083912F8FCADF1995FFA7E9DA
-:10BE40002D8959E8ED8814C8B72573FA427D41520F
-:10BE50003AB5C037E93FAD47FFE5FFD2FE0742FFE5
-:10BE6000D996FEEFFC97F63FACC7FC57C6EABFFC7D
-:10BE7000B96D3B43206F4A9E79C8C3601F3AA9D46D
-:10BE8000A4F800EF659B577A900E4E28210FD2F34D
-:10BE9000C9B03C3D163DEC467A203FA2DF25A15DAE
-:10BEA00085FF84FE4F3D75DF4CDC673EDBACEA640A
-:10BEB0002F6DB147ECC0AF158DC533D818CA1FE13F
-:10BEC000F9BBCFC8986FB2D267C9930FA5A0FF0D79
-:10BED0002845D81311D2972AEA3ECCC57D28C83A06
-:10BEE00089CFA2DBE1F8E7FA907CCCD7127A96C32F
-:10BEF0003C49CF0F0AB8041BEF3B23A3EF93B57265
-:10BF00003F6854FD22A1FFD4DBDC49C7C07462DF67
-:10BF100061DF417969C08385B9FE53BDF5E13147E1
-:10BF2000603E6D75BFF1482638197C76B661FE2FEC
-:10BF30009EF7F62E8FDB859DD7DD2E4CEDBC4D4256
-:10BF40006F6BE669991AF1A05E5CB641F585E07306
-:10BF5000D9B64D4F3C8A76EABB76DF70E8BF74DB1A
-:10BF60004B7F9800F9D2ED6AD20CBE0C9794D28D1B
-:10BF70009720FCBF746C371E4A7EF592E61DCDBF3C
-:10BF8000FFB84F373E4AB7EFD3D8E89EF098D2B00B
-:10BF90004F6B75C5C04BC3915CD4AFAAB77EAEA141
-:10BFA0003D7972AFC452D363C073C34BA427209CA6
-:10BFB000088F024F5D788BAA1F04BCA03C37F01499
-:10BFC0005DFE80903FD89F7714D1F3D3CFA35FF964
-:10BFD0003DBB0FD75FF4F4ED1E5CC771A592D3F59E
-:10BFE000632B53FC306E911A4AD129E5DF8B1EFF7B
-:10BFF00021D15BE11B3F4CE1F6A0BF9F8DF6A6501F
-:10C000003F5CDFC2F537D0FA0A5880E8AEE8313934
-:10C010002F0CE9A70A9BBE3D065F64C89C2F8E6F5C
-:10C0200004850BD6771CED12F4B3FE4E0E6F267FFF
-:10C03000C82286FCFF43C33FCE1653FE5307C79367
-:10C0400043B609BE026DCF4CAF7577B7207E4E0D5B
-:10C05000F2A7A21F2DC894908087F425F42BBF313E
-:10C060002D95E38779956CD10EF48029F81DEBB7F7
-:10C07000A87EE7184B3BF6657AF7F84BC4F830EF2B
-:10C0800038DCBF8FA7B0A28618EBBB5536F81EF67A
-:10C0900071137D99F89BF37BDD3D9CBF0D7E0FCF27
-:10C0A0009A8EE59FBCC9F907DBE1FE08F38AA4522A
-:10C0B000F9BEEB259207761689C5D775AAE06B6B9A
-:10C0C000B94127306F454A30D10BF6DF87E04FFE8C
-:10C0D000B38275D0CE242F83389EA7677F06DF16E4
-:10C0E0000AFE1F255BF99FADE77CDFBB7E15A27DB5
-:10C0F000AE4C0D3FF128F22BF067C88BFCAAE6E1AD
-:10C10000BA4FD71FF8C34DC0A7A71B0C3EB5CACF67
-:10C11000683E2D7A76B384F419CDA7A78B401B898E
-:10C12000C5A7F03D269F16B5FE3F959F06FCAE8F36
-:10C13000829F210F7B8363B43C3C63F3123CA3E5F5
-:10C1400021FCBDC9B27BD29F417706BD95FCB2FCF4
-:10C1500022F217187469D05D175D1A74D7C3FF6295
-:10C16000815F74F960A405A093BC5D2AD95565CDA3
-:10C17000FC3C0CDABD3C208BE0E4A76D8CD5BC3CCC
-:10C1800020C99C0F47E51BA2EAFBA3F27951F503F6
-:10C1900051F94A4BFDB2A6031A23FC472CF5EC4B90
-:10C1A0001F651FC4B0878CFD26D878460B215D0C17
-:10C1B000ECD450DEA9CB410545FFE01E99ECC50E3D
-:10C1C00080F12A18A7A33E3D1C02B9B1D2C9EDF0F7
-:10C1D0000EBDD3D307D295893CDF99ACAD42B96788
-:10C1E0007CEF74723F47475EA727D1E4A738D22C73
-:10C1F00093DC6E0DB3E9B1FC20B0A310DE5B596F88
-:10C20000E5DCFF394D760D5E8AF6688DEC431377D9
-:10C21000C1B21B3DE82AE9681E7ACD6CF8BEF05524
-:10C22000998E553AE23C63705E2CE457FA99EC899A
-:10C23000132CF4B389E8CF6CE676C5823551FA0841
-:10C240005B43F454E05AA2A13C053BE07DAB3F9731
-:10C25000F34589E8AF68BDB5DC688F275A68DF957C
-:10C26000D459CB03C23EDA65F04906CB2039838628
-:10C270000FDAE7422E4F93475D331BF0D1715066C2
-:10C28000789E79B659267C9CADE7E7972C944CFCB8
-:10C2900056C13A491E1A706A437ED27A97576D3B4F
-:10C2A000FE9C7D17D2CDCE3F8EF939A46D3BDF1DAC
-:10C2B000B11BF3CFBD3DF88FAC67FD297B9DE43703
-:10C2C000EED8EB267AEFD8F3DBC177617E979DFC41
-:10C2D000751D7B3F1F83F4D7B1DC5E84F2AE631023
-:10C2E000B787AAF77C3EA695F6D71584B7A3B2C642
-:10C2F000F5A3E6BF1E9692308555A1DEB0379EF8B5
-:10C3000029F8BC93FC0B1D7B3ECF0EB8FE75EBA944
-:10C3100010E7391D6E36FB599C5F22F78307778F34
-:10C32000DFB40CCFA31BF769F3A17CCA0B7F1F837B
-:10C3300072B4E359AE0FB5ABAD8FE3794587FCE13D
-:10C340003215E0DC8E4CD59FB1FB94119343A36270
-:10C35000C1E5EFE437B95078680AB74FFFFDE12136
-:10C36000F9B9BC73871D12AEFB8BC37F44B9B0D73C
-:10C370004E7469ACF774C332D257CEB7EEE1CA7FC0
-:10C38000173AB8D0754B910B59F7D47F737CFF5A8D
-:10C39000F6D2FCA2F9A0279DEFB983F2DBDC3E9A2E
-:10C3A000EF05D2FB82FF69787F16F0EE39FFBAAB5A
-:10C3B000FFCDD7DD3BDE5F9D2BF0AEE3797FF085CF
-:10C3C000BFD3FCBEAE9CDBF4DF94EE0DBDFE159B2F
-:10C3D000F7CD0CA83F9DD5B850B1B8B27CFFAB19D2
-:10C3E00050FACAC0038938DFC951E73746FAA6C2F6
-:10C3F000EDA6C9928DEC419628097B90DB51038410
-:10C40000FE30604901E9210306DECFF506C5BB0E0B
-:10C41000CF1F5F193CDF47B1146CEC3B01CCEB97AD
-:10C420008BBCD59EFCB9C4FC78343A60F0F70FA2FF
-:10C430005E3B70A04C7A2FA4A4EFBEE899CEBF97C4
-:10C440006916BBE74AAFD50ECA4DB2DA4B53457FEA
-:10C45000D3189FFF3497140E031C260FFA6912FAA3
-:10C4600047270F579904F95C165881F6C55497B5BC
-:10C47000BF063CC319F7CDE168570D380E599787B1
-:10C48000701C24939FF4BC70C47913DC32C2182F43
-:10C49000C3141F87639F721FF99D85BD4D474D9043
-:10C4A000575CAB5A909F15B497391CC8CE36ECE553
-:10C4B000DEE0CD84FDAD88210DF82B0365BFD3DA16
-:10C4C0001FD9DF065EBE2E3E0C3C7E53BCBC1B85D6
-:10C4D0009781AE450AF2EB74B417FA62FD0C9E1F09
-:10C4E0001852E8DC4DD80B57781729A4F70CCC501C
-:10C4F000105F858EA6ABF01CC4E193681E17B7D9F8
-:10C50000687F70644904F791B50AE5DFB0E9E3108C
-:10C51000DF332F7BEEF49D0CFDE67E8DC73DE5F10C
-:10C52000F38FBF7DF9E5448C1714782C84FFAF4658
-:10C530003FFF7A168903382D545828A10FFABD25DC
-:10C54000F6BEC5EF6DCDE3DF7753BAFB395FFDDE95
-:10C55000E4CABF3A7D0EE4D8FB00F35D980EA3E178
-:10C5600015B35DFD9D660EAFE021161EC2E32AE401
-:10C570003CD339E11D82FE9FFBD3B39968D74EEAC5
-:10C580001895C0E5EB30B21782C25E38CBBC093ECD
-:10C5900017CAD7A10974FE795076C78A2BDC2AEC1A
-:10C5A000ED5F627C09A41D75AC4646FB8D75921F3C
-:10C5B0003754E7609B63C4B7E4AB869F4AE00DFE47
-:10C5C000E46C3C8FE1E32F84A60966BCB5CD38A9A5
-:10C5D0008CE98907FC7BDF741EF54DE18BF63DC2CB
-:10C5E00077ABB335372F86FCB85DC06FE6FE2FC83A
-:10C5F000FF7969F3061BD2EFA57536CBF96AA92A34
-:10C60000ECB1B16C2CCE6BE67EA73B0BF17250F611
-:10C61000613C67B0F98C1688712E180D4FEC1FFD28
-:10C62000E95B559DF86BB7DA301FE1BAFB2307438E
-:10C630003B7A9756531A6B9E03EC7C9E0B59C3EDC5
-:10C6400063D2FFFDE03BA9C315998CF6671D137EED
-:10C650008F68FA6344C767B7B030EEAF68AFA25CCB
-:10C66000385BCF687F0790DC8F7637F0FBF7CC7EA6
-:10C670009C8B9BB6FF12F5828A6649C723860AA562
-:10C6800055433F6DB02951C67D38C36BC4BBEAA387
-:10C69000AF37F1C5565521F81E98B0FB661CF7E37D
-:10C6A000368DA19EE27FB1D383FBF8C7CD99C40735
-:10C6B000BDADEB5755ECAAA948372A9787D1F4307E
-:10C6C000AA3ECE92BF4C0EF447FE9A696F5DE28B94
-:10C6D00081BFEF6B923817BC40F916FEFF4CBEBD10
-:10C6E00069C8B7809C67E2A3BE5A0FF9961A4BBE81
-:10C6F0002D96BCA908F7C57B86A6225E17BFAA2681
-:10C70000C7926FDBAAF839E733224EB9A311E4DBF5
-:10C71000B74DF2AD11E45B8C7890BF5FA87C0BFF46
-:10C72000D7F0DF36946F31D6AB6B56F936A6F908E1
-:10C73000C9B7318D364B3CAF5D3B9F7C9392AF4781
-:10C74000FDF8A0EA8B8F413FDB843EFE8C884BC412
-:10C750007150CEE56A3A8D7FA172EEE20B9573FFC0
-:10C76000457036E4DCE21D8CE29C7BD22197738B12
-:10C7700077819C93901EB99C5BBC8771BF5C947C55
-:10C780001BD943BE31AA5F11E1ED834DE90FDF02F2
-:10C79000FD8DF5AB3E07D41FDB2DEFC699E55DAEF1
-:10C7A000A610DC7AC8BB831726EF76087907726C6F
-:10C7B00008CAD768FAF0355BE3C1778F3F5EFF2B7D
-:10C7C000E497DFCA74DEF8868D9F0FBD36FE7816BB
-:10C7D000D2D763623E8B84DC6BAF0A51FF535EE4B9
-:10C7E000EB2B77F138F18A46AE1F56D44B612FFC04
-:10C7F0003377C2171ACEBF788FC452213FCBCEEB0E
-:10C80000B3278DF3323623C3440F0B724AC9CFBF0F
-:10C8100040610EF4E397BA724FA2FE5B9AC3FDFE2D
-:10C82000A5E27BF1ABADABD0FF5DFC8844E7A5464C
-:10C830007CAB11E7DB236EA27919F977A3E32766B6
-:10C840008AB8A999BF94C21B62C47F946EB1E67F77
-:10C8500022F86F96DC4AF062AFCB31E3388C7A5D18
-:10C86000703A28E05427D37EDA0527809B37BD270E
-:10C870009C00D3333252BAE152FC5B586F56EFEB57
-:10C8800035E016BD6EC37F5D2AFAE90D0E069C7B6E
-:10C89000AC5FC01DEC029293D1F058A775F9B53387
-:10C8A000314E09E886E44CE8D70017182F6FD27094
-:10C8B000CB7D974705FD64D64C9A82E10CB330AE30
-:10C8C0001CCA0B6A17BDDC0FE031EE1DEF58DC4EC1
-:10C8D0002F9B600FE039EC566727C941830EDB358B
-:10C8E000AE071C14F0DDDDBF7232D9F94D928E7A9D
-:10C8F0004830E224B80601AE78FF28A870FC068113
-:10C900001E91FF0E3CF21987E31EC98BFE9D5C63EE
-:10C91000BF42BC40FDCC668E97605822BC64B14ECD
-:10C920003A7FA9A8957C11845FD306829F219FE15D
-:10C93000CF65C693897E9558F44B954CFB65A9A8A5
-:10C9400037D35EF307A4E7994FAA6C03811BFEFB64
-:10C950002A7A3E4F1C50349EDA04BCB6213C5D0856
-:10C96000B74EAE7745BEA0FB504679500959E03925
-:10C97000E5D1735F09AF7106BC908E51BE35E7CB30
-:10C98000982F689258DFF49EEBC5F35033BF17EF32
-:10C9900039C2FB7F4CF2B118EBBE60BAEE859E8BBC
-:10C9A000806EF1BCA437BA8E86533BD2F3B7BAE996
-:10C9B000F93567E7A14CA4E73D12F74334275ACE77
-:10C9C000353D761EF7B5D509740FEBEE7C55F56D48
-:10C9D000F4C690CB82EED17E30DF37BB041782F1F4
-:10C9E000A25B1C14EF47F318C2F553B37CDEE66478
-:10C9F000C9D767F5DEBFDB2EC58C2737F423233F6D
-:10CA00001AC7C3F8F926186F64F778D1FB83E12FB2
-:10CA100038DFBAFADBBFD9BA8C71BE6E3C5490B520
-:10CA2000105E8DB8A82352E0472AEA73D3254BFC49
-:10CA300015CC5CC8AD6FDC7FAA96DC7BFF2C4DA7C4
-:10CA4000FB74B7EBC6779DE8334F67E27C6FE2DBA0
-:10CA5000B8EF7FECE7E7985936F6D644DC3F26ABD3
-:10CA60000CE9EAE3432AF9A13F9ECAE36EAFF9ED70
-:10CA700001055D3ED7F0983876CD3889ECAC37B0FB
-:10CA8000EBF1A8873B987F04C12F13EFED65D4D558
-:10CA90004CF1025F8FDD12AEC6D437A533E935C441
-:10CAA000DB249921DE5AFC7DA7B8207FFB872C036D
-:10CAB0005DA0A01F50FBB1075932D69BE04F263333
-:10CAC000667CE3276F5E07F3187F48F679A1DEAC3A
-:10CAD000032E17037D7AE47A1B0B98E0358185AB32
-:10CAE000D1DF34FEA8FF3A9C7711E83B784FA4A829
-:10CAF0007943B507F3EB256A1F0C05723DB09E6DB7
-:10CB0000B56772BF857201EA6137C1F5BC5EB04E90
-:10CB1000F261887241F35A8A2F2AA893E842E1B65B
-:10CB2000B0C41CBCDFB003FADDB61EDA67E1FE0557
-:10CB3000EDB1DFBA336F5E877207E649EDEBF9B905
-:10CB40007C01B4F322BFD42DA2FE8AD74B0CEFB3E5
-:10CB500014D5F37DA9E890EAC3F2C67D8FD07E3B61
-:10CB600003C6EB978EFB50642ADD0BCA9474BA2F70
-:10CB7000191A4CF8EB601C7F6CFA20F20B52BCAB1C
-:10CB800097C0A098E363FE641F42F2B3C0B74CEBBA
-:10CB90000BFDBC96939C6E23BA3A43E7ED4701DE4A
-:10CBA0000180F71B225EE540CE075AAB695FFCC2ED
-:10CBB0003E949F9B344DA2388E852C8FE238668E32
-:10CBC000E7FAE6EB973BC3E8E77B5DED1C88DF0FF8
-:10CBD0005C6EA7EFEDDBB81C6E1FD44AFEF6E3EBEC
-:10CBE0005586F758AAD7CB242F8ED7AB743F567EE5
-:10CBF0008CC731146EE3FAC781F5BCDFE3A8B7E157
-:10CC0000B9079643BE70AB11E7C0E5B4617F16E883
-:10CC10003CFEC290BBE562DD3DF6A175CB3424D964
-:10CC200068795B2EE471098B90BD1C2D77CBF11CCC
-:10CC3000DD837C191D27E6EAB663900E225F105D46
-:10CC4000571C5219DA31D2076DB91497B647A2733F
-:10CC50008BF1CD921FE31A8ADEB18749FF0EE7CF31
-:10CC6000FB11EE2FEFDA19862C1F433C809CCAB1D2
-:10CC700077FEE9A7F0FDE41B0E8C0802BAC927B8BD
-:10CC80001B71BE599B793C4FD61BEB52F03E2F9B3C
-:10CC9000DA97E44061ADCC0226397152F25F771326
-:10CCA000DF1F74D4770C7C66693505B8BF7ECBC1B5
-:10CCB000F755EF66156364D8EF843D04F6811FF5E0
-:10CCC0009BE25D6B5334131D14EF599B22C3F75540
-:10CCD000221EA61AF7576857ACF1718AF74AFA066E
-:10CCE000D338463F46BFDA2EDE6EE81E9EF6D67F6C
-:10CCF00031CE8FD6F9A986F222BA9F1EE3F7D24F22
-:10CD0000CEEFCFAD93605E39AFCB14AC9EF3C18C48
-:10CD1000A1E6731D2335FCCAD96FDA98DF04BF9CE6
-:10CD20003FC531BF09DF8DE380EF017F5737496190
-:10CD3000A784F9235A7916E575E4F30AE17FAE98E2
-:10CD4000CACFEB1A33DE58817C3F234B227A60A195
-:10CD500080D63789F4352FFAFD0BB378FB42688F04
-:10CD6000FCD8F808E74F90135E942315EBD7E652F2
-:10CD7000FD3AC98BFD376EC8277DA4284766545EEF
-:10CD80007784F4A3A2A62349C8C7C0B7EB501FA855
-:10CD90009868D7518E1BFC68F0F7EBE23E2B73E8E6
-:10CDA000A3F17EC6FF46E68BC1D7F2212ED783F5CD
-:10CDB0009C1F83399C5F5FDFA6E20A2F84BF899F97
-:10CDC0008F6FE1FC2A3F76432EDE872FDCCCEFC34A
-:10CDD0001F583F45437DFA7858A2FDA6277F73BDB3
-:10CDE000359ABFAB25BEEF7D5DFDD2E06F838FE14D
-:10CDF000EF6A1CAF0CF814EF4F46F3F54CB5E10F9A
-:10CE0000B7C37CAF791AD603F39DF2DD3B3DAD2667
-:10CE10003909F914CC17283C9ECB902BE50A8FFBDF
-:10CE2000FBDAF38B1A3F6CB7FA477E674FE4F1EBFE
-:10CE3000752AD1FDF9F8B3079F5D207F5E285F9DBD
-:10CE40008F3F8DF1E53DD67E7E27E82DBABF7680F7
-:10CE50006B04E0FA4AFD268AF3FDE8A92333113F6B
-:10CE6000A5BB81CE91BEEADD2C82724E09D37E55E0
-:10CE7000D228D33D01A644B2AF739BF998C76D95F4
-:10CE80003EE3267A2A79D61E9E01ED4B767E3086C9
-:10CE9000E2689677525C5AE829A12F875AC7201F6B
-:10CEA00094283C7E2C5A2E041CDC0FD7B62B7E36E1
-:10CEB000AE4FDAC2DF8F2869B851B59BCE256E74AC
-:10CEC000A8463D3AD70D011DE3FD5D9C9FF9DD02AB
-:10CED000236EAC6D2B9713254D2AD981255BB6B7F0
-:10CEE00063FC70C93B76F27705B79CA1FB10539E9B
-:10CEF000D946FE9460936C397FEB11B7B9458ED853
-:10CF000031EEB0B19CCE1D217F84F20DB1E397CFFD
-:10CF1000175F58FACC9E9D210061E9AF9EF4A07C7A
-:10CF200039D5B2D98370877EBF326EBA479C66C34B
-:10CF30003D5F19A7790AFF018C738F43D835469C52
-:10CF4000EB96BEA447C2FCB2F3629C7374E9E5DBC6
-:10CF50003E7D1CEF11B43D7BFA719C6FD93F3E7E44
-:10CF60001CE3C1D85E27ED77C1A7DEA2386CA3DD34
-:10CF700026B1DFB56F7D92E2D7DBDFB5FBB0B7F648
-:10CF80003DC707633C60FBF62F52D06FB964CF34C6
-:10CF9000F2EB2ED9312595C5D82F8C14E9367C01BA
-:10CFA000F1F3D1F83AD07880E2D63E027CA3FCEBD4
-:10CFB0008ABB6D28E771CC5E116F5B1FFB9E428FB1
-:10CFC000F8DAC6EBAEB91CE57E23D71FCF1B67FB93
-:10CFD00026E0F1DB1780BF7AC32F101B7F1FE13FD4
-:10CFE000004FFBA2F0F769E3C25F3C8A658D7D7B51
-:10CFF0008DB38D5C00DC8C7B100F38FC871CC988DE
-:10D00000E75F525C33E26D8617F79F4F07E3FD91B0
-:10D01000136AE75CBA5FB8C7AE63BC68C99EB789DC
-:10D020007FDA77BC417E6826EE23B4B3AE3F1E3F65
-:10D030002E8975D6B9797CAE803FC6EF7A3DF45D16
-:10D04000C4E9723A36E2777B8BDB959D5CCF36EE96
-:10D050006794D7FD51C4C376E34BCA413C1DF9CA5E
-:10D060007868030EBA90C3DD71E8B1E3A3BBEE2B81
-:10D07000087C21FE701FEA8A3387FCC0B1E4377A4E
-:10D080009BC59007ED1B78FC7ABB1AFB5EB011972D
-:10D09000FE8F683E0D5F583CFAF9E6FF75E1D381DB
-:10D0A000CA4F724F38B5FD2DB61C4F774ADFEC9E44
-:10D0B0006199147D6FCAEB1C87713B4734B483BB05
-:10D0C000EC6CB1DE36E1576F7B4AA678E5550D076B
-:10D0D000488E47CB8B0A7C2F25C67C33C57C2B9A88
-:10D0E000F83ED1F6AC3BEC827EDAF6EF227AAEA8BF
-:10D0F0003F42F1D22F6FF995D66A8A8BC07D226CA0
-:10D100009A7FDBD3FBC690DC16EFB2448F33498C99
-:10D11000136C8E3D4EB0FE8C659CD25083A6BBCE68
-:10D120003FDE29C57F23F677AA85EB83A71AE4E9BA
-:10D13000E118E30F73AAD677A160BFA4F767DCFC00
-:10D14000BD19D91347FAE51277CE3B0949986A14FD
-:10D15000AF55BD4CC477FD872F0DF15DEDBE8AE163
-:10D160007C57227C4D7E1E550F30D44BD5B4BC2C41
-:10D17000F42B44CB1B2DC9C6C226FC2F714F4FF593
-:10D18000D279476420E2F370C67115FBFD4B949F82
-:10D19000EA2F0A5B950AF3FB4B48F22D837ED9DF19
-:10D1A0003E1894E7EED97F971EF163D9E257AAB0F3
-:10D1B000771E46BB84BDE0A4F80679AF93DEF9087C
-:10D1C0003EEEA4F51ED8F1F913A45FFFC2CEF8B964
-:10D1D0000F582F20AF0A75DEC7F11D9F3FFE57D4B1
-:10D1E0009FB1318C5FF838D447BBA13E9EEC9C8E3A
-:10D1F0006713C6A05FA4F085BB66A23C2B8CE7F446
-:10D2000058F84C6AB81AFA3B96CCF3C7B60DA27719
-:10D21000254A9F7553DCE8811DCF55E0BED4FE4CF6
-:10D220003CC37DA9FD05A1E7FF52BC5355AB7ACDA8
-:10D23000F1E3C54CF19AEFF39462DE12AFC4C82F4C
-:10D24000417C84FEAAA604BA0704FAAFA59F8FD436
-:10D25000CE3B7C44C7A1FEFCFE53A43FCA83E87AC0
-:10D2600046F9BDCE21E25E39B47375D70F6A9D05CC
-:10D270003C5FD39FCB9316AAFFB053F88F4579CF6D
-:10D280007E79FD8784FCEEEE87B7AF10EFD044D3F4
-:10D29000EF46D16FE996BF5F1CEB9D9518F3A7EFA2
-:10D2A0003F9458C8867ACA7627BD7F85EF28E07DEF
-:10D2B000859D1A3FD72AF344E89D9BDD421E97C502
-:10D2C00045E8DD9DFE621E581FF3CCD1FA34BD9FA8
-:10D2D000F69C93615C59F90B6E3FE2BB7CE7E7C7B4
-:10D2E0007E9E857189F114175FFEC2FF223A28B72E
-:10D2F00047E6223F746EB7B38DC8E7DB5F1D8CFC39
-:10D30000DAA64606F7F98AF3BAF206BBF5FEBF586D
-:10D31000C7A9AADACBF0BEBB71AFB6A41739F357D1
-:10D3200027D7A35F71FA5F7212BF5BDF733A55357F
-:10D330003B13DF5930EA973862CBC577515E7C13D7
-:10D3400039EEEA713FF55D9CCF47AC2505FD3E15F2
-:10D35000A077A33C2FD9923E10FD04FB9DC63B0451
-:10D36000DE04DC8FF6AB5EB2A73135EF3327AA7C43
-:10D3700099CA30F4DF8CCC54601D1D1BCE14F467A9
-:10D380001847EA9C1D4BEE9D76C6D33A4A1CF69888
-:10D39000F79DCF09BA7A0F8DFE643E1EF28731EEFB
-:10D3A0007E354C72F88E382FD52B01BB08BF976E97
-:10D3B000999369797F45A9A17AC0A704CF62B64E37
-:10D3C000CB32C96F63BCE2A559994A267E57FE4FFE
-:10D3D00017BDCADD7866A124D20B150163B6AE9FD6
-:10D3E000E57E88A2E639107E1ACBD3151949A586A9
-:10D3F000F83D8E3550EA02758BBF5356C9504E9E8C
-:10D4000010E7F6E8EFC2B41B5E7792DC0F0D626C9A
-:10D41000783ABE07E14DD04DF053F1101EE6635748
-:10D420002A1997173374B493A550807D09F4545D7D
-:10D43000353D13E911FEFC180749A607CCCFA3BF61
-:10D44000FC05EA4140A7FC3DBFEFB270358018C330
-:10D4500081C9AF3A99F177E856BFC3CCF6C6A5713A
-:10D460009278E7681FC93117EBFEEB843C8A55942C
-:10D47000B7D509FFC8C1734497CE22A817C6BB58B9
-:10D48000241E52D728E59499FF3D599037D1A93EE3
-:10D49000D15A1ECD1720D7A2C66D20F841BF9F4498
-:10D4A000F5FB4954BF9F7C55BF069C828E8D3E7C08
-:10D4B000A76265559E801B1FCF21E006F01989EFFA
-:10D4C000E8315B9C4F9C87135CE3C46CEC581FF005
-:10D4D0005A1E974E78B92F616F27C641B3A45A865A
-:10D4E00076EF0A89EFD3F097E732B563BA83F8F0A5
-:10D4F0001E314EB980F30AC33FD5A3BE93F4AF1ECD
-:10D50000F59DBDD58F8B5DDFDDDB7CE263CF27B181
-:10D5100097FE6BE263F6FF75E552C50B6FBF86E7BA
-:10D52000B65DF24907D05BF5CCF238D433138FFDEA
-:10D53000A395BE703DD331D08AEF38A46FA0B7B8A1
-:10D5400061D6EFD174D21B7DE58B7540DED50FE03F
-:10D550007093187F6A1D3FF7BE6509F7D38179E89C
-:10D56000C7FA378BFA37390AC9DF70C4C6DFBFBACA
-:10D57000A596EB91B7FC58A6F3E91EEF51E13F8069
-:10D58000DF6E5D2A8523E9B1DED76275783F6E9E36
-:10D59000183FFABDAA00F3E6AE9663BD57C5E9D2BF
-:10D5A000B85717FD4EC5029627DE21B37E3FEBD458
-:10D5B000BBE467CDA8EE7D2CB416E81EF54FA07B2A
-:10D5C0003C97C7EB621417E2D1785C48CB203A4F06
-:10D5D00033E4DFD991DE04DCAF997F30FFAEF3EFA7
-:10D5E0008BAFF4A69AEF1D2AE7E22CEFF554ABBE01
-:10D5F00034946FEA39D05FC154D6CE0D615E533991
-:10D60000E8ADC4FC18BE49722A4D09A35C54F43C31
-:10D6100056887AAF78EFC3A8AF255DD5A567BE0E53
-:10D62000FF6F8E4B26BE5CBCD64BF7B63F8BCFDB75
-:10D6300089F4247B727C01574F7A08EDE0EBAEC68B
-:10D6400075A7F75C4FB5E6F391BE7D158080FC6F42
-:10D650003E07CE4FB67BDFF6E2FC7EA332F4BBF48E
-:10D66000848FEF4418CACF8607507C889C306304AF
-:10D670008EBF46BC6FBABA6A24A52BAA984879BC5B
-:10D68000DC8A2AAF487344EA17E974AA776F551AFF
-:10D69000E55755F92835E0EBF0D5D0FB938E617C4A
-:10D6A0007C872EF0976413F00B90FEE548ABA473D3
-:10D6B00045A75E19C177DFD840D87770597A0DC178
-:10D6C00057D319F935A13EE5ED988754AD9D41F842
-:10D6D00052F44A5608E56FC5078E225C9DDE4B2D3D
-:10D6E000EF5ADAD3C646BD7F1A056F83DEB671B82E
-:10D6F000DF2F717A8B86FBFD6A8B17E322EEBFB2B8
-:10D70000EB5D29823B98431CEEBFE6E7B43DE1DECA
-:10D71000327BBE09EEEEECE904F7FB049CEF1670D9
-:10D72000AD1678A816F0AC46B8537EA4C8FB443AB0
-:10D730009DD27BC4FBB72B111F90CA087780877DD1
-:10D740005488C9301EBA79F1CFEE1274ABDBC81F12
-:10D750002ABBF2FC08777B1287BBC3057820BA0688
-:10D76000B87BB13C44F0545D1CCE509FE341E415BE
-:10D77000847B267EE7F800B8F78D1F87F27082055C
-:10D78000CE5AD2E40B83FB237C7F4B127C1E0DBF51
-:10D79000248DBFAF6BF0776FFA71B588B7AE16EF17
-:10D7A00027221C51AF7908E0C3340E4FFE7DA4C878
-:10D7B000FB284D16F67F35E001CB1F16FA10C21973
-:10D7C000D31FC573FB3CC956B94F4538F5E1EFF29D
-:10D7D000B0A4101B98CD78682FFEA5859817F3C6C6
-:10D7E000F9AFD74A3FB2AE44BD03E97D18E96DDD1C
-:10D7F000ABAA0DCF3FE4A55759EE67CBB3FD895EC9
-:10D80000827F4042BDE63EC1876B915E687EDC1E32
-:10D810005E29E8E06EF1FEEE3D827EEE17FCFCA094
-:10D8200041373E7E3F64CD741EC798946113EF204C
-:10D830004698394E30D1D7C0349817D9365E4AE968
-:10D840009D4BF68E9DF8367E14F3237D25BE7367BF
-:10D8500098BF439BD70FF5A144E3DDD989DEC439D6
-:10D8600074313DA288F720656E4FB6C47CDFB5DA0F
-:10D87000B7DF817E99DEE613EFF3A7AF84F1E26BA9
-:10D88000DD6447F50DE4CD590879572DD8550CCBFB
-:10D89000B97C70C1BC0B4DF411DF8B5F47755D59CE
-:10D8A00080F44AF638A43FA91DEA44F802ACBDE86A
-:10D8B000BF7A48CDEB87FBC14389B1FD70B3E2B9B4
-:10D8C000BFC49375A9C59FB04EF5533B7DA255DEED
-:10D8D000AC13FB439FA956FE30F683CB447F9FC514
-:10D8E000077E140F7496726E2AC9CFA46B63EF0F74
-:10D8F000D5AA16C2F739AA4773BE0EE56B5C6FEE68
-:10D900002177189D839C0D8CD888FE2F83BE96337B
-:10D910002EE7428CEB93C6BA7E86F43E02F7019D59
-:10D92000E81EF701CCCBC334A29B945B6CE47F5818
-:10D9300025F8EC5EC15F6B045F3D807C3502DF81C2
-:10D94000F651FA13C14FEB90FF20DD129FCEF57810
-:10D95000F1BE9761C72C778CA5F71CAB5D36DA0F4B
-:10D960009477ED6117DA05FBC6EBE8F791DD597A9C
-:10D97000C08DE5590E3FC0434ACCD2915E3E732F15
-:10D98000B8E8ABE25B01FDF4AEB0A2727FA49E9456
-:10D99000C7DE1F45A753F49E80AA5FCBD03FFD7022
-:10D9A00052A513E1FC703C8FD3AACDCF26B8033E1D
-:10D9B000B6C59BE2A552675FD5F51E1F76FF702F97
-:10D9C000EF12EC12F2820D0CB16126F9502BDE7BC6
-:10D9D00064DE101B699213CB87E732F4EBF5940FEA
-:10D9E000BDC8CBCD5C5EAE9062CB4B437F37E46568
-:10D9F000B45C31D295174DB7DCA7545D3E46F26654
-:10DA0000646CFFC1EFE3EDFC1D6AE6F3E5A7F72CBC
-:10DA10000778FDDE0C2FD4830C7FC5F762AC275A44
-:10DA20003E9EB8CAD85703F43ED002CDFBF0F8AF03
-:10DA3000DC57ADFB41E1B9D5A40F149CCBA1B4A830
-:10DA4000763AF111C3D318939D7C7CFD0F3D88DF9E
-:10DA5000E3B5E27C7CBD1AC6B8A47D1BEF7A600EEC
-:10DA6000C075C1E3329D8FE33D0DD914DFC2B2BC56
-:10DA7000A4A71BEF231E0FDFEE31C73114FCD4E93E
-:10DA800047FDBF377A2C581FDB7F538DFF44BB8384
-:10DA9000F946A25D01FA5D6704F5BF9F38E9DD181C
-:10DAA000231FDA18EF33C78F18E95BF1D3CE21DCDF
-:10DAB000DF8AF73317D29DAB0F9DD7F4CE177CDCEE
-:10DAC00063E833C773D247459C35C07D96C57FCA8E
-:10DAD000CF498F097F1873F4521E27CABDBD947BAE
-:10DAE000783C13D36397FFD37EA4513DECB421B8A7
-:10DAF000FEF2DAD3ABDEA52FD6F3806211C7BD608C
-:10DB0000637C78790CBE5920EE072F10E75D067D07
-:10DB1000157FDFD0B3395D46D3ADF4D42544A71FBC
-:10DB20001F54C95F5B01F4877A98F4D4787A8F69BF
-:10DB3000D913973D780BC0F993433295979D731095
-:10DB40005DB6FF878FE2FC3B7FABD2EF267C727025
-:10DB50001AC5EBB78BF79EBBF8CEC5EDDA1B5C5C44
-:10DB6000AE149CBB97E8BB8BAEC2F335E4DB82738B
-:10DB70000F905E5680EFBD4EC0758F78799222E887
-:10DB80007702B61F92BB1CEA15B6723E61134315AD
-:10DB9000E48FDE10EFBB37063FDFE0F25AE2450BC1
-:10DBA0005BD750FF0CF4C324535CC802F1FB07851C
-:10DBB00078B884E57A88A521DF08F9D64DFFD677B5
-:10DBC000B0DB9DD6751AE9C2AE754EB0D861DDEBFB
-:10DBD000FC2EE773A16F14B6E6F07975ADE7E7E3C5
-:10DBE00063ADA77B1D13A97D7B62ECF1EF17E31FEB
-:10DBF000AB2AC29B5BAC44BCB75B10BE5DC3F7D520
-:10DC00000AD627F6914CEB2AAC2DB5C42B15D4E6D9
-:10DC1000D3FB7A85EBF3B5DB4CFB53175E42FE97E3
-:10DC2000270DEBC6CBFD6B2E23BCA8AEBC3B917E73
-:10DC30008F3D557CC77B5EEC97E3E984161A534908
-:10DC4000F2EA764FACFB4DF747E3A956E009EC80CA
-:10DC50002C139E0CFC44B73FB6B9FC8EF7F01CE2C7
-:10DC600011FE9A50EFF22B0A7FE9B1E1F7A4A0D799
-:10DC700063A00F042E087EDFB2C4CBF50A3F816F8C
-:10DC8000033EC677D0E7C208B727913793B13F4E1E
-:10DC90000FE7835BF7F8821E26C55ECF6B5DEB59FD
-:10DCA000CA42A0C79CD4B83ED1FB7AEE6221C70518
-:10DCB000ACA78B4FF32D7CFADA9A5B389F0AFC9F56
-:10DCC000DC7F0FD1F5B170BC0FE3547A5BCF6B48AA
-:10DCD00007E362D0C1B0101B95FD7F8F0E4E68FE2A
-:10DCE000118FE03E02FB15EED3C54FDE3FC63CBFB1
-:10DCF000B7E227FD9EF6A59A0B3BA70E4DF61DF445
-:10DD0000D27E27FBAA6149435D813F63FB12CFA30B
-:10DD10009FA19F6E45E2CFC6C4D28B5756052EC732
-:10DD2000F38BEAAAA2CBD18FAA0A3D97A19E9BCEE4
-:10DD30007F1723D67B7DCCCDF1BBB2AA92CE3F9884
-:10DD400023C4F494EE7700D8894CF2472B2EAB7E97
-:10DD5000A6A9011DFDDF9A78A7405502ABD3B3D029
-:10DD60005F94941132C1EF1F2E7EEEB2266DBF8EEE
-:10DD7000E71A76E81FFD608E81CA598BFFEC456576
-:10DD8000415FC093F11C731C6BF04B12F913CF462B
-:10DD9000F913CF5AE69104F3FE0A3B5B7178E81C55
-:10DDA0005261C28F2CE0015F681FBB5BE7EB5C1E1A
-:10DDB000EF217D60D54536B2EBD609FFF4CFD02FE9
-:10DDC0004D7051E8BC01C3E0B0BE96C0D7E1C4734A
-:10DDD0000C19EDAD08E5DDF862974C4F1F4A984FDE
-:10DDE000645E09F37D596415DA0F1D935AEF203FE5
-:10DDF000A03390E606BC7ED6AFE5B084E712798109
-:10DE00008B11CEB57228C30BF57F21776660BDC13B
-:10DE100050F44E1F9E5E84F71202A6F3CE21B48EFC
-:10DE2000EEBCDC337FD15225EAFCEF6F179BCB5F52
-:10DE300071FA2FC679543BF9FB60491F4874BE57ED
-:10DE4000DD75EE9447FBF26437C723D105D2D54187
-:10DE5000AE379D55BC097DC89F3D32F345CB3C7C18
-:10DE600096BC22ECD13AA0533CA732E86398E2B7C3
-:10DE7000211D0DAF81EF663CC6D077FBB8E879F085
-:10DE800098FAB9313F1897E8553E97CBF7E3287ACF
-:10DE9000D82DF1F9878AEDDC6E642119F13AC7209B
-:10DEA0003C6505CF2732E38FECB5778D7327B682BB
-:10DEB000E7759E0BDEC6CFB9A3E733A7F9EE163C94
-:10DEC000EF99D3DC6F3E9E7BCE29BAF8434C77ABFB
-:10DED0009DFBE3515EFC50227DF6A6B75E54E32124
-:10DEE000DDF1E6467A9F60AE9BEFBF7359A78AF8D3
-:10DEF0000F305DE3E756615ADF6DCC27F20D2AFA49
-:10DF00001D6E89846FB81A72B7BE18BE1AD5BDB916
-:10DF1000073B5F42B4051AF45C3A1B32DA35F95E0E
-:10DF2000E679DEAE0B0E4EF1FB478A83D6D5BD6E89
-:10DF300007C1C15827D4247C74C149BCCF66C0A591
-:10DF40006BDDF1375F85FEF8DEE4DC1CC7E80F7996
-:10DF50009C3C9F57349C3EC12290930BDDFE1FB921
-:10DF6000A1FC7AB7FF2E4CCB1C9D839521C437555D
-:10DF700098AF900317A5001C3E1A14B83819E1D1C8
-:10DF8000D2F782F4FEC34E2E0F0EA71B7A6DAB1B89
-:10DF9000E99BBDC8F55AE3F73256ED387EFF8D0098
-:10DFA0009F8F5EE5EFCD95CBDE6BEE22FFB2CC62AC
-:10DFB000D921467A58F80D1E76DBC47BD17C9DF3BF
-:10DFC000140EEF798DF174CF6EDE52D9F2BEFDBC26
-:10DFD000A53C7E95292D63AEB7D8092B045DF7ECDF
-:10DFE00007FD1AD1FDCC5F3A99DE2DD9A9E993C876
-:10DFF000CFF138A7B3F953FD32C6FD4F582D911F0D
-:10E0000069FC516F532BE4E787137DC8AEF3EF5CD7
-:10E010009C89EF9754B4703F67AABC28E33F207DEA
-:10E02000683FDFEF31BF08E1E4F27B5DA6F39A368B
-:10E03000B53243477ABED5E54779907FBDFF5DC4D1
-:10E04000A7E1E730F6DDE7400FC038CEFC5BBC3916
-:10E05000481FF90D4E3FA50EA6C4815CCB5798030F
-:10E06000D3548D294E4CE39803D3ECE5427FAA9D0F
-:10E0700045FA8327274FC3F7C4F39B9FFC14DB1794
-:10E080002A917D92899EF29B5FFD82EEC3F9F3286F
-:10E090004EF75B5B348BDD39BAC19AFF7693359FBF
-:10E0A00011B1E6330F5AF303706D267D73FF1E1E08
-:10E0B0009F527A9ADFEF7D1E60A0223CB6D9493E7E
-:10E0C0004E296DCEC67887D34FBB6D58BEFBEFDCB3
-:10E0D000EEEEDCEAA47725F7BD17C7E292F01D6AE1
-:10E0E000E7462C3F1DD7908DFE45A84F714BB0BB26
-:10E0F0008E40BB71E7A506BD8629BE69E73FF8FDE6
-:10E1000094CEADF630C6519CDEF5E4D3489FA7B758
-:10E110000E207DEC792964C37E43F770FC4F88F3B1
-:10E1200058E454E916AB3D7E42E8011D27B579E875
-:10E1300017BAB8D6BAEE4BC2D67CA7A87F1B337DE0
-:10E140004FC7F810EFAA34DC6737C57EBFFD73C137
-:10E15000174F3DA519742B8BF71E9937A5FBBEE20F
-:10E16000EEEE73DB2503808E4A111643BABF974645
-:10E170008DDB850FD17F92382FEBFCAD4CF03955FC
-:10E18000556489EFE8D2FBAA7C69534DFB5141ED00
-:10E19000BE947CD257F7A5DC66DA67CAB61E48B9CA
-:10E1A00019FA6BDBA2D0EFEB95CD79E2810949F842
-:10E1B0005D6EC0F96239FAE7DA1A5EF2603DD08B23
-:10E1C000C79AE3BD0A6BC7A54D35F1E9D7A54B83C7
-:10E1D0009FCA740E9FE7725A72F11E46692DFF1D89
-:10E1E000BED2861BAEBB1AE1BE9EDF4FCF56589EF5
-:10E1F0000CFC53B6FD86EF8F86EFC1C7C6F9703EA3
-:10E20000D9F8242DDEBBAD3F43F776EEB571FF4460
-:10E21000345C467B387EEFFD81AB08E512F4F7A253
-:10E220006D2CB53F68037DE4C4E4D06B374395D3D0
-:10E23000ACE10F57535C96959E803E25D4B73A3794
-:10E240004BBE8DF47579F6B5A85AFB97513C3A94BC
-:10E25000C7B4378AC3D67EA2F17CA547327EF76861
-:10E26000A4995EA2EBF59D11A2DFB72A5B0A72CDDD
-:10E27000A4EF971DADA178D8E871C819688A3BC191
-:10E28000FDD14B7CEC147A02931CD9225E7C28CF02
-:10E29000D3BBA748974010A597B2A95E84EBB56C95
-:10E2A0003AA6CF4B91076499CB03F2336D8B277954
-:10E2B000D0A6B73EF173A4A3FAD1741ED65FDCEFEB
-:10E2C0006EF346E8BD58E37771DA749E2F69765293
-:10E2D0003CD5E98F349297CB308E13EB3FEDB4D918
-:10E2E000405F3BBDBDEF648C0B6E6BE0EF8A9F6AB5
-:10E2F000E83B59FB8AFD379AEF8D7DF108FE13DF6D
-:10E300004FF5F88B3DB8DFACE071D3A97D2B332AF4
-:10E3100063E0C96897A45566A0BDD279ABCBB7912D
-:10E32000EB53E90AF9DDD3C8AF922FFC49F7E9793D
-:10E330007778A0BE1BEAFAE1FF3E07E58DE877FC9F
-:10E3400040F6DDA10FED3E1F5F9015A0FBE3F40347
-:10E350003630FE7C854514A0B7F9B8AF8CA13CC916
-:10E36000CFF9EB258A235CB0C6BA1E7CE7DABC1F66
-:10E3700016E12F290EC5B8B0064A8BD65BCB8B7140
-:10E38000FFF050BC17C5CB94D459CB198B901FAD5F
-:10E39000ACFE4B7B2CB87DCA8CF5F96B3C16B9A34F
-:10E3A00092DCF950CEA3F595A23700D29BC4FE1C97
-:10E3B000BC33276D01A41D4B27A42DC8C47BEE7C64
-:10E3C0001F23D38EF898BF8F573A954506F1777182
-:10E3D00018EE8FA5CD526434E61D2CE419CBBFE3B3
-:10E3E000FB20B86EF33D3163DDB85EF377F626C7E8
-:10E3F000AB71CF10D76B2E2F137028ABB75BFC3AE5
-:10E4000013EAA590FBDB787FA995DA55347E69B7CE
-:10E41000F42BF65FD8B79913F035A168838C8B790C
-:10E42000A84B8E872F89750FE5B080DF433714F432
-:10E43000437E7D10F5CFFE02C039249F849F804526
-:10E440001C305E5C66579ECAB397F3FC3E4FE08A71
-:10E45000DA8160AFA9013A879A2FE7BD8CF71B4795
-:10E4600026065E42BCCCB7F9072BC4B7FE11E417F1
-:10E470005DCAE1F0F0D8CA4B2A63D9C502BF3F9309
-:10E480001AE85C3EB48BEFA3EEAC4ED5ECF7FE8BF6
-:10E49000904709FB5BE95E4FE70E89EE133F221DB3
-:10E4A000A1FBB68F5CE96568C7A7019E50EE3E22CE
-:10E4B000B115F85E5E56E3AC452F219EB3E27C7841
-:10E4C000DE5FDE38492E77D1FAB9BE155FB901CFCC
-:10E4D0008352E78D1C8B740EEB9E772D7CFFD0E36F
-:10E4E000A5F1FAB938DED39687D2178FC2F1F316A9
-:10E4F000BD847C383A8EEEA1A702ACDC7D285D8D10
-:10E500007A541ACBD887FA60DA0CEF58F4B93FE4A2
-:10E51000E1E324DBE479B350CF1BCBF37D7E2CF910
-:10E52000371211AEA57152ED6C3ACE17BFA35EE85B
-:10E53000403F82CB84EF299519387EEA509E2669A8
-:10E54000118A0F3C64E0BD99C7E92DD119C9E925AD
-:10E550005F4C4A453BEE501B18D420BF0E0D34ECE7
-:10E56000CC888BF4F06123797D61F72DC9E0F75FEA
-:10E5700092061BFA0FAFD7A1FA133251AEBEC1F506
-:10E58000F14F5C7EF2575FA6C58EBF4F48E0780A18
-:10E590009E8B636193FF3838FB33D21383E73C2CA7
-:10E5A0006CDA27F0BD4D731C7759D17EFA1D847249
-:10E5B000D642F701CA1BAC71E797C5C51ED7A0F3B9
-:10E5C000E0391B0BF525321E88F6D721A973D5C279
-:10E5D00024BA174BE73BC1731A0B99C60F9EEB6326
-:10E5E000CD77CD3385FAE9AEC7ACF59A3EA77A2C44
-:10E5F000A7D583E3B4EBADB48F04CF29D4CED86FC5
-:10E600003AC2B6900AFCDCEEE5E51DE23CCFA86F0D
-:10E61000F4D73E5B13F7DEF8BBE86D552078002E8B
-:10E620008F369F217F7459F33E828B410FDDF08935
-:10E630006721137C52AA5B2236E0ED690F6EB87B2E
-:10E6400014D890C9FB051F8736DDED9F08E5F8BBA0
-:10E650000F26BE8ECFEAE27312330FD9642E174213
-:10E6600075774F9D68CA8BFA5DED439BAF980A346E
-:10E6700095358AB7BFE6C1275E594E4E8B1A11DF1A
-:10E68000DF3938CF6DCA3BA2F22EC88F36E5F5A828
-:10E69000F2A4A8F2B4A8FC405EBFCD1D192CFB402B
-:10E6A000DE3FF8D415F8FB9E6DFD2273F1058F3522
-:10E6B000F2B62BF0F77CCBB3F8EFD356344B3EC910
-:10E6C000243F2BBACEF35BB5F9A3100E2D2FA31C5C
-:10E6D000286B9274D4EB5D0DDB2394C7765E53BB3D
-:10E6E000066E3F96351CA176BDF63FD2467C7CEF88
-:10E6F000C8F7A9DEF9CE9FD80CEBEF5BF5761E7557
-:10E70000440A2C4E48EE7E7FBD6DFBDBDDBF2F0A39
-:10E71000DFDBFBF90F901C8DBA071EC4F9B8BAF9FC
-:10E72000C480E3BD23CFD27BB47F1CDDFC16AA03DB
-:10E73000F14BCE2C53A0DD9FCB8F8F437D0BDFB4ED
-:10E74000C57DE36752F812DC8F1E65814B70DC5B80
-:10E75000CB87EFC39F4C38ACB63E86EF956F78F011
-:10E76000E52B1498DF6177EB20FC09B74D096FF0BA
-:10E770007C722B7F5145FF1DE1E7F0A0D64136C8E2
-:10E780003F99C0A6537E78EB63987F3DE104AF3F8D
-:10E79000BA7590ACA30972F28AA990DFACC7E6F70C
-:10E7A000DA04AE371BF39B36DCFF53840B2BE3FB01
-:10E7B0000D5E3376803C9D5B726ADB6680C7DC1F32
-:10E7C000C5939CDBDC76DD55790487501EC611A607
-:10E7D0000A78D37E48725D217DA21FEE817DBAF159
-:10E7E000E91EDCE2A5FDE2D2CAEDA837A4CE1D45A4
-:10E7F000FB45A1C72FE9C9DD69381952A82FE93AAD
-:10E8000097EBB28DE22352EF72931EF5A0F83D0311
-:10E81000E03BA20F97C0CB36B19E6D09DCBFF680FE
-:10E82000671AF5F39EE47FC42163CA424EF2A7C57E
-:10E8300091BE72F306902B20D7D78979AF5B7B0905
-:10E84000F9296E463FF128FCEEEFD76754B7FEBFBB
-:10E850002E03F2AE6EBB6EDD2C7F3FF3B9F6BA0D20
-:10E86000BCDC905BEBD2797B63BF4AADE6E3A43EB0
-:10E8700078C9465C47BCC2287E7BE1EC111B97D16E
-:10E88000FE7F2DAD9FF9FDFDD00E3F5A3CC4867A28
-:10E89000A9819FC2E1FE5712603D3789DFEF35F055
-:10E8A000648C4FB7E2517F90417F403B353140EB64
-:10E8B000077D620C0F6EE0FA04D21633C19729ADC2
-:10E8C000E3F0FBFF2038B5FD2BE0F44F9F7747C9FD
-:10E8D0002190370CFB2F5F7ADC72FFED3F01D123D3
-:10E8E0002A700080000000001F8B0800000000005C
-:10E8F00000FFC57D0B7854D5B5F03E73CEBC929920
-:10E9000064264C9249C8E38440081071124344F0D5
-:10E9100031848851693B50D4D87A71203C022699C1
-:10E92000A8D5624BFF0C12790918342250C181021C
-:10E93000C55BF506458C1A70448A7AAFF68EADB782
-:10E94000576C7FFF08888F4A32A2F5D297FDD75ABD
-:10E950007BEF64CE24A9B4B6BDF93EDCEEB3CFD9CB
-:10E960007BEDB5D76BAFB5F61EA6F54C0A5CC0D8EB
-:10E9700066256ACEAE642C7C48F1ED61F007CF6766
-:10E980003B19FBF7B4A0D595C9D89FF1EF0AC6E6AD
-:10E990007EBF29275806ED8D2318CB612CF5BBCF00
-:10E9A000D4DE00D5B94B3F7A7C0F7C3FF77BA98C36
-:10E9B000E903EF438F8CC1F7EFBC6D5BCF2E84D2A0
-:10E9C000D2193579A0BC86F956C07BEF98584327F9
-:10E9D000F4F70EBE7A096355DFBBE5353691B1DB3E
-:10E9E0005D2A6393185BABF873988A250BDBE0BB59
-:10E9F000F02C4B644F11637D1153D80CFD75B82377
-:10EA00005B17C1B81DD795F9C2D05F1F637E86EF33
-:10EA10002D4BA5F73ADC3D4CC3F64B741740C20EA4
-:10EA20007EA1FA19D4E3375A22BB14785ECEC2769F
-:10EA30006C5F323E1286FAF3300E7D7F634A640FBC
-:10EA4000B6CF828FA0DE71A3371286FEEC2C624710
-:10EA5000783A76FA73321C8CE5AAAC05E1EF28828D
-:10EA60003A94592BD9CD0107E2CF3F719673000F2D
-:10EA70005F7799683EA9953D4FFF37F4C7D6DB7D98
-:10EA800063A0B0E1AB586FCF2678993B5885F86604
-:10EA90001AFC03B8EA1FC889ACC3E7CC5785EBB1B1
-:10EAA000DAE99F47F0FF205547F81FB6B335B60A9D
-:10EAB0002815D666CB00FC0B7858FB43000C633757
-:10EAC000E3008097FFD770D6A9C3F32B5D0AAD078B
-:10EAD000FCF96D558CCD67BC7DFEF2D477958958D5
-:10EAE000AA516B1A3C5B73A5BFC746EFB13F8FE2DB
-:10EAF000A50DFA0B32F1B725EE44BA09E27769D8D1
-:10EB0000FFEF9DBA03EBF0FD445C76F8BE74E0FBCA
-:10EB10003A17A3F9CF5539FCAC355547FC4AFCC828
-:10EB2000B24EC2D7FE903F713C394E72BFF7BAFC6D
-:10EB30003722BE00EFD1740FE245A5754D86D7632D
-:10EB4000896FB043FBDC56D57D37E033B8CC49F351
-:10EB500095F0DE9C1DBF8C150FEEFF746A739586D1
-:10EB6000F35FC6E99D2DB702E212F16219A8035DB9
-:10EB70002C64F163266588E75AF445847F5147C2C7
-:10EB8000F7F4DF2FAC89EF497E61BA9204BFA02B66
-:10EB90005DD170DD820A5F378B253E375036186EA7
-:10EBA00089CFD582EE245D24E37B35E27BD2607C85
-:10EBB0007B2C3DF9D86F709995F094DC3F6311FA86
-:10EBC000EE213BF00FD0DD1645217ADD72576A64E5
-:10EBD00025F2A73DBE17F1193A7C15AD77EF9214D7
-:10EBE0009DC12BDB2C30419433879D9C8F4B7A4AFF
-:10EBF000909F7A61CE7E589FDED7D59D614502C138
-:10EC000058F3EBEA2EA4FFDE67AFE6FDAC48D5195A
-:10EC1000D4438861183714FE432B03BC9E34C52CA3
-:10EC2000345E17E057C209FF7AE15F43C580BCE854
-:10EC3000C3061CBF8BCB0798E1121AE7DB296C1DBA
-:10EC40008CDB6C52FC26686F5E3A3EB292C3614325
-:10EC50003E6A1420359B589B5231C0F7CDA6132530
-:10EC6000B795F1360DDEBB85F17581F78E2A005F11
-:10EC7000A36D7D4C45BA45FA87F6A5D85E3480FF72
-:10EC8000E6F5BFF913C2DF7CC048178D8F19E7B1D5
-:10EC900034919E8A06E824B592E389D5B0C81880DD
-:10ECA000D729EAA9B5B1888A785A56CD4E02E966C5
-:10ECB0001EE99981F4E3ACEC64F3A10C7DC0FC1176
-:10ECC000807B4AF7CE9746C2FBEEDA583E4E37B409
-:10ECD000ECB68B4E5D34B0BE12CE4BBA37A9CC41E8
-:10ECE000E3D177008A7FBF83DE1B37FB82C4F26EDD
-:10ECF000FA2ED3A412BDF6E023E41BCD9FA3C038A7
-:10ED00009B978C32E17AA6827C43B9BCB07DECAE95
-:10ED10001584677F09CAB707D380CE099FBE2A949E
-:10ED20002FA5EEEA5FBBA0BFA7DCD5FF8D258E1314
-:10ED300070E2F44790BE48A6E764BD23DFCB2E6E99
-:10ED4000296F710CFF1EF017E12DBE359DCB0F4DC5
-:10ED5000A1FAA2FF30EF5C47F0694437B76D2F226C
-:10ED600079DCC0DA89DE1A59C482F4BBC8C6C2692C
-:10ED700040178BE0B57428176FB1323D61FD9644A2
-:10ED80008CF546210F6E6131FAFE967D49ED352CEA
-:10ED9000EA84F6261B8BA662D9696C6F667141EF17
-:10EDA0007FB6263E671D7CBE378B7577D744D4204F
-:10EDB000CC7BAB1D745706BED04EEB3365F94E5A73
-:10EDC000CFF40A7FD13DA84F5E35FB7601DDBE272B
-:10EDD000D64BE2E75E57F5BB88F714D544F38FDFD7
-:10EDE0006325FC9C02BD8DEB7F9F9BDD3C1BCADE37
-:10EDF00056DD3B7A34A2C95530DB3918CFEB9EB3D0
-:10EE00003720DDB8DD26C2B77C7ECC65A67AD5DD9D
-:10EE100002FF2B5223BB8A08DD13919EAA46497D2F
-:10EE2000CA26CE82FABB6656D709F5E6EB1D41EC41
-:10EE3000AF07ED07A817B8B9DE28705B687EB22E61
-:10EE4000E72BE906C6A1FE522EE2A584638C5BC8BF
-:10EE500041B6897F27F4EFE625293B49FFF6D3AF7A
-:10EE60008911FD96052C88D7E7845C794ECA9536C2
-:10EE70002B972B9A6BEE32A83FF741996F1DE095C7
-:10EE80009582DE83EF1B3F4AD1919E5EF9E85FEFEA
-:10EE9000FD19B49FFDC0A25BA17D01D218ACDB734C
-:10EEA0000A9747607F30D48F8DC0F6386EE3C1B1CA
-:10EEB000647F1CB408FB46C8CFC6B4E0D685D04FEB
-:10EEC000E393993EA064F6BC39F2E85E6C3F64F7C8
-:10EED000ED817E1B53385E1B9F1B49DF3F610F4E48
-:10EEE00077C33C73AD919F3C8172E3052BD97B675F
-:10EEF000597411C27FB6D3AEE07B27705EE95042F1
-:10EF00009B82F3EA76923D047C9AB310BE3BB936FD
-:10EF10009BCF4BE0E9E48609C4179BCD7CBCF0B3E2
-:10EF20000ABD7FC21C989103F5134F97FB564053BF
-:10EF30005FC012B5003D87EEE3765EBD49DF8178A4
-:10EF4000628753095EB91EA18D8B67627B68E9F207
-:10EF5000AFA37C1C8ECF51DEB304B9D9CBE205C878
-:10EF60004FDB1A467546519F748FF3915A655E5870
-:10EF70007CA01B177FF79499E3357EC84CF47CBEC8
-:10EF8000FDE37CB52AAE7F709C10C86526F98FE43E
-:10EF900072425D1DAACEC8FE0C3D972DEC3A63FB74
-:10EFA000EBCEE01D6EA0BFE6FBFFE79D6584DF387A
-:10EFB000C945D69E497C79CAEC9F8B74EBAE895AC1
-:10EFC000E627E8F30D82AFEAADC2FE63514B221F84
-:10EFD000CAF6AA6A23DDCB72BDA07F678CCBF7C1CE
-:10EFE000ED26C11FDFB4A21E9BC2416685A8471C47
-:10EFF000D8BF4EFD4FF9206AA9877AE1F2A8659142
-:10F0000028914F00DF511BCCFBD45627E76F4003FC
-:10F01000F6B36832237DB94805FBB5029FEB5D3D31
-:10F02000B02EA79F7673FAFA236005F03D8F89F71B
-:10F03000AC60EF821C7BA64D89E27E60DE16EB2E73
-:10F040007B11F2B55F75E27A6E57488ECD6B9B5699
-:10F05000B215EA4B0F5C40EB9F3699D3E5D2889B03
-:10F06000F4E214211FEBAD110BD9DF3F5118F2016F
-:10F07000F44F7674237C945331180F28D70DF41075
-:10F0800049A8835D34A593CB5506F29C25D84B52F5
-:10F09000DEA31C6749F69F913EC2521F71B9C7F4A7
-:10F0A0006C947B522EDFEB0A74B949AE8DCEC6F557
-:10F0B00085F5E47273BF42786D622DA44FA41EE8FB
-:10F0C0001F57E891D36A98EB2BEB262A5F7717D16D
-:10F0D000784B5927E913A95786A383D7BF840E7E9F
-:10F0E000867400ED8D1FB0E865305EE372166D9A90
-:10F0F000C84BE744D28F5C4FDAB89EC432E53CF48B
-:10F1000065B27E4CD687C97A30DBC2F59D5C6769F3
-:10F11000CF644FE776C094E51195C1FC36A6F93F60
-:10F12000CE9C3460D784DEB2D9F40BB11E60A3E06C
-:10F13000BDC569D36ECA86F690C6FCC857A980972C
-:10F140009DF07CBBB07B6BB339DD7B2D9C7ECD5AB3
-:10F1500080953B705D62B4CF8D673217D2A3C4E750
-:10F1600076277C5781DF71FDD4FFBD8DB5A5247C4A
-:10F170005FFD9C9DE4EAE7CF3A2356B24782856E55
-:10F18000E82FEB5756B2537B9F73923EED15FAD0A2
-:10F1900083F628D1CB2AAE5F715D272135558F6468
-:10F1A00048FBCA352351044AFBACC9CDEDACC1F6CE
-:10F1B00090682F8A5DCFE9CA4AFBCCCFDD3D7762EC
-:10F1C0001DE061689FFF8F58E7D081E9E5DF87E7A1
-:10F1D000A180C3C7B11F2C477AB5AADFB9DE06F4F8
-:10F1E00035435D1EBF0BE6D194EF70A19EAB29FCA9
-:10F1F000F52F6F84FA8707CCCC8AEBBC677A1D1B8E
-:10F2000035BCFC5D12319FE849E0975BF619EB4D88
-:10F210009DC67AA8CB582FC8707A4E4F20D9E1FBF3
-:10F2200033D0B5D5DAF2C14E80D7FABC95F4D1A768
-:10F23000EE607106CA5B53FC18E2D95AF8F144F447
-:10F240006F84BA3F51B0B402EDC4CA38FE91AF3FEB
-:10F25000B7CF2B740D81B701FC319B89F00CD63AE6
-:10F260002F49CE85049F782CFE0F5F84F92F9A9D3D
-:10F27000E2BA9B9EF8674EAA427B926064A12D572A
-:10F280007F88FB2D786F09AEFFE959F01EC0D5B01D
-:10F2900085EBC346164B43BE6D06BBD3064B7C477E
-:10F2A000065F875BDAE25551F8DF8E8CDA7108A7CA
-:10F2B000F6272D80F4B11AFB4DB093AFCDE07AE084
-:10F2C000967D76D729031EDD867AA82BC7752A91ED
-:10F2D000FF84FC61798A96B81F7A57095E8BF86BB8
-:10F2E000B2F558A6C1F857FCE93392F78B97CDA732
-:10F2F0007DC4805D6D25F9B4F8AE203D7F692BDFBC
-:10F30000179EDE6AD711EFA7B7F3FDE3E23C47C4CF
-:10F3100006FF7B859BDBDB8BE13B45198CC764BC1F
-:10F32000BDFFF0555EA4A3F7191F2FDCC9ED8FF7C1
-:10F330005D80AF62FE0EF6F77E17D8EF0AE2F9AAFB
-:10F340000F512E2EDEAEFAD04E60879CE48F59BC52
-:10F35000FDCA710B1DD8DFA723A6A15F68C795E87A
-:10F3600089C2F70211EED7895D01CFB51D17931D34
-:10F370007774BB95C3E9B6EDC5795CF12795F84A7A
-:10F3800033B120DAC71D16FF38E467FDE13D337065
-:10F390005DDE9F956BA2F71F57980BF1E15E968596
-:10F3A000CF172B5A00F9B761CB929989F64E6A862E
-:10F3B0004AEB35AD7079568F83F8E97AD4A34DDBEB
-:10F3C000817F70FCD96FFFF2464F223FDD5EC54C56
-:10F3D00009F6CBC35F237AC2BF28E06BB1C0D75711
-:10F3E000E52B6BAAE48B961294A38BEF6E29710D1B
-:10F3F0006157F4F3C5C39C0FEFCB50B8FF202FC368
-:10F40000B0CF186E5FE62835915EB1F9987F0F9402
-:10F41000D9B02DC6FDF7810C8DDA0F64707B5FFBD0
-:10F42000DD6DFB5E87794DCD086ECF807A21F39735
-:10F43000E3BAEB71573598B18862B2BBD8C3566E48
-:10F44000C76ADC8EDE9CC9F6AE4BD88F77627F9997
-:10F450002417F6623FBDC7FF780CF1DA5CF0F14487
-:10F46000B40F42E73EB3A01FCDD1AD903C77F80278
-:10F470000CE925D43D8B2D281B90C3211FD713C920
-:10F48000F3FA5306DFEF843C71EAE7FD119C7F3B02
-:10F49000DC9C3EB72D4B213FE4364FC48E40FFB578
-:10F4A0007C2AEDA525C2EF67DBFD945F45FA8E2827
-:10F4B000AE3158D7397FF435CC8DA830CE87BB8B91
-:10F4C000C9DFD977609A4F8536C7EE1FAD198578A9
-:10F4D000EA32FBF07D87AF270DE7F7E1EE9369385D
-:10F4E000BF86DD2ACDBB21F249D6C2B201B9F033C5
-:10F4F00025F83ACA01E6521C38BE940F1FEEFE34BE
-:10F500006B8183FB0B487F560E8D97A7DCD37E8ED5
-:10F51000DF5F71395F978F1EB74650EE7D6407FD40
-:10F5200096206F3F72727D772A43EEEF3A0B50DFE1
-:10F53000F4D76F2A35A19CF88E8BCFDF63E92C407E
-:10F540007EFC8D62EC67E91A138B806C5FB206500B
-:10F5500003F2E8A3479F294079FFE19E670AE62767
-:10F56000C097FC9D2C7BE578C26F26FDA81E4B340E
-:10F570000FC79BEFB3727FE5307E54F93EDBC2FDCF
-:10F58000A17D3EAB8E7428BFEB6B48F1A37DDBC73A
-:10F590006C24FFE6770BBFACDF3FDA83FB18F97D05
-:10F5A00052FF151E4E4F4A9742FE83D4B238C9E32C
-:10F5B000BF59DE7B603D13E43DACF3BF215F34D91E
-:10F5C000E2C74632A20F0BE2CDD2ECD0503F65AD80
-:10F5D000E4F415BFC344FB2A4BAED781F2EC8A9208
-:10F5E00094361330A227256D22C601F2734BE9FD34
-:10F5F0007035A7FB7016237F5B0E6B51485EBBB85E
-:10F60000DF3E6F3273AD83EAAC11DC9EF132DF1660
-:10F61000B598D65D41FF90C487D40B483F281F3F63
-:10F62000526C443F4AB74276A76AEA9C8BFD0E476C
-:10F630004F1347C8FD3FA7A7FEFA3F899E268F18A4
-:10F640008E9E823AD193D736343D093FF179BFCFB0
-:10F65000C201DCBF660B7CDD27E44EFC0E9BF49BF5
-:10F660002B38DF99A2BF9936475445FDE1337F9C83
-:10F67000E8FF7D18EC5FDC27E5A0FD0EE5C895F3FB
-:10F68000745A3716EB417F41EAC536D28FF79A623A
-:10F690004568AF648F6FD98F74913DB7AC6225ED2B
-:10F6A000FFF2DCA80F50B7921F745975E0D488049C
-:10F6B0007BE110DFCF34DFE5A7E7D3BBB97D101ABC
-:10F6C0006D217B38D4A584719D9B039608DA416B2C
-:10F6D00015EE5F096FB0EB3CEEA3AFA0B8CF0F748F
-:10F6E0001E178A48FF6FCF8EEF23BD3538C8EF91C4
-:10F6F0001C3F3AF885CAC71FC368FC8E721EAFEA6A
-:10F70000B85AE7FE15B17E1DB3FC396EB407D618A2
-:10F71000F959C685FA9C8018186FFE7A3BAD43AE46
-:10F72000CAF1CCD26D5CFF0C960BE467CE9A2C1616
-:10F7300046C46FFAF91C2405D67345BB8C3739CB08
-:10F7400002456879BFBBE9B7AFA400BD66A19F8E33
-:10F750006FCAC268F7937F98D7C97DFCA00900C91A
-:10F76000C5D6FF5C577369425DBC3FF0FDDC6B6B37
-:10F77000F248EFF6B723D8A08F65DD6FD7311E357D
-:10F78000D0AE81BD6BEB52F8F761C7B5578E063C22
-:10F790002872FCFF5CEB477FA19D19C64B844F4B41
-:10F7A000EADF0CFD3B74F97EBCF64A78E1C10A59E8
-:10F7B000BF66AD1FE0BBCF6CEC8F502ABEC78A1C62
-:10F7C000EFD6AC6DEBD6E70DD8056027EC1A913972
-:10F7D000601FAC7E7B66FB853056AAEB530BEA5D5F
-:10F7E000A9E7431E85EC8F647E3D20E4C3DF2C57E0
-:10F7F000F54176F4811124577B66204BC2FE83E4E9
-:10F8000076687980A13D07F64817C2DB7BFCE3D31D
-:10F810002F427BEFECDF1F1BA9E37BB7CE45BB3745
-:10F82000744E23BA0DED53230AD0AD4DF00BE871A1
-:10F830008A0B487A5AEA1274EA0E338C73741C529B
-:10F84000268589BE5A0AAE83B5CCF7F85F4238E404
-:10F85000BE3279DEBF1EC1F70FA1D2EAAD25D8FFB7
-:10F860006E85A19DB0AEF444D602DA37BD9BB530AB
-:10F87000E1BB255D0F123E97EC330F89C75F8FE028
-:10F8800071DEE6679FF6A3DCF828A2904C68D022D0
-:10F890006BA740BDA1C1849620AB8CCCBB91E21C70
-:10F8A00075163606E67704ED268463DF37C353709A
-:10F8B000DEF04F8147DB028B489F6EABB339284E99
-:10F8C000543AFF56C2832BC58F7858575A9D83E30D
-:10F8D00034CF9AE1A2F808D871D8DE7CD7B7C82F08
-:10F8E00024E15AD765AE453BA70AECB9A700EEFC68
-:10F8F0008C6B6A7DC0C723D5FDE5B73B305E3EB457
-:10F900001CFF6E26A78B362510FE4625F94159A20D
-:10F910005FB3B08BDB8D9F8DB018E22B9F8DE0F62F
-:10F92000ECA5E1D874249FC35A4F2ADAD321E6FF0D
-:10F9300004F7CF2CE0D0F7D03A7179E469D5C93F0C
-:10F9400066F3F4DC7B21B65FAAD1FE85693D0FE04A
-:10F95000B8BD6B3DBE754CF001D6EF2AA37D4FBDFF
-:10F9600027A87832F9BC707D7B9FBDAA1CFD88D288
-:10F97000EE5AFBA89DF4E65AA77E7F2DCAD3DF6915
-:10F980003C1FC0168F4D877E96FE3E83C65D6B8FF3
-:10F99000ACC5F50FEF54A9BDD8117460BF4BBEB90B
-:10F9A0006522D22B73444A508F9A3DED0CE918B66C
-:10F9B0002BE42FB179020CE3C4D3C3F33405F5452E
-:10F9C000923D331DFD55B45FF190BFB65AF0C71894
-:10F9D000A082D3366285B63F8F18B06F5EF9E31C04
-:10F9E0000D1F4ABBC764E3FEF39ABA1486F62D5B7B
-:10F9F000153F66427FBD27C6D00E6EEA54689CA6AE
-:10FA0000D2272DB86FB9A593F37748EC33007F0563
-:10FA100068578CF1A40A7BA08DFB3958ECD848C4F8
-:10FA2000F3637C3D1983F712FCAB8CADE0F240F43C
-:10FA30006711718626E157024D48ED3E8FB45BEFAA
-:10FA400016FDB7F3528CBB5989F955C46BB962F0F6
-:10FA500087CBF22AF17DFA91F80CE4DF38D017FA5F
-:10FA600097B62AB36EFD29CC6FEBA4F13E34C1BC2E
-:10FA7000404E6A053E075204BC57767D3203E98644
-:10FA8000D532E2D7E6AE696A9383C76FD05EC84EBF
-:10FA90006DD989EDD93797927EC6F8C86C78FE3556
-:10FAA0000FE7B31C07F7D779EF0E1761BC33FD489A
-:10FAB000E0D69FE2F817A490BF351BD6C69941E562
-:10FAC0001AF46F7959F98BA87FBD33F50A8447C6BC
-:10FAD000F5302E38AB8CE438D5337C8A7F179437D9
-:10FAE00078DC340EECEF6A115E7C1E710CC419D107
-:10FAF0006F87E3621C0FCBDE9CA8467E7ED0E77B3F
-:10FB0000904EBBAC2EC4D7CCAE97DF427D3BD3C664
-:10FB10003A29EE9A64B7C4D3BE19443AED3B737ADE
-:10FB2000C73D08D775077D94CF92648F5C7139B754
-:10FB3000CB3FDA93AA233FEC12721BEC471E7F796E
-:10FB40009CEF2393EDC8EFF6AF2FB723FBEB7F7746
-:10FB50003B92C317DEC3F328A47C0F897D5F5FC38C
-:10FB6000D934D45F2B3DD2AE4DCAF7D82DF23DBA71
-:10FB700087CEF7D076F2F80F864149EEBA2D22AE45
-:10FB8000E5F7CE43FF87BB84E4C02B7B53C34837E4
-:10FB9000673BED6497696E4B14E16A7BDA1AC13CEE
-:10FBA000883645E0EB90885759441C2CA344478382
-:10FBB000E2A02540723FFCA499C7ABD2228FEE850C
-:10FBC0007AE3E11C11CF62D47FF8D954C277638AFB
-:10FBD0009E8EFD37FEFB088671AA3E180FD7F909E5
-:10FBE0007B70BB87E25ABC7FF68255E7F1B3688928
-:10FBF0001BF0B033C2EDBF93A5A6A805E6BD93895F
-:10FC00003C9FF532AEC5E7D9B761248FCBA03182D6
-:10FC1000FBB2B5DC5F542FE35587B91FAE5EC4A5B8
-:10FC20004ECE5EF408A658B4292DB5B84FFB7CDD46
-:10FC300034F29FDF79FF2C2AEBD718FDFD8BD03FE4
-:10FC40005F3C103F967EF7F9CC67E1F6F380FFD07A
-:10FC500004F68CBE46AB46FD59C45C77A33ED0C3C8
-:10FC6000B07A1743D906251AF10A6019DED3D67A7D
-:10FC70005270BD57B799486F85DB4C7E7C4FD2CB15
-:10FC8000AB1EAE67DFF570BD03A88EE038B26C33F3
-:10FC90008B7883E86F053345B13429BC5CEDD26ABB
-:10FCA00087D2DFB2BF36738B6D1ADACDF926F277C1
-:10FCB0007F6EF1D791BF38A384D6A9CDD9B2A696CD
-:10FCC000B7132F7D6E8F07A8FD328D1B964CCF404A
-:10FCD00079FA8287C71792F1B6B0DD584F8EC32CE0
-:10FCE0008918EBF52C3836A798C70D129FBF20F462
-:10FCF000C4E7EB8A04BE7D1694BB72FE2BF238DE9D
-:10FD00004CF9BC1C955F5D8774300AE3CA45587294
-:10FD1000BF2ACC84E01F75994721FA4882B7CDCD20
-:10FD2000E929BC96FB21FF5AF893E1FED09325F810
-:10FD3000D8EFC5B865BDCB4271E8F3F597A4641A56
-:10FD4000F7B7FDF5BFFFFE96EFE7D7AA22BFC6457E
-:10FD50007269BE8BCFE5A4E2DB1BC5E70EB01F7056
-:10FD60001E6BD50A9423D3BFE9A079341F063982CC
-:10FD700071ACE53D05A8D79BAB7B4A305E938C5FA9
-:10FD8000845693F20CDE9BEF81FD08DA0D6B8CF14B
-:10FD9000B8C1F1557F616626EE7B4EEE7F19F5D72F
-:10FDA0007E3BE92FF8BF17ADC8FFCF16915C8B38AB
-:10FDB0008363312E144A89EEF87111DA31DC8E6AD0
-:10FDC000EAB6EE443B717E5B427C0FFFB3DE18EF78
-:10FDD000636B32C8EFCE3A8CCF1B1E4EFA6E50FCCE
-:10FDE000AF9DD665B325380EF91DF410E51D9C595D
-:10FDF0006262B8BEF5AA6F112AA93376A37D7EC6CA
-:10FE0000C9D76B46A6D43F3EB2BFFAEB83D6D957CB
-:10FE100082EB5C6F62C1C47E9A709D617D1BC53AA6
-:10FE20009F79FAE2125CE78FF75F5C82EBBCD9DC6A
-:10FE3000EE47BE297507AF41FC9CBA3240F615E685
-:10FE4000EF201F9D2F3DDE94448F37FDE3E8B12E58
-:10FE5000311F32593F36F4E3CBA81F3D163D0FE565
-:10FE6000C17C9BF52FEA49FC1BD29F67B392FFE34D
-:10FE7000F01F3FDD48F918DD2AD927B2BFC35AB0B9
-:10FE800018EDA3C36F797D6165F8FED385FDE5B5F7
-:10FE9000B130FA59E4BE40DA97C9F278B998CF0385
-:10FEA00099FEDF8CF81BE23CD27FDC20DEB1453EC0
-:10FEB000E576EF6EC5C7FDC79DE44F6E3E34CF8536
-:10FEC000FEE20F22DC7FDCFC7439F98F97445E8AF6
-:10FED000623E19EB565CB81F59B2FBDD34CC03907F
-:10FEE000FB5ED8E7DE9F49F935C6FDEF07919369C0
-:10FEF00098370070BF8F70A77AE216A4FB66D8FF10
-:10FF000061DE60B3163F86FD367B18D905955DC668
-:10FF1000FDA08CEF6E0B5848EE6EEB562228AFB367
-:10FF20002CC1A23CD46B2CCF753A7580CF2299FEA0
-:10FF300017907E07E2EAFE5D5897FEA79EADE94462
-:10FF4000BF3D66E677A13CDBEA14F24C23F9F6DB11
-:10FF500087DD91750976C36F23DC4E5822F3C134D7
-:10FF600016D560BD16CDF11FC7F546791F4D92F726
-:10FF7000897519AFBF8545492F35B19EFEBCB0C408
-:10FF8000F792E3F9180737F4C35ACA75F493DDE41E
-:10FF9000F0519CABEBCF56637B98EF9B811F96553E
-:10FFA0000CD0AF5C0749BFCDC21F1D6A38B10AE94A
-:10FFB00037D4A5B8707FDDE8E3F4DB08FB2FCC9BDA
-:10FFC0004DE677D669CC131D8EFF7FDDCF779CFF82
-:10FFD0007F3DAC9CFAC7F85BDFEF973F9CEFE5FCF9
-:10FFE000A5FFBE7F9EDD0AE7CBA47925EF5B93FDDD
-:10FFF000EE72DF79BEF2F08B247C7CF10FC6C77005
-:020000022000DC
-:10000000F230256BE8FD42725CE3AF9687FFE0F8C3
-:10001000C623871E4A3381A8585214F672BBCE6F8E
-:100020008817CF501D7E1E3755793E4572DC5D9F87
-:1000300021E2EE9C9F5F7A5AA5F56A12F1E1A64390
-:100040004E1FBEDAE0584CF1D9E4F8E952B67F060B
-:100050002E51721CB511F9B8F8CBE3A91765393DDB
-:10006000249F745684790AC9795A2F393E1D114C40
-:1000700058EFEA32D8080C41D7362DCC32129E4FB9
-:10008000CBE2F6F44B229FC86BE1E705EE73A6FACC
-:10009000711FE335F17CA77C4F607AD62494EF0280
-:1000A0009FCFDEC04C809747CC9D244FC24D0E1F82
-:1000B000CA3FE9C791FDEF10718BF3A5F36F671984
-:1000C000E9BCBFFE4FE2FB8592BEFFDAB8DD16C089
-:1000D0008D811F18D1EF6B18672A1A4CB7C3F533FF
-:1000E0001CFD2ECB0ADC9E4578F14FA4FCE6F39470
-:1000F0002FA995F193E82F6207AC3AFA376DE2FC2D
-:100100000B5B9F23F6EBBEAA599497CDCF8FC87394
-:1001100036C3D98F1BFBF99FDB8FFDF5BF93FDC85D
-:10012000DC81769CE7A9697ECAFB5FED04F8715F0C
-:10013000F8A875C8F32CF2DCC597F95DF6F6C3CDC7
-:10014000E96AEFB070FF63E5E793FF34F9F9FB3438
-:10015000F4A30EDF4F58E47BC6FC229EC67625F83A
-:10016000B743319EAFF79280573E7F44E8C5F46CA9
-:10017000FF515CA78F8FDB6C2C1D4C9E4A2E179B6A
-:10018000030E8A2F3477F2BC97E6E58CE47733FAD6
-:100190004FCBD0AF388BA1BD373523F833FC7EF57C
-:1001A000DB8EB09A8E7EF7D90CEDBBDEE3BCFEA9E8
-:1001B0003BF8736C0F2DEFA17846C7EC8F28EFAAA0
-:1001C000EACF9FAEAAAD2478C98FE0B11ACFAD7C3B
-:1001D00091C5E30FB2FC43BF3CF1935FFFE3069E82
-:1001E0009F1DF2F85DE88F907EF1543D467EA6E6B5
-:1001F00003DC68AB52F97CD8F7F3889E9A0F4C2B3E
-:1002000047FF29EBB497A39D5BF52B07EDF73EBEA7
-:100210002B97F224EA3DC10F513E3A2B2357A35DA1
-:100220005A08E3A0BDFBF1FEABCB116E29FF36A34C
-:10023000FF1CC6DFEC34FAC7998DE7D92FDD9B4F41
-:10024000FBCB6247F053EC6FB39DC311DE23CEA30B
-:1002500008BF7932FF4BBECF564D344EF6B76D1402
-:100260002F977261B399056DC503F2E478962EF26B
-:100270004C445E63F72C9EA722EA0E8F31BFF381B8
-:10028000CC2B8F233CC7B3B4AF961FE618942F40F6
-:10029000FD627E18C505589CFC2DA9E7B81D3DCA16
-:1002A00065217A7202DF519C06E809EDF94BE3B152
-:1002B000E9789E6B7447F452C4F3E17326C2933617
-:1002C000EB358AD3A42B7CBCE2F53D6BC7A21FC6DD
-:1002D000F5E665B8A47ABBAB1A513A3523909F4D29
-:1002E000FB8C96521CAFFABFCC3C9FF2502AF917F8
-:1002F0003A0A1A299FB2F76DABE13C4E7219667744
-:1003000053FEE4A8AE5F50BCC0794019322F76721C
-:10031000B683F0D61C8ECDA01C9B4B3D2467B54305
-:10032000BFA238B5B6564309C4DACC7E139E430B40
-:10033000AF60E4EF1CD3E132E17A158AFC98BEC3CA
-:100340007F9818A4FD8A8C0F44787E93B96715EEC8
-:10035000C3B4153D9787713D0EB84DCD65D85FBCD0
-:1003600099FC2D875219D24F6157F1DD53A15EB828
-:10037000C645F1B0BEE76E2924FF2ACC73CC10F33A
-:100380002CCA36F3FE0FA59A509F699B980F47D54C
-:10039000DC59D504F78350877E468A3C55193F4582
-:1003A0003F14EAA9F4ECE0D7303FB6FF1CD2B214F8
-:1003B0007E0E49E3FE12E7B2B71FC7F33D3B2CFCAC
-:1003C0009CE791C3136693DF6FADA6E03A7CEEE63F
-:1003D000F99437669B0CE74206F07F84F256471D7E
-:1003E000FA05D76B3016F6AF9939BD686B3D3BD136
-:1003F000BFB8382D4879BA97B545558A9FB94E3D53
-:1004000050AB27EC73B6703DD3BC8FEFCB93F73571
-:100410005FA65F6ECB36DA2DFDF57F92DDF283FEAF
-:10042000F1FFC6FD0A33EEF392ED97E47DDD203B4C
-:100430003CA9BFE1EC18998F523D300EB7A79DD271
-:100440004E0A1BF275AA1DE27CA1CDD8FFE5235C04
-:10045000345F99BF93B5525F8179FAF11F30F2D7BB
-:10046000C93CA27035CFF7099B6C74EED0CBDA296A
-:100470007F68248B2A0AF9D37AE87C6D36E611C1AD
-:1004800077EBB24751BFDB996F8D4AF25257106E2E
-:100490003BE69F50BE6A64EB221CE73A078D63C7B8
-:1004A000FC938B3085C0BF15E5EBF4061E5FC805D5
-:1004B0007D8CF49B3B9AD3A1BD8EE7A1C83C1399D8
-:1004C0001722F1502DF09B3B765111CAC1B54AF06D
-:1004D0005171AE99CBFF0D4E715E19EC6BCFC079A7
-:1004E000E43EC6FB0F3798F8796437AF778CD1F9C3
-:1004F00079A02FF839BB8E729E7732283F2509AF3D
-:10050000323FE5C9B4E011E497E4F3CB924E12D642
-:100510008FCE476F3BC4EDFAEA060BCDA36FC9350A
-:10052000E497EC5B6262A8FFABBBAD9CEE92C6DBCE
-:1005300056676151EC578BD8517ECAF5FF32BB1616
-:10054000D6B514FDBE475A6B2F3A05383EDA1AA0CD
-:10055000B2CFAE74AA17D2F9D2B928A99ED8F2F9AF
-:10056000B55A0EE6DBC40B142099E7B77E3493EA44
-:1005700099F177B0FEEA16CFD73490C37D63E23BA2
-:100580001478FFFF797FC4DB911673197BF7A1877D
-:1005900066861D5F41DFFD9125E7719C41BDD3C497
-:1005A0007A56C5C85F24F45D2597875E8785EC255C
-:1005B000AFC83F6535221F15233B505F99534E71DD
-:1005C0007B07D30FC4B03D8F9FCF8276A2FF956388
-:1005D000B87FDA26E882E549BF544F18E5DBCA2226
-:1005E000377DDF2F8F0F5823DC3FC6C77FE3E90B32
-:1005F00028BE25F36A1973E5CFB980F26C0CF5FBC0
-:10060000ECE21CA6E6CAC773EC2BCDC2EE15F5369C
-:100610006730C58BF3443E047BEE8D2BBF5B867C3D
-:1006200074E6E0F747A35CBBCA02FB8221E4D8EE84
-:100630001C2EC7FACC8E350A7C57E30C8EF0C2FA1A
-:10064000BF953A77061E29A81B31CD82471758F867
-:100650005115F19A29E8C43D87C3E7AE0928987778
-:10066000BAD2CEC7CD0C6A7E3AF7109CA35C077055
-:10067000AF54B8BC868FD2C98E2AD5D3F11C61A3E2
-:1006800038D7AA0AB97149E72615EDF59FB7BE35E7
-:1006900055D306E0FB858887FFA2C8783EA2DCCB55
-:1006A000ED6259CE56F50B90FE56ADF0BC36F31206
-:1006B0007CCEE9F8CAB4659598A77D556A4B25FAB2
-:1006C00069073D4F87E76509752B7FAFD1162FC0AE
-:1006D00073E60BEDC149888FCFE7BD7B27CA873B07
-:1006E00073DF7807F324DE300B3991AF88F5EE988D
-:1006F0009E06EB79ACD82DF23C6C440FC7C6723F16
-:10070000647F1EDB3885F2FA66CEE1E749AF65B15A
-:10071000B61EF89E9C15D03E637211D9913345DE0A
-:10072000C58CB70269E8179871435C43393A9C5D00
-:100730007495D7ACF724F0C3D5BAB17E6DA9B1FEDC
-:10074000359FB1FE8DC97F1A9B587FD9EE9F8DF4DE
-:10075000F4BCC2F33EC3973017D1BD4709A3FD32A5
-:10076000E1995C710E97E727FEABD8773D3399513D
-:100770007BD63EDB2E3C3720FDD7AA689FE065B6CE
-:10078000C20C7EEF03EABBB822F21C3D14D3610712
-:100790006F75713F2EBC6B817E0ECED3893FAA460A
-:1007A000DA52904EB21C267639F252A58DEC9A237D
-:1007B00082EEE4B9EA2A8D0530CF02869C83E51BE0
-:1007C00066D78BE8A70E7FC818E7DB691AE55B8A56
-:1007D00031185B41F587045D1F91F2FF079A585766
-:1007E000E04018EFECFA5C1E872E65745EFE6C65C7
-:1007F00009D525DD4BFE01AE1E8DA14145F427E94B
-:10080000F9A74E0BD1837ABF49F8BB34130259EADA
-:10081000927080B8C9423DC9C8FE9571BA7C9B6C84
-:10082000D7FCF87E0E93757EDE2B4BD4A1296AAAE5
-:1008300040FDFCF2EF487F3B7C419C8725CD46E79D
-:100840009386E3A35D827F7625F1914BBB9AF8E80E
-:10085000A7CE923B08EE6B9C2ED4AFA53097BA0C76
-:100860002AFD232AF03BCE4F6A8A4F47BEF966ED38
-:10087000F1A95A829C86EF9BF8F7A9C6EFBDF07DDF
-:1008800046C2F769F07DD9E0EF773B6D51D344EC78
-:10089000A74AEF217D18A5C95E23E6AD66F1EFAE4C
-:1008A0001179B1A3D3E07DD45BA5C63C1336D967DB
-:1008B000A3FCE4A4BC92AB94E539C85757DB9ABAC1
-:1008C0007BA0BF97C53A5E650A7EE682E72FCF2DF3
-:1008D000398AFC576B8B6898D7772D8BAEC2C5EDE4
-:1008E0009B167CC45D4CF2E159E4936635383603BF
-:1008F000EA67CCEDA36F2D22FE79CE9B39185E49B5
-:1009000027125EA417A43F492FC970F7AFE7D73B62
-:1009100029116F3BD851584ABB8AB1169E77ADE773
-:100920000FCC0B886886AD6534DA352F2F0993DC40
-:10093000B8CAFD00E565BD9C1BFC4F946775177E2A
-:1009400052A0E1CBDE796371DF00F0C6FE37E1959E
-:10095000F6E3A0BCE30F2D86BCE3E1F84C8E1B420E
-:10096000BB50C5FCE49D94471C9AE3F0E1799110DB
-:10097000E6C15652FC8AECC2E7146E6F87159BB035
-:10098000E3CE373F99717BAFA9DFDE33E4D77794AD
-:1009900073B83B6ED5E5FD35DC5E9CC7B83D394B81
-:1009A000B42F7451BBCCC3EFD8C9FD861D4F8FD572
-:1009B000B15FB003C97E60E9C2CE2C32DE9B837F7B
-:1009C0004AD640DEF86633B75FB7997C5594E76244
-:1009D000E1F7E29C91FE8C317CFC64FF626E8E62DA
-:1009E000884FF7D7FF4EFEC55277303F07FA5B5866
-:1009F000E62F504C0817F733027D3E1C6398FED655
-:100A0000321AEDFEAB59CB9BA662A2CFE21CA4CF5B
-:100A100009409FC506FA1C9D93C9E524C225E9B388
-:100A20009F2E4B93F3CA8217603F1DEECE5F35A316
-:100A3000BDDC6DF5F1BC5A9E27982C0712E059A039
-:100A400071783CAA4AF04CC27193E1391F3E49A427
-:100A5000CF6CC6F961387EC9D658D85931C02F2F0E
-:100A6000DB8335087F3FDFACE2FBA34170AB0EA216
-:100A7000AFEB6FE47194502AD747184FC981F167E3
-:100A800089F1AF5FCBE9F0FA7FB110DD02F8518454
-:100A90007FB6689FD5DD447954B36BCC2712ED0047
-:100AA00019B7A913EFCDF1949B9105E6CC34C64B51
-:100AB000EA6EE2F19AEB588B19E1BD7E8EB19F3A56
-:100AC000B6FE13CC0BABBBC9F83C98D31F67198B90
-:100AD0007196A3C28FD007FC82FCF4D3CCC50FDF84
-:100AE0000AF43BF6876515E877BA326BC9EE4D50CC
-:100AF000FFF1B6F154FF69D6B7BFF306B6EF28A1F0
-:100B00007A0D26B9E13E08F911F54DD58DD714C1FE
-:100B1000B847EDA2DF5BF939026F4AB06316BCE754
-:100B20009D388AF2216B84BCE95BC8DBAFBDD0C9BC
-:100B3000535E6FD6C9DF5893C2EFF579ADFCBF2B7A
-:100B4000303FB76694A8573C3F1EEB47954FE81ED1
-:100B500080DE268786F86FCEE57EDA09A54A741C0A
-:100B6000E0A52643F4DFC4E735B3E2D15CE48F9A15
-:100B70006ADECF04DFB4B5C5F89EE92CD57B736D72
-:100B800069280F259FB5E770FD2CEDA980E0FB6774
-:100B9000FCEFB68D807E0336C587530C4C7E97DF05
-:100BA0005FE5E0E7CB02FE220DFDBCD3FD3C7FB349
-:100BB000DAB62207F7E75F0F5A2A715E2E5BF9510A
-:100BC000B46FD2274F9B44F9BE3666463D0774DFAB
-:100BD000417C78F1270569486C0E23DD4BBA9A25D4
-:100BE000E9BDC648D7C0AFDB7232BF5C5E1BE8DA36
-:100BF0003E40D7C3D9B900D78F09AEA946FDD53F2E
-:100C00004E125F268F3B9CBCC0BF44793A005F27E1
-:100C1000F15F1E66C515237FB64BFEEC42382CA64D
-:100C2000189DB329547CE3E960EA307686842F1F4F
-:100C30007DAE1583E1C23F4DDA7FFCCF83FBF23CF2
-:100C4000D10EDFF959C6005C30FE2B240F577178A6
-:100C5000B62B2D5CBE087B5CEEE79BE57CBB8CF382
-:100C6000AD4AE1E7DEBDE87721DF7BF9F87EB8CF5A
-:100C7000631DE47C42426FCFB1059C1698DB75EE94
-:100C80007AA29F1B58F869B48F963983FF17F174C5
-:100C9000C4143E84FB9C85CC4FF157A08F77721211
-:100CA000EC0D096F329E9A8791A7C9F349C6CFC050
-:100CB000BAC5C8BE93E7D8FAE77B9EF3947689C796
-:100CC00062F4776508FF5486F0472145A17E9EC9EE
-:100CD000527CB82F98EE53C8BE98C96C249767D63B
-:100CE000727D9EE1E0F687D4FBC3F1C7159733927E
-:100CF00057331B993837C7E7954C87D9ACE70E2C8B
-:100D000067DAF4AD0B90EFD14ED107E09FE9E07EBA
-:100D1000ECEC5C213F58CF24D4F3FDF5417ABE675B
-:100D200012CA9FE4FBC9669EE3FED28C738CCA99FB
-:100D3000BE7727A19ECFA8ED998472CCE9F27B7390
-:100D4000270DDC1F988CC7D1B92619873B2FFA4C89
-:100D5000E61F193F6B7306C7E238D2CF714689553B
-:100D6000E14B151E97E83F588474EC76154D43FF10
-:100D7000C51C1BE82318BACB15BC3017E9ED8F0052
-:100D80000F6E0EF155C0E37535C17B343E2CE1E1A9
-:100D90003681872B855E3DFBB04AF1891A7FE94396
-:100DA000184208BD626611E2573FE94579BFD8593C
-:100DB00030A0A2F8FE634EB23316BF5A4FF195B180
-:100DC0005B4C4C4FD093E32229867B3226ECCB3010
-:100DD000D42FE8CC35BC7F61D728437B7974BCA184
-:100DE000FDA2572A0CF549B12986F72F7EABDA50C0
-:100DF000BFA4E71AC3FB533F986DA883C6D070DE2B
-:100E00007B9F55D83698F765F16F19BEFFCDB6199F
-:100E1000AF60BCF3A4D8F7B2B03F560A785820E9C7
-:100E2000F6DC7C637F5125AA5421DFF3BF05EB7903
-:100E3000BEF634C05C62BF0BDB8DF6C4E22DC67A11
-:100E400043F7A655281B07E779B454E35539C97908
-:100E50001E35AE7926A4CF502ED817E31011EC62C0
-:100E6000CC331B8ECFBF6CFD4BD8E82F5B7FFEFED3
-:100E7000160BD9F58B5F7DAA2A0A8FAC5EE3FADBED
-:100E800075E3FAA7961AD7DFE933AE7FFA64E3FA7F
-:100E9000BBFDC6F51F516B5CFFCC8071FDB3EB8CC5
-:100EA000EB9F1334AEFFC806E3FAE7B718D7BB7061
-:100EB00099713D8BC24B0DEDC9EB2FE565F19ADBC6
-:100EC0008CEF017A4D097420E96841A081F277C660
-:100ED000B47FCF304E323DC0BED144F7BFC13E6E6D
-:100EE0009B72FEF401D28AFCBDC9F4F16FB9C2EE67
-:100EF000147401FAA813E50AD8174F61593756D868
-:100F0000FB81A1ED0B29BF12F579E2BE7838B93625
-:100F1000484F897DF2B07A0AF7C9F6817DF270F404
-:100F20007B1CB38FC88E5A4F7EA51B5D1C8E4FF164
-:100F3000D125E8CF7D82F4F271007032C07B1CE7CE
-:100F400003E31F4F9940FE8D6FB328D9EDFF82193F
-:100F50009630D8CD98A8ADE23D4F3A95F5426F2F27
-:100F600014FE8F85F6E05BB9DCEF519885E3E6C5AA
-:100F7000E8BC147B6DC479DD237102E30820784F4F
-:100F8000611C01CA5E3BA79BD352AEF899EE49C0E3
-:100F9000E7FCE94A29D9B56A0AE53DCDBF4121FD03
-:100FA00034FF7F781917FA2CB95CB94CE2B35DD8DD
-:100FB00003DC2E48C7C39A1477624107E1CDE7C22C
-:100FC0007586FEB81FFF47FC7CCDE30AD32667D0A9
-:100FD00031335A675C6F3C0FA5DA389C8F9B990DB3
-:100FE000F1398105C90EBC5703D1C6FB1BCFFB7B72
-:100FF0006314FAD354F5FF7CAD06E3CF382EFA9F85
-:101000001D3E86FE66D5EB63E8BF1AF4FCC014BA39
-:1010100024A3BFCEF87BF88778917EC23C412FBBDA
-:101020009D8CFBBD92FC86235590C098BF63E6E77C
-:10103000C3BDDA16BE9F3CE65B634D9837636637E7
-:101040009EE7FB327B08F36D4F27E4C7C3BA0C79E8
-:101050008FE9B43CAEEF57B6365C8671A25E1107DD
-:10106000BBA7357819AEB7AAF9282F0EEF5772270C
-:101070007C6FF1407B029F6A8E0643DDEC08105EB8
-:1010800056B5B610DD98C53D50ABF36E730513FC35
-:1010900012178E14F6862DCC5C594C98C6F0F7C109
-:1010A0007486F3555DDAE9C47DA8D50BFD25CA2BFE
-:1010B000AD9025FAADD7B4B610DCAB9460103BB35D
-:1010C0008E66513BE0DBAAE1595478BEF52A92675F
-:1010D00016E76D3EBCF76738FC59BDDAE78972C880
-:1010E0003FD22887EE6FB55D8EF85AD9BA8CC69379
-:1010F000786B6F755D8EF58DAD5ED1BE82DA4DB5C4
-:10110000BA82F4711A6821867116ADC789713DB033
-:101110003319C603CD5E5B0499C8EAE1F0B2A305BA
-:10112000441F735D1C06F48DE5037DBCB3CC4CFB02
-:10113000D3DBF31DF4FEEDAF8F79D10F7C60011E80
-:1011400051FF8AF9F48F23F06711728869C100F2A8
-:10115000952557237F74866B36ADE3DFDA9FC4BBDA
-:10116000C5CE281FD492EF20BBEB7CE10C8D14F789
-:101170005009BC27E30FF04472F47681A7DBEFE25D
-:101180007EBEDBEF6094C7CE96C15FD5005D8D1447
-:10119000F2259B05A86C6F05C15282EB6563410B7C
-:1011A000E875D6492FDBD1BF83ED7ECD8DA1EA4D09
-:1011B000359E59586E9C7CAA1DD9F1BE4B3F8B6160
-:1011C00089BE74C497AB8145F0CC1FC58E3D781D98
-:1011D00035AFA789F6B43A5E4F17EDE9015ECFF758
-:1011E0003FA9D4206049F1977C47C6D5A351BE2DB5
-:1011F00060FC7CB2B8E7603B13F2C29131AB06DB16
-:101200006F6274BE40B6FF50B4E7384EAC29463921
-:101210003CC7F8FD5681876CC789F6E9149F31B643
-:10122000CBF84AA6E3EC2BF47D99B1FD41F1BDD397
-:101230007136361DDB471BC7DF20DA531D3CEF0834
-:10124000C4213F472FDAEF15ED766CC7F14B8DEDDA
-:101250006BC5F82B9500AD433F9F89F8E48E569DF2
-:10126000EAC97CF6EAC80C7E8E59F0996B191BF21C
-:10127000DCFCAB2379BE4C9ADEE3F70F210F657BD4
-:10128000864BA3B8AFEAB5101D591D428E083EEC3F
-:1012900097234A8B8F1317F7977F193D03E17E8EB3
-:1012A000F2AC00FE909EF3BE6362C1047996DB98B7
-:1012B000C28209EF7B176418EA5937E51ADEF7CCCA
-:1012C00019656877548E37B4B3583EF1C76D82AE56
-:1012D00052CA2A0CEDF2BE02A6733E9276B579F49C
-:1012E00014C37B674BF574A4EDD357CBFBAB7C36B3
-:1012F000940BB7394765231FFEA475321ADF20EF20
-:101300006CA27489D24B47C956B6EAA25E4AF5C7A9
-:10131000DC3CAF7A65AB8FD78B189D6F5ED95A4B8B
-:10132000F5C7812FB1FCD7563F957BA00E160EFB5B
-:1013300011F4AF433F3BA17FAC3F02FD63B91DFAFF
-:10134000C7F287D03FB66F857EB1FE10C085E583BA
-:10135000D00F3E7F00FAC7FAA6D600D5EF6BADA33B
-:10136000FA86D62095F7B636D0F3B5AD2D545FDDAD
-:10137000BA8CCA7B5AC354AE6C5D43ED16A1371FBD
-:1013800013E71F1F9BC6CF7D27AF7F469EF2D5EE8A
-:10139000BBA804455E65C893C8C8C37D75A7312F37
-:1013A00010F14770D8391E93E1182BE018CF622B4B
-:1013B00052B9DCA038EB982EDFDDA9C0A7235BF87B
-:1013C000BA1775C5A93DA7818F3756CC9379C22C22
-:1013D000AF8A1FEFC5F77A9558752A8F37931F8309
-:1013E00079013F55E2DC339179C484706993417F80
-:1013F00027CCB31F5F6E0E27E26D28782BF2787C26
-:1014000043ADECE4F79BD4B64791CD52FC2D74BFAD
-:1014100089AD2E10D5A0F40482744FC2F8733360E6
-:10142000930572EDDCE54C8732AFD1B8FFCA5D5051
-:1014300061D8E7A8E73632FD22E8B7CCB84F4A19A1
-:101440007D9BE13B5BDEF70CED16CFDD86F6F9B751
-:1014500014ADF2223E47328A3B59D7AF603900D7EC
-:10146000C28E4D045750E0BD57D1F9FDEDFBC5EFDD
-:101470004408FBFFC72E812FDB7ADAD78E75F36A1B
-:10148000497AD884FAE7E3A7D2498EEE7DC444FEB8
-:10149000ED712C6242793301CC486CBF006F7256FB
-:1014A000E9CA1C15EBE54C57B17E118BD3BE08EC95
-:1014B000FF3AA417B0FF1FB143FD4C7EF0C73CBFFD
-:1014C0002B4A7ABA44AC6789DC076DD192FDC373AD
-:1014D000F3C85F633C07D626F6012BDC55D918EF1D
-:1014E000ED1D26FFCEE9FDD6D405B01ECE9C3A2ACE
-:1014F000E5F30DBA69C873D1CBBE2ABF6C013D625A
-:10150000E4976508FF99CA9F67A1BBAA79749CF804
-:10151000A6CD2CE5989E8E726CA0EE4B27BBA23B0D
-:1015200087F0A389F5D9DB1AA4FC00394FED77D3F6
-:101530005C980F5622F24FF7B5DE3AB526211F66AA
-:10154000B7A0DF5216AB453D5A5A66F245A827AF01
-:10155000C17F611FDDEEC773FA5A05F3A1181EC7DC
-:10156000DAE9BCBAF6854A7940DA914B980E76B042
-:10157000C31165E1B2817E99F0837C47C8F5CF5CE9
-:1015800035340FAD40DA473ED4DDEC33873F867407
-:10159000F7598799B3E509637BA983919E5B546AE8
-:1015A00089E80AA623B4D33D8BDA0E85E515211C04
-:1015B000D3BDF3508F1F4C25BA4DDD524557C37B29
-:1015C0004CC1F57900C7991EFDA0491A57F05ED3AA
-:1015D00004CB2EB41BC7225E709CD1A584C7856244
-:1015E000BEFB5A57109E9E15F368CBEFC73B87870B
-:1015F000F9FC78CFE9A20EE9BF31CE734365F53728
-:10160000F0DEC6953155D874467CAE33C726CE532E
-:1016100006E002389F453855849BFCBF7C7E4D8F89
-:1016200070BF19C8B15A8ABB4E32B1C4B8AB2CA333
-:1016300042FECDC87311BC4EEFDCA90B2E4AACDFC5
-:101640004474FDB8C2E71F766A3C2FCDEFD713FD77
-:10165000C4EBE47E599C7F4811F0F6DFE3369EE749
-:10166000613A586C0BE62D0DB71FFE252ECAA4C497
-:10167000FD30E81818579D64A33C9F75328F4B7F4F
-:1016800043C77C332CF1FC8A4DD0E96AA731AFE423
-:101690005C1EB777CE89F5E8B371BEC6B8647956DB
-:1016A000C2BD17DDF5E4FF9171CCBE6E9E0F2EFD1D
-:1016B0006B4B0409F41DE578E87B58A5F8E592EE3C
-:1016C0006BF97DA1871EA07B56A12F1DE9A15EBCF1
-:1016D0005FBFC6E8EF59B03BB02A451FEC575AC46C
-:1016E000C2E4D748F62725FB917E9B27F6693E5634
-:1016F0008E71CA93EB8B8FA5E07EA688D1B9DB9162
-:10170000EA93748F3158FBED784F292BE3F7F424DB
-:10171000AFFB250516C2F33EB9AE631CE467D837AC
-:1017200089F3FFBE17CF7E7D0CF4F396AE18CE8101
-:10173000BCA59B098FE381AEB1EC64AC76A8FBA09D
-:10174000B2F34D5FEDBCC0A5C6DFD768EAEA3996B3
-:10175000AA93BCCBCA0778FA8EFD3EAD8CF8274E13
-:10176000BF075157C4E141B8F1FCCB7ED3277313B7
-:10177000E9607CBEC6ED837CD35793BF3546B8CEB7
-:1017800094BD99750D876B1CC2D51B3D919568B7AB
-:1017900048B8F60F73BFFAA55F154F938DFA200175
-:1017A0004F53FF129EF65B86866796C0CF4F8EF230
-:1017B000FB4206B77F45FDD56184F7CC63B1EB51A1
-:1017C0003C02BCB3087FDE5359143315F8EBAC145C
-:1017D000F45929E48E8FCEA8B0D0DB17537E5EA7D4
-:1017E000C6DB43772E8AE07902DF8B0B0AD1DFE07C
-:1017F0003C6EA57B9E42497922B25C2FE6B13F57F1
-:1018000019120FABF3B9BC78F1B5F9D4DFBD6F593C
-:1018100019CA83ED22DFF55E57A70DEFEF9578C467
-:101820007A0594214B7C112ABA7B2B3FB3E98E2198
-:10183000C633F1F1EE4BE21B399E2C57E49772BB95
-:101840005439AAE23987FB2E7D93EED9BAAF5223E1
-:1018500099FB37E37F7D12FEA36F667D9DD3CB8A14
-:101860007CF4A32AEFA57D03EA2125FEB332C49FB1
-:101870002548F30FBD6D653B95C1786A14F42BE7DD
-:1018800027E72FE1765EB680CE99E07A20E0ABC5FF
-:10189000FB524FA40BBD87F3223D71A9C6CF894CE3
-:1018A000D2685DEF9B3C85CEF5EC17F914F14B2C1B
-:1018B00043FE2EC333026FF79EFB450CEFA90D7755
-:1018C0009BE95E05A6F578BF0974147A5DA37B9A3F
-:1018D000819E6AF1DEA8175F3B9B86FBE803F966F1
-:1018E00082FB403E97877DE7D45A3A6FF3DA672E42
-:1018F0003581FE9FCE57855D128BE1399A8D15FC9F
-:10190000DC8043D8018ED74E3520FC8EC9DFB32A48
-:10191000097A764FBE95BEDB688967F9300E744848
-:101920006551EEDFA1FBEFFACF0BBA381E9A2B8F71
-:10193000929DE0E8E6F7E23D9DAF135C08F7417841
-:101940009E32EE33573DB657C278A306BE77BAF83B
-:101950007AA64CE2F7D0DC77E9CF5D78EF5EBAC2C9
-:10196000E8FEE84B0ACC06395E5FC4D7A1B3321655
-:101970001B85FCE5D228AFB6337A9B0DED7AC917EB
-:10198000A347A9F4DD6A9197BE7A7229F199A4E37D
-:10199000B905C157916E36025F3C49764E2C309D99
-:1019A000F0E32AC7FCE3C795581DB73F2C2ED42F70
-:1019B000A5269381DF8A0B38DDC812EC52B277EE90
-:1019C00010B42CF57D5BC4C630BFFFB7E766A5A396
-:1019D0005DDA9627ED3CBF0DF1B55D09A417E1383E
-:1019E000FFA5D2BEEFC5D74E34E0B86D302FE4DB93
-:1019F0007B7EEA588FF6499BCB4F7C2AC7D7DC26E3
-:101A0000B11EBC9FFD16FF2BE86F8CBBF97D4447D0
-:101A1000A65C6343FA87F74CD8CF7BADF80B1AD896
-:101A20004F0DF90716BA66CFC0EF16B1E02AB46BB6
-:101A30001775A8867B17EE11F262E1B914164DD81E
-:101A40001F2C9CFC2D3A37B6F05C1A8B82BD758F2B
-:101A500038177D8F3857C40A383D3B44E915E5DF18
-:101A6000CCF7BE24BD95F9CBBDF339DFB302E8B79F
-:101A700049E9B114C1101BA7FC9ECEEBBCD7EA62AA
-:101A8000D192047807CD73048B268CD3FFDE391BEB
-:101A9000CD67607D39FD0ECCD7417878AFD54B78D6
-:101AA0001CBEFF91063C0EF43FCA80C7C1FD97D013
-:101AB000F8EFB5967E49FF1386E95F37C03FD0EF58
-:101AC000681AB7F7C8FC1FA702DF1D89DEBDEDF954
-:101AD0004AFC1D332BFD7E01EBEAACA673848F33E9
-:101AE0003A677AE7E1DFBD83F99A77EEB2F8708C56
-:101AF0003E737CAE6F083D339AB9C2789F972CC76E
-:101B00001714D37C929FDBB4880BF3326DA59A0B2C
-:101B10007F1FD1C66291BB71DF5269233927E3422F
-:101B2000B2DF3FE5A9F23C3BC907796FCB12919731
-:101B300057EC085E81EBBED4D4DEFC13F8F683D2FA
-:101B4000363A37CC989BF633326EA3E12FBF15A3FC
-:101B50005F30C0F0FCCD137A70067EF74310271873
-:101B6000C7512FD81DC4BCB50D62DFB8C11EF3FA32
-:101B700012E4E60D05DA57B317DA93E876D22FF7B9
-:101B80004639DDDE50807E2235F6C4FC22CCB7ED2E
-:101B900011F776E9168A77551EA3FBFEE6CB7DFF8B
-:101BA0009AE4BC8E7C37DAD132CE94867977686B32
-:101BB0006CE4F7BED5A7F27AFD7F8CA07310B0FF5E
-:101BC000492D43F9B25FE5FE2011DF3A2BE6D067DD
-:101BD000DB5840F9F7221FE46CF74B74AFE4D935BA
-:101BE0006368FDEB5FF83EDD0BB73F97EBB1BE439B
-:101BF0004ED263F5565F15DE5BB83F97DBAB9D5A5F
-:101C000034AD22C17E5D9D574DF2F9E335634C89B9
-:101C1000F18FEF0A79B051FA37B578159E67F9B8A8
-:101C200032FA33D2A307ECF43B51A683BFABA2FB3D
-:101C30002D375AE97701AA0F8EDB5C87FBC3348D01
-:101C4000F2914D07ED04CF9975FC7E2DFC16E55DF4
-:101C5000D3C191F4FB56F5A971CA276C4AF195607E
-:101C6000DCAFFEE054BAD7FFE486710528FF4E646E
-:101C7000EA0574AFF1063CF409F54363F9F3B517CF
-:101C8000D37955E7C6D4E0507E10A98F92EFEFDAF2
-:101C90009F5BDEDB85F81967F3A1FC7D4FF1F1B89E
-:101CA000EF2BF1D93AC515F9F9D27AD769FA7DBC8B
-:101CB000FA8E776F62F4DC43742BF773C9E3D50BAC
-:101CC0007DB5DF129F8BBF4B56BF52E05DFC4E626D
-:101CD000BDA99C7EAF4FE27D63D23DB74F08FD2486
-:101CE000CB93AF69745F20D81105E81F3A79D84AC1
-:101CF000747672E3043AAF2EC7AB079CB8802F4FBF
-:101D000064E813715D9F16F2AA7E25DFA7CAE7304B
-:101D10007E0C7FE7307E48A5BCAE3E573C0DE3927B
-:101D2000F23D59EF9F4FB74ABF97B53FF7455A6FFE
-:101D3000A02786F4647AC1497A3AF4827517AEE72F
-:101D4000C7952C8CFECFF05BFCF7C78E1CB292FDC2
-:101D5000DC779CEF6F07DD9FE68817E0FDA1A117F8
-:101D600046921CEBCB8FEFE0F6B69DDFABF846F06A
-:101D70006211FFCD11F711E6A09DF7F9217B14ED5B
-:101D80003C28299E1066BBBDF4FC702A43FF0F94CB
-:101D900014CF63CA012FFDEE0C6B17DFC7E8FB3BC6
-:101DA0000B8263512EDF590CFD3BF0FB53F4DEE751
-:101DB000A38217520C8AB15C315E2EF59B1F2CA4B6
-:101DC000E7CA675EFE7B2AEDA23D46ED216BF0621D
-:101DD0009AC7AF9C6CE710F3FCAAF7EE1D2D1841D3
-:101DE000EB28E1063C93DD988C97B30526F17B3B0D
-:101DF0001C1FC974D9BF9E5F021FFA5FE8BCF621A1
-:101E0000BE8EEBC659B81C593B81EC63D69662C8AE
-:101E10009F5B7188DFC3D0BBC149EBDC67F63F84B1
-:101E2000FA28FE8699F17BEDC022403FC5E4A1F976
-:101E3000E523914FBF642DCFB3FBE8D1F70BE63913
-:101E4000F05CF2FB8673C9D25F089DA4A13FC6E196
-:101E5000D3D3E697717B5D25F8F8EF7A6D34EBF418
-:101E6000BB6BE10DE3C81F71D2A21FA4DF875B77B4
-:101E70008109E94A2D17F277139F9FBC2F4BDE7B18
-:101E8000958C9F8AC262927F4D2C7833DEA17E8230
-:101E9000E959C26146F7FF917BDF8469889A9FE226
-:101EA000B6AC85F4C2E07BF62C5FF2BB6CFFBBF5F1
-:101EB0002A5C2BF4EF9587D350AF7EE0E2FB463AE5
-:101EC0007D8F7A5DE5F36CC30F30AF8305A6144EAA
-:101ED000A27692871F28BC5DCAB941F3477AC17EBA
-:101EE000F03DE8EB9A42EE7F63AE0C71C82B6CC1FB
-:101EF0003C4DA99F428A66C273F3A7DC7A1AD2E3EB
-:101F0000A9B5C5192B300FC6AD6725DAD5A1A38CAD
-:101F1000CE8BEB78DFF8C5F8FB32FE89E8F7DB9F64
-:101F200061F43B24C3F3E4B49EB989ED730AB99E0E
-:101F30009B5F28F699854CE45726E38DAFFB62B191
-:101F4000EE6A79F072DA8726BDB7784BBAA087A41B
-:101F5000E7EDCF7F97F2A01E36DE1349B15F18EF91
-:101F600083572C61E5422C5328AFBD611397730D45
-:101F7000AFCE2CB98BD7E95E85693BEFA1DFE35982
-:101F8000B0EBCA12C6E516AD83A4C70505FE12B4B0
-:101F9000E3E25B5517F245C31695E051CD3ED756A7
-:101FA000787E7A8B99ECBB0601CFE9BC601AAD9BB9
-:101FB000C6340BE0FDB4164C23FB75ABF8DDA1A4D1
-:101FC00079C07B6F6A1543E0C7C6D799F0533C04CC
-:101FD0001DBC61A2755A80BF0B8970EC54C8BF79D3
-:101FE0003A3F7833D64FC1FE1FCFE9AB9B96D07DE9
-:101FF00036C9F83E6D0B127D2E16F391F84C1E4734
-:10200000E2B30FF189F6D22B5348EF851E5491624B
-:10201000D98BDD9FD2BE7CDAA12BDF998ACF3781A5
-:10202000DDA2A39E1DF5B36FA39E5BA3528C7AFE27
-:10203000A1E22C96A4AF71FF39FFF53969A6043DE2
-:10204000A93EC8F1A43AE7A42DA4F7CF7E1DE9EB81
-:1020500084EECBAA4878EFF1C2FEB88361BDEA37BF
-:10206000FD210DC769586FA679C975E9C379A07CB0
-:102070006B4F8D20FDF7E5C5A95FB94EFDF48DEBE3
-:1020800020E909DEFBAF429718274CF2E85451B023
-:10209000CA37049D2C7A00C6C5FEB638E9FED2F3D5
-:1020A0001D57E2A37FBD055F531DD7714711F9D1BD
-:1020B0004D6F6874C8E044FB5505C8C7F5A02FD024
-:1020C0006F51AFC4DFA17B640F59E91EE6FA4DB72B
-:1020D000DC8CE3D51FB79AB0FDD4E1AB26125C4986
-:1020E000EB0A782A188ADEFB8AE205BE04FC813DF1
-:1020F00041FC2DE7930037C101FB29BA8FA8AF0837
-:10210000D633410EBC59C8ED2E78DF6521FAE6F7CB
-:1021100061F5CFD795345F57D27CDF6444DFCC17AD
-:10212000A4F92C78DB6AC2E70BEEBFB604F73DA733
-:10213000D64DA7799DCAF04F44FE3A5500FD0F21B8
-:102140002F17DC0FF32CFB0BF36CB7D37A0D3BCFBF
-:102150008CF80EF617E6F989A04339CFF7343D0D18
-:10216000F3F943CFAA0CFD2EA1FCC0C6A9BC4EBFFB
-:10217000131732737A086D4AA57CDFDE6EFEFB040E
-:10218000520EC078E7490F26A28753D5FAE6C9D088
-:10219000DFFF073F3717B700800000001F8B0800E4
-:1021A0000000000000FFCD7D0B7854D5B5FF3E73D5
-:1021B00066269364924C12088140983C09908449A9
-:1021C00002888A767804D1020D4F798993071042EC
-:1021D0005EA0B5696BCD4002A2450D352A5AD401E7
-:1021E00081A2A20D0A0A15BC032A6245C5578BB607
-:1021F000E526405179C6A05EAEB5D7FFFAAD7D4E5B
-:1022000072CE9054DBDEFB7DFF7C1FDF669FFD5AA4
-:102210007BEDB5D75EAFBDE7C23DAACBEF16E2E4DA
-:10222000DD056FFFBC17A5F7AA2E81FC58DFCD0294
-:10223000F98FC32CFE144A938BA670FE659B6BA589
-:1022400022C489A6BFFD41A1FC857D36B7A0F20B53
-:102250002945F7CE467E8FEA5A41ED2F0C689F251F
-:102260008673B9D844E5EA5D239A502E1E1EE6CA4D
-:10227000A0F2F20D61426409FEFB56687F23E93B40
-:10228000520BA56B556F7834A54D2FFD44C9A56F32
-:1022900056378F57F3AB24F7DD347EB95558EDF937
-:1022A000A8DC9E392D4788F37B6D1303D9323F2379
-:1022B00087CB3FB052798D5DF85AF87BAD7D6A0EC1
-:1022C0008FE2B6D2388BA90F914AE9FA18EF60EA8B
-:1022D0007F318D9342E37D8BBF1F5C0EDF0ECBE71A
-:1022E0000B8AA89F7B6D62F673D95DF5F434DB4DE4
-:1022F0001DF6466D7B573B558825C63CE1A122243F
-:10230000BF14794757BE32A4BC2AA47C47BFCFA7CD
-:1023100014392F1F7F03C61FD185C7120D8F3B2C89
-:10232000F41DEB728F12D844FF2DB1BAEDCB09FE2C
-:10233000E7C6889BD14FA95538AECD47BD0E9E5FED
-:1023400089553486E5E3BB87EBE9F3A6FE1AC3E2C1
-:10235000281FD1CEE353BD8976439EDA9BE09AAB2A
-:10236000C1A3A74BB785BB4EEAF3A07F552DB1A6FD
-:102370007CCDEEBEAE93067C2FC57FFAD2BF49342A
-:10238000FB91C08BFCABDADD7A3092E8A74DF1CD42
-:102390007553BF170E7E1D9DEDE6751F5944EB9BCF
-:1023A000AFA63E7F98E6DBBE47F56C42BF6FD8FD17
-:1023B0004A0CFDE79B8B0F6EA7EFD52FA789BBDDDE
-:1023C0005DF30FC5E385DD17A353E9FBF943F60879
-:1023D000318CE6B9377EAC9DE862475C7BB778AF5D
-:1023E000D5D65DEFEFBCB5357AAAA1DE79D11A3D1D
-:1023F000CD402F25BB2FD68B5CC69F5FCDEFC2EFA4
-:10240000897DBDC7AAF4BDF4F7FDC65A28BD5FC3D8
-:10241000DBBD36F7136B096EFF9E30CF1682FBFCD7
-:102420001BB32D687FFE8D722DBDCDCBE95F4F2490
-:1024300063FC688BA4777DBC356E0BF7536A697BB0
-:10244000EC1ADA8FA5BFEB93D290D2555E6AC9CF52
-:10245000C43A6FB7B52F00DCE715B14689EBEAE760
-:102460007EB79BDB9FDFF3C963E00F27EE1D904F24
-:10247000644DF941B93E2A3FFF5141A68BFA3D7F99
-:102480004F5F0FF8C2769BFB36A6B7BBA23CD8F7CE
-:102490007A7F18A716FDEFB962A40FE947125ECA4A
-:1024A000E7FAE4B87E25BFABDF688BFBBED1E0174F
-:1024B000BFB779B650B2FCEF697D62313FECE76E91
-:1024C000D6A1744D98709BF8C94A86BB4478EC221B
-:1024D0004D960B03BD958922FEBEB0C9FC7D11F15E
-:1024E000097C5FBCDEFCBD5C34AD6EA5F92D09989E
-:1024F000BF0BDA3FFE04EC6BFDAFC55E14057AFF3F
-:1025000036CC544FF835FE401F095F25B41FC1C7B4
-:102510009E5102819558DFBB549E67E8BCDE75A7CB
-:1025200070BB8722FF6741AB615D8F5B843591F0A3
-:102530007ADC2E1C89F9E8470885FAF5EF0B0B6C5D
-:10254000A126770FFE2AB9047CAF31C22208BE5BF8
-:102550005DE07C42ACD8F74932FA295D53E86D352D
-:10256000C077C1E67DE8E7D4BEFD5DE2D754EFF861
-:10257000D840D35882EBF8DDAAA7A11BB84EAFB163
-:10258000884001E1E32E2102F1947FF293E4625A44
-:1025900097CFB67C925C62A47F45CC36D2A39E12C4
-:1025A00024BC3EEF61EFD2FC8ED35C309FD07A5DCD
-:1025B000EB6B8657C767B82A6ABBA387CF40F7542F
-:1025C0009EF5775578B1EFF7D902A0CFC88D5F3C63
-:1025D000380FF4B9D7E64AA1B16BF6A95E95E62D9E
-:1025E000F6A8810C9C637B4F4457E09CD953E05282
-:1025F0000DF3AED9A316E17C39BFFB62426936F711
-:1026000033C5ED44FB073CA0DF9EE0F89B5BFDF784
-:10261000F89FD7CCFFCE657F907003F8C0C6539962
-:10262000E0EFC407FFE6A6799ECFFCC68EBC10ADD6
-:1026300023417F045FB49BE0BC10F82A5A105C8EE3
-:10264000BDAA37D0CD3A44A5D8194FFF327C130923
-:10265000BE842EF8089EA894115D7056BBDBED3841
-:10266000672F38A273C14F694293F212B4F3C90DB8
-:10267000FE5A3A49107F1DBF67E1CA70C80B4D8AE8
-:10268000278CBE97ED55F9DC2ADB1B19C016183FC5
-:10269000C8C9F9D247D54018E527A8A3FF309BEA5F
-:1026A0002FBE47F5D08E14FB37DEF6071BD6758399
-:1026B0004DA01C88035C4B34B896ECFDE1670A8D95
-:1026C000B378DF2D0730CEE207140F17A8F3EDE83B
-:1026D00077C9438A88574067B6E3463A5BD864CEE9
-:1026E0002F12AD0B5415FCC1FC9DF09E5C41FD9674
-:1026F000EF0E73DD8DF102A1E542BC4AF0D468FF14
-:10270000CFCA583BF700D5CFDA68673C9C0F17E279
-:1027100008F6ABB53541200DB626631DCFEFF96B3A
-:1027200032D6B1E677FF9529BA59BFCEFDB437AAA4
-:10273000D7A94821AE4E51C4B7A9A0FB8B538ABA82
-:10274000A96F1B20F7C5369BBF9F87CA0F6CFC8AF9
-:10275000F9C1853DBE81AE6EE8B76BBFFAC32D8966
-:102760004883E102E9F016D70DD827240F62BE3561
-:102770009B564FDB44F9F0976C38B9444D8693F77C
-:102780000BF6C74243BFFA3ED906BE807484E40FFD
-:10279000B601F21C3DAA9D7BDBF6774CC9E8069E8C
-:1027A000A36E1BD7B30D105CEF5977D15CD05B845F
-:1027B000C51F0DBE2DBC5E772FC2B3A2D157435D9E
-:1027C000AD82EF89A289D3FEA285D34785F0395126
-:1027D0005F785CC0B3100362813FDEF38CCFBECC68
-:1027E000377FACAD217835E8C41F2B025BE8FFEAE8
-:1027F0004687506320EDB546A35154CEB4FB065234
-:10280000B9ED03D5A240DE1DA0AFA7C785FDF7A592
-:1028100073468C71FDF61F2E9988FEAA76A9228C2C
-:10282000FA3BB7D326824ED4A7FD027C1CFEC29E83
-:1028300002BEB4571190976B288FEF35A3ADDE80A1
-:10284000012F77A4D8180FD52999F29CB67A0F4D8D
-:10285000A27ECFBB4AEC90EB6D87CB26E2BCB125C4
-:1028600096D801D7FEC3631D2958B7582BEF9BD5C7
-:102870007BF5718FB8D07F54EC070C6F63B645447D
-:1028800053BBC6A3610146A643F2A1300DAF8DC173
-:10289000F10E7737EBE317E393C4282ADFA94E0440
-:1028A0009CE75C252EACA32D96E8EE0A6A6FF34EEA
-:1028B000BC9AFA0D8B8D8B077C6B52D2783DBF8A08
-:1028C000AD6538BF22F1C2CFFBB7B608F9C6FE65C9
-:1028D0002AE3BEE921DECF350E397ED43E95CF51B5
-:1028E00071A543E3DBEFBB4A699C05C9BE47410FB5
-:1028F0009DFC6DC4AB02FC39CB6261F9ACF135E7EC
-:102900005AF021BDFC6C8AA4377D3D56F5B2BAC0A1
-:102910003F1ED5E87395ABC8916F98A7ADB745C377
-:1029200057910378DA612F3A84F3A59DBEE3DC3C2E
-:102930009038CD013D85EA59D0CFA97ADA3176F4C5
-:102940003BC301FC2EEA553201ED168BDAD5D86F68
-:102950008BD7AB2268E0AB8D3639EEA24B11221833
-:10296000DF35EE225A3F6E7F295A04E9DC6D0C9761
-:10297000F51AA3E4FE792345EE9F0FB5F9B469F982
-:102980007F99AF7BCC7CFD5CEC1FB69648FEFE4683
-:102990000AF55BA5B44E48A1F9AD4EECB003BFA754
-:1029A000EA5D22986980F7B279C68BA061DCCE7AA5
-:1029B000971C3C9FAEF57033FC5DF375321E4ED50F
-:1029C00027321E7BEE3FC984C7AEFE534D78BCBC98
-:1029D000FF4C1EFF547DD677F43FB487FEDD26F80A
-:1029E000BBFA4DE771C56EDF40F0973B5DC40F98B1
-:1029F0006E885F50B95DF13D7E35E4DB8FC204E443
-:102A0000BEAFC27D835C06FEF00DCE65D6E782497F
-:102A1000E0B77ED1CC69CDEE8B13D0DE4D7C01FBCF
-:102A2000492FAF11ED0C27F885E88335B4BAB97C8E
-:102A3000B76F10F4221D8E4E79E675A7DF42FB209A
-:102A40006CDFDFA3B18F2F58DBA778286DD9AB4699
-:102A50001AF7757CAAA4A7B103BEC86DA5EFD56807
-:102A6000477CEFB697970E027EAAC3DA7301F7810F
-:102A700097FF968B73E4AB7D4B07E2FB36AACFF250
-:102A800087BDBDDA63E82F5DB8FC96515DA933556B
-:102A9000EEFFD0EFDBF635F4031CDB89BD09920BAA
-:102AA000ABEB2A0A4EC6830D79EF07FF12C4B75865
-:102AB0001FDA3D5D1D03F9EE439279283F7C8F9428
-:102AC0001B860F10014B0AE4BE0F67834F548FB073
-:102AD000BBA00A47E41D61793B6284C3A550FDBFDA
-:102AE000F797E3DB212FA4A17D613CE8F9CA64F1EB
-:102AF000EFC96D1B42F64FF0BDEAED345E95DA3A50
-:102B0000659CC2FB283F157CFBAD2FDED6F4D704B5
-:102B1000ACCF019C6B04CFFB5A3F65A9BE2B50CFB5
-:102B2000E768BDE70AAA377356DF64E847C59A7EAF
-:102B300026261152AE647E94033BC8E5E7B6D483E3
-:102B40005E527C3EE0C1DFD7E1C1F935344938FA45
-:102B5000125E456220751A8D3B21D5A2DB0F14C091
-:102B60003D449BE333FD5A96C7F2391988031DFD96
-:102B7000B3E34E4BF54E06FC7AFD0F67CDCBF175F6
-:102B8000736EE8F2BCDDDEB20C70B65739597FFCCB
-:102B90000045D4EE89596141351A7A8A730DF4F9EA
-:102BA000A3910B0EF6267C8C8FF2CD43FFB36FBC46
-:102BB0007E35F2CA8178F772D07371EB48D6EFC2D6
-:102BC0007D37A3BCD2E11B9840533C37C037280661
-:102BD000877C51BC5C27519453D42DFC129E6245D6
-:102BE0008EDF18E52B473FC596238F5D816FD62377
-:102BF0006C6F108DBDB99F737651DE9DFCAFE3E124
-:102C000098368FFD3671ED259ADFFE75319E06826E
-:102C1000B7ECCE1B17D450BAD0529410544D70DF7D
-:102C2000964A5D57FA8B07F62579EE9C4D83BB4E8D
-:102C300083DBEACA34EEE750B81B7479E5170AEB78
-:102C400083FC47F917FDB181BB291F66B9F8C17430
-:102C50009C5B3916B6936C88A0BD457AE43B1A9C00
-:102C60008FD2BE73C4F1F735F89E1821DB273E687A
-:102C700009C07E5034760FAFD313D54E8F4A6315FB
-:102C80000BB71D7250A9F0B2FEFCD7317FDBD74ADB
-:102C9000F36A4EF5DD07BCDD1C6F49FE80E1F00DE7
-:102CA0009D0A796BB49CC73F9037791ED384CBC6FD
-:102CB0004299586B81FC31CD25A7B25091FB63BA84
-:102CC000F0DA30DE4CE1E37AEF9DB77BA14FBC0731
-:102CD0005D88E0BE51F8F9FB1C11E0749E0872FD9E
-:102CE0009B442BE7757C137DDCDC4BD2C7277D54DE
-:102CF000C6FF56C0FD6E64EE803A9AC7D48706655B
-:102D0000B07ED5DC9BF1F35D704FD5E886F6EF6FB2
-:102D1000B18ED8BF33A89F693784ECDFF1BDF5F5DC
-:102D2000CCF847FBE84847A7FEE4EC4B78B84E5B8D
-:102D3000D2EBBC4B597F12C2C5F2D18FB47D5BA8D8
-:102D40003A452F5A9F236ED297089689639625623B
-:102D5000BEAFAF106F15D03ABE3E46150D5CD3CB5B
-:102D6000EDA668FD4DE93FE133D85B0F8B60AFE125
-:102D7000D4AEF092EFD518827B8ABABD3196CA27BD
-:102D8000F627BDC6C0EFAEEFB5C30AFDEE8674F3FD
-:102D9000F749D966FD67B2685231FE94E1E67AFBE5
-:102DA0008127A2B3F753A5FE22868821DFF27A0B92
-:102DB0008B713E1D932EDA2F101C1169BE8FB12E20
-:102DC000CB27FF7501C61556399FEAB755B6EB1DDF
-:102DD00027798B28509CACA7932253CA25C87F4AD9
-:102DE000F203D2D3F56E4ECFD2798FF2F3F51ECE29
-:102DF00017A4159D40BF256B3EB7627DEE0C97F87A
-:102E00002E6F699A00B02A76B71C445A162C9A8005
-:102E10006376D1A1DA8348EFECD4DB6A59BED3E103
-:102E2000BE45A3D35BA2A6FD3087D6E1963DAA8717
-:102E3000F303A64D9FDC0B791BE77BA2A3AA4B44AF
-:102E400033245754ABDE2F0197776FDBC1789ADFBD
-:102E500027F5A318EECFEABD0CF799FA899C4E4AE4
-:102E60002BFA1BE8CC2B3E67796CF2F6366B12D549
-:102E70002FF42A5EECDB6BBD2210A0FDB7DE26CF5F
-:102E800081F5740E601F8FC999F6E8AD027CDA6790
-:102E90004BA37166DEB0A410E34C19556C45BD1B05
-:102EA000BF211920A58B4EBF8BEEF5F95769EB7644
-:102EB000EE6585F1D8B1332D0672C1F25D697D9062
-:102EC00012BFD4F5DD48E0ADE39285E1EC381AC1DC
-:102ED000FA86DE6EF9AE48E63BCB07D803C260B790
-:102EE0003C43EB2C0CF2E699677EE2369E2B67E2C0
-:102EF0005ABEFA18FCED2F92BF916473EA11F0BF2D
-:102F0000FEFD3CA093F39A9C4D7A4624CEBF6ACD39
-:102F1000AE08FE84FC990869CF1DF96CD258EC2FDD
-:102F20008C471C4EE8FC2BF3D987527FEEEE1A6FCC
-:102F30005BCBC28F1FA1FCB980C56FA3F3E99C686E
-:102F400039FF3BF0DFCD4EB6EBDDA9103C387FB743
-:102F5000F4E37C96628DA8C3F92B02BCBFB314B70F
-:102F6000B58EF855E5730FF703FDBD44381845E5F8
-:102F70002FAD8B647EF692CD73AC0EFD3D2AFBFB2C
-:102F8000CDBD3F3DBE1BE93D55F93FC5F2A4C5315E
-:102F9000FECB7EB56408DAD3F92EFA527F4FBFA874
-:102FA00004C3693FE734EF5FD997E01BB6A1CDD2E8
-:102FB0008FD2BCCD4A03D2A1036E3804BBF30D6996
-:102FC0006E6E5FB03D454DC236EC17F8F8077CEEEB
-:102FD0009BE581ECE6CFC7F6135D72C110A5E5F461
-:102FE0004682352CF968BE8FF1D7C4F3D9B577FA8C
-:102FF000FBF304E6411207E02EB67BF81C0AF83713
-:10300000623DCFF9B23CACD715F91F069D9DF32563
-:1030100078702EBD407AFC55A87FCCCAF37C71F342
-:10302000BBD1B0EBC4907E1C0E7F485EFB04D4AFD6
-:103030001AE0167E6A3FE0B1EB26023FD53B776D82
-:10304000E47E2A1D1EE8B9E5BB2E1E4C829C78BD8D
-:10305000F064800E77CAFC2FC77B3D2A4DB57CE318
-:1030600097327FA488F345A4755A51BF54CA470FBD
-:1030700069E79F68CD65FEC8A4EDEE5AAF5F523197
-:10308000CAD7A7F8FBC2AEAD9F9B74DE55A561AB56
-:10309000D865FB2363E725335EBEE77967D7CE2D7E
-:1030A000BDBF87ECC21F4EFDC06C033BFA06BB3CA4
-:1030B000A7B7107F01BDE8E7348DFB0BEC5F6AEF2B
-:1030C000053F4D52959C9D848FA487C258CEF8BE73
-:1030D000E3CF8E59CDE7B62E67D544483EC8670585
-:1030E000B55F18E5BB0BF35BA89DF3C2EACE861C67
-:1030F0003223CA7B37BE573ADA9331073A3FEF455E
-:10310000BE5A25B92BCD207739E3BED7F95917E53B
-:103110006DC67CBE6FFDB19104670C525DCF22ADD0
-:10312000A35B7E9CBABD05FCF88130C98FA30A98C9
-:103130001FE9F30BEDFF15DAF73EE233AFD179E289
-:1031400023DC8F738EB1F27ABE6AA93C48E770A186
-:103150001C01846C8D1DCE796F14E16FBC5315BEBC
-:103160006EF4453DA5F57A1EF899D02BD254AFB038
-:1031700057AC1DFBF7FBCE5BD5D6478DD0F9A9BB6D
-:10318000977076376F39CF5BC247F4015EC62ADF8E
-:103190006FBE0E5BD141ACC338671E9F8BE39C535F
-:1031A0008FF904C37F18DF43E7193A1FE1F87EF275
-:1031B000D28F15E1B760FF7D6E67FBDA5E5BEBD304
-:1031C000BF257CEE5D92ED819DE805F05EF0CF6855
-:1031D0003BCBB37BA3841F7C65EFD48400EC452FED
-:1031E000414F04DFE82D6479B8ACBF770E95537F6B
-:1031F000FDC2685FC05E342F42EB9F0646FB157D23
-:10320000B87D8352FB660EDAAF8864BE733420F952
-:1032100078736C709E4ADF9B3FCF14A8775404D616
-:10322000A4A2DEEDD25F43E54935D46FF3922112BB
-:10323000CEFF51F9DC68CEF3F68D73321F67FB4C7D
-:10324000F3546F5FF8AF7A69EBD5BC5196F7833DC5
-:1032500014E52994A7F4639BAC3F57ABF7914697CD
-:10326000B4CF990FF8A6445A41E7FDD24BC2D29988
-:103270002979FBC2EFF3485906DB28E7565C9FC269
-:10328000F4A3D9CB666B7C5BEF0F0D1C23212FCBF6
-:10329000BF390BB784839E679687B741EE3B5ABE12
-:1032A000320A7AFB4C9F1A0C835C39A3D0DB29AF1E
-:1032B000A5625CAF1CB74CD7FF82A5C0EBCBED0E6F
-:1032C0007137CBF7C102A33EA5AF6F55CB9878A35A
-:1032D000DE5C6127FE42F02CD1F66D9AD3D73B7DA0
-:1032E00004F4E9EBE38DFAF4A7650FE4F2FED2C62D
-:1032F0003B5BEF8D3F990EB96D22A7FA789D7A0F4F
-:10330000D64DE757A097DB25BD086BFB478B29DF20
-:10331000307B8807F6EA89D31C4C6F1D2DE12C1FEA
-:1033200037CC8EF0C26ED7B02B8CED06376BFB839B
-:10333000F428A61BFFBE28EEA7D22EF395CF65304A
-:10334000DDBC600F3CB915E52F87B37FB6325A8ECE
-:103350005BF9BB248D2EBD29AB7AB15F8EE9A53216
-:10336000C21DC3E5BF8F677A7A36DC57007C127DB9
-:10337000B25DBCD21ECC8C25FC1FD3E80F7A23FB98
-:10338000F56AA3986E8596F7FD3C9EF538927F7995
-:103390003CDF7D4339EFB37BFB2EC43E5A1EC9F0A0
-:1033A0001C73C9F26395B1BC0FE6DFB7F430FCC5FE
-:1033B000C78AECBC5F8EED5559DEFA739D1A849F67
-:1033C0005BA7CF9A25C7DF86F9A8BAE1A3E4DDD4CD
-:1033D000CFFC955593D06E7EC5ED5370DEF69AF610
-:1033E00029FB6943F7F3FC4AB37FD497EE9D8CF930
-:1033F000D56407761CA47E1E9C736A11D6D39FEEFB
-:103400009B86F53E6F6F7DE14F0477EB8A3FB25E9E
-:10341000747DB46F26BE5FD8F31BAE5FBDF2BF16DE
-:1034200041CEAFB64A7AD1CFE31A8D7E45866F1E64
-:10343000EA57AE7C9DF581C8EC23927FDEFEFDF855
-:10344000CEE9BD5B5E50A8DDD288BDD59CAA815C6B
-:103450009C6B679460B492067C4A3DEDAC2B188D52
-:1034600075F159A49CB8745B881F184B91A0D97F43
-:10347000A8DDD21619BF42F2821DF4195A7F297DA8
-:10348000E77ADFF37B856891DF6377DF7BB55CF7F5
-:10349000607038FCAE199BB0EEE776FD26D3E87776
-:1034A0000D4D2F8757CEFFACB65FCEEAFB65B6BD9C
-:1034B000D35E00B9EBFC337D4C7476FEC9C19C3FF2
-:1034C000ADB42B114A977F57785A46727C8DB765F9
-:1034D00024E4E707B5EF4BE35B4682AFE97C4E3867
-:1034E0005A7259FFCF6AC985BEABF34751D492C90E
-:1034F000DF032D9968FF8245DA53F88FE0A8783A08
-:1035000069E3DDD20FE1B70C477EE826E4F5711AD6
-:10351000C2251FE969BE8FA54B3BE6F939F69BBD75
-:10352000547FD07ABBA97C70C09CDF9A2EEDE70354
-:1035300043E26FFAA9EDFBC3708E3C21BAF5D73F89
-:10354000A38DF3D4539D713CAAA6CF0AB74E1F6E2C
-:1035500029DFDB80EF8F3AF17D6B12F1E5A59863EF
-:103560002ACF5F9E674F49FBCD0B79BE249C17E79E
-:10357000811782FF8558CA6743BE9278D5F33A3ED9
-:1035800043E7BFF2A34549B0DF7E94AEDBF93C7D53
-:1035900040973ADE1A6CA4EF64433F2E2F386985BA
-:1035A000DEEC492CB31AECDAEBF31CD8578B37E47A
-:1035B000398C74D6B0ADE010491CE2EC36AB072074
-:1035C000375803F7427E6FD8A6B6F805973BBC5430
-:1035D000FFACF3C0DBA8B768436C3EE46DBDFDE211
-:1035E000F52312CB0C700EDD665E879C16737ED8B9
-:1035F0006E73FE04CE80DEFF7CBBBCA0395F70C85A
-:103600009CFFE4835B67819CCB55FFBD2AF4893F17
-:103610004D3884F3F1D3175E8CC6FA2CFD4BD9419B
-:10362000E849A17122B46E0AF408FF5685E9E3B2B5
-:1036300078911EF8811E0F819D61A4930AE13F6875
-:103640004DB9BCFE19D132CB4B745559B7BCE064AF
-:103650004157BF57B6ACB343CE0B1DB7A7FD2F9C48
-:103660005E37EC6AC5A364D9557563C509F82DD6D4
-:10367000BE3B01F457FC4B85E58AE2E707BD0ABE75
-:10368000DFB663CE0D9CCE9AC8F8D0ED7D8BF72ABD
-:10369000C128CABB4649BA5DB85E617DBDA4D11CD4
-:1036A0004757B63624DEA6D95CBE78F7FEFF869F64
-:1036B000BEDCF118C7335C1E271878057A5BC5A7F6
-:1036C00082ED3D159BBF0D3397CB792DD4E7E1BF3C
-:1036D00096E3E1AE92553ACFB793C8D0F9F04B5785
-:1036E000516A06E1FDAAE68DAA949BBDC5EC9775CB
-:1036F000DA39CEB0CA21829104CFA128BBD745DFE9
-:103700002FAE8F6279615118C99FF99C8A708E43E0
-:10371000F4C4A0DDA977549683AAE2251EAA1E57F9
-:1037200002B0C556C1488AFC1332BF04DE2655D20A
-:103730008FD7003FD6CD98174D526FABB406F70325
-:103740002F9DE7C03673BD4A9AE7D138C859E6EFD6
-:10375000D5A29DEBD7ECFE36CCF8DD60DF657D525F
-:10376000D76B55C83304A77A4704CBB3C49823401A
-:1037700057AB14EFC30E15299DE3A0EF254E962FEE
-:10378000E66E94E747338C839083D70D66B967AEB6
-:10379000E2CD04BEC4BA70D6A7A9DC1FDE8BE564F7
-:1037A0009643484E6639AA7D8E9DE3129BF35A825A
-:1037B00090C79A1F48F1D00A327FE4F3E89E7096D2
-:1037C0007B9AA74AB9A7795D1F6EFF3140EB0B3991
-:1037D0005AE2B9F99E1C1EB79F2ADB893E520F2080
-:1037E000B93A137A02C1E541B92E4767C5FA4AB022
-:1037F000EEFAFC9B63DBA3E0C712E5F1DF4B6ED86A
-:10380000A29D87EDEBC203F0539C548A0E5A0CF62E
-:10381000A95B32E4F93172AC77AB568FFD1965962E
-:10382000A977FF80E0297BD0E26E48E95A07E1F5ED
-:103830006662FE27D785E783EE468E95F6A7637905
-:10384000929F470E171CBF73BBD6EFED1916539A04
-:103850001841F448FD9C2C94F6EDA8E1456C07A4B2
-:1038600035BAB9BB38903519F29C2AB317FDFE9AC8
-:103870006EE0E9A48BF152DE3DB94CD924E1F2723D
-:10388000BCDFC85F85B3FDF0A476DEE8EB4174349D
-:1038900082CF718D9FADD3E8665DCF7463A28BB983
-:1038A00090B7413773E4B9D84957DAFA12DDF07AA4
-:1038B000B7135D48BA11E26BB42F744B793B44DF08
-:1038C000EAD4B77BD0B7880E9EC8E86DA817420728
-:1038D000C21A18F18FFC2C25A362472AB40449565A
-:1038E000E147DC2CCE46C6D75DD6C04A82A7BF557D
-:1038F000AECB00ABA43B3A65FC11F95CDF8BF8D989
-:10390000E2FB170B2FD52F4E126CB74A27F926264C
-:103910008EDB09A47007AAB0E7508AF6C531B2FF62
-:1039200062A26FC4B3517F5E4B9CC6DC46C27F2A45
-:10393000587E40FBE87C6EEFB7C8F65E2BA503D33C
-:10394000E43E6A5F15C6F82BBE734026E864D25881
-:10395000339D24664A39414F1B33DDBADC90087E23
-:1039600050D23898CF9986F0A2AA5DD8A7CF487DCB
-:10397000A378F54D934700BE67E33DD8C2A7A7ECF7
-:1039800060FF4A49E39C1F7F083D655B387FDF98F5
-:10399000E97B0F783FADB817ECA20F25335FB12755
-:1039A000527B5FCBD473BFA3748A7FC7DB9023A6FF
-:1039B000CC50B9FE1421EDB9A2518E33D9FFB935DF
-:1039C00091FA9B3C5AE1F094B67057F232F855B434
-:1039D000F53DA6D17743B898FD9C13700DC84CCD2A
-:1039E000861F8224D46EE4E401995AFD31CA06C8C8
-:1039F0004303C7C9FDA7D7473FE8372D53EEB7CFDD
-:103A0000B47DA7E709AF5CBF6C4D585B5A34525B7D
-:103A10007010A5F3B2C69E039F99942A26AC07DEC8
-:103A20007FAA8A4D0C6F7B31F385A84C37F8828FC3
-:103A30001459A6FB6D8399EEDBC6B4B7DD49F9B620
-:103A40002D39D27EA7E9F30B5D82E582B63192EF84
-:103A5000B56F8964FE73CCD51A1527ED5DACDF9781
-:103A60006A24F1D7BA867BE1372E75DADB707E2CBB
-:103A70007C603AFBFB4B9B49BF475CFD5AB37E4FD2
-:103A80007A78586637FA7AA85E0E9A011D95AD5578
-:103A9000980E073678EC7D99CF292ECCAFCC194CF7
-:103AA00007FF2FF384735CF0657AFB3784F791B0DE
-:103AB0001F0B0EBA1A3AC8D70BE3163715B37E1A86
-:103AC00099ED63FE355025BC101DCFD4E86F12EC84
-:103AD000A0E04BD6D6BED897AF6568DFE35C994EC1
-:103AE000A6EB70BE6FD066736502BEB655E1169C3C
-:103AF000B793564AFAA67DE7C0BD80BBAC2202FC54
-:103B0000E0B8D67EFE0A6BD146CAF777086B541C24
-:103B1000E82B8FE93B90E5FB0CEBF7E92FC428C8B5
-:103B20000DA56BD749B834FA10D623E3E3699C4F4F
-:103B3000B7A4E4C3AEA0D353206B6C76E608035D54
-:103B4000CC50981E683E87609F9D9755928F72FA61
-:103B5000BE1FF432696C301D71D8856A25C7AB76FB
-:103B6000240A0FE2873A443BCB231D248F803FEA8F
-:103B70007C46E72744175E4742D77AEB7C656B3D6E
-:103B8000814678DE56EFE0F4A97A97B0124FD85EFE
-:103B90009FC8F967EBDD9CB6D467F1F7E7EA3D9C77
-:103BA000DF593F8AF32FD47B39BFBB7E22A7BFAB3F
-:103BB0002FE2EF841FE64B3ADFD1F9934E5F3A9F35
-:103BC0000AA5AB058466DC33A0F6CC0F753E887978
-:103BD00058F2BBF893BECEA94A913F11FC50B4CE27
-:103BE00001FF2854CF3EF322E1B9A3DCC9F1A11DA6
-:103BF00042F2C10EA783CF8D64BBD80DFB40C33208
-:103C00006FDB9D8673785EB922AC06BABDA9365CBF
-:103C1000580D747D735DAC293FBFEEFDD7FA50FFA0
-:103C20003F8BF12DC2FA1CBBE3D4A37FA4EF8FDF3F
-:103C3000713A03EB4E706C7908E3DE1EA1C1D12A04
-:103C4000E1BADDCEF2D2C008A94FE1CF6188732D71
-:103C50004E897DFB3704E7316D1D06DA5DB346C141
-:103C60002EB34A75ADA42A1F63BDE8FB9FB5F52AA4
-:103C7000A90B637C96346AFBD418FF4CF83CDE57E2
-:103C8000B05CA77885801FE9F82FEC419211C471D0
-:103C9000C51150681C8594ADF9B017AE79FD28E4C4
-:103CA00074A5EE10CBD53E8793E32884DF76D6D873
-:103CB0009F527790EB89D6FEA638C8C8E15E3BF8E4
-:103CC00005681BEB56927540609F8B2685EFF1943B
-:103CD00069DFCBD628A6F8E27B3355E68B8732AC7A
-:103CE0009C0ECA149A13A589CF299D5E897F703CCA
-:103CF0006359539E7D91812F9768DF4BB32CA67833
-:103D0000C74319322E6A109805A57767A5DA1732CE
-:103D1000DF7373DCBD5EBF242B7F75EA70F483E82C
-:103D2000A0AEF68F645AB9DDA10C9784C741E7595C
-:103D300014C7E9747B2EE872CCA7F8EF950C3FEB23
-:103D40005915CF3EFD2CFC7B157F0AE3F3A9629841
-:103D500066DFC80E8C9CCEF28FD7A98C84FC2DD741
-:103D60007FFCD37F89467C54CD4E6957A5B40D693D
-:103D7000F5EDE56C57ABF6D0FE88039F35FBCD5FC4
-:103D80007DF64FD1ADAC97F893B4F85B8EF7AADE11
-:103D90007982E3C0F4B8AFD07635CA37ACA7EA7100
-:103DA00001BA3FB6709F8DF74DCD1E85F5989A5D8F
-:103DB0001713C0E76AF6AD4AE82E2E27B45F3D5EC2
-:103DC00040B7BFD588B59FC37F4884C3F80FADFF08
-:103DD000766654AF53430562D5AE603B8855701C80
-:103DE000C7722D8EB32390C17EE19EE4ED9AF5C497
-:103DF000F049BFEDB0BA6310AF7C418889DDAD53A7
-:103E0000FC20797E9FA37D04BFF085ED2ACB91171E
-:103E1000B647F17EA8DE7EFF41C4DB556F56D88DD4
-:103E200057258E30DEAA77AAC261E00F35B00BC5E8
-:103E3000F70CE7D2A7A36A415F4B5A14EF16F8AD0F
-:103E40001DEE98DE0678DA35FA5A1AD63292D74540
-:103E500083FF14F89A41CE5CB2F77E8E13A47AE702
-:103E600059AEF96D24C7B3510F6F03CE331B0AD877
-:103E70004FBDA4654735CB05DB235D10694EDBCC18
-:103E8000F729BED1C6FB4693D3CEC04F82F6CFAA48
-:103E90002C0F034EECCBD35A3CABDECE3248B6B33C
-:103EA0006878FB0DF6E788AEFA4B5ADAA2D3A9FE82
-:103EB00027BBDFE7D43948EEE325CE23B938473FA7
-:103EC000D919C9F7ED3ED9F9EB092FD178E75AC6D0
-:103ED000F4520CFB6CE0201BD73FB741C601F32521
-:103EE00011D60F5A783E67B62729AC2703DF849F87
-:103EF000333B9F8FB6F03EF6FF7B71ABB3156BC8BB
-:103F00007D84EBB24780FE5BB5FB11ED9AFDE57F4A
-:103F1000A7FF6AED7B9B52A48D23EF3B083D0EC2A9
-:103F2000A5ED3BD5C9FB6E79949DEF2F2C18E6BE0D
-:103F3000711EF8E89B328E51F4773F04FD6FC13B50
-:103F4000F16C6F596E73F741FE8BC336F6132C2854
-:103F5000F01CF5A17E8C9DED4A22B17504ECAD6D8F
-:103F60002952BEA85C433B9350DC8FE8CD4FF8ACA0
-:103F70000C58848FF29307A5F2BA3E526EF1DAD94B
-:103F8000FF13E4FB92C7ECC28F7B2FFEE7A47E5D9C
-:103F9000992AFD0E8F607F515A1917CC8C87DD4E00
-:103FA000A39BCA69546EA09FCA4DC14CC84F67ED10
-:103FB000D21E8972E84D95F9B25E8346A7E807FDE7
-:103FC000B6A5B8CEB3BCBB2B4A40EFB0BC1825EDAC
-:103FD00021BF09DF146638AF6F1A24E9B841F3072F
-:103FE000FAB748F80017E4F825F6A64CC8B9FAB8AD
-:103FF0004BA29B78BCB3DA784B229AA4FF448BC7C0
-:10400000437D1EDF26D8BFD3FE6418CBCBA7FB1E93
-:104010007901E39F7E7230C711B4A50416EDE6F274
-:10402000708EE3AE782A2C08783F7B328AED589F59
-:10403000D9A41CF6595402CB6187A21E5C80FE3ABB
-:10404000368729E0A39F29C29E88F22DBD590EA86C
-:10405000A8AF633F4905B117C8AF944E84DCF7D9C8
-:1040600096C16C27FAEC0D952F29D0F735F8EE1391
-:104070004D0B7EC6F2BFF43F9E7EEA6F83BBF3AF6B
-:10408000546C36DBC3F4F5D7CBEF1824ED03770C73
-:10409000927AC9CA412EE97F8B6C793095E729F96C
-:1040A00003AD03EB7FB41F13606F3FD6B22741719E
-:1040B00002CFC1CC5F03EFDBA49E757ABB8DFD42BE
-:1040C000152F4679D9FE74E7157CEFB042957278CA
-:1040D0008545DEDBABD0EE99564467B27D8BF0CDE3
-:1040E0007A6DFB16551B478EFBD9D601D29F10D493
-:1040F000F22FE4F03DB84971E2E6692C5F6DC80526
-:104100005E2F6E8EE4F8791AC78BB8878A9FFD5CA4
-:10411000E2336611EB0774AE317FAED4F873D59DF0
-:1041200057C7E05E817847E5FB1217AD9E3EE0BFC2
-:10413000A1F87A4FE3634B5F7894F94125ED17C4FA
-:10414000592DD5FCCB4B9F52589E5CBAFAEA879802
-:10415000EFBE6D13B85F70B6E5FE68E37AECD5F894
-:1041600067577B0FD75F4AF565FB37A3199EAD36BE
-:104170000FE0095DC7EFDDFE29F55F6A5FD142F20E
-:1041800045EEE5F3BF288EDCF627F095EDE16C6790
-:10419000A3F5E77B46676C2D8B30FF33CF8433BFAD
-:1041A00039132BF7FD27749EFAED80E787F7B15D91
-:1041B000EDBDE902E7D0E280B95F1DAEFD1ADFAFC9
-:1041C0008AF7C4C04F5345EB81FE687D7EC4EDDFA6
-:1041D000B171FBD0F93C8E76230CFBF49948A69B79
-:1041E00033FDE4BA9C7976109F676DB192DE09DEEB
-:1041F00064E84B6762658A1B3EA0870A97A48733F1
-:10420000635AD81E7046D9C1699B4DB6ABA8D3FC82
-:10421000DA447F89A01FD026ECA98EB54720C7803D
-:10422000CF8FCCE73488FBCEA17673D029CEBFBE2A
-:1042300059F2DC8478053ECF7E1BF6E3B4F03D7383
-:104240009F264F566EBFDC4F8875AADCAEB03FEBA1
-:104250009276FE02EA5EBADD9FE872A95FF1226EF5
-:104260006B69E3B225A0FBA5B5EBE681EEF5792CF1
-:10427000D5EE5FB7292AC3D3164EFB27FBF2F174A4
-:10428000FCAA598A1E9F275CFAF9457B382CCB2D56
-:10429000E988B24DD45F65A3B296C749D1F55B39C1
-:1042A0003F1D4FB8CD02FB5E9B76DFB9A7F9EB70DF
-:1042B000F6044F5296E44F6D29F29E6FFB5BF2BEFF
-:1042C000F6C56F0A62E2FE813CC891FA7A7F047FEC
-:1042D000166810728FC6E796C2AE4E70666E30FBDF
-:1042E00073B2369BF343B69BF3D93BCDF9DCBDE605
-:1042F000BCE75573DE85717B77E109FA36E203A1ED
-:104300006F2385BEEDCE94FA36F2D0B79142DFC668
-:1043100077E8DBC843DF461EFA36F2D0B79142DFBA
-:10432000C6F7391A9E2A357B29D681E3D4F684EB69
-:10433000F100BC5F2ECC49603E2AAC521FBDB024B8
-:104340009BE5C74E3BD35407DB99F438A7B7A27C53
-:10435000E3B27AC37F7B6475DF146EC7F6E79ADF3A
-:1043600049FB73657EB813F68ED6559FAC86D8137D
-:1043700088F24D44FD0BB6F6ADC06F55DD2BEC6FEA
-:104380006F5DE17EE70772FDD8EEA2C72D15E3DC75
-:1043900003DF267D49C66F7B1C463B6AA85F48AC9D
-:1043A00035E4213F359BF3A17E20F035AF695F35C1
-:1043B000311D3C6E6BEF0BBE7FE24907DFF33AA184
-:1043C000D9EDC46C17CB63BA3CDF298FDDA36CC277
-:1043D000F9BD242B8EDB771CCA30DDD30B4D4B2F60
-:1043E000E5B3BCDA995FAB58304ED98C15FB59AFA9
-:1043F0004E8CE673E9160DB64190FF0D700F0E441A
-:1044000098E868E8B6B810BF653F53FD61BB5343F9
-:10441000FC96434CE5D3D71698EFB5175D6D2A1F70
-:1044200068EF8C877348FF96069F4BD6B9E8CCE7B8
-:10443000F986D64B563C7F84BF56BC25E5D3329ACD
-:1044400087B7407B9F231FFE39EF14E0AFBCC51632
-:104450008BF3BE543B87449DF95C2EB70ABF2BAE4D
-:104460008BEECA5DC21B4BEDBFB43625331DDD712B
-:10447000345925142D19722437087DE58D2746827D
-:10448000AEAAD48DC92E2ABF55096CC545ECD3718F
-:104490003B12AEA4F2FFB4F81EC9A2754AB605EFEE
-:1044A0009D0F3EBA234DE0BD91136B9F8FE6B83C44
-:1044B0008DFE926DAE08D0C1C62695F514D8CDD428
-:1044C000B82E3AD9D8141F01BDA67C8CE297727120
-:1044D000B449DF0BC547A19AFD8E9BE67BF1902A7C
-:1044E000EF406AF35CEE92F545BA6CAFDFB3D7E705
-:1044F0007B52D3472B36BE96790B7D3F3B787F2E80
-:10450000AE8457D6EFE6792FB56CDFDA97D27B1DF4
-:10451000BE5D98D7F2B7C6455F49E37CB95DC687F3
-:10452000FFB5F989C7FCC44FEF6C7AC20EFB418519
-:104530003560871E5CFEE4463BE218AEDBB691BFF9
-:104540002FDA56CCF600FDBEDAA77A7CB3868FF25E
-:10455000B1CA0617CDB3FF60C94FCA23641C4BA173
-:104560003AFA35DC13B8B84DC9C3BC6614EDB0E3F4
-:104570001EFF3B1ADF09DD371D87A717F686BDAB87
-:1045800045F120DFD33E9989CB72440FD32FB9393F
-:104590009D716908EBD51F0AD2BE708E6487E8D77B
-:1045A000875569CF433C12AD73B93DD86B3AE4856A
-:1045B00097E5FB0F55740E8DCA87DE2EC4559416F1
-:1045C0008D564D745E333ED2B40F660BC3BEA2FE51
-:1045D00066897EA6FC8C4969A6FA37CE181AE2676E
-:1045E000CEEF2A67FE7595E95D97AADBFD6E85E340
-:1045F0007BC69ABF537A3BD3D90DA6F655629AE98A
-:104600005D97259BDF653C1395D9A18F956BF7418D
-:1046100066FBDAB4EFADFC9D2662DAAF03D33C7FD4
-:1046200094E7A58DFD08BA1D7D36FE9FD6DD79196C
-:10463000D1198F89F85BD83B7C6679E408EBA942F5
-:10464000AE4395668FAACA92F6A82AFF113BE29B59
-:1046500009FFD62442497593C2F646AAEF488A93C9
-:10466000F9DBF17DA7F95E07FABB84F2436A31F604
-:1046700057687935CD1BE74235EC47B083E9FD6BD0
-:10468000FDEAF4197ACF3EB41FDF6037EFE78A6D99
-:104690003B0EF623BC4C2F8ACD437C4965CB545B43
-:1046A00071F6E574A6F3FD8BE516B67F751C7E8565
-:1046B000E9ACA3DCEA91F1DDFF181FD55E696F0D4F
-:1046C000A5BF45341FF89917ED543C0145D6035E4C
-:1046D000FA812E43F092D40DBE743C75E22DA47C79
-:1046E00031FE331CF1114A007CF232BCE878D4FA76
-:1046F0005FE4132C67123C018627A43F312A74FF24
-:10470000DDC2EF20746C50844BF96E3C4CBB24ED41
-:104710003603D3E4BCDB77291EC8EBB32E59F97BF3
-:1047200027BD14C938F51993CCFBB3937E8AE47E78
-:1047300099792981DBFD6FD3D177D18FEE9F098DD8
-:10474000FFD6EF5D2D1AACDD4B1A21467CFB4FC422
-:10475000AFEB72404FE749E779E3D2F0EF4CEDF66B
-:104760001C5E1E95CAF1DA3ECD8EA8F3639FD64E2D
-:104770001FB798CADD05A0EFFE09B017AF6E4C4B0E
-:1047800036BE17E35B65633B6FF28A784E8BC35D81
-:104790000938478A57C8774D8EDFD52701FE88E351
-:1047A000AB6CBD2651D7C77F3A3C59E4205FC8E9BE
-:1047B000897561B38D76783D6D1A2CED35FA397EA9
-:1047C000CE72387A36F6DFAA5DD108055ABAEAFD0C
-:1047D000912E3ACF57597C8F0F667FEF463ECF859B
-:1047E0006B632EEC70BA3C51B1AAB00FCEFDCAFF7C
-:1047F00079E5319CFBBE15B604C8A39F7DA00A8451
-:10480000CED079C672C4A7E192AE3FDD12C9F710CF
-:104810003F558417FEA625EAFE5C97E95CDD3B0B5D
-:10482000E3FFDE41E38EC0B881AD8918D7E3CFC482
-:10483000B8BE151931DDD957F4B466BD94F3B6EAA4
-:10484000F664CDEE0CF91E79C8F7706241BE471EC2
-:10485000F23D52C8F7F8BE4DF32F0C6C68CF837E43
-:10486000EA1F2BB26AF9BC7566417EBF4589F080AC
-:10487000FFDCA278FA70BCC166F9DEC4F29075D58F
-:10488000D36BDA490633D0ED0F2E3984316E6E8C3E
-:104890008835E5C739FA9AEA17BA524CE5D7250E9A
-:1048A00036955FEFCE33E57F9875A5A9FE64CF18E6
-:1048B00053FE47A3AE37D59FEA9D6ACA4F9F38C7BC
-:1048C000547F6651B1A9FCC6D94B4CE5737CCB4CE7
-:1048D000F979E53F35D5BFA97685A9DC2B5C569CD7
-:1048E000777BA17711DE5F86DE45E92D6F65388D18
-:1048F000EB3A7A9CA5DB77794E697250BFA1DE3620
-:10490000D025EED7800E0768F767BEC0B9D21B7EF0
-:10491000C9A022F5DE237D4137A1F542CB47471ED2
-:10492000B8E8A6352C7A2A7AA695F8C4E82B0E1496
-:10493000A4517EF5538533ADC45F465F7DE0F954E5
-:10494000CA373DB54A960F3B7011E5514FDF20F352
-:10495000D3058B1A8F0CF97A869FE631FA07A96B7B
-:104960003DD26ED26DBC69A73D88F080784DE001E4
-:104970006990E813E901A24FA4AF127D96A50B71CF
-:1049800090E813E921D23FF1FDF7A47F223D4CFAD4
-:1049900027D2B749FF447A84F44FA4EFD5CFE6F489
-:1049A000837A1FB7FB437D39A747EB6BF9FBC7F54C
-:1049B000759CFEB9DECFDF5D43743B4390ED31BAA9
-:1049C000FFAB1A7E47D8ED76DBCE1AFDC28A579E22
-:1049D000A7BABFB2A156B446629FB65A634F39BA5E
-:1049E000FC903DF35BAB386590BF5E0FF7260DE1A1
-:1049F000F1FBBB986F6BDF8F89E903F2699D0A5267
-:104A00007D29289F995FBA2A86F8C70FBEA9B5816C
-:104A10005E3EB4747F7FFB0B8D4EDA877833878CD4
-:104A2000E8F2BBEB7EEFCEF81A835F1EFE6C3D8E84
-:104A300047F7C7F39F213E47F793EBF141D76AEF62
-:104A400023E97E703DFE47EFB7F09260BE77CD1A46
-:104A50002BCB2D515611C4387A9CCF358E963CC441
-:104A60003B5C53E9E438B73EF41DEF23523D2FDEA3
-:104A700099DBFC25D5CFEDF2BBF7D1E641E53C8FC4
-:104A8000C24B3EB6D75EA3C51DA0BD4396F33B7592
-:104A9000881183FC4129DBE11E55A87D7E571C004F
-:104AA000EA47CAFA41F497FE158D17DDB58F06C4A3
-:104AB000B5E4216E6C40B593E3C6368C09F2BDB9FE
-:104AC000E9B1D7DED3AA224E38E6C7D8474FA7FAB6
-:104AD0006602CFEFEE730FF0507E5A5C5A6FA4530C
-:104AE00043DEB5EB667DE6625D757CE978D7D74B32
-:104AF000C7B7219E8AF1FC5DEB17BA6EA1EBA5AF9B
-:104B000053E1A52EFC037F97AF4FD7FAC13EFBFFC1
-:104B1000CBFA0CB7B6F07DCCB04A8707707DD77A58
-:104B2000DDDC2E26E03E78F125F741A44BD27C5FF8
-:104B3000807F968A31135CC0914BCD819D27B4DE76
-:104B4000F2EF59EFE1907A07E20AD67C9D7679BDC3
-:104B5000DD21F51A620BD67E2DED4C37E27C3DE46B
-:104B6000B6B11FEDCD703D1EC3EBCCA3751CA7F1F4
-:104B7000A343A296CF0F12D7FC58DFF1DA528FCBA6
-:104B80005ECC72EE78A7596E9CF04D5123C69DD035
-:104B90002B448ED6FCE13768FD5E279AB8DFD07BC8
-:104BA000F23768F269E83DF9E78668F2658A4801FC
-:104BB0009F1A2F3C122EEDBD83F12ED96F92462FF6
-:104BC000696E558C063D089F15CCF155BC77908BCE
-:104BD00071FD9CBF5E0438FDA108723F938991224C
-:104BE000FF23216CF29D03793FB35AF5FD27E42C96
-:104BF000FD5EE6C270DFABD877AF444E998FF728E1
-:104C0000C6158C4B47BB03E3DD2C9F1C70A4B1BCC5
-:104C1000847D658BEBDA7F6FD0F9926E95F7069104
-:104C2000E2DE603A6D96D7E9FC41FE86AC1502EDF6
-:104C300026B8CD71387AFB1FBAC60A6B41CFFCFD8E
-:104C400087B97BFAC3AEF366ECA0F1B083BF197BE2
-:104C5000C578CCF7CDD83E169986D939CD7931BDF6
-:104C60003B794EA7E7AEF126086B7CCF78D6F11AD8
-:104C70008A4F1DCFFF025E2F7487D72F060B29376F
-:104C8000474A3EA2E3B72AACF31E671F635C44A504
-:104C900043E2E933808C7BB87557F13C3EA917FDA0
-:104CA00081EF4575A3B83CD40E2536C7705E7FC72B
-:104CB000ECCC83EF4627127CD7397CEA50C2CBD9A3
-:104CC000FC60264930E2930D0D7CEFFADCB3AA07B5
-:104CD000F27FA5EA5EEB014F7953653FA0F8E695B8
-:104CE00064F809C5E6EEE3A32B1D12AFBAFEB3329A
-:104CF000AD88F7A7701524CAF7D5E43D725D1EE8AC
-:104D00001F26E38BF5FBCC3DC9072323241FEB1F94
-:104D100026F9AEBE9ED48EF349D4CF48E25349F76C
-:104D200045B03EB0DBE54D1A0A7FCA786192A7759F
-:104D3000BDBFA3977C3FF05A91F9D068CA8F3F64FA
-:104D400013012AEF182F4CF164856F94F2BB16FA09
-:104D5000FD98B044D2AF0CFC20DC1D617A6F343278
-:104D60002BCE948FF2F433D58F19956A2A8FF50ED6
-:104D70003195C74FCC37E57B175D65AADF67F658DD
-:104D800053BEAFEF0653FDA4F269A6BCCE9792E4E2
-:104D90002731A076AEA9FDC0BA1253FD147F85F964
-:104DA000FD54BFF74856029E77947F696B9687BC87
-:104DB000AF6A1196915DEF90FC3A5ADE0799E85C74
-:104DC000C4EF916434FDCC0C8FFA8D8A732629468A
-:104DD000E1F724AE739BF96061A2393FDE95F72AB3
-:104DE000966E9C2B34FE28A8809E926AADA6EFF3A7
-:104DF000866A7C3457E4B29EFE5DEBEF1B625AFF7D
-:104E0000507C5D4E0FCFE705DDD29E6F9C17ECF90D
-:104E100046BCC09E6FCCC39E6FAC0F7BBEB11CF670
-:104E20007C6379C121331D8C3862A6832B8E9AE96D
-:104E300040A7CFD0F5BAB2D54C1FC2A7F8947FB027
-:104E40005E577F6AA69FD0F521098BD76F825311D9
-:104E50008FA4FCFBEBB52E64BD3AD787F00DF9F6B5
-:104E6000DAE050BE275B78481578B7E4516D9ED7DD
-:104E70000DADE527C3B65B7DBFE67DAED155435F83
-:104E800049571D879E0F071F7D34A4FFD7FBF902EA
-:104E9000A83F3BFE62B21DF4D12EDF456B031FEE2F
-:104EA000DD15B7497ABABC77F23395E3188E599A73
-:104EB00014F0EB8218DF36F0CB9BB36B15F8671359
-:104EC00045D18E4588CBF98FB064E4170C94F77701
-:104ED00045762BDF7FD0F9E282241917D83254F3BC
-:104EE000F37A64DCCEF343A5DD24CAE3E238E3E2DF
-:104EF0006C79BF83D499E40539C0C7E1F041C0475C
-:104F0000B385DF696CB5B9396EC4FF862AE0F783D3
-:104F10001C0BF9728026DF357CE47000FE41EB85C6
-:104F2000E99C1D1C7098E25B876E7399F2392D899C
-:104F3000A6FAC376BB4DE579C12C5379C1218F29DF
-:104F40003FE2C82853FD2B8E7A4DF92B5B279AEA56
-:104F50005FFD6991299F24DA1F067E072A528F3E42
-:104F6000333455E2C92D387E6FC19DB1F2DEA7A65C
-:104F70005FEB72BA1EF7ECD3E83954DE1F68F771A5
-:104F80001C75435FE1E17B180E4D9F12663DC0A783
-:104F9000C52D77DEA3F09BE396F578E54E7D41D3F2
-:104FA0000F7439DD10AFEC35C62B2F08EBFE3DE05A
-:104FB000FFD2D63D14FE817639DF869FDAF9DE888E
-:104FC0000E57283C33B538DA2D8EEEEFF5D8B225E2
-:104FD0009D256514FD1DF4FE98CDD3CA6FDD5F36A7
-:104FE0009EA7D54FF4D5F00BBB67A5FBBBC75B30C5
-:104FF0004CCE67BEC572F3D46C8ECF32BD83DF3B1F
-:105000005BEAFD51B94AB7F35B1023E3A7448CDD9B
-:105010000DFAED793C89CF44BB68E4FB475A9CFF0D
-:105020004D6B5BEE194445F3ED4DDA7B60011BE8F7
-:1050300061D25892C3F284D8B66557B393E4A2C73D
-:10504000EAAC6C3FE9BFDD358B24B8CEFB1B0349CE
-:10505000EF017D40B681BEB42147E571AEC19E1B14
-:1050600081FDF64D679C3DFB0584D0CE0BA94F75A5
-:10507000436F4C87FA3CFEAFE3ED43F1A4EBAD4246
-:105080008B334CD7E0D2F1D76977D0F0A7DF7F70B0
-:105090002FB3156D72F23D8A8988DBD2D7AF2547D1
-:1050A000D265AD860FD4033FEAA95EA19A1D03FB2A
-:1050B000728770C7B8BAA1433DFDBFC28B8EFF9EF9
-:1050C000EE57F5C41F42F9C277DDB7EA894EFFD922
-:1050D0007B57063E21E368B47509A45BD83F7D6722
-:1050E00094793F6FCC96768D71DABEA2F3DD996725
-:1050F000E61702F6F18655AAC62FE4395E9C52C423
-:10510000EF118B3A17CB33E51A2FD6CFD7850FC8BF
-:10511000F7E0AEF516255C45F992669BD848A015D8
-:10512000FBBB8FF366BF931B71FE9E44C0CD263739
-:105130001AB7B44909EC4FB9FCBDECC54EF97E5C19
-:10514000E8BBD98B35FD172F2A60DF86FA65EECFD5
-:10515000D6CE6B8FF07C2BE167BDA50B7E8DDE027A
-:10516000F21D31E8C3AAB4F3709C968E3737FC2445
-:10517000F15D79C26F4416CEF3466BB771749DF83A
-:10518000D5FD2A9D7EC2C31CAF1F1A1770D6FF4AD9
-:1051900074777E1ADD7FD3D33EE8F4DF7C875FA887
-:1051A000C369891E053E04FFBFDBE857F9F3488257
-:1051B00090FD2731F08FB46AFD898DB9DDDD4FF4A4
-:1051C000ADD8C5F110AB2CBEFF405CF219EA1FEF61
-:1051D000B0DEE53C9080FBF89334BBD3E5F3D6E436
-:1051E000B0D1F27E40875FE5F5EE9828EF73131F8C
-:1051F00015D877BA1F7FAA08F642AAFB497C6B46EE
-:1052000031FE753F49717014C339B361B10D4F4818
-:10521000B63E7C7B6184BBCB7FD23A40C6E7F4E4E8
-:1052200047997EC9C3FDCDB87415F7732C3B45CAA9
-:105230006B8DF72C039D0DD9266C9867ABADFBDF0A
-:1052400019989223F7D152F8D27B1BE27E5628ACF4
-:10525000072C57841E07C47C5ECF5F6CD2F2853268
-:105260007FCB2A996FD5DEC5DAAAD93B304FA498F7
-:105270000FF4F0ED9A3D04F3408A79E03BF81AF21E
-:10528000E06BC883AF210FBE86147C0DDF4B445109
-:10529000729E2AFD3DE30DFB03FE9EF106B909FE59
-:1052A0001E631EFE1E637DF87B8CE5F0F718CBE1D4
-:1052B000EF31E6E1EF31D687BFC79887BFC7581FE8
-:1052C000FE1E631EFE1E637DF87B8CE5F0F718CB97
-:1052D000E1EF31E6E1EF31D687BFC7587E739D62BB
-:1052E000F207DDACBD3B50BA3E8EE9A339B52829A3
-:1052F00087D6F73F23FFE7C7B654ACF3DE25FC6E35
-:1053000060558447AE73D344B9EE1621D7B97D0EEC
-:10531000AFF3ED76992F94F1C2A1F403BFCAF874EC
-:10532000E957410ABF0A52F85590C2AF32DE2AFD52
-:105330002A48E157C177F85590C2AF82147E15A470
-:10534000F0AB20855F0529FC2A6807BF0A52F85593
-:10535000F01D7E15A4F0ABE0FB318203FE151D2E7F
-:10536000C8F9E9263D94E8D0A487BA4C79C8F9C6B3
-:10537000FA90F38DE590F38DE590F38D79C8F9C639
-:10538000FA90F38DF91BF188716F29EF1BDB41DE79
-:1053900037E6739AFCAFC1863579C3F95791B646A3
-:1053A000298F292E92EB729E9A05FF586BB8921C9A
-:1053B000EB213976C56F678DBF92F889166F972BF1
-:1053C000DA2D586FF67BD3BAF98282E38373FE3B02
-:1053D00091CB757F2BFFD1BAE7ED14AC376CCB9036
-:1053E00070E9ED3DC2A522D5EB77E5BBAF173ABE1C
-:1053F0005E8FF9A5010E5228F310079177BB331F7A
-:10540000F1ED5B2D8A8C0B5D29E37243E9AA49E338
-:105410004B5B2D3B0E4450BBF662C5837B07995610
-:1054200071C8960F3CD5E6439EA8CB89D5E2836B25
-:10543000AF423C900EB76E7F243EC1F7DD46B70BFE
-:105440007B198D73CD17C28EDF5B986497F204DAF7
-:1054500041DF1CEA57BC9B0CF4BD32479E7B3EFFEC
-:10546000B2ABCAE8FBD0EDB557E11EDDA408D9EE1A
-:10547000378F47331EA7342A9BF0FEC9E8EDC28B55
-:10548000FBB1BFD4E01EBADD652FE3715D7CFF4E3A
-:10549000EFB7784332DF172C16ADE313D927A1F00D
-:1054A000FBE63ADE687EAF627EC4E20FC18EFC2F5F
-:1054B000DFC32171F1FBDCC3B966786C21E2DBC488
-:1054C0005EF90EE4E4E1C5AB7A135CBE807C07F2C2
-:1054D0009A2F6A5FE3FC66F90E2493CF48868FCF3C
-:1054E000C3417E85DFFF98E2DF68E9E5C6BDE015D0
-:1054F000B604D4DF2E3C500B060979AF559F57B642
-:1055000038620957402FE2957803FD11E798017A38
-:10551000C9F3D8F87D90A956970DFC4697738A5D1C
-:1055200072EC4275740CDFF70B91132E36F6E6B869
-:105530008D7F3D8EA483EF932FDF15CE72858FF87C
-:1055400007F8E6B93C197759B9ECC39196D4AE384F
-:1055500092D32981AD78DFF374EA8EE8510ACB113A
-:1055600087C05FDB1A9FE77B82C5AB5EE3FB10174A
-:105570001B1F8896F7AAA47FA54CC39B6E6F5AA8E1
-:10558000AD4F99163F74BC5EBECF4BE730BFF7718D
-:10559000B1D1C67246A8BC2884EB0F88732B6FB4B8
-:1055A000F1DDD3C56B8B57278AEE7E77C52BE3CF12
-:1055B000B5719734DA384EA85C7B472BF477589650
-:1055C0006A72E8D26DE6EF277242E44FFDFD44AD0A
-:1055D0004EF15BAFCC6439A8D6C671EEF35748B92B
-:1055E00048EC1001DC6798BF629C05EF58CCDFE502
-:1055F000F528DDD0D13B9A7C34098312DEA75E8A80
-:1056000060BE32ED523FCECFBA94C8E98D97B2E476
-:1056100077AC1DD14B6BA1BC5FFFBE2617CD441CE0
-:105620006501E4B23E4CD71D44D7182257E35743D7
-:10563000BCCA2B30C34FB2F956214E73D246C1F7C4
-:105640009126437EA282D990A70AB02F520AF93E32
-:10565000C64485EFB74C1EBE4CDB07B42F04F311D4
-:105660007EF7C3377E6A00F137B37D3B2C58777DD8
-:105670003FF8FC6DFC0EE664BF62C77B813E4DCFF8
-:10568000D6E93D745F2C88D4EC634E69FFEAB48F91
-:1056900001587E9C27F246C4B32E802DB39FB6B02E
-:1056A00084AAA86C599E9C1B79632394AC7FD36E0B
-:1056B00032DF6291F79F48FEE3787571A4B00FE581
-:1056C0008BD72AF98897D7E1FA7AD8D849C37A775D
-:1056D000D14149E7FECCEE03BD60F95D1926FF4CD0
-:1056E000685A4AF8C63E5A10D3FA63FCD2D0845C9A
-:1056F000E11D9F8877C8F5F98A20E202E76AF9DBA5
-:105700009EBDF28F6B9C8C27CE8FCDED7723E23F31
-:10571000FE65FE385FB11A7F37AA4DF17973E53D1A
-:10572000C80958DFC8EC767EC76066A64B9E2F215D
-:105730007696DB72DDF25D84107B4B69B63C6F843C
-:10574000D59D3C8FFD3A6EB657EAF33E6E33DF339C
-:10575000D5D3EA5C6937F8BFBA27F1A045DEFB7FF5
-:10576000C412D8F122D16BA0B76F01E6FB08E2BDED
-:10577000197E1FCF4F7F47A3934F69EF65E8F474FD
-:10578000ACEE22DF972871DADDAA819ECAD6287C8A
-:105790001FB1A44EDE27F6AD51E4BDFC1EEC578FC1
-:1057A000CFF99ADF517AFC1711B250C3EF7CFB910D
-:1057B000D71C295DF8FD53DDAF6C927F0633106F67
-:1057C0003FB7369CDF41FE7A58D18F017F64B687A0
-:1057D000D76912F134D49F1AE3FB29BE97882307B7
-:1057E000616F5CF0F3B7F87DE19ABD29FCEE61F1E1
-:1057F000EEBCD57847E5EB61BE3B72897E8B9D2E72
-:105800003BE490EAC6583E9717F4D1EEA98B76F6A2
-:10581000E7E9EBF360AE94078A3C729C0B9A3E4535
-:1058200008B34D35D593E77FE83ED4EDA2A1F695B8
-:10583000D0F72ABECB9E027B89DD6057D5ED31B60D
-:10584000ACE373709ECFB777FFBB8DAFEB76474D60
-:105850009F5DD8A9CF664FE803B97F9DE2821DBD49
-:10586000CCE9BE11F1F565876C88F01493E2DCF2A7
-:10587000DD92BBE4BB2525B7E6313F9B8F35C9C719
-:10588000BD8751BC8FCB0294C6F7BCDFE7AD7B650B
-:10589000C01ED053D0CBF7E0CB5C5E7B9C412E2A60
-:1058A0006D524CEF18E8F91773A51D723EA919C087
-:1058B000DF4DB7A6D8F186D07C128F1037F8BA46E4
-:1058C000277A3BAAC771259352C541F9AE14C19DF1
-:1058D00022C733FE4E514993F93D06AACF72DDFE31
-:1058E000DC28EEAFD845F34E41EA6238090F8CA7A9
-:1058F000F67BA83F378FC3EB511A0CD86037988FCF
-:105900007816CACF75056C18A7A451BE8FE25B2B21
-:10591000C7F1AD89B5E7402EB0BAEC038CF260A3B5
-:105920007CCF78BEF6FB11042FCBCB658427DCF34C
-:10593000D2EF7D86E2AB5883BFAC29D62C5F36AD63
-:10594000B3617DE6F4F05EC3971A1D97348EE1FBD8
-:10595000F565562FDF97F069F8FEEBB2F0BBE12753
-:1059600099D3FC902D05798D2F7D093CF7069E82F9
-:1059700019FC3ED2B2708E679EE36AE2F976E2FBD2
-:1059800001C20FE4155711E39BE8C48F38C0B2661B
-:10599000F3FA76C11325DF656F2EE6FDB7C8EAB3CB
-:1059A000BB8C70ACDF9F81FB5B7368DFE3FD27E19D
-:1059B000F2F17DCC530FDCC8BFFB063881E7288F9E
-:1059C0007B02DE3B22BA61BAD6E9674181DCCFFABD
-:1059D0007851C3ACD20E3FECBBF6A9F720E4F30636
-:1059E0005A6FD8FF7BDAA7765C00A471ED65F2DD13
-:1059F000BAD07DABEF577D9FEAFB56DFCF8FD98AB8
-:105A000082894A17DFA1F3BDF6B96EF03449837776
-:105A1000AEB6AE84D75785C1AE376298DCDFF3539C
-:105A2000CDFB1FFDA1DF54BD7C6C3003F73DF5FAC3
-:105A3000FAB8F3E3643BEC03D05BEA304B67FDE577
-:105A40005CDF62E21FA59DFC63FBAA04F08F1D0AC8
-:105A5000FBE196DF23E5BEE5CFC87BE16796BFF8A3
-:105A6000F62CAA77FAC18D0B8CF72FCA82925F2C85
-:105A700024790BFC6391260F6CCCF4E50D33ECE735
-:105A8000B2FB9FC9C4FE98DB92770A6FA8D1BCF91C
-:105A9000BDA33F3FF3D28757B9BBCE5D7D1E256BBB
-:105AA000DEB5153B8D7893F47E7756079F5BA5385E
-:105AB000B7E853696331F36191487A8FD2B5EEA1AB
-:105AC000F450DCA8B09C575A3732A0FE2FF2EBD22C
-:105AD000B553F98D287DBDF4775FF47357877FA6A2
-:105AE000B64E73357A9E3D4CEEC3B9E529F645BCFA
-:105AF000FF53ECF8BDCD395AF99C32F3F7CEF5726D
-:105B000075F2FBD5D827B89F84F5EA586B93F6CB8E
-:105B1000ED97AD5732E4021D8EC59A9D72A1666F56
-:105B20005CA4C9CBB45E8B8DEBB5F871B95EA5CF23
-:105B3000BEF517BC5346F3D3DEA393EF0A94B4EC3F
-:105B4000E0759BB3669D2D85EAFD64588A29FEA801
-:105B5000B436CF053BFDDC351B6DE0073F1926F160
-:105B6000164AF7F3B5F8621DAF388F14833F47AF7D
-:105B70000F3EB883C6B9755978B4F177ED021A3D76
-:105B800097D6C6C661BCD2DAE27BA17FE9E740E8DE
-:105B9000FE3B112EF74509F587FD79628C87EF559D
-:105BA000CFD77E372FB4FE431ADDFDDA26DFBF4C98
-:105BB0008A6C7992E33B6A223CE013E9E9AD018CFF
-:105BC0000B7A06DC768B7C2F33BDB2F573C041A215
-:105BD0003CC7F520C57B5B10ED1328BFC922EF79C8
-:105BE000A5AA32DDA7E107A637948B5EADFC1E5F48
-:105BF000E7BB5121F46A179BD7E0DD1F7B2FC1EF74
-:105C0000A6E9F4A9F7A3D3A74EBF3DCD6FD7F79C64
-:105C1000DF8914CDCE92E54976D0B80BEE1BC4BF18
-:105C20006BF15DF3B46BEF3576CE374CFEDEC765B6
-:105C3000F34D97FA52CFF36D2E4CE866BEA1F3D424
-:105C4000F7891E43DFE94F6992FE94130A9D63D4DE
-:105C5000EEC4B2708EABD3E7A5DBF5BFEFBD878F87
-:105C600086C569F6AAD628C897F3B5DF51114199C0
-:105C7000C7F7A986EFFAF9AFBF5FA7F3E993B5DAE3
-:105C8000F9285AEFC17E1675697C0FF558D389281B
-:105C9000BC1373628C844F6F77AB4DDE73165176F5
-:105CA00037DECFBBE9D63CFEBD94858D7D589FBDC8
-:105CB000A92E8DF9C24D7E581745A71EB048E38323
-:105CC00091B716AFBE02F5D7A7F0EFC22D747A4E8A
-:105CD000ADE7F6433D9013239BA7DA53591E96FA7E
-:105CE00082EE17BB5511457C4F0D7C12FBCBB23FAA
-:105CF0001DE7CFE2F5523F9864116BE03F1DD8508D
-:105D000034A12FF8C4C38AFC3D9A0DE6F7BC860E79
-:105D10002AFA027C26F45DBC5B6D2D5EE8A782E466
-:105D20000ED8D1163A8B589EBF45E393C79ADBF83D
-:105D3000BD7E1DAF8FE0BF78A72AC47E146A271AE4
-:105D4000A8D907FF1FAF8F7B3D0080000000000037
-:105D50001F8B08000000000000FFB57C0B5C546541
-:105D6000DAF87BCE992BCCC080C84512878B84850E
-:105D700034C080D7DA518150BBA0BBB9BA218E653F
-:105D8000CA650650DB5D77D7FE8CA1A6667DFA4515
-:105D9000A665ED80976AC376483428A8C90B99593F
-:105DA0007F62376A2FB9635BE62D40BAFCEDBF6DA9
-:105DB0007DCFF3BCE7301751DBFDBE6FFCF97B797B
-:105DC000DFF35E9FFBF3BCCF3963348C751B186324
-:105DD0002A8B8E413968488964998C8D09695F6185
-:105DE0004C89C3F625DB45C64640FB7C93C8621947
-:105DF0002BD731FA7D8FBF1F31761F3C37C3F3425B
-:105E0000A934D607FDD737CCA072C9D6C26DAEF182
-:105E10008C250925B1936360C0E36AB6078A25CE55
-:105E20001977302BCCD3A48DD225C373B52B29C7BA
-:105E3000E09F6F49E343490CC69D69D4CF77437B0C
-:105E400081694E41148C5FBA332A5B32FBFB5D6F74
-:105E500011181BC958A573461C4B61CCF1DDE167D5
-:105E60004CA9B01F98D304F37FE50977BBA08BA39F
-:105E7000AE2D4982233CAAB3A758A07F95D8316F95
-:105E800012CC734E70EF4DA0FEE63853C0FAA1E578
-:105E9000E93AC6CCE98C39FFCF8734CFE7E2893BBA
-:105EA00016C07887737F04CE53F5F81FF201326C69
-:105EB0009D68CFB2E4E1BC8D7B4D121C747B6356B0
-:105EC000099CE3BEC7C746DA332F9FF7B668B6A86A
-:105ED00004DACBDB18C157695FE88ED420DCED5EB5
-:105EE000A6316169629A6828CF486C9507CADB526F
-:105EF000D8A2B9067FBB0DE100EB9E89DC9254026B
-:105F0000ED157B9F48324379D6C8EBA57B7F7A9C01
-:105F10004540FFDD5A0DE2D5AE621A0B8CBBD7258A
-:105F2000D8DC50B2F268C61210A36E7D9991B159B7
-:105F300096709AAF627B0E63B9FE7DC1736A3FAB08
-:105F400062C5B88F31F503D9CBA1FC8BCA7B1FE2A8
-:105F5000F32FB57A8B2B19F16226BCFC658B548428
-:105F6000EDAEFB053656C0FA7E631AAC5F16C96A01
-:105F7000717CA1F4579B04CF571C10B2B5307B78CD
-:105F800066B7E61E039116D159B589D3D98A7675BD
-:105F90005122E07F458B402D0E9557331CBE2A2F92
-:105FA0004D66E680FD56B6B668CCB08EA319CE0914
-:105FB000FD1D9E539AA5785EB685B17CC027FE89EB
-:105FC000F86B3EA5B937003FD5AD1C2ECE56DEBED0
-:105FD0003803903B99B66213D2A0DE2650BD3E6BCB
-:105FE000C2FC35AAC07AFEFC3569589A084E4C3579
-:105FF000905402F0DC94D1A341FC3BD7CAF3425D3C
-:106000001DB05E0D12E548DE9E6AC0F1661AAF3C17
-:1060100077B646D178AF336C03BB0936516D50610A
-:1060200059EF344460B9B356CC50597173611609B5
-:10603000E0DF111691C52261CAAA5E3D4012503BB5
-:10604000705884F6DC48FB83489F710CB802E83333
-:1060500091790506F4DFDFF9592ECE7FCB18DF17D3
-:106060000CB6AE5E337D7E01D0C3268B7C8E4C5F3A
-:106070002ED2F1C84340AFB0BFA7D56C833E07CF47
-:1060800057C2E6423BCCC208CFDF84B9F7C0DFAFCE
-:10609000316F22CECF74DE541CF79ACCA7255AC399
-:1060A0000601F6F59B14FB63B88F3B05F5F86C1100
-:1060B00071208DC57EFD6AFE9C6D79C2A603FC4FE2
-:1060C000E7E867A345E66240A29A51F106A463C1DE
-:1060D0006663AB60FD07330FDDCB802E1E1ED03113
-:1060E0002D9CAF5ECFCF3D7D20EC9400FD468F2AE6
-:1060F000165916F437AB5829F43F94297A55D89F8E
-:10610000E9DCD89FE90A6DBE0C599681FCD0887AEB
-:106110001BF5EF78F31B01CA44E9E2E1483857E286
-:106120002F054B3DF4291B3CFDF4FF85B2F452537F
-:10613000CBEFA1FC75A4BD19517772B0F8941D5036
-:10614000F6B0C9A3B364F2F902F7DFF1AB6F22A294
-:1061500045FFBEFA074EEF7BD98AA5CE22C0B8E92B
-:106160001D92579B75F97EFAE361E3A9D48FE1395B
-:10617000FB0DA25B10B0FFE10F717FD37506AF146A
-:1061800081E3D4177C3AFF38661E1D75FA4646280F
-:10619000F83E91B158DC3C8C1FB8687037C1B96FBC
-:1061A00091F94FA1AF1E8B48F8E991F1A4C091E994
-:1061B000B222917EEBD58A5EF085B34C3F7FD6E864
-:1061C00038FF0C5E126D38FF60B9D6CD608AC18E83
-:1061D00054D2275792A77F0079CA40D7BC976AFB51
-:1061E00033C20FF94A07FC78970C2FC03FC3F9253B
-:1061F00079FEBB64B8DD6510399C7E120227996E6A
-:1062000014BA50F62F98635869B41F9FECD7DD4736
-:106210002393098FE3FF83E3EF13C2DF3727D60110
-:106220001BB151FF984578FC5FC09F57B4FE0BF837
-:10623000EB0EC59F577F3DE2EF71D1D284FC800801
-:10624000C8A1D226C2F9580623FE2F93C22C9BE088
-:106250007C76E4FF9B88EF8F22DF2BFC3EA6D837AD
-:106260001EF5E449C69EC17DF9440FB5A766A71087
-:106270009F5FC7BA13B01DF09C3717F12ED876E890
-:10628000242C7DFB5E86F55D1506CB1E386FBF5B4B
-:1062900074A961FE8628F78EA5B06EC35D991617A6
-:1062A000B63396D58672A03CCC827ABE218ACB8545
-:1062B0008605E9A4870F7E2725ADC2732C08B33469
-:1062C00041FF866CDF2313A0DE30D66C7141D757B7
-:1062D0000596BE1DC7CFD1D13A0D7338DD363C329D
-:1062E000DA8D7A05F4CFF37AA83F591EC6F09C0DDB
-:1062F0008DB68468A0CB9722ECA3B361FFA3244E94
-:10630000D70DC9D00EE536A164C17D38DF78BE6FE8
-:10631000DF82B017F7C22CFA341059D07E7295B1D3
-:1063200009E5A5429777A5737937C6756A07C2C98B
-:10633000359D65D4C2FC7F93E94B81BB60636C558E
-:10634000B41FFE0A9DC5C8701756737A734D97E542
-:10635000623573D70B085FE60B07F8966941414237
-:106360006934D9ADB8EFFAE5801709F7CFE17F526C
-:1063700064E59E61F8E747282CF3884C04E48F32EB
-:10638000C6F9A30CE908E96F15D05100FD31DF759E
-:1063900051A7C3653A82F16B8D25D370BDCF853F80
-:1063A000E463E3897F4AF3875B67563697030BF410
-:1063B000F699D89FED8E14515FAE30F1F54E647FA3
-:1063C000361AF5C5C95FBD791D96C7234A6ECB86BF
-:1063D000FEDB167C5D84E2FC6F093E359EE36F0BAD
-:1063E000FEFF68B443CA56BF49F4FE43F759281963
-:1063F00032504EAF047DA615B0E474B0F23E467440
-:1064000090C86A896EE365FD050CA3473975F300F2
-:10641000D88ECABCF0FF4797746C89CE5F9FC6A226
-:1064200082EA33740941FD0B4DC941CF6F8D1F17AF
-:10643000F47CA6393BA83E3B635250FFDB2DD38250
-:10644000EA774E9C19D47F8E6D4E50DDC64C241FCA
-:106450003AEA8A733F01BBE1B5BA92DC4F5497E345
-:1064600063AAF6D07EB305E824DB3B5F3509EA91E9
-:10647000875626437D53CB115E4F3CF44532E06690
-:1064800073CBD1F92AD0DB536F3CF4450AD41F6D8E
-:10649000E9E2CFA7C062A340ACB6BC39DF05F89AE9
-:1064A0009B62DF8AF89A77A9F6288AF9F7D7CCBDDC
-:1064B0002F5942B930677406EC2737C5FE103EBF2E
-:1064C0002BF69E759100FB1F7D5BAB463CBF985D34
-:1064D000B215E9A1FF22A7F353889791FF7E099691
-:1064E00003D9618A9CBD923C54F8AD03F4C61215E1
-:1064F000C24947A5B7CE44E5A1BA782A8FD499D925
-:10650000128063575D0695C7EA2CD47EBC6E229537
-:1065100027EA6C54BE5B574C65775D09950AFFB25C
-:10652000BD960D6A2442972AEAB4CE4F8F57D263A4
-:106530002028D969059FD0F94DBDAD399BCE759DF9
-:1065400009E959693FDAF9815904FA9D6AD5113D83
-:106550004F35749B75565E47B9B8FB22F38A11BC60
-:106560009F2AB05F8C271BFD98A90E03F54B1B8457
-:106570007E59D8EFCD0494F7536B3516B4639E5013
-:1065800033971EF66F14DF90701DE320CA6CD80598
-:1065900018D53A905771A06BF139F4633A28770F08
-:1065A000F2F54647D72E47F934BACC60A9E7F29501
-:1065B000E44BE2086F02EE2F71A586DA8D628F1927
-:1065C000E5605F9D7716D269812CE70A345CEF3075
-:1065D00011E4BD807CFB6D5722DAF3EDDC9E2FD0F9
-:1065E00096EC44FAAE5671FE65317AF71E5C47D5DB
-:1065F0005DF12CF4EB894DB46C4268C51F64696091
-:10660000B717D61467A2DCED615B88AFC15EFD13DE
-:10661000D2DB8F3381DF459948609EF8E2F0A64DCA
-:1066200002DAADD7E7215DCED59A0F30E0075FF6ED
-:1066300000D1FBDC48731E7A0ABEECAF793DCE7CFC
-:106640004080E7263630BF00EA55CFE94D9F04F081
-:10665000A9D3131554AF694B307D12C0A755F80765
-:10666000FA47B7092A94BB0E792BA704FB05C4B7D8
-:10667000B3F8730DDFDF8006EDD88BD966A26FB05B
-:106680009749EF0FCC34BA9B60BF71236AB357A010
-:10669000FD9469CEC37E49EA8108F463FABF5515BB
-:1066A000BBC9EF1988F8C9783F7D3DD321517B28BC
-:1066B000DDB5E6707FAF26CDB019F1501DAFD351D7
-:1066C000D971B188919D56928676B94DC3FDCBD0D4
-:1066D000F17B73B81E495EAF21B940A208B66C0BBE
-:1066E000634ADDC52632D6F88BB021BF07C0C93456
-:1066F00063653FC8356247415A507F1BF61F7A8E4B
-:10670000F61CF38F4F7949BB63AD4A5E0FE96529EB
-:1067100073A33F182AC7AB72A365B9C0F1FC748C90
-:10672000BE11F19C26017DE750C94C50268633B23C
-:1067300037135FD7BB913E77EB39FDA789BCDC2DC2
-:10674000F2FE9A30E6427A57FC874DB9F629B979BC
-:10675000348F97E6915AB291AE139887D657EC24AE
-:10676000A51FD8437A1202AA8174C4D754491C16B3
-:106770009E2772A615E58C44FEB0B14F03E4775F07
-:1067800078C4AA40FC55E37843E0B8E9344E19EFE9
-:106790005C25B24F47905C243A72A689E42F564B91
-:1067A000EC8880FE16EBD6A09E53C6F5821CFC1426
-:1067B000F0F047908B587E08F210D7FF33C8432C77
-:1067C000FF0AF210DB4F823CC4D207F210DB3F0617
-:1067D0007988E5BCBB8D56E49F9AB669ECD3207EE0
-:1067E00050DB7D01F5DE69C3D39143A6A3DEE4E16E
-:1067F0009FAFCBE17E45EF2D1C9FFDA0BFD1FF00D9
-:10680000BA5C6B8ABEB21EEF37B2F91E80D3B67C7B
-:106810006E87F427F0FAD21C35D56D22DB8EE3B7F4
-:10682000E56BF8FA2962393EB745F3797BD345B277
-:106830009FA64E9EB624079EDB62A13DC75FEFBDBB
-:10684000813FB78DE2ED437A567E3E25D7A4F8EF1F
-:10685000E9DC2F65642701BDD3FC4AFFF726723EB1
-:106860000CEDEF4E138BDDC3C0E32D996F892FD054
-:106870009E463E480EE08B6A33F18542870AFD55FD
-:10688000E57238A769653A07DD42F0431D83723A25
-:106890004E4FF625C0C5C6E03CBB05995F42F901E5
-:1068A0004AD4070A3F287CA0D07B22F09910ED3F04
-:1068B000C7CD21F4AA948FCAE7E88E35FE9CF0DAA2
-:1068C000A136A1DF7733CC87E313C5C177EF46FE4E
-:1068D0008C359AD1F52C7CC8503B9C1CEBFAEFC24E
-:1068E00043910B5780C76570D0F0F25F8503C939BB
-:1068F00094E348BFC3C8ADFD39D1B25DCEE9F744DA
-:106900008E6D1FD251BFA057A1DFD0AF67C3DAD9B8
-:10691000DBF2397F287454053A10EB8978CED4CB5A
-:10692000E59E729EA1732E6324FFD2C2787B289EBF
-:10693000957305C8BFC33901F11FC6B87D711DD855
-:1069400017E84F4DC935D33EFA477E56B695F9CF75
-:106950007F470E6F7F4A94881E14FD32D42E488BD9
-:10696000E66406E91D66423FAF534BFCEE057FE649
-:106970002518873E219BE43FBF20E37170FE58112C
-:10698000EDBBBEAF0D2ED4637DA3064E0A30BE6FA5
-:106990003B18366497D86E1340EFDE073A06F5D4FD
-:1069A00005907B2C9DB173721CA1CF73F124FA73F7
-:1069B000353B24A603504A3BBE9A87F4B4B4536DCA
-:1069C000A2B8D0F6C78E213D9E6E15CC6897F4B55F
-:1069D000C2F1A1BFB3C1E8D643FF22A863FF650699
-:1069E0008DDBCCD7A3F883435EEF537D750AC68554
-:1069F00066EC5013DC973E2FB9D13E3BBC7DA50A17
-:106A0000EBA7DD028B837145D2EAAE04A8573E2D79
-:106A100058B430CE61283A8BF182CAE799C50BF39E
-:106A200057B618C9CF5DDAA0FED817605F94BBB720
-:106A30006AD0EE29DF19DC5EB93BB80EF822F9EF17
-:106A40006886F600F9FC6D8E3186ECCD712C1BED5D
-:106A50004DD6C0E3B98A7CBFDC6E757139BA82CB82
-:106A60006DC6BE8C457F5FEAFC2AE96303AFCF9118
-:106A7000EBA7A0FEF9571C2F0A5CAAE5B53F4F60B3
-:106A8000560F9CB7BA536F42FFBFBAFDEF1118B74C
-:106A9000AF09F3517C9FBD2299D0DEDBD826B91017
-:106AA000BECE0EFD2E11E0567DE03D8DD988705F83
-:106AB0004EF6CAADCCB51EE3DC5E5164DD4447DD65
-:106AC00014A766B681A5384F5FBBDE847640F52BF0
-:106AD0001F74DD8DF50302D3231E47FB884E96EE0F
-:106AE0004086A52DDD26E4FBE94442BC229E3D9173
-:106AF00084AF658877C433E01DF12C213E71BC5111
-:106B0000E3E6742251FDF4731CBF0ADE8BA4CD1A98
-:106B10006CAF6CE4789EB163CFB630A2033593E9D5
-:106B200080F07E7A27C7BBA6739D6614D26F630878
-:106B30001DB46B87E800F777191D84E0BF02F08D64
-:106B40007220940E42F1DF93C3E506D8DFA79F427F
-:106B5000FBDB087E01F3C7234656F51E8D81F5CA7F
-:106B6000A2CF3B9743FBD8F89758DA088A7F15E401
-:106B700062FC6BE63BEB105D3DB35EC8467AA957FD
-:106B8000FBF63C81718BA8708AE3F427CFD9F932E8
-:106B90009CBB20FA9BA416D87FCD6B5ABADE28C9BD
-:106BA0001587EC358C9729F174C033C5C99C1D5AE3
-:106BB0001E176B2DB405FA73FD09FC5C859A81B232
-:106BC000E5E817C07CB88E60E37E5E55078F172816
-:106BD0007E59951237680E8E1B08A677A85F452E42
-:106BE0008F5FA5C6DD6C463BBC7E01B387A55E4DBD
-:106BF0003FF078CCD3B2DF7445FBF10A7A42B11B87
-:106C0000992B386EA1C8A96513F91E8FFEE2B86AE8
-:106C100004C6FD760B848F8A0E904F70DE0AB7DAB9
-:106C20006D1602F849EEFF19D21BC0ED8CABF6A031
-:106C30002821DD1968BF0E993EAB918EE0BC95D638
-:106C40003722F09C0E59AE38DA8D147FAB645B8A24
-:106C500090EE2A613DEF30F454F95C0BF929D7A28C
-:106C600027C5CEAC6E0DEEB7317748CE8CFF1EE057
-:106C7000BB016439D77B2E99FE3223F1DE6F9099E8
-:106C800023919F87F49FC0ED3745FE5CBF1D583CA4
-:106C900060DE716E1D5305AC7FE373A6A0FA784FDA
-:106CA0007C50FF9BDACC41CFB3BD1941CF738F59D4
-:106CB00082EA79DD1383FA4FF8D016549FE42B0E45
-:106CC000EA3FE54C49507D3013CE7395FBC15BE341
-:106CD00085A0FE33CDFAA0F967674405D5070D32CC
-:106CE0007C64BB52B1775FCEE5F66E68A9C0F776DB
-:106CF0004BF03A8ABF7EE7C4E0F5E6D882D7FBA125
-:106D000078D90BFA54057EC273A05FB1FC1DF8134D
-:106D10002AF0139AC19FC0FA8BE04F60E9017F020D
-:106D2000DB5F027F02EBADE04F60FD20F83F586F64
-:106D3000AB2BA6F295BA126ABF16FCBAE4758FC9DE
-:106D4000EB1E97D7FD77E174429EEF5D79BE6E9C96
-:106D50002FCDFFDC593C56BC04FC3C2DFAACC68759
-:106D60007EC30A5F11C62D06DE9218C6A599DD7D89
-:106D7000AC2E06F5D9088A33B39281B731AE527D75
-:106D800020D5B4C98CFAEC0FEFE2F3BE56C98C7C67
-:106D900079A8EDEF1138CF854B61745F4A7A10EF17
-:106DA0001BBF6154DF04CF310E3AB3050408E93745
-:106DB0000FE9B70B694ADD4DF7BD25CD2D1AC45338
-:106DC00015F2293C7FCBA30E7EFE5C63D07313F6D5
-:106DD00087B24AE5A638C2B936653E2FF577A4F1E9
-:106DE0007BCF73CF1D5E3F05F56FCBE211787F5EE1
-:106DF000D5FC5EECBD57C1C7E7075FC8A4FBCA76E8
-:106E000098CFE09FCFD9AE96EB7CFF8EB496A26868
-:106E1000541CCD021B0BC505B685EE5FAADAF63809
-:106E2000506E5565DCAD66009F7E8F24C737F8BD78
-:106E300091C3C4B81DE7F92202EF575FF71CBDC329
-:106E400086F8ED381C81EBF6B74A41FED3682BB7C4
-:106E50008F475B3584BF0BAD8723F05E77A3E730A8
-:106E600087BBCA4BE73F24D7FBA12478B74974FE00
-:106E70008A4B62D03D768655A27966B68D35E2B9E9
-:106E80007A3C7CBD1CAB99B7A72D5E82FB3F1EBF31
-:106E9000204F227B100435CAF11B66EF413BA4CA88
-:106EA00023D986F3EF0AE479BBD49C4EDF4ADBDFBB
-:106EB00085F2F878F1886CD2118A9F69E5766F9136
-:106EC000C69E867AA4C76036229D3F589C6A44FCC1
-:106ED0001EC212DB8B7769EC06BCC7E6EBF598BAED
-:106EE0002390EE7A5A7325B47794F9F2E57587E822
-:106EF0007B086F2EC253B9BBD180F3F8F1C7DB73A7
-:106F0000AC26EA7FDCFDDE3CB4AB7A32C2C92EE9A6
-:106F1000D230F2A7AB9AB95DDCD391D818784F92F2
-:106F20006395FDF20C91F0DAD7A696FBDDBD8705DF
-:106F3000F553D3392FEC0EDE8FC97DEA51B4C71D4E
-:106F40004F4B0CF5A2435D1B8BE7FF6C67F0FECA4D
-:106F500065383BD4DED8D8007A75B40FF18D81E85E
-:106F6000BC5DE11333E153C1634F06B7E77AE2F941
-:106F7000BDA4A3650FD1F5E5F1A4EE64F41F127F63
-:106F8000A9A378E7B5FC67C56E08F0AF18FA8BEADD
-:106F9000E2D43C31C56F1FBC966BABB68E44BFAB21
-:106FA00084FCCA1E06F62CACE9447B3A92F21FB66A
-:106FB000E1BA83AD6ABABF76EADA667D0276D9A015
-:106FC000051805F63DB8532DDF7BD90C68D72E95F3
-:106FD000EDDACFCCF67C09F4AF738D48E7736486A5
-:106FE000911FD327CBBDCF5B92EF24BBE1986442C6
-:106FF0007F688687DBC18E666ED7567B92FF632AD9
-:10700000DAEDCD6ACCD4608A1DE294ED90D3B2DD86
-:107010007B7ACD8086FC9B4E813D968C792A5BBB2A
-:1070200012E1B9337316D9B34EA999EC8965DB83A4
-:10703000ED07B06F82EA55CF85DA17727CCB13DC8F
-:10704000AEF887DBAC4376C638F4670AA5A971C8E9
-:107050000F2FC87855FC9B95E32D94B7B351659ECF
-:10706000A5C421105E359DFB2B70DF6E479885FC13
-:107070008D55AF105CFBBFE47E4C7F3C2378F4332E
-:107080000EDFFE364EE7356AC18DF9483540B6341D
-:107090009F4E70AFC138B36B3082E41363C5C8171D
-:1070A0002B16707FD586315F286B157E08D1ABB764
-:1070B000A87C5254809C68B3A650BF020DB3A33E77
-:1070C0005B69B4907E1BA3E3767AE16A4F36D2C344
-:1070D00018F0C7B501F1F831860101FBED7E80C7DC
-:1070E000FF9578C21C95491D15A01F195B43FD959E
-:1070F000F941A2F0F1D79ADF04F31BFCF303BC23A0
-:1071000011DE5F582DA4B793E628F7FFB5C497CAE0
-:10711000792E00BD611C1863348837C7CE37C89FED
-:1071200073B2EEF538AE2882EFA308F783F5305E30
-:10713000FE5196E7B179BCBC4D2E15F9D590677B11
-:10714000DF0AF59579F63F5949AE99883E57CAB49A
-:1071500002F64C9C6F18F9BBE21D89F0FA05F003AA
-:10716000F2FBC25AC19C16642F713AAFE14DEC3C60
-:10717000F3F44E4538B86CDD1998D7C6387F2D5AD0
-:10718000A537A705DE0720BDA3FF5102FFF2D12FCF
-:10719000E3BF7253C56D9457B52AD68CF71735C81F
-:1071A0000F29D7A6FF50BA87DF4EA4B76AA6B5A0AD
-:1071B0007EA9690B7D6E51A13DFE4D085F24C97407
-:1071C000DA6817E87EBDF15B158FA3950A1437BB0B
-:1071D0000B1A914EE987FDCAA7B9717ECCB3A0FB0B
-:1071E000AE861839EF2B86EEE17E229FFF2E95F7B3
-:1071F0000DE4EFA36A4F32C6718E3AF93DD502E62F
-:10720000A17BDD52D64D656F78F5012F4DEE1A8DBD
-:107210007EF807762DC5911AD7361951CE66B1B5CD
-:1072200026BC1F033679EEFBDC2BDB1BA1F7689431
-:107230009F95E7C7F3CABC92F83CA0833380A3F8BC
-:107240009CCBC757BD7F2002E17EFEFEFDF37ECAC8
-:10725000D00F02B905F354D6B664D0BD8C8B7567D8
-:10726000E4FBF1ABE053C11FB49983F00A67B90E98
-:10727000E0339F0DE4636ED3B5F0A9C039493DF00A
-:10728000630425E8319243A17856E05ECD6AD53C8F
-:10729000FE56FBEE02E8FFB3B5A219EDCACBF07EB5
-:1072A0000DFC78F5FC91D728903F7B257C29785AF6
-:1072B000C8BC54FF308A8FFB70A144F1C3FF697CC6
-:1072C00035E4D94BF2AEC2B7A17C7A25BE5CB42AB4
-:1072D000847F43F874882F2DF02F007FF65511C45A
-:1072E0008F0A7E1D66F09351FF75182D6E76393E1C
-:1072F000D1DFC5FD54B60AEC49E187F0AB8FFCE362
-:10730000507C01ADD8501F54E705F3A982C72BC9A3
-:107310002D45EE7DC4BC474D02DD67703EFE85966F
-:10732000F2E994FB0CE5DEE2D13CAE6F42CB8FC0BC
-:107330006EC17BA24D193D23D1DEEBD528F3F07B46
-:10734000D78FD6748FC67CCD8FA6F1B257C3F34CBE
-:1073500094BA2D8CC7033F4AD0BA106E1F09E3A61A
-:10736000A31DF091F0CB3B783D4E63C6FA82B8E99D
-:1073700026A8F7AA95F8E183B2FC7653F9D18209E1
-:1073800005D44F6047101E668195D03A82105D0C7F
-:10739000FBF9E8E76373F05E4039FF03793C8EF454
-:1073A0001BF91C43F1F65F09146F5F04AAC384F74D
-:1073B00002D39F284E81F693BF4ECDA6FBCA15C1BE
-:1073C000EBA3FE4DA638E5569AE7964B03EAC5991E
-:1073D000FE7D0DE9CD828BBC7DC9D8A07C665BF4B7
-:1073E00038EE27BB5323518F297A6DF0D87E436046
-:1073F0001CF5AC1C771EAA8F7B2429502FBEB1F739
-:10740000E1749CA75CE3CAB218308FF9A924B41FB9
-:10741000CAF73E944E76EDDE8DE9E89F94373D9CA9
-:107420006EA37AB89DFC23153FF7F97D93766D0A1C
-:10743000B0A36F9DC0EDFB52DD1B8568DFCEBAF1B6
-:10744000F37518B71FFB6B81E2700B59F73AD4B78D
-:1074500065199CAF58838EE43FCC47F7A47BC6DD0B
-:10746000BE1BE5FEF18CBFAB97A0FECD53D17C6572
-:10747000CCBD390EE36F1B048ABFF9FB8FA67BD707
-:10748000C56B054D7C0CEA519E77FDC7BC2882E395
-:107490003D1BB2BBB0BD6C356F9FA575B7F6E03C28
-:1074A0004F6828CF0A14654A49C03DF61FF3F83DDE
-:1074B000DDA2CD72BEB1BCCED86DB18D81E7FCA38B
-:1074C0008C7F56FE01C9833B65BCDCB6FABD23F157
-:1074D000306FA4DAFE67942BEF3E7E3A0DE55941FA
-:1074E000F4D94CA4F3B11AFB931578EE262DC52BD5
-:1074F000AD5989521CF4CFB97FDA63582E5ABDF8C2
-:10750000C90A8CFB6ED7911FA6EC6F856016D15F00
-:107510003DDCF8D37B106E671EE779A42B1AAF8F82
-:10752000BB5AFEE2B3753C1FFCF93A1D952FD49966
-:1075300098198EB8AF2E9EEABFAF3353C9E673FADF
-:1075400052F2A6AE345FEEA530CA5BB66ED0511EC5
-:107550007DAED6F6551EC06BEC0DCEA68DF2B9C62B
-:10756000C2F86C57F20C848375E3F22E34614FE558
-:1075700071FFEAED9E0D496487AF3EF54C053CCFA7
-:10758000CC2FF90EC7EB765EA478C1E1F687CA105E
-:10759000DEE54D5A7E3EF9DC671E4F8F7B12E3BC61
-:1075A0006FA9C97FAFD979EA998D50DEBB79B92629
-:1075B00090DE7FE879BF95F7732DBEBA121CFE7579
-:1075C000BE7A3889F8A709F82AF3DFE7AB9AD56BBA
-:1075D000087E73F34BC6E6C3FECFA85D49C84F676C
-:1075E000C6DD4C74EEEA1408FE8A1C57C6A7E6F303
-:1075F000FBE82AD1B399EC48598E7F059E23C2F748
-:107600008DF6CFD2D18EFEAA6DC155CF7DB00E3D85
-:10761000228C9BE9A80C7D9EAFB1A7625E71BEC8AB
-:10762000EDE7D0E7B7E72B71781EB7C59F1090A79D
-:10763000E2848D4546A3FE13BC6120979D6DB79EE5
-:1076400055A1FF067EE1C7C17628FB3840AF5F69D0
-:10765000BFD72AAB711E955FEE4EF85064DE003D39
-:107660003EC917C6BC01EB0EF92BD0A6A1FB9E04A8
-:10767000920B8837CC87EA6B1FD784F5B31A8EC775
-:10768000BE83E097F1B80C93F2FDE73CDB7E3E0B46
-:10769000E56CE879AB5F394FF4E1687BE8A240E73D
-:1076A0009F79569575EDF3BFB1F77C16E2EFACDA32
-:1076B000978FFE579FC6978578A87E95CBF37F1549
-:1076C0000E4A7BC5060D8F130A26F2230BA50B1459
-:1076D00007E83BC6E300D5EDBB489E0E76F0784C3C
-:1076E0008DD85D1487F18BDA535D28CF06E3B95F3F
-:1076F00006F3DB28CF2155D683AA81A43920D71ED3
-:1077000019A207EE0F9E41FED5E03C1E07E561651C
-:107710008533B42BCE213F437BD9AAE4F548E767F4
-:10772000DC2373503EBE9DF58F6A8ADFBD1E6E92CC
-:10773000C88E9530C778084E43E7704B3CD18729F7
-:10774000767138B305F4ABD198EF24BFFA38BF9FF8
-:10775000ABB981F3137B85F39373ED1B9AF880F932
-:107760007E25F393624FCE7AFD1FC4970FE7DA9E12
-:1077700040BE0C475988F3C547521EB5F21E8772AA
-:107780001F69E890FDF862899ED7B4490CEFE5586F
-:10779000BC91F20A8AD916CAB79CC53C53795E8F50
-:1077A000EFD129F07CF6EB522EE6A1813D4DF7DBBF
-:1077B0004561F634CCD3EA150519AE1EEB9C007D6D
-:1077C000F67E3EF757A74A02E9B1818470B253664C
-:1077D000CE7796E27E957E5A91EB339887EC2CE635
-:1077E0001EC8C27B55E61DC8C2FB56A5DFBCD7C369
-:1077F0006B492F328F755EC03AA7F379BCF30BBC8F
-:107800001F07795223DFC3164ADF6E437F6B45277C
-:10781000BF7FEC15933FC03C3317C019F17A1EF0BF
-:107820006A43FD6367361BF2CFF8916EE49F9A7D41
-:1078300002C37CBDEA766D13C685AAD5BE58A4E7FF
-:107840008D6DEF6B909E6BF05E763C8E6772BCDC4C
-:107850004479BF3526C6EFF5DAAEFF00E376CE6396
-:107860005C8B3A55EF513C00E536AE57D5DA42FE17
-:10787000BF8379C9FF773407D3CD603C8FE787F2A8
-:10788000C9E97C73107FCCDCCEF9631EE6731B68FC
-:1078900038C55F67C6C7915DE21FC7F16093CEAF81
-:1078A000433BA63F45A07CFCFE30D75AB48F5CE931
-:1078B000DCAEE97FED052BBDF7A3735B7F8CF93C54
-:1078C000B2DD3B73C3569514B09F991D3CDED81FA3
-:1078D000C6CA0F12DEEDD7213E7CB92567F231BE54
-:1078E000A31978770AC683441E1F0D3D875D8E6BF2
-:1078F0001C67FCFD2865DFB31313B93C636EA2A3BC
-:107900002E39BF5BC9D751C6DF324150EED1B89F87
-:107910002458AEFA5E1ADED7609E2BDED760F93BA4
-:10792000391F16EF6BB0FEA29C0F8BF735D88EF780
-:1079300035586F95F361F1BE06EB785F83E52B72E6
-:107940003EEC71DC2AE5F16D7C0AE9A20B796D94BD
-:10795000BFDE1B1D521F15DCBF375A08AE8F12A8A1
-:10796000BF69C2C6A730FF7893922FC5CC46B4C377
-:107970002AC2F9FB1AA9067BEC04F4F38B77ED45D8
-:107980007F1EF89BDE9F2B885E504AEF97C46819D4
-:10799000CAA3DB27D8474F80F1C78ECD48DB4A7298
-:1079A000524FF7ECBD3FBB3192E27A6F494C8225D2
-:1079B000A765E4AEB5427D9A4120FA85F96E2A5159
-:1079C000FC4C986746C762AB8ACB0713DACB85922B
-:1079D0006309AEB322419F8B72F888D59E81FB511B
-:1079E000E05D346A591ADA455D6AF307189F75BD80
-:1079F000A366E85729713CA5DF93D669F9B8BF990A
-:107A000019A96B73707E60369477360D6BC6FDD9FD
-:107A1000C470A19EE4975985F2207F02A79BE96676
-:107A20006E1F7B35665534FAF561D362F05EB74B55
-:107A3000C6F33119CFC7653CE33D57818ADF7361D7
-:107A400089F75C5886E6A32DCF2FB14D20780F24FF
-:107A500005E6B3CD92DF97000AA1F7D49C721CF320
-:107A60004B59EE34E695DCCAC779689E2A398E7781
-:107A70005E1D7C6FA88CF38F6754CEBD89CB6B16CF
-:107A8000A9E179BFD73117E615CF7D3981E2507D65
-:107A90006ED1A506BCCF055E4779C65EE6FE2E8B8D
-:107AA000E77C33777F1CF5AB97E3A9CEE8EE747CD7
-:107AB000AFA34FE62FA57EF03B9E97E4CC81BA8121
-:107AC000DE23A1F339E776A74741BD4FD08B485F4E
-:107AD000CE26FEBC47E63F678A3C9F7C1EA6F32469
-:107AE000213EFA3B5F4EC2F7103719BC4BB9FCF789
-:107AF000A693DC66DE74CC6F3A2F784E62BEF1AD91
-:107B00006D29A5986F7F5EED7906EBB3DBD2785DCA
-:107B10006839690A7C3ED29384F9C8B7B6A59662E3
-:107B20003EF2F9912DCF445902EAEA974EE273CD25
-:107B30008369A5989F3C5BEB3E568774F37B4E5F51
-:107B4000FA7D074E237CAADAB9FD3E7DDF810B2F3B
-:107B5000A17E3E60A4BC8275139209DFF5EDCF6E65
-:107B6000467AEB6B51133F6C6A7EFF99DF503F2DD5
-:107B70008559666B3D560CC994B41DBA1BF7353B4D
-:107B8000DCF325D6174FBC89F6317B04E7EBA51350
-:107B9000734A914FFB0EECFB05EAB3D99160D8E232
-:107BA0007E5ED0137E2AF78F2BC0B8409FB1BB0CEE
-:107BB000E7AFFE9D96E71FEC8F9B8E7182FF9CC006
-:107BC000F3312A6ED89284FA567CE5F9BDBFC1F82C
-:107BD000E6EFF474DF5313CDEDBD4AA9317F39E1EF
-:107BE0006FD75ECC5BE97B5E4FF7AF151893B3E2BE
-:107BF0007BAC63293EFFEA3FFF5E8678289476EEF1
-:107C0000C5F62F77EB4584438FC6167933F2618F23
-:107C10009AFCCE0AB95ED13B82EF27DC5744F88B41
-:107C2000D99284FAB672C4AFEEC07DCF96B63C83CB
-:107C30007E0F7B564B770E679F07B8C1B8B37BD4D6
-:107C4000984903FB30AA905ECE0B5BCA9EC4F9F73D
-:107C5000F07EE7F55B089EAE3DD7335C0FFA31D47A
-:107C6000C7E785AD41ED67F73C9B857EE9B9DFCD80
-:107C700026FF54A173855F2A776B83F422498258CB
-:107C80008C5BCA3F938B1902E259E70EEEE87B92B8
-:107C9000F9C79F6B567B3500A30A2D5B8BF9CD0A84
-:107CA0003F5426DE5A8CE7AB141BD3D17EA9C8F50E
-:107CB00095215F9CD5335D3CF47B5BD65B95AD6BCA
-:107CC000E6A01D7CA5FDFC4596475FC97CF8559B49
-:107CD000DE1D78DF185AFEB58E994FA8FCF585B5E4
-:107CE0005AB2E595F9DED6781CE8AF554773F971BD
-:107CF00012FA37831CFB93ACEF16AD0AEEFFEE04CD
-:107D00009E4F59ADF1A5A3FE53E67F7B8289DB87A9
-:107D10002A5F3ACAABD071B32559DEBC2090BCA90A
-:107D20006C154ED1FB2408D2583F3C2B752E37E6FC
-:107D3000130D8787F87C190F12E6F170BEAA6CD676
-:107D4000DBF4304F55982F02ED2587D117817650FF
-:107D5000DF2B126B92D117A3CC9FE25F4F89535652
-:107D600078D436FD70EBC171D04F5E867F03285604
-:107D70004FE47C53DE164EEB31932F1FE9B67C6740
-:107D8000F0383CA729801FFBDA76C506FAEB0CF722
-:107D90004DF751A7886FFAFFF931BD075E29B2B5DB
-:107DA000784F794EE0EF83409DDE073927DF775625
-:107DB0007E6D0843FA39F79583F8B84FF0919C7BB4
-:107DC000B1CD4672AC4FED2339B76B6211AF47F9B5
-:107DD000CA506EBD38F1A7243FFA127C65F89ED2D6
-:107DE00066A58E2FCC811DD0D1B690E4C96C89E7F1
-:107DF00051B05D6A138F1371782F93E1C4D886DE7A
-:107E00003AF243D466B4973A272AF7421AFFF92583
-:107E10003F3FF531F3BE56E4CF7203C57DC0BE6A65
-:107E20007E09EDC005B1168CA787C24DB95F8C895C
-:107E3000FE6629E2E91DA37DECC43CBCCFF4919F12
-:107E400001D44EF67CF56B5AF237FBD5037B517E9D
-:107E5000B98DF67113019E0E4DF77A547117D4BE89
-:107E60002E34ED6721BD911CE1F4D697B98BBF0785
-:107E700022DF4F4E92F100FA8C35227D081CCF870D
-:107E8000DBF69F4079D3D79D4A723A949FCEB63D98
-:107E9000168172E343D0EFAE8078C0878B9FA57CBC
-:107EA00080F9980702E53D6B83CF37F8ED8FC92F36
-:107EB000649B03DA911E1B82EBA17041BAF406F1B8
-:107EC000818BF67D3FF21BC0A76A7A7735C261A825
-:107ED0003E17EA5240FD50483DA43F2BE1F6C3FD5A
-:107EE0001318CDEB18EDED253F7E1FCFEFAD07BD8D
-:107EF00046F503E1743F2DEE03BD15C3F516EA8B7D
-:107F0000AA886E8A5FF51DD0D2BDCA83ED9F25E198
-:107F1000F9811E294E53D5FE722CFAF7EB2698698B
-:107F20007ED08FB1941773A03D16FD11A5DD217A87
-:107F3000D2E5F70CB2507E28ED4EC99B4E79E54252
-:107F400077163E5F27CB1987087509EB8CCEE110B9
-:107F500038DFB37689E47C28DE56C9F40AF2218B37
-:107F6000F2395EE1F103451E54C872E510B667723E
-:107F7000FE3729F75278CF847C3F8C9CF85A8123B6
-:107F8000ABA5F8CEFD13CDBC2E8FA77979FC89E780
-:107F9000EDBD7A3E2B2513C79995F745FDF228D5FF
-:107FA0002F5F500EC4931C78501D0BE7AA7C46B07F
-:107FB000D4C3908AD23545D09D2D532D2FA2B81A07
-:107FC000E6E71A2EDF57281D454EE4F8AD14B91F19
-:107FD0005EB957A0FBA5736A7E6F07F286DE0F5865
-:107FE00056B0A608F9EFBE18A726D05FBED6FC4B48
-:107FF0001B82EBCB6AD714C50DC3E795ABB6768D64
-:108000006497CF57616F2C8A355FDEAEECFB9C5EC8
-:10801000D9E774F5C84078CC5F533412CA65BA7F8B
-:10802000171EFCDCE7DAB55ECA572D5D43F7C4B70F
-:108030005CAA0D8AB35E6BBE0AE6A67B902BED3F71
-:10804000B47408DE5E8C2B31E0AF3DC467C03701ED
-:10805000EBC5CBF43A149F285F3C06FD53665F3CAA
-:1080600026303E115AE29B3322E58AB8A8043E2C02
-:10807000B30C030FA5FFD1893CCE1A3F91D3F1A8D1
-:10808000D9553B5E6214D7E941F97BA5F74CFE2236
-:10809000EFEF07BF6732239CF7EBD49B30FED3DFB3
-:1080A000F90DC587FBD719E6F37B07034B80E75D26
-:1080B000F1E39B02E3C0AB26713B24DCCAED9D9A41
-:1080C0000CF5D5E34B99C6A1F812D91B99E174DFE1
-:1080D000D2D7F605E9B7FE8E3C13DE8BF475BB0DE7
-:1080E000C86F35FFFC7FB1A887FB3A3EA5BCB4BE84
-:1080F0006F3FA37CB58D72DEE0A13639DFABDB6C60
-:10810000C4F6FEE2BF1761BF4D72E98F2FF0F898F9
-:10811000522AF18300FFF93BD4537B4C1B1FC554FB
-:1081200099CAB02D24BFC07F8E46BDE18F2B98E346
-:10813000868BC304C615D2543CAE8025C615D2D258
-:10814000785C01EB1857C012E30AD88E7105AC6356
-:108150005C01EB1857C03AC615B0C4B802B67F2907
-:10816000BFE7D10F828BC73D0D24F757627E33C026
-:108170006F6527BFBF5AB947A27B617CCF03F5DF8C
-:1081800065793BAD72DE8E672BDD07D61C902C889F
-:10819000227C1FC4958EF93B0347311E54D32258CD
-:1081A000D698B17D3EED636347DE07A5D8BE476D27
-:1081B00011CD444F1C9F8D825B8F7CD5B187E257D8
-:1081C00005719D94EF5FD32C308CBBCED3723FD919
-:1081D00029416B0EDDAB921DEDD47693FF52F59CD9
-:1081E000600E7CEFBB66E2459213CA7DF552FE88B5
-:1081F000393D7AF392203D6BE37957F827ECC72994
-:10820000E777931D1260172DC57B6C6C97BEA5F7A1
-:108210004D9CE0E08E10AE9D7755D9D1B21EF3B5DE
-:108220007E68FE55E124F9DE3A9BBF4752FCF89286
-:108230007D0760BDC12D5AB2536E9F60BF6D521E47
-:10824000E619D828EE72B4534F7ED6275BAF0F8A5B
-:10825000BB144AD751DC63855A20FD7DC46A9F3B1D
-:1082600009E87246F1BD146F99116F243E56E8F08B
-:10827000496BC94F70DE15E3F977980AB5ECE7341E
-:108280009F9CCFA5E0A9B05E70E3F72C16330BBD21
-:108290003FB008C0877151E5FB1F8B18CFAF50E886
-:1082A0006AC55681E88ABEBC10F0BD8445F83D1011
-:1082B000D07FF76AB9FD9B28F27BF2C44D3C8FE278
-:1082C0003E66A7FC9165487D12E9D7D77CD06E0F3A
-:1082D000BF2E89DBF7E6389C7FF17135E50717C6BD
-:1082E000DD9E6E273D5F40F91382F76EE9FB1BAF01
-:1082F000263F83F3278EAAB9DC0178929FD585F4B7
-:108300004AF11E3B95C7EBCAA99C22BF1F16FA5E15
-:10831000437FE7CB2D38BEB0C66041F85FF13DC06A
-:10832000B0ABBFFFE694F3EB12C59E5C33C2E36BC8
-:108330008305E15118D749EF89A5CAF33F9C5BB289
-:1083400009F1698B602E5C1FEF69B6007C8BF040F1
-:1083500002C6D13D367CCF66A05330513EF56572E2
-:1083600074EB3ACC53A949134C18AF2D0ADB5218C1
-:108370000BF317A524D377766ADA781CB60F4A4E2A
-:108380000753DC92C0C7AA62317ECFF1E8CBB53F7C
-:108390003D29CFDF3E5BE6B3FE8E2F781EF1B5E3BD
-:1083A000B4BBE9FB1C4C4FEFAFD30FF635FBC6D186
-:1083B00014AF55E868B039AE09E9A845D613A5A5AC
-:1083C000EFA9D18E68CCB337231CCA965C5C174BDF
-:1083D000E71C3E4EA6E4DF87C6C902E5EDFF46DE98
-:1083E000FD89BA5A2ADFAD5B4565779D8B9E07E80C
-:1083F0008B2308BF1F106F7D7BD230F156A6334709
-:1084000092BE05BEE7F1ED90F82AF0BB18C0EF333D
-:108410003AA2EED980F64883C682F7CD98FFBCD247
-:1084200040F2E1FD49C3C65915F819282E3BC8F49E
-:10843000398887E919A92A119EFF6D921014E74423
-:10844000BEC17322DF60897CA352F9F9E6690DA3EE
-:10845000EF94A17DE022FB404FF85DBF06E40AD413
-:10846000EF65A620B9722144AE8023F3337A5FAC66
-:1084700043CB3609FEFCCFE9505CCA1946CE78B82A
-:108480009C191DE6799EBEB3501D46F9C5C0EF4448
-:10849000674737F2BCBD25AC84D61D46DED07B3E97
-:1084A000F78E1838F914F4BFF76103D939EB139636
-:1084B000E6FF77E4CD9F2771783C81DF73505DED57
-:1084C0007B0E9B05BC8F5DB1906523BE95EF39C4D3
-:1084D000C118F27BFFF5EF398C983C12BFE7E00A38
-:1084E000FA9E43DC15BEE7306AB27161E0F71C46C4
-:1084F0004D1EB130F87B0EC685F89DB2FFC1EF3935
-:10850000A44FCEBBFC7B0E374E36FFA0EF39803D2B
-:108510009B89E34FE4D8C66399289F3BF4FDE5E3CC
-:10852000F23D6497682FC5B228C2A5A276D16DC569
-:10853000F26DD1733FB6035F4C4478153D967D03D1
-:108540007E972551EBA1BCF227ADB64938FF6BB938
-:10855000B6C9F83C34DE5F2F9F0FF6730BF60BCDD8
-:108560001F53E8E2AEC95C0ECD93CBA9F5C3BFC7DC
-:108570003F6F32BF4FBED6BE61BF77E07ACAFED929
-:1085800096C556DC0FECF74EDC27ECB7044B66883B
-:108590000E7A0FF8727A75C9FB62742E908FB33F12
-:1085A000E1F62895E92A7714DA0DA31E7047E17EDB
-:1085B00047350EE8F17D90DFBA06F4683FFC76F5AA
-:1085C000801EDB7F6BE3F9DAA1F36F9FCCFD91F4A2
-:1085D000A903347E0CFCDD4DFEC14014DA6DE9E5E3
-:1085E0004734AE147A4F6DF62741769399F87B8C19
-:1085F000DC36E60191213D8CD9C1781E63410CE93E
-:10860000B94A1DEF5AF9C0FD22D2D13837EC3B8070
-:10861000FEAEDFAE1A0C7EAFD74BE3AAE425C05EF8
-:108620000B7AEE643CBF74942C8FD05EC4EFD939C2
-:10863000CB8FD077A6C08E0B998FBE7930944F59CF
-:10864000ADB3BFE63353BE6250BFA577FF663DFAB8
-:10865000B5E5A55B35E4172F69598FA5C3F19E26B3
-:108660008E917D19D41FECCBA0FA65FB0CD947F590
-:10867000FD17D7C70DB32ED0C156A413850E8EAAF1
-:108680003DE3D04F3DEA0CB3F0F71D3CF45D9A2674
-:10869000F9BDF45DFF39DDCAF365395DC0F81D3FF2
-:1086A0008C8EEAA9BFF21DAF6B958A1C1CFACE8D89
-:1086B00086B9285E39CB4872AE46F6FFAA9798C8AD
-:1086C0001E51F8BA5AE539B51EFBC51879FE9B8ACA
-:1086D000D1F7AB7AC45194CF4D3FACCF4AA5FBAC98
-:1086E000D87A8F17E71DB85DA0EFB9158473B95A12
-:1086F0002896389E85E74744FE5D81A7517E4898BD
-:1087000047C1BF37302597BF3F10CFF877DB98CAF6
-:108710001CF29D36391E7AEDEFB4F1EF92CDE7F7FA
-:10872000720D5125A5CBF1F9821BE8F9C1EF521F5B
-:10873000B1E2FE2A94EFB4717BBF614E063D7F55D6
-:1087400030AF413DE17A805DE93B6D7AE4FB80EF3B
-:10875000B3BD87F8BAD6F7D994EF0F1C5D70C32369
-:108760007B391CBD78EF5533CB18E4AFFF17313C94
-:108770009ED2C05600000000000000000000000073
-:088780000408350000000000B0
-:00000001FF
diff --git a/firmware/bnx2x-e1-5.0.21.0.fw.ihex b/firmware/bnx2x-e1-5.0.21.0.fw.ihex
new file mode 100644
index 0000000..c51afd4
--- /dev/null
+++ b/firmware/bnx2x-e1-5.0.21.0.fw.ihex
@@ -0,0 +1,10184 @@
+:10000000000028B0000000600000068800002918E9
+:100010000000161400002FA800000098000045C042
+:100020000000738800004660000000CC0000B9F0BA
+:1000300000009A4C0000BAC0000000940001551066
+:10004000000057B8000155A8000000B80001AD68D5
+:100050000000CE1C0001AE280000000400027C4815
+:10006000020400480000000F020400540000004594
+:1000700002040058000000840204005C0000000636
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000060400CC0000000418
+:10010000020400DC00100000020400E012140000F1
+:10011000020400E422140000020400E8321400008B
+:10012000060400EC000000040104012400000000AB
+:1001300001040128000000000104012C000000005F
+:10014000010401300000000002040004000000FF70
+:1001500002040008000000FF0204000C000000FF81
+:1001600002040010000000FF02040014000000FF61
+:1001700002040018000000FF0204001C000000FF41
+:1001800002040020000000FF020400240000003EE2
+:1001900002040028000000000204002C0000003FC0
+:1001A000020400300000003F020400340000003F61
+:1001B00002040038000000000204003C0000003F80
+:1001C000020400400000003F020400440000003F21
+:1001D00002042008000004110204200C00000400A6
+:1001E000020420100000040402042014000004197A
+:1001F0000204201C0000FFFF020420200000FFFF7B
+:10020000020420240000FFFF020420280000FFFF5A
+:1002100006042038000000020204204000000034E0
+:100220000204204400000035060420480000007C41
+:100230000204223807FFFFFF0204223C0000003FB7
+:100240000204224007FFFFFF020422440000000FC7
+:1002500001042248000000000104224C00000000BC
+:10026000010422500000000001042254000000009C
+:1002700001042258000000000104225C000000007C
+:10028000010422600000000001042264000000005C
+:1002900001042268000000000104226C000000003C
+:1002A000010422700000000001042274000000001C
+:1002B00001042278000000000104227C00000000FC
+:1002C000020424BC000000010C042000000003E82C
+:1002D0000A042000000000010B0420000000000AB6
+:1002E0000205004400000020020500480000003222
+:1002F000020500900215002002050094021500205E
+:1003000002050098000000300205009C0810000063
+:10031000020500A000000033020500A40000003028
+:10032000020500A800000031020500AC0000000238
+:10033000020500B000000005020500B40000000640
+:10034000020500B800000002020500BC0000000227
+:10035000020500C000000000020500C40000000506
+:10036000020500C800000002020500CC00000002E7
+:10037000020500D000000002020500D400000001C8
+:1003800002050114000000010205011C000000012B
+:100390000205012000000002020502040000000125
+:1003A0000205020C0000004002050210000000409F
+:1003B0000205021C000000200205022000000013BC
+:1003C0000205022400000020060502400000000A89
+:1003D0000405028000200000020500500000000714
+:1003E0000205005400000007020500580000000844
+:1003F0000205005C00000008060500600000000423
+:10040000020500D800000006020500E00000000D13
+:10041000020500E40000002D020500E800000007CE
+:10042000020500EC00000027020500F000000007B4
+:10043000020500F400000027020500F80000000794
+:10044000020500FC00000027020500040000000176
+:1004500002050008000000010205000C0000000178
+:100460000205001000000001020500140000000158
+:1004700002050018000000010205001C0000000138
+:100480000205002000000001020500240000000118
+:1004900002050028000000010205002C00000001F8
+:1004A00002050030000000010205003400000001D8
+:1004B00002050038000000010205003C00000001B8
+:1004C00002050040000000010406100002000020A8
+:1004D000020600DC00000001010600D80000000058
+:1004E0000406020000030220020600DC00000000F7
+:1004F00002060068000000B802060078000001143F
+:10050000010600B800000000010600C8000000005D
+:100510000206006C000000B80206007C0000011416
+:10052000010600BC00000000010600CC0000000035
+:100530000718040000960000081807600014022342
+:10054000071C000034B80000071C800034E90D2FA0
+:10055000071D000009DD1A6A081D14005D800225D0
+:100560000118000000000000011800040000000055
+:1005700001180008000000000118000C0000000035
+:100580000118001000000000011800140000000015
+:1005900002180020000000010218002400000002E0
+:1005A00002180028000000030218002C00000000C0
+:1005B000021800300000000402180034000000019E
+:1005C00002180038000000000218003C0000000182
+:1005D000021800400000000402180044000000005F
+:1005E00002180048000000010218004C000000033F
+:1005F0000218005000000000021800540000000122
+:1006000002180058000000040218005C00000000FE
+:1006100002180060000000010218006400000003DE
+:1006200002180068000000000218006C00000001C1
+:10063000021800700000000402180074000000009E
+:1006400002180078000000040218007C000000037B
+:100650000618008000000002021800A400003FFFFE
+:10066000021800A8000003FF021802240000000086
+:1006700002180234000000000218024C00000000C2
+:10068000021802E4000000FF061810000000040039
+:10069000021B8BC000000001021B80000000003420
+:1006A000021B804000000018021B80800000000C2C
+:1006B000021B80C0000000200C1B83000007A1204B
+:1006C0000A1B8300000001380B1B83000000138805
+:1006D000021B83C0000001F4061A2000000000B2D3
+:1006E000061A23C800000181041A29CC0001022740
+:1006F000061A1020000000C8061A100000000002B0
+:10070000061A1E3800000002061A1E300000000201
+:10071000061A080000000002061A0808000000027D
+:10072000061A081000000004041A1FB00005022871
+:10073000041A4CB00008022D061A22C8000000203E
+:10074000061A400000000124021A4920000000009F
+:10075000061A14000000000A061A145000000006D1
+:10076000061A150000000002041A150800050235DB
+:10077000061A151C00000009061A15800000001456
+:10078000061A09C000000048061A0800000000020E
+:10079000061A08200000000E041A1FB00002023AD8
+:1007A000061A2C2800000002061A23480000002028
+:1007B000061A449000000124021A49240000000097
+:1007C000061A14280000000A061A14680000000621
+:1007D000061A154000000002041A15480005023CE4
+:1007E000061A155C00000009061A15D00000001456
+:1007F000061A0AE000000048061A08080000000275
+:10080000061A08580000000E041A1FB80002024120
+:10081000061A2C30000000020200A2800000000135
+:100820000200A294071D29110200A29800000000F6
+:100830000200A29C009C04240200A2A00000000070
+:100840000200A2A4000002090200A4FCFF000000B4
+:10085000020100B400000001020100B80000000124
+:10086000020100DC000000010201010000000001A3
+:1008700002010104000000010201007C00300000C0
+:1008800002010084000000280201008C000000002A
+:1008900002010130000000040201025C00000001BE
+:1008A000020103280000000002010554000000308E
+:1008B000020100C400000001020100CC00000001A0
+:1008C000020100F800000001020100F00000000138
+:1008D00002010080003000000201008800000028B2
+:1008E0000201009000000000020101340000000439
+:1008F000020102DC000000010201032C00000000E4
+:100900000201056400000030020100C8000000017F
+:10091000020100D000000001020100FC0000000103
+:10092000020100F400000001020C10000000002091
+:10093000020C200800000A11020C200C00000A0022
+:10094000020C201000000A04020C201C0000FFFF13
+:10095000020C20200000FFFF020C20240000FFFFFB
+:10096000020C20280000FFFF060C203800000002C7
+:10097000020C204000000034020C2044000000352E
+:10098000020C204800000020020C204C0000002136
+:10099000020C205000000022020C20540000002312
+:1009A000020C205800000024020C205C00000025EE
+:1009B000020C206000000026020C206400000027CA
+:1009C000020C206800000028020C206C00000029A6
+:1009D000020C20700000002A020C20740000002B82
+:1009E000060C207800000056020C21D00000000107
+:1009F000020C21D400000001020C21D800000001EB
+:100A0000020C21DC00000001020C21E000000001CA
+:100A1000020C21E400000001020C21E800000001AA
+:100A2000020C21EC00000001020C21F0000000018A
+:100A3000020C21F400000001060C21F80000001057
+:100A4000020C223807FFFFFF020C223C0000003F8F
+:100A5000020C224007FFFFFF020C22440000000F9F
+:100A6000010C224800000000010C224C0000000094
+:100A7000010C225000000000010C22540000000074
+:100A8000010C225800000000010C225C0000000054
+:100A9000010C226000000000010C22640000000034
+:100AA000010C226800000000010C226C0000000014
+:100AB000010C227000000000010C227400000000F4
+:100AC000010C227800000000010C227C00000000D4
+:100AD000020C24BC000000010C0C2000000003E804
+:100AE0000A0C2000000000010B0C20000000000A8E
+:100AF000020C400800000365020C400C0000035487
+:100B0000020C401000000358020C40140000037552
+:100B1000020C401C0000FFFF020C40200000FFFF01
+:100B2000020C40240000FFFF020C40280000FFFFE1
+:100B3000020C403800000046020C403C000000055A
+:100B4000060C40400000005E020C41B800000001AD
+:100B5000060C41BC0000001F020C423807FFFFFFDB
+:100B6000020C423C0000003F020C424007FFFFFF26
+:100B7000020C42440000000F010C4248000000003B
+:100B8000010C424C00000000010C4250000000002B
+:100B9000010C425400000000010C4258000000000B
+:100BA000010C425C00000000010C426000000000EB
+:100BB000010C426400000000010C426800000000CB
+:100BC000010C426C00000000010C427000000000AB
+:100BD000010C427400000000010C4278000000008B
+:100BE000010C427C00000000010C4280000000006B
+:100BF000020C44C0000000010C0C4000000003E89F
+:100C00000A0C4000000000010B0C40000000000A2C
+:100C1000020D004400000032020D008C021500207D
+:100C2000020D009002150020020D00940810000033
+:100C3000020D009800000033020D009C000000022D
+:100C4000020D00A000000000020D00A4000000053D
+:100C5000020D00A800000005060D00AC0000000217
+:100C6000020D00B400000002020D00B800000003F5
+:100C7000020D00BC00000002020D00C000000001D7
+:100C8000020D00C800000002020D00CC00000002AE
+:100C9000020D010800000001020D015C00000001CE
+:100CA000020D016400000001020D01680000000255
+:100CB000020D020400000001020D020C00000020E1
+:100CC000020D021000000040020D0214000000405E
+:100CD000020D022000000003020D02240000001893
+:100CE000060D028000000012040D030000240243E0
+:100CF000020D004C00000001020D00500000000237
+:100D0000020D005400000008020D00580000000809
+:100D1000060D005C00000004020D00C40000000489
+:100D2000020D011400000009020D01180000002945
+:100D3000020D011C0000000A020D01200000002A23
+:100D4000020D012400000007020D01280000002709
+:100D5000020D012C00000007020D013000000027E9
+:100D6000020D01340000000C020D01380000002CBF
+:100D7000020D013C0000000C020D01400000002C9F
+:100D8000020D01440000000C020D01480000002C7F
+:100D9000020D000400000001020D00080000000127
+:100DA000020D000C00000001020D00100000000107
+:100DB000020D001400000001020D001800000001E7
+:100DC000020D001C00000001020D002000000001C7
+:100DD000020D002400000001020D002800000001A7
+:100DE000020D002C00000001020D00300000000187
+:100DF000020D003400000001020D00380000000167
+:100E0000020D003C00000001020E004C0000003208
+:100E1000020E009402150020020E00980215002018
+:100E2000020E009C00000030020E00A0081000001E
+:100E3000020E00A400000033020E00A800000030E3
+:100E4000020E00AC00000031020E00B000000002F3
+:100E5000020E00B400000004020E00B80000000002
+:100E6000020E00BC00000002020E00C000000002E2
+:100E7000020E00C400000000020E00C800000002C4
+:100E8000020E00CC00000007020E00D0000000029D
+:100E9000020E00D400000002020E00D80000000183
+:100EA000020E00E400000001020E014400000001F7
+:100EB000020E014C00000001020E01500000000271
+:100EC000020E020400000001020E020C00000040AD
+:100ED000020E021000000040020E021C000000047E
+:100EE000020E022000000020020E02240000000E6C
+:100EF000020E02280000001B060E03000000001274
+:100F0000040E0280001B0267020E00540000000C59
+:100F1000020E005800000007020E005C0000000FE7
+:100F2000020E006000000010060E006400000004C5
+:100F3000020E00DC00000003020E01100000000F92
+:100F4000020E01140000002F020E01180000000E16
+:100F5000020E011C0000002E020E00040000000121
+:100F6000020E000800000001020E000C000000014B
+:100F7000020E001000000001020E0014000000012B
+:100F8000020E001800000001020E001C000000010B
+:100F9000020E002000000001020E002400000001EB
+:100FA000020E002800000001020E002C00000001CB
+:100FB000020E003000000001020E003400000001AB
+:100FC000020E003800000001020E003C000000018B
+:100FD000020E004000000001020E0044000000016B
+:100FE0000730040000C900000830076800130282BF
+:100FF00007340000341200000734800037B70D05B5
+:10100000073500002E7D1AF308356F405218028410
+:10101000013000000000000001300004000000006A
+:1010200001300008000000000130000C000000004A
+:10103000013000100000000001300014000000002A
+:1010400002300020000000010230002400000002F5
+:1010500002300028000000030230002C00000000D5
+:1010600002300030000000040230003400000001B3
+:1010700002300038000000000230003C0000000197
+:101080000230004000000004023000440000000074
+:1010900002300048000000010230004C0000000354
+:1010A0000230005000000000023000540000000137
+:1010B00002300058000000040230005C0000000014
+:1010C00002300060000000010230006400000003F4
+:1010D00002300068000000000230006C00000001D7
+:1010E00002300070000000040230007400000000B4
+:1010F00002300078000000040230007C0000000391
+:101100000630008000000002023000A400003FFF13
+:10111000023000A8000003FF02300224000000009B
+:1011200002300234000000000230024C00000000D7
+:10113000023002E40000FFFF06302000000008003B
+:1011400002338BC000000001023380000000001A4F
+:10115000023380400000004E023380800000001007
+:10116000023380C0000000200C3383000007A12060
+:101170000A338300000001380B338300000013881A
+:10118000023383C0000001F40C3383801DCD650061
+:101190000A3383800004C4B40B338380004C4B407B
+:1011A00006321AA0000000C206321020000000C85B
+:1011B0000632100000000002063214000000004059
+:1011C00006325098000000040632508000000005EE
+:1011D00004325094000102860632500000000020C4
+:1011E00004322830000202870233080001000000A8
+:1011F00004330C00001002890233080000000000D4
+:1012000004330C400010029906321500000000B4AF
+:1012100002321DC80000000006324000000000D865
+:10122000063217D0000000B402321DCC00000000CE
+:1012300006324360000000D807200400009200003E
+:1012400008200780001002A9072400002CCF00000E
+:10125000072480002AE50B340824DC6062DA02AB44
+:101260000120000000000000012000040000000038
+:1012700001200008000000000120000C0000000018
+:1012800001200010000000000120001400000000F8
+:1012900002200020000000010220002400000002C3
+:1012A00002200028000000030220002C00000000A3
+:1012B0000220003000000004022000340000000181
+:1012C00002200038000000000220003C0000000165
+:1012D0000220004000000004022000440000000042
+:1012E00002200048000000010220004C0000000322
+:1012F0000220005000000000022000540000000105
+:1013000002200058000000040220005C00000000E1
+:1013100002200060000000010220006400000003C1
+:1013200002200068000000000220006C00000001A4
+:101330000220007000000004022000740000000081
+:1013400002200078000000040220007C000000035E
+:101350000620008000000002022000A400003FFFE1
+:10136000022000A8000003FF022002240000000069
+:1013700002200234000000000220024C00000000A5
+:10138000022002E40000FFFF062020000000080009
+:1013900002238BC000000001022380000000001027
+:1013A00002238040000000120223808000000030F1
+:1013B000022380C00000000E022383C0000001F45D
+:1013C000062250000000004206221020000000C843
+:1013D000062210000000000206222000000000C0CB
+:1013E000062225C00000024004222EC8000802ADDB
+:1013F00002230800013FFFFF04230C00001002B588
+:10140000022308000000000004230C40001002C565
+:1014100006223040000000A00622354000000010E7
+:10142000062236C000000030062240000000020004
+:10143000062235C00000002006223840000000309F
+:1014400006223000000000080222511800000000AF
+:10145000062223000000000E0622241000000030A7
+:10146000062232C0000000A00622358000000010D5
+:1014700006223780000000300622480000000200EB
+:10148000062236400000002006223900000000300D
+:1014900006223020000000080222511C000000003B
+:1014A000062223380000000E062224D0000000305F
+:1014B00002161000000000280217000800000002B9
+:1014C0000217002C000000030217003C000000047B
+:1014D0000217004400000008021700480000000244
+:1014E0000217004C0000009002170050000000900E
+:1014F00002170054008000900217005808140000E2
+:10150000021700600000008A0217006400000080DB
+:1015100002170068000000810217006C00000080C4
+:10152000021700700000000602170078000007D0C4
+:101530000217007C0000076C02170038007C1004C2
+:10154000021700040000000F0616402400000002ED
+:10155000021640700000001C021642080000000144
+:101560000216421000000001021642200000000195
+:10157000021642280000000102164230000000015D
+:10158000021642380000000102164260000000010D
+:101590000C16401C0003D0900A16401C0000009C52
+:1015A0000B16401C000009C4021640300000000861
+:1015B000021640340000000C0216403800000010F3
+:1015C0000216404400000020021640000000000106
+:1015D000021640D800000001021640080000000179
+:1015E0000216400C0000000102164010000000012D
+:1015F00002164240000000000216424800000000AF
+:101600000616427000000002021642500000000060
+:101610000216425800000000061642800000000238
+:1016200002166008000006140216600C0000060096
+:1016300002166010000006040216601C0000FFFF86
+:10164000021660200000FFFF021660240000FFFF6A
+:10165000021660280000FFFF02166038000000201C
+:101660000216603C000000200216604000000034BA
+:101670000216604400000035021660480000002396
+:101680000216604C00000024021660500000002585
+:101690000216605400000026021660580000002761
+:1016A0000216605C00000029021660600000002A3B
+:1016B000021660640000002B021660680000002C17
+:1016C0000216606C0000002D0616607000000052CB
+:1016D000021661B800000001061661BC0000001F80
+:1016E0000216623807FFFFFF0216623C0000003F4F
+:1016F0000216624007FFFFFF021662440000000F5F
+:1017000001166248000000000116624C0000000053
+:101710000116625000000000011662540000000033
+:1017200001166258000000000116625C0000000013
+:1017300001166260000000000116626400000000F3
+:1017400001166268000000000116626C00000000D3
+:1017500001166270000000000116627400000000B3
+:1017600001166278000000000116627C0000000093
+:10177000021664BC000000010C166000000003E8C3
+:101780000A166000000000010B1660000000000A4D
+:10179000021680400000000602168044000000058A
+:1017A000021680480000000A0216804C0000000566
+:1017B0000216805400000002021680CC00000004D3
+:1017C000021680D000000004021680D4000000043D
+:1017D000021680D800000004021680DC000000041D
+:1017E000021680E000000004021680E400000004FD
+:1017F000021680E8000000040216880400000004BD
+:10180000021680300000007C021680340000003D8B
+:10181000021680380000003F0216803C0000009C49
+:10182000021680F000000007061680F40000000594
+:101830000216880C01010101021681080000000057
+:101840000216810C00000004021681100000000442
+:1018500002168114000000020216881008012004FC
+:1018600002168118000000050216811C0000000508
+:1018700002168120000000050216812400000005E8
+:101880000216882C2008100102168128000000088A
+:101890000216812C000000060216813000000007AD
+:1018A0000216813400000000021688300101012078
+:1018B0000616813800000004021688340101010177
+:1018C0000616814800000004021688380101010153
+:1018D00006168158000000040216883C010101012F
+:1018E00006168168000000030216817400000001E2
+:1018F00002168840010101010216817800000001F2
+:101900000216817C000000010216818000000001A7
+:1019100002168184000000010216884401010101C1
+:1019200002168188000000010216818C000000046C
+:10193000021681900000000402168194000000024B
+:10194000021688480801200402168198000000054C
+:101950000216819C00000005021681A0000000050F
+:10196000021681A400000005021688142008100148
+:10197000021681A800000008021681AC00000006D3
+:10198000021681B000000007021681B400000001B9
+:101990000216881801010120021681B8000000011A
+:1019A000021681BC00000001021681C00000000187
+:1019B000021681C4000000010216881C0101010109
+:1019C000021681C800000001021681CC000000014F
+:1019D000021681D000000001021681D4000000012F
+:1019E0000216882001010101021681D800000001C1
+:1019F000021681DC00000001021681E000000001F7
+:101A0000021681E400000001021688240101010190
+:101A1000021681E800000001021681EC00000001BE
+:101A2000021681F000000001021688280101010160
+:101A300002168240FFFF003F0616824400000002AB
+:101A40000216824CFFFF003F021682500000010088
+:101A5000021682540000010006168258000000029F
+:101A600002168260000000C002168264000000C0FE
+:101A70000216826800001E000216826C00001E0022
+:101A800002168270000040000216827400004000BE
+:101A900002168278000080000216827C000080001E
+:101AA00002168280000020000216828400002000BE
+:101AB0000616828800000007021682A400000001BA
+:101AC000061682A80000000A021681F400000C0825
+:101AD000021681F800000040021681FC000001009F
+:101AE0000216820000000020021682040000001787
+:101AF00002168208000000800216820C000002001C
+:101B0000021682100000000002168218FFFF01FF7B
+:101B100002168214FFFF01FF0216823C0000001330
+:101B2000021680900000013F021680600000014014
+:101B30000216806400000140061680680000000262
+:101B400002168070000000C00616807400000007B6
+:101B50000216809C00000048021680A00000004889
+:101B6000061680A400000002021680AC00000048A7
+:101B7000061680B0000000070216823800008000C0
+:101B800002168234000025E40216809400007FFFD4
+:101B900002168220000000070216821C00000007C7
+:101BA000021682280000000002168224FFFFFFFFB9
+:101BB00002168230000000000216822CFFFFFFFF99
+:101BC000021680EC000000FF02140000000000017B
+:101BD0000214000C0000000102140040000000018B
+:101BE0000214004400007FFF0214000C00000000FB
+:101BF00002140000000000000214006C000000004D
+:101C00000214000400000001021400300000000172
+:101C100002140004000000000214005C0000000038
+:101C2000021400080000000102140034000000014A
+:101C30000214000800000000021400600000000010
+:101C40000202005800000032020200A0031500202A
+:101C5000020200A403150020020200A801000030C7
+:101C6000020200AC08100000020200B000000033C5
+:101C7000020200B400000030020200B8000000318F
+:101C8000020200BC00000003020200C000000006C7
+:101C9000020200C400000003020200C800000003AA
+:101CA000020200CC00000002020200D0000000008E
+:101CB000020200D400000002020200DC000000006A
+:101CC000020200E000000006020200E4000000043E
+:101CD000020200E800000002020200EC0000000224
+:101CE000020200F000000001020200FC00000006F9
+:101CF0000202012000000000020201340000000284
+:101D0000020201B0000000010202020C000000010A
+:101D10000202021400000001020202180000000288
+:101D200002020404000000010202040C0000004052
+:101D300002020410000000400202041C0000000423
+:101D4000020204200000002002020424000000021D
+:101D5000020204280000001F060205000000001215
+:101D600004020480001F02D5020200600000000F80
+:101D70000202006400000007020200680000000B7D
+:101D80000202006C0000000E060200700000000459
+:101D9000020200F40000000402020004000000013E
+:101DA00002020008000000010202000C0000000115
+:101DB00002020010000000010202001400000001F5
+:101DC00002020018000000010202001C00000001D5
+:101DD00002020020000000010202002400000001B5
+:101DE00002020028000000010202002C0000000195
+:101DF0000202003000000001020200340000000175
+:101E000002020038000000010202003C0000000154
+:101E10000202004000000001020200440000000134
+:101E200002020048000000010202004C0000000114
+:101E3000020200500000000102020108000000C878
+:101E40000202011800000002020201C400000000AA
+:101E5000020201CC00000000020201D400000002D6
+:101E6000020201DC00000002020201E4000000FFA7
+:101E7000020201EC000000FF0202010C000000C899
+:101E80000202011C00000002020201C80000000062
+:101E9000020201D000000000020201D8000000028E
+:101EA000020201E000000002020201E8000000FF5F
+:101EB000020201F0000000FF0728040000B4000047
+:101EC00008280768001302F4072C000035D700002B
+:101ED000072C80003A590D76072D00003B741C0D2D
+:101EE000072D8000226C2AEB082DC6F0472202F64F
+:101EF000012800000000000001280004000000008C
+:101F000001280008000000000128000C000000006B
+:101F1000012800100000000001280014000000004B
+:101F20000228002000000001022800240000000216
+:101F300002280028000000030228002C00000000F6
+:101F400002280030000000040228003400000001D4
+:101F500002280038000000000228003C00000001B8
+:101F60000228004000000004022800440000000095
+:101F700002280048000000010228004C0000000375
+:101F80000228005000000000022800540000000158
+:101F900002280058000000040228005C0000000035
+:101FA0000228006000000001022800640000000315
+:101FB00002280068000000000228006C00000001F8
+:101FC00002280070000000040228007400000000D5
+:101FD00002280078000000040228007C00000003B2
+:101FE0000628008000000002022800A400003FFF35
+:101FF000022800A8000003FF0228022400000000BD
+:1020000002280234000000000228024C00000000F8
+:10201000022802E40000FFFF06282000000008005C
+:10202000022B8BC000000001022B8000000000008A
+:10203000022B804000000018022B80800000000C62
+:10204000022B80C0000000660C2B83000007A1203B
+:102050000A2B8300000001380B2B8300000013883B
+:10206000022B83C0000001F40C2B8340000001F41C
+:102070000A2B8340000000000B2B8340000000056A
+:102080000A2B83800004C4B40C2B83801DCD650013
+:102090000B2B8380004C4B40062A3C400000000480
+:1020A000042A3C50000202F8062A300000000048D2
+:1020B000062A1020000000C8062A100000000002B6
+:1020C000062A31280000008E022A33680000000032
+:1020D000042A3370000202FA042A3A70000402FC57
+:1020E000042A3D0000020300042A15000002030236
+:1020F000062A150800000100022A197000000000DD
+:10210000022A197800000000042A19600002030462
+:10211000062A4AC000000002062A4B000000000404
+:10212000042A1F4800020306022B080000000000DA
+:10213000042B0C0000100308022B08000100000013
+:10214000042B0C4000080318022B080002000000BA
+:10215000042B0C6000080320062A3A8000000014BB
+:10216000062A3B2000000024062A14000000000A72
+:10217000062A145000000006062A3378000000D812
+:10218000022A3A3800000000042A3C5800020328C2
+:10219000042A3C680010032A062A5020000000028E
+:1021A000062A503000000002062A500000000002FB
+:1021B000062A501000000002022A504000000000D1
+:1021C000062A50480000000E022A50B80000000104
+:1021D000042A4AC80002033A062A4B1000000042B3
+:1021E000062A4D2000000004062A3AD00000001400
+:1021F000062A3BB000000024062A14280000000A2A
+:10220000062A146800000006062A36D8000000D806
+:10221000022A3A3C00000000042A3C600002033C11
+:10222000042A3CA80010033E062A502800000002A1
+:10223000062A503800000002062A5008000000025A
+:10224000062A501800000002022A50440000000034
+:10225000062A50800000000E022A50BC0000000137
+:10226000042A4AD00002034E062A4C1800000042FD
+:10227000062A4D3000000004021010080000000182
+:102280000210101000000264021010000003D000C1
+:10229000021010040000003D091018000200035055
+:1022A00009101100002005500610118000000002E6
+:1022B0000910118800060570061011A00000001812
+:1022C000021010100000000006102400000000E0C2
+:1022D0000210201C0000000002102020000000015D
+:1022E000021020C0000000010210200400000001C4
+:1022F000021020080000000109103C0000050576CE
+:1023000009103C200005057B0910380000050580F8
+:1023100002104028000000100210404400003FFF5F
+:102320000210405800280000021040840084924AA5
+:1023300002104058000000000610806800000004F1
+:1023400002108000000010800610802800000002AB
+:102350000210803800000010021080400000FFFFD3
+:10236000021080440000FFFF0210805000000000B7
+:102370000210810000000000061081200000000211
+:1023800002108008000002B502108010000000005A
+:10239000061082000000004A021081080001FFFFC1
+:1023A00006108140000000020210800000001A8028
+:1023B0000610900000000024061091200000004A42
+:1023C000061093700000004A061095C00000004AF5
+:1023D000021080040000108006108030000000020F
+:1023E0000210803C00000010021080480000FFFF37
+:1023F0000210804C0000FFFF02108054000000001B
+:102400000210810400000000061081280000000274
+:102410000210800C000002B50210801400000000C1
+:10242000061084000000004A0210810C0001FFFF2A
+:1024300006108148000000020210800400001A808B
+:102440000610909000000024061092480000004AF8
+:10245000061094980000004A061096E80000004A12
+:102460000212049000E383400212051400003C10A5
+:10247000021205200000000202120494FFFFFFFF79
+:1024800002120498FFFFFFFF0212049CFFFFFFFFF0
+:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0
+:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0
+:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C
+:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68
+:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48
+:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28
+:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8
+:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7
+:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7
+:10252000021204F4FFFFFFFF021204F8FFFFFFFF97
+:10253000021204FCFFFFFFFF02120500FFFFFFFF76
+:1025400002120504FFFFFFFF02120508FFFFFFFF55
+:102550000212050CFFFFFFFF02120510FFFFFFFF35
+:10256000021204D4FFFF3330021204D8FFFF3340BD
+:10257000021204B4F00030000212039000000008C0
+:102580000212039C00000008061203A000000002D3
+:10259000021203BC00000004021203C40000000485
+:1025A000021203D000000000021203DC0000000051
+:1025B0000212036C00000001021203680000003FD9
+:1025C000021201BC00000040021201C00000180805
+:1025D000021201C400000803021201C8000008032F
+:1025E000021201CC00000040021201D000000003E2
+:1025F000021201D400000803021201D800000803EF
+:10260000021201DC00000803021201E000010003D5
+:10261000021201E400000803021201E800000803AE
+:10262000021201EC00000003021201F0000000039E
+:10263000021201F400000003021201F8000000037E
+:10264000021201FC0000000302120200000000035D
+:10265000021202040000000302120208000000033C
+:102660000212020C0000000302120210000000031C
+:1026700002120214000000030212021800000003FC
+:102680000212021C000000030212022000000003DC
+:102690000212022400000003021202280000240398
+:1026A0000212022C0000002F02120230000000096A
+:1026B00002120234000000190212023800000184E4
+:1026C0000212023C000001830212024000000306D5
+:1026D0000212024400000019021202480000000623
+:1026E0000212024C00000306021202500000030610
+:1026F00002120254000003060212025800000C8667
+:102700000212025C000003060212026000000306CF
+:1027100002120264000000060212026800000006B5
+:102720000212026C00000006021202700000000695
+:102730000212027400000006021202780000000675
+:102740000212027C00000006021202800000000655
+:102750000212028400000006021202880000000635
+:102760000212028C00000006021202900000000615
+:1027700002120294000000060212029800000006F5
+:102780000212029C00000006021202A000000306D2
+:10279000021202A400000013021202A800000006A8
+:1027A000021202B000001004021202B40000100471
+:1027B0000212032400106440021203280010644037
+:1027C000021201B0000000010600A0000000001687
+:1027D0000200A06CBF5C00000200A070FFF51FEFBC
+:1027E0000200A0740000FFFF0200A078500003E088
+:1027F0000200A07C000000000200A0800000A000F9
+:102800000600A084000000050200A0980FE0000070
+:102810000600A09C000000140200A0EC555400002B
+:102820000200A0F0555555550200A0F40000555582
+:102830000200A0F8000000000200A0FC55540000B7
+:102840000200A100555555550200A1040000555540
+:102850000200A108000000000200A22C00000000FD
+:102860000600A230000000030200A0600000000784
+:102870000200A10CBF5C00000200A110FFF51FEFD9
+:102880000200A1140000FFFF0200A118500003E0A5
+:102890000200A11C000000000200A1200000A00016
+:1028A0000600A124000000050200A1380FE000008E
+:1028B0000600A13C000000140200A18C5554000049
+:1028C0000200A190555555550200A19400005555A0
+:1028D0000200A198000000000200A19C55540000D5
+:1028E0000200A1A0555555550200A1A40000555560
+:1028F0000200A1A8000000000200A23C00000000AD
+:102900000600A240000000030200A06400000007CF
+:1029100000000000000000000000002E0000000089
+:1029200000000000000000000000000000000000A7
+:102930000000000000000000000000000000000097
+:102940000000000000000000000000000000000087
+:102950000000000000000000000000000000000077
+:102960000000000000000000000000000000000067
+:10297000002E0050000000000000000000000000D9
+:102980000000000000000000000000000000000047
+:102990000000000000000000000000000050008D5A
+:1029A0000000000000000000000000000000000027
+:1029B0000000000000000000000000000000000017
+:1029C0000000000000000000008D009200920096C0
+:1029D0000096009A000000000000000000000000C7
+:1029E00000000000000000000000000000000000E7
+:1029F00000000000009A00DB00DB00E900E900F7BE
+:102A000000000000000000000000000000000000C6
+:102A100000000000000000000000000000000000B6
+:102A200000000000000000000000000000000000A6
+:102A30000000000000000000000000000000000096
+:102A40000000000000000000000000000000000086
+:102A50000000000000000000000000000000000076
+:102A60000000000000000000000000000000000066
+:102A70000000000000000000000000000000000056
+:102A80000000000000000000000000000000000046
+:102A90000000000000000000000000000000000036
+:102AA0000000000000000000000000000000000026
+:102AB0000000000000000000000000000000000016
+:102AC0000000000000000000000000000000000006
+:102AD00000F700FE00000000000000000000000001
+:102AE00000000000000000000000000000000000E6
+:102AF00000000000000000000000000000000000D6
+:102B000000000000000000000000000000000000C5
+:102B100000000000000000000000000000000000B5
+:102B2000000000000000000000FE01030103010E90
+:102B3000010E01190000000000000000000000006C
+:102B40000000000000000000000000000000000085
+:102B50000000000000000000000000000000000075
+:102B60000000000000000000000000000000000065
+:102B70000000000000000000000000000000000055
+:102B80000119011A00000000000000000000000010
+:102B90000000000000000000000000000000000035
+:102BA000000000000000000000000000011A0152B7
+:102BB0000000000000000000000000000000000015
+:102BC0000000000000000000000000000000000005
+:102BD000000000000000000001520176000000002B
+:102BE00000000000000000000000000000000000E5
+:102BF00000000000000000000000000000000000D5
+:102C000000000000017601B5000000000000000097
+:102C100000000000000000000000000000000000B4
+:102C200000000000000000000000000000000000A4
+:102C300001B501F0000000000000000000000000ED
+:102C40000000000000000000000000000000000084
+:102C500000000000000000000000000001F002354C
+:102C6000023502380238023B00000000000000007C
+:102C70000000000000000000000000000000000054
+:102C80000000000000000000023B02760276028095
+:102C90000280028A00000000000000000000000026
+:102CA0000000000000000000000000000000000024
+:102CB00000000000028A028B0000000000000000FB
+:102CC0000000000000000000000000000000000004
+:102CD00000000000000000000000000000000000F4
+:102CE000028B029D000000000000000000000000B8
+:102CF00000000000000000000000000000000000D4
+:102D0000000000000000000000000000029D02B270
+:102D100002B202B502B502B80000000000000000D7
+:102D200000000000000000000000000000000000A3
+:102D3000000000000000000002B802E600000000F1
+:102D40000000000000000000000000000000000083
+:102D50000000000000000000000000000000000073
+:102D60000000000002E6036D00000000000000000B
+:102D70000000000000000000000000000000000053
+:102D80000000000000000000000000000000000043
+:102D9000036D0374037403780378037C0000000060
+:102DA0000000000000000000000000000000000023
+:102DB000000000000000000000000000037C03BBD6
+:102DC00003BB03C303C303CB0000000000000000EB
+:102DD00000000000000000000000000000000000F3
+:102DE000000000000000000003CB041F041F04319A
+:102DF0000431044300000000000000000000000057
+:102E000000000000000000000000000000000000C2
+:102E1000000000000443044D00000000000000001A
+:102E200000000000000000000000000000000000A2
+:102E30000000000000000000000000000000000092
+:102E4000044D0453000000000000000000000000DA
+:102E50000000000000000000000000000000000072
+:102E600000000000000000000000000004530456B1
+:102E70000000000000000000000000000000000052
+:102E80000000000000000000000000000000000042
+:102E900000000000000000000456045B0000000079
+:102EA0000000000000000000000000000000000022
+:102EB0000000000000000000000000000000000012
+:102EC00000000000045B045C045C046E046E04807B
+:102ED00000000000000000000000000000000000F2
+:102EE00000000000000000000000000000000000E2
+:102EF000048004ED0000000000000000000000005D
+:102F000000000000000000000000000000000000C1
+:102F100000000000000000000000000004ED04EECE
+:102F200004EE050205020516000000000000000086
+:102F30000000000000000000000000000000000091
+:102F40000000000000000000000000000000000081
+:102F50000000000000000000000000000000000071
+:102F60000000000000000000000000000000000061
+:102F70000000000000000000000000000000000051
+:102F80000000000000000000000000000000000041
+:102F90000000000000000000000000000000000031
+:102FA000000000000000000000010000000204C05A
+:102FB0000003098000040E4000051300000617C03E
+:102FC00000071C800008214000092600000A2AC0D2
+:102FD000000B2F80000C3440000D3900000E3DC066
+:102FE000000F42800010474000114C00001250C0FA
+:102FF0000013558000145A4000155F00001663C08E
+:103000000017688000186D4000197200001A76C021
+:10301000001B7B80001C8040001D8500001E89C0B5
+:10302000001F8E8000209340000020000000400020
+:1030300000006000000080000000A0000000C00050
+:103040000000E0000001000000012000000140003D
+:1030500000016000000180000001A0000001C0002C
+:103060000001E00000020000000220000002400019
+:1030700000026000000280000002A0000002C00008
+:103080000002E000000300000003200000034000F5
+:1030900000036000000380000003A0000003C000E4
+:1030A0000003E000000400000004200000044000D1
+:1030B00000046000000480000004A0000004C000C0
+:1030C0000004E000000500000005200000054000AD
+:1030D00000056000000580000005A0000005C0009C
+:1030E0000005E00000060000000620000006400089
+:1030F00000066000000680000006A0000006C00078
+:103100000006E00000070000000720000007400064
+:1031100000076000000780000007A0000007C00053
+:103120000007E00000080000000820000008400040
+:1031300000086000000880000008A0000008C0002F
+:103140000008E0000009000000092000000940001C
+:1031500000096000000980000009A0000009C0000B
+:103160000009E000000A0000000A2000000A4000F8
+:10317000000A6000000A8000000AA000000AC000E7
+:10318000000AE000000B0000000B2000000B4000D4
+:10319000000B6000000B8000000BA000000BC000C3
+:1031A000000BE000000C0000000C2000000C4000B0
+:1031B000000C6000000C8000000CA000000CC0009F
+:1031C000000CE000000D0000000D2000000D40008C
+:1031D000000D6000000D8000000DA000000DC0007B
+:1031E000000DE000000E0000000E2000000E400068
+:1031F000000E6000000E8000000EA000000EC00057
+:10320000000EE000000F0000000F2000000F400043
+:10321000000F6000000F8000000FA000000FC00032
+:10322000000FE0000010000000102000001040001F
+:1032300000106000001080000010A0000010C0000E
+:103240000010E000001100000011200000114000FB
+:1032500000116000001180000011A0000011C000EA
+:103260000011E000001200000012200000124000D7
+:1032700000126000001280000012A0000012C000C6
+:103280000012E000001300000013200000134000B3
+:1032900000136000001380000013A0000013C000A2
+:1032A0000013E0000014000000142000001440008F
+:1032B00000146000001480000014A0000014C0007E
+:1032C0000014E0000015000000152000001540006B
+:1032D00000156000001580000015A0000015C0005A
+:1032E0000015E00000160000001620000016400047
+:1032F00000166000001680000016A0000016C00036
+:103300000016E00000170000001720000017400022
+:1033100000176000001780000017A0000017C00011
+:103320000017E000001800000018200000184000FE
+:1033300000186000001880000018A0000018C000ED
+:103340000018E000001900000019200000194000DA
+:1033500000196000001980000019A0000019C000C9
+:103360000019E000001A0000001A2000001A4000B6
+:10337000001A6000001A8000001AA000001AC000A5
+:10338000001AE000001B0000001B2000001B400092
+:10339000001B6000001B8000001BA000001BC00081
+:1033A000001BE000001C0000001C2000001C40006E
+:1033B000001C6000001C8000001CA000001CC0005D
+:1033C000001CE000001D0000001D2000001D40004A
+:1033D000001D6000001D8000001DA000001DC00039
+:1033E000001DE000001E0000001E2000001E400026
+:1033F000001E6000001E8000001EA000001EC00015
+:10340000001EE000001F0000001F2000001F400001
+:10341000001F6000001F8000001FA000001FC000F0
+:10342000001FE000002000000020200000204000DD
+:1034300000206000002080000020A0000020C000CC
+:103440000020E000002100000021200000214000B9
+:1034500000216000002180000021A0000021C000A8
+:103460000021E00000220000002220000022400095
+:1034700000226000002280000022A0000022C00084
+:103480000022E00000230000002320000023400071
+:1034900000236000002380000023A0000023C00060
+:1034A0000023E0000024000000242000002440004D
+:1034B00000246000002480000024A0000024C0003C
+:1034C0000024E00000250000002520000025400029
+:1034D00000256000002580000025A0000025C00018
+:1034E0000025E00000260000002620000026400005
+:1034F00000266000002680000026A0000026C000F4
+:103500000026E000002700000027200000274000E0
+:1035100000276000002780000027A0000027C000CF
+:103520000027E000002800000028200000284000BC
+:1035300000286000002880000028A0000028C000AB
+:103540000028E00000290000002920000029400098
+:1035500000296000002980000029A0000029C00087
+:103560000029E000002A0000002A2000002A400074
+:10357000002A6000002A8000002AA000002AC00063
+:10358000002AE000002B0000002B2000002B400050
+:10359000002B6000002B8000002BA000002BC0003F
+:1035A000002BE000002C0000002C2000002C40002C
+:1035B000002C6000002C8000002CA000002CC0001B
+:1035C000002CE000002D0000002D2000002D400008
+:1035D000002D6000002D8000002DA000002DC000F7
+:1035E000002DE000002E0000002E2000002E4000E4
+:1035F000002E6000002E8000002EA000002EC000D3
+:10360000002EE000002F0000002F2000002F4000BF
+:10361000002F6000002F8000002FA000002FC000AE
+:10362000002FE0000030000000302000003040009B
+:1036300000306000003080000030A0000030C0008A
+:103640000030E00000310000003120000031400077
+:1036500000316000003180000031A0000031C00066
+:103660000031E00000320000003220000032400053
+:1036700000326000003280000032A0000032C00042
+:103680000032E0000033000000332000003340002F
+:1036900000336000003380000033A0000033C0001E
+:1036A0000033E0000034000000342000003440000B
+:1036B00000346000003480000034A0000034C000FA
+:1036C0000034E000003500000035200000354000E7
+:1036D00000356000003580000035A0000035C000D6
+:1036E0000035E000003600000036200000364000C3
+:1036F00000366000003680000036A0000036C000B2
+:103700000036E0000037000000372000003740009E
+:1037100000376000003780000037A0000037C0008D
+:103720000037E0000038000000382000003840007A
+:1037300000386000003880000038A0000038C00069
+:103740000038E00000390000003920000039400056
+:1037500000396000003980000039A0000039C00045
+:103760000039E000003A0000003A2000003A400032
+:10377000003A6000003A8000003AA000003AC00021
+:10378000003AE000003B0000003B2000003B40000E
+:10379000003B6000003B8000003BA000003BC000FD
+:1037A000003BE000003C0000003C2000003C4000EA
+:1037B000003C6000003C8000003CA000003CC000D9
+:1037C000003CE000003D0000003D2000003D4000C6
+:1037D000003D6000003D8000003DA000003DC000B5
+:1037E000003DE000003E0000003E2000003E4000A2
+:1037F000003E6000003E8000003EA000003EC00091
+:10380000003EE000003F0000003F2000003F40007D
+:10381000003F6000003F8000003FA000003FC0006C
+:10382000003FE000003FE00100000000000001FF59
+:103830000000020000007FF800007FF80000026F27
+:1038400000001500000000010000000300BEBC20C5
+:103850000000000300BEBC2000000001FFFFFFFFCE
+:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68
+:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58
+:1038800000000000FFFFFFFF00000000FFFFFFFF40
+:103890000000000300BEBC20FFFFFFFF000000008F
+:1038A000FFFFFFFF00000000FFFFFFFF000000031D
+:1038B00000BEBC2000002000000040C0000061806D
+:1038C000000082400000A3000000C3C00000E480AC
+:1038D0000001054000012600000146C0000167808C
+:1038E000000188400001A9000001C9C00001EA8070
+:1038F00000020B4000022C0000024CC000026D8050
+:1039000000028E400002AF000002CFC00002F08033
+:103910000003114000033200000352C00003738013
+:10392000000394400003B5000003D5C00003F680F7
+:103930000004174000043800000458C000047980D7
+:1039400000049A400000800000010380000187000D
+:1039500000020A8000028E0000031180000395001F
+:103960000004188000049C0000051F800005A300CF
+:10397000000626800006AA0000072D800007B1007F
+:10398000000834800008B80000093B800009BF002F
+:10399000000A4280000AC600000B4980000BCD00DF
+:1039A000000C5080000CD400000D5780000DDB008F
+:1039B00000007FF800007FF800000174000015008F
+:1039C0000000190000000000FFFFFFFF40000000A2
+:1039D00040000000400000004000000040000000E7
+:1039E00040000000400000004000000040000000D7
+:1039F00040000000400000004000000040000000C7
+:103A000040000000400000004000000040000000B6
+:103A100040000000400000004000000040000000A6
+:103A20004000000040000000400000004000000096
+:103A30004000000040000000400000004000000086
+:103A400040000000400000004000000000007FF83F
+:103A500000007FF80000050900003500FFFFFFFFB0
+:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66
+:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012
+:103A80004000000040000000400000004000000036
+:103A90004000000040000000400000004000000026
+:103AA0004000000040000000400000004000000016
+:103AB0004000000040000000400000004000000006
+:103AC00040000000400000004000000040000000F6
+:103AD00040000000400000004000000040000000E6
+:103AE00040000000400000004000000040000000D6
+:103AF00040000000400000004000000000001000F6
+:103B000000002080000031000000418000005200D1
+:103B100000006280000073000000838000009400B9
+:103B20000000A4800000B5000000C5800000D600A1
+:103B30000000E6800000F700000107800001180087
+:103B400000012880000139000001498000015A006D
+:103B500000016A8000017B0000018B8000019C0055
+:103B60000001AC800001BD000001CD800001DE003D
+:103B70000001EE800001FF0000007FF800007FF8E8
+:103B8000000004480000150010000000000028ADEF
+:103B9000000000000001000100150005CCCCCCC1E4
+:103BA000FFFFFFFFFFFFFFFF7058103C0000000009
+:103BB0000000000000000001CCCC0201CCCCCCCC39
+:103BC00000000000FFFFFFFF400000004000000079
+:103BD00040000000400000004000000040000000E5
+:103BE00040000000400000004000000040000000D5
+:103BF00040000000400000004000000040000000C5
+:103C000040000000400000004000000040000000B4
+:103C100040000000400000004000000040000000A4
+:103C20004000000040000000400000004000000094
+:103C30004000000040000000400000004000000084
+:103C40004000000040000000000E01B7011600D641
+:103C50000000FFFF000000000000FFFF0000000068
+:103C60000000FFFF000000000000FFFF0000000058
+:103C70000000FFFF000000000000FFFF0000000048
+:103C80000000FFFF000000000000FFFF0000000038
+:103C90000010000000000000007201BB012300F3CF
+:103CA0000000FFFF000000000000FFFF0000000018
+:103CB0000000FFFF000000000000FFFF0000000008
+:103CC0000000FFFF000000000000FFFF00000000F8
+:103CD0000000FFFF000000000000FFFF00000000E8
+:103CE0000010000000000000FFFFFFF3318FFFFF16
+:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308
+:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69
+:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7
+:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3
+:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7
+:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61
+:103D50000C30C305C30C30C3CF300014F3CF3CF399
+:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4
+:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387
+:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98
+:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367
+:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2
+:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347
+:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45
+:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327
+:103DE0000040CF3CCDCDCDCDFFFFFFF3310FFFFF26
+:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307
+:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47
+:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6
+:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2
+:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6
+:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60
+:103E50000C30C305C30C30C3CF300014F3CF3CF398
+:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3
+:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386
+:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97
+:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366
+:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2
+:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346
+:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24
+:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326
+:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45
+:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306
+:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46
+:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5
+:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1
+:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5
+:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F
+:103F50000C30C305C30C30C3CF300014F3CF3CF397
+:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2
+:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385
+:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96
+:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365
+:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC
+:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378
+:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62
+:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325
+:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23
+:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305
+:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45
+:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4
+:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0
+:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4
+:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E
+:104050000C30C305C30C30C3CF300014F3CF3CF396
+:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1
+:104070000C30C30CC30C30C3CF3CF300F3CF3CF384
+:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31
+:104090000C30C30CC30C30C3CF3CC000F3CF3CF397
+:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B
+:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377
+:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61
+:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324
+:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24
+:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304
+:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45
+:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3
+:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF
+:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3
+:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D
+:104150000C30C305C30C30C3CF300014F3CF3CF395
+:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0
+:104170000C30C30CC30C30C3CF3CF300F3CF3CF383
+:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94
+:104190000C30C30CC30C30C3CF3CF300F3CF3CF363
+:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B
+:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376
+:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61
+:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323
+:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57
+:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337
+:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76
+:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316
+:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55
+:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6
+:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34
+:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6
+:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12
+:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6
+:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE
+:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396
+:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6
+:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376
+:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96
+:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356
+:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56
+:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336
+:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75
+:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315
+:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54
+:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5
+:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33
+:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5
+:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11
+:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5
+:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED
+:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395
+:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5
+:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375
+:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95
+:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355
+:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55
+:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335
+:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74
+:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314
+:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53
+:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4
+:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32
+:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4
+:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10
+:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4
+:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC
+:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394
+:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4
+:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374
+:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94
+:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354
+:1044E0000040CF3CCDCDCDCD000C0000000700C07A
+:1044F00000028130000B81580002021000010230DE
+:10450000000F024000010330000800000008008096
+:1045100000028100000B8128000201E0000102007E
+:104520000007021000020280000F0000000800F0E7
+:1045300000028170000B819800020250000102709D
+:10454000000B828000080338001000000008010002
+:1045500000028180000B81A80002026000018280BD
+:10456000000E82980008038000028000000B802863
+:10457000000200E0000101000000811000000118AD
+:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B
+:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B
+:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B
+:1045B000CCCCCCCCCCCCCCCC00002000000000007B
+:1045C0001F8B080000000000000BFB51CFC0F00360
+:1045D0008A7BD81818367020F843015F646260B88F
+:1045E0000CC45781588099812198918121849178B8
+:1045F000FD49A208F62B210606316106866841A016
+:10460000B9C208F1A3403556220C0C7FA1628D403F
+:10461000369B2875DC3FD0789314A6D87A09047BA2
+:1046200033167964BC054D9E4F1295BF9580FE816F
+:10463000C68F1551F9620A103A1F2AFE044D5E1CFE
+:104640002A7F19EAAFA78AD8CDBD02950700C8E92D
+:10465000674460030000000000000000000000004C
+:104660001F8B080000000000000BED7D0B7854D577
+:10467000B5F03E73CE9C9949662627214F1E6112E4
+:1046800020828638BC0228BD4E0844AC5C0DF8423E
+:104690008B3ABC43DE50B4B4B55F2610224F6FF0A6
+:1046A00047452FD8E161458B3660A4D1021D4010EB
+:1046B0007BBDB7C1528BD5FA4554500C24728BD2B6
+:1046C0005B7BFDD75A7BEFCC39930960FFF6FEF791
+:1046D000BFDF1F3FBFC33E673FD65EAFBDD6DA6BBD
+:1046E000EFB1B334A60F64EC6BFCBB81B11A1B6352
+:1046F000F0AAFBF9949DDD5FEA662C6FA36FB93BCE
+:1047000015DEB7E6EC4AF43196B577BD3211DE67B7
+:104710006D6A5266E747DB8F76C1C731F0BE75BD63
+:104720005204EFB3DE6C5266E1D361636D509F6952
+:10473000BE24864F16602C9DB141E398F80BB8B3A8
+:104740000A19EB8FFF842ECE1B89D01963392B6C8D
+:10475000E19002EF8365539997B16D0057560AB403
+:1047600053BF3A60C7BAB5DAC97627634ECDA97D83
+:104770009DCB58F60C6663F01CB894BFC7BFAFE181
+:10478000FF9C90B53C8899CA3958F6A49E8221991D
+:104790008779BE56E3C1DBA5970E8FCE533E37D542
+:1047A000F9D2DD5ACFF7F2B978D127FAC3D0FA6936
+:1047B000AC3798B1704CFDAA90AEB16BE1090868B6
+:1047C000CEEFD97E2A2B2A443ADCC726D2B346F351
+:1047D000DD8578A9396A672180BBA6F65409965908
+:1047E000ABC286E4F46C3F9CD9891E454CD14EE1A6
+:1047F0007CBDCC8BF3532B7D4F94009EE726062681
+:1048000061BFEB1283F494EF33674FC90C023CC5D0
+:104810000BF2430CE87E7EA3E27740F3D34A58B70D
+:10482000033D2A6EAF2DB811EAFD560FDE8CED2A3E
+:1048300067B41D217AB0DA3CC4539BCEF967606B34
+:10484000D1A71AD00D582C9494827461ECA4890ECF
+:10485000F87772A828ABBDE3F172CFB9D88F86BDC7
+:104860008469BEF27D4EE8E8A0C131E3B14282879F
+:1048700031E471D6AEC4A3EBC0578A8E6A05BD8FF2
+:10488000F7F79F4788CB21E00EE95BE5D1C3CB80EA
+:10489000BEC52FDB2337003DAAB6286107946DFB08
+:1048A0005D01A4CFB9ED5006BA443C3AD53F6B3810
+:1048B000A95CE3687BE47A2877BDACB2ADD8EDD0D3
+:1048C000041BCADD29013B1B0D65C0C77C172F5691
+:1048D0006D39701FF657D6EA602EE8BFEA9505B726
+:1048E0005C0FE505C06F58A5EA997ABD2F9417862D
+:1048F00095662C774E64C41FA1143DFC0C8CD7E93F
+:104900006D4BBF03E4E54C9D93F90094E59EB6F42E
+:10491000DB818FCAC3BB4AB05DF94EC58F682F7E5D
+:10492000F999235938AFE780AF808F2A7624329FD8
+:10493000C41FFC7F0AA672037C5F0CF344F95FC0BE
+:104940009A4A988AE3AFD77D9E28BECED419344EBA
+:10495000B73C3D07E340BBEA17153F4EB1DAC682CC
+:104960002857E75E71CDD8E6C6F9D5EB791E9CD7FE
+:10497000C33AD65B109EB507555679788B5E02DF39
+:10498000CB376DD1E7E723DE40EFE5235C7DAC70EC
+:104990006D540388DFC5C9CEAD2AE087B90399D32A
+:1049A000E3F0CF993A506379D17239CA37E993B0BD
+:1049B0003ECD54BF4449267EADD8A1329F859F3855
+:1049C000FD43C738FD43FB3CE16772A2F45B6C70AA
+:1049D0003D29E9B73859D053EB2A8C07CF23480F2C
+:1049E00080A709F105CFB5023EEF0456A4015DBCD6
+:1049F000016628ECF2FCD96467B3188CFD169B178E
+:104A0000D0C64359678B989F3143AB0A4C82F2570B
+:104A1000ACF44D9C0F637E5F29E0B951613370DEC9
+:104A2000871158984F63964EF86B9A5CB84D5504B1
+:104A3000CCA9589EFF93D539D4FE38B5D7A0FDF048
+:104A4000DEDB1B25E32CED8D9232D9FE3DACC79CFD
+:104A5000976EDF54729D75FC9272D9FE231ADF7D2A
+:104A600069F88D1B2758C7BFB192DAD73838BDBA5D
+:104A7000929DE1AD506E70F9031AD24D63117CAF77
+:104A8000A5E46DC57AAAE407D61650A1BD7B67F2EE
+:104A9000C8D5CCCC1713FF88E379405ACC7C91342D
+:104AA0002EC1C28FC981144B197A324E5D13D54382
+:104AB00001AF93E0D1FBEAA42F8AFA3A09DE07F7A7
+:104AC000BBA8FCE0751CDE07FBBA49CE10069605B4
+:104AD000653D78AD615A8F004E856532764109BAE1
+:104AE0009431E6F73E1BBE4F50592DCE27C1C14829
+:104AF0001F3D9C53B82D64C2CFCA01405F28A72A2E
+:104B00003AC7A3C0EBC303E667CE328DD338409FCC
+:104B1000B1359FBF9FE3C6F14AD315D4837A579E20
+:104B2000E1EE398E23779C651C6776198D931333DC
+:104B30008E23BB2C661CE78CADE2BD1867D0A5C6E2
+:104B40007938F73AEB7CB2CB699C82D8F96497C785
+:104B50008C93C0E703EFC5387EC45FAFF31934C14F
+:104B60003A9F819534CEF538CE18D37C0656C68C44
+:104B7000E3A671F03D8E0386948F6500DD1D5DF325
+:104B800089FEBF7491BDA03B82CF62BFEC5D17234D
+:104B90007DE283713350AFC0E20CF2AB292934CEF1
+:104BA0001709407FB799CE5C1FD113F4CF3C012287
+:104BB0000B0344A07FAA058FCEDD392DBB1E9FAD10
+:104BC000C599B3D02ED9E0F10F01D139D75AACCF66
+:104BD0008963DFCC6BB29F6AB7F0AFD07B13D9D0BB
+:104BE0005A18BF05958DA97C0AF41703BD7512F4F8
+:104BF000173E4F0BFBF423D06F4C37C35B4FF3389A
+:104C0000A5713C9EDAC4D7912FD61FB383B187C359
+:104C10001CCF07B8EF14D398D704C69F49CE6A04B7
+:104C20003DBA5E7184B7123D02FD6CC0E76C631F34
+:104C3000C095A80776E61F843D0A7FFD6C60CBDE39
+:104C4000B372D761ACF6B6326BC06298EF8C96F552
+:104C5000F67E503E676FBFCFEF36F533C37E12E767
+:104C6000ED84FFB09FBB83768B7DFA9D326BF9DEBE
+:104C7000187BB552C915F410E3FAC276A4D79DE9A2
+:104C80001C9E7BF139123F1B44AFFB0CDE56C25316
+:104C9000F3433B8BD07AD49EC6F2111F696417058B
+:104CA000E5BA1203DF7D7667A014E879DFF755C215
+:104CB000632CBCEDFB130336B097DA37FEBB1DED5A
+:104CC000EFCBC17FFF52EB7716E2E349BC4A3EB817
+:104CD0006B46519F8F4CF5EE0EDED4E72313BF7C5D
+:104CE000A76C9AA57C6FEDDD96FAF72F9D65F93ECE
+:104CF0002BB4D0F27DCECA4596F2BCA6EF5BEA2F6C
+:104D0000D8586FF9BE30BCCAF2BD62C77A4BB9AA97
+:104D1000F9494BFD9AD62D96EFB6FDC36E45795CE9
+:104D2000FE5B95A17D76C17DEA11B4AF2E189A1F66
+:104D3000EB5423AF811C7E529749FC7DA6CE47CF12
+:104D400073ADA39C688FD724803CC35ABF5FF943DF
+:104D500068E504D423501F74F841E5C350089CA7AC
+:104D600037141FF1BDBA516711605585A574F375ED
+:104D7000971AFDAEB5C3F751BD7F57376A71BF6B48
+:104D8000ED5ADC7E3B95AE3CB4EF42EF3818DA8149
+:104D9000BDD90FF0D70FD78BDEBE77D85859B3499E
+:104DA000EF9C526CC407772A134FA17EAED4B9BCD6
+:104DB00057EECE9A88FE60A51EC9AB755F62BC66D1
+:104DC000002603FBC9A5792D0CF78BCA2FD16F9054
+:104DD00045EE97B0E0C7A89F3B0EA8A46759E450E2
+:104DE000F66DC371FCC0297CCF5AD3687D7CBB2E85
+:104DF000D0E723F0E74ED44DA1E7EFEB4AFB7C046C
+:104E0000BAE6BDBA19547EBF2E48CFF6BA327A9EA2
+:104E1000ACABA5EF1FD52DA5F2A9BA103D3FA95BFC
+:104E200049CF33754DF4BDA36E2395CFD585E9D910
+:104E3000ED07087B94A50AFB4FD8EBB07250F9BC84
+:104E400098830AFFE67EAB3F13E5FABCFB8B3CB4CC
+:104E500073CF9F00C3248E7F289FB1FCD63BFD02F9
+:104E6000B4DECF0F03FD47F5FCEE4AE0F471D9D86C
+:104E70001406FA67D5109D69307EC22FAF217B19C9
+:104E8000DE6B8CF465D83FCD13A77F9C73C6E5E934
+:104E9000D4CD1F4FFDB910E30F770A7D987048AD50
+:104EA000E574DBE647BA99F0C7EDB297853E8FC14E
+:104EB00023D972593DF179364DE2B32D1BE3001B26
+:104EC00094D26136E083F32D0E9AD7F9BD896186BD
+:104ED0006D313832FE5278E37054EC701966FD5033
+:104EE000D59C6C58F5459661D617E78F6EF3A2DC1A
+:104EF0002FCEB4191F8D42FE0808FEE07C27FBAFC1
+:104F00006ACE31DC967EACE5F34DCA14F48340B929
+:104F100027DD1EC73F90CFC599BAF111C8F7991D7B
+:104F20008392705CF0E30C1CA7A3CE30F8B899868E
+:104F3000992F2B9726507D095F6FFDFEADE143CB86
+:104F4000E0432723D47F3DE89BFBD94CFB23C5736B
+:104F5000D85EFB17B8EE38E0FFAF291EA05159F616
+:104F60005BD3AC861CD7E2FB9D96F1A09D4FFAD097
+:104F7000B85EF54E778D9D32C505AA710CF28F9CF7
+:104F800044E720F49804FD756AEE950A8C33C5E673
+:104F9000A3EF35821FAB9CED7A105E9D6DE1F4E8C6
+:104FA0006D9C3375477D1AE88F32277864304E59EF
+:104FB000F3B049A81FCFB62C4F0F02DF56A8E71F4A
+:104FC0002C8DD37EA54DE1F084ED5DEDA6F9C838BA
+:104FD0000A63D0AF330A3F72FA295339565FCBE7E1
+:104FE000A3D82FF047F5CE6325D703FCD5AD9FEBB3
+:104FF00008C7145BF0515B5A74FE0ACE1FFA29DF12
+:10500000F1818EF3FBC41ECAFBE125F4544F38DD59
+:105010009914B793F085581BDA31B3BBE38ABEBB52
+:10502000DE05D1FCF45FEC6C35C0C1BE825AF0DD08
+:105030002EBECE65A55EC4D7EC960A8A2F7E6A93F3
+:1050400076535321F2C759669B82F33BCBDEF28E37
+:1050500032E1AFC5C6ED7EB692DB3121F80FE1013A
+:105060007BD662D72CD8682DCF67D3D3516FCCDFD6
+:1050700060676140D142B48B247FC0BCB7DBB8BD50
+:10508000BB80D536A23DA739B87F30DB605A3F8060
+:10509000ABEAE79B0BD1EEFF85CD46F49171868597
+:1050A000291CEEF2D4B01E80EF1FB68CBAF37AE45E
+:1050B0003E47B811D76596C4FCCFB09EF89CB3D2DA
+:1050C0000ADFE5E08F8597B165163864BF120E756B
+:1050D000871208C7E1BB3724DF093D92A25AEDFCD5
+:1050E0008C98F27B3611BF54998A743E6B3843B664
+:1050F00024FAEE8F607C64B7C3BF1CE8FB80ADB4BC
+:105100001DF533D80505CC54EF015B90DE77286F91
+:10511000CE47FB94699102F4EF614DD1901F74C1A9
+:105120000F6A82B700E3B11E06EB27C8A503E1832F
+:105130007E1A3D65535901C65F414EA1BF75DE928F
+:10514000A30A945DEE1686FD3932ADF16597CF5A0C
+:10515000AEC17F201D86328AE3240EB57E87058B83
+:1051600021BF79FCD6F7FFD18DA708F1AD97581A6A
+:105170009E4E774485F1D938ADC36C37573B39FC27
+:10518000E49743FD25C29EAF66BE10C58933391F23
+:105190002CB9C946F02CF1F8FC21F8AE680186F272
+:1051A00087B16AF33A56731144AE8FA9AC75E9C85A
+:1051B0009735173516067D5F600B7AD43188BF00AE
+:1051C000D9B94E40D6D700B2E69E62B17B59FF14E2
+:1051D000B1BEF637CCF2DA1FE93C264A67A917ECD4
+:1051E000422F82BEC850D3500F7695905FC2DA49E5
+:1051F0004FC87A7AB45E7F84A3B77AAE68BD9C78D4
+:10520000FD55FDFC853D21C07FF9CF1EF302F1D98C
+:10521000A75A53BA1FDE573EB3C28B7CFC8916F2E5
+:10522000E2BC3F0DAB53E2F1F39DAA22FCB1805BDF
+:10523000417F58D0E9CCF36B6E41BC7FF18CDDC06F
+:105240002A353B1C110710B1BA6521E7A71D8E0F47
+:1052500078F9E1CF919E35AD56792B7FF6B1748CFC
+:10526000770286B8DFC822643F576FFFB804ED911C
+:105270001AD6457A22B61D8E7F3185D6AF597A521D
+:10528000CFEF72FFA546F07D4DCB9ACF552F96AD4F
+:10529000F25D26FC911B554F2AC595C6B2B1483721
+:1052A000890716E6F6F0F2E79E28F800E0E8D8FE57
+:1052B0002F5EC51237E2FAE17CF39C1FBFEAEB5D7B
+:1052C000AF9F13FE7CB45D98DAF95AB9FDCEF6F2C1
+:1052D00067A53DE2457FA9728BDD0F92C92A5FD891
+:1052E000F693A790AFDF71509CA1E285C36F5F0773
+:1052F000E58A5DF6D4A97C1A6E253D4A8F1AF87F9F
+:10530000E9C828FECB5F3AACFB86F3F70FA544E96A
+:1053100050B1EB80CE86F7C45B71F301BDDD1D8714
+:105320001ECD1F94A0BDBDFCB92F7594AB4FF72BBC
+:105330002C23A767FBB22D87C99E433C11FD047D3A
+:10534000BAE9D5834E915B5E1D4DF50C5CBF7AA327
+:10535000D3D5B8F6A5111FBFF82AC6EF7FEFF0E34B
+:10536000FCCB5EFCAE17E7715AABE5FCBC79457A25
+:1053700000C62DB387D20D7AF2F7654F3F407CB659
+:10538000E0D803E9140F60812C1BADA1A12C9CDF98
+:10539000BC4D77D0FCE6B320F15BD966B5348CF117
+:1053A0002C8D4DD915471EDE14F2707AAB03D71E33
+:1053B000761A152CFA876FA9B44FC0D8228A373CC9
+:1053C00020F721D8622A5F70723A6D536D32BEE1C8
+:1053D000B4F0E9F687DB903E67060432303E097888
+:1053E00008097C29A877D4639333387D984F2B1410
+:1053F000ED402F16E37BACDF660FB80A2CEDC43A04
+:10540000C6C75F22C607B813D01E3B9D0EF64D9C43
+:10541000F97DA94ABD0CF68689BF4C72CDE57CFBAF
+:105420002A2ED752CEC3D3A6E0F73F1EE7F283ED74
+:10543000705D07B82219F4FDC0ED0AE901078BC4BD
+:1054400093E7ED7621CFD6EF727F12E0D6707D8A9A
+:10545000F209F49F42F8273B6DFE066867D2CB3510
+:10546000381ED5D3A3EF4DEBFA0221FFAFAB627F1D
+:1054700054C83FDBC4E5BE77BB37C4FD037BF827C8
+:105480004FA1BC827CE23A53F982BD14E7FDD9CE2C
+:10549000436FDF037CFD59B39453ABDE8C95D3B2DD
+:1054A000DD63583C39FDCCED6771E514DEC79553DB
+:1054B000773BF1F1DF5B6F4ABC9D8BD19B520FF6BE
+:1054C00086BF583DB856F5C5D583F0779C15F6E4F0
+:1054D0003BC96F92CFCA7F5A3590E246921F25BFD3
+:1054E00075F3A3E4B7D8795AF116FBFD15A16F2423
+:1054F0009DEDCB58C883F1D27D2AF9D79D00532367
+:10550000D0B773674E18E3CE2B5C3C7ED1697479BB
+:1055100053E0B9229997BBD2F446D40FF27D978B12
+:10552000C7B73B4BBBBCC926BFE283BDAAD707DFC9
+:10553000DBC36C4A3C7F03342FC1D1CE7AFBCEE370
+:10554000C1935577F652F4DB9B54DACF9E5B7F977D
+:1055500017F7813BF70EFA27D44FF3DE000313E071
+:10556000ED443B3009A717D0302F618EA0F7272CD0
+:10557000F4F80498DF9CBDDC5F98BB36C6BE772F7D
+:10558000D151DF807D7FD21AD7E67C532EFA29DBFA
+:1055900064FD5ECED612DDCA63F82828FCC0B19A3D
+:1055A000E0A3116C84F0C378FC42E8ABC96AFE3F0B
+:1055B000A19DD17994C715CFEF5509FFE7772A61EF
+:1055C0008CFB507C773CD2BF4B67267FB903F94DEB
+:1055D000EF5D8E3B5EFE43E10FA14AE59E770BFE39
+:1055E000199E1D7BDEC9FB05967FFEBBEC7759CF6C
+:1055F000FAC5FBFF44FBC79DFB1D0447E7FED7B37D
+:105600007F88E5571D7E84B3739983F6CF42FB3DB7
+:10561000E121F87D00D01BD7CD7D5F16B4D3BAD37E
+:1056200040749AADF1FD8EF37BFFFCBE82F9077BDF
+:105630001D3E9C47CD7E9E1752F3AA8BE22E9DFB0A
+:10564000BE2C0CBAFF76F3A9D65990F8CFC366ECFE
+:10565000467E4DE6FB0035BF18BFAD1EF7C35B0E9F
+:10566000E8B8BF52FCCBBF14A07EE9DCCDED84735B
+:10567000F6F6A7711FB44A1BBCCC8E728F365B5FE7
+:10568000B03BEDF32686F2E3E185E3A113F080F36E
+:1056900002BC94A15EEC0D1F0D1AF737FFFBE1E38E
+:1056A000F3FB70FCCABD63496EA2785102FCBD27B2
+:1056B000EC5468FEFCFDFE2F0BD0EEF9ACB99ED683
+:1056C000F1CBCD7BDBFFB8792B912B99F7C1FFE6AE
+:1056D000FC3F45E3EB52AC1CF4E4F39F3F48E51775
+:1056E0003D7E82F70AE5FFE4FF34BAEF06BA7B2F6E
+:1056F0004F77C5FEDF75DE97A3FB1B82EE1E03F31B
+:105700000A3AF7FD85E2E572FE979BB7EFFFD17984
+:105710004BFB67B5CDDF940BF5D7B2489B0FE05C30
+:1057200031747A138699C04D288D678F94DAB97FCA
+:10573000A42A3C0EC306F0B81013FE04A580F9306D
+:105740008E329FEC3ACDDD487626D3FC6D01C0C782
+:10575000EAAB67FB2957838D3C11C472FF097E8A2F
+:105760006FC6F8550D0A0B2860EF69577FFB28DAE2
+:10577000F9F6A1B688A3809E1FE0F36111C7B21BA2
+:10578000BAC59F70C7F8032E9FF5BB43F4E76423A7
+:105790009B72314FC1AD196118DF5DD444F3710FB5
+:1057A00061ACC9B40FE860A6F6D05F3E06604DF666
+:1057B000E337C55F7D37FE46B605107FC36C14D74F
+:1057C000A2A43EC2873FBC9AFC4CEE3F46F1D9D81A
+:1057D0008678D418F87F7C7EE43732E12F6AA20BFA
+:1057E0006DA82DE0B2D6137ED165E9C3E9915D299C
+:1057F000E8B3D8420F89FF3874B1D043E2F79BD2A7
+:1058000025961EB178BFDDCEE36DB174B2E477A406
+:10581000713F24027EC8EB3BB751BCE3ECF31FDCC5
+:1058200082F52B7EA13227F4736EA78745507EB593
+:10583000B08EFE54798B1A37CE2BEDF28A9F7968A1
+:10584000BCF2DD8EF054685FBEE7C302B29B967572
+:105850001DE9877181E7154EBF507B01EEDB956B2B
+:10586000DC3F88ED6F939DC7053A5E499C81F10747
+:105870006507CF572C6FBECBEE30F1DBFFB2F3BC28
+:1058800057A847F21C7A4EA1F5A6277CDC2FE878B2
+:105890004EE1F0B5DAC398F758BE638B1E44BF7271
+:1058A000C7E714C72EFED90BDE76F21755ABFFBC47
+:1058B00043257AC293E817EBC756B754919F50DD42
+:1058C0002CFCC4183FAAE267FBF6840035152F3D77
+:1058D000EBC5F8CB99B667BCE49FEEE0FEA7E6D631
+:1058E000E2FBA797F34B9B57C5F54BCFE03FC09F1B
+:1058F00038608FF1E777F4B9B2FDCB172E3C8D718C
+:10590000D28EDD9F3D8D7057FEE7BF3F8DF63DDBAC
+:10591000EF329E81F9D63CFF5B8A37C976EF0A39B0
+:105920003D378085B2A0DEB9771C943F726EDFE907
+:105930006CF4E7CEEDFA533AFAF54BF64DCEC0795A
+:105940002F79B93883C59177F944BE0C5F419C30FB
+:10595000960E875A0E911F72F68483FCBEEEF842B3
+:1059600073158FD7F8445C6167FC38ACF487AB5B88
+:105970003E2CE1F131E1175F2E8E701CE878ED15B9
+:10598000D06BA78813C5D0EB2CFE03E8F2650CBDE5
+:105990002EB0E08FB3701FB2A54FAF7184C815E071
+:1059A00049C6778FD803361DE5607762379DA622FA
+:1059B0009D5EB8908DF1F04FEC5D64F774ED731857
+:1059C000E8DF97EFFB1DC9C5B9978F51FC94893863
+:1059D000EB39D6FDC7E3628A98DF760F8F3F087CEC
+:1059E000637CC2E7A5F7220EC1F955C6277A8B4B17
+:1059F0008CD545DE93883B576D7F576731711E65A7
+:105A00001CD2E9034B7C5CCE3BB63F03F130D61C85
+:105A10005F8B1FF7917E73944E3CAE26E367E7B62B
+:105A200088B81BBCEF3F12FD411EC7A8092BBF63FE
+:105A300071E450C6D746EA317218BEB2B8DAE5E072
+:105A4000FD6BF13144E7EB83C44BC757F1F5F03FF1
+:105A5000EA5CAEA7D8825375D37EF6FD629F45E21D
+:105A60004BC2DB21F2F03A9E57291ED4D87C88F431
+:105A700069AC3C57F7720EE23E9DC75BAB5B0F14FF
+:105A8000A0DEE938F80AF15DF5CE0FF410F4736486
+:105A9000C74B3AB727399FA39E0E9BF474C78B0759
+:105AA0000A78DC8FE7DDC6F65F21FAAFD96BEDBF70
+:105AB00066E7E796FE2B42CDB4FF75B971CE6881DB
+:105AC000BB70BE67DAEC0CF5DD9966754A389E1D31
+:105AD000A8DB2DFBA08DC7745AAF46BF9540F9B91E
+:105AE0004B8E4D793709F7E940CCD0FE6DA9E77CA4
+:105AF000D5F2A3403FA44BCBB17B545C37F6201EBC
+:105B00004D7670E1F1DA620FC86BE17BA5A391AD30
+:105B100062F5C0D813360BDC304E06EAE306E80720
+:105B2000F3E9317F08F747556FC9148447356C8610
+:105B30002BEEFAC9FBB3BB4B19DAE576C39AAF9CDF
+:105B4000395DC4D122D6BCF54C9D0DC57D70664B28
+:105B5000F0E37EC0E26181118731AF7E5E26C589A8
+:105B6000B36EE3EDCE1AEE90EDDAE8BE6DE245E8F5
+:105B70001FF3606CE1F533A15DA2D6ACE03E003CC2
+:105B800019D2E5015B70AB9E86F574E603D5F8B4D7
+:105B9000AE68947F21CEBDC8FE64BDDEF683E539D4
+:105BA0002455C03F48EC070F60ED0AEE076FF2F096
+:105BB000F34803DDA974DE689BB0DB7CB8EF8AF59F
+:105BC0006AADEBF665CF23ADB496538B8B160DF40F
+:105BD00033F661E383C51AE883D4BB8A76F5337064
+:105BE0005F7A4331E6DDA73E5B34220BCA77398604
+:105BF0004FA2EFBF2E1A910DE55AE7B849F4BD4206
+:105C0000A1BCC07D7A6771283F2A9F6960DC62BEB3
+:105C100005C8ED4194DBB3A51D8DF8B5EA8E2F7450
+:105C20007E1E8695E2FC078CE3F3EFEF7E6F17CEC6
+:105C300077A0ADBD1EF9EFC7FBBE4CC67A3E66D05D
+:105C40003C0DD660E0BE3CBC1AF7F525F27F62F34E
+:105C50006024BF6F4B0CFE06E158357BE81325A886
+:105C6000532BFDC447B1FBC4CC4825BACC157441B5
+:105C7000389DA63CE4056A88F25EF04402E5F5B082
+:105C800049068EA7842AD5AFAFF9E6709DD645BEEA
+:105C900081380F663A2F7506E15D9718A467EC7995
+:105CA000A9837A6907BECF9A7F311BE721CF4115BF
+:105CB0002F70537CE0FC5E1676C49123F9DC5AC742
+:105CC000D2B4C1BD7FFF8D23F81FD87FEE2F7DBBDF
+:105CD0008F427FD7CED5FD98C276EDD2D169DA2832
+:105CE000C627847685A05F26D214E5EC41C6CFE7AF
+:105CF000389400FA8F9DDF35480FF79F3B95FC8C59
+:105D0000CEC49C66CCA3E8FC21CF0780955E417988
+:105D100018B03729827E10F0F31731FCFC8575BD71
+:105D2000B18EDBF9B5AFB59DFA33447F60F0A4A323
+:105D3000FCF0BF4E95DBDB9D753E8203CCC303B800
+:105D4000AE5EE978590E110F17F401BCF77398F0A5
+:105D50003ED0D12BFD721D9C7EF48CA5DF7C676D3F
+:105D600036CA7379697309BAA8BFD5835761BDD3A1
+:105D7000F38F34DAA15ED5CCDA3C64F69E74E5E7A5
+:105D8000B1D2F7CEAAB763BC02E9E2EB49BF6B9789
+:105D9000FAD3B43E167A8E72403FD7EEFDDC8670A1
+:105DA0004B3A3E21F2FC63DBFF834311E356D6DB23
+:105DB000314ED2AA933D1B5B6F0A1EAA1A132D17F0
+:105DC000380B69DC0C1B8F77F4ACCFD7BF68BF4EA4
+:105DD0003A97D51B1F1618BC3FC0FBB7117E89F739
+:105DE0005B1C42DFF6C4FB34AC0778A7E715E0FD87
+:105DF000CE4BE15DDACF15421F54E0FE09F0CDC76E
+:105E000081E9E98361DC12D54D7CBFF01995E40D81
+:105E1000EA4FCD4A8FEA8F85E36B0FE03C176E5651
+:105E2000883FE78AF3A59F897CFED83CA8F93342D6
+:105E3000B4AFD3231F2A1CE3CFC5E4B95747F97485
+:105E400020CF4FE3E7B5542107C50BF293D00EDA0C
+:105E50006FF7FD9AECEB3754B6350EDE89B9D2A256
+:105E6000E501B5364B7E2C9B9B6CE977D2827CDAC0
+:105E7000EF5EECF15DD29F1AB8D4BA5EE784ACE76E
+:105E80008B06ADB49E2F1AD2D4D752FFAA8DB996E5
+:105E9000EFC3C2575BBE5FB363A4A53CBCF93A4BEA
+:105EA000FD6B5B275ACA2322DFB6D41F7574BAA5CF
+:105EB0003CA6ED1E4BFDB127665BBE8F6F2FB77CF6
+:105EC000BFFE93C596F2B7BA7E60B54F6C8CF421D5
+:105ED0004B50483FBE56372E1BF3B0D9686512E2CF
+:105EE000B358E411BEB648B7195E7CE6D90CD0535E
+:105EF00007E74DA5F5FEB545E9011F3D0B03E8CFCA
+:105F00003075C2E878799A938DF1D9E67CA862A7BA
+:105F1000DDA2CF261BD6F2CB926F0672BE79354634
+:105F20009FD96B2744C022647D170ECEC0F140BEBE
+:105F3000F609BDB6EF0AF5DA4194C3D3E991462CD0
+:105F40004BF962625D2D127C04CF808EF990933CF8
+:105F5000B4FE06F0A58FDE87349093894E7FFFC391
+:105F6000381F9B3F15996FD28CD2D7786EA5587F7A
+:105F7000D950DB37597FA57C67DA44BE5A0ACF5720
+:105F80007B725E5E1233E1F55D874DD8CD4DFC69C5
+:105F90001C7575E7A9E69ADF7F92A099F2E3940554
+:105FA00053293F24B3173DA867E6DEB41DF4AF9E26
+:105FB000E5A3A77CDF38C31637EFEB9CD09BD2BE9E
+:105FC0001A16B5AFCE211DCE66BEF538E62555CFE3
+:105FD000EC22FB2AD3D6B4E808CEEB57AA8857FAAE
+:105FE000F8792A6117CFBBE9D14547701FFA5F875F
+:105FF000905E92E36CAA9B7293663A37DEBF173FBE
+:10600000699893AF0F4FD70DBD692EE5691BFC7CD6
+:10601000A8E83F3B54558276F240915FFAB82D7E56
+:106020007E4B8293CF2B03498EF01A6E928FB3F37F
+:10603000DFF36A308FA76CC10427EED35EDB56C84E
+:10604000FDBC801FCF9D6647EE7D1CEB67676A94A1
+:10605000DF1A3B7EC6CCE0CA1C985F438ACDEFA610
+:10606000729782F51D0F31D607EA37FCA74AF03444
+:106070001C1C4FF91E0E772D43FB55CEEB50CA5317
+:10608000841FB52591D63D26F6C1657CF542E6DC38
+:1060900036B42B2E6CB0D37817608E06F47FA145F2
+:1060A000A57DD6232909111B94D5951E52A9D9681F
+:1060B0006B42FDF92D9EB02F278A176DE3043AFF3E
+:1060C000E2E8CFE7DF90E20EBB7368DE29386F09A4
+:1060D000A79CF7805EFCCA1B041EB3AEEA3E97C1C4
+:1060E000908F5543A37EE725F37397E1BA71825EE3
+:1060F000D6F934664EBFF56E3C2F745C65980AE2A3
+:106100006B6FA2F9CF87F9637C3716BF677D395F64
+:10611000D85482F3068453DD5842F3A07AD0AEEA15
+:10612000C70A7B2A07F9303885E8DAD746E70063E3
+:10613000E12E71F238EB8D4E1E0FD033F36EDADEA6
+:10614000079F83492E6E76F6BACEDFE2E47A889E08
+:10615000577E9F40C4B2CEAB011BD941B17081DEE6
+:10616000BADB69B26BD4A4870AB0DFDEEDB15D079C
+:1061700074B4C7DC8CEC64A92F7BB3C7D00E437E0C
+:106180009376D802A755EFC2FCCAC5FCCAE3CD2F4F
+:106190008E9EADC17AA7EF89C4B563D2F4F87A6850
+:1061A000B3C07F8DA1338A2BF5120F7FC229EDC1B9
+:1061B000BD0774C42BCC13F19A09FE7109E9197B50
+:1061C000DCBCEFCBF919B96BF2771FC5FEC08E4569
+:1061D000EE39DFE44B4AB9841D615FFA2B97198FC2
+:1061E0008FC4F007E06DBD93DB7FF4EC81B754C042
+:1061F0009BCD82B7C79D97B4FFB8BEED2BCE0F9C49
+:10620000137802BDFB7DECFFEC6DE7EE44DFB0EAF6
+:10621000B6AF845FCBEBA70BFD0C7EEF3F7CECA30E
+:10622000FA4B709CA8FFDB5E887ECFF297AF4A42A4
+:10623000FB69D29EBB0D7C9E4F1D4CEBCFD93D8E92
+:10624000008E733685E7D39DDD33F608C6073EAB77
+:106250003B9A6BD6CF675F3C5668877ECEEE3E5644
+:10626000A851FE6ED8628F577DFD9B423C2725F3D7
+:106270009EBBE9ECE47A7D838BC71DD2D2F546CC78
+:10628000E7EE4848A6793F966E7B245E3C05D51D17
+:10629000EDAB7B74DA475C3CCCB7DC8DF1941C83AE
+:1062A000F264972B81AC79B80F32CDE9C7387D6A9B
+:1062B0002E1B9A9384A1C62073030B395E6BA2E355
+:1062C000A0096DC6013463649C452BE6FAB1EB0E60
+:1062D0009DF2BA1235DF1333A19C3943A3F549C6A9
+:1062E0005DFE9C9042F0C9B84B373C6FD869DD58D1
+:1062F0009C136C2A82768BC7A7503BEFB4B789DE1C
+:106300009D3E5BC88EF3D1BA28FEF24F7543D3068B
+:10631000031E8D2CDB4D64837C05D832E5E77B358D
+:10632000164A027B640DF0EF60E0DF963A27D56FE6
+:10633000043BCE48A17B0CA2F77098F87E779D4174
+:10634000F57E529749ED1EADF3D1B37BDD67BC1DE1
+:1063500095E3E8C3BFD7735D1DBFEF4396FF7D3460
+:10636000D85540EFD4B14055C04BAA381F2EBF3F7F
+:1063700055F7C6A049830532009F7D2B8D2DAB2F8D
+:10638000016FAA239C8C478007BA58685226E6E121
+:10639000753D52928CE717EA274D1A0678C4FDE73F
+:1063A000EBC09570AD6D084D007EA8F4D5635C2EF2
+:1063B000AB5569C6F526AB757D11C6F9A11E9DEBDF
+:1063C00093FDBA5C5C3F251E7A52C91D8EC17FBE0B
+:1063D0006FCEF62586E39DFF1CEAE27A6AB068B7C5
+:1063E00046EC7B774D73D33D0989875CC42F597B7D
+:1063F000AFA1FD37772FFBBEB1FD241EFA13C5698F
+:10640000DD4AD301DC4764F3B8BD28F9A9B7765853
+:106410005FBF82FA9D7E8DE2B660A6D2FCCE4EEBC7
+:106420004FF8C6FAE67B3C3AF5F876D46817B753CE
+:1064300057D8E3EB6F8D71FB60745B17ED37E2BDEE
+:106440004A88EFACE34D0AFAD367159E2FD117F0B7
+:10645000B11BCA59139AE8DEA56DCEE0752E80EF08
+:106460008FC689BC15008E2BFFF7D9D84EE2432D7D
+:10647000D09DA84FB2F67EC0CFE1D8DA75CC4FFBE5
+:10648000CEAA17283EA8EAA539BC5CB702E3876903
+:10649000DED22DC8272CF4C2A4D7C0E7794C9C2BA0
+:1064A000C637A8F7D6B84439F47C4300F8648D9D0C
+:1064B00097BFB3EAB9063C77BCC65EBA10CF256376
+:1064C000B901FA5F93DC9C6983B2BBFED986A30352
+:1064D000B02CEB3F4B7C76A78B9FEF61EED22CC4A8
+:1064E0007B77D980F2705359E365E6E44F39BFAA50
+:1064F000437F3AD20FF8A57A2FBF87A61B6FADEB6B
+:10650000155C4F7E5277D4D7A0093991FA03D6E5AE
+:10651000AB3219F9157A5809E72A781FC7CA74737C
+:106520003EC9AD898A585FA0BD392E1873EE8C8E96
+:10653000B2E0FADAC0F33662E9FA46425143C218D1
+:106540003C2F1A5CADA21E7CC16E50DE7BBB467A2E
+:10655000BB43E6BDD7DAC97EAB14E750EDCB82ABC7
+:1065600087A15CDCABF9310E5091D35484F64BC556
+:106570002B39FE7A16CDA3AD486E4E1FE98EE6D1BB
+:10658000CAF2721137CA48AE4D4ECEC7FD92F5D948
+:10659000B89F51CD9AEEFB01C2FBA6CA90DF3F3DEA
+:1065A000303E09EF05AA8232C6A9AA5A8EE941A84F
+:1065B0005790C0EFA3A96E01BE71F37B6202798C84
+:1065C0006DD18C04D4F33F09D45E8D26EC13AEA3B9
+:1065D000935C40D767730306D2F9A5556F3538BF72
+:1065E0000565DD18C64660F99D06E4B38A1136CA12
+:1065F0008364A1775E0B0C16FBB1507EC89531D930
+:106600001C97CE12EB78CD26379DD78275F971E4B1
+:10661000EFEA8DB610EE6FD99C6D744EE725975C4E
+:10662000FFADE79B36285C1F86E6F138E7929B5268
+:10663000BE4DE79B56E41AA14BC45BCB2E26D03946
+:1066400026592E48F051FF655A88F679CA2E7AE904
+:10665000FCD3DF6E3CA7E53C55CFF1DC048F1CAFCB
+:10666000323A1ED1F5D0C85F3D3E18E8B66497DDDA
+:10667000E630F1DD925D62FFDC15C8C07ED2748E1B
+:106680006786FE1BF01ADD41C3CB210DD681755202
+:10669000BE431D0D932620DDA2DF9955FE03E83F82
+:1066A000AF4B90E50BF1EB27C4D4CF95FDFF85EA06
+:1066B000C7C29396102D3BA1BEF617477719E15B31
+:1066C0006F8BE92F4596F51593FA47F9EAA155DE48
+:1066D000C321E0AB75C94D45A8FFBBE6311FDE7392
+:1066E00085FCEA37E9DB875C5CCF965DCCB5D03BB7
+:1066F0008AF73C0B5D4ED7655AF62517CC5C42FBFA
+:10670000A70FA1B0603F2CC4CFC16CEAC7C2A6B826
+:10671000CDFF87E3AF85E3BA5EE0F887FF62387CA0
+:1067200096F1A2700CB6C0F7D7C2B1F5CEBC6FE738
+:106730004095C794903317D7851FF1BC35357992B2
+:10674000AF1EF74B7EA451DC7D08E3F928B91A3B54
+:10675000AA8D44F9690A60DC822DE3F60ABC5F6900
+:106760001F49EB10F90B83F63A66615E456E59607E
+:10677000213E59FF7CDA8F91FB984CC4F5E4FECBA7
+:10678000108315E1BD7C6F27CCA2752AB77466050E
+:10679000C6BF55CFE8045C0F1FB38543385EE85190
+:1067A0003E5E9A2DDCEC447BC93BD8C0F52ECDCBA8
+:1067B000F51F5B9D4FEBDF565BEED58B008E154AC8
+:1067C00051C21B88E7E45C8A63E37BBC0767AB5874
+:1067D000B7D464BF81EBD456B16E2D17FA5DBE4FAE
+:1067E0004C299D8576C4F2D545939DE3510F0556FE
+:1067F000F681F566D9EAA21599E371BDF1E53A6132
+:106800007D599650B4C20993D95AEFEB6B2447CB0C
+:1068100043FE02AB35E989A21568A734B81797A3E0
+:106820009D03DF0FA35FF86C8AD43BFC7BAED4538F
+:10683000A897408FA9F5DDE510EAA5DC6EBD5344AD
+:106840007A67FBD32A95CB603CB47B601E21BCBF2A
+:10685000AB6B8846FE910B604980B26B582EED6B96
+:10686000C1BC5902C6F587F1EF725F421F62A37D7A
+:1068700009AC8F787465F1FAFA347E9E59F7B8C97D
+:106880006F93FB1CAAD8574B1079248A318DCED92F
+:106890003AD78E5C8C7E9473B075FF588FC9375190
+:1068A00063F34FDC11B2BB1A12449CB90FCBA47B2B
+:1068B0000DC47BC6FC23F1997E774311DD77E76138
+:1068C00006E63B670623CC6C2FC9A703D6519F4928
+:1068D0006E1C6E168897EF704F22B787DD1735EE66
+:1068E000272A60DFE03AEA1176B8B08FECF21EA2F8
+:1068F000987557DA4B7671DFDD929B2666E0B921F9
+:10690000D51D70A29D73C01849FB292AF3DF5A6474
+:10691000B2771A2237513C5133020CED9CFDC2CEA6
+:10692000510D3F33DB398D75E080C35AB5AD308FE3
+:10693000EE9779CA15710E42FA3E66F3A3DE38343B
+:10694000B23CA4603C71292339DD56983E11F7030F
+:10695000B668A549F7A2BC1C87F17C9C6E7CFF79C8
+:10696000B982F1EF0BCED224D407EB9299C58F2ACE
+:106970004EE4FEC89309DCEE947E4223C013013836
+:10698000B48B57D37D3B43845DAACF9C44F12D4CFF
+:10699000D3C178A583D5860C77F43E3947A6CD922E
+:1069A0009FA85D2CA0F8DF930936CBFED1C3E23E51
+:1069B000405976B25A1EE7059E8EE7BFCD12703A57
+:1069C000C01EF2917D12B33FDFD33E227B45D2A79A
+:1069D000DB4E51F8B9CDDEECA39A8B368B9E8D9EA3
+:1069E00037D7492F9F13E7F9659E865BE8B3C6CC7E
+:1069F00060D3F539D1F3FB9AC8D7582BCEEDB34C01
+:106A0000ADCB7C4E3E11E331F0BD41E46D24C69C1C
+:106A1000BB77B99790BFE01AAA59CE69395990DA75
+:106A2000397CD6F75A66EC79FE50779E16E5156AE2
+:106A3000EC49850EEF737BB79FC8933A9BF87E2194
+:106A4000CA2FD8BB3F77D23E023FC729E359DFD4D4
+:106A50003EDE8F76D518F40BA78CC07EBF23D6A35D
+:106A60002C569AC537079B19E5F524F8DB19BF1397
+:106A70008CEC2D55EAB9D00B0DE847A599ED3B9369
+:106A8000BD3670CD0B0D0DDCEFA0F27756AD263D77
+:106A9000B8C225CB2BA80CEB5504FD1EB6C7E143AD
+:106AA0007E82F601941B76671ED9CB6A2EB8B4009D
+:106AB000F724BC9F10E3F97B1C5BD19E05BFF64E0B
+:106AC00097894FCF7A4E64B3FCB8FD852CFD657F66
+:106AD000B3FE60FC16CC0392DF2779374654DECE36
+:106AE00087ED58FFB6F743D0FF632F3BE8DE107900
+:106AF0000F722CBF162672BB01F58639DF529F3903
+:106B00003780CC29E5D3919960C9D396F2AA5D1C50
+:106B10004AF229DBED4FC8E1F77369018AAB6917C7
+:106B2000F349FE9F14746DAC332E334E4A2FE38C21
+:106B3000A47E7A1FA750E80926F6B334C37CCF4B56
+:106B40006FF21ABB7F17ABDFE453EAB7DDA2FF3B5E
+:106B500012ADF1E1F28DCD4790857E600BCE481CE1
+:106B6000837959EF797129AEB4450A50DE1EE8F9F0
+:106B7000BE1A27B7C0C5F727F2762C3A88EC3A3709
+:106B800031D884F6CC7D89226E9F09EB9A8AEB1668
+:106B9000CF2B5A87DF31FE1CF43D3119F5D4B412E6
+:106BA0008A3F6F4B2C7D1DDBAD9A5E48B10209F721
+:106BB0009A3A9E0F27F5A51BF105F51D5A2DE1CD3B
+:106BC000E10E44D0BE684CFCF564F4B1548DCB4169
+:106BD000E59ABD24074ECD4F7CE574DB7CB8BE3B07
+:106BE000C1BFC375AFDE6DA378D272BCA73707CF24
+:106BF000034C35505E177B7233D825F4A376315D94
+:106C0000E85FEBBD377FFB7152A97D8FFB750E8D61
+:106C10008F607F9A9F517E0B22E143935E95EB7AC2
+:106C20006CBBD8FE253E257E1D5A90F0AAA3DD1030
+:106C300007AECDDD7119AE0F33A4FE4C7E3B2F02A3
+:106C40006FAB94762FDA27A0173727A25E1CDEF5EC
+:106C50006F8A8FF4693AB76742F23E01CBFD453245
+:106C60002EAFBAB95D23E15FFCC6634EF33E512CF3
+:106C7000BCB1EBA53BDF9A47E1EC9F10739F6F3DE2
+:106C80001F472B25BEB14F0838514EEA8D9106DAC9
+:106C90002B0D9AEF7701CAFFB093DD0C76B8657CB7
+:106CA000F95C27EEEF3D2CECA8D8EF1E71DF71ECFC
+:106CB000FB8F05FED61DB89BF4706FF4C303CF485D
+:106CC0005F4F2E33F0FC8C5DC0EBBD4CBFBDF1D1EE
+:106CD0002307785C571BE70CA38B153B9E6A2F0D8F
+:106CE000E0792F7504237B571DC0C7075A1A181760
+:106CF000F68E4E61434DEBECAAC1D3F9FDCB69068C
+:106D00009DBF533DB6D27876A6C4536BA2CDB23F99
+:106D10009F29F966C8EF693FC9C4371FA17E89E57D
+:106D20009B56E4E1340E87999EAB06E766C4A34FF9
+:106D3000542F72BEBA1C5F144EE0FC9E01CF2D3062
+:106D40008F16719F4615E20AFC9DCABBDCCC80758C
+:106D5000ED2B4FD117085F61DB419EEFDE9246CEEF
+:106D60005FE584F8F2B2C8CDE9B2C8CDE3A84927FF
+:106D7000023FC57BC35BDA127C0A7C6A4989AFA7F4
+:106D80000BDC52CE44FE84D65E80F688AC5F38D3EE
+:106D90003A9ECFCDD7BF01B25DE8D614B4CBA66280
+:106DA0001780C7417E85E771B42686F17E7AB06A86
+:106DB000B5DB00AF3B84FFB703FCC269D06F7A023A
+:106DC0000BE2BCD3FA40399FDA0776B9A3FDBDC9FF
+:106DD00051C6260F2ADD8EFD4DCEC81AB13C87B7AD
+:106DE000C77E0E27B006E7C828DE6F7500CBA5E08A
+:106DF000F750DF45F9D1F7875176A15E7A7A7B812A
+:106E000082FB92B6403AAE231F1DFB01E5C12EC0A6
+:106E10007B8C9C78A5844A7E52E18952BAB7EC53A8
+:106E2000FC9885F71D950E738FC1FC30EB3DA46C6B
+:106E30003B3F3F23F1D5931FB8FE013843CE140BDF
+:106E40009C6C1CC2EDE4ED62F1DBFD147C2CE909C5
+:106E5000E8B9C623E88972DA22EEC5ECE61B71AF09
+:106E60004287B80F6A76A2B817CAE0FE95BCE7A4BD
+:106E7000450B24A27D3EBB3B3F2140E78F2A5D812D
+:106E8000A4F148B763DC7F3A5DC4EFA73B6D0F24E4
+:106E9000A1BC9E3EA62AF594DFC1F33E655EDD6986
+:106EA000BB6FCDD5F07DCE3FAB817AFA6CF50B3A56
+:106EB0005860D4BFA29FD4AAD23E64CEA3B3D4E17B
+:106EC000507F2E380CA88F6617BB4368C7B5FCBE31
+:106ED000F67D5CCFE63CEDF02D83715EDB38EA0B8E
+:106EE0002C9F5AEBF13928DE9AABE0FDF14BD6E747
+:106EF00018B40FB9948938F3C4926258839FC7A11C
+:106F0000E5FE8593EE9317DFAB1B27C1FCAE4E6BFE
+:106F1000B1212AFFB0B6BA11CFB3ADA82FCDC43876
+:106F2000C25AF7E4468C23A4A707DA6E80753DE2C7
+:106F3000BEB104CB2D4FC9FEA63462DCE017B660AB
+:106F40008E02DF4FBB679550FEF520D9FF92C60039
+:106F5000AC09B37F7CD51727305F7B5D6309DA0509
+:106F60004057615FAF21F8E64D90E526BD7830B41B
+:106F70004F649678AA3D1A97A0786D4BB77DBEA155
+:106F800004E3107326D6166BD07FE1BAA71AF3413B
+:106F9000C58E6D2A320250BE7EDDA6125CFF5A58A5
+:106FA000A002ED921BD63D5D8271F9D43ED6FE5310
+:106FB00055119767DB1AB1BFC29981110AB4FF97C7
+:106FC000752F35A21F9286F9B930DE05CF9F1A437F
+:106FD000FDA3FAF396E83D5AAB510EAA9CED47305B
+:106FE000549BBDB44BE779DB426FF4E7FCDC5D1EDC
+:106FF000DACEF3EB653993975B96C5D7438F7AB9B1
+:10700000BFD99210FFFBAB42EF4879493AC1023B2E
+:10701000E3C8CD16B7FBFF48EE5AFF6FE9B5E4CBE6
+:10702000E8B564A9D7043EF3AD7A1A8611FAFEEAF0
+:107030005CD40F0B30D9CA642F14B64DA775E47B0E
+:107040005E6E3F331F6F9F56CCF39DBA5E49E4F7E7
+:10705000A43ADBF2CCFBA2C7053E8A1F9EFA049D30
+:10706000776FB3333AA7B2ABE89279A69518DF35BC
+:10707000F91F955A84FCFA4A8CEF8EC2FEDEA47387
+:10708000A6D80F9E43C17D0C8CCFA62D8F4F7F6954
+:107090004F555E3458A84FCF7537DA7F2A0B8DBA1B
+:1070A000FCBCA2FD59E30F3DFBD3C57E50CCFAA832
+:1070B000C787F3CF924F01DF36137FCD13FC26F73E
+:1070C00095CFED19B6D5BC8F2FCF87817EFE29FED7
+:1070D0000E4608F43CDA99855AE066AC5FD89642D1
+:1070E000FB4C923F245F48BAB6A4D452DCAEEB49C5
+:1070F00085CEEBC5C265F3703A166EE4F73366CC05
+:107100000CAAE6FBE4A53C40FF2DA2FFD1E3487E9C
+:1071100036737900B9B917E517EFDBC179F8DB0BE6
+:10712000CCBF3B21E1AF405E4C233A72FCBFECA2E6
+:10713000FDFED875328AFFBE97A16736D153DA417A
+:1071400095BDAE975E9EBF7822E2F561FC08F91FFF
+:10715000F549F387747F5C4BABCA141F9F37EAADC8
+:10716000C26E7DFCF5E1891AD963D1F5C3477699E2
+:10717000D49F11A7335ABF6BCDD793719F3955DC7C
+:10718000CF9CAAE211EC281C233C5C8F8D0BC68F90
+:107190008716B83D9C0E621E4F2E9DC83E84F97F17
+:1071A0004FACF3E3DA43F4FB4976C4E398283EA4FA
+:1071B0003EBBD5D1FEA238F762E14759063BA7DABC
+:1071C00036C8F4DDCDF5AE1C0FE06DC0FB98D3E002
+:1071D0008957FF5FF0E4887D77CE9727F7646CA12D
+:1071E000DF6D18141881FA46F217AC2762BEB6FBA1
+:1071F000A7BB39FF4F8F4387E982CFE66DE4F36F7A
+:10720000F98FE29B910F5ADE4A495E66E2F77AA156
+:107210005764BF529E643BF97D86E8EF5E8F979E70
+:10722000F5027F0847BCFC0AD90EE74BFA7A25D74E
+:10723000D730EF10D209E61DC273F8173C4A0C5E36
+:10724000C5FA20F05DA5039E018F3BECA1BE98AF6F
+:1072500095A6F27C98CBC92FCC47FC8E8087F44E44
+:107260006CFF6B057F6C11F7E81EB6813CA39CB9DF
+:1072700039BCE7F66451BF75A2DEE5F5E195C9CFEB
+:107280001691AF02F0533E66D5ABFDB658E1AF178D
+:10729000F00797E339C2D427987F3923BC45105FA4
+:1072A000295EBE9EB4E841B2DFBA9E64E4B70E0127
+:1072B0003BC207E59A52F74825272AA779CD0AD17C
+:1072C000B17003ACD38837A7C4DB1B3BCDE36EF0B2
+:1072D000782CF710540AFA0F81F5FDA700EF10E89B
+:1072E000E745829BC375F2F1E6EB313ED7BDDE0B7D
+:1072F000BEE8096744EFC7E1A4BC0AB4777CA3A346
+:107300007062FF94E7E32E5D86FD56FF66773F735C
+:10731000BF2F76F73B7BA20BF5D87AD0ABA40E82B9
+:1073200087F01CC9DCBDC906DEF700FE820DFD42F8
+:1073300039EE5C4DFEEE4F7B21DE779ED73D0EE8A9
+:107340004F93FE3BE071F3FACE8303F11E6DA6F17D
+:10735000F529ADE9F48F701FA2B775F56FC50F4021
+:10736000479A77D72E98972F8ABF96E659CB5CA875
+:107370002F4F303FEA4B39AF2133DBBD987F53238A
+:10738000F428E0C5867C90FACF3EB6DC67D2CF8287
+:107390007E43199737E99F0CC50D1228BFE32910CA
+:1073A0007A8B519CE0E4ABFB7ECAEFEDE0F4AA9946
+:1073B000C9E92BE5F52B4F30C58BF6E95D0F4DE4A0
+:1073C00097E146E89EE6CA0D7C1CA8D7CC486EDB48
+:1073D000B26762FE25F2D3989E744B2D6D76517B79
+:1073E000C1FF675F191E463E4CBBBDAB18DF033FB4
+:1073F000103C2DCD9E30FACB642F63FB7D0A5FBF1E
+:107400005890F03277A6E137F38984AF9BEE0CE811
+:107410003E3CFA7EC84CDE6F4D2BF4CBFB21F9A924
+:10742000BC9FF1FBA9057D80D5428E9151BD03E53E
+:107430008823258A47893FD9BEFA7EFEDB3D182F77
+:10744000403FAF86B553DCB4522DED8FFE1ACB70A2
+:10745000D0395BF07F49FF1C7631CD05ED5F872782
+:10746000AEEF93D545741E6AF22085E41C2449C60C
+:10747000CBE8F7C66EBD2191E7BD7DF5DDC1389F34
+:10748000B444CE77D08F53F4E3243B55E8C35F6711
+:10749000833E34F9A5871585FA39FCAD6BB62E57B6
+:1074A000A2F3C4FED06E38AC4CEB4FF6AC886B0048
+:1074B000DE2CF97851FE0D09B8DAB3F1BBD94F4291
+:1074C000BFA6DBCF62490FDF087ED5D829CD11BC1E
+:1074D00052BB3E947CE3F760DCC9E067B960FEFD17
+:1074E000918FD12FC809A95E846B8842F7471F4945
+:1074F00008E6F37B88F938E922EE952EF2B4D19EA6
+:10750000C7E7362F5F2F8627F1F5E5A1245E4EF7FA
+:10751000C68F933D21BED7887BBB5717C5CF071CAD
+:10752000E7B5C6396F15FB3EE06F8DF3A6F1FBE0C2
+:10753000799E32DF2702BB96F05BFCF04CDAF7BC99
+:10754000D0764712BF9F82CBFFC74AE0DFEE52F0F2
+:10755000594AF703867EAB52BEFF4746C08BF9619E
+:107560005509F1F3CFEF15705489F99FAEE3F74950
+:10757000CCC3FD48D017B70AFF6C41D36D2548EF47
+:1075800005E0BFE37EA4CC7B90F42DDBA45AF62368
+:10759000E6E17E649FBFC67FF0F7E23F8CB6F80F4E
+:1075A00072DC583FE2645DA665DF6476D320718F9C
+:1075B00007AF3F87F909EE392BFB59F64FD9CAB40B
+:1075C0002BBBE714FC86505CF874D2AFF2FDC93ACD
+:1075D000270B99E1F86430E58D8CF3061FF05AE033
+:1075E000486421331C6C02FF5D2F178F5B03DD4362
+:1075F000667B3A16AE55DEBFD64FCBED05CF79FF91
+:10760000257E5AE104AECFF05222CC81193BC96AE3
+:10761000376FF6F27572B337D16237CF9D69ADB768
+:1076200045D4DB22EA5DCEFF37DBCBCA20D41BBCBE
+:107630003FF97B3C3967DEA2BCD3F7BCDC0E389E39
+:1076400014D881F2B856E4E96FF9CBA1CC39685F60
+:10765000FCAB9DF2048A362F598E79D4EE66C5A014
+:10766000734AAD563EFAC7A5CD03E7023E5E1274DB
+:10767000AAF4F37954FA23FA6037E675F3F1FB378D
+:107680001F5034939EE85FC6EBEDF3DA2D71F703DC
+:107690005E7E8FC42FBD323E183E70532AD60F68CF
+:1076A000B8AEF4C5DFC10178FAD6323A07D57734DF
+:1076B000B7C7FE71F416057F974BCE73A56D5ABE02
+:1076C00001ED56A627FA514F671BC1D7719E95EF62
+:1076D000452218BE19FB5E9B86FE92DF081C457E84
+:1076E00095F3F2A9465F5C6F12DFE3F03575C721B1
+:1076F000B89E666C8DF05FB6723B56654719B773DE
+:1077000069BF367DD9505A2FE47CD25384BE4D6771
+:10771000C1DD646FB395B4DE39F9FA99BE8CFF8E82
+:107720009EA467347E326C24C64F06AD8D68B3A12B
+:10773000DDAB9B6C71EFDD3825F00EF3F800E71739
+:107740004B9F5ED71D51CFDE4B5C4AF27BE294F833
+:10775000FE1E638FD0F7A2CDA9F7905C36E8744F78
+:10776000A2C4BFDF28FD23C2D3B7798B82B83929E1
+:10777000F2194EAEFEA982F6D6771732438DC34F6B
+:10778000DDF2BA74F7C0B9267D03FD133DB6C4E43B
+:10779000A74BFFC49DC4F5F83CA3544D4AA37C619C
+:1077A0008AE32DDCCE7F8FA3577C5C21BE9432EE22
+:1077B000C754CEE0BF475AB459237A5734F0DF2379
+:1077C000ACDCB98BCEE3B187981FE5BDB2799732B7
+:1077D00017C6ADD8B94B9967C25FBFCA30E5755FB0
+:1077E000E59171EA08DD3B16CBD718DFC7F5FD88B8
+:1077F0008BCB7B47913B8471EB0E7BB012EB7564B6
+:1078000025FA717F54E2FBF55D37D2FD079EDD8ED0
+:10781000083E57DAB6663AA1DECAAB753FF291DF91
+:10782000080E45BCA468A52DD83E39D5E3C7B8B726
+:10783000CFC146D23A778578181BC30F631FE27217
+:10784000724F9257DA59946F3531C923ED0ED24FEA
+:1078500047EC7C1EBB1987779B373016E16147F9EF
+:10786000EF29F4AD8C2898A7123B6E949F02DF4A53
+:10787000FA06FC0DF6928E7ABD42E899A2CDDB9510
+:107880000F4D704F456304F973E71605E32AF09D29
+:10789000F40CD467980FD577278F2755C0F7792632
+:1078A000BD22E71147BFDC86F0B9DF6B7B8DEB971C
+:1078B000088F230B7863E9797F12B7DB4A6059A5FB
+:1078C000F77A6828FA9B477213A83F29EFB1F2793B
+:1078D000BFE0F3BE9BB62B3637C5DBC9FE92F0C9BD
+:1078E0007AC79326CE491A837868233C546DD268B0
+:1078F0003E93F5D2C18B4CF2B048F477F0AEF7E985
+:107900005EA00D3F3F46FC58D5A470BBBFE9987EF2
+:1079100007AE2BA1E754DC1FB9992FE5EC71715F1D
+:10792000D6CD2D5CFF56B5ECD2F07E49C9A739679C
+:107930000ED23D5B55CD0E86FBA5C07FDF43FCC458
+:10794000F2A9C48FD4AFBDD113F4103FA710D24514
+:107950009C3A9833DD13D5CFDBBC627FD4CDDF6F8B
+:1079600048E2E528FF04572559F4AB8BE422E7CC25
+:10797000C883980F5AE557E85C656AB1F87D321301
+:107980005CE6F331B1FA11E3E13C7ED29E3DDD7459
+:107990003EAE5BCF8BF64F20BDF9FB087FCF7271F7
+:1079A000BD96F0C7D2EF90B0C7E3F0593829CE3A70
+:1079B00026D7F59CA7776B788F92E49F9B91EE2654
+:1079C000FEF95912BF8FF767491AF5FF7811DFA743
+:1079D0007ADCCED7AFC7EB9D94BFF9FADD3C9FCCE4
+:1079E000738F1EC1E761DBEC4AFC7EB82F8763A56D
+:1079F0006D199DF703B96C4E22FEF132AE1FB93EF0
+:107A0000DCF012D767952137DD775A19BC7D2EE55A
+:107A1000D9A6BAFC743F68F035FD0E4F4FBEF2EDAB
+:107A20003E40BF8B7C7333973F4907D0A7C45F525A
+:107A30001E245EA3F8E47897F224E9B14DEE0B0022
+:107A4000BF70FB88FB23F94CA5FD9F3267E0089EC1
+:107A5000CB2C13FBA5F9E2775FE47EE96C4197023A
+:107A60005BE9AF719E3DF64BAFD0AEAE58FAAB615D
+:107A7000180F29CF3C4A4F29B7E0F759E4FB7D4165
+:107A8000F7C3E2F9B1E09B8AD1CD2497151FD592B7
+:107A90003CBBA770BDE67ECFAA8F195B27E6BB96DD
+:107AA000DA4F4E6C2EC1FDC6C93F560CF4877B835E
+:107AB00073019E5343FF68D321EF2CC4AFF87D2997
+:107AC000799EE70BA1273A76A8E2F7366BF54BD9FA
+:107AD000DF97EB8F458E2B74EF89F0A93A76168FDE
+:107AE000FF18FDBA1D49F4FB279FEDBCEDFB1FA756
+:107AF000E2EF8BDCE0473B21757929F14F579ACBB8
+:107B0000BF95C73DA7605CA7BEF99017CFFFFC6F7C
+:107B10005968C8A800800000000000001F8B080002
+:107B200000000000000BD57D097854D5D9F0B97359
+:107B3000670B994966267BC832091050499884849E
+:107B40007D9924844516270805641BF600D958DA68
+:107B500062A57F068388886D68AD225ABF01C16225
+:107B6000B53560A441020EB208553F470A165BB412
+:107B70002322B284648AADA55FF93EFEF3BEE79C82
+:107B8000CCDC9B09A85FDBE7FFC3E3733CF7DC7B3E
+:107B900096F7BCFBFB9E33975FEE5760B01362B65F
+:107BA00068084920E4CA6BF21AAF8990877FF1EA2E
+:107BB00088A185842CF74A71064248EBEEFFF89FB6
+:107BC000D478422A76D658245AAF7FF94D7D80BEAC
+:107BD000A7F16E67CF77C75AE0BDCB2F6C1941FA7A
+:107BE000D2F6C67A6CBFF2C276ACBFF58B570FFDEA
+:107BF000177DAFD215E380F7AEBC76580FCF2BDDE3
+:107C00005A67232D89FBA87EAA99969E976492486D
+:107C1000C878C2FE9EDA73586FCFA5F5463A2AFDA2
+:107C20009E4CD77B7B65D1EF1AF7681798E00D2F34
+:107C3000214574DC5FCC1DEC867A335D444AE8F95B
+:107C4000463DF1186DB4EC4648142DAF169B3C52DE
+:107C50002C5D5789692394577F15351DD65BAD0F71
+:107C6000E458613E7D8913EADD011E4530CE0A5D90
+:107C7000B509BFC77E3ED41102652EF1908B7DE819
+:107C8000FA09D979AB3F8CF76B841F7D6F50540193
+:107C900021D3667D2AC17CA2FBD6EA96E33C5F66CF
+:107CA000ED74D5E1ED0356D3F1E8B8B7E06F64A801
+:107CB0002CB298F07D0A102C539BCAD3ECB0FE78FE
+:107CC0008303D62FD6975AE1AE37D3E7F7AE763B8C
+:107CD00064BA8F6F5C3A35BA3BADFFA28FD45F8632
+:107CE000D76569AE8BF65FED31E138556B4AC867F1
+:107CF00074BE636017E9F78916123F84AEA74C4B38
+:107D0000E24D5012725A5700FDEFC276BB8138091E
+:107D1000C503FB9BD376ADA39F3CA573A714413F3E
+:107D20001BFD7A3B943BD9FCE9F7165301F6671922
+:107D300002DF1BC94AF8AE7DDD84F84D12F6EBD7A1
+:107D4000D942F3262498313597F55708701AEB99E4
+:107D50000EEF13BB1ED777055EC17DF4E4CDCE8553
+:107D6000F209365F0D7103BE24EA69897075679563
+:107D700053BC596429765B8A42656237D6AE86EB7E
+:107D80004E68A7F0BC6071624976C71132B8F37BC8
+:107D9000A214F07F6B5A9B3E40C77DF2C0A788B704
+:107DA000D580B730BEFB821ED621F076217C42F70B
+:107DB000E1A9FD9F22DE2E6C96103ED5CDC5FA05B9
+:107DC000B4BC5AE7249F69699DE3DF53526031E0F8
+:107DD000B5677F94651785539BC0CF864F2FCAF434
+:107DE0007976738A5D82E7FB199E1ED3683C00A7F3
+:107DF000633BEED95E2F85CF731DC247AA2048276B
+:107E0000D5B5C46BA0EDC53F5F7D6A1CAD5755105D
+:107E100007D079B50A8FB29E3FBF01F0C55A490A13
+:107E2000A3ECB0CE4F4677A7FD57579222A0D3D4EC
+:107E300051CEFD5027CD12E905F50AD74218FFDED5
+:107E4000F8A50E99F66F1DE56A82F1EE8D1FEE9092
+:107E5000697F4FA5376E30D2764F19B1EC0238E802
+:107E60001A4AB4B4FE5499DD422149E1B63319DA15
+:107E7000491FBD6317E0B17B6125F4579D3CD301D9
+:107E800078D289FEF7AFEB03F3ADB6777344D1F741
+:107E9000C7374B8857C4632230FF6A0A5FA88FF741
+:107EA0000EF5C27CAE71F80938B6E9FC73607E6DE0
+:107EB000AF1B8887B68F1FC5F0D53AAA11F9C7DB6B
+:107EC000FBC79C90F2427869DE67F041DDA6B548B9
+:107ED0000EE04BE47E03CC67019F4F838ECC75D1BF
+:107EE000EFAC63593F3D364BC82F7E0DF49400A58F
+:107EF00086977A8EE70DACB478F25C141FAEF1FD74
+:107F00004734A1FD2EE7F852B5D087F454F90AEBB7
+:107F10002FDEE0CC5F1586BFF1A504E978771499D0
+:107F20005B4E9FEFB6B2528DAFA7395D673DBF1272
+:107F3000F77D01DD77D8D7D4CDF439C08DE205C007
+:107F40008DEE23E2C1BDF14B70DF166C961EC07D35
+:107F5000F40C20504F8863EB54F77F96F3C5DD5146
+:107F6000AE4289F6174C303B7648301FA7260AEA06
+:107F7000F956C70E02DFBB76C2780949518EFA3036
+:107F80007E4588AB5043C7B9946866FBED7D5F3B87
+:107F90003917E8D18EED0932F111E43F24DB951B4E
+:107FA000FAAEAC07EBAF8CF737A1C19347B2193CDF
+:107FB000102E1C1EDE75DDA687F3D34F383CBC7730
+:107FC00091E9C0378EE989C908FD5BE838B4BFC4C0
+:107FD0001D435FD884F3ABC77D7BDB62C1B22CCE7F
+:107FE00055580B2CB8876B35C045AC530D8F451CCD
+:107FF0001E6F4D9B93AF013C9E627200DD3D794048
+:108000009A8F78ED3152A204BC677448E87E005D17
+:1080100010B716F7A3BAD6E58D8CF7E54867D5F10A
+:10802000518E2809F1DE89F2CF63F232BC67F22F5C
+:108030007A2C9357C027CB733BF303C16740BE0133
+:108040003E0BBAA81E11C881FDFDBA7CA54DC7E83C
+:10805000BC8DC201E848D08DF90D462F9BD6D98B37
+:10806000A17D13A5FBF0FD3EAEF720FD1ECFEEE691
+:10807000807E619E2E7388BF67585C362B8577B5EE
+:10808000C6B7419B15E2C7D56F3C96E38E807F82D1
+:108090001F1BB58CCF19BDD15ED62F1BCF48C16D2C
+:1080A0002EC0D203F2287A0D838FBA9F5E56215FCD
+:1080B0008D960B548E4FA29B14DB8390B11A772FB1
+:1080C0002BEDA7CA18384E779664AC09EA611E8971
+:1080D00020BB807E76447B816F252612F7DE08FD6B
+:1080E0002659191F10FBD26063749418C3DE2FB693
+:1080F00032FE50686578792F2FC5FC05FEDB35EE22
+:108100004F89DCB51C13DFD17961BB980FFD7E234D
+:1081100061F217E79BF870CE8E4D61FB11A2A3BBF5
+:108120000A609F7A6CF669E79B42E30879AADE7FD2
+:10813000983FD00FACA7BC6FD7EF351C66F4A8C62C
+:10814000C772CE1763AD84BDA7F3FD15E96A8599A3
+:10815000EC80F96D25CE383AAF9A43BD193D38838E
+:1081600039D0FF119BFB15D88F81A3389ED3E7939D
+:10817000E9F3E55AE231D03D59BE5BE70D1819CD60
+:10818000DCA2FF95D858FFED66A347A6787EC6E629
+:1081900076037E794A88C30772E907947F00FD1150
+:1081A0005F11F0971A1288013857CBFE1C42F77FF7
+:1081B000B0C9BD08C63BAFF167C073420288AFE7E4
+:1081C000A262F208EDAF49EF4BFF3ECCFBA44C7628
+:1081D000D07EAE13E77858C775BFC6E6A1EBF8B8F6
+:1081E000F977BF3A40BF9A7DE0DAEC87004A9BA25C
+:1081F000E73C4BCB59468D51DB3F048F73E6C8FCFF
+:10820000F5871C7F12EA99DE155C67F0027CD4EFDB
+:108210004DB0B1FDAFB9914A3C71E1CF191FADD15D
+:1082200006F5A042D6DCC8201E3AEEC71A52D11875
+:1082300041CF0C5819FF6AA2A81FA9FD738E67BB16
+:108240007524672BCC673BE583003FAD1DF945C521
+:108250004FB31C9B68B5293B781CF488E0CF24E41D
+:10826000FFE7748CEFD0BF29C60121F909EA09E8BC
+:108270008715168F4F43F946C56AB34FCEC3E7DA69
+:1082800061B0771E8B16F8E07C2E1717D4BEFD77F1
+:108290002986B66B897118FDEE0BD3C218100B8BB3
+:1082A000BFBB2A1194EFA4590D489F848CB2803E25
+:1082B0002E3927C8B7A26FA7CF69516F477CA1FBA2
+:1082C000EBB2B95E80FD9E15CBE03D6B55B4D71384
+:1082D000C6FFA671F8A8F16C37E0289DEF2712932E
+:1082E0002BEA715EB595DC07789714E3FA35F6BF93
+:1082F000EA9A829FB54981179F057C5C6176EC62A2
+:10830000DD66B8C2E8E51D31EE0D0DEE5F7BBE3FC8
+:10831000674D16E07D30E3F714CECB5B0C168F1D56
+:10832000DAF58AFD3F5F47195F4EA83EFF52CFD175
+:10833000C404F0776C007C58B0319A78FA84D60186
+:108340000A37E077F50D82FDCC6F79FB2CF0F36AEC
+:108350006D00F167BED184FB537D438BF3201B7509
+:10836000AD01F13D95BFFD629C2791BE1E1D66BD0E
+:10837000780F7D98449FE3FADDEFC3BA9F8E8E217C
+:108380004E462FDEDE74FED78DF6581B85578D9E28
+:10839000E2473FECC6650CD3AF489A59B9FF2D2789
+:1083A000FF0EF3596874EB41DE2F9A5EAB07BA9C5F
+:1083B00015EB2BB2F40DDFF761F2AD7BBEFEBE37DD
+:1083C000713EF4B19ED245043AFC9CC37F02E02486
+:1083D0005DDFC7A98C7E3ECE20157BA1BC9B96F4A9
+:1083E000BB8FB379BD80D5D5FD44D9183D7F9CC7DF
+:1083F000E4956725931FEAF7FEC1C773D99C5F0216
+:108400003CC573A78D3D7FD5E6FC0A9E537EF85F81
+:108410001C5F7D56DADFAC370D88AF647D3007F620
+:10842000B1635D397CBE8991E7956163FC98F62B59
+:10843000D98AF03D27EAED87A2BC60879009943F76
+:10844000033F5E994E801FD371A36CAC5F9F15DF15
+:1084500033E03AC846CAA729DEB617D9715F361588
+:1084600053FC043E71D060013E21F049E0911A7F37
+:10847000126D42FE31397C1FC86119E570A28DC9A9
+:10848000613DD039ED51CFF4C19EB8DF8867F2D796
+:10849000DFEF3D46B68F94DEED3694FBBEDC707A9E
+:1084A0001370167CF2E36E4ABCD8CDF9601F0EB78C
+:1084B0000E38DBD87BF13D98DC13F6C120BEAE57F9
+:1084C000383F17A5906303C72AF59257B85EF08A24
+:1084D0003546EC4B21AC5FC8BF4EFBFD1CDB6FFA91
+:1084E000DE6058CF2C43704E1C955FDFA17A91BEA1
+:1084F00000BF6B82EF3AF9294631B95BB3D24C40E9
+:108500002F28B55918FC0B8319D01FE913443E34AA
+:108510009F507E23DD79FFC02790426964690C93E8
+:108520003B924C07049AE943ECD01F85F7245B513A
+:1085300008DEEAF1CE4113D503A7DB242DEE573E2A
+:10854000C987FD9AF3C197E6D9B4CB6B16A347430D
+:10855000E5C87735EE59D04FEB832751EF3FA7F7AA
+:10856000E5349822B4EB7DCF3F2D85DAE7BE247B3E
+:10857000F494CF34F95B7F368DE2E57CBFEC80214B
+:10858000E7AFFDEB7B03419FF6EB1C60D7527D62AA
+:10859000B316E65DCBF4CF731AE5FE5FFD1EDB5F1D
+:1085A000517F90E30BD5B3B46440885F093D6129E6
+:1085B000F1F5027D620171EAA13CBF62C90442E1AA
+:1085C000B7C8B41AF9D8E595E3507F5E4C3CD8BEE5
+:1085D00060A3EE7CB87C59D4A0AC2FD9AAAC2FF5FF
+:1085E0002AEB42FF4A288DAC57BCC8F9D0552A2E39
+:1085F0006EA7576CE1785BFAE884A791FEFD3A62BA
+:10860000A0EFAD3E589C4422F42BCA9A1BD9C41B40
+:10861000268742FA470EF1F687FE6EA23FF079AE4A
+:108620009F407F60EFAE8E7226815D72B524F2BCF2
+:10863000B7F179D7DCE8A6E8FFF94E7A4E0C8E53F5
+:1086400073C38865E77998F0FBAB8B238FB3BB438B
+:108650009FB228E469E8FB7826FFB83D2FF0A1E639
+:1086600046323E1775A16787BE4BC3FEA860B35C58
+:108670008C0EF1235D37360F81FF9F49C49882FE2F
+:10868000B12DDC2E71E4819EFB19E851407F63EC33
+:108690008702748A0B1E1A9CA3CD0ED1877A1D14F3
+:1086A0008FAE04C2E4FB219B391EE5B28338605CC7
+:1086B00081DF731E2C8B75D3F9FE696D6992BB6FD8
+:1086C00038DFF4E0F8D57AA1BF9914F298A8E4F560
+:1086D00082E693A89F2D34BA7280C97C7EF041C493
+:1086E000EFC5C4950878DD7EB07786FB7F21A7C5EE
+:1086F0007CEEF7CCD3317D9C122DA5B7C97C3EF71B
+:10870000B730FD506374EA701C27B15B12D1E46688
+:10871000F3A5CC524BEBC33BE60FCE434286F1F9B7
+:108720004BF03D85EF705E92F9EE6498B701C6A5F7
+:10873000E345116F3294F5831D7628474A2E2D9B11
+:1087400007DBE7D1A4360DDED71803325B279D4146
+:10875000227CDF012FAC9B797DFD94EB7316C173F6
+:108760009319F9869ECFE316F03F23F21323ACDB77
+:1087700060F25D86759979E92961FAB6279B38EA36
+:10878000E96BDD482381714DA66B1E58AC855824DA
+:10879000A84759AEFBC0EEB866317934FD902FCAB8
+:1087A00071147EADD2BB8B615F281F667EA8AEDAE6
+:1087B000B53EB477045FB3F1F9D573BE9642181C89
+:1087C000E289EBB093F2859F98174F2031208EDD20
+:1087D00038FE3331634FC07C01F028AFC76ACF87C2
+:1087E000CB8B049756C1B792A62BEB296E65DD485B
+:1087F000CE59007F259F2BF9561CDA717DC02FA31F
+:10880000E3FC624A37362F813FD9711A853EE1E297
+:10881000767DB54D4FD01F986834927EA85F64C7AF
+:1088200031FDE213BAD3D4FE0B221FCE1FE9ECF5C3
+:10883000330AE70D1FC88E87E93E6D30DBD76941EB
+:108840006F9B21313D5DDBE8033FCFF63956C726EC
+:10885000688F72FEF8BFA1FD039980DE5403FE7598
+:10886000A4774B317CB73DC382EFC59706D12F1A51
+:108870007C8CA05ED4094F6FD2F95378BF00750A83
+:10888000DF9A8596E5AFD0F7535CD10E29AC7D27F2
+:10889000B4D3794A1C2FE0F9C80160C7B2BF1E2DBE
+:1088A000F97E27F8299C32CAB59A96FC23263A8F7E
+:1088B0001EEE7C07A06DCF161E47893778591C81A4
+:1088C000522D9DC754239B474D4BF17D45B4BDA709
+:1088D000BF3F817842F409FBCC4A68D250FB19BEF5
+:1088E0002B8946FFD569EE47229C1F0C54D1DBD063
+:1088F00010FE637BBEA853F1EF1CC0DC13588F67DA
+:1089000074E020E28FD1E71012FA83EF4B43FD2190
+:108910003F1A156A0ED11B5D5A81D1515F49DF3B69
+:10892000563E06F1B006EC27BA1F03B5BEC340DFC2
+:10893000437999CF4B32BF01E1B9699D5306B8170E
+:1089400011B7BC85D60719FD71400FC38C8175091D
+:10895000B4BFC1D3E72543FD20285945A86779C096
+:108960003F6F3569BCEB7013F31D4037D3A6333F1F
+:10897000EBD4E9462FF8EDA76A098B6F69DD59DF63
+:10898000A1EDDF99C5FCBB509F15E63F11F18CD3DB
+:10899000D41ED913C19E3C18C7E493F8BE66BD5ED1
+:1089A0001137DA1F67C2F6FF881BBD360EF1DF9D57
+:1089B00005F4F7701CD7ABFA903EC057C2E87E03AF
+:1089C000BCD75AFC4E577C41D9CEF9C254E74F75FB
+:1089D000A88F73FE20F8B00BE8907EE7979C3A8052
+:1089E000E747250CFEA78A97227F9846DCF89C2251
+:1089F00088CE15EE371A1BA6C7D071A6BA947ACDC9
+:108A0000B4E96A3D87E1AB1877865BD93E59E8A99E
+:108A100063957AEAACEFDFB4A2FC4D7AB1EA562650
+:108A2000C649D0DEAFA1FBC4E2245A163759AFF7CE
+:108A300082BE53D3BCE25802D0D15AC2E9688FB487
+:108A400010E3387BA44561FA43F74AAF047CBF3793
+:108A50005D931FF73588F1A1D33AEF61889B9C5E47
+:108A60004A574CE77944CFE28F47A38807FCCF02EF
+:108A70003FCD9399FF94A231C641D22CD10ED0CBD9
+:108A8000376A0AD0DFBA31C6EC08F76F6E5AE72EA4
+:108A90000BF7B3DA0DA4C0C2F126921D7B8CF3C391
+:108AA000A724E6EFF6CC30A2DD96D0C3A5882F240C
+:108AB000C8E42CF80DD7C6D951DE3EC5FD1A109F6B
+:108AC000EB4F4BAF4405627CD8F732598F7E461589
+:108AD000FF498873A07F3F213617FDF4D35BF277FF
+:108AE00022BF3145397A49A1FEA7BBB76B1781FE7A
+:108AF000D4B25DBBD014C2BBB3025FA34934E06BF8
+:108B000087DF6EAF01FD76DFD5B8CE015E56EA7D18
+:108B1000794489CFF8BC2B39B684E38BAEC4356376
+:108B2000119D4FFB7B7AE6C75A4B905E5FDB6F452A
+:108B3000BFA376324179B2BE98203EB46F97504FB2
+:108B4000FEC25A81FAFB7AA901E5449B6D34EEDF3F
+:108B500032D351B44F2B9ED39D0FD7BB96ED54D635
+:108B600097133FDAC795AF74C267E45F823F563709
+:108B700029BF233D95FC319FF3FD0297E3FE329818
+:108B8000FA74470F661F139F81AEA3E85D3DF7F7A8
+:108B9000CE627293BC2881BED56EBE24333A67FC88
+:108BA000B888F7A79643455C9F1A41F916D89142B9
+:108BB0003FA2EF63FDA8A6454ED684E655C8BF1375
+:108BC0007A99E0DB625F8A07812D4C48463CD76F7B
+:108BD000B24936EC2BED1FE9818EEBD1DBB07F0F74
+:108BE000D85F43F97874DF3D20673D1AA317F0681A
+:108BF00083548B7CDA4838BF96DCF5F0F16F3C1E6D
+:108C0000E4DB8349EDFD13B2805FFBA3011E141F5B
+:108C1000B2E3C3F0A49EF832F6480A7CC1F656EBE4
+:108C20003B11F145C817DF474CBF184F570CFD9457
+:108C300041E08696472566CF8D313DA985EFDFD18E
+:108C40008C437C184BBC5A985F9945B9CF63929579
+:108C5000F571F64E7820C3B84E0ECFF17D94ED4EEF
+:108C6000C1D78892AF65919BB8CFE4B1E3DF05FB34
+:108C70003E7A0DE9037A07D51091DED4FC6054BC2E
+:108C800049A11F85C53D46C527748E7BB4733FEE51
+:108C9000101258FC8AD4195FDA8EAD9193C3F04A52
+:108CA000E0F11B3C4F427A93C7570B995F2F24E7A3
+:108CB00019BE0CE0B521806FF4FD45024F32492604
+:108CC000E0C9F0E6289F4CE19ACFFB1902785310D7
+:108CD00092E73E8DC9AECF06FC706C94E5CE7A7BF0
+:108CE000A2CD8E78D25F23E4BB238EA07C6FACD75D
+:108CF000C2FCF70FECEE3629F06229E28544F1025E
+:108D0000E9AA935C54B6ABF046ECDF09AE2F8F2195
+:108D10009E9E301E656347415FF66531BC29234E38
+:108D2000C493B7B3C7F1F8B35B8BFD10A53C2C35EA
+:108D30002AF1408D5774444DF8B86A3CEB0A6F3203
+:108D4000016F843C8CBB33DE3CDE35DE3C7E3BBCBD
+:108D500051E38BE0277BA22CA5A097D65448C88767
+:108D6000FBBFD7B31EEABDABB2308F658FD5817A1A
+:108D70006B4D2D6B2FF43B65C873E9B19AB767B99A
+:108D80004AA15EB386C51B8A4EB33C989E6B597B45
+:108D9000FEC3B547CC20DF3DECFB372E6F906368F8
+:108DA000BB7703FFBEB8A114EA351BD9F75F40BCFF
+:108DB00088EEEF80B3DE7A787ED7E62C07333F99D2
+:108DC0003E3B92E3E91E69EF11FCAE817DB7E4B84A
+:108DD000B11B413D98E9AD23F83A473EC7D619FF8C
+:108DE000D9BD63ED147F17053DA8375DD4540E40FF
+:108DF0007ED3859D592C35A44149F106F98CD34881
+:108E0000F13A9BC51377D021DE8E677AA088C341E3
+:108E10005E40781EC0DBF14CDE8BF7126D84C58D91
+:108E2000B799D1AF2BE284BEA7890474066BE4F234
+:108E30003F62DC704C8F5A8C178EC914F1C2807659
+:108E40003E1D37FFD697A323F951FE938F7B89E709
+:108E50003988E715DE2C0DE0C51E4092540052F50E
+:108E60006F416FDA037E5426343C6410EC2BAB9FC9
+:108E70008B5FB6692335D297686AB51E103219D454
+:108E8000FEA25D4FF2135F6C4CE7F98FD1121FC841
+:108E900027A265F35F5C4FE5A014E24B5305DB1995
+:108EA000D60BE9740ADFA7CBF15CDFE84FFA03BF0A
+:108EB00099CAF7ED3BC65A1D93970D3A15FD5F43CE
+:108EC000FA7FA64BBD59D9AEE20F157CDCC55C5FBD
+:108ED0005E4A82A8175C94BC585E7A86E9CBCB4D7B
+:108EE000A751AF68DFC6F4C44A1240BD43EDF75B3B
+:108EF000BE5B59AF6A54D66B9A95F5F65C0F8ED36C
+:108F0000FE4CD500F0BF556C7D0FFDBB15824F7830
+:108F1000957C822A488C4F3C7D37FA6D3446CA27AF
+:108F20000A015CDD306FA43F71C6013F00217B8BDD
+:108F3000D61F834F52685DE38A49403FD6D8B80BAD
+:108F4000627C19E3B2EF39EDA17DE9B00B557C22CB
+:108F50005FF8637ADAD05F25F8463E617242AD175A
+:108F6000F54950DA3942AFC807BD82E2855F63F246
+:108F70006A34E17A8417E98FDA8BE3A3B201655C86
+:108F800032D4FBCF2834F27D27AA7DED9B707B7B0A
+:108F900049D9AEDA7761AF0CE0FB3E83B8BBC33E84
+:108FA0004C21AE6320174E7D54A1B0933EFAC368A6
+:108FB000E147417BE99BDB494EF9DBD8491DFB1DAD
+:108FC00045F5465A964E1ED7EB6710DF6E8AC2BC37
+:108FD000CD1A89ED6FE28CD319E17EC3537524411C
+:108FE0001B46EFF5E30C4688EFD5EB981D3179FC75
+:108FF000C703E687F18B178CC52E80D706C9FFBD46
+:109000003F825D7152269817D39280FB7DBD813ED1
+:10901000A77876FDB97B1C1EFAF8AA8EC50BBF9007
+:109020006A17432A9398C7E235BF8DD252F9752546
+:10903000FA10C683CFE8DDB301EF96BDB30FFD9103
+:1090400095A077F708F5DBB5DFD1837689FE2D266D
+:109050000783523707E625104F4E789C685622E367
+:10906000AF676CAEA5307F21E784DFFFDC8A31B1CA
+:10907000200AFE429CB1109F94284CBADB3A8F071D
+:10908000F900EBC3FCCCE7A294F105517E2F81F9E6
+:10909000BFF7012DD1F1D2ACCEEFC3FA2E717BEF29
+:1090A000128F535D8A6171AB871318FFDDC7BFDB79
+:1090B000CACB4B3CAE75C9A6B413C57BDBF877179A
+:1090C000EA8CC6F561FB687FDA50EBC53C289EF759
+:1090D000B19A30BB68BF75FBA6B0F8C1AE84E27D23
+:1090E00030AF841E4E7D0AC06F3F93BB1047867819
+:1090F000EF308BBB01E0556D274E8897127B407F88
+:109100003FC40DC1CE447D81E1497B142BC5BC76A3
+:109110002594EF4338AF0820DFEAA897337EB82BB9
+:10912000C185E3B64F15EDBCFE04AB13EE2F10FE68
+:10913000EBAEE258EAB815CC18F5EA28C6B7D4F178
+:10914000EAD9826FF178F52CCE8766B7307FF81CAC
+:1091500023D9D09DB6CF6D4962F6618C274711AFF8
+:10916000F6447FA33C05819FEDE9FE8E38EBB6B057
+:10917000386B158FD35589F53529D77724A1CB388E
+:10918000EB9184087156753C7F1FC8F39E2178AE21
+:10919000B4B0F597C995A57AE00F0B09E67FAF3C0F
+:1091A000B9A0DE48EB2B1F034F1FF221D44FAB3881
+:1091B000BCBA9A5F824B43EC0ABF7037620FB3832D
+:1091C00053DC36451D35DEB0FCC9EE15A98AEFD358
+:1091D0006BB315EF67AEB95BD19EE52950D47B6CBC
+:1091E0001CA278BF574389A2DE7BEBBD8AF7F34907
+:1091F000762CFA8F4EC8E01B217779272BDAEFD92E
+:10920000FD80E2FB2F48ED53C3E87B4D518CFF13EB
+:109210008FD3DF7740285F38B771BEE2FB7AA97140
+:10922000808FBEBFD0CFFCEBFD9A9729FABB1A33D3
+:109230009AD90D3C4E584BFF31FE6D9751FF699600
+:10924000C836A973DCB0A265CB86EE2452FC90C967
+:10925000F56554AE83DEA4D62B0C893C8E944A521D
+:109260006F85D155080F4CA8775D7F4E46FF593E5C
+:10927000C9797A18C24747BCF6CEFB759D30BFCE80
+:10928000F557CC0EF08F2D39B900F1CF90ACC483D7
+:1092900028BB120FA2FB28F1C0EC50EE7BEC20E5BE
+:1092A000BEABE16C752AF140C051C0396EAC122FD3
+:1092B000047C07D17F00DF02123C8EF9D15EC9E148
+:1092C0002311E2B2CDDB711D77D2D3F255F0EC7FE2
+:1092D000D4596F4238B17C29A11719B85EA2F69310
+:1092E00077F85712B9DEC3FB117EED0D9207F59C9E
+:1092F0008EF8D5205F862F0BF49D5AC2FC23AEB2A8
+:10930000C4C87E347CDE951F4DC051E831CB418FFF
+:10931000A1E32C226EE44B17B81EB3C4F424C6019B
+:10932000AFFE81C1B78278915F7FE3B836D50B4934
+:10933000987F510D47A945F299810E38DF4E252DB2
+:10934000826FBB31DF81A29D7180229EA0D43B89B8
+:10935000530AE74F420F15E309780ABE25C633903A
+:109360005A3919E840C5C7481F753C43E9E7107EE4
+:10937000111C2C2C6E31B0231EC1ECC2909F8BF9B6
+:1093800035E4CCAC7A02FAB645F831FC33E1B9F0F9
+:1093900063A8EDF93BC541EFF7488167B33AC73F92
+:1093A000453C952EF3B33FD28F8749F674186FF280
+:1093B0001BBD138826921FCE71F600ED47D604E33D
+:1093C000C2FD63C25FFDB614C0797F87381F21617B
+:1093D000FA4235691C3D330BFC9D546EC540C9FCF7
+:1093E0003CA459AD8FB2F8A186AE04F07B39098B4D
+:1093F0000F6685DAB12E77AE8BFC943BC9F75E49D8
+:1094000016712E2587B533FE26ECB5AEEC2311BFC1
+:109410003FA6A7302908E5A33426723F561EC9830C
+:10942000FE295D352526803D4EE9500AA7BB8EFCFE
+:10943000156CEF4477AAF58BF8BD6C2E443FCB82B8
+:10944000F0F57E0D78083DE2065D1BACF7478976A6
+:109450002CABBA9DFBD009CD857E451E628D9EE565
+:10946000FD9246A5FE7C3651C459999D71273875E9
+:10947000BD0F3C9F8BEFC3D7D587443E9780DF2736
+:10948000820F86E07D5E01CF0E7BAD03DEE723C158
+:109490005BC0E35A91FF45D827D97C3A11E09C1470
+:1094A000E3FA02F862FAD9C04549139A5799DC8A5F
+:1094B000799CD79B65B48FAA87B37C9EEAFD18245C
+:1094C000276D2D068C0356341F41FDACB58E32D26C
+:1094D0009E5DC3A963BD2A787765AF88F5DC52AD80
+:1094E0005FE487407C3FA9E8B67050B67338887C4B
+:1094F0009632B96F6C20CC2EF1F17D8FD2BAA29248
+:10950000E8F885BF4B8B01F894C92DC753010EAB0A
+:10951000253C6734D2403CE0DF4FE1E7CD06056AE9
+:109520001D160A8FE434139E1BEAFD5DD905F1CBAD
+:109530008F57AFB2C1B9A82B7574686A77F49634A7
+:109540002EC437B2F7931F14425C6D16E617CF3660
+:10955000B0787FD6F7A27D3D289F78534F8C406F1F
+:10956000BAEC5A3C5711B4CA686FC4CB6414E09784
+:1095700080737C345B87785EFCF39D12E42189E77D
+:1095800023EB83FD57D2F273D8F784D03A4796067F
+:10959000FBD79A427016F97D441BCC981C461F4796
+:1095A000383CAA13F41B401EB619B91DC8ED416220
+:1095B000D1221F59CDE3EBE77A11E2C77E7C66C862
+:1095C000A7AA8E72C60E04FF16E40FD0E22F16670C
+:1095D000AC15D76F47BD7935D7AFDA787EF6EA712B
+:1095E0002549604F25D447CE631A9DC4F4FC4A1E1A
+:1095F000F716CF2BB53ECC47AA847CE1B0FCA86F10
+:109600009A2F2CF2C4BB8483554BB4140ED512711F
+:10961000DDEEBD03FF2347B477AB9234B7CD635B78
+:10962000C8D727F2D3AA213F8D3E5ABDBF388944FF
+:10963000E8AF43DEDC18A2C80B13F9CDD53746607E
+:109640005E58E9A3AD78BE0FFAB19B4279695DC15E
+:10965000F948229B4735E48BF50F7FCEF847A8FFEA
+:1096600078DC875F0200C1CFD12CA31FF697273487
+:1096700063774498EF16BEFEBB13B4481FF7F88813
+:10968000737B84F1C57BE2FC07C0B93CB7F3FC9A5D
+:109690004A027360FE90771A69BCF549CCCE16F386
+:1096A0006EB20516733CC7F3171D758B721F5FE012
+:1096B000FBD8746F2003CF118D8B9C072FF6FBA670
+:1096C000D9FD26F0DBCA69F465F0B36B6B254B1846
+:1096D0007D75B5DF21386B14F97F9DE1ACC7FD15B1
+:1096E000FD097BE4F25619E3FB974F717A244E9300
+:1096F00044E96A1E975797098B135C6E90D00E99B8
+:10970000EF26640DE52BF3762EC738CDE25DFD37ED
+:10971000809882E76B29FF98974CC8085ACE5FAFB4
+:109720008CD32EDCDCC9FF46C2E522553BD1AE5EB0
+:10973000FCA4F2BB0AB2F9CFA0F754A8F49ADEDC7D
+:10974000BFB52F89DA09A0D70D200380AFAFDCF5B4
+:10975000A51E526DBBC2F32B949E7B6A81FF59B04C
+:109760003C91E43C08FCFDF7496E1F94ED1F303836
+:109770005CAFBCCEF8FD73F128670CC094E9FF1A0A
+:1097800066B278EBA3944D409CCD60607A8DD0E7B3
+:109790006479951C43DB077FBEDA06FEBFF897C7E6
+:1097A0008C057D3FE1E56827C06B53B1331FECFFAB
+:1097B0004DE526CC5B301A589CD7FBCBC16F81DBC3
+:1097C000BF67E39612B03F2D2D877DE01FD9A8F922
+:1097D000339E1BD93882E5B575E44FB694EF81F915
+:1097E000644C61F262539633DF12D62FE1FA593599
+:1097F0008759FBC1DE3F86F3EACF9E40F598AE2F36
+:109800001BFD707713B69F227F0AC60ED7435BA954
+:10981000DC81243C51BFBB51F2E9E87AAA9AF66098
+:10982000BCA2F2615FE24C902F2F6931DE23E61774
+:10983000FF664A09C475845C992959989F91EBD9B0
+:109840003388F86371A1E91C0F6670FD7A66348372
+:10985000EF7CE2C880EF1E309218F04FCF2C6D2CB9
+:1098600042B9B35C6705792EE21B5DEB0191FD44C3
+:10987000D52F9AD9F9572998039D5CA1760761FEE7
+:10988000A28879BFE6644E67395CDFEB499C104FD4
+:10989000AB3ED47B3BF8030CDD58DC95F21BE3A018
+:1098A00002D4778D60C72C3D10E5637E6A2F3FE7B9
+:1098B000EACC87FC8F9AC9690598877096F20D33B8
+:1098C0009C1F0C64209D527E22519996936C9EA001
+:1098D00085737EA9549FA2F5295B53276829BE573B
+:1098E0006707166B687D6D72216BBF3B7011EA1BB9
+:1098F0009247B2F682C06299D6B7274F647530ECB2
+:109900002862FD3A79CA040FEDFF8A95CB694700BA
+:10991000CFFD56BFD15B13EEA7DC06C90B143E5733
+:10992000B8BFF54A16993B19E0DD2780E7CAC47B2A
+:10993000FF87BF27F27DC53AC577243972FF45FC02
+:10994000BBA5FCBCEEC868B2318AC5A53C3114FE8B
+:10995000475B7A635C2D35D9C6FAB7D07E0A43FDE2
+:1099600008388AFEC4B8CB409E029FD5317FA968D3
+:109970002F4966FC9B8EB31EC7E9E964E75027A711
+:10998000E5C3BED1FDD2F2FDD232BB733B9B1FEDCE
+:10999000D79A877CBD3FF8BB8FDEA4EF6785E6AD25
+:1099A000C68FFB387E2CAD67F1C4A0B507E2D1C8E5
+:1099B00068A6E79142E53AB62733BEBF2DD9CAF073
+:1099C000A2633F92241CA79EC3318DC23DF79BAF7B
+:1099D0007B1E9FCF3F7BDD61FBE584FCBEA3CD7783
+:1099E000ED085F8FC8CF16FD5C59A7FA6E10CB93B8
+:1099F000AAB6F5C0EF1E8D22467C4E76747C9795F4
+:109A0000C7F44BD03BC57D0CC433029D04959C6BC1
+:109A100074DCAFD0C8F3053BD637A190AFCFC2D727
+:109A2000673186DDABD0418FA7831953CC9DF1B749
+:109A300003EE1DFDF52DE0FD29E83A527F401F5D44
+:109A4000EDC74FFFD97828E6A98267079C55F31325
+:109A5000F0047AC6EFFA2AF151CC7343C73EAAE864
+:109A60003AEB5B8E57CCBEAB7A90E7FDDA95F85CAB
+:109A7000D594A58178B9F86E2CF8D81342FEB67D3E
+:109A8000C9DC6E4B23695DE4BBBD919C10D14F874F
+:109A9000CFD5765BBB95E539ABFD06ED090E3F9C56
+:109AA000C3F35C63E7CF87AAF40D88BFEC3585BEAE
+:109AB0000BC91365DD90C2F85B673F5010CFCB1622
+:109AC0001A4A5EB33B28BA242F43FE5D185BB22AC4
+:109AD0008BD63F4AAE447E5DD8BDE4CB2CCABFFFD7
+:109AE000985CC5EAF7947C990DF5AD55ECFD91CEE7
+:109AF000D780BF134FD584512921FDE15CB29DE988
+:109B00001FA51A027864905738404E0A7876551689
+:109B10001A34B511CFB576E0018B4F0CE2F2799093
+:109B2000B0CB035A855DDE1EC3CE13B7833CA5EBD5
+:109B30000D26BBAF00FC6BA25BE764D1AE1E8EFEB0
+:109B4000440FFA90E4A4FA06F839EC16320BF2E767
+:109B50005A37B9403F22CB1C462DC293FB9DE8DA11
+:109B60006ED17E0E1C7AE9A1EE6C1817CC6330A77B
+:109B7000FF9A437FFF0AE2A235574C0E50FF06B70B
+:109B80003CB30AF4ABC12DEFFC9DC95B762E43CCF0
+:109B90007B30F80FE9F341CD069CFFE096BB16C180
+:109BA000FB437FD7D203F063F8395F3DB083F68380
+:109BB000BFE9AE388F41BE90BECD798C0E787C4E19
+:109BC00095A75884872905E17113F3A2DA124E6D27
+:109BD00008A09EA63CF742F5728CAF5E27DD1C10F4
+:109BE0002710E7B4D5FECAB3E5747DF4F9F0209DE3
+:109BF0004198BE3CF206B5EBC3F4EC626255D44B1F
+:109C00008D298AF7CB2C598AF631C97729DAC7D939
+:109C1000F315F5F17D062BDE9FE82856D4EF1B34B3
+:109C20004EF17EB9B35C51CFF7352ADEEF7FA259F2
+:109C3000D97EDA8EFBD0FF9CAB14F47887DF5D0F02
+:109C4000E5C0D686D2583BE9E4A72D0C78EBE1F9C4
+:109C5000D09BB5453E12E1BCCA3237FAF73B9D575F
+:109C60002966E7D7DB34ECBC86F0CB0E36B98B61C6
+:109C70009FDE9628D829B047188371B05F65739F1F
+:109C8000C0FCA8EB41827EAC267DE0474341CECFAD
+:109C90009651EF6DE279354DD37331DFFDAC14D8B9
+:109CA00007F179CF6C761E6038D57071DD10D394D2
+:109CB000609FDC8A751793A5AA7D5AA1A897591EA3
+:109CC00054BC3F26799DA27D9CFD31D53E6D51D47B
+:109CD000273A9E51EDD376D53EBDA4681F7E215014
+:109CE0000F6434B2D5239BE9FC879C6D28857D19D0
+:109CF0007ACE331BE8A5D0E7AE07765874B4F608E1
+:109D0000943E6A4F817FEAADBA642C8FD6D9D1BF19
+:109D100074BCAE0F9627EA1CF8FCB77583B07CB70D
+:109D2000CE89E57FD68DC5D25FE7C2B2B1AE11DF75
+:109D3000DF5BD78C2585603AC88BF8B88E7B13D251
+:109D4000C18E6FD304AA2182FAFD670E225F6CEBED
+:109D5000166883FAC3A465C2285A9F0FC614E85731
+:109D600050D2FDF4A43AFF2B05F22952D8739197F3
+:109D7000D0A871E6837EFDF833C7366BD3097964CA
+:109D80009D2BD962657523ADE366431F9E639B9D42
+:109D90006984FC0A44C610AC4F807A7B146BDFF0F8
+:109DA000CCB1091E9C1F8B1F4F09C58F1F4F8910F7
+:109DB0003FFED525BB19FC28A76EF636C3BA4E71F7
+:109DC000BF9193E4EBE6D1B2589BAF03B97856A5A7
+:109DD0004788B24653FC24E069A3C63115F380EFEF
+:109DE000D511C83B9F2C317BB4430F4C65F2A87D45
+:109DF000A201ED9DD31AE722CC6F9282CF03BC5E05
+:109E000049F910E1D76E0E66001C7E997286D51353
+:109E100082CF4B8EB0BA8EADF38594D35DAD7337E0
+:109E2000CCA7D33A53D87D31C4E74C07F92BEAA726
+:109E3000CB9D5520274E173B7BC17C4EB90C483F2C
+:109E40001E97D90BF99544EB2C9A1AE64FE99DAA77
+:109E5000C3EFA6E8199D9107E488E7C4CB52999E09
+:109E600085FB06F6DC8C68D4C34F6B229FF39ECD36
+:109E7000E173B55B64FFCA1CDE5E72BF19FB6B5FEA
+:109E80001D85F1DB76576FD483DA6B2994287DB476
+:109E90005FAABDF63AB61B44680BE39433399FFAC8
+:109EA00055CBAABF9EA1EF7FB23ADA813CDC723774
+:109EB000CAA707F8CBB3E38CA8B7CC9E9C5E02720E
+:109EC00069268F77CD316B1331ECA5B5EAE10AA095
+:109ED00085A6FC0D20FE17C797EBADB45E91B66268
+:109EE0000394CB7A6ED1C391CFCABE7B3680FA5829
+:109EF0004549AB08EDA5C07B75745E73D7C876661F
+:109F00003F897386CBBF517E85C0C3D33C4F86C289
+:109F100017EDC2B9A992C22E999BCAF4866B295C2F
+:109F20006FCB25B9B794719C3F033DB4CE7E2FA76C
+:109F30000B7FBBB29DEB6D1FEAD9B8EA7B26C4B894
+:109F40006E3E8FD37AE294408F7BC08CF89137FDC0
+:109F5000CB878BE8FAF35A2C1A8CC30B3EEE67F7CB
+:109F60007D155D70239F1BD81A78F10C413C6F065C
+:109F70003AB9939CBADFB30EE5C3E0BF50F9037C56
+:109F8000F1A6FB9333D81A1FF1FCA5AFAE82F3C73D
+:109F90005AE46B47EBD660FD789D07CB13751B39F0
+:109FA0007F6CC0F677EBB672FEE8E5FC71373E6F6A
+:109FB000A99B8EE5A13A37964931AEC454A00BA3B4
+:109FC0001BF3318F3D632032C4195A0C88A79402C9
+:109FD0009E7F361EF25F0C163867A7CE8351F3DBE7
+:109FE0008EFD6FEA748F45766A5158DE0BE86799EB
+:109FF0005DE3CF296237033F19B22D6522F08F53FD
+:10A0000076BB19F4D6A1A9A9ACEEB49B75B43E6C8D
+:10A010001BAFBBED6603AD0F4FED3E11F4DE531EDB
+:10A02000BB398AD6476CEBCEDABD0483D4A5DBEC12
+:10A030001381FF1413E928D043A9316B14A4C896E7
+:10A04000598A8F021D8C499E370AE8606F8A1DF17C
+:10A05000619C7DDD51A88FEFB35D0B476B9CA6FC27
+:10A06000F5F05D497CB916BE1B95B6623D7C37BAEA
+:10A07000E7166DF87763FBEE590FF5098EED5AD0B0
+:10A0800007F7A6B0F8A7E847D445BBE0AF224FAB2F
+:10A090005F8B0BF9785EB30BF978873F624AF9233F
+:10A0A000E0A7AB69962C12CC638AD4117C875CB88C
+:10A0B000EA9B945A289F9DBCED1EF33A4A5F3550A7
+:10A0C0001F82F527D645E6BBD35223F0DDDF733A76
+:10A0D00005B909F9CFBFD7B37B387EC3D757D33281
+:10A0E000CF3C0FED19B719E4EBC11426270F73F914
+:10A0F000F8675E7EC59FD7689CF360FF2B5279DCC2
+:10A10000B6335D57C23C28DDAACE0574D1CEE9BA7C
+:10A110003A95CB077EDF411561E787EE94AFB53402
+:10A12000DC7ECB82BC9CC6E39027AACE7F10F98D43
+:10A13000EABC5FCA17F15E17D2ACCC1BEDB03FBAD8
+:10A1400031BE07C715C1E87834B54B7EF6F81DD689
+:10A15000FD78A4752F252C9F59BD0EE24E40DA12D2
+:10A16000F9CD9DD71388BC9E4EEB6850DCBF20FC18
+:10A17000EC540F7A16E65336D74CC07F13CE27CE59
+:10A18000DC864FA8F9CE3F8B9FDD86DF34C23CD5FD
+:10A19000FC469C6F5697429F837351906F07F7B4AC
+:10A1A000809FFEA144F701C0DBF692E0571AB0CFC2
+:10A1B000E20388676956F721782EE959DC5DE4B13E
+:10A1C0005ED2787E0D7AD16FB72D423ED406C28121
+:10A1D000D2E35BB40EFED36116D7519817E9C3F0F2
+:10A1E000A7ABFCCC77B81ED2B9647425F214DBB7E8
+:10A1F000FF3D03FD5877C0F7AEE050260F0B40FE41
+:10A20000FFF541D1A8F2B44AC42715409E7522EA51
+:10A2100011ADE97A2D94FF6C3BB1353D07FB57DB5F
+:10A220008BAD29838C6CDCD163A16CD6BBB7CE031C
+:10A230003B69B001EDA4F7797EDFA4F337E3415E1B
+:10A240004D927D897952673BB3F5E4AC127B5E6732
+:10A250007B93AE6F14ACEF4E76A7CBE8B70118D561
+:10A26000F667E59AAF08E4430F5D7393C07D6377AB
+:10A27000B647890C6CA2E0ACE3089445179C98861D
+:10A2800033E052ED112807FF8599E777CA271A7244
+:10A29000A3F1083B0EDE5779BFC2A07798BDCACBA9
+:10A2A0004EF7B02DF328F3D48A7D45983F210762FD
+:10A2B000A0BC2605D0EF256BD8BD0BE2BE056AC752
+:10A2C000A6764F00BB97E54B8D843C233AB9B21F6D
+:10A2D0007C34E721A4FB28D47F3AECD8D735981FEB
+:10A2E000D0A475C60E073B764D2FC73A5AFF933F51
+:10A2F000E16707685963F98A84DFCF56B9E6BAA2E5
+:10A30000DEBA2E74BF0FE44157FE8F8C72A7929075
+:10A310008DB05F95E42DFDCA3039481AFFDC01F796
+:10A320007E94CF9503E0D0AED24E72D2F7CAB9BDBB
+:10A33000413C8FB03AB7B308F97CA293F65B9EC05C
+:10A34000DF2733587BBA687F80D57B89FEF64FC400
+:10A350007A8AA8F3FEEE12F52DAC9E25BEDFCBEA7D
+:10A36000B962FCF7D97866F67E69F7EF4D02FD43D6
+:10A37000F0F771DD95F7F2507E3FB1FBEDF34994B4
+:10A38000ED5C1E887B78CA7E302EFA3DA0E7460938
+:10A3900073DF2AD7EAD0BF7DD5D698177E1E59E441
+:10A3A0009FB84ACD4ED0F7AAF6F5DE21F37C1CD03B
+:10A3B000377EC4E3CA65B209E311D737333EDF9570
+:10A3C000BEB678CD1B8AFDECD4CEEF49C6401D1D2C
+:10A3D000EFDA134998DF4E7AFA310EBEBCBB24E2A5
+:10A3E000ED789E55E47BC5F7204EB04FE37F13C553
+:10A3F000EEA1BCE047FEBBF837CCDF5BF5CC119497
+:10A4000073F3653BE2F1F12CF70A804F9B99DD373E
+:10A41000B878CD21A4D7B5995C4FB004FB86C3F3BF
+:10A42000C1CEF0FFE11DE0FFC37F27FCD57E667142
+:10A430001E7AD937CC4B6B33B338A883EFD3798DE1
+:10A440007D0087D7D340E7D716F973AC32240DFBD4
+:10A450001359BED1BB4560075DAF35E3FD44B3562C
+:10A460007D9C177E1E45946AFDFF73A0A38410BCDB
+:10A470007675E7FA5E08BE2FDD01BE2FFD3BE19B3E
+:10A48000A40DE81D10373DCBEE0B1BE03FAF0FCF07
+:10A490007339D99DC9DDD866162752E76B9DEC6EDE
+:10A4A0006678C5E3315593DF1D06F118410F23A3EC
+:10A4B0004923F8D7295E3B385E3B00AF05FE86E2B4
+:10A4C00032F4BB08F415C25FC2EC620E277F67BC92
+:10A4D0003D7D07B89EFE77C2B589EABF18C77C3DAF
+:10A4E0000AFD276A38FF8DD3BB80B731EDF6703691
+:10A4F000A6FD6BE06C4CB32BF2D204BCBB924FEACE
+:10A50000FD11F38E40A745DF864E1F4DE77C4A1BA9
+:10A51000C03C51F5BEC7A675DAF7B8B4DBEFBBB2E5
+:10A52000FD5FBCEF6AB8A9CB4A1EDF543FCF4FD3C3
+:10A53000FC4BE1F8FF9BFF7C76ED6145FBDC3527AA
+:10A5400015EDF33C1F28EAC302FE524073E10F1FD2
+:10A55000712988FAE5B7F5AB77E54F9FF4DA120D6C
+:10A56000C4DB06F9993FBF2DDDBD01F0EB7D8DB752
+:10A57000DE4CE13AF05C23BBA7AB2207F38756F130
+:10A58000397E39EC6F9F3C44F1E64B62407FA7EF88
+:10A59000F05D5A7B6E673C28BEA121CEB03CB46210
+:10A5A000A355EB447F0D7146C29BC7D318DE61FEF5
+:10A5B0000FA5F7E946A28BA7743E7DBA84F94ED366
+:10A5C00009CB87A6A5CF4DDB2769890FEE352E373E
+:10A5D000697D068CF329CF2F1BF8BDC7243E4E7131
+:10A5E0008E5976CA98973675108B0F3E606AC47381
+:10A5F000A4334E3C7CED21DA4ED67B8A58BEB5386A
+:10A600007FF607CD3789FB3D9E46989F5DE27164DA
+:10A610004987F761A9BF9BCBD73B495E2743BE4B18
+:10A62000F003827AB7A03BBABE13860276BE027EE2
+:10A6300077A29CE87CBDF17CF3965278BFF2B41D02
+:10A64000E15233685D1EEC63CD28E953435EC8AE2A
+:10A65000A959F317ECA74C7EA51EDEBF7E96B9C2A2
+:10A6600007B6523BC51EEEAF0CCC01BABC93FD231E
+:10A67000E67DAECE87F8F449DD092CDF1FF14E11DF
+:10A68000E819813A7F44BFE4B7F50F08BF80F013A3
+:10A69000083E20EEE17B3D8DF305A3D41DEF4FD3A3
+:10A6A000B252F0CB039DF9EB9B77E0AF6FFE3BF925
+:10A6B000EBD7C5F3CA642617D5F8ADC66B81CF704A
+:10A6C0005F37FCDEC00354DF03B93A9378722B295D
+:10A6D0009F9DBEA4413754FAF678BDCC74218344C3
+:10A6E0003867F2CDF9B91DF74D2E95D13E10F90915
+:10A6F000621FAEA775D233BF4A4BB8EDBE29DBFF50
+:10A70000ED7AFC8539DF4EAE11853E604DEFB4EE3B
+:10A7100084F4DBAF5BD9FE2F5E77D8F99739B22688
+:10A7200074DE03F287218FB1DDCBCE33566435E082
+:10A730003DF164503006F4C6A50765C443A2756AAE
+:10A7400053C2EE976A25BE0F011F970C5B82E7E0AC
+:10A750003ADD0B656AC27371EAFBA144BE7035EF46
+:10A76000477D4F5435CF13AE56E5ED0C49E7E7086A
+:10A770000B4801CBAF50EAA5EAB2AD8E28FC926D32
+:10A7800037EBD00F5092BEF7479EB4D03E8CEDBC55
+:10A790006F13EEB06F13FE9DFBA6C657D9BC13CF47
+:10A7A000437D537C2576E73C98B7E0C3B320878B85
+:10A7B0008E3BEB80C10BF7F98B7BADDB2576FF4C35
+:10A7C000FBA704FD4677BA1779F069379EE71CF8B6
+:10A7D000AE536679042CDF40E829426F19DA1A94E7
+:10A7E000D9FDF5FC1C14CF0BFABAFCCBE1B7A09E47
+:10A7F00023FC6FFF2CBFB590737B8C8C3E847FB0A5
+:10A8000030E0423DAE4DE72B827BE83DFBA322EAE0
+:10A81000013F4967FBD4D5BDAD4931EE9FA4433B11
+:10A82000E7EFE2FED63299DDD37CDD2FA3FF6EF594
+:10A830000F7FF7EB67ED77B6EB6B2CD723DA45A2EA
+:10A84000ACD1B0731205A576CCDB037B09FC77C2D3
+:10A850009FA77EFF5066C9CE74F42F0DC3FB34AFA3
+:10A860006F65F3E96A5F6AD60471FC2EDBF9F8358F
+:10A87000078B2CE1F7607C9E2E097CB65C3486F653
+:10A88000F5EBEEFFF0E074857EF3FFBADD3049A60C
+:10A89000AA23958FB99297E9A784E9A9B3881FCB1A
+:10A8A000392488A59BB07CFAF9C481E542E2C2D282
+:10A8B00095E9FE281DF35B8289980FB9EF1F7D0192
+:10A8C0006FAE8D18DA00B973FF2A3DAD3DDF8EE320
+:10A8D000B7BFFE8F0CC86BB913FDF78B71B6A647D7
+:10A8E0008827FF67B18CF11392BC12E9A19CDF921B
+:10A8F0004046B1B8D88F12B3D83DF51DFC2F69BBC7
+:10A90000E07F106FCDFD54C3F243964A787F6B739E
+:10A910004083A495BB28CB0BF7F13437B1F6DC2A82
+:10A92000AB57A2F5DCC151AC7D85D50BE71E669314
+:10A9300000D2E35C38F520C33918C6DFC43DE554C6
+:10A9400063CF063D6B518B91E5EF93404FE0E37988
+:10A950005DD8376333985DDC2F9BF1ED7E254A3F50
+:10A96000444C06E3035599254B3368B92AC3190BA8
+:10A97000653F9B7FD34F0BD12F8FBFA3F2C5E0075D
+:10A98000317E28BE7B32B3241EDE7B5562F9E69E03
+:10A9900083FCF706483031FCFE505766696A061D95
+:10A9A0003F2B83303AEA02AEF07B73AE08F69CC8C8
+:10A9B00067EC073615FAC7D93D54AF4AAC5EF0BC18
+:10A9C000EDBEF57DD187EF01BDF6C94CF73D387F6F
+:10A9D0003D212698FFCF0DDE1DA87FD666803F72F1
+:10A9E000C9F3060DE8051F51B10AE74AFE5867C4CE
+:10A9F000F2636AE742F9276AE742F929B573A1FCD5
+:10AA00008CDAB9502EBAE12084F28FF7329CA3324F
+:10AA10008A42F136F57C877378768C7F508FE357C6
+:10AA200065BA11BE1DFBBD9F78211EF2AA35986A3A
+:10AA3000BB0DBE75CD673CDCDE8B9C9FD59FEF7B4D
+:10AA40005E9316E5785E73206671D87B9333F4D8F5
+:10AA50009EFBFA053C1FDA66E980AF53A24B9EA429
+:10AA600061F5C9CFF741F856653A97C23E52FAFEF2
+:10AA70000E9479CDBFFB099CE7A1FD631E41BB1479
+:10AA80007C0AF57CD53AD47010EB7AD5EADF04DF86
+:10AA9000BFFA7A36AC84F21BC2E806F0488AB4DE0C
+:10AAA0007508D7FB0CC14238A772DF2D3962DE7002
+:10AAB000556631C25927F04DC089EFD7B7A5EB8E47
+:10AAC0007836C75322EED700DE690739743306F4AF
+:10AAD000BA721EAF6F6EEAF93EACCF734226BDEC80
+:10AAE00088BF0ABA7B8EEF8F28730FEA5DB04FAF35
+:10AAF0001EBCD813EE5BA5FBD213EE5FDD9CD14BE1
+:10AB000091DF943BF8EFDB7E1A8FEFE3EF7CCE20F2
+:10AB1000DBCB209F64A6F1F03158D26CCBA76590B7
+:10AB20004F3237593A0EE53C7BD668C82311F9EE0F
+:10AB30000BFA141F07529AE028477DAC18984B98DF
+:10AB40003C283546F3CB9F85FC8953D4C7247757DF
+:10AB5000BC3FCEDE43D13EBECF3D8A7631EE0447C8
+:10AB60007FC57BFD6CC16CB0BFE83AD87DD7BB64B4
+:10AB7000CCBBCB7DFDF4BDF7D0FAA417A7E2FD7ED8
+:10AB8000AFF2F6497B4BF1F703DB293CF55491BA60
+:10AB900034E8B1A77E0A9DA9F4FBCA832F1C77DA9B
+:10ABA0006FA3DFDF41AF17FC75798BB108F8EBD7E6
+:10ABB000D5F3D5FBB23F839F0BE47A7F57F8D241A0
+:10ABC0000F929DE10BBF674B8D2F9059CAF08F9567
+:10ABD000934EB17360DF948F7D0E7C2CEC1C664726
+:10ABE000A9F2B7F5D33BDE5F05FEF7F76482E7EA2B
+:10ABF000F8F9BCC5F0FF7208CFC9C2ED8FC07D5215
+:10AC0000F4B907F44F3807EAA4FDFF3983EB4D95FB
+:10AC1000871F49290CB593D59F2ADE276BA50D8A7E
+:10AC2000FAFA2C657D73F186F0EFBBE2878BB7CE25
+:10AC3000D3BBF1FCA614F1F75AC57CCADE8AC2FC6C
+:10AC4000BC899077421F55177EA085F8EAC42EE490
+:10AC5000A7E03B3364521BA9FD6606F3DF4F782B58
+:10AC60000AF359BE69BF1F515862BEE06F98FCFCE1
+:10AC700028D6AF0DDF774326EBFF5AD1961F7E050E
+:10AC800071CFFD04F337AF5919DFCF6BFA42A3A19F
+:10AC900065BF6E0C5FF22C010DC893F68A680FE455
+:10ACA000E7D72C35635E67BFECE087C67C42623332
+:10ACB00037FFD848F7ED0F7098314C9EB6838D431F
+:10ACC000EBC9FFF138F2FBF16F45F934DF623DC9A2
+:10ACD000548742795DC2E87B0EE00D972BE03BAFD5
+:10ACE000798474C819E007B07EA84FCAFCF1FB4F05
+:10ACF000D2716B4E32FA864C39B5DD3E33CC6E27BD
+:10AD0000CF31BA34D27FA0CF2D3BDAA0077BEECE75
+:10AD1000F4DD8879335F97AE0B3295F67B043A3ECB
+:10AD2000359EEE4BCD7E76BFC4F5965E78AEB52BE4
+:10AD3000F95DB35583F427EA6D2DF258C057F5F944
+:10AD400070014F62C951DCE3B472F8DF26839C5C6A
+:10AD50007950CB923DBA1A67A386D8C3C679F590CD
+:10AD6000A182FD0E259B7FBB90CF07FF6A2BEECB08
+:10AD7000CA7511E41C95CBBA7890CBE5ECF715CEEB
+:10AD80001C4C2A01F89F9188CF8EE7AE589EF1FDAA
+:10AD9000AC3B786EC2FB4392FB68C3EF371476E49A
+:10ADA000D483537B811EF961D3FC337467C8A2CC72
+:10ADB0001E38DE34E241BDF78CD5950EFE86493C47
+:10ADC000DE7FC61A6C057E7C6678B404F17BDAFF00
+:10ADD0007A12765FDF199D2B9DDD0321F28AEFFE4B
+:10ADE00056F7B695C96B8BC743BC7A16B1801D79EF
+:10ADF0009FCCF45AF226A34BC1EF6A24BF0DE6E9BB
+:10AE0000CA9CFCFD4CFA5DD29A1FA15DD901372D79
+:10AE1000FF9DA6AFA9D776D8AFBB25763F8983E93A
+:10AE2000FBD5C3AEFE6C1A9C73A376B644E733BF62
+:10AE3000F930DEC3A3B6AB3BEC9BFFA57FB4B37D7B
+:10AE4000E4DA925914F27BABEDA40EBD5CE877BB5B
+:10AE5000589EFB91E14FB72DA7F5D5BBA2118E9758
+:10AE60009F3778807F5FDE61407BE7B22D786E157B
+:10AE7000D4F7E63A3C385A0E9EEF12F8BD4463FF11
+:10AE80003DC81DF25B1DDEB7F1C5CF0DF87B1E4B33
+:10AE90005FB86B07D84F5FA4DB5F7E05FC7B2F2775
+:10AEA000E07D0024997D3F91D323D0979DEE87FCD0
+:10AEB0000B33EA0D4B5F4B41FE25F6EFD2CFA3F0EB
+:10AEC0001CFCE513F7C7821FAC55B387FD8EA46C3D
+:10AED000F2001F5EBE230AF53EA277BF06EB2FFDF0
+:10AEE000C5C469FD61FCDF2510584F7BCB6BE87F43
+:10AEF0000CED6F64B97EBDA507E3031D7296E5CD29
+:10AF0000CE0DDDCBBC1FF0A78A887B1059DE6C818B
+:10AF10002CB1DF957C22F239F0DF66F238A9F09788
+:10AF2000C4116332D0A19BB07B1F9FE88DF7EA9ECE
+:10AF3000CFE4E79749909F7714F876AEFA00FA4B82
+:10AF40000C2C5FAF8B7B2D3FCC64E782171BFFA2DD
+:10AF5000F09B54AFB9A1ACF765BFB35C506FEFBFC6
+:10AF60008296AB389CFF91E4FA08D6B7AC71CBBEA1
+:10AF700077112ECF7DEF0F30EE0913FA69C8BB0CA5
+:10AF80007E6AFB65B131C8E30EDB1571F58BCFFC32
+:10AF90001EF3472EBE7E0FFEBED87CD97F11EEC7B2
+:10AFA0006A33FB3F7988967B4F9CC27D51CFB75364
+:10AFB0001C5E627CA512D6D11FF2575CED9948B792
+:10AFC0008CDECF6FCA45F8093F6DFBE5C8F6959852
+:10AFD000A7E85FCC4FF42FDEFBEF4CA6DF5FD3FB7F
+:10AFE000F3402EEF843844983E7F2DC69F073F756F
+:10AFF000BB339DE5735FB3D17A18DEFC5F8A9C0C8E
+:10B00000C3008000000000001F8B0800000000004B
+:10B01000000BAD580D6C14D7119EB77BB777C67770
+:10B02000F6818D7FE21FF6CEC4187CF816FFD5B1ED
+:10B030004D39FC832842CDF193D44A216C9A4028A3
+:10B04000C4F864438B92AAAC7B95F911515C358AA4
+:10B05000A04DAB83081455541817228A30BD04152F
+:10B06000701BD1438914925A68EB36D46D0CE7D229
+:10B07000A42D6A2477E6ED1E77EB9FB4897A966F4C
+:10B080003CEFCD9B37F3CDBC99F7DC01F8A906E87E
+:10B0900070823D37176907532238D401A0C13C4E56
+:10B0A000632ACE3F5770016C35240C21671EC063A4
+:10B0B000607E72736C500FB091FE9671BCE1B7F771
+:10B0C0005916C01330608732809B42EF1E49041826
+:10B0D0001FF8A15D7591509BE7760500D33E1026C1
+:10B0E0002B0126E9B3623A05B001C9D16752A46FBA
+:10B0F0000D603E7EB7404518F5DCF1B834210050B4
+:10B100002A331B972B811292C37925568B74D0A1B9
+:10B1100044D09E3D42C827E3BAE7A4581588A975D4
+:10B120007B04958F8FB3B7B7818FB68B5585DC00C5
+:10B1300089B912B06CA4F3957810F1D03E01E50402
+:10B14000EA49D8A16310F7AD6D15C283DC0FDBA807
+:10B150008EFB0AC0B87DB59538EE07584EE34ED346
+:10B160006E2F8E07ACF2297FACFC0559E0FED5E6C8
+:10B1700008E101FF743C36D07C1D40046222E18A64
+:10B180009F8D4EC4BDC9C41D202802C66597C9EF56
+:10B1900072BA626215DA9DE5D444F4A7E922C605C5
+:10B1A000F9265BEC4DA22C08B017E30BE7EDE30F9B
+:10B1B000EC201C0A2A6DA4A7D10C2F435D9B50AE36
+:10B1C0008F8581F675423FA787589CDBF16598E033
+:10B1D00034081E1B51849FD3360871BA0AC29CAE34
+:10B1E000867E4ED7C000A76B21CE292C8945C04B47
+:10B1F0003B7DC7733B13C9579E152691D67E0DC262
+:10B2000003AEE938EC31719A1D078D513E7E5E1C0C
+:10B2100056815AC0F54DC5A3B882E7F7543C1C943B
+:10B220008F18B70C8816105D0EBA487405252EEAE3
+:10B230005909B28DF8560872BEFD7FC4A141576D01
+:10B24000AA7F063C5A67CE8BEF9A7921128675A9A0
+:10B25000389D9165CE27E305686768E9F43826C70D
+:10B260006B335BFE2E7B008E46DB42B642E46B5AAC
+:10B270007ACA90FF99BCD1E09B5A7EE143FE54F418
+:10B2800031830FB4D4D81580DEDEC7436D8F00A89C
+:10B2900019595510A0C2512E50FEECF618F8ABBD4E
+:10B2A0007B140F9E23B5C4A5907F4E076286F88954
+:10B2B000652234206D93D49765B4B37475BCCF40C8
+:10B2C000B825BF03CFEF78DC0E8770FD7EC990777D
+:10B2D000E03A6775CA2F1CD732901F1CACEC61BED8
+:10B2E000D9F747FDC748BFDAFBB00664C739A67C6B
+:10B2F000D63E3FCE574F923C38CB81E25EE434F4E9
+:10B300008C0F5656525CCE1048349FEBAD21DCFEBC
+:10B31000921F3A43F209B7915F672807E7CF4EDFE4
+:10B320009783A7497EEA78E2433400D7BF25ABE78D
+:10B3300068BE2BF3D372AA4B7797BDD3A77B537903
+:10B34000CA70FF4DE87724085189D79166CF6DAC5C
+:10B35000A3803199C47826B6A21EC4A136A446ECB7
+:10B3600038FCA54D13F558A4486F8CEA5D97A49757
+:10B370002EC3752F6FB8251979566CE499598786B5
+:10B380002E0DBF5064B021483B575D97EEFFE3F7A9
+:10B39000885FD73D9742E2A9F374B407B248C86505
+:10B3A000A91BC973D678DE1113B3885FBC95E496E8
+:10B3B000BF3352467EAD18D1236ED233F45E916115
+:10B3C00087D91782FF645FA42FB48B549C01BACF36
+:10B3D000895107E2D5CDC297DDC4FF9C291ADAFF57
+:10B3E0006727E64736C9075D85E8D776D3AFCEE154
+:10B3F000137D6EA4DB5F7D7A2D54D171B0F3FA2DED
+:10B40000E30F9DFF9DAFDB53F59C7F6320D0CF2ED4
+:10B41000487E6212E541E78055AE0B0EFF8DEA4E85
+:10B42000577A9D47BB2664772EC7DBEC57402D0427
+:10B43000F53D6BAE253F5C64F790147530A43FE991
+:10B44000513CC49BE7072E7E0FD2E5E1D51C1EFBC5
+:10B45000E479FAE601B43D278557E0A42348B8070C
+:10B460004EE607C9BF80045B421CEF28CFE300E62D
+:10B4700006C37C3A3D77C227E03EA7872A14ACA0DA
+:10B4800070615F10FEB830655FB7799EDAC553AD65
+:10B4900012E6C1BD67C0834712BA875F8B3891EF50
+:10B4A0003E082401F7E80BF5DC1B13A2A4A771B832
+:10B4B000A680E27DD63C9F8E0201E4349C32E439C2
+:10B4C0002057A4F824BE0E333E9915F32CF36EE5F5
+:10B4D00021CBFAEC069F75BD168CFBEBA91E1BEB6E
+:10B4E000E7069758E4F767ADBA4679B93CBE6D2DCB
+:10B4F000E192B3BADA325F0F4E7E7FA82B762951E4
+:10B500005C0F1F1BFDBC017F783F80B048FE35E912
+:10B51000003FC278348EDB2C71CFD0311F512EE327
+:10B52000DDB4B8E3AF43B6F2CBBC661E1443717A08
+:10B530001EA470763DC091E7C1300A11CE6E298AF3
+:10B54000578E6938D5C3C26C9AAFBB264294E3DEEE
+:10B55000A3C4707C7EC88A777E8715EF42D58A6F38
+:10B56000D1762BBE25612BBE0BF65AF1F46A56FC40
+:10B57000CA0E345AE41FEE6FB1F08B8EACB1C82FF7
+:10B580008EAEB7F095AF3F61915F3AF00DCB7CE0A6
+:10B59000FC0ECB7C32AFA6C67D59ACDB223735EE34
+:10B5A00035D79EB7E84DC659C39FFF679C774D8935
+:10B5B000F3F3681B9DBBEB596387E9187E35D3A86D
+:10B5C0004BED62733C48F16EB62B14D3DFC939AD35
+:10B5D0006E3AEF661F0A997D08D43E1EF7909927B0
+:10B5E0004A5CB94C75B4FA66A8350BF95A3D7C999A
+:10B5F000CA71FD587F6BB6CCD344F6A03C33717949
+:10B60000B48181CD725E90CF4BE1B641EB15B35161
+:10B61000B8E9D36884974B4A2ADC7FBD39CF1A8CAE
+:10B62000BABE2E9801B6343C969BE3007E6E5FB3A3
+:10B6300031051BCCF700DECB41A27BB9E08C46BCC8
+:10B6400033DD27952322BF27A9FCDE7495A976A2B6
+:10B650001B9DF152EA5FC7F2D4235EACF377054538
+:10B66000E6F72CA647C8A90439C69BCE8D50D04F0B
+:10B67000F777FCF321ACBBC2F590E6E7E67B74B448
+:10B680005F35ED39E1558F919E51E6E9ABC1B5D7F4
+:10B690001B3F2AA5FEE3101109AC8381ACE06B349B
+:10B6A000AFED6F9ECBFB6A3EFA87755417647E7FC1
+:10B6B000D09E67FC3DF011297B24ED9C1EB0F3BEAB
+:10B6C00003E6FB68B38957F27DB4C9DC7F14556C7F
+:10B6D000C73ABDF9FC558ECBCE8271B0E5F07CE364
+:10B6E000F7A4A78B5DD587C8A7608DB27E298D276B
+:10B6F000DF4B45E2E7E98BEDA23F5B9FE1BE98A4FB
+:10B700003B0BC6F87BEEC1FA53461F995DBFC6FBE3
+:10B710006CCA6F43FFE8C14CDE5F460F96B4104D14
+:10B72000E9BFCBF56F0EDFB0E4C996BDEF5BF2EF7A
+:10B7300029ED0F96793D77C25E84FEEB6F14AEFA69
+:10B740003AE277E79CA39EDE8D18B79BDEBA947E23
+:10B75000FDC5456DB4DF7FF7F3AF1CDF917D71B0A0
+:10B760002D4CF9796BDF4DCEEBFB744EA7FA997C2B
+:10B770006726A9F41654D8303E136C8E72DC3B7DDC
+:10B780009F2D3EE35D32B232AF85FAEC48896433D7
+:10B7900068B9C11736380D7ED56AA209BBEB00BD6A
+:10B7A0003347180419E6C32616FAE953E8F70B796C
+:10B7B000EA27947F5D3B26AA6C781EBA02FA930CA6
+:10B7C000E3593C57FD17F9CFF07A57388FDB594EC4
+:10B7D000F78E3141AB62580BAA7D85EB6C1897B19F
+:10B7E00039DA5DEAC44B8EE71ABC649C8F46DF24CD
+:10B7F0003F0FCD1E55F0A19E0F9918E3F9FC4B1693
+:10B800003DC1F34D97D6BBF979EAA07717BD77E92B
+:10B81000BD91C83068868F71FFE64CA10B7D463D17
+:10B820006B3469BB78B89CD1FDE08803E83CE03E0E
+:10B830004181F61972444F209F87B6D33DE5D792D8
+:10B84000719FAFFE95234675639BF3631EA7129FFE
+:10B8500097EBC92DC3CA85EB725F724423649F1EA8
+:10B860002F5D87F6F5DBF1FE42EFE977711ECFDD44
+:10B870009D17171D3F94168F12330EF00C80319FC9
+:10B880007F8CE63B87476F511DB9E255BDE4FFA8A9
+:10B8900020D7531DE9CC7A53A2FA53E393F93AB473
+:10B8A00097FB8FF5E0FB8CE3ECF4FC09F3750B16CA
+:10B8B0009B6C7ABF09EA625ADFE9D425D28719C1A5
+:10B8C000EF7FB3F97F676BFC153FD2BB6EA594F693
+:10B8D00049EE8B76D4909EA4DF493B527A3E3BAF33
+:10B8E000B739272CE7F7F6D1FDE5744E105F95ECDC
+:10B8F000AF16D996F533AC7FDC8CDBBFF3432B7DE1
+:10B900004877847FF0C6DB726A3EC1FABFF501C595
+:10B910006BD8C5EBDC6CEBA7FAD9796998E3817E2B
+:10B920003E49FEA5F9F928ED93F4F3CED07BAFF8AC
+:10B93000E52FEE5FA2242E91DEC4B1FBA532AEEF5F
+:10B94000BC78F526E54FA7F9CE87B3D6F7BB630ED3
+:10B95000BE13E7A5D573AA710BF8344BBF3F3992DC
+:10B96000EB8B6DD6F578511670BFB3E6FBE13C9DCD
+:10B97000DB19DE9967E3026F95670BF07E467D0069
+:10B98000FB2ED5FD64DFDD7D43E0F9B8DB0B7C9E4B
+:10B99000ECA2FC67FA15DE0792FF478830EC6F983F
+:10B9A00007DD92FA6DCA0F507B785F1017B814CA82
+:10B9B000E3C1DFAC31DF4B469FA933FB4A1DE921D0
+:10B9C000FBFDD9BCDFD49AFBD63BF11EE3A392ADBD
+:10B9D00099FF2F31FFAF70F00A7F67FD0774153EA6
+:10B9E000C90014000000000000000000000000007A
+:10B9F0001F8B080000000000000BFB51CFC0F003BC
+:10BA00008AB7C9333098293130242A33309C01E277
+:10BA10002479841CADB02A0765FA5F303230BC024D
+:10BA2000E23740FC8E9174FD3F8510EC87BC0C0C16
+:10BA3000BF80FC8D405A4C8081E12690FD1B88BF61
+:10BA400003F9E27C0C0CCA406C06E4BB00E93C2024
+:10BA5000F607E23F407E1B1F6EF3FF0AE1B7FFAA25
+:10BA6000002A9F571095FF911FBFFE0E41FCF2BCAC
+:10BA700004ECC7864FA8911F1F3CEAB44F33D4C4CF
+:10BA8000371950F9A7651818EECA323028C843F89C
+:10BA9000D790E48D8062676420ECAD620C0C7BE58E
+:10BAA00018182E336037771B507E1F50DE0E6A0E3B
+:10BAB00000B5BC7B1E680300000000000000000011
+:10BAC0001F8B080000000000000BE57D0B7854D5AB
+:10BAD000B5F03E73CE9957662693848484F09824FB
+:10BAE000803C020E010248A893071425C008A868EC
+:10BAF000110651088F3C44ED976BDBCBF04AD1D255
+:10BB000036D6B6D25ED401E15EA45803448D1A60E5
+:10BB1000806051C106EB03ABD600B6080219A0EA5B
+:10BB200048F1F75F6BED7D92732633407BFBDFBFFF
+:10BB3000DFFF8FB5DB7DCEDEFBECBDDE6BEDB577D9
+:10BB40005496CE581FC6BEC1DF8D8C3D2031868FE6
+:10BB5000B4127EFFEB9B0CC6A65AE1BF64C6C6CBEF
+:10BB60000EC6463036C5C142166833A5081E766338
+:10BB7000ECCD4D5248C63ED02E58C8D822C67F5371
+:10BB800015D6245DCFD885D13BEB867918937C3EC2
+:10BB9000565B00A5C7CD666159B4F72BC9C558F2ED
+:10BBA00068136303789F6FE0DF149F9DC6D2EA6934
+:10BBB00013530DF5747F0F43FBEE33730DEFB30298
+:10BBC000830CEFB32B0A0CF55E353718DAF7A92D85
+:10BBD00031D47382371BDAE7AD9966A8F7ABBFD3D0
+:10BBE000D0FEBA75771BDE0F0C2D32BC1FBC65A9C9
+:10BBF000A13EA4E12143FBEB9B5618DE0F0B3F62F5
+:10BC0000783FFCE0CF0CF591ADBF36B41F7574A33F
+:10BC1000E1FD98B6AD86F7633FDD61A88F8BBC6C04
+:10BC2000687F63749FA15ECCDE30B42FB5FEC15037
+:10BC30001FEFFEC0D0FEDB99270CEF6FF27C667819
+:10BC4000AFD1C1A401170DCF277BFF66E8A7303F16
+:10BC5000009B3133ABA1D2CAEAA9B4B3062A1DAC0A
+:10BC600095CAEFF60EDC49F4F964B08E01DDAD0C37
+:10BC700046FE9406E59BA3F39203F9389A8F31A010
+:10BC8000DB297C6836C5EA08CB4067162B0BDA80C7
+:10BC9000145C51A0B734A0BB28A3D21D057A1B0E9B
+:10BCA0007417B552991A4DA5E769513795DDA23D34
+:10BCB000E8797A3493CA8C682E95DDA31E2A33A3C3
+:10BCC00083A8CC8A0EA0B247B480FA6547BD54F66B
+:10BCD0008CDE40CF7B454753D93B5A42CFFB447D56
+:10BCE000547AA2375399139D48656E741AB5CB8B5D
+:10BCF000FAA9EC1BBD939EF78BCEA4B27FF46E2AFB
+:10BD0000AF8B06A81C105D44E5C068059583A24B67
+:10BD1000A9DFE0680D95F9D187E8F990682D954382
+:10BD2000A32BA8BC3E1AA4D21B7D84DA0D8BAEA136
+:10BD3000B220FA337A3E3C5A4FE588E8AFE9F9C8B9
+:10BD4000E83A2A0BA31BA91C150D51393ABA95CA1A
+:10BD500031D12D54DE10DD41FDC6461BA82C8ABE14
+:10BD60004CCFC7459BA8FC16D25B1AD25D984A5FA0
+:10BD7000F4757A5E1C3D486549F42D7A5E1A6DA50E
+:10BD8000B22CFA477A3E3E7A94CA09D1E3547E3BFC
+:10BD9000DA46E5C4E8692A6F8A7E4AE5CDD10BD43C
+:10BDA0006F5234426579F4123D9F1C8D52A9C93BF4
+:10BDB000365A3DD3A6D15F2EFEFF2CF75F06835C7B
+:10BDC0006201D337503207D0C198CEF6B125483B37
+:10BDD00092932AD05512D0770AC8429487536AA406
+:10BDE000D0B773803EBAB5B5605D1D6DF158A07EC9
+:10BDF000178BA848BF1FB13627CAD3BD634EF66C58
+:10BE0000037A7D333DDC0B881B7F246F559C531ECA
+:10BE1000CADB334A1B3C9FD26D5F7AC081FD8137FC
+:10BE20000A90BCE1FB48DF408E38CE5D0A0BBA6059
+:10BE3000AA47708431D42E6C81FAAC72E62B80F65E
+:10BE400075632C3343F09DBA027F851FCA1FE7F844
+:10BE50006762F93A320FCC7FBF288F3013953FEEDF
+:10BE6000EDA672D67DFD383F950110B3AE0E87F476
+:10BE70000CDE8F3922BDFD43AEBD9FC2A0DFC8CE10
+:10BE8000F6CF30FF3BF83C58C206D4383ADBC1F35A
+:10BE9000A3D82ECEF30FE23D6F308120007D154CEC
+:10BEA000358736A37E629EE45B705E564FF2346740
+:10BEB000E2793DBC2C335FE9AB9F6788E6F7B0C4FD
+:10BEC0006636D0F8BECC6943687CC27730D51ADAC2
+:10BED0009C43A830D0CB5F119ED02FDFEE6FA7F52B
+:10BEE000413FBF13E1E3BE26B840BF2F089E0AF4CE
+:10BEF0001B72EDFD1297F54CCCC343E389E7D516D1
+:10BF00001694004E91CDCED0C61C5C9387E4678515
+:10BF10005B08D06E000CD0EB15290842C65A762774
+:10BF2000854DD0BE68B37323DA01ED25C18CA90815
+:10BF3000878D2ADB0C4D56ECFED1BBFF01F5A20D1F
+:10BF40002AB3407DE1C59F1732A0A3EB24897F3F30
+:10BF5000E8DBDB17C60F30EDE79370FC058C8FDF55
+:10BF60002E09B86E4E26BC7D5AB6A96E2C946DBBB8
+:10BF70002ACB19C8F19300D62CA0EF8576A660399C
+:10BF8000AB66BB99E834A87ED2A6E917E267A5B3F1
+:10BF90002E77AD2FC0BAC6FFB0EE8521B5B30EFF28
+:10BFA0002EDE62ACEBE0457650E4BC12DA487495C4
+:10BFB000CDE1A3C1CB97CDE127E055765E099ABAD2
+:10BFC00011BC42280792250FC1A1E2BC1296619CC8
+:10BFD0000A8023B260C5AE8733104E8BB7D8DC9F82
+:10BFE000E8BE5BD99062A8573765B93FD1E9D10B5C
+:10BFF000079F76E1FA97669ADC9F807C3BB3CC97EB
+:10C00000F609A0ECDCB289546AF451D990E37618B1
+:10C01000C631D62FD44B131B487F7A92670C494CFC
+:10C02000674B33CDEE4F80554F6FE1FAF6F432ABEC
+:10C030001BBF736699DBCDBF9B49A506AF25B576BF
+:10C040006AAFCD2FD1B8FFECF931D6C84E58519E0A
+:10C05000C3BBBCC4ED13F293F25733F149B3FA05F5
+:10C06000D28D15FEFDC6447444756DDCEA06396850
+:10C07000B91E9F6F337C0FFA79FEA2D32F89F95630
+:10C08000617FD1D1E5FD3800F1A995F01C801193B5
+:10C0900061BC76C5B106EDA8C9827EAAB11DC88370
+:10C0A0004A6B9B39008FCE36727C24FACEE9655BF1
+:10C0B000B251AE5558EBCD28AC2A1A0696213F9DB9
+:10C0C0006D5C9981FA65B17CE1BBFE38FD7FACF116
+:10C0D0006D488D18F56548CC13C635F0197374ACEE
+:10C0E0001BEA674CF02947D7711F97B8DEA9DA76AB
+:10C0F00064C258987F55D37933CE63B214785C4AC2
+:10C10000EF5CBF84EB8771166D39467CFEA91AEC93
+:10C11000FFBD9C2BC0B3CB3C1D997F49D2CD2F08CE
+:10C120008624F0EBDDA305BF32CFED1F007F9E7AA2
+:10C1300043658FC03CD8656805EF7B8BB7F730BF90
+:10C140000BE17577E362923FA750FEA01E66F5856E
+:10C15000481F67996922AEEF2C7BCB355C07BF7D0A
+:10C160009259C0074C59900716FA14C12D0BF5804F
+:10C17000A5A2AE551E8ACF95A0904BD237244F4230
+:10C1800012E9890AFE3CC8ACCB691D6BB83C0AC2F7
+:10C190003F58BFB7DE289F16AC33D6E7B369190AFC
+:10C1A000C897F93F576144906F7AF907F07B46E2F0
+:10C1B0007A7701ABA973C3FC9F30039E60FE77BB07
+:10C1C00099920DEBAB7CF189C2B9507F4DE27AECCC
+:10C1D000F432987E7F182795AF7F516DC8ECCBEF76
+:10C1E000BABE138DC36F1BCB683C9293C1459AFEB8
+:10C1F000651EA590A42518B989D79FDD28FB6C2E54
+:10C200006C07CF75F279DE1AE3FAAEB6FED8F532D6
+:10C21000F633A2B7455B6E614867DA7A347C69EB26
+:10C2200051B748BE501C3E6813F4AAC9B588809F18
+:10C2300066777C1E53BF1453FF26A6AED1B72AF8EB
+:10C240001BE8FE736924F2736402A79336AED744E9
+:10C250003B7367BB4B576A6711FC02EDBEB9523B9B
+:10C260005BE7788A29BD6BBBCA179F7D2108F4BDA7
+:10C27000E8B95FB818D0E329A53EC30BCF976C5E31
+:10C28000ED42387DAA045D4837A742F2C478F01A1F
+:10C290006392347BC32101DEAB34FA2F5A3E05F59D
+:10C2A000FB179B55F7238097EA2D96B005F05DD5D7
+:10C2B000B8B09C0DA5FA315EFFE179A48FEA26F5AE
+:10C2C000B81EAF8BFEEB17191E27E121DB84363039
+:10C2D0000B673328AB36FD7902DAD1D52C42F41C3A
+:10C2E000DB0FBF8FAE1DC8EBB9E6E4AEEF35BFB1D3
+:10C2F0009A3F62D58D3F3A8F7E6335538EEBE9A826
+:10C30000026919ECBC41266737F417D828360AE5CC
+:10C310008A0607164A27B9BCF299C7871E83799CFB
+:10C32000D9F4864BD2C1072C2482CB8586791FA7EE
+:10C330005D412F9C03FA64FDF5FD42D4CFD3041375
+:10C34000E80ED5665E2E51C3AEB100CF251B542F2B
+:10C3500050265BF2ECD3FFF96BE03BF6BEC5DB0F7A
+:10C36000E0BDF8D903EFDE00F5C5DBD56EE57C193D
+:10C370000E29A3131FD5F02FC66534F82FDA79C024
+:10C38000EC19C29F7F3FB5130F8BB7EF35B3215D1B
+:10C39000E156DAB0D7DCE688838F866313D09E59E6
+:10C3A000F9CC9766C4F7A9DD12EB9ED3B57FC5869D
+:10C3B0000364BF209C087F023F1DF8EA82A7F09427
+:10C3C0009747503B37CAEB447872A2AE1E4974FCC3
+:10C3D000DB97E1FB157FB47871FD15BFBDDF85EB01
+:10C3E00038A9D4707A7E6275860FBE5BA10633DCF5
+:10C3F00054F2E7154F3E4874B6E0C8836497017D58
+:10C400006499486704B3707DF7AEBF95D6379F0532
+:10C4100088DE2A9E90FD2194030A9BB83D0E3F3C86
+:10C4200027F8E1E4469094B0BE93281FD1CE7D4B0F
+:10C4300016F2F13EB2231F146B054B86EA9F5B395F
+:10C440009EEA4C262D2E6735D0E9A61F921C3DDDB5
+:10C45000CBD7DD9D4F70D0E426C953F9C8F8EE1C48
+:10C460003F5CFE523FA0BB527C8EED5B559F6DA89A
+:10C47000A19F9097FCFB0F88EFC3BCED687F9CCC1D
+:10C48000E07A22767D7F3469F211F4AB8EBE747C43
+:10C49000CDF97CD3C39CAF353E0FDD3211DFFFF504
+:10C4A0006DCE3FD80FF50FCC2BDC9DDEEF9D21919B
+:10C4B0001CB0B0703C7EDEA40A7E36BE07094DF685
+:10C4C0001BCC5B9192F57402E3A712FCC92E99FF75
+:10C4D00073E8A7B3A7ABF17BD4CEDCF93CA7936F8D
+:10C4E0001708FEDF8AFC9FD4C9FF6C7DFA35F96717
+:10C4F0004BD4D07FFE1AF915F833E8417E55FDB8CC
+:10C50000EECFB6ED7FF74EA0EBCF1A343E35CACD55
+:10C51000583EADD8F12043FA8CE5D3CF7AD6B0B8E7
+:10C520007C0ACFE3F269CFB6FF11B9A9C1ED480C7F
+:10C53000DC400E3EF5B22731FC62E560B5C9135709
+:10C540000EC2EF6D56D895EE347AD3E86CD16F2ACF
+:10C55000FBA0BCE9A0478DDE3AE851A3B7D8751A15
+:10C56000E116FB7E3DCA1B9D7DA0AE604127E039F0
+:10C57000B24B263FB1DD1371A5C27757DBD81CB48F
+:10C58000B3DBDDA29EC2EB9174731DCA05ED79C4C5
+:10C59000C6E30DEDFE882B45673F1F6B965D1E7849
+:10C5A000DF166213E3D9D52071E9FB6D2CD1FBE5D1
+:10C5B00004BFF1B2A377ED08F4AB642FDA6EF72C69
+:10C5C000BFDD85218BF6E6BCA933E1F9BDAFC91407
+:10C5D000D368B7BB86E2BCC06F57B200BEF3049EFF
+:10C5E0003F65C15F16C1BAE63573BBF89EB54678A4
+:10C5F000CC773C60463903F667271DE8E845DB2722
+:10C60000A8586F7CBF88AD257C2D8AA19F80F077CC
+:10C61000B264413FC3D830E16F9870BCA5424E8DE3
+:10C6200097F3A7CE04B8B71F949905EA179A6556F1
+:10C6300087EBDC268518F271309DE8B00AE403D35D
+:10C64000F9856790CECC89F9F7CCF31F157E0F9A48
+:10C650002C79E183A1FF01E59917DEEFFF0AD65F90
+:10C660007CAFF707AC6BFBD2DD5FCD46F9DEBEDBFE
+:10C67000C2284EB2FB77BDBF87F5972D5E8A73AC9B
+:10C68000B0F0F8D46E67A81FBEEF05F8467DB9EB91
+:10C69000CBA16DA46F56119ECA64EE475C68FEDBA9
+:10C6A0009FA46E58C2AA508FEE4E22FBBAFA655B69
+:10C6B000089DCEF65D5F16061CFFBCF554995980A7
+:10C6C000E8CFC966EE407A4D01C4C1F7AB5F19F3FC
+:10C6D000F472F87E65E35EF33C785FBAE7EBA1287D
+:10C6E00057DA7770FBE09CDAF624F3323655FEC554
+:10C6F0007215F0750E6DB51E2097E4778B838E78DA
+:10C7000070E170680738E0BA002E15280F13C16376
+:10C71000FEBF2C3CCECFC6EF2F691EC5E41C3D5C8E
+:10C72000241F7FEE0C59255A3F7FBEFBCBA12877F3
+:10C730003F6B584EFAFB6AEB5E8DEB4EFF7F69DD77
+:10C7400052F85AD6BDE95F76DD9CFE07C95C1FC56D
+:10C75000F241573A7FF1BB54FFADD34BF3BD46FED8
+:10C760006FF9975DFF3F88F71D12EDC75D0DEF274D
+:10C77000FE65D77D35BCBF26F0EE7463BCB77DD7B0
+:10C78000D7BD996EFD575BB749F957956F575EB79F
+:10C7900066F7B49A6ADC23607EEFB3FA5B73A0FCA1
+:10C7A000BDEF623774478107FCF1FC860285FB0D03
+:10C7B000168C3361C35B252D5ED46AD8C7ED594111
+:10C7C00076C614DF8FC93E604A4D6B31B46F2D9928
+:10C7D000E77D845A141C0D607DC6385137FA536FBB
+:10C7E0004ACC27811D3BA564D241B4EFA6FA64B2BE
+:10C7F000FFA024BBEF9DDE13F8F3D1463FE28E1875
+:10C800003FE0F699C6F7B78AF16E634BDD23005E11
+:10C81000B7F554DC2100D11DC5352AAEE78EBB2407
+:10C8200056AF8B57DE1A339E4B61224EF28FC1EF0B
+:10C830009E0EF82D2578B062D9BB995D03FC188750
+:10C8400077EB8C61218CC330C5CBE1775BA597E298
+:10C85000A0C2CF54457FD5B1A615F9566546FF5203
+:10C86000F31313C19909BF93C6C9ED84BBEA93C9F9
+:10C87000EFD48D47F0D0F0F1F7E241C3DF7F171F0F
+:10C8800085888F38FB670BADD65B71FFC23A4022BB
+:10C89000BF7DEA5A99F260ACF912C1D13F5AA5FDA9
+:10C8A0009D3F9BFC856838970F1F55F5101FD68B51
+:10C8B000F05928E0389FD590DDC92E7FF34D11EE59
+:10C8C0001B1184E0BD8FB1C9E087CC2F92C276588E
+:10C8D000FF028505930B30AE29B1E3FAB866C8585C
+:10C8E000C7DFB7323AC7B95AFB44F2E19F5D7E0C0D
+:10C8F000F2E8785FF057B054E8F38ADE4F9CD3CC6F
+:10C90000E158BD440AE5121D8555BF6E5FE77D41C4
+:10C91000D71F7F7F38C9B9E29F0E4926FFD53788D8
+:10C92000ECFD6A61EF5F087A92315E73A1392F19CD
+:10C93000E331170E96BAF472512B8F083FF20FCBEA
+:10C94000AC54B69749F532FA5B2C3285F470998D68
+:10C95000A1DC89EDF792A2C55D6ACC1497879F5C34
+:10C960008878E4BF05D035395587B7B5934F29434B
+:10C97000BBE2017FC775FB24FF5DF8A2DF8A703D33
+:10C98000626B9BE08FB3DE3704FCCAF77D65C63867
+:10C99000C1B4E61C15E132AD4C36E4DDEC57843F02
+:10C9A000359C0DC77995EFBBC93506F17250F6DAA3
+:10C9B00000BED5CDE7CD8138FB6DB1F0C4F1312E8D
+:10C9C0007C42F5CE47789EF8B18D05811F0E8BFD18
+:10C9D0001F78E543F90543F9303EF6B6C2F7150670
+:10C9E000AA3C2E3EBDBC584D87EFE637BA87A18AD8
+:10C9F000E921DA0F543DF43E5BF4D3DAF558C2DB9B
+:10CA00001D33BBABE2AD7FB299AF7F01F37E77B44C
+:10CA1000F4AF87B7E29F3AC325A8DFCB2492235D0A
+:10CA2000E99A117F5C98288550FFA21F4BF5728907
+:10CA3000F4FF612DFF601AD7971ADDC7C25952392A
+:10CA40009CB5EFE7A89C9ECD2A878F06670DBEB1E7
+:10CA5000F3D5DA83BCBA511F5F99DA34ECB7689F1B
+:10CA600054354B6E0CFD55296D66E4C3EAA6475557
+:10CA7000DC2FB8C3C3C7658A7FA87EBF76A0AAD0C3
+:10CA80007CF6178C25FBF1E25A6E1FFBEE39EF4264
+:10CA90003BE8B0C9FBFBB1C88F6FCA944F90088EBA
+:10CAA0001F2CDB32A34CD18F9B43F39CBEA458C5F3
+:10CAB00070D07796EC55BBEBE869A09A4AEFB5E7E2
+:10CAC0003D96780AF0397C8FE611FC8985611E4716
+:10CAD0007E436B4912BCFF4E4D0AA7C38A86BD66D2
+:10CAE000AAE7507BED7BDA7762F969467992A13E3D
+:10CAF000AFB4AD27C2A5DC127EC01B874E5B546D60
+:10CB00009FE4EFD4133EA0DBA1FF3FE889F3137C41
+:10CB100071E0F698DA453F748FA71F962EF7744799
+:10CB2000F82FDD95D71D9963E96BE333E2E9877749
+:10CB300096F1FDC0F7409E61D93E03F4C3F53AFD7E
+:10CB400030C346F411DBEF07EA35EA070D5FFFC398
+:10CB500072E61DD40F71F8BA5E35EA87DB9AE79268
+:10CB60007EB86D86CC3CBA78DC0F55B1CF95503F7E
+:10CB70001467DC4175D59B14876EDE117E09C215E2
+:10CB80004BFC0EEA893D42EEC7EA8B44F27C9A598F
+:10CB900012FBD55791E7FF97E0ACC9F3A5E0BFA022
+:10CBA0001DD8950E19C9EBA577803C97901EB93C0E
+:10CBB0005F7A97884BC6C8573FCAD7117AF9CAFB24
+:10CBC0005705B83EA86ECA797C16BCBFB35EF55A4D
+:10CBD000A1FD9D9DF2B6502F6FF708790B70EEED19
+:10CBE0008E83DF99B39298C728AFFAA29C3A31ECB2
+:10CBF00077F93B91EE0FCBB48FF867A1C70F0DFB10
+:10CC0000DD088C9F77332B443F7F16F2EBDCB2D0EC
+:10CC10008C32E0E3D27BB83D5CB94D263854357296
+:10CC20003BAFAAAF3DE481FA8482AF683F70F12E3A
+:10CC3000BE1F08802A2FD6E171F1E1B6BA6C7CBF25
+:10CC400041A2FDCCF9DEC514C767EB789CD80AFF7A
+:10CC5000F0BC0E1FC5912B05BC16366FA078F3C231
+:10CC600090310E5DD9F7E653E80F68F277F19698A8
+:10CC7000F7DE8769BFA212E3CD3A3F4416F6C3BD83
+:10CC800072387F27E676FE9EFB55B1F8D7DA75AC91
+:10CC9000BFE2BFB9FE23B0FE11FFFCF55FEBBA5552
+:10CCA000B3E0F7023602F9E3CF261FF17BF07558A7
+:10CCB0003F7CE79E47FB75D7E719A509BE3C6C0A88
+:10CCC000D46561BB2A89DA2D58BFFD4006D467358B
+:10CCD000B06118A65FB0CEA8173BF470A387F4EC40
+:10CCE000AC9AEDD2DDF9086F56837436AFC012C02E
+:10CCF000FDD423B608C92F8DEEC699393D8F15DFB7
+:10CD00003DD12352467E4493E426BE08DBB85F0142
+:10CD1000F0B7417DFF982F270878533CA6BA89E3E6
+:10CD2000A71AF0817C35A159D4B7703BEC3BA06FBA
+:10CD3000683FAC79AF8AFD2AA07D1AC99B41867DE8
+:10CD40002EDC9F2BCED0E16DD7314EB79B252F8B9C
+:10CD500083B701F04F5CBCFD93E85583C738B3B08F
+:10CD6000E705FE8ED85ACB87D33E94E4DD888D9BB1
+:10CD700053681FE593FA3CC2E32441BFB1748DF6BA
+:10CD8000BD47174FBA05270EF2954DB4519E1B7D36
+:10CD90003797DB3F7A7912EB3757B356B263264B9E
+:10CDA000818F145D5EDB6D22FF44DBA7D5B57B5C14
+:10CDB000BD423B96E936A19CBC5FCBB7C4FCE10CFD
+:10CDC000CA5BA2DFFE5E85EFCD82F55E5C237B71E0
+:10CDD000FFE77693E7DD22E4DF4754867479F1902C
+:10CDE000EAE3766712C9DDB9874FA8180A990B30B4
+:10CDF000417CCFFD0197AF27703078F647D05B3E7E
+:10CE0000DCAB670D23317F788677EF780FE0E5D6CE
+:10CE1000114756E33EDCF452F7BBEF227C1F961914
+:10CE2000C2F7F89A52F24FEEBF4F22BA3E0A70C4D0
+:10CE3000FEB7CEC879F75DF8EE5D6BD2695F6D968F
+:10CE4000EFC078A4B379539D0EDC5F9B344066013C
+:10CE50001D1CEF62ADAB515ECFAAB9EF569C6F05BA
+:10CE6000E8018CB356341F19DF1DEBEB25AF07C665
+:10CE7000AF0E06CCDD0185ADEBCE9B31DE311FDA86
+:10CE8000217AAAD7F376D59B24AF0DE9B1F9519257
+:10CE90003BF33749CC8DEDC1DEB3F271435618B781
+:10CEA000753DF487FA02EC8FE36E4AB90DF7D1AA0B
+:10CEB0000FC9BCFFE8E5AFA25C9A0FFDE0356BDD62
+:10CEC000741F8DB770BDC43261BC8AD1393F198DD2
+:10CED000E31D52BDF8FEBDBDBF32E3BC67C3F7B270
+:10CEE00060FC7972DB786CCFBE27B93753BC89E719
+:10CEF000C9B60B3E606F6771FE92445DD8819A3E61
+:10CF0000FC833997E8697EEDF23A5C575B303D0768
+:10CF10005DA0EAA6F366B4EB3E013807C06E3B2184
+:10CF2000F2D8F6074F98DB74722A62CEA3FEF7346C
+:10CF300015137FDFCBFCB4DF1D58CEF5F0B1D5B6AD
+:10CF40009084F687EA263DB97FF575BFC4F59F7BCF
+:10CF500056A5FDD173BDDA281E7B72BDCA8230C7CB
+:10CF600095EB65921B27B7F13890FC844AF5050FC5
+:10CF70009AA9BE7FFDF409280F4F02FC910E4B9F2A
+:10CF8000186FC6FA0290EB9638F263BE67119717D6
+:10CF900031F261C13A23FF7791170F4CE0F23D4621
+:10CFA0001E54F6ACA3385FAC9CA8660E4D3E1460D0
+:10CFB000BD359C45F45B75486568CF5529EED9EBC6
+:10CFC000906E66D970A718F8227C00E5DAC590E467
+:10CFD00009C2FBEFCC796924C2EF2F086FE48BB54F
+:10CFE00069B49F3A3F3497E0AAE5132E5867A467C7
+:10CFF0002D7FE98E80CC7C7A3D5091C47CBA76EF4F
+:10D00000FD00E812BE37A7490AD924AC1F7BF5C141
+:10D01000115477231D56D50A7DBAD64974FBDEBF5D
+:10D020009D5F8D7439FBFB12CD9F050375A857AA30
+:10D03000D6491E8C632EF83EEFBF00FA23BDBCF725
+:10D040002B4E3F40C71EA4F3AAF58FBE4AED3749C9
+:10D050001E1CFFBD0D7349FF56046546EF371D23A7
+:10D06000FB18F400E501ED0FCA1948E755AB2C6E2B
+:10D07000C4A3462F1AFD1D53C53901AB77E874E8E8
+:10D08000B7C1ECA175C7D29D3C3387E8AB7A9B4A08
+:10D09000F4511DE4F474EC5999E870FFEADB897EE1
+:10D0A000CE6D9612D05FA9390BE92FC4DF77D0DFA0
+:10D0B0003392A03F4ED7271FE0F4588AEF91FE9E8F
+:10D0C00017F629630EBDDDA1D19F464F57A3BB2E96
+:10D0D0007A2901BD816D7C1BCEEBFED5369A77692E
+:10D0E000DD4BB7D512DFA8B43F5F5AF76F19C8A759
+:10D0F000F3159E87A1C1B152E1793A5DE6F1F3E5FE
+:10D10000E6AC6B994FCC3CF676EAC502D48B9857C7
+:10D110001286EFFC6EDBD394BF7676EB31CA4B5CA4
+:10D12000FC0AE01DDA9FDBE66461B2A743245F16C8
+:10D1300035CA9417CA9470E174DDF9112DDF62F1DC
+:10D14000734E82EFA21D965039F45FF4C289A1B4E8
+:10D150001FBE22F22AF24F70ABC4E3F2C1B6A1D3D4
+:10D1600031AF52E1791FB17A778C85C76BCEBC9411
+:10D170003413ED1F69CB5EDA4F5AD470BB6AD1C548
+:10D1800027BD1695BE0BED689F260878C77D449C89
+:10D19000DF2D43F4F35BCEC77B86F3CDA22695EC5F
+:10D1A000A2455B36505CAF7ACB79CA7B2D7DEE59B8
+:10D1B00017C2A1BA4936E6436D91C316CAD7928FFA
+:10D1C00059B87C32E4255535F27319550D22EF27F5
+:10D1D000262F66F173BB5E08026816EFFC2F17F26C
+:10D1E000D1E9D6CD2E84278C47F944534727C83739
+:10D1F000BA5A9E51C3C371F38C4EE37F0081CCB603
+:10D2000018F333D9162EA700EB85FE38F14CCD5E0E
+:10D2100059FCECE74F62DEEB991D9F3D89F35EF20E
+:10D22000BF2E3E89791B6CB7CD8DF643F5D6772896
+:10D230007F50EB576B11FECF33FF457997E7DEB791
+:10D2400090FD776ED7C9DE681F9CDBFE5506E6535E
+:10D250003EB06B3CC51F1E78BEB43B8BE3DF6A2536
+:10D26000D265E81AF23E63F1B0BF510E3B609E6793
+:10D270008F5A88BF3BF2C51A2A79FE9D47E4896D13
+:10D280008B9F57ABE53755354E9F3A0EE55B23D75D
+:10D29000E31DF94E57CB0F7B1BF079FD35E06D9BFD
+:10D2A000C8FF8BC1DB59FC0FC0CF2F2CC6FCB0CF01
+:10D2B0001BEF7DEAD7F8AE31FE79328D8FAF062FA6
+:10D2C0002D6F779EC517B220DFECF80DE5E121BE8A
+:10D2D000CA3DA8E73FEF8D71CB4FD508C50323BBEF
+:10D2E0002C6ECCDB5AB4EB3DE28F73CF1FA1BC5840
+:10D2F00026F267CFB18E1FCF77143189EA4D4E9E4B
+:10D300005726E08E79671E173D17F9659C6EB5BCF0
+:10D31000B344F966EF5872C5B90B9E1757E96935E2
+:10D3200023FCF57968D268C4D33143FE9EB6EED8AB
+:10D33000F1DC088751FABCC944F97CC21EEFC01366
+:10D3400097C3E736883CCA8EFC48C67A1660BE0F83
+:10D35000D777D521E93D16871FB5BCC9D6587E0CB5
+:10D360005D5BBEE4D5E7FB8FC163BF85C79F34B863
+:10D370009CB91C5F1E7F26F81BFC92D316DDB99466
+:10D3800039C22FD1F2C8B4F9D63570BD7B660BB760
+:10D390000B63F9B94AC4DB63BFF395F84E55D3DE8E
+:10D3A000A12877CEEC7B49D01BA7E7AA6DC7CC415B
+:10D3B000219F437AF98CE3C59127B2958F077E6C44
+:10D3C000DCF1AAB79D8F3BDE69C5773BCEFF742B9E
+:10D3D000B7334E37C8134371C63F2BF44FC7BA9DBE
+:10D3E00066F2AB64979DE4CF03CED14793BB6169EE
+:10D3F000A6FC8595CB45BEC30FBC9908E795CE9B8F
+:10D4000019CE6735C247E767AAEE00433B47CDF424
+:10D410008F40FF499BAFF6DEDCCDC4427AFC2BC1C6
+:10D420009E18779D92FBA582FAA57599F15C47AB92
+:10D43000E23E9006E3B596495EB467BBD29971FCB3
+:10D440005B7CB2211E86B1675CD705AF89F0E934F9
+:10D4500085DDD084396DAD99E4C8799847C9A09429
+:10D460006EDADF7E64D9965E78CECAC5BC12BE770E
+:10D470007A3BCEB7D078C92C36CF9ABDDDB790892C
+:10D4800023C0F8DEBD17E312F6016C009EDF713396
+:10D49000BB17EF57784C9C7B5CEB0C90BE4DC837AC
+:10D4A0005E7EEE458B13258F560CE762527CC67A62
+:10D4B0005ACC39484D5ED3113A80FF0471EF43CA0C
+:10D4C00078BE7E8C57F5CBE89C6F4A3AF386F1FD27
+:10D4D0006407E5333B1C7C7EDA7C613E240F004C04
+:10D4E0007C3EF96D41B4C3615E317CCCE8DC13CC89
+:10D4F000EF78CCFC0C76DC1D56A11F14A6A01C7185
+:10D50000585B9980F305639E699061DE4172075C08
+:10D51000E13D8C93234DB560DE821BBDE03CFA5E9D
+:10D520004CBF9E6EFD79B1EB85DE28CA64F974AEFE
+:10D53000B0B91BC9ADDCDA127602EA523DA78FBE44
+:10D540006B19D17DDF88C8635965277B4CBB774059
+:10D550005258502DE8A43780C80A3C17AAAC019A4B
+:10D56000817ECD9112D3BD00D4067C05E3DF6BF53F
+:10D570003D68857675B704324DC37039C5AB5A8A9C
+:10D58000E814EF408C309996FB5A0EF62251C3D81E
+:10D590000DF8DED782B45AAFD54120E27D0BF5F607
+:10D5A0008EBACF0A72B23E97D757AEF1AD5A03E3A7
+:10D5B000C94EFF4A2BF2B1D53D88F62FC2D776EE81
+:10D5C0005D9BE7804DE1523B4CE2E6080014F0DF42
+:10D5D0000F7990ECE4563312C96687560F931DED10
+:10D5E0006F3C427E7965C3117A6FC23A947DD2C294
+:10D5F000A5D9B0CE8DD65BCA3207C2788D73334DB4
+:10D6000020A27F63BDA54549D7C3E156031C9415ED
+:10D61000D35B0E8ED3C3617A0BEAEB6B85C36FD6F7
+:10D620004C5FB5A6E7B5AF3BCBE6DF8A7899546C83
+:10D63000223935EAA883FC35F8D9283E25C6D99089
+:10D64000E0DCA3668F6BED343A4A442779CC3D8801
+:10D65000EB1723BDD4637E37C6EF02016FD9F04EBE
+:10D660003A65EEC0703C9F9E65BB3B6CD5C5F52608
+:10D67000152F9573613E943303CFD36B83B6FE4071
+:10D68000A7E93E13E52367D90207705DAE99913093
+:10D69000E6EA8C6281FBA5BC4E7AD7BE53B78BFB02
+:10D6A000A975734DA115240FDA245C7727DEDB62A0
+:10D6B000F01EE1786F3A4678AF6A3EC6F1DEB4BC40
+:10D6C000C42EF637D00FAC67916188CF0FD6549631
+:10D6D0002940D77D922275480F2A5B5C566E23B88D
+:10D6E000BF8FEBE90277313F0DFE89F0567F30F7AF
+:10D6F00047F9E8271D32D17E8606AF8E76369E77B3
+:10D70000B7C71EF80B7EA77A74DBAB28DE771C7CCC
+:10D710008BF6D55D87A6EDC5FEAE1980094FE7777C
+:10D72000EB0FAD2841FAAF8F50580DE44C248876AA
+:10D7300047627870BEE88047E331828F09EBF07C66
+:10D74000AB389752D424F950EFF64902BB04CAAF64
+:10D75000ACDC2F74DA645A8FD3C6F57BFAA17D3224
+:10D76000FA1945AB4CD43E1DCB7CFDFA57897E8A15
+:10D7700021CF4CC3A74647403849B7C09CC72407B0
+:10D78000CCB6917ABA494DCA85F7A35AEEBE1FF5B9
+:10D790009BD6EF27CB98F71EDDF972A09F13067A70
+:10D7A0001BA2DA106E5A7BA44B7F9C7B17A05F37BD
+:10D7B0005B3AFF0EC655B7B72C95E99CE235E2B54A
+:10D7C000D0C26A70FE8549AC6607F42F4C8612EB16
+:10D7D00069A2DE5DD4B345D9473C1FCCEB791F7AF3
+:10D7E0004D9203E3343C6E38D426F67315F720E4EB
+:10D7F000A3A1361E1F2FCAB493FCD7F8550170E2BF
+:10D800007EA322F61D7323B926C4A3C6BF4AC4143F
+:10D8100076821ECC553C26DC7F7E7D19C041492C8A
+:10D820005F6E1EC8CF8FC53E1F6B3319CE83FB3A88
+:10D83000CF778E453C555ADB7E320DDE560DBC4807
+:10D84000FB3F2B92AAC65EE91C78EC3C5EBFFCBB9A
+:10D8500024A4AFE6A825EE799107C4FA0F2E9B49C0
+:10D86000FD1ED6CE8308BBE55B249AA0ECCBE34734
+:10D870008596A0928AFA2F89C73B0A93B87E64DD09
+:10D8800073E89E8C42EC8BC2FABA4194B752981658
+:10D890002AA7FAE03CC6F33E75F98516D6615F11FA
+:10D8A000CA73119F819578AE86C93934FE8DCC68D4
+:10D8B0004F1566D7ECA7F7961CDA8762516EDF68C2
+:10D8C000F6D078B1BF52D8A7BE8CE699CCC72966EE
+:10D8D000C6F3C385D70515BCE782E5E5D0BC4AADE4
+:10D8E00031EF07F3FB45B4758CEF6247D57BF19EB2
+:10D8F000914903E67ACBC4F38BF06F1F0B9B734BFC
+:10D900007EA77CBFC97387B7CC607FD47B910FDFC4
+:10D91000F85A9E136F1FFCB0E0FB83CBFC5EDC6FFC
+:10D920007CCE06F800BFBBC423AD727AAE0EBF58E2
+:10D93000BCC5C2EF5BCDF3C97E8B855BF187DEB2E0
+:10D94000544F5738C5C2653CAB1F40F7D70838C79E
+:10D95000C2E5752BA787D7F32D21F42F5E5700CE94
+:10D9600080AFD73D12F91B85E27E0D20724E2F1A33
+:10D97000FD24E5707A4936C23D16BEB1F0D4E4C04C
+:10D98000AB082FCA2FF1958FCFE85C7F61F79A968D
+:10D99000141DBD68EB2FCC1674BAA73F9F8726379E
+:10D9A000AE137244C80FCD5E1E2FC6037B99ECE107
+:10D9B000D27427C5654B2BF938A5FD1C1B31BF81DF
+:10D9C000856FA47CD942267E516EDF823DCAE9B3C1
+:10D9D00079C229F4AFFB5802AB9C18879052685F5C
+:10D9E00009E07E3C06EEC78D7037DAC9B170780E5B
+:10D9F000FF634C577869F4D6621376750FD613ED32
+:10DA0000DEA12F8D4846F9CD9A53E3FAE9A38EFAA9
+:10DA10003BC611744B7429B140C77337D041D380D2
+:10DA2000D58FA13933D65A2F23FD8D65BE34BCCF97
+:10DA3000049364719EDABC864BFE77509E8D699B81
+:10DA400098A6BFDF44FBBE06E77102CEE358702FF5
+:10DA5000C651C631E5AFFA788336DE9F6C22DE9080
+:10DA6000CDB2713D45B83990DE399EB6BE3E792CB7
+:10DA70004CF7DF48563AA707FF0B9A533BBFA7E581
+:10DA80003F4F724EFBD44672B886F13C9F3021B1B5
+:10DA900048BC2F12F78CB18892E85E29F64D52E708
+:10DAA000FCBEB0490ADD9321E677768B3588F946CE
+:10DAB0000F49814BF89D33D2A1A1C4AF4AB83FDDD5
+:10DAC0003311F3FE62534B15BE8776F3A99D58D7E9
+:10DAD0006299C77923BB2C749F4F42FBD30AAA4B90
+:10DAE00027078AEC5C8E8CC7785F1EC90B05CBDDDF
+:10DAF000E779DE7871538182DF397081E759973099
+:10DB00009F827ED78D51A3BF76553A75C7C66FC425
+:10DB1000BD444AA437C255B3CBF2ED81EE76C0D7EF
+:10DB20002A21DF9ACF4FF020BE360E1879F37468A1
+:10DB3000923B70F834342B4CD65615F5DD5D82AE31
+:10DB400046235D4964F56874E5B1A31DBD2686AE24
+:10DB5000DCA9063F6E160BD381C7A21AF592C11F2E
+:10DB6000147648AC7DDE6997D7C7F5E7580B38A81F
+:10DB7000403FB3057C57A5988328B794FB78BECF68
+:10DB80005D8CF5C63CA0BB6A5483FF393B4521FC44
+:10DB9000CD5E6EA33C4FBC376A2ED403F09CCE35CD
+:10DBA0000CE0F74875E0B356D71FE9C09141743BCC
+:10DBB0005BEC87FF49E27EF8EC944FD2C9690FAA6B
+:10DBC00017F4F419FBFD84E3C6F45B25F178CE2A43
+:10DBD000D597E9D5D91B13EDDC7EBAE02E5B67BA89
+:10DBE000C2FD06016B8F7C45771F505B8A7566BC52
+:10DBF0007B24B4F1347BAF28C0FDF044E3F68D9470
+:10DC0000911D66FA795846FBBA6F84913D5C14F118
+:10DC100099E619EC72EE8F76B1CBF13E03A82F692D
+:10DC2000DCCBEDF286E564DF2F01FB1EE5F906DCB7
+:10DC3000F3ECC1F884F2C95EEFF02B31BFA5A84127
+:10DC4000EAF03B15C07B5E3D6FBFEA9171EAC30A03
+:10DC5000FA85814CD58BE18192D556F073EA7298A2
+:10DC60008D819FB3C25E327E2DFAA5A93E89A55053
+:10DC70007DB523EBDAFDD855F6E2D5E8C726F227C5
+:10DC8000ABED1E825F227F5276FA57D975710090F4
+:10DC90008B71ED8F49CE9235D84E93170F9BC27979
+:10DCA0003FED46F941945F7173EDDD64EF4FAEAD2A
+:10DCB000F0E2956EEDFB2EF7C7FC8A2281EF5FD86C
+:10DCC000B93D599DC4ED48490AFC02F9B375C0D36A
+:10DCD0006B0B803F6635F1BC0DDB75977BD37D40C8
+:10DCE000239FFE79018CFF5144A1F842B393C79B57
+:10DCF0003F6212D9AB45472CFE46C0C365905076B3
+:10DD00009DDF729995519DF5CC309C0FFE88EDCD2D
+:10DD1000FB297C2758C3F3942ED4E42423DE9B559F
+:10DD200063FC77AB9DE7B76D15F4370BEF8D1C8E59
+:10DD3000EDC2D9787FCB2C25AC527E46D4CCEF39BE
+:10DD40008479E07C9A6DC67176DAB9DFB5D3CEED11
+:10DD5000F859E2DEC9665BEC380A1F5FDC33170B4B
+:10DD6000F7347BE98BB89ECBCCD744780279857A9F
+:10DD7000A16844CB51B417AEAE7F7C12EA9FEACBC8
+:10DD800052B80FC6A71B55F2DFCF8873E2671BF7A7
+:10DD900067DC0D65E5F63FB8D0DF7B4DE0E9ACD23E
+:10DDA0004AF7BC2C795EA67B0AE0BB19DFA1FEF323
+:10DDB0000AF9392B7E4E48D3CB055FEFCFF6F3E05F
+:10DDC000209DFBD1ECCE71D66008E7D7BC5C26B9AC
+:10DDD000017ADB70EFCF8DE2DE9F587BF463BB16D8
+:10DDE00067CEA0BC9F07DCFC3B89F8BF289ACA42DB
+:10DDF0003AF950A484659C7F5134838500BE670F37
+:10DE0000E63E568EF4CA546F3F1C56612D640F8B4C
+:10DE1000FD1BF8B5E0FD74BB45654FE3C5E96389BB
+:10DE2000F9DCAB06439B6F8503DDC83EC610686115
+:10DE3000A7DD7763D418578DB5934B9A87AD42937E
+:10DE4000F20C3E40FA8BF07B91BAD8CF910971ED7C
+:10DE500066C61E2538143C9F3709EF7B2978CDE430
+:10DE6000C6EFEE41BEC6787EE345BA8FA48A856FC1
+:10DE7000C3F7558DB23BCCAE14CF5AF5C68D308F5B
+:10DE80003D11C583FCBF27D2621D4A7513C5318A77
+:10DE90000E170D46BE6D8E2814FF2F3ADF92342FD9
+:10DEA000BFD37E69BE6CA2E77B2EEFA3E7DAB8CDC5
+:10DEB00091D4C1A88FB79BB83FDDF2EAA52494A7FF
+:10DEC0007B2E5F48E3F70F2DD7EE058AB59B092E11
+:10DED000A54EB923CEACB7D3995CF436E62B8D4F63
+:10DEE00056994C78E0FE6617FBE343B6CAC9BADA26
+:10DEF000212568D7C871EC914E781BECE7FE49C22A
+:10DF00007EECC50AF03EB7A6CB698BE95C677392DD
+:10DF10007B05C59DB8FDD0DE72FA6793F0F92199B3
+:10DF20009FEBBF2C133FEDDBBDB84F9B430FEF3A88
+:10DF3000C2DF1759E7CFBD02EDBF3860A77839536C
+:10DF4000BC83E3C5453AE3C4E11E7C7F2BD883DF65
+:10DF50003FC3E300DFEA8C0314258DE4F737A15AB1
+:10DF6000EABFFE9819E3287BECFE6F2511DF34240D
+:10DF7000A19CA8B073B9146425D96024B1E70F9AA5
+:10DF80004A904E462CF710BEB7AA604A215F6CE655
+:10DF90007EFB563C070AE32C6CA837E7E8F0BB5041
+:10DFA000EC377DAA067BA7EA9EFF3E89FBA59F1E54
+:10DFB00058F414E523BC6F61FDE2D89FA1242E071D
+:10DFC000779A8393B661BBE3263AE7D1F2EACBAF07
+:10DFD000F600FC2E3CEA1986F27F599287E0D57450
+:10DFE000686B5D0F68D7F4216A4930B937CD954D1C
+:10DFF000F0DD579887C7F3DE36D17C3BE29F6007A0
+:10E00000E27A7F20E6F3CA419361FFEA153BD76BC2
+:10E0100095492ABD9F97C4E3693B0E96A461FEE92A
+:10E020001E7B603EC2B3FA93B63A97A733FEA7D9D8
+:10E030008163DEDE316908FCE798332637A2CFF32F
+:10E04000F64619D7EBF994B114A96B7C0AC6AB411B
+:10E050003C68E3BD72868F07F3D887FC1659CEDC87
+:10E060009497C9FC3FCA87FA2BAD4A2AE62D6D1555
+:10E07000FBAA1A1EB4F568F3F03430DF0607B18648
+:10E080006FC795E2CC223F72B8909B5FDB7DC124C5
+:10E090001E07247BFBD30376B2BB768A7835CB9CF4
+:10E0A000DB07E1A7E169BD2863E793E8FB8F2771F0
+:10E0B000BDA1955B554F90E8E179AE6FB73AC3D6F5
+:10E0C0003C947F2FE551DD130C260DC53CA8A67EA0
+:10E0D0005EDCEFC3FCCF24DD3EEB3841E79E868853
+:10E0E00039478787C4728DC3BD837E9406A2ABA6D1
+:10E0F000A38CF86DD196FB787C11E481B8CF89F6BA
+:10E100008F912FC43E7296C44B17F2C998E60D2B1F
+:10E11000B33D74BE80F66D353878902FA0DC2DF0BD
+:10E120008270C1F72F89756BEF5F14F01B2FE72703
+:10E13000EBF31163CB3DCB3229A6A8D55F12F35F79
+:10E14000C81E253B74E1E57AB24F3D35BC5CF80052
+:10E150002FFBAF9F6BC6F8EFC275F1EFAD1B95C4F7
+:10E16000ED97B3820F98C9DE03F3393AF46312D7FF
+:10E17000AFA71A1FDB9F4DFA24F02AD2C70D4D8F8F
+:10E18000FE12C1A4D1FFA94D2AF5D7E488D6FF0D10
+:10E1900031FEF36F73FE19B3492DC17B8CC6049910
+:10E1A0001BE3E4AF6CDA2CA35C7F05F92387CB0D6E
+:10E1B000D4C79F1E7824E921A483632686F1F89DA5
+:10E1C0006656B15D87DF960D2F1AE4C1A22DCB27CD
+:10E1D000E138A3DA522594FF9A1CD0F0BDD3ECBDF0
+:10E1E00089E4C994187952C6FB47053C1F13F2E431
+:10E1F000B189204FE051CAA61409C7D9698E7FAFF3
+:10E20000D5671ADF097A1CDB29773FE372B7CD9512
+:10E2100007E3544DBE40F1D78EEF08BA7BAC4CA358
+:10E22000BB1C09E108F6BCA92FAE1BE083F40FF676
+:10E23000FC9C69F9C4A50715DAF711FB48226F8227
+:10E24000384CC7BF9A9CFBDA1EF81BF2496159CDC6
+:10E250004AF433D2CA8344D7A7A4409F54D057A7C7
+:10E2600090AFE3C885E3623D5FA8813EEE38EF3BA7
+:10E27000F988F5403EA8600113AE83AD97DCFAF350
+:10E280000F9EF59CDE521C92217F5CAB6BF0BA9125
+:10E2900075DC3398E248273D65C6BCCAFE21AEA7AF
+:10E2A000985442F4C84C37F7407E3BA532A29F53A6
+:10E2B0002017116E0BED463F445B574F07E7AB2F1E
+:10E2C00052F83AFE28F88E7CDC91D48EDB59C526B4
+:10E2D000DA8745FA207A9B924A7E0A38460AF17913
+:10E2E000C73E435896B83C90711E6EF4DF280EB4BA
+:10E2F00081E7856DDB40749332D14DE7191E53BC25
+:10E30000B6145D1CB765F3E3E437223DE11C12D17E
+:10E310006305D2238B438721A043E8973AB186F067
+:10E3200008F81DE5807153CA0232D24D2C7EB5FD2E
+:10E33000430D1E3B63F61BBFE7E07C3951949E04FE
+:10E3400079279D7AC2286F015FDFE6F8EAA46FC4DF
+:10E350009BC66FC31D57A6F39083DF075EF7D13CC2
+:10E36000CAF7D0F699B47D63EDFB77087A49B44FCC
+:10E3700094650BCC7418F6A396D27E97C627DADF85
+:10E38000A558BA99E7BD6DC73708F7167B487F5E79
+:10E39000CFAD301FE2B3C29143DFD3F0EBA935B369
+:10E3A000BEE02F7C9133B7055F7DBB35583E04D668
+:10E3B000B1DD1C9C3199EC6EEF4D38FE4DE526F732
+:10E3C0002312E60BB8258C771089235F1CE2DF61EE
+:10E3D0001EAF61DE4B05DC353C697048A4AF12E12D
+:10E3E0002724E0932EDEC7F275B983F373BEE35A98
+:10E3F000F93A2823DDBB586005DE3FCD8AB81CEA18
+:10E40000E0EB2246FB886BC578DA73AD1E87AFD789
+:10E410003A46EAF87A749B91AFC1C215FA94F82B88
+:10E420007D93CAF368059F7D61E3F3FD9583DB630C
+:10E43000E9A83F007FE941BE9FBA54D0195010E5CA
+:10E44000E5D56FB230C483C6F7AE19AC44C57D596B
+:10E45000D437D86A46E0E838DC8FCD347B707FF85B
+:10E46000941A213C9D0207B59EF0E9A73C935307FF
+:10E470006EE0F2607287FEF1E17E4FF08F3DF97E33
+:10E480008EDC4C74BD743C23FDD1B27914D141456E
+:10E4900079AE8474B6684B8A84EF53CBDC26592757
+:10E4A0001747D59A58DFE144B7CF3974727154B029
+:10E4B0004646B8F4490B64AA29603738E64CD0C701
+:10E4C0007F5E81BA3EFE03F5BABF27FEB37BED5DEA
+:10E4D0007518FF694FF235233EB26CFEDDF8FDC2C0
+:10E4E000EC1A99E9E4C5D5ECA66A113FFA70F5EB90
+:10E4F0009BE7C2BA673D1C598D6FE7607C7500E6EB
+:10E5000005F0F86A75F3118ABB360B7E1E2EF90FE3
+:10E51000E377EFAAB9C918678D5CDB77BB09BE65E5
+:10E520001F32827F377F8D8CF1084D2E7C807F8F4C
+:10E5300081FB8D12EEAB69FC807205ED4F2DBF01A2
+:10E54000E35ECED44EB98CF5649D5E5D5B6E8A7BD6
+:10E550005FED6987C3A0B73439C89AFFF6C243DAC2
+:10E56000BD995C2E9E76E8F4FE63E5C7E93C311365
+:10E57000F7D0DD2F7CC8A756787F7F5DB7CE73ECD0
+:10E58000C32CE620E64F82DBEB71EBF261A5662936
+:10E59000ECC43CCB4BE8B900FE2E99A87CEADFFD29
+:10E5A0001373D08F6F3279C112C03C09A2636F1F01
+:10E5B00046E71E1AC43E6CF17E874F1D81F7E65B6D
+:10E5C00049FEB5EFB50791AFDB9D268A1FB7ECB2C8
+:10E5D000105C2FF6B50BBF3A64F0BFB5FD0D9BA5DF
+:10E5E000EDAD22E8BFD1C6C7DDF8707FBA4F23D1A9
+:10E5F0007E77516D2EC5F3B4F8626EC463E2496153
+:10E600007C7C25C2685DDAFEF73ACCBF189138FFF2
+:10E61000A297D3ACF94B194EA4C3996DAFE2DC625B
+:10E62000FDAF8C43C7F7E23819B53C2CB0EED052A1
+:10E6300009D7B76E567CFF4BA39F7522CEA5CB732F
+:10E64000C873EAF5CADCD4A45C9DDCD4FAFD52E4BC
+:10E65000398C6AB97B27DA77C0D7694E1D5F4F1AAC
+:10E66000B2DA166FBFDD5FFB10C53F13D1BDDFC44B
+:10E67000EF5B8A7D3EDE29EC1825D283ECC03D5F3E
+:10E68000D83D71F21FFCBB4CF47741B4784CD7EF06
+:10E69000FF3BCDFF4667C7BE5E8F6BD9D78B9D779B
+:10E6A000ABCA7AC5D327B17993DAF7E2F4BF4B7FCF
+:10E6B000EF81DFCC02DB1D5DFB69F6AE5FE2F74E5A
+:10E6C000B18F18E9558D4E00EE7720BE861E9E371D
+:10E6D0001C43A9CC5A23A31CB8D8D4928D71AA4448
+:10E6E0007EA1361FF8F58B1767F1E3BD4A71D67727
+:10E6F000BFC0835FE5F6A7547CE03B382FFF79B3BA
+:10E70000A43F8731C72919F8498B83369F7F773813
+:10E71000C947359C1D0F7EB1FB96733068C5F51C4B
+:10E720008783804B5D312BB174A33801DBE841FF57
+:10E730008FCB494F2D23FEBE5EF2D1BA5738B95D5B
+:10E74000B38EB5525EE3C5433C0F79E87D1EFAFBFC
+:10E750005CA00F8248B7A35860A74997D7A5D143BB
+:10E76000DDB3609F18E2559C7F34BFB59788FBF4FA
+:10E77000C47B4274EDBACF0452D5C9FBAC80952955
+:10E78000BAF85A7685DB50EF559369689F190C4BA0
+:10E79000C85799B51EC3F34E39C5D7DB2BC836A071
+:10E7A000DE5FC7DA687DBDC57CAE9702441F170FD8
+:10E7B0009D48C5386448E003D6FB24ADB736705198
+:10E7C0004F1FDA7AAFB6AE0F97C17C80EFFF847E21
+:10E7D0003994773D704CEA4E707753DAEF1CD1AF25
+:10E7E000D7F78F90FFD8ABA695ECF7D9B57B25D49A
+:10E7F0005B2037A8DFBA65562A7FBDCC4D3254C3A3
+:10E800006F4F68877947DA7DF089F4D22EE735EBD0
+:10E81000A55DCE387AC9648DBC86FBDB95CDB20789
+:10E82000E960E5F753297FE2A9067E2E717F33CF99
+:10E83000E77BAA8EE76D6BDF3DF77C32EDEF9C1333
+:10E84000FB7CCC7729631AED7B5FCAC0F3451F3B85
+:10E85000026FE8E5E053CD9FDB505F0CD6F26463B6
+:10E86000F40B0A5E3CAF42671F25B47B86AD917105
+:10E870001DB70586634A1BF0F73B9C3EB91EFACDD7
+:10E88000B61293FE9E8E8B4D7F9DBDCFD3B96FA4E4
+:10E89000ED2B69EFB57D27490A7CAC97EBB1FB4ABC
+:10E8A000B1FB21B2CB4A79D65ED9EE958D7A95E847
+:10E8B0006E653FAE3757EEB513DC56F673D0FE2DBE
+:10E8C000CCF70CCEB705F4169EC3BB78D441EDB49B
+:10E8D000F9C37C871ED2CDB7DA1499BD4F8A3BDFCE
+:10E8E000CFF570EC3A5F633EB2363FD9A9D0BCDBBE
+:10E8F00099DD8B786B30F3FBDB826FDA291EDAEE61
+:10E90000BB64C37B83DBD9251BC6694F3B02920BDB
+:10E91000BE23F78AB8D00FD9DF7C7120D27FA27DC9
+:10E92000BE41CE1215DBC33AAD588E72072E6E6310
+:10E930009CCF0257E837C959E2708DFCBBD69FEED9
+:10E94000BA22BE8CEBAFC6BF83A2B3A324216F63F0
+:10E95000E94D6ADEFB15C6F581BF285F34D89B857B
+:10E9600056029CEA8608BA9BC1C4DF4132D2C3C7B3
+:10E970000E7F3F5CAFC6975780CF409CF75B0EFF82
+:10E98000606C8FF3C0F33C207786B8B89EDA894775
+:10E990009635FBA94F1E97639114467926B1FBB3B8
+:10E9A000939CD34660BFDC011E13DEE3FE77D0FBF1
+:10E9B000B82BC32F4C792ADA79E24ADC27C4737C5E
+:10E9C0008DEA19E3DF4B32C2E1B4C3FF6D1C375847
+:10E9D000D249572B3D5784C72484C35B8EC0142C67
+:10E9E0009D2AD00B0265F45CFAFB555936DF2ADC10
+:10E9F000BFDCBA9CC3A1FD590E87ED2D26A2E30D05
+:10EA00006C10F1DF20D385D9383EC8979938CE886D
+:10EA1000D67A13E6F3F50B794C748F536B83C97474
+:10EA200065BA9D25E8768EC0C3FD8887C1DB785C1A
+:10EA3000E50A743B4FD0EDB5C27D89EB8A7CDB855E
+:10EA4000AE6AF47475ADF9439238071B3B1E636DD3
+:10EA500014BFDFFB9285E477D50E7EEEB76AF749E7
+:10EA60003A2F5AF5B28588B2EC651B3FBFD2C8DF9A
+:10EA70009F2B8EBFBFFC6F2EEE5F5536DCE7D5EBCC
+:10EA80006BCD0EF8A9EF82BBAFDCB94F9736999FDB
+:10EA9000075969D3F241F97E9D4BD0595A2FBF0FC8
+:10EAA000F54EDA781E177239E6D37E5DD7731F9C58
+:10EAB0006FD3453FB7DB43F640EC399074BC179CED
+:10EAC000EFBB12BDC826BB17F72DD326C6B4734CB7
+:10EAD000A4FCB9F498FDBC904BD8C166964972D499
+:10EAE00016FFBC9792ACD97376935E9EA09CA7FB51
+:10EAF0007A9C565AF7D27496568EF101A742E73D9A
+:10EB000063C7D1CA149FC9709E286DA2DD705F468D
+:10EB1000BA3FD550EF3EB387A17D5620D7F03EBB1C
+:10EB20006290E17DAF9A0243BD4FED0D86F639400C
+:10EB300070FA7ADE9A9B0DEDFBD54F33D4AF5B773D
+:10EB4000A7A1FDC0D0DD86F783B72C32BC1FD2B0A1
+:10EB5000D450BFBEE921437B39817DADC159D6EC8C
+:10EB60006BE788009D1F735A25BD1D72D8C5EDF057
+:10EB7000629795E0BF5AE8E3D5E2BCD96AA18F5B02
+:10EB8000D20BAFB8BFF28FFA63675DC6B8578988FA
+:10EB90007B9DDB673621DD57ED07BAA0BFCB15386B
+:10EBA000EBE2F6D794B9B47A7E8EB235413EC79780
+:10EBB0002ECDCF03BF248E7F674AF6C4F5AF40AE9B
+:10EBC0005D72E9FD205623A31CD0E452751223BBCD
+:10EBD000ADDD15ED8F7C04724A4A4E47F9F458CDED
+:10EBE0003E944FCD16924FAF0F38417EF5CDB5F321
+:10EBF000092E875D3C5E2B9BBD1E7ECED4A8770F71
+:10EC0000A9AD94A77D68A4CCF07E948BDE51749E50
+:10EC100039113CDF44BF1964D77E940D23AFEE77E2
+:10EC20001E5A5641F9CC89C63B34CC4671CFF29876
+:10EC30007B7007093A2A4B16F0B470FFF1EC0B4ECB
+:10EC4000CA2F3E5BF00EFDFDA2B38D7F181EA4BF40
+:10EC5000D7D57A3FEEBF07FFEAA0B84CF9B0778668
+:10EC60002F27BBD6C7FD37F177C1C6BD78D8857EC3
+:10EC700077F9F6FDDD823AFCC5FA6D65627D4C6977
+:10EC8000EB4F79A1AF9CA2BF1B53FED2816E3C2EED
+:10EC900064CC5B89F5D7CB6BAB086F5ABD326A3554
+:10ECA000E4AF542AFCDC6F65D441F92BAE64A33F7A
+:10ECB0009F105ED708CFD8E71A3C0F0D3BC5CFAFEA
+:10ECC000DBE2D36F4DB2313E1C7BAE2051FEFAED3C
+:10ECD000A2DF45EF183A075F6E0EF7BD96F8820681
+:10ECE000A7D72F2FA0F30A2F2438AFE04FE671F7F4
+:10ECF0001706DC4B79C763AC35A5A8BFC788F86594
+:10ED00009CBCE37B9247623EF33F27EFB852C38F30
+:10ED1000C8EB1D837C9CCEBAE41D5FED3CC824BCCF
+:10ED20008F3B0E7FDDD401BFF767E0BD4EF73FA1FB
+:10ED3000521ED002984310E3261B548A9F1EBE6CBD
+:10ED40006118CF3EB95E7D1AF3552A9ED8DFF331A4
+:10ED50008C5F0FB3501EDD820DFC3E1036CC16C208
+:10ED60003C8D8A0D0F66607EE467C0B74B605E0B1A
+:10ED70009E48A73C9EC32D8F64209E4E097EAEF810
+:10ED8000FA87B721FCB79BDD838741B9649B64C8D0
+:10ED9000035FB4C966A86B79401AFE98D4991FEE38
+:10EDA0000139FA78B2F17CCBF0CE7D85C793853CF2
+:10EDB0009D0EF3AD1A79D18C78DCFFAA9DE6BDC714
+:10EDC000C1EF570B0FFBF28DEBA15EFAB5A2DDABE5
+:10EDD00063C82B62B80981F79C88FCBFD297948ED8
+:10EDE000FC7CE13738C6EBF2A0C3CB6A886F4A7F60
+:10EDF000C5FDE2521BCFD74D986FC4BAE4330F4024
+:10EE000079DE25CFA8F33C84C12ED1E8A63159E4A0
+:10EE10001B09BEDEFF2ACF2B9A7F48D89357919BC0
+:10EE20006FE2BC15C4D7EBB370DFF1B080C6E1CBA5
+:10EE30002757D13D44A3258CB0B19397E3F38D5967
+:10EE4000939F98BF3FA0133F93BD0B3BEAC89653D7
+:10EE500047DF67385770EDF2E6CAF2A436999FBFD4
+:10EE60008B95EFB174FF7F4ABE970F3BD01BCFC984
+:10EE700043F99F745E7E3B978FB17C1E2BCF6F8AC8
+:10EE800091839D72DC6490E337097DDE29CFCD2428
+:10EE9000CFC13CE3F7B7142AA19512F93D5FA0BE9C
+:10EEA000CE7778D28AA1CB2A776E52E0CA7EE82547
+:10EEB000E493765BE06B2CFBFC6610FD5DCFC1DB61
+:10EEC000EA4DC8BFED09EC8FFF0D39A0FC7700803B
+:10EED000000000001F8B080000000000000BCD7D2B
+:10EEE000097C94D5B5F8FDE69B2DC94C3299EC2BE5
+:10EEF00013761570801010A27E4900A3101C5001DB
+:10EF000035E82490842D24205AFA6A5F262460C4B0
+:10EF10006843B58A8A7650F051450D8235B651273F
+:10EF20008014AC4BACB6A5AD621044362582FAA76E
+:10EF30007D2AEF9C73EFCDCC3799B0F4F97EBF7F7B
+:10EF4000FAB397FBDDFDECE7DC6566451B181BC3D8
+:10EF5000D8B32636BBD506A902E930C6CEE2DFD546
+:10EF60008CC5380A66452731B6DF0A29D463CCEA56
+:10EF7000383494B15C6660712A63258A37C601E52E
+:10EF8000D5D6AE07CAA074C96FBE354311DB10EDEC
+:10EF90004D352632E64B37BB37E504FB93699203C8
+:10EFA0002A41BBFE2B0AD9C104C62C56E68B1AC5D2
+:10EFB0009862643ED3281CC7B5D200ED8D4D8CAD50
+:10EFC00081F6B17646F36443530D2C99B13BAC8C7A
+:10EFD000FE7C850C27C37C3BA2FD0D0A63DF332D2D
+:10EFE00003E7F303D3321D50FF23A665615E8EDB7A
+:10EFF00028D6693430EF565BEF79CD74287C1CE657
+:10F0000019EC81312B0A9937141E322D7018A95E24
+:10F01000C1C337677741F9671DB76433E86FD7AF6E
+:10F02000C6C67545A82FD3B575B5EE89D0F4FE3A9E
+:10F030002FA5F18C69389F5FD4CDA7BC13F25BA1DB
+:10F040007D85D933383EA49F818E788297A3E04F87
+:10F050009E01009743CDAA437141CA0CC5D8FEA0BA
+:10F060003FAE78BB6897A86BC7E7A9328DB101B0F6
+:10F070006E9BF15F5D02766719AE9751BF7DAD73F0
+:10F08000A683D38799B9ADD8DEBCE33A2BE25755B6
+:10F090003407E6253D5C0123203DDC839FAE606C98
+:10F0A000B4E2F538A89D9620CBCFE6E0F8C594975A
+:10F0B000E3B34C58715ADFF0628A7613E2EF08D35B
+:10F0C00066627FAD66769903D6DB1ACDE6479A6F06
+:10F0D000A9C05FBA43D00BB3390E5F26C683F99D32
+:10F0E0008CD16EC77ED2A23C65D86F5E46AD6A8277
+:10F0F00026B3A21DA2BEA67886537925D663A99A07
+:10F100005202F0CEFB04E810B2DBF6142A2E183FB0
+:10F11000B173A2E282F11305FE7ACD5FC0ED25C680
+:10F120008A23CD7356349FE75201FFFD560FF1D766
+:10F13000EA1C6F6A2DF4E76A659A1FDAB5E2944219
+:10F14000E0F396C34CF5374477F954A4FB5B987B06
+:10F1500013D0414ABE4F31429A31B5A50030CE1A84
+:10F160001C4EEADF59EC4D55A05E7AAAD9AD2A179C
+:10F17000CE6FC35A35D50BE3E77A0D348F759DBE3C
+:10F18000A8C130AFE44E6F8119D2A2F864EA3F857E
+:10F19000D5D6233EA03D43BE1CEDE0FFCCF516AA1C
+:10F1A000AE10B8E4CDAB6D30C3F7EFA3BD6B43F940
+:10F1B0003163B18FC639AA78FB39819E8EBE193D65
+:10F1C000DB8FFD059C4447B2DE5388D724A487C259
+:10F1D00074960AFD6F34D1BC7237FEEA36E4FFDC68
+:10F1E0008DD718951039F38AC344F58FBEB9B01F77
+:10F1F000AEDFF7370B1B14410EBD28E8E5618187B0
+:10F200006DE6C874F59C1C5FD0FB04A648F9F79C1A
+:10F21000907FB103607D4BAA4F91FC6B76B8A8FE3E
+:10F22000E3C6D6DDE900D7C7E731B70F3E2DDCBC1A
+:10F2300041C1F56E33B75EBB05E7B5C4C0107FBBF7
+:10F2400076FF6E773AE4E7CF738DB4B842DABFFD4C
+:10F25000EC6AFCFEF87C3612E19AE65FAB18003EE1
+:10F26000DF46B5D0BABFDD6461F530B5C7373E9231
+:10F270006CC77A5E8303EBF5E22340B32115D3809C
+:10F28000C9308EE311E595C49F843BAE1FE5E2AE25
+:10F290004DAFD0BCE57C8050CC08F7A27817C16B8D
+:10F2A000E1E6ADD722F1A72F762A6A4E705EE7938A
+:10F2B000FB1F0ABEB8503A7C339EF331C8790DC7A4
+:10F2C000F3E51949CE7F62F3FE1DE13ECCE64A2804
+:10F2D0008029353AFAC77861FC7E03D8ED9E08FC98
+:10F2E00078A9BD703FD63F19E53D807CDDEFB94B75
+:10F2F00027B258C62EDBD262407C9C54B85EE8CD63
+:10F30000A7423F0ABD28F5A42C3F29E8E20EA12719
+:10F3100023E8C79391F4A38BB9EE1B06F8626F1B29
+:10F32000887FC3C75D2AE87282E62D427E9E1DE378
+:10F330003D83F3BE629C7FA70AF5C716FB7622BF0A
+:10F34000E72AB53BED0017762D9703095DAC0396D0
+:10F35000C5E2F77569B1909F8B7200C61F7F44EBC1
+:10F36000C0F1E23C4CC1F6CF229DC33A5A9CECF668
+:10F37000E911E8FD36B12EC343DD66D46789ED0A95
+:10F38000F15B6FF8707904F232261EE697D70FE42E
+:10F39000694E6F791A017FCE786877C996C00EAC36
+:10F3A000352A7E600C343B17FE92E3097F5A0A8EA1
+:10F3B00023F175E959F576CFB0DEF8CA8EE7F3BFD1
+:10F3C000D3AE6561BBCF843EE80B8FC3E339FE8AC1
+:10F3D000E2B99DF3AC5DD48BD2D72B8BE778A988AB
+:10F3E000D7CB83107C0F8F8F806F29C7B7ED7949FA
+:10F3F00045BCE54D6C69403C005E47E37AC6E7D703
+:10F4000036E0F784A95C1E86E355CAC370FC86E328
+:10F4100095B17A9A1FE0E3AAF808FA4BF613AEC743
+:10F4200042E404AD6B9DA04F1FD227E3FA68832D01
+:10F43000B80EC93FB709784CF07A8BCC9C4E4B7014
+:10F44000DC2B66FB779A904EE7FB769A43E97401D2
+:10F45000A3FEE43C32BA7CB49EB47DDE024CC71FEE
+:10F4600009740C837A29B5B01E165C4F56E7870ADB
+:10F47000CAABACDA4E85A1FCDCB383E69DD9B98B6F
+:10F48000A7A88787F5D6B78CAD1474C8FB79339ECF
+:10F49000CBD5D55FCC4D45BA595DC0F5ED2ABB56ED
+:10F4A0008EF3BEC3A1CD45FCADB36BF3303F2B9AB9
+:10F4B000EB85E1F15A257ECFEA43DF2F117000B8CA
+:10F4C0005763BBC4E5CCA7C03AC6EEB3F9415500BB
+:10F4D000E9C3BC614189B53EC50C704DD4981BE5AC
+:10F4E00074BF046FBD09EA755FC1DC4F413EAED405
+:10F4F0005180F072CE7777203C577FA1927DBB7A06
+:10F5000029F3AFA47E18FF3F6F7F3FCA57E4DF5057
+:10F510007EF18979F8E2391F80BDF3F378CE9F75CB
+:10F52000C49FC2DE917CD997FD12C2D7AB2F92AF98
+:10F53000EFBF48BE5E2BF8FA97949E87AF1F0DF27F
+:10F54000F53A9CD7F9F87AB3E0E737057FF7C5D7E6
+:10F550007F10707B27BE4F3F67338ED75B8E73BAA9
+:10F56000937CF1D29E5131E5D0EF4E31CF10F9DDD1
+:10F570008AEB3B9FFCFE37F8FCF7D8EFF9EC54D947
+:10F58000AFC4F7F9F864B8D343F092F668ACDD4144
+:10F59000EB917C0FFCB247F0CB5EC12F6F613A2B31
+:10F5A0009ADB07E1FCD5A3EF3AB93C014F2606E907
+:10F5B000478E7FA437BCFE12095E594CC0AB98CB76
+:10F5C000914CE65363B1DFA90ECA3B4E38EAD155E0
+:10F5D0008C3DD4ED43B87D1BCFFDCC5C857922D921
+:10F5E00075C7049F247616927C01781EC27125BDD2
+:10F5F0002732C714F473A29C5C6E8C1EA7ED44B92D
+:10F60000E4D03C2ADA1BB94ECE0F124ED0FE8B4806
+:10F61000F8D88EF818D6DB6F08C7C3A762BE514E64
+:10F620000E8FF0FEA5FCC1FE8753FF2E03F62FDBE5
+:10F63000FF109443DF237EC62EAF55715D894C8B3E
+:10F6400041F923E524CB84F6B9BDDB9BC4B8D0DEF9
+:10F65000E484746C2DB41F166C9FC5020AC2C339B2
+:10F660001FE41443FBDD4DF66C9BD5637312BD3074
+:10F670002EAF0A0C240FA6D934E2A748FADF7991FD
+:10F68000FADF29F4BFF342F4BF33A8FFB19D723E05
+:10F69000FD2FEA8F709E5B4EB87BF022E304BDF530
+:10F6A000BF3382FEDF6FD5A8DF087C3412D713E3A7
+:10F6B000D046610A7C34DA9914D43BD06E0C7E6F4C
+:10F6C00013ED9BA71A86927DCDA2DD91FC9942A7EE
+:10F6D0004D37AF2B859FC2DAFFFBB7FF91C7580D9F
+:10F6E00016F179163A43FC9607A77E9AEC253F8ED1
+:10F6F000E9E22BBF5EE97E6F088EF7AECA90BF7E4F
+:10F70000FD9F5D6684776B74EC0816171CB7E65F87
+:10F71000405860CF9FFC97815289C725EDCA680683
+:10F720000C59B0F33B8A939CECF817C5492EB5975A
+:10F73000CFC075ED7A8DC74B4EBF7DD0897424C77D
+:10F740005F26FCC849EAB0D600D0D3A9CD6637FA07
+:10F75000212A733D920FF3A9D963627E9283CC8AEA
+:10F76000F54D7CBACCB47975A71A8B79A34FC439FF
+:10F7700094B3A4EF5C714897A63D2AF9152C919794
+:10F78000D7326BFDD9FE2057C719982B242E12AF04
+:10F79000453357489C22A1D8A9CB338CA7C0B88B3E
+:10F7A000189F6792275DD73E65767F5DFD34EFA594
+:10F7B000BAF28CF9A374F9ACDAF1BAFAFDC03F0AD7
+:10F7C000CDE7F8AED3D51FD03443971FD4728BAE9C
+:10F7D000FEE7ACF6E17C5CB74FEB1C08F39C27E638
+:10F7E00039645DB9AEDDA586D63CE068362FB070D1
+:10F7F0002A1B01FCE85FA8EBE7F8B3C57B14F8CE41
+:10F800005A4C8738BC6A19C28BD60FF0AC6C53D8EF
+:10F8100063D0BE6A1D2F97EDE6B7AF5D9D01E9028B
+:10F82000BFFE3B637E33CAFD459BF5DF1F74DA13D1
+:10F83000294E93CED2CFAA91E8C046E39D5AAFFAA3
+:10F840002D803FD537248C0EF4F860FF4BBA700939
+:10F85000BAB0A4EAE922CAA5A78BAABDDBF202AC22
+:10F86000379C63863A23C251C2D9EED6D38B842FFC
+:10F87000E8C9FF13F8BE81F08D09C2372DCABB035A
+:10F88000F9EF74DB7295E1785EEF686CD797FC9DB9
+:10F89000622FDC8DF2E274DBD7B7ED80F5D5C47052
+:10F8A000FE3FB9E3BBC128DF64BDEB5694BB278E96
+:10F8B00006E02ADEF7B07FF9BD73E8D3CDA3603D43
+:10F8C000A56D2AF1F149A3AD49B99C96E97200DC16
+:10F8D000941EBC713C4ABC29ED3BFFA900DE2C30D4
+:10F8E0004313C61BC7B9AD384F8CF421BD286087C0
+:10F8F0009E8D217DF231CECF57A8318AF7FC89B990
+:10F900001BA056833DEFB2F3C4050E38495F7A1B46
+:10F9100051BE8EEDF49EDE82DD1B3B1D18FF9DE285
+:10F92000F5D27A2EC70982FDC41C00277BB03DB4F6
+:10F930003B8EE34E2970C6A0BDB575D732F2DF58B5
+:10F940007B22D9834832A1764EB89F25ED46B0D3AD
+:10F950004FF17978BE7686DAE9C26E93F6765FFD6E
+:10F96000807E1D8AF6415FA9B2431D6A04B8742BDC
+:10F97000D1EEA722E80D4B82DE9FBD3218DFB22404
+:10F9800084E88925779EDE8DFA03E01D9D00F3B49F
+:10F99000DB417F2B17A4BF63B1FE2331B144D7DD18
+:10F9A0007B55FF106870CAEA8A7302BCF2519F5CF3
+:10F9B0004E712096E10CB6ABB5A60F33823EC93F1F
+:10F9C00035348E9D23AE9E8FF54607F3ED514C677F
+:10F9D00017AC1EC5E7E512EB3C10C5EDACB1225FDC
+:10F9E00013168FAA69E2F1D70D6660B5907EC62620
+:10F9F000D879BCC75A3016D7B341C4A157E7286499
+:10FA000027AC5614B21B76DA0AA9FC90B3200FE19A
+:10FA100077B918672C8C81FAB9A5BF988FB0C764E5
+:10FA2000FFDDA27EB7B390D2B1090E8117C7A588BA
+:10FA3000FF0AAB46FD9A5535229CF313B8FD5313CC
+:10FA4000CDA49F46FC3449F0D76421478BEC204776
+:10FA5000B91F387512945F25F94FCDFFD00CA43B28
+:10FA600029CEC4305E7C959057EC8CF15394270ED0
+:10FA7000F81FCA276DA863178CC40A98E9D35039B8
+:10FA800053C83AD3913E8AACFAEF93B64F3E8AF20E
+:10FA90006F123306BFE77078C738837C7063428F7C
+:10FAA0001EC84439D516DDF5CB29E81FBFA3BA9F80
+:10FAB00062BDD75B91C0EDB066B4A36D042A0DE3BF
+:10FAC00097D9621FA5777D0E9F0D7DC4792BAC055C
+:10FAD0007311BEAADD538129B0C3A5C8EF6D666F4F
+:10FAE00003FA1DDD2F339AC7503FDB81F9E13E1742
+:10FAF0002E17F0EF8B1981743DD2407EBC6B5DCB2D
+:10FB0000CE282877AD579C0AE44D46E6B38F0ACA43
+:10FB100093C6841C9A6C7357F90E3B9427AD9FAE25
+:10FB2000F487F9B4B096A258B4B7D6B38871C13A85
+:10FB30004147530A76507C3DA91BE834021DD42569
+:10FB400018A41DFF9FB88EB1DDDED14AFFA03C2274
+:10FB5000518B7ED32E833F529C769AADA811DB0D3C
+:10FB6000F7B38871BF9A683E8F26AB670DD2E9F074
+:10FB7000ED01F287AAA45C9F676046A0AB1B841CC2
+:10FB8000BF617DC73FC98EF8EEEC5955DAA18CFAFA
+:10FB9000672897AA6EB4FB317E5FD59EE3A379797F
+:10FBA00014F720486ADADFF760BE2A37D78171661A
+:10FBB000EDEF4C393C944C58C6E59F911D967A96D2
+:10FBC000EC06748A189B21E8B906FDD124D21FCD1A
+:10FBD0003100FFAAF5F53BD2A0BF3F3F0D7D40D1DC
+:10FBE0003ED5BBEF67D0EF4DA0C4568CC2D4C84AF7
+:10FBF000290E9D4AFDDC28FAF1FD0BC6B506C7BDEE
+:10FC0000A97D2FAD679F89F9AC40BFA6423EB4E9FC
+:10FC10003FE2FC0D2808999FE86CA6B56512EAD76B
+:10FC200093E6EE116EB47F5FFB6B960FE0FFF1CFB2
+:10FC30004FDBD12EFEC4D86DC7EF47EEFEC0AE013C
+:10FC4000FC3EBE5B2D4678DF26F48D847787C07B33
+:10FC500042A2A70DF1727BDDF779DE10BCB3154926
+:10FC6000C43F0BFC30C310BB63D1E618B4847AF2F6
+:10FC7000D5AD09BABCD41FD516561B290EF48DE09C
+:10FC800097055B3698335C38BEF72D1CFF8891D3FF
+:10FC9000CF91ED76BF2F27389FF22D23CD68977C2B
+:10FCA000D26E6101D483C64E13B37139A3003D787F
+:10FCB00005DEC3E7B9FBF518EAAFE2575C2E95C144
+:10FCC000582B00AEDEF605247FC2D751F1B16B721E
+:10FCD0000AC0BBE25E85E1BE0AD6BF1BF0E65D71DD
+:10FCE000CF5768E785AFB3CCA79747739BF47929C3
+:10FCF00027AB04BEE7317713DACF152DFA7A55ED2D
+:10FD0000F751FF556172EC7882B0AFF2D8D8B3608A
+:10FD1000A734D8FAC779CFA1AF4ED4815C1FCCD815
+:10FD2000B13A2BA547EA18A56D092E82F7E2F6F73E
+:10FD3000EF42BA59D2B6D58CFD34FA2739C64315ED
+:10FD40004BFBCD0CBF5B705F159ACEC17D559827DC
+:10FD5000DA3A88FFD18AE77BE44793236C9F55AC5E
+:10FD6000AF54C09FD9B85D518AEB1981DF8D5F8791
+:10FD7000AEE7D49ED1561CD79C28E4F15858977A08
+:10FD8000E1EB92EB91EB93E5D52AD05984F692BE44
+:10FD9000DB04BDCDDB387D753A80A2E1B5CFB3BBC6
+:10FDA000B85F4AF6BC51E0C7685B43F6BC9181BDC1
+:10FDB000CED729EC79F621F2ADA4B3703AAA423835
+:10FDC000500087B7B30A3BBF877EDAEF2778483CFD
+:10FDD000037FA48A7DB354DC37033A3A144647BA0A
+:10FDE0007C458B3EFFA5A92B1BF91BE8E550287C21
+:10FDF000BF0C3B6721D3A4C4FE0487792E6DB203E8
+:10FE0000CA2B986735DF5F6D21B81C31B6ECFE193F
+:10FE1000F2DD464EF79F08BCFF32D1332111F59534
+:10FE2000511B81F2BD70659A9A08F5CA9A1507F2BE
+:10FE3000D3DCC69193910F47318DFA9B9310D94E25
+:10FE40009B93C8E15F5E6B6266B0EFCB610C946B15
+:10FE5000E5DB55E273A0235B09E061BEC043F5BD5D
+:10FE60005BCD6990CEAFADE276829FF30BC095EC8F
+:10FE70008485CD1D66A457F04722F29BD403D5ADEF
+:10FE8000FAF21AD64C78A8413E93740CE3CF4E1484
+:10FE90007CE6666EA447EF5D76AB1277FEF5B2DEC8
+:10FEA00071058A3B9CDA3388ECCA532E570AD6F385
+:10FEB00002CE3BD15E367AC7E2778013E9A3EEFA31
+:10FEC000183FDACD07CE803F88369CC33B16EDA4A1
+:10FED000AEBF67B1354A903EE57A6AACCD449F35F6
+:10FEE0004CEF6F96816383FB9B659B12FC3E85FA0A
+:10FEF0001FD18676C52613D90D3EB62C95019D7966
+:10FF00005699481E96B7C593BF5BDEC8F701CAB7BE
+:10FF1000C4FB55EED77F38302F8887038D45E634F4
+:10FF2000C2538E9BE2C36D261D7D4BFC84FB8B0B65
+:10FF30009B3A76A7BA7AFB8B11F073A80FFC1C0AC8
+:10FF4000C54F73187ED8DD095CCE2C7D739015E605
+:10FF500077AA36CAAD46B037A41E6299408079C1EF
+:10FF6000F853713AC70733BA93119FA79BC710BEC6
+:10FF7000C2F154FCC35CC207FBBB9DA13D3307FC2F
+:10FF80009019F0FD7685F3C79C866B8B515F6F4AA5
+:10FF9000E472E63D904F9A99B1F7413E69209F3E49
+:10FFA00000B985F93FD7A552FEAF752E4AFF5637E7
+:10FFB00094D24362BF54F20D108019EDC2E704BF22
+:10FFC0003C9728E381CB53D17428FEE1833106347A
+:10FFD000DD7D33AF9B94C5D8F59A5EDFCDBE51AFC2
+:10FFE000CFBA4C8EC9A9E8B7DEAB90DD57EE99A029
+:10FFF000ABCF8C2EF3740C6C0F1D1DFC4EF69CCBFE
+:020000021000EC
+:100000003C03F8FDE6A909BAFA339B3274F99D89DD
+:100010002E5AF7F4E201BAEFB7945EA6CB979D0192
+:10002000208C466A76121E965B9930169D3C2EE80F
+:10003000E075BFAE1D9BF21398EFD76F9BA83C1CD9
+:100040001F12AFF3D6199817A636771DAC0DFA3DDF
+:10005000D402788276C7F7D9C9BF58BD65F4BBE32F
+:10006000207F608B89E202071A131E40FBE8C096CE
+:10007000A45806A977B52AEC08879985C8ABA2C60B
+:10008000FADB502E95F92D6EB21776F99E947917FA
+:10009000FAA33849E4970F553FC6B7007F3C2EF0CE
+:1000A000AC85ECDD2360B7E1D6F8118535628A8A2C
+:1000B000250ECABFE94CF2233F17FFA06AA9484F9B
+:1000C000CF46517D8A5040F9B1F7073DB586E8CB60
+:1000D000D51A20BEB5903F30B78BAF8F29A3321011
+:1000E000FF47E299160F93A85EF6D7FD46C0D3826C
+:1000F000C19D2302D0AE342790340BDA9DD868A27C
+:10010000F320D8AF03F2D5CF59367039A2A54C1FD2
+:100110001E0A4FFF085CF71C83E7FF2502FE8E5581
+:10012000FA47903CBB3B89F82A1CEE87CC5E82AF35
+:100130000FF94009CAC7209FF17D1E106A69286720
+:10014000E69ADCC9A89F0E359BC8EE04FD113B9DC5
+:10015000E22B2F111D1F32BA26E3BA0F35E530947A
+:100160005772DCF26695FC02A43FAABF56F5828D59
+:10017000C0A49EF235295E96D29B6EEE583A3605A3
+:10018000D7136EDFCAF44BE0556F88BDB0F035D59C
+:1001900043E78172BB8C370E0F5D4723E7B754DE10
+:1001A000FF7221D717F7FFC37E9B01E5FA80388CD9
+:1001B000931FFD50253A3BDABF252F1548FF846178
+:1001C00047DE4F207FBCC477D808F9272DDE814950
+:1001D000B0A44586E66CF48F4EB61F7C6002B43B3B
+:1001E000F6BCC98DC32E7C76413F8AE708FBBAB7BF
+:1001F000DC0AA473FB404B53009E8B5CADA4B75D3F
+:100200005B14C6D7EFE7E705841E773CA4A02DC595
+:100210000E8EB1AFC178C75C608F50BBFBA089DB8D
+:100220000579495C9E48FDBE5CE4E71A385DB3D7AA
+:1002300015FF2661EF84EA0129972725F5A7FA3DE6
+:100240007A99B592BCAAC4731DB0BEC59B2D7E7FA2
+:100250000EB571209F2FE0E861F5492E7EBEC7FCE8
+:10026000FCC3C84355AC93E67DCCE4AFECCCC1F6FF
+:100270001B1A9DD4DEE4A6B8ABD027566020944765
+:100280005582EFAA5B147F80F886EBC50AD13F4305
+:100290003D1322BF7AEB15BD3EA9107AB48285C505
+:1002A0006D5BF4FACD1363A7752D8471515F06E77A
+:1002B00005F631C0ACD2EBDF3D8DE6ADB8FD11E601
+:1002C00051C5BA03789EAE7A8BE20EB0DEF30A5FB8
+:1002D000C785CEB3D23D7D627C6EC8B861F396F01F
+:1002E000A6C06F081E24DC2B7D1C9E95ED0AE1EB59
+:1002F000336197C11FC59B25DEAB98671A9E37A84F
+:100300007A08E4654E900E7AF4FE56BF19EDDEE3EE
+:10031000AC25D60674BF78DDD6995760BBF5EF9350
+:100320007F51EA0C0C32C4837FE7EB58539CD5DB3A
+:100330004E08B70F7E2CF8E0EC8D79A21DC0A362A9
+:10034000A3AA458DD0D5A3F6D23E98EFF399319E5E
+:10035000395FC409CF37CF1AAC37EA42E61BD99EC2
+:10036000F9DFCEFB8524E13FF5B2870645F4A37A99
+:10037000ECA0F3E8DF8F4C812CD4BFDD5946D23F8F
+:100380005F1BDD7F2D48447D3C88FC82BEE46BA56D
+:10039000D0C315A897213DBC6E5B2CFAED9F3DB4F0
+:1003A0008DF6FFCCCF57C4A25D7C78DDDC077CC026
+:1003B0005287B7CC253D5CF598D4C35E73A87E2FD9
+:1003C0005A57F6EB9F237D6E8E725BA0B8729757DB
+:1003D000D8DD20EF500EAEE3F28E3DC4E56115EAA4
+:1003E000AB61A4AF8660BDBB2ABD4390CE43BE9334
+:1003F0001EBB6BAE772CB5678E00FA5D203903A863
+:10040000AFA43E957AD668F07E9484FCA3BEFDE747
+:100410009FC2FABF784925F7AE5ADD90EDC0FD8244
+:100420003EE4F6BF0F6F430FBC732E00DEE5086F8E
+:10043000B27F38BC3F6DE2703ED8CCE1BE7ACB8053
+:1004400058F46F3F6D1A4076CFA75B0611BCE7AD3D
+:10045000017893DDEBD2DB3D4D006FB4F311DE305C
+:100460006EF92E9780B79BC3BB49E89D669ECEEB85
+:1004700005571F9D1BBDEB698B1BF5F991A8401219
+:10048000FA2347B6AA0CF7E57BEC2261BF48387F18
+:10049000C35A9E443BAA973DB3D6C21CD0DF829775
+:1004A000ED7E06F9634A410A22E044CB1F6271BC2B
+:1004B000E0F83D768C23794C881D7381F859C23C55
+:1004C000747E7D49FB1FF6A11DAF68DCAF5F62B58E
+:1004D00005906FC1DF39112ACF1517CA348C93B834
+:1004E000AD56A4834CE6D2EF1B7919EE1B7D3BE899
+:1004F000ABDB96113F770F0EDDD7A9890E9830BE82
+:10050000D4BD55217C572F2F882D60B82F554BF324
+:10051000189ECCF5B1A2691437B400DD44C378EE5F
+:100520006417FFEE72F038E27A18D71E9C6FF8F766
+:1005300069487AA8CF6D06D2E7E1EBBF2D99FB2B76
+:10054000D5AA81FC8EC566EE7FC8F30F578AF22BC1
+:100550009379BCB72899EF179C8C62A4374EAE8D67
+:10056000F1D7D3FA26523CB3277E22E1E6307ED97A
+:1005700023AF90AF44FC603FB68179CEB388782E2C
+:10058000A8586C7FAB687F6BCB3BB42F079ECB1317
+:10059000A877E7ACB0B8D17EF5BD6621BABB279A83
+:1005A000EFA3B0C43823F2D12D42CEDEDA729F071A
+:1005B000CF3DCC6989D13085717C4CC44F73711F9C
+:1005C00036DD4CF1D3526BD7F3E866DF9E7AF04EFE
+:1005D0002B2CADDEC0ED967A27A3F3239783D98E1B
+:1005E000F15828DA7E36E15CF4A38F0F2FC638ED80
+:1005F00078C6096B1CC155975F6CE6E5CB93474DF8
+:10060000792893B13F31D770C4F762840DD2435932
+:100610001CC501AEC778B1135323D1D90C23F319EC
+:1006200078DA84A135193F9E26D67DD33816888383
+:10063000F506F6EAE3D7B30286C010C0C3F5C6409C
+:1006400007D2B5C1EA32A13FE0295646A19FBC7846
+:10065000E585CDF79EE42B69BE8B0D063ECF9F2A24
+:10066000FEA7004EB70293237DDE6664BBD4511C07
+:100670007F487F354E978FEA2DE5F42DE3E6124F44
+:1006800023A1FB50F8DE2AE607FD34C5627B73E444
+:10069000F8D183C9D20FE6F6E622C1AF8B24BD6D37
+:1006A000D1F3E936E4173C9F83762DC0ED5691F6E1
+:1006B00045EFAD82DE5B05BD3F29F2173A5EB58599
+:1006C0000568DDAF59088F72DCEB45FA4232B79B03
+:1006D000E53C243D3311873280E4403A3AD4D2409D
+:1006E00076D3FCB038300B8D57A991F23DF2C7702C
+:1006F000165373F73C9C8F7255941BE9FA5673EBB3
+:10070000A05A5BEF7A721FB794759AF8BD1B11CF90
+:1007100012FA6A926AA37341A54AB41BEDDF9305EE
+:10072000769F210EE32D26426D29D003CAE78FA2C2
+:10073000F8BEFD9CB8BBA6A15D581A6B36627A3B29
+:10074000EBB4E7E404ED92D5052AEEC1C1C0D55360
+:1007500034C837A03CE1F9FBB44C8A0E89FCB23FA7
+:1007600062F98DDF01FE297FC7140DE4C5C9374545
+:10077000395B4EED4FAE1274EC5B3105F7394EFE2E
+:100780004A96FF9C97DF2BCBEB79F9FDB27F915F07
+:100790001B565E1F56FE28CF773D5C3FC587701203
+:1007A000FB31A5E31592272E4167A52B0304DF52E9
+:1007B000C30E9E16B28021F7FCF56C291E5732ED50
+:1007C0000B1EB2A3DE4E48D35CC950CF96E43D8EDB
+:1007D000DF174E577C6694931FFA070BB91EF15C26
+:1007E000AD4BD06D542AEF4FC21BFAF91AFBBBD8A0
+:1007F0007ED6E1BC9274FD7CFFEFF4332FB5573FFA
+:10080000E6947FA39FBD61EB92765159BA9683FD22
+:10081000B14389BAF3658BFED31D877615C3F365A3
+:1008200000FA452B5BB34743FF8B5E7835BB32C480
+:10083000EF5E72C6C034B09F6ACE304A8F77FCCD6F
+:10084000EC82F92CD9DE619E0CF56A202D0A99D72D
+:1008500062794E9275196784E8F5C12906219FD601
+:10086000D27C17BD70D488F85C64683DFC18C67BE8
+:10087000C62B11F75D6345BBFD7DDCE71A96C2E52B
+:100880009E2753BB2C05CF45A0CC407DDC10799F23
+:10089000FE4ED15F6934976F73F3EC5617C079CC75
+:1008A000877C9FB9727DCE288CE35E9E543806FB10
+:1008B000EB3B2EDACDE3A2ED3C2E5AEAEC5C0EC205
+:1008C0009BD5A66CB8CF7A2563531E917C062C0B62
+:1008D0006D8B2D32DF3665623EC5B9287FC3235B41
+:1008E000EF43BED913CDCF4DCC193B3C1AE542574F
+:1008F0004E8CC101F2625C62592DE26FCED82B277B
+:10090000E3F7028B7D70198FAB135D8C4BF44CC1F8
+:1009100072AC8F710DAF99C7B9BC6FA914E7F28E95
+:1009200088F146DA47BE56C0A136859F73DD03685D
+:1009300046BB43CE438E0F86CAF24EE8EFD0CAB410
+:10094000916B5CB8DF515043F424C6FF65A2B73405
+:10095000747C58EE08FC7EA1F3B83985D36F0DE2A4
+:100960000DF198AF322DC45F9C31314697BF716A4B
+:1009700002D342E3AD3766E8F2B34B07E8EADF3271
+:10098000EF325D7989A533B7F622ECDF1ABB3D1A49
+:10099000EDB08FDBBFF9CBAD68D76D54DD0AAC6726
+:1009A000C16B9BFE32016A9DC2E397FCFE14C5BD7C
+:1009B0008EE17936E43DA3660CDDAFF98275D2B9DC
+:1009C000C090FD00DDBECB22C72E3AAFFA63EDD753
+:1009D0003C9022FCDF516C14EABF53B57FA638DB94
+:1009E000121B5FCF17AF1E30E339063C177016E8B5
+:1009F000FB1A6CA8229FFB280E5DD476C08CFE915A
+:100A00003B85CBE525994B8D6091B11A48516F4CD0
+:100A100006F91407F4D1D9C1866FC7731339763A32
+:100A2000075E7D66060869A423DFB0A5506F5153A9
+:100A300031E5979C89A67EDF533B27D379E4571491
+:100A4000DA2F28C998B312ED51AC7F078C57F2E228
+:100A500035C5089F25DBF9BDA712F54FB9D8CFE200
+:100A600096626A5FA2B23D0AD807538AB89E2D41AA
+:100A7000DD0E7935CFBE06F5AB6A0E0C7E1CE5891E
+:100A8000D94EF224EECC2D347ECD192BB5FFAD908E
+:100A900017A62E3EAF49673CF45DE2BD3D85EF03EE
+:100AA000CABC2969A311EF1598BA18D5BFEECCA519
+:100AB00094CA75BE35F4E9449463A6A4AF276700D1
+:100AC0007DBC95A838C8DC0893B7A76BC7C6B1082A
+:100AD000F2A8679C33FCFCAEE50C3FCFDB9EA6FD85
+:100AE00009F96ADADD5D46DCBF6136AB03E1356DDD
+:100AF000DC485765081FA93B6E36235E4C0FBD6F5F
+:100B0000467D6C81B428A4BC5A9E3B0F93C7FB045E
+:100B1000DFC97B0752BF30DF6CB2476F13FEB7E40B
+:100B20009337457DD9BE13691CF1F8B285FCA73F08
+:100B3000A7798FA3BCEC2C60B35F22F9D8998DFB09
+:100B4000263FD6FC01CF5685ECFB2E3ACF3E6D9C5E
+:100B5000CB80FB01DD3DEBE0FC7ABE757C2CEABF6F
+:100B6000A7B215D8EF7B575FDDA9417F1D3F1B3D25
+:100B70001AE5BE1C5749E5F77098A3FB3BF4E76AFA
+:100B80005E8F71215F97A073941BB463E13BC3F840
+:100B90005FCDEB96A71428AF89057F16C62F7A2361
+:100BA0002A8074DCF1469411F5437DA657491D83D4
+:100BB000DF874C44FF4D6BB71819D9379A01BFF73F
+:100BC00035DFF3C9A7703A937CE96DE2FC5226E861
+:100BD000B45CF09F57F0D1E9DA14E2C3D377C3A431
+:100BE000719FF36E65F876B4075C76F72057902F07
+:100BF0004BD0EF81EF2597C593FF17C277C4878B42
+:100C0000CF38A8BFEA332EC1E74ECA4B7E2B17FC64
+:100C1000621176C43C41DF49E9DE91A930FF9206BA
+:100C2000E07718C7BB322D17F928482F6607D21571
+:100C3000D04B6A6508DF3474DCCCD0FEB0247A88EF
+:100C40005EE6411A6A7F54F4D81F8EC9C930EF6935
+:100C50008D39BA7B1679A91747F70352C5BEBC2D4B
+:100C60003008ED55536D941BEF839D4AE4FB33CB65
+:100C7000EEE5F05B66F214A1FDB0EC51C50D9821D4
+:100C8000BB02E551DEBE5A7368BCF1E63323980B14
+:100C9000E070C39981945E9EE49D88F82F3B3353A6
+:100CA000C06BC4BFB50F3846E3F12593DFE2DE80A9
+:100CB000FB6C515E15F17B248B391E0C892F613C36
+:100CC0000CE362727F50C69B2CB89F1AA227BF31DB
+:100CD000B664A3BFD32BEE54A0DF475BDCF1A73C87
+:100CE00003941FCBD128FE34C7E0BD0DF1BA708646
+:100CF000FF0513E417DDBF2D16E3DD129EADC6C060
+:100D000020D493AD00478C83B536ABC57E6ECFC47F
+:100D1000F0FD2F4ED7928EC3E97BE199FE444FA799
+:100D20006B2DA4774E03BDB210BD23F58D94EF5209
+:100D3000EF487AAE3672B9556D8BA37315417D338A
+:100D4000DD83715C36949F7F0BEA9BA71E188FF49E
+:100D50007F3291CE3587D3FF2B75A974CE46EA91A9
+:100D6000707D23E5B994EF525FDD95E65D8B702AC7
+:100D70007CEEBFB7FD1D3E5D67E47AEB3AA39DE8CC
+:100D8000E7C2E5E60121370FE8E4E6923EE4FEC360
+:100D90001749FF8DA23ED8AF6417A25C0FEDEFCFCD
+:100DA0006985BF41FA7D2195EBD51F6BDE7DC9FBBF
+:100DB0001752A51F7161F2FE7151FF7CF2BE43C84C
+:100DC000FB70F9CEA03F94EF275FBB84F6A7F73303
+:100DD000D007A8F7DA635C9B84FC27FD101DE73F72
+:100DE00097FCF764CEEDE843FEEFF8DFC87F498F4C
+:100DF000925F247F487E08E71FC90F53EE03FF0F61
+:100E0000F1F41EBF5F546DF46DA1FD4357CC48E46F
+:100E1000CB1EBB6DBB427CD64B2F08BE09F2895E50
+:100E20004F48BE907C22F9A35AF04345183FEC543A
+:100E30005B1F1C0FED6E4EF39E0EE58BC52F85EBF1
+:100E4000853EE90A2386AC22B196215D55431A4AB4
+:100E500057963EF8E14C0F3D5D183F1CBE407A8A24
+:100E6000493353BDFF437A8A494B8A484FB6B41F72
+:100E7000D19E385DFBD75C17CCE7742EC8D99C2077
+:100E8000BD4DF923E3F6C2006EF7EF89E6EBDC63B4
+:100E9000CEA278CE94B3FC5CABA44B8967690754AF
+:100EA00088784271BAC78DF395FEC285E2D992D88F
+:100EB00069463FA402D250FDDF97BD3B26EDE2F02C
+:100EC0003C20EDC2ECC4C902CF3FA29D383D125E6A
+:100ED00099C3A98B4380FEBB81ECB780918EC8F487
+:100EE000E957ACE37096F95501A3D4B709A86F810F
+:100EF0005E66E078FF2EBD941431110F7C79AA96BE
+:100F00000F78FF85C8B357A7227E668E93E5BF6D25
+:100F1000D606A2DC61328E4E7191F75491F7BDF284
+:100F2000F644A83FE541168CB343F9A4FCB89E38BB
+:100F30008AC282F5973EBAFDED66C2333FF7C2BC66
+:100F40005D46BECF24F2B990B787E4C785E5D7F3F5
+:100F5000FAB1C62EC6CF29FA39BFAAB8F5C6E9C775
+:100F600013628F002627E3798269DB1507C6416E7D
+:100F7000C93F49FBB1C1F5BF41EB5FD2AE88FCCEA2
+:100F8000B771BDB76CE7F9471EFD43B36FA0E82FFB
+:100F900099E264F4676A55343CFFB0789CE2EF9FB5
+:100FA000D31BCE8FA4E9FD1BFC33EADB333C7F77F8
+:100FB00031ED11CFD4BE3FB50F582E62FC59F991D7
+:100FC000EF3DFC97AC27E209D43FC0F286D6C8EFCC
+:100FD00097BC28F8B113F74D085E1F3523FC3ACDB6
+:100FE000129EFF68C67837DD9F81FCAB8FFE63AA37
+:100FF0006F189FBE16B6FE73CDFFF108EB77E9DBE5
+:1010000007CE05BF0DBDDA0BFA99AFA7A738A367C6
+:10101000D769E8270EFC7FB48B9778A29AD1FE0F90
+:10102000D2C761A28F4E19CFEF45FF9F4F9D682316
+:10103000FB47D43FDA8C7ACC63E8A9CFF941D217C9
+:101040005E05C2B3738CB7FFE0D123CD081FC00F7C
+:101050009553DE780E7E680DCBE787F18FA07FE297
+:101060005F94F3009F4111E4CC29019F2FC4B9EA9A
+:10107000CE426E2776F6E7A9339DDB85FF12F83660
+:10108000A4F3FA9DD1217008C133FC05D00F095992
+:1010900037C1E9E644B9EEA892A9B0AE4E272FB702
+:1010A000A59BEEF7E507F3E1FDC5A64795205C8219
+:1010B000FD5BDE41B974B3809B33DDFA8E8FCB4389
+:1010C00005F9B29A0804E862BBE253D14F40BA88EE
+:1010D000B0EEBFF7A62B5F587BCD748EF65DBDDBFF
+:1010E0006B61ED9929F762DA0BBC4D0DC36B71187A
+:1010F0005E2786E54B65DEAF937F522E96B7AD5DDA
+:10110000959C88714985EE8A06E939A504E97991AB
+:1011100043D26F2AC13548CF69EF20FDCE6895F2E2
+:1011200030FD7E0DF0361DE5E1F860FE0694179463
+:10113000CF28D1E242F5452695CF6A92F5B3EE2746
+:1011400079DA28FBCBA6BCC423F3F52B21BCE60A35
+:101150007DE173BD83E50BDB79FB498FE5BC734E05
+:101160007E680983CBFAB0BC2FACFE43E7D12F8D4C
+:1011700061EDEF0E2B6F0ECBAF0BCB37E9DB97CDCD
+:1011800053880FCB801E1011E7E3CB9BD27BECD4AE
+:101190001E7DAAD8C86ED3F1D594069EBFFDB111AD
+:1011A000254DB6907CBABB24942FE4BD604B22231E
+:1011B000BE30F5212F4BD2F5FE59CF7A8686EB5BF8
+:1011C0005EFE09FE338DF6777476C14E559FEF5063
+:1011D000E5BCAF7A67B92D641F945D5982F195BE65
+:1011E000F75B26944CCC0CB14B7CE34BB49075CAA6
+:1011F000FA93BF3FABE27877A68F2FD988FB39856A
+:10120000621FD2C953D06B2AEACD1A118F998CE78D
+:1012100063B15E7460D0B2503B84B50EC67576FC87
+:101220008CDF1BF035007E30BEC6DC668CA774C434
+:10123000C5AD7806EAEFFC99BA02F5E8FE15097427
+:101240002EE94FE9DCFFDC19D72FB902F21D31B7C7
+:101250009BF1BD928E7B2651BA43D5567703AF3DA5
+:10126000F8D8B525B64BB03C8EE0F38BF44925F5A4
+:1012700040D7BFC44B3BD0DEEB7424E3BD06B6C6FB
+:1012800044FB7A8CB99F24BAB9DF3212FDE7B2FA77
+:10129000CB68DFAAFC57D327D3BD855526DACF808C
+:1012A0003F3A7FE25D3389CE3DCD6B14A9EF1A4AF8
+:1012B000DFF8E1E906BC1FD9FD8442F725AEFCBA90
+:1012C000F58F23F0DC63D30037A2E675B0EBF13C79
+:1012D000D2A7EB86D03D898351B574EE13EA33ACC7
+:1012E0005FF59DEBDD69B9585F75E0D18AC3F01DEC
+:1012F000EDE1C3F7AA4FE1FDC3B2587B349E973EA0
+:10130000FCBDEB5DB46BA1DCB112BE1F5EB5201954
+:10131000EDACC38A2B16DF1279F1B15925A9697892
+:101320002FDF22F039CB5E067C5E66E8A117D21F64
+:1013300095F13CFF62FAAC924D30FFC38F0EA17362
+:101340005F8333B4D674C0D3E90C6D2BA607C57D7B
+:10135000E5377EE0FB85BF3F519E8CF4F47B41C7AF
+:10136000AF9F294F2E0FB1772ABF3012DEDF30BB7F
+:1013700096E33CDF88CE52E87C366B4DC078F73C74
+:10138000E17F00FDAED816C1EE79385D253C75DCF5
+:1013900097948F780DD27125C94BF21B20FFF6630D
+:1013A000E5A4D70E5956B08368378AF38B6C67145F
+:1013B000BFEFB825CA1F9583F14F6D32B663A9AD53
+:1013C0008367D843F84ED4FFD8C7CFE77E0CF5D15A
+:1013D0007FFBD8F70F7BE83E84AC5F156BF7A1313C
+:1013E000F1B9DD6E443CEC37D61DC6737D954F9840
+:1013F00048EE573E91747737CA1BA0178C8F85AF84
+:101400002B35C344F0EA930F7D77944CD4F90777DA
+:101410009C930F0F3FB6AC64A3AD6F3EAC127ECA77
+:10142000E4274C744EBD6A8CDD88FB8F854FBCB9B8
+:1014300089EEAD2E8D1A85F713AA9EB010BEBAECB8
+:10144000769F03F74763EDC67848BF167648125E6D
+:10145000AEC4B88CCA8CD65194D2BD04B9AF7774DF
+:10146000C5830FE331CA63CC3F732CC0EF14220C49
+:10147000E0724ADECB0ADBE7ABDEBBCD5CC0CEB1AF
+:10148000CF779EFD3D205F7A47E242F7F96232C492
+:10149000BD9F9E7D3E13BD0B5125F6F98AD6F3F311
+:1014A0005B552BF8FB1D45093CDE7BA8CE878FC41E
+:1014B000E27A7D0EBC9FFB10D72F554CF15BE19F6C
+:1014C000D7AC5F6AA4FB8FE91C3E65E21DA7835180
+:1014D000EE6CF4D32B9F8822B8563DB9E02F8F4293
+:1014E000BBAEFA92C450BF3847D003F4CFF09EAEE3
+:1014F000ECE7F3FA9F6723DD17FD1AFC5BBCEF17DF
+:10150000CF5EB83907F194968DFB91B25ED5CA9F34
+:101510000DE6F5C03F063FB8EC5E95BFBFF6B2855D
+:10152000F41DF0782A0BB9CF3CAF71AFD93C2C78C1
+:10153000FFEB53C8E395FB907B60668497BC978470
+:101540007FA979C2DE7691FCA077784B0D0ADD5F2A
+:1015500002C945F77EAECFE0F6EBC40C7EDEA92CC7
+:10156000DB4DF75FAA1FB0B857E6F07E7AEE55E381
+:101570003927436725ED3FFED64271919AC6282D43
+:101580002A969F8B7869189D8B369A71DFC4C5E5C2
+:10159000C4F582FE6A5CD3AF417A81F27D463C8716
+:1015A00065E7F2B03A1EE0CEF5B06680714EE2BF5C
+:1015B00006F07ED346848CAF88EFD08F2B36D8EFE1
+:1015C0001E036BC2B80BD6BF6404C23161E66C9CCB
+:1015D000DFF32AF1312CFE817168DF3DAF8E46BF0B
+:1015E000B6ECDE9D93D7617EEB48BCB1C0CA5EF815
+:1015F00080F4C52281FF2E711EAC1CF278DF7F7E45
+:101600000697935E95C77BE60B78493A90E5D5F748
+:10161000F2F350D5AB2C64BF54D7FF95FAADB67733
+:1016200026A3DCAD7ED944F79817897997D767E56B
+:10163000EF03BA2A37C5D17BCB8B7D2566CC2F6EC5
+:1016400051281F6C97948D747ABCF19558A49F8390
+:10165000518141A887BA9746B9F11C9E8CB71D6F7E
+:101660001CF414C665E6393AED781F69DEF2014EC6
+:1016700094DBFB1D013396EF6FCD31605E7338F262
+:1016800031AF192FA7FC7171EE84FE905E148EE7C6
+:10169000C55B769AFBC3782D822EBE78FE83C1A8E7
+:1016A000A7AAB33B07A33E013A189C81707E56213E
+:1016B0003DBC640B3FA72EE96009D201F0DD424139
+:1016C000074BB6BFF213E4872588FF51BDE908E850
+:1016D00074177D7F69C364C6DBEF423A91FA0BF25F
+:1016E0008D2627C6DF441EC6C1FC5A014F289FC85D
+:1016F000CB7DC3F839B72E3AB75723EE2BF6C8A7E0
+:101700003EF0FC82C06379BD85E4ED0B02CF5DF74E
+:10171000BE1C8B78FCE2F99DBB719FA4FA25C5C164
+:10172000F7ABC2F842C0A506E1104BEB20BBA20606
+:10173000D71D1B84430FFD0B7EAC617C9D72DD3594
+:10174000460107592EDABF88EB4C42F80AB86D1FE4
+:10175000C2F94FF01BF233BDCF23D6E775EADFDDC8
+:10176000FE3083EB83D744BA18E802EF6731BC9EA2
+:1017700028E504147DB17503C57D24BEE4BC0F07C4
+:10178000F58816EF0CE2B1CBC0EF2F86EBCB7704D8
+:10179000FC0EAC4AC96E03B81DDF4CCF5412BD1A03
+:1017A00043C6937423C72B7A6EFA75B85EE83F8000
+:1017B000FDCB71F7FB628CD8CF7EC6F903E913E548
+:1017C000A7E4CBA28639D78DC473BFBE2FEC0386A6
+:1017D000E17A39DD1ECEE0E77F34B413A0BDD6A692
+:1017E00050DCF980F0E70FAC7A25B63C044E874414
+:1017F0003B4967F887F12839DF3D4E1EC70D9FB77B
+:10180000944372DE45F7CCBA0EBFCBF94B7A95F410
+:1018100029E128E954DE7F0BA757A235A93F559D42
+:10182000BC27FD784DE65766AFADF7F7F0BCB48343
+:101830000E8AF3DBDD498CC7EB1B537785DEF7811E
+:101840003F5BA8DE09D127CDC6107D22F57F4DA2D2
+:101850007614F1559CC9CF951C63ADE602E877F18B
+:1018600091CEC9F84EA2B43BAFFC3AA0C6611C6A47
+:101870003B3F7F26E1BDF8C42EA2FB6A712FA9EC85
+:10188000DE0F4AC6227DFFC644FB3165AB26D1FD83
+:10189000E3059BE6E621FDE07D0694E747378E19D8
+:1018A000CD9FF37224CFC47B0D1B1F9C790B7C9FB3
+:1018B000D7A6BA49AE433FC8AF65778E66482F07B3
+:1018C000A3BA4AC6A3BDFE53D581F6FA844D63EE92
+:1018D000C6FA13ECFDE2713DDAC604CA6BC638D213
+:1018E0000BD2CE95E7F21A4C9C1E466572FEB9A447
+:1018F0002755C479BC86C1B87FDEBD218ADE412A66
+:10190000358B7B9CAFA5903F5163C62B85742F947C
+:10191000ECB0F966664DE3E79DAD69F07DAFA9F3E4
+:101920004ED41F7BEFB48FA473F5EA7779E5DC7EA4
+:10193000E6FB8509FA7787E43C468AF1C3FB93ED21
+:10194000F788F3C607C5FC8F36FE6626EABFA39B61
+:10195000073971DD9FBF1645E7F03F0F7BB7F06297
+:10196000EF6901DD86DD835AC9E545A6FE9C96A494
+:10197000F3F3DE53FA28316C3FE0DCE78B4ED431D1
+:10198000BA4F6D015F98EC9998EFB7E1B9BECA16EE
+:101990008B03EFB31C42BAA7F33C2ABF776BE57CFD
+:1019A0007068EB483FFA8D951FF1FB45BBD6DE43CF
+:1019B000E70A2AC0AEC4A3543D76F2436B67221BEC
+:1019C0009C727B57E33B2FA736F37310BDDE2DD8F7
+:1019D000BB6D77E8BB05176B1F5FA85D2CE30A356D
+:1019E00099FA7BF112AED23F7A03F03F6E54104E5B
+:1019F0005FD6CD27BBF8449D97D293CA8107262096
+:101A0000DDDAE3E8BCFEEFDB1E54F19D95EAED2341
+:101A1000BF43FF76BC2DCE81FCFA65DD0ADAEF3CD0
+:101A200051574B69F05D573FA5576EEFA0765FB6F3
+:101A30008D6EC77BAEAFDBE284BC0FDFD7E178EC05
+:101A4000EBFEAE5CD7B19F727CCA791FDB3C3716C8
+:101A5000D7D5F17842FB1588C7983807DA7755E271
+:101A60009CC7E175DC7E3E628D7B662A9E0F597FA6
+:101A70004332BE8353D171E34CFC5EF99AE240BB22
+:101A8000DFFDDAF4588CA37D66EC8AC57B4D9FADF3
+:101A900093F7A1FCF41EE9F86246FB4EE30346E629
+:101AA000CAE15BCC4827579C30D2BDD3E3B81F8531
+:101AB000718FEFA229EEC1C43E53C5AB3C5ED2E3A9
+:101AC000C70A3F6E8258F75B994EB97F40DF8BC6DD
+:101AD000F1EF9FAFDF360DFB3BBAD1E4C0797FB9A0
+:101AE00091BFCFB010FC2FBC9A726433F76F16B65B
+:101AF0002AE40F1FDD0CFA19D655BDD4A4F1FB9AC8
+:101B00007AFA2B82723CD728E96FA1E627BA0E7FBA
+:101B10003F239EB5D2BDAE1F8B1E03997A3FAD8782
+:101B20000EFBC2BF8013F22DD2A1C4F3C2757CDFBD
+:101B3000DCD93AB200E949E25DCA05795FA1C1CCBE
+:101B4000F87BA58668FA3D80E936974981F5DF90F4
+:101B5000D83511C5E7B02C6E7FA845060DEFA1B1B1
+:101B6000064BC4F7A8FE26E4E89C2C46E93799DC2E
+:101B70005E90F7B1640A0BC9423D3D3DC6F98D0B3D
+:101B8000AA1C5EBF749A11E63F7D82F3CE016EC03F
+:101B9000DBFA9F4C3302DD4E1FED7CB93FE4BB33D3
+:101BA000EFE2F9CB9D634C90AFAF5F316D22D4B7BC
+:101BB0006769873243C691FDC2F7CFF1BB3FC17B56
+:101BC0000CD31A33BF1F7552E91EB1222758FF7D6F
+:101BD00085EDFFBD12CC779918BD03F34DA69C7F10
+:101BE000E4744C96763A734CEFEFE58CADA2F3714A
+:101BF0003E7EBF05FE3CD664BC7FC4E9A95CDE77AF
+:101C000069D2DF77616E7EFF4ADE4392F78C2E0940
+:101C1000DE9F5A7F31F7A74E9A60BD71BDEFB329A1
+:101C2000ED7FA0F7B01A7CAC2B8AF0A0BFBF521D8D
+:101C3000C3DFF75BF6F217BB90AC16487B05956DDA
+:101C40005EF0FE3E4BE5FBFE770A3AFCBC8E0D1CB7
+:101C500008AC7C7D6767AC0B267B625A6030F2B7BC
+:101C6000CBE2CDC8423F7E7D43E6B244BCF769710A
+:101C70004F85FA47FCFC5EE562616FB28D4982CF09
+:101C8000D5C0D5506F4FCE25F47EC3A02CEE479C17
+:101C9000C80964E37B3ABE1CEEDF403D3ABF56BC48
+:101CA000F29A24AC7762EB3D032B006F167CBFCD1C
+:101CB0004929C3FB4FD742DFE39CF4AE1B53699F16
+:101CC000D64FFD61BD58D4EBAEB9A93C8ECEEFCD59
+:101CD000493C49F8F7C20B4C01ED5183959970FED0
+:101CE00097B0F50EE453891FF9FEE9B29779FC64C9
+:101CF00099D2D59880F9E7153AFFF6B995DFEBE967
+:101D0000ADE7369911D4F3D7CFD5BDCF23DF19FD79
+:101D1000B1E34053B3847C19C94686BEE35A25DA41
+:101D20004E524B5DF8DEDBB2242BBDDBB1EC8901FA
+:101D3000A44FD8DB77B0D07A6C7D02D1C7EA1C956E
+:101D4000E0BCA08DD1BB3B256DE9745E716A9B93AD
+:101D5000D2D833A9F4FDE8337FCCE5F287E3A1E4E0
+:101D6000BF520AE97CD07F0DA194F5F5AEB0CD4A03
+:101D7000F76897EDE57A69D94D2AC52799B81FEE1E
+:101D800011D3F1D89A289EE36191DF8FF5C8F763EC
+:101D900035D339DF8F95F0B508FC84BF277BD3DEC0
+:101DA000D1A9F41EAB784F76B6A8D729EE6D85BFC2
+:101DB0002B7B4FEC647A5776B65615F15D59A32FFD
+:101DC000CA8DF6AD29D3C6DF6BF086BF33DB65C4A1
+:101DD00075CFCCE7EFCCDE343BE45D04F8CF94FF65
+:101DE00015C969537EAFF7814C48DF168FBE7EB3AD
+:101DF000C4FF25EC9273BEE39B69A677DE8CF89E48
+:101E000033E4678A777CD18E43FBFC94C6DF95B3BD
+:101E10008877A63B596E2AF2FDC5BED3FCFFDBBB1B
+:101E2000CCE1EF2F87BFB77CD9E665BAFCF0D6FFCF
+:101E3000D0D5BFBC6DA5AE7C64608DAE7CF49E5FDA
+:101E4000EAF2633A1FD3D51FBBEF295DF9155DCFC9
+:101E5000EACA271C794997BFB2FB77BAFA579FD9CC
+:101E6000A1CB17B03FEAEA17593FD0E52739FEA1C9
+:101E7000AB7F4DEA415DF9B5AEE3BAF229434FEBD2
+:101E8000D763F4FE0DE57C89FBBF75EDA631D72F36
+:101E9000F0FDE75989067AAFE31F59C27F1174F745
+:101EA00057A9B707B26C945F93D4FC00D15D9BC275
+:101EB000DF1F0ED363C6E31E0DE371EC157EFF2B0F
+:101EC0000EEC3E63C878F19A151CC2603EA1D8A101
+:101ED000CB27795275F55366BB74E569DEA1BAF27A
+:101EE0008CF96E5D3EAB769CAE7EBF159A2E9FE35D
+:101EF0002BD6D51FD0E4D1E507B5CCD6D51FB2CEB1
+:101F0000AB2BBFC43F5F577ED9E65A5D7E78EB0AA4
+:101F10005DFDCBDB7CBAF29181265DF9E83D2DBAFF
+:101F2000FC98CE75BAFA63F7F975E557746DD695D6
+:101F30004F38D2AACB5FD9DDA6AB7FF599802E5F53
+:101F4000C0F6EAEA1759DFD7E52739FEA6AB7F4D81
+:101F5000EA015DF9B5AEA3BA7269B74C19FA95FEFC
+:101F6000BBB0634ADCFFD4B5F7158A77A55F52DCB6
+:101F70000D2E584F767FAEEF418046E1BB883E0F75
+:101F8000C57D9C78B00FE514DEBB76F27331A514E5
+:101F90003F4A243B8754910BCFE9801D108BDE55BF
+:101FA0004E0EDAC931417B2CF36CC839B9F3D963D1
+:101FB000D764339AC75DD9DEFCEC24F43FB64EA655
+:101FC00077C1996F35CE43BE73F76ED87BC832BDEB
+:101FD000D67A841943ECBFBD512D99A3CEE1BF5FE2
+:101FE0006B3DC1F09DE59E7E45BC4281F52D0BE920
+:101FF000FF01F0178C03196BA903BEC17DE13A07FD
+:10200000E51FAA4BA5FCC3752E4AD7D50DA5F4B183
+:102010003A3795AFAF1B47F927EB34CAFBEB8A2958
+:102020007DAACE43DF37D6CDA6FC33E01763BA19BD
+:10203000FC644C9F057F17CBB780FF8BF917EA7CB8
+:1020400094B6D635D1F797EA5A28BFBD6E1DE57F05
+:102050005BE7A7B4AD6E33A5BFAB6BA5F2F6BA369E
+:10206000CABF5E17A07CA06E0FE577D475527E576D
+:10207000DD3ECAEFAEEBA2744FDD114ADFAAEBA63C
+:10208000F2B7EBCE50FE9888B72ECF5674F7956412
+:102090005EBEC720EDBF6968BF23718C337DA9B3D5
+:1020A000DFC3ECE8707CC87182EF270C7EAA21C4E4
+:1020B0007FF26573FF4ABEC710FE8E0213F6A97C3D
+:1020C000F754BED75029E65525F8610CD2E750A247
+:1020D000CFB72FC65F90FEA02DC9DB42F49965F003
+:1020E000913F6CE3F7892F4FF23E983D06F70B2B9B
+:1020F00076D3780E37ED1B96580249B372E99D707E
+:102100008ACBF5355E8D38F7DD67F9EB4733D19E25
+:102110002EFE41A577B6DE35D967A3FFFF8CC0C37D
+:1021200033D9065DBA2DC9BB09E7F3ADBDF6360359
+:10213000CCFFDBAB963E73474ED04FBE1E5D4DF0DD
+:102140006FA6339789CE1532EDCD1CB49BC0B0C2BB
+:10215000FC2CE6A3745CA2F705ECE76630B831EF1F
+:102160001D6FC98EB4AEF079BD2AF0F56AB64197FD
+:102170001E48F2B621FCBEB56B34AF77AFB86630FF
+:10218000AE4BCEABBF7877641AEB7E12E7F7ED6B00
+:102190005F1D560604E12FFD71BAD78F726CA9221C
+:1021A000DEB5EBF58E009597DEA9907D3607FC191C
+:1021B000DC1F92EF069CAA35D13BF2F8CE00EE9FD1
+:1021C0009DAAFDCC86E40CF518EE6F34E0011D28C5
+:1021D0006FF829BF4F5F8AEF628CC2770BACBCDF10
+:1021E000BB15A2BBA4E41C7EFF19EC3DF29F12BB01
+:1021F000E99E1ED0C99F116E0BAF50E9DEF9BB06F8
+:10220000FF6085F6932BCC0ACCAF2A11E8A37FDFC1
+:1022100074B044DC1790DF81BE3E41B87DF9EAD846
+:10222000A1147F7FFD0A17C2ABC1C0EF0FF9DE52C8
+:10223000F9EF2E0911AD4E184E71466674BB315E32
+:102240005422EE9B74A86C45A4F7C4957E9C8EDE48
+:102250004DE5EFE73584EDB3FC53D0D53F05BD9593
+:10226000ECD84BEF082DD9C3DF3B64B95DC342DF27
+:102270009DE959CF8AB72E1918B28E9AB603FC7C05
+:1022800005EB1A167A9E3C5D8C2FE94835DBBD1BA9
+:102290006CA1F3EBA16BD60FE9271EE87A00D1F50C
+:1022A00061DC579C6671C5CD82B40B4084EFFB782E
+:1022B0007FEDA0F341F29CD03CE6A1B40AC800E94E
+:1022C000D8E35B4BEFB92EC45F62C5F778C6CDCDBE
+:1022D000C67C0DEB9E980A70BBA9A9FE4D7C0EEF43
+:1022E0008696B59330BE3AC35FF626A6D3372A87C3
+:1022F000D14F05BE88EF87F110A576151EC9BC65C4
+:102300004BC12ADC7A99A6727CB03F727C00DD68F2
+:10231000AAB3F73A810FD2F83A345A871A5BACE382
+:1023200083D2954C531283E7DD7BF862DCA24F70B9
+:102330004B8D19BB69DFBCE6758B13F1BC9071BD89
+:102340001D8C67487DCD88CE17B16837D63B26E80F
+:10235000FA581623BA3EA630BAA72EED4896ED4D90
+:102360001D3520A8778F19FC79B103482FBB71BDAB
+:10237000BB536F70611C6C51A295DE3F3D16EFCFD1
+:102380000E7BE783DE239271AC074C3CAE143E2FEC
+:1023900065DC6EFE7B1866E6C3FD09FCFDE33CE4EC
+:1023A000677C3747A177A0BB90EF4D851E57A4FEF1
+:1023B0001B45BF7BBEE7FEAE0FD683F71B7B8DE3CD
+:1023C00010E344F371A4FEE8F9BDE564A61B6F7A3F
+:1023D0003FCECFEFDA359A7FBD219EE44D9AD5EB03
+:1023E000417CC9B88EF403F7E47C3E90FCF5EF1A0B
+:1023F00032D13EA77708D0FEBE8ACBA5774D2E7A84
+:1024000077F7DD821C8ADF4B797BFD381EFFBA5ED1
+:10241000C6BBF2C3E25D61F116961F39FEC598DBBB
+:1024200084E35EC23E92F0A138CB8E7C23E15DFE58
+:10243000BED20EE17F9E2A4ECC453AFF5D3F5577D6
+:10244000AE40A66B447CB439ECBDEB35B9CB1C78FF
+:102450001EC0F23CDFEFBDBF307A7EE839F42707BB
+:10246000F1F329EEC1059B114EC36CFE4252CB9A8B
+:10247000D185F356C43A2E73009C0D686F7A449C44
+:10248000D36DE5F1A589A497257E2F542F3F6BF4DA
+:10249000AF8CC67526F2DF19B0AFB392DC545BB5D2
+:1024A000001E89FE72D08C5548B7CCE8198AE374B7
+:1024B000E445331BD4FFB6C34CF1A7D70DE5BFC627
+:1024C000F3EADD7FB3303CDFD06ACF30A271DBFAB4
+:1024D0003DFF5DAB56FB84C9FCDD491683EF638E7F
+:1024E00074B0A75F44E4887B61AD0ADBC31F69D584
+:1024F00062F07DB756033B7D35CCEB25DBA8072F7B
+:102500002712F3A8B8CE67077AD7E13CF2582DE539
+:10251000EF377BE66F8071EF775A892E0A077A1EB4
+:10252000E7F364ABA6C2FCAE2A52E8F7D65689DFC1
+:1025300077B0BBA375EFEC7ACE0C263DF14C3FAEE5
+:10254000571B53B54EBCD0D127DC1CC66EDDFB58E3
+:102550002C93E272128EA1F872E4E9F0E53585E27F
+:10256000ABE7776B24BEF8EFD65C28BEEAFA319A67
+:10257000AFA4475FA16BEDC45CAEBF1AA89623174A
+:10258000FBDF119D312CF47701243D4AFA8C4097F2
+:102590004B77A2DCCD323830FE79CFD468D263924B
+:1025A0004E257D7E9CD343A743FA631CDEE69984C7
+:1025B000B2229C4E31BE154A8FA57DD22D7384F276
+:1025C000E534B013E29C68D71CD9D81A428FA5B560
+:1025D0005F19B99C387B75745E301E372D5F619F23
+:1025E00086E215FEFB74A8581FD93546F2A724FCD5
+:1025F0002E14CEA61BEB87A29DB61AEF0D02BC9A35
+:1026000014B79602FD196B0FDC81DF57897BBBBEC7
+:1026100061666E3F09FE90FD7D39A8F038D2A37D3A
+:10262000EC89984AA8F76DB2C185C059E52A7F9117
+:10263000F86D5F0CBD37119BD039FF69E29F210C0B
+:10264000F7F3BE5DE0ED87FBEAF7029E3EA5FB399E
+:10265000FE14FEEE61570A7F5FD625DEA1F7A6F2D3
+:10266000EF4C94FB297F474E7FE15768A27E17D538
+:10267000BFD7DC628DC67172AC8EA742E8FC6A11CE
+:102680001FFF1FC180237D00800000001F8B0800FA
+:1026900000000000000BED7D0D7854D5B5E83E3309
+:1026A000677E330927C9240CF98133C92484640265
+:1026B000930410446512020D083AFCD520890C8A57
+:1026C000DEA82493426CA3D77733908001EC2DA22F
+:1026D000B568793AD042F1AF3728A5A18D74127E42
+:1026E0002E5A2A83D5165BB581FAACB60582785B83
+:1026F000BC9796BBD6DAE764E64C2680F6BEBEEF02
+:10270000DDF7E65EBBB3CFDE67FFACBDFED7DA8791
+:102710001C59C7580663EC52BB3C3F99B11C59A0E9
+:10272000FAE36D5B7D1FB818DBD016A2327D6E8890
+:10273000F94B19B31605E520F433AF65FE2E1B6384
+:1027400097F1373D5A3EE014199B04ED7D4F311946
+:10275000FAA5BB3C821FFAD9E7C278458C7E97E187
+:10276000BF5B180B8E28877E3B98974D646C9D6CE1
+:102770000D0585A1E3DD925175544C19FA7CB0FD2D
+:1027800006819D3647C7C5DF69751E3D8CFF57BD65
+:10279000BFCB8D35878E6532D6827D65C6AAF3E0C4
+:1027A0000F9CB7D5B8DD04F34E965369DF9FDAABC3
+:1027B0004630F7F0F33DD3060B2F642CD466A67297
+:1027C000479BC48246C6BEDBE6A0FAAE3699CADD98
+:1027D0006D45543EDFE6A1F617DBA650FDFB6D5EAE
+:1027E000AA77B5D550FDE5361FD5F7B6D5527D5F32
+:1027F0009B9FCAEEB6062A7FD4D64CED3D6DAD54F4
+:102800009F6E62CDB49FA2A063019C47E78346AF51
+:102810000CF06954CEF1A0372FDD6367CC52A4636E
+:1028200026E86639B685E17E2C0E9D3704E7B0DEDA
+:10283000B185DD05A5617272A73002F6FF92AD5336
+:102840009800EDE2E34C86E7CF08C106E6616C91A3
+:102850003CD6278E62CCE5F84A551AD46F974B3791
+:102860009B9D8C15CAF36BD7C4D4E5E4F2FBF64804
+:10287000D1FA18F776D10AEDCB421336DB05BE0E3E
+:1028800096C5D8BD72B96F0DE051388F0511EE03B2
+:102890004E636807B4AFC0F31271FD12ADFF66D688
+:1028A000EED0C1FAC7C8C6722650FF30B35F7BFFB7
+:1028B0004659A6E7F1EF5DA99F6EE235F563FA2B65
+:1028C0008C87EDC215C6310B0BCD1158FB2603FCCE
+:1028D0000F3C0F66D8423B015E9D06B6CC0770EFF9
+:1028E000B4F0F28893D3DFB3CEAAF14EA0A3F14E99
+:1028F0007EAE9D96A05485F397EA3C3B109D5B9D70
+:102900003FCF83F9BEFABAC836CA51FCEC403C80CE
+:10291000F70AC6247B711EF68FE65001CCF3A53171
+:102920002F75A441BDE03B1E8F1EFA6F621E2BE285
+:1029300049F0511DDB09F51726E6A7CD87EE259353
+:102940007E90E6077C398D7C00C609315683F8B647
+:1029500066DD3D63FAA1FCD309FF1809D6F9B83248
+:10296000CF7643A499CE73928DE1BE19DB9CA473FC
+:10297000407F071CD2758CE946F1D268906EC77E05
+:10298000C675461684F518FF729DD907E3B55F3406
+:10299000D5201F612C92A49B02CF2D7E29159E6FFE
+:1029A0000EEA882FB4CBB69000E36EB2951F95A1C6
+:1029B0001E94749E0284A35B4770ECB07D39A4879B
+:1029C000F144614D03CB87F54A2F9B9DF03CE4D643
+:1029D0004948E721EF821AAC07FDA2A74056180428
+:1029E000B6FBD3421B715C36F0D309D85EC73C08F6
+:1029F000877599FFDE9704F5F6C59247CF7BCBE24A
+:102A000064C646E15F3065BBA17F6D12AE6309EF1E
+:102A10000F7F79E6031DA698F8F97DA377B6945742
+:102A20008ACFC5603FE74BC2652044D1E0317BA02F
+:102A30007DBCADBCC60BA5985C6E96619F1D52B95E
+:102A40007939ED9FD918CC93CE387F6A97743521A8
+:102A5000A5FD2EA477911D724D2652A2F60EDB968F
+:102A60005E84877837634E19D707F3A97C0FE0613E
+:102A7000CEBFE1A80CFBE8BC278DF6210A1EAAB345
+:102A8000BB455A77966C0DB3F1708EC6794719F035
+:102A90008F2CF3FD73B13EAA41FCA03F864F8FF40B
+:102AA0006BEB19B5DA7A3A83BA393AEF6F14F91148
+:102AB0000FB778788C923A4EE0FA47F9457A18BF0A
+:102AC000FEA7A427522B19AED346EBCCB4DD59098F
+:102AD0001082A17D6B10FFFED6758E9716989D30E3
+:102AE000FF78BB0EC1C926B081B538EE2605DF3BA5
+:102AF0009DFC3CA374A557E97224D2E598561D0BA2
+:102B0000C6C81D67D0CA8231F3E577A669EA059B7E
+:102B1000B334FDC76ECDD3B48F0B156BDA4B7697FC
+:102B20006BEAA55DD76BFA4FE8AED2D4CBC2733453
+:102B3000FD2B8E2ED0D427456ED7F4BFEEE49D9AA0
+:102B4000F6A9FDF769DAA77DB44A53BF71E0214DBC
+:102B50007F20E386AE04723255E1571D0E6FC49B91
+:102B6000409EAB2593C481C1F300DE69720066C745
+:102B7000CC97ECB1021247EBA099481F2629759219
+:102B8000EBEDF25AC4E71423E1B388F21CEAAB1E62
+:102B900034864C88FF377964E42F2627E763FB0AE5
+:102BA000BDA39DB0AECA1433C905D1C6FB89B659C1
+:102BB000A4A78CDE0A7CA902EA121B6C4F42FEDC41
+:102BC00016F4B95CD1755BA4CD0CE9B732A586F5D6
+:102BD000DBA2EF8B9297F993713E99EB3F5290FAFB
+:102BE0005964783F665F07743A66433EDE0B7202B3
+:102BF000C6EF4ACE1691FEBAFE525C4D65F2B4594C
+:102C000088EF6512FBCEBF40FF2E811D65A02775A2
+:102C1000E9D885E9B0EF976DE58F83B806D6E8D39C
+:102C200023BF9BCC9AA91CAD63562CB70BFDAB19E7
+:102C3000F473379FA81A09FD9E77F9BDB8EFAF83EB
+:102C40000E81FBFAFA78AE67ADCB9C23A35ED6E982
+:102C5000EC3A9A87EBC900B9828420FA3CA857A8BD
+:102C6000FBBD4F394F31AFB31FE5DFAA54B38CFA28
+:102C70009268DEECFB00E0F58CA1FFB976A877083E
+:102C8000D2CA2EE48B0FDA3C3B19EA8F1C6E72B26B
+:102C9000AE622D8CDBB5C62BA6427BD706E6E9409B
+:102CA000FAB057AE4D85E70539CB7569480FAE359B
+:102CB0006BB1AC73E611FCC6B9B7EBD2A1BD6462CF
+:102CC000652D43D92BC17CE9C3E3933E652BC3FD3E
+:102CD0003097F821E2954E063E034BAF4C83F386C6
+:102CE000792D78DE02950407CB455BC8827517877E
+:102CF0008BC52B8492A06E777905AF1BDFDB4AE78B
+:102D00006B096BF5D82A97FF3EA47FFB5CEDB98A6F
+:102D1000E627687D9B749C2E3A53E563289F3B9D74
+:102D2000AEB47639BA4E95AF3CA0E86BEA7395AF76
+:102D3000FC0ECF2023AADF009E6FD5E5A37EB699B7
+:102D4000217FB23CBC99215E5BA4A0CC500FFFA7B1
+:102D500020E1B9AADFAE5668A63AAFD68CF2FA8265
+:102D6000BD9CF4594BEB2E3AAF78B859FA75CC7B31
+:102D700005B8A6143E4DF21D18B05C00F0E9CBB4C6
+:102D8000356C4FA0F78F50F4850D40C61192573E19
+:102D900033F26B831EF455926FB06190071724468F
+:102DA000F28B7539A9BE3A95D7D5715667948FBC09
+:102DB00092FE6DD96A66FE987D6C8079102EEB2E9E
+:102DC000CDAF41B8329188836DFA8B7BFB46A02F43
+:102DD000D5AE19A1E82B39383794A38D8CEC028F2E
+:102DE0007D6E0DD29DEF621E09DF83CE346AF7043B
+:102DF00099BE99D66D50E592EEF2045AAB6C54E54B
+:102E000030A9B65C6EC1FFF75E1690EFC7C8315EA1
+:102E1000905C57E576C1666DFBD8ADDAFAB8D09014
+:102E2000F7DF42B9BF98FF0D7241DBFEB422BF1736
+:102E3000A3FC86922D3290DC33C38A2E73B91B9586
+:102E400083C01772BBC295C846735A62E421A37D42
+:102E500068E463954B26FCF31D150D788EBE8B60E0
+:102E60007C540CE5CBA34D1CDE7DC6E4D05A78EF34
+:102E700051B08BFCD0753DD8437E20B5AF8B9E5FA3
+:102E8000D6A19D7554EF018C1D3CA7F873F5E4A9FC
+:102E90007AAFEF2DA403C6FA2B7CC97C3E7FCC7C95
+:102EA0007DD694F10CEC965D85FE5F61BF4F6AECB8
+:102EB00013913F98729801E913E767CAFCCC88FA2E
+:102EC000333FEF4D9E379B0FC23A1E396942759CC6
+:102ED000CDD41F3BDA06F555B922F133E9BA95CFC7
+:102EE0005A810F54FD1ADAE19D47647924E9E947D4
+:102EF0000D0CF5F42A058FAB14FBEB9902038DFB47
+:102F000089225FCE3A55BD276845FD172C022BEA72
+:102F1000B325BB81176BCF3389B77B49DF2DED8A92
+:102F20006FF732A4E362055FA06EAB847A9952EF2B
+:102F30006242BA04E738A1B6BF0F4D09F76B87ADFF
+:102F400088877B2C5C7F7B5EC1874C2678C2B0FE75
+:102F5000CCDD364F08FA25EBD99E08ECC373483C0C
+:102F60001D7BEEE37BB475378BA93B711DDAFAA3A9
+:102F700072B3807079B40E7474D8B2352FD9FE61F3
+:102F800009439817227ECDD4DBCAD09E5A55696377
+:102F90000857D3A9B1DF8A20FF38A1672817A424D6
+:102FA000F9B16A785FFA69BA678D1C3DFFE7DB907B
+:102FB0007533F6E4650FEB009EFCF52A6B03EABF60
+:102FC0002FC279A21CF93ED8D9D8DE05E78AF59739
+:102FD000C1CEC6722FD8D9F87C1FD8D958EF063B7E
+:102FE0001BCB1F819D8DCF7BC0CEC6BAA7B072749C
+:102FF0001E9C4FBDCD375340B87A455902BA12A234
+:1030000070661F1661BD5FB80C045227B17E13C0F5
+:10301000F5F81899CED7C47C0CE52BF37BCC8897B8
+:10302000571FC7AB8EE337241A670A8C4376825941
+:1030300042BF481EBC31029E9F79F057BB505ECC08
+:1030400013FC1E5C6FE3A4D346AE3F0F18B1FF36EE
+:103050000BE03FF0A11C850E8255004F94BBAFEBF7
+:103060003DEDD0EBA619A7566780FD5D95E79C2F37
+:103070004E85FAFDA72A4643BD73C7A6F968CFDF80
+:10308000F4BD53AF64030F3E9B378FB73F7EEA42D8
+:103090000EB48F605F9B5F0DED29E95C3E6D1358A8
+:1030A0006DAC7E776B1EC7F340EB169273C0DF19D1
+:1030B000C2A13DD347F2F19C7D206539F40F640C29
+:1030C00064DE7905FE1D687D92E4507BCAEF49FFFE
+:1030D000681F94171E9217EABCAABCF844C13D555C
+:1030E0005EACB2F0EA603F7F3E3D7F5CF1EBB050FA
+:1030F00001D5D32DBCFECF55F271B47B003E64E701
+:103100001E4C29FEC60D6857D6881E13D41FB795CE
+:103110005B50DEFCA3C27F60DC20DAF1C199E6D00F
+:103120004E3C54BB4CF498A68E6F77A1D2C5D29476
+:10313000751CBADE1A463BBFBDDABC03F5C92DB615
+:103140003C1AAF7D8A3188FE15B5BEF6FAEBCDA8E4
+:103150004FA4A6A439B1AEF2A78D80F758C24F8F05
+:10316000E35629DBAD32DBC27AE4E766C31F63F5C1
+:10317000641B8B10FE7874609000BD19F3395E55A6
+:10318000304F2D3E370ACD4144C66DB876DC47B28C
+:1031900091FC0C8C65F375ABFBF066F37DA9FB48E5
+:1031A0003606957D909EB4C5A60BA3BEB705F685E1
+:1031B000E305F264824FFCBEE0E7C371674C51D671
+:1031C0002DDDB017D73153E7EDC0F70E7F566707F7
+:1031D000F462B358B388CFF3C1A2FDD04CA2B3E3DD
+:1031E000F215F40E14E41FC6C8AD9B7E2BD07ED81A
+:1031F000FD463A97CD057CDF4F1B434E46066E6871
+:10320000D482E4E1F1F78521F8EB65484FED695E82
+:103210008EBFD240CA1AC4DFD481CCB5B4AF70C25D
+:10322000F388C7E3F8F3D907FF2972408FF0BDDABE
+:1032300079AAE7A8E241BCFC32E64BEAF93A689F7A
+:10324000DE224E07AA1EC5C0CE491E0ABFF5309E1B
+:103250005C18AD1B1D3ED28F0D764F11FA6FDBFF50
+:10326000AA6F48E4BFFD5081D39A142BE9CDED2914
+:103270005C6FEE4D99A3B177AAC1FE11003FF4E94E
+:10328000AC0BE9483FE276F27FE947A28684EB8AFD
+:10329000D34747CCE5FAA804FA688279D552447D31
+:1032A00034819E3AA88FA6CDE1FA688A91F4D16D57
+:1032B000C9C6DAED09F8CD813CAE5FF7E23E12D81F
+:1032C0007B60E7911F52B5F38C929FEC35759F0799
+:1032D000147C57FB9BA466867E31BDD123A3BEA977
+:1032E000B772FDD104DB2C8A91DFEAFCFBF30CF40E
+:1032F000FEB70BB91EAF3373FDE4A6E3427322B8E9
+:10330000FF5981FB7078F737E00DF185729BD18B07
+:10331000FA41B9CD5185FAC170EF81A919FC282D68
+:10332000CA573C7F9DAC27F9237A1C88675D86FECF
+:10333000578EA31D77D846F246D59BC14EF57AE04D
+:10334000E53DFF0114A81B6A9F82DD24E5C3787D5B
+:10335000AB3227F2F140BF2B1DAA4FC6FB0106E995
+:103360003C659793BF171A85EF09ABA68C447C8AFE
+:10337000A773B5CC75BC9EBB02D6953BEA2895EAEF
+:10338000F3FFC9F4E4578BEF3F365F853F97C7E300
+:1033900060B2117A92C36371DD675ADECCF4C05219
+:1033A0009AC4F3248F3F699E32E21199F3D9DD2844
+:1033B0005FBE22129FCDB9B737352DE67C9F6EEBED
+:1033C000CE155D182F88E456BBC80EF0265AEF4282
+:1033D00075FEF018E2CB06E5FC657B64F65880B715
+:1033E0006CD379D0150D425743FF95626AB504F34B
+:1033F000E7B6318F0DEA4E26911F2BF7B29EF02CC7
+:10340000F7E012C2DF31F60121E88E990759704CBE
+:103410003CE4D3E66AA2CBDC9183F61BC50D3EB536
+:1034200087E7235D7FFA045F51EE77B4ED205BC937
+:10343000CF7C4F8B358426E09887251DD6739F154A
+:10344000588E13D771D0F908FA697E98447E1AFD18
+:103450005617F9599E15FCD3F2812ECE84E4AFA203
+:103460007D4B3FE8D7F835EB8E8D24BF22B3497EE4
+:103470003DA0633B13F8916ECFE7F6DCD27C4E5F44
+:10348000B98E3772575460798CCEFB5AE9A813F97C
+:10349000358CF3C888CD14E70A56B122B4FB3A0D37
+:1034A000805709E8F45FF3957899CA8715F859D0E1
+:1034B0004A817DE80545BFDBFDFCF3CF67A2BC6612
+:1034C000A8DC0DD29B3A4E525117352679BC0CFD23
+:1034D0000D82E4E5FC550A3A8218D7F98B3E215E4D
+:1034E0003FA99CDF1AE77A07F6AF76791C4807BD3B
+:1034F000CEC98E3B017E369B919962F8AF8A2787B1
+:10350000922793FEA18EB32A39EF8A76B611F8B0CE
+:103510007C05F96C447F37EA317D53CD32AC77BD01
+:10352000AD3C827AD67A9BBD9CFCE636E017317EB4
+:10353000249BED08E1A1CDC3FD6B36E4BBE8475207
+:10354000F6DFEB3C42FB57FBAD52F88FCD13E67133
+:1035500047B062B09F45F405D1BEB0D819D99316D3
+:1035600033A7A724380E730C1F51E7BD3F9FDB69BB
+:10357000EB73CA2395B43E113D016CBDA3DC4172CF
+:1035800010E18C7AE8A8413D94FC25CF297056C7FC
+:1035900069EFE5FBF4B53ABCD5E9687FFA9E45BE14
+:1035A000B0DE76A73988F22079E215C77B255FD097
+:1035B000F87BA2E3B5CE50C67B0EC7D327974B3816
+:1035C0009E01F94402FC0B2BEBFAA2FE3080A844CA
+:1035D000F61AE37A1560BC2391FEA09666C5AF3556
+:1035E000F43DCE279D8ADD027CF218AEBF31E7F4B0
+:1035F000914AEAC5ED95B4D9629108E7F5099CA016
+:103600005E88DAEFF17A4CA57E80E4992A8754B976
+:10361000F434EA31C6283DA97E97EC061FC96BC178
+:10362000EE23BC01BD4646BAD163BC3701DC24178A
+:10363000879B903245467AA9BED49F4D723EF9A32E
+:103640006C16E33F53F9E1A1CF7659B0FDD386AABA
+:103650002BEA2B6A3C78B83870CA43BFFF4AACBE2D
+:10366000325C5CF86AF1E0BE1423F9DD9E11B47C93
+:10367000C9EAE2FCC8E052FD27FEBFE0393C23F86E
+:103680003CA42F2A7E947D857EE642BF57A79105F4
+:10369000E13C0F7C36D981F871ADF055FDE6598AD1
+:1036A0001E9565DB25209D66358404F47B673774A1
+:1036B00009DE2BF47B07E93923DADFA08C3F5D1CA0
+:1036C000D0A3BC9AAED071F6459115C5E87F6FE5E1
+:1036D000733DCAA0E8ED297DCF5970BC3E9DAFB3C4
+:1036E00010E5438A4EDE1943EF867BCBCD5531F092
+:1036F00069C7784E82F32B770DEA5B6417A9F2D67F
+:10370000A0CA09BBA8911381248EB7AABE13B89E84
+:10371000DB4182E02F41B89EBBFEF7B7E016CF0930
+:103720006183DD79F578C6A05EA30B2D57ED17A454
+:10373000972E83DCDD4FFA558A07FD00AA5E55F609
+:103740003D211FFB79042FD1C924E6A7F23AC6F523
+:1037500040D0AF6E7091BE075B89397786AE88CC5A
+:10376000ABEFAF00FDE018271023E44FFDFA2581F1
+:10377000F87B3CDCDA06E13618CFD3F845B315798F
+:1037800097ADB4CBE81775627C4AEBB7AC38AAADFD
+:103790004F8A68EBD79D8CF38306BD6FBB3279FCF3
+:1037A0001F07DD06F4867C628512B7CC09862A25C0
+:1037B000586F2EEBA2F86076439A06DE37E995BC87
+:1037C00009E61598BA4EF8658BF33EC6F75B5C8345
+:1037D000FE3BD2BFEE51DAFFA17AC5573BD096DE51
+:1037E0006C20FFA819264778FDC3EC0533F1BC8790
+:1037F000F8579BB57ED5ECD87680C33DDB0C9A7626
+:103800009FB78CEC82858ADF7670BFB88E0CBEDFE6
+:10381000ECF2A1F35F7D5EF82F6DE8FCEAB84F0390
+:103820001F42FECA2EC1B94E46B831F440B05C31D9
+:103830002C609C3AAB9979514FCE6E61DE44FEFE0E
+:103840005D0ABCE2E1CC82D3097E33946759363DF0
+:10385000D9ED592D3AD20FB3804F207FB86525900E
+:1038600011D4B357CAA45FDEDAA063281FD8A536E7
+:10387000CDFBB05CF27FAAE7FE348E87FA65230B9E
+:10388000E9703FCDC54467B4AEBC283E00BC4E7362
+:103890007899095EB74E3168FC9CB9E8D78C818B6A
+:1038A0008A07D971CFBFE492347401726E978BF09E
+:1038B00084CBBF02947FB0A433534FEEEA82F5DD90
+:1038C000B496D17E0752AD219E0F31183FD05F1EB6
+:1038D0000B7CCB3CA308FD2C9B24AB0EF3160EA453
+:1038E000F67F9BA532D60D6A71750E633FB10E94BB
+:1038F00008503FE46AD8D27923B45B065E40E7AF54
+:10390000CD16585013534F49695F5083873685C988
+:1039100022C0C78A33C03EADD29CDD7A98DFEAB6BA
+:103920009153D2CA06E994F6D371BDFC28E67D74A2
+:1039300014E8487F62B1EDB08FB20249A1036F1164
+:10394000F18F1A1EC78F1D5FB45F61FC3930FEC452
+:10395000CF31BE99AF3F131F81DCC9C4F5A3DF1A75
+:10396000C7C7F345E751ECFCCA78220B6EC7780B4A
+:10397000CC6713F87C12E69564326D1EC1E07C12B0
+:10398000CC57FA77D84FEDD0F3305CE93C6EFF7C32
+:10399000E7D1A1F3D27A83E36D64173168D64D463F
+:1039A000FB83CF6711D921B19CC3B5637214AEA05C
+:1039B00007D2B8D07DCD6505CE0684B36424380F18
+:1039C00007B73E89E7356D90ACA135CEFF03E7E53B
+:1039D000E0E7153B1FEA93D73CDFED309FFDDAE7C8
+:1039E00043F822FD0CC217CE646DE6B5C317561519
+:1039F000BC16F8F6C1B8BA18B846F3879E92D02E16
+:103A0000B0187C660FF0DF9B0A5249DEBAED0BCC92
+:103A1000944F90B1C08C797AEBDCB61ACCE75BE7B7
+:103A20005A6436C4C8E975EE3A6A87FE94F7E40E24
+:103A30005BD16DC14A5984FC021B6EA8762C47FCF1
+:103A400069E679546A5E912A0F9912AFA47DC18B01
+:103A5000236EDC3BD007FD37344FA4BCB111A9FF66
+:103A60004EF9529B1A3C1E6CFFB685C71D9F54E24F
+:103A70004E88A8E4571B7FFD7730FE5A5EB04AA0FF
+:103A800078E3CA2BC71BCBCF47AA30EF8A2DE77943
+:103A9000558E3A314E1E6AE97613C295E73F85048A
+:103AA0000E5FCD782D05193C1EEDDAC1D0EE7B05F9
+:103AB000C6D26BE94B877948F1F4281ABD5225EA42
+:103AC000EBAB74B48E6C0CED83882B2F9DEB580EF2
+:103AD000CF73EE163D023C1FE97E98F29140DB2742
+:103AE0007DC3ED3E5685F521FB5CA1DD47FCBEE2C2
+:103AF000D70D828BD6AD9E57F9794F12DA57E5056F
+:103B00000B285F8C7E2ABDEBE3F6938E76B1CE6BED
+:103B1000198F7641CCBE98A69F62BFFDD7D6EF44E1
+:103B20006442BD303E1EF64F3E5AA78979CC467A94
+:103B3000AF8EEC4835CE9685B483E73E9AF1384592
+:103B4000FCFB93F9FBCCC1E36E262B98A4407FC20B
+:103B50007D56F2679A4C5087F3118CCC3C0A9E3FFD
+:103B6000ADF803D7084CC47A74BE30C3F9DA05DF68
+:103B7000668F134B6E4719527D946F8861DB587BBB
+:103B8000B40FF338A07DD5BDCE91E8CF1B01041151
+:103B9000417B5A8953A9FE9394FCFEA528BF5F2C54
+:103BA000F8688119E5333A9CAE676CFFCED35B822F
+:103BB0003951BA345DCC62728C5D63129B299FC30C
+:103BC0007471B4C6CF1256EC31B5EEB58BD5385FF3
+:103BD00004ED05CC5F625207BE5709409163FDA614
+:103BE000171D9A71A2E3E768E60D835D1D1B171888
+:103BF0007EFC242617C58E9F37CCF88571E34B09D0
+:103C0000C78F8E9BAE19779DC8F945D06E0D25F2F2
+:103C1000F39D2DA87A1B4979B87CB33305DC0F08D6
+:103C2000FC58A4389482378F389A29FF4C6FE5F1FD
+:103C30005283123F3998DCC0F32472B4F967554CB3
+:103C400012B17D5DCAACA302B457D9B47AFAF44B71
+:103C5000A7F5C877A68B5A3DDDCB9A093F6F62DA8C
+:103C6000E7861C2D1FD8A8D0872E796284F2D43223
+:103C70006C9477309C5FE1DD3646F95386245F33E0
+:103C8000CA3863E1A5B4750EA88FE0F8652F4C5DC6
+:103C9000887EA277153C5E07748F70AC5B3572BB73
+:103CA0003E66DC3A63B800E5489D8EE7EBD30FE64D
+:103CB0007F37238BFCACF1F352C66F8CDFABBE5960
+:103CC000F0B962F6F1AE421783F3ADCEDE8E7AEC38
+:103CD000E07CA6F0249A6F30EF47992FF38BCDF755
+:103CE0009E42CFEA7CF55FD5EEAFDE18A1FDD5EBA5
+:103CF0009892E7CFE77B0FF7E7FC02F329F95B83A4
+:103D0000F37D4DBBBF7A5384F6573F684F2AF36566
+:103D10007EB1F94CC6668ACF3C26F0739DBB6BD44E
+:103D2000E3E8A7BF3077958CF8A6DA67B7E00B8099
+:103D300067B728F94DB7E618496F50C7DDDD3685FE
+:103D4000798DDC9F8365D10D02E5FB8F9B22783155
+:103D50003EB60DE8DE5B88FE2A89DA436D0E2A77CF
+:103D6000B4C9547E17EC412FF9AD3C54FF1F85DCDC
+:103D7000CE7F6C94B46405EA0B95569EEF7CC334F9
+:103D8000D044A3F61618607D16CC2BFC322BDB0832
+:103D9000B5C2AD1C1EF6EACC109E93B5EC50A40D36
+:103DA000EAA6A97A19F3B84D4EE64BE48F692DE4E3
+:103DB0007E9E47D4FCF81B051E7F077DA412F6BF2C
+:103DC0004C0135D3CF1550AFBAF56BA9A48FD42DC4
+:103DD000EA4F96601D7708656FBB001EBF51F491D6
+:103DE00065A3391DC7DB9376942C13317F4F1F0ACF
+:103DF000C19F0B9317923DBA70316369F0FEADF825
+:103E00001EC895E38A3EF346BF89A1BD16ACE67194
+:103E1000E73B1ED6DA918F59C212EA718F95D919F4
+:103E20009E475D8BB6FD11258EB030CEAEBC352ED3
+:103E3000AF06B44C9E1F827B9ECAD80385DABC9A1B
+:103E40008A4299F3B91C3B2555A7CD768DC078A43D
+:103E5000C998F81E8E3ADE33AA5CB67B090E6A1E3C
+:103E60001AD3BF5846EF2BF3A9EF3D2DBC38EA4AD1
+:103E7000FE4ED0DB3EEC2FE2F219F5EB8D71EBBC80
+:103E80003037EF1BD52C11DE0E88E85750D7FFBF17
+:103E90000B5FABD1A70178747CC6A713290EC37240
+:103EA00068DFB7A8F8A3E4572D1CAC8B4C8CC9AFC6
+:103EB000638E01379EF75B3726793612FE29FA4367
+:103EC000F81DDDE5A4CF3FDEE03A1CDE5CEE8FABF3
+:103ED00096283F48196F3838C7E73FA87E1BFAC5B8
+:103EE000E41FB66FE7F98F59F6AA8FF19E143E3F93
+:103EF000ADC12BED7DA8F6DEE704B42FBE8DF7BB78
+:103F0000C4E87CE8BF0D92FEAABDA715BF2EF5FE42
+:103F10008DBA9E76232B227B5407FC01E69B67EB30
+:103F2000170519FDF10322C5CBC7723F11E608F34F
+:103F30007B2F5CCFD367EB783EC71899EB7DAE81C2
+:103F4000D1B1F1A28F0AB95C9F97F4668B0CF2EFA6
+:103F5000FDC2C042CC579A37E2CD1627D44F153652
+:103F60002FC47CA679D96F7EEA049DEDB7855FE109
+:103F7000F592373FCD83FAFF2A5CC5EBD31801E5F4
+:103F80007785AB17225FFDA85052FC97911C9C6F60
+:103F90009EC0F1E58B967A932E613CFF7CA1EA4F9F
+:103FA00064069CC7D7F3AF27911FF954FFAB571B8B
+:103FB0008764D89489F786949F3D85F49939F837BA
+:103FC000C0F36631DC8BEFEBCC6182EB58CCA329DC
+:103FD000221478E2F215F225E2F14800746D457D75
+:103FE0005996581DE8C7EDADCC6FC98FC173E65522
+:103FF000F09CE7F5A8EB51E71FB22E3852312D7631
+:104000005DDB681C755DE7CA4C41BC5FA6C655D533
+:10401000759D13069E4167C49C929D8BF15CCF25D4
+:104020000F8C16A0FEFCD8B7E99CCF650C3C23781A
+:1040300062EA067E8E23C73E4A7A4F8BE01D391610
+:10404000F9A5D146F7D83A153D6F53863FC8B87EDB
+:104050004FF98FC15C7E3FA07AA2E08D8DFB3BC7FC
+:10406000F2B8494829679A36379F007C0CEC15D87E
+:104070001AE81FB874C188F6F8BC9E5346B4BB9BBF
+:10408000F69E32A25DDD847518A7699B91F8553CB8
+:10409000BC778ED56BE2EBAA3D7138B7709D1DD60B
+:1040A000D3B442F060CAECAAFDA933B1BE6A39EEBE
+:1040B00092B1DB6FD83313D1A5DED7BB0ECB65AC85
+:1040C000FF30DE9F5BE2D7EAF94B1BB47A797DB310
+:1040D000569F5EB6194E07E4D7B2D66CCD7B0C3531
+:1040E0006458CF12E53C97381E8DE8C7633DE65E05
+:1040F0008E40644DFE9DA57C07506AFD16F37A0440
+:10410000A2E3A65A33F95F0FE7F27CFAC04A3DE515
+:104110000905101DB0DE2C28FE2C2FF147557ECF4F
+:10412000EC3E7F241BDF5F692038B0A037827EFD24
+:104130005A059F96D5D67C8C78562BDFC7E5F89824
+:104140005D06F2AFF8B93E2E2BFEEFBAEEC7AAD34A
+:1041500050FF6C11C8BFB1B441ABAFD7E31FA8BFCC
+:10416000B50AA1B013E1A46D5FD6AAADDF355691B3
+:104170006325AC04E9A461AC2012DD28F53FE6FE1E
+:10418000E28D304CF490E0BB7F2C1CD04A63783C2D
+:10419000CAB587043FD5D57678DEC4E50E97F73AE1
+:1041A000A028E2BB06EE5708360A848F4B87C8FF6B
+:1041B00018FD403FB4FECC582EDFDA2DBE16B29764
+:1041C0005E1524D447AA45AF98E68EDAB3F1F8F825
+:1041D000AC82DF6FB07E37AEAB10810EF02F5C3853
+:1041E0002284FEB0C29F2CA77CC7C20AC1A3237A37
+:1041F000D6B1D6722C45E20FA86F5AA02CD477D531
+:1042000012BF9E6094783EA183C5F201EF734CC04B
+:10421000BC3E5C3ACE7B73CED1CFF01C6FD9FAE8AE
+:1042200079E477AE7C6FF963B0BE4D163EFFA6FD14
+:1042300002E9AF4DEE23C41747029AE0BC4D0E854C
+:104240003F76037F54F70FE73D12F9155E1099EBA7
+:10425000A67947A9F10135DF365CA5BB0CE73752DB
+:10426000997767A94CFBCEBCAF4BC07DE7B2E01A93
+:10427000F413FDF3584670544BD58FBF381AC776E8
+:10428000E279363AFA8DA47F2B71EC04FD4A12F6DE
+:10429000F3328D1F61A6FE520AC69B57BD9A7FC599
+:1042A0007C0BBD59A7A1578364D5D0F5CD455A3AAB
+:1042B0009FE7D1D2F7AD53F235EDF3BD259AF685E0
+:1042C00035159AFA62DF344DFFDB6A6768ED7DC70A
+:1042D0001C4D7F8BBC40534F2ABA5DD33FD973A787
+:1042E00096DFD8BB28AFC0680EF6FB010E9D80ABF1
+:1042F00053D2A2FCBA24C58C49C7CC5A61B161D94A
+:1043000059660AE3B97566F138ABE9B5071C6184F3
+:10431000FA8817CD9550BE2084AA305E6456ECBC56
+:10432000E28799869F8F2DE178AE96EF8FF57F5CBF
+:1043300004A57BB79CCDF3A723C5783E66742022E5
+:104340001EEF3393DE31214EFFFD5E69E56F51AE06
+:10435000B81FF6CE26BF543793F0FEEC0E23CF7372
+:104360000AEEE3F9B4EEEE7E9D3786DE02455CDEB2
+:104370007FD35745794B4D3D20CD10BFB79E36A218
+:10438000DFAEA9A73705E5C678DF6923EAD7D1E70D
+:104390008A3C1107AC18BFFC97AEC4F969638A8CDC
+:1043A00034FE1185DFD63FC0F92D20DC5CB48F547C
+:1043B000FE59BF87EFAF7EB191E85BE5A3C03F3503
+:1043C000F1B078BEBCF486D03AA45DE0A31AFB65D8
+:1043D000D9A2591FA33DC45898F418E0A3DAF69C5B
+:1043E000F544DFCBE2EC9BE422E0A7A8479430F74A
+:1043F00065A097933E5DC27DB94BF8F7024EFA6710
+:1044000010BCBF097043BBF19B43E0C4E17735F8B2
+:10441000BCA4F813D5738AEF5756C2F9E84BC3F022
+:10442000CB078A78FB0E21528ECC2CE0B3129E2E45
+:10443000359B1763FEC191DC3FADC77842FD0F0489
+:10444000B465D9AF7B5FCBC47C04E39EC399982746
+:1044500011E83A9CC9004E2B0DF21AD48B010F3C87
+:104460006BE05C9ABAC3B4FEC6AE8A5E7CDED82D21
+:1044700078901506F69E9F45FB64FDEB518FDF316A
+:10448000CCBAA615717D785691CCF398FD3027CA29
+:10449000D9BD26B263EBF7001FC275ED17E85EC603
+:1044A0008E0DE6DA44FAC9648437C0E9D00623C326
+:1044B00038CA4A781FF77124F788D18C78B347201F
+:1044C0009B30D0756231FAE3032D0686715B757DF2
+:1044D000677223EFE3FEDF596160788FB07D058F4F
+:1044E000C7BED3A2A771F4771BA8BEE45E9E377C3B
+:1044F00070C56FD767C3B8EFAC1428DF7EC6DDFF89
+:104500007604EB4BEEE57A503CFE0EE26B1C7E2E01
+:10451000F16BF16E089E367C313CBD338AA7E351C6
+:10452000CEC2B9CF1C89F8F320A37B8CB5970E1AA5
+:1045300046C27AF3D64B1E0CED96EA43EB32912F2E
+:104540001CE4ED652BB70B9CBFC874BF3DBBD3C843
+:10455000D06E7C4039AF0794F392D98080F96E4CCD
+:104560008CE4E1FA9C4A7ED7CB0656BB07FD482275
+:10457000E72FA53F746C8FF523B914BEA2F2BD12CC
+:10458000B0F7F7901FBA2B0BEF9DBF64E0FEB1D1DF
+:10459000CA7805F903B3E643F9CD22CE07DB94755B
+:1045A000A875AF82FFCCBE83E03BCFCCE13EA73500
+:1045B0005C87FBB847F4AF2B82F6B9A37FB1925169
+:1045C0007EE4EB6E3FF9B98A49AE0594F33838F5CD
+:1045D00077DB56631EDE382B9DE3FCBEA72278AE48
+:1045E0004D2E91F20F2D051347FAAFE047085C946A
+:1045F00035F7F89A7ACECFF226A0EB69CA7A4B95B6
+:10460000FB7AAC87FB0F801F8B53CAA3FDD4FDAB95
+:104610007E0F4BC177E99C567F8595F17BFC8FD14E
+:10462000FE97AE3C21E03D95DB0C5E830DE0FC8BFC
+:10463000116C31DAC1AFB731BAB7760CEFAF012BDD
+:1046400079A34DA27A44B9C7F6669B4CE56D46DF67
+:104650006E84CFE243CD0508AF83B94FFAF0BB0CAF
+:10466000E78E29FA2C93F8BD4605F72EF4E8991940
+:10467000DA2FEC1542E43451D67FC7C52CE6077E0D
+:10468000F22BE5BE5C63EBCF89CF791ACECF423BEC
+:10469000A36CE5A9F5580FB4FEDB2CD41BDE07395B
+:1046A00081F815E8169803C6A9BB9846EF37769FA0
+:1046B00030A23DFF926E6016C23F7840A07B5681CB
+:1046C000E6F3C43FB729FE958F8A781C31D053A6F4
+:1046D000A3F3F41673FB4439FFDEE27F4F41FE651E
+:1046E0006E958F4FC3733CAAA773DC583590222573
+:1046F000389793302EE68FFC4AC9D38B6FAF3506BF
+:10470000C92F5BABE06D7CFB070A3E02840D4A9E1D
+:104710001213603D750A7ED5E3F761D250CF17C200
+:1047200056A0DBFA9E19E4DFA86FBEF2F75E86C3DF
+:10473000B76B2D9B18F76FA875B4BF62F3B8D0FEA6
+:10474000D2DE4B0FD23E4CB9AE91FE2BE87781FE04
+:104750002C8A9F3475328A97345E2CA6F2ECFE4781
+:10476000E81E94D93AF024CA0556A823BDBE31A844
+:10477000D56F8E17733A385ECCE9F95211D8276697
+:1047800036689F801D7219F112EC90943EA6B14FCD
+:10479000E29F937D6256FC86A02EF95F4EB0EEB785
+:1047A0008AABC4711948579B09BF19E037E255FC21
+:1047B0003E478CE3EB52E97949DFC746D47703DD06
+:1047C00089E9F937C5952370DC0DC3E4E5BD5DCCFF
+:1047D000F95DE35646F00A6C4D23389D615B7D55CB
+:1047E000809767601D784FFD9CCF97940AEF9FF3E9
+:1047F000FB92303EA7D27FD3562BBDB7C1B5201D4B
+:10480000BFABE11AC7BFEB73B67B8619E17CC75615
+:104810004E77EA7CEF8797A423FD4C320C18D13FEA
+:1048200099D3732A05F5BA49FB17A623FD0DB74E98
+:10483000BB721E8DAD598BE91E10FCF440F7F72BAF
+:10484000722CB0366C44F8DFDFCA087F7BF7FDBA04
+:1048500009E9F76C4F928472F2CCAB4941E4F7E777
+:104860000E98423A186AA5F23DA43386FE5B487F53
+:10487000DCAFA77C85C0813F3C89F418D867A27B58
+:1048800035F7F73C721EE5DCCA9ED91F8B58BEF87F
+:10489000F7A587C6D6D18B63F38EFFD0B63B0BF955
+:1048A000E75991F389FBBB5F217DF6FE4B17C66389
+:1048B000FEE09957FF6332F2B3C04F2E4C463E16CE
+:1048C000F8F185C9D81EF861527322FD646609FFAC
+:1048D000CE862A1F9D6F891A3FCB39053F9C1D9BB1
+:1048E0006BF0BB05934E2CA23880DA3EA940E7C39B
+:1048F000FE93DEAE4EBF3BE6BD8E8848F912134FE5
+:104900005427AD88C1CB0F8A0DAA9FEEDAFC234A4B
+:104910001E82EA1FD91011F93DBB067D08F37B9773
+:104920004678FC3DDE6FC298EFE6523CEF7B333CAD
+:10493000F8BD1EBCA78E7191730F1684E89E7AD0C5
+:104940007CD815A3072D89E8C226F483F498C2A861
+:104950000F2D8988A74C317E91F7A597D7A11ABF53
+:10496000C4AFF563C4FB41E0972CC6C44FEA5BC2F9
+:1049700006554ECD83F97FB18E4918B719E21FA9AC
+:10498000FD12F961E2FD2472E40933BE27BBF8F79A
+:1049900075543D13CF6B6F027AB72974A2D2514779
+:1049A0004447E7D011A932BBA03428ED7B416C0607
+:1049B000312FA867E14EB4D33B2EDD9684F0EA7820
+:1049C0006B01C3EF479C93AACC05F8DEA52F99177E
+:1049D000BBA3F831847F8CE37265501F1846CE1D4F
+:1049E00051F8D6DF4BDEF58DFBEF21EFC0AE7E6DCB
+:1049F0001CB7AB9772BF07B7ABE3E584CA7FD5712D
+:104A00003F53E03D94FF7E4CFA0BD8BFC47F3F1B61
+:104A100027F3EF34F4CC4F27BBF8AD45E9B26DE88E
+:104A2000F8F9A24797E61E3ABEAAAF0582DEC36632
+:104A3000B463BC3CFF34B048A0EF48057C02E9D920
+:104A4000813A4308DBD5F54416F1B8E0628F40DFC8
+:104A50000551F53F553F1C6C9F08EDCEA8BEA8EA56
+:104A600085111FF78B2EF21AA8FD36A37F60DC2478
+:104A7000DC9F859E4F9ACAC7053E7018FD9FB77D83
+:104A800059A0EF76A9FAA28A9FF1FAE4273DF957D7
+:104A9000FC1EDD36052F55FA1A1D4717AA9C7229F0
+:104AA000F06942399D8E72FA3363BF6D78BD1BE4A5
+:104AB000B4584CEF31C2DB896F8BBE4476F7B7C672
+:104AC000717E6C2F56CE2D72A812D79BCB229417D5
+:104AD000359CFCFCB498D3C370EDAE715CCFB91AB1
+:104AE0001D4F2FFEFBD2F1B4E2FF1E743CA8FF194C
+:104AF00013EFF3ADE2CA6A3C7FABBE99EE4DB19FB6
+:104B00001AC86F1DDFEF3305FE20CF34787C38D70D
+:104B1000A843BB27D0C0EDFECE54F938D927AFF15A
+:104B20007BF8F72BF94AF75D94A8ECC40F8561FB7D
+:104B3000034EF2DBDCB7FB84C10BEF2F6D11CAD043
+:104B40001FB4B441BB9FCE0CEFEC583F78E7A82EC2
+:104B50008A2B0477E6CB387E3D6E16FD219D5921C8
+:104B60008C3D36A11F67023E8FB98701F3342ACFEF
+:104B7000A729FE1D16A707FCB8F71DF2F7605C0811
+:104B8000E9D7D823505E48E028F77734F570BEF0B7
+:104B9000518340FCE423253F23D06A21FFB6AA4776
+:104BA0007CACF4BBF74181F4BD217A85571B776952
+:104BB000FCEEDBC417E3F588B4BD7C1C8CB7A05FAA
+:104BC000E670EE6401EB8D60178E447D51966FCDDB
+:104BD000E6EB6321E22F5E8D1FE593A3BF253B72B9
+:104BE000E97E81A593DE11177FE99C13177F397247
+:104BF000381BC751F40C09FE0FFD87F17A4653F7B5
+:104C00000903DA05578BB36C2ED6FA05C788DCCFBB
+:104C10003AA64790D09F344681D3751BAC04A75960
+:104C2000EFAD48473A57CFE7EC7C7E5E67DFF9B4DB
+:104C300012DF9BFC9E2821BFFDF13B2D3FCFE67587
+:104C4000D92CE37B2D4968879C7D6F5512C2F1C733
+:104C500050E2F7927E78524CE83FFC6BF1A0DF788F
+:104C60006731CAB78715BFB108F22D39EA7F897F4E
+:104C70002FA784F3A94EFC8E11E2DF7E1EDFEE1C0F
+:104C8000E59F43F5A7F2781EB1C8F1F5959E54094A
+:104C9000F5BD12D82CC661BF6F651D185FE9CCF059
+:104CA000BF4EF4F1948EF017DEE7DFA1D82393BC5A
+:104CB000C3D014C63FC683AC31535EA39DE220EA45
+:104CC000776246811DAA7C576111C65D4B9438C836
+:104CD000782B1371FC4D06FFC6711877E9153D6BF3
+:104CE000F01DD1938EDF458A8FC7A8F161352EA3C1
+:104CF000C689878BCB0838CF788E67B1DF3D51E30B
+:104D00002FECCB3C7FB37D4A33DD8BDD8E3112E25D
+:104D10009F43E2297F463B353E9E22A2FCA1388D6F
+:104D2000369EB6B1E865C2B7CF1B479B5E3CDCFC44
+:104D300032B7E7E2E69F98FA4926D92F7FF9730A3E
+:104D4000C9B39E0B2477CE0D9894FB9DFDDC4FDDFF
+:104D500063207BFD1CD8411931F26CF9380E87BEF7
+:104D60009E19848F7B23D549D8BF53D17336BCB5E8
+:104D70006821EAD3C188C8F3B119B76BF646C449B4
+:104D80005C3F180227A93841DCC96C4D9C071456BA
+:104D9000FC056165DF33DEE1F64AA085C70F248597
+:104DA000DE023546E22747723305D58F3C32517C0F
+:104DB00061FF00F1D9FA7B797CF79AE30BDDBD0640
+:104DC0009697C06F5B338BF8CDB5FA6B195AC193C8
+:104DD000A3FC39AB44E127A58AFFB698E7F3A735D2
+:104DE0009755E2F7EFC2C39EB77F634982F34ED077
+:104DF0006FABFBDAE281BFBEC6B8616AD1B5F51B05
+:104E000093881E12F49B7E8DE37DF31AFBB55DE360
+:104E1000BC0BC725EAF7FF68FC333EBE191F0F8D98
+:104E20008F739A5EBB3B886D8F088F0E8411BA29F1
+:104E3000FB6A05205531F5BB66E46B73A7F278C0B9
+:104E4000866A7368BB108D8BAAF00A9672BD4B728E
+:104E50009F0FE27712477B23D5E940C7E7A632B21E
+:104E60001BCE5994EF2389D2A8F9747E127D1FA717
+:104E7000D39238BE3451196F383EF2BDD2CAF548CC
+:104E80002FD230DFAFC82DE17680D4CDC85FC344C8
+:104E900079D4029A571E45DFDF3BC49FA78419E5EA
+:104EA000F741BB7301E9CFB213D7B745897BA5CDD5
+:104EB0002974A29F2E0DE42DC6451EC3F808F9F5EE
+:104EC00025EAA7CE97ECE6F36D313001E358C171C6
+:104ED0003CAF82757C5F13D73866087FB05CA0B8A2
+:104EE000C6765CFFCF7461F70E273F1784AF7BAFA8
+:104EF00044F19637A67EAF88EECB2B718ED512EF9C
+:104F00007210ED0C58C7EA572B087F97F64DFD65D8
+:104F10001DEA832E91E03C440F57ECAB938A7DA8A9
+:104F2000DA57FD6827C6D81B3F50F4860474F58312
+:104F3000447C698BC0EDDFE0CFB8FD5B61F4E4C772
+:104F4000E653F52A7192E561EE8755EDDAF1DE90D0
+:104F50002E13E050F1A03E6C02395DB1BED488FC46
+:104F6000BA627DAE95FC4A2BF6E85478273AF79F53
+:104F70002AEBDC707480E212AFC4C52793DD466A69
+:104F80007F48C19F643C5B28571788ED287E47DC2B
+:104F900020E913F9C5EB41EFC7F52DEFE4EB55E33D
+:104FA00020F5617906CE73EAF0C07A2CCB1B9C33D6
+:104FB000C86FB8F2FC7A949B814B178E4C273F80C8
+:104FC000514E745F604B29F71FBE828A08C26BB6D0
+:104FD0004879BB15B3453AEFB47A0BD9E16906A617
+:104FE000C7EFB0A6CDE772ACBCC63E03EB6C512A4E
+:104FF000C9E1F2A372EADDEEA89D9F36BB2503E16D
+:1050000074B5F890EA2FB8CDE8FD6349C6E78F0F75
+:10501000351E7B8BF2CCEEE8D7C687D478CF70F103
+:1050200021353E1BA8F954134F0E8803B3D0AF525D
+:10503000F1EA298A0F07BA05C9E18CC68D027BCF38
+:105040001B09BE4ABC08FA1BF1BD0A38F65169F8C3
+:105050001D021E3FDA87F9B846FCBE9E4479B73F71
+:10506000C27CDC42FCBE1ECFC73D80F9B846BCFF07
+:10507000C1F371FB94FCDE40CF798A37A5B987E490
+:1050800053513CE221C197E19EA48957503D3E5EB9
+:10509000A1B7723B3470D440DF3F0F1C33139FAD78
+:1050A000EC593E06F531F5BBE44D182F88F12F9DE4
+:1050B000F57A2C78BFE7ACCF63C1384145EFC746DE
+:1050C00099F84E381B53989AC48811ED7D8403E5F6
+:1050D000F9F5545A10AE57F5EB77FF7FBFFEE7F1B5
+:1050E000EB7F2B4A97C43FCA7D3ABA575E7ED46B9A
+:1050F000B93B863F6CF071FFF006571ED1DF13BE3F
+:10510000BCD415B17EFC1A6EBFA5CD7659629FBF87
+:105110005BCAFDF86942E2FB0577B987E5B777B965
+:1051200013EA3B89E3011B6A381F51FDFD43E3038A
+:105130009ED75C317EFEB33F33D3BFAFD0BBDF44DD
+:10514000F2FC4FAF9A76A0DE5D5EB3624C32D4CBF8
+:105150004F9A9893CB234D5C61698DCE6B4949146E
+:1051600047F066D3F743E3E305353AE2EF83F18294
+:105170001AF114D515FDFC8EF3BF4BC64F94BE2219
+:10518000843AD1BE78A551F0F4B2A1F10318389B4E
+:105190004D815DD4703BC1536B26BBE06A7185BA0B
+:1051A000BD27D6A19FA08C6DEEC4EF5196B97412A5
+:1051B00088A20471059EDF59AEE811F1FE01C40F0B
+:1051C00094FBF17EC1AD6E6E9F6F55E47E5E0997D4
+:1051D00033EA38EA7BF1E77EC6AD8D3FC4B7BFA79F
+:1051E000B477D4946FC0730BCED531E4FF1D355521
+:1051F0006657CC782FB879DECC168C53D863E3147D
+:105200003C1E111F9F50F95345EF67B3F0DC9FE838
+:10521000E1FEA38083FB332B0E54D23D93E83A3951
+:105220007E3EE118BC6798CAF8BE9899FBB9C8AF32
+:10523000503EF7D33EFCF707982F95FE3D83C031D3
+:1052400057BB0DF9C85C719220937F7BD0DF8DFE38
+:10525000A885C71BE6603E70C5E2B213782E8BEBC3
+:105260000C9477B4F0782D7D675C9557158BB7AFAC
+:10527000B5627B91E0B1C8D85E5385ED37BF184663
+:10528000CF1E9B87BB077A891C83DE79E4DFFE296A
+:10529000DA4515F315BF771D97AB8B7BE61BF847F7
+:1052A000AFB472EE60EE9FC86EBED05341FEEC7498
+:1052B0008CB7BAA372A6E255903FC951F9F3B7CAA9
+:1052C0009D336E9EE73F01E40FAE276D3E8F0BC608
+:1052D0009FFF0B0A3E0D274F86E39F283F745338EC
+:1052E000BD088EA8DC95D19EBE2E2A7FA56EA88F04
+:1052F0001C1EFFF215BC4E1D46FF1A5D2A28DF1B3F
+:105300001B265FA3FBEFE3F7CE2A55F9E7FFE57E07
+:105310006FC5BE51FDDFAA3DD4A2C0592D1F50F468
+:10532000D9BF395F198562C27CE5B4C4F9CA777404
+:1053300009F41D16255FF9B09155EEB1639E9E727A
+:105340002F21E423FDE6F0D3BF5AFF9C1DEF250873
+:10535000128A9DC6AE13249F1B419F213DA8E70FD3
+:10536000DC2FD5C5F34B1BBBB5F71FD4725B29BF30
+:10537000AF500DFB213FB292C7376B2FA7EB80D701
+:1053800018929DE817FAAA18EB170AC8910C353F36
+:1053900030C4E552C23CBE263640F97E4D0D820730
+:1053A000E5C117F61379797EDFB5FA89EA4BB57E48
+:1053B000E6B525DC2F54EB1704D447CD3ADF4ACAB3
+:1053C000EF3D204889F244572BF87EB3E2A7DD6514
+:1053D000E478B0EB7A81F26AF15E0C9EEFAE033CAA
+:1053E0007F7E5739CF9F57FDB26A5EFCB8A85F96A3
+:1053F000EEC3A8F9F46A7EBC7A3F74FE566B18F5CA
+:105400008B4D862E07D2A19A57E42AE572CEAA7C4C
+:10541000773C7E9DCB4A2B5DA518A72BD50DE7E7E2
+:105420006A2B4DA0DFBCAEC8CF75A5C3EAE59DA52C
+:105430005ABD9CEAF17AF97F955F76CCF07EE15F08
+:10544000975C9BDFEA96C47ADC907E95A509C66BD3
+:10545000B724FE8EE8EF54FE1BF7EF8FB021F77BE9
+:10546000B87CEB14E45F4EA3389781E25C2A7FE9B5
+:105470004CE6E3EF53F88A5A9E50C61FEE7B93EF3B
+:105480002AFD5A04EF0F70DD25BBB57EB2D22EADDA
+:105490009F6C42779AA65E16CED2F4AF389AA7696F
+:1054A0009F1429D6B45F77B25C539FDA7FBDA6FF05
+:1054B000B48FAA34F51B07B47EB2E91717C4DD3BDD
+:1054C000E2F85D091811FBDE0CF35D9A7ED90DDA66
+:1054D0007DE5366BF735A655BB2F755C6750BBBFB6
+:1054E000FC4EEDFED2D07FEFFEE2FEFBDBDD32CDE7
+:1054F000D3D7934FDF03DC52E3A2EF5EABF7FFFE9F
+:105500001307AFFB52406F000000000000000000D6
+:105510001F8B080000000000000B53E16760F8518A
+:105520000FC15BF918182EF021F8F4C01CCC0C0C3C
+:105530009C40ACC8C8C02001C4FC40CC06C49E0C32
+:105540000C0CFF81F81B10BF05E22740EC0CC407D0
+:1055500058B09BE3C6CAC0E001C4DC40B378988968
+:10556000B7DF8917C17ECCC3C0700E889FF1D037DA
+:105570000C061B5E27403FBB7E43ED3A2932F0FE0E
+:1055800006612131609A1447F0A78AA3CA0B8B21C8
+:10559000D8C9D294D9950FD40F00F19321F080038C
+:1055A00000000000000000001F8B08000000000049
+:1055B000000BED7D0B7C94C5B5F87CBBDFBE92DDA6
+:1055C000CD26E44900370960501E4B80C84BDDF002
+:1055D0003252C40411828A2CAF10027914A9A5FF9B
+:1055E000DABB0B2804AADE5851A37F6A17041B2DCF
+:1055F000DA80D11B6DE02EA208D56A684551AB0D4B
+:10560000888808498C8F6AB57ACF3933DF66E7CB53
+:105610002E89B6FE6FFFBF7BC3AF1DE79B99336733
+:10562000CE3973E6CC9999B32696C20C9733F60D12
+:10563000FE416A3331C6C674A5ED4AC77035A7ABC3
+:10564000FC36BF9779CD8CD5F9AD946EF1A733EFC9
+:1056500060F8EE331406ED8CDDEB7751FE17FE4259
+:105660004A6BFD4554EF4E7F09E56FF7FB28DDECF3
+:105670002FA3EF35FE6ACA6FF0AFA17493BA280D5D
+:105680005082BFA2C2AC64C6AA9EC9C9DB0CB92DA8
+:10569000B3C627A8A321FF8A9119B300BE4FA5FE68
+:1056A00098EADE347074573D0DCF4DEAA47E08A70A
+:1056B0007609C78B59992D46BD2C1CE79D4B043CA0
+:1056C0007B6B4D4E72D47A8311DEED25006F28146A
+:1056D000B842D69CE8F02E46789B4B545E2F395842
+:1056E000931D1D9E07EBD5DC20E0A507AC31EA8DAC
+:1056F000C17A1B6E10F8F5F3D56445EF773CD6639D
+:105700002EF56FAD56467FDF64E3FFDB5DA72E16F7
+:1057100079236693181BD7D54E9F321660384E9565
+:10572000F90A890FEECCAFBFC967EC268409ED03F7
+:105730009358C808FD079258707D96547F26D56F00
+:10574000EDFBF537A952FD80214A7D136B50B0FC6B
+:10575000E72847C0F7FBFCB9946E14F273DF5003DF
+:1057600063D82EDD1C1C04EDEEF17B485EEEF68F57
+:10577000A5F2BB841CFEBB90B3A090B30751CE2012
+:10578000DD8A7266C6FE7CADA500A77D6F3CDBECB2
+:1057900026F95A4C78AA8CE06FD83B64FB66807F70
+:1057A000DF0DAB4E6F03FAB7350FF318A1DE3D43A3
+:1057B00035F9625E96DC55EF9ED9279C8B8612BD2B
+:1057C000CB10CEDD1EC13F15061651EFEE19E17A62
+:1057D0001558EF2E4F185E28B2DFBBA684EBAD2222
+:1057E0003E2BACA4C1DE9D2F3B9842F3110485E80B
+:1057F0006B42FAC2BC7C76C0754A2BB44F49CE4B83
+:1058000063D0EE7E9C8F669C776EA28BD61EE9ECF1
+:1058100083EF1916568DF081B2FB8D80AF69B63BD0
+:1058200011E972FBB5454C19C6585F519E1A2852B2
+:10583000B200AE7D4E9182DF4DB3A11CBEBB447958
+:10584000F21A5E7E3B963BBACA13B11CBE27554383
+:1058500039E4ED7379F91D7EE0C4E0AE7A9B80CF28
+:105860003EE2773AFF0E6C45FA9846F354C3FB09C3
+:105870001412A0DF414CC774E1BF69D0BD190BED14
+:105880005DF8DA06D7535EC36FD3E038CA6BF8D839
+:105890002EEC97B110D2BE4BFA326FAE980FAC3BE4
+:1058A0009D13BDD95279A6EA4950814E992F1959B5
+:1058B00000589009E289F0F4ED8A9881F0EC71FECD
+:1058C00025F76EFE9986CA74D0D2A3821E1A1D36A1
+:1058D000F697E9601920D361E300990E960BCE4F3D
+:1058E000871DCC4D748E450FADDFCD43E47EE32E96
+:1058F00092FBDD7C91DC6FDCC5FF9C7E6BB2E47EAD
+:10590000ADD972BF35D972BFD69C7FAC5FA67A6025
+:1059100032A0BED2FE2E94F4DBD5CC7716DBA39E4C
+:10592000C3F9A4E93953B28FF9EC5DFC84758AB1EF
+:10593000FC48388325BD0A703EC57A00C77B7E3897
+:105940002E1D9C417A385F0B7C58A49EEE06870D75
+:10595000D48FC3A4F076214344FF4CF5B1224764B1
+:105960003B8FAEFF1C7DFF4E458CC370DEFEDD3AE3
+:10597000BA66EBF14913F830C3F9E8C15C3A38591B
+:105980007A386E814F48392F1CB77E1C178AFE0368
+:105990008AB47E013D8675B56B07FC689DCAB30469
+:1059A00077827E08EDFBF214AE03E71AAF755BA0B9
+:1059B000FEFE9196D0E5507E2E5810B440F9E427B3
+:1059C0008F3AD18EA978D2A862B9619F8DD697B649
+:1059D0001D0A9557595AEE9C00E51D4F1AD976EAD3
+:1059E0002ED380E33B25740A0BF17CA98D672BB67F
+:1059F000EDBF11DB973559980DE0553CBD6CE604C1
+:105A0000C82F3B646258A562E75A735FC82F0F2AFC
+:105A10000D98077C699D0AE4D9823BA1FEBA7D5F9F
+:105A2000B621FEE71A4D83109F33B04EB8619D78C2
+:105A3000C9D1923A1BE8531EDC3D0DDB97EF523C77
+:105A4000A0E100FF9D073310FF47148F0558B8A24F
+:105A50003E9EB923E6CBA946238D77D53625C800CF
+:105A6000DE32563B0DE95981C4413C3C96A04DE9DC
+:105A70009A6F67FC75D49F96AF7804FA83F6958F7A
+:105A80002B1E1C72A581F9701EB73D6D2B79C88E37
+:105A9000E35D6B1EECC0716E3463BD65C1854FD98B
+:105AA000DC88E736F334C477EB3673E950A4235B24
+:105AB000503414F1FBBF327E75462F8E77D548CB1C
+:105AC0007623E0C1ECA181B31CDDF5EC1958AFDC05
+:105AD00011EB673903BD4FEB77D05C3CACEBFB9728
+:105AE0008644D21F2BEA8DCC6DEDEA47938FC0110F
+:105AF000211F7B1D446F8D9FAB5C7C0A68FC5C950D
+:105B000028F8AB76E4CF1AD61D9F3B912F644FBB8C
+:105B100028FD05AC9B986E81751EE9772FD84F6ED6
+:105B2000B2CB3DF4FD01B09330DD0A7612A60F82B0
+:105B30009DE4167612D6DB0E7612A63BC04EC2EF5F
+:105B40000F833D8E693DD8E3F8FD51B0C731DDE5E7
+:105B50000FD0F7C7FD359436F86B29DD837C83B40D
+:105B6000D11FA47A4FF9EB296DF237D0F767FC4DBE
+:105B700094DE2EE8E89CC80A701D757A990BC99EC0
+:105B800034C35B60827C5211CFA7DE102830433EC5
+:105B9000D50779A04BDF95A1020BE4FB56F3F20188
+:105BA000B7B04956C80F08F0F2ECDBBD936C90CF4C
+:105BB000AEE5E583B70626C5417E7090975FB42BAE
+:105BC00034291EF21735F0F2E1CD6CB21DF2C34359
+:105BD0003C9FF79277B203F2792D3C9FFFE7C064B8
+:105BE00027E4F35B79FBF16783467794F5778FC9F8
+:105BF000BD1855CE01E56DAF9A0179B3FB265489E6
+:105C0000479553946F3479A9FC7DA5DDABC23ADF8B
+:105C100068F652F917CAE7947FCAE4A3F278835270
+:105C20004079B38FCAFB1BE228DF640A50F90843AE
+:105C30001F9E3707A8BCC0D0AF00E13F630A52F9EE
+:105C40003586413C6F0E52F92FD4E10553A0FEE397
+:105C500006DF5ED477EB155F19DA874C6D48477D18
+:105C6000A5D9953B717068676698691EECF943FE8B
+:105C700043340FF02F19F3A50FA35D0A700E121C09
+:105C800013C031F60C27EFE5B1129CBC97CB34382A
+:105C9000AF101C5BEFE0EC7979BC8CCFCBE51A9CA4
+:105CA0006304C7D1BB71E5BD3251C6E795951A9C17
+:105CB000E30427B177F8341E95E9D378344C9F3349
+:105CC000B83EAC4FE91D3EA35F93E933FAB5307D92
+:105CD0003E267C327A07A7F135993E8DAF85E9F3F0
+:105CE00015C1E9DFBB718D7E5DA6CFE8D7C3F43166
+:105CF00019104E56EFE03CF5B64C9FA7DE0ED3C709
+:105D00006940FA0CEADDB8F2DF91E993FF4E983E64
+:105D10006984CF90DEC179EA1D993E4FBD13A68FED
+:105D20009BF019D6BB71E5FF45A64FFE5FC2F41983
+:105D3000427046F60E9FA6F764FA34BD17A64F1EB2
+:105D4000C119D33B7CC69E92E933F654983E1308A2
+:105D5000CEB8DEC1693A25D3A7E954983E5388CE20
+:105D600097F66E5C63DF97E933F6FD307DAE22383F
+:105D700005BE7AC287011C476C38CF9C93E9F3CCEF
+:105D8000B9307DE6109CA90027A76738E3DB64FAE9
+:105D90008C6F0BD36701C1B9B277709E6993E9F339
+:105DA0004C5B983E6544E7AB7A37AEF1ED327DC689
+:105DB000B773FA54593C931D68DF2532CF76687269
+:105DC000C9C986034EC89BECCC83605F52423B102E
+:105DD0003EAC956417AA1ECD4EF130B4436738DD52
+:105DE0001EF4FB18357B84B5D07EC1BE2B51F20763
+:105DF0007D6998740BE2EB00AB2DD22E49181B275E
+:105E0000D94389DE2429DFA7B0AF543FA5285B2AF8
+:105E10004F2BB9482ACFF0E549F9CCB2F152FDFE3B
+:105E2000D593A4FC056BA64BF5B302B3A47C4ECD71
+:105E30007552FD41B58BA4F20BEBCAA5F221C155F9
+:105E400052FEE2FAFF23D51FD6B04E2A1FD1B45915
+:105E50002A1F19FA85941F75E801A9FE9896ED523C
+:105E6000F925C71E95CAC7B5EE91F2134E3FA3B3ED
+:105E700003E5FDFFFA02C6EDC10C33D983218799F2
+:105E8000F2E67D36B2FFF7631EF869EE3B83F2E679
+:105E90006717BB93713F8D0060BD2FE85B7621FAD9
+:105EA0007B6E1EEFBBD005DF6F36FB46B8A2F82332
+:105EB0003CAA6F9F81FC452D0A4BC7D46DC034CEE0
+:105EC00028F6EB162E5F1BB3F21F0A44C8694D7FFC
+:105ED000987F903F6C3093FDAAC9F7C6FEA5E90BE9
+:105EE00023FAD9D0DF5CB27D28FFBED88EFD15BD68
+:105EF00088F3ACCADC3118F1D2F763C91E2BF56305
+:105F00001D5046FDBC86FD44F8BD2C03CA74FD58E7
+:105F10004BB68BEFA29F6338AE58FD6CCC1E2F8F13
+:105F2000674039F5F3AEAE9F8D03CA75FDC4F1F13C
+:105F3000C077D1CF7BE71D4FCE44793C17ACA47E10
+:105F40003A7474B35CB052D78F9DFAC1EF8BC99F7E
+:105F50000BBB8034E0B3A5A394E4E03F6D2C00724A
+:105F600061CE2CFF35E6D95B363608FB7143BF5056
+:105F70008FE572FFD1D386241ACF6771C0FF083B2B
+:105F8000B56B3F1BA07DF15281220B0246B0BFAD25
+:105F900014B2B96457F1809BDC90361D187837F63F
+:105FA000B3C5E11904F9B6A6C9E6C551E46969ADFE
+:105FB000E9546BA45F44DBDF4C62B9D5D0FF2E9B64
+:105FC0004BCA6BE94AC5C5843F82F22760DFC260D5
+:105FD0003FF067D8173020D5BB26BE4F7B07F6377A
+:105FE000986F85FD0D9633B696DA9D107EDA13B75D
+:105FF0002B41A4F7673FF9A189F47880BD9A9E8A66
+:106000007E37FEB7604D3CFAF8C3F82D0CF491F2E0
+:10601000A02E330DE9B42FA4FD6FC7D396E076A46C
+:106020006B4D26D054D4CB66EC75D8E4662451363B
+:10603000D33096B1D9D5C553D3681629FD57019EE3
+:10604000B31A479AA0056B33B5DEE8B177C1655E38
+:10605000D309A48F15FE219C6B0A211FD1FFB545E2
+:10606000727E2E53BBF2C0EFC1C66CC137D1AFDB1D
+:106070006B42BE16A5727CE6629A87C5DCDF51E2F0
+:10608000E26D357CAA169B5888F6A7811486FEE837
+:106090004032D5BB4EDB67EAF02B3159BD4540D7C6
+:1060A000928546A2AB1EDF37F7C57B0DC321ADB984
+:1060B000DB84AECD9EF09FE793CB5919EF4FA3AB96
+:1060C000262FA7047F4F20FF217D1FF90F789F14F3
+:1060D000FCEF9263CEFF2A8B6F26F2BFE37E232371
+:1060E0007E09BECF117C5F5A2BF37D0EFAC9A1FE4B
+:1060F0009CD559C1F558BFAE8FC45F18B84C87DA2C
+:10610000BBA6825AED86FFDB420EAEABD9FD3CB298
+:10611000F7FA32DDF8041F6E147C98AFA3C71CC1D8
+:10612000B7F9826FCB58E0B60CF21F054DE8179B0C
+:1061300057A630D417553FD5F8D62AF1CDA7F14D43
+:1061400087EF8D826F37FE84F34D8F77ABE05B6B0B
+:10615000DDC72696DD1D6F3D9E0BD6E8C615D0F334
+:10616000AD569C3BB8CC68EF147B0BFA9C8CA87F97
+:106170004DE1957D4E46E8856B8B8AA5FCDC9279D6
+:1061800052FD79BE8552F9F565CBA5F2F9D53F945C
+:10619000F20BD6FC44AABF30B0562A5F5CB3492A42
+:1061A0005F5A7B97945F5677BF547F79709B54BE3C
+:1061B000A2FE11A9BCA261B794AF6A7A5AAA6FD89D
+:1061C00037E46A94AF978E1A19FACB3EF5BC4FFEAE
+:1061D000BA4F3D260FD6A944991B87F2EC26793E8B
+:1061E000E5CFA5F4B4DF43F27EC63F96D2B6A60350
+:1061F00076F43F56C581DE4F043BDCF8E6DA9A7E42
+:10620000B8DE40FBF18C351B5BD706207F000FA367
+:1062100060DECCA833B3D02806D2DD372CCF1DC624
+:1062200088F2D61ECAEB5416EAD3BD7C466BF4EF57
+:10623000ED4AC7E00CF413BE61613B23FC75DDCF72
+:106240002B5826DA15B1CACF1A5859E479D6492302
+:106250003F27711A279D3442BAD2CCE7FFCA3D19B5
+:10626000939813F3A1C1D551FC2EE1FE1A00993485
+:10627000E4738E34EF97D55DDC35CF19F6934D720C
+:10628000BB3C384AFABEA27E82D42E57F1BD6B8445
+:106290007A67F71B69BD66A10303AE1986F8794FCB
+:1062A000E277D6944276578BDFDBE7E440C6FEE820
+:1062B0002FA4F4557F11A5AFF94B283DE6F751FA0D
+:1062C000A6BF8CD23FFBAB297DC7BF86D2567F804D
+:1062D000D213FE1A4A4FFA6B293DE5AFA3F4B43F3F
+:1062E00048E9197F3DA567FD0D94B6F99B28D5F4C3
+:1062F000674FF2775AACAF6750FEA2C899F956B60D
+:10630000AE6662979CC5A9967528671A7D67D459B1
+:10631000843CA44AF29088EB30C9590FE5752621D8
+:1063200087B1DA472F4779EBFB3DC81B63EB480E7B
+:10633000660AB9FBAEF2C6D01B9F82F294A99327DE
+:10634000590E3539D2F440AE52345C1DD325573343
+:106350008DDC4ED2E4EAE7682746B1B76E5015B13E
+:10636000FE71FB88F9320C68BFAD127E7FE64EA746
+:106370007CA7E87B3D806BC17A6A3017D791CEDC71
+:10638000BF0D46FF78E7310B433F7CACF1E9E525D3
+:1063900036DDBDB47F280DC2A236AA7BB92D8ED3BF
+:1063A000D56660852C0FCF67F38FF9809F71FF79D9
+:1063B000711EEE6BE1BBCAC8AE0A7A8AA3F8DB197C
+:1063C000CA785ACFF4D5EA9F7AE0CB7C3C379F2934
+:1063D000E679DC01233FD70E3DE4B926E27C06F6E0
+:1063E000DBE9E877EE18647691FD10EA2BD331D81B
+:1063F00057A2E381419F0DC6F38D4D208738BF3AE8
+:10640000070E4E60E7918F9EF47C4FF45C14ECDB3A
+:106410004B7A9A199E1B013DB7E3FD97DED2B32755
+:106420003DD9937E3CB199D3D929ECD358746E9F52
+:1064300004F32E8A1CDFA3AAB21CB381FCBC43A3C5
+:106440003FEE4B23E87FA9DD4DF59FDBF7D6805665
+:10645000E8A7B3F1C204C6CF73C8AEEB7852D8ED4B
+:10646000EE4C998FAD7D09AE06E7B9275F1F80FB23
+:10647000E4DB3003F3ECC9F8A25FA9295DF07A7B75
+:106480000E1F6B5CBBBFE5FC6C4FD5E667CB009481
+:10649000A7CF841E8839BE9EE414C70770AE52F899
+:1064A000F836188B7E877A263CBED129BD1A5F55F7
+:1064B00082992923003F87D9CC1218DBA1FA0EAAB2
+:1064C000B48FF3B406D04FB12FDEB31E5852E53C63
+:1064D000F372C88DED647FC68A7A9B4BB69F125DBE
+:1064E000B2FD94E18AB49F3A0F3DE4F4017EABD251
+:1064F0000DAE93A3709DF38A758EAFAB1A7E150D0A
+:10650000592EBB0447CE77D62A850D244FEE84D969
+:1065100051CECBB47455BAD97512D6AB33F539090F
+:10652000D8EF19BFD5C5D757978BF79BEE8A5C5F1D
+:1065300057AE89A3FA1A7EB1E0FEB3F163AC91BD08
+:106540006BC57511CA7262D78FC94FF513339D4B56
+:10655000379B3E43FBDD96ABD9EF2AE535B8550DA9
+:10656000C68065047EDF25F507EDDCDA1933B68BCE
+:106570002D372A3BA5F113F86FC58377DAB75A890F
+:10658000CF3E809800F0DA557B0DCAD50995CFE74C
+:106590002A21A715D656B3CF4DE46E41795E3496C5
+:1065A000691366EE5BA0A73F78D144F7B4D85700D3
+:1065B0003DBFEBAAC01256E444A7E7A2C61533704C
+:1065C000DDFEC0A0ED876BF371DCE798A110F5D27A
+:1065D00039F647E7A888F93AC4C4FD31AC86EF73B1
+:1065E00002F00FC7B7B456DEF72CAB93F3A56C5689
+:1065F0002AEADBD22D261604DC97E3BE491B37E8D6
+:10660000DF0C13F76B2C63D51B709F7EAF89FB7B70
+:1066100016B9989A097855FCC72FF3D1EFE3317179
+:10662000BB433B4F5E9EC4F12E9F1D347BA1FEBB3E
+:106630008DA3E680C685F6C10D64FF1433CF4ED618
+:106640009DEE8B6B64FC7AC25F8FAF6607753BD79C
+:10665000167824D72BDE60143D77994911FB3F3E15
+:106660003F669B647FCE3C93ECF7D1E4C024E4E02A
+:1066700084EABBDA3486F31DF9A8A81D665F443DA1
+:106680007357BDD9E7AB67C17A46AA37CF9482F575
+:106690003AA6D1FE98813C0DEDAA67EB827723875D
+:1066A00027D7ABF88FC79E0A80BC94FFF61E2783BE
+:1066B00075F303B536D503DF57EEBCCDE985F4B4E9
+:1066C0001A70223F3F081A0BA3D1634B981E5EBB82
+:1066D00082FE34219FAC26407E8ACF769A5CE4E726
+:1066E000AFB7842C20A7958DCB67B0E1943FCEF354
+:1066F0001B3F3262BE49E657F9AFEF4975F37B366F
+:10670000DC9FC44264E756EE786F1AAE1755AC832F
+:10671000E44CDF0EFBFF3C89E6F5427342F772C0A2
+:1067200093FC095562965535FEFC23A313F3B27C06
+:1067300094097B15E984FBFCDB4C8EE453F190BD9E
+:10674000845D82F35CA3070B72BB75FD23F70D3FDD
+:106750000EF89CDDF1A253191AA91FB89C75362CAE
+:10676000FE95D5105B8FB4811C46DA470098DAB9E4
+:106770009B84BDDDCCD395A69013EFB3ACDC66F261
+:106780008004B2958F1919DE03606F5882E8175D97
+:10679000F1D8F3AF8D07BAAFD86D4A9EC187635762
+:1067A00052BBF85205FF5B93D7C587F2279E37BBD4
+:1067B00087F1EFB72475F163C5EEFD6636AC3BFD9E
+:1067C0002637EC37B7DAA3F0A5E1F8345C67D73F9A
+:1067D000F25733FA133FD8A7B0B4ACEEEDCBB63DC9
+:1067E0004FEB1DD289F828F814E65B377E85663EAC
+:1067F000339AEAB9500FC6E2D732A177419E1F7F84
+:1068000006EFFFBC69F1E0F8CB1EBFC989E3785FF2
+:10681000ADE672FDCBDB52717E979902A92E4AF943
+:10682000F7B2077F44F2B6ECC88F52C95E60DE0C47
+:1068300003E9E240068E6FE9D66B697CA5CC47720E
+:1068400057F64B6311DE47FC546585BBA3CC8B38F0
+:10685000B342F8BCBF1D0C1918DFFBB8BF447DF66E
+:106860004723DD8B62EC87746FEC4762ACB0F2516A
+:10687000FE532BE7D371A12771224BF2BA63630B4E
+:10688000F2E74C7F6F1A9E73001D02825ECA3700CA
+:10689000D778646A1AE70F73ABF9A21DE8F7C9F855
+:1068A0001DEBB798BCB6E1523BA10F79FFAB45FF9A
+:1068B00080771CAE57EFA746B7F7C688F1C15F0BCC
+:1068C0008B90AF88F9CDE7FB8E4D7C7E6BF33D5806
+:1068D0005C88E59FBCCAE70FB6C3F501F00AA55175
+:1068E000F9FED90AE903D857479BD73B4C625ECBE8
+:1068F000E56029D27A0F78AB4A42A49C00FC24A21E
+:106900003FED834BB740BB08FBAB0AFBA37AE6AE77
+:10691000EF11EBC332A1074C6698FF1777CD7FB616
+:1069200095CFFB9EECC995A6E0C30FE07C7DC3E24A
+:1069300009B871BE9A8A70DC1FEE3AF0DA7520D77A
+:106940001F3668F354D69FFA795AB6670C8B364FC8
+:106950003FB4C3FE2ADA3C85EF51E7A9BD95E4F8C0
+:10696000FBD69F1ADD869A65BD897AF019776CFA95
+:10697000E9F5E0EF4D6EA2A35E0FC2DFAB2CBFBB0B
+:10698000DC69F2A6C959F96F2A2E407D1396474D4E
+:10699000DEC2F2A8C99B7E9C32DDF4E57F15FAE6E3
+:1069A0007A6BE13568175B3B18ED570A661B83B8B5
+:1069B0004FB67EC268BE4FBA219EF2738DAD4FA016
+:1069C000CDF756C5DC61B88E5FCF02267E6E5E6B5A
+:1069D000223BF5AB6FBE9908E3B94ED0F57A20F3B0
+:1069E00055C087125509C5019EF354164848427F89
+:1069F000B1C24E44E0717D999CC7BFCB52BBE0F45D
+:106A000054FFDBDAD5DF353DE2E767577FC294F606
+:106A100017603847C85171333FA7A81AAD04B3694E
+:106A2000FEB5AA4511FB84C7CCDCCE3832E59A31DD
+:106A300048BF82B9C31248BE6B87D03EB04AE8ADAA
+:106A4000CE803B01F57967730EEDFB3A0F2D76F89A
+:106A5000A2E8AF0342CE9E17E72CED76A5D608F24A
+:106A6000DECE3AC86E09D86D51FD6E756683B0777B
+:106A700004DFE0CF08FD9708399C074D13F222F898
+:106A800036FBAA0F5467773EE0DF89887DC33F4A13
+:106A90005F946BA4EF015BEBB4A228FE994785BE1F
+:106AA000BEECD92FCCB8CE4D692E50918E53EC460A
+:106AB000C9DFB15D9BAF43D950C4EBB26797DF31FB
+:106AC00006E4B8EA90D16383F155357F64F645D981
+:106AD000BFE9E989F0D17E6C3573FBF8A8A9682974
+:106AE000D2F5E8B5FC3CF74F664F45343C675B395F
+:106AF0009EF358D1A7A3957F3DFA16CC7584260145
+:106B00003D3AEDFC7E7277F9E3F3BED3A504D72AB4
+:106B10002887469E4FE6F77FA731DF1D13159AEFB2
+:106B20009747EAAF82A6E2C7F03E4B65B3E2324038
+:106B300079A5DA6A4639AE6ADAADA25DFE03377F1F
+:106B400067C1D4EA61B323FC5BAD66EE4F3AF0B7A0
+:106B5000EBE6237D3F9E6D61889777E8474E5CEFBB
+:106B60003F6E1E45F320D6B8FEE0F75C3305FDF11D
+:106B700066AECFF4F2302D395ECA5F3B99F5C37330
+:106B8000DECB2CAD3779A2F06F9D85CFD35EEB378E
+:106B9000EBFF30FD3611F41B976B53A47E9B6EE127
+:106BA000721FA1DFD2A2E9B7556BDD692817ABF6DA
+:106BB000E6A4215F571D5E9A124DBFBD20F6B58732
+:106BC000C53DE9F67EA0DF4644E8B77EA0DFA2F827
+:106BD000C1475B34BBB307FD66FDEF997F2FA07EF5
+:106BE0008B32DE2B84DC69FAADB0792DE9B7C27E39
+:106BF00046E93ED2651661C7C5D46F0BEFB996F270
+:106C0000264F7C14F941BAA27E3B2CF41CF6837A01
+:106C1000EE67966FA7E7E65939BE3DEAB9FF263A17
+:106C20006B7A6E557F85EC97EE72C8F5DCAA2CAEB8
+:106C3000E756EDE57A6ED520AEE7F4FA6D5237FDF2
+:106C4000C6DB57E6427BDA2766DD7703DEE72B31CA
+:106C500079AC507F865B7B5F503D2652DFFDCC12C6
+:106C600043DF7940DFD97BD677AFA0BE53498F0D84
+:106C7000C479A4978FE903E3A5FB6A47BF38F59B66
+:106C8000DFE27CF98391EE03BD6EE0FBA17D5F9CAA
+:106C90001A85F3EE65C407E6CB4E217F6DFEB1A4E5
+:106CA0004F270FE5F3BDE2501CAD13958D0A1FEF82
+:106CB0002D4AD08DEBC0DF3EA77DF2FCBD7C9F3C12
+:106CC000D7C2E9C17E6CE4EF2280040B23E4A1E487
+:106CD000F372F2F395A8CC8AF6EB8243D33F40BB24
+:106CE00075C1E73564EF2EC0EF78BF6277EB864C55
+:106CF000E877FE7285F61B4CDC87D0EE4B5CDFBC80
+:106D00009FEEAFE8EF4168FA7C7EB5FC7D81CEAEA8
+:106D10003F20C609F62CD185BD628CEA9F3BA0A717
+:106D200087878FBF6235B78FC3F400FAB895EEF44A
+:106D3000008ECE5898DA35FEF94FC2B892BBC6A580
+:106D4000D1433F3E6D7FB240CC8D58E3D5E8D76D3F
+:106D5000BC1A3D75E37EDE22ECA28BD9309C67AF76
+:106D60001B7C778C41B9F83D8C1FF099336F505ADA
+:106D7000A41E7E51E8F3AB7CC7A7A4BA915EFCFDCC
+:106D8000DD7565BB9F4F85715CEDCDCAC3AB08D780
+:106D9000FECDEC433FC2015B07E9354DAE2EB47228
+:106DA00039FFBB8073B4AF6B0AAD1F4D8A8BE64BC6
+:106DB00048A7B7C4BDB02AA027CEC7AA26B1DE8097
+:106DC000BCE17C9BA6AD3F487FF8CFAB9A39FDABC9
+:106DD000AA15A2FF4CD67110E95B99AC7842006A03
+:106DE0005AD3EEDBF01ED50B36F88EF3B64CF16CB1
+:106DF000E7E4B067A446954B359A5CB2EA21E457C4
+:106E0000D0D6C105582F09DF8BBC9E82F689DEDE05
+:106E1000B8CCD27214F1B8ECC726B68D75B73F3432
+:106E20007EE7C2BF6FA2DDE7E9417E0709FBF205FD
+:106E3000A4B71DE9DA6146B9AF0AF175432BAF5229
+:106E4000DD53883E1ABD9B605D18CDE98DEFBEF421
+:106E5000F4BC5ACBA33C63FD66C584EDAF043EF49D
+:106E600081A2C9862F0E6AF28BEFC4F474C1FD7F34
+:106E700046C47C47BD1479EE58D97484E8327D3518
+:106E800098551174477D753EFA749B0F4DFBA3DE38
+:106E900083FAB6F3E142AB3C1FF6D93A5E1C81FEA1
+:106EA000ADBD0AE903D69C28EDEFAFB0F27DD3016A
+:106EB0009B8FE4B6E3B089EE7BEBF5C658417FDCEF
+:106EC0004F44BE839B8C03C1F35D978DBDABE191B5
+:106ED000CDE527525FBF60F3119F62C19F26E0C7D7
+:106EE000B297C2F8627F789EE296FBD3AF179A9F63
+:106EF000A7A7715D23D6FBEF3AAEF0F9246B3133CF
+:106F0000EECFDF6D8E38679A23FCFC9A1F2CA2DE31
+:106F10004CCB98D8F5D0DF128271BFB0EB21F2EBE9
+:106F20009E7BF4F84C94DB15BF33322BF0B96D9790
+:106F30008385F83D0A33AEABE58DC6A8E7228CAD5C
+:106F400027FC56FCD6417AA57C8F253803DA973F7B
+:106F5000F5EE70F44FB5ADE3FA25F0A8908F40EB55
+:106F6000703C2F2F57F979B11EDE8F85BC9C7D3A7E
+:106F7000BE04F5A352CFDF759637CC355922F6E51E
+:106F80009578E0C6EBD13DE4C0230AF9C1BBE3B775
+:106F900096D77B84EBBDF2265310DF8796D76FA37D
+:106FA000FD6C55FD4766B4E326FFF631B223AA9A7D
+:106FB0008CB29FB0DE18B2901FD3781C53BDBFAE09
+:106FC000B2B182E6636583F087E9FC452B7EBBF7AF
+:106FD000A9009066C513BF76A29E39D3B2D3497E6D
+:106FE000B87AEE6753ED6A743F5C4FFEB7864D5139
+:106FF000FD6F67F03F60FE6DB5CAFE3756DFA757DD
+:10700000E7E02B1EFBF4413C173ABBE7C30711EF47
+:10701000955F7FFCE04FD13ED96773E17A57F5E881
+:1070200051F2AB6BED9E12F3AAED915F3FFC00CCE9
+:10703000BFB6372C74FFAA6DEFFB03DC30CEB6DD94
+:107040005FA4A2FF72F5DEA9B46F59FDE4E4B4F3C6
+:10705000DD2341B90CF6E23C44CF87038D4686EF31
+:1070600020CF1DB3909D11F6A3365470BFB45BF8CA
+:107070004F77453F77D2FC7E958DD75C7D29AE7BDF
+:107080008D268F9BBE0B3F604F7ED357819F237A07
+:10709000C1B75DC22FAEE3DB39FC0FE0CF9FACB2CE
+:1070A000BFF9D3C6A5BF7A00CB1AFBC4F49B867A7E
+:1070B000412FED5C6B9BD5FB8E15E7C39EDF907F68
+:1070C0001AF90536376B7BECD301E86F386DEAB8F7
+:1070D00091EE5FECB5D03DA1F2BDAFD3FC687BF281
+:1070E000089D173171AED4C6C27FFC1C40EC65AA66
+:1070F0007638B8BF55D01DFDB16E277D177E572E4F
+:10710000B79A3F36961FB68F4DDC0317E76C153BD9
+:10711000DE32339D5F5B198B7C3A2E9D0B6AE3D682
+:10712000C373211D2E893C4F88E5E7167A34CC279E
+:107130007E8ED0B64D9C2F84CF0D18EB9787F7DF4E
+:10714000F979775550799D45998FDA7982D3A69B45
+:107150008FC1DE9D23F48CEF77A38762E3FB568D0E
+:107160002E67BF8AAE8F87D814F1FEC0976B8B58FD
+:10717000771688F5A412E8C5DF93717CCF8AFDDD10
+:10718000D9478D41DC076F6838407A553FAF2B599E
+:10719000F4F821E36D5C9F5436ED1F8EFAE7ECB3F3
+:1071A0004F93DC55EE3A6E0E009C83F54F985B874B
+:1071B00076C939EAEB6084BE3EFBF8FEE1FC9C83B5
+:1071C000EF23F5F0AF10F0AB9A65F855BB3E92E0B7
+:1071D000AF0834985DF69EFB39A37AE7E278CFB426
+:1071E00098282ECA99066361B47825433190544A91
+:1071F000179D3638F8FB38639299ECC8D58EB1C725
+:1072000012923135BB711FBD7E2DBF0FB9FE679E37
+:1072100074E4CBFAC439740E54ABA3A32BD95580B4
+:10722000FB6BD794A2D128567A3D90E8354878AFC9
+:107230007614A6E17BEE5B853DC2540FBDDF333A89
+:10724000A715E2388C2E83CB16751DE5F04CF6227F
+:107250008A176172C9EFE9BEF7F80FEE7E72FC87FC
+:1072600040BF7F34FE03A33818FFEFE33F04B09F15
+:107270007F81F80F21F2DB68F11F92BFE7F80F6BF7
+:10728000991CFF41F0331CFF41F0F37FE33FFCFF0B
+:1072900015FFC118F7F729189F418BFF9012679EC1
+:1072A0001A19FFE1C2B884A991F11FC6C5A54F8D77
+:1072B0008CFFF083B8ACA991F11FE6C75D3435327D
+:1072C000FE4355DCA8A991F11FD6C64DA4BC16FFFC
+:1072D000E1EEB8A953E5F80F33A74E817C5B9CEF34
+:1072E000EFB85EC58AFFF01E4E96313DC77F00386D
+:1072F000E6B831B1E33FE8E1C48AFF007012084EFE
+:107300008CF80FDDF08911FF01E0A4139C18F11F28
+:10731000BAE11323FE03C0C9223831E23FE8E1C4D9
+:107320008AFF00702E8A4B891DFF410F2756FC07EC
+:1073300080338AF08911FFA11B3E31E23F009C8916
+:10734000042746FC876EF8C488FF0070A6D2B86296
+:10735000C47FD0C38915FF01E0CC247C62C47FD0F8
+:10736000C38915FF01E0CC257C62C47FE8864F8C81
+:10737000F80F00C747F8C488FFD00D9F18F11F0011
+:10738000CE72821323FE831E4EACF80F006715C128
+:107390008911FF410F2756FC0780F353821323FE08
+:1073A00043377C62C47F0038B7129C18F11FBAE1E2
+:1073B0001323FE03C0B983E0C488FFA087132BFE0C
+:1073C00003C0B997E0C488FFA087132BFE03C0F960
+:1073D00015C18911FFA11B3E31E23F009C7A92C387
+:1073E00018F11FBAE1F35DE33FD84203951C8AFF11
+:1073F000407122C3F11F92BF75FC8766C4F77FE31B
+:107400003FFCCF8CFF70B3DDF7751CF941BF5BFC0F
+:10741000075BFCB78BFF70B3BD283E1EF797DF32CA
+:10742000FE436AFCB78BFF00FDA4C78F89DD4FAC1C
+:10743000F80F39BA7E7A8AFF00FD0C3AEF7862C401
+:107440007FF0E8E8F67DC57FF822EEFCF11FFEE54F
+:10745000E22CC03605CF7F8A4914D9BF4CDC856B3E
+:10746000E3FFC97117C858F8578ABBA0BDDF6F305A
+:10747000E17AF5A6E0FB6B422EDE12F1178EC58C89
+:10748000BF10BC8AFCA2CBE5F80BD3051FE7F9645B
+:107490007998CEF879C3F429593C5E66992EFE425C
+:1074A000AE7C7E3DC377640A80635779E4711C111A
+:1074B000F230B3E4A3E7903D578F8D1E7F6196E0D5
+:1074C00047B18E2ED305DF8A457A3D3E4901799E2C
+:1074D00051764445BACE74B7AAE4D7FE81C63FB709
+:1074E000C4BFD902AE1EDF59827FB3AEE4FCD3E342
+:1074F000FD2AF2CF0969D928E29F1E6F3D9E7AFED0
+:10750000B3487E47C4CD286072DC85C95639EEC2C7
+:1075100054971C77E18A7439EEC2956E39EEC20F2A
+:1075200072E5B80B5779E4B80B578F95E32E147BAF
+:10753000D7EAE23E6CD2C57DB84B17F7E17E5DDC41
+:10754000876DBAB80F8FE8E23EECD6C57D785A1742
+:10755000F761BF945F5C7358AABFB4F688945F5616
+:10756000F786547F79F0B854BEA2FE03A9BCA2E10D
+:1075700023295FD5F48554BFB7711F5E15EF815F76
+:1075800013EF818F89F7C06FC688FBF0D79F7F719B
+:107590005BE47BFC2F7FFECD6DF81EDF20DEC1C6D5
+:1075A0008AFB102E8F11F7A1ABFDB78FFB9092FCD9
+:1075B000CF7F879F63E7E79B13E227E5D853BEFBA6
+:1075C0003BFC6B8BE4F7CC734BE4F7CC3976AECF56
+:1075D000E7F9E477CDD797C9EF9ACB6CBE6CC4437B
+:1075E0001FF76142BC37C78EFA52BCCF0FE1FB5484
+:1075F000581B9FC5F7A9903E87711F203D88711FBA
+:10760000203D84711F20FD3DC67D80F4258CFB004C
+:10761000E9CB18F741C5B811011137A246C48DA8AE
+:10762000157123EA44DC88A0881B512FE246348878
+:10763000B8114D226E4488E09CF01FA2F4A4BF85CF
+:10764000D253FE63949EF6B7527AC67F9AD2B3FEA7
+:107650000E4ADBFC9F53DADBB8119A5CFE19ED068B
+:1076600033F6CFE55893D319F6811B22E5B4C87ED3
+:10767000D10694D358F122E6224D5362C78B089766
+:10768000C78817D1D53E76BC88B4D1DF5FBC887F70
+:107690008BE7F2FA8FC68B985F2DC73358B0E6FCA4
+:1076A000F122CA6C45AB512E3579FCB7787E5ED598
+:1076B00053BC886D7645ACD74017B4BB802EB45E02
+:1076C000F7F0DEFE39C7C3B9B89FE8CCBDE8BC719E
+:1076D0000EF472119BDE3CAEC175DF739C889EE890
+:1076E000AAD57FB39CC72FF8B7F8F3C72FE81627A2
+:1076F000A2A7F802833E233DD9DB38113DAD0B3DF7
+:10770000D173D6F71C27A227BDDA933EFDE3744E52
+:10771000E709F1E78FC7118E0B676D39488D5D5E04
+:107720009ADAAA78075E30DB45FE93F65DE2DE98D2
+:1077300097B95DA9FC9D3ADA9BED7B1286337ABF3F
+:10774000EE625EE04FBCF8AEECDABF1FCFD36F75D0
+:10775000326F6212C583771B73701F36D28AFE9414
+:107760008AC68F5EFE1DC0B5351BE93E593BE0D091
+:1077700042769F3711F916CF6EA77D3A9E717DD361
+:1077800027F23DB3EEF71BB04AC4F9CD54A39DF6E2
+:107790004D9D5BF93D4F23BBE8BE89C9749F9A0597
+:1077A000DDC43FB25357083C3B31C5FA3E2BD98F5D
+:1077B000CB0E3F911F62FCBC32D26FD0A750F6D3E4
+:1077C000D4D99CC3F15D250B785BD0FE5E22E0A589
+:1077D00014C9FE9B0F17151EC273FA25BE52BA8735
+:1077E000905622FB739878378EDBB1F07D39C0A7B5
+:1077F000B449610F28DDDF919735DFB501F739CB4B
+:10780000837AFB9BE5A29C95B3380FEE7B57D4CBD4
+:10781000E50E87B8CF6167F65ED1AD75F07D134791
+:107820009F976E9E10D6DFE5A0FBB0CB0E2F3623C0
+:10783000B32CE932DD6C6E996EF1B9327DF4F473DC
+:107840007864FAE8E9973056F67F69F4D3EE1BAA1C
+:107850004CDC170DF27BA4DDDEE1376D233CF5F443
+:10786000D3D36B9443DC93E8A257913595543EE112
+:1078700099A18648BEF5F321D31E52F0BFFB27071E
+:10788000D7522B8F4345BD95CE413365096F178F76
+:10789000F301E3CA320FCD07DCD1A37F379EFD5938
+:1078A000C8FDBBEC1B486F2A7EEEF82228DD8AF269
+:1078B0003682FFFE02F9ABB4DF4D601E17EEA31A4D
+:1078C000FC56F71215CF05997BC9403C0F74517ACD
+:1078D000A778F7DB3E94D1BEBF21F4492A9EA3DDF1
+:1078E00099D73113FD0F554B5911AE5F3F72F277A7
+:1078F000179B443AC2C9FD339B8B0CCC3B1A7F8744
+:10790000C71854D0EFEAF21EBE1CEDD166939BDE81
+:1079100011BB3A5EBE9ECA47D1FBE80C43ED48C49A
+:1079200007EAD3FBDAF6E6779D8B23F4705BD3DDB1
+:1079300043F07EF1FD86E8EF7A4B1DDAFB367EBF21
+:107940006344579C8152C7188A47706736F453596D
+:10795000DC497CD4E47282A0FF73A5D309BF279BC6
+:107960001537FAEBA6196FF8C130C06FDC5195EBF3
+:107970002F71AF7BB4A8FF34F3A423BEE32E650AB6
+:10798000CE9F716F304F00495C5D4AF7E97EE79CFE
+:107990007608F935A519E409F5C859BB07AFCA8FB0
+:1079A0006991EFCB254EF11DC0FB85971C63A4CFD9
+:1079B0002E39A6EAEFC71871BF3FAE55FE3E41B75C
+:1079C000FF5CA7C99D93A5A2DC6DF9CA4878B5777D
+:1079D00030CF3A80DBBEA42F9DDBB67FC2C84E6C91
+:1079E000FFCA5818ED7EC9DD0EEEF7BADFCC487F2E
+:1079F000DF5F6AA7770ECF96965F80F6C5673FF187
+:107A00005D10CD4F1961A725F0F7E7DE043616E5C6
+:107A1000F05685D3BB36A328CABAA5C99D26879A36
+:107A2000FC6594C6F9A2DDD74C7672FB685269AE4C
+:107A30006246F9D9A730A46BDB3AC0EB3CEB768009
+:107A4000ADCB447CAA9A3EA67B58D66625EAEFF2D7
+:107A50003CE170F2FB80EB026BF1FEC5CD3089504A
+:107A60004F65986BB3A2C10FB02D64973EE070F3E1
+:107A7000770356114748ADCDC0FB086D4D93AFDC81
+:107A800000783E00F301F97BBFC94378072A18A3A9
+:107A9000FBA4C25FD76F26DBB639C2FEDDEB283808
+:107AA0008C727BD8C1EDC63E3E8F82787BFEFE573E
+:107AB00027C26FFFDC42FCEB2BEC4DADDD4907A785
+:107AC0004F89D37B00DBB3B264523E1E9FD3BDA46B
+:107AD0000FFACD81DE51EC2B6D5D4FF2313A9F48AC
+:107AE000B21B82A49CBC5EB74BBAEF1DA079A3CD9C
+:107AF00003165218BED7D7F49BD2AC841C20F7A330
+:107B0000ADF610DE3F4B2A837127633C0F2B87D7DE
+:107B1000A29E95FD5A208FF968DC337AEF8F8E5440
+:107B200084AFE93D4D5FDE9AC8F5D1AD77A9140F5A
+:107B300074ABDA6A437F6A96D73D0943D324A96EB2
+:107B4000BA97D2BF8CCFC3F89C5F2686ED0098E42D
+:107B500023BF362E88F69E2903E52905E9E5FBD0EB
+:107B600001E9F0431DCFA2B9E0B1B13EFCFE94D0D3
+:107B700013C2AE9926D6BB71EF19F83BCAD0E52CDB
+:107B8000F27D915E4F80DCFF097FBFE7FEF7548AEC
+:107B9000131AD60FA5D3687D62C6A10750CE26BCA6
+:107BA000C8F87194D00F2EF887F4B9E425DF7A4431
+:107BB000E3BBEA053DBF59C81ACEE34FB38D3A0483
+:107BC000F32D729D758AF55EE8919B8A07AEC7F921
+:107BD000A5C9D105B7788CBE083AEADB87FD948A3F
+:107BE00035FCDD9D837AE42523DE0F6B2F007E03B9
+:107BF0005D9EC4F902F44EFC247825F27D4BF3150A
+:107C00003694EF5B43935C33A04DA2B5889897C838
+:107C1000BCE4CFC903EA609C88F52414B05F578B9D
+:107C2000B29C29788FAB50F2F768BF8B070325BE53
+:107C300084F900721C798F55934FBD3C6AF2BB1ECC
+:107C40003758787E871E73488D4A0331C8C2B6BA4A
+:107C500050CF6AF6E5FAB03D9748FB8CD5C22E5A54
+:107C60006F9F662535B03F99D6F3D5B83EC1F8571A
+:107C7000A7309A07DA38F4F258F5B9810523F607E8
+:107C8000556A07DDE3ABFADCCC827D70DCBE493897
+:107C90006E8D2E23055DF474C8768AFDA6A0476C10
+:107CA0003CF35D787F36D1EA651B09CF4974CFB9C3
+:107CB000219467C5F5F6361D9EBDC06F4E34FC5449
+:107CC0007B0CFC44FCB609CCF7BB5690D7FC9BEA76
+:107CD00032F87AC15E4D8FE09F7EDE8C6DAA3E60E9
+:107CE0008E982F9A5F573F4F4634B36B90EEE34226
+:107CF0002AC3F3D79EE6CB2762BC55F19C5EED7399
+:107D00003A06A37CEE507DD54EB22F5A0D18F7B728
+:107D1000FD6946F3D9B3FFA493E21BB5F4EE7EBA36
+:107D2000664769F693BE9E663F697A57BB1FBEDD04
+:107D3000E9F363FF4A13C8278C7FBD8BEF8BF63ABC
+:107D40007CEBF07B3C8C018F92586E288BBF7F952B
+:107D5000E53F96BCC7EBE4B901E844BF9305FA7F61
+:107D600090D21D0FADFF29CE447EDE02B319F5502F
+:107D7000BF7CC63BAB64747FB2DF70E6C3F5A95F1E
+:107D80001EBFF71714EBF636A16FB574AFA3E87EEC
+:107D9000C4DFA4B28025EFBBE38DA8E27DECED4EFD
+:107DA000EF7D287FD6422F8D23D3C53C687F66AAFE
+:107DB0000D0ABE9B4C5AE956F83D6CD6F58E09E08B
+:107DC00065CE7017A09C64E23E1AEB37478FA3F58F
+:107DD00084D324D9991E168E53F504F60B76E6410A
+:107DE00033E0DD678616F74A3BB7F12848A736C768
+:107DF0001C42BAED5385DBE3899C5EFAFD00121E3E
+:107E0000F15345FE3633536D49ACEB77380D56B21E
+:107E1000E3E399A701F5D2CBCE6C712EEAA9C1FCA0
+:107E2000BFAB1DD6C4A15D727CE7C4591E15AA382C
+:107E30002FED1C8E7B2690E7C3886FDBC4CEC1B7C5
+:107E400012313A0670B9F11AA5B8381AFD9B4C12D6
+:107E5000FD6DB8CF8ED4830E33ED23DB94380FCE77
+:107E6000B3B6E50AC753B18AB841AABCFF17FA48AE
+:107E7000D3AF9DCE2CC23F9E05681FC0AC1E2BDD2C
+:107E80006317F8635C45F2EBEC8D0F6EC7F3285D6A
+:107E90001C457D9CC5C98BED74EF62CB5E1BED4B21
+:107EA0003B8BF8F97C67B385F46FAC799A86CAE0AE
+:107EB0003CF102816E1D48B734537522EABDB4F916
+:107EC0007CFEEBE9D18E03C5FDCE1F4CC168EFD51A
+:107ED000B5343DBD6F31DA65E919E9946ADFEBEC41
+:107EE0006AD47BD8C604458AD337047A14FB1C6352
+:107EF000027C3FE7FBE36B5ED675AFBD2E8ED3AF42
+:107F0000D3373EE161942B1038FA3D01ED5C53EC20
+:107F1000E7B5F8495A3F5BFCD6620CF959B768BA25
+:107F20000DD78114E6BD721E4ECA2D26B693DAE532
+:107F30004AF75DEFF58F2CC6F7C99909FC1EED27AE
+:107F40005BA6D27BE654B6CE3618E8505A64F0A051
+:107F50003FE0DCA2379D06909F45992DF928A7099F
+:107F6000265F66C218725DD17E6359893918027A1C
+:107F700025D78142203A06AE243A2E3444F50F67C5
+:107F800027F07DE75B623D494F1F50BC645464BEDF
+:107F90001FD1559323983F194B4677C5C3047E5E86
+:107FA0009410651EB49B5813BE97D0F451B2103391
+:107FB0004D1F6A729C8CF303EDB822D04FD2791F0B
+:107FC000544DEDFA3D43A5F9852FD08E755E3A8963
+:107FD000F40DCCDB1A92F35CAE3F6DA8CF22FC56B9
+:107FE000ED7B5FEF8FEF98DEFED9C70E7CD7F217DF
+:107FF000B5C381FAEBF42D7F72601CB0B76FE1FB63
+:10800000E41B75F6FF55423E8209455390AE0BFCCA
+:108010007FCF8FB4D7D81AEE7F5E1E94DFAFE2FD1C
+:10802000EF483F604583FE3E4080C72913BFCFA97C
+:10803000E7C33AC187E5BBB69933DDD8BF6F0EF60B
+:108040007F5AEC6F4E373AE83D8586CFA25D23CD4F
+:1080500068F3FFA5D922DEE9B598B85EF6CEC0F781
+:10806000393E41373D9E07F7C513BCA5F7F0F7AB86
+:108070000BA1AF35A0177DCD3C8E927E1C4BDF76D9
+:108080004F433FFAD24D0AEDE3B0FE2DB04EF8D685
+:108090006CA4773CFA712E0CC8FE1C7DBC466D3F6B
+:1080A000B04CF07F09FE1A6F4E94388ECDFC3DDD4A
+:1080B000329D7DD17928271EC7BF2641D8D9F9EC3A
+:1080C000128CDBB9E7507642B478185A7A569CF78E
+:1080D000E3BD7E4C4FFB19A55312DC3C5E57F39178
+:1080E0009B51AE2A9B76537CC47DC1F7FA8C872ABC
+:1080F00005CD5F1851A80A843D365FD8637B189779
+:108100001BB0A337A3FC5FFEB9CE8E16E3BC419330
+:10811000FB4349243737E0B886E377F59368E3BA41
+:108120003B417EFFD5DB7169E3D1C6A7955788F740
+:10813000E7FA769A9C4F1172B76447F186BE408A7F
+:10814000F57BDF1F20E2C8519C2D4D8EF472B24C9E
+:10815000F02D2C0FCD77D0B834BE81BCA78B7749DA
+:10816000E9E8CFE8492EF4FC6F33B50EC0F9AAE771
+:108170007F5B8C739FED09FC5C6389DB3B0DFD2B02
+:10818000601E6E7045D80FA7D5DA833FC579B483DA
+:10819000CB71E4BA48C6D28B265A675739DC698955
+:1081A00076C1B771F87ED112C07A5A3FA7FC35B3B9
+:1081B00006D27963EDAC8103E9DD06A55A79E9FDC4
+:1081C0001F3BD13E6DCF65E45F6873C8F81EC1C523
+:1081D000660CA69CFE2BD596AFDF421DB4A385E2AC
+:1081E000B79EFA4AF827BEB214461BE7D9046E07B9
+:1081F0006AF74F6E14F3E8C666FEDE6ED1D66233C0
+:10820000F901D6C8F7355E525CD332A1A9AF61A49B
+:1082100019F9ACE7C752CF15F40EBC1B5FD8EDC4FB
+:10822000D7A5FA776DE21ED302211F335D6E61A7D9
+:10823000F9E81DF1923A23D9F7CBDCD5B4BF59A1A7
+:10824000467F8F35C66538EF78F4E358D8A890DEBE
+:10825000D3E3BF6CC7DA0D7D198E9F8FAFFB384219
+:10826000FD48CF8871B2D6CBF9BB4CB16EFF174732
+:1082700094BC5700800000001F8B08000000000025
+:10828000000BB57C0D7854D5B5E83E73CEFC243395
+:108290004926FF21413C21111212E2908400017114
+:1082A000F24BC408030182607540518490207A5BD0
+:1082B000EFABB79990682DFA7AA358CB6DEDFD0618
+:1082C0002BAD0A4880A08126E9041403040D820A1C
+:1082D00096D68014B1053280B5587D8FB7D6DAFBBB
+:1082E00064664E92426F5F87D69D7DCE3EFBACBDED
+:1082F000FED7DA6B9F65ECD94B720E630FB7CB8C50
+:10830000E53356FBACEC65A98C2D63CAE9BE0C467F
+:10831000BF6BA9F85F67E59204C6EEC53F5568DB01
+:1083200057553278AE5CAE9985CFF56F90995982EA
+:10833000EB1EEF53C971D036498E4618C71E379EC3
+:10834000EEB33066817FD746D33C8C25E0FCFCD76A
+:1083500023B1A75260FEB38AFFBD0878EE2CC0E1BE
+:1083600081799678F873F47EF8FF32C78C2F2478E1
+:10837000DFFDEDF229730E5E5D6D32C0F8A52F4969
+:108380006C1D8CBFFF69DD78B12EFD3A1EDAF0A3BB
+:10839000B9E91981710F7B9F0BE9C3DA5456C0D834
+:1083A0007D023EF6EA7F05EE73F84DAE08C632ED6B
+:1083B000117167B3A05BC0265D4B63ACCE1A99C345
+:1083C000A2A03533C2233B64F46E02B8D644C08207
+:1083D00001CE355BA3BD1EC4E3EA68C646C0B8F64D
+:1083E0008D26B70DE6C4DFED8C9DAB6F9E9B9E0E78
+:1083F000EBAF7F7A6EBAC2D82CBB9DB189408FB6E5
+:10840000E7685CB7E29A6487FE2A4BDF8FEF5683FA
+:10841000F03899D363995C696286C07CFA7659B367
+:10842000F1CBBEA0751621FC56F86312C02FFF3D9C
+:10843000F8D5C4685B006EFDBC7FAADF1002F74A66
+:1084400085395B6C81F568E326DA0DB41EFDF37A9D
+:108450007A30E6A5717ABAAC443A04D117E15400F7
+:10846000AF3D1D56EF5A89F888E0F6748411DC1789
+:1084700093D6CD3D93C7D8617C00E0AE1DF132F5B7
+:108480005F515C6E7B3C5EF48F728DC76762199B97
+:10849000323CDE6046C6607C2ECE0FE3768539F333
+:1084A000988CD75DB1C807D31BFAAA2C40AA3AFB17
+:1084B000A40A05DE33FDB9BEAA30E83F629FCCFBBB
+:1084C0009BFA8E5A1C8C35B02915A5F0FC63700FF1
+:1084D000E7BB5E9B6F762D66C0573580534B0CB45F
+:1084E000C7C6BC8DF256D35B59214542CB984FCAC3
+:1084F000057E7046FAAC39D4678530AE33CAFD1FAD
+:10850000B8BE55579B2EC938EE98C2E5A53B8EF0F4
+:10851000A000EC61F05C53B853B503BE9A622C8E98
+:10852000C654BAEE098BC1BE535583AE6BF4C0E797
+:10853000108E2603734643DB75604C545FF6F0786B
+:10854000EBAA57AB14A0FFBEFA0C6AF5F78B4CF6FA
+:1085500074073C5F6460EE16DBE0FBAF22BF109D4A
+:10856000D414A4736DB789E41C7F12F0FD2AA1878F
+:108570006A81405100CFAA63CC171E89E3CABF505D
+:10858000B06D95D8E910BE6281BE3C3CDC37DAD6CE
+:10859000E27C4A309F703C152BA9554AD07B4B6D2D
+:1085A00099217D39D19081EB6172B86313E0574E08
+:1085B00031ACDE01EB976F8616F0A1D81DF2126880
+:1085C0009B4BA6CB4BA16D34B2852DD81AD8F26047
+:1085D0003C750879D2DA4B76D76F90EE17DEEF2D27
+:1085E000B0929E1A6927F916EB6D941C3ED4439EF7
+:1085F0002EE6D804D79A6417E37CDCC2908F7F2FD5
+:10860000E671980D3B55E0D7F7EC0F12FF3AA20C3C
+:108610008FA642FFA3E615150AF0AF23C5702515F6
+:1086200078F478F34ADECF325C190DFD4F9A6B78FF
+:108630007F2A4C99CCD8C9E655159E6C9C97EB3196
+:10864000B6C59985EF510C12C9A9B2D7E46D843F24
+:108650009B22393F3519812F6370BC4AE39F6A28FA
+:10866000DE6C05FE578A9DEA6A1BC735F2C3FFB46C
+:10867000D5F0285B0DAB118FD822BECF88756B74F7
+:1086800060ADCEAC39A8175A9C59732310AFEECF0A
+:1086900011AF793DBDD3510FB77EF049813B9BD3DC
+:1086A0000BE7C9EB612C12D673E1AD9B36CA528041
+:1086B0003E97EC45E7515F4BA0A61F877549AA9DE1
+:1086C000DD0372D7E864AA09D695C85EB2A3FD306F
+:1086D000207D4005B532AE5F3AA35C5FE2736CA4C7
+:1086E0008FEC4CB5DDF515BE5FD3CFAC3766483D9A
+:1086F000ACD757A69CC765067C1093D2767C29EA36
+:10870000F3DF9A1DB7A8088F933D0E706C33308548
+:10871000C5107B642870DFCAC21DEB50DE1D2CC95A
+:1087200003F2856823E0E01707F6D02864485B076A
+:108730003C5FCAA09D8470DD4AEB92919F263097E2
+:108740008C7AAB8079ADD8F677BC9584F87A3E8C7C
+:10875000DDE782D6F22A737A83F4467EB444F89F2A
+:108760001563A436DCD83217F934FC12B3A31FD03A
+:10877000FF0B9382F38360DC89D71DFB0D0CE1FCBA
+:10878000B5D16B8F82BE3F53515F6681F9FA059D6B
+:10879000B5799F37A999D1D0AF8A91082FBF2EE222
+:1087A000F6D8FF85C9FB722AE2C7B2DA1B2457E369
+:1087B000A3F9B8BAB8E2B1D1F07C4B4738C3F74F50
+:1087C000EA0C3720FE376FC90D433ED886B881F5D5
+:1087D000C798ED8FE07C315700DE54BAEE24BC2AF6
+:1087E000EA8428C06BE14C9BBA0EF0FEEBB0969980
+:1087F000C8F7FEAD06F632BC629BC93107FBDB2E23
+:10880000AB76D4B3BF4E6D09A7F56C35D07AB6857B
+:10881000FBC7AD01B8D7652815089F62650AEA5FF6
+:10882000C550AC3E02D7A74573FDA8E9E39A689509
+:10883000FACF4BF0FE5C1C5744725326DB48DEFA3D
+:10884000FDCC6B86F7C4CFEB95911EE173809590BC
+:10885000DF159FCC703E17121A5A9BD1AB929E75B2
+:10886000DA9600DDA70B3D3BFD644D258BC48EE3FE
+:10887000D854986F9FCDC8705DB7B13ED902FDDB6B
+:10888000AE32870FF9E7AA427E981DFE05FB7B6595
+:10889000629E5F494C898271455FAA0AF257110BAB
+:1088A000F5DBCA36947F81F6ADC4A2BB8EFE5C2494
+:1088B000B64AE03ACCB3285AF861A3D8A86BA4CF43
+:1088C00060D6046147555C7FF67FE1BAFA2B4C0E07
+:1088D0005CFF769BF3E3A9A8077B8D6C131B5E8E70
+:1088E0007E550F1A7D0C08C7D570E68D253EB42144
+:1088F000FDC76D68F684C17AC7A5F3F991DF506FA3
+:108900008CFD455C2CEAED8868AE4FB456E32FE44D
+:10891000237B14E723FBAD01F9FB5E742A8DD3E4BE
+:1089200009F90BE7D963F42E760D6117812FBF8704
+:108930007CB9DDC62A90CF9F19615988F2A4BD6722
+:10894000B7E07B7DFB54C39A2E23AEFB2FA0FF0123
+:10895000EED2E4ABA660FBDD15C7E12D93BF25BFCA
+:10896000FA62BB44FE7C423BD7D7C17C316268BE11
+:108970007801F17A3DBED0C7011A5FECB81E5F7472
+:10898000FF637CF18B68E1DF0ECB17DF46E2FA1F55
+:10899000EB2849647FC78F69137C30DCFD2956AE14
+:1089A000D7F4D7DB053E779B9AEFCC41B9BFCBE03C
+:1089B00040B906AAA7CC05FBB23B9C3FC794D5693A
+:1089C000D8DFAE703DB2BDDD4C7A64BBCDED267B09
+:1089D0009D6461E82730C5DDF77DD47FC916755DDC
+:1089E00010DF3E2EF4408BD137E573F47F0F70FA21
+:1089F0004EBE2B5736C1B8110F70B9CE3F67DA287B
+:108A0000C33CD53145BE6818DF17CDED62DD1918BE
+:108A1000057C597BC644FAEDADCE23E54E1BF937F4
+:108A20004EE4AF497B8E941767E378CE47DDA2D53D
+:108A3000FA53704D3164768E25017E5DC24E4C61D5
+:108A40005C0FB9903F72027DE634523CA6F141358D
+:108A500063596827E6F639CA908DAA2A42E95BED88
+:108A60009B4971DFFCE3CEB20858D77C97EEBEA0DD
+:108A70007FB58EFEE007FF01E564D5E6DE4E1BF212
+:108A8000ADCAED698B697516F77B56A7A1FFAFC913
+:108A900011FD004F2DBFCF78795D901D5763F83AD7
+:108AA0009F752874DFD367F2DE0297FE37E3CFB5F8
+:108AB000087BF3AD90E3DCC7DE588CFC9BB7DCB9D8
+:108AC0000FF1BF284EA6EBFFC97C9634A48F43213B
+:108AD000FFABC5A8967C2E05C631C5956183FB7B8F
+:108AE000E2C3F3F0FDD531EE6B4827A6F8BBF1B930
+:108AF0004985B9792857B6094DB1687F34B801AEB8
+:108B00008A4DB6001C1A5CE785FEA98E59720DF1DC
+:108B100080CFA15E693B75D682CF6B746FE9B8C414
+:108B2000E91D447FA47780FED27DD8D7F06011ADD7
+:108B3000D6FFE7E9EF1B89F41896FE18F747FE8F7A
+:108B4000E83F2A6608FA833F958ED7357FAAC50489
+:108B50007E7576A0AFD1BDDA5E44E31C265819FAC3
+:108B60004F9D1057A21CBAA3D1B9613BEDFC5DFD2E
+:108B7000BF3F3B0A5C4036292686CB93C93F06FDA2
+:108B80008D093E89FCBE0920F0F7909F3592F49D37
+:108B900043E0879D95A4B319DC05BF9682FE9F2F05
+:108BA00016E56082B9D287FCBEC33A3D05FDB75CCD
+:108BB000EBB434E4A737331E3B8426E7CDE4E53B32
+:108BC0005F51037E8EA6D7F68969B5F797C770FA0D
+:108BD000DF0E6A16FD3D740D83E1D0F4379205E196
+:108BE000907CD5866B56D2C7ED7D80AFDB110EC071
+:108BF0006B97C45A517F17199C7125E88FC5FB14D8
+:108C0000EED77D3D4A05BEA96C7FF738C25B69B1DE
+:108C1000F930DFC21CC6F37D41F912BD9FABF925C7
+:108C20009ADFAFF92D5A7C89FE0DDECFC7EB00BF6E
+:108C3000DD0C00A2FDF159BC0DF0FEE72FAB994E03
+:108C400021AF0AACA352AC6336EB25B8D8B7D7AE88
+:108C50004D03FACC12F8A8EC86B83007EF3376173C
+:108C6000E0E12E85C78B7739203E0CE2A3D99343F0
+:108C7000FBF89B9E1098E77AE3F5FA7FAAC817FCE9
+:108C8000B371A6D676831D3A0D0C70B09EC734859D
+:108C9000A3658F82F1803BD380FC5827EC1A84C9EE
+:108CA00043DB2321AF8586BE1C07E0B76BCF37645B
+:108CB000FFF6EEF9E623F4E7A67CA130333C5FF83B
+:108CC000457E14EA07E60A9DB7EE8FAD56C6AF1390
+:108CD000FFD48AB5EFAFC78C18C267A1F637E79FFC
+:108CE0005F8FF37D7946E1BC2DDE5F6E72A7DB6D91
+:108CF000D8F2787FBFC4FD1DEDFE7E23C00DD737AF
+:108D0000C568717FAF42F919F89983E87C17C6FBF3
+:108D1000B901BADE75AEE20B2567307DF0F7FF23AF
+:108D2000DED7E2FCB744FCC0F69D30A900D78CD654
+:108D30004714F4A36724C9CC19F4DE3B542B730603
+:108D4000C5FB6FC4E8FC907DAFAD9F0576A4AE4730
+:108D50007684A1BCB66F3F9483FD5ED9611D828F7E
+:108D6000F4F89DD1FE8882FC9F10CBE5E67AEF2FC8
+:108D70001C077C722BD29D911F77B1402239D2D330
+:108D800077EF9E9FC7F6650F8FEFE1E8AFA7C36F40
+:108D9000CE1747215EAE470F3DDF76C23A3DB03E6B
+:108DA0001FACD303FED6DE7A3BF5DFAE4FA2BEC6C4
+:108DB000AF751DBF8C457F4DE3D3B258CE37537688
+:108DC000AF8F65B600BD347C5D1474AB668EF9B3AD
+:108DD000E0CF5D922382F48487F5261504EC55F5E7
+:108DE000B172F233347B552D671B51FF6AF60AD3FB
+:108DF000C2A8CFF4F6697E7A9111D5AADE2EC102FF
+:108E00008DC8BFD50B43AF57F4342B11D433109D0D
+:108E10002449E043F8D51A3C1F3217C1ABA7A70677
+:108E20009F1E2ECD9FAE1674837596E1D2E7AA459C
+:108E3000B48E417655ACF746EDA9393634CEBA72C8
+:108E4000AEF4FD9C21F87538BED5DFD7F44039BEAD
+:108E500020975A0FFA1109B10944AFF2AB26E60484
+:108E60007BC14686B1CF82F3EFAF6492BD7B54D80D
+:108E7000DFE1F8A6F6AA81B96303FC636C7BCE8AB6
+:108E8000FCB35B69B662DEF136DB9CC628C053E9F1
+:108E90001F8BE7A15F57D76760989A2A6BBFB40F03
+:108EA000E3F6BAE3CC81FAB0B8BDAB04F9ED6DA539
+:108EB00057A638FA4BC69E0BF20FDBDA1BADE83F24
+:108EC000B5C5C914A7EF8FE6FCA8DD6F89E5FCD70F
+:108ED00076E6F22CE710F73F13F74B4FE51AD1482F
+:108EE000F6C74750BEA1FC6903ADBF54B25755A2A7
+:108EF000FF718791FC7A885BFEF07DCC37B599B71E
+:108F000063AABEACED878FD881102DFFE7B306337F
+:108F1000E60FE6488E97615CB9EAEFC27EF9BC5471
+:108F2000DA8799F47F65F25FFD774B94F72807762F
+:108F3000C17EF93DA95ECC3FEC9178DFD3C1F3FE51
+:108F4000CCEE899D05EFF9A03276C23AE229AD7FD9
+:108F50004BEE3A261838289E7A6C17DF3F7AAC4CD5
+:108F6000A2FDA3327B0AF304F155F9D340CF3CE0D4
+:108F7000C7F6C462E4DFAA0A997983F87ABECBCA3D
+:108F8000BC41E3F7877178FC92D98BF9124D5E678B
+:108F90000AFEAE5E181B327E0EE37EE242D66C44C1
+:108FA000F9AE13F0D415013CF0FC4C11A7DEED4EE8
+:108FB00009796F256641606856DC68B28FB3BFECF3
+:108FC00023B33A473E796C31BC876570F9D0E4AC85
+:108FD0004CAE69223E48921C181FCF97C0AB9451EB
+:108FE000DF85CAD1ECC9A1FD394EBD7E089577BD9C
+:108FF0001ED7E47C7E876CC4387A7E91E46043E8B7
+:1090000003BD3FADD703930C8E7730AE9E7BD54921
+:10901000FC35480F9CACF887F4C05B205B93415E45
+:109020007FA4E9839BD84DA80FCAE42DEB913FFAAA
+:10903000C1AE9987E00FCD2E68F17639C827F203CB
+:109040003BCFF725CAAE829CC606E2ED01FD007E4D
+:109050008363087FE657B16921FB4903FA22C86F91
+:109060003016FCF37E4319F88BA65C846F24F3E47E
+:10907000919EA2FC1EB43ECAB3255DA23C4A1DC40B
+:10908000F114CFB35F125CA8D7A49800DFEBFD0901
+:109090002D4F3B42E409F4FC3090B79B67F4229FCC
+:1090A00069FC506EE772513E4FA6FCB99E3FB4F783
+:1090B0005D8F2F7C12F085F477F842C8D38DF2C50E
+:1090C000218D1FD259FA8DF083C6071A5FE8EDC5CE
+:1090D000415DDE65387B71F23AF6E29D0C23E9656D
+:1090E000BD9DD0ECC28138AE7FC7C7F27D8A999909
+:1090F000F36DE8578C407D80FE9EB0370379A30D59
+:109100009C0FDEE95BAA486837500FA406E15DE4D6
+:109110004D35BEAB7D9A51FEB052E89F8B1D3C9FF2
+:1091200056572A7B2DF06749FB73EB79DF48F9B678
+:1091300022A54BB1C0BCB31D9203F3354E917F9B6A
+:1091400075D5E455293F3FF47E7A95E01B8C73700A
+:10915000FC6CA7E4851074901EAABACAEDBE5E1F0F
+:109160005589FDF22ADD7EB9294ED0F56676F3BF2A
+:10917000D2EEC7C72570B919868EDAF31A1D35FAF3
+:109180004DC0B1283FFBBE36A911DC3F46FACDB831
+:10919000AAD03CA3E242FD962FCFE7FE27C574621A
+:1091A0007C5DFB25937BFCF0F05FCF2FBD59F3C3B3
+:1091B000855FAEBD7726C8780A3A863AFBA1BDE73F
+:1091C000BAF6423CAFA7D3E4B8D07842A387A6470B
+:1091D00007E15BE8D9E1E8753D3DABE9B37FB59EBA
+:1091E000D5E6D7EC80F65EBDFE1D2E3ED3F4E953E6
+:1091F0001B0D9417B94DC4C1B7893CEB8342CE9780
+:109200000B7DDBFF178B01FDAC6D9DDC1F7198EDB5
+:1092100087D06F08E4F3385D9F8C601EDC2F674AAF
+:10922000AF85F62F8B81A4B87F99CCF72FB7283E56
+:1092300017E96987C21A405EFE2AF2164FEEF52C36
+:10924000463DFDE4E93106DA47577CBD18174FCAA1
+:1092500055683F28DAAC52BEF76287D98ECFF5EF5A
+:10926000FE5E9711E7F90B7360A8F6768779603F89
+:1092700006F54299DC23635EBEDF0FBE388C9FB6D5
+:10928000D05782F1CE6DACB711E3EA42A4E310F4FB
+:109290007B55675FF479FB920EEE279544F0BA9FF9
+:1092A000E980467CEFF43613F985D7CBDB177DC90F
+:1092B000C85F1A94AF6FE37A0606119FDC68DEBEC2
+:1092C000107D3DE0E39FE8F40E1B267FBFCDC4F781
+:1092D00073FC478C0CFD5E762E6EC8BCCBF5F2F8A5
+:1092E000BB3BC39D6A24EEBB71FF7C7767B253CD55
+:1092F000197E7C4E9FBF18F395DBB6CC55284E14D3
+:10930000F9CF41FB223AFCED90589315F369ED8EAD
+:10931000528C3F86DBE728F63B69DE1BC51B63CD1D
+:109320009CCEA27EE9762163DBCE863B91BFB79DC2
+:109330004D76223CBB057F6AFCBEFBCCE570DACFE4
+:10934000343955DC07F6475B1C2F13BF723E6F198B
+:1093500031C68BFBADDB853C6C0BF71FCC8A0BDE7B
+:10936000CFE0FB179DF59EAA33E9B4DF2D61BE5116
+:10937000DB27F680BC505D4E0C237E32B21686EFA2
+:109380006D74B29F633B7D9A1A85F8BE1CA7ED47AA
+:10939000AA519467F8F64A816BFC60BCEFA877513C
+:1093A0003D496BFDC22A05607CB3DE4D6D5BFD72ED
+:1093B0006AF7D4AFA6FB6B0F453E8E76BFCEB9A041
+:1093C0004A09D21B9FC5F3FC526ED6E912E473F62C
+:1093D0000D6318EF4C7FA24F463D71FB555847482F
+:1093E000DD887219F14CF9CBB4403F555A12867C96
+:1093F00079FB55E8078D97E2A3391D9A94A65B0A7D
+:10940000485A881FC2E29D17E3E0FA0FED2E7F5CF9
+:109410003CF241F5BE0B8CFA97F1FA0EE96EF902B7
+:109420008CCBF31551DE380FF3C6B934ED62C4DFCF
+:10943000C42E13ED7B6BF9DB5C31AFF3ABD03C7228
+:109440009EC8DBBEC9FA289F9C6F81C0CA8070711C
+:10945000FA39A5F94912E6FBE24D0EAC579898E6A9
+:10946000CAC37C6B573CA3FC695757C24815F0E050
+:1094700054785ED7A9E575D9DFCFEB767F1AE9215D
+:109480007D057E0AEAA7EEA3910E1FEDFF59C8FFE6
+:10949000DB810F627D4338AF1760F3E6511EFD7626
+:1094A0000B5F07D89FF878CAFBF9F61D86E77E7B2D
+:1094B00099F17DC4DE93B43F5D62C84CEC0338F78C
+:1094C0004963A3B07DF1D3C86C6A8F469E47FC7494
+:1094D0001AAC2ABEF7C37A56857567CEF76DB49F6E
+:1094E00031FD7D9B82EDE1FA3EAA477BBFFE1CB5B4
+:1094F00047EAFDD41EADBF4AED3B701DF9E7103CB5
+:109500008F6DEEE2087A6EC7A20813C2DB19C9B6E6
+:1095100068EFC17A335FB8AF1593F9EFC57FBECE60
+:109520007213D83BB37BBC3481B113F19FCF54A0ED
+:109530007F68C6A87FFF0BDCFFDD4F2EACB3005C5D
+:10954000F38EDA5A7BA0FFE94F2EAEB3A19E3D14F5
+:109550000ECA0EF546FF4190749687363D99710507
+:109560003B19FAB1A2EFE99F590A245F50D297C57F
+:1095700080B5A6FCC43FD302785C6075FF1BF64D36
+:109580009E976696DE847DE6C17A2EBF64A4F89E1F
+:109590008D94E2B07E6599DD7D2C3EC87E3BA53F73
+:1095A000D2FE51815362D1714457DACF62F653B182
+:1095B000C1F2B6CC5E760CE971473CDFBF9A384DFC
+:1095C0007206D749E8C74D3CA396229D0ACE95372F
+:1095D000613BBB229AFAAE85939A509E4B6DC33D78
+:1095E0005F42CF2F8837127F162B52487D887E5CD2
+:1095F0001E3013FAC7FE03E194179878CCDD887506
+:10960000A36549A9B9B2D0798CFAD11B711F6D62DB
+:10961000E587A5B1283F36C981E6A180F535C5C6E5
+:1096200061FD231644E1BA9E2BC1FA9D89AAE4404C
+:10963000B41539BB5AF1F9224784A308FDF1636AD6
+:10964000299A9CA3CA84C3F9306E46BAECB0C044D0
+:10965000477D774CBD00FDA28C28CAE31629ABAF2D
+:109660001CA67E84A341C5756CFC792DCD63267B39
+:10967000BE6356C97F20FF14BBA228E7576A3B355B
+:1096800037B82E0CD64D7017D9656F9884FCFD83C2
+:10969000523BF4778C9218CACF515FE69FE97E77F0
+:1096A000B81A0680EE30D94B71BE1D26C9BE96FA97
+:1096B000AE121CEF196354314F541EF745C8FC33EA
+:1096C0004AA5296710FEECA80978AD62E4A590FBD5
+:1096D0003D8BAC64272ADFCF267FA867510AD98B40
+:1096E000CAF7A71563DB63E07E7AE5FB951574DFA7
+:1096F000C0E3DFCAC5DF718A3EC5BB958B5751BF3A
+:109700004B4AFC777CDF95ECA85CCCA3CD4CFF7A70
+:10971000AE12ECFFADCE24F9CF1579BC2243E6FAA8
+:109720006900FFA307F83E4465B6145237372BFF94
+:1097300054483DA86BDA1721FDB9A59742EA43E7E3
+:10974000557E1DD25F304FAA0A1E5F7A209FEC6BB8
+:10975000BEA85FD2F24B458285DEA9CFA82A05B903
+:109760003C00ED03A01F8A7A45DE55E1717506FCC9
+:10977000433D586AD3E577994AFBD915DD7CDFBABA
+:109780003CCE783AD83E54C84F707F41B7FEDC03D8
+:1097900046B293B9D132E5AB34F82A46863EAFF9EA
+:1097A0005F1502CE1D0677530CE5C79CBDE87F68A8
+:1097B000F06BEFD7E0AE90EF29A5EDBFEBC0AF8720
+:1097C000170025FF4D0FC78178118780BF41FE59D3
+:1097D00037AF4B835FDC50765BF3CF2B414F4507B0
+:1097E000EB299B1487F576C3E9296DDEE1FC306D2A
+:1097F000DE6576173DEFDCFAD9D14239A89F7A2A87
+:109800003626B8FFDA67EB43EEC79FAA8A0EEE6FE3
+:10981000FAAC0AEF4F57D4461BF0E34126393CC857
+:109820009F3DAA82FBCF25C79C4DD8969D74639916
+:10983000299B71C6D384EDD4F3DE1E33ACEB8E0CC2
+:1098400059C5B85DF33FF4F09A13781C72F0AA6A18
+:10985000C5FDD31D1ED58AFEFB8E27542BFA1F3B58
+:109860009CAC02E331679A6135FAF3CE2C5E6778DF
+:1098700055E8E16FE2F9F35A7B5A717F837A11EB75
+:10988000C2D127A8FDDA4F75E007D1AFCA1EEC5749
+:109890001D54BC367CDFC127BCB6E07DC21BF5ABD6
+:1098A000FE8C363A1EF96C4E887C9658EEAE0A96BF
+:1098B000EF32FB9290FB9FC6A904FF8CA48743C69E
+:1098C000DDA13E12D2077F3103FD914613A33A5921
+:1098D0008F81D7C9EAF1F8A8C0A3C36647378619B4
+:1098E000E354AA6BD38F739470FCE9AFA727F0B849
+:1098F0006823C80CB6F72470F8F475B1FA3EC47C3E
+:109900000B713E983909F9DC61355C0157973913C1
+:1099100092EEA47AD93CC3A369D0AF4EC8E2FDA9A8
+:10992000869D581F7B774236EFDF6AC833821FF06F
+:109930002B36FE4EAC07AF0D13759D0F24D27E98CB
+:1099400016DF2886532F2EC638738F9161FEFE19BD
+:1099500013D8BDDCC0BEB9D5CCE352AB89D76D3FBF
+:10996000957AF429D41B6A987B7A02F951C52AE2C8
+:10997000EFBCDD42759D8FED2E4B44FADF93C0F3B3
+:109980005C593BA726A17EF917BC7F56C2C4E1DF14
+:109990008F75BE38CFF91D59E47F67DD0CE895025D
+:1099A000F887F098AE87419840E725983309F36C23
+:1099B0008DD1269AE79E04CE7F37DA0EAAFB8D3230
+:1099C000ACDE0EEDFD82FE0FE07B095FFE51737091
+:1099D00063CEEE1F35773CEF237D6539D78F7EACA4
+:1099E000FF3B11B4AFC246FA69FFE5E37BB21CE866
+:1099F0009F7E12CEF1B7D03BBAB14FC5FA0DEF4DF5
+:109A0000582F9191E8AE453C2C327B6F21FEB1ADD1
+:109A10008EC0F96FB41E78F07B218004FA544FE1B8
+:109A2000F4D1DE0B38B5A03DF8589C03D1E080F7A7
+:109A3000FF00F9408367000E5D5DB89667AEFBA33B
+:109A400081F20C7512E83DE8EF3CC91C1E98E7A2B4
+:109A5000E6AF8BBC266E45E17BA61C5E5A62833660
+:109A6000BF6D258F737B95903CD7A4E38A7EBF831F
+:109A7000ECD654ED795D9E71AA886BA7EAE2DA17FD
+:109A800013849D4966C9C1798035226EB8DC333AAA
+:109A90000AFD4CD45132E0D5A4CA6C724C40CE5B66
+:109AA00021EE674171BFC667E38FD9EF47B8C71F83
+:109AB00063F7915DD7E61DC82F70BC5C3ECEF132D6
+:109AC000A12FE3A7D3A06FEC3632AF1A584F21076E
+:109AD000955DC6FFE078BBC98B75CB05077E99E71E
+:109AE000834BE624035383F010A6863335482F5A60
+:109AF000336242FAB2866F61CFF3C4FC118EE490F8
+:109B000079F6C49477A37DCFB32D27FB1E357974E6
+:109B1000C83CAC4709B1F3B028DABF9C0840FD0C43
+:109B2000F05A704C09B1E793E23CB86236F9A4A24E
+:109B3000B3FFCD32CA41E199D0EB0786A3CB70F8D1
+:109B400063393F45FFEE1FC55FB433147FB115A1E4
+:109B5000F88B7785E22F7161289E46B843F192B267
+:109B60007C5CC8FD9B56E786F46F7EBC30647C2A23
+:109B700018A4E07EDAD33343C6DFD23C37A43F7665
+:109B8000C3A290F199DEA521F7B35E5D7143F41E87
+:109B9000DFB226649C9EDEB7B6FDAF9079357A7B46
+:109BA000E0DFBF82DEE6C4507AA70AFD1AEDE4F5D5
+:109BB00065FD46DBD312E8234C13A15E8B6E7FF765
+:109BC0006BCC43788A55AA9FF3CC64B40FFD82EC2A
+:109BD00092500FA5C0148634AA5FA7FABB1F1B0CB6
+:109BE00021FBE28989DCBE2726F27CCDCF4DFCDC4F
+:109BF000520AF88F64870C2C102F031E22315EA6A8
+:109C000078FAC7CF60BCDC14DD97A1427C6CC6FE3D
+:109C10004D017DB9C8AC36F6013E26C85C1F829E58
+:109C20004C4B84F93F919E30723FC263443F22C542
+:109C3000C23C91B9643F287F1CCDE224ACC78F0A97
+:109C4000E869F51A106BDF8A2C3A07F51E4282FE8E
+:109C5000AF2586ECE8DD9A7E5A9E49FAE9B22DD40A
+:109C60000FBBFC401A5D3F71AF99F6FB4F883A4439
+:109C70006DFDE784DEFA53BD85DAF3F5F6103DB6E7
+:109C80007CE3FA08F41F4F64707F51BB5E82789BBF
+:109C900088AD2CEC9AC58EF9AC7BC0384701BE5715
+:109CA00075F7452E62E43716E3BA6B375EB9F74DA8
+:109CB000E8D719FC09DC3E7878BDCCC78CFCCFEA2C
+:109CC0006F5888FF343791C7E973C5FC0BA0B10307
+:109CD0009E1600FEA3B17D775A39F2275CA7F3697F
+:109CE000B3BB19D59FCC71A7D23EE351E6F87017EC
+:109CF00080F89D4495E09CC75CB45FFFD1BDAB226A
+:109D000070DCC07CDA3CC028E86F7C1CED3126603A
+:109D1000DC7F1BAF6F80F759F0BAEB9E9427D10E12
+:109D200069EFFB88B92F7C88FBDDCC41F36AF33304
+:109D30001613A29F762C5FF9692CBC6FCD0103E549
+:109D400013D6749829EEEA5FF1D7AD2FC2FDFB520E
+:109D5000FA6E42BBFCC98A6FC6203FDCBD01F4101D
+:109D6000ACB130CAFD7062509C72E2812B11781F39
+:109D7000ECEBA617D1386E36537DEF272B368F09C3
+:109D8000F6471F4D2CAAC5E7D8E41B3B6F58F27A63
+:109D90006622D563097E7A58F0D39AD7C6921FB54A
+:109DA0002662809F787F13AFEFD0D6F1A1E0C71570
+:109DB000AF7F5D107CCE7407F0913A86EF6BA920DF
+:109DC000533B7B2EE7E0FD57147713C2D779F57428
+:109DD00024F677BEF737829FCDBB317851063D051B
+:109DE00081FD65EDDCE5C2F6D83CA43BC85933CE15
+:109DF000BFE837AF5DF81DE2A763F3A6EFE3981B5A
+:109E00003C7FC9847D71083C807DA1F8A09F85F3CB
+:109E1000731D428F2AB8839E86E7991C2AF1B3935B
+:109E20001DC27D97C62E03C3BA9548DCB409CAB3D8
+:109E300045CA06CD08392D49A09F855E7925F1E4F4
+:109E40009D4DE4E787FA3DF96FAF08F1775CF08F3D
+:109E5000FC9D97DC8D9807BAAEDFE3332C3145DDEE
+:109E6000B8FF0381B0532A105B38F06B4B14FB2210
+:109E7000420F77A21C61FD3FCE85F97A5F383F67BC
+:109E80000CA602F5F80F604DF8B02945B4D2C50C08
+:109E90000BE8C5BD897F78E669D0939674BE5EEC09
+:109EA00037E2DFDD9CDF06FCABB7C7919E62DFC205
+:109EB000DB100F225FA1A7533EC8078B0D9233F131
+:109EC000BC6FFFDF22314FBB35467D1FE9E03F20ED
+:109ED000D33E4D98D2678A1E222E7B13F59E89FBB6
+:109EE0004D546FDEC6F38116D5C9300E08B3DB279B
+:109EF000049FB36B17FA6ED5FE4F4699800E170C70
+:109F00003D91D9307FCDAE1D91E8C6DF6B747F8A5D
+:109F10007CB7F2C40705763ACFB671149D03F08D75
+:109F2000A6BA83F10AF328B983E1A8DB904BC6B83F
+:109F3000760325E3D9F8F6BC87501FD5F9F83A71B6
+:109F40006E2CFCCB6C63D4BFD8D61883F3D5FDB68A
+:109F50002319E567733C8F135FBF3A8E3FAF30051F
+:109F6000C77F99182DF8D96BC03863B3884F2E5E20
+:109F700035D038EDFDE3DB8A643BF043B6AF792F93
+:109F8000C543ED6615E91AF60AE378680F2339AF81
+:109F9000EB9CC1309FDF1FCD1C12DCDF1AEEFF03EC
+:109FA0009D33EB30AB981F0DB337B318987FABD808
+:109FB0000FCD048EC2F34ADA75ED7D61ED3FC558D1
+:109FC00002F981F2B4614A33BBCD168CE708C27343
+:109FD0003CF2533CBEC767C0FC88FF16C65E26B87D
+:109FE0000270327AAF066726F9735B4DFEB3787E56
+:109FF00005E0B223FD33198793B58F5531BE0FB3FA
+:10A000003B691D6176D5E19106C35597C3BC68BF16
+:10A010007FBC960DC82BCA6F5D78A06F0119D83A26
+:10A020009A09F9B63F5B3A2DB80F8A6472E0F9716C
+:10A030001B629E6D1A49718347C63816DA88185C10
+:10A04000A7CACF3B636A2897E301F7C5AD167E7FA9
+:10A05000603CF0B70DFB363ECE1165B7CE94484E4E
+:10A0600028AF572BE4FD31C977F67690D3BFF8F6C9
+:10A07000E6A8004BCDBB7B884F571ADA5F1C0FF761
+:10A08000375ADCF94980CFB74E1AE81CE99F5E0BBE
+:10A09000F35662FCB87B63827308F9D0CFFFC3E349
+:10A0A0006B9F4F41FAEF9654CC9BF61BFDA310DE3D
+:10A0B000DAF6CF4D548FD0768AEA938E24B99DF884
+:10A0C0009EC96D0DB46F3C8535D3BE7196387FDD6A
+:10A0D00092C4F5C7E563635E6E08C2FF8349DC0F77
+:10A0E000637EF7CD2837ED423E3BD12F817697F046
+:10A0F0008F7675DD9DA606E5FD1AD8DE14C4F75AE5
+:10A10000F636B5DAF57E2F3FCF98F591E53E67102C
+:10A11000FFB993B89FE716EFF327B91724A1DC76B0
+:10A120009D3645AA785EA56514DA9116F09FEC433A
+:10A13000E065406E757254A7F84D38BEEE1C3F774F
+:10A140000A746EC2FAFFCD1FB58D5B02D77701AEE0
+:10A15000B1DED373C24C758FBB8CAE141CDFF0E143
+:10A160005739A8B72A1069F0BFAF3A56DE8C78038A
+:10A17000BE2F0E47F9DACE488F69F2998DF209CFDA
+:10A180006723DFE7633F93F4F056532F3FF7B98B14
+:10A190009FFB04BE273900BEB7A39F906D0739A06F
+:10A1A000E7C7927C6FED35D0F9540FE8F15BA85FFB
+:10A1B0005C85FDADBDA576926FCCC3E7A29CFAF697
+:10A1C000D23C2D108320E924E60AF61FDB132389F5
+:10A1D0008F35FD783091EBFF960C350AEBFFADB271
+:10A1E0001C2217417690F7859DECDD50FCEC0BD3DB
+:10A1F000D0DE09BB20FC27769CEBF94785AD5AF3EE
+:10A200004EE1EC2DB0CE3587E5817A6EF4577D8234
+:10A210004FF60AFF15ED849AC7EB67F0FAC40DBC40
+:10A22000CEB5C0B9BA04CB38265734EFC3B6D0D5B3
+:10A230005282678EA72DECDDC7CF1EF3F3E3AD7B13
+:10A24000EFC8C27DEAFE136686FB24AD7FF3FFE113
+:10A2500075C0C3773B01FF43D825580EF11F58EA5C
+:10A26000149634F87EBFA4E98FF995286F175BE543
+:10A27000401FEC612D3038F67F9D54F5AC07004B44
+:10A280001BE17C1D59A230D94D6DFF91BF25A02D3A
+:10A29000D8758CFB4DAD266716F24FEBE8D0F3FA7C
+:10A2A0005AFB62123FE79C6F6643E6250F09BB37F6
+:10A2B000C6C39E413EAA6D95ED5EA0FB8556D96949
+:10A2C00002FFE6ACD39D806765CE31CF82A968E7F7
+:10A2D00045DCA87D4F6519FA2760A71E7C61501EDA
+:10A2E000DF807CF450BBC47E066B5EFED2D0FB0ADE
+:10A2F00035629E87DB36EE4F013AAE7825745C8D71
+:10A30000A813ABD1F92F8792447C98C6D2D02F01E5
+:10A31000FE21BD605458B719F8F5C1647707C61B14
+:10A320009BC5770C407F921C7608BEDC2AEA04FCB1
+:10A330005B25DAD7CB7CD52B1BE0F942C52BA39D3F
+:10A3400062D0E23EC164A7BB1CF10BEB3E86FB353D
+:10A35000CB851E5CAEF9655EBE9F01E696FCB22918
+:10A36000CCDB1889EB7E5572F854FC8EC8A03A5CA1
+:10A370005A779D5877CD8623FB318C5BD5123AAE48
+:10A380004EACBB4EB76E6D5FFBCF49BA73C837B8E2
+:10A390006FF16723F7133E10F368F7CD23B83EAC97
+:10A3A00005F0906E355ED9EBE57E9D0DBFC373BFA2
+:10A3B00080F77E41EF3AE633A5C0B8552FF075B26D
+:10A3C0006743EB3F1F6C7DC484F1959E2F966F31E0
+:10A3D000923F0A8833A1BFA8E78B1562DD2B74EB8F
+:10A3E000AE754B3AB8B89F3C18AE960548D7555B4A
+:10A3F0008C0CEB11F5702D6B59528E7C36985F39B1
+:10A400005D5688F90270AEA6737C370AE7A8118200
+:10A410002FC7B17144978AD81BA28BDE8FDDBE7F18
+:10A420009C15E5FB72F7688ADF35BAEB9F2F177E24
+:10A43000F08C0D8CDA0B6D25D6F118A7F4181C9250
+:10A440004AF156E478C0475E87CC2AA1DFDF9EB68A
+:10A45000DE0378CF3D9C5F85F17CDE61039D77DB79
+:10A46000D99D4FFBC07907D263D3281FEDA0EFCD54
+:10A47000C03C643FFB7B72D7E3B980FE9ED27C9CDC
+:10A4800057827168E773851D68E8C9B5069FEF2E8E
+:10A4900018C1E3F5A7923EFB31FAE133B61BE97C24
+:10A4A000C30CA3FF3DAC9FDAD9ADD0BE75CDE1A5FD
+:10A4B0006BC390AEAF49B46FBDBF774DDC62E4AB08
+:10A4C00076A31DF7A1FBDBFF6D2FDEF76C91E87B18
+:10A4D00012751D65595BA19FBB31CF117CDE2B37F7
+:10A4E0005A25F8D8082BC5C3336E32925D3C9F6C59
+:10A4F000FD25FA372B9C1B498ECFEFD969A2FAB9FB
+:10A50000AD1243D3BF3F69DF1B888FF36F1E31A1AC
+:10A51000935DD27AC4D4F777ECFD052F04FE1407BF
+:10A52000379B304E59B551EBF799904E2EE1FFD441
+:10A53000BE728AFA2BDA24D2332B5E92E93CFBBE40
+:10A540008EB74CC8C7B55B2496981A747F8314F2F3
+:10A550001D84A58CF3C152A1675632EF53C9306EEA
+:10A560006533AF23604F87D6E5AEDC3287BEDBB400
+:10A57000AC79687DF3B0E0EB87301EBC15BF831467
+:10A580003AEE61EDBB5C3A7E7E5CE3E74C9689FC7B
+:10A59000FC55911A950DD7BF3AB2E2E6A1CEB1F7BC
+:10A5A000083BACD9C1CB3E03D911FDB88B6D570820
+:10A5B000DEBA9ECB26B483E5ED9708EF95ED5D54AA
+:10A5C000C7711773D7209EEE6AB7DA518E2BFBB88E
+:10A5D0005E9AD96EF67A25BCDFD284F4ECEFE4758E
+:10A5E0008B9E3D12F92F9ABE7A48E0EF2181BF87FA
+:10A5F0004041A7E4A21FCBE3DE873336EE8F81FB19
+:10A60000B5E27ACD817D91E8EFCD6497EE457AC0D1
+:10A610007B18BE87BD148AE73B1987E3CE2DBCDECD
+:10A62000596FAFFA4764CDA6FC23C49D084FCD9661
+:10A63000503CD7EAE2ED7523B87DDEA4C373A59F35
+:10A6400059B3110E5576786974AF82EFEDCE91282B
+:10A65000BFDAADA6450DB5FFA8B5EF09BF59EBCFE1
+:10A6600016E7AB5BECCDB6E038D894CCEDFF8A2989
+:10A67000B207E934103FA4EFCB510D81F801E28617
+:10A68000DF8C88E771041674BC3B5266717181F8E7
+:10A69000E18749EB2B73A15FB785CBF9C5C9301FA3
+:10A6A0007EDF4B61E45FD66D31D339C03AA03BC544
+:10A6B00009EDFC1C83AB5D2A437A83FFFDEE88899C
+:10A6C00078AE8619E360DD73DA389FCF29BD447C0C
+:10A6D00072209DAFF7B2A2260EE58F6B7E389EC327
+:10A6E0005283CF3F805CE2F8DA765E0FD4BAF7EBA4
+:10A6F00051A9A8D73AFE3A6A09B45746F0F56B7EDD
+:10A700009E1FFCBCD1DCCF3986FEE7839ADCD8F9EA
+:10A710003EDA83C2CE30A989F8BBD6D8F2760CFADD
+:10A720004D5BF9BE3DDB6DC46F9CB1860F5E6F8AD9
+:10A7300081755F7C5DA27A347CFE09E0B38B4B5B54
+:10A740004EA31FFDD5560BF98F0F828F383D77B082
+:10A750003C6A72AB7D77AA81AD257F722D6BA276A4
+:10A7600095E0E38B6D8D26CA9B79839E1F3DD8EFC4
+:10A7700058A5E33B537228BF357C104EFE5FFF01A6
+:10A78000D98EFB2780A7FF4E0EC687F02F5AF7867B
+:10A79000113DFB8FD8C85EFC49F0D97991376E988E
+:10A7A0002CD3FA0D53789BD5F9D668A41FE21BEB86
+:10A7B000DE3777BE358E9FA7F612DE57BE8A49F187
+:10A7C00020385BAC94DBD3FA0D1F2CA2EFF0D4ED54
+:10A7D00019806B8C292E00D770FC2F493C1E344801
+:10A7E000A1F160DD6ED9155CEF05EBB90FF54F9265
+:10A7F0009003A6F813D02F1999AC92FD6A68E7F47C
+:10A800003474F016DEBF80E73B8CF4FE41F78B3DDD
+:10A810003578FFAB542BDF4FBEEAA9C4FE7747CB98
+:10A82000544FF9DD0F568C0DD69B0CE1047AD619E6
+:10A83000FD0914371E31107C75472E27A4DB501FED
+:10A840006D2CB567A3DEE1FA6EFF68EB72E4630F6F
+:10A85000BE373130CF6BC2DE325C6F127A152FF00B
+:10A8600079C57AD7B2B9223EE67C942DFC3D882B7F
+:10A8700026264F1C1C57DCA83F09F6E0E86209EBCE
+:10A8800089140FC6B53B8F737DD0D0F1D0A7C8E730
+:10A89000759F98A9BEEABB9D0F8DA53A5BB7FB5685
+:10A8A000F42BBEEA7CF856CAF3496B092E0FC29707
+:10A8B00084FECB8709580FBAAAE3C304B2AFBB2604
+:10A8C000AEF744A09F927B275E07BF81F80FFC176D
+:10A8D000E2BF9D3DF99ABF62C579571D505C889FC4
+:10A8E0005507F20F55A21F71B8381FD5B874389F9D
+:10A8F000FC953CF4576C01FF455B4F6532AF77E93F
+:10A90000EF0AA33C81C44673FE61E921FC53D3FAEC
+:10A910000ED9F59A3639A46E507BCE9DACF07D7E73
+:10A920008D7F5A2427F1C776DED6B4EDA4F5AD3479
+:10A93000B610BD1BB618F9FDADBCD5EAAA3D2CC6B4
+:10A9400083F8388497800E334D5EFA6EC5C154EE9D
+:10A95000BFEBE9F15932CF631C3CE1BE19F9E56068
+:10A96000917BAC7D08FBE061C53C3E9504BE5BF984
+:10A970007925FDB853C93C8E8F8C0D3D3F3A605F01
+:10A980009239FFCC340DFD3DBD9F69F2C4D833062A
+:10A99000E08BA39546FB3AE1B78F08FA5E42D55D9E
+:10A9A00046F20F8E32FB3B5867384BD3AF93B95DFD
+:10A9B000D5F2DDAE0D2ADFD7197CAE91F4E47C6DC3
+:10A9C0003EFD7969E1D7CCD7F935EB35FD37868D7A
+:10A9D00041FDD722CEB9ADC90CF306E7A3F4ED7E55
+:10A9E000B18F81E775B06DC8FC98F23607BB4EBCDD
+:10A9F00041756627C2D8689E97A3FCF5AA61F2D775
+:10AA00000D03F2382F84BF347A5C10DF55D1D3E3C5
+:10AA10000D81776D9F2D5CECB39D56DC6F24535DEB
+:10AA2000D67913FF8E9A9FE2AB864CEE1F5D28937A
+:10AA3000685F1CE01C650ED2EB1746F0B8EABB0B52
+:10AA400024CA9B76E1788C9F5A24AAAB5EE5EB354D
+:10AA5000211F8D695DF224C9AB871D6341DFA99871
+:10AA60006DE17671806EDABA07EC568C87EBE138CF
+:10AA70006A713CDAC159C2EEE9CF218D65BDE51896
+:10AA800057563B2507EEDBEBE93D77E18477E2FFA4
+:10AA9000013A9F4B761F21FDD67B7901E63F0F6679
+:10AAA0007E3E0AED65ED307CFB3BC1B7DAF7591C01
+:10AAB00063D546FC3EC98F12DD9F207EFB0DDF462D
+:10AAC0008E63F87CDF7FAF91902E8CE8319C9C9C4C
+:10AAD00012F39D4A16DF258CE3FB24CBB18FF26A7B
+:10AAE000F48EA4FC42F68DED4B35EC7E3707F5D69F
+:10AAF000C5AE0339A6203A9E5F03F28EF6A3635FCC
+:10AB0000826A0BE63303F1972469FCA608BB18CAD6
+:10AB100077E791EFB2B1FD30321DF5EEF6A391B7B4
+:10AB2000E07CBB783BC09FED328D837867CCFC889E
+:10AB300060F89E24F82EB4F07918EB1B53353EF8DC
+:10AB40007EE3707C6B4CE1F584217CABADB705BF37
+:10AB50008783FE7DA799BE8783F9E6E820B9484D33
+:10AB6000E1F230497CFF660AF3D0F7002789EFE075
+:10AB70004C51984F89C17D2E9FCCF765F97986029B
+:10AB8000C1BF93145F17D6394C11FB3285AC97C601
+:10AB90004D677E6A9DCC4EE7148A9983DAC916DF29
+:10ABA0009D9876C96E69A1FA3F5F82127DD622CE4A
+:10ABB000430C41B7C0FA15FAEE0DF1A58CE761869A
+:10ABC000FE6E4A650A9773FA3807D2F702A3FC149F
+:10ABD0007EDF0C5F325561155877749BC22CE10003
+:10ABE000EFF6B70D24BF9D7DAA17EB401DB1E2B96A
+:10ABF0002F18D5BB4E7272F944D3827512DA7AF5EA
+:10AC0000782884F9303F364981C892F0E8A3F7DD0F
+:10AC1000CEF8398D22A6D207566EC78F27935EF7DE
+:10AC2000539C54027112EA7583C543F828C3E4CAE1
+:10AC300044BEBF1109F314364BEC38EE57A4F1F5BE
+:10AC40006AF3170223E0B9BD32B15E4C811E8FE179
+:10AC5000FB1E9154385C6AE7DF094AA0EF04DD2847
+:10AC60005EFB13F8772123EFF75FFC7E7E60FFC762
+:10AC700081DF0D8A0C7C8FD281E74C307FE753CE89
+:10AC800007FBCD77A72CAD4E9918A897636EA6A2A7
+:10AC90005FA1AF9743F49D0B3ADFACD57BBCEA9D37
+:10ACA000ABE2B9B98571163A4F9B6B199587762B34
+:10ACB00023D15D9D42751F5B6EA14914EF4457443B
+:10ACC00080CFADCC3919F11CA8D7E3DF4F1A38CFAC
+:10ACD00094C0E8FC9FD5CCEB199F01B9C0EF178158
+:10ACE00054A958D7C29E28A1FAC7A7A22D0E3C8707
+:10ACF000604678AD01781B2DA2EE475777D96833AF
+:10AD0000D0F7381B59389DE79E15E6FE1EAEFFB101
+:10AD100088623A2F9DB56D5A12F983B0DE69DA7AEE
+:10AD20000D83EB10B1FE0F9FD3D7FF69EBC2E3EBAE
+:10AD3000F85EBBC097B64EBB76DEC7A9849CF7D140
+:10AD4000D6FF4C385FA71177E2D3E85915F5837E1B
+:10AD50007D1A3FFC3FDDFB356D605C0000000000AC
+:10AD600000000000000000001F8B08000000000031
+:10AD7000000BBB26CBC0F0A31E815964181826F126
+:10AD8000A18AD112CFE066607804C42C3C0C0C85FB
+:10AD9000407B23807424101F01E2A340ACC2CBC0CF
+:10ADA000100BC471403C07C89F0BC4A5409C05759F
+:10ADB000632B0B03433B107702713710EB303330BA
+:10ADC000E832136F7FB10803C31309045F5112689F
+:10ADD000A734FDFC3FD8F00C7DFADAC76DC0C0B0D7
+:10ADE000D402C11703B29759A0AA596E81DF8C15FE
+:10ADF00068F22BD1F8ABF0E8DFA787CAD7D340734E
+:10AE00009F160383155298E86BE0770B3ACE04EA5D
+:10AE1000CD0262009F3090CD68030000000000006A
+:10AE200000000000000000001F8B08000000000070
+:10AE3000000BE57D0B7854D5B5F03E731EF3C8CCFE
+:10AE40006412420810C2092FA30D382121058AED92
+:10AE50001020A2458D8F2A54D4098F24E435011F78
+:10AE6000176BDB0C04232068B058A2463B4150F01E
+:10AE7000061D6890200107B01A7A7D04AFF5D1F65F
+:10AE80007A8352400824E20BBD6DFDF75A7B9FCCBC
+:10AE900039273340FFF6FF6FFFFBC7AF3DEC73F67A
+:10AEA00063EDF5DA6BADBDF61E990C24D20F08F9EF
+:10AEB00016FEE873A644087DD5F774BE4254924846
+:10AEC000487D0E2DA710923E8A84884048410D2D62
+:10AED000E711F2D06D2464CD2464FFEB16FCBECAEA
+:10AEE000CFCAB45DD87239FD3E9ABD7F2C8BB6A314
+:10AEF000EF1F3B2762BBE02C12DA4CCB4984F636BD
+:10AF000092D021FCF82CF036D8C7D2FA4DB7598828
+:10AF10005525E4513A0C9944888BF8EC84365D351C
+:10AF20008AF5F7C82CCB33A2001F2369F36979F5A2
+:10AF3000F492FCD5B4B446667035CE29792648FB28
+:10AF4000F75846E23C68BDC79CB4DEC3EF9792D584
+:10AF5000B4DD86B916A1249BD66B566687B2A3F3DF
+:10AF6000D79E7389C4DB05AD9689F0F4F1674481FF
+:10AF7000E72FA658709CB5350C1FB49E624923A4D8
+:10AF8000B5F380CD4FFB5B5BD97AB8907E7F709430
+:10AF9000C54B31481EEC3C60BF848E1FCCB3784754
+:10AFA000D3DAE95244F038A3E34D2214F009B49EF9
+:10AFB00077874D75F6AF4FFB9D0AF35E43F12E6622
+:10AFC00046DB8D073869BBB59464613AEE2F65EFB7
+:10AFD0002118F797D7240B4112AD77150009F5E634
+:10AFE0005A4884D62352AF8DD071564F79DB369AAA
+:10AFF000D65F5D64814990B55EEDBBD74EA0BF19A9
+:10B00000630E8D02BA5E45BFC33CB21F990DF37E3D
+:10B0100078BA4200FFBF14683D8AE2C662E5870045
+:10B020009FAB8678E03D7DFA62E1B54DB0211C64AE
+:10B03000CD0642F20980807FAB7DA1952380BFF2CF
+:10B040008817CAE95EDADED9BF7D976045BA34CA8F
+:10B05000C1C180BF78F41BC5F1B93A6B891DE841C5
+:10B0600048435AD15842D6039E6050C9AF5EEF8A1A
+:10B07000D65F2930FCAC93894FA0F34BC85342CB29
+:10B08000289E2DD99E39305FA75F2157D2F22A2101
+:10B09000385804BA8C55C86615F9C23E9A96D75EE0
+:10B0A0009AEC05FEAB17C269127CBF867EA75D1EB7
+:10B0B000281A3F07F8B3C9AB203F53FE3904F85EA6
+:10B0C000EB4F26AB55FCDE89ED9DA33C56C40485B1
+:10B0D00087E26500E525C06BCE75F5578D04FA4C07
+:10B0E000B0788042AB85A9EA7C909F249B07C697E5
+:10B0F00027DC80F49307260B4447EF9F03BD299E6E
+:10B100006AD5A29FC3BC9EC8FB286934ADBF26E7A1
+:10B11000C546A0D393F7D8907E4F4EE85C0C72F5ED
+:10B12000D8B9DCF7FD28978A7733EDE7A99C6399B6
+:10B13000840EF8C8CC8F92007FC34635DC49DCF41E
+:10B1400039ABB7968CA3F09186A20599C827C28D1A
+:10B1500014AFC3962A44B5315A7E4BE03BF185B318
+:10B1600059D949E7338CD3B9B5F36D5B31F43797CF
+:10B1700044C6B8F1BD2D3539AA6786E591482AED58
+:10B18000FFB185AFA29C3F7959AA97C9791AF24BB2
+:10B1900006EF271DEA53FD926623C104FA1CD6D19F
+:10B1A0007B03C0352CEBD85C8073FF1BAF0A40B724
+:10B1B000A7C6A5AAA08F92FC9DA48BD27D58F6BBF2
+:10B1C000F7413D97339456948DF5FF82ED4CF03F57
+:10B1D000A9FA3601DEB6093587803EC11C8B97D1AE
+:10B1E0009BE9C13577A586408F0C73FCF17A710419
+:10B1F000F20121A9143E0F4139A91722B691D0EED0
+:10B200005ED66E38090980E76159C1C5A21BEAFB09
+:10B21000852257FF715B4123827C504E077EDDAE55
+:10B2200090F2A21872F03297E77A81CC467E26D24D
+:10B230005F816F862731BED1CA4F013C74DCEDAF10
+:10B2400024FF309BC2F3ABA52372440ACF43D02E18
+:10B2500086DCACE572E0E8204181E275FF6F7F6B30
+:10B2600007BC6DB79032A83F352B6CEBE274057AC2
+:10B270002C24ACFFA6EC8D36D4174216F2DDC28921
+:10B280008ACF3E0EE46FB9E0A7EDD33C4C2FBBBC98
+:10B290004A08F4B22B2D2858283C6A36F16CCC644D
+:10B2A000DD0529FEE6C13F80D125567FCDDAA4D049
+:10B2B0006AFA7D5E361534C01BC595858EBB80B09D
+:10B2C00079CEF3D62F06FA115264017CAEF630FA2D
+:10B2D00034C138742A4DE9AC9FB57793D072E0231E
+:10B2E0000F6B3F0A9A50BA8DCA7BF15F04DA6F3A4E
+:10B2F0006F07720FED12D242360B6DA7D65808C2F7
+:10B3000027450E0940F7B1A92AC0D394E6FDF759A5
+:10B3100000FF6CC9BB917E1E0570D07E9A6A2C3EE0
+:10B32000D417794A33E8E9D53EA6E7357C65F27152
+:10B33000D3BD1181CE9D64523D8978F245EC1E2823
+:10B3400067337832F3D8BCFAE01FAB8496D3C6E9F2
+:10B35000B608817A1A1E4A787F257C1ECEB4D04A60
+:10B3600009E0CE6370D37519E149CF569A410ED2E8
+:10B37000D3587F2AC58F867780CBA1C19547EB83B1
+:10B380001EF62ACDC00A0E0E5F49368367FFEB6FAB
+:10B390007708AC3F942B0787D7C1E74F00DE54AE48
+:10B3A000D7697F2D72441069FDD004A26E64A3A9F1
+:10B3B000527EF4FB2335140FB4E0E4E390F5569489
+:10B3C00007FA2AF82DE583F90DB49C15958FD12B3A
+:10B3D000AD067971F27993062647946D22D02E93AB
+:10B3E000B0B205CA741E25594639235E5D99C2E183
+:10B3F000027EA7FA67D92485F1CFA5CC8E214457C8
+:10B400000FF87C82FAF41AFCAEE0BA9EF153C50044
+:10B41000DFB09AD40211F449C7E3375880AFEE2267
+:10B42000163111F959E8D35F74BC1D4B227698A4EC
+:10B43000A3A32819F09651935CA0001E3BFC5876FC
+:10B4400074D4F8F0094BD378428610DD3899A05FA8
+:10B450003D152D14AFA4460983BE9EA087937ECFD1
+:10B4600078A5E17AA0D7038B5F1D0CF29B6A6A3F37
+:10B47000CE3202E574D82BB4168E7FEC67507F1560
+:10B48000D7270E80783C3E5F81E73027D5B3544FF5
+:10B490006750042BE3A3FA62F5A5EFE6F89D9C7FC5
+:10B4A00092F11981A759AFE8EA5FCAEB0785F3D695
+:10B4B0003B86F53478CCDFCF0816D4532EB0332931
+:10B4C0007E1F269E39B82E7B2DB82E26F0F761EF11
+:10B4D0008102A4679878854CD0B77FB5EAF9E02758
+:10B4E000F012F4AD14463951321C681F52394E80A7
+:10B4F00075AF49AA2983F7E1740701BD7060C6AB37
+:10B5000002E033BDCD3F1CE450B3730BBCE1347893
+:10B51000FFE021FF25289F71EC46CD4E34CF67E830
+:10B5200015CB511F0CF7F776C07AEFAC94BC5702DD
+:10B530007FF9295C4ED4932AF92E85DF1B5C067AAD
+:10B5400056F5D3F220FAACE4CF32F67D556D59EEC4
+:10B550005129DAEFAA51D41EA57A717DE77ADB353D
+:10B560006067D45854E0DBB5DEB76D3E27940B0618
+:10B57000009E5B8B34BB2F22C078E9EFF8D0CE9BC6
+:10B58000E0513CA0B4C65A23833DBAF5A269C6BBBC
+:10B59000E3010E721325E2E0F874A4F3453E8BB785
+:10B5A0009E002C16DD3AB23F6B07AE2F6F904B9189
+:10B5B0002EDABAA2AD23D823D52FF3B91C3DA88625
+:10B5C0006D02EA2B2ABB943EF3B91E7172BD49F598
+:10B5D00030D3737C3D59BB3815D7134D7F826D0D29
+:10B5E0004A623ED7B76B739E49BA86C2E4043D0BEC
+:10B5F0007A298D14C0FA3B1AF40CE8272928C07860
+:10B600004D133C6435AE63467D3ABA86E9C107D333
+:10B6100008F2135D879A61BD6B4A0FA7413F4D3514
+:10B620000704BF6EFDD4D63B574D27013D382F8F01
+:10B63000AD73F3B2D978BF07044D60F0825E35AFC9
+:10B640007BBF98B203956502B7B7CCF8172CCC0E28
+:10B650007C78D6DB88C7B50B1EC12769D880FDA5CD
+:10B66000D9180D56651DC0F76BFC96996077AF979A
+:10B670003A578EA2F0AF9F394F09D2EF6BBCCCEF97
+:10B680005A3D65DE33B0AE592D0A83ABA60CEDD51D
+:10B69000040ED706E81BFD4405FDA2BB6FDBB872A4
+:10B6A00004ED278DFA31820A9542362BFDEE049A7D
+:10B6B00082FEF64718FC5E524062C0FF1F8283F98B
+:10B6C000A1FECE8ED1484F8B07E04DF0F6DAC04F89
+:10B6D00054A91FA6AA00AF6A1F8BF05A3CCBD468AE
+:10B6E000FBDF717FE17658F8C1BE9FF3EE4C90AF5F
+:10B6F00075B731BFCC0CFFDD53431D161C87A05B13
+:10B70000E78A83D7B9A0C140FF784308972B8BC144
+:10B71000755460F47AB8B3E02AF4938AE87BDAD1FE
+:10B72000239D23EC20DFFDECCC840F73D0DE31AD04
+:10B7300033172A0F33E9FBB1D6F0D5C86FDB2CA83D
+:10B74000A708617A4E2016F5DB91B08830B890F5E5
+:10B75000A8FE5E2147E62CA0F557EC7412C097C6F0
+:10B760000FE9BCCFD535940F62CCBB4310E3D19D1C
+:10B77000D9199CEE9D30DEC00BD39F4AB31DECB6A9
+:10B7800070A87E4839F81F35CCDF0D470EA0FE4962
+:10B790009F7E33FA295B9A53E72C00BECAF27901E7
+:10B7A0001D1A3C609FC4F213AFB6D8CEEBBFC7D30F
+:10B7B000C38D952BD0EF6DEC8C3DFF2916E66F877E
+:10B7C000A99EF466C71F3FDFC2ECE8240BE7BB1954
+:10B7D000AFA6E9D7336D5DD5D6D96112098ABAF51E
+:10B7E000F0268E3FF3BA49A406DB18C6E7E83F36D9
+:10B7F0002E6071880D532C185FD1F89CD64B03BC7A
+:10B80000D279A03D47F93004F6DCC3A401E526480F
+:10B81000DB6F26FDE1BE8D582E6A7E93F9FCFAC6D9
+:10B82000E3FEF5ED5C5FADCBB9C70E5DD1F1D28023
+:10B830003F026EA627AB5CCC8E9DB6538EFC80C2B9
+:10B8400051D52CA09D65D9674738CF6CA265DA75B4
+:10B85000C4A560FDD31E1B9603D6CE87BE47CBBDC5
+:10B860003B4582766496C302FC7A8CF32BC9A365B0
+:10B87000B087EDAC58D5BCFF76E8AFACCD4AECB4A0
+:10B88000FFAADDA5D77E8F964B3B640255AA362FC3
+:10B890005386D0F2A2901086724F015DA8002FC986
+:10B8A0004A08FCF61E7767EA8FE8BC4FD6DA884A6A
+:10B8B00041A97375A6DE44F1511EDA5E08EDCA5B3C
+:10B8C00004D088741E9B5F1D0CF3DA2A78C1BFAFC9
+:10B8D000D89260B0078FD1A9FC807E5F42E70972E1
+:10B8E000594A1A0A619DABDABC4E5175F18793B57E
+:10B8F0001E1C472B576DA5E3D076D5CF0B5E986203
+:10B90000B585F8410F9DD96D9FFDB413E6B74C196D
+:10B91000E382793DA040BDD250F18B7615E06B56A5
+:10B920000AE9F7F2A66605E25B012BB903FCDC8AA3
+:10B930002D038C70358A28AF4B926C1B419F13A747
+:10B940002FED86B1FDE97CB296EAD831D17239E8A3
+:10B9500043E4C39072BDAEFE703109F9B5628B68E5
+:10B96000B4B3F9FA1F3CCCE81FDCEBC2B89F46BF6A
+:10B9700025DC5FD6E8B72489D353EACD8F05CF43C2
+:10B98000400F0A4F03E08B3ED770F8DC53C8548851
+:10B99000BBB87DC423C4E06BF3B34126C5C0BAFF76
+:10B9A000BAFCFAA9D260741F1643E4C9B362CED4BC
+:10B9B000E9B4FC3B4BD1660BEA0FAF0A72A4F9D98C
+:10B9C0004F59985CD60F56107F0D33F29F66F109E0
+:10B9D00082EB5EC38C9267C02EA0EDB759500E6902
+:10B9E000FBB1F1DB7B0A271ADA7B0ACBB4F63BB159
+:10B9F000BDEDFCED1B0A271BC72F2CD7DAEF45F84E
+:10BA00009DE787DF73E514E3F8575662FB8095D115
+:10BA1000AB37C98676CD0ABBD727313B2A02EFA5C3
+:10BA2000E4311BA19EA8F103E9F481FDED6C491AF4
+:10BA3000BF9AE8F9A2E00D80C345A545CF17891349
+:10BA40001D067E4CF2251BCAB427CFB1EFF0320C95
+:10BA5000E2B6213CCA1005F5C5D4213684F79E7D97
+:10BA6000762CDF3399C17BCF1027CA19AE2D948E67
+:10BA7000F728FECBF5762BAC4C104A7A53F47F04B2
+:10BA8000F88DBE572DF0DE21921AD4CF5682FAE8F7
+:10BA900081CCFCA7833AFCAC1C46E94BCBA7C1FE8A
+:10BAA0001918C5EB03C34AD28A75E3D40F53666FE6
+:10BAB000CC66EFE73B61BCA21EC04340E91D0376A4
+:10BAC000A5791CEB888986716C196538CE37A6710B
+:10BAD000AC1965A6716CB337F2F77C9C3FC3BCE22E
+:10BAE0008DF3C088C9C6F96494E33856D1349F8C6D
+:10BAF00072D3380E361FFA9E8F6317CF379F91533C
+:10BB00008CF3195E89E3A4888A216E651D5E691A2B
+:10BB1000C789E3C07B1887A433FF46B1F69620FDA2
+:10BB20005FB613B0A715ABFF59E897FCC14E509F05
+:10BB3000A874DC41A0579271BFE03F2CC9389F2FF9
+:10BB40001D94FE4E3D9D839A5D80F6CE420E2209E5
+:10BB5000D5A37F5ECD797441CBF519CBE0D9362DD5
+:10BB6000AD18FCECF52E2FC44FCFB44D53E6C7B043
+:10BB70000B1636C8C7BA0CFCCBF55E01C9AA013F4B
+:10BB80008BDB015AF918D55F84EAAD8FA8FE82E7F6
+:10BB90007199EA69FAFE28D56F44D1C3BB0CDB1D4D
+:10BBA00093181E8F35B175E4CB7587658CF305C985
+:10BBB0003B59741E37F3692C6C4860BE028723C062
+:10BBC000E9D1BBDB1ADA88F4F00D05BB87340EA08F
+:10BBD000B8E2F54600BEA8B824637128D8473F5E96
+:10BBE000B9FD3750ED5DA178D8123ADFD9ADEBE45D
+:10BBF000A1B47C46EEBADDEBD4F5335BFE08E66D0E
+:10BC0000A3FF413F73FCB4AC1BFFD63263F936226D
+:10BC100045CB946E33C4119C1E7C5C352403BD6EF1
+:10BC20004E65F0DC06CFF1F0D983F4BADDC3DA6AF1
+:10BC3000F004EE934904D7A3AE81CCB81D88F5FC7F
+:10BC4000DABA6282EF76D9E62BA2F4BCFD5E11F17E
+:10BC50006886B76B5F82CF42FDAAAEC6CF64F02F75
+:10BC60002F04FF1D4B8DDF49908DA7E155E3835BCA
+:10BC7000664F1D7054576F8EFFAA014775FC726B9B
+:10BC8000D9F586F26D35730CF5EF585A6CF85E1CD9
+:10BC90005C64F83E7FE562437961C3BD86FAA58D99
+:10BCA000CB0CDF17855619BE576C59672857851F6F
+:10BCB00033D40FB4351BBE5BF65D7A1DC863DDEF70
+:10BCC0004402F6D917CE630F817DF5855342BFAA92
+:10BCD0001A788DCAE189DA34E4EF93B52A3ECFB4FD
+:10BCE000E5E2FE58C041E599AEF51BEA0E2D5B3941
+:10BCF00005F408AD4F75F813756F2D0B52DF7D23DA
+:10BD000004A929DF8B8D0A890C003F26B98FAF7BF0
+:10BD100045DDF7AE0B7C6FA40B566EFFEF6257EC60
+:10BD2000F73D42EF18B0EF821F5871FF269EFD408D
+:10BD3000FF869218FE83F6EC86F8864EEFBC2C3216
+:10BD4000BBFA72B1E065913E2B1526EF953B0617C5
+:10BD500040BCA052898CA9896167F78D17A6C00CD9
+:10BD6000827E98BC2C0A0D8DCA2FD26FA441EEAFF3
+:10BD7000B1F8F7817EEEDE2FB2FD81C8C10CD8A7E5
+:10BD8000B95CF4BD0CEF49DB405C1FDFADF50D384D
+:10BD90003A8A90F76B67E2F3F7B54503207EF4C764
+:10BDA000DAD958FEB0D68FCFAEDA327C7E545B83C0
+:10BDB000DF8FD62EC5F2B1DA203E4FD4AEC4E7C92C
+:10BDC000DA06FCDE5DDB88E533B5217C6A72A0D93A
+:10BDD000A32485DB7FDC5EA72B0796CFF23988F49E
+:10BDE000DF9D28D7DE3490EBB3CE2FC7809D7BF646
+:10BDF0007D2B06D1E3E1C9CC6FF1E9E7C3F5BE24A1
+:10BE000044E99FDBFFBBDDC1E863B79099E09FADDC
+:10BE10001AAD1088AB3B5EFE0EDACBF4BD44505F2A
+:10BE200086BCFA7DC4BEFE61CE832E4C27ADFEB12A
+:10BE3000C7FF2B7F5E36D087D1D77150AC61747B42
+:10BE4000DA0B74D3E18FD9653BB93E37E151E27229
+:10BE500067C6E7E9811A3E3B3320DE522516592496
+:10BE6000FAEE6CAB15E775B63D81ED637B522E2A79
+:10BE70009E57B1C5EED1EB87AA7092C7A82F067B5B
+:10BE8000F4FAE26CC7D36E90FB256916CFD15CE063
+:10BE90000F1FE70FC6775AFF55E14C8FD3D08FB1F4
+:10BEA0007CB64198C9F615D5C49B62F807DA734988
+:10BEB0009AE2394AF5C2C92D2313615CEAC7796059
+:10BEC0009CEE5A8F878D9BE6D1F365E55207D6D756
+:10BED000E08BD7EF3F1A3ED8F1FBD8C6624D10A7D2
+:10BEE00089573F2E3DA4CF15F00F48BBFC25AC3B36
+:10BEF0008E2C6DDD91B0ACF51B088B41EBE5F0BEEF
+:10BF0000C5301E6DA76A3E34B48B4F77891CD3E8C9
+:10BF100049F5E4953C3F843233D2D94F7B4CA4FDA4
+:10BF2000F548CE9510E7CD9454D477011888F25394
+:10BF300095AD4BF1AB88EE4E8C7B4ED4E45EBDE507
+:10BF40000F94E53EF93719E319E4CFB477FA5DE6CB
+:10BF50005F179022373819F35A2B66819EFCC4A2D2
+:10BF6000D9030DF930EFD3C482FBF9A7C9DBEE5C2E
+:10BF70009D5D5626F1F8E44AB63E07E97F303F6AF8
+:10BF8000A719D6EBD24663B984DC900AF250B25EB0
+:10BF9000861D5BB208D67BDDBEC96CC983F32E2536
+:10BFA00035F560A7AC96D93EEA3C0F918652B8AA07
+:10BFB000763D990FF66C4062FA5EF39F172533B811
+:10BFC000CB53428A8F7EFFB835F7E6EF11681FAA80
+:10BFD00007BD1674116FAC78CCFC9546F82E04BFE3
+:10BFE000195E42961BE0D0FAD5E010B70831F33461
+:10BFF0007E26093CAEC3E463AD64B45F1FE178D034
+:10C00000CA1B4CE526537D8D4F64CE279992FF11B4
+:10C01000D03F55B6DE42B4D308E58FEC683D255AD3
+:10C020006FC3F9EA59A19E88F59AA409F1EBD9A347
+:10C03000FD35C7EAAF6AD7B61783949FCA5F78D435
+:10C040000D41DF4FA48654887F556EBEDF0D783AD0
+:10C050002105DD40EF4F4262CCB8E07B7DF8F2393C
+:10C0600005F02390B529DE9F7BF05AD0D75F6E96FE
+:10C07000312F26B0C51AB1523EAE6E5D340BE2F7D9
+:10C08000B47C84951FF814F60D036D467A963FFB39
+:10C09000682AC489282699BD4D226877546FFA53BF
+:10C0A00021E8F100E9453E34B783F1CF25A3DC1741
+:10C0B0002B89FDBF6BF90A012E6781D6073F85BC2E
+:10C0C0008480897FCAFAD6932E05E2081D922B053B
+:10C0D000FDF2EF92EF821ED0F04142CC9EA8DBBA77
+:10C0E00061DC110A4FF7A67F730B06BF9BF1E1D904
+:10C0F000F0FC5FBDA4C6D73367B83F146D17C27696
+:10C100006A1BB37F483B7B56CA1137D89B95CDB28B
+:10C11000977228A9DCF6F4338F839FF68115FDB45E
+:10C120008A6DBF7977322D576C975366B1E93885A0
+:10C13000D4285D02F47F4BC747E950FEEBDF28EAC5
+:10C1400058F6FEA7C9517A546CDFAF90B1FDF137B4
+:10C150002DBC5FE972C6A04BF84821D82B755BBF98
+:10C1600052C0EFFA649F400665F66F5FD6FC1B5C19
+:10C170000F014F48474EA73EBAF5A357E4DA97F2AE
+:10C18000B09E07F4643C7A3DC7F572D52E174982FC
+:10C19000F8E7EFADA15940C7E7EF74C33C8E4B35CC
+:10C1A0008CAF9FBC3F15F6FFCAE460AA079FEC7DE9
+:10C1B000D9537723BF950A35A96C1FD33798C7CBBE
+:10C1C00007C3FC1636FD08E75742FCC877654F8A5F
+:10C1D00045101FFE422233B7C7908B6B64B6FF74C5
+:10C1E0007CA31592FCC871B0F3C1BE7E5BC4382B32
+:10C1F000218B711FEC6E2D8E4B9660F90BBE2F3587
+:10C200004AB668FEA1CDC0AF9B1EE804FA9C1CE6AE
+:10C210001B0470523C0439BE04D8EF170FCF18C46A
+:10C22000E8C3F20DB01DD5FFD3E03DD4EF94719F6C
+:10C2300050D78EEB4B36FE5D7C7C0AB703D6B3E35A
+:10C24000A96CBFD23CBFA57C7EF4AF93E8F84B2726
+:10C25000DF4CDE37AD62F2ADC97BE8FA99F0FDF351
+:10C260007798FC403B583F285C9141F87DFF4D0298
+:10C27000EA032B89C492EB4D32976BE3F700955399
+:10C28000880B50B825C86788F209ED3F19F18F7EF9
+:10C2900049C97ADA4E679F05603CACA744DFEBD60C
+:10C2A0008F52AE0766CA46F9274D032FCA5EAC947B
+:10C2B00049104CCBCA0FACE877576E938B60DEA762
+:10C2C0005A0EBEFB63CAD7A7C29A9C1AF5A7594E4D
+:10C2D000CB766C16803FCD727AAA8CAED6B1E49440
+:10C2E000BE8F29A7655DFF57F4A786B780096F54F5
+:10C2F0000F0E4FB2C4C79F590FBA6435A61EA47F54
+:10C30000EF90FCFE7CA7F19BC667D4421B0EFABBE4
+:10C310008F1F357EEBE3478DDFCCF334E2CDFC7D20
+:10C3200032186A14AEA2DD32FA2595ED6CFF86B69E
+:10C330007B75681EE2C787CB17697875688ABE1C53
+:10C340003295C3A6FA3E53B9C854DF6F2AD718EA0C
+:10C3500057B61D54589251C450CFBAF471F2710CB3
+:10C36000FB5E5B6702AD9F2A41E087F45E05F49CAB
+:10C37000BC9C9A66103FDB2BA2BFD5A3F6BA93E90B
+:10C38000FBFBEDCC8FEDF1F072122BF70E54EA416E
+:10C39000CF69EF7BED2CCED953D4EB4ED2F9F747D2
+:10C3A000DA4537EC077785583E6A7F78EA506EBAEF
+:10C3B00048BCEF2C2E384374662C05FFAD41F48247
+:10C3C0006BB860D92D6ED877EB691F79DD6CFA7E7A
+:10C3D000E12111CC67D2E3708F03B848D0270DCE8E
+:10C3E000E7F913F4EF0409FE720AE44DB433FB7A63
+:10C3F000C11A933DECBC4BC1FCB2F5BAB8968EFFA6
+:10C40000CB793F654DC6EFE5640DF25FB9491EFC7F
+:10C41000DC1F38ACC9430EC961FBDB84F9B15CEFAA
+:10C42000CE10B3AF9B4DF1DED32162DEECD9769115
+:10C43000D4C33C5B04DCE724C1812857D5A417F59D
+:10C440009D86976E901B25BE3EEADEF91FF9F70127
+:10C450007FBCF887714FD067F78B1F8CD903E55DE0
+:10C46000EF65FC81F4AF3F6DDFD7B88FD8B3CF8ACB
+:10C4700071AE9E7DAF65DC07E597AC18E7EA596EB3
+:10C48000C57D94E03E5768347C1FC6FC81BABD5F11
+:10C490008D6379922B904E7F96993F72B6FDBF3E89
+:10C4A00084FC91B3ED74566017EC4B40B909BC6441
+:10C4B00047FFBB67EF57F97EE73F6E3ED50AF12392
+:10C4C000FFB9C8EC1DC0AF492C1E1CD833E969C8A0
+:10C4D0006FAE6ADDAF409C7DDACB7F19077AB26719
+:10C4E00007B377CEC85D4FC17E9855F974B94CF14A
+:10C4F0007C06846708214F2BE3A705B363E185E140
+:10C50000A187E201E645F15206FA3D1E3E32947FD4
+:10C51000567C7C7A3BD363DFC53CFB285E041F7BE3
+:10C52000EF0AD9049C3F7BBFEFAB71A0674E8597A4
+:10C53000A13D72A1795FA1B07D96FF39F316221754
+:10C5400033EFB9FFB4F466FCFF11ACAF03FBCB4192
+:10C550007F3EDF750F969F777911DE8B94FF9FFEEC
+:10C560004FA3FB0E4A77F785E9FEC43FEDBC2F448D
+:10C57000F7439CEE2E0FEC2FF7ECFD0BC64DB5F9F3
+:10C580005F68DE2FFD3F3A6FCD5E7FCDA2BE934345
+:10C59000EB1F220DEF8C11207FF1E0613802562055
+:10C5A00090A258F6C84985C53F0A049627489204C8
+:10C5B000EEDF31BF6828B71386DE558276C6D0F429
+:10C5C000B5681F10495D0FFB71AF65CCF7B27CB049
+:10C5D000F1780EE535CF15BC6CF40F9F10880FF283
+:10C5E000868766FCB003ECD5F47411ED59FA443B30
+:10C5F000F615F74CF6BE5231F84557115D99CEABA2
+:10C6000030C5E8FF4CE7FDCD2023DEC9A1F0CFB057
+:10C61000C99E1045D15553FD12CCE7AAC10269D07D
+:10C62000ED074D37F949AF825FAB8B97FDADF84B06
+:10C63000B7323FB24018B1BE08F0374CC478E005BD
+:10C64000F14758FED76B9E1C96D72A7919FE92ABFC
+:10C65000BC184FE57E338405C05E919CF59D20B7E4
+:10C6600012A17E2F831FFD65CDEF8D8767C2FD6808
+:10C67000890FA9E15D4A17315F55D71FE243A3C770
+:10C68000DF4A078D7E7F2F3DCE98E891FEB94702A5
+:10C69000F99CC6EDFFE99F778A584EF74AB81FC547
+:10C6A000EDFFA9CE2409ECFF2BA4C322C865A9ADD8
+:10C6B000ED6A88D3DBBC02F2F525DD16F46F6C79E8
+:10C6C00002E23DAB51C2F2618B670218DAD77E6F8E
+:10C6D000D7A97B09C4877D0A1ADEA488C5E7FFFCB9
+:10C6E000EDB753B4F31AF89D906BA8FFB5A0894439
+:10C6F0001C144F0B25124C4C86F8AE403E32C477CA
+:10C700008D65F8FB7E6AB49F0BD58FA747FED1CF0E
+:10C710005D546F7D449963373C715F85B284CE3F31
+:10C72000FE6E3BC357E075121A8171059F58A4DB5A
+:10C73000377BD0CAF4C7AE3FEEC885B8D8D49EECDC
+:10C7400044A64F47A15F10E07EC159A22642FEC118
+:10C75000D9F69189B82FD821BAFC31E2325BB9FF02
+:10C76000FCAF904F419F3D9B48039CC3E821BD18FF
+:10C770008F0D6EB2C5DCDFBDC7AAC59B38DDE89F53
+:10C78000A89D3752315F2498A8A75BF7AC4FA471DE
+:10C79000FDE9007F1FE9F64BFE5EFC82BF0EF8DD6F
+:10C7A0006AEF2A8C751E6C25C7DFB507BEC638E652
+:10C7B00065EDCD16E0DFCB36590CFB8D412BF7BB79
+:10C7C000C693F100D7B507ECAE3CA04B87E885FCDB
+:10C7D000C140FBA78A3FC6BE95199FD03FC4C5F78D
+:10C7E00059599C7F8F1C9E0F78DD73DA86F939BB0F
+:10C7F00095868A58705E62677A6E2109DF392EF35A
+:10C800009F0FBF537B9C9102F03337111EC730F34B
+:10C810001F413E3EBB85E0F950F04B412F9C6D61BE
+:10C82000E780294AD6823F4DE5FD07FAB8CC256D51
+:10C83000DBFF15EC80EA76C103A9B3D5529702F16C
+:10C84000D6405B9208EB6E8EAAE5557AC6DEA493BD
+:10C850008B7D56966F7C70F29E5B61DCCFBA1502C1
+:10C86000F688EF955E37ACDB9FB5E726C6CA9BD747
+:10C870009EBFAE25574F97A01F827837F343768B24
+:10C88000C350FE9EE81F02F275ADB5EB2E6F0CFA99
+:10C89000F96D8CCF2E5ABF85FE3FD36FEF68FACD6E
+:10C8A0002F16E9E428CBD64FBF0D8AA5DF9608EAFC
+:10C8B00020C0FB92BD2307015D971C9207C6D26F73
+:10C8C000DB6AD97EDE0B3C1FB6A795EAB7CB75FABB
+:10C8D000ADD5867971E676C9360B5F172FA0DF429A
+:10C8E000FF3DF2B70DF45B8CF98EB631BDA1E9B70F
+:10C8F00071ED4750BF8D6BB518F246D36D17D26FEF
+:10C90000C2C09BC01EEE90BD0931F8671BB7BF5F68
+:10C91000E07978300EE8B95B6D6C7FF362F55CB658
+:10C920009DD1FB827AEEBF09CF9A9E5BB2533BE763
+:10C9300068E643A6E796ECA67A4E007E647A6EC956
+:10C940005E768F8359BF65F5D36F04EB574758FB6D
+:10C95000405BE686B9B4BFF13ED96BA3F5C747F596
+:10C96000DD04BDBEBBD5C6EE5DE8A7EF3A2E4EDFB7
+:10C97000EDE4FA8EEAB111A05FCDFCE16D37E61D62
+:10C98000EF9974BCE5D7202F6F88B86F78989F4BCC
+:10C990007B73D2F13CE0AF161BD3BF759CFFCED4A6
+:10C9A00006B1FF69AFB0F95539593E72752BB30F17
+:10C9B000AB5B84904AFF5938F96B05E05FB45720B0
+:10C9C0008368F97A2BAB4F9ED5F6BDC8AC1C1D3FD2
+:10C9D0002C98588171FB0512B1415CBEC259F8090F
+:10C9E000D8BF1513591CBF82BF5F74A8AB1EE2D914
+:10C9F0008B1E1370DF93F07C002DBFB1B47D19C680
+:10CA00006BCD79019A3E5F1432BEAF30E53336F319
+:10CA1000795E2F76215EC85B62CCBC8466333E3A79
+:10CA2000383E3689B86EF6E183E247CDEC8F0F4A87
+:10CA3000D15939A9D1F92F7A83CE2B2F3A2F0D1F37
+:10CA4000E6F96971E70ADE2EDE7C35FCF59BAF86E0
+:10CA50004FD3BC9F06BD010A2187E4425E0CE5036B
+:10CA6000D41BC1DF8A787EBF68EAE8417A3DBC9575
+:10CA7000EBF3DC86A9D30613C017A901BE29695CB4
+:10CA8000FCEA603AEF09EFABE36179FCDE64AB1FCF
+:10CA9000F647B7DA7B51AF697CF50DE7AB77391E06
+:10CAA000F70CA9C173AA8136C1037645206247FC01
+:10CAB0000528FEE0FC4A809F5F0C50FE02793AF8A0
+:10CAC000D8970C5F7B0515E2E385DAFA03F8A7F542
+:10CAD00073DB19FE032101F19F477A717FA4BA51DC
+:10CAE000F04668FDEAB6C598F7A0E95BFAE7D4D34B
+:10CAF00043C78F522C7EC44ABAF5AF82D7BBD6DA71
+:10CB0000F02EF0E7B5CFCAA459C79F59F4BF6F63A1
+:10CB1000D049C3E785F8F21CC7D336C0A313F0D5BC
+:10CB2000CBECA7C8D7788E46FB1E9082063C4E7B86
+:10CB3000FCDC79F13441C313F029E8A9F66211CA8B
+:10CB4000256D021990D97F9EB03FA997DB457B8F59
+:10CB5000B0FE9F14F0DE1233DF6AF3EEC7B771F850
+:10CB600015CEA5815F74B17CFB8D896FDFB4F7BEF4
+:10CB70009E0B7CBB5760F183F624C3FEE2103B5B47
+:10CB8000FFB7DA297FC3BED621D9BB51ED2FDF090C
+:10CB90007CFD02BB5F7F2EE9529808E43D6EB161D7
+:10CBA0001E19C23182D9957ABDBACD4E06DE9417D0
+:10CBB000BFFFC1BCFF78768D561E0BE341BE571BED
+:10CBC0001D2F2B3A9E59AF6B7EFE85E635E6EF9C16
+:10CBD000575F1E26E9C47DA74CC9FFB0559707775C
+:10CBE00033CF33A210A07DA5AB976D3B4F3D92E6AE
+:10CBF000C1F34F777A343E63F9EE453C8F7D86383A
+:10CC0000E53D583F3FF3B17DBE3C0BF9DD14D0CF7D
+:10CC100005329EE3FBEC7519E3B59F4D67799CD710
+:10CC2000BD71508238CD75A09C283EAE9B20A0BF20
+:10CC300002C7B060DF6C17B56F7C63703EB9708E51
+:10CC40002B6753C334387F3C7E4BA80E9EDE69BDF4
+:10CC5000296F021EA78A04F0D8E91B300DEE4FBAE7
+:10CC6000F34F04EF0FA1EB2CB61FDF410642BDC905
+:10CC7000BE81E80E4C6A5D3F0DE2A3D71F743AE116
+:10CC80007E96AC260BF519A2F89B4C4275B0DF3EA0
+:10CC9000E9A8EF4680B78CDA0B10772E6B6FAE7376
+:10CCA00043B949F0AAB4FF40D05FE8A6F3D8D6F85C
+:10CCB00069E177401E693DE826D0C4EA0536C1C562
+:10CCC00043F07E1DE6D9946C12F0E0D7B690406C2C
+:10CCD000ACDF908DF6BBAD89B6CF837582B6877E0B
+:10CCE000377DFACE8D20EFAF8BAC7D0BDBA72EA16D
+:10CCF000ED54E0DB4D8BB1BF454D0249A3FD95B529
+:10CD0000B075A0EC75D90BDF5BF73F86EBD82C3AFA
+:10CD1000DEE04CD0FB91E95026B98207CFA1548EBA
+:10CD200041BAF5703927534633FD21F032F71B34F1
+:10CD3000BBE95D3BCBF72DF12E5306D07EDE9C3850
+:10CD40003013D202026D9FE2FEF3518A673FEDF28B
+:10CD500030CFDB3838F163A54BB70E7D6667F75BE4
+:10CD60002D689B8AF90C0B4911E6335C3B89D96B22
+:10CD70006F5D610FC115076FC9BDE9F0FEE0155683
+:10CD8000B47FCF6C93918FCE0CEBC2F8F4F12619DF
+:10CD9000CF0DD735B1FBB98EB7B0755C7C92EDEB9A
+:10CDA00097BA142C1F6CBAB110D6B7E39BD879C7C9
+:10CDB000694FCE50A05CDA2C78D9FD454C3F6AFE15
+:10CDC0005B8987E52368FAAF8ACFBB5FDEA249DFC4
+:10CDD0005569EB8D49DF55C1BEB21B9EC6F701E216
+:10CDE000647A10EC7EA07BE46BE4DFEAD765027620
+:10CDF000BFF0717721E663ED15309E3FA95DF0C16C
+:10CE0000BE7ED9FBD610DAABA1E23B7E027AFC03F0
+:10CE10002B1154C86BA778A7FA61A2B5F78FBFA0F2
+:10CE2000EF3F396C834C18CA27C588672DFF336FD5
+:10CE300033CB63C93BBC3E15CE5B92E90350DF9612
+:10CE4000368AC4AFD31B9F08BE1B7FCCF432DE4FA3
+:10CE5000A1D12F4F692881756CA483E92575B30C86
+:10CE60003922E4108F93507B1ACFDF2EDABD2E5576
+:10CE7000A1F5EA79FEC7A2BDEB5245FABE0ED62F48
+:10CE80005A7F91C2FA5FB44FF034EBFAD7DA6BFDF8
+:10CE900069FD28BB8DFD8CDCCBCB17D98F0687367F
+:10CEA0007E3C7B7CE2BF9F5B0FF7C54C7C4BC4A4F0
+:10CEB000E3891FCF1AA9DFEFD09E5AFC35FF1D0B67
+:10CEC000F1E9F036F18F0EE2D3F145EB042ADF945D
+:10CED0006ED7B4092100A575C211A52A0FCB1E90EB
+:10CEE000E76A1EA7AD9ECEF6AD5A730EAF00F99E4F
+:10CEF0009527201F90A05F19908276900AF1F1D2B9
+:10CF00003CD6BE94B607B96B7D8CC921D5072AE8FB
+:10CF10008BEAA67585587F93A042FFADCDC5B8DEDC
+:10CF2000974D14097EDF7404ED8FB2B6232920AF2C
+:10CF3000543ED7C3FA5B3DC58AF7796972A7C9F138
+:10CF40005B32BFAFC9E6190B79FDF7015031E457E9
+:10CF50007C9D303FB54546390B4C6472F9D636118D
+:10CF6000E5F9E015B7A01C9ED92CC491E3690A9C91
+:10CF70004B3E1E62DFFBE478ABC0E598E987E34EE9
+:10CF800026D7D3E03BC8F14E81FB83CC1E34CBB116
+:10CF900026971792DF8A2D26798E23B79D52D74D7B
+:10CFA00030EE9D57D811EE69DFDFFDEE9DA87F645E
+:10CFB000CCFB98F6FD7B5341DF95482C5F49C3635A
+:10CFC00095C4F2D9FAC1B17E9932F8A2E031C2F12A
+:10CFD00084DD15D51F22F039BB872BB849463E3773
+:10CFE000CBE1DF2B3FFF28793EC4F9478347DCCBF9
+:10CFF000DA43FE5884E2E9B596A7314FF5F473475A
+:10D00000AE053C57ECA17C4BE77BA6C5C5EF7B0981
+:10D01000E13A53DE2A621E389122F937BAF472C916
+:10D02000F2902A5E70217F94EF60F9A4E52F7E3C98
+:10D030000EF34496F7627E55F0396E6F06BBC6015B
+:10D040005F974B2C1FCA2CE7373998FDD9BD3B6140
+:10D0500036CC43D8C2CEE997876F91810FB57A3F1E
+:10D0600074C85A3DDCBF0C52BE85FD75804F7FEE03
+:10D070005CCB83EADECAE4BEBC4D467FA97C4B3361
+:10D08000C6B1035B3EC53CF7692F6CC3F841A04DA8
+:10D0900034E63D6E112356CCCB148F58D93A65C86F
+:10D0A0003FAC6EADC2FDB6EA30CFEF33E5BF55BC45
+:10D0B000B0F7C520454DC5AF9F75831E38D9B9D986
+:10D0C0000DF8A4FD61DEE0F73F970C7951F1F37B99
+:10D0D0007DC67CC2F0AA98F98427E11F94C1EF7540
+:10D0E000707ED5F230B70CE079DA91FCA218F1FB32
+:10D0F000BE733BDBBE780AF2DCBB779C7A0AE0AEFB
+:10D10000FCEB674F413E13D967C77529F0DCEF3060
+:10D110004F586BF70B07F7F3B73E8BF9D5673EB067
+:10D12000A29F7366EFF10CC85F3BB3FDEB5488C759
+:10D13000DDB57706C62BEFDA396D1089A1DFB5278B
+:10D14000F065E822F2BBCD7438D87A10F3AE4EBF4A
+:10D150006F457DD697171AAE6279B62ACF076D89CB
+:10D160009D47AFE53156B7DE78DD15A09F5B993D51
+:10D17000D797D778A13CD077283D2FBF08BAB5F014
+:10D180003C5F13DD4EC33F287DC226BA7DD1BAF085
+:10D19000578FC3B7D60171F3402317812F2D4FFF4F
+:10D1A000E70EDF1E079CFBDB91104C63F40ACD12E7
+:10D1B000C0DEFB2203CE359C907B31DFA377AFD559
+:10D1C00003F98CE57BDF43F938B3F330C65509CF5B
+:10D1D000933F43FAFE585EB3C0E7B7C9C5F247397B
+:10D1E000DE21BF5475E37B9E47CAF856CB2F8D973F
+:10D1F00057DAEB18C1E2D0FCDC4015F593F8BD59C5
+:10D200007DF9A6C244A0D311439EAE366F737F1E34
+:10D21000AE37A3F9D1B1F376B57CC1289DD83AA237
+:10D22000E53F9F69E679D3F47DFA78C88363EB75AF
+:10D230002024BC4762C8A3961F7DCA61CA8B0E5DBD
+:10D240005C5EF485E0FDDFC5C7870E16AFD6F0D271
+:10D25000FDE7D8FA5849607627F54FE504DC1760FA
+:10D26000FEE91DDC3FD5F0A5C15B1F667643F716CE
+:10D27000E61F98E5B93ACE7D49297C9CEAB6FDE3E4
+:10D2800040EF741FD8CDF98DF17375CB1196774BA4
+:10D29000F57348AF9FF9FD12E6FE32787F81F6D82C
+:10D2A000FD055A3E8DD9DF49C9770BC07FB293D9AE
+:10D2B0004927C3E2CC58F7DBD8126443FE40BD8B4C
+:10D2C000DD9721BA1D681FDDE59AF87E620A3C15DC
+:10D2D000CCEBA95BC6F3807EE6C57B45EB5C5713C0
+:10D2E00080E77EC08F2ECE207BFC04EC3439AD2845
+:10D2F0004F54A3F0F6D123C542427AFA4B9174D031
+:10D30000E71FE61C97A1BFFF34C547FE5322F583F4
+:10D31000285CFF1914BCCBD4F876B556F6FF54340C
+:10D32000C433AAADBD1F827D4E5EB6E37EB8B8CFD2
+:10D330001EC4F8D853EC5E8D833BBF7A06EFE5F947
+:10D34000959570BB50007D50CAE314C7777EF5D425
+:10D350007F811D098DE9F8A54FD1FA603FB724A060
+:10D36000BDDFB323711CC4014A5FBEEF5AD017A5BD
+:10D37000A0FBC0CE7C6150A88EF6776C202B1FDB03
+:10D38000360CCF0554EC70613EE1C19DBBAA41DF74
+:10D390009F79218180BE3F2D77FD15CA813D89A4EB
+:10D3A0005945BB4FD5AFAB8B88A4EAEDB90A281B12
+:10D3B000F25B08E6B760FC8DF273455B229EFFD0FE
+:10D3C000D5E3F21C1CC2EF891A027247ED46D598CC
+:10D3D000F7CCBE2F4860FA2B60EDBD87DD87C0EA31
+:10D3E0000794DE12566E18C2E4B613EB2FD6F895EA
+:10D3F0007FEFDF2FAB1F4860F180683FAC7DB595B4
+:10D40000DDAF61A6EF4F13047E1EF72F97C4BA7FDE
+:10D410002206FCEC5E2E8104E1FE55B2DD8EF7F1B2
+:10D42000542A913190AFFEA2C2F63F2ADD9131908D
+:10D43000AFBE87EBBF4A072DD3F743381C501FCA36
+:10D44000C4D6F53CDEEBB4CB8EF7E155BDECF2A1D2
+:10D450009FF0E257C79EC8837CB504CC93AE7AF99F
+:10D460005F90FE55D6C8EDC0FFBDDBAD783F69F7D4
+:10D47000F64319603774CB918CE4F3ECEB5485AD33
+:10D48000867D6A6D1E276B974E8673BCDA39C3F2B0
+:10D4900038FAE28D0496D7D19CE0FB15D373C6FB16
+:10D4A000654ED6CE36DC9B586E8BADC75A402FE802
+:10D4B000E27862F45C610BF47B9A74D50FA124A925
+:10D4C000127A717FBC7C4B663AF8BB07EC97E0BEE2
+:10D4D000D50159457F109E7A7D7CA2D69B2BE179A0
+:10D4E000FAAC5C89C2D1D3FC69C91002F981F6D9C2
+:10D4F000B1F4D3DE8404E4A7729B35E6F9CDDF7284
+:10D500007EDB06F236818DE7CD8E8E7B400E2900C4
+:10D51000C714A78AF329A77E00BB276A4EAEFEDC9C
+:10D52000F622A901EB51F9427C2C22EB953C677F56
+:10D53000BDB268695EAE948B0AEB9B3E7E13A3740A
+:10D5400022C114B493244E43B27EB021DF5F928B8C
+:10D550006C802F851479241148DD8072EA20617C6B
+:10D560003AA919C2D6A11A02F1F1137C7FD62AA9D1
+:10D570000FE37D331D22EAF30BE1EDBD0437C26DED
+:10D58000956A8817ED8D591EB0C784A09F7C4BF912
+:10D59000A1AE76662E3B174E7C90EFE6260C3EB78A
+:10D5A000E7D5AFC13EA07CC6EEB1FA3E09D5D1F1B8
+:10D5B000E09831C6FF0AD87DF6E6F1FECCE940825C
+:10D5C000FB0DF79DC35FAF767F1EF8EB897F9D084B
+:10D5D000FB314E0F8980BD94E024918471704F9E81
+:10D5E00074522FBF6EC2CA23283B835EF34C317E38
+:10D5F00037F335F14A9FF7E94511DB7F6E6AFFF992
+:10D60000F9DA6BF808D8367A8FE646F1E2E073086B
+:10D610001678CF75013EC6B9BD754047A5F7C3FB67
+:10D62000001FE39CCC1F4C69247A7F2DD7C9F4D509
+:10D630000A7EFF34FD2B72EAFA231E1BC647577180
+:10D64000BCF7D5D7E226FDEADB25C06BBFFAF6783A
+:10D65000F51DB1EBBBE2C193101B9EA438FD07631F
+:10D66000D7AF7EF9BD37232ABC647A0382F3FCDC92
+:10D6700072AE13FCABC40F538B1957B0FD0013DD12
+:10D680001CC07F941F1CA374EFE1FFB275F41B1143
+:10D6900083FE24827C57CCE1A165E7600ADF8F39E5
+:10D6A000B8D337B1FDCAB977B138D18F6DA5E8EFDE
+:10D6B0001EE1F701CD6D647EF5DCA56C1F9194B180
+:10D6C000733E1EFA1F8C771B7442E97D5B83108AC0
+:10D6D00064C2BD3526FBB5EF7E9C450AD42F36C506
+:10D6E0005D347ED2CE23CDE7F67526E7CF85A4D76D
+:10D6F00005726F3EF7FE0AD76B9ADE0FAE235970A4
+:10D700006E5FB438BCB03F2AF273A6C4CDEEF323EB
+:10D71000BE61EC7E392D8F2B4B4D84F58D84F97BCA
+:10D72000BECFB2E42A7590FE9C9674CE81F783D466
+:10D73000C9DE34D083F2396AD751574D393782A8C0
+:10D74000BA7364D49E43E1963DECBE44C953444A47
+:10D75000C10EE4F7039094ABFBECAEB7281E96AC79
+:10D7600053F1DCEA4227B3337FE12ABAD33901EC23
+:10D77000CB895E76CFAD918EC19D6C7E7530BFCC6E
+:10D78000FE70D7295E2FDA9D57538B01E3385EFC7C
+:10D790007D07D1AABEA7823CFE9BCC7EAFA01F1EF8
+:10D7A00018FDCEA624E3BDEC0BDCAB3F043E5DC30D
+:10D7B000EF235C599B85CFD5B5696877D6D77AF1C9
+:10D7C000A9E1C5E66DC07BDF6CA3587F368F9FD97A
+:10D7D00015D496817C0AC9531381B22DBD8680BDB4
+:10D7E0006BEFC34F03E247E92BFBB16CF5B0DF8D64
+:10D7F000901B67219E697B524ABF2F71F91F073921
+:10D80000B1AB9719EE91B3A68D37DD3768C29BC6D1
+:10D810001FDB18FED60A8C3FCCF85B2B77AAB0AF83
+:10D82000BCF6AABE7B67107FD4BC67F8FB2DDB6714
+:10D830008B8B3F4F32DAAF0BF2EB6FAFA3AF1EE42F
+:10D84000FB8B0FD44E447CADE2F748DE5FEBC3A701
+:10D8500008F8A3F3B3660709DC8FCE7E1B823E9DDA
+:10D86000453EB87F167817F0273A193EAD6935B8AE
+:10D87000BF6673327C89CE20E24576327C894EC603
+:10D880006F0A2F4B80BF5C6C8FEF29FE0E007FD993
+:10D89000D2271BF0A5A4145C1CFE1EA3F8A370A441
+:10D8A00070F932E3214561F7536A7215CF8E7B948C
+:10D8B000CE1FD6ED0DB5049F03E3F88B235C6CDD22
+:10D8C0004CB1D4EC97011FC984AF2741929E4F58A9
+:10D8D000EA21FCA505890A6581C1411A8619EE95E0
+:10D8E000143D92E95E367503F0C1FA43B205EEA32A
+:10D8F00013975E6D380F2ACEF625A9884F3FDED3E9
+:10D90000FC60AD8AF45B0774847B40B9FF753FA768
+:10D91000E703FC1ECA555C3ED672797998CB491D47
+:10D92000BF3779CD4C9667959263E1F79545883E70
+:10D930008F29C91B260A850B6D6A159F78CF22791E
+:10D94000DF1A1A4DDB2564131FF049D2FBF786D886
+:10D950007D8D4583C10E4AD2EE5F9CA226CDC18348
+:10D96000B01189F91D5415A21FD36989754F559DB2
+:10D97000F7800DE2A1F1E049F0FA32EFA7E3253498
+:10D98000BAD07E1FE02F9AB390969D8D0918FF4B59
+:10D99000E0BFCFE2A47097EAE81DEF1EEA8DAEABC0
+:10D9A000125D949E1E80913E1F691C89BFCBF2A818
+:10D9B0005C84BFE3F2285F4FB57BCEB576DF70FDA8
+:10D9C000E8CEBBCCE0B7AE977DD8CE33C528FFEB11
+:10D9D000B9BE4D9E6EE4734DDF1EEDD3B7FE110050
+:10D9E0004FEAB9E9A8C7526E88AD77EB6405EF2D11
+:10D9F000AF1BCBE43C58ACB0FB4BFBEB018C539F13
+:10DA0000F58FD9087A54E3ABE584E99D20717871EC
+:10DA10001DE2F7DB6876F04AB80790EB57788AA3E7
+:10DA2000D8EF0FA4CE65F7F9AEE1F7583D44F98A77
+:10DA3000E0BDA75E7C5EED62FB13CB6DE3F13EB50E
+:10DA40003AA705F584F48135042687B47F9207E26E
+:10DA50000592ECEDF441BCCF2585E1DEDC3A671E92
+:10DA6000DEFB2E24E57980FE5FBA160C3F5F3E1D7B
+:10DA70009D28DE97E94929221F65E36E009E47969F
+:10DA80003D3710881B6E48A9B103DE26B9585CBF2C
+:10DA9000B1381FF148F17B9D6B60B49F41B3AFEE8D
+:10DAA000BB070BBADD10E75CF3AD2E662F91F420B7
+:10DAB00019A593F346ED774ED420C9D2C9FBF2D114
+:10DAC0008504F687FACB791C3DB699E9B115426C0D
+:10DAD0003DA6D9999A1E934DFA417BD60F9F69387E
+:10DAE000A7A5A4788177E119B478C1BE7BB1FED631
+:10DAF00024C4430DE081A45DDDE7BFFE6004D88F40
+:10DB0000F931F9CDACBF16F4ADE7BE54A0D3095935
+:10DB10001D3407F8E950ECF57CEA23973E0C7CB005
+:10DB2000E0B7A2A0DF4F293DB712D7D3927313F10C
+:10DB300059D63813F99E40145CE7871D6FBADB0D88
+:10DB4000701D6FE479004D7208F2338E37DE8DF769
+:10DB500095409EB7A8DBDF27792ADA97DA3D63C7BD
+:10DB60004377BAF5FBBB25BFB0FBC06E8DC75F2501
+:10DB70004DB1FD7A5843217E4A01CC027B98DA37B9
+:10DB8000BD11B07F365ABD41122D071FB1C7CC4F12
+:10DB90005CE29AF128E07D89CBF724C83971B27B29
+:10DBA00041E3F3391BF7186C02C37ED3E33C4F53B8
+:10DBB000F2BBF5F7BBF5DDC7C9E324C416E7BB43E9
+:10DBC000FB7D8338DFDD2C9F8378627FD7FC8484E4
+:10DBD000A89FD006F3A86A3C55FF01E289FB091C07
+:10DBE000EE133283FBC43356F63B3726BE38C1F3FF
+:10DBF0004716090CAF1A7F9FE8B377FC780F8D9911
+:10DC0000FF848D976E9844FBFDAC43C6385C25E5D8
+:10DC10001FE01B61E324CC5F171E99F430E4257DDF
+:10DC2000FEBA88DFCBCFD9F07BF7CFBC1BE6429C96
+:10DC3000E70D19EFEBFEBC6346228BF318E3D00B24
+:10DC4000DD6C9D3FC9E5BEE4DC6AE4CF3EFE68586A
+:10DC5000A8805C959C7B08ED99922D02DE13498289
+:10DC6000BDAF4E95381F4E86F6A70B9703BEA7345F
+:10DC7000E0FE46E966AB77B5D09FCE275DAAE15EB0
+:10DC8000F5D2AE35D82FA1F6548A6EBFFB04CF0370
+:10DC90002E3DC7EE07249E204903BEE77A27CABF60
+:10DCA000C67B5FBBEDB1E3ECDF707BA6E4DC648395
+:10DCB000DF109DDFF7997CF2F5BCB46B2283AB6F6C
+:10DCC0003E1B26C59A4F741E53B07D7752ECF1333C
+:10DCD000399E8FD596C1C90D52A6B07A250D772BE6
+:10DCE000A04F4A9A929205DDBC4A1B2B0C7918A5CD
+:10DCF0004DC5CA3C5DBF513A385E9B3A2A4A87CC33
+:10DD000087E42B973B61BD2F72B961BC8D8BF27F8D
+:10DD1000A2427F4CFF7C223764D4A07EB9D31DEB96
+:10DD20005C43A65B35C4954A1B397DA89D9CA7A37F
+:10DD30008F461773FB63CDA5F93F8178F263EC56EC
+:10DD400090F87AC744B7CCD8789BDC87B72CCC073F
+:10DD5000BA30DEBE63C8FBE987374E5F0D2FDA7B32
+:10DD60006A1FE502BE2643C06920F4C3E87F217C18
+:10DD700045C7E5F49F1A7B1EFEBE792C25416A3FFC
+:10DD80002CB8E03CEE2341DB79E6A1D19F5C66A094
+:10DD9000BFFFA1D157821C6AF45E70E031E4DF0559
+:10DDA000541E615FFE78C3DD86F5210A5F1CBA8FC1
+:10DDB0000A92ECFCFF7374FF440E6640DE57701D40
+:10DDC0005B474E6C7C30438FE725AEA90B812E64F8
+:10DDD000D3C08B5A3F8205DE0E15D72519E361BBF0
+:10DDE0005DFE809BBE2FE37EF58AA4C231B1D67D55
+:10DDF000EA174E81F8735DEDCC29106F93B9DD08F9
+:10DE0000BFAC05F6265C811EEB7EAD064ED7FB6BE4
+:10DE10006B307E4D6C41E2D19FF725CC2EFA86B057
+:10DE2000788BD64E91FD1E887F2AFC3CB22CF95788
+:10DE300066E6411C232527A8C3DF436E66D7AD499C
+:10DE40003BE0817C522BED1FE231B674E9AC719F4F
+:10DE5000929573844932CC474E09138C6766D3F789
+:10DE60003A7C2B2914CEF3F89B92CD8DFB451261A1
+:10DE7000769A367FFA06D7B307F8BAB41CE2B82907
+:10DE8000608759D01F5ACFE394BFAC2DE2789070D1
+:10DE90001DB326B1FA4A2283DB0E716B11D6D50869
+:10DEA000965D70C38E885793E1EF8F2611157FA77B
+:10DEB0006F0089D4E33D2653BBEE81F7BE04FF1605
+:10DEC000E0832F07777E28401CBAC87F09ACBF8D3E
+:10DED000623047A5F57F25F6E6403DF87DAFF79324
+:10DEE000D97338E42DFB75FB52EC5E4E551FD733CA
+:10DEF00097872F954CFB357FBE44FFBD39C1B70BCB
+:10DF0000E048F958C07D983A3BBBD7A7CE7573223D
+:10DF1000ACDF8739BD90FEC03F1DCC8E392BA9895F
+:10DF2000C918DFCCCA7DC530BED75096B8FFB689B8
+:10DF3000F2A3A4BB977594E4B300BF8C6EA0EFF579
+:10DF4000F48B11574B76E2F5B731F76134F8E8B846
+:10DF500004F0279E2B64EBAB890FF6080CFEA08B18
+:10DF6000FB5B2428023DE768F7054B2B5859FBBDA6
+:10DF700008A02285E3036D7F81AC6065BE4F1998D0
+:10DF8000C7F621CDF0CC697FA013E2FA73DA07CF90
+:10DF900087FDA939CE317F82E71EB9F74002D881CB
+:10DFA000770B78FEE3C7BF7B454EA0CF9DEF6CC4D7
+:10DFB000F3C6A7B9DCDD4E7AF11E763FF1F07DF2B3
+:10DFC00010BE9F073F3087E5B00C7EFADC48E8477B
+:10DFD000D7D0D26DAF84AE01B3EDF68EDEDF801AFE
+:10DFE000F0873D85B807A0B56BF3BECACAAC5D1417
+:10DFF0000F366E8FDA705ED179DB100F1FF4E58D6E
+:10E0000007911E7D78E2F72A6978E99B77E2CD5780
+:10E01000439C379E3E9BE3CCFA13DBFC607099F186
+:10E02000F4397CA276E4E76E9F3D91EAB78FDD3E3E
+:10E03000073C2B6DBD19D20894173794AB45FFF000
+:10E04000548A87D3C3FC970C047C740EB8283DFA1D
+:10E05000A19DE901929781F3D1EE7D3F78EF711791
+:10E06000D89DF53BDFCB806795D8B5F6168C6F8AC7
+:10E07000E80F9D6DBDE4BCE7C33E84B8135DFF4669
+:10E08000276A7CC8E677073F5F73476B029EAFB98C
+:10E0900063A968B8B7F98EA52CEF8E489DE36E3260
+:10E0A000D8EB2BE2F6037100733FF39716908F07BE
+:10E0B000C03EAB672AC6059E62FC357FBA4F847CA2
+:10E0C000E4C92B058CB74C3AAAB675D1F2FC5012B4
+:10E0D000FEDED1FC7B97E4C23D04D59D2CBE3748C3
+:10E0E0005C9CF333889F1C60EB389417837C3B7DEA
+:10E0F000AA5317EFEF966B72E0DEBDE06D4E1FF096
+:10E100004FF14DBE0FF0F712791C425B5777351671
+:10E11000631E6BF15C7522D0BD386CC7DF1F2CB657
+:10E1200011C941F558B1446CF01CA410C90E4F0739
+:10E13000B1C1337F39BB27BBA4F17AB40FDC138B99
+:10E1400014B8FFB6B8FDD92FA07DA914D9CFCEB58C
+:10E1500030FC14B71FFA1AF867A1AF08F30EBFB36B
+:10E160004531F87F63C3C6F2E56DC6724EC458CE22
+:10E17000ED3096B7C21D673A3BE2C05E2BAE131579
+:10E18000A7D839BD9704589B201E6C45799A56D163
+:10E190009E0FFBD1A79E7759E0FB9EBF30BFB7779C
+:10E1A000AB1DEF7BDBFF7B0771405EE10BF68DF073
+:10E1B000FD94239C0F71385A9FFDCE5651780CF870
+:10E1C0006F2F5EA6F9E9A17130AF17FFCAF2647A2A
+:10E1D000B75AF1F7534EED7EF679D8173BB575284F
+:10E1E000DA592F09410BF41B5CC5E86FE6D38A2D81
+:10E1F00046BFF89E44A66F7A0486EF4B1A8DF3BE95
+:10E2000034642CFF3C91F953F388EE7D26ECDFABB0
+:10E21000F569B0AE3E1DFBBEE1FBB95C3CF79CA2CC
+:10E22000F1ADC8EF6723AAEEFCD29EE8FEDD5D43A8
+:10E2300021AF02703122FABEC234AED67F5122DB4A
+:10E24000874FE1FB33BD6F88889F93A6DF2DECB32A
+:10E25000EB6A6B064FD7AD43258DFB538BC13F6AED
+:10E26000DA9F3A4FB7BE546E3D987A2BE62549F8AF
+:10E27000BB4C95739E7968720ABC17C3002F7C87CC
+:10E28000B85777F8376EA847EDDDF1A20EEFA58DF0
+:10E29000770F9EAE93D3BF952F3579AAE4F6C9AE1A
+:10E2A000899D8590275ED1C87EBFA922FCA31BE172
+:10E2B000F71749133B679A2F912291CA4FE5F61F32
+:10E2C000FD107E8F2BF0E4042FC043BBB809DE574E
+:10E2D000B47C8AE709569B7E47407BEEE3F4A5F5C4
+:10E2E00023165A7FF5CDCE32D04FB4DF57A07C2015
+:10E2F0006B23DE6FE23EC1E2B4F4FDFBF09328270E
+:10E300000A826FDE4A9B9E22E177AFC984791BF9AE
+:10E310008CF2AD007657EF66017FD7965A5AF937DF
+:10E320008049ED5B8679B7F4FB1DB1CE3B2F0A190E
+:10E33000FB31D3FFF79C7FE95F969E8FCCF506CC2F
+:10E340000AE2B9C4CAA554DFE9ECFCCAA30D789F60
+:10E35000A3791C0CC2E9F20D60BD5451BEEDDC6E18
+:10E3600020822D9FE7CD8E6465BCB710F895324AA8
+:10E37000C56564BA0AF8BE81CC84E74B42E42151FA
+:10E38000647A02E340DB12504F747BBA9E7902F844
+:10E39000AB652CC69F86F0F39EDD6A04EF79ECE155
+:10E3A000F1C96E0F2B97B7DB310FE6D46905F5E89D
+:10E3B000B2F04137D0A3FB79BB057E97F4D4F601C8
+:10E3C000059027D91D66F7FF9E0C0FC0DF7F8DB724
+:10E3D0006E99F581B64E1E817FC27A9AE8FB06D609
+:10E3E0005BB282E5910E1A509313EBF724B47629B1
+:10E3F0004A4D0EF829FF0BC935400200800000008D
+:10E400001F8B080000000000000BDD7D0D7854D547
+:10E4100099F0B973EFFC65669299C9249984FC4C14
+:10E42000420801024E42884851272160C054078AA1
+:10E430001A7F8AC37F80FC89B61B956E26266242AE
+:10E4400051C31A1110704051BA6A1B5CD46883CF53
+:10E450008068B1D57EB176BBFEECB223B088562081
+:10E46000A2A5B4DB96EF7DDF73EECCDC49A2747716
+:10E47000BFEEF37CE943AFE79E73CFCFFBBEE7FD72
+:10E480003F6786BE6BF5EECE67F017CC575C8C9D70
+:10E490000BB8BD1BA0BC58825757306671FA8DF679
+:10E4A00034C66CE58CF9E09FF388BC5B86FAE3B276
+:10E4B000F7FBF6B18C2D637E03C36779C0C00AE019
+:10E4C0009B4E689CC9D852858515273C17FA3E900B
+:10E4D000A6509931F87EE97629D401DF2FDB6864F4
+:10E4E000CCC4E8EF22FC5BD10BE5E25879150B199F
+:10E4F000980CFFB13DAE1DF4BF4A091F9492195B01
+:10E500006D62610BF4BBFA29ED776B5898E6D3F096
+:10E51000DC45637CFFB03EC6606ABF63EABA7C1E1E
+:10E52000FB34C65C0628C3BA87DED187100EFF21F4
+:10E53000FB695D6B5880FAB9A5B58A1D4F65ACF9CA
+:10E54000EED6CC65F03CDB7A4FE6B2A9508FF38073
+:10E55000F1AD8C7FCF605D7B00666BAA593807E612
+:10E56000B71CD69B5406E501293C19CB26164C2E28
+:10E57000E3EF53CAF87A7D71F3AB673D345EFD7605
+:10E58000ED7BF6EB548267031BA47AF6545C3DC026
+:10E59000A341C0A1E139781F078719CF4941DB6545
+:10E5A000580A75A4C3FC9A4E31B6014A4DFB2F1A86
+:10E5B00035FDB31EC6000E19498C99015F8F4AAC18
+:10E5C000AEAF84BE9B307F32B4C1BFABB1DC4EED89
+:10E5D0008E0AF83D7AC38ACC00B47BD801E52C01C1
+:10E5E000E0E930860E07A772D804E3244D8D96A982
+:10E5F000BEE23E5E9E6F2FAED992CDD8667D20D30F
+:10E600000E405C2AFBDFD401FC9E71066E40BC2CE0
+:10E61000D5F972155C2FF315F9611EAC95C3E1B104
+:10E62000B296092D25B179C5E6C7F1BB59EA0BEBC6
+:10E6300080CE82AF48DE3D1EA4DB217DC01A6BD7A1
+:10E640006C97681D2987226F8E41BCBF28B1DDD031
+:10E650006EABF4F19B63E0BBAD733DAC03CA6EC01F
+:10E66000935C86EF59A7047029DF3FFF8E3710CFE8
+:10E67000E549DE71F068DC5F29375A69FDB7FB6157
+:10E680003E1996965D3AA8CFB8BDB80CE91BD67D69
+:10E69000FB02787F97DD43E3655A39DEDDF705F34A
+:10E6A000D796E0F8FE3BDE80F18626277971FC0CD8
+:10E6B0008095CD49CF2E33B663ED12B67B3499F7F2
+:10E6C0009FA6936F9F8FE5325E76AE937CBB89F8F1
+:10E6D00036D1BA338CAC06E789EF4325B4657CFBB1
+:10E6E000A83EC4F13BABA514FBCB18CB9F2E4338FF
+:10E6F0001BFB795BC5F740A68EA5E37CE1BF613EBD
+:10E7000077EDABCC70C2F76F7F6E527429F0743323
+:10E710003688ED94B095E1B3B098B73789F6A5B3D4
+:10E72000327033B872B5EDCEEA7D2953012EC17730
+:10E730006586F8F8CAEA4B7140BB6F19F83A12F1D6
+:10E74000B813F103EB69BE00334F8DC35BDD790372
+:10E75000F6D77C4161A1A9B1F79FB79958A828566F
+:10E760006EA83F3407DB35B2C1F548578D7D1616CC
+:10E770008AA3F76F258D3CAE4ADFCD17742C984ADB
+:10E78000E49BEDB7217C86D62FC7F91F90D81E8653
+:10E79000F506168C1BBFF982535B8ECE339DFA892A
+:10E7A000B563DA76FDBFA7766C7A2419C739638F13
+:10E7B000243BC5FAF0BB2C99B5205ECE8674413D52
+:10E7C000ECE3331E5E7F96B19A3E6BACBDDADF9907
+:10E7D0003A030B13DC87A85F844B1078DBB6812FDC
+:10E7E0000C1E28370C1C24B8A8F4100F9F601CDFE7
+:10E7F00048EF180CEB604FFFDABEAAABC40CA83888
+:10E80000A4EEDF355DBE99502FEB34FBD9521EDDEF
+:10E81000DFC4561ED5C9821F347455CF8C2FF3F632
+:10E82000B1EF1B6BAA61FF9797F0EF8FDA9B8EDC3D
+:10E83000A7C4F811AC2317E1122D9B12CA56284F1A
+:10E840008E2BDB13EA5D09F5EE8472366FFFB92D6E
+:10E850009C2B7B19FBD4BEB64601FEF279667891FB
+:10E8600004E58D1D77D554039F6B2C1FF4C9C83F59
+:10E870000724AFC462F06BF2325F08E067F5460C24
+:10E880004B4B100E836FE2FE6FE897EC12D0B9B5D8
+:10E890006F5F98CAF89D27EEBB3E89BE6BE8FB9878
+:10E8A000BE1BB5FF621DEDE30DC5C7A81D00C07EF0
+:10E8B00002F0741393580A80345F09FC11F9646301
+:10E8C000DF275CEEB221035F1FE78367327DAF1362
+:10E8D0001F3C20D971DF45E90EFBB5C6E85D6DFF31
+:10E8E000D1E4817FC66E2C777DD1AE40FB7F6BFC7F
+:10E8F000641A03547D844DAE40BE1A9A80F2781B90
+:10E900000B4C4039F4DDC6710775D0EEA83EB283DA
+:10E9100001BC8A1D1B6A146877D416C99180874C84
+:10E92000DCD4CBCB69911D08CFE0A64709BE477365
+:10E9300022393A284F718479795C6407966FDCF448
+:10E940002C2F4F8EE4C8F07D41F0B99A6A28EFB1C0
+:10E950008FBC5FF31C9C8FABF33B31D697E54843EC
+:10E96000B2E37262871E2006FC70D1EACF9EDF03FD
+:10E970007058748F85F8D49ECFBF33CF4FEB0FFA0A
+:10E98000950AE0879CF4B91C237EAC901E9089B256
+:10E99000CB19C3872D77D0437C7E62CB3E94F71989
+:10E9A0008B4A88CF5F48F1B53BA6C59EBF4BE7CFEA
+:10E9B00076879DF36559E7A3F6F7DA48EF79D8CC67
+:10E9C000D703FB86F06B15F82817EB2977E8E89951
+:10E9D0006B9F4DFD7C28F9B69A647CB2A019F1B901
+:10E9E0002A89F48C5B77015F00BEDC2BE6DDBB6916
+:10E9F000422808FDDF2A313FF28D5E872F13F9C3CD
+:10EA00004B7F916FC7F5F69642199E3F15FCBE7776
+:10EA1000BE2FD31127177B77F17A95EFF4E6F3EF4A
+:10EA2000557993D1C1C7C97878C26E5C8745613E7C
+:10EA30002C2FAF2BDADD4E727B01CD97F97C99122A
+:10EA4000ACF7C4AA021DEA912A7E9442DF75587F72
+:10EA50000BF66F8DE1491DBF1DD79D867A00C87DDD
+:10EA6000586F9B33D08EF8043D600AE981420F68ED
+:10EA7000C7F5C6C197299169F8FEFF2338DD89EBF8
+:10EA8000FEEFC269047E11C4711B5B815FE8E2F88E
+:10EA90008580DF6629ACCFE0FCC28B720EDF2F00D1
+:10EAA000FE788B3DF000F6AF8EBFE8DE46D2FBD499
+:10EAB0007959FEEEE59A9BD8F07D96A8971DFDD07A
+:10EAC000B491811C3B6AE823BE78741EF3B623FF21
+:10EAD000D0B17A84A3AA5756DCB3E66D06FAEC9758
+:10EAE0000E99F0DC2DF932715DDD805713CAE1F922
+:10EAF00086D09EFC985CEC7584B6AE40BCDE50E2DD
+:10EB00000D7A483ED27E0BB65AA85DAF23C214AC34
+:10EB1000BFC2638799209E091F43371B42BB25C490
+:10EB200037A797DE5513434189F01EA4EF6FE6F433
+:10EB3000D33B9F917EDF7BB39BE8C6CC42669CCFE4
+:10EB4000687490DEC1888E98E29B32DF1683C32FF3
+:10EB5000C5BEB694475EFC17D423379A498F4499B3
+:10EB6000897617EBC9A0F9023E5F22FA50EDA5475E
+:10EB700032431BC83EF356203E1EB0F916D3FC7F2D
+:10EB800060F1E0FCB79B5997A90CCD0FD649FC4E1C
+:10EB9000CC87F53CC6503FBB5DE867FF5E7FCE8605
+:10EBA0007AC01B0EAE5F21A19880FF2D61BC7EC98B
+:10EBB0003ACBC768CF2C5927878D60AFB0AED9BE8E
+:10EBC000489C9D411405FD0504BF645B866C483775
+:10EBD00001FC2E19FBFFA3CD63C5327C3F05D10E8E
+:10EBE000DF17C7BE7F5FECDB45329F3F6BB378100A
+:10EBF000BE897CFD7D757E3D8FF9E2C753C749EC28
+:10EC000017ECB80F903E01EEE114D4E77F20135EBD
+:10EC100013E7EB320C3D6886FA456DB2E33E806740
+:10EC2000A0D546EB55E77B7BC6D095645F25F47F86
+:10EC3000D2D254A1E0FA85FDC1D669ED2FC60CB140
+:10EC400032D0C572364476CCB0F7C26E4DB4FB18E4
+:10EC5000FB8B31BE9DBA5F98474A98BFA02B8FA40B
+:10EC600020DE0212C79BC130B408F94EE2BC5578D1
+:10EC70001A9D3A01774E1789F0363AB9DC4984B7C4
+:10EC8000CB10C9C17E03AD46825362FFAA5C7CCC27
+:10EC90000CFB07E86E8B2411BD6EB9DB42728E99B6
+:10ECA000389E9B572779907EB719869EA67DF5AA38
+:10ECB0009121DECF9A875E227E55C8FD0A677F29A3
+:10ECC000EFC27667D238DD9F79454FFB8D4F06F452
+:10ECD000A15FCABBA95EE2FD9E69B77870BF36230B
+:10ECE000A461FCE6E07FB63180EF711DB7939BFB1A
+:10ECF000B5F6F019F8575F16E31B67191F27D8CF31
+:10ED0000F904AC74158D736B12DB00FD36E9241F1A
+:10ED1000EA4F4DAB27863A383D99703F3588293503
+:10ED2000E9C02E2C8BEDFF26DDB122B4AB1A4C1BB3
+:10ED300007E564AA3F8CF618437B0ABE5B8D1FE58E
+:10ED40000F877FD3C6DFFE19E7DDB45F4B170D31A8
+:10ED5000FA912E4AF87D1C3DE5C7E884F46FE41F64
+:10ED6000D52C344EE27E1A2C5B6A0643E8A769165E
+:10ED7000FE8BB4439139483FB6F23EB6049ECDA710
+:10ED8000B8FE316360D7EB68073B6A06737099CDB4
+:10ED9000AD6BA79E981AC3AF3ACF2B0636C968DF72
+:10EDA000A97A4B9C7D3961C1E4F8E77DF41DDAABAB
+:10EDB000385E045FE1BE51B8BCDB2CE41DC845E2FF
+:10EDC000CBCB7BC6935C44B985FC4DB57791DF21F5
+:10EDD0007F79C659759B13D6E94DADBAC9398D8F68
+:10EDE000437A3E1A49570C8767A2DC51DBA1DDDB71
+:10EDF000621DBD5DD40FB43585F30F45A2F28A5F65
+:10EE0000E8776DA0F929442F6B77E4133F56FD3561
+:10EE10000DC24FB542F8775608FFCECA2D46E68997
+:10EE2000F76785B4E506C10F1A5984FBB9F6427D30
+:10EE3000BC5FA79A856D588FFE1D7CF669BF6F6613
+:10EE4000A1590AE2B7FFA231FE3DEBE5EBBD5DE063
+:10EE50007DAB99FB7566ACDB257367155F6F4A99CF
+:10EE60002FFF7E94236FE9C9FFF01F024F2A5C2C0D
+:10EE7000CEAAC508EF24B4D7B0DDFD4682CB0990F9
+:10EE8000D7FB84DF6301DAA16D81CCC242048F3DE0
+:10EE900077816D387C37BC6AAE477AE97172BD45BF
+:10EEA0007D3FC7A9A732F98310EEED16D2BB01CC86
+:10EEB00053908E2A0A5439CAA6A01FEA633DE8631C
+:10EEC000506EBAD11AC0FE22A837407987E05F3B66
+:10EED0009C06EA4F2D47ED3C412F300EF5877E19F9
+:10EEE0007F1C1D3C156DBF49E8939C2F6C5E9544BB
+:10EEF000FC2846B73A46745BE237A03FE955C14764
+:10EF00005E0580929DD567E67C44E1FCE9D553130C
+:10EF100089EF1DF96C35F195737549CC28517B9FAC
+:10EF200084F52F1A43F7417999F0B3BE2A713D3128
+:10EF300078C046FD3418025BD1EFD0F0C2382F60A4
+:10EF40008CBD6408FDE869AC7FCD4C7EAD86643E27
+:10EF5000CF8657C7109FFCA93EF4EC8FC94F6124A0
+:10EF6000FDAD21C99342F53F4F6558DF65098471B6
+:10EF70001F6519B95ED960081739008EC7425C3F1A
+:10EF80003E868C06FB1FB091DE03D3CCC4F18F7795
+:10EF900067783778627039FEE024A2FFCD7A8EB7A9
+:10EFA000E02BDCEF794CEF9F9309E5632F967AC154
+:10EFB000B26467FD86B001E6D8FC30D7E796EA3C3C
+:10EFC0003B5B9137BD66F16AECD18756D6627DF323
+:10EFD000EA75D7211F1C6D3F233F8FF7E79E6143E2
+:10EFE000B9648FD617F48561DC330313BC243E99D2
+:10EFF0001B900D7462E76D4FE801DE485F07F44433
+:10F00000BF97DA3FAE17ED43942F384E33F0DFA8A9
+:10F010009F99F86F5C591EA9CCF1D9FC6A86D0DFA4
+:10F02000B4F5B7A604CEE1FE6AFA87DF1F6D25F8B6
+:10F030000E11FF633DDC7F7E42EF5B8474EAA80E15
+:10F040001B96C4C9EDA4542ECF971A859EC7C286BD
+:10F05000F87DA7D6575469E95C7D9A5339BDDB0624
+:10F06000391F1F5EAF13FBE13B46945BDCB503F633
+:10F07000F629EEEF484AF550FD8C5361C35228E75C
+:10F08000AD0B1B568827EE0B8077D804EB3EB1D52D
+:10F09000C6F7338001FB59319D91BEB242063DB5A2
+:10F0A0000CDF7BFA238097932F3A387DFD09A0026D
+:10F0B000F05ECC443B23E8B5C0B75EEE94C2A8F73F
+:10F0C0002FDE62DC6DCEC77DEC936D88CF1D12F113
+:10F0D000ADC59D95455BA1BC7AFF64C27FF2744EBD
+:10F0E00097AB430E927F33041F5C6A0C1948CF7EA6
+:10F0F00096FBF1A07FD2971BE0A3CCB2E17040FE5B
+:10F10000ADA18790360E31A34FF0D3BD71F1878248
+:10F1100038BEDE97F03DE8795AFA08AA7287F339CB
+:10F12000E6C9403EA7F2618BD33F2D95F050988100
+:10F13000F8057C723EB94F22B836B2162E3704BF9E
+:10F140008F8E2BE4C54939C8E59271133DE7A5E6DA
+:10F1500013DE56A3BC21BF3AB7FF46A38379A93A71
+:10F1600061278C4C07D70A3A6838C5C257C2780D58
+:10F17000EB58B8710A7FDAA6901CE4F2D024E21DA5
+:10F18000261E0FF926B998280787C9BD047997610B
+:10F1900010F24DE039DEDF8DF27EC6BA908C7ECF64
+:10F1A0005CBBAF32635A4C7F697EDF64F25C86657C
+:10F1B0003F2BB0A2FFA6F25937FA7FC15EC77D652B
+:10F1C00001B8EC42F9A2EAB76EBE5EB781D3AF5E7A
+:10F1D000F1B3522BE26590ECD9A13466477A54E141
+:10F1E000B9C306DF95E1777CBF45BF37B1CEA4B880
+:10F1F000EFAB5E35135F3DFF8A2D6424BD2390E79E
+:10F2000080FED23F32921E7AE6551BC9CF3342FEB2
+:10F21000B954BF005B4FF85927F01A645563D0BF4B
+:10F22000CAA479639005AA7A58A363347FB7A8CF9C
+:10F230001FBC91D39591ECC9F38EC8F7B10CF36163
+:10F24000A85FDF25F0DCBC7F56E9BDF0BED96FF5C5
+:10F2500072E8074A915E8DF25D37A2DF658EBC6E63
+:10F26000E86E5847638ED56E844FAAF3FEF53737A4
+:10F2700043F9D3FD7A66443CEF9955C70A46E7BF88
+:10F28000AB42FA6391B8FDB266AFB6DCD8A72D37B2
+:10F2900033E558248E1F3F9E6A739D9C44BCC37BFC
+:10F2A00011E8DB686C39B50BE66BFCA991E4514BB6
+:10F2B0006A20949A867AF9D09B086763DEE753D078
+:10F2C0008F5195F7278AFB9CFF01F3E2BCCF9B2B64
+:10F2D000497E9FDF6AF604E3F857B3A0FFDEDC5AED
+:10F2E000AAEFDD66F448BCBE765A05EA833436FEE2
+:10F2F000997400FFE62D733F25BB09B57628F7A268
+:10F300007E89DFBD2085DA517FDCC2E5DE69D01F52
+:10F310004D309F9308678C7BC803734CF09FBDCE24
+:10F320009A09C85F943F2B7EC4FF03D8559CBE7BCF
+:10F3300020CAA7B99FE75AF4F38C253FCF01E41BFD
+:10F340008DA688A112FAB9FACF5F115F5ED9BA848F
+:10F35000F4FA989E6B243EB2F2EE00BD7F7DEB3551
+:10F36000B4AE93B06E84CFC91DDC9E5B996D0DE188
+:10F37000FCAE7670FD77257C2749C3E19208874F64
+:10F38000B65FE3467C7FC2F878C13EAE277C621F41
+:10F390004C26FEE36949463DAF79CB359F22DF5AC3
+:10F3A000B943F6A21C67076CE41759B963F684E504
+:10F3B00056ECE7CBD44A84DBCED97699DECBFE106F
+:10F3C000F7AF0C5E0DEF959D977B709F1CDE61E49F
+:10F3D000F373989EC6F95FFD6799E85ED1B100EAC4
+:10F3E000ABBD06DF04DC6F9EED7BE6205C3F999FA2
+:10F3F000A5A3F6CF4BCC8E7070B4A6E3FB9592E23A
+:10F40000C7FD55BF65556DBC3ED2952A137E2AF3C4
+:10F41000D6A547AC44EF37A29C6BDCA127BDEEF02C
+:10F42000820F7F73B32B46EF2BE59E1B67C4E91B4E
+:10F43000CDDBBF2DE8012436C069A58093316F5D17
+:10F44000118EFB4DF4BFF2BE96221EAFF9FA7D106D
+:10F45000DDDFDBF97EF833C8FB8BE8EFCB766AF4AF
+:10F46000FBD1EC20D51F6DF232DF1E2BC5157D6858
+:10F47000E716B814AA2F400202FA52FEB076EF3B0C
+:10F4800030FFFDA9018B0BCA79CC578A78F50CD9CE
+:10F49000AB409DC42591FEC3B61BB93EA970BFDC2D
+:10F4A000E634F6F486B879E68AFE607FBAB09F3318
+:10F4B0001FFCE94D845F53EEE75378BCED2B8A5F68
+:10F4C0005907785CD3EAF533A48BE681F96C594986
+:10F4D0008C1F367B39BF1EC6575C7ACEBF5C43D4C7
+:10F4E0004F4D1AE767AA3F785B6B12F9FDB6B94238
+:10F4F000666EDF0619F2F3EBCA651E8F117A895F1B
+:10F50000F8D14CBED719C66B9857F68E83F2A0EF90
+:10F5100078672A94DF299FED95A16CF53DD9558038
+:10F52000EBF6EA45FD58F227BE3DB392F493EB7C2F
+:10F53000328DCBEA93C95E1FF4BDE75A06E35ECF76
+:10F540007CA927608C1A10D688C7411C1BF0655413
+:10F5500002D35D7176D3B7BD73534FC4CB4B1F97A6
+:10F56000FF688FF789B8C24870F0A6565E85F0BD77
+:10F57000FA2A8E87CF9EE7F6C76766EEE756DB7DF1
+:10F5800066E372C6EF52FD847DB9C8E7A3E5DB8A66
+:10F5900035716297A12F17F7D96F256D3FABBB74FB
+:10F5A00014BF5DD5C5285EFBD98F5ECE457EFBE9D5
+:10F5B0009E977397C4CD2FF13BF5798B3A9EF04B14
+:10F5C000A97E4A97885B2FF11AB93F70143FA5DADC
+:10F5D0009E6DE1F6D859E0EE4877EA7767EB937CC9
+:10F5E000A8579E6526E2674B0684DFD3E72B74A1FC
+:10F5F000FDA07E9FD0FF23827EA47E89EC734BC941
+:10F6000010F1D75526FF9B633C98B7E223FCCC450D
+:10F610003C4A48AF3E03AE5B11769E51F1DF8178E4
+:10F6200058DEA3C5638E4BC433EC2EC2BBA1C9AA5E
+:10F63000A07C48EF10FCFA7B3AB25F0C596E2BF2BB
+:10F64000A5AB8B923A312EEF4A4A9E827EF59CAC56
+:10F65000626A1FACE2741D4C67E4B7CA642D12F1F4
+:10F660005B3BF783674F6776CC03F9A98BEB0D6E95
+:10F67000E6DD22933ED827513C40AC5FE5EB482FB6
+:10F68000C8E73E934C442FD28044FA9DACEB5B8498
+:10F69000FD8E463F5B5CAA5DCDE9275AFE1BD1CFAC
+:10F6A0006E75BC61F413A038DE12B76964FA117E7E
+:10F6B000D74B6E3F5A1CF17B26D50F2DE17A6B4557
+:10F6C0007FB5266B589E42FCE1F3787FEA76D03313
+:10F6D000D11E51E38E633A167BB89E3E1841BBDCC7
+:10F6E00072B989E4DC0F7583F9A8CF27C62101B36D
+:10F6F0000EE4F7C863C8AFD85AE53F911A27EF0F59
+:10F7000070BBA1E96E1FBD9F35C0E57B73A181F47D
+:10F71000CEE67E2988786EF21B42A67C8ABB2C2618
+:10F72000B9FDA0D9C3E3289E768AA3FCC0C3E32C0D
+:10F73000513F6A64E7BD486FF556F23B24C6635EED
+:10F74000FA8BCCC71FC768FCDE521EFFE99DEB2178
+:10F75000BF46629C8D7569F7AF1A67396B03C0C0ED
+:10F76000784B369A090F593287334B3171F9329CF5
+:10F770000F90BF367DBA408C888744F73590249629
+:10F78000B344BD1ABFB195F8F351C35D94BAFFAD50
+:10F79000A4697F4DBEC33D3FC47C8651F31D82C624
+:10F7A0005AAC37A1F62CEA71DA206FD5B2CFECC192
+:10F7B000F84EAC5E01BDD1D42F89F15EBE7636889D
+:10F7C000E0B3923A7EE7069F95E2C99AF1E2E7A795
+:10F7D00024F4AF87FEAD1ED13EF8E3B9B30B296E1A
+:10F7E00029EAA50D3E98DFC37A6D7F0452F13D16DC
+:10F7F000D4F10E67D4FC70E3CC98DC073DC09A3698
+:10F800002D26FF1FF8B0B6E73218CB62FFD2807208
+:10F810005595E3CD2E9EFF90B85FD3D338BF07FD3B
+:10F82000353D8DE40ED76B6B45FC12F4D939B8B574
+:10F830009AD7F919C62F415FC84A237DE1F3930790
+:10F84000117F0B3E237DBEF982C2FD2EA077A07EE4
+:10F850006E1274CEFAF5246F553A582DF84FAF0357
+:10F86000E43DD2EB01695A90E8A225F706C0C1DF5A
+:10F87000A7F90A711EAADD9538DF2BD3B87DDC5CB1
+:10F880005CB5B508FB7F4A6228EF37141F4B47BDB4
+:10F89000A479E0E3F4E571DFADEA7F94E0B06AAF0C
+:10F8A0007EC4F55F99C6E39D4DAFBC48FEC1CF4213
+:10F8B00012EDE57A25D43D03CAF5F53AD4D058794E
+:10F8C00068F1CDE4EFAF33B071B0BEB1288F701ED8
+:10F8D0007BBF139C81F619FC93E0D536FF0A927B1F
+:10F8E000DBEA4C568C3B34172FB983E0604FF22192
+:10F8F0001C36145765E2384DF3E7D8294E00FA1547
+:10F90000D637DD7D0BF94DD4796DE8D7D7A0DE551C
+:10F91000017AD63FC1BC739CF36ABCB0FFC6C8FB7A
+:10F920004AEFB462DC7864FEFB5E3AC767A7E40F77
+:10F930005E5F4E7E4216EFF7CBEBE7FADC0D690611
+:10F940008D5FF8863485E0303338380B69EF352524
+:10F950006241BDB799F9BE40FB92F9AD9E3D842747
+:10F96000CE475C6D1EF21F995C911F5E86F53315C4
+:10F97000B21F98127904C73DD3EDF26E60827EB15A
+:10F980007C774908F9E8EB69812588DF0AA13F9E69
+:10F9900079E59A52F4B3A9FA51F72E7308E384DD9E
+:10F9A00036CF3FD4201FFC83C2E3E2A6A1C1598811
+:10F9B0008F3F3AA9DF6E73A81BF11FDCA4A7FA578B
+:10F9C0006C8146A4CB53F36B8A282FC71A2CC238FC
+:10F9D000B0DED5C3504F007381FC0926979F61BCF0
+:10F9E000745670B122219F4FD03B6689FC52629EB3
+:10F9F000F0BE4AB0B1714005274DB4053A2FA6C6F6
+:10FA0000F490237F5AA8E04B553FD199783CABBA8C
+:10FA10002E89C948F7EB87DED4A1FFDA3548FA6BA7
+:10FA2000639F44E33416BF40F9626B445E52343F37
+:10FA3000488950BED4FA348BD0033BB91ECD06C9D9
+:10FA40005E66CF717C3216A13CAA981DD14EEDD4D2
+:10FA5000FE0CC2EFDE28FC2E20C1A87E539AAA5FBE
+:10FA6000DEA7F5D78B71374B833E19E15A2A69FC23
+:10FA7000C5EA73AFF83EE5D0D01CDCBF43AFA87930
+:10FA80009C3C4F73EBB4895E549D86E571F67F31E3
+:10FA900007E906146DDAAF4DFD9796C7F9BCD86734
+:10FAA000FFE3799C5EC9B71B9E2FA739B4799C5E92
+:10FAB0000E3F35CE9698BF792633ACF07CACC8CEDD
+:10FAC0003D489FFD46CAF3AAEDFFD9FB281F6B4DA9
+:10FAD000AC0FE390897A469BFD3B61A4FBB3A74F33
+:10FAE000EEBC9F611EEF4B5ECAE748D01F12ED844B
+:10FAF000DDD82473747DEF37517C727D2F5AFE1F41
+:10FB0000D7F7B83E1FDCC3F307547EDE2CECB3B34B
+:10FB1000F5E79251CE1C4B53F5CF843C87A7449E0A
+:10FB2000C3C0C8790E8AC817027D3D4874B28FC71A
+:10FB3000758E3C6D21FE71CEAEEC467DE9B46DE86C
+:10FB4000FB082C45E8499D078C1EE417C0EF887F11
+:10FB500007F7E9799C06E33618C7796D8288E38850
+:10FB600078D1AB16D25B1A923D29F8BD1AA7F9A934
+:10FB700090370D493C3ED36509FC3E6D84B8CD2ECF
+:10FB8000A17FED82AEECD8DFFB4611C7060681F6F9
+:10FB9000CE83393CEE20E2366745DCE678B12E6C48
+:10FBA000E07E08F25379BA149609F59EF7CD210F3D
+:10FBB000F767997420F797AA719BD7B89F6AA988AD
+:10FBC000CF1C5F3087F28796637EBC8C7E0CEE671D
+:10FBD0008EE6EB33BB0ED7B306D8C5366431418011
+:10FBE000FAE5F05AD249A84F783AA14CCAB2AFA769
+:10FBF00006C65DD2A9237B646997D65F7E7EC31D4E
+:10FC00003528BF1FE8E4F1C7609744F27B29F3B9B8
+:10FC100051DF50E9615C7A2AD159B053E7C371AE24
+:10FC20004CE7FE04007D88D6279E9D7AE16717F396
+:10FC30006867BA303E75127F3E60576A4694CBA221
+:10FC4000BF4E7D8BA912F5D81C1DF979CF1B7C7591
+:10FC5000E427751611DE3A6D2D5D35BC9EF6CA7926
+:10FC6000F3909FEAAF54B8A2C73C4EE49363D245E9
+:10FC7000FC2661BDCB7BB4E5C4F8C3AA90B6BC94A6
+:10FC800005C667E23985BDDAF763D239FF3FBF2188
+:10FC90005FF8F9BDE4E7EFD47B7E958F7CAA5B210A
+:10FCA0003ED99ECDE1A5CBE1CF0247751DE9070EF8
+:10FCB000D02B68BE7CFE0557BA2494979D0E4E97B4
+:10FCC000FFDD7927CE77767A11D71350B9C37DD46B
+:10FCD0002D8538BCF8BC2FD55FB1225D6B6F46CB4C
+:10FCE000FFF3F626A7C76E59EC373BF19F2522DEBE
+:10FCF000785CF23E1DC6F756D00B60DE4BBBE5329A
+:10FD0000D44F667DC74AEB687ACD1C32427DE3BA98
+:10FD1000482EEEA3A6AA4851CB0870C5D92A2ADFDF
+:10FD200082764B5C601FE0BEEDD2C6A186C7157D12
+:10FD3000F7A6A7A11D727CDFCF10DFFBCC2497E0D4
+:10FD4000BF0E1AD1DFF14A3EE94B5352021DE9289A
+:10FD5000CF93C23B9FC947FD84EB478D03C65DA887
+:10FD6000FF2DE9D49EAB611BB5712ED6E5247F062D
+:10FD7000EBD5BEC7F32B9AEF86C5BDB89CDF6C08E8
+:10FD80004C40BDEEEAAB787CFDF42A1D43FC2E9579
+:10FD9000BD2B908F9C366BF5EED3368EAFDDE9AA86
+:10FDA0009CF116219EA3E56178F616219E97EA58EC
+:10FDB00020BE9F46C4F354CC4EE7783EFDE2E545B5
+:10FDC00088E7CFF75D5E8478DEACEFF1E1BE79C6FF
+:10FDD00019781AE17362B69FF42635AFF252E9B191
+:10FDE0003F811EFBFFDFD1635D7CBE5FA21C3C1C1C
+:10FDF0008597560EBA0C9E6CE4874B4CC6AF958720
+:10FE0000F837A23FCD64247FC46B7FFAF221946F50
+:10FE1000C10199F40FB5BFD794C058F417BCF6BE12
+:10FE2000DB1B9446EFBF45E8556E130BA2DF43D5AD
+:10FE3000F755BD31911FBF2FE0782ADD578B7AB679
+:10FE4000EA9FAD177D9A425F72FDF42989FCAF26C7
+:10FE50004F1FCFAF3FB0D88EFED95321EE8F6D7AB2
+:10FE6000B194FCB5AB42AF8731FF890D4876B41B26
+:10FE7000563DF57132C6B3C10EFD243D2EBE325B38
+:10FE8000D8A1A742C79331EE0DE3D7A05CB6B886E0
+:10FE90000C48BF4D609F4113D6A40CD1B9A22617C0
+:10FEA00023795FDEAFB5D7D4F8E436BF81F8DDB68D
+:10FEB000012984F659BA21909F8DF28965DB4F5A4A
+:10FEC00062FBE577E93E17C62D637161DFEF715E76
+:10FED000AA5F27B23585E830A2673ED203B6DA04BE
+:10FEE0005FE2F19ADF6D778478FE126FFFBB503EC0
+:10FEF000955579BD429CD35B21CEE921FF0E27F0B9
+:10FF0000EFF87234DEAC9E47037E1E1E29FE1D975D
+:10FF1000B714FF7D131B12F979178D9A7EA3F93A56
+:10FF20002DA51E98F79ADBAC740EB119E8BAB52C62
+:10FF300046870D62292A1D3609BF6E73FD31B20353
+:10FF40009AF1FC05EA555E4E870D601F617E67E2FF
+:10FF5000BE657DDA7CC6D1F6716986761F47CB7F98
+:10FF6000233FE6CC0CEDFE55D7AFFAC1A3EB1C90B6
+:10FF7000F8FE4A5857A25D99E8BF56EDC24BE56BB3
+:10FF8000DF89CE87C3235AFE1BF3B5DB3346E36B11
+:10FF9000DAF8C05FCDD712E30485DCFF8D71028CE7
+:10FFA000DBFE77E3049F7A7AD2753C4F5F133FED17
+:10FFB000925AAE338DC5B8228F2F37DA8C14874D05
+:10FFC0008CAB367BE68838E2E06FAE40B9B95FCFE4
+:10FFD000509ED75B5752BCB2597ECE80470E87C524
+:10FFE000139583A4B7FFB571F5F5193617F1230FF3
+:10FFF000CBC7B87A625ED1EBD62F530371F8AD2A26
+:020000022000DC
+:1000000001857F043A362941167F5EAD3783EBC107
+:10001000AF8BFC17B781E7B13F6C033B0BD6E7D63C
+:10002000F1FC9CBF4FF36FCE48433ECEE1F7C42BAB
+:1000300037313C77F484BE8FF844B0D1EA457EA7CF
+:10004000FA55A2E309FBF352E9FAC709FBFCC77FA3
+:10005000E37DDEAFD2F35F1BEFDA026BD5D03FA3B7
+:10006000B8D6DB18AFC91F4EA7A3F5331ABDFE22C1
+:10007000C3FF6606ED33DF14CABBBD447E62291F91
+:100080003A8EFE1BB6DFE8417BC224CE65B08D9967
+:10009000224FD25B319FF285F9B906F5FCC7687A29
+:1000A000DFC7D1FDCEF5BE8F47E53BFF35BDAFCDF8
+:1000B000E93F8E72F644A5AF08E5E20336983FDAD1
+:1000C000733F328E78CE423D0F00F4C4CF9B3CCFBD
+:1000D000E3DC8974F587047EF987FF257EA977FF25
+:1000E0008DF865FD1F93D1AF397A3F419EF75B359F
+:1000F000E8137129867121751DCD833CBF2C5DE409
+:100100004DA9EFBF127AECED6E5F861B9E9F7F605C
+:1001100032B114507190C650DFF25BC9DFDFD4C733
+:10012000F3409AD6318AEBAAE7289BFAE733D4EB5F
+:10013000F6A706F2F1FB073EB406E514F4832F6040
+:10014000A8CF9DF980975B5203E3B0BE795D44135D
+:1001500057A8B8F8E57AF457C07CC9FE7719B5E717
+:1001600029E6BB393F539FD7097847D7E5E2F364C7
+:100170007D7208F5408B6790FC444DFBB9725621A7
+:10018000FBC81FCFD638E97C44D3FECA523A6FDE93
+:10019000672E453DB6E2A35A3BFA1F3EBFD24579D2
+:1001A00004B9726415EA51AFA70566E27C6DE5A15A
+:1001B000B9A887E6811E8A7AEDE7FBE69606E2FC9F
+:1001C000D99BD19F0DFD6EB669FDD5CCC4F3C0EBB4
+:1001D00077F33CDF576C8139D8DF66339F6F7093BC
+:1001E000C86B167EECC4FDAFEEFBE839C75B4D145F
+:1001F0007756F9C2663D0BA05C53F94989C8830361
+:1002000078F03CBC81F93C9F4394AD2E6D3EE2A951
+:10021000F4D925389F12378F0B2C370D49E8575FDB
+:100220002EE2ECD7887C09353FCAA8F8BF8BEDD900
+:10023000BA9A587CBD00BFB78B73BF3C0FC67281A2
+:10024000EBC7057603D18D0DF617F93F806E103F91
+:1002500033870667E179A2C2DEF04C84E76B17743E
+:10026000040F65FEDB141F4941B4413F633746BAB2
+:10027000C7A39FC4FEEB2B112F9E1E7B15826E7FA2
+:10028000AABFD14DFEEC9662B41BABFE59CFF3FC76
+:100290000E58C8FEEFCD6DA03CBF331F1A473C1768
+:1002A000A23E83EC3ECAEB2BE87F8FFCF4B6FDD276
+:1002B00088F99A5D6E2B8F1F0507297F8CCD74F10D
+:1002C000F384073EA2B8AED2AD9087A253EFD3E13C
+:1002D00039A8603B23FFE4B85EBB0EF19227F247DA
+:1002E000CEBEF69F53026487A87EF910CFF7D147A0
+:1002F000D6A35DA5B447AE821DCC1AF73B744D253D
+:10030000D8DF5013CF5BB730A493BCFEB1F77D0BA1
+:10031000CA795D762621FF79754D1EF943619DE30B
+:100320004658E71D6E9E9FA31CB0E8506E299B188F
+:10033000E5172A8EF42A9AF7A350867ED608BA517A
+:10034000E38D305D37CAA3DBDD811D88EFE8399886
+:10035000D6247E0E469CBBB4B57EF83C9E2FD96950
+:10036000E0E70C0FBD366901F9E5BA1509F170DE59
+:10037000B138CF0EEFF78A7D6B530699DD1A0FFF68
+:1003800043944F597080E79D297A4E274AB76B17DF
+:10039000FAFD2EA404286FF4CACEB04CF12AFB89D2
+:1003A000476A3C7176CB162E479AF6727B39D14E4E
+:1003B000F926F971D0ADD54BA2E5BF915EF27682F8
+:1003C000DCF8ABED0FA6B5DB12F593443B6D985E00
+:1003D0009DD0DF687A8A9AB751151B87E8E1759B33
+:1003E000AA070535792D555671AECDA4ED7FAF8B9B
+:1003F000F30935CF25BDC3D38E79E3433F60E4478E
+:1004000053F36D8255DC2E08EA4C74DECDCD7A288C
+:10041000CF660C0B4B12E9F7113AD79981F936F0F8
+:10042000DD07EE027E3E8579BB64E2871E09E76D3B
+:10043000C63C0DCACB0C6D5D81E3DC60A571CC9828
+:10044000A7311543EDBEADC83F67D5F3384316C895
+:100450005BA4DBAC424E87E63A9EAFA1E663A8F907
+:10046000132A1CAA047CB3C6AFC847FDBF5B0AFCB5
+:10047000483D4F1B7F4E3A7A3E7A55019D27899E13
+:100480008F2B64A2FED2CE4927C253CDDFA8B2077C
+:10049000EC9969C3CFCBAAF41187379AD7B6035C1E
+:1004A0005FAFAA37D0FCCFAE9A477EC2B3AB740C15
+:1004B000F74DD58091D35BC278DBA2F76084CC7412
+:1004C000DF85C0FB37E9AB80CF62F4C31E6AAB990E
+:1004D0007A02607BB8CD4FCFB366A94FBE8CCE2BCE
+:1004E0002E42CEF465E6B65ABCA7E0AC6D2817EFF5
+:1004F00039F832EBFE6F53396DE8289693B39EFFBF
+:1005000036DE7B7076DCD04EBCF7A0705B25AF4743
+:100510001ACC62ECB2CC8A6F0769DDDCAF342B7683
+:100520003EBB1CE1D3C822EB07C97FC3F3F3319F65
+:100530000FF1E0B61A489F718B3C4A562DF22A31D2
+:10054000C202E58ECC528A475B9967FF20D667F3DB
+:100550007340504FF4DB318EFB7D4D02AF2C5BF5C9
+:10056000134582C89F3AF21DF47D948FEE3786B80A
+:10057000BF8A8FFFEE8B93297EA4E6873266CF5920
+:100580003899F2493465F57E03A6D873505FE8D0F8
+:100590000BBD5494535302F333E3F4A27767FF5D2A
+:1005A00009EE83D32FDD5B887CE91A03E8ED23F0A5
+:1005B000A17FCDE27CE8ACDEDA25819EF65E72E0BA
+:1005C00016ECE77DCBA2390E58575D6AA5C181F3C1
+:1005D0000DFE4846BE9826F0ED58C8E7E7A8F64B52
+:1005E000CBA1DF0E33EC5FF83E2DA0F8288F3EB094
+:1005F00050BA01E6DD21717E0B1FA5905D52EC49DA
+:10060000C1FCE406711E5216FBFE8ABE4D32EAD3CF
+:10061000BF6AEB9FA114C6E53B88F8F17BF9ECF6C5
+:10062000F923F82D5B3339DF5E207B26231DAD9740
+:10063000FADFAECDC4F79C1E6727B796635EF1352F
+:10064000969672943FC3DEA7C0FB92B8B291B76B87
+:10065000300DE5E2F9649F25B02E13E33E8B3FA6F3
+:10066000B8E4F7B3DE3D8A7905EFEA7B6625A37C23
+:10067000C917E7FA855FF0CDF1AA5FD0C4CB93B874
+:100680005F309AAF3599E78BD52EE4E7106B453E86
+:10069000C21C3B3FB733A73CDFDB0153BC8E0D29A7
+:1006A000C8F7E6BCEF4F46BB9D2D0C94FB278FAEE1
+:1006B000CF30B7DE13BF5FE77AE2CAF0EFDA626DE0
+:1006C000F9DB5E6DF9FAE97F1E1F5FDE65F16DC52E
+:1006D00075FF54E2F98DC12B989DD6E99282A877D7
+:1006E0004C7A394B9CDFE47978FF28ECA297A7334A
+:1006F000AA4FDF6BDA8DF9EDAA1F5916F593DCCC02
+:1007000094E7E4F705A0BC1A92443E9F8B6225EC67
+:10071000A53BEC1C7ED0D600FDBCB4D843FB23DD4A
+:10072000AA6357E11E2A37911E5231C6948474730E
+:1007300048D09D7A1E57A5C30A85F9313F01865ED0
+:1007400088CF77F5F683E83F0E7ECA18C757A542D3
+:10075000F985622CC6DAA9FC98A0EF43624EC11F4E
+:1007600028B49FDFB019089FF2CFE55D282730F647
+:10077000827EE1731B27D2FCD4FD03BBBAD0954E19
+:100780002E6BD1AFA2C349140B7D42A56FD480B0AC
+:10079000DD18FCCF7CA273E23743D3F8FD09EFE507
+:1007A000737E32B4C929CE7BF178588E29DAAF0F27
+:1007B000FBCD8C8EC3CF13A58B32548575B0EE4F15
+:1007C00032F369D34A033FFB03C965AB3780E318B3
+:1007D000924D740E46DD37F6CEDFBE5D7B05AEB3BF
+:1007E000E87BB4CE79363BAEB318C8BACE494F5F7A
+:1007F0002AF5C7F78F9CE4F5E03EF94ECD2B3394F4
+:1008000038BA81EF1BF9F716EDF76EF8DE19F77DB0
+:10081000327C5F32FCFBA76CA6B06E0AF653E1890E
+:10082000103F0FD362E68975C9E9FCBB7922DFB3BB
+:100830003019DAA3BC29D6E663B0E95E13BFAF4333
+:100840009B7F718DB42E13F7D55C53E34004FAFB04
+:1008500099C0DB35BAC057783FDDCF16151DC6FDF0
+:1008600056630A29680F5DCBC2EB1199672B034FC2
+:1008700038C6123FF80BEE8B263930DE09E5D3FA85
+:100880009EC23BF269BF5CCC9C367CBE2A5DA8F35D
+:1008900045FA403A8BD247C2BCA378BAAE8F12D584
+:1008A0007680DE834F550F024B9AE7137B7262EB23
+:1008B00002229A636A29443DE467ED41E21BD7387E
+:1008C0001EA1BCA5336302AE2CC07FDD655FD0BD29
+:1008D00026CCBD783CEAF730DFB4ACB4FFBDF9AA52
+:1008E000FADEB07CDA4F0D9A7CDAD1F6953A6E33A7
+:1008F000E3F7D3CC1AD845F9B1CD0BAD5E3CE7D0C8
+:100900008CF99DE5143F223D0ECF01D33D2792493E
+:10091000E85D979A77CBF7616FA387F4B7281F1725
+:1009200079E3BDA57CDEBD7778D47B4EB87EB798E1
+:10093000F17B52D47B4E96DBA95ECD2FEFDDC5FD5A
+:1009400078BD2F8EA7F350A0BF91BEC052747C7E9D
+:10095000F9DAFB55F04F4A8FE5436FD6737D739BF1
+:10096000CE5B8170DE86719EAF89EFDE94A5F59B2C
+:10097000A8E544BFDE33CEC02D59E80F28F1E54A83
+:10098000403F4B0DDC6F07F4B51DCF4ED4B096A79A
+:10099000F0FEC0B9ACE5D7BAB1445F01A2AF495F80
+:1009A000F07B0563F4B598D3579098924A5F51BA9B
+:1009B0002A4ECC9F0AACC6F6BD8EBE8F9A504F1DF4
+:1009C00030125ED43CB8C47D1C379F137A3E1F970B
+:1009D0002CD37CD68E349F4BA1F378FACA609C9EB0
+:1009E00047A3F70C85056D65317ADF6509B4E3B877
+:1009F00051BA5FCFED9161F396AD441F37DE2CF312
+:100A0000FC700B9757188FC884F1E78BF16FECE6F9
+:100A10007474A3CD4074377FA091F28558358F2B25
+:100A200078E17FDC0EF4117CEBC4770B5DA57A24B2
+:100A3000D985B5DAF8439D558D6FF8F5B81F6F5C11
+:100A4000A83F162FEFEBD8C62F30AFAD0EE314EA58
+:100A50007730EEE359D1F37FE3314E7158D8E9672F
+:100A600081BE91FEDF485BB9FD0EA0DBF18F97944C
+:100A7000A13F6776FAAAA73641F9996D13A9FC46FA
+:100A8000FAAD77BD8BF53B8BA85C8D97B8A0BDD137
+:100A9000C8BF2FAEB8795E3E8C7BD82CFAC57D8559
+:100AA000765F52A0773EB4734F2928C37CC36AC1D6
+:100AB0001FCEDEC1F3DDAFBDCCC65338577AC86F49
+:100AC000549D24EABFCBFB7DBBF45FCA30EFB4BAC0
+:100AD00080DFE3F276D94F2762F9B0F4C5A291E244
+:100AE000DF938AA5F004804FB593B7AF2DFB511665
+:100AF000DAF1D555BC3CC95BD93D16EB75E7168DCF
+:100B000074EEF317623F45CF35897DFAB2EF633A51
+:100B1000C7E437495E5CA27FFAC7FC5E22AB64473C
+:100B2000FFA3DF97AFA09F74968FE7255699DA331E
+:100B3000D1FEBD2E6028C7FC52BBA9F430EA1929AA
+:100B4000D32BA7217E6799981EE512D0F9FF213A91
+:100B5000BFFC8BDC64242EAB96CE553A9AAFD2778D
+:100B6000B5968E617FFE7356DA37F3D7D1E818C693
+:100B7000FF77E41375DFD2CA95687F09FB2DB1FFBB
+:100B8000D1F800FEC5F3B9D83CFA685F6563D6D7E3
+:100B900058DC773DEABE1BC27518748374AE234FD0
+:100BA000F24EA4038DA3C87F757E39C0DB58D9F0FF
+:100BB00079E19FA2EA65FCCF85766EB6A887EF7CC7
+:100BC000CC199B178CCFC6A0DC5FCFE7B3436AE19B
+:100BD0007C43E8C5AA7DDCA4AEB75FBBDE8A247E79
+:100BE0009ED98DFE0BFCCE553AF1EBE6DD2CE4E60A
+:100BF0004293FF4123ACE106C752A2879B58F045C0
+:100C0000D44F8C2901E79834B4BB820722F9E4CF92
+:100C1000A5BC00C077EA9838FD449D57223C9A460F
+:100C2000E18789F34E84430C3F83A45FA9E7A3A225
+:100C3000EB4A588F2AFF5D06AD1FC829FC364EE1EE
+:100C4000A7410A413958CB92286F61965722395EE5
+:100C5000CB4CC43F6B6BB8DC745AB99C57E5EB685E
+:100C6000747DF5559CCFD4363071EE8ACF3F91AE6E
+:100C70003258E47BF8AC3579B62EC3FD8AFA80276A
+:100C8000B6DF6BADDCAF3B778CF01BB2C834B46F12
+:100C9000A3E5617EC4C834E41B89F745D55EE07ED8
+:100CA00044A7B897B5D6FBF134B4D79D359169C840
+:100CB0007F1E74F8E621DED4FBDC12F9CE8D63745E
+:100CC000AA1FF192E82D110F6ADC2835C55F87E372
+:100CD0009C96062BB0F29134E1D767817CA44787BC
+:100CE0003DBF12FD01C0DF2E5E44A30AAB005ED300
+:100CF0009D8100D2DB4DCC3F1BCFE2396B027AEEF7
+:100D0000E766B4FEB562FDB385DC3BB75D263F7D8B
+:100D1000B5AFF83174A5371FD1B310ED3B1FC9B182
+:100D20003562FEE718C7D3392B977F2BDFFAA70A66
+:100D3000A05C367E8B2E768F01FC9B104AD2DC6342
+:100D40003069AF53539EDC97A5697F597F81A6BE5A
+:100D5000343C51533FF54899A63C6D7086A6FDE59D
+:100D6000EF5769CA5744E669DA7FEBD4024DF9CAF6
+:100D7000A15B34ED8F0BFB94057D83C5E978CFB77C
+:100D8000A0CB0B4B34DFFD3679CE11A4CB651B799C
+:100D90009E70254046739F430F97EF2DF03F8E576F
+:100DA000BF82F05A017A2FE607AFDCA295FFF50368
+:100DB0009BD6234F4BCC5F58CD5AAAF06AB8C4FCDF
+:100DC000856AFB621DD2E1E363449EC2E5EC727169
+:100DD000FFCAD7E2B58815FE97F06A746BF16AF620
+:100DE00068F16A29D6E2D5E6D5E23565BA16AF0EC6
+:100DF0009F16AFA9355ABCA6F9B578CDA8D3E23570
+:100E000033A0C5EB987A2D5E735AB478CD6BD5E2DA
+:100E10002F3FB85A8BAF047CABFC6F6CD75A4DBBDD
+:100E200028DEFDF5947732AEE71E4DBF2ADE83F053
+:100E30003F8EF716CA0BFF6BF10EDC86FCA089789B
+:100E4000FF2001DF20373E44BE00F2FEDFF05937BD
+:100E50005EE8D5FE91E5BDCA7FE2E56BBCFD381AC0
+:100E60005F1A264F843D39AA3C49B0273FC0EC1891
+:100E7000D2533692BFE566419F5FE2AB2BD09FF91C
+:100E80006392931FC044A6C3BC3EC079C3381F24DD
+:100E90004D227BFF5616D6D3FDBB98F1079DDE8E03
+:100EA00009C032DE9BE3A1E7522147970B7F80CF39
+:100EB00012B83886FB01F2D271DCEC417E0FF2DB16
+:100EC000A997741FC031F4872B8C9D407F383CCF8D
+:100ED00098393D9C54F9838F795C71705B324B2A51
+:100EE00026BD514EA2BC9C253749244796FC9E3F07
+:100EF000D3B3B9FE99F8EC6855E1C6ED9299D91EC5
+:100F0000E2EBD9AC4FC83B16B08EA57EB8FFFA49CC
+:100F10007E0FE8F31253A63BE93812E131C3C4E770
+:100F2000F5BC9E99107ECFB28007E1F243055813BD
+:100F3000CF879F88F4B0E4F7EF16A03F49EEB05F8B
+:100F400087F73C4FC0F1601EB36F6B91D0BF9AE141
+:100F50006E91D07F33ECFDFE7B243CC7172D33DE32
+:100F60000EFF100EAA9FAC58C7E3C54377703DFF34
+:100F7000A9EF32F2FF74B4062B83182792C120C365
+:100F80007C123D3FF73B339BFBBF32D920DD2FCA9C
+:100F9000DE14FA99B897BD44E4979F11F19615BBFA
+:100FA0004C0CF3154AF61D74627C6505E07210E581
+:100FB0009912A07B2C4AB6BEE1E4F77DEB1D785E6A
+:100FC0004C95A3A3E35B6127E3F2B4018F23DE1703
+:100FD000795B0E97E31D6D3533313EA2CEE7FE36C9
+:100FE000DF4CA40F59F1529E17DE6FE388FBDEE061
+:100FF00082FAB8FDAB586B3465BDD54F9746AC6FE0
+:101000006B213AD38B7B781EC85E6B8FBFBFFFD638
+:101010006CA1479882CC9ECE840A8B4FE524F28740
+:101020003F326E0F1ADDD04F3C5FBB2B97C5FB776D
+:10103000BBDAFC34DFF55220809D180B59D89C8C0C
+:10104000F90378C611DE6FBDE608E6B3186C6BBD18
+:1010500061CFE87033BA95F3F17CA9215BCB97FEA1
+:10106000A1ED14C1A9A3AD8EC63B83BA1CFA773299
+:10107000B97FA7A36D31BDD7D578889E5EDF3AFED4
+:10108000A007EA8FC23FBC8FC6E8E2F362E5B9244D
+:101090009F16093A40DF510ED0CFD1563DD1D99D90
+:1010A00039D6106EC23BDF197710EFD334008CE4D1
+:1010B000BF62DED171049C0C822F013DF971BF1912
+:1010C000B214F2C33AED0B084FFFD5FE54F81ACC18
+:1010D0008CEE7B31E458C97F72A9F3DC922DEC7C55
+:1010E00055CE97E7121FBD53C0E5F5AD3CFFE7E8CD
+:1010F0005D8CF4EE3BEFE67EB03BC18EC77DC95AF6
+:10110000E1AF2246372ABF4EC31B37E0654F1B3085
+:101110009A22C61E6A33E1092766417FD5D8181E78
+:101120007B7C8A03DDE29BAA5DF3F1F9D0F4133DE9
+:10113000C8561E9EF9D5203ED1D78CE3DB5B5808FC
+:10114000F54C8A89C2F88E7A28C3F8C9A23E39C004
+:10115000CB29A23EA58E97737C2F48D538B18478D1
+:10116000448ED539B710F9DE32C6CFB78AF3ED3BDE
+:1011700004DF1D6375CEAFC6FADB18E5BDABF58F96
+:101180008BFA4CEBB1AEB1C897176ABFDF2AE0907B
+:10119000613DD6338BE216DA7A35CE90663D7784A0
+:1011A000BE2FD1D63F2ABEB759CF0DCEC2FA42EDDF
+:1011B000F80F8A7A8B95F343E6E7F794AAF53F1484
+:1011C000F5662B3FE7053C5953DF2DC6EF9042846F
+:1011D0001FBA8B15F74F1AF75BEE6C6357E2FEE907
+:1011E000691BA27DF450DB05C2D339CCF39916DB21
+:1011F00057F65636E2B9EB73829F247B223EDF0816
+:10120000FC4EAD77DAF9B972D96D203A325A05BF82
+:1012100010FB30CA2FA4162F272EEE4FFE267A86FB
+:101220000D761EF58B5CF8437ACEBE4BC702717CFF
+:101230002BAB218905E2DABB973935E5F4DBB23413
+:10124000ED5D0B0B34F5D6F2899A7AE6CBA1FDB2AF
+:1012500056D055524999A65E3DEFCE7A7234FAB314
+:10126000BE7086A6DDB9620FFD8EC7C9B9EAEF7DF3
+:10127000784DC817D6DA0A3250EE3CDB361D956C35
+:10128000F63CEC273CA2F49C83E7F93E87F151A899
+:10129000FFC7361FBDDF03F5A0B9B02761BF79A036
+:1012A000FDAE363B959F6873D373479B879E8FB780
+:1012B0001553FDD6362F951F83FEF1F928F483EFE1
+:1012C0001F69ABA1F2A6363F951F6EABA3F2836DEB
+:1012D000017AFEB0AD9EDE77B7B550F981B6567A89
+:1012E000DEDF16A467475B17D5170BF9F69C382F7E
+:1012F000F85C253FFF9B88C7C939C28F26E2F8B644
+:10130000581C7F720EC6F1FB229A7BD671DDD49FEA
+:1013100099AF3FB1BF2AD1DF4436D86EE1FB98E2E6
+:101320007FE3FABDF75980DEC7B4703CE4F70F5194
+:101330007D663DC74595982F73055976053FEE8923
+:10134000EDCE488355161E0F257F0073C33A2BC47C
+:101350003D344476211DCE4B99CEE5A68AD7E8BA16
+:101360001D7C9EB8FE91E6FB6D315FB9BC8FDF330B
+:1013700051D31346B24FF2B5D03D13A63A7F187F32
+:1013800047C2E50FD0B9F78917E68071037CE6C242
+:1013900055CC03CFEC06ADDD93B5AC4C635FC817FD
+:1013A0001E629EA9D06F89D63E492A5CABF9CE94C5
+:1013B0007D8FA6DEE0BA4F53BF644DFE7A37C2730D
+:1013C0000CA3388971633BC3D0DEF2DE4D34AF7BB2
+:1013D000C53ACE481E3A371BDCA7C6C9B97EFE8C7B
+:1013E000902BCCB491F6C378072F16A50475281757
+:1013F0003EFFA714E2474F3FA10BA11F74020BE968
+:1014000070FF4F02750FEB27E34DB5325D5D226330
+:10141000B99479642C4F6543649F807E7E27D20BFC
+:10142000E8E74F98314E97137886E70F85496E1697
+:10143000097C16A9F6C81625D13F7A770EF93FB474
+:10144000E7863A859EDEEEA8C8C0F8E49951F2BB63
+:101450006CEE1933F0F7AC6C99D3E9A9BE7FD0A339
+:101460001BF13CECC61CD58FC4E97E0210B9A0FB71
+:101470008D388FD3E5BF4A4773AFA97088E8FF8CDA
+:10148000E4732F46B8BE25733A1CC8A4752902AE72
+:10149000CABE4AF762809FF2CE586F90C5C679BA2D
+:1014A000CD37435162E522919FB8B76DFE8CEAB803
+:1014B000F7FD027FC56CB006E5537189CE1BA29E75
+:1014C000DD1AFE652EECF1E1796EA58C7991BD4DAA
+:1014D000603DF7A1AC56FE2253BE8972E80AE601D0
+:1014E000BBC06A0D33CCCFE98FEE6FA6F99DA3AFD9
+:1014F000ECD529742F5F5694EFA14CC4DF351A4404
+:10150000FAF9AA57CFD775485B5F6CE579342B8A17
+:101510000D218F84E1ED1EBA7F4ED9293154FD95FE
+:10152000BFCC2238B0972C447F962D53E8EAEAEBE3
+:10153000944008E9E374D8F3926EACA04568D738BC
+:10154000C9B01BF5B1F108175C506131C175B958CC
+:10155000EFDEB6C504A77704BE3A7312E6C3BC3EFD
+:10156000BC9F7145AFEAFFD0AEF3C1F2AAEBF13EEA
+:10157000BB8E4159E84A5A786ED00F4EC1DF883B86
+:101580001D8179C934CF7710FFF2960AFA9D231096
+:1015900020B4BEC627C0DECF277E5443727B9A8E0E
+:1015A000F24413E9EAD7828F2DCEE1FE3C9BFBAAE1
+:1015B00019F87B6BB1F24CA2CF6775DCCF1AD471EE
+:1015C000FB52CDA300C5C183765D41AEEA67EC64F2
+:1015D000F3505E3B74947F27EF4AA27380B243A11D
+:1015E0007CDF4E6BB57D35F6635728BE31479E399B
+:1015F000887AB3D1A19B8A7AF7E1DDF70C629E87E6
+:101600009CA330F41775DA15AE7764EB282F4A7176
+:10161000549B301E52643D5189F03CB8EBFBE4DF33
+:1016200090BF277235843F492F50D6C95AA8FF6012
+:10163000B622EECDF0D596A60B57BE07ED9F9A4F7A
+:10164000D18F72D87ECE8CFA8AC7BA82FC6969B90A
+:10165000DC2ED463DC0BCA4FAC3BE740BEF5D6AE04
+:10166000F5CE7CD49F430AE920C57FEEC8A2F3DD06
+:10167000BB0C74FE5C856B5E50D1C4CF725AB565ED
+:1016800063421C4D9F70FE2709C7A7FD5EC7C2714C
+:10169000EBD1BBB9BDC65C56B277D27225EEE7116D
+:1016A000656B2EBF7770AF3E98E505F81CDAB52262
+:1016B0000FD775FE9500E5DB8EA6EF7F94E311F85A
+:1016C0000B9A75748F69D88CF9B74FB5B134D4EFD4
+:1016D0004C2185F29FF7087E5668E5F4FFFB5C4ECF
+:1016E000E789CFC21EBEEF94E7924216C49BBDAFFE
+:1016F0002C087432E9F5B9CC03F2AFD0EE23FF61C8
+:1017000061AB210DE3F8737E62253A39674D223FC4
+:10171000A1D29AE4C5F71DBB2B8AE3CF3585DAEC5D
+:1017200069981FB3BBCD94867C2A340A7F1DEBD009
+:1017300051DEB047C7F3DABE25E6F5AD5C0BBF4717
+:101740003997F3992795E0029CE793804FCC573E59
+:10175000B891EBC36BDB4D348FB56F8D25BD6A340B
+:10176000B83DDDE64EC37BD8776FD465A1FFA8B244
+:10177000BB7003DE47B0D6C6EF6395532692BF9386
+:10178000FD42CF507FEF489EE15D1AC7DFE5949997
+:10179000C54857B21CCC42BF887F67D5F598B708BB
+:1017A000F8DB86E5BADC89D7635EE35E5B300BF37A
+:1017B0001C03B95378392DB80DF31CEB73CB783972
+:1017C000279885BFE7D4925BC1BF1F17DC86E5D69B
+:1017D000DC19BC1E7D4FC03B83B9575D1F84F13AB5
+:1017E0000CDE7A64C83F86F997C0FCFBC4F33E0167
+:1017F00017B5FE057C0F70DE2F9E89F52F89EFFA55
+:1018000047A97F55D40F8CD2FF6BE2BBF028DF1FB6
+:1018100012DF1D1EE5FB37C5774746A9FFB9A87F34
+:101820007B94FE7F29BE1B1CE5FB5F89EF7E3DCAD2
+:10183000F7BF11DFBD3F4AFD87A2FE5F13FA3F2AC3
+:10184000DA47C4FB02DBC60FC3407705C047902FC1
+:1018500015DB363A719FEFEE2A27FAEFA8E0F11D6B
+:1018600095DE0BF07794A0FECB5C7E3FE89782FF7D
+:101870006E17FD031D3E8C74B7F61D99F25D3A7428
+:10188000DE5321E4A31B74A40FAC7D8BDBE76BBBA1
+:101890009550FC3988ED09F35F2FE6D729E6DB9BED
+:1018A000CBF3A98D6E775A6DBC1FC9AE2D637A1428
+:1018B000F25DE0DF943F5BDC5DD5550CE5314E1DFC
+:1018C00069204AA3298CF72228362117ECE53DC56B
+:1018D000383FAB42E7C1158712DE8BDFBBCB49BF78
+:1018E00053E7D76955E85E2CD9C6E5C09C9FCCB4B8
+:1018F000A39ED5C902833EFCDEAD90FE7EB0ABCC8C
+:101900008E7CCF605B66C7FDBBD6C3F77F75537116
+:1019100012F26BF9411DF1EFC376BEDF77BA75E4C1
+:10192000B700B942E74A805F7B51468C67E1763A5F
+:10193000A7F0D04B8BB95F8FD94A2BE8DC861A0F02
+:10194000969438FDFF04C207CF4B0839A2A07C81D2
+:10195000E793E5E2BC4190FB9FF214E61E13776E1D
+:10196000F244AECCCF63280823E84BAEA5FB8172CE
+:10197000D7291AFF7BF65DDAB221416E280972651C
+:101980006C17F0C938B9931FB46BCAEFE50ABF9959
+:101990009779517F9DF3938DC40FCFA17C9346E738
+:1019A0007B51FE2BF8F193E2BE9B2783FCBCEEC17A
+:1019B0008D653F477CAFEDD6D1FDCE97CA47B7E7DF
+:1019C0003282C3B800C81DD467149685F6D237C1D9
+:1019D000619CDEEFA4FB0BBE011EE31E2D7722BF30
+:1019E0001D175048EE0C931BDF00AFE725EFFB01FE
+:1019F000C4A32389EBD576BEEECE7417BFF7479C00
+:101A0000039485BE76BFF0832B29733CF8531C9D4D
+:101A10008E162AAF97BC19D742FB07A4801DCB476F
+:101A20009C495CEEE424111DEE455D86EE2FCCF45E
+:101A3000A37FA42F6450EF030CE3FFEDC33C19F523
+:101A4000BE4137E967A2FCE0F5D5D85EB14F4295BB
+:101A5000B328AFE761FD95D0DEC0A2EDF15CD3B352
+:101A60008775A2BFCD0FA3BEBA2F8969EE5BDC8755
+:101A70007E742A6F7D18EF4F84F1AE95C1069BFEF0
+:101A8000C4130F5BAF88CD676AE8A987DB295F9530
+:101A9000DB250EC6EFC33EED8924E37601FBC4933C
+:101AA0008776F9AE13E99ADF3F13ED5344FBA68125
+:101AB000A1A6E73CD4BE88DAF70F2597D0FE1AAA74
+:101AC000886F9F2CECFDB8F6255FD7BE589DCF736D
+:101AD000BFBAB184B72FC3F6673C9174CA3D499829
+:101AE0004FEAF0FEA77F5DFF1345FBD3E15F51FB9B
+:101AF000332C923E399FBEBB3A0FE8F8ECDBBFAA0D
+:101B000010EB4E473D19B8A20FDF277B98B877AD91
+:101B100085F4E73E538F1DF535B3BEC78F7CB710F4
+:101B2000EF4F9A1E7BCECA2BE47A55C2FB3E134B75
+:101B3000AD457A6CD591FDD2671A2C2B417DFA65A3
+:101B40002B6B87317479EBBCC807FB236BBD25D0A9
+:101B50006E67F64CB22BF6195AFAE89CED622B9D93
+:101B600003DD69EFB1E3FE313B7AEC184790EFE615
+:101B7000FA93B2C41A780AE929BCB67879DCFE9DDA
+:101B8000EAE1BF23D3FD867523DA01DD7A6FCF78D2
+:101B9000D4B36D0AE5812B4B06E6D1B9BD1FEB1816
+:101BA000F177585715943B1B75742F7C9B67C9328E
+:101BB000842B53FCFE2AF82E374D91F01CC4FD8A6D
+:101BC000DF84F10BA3D0DB767AF9EFAEAAE36EC81F
+:101BD000E3F269431EBF1FAA7BF173C56FC2773B57
+:101BE0005BD7F6E178E6092686F95E3BB34F76E3EC
+:101BF000B9CDC7DD60F1021CAC0D3AFA5D94C76B3C
+:101C0000A14D0AFA330C1A7FC5F3521FB50F36EAFD
+:101C1000C84EB0961834FE8DD4069D0FFD8E3B3C09
+:101C2000817B71DE53DF51AEC5F1DCE3143BCAA703
+:101C300007DDBF36E9609EC9E5DA7EED33B5FD38D4
+:101C4000ABB5F5AE5A6D7DFA426DBDFB364382BF32
+:101C5000465BBE888208E1083CC00A72288957B1F9
+:101C600024EB79FA5DAEEEC0F69EF1B01EA32558C6
+:101C7000FA26CC37696212D9FB0FBC91849B0FF80E
+:101C80000F23BEF3C06446F9A78772BEEF46799A68
+:101C9000089F9DD9065AAFB510E0998FF6FA29FA38
+:101CA000FD2C2B8B6B978FF0F16DCF9BC6CBEE0A83
+:101CB000F4CF31E283CFABFEE31BF8B9A69DADDCD8
+:101CC0002FFD601DCFCFA31554E0FEE6ED93F1F795
+:101CD000BCA6A0DFBEEB0ECC3B4C846B06E6E3C893
+:101CE00031FA58AF9E23C1538C159C2DE3BE3BEEB9
+:101CF000E174F2933C2EFFF7897B0FA2ED711FA6D2
+:101D0000336ECA427FAFE6A9FE079E97BF598DC7C3
+:101D100088325E1788E57D879DD7E27EDABCD05990
+:101D200086FBE901A197A5641B7C1360BE8F1C3163
+:101D300004A5CBA0ACB0C37A90E7FB9C7C5CC35BF2
+:101D400049413CD7F488BB9CCE497D24E6F542A5A9
+:101D5000F7BD5ADA8F0AE5393DE2F29ACBB8BE8177
+:101D6000774A33FA4954502D0ED696919DFA88CF72
+:101D70006BC6FDFA48B6D78C79C2E64CC58EFBD847
+:101D8000E956E8BEAA474C013BEA2D4E1080F83BCD
+:101D90006D869C9EB9743E0860A8ABE0210126F2D6
+:101DA000E9309F2D55C06BA77B991DCF91BB0AF7DA
+:101DB000FF1DFAD553B1BF64FE1DC2C921E0743CBA
+:101DC000CFC3F38345FFA9CB5EA0F6F8D75911D74F
+:101DD0009F97D397612E0BD1EF8D89F1D57EA2FD10
+:101DE000331FF9EDD7FF9CC3AD3D87DFD36358C3E5
+:101DF000C80E7BA132B0F720C2273389ECEC2C77D8
+:101E00005615D247D6916D0BF03CC0FA9F73F96915
+:101E100058CEE34D590A335D85EB4E0BD8118E89B0
+:101E2000FB30F370CF7C2436152F89FB3253615D74
+:101E3000B273F8FECC74BBAA8AA68CB04F13F641DD
+:101E4000E691A1EF61FF89FB7587E56829C2E5FF8F
+:101E5000029F8BFAF4008000000000001F8B080036
+:101E600000000000000BD57D0B7C94C5D5F73C7BB2
+:101E7000CB26D9249B04424248D8CD8D402E6CC23B
+:101E8000C588A84B48102DE2227235E2131220407B
+:101E90000201F46B6CA9590C372DD6F0360A5AD4CE
+:101EA0008D058A8A362820566C978B8AD56A5AF512
+:101EB0002D554B13A18A728BA17D3FDAFAB6DFFC58
+:101EC000CFCC24FB2C89D27E6F7FBFEF4B7F7598E0
+:101ED000E79967E6CC3967CE9CDBCC3266632E3B54
+:101EE000A3BF7F98F1DFAFAFAFD53AEE1F369A317F
+:101EF0007F8AC5B3C3C5585AE87B37FEFBF708D4C1
+:101F0000356672FD2393B151AE78C606E279BDCB3A
+:101F100057C0D81E9B73A26300635D2B98E729FE10
+:101F20007DE94B9BE6BEC5EBFF95E67046F056A9F2
+:101F3000C79ADBF3F97376401F86F6DB2CFA93D150
+:101F4000FCFDB6E383985F632C229AD5B7393854E9
+:101F500026A6A3FC07FEAEC738561A6794CBC4D892
+:101F600018C678170153F2BF5EB60D1992E7F4F068
+:101F7000FE0229ED76DE6F9BC59967E1F59CA1CD48
+:101F80000F59AFC53C388CE368DA5E56C2D8B34708
+:101F9000F9B883517DE4A1320B7F1FD5F3DE8FF7B3
+:101FA0007B4C26597FF4A1B2218C0D39DAB6C6E1FB
+:101FB000E4F31FDAFA909DE32DF257E2FD045EF799
+:101FC00067012FB5433BF8FC0EA72FA1F937FD2E73
+:101FD0008245F0760566CF56D4D947916C07AFEFAE
+:101FE000DA377EB68BB76B8A19EBD2F3192B73698C
+:101FF00034FF525986CFCB6CF3E81EC7E5CFC74BF1
+:10200000BC31E639DECAE95BF0631B7B80BFCC05DF
+:10201000DCA0576B64E029D0B7790B63498C553B42
+:1020200005CDABF73F907E88972FC74CBBCDC5F150
+:10203000541D53960478522F31A62772BA35DA9977
+:10204000CE71953AE0058D71F8860C383A8139C029
+:1020500037ED6B9C28EBA398AEF807F4BF6461FAE8
+:1020600028F4E7A5FEF0674F02178ABFB5093A5B6F
+:10207000C3E1F1735CEF00773AA33AB542FE8FE417
+:10208000326F47AEEC27037CCA66B7F1F12A8107AD
+:10209000DE8F8DD3C45ACC4B872518D147FB8512D0
+:1020A0005F66BB23681EC94BE7EBC7A95F87E56C7A
+:1020B00087BDB79D3D60217CB05A16C8D6084FFE3B
+:1020C00008D4E312A8CEBC5ED78024F03F23E4A658
+:1020D0005AD8D1083E2E712F5F3F292C48E5E31CCA
+:1020E0003D8E4C344A8BFF349AE111031F3FC5D813
+:1020F000E450BE56E5C57413CD23ABC134F014C70C
+:102100004FDE914882C3B2910522F96059A007A71A
+:102110005BD62616B0B8D1CE36F05422BE73D17736
+:102120002EE634311AAF6D04D6D5D6D71D9B581C78
+:10213000D1F74E1F1F6F6B14AB01BED4788CAD214D
+:102140007C6C768971B7353A898EEAFD90DAC36185
+:10215000744C30D051B54BBD3498E8D9DB6F80FA60
+:102160004D6DD84BFC907A295DF289EB1BFACFE8D4
+:10217000A7FF64FABEFFFE87D0F88F07DF8F9FCAE4
+:1021800051F1A3AEBDF13E5E465A9B7D9E3EF09C52
+:102190007A57883CE3FF1F7980D7737BEB0A2F9136
+:1021A00056EF80691CFF91779B3CADBCBFAB8E1B8B
+:1021B000DB4D767F108FF5D8DB3E38603ADAD78971
+:1021C000F6D79C36B6F74DD817D65EC077FD256397
+:1021D000BB70FA84C3CBE11A382304AE89F608C376
+:1021E000F7B32B2F836BE0AC10B86E4836B6D7D759
+:1021F000F40DD7B77223BE162ED5EE96922B6B1721
+:102200003E8FE99323FAC1BB683F6BF695F57B7B64
+:10221000CDD7B7BBB3217C1CBFDCAFF8DAE2EB381B
+:1022200011FFE04B20B1C1E48D8C65CCC9BA18D642
+:10223000D1C9A12E6A97C09CB49EF9C2D7B0AEDEB8
+:10224000C33F53F856E0F69D738D01FEBD150FF3A5
+:10225000A66572BF6253788F57A3735FC1AD0597B0
+:10226000F31F63F7115CAF68BACE689FB57B76F059
+:10227000F59D97CAEC2909FC757220E3D618C6BEF5
+:10228000EA91D75CD470384748DC3D37B86D653C7F
+:10229000ADF34002E0F967C7B5BBBD66F798DEF65F
+:1022A000E1ED7ADB0B3CD96C6D2B0067579DC38346
+:1022B000FDE17DBCE2DFFD786644D0CCF175C1EA7A
+:1022C000D8A87139733C7ADEEB03391EDE8BD5E377
+:1022D000D1FFEC5937AE475D3B9CE85AC9E1BB5092
+:1022E000D9311678F546EB03DDBCDF5ABB3E3489A5
+:1022F0004FF15C9A3E2C0EF8F525125EF93F0A7CF0
+:102300007DC22FE029D304FE13E3F474F453666A0C
+:102310007FC2876796F6B1F88E3907127CE76C5C4E
+:10232000DEF5B1FE151E4A653F87AC9EAFBAF8FCDC
+:102330000E6D8EF3347178AB1367CD5BCE5F2D30AD
+:10234000F992826603DCF904B7A372680AE0B64A20
+:10235000B8ED0325DEBD595F077713C6C3BEF63D52
+:102360002DB0C32D6889FA4BFEF8C003BC1E61BABC
+:10237000F83EE4475781C9C3F708B68DEB1776BE20
+:10238000AFBC2BF1FD38577FEC09F47C239E274727
+:1023900089EF931F31059AF8F7BED297894E3F5EB9
+:1023A000E6F098F95895CC6503DF5631AF0DF0FF94
+:1023B00071C2DF5EEDE0F3BBC9AD97833E77269A2D
+:1023C000D2DF2738F4BC699CDFD87881FF6FE20741
+:1023D000C63699D858C66E95FAC10289C7E9CC6B42
+:1023E000C53833986EC5B8BF396FF332CE1FBFE121
+:1023F000B8621CDE59CC4FCFE7B00095B7B320B51B
+:10240000BF837550FDD7D185690D1CBE695B86659C
+:10241000633D86E0FD76C92F770E10FCF2D920E0EF
+:10242000BD65E015F1EF344DE06FB05BAF76D37A68
+:10243000750DF00026E7C421BE9890F5533650F094
+:102440009FC599FD75EBA7BD3BB6908D2479E048FB
+:10245000E178B84192F206EFD229982F2408D6EB02
+:102460002D72BD969B1D6C00A74BBBCB1C88E0B0AA
+:102470004C9EB02219F37D630DFBD5284EBF372645
+:10248000985913B5F4D27753657F53874CFA1CFAE9
+:10249000C9DB2C386034FFAEFC927E348EE367AA31
+:1024A00079F75AAE71B3C943AC9F7484C8B51B07A2
+:1024B000ECB130AEBFDC94657C3E259FD743E4EEA3
+:1024C0005466E97DCFE97F08F881DC61CD66F0EFE5
+:1024D0004677CC804FF37875041B21EC034E8D902A
+:1024E000F974DBFF6EBBC0BF7BC5AD3F04BAAC8CDB
+:1024F0003F3F8FF40E8B98CFB277CCA4577ED2C8D3
+:10250000C079EC14D70FBD398C7DCAF50BD44F3789
+:102510002653F905D707509E6DCCA5F7E71B3D5410
+:10252000FFC4EDDB8A7EE76FFCD2827D6943A4C2E3
+:10253000B7806395E4BB0D6963B7FC95E375C3DBB6
+:102540007C6170786ADA9A2771358BAD4AFBE43E7C
+:10255000E8CFAB9ED63C68B7F4A0D7E6E0F02C38C5
+:10256000AAAF079917BDDD311562A20EFA2BD71B52
+:10257000EEB7FA7662BC311F9C4AD27903EFC1CE26
+:10258000D71379FBCF1A4B08AECF1BBD04D799C622
+:10259000C954FECDEDDB8DF65EF6A50DED6FDEDDEB
+:1025A0006949E5EDCBBD9A17EBF13A2F0B04383CA6
+:1025B0005BAD42BE6FE5F21DEB7342C1AD8FDF052F
+:1025C00071E1D6F7830F6724549527F2E7534B2A1E
+:1025D0002D6837EB2B2ED3DCBD7CF8CDEB50E0A380
+:1025E0004ED2E5DCCF35C2D3B9FD79B75CC3FBFB76
+:1025F000F931333373B8BA2F9908AEEEE35101289D
+:10260000ADAADDCA7D66D22757A6D902C0DFCA7D32
+:102610007983A04F9DE1746339BDE39D79EEDB2E94
+:102620003D448E9E4968FBAF0F21A77E2FE414D74F
+:10263000373F7D0C726CC8600FE87EDECAF57220F1
+:102640009AD547631F5B6693EB8BCB19D4CF44318C
+:10265000D247C73E9F5A8AF582F15CB65E3994F341
+:10266000FC968CEFBA7AC7DBD5B6E0C3C778FD5CC1
+:10267000C0E4B7F27DE61C6B3BFF33C8D1ED0E0F13
+:10268000EC830D1A8707FBE88EC154CFD52C510D72
+:10269000C4CF015AAFB99ACBD2C0E54FED0B8F0E24
+:1026A000063FBDC27150C2DFBFB2399AE4D32B5688
+:1026B000CF8906F4F7B8E8EF273FB8E79303281F60
+:1026C000AC2BBE879717DD09D44FF57F2C1E81EF09
+:1026D000F93ECD52787FCFBEA40523F9FA2C683994
+:1026E000745F0A876FE4B64ED3605E166DD79A505A
+:1026F000E6A5DD74CCCCDFFFC5ED1276EB6EB73905
+:1027000015CB6A70E0C3EB69FF36EEEBF92D5F96EF
+:10271000C2BC54FBFB08ADED8B56D8C3E9C78B7523
+:10272000C25F33C1B1EFE0F4F76E679807D71C00C2
+:1027300077A5CD43FB49C0DF0A3A9FD3733D0F60B5
+:102740004DFBFC8F82BEE7F4240FF697FD267FEC4D
+:1027500038B43F61A179BEB4FDD7B1565E8FDB6B53
+:102760006591FC7D5D51D724B4AF4B73911D9EF6EE
+:10277000C40D93819F657BF7B5523FB5768F867503
+:10278000B6EFE2EBA9B0876E649E6CF0DD5E51FFA0
+:102790007E99D7037EAB69FDB3A8B7FBA8EE33FBE8
+:1027A000DD16B4AF127ACE16B98FB18E429277C4CD
+:1027B000CAAE5E7A7D9FBFC6FBAD6E7F4ABDA37772
+:1027C000FFE3FBD6900CFE3EC526BF774E4FF7FDCC
+:1027D00013FB964DEE43AABF2D36E68FE4FDA4F120
+:1027E000E71AF6559BD86F7770F9027E51FB2D1FC3
+:1027F000371FE3F2EFBD9093A97C732DE2F349DD1F
+:102800001211A03DFD0AC7577AD2F22821CF94FEBB
+:10281000313BB1E9D50E8ED73FC5EA2519BCDD02A3
+:10282000B95F338B2719F33B19EBBD3A83F6BFAE83
+:1028300074CC81EF87D7A2BECCCCF5A7CC10FDC954
+:102840007E65FB61449C7722BEBFD2F6E3A3FA9675
+:10285000BFE3BB4B48FEBE2AE5EFAA3F9B5811AF32
+:10286000AF7A3882E409ED697DE0E555BEDE752E6C
+:102870005F7E01BF012FAFFD538799EC8FA3A6DACE
+:10288000D7F97E4A4367E03F5D4D71A3A9EE0599F4
+:10289000AFFB93A94FFB50959C4E95A093F72BA3AC
+:1028A000BFE1FAAF9C36EADF917045F335F7335F4D
+:1028B00073AC98EF41CC97D36ED597C5242F0F5E9C
+:1028C000E13CD322BC2B015FF83C38DC0DA047383B
+:1028D000DC3DFCDD756570DFAD31BF09EBEC4B5BBA
+:1028E00000EBEC200713EBF6E0E2FC00D6F37E9B56
+:1028F000A8FB636DA47F1E8C617EC88F83D3920278
+:102900007EECE7680FF9309089F791F2FB3949F4D2
+:10291000FDE008CEFFBCCE6E8F92FDD7BF5580F78D
+:102920006B523D1C02AEDF063666907E6B26BFE121
+:102930007129AF5BE283B79BF9F3962F7318C63901
+:10294000CE82A9CBD1AE268AE4504BBC372581E399
+:1029500071FFDFCDB42FB414F1BA83E434F9775AA0
+:10296000A67953E2797DAEA44B4B6B60C723E86F29
+:102970005AAEC7CFC7196C66F5D4CE2DFAF9D02A56
+:10298000BEFB9DA40B5FC7B4CE8F66CCDF03FCEB10
+:1029900053A32DF08B708CA7681CFEC7AAB319C96E
+:1029A0004BE9F79A2D6930B7970FBCF6B1D06BC5DC
+:1029B000DF9C053B22218F67D444925FEA78CD7D6E
+:1029C000312E3EDE0CDD1C8C80FE775BB9C1EF74CE
+:1029D00034C34BE372C342DA09C12AE0F1E75D7602
+:1029E00006B9DC1F3DEBDA26249E0AE1871A9B908C
+:1029F0001FA7A53EF4728CFE0BF0CDF20337269E86
+:102A00000AD1F7AA1794E7407F56E37D13DF34819C
+:102A10004E2369BDFA4DE08FB648A2FFE45BED445A
+:102A2000EF6E87E929F825EF94F2AA0986307FDE58
+:102A3000B42F22701F7FB63C223813F28AD3FFE9ED
+:102A40009DA0EBAB9144FF5A9BE0A7DA9FE5117F75
+:102A5000EDB779DDEBD0FFCF2388EEB5B1AE387A94
+:102A6000FFCB4426F98FF486DAA8604E3CC7E7C650
+:102A700068FD43E08DF31DF9836B6DE2F909C957D9
+:102A800027781F80C35F1F43FCC8645DFF6E22D997
+:102A9000535C1F25FED51FCAA3BA6EF3A62CC0FA3D
+:102AA00058194DF09D90FEB413B5F1C4DF150F2DEC
+:102AB0007D9B717A9EF0EDBC3F87B73B71D0EAC138
+:102AC000BEF471833968E3743DBFFAE4D8ADBCDE6F
+:102AD00071DF47E97A881FADE2BEBA29F8AE62C954
+:102AE000EAA9D82FFBC377456D0497B9BD74B266C8
+:102AF0007AFF04FAB933F5FF8D792ECFEF5808B974
+:102B000077DED6FE04EC830FE3F4BFE2FD85973F4A
+:102B1000DB49F2D0D29503FD7C9985F301F852EEA2
+:102B20009FCB255F063275963986F047FA78747E1A
+:102B3000BB907BABAF4CCE7F7170C77E8D8FB334B3
+:102B4000EAE0322ACD8142F473460BC66A99C01F6F
+:102B5000D7E3787F679DC158D0419776D3D25DC6C1
+:102B600079E10F7E95A5F807FF6E699B99FC2A1CF9
+:102B7000421BE05F0A4FAF219E20E40AEFE7295A8B
+:102B8000878E8FE77D97E37FC9D3C38BA14F2E8DAF
+:102B90003FF0836BA81DFF4EF1B9F9F2BA9ACFE569
+:102BA000F088F99D957C7E96493938DBD66387435A
+:102BB0000F3AFFDC2003DF9C7F7A38D5BFD0BAB450
+:102BC000280ED779298F98A76DEC341810DEB6B18E
+:102BD000D0671F91CF9726B68D85FC51F288D9DB3F
+:102BE0000AC9AECE6D2B843DA9E419F3B5E5D0F347
+:102BF000405B0EBEDF6F127E0AFAC3BC9F4D6D258F
+:102C00003CD8C57A5CF26C1EE1458D134EBFF0F9DD
+:102C10005E9F29FCDC1CDE3B7DBCFDB0AD36C3FBFA
+:102C2000E10163FD06D97E68185D069BBB0E454039
+:102C3000DEFF98D17A0D1F77AAFCEE99677AE860DB
+:102C400096F6227329FABB84BE6D05BE7FD783EF4B
+:102C5000BB52B93C5D8A3966F4CE7F7F919E0AB93A
+:102C60007FDE24FCD4FBE3793D1F7A8EC0A7AA2B1C
+:102C70003C86F3D17DBF5B988A78CA3D9926A954DA
+:102C80007A0681DF9A202FB9BC68B20A7C7CD158C1
+:102C900033EA9405F6687D4AB5A5773E0BB716D999
+:102CA000B15E166D2BB2CF0FB1779A768D3AE6E210
+:102CB0007439BBCB426E83264BE007D0A39B769939
+:102CC000DBFC8CDEDBBDBCFD59C7E177D06EE1B625
+:102CD000F862E8BDEAFB455BEF4EA90EC177DE2E38
+:102CE00023FE0BDA8C75F8A343EB4DD005C7FCF33C
+:102CF000DF15058DF551C78CF5CFDEBF6B26D8F8F3
+:102D0000A512C1EFA7033101C4A96A3E9A740CFB56
+:102D1000DAE9FD2FC5823E4B7F5FFD3AEC96455BBD
+:102D20008D7CC6E9A641AFF7EFD4883F1607C2D71E
+:102D30009D5CEF97ADC735CAAF991BCA27E1F43C3C
+:102D4000C3DA667A393FD536AC1C857848CD14CEC7
+:102D5000B81C9EABDB36DB1037081FAFBF75CF1C2E
+:102D60005E17FC559525E2DDB8865276124EDF4D92
+:102D7000BF9E84F556F97D8DF6FFCA17871D85FC29
+:102D8000EEDC33E7262A674E263C28FFD9A2835A79
+:102D90003086D79D25AE031DFCBB05018DF687F956
+:102DA0006B237AE510FF7FF5A630385A42DE73F8C0
+:102DB000171D38F4178DF75FB3CDF8DD628E2FC87D
+:102DC000FD25DBFF1111FA5CD97DE30EB69A31EFD8
+:102DD000050A7EFF750CF31221482E3AA4BE720A32
+:102DE000152EEFA3137C8732F9FCC7B588EFB8C066
+:102DF000AAC47CEB1C3617E65B6767C1680EC7B1D7
+:102E0000189BD7C99F5FDC1A43FEA985115C2F2C44
+:102E1000A6924516E33B0FEDD39FBE6B267DA50E14
+:102E200063A39F2735B27FEAE06C44FDC7A2BE983A
+:102E300005691EE0176FE8FC02C63A6B167653ADC3
+:102E4000257808F858C23A84DDC3E9E80D89C7D56A
+:102E5000F2791E4F803E64FC7E396BA3F6CB0FFCEB
+:102E60002322F479889F94EC3965579A6DCC0BFD39
+:102E7000D87C6F14EDF75C1047813FD769DE47EDD2
+:102E80006694625EFECD42FF99DB2AF60BAE9FE6AA
+:102E9000003F2D9B877BA0A7CCE57A7624F488C5DC
+:102EA00051D4AE259E917FA5654E8ED0B3FFFE62B4
+:102EB00010E3743DAC917FA4A548F4DBF2E0707A96
+:102EC0000F79A8D13811A4B7B44C53EFD3484FFAB7
+:102ED00010A0A540CF95CF07BAE8F960B33707FA3D
+:102EE0003AFB6124D9FB4AAFFD4982FE0FECFB6A35
+:102EF000BE4A0F663557A6FFED90FB5DD76611FF02
+:102F00003DA5F95E3785E8A5CE2C21E7C7967A77EF
+:102F1000CA761407A8364D7BE07A0E4FF523265764
+:102F200093BB17EFCCEBCDC1FC4F6D8E2C069F8D64
+:102F30002D15FE9E1345426E478F66DE002F5364AB
+:102F4000BF29592643991CC5F98FF773AA5CF887E6
+:102F50006346FBC8CFC6753692DFE1F3C896FD54D1
+:102F6000DB7CBFBCB60F787AF8A04CE819A756688E
+:102F70004F09B8385D797DEC7F44927FEE94DC5741
+:102F800014FE39DF8CA17D5AC549259F6C06FDB121
+:102F90009F2D1676502F9F18F960AE26F0CA1E148A
+:102FA000FA694BBCA82B3EE0F60EFB2BF8A49C1153
+:102FB000DEFBB37BD43C5B5AC57B4EEF6BB3C65C88
+:102FC0006EF7287A334B600CECC6FEE83DBF247EDA
+:102FD000AC66A2B8B51F716BEC758497FB2D81FBB5
+:102FE000381C432C02FF6916C15F5C2AFBA38AA927
+:102FF000BDD7C6EB953F5CC4BCBC7D652A237F1062
+:103000006FCFE2D09E7763867F8497F8AE324EF41E
+:103010005B3988919D407F5C5E65A1CCA07EBDA69A
+:1030200004F17D6C317DEF3789EFBD165E0ECD1456
+:10303000FA7CD7BA88C05390CF1BD272C007534ACC
+:103040008D7CD026F94695A9D92E95E7908CF53D33
+:103050007FED70DA2F9A227D75FB40B7E784FE5F23
+:10306000B9FE8E9BC700BEE7133D00EF8BA97B28FE
+:10307000DE307FED9CBB3F80DDB02B929E9764EBF2
+:103080004BB3A01F6BAE79FBF883F9338ED892F95E
+:10309000F77ADBB4733FE3E554FF9E77A00F4CBD96
+:1030A000CD4CEDA732E11F656BC53837FBBFB424AB
+:1030B000F3FE6E1EAF51CE4067A4337D05F2162499
+:1030C000FDBE0DFE851D16C966BFE0005C6939199D
+:1030D000FCF9CDD030FB885FED93FCDE3441DB069C
+:1030E000BD66E844B1BE547BF4837E5FC9127AD0DA
+:1030F0007DB254758E576A5FBD31A2333316A53544
+:10310000380CFB5D4EE97AF0D5940C36692BF07ED5
+:103110008F19B90A1CDEAE4A5AF731392EF0A9CE02
+:103120005890F22302C389AF3B2774756EE0F5CE49
+:10313000D6611EF2F9483B7A01EC2B17DE0B39A65B
+:10314000E4CB0967470CF1ABB4ABAB246BFCB161CA
+:10315000E22357F1F6550E5B27F683050F4F8F4597
+:103160009E49558B59E4736C32DAD5DCFE0D00DED6
+:10317000703B39DC1E06CF808FAA3769C487439B1A
+:103180003CB61492639A13F3AB7604B320DFAB3DE5
+:10319000911EBC3FDBE84D3C958578C4642AD95725
+:1031A0001CEF63E18F6594C4F162B6FE1CF8A1B216
+:1031B000B992ECC5E87C9DE4D3D92CC17753E04F9C
+:1031C00084BCB174A4601DCE53CF139C390EE2E7CA
+:1031D00048063C745A9D3980AB735DA409FBE694A4
+:1031E000FB045FF37566B7F0EFEFB7B028ACF7EF0D
+:1031F000E27B3E5EC51A8BAF95D787D8992526010D
+:103200007C55447C9D394CBF0FF09CFE1E2BC1FEAB
+:103210005FB56933C1A3F88259DACB12A1DFED7033
+:10322000173FC07AF9287358E951E0AF871F6ED372
+:10323000880F78792893F8E1D637891F4A83592B6C
+:10324000F311C7AA655EC411929907FE806ED64538
+:10325000FA4437D72720CF943C517283F3811779F2
+:103260003D8ABE4A7EEC6CE42071BCEE6AB453F930
+:103270004CA39359B80CD8DD984CF5E71B5D54B6B8
+:1032800035E6D2F3171A3D54DFDB5842F5FD8D5E6B
+:10329000AA1F689C4CE5CF1A7DF49CE385E49092CC
+:1032A0002B4A1E297E5272299C8FE671F45E574C80
+:1032B000DF93DC53F20EF33015F7CA2345DF0CCD54
+:1032C000E74F76438E75CC81BC28379F7DEE25F87D
+:1032D000496A1C9E0817F022E45EB7C34E723EDDB9
+:1032E000C60EC05E6F5AE1EDDC10B2AFDE5EA331F8
+:1032F0004B089FDE511FC92C217C7C6743BCA15E1B
+:10330000D1F0DE6B8378FF5ABCFEDFA0CB897B3F18
+:103310007DFCB7FCF993F77E910D7A7338766CC11A
+:10332000B8ABA37AE048407DAD95F487A151C20EB9
+:10333000C21FE8329F89F5F9E4BD7FA5F5DDD910FC
+:10334000E132F376F31B22085F1F824E1CAF1F4B46
+:103350003A55AE3BF9DC4B58E7AB6D24E7E6AF9549
+:10336000EB7223C76788BEF6490A23BD4CF3328649
+:1033700038CC27DFB305F99ECF3ED1EC010DBA0F53
+:1033800037922AF8737DE31B947FA5351C237D5863
+:10339000475E16FC047EAB211F4B6B90795A1D4390
+:1033A0000C7954D1A3BD36C807F034E8363FF73066
+:1033B000C3BA66CD9A135B40B57C5EBD51237DA335
+:1033C000475FC836131D2BB32C54FE026B9CECC513
+:1033D00066DA9F14BF7279E10D605D3417D91686E5
+:1033E000C8E1F9F27955AE894AF5BC32CB46FDFC0D
+:1033F000028B91F7FB406E866D01C939970D7240C3
+:10340000B59F9F5BBC3E6334FA99308085ACC7A200
+:103410006C0B7D5F89442FEC5F76E1FFAFED671F9A
+:10342000507AC969FCF36A829FECAD25CF3FFB3C23
+:10343000E2634B3E8A203A2D1929FD11F981B1D35F
+:10344000499FF13A343ECF6592FE65CFFE3EB6838A
+:10345000BF5FBE57F82F79D98972D9EA1AF26B2D5E
+:10346000F3F0F59100B96A8C231F7DFEA3D80EB24C
+:103470002BFCA9C82FE4DB422A4B46BCE8E424F825
+:10348000C597B3AEF5C8EB0AFF6EB9F655ACF0EFD1
+:103490008B38B98A5F96BFFAE7248263DFC524C8F8
+:1034A000B5E5AFAE4BD2FB98F7F2B0F8B58A9B2BDF
+:1034B0003FD872B6E94BC4DDC2DB5565C70C00FFCF
+:1034C000B0ABD855E4A7B030CA6358691778E80E96
+:1034D00064C7B13EC6EB19772B17ECDC0EEDB6B81E
+:1034E000E23C1CCE0BFDE4F1EDCA16FBF93919479D
+:1034F000BDB0DB4C7AE185DD31C4FFCB76FFF0F562
+:103500006B787DD9760DC3B23AD64E785AB6D7CC01
+:10351000ECA1F60DFC3689FDC3B9F4D9987AF0D345
+:10352000E236CDBB231F717957DCC01078D6497EB7
+:103530005A1AD13696E820E1FFAED48F54BBC507A6
+:103540007F6803BD78BBF3A4B7FC341ABA36FFEB2F
+:103550007A07709ED9368AE2BA8BDBF62CA37D7F80
+:1035600077B41353FCC26AF4476D96E36DCE167AB6
+:10357000C619E9FF3DF3BC99E40FE0C43AFC4213DD
+:103580007E5EF5DD16F9DD1689B7EB10541CD3DB32
+:103590007E715B676C166FFFD981F7A86C95ED178C
+:1035A0003BDA0BB15F7EB6377A7280CA1F4D7A85DF
+:1035B0008F77AE6DC2002D645D3D9F6DA5FECE6D13
+:1035C000334F06BE5840E519B5D17CCEEC4ED5C878
+:1035D000AE05BE397ECEEC7D31D644EBD66FA0A3CE
+:1035E000C92EFCA96E8B4BEA977627F48CB95CAB9D
+:1035F0008BE3F2AE6EAFC807087FAEDAD37A4B0129
+:10360000BF77D904FFCBF8BD8C2F214F84E2F13175
+:10361000B600F6D779235DB36E873C7BCB2AE831C1
+:10362000C4B50576D5BC7713C95FB1D2EA1A84FA5E
+:103630009FDEB692FF7CDE28B9CE933BC6C03FD951
+:10364000E916FB7AED46BE42F8940773FAFBF9FCE3
+:103650006A0326CAA77C3F3B83E6F7588DC96BA354
+:10366000384730077ECA1336E637434F7E2192F43F
+:10367000BBDA0CE1777F0CFCCECBDA84604E22F40F
+:103680001D49C7DA5BF9FB107AD63E15CC81DE7294
+:10369000D626FC7878EF44592CDA3549BE413FE80C
+:1036A000B7D3ED3C4FFAE5BE18063DDFF4528CF07F
+:1036B00027FC2492E20EAADF53D942BF6F92712EEB
+:1036C000FF0E011FE082DEBCD8D69C03BD528DBB2D
+:1036D00038B699C63B2BC75B1CD52CE207322F0CA2
+:1036E000ED697C2BF3C21EEF7A3A82F4D32F52DAC3
+:1036F000F763FC2F9E1E4E71F04E7760E1017ACF8A
+:10370000F5364E8725CF440401EFE74FC7509CF3B1
+:1037100073ABD0833E8F49223DE858CC23F3D05F72
+:10372000F7F6080DFE94CF35664BC6FB1D03295EE8
+:10373000B5A4B181E2044BF872473C9A97931157B4
+:10374000FE7CC770F2B37CFEA699E28BFCF9463C86
+:10375000D759F3BCEF60DDED8A263FDB17CFFC6D58
+:103760007868FC41954BB61BFD498AFEEABD35479A
+:10377000D80DD61C81C7C81CB1CFD445B73D9241E6
+:10378000F314EB95D381EC2DBE3E92E09F3ED1F633
+:103790007292E6009E83393F02DE7709BBE68BDD3D
+:1037A000568A8B2C7929C64BFE9B0D5799B05F2CFE
+:1037B000310BFD77096737510AFFD092D81CF20F01
+:1037C000717C93FDD8B5C32CC711E37EBE334DF891
+:1037D000DF83B2BEBF20003E9F92C0EEBC95F49B3B
+:1037E0006D85C0EBC5EDD126F0051FC78BB8FD92E6
+:1037F000EF7C57E0336E21E9E30C79D063112F178A
+:10380000F2B26EC33571C88761EF9A1944DF458BF8
+:103810006710E46138BE66E74879B9FF711BE2675B
+:10382000B57CBD203F68A98C9B2E7D46237D6EE92B
+:10383000FA6BB6901C7CC7CAB2391C67DB7E181BBA
+:103840004A8FD21CA157F47EEFA1F64B797BF1FD94
+:103850005BB104CF4EAB07F084D3F18ABF7FC67C47
+:1038600045DFF7F0471BDFD70B2F9FF745D6FEBF8D
+:103870003E821CD91DE9F1D3D3368A3B9FB1B62DC8
+:10388000C4BCCF3C1749F2E54CBC58EF9F7179E8B6
+:10389000B7018E6F3D44FE8DDF4C6710DD8B02C695
+:1038A0007ED5B837E488731B75899E38C433EA38EF
+:1038B0001DD01FA7CB2DF4FDBB56FA3E7C1E393917
+:1038C000426EF7ACCFE7A2895FCE0C16F438F3FC5A
+:1038D00030DA573AE3059F7378D361A79C8917259F
+:1038E0008332C2F96089B443CF4C6823BBFB8CB6EA
+:1038F00087CA4EABF86E49838CDB72BE4B06DF8005
+:103900002711B7B26F6A871E01FFF4D8622A8311AC
+:103910000997FB99C19FD8879E94EB0B6A0DE43AF7
+:10392000C537483F69B3411EEB528FABDD7D79BC93
+:103930008CE2A0BB358AFBDCABFAE1500F50FE7184
+:10394000CE8F4BFD9A17F9464BD7AE580C7E5F5A77
+:10395000BFF976F0BB9AC7520B9B0CFBAA533313EB
+:103960003C9D917CDD000FA1E365F4E2F7FE1CAD08
+:10397000270FDA99447A2629D70FE688FD0AF566DB
+:10398000DE5FED5A6D138DE356F6A4989FC2134780
+:103990008B0D7E326EE78BF7FDCC5FC1193E7F0544
+:1039A0004F6B8ED01B3ADDAE87C683DEBF3293FFEE
+:1039B000F4E257A3E212BE462F83C5D6E32FE6F00A
+:1039C0003FCFF76AC0BF42CAB7A5F047733873B696
+:1039D00019E31FB9DB8DF511BB8DF5FCBDC67AE18E
+:1039E0004163DD73D4587F04E30EECC513EC5CE453
+:1039F000B5C1CE45093BD79523EC5CD461E7A284E1
+:103A00009D8BE7B07351879D8B3AEC5CD461E7A244
+:103A1000849D8BE77F9078AA957E47D081F2AB5E3C
+:103A20008E5471705A2F17E62491FC54F1CC0B8BF5
+:103A3000F3A9DEE3CF9966277F8ECAD3B93D4E7FC7
+:103A40003387E286EDEB5340374B07F97197FF4C14
+:103A5000F8716B8B231DF02F74ACFB6C3DD4A7C2A7
+:103A600038FD1DB4BF60EDDA29F2958224373AD6CD
+:103A7000B8DEBD5ED08FFC1C2AEFA612FB5D42FFB4
+:103A8000740C8FA3B04DC6B849781C253C7E12CE6D
+:103A9000072A6EF2A4B52B05F2FEE4D3F64D80FFA3
+:103AA000A4F48FB1D94ED2BF945EDDA37F3DA83D73
+:103AB000857DFB428EC8FBEB3EC6F5ED3EF65B55C1
+:103AC000565D2A26BDB1A7BE493351DE48722CEDA2
+:103AD00043AB244CE95A57E706C8BB1813EDE3176C
+:103AE0001D26B20B2EBE6F263D6218F4F390F90C22
+:103AF0000F4419F82B6F574258FC6FB0A1FDC80353
+:103B00001961F1BF11C6B8D46D6B0EC1BE9EBE69FE
+:103B100094A15DB5EF9A303C4AB8A55EDAB47A6BF1
+:103B20003AE4CFAA986E827FD5BE48CAABADE6F024
+:103B30007A11974385A3A0C6EE9D0AFCD5B459E33C
+:103B4000B1CF57C9FD873518F7E31A0BF33B137A4A
+:103B5000F9AEC6C9BCF1FCFB7345CD3B4D9C6EE78D
+:103B60004CDB1E19EF425CA935DDC9F9EA2EAD2DFB
+:103B7000E96ADEDFDF2C7ADA304E8F746BF00715DE
+:103B800090977B32D91ADEEEE4A6176349EF967C54
+:103B9000966E754681DEADCD66B20BE0973227F4A6
+:103BA000F2436B73625496A3779EBDF4FF8AE6C717
+:103BB000E9E2C139C56EC7E121ABA0C7B589F9D625
+:103BC0004CD0FCA427CBF9AC94FB0ACB12FDDC252E
+:103BD000EBA7A4BDA0E67776F8A14217E2988D077F
+:103BE000D2CD90E3A6DD3B717EE0DE28BD64D840F7
+:103BF000E44B66FF763C1F77C907225FF78F2D13D2
+:103C000063AF86FEF99CD53385D73734FFD806BB22
+:103C10007889256083DD59F374ABCDCBCB1B76B5AA
+:103C2000D2F385BB2AC9DE5EC4EAC98E3CADF26F11
+:103C3000253E6A4AB56D4E0EF793C384DCA88912FF
+:103C4000791BE5E6F1AF212FFDE22EAD08F3BDCDE6
+:103C5000B7C756C99FDF3A4C9E3B095B1FDD6F4FCC
+:103C60002F1F087F529B887BF6B71E660473693D41
+:103C70004CBFE4A2F2B64B23C88EFD80F90A484E31
+:103C8000E487D9B36F8B3CE4EE83621DD4D8820302
+:103C9000A6639DFCDC4AEBA48ECBAF9262D8C98CA4
+:103CA0008DE3A56FBCD9C0AFCBCBA20DFC3C9B254F
+:103CB00018E2C833716833A47EDB944C43FB59B7D8
+:103CC000E585F17F71EF7B9223E30C792675ABFDDF
+:103CD0002E8DF2594A8DCF79B99AF8EC26C3F77533
+:103CE000ECD6DE76B083B7FF9AF0CC58BB0DF65613
+:103CF0008D49E4D5CCD63BE5F30E7ACE27625887C2
+:103D000043333DBF15FBA295FCF2CA2F3D1BFFCEEE
+:103D1000EC6B5FE48496E3223F14FE05437E2107AB
+:103D200080EC4F26E85027FD3D75B9C2DF53E76FA1
+:103D3000B721FF96E3DF92CA51B2AC59237F1E6FC1
+:103D40006F4F4D10F5D578BED778DE00FD5DC2FB14
+:103D500063E64AAC97F0F7CBF8BCA1672C839F06CB
+:103D60007E26D5BFEC57F1E7A2AD46BFD132F8733E
+:103D700042E8F8C93017F1F3925D7B5E1FCCF13257
+:103D8000DD175F84F553DB36CD5A997F399F29F9CA
+:103D90007EB1C64471EEEEB78F109F75D758889FDD
+:103DA000BF091FCBBCC29F19CE7F0BF97C10975D5A
+:103DB000B857F30434D10E78190CBE0CC34B6A1FEC
+:103DC000F85278EAC15BD8FB45F8C768E40D688112
+:103DD000A0BB2FBC483CAAFEC3F0C44A8C7858A8AC
+:103DE000BBDE85BC5978CCCC025730EF45981FC656
+:103DF000E7F3C3F8B75E127E1215379879C942F51A
+:103E00001E3EF189FCE9DBA618D7650FDFF8C43A3E
+:103E100099712989BEFB9FE69F6FE21B0577787E2B
+:103E2000B23ADF737A983CFF32868DA1F57F8579AF
+:103E3000C36ABF57781E7A6F09E513753B32487F16
+:103E4000E8D96F9CC6F72B6332288F5897FE392527
+:103E50007775D94E8D53C9DFBB46818F8724C1EF5B
+:103E6000BA7E6D667A47885EA2AFB392DF347D4D2D
+:103E700022959591CE24EC17956BCC3EEC839FDC7C
+:103E80003F28A9047EF875D6015378D79FDC333AD2
+:103E90009D15A05E4EE5C9CD11B343FDD9AA8CCFC7
+:103EA00015FB46DDBDC769FF3A677A3B7636D6D942
+:103EB000BA7DB148A959BAEEBDB14EAE7AB45A74C2
+:103EC000672EC5495B773A8137676B21FCD174F661
+:103ED0007260AF9EB0645DF920F8BF6AFF7EE409AE
+:103EE000ECEFFA1A6B12F4CCCFDFE7FB9F46FB171F
+:103EF000E907A7917F3C0071AB683ADF765A635EB1
+:103F0000C46F169B0F153A0DFBE9C19980E3E528B4
+:103F1000DD953B06E3077626637C8F9FF225F5351A
+:103F2000D9717DF94B54B97CABD0DF762A7FADF4E3
+:103F3000EB426F471D7A3B8242D0DB5187DE8E1207
+:103F40007A3B9E97C25F8FB86A535711EC4E7F2918
+:103F5000CBADA7FDD5910BBD7C9516E581BC59A5D0
+:103F60007906C10FC6B6A7887D358CBEAABCB68BB4
+:103F7000EB5621FC7EFD253B0BCD1F9BC0E20DF5D2
+:103F800089F61443FB72A7DBF0FE86E4E186F7377F
+:103F9000BA8A0CF56FE55E6D687FB36782A17E4BD0
+:103FA000C98D86F6D3BCD30CF5E993E718DACFF0C8
+:103FB000551ADECF9ABDD8F07E8EBEC250BFBDE688
+:103FC0001E43FB3BEAD718DE7B99D382FDED20EC44
+:103FD000298EF79FC39EE2E5AA5F653B42E93A7EE0
+:103FE000A2A9BE2F7FFCA25CA1CFDC3FDC3B1FFC63
+:103FF0009126CF81A4C9F31C77E7BA44DE00CEED49
+:10400000933DDB9E02BE096F17FE7E7CF4E18B2E92
+:104010004EC3F6DC5B6EB370F930FEAAC3A33279EF
+:10402000DDFC74D36D162E57C65F73F8C50C5E8F1A
+:104030007EFA55511F79F822DEAF7E7A83A84F674A
+:10404000A45A243E3DEE363F9FC7F8EB33367984C1
+:104050003FA4CF7C4B55020FC85B041E5006397F2E
+:10406000A23CCCF913E551CE9FD5598CBDCEF913A6
+:10407000E5316E57E2F92FB95D89F26D6E57A27C7A
+:1040800087DB9528DBB95D89F2378DB3A97CBF51F9
+:10409000A7EFFEB3B186CAE38DF5F4FCC3C6062ACA
+:1040A0003F6EF4D3F3CDB9CA4F11243F8B8A272D2D
+:1040B000431C0F7EB803D6B3A17156150F54F1BF40
+:1040C000A67AD6118D75DA6189FFD4DE1BD7EB5F36
+:1040D000CE5AD8A721FA566BB4775B2EF92F8638C3
+:1040E00029AE239F976AD3D38A79F9854B7F0AEF4C
+:1040F000671457AD8B73E31C48BD15FCF281A9EF23
+:1041000073C1774B3EA91AEEFD09BE53716C15477A
+:10411000EEC94F0989739B42F262E82F24BF45C55F
+:104120009B553ECD7576919FA7E2C92A6F46F557FC
+:104130007E8991BCBB76A385F493180B0BA27F9567
+:104140001F73ADBDAD08F902D7D63A280F6D107FA9
+:104150006E2BA6765E332FB7FF99B72FEC8D5F0FCE
+:1041600092F0F3F7047FF9259DFCAED7CAF83DBE67
+:10417000B78BF77E7C8FDC29E819BC24BFDAE3C853
+:10418000732AEE8DA7A37DB4681F447F59FFC5C76E
+:104190008BED5D3F69096D45C8A74A5BE6A07CAA27
+:1041A0006D1382747E4B77EBEF019FBE08E7EFA3A0
+:1041B00069FD64A6C14F304DEABD5F4387E358AF48
+:1041C0000A3F0ACF8A2E0ABF21794784D7FEE81416
+:1041D0004E9F70BA287A945FEAC533F074391D7A1D
+:1041E000E9047FECFF2B74186D69A3F37F11B5769A
+:1041F0000FE0FA26BADCD9C526E13C7172867E371B
+:10420000E85379C9F53AEA556CC2246C4DEABDFB16
+:104210001BDE4FFE86F70BFB79FF56A4CA47F03A28
+:104220008A385D264AF9B1AA5CE077B2DB4CF89D8A
+:1042300098BF88F451E6107A9D8BFF0FF264D25735
+:10424000BEB5E86FD200A37EA8E2C137C9FE2687BB
+:10425000C5816F927AE34D617AE1B0E1323EEC665E
+:104260006E61F78973EE65729F4E9574CEE4C6FC5D
+:1042700078D091E91608ADA338E75E8873E07EAA8E
+:10428000DFC802547E8B0569DFBA990B38D46F61A1
+:104290008CF2198F444FAD58CEFB9B386A62169E44
+:1042A000879CEB2B193E86CEF5FDC11972AEEF70DF
+:1042B000998BF486C3F64CD263B00EAC217EB43732
+:1042C000B9DC472AC311BE2FA07C8DEF0B599CC9C6
+:1042D000DFE0FB02EA37E5AE61F86E92CB986FA2A1
+:1042E000BEFF96B3945946F52F77BF55F8F210F8F4
+:1042F00057DE8A1F5606BFF35BF1579561BE6FC547
+:104300000F328932C24665C14B597DE9598A0F7B0C
+:10431000C79BC42C8997E357E1331C8F0ABFFF0268
+:104320003EE7F785CFBBA53EDA6D7F2F363903F127
+:104330002FB1FEEB5E2A1804F83F0768C84BB60B96
+:10434000BC84FB773E6B6443805FB63D8E9EDF2D61
+:1043500079E8DA8671D4FEBA86129ADF3551FAAA64
+:10436000E13877521CCCE19A03FB6C5B139DBF3D97
+:10437000F7BCD903FDBBD6ECDAE4C15A7F4B9C975E
+:10438000635F1D4947BC8D6DEF3B6FB7D6AEF0E65E
+:1043900027F88B32BC778BFD4F9C2356FBEF9008A0
+:1043A00091EFAACEB3F6B71F8F8D12726548849035
+:1043B000838A4EFC3BAAA7F27EC672B991FA5014CA
+:1043C000E9DF2509DE07804F56C60CFAABB2ABBB5E
+:1043D0000798296EBD12F1CB01B06BECE4CFB98E1A
+:1043E000E5DC023DB80CF626C743F99B55744F81B6
+:1043F0003A9711916C32DE6FE38A32DCD7129D9BC3
+:1044000060A8C778061BDAC7956418DEC77B471813
+:10441000DE274E2E36D407FAC619DA0F9A5D6AA83F
+:10442000A7E83719DAA7D6DC6AA82BF9922A1EB1B9
+:10443000B4FAB986EF8736CC37B477FB9718EF9F7D
+:10444000F17BDB73932097C45FE6C69586F73F8ABE
+:1044500015E70E263B16D27D12D9CDDF318E6FFEC9
+:10446000CA0CFCA6C669E2BE0097907F7EFE3FD0D4
+:10447000B53CD9280F273A8DF630D7D734ECBFA9F1
+:10448000F516C3F337864BBBB7901592FCFB27E9B3
+:104490001C8E97EE32E609A23DF4155EBF4E1FF169
+:1044A00010FC0E6503AC9E0013FEEED079C1DF1D3B
+:1044B0008A07F8BB43EBF0771BEF6D32D21DFEEE9F
+:1044C000D0F7A38E19E93EA6DD48F7AB8E1BE9AE07
+:1044D000F8319C3E577718F9219C3ED79C0EE30F8C
+:1044E000498FD9FC7FFF10E798895E931C1A7BCC1B
+:1044F000FDAFD3E76F61F4E9A187C34EFAE275C15E
+:10450000BC38D4CBB1CEA037C8F9DC9057EFC88007
+:104510009CB4E9D611037BF9A72945F04FF7B117F1
+:104520002321F7224618FB3F9FAA47A1FDECC48B2D
+:10453000E936F04397B8AF6FBE949F2A9F90DBBBDC
+:10454000E23CDD77CC14DF3F616AA6FB920E3BF5BF
+:10455000047C7F677EBD86F84132F3ED59C8C79B66
+:10456000F78B088A27CC1B2ACE75B2FC0ECAB3572C
+:10457000726E5EAAC863193C42C6273D229F256D14
+:1045800084D00B633C4ECA7BADCC17E708B859907A
+:104590003EAF00F8783B12F71676B708FF7D8755D7
+:1045A0009C2FF5733E455C0C7A22F4B834A947354C
+:1045B000FDCE6E07FCC3B632C3BE383C6037E45D47
+:1045C000E6ED721AEA056DC986F6230FB80CEF8B7B
+:1045D00082B986F7A38E790CF531ED2586F6571D45
+:1045E000F71AEA57774C36B4BFE6B4CF504F655D43
+:1045F0008F02BF4335618FCE1821F278F81AA57863
+:10460000D2BC0DF1E2FCA0B453951EACF27175C999
+:10461000D7E1FAF4509B4EF9BD4D29CC43E700ECAD
+:10462000D23E61463D5B97F9B44A1F657E633EAD5D
+:10463000CAA3EDD1C7A5FEADF4E1903C5A6F681E48
+:10464000ED3C79CE377CDFAB1C21CFF385C13FD465
+:1046500026E6DB748F8DCE2D28B8C2E1392BF33BD3
+:1046600077D8FB3E3FB27C84B0637F96E95B3482AF
+:10467000974F403C65F6359EA7C3CFF9ABE97B3633
+:10468000CF7DAE6F1E6FDE48319F0A93E9CE69F988
+:1046900094B734FB8590F11B257F57E76B7DCE6F78
+:1046A0005E9CC82B62713617F8B7FFF1043E936D1C
+:1046B0006C2D9D739179E7776C6A7B102EF20A5B03
+:1046C000B355DC5F16B0821FA69472FDA988DBC9C2
+:1046D000DBFFEB870EAEE73CD160213FC4FA67CA2F
+:1046E0006770CDABE71CC1506E5F803FA0ABC02EA2
+:1046F000F94B9EC89BFDC9084665B9F9AB9EFC6F96
+:10470000F2A73326F70761B7F4C16FC4876A1EFFAB
+:10471000EE3CF0703C29BB90C9BCBB2C0997C25F32
+:104720008F1D2FF1A7F2F15D2BACBEA71C94D73FD4
+:1047300019F94C8A7E31F9822F7F27F181769047D3
+:10474000FDB52B37E7C7C15FDBCD5C71CEAFF1475D
+:10475000FEBBF0A2F0DFDFF99EFEE4C36572A19F0D
+:10476000F33EFDF127FDFD13E77E42E483C82F9160
+:10477000F4086499289EBB21C6B88EED79625F78F3
+:104780004EED177E6E4F1AE504837FB9699D59CAB5
+:1047900009B16F63FFC4F305EBACA4CFB006918FF2
+:1047A0005C23653163BEA471A3118FB5D27D56D74A
+:1047B0007919E93BF31DB6402B6F5FE90FDFB7BDF9
+:1047C000F43DC56B5CB8B7C4B31EFEF7AA8DC676C0
+:1047D0008B1CE25EAF056176E92269972E0AB34B26
+:1047E000FF3A42DAA51EE621BD4CC69F159C3D7CD2
+:1047F00015C8A4BC60D8A966E12FA17C2585271720
+:10480000E20B21F768727C46E562DF5E6BE9338F6D
+:10481000AC079FFDC4C9CF224EEEC2FAEFA6F33F0C
+:10482000DD7B23451C4DC52F64FBB3FE8BF41EEDD1
+:10483000D1DBB9A2F642C4917AE21D6171936E8711
+:1048400029B604FDED16F72FA83C80257F0D143AFC
+:1048500043E29C7A87C99077115EEA6BF6515E401D
+:10486000AB45CFCC433EB2C563C77D91F73B0E2726
+:10487000E1BCF614E9AF0987B747AF1AAF8938A191
+:104880005FE8B9DD9335D273B95C6458472A9E3D21
+:104890008D0507A054F1037D6309E159C50F2A83F3
+:1048A0002504E78CA645565CD9D7F1E8EAF22857EB
+:1048B0006F5CA1234DE4A3F4175F987EC943FDDD2F
+:1048C00076691CF5539AE716E7F5D73EB8027C34B3
+:1048D0006217B3629E1D61F9D8AA7C214FC89F77E9
+:1048E000F394DC96792E6B34A1C76B4CE5BD90DC5C
+:1048F00056F58BCDB25E2EEAABD6897A87BCC768F7
+:10490000A7F437609E28311FD8C5BBA53F02F340EE
+:104910008979E039E414EA9053A8434EA10E398511
+:1049200012720ACFE7335F7A9159C441CA42D60D59
+:10493000E22065217A10E220A175C44142DB230EFA
+:1049400012FA1E7190D0F7888384D61107096D8FF3
+:104950003848689D95DCD85B875CF34E33D4A773E9
+:104960007DBF2C64DD220E12DA3FE22086FEF415B4
+:1049700086EF6F670D86EF1107096D7F6783668885
+:1049800093DC29CFA5576D4D20FEB8C9ED6BCCE364
+:10499000F4FD43F4DFEFB6C20E341F5C4CF6595DF4
+:1049A0009447D0B979B2A0BB89093A77CD213AAF03
+:1049B000B6897AB9C88BED2BDE509625E20D281109
+:1049C0006F408978034AC41B701F36E20D28116FAF
+:1049D000C073C41B5022DE8012F106948837A044B5
+:1049E000BC0125E20DF80EF106948837E039E20D9E
+:1049F00028116FC0F313887B64F5C205BD3DCB6001
+:104A00003F723E34D88F4E431D7A7B687BE8EDA120
+:104A1000EFA1B787BE87DE1E5A87DE1EDA1E7A7BBD
+:104A200068FDD00817AD33E8EFA1DF417F0FAD1768
+:104A300034FB5F838FE9E66DE78FA2EC88D19ED0CF
+:104A4000B82808E67D3C0371A48E482D3D9E2F7941
+:104A5000EB9ACE1965BCAECBFCB242D645F73BEB28
+:104A6000F2DE1A3DC8281FB6E02FC9422EC83824EE
+:104A7000FD71BA17ED65640794CAF383EA7B0F737F
+:104A80009A51AAF6BDF5BEDB858FAFDA91BC0C81D9
+:104A9000831B8845C883285AED28461EF74E932667
+:104AA000F220EF1379A8E17CF527B96FEF34ED39E7
+:104AB0001C85BC964A8DEE8BCFB1B063B8C7BBA046
+:104AC000B9BE18FAC2C7793DF7CB8F435E8C825BC3
+:104AD000F901B99CA07355E3BB98AD3A1FF7893132
+:104AE000DB02C8779BD013F01DECC73CBFE67D2AE4
+:104AF00084BF3FCD137ABFEE5F31AE9A3FCFDB5D0F
+:104B00003F0EE7B5A64489EF7EF2642CE171EA5AC4
+:104B1000ED299C8B1BBF9B7971FEF282843B6FB7A2
+:104B2000D3564DE33AE99C578FBDB22D9DCEA55586
+:104B3000B28EB264F2E56B748FB9C21B9FDF51CCA9
+:104B40008F8BF86356D247C5799128795E449D13BF
+:104B5000715B7C7B608FA8F322D78E8E2F47BE16A9
+:104B60003B28EEDDBB7974E5BA81BC7F3D20EEDDEC
+:104B7000BBF64FF5AF517DBBB8778FD8602C8D4316
+:104B8000FBDA30BF46F73D4CF5B79A06B8707E7435
+:104B90008D3509ED77330FD49F614C9C8354F0E53C
+:104BA000B37613EE1DE75BCC91C4103EE29C7A1BFA
+:104BB000E85EE4B1D27D10D32C4E2BE446F83E7E65
+:104BC000793E5D989E10960FD1B4FA78BA3903FEFB
+:104BD00024932708B9B52F9AF405A5EF54CA3CA829
+:104BE0008B6B5FA3FBAC2BF708FD40E77200F24F25
+:104BF000E547D46506D24DD01706B7162698C5FEF0
+:104C00009FCFF178C6FFE2CC1217CE31BE46F9FA3B
+:104C100095EBC6C489F33A22FE502DF1542DF35F73
+:104C200058BE33097AA7BAC7B4DC3C3E8ECEBB353A
+:104C30000B7D4EF9772A7F35EA75D0B9F271791F6D
+:104C4000C8C64A3A07149E87A2F44375DFC9E2B585
+:104C500056CA6F591CA6072E957AE0D2303DF09ABD
+:104C60007CE99F517AA0BA9F4EB6A9FCD59119A4B0
+:104C7000A7D48BFBF82AD608BD85ED11F7D857AC21
+:104C80009968C2BD1515FBBC1EAD0FFE7857EA2F03
+:104C900053306822F27C065339F3523295B32EE535
+:104CA000921CC0590CD0BFE36546FAF47B525F9961
+:104CB000813C3F9C8FF347C87C3E46FA5211739665
+:104CC000436E8CF06A47E0BE9E62D5D7218F704A52
+:104CD0002BA3F3303743AFE12F6643CF19053E775F
+:104CE00097D3B980C91A9DAFB879F40AC9D79CCFB8
+:104CF00019F8DC2FF9D647F59EFD40F2B7EEEFB478
+:104D0000D0BDAC7ECD867BD97469CF2AFE0DE7F38A
+:104D100079F2F7269843F8997AFC50001697ABF889
+:104D2000C7CE84BE380FBEC1C1929076D875E2FD61
+:104D3000DDBBC7CE5C8B1CEBFF4BFF4485FA1D0629
+:104D4000AE67419EDE7157916D7E885C292D2C6D7A
+:104D50002918D84BF7F93DE7C6F20741FF5F797F85
+:104D6000F6A0AF3BBF58C5F18CF5312FAEE36EDC3A
+:104D70008CFB703EF39625E33E66A62E9109225FDA
+:104D80006DAEAC1FDE7DE77F6E74107EA8BE39BFAE
+:104D90007CA69FD68B9057B7435E9921A7F487F2E4
+:104DA000911F64EF98047A44E777C9F3F0F21C6B23
+:104DB000983FE270BEA043B85FA22A5FC8716671D7
+:104DC000A5DF4EE7545DE4D753F07F62359E1B5458
+:104DD000E5CFA47DFDEFCAB7FF7392FE2CE6F788FE
+:104DE000499CDF1E6C6E66D23F247E2743AE1F2691
+:104DF000EF33E8A53F971AA0FFFD9A3394FEFA46D9
+:104E00004D9C9BEEC78FC372BB1EDD013F5EA3F8B6
+:104E10007D8E2773041F3DF91D1BE9DF15B6F6D7FC
+:104E2000704F93C2E3470DFF61A5FBFE58301BF79F
+:104E30004FCDAD8FA4FB5E4B0B7D8720F7A2F33DDA
+:104E4000448F9602C1671D4EDF513CAFDB74E80909
+:104E50009C1F5F7ED04DE71A2B0F14ADC7BD16A562
+:104E600085FA9B986FA5C369C3FEBD6C6D3CED6769
+:104E7000F306C9F385AC8BE2540AFF9DF9621FDD8E
+:104E800052C8E43DA732BF9E0BCA69867632AF385E
+:104E90006C9D28FF60B89F21FC3E81FED68FF227D3
+:104EA000C07F600BF12F2AFF8435F79339D83F2B51
+:104EB0006CC6F370AA4C289076AEB40317F4EC5F7E
+:104EC000F99306415FDEACD1EFD6543B5CB3AEE65E
+:104ED000F5EA6356640AB229092E718FC4FDE21EF9
+:104EE00089F97CBD42DE54C8BCA1EAAD25B4DEAA76
+:104EF00003BC4CEC7F5DDEBEF948DACBE09FA097A7
+:104F0000CE89573BBDB68490755FD5AC19CE99ABB1
+:104F1000BAA9C02CD611AE302F86BC70DB70974B6F
+:104F200005572B9087965020F8437DC7DB511EC351
+:104F3000940CF6BAB8C787C3ED16E31587F43FBFE4
+:104F4000D9785E9EB7277DC8511023CEA73BF9BC08
+:104F5000E1FF703A094E8E07C253D783BC3F178DCD
+:104F600043F4A80A06ACB0B72B903FC1EB739D0188
+:104F70002BC699BF56DC5BA16F12E3E81BE36D05FE
+:104F8000D0972C4E5B1AF027EFB5E7F0911CACE6FA
+:104F900078C1F91F750E301C3F9512DEEAE678A342
+:104FA0001ED6BCD90A7ACCE9E7FCFC7505826FE70E
+:104FB000AF9D40E79FAB2D5ECAAFD7257EFFB822DD
+:104FC000F201C407E6B46CB1BA79BDB040C899EB40
+:104FD0000A047F4DC90866D3FD342B223D80738EB1
+:104FE000B399E6D783DF87393E34DC83E223FC7252
+:104FF000BEF0238FACBAC548CF5E7862C43D462D63
+:1050000095B4DE165A749B33148EAD87B271AE67B9
+:105010000E5FDFB8778739753A6FF3E9C3B3D269AA
+:105020009E1C4EE035C6E39A84FB66389F101F2B0A
+:105030007E51E783D578330BC479C799057DFBD7BB
+:105040007BD7A597F49B264E5FF8BDFB5B97361C7C
+:1050500034E2E3DAAAC53D60E1EB54AD4FB52ED59D
+:105060003A55EBF709AB2F98ACF5CA19BEDFD6BF9E
+:10507000D0079E5A0A841C992BE9CAF17A34F45C51
+:10508000D1F7E47AAEC830AE77F447F7064ABA579C
+:105090009406B3710E50B557E3562488EFC0F7E07D
+:1050A000B7A5723CB45F49ED4D067951D5232F76F3
+:1050B000AF4B82BCD8A391BEBBF2C12369DF861E71
+:1050C000FB9CD063CFD4EE589602BF8125901E7A08
+:1050D0003F537550C887055CFF81BC5828F7E9929B
+:1050E0006CFD3B0521EBB7FA87CFE5E842BE042112
+:1050F0005F3E7EEE950FC6B97AF74F05FFFC8DBF78
+:10510000B6563A42F1A5C9FB28BAE9DC5795C3E681
+:10511000429E6DD5DA4A92B72C99DB135A489E54B9
+:10512000181F54AED5E8DEACAA86B101F3FFA05C2F
+:10513000AEDA348DEEE6517452F76FA8FD54C1FF1C
+:10514000B8847FAEE4E380946B736BDCB685B4EE19
+:10515000DDB62AF0BF7C3FA7DAF8BC874E3D71EC84
+:10516000FCF5C9F21C0BD9259BACC2BFB73B86F43A
+:10517000D5332B5F7A67266FF7C523ADE9D04F147F
+:105180001C8BA41F6F81F4C72D947A2BA7D34F0BD0
+:1051900042F25B163D29E854F5FCAF7E8FFBA12A55
+:1051A00032A43C7B509C2F9FDFB687E83667E366CE
+:1051B000AB9BB7FB4581DB20A7ABEA8B9CF04FCFC5
+:1051C000DDD86A851CF8859437E1FC5E21F3521521
+:1051D0005EB1EF6821F10BD51EF26F0F1FE7AE1520
+:1051E00091B1C87351E39C967C5C551F9F80F1AAD6
+:1051F000EA2B7F00BB47C9FBF075773252AC87F9C9
+:10520000BC3FACCB93133C74CEB642FEBE5478FB8D
+:105210003F48BAFDC82AEE114C8D6E7B9AF2169665
+:105220004779201FB2B23A021817FC0CB86D2671EC
+:10523000EF60566DC7978083ABC5949F8212F71DB0
+:10524000414D4EE2F5A74CE23C50865994D642C1FE
+:105250000F704DE13D1BD041F79F85E4671AF8D5EB
+:10526000C6B66FC4FD2BB6018C7EEF45F1A7EA47A9
+:10527000F1A7E2DFFEE6F7DF5738BF936EE987C894
+:10528000F5A4E31CC5BC8786D1FDFCDF344F9BBC75
+:1052900007AF67BE11E2770B2E9B6F968C8FF73BA3
+:1052A000DF96F2A43EE61B3E4FB54E54EE754F5CC2
+:1052B000A159C4154E6A7CFFE2DF9D5C1149795FFC
+:1052C0006A5ECAEF7DA5F9F2EEC2049937DC1103DC
+:1052D0003DB242FE1E040B8A3A9E4F0B79AEF67D1C
+:1052E000756F9892CFA7EAE5BEC83A1EC47A660DDC
+:1052F00099744FC689E69331B8BFE3E404019FFA7D
+:10530000EE2EAB38F7CA626C2EDC9FC8ED2BFADDAF
+:1053100087056B07911D79474326C9853BFCF1C280
+:10532000EF20F5FB85520E46DF55B9FE2AB4DFEAC1
+:10533000766A7C9C050ECFA75BE9FB3C0FF4C1E8C5
+:105340009669B60CD27B851DA0E2407769CC47E711
+:10535000992027B1BE4C87B2B0EF2CDA2AEC802915
+:1053600026B611F1C2A14DBE492990138F8A7B2325
+:10537000D936E3BD4A2F66FBC617026F61F791DD90
+:10538000656DF30E821CE7FA06FC4C0B1C3ED2DB6B
+:105390005F9172F2444B27DD4FAEF07AD939159BFD
+:1053A0003897DA156322FFDB959E57A996F124C53D
+:1053B000372A1EF518FE7335F064A27DADDC5C4122
+:1053C000F7FAAC6F994865F5E6F247FC05380FEB44
+:1053D0004B1A47705BC93F565D37519C1F7D2A228F
+:1053E0001EF64DBAD59F1EAA9756B76EA0732AA770
+:1053F0005B23E99C4A99735A59FC00BA6F97CE7D9A
+:10540000A976B585623F5F5237D170CE6401EF1344
+:1054100079B07F6E8BA6BC52757EE4DE287D51E1AB
+:1054200040718EE46A97383F9242ED5D7DFAC35534
+:10543000F969A3388F10722E66EA1CFE7D6DDD8B34
+:10544000B1E867E9C3EF8DE59881FF6915FAEF3997
+:1054500017B3559C8BB90BF612F4C804DFCC39C0D6
+:10546000FF9B66C27F7FE3D5E0474942EC883B0261
+:1054700071A4B7EA4166433C597732D28B4F9B59AE
+:1054800003F400A5BFA8E71B245E4EC735A7833FE2
+:1054900016EFDC928EFDE5F31851AFD839EB9790FB
+:1054A00057FAF608A19F5B18E9C3557EA15FB39A2E
+:1054B00004752F66E43CCE479B0BA3C53D3DF2FC33
+:1054C0008C824BDDB7FAB945DC17837331E0F78F77
+:1054D0002CC105A0EF475C7F851D5B2BE5D847CD30
+:1054E00066FADD113F5F28D0433E6A7E3106E773DE
+:1054F00095BE566EFED88BFB6856EE13E75471AF1F
+:1055000039DD5929FD20CBA41F64E5CBD649F8DD50
+:1055100011AE7FD1935A4BD0D617FD9648FDAAA75E
+:10552000BE770FD96DB5BB85FE50DBD649FA83D265
+:1055300047D4B9B8A5BB3B499F50DF2DDB2BF052B8
+:10554000B7573CAF44DEBAFCBD502D0BF6B446F560
+:105550007776CF9DB5C6509F43F577F2A5BFDED2D3
+:1055600045FAE003B9BF213BBC6EADEC97D7AD2146
+:10557000E3ED07138D11CF331DF8DE65D01BEAF67E
+:10558000C6D3F7C1BAA88DD8E7BDCB1C16944D750C
+:105590000EDAF7B7D59B722DA3015C94077ADC4134
+:1055A00099BF3570E97F46C27F90C2BA8EE0DED7E0
+:1055B000C34EFD4DC819F57B96EADCCB85573F1BE2
+:1055C00085FEAF1BDA7111773C58B585B3109FF893
+:1055D00075A19C477EC728F0F5C0C3423E3F6E656B
+:1055E0001BE9FE608B8FC16F1F947145FF5F4CE21A
+:1055F000F725B4E08F43F52BEB48B19FFA22447CAA
+:10560000B1C8AD7F08386ED1AC0545B0A95DE66C78
+:10561000F4AF7E4745E9A9A5523EA749FBCA3638F3
+:10562000D9013ED6BC5E3A87785FFEE12AECCBDF3B
+:10563000EFB2D3EFABAA3CBFD2AE28D25BD3064FBA
+:10564000A6FD4C7359584531FC2AA620F255BFCF10
+:10565000EC222FC01EA6D79A22291F593BF8C65FFD
+:1056600020CF53CD5F1EC1EF94A47E5BA3FB2FE739
+:10567000757FFA387E63A682058AE81EBC78FD2213
+:105680004877A27B72A7CE49F67D679BDD23F6099A
+:10569000160AFFC17BFE129B60EA85EB42D7A77416
+:1056A000AFE0852E3BF96B4B0FCAFBF6C2E0B99019
+:1056B000ECA2BC68DE8EF4CC0B0E13DD33567AF010
+:1056C00008DD9B57AAEED5B31BEFD563AEB478F8CF
+:1056D00093C987CA9582A42641B7EBE28C7662D241
+:1056E00048A127268DD4E43DA5027FDDF6F36FE9BE
+:1056F0005AEF3A5CAEE2F7EAF7A66A22E8F7A6BAF2
+:105700000F667EEDFD09EF417FE07AC1F732BCE91B
+:1057100023C7F4EE9F33245ED43E6C96FDCF90F801
+:1057200099E130097C84FDDE86E20F457F05AF3AC2
+:1057300077A4E8C6BED3FE1ACE05717A153CC4889C
+:105740004EB918FFC45FDE5E8763FE83CDDE4EDD9B
+:10575000FD6FA15310F7E05C319DDAC3E9148C1C96
+:10576000063DE161F1FB5BE1798D2C97D13A9F67B2
+:105770008E223FA02EEF05E7EBFB35AC6FB5AE8771
+:105780004EEE28C0FE78829BDE80ABC3D446CF1796
+:105790008DCCA0753884B5A7C8FC9B31D0CB9AE4DA
+:1057A000FDC73DBF63B8D841F78D5C08A8FB8F03E8
+:1057B0008F2EE4E3B6CCC827BFFE0526D77B4DCF9E
+:1057C0003DD9E2FEE39E7BB2CD7EF293CC89223FAF
+:1057D0004FCF3DD9D9E2BEEB573496837B68FDD3DA
+:1057E000EC941F1F7E4F36DF679E463CE3B19A283C
+:1057F0008A43A9FB914B9D7AE5C88197DF8FFC888E
+:10580000E69BB300FD1538A8BF8E3951CFEF146861
+:105810000EC28F73A22186EE85567CA9FCD743FD6C
+:105820009D8F024FEA5CE71F247F29BCAB736D0A92
+:10583000FF8ACFD47DECDA6AC16F3D79B2CB18F91B
+:1058400047867010A229EFD1E3029E1F8CD71B0060
+:1058500077D30A2E37C82F2EF2374F988CBFDBAB89
+:10586000CA26B92E99CCFF9F27F7A9792ADFBFC195
+:1058700098EF1F7E7F66629C6F1DC63BA7BD3716E3
+:105880000FDFFE6F739FF9233F90727974B4FE208F
+:10589000DAAB730F4A2F7CBBE8B334FA9D91AF8E1D
+:1058A000D0EF29CE75FA9AB18E22B3441CE00F29AD
+:1058B0001D744EE30F73FE9A467EE4D5E2DECF2BD5
+:1058C00085F3F273B4820F562D107986A9AC9EF839
+:1058D00036B9F77C6624E0F8FFED1C6DEF39D7C9C7
+:1058E000A34E51BE858F7EA7229C1EE3230EBFE8E8
+:1058F000E216CA1B233F9945E74EE30EAF72F3FA57
+:105900003B3FFD54D4530F5F74E35CEA4F3F9B452C
+:10591000E74CF30E5FC439D4DFFCF4B4787F0DA3F9
+:1059200038D6FB3FFD7C16CE9DDADDFA07A0EBCC26
+:105930004BF5AF615BFD60CDAD0BDC748E725A5AD6
+:10594000AE3847F916E8392369FEBA38ADF71C6559
+:10595000F748DF07787EE14BC1E76EC4C006FEEB77
+:10596000A53A47AAE46C7FF250ADB77FD73958B556
+:105970007ED94ECF462B98D0FF2F9F4FED12FB992B
+:10598000F17CEA6BAFFED685BCC3F1A3EDC4CFE3D7
+:105990001DED2EF80550875CDCFEA538CF87769686
+:1059A000D07603C439BEF1384F01FF41B73867F8EC
+:1059B000DAAB6FA440DE8FAFB7519ECF16F9BB00B4
+:1059C00031A643668CF37F00B1492F16008000009A
+:1059D000000000001F8B080000000000000BB53C19
+:1059E0000B5894D795F79F7F9E30C08008288A3F38
+:1059F000820413A433BC345BDB8E0A14A54D31DD65
+:105A0000A41A098E9120AF01D4B671B7C9C7188CFA
+:105A1000519B74756312638C1950D434B83B463073
+:105A2000A0D84C4CA4C63C96B05BE2B7DBF86162F0
+:105A30008CAF0C48926EFCD6D63DE7DCFB330F20D2
+:105A400026ED2E7EEDCDB9EF7BDEE7DCFB4FC430DB
+:105A5000634D1263530C8C19B3188BD733668A616C
+:105A6000EC591DC050EE1D665E4D246353631A56FB
+:105A7000B31C28CBCCD6A664067F6EC672194B9C8D
+:105A8000E09D6484FAC4B57AAA8FD0F4290D66C665
+:105A90007C8DDE45E75319CB0F8BCC64DF8152CF71
+:105AA000D2B5D08F69C2ACADB05E817CA32711E0C6
+:105AB000355D920D9666F986925D2C85B13A2D0082
+:105AC000B1F83F93BB15D7D1F656ED877E7D71892E
+:105AD000D62D004E4938C252B3617C7D51069BCE13
+:105AE000D8098B638A7522B4B3AD128E0FCFE0E371
+:105AF0007F5A14DE22C3F8C1E3B7E53AA0EE6E8305
+:105B0000D2C1AC8CA578A29768EF04384AC9952C0D
+:105B1000005B63976827011CAF7448D06E74452FF3
+:105B2000C99F84E7335ACEA733F63326B12899B1FB
+:105B300064AD231DD771167DA6671A6C1FD297CC52
+:105B4000622CC36A213C4C3C0178827D0E2D8C7006
+:105B5000B7C0F95886928BED49BAA1480BE063F0C3
+:105B600086B6C86DA671917F0FF537F1EF078CED02
+:105B7000EE96A95E85D5D267854960BDFA54F313C8
+:105B800088BFBA04A391CAEE6B850CE7D196A4DE58
+:105B90000DF3D8F56C7949C6E8F103560DED2B7974
+:105BA00023107432AECBEC4C81FF0B632AEC627392
+:105BB000186BFE2554FC1D6F879330FD0C8D806D96
+:105BC0003BF25383FADBB1BFBF9DD98DCC3FFE7E44
+:105BD000EB8C1D1BB4623DA4730573CF802324B2EC
+:105BE000068901FE129897E8B3DB1643FBA23FA09B
+:105BF000D30BB1A6E62DD02F55662E531695CC02A9
+:105C0000656238AC07ED89AF99DCC8577B4DD00E83
+:105C1000435335BCDCABE1FDF561CC857C3A1560C6
+:105C200006E5319BA3CE3691E6F1D23CF2211BF280
+:105C3000E324E6A1F5E3998BF6A3F69BC27A4D081F
+:105C400033ED501AD26BAEAC19139F3ADBBCF5485A
+:105C50007F5FA39D7DA20DA05378E4BA40FAD5E101
+:105C60007873E0B8F9344E1DEF5CA7619F4CC0C358
+:105C70007B897F9CA91ABB3B03C7B137A52CACEF2E
+:105C8000D59744F8C7F5371AD9274087FF68645479
+:105C90009E69B4D0FAFFD99840E51F1B15AA3FDBD7
+:105CA000984EE540A395EA3F6A9C43E5BDCB22723E
+:105CB00090FFEB3BE7B14F8C1CED37E17F4E8FCE71
+:105CC000311000F7CF1B9B8FF60B3EEA4F1EBBDD5A
+:105CD0008BEDB8CFEF737A0E3EC8DC2DC9C4971B8D
+:105CE0002C31A3E90FE733E1F90623D8120FE0E9DD
+:105CF000588E44F30F4EE270B35547F3D9356C0715
+:105D00008E3F96A3E7F34FD75462BB3D86CFDB9F10
+:105D10000630ECA768CEBC17114FF638A8CFF2C3F7
+:105D2000FDB7F376FB645EAFEE576DAFB359685EB7
+:105D300095EE833A583F83F89DE657FB7F96C7E57B
+:105D400030B4BF3B5553E41E031F1A1BEF4F7201C3
+:105D5000F870A11C2407C8459D4272A1F2A1CA7F18
+:105D6000BB6D1C8FA906C1E7E12007312407342E43
+:105D7000311EE44022BCD8199C67AF24E425541E90
+:105D8000A0443DAECA832A072ABF27829C4931FE20
+:105D9000737C2F845FD5F29495D3A5372EE21744F8
+:105DA000D76E9D055421F40742C6207C4F8E1DC638
+:105DB000153C6E6E184B7FDDB4FE8D7850F5C13802
+:105DC0007818757E3D2FBFEDF949BFA1DE46BE1D97
+:105DD000435F7D6655F515E75B9DCDFEA915F95529
+:105DE0003269A528284D9C6F42CF7F2C87CB8DCA66
+:105DF0003FBB6D8CDB4B3C67CA687DA79E67E49C0C
+:105E0000AB18E9BDD4305E1F4A5FF55C017AEFCF75
+:105E1000B82F159F8C796C1698674AADD9BA25D9D9
+:105E2000CFBFBE89D72BD07E6DB62AB49FE735325F
+:105E3000D15FB52723F592BC7C7146909D6116A079
+:105E4000E3D07103C9B757C32A5F8171ADB8D49D40
+:105E5000FE73CF16F41B5E3243B30EF6E5FB93D907
+:105E60008576CB3779E8AC04E37D3B74CC45FE8383
+:105E7000FD47521C630F824D41BB7415F41C4B63EC
+:105E80004C7EEECBB312ECBBE239991900753E5053
+:105E9000DB328CAB7F3AC26DE4E3188371B5625C90
+:105EA000D38ECFEF45FEBA00FC6980F64F4C75D318
+:105EB0005926630B9ED3111E2B22F46EAC7F63C751
+:105EC00053A796017CA15D52D0DF2894CDD45EFD0E
+:105ED00092ECC6756ACD859724F0737CEDCDCF84A6
+:105EE00041BDF3808E99605C61BB64F5C2FCAB3C44
+:105EF00011881956B15DF7D140BA5F6FFE50D8B125
+:105F0000CABD921B388655EE0A6EAFDE1B0CD73227
+:105F1000AD1F86F9B36C11B117EE006026B3DD44F6
+:105F2000BA6D8F416335A2B743F90ACD36E9C7355B
+:105F30005C1F33F645DCDDC097F2F12F933E3273E0
+:105F400078B180CF01FCD9971CFF2ADEEA84CEFF0E
+:105F50006C12CBF1C039EB8E9B2C2E38585D974CD0
+:105F6000E7F079A208CFF5610377919C1E952DE8A3
+:105F7000876DEE945DD8EEEC36EDD1C039EB3A2466
+:105F8000A645B8D3E0E678BA5681EDAB3A4D160592
+:105F9000DB8F1A980CE37D403713D271EA00D11FD2
+:105FA000E9EA92680B3F92F2FCF497915EB17E7A37
+:105FB00035EDE0FBB97080D3A7507E584BF46A965C
+:105FC000587C009D7FAF7979845ED86FC1737FE87C
+:105FD000413A57C0FE0C0AD25D263A5F00FAE0BC97
+:105FE000FAE39F240D98FDF49681DEBF52C743FF6C
+:105FF00055B7A07725736D447FEEDBD2395CC83F7F
+:10600000F8BD179E47BF37426F453E8C15FEF1C461
+:106010009AFE93B1B06059CC15E76AA89F91F00A37
+:106020004B053F418A763C6483716717BEFB18922B
+:10603000A36FD1CB36E48B26DD40EBB350E18A0E63
+:10604000B7A20C0E262FDEF52AAC931F733DE91084
+:10605000CACBEF0C1664A726218FF86704FA3B1908
+:10606000C737D0F11C9EDFD96DF01A008FACBDC0D0
+:106070003EE20F4C477BECD1A39E2AD00F95AD4654
+:106080007F1CE6C37524602394EB9AEEDF9F91603A
+:106090009CA4C4B252848D66AF8CF3B4E9AE8E9CDE
+:1060A0001BE6912CEF52BF5DB6E9B48F94F8EF294F
+:1060B000A87F9A96324758CAD7E979467AFE059D55
+:1060C000D0EFE3F97FE3E87BD5EF63AE29D117602A
+:1060D0004EC405971FAE7756CD61E24FC885802B21
+:1060E000D7BB228DD079D51DD6043CFFA7C86791B8
+:1060F000C87FEF6827C0BE6A5B25A25B1DF20F9CBC
+:10610000EB24DA37A81FF4083DF2526FFE84582CB6
+:10611000252B482AABEA96AD5E68AFEAE4FC348AE8
+:106120006F84FEA86EE3FA63141FB5011CE0A7D5C7
+:10613000215FA930D0FBA85F7FCCBA09FB7D713607
+:1061400013F4E67AA240CE881A007E19664A942596
+:1061500023C06E49DCDF52F5CA6D3B40D507AC3B2E
+:10616000D36D64DA8075EF3860098267791282FA3C
+:106170007FA753096AB779D383DAB34F5983E0DC39
+:10618000DE3941FD679FB107C1770E1405F5FFEEBB
+:10619000C59220783803CE3396DF21CA1F264841A6
+:1061A000FD172AA6A0F98BD3A383E061B3C08FF0BB
+:1061B0000355FFF4A28DFB41A1A58ADF1F5B83D7A6
+:1061C00051E3E29FCC095E6FB13D78BD6F4A977D88
+:1061D000E0F76BC1AF3F00F611CBDF82FFAF05BF29
+:1061E000BE0DFC7F84FF05FC7F2C3DE0FF63FD2B93
+:1061F000E0FF23DC0EFE3FC247205E41B8B3B1880A
+:10620000CAA38D25547F2BFCF588754F89754F8B5C
+:1062100075FF5A3CA9A5B36886E62B90D3793197D0
+:10622000F4A887ED6B060A310F30F496CC5A504033
+:106230001CEE538DB1688F2630F45B58C9D0DB1A41
+:10624000843B522C5B14B443FFFE1EB6FBDA65059B
+:10625000F5F989CE8F23719EAB5F811C66E3B88F01
+:1062600023313EAEBDCE08DE02ED0AC00B0F8162C7
+:10627000207F06F41AF64F5561B79E4159D27648F1
+:106280008FF4A8397088DADFF2E882DB0F3407B5C3
+:106290005BB03F94355A37C5F7973BD5F9BCD4BFAF
+:1062A0003655B2A35F7CF9C0BFC75560BFB6F7E3F0
+:1062B000567E0DBE3F3BF27206EA7527D861AFD914
+:1062C0003F8FB34B2760BEEFDAD44385316808DADD
+:1062D0002436038AAB6C2B5B07FAAEA6B3B516F572
+:1062E000504DFA321D4B267D24F20DA06DD15FC2B8
+:1062F000E01EF077D5F379E44A98F735CFC9BBECC7
+:1063000048BFEE372271DDC17639289E5994C5FD0C
+:10631000D645597AA2E3D5F637221568DFEC7983A2
+:10632000E35BEBA5739F10F0209484E74E99CE5D5C
+:10633000F59586F0AFCE774F964CF32DEC9C1181FE
+:10634000E7EAF3F0F596672934FFC2D415E5B8FF04
+:10635000D3094B7365F2F34031A35EBDBDB815F3AD
+:1063600003351ED93E56BCB55ACCDBA3E37CF856A8
+:10637000EAE19EC9C01FA78B26D848E78B7E5559F6
+:10638000DC1F2FD43B52D12EF4999508E4E3478BC0
+:10639000522290AE27B0C4FAA23D7A0794D5ED7C84
+:1063A000BD3E4B6F24F25B5F7BB68C7E8B3ADF4A3F
+:1063B000B1EE085F8FD0CD4574AA74379B711E3F34
+:1063C000FD78FDF22C9E2F3AED7EFF5EF453FAD25B
+:1063D000C3AD48971E3DA3F8B606E88AF6A0AF3BCA
+:1063E000B119F1A0AEB73C4BC4C9E91AA2ABAF5387
+:1063F00027FA2D6B6541FD78FC7C756FF07E2CEEE5
+:1064000073BF598676E905F0ABA1BA56D71087E776
+:10641000FF7457F0FE2A059E6B75DEB8B8007EAD9E
+:10642000ED1A911733F177972A1F0AD153A5635FAD
+:106430003AF7DBFA120C6E8C176B0FB5125F8FCE2A
+:10644000EFF426A39F9FF89091F286B78A67553F95
+:106450002020EE6118C7E98A527235D3FDF67ED04E
+:10646000667F3E6B22C6432514EFF5B1A10A34FEC8
+:106470004EF483A350EFFEF1195C77B81DFC3D5834
+:10648000D769EC5C741EFCAC612B080AEC7B789736
+:10649000CE2DE21333FAA715C23FFD5471E4C96053
+:1064A0005F9DEB3574BEDA8C30EED70A3DF9D9A189
+:1064B000E49F20BFD69E922D46F443216E21B88DD5
+:1064C000FB05759EE47F9A8BFE769B8EFC00D5EFD4
+:1064D000700ABFE382F0672FAC1FD293BF7A5C6271
+:1064E0004FC13E2A3BB7F52442BB336311F9AB4E93
+:1064F000B98DF28FAB7604FB0555EE60B8E64030FF
+:10650000EC0CF11BD4B8ED44D688FF3013E38F02B6
+:10651000796E3CCAC107829E6A3CB27696351EE50A
+:106520007DB35659A4E603104FF5C70F57E17EDD42
+:10653000B561568A0BD61D257C0E7EC1E38EC10443
+:10654000C6FD23C6F13AD8C9F9BB5E27F13803D896
+:1065500095E6334AEEF5D034E81A8E24BDC45811BE
+:10656000CAC39AA53C8EB463CE15CA17845E0AB519
+:1065700097DFD70EC8D101FAE17C16F737F3F5CCD7
+:1065800081766A6D8495ECD63423F7B70B1EF6D866
+:10659000900FA6417C6C08C8674F330F49D86FEF46
+:1065A0002310E266FAE3FBC55A8B2E3AC0EE31B6F1
+:1065B0009EFAABF38326E1E36F35BF05E637FBE7D1
+:1065C000077C4721BE3FCFB1923D4E5ACC582FC9D0
+:1065D0006303C9A37A9EABC067988FC59C09D2ADEF
+:1065E00076D7EB940776B25E8A470A23F93E0A71A2
+:1065F0003F0887F19265737CD9B3B9FE589B1D6C37
+:1066000097BBB2ED5236943BB21DBA6CD26716E21C
+:10661000CBB58257C04F891F1843EFAE7997C75546
+:106620009F831CA09CDFDF2029A9417E10E7EF7A21
+:106630005EC5AE304FFF5CC483CBDE9B1E877114FA
+:1066400097ABE5EB4C4A6A009FD6239F035E2A2D49
+:10665000553F42BFDBB12E4EC17C7F3DF2FD7444FD
+:1066600023E7EB58F887F1C5283EF704C3F0B70BD2
+:10667000F9AB8E19AC6847EA3B43DBAD5ACCEBA4CF
+:1066800064831C84FBE52049F065B34372A3DE6F8D
+:10669000BEA1E579AC5289F256F74025F225FD619D
+:1066A000BFCA796E9CFF1E00311E62DB63496EA873
+:1066B00011F4C8DF8BF3DEA3F5BE8E727C52E7497E
+:1066C000C67CCA49A7D18AF32F65E070807E296510
+:1066D000BD54F687D775786972D7548C9B3F701874
+:1066E000288FD3BCA12502F56926DB60B9908EC640
+:1066F0009D1DB8993DBE5F018CC42EA874A1BCD06D
+:1067000056118772BAEEC8B6CFCBCE1D7F7CCD1F97
+:106710003AEEC290A2E617ADFA78CE36BDE9797EA0
+:10672000FAD5334F3AEE57A5D708FD60CF53000F87
+:106730004BD8501EC6352ADD8CF06F2CBAA9F84C08
+:10674000D20DFD1451067689F44B283D55FCD6B187
+:10675000061DCF7335BCB714FADFB741A3A07F384D
+:106760008ABEB7A083D7C49BBC1112C59BE3D14599
+:10677000A5874A9F33D17CDC99FB65CAD3FD5FD3E3
+:10678000A52BDBF1D0D7C963A8FC8D276FCBD785AC
+:10679000C86588FCA9F472AC8B243953E958AB3036
+:1067A0008A5B6BBB23AC6EE6A79F19FE21FDF09EB2
+:1067B00082F231ED12DB297D13391CA07B8D50FA5A
+:1067C000006FD851AF3F951D6C8754BA8DA77F5489
+:1067D000FDF521F39EB448743FC0E5F3970637DE1C
+:1067E0002FAAF703EA3DC061A1F742CB0FC1EFC06A
+:1067F0007B972DE97D13D15FEBD7ABF3F0FBC70F90
+:10680000D7F74E5D0DE33F9CC7CB7EF4D302607B90
+:1068100018CFC37D38C9E042BC7D28CD9C8F76FC63
+:1068200043E9A1BB381CAF57105E1A3FDF0270BFAF
+:106830004ECDDB3D2AF4B09BEF63E9EC7CEA27B157
+:1068400037111F8AC44A681D498A2982FD7CF88B4A
+:1068500019594DCC7FFE966CEECFBA55FDAEE6B120
+:10686000FF41A23CF672300116CCB7CF7FB6683A32
+:10687000D49FFDC7141BDDFFAD095E1FED6832E537
+:1068800007B7D13CDFFF6A48B722C3BFAF11FB9700
+:106890007F8DD797CFA078A252D0D01E3393C7B1A7
+:1068A000EE9428B447AA7D1A3E75D81C98BFBC0444
+:1068B000F68BE903E0994F2605DAB7D7F7FD3A0DD5
+:1068C000E7A9D4BB32AD184F363F9F847E40E5BE6A
+:1068D000C7D3C82FDDB7390DE38BCA965FA7D90997
+:1068E0000E77507CA3E5E7BE72F0CE3D5B02FCE084
+:1068F000EA5C99F65F6A7CBD00FDD345777CF618AB
+:10690000E6C367FCA34479B1FB59EF636837CBD288
+:10691000B91CB1ED46D2EB301FDD3BB6CEFCF15ECB
+:10692000D4E7A7D33FD69543BFEBD95AC24F1973CB
+:106930003F118FF9B04D12E5C3FCFDA7D23DE68AA9
+:106940000D923E2116ED61B44D56705C34EDE3813D
+:106950004DB61EAC2F7B98D72F32B8DBFB709E67ED
+:10696000F5D65605272A995E12702F7C3D9BC75D90
+:10697000CB9F90C81F57D799F14C5C73E039AF0B90
+:10698000FAB31BFF46FAED27822E3F7AF8FD371344
+:1069900014BC4F72DC443DF2DED31752517FE5C781
+:1069A0005CCA403E9FA177ECACC273B718287F98B1
+:1069B000939928C743FFAC9FCF7B0ACBE50FAFD895
+:1069C000598579D01D468AA3D4FDAD91140DC69B7F
+:1069D0006F34FFEC01C4DBC5A78DE447AF69BE2D62
+:1069E0009E8D21A76AB91FE8AFA431F652A391CAC0
+:1069F000971B2D4C81231E6C4C20F85F1B152AD948
+:106A000012CE5F6B44BC3ADE7CD910EF2BA0AF7284
+:106A100036C17CE06FDA4CF6C93980AF19B73B5B01
+:106A2000368B73CD80F13657F202C443CEE6D53DA6
+:106A3000E88AEA73787CF476DFA624F2A31F3EB7D7
+:106A4000BB0ADA17E794A4E078E3AE6B14E7BFD192
+:106A5000F57819E5F55B0CFC7CE2DC179F4E8BDFCB
+:106A60008979D7B774147FD7EF3AB77B33942B9FCC
+:106A700058AD0FE4F76F7ADE64B19F5BC9D57878C3
+:106A8000F8F672F5EB24929F1690AB8CBF5EAEEADF
+:106A90001F5E4FF87B28A764510EECFFA2CE9584B1
+:106AA000F27471E6F788CF5DC725C2BFAAC7D5F1DA
+:106AB00045E2BC351ACF13E40F0A3DFE25447E881B
+:106AC000DFD7BB3E4D437FF8CBCEA55F7BEE238D5A
+:106AD00078838E792D2395A1ED797A478A15CE9703
+:106AE000A7E17EF028FF55DCCFA9F7EDF88779E123
+:106AF0005A613F9DB0B1A818B47F92372C13EF397B
+:106B00007E78498BF117C4751F05FB97ECA3003BFA
+:106B10003EDE7E6F55D6E13C5ABFDE9D7D46C3BC4E
+:106B20000176FBCE8130E60D587724EE30224F43BC
+:106B30001CDA3589F402D20DEF657C5D335B10BE43
+:106B4000A4E774F41D81F88AE755989CE73FE7A510
+:106B5000AE2B99A86743CF5B77F40AF1476DE7E363
+:106B6000D7243AFFC24BDACC5B9FFFF57D573291B9
+:106B70007E977403791847F9F403994887BA635CE0
+:106B80009F7F5B3CA8F5559BF43CBF2759281E2CE2
+:106B900090AF521CEF3BC5E3F8BAAE3DA44F87BBA4
+:106BA000793EA55ED35B188FF98786733DA8CF86A3
+:106BB00013787C05F3DB116F7353841DD40E252DE0
+:106BC00006BDF6CA083FF0B8EE22CAAF1EE7F1D400
+:106BD000D27BA4CC70867EC5659467A82F5B97BCDA
+:106BE00011F9FCA27B226682D8DB99FF5347F9B7E3
+:106BF000D7C22D32F9AD501B40BF9173B865FE70FE
+:106C000086A9717A38B307F4ABD72B3FA1F8F834D3
+:106C1000BF27ABBF9DCB133BCAE5C9B9E1757D4228
+:106C2000C07CBB519E68DFDC7F5CF4DAFF905C7651
+:106C3000DBECDD2897E1A80B71BE8428B724897EA0
+:106C400079FE7B4073B788C78B646AAFEF94D92411
+:106C50001C931041F7F5456CAB16FDDD45CC339721
+:106C6000BF9319F8CD77A1BDF835391BDF6381FFDC
+:106C70004CF7C785618ED435E81F692481574FCE04
+:106C8000E2407B26DE79CC9525B2634393C2C94F9F
+:106C900059B8C4598AFB1DD10F5ADE0FE6213F8B2C
+:106CA000B98732F13E93798732F19E53ED77EF6BDE
+:106CB000E10D64179927E7DE8075C272B9DDFC1C0F
+:106CC000EF9F419FD48BFBCF02F9C6331847AD39F4
+:106CD000CEEF09FB35C91FE07B2D17E019E97A05D6
+:106CE000E86A47FBE360763BCACFAC896E949FFAB3
+:106CF0008312C3776B755D8616CCEBD4E906E29000
+:106D00009F3777FE418FFC5CDFF1BE5E9985E379AA
+:106D10001E08FC750DE2B75ED82F67E76D1F60DEB9
+:106D2000CD798A5B51A7F67D8AEB6BDA0F51FC5E59
+:106D3000CBBC14BFD7B605F3CB7002CFB387CA471D
+:106D400058AE42FA528517EEE07271AFCC1A28DEC7
+:106D50001779D38509F1E48FF8C7093F51BEF218BE
+:106D6000FA2F83D325AB04530D86B936A05FE44ACE
+:106D7000E3FECCE0EF5ECEA920BDE2CEF929BE8BCA
+:106D800011FEEEC24DDBB472C07E1676F33CE160BC
+:106D900018AB3C42F4764C413A446695987373497B
+:106DA000AE32E99D8F86E73543CFF1A4C8679EC612
+:106DB0003C4F867FDFC589895C8F3137F14F8F86E5
+:106DC000AFAFBE7B51C7AFC89582E2A53512CF4F9A
+:106DD0008DA757F01EA55CDCA3948B7B9472718FFA
+:106DE000522EEE51CAC53D4AB9B8472917F728E5D2
+:106DF000E21EA55CDCA3948B7B14AC3F8D5BA5F7F6
+:106E000070CFEF44FBD9833236D90FF7C784C093D4
+:106E100083FBF7C748C1F06489FAE7E43EBFD39526
+:106E200081794C8B906F2502FDAF8B269E5FEA8A9D
+:106E300070FC1DE2B97C61D33EFE1ED14EEF59F2CB
+:106E4000639696A27C0DC71A18EAA1865CC7BC5C43
+:106E5000A0FBA9530B52B7917E3459F19EBBFFBEE4
+:106E60003BA2282FF796CC6458725E7AF6861C8077
+:106E7000E79925E25BD013DF2951E3499867413751
+:106E8000BFCF28906BCB71FE35934CD9A87787B2D2
+:106E90001CC5B901FC583879552AFA413D3AE50339
+:106EA000CCA7BADED5318CA3D4FC9BDAAF276BDE3E
+:106EB000521CB7303D654316EA1B102ED46F763D49
+:106EC0006BC37DD935E15213E92B458BF2BF54F0EA
+:106ED000EF7C85FBC35EBDA28DC1B83D6C5EAC4B43
+:106EE000E1F755E5E2BEAA5CDC57217DDEC1BC19A5
+:106EF00094EF413D96BD508F65E87BAE67724A5670
+:106F0000E652BC3D9414F81E6C11CA15D73349C81B
+:106F1000CF3B05DF26083DD3935D524DFCCE3C347C
+:106F20004F8DC8BF5DD105DFE3A9E3FCE319957779
+:106F30007F87EB6716A5E7EF5DA73017BEA7BDFB00
+:106F4000D549944FF2B9352E5D14C020E3A8BFD8BF
+:106F5000AB3CBE65095C5EEE3E1C4FFD9A441ED400
+:106F600019D39B16837657C8950A1FF90B7FE7E361
+:106F7000CC0218CA63123F9FF3EEDEB468807D92A4
+:106F80004983F971670B6FEF1372E79C2EE613E7E5
+:106F900061464F12D263F0F8AB490F00BCC5ECADAF
+:106FA000E0FADE9B467A9A79D3F0BDD015C9731604
+:106FB000DFDBAE3A92B50CDFD75ED17976235C7316
+:106FC0002487C3D2A1B396C0F6899E247C8FBBEAE6
+:106FD00048F6327C9F7B65E2A1DDD1D60058F7CA26
+:106FE000596CD73F9AB32C1FE06283FB5423F2CD38
+:106FF000BF72FE321DECB880F8A9E9E2FEFAFC830C
+:107000001D575F417BDC1141F7F507729389DE4D17
+:107010005DFB9F407EF31DD2911C6C69FBC3EE5F4C
+:10702000513F03A5518A0D9E1C4CB934E4FDC77D28
+:10703000B86E71B8E70B84D7E7FD80F6513C81CB81
+:10704000F3C6BCF9CB503E7D1D077F89F2571C0566
+:107050008E2CEEE76513D1A7FAF0CC7CCC03F82296
+:107060007ACB70FEBADF1AACC8A7D587E3E7635EB8
+:10707000A02397E7A7AB6EDF9A84F65573F4A57D3E
+:10708000BFC23CE56F4D743F531FC3FDBB6AB939A6
+:107090006F35D16FCF3E7C37E27BC944F7A45530C2
+:1070A00007AE57B56F06E5D58FFDF9E332A44381EE
+:1070B000BC6B1FD67FB1D7A4413CF4E9ED51DF434F
+:1070C00039ECD3519C5925E0AAFE097C3FE10385A8
+:1070D00044BFD8AD49685FAB27FCC35DB8EF6279A8
+:1070E000EB6E8C73D87E03DD155C7A09F006E32E17
+:1070F000B5EAE895AAEFA5082DF2CB15696BD94E34
+:107100009CBF95F7BB62DA4AF874B5DEC6703DE8FD
+:10711000C7505F5D91B605D55F6ADD9F8971E8E56F
+:10712000DF16533CAAF2F9489CB1D710640F4913FB
+:10713000C489F71264665DCC0C76B64A80978F3CA2
+:10714000E7DBC9FCE32FB7E9BC7AC05195816DC07C
+:10715000F7C1AA3C5427FEB008CF57AD694E437F14
+:10716000A52A7BA00CE5E292891913A0DFDBC25EA1
+:1071700055B7AF5F8C7EEF78FBF98BB03F5F0A3974
+:10718000FCB2D3E40EBC1F0C2DFFD8C8947702DEEE
+:107190000DDFDF6020DF5D9DEF6DBDA716E3B3BAA5
+:1071A00018AE3FCE42FF36D0633784DE5BBE2EB8CA
+:1071B000FFB5DC18FE2E553F9086764F9DDF97ABCE
+:1071C000EAB58134D457A1E38A65A16F5E9648DFA2
+:1071D00054B74BE764C053B5D1E5C6F73BD5184C5F
+:1071E000F2736A6F4A7C5C429EC03B8C7D3C2F9957
+:1071F000CE5DDD66B29B605C4DD84024FA43B5118C
+:107200000391E8E7F88ECAAC45902B364ED067BAAA
+:10721000205940DEB1CAA3B39B32C7A033FA4DF860
+:107220003E07FF1BD6DF95379DD6ABEC0CA7F59834
+:1072300065200FF9B47257F0383C972540FE7C9DCD
+:107240007BE202E3F164B1EF41E91CC9C9E09F3F71
+:107250004A42BA576BD806BC47BC2CF1EF1E00A6B9
+:10726000EF1E2E8BFBC8EA3F99C3905F2E7F594BD0
+:1072700072EB930648AFBD7BA484F4814F37407A0C
+:10728000ED44DEBDA4C77CD10365A8A7DE3D52C195
+:10729000DB270D9429D0DE8630B64F6564EFFF2BD7
+:1072A000CF49FAA358E6EF1BD81E9D85E78136F536
+:1072B00037525CA15302E3EE3FE6A9F7367AFFB9F5
+:1072C00065BFDCF89872B01DE5B0D24CF91CF09F98
+:1072D000DA5E413F6F699C15F3E295388EF3813E8B
+:1072E000F0FE2F36E67A05D2675994A3202F17EFC8
+:1072F0001907287E00AE263FBDEE77068A23077564
+:1073000043FB504F65463916E6017FD5EA7B37A22D
+:107310004B7F5537D083F77E8B64AE8FD87ECE57A8
+:10732000BE8C3DFC3B09717FB854E01FEC166B46E8
+:10733000BE90387DDFE83CFC0EEA155F6F0AE9E39A
+:1073400050B9B9D4F95424EA873360C75D0171FE9E
+:107350009915FBE99E7E09BECB80F2810DC1FC3000
+:107360007CE3A714EFB12702EA910FB707C3A17C12
+:1073700084FCE80DD23B2E92A76773B91F5633BF2A
+:10738000B70EF13002DF0DB01C009F088143FAB345
+:1073900012EE273C8BFF8D789CEAEDA7F8FC207F4E
+:1073A00017DB04F68BE08E70BA37D61C04FB14CBC7
+:1073B000ED13DA859AC85ECA4BF93A0C743FF2684D
+:1073C000D7A7F49E11F890F22F355DAFC661DC7E31
+:1073D00000E3845CB28371F44EA5A32B0EE30DB5DC
+:1073E000BE56E34913EFF1C94F57EB9DB2370DF786
+:1073F0005F23F56662FB01B1EF5A0DC032C262DF56
+:10740000129777D625933E0FA5DB0EC1AFA017329A
+:10741000E99DC5519E1750F54095D02727B03E8372
+:10742000CBBD45BD5792F0BD5CF898FA213E4FE8C0
+:1074300037D640799BED797CDFEA789A97E795A873
+:10744000BDEED895CCE919384E19790739A2875283
+:10745000FC7A05E53F81E4FF515D1C9CAB7AB76483
+:107460006D423D55BABE10BAB355DAD585942F1387
+:10747000EF3F43F715CA4756D80BE9494D74416CA5
+:10748000C07C97215C4FC8223D43EFE81F8C7DB242
+:1074900010F3133F2BDD46FC3C626F02E51CCFB3BB
+:1074A0008BEB71149B9B9AD17CBCAAA17963FC18CD
+:1074B000FB08DD6795A3B9304E195DAFEEF7B24911
+:1074C000DDDF7CDDC4403C2C595F3811CA55C6BF96
+:1074D000160FFCBC97BB0C5EB4AB55A5AB37468D05
+:1074E000C137A3ECC1AE00FB351DE9EBA67B8DF1E6
+:1074F000F61F5AD64ADE7ECC133190AB56922F90AF
+:107500009700BB30272F24DF50B9621AC69DCCB13B
+:10751000621ADA1990AB32EB1871257E59A2A1B725
+:107520001B2E2A43F7733E8FE749E7E47179E9B6EA
+:10753000D97DA837C7FBDEE2BFC53EC6FBDE2251C0
+:1075400033FC1ECA5B625C8482F740050BC279BFC4
+:10755000E3260BE66D068F5FA7BCEEE063E625FC35
+:10756000BEC0CC26417B4FC2AC96403BB275365F65
+:10757000273C87FB2DF5E9BAAFCF0B65448CE4853A
+:10758000C86FC808A77B125FE7E764B706BB732D17
+:10759000789FE1EB85E810E4A9FECFFF1D87F6D5C3
+:1075A000D7FD09BD07F3DDF894DE896D16EFF44EC3
+:1075B000748A7756BD4A047D1757F47121F6DB2291
+:1075C0004A7F7E80E789D5528DFF03E2DFC9B3C7CA
+:1075D0008E7F631CE6C0BC80123F561E25302F9064
+:1075E000AAE579012C312F909ACAF30208635E0054
+:1075F0004BCC0B603DE60510C6BC00C29817401886
+:10760000F30258625E00EBBF10DF3F0C8262E2F9CA
+:107610004A33E9F5B5F8BE1DF0B7F638BF775ADB47
+:107620002AD3FD2D7EFF80F66DD4BB9976F16EC610
+:10763000B38DEEF1EA3B642B92A85E377412F338F7
+:10764000F58724EB7AD42B8D4B68FDCDDDB91F94E3
+:10765000627DABCEAA51888F381D9B257AA75FDD4E
+:10766000DD4A79A7FCF8E37AAA6F9318E649EF356B
+:10767000F038D729436D16DD83921FEC34F452FCA9
+:1076800051734052CA03DF69CCB9467A40BD4FAE50
+:10769000E04DCCE93129E563BC031979772EDE4D45
+:1076A00057E03D33BE17976FD0BB7E2704A41390DD
+:1076B0000F77F0F7CF16F847F21EF2AEA9BAFBD05B
+:1076C000467C0F157ADF3CF23D5DC8BD73D96C7105
+:1076D000AF6CE3DF57143D5D7EB003D61BDE6A203E
+:1076E0007FA321D7F120F2D1499D9DF223278F9BC3
+:1076F000282E3ABFEDB6A0FCC85096A37A36E59B7B
+:10770000A650BE628D4E227BBCA028251EF1B8E09B
+:10771000948EEC4E4F56492DF65B334BA17C548131
+:1077200081FD82E611EFA5547A1434496E0DC02B09
+:107730009895DED92F073461BE725067DE84EF9AC8
+:107740009633FECE41E59B35DB24E21B4C10203EF8
+:10775000CB043E9777FFFE3ABE635869E07E6BA28A
+:1077600086DF5F276EE1EF191E640E3DDAD955C83A
+:107770005D32D9C7DF0D40BD237C4A12F7CB957827
+:107780009C7FC5691DBDB72D88FF719A83EC743E3F
+:10779000BD6390BCCBE49B778C2F3FA1EF184EEAE2
+:1077A000B85E013C523CD4837C4979190795A71BEC
+:1077B0002BA9AC13DF438C7EFF3F7416E3C4C4F8DF
+:1077C000082BEAB971BF770BFBFAEFBD768AF76B2E
+:1077D000899ABE6C05F1F127B315F1A1BE13ECB681
+:1077E0009534239DEC91CC65A1EFC14003025E0B63
+:1077F000F12012E6B53D76FCEE68E8B864A177C9E1
+:10780000A3F4E3B6C7F09D487DAA649114CC7F6FC2
+:107810002D88837D174E4FA67DD777F2FC286128EF
+:107820000EF3E79C5E91598EC3B373FDF5C5426EAE
+:107830007CD09FF3C977DDC86FDF206FBA17FBBB21
+:107840009889BEA7A63FD84FF11D53297FAAF2CD34
+:10785000705B7C0BF2CDEF67F338B2B4F47D1DDAC8
+:10786000FF9E6CC709DC4759F9B5C7E2E87C63E7BE
+:10787000AFD477EAA1F9AB40FDF9FFF13EFD9DC61B
+:10788000062ADF6B5C47656FA38BDA03F4FF7F8EFC
+:10789000A3FF43F39FE7B05F68FE93199528B29F5B
+:1078A00020DF3CDF1C92EF2C9AF0C026C0DF82ED77
+:1078B0007A2B56A9F94F7C3FBCD64CFAE0F2EC315A
+:1078C000F39E2ADECC94271D66A62CC4FFFCF4147C
+:1078D000AD06DABF107450F38E281F783E940F2C3B
+:1078E000513EB45ABF7CBCA00711CEE176DE45768E
+:1078F000DE4474DDB81EF407C02B9925487F5C0D6B
+:10790000D11F1070DC47DF55751B18E609D5779439
+:10791000F3A1F82A6B0C7DE2E1FA646A98E725FA94
+:10792000DEBF2E8CDEE79E14EFE14E6EE6EFE1CA7D
+:107930005909AD3B865E89447AAC9C3074F679E88F
+:10794000BFF2D766F257364EAAC8FB5BF4CAE06CAA
+:107950008E8F67F17705B45FF7BB024F48781FBA87
+:10796000E67E66433AABBF2B102FEEB3BFC5EF0ADE
+:10797000DC3667E237FF5D81CC39F1A581BF2B9002
+:10798000D93989C3EAEF0AB0F8D2717E57207B4E0D
+:10799000EEE8DF15983D87C739E3FDAE00F8937335
+:1079A000707F3A9BFD4E2C13C53E43BFA73D2DEE85
+:1079B000EF7A348E522C0B235D5AAAD7B873B07C61
+:1079C0005BE3F939D6033FE7E33E0A9FB2DD9E0E43
+:1079D00070A2C1437AB227CB5E80F583367B21AE9D
+:1079E000139A3747DA627C0FFB5984EDA1EFAE544E
+:1079F0007AAE98C3F9FE0151CE6D1AFB7BF207E611
+:107A0000F0EFD56EB56FD8EF7DB82F75FF6CEB8AB0
+:107A10001C92A72CFB32B1DF522C993926E8FBD4FB
+:107A2000D17CE612FBE2FC05FAACF83CF707A94C66
+:107A3000D3BAA3D17F9CFC883B1AF73BB979C884A1
+:107A4000DF41BCE81A32A17D7FF1E12113D6BF6886
+:107A5000E7EF9543E77F710EFF4E206DEE108D9F8F
+:107A600006FFDD4BFEF95034FA4F6995E737D27DBA
+:107A7000CB8199645FA609FB32ED91E99D03C06F4C
+:107A8000D39E8BA2FB6C961F4BEDD5462EA7D58FB0
+:107A9000941FE950E8BBADE2F301FECE4C37EC3B5E
+:107AA000C8FFD20EF3779700239E0EE808469E4546
+:107AB000FFCAC9F8BBCBC9426FA09F560A7AC15909
+:107AC000F9E675BAF7C7F1381FDED122FF75EA86ED
+:107AD000C5F769168C43572D59DF4371E18E917AB2
+:107AE00011671EDA887133F86F41F5D5E5AFF7A05D
+:107AF000BDA939105CEF6CB846F12BF86F41F5F772
+:107B0000FFFC9C9EFF7E41703DD07707F29B4ADFD1
+:107B1000933ACF4C8CF34E3AC3ACFCFDBE877EAF9C
+:107B2000A4457CFFBCE79FE7E7F0F7A29CDE30DED0
+:107B3000FDCDF8A389FABBE6B37494875B95AA5E82
+:107B40001AF9FD133D73517E6F5104E99D7A115767
+:107B5000D5955BC8CE27D619497F15C8615684478D
+:107B60007EFFA448167ACA43F2DF775734E5F1E87E
+:107B70000008C7CCA27B9FB8260E0F4D34907E28FC
+:107B8000D094D4EE87F24D4DF077EC2FA07E90513B
+:107B90007E793EB55EEFE1DF896B955C8C739B244B
+:107BA000FB73F8DD639324F2885566BA2F18C4FC82
+:107BB000229C677BB4FBB90A5867FB3D19E41F0F91
+:107BC00032AE4F5D4BF8BDD5F6E892D2D5D8BEF4B3
+:107BD000766A3FF297942773D07FAA0AB3A2FFB4C4
+:107BE000DDC6FDEBED8BD3A9FD98A4ACC773BB1E1E
+:107BF00061B4CEF6C5FCDCDB9F9C2ABEBF709B50F7
+:107C00009EB737DB27E17DD47C8BE30CD26BB2B817
+:107C10008FDB9E0CF5503E23952C7D10E799C5F720
+:107C20005B6753885E2797DEFEE43E85CC8817EFBE
+:107C300085EA1745501CFCBF93011353F046000022
+:107C4000000000000000000005001500000000001A
+:00000001FF
diff --git a/firmware/bnx2x-e1h-4.8.53.0.fw.ihex b/firmware/bnx2x-e1h-4.8.53.0.fw.ihex
deleted file mode 100644
index 48d7612..0000000
--- a/firmware/bnx2x-e1h-4.8.53.0.fw.ihex
+++ /dev/null
@@ -1,12028 +0,0 @@
-:10000000000039D8000000600000063000003A40CF
-:100010000000191C000040780000009C0000599866
-:10002000000082E400005A38000000D40000DD2007
-:100030000000C7CC0000DDF8000000780001A5C872
-:10004000000056980001A648000000C00001FCE82E
-:100050000000F1D40001FDB0000000040002EF88B0
-:10006000020400480000000F020400540000004594
-:1000700002040058000000840204005C0000000636
-:100080000204007000000004020400780000000078
-:100090000204007C121700000204008022170000F6
-:1000A00002040084321700000604008800000005E6
-:1000B0000204009C12150000020400A0221500009A
-:1000C000020400A432150000060400A80000000489
-:1000D000020400B802100000020400BC001000007E
-:1000E000020400C010100000020400C42010000030
-:1000F000020400C830100000020400CC40100000D0
-:10010000060400D000000003020400DC0010000020
-:10011000020400E012140000020400E422140000B3
-:10012000020400E832140000020400EC4214000053
-:10013000060400F000000003010401240000000098
-:1001400001040128000000000104012C000000004F
-:100150000104013000000000020401D00000890603
-:1001600002040004000000FF02040008000000FF79
-:100170000204000C000000FF02040010000000FF59
-:1001800002040014000000FF02040018000000FF39
-:100190000204001C000000FF02040020000000FF19
-:1001A000020400240000003E0204002800000000B9
-:1001B0000204002C0000003F020400300000003F59
-:1001C000020400340000003F020400380000003F39
-:1001D0000204003C0000003F020400400000003F19
-:1001E000020400440000003F020404CC00000001AF
-:1001F00002042008000002110204200C000002008A
-:10020000020420100000020402042014000002195D
-:100210000204201C0000FFFF020420200000FFFF5A
-:10022000020420240000FFFF020420280000FFFF3A
-:1002300002042038000000200204203C00000000DE
-:100240000204204000000034020420440000003575
-:10025000060420480000001C020420B80000000131
-:10026000060420BC0000005F0204223807FFFFFFE5
-:100270000204223C0000003F0204224007FFFFFF6F
-:10028000020422440000000F010422480000000084
-:100290000104224C00000000010422500000000074
-:1002A0000104225400000000010422580000000054
-:1002B0000104225C00000000010422600000000034
-:1002C0000104226400000000010422680000000014
-:1002D0000104226C000000000104227000000000F4
-:1002E00001042274000000000104227800000000D4
-:1002F0000104227C000000000C042000000003E840
-:100300000A042000000000010B0420000000000A85
-:1003100002050044000000200205004800000032F1
-:10032000020500900215002002050094021500202D
-:1003300002050098000000300205009C0810000033
-:10034000020500A000000033020500A400000030F8
-:10035000020500A800000031020500AC0000000208
-:10036000020500B000000005020500B40000000610
-:10037000020500B800000002020500BC00000002F7
-:10038000020500C000000000020500C400000005D6
-:10039000020500C800000002020500CC00000002B7
-:1003A000020500D000000002020500D40000000198
-:1003B00002050114000000010205011C00000001FB
-:1003C00002050120000000020205020400000001F5
-:1003D0000205020C0000004002050210000000406F
-:1003E0000205021C0000002002050220000000138C
-:1003F0000205022400000020060502400000000A59
-:1004000004050280002000000205005000000007E3
-:100410000205005400000007020500580000000813
-:100420000205005C000000080205006000000001F9
-:100430000605006400000003020500D80000000665
-:100440000205000400000001020500080000000190
-:100450000205000C00000001020500100000000170
-:100460000205001400000001020500180000000150
-:100470000205001C00000001020500200000000130
-:100480000205002400000001020500280000000110
-:100490000205002C000000010205003000000001F0
-:1004A00002050034000000010205003800000001D0
-:1004B0000205003C000000010205004000000001B0
-:1004C000020500E00000000D020500E80000000742
-:1004D000020500F000000007020500F80000000718
-:1004E000020500E40000002D020500EC00000027DA
-:1004F000020500F400000027020500FC00000027B0
-:10050000020500E00000001D020500E800000017E1
-:10051000020500F000000017020500F800000017B7
-:10052000020500E40000003D020500EC0000003779
-:10053000020500F400000037020500FC000000374F
-:10054000020500E00000004D020500E80000004741
-:10055000020500F000000047020500F80000004717
-:10056000020500E40000006D020500EC00000067D9
-:10057000020500F400000067020500FC00000067AF
-:10058000020500E00000005D020500E800000057E1
-:10059000020500F000000057020500F800000057B7
-:1005A000020500E40000007D020500EC0000007779
-:1005B000020500F400000077020500FC000000774F
-:1005C0000406100002000020020600DC000000010A
-:1005D000010600D80000000004060200000302200B
-:1005E000020600DC00000000010600B80000000068
-:1005F000010600C800000000010600BC0000000069
-:10060000010600CC0000000007180400009B000059
-:1006100008180798000D0223071C0000325E000036
-:10062000071C800035960C98071D00001AEA19FE79
-:10063000081D43D057860225011800000000000065
-:10064000011800040000000001180008000000006C
-:100650000118000C0000000001180010000000004C
-:100660000118001400000000021800200000000122
-:1006700002180024000000020218002800000003F5
-:100680000218002C000000000218003000000004D6
-:1006900002180034000000010218003800000000B9
-:1006A0000218003C00000001021800400000000495
-:1006B0000218004400000000021800480000000179
-:1006C0000218004C00000003021800500000000057
-:1006D0000218005400000001021800580000000435
-:1006E0000218005C00000000021800600000000119
-:1006F00002180064000000030218006800000000F7
-:100700000218006C000000010218007000000004D4
-:1007100002180074000000000218007800000004B5
-:100720000218007C00000003061800800000000290
-:10073000021800A400003FFF021800A8000003FFF9
-:100740000218022400000000021802340000000019
-:100750000218024C00000000021802E4000000FF32
-:100760000618100000000400021B8BC000000001EE
-:10077000021B800000000034021B804000000018B3
-:10078000021B80800000000C021B80C000000020C3
-:100790000C1B83000007A1200A1B83000000013806
-:1007A0000B1B830000001388021B83C0000001F4B0
-:1007B000021B1480000000010A1B148000000000CE
-:1007C000061A1000000002B3041A1ACC0001022716
-:1007D000061AA020000000C8061AA00000000002AF
-:1007E000021A1AD000000000061A1AD800000004ED
-:1007F000061A367800000006061A3670000000025D
-:10080000061A500000000002061A500800000004FA
-:10081000061A501800000004061A502800000004B0
-:10082000061A503800000004061A50480000000460
-:10083000061A505800000004061A50680000000410
-:10084000061A507800000002061A4000000000025C
-:10085000061A400800000002041A62C000200228A4
-:10086000061A20000000016C061AB00000000028E3
-:10087000061AB1400000000C061A32C00000001237
-:10088000061A335000000064061A810800000002B6
-:10089000061A25B00000016C061AB0A0000000285E
-:1008A000061AB1700000000C061A3308000000128E
-:1008B000061A34E000000064061A811000000002ED
-:1008C000021A2B6000000000061A3000000000022F
-:1008D000041A300800050248061A301C0000000700
-:1008E000061A31C000000008061A5000000000027D
-:1008F000061A508000000012061A40000000000294
-:10090000021A2B6400000000061A303800000002B2
-:10091000041A30400005024D061A3054000000074A
-:10092000061A31E000000008061A5010000000020C
-:10093000061A50C800000012061A40080000000203
-:10094000021A2B6800000000061A30700000000236
-:10095000041A307800050252061A308C0000000795
-:10096000061A320000000008061A5020000000029B
-:10097000061A511000000012041A4010000202571B
-:10098000021A2B6C00000000061A30A800000002BA
-:10099000041A30B000050259061A30C400000007DE
-:1009A000061A322000000008061A5030000000022B
-:1009B000061A515800000012041A40180002025E84
-:1009C000021A2B7000000000061A30E0000000023E
-:1009D000041A30E800050260061A30FC0000000727
-:1009E000061A324000000008061A504000000002BB
-:1009F000061A51A000000012041A402000020265ED
-:100A0000021A2B7400000000061A311800000002C0
-:100A1000041A312000050267061A3134000000076D
-:100A2000061A326000000008061A5050000000024A
-:100A3000061A51E800000012041A40280002026C55
-:100A4000021A2B7800000000061A31500000000244
-:100A5000041A31580005026E061A316C00000007B6
-:100A6000061A328000000008061A506000000002DA
-:100A7000061A523000000012041A403000020273BD
-:100A8000021A2B7C00000000061A318800000002C8
-:100A9000041A319000050275061A31A400000007FF
-:100AA000061A32A000000008061A5070000000026A
-:100AB000061A527800000012041A40380002027A26
-:100AC0000200A294071D29110200A2980000000054
-:100AD0000200A29C009C04240200A2A000000000CE
-:100AE0000200A2A4000002090200A270000000009F
-:100AF0000200A274000000000200A27000000000CA
-:100B00000200A274000000000200A27000000000B9
-:100B10000200A274000000000200A27000000000A9
-:100B20000200A27400000000020100B400000001F5
-:100B3000020100B800000001020100DC0000000119
-:100B40000201010000000001020101040000000197
-:100B50000201007C00300000020100840000002837
-:100B60000201008C000000000201013000000004BE
-:100B70000201025C000000010201032800000000E5
-:100B800002016080000000010201055400000030F5
-:100B9000020100C400000001020100CC00000001BD
-:100BA000020100F800000001020100F00000000155
-:100BB00002010080003000000201008800000028CF
-:100BC0000201009000000000020101340000000456
-:100BD000020102DC000000010201032C0000000001
-:100BE0000201608400000001020105640000003081
-:100BF000020100C800000001020100D00000000155
-:100C0000020100FC00000001020100F400000001EC
-:100C1000020C100000000020020C2008000002114D
-:100C2000020C200C00000200020C20100000020444
-:100C3000020C201C0000FFFF020C20200000FFFF20
-:100C4000020C20240000FFFF020C20280000FFFF00
-:100C5000020C2038000000C6020C203C00000000FE
-:100C6000020C204000000034020C2044000000353B
-:100C7000060C20480000001C020C20B800000001F7
-:100C8000060C20BC0000005F020C223807FFFFFFAB
-:100C9000020C223C0000003F020C224007FFFFFF35
-:100CA000020C22440000000F010C2248000000004A
-:100CB000010C224C00000000010C2250000000003A
-:100CC000010C225400000000010C2258000000001A
-:100CD000010C225C00000000010C226000000000FA
-:100CE000010C226400000000010C226800000000DA
-:100CF000010C226C00000000010C227000000000BA
-:100D0000010C227400000000010C22780000000099
-:100D1000010C227C000000000C0C2000000003E805
-:100D20000A0C2000000000010B0C20000000000A4B
-:100D3000020C400800000411020C400C00000400EA
-:100D4000020C401000000404020C401400000421B6
-:100D5000020C401C0000FFFF020C40200000FFFFBF
-:100D6000020C40240000FFFF020C40280000FFFF9F
-:100D7000020C403800000046020C403C0000000518
-:100D8000020C404000000034020C404400000035DA
-:100D9000020C404800000007060C404C0000005BBD
-:100DA000020C41B800000001060C41BC0000000329
-:100DB000020C41C800000001060C41CC0000001BE1
-:100DC000020C423807FFFFFF020C423C0000003FCC
-:100DD000020C424007FFFFFF020C42440000000FDC
-:100DE000010C424800000000010C424C00000000D1
-:100DF000010C425000000000010C425400000000B1
-:100E0000010C425800000000010C425C0000000090
-:100E1000010C426000000000010C42640000000070
-:100E2000010C426800000000010C426C0000000050
-:100E3000010C427000000000010C42740000000030
-:100E4000010C427800000000010C427C0000000010
-:100E5000010C4280000000000C0C4000000003E880
-:100E60000A0C4000000000010B0C40000000000ACA
-:100E7000020D004400000032020D008C021500201B
-:100E8000020D009002150020020D009408100000D1
-:100E9000020D009800000033020D009C00000002CB
-:100EA000020D00A000000000020D00A400000005DB
-:100EB000020D00A800000005060D00AC00000002B5
-:100EC000020D00B400000002020D00B80000000393
-:100ED000020D00BC00000002020D00C00000000175
-:100EE000020D00C800000002020D00CC000000024C
-:100EF000020D010800000001020D015C000000016C
-:100F0000020D016400000001020D016800000002F2
-:100F1000020D020400000001020D020C000000207E
-:100F2000020D021000000040020D021400000040FB
-:100F3000020D022000000003020D02240000001830
-:100F4000060D028000000012040D03000024027C44
-:100F5000020D004C00000001020D005000000002D4
-:100F6000020D005400000008020D005800000008A7
-:100F7000060D005C00000004020D00C40000000427
-:100F8000020D000400000001020D00080000000135
-:100F9000020D000C00000001020D00100000000115
-:100FA000020D001400000001020D001800000001F5
-:100FB000020D001C00000001020D002000000001D5
-:100FC000020D002400000001020D002800000001B5
-:100FD000020D002C00000001020D00300000000195
-:100FE000020D003400000001020D00380000000175
-:100FF000020D003C00000001020D01140000000978
-:10100000020D011C0000000A020D0124000000076F
-:10101000020D012C00000007020D01340000000C3D
-:10102000020D013C0000000B020D0144000000070E
-:10103000020D011800000029020D01200000002A05
-:10104000020D012800000027020D013000000027DA
-:10105000020D01380000002C020D01400000002BA1
-:10106000020D014800000027020D011400000019C4
-:10107000020D011C0000001A020D012400000017DF
-:10108000020D012C00000017020D01340000001CAD
-:10109000020D013C0000001B020D0144000000177E
-:1010A000020D011800000039020D01200000003A75
-:1010B000020D012800000037020D0130000000374A
-:1010C000020D01380000003C020D01400000003B11
-:1010D000020D014800000037020D01140000004914
-:1010E000020D011C0000004A020D0124000000470F
-:1010F000020D012C00000047020D01340000004CDD
-:10110000020D013C0000004B020D014400000047AD
-:10111000020D011800000069020D01200000006AA4
-:10112000020D012800000067020D01300000006779
-:10113000020D01380000006C020D01400000006B40
-:10114000020D014800000067020D01140000005963
-:10115000020D011C0000005A020D0124000000577E
-:10116000020D012C00000057020D01340000005C4C
-:10117000020D013C0000005B020D0144000000571D
-:10118000020D011800000079020D01200000007A14
-:10119000020D012800000077020D013000000077E9
-:1011A000020D01380000007C020D01400000007BB0
-:1011B000020D014800000077020E004C00000032D2
-:1011C000020E009402150020020E00980215002065
-:1011D000020E009C00000030020E00A0081000006B
-:1011E000020E00A400000033020E00A80000003030
-:1011F000020E00AC00000031020E00B00000000240
-:10120000020E00B400000004020E00B8000000004E
-:10121000020E00BC00000002020E00C0000000022E
-:10122000020E00C400000000020E00C80000000210
-:10123000020E00CC00000007020E00D000000002E9
-:10124000020E00D400000002020E00D800000001CF
-:10125000020E00E400000001020E01440000000143
-:10126000020E014C00000001020E015000000002BD
-:10127000020E020400000001020E020C00000040F9
-:10128000020E021000000040020E021C00000004CA
-:10129000020E022000000020020E02240000000EB8
-:1012A000020E02280000001B060E030000000012C0
-:1012B000040E0280001B02A0020E00540000001069
-:1012C000020E005800000007020E005C0000000F34
-:1012D000020E006000000010020E00640000000B0F
-:1012E000060E006800000003020E00DC0000000390
-:1012F000020E000400000001020E000800000001C0
-:10130000020E000C00000001020E0010000000019F
-:10131000020E001400000001020E0018000000017F
-:10132000020E001C00000001020E0020000000015F
-:10133000020E002400000001020E0028000000013F
-:10134000020E002C00000001020E0030000000011F
-:10135000020E003400000001020E003800000001FF
-:10136000020E003C00000001020E004000000001DF
-:10137000020E004400000001020E01100000000FE8
-:10138000020E01180000000E020E012000000000F5
-:10139000020E012800000000020E01140000002FC0
-:1013A000020E011C0000002E020E012400000000AD
-:1013B000020E012C00000000020E01100000001FB0
-:1013C000020E01180000001E020E012000000000A5
-:1013D000020E012800000000020E01140000003F70
-:1013E000020E011C0000003E020E0124000000005D
-:1013F000020E012C00000000020E01100000004F40
-:10140000020E01180000004E020E01200000000034
-:10141000020E012800000000020E01140000006FFF
-:10142000020E011C0000006E020E012400000000EC
-:10143000020E012C00000000020E01100000005FEF
-:10144000020E01180000005E020E012000000000E4
-:10145000020E012800000000020E01140000007FAF
-:10146000020E011C0000007E020E0124000000009C
-:10147000020E012C000000000730040000D2000022
-:10148000083007A8000B02BB0734000031B600008B
-:101490000734800036500C6E0735000037591A03A8
-:1014A00007358000286127DA0835FF40401802BD63
-:1014B00001300000000000000130000400000000C6
-:1014C00001300008000000000130000C00000000A6
-:1014D0000130001000000000013000140000000086
-:1014E0000230002000000001023000240000000251
-:1014F00002300028000000030230002C0000000031
-:10150000023000300000000402300034000000010E
-:1015100002300038000000000230003C00000001F2
-:1015200002300040000000040230004400000000CF
-:1015300002300048000000010230004C00000003AF
-:101540000230005000000000023000540000000192
-:1015500002300058000000040230005C000000006F
-:10156000023000600000000102300064000000034F
-:1015700002300068000000000230006C0000000132
-:10158000023000700000000402300074000000000F
-:1015900002300078000000040230007C00000003EC
-:1015A0000630008000000002023000A400003FFF6F
-:1015B000023000A8000003FF0230022400000000F7
-:1015C00002300234000000000230024C0000000033
-:1015D000023002E40000FFFF063020000000080097
-:1015E00002338BC000000001023380000000001AAB
-:1015F000023380400000004E023380800000001063
-:10160000023380C0000000200C3383000007A120BB
-:101610000A338300000001380B3383000000138875
-:10162000023383C0000001F40C3383801DCD6500BC
-:101630000A3383800004C4B40B338380004C4B40D6
-:101640000A331480000000000233148000000001FF
-:10165000063220000000010206328980000000C826
-:1016600006328960000000020632322800000004C1
-:10167000063232000000000904323224000102BFA9
-:1016800006323180000000200632500000000400C5
-:10169000063240000000000204324008000102C08F
-:1016A0000632400C0000000306326B6800000002A6
-:1016B00004326B70000202C106326B10000000029F
-:1016C000043274C0000202C30233080001000000AB
-:1016D00004330C00001002C50233080000000000B3
-:1016E00004330C40001002D506329000000000A028
-:1016F0000632950000000040063297000000003CD2
-:1017000006322450000000B406322AD00000000245
-:101710000632308000000020063280000000012CDC
-:101720000232323800000000063250000000002073
-:101730000632510000000020063252000000002056
-:101740000632530000000020063254000000002042
-:10175000063255000000002006325600000000202E
-:10176000063257000000002006325800000000201A
-:10177000063259000000002006325A000000002006
-:1017800006325B000000002006325C0000000020F2
-:1017900006325D000000002006325E0000000020DE
-:1017A00006325F000000002006326B780000005215
-:1017B00006326E080000000C06329280000000A085
-:1017C0000632960000000040063297F00000003C10
-:1017D00006322720000000B406322AD8000000029A
-:1017E0000632310000000020063284B00000012CD7
-:1017F0000232323C0000000006325080000000201F
-:101800000632518000000020063252800000002085
-:101810000632538000000020063254800000002071
-:10182000063255800000002006325680000000205D
-:101830000632578000000020063258800000002049
-:10184000063259800000002006325A800000002035
-:1018500006325B800000002006325C800000002021
-:1018600006325D800000002006325E80000000200D
-:1018700006325F800000002006326CC0000000527B
-:1018800006326E380000000C02322A3000000000E0
-:10189000063230000000000406324018000000024A
-:1018A00002322A340000000006323010000000042A
-:1018B000063240280000000202322A3800000000F0
-:1018C00006323020000000040632403800000002DA
-:1018D00002322A3C000000000632303000000004D2
-:1018E000063240480000000202322A400000000098
-:1018F000063230400000000406324058000000026A
-:1019000002322A4400000000063230500000000479
-:10191000063240680000000202322A48000000003F
-:1019200006323060000000040632407800000002F9
-:1019300002322A4C00000000063230700000000421
-:1019400006324088000000020720040000740000F6
-:1019500008200780001002E507240000322600005E
-:1019600007248000246E0C8A0824CBB064F002E7C0
-:101970000120000000000000012000040000000021
-:1019800001200008000000000120000C0000000001
-:1019900001200010000000000120001400000000E1
-:1019A00002200020000000010220002400000002AC
-:1019B00002200028000000030220002C000000008C
-:1019C000022000300000000402200034000000016A
-:1019D00002200038000000000220003C000000014E
-:1019E000022000400000000402200044000000002B
-:1019F00002200048000000010220004C000000030B
-:101A000002200050000000000220005400000001ED
-:101A100002200058000000040220005C00000000CA
-:101A200002200060000000010220006400000003AA
-:101A300002200068000000000220006C000000018D
-:101A4000022000700000000402200074000000006A
-:101A500002200078000000040220007C0000000347
-:101A60000620008000000002022000A400003FFFCA
-:101A7000022000A8000003FF022002240000000052
-:101A800002200234000000000220024C000000008E
-:101A9000022002E40000FFFF0620200000000800F2
-:101AA00002238BC000000001022380000000001010
-:101AB00002238040000000120223808000000030DA
-:101AC000022380C00000000E022383C0000001F446
-:101AD00002231480000000010A231480000000008B
-:101AE000062210000000004206227020000000C8FC
-:101AF0000622700000000002022211E8000000002F
-:101B000006223000000000C0062240700000008065
-:101B10000622528000000004062267000000010037
-:101B2000062290000000040004226B08002002E955
-:101B300002230800013FFFFF04230C0000100309EB
-:101B4000022308000000000004230C4000100319C9
-:101B500006228000000000A0062285000000004050
-:101B6000062287000000003C0622404000000006DC
-:101B700006228280000000A00622860000000040AD
-:101B8000062287F00000003C0622405800000006B4
-:101B9000022211480000000006223300000000026B
-:101BA00006226040000000300222114C00000000BC
-:101BB0000622330800000002062261000000003007
-:101BC0000222115000000000062233100000000223
-:101BD000062261C000000030022211540000000003
-:101BE0000622331800000002062262800000003046
-:101BF00002221158000000000622332000000002DB
-:101C000006226340000000300222115C0000000048
-:101C10000622332800000002062264000000003083
-:101C20000222116000000000062233300000000292
-:101C3000062264C00000003002221164000000008F
-:101C400006223338000000020622658000000030C2
-:101C50000216100000000020021700080000000219
-:101C60000217002C000000030217003C00000004D3
-:101C7000021700440000000802170048000000029C
-:101C80000217004C00000090021700500000009066
-:101C9000021700540080009002170058081400003A
-:101CA000021700600000008A021700640000008034
-:101CB00002170068000000900217006C000000800E
-:101CC000021700700000000602170078000007D01D
-:101CD0000217007C0000076C02170038007C10041B
-:101CE000021700040000000F061640240000000246
-:101CF000021640700000001C02164208000000019D
-:101D000002164210000000010216422000000001ED
-:101D100002164228000000010216423000000001B5
-:101D20000216423800000001021642600000000264
-:101D30000C16401C0003D0900A16401C0000009CAA
-:101D40000B16401C000009C40216403000000008B9
-:101D5000021640340000000C02164038000000104B
-:101D6000021640440000002002164000000000015E
-:101D7000021640D8000000010216400800000001D1
-:101D80000216400C00000001021640100000000185
-:101D90000216424000000000021642480000000007
-:101DA00006164270000000020216425000000000B9
-:101DB0000216425800000000061642800000000291
-:101DC00002166008000004240216600C00000410D3
-:101DD00002166010000004140216601C0000FFFFD1
-:101DE000021660200000FFFF021660240000FFFFC3
-:101DF000021660280000FFFF021660380000002075
-:101E00000216603C00000020021660400000003412
-:101E100002166044000000350216604800000023EE
-:101E20000216604C000000240216605000000025DD
-:101E300002166054000000260216605800000027B9
-:101E40000216605C00000029021660600000002A93
-:101E5000021660640000002B021660680000002C6F
-:101E60000216606C0000002D061660700000005223
-:101E7000021661B800000001061661BC0000001FD8
-:101E80000216623807FFFFFF0216623C0000003FA7
-:101E90000216624007FFFFFF021662440000000FB7
-:101EA00001166248000000000116624C00000000AC
-:101EB000011662500000000001166254000000008C
-:101EC00001166258000000000116625C000000006C
-:101ED000011662600000000001166264000000004C
-:101EE00001166268000000000116626C000000002C
-:101EF000011662700000000001166274000000000C
-:101F000001166278000000000116627C00000000EB
-:101F10000C166000000003E80A16600000000001D3
-:101F20000B1660000000000A021680400000000648
-:101F30000216804400000005021680480000000AD6
-:101F40000216804C000000050216805400000002BA
-:101F5000021680CC00000004021680D000000004AD
-:101F6000021680D400000004021680D8000000048D
-:101F7000021680DC00000004021680E0000000046D
-:101F8000021680E400000004021680E8000000044D
-:101F90000216880400000004021680300000007C55
-:101FA000021680340000003D021680380000003F19
-:101FB0000216803C0000009C021680F00000000722
-:101FC000061680F4000000050216880C01010101CC
-:101FD00002168108000000000216810C00000004B7
-:101FE0000216811000000004021681140000000295
-:101FF000021688100801200402168118000000054E
-:102000000216811C00000005021681200000000558
-:1020100002168124000000050216882C20081001F9
-:1020200002168128000000080216812C000000061C
-:102030000216813000000007021681340000000003
-:1020400002168830010101200616813800000004C4
-:1020500002168834010101010216814800000000C7
-:102060000216814C0000000402168150000000049A
-:10207000021681540000000202168838080120046C
-:1020800002168158000000050216815C0000000560
-:102090000216816000000005021681640000000540
-:1020A0000216883C20081001021681680000000812
-:1020B0000216816C00000006021681700000000705
-:1020C00002168174000000010216884001010120FF
-:1020D00002168178000000010216817C00000001D8
-:1020E00002168180000000010216818400000001B8
-:1020F00002168844010101010216818800000001D6
-:102100000216818C00000004021681900000000479
-:10211000021681940000000202168848080120047B
-:1021200002168198000000050216819C000000053F
-:10213000021681A000000005021681A4000000051F
-:102140000216881420081001021681A80000000859
-:10215000021681AC00000006021681B000000007E4
-:10216000021681B400000001021688180101012046
-:10217000021681B800000001021681BC00000001B7
-:10218000021681C000000001021681C40000000197
-:102190000216881C01010101021681C8000000011D
-:1021A000021681CC00000004021681D00000000459
-:1021B000021681D4000000020216882008012004C3
-:1021C000021681D800000005021681DC000000051F
-:1021D000021681E000000005021681E400000005FF
-:1021E0000216882420081001021681E80000000869
-:1021F000021681EC00000006021681F000000007C4
-:102200000216E40C000000000216882801010120DB
-:102210000616E410000000040216E00001010101AE
-:102220000216E420000000000216E424000000046E
-:102230000216E428000000040216E42C000000024C
-:102240000216E004080120040216E4300000000534
-:102250000216E434000000050216E4380000000510
-:102260000216E43C000000050216E00820081001F8
-:102270000216E440000000080216E44400000006D4
-:102280000216E448000000070216E44C00000000BB
-:102290000216E00C010101200616E45000000004C3
-:1022A0000216E010010101010216E46000000000C6
-:1022B0000216E464000000040216E4680000000452
-:1022C0000216E46C000000020216E014080120046B
-:1022D0000216E470000000050216E4740000000518
-:1022E0000216E478000000050216E47C00000005F8
-:1022F0000216E018200810010216E4800000000811
-:102300000216E484000000060216E48800000007BC
-:102310000216E48C000000010216E01C01010120FD
-:102320000216E490000000010216E494000000018F
-:102330000216E498000000010216E49C000000016F
-:102340000216E020010101010216E4A000000001D4
-:102350000216E4A4000000040216E4A80000000431
-:102360000216E4AC000000020216E024080120047A
-:102370000216E4B0000000050216E4B400000005F7
-:102380000216E4B8000000050216E4BC00000005D7
-:102390000216E028200810010216E4C00000000820
-:1023A0000216E4C4000000060216E4C8000000079C
-:1023B0000216E4CC000000010216E02C010101200D
-:1023C0000216E4D0000000010216E4D4000000016F
-:1023D0000216E4D8000000010216E4DC000000014F
-:1023E0000216E030010101010216E4E000000001E4
-:1023F0000216E4E4000000040216E4E80000000411
-:102400000216E4EC000000020216E0340801200489
-:102410000216E4F0000000050216E4F400000005D6
-:102420000216E4F8000000050216E4FC00000005B6
-:102430000216E038200810010216E500000000082E
-:102440000216E504000000060216E5080000000779
-:102450000216E03C0101012002168240003F003FCD
-:1024600002168244000000000216E524003F003FEF
-:102470000216E52800000000021682480000000055
-:102480000216824C003F003F0216E52C00000000BF
-:102490000216E530003F003F0216825001000100A5
-:1024A00002168254010001000216E5340100010009
-:1024B0000216E538010001000616825800000002ED
-:1024C0000216E53C000000000216E5400000000096
-:1024D0000216826000C000C00216826400C000C004
-:1024E0000216E54400C000C00216E54800C000C066
-:1024F000021682681E001E000216826C1E001E005C
-:102500000216E54C1E001E000216E5501E001E00BD
-:1025100002168270400040000216827440004000A3
-:102520000216E554400040000216E5584000400005
-:1025300002168278800080000216827C8000800073
-:102540000216E55C800080000216E56080008000D5
-:1025500002168280200020000216828420002000C3
-:102560000216E564200020000216E5682000200025
-:1025700006168288000000020216E56C00000000CA
-:102580000216E570000000000216829000000000B4
-:1025900002168294000000000216E574000000009C
-:1025A0000216E57800000000021682980000000084
-:1025B0000216829C000000000216E57C000000006C
-:1025C0000216E58000000000021682A00000000054
-:1025D000021682A400000001061682A80000000A6C
-:1025E000021681F400000C08021681F80000004079
-:1025F000021681FC0000010002168200000000208B
-:1026000002168204000000170216820800000080F3
-:102610000216820C00000200021682100000000068
-:102620000216821801FF01FF0216821401FF01FF4A
-:102630000216E51001FF01FF0216E50C01FF01FF84
-:102640000216823C00000013021680900000013F39
-:102650000216806000000140021680640000014004
-:10266000061680680000000202168070000000C09C
-:1026700006168074000000070216809C00000048C7
-:10268000021680A000000048061680A40000000288
-:10269000021680AC00000048061680B0000000075B
-:1026A000021682380000800002168234000025E401
-:1026B0000216809400007FFF0216822000070007A8
-:1026C0000216821C000700070216E5180007000723
-:1026D0000216E51400070007021682280000000019
-:1026E00002168224FFFFFFFF0216E5200000000013
-:1026F0000216E51CFFFFFFFF0216E6BC000000000B
-:102700000216E6C0000000020216E6C40000000146
-:102710000216E6C8000000030216E6CC0000000422
-:102720000216E6D0000000060216E6D400000005FE
-:102730000216E6D800000007021680EC000000FF39
-:1027400002140000000000010214000C000000014F
-:1027500002140040000000010214004400007FFF4A
-:102760000214000C00000000021400000000000031
-:102770000214006C000000000214000400000001BC
-:1027800002140030000000010214000400000000E8
-:102790000214005C000000000214000800000001A8
-:1027A00002140034000000010214000800000000C0
-:1027B0000214006000000000020200580000003215
-:1027C000020200A003150020020200A4031500204D
-:1027D000020200A801000030020200AC0810000054
-:1027E000020200B000000033020200B4000000301A
-:1027F000020200B800000031020200BC0000000329
-:10280000020200C000000006020200C40000000333
-:10281000020200C800000003020200CC0000000217
-:10282000020200D000000000020200D400000002FA
-:10283000020200DC00000000020200E000000006CE
-:10284000020200E400000004020200E800000002AE
-:10285000020200EC00000002020200F00000000191
-:10286000020200FC0000000602020120000000003D
-:102870000202013400000002020201B00000000167
-:102880000202020C0000000102020214000000011A
-:10289000020202180000000202020404000000010B
-:1028A0000202040C0000004002020410000000407C
-:1028B0000202041C000000040202042000000020A8
-:1028C000020204240000000202020428000000208A
-:1028D000060205000000001204020480001F032904
-:1028E000020200600000000F020200640000000706
-:1028F000020200680000000B0202006C0000000EE3
-:10290000020200700000000E0602007400000003C6
-:10291000020200F4000000040202000400000001B2
-:1029200002020008000000010202000C0000000189
-:102930000202001000000001020200140000000169
-:1029400002020018000000010202001C0000000149
-:102950000202002000000001020200240000000129
-:1029600002020028000000010202002C0000000109
-:1029700002020030000000010202003400000001E9
-:1029800002020038000000010202003C00000001C9
-:1029900002020040000000010202004400000001A9
-:1029A00002020048000000010202004C0000000189
-:1029B000020200500000000102020108000000C8ED
-:1029C0000202011800000002020201C4000000001F
-:1029D000020201CC00000000020201D4000000024B
-:1029E000020201DC00000002020201E4000000FF1C
-:1029F000020201EC000000FF0202010000000000E2
-:102A00000202010C000000C80202011C00000002CA
-:102A1000020201C800000000020201D00000000014
-:102A2000020201D800000002020201E000000002E0
-:102A3000020201E8000000FF020201F0000000FFB6
-:102A4000020201040000000002020108000000C8A8
-:102A50000202011800000002020201C4000000008E
-:102A6000020201CC00000000020201D400000002BA
-:102A7000020201DC00000002020201E4000000FF8B
-:102A8000020201EC000000FF020201000000000051
-:102A90000202010C000000C80202011C000000023A
-:102AA000020201C800000000020201D00000000084
-:102AB000020201D800000002020201E00000000250
-:102AC000020201E8000000FF020201F0000000FF26
-:102AD000020201040000000002020108000000C818
-:102AE0000202011800000002020201C400000000FE
-:102AF000020201CC00000000020201D4000000022A
-:102B0000020201DC00000002020201E4000000FFFA
-:102B1000020201EC000000FF0202010000000000C0
-:102B20000202010C000000C80202011C00000002A9
-:102B3000020201C800000000020201D000000000F3
-:102B4000020201D800000002020201E000000002BF
-:102B5000020201E8000000FF020201F0000000FF95
-:102B6000020201040000000002020108000000C887
-:102B70000202011800000002020201C4000000006D
-:102B8000020201CC00000000020201D40000000299
-:102B9000020201DC00000002020201E4000000FF6A
-:102BA000020201EC000000FF020201000000000030
-:102BB0000202010C000000C80202011C0000000219
-:102BC000020201C800000000020201D00000000063
-:102BD000020201D800000002020201E0000000022F
-:102BE000020201E8000000FF020201F0000000FF05
-:102BF00002020104000000000728040000BD0000DC
-:102C0000082807A8000B0348072C00003406000022
-:102C1000072C800037960D02072D00003BC31AE8F1
-:102C2000072D8000382629D9072E0000124537E3EA
-:102C3000082E22203BBC034A0128000000000000AF
-:102C40000128000400000000012800080000000026
-:102C50000128000C00000000012800100000000006
-:102C600001280014000000000228002000000001DC
-:102C700002280024000000020228002800000003AF
-:102C80000228002C00000000022800300000000490
-:102C90000228003400000001022800380000000073
-:102CA0000228003C0000000102280040000000044F
-:102CB0000228004400000000022800480000000133
-:102CC0000228004C00000003022800500000000011
-:102CD00002280054000000010228005800000004EF
-:102CE0000228005C000000000228006000000001D3
-:102CF00002280064000000030228006800000000B1
-:102D00000228006C0000000102280070000000048E
-:102D1000022800740000000002280078000000046F
-:102D20000228007C0000000306280080000000024A
-:102D3000022800A400003FFF022800A8000003FFB3
-:102D400002280224000000000228023400000000D3
-:102D50000228024C00000000022802E40000FFFFED
-:102D60000628200000000800022B8BC00000000194
-:102D7000022B800000000000022B804000000018A1
-:102D8000022B80800000000C022B80C00000006637
-:102D90000C2B83000007A1200A2B830000000138C0
-:102DA0000B2B830000001388022B83C0000001F46A
-:102DB0000C2B8340000001F40A2B8340000000002C
-:102DC0000B2B8340000000050A2B83800004C4B451
-:102DD0000C2B83801DCD65000A2B148000000000A1
-:102DE0000B2B8380004C4B40022B14800000000111
-:102DF000062A29C800000004042A29D80002034C2E
-:102E0000062A208000000048062A9020000000C802
-:102E1000062A900000000002062A21A80000008671
-:102E2000062A200000000020022A23C8000000001B
-:102E3000042A23D00002034E042A249800040350DD
-:102E4000022A2C2000000000022A2C1000000000A2
-:102E5000042A2C0800020354022A3010000000014A
-:102E6000062A404000000010042A400000100356CB
-:102E7000062A6AC000000002062A6B000000000457
-:102E8000042A840800020366022B080000000000E8
-:102E9000042B0C0000100368022B08000100000046
-:102EA000042B0C4000080378022B080002000000ED
-:102EB000042B0C6000080380062AC000000000FC00
-:102EC000062A24A800000014062A25480000002431
-:102ED000062A266800000024062A2788000000240D
-:102EE000062A28A800000024062AA00000000028C6
-:102EF000062AA1400000000C042A29E000020388F1
-:102F0000022A300000000001062A502000000002C2
-:102F1000062A503000000002062A5000000000027D
-:102F2000062A501000000002022A52080000000188
-:102F3000042A6AC80002038A062A6B1000000042B5
-:102F4000062A6D2000000004062AC3F0000000FCE1
-:102F5000062A24F800000014062A25D800000024C0
-:102F6000062A26F800000024062A2818000000245B
-:102F7000062A293800000024062AA0A00000002804
-:102F8000062AA1700000000C042A29E80002038C24
-:102F9000022A300400000001062A50280000000226
-:102FA000062A503800000002062A500800000002DD
-:102FB000062A501800000002022A520C00000001EC
-:102FC000042A6AD00002038E062A6C180000004210
-:102FD000062A6D3000000004022AC7E0000000004D
-:102FE000042A29F000100390062A50480000000E21
-:102FF000022AC7E400000000042A2A30001003A0BF
-:10300000062A50800000000E022AC7E800000000D7
-:10301000042A2A70001003B0062A50B80000000EDF
-:10302000022AC7EC00000000042A2AB0001003C0E6
-:10303000062A50F00000000E022AC7F0000000002F
-:10304000042A2AF0001003D0062A51280000000E9E
-:10305000022AC7F400000000042A2B30001003E00D
-:10306000062A51600000000E022AC7F80000000086
-:10307000042A2B70001003F0062A51980000000E5D
-:10308000022AC7FC00000000042A2BB00010040034
-:10309000062A51D00000000E0210100800000001A6
-:1030A0000210105000000001021010000003D000B8
-:1030B000021010040000003D091018000200041066
-:1030C0000910110000280610061011A000000018B9
-:1030D00006102400000000E00210201C0000000088
-:1030E0000210202000000001021020C00000000299
-:1030F000021020040000000102102008000000015E
-:1031000009103C0000050638091038000005063D8E
-:10311000091038200005064206104C00000001008E
-:1031200002104028000000100210404400003FFF41
-:103130000210405800280000021040840084924A87
-:1031400002104058000000000210800000001080B3
-:10315000021080AC00000000021080380000001057
-:103160000210810000000000061081200000000213
-:1031700002108008000002B502108010000000005C
-:10318000061082000000004A021081080001FFFFC3
-:1031900006108140000000020210800000001A802A
-:1031A0000610900000000024061091200000004A44
-:1031B000061093700000004A061095C00000004AF7
-:1031C0000210800400001080021080B00000000196
-:1031D0000210803C0000001002108104000000007A
-:1031E00006108128000000020210800C000002B5C9
-:1031F0000210801400000000061084000000004A45
-:103200000210810C0001FFFF06108148000000023F
-:103210000210800400001A80061090900000002424
-:10322000061092480000004A061094980000004AD8
-:10323000061096E80000004A02108000000010808E
-:10324000021080AC00000002021080380000001064
-:103250000210810000000000061081200000000222
-:1032600002108008000002B502108010000000006B
-:10327000061082000000004A021081080001FFFFD2
-:1032800006108140000000020210800000001A8039
-:103290000610900000000024061091200000004A53
-:1032A000061093700000004A061095C00000004A06
-:1032B0000210800400001080021080B000000003A3
-:1032C0000210803C00000010021081040000000089
-:1032D00006108128000000020210800C000002B5D8
-:1032E0000210801400000000061084000000004A54
-:1032F0000210810C0001FFFF06108148000000024F
-:103300000210800400001A80061090900000002433
-:10331000061092480000004A061094980000004AE7
-:10332000061096E80000004A02108000000010809D
-:10333000021080AC00000004021080380000001071
-:103340000210810000000000061081200000000231
-:1033500002108008000002B502108010000000007A
-:10336000061082000000004A021081080001FFFFE1
-:1033700006108140000000020210800000001A8048
-:103380000610900000000024061091200000004A62
-:10339000061093700000004A061095C00000004A15
-:1033A0000210800400001080021080B000000005B0
-:1033B0000210803C00000010021081040000000098
-:1033C00006108128000000020210800C000002B5E7
-:1033D0000210801400000000061084000000004A63
-:1033E0000210810C0001FFFF06108148000000025E
-:1033F0000210800400001A80061090900000002443
-:10340000061092480000004A061094980000004AF6
-:10341000061096E80000004A0210800000001080AC
-:10342000021080AC0000000602108038000000107E
-:103430000210810000000000061081200000000240
-:1034400002108008000002B5021080100000000089
-:10345000061082000000004A021081080001FFFFF0
-:1034600006108140000000020210800000001A8057
-:103470000610900000000024061091200000004A71
-:10348000061093700000004A061095C00000004A24
-:103490000210800400001080021080B000000007BD
-:1034A0000210803C000000100210810400000000A7
-:1034B00006108128000000020210800C000002B5F6
-:1034C0000210801400000000061084000000004A72
-:1034D0000210810C0001FFFF06108148000000026D
-:1034E0000210800400001A80061090900000002452
-:1034F000061092480000004A061094980000004A06
-:10350000061096E80000004A021205B00000000113
-:103510000212049000E383400212051400003C10E4
-:103520000212066C0000000102120670000000008A
-:1035300002120494FFFFFFFF02120498FFFFFFFF37
-:103540000212049CFFFFFFFF021204A0FFFFFFFF17
-:10355000021204A4FFFFFFFF021204A8FFFFFFFFF7
-:10356000021204ACFFFFFFFF021204B0FFFFFFFFD7
-:10357000021204BCFFFFFFFF021204C0FFFFFFFFA7
-:10358000021204C4FFFFFFFF021204C8FFFFFFFF87
-:10359000021204CCFFFFFFFF021204D0FFFFFFFF67
-:1035A000021204D8FFFFFFFF021204DCFFFFFFFF3F
-:1035B000021204E0FFFFFFFF021204E4FFFFFFFF1F
-:1035C000021204E8FFFFFFFF021204ECFFFFFFFFFF
-:1035D000021204F0FFFFFFFF021204F4FFFFFFFFDF
-:1035E000021204F8FFFFFFFF021204FCFFFFFFFFBF
-:1035F00002120500FFFFFFFF02120504FFFFFFFF9D
-:1036000002120508FFFFFFFF0212050CFFFFFFFF7C
-:1036100002120510FFFFFFFF021204D4FF802000FA
-:10362000021204B4F0005000021204B8F00080004E
-:1036300002120390000000080212039C0000000820
-:10364000021203A000000008021203A400000002FE
-:10365000021203BC00000004021203C000000005B7
-:10366000021203C400000004021203D00000000094
-:103670000212036C00000001021203680000003F08
-:10368000021201BC00000040021201C00000180834
-:10369000021201C400000803021201C8000008035E
-:1036A000021201CC00000040021201D00000000311
-:1036B000021201D400000803021201D8000008031E
-:1036C000021201DC00000803021201E00001000305
-:1036D000021201E400000803021201E800000803DE
-:1036E000021201EC00000003021201F000000003CE
-:1036F000021201F400000003021201F800000003AE
-:10370000021201FC0000000302120200000000038C
-:10371000021202040000000302120208000000036B
-:103720000212020C0000000302120210000000034B
-:10373000021202140000000302120218000000032B
-:103740000212021C0000000302120220000000030B
-:1037500002120224000000030212022800002403C7
-:103760000212022C0000002F021202300000000999
-:103770000212023400000019021202380000018413
-:103780000212023C00000183021202400000030604
-:103790000212024400000019021202480000000652
-:1037A0000212024C0000030602120250000003063F
-:1037B00002120254000003060212025800000C8696
-:1037C0000212025C000003060212026000000306FF
-:1037D00002120264000000060212026800000006E5
-:1037E0000212026C000000060212027000000006C5
-:1037F00002120274000000060212027800000006A5
-:103800000212027C00000006021202800000000684
-:103810000212028400000006021202880000000664
-:103820000212028C00000006021202900000000644
-:103830000212029400000006021202980000000624
-:103840000212029C00000006021202A00000030601
-:10385000021202A400000013021202A800000006D7
-:10386000021202B000001004021202B400001004A0
-:103870000212032400106440021203280010644066
-:10388000021205B400000001021201B000000001A4
-:103890000600A000000000160200A0EC5554000035
-:1038A0000200A0F0555555550200A0F400005555F2
-:1038B0000200A0F8F00000000200A0FC5554000037
-:1038C0000200A100555555550200A10400005555B0
-:1038D0000200A108F00000000200A18C5554000075
-:1038E0000200A190555555550200A1940000555570
-:1038F0000200A198F00000000200A19C000000005E
-:103900000200A1A0000100000200A1A400005014C8
-:103910000200A1A8000000000200A45C00000C004E
-:103920000200A61C000000030200A06CFF5C000067
-:103930000200A070FFF55FFF0200A0740000FFFF0F
-:103940000200A078F00003E00200A07C000000006C
-:103950000200A0800000A0000600A0840000000576
-:103960000200A0980FE000000600A09C00000007E5
-:103970000200A0B8000004000600A0BC0000000384
-:103980000200A0C8000010000600A0CC0000000348
-:103990000200A0D8000040000600A0DC00000003E8
-:1039A0000200A0E8000100000600A22C00000004B4
-:1039B0000200A10CFF5C00000200A110FFF55FFFF8
-:1039C0000200A1140000FFFF0200A118F00003E0B4
-:1039D0000200A11C000000000200A1200000A000C5
-:1039E0000600A124000000050200A1380FE000003D
-:1039F0000600A13C000000070200A15800000800DA
-:103A00000600A15C000000030200A1680000200085
-:103A10000600A16C000000030200A17800008000F5
-:103A20000600A17C000000030200A1880002000043
-:103A30000600A23C0000000400000000000000009E
-:103A40000000003100000000000000000000000045
-:103A50000000000000000000000000000000000066
-:103A600000000000000000000000000000310032F3
-:103A70000000000000000000000000000000000046
-:103A80000000000000000000000000000000000036
-:103A9000000000000000000000320056000000009E
-:103AA0000000000000000000000000000000000016
-:103AB0000000000000000000000000000000000006
-:103AC000000000000056008C000000000000000014
-:103AD000008C009000900094009400980098009C46
-:103AE000009C00A000A000A400A400A800A800ACB6
-:103AF00000AC00B100B100B300B300B5000000009D
-:103B000000000000000000000000000000000000B5
-:103B100000000000000000000000000000B50100EF
-:103B2000010001060106010C010C01140114011C25
-:103B3000011C01240124012C012C01340134013C1D
-:103B4000013C01440144014C000000000000000061
-:103B50000000000000000000000000000000000065
-:103B60000000000000000000000000000000000055
-:103B70000000000000000000000000000000000045
-:103B80000000000000000000000000000000000035
-:103B90000000000000000000000000000000000025
-:103BA0000000000000000000000000000000000015
-:103BB0000000000000000000000000000000000005
-:103BC00000000000000000000000000000000000F5
-:103BD00000000000000000000000000000000000E5
-:103BE00000000000000000000000000000000000D5
-:103BF0000000000000000000014C01510000000026
-:103C000000000000015101520152015301530154BF
-:103C100001540155015501560156015701570158EC
-:103C200001580159000000000000000000000000E1
-:103C30000000000000000000000000000000000084
-:103C40000000000000000000000000000000000074
-:103C50000159015E015E016A016A017600000000FF
-:103C60000000000000000000000000000000000054
-:103C70000000000000000000000000000000000044
-:103C80000000000000000000000000000000000034
-:103C90000000000000000000000000000000000024
-:103CA0000000000000000000017601770000000025
-:103CB0000000000000000000000000000000000004
-:103CC00000000000000000000000000000000000F4
-:103CD000000000000177019A0000000000000000D1
-:103CE00000000000000000000000000000000000D4
-:103CF00000000000000000000000000000000000C4
-:103D0000019A01C200000000000000000000000055
-:103D100000000000000000000000000000000000A3
-:103D200000000000000000000000000001C201F3DC
-:103D3000000000000000000001F301FA01FA020196
-:103D4000020102080208020F020F02160216021DEB
-:103D5000021D02240224022B022B02630000000039
-:103D600000000000026302670267026B026B026FD1
-:103D7000026F0273027302770277027B027B027F7B
-:103D8000027F0283028302D102D102EB02EB030520
-:103D9000030503080308030B030B030E030E0311B3
-:103DA00003110314031403170317031A031A031D43
-:103DB000031D035E035E0362036203660366036919
-:103DC0000369036C036C036F036F03720372037563
-:103DD000037503780378037B037B037E037E037FF5
-:103DE00000000000000000000000000000000000D3
-:103DF00000000000000000000000000000000000C3
-:103E00000000000000000000037F0391000000009C
-:103E100000000000000000000000000000000000A2
-:103E20000000000000000000000000000000000092
-:103E300000000000039103A603A603A903A903AC95
-:103E40000000000000000000000000000000000072
-:103E50000000000000000000000000000000000062
-:103E600003AC03D9000000000000000000000000C7
-:103E70000000000000000000000000000000000042
-:103E800000000000000000000000000003D904DC76
-:103E90000000000000000000000000000000000022
-:103EA0000000000000000000000000000000000012
-:103EB000000000000000000004DC04E304E304E769
-:103EC00004E704EB00000000000000000000000018
-:103ED00000000000000000000000000000000000E2
-:103EE0000000000004EB052B0000000000000000B3
-:103EF000052B05340534053D053D05460546054FB2
-:103F0000054F0558055805610561056A056A057381
-:103F1000057305CB05CB05DD05DD05EF05EF05F2E6
-:103F200005F205F505F505F805F805FB05FB05FEA9
-:103F300005FE060106010604060406070607060E2E
-:103F40000000000000000000000000000000000071
-:103F50000000000000000000000000000000000061
-:103F60000000000000000000060E06140000000023
-:103F70000000000000000000000000000000000041
-:103F80000000000000000000000000000000000031
-:103F900000000000061406170000000000000000EA
-:103FA0000000000000000000000000000000000011
-:103FB0000000000000000000000000000000000001
-:103FC0000617061D000000000000000000000000B1
-:103FD00000000000000000000000000000000000E1
-:103FE00000000000000000000000000000000000D1
-:103FF0000000000000000000061D062C062C063BF9
-:10400000063B064A064A06590659066806680677B8
-:1040100006770686068606950695070600000000C8
-:104020000000000000000000000000000000000090
-:104030000000000000000000000000000000000080
-:1040400000000000070607190719072A072A073B7F
-:104050000000000000000000000000000000000060
-:104060000000000000000000000000000000000050
-:10407000000000000000000000010000000204C079
-:104080000003098000040E4000051300000617C05D
-:1040900000071C800008214000092600000A2AC0F1
-:1040A000000B2F80000C3440000D3900000E3DC085
-:1040B000000F42800010474000114C00001250C019
-:1040C0000013558000145A4000155F00001663C0AD
-:1040D0000017688000186D4000197200001A76C041
-:1040E000001B7B80001C8040001D8500001E89C0D5
-:1040F000001F8E8000209340000020000000400040
-:1041000000006000000080000000A0000000C0006F
-:104110000000E0000001000000012000000140005C
-:1041200000016000000180000001A0000001C0004B
-:104130000001E00000020000000220000002400038
-:1041400000026000000280000002A0000002C00027
-:104150000002E00000030000000320000003400014
-:1041600000036000000380000003A0000003C00003
-:104170000003E000000400000004200000044000F0
-:1041800000046000000480000004A0000004C000DF
-:104190000004E000000500000005200000054000CC
-:1041A00000056000000580000005A0000005C000BB
-:1041B0000005E000000600000006200000064000A8
-:1041C00000066000000680000006A0000006C00097
-:1041D0000006E00000070000000720000007400084
-:1041E00000076000000780000007A0000007C00073
-:1041F0000007E00000080000000820000008400060
-:1042000000086000000880000008A0000008C0004E
-:104210000008E0000009000000092000000940003B
-:1042200000096000000980000009A0000009C0002A
-:104230000009E000000A0000000A2000000A400017
-:10424000000A6000000A8000000AA000000AC00006
-:10425000000AE000000B0000000B2000000B4000F3
-:10426000000B6000000B8000000BA000000BC000E2
-:10427000000BE000000C0000000C2000000C4000CF
-:10428000000C6000000C8000000CA000000CC000BE
-:10429000000CE000000D0000000D2000000D4000AB
-:1042A000000D6000000D8000000DA000000DC0009A
-:1042B000000DE000000E0000000E2000000E400087
-:1042C000000E6000000E8000000EA000000EC00076
-:1042D000000EE000000F0000000F2000000F400063
-:1042E000000F6000000F8000000FA000000FC00052
-:1042F000000FE0000010000000102000001040003F
-:1043000000106000001080000010A0000010C0002D
-:104310000010E0000011000000112000001140001A
-:1043200000116000001180000011A0000011C00009
-:104330000011E000001200000012200000124000F6
-:1043400000126000001280000012A0000012C000E5
-:104350000012E000001300000013200000134000D2
-:1043600000136000001380000013A0000013C000C1
-:104370000013E000001400000014200000144000AE
-:1043800000146000001480000014A0000014C0009D
-:104390000014E0000015000000152000001540008A
-:1043A00000156000001580000015A0000015C00079
-:1043B0000015E00000160000001620000016400066
-:1043C00000166000001680000016A0000016C00055
-:1043D0000016E00000170000001720000017400042
-:1043E00000176000001780000017A0000017C00031
-:1043F0000017E0000018000000182000001840001E
-:1044000000186000001880000018A0000018C0000C
-:104410000018E000001900000019200000194000F9
-:1044200000196000001980000019A0000019C000E8
-:104430000019E000001A0000001A2000001A4000D5
-:10444000001A6000001A8000001AA000001AC000C4
-:10445000001AE000001B0000001B2000001B4000B1
-:10446000001B6000001B8000001BA000001BC000A0
-:10447000001BE000001C0000001C2000001C40008D
-:10448000001C6000001C8000001CA000001CC0007C
-:10449000001CE000001D0000001D2000001D400069
-:1044A000001D6000001D8000001DA000001DC00058
-:1044B000001DE000001E0000001E2000001E400045
-:1044C000001E6000001E8000001EA000001EC00034
-:1044D000001EE000001F0000001F2000001F400021
-:1044E000001F6000001F8000001FA000001FC00010
-:1044F000001FE000002000000020200000204000FD
-:1045000000206000002080000020A0000020C000EB
-:104510000020E000002100000021200000214000D8
-:1045200000216000002180000021A0000021C000C7
-:104530000021E000002200000022200000224000B4
-:1045400000226000002280000022A0000022C000A3
-:104550000022E00000230000002320000023400090
-:1045600000236000002380000023A0000023C0007F
-:104570000023E0000024000000242000002440006C
-:1045800000246000002480000024A0000024C0005B
-:104590000024E00000250000002520000025400048
-:1045A00000256000002580000025A0000025C00037
-:1045B0000025E00000260000002620000026400024
-:1045C00000266000002680000026A0000026C00013
-:1045D0000026E00000270000002720000027400000
-:1045E00000276000002780000027A0000027C000EF
-:1045F0000027E000002800000028200000284000DC
-:1046000000286000002880000028A0000028C000CA
-:104610000028E000002900000029200000294000B7
-:1046200000296000002980000029A0000029C000A6
-:104630000029E000002A0000002A2000002A400093
-:10464000002A6000002A8000002AA000002AC00082
-:10465000002AE000002B0000002B2000002B40006F
-:10466000002B6000002B8000002BA000002BC0005E
-:10467000002BE000002C0000002C2000002C40004B
-:10468000002C6000002C8000002CA000002CC0003A
-:10469000002CE000002D0000002D2000002D400027
-:1046A000002D6000002D8000002DA000002DC00016
-:1046B000002DE000002E0000002E2000002E400003
-:1046C000002E6000002E8000002EA000002EC000F2
-:1046D000002EE000002F0000002F2000002F4000DF
-:1046E000002F6000002F8000002FA000002FC000CE
-:1046F000002FE000003000000030200000304000BB
-:1047000000306000003080000030A0000030C000A9
-:104710000030E00000310000003120000031400096
-:1047200000316000003180000031A0000031C00085
-:104730000031E00000320000003220000032400072
-:1047400000326000003280000032A0000032C00061
-:104750000032E0000033000000332000003340004E
-:1047600000336000003380000033A0000033C0003D
-:104770000033E0000034000000342000003440002A
-:1047800000346000003480000034A0000034C00019
-:104790000034E00000350000003520000035400006
-:1047A00000356000003580000035A0000035C000F5
-:1047B0000035E000003600000036200000364000E2
-:1047C00000366000003680000036A0000036C000D1
-:1047D0000036E000003700000037200000374000BE
-:1047E00000376000003780000037A0000037C000AD
-:1047F0000037E0000038000000382000003840009A
-:1048000000386000003880000038A0000038C00088
-:104810000038E00000390000003920000039400075
-:1048200000396000003980000039A0000039C00064
-:104830000039E000003A0000003A2000003A400051
-:10484000003A6000003A8000003AA000003AC00040
-:10485000003AE000003B0000003B2000003B40002D
-:10486000003B6000003B8000003BA000003BC0001C
-:10487000003BE000003C0000003C2000003C400009
-:10488000003C6000003C8000003CA000003CC000F8
-:10489000003CE000003D0000003D2000003D4000E5
-:1048A000003D6000003D8000003DA000003DC000D4
-:1048B000003DE000003E0000003E2000003E4000C1
-:1048C000003E6000003E8000003EA000003EC000B0
-:1048D000003EE000003F0000003F2000003F40009D
-:1048E000003F6000003F8000003FA000003FC0008C
-:1048F000003FE000003FE00100000000000001FF79
-:104900000000020000007FF800007FF800000704AC
-:104910000000350000000001FFFFFFFFFFFFFFFF69
-:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
-:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
-:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
-:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
-:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
-:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
-:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
-:10499000FFFFFFFFFFFFFFFFFFFFFFFF0000000023
-:1049A000FFFFFFFF00000000FFFFFFFFFFFFFFFF13
-:1049B00000000000FFFFFFFF00000000FFFFFFFFFF
-:1049C000FFFFFFFF00000000FFFFFFFF00000000EF
-:1049D000FFFFFFFF0000000300BEBC20FFFFFFFF42
-:1049E00000000000FFFFFFFF00000000FFFFFFFFCF
-:1049F0000000000300BEBC20FFFFFFFF000000001E
-:104A0000FFFFFFFF00000000FFFFFFFF00000003AB
-:104A100000BEBC20FFFFFFFF00000000FFFFFFFF04
-:104A200000000000FFFFFFFF0000000300BEBC20ED
-:104A3000FFFFFFFF00000000FFFFFFFF000000007E
-:104A4000FFFFFFFF0000000300BEBC20FFFFFFFFD1
-:104A500000000000FFFFFFFF00000000FFFFFFFF5E
-:104A60000000000300BEBC2000002000000040C089
-:104A700000006180000082400000A3000000C3C06D
-:104A80000000E4800001054000012600000146C04E
-:104A900000016780000188400001A9000001C9C031
-:104AA0000001EA8000020B4000022C0000024CC012
-:104AB00000026D8000028E400002AF000002CFC0F5
-:104AC0000002F0800003114000033200000352C0D6
-:104AD00000037380000394400003B5000003D5C0B9
-:104AE0000003F6800004174000043800000458C09A
-:104AF0000004798000049A400000800000010380D7
-:104B00000001870000020A8000028E00000311806D
-:104B1000000395000004188000049C0000051F801D
-:104B20000005A300000626800006AA0000072D80CD
-:104B30000007B100000834800008B80000093B807D
-:104B40000009BF00000A4280000AC600000B49802D
-:104B5000000BCD00000C5080000CD400000D5780DD
-:104B6000000DDB0000007FF800007FF800000487E4
-:104B700000001500000019000000002800100000CF
-:104B80000000000000000000FFFFFFFF40000000E9
-:104B90004000000040000000400000004000000015
-:104BA0004000000040000000400000004000000005
-:104BB00040000000400000004000000040000000F5
-:104BC00040000000400000004000000040000000E5
-:104BD00040000000400000004000000040000000D5
-:104BE00040000000400000004000000040000000C5
-:104BF00040000000400000004000000040000000B5
-:104C000040000000400000004000000000007FF86D
-:104C100000007FF8000003E000001500FFFFFFFF29
-:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
-:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
-:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
-:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
-:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
-:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
-:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
-:104C9000FFFFFFFFFFFFFFFFFFFFFFFF40000000E0
-:104CA0004000000040000000400000004000000004
-:104CB00040000000400000004000000040000000F4
-:104CC00040000000400000004000000040000000E4
-:104CD00040000000400000004000000040000000D4
-:104CE00040000000400000004000000040000000C4
-:104CF00040000000400000004000000040000000B4
-:104D000040000000400000004000000040000000A3
-:104D100040000000400000004000000000001000C3
-:104D2000000020800000310000004180000052009F
-:104D30000000628000007300000083800000940087
-:104D40000000A4800000B5000000C5800000D6006F
-:104D50000000E6800000F700000107800001180055
-:104D600000012880000139000001498000015A003B
-:104D700000016A8000017B0000018B8000019C0023
-:104D80000001AC800001BD000001CD800001DE000B
-:104D90000001EE800001FF0000007FF800007FF8B6
-:104DA0000000023E0000350010000000000028ADA9
-:104DB000000000000001000100350804CCCCCCC587
-:104DC000FFFFFFFFFFFFFFFF7058103C00000000D7
-:104DD000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3D
-:104DE000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2D
-:104DF000CCCC0201CCCCCCCCCCCC0201CCCCCCCC1D
-:104E0000CCCC0201CCCCCCCCCCCC0201CCCCCCCC0C
-:104E100000000000FFFFFFFF400000004000000016
-:104E20004000000040000000400000004000000082
-:104E30004000000040000000400000004000000072
-:104E40004000000040000000400000004000000062
-:104E50004000000040000000400000004000000052
-:104E60004000000040000000400000004000000042
-:104E70004000000040000000400000004000000032
-:104E80004000000040000000400000004000000022
-:104E90004000000040000000000E0232011600D663
-:104EA000001000000000000000720236012300F331
-:104EB00000100000000000000000FFFF00000000E4
-:104EC0000000FFFF000000000000FFFF00000000E6
-:104ED0000000FFFF000000000000FFFF00000000D6
-:104EE0000000FFFF000000000000FFFF00000000C6
-:104EF0000000FFFF000000000000FFFF00000000B6
-:104F00000000FFFF000000000000FFFF00000000A5
-:104F10000000FFFF000000000000FFFF0000000095
-:104F20000000FFFF000000000000FFFF0000000085
-:104F30000000FFFF000000000000FFFF0000000075
-:104F40000000FFFF000000000000FFFF0000000065
-:104F50000000FFFF000000000000FFFF0000000055
-:104F60000000FFFF000000000000FFFF0000000045
-:104F70000000FFFF000000000000FFFF0000000035
-:104F80000000FFFF000000000000FFFF0000000025
-:104F90000000FFFF000000000000FFFF0000000015
-:104FA0000000FFFF000000000000FFFF0000000005
-:104FB0000000FFFF000000000000FFFF00000000F5
-:104FC0000000FFFF000000000000FFFF00000000E5
-:104FD0000000FFFF000000000000FFFF00000000D5
-:104FE0000000FFFF000000000000FFFF00000000C5
-:104FF0000000FFFF000000000000FFFF00000000B5
-:105000000000FFFF000000000000FFFF00000000A4
-:105010000000FFFF000000000000FFFF0000000094
-:105020000000FFFF000000000000FFFF0000000084
-:105030000000FFFF000000000000FFFF0000000074
-:105040000000FFFF000000000000FFFF0000000064
-:105050000000FFFF000000000000FFFF0000000054
-:105060000000FFFF000000000000FFFF0000000044
-:105070000000FFFF000000000000FFFF0000000034
-:105080000000FFFF000000000000FFFF0000000024
-:105090000000FFFF000000000000FFFF0000000014
-:1050A0000000FFFF000000000000FFFF0000000004
-:1050B0000000FFFF00000000FFFFFFF3320FFFFFC3
-:1050C0000C30C30CC30C30C3CF3CF300F3CF3CF324
-:1050D0000000CF3CCDCDCDCDFFFFFFF130EFFFFF86
-:1050E0000C30C30CC30C30C3CF3CF300F3CF3CF304
-:1050F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFF0
-:105100000C30C30CC30C30C3CF3CF300F3CF3CF3E3
-:105110000002CF3CCDCDCDCDFFFFF4061CBFFFFF7D
-:105120000C30C305C30C30C3CF300014F3CF3CF3B5
-:105130000004CF3CCDCDCDCDFFFFFFF2304FFFFFC0
-:105140000C30C30CC30C30C3CF3CF300F3CF3CF3A3
-:105150000008CF3CCDCDCDCDFFFFFFFA302FFFFFB4
-:105160000C30C30CC30C30C3CF3CF300F3CF3CF383
-:105170000010CF3CCDCDCDCDFFFFFFF731EFFFFFCE
-:105180000C30C30CC30C30C3CF3CF300F3CF3CF363
-:105190000020CF3CCDCDCDCDFFFFFFF5302FFFFF61
-:1051A0000C30C30CC30C30C3CF3CF300F3CF3CF343
-:1051B0000040CF3CCDCDCDCDFFFFFFF3310FFFFF42
-:1051C0000C30C30CC30C30C3CF3CF300F3CF3CF323
-:1051D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF64
-:1051E0000C30C30CC30C30C3CF3CF300F3CF3CF303
-:1051F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEF
-:105200000C30C30CC30C30C3CF3CF300F3CF3CF3E2
-:105210000002CF3CCDCDCDCDFFFFF4061CBFFFFF7C
-:105220000C30C305C30C30C3CF300014F3CF3CF3B4
-:105230000004CF3CCDCDCDCDFFFFFFF2304FFFFFBF
-:105240000C30C30CC30C30C3CF3CF300F3CF3CF3A2
-:105250000008CF3CCDCDCDCDFFFFFFFA302FFFFFB3
-:105260000C30C30CC30C30C3CF3CF300F3CF3CF382
-:105270000010CF3CCDCDCDCDFFFFFFF730EFFFFFCE
-:105280000C30C30CC30C30C3CF3CF300F3CF3CF362
-:105290000020CF3CCDCDCDCDFFFFFFF5304FFFFF40
-:1052A0000C30C30CC30C30C3CF3CF300F3CF3CF342
-:1052B0000040CF3CCDCDCDCDFFFFFFF331EFFFFF61
-:1052C0000C30C30CC30C30C3CF3CF300F3CF3CF322
-:1052D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF63
-:1052E0000C30C30CC30C30C3CF3CF300F3CF3CF302
-:1052F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEE
-:105300000C30C30CC30C30C3CF3CF300F3CF3CF3E1
-:105310000002CF3CCDCDCDCDFFFFF4061CBFFFFF7B
-:105320000C30C305C30C30C3CF300014F3CF3CF3B3
-:105330000004CF3CCDCDCDCDFFFFFFF2304FFFFFBE
-:105340000C30C30CC30C30C3CF3CF300F3CF3CF3A1
-:105350000008CF3CCDCDCDCDFFFFFFFA302FFFFFB2
-:105360000C30C30CC30C30C3CF3CF300F3CF3CF381
-:105370000010CF3CCDCDCDCDFFFFFF97056FFFFFD8
-:105380000C30C30CC30C30C3CF3CC000F3CF3CF394
-:105390000020CF3CCDCDCDCDFFFFFFF5310FFFFF7E
-:1053A0000C30C30CC30C30C3CF3CF300F3CF3CF341
-:1053B0000040CF3CCDCDCDCDFFFFFFF3320FFFFF3F
-:1053C0000C30C30CC30C30C3CF3CF300F3CF3CF321
-:1053D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF62
-:1053E0000C30C30CC30C30C3CF3CF300F3CF3CF301
-:1053F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFED
-:105400000C30C30CC30C30C3CF3CF300F3CF3CF3E0
-:105410000002CF3CCDCDCDCDFFFFF4061CBFFFFF7A
-:105420000C30C305C30C30C3CF300014F3CF3CF3B2
-:105430000004CF3CCDCDCDCDFFFFFFF2304FFFFFBD
-:105440000C30C30CC30C30C3CF3CF300F3CF3CF3A0
-:105450000008CF3CCDCDCDCDFFFFFF8A042FFFFF4D
-:105460000C30C30CC30C30C3CF3CC000F3CF3CF3B3
-:105470000010CF3CCDCDCDCDFFFFFF9705CFFFFF77
-:105480000C30C30CC30C30C3CF3CC000F3CF3CF393
-:105490000020CF3CCDCDCDCDFFFFFFF5310FFFFF7D
-:1054A0000C30C30CC30C30C3CF3CF300F3CF3CF340
-:1054B0000040CF3CCDCDCDCDFFFFFFF3316FFFFFDF
-:1054C0000C30C30CC30C30C3CF3CF300F3CF3CF320
-:1054D0000000CF3CCDCDCDCDFFFFFFF1302FFFFF42
-:1054E0000C30C30CC30C30C3CF3CF300F3CF3CF300
-:1054F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEC
-:105500000C30C30CC30C30C3CF3CF300F3CF3CF3DF
-:105510000002CF3CCDCDCDCDFFFFFFF630BFFFFF6A
-:105520000C30C30CC30C30C3CF3CF314F3CF3CF3AB
-:105530000004CF3CCDCDCDCDFFFFFFF2304FFFFFBC
-:105540000C30C30CC30C30C3CF3CF300F3CF3CF39F
-:105550000008CF3CCDCDCDCDFFFFFFFA302FFFFFB0
-:105560000C30C30CC30C30C3CF3CF300F3CF3CF37F
-:105570000010CF3CCDCDCDCDFFFFFFF731CFFFFFEA
-:105580000C30C30CC30C30C3CF3CF300F3CF3CF35F
-:105590000020CF3CCDCDCDCDFFFFFFF0307FFFFF12
-:1055A0000C30C30CC30C30C3CF3CF300F3CF3CF33F
-:1055B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF73
-:1055C0000C30C30CC30C30C3CF3CF3CCF3CF3CF353
-:1055D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF93
-:1055E0000C30C30CC30C30C3CF3CF3CCF3CF3CF333
-:1055F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF72
-:105600000C30C30CC30C30C3CF3CF3CCF3CF3CF312
-:105610000002CF3CCDCDCDCDFFFFFFFF30CFFFFF50
-:105620000C30C30CC30C30C3CF3CF3CCF3CF3CF3F2
-:105630000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2E
-:105640000C30C30CC30C30C3CF3CF3CCF3CF3CF3D2
-:105650000008CF3CCDCDCDCDFFFFFFFF30CFFFFF0A
-:105660000C30C30CC30C30C3CF3CF3CCF3CF3CF3B2
-:105670000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE2
-:105680000C30C30CC30C30C3CF3CF3CCF3CF3CF392
-:105690000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB2
-:1056A0000C30C30CC30C30C3CF3CF3CCF3CF3CF372
-:1056B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF72
-:1056C0000C30C30CC30C30C3CF3CF3CCF3CF3CF352
-:1056D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF92
-:1056E0000C30C30CC30C30C3CF3CF3CCF3CF3CF332
-:1056F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF71
-:105700000C30C30CC30C30C3CF3CF3CCF3CF3CF311
-:105710000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4F
-:105720000C30C30CC30C30C3CF3CF3CCF3CF3CF3F1
-:105730000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2D
-:105740000C30C30CC30C30C3CF3CF3CCF3CF3CF3D1
-:105750000008CF3CCDCDCDCDFFFFFFFF30CFFFFF09
-:105760000C30C30CC30C30C3CF3CF3CCF3CF3CF3B1
-:105770000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE1
-:105780000C30C30CC30C30C3CF3CF3CCF3CF3CF391
-:105790000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB1
-:1057A0000C30C30CC30C30C3CF3CF3CCF3CF3CF371
-:1057B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF71
-:1057C0000C30C30CC30C30C3CF3CF3CCF3CF3CF351
-:1057D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF91
-:1057E0000C30C30CC30C30C3CF3CF3CCF3CF3CF331
-:1057F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF70
-:105800000C30C30CC30C30C3CF3CF3CCF3CF3CF310
-:105810000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4E
-:105820000C30C30CC30C30C3CF3CF3CCF3CF3CF3F0
-:105830000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2C
-:105840000C30C30CC30C30C3CF3CF3CCF3CF3CF3D0
-:105850000008CF3CCDCDCDCDFFFFFFFF30CFFFFF08
-:105860000C30C30CC30C30C3CF3CF3CCF3CF3CF3B0
-:105870000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE0
-:105880000C30C30CC30C30C3CF3CF3CCF3CF3CF390
-:105890000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB0
-:1058A0000C30C30CC30C30C3CF3CF3CCF3CF3CF370
-:1058B0000040CF3CCDCDCDCD001000000007010051
-:1058C00000028170000B81980002025000010270FA
-:1058D000000F028000010370000800000008008033
-:1058E00000028100000B8128000201E0000102009B
-:1058F0000007021000020280000F0000000800F004
-:1059000000028170000B81980002025000010270B9
-:10591000000B82800008033800100000000801001E
-:1059200000028180000B81A80002026000018280D9
-:10593000000E829800080380000B0000000100B0F8
-:10594000000280C0000580E8000201400001016003
-:10595000000E017000038250CCCCCCCCCCCCCCCC93
-:10596000CCCCCCCCCCCCCCCC00002000CCCCCCCC87
-:10597000CCCCCCCCCCCCCCCCCCCCCCCC0000200077
-:10598000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC57
-:1059900004002000000000001F8B08000000000031
-:1059A00000FFFB51CFC0F0038A277033309CE345E2
-:1059B000F0E981831829D35FC6CEC05001C4554099
-:1059C000BC0B883FB132307C66255EFF352904DB95
-:1059D000488281211E88D7883130A84922C41DA45D
-:1059E00019182603F9A150B147403A5F8A32770F60
-:1059F000169CA68029E62A8760A7639147C6196886
-:105A0000F24BE550F99904F40F34BEA28ECAFFA2FE
-:105A10000AA113A0E257D1E4BF42E53BA0FEBAA61B
-:105A20008EDDDC4E32FD5DC302A101FC99B04798CA
-:105A300003000000000000001F8B080000000000B1
-:105A400000FFED7D0B7854D5B5F03E731E3393798E
-:105A5000E424E43181104E1E2068080384888AB74C
-:105A6000271030F6D27678D5582D0EAF10F2866B0F
-:105A70002DBDB67F06084978A8C11F11ADD5E12913
-:105A8000F6821D3122B6880328D2ABBD37587C552B
-:105A9000EB1FD10B8A90442A6AEFB5E5EEB5F63ECE
-:105AA000C99C9309047BDBAFFFFFFD7C9FEEECC735
-:105AB000D97BEDF5DA6BADFD18C93181A40D23E476
-:105AC00022FCFB0621929D1032A1379DE32021D7B5
-:105AD000184292662FFDDD921442DCBAE2BF49A360
-:105AE000A9BBFEE41A9A5F5FECF0AFA44D5B1F4DBB
-:105AF000786A092DBFEFA12FC34FD07CFAEC79ADA6
-:105B0000C5B47ECE24C90F5D1D1AAB1002EDE7D8D7
-:105B1000C276015281E5979030A17F92AFE8F845B7
-:105B200084B8E89F2497FE37891CB2A5603EE4D173
-:105B3000A09E029946483631FE55607E36FC09F536
-:105B4000447767D0EF759E77E513EC7F8E5F0ADBB5
-:105B5000E94773F20372C84DD3C6086D49C71DFBF0
-:105B60005D3908F9C00C99E46387B6D8FE6FCA0F97
-:105B70004C7514D2FE670B08FFF9D94936DA82CC8E
-:105B8000A6EDE13B224E1F1ACC679FD9E8B8DFE0B3
-:105B9000DFDDDF40FFA7C05F4B09A1E5CB1C0C9EFA
-:105BA000E4D9D9C530CE8919D71643BF73A61332AD
-:105BB00088564D9D3DF69044F3EB1A89DF4EDBCDC0
-:105BC000290D1CCF81D9F8CBA79302E8978EEE6000
-:105BD0007D5FC4FFEB38EF643EDE3FCC1E2B10FA36
-:105BE00041F6978AA95D72A0F953D14B486A052DF9
-:105BF0001F1953EE9F769AD0F2E4E9E6F64013724D
-:105C00001D2125C49372EA1AFA7716C9BA2842AD43
-:105C10006A0B8CEEE50F6B4AFFFDF922D001FA12F8
-:105C2000FBD61F6A9CE9E9A0F85A377B9687D0F427
-:105C3000F5C02C0FE0EFF5D9B3108FD6F673666779
-:105C400027025EFB1BEFFE063AD008FA3DC7B3B54C
-:105C50007E9048EA23F4FB393AD1C331FDDF01934A
-:105C60004D256409301B4DB325D5A6D2FA6C8DE8BD
-:105C70009138E39502B1693B92499928E352F30FB9
-:105C800061BB3726D94AC371E67307EFC7551AB807
-:105C9000670EA56FD674127551BA1229AAC6E2759D
-:105CA0005D8A541A8E03C7DD1C5E42687BCFC0E15B
-:105CB0007165D802D09F32470CC4C2F50380674299
-:105CC0006F4AA24CEEE6F818FD72BFFB6C508F33A2
-:105CD0008FBB008E0990AAEC3B0E8F0C7C9301B217
-:105CE0009682FC43C26324E0FBCC1EB9240107E585
-:105CF0008FA1F01715AE2DA47BD41214B256EC4729
-:105D0000F4A42403BD5711DE0F29514F517E1542D3
-:105D1000AB848BD75C6A9E123965F035F0A93B19CC
-:105D2000C7BF1C5E48A018E55231D48878C007E38D
-:105D30002BF94DED02A5CBBAD1E57E946F8A219067
-:105D400033437EE1DF57F43B37FFCCBD9CD291CA91
-:105D5000916B39D38F8ADF2C67EB928EB50820C800
-:105D600064B9490F1012244077036FEBBEA278BCD0
-:105D700004BF5BFBDD6FC8E7603298C927933F051E
-:105D8000FA07BD79D37E07F0F53ADF5E07CC6B5D8D
-:105D9000FE5E827A8AD3C7E8D795AF5D52CED681B0
-:105DA0007C8D80EEC348A79EF2D1A7C6027E76A660
-:105DB0002AF78B747E3B9308EAD9756B48782BD011
-:105DC000B594E5B56F69E1B5748E3B9DBCBE98D6C0
-:105DD000D3BC06EDA9BEDB3A490B87687E6B8B8D81
-:105DE000B51FAB85459A1F319184148A4F6DC5C28A
-:105DF000954E5ABE75A3EA17B55EFD34A225672DF0
-:105E0000B4DFB2DEA60AF0BD8FAD233BF3493844C0
-:105E1000C7DFB139F99B23693E14B2F987D34FF23A
-:105E2000F8FA45D9A5442802B4313A9C21795CAEF0
-:105E30000402E5A9BC7CCB7EFFBF8EA4F03D365D9D
-:105E4000F2AFA0453BD6CF4CD0289E766881043F68
-:105E50004D7FF0C07CCCEFCC0C2600DD766E9C9F95
-:105E6000004CF1C0E6991B46417B61D2611DE96C93
-:105E7000D6FF471F283AEC00384B999E4F6A0D7E9B
-:105E800053A2F9BC4912B9894E21CFAD21DCDB1FE9
-:105E9000B211584FFBE86D8BBE4ED4CD7957EBB4A1
-:105EA0008F817F5D0F160920DA3B3586E7413792F7
-:105EB000F08AECBEE3EF5CC8EA13295D800E2EBFCA
-:105EC000625967965AF856477970713CB95A751CF1
-:105ED0008F487A8990D68B57FA9F4662F0E97AF01C
-:105EE0002881F5E98AE76381275DA07C0F83AB9C5D
-:105EF000EFB91E1CF7CA5763E3F1B121EF1EA07F73
-:105F000022C577612404EB507A61240AFCE2C95768
-:105F100034B00B9A0931C9C5A1D1FB7C1D203713C0
-:105F2000223E58AFD78D7E83C98F5681F830E66FF9
-:105F3000B4F7E4B79358FBC1A88772F8CE537869D9
-:105F400039BB87CB594F7F84AD4724731CC2754F33
-:105F5000E161755E1C7D4CC80A94CB9749E07A815B
-:105F6000A6DECDED51A7066CAEDF0079B7400291F9
-:105F700038DF4D13D87AD242745DA0E9A3442F16BE
-:105F8000709D4B66FAD7B22EF5D19FBC5D16E9160F
-:105F900040DF68D43E803487F831CD23014C4792EE
-:105FA000564CAF26114CF3493BA605A41B5343AFF7
-:105FB000F8892A427EC4C4FAC920E7A4DA638BE5D3
-:105FC000BBD06432B23ECE3C9A2D787390F8EBF899
-:105FD0001D025FE748A68AFC43F87AF16EB018E824
-:105FE000C55428FCBBDBCCEFE224BE0E38EA3D6989
-:105FF000805733DD8D5454CD7C5A6DF0A944241C58
-:10600000C7321FC463CCB8D6FE5673FBC6989F9C9C
-:10601000A2231F496E66CF5038F4BD71F0D1280815
-:106020007C9E41ABDC3AB229BF4B49B6C85A9A6B49
-:10603000744F76E8382F3F894767EB7CACF02ABE77
-:1060400081C1B3A9079E0ACB3AFA97C2F34FA6FEC5
-:10605000A44CB21DD60BA28670DE56BCF6F9DE4209
-:106060008FFEE4D29169D6574A8AD70287859F0668
-:10607000687F7CE34BEA7FE4C3FA1B21412AECA949
-:10608000F90101E67FAD401A13295EC868A2EDA0B0
-:1060900070CDF56ACC8E8B693719F491660BC97493
-:1060A000BECF92EE23D03EE427911DF4B367F36D8B
-:1060B000A55B697DAA9FB663FD05401EAE1D6D0BF5
-:1060C00040B9D19F4E9E32F547FD2E11F0E136E8E2
-:1060D00063F1C3E4B136B41F957CA26F89235FC717
-:1060E000B97C151D71EAB09EB8CA94B0331BFA8F03
-:1060F00014433EB59AF8615D9FD4CDE651C6E130B8
-:10610000E69DFA5940007E6AF7313BC05548D03FC2
-:106110005432DA74F01FDDB40EF5427E541753503A
-:106120003FA23FD81F9E3D5F3DED0BD07E7DD4B991
-:106130006A07BE92FCE9A09F578F56C860FABDF867
-:106140003B3BF6FFB9A762188999CF470DD1B10B38
-:10615000A9C170A6E118A6671BDA31ED6C780BD3E4
-:10616000FEE94A598EDACEEB7EE2D7C01E100F3F11
-:1061700047340FC01DD5755C171CA212B32E808248
-:1061800006FF6FD3D8BCF0DA6CC46B08E64DD56758
-:10619000787836E05B0A009E873822C2D27C867708
-:1061A000C03FD001CA8B8E3CB702F15C4DC6029E47
-:1061B00037C9A40CF43CE013D6897D82ED0E800330
-:1061C000F2F369FEFA8FFAC1FB5986F78C97299E84
-:1061D000004E494B64C6AD8EF2953B910B12D7270A
-:1061E000BD7A92F9D9BDF6BDF6EF00CF964689ACDF
-:1061F00085BCA6684A11B7F7414A8215D3C1DFDCD6
-:10620000563EFD28D80BB9E25787645A3EB45E3A31
-:10621000D911234F596574FDA476C2B0E5E6F2ECBE
-:1062200090394F07407F34B7C55C3EC4C6F5AE8792
-:1062300078401EADF35AB6E85771FDD3550D24EAE8
-:106240009663F202C3A79117BC133B42747ECB4600
-:10625000118C034CB7B1F5B315BEA37C712F4FD78A
-:106260005BFA315269A2DB46C6303D196F7DBADD5B
-:10627000563CCE46FB6BB04D1E67A372E4922204DF
-:10628000EC77975BD1E3F993D36D128E9F20B5EB3A
-:106290002285ABFB3AE2DF4AF1BE4CEE8E827C2CCB
-:1062A0002BD6FC215047FE30CA6312D56162F61529
-:1062B000C153027050784A6C384E04FBE9A6380787
-:1062C000FB7D99CCFA5D364A236837F603E75536ED
-:1062D00019E10CD80409FD344E97551539F74DA333
-:1062E000D94E559F05FD67260567C17846B96F7E73
-:1062F00029FA6319C3CCF42B77D467017F540622A3
-:10630000D3807F4E7B5F6C92E9BCB73610BF44F1FF
-:10631000FF9E2B701BF457737BFD08B07FDF065E7A
-:1063200098002A3B807AACA564A55FA2E572891427
-:1063300095293FCA130FBF2517401A2A86388B9319
-:10634000D4337D47F54B2235BD1C23F58F217EA22A
-:10635000803CD072556F25600F38A8DB703286EF15
-:10636000944C731E6CFAD87C7F7AE3722998E727E5
-:106370008703FE09DAE9DD49CC7F9226FA0B00DEBD
-:106380007BAFFFA606F0FCC46633F967567F4D5A13
-:10639000FE6F69791068E2FEB6B4FCD5B4BCF1803A
-:1063A00097569C9763CA32940B05F02432F907BFC5
-:1063B000BE671DE478F85BCFDB582F5737BC35F844
-:1063C000C3E120A71D833FA4C4592D0591FF423E80
-:1063D000F0B5281C92998F09784F1362526E1718E6
-:1063E000F69B9C5A887494DCD2A98E98F5DDC08FF8
-:1063F000B2FCDDC11F8E87F46D4CAD7855A4200131
-:106400003FD068D713B718E0FAEF34E2A979C41F78
-:10641000A53873A4B0786A7A5E280AF37252FD092F
-:10642000EBD33D235F6BC5F081C50F3B94AD203F9F
-:10643000B48CB6615CB36578E49002F90C6A40D123
-:106440007A67CA5D21886D4CCD637CE3F4B3F5D4E3
-:10645000353C8C7E98A1BFBD1C1F5EAD1CF5B3679B
-:10646000A2D9DE31D601272BA2F436DB51CE94A679
-:106470004FC582BE7E9A539B761AE569A4B93F2325
-:10648000DED16EE3F18B6BC9B5683759E212FDE1DD
-:10649000CD6BF87113D9BCDCD34918FCE6F48951F3
-:1064A000C49BD7CFF066D89B1E3EBF9B4A2304FCFB
-:1064B000BE9EF8F3CD0C6FEBAF8BA27FB77EEC29BD
-:1064C000B467BD851D263FCEF81ECAA1FEFCC4766A
-:1064D000A8A1F618CB1B71238AA7E91969BDEB6146
-:1064E0002BB7DBAD7453279262D0634747A7158360
-:1064F000DEBEB784C24EAB3C7A589762F0ADF27EF6
-:10650000D47C86DF7BCBD87C697BF4D3EF9D9893DA
-:1065100004E366F2F8B0117FEEF1CBEBCD784F28B3
-:10652000B4C4852D7EB7EA67F4524BCCE5AB395F36
-:106530002B22A7572A19CEE835303E4F32F8BC84BB
-:10654000F17932DF37482FD10E011D924A99FF4D64
-:106550002C7EF34D291D8C5E378FC8003FFCFEA9B1
-:10656000DD3E669730BA26717EBCEFC61102C87157
-:10657000728926407D723EC35332C513AC77C9A5DC
-:10658000CCEFF64ED4B05D5209A35B0B7C4CE15FBF
-:1065900003748A891F3B4B5B75A07F6BF14E1D74A2
-:1065A0005932C5E1200ACFD4520A1BD89DB45F806E
-:1065B000D75318C5B85A524970D8A5FC7A42A2825E
-:1065C000CD87F8106C684BE93C25587E6862B22094
-:1065D000D07EEFA77CC0F180713C178FA3DF5F787E
-:1065E00012F5DCFDF04D36C8A9F6EB1C9A27A5364E
-:1065F0003FF807F797E608F1E2E7C6BCFB83CB2A32
-:10660000C712F83531FC7295C8E3DE16FE5D4722ED
-:106610006A2EC857486FF7A5F5EA0F83FF7AE4653D
-:1066200012E3CBFEF489A187DD2418B265F7D51FEC
-:1066300092CEF8DE9E174079EB03EF24C6AF528A64
-:10664000B9FC3691DB7F865ED19207142727A10023
-:10665000AE7722D74F4FDA020BC554F0BBC3B84E0A
-:10666000B8C874AE37199FCA9CFFA6E633BDE24A8C
-:1066700089B076978DA73A90DFD634A8A81F5AC65E
-:10668000DED59E43F1B06678931FBE738C6B19B94B
-:106690008DF6DB3C7C79702B0CC0FD30D4BF22AC76
-:1066A000838C5F8D7D30030E9219D2619FCC097E61
-:1066B00011E06724DB5F902412B58FEB1DDF954757
-:1066C000E1CD6769289FC10DFEC9EBB6E02A9C6F3A
-:1066D0007E6B94A29BCE9BC9CB6A21425C22CCEB01
-:1066E000727C1EB231BE8E9FF6F75D02ECD3C4E120
-:1066F000DFDD22DBA7592D478850087E1BED89F28C
-:10670000C9EA6C6A97C781A391F36BD52E67F8C36A
-:10671000187EAB892499F275FB33C21FC6FA117734
-:106720000AB84F51CDD158433AB200CFEF291AF6EB
-:10673000576BEB48837C17E94E5B027810038F8B15
-:1067400074FD7752BEC4B8907B60EBD6E5F0A781AC
-:106750000CD18540CBE4A90F79988E17DC07E3694B
-:106760002A2BBFD271E3F0F50BB17C4DC457596AA7
-:10677000E56B7F14F9DA9D12C57AB79FF1B5C18F29
-:10678000899C1FAD7C688CBF9EC7AFD6723E5F33BD
-:10679000A1498570DFDA519B309EE62CDA5C017CE2
-:1067A000DE32AA250C7CDE64F035DF17A1FE2EDB7D
-:1067B0001FD35AA3B04E2672BE56D4EE06907BEB82
-:1067C0007C5D9338BC3405BE06B8395FBF07F893CB
-:1067D000FDDD08AEC1D76B07CCD7BA456F9BD3FEA2
-:1067E000FC27D9C2D71E89F1E767C0D7004F0AB38B
-:1067F00063DC3E96CA7EEADFC7E9E70689F9996B52
-:10680000B91CACE572B0B61F39F83F22F303FE9A0B
-:1068100072308BC98143A2E58993AE8C1F25B0D31A
-:10682000E3C87B9E24FCB5E1DE3443BC723CFE270A
-:1068300030CD84BEF434D2CF44E7C0E43B8FC9737B
-:106840007F72BE76687C38FE5364F4A7F82E9226D9
-:106850005C39BEFF5A7015727E36F04382C528B788
-:10686000317A663AC02BA9869E7904D3A979AD28DE
-:10687000A786BE81580AFA2B6A2BC63B9C99AD6845
-:106880009F39F398BE31FC24EB7C8DB87813D73355
-:1068900049792102EB9F3D85703FAA9EF95199CC21
-:1068A0001F30E2D586FDA8187ED4D0BB709FA77993
-:1068B000783DDA97CD37D63BE2EDC336FBEE77F085
-:1068C0004D5FD33EEB1A5A0EFDAEC9BB9FC4B3C396
-:1068D0008C7918FB464E3E6E731EB5A8605CDF32A5
-:1068E000FCDE6AC73467B2FE7ABEE77A57EED1BBE8
-:1068F0002C8F76546E8C9F6FE9C7E00385E843A325
-:10690000103718E41E09E74C9A84043FD8C74D920B
-:10691000209D72901E7BA95A891640FF2766BC9C59
-:1069200085F6B23DB806E4BCE9AB8003E2A9AB53FF
-:106930005EF3C6969F9DF1E6B7C16CA5DFD5E27EFA
-:106940008E8348B1FB6327DCDBD17E4BC837C7E9B8
-:106950009C14AE0902C413CCE50A8FBF2899E672D5
-:1069600099C75FA4144B39E70FB934BE5E7993EB36
-:1069700015DF02764EE7C41C16D73B712B4F6730EC
-:10698000FE3EC7DB75F334C2F5EE5F531F25E5F617
-:10699000C2EF9BE2C7F822996547BB3E2B859D2B32
-:1069A00020B1E726E05F6BA24462FCCCA18197FF97
-:1069B00008F1D4610BBECA063C6B15EA615846DB90
-:1069C000A56C9CC76342F72818CFE63A8BFBF5020B
-:1069D00045E3726A120BF4DBDB2185EFBDC0523A4E
-:1069E0008F7B0591BFECC03722D0298CA98B44B195
-:1069F000DE433A309F081BE6B9E08751BF4BC433F2
-:106A00004C611BC68D7ECCF643D688786E83A80376
-:106A1000B4BFC9ED2AF89742887EE71AF877BE40DE
-:106A20006B31C8C4E0B208C693ADED7C53D839A031
-:106A30003E7AFBAF4FDF375273818F542C37E81CFF
-:106A400014F54E6942DFF25F8981F312C6AB58DC60
-:106A5000CD5A5F2AE91740DEACE5C20B7F3A057ECE
-:106A6000F4AA6764F4A3A73C2347BF41F3355B0452
-:106A7000F4536D079DE80F773EC2F2518FA243FB9E
-:106A800073DB058C07D5D9DBEFBD01E28ACF880423
-:106A9000FD8D7019EE8B9DE27326FB59BE9C07801D
-:106AA0006AB61C9A0BDF57ECB713D877A8796EF14A
-:106AB000B76FA0F9C5C764F4516A76AC50607F65C2
-:106AC00049588840BE6B32C1F143FBC4F00EDABEB8
-:106AD000CBDB9E36C70DFB2B0EA25D45E1F6B4A7BE
-:106AE000CDA6F4A90C3F350DBEABDC2DF8C1FF9847
-:106AF000F2CC8EA319F4BB9A27043CA750B5CB4522
-:106B0000B418BA9C6A13A3DF80F8339D27F8C58BAD
-:106B100049EB34C07BCD8E0D8A1613B73CD330922F
-:106B200068F6DE7CCD13741CFA5DED93821FA658C7
-:106B30006B2341E08FCEE79C65DBDC30BF15CA08D4
-:106B40000FCCAB5981768BC3F3F6C17E7A65788B17
-:106B5000328DD6573EB245298FE1A7AA5DD7102DB9
-:106B6000863F4E6DCE4DBFD47A7B86AE5BB1F0547E
-:106B700012A6B788145666C4EC7B76C8499C3F457C
-:106B800053FF06DF875E2718C70A3DEF41BC1A7422
-:106B90005BA632BD60D0EDBCCAE9287517CD88B3BD
-:106BA000AF7A2FD0C10EF12A15D3FB1B7C986E6CE7
-:106BB000D0903E9B007F57E1BE06967B279162886E
-:106BC0008B7875A2C2529F3C5D2F96214E1260F9C0
-:106BD000B4DB83827689F91BE92639380F825CB7EA
-:106BE000C94F4C96E8BABE49092E257E3ABEB47705
-:106BF00072C97560A705E7C8A9B09F1DAC60F1E830
-:106C0000880FE4A289EFCB7C4B66F2D694A1607C1E
-:106C100064D3F78BB6A1ED41185E367DBF7C27ECBF
-:106C2000ABD17EE6CA54AE1A65DA4FEEE5FB499B5E
-:106C30003BD1D44FDADC0AA39FC5D88F7360FD6CBB
-:106C40009A7BBD199EB995463FF5D88F6760F34A88
-:106C5000BB6392199E3BAAB19FF4DBFD681F8806B7
-:106C6000FF9076DC1775EF4E1AB796C4F2D1E41F89
-:106C7000C3781E2A55B17C943831C1244F497AB269
-:106C8000293FA874B0A97D6A20C7549F5E76B58558
-:106C90002FDDA8BF314F818A26B138AB325841BDB4
-:106CA000533CD881F9BB06BB51EFDC757DF02AB0AF
-:106CB000F70056D0F37729C1316A1CBEA1F3120840
-:106CC000C6CF341BA47DEC32BEEF3979C85723DE22
-:106CD000A7DFD7D9BA4724D1FC434AF12330EFAD1F
-:106CE00032B3E38D3843829DA0FE6BCE2EDA168A36
-:106CF000C16BCB50CA2F426FBF2D72D007FCB87347
-:106D0000F56F574A14BEA6A10A1E6E7A5CFEEDE12D
-:106D100010B5999B8796FB00FF7685EA8FD8F11511
-:106D20003A7E3E8EBF1BC6DF2B333BD93ABE3D6752
-:106D3000A2697C475685697C8742C7A7F2B16FF587
-:106D40003B7C7C8ABFEB0979567E07C7B76755E065
-:106D5000F8CD0AA9308D9FD033FE01909FC3FDCDA1
-:106D60003FE77AF3FCB32ACDF357D8FC8FAEFE8011
-:106D70008F9F80F37F59FE80CD3FAB92CDDFCEFA5F
-:106D8000ED19DFDB83FF5761FEAFF537FFDC49E626
-:106D9000F90FAB36CFDFCEC67F63F5277C7C378E0D
-:106DA000FFA6FC099BFFB06A1C5FB107FDC047CA84
-:106DB00090847AF09FA961A461405DA3E3403A9278
-:106DC000C5A937C83908C75D098CEF3E4FA0FCE65E
-:106DD000EED5A7244C2590EACB5ACED355BB8B15C4
-:106DE000E62F84D05F58C4415DB85FC4F58C6CB4A5
-:106DF000878753783BF78B21C82FDC78239E5BACC9
-:106E0000B313DC77A75630FA1FFFF1C0E8ADB1F33A
-:106E1000B2A68B5A65CBFE1383C738EF5424ABA6BA
-:106E2000FC2988A7503D7C12FC1F9A9E96E978B4F5
-:106E3000FC43F083AE8A951B762E8C7677229FCE0C
-:106E4000EBBB1CFE5312C3F7A93B05DC47F87CC320
-:106E50005205F4D9A25697C96FA8E374EA7ECE8E84
-:106E6000FB8DC679BE5B501409F9FDC16F1D05BBD2
-:106E700071F1E641A6EF6E27E1D5701473C1FA797E
-:106E800043553AFFDBCAECE3448C6BEB43581C9C44
-:106E90000C81B84959DB067908CDDC52269BECF908
-:106EA0005B83E6FC6D15E67CA71C966D60CF2C110C
-:106EB000C816DAEFF7EB65CBB900368E5749E676A0
-:106EC000251BEFBB948619B4E8FB908E836215E90D
-:106ED0003A5765DF1AF0D4DD2D9328AEC71DA9B847
-:106EE0000F144A45BF2DA8B2795BE19D2B3BF400FE
-:106EF0008567EE8F44C4A715FE8E832EDD46EDF325
-:106F00008ECD7F90217E6C9D8F15FE3B965BE7A317
-:106F10002AB03ECC0B59CB199F58F9A96E7FF13698
-:106F2000B33D7BF3B658FBB56AD70C537E49F85690
-:106F300053FBC59BE799EA17B52E31D52F68596ADF
-:106F4000CACF0BFDC8D4FE8EE52B4CF5DFAF5F63D7
-:106F5000AABFAD6283297F6BF02153FB5BCAB69851
-:106F6000EA6D07477D07E468D5EB229EFDBDE03E54
-:106F7000752FD89B17DC12EE737E44ED159083338A
-:106F8000D45E81B473FF78F4A7A91E2C874DA2F9B3
-:106F9000CA98552D99A09709EACF7265C2AAD02444
-:106FA0008A17B0D7A97C889B15121D04CE4C720F8E
-:106FB0001F778B31F51D97A9DF4C057D7CDF7AB1FA
-:106FC000237E79DDD679C3D4387E6AAFDC9221B0D6
-:106FD000CE7559CE9F1869B5E53CA7B1BF7D81EB51
-:106FE000D96A85E983EABD1993617386FAE523E2DC
-:106FF0009D9BECF93E22B00D48B0FE53811F869850
-:10700000F66BAA76E59AE4FBEC2111E1AA059D4016
-:10701000F5EA1752608D0272163D92356B34C0A1AD
-:10702000AF5540EFEC4FC575FD6C43E936D8AF3F27
-:10703000D310C0F4A386324C4F350431FDB0A10209
-:10704000D3930DF59876342CC7F4BD8610A6EF3691
-:10705000B460FABB86564CDF6AD88CE91B0D614CD4
-:107060003B1B744C0D79E8D1BF016E0F1B1BD784FD
-:10707000DBC37C2E8DA93DE7C270FFF7BCFBF3118B
-:1070800060EF9F7FCB8EFB6CFDE1CBCA6FFDD351D0
-:10709000477BA53C3C089D636BBD3381D1C9692307
-:1070A000A5641CECFFECF4CFCFC7BCC42EF584FD67
-:1070B000333C71FA85785DFAE5E944F4EE829994FF
-:1070C0001EA71EFEAF22E8F702AC7F60071C1171FD
-:1070D0001D26D16D7EA0D795E24D78E1F759102F8E
-:1070E0003BD783BFF62C888B5DABA8D8FFF9363B26
-:1070F00081F8D2F9032EBCCF75FED8362FC8E33203
-:107100009F188E3D47614D6B22D961B7C9EF36E7B5
-:10711000CFB70AA5781E9A6889B347035FA961387B
-:107120000FD2D9E0C3D4E867994FC171CEECCA65DC
-:1071300071337E5E83EC4E427EA57E27B6FF9F862E
-:10714000A7BF7E0C780869231F38085E71BB98DBE7
-:107150007FFB7EF949FA4C81F82A39207F0EF682AE
-:107160009DFE77111C652261DEE8B72E2286EC6356
-:10717000A07CB7693CFA9D66F8F417732EC5B7E694
-:10718000FB34220468BF469CA40AFE80F330F5025B
-:10719000C6AB8C784997E46E11C6F4C64BEA78BC4E
-:1071A000B8C6D1A10469D1B9B6DC4BEE9F9E69384F
-:1071B000A6C239AF0A47AB02CE4F45645409E8B9BD
-:1071C000736DABD2C01EAC12CFDF152F7E9B6767ED
-:1071D00071BD2561B9DBBC8E72FE20B45FA39C1D1E
-:1071E00072749F8AC99FB5313BDBDAEF04FBC0F6AE
-:1071F0002D6A771F9F7683D6174FB5FB3F55303EDC
-:107200002E11535CC9C0DF7B4A60829DE2A972D710
-:10721000FB688F7E248746DC7D09FDD4777E6E9FD8
-:10722000E97C7288B4C338F327F2818876CB3B744B
-:107230003DFDF815999DDBE4E7807BF695F9BEFEF0
-:10724000029E9BDF5685E7843EDEF78F68FF2D2484
-:10725000012FD281B416811D798ED84A014FE7C81B
-:107260006BDEF13174B8953A4A40EF052D663B86E6
-:10727000DABFA6FCE2CDE67C39999906FAA47CA394
-:107280004CC202CECF547FB35DC57E1793FA265809
-:107290005725EE8FCC57893484EAD59A677F5634C8
-:1072A0008FC211B4333FC888BF2C49667660654AE7
-:1072B00058817DC20FDAC67FF70620833DDC04715A
-:1072C000289248FC3B485FFC5E29FC56788DF5BA55
-:1072D0004F1C88C321EE12E2EE03D6DA056ECF868C
-:1072E000303DC0E76DF805C72CF915767EDE5224D7
-:1072F00022D0FD9CEA08D912B1DE1F8578DC5EBB86
-:107300007F950671FCC06A7B6A6FDCDF6897640F4B
-:1073100062F959E1D5723CF720450BF0DE218FEF81
-:107320002B9C1FC4046F019C23F540DC1ECE753AD4
-:10733000BD5B21DFE4A9C0F31F7520EFB4BF7BBCA8
-:10734000D38E419CDA415AA33AE55FBBCFB21FA06E
-:1073500099F32E904BD0675080E7A209C6B95C2301
-:10736000CDED3C7E73FE312E8F7481433EEE39DFCE
-:10737000E67047E13C0999289DEDF1B772C0DF63E3
-:10738000F0C3FD56687FA7CADAD7F27DDD3BDF9EEA
-:107390009C9E7C097D54F7A540C231EB489DD4AD3D
-:1073A000001FD67D2961F9D7D69B1A5D5563F4E697
-:1073B0002B4AF059FB04A627013E818E13BBDF64E4
-:1073C000BD877002F861422F3F7C6D385288497F3B
-:1073D000BFA7048FC583E36BF7EFEBD3FF09E0BBD7
-:1073E000FFB1FEF3FAF4DF110FFE9A67F7EC0BD151
-:1073F000F5B5F2170F78E110D3C7526B1A9CEFACBA
-:10740000DEB1DA0B72F99114F2025D3F0E8B71EF6F
-:10741000E7A63B0CBED3DD708FB096F3DD999FAF2E
-:10742000FB36F82F9FEF90558C0FECB247ED942967
-:107430006BDB9630F9D8657F9FE59BF1BC53DD7E11
-:10744000B3BEA87CFC81340D0F5585B8FF1C45FFE9
-:10745000A076FB7F4C03BBAB8E74A3DEB37E07E349
-:107460007F998CF6C03C25B16FBD710EAB8EE3A544
-:10747000AE6D1DDE13AF6BBBF934139A0EF43BAD4A
-:10748000DF5570BBDFE1309FDF34F042C2CCEE5FEE
-:10749000F5C48305EF53B8CE6E7FC52BE4C7F22940
-:1074A000D37FE7230B1EFBA5D6BF5C7552FD186B7F
-:1074B0005F1BEBB4B69FFB2B07585A2D47BDE00F5F
-:1074C000566F91F1BC7BF59E6D3B1F86F8CCDB7649
-:1074D000FF70DA7FD59E97DEB89EE6AB9E9253A6EC
-:1074E000B369B8E19EA2419F3AFADFF271BDF4A8F8
-:1074F0007CFA25451BCDCA7F9CDC4B97AAA70E2999
-:1075000064745F7C4C891C52D87EB6853E91F7A787
-:10751000815FB1EA892F14D05F1F1F14487A761C4F
-:107520007C6E7909ED63C013D293D3AB877E96F658
-:1075300075942EA8172DF4B2B6FB98AF07D02FC4C0
-:10754000E3297F3FF94BD8B7F99DDD0F78A878F292
-:107550009FBC309FD3523DE3F39FAD4E83FB20157C
-:1075600072284DC59495573CFA03E4BFC5C77F9078
-:10757000C6CEC5EA19FC5C5706CC73D12373709E46
-:10758000E524887C58F13376CFFC82444A9F8A23D5
-:1075900027F739D83A767AAB1D37114FC34202FB31
-:1075A00018AF89E11D180F64E70D7F60EC3F91650E
-:1075B00098BFE060F45AE430EEF1D1A524967FB78D
-:1075C00037B7039DCE0CD5D3218E5C47A410C78757
-:1075D0007091F62B1E9F9ACECF1D685211FF8EEA36
-:1075E000FF29500EEDDB65DD5960FA8E5CCCEE1D97
-:1075F000FF4E3E3E853B01ECD7D369D41E8C33BF92
-:10760000030E639DA676560C9FC5C83B93FFED6B9A
-:1076100098BC1BF21F9E510AF59F9D607204DF818A
-:10762000FD42E18AA663FDA1D902EA073B89C69320
-:10763000F3ED32977373BD955F28FC12ACC73D7CA8
-:1076400003E324231DD0BE2DDF48BF8FD5AB30AE62
-:10765000B76FBF861C2FE6FA60AD451F90475207F3
-:10766000B47F5B2D87773E0CF24BE535A481FCCAD5
-:10767000F85EC127BB8FBCF13D2AB79F440CB935DA
-:10768000EB55ABDC56EC9D40E2C9ED276E3F892BF4
-:10769000B7B43CAEDCBA3B909FFFD67AD5C0E3D3FB
-:1076A000163C1A7AB23F7C5AF5E4B71D5A5C3D4944
-:1076B000FF9D20457DF9D1E04383FF2AFFA506CF3A
-:1076C0000BF5F0A9C1873D7C6AF0619F78A4098F12
-:1076D000D6FABBE16F3A85C07332C6CFAB0FB0FDAF
-:1076E00067FADDD12185882F1D9739D27A74484AEF
-:1076F0006C3E6CC9472CED754B3E60691FB4E4EBE2
-:107700004DEDABF71F51D8B99EA8A99DB8FCA7E4D1
-:107710008338F101631DAA6BFB5409017FB8BBF1EB
-:107720007B79250979205EFEBC88F1F22E8AE3265A
-:107730003A4ED7EE6C7C8F60B593C557BAD46E2F96
-:10774000D893AB9358BE3B5569023D6894773B593B
-:10775000DCAF2BD0ED4D8AB1EFDE3F20A21EEF084B
-:1077600093D2787E28DE40A1F8ED20FDD5B3FD80D0
-:107770002EB0D761BC84AC30F0E354D19DB51CE28F
-:1077800035AD22DE6B5BB8E2162F9C23E93A90FB05
-:107790009D325ABEE8D722DBA60CE952468C1FF870
-:1077A00011096D9A24C0FEF57AE49F0507985FB829
-:1077B000707D7C79A8E4DF95BBEF5440EF527FEEFB
-:1077C00064ECBE87D14FC52396F203FFC8E5A6152A
-:1077D000E31F95DBCDF5411E3F18ECE4E7BEC792F1
-:1077E000B1DC7FB7C5DE0F9E2AE67FA78CD2A7EB60
-:1077F0009848E03CC1F90322D2E7FC6E767E00E3B4
-:10780000FCD701BF772BB1E7A9CE827C5DD5BF1E27
-:107810003BFBCCEF8BEE063EDAF74EC14F697A7632
-:10782000DFDB237E05F967DFCC7A87F46D3FE5A0C7
-:1078300013F755BA0E7A90FFBB9EFF4DD6DD907FB1
-:10784000CE8EF1ECAE835F14003F75ADB457801E51
-:10785000ECE2E7EF563DFF454107AEBF8D48C7A9B3
-:107860004EE64F9F3FF05FEFC1FD81F307E8ACC0EC
-:10787000BE38E842F9AAFBA513E36F5DCF7F511430
-:10788000EB27FCA5F3A9E5FB9D5D1E52B617E04B67
-:1078900062FB4475BFBA6E1BBC2F51D3764859406A
-:1078A000EBA7BCF0A702D0AF5D7B99DDD429773C74
-:1078B0000AFB7981350F34CA945E9D20648369FF89
-:1078C0006BDE280139EA8B973F615C71A0F858FCA8
-:1078D0007F0D3E049DE93F4F184C852907FFF8DED8
-:1078E0003BA0270EDA912F8DF97E125981F6CCE557
-:1078F000E6DDF4FFDCBC85E840E6BD03E63DE1EFF4
-:1079000077DED7C0A1A1D4BE72D097CF9FBF0BF3B3
-:107910007B3C7E847780FCFED2DFF9FCAF98EE7B67
-:1079200029DDBD979FF7877FE7F3EE9FEEBF9ECBE4
-:10793000E9AEC27998BA17FE84F05DA99E9312FE53
-:10794000BEE5BDBFF91BF6FE5A9BBF35271BCF9383
-:107950003AC0B0707B66B6407871EDC8992AD89D60
-:10796000623FEFD54C48607E9528B0F721C850168D
-:107970000F24DCCF82630DF80E889BDD3B93DC4D3A
-:10798000687713C9DFAE53BCACBD7ABE1FCF1A9166
-:10799000716F05219F39C98FF16E8BBFD928105D9A
-:1079A000A0F6AE74F5378F81DF238FB445ED0598CF
-:1079B000BE0F69338F63CAAA62F287DCF9E6BC5353
-:1079C00033E7EDBC3F0761F03B7C240CF16C71D4D4
-:1079D0006115CED3896325024FA538496B08FC0E8B
-:1079E000BBCFFC7D5202E17EEF5F86C78A0416A7FB
-:1079F000128571ED3AE071940DE3DC78481BF1E2F9
-:107A0000C7F7BA08F7AF7BF1DAD40EF894C03F6637
-:107A1000F617FAD584FBD312EF421A69D39DE676A6
-:107A2000DC8FBE2C9D185DB2AA399D9699E862D074
-:107A3000210E7D4C7431F07CA5F4B1D2C58AFFEBE8
-:107A400013185FF7472F832E996E1DEFD7C9DC7F80
-:107A500028013F13F2990182FBABDC7F905274BC8A
-:107A6000A724AA7EBC97007E5C941AE02FEFDE86E6
-:107A7000F1A4733F7FFFDB004FD5AF44E2A0F8EBEA
-:107A8000DCED2151F85E0A2BE09F56B689B84F40D5
-:107A9000A468D1AC987D62C30FA8FA8507E753B9F3
-:107AA000D71E9E4EBFAFDCF74101DA612BBBD1CFB1
-:107AB00009FD5C60740F7514C03E70A5C4FC112BE9
-:107AC000BFAC4960F196B3CFB9CA20AE23EC62E7F0
-:107AD0007F2B23B7C8F698734DA10499C59B9E735D
-:107AE000A15E083D21E0F928802FF6DCA9E1879C02
-:107AF0007D4260F0ED97F19D98CA5D4F75427CAA7A
-:107B0000F22DBB1FCCF8BA5D9FE27EC8945FECF10A
-:107B100076A01F2E9AE2127DE201BB44E48FDAB612
-:107B20001AF443681EF9A236C2FDEF2BF457AB7E60
-:107B3000F1FC3EB87056F5F4E35E887F9D69DFE1A5
-:107B4000C5B8C0AE4BC7E7FAF8FF9135DCFFFFD6EA
-:107B500069764F3BBEFF7F06FEA076F1D30996FB08
-:107B6000ABBB06B1F71449B4E852EF7155EDB9F06B
-:107B700028C4AFCFEEFDE45180BBFACF7F7814FC70
-:107B80000A72D0A9C27D82BA9FBF8EF13EE3BBDFED
-:107B9000703DD0F9C4E3182FED7C9BFA1FF45FE72A
-:107BA000F3A7B3C0CFEC7CEA8F69104FB9F3F9A902
-:107BB000F86ECE9DCF4C492771F4899102FF86075C
-:107BC00010AFB5D2ED48DB11F47FCE51BA83FFD9A7
-:107BD00013D789D4B07899C6E339BBE3C7C7FBC4D0
-:107BE0006FDA667DE7C6424865BF460610C7394171
-:107BF000E939660074DCCDE375916F5D328E730EEA
-:107C0000FEA0F43A6BA1E385B6458F3D0C756D83FC
-:107C1000FA8DE34407803F23FEBE3F41FF2201E48B
-:107C200068EFBF60FC0CE8379D4EB873CF852CD849
-:107C3000BFF848EE9E8BEF853C6F57211E51F9FC33
-:107C40009B284F9DCF1CC7F836E171F04ED2F38FC1
-:107C5000C52BF999CCBAED1E16FFE17480F890E6B9
-:107C6000C5721E07627C6DC487FA8B0B8D71B17370
-:107C700027C6BE40CDF67778BCA5976EC244A0D784
-:107C8000FB97DCCF30F0A0021EAE8D8D7BC68FC37C
-:107C9000F5C43D2D74037A42BCB327AE49D8137B9B
-:107CA0007561E1CD7871F4CE2D2C5EDA29C73F8F56
-:107CB00065C441AF7659E29FE181C53F2F378F2BD5
-:107CC000C5D3609786FD5AF175F6ABF8FAFD5BAE49
-:107CD000819D5FE8777FADDA7C1FE63D2538DD05C5
-:107CE000FB6B6DEF2B04CFA774B3732B7CBE67F9CE
-:107CF000F9D3B33F17312ED6143982FADDAA3F8C5F
-:107D0000FD572BBC7770786BF7B3F5E3EC5E4FD87B
-:107D10004DFB397BF839E4EBDADDEF635CEEE8AE7E
-:107D2000A7958E98F516D68F70CC7CCE3E79A8801C
-:107D3000C579E3DF1BAB71317BB3EE40FC71EA76B2
-:107D40007F6A1AA72A1451981D70E9F1CE48FA2DBE
-:107D5000D0DF997619DF4D3A1311E3BE171C70C9B5
-:107D60007C1FA195C90F5D47F19EC071767FA7F07A
-:107D7000B5043C577FE7F1D277E0FDB73BA95883C4
-:107D8000DDDFB682F169DB4FF42140EFB6E3DF13AC
-:107D900061FDDA07F88DB1FF8B4ED44FF150FD50E5
-:107DA000F46EA010D8D5AA77AE7DCB66829F8E9355
-:107DB0000EEB4223ED07EE83C0B939BC57EE9D565A
-:107DC0000AF088AA4D750A7DE721BBF97D55DEAF23
-:107DD000AC9AEF2190AFC66BD08F6F268B4B66CCE1
-:107DE0003252169F0C19F787CA13C2ABE87C7FAFDB
-:107DF0000637BB285E7C9E8DD92F1178276AA20694
-:107E0000F6D3632E7EDEC14BBCECBC833B64A37A0D
-:107E1000FD61FFF60D93089E67D8067CD9739E819D
-:107E2000440B802F8D767DEA2DE71D32E1132A5A0F
-:107E300022873317EE2550FDB26A86772BE41FF1B7
-:107E4000B0F7CDB248F72138DFB08DDBA3D960158C
-:107E5000E7F67DE7ECEBBE6F9632A578E9303F851B
-:107E6000D3F55F53E15C7CCA2DC54F0D5169852D5B
-:107E7000631ADCA34979BC786C06CDCF5FFFF4347C
-:107E8000ACFFF7E2B15934FF937B0EB2FA2A01CF6F
-:107E9000C1BEB0AE761AF0EFD796FBD9143366B9EF
-:107EA0007F05F0772EF0EE77176970AEA25BE1EFF9
-:107EB0006504A0DDD0890C7F99EE779F027F6598DD
-:107EC000AD6305F0EB63CF7F9184F716F9FBA12A30
-:107ED0006954E1DC152D9A78F112E7F3FABCFBCC7A
-:107EE000F5CB8D49C177813F9AE78DBC6F1A1DEFA5
-:107EF000E18A710E760ED0F24EA39A82745DC8E9C3
-:107F00004AF83DCB457C3E8BC590C202DFAD5C7F1D
-:107F100019EF51578B57F41E3587ABDBD5EFFB6755
-:107F20007F00783393827F00FC59DF3F7BC515B813
-:107F300000F519E55FE27D5CE33D33EBBB6844EAA5
-:107F40008EFB3EFB56FE2E5A7FF0FE9B3B28BA6905
-:107F5000FF392F687B8F51391BB350F1C3D1CF311B
-:107F6000CB0BFDD220C226047610A71F3CCF88F78A
-:107F70001FEE22B85FDB651774F0AFBBFE49457D8D
-:107F80009EB9703AFA5F5DAEEC089C33EABA5BC307
-:107F90007D3D8A0101E469E881C428F887541E3ECA
-:107FA000B7C8C3E766FE378FDB7551DBDF81FDA9FC
-:107FB000BC3F6AA0C5DC8BED12999EEE6AD0108E94
-:107FC000A1247408D6FD818E97E3E6EB37A7CF4650
-:107FD0009B9EEB9E80F81FEE8EC1FF2877BF74CC6E
-:107FE00077333AE6BBE3D0D1FA6EDD7BAEE058687A
-:107FF00077BAFC28BE5F677DAFCE4ADF3AA9F5218C
-:10800000783B2BEDC0A7B8FE18F41BB37C2CD2290B
-:10801000869E93008E31073EB501BC061D1FECE71E
-:108020003C79A99BAD73D6F1D2CA3A0607E3B49F57
-:10803000E5D64CF70E0A1C457E89CA69BA8DC587FC
-:10804000FAB6EFB7FF9C4B9DF32C5059BF14FF734A
-:10805000004F06FE6F75F3FBEA7DF17F3BB4A3F89A
-:10806000BF1DE63F00FCCFBB14FE0DFBBF8AEB87B4
-:108070002AD89FA27CF41FDACCB41C3AEE34D18DFE
-:1080800072B06487C8F731D9FB5F863E59725DFDD7
-:1080900021B817B9E46702F2EB42FEFEE527FCFDCA
-:1080A0004BEBB9C1F2B210EACBCB9F1F0CA33EAA97
-:1080B000DA652EFF6777CFBB975978DE172435AD89
-:1080C000F7BD4E2BFECFBBB9DE58E8B4C57B2FD72A
-:1080D0004887D6DB4CE7CC33A6F4F483FEA0CFA6CA
-:1080E000BD89F1B87F9509C4137429A510DE192044
-:1080F000854209F45BCCE5D7E86FD872F3FA9F1D8F
-:1081000032DF43CC6D31DF431CDE6ABE8778D56633
-:10811000F33DC45161F33DC46B768D33E54747AE03
-:1081200037B51FB37FB2293F36FA4D53FBF1C7660F
-:108130009AF213DABF676A7FED5BF34DF5D775549A
-:108140009AEA6FF86899297F63F73F9BDA471731FE
-:10815000FD78B8617911DC5B30F07278A96253A1C7
-:108160007CE9089B5A105B9EA66B059016E9E07FA0
-:10817000F5272F531C3F2A8A5DA78B896CD26F533A
-:108180001CE67CD46DFE7D8F972C7235A47E52CB7D
-:10819000089A1DBC240FCF6353F93AC6F5DBB10131
-:1081A000EAB7DFA07CD5469B206F952FE3BD019AEF
-:1081B00086D88FADB0779F1F729AF9D4D78F5EF9AA
-:1081C0009DDB3807D4CAFA53CBC64B263931CA3F98
-:1081D0002A8C2D17164FC77340FDF5ABF8165CB30C
-:1081E0007D10BC3B3C0F53A3BCA9CC16F7DCDF676A
-:1081F000EEBFD07FDADCC78EFA0CF07CCEF7DA2641
-:1082000038BF567B7B37FA511976335E7AF3EC5DD3
-:1082100063039E471A483EACF7C6FDB64534E1EB12
-:1082200036CE77D1DB33D3E09C41663FFE55A18744
-:10823000E9EB471B42D72C04C21187E95E7956B49B
-:108240006E1AF839C3F879EB4DB6F8E7A0923C0CFA
-:108250002FE9A048C15E50DD682F9C2B7FD70B4FC4
-:10826000C7DC680F2679E838F3C7B417B1FBD4BA76
-:108270007FE6E85EB80D7D94E50E6C02FD92E59315
-:108280008896DD179EF4DB832DF08E7863B2CDEFF8
-:10829000C67CB700E3D97F4CC8203A5EE39F458493
-:1082A000AFF1F075783EC8EEAEC7B8AB314FC2CF74
-:1082B000091871E60BBED98980CFC6AB7BEE07E10A
-:1082C0007B9017DCC176E8F7C24619C76D9C2C98E5
-:1082D000EA8D794B9BBF8DF7BEB2DC6CDEE574DEB8
-:1082E00000B73D93C1D5F8A8403211AEFFBDF428C8
-:1082F000F835FB5CF8DE07C5C710C0C7393DFB7316
-:108300009B31793AAF9A41EEAD6BD19E89EFA74E82
-:1083100037E6A18F34D13BE32A33FCE24619FDC690
-:1083200045496E3CEF106E8872FA9AE7DFE49BF9DC
-:108330009D5B295CAB4E88F8DEB6D6D1BAF428FD39
-:10834000AEBCCDE50F6B7DF17F4E63F052F8A77B9D
-:1083500040DE364FC3F9E3796A80FF31813C9C0DE2
-:10836000FC172C453E186C23B06FD3C74EF0307904
-:108370009EED51D97B35BE722687BE85D76CA7FD91
-:108380009579FA5DF76FF3B075FF364F9C75FF7204
-:10839000EF075797B51F8554D445B43708A91F1167
-:1083A0006B47533D560EFD1B7931F1C705D06FFF6A
-:1083B000769ABF6544F6E5ED34B0CF800F0DFBEC47
-:1083C0004E8FD9AE8CD1BB3FF430BDFB43CFC0F450
-:1083D000EE8FA1FDE9EF45E3DA35A94A7CBDF7B49C
-:1083E00087DD1FAC531582E703FBD90FD8C9E5DA47
-:1083F0003AEFFED6A5CBF91F392E834FCDFAFEFCFE
-:10840000312D11F454CA0742DC77B7862CBF6D3C7E
-:10841000D06B9BAD7833CCF76716FE78684D9FF52F
-:108420002BCCF1188E8BC76A8A479B098F3B3C97F0
-:10843000B00FBFB6BEAF30DFF3E9E4F8A67ABF09EC
-:10844000C63B37EBBD22886BD4CEF91CF5FED71E98
-:10845000A7CCBCAE187E391D6705E0A173D69F7905
-:108460007CAE03E34AAB9EB92A11E25835930D7AEC
-:1084700044F07DAAF3F939489773FBEC3AC0792EA2
-:10848000999D133DB7EFDAA310F7F8A4E158722CC9
-:108490007DCF3D79BC48A6FD9DDB7BBC48C2037700
-:1084A00061D33BD435177F5B1470F7DE4BE8E137BF
-:1084B000075B8F363A597CE54138173786DABF6A51
-:1084C00012F2657A9AED5E28171DBF1DFC215C39FA
-:1084D0003FE62FA659B24AD03316C17ED33C37EEC1
-:1084E00067F972C9C86CFA9D12AD87E3CCC4F96A0A
-:1084F00098C0EF04B84E44F1F7023CEF7660F83EC6
-:10850000F143B2029EC2FFBD1A3C09784F3AAB0953
-:10851000891AC4778A6E1E4753690AD3BFDDB73AFA
-:10852000F0F78C8405AFAA53A8FEDA3C93FD8EDDEC
-:10853000F9630B92C01F695599DEF20DEBE163B44C
-:108540008B07E76B371723E6757C574055191D924B
-:10855000336C6B8A358CC7F9F398FE25521AFF3DB0
-:1085600029CAB71ECDA6431CD8F8CEC5BF2B52FCD6
-:10857000BFCE037846DBFCF04E8FFBAB6F38CA9260
-:1085800069FBCC28BE5F5E94C0E19DC3DE07EFFBB4
-:108590004EE345D37D18B5D4FC4EB727D0B414E2D2
-:1085A000FCD0EF6DC9F8CE8BB99EA2389196BB0B6B
-:1085B000CDE5AE0A9A8FE147EB77D6F6865F92AEAD
-:1085C0003238F63738100FBF6C50FD79948F0E3467
-:1085D000F8307FB041C334DA3012CB0F37F8312F87
-:1085E000DAF46C984FFAAF7F9014BBEEC2EF549D53
-:1085F0008CE1C37572E4ADF9808FDF8888AF15AF69
-:108600008E47FEDE349A8E3A86BD677332C6FEFE12
-:10861000E9F257D24A285F0DF9D1AFD34AC6C3EF6A
-:1086200096B0F31770413AF61EEE7A25A0F993E062
-:108630007734C6343B86C2FBA4C15BC9589423FD82
-:10864000C589F0BB0B7B336CB47E9A94D7ECF807EA
-:1086500080ABDE64E7AFE7E7331F9F6CD6AFE3BCC8
-:108660004CFF660AC5E3BC71F8097E5300FDAC39C6
-:10867000C6B907331E8954BFE1768AEBE6EFB3DF54
-:108680005F4854C7FBE1BDF7CD5EC3CEA9F7C5BEB9
-:10869000E7BE99FF0E44E2E1256817293EF63B103C
-:1086A000290A7B0F8904934DEFEDCDE5FDCC06063D
-:1086B0009AD0571FCFE6FD151D790EFB83DF9788F3
-:1086C000F5EF87F0DFC3D8CCF5D3743550EC4DED22
-:1086D0006D67D45BBFEB59776D21D10BF6430189F0
-:1086E00080BD04ED8A69BBD40F0302DCEF33CED723
-:1086F0003E0BF8CDEFFDDD937D02C3EB933C7D8A0D
-:10870000FF4E49D4139807E3FB163C12DA0376CAEE
-:108710003EBB06625274E48FF87E94F83BC501E7D5
-:10872000FC530FBCCFEEE5D93A1438BFB8D25B7C0E
-:1087300013C45145A53E03F3F74E6F81FC839EFAA7
-:1087400087D8A3DDC537011FA4F3F706080400018D
-:108750000E08AAE18F63FD43B34E65649FCCF22BF4
-:10876000BD37368732215F3F0FF808F28DB4BF7DE9
-:1087700049C121C0476EE186E6633742DE687F0368
-:10878000B6FF895765FE8F3B980DF64A4F5EA57977
-:108790004F4C5E6279E260A931BF9A237FC473D0E7
-:1087A000B507D83B5DA907660830CFD4FD3310FF6D
-:1087B000E7D5B7BC2B348C878F60EB048B971BF409
-:1087C00030EEE1A6D983F77963F8619DD76CC7C411
-:1087D000DC27BC0FF0DDD31F8FAFCB36F69E4AF7F8
-:1087E0008FD8EFC60D037B5484B8B986692EDCA3FD
-:1087F000A7FEC170125C3998D65FE3CD413A5EB5F1
-:108800003BFBCDA95A2F5FA7642977803E4EB5F870
-:1088100035D95C3F8F508B7F93482B370AC1B5F019
-:108820009E6C688FACE27D935D19284767B98E22F4
-:10883000F583315FCDEFBFCB2B836B47811E59C4CE
-:10884000F46E5576A058A6DF573D978DBF0B67F0A5
-:108850005D5552246D9CBBF75CB791377E47E42190
-:10886000B5D509EFF218FB5AB5FB3764C13EFDC719
-:1088700087DE463B71496236C259D3765C81DF6937
-:10888000A96DA37C47BFFBD8D963C7A35FF287C894
-:10889000A06F02BEFED068C3CBDDFDD9552F52FDBF
-:1088A000A6D385EA688303D39D7AFDD5E00A9CF0C0
-:1088B0002EB8C949F9E9F11C5D05FEEABCB71EF501
-:1088C000D8E38A3A0AF8AFD3FBC366E0E7AA24915B
-:1088D000F3EB0F5FD6F3F87E3DCDEFB9B7EDA6BF52
-:1088E00068DF60A1D9FEA97BC48DFC41ED92DF0257
-:1088F0001FD56EB68560FDB339DAF1BE7327E81B6C
-:10890000D45FE6FB991B05A60F4373581CFA72F758
-:10891000342BBE7491708CFDBD2491E9AB0A29847F
-:10892000FB76155F7AB1FE2F1FC769BA0FDA771C85
-:1089300037D61BE354F78E837C52FDF661F4CF5F8C
-:10894000BCDAB0AF75D4FF773EC5CF6138F574E8B7
-:10895000E741D9D027D4CFA47886E71E793E24F901
-:108960000879A947FFAC6D2EC904FAF6D613B37E79
-:10897000D2254AB79712783E747F73C9A438ED1395
-:108980002CED738CFC4FB17F2B3C0F3A7BF30EDA4E
-:108990005EFA93BD270FF06DB059FA4B36C6DF86ED
-:1089A000FD19FCB7C7BBFB6578EFE9A5A440F11042
-:1089B00066DF6820875B24157F87D1C0F31EBE3E2B
-:1089C000557C798D09FFBD782F30959F6ED04CFB7B
-:1089D000A18B172EC37B3F7BF83A564142EC3EDB1E
-:1089E00023B9A67DD0FF0FC7D785A3B81F384AFE8D
-:1089F000C6708C32E9815E38F24DE55F170E316941
-:108A0000766936EC53ADB1A19F90660B3972C06E9A
-:108A1000FB5FECF71A203407E799A8616CDA57CEB0
-:108A200039609F07C6798E448E49E3409E746D0578
-:108A3000AC533F91D0AFA1E50E3919866ED5E1FD5B
-:108A40002B2A95D85F4E75B08619F5E6776287AB0D
-:108A5000A458A2E5E3D579B8EEE594DD5507F6FD17
-:108A60003677E1CF571393BCA27DB25A588AF6C726
-:108A70009AC4179B61DF383D81D9330279B1F95827
-:108A800046BC7A26AF2DF7BD7813C431B6AED4AE4E
-:108A9000067F6EAB331C390CEBF93D6EFC3DAADC56
-:108AA00075E116F8BD0A71830DD74B3129BC6B2BCC
-:108AB0009C177860841FEC8BAD60D740FB356E5CF3
-:108AC000FF5B1A42682FAFE2EBC0F6F5935438E72C
-:108AD000DCE8969261BD6B91EB6F05B85EBAEF640E
-:108AE000B3E33AD063FE96413CEFCB80754DCB713A
-:108AF0008CE5F514195B576883C18534F2C3FF44D4
-:108B0000AD12D43327D10E6B742FAB043B8ED6BF7E
-:108B1000ECA0787A3C99E385D7E7F4E8A593CDA05B
-:108B200007C515BDF9123AEF1D3F637AEA09DA3F2E
-:108B3000BC2B45E713827718BB4749E8872524C13A
-:108B40006FC7D074740EFB9D5BAA17BDE8C7493888
-:108B50005F631F4919C57E0F1DDAC37A9390918315
-:108B6000FB98CA0CF65E83E271E3FD66E37756DD9F
-:108B7000C4F8A7B37829DF677159DE4370AE5F8907
-:108B80009BE94E783721864F15CB7B0B1209CC071A
-:108B90007B4B54CDE5BF49E4FB4A83D8EFAD0EB71C
-:108BA00085D02EA35284E935248AF6D968D281F97A
-:108BB00031E06DE6C2352C0D2F8E8D27BAC8E2BB91
-:108BC0000111ECC7B45B8D784CF0F544BADEBF966A
-:108BD000C8E336FC778C536614E27E7D6612AB5F89
-:108BE00015C8BB0FECBC8D33A6619CC6B0EF8CF5ED
-:108BF000D2B0DF16729857AB425C7BC1B0EB163A2D
-:108C0000593E75B6FEE068886BB6530B341BEE2FE9
-:108C1000B3F86AF9E6E234B0CB161EBA15EDE44CAF
-:108C200095D9658B36CE5082A3E1DEDA3CF4078A13
-:108C3000374C48847D84D54E7FE27585E867E2FB3A
-:108C4000B903B5C7B6A65D3519E471AB8D1290CAEC
-:108C5000FB4BB2EE1E0B7CB1210FEDCCAD09C1C6B2
-:108C600024DAEFD67FD6FCAB68FEA74EBDF0388C79
-:108C7000B33A81D5C3BB51C09B3DE712B6E1BBC936
-:108C8000FD8D6F3D97F052127B7FCAA8FF6F537E18
-:108C90007C7D0080000000001F8B080000000000A9
-:108CA00000FFBD7D0B7C94D595F8FD66BE796566A9
-:108CB00092C963F2220913C24B5E4E9E80224C126F
-:108CC000C243B44C102A20E8F03490A7485DDCBAC7
-:108CD000FF0C043050B60657112BEA8462C5AABBBC
-:108CE00041A31B35EA8080B8D66D44DAD216FD8FD9
-:108CF0004A1510488AB5D2FEDD65CF39F7DECC7C47
-:108D00009319F0B5FFB4FE3EEEF7DDE779DF73CEE1
-:108D1000BD73E912FC4D612C94A43056CAD8C151E0
-:108D20008CF58C618CA9DE2406CF4D066FD2E2341F
-:108D3000C6FA7EA367BBE1F517666F92C3C6D82556
-:108D4000D12EFA79AA99B1A089B1B3CD6E161CC102
-:108D5000D8996633956B961F98C6A09F9A0E85B9D1
-:108D6000F2195BC5DA36633FAF3B9269DC55013DD2
-:108D70000B8E64F47709FE5BBDFC28D55FDDC9EB83
-:108D8000D7B20EAABF92314F073C6BF75A59D01C8D
-:108D9000AE5FDF51AC691F4AD251BFD725FB063BFE
-:108DA0009C8CDD5B3DFCBE2A789F565D62F6E1FA45
-:108DB000588EE313ABA8AF87F73AE6EB88B1AE77EE
-:108DC000045CDE49828A4EACEDD0B132C6D63AE0C0
-:108DD0009F2EC61E50D87C6CB7F6F715192963C2B2
-:108DE000EDD62A9E0CC798F8706ABCA86781D48813
-:108DF000B2DA67C4F5355E34D2FBF30EB35F0763B6
-:108E00001EC9F43F702DAC7F26EB5319CC539F90B5
-:108E1000388E5DCD588B2571373E67BA0C7DA10821
-:108E200038303353717E33F82BF6EBC469479471B5
-:108E3000D83E40ED67D98EA90C4073C45E7303839E
-:108E4000F737B090CA0A06CE0FFAFD28B2DF5923D1
-:108E5000B5E51BDDDAF2EC09DA32637E82D74F9A90
-:108E60009BCA4E1AC2FDFE04A6D611032EB70258A5
-:108E7000B17EED5E4BE064041EEB3B9235E5C6AE81
-:108E8000ACC0C988716AF11F59F05F135F779D58B4
-:108E9000F70746DFAD0EC05B3D0B1971DD40C146E3
-:108EA000EF58C6AC16E6457C1DD86FF1B012E8CF7E
-:108EB000666EB7007C1BBBAB9525F0DE6A87EF3092
-:108EC0003F2796E16935F0FA8C05880EE08FDA3994
-:108ED000BD99ED5B15E413B7ABDAFECDE7DD00FF1E
-:108EE000DD93024F953DAC2446ACA30ED6911E5E99
-:108EF000C739EB0765882F58CF6FECA5481746A6F2
-:108F00002485D7F3ADE1B55C0BAFC65D36A237184B
-:108F1000E7BD4418A761A7CE6F84B2CEDC63447E60
-:108F2000B917E93C06DE721C4A4C3C6F433CC7E073
-:108F3000A7EDACFC3EE4C71CE41F18C7B6EE2765DE
-:108F4000278B818FAA3717FAA0BE4D05FE86715474
-:108F5000F8BFA908C8D93B6D5532D0E9293BE7C312
-:108F60000D892E7AEE50BC0AE2355DE7C947FAD585
-:108F700027B843CCC1F1A366421960CBAEC162F9F8
-:108F8000BD1EE8EF21981BCB168409F078C8C2CB30
-:108F90002F39CAEFDD08E36E4AE6E50D3FBDB9D5CE
-:108FA0003F09CA16599E43E5870C6D413DE0DDFF40
-:108FB00082C9F5443EB5F728585E3032F0044C4D76
-:108FC0003F8465235EA62642E720B7F42F9A769B5E
-:108FD000A05ED0EEFB2784A75CFF39FBF13C362670
-:108FE000667F7E4D7F79DFAC3F18BF537775F8FB06
-:108FF000D4C49D413D6FE7C2762CA7E7033FF49FA1
-:10900000FEA2896D85E22306769B17DAD55D2C6377
-:10901000C10839D423F079B6D941725BBEAF43F9A8
-:109020003D06F9A987E4707D47AA46FE4AB95C7FF0
-:10903000F15A4D7F398E7CC257BDDA43F2ADFEE264
-:1090400064FA1E12F2F46C7326E989F8E30CD2C8B4
-:10905000F5F0381359B0F872E34CA2EF721CE6CB6E
-:1090600022B9BD06E70C24A43782BC87712E0C758B
-:1090700025255F469FD976029145AC679B1A3463DC
-:10908000FFDBDC071CBE18FC20E544B8BD51DB1E2D
-:10909000F4231B81F4ED6348B7FFAC7ACC91FAD48A
-:1090A00066F038506FA8F68A232E37344D7E6486DA
-:1090B0000A286951393D7FD9B681E8D16E701F41C8
-:1090C000FCDAED3A971FBEAFB7E93C48272D0E7387
-:1090D00000F1BD51B9C1817243F66B07318FF3B80E
-:1090E000601B427A3DDE7AD58B89540F669219A9AE
-:1090F0001FFFF7C683C5170F1C8FBD31F1880BFA10
-:10910000574B746E0BE00B91FA71041D44F763DF4B
-:10911000A9C69C77743D09FFB8F836841211FEE7A2
-:109120006DBA198118F32E4D56BE9B9E5A1425DF39
-:10913000937F3B3C88ED95D00F0AF249FE9626A31B
-:10914000FC2DBC9058E922399FEEB573B185E3B68A
-:10915000D88E9A7DA48F98ED13D9BF3E3EFD49B8B5
-:1091600018DEAA64881F6004867AE34A70B02B4137
-:109170002FE29715AA0CE5D3403A6FA7F9F4D777F9
-:1091800043E711EB6F51DD0EA46BFD751E33CA99D9
-:10919000F58E39E6109437AAAED9F92087FADE02A7
-:1091A0007B12D6B729ADC81C8B8F5AC16EC4F92D5E
-:1091B0004DD669D6239F661DE7DFE8F75B92B99E1F
-:1091C00068DD3FB1C753129F7E40D279518F9BCB50
-:1091D00054C756589FDEC0E76B896307CA7EE3C158
-:1091E0006BCB7E0BC96975A83980F644F4789B5423
-:1091F000778F07BE6F82F9F8B19CC3C7DF54A23ADC
-:109200007643D71657023347D437384B08FE176CCE
-:10921000694C0FDF37213DC6989784D3BCE4EF68D3
-:109220003FF9A2E832F7B7C3D9100D5DB6C6A2CB9D
-:1092300079A8374BF9FC993972FE4393BE8E7C8C2A
-:10924000A69BB249CC837C9701CF76586FA7CA669C
-:10925000EC437D80B6D64498DFCD36E600993E39A2
-:10926000B57C6732ACB7ACE78091213F743A691D99
-:1092700075A27DF4B8A6148E3F538A839E49C73DDC
-:109280004F4F01F876F624B814F8D49902FA300654
-:109290007C8F08BC33D6C69F6A681CF28FAC5FB661
-:1092A000887976C3F350026B3583BDB24FC807C6C9
-:1092B000EEE74F151817C699FDCAE8DD642F8AF549
-:1092C0001F02B580F5D3D343E314FD77C0DB5E58AE
-:1092D0007D04DEEACD21C2DBDB46DF6B089FC6E3FF
-:1092E000A1742C771E3D9387F870B670FBB5EF25FF
-:1092F0006B00E96E207ED6D3FCEA2E0E62FEE28180
-:1093000078AB5383A45FEB2EE6D17758B7DF9C127E
-:10931000FE3E1B6C8609B02E66E67042F8C4C2475A
-:10932000BBE06B890F50EBA3ED021F08A78FC43E73
-:10933000A71FEF4EE36606783F6BE6EF996724DFE1
-:1093400087097DFE51425E00F7331F0D07CE467A36
-:10935000505DE9917AA7CEE2B96F3EAC9BBDAB6799
-:109360004FC06359A5AD15EDAB65264F12DA5DCB45
-:10937000DED32BEBF30984C4072B043CCF32F75D1B
-:10938000883FFF368BE309C29F76FF97BFA3BCF8E7
-:109390001D68BFA24BEF46937169A5CD8FFD96F571
-:1093A000543C6D87F72B5BAD2E06FD2E9BE2FE0431
-:1093B000EDBD65F7595C1BF271BF38A43C0BFA5D3B
-:1093C000FB60BE03E581759D37D3EC0693E07EEB31
-:1093D0004C2BE06D93B264895208AC7D7FCA1615A0
-:1093E000F0ACFE57E56716285F757FC116F3758CE4
-:1093F000BD82B21CED59FFD09968DFFE12A746F678
-:109400002EB76F7F794427CAC55BA6820A18E5ECA0
-:10941000D4D960CE2B538AB79861FCF4144FA10EB7
-:10942000C65B93326126F6B7F4BEB17FDD09DF7704
-:10943000A4CC9AA9E613DE447BEFCCCAA1D06E92ED
-:109440002CCFB354427F695616B6A72700BF0F0929
-:109450008F8FF67767BFFDBD60E6D41CC04B4553C8
-:10946000A50AFDBF9E72DB9631573136FE817287A9
-:1094700007C63F98B264A615F0DF6994F5976DF1C1
-:10948000C0589DCCF78601BEFFF1FEBA9966A89F31
-:1094900096EA2D74C0FA53CDF76F9991FB1DF865CC
-:1094A000A412BD4F2C487112DF1C4690E6ADEB3381
-:1094B00072FD2AF83D87D3717F792494ED11E54C34
-:1094C0005EEEDC105B7E9C4EE572B93321F6778F41
-:1094D000904B00EFA00EE9B3CB1A18961F9627C049
-:1094E0004FE609C45FDBB93C01BE9A63273E8ED9C3
-:1094F000DF37E55F803BF5D3A97AACE8BF90720D0A
-:109500006666C571BE4C7669E47559CF5292B7BF95
-:109510004A157CEBE2F071566AE50A33F70C47B85E
-:10952000C8768BC53AF3474BFF52D088FCB9D6E2D8
-:10953000C9C0F9ACDD579EC12E6387D75D2CD7F823
-:109540004BC2EB984AEF07F40BFDB944FFEE315FD5
-:10955000075EC95780571A7DBFD23AC3FD69FD3BEC
-:1095600003FBE37E9E017AC5187B9E1B53B85E41C8
-:10957000F8EB22E4DA4A215F416A913D7EFEC5ABF9
-:10958000766FCD8F1C7703F50FF87D7A0AEE2F41A9
-:10959000BEA21C2B533DB3B07E594F8A03ED79A078
-:1095A000B78D82DE54A43789E7CE94A6725AEF763F
-:1095B000C5B13B861DF81339AF36C583F649C622BF
-:1095C0009F7E49C4FCA4FC87FE3B45FF259C9E1F53
-:1095D000EDA7E7C5C83FC22FC4DC40DF6307CE5FFD
-:1095E000C136CE08FDF5822580F39170FBB6F42FCD
-:1095F000ED87BAB87A2A91DA651C0F26BAA09E21A7
-:10960000C5C5F9B9E3E3C46B515F75E999E2E2EBD3
-:1096100046B95126E5A4BFE748854A764C582EBB8B
-:10962000C89E917233683687EBDFBFBD67C646942C
-:10963000AB26BE2F4FD383142F0ACFE3E514AE2FF2
-:1096400027F89827961D7824D92EE508ADE3E17513
-:1096500095EC63589F5DE8D709213FF9B39E4C66AE
-:10966000C23EE1F090FA7BB629F4AFDC4FA6A547E5
-:1096700059063BA5415710EE1FBFCF89A0FB63825F
-:109680000EA2F1F35DE513C0C18F70484DE172C8C1
-:10969000096505ED0B15F417C0FF5CB5CDBD353F71
-:1096A00062DE362E8F9D7A1D976357E08BB454FE91
-:1096B000BDEF253BF173181EDC8EF92F01F7761DE7
-:1096C000ABC17DC1211DF009D2A28DAFF3FC8B5936
-:1096D000D4EFE7293AB9FEEF452EB71B613CCED750
-:1096E000643FD6BF3CA85D3B7FDEDFDC544E8F6518
-:1096F000C73D8568C70CF3DADCB85F28EB9973C007
-:1097000000E5E1DD8A036B4B3A1FDEC1F914A84B7B
-:10971000C0E5AD6722FBB5A5723AFABED631FC387A
-:10972000A757C4CBE2083ECD4DB57178C1FA4C08BD
-:109730004F552B47E5F3FB9B87F78001D65B07F07E
-:1097400040B12DE1D6D9B1648305F9F83873231FF0
-:109750009FEF58A21B8B78DDC9C8BEEB970F0FF0A7
-:1097600075487B14E8B203E9F2EAD45C1A6FD87149
-:109770008F750C7C1F867613FA953BEC01DC574CF9
-:109780004EF5CD4D4578CEEDAB64204A1AAC4DEB8D
-:109790002D11EFFBEB77417DA2639F7E2CCEF3363C
-:1097A000C6B6BAC2EB81A9FAD11F5A6F043E2DA0EA
-:1097B0007210E1D669E4F5FB16338ACF34E8FB8CEE
-:1097C000F81DF4F72CA2CFA3BA14C42FEE9BD06ED1
-:1097D000AED37B7314DCD76798DCA807601F42F414
-:1097E0007EC8C2540BF4FF263C514E57E9EFD88F88
-:1097F000F0AA2A50DC2D24AEDA85DC6041DC37CDBE
-:109800009E62257A645FDD39B41AF5BF95E309FAE3
-:10981000318B7ECCE6A230FFFD3AEF2ADAFF48FD1D
-:10982000764851A89F43D78DDEDD12B12FC2FE507E
-:10983000FE1F52AA73EE40FA17FB3AB20FD3C27A58
-:1098400017ED95225B24DEFD627EA13CA4A3487B3C
-:1098500014EDD37E7BD6DFB1653AC8D9F1333A82B5
-:109860003A0752D1F333FF01D65105F6AC05E0704B
-:109870005B2A973387F2FDFA449CDF30583FBC3AAD
-:109880009CE01BD3640B8F932EFC0FE946EE2F4810
-:109890004FE0CFBFA7723BE727695C1EFE218D9783
-:1098A000D31363FB2BBE10F55413971F5BCBB9FC8E
-:1098B0008FAEB741F4FBADEDDE318A667F0F76EFF8
-:1098C00086546EF71AB95F88C713960AFA063B8763
-:1098D000F014B6AB783C50DAA15FF4CCA3F272F38B
-:1098E0007BD9E8BFBFED9FE6DD87F4B6F2377AF2A9
-:1098F000579C14F18295C9BEF464DCBF27C4F6AB53
-:109900003C27D675BA99911FF8538C1B82EC3D8980
-:10991000714328AFDAF9E034E4BFD52C40FEE0E52E
-:109920003B37515C707940612E05F7695EEE271672
-:10993000F858BD47AFF14BDFAE361993C784E977CE
-:10994000459B366E58B3AB5853FEF6F669250B446B
-:10995000C8A1B0FC9946EFA3FB95F41E6DA77ED479
-:10996000ECD2F8C397EE1C46EB97F5973137AD77FD
-:10997000596B8166DEAC95F349BCF949BA45BBD455
-:109980001F739E46CDFB8F00FEFE08FFFFD25343A0
-:10999000691E2DA9BEFF40BA09CFC3CAFC1ABFDA9F
-:1099A00024C727B05666E17E49A023FFE5EC81502D
-:1099B0002AA7FF6F0FF7D171F605E3FEBFEE0BCAC2
-:1099C000267139CCDA14360C1EE3A76AEDB4BFA0B9
-:1099D000BE2BC5A795EB6B61472D5FA4AD7751D426
-:1099E000BB28EA5DC9BF12699F290528D7787F0D7A
-:1099F000828FF3CF1C35BAA0DEF8346EC716393D1E
-:109A00009750EF6CB3248E437FCA364B5E00F552FD
-:109A1000FFFABA381D6D33483F8A3B03E1D6FE5F3B
-:109A200077B6A888C77DB00F007958FEE841168A3E
-:109A3000905337AE533CCB01DE7621EFEADC7C7DE0
-:109A400075EEA07128F4935DC7E795D3B15F5123FC
-:109A5000DAE5D4087F5F9A41B3CFCCC1324E258D71
-:109A6000CBE39C9AA03214EA65EFDAA3A8D85F870B
-:109A7000427A33BB0900134157D925DCBEB9B1A4E2
-:109A80005D5936260C87565DF51807E0A735DDEAE7
-:109A9000467D738FD337240DE7792218C4EDFCF887
-:109AA000133D2ADAEF3F757A0AD29C6138B8F48EFA
-:109AB0006CD4A7D6137C9E6DFDFB63AE6728A24DC8
-:109AC000FEABDDDC9ED1B3238CDB87A4AFD2378C19
-:109AD00024BD27E7979E22F4453AF33D67A3FAADEC
-:109AE0008CF0C9683DE91B86EFE6F62CC7775581F7
-:109AF000770FBEAFCAB8AAA805DE176C0BAA4BA198
-:109B0000DDCBBB62FB83CB853E81754CC2F5C9754D
-:109B10005C492EC87A86387E0AC90FD619B1F71F5C
-:109B200030227D2F7F346D21CEB76EA39199943072
-:109B3000FC7FEAF4CEC6F96477B42B081BE9DF9307
-:109B4000E34AFF1D7E47FEFCC828F996D35F5CFE02
-:109B50005FA7F72C8F94671B8D8427693F87E7C722
-:109B6000EDFDD5695CCFBEEAF42EC1F934746D27E2
-:109B70007FCFAA3D1F1A63F9ABA3F9E24A70546A7A
-:109B8000F8BEA06EBE3980EB2F7F54253AA8DD6861
-:109B9000A43859DD33FBB89FE71EE6463951D7B1EB
-:109BA0004F590EE3D63EB34F591101D74175010508
-:109BB000E733C22EF990CBAF68BA473F32DA2D8730
-:109BC0002D5C4E9C2DB7F91580EB5983AF0EEB9DA4
-:109BD000CDB2BAFDF9613CBCB96FFA11CC37B03FD8
-:109BE000670AE2B355B73BD30CF55A4719DD485F16
-:109BF0003F75FA36235C52546F27B64F4EB3BBD72E
-:109C0000435B978915A1BCFBBA70181F4527E3EF8A
-:109C1000E1FCD3857288DB9145C83F8134BBB4A792
-:109C200048AE1D36F0753CC7F87CFF9EEA7990E897
-:109C3000F8480A8D9B5D1754D09F9D7FE639926B43
-:109C4000B2FF309D791E89E4DF2BCFB3C388F45671
-:109C50002BE450F9A37B948F23E6FD4B30F4916EF7
-:109C6000B29F01BAB4D1F7FD33D3A83E33B9F0BDEA
-:109C700042ED6AE1FB8A087923D71143EEECC3F584
-:109C8000D84EF41CE47227C8FD8D62BED1F87C1555
-:109C9000E51F7C9A06EA99DE1BFD23312E7A78486F
-:109CA00002F527E54034DFBE2AE81CE5A5CE46FED6
-:109CB0005AB22BE5FC64BD2267C5FE3482430FC156
-:109CC000A17E974AEBA9327A87DE11C10FBF16FD3C
-:109CD0001DB8F90323CAFD07FEFD5DA2C7FA36854C
-:109CE000E2F1ACED5DE33CD447FEA7F46867CEE259
-:109CF0002601DBF1C2BB84A7599D5C2ED777EE53BA
-:109D000097D9C2749A7FE6C0AD4867F51D2686FBD9
-:109D100022A0BFDF207CA2E954C247CADD78F8B494
-:109D2000CEE07294F98DE44785FD543EFA29A4DC17
-:109D3000FE7BAA4EF809F8FB0B69BC1CA61FDFA727
-:109D4000088FB0DCB5105FE49F293A60C67DB85B30
-:109D5000213F7F5A258767E4BCAAC7C6979BCE548C
-:109D6000A137D450DE1C7B58BEF7CB7FD1FE0B81D0
-:109D70006F781FE4EFD910D4F372FED1F8CB77726D
-:109D80007D1B83CEFE1BD711ADDFA43D20E9E6C9C4
-:109D90005DAA468FD89D46EACF0E1B739CC78E7274
-:109DA0001ECFD861E0FA6CC77A7300E5C99B0B78C7
-:109DB0005E997DA13188CF43BAA575F8FD50361F55
-:109DC000BF55A75B83E5D60D36D64278F5243A4BCE
-:109DD000917E1219978F5C1E3EF03C9767757E5BF3
-:109DE00080C13FEB7C739753DC39CDE2C6B833F3C7
-:109DF0001D34CEB30FA42BD773FB8D2E783FAB83CE
-:109E0000F39FC403C853A22FC90F12AE617872B872
-:109E10004B7E92F8F8BBF46703BD7CA7BCAA3DDA81
-:109E200078DCDB46DFD54EBECF3A6C70A19F86C78B
-:109E300017E2D16FEDBAB7B34F821DB53AF32D7A61
-:109E40004ABE85FDAC86BF2709BC1738B9BEAF74C2
-:109E500072BAA92DE920BEAC3DD944FC6C9BC1E58A
-:109E60009AED84561E33F6CF62BDDBA85D95B563CF
-:109E70001AE677543DAE3870BF1F4F6EDEAEF0FC71
-:109E8000B84F77BD9188F972EC2BB0F2319E62E148
-:109E9000EB9DEBE472E2EC5E0038D17B93F172F65D
-:109EA000FB95FA63C1630AC2B356C0FAEC3395134B
-:109EB000FF847EECBD49EE61B0E4CF9EB9E9EE3F90
-:109EC000C1BCCFEE99E246F7655A8B97E8A7CF69F8
-:109ED00071E37E03C4F70CF417AEEF7823F15A68F0
-:109EE00077FAE9AB8B506ED78A799E795EBF0EE127
-:109EF000B2E1C97F9B8CDF6B034AAA09C7D9FBF883
-:109F00007F6763BEEA9E46F217B53CFDBA11F317B0
-:109F1000748176FE7E6F9203EB9DFEF9F6C908EF21
-:109F2000968E16FA7EE6E7ED543EF0E4BFBDF67776
-:109F3000F4E37813DD58EFCCF3FB092F753E95F26F
-:109F4000DBE2D1F58E7DFBB9BC443D8F7C309FCBED
-:109F50003149D7927E4F3F79DBC448BD21DFB70A34
-:109F60007F4E6B02D7239F09FEADADE0F1CECF9EB1
-:109F7000B5CCA7FD8131341CF7C57563385DDC2D88
-:109F8000E051D77187A1C146EDA99FDF02DFE373DE
-:109F90002CD0E72723298564CF25CAD7F957AA0FE4
-:109FA000F526A0BFE7E6451F2A381FEB9826432D6C
-:109FB000CDF369FE1D561DF9BD6C6D6C3FFBBF38BE
-:109FC0006DC22EE07C90DD599DE3223960720F8BCB
-:109FD000B087B36B7C2D1827BE7EADCFAD073CBEDE
-:109FE0007CEAE8B441507E72A4524CF8D72B5CCF87
-:109FF000F96D344E3DFAC1818F760B3E497730F5CD
-:10A000001A9203DC1F50A532D5467EAA3E9213F564
-:10A01000AD420FEE117E6E735FDE4D766A67BB2632
-:10A02000621F06ED6C362AF7E5FD10F34A67F8E784
-:10A0300093DE711969BE67A43C607EF27B4A7E8B19
-:10A04000F61BA1BCC1FCD1579DE55D281FE5333D42
-:10A050008EBFE4EFE2FBB8744F17CA15B63755A3AD
-:10A060000FE2C99503379FE77AFB950F890E1B9086
-:10A070000E717CDF498DDE5E4EC215E8F0A50F89BA
-:10A080000E977771F9DAD0556EC4FDD40EE1D76919
-:10A0900010F4847484FBE8BF3A93699C86C9A1E1FB
-:10A0A00028A7CE0BBA3BFF12A7B7433A1DF9010E02
-:10A0B000ED1EDDDEA20CD48F4A8D97F0DD00F8E6B0
-:10A0C00076F3DAA36867D5D73037F26B43A7E0079A
-:10A0D000B07B11BE0D5DD5CBB1BF416933C9DF0D7A
-:10A0E00076C9B441506EA863A5C86FD9BB2A5E4239
-:10A0F000BA605D7C3F9E5D03F62CD24D5ABD5B9FDE
-:10A100008F7A8FDBBDD78F2CA3F63B725D14E7F2FD
-:10A1100057318AF3EF40FB19F55DD6686E3FFB3689
-:10A1200092DDC55C09E437653E750DD66FF02F6290
-:10A1300094D711CDC72F29B40F680858291F685626
-:10A1400017B77F1ABA381F9F93F0914F43CFADE4F2
-:10A150008F7FC1C4FC11FED0375F9ACEF5EC8B2601
-:10A16000D2B39F357BD8C7B0A0B785BC9770AC6D14
-:10A17000CBD721DD32769309E7B14CCCA3CDC0F526
-:10A1800046B2D00305DBF83CD474E1774CD789A7FD
-:10A19000519BE7E2F0937FE19C188FC8225DE8397C
-:10A1A00018BA7E7990F8A4EE19DE5F9AC9537867E1
-:10A1B00004BD4AFB289A1E0BC4B8D9BB0E2A284CF2
-:10A1C000B277CDD1F0F9F5352CD808EBBC7E972EBF
-:10A1D00038651CD94D0B499EAF37B258F92A23D2A6
-:10A1E000B9FD5695EA2D44BF76D5CD3677A43FB953
-:10A1F0002AC1A3B3A01D5724FDD8DE128C1B9D4A93
-:10A20000B7BB116FE3D25DD20ED3D85B03F7DFDCAF
-:10A210000EBCA1CD3F0EF71F81F509F329AE09DA77
-:10A220008DFCDC0E688FFBF7DDD7FE9CEFDF5BB8A3
-:10A23000FF020407C999546F09FA8F9D05DEB55CCA
-:10A240003FD9DDB1D6F3AA93AFE7C0CDB716E23E52
-:10A25000B161AE8DF8E1815794A59CDE4011E2BE5C
-:10A26000DAC7F983017F3CE1227A243BAAA1C91B0A
-:10A27000884D8F9C5F1AC0AE423B1BE8710DB793AF
-:10A280006D8CF313A74BB9BF47B91569CF4A3E8D03
-:10A29000E67B49BFFD7CFF35F9FDBC81F3E37980A6
-:10A2A00003D27B3F9DBFCCE97CEB7AE047F8BE153B
-:10A2B000F8B12542FE47EF7F709EB81F90F2F61E60
-:10A2C000A777513ACAA1DD6F6DC650AB948F0D2FA1
-:10A2D0006F197E39BBCB8C95A15F33F06B24FD6089
-:10A2E0008CD65E444F3FEA09EBBAD8FE8FBBD26DE5
-:10A2F000DFCD3F3F302FE5AEF4D2817929E9A87355
-:10A30000106FBBAD01B48FA51F297A3E4B049F4946
-:10A310007CCAFD03C621B0FEFD82EF37897A8F88A3
-:10A3200067C4BE84F8C1A5F37D4879F671F4916CD9
-:10A33000F77DF9B5E438522F46D38D8CA3E07AAA85
-:10A34000C7C4AFD7B65FECCFA2E8F829C15F0B80D6
-:10A350003770DE6D86E017C48F77D819E513F8994A
-:10A360002715E371AF8DE07C34B26F38B6B766FA6B
-:10A37000BE44BA927E5D7C8F71AA5A11BFACDD6B70
-:10A3800008449E7FB93783D138BD76B35F0FFC9107
-:10A390009BE9DB87EDFD15CC1D443DF38F168A2B21
-:10A3A00081815B8AF2A691851211CEEF25FB5E209A
-:10A3B000FAD5F70C47BFE33925340EDF9F10FEDADC
-:10A3C00013C25FFB7ED77BCFBE02AD17BF726EF1AB
-:10A3D0008F91CE5EB4E4217D9CB0F4E7BF25A1DD72
-:10A3E0007D81B9922E770E699159EF5523FC67272D
-:10A3F000ECB1FD7F6F0B3C378A782B5319EDC3B757
-:10A400006770F9193EBFC4E3ADEFEBB4FE37F91C3A
-:10A4100093C1E1DF19E71C506106DFD7740EE1FC40
-:10A42000D8D7AE50BCAF66DDFA3FEB412ED4ACB509
-:10A4300007E9099FD18EAB71F8833A289F3070B934
-:10A44000047F73CD6561FD07F5D449C8337E07C528
-:10A45000BF960AFDB5ACE9CDBFA15FA14665E6494F
-:10A460004518C7F21E1E049F3EB52D4F44F1BFF2A2
-:10A470004777A6A37ECA58D426F2C1A63AD0FE5585
-:10A480003C37E82F592F676FA96427131D00DE1E84
-:10A49000CCF0F6221F2F4AE27EC145775A03FE0810
-:10A4A00079B857F06134FD7C10E7BCCD97191501E0
-:10A4B000EC6F61AAF76FD4EF9DE73472EDBC12FA2E
-:10A4C000C523485F77D8DD4FF0EEF222F363D20563
-:10A4D000FC6B310E04A2B1B7B067F8BA7CA4E3BE3E
-:10A4E000BCDFA15FABDBE4F0BBF0BB91BECB76F190
-:10A4F000E241F1E3402E23D247C34585E86169F785
-:10A500009BC751AE37A821A293A5661BE1B1E1A27A
-:10A51000CAE9A9D5703624DB03EED7A47AD232601B
-:10A520009EFE7B2725533C09F889C3172A459CE3E7
-:10A53000F832C3372803E0F79035F136DC7F5D3021
-:10A54000BB92308FADD108F4703575E73547D843ED
-:10A550002CC7AEA583EEB7FE86F35A6EF61951AF3F
-:10A56000AFF034D179B14549C152C79848BC4FD2F8
-:10A570005F1AFDF5F17E49C897F78D3C6F64209D09
-:10A58000733C6CCF10F5B239BFBC9FC76A9EC3E75E
-:10A59000287842BBF787887291280F17F5D279790E
-:10A5A0009AE097F7C7F17AD1E32C15E37C99E1990A
-:10A5B0008C7082764123D2C76B163A67C44A40FE3C
-:10A5C000A1BC5B934B762CC8B96908771827984CC7
-:10A5D000F54CA4675813C841C0676FA98BE0B3B5A9
-:10A5E0001CE805E341AF9A281E24F12BF11A8DCF08
-:10A5F0008519CA77CB4F1F18BF5E98513A307ECD70
-:10A60000D850C217D14B8CF31FF1F0F56B3BC70349
-:10A61000F0EBF20CD283C1B1917CB349C051CAB501
-:10A62000F713B478FD3C9DE3A15ED4BB84761FDABA
-:10A63000D1EE3EE2BFF75378FDB402AE97A45DFEC3
-:10A640004F022E5FA66B9F52CF44FBD1BF14F2E2A4
-:10A65000CB74EE4707BCDE8DF395FA09E44C301954
-:10A66000F878D1EB2692336C631FE5D540BDFF83AC
-:10A67000F05A64EABB3515F4CA0FC1DE311651BB7E
-:10A680004B284706ECEFC748BAB033D4DBAD190E00
-:10A690006E1F94F4F1B8D748BEAEA50CE48772657E
-:10A6A000FC630C210BE4F06B22BF42C1BCAE146210
-:10A6B0006717F60770FF978CD230DCA3C73B21E801
-:10A6C000E0D10C4525BC15B242C4DBADEF7E6E5F18
-:10A6D0000C5D9E13E765934DBE76ECE7ECDD6F9164
-:10A6E0009D7EC2181CDE668BF1DD187CEC2125FCFA
-:10A6F000FDB6A7F47EE3D5987F7EF6C19B61DD4B66
-:10A700007BF46E1C72E93D5FBC331EEDEC1E03C58D
-:10A710006B40DF6F5371DE4DDCAE3CA1D3D2C1671D
-:10A720007769F73DAF0B7A90E772A5DC91FA7C155B
-:10A730007373799390B81BCB1FDD713B9DCB5DCEBE
-:10A74000BC873D00F7D36B66925D7C3BF3515ECFD7
-:10A75000B256ED39DB156DDAF2ED3B079CC32539B6
-:10A76000BC2A10FD5EF8A52B63EBFBF3822E3F3372
-:10A770008AF8FD7A53CCF8FDEF85FC09C7D9FBB404
-:10A78000F1FB572F1FBF6F8C8ADF87ED88E8F83DFC
-:10A79000EFF713616F60BF9171FCCF2A62AFE3A343
-:10A7A0000C69B75835F9199F0CB05B12E97BE3458A
-:10A7B0004B9CF9D8E8FD672B638FD3D73F8E365F6C
-:10A7C00020DC9EE709C8FDB5A493C68B59A4676534
-:10A7D00059DAC7E17639F43DFABCBAF46F4BBEF8EA
-:10A7E0005861E62CF2476D1776BC9BF2333F46BBAF
-:10A7F00008F972BAEBB5104C71D98F270E578784C0
-:10A80000F9267A1D405F674211F2D898694F23FDFF
-:10A81000EB666E3A9727E8FED6BBABE87CCFFFBD70
-:10A82000A73223326E2AF7530D46698FD934FA9630
-:10A8300045E9E3655D6F911D06F6D770143E7F7A9A
-:10A84000F56ED2C32B99371DE9BDF7D511746EE5AE
-:10A85000DBEA61399F9BFC4B0C3CBF358DEC8739A3
-:10A86000623E3775733B5067F618681C0F7339D218
-:10A87000698BCDE70B425485F275FDF347E71D6305
-:10A8800093C4FC156C0FF0BD4E3CD9525F26CEDB55
-:10A8900084E3EA310D269089CF96896E173EA7286A
-:10A8A0005E95CF83E3791A6BCAC1FA3A7348CFD762
-:10A8B000093348C7F6FDF0A2B25D9437CEBD70EB08
-:10A8C0000A7C6FB3933C318A794CCF04B988FC6D14
-:10A8D00066665CB7C9163C4DF133F1F457B8888F02
-:10A8E000FD4318F9411258079D3FB5D9CEF971B112
-:10A8F0000EE650B06C715C08E27EE29CC3E6C7F3E2
-:10A90000C4202F6765A23F5FF9D54AC40BC867EE24
-:10A91000178AF75D0DF2F31142DEA588F9B50879C3
-:10A9200097C5DC8AB8C780E4DDFDF69537E07E2662
-:10A930008D79F7A3BC7B387106C5FD32988FE693FD
-:10A940003A43D5C82DA7575BCE98AF46CB3B05E71A
-:10A9500097E5D3BE37B3139497A404BD9997526972
-:10A960001F3612FD310621378E59783EC26631CF2F
-:10A970003B3353886E8E59785EC2B7B65BDCDA7DA6
-:10A980007D430A3FBF7F3EDD6CC6F1C08EB913E147
-:10A990000776CC077E16CEDF2C9CD24179029B6FC6
-:10A9A00054DC1BE0FD66BB6BBD0AA4EB9FA9707F66
-:10A9B0008FEA28C77C9CF63C871BF3441B45BEF7F7
-:10A9C000668BA3F619F2639A783DD6B719E396ED34
-:10A9D0005B1D0EAC9756D937CD88FBAA15CCB19B21
-:10A9E000C5A0F7AF808F60BE3FC732E04911F46366
-:10A9F0003DE2BA85D620BEEFC17F17F0F29432DC7B
-:10AA0000BFF2BF82EE423A77C93C7AD2978DDD859C
-:10AA10006FD860BC82B985E4AFF756F2B82F1372D5
-:10AA200060BC1C57F0D9B561BAA7EF85A23CB45BF6
-:10AA3000F87FD34C3CAEEB8021CAC49143AC9FC697
-:10AA4000F9C1CDE41FE7D36B58F80FFBAB0CF74F00
-:10AA500072696AF87398EF60A822B3BBA50EEA8DFD
-:10AA60005783FB91AFAF15CF42F13C547E23E9E50C
-:10AA70001E9DCD65D4713E3717A0ABC3AB47B894CC
-:10AA800039B6B4603FD729417AE6CDD8DE82D39F6C
-:10AA900023FC4CC999C6009E376B99007826BFC825
-:10AAA0009F0FA3FF5AFF2FAC18F174CC20F59E27FF
-:10AAB00089E7FFB9683DD50E3E5997CE337B2EC24C
-:10AAC000F9283FCFC6D0748BF8FE97A9554997D780
-:10AAD000BB3C0F30254BCFE5E30C1E876D9C6FA66A
-:10AAE000BCE546710F03537DF93F8CF0AFC8B8C584
-:10AAF000BB06367F5F8CFD464A16B707E6DCC0FD15
-:10AB0000C28D221F477E4FCCE27EB2BF644E7B37A0
-:10AB100093EC3D1E6FFD9D945F23D948945F11F225
-:10AB2000E58F245FCADF8E277FB4DF85FC99E72994
-:10AB300036D0BE40C82129EFBD22EF6801F31810BE
-:10AB40004F3DE21E95A3E5AB480EDDCC7CF4FEF74D
-:10AB5000153CFF0008D380FDDD34436B3FCDF36A25
-:10AB6000CB37CF8FB6AF383EE4B80B7CDAEF73A4A7
-:10AB70009D3C436B272FFA87AF9249CF67FCA2FE1B
-:10AB8000D2E0703E5163543E5183C8276AEC2A3CA0
-:10AB90009416914FD4D8CDF3891ABAAE944FC4ED20
-:10ABA00029AF29B01FE324DE5AD294EC0D917F72B5
-:10ABB00010F34F8AC2746EAFB0F33C0CE6A1BCA296
-:10ABC0001C8795CE5DB4EA8AC88FDB9A68D7F8DD1A
-:10ABD000B7AE7755613DE9BF95F9434837B1F6C344
-:10ABE000D9597C5FB343E17E74FF0233ED3B9D0591
-:10ABF0005E4D5CC1A967C7D1AFF86EA64BD6273FA3
-:10AC0000C90E832FAB189E0185D17989FEF67AB6DD
-:10AC100091FC905172CA99EAA6388033692CF9F5F3
-:10AC2000E77517923F92D92CEE614AB8FF7973DB32
-:10AC300055CCEB69EC6E5797DBC27437364BEC435F
-:10AC4000ACCC8AF4DAEFD77BCE447EBD6493B730C8
-:10AC50000BDAD71983E4BF8BA0577A1F4F5FDE2E24
-:10AC6000E8C550E15DB002E6D7FB8ED18DFB6B0AE3
-:10AC7000CC41FFCFBF944C7E49750E233DB5B19CAE
-:10AC8000CB935EF493C13A3E4DE6F7FA6CAC66A402
-:10AC90005FCFA74C233A5EC502873DE847DB0574CA
-:10ACA0001879CFD21E6DB98E7590FEA97B66003DD6
-:10ACB000937C94F2B89EB9F4068C1B746ADBB3A142
-:10ACC0005A395C28F447F1BCA92D98FF50ACE3F247
-:10ACD000912D770F9A43FBF5458E4F2C28727FA15B
-:10ACE0005CCEAEEBB59FD273FEE77AA154F41FADF4
-:10ACF000BF4A853D3719E417EE6FA57D06F5A97C9F
-:10AD000050D7ADCFD485E75922DA49BB50EA0B8939
-:10AD1000AFF2098CE179B5BBB2847C1AC28620BE41
-:10AD2000A17FE21305375829D4BF1FF785D78AF1D1
-:10AD3000801EFCA8BFFD3A7300E96BB3D244FAD27F
-:10AD40008CF63F3CB72A3ED20BFF5EE3D7237D4C07
-:10AD5000644D37DD00F526997BAC28B7804EFE3177
-:10AD6000927E5A58306F9FA2A123FA7E36F9ED9851
-:10AD70007424F55AF0F7DC9E99C5BC74CF93E70FA5
-:10AD8000DCEE3AA8F07D26D89F07D1EE7A5B3793A8
-:10AD9000E864262C03EB5539B4F89F9EA92D47DFB4
-:10ADA0000FC5D05A284374487806549C4FF4BD51BF
-:10ADB0001E29F79856EEE5B3AF78DEF896C33F420A
-:10ADC000FF83751D1B89F60E58AAC48FD1F4B027D6
-:10ADD000EB7B8FB7ECC98A116FE9157EE56B58687C
-:10ADE000E533CA407A3B7F689D3E33822E257FBC87
-:10ADF0006CE07913CAEB3CAE35C1CCC604112E25EC
-:10AE0000DCFF28F9E31AA4D39430FD9589F787A4D1
-:10AE10007C19CC0623BD5DD76509EA013F85A2BF39
-:10AE20006B90FE8AC2F689DC77B44C184067F998BB
-:10AE3000170EF64C01D295B44F8A958E163CE7FD5D
-:10AE4000FC4BF7B6E07C23E8EA2D84C35905E88A79
-:10AE5000FC6A03F4ADF67B14DD49FC4B7BBA9C35F0
-:10AE6000D17E676E02D7B3C1EADB49CF82B824BA7C
-:10AE70007B730EA7BB2AE621BA2B675A7AA9346BDB
-:10AE8000CBD1740923EAB474E723BA8BA6D77874BC
-:10AE90003718E94EEADBD42BD3DDE74877DFC58FDF
-:10AEA0003990EE3ECF72C6A7BB687A93F26C9FC50D
-:10AEB00051897675638D42FAA1F89DA12D581E51D6
-:10AEC0009F4F76F6BE6437D9DD8D4DFC7B498F47A9
-:10AED0008F7933056BC5F77C6F25961BD7C177E853
-:10AEE000BAF418CFAB197A0FFF5EB8A1E90DBCBF59
-:10AEF000A0D1CFDBBF7C7A339D870A6C16EDCBDB0C
-:10AF00002AB1DCD8CADB7F8A71AEAB31BF2DD082CB
-:10AF1000EFAFDA96EFE6DB6F6ED74F11EBDDA73CB4
-:10AF2000F706B56BE3ED6E3F6C4E60E427E0F6FA92
-:10AF300064B1CE29BBF83AD33EBE7E860BE86345AA
-:10AF40009F9FECB94F74756524EFE2ECB3CB95B6D7
-:10AF50001C7C4E4739A647BCBB5BF543781C743755
-:10AF60000C717536F7D3C8F821E6295447D817571E
-:10AF700067733B44D64B4F61747E8DFDCC4EFE72A1
-:10AF800019DF0C3EC414D407B8466197C48C774EC1
-:10AF90002F6822BB62FA6019E70CA94B61DCC24B37
-:10AFA0009F4F8BE5472ACBE6F6F329917721DFD730
-:10AFB00004F2754817FB9048E8FCF09077D09EDBD0
-:10AFC00097CC34E7DCF6E5F3F2D4ECBC7F6ECD0130
-:10AFD000F8EA9A54BCF78BE52994B7F2831E164C15
-:10AFE0004A1C38FFE92A0B1A290F8ACF7F658B513B
-:10AFF000DC57C2E5DA3C813F366918D1EF5C81A7A6
-:10B00000EA6CA1178B5931CAA979026F3F343719FD
-:10B01000B8BE6E3344C98F79D9283F1E8E6BCF6B73
-:10B02000BF47C9971A31EE4A61C7AF627DE43FFD61
-:10B0300044D8F1A71EE676FC6AD641FED3DE9F71A6
-:10B040003BBE1E9687F412ED07ADDDAB2DD77768BA
-:10B05000CB0DA0DEB1FFC6AE28B93386FBA57B1FA2
-:10B06000AE2F433F64CDCE77C8FF5D23E54C402B28
-:10B0700067C040E772E6A151E4BFFAD6F2E319D8FF
-:10B08000D59569F24BEFC97646F8775EE4792E0DD7
-:10B090008CFB117AED236FC17D2C8BD24FD172A521
-:10B0A00050C815E9FF90F25BCA9B42C6F514EC77D5
-:10B0B000DFF1609B283BEFE16CA1AFC4FE4DFA4D80
-:10B0C000A47D5488F611D2D7A82622BAB07E72BFCA
-:10B0D0006DD247E8A5052566C47B9119F81BE1A64A
-:10B0E000B78DF5D934F4F168F6E5F783DAEF51F46A
-:10B0F00023F7630B05FDDC84911818FF0F721FB84E
-:10B100008AD3CF5CE63D84F4F3FBD59C7EE4BEF0AD
-:10B110009BEF033DFAC87DA0DC4F7EDDFD603FDD87
-:10B1200058C03E86E7B15CE917E0F1FD4685D3459E
-:10B13000FD9CDF3D56C5C2F2E2683373AB8670B941
-:10B1400065A6C98C7E971603DF2FCD99F57ED9D2DF
-:10B1500008F913B4971F40B8B16E27F977EBADDA51
-:10B1600071362B3D77FD11F7558F5AC9AF74E10841
-:10B170002393E5C2AE11940FFE9981C75BE57C6E07
-:10B180003FBCF7B510D45BB9EE9662CC2FA8550240
-:10B190002FD6C1B70FACBE7791BF6B7541712F67CA
-:10B1A0000FC527E4B8F1FDBA7E92C7C6035C3FF72E
-:10B1B000290994DF0BEF8747C6E9FE3888CBEFDC1F
-:10B1C0004CDF07B81EA9475BFAF327F813B4301B0E
-:10B1D0009412CEA708E74D707FCB5F98E78A79136A
-:10B1E0001B23E204D03E66BEDB7921CF47617201AA
-:10B1F000CC6765BAA717D77F4AC4854F8938E2A9BB
-:10B20000441E57FC7B7F7DFEB40DE27AE894883BB8
-:10B210009E4AD1C69B64BD44F13CD96CF66E346045
-:10B22000BC9E793782FE703D646AA27C95451C5FA6
-:10B23000BD2F256BEE11C81A543E6A10B4FB99D38A
-:10B24000AB1F04E32C6FD39E83EA15F7DBF60ABA33
-:10B25000E9B5F0A71C376B50F5286CD7BB80DFB37E
-:10B26000DA5F9E28CB5EEABFF7BA10C9A3FEF28F61
-:10B2700042E29C3AF793C8F840BCF86174BC30FADB
-:10B280009C6974BC7FB1E43711EF5F24E4D4E26EB3
-:10B290001E6FB8D5CC360F82EFB7756750FCB82655
-:10B2A000D13F5C13EFF75BBF519E87A4CFDEDC9EDE
-:10B2B000FEF8F8CF22E2E3F5223E5A2FD7D7A95D58
-:10B2C000DF6401CFEF313E3E799073607C3C3A9F62
-:10B2D000E245B4330C613CAC7170B855E9EB2AD14E
-:10B2E0004F7C6139A33CF7356F2D6B413FF29A2DAE
-:10B2F000E296556177D70B38C75B97D3AB632E8D3A
-:10B30000BF3E81B922D693E54BD194C9928FC83301
-:10B310001D5493AD699FDB3444537FF0BA519AEFCB
-:10B32000F9FE224DB9A0F51A4DFD616D159AF2880E
-:10B330009DD76BEA17B22149E46F3BA2475F12BB6E
-:10B340002A3047F37DF4DE859AF69FB2A61D93A0BE
-:10B350005EA7457B2F33F37B7AC69485F3A9C77626
-:10B360002CD5F4C3824A50290BDF33F699B8A7795C
-:10B37000790F8F875CDDB55A334EADBE8EF0181D48
-:10B38000EF2D627DE4376E0828EE201B18FF5DD597
-:10B39000D54EEDAE64F7C878C8C64122DE97CDB26F
-:10B3A000395D47D3858DECC30BBBF4E47F2C64C3BC
-:10B3B0001F9A44F032B0806B20FE2E30EE17BBF0A7
-:10B3C0008CDD8D7945B7BFB58CE663CAD4D205DE76
-:10B3D0001F18B95EEB482D5DD8DD5A3A489AA0A5F2
-:10B3E000836878277BB474C142F0BFCBC03B7586BD
-:10B3F000966EFEB7E0DC81F0B586E15B7CD0D3626F
-:10B4000023B8F1BC35699F99843D141DD790764EC1
-:10B410007090B0BB453F322EB159F1935DD51F7787
-:10B420009C10CC0BE6A33DD5C4B85FC97B10E56F7B
-:10B430000CBF24BD8FE79794709D9BC0F5672DF3DB
-:10B4400092FC3E66E1FEA493D5ABC89FB4923591C1
-:10B45000DDFDD99CE9C2EFE8A77A57CA5318909F3F
-:10B4600000F6298BF0D7AE068B1AEF1F8A86A7D27B
-:10B47000AD04ED786E98754B7DE0A3FC150FDEED05
-:10B48000A989FF68ED5FE65122E597B487E5781258
-:10B490009E52AEC9714CAC499F897C1125E7D8C832
-:10B4A000E8F893D69F23FD41328E23E34CD1FE9BD7
-:10B4B00008BBB8558F71D2C1F92D78CEB7D8E1212C
-:10B4C0003F6129EBB905DF4F3077B4A82EE1BFB853
-:10B4D0008AF5FB2FE2EAAB2BC4B56FF22BA147F242
-:10B4E00007C6B3657C1C96FFF11FA1F124C5958B9F
-:10B4F000F398F3F20827D2D340BFA6FBF82BD08FE6
-:10B500005ED7978AF5AA30313D22DEFDA612A2F55C
-:10B51000FC907936459EDB6F601DD36E217F32E84B
-:10B5200049BC27A793FBBB5857B43DAC92BF590702
-:10B530002B41BAAF651171DEFCF0772AEB079665F7
-:10B540001ED295EC89A7F18272CAA3E0F9534CC8C8
-:10B5500041B9FF8CB7CF93F918F27E4F9977549485
-:10B5600023F8751C1B87FD03BF95E594A27F01F8A6
-:10B570005389E4C7FE3C25FA3E801FA3D62FF33142
-:10B58000F4F612F21B2D8B5CEFD78087B45B7E9CA8
-:10B59000C3E8E9C871D1B33EE1C46F3DF8B9A4472F
-:10B5A000933FDA68840D0DFA135E1479811D5ABB3E
-:10B5B000FD961C9D801BDFF75C095EF1F121F2F81E
-:10B5C000043EBEAE1D26F3F8241C970C84FB0A0D26
-:10B5D0005CFBF78FFD705F110BEE122EE74A7B7E4E
-:10B5E00081F8D2DB8FA523BC17A67A5763FDDCE375
-:10B5F000A14F145D785E55FAB394877BA14B4FE75A
-:10B60000FF1AAEE372B0E1253D8986F3DD268AB3E9
-:10B61000D674BD4176E1D96610B406FCBD0C187233
-:10B62000D865FC0851F08EB74F92EBD99023F6E520
-:10B6300062FD32EF07D6B93927665E473F1CB4DF9B
-:10B64000051CAAF46392F01C597FBE92DA97177911
-:10B650005F5FF43A2A7278FEDB29B3F73EECEFC362
-:10B660009E9C1DD85F95BEFB7036C267AD42E7BB9E
-:10B67000A698F879DC2C715E6F42A8C98DE79933E2
-:10B6800073F87D66237EA4F7621CF9FDB577A6E00A
-:10B690003934D9FF084547E747197BEE837F2CC132
-:10B6A000F8E62237DE6FBFD824EE2FBACB1A2C0073
-:10B6B00039F2BA91DF476518D244E766FA92F5E4A9
-:10B6C000D74CD3B3A9487772DEF2BCAD7C8FF701BB
-:10B6D000605EB17C3FA5A5AF780DFA7B043DC875CF
-:10B6E0004FA9EC2B6EB285E12FF33CA3E15325F873
-:10B6F00043EE431BF05E5BD0BFE7CDBC1C7DAF6D5E
-:10B70000FFFE7458FF3D36F6C8B87E83C593341EDD
-:10B71000F951DC6BFB17872789DF77A4BDA7F6BC3F
-:10B72000C8B797BF5312EFDE9BFFCC51BE977B8209
-:10B73000E2E585CBBCFF7870694856997A359D73F0
-:10B74000F75EAEDE2BFFAD8FB9DFBE28BEF7DFD3CD
-:10B75000F96AECBCC55EB1CE707E6188CE29F7E790
-:10B760002DBE547ED97B471AF03ED20838C8BCF6AD
-:10B7700006BC8FB43846BFD09FCB76E57B87AAC482
-:10B78000BC1A308F3035F23DA7B7F03869222F3020
-:10B7900094887CFBCB2E3D9DE3FFE511DD8CDD31F4
-:10B7A000E69D9BCBE132CAA9121F8D0EF2FBB5E3D9
-:10B7B000D593E779E4B9D8E8F97556846EC5F9638D
-:10B7C0009E72ACF11CB97C3F2BE7DD99C2F1D1F040
-:10B7D0009A89DF9BAAF27CF2CE94D04AE2138716B4
-:10B7E000CFC3041E3BAF0FE5D1B9B299DCEF108F88
-:10B7F0001E26A7FACA51BEC87BEECAD426C511C1FF
-:10B800008F57A28730DCF51ABC0E84BB91BECB7E6D
-:10B810004F1F157CCB3C36DCCF2D11FA6EC99E5ADA
-:10B82000B287E57EE9F44E3DE56F9C663CAE72BAA8
-:10B830004DA1FDD0521F63EB402EAD7CA27833AA00
-:10B84000AE2599B09614FE1E7F1F66E9C6A8F8BA09
-:10B85000D85F49BD2AC75FBE4D6B17D7B06D7F4615
-:10B86000FBE9F4512E3F56B026D23F2B1FD0F6579E
-:10B87000B367D6A738CFE8BC8011C28F372D57ECFD
-:10B8800057CA5819EA8F354F7C6EC49F6089C71715
-:10B89000F8FB4F4387F1DF7DC227FE8E083E6FC95C
-:10B8A000F5FC2017FD3EEFF2F9AECEF5CDC9457F90
-:10B8B000C9BB7C7E17EA2E703DB32B8DF45B8BFDEC
-:10B8C0002E92FFFAC15CFEDF8BF735009C4C26718F
-:10B8D0006FBAAE499F48F64D80E8EC43E71D737E92
-:10B8E00040657726F243DAD3D36760BFCEA7AD1E9B
-:10B8F0005CDFD6724F21FA2FB656F3F3A166138F91
-:10B90000DF077E39F100865386766CAF40179DA322
-:10B910007B7F10FD42ADBA3F1FC6BC98D6C93C5FC5
-:10B92000325D17DA3F28623CA7359089F17DE768E0
-:10B930007E6F4E9ABEBC90CB7F6E2736085C5CE86B
-:10B940002A207F62AF41FA173B2C742EAB8EFF2E5C
-:10B95000C628C6F12FF3EA700E9176F1D966A6F9E2
-:10B960009D86511D4AD09048F7A8503CA86E4330A0
-:10B97000FD16D4674FA9144F93F34B7B3DAB02E305
-:10B9800066528FDDA238B8BF4DD8FD0B98FCE3712D
-:10B99000B7F9829E16087BFF162B87F752E6CEC3B7
-:10B9A000760BCD2C5107AC764B654729ADB3D690BD
-:10B9B0008C76858C1FC5B74762FBC91A7E61E7E7A5
-:10B9C0009E95BEE1D8C919F4415D863FDB853C698F
-:10B9D00018CECFFFB1A1CC83F1CA86D746D0EF30C5
-:10B9E0009912783C1CE49619EF113A84FA1ED6BDE0
-:10B9F000EA158BC85B0A8873CDFCDED8C639394599
-:10BA0000741EF1781FDDFF71DE10CA23FE067984F3
-:10BA100037A6BE92FBBB1FE0BDEB0DD960D741F945
-:10BA200074EE9F7879486825DE1B9992778997474D
-:10BA3000853EC1724E5EC26C2A178556EAA13C3E15
-:10BA40002F939771030A0436356FF06C3FDA2DC9D6
-:10BA5000C22E7087E8BC77C3CB237491FE58771E43
-:10BA6000976767843FF94C3EBB6D0EC27B64ECFA6E
-:10BA70006979D2DE6EA3F5C9F5CAF62C3376BBFF21
-:10BA800010727E9538A73DC5CA5A2D3CFEE74F047B
-:10BA90003C1CEC1E41F1CB7FCD4DE1FD3B42744F90
-:10BAA0008FEC27FA771CE4B8AB15FE7B59E7A3F2BD
-:10BAB000BC7E97CBE52B8CB391C619EAE1E79BE7F7
-:10BAC000E41422FE006FAAC09BCAF7C9ED7C7ED0A9
-:10BAD0002FFEFE13E88762F4FB1FFC0AEAE787E704
-:10BAE0001D4D2727C538AB5A78DCB62FB980E869D9
-:10BAF0008A55DCF752A25DC7F83C6E9FBAF392C537
-:10BB0000791D09AF0C85C6691170CC090D9F33F6FC
-:10BB10009BAFFBAFFF4BEB8EC09707EF6D39D8C5DE
-:10BB2000EF371E9FC7F185F49C4276E0764D7F6724
-:10BB3000D647B59FC0285FAE21A580DADF2BEE6F18
-:10BB400095F7D961BBFC71DCBE45BB57DEA7C1FCD4
-:10BB50009359641CB2FFDE8C0E71BF70FF3A6F28E0
-:10BB600011EB7488753A22EF33ECE7CF637D79737C
-:10BB7000ED03E9B81FFEFDFD8D2912FD69F83C5665
-:10BB80007FC8D7F1F072551E9727DF1B5EE43CA3F8
-:10BB9000E0D90FE7A8F94978227F53BB315ABA940C
-:10BBA000F3CC11F43980BFF3BFE578E27ED9FABB5C
-:10BBB00079BE387369E9BABE335F87F909B2DD0728
-:10BBC00078C0A034EC27BC214FEC2773584E9CBCA6
-:10BBD000476F9E33A67F91DE47EF277B93E5EFD932
-:10BBE00069FD1ABD4EFE7B39FE73FC7E836BA3FCA0
-:10BBF0003C188F7ACE166E17D62FDAF263027E03C8
-:10BC0000FD547D7938BF1253C5F3F83B5BABF34A63
-:10BC100067AB6077942455DC990FE5A6C7C693FC03
-:10BC20002E1954F1793EC8F3358F4DE0DF47577C2C
-:10BC30003E04CB791379798AE77994F760B4CC9E86
-:10BC40009A15B62BEECC73D1B8FA4A1DDD6B67425C
-:10BC50002306D6637ADD44F98012AEF19E25265D77
-:10BC600053ACF3BFF7F4D3038FBF4CC07FBAD01FE0
-:10BC700028FC052155E32FE84DE4E7CF7B5FFD92DB
-:10BC8000CED7DC9BE75B9F07ED1BAD676FCD87F2DF
-:10BC900006EB0714EF533C6087A01FC6E5608B607E
-:10BCA000BECAD9AD5EB49FD86AB75925B80AFF1885
-:10BCB000DEA907F07BE5B5A77E3C880FE3C5794C8C
-:10BCC0001472A0F1B5BFFD15E3C48D676C6E341B13
-:10BCD00027763F7C27DA5F13BBDFFE1BD7C3FC3C14
-:10BCE000909CF744F47FC2FB095D269AFFC4EEAB3B
-:10BCF0005660FD6BDFEB2E403AB9EE44B005C5420D
-:10BD0000EFABFF3E48730E887D7AD97CD1B8F1390C
-:10BD1000098F3F01A093081E3FE7F0F88AF2D9CEC1
-:10BD20003B8F6E0E9193547BDE0AEC788A3B5F600A
-:10BD3000096E8C7BC873FDD17ED5E3D5B03E787F8C
-:10BD40005D1FCC20C29E9E72D10C82245C2E67C9DE
-:10BD50009A72A5394B53BFCA91AFF93E3DF32ACD34
-:10BD6000F799AE424D79D6C8899AFA37BACB35E5FC
-:10BD7000D913666AEA577BAA35E5C26087A67EF1C9
-:10BD8000912EEDF7634C8F78283AEE7E039FA5271E
-:10BD90003DE49E2D3BD5F4063E27FE858323DAAF96
-:10BDA0007CCDC58E37F0BDF42B479F9F927EE69BDE
-:10BDB000F5B68031B63F39532D08DF83A0D7F1F3B4
-:10BDC00053EF25FBFE807893E7A7A6A05F1990505C
-:10BDD00075DBB99FE2EF325C58C4FD6EC711319438
-:10BDE0004F6E277FE57143D3B37FE47903B928F71A
-:10BDF000AEEB9BAF59F7948B3ECDBACBD9AA283C7A
-:10BE0000DDA1295739EED6D49F9EB95EF37DA66B8E
-:10BE10004B149EB66BCA37BA1F8EC2537B149E9EBC
-:10BE2000D27C97F4DD2DFC5FAFA1DF0A9E93423DEB
-:10BE3000958887C9A7FA081F137ADA2A114FD71CE9
-:10BE4000EF207C9504BD95282ECB8E34BD81CF206C
-:10BE5000ECCBB0DD81E64C7A1E6C7691FFEB70F393
-:10BE6000487A1E6976D3FBFF689E40CF5F357BE83A
-:10BE7000F99FCD33E8D9D3ECA567477307D57FAEDB
-:10BE8000B98BFBCF52FBEFDDC845BFC1795DA8017F
-:10BE900023C68EC15B499E9E4F089DC7F2067FEB6D
-:10BEA000ECA92034F0671D902F7F209E452E4FFB7C
-:10BEB00060780E1ECCF8FD19227FA343E729443B8E
-:10BEC0007CF4E30FDEA7E632B669BD37137F3A187C
-:10BED000CB662813B2E9F7901EBCCF93C3D8B3A8A2
-:10BEE0004AE8BEF7076763B957FC9EE7E0C71F241F
-:10BEF0003BFC5BC7D93D03E2ECA307C788B33F7B9C
-:10BF0000CA65477FCFD1AF46D8111E4785DFCBC367
-:10BF10000A0DF83B1CE56AA101F5ECF138E7215464
-:10BF20005379C9E0525CB77B1EE5915F6FA0DFE1FA
-:10BF30009BA3F0FDAFAC97ECE2FAA0F74613EDA798
-:10BF40008EE93C2B903F7A95BEC710CE373DFE144C
-:10BF5000E9A95E7B5F1EC2AFFAF1BDBCECEC7B4C85
-:10BF60007147940D1C3E958F3F39DB6FFB5EE133CB
-:10BF70001BD7110D9FB9831D7C5F11F4E4A21D2016
-:10BF8000CBC7AA3DF514572CF70CC3751CF59A388E
-:10BF9000FF7AED8161E437F294CE8BF0FFF40C363A
-:10BFA000D0FAE7A2DE443FE8427D20D6EF159E1F7F
-:10BFB000CCED3DA213DC672EB0D2BEE0988EDFA39D
-:10BFC000105DDFEEE2FBA3CFE2DC879C28BE57DCEE
-:10BFD00054FFEC0BD05FEF5A0B75DDEB1D41F658AB
-:10BFE0006F13401768BAF754D339FEDDE41620A169
-:10BFF00038EF2DF82FF8FE6CF79D5FFC06EA7FB056
-:10C00000D6EA261DE21845F05B282A2F4E3593FD0F
-:10C01000B4784E6E05EAC55B44BCF056BB9A4E61DF
-:10C020004335D9E8807E96DB0A370304D9CAB46A5F
-:10C0300023FE64534DCE1D9BF1B97AE87623F25866
-:10C04000DD987D9BD18CAD07162E25F9177AA7199F
-:10C05000E675DB3ABD8BEFE7E4F9DADA6F94F722A5
-:10C06000E9F798C84F0220D07E35C9A568F649493E
-:10C07000824E1F182CE23163D9D84BDA78D74EE4C0
-:10C08000A3B38BDF191E271EA1FD2EECC7DF8A7B11
-:10C090009EA3EF4F91E33A5C7CFF75CC089489F640
-:10C0A000E442AE07C6CDFF7C4329AC7F5CB7434773
-:10C0B000790DB7D5BF8078B8D025F068605DC84FDE
-:10C0C00037F9977CF01B424C9AE6DCF095F4A5BB5F
-:10C0D000C75119A92F4B42DECA487D39A1AFAD1215
-:10C0E000F5A2D48FC1E61A218F9B488E1E6C5E4745
-:10C0F000E5C3CD7E7A1E696E15F2B88DBEFFAA79B2
-:10C10000A790C701218FF7D2FBEEE6F9F47CADD9F9
-:10C1100047CF85A9BED7116E328E3BD7ECA3BCDCCE
-:10C12000430F9B18C6F12E749B288F0338E2B1474A
-:10C13000D2304FC944E744A3F395A2E57C3F3D7458
-:10C140000EB8B7E56DE4F7FE3C23B41707C7A7A701
-:10C15000A3CC6547B9F4F1E0F324878EBA5C76B4DA
-:10C16000A74F3E2ECA1E97DD00E53F0DEE25FD715F
-:10C17000D4E7B29BA0FCC9E3BDFCBBDF65B740F9C7
-:10C18000D3C17DFC7B8051D0FFECE02F488E9533EE
-:10C19000E520F247A5397F2AA80BD0D7E507912FD4
-:10C1A000A6672E998A7CB160B08BE872A66BFD41C0
-:10C1B0002CCF1AD9AEE215151E5BE1466C5791568D
-:10C1C000AD62BBA939776CC476D3866E5723DBCDBD
-:10C1D00018B36F23966F70B7AB689F2E4039561A0D
-:10C1E000EE4796E57729A7653EDDD5DD5ED207E30C
-:10C1F000BABCA40F245C2AE6566F42FF676397E23D
-:10C20000C0DFA5A998ABF4273360EE6203DE930A82
-:10C21000F2FAFF3DAE77AC87753662F91A2AB7ADF0
-:10C22000FF06FAED7F00F6E231E800800000000032
-:10C230001F8B08000000000000FFD53C097854E582
-:10C24000B5E7CE9D2D64924C360842E2649924965F
-:10C250002C43B6261064480CEE3001F944651910E1
-:10C26000C2164804EB17AB7E191A17E0698D6BD123
-:10C27000AA6FC4B5AFB6E461D458091DAA52D287DB
-:10C280003A5510B47974A488F0999011DC78D2C72B
-:10C290003BE7FCF766E6CE248014FDBE078693FFDD
-:10C2A000FEFBD9CFF9FF5F008053F8B3027F603403
-:10C2B000FE38253D8C046804F167BFD16DB295034B
-:10C2C000AC34078CA0A32F41A3AB1060AF0E9676C1
-:10C2D0001400A424C3FC7A0B968DB0740B96E75D12
-:10C2E0006803480568DABA206E8185DABBE36660C8
-:10C2F000FB4517E2AF38CE52056E54E0930AD49B4B
-:10C300009C89344F9A4DD21FCAC76F8550784A0610
-:10C31000E8B79A3DBA048044937BAC0DC7ED9BFB14
-:10C320004E835887AF88D6316CBD1EEBE300326C6C
-:10C33000561E1FCA8219545E09ED46C846B8F5CF8D
-:10C34000FBA422DA97C52723844E435F205FECF9D4
-:10C350005416FE63063D54E07AE9036E6999D7707E
-:10C36000206056EAF1673974EC706622DE5ED47E96
-:10C370006F04BF18BF43FB7D15E28DBE377569BFE3
-:10C3800003545B0F8D433002CBB8DFD912FE5E85BC
-:10C39000FF0D8F874967C0C3A4A1F010B51FF01A25
-:10C3A000418EDED70ACB6EA673E4BEC09DCAFCD117
-:10C3B000088121F7A7F245F4FEDA05FEF502FF2514
-:10C3C00036E7745A5FDDFC389053008E6D35794D39
-:10C3D00099DCFFA93D2944179375832D9A3E5B5B39
-:10C3E0006783DE00B0ADD5CDD0D7BA14F476803FE8
-:10C3F000B53673F9ADD6162EEF68F530DCD9BA8EA6
-:10C40000E15F5ADBB97E57EB462EBFDBEA65E86F8A
-:10C410007D91BF5F3B7F6586DB124DFFD5C9CE4561
-:10C42000C48F9E7BAA13993EB8F753C8AB9E1AC817
-:10C430006FB644C30183659D94C0658F11F7E1D940
-:10C4400016E36DC37DFD738CBB89C619A8097EAD4B
-:10C45000437C434A80F1D030D2BD9ABE4B461C3A51
-:10C460008966F5E412FE0EEB3CBF0764D9569BD3F8
-:10C47000A5473E381A8F551700DC82650FCEF3783A
-:10C48000AAAB85FA417EC048E39CA23F93717C0928
-:10C490006677F03A10A21C0EC408E8B1492C8FD17F
-:10C4A00050C8DD40BA9FF960E0E91319B68233CB7A
-:10C4B000C570F8A893AB039E32A46765ACC384D55E
-:10C4C0007D12F8A412845346D6008ED3976ED413EF
-:10C4D0009C14445650C7C39FC9DF226386F1CB1416
-:10C4E00048D4946BCDA335EDEBAC999AFABEF45CCD
-:10C4F0001EFFD2B48B34EDFA46579AC5BC532F2396
-:10C50000D865746F5C80740956991C9BB0FEBD9809
-:10C51000F822280698161BBF89E07B31195E6A371E
-:10C52000EDC0C914C07D4E937D238B105597DBC69B
-:10C530006BC7ED995363C37657E65769D721C12579
-:10C54000B4DFAB1D5334DFA7575EAEE9EF32FB9388
-:10C5500008ADF5CE7ACDF7C696AF419F0C30B1E568
-:10C5600024E84B01C6FB3A34E394EEECD2B41FBF8F
-:10C570001B6412EB927D8E3709961F74CAC42A156C
-:10C58000879BDF2458F5A53F83F6014EB059519F94
-:10C590004B8ADC8347023D962729E5CAA0B72D8147
-:10C5A000E87012F2F548BF8930C2216363A9F2BF77
-:10C5B0004E101F4C5220003207F6AB164B80793AD2
-:10C5C0008BD798456A05E51BF5C106C991A6473882
-:10C5D000470E5450F928048A08CA3A979EF86B2AE5
-:10C5E000348FA5B209DC69043F4874BF4F7CDC2F4F
-:10C5F00005DAC4E282C9C4CF753FFF68DE6DAC17AF
-:10C60000621C265CDFEFBAFE914A6BFDBB3FF591E1
-:10C61000376C217E6FB27ECD7852CB8D2DC7197FBE
-:10C620006AB96F2DCC77E192DB0D689F1036FEAFB3
-:10C63000CC760AEDDA3AA25323FCC9B8BA20D41E4C
-:10C640003ABE18C47731EABF7A5AD304C2D7DF5D45
-:10C650004E6C576F1072089E45F54E1CA73E46293A
-:10C66000834FD4A72AEDA1B29ECBE96A7D95686F6E
-:10C6700057C77B58B41FAD9695F12E52CBCDA29CD7
-:10C68000A9CEF7A02817AAE5FF7071394EB43F6113
-:10C690009B55EF2908E9FF53AADD180FE3C96EA0E7
-:10C6A0003D9033C91E48BB1A981FA2ED85B65EB1F6
-:10C6B00017F37F237B8CC5448FCB63DF21B9EE90CA
-:10C6C00080E4BAF17683D38BF37F9ED451B4C61243
-:10C6D000C2DFE7B7087CBB6AE39C32B65FF96ADE6B
-:10C6E00026E223396EF7C885F8DD3A56C77AA74E99
-:10C6F000B63881E87BAFD0FB6AFF48D8D0F2868697
-:10C700009E51F5B2C4F3C16CFCC1F9FAEF1BF5F40C
-:10C7100006C2598E3F9770939929F4DC48D4AD95A1
-:10C72000F8F336EA5933D23D251B9C3A6C9FF21A36
-:10C73000EA67A2F141BFD0C7AFC5F824149C958F1A
-:10C74000BDC9F66FA18C528EF87B2DCF9D97897C49
-:10C750007A34CE9F4B7CDBD0B28DD7758DDDCAE3AA
-:10C76000833558108ECFE2CC28FC979E01FFA53F61
-:10C7700026FE718203A4CF752874B4BEE596B778FF
-:10C78000BFCB95EFAC5F3243EDB82C47978FC639DE
-:10C7900032081F0E854E0774B60A055F5713BEFA9E
-:10C7A00017FB7313B1ECF0F947BAD93EEC2A97881E
-:10C7B000EECD7140743F2AF98BF60E41FF8ED60EF6
-:10C7C000B6CB5B5ABB18BE8473D0BA557CDD108DD6
-:10C7D000DFF967C0EFFC1F13BFA3F401A303FBAD98
-:10C7E000DA073C4E85FF8011C2F44C2BF125E2277D
-:10C7F000A14BE2FA3AB92021A0A98F13FE528E7301
-:10C800003CF1E9CA19BBAA37482179981C0B1D31A4
-:10C8100049CCD70E85AF1DC4D72AFF223F96EA1117
-:10C82000CF6F9DC47E43E037C4BFC0F3A878BA3B46
-:10C830001AAF1B888EA7C1ABB6FE07C66B27FAC717
-:10C84000A43782AFC478376546E3F9770A5E557C32
-:10C850006F53E47F383C6F233CA79E7F3C6FCBB483
-:10C86000F1B891F81ECE3E45D2475DF710725A7E60
-:10C870002E723A2DDBAAF8DFE8771646D3FD6DA2BB
-:10C88000BB5943F79E33C853CF8F294F91788B8480
-:10C890008D12B83A2CD1DF3FCB1C56DF9D173C4E92
-:10C8A0000ACED6F86793BF756BFCB329186169FD92
-:10C8B000D89B34E53AEBAD9AF697A6ADD5D45F6E2A
-:10C8C0005BAFA9BF32FF014DF96AC763117EE6D3A2
-:10C8D0009AFA7AE76F34F5739BB76BEAE7B7F468B7
-:10C8E000EA1778FEAA29AB78DCDA0A1C2F6D6B35C3
-:10C8F0002BF1D3650CAB03FE5A12838B0F07D9DFE4
-:10C90000ACF4B7D7B24BB2AF83FDD1329FAB96C276
-:10C91000AA8A9DCD6F12F4B55A95782D8DE15BAD45
-:10C9200036D6EF3B5AF319EE6C7528F15A25C35DE4
-:10C93000AD4E254E73318CB40BAF66BBA764213D61
-:10C94000A6BDBC4407B880E97FF867C15E5ABC77D2
-:10C95000BC8EE2DC35CA5E8E577FB3FF36E4AFE3B0
-:10C96000CD2607957BB71F31D80AA3F965EEB732FC
-:10C9700038C3F86C6ECB5F0DE467CD450FBA630822
-:10C98000399D9AA5637E20F703502FCC368321056D
-:10C99000F5C1ECD992A30DF8BB079218FADC583F09
-:10C9A0004D0F3E1396EB2D7A9F299E97E632A33FBB
-:10C9B0003D4B2C134C7AF0503DA424739C7E0D7D8E
-:10C9C000B4A13C3865B818BFCF223F1CFB5D6FE9AE
-:10C9D0003090DDBD6EE72FFA6FC37AB8D353CEF136
-:10C9E0003D5C6225FD2D793ED69D1A37BCBC2035B5
-:10C9F000E150185F4F25194EA5F8D1E17752DC7A46
-:10CA000093C1F19C2DBADF05CA7EA7C912FB6FC185
-:10CA1000D74DDE4D52483E717F3B4DB8CF26E201E7
-:10CA2000DA67B3C19757447EF676F6B39B2AD716DA
-:10CA3000119D9A2E913E311585E29DA6962FD98F94
-:10CA40008FD4CF91F04CF190C36F65FEDBDFBA93CA
-:10CA5000F9458D8B7A5B7D5C2E0BB86AC3E3A339F5
-:10CA600093FF4DA6B8A7EA4B11FF4C3CE9DCFB5302
-:10CA7000DC77A0D5FF2FE517D4BC829A6788CC5B02
-:10CA8000A87A64DEAD75096EDCEF9A2C5106F3943A
-:10CA900074A6A35E4055DFDE9A156597EFC83ABDD0
-:10CAA0007ED6D6FFC0FAF96CF9BF314DD8D548BE55
-:10CAB000DF37E30503AD53E5EF48FE9F437D70FE8E
-:10CAC000394D92D7837A7AF69276C344E9DCF97DC0
-:10CAD000B9E5A0888B23EDC2F7B60736A69B5C2B81
-:10CAE000737C61926F72501E44A5434734DD3ACF88
-:10CAF00040B7CE1F936ED176F1E0BC73B38BA0F13B
-:10CB0000CFDFCB8AF2273EC83ABD1FA9ADFF81F720
-:10CB10006D1D6B63B87244EF3C5927EA457C620196
-:10CB20001DF2EF8057E6B87469667B3CC533501937
-:10CB30008C277DB7AC5B06F20F41EFD48F46FE5CCD
-:10CB4000A2F0671FF83E247E5C05F77E4109982518
-:10CB5000D54BAE223DB7F40943084FFCAF93F32702
-:10CB6000AB947ECB2D9D46DAEFF267B5EDD4711A0A
-:10CB70005F8AC81F575FFA19B0DDF073DE6F55A7E3
-:10CB8000B6DF77597129876259164B08EF67D2A72C
-:10CB900047C9AE1BC2CA275B39BF203FF3E0039EE3
-:10CBA000B121FAC46447F1715CF6E9F9585BFF23DF
-:10CBB000F3B11CF7AC91E8F97DF978BFDD9945EB4D
-:10CBC00056F5F3A0DE79C3C47A67A0DC26F2A43759
-:10CBD000FDAE2D9EF8E40438881D162AF9D2856A28
-:10CBE000BE749D365F3AB9CFC779B94907BD6D713B
-:10CBF00048F789BD1ECEDB55ED76B759B0FCD35D45
-:10CC00004E99FCA3F16FB9645AB7EADFA8FE4E480B
-:10CC10008FE5B0BEE3BC6BF6D9EB3BD52EAAF63060
-:10CC2000D20E5606DB6BC9FE4DF8B6E34D82E72BFC
-:10CC3000AF1E69F7DE8B137AE2A8C157BE97FC8C52
-:10CC4000D7631CCF41F4FAAFCB167EC64CCF02039C
-:10CC5000CB1F091FCADB0C456EAE4F765F974DF5B3
-:10CC60008ABDD0999D06B2A37572DF23D7125FF9F2
-:10CC700065CE1BDE7CC707BFFFB5EDCCF98526EB83
-:10CC800071F63F868B339A74E0A6F8A2A4D6564A72
-:10CC90007E0CC56D944754F38A91ED9FB0D7ACC814
-:10CCA000E63C57B5DF49EBD928D6331CBD9A5ABEAE
-:10CCB000D0E431879BBFA9BBDCBA304C3E5ECA16BC
-:10CCC000F12ED2DB7AC81CA2F7D9F2C5FFB7F865FE
-:10CCD0009A0C1E09ED6CA1E415FE2F083F780EF8A2
-:10CCE00019CE8320433758F97C6A2138182E021751
-:10CCF000C37CBBDB4B7C3360088E24BEEA7FF5BB74
-:10CD000002E29BFE8B27B657C1F93B5F8AF4FF0610
-:10CD1000C6DB78FE8157BEDB43FC397087E1ACF49B
-:10CD2000C6EA646727F151E479CBBB53643ED7016F
-:10CD3000FD7A968B7AABE80397A4721BEBD84CE68E
-:10CD40008B90DE1CF5B4AA371760BFC24F74ACD706
-:10CD50006099E4B563D3AE808E45AC7071A657A6DA
-:10CD600072A7A82F5C99E895B05C581523EA6F4A22
-:10CD7000F44226C5430196CBF900AC0F1780D08B47
-:10CD8000378293F78991419684FD176F3597703EEE
-:10CD9000160239A4FF8B288E1A224EB7E608792F87
-:10CDA000CE12FABEB8469B17F9305BC91BDB6B4A43
-:10CDB000721056E738F7121D8B93FC1B1E2AA37CBA
-:10CDC000900E36A17C7D56752B9F77AAFD1AED3506
-:10CDD000BD84BFCD1270BCE2E936799F13E78C2386
-:10CDE000C3CFCDF2EDB507A8DD115A7BF9F078C5B8
-:10CDF0007E1CF747CB9587D7574CB11BE7FBF14318
-:10CE000025CFCBE5FF79E6EBFA3B0BF84CC1437E2F
-:10CE100072A3DD7D9CD76F04B0D0FA9F14711440CB
-:10CE20007306E547973C65D2919FF1119A63C80359
-:10CE3000F81BC6DD04FF1BE367827FC7F899E02774
-:10CE4000183F13FC07C6CF04177F3B1E8322808D3B
-:10CE5000394E4B4E79E81C3072BD861C81CFC1F92A
-:10CE6000BB8D3C7F9DDDCDF81DA4F7EBE0A573994C
-:10CE7000CD89C10B924EC36F03DDDFF0F9E9707805
-:10CE800051CF2523EBBF53E85AD4A967FB5FD415D4
-:10CE9000886F086B77418E91EB0B5F39184FE31F5A
-:10CEA000B50EE2D729E196A7E944F982672D330848
-:10CEB000BF75766709ED1BE53C83F651D4F5C18358
-:10CEC00013CB787CAB64A375041FE5B821621F9176
-:10CED0007850F7B539D1BF81FA6F7E258B76827A8B
-:10CEE0000784DC101F4943ED772DF3CF7453B0CC8A
-:10CEF0008AEB9D7E4A6E1E0AFF75F6298CE77754F1
-:10CF00007E53CFC715FE52E976AEF21D391E906BE7
-:10CF1000847EE76AD2A536B24B27E3C92FAC57EE21
-:10CF2000197475E6BC47FBF4EC94C16E633ED6C839
-:10CF3000DF62855F5458D86D7411BD36771FCA59AA
-:10CF40006461FAE42CC6F6B372EC9ABC6761D589C9
-:10CF5000C71F4AE1F6569AEA3A78BACE8AE3DF600A
-:10CF6000DEFE366D69AEF593BA442CCF4F93761042
-:10CF70005C60CB9C9A64A3E57A79FD37E64FD94192
-:10CF8000227595A39EFDB929A464C2EC43AD3996E0
-:10CF90000E1F07CB75D6644DF9D2B4319AF697DBE4
-:10CFA000B235F557E68FD3D4ABF35EE528D5B42B75
-:10CFB0004E0A66515C87FB60B980E764AF5DA27D75
-:10CFC000EFBE621C96A73D3FCB416ECA66A57EDAD6
-:10CFD000965A2FD16300F1694487EA70E5FA471F3A
-:10CFE000A2C122E286C6EE6776386DE710370C13D1
-:10CFF0002FAC00718E3F5CDC10192FA0FE7C90F4EA
-:10D0000067F1ABD758DB70DCCD55272EB0E13EEF92
-:10D01000CCC13882EC8D12470CC73F837222D904F1
-:10D02000FFF4C8F0DC10FC03F00B851F059CF63EF6
-:10D03000FA3305DF5FBF7D4AFA8DF3071EC5EF5750
-:10D040006044BEAFD8E8786F0DE5A7DE9181CEF9D8
-:10D05000E124AE03EB1BE87739C4F7B0E8E9BB463F
-:10D06000A7F0770FB9A6AB94FCDF1F7314BFAA71AA
-:10D07000FB5DA3CB42F570F3279AF670BB74B7A69D
-:10D080007C67A6B67CEF94BBC3FB0FE797356C5C5F
-:10D090006074A39C363C2C39BD43E88BC1F5A428B1
-:10D0A000FAA17B09EBDB43DB97196D71D1ED57E1F9
-:10D0B0007894B76C18C6DEAA7AEA3A199A87AA7FDA
-:10D0C000479DCF717EE7FB08714FF6CDF39AB0C351
-:10D0D0001F25B88DE17CB22F479C7BF43FF6C01D25
-:10D0E0005FD379EEEB22BEEA4F14F6A3A8F3339D8B
-:10D0F0000E61F108C15F45D6808EECD2C0D2580FC8
-:10D10000A09C352D8BF3E88AC98F087E681E4F5E80
-:10D11000C72D0F9A91CE1FEB741ABB3C40C11696D7
-:10D12000FB9EFDD98C3BE9F702712FE97CEDB32F13
-:10D1300007847DAD117A631EF19F62B7005556D307
-:10D140005D3068C748CF105EA89C6BBFF5FD87C9EE
-:10D15000CFEF117A83F20A37B05FE0B468F30D1DA8
-:10D160002CE7F8BB2DFC3ED759EB8FB7DA8D96F341
-:10D17000A84746D8B5798721F4C5FB57223D9B5E69
-:10D1800097F95ED0B1ADF60408D31F91786CDA2818
-:10D19000B39CABE5A35BE5CBBC6C0F8319F585D1E4
-:10D1A000F806A783E57FB555CCB77AD23733C84E9A
-:10D1B000AFEED68B4B2FC3CDB34E065BD83C9BB79F
-:10D1C0009996925D53D73F6055F449F75749530AF2
-:10D1D000045C3B847D45BFC090427E41BDC4F1EC00
-:10D1E0009EEE513584A73D12F86C253CC435665C33
-:10D1F000DF4C311C7DB7505E14D2F2F99EA51AD7D0
-:10D20000AAF1ECACEE5976F2633FEC5CB807290763
-:10D2100093ECD9CC4FD78287FDEE3D89AE74CA938B
-:10D220004C53EE3FEC490CF691BFBD6752AC44F74E
-:10D230001970FC3B697C755F7B0CAEF466DE9792DF
-:10D240002F75FE443E157BF671A2AA67EBE4DBA7BF
-:10D250005C49E7F773C04AF1EC7459F8D5F04721FF
-:10D26000CFAA5E6D92FC496CAAED33A6DB114FA3E9
-:10D270005A7EA9E47DDB35F700CFD6AF1E8CA35FC5
-:10D2800094987F563944BCB1AAFAF347AEC5F95712
-:10D2900061BC4FFEDDC2AEEDFB087F91F1FD607C0D
-:10D2A000F52FE67BA3E333D732DADFCD771CDF73CC
-:10D2B0002D44C769837181EA5F3E17CBE7D6A85832
-:10D2C000857C28FC7A645BEEDE35587FE42F0666A9
-:10D2D000D73727FDEAE8AD58BEF9B958C6F391240F
-:10D2E000F0901D39B229CFEBC1064B74C15EB26F0D
-:10D2F000B0258ECF693E7B32EFB72F517EF2B776E5
-:10D30000F643487E6CE8C27C46F78FE8FBCBA3B9B6
-:10D310001FB8C5BC0D8A5CCA2F14DE5F4DF52F24E3
-:10D32000737E42A5DFE127639C14AC7D05BE222BF2
-:10D33000B2DEE792E710DD5B5CA17B69BF847CF91C
-:10D34000D508F706DAF7F2C7FFF3C389B89FDA17F3
-:10D35000AEFE5515AE6FD907A940E384E83AB4DFB5
-:10D36000706C6BB6907F053F2B5E8CF11E0CD32743
-:10D370002B3B1235E5A6AED1DE83617A68F09E7252
-:10D38000A3C4E7048D8A5CED37BADBED94D7A5FB27
-:10D39000A94C3F711FB584CEAB08FFF79918FF91D8
-:10D3A0007CF6A25D396756F33CC9604E23B9750B14
-:10D3B000FC0DDC97B789E2319F3D49F13B82B933DF
-:10D3C0000AC3F9B377D51B9CE731897B8F31439F23
-:10D3D000EB77DA13B97D83F94B4D9E6955CB094D37
-:10D3E000FE675501B01F50D2662BBD89CE8714BA97
-:10D3F000DC9FEE7A8DF1DEF1C0ABBB189F4FDCF203
-:10D4000031CDBBD3C2F4835D4A3C16116F3598BF52
-:10D4100050E4EF698D7F7EE8B1BD4594FF38F4CAD2
-:10D42000B822CAD32E94FD877E9DC9F79CF6DF866D
-:10D4300070CBCEF7392F1EB9DEA87B0C92D0438D6E
-:10D44000B48F64BAFFE37AC7CE722EF4C3810D8520
-:10D450008C3F351F3D7064E878505DA73ABEBA3EF8
-:10D46000757CB5DDDFEC225FD06FF41791FD5F4175
-:10D47000E73061FBEA8FF717255AE8BB55F81349E7
-:10D48000580EE3B77FF5BC2AF27C6AF05C56C947B8
-:10D49000EDD3ADFD9911F9AFAFE321833B5CEF7E96
-:10D4A000CF732A75BDEAFDDA7EAB85FD9B937625A9
-:10D4B0001F9F0EE9D40EEB1D3EF2BFB7981CE4C7C8
-:10D4C000279A5C908BF86934FAF8FE9ADA2FD1E447
-:10D4D000E6EF9179F9814423D0BDE58154E5FCF76D
-:10D4E0002B60BD4271E8169CB7AC56D7BCC512D2B2
-:10D4F00087AAFE2C1B87DF0BE81EA93EE42720DF4E
-:10D5000094156BDB87F6A32DFF7BAEA06359B26E3B
-:10D51000C838B92457C8651B74C8429E851D9DA88C
-:10D52000E01D0DBF1CEED7AC52F4FC40BCD9430744
-:10D53000BB13B78A7BAB13F5BEED04510B404B1206
-:10D540005D99F489F1BAB4FA9C6CC81CB6CBE3D8E7
-:10D550002E4F50C87DB7D4CCF75B43F75CFD32C18A
-:10D560008B21C8D009563D412403C34BC0C5702A46
-:10D570003433BC0CDA195E011D0CAF023F43F8894D
-:10D58000AF0DD81EDC6E65FFE9F2253AB2CB65D748
-:10D590000EED97CF52F0353C3E50CB579C3B3EA60C
-:10D5A0002AF77287C5CBD87CE67B152F26E24FEC95
-:10D5B0001703DE34829320C0E34C2646CEA678DDE6
-:10D5C000C6F77E6BC1C9E5BAB3C44765C0AD77176E
-:10D5D0000C8197DAA1F9649EC22703B9C0F851E91A
-:10D5E000F548AE8DCB2ADD30504C237B104D4FC813
-:10D5F000A07596C5D61CA7A722B73F5F36538F7A72
-:10D60000B4ACB4660DA9905FE64E15E589352FD30D
-:10D61000517DFBF3978A72714DA9C1815EE8DACB27
-:10D62000665E82FAD9ADDC2737A311A07B6372B6A0
-:10D630003817762BF7CA4D72E65ABA2F66BA0D58CC
-:10D64000DFB86300FCECD722B791BCB8451C7BB3B4
-:10D6500055D0AF3AD67D4B2ED933B32FDE8674B872
-:10D66000796DDD28B29BF718C5F89FA4DAC6BD8195
-:10D67000F83299C4BD5675BF58EF89C17240B2AD3A
-:10D6800069C90CAD4B5DC759CC7BD7E9E6CD4F7767
-:10D690006F203D023607C7156314FBBE65CBC4344B
-:10D6A000F430701D565E47202E774D0B56DD91EEFF
-:10D6B0007A84C61B88137CF808D1297578E8CB7565
-:10D6C0003E943BC4F781B5DFBCEA23BDF4292E04A8
-:10D6D000C7F94DAEFB715A47932E90518AF4FB4522
-:10D6E0002C7A000521BE96909873100F6D4EF01A9B
-:10D6F000595E947736CAF9992A17038B713CC44F47
-:10D7000099CB558BEE2254CC6E7E9360A5BBBD1693
-:10D710006B689E17683D4D72B081F8E468E207C6F9
-:10D720004F596EC70AFE54F459F7B69EDBC688A25D
-:10D730000BC2E4B269DB89AFFF86746F3A66715041
-:10D74000F3903C3EB6469CE75A34FA4695D3095DC1
-:10D75000263E389CB8F5A2C5D46ED207BDD9A4B771
-:10D7600027F706DAC87D1EE8DE3B46C889EAD77F80
-:10D77000239D8B7DF9CC8CFC914010F9235E9C831A
-:10D7800073FCF48A38075FADE43DA9ECE17D8B784A
-:10D79000548D3B57F6BC2DDE8579F06F05BD2B12FD
-:10D7A0007F963E71E355C46F91EF8BD478B449698D
-:10D7B000B7A2D77B37ED27F2BD5113C5A345C3BF31
-:10D7C000376A7AA296E3D1C8F746BDB94AFE4AB194
-:10D7D0008FA0F8A14B9436B43F0BC78746AF09F72B
-:10D7E000B6FAC9350E2B95D32D0ED6C7573D0EE18F
-:10D7F000EDE18964E619559E97AD93D8BF56F15A6D
-:10D80000FCBCC949EB287E7E14FBCDE8EF8B7BE99D
-:10D810004A3E91DE12D07B83CD89C12CBA67BAB95A
-:10D820003BDF41FEF81F5A9DF00F43687D6A3C5074
-:10D8300027BF544BEF878E2DC2380B3FADEE79A634
-:10D84000CD8CE5D5EBE95510A584F313C8AF2ADFDD
-:10D85000298397C601EF43D5083B153937A5E9C0A1
-:10D8600016868F18DB08B00D910F3029F48BCD4F41
-:10D87000D2D4C7392ED0F44FA8CCD2D4B7C588F7AC
-:10D8800032E071FA0B2A42EF48129D3FD1F4830037
-:10D89000FEAD08BD17B9277EEA4E7E4FE26FE03C31
-:10D8A00045F265259AF62679AB4CFC5DFDA55E43F5
-:10D8B000CF9F52A61BF156B91BFD1C9C67429FB619
-:10D8C0003E26E001EA17B35BAFC94B986CDAF285EC
-:10D8D000794A9E622C8CD5E42906F12EF8FED86197
-:10D8E0001DF34505E4FCAABA8CF06C00AF2D1A6F4D
-:10D8F000C740F85DC7C65A1CF4966A42CFCB32C9FE
-:10D9000041AA4B8BFF51B3B5F81FEDD6E27BCC5249
-:10D910002DBED39BB5F8BEB0458BD74C8F166FD9B3
-:10D92000EB2668DADBDB6B34E5BC8D5768DA5FE445
-:10D930009DA1298F7BF17A4DFBC28E859AFAE2AECA
-:10D94000E59A7A95CF86E383F1BED511FCA603DD77
-:10D9500069F8A074E7CF35F3FD50F49F9FA7E80561
-:10D9600085FED72B76E5DDF8C3F792B84E8B157A96
-:10D970007030DF506DE078EE3D5B726D1CE905C5DF
-:10D98000DEB9147B07394F89B255941D7E71BFA251
-:10D99000649FAB36DE46F72CC4FD8A8AC3EDB50919
-:10D9A000D43EE21DD6F44A4973DE1DF92E6BA667FC
-:10D9B000AD9C20D1BD44713F31F21E84FA3EABDEF6
-:10D9C00019A339271FEEBD969A5FC278018C142FD8
-:10D9D000E8CCFC3E31DA1F726C94D95F73B3FFF66A
-:10D9E00067C9CD79A76BCCFE0CE2EFECB1EEF5790F
-:10D9F00088B7A33A878DFD3DE5FDD6006D8CDF2FFE
-:10DA0000F5CCA43CE90086BB94D7D4DFB36326BD34
-:10DA10005BC4E55B031522ACA63F8FE6B91FA4717A
-:10DA20000E48D6BB4BB1EFBB133ECF207B66A27333
-:10DA3000FE123EFF7E382FFCFC7B14EE0FF56D408E
-:10DA400067F3F079EECF258E533EA7C1AAC2E477E3
-:10DA50009D41794F2AE2B6B90ABED4B86D8E32FF25
-:10DA6000011C6229EAF3B95D7F66BCAC48EB53E266
-:10DA7000BD668715C7BF71ACA584EF7B394B1D22EE
-:10DA8000DE57E3B831F2F7B1B367BA87B522ED8854
-:10DA9000269E86979287CC5746E6C542FB16E31F23
-:10DAA000581FCB76E8C0FA74CE3F86C63FCAF985C8
-:10DAB000B9CDDAFBDDF35B3ED2F0DF02CF279AFA75
-:10DAC000404AD03006F71F7875F4D41B107FFDAFA5
-:10DAD000982A289E45BAF5E49587C60FDC97778982
-:10DAE000F01BCEB4CFCF791DBDCAFD5A759FFB5B2D
-:10DAF000F77139D01A88B8EFE4D1C4BF2A34FE09CF
-:10DB0000F2C98F0E4A231C43E57366E78B38A95789
-:10DB10007977DAABBC3BED55DE89F62AEF427B958F
-:10DB200077A1EABBDD5E099C74BF648EE47A6A81EA
-:10DB3000C4EF760FD13E9B96078BE85D635371600F
-:10DB40009E24F3BBDD23F47D8877BB459295F46971
-:10DB5000EA35F46EF7F008CF51B2D8D9F989D75029
-:10DB6000BC70D828E4A3F4C56F66D27BBDC753DD73
-:10DB7000C789BF3F95641FF3F3EB129F2B8333607C
-:10DB80009C7116EF7ABFCB13E73427F3C4B9890A27
-:10DB900047E60BBD564AB09CE8726F2EBFBBDA68F1
-:10DBA000E27757389F5317761F22F27D5CC91F4DCD
-:10DBB0003ED21F6ADE27215F9C37D3BB395A67CA22
-:10DBC000FD26F16E2EE0CFA07776740FCA45F2BD28
-:10DBD0001B9CE21D5EDEA6F0F73009F9CA3DBD458B
-:10DBE000A079A7B7B2E7C07ED227AFE5B993F353C8
-:10DBF00043EFC756C66F677FAF20DFC6F3E27A797F
-:10DC0000FFA817EE24FA9CC77C61567E79F4FFD7F3
-:10DC10006038BCF52FF63F5A90197AF716F6DEAD4C
-:10DC2000203F2CAFA7AE3F34CEE9E542CD7BA9E53E
-:10DC3000438FDD934B72867411F948599A3F63887C
-:10DC4000FED3F305FDEF4F774DA0F997378BBC60FE
-:10DC5000886FDA6FF998E8DC6319F23EBFDA3F7239
-:10DC60009F2BB7F5303E709FF3687F61FBBC8CF053
-:10DC7000A5EEB3BF7BEFA305B673DFDFF77D776E4D
-:10DC80001A81716DD2507976B43E617E9949ED3F2B
-:10DC900056AFED8F0E39E5B1BB48DED16FE954E2E6
-:10DCA0001EB2CBC417AA5DEE54E22029B083ED0268
-:10DCB000CD4B7271B7E461FBA8E63BDA24B47F94E4
-:10DCC0005770AF617B215F6871105F7722EFF94970
-:10DCD0001EF4CE58CE7347C4D73F8B75DF4478BC53
-:10DCE000F9AF35A328FEDEF2972B94384ED8AB72ED
-:10DCF000853FCB697EDA474102F36D99B2BE0A7364
-:10DD000033FBC955E091455E43C993ACDFC1F1DFF8
-:10DD1000FF011A14AFAAD043000000000000000069
-:10DD20001F8B08000000000000FFFB51CFC0F00374
-:10DD30008A739418187A351818366B32306868313F
-:10DD400030883120E46885AF7153A69F9B9581810F
-:10DD50001788F981581088D73331306C60225EFF04
-:10DD6000115104FB9E2003C351207F1990EE1466CD
-:10DD7000605805641F03E22F40BE801003830C101F
-:10DD8000FF1561603005D2C1406C03C4C745F19BEB
-:10DD90007F82807CBC082ABF1B8D9F278C5FFF255C
-:10DDA00011FCF20F08C863C33216E4C74722057A94
-:10DDB00007023729A2F28FCA33303C546060D05139
-:10DDC00082F09B91E4ED8062C7E421EC2992C0B817
-:10DDD00007CAB5286237772A50FE0450CE4B8934E3
-:10DDE000F7DCD341E5AF3484D000BC3E14E4A80393
-:10DDF00000000000000000001F8B08000000000071
-:10DE000000FFE57D0B7C54C5B9F89C3DE7EC6E92B4
-:10DE1000DDCD262121BCC22601440DB8400CA04115
-:10DE2000370F5294A8E1A1A2226C782421EF22F6A8
-:10DE3000621FBFDDF088C4521B1FC5D48B7651B062
-:10DE4000D18B3640D058175C9E458B6DE845A0D5E8
-:10DE50007A13405E06B240A5B645FDCFF7CD9CDDF6
-:10DE6000734E36266AEFFFF6FEFFDB9F1DE6CCCC35
-:10DE70003733DF7CF3BDE69B8964BE91D88713F20C
-:10DE800025FC6E25E451891092184E9B3C93C69F49
-:10DE90009409B1ED7E24EA3B99840C9E6B7046D1C7
-:10DEA000A25F08644E4B0621C9658D7546FA3D791F
-:10DEB000917DBCE808C319987CE4BABD09840C7252
-:10DEC000D3F66682BF2FE97F3FB737C69174C87912
-:10DED00085A231E1FA4A9ABC48FA7B87AABE9B1414
-:10DEE00075A6DD48FBFB51FD20B785901FC3784622
-:10DEF00042A9CB40B2E8B8785D6F2EFD3F3A0EAF35
-:10DF0000CDE85B2910221A1CB1442424262348A002
-:10DF10009DBE9F673CEDD74908A736AAC84AE74986
-:10DF2000C8B49608F57289807888CD76257BE97823
-:10DF3000577D2EE2BC570D22A49DD62792D34E6862
-:10DF40003A95C461BDC72D2306427ED5AE3F120768
-:10DF5000851B9B19245E15DC060F210E13C5AFC768
-:10DF60008CE92A8F9DA7C9C4710D21AB3D0E4C577A
-:10DF7000794663FAD8D027DB7306D0F90C32D8E99A
-:10DF800048488363A6DD91118627C72D30E73809FD
-:10DF9000C92629AEC4545A2FD140C84D84DC42F35F
-:10DFA0007523081949EC8450FC3D93BC2CCA9D0193
-:10DFB0007907E6450371C37C6332032E91E22DC6D7
-:10DFC00069CF951CE1EFF81B80DF5F782C15D6C177
-:10DFD0007D1BCCEF19E2ECF0029EDD46E7265A7F6E
-:10DFE000A5EC4C5E4AE18A46DA2E83ADBB94101E46
-:10DFF000DF4CC01FED8FCCC9D5ACD730184722B449
-:10E0000073DC05EB6471B2755A097415611DE6F293
-:10E0100075586577D919FD384924FA11ED5AFAB1C6
-:10E020006468E98F7EB19FBA9EE769BF4D42ED3BC0
-:10E0300053E93CBD4B0CCE4DF4DB60A15100F80A16
-:10E04000BC25C480FD2AF9416552A063B41A9E170D
-:10E05000CBE9F7F60E73CFEF2D06E252E872532AA2
-:10E060007C77C4CEA0E3266647EC4C6BCFF187E902
-:10E0700024D925C940EF0E4C1B0447AC00E37C4774
-:10E08000249B049C7F72A4F6FFD3ED08F1E17A375C
-:10E09000F07554DA513C203D791F8B463C88503452
-:10E0A000390CE7171CCF17AD454F434A48E3685872
-:10E0B0005F9A5F87F463A6792BE69BB0DC1ECA3FAC
-:10E0C0008BE5C9AC3E5D5EBA18BDE3555917DA6EF3
-:10E0D00003C29142705E44389650BF9B303F2094FB
-:10E0E000FF25D61FCAEAF7B71F25EDCE0D9EC2F950
-:10E0F000BF2E3B009FC2DBD6C0AD942E0E6E107CAF
-:10E10000269A0FEC8C41FE757EFD0C9F89E267D745
-:10E1100038930BEA9FDF9883F9BCEDEFDB245A5E5E
-:10E12000B55D94206FD879D6D641F15B636A7FFCE8
-:10E1300066FA3DB85D242F6077D3719F9DE2B448A5
-:10E140003E63F9922896ADDAB06B1EC02D6B339109
-:10E15000280AA7EACDD23B6FA6F9D20332812A550D
-:10E160009BEA8C83697E894F6881FC8A9D1F603F92
-:10E17000DDB9A40CF6F739E05B942F75DBDA93EE8A
-:10E18000A6DFCB7D5B0AA07EF966C1094B5CBE7E33
-:10E19000D78700BFBC551E2152F815CD31C4A1DA76
-:10E1A0002F79DB17DF09E3AD7A472694ED91B2AB07
-:10E1B0000F199118A44623E0B56AD31346E09BE7F4
-:10E1C0003C07B01F059F552FD37E68BBEAD70427B5
-:10E1D0004CADDAC0F8CD8537A3E6BC688179D51996
-:10E1E0004741FB371F3542BD525FF1EB510E18DF3F
-:10E1F0000663018C73FD0663898A6F5634FF5633BC
-:10E20000AE534DE903DD19BDAFE739CEB7957C3983
-:10E21000154048DF92CF3843C5879E33C421FD5750
-:10E22000348BC411811F78DFE7FB608795F103BE53
-:10E230005E4BEDC01AC2EB75C9CED74F0A66CD88CA
-:10E24000C0E71EE7F2A391CB8F27417ED0F4692E61
-:10E250003FD671F9D1E471E2F7673D93305DEF711C
-:10E2600061FABC671AA63E4F11D67BC13307D38D26
-:10E270001E377E7FC9538669B3A716BFBFE2598E8A
-:10E28000E9668F17BFBFE65983698BA711D3AD9E8F
-:10E29000264C5B3D3EACF7BAA719D3364F0B7EFF39
-:10E2A000B5A70D53BF2780E94E585F9A063CED98FD
-:10E2B000EEF61CC374AFA703DBEDF79CC1742DC74A
-:10E2C000BB2D9BE448146F36174139185FE8CA919B
-:10E2D000693EBE88E593E67A738C349FE4A6798A1A
-:10E2E000C7C195811C13CD0FAE65E5293F24B966E2
-:10E2F0009A4FF1B2F2B4B5AEDC289A4F6B64E5A345
-:10E30000D67B73A3697E948F955FB739901B43F3D7
-:10E31000D7B5B0F2B17E9267A1F9B101961F7FD057
-:10E320009567A5F9F1ED2C9FF5A137CF46F3591D5F
-:10E33000ACFD4D5D81BC589ABF29C8CA6FB94AF27D
-:10E34000ED03402E0B98CFB5E4E4C7D17CAE9DE53C
-:10E350000B86164B8E08F4B753EE5808227C86B015
-:10E36000D125517EB3D3D8F110157D64A1F0AA4B0D
-:10E37000A2FC3320934550FEB0F03A96078C641906
-:10E38000943F2ABC8DE5BB650796FF5C38C0F2461A
-:10E390000796FF877008F37B651796EF10FEC4F2AF
-:10E3A000461796FF5E3881F9FDB21BCB3B852E9652
-:10E3B00037BAB1FC49E953573EED2FDFE09E2EDC22
-:10E3C0000872DB5D8672596A49067E59CFF9FF04EF
-:10E3D00040062DAF1F644439B8F3F3AC174581D321
-:10E3E000F600C897BC04FA0585335B48047D82C2F9
-:10E3F00011FB8673CB179334706EF9A24C81F32016
-:10E40000C289EA1F9C9D5FDCA41DCF17E50A9C1200
-:10E410009C97B57FF3BAE5CB6CED78BEAC54E0D4F5
-:10E42000209CB8FE8D27204FD4C009C8A50A9CE5C2
-:10E430000827B17FE37119276BE0B88C4B1438754E
-:10E44000086750FFE0048C376BC763AC50E03C8634
-:10E45000781ED6BF79B94C53B4E3315529709EC2AA
-:10E46000F1A4F60FCE6EAB163FBBAD21FCAC473826
-:10E4700023FB37AF5C9B163FB9B6107E36219C6BF1
-:10E48000FB0767B74D8B9FDDB6107E5E43FC8CE9C2
-:10E49000DFBC7263B5F8C98D0DE1E70D1CCFB8FE86
-:10E4A0008D676FA2163F7B1343F809209C1BFB3737
-:10E4B0009EFC242D7EF29342F87907E14CEE1F9CDE
-:10E4C000BD495AFCEC4D0AE1E70F08674AFFE695A3
-:10E4D0003F508B9FFC8121FC7C807072DCCD4CA96D
-:10E4E000A470ACBDC3D93F4C8B9FFDC342F83989A2
-:10E4F00070A65238E97DC32948D1E2A72025849F20
-:10E50000F308E7B6FEC1D99FA2C5CFFE94107EAE38
-:10E51000209C3BFA37AF82E15AFC140C67F8B955DE
-:10E520001A877286CA4E27D8E7DF199AE31232C1DA
-:10E530004E6279D1EE24A0F7888A3E43DA5D22AD9F
-:10E540006FD91C37FE31A2D66B728D064ACF56AA00
-:10E55000E5A9F59AD849D11A3D2ACE15AFC9274C5D
-:10E560001BACA99F5894A6291F38E73A4DF920F70C
-:10E57000784D7E48D94D9AFAC36A7335F9E1CB6F6D
-:10E58000D7D44FF5CED4E4D3D7DCAFA93FB2718155
-:10E59000A6FC9AA6724DF9B5BEA59AFCF5CDDFD7BB
-:10E5A000D41FD3B242537E43DB639AF27181273585
-:10E5B000F909079ED5D4BFB1FD054DF9C463AF6815
-:10E5C000CA27776CD5E46F3EF36B4DFD29C1DD9A08
-:10E5D000FCAD9FBDABA99F43FE53AB6F9B3FD0D417
-:10E5E0009F6A3FA129FF4EF2273A3D556B1FAFCCE2
-:10E5F00021CCAF3288D9AF01AB11F3C6C11666A7E3
-:10E60000584B1C2729FD18772F740CA0F4033403F2
-:10E610007651CEE0B26B3AE8F7EFDDE4BEC64EBF0E
-:10E620007FCFE8BEC11E41BFA1F4269064481D06FD
-:10E6300048F5E58FCA8CDE73875C1DD549DBD7189A
-:10E6400082A3E268FE2331E73EA0C7F90603EE830A
-:10E650006891D442BD681341BBE9D1D4AC17BDAABF
-:10E66000FDB06618D5338430DC35B23B19F528C3CC
-:10E67000F83AD09BEA87D1790D2664D18A71BBBC68
-:10E680002368FB6125C9E08F3019993F24D4BF91DD
-:10E69000F69F81FD2F81FE6B7AE9DF943649D3BF67
-:10E6A00039A54CD3BFD948FBB713F290E126DEBFA2
-:10E6B00019FD36CB564CC6FE4D2965D8FFA3466AD8
-:10E6C00077A9FB8F0EF5FF8881F6EB3130BBB9C718
-:10E6D000FCD36ED2CE3FA55C3B7F239BFF4A432EEB
-:10E6E000EF3F1AE7BF6A450E9B7F4A399BBF89C13E
-:10E6F0000DF56F0BE1BF01FAFF692FFD9BD2B3B59A
-:10E70000F31F5EA99DBF89F5FF94E176DEBF05FB8F
-:10E710007F7AC56D6CFEC32BB17FA3C9ED04FA31BE
-:10E720000E89AEF5D1FEC9506A250D0472A1FD40D7
-:10E730003A3A1EFD08771AD2701CDF8B66F47625F4
-:10E740009AD21BF2332FB3C37D947352BBAA9AD3D0
-:10E750007AC5E61C23F03D2C4F2264311FEAA23615
-:10E7600011E99B3C6DF28DA4E3BDD0267A21BFE870
-:10E77000E9293EE0AF352632BF08DA492400DF3F01
-:10E78000FED99817D4F3D2A78B1BE55391FC45DE35
-:10E790005C32BA968EEF0210812A7F9CDA71601883
-:10E7A0007F48ED1E42ED9F1332EBEF236AEF41BE2F
-:10E7B00083DA7B6838933AE657F3BADE1F41C75FC6
-:10E7C00044949F0BE7792F6E290A4F62FBF7F85AA2
-:10E7D000C107EB317F790C457E783CC5DE044DBE28
-:10E7E000C6C4EA076F137C2F0808C30DF899C1E16E
-:10E7F00011182FCDCFB1B3364777DEB15FB0D17DE1
-:10E80000B466085D8B309C59C4250FA4EDEF5E56AD
-:10E810002C836BA75D1086819FB066A14C02683780
-:10E820007B134906270E3ADEFBED0CFE0C977C525B
-:10E83000ED479B239B5D45743C738A451CFFAC6987
-:10E84000DAF23FED8C7119C6D274CD53D8CFDD45C5
-:10E85000DAF27BE768F3F7B9B5792A576590AB0F21
-:10E8600094E9BF53B42481DF31F41B00E37C90E3CF
-:10E87000E1C15AD9AB59576A761B95727084B809B1
-:10E88000CE0BDB8B3DEBCF5FAECD177BB5F9856B48
-:10E8900074F039DD9CE2EB7F1CE883A6A7813E285B
-:10E8A0003E4F72FA08F3552D7DDC139A06A30F65CF
-:10E8B0001EA724B604A7D633FA58DC1813991E8A6B
-:10E8C00043F4E052D397420FF3383DFC99D34369A8
-:10E8D0009396AEEE23BED5C9B4FD036B77E13A1D26
-:10E8E000118A193DFC40A1870E0D3DB8393DE8D78E
-:10E8F0006F1EA787798F307AD0AF6707A7878EA65C
-:10E90000CB3249EBB9AE741D3479BA0EBA75B7A3E0
-:10E910001F8AAE47447A58109A379D38CD2FE46548
-:10E920003DD68BD30396A701DA09E209DBA7F7AC42
-:10E930004FF984265FDA1479FD6BDA36AC3DA9FA1B
-:10E940005ED5F2F25AB57FBBA2798B26BFC4F7A67B
-:10E95000A67E69D32E4D7E71E33B9AFA0BD71CD26B
-:10E96000E48BBD7FD4D49FBFBC5353FE60ED594DA3
-:10E97000F903651735F9FBDC7FD3D4BF778EF0132D
-:10E9800075FEEEA2A89FA8EBCF9A16A7C9CF700D6F
-:10E99000D2D437ECBCF62EA0C783EF8B04F48F4F94
-:10E9A0009DA7D1FFF9A95376429D931E07EE83538D
-:10E9B0009ED1989EF138719F9CF34CC2F442DB1EAD
-:10E9C0000BC8152A474BE0C8A674E596BA35D9207E
-:10E9D000D709CADF8A956FD4798712B21494638AF3
-:10E9E000EFC22623094C204400E1C4C7151455E5A5
-:10E9F0001D7D9437514191D0B3BCB023F2F79A27D3
-:10EA00008B87DB239C7F84F73519027A52772FE7B7
-:10EA100024950229527F276405F281AD5C4FA93409
-:10EA2000327E51B975502EB1413E30AAF6ABFA6B29
-:10EA3000A19B6C20D049BA663F97365DAFE1F704E1
-:10EA4000BCCF89406F1334DF2B9A6FD6B4EBDA2535
-:10EA5000E2B8AB819750B9FD2A297A52043E15D805
-:10EA600093326B0C8CD3F514E6DB12518FECF2343D
-:10EA7000AF85F3C7739E164CCF78DA303DE509AC0D
-:10EA80008573C0939E03981EF7B463DAE13986E973
-:10EA9000479E0E4C3FF49CC1F44F9E20A6C73C9F5E
-:10EAA000617AC4437E02700E7BCC98FEC163C7B40A
-:10EAB000DD938CE9058F0FFB51F65D5F747786CB94
-:10EAC000ED73407F11E86CBB78AC6ECDD0309DBD4E
-:10EAD000B9F223A43305CF854D264E0F491A7A0883
-:10EAE00080ED7723D04B1FE54D32A7C3DEDA472EEA
-:10EAF000AF79E1BF87DEAE7C4B7A0BD3D3101D3DDF
-:10EB0000A5F7454F1FAAE9E98AC1CEE420A7A71FB0
-:10EB1000F3736B7DBF51123BA70CE977AEDB0C8022
-:10EB2000AAA5FCDC84906998BFC4FB5E49C1B5A36B
-:10EB30001EE81B0D72EBD2E8BF8F8273874BC7E8CC
-:10EB4000E2A7F63E3F3D9DF48E7717DA43253EBAA5
-:10EB5000E80911C61BCDF01A6520D3C878421A46C1
-:10EB6000BEE45C90817989C4437B9F734684F33A09
-:10EB700042756BC06F5F785D69BD3216E09D7AF6B5
-:10EB80001F59905EE1FA75F41E11F57C1278D109D7
-:10EB9000F80DC925933319FCF3C191463BEA09648A
-:10EBA000BA167FDEDB35F86B4855CECF1B93117F4D
-:10EBB00023AE8C1AD40FFCF5C5DFFBC2E70298F731
-:10EBC0007F033EFBE28F7DF145E272BCD646E7DF74
-:10EBD000BD73CCF8C71CC007BF1ADFCA799C7E3C46
-:10EBE000F992F4B5E8B83B49A1E3F614885BD82460
-:10EBF000DA11FEA5D66B62615D4270FA584FE1ED05
-:10EC00003FA780BD7F3E550B2F4B07EFD281176D7D
-:10EC100060772D4D5ED87032C23A2869554B5D83BE
-:10EC200045AD87B669F3971A85692D382E47ECEC08
-:10EC30003120276A1B18DF5E8EA90267697209F608
-:10EC400073AE393D96D97B3EC60F36C721BF38E734
-:10EC500029C3FAFFECF1F40647190F21ADE484193A
-:10EC6000F8312D4BEFBD7EAFF42CFDC588E7DD7E7E
-:10EC7000F90AE88966FADF9760771009F30ADC9AE7
-:10EC800016D16BBA01BE6FD6F447DB399433E22F4D
-:10EC9000D3BE6ADF48E49442B7545ED483BD80E7B4
-:10ECA0009B4B1AD47A5955CB7735F99AB6471AD473
-:10ECB0007A5C05FC83F25F522B484037959C8CBAF6
-:10ECC00025CB1A818EAF18824F808F08AC5E95B924
-:10ECD000C3E8A69FCEB7B275EB6D7CE73CE65488DF
-:10ECE0003B283337E2397259CBB5F92067CEB7AE3E
-:10ECF0004C02F95B215EFA5E5184F6BF94042E5FEC
-:10ED0000E4A056CFE7F441285CD5BCE9CF12C21786
-:10ED1000CD7719985F460FB78DCB91BEF053BDF9F3
-:10ED200050C1CD8E9E78AA6EBB6874235FA4FFCBC2
-:10ED30000AE349C15FB154D426D171973777A2FF56
-:10ED4000E28CEC1DF583AFE0973DE767493E15A3E4
-:10ED50009A9797B4433F0B26F18E88E3DE0F281F66
-:10ED60003FFB5B99001F225769AD2C74CD70BBC768
-:10ED7000400C5961BB67416B4521E0FBECEBD3D103
-:10ED8000EE5B448A6CB80EA4310BEC9CF3C480712A
-:10ED900055E7C91F6C1354EBF0B164E478A65C30FE
-:10EDA00089BB3410BE7B10D85FA639F5EDE258F868
-:10EDB0002E297690F025CA15B780F11773D8772FD2
-:10EDC00031D701FD527B4A63AF517B4A93A7F6943A
-:10EDD000265F426626413C45C9D332F10988274D5A
-:10EDE000F941C98EE32B25B5F5A01FFD9CFBE1166B
-:10EDF000D8893484CA87AA379ECB2AA6F3E9929889
-:10EE0000FF4B890F584265C5205A5E5EE633BA2C27
-:10EE10003DE777A275C23D94F3033C160770BFD15E
-:10EE2000C7E26B8843CAE2AA4F5AEFF31FD82ABA47
-:10EE3000A26C508F7E57C69BFAF5E7AF9F2F214FEC
-:10EE4000E23CCA9B67601C568F78073E1FB9597019
-:10EE5000F922EC27511634F12E0932C39FE2D71A5A
-:10EE6000AECB5F0F7995DF6BA2AEFC1BF39701442D
-:10EE7000C35F8A25F7703991F113C0BF2005717FF8
-:10EE80007D63F8C93DE05F2FDFF84F843F54BBEF4F
-:10EE900029FC89FFD4F18FE831FEBC48F0ABDE7865
-:10EEA000F57588772CFFD5CF6C84EEB7B35263929B
-:10EEB00093AE7BE5A6D53617F01DC96B837D71D661
-:10EEC000274E8B440FDF9779DC1F715904F0BBC2CA
-:10EED0003F29FC73AFFCF84EB0A3AE6C92EDE84F47
-:10EEE0006D36054C949EAB5B971492B198EF64F924
-:10EEF000472F02FDD7B4C9C7D5745AFECB9F254111
-:10EF00007C10A5942186644803689F546FFCB80068
-:10EF1000F48D1A12C4FDAA6F07FD7F168FF2B0D8C8
-:10EF200018DBB31C1D3449D09EFD6A5A7F7C51B456
-:10EF3000417ADB69E06FD4B244BF90BE5D19B73B44
-:10EF40002A64EB00E4AB13C944E0AB0A5E888FD9B6
-:10EF50001D2B5F7E666C271D57D7C6DFDA0415BEF2
-:10EF6000147BE952CBC25FFCDAD13B1FBF40F7A351
-:10EF70005ABF55E494A38DDB4B7E9656CA011BC441
-:10EF800073556E909D5EFAB9F2D5175F7A16FCD96B
-:10EF90007F34394752F815AFEE3B7213CD576C9161
-:10EFA0000714B2695884A4F0FAD4D0FF968F0FAF3B
-:10EFB00047F9B67D46C718F6FD87F1E175A9D8B2C5
-:10EFC000CB48C6F4C4475ECB2E638725C2FAB4741F
-:10EFD0001680FEB7F2E5BF1A81EF9DDD299081A969
-:10EFE00011F0B9611FEA8780275C4FBE5EA1F5D39F
-:10EFF000D5AFA1EB027246BF5EFA7A859CBF005C7A
-:10F0000088B3A1F4FDDAAF210EEE4F2627E0A1EC84
-:10F01000B5876C309FD3522DA3F3E7562701BF2B42
-:10F0200093BD49764CD9F7B2E71F46FA2B3DF470F1
-:10F0300012F357BA061950767A07C13C17AFBF1BB7
-:10F04000E75942DC488765CF89453E9A7E2A916917
-:10F050005B22EC934B7C9F9C7E812E2E9DE7694525
-:10F060002EFC41E472E1BBE80F7D98CF856A909851
-:10F07000FFD4CCD6EB806CD0C8D110FD6E7C14E5EB
-:10F08000C7B961AE8170EE561396172847C4435333
-:10F0900007B275627207DB51B99307DFA17EBBEC43
-:10F0A0008A1AAB69877246E97F19EF9F8E3B1AF483
-:10F0B000B7D34991ED91E146850F503D434567AA8D
-:10F0C000FDCEF6FFC606B6DF95FDEF9B310DCAFFFC
-:10F0D0007298ED23680772978E2B3010CB77CD1680
-:10F0E000903F984820D23EDF28F37DAE2DD7D30B3A
-:10F0F0001DBF24C4AAE806FA89C77540795FF234B7
-:10F100006DAFE2A335D0AFAD275C651F97727E70FF
-:10F110001EF8C1F5617E40D627F62B5EB452F6BDCF
-:10F12000F42CEC5FBA5FBD0ED8BF7211CCFF93CD4B
-:10F130007B8EDC4FF7ED272DCABED5F255FDBE2DD7
-:10F14000DBFA30C69FEBF7ED27436B49C47D4BBF1D
-:10F1500047DCB7433BFE47F8AA82C724A396AF2AF1
-:10F160007CB2377CEAF9E416D98178D5F349FA3BC9
-:10F170004CB27AD2A342870AFD95FF47D570E0478B
-:10F18000213A55E83044A70A1DEAE7ADC5A3BEFC05
-:10F1900023F02D527A297A53C6F3954A3F8B03A662
-:10F1A000EDF60FC9447CB950CC91C6FD4306A8F3D7
-:10F1B0003E5DBE4557DFA5CB17E9EABB75F95A4D51
-:10F1C000FDCAB63D46827410D0D41397FF3B393147
-:10F1D0002112DDFA98BFA1F5A211EE39D45882D8D8
-:10F1E0005E5E41BC101F19DC21E2B95137C5713D8B
-:10F1F000F83736A7FABC948FAC8E627E856E7BD0D2
-:10F20000164FD3D5712C1F4C34D6031F54BE07A301
-:10F2100098DFB1BB28688B53D95B9D7E11F9788745
-:10F220002FF2BD0D2A6970DD3B7AB9D7A19C8F758D
-:10F2300047DBC6627FD1293EA0C7A9A2256539F860
-:10F24000A11A4527E8EC8BEAEEB5C17955B73FFD29
-:10F25000AE39F4FBE27744168EE37549835476D0D9
-:10F2600019E25D972D405CF05AA49F857E66172DAC
-:10F270005A1B793F94F37625966546E0BBD40E3948
-:10F28000AE3EEF51E094ADD77DF74FE7FBA611ED11
-:10F29000FFF28DDA7237B79F7F64E4FC671C19C7F1
-:10F2A000ED57E6BFE17C7BAA9871D71CBA3EDD071B
-:10F2B0004462A2F94B7E11D7E7D266C107FE37E25E
-:10F2C0004DC4FD574D8246F57D882ED85FD7F4CECC
-:10F2D000C7BAB6FF39EB074047AF7F30F6DF69DAD0
-:10F2E000F5FA1F47BD05F9378EA67C407AD6CFDBED
-:10F2F0001985F102DD3BAD48FFDD3BDE4BF901E452
-:10F30000DF3439619CDD3BFF3A16E8A97B85A90C07
-:10F31000F860F730E6BF5DB9E3AF633B50FEAEC2C5
-:10F32000756C361A999FC9FF8F8FE0DEC2253F9D0D
-:10F3300015E8173CAEBEE6D7513E82F0FF9AA5BE57
-:10F340000FF46DE753CDE343BAAD64CE56185F1C9E
-:10F350008B7FA8796BF28B75B4FFAAD65DC685B496
-:10F360003CEFEDCFC7621CFD56A6375D903B9E87F4
-:10F37000F8876DC6EFAC94299E2FC026A346F65D94
-:10F38000A63579B08F7AE2E573F4A7F5171FEF1A67
-:10F39000997DFDAF8F0FC1C5F89FD5671660DE7FE1
-:10F3A000FBE803F4839A902E95F97ED25287FA4CAB
-:10F3B0005FF33EFBBF860EFA3B6F21D09F799B4DDA
-:10F3C000FFDAEBFDB8D181EBA2DF073DE97CC7F79F
-:10F3D00030FFAAD589E3ED27BD8F36FD3FB6EE5B42
-:10F3E000E9BADBFA9EF777FEC5E7DDFBBABF338FDC
-:10F3F000AFBB1DCE536BDEFE1CC7F775F95CE9FF92
-:10F4000052BA57F4FD7643AD3D938E6F0E69B482C8
-:10F4100062715FE2254BA603A2702F0FC0F83B3844
-:10F420005F8D6057359998BFCD241858BCDADD82BE
-:10F43000E247443BEB4EAE5FDC39B40CF5903B5DEC
-:10F440003F417D8248B5ED39B47E7BEE4227C66AE6
-:10F4500092F1C7DC909F3D85E7B5F6E6EF04E21236
-:10F46000A87E7F67EEF403A0E7DEE512510FA62920
-:10F47000EABFEFA714B0EF93B4F6D07D6E6DFEDE59
-:10F4800039DAFCDD1CDE3D848DFF9E22C1077E58EB
-:10F4900053CE5389E097352D9689900A7146B5ABC6
-:10F4A000C1EEB8BB48DB7E1928672A7FE337C5E386
-:10F4B0006F43785C8A78213922DE03ED138F7CDC80
-:10F4C000EDB3C7F920CE9A484E86C77BAA9CE83791
-:10F4D000E7F6B8CCDBCB9635EDB09F659D1DAED879
-:10F4E000D3BDE19B70FB1CE1A485F12FBB44B4CFDD
-:10F4F000659D7DAEACCBD75D0F651DBFEDBA3C07FA
-:10F50000EB7263785D865A5C04F6ABCCED877C8B3E
-:10F5100093E587161176AEE8C3FAD20017F1668438
-:10F52000E3D197988B2BE09CCC3C5A407FC85D6B15
-:10F5300045940FE60C01C7553449C6F8E38F0D45D5
-:10F5400059B0DE851326567F9F0DC309F85CC2F1C2
-:10F550005E426A517F2557BFFC323B0BCE2508EA3D
-:10F56000BF4B5C84DC41EDB8926C21100DF16A1246
-:10F57000F1C68E073FB9408E6BFCE4DA3CFC6E4965
-:10F580000AC3E9AB7E6FFCE59F9DFE17E567C729BF
-:10F590009174423A12BB97D476F77C3FC3634DA572
-:10F5A000E04B43BA0BC8EAFBD30566B60FFEEB8708
-:10F5B00013904FE6FC744C2CF30764E27DC41A6E82
-:10F5C000375CF23A62C10F76C99FCECF73F36C6A93
-:10F5D000BEAAA487B81DFE9F109748D3EE7CA15108
-:10F5E000043B8B04D1FFEBCD8FC27BC5FA76A3CC55
-:10F5F00006BEAF6BD12F003F11EEAFF27994D2A6C9
-:10F60000B1F1AA755B7BC759696CCF7580DF71D585
-:10F61000F9DDB7C52FD8FD80D743511D054511E64B
-:10F620003B89E3AF70F7DFF0FEEA4C7FAA0C7899D4
-:10F63000992F6ACEF99D66EECF984026C0B80A771A
-:10F64000DF669B0CEB724074C27DD51AFF45A33B6D
-:10F65000C2F9B11E9F001FFCF027646709E0F3C4E4
-:10F660004FA208D8D5EFF173C90CB8CF9181AE1E67
-:10F6700017F81D73CCCC4FB8CE6CC77456618E9CF6
-:10F6800048FBCD68B58F8350B5C1BCFE3AB303CB00
-:10F6900087F0764ABDC195AC5EA7D15E1D69FEBFFD
-:10F6A0008B12F87999F37B93847FBD75CBF9A935DB
-:10F6B000900BFA41BEE267D1D335C1FD71699AE082
-:10F6C00003F90DF630E60B05D41FDE53EEAFCF6421
-:10F6D0007256A17B3D9EABCDDAF7021EE7787F889C
-:10F6E000D387826705BFFAF12AF529BFBA55ED9F86
-:10F6F000BAAB6DDC6BA0DF54FB05BB8182AA963AE6
-:10F700008CB00F6BDA9E90E17CE63E07834BA4A29F
-:10F71000B1EAF8837566160FB267FCCDF3804E2E02
-:10F72000AF35812C24AE45176DC087DF33387F0F8E
-:10F73000716CDEDF8964D357F0AB0F3CF6F27C5975
-:10F740000D3715E733AB32470677DA0395BBE48113
-:10F750002A7A5A678EC772E5FBE04A07BE0F42FB62
-:10F76000C371781F3711B84F92D1D28EF76C1FA892
-:10F770008D637458D6B2CB88F954CD7B224A3FFAB8
-:10F78000FD34BB501BAFBC30AF6328E0A5D014588C
-:10F79000E68C40A793A39473CAAF29275C946EC7E5
-:10F7A000FE7F2427962972A203E3E395F602DFE7A2
-:10F7B0002A393130929C585AE71808EBB07447FA4E
-:10F7C00040D8244BDF999A14494EBCEF61E7CC47EF
-:10F7D000F97DF6EED9544EDCA09213B3A3904EF40B
-:10F7E000ED3E51F6495F724259B7FFCBFCE67D9082
-:10F7F0001311F6F7173A39718FBF18E5C43DB345B9
-:10F80000CDBDAC4FFB94133949F7615E76C644A079
-:10F810009FF7B97D7394DF0B807E405E6446D911FB
-:10F820006F7AB9D11B5FFF537FF9FAFF109E15BEA7
-:10F83000BE94DA3FA6D4487448909E97DE47F9BA42
-:10F8400000F4C8F8FAD207B99F53C7678B80CF6618
-:10F85000AAF92C6B5FED6672A1A62DF599B9B4FCDF
-:10F86000FE46D909A2F2FE30DFCD52F3DDCCA85E10
-:10F87000F86E19E3BB97FD13507FEA6D7E7FE6FCBF
-:10F8800096F2B311CE08F431676E8CE6DEDE897134
-:10F89000BFC9D806FBE53D11CF793FE67AC0C171FB
-:10F8A000BFC9047DFA493E9E797C3D2F7848793E58
-:10F8B000C55FDE22A64F576D16117FD5AD6CFF5781
-:10F8C000370B3E07CD178CFF1B9ED756EC60E7B574
-:10F8D00074068539AAF5AF78AFA31ECE092A36087B
-:10F8E00078DE0CF71E009FA51C9F25CE0A3C5729E9
-:10F8F0006DD2FAC11BA26D2F901B101EFAC3AB78FC
-:10F90000FD425310CF1D0A7F293837209FD4B6AB54
-:10F910001A71FB59B04F2A9A75DF9D0D78AE0437E6
-:10F92000D441AFAD6AD1967BF8BC178B818C6D1436
-:10F930003EF93DB3F3F478F7E8F153F62DF173880F
-:10F94000E227F39F879F25FE5D785EF075F1A2C7E1
-:10F95000475D143F1F184F32613F7E6C70217FF16D
-:10F96000BE2BE2BB4E8B9E18A9790FE5A71C2FEF8B
-:10F9700019DCF583A05EB580F54AD76FD99744F3BB
-:10F98000735BC8383866286DD2CAE390FC6F75A0E7
-:10F990007C9F5BBB4580B8DAC5FCBE6099EF097CF3
-:10F9A0003FE6C1E554DED3FA0BC79BDC705E7E28D0
-:10F9B0002A88FC53A1DF9D40BF946FFAF9384E0CA2
-:10F9C0000EE6A39C6A13ECB82F03514C6ED17582DE
-:10F9D000776DF64CFE6B015F17E65F6A63EB584389
-:10F9E000D70DF675819FE75B983EF880FF223BE7D5
-:10F9F000F4EF92D9FB380249407EE744FB5C918FDB
-:10FA000070EE9A93A45ADF1D9D8CFE37094EFCE0E0
-:10FA1000A3FFFB36EBDBCBBA2AFA4C7FD757C1D317
-:10FA20004EDD3A1F8A6A2F9C80E7728213DF0BF249
-:10FA3000C7E179D1C946F6FECD41AE1FE9F705D839
-:10FA40001FEAF77866C0C0212E7A5A14C69562BFA5
-:10FA5000694C3F53F329FD3B485F376EA986B4A339
-:10FA60005E168E7F74DF6E06B93F4DD0C449D11942
-:10FA7000E1BEFF27C097A3BE023E4936A37C79C8EA
-:10FA8000CEBEEE196624F01EDAE53532D2D1BD06BF
-:10FA9000C7916CE02F8FC904F6C7E583371E9D3BE5
-:10FAA00000CA45A48FE2F72654836BA598C5AA9196
-:10FAB000E247985C3AC1FBFF1395D7AE6B7897A0ED
-:10FAC000077BE27C70BF74B673D75407F85B320FC4
-:10FAD000AD8673CF5979F62347601D1BD8BB4FC73E
-:10FAE000D7E4A19DF6D07705DC67C7E87A019CBB17
-:10FAF00067A71E3942C7F7E09A443CB79CEB4ABC63
-:10FB000007CE31E71E149D0E5A6FE15D560B9C7FA8
-:10FB10004E1F2D12B70A2F0F9276F4EFCCADFDEEEB
-:10FB2000DDB04FCAA83C84F79CCAFC87A60E84FCB3
-:10FB30007A01DBD778DD46B8E7D9DE74D19849FB86
-:10FB40002FA1F500DD35EB59BD9A8D02BE1758E2A5
-:10FB50007F02F964C946011FC469A7FAAF99C1F5CC
-:10FB60008129D1BE9EB6A7F952680F7037C6DD0352
-:10FB7000E79335749CD87E521D9E5397D076B498E7
-:10FB8000B46FFC2EC25BB25E2070AFB06C52EAE381
-:10FB90009300DE41D909E54777FDDC08E39E47FB8A
-:10FBA0001B44E12F143BA6427DF203C18EEF2E15BC
-:10FBB0005E8BFBBA9BEF3B621FCDE21404A2DCEF2D
-:10FBC00093D4F12A25D169B89F4A96D7D5C3BC3AB8
-:10FBD000BC89A906A4A78B4690E32729BEDD547FE4
-:10FBE0003D616471307BBC278C1D2AFEB9323A1D01
-:10FBF000DB2F6ACB413EB39814613C85BB8EE92371
-:10FC00009DABA37CE057EB94ED29F07DCF6A137E8A
-:10FC1000BFF02A933B178675A07FFBF47A99C0BD8D
-:10FC2000C795EBD3D7C13A9EDE2C3BE1DC407C8EFE
-:10FC3000C51194BECAFC647BD633B8A79B197FCB91
-:10FC40007BEEEE02E0DBA5944F99707E5A3E56E2C1
-:10FC500028473EF55C14E34B7A7EA5E753658D1B80
-:10FC600022CBA1650591E5D0D07AEE378D2C9F6B24
-:10FC70008885E9BBE3C978F06316570D9BD704F478
-:10FC8000FC20BB70D01E78F3D39F81DCADB4E23B87
-:10FC900065D5927D9DC0E88300FF9FEBDFF229ECE4
-:10FCA00087B2B951F80ED929580FD8476B13F01CF9
-:10FCB000BBC4578C7857E2794B9BB4F4AEF821EF74
-:10FCC000738BC4A5965F6531C4A5AA77F447946E7B
-:10FCD000693FF3DB041FB0CAA33FEADCFF7026E6EE
-:10FCE000ED38AEE55C3F586B45BA3EFAC8C5D54025
-:10FCF000B7F37E2810D0DB89D75D0FF2B0BA497018
-:10FD0000809FB8F487AC7D296D0FE33EFA73465FA0
-:10FD100094CE1DB00FAAD73FB11FEB6F141C00FF8C
-:10FD2000E88662D427CABC22C1F28D9D684750790B
-:10FD300085F1687BBC6212EC83EA55263BB86215FC
-:10FD40007A52E8B393BFA740CCCEB1B3683B67B457
-:10FD500003F9B29E2EC53942489E02FDD47819BDE2
-:10FD600075BE2A3B618BF44D9FEC1EBD427F22D0B5
-:10FD70005F6698FEF6ACCF33023D9EF60918679198
-:10FD800007F40BF4F9B2E29F2116B51ED5177DEAF0
-:10FD9000E9B007FDC1CB58E961FA54E8514F87C774
-:10FDA00025720F8CFBA1D551388FBCFA37EF59CE95
-:10FDB000F6199ECFE5D53F9204FBBA446271400A22
-:10FDC0005EAB241637D6635C4FD71907F5677CBA4C
-:10FDD00071CC8A0EC9EDF120B7A93E4A02B49FDF6B
-:10FDE0006C7E11E32BCFBFD27927EA376F513A00EF
-:10FDF000FC6FB69200DA213EE447E5AD22C66913F6
-:10FE00002990354B65BF2B713115BFB222BECBB7E0
-:10FE10009A7C85B47DF9EB27C6625CC20AA67F7B1B
-:10FE20005F11D83988B7632CDC3B2A97587C8E5EEB
-:10FE30002FF85D34B3C3BBDE8C99037A9BD0CCDE44
-:10FE4000172C6FB95736A9FCBBFBA265A51E9E9364
-:10FE500079E93AC3FB0A303EF5FB764A5C4ED7CBD4
-:10FE60008CFECADB64D4E7CA9BB75C8078CDF263B2
-:10FE700026B4776B9A2F1AC19ECDFBD5ABEC1DC46F
-:10FE8000365113A7D7233EAE590C9820AEABB50A16
-:10FE9000CF7168BE13F32D3C1EED6BC66F55FC6A27
-:10FEA000C7EB5E8AC28A6DBFB4E17B85ED9B6C783F
-:10FEB0005FAAF9ABE3557BC4C3B534F078B83B4EC9
-:10FEC00013E48F91E3E1CEC13F28217D16AD8D87EC
-:10FED00023CD8CBFD17166457A0F35A477BDFAE981
-:10FEE000F310CFDDB5F593E761DC955F5C7E1EE234
-:10FEF0006CA88268073DA5E695F731FE5569171F86
-:10FF0000C3EDA0977F89F1C317FE687202B40B3B63
-:10FF10004EA780FE7161CBDF92202E78D98EA9E8A2
-:10FF2000DF59B63D0FDFBDEDCD9E05FAF5F5237E19
-:10FF300059BF6E7B5AF7603CD079BAEEC027427148
-:10FF40008E2D552C7ED4C1E31B37478E17EF11CF72
-:10FF5000D83AEBAE29C01F5B999ED0675CE361BACB
-:10FF60009E37F4631D37F3F8D5963BBE32AEF13CB5
-:10FF7000FC83AED7B8186D7CE8A7AD8B7FF12C94CD
-:10FF8000B526F41AD718E807FE9478F4CFA35DD904
-:10FF90003189B0DEFF81F1A4B07E850EE0D79FA647
-:10FFA00080BFF88C1C44BF44708709EF6B96EF3814
-:10FFB0008AFBE9C2F64318EF4D785CF80512FAB1F6
-:10FFC000F85DEE03AAD96865F1907C1D205ED261D0
-:10FFD000C3EF3C2E92D1B5122FD95B9CE4B298347A
-:10FFE000FE3E0B8BE7ACDAF8018F3F0CAF9B30097C
-:10FFF000D6ABF32BE350153CD8010F13D571C0914C
-:020000021000EC
-:10000000E3524371C0BA7583F5043E1E8AF3A5F925
-:10001000A110EFE9138E468A2BBFB081C50F5F9008
-:1000200023DF8F56E2826B6274FBD6D7BF78E0BEC7
-:10003000E6F175F1343FC6A1A11B055F5D5723F3BF
-:10004000F72763846F64B785EE9B540AFAFB2C4F45
-:10005000C4C07D99D64E23BE93A2D8557CBE5DDC2C
-:10006000DFD6F58A8871A2F52D7B90BFEBF9473575
-:100070003F47D18F77231F6F751B931F5D5BAD3E8D
-:100080000B85D3B5FB4DA4EBEACD9D18A7BABF797C
-:100090009BB14375FE0CF2C3A71A7FD76BBBC62278
-:1000A0003FE7EFA2E9FBD9CAF9638D3F723F359B69
-:1000B0002F6AFAA9F0B618ED96BEFB3B27B9EE05FC
-:1000C00078E7DA991E75AE459CE68BD0FFCF626467
-:1000D0006E5737323F3895A3F83E9C95BD0727DA17
-:1000E000A2512F5B669D740CDE215D6635625CCC8F
-:1000F000CA3A1E47F3236732ACF74AEBED04C6BB9E
-:100100001AF0ABB2EF65BB9B803E27271765AACFDD
-:100110006194F11B0718884FBD8FADD306827D4ACD
-:1001200024EF5018C79D697F95402EB67B987F9F1E
-:100130005C3D3102BEB74BF67D09146E7BBEE00418
-:10014000D76C4FBA67F0437E0697F61D5DBC5347E8
-:10015000E777C969403DD16A08D86915628D6A4F51
-:100160004603D7411C52125EA5C07889C73CE611F0
-:10017000703FD446A8DA0AF59C92E65D95D849927C
-:10018000EE9D15727804A5570BA757C55F6765FFED
-:10019000A6703BF0FD96B80C5207E4BBD6EA467D4C
-:1001A000E2299B0BEF3FD2DF6888938827D14EF579
-:1001B000BB50B45FCD7D3BDAAF261FE7D2E613A676
-:1001C000492723C99B043E8E02D18278889B6AE02E
-:1001D000FAB2AB70645278DC7189C41980F23B2C9E
-:1001E000788F806E2FAF7A1E168B76DC747C1A3E69
-:1001F000119BD1E135B0716ABEDB8903DF47A7E30C
-:100200003DAE1BAF266FB5707E271109F89DC5DC8A
-:100210004E38FE2F69F0BD4A2A8A4F224C64C238FC
-:10022000E93021DE2596CF83F6AFA96F07EF01EB0A
-:100230005F0B870CB5ABEFB5DEC0E5E0114B518A23
-:1002400085EE93ACE1B518B89D9D2CB84E4EA065D7
-:10025000FE01C89FD296E7615C8AD0C8E86AC45A9A
-:1002600082FB664490C755AD8A463DD56426DEA81C
-:10027000F1703F8E78E5F1D08B8F9F3F395618286B
-:1002800028690DA535DACE1FCC352CA68BD00245BA
-:1002900014FE108B6B0CF45F3FC39D6C1807D31BCF
-:1002A00056BF7728EEDA6BC16368A81BBAFFC0148B
-:1002B0006421F82E08F10EDD0F72B851C953C60E35
-:1002C000EF06344687F22E33E5F78D692C7FF3DA9B
-:1002D000A1F5F07E4DA7BDE8660B8CC76CBF0ECFB5
-:1002E000C302F19AF7D57B932FCA38476F0CE4C14C
-:1002F000FBC7B707D9FBC523ADA17BFC288F3759B6
-:10030000947C00ED8BA2D643C8D7AA5A0E61B901DE
-:10031000F2341D9E10C81B42E779BF654C41F2B50F
-:10032000145E6B71323CC1B1D03266BFA4C1C3B898
-:10033000FABDD9613C482B6ED0E1E186AF85878557
-:100340006B6FA887F755FA3B6F4A170B005FD373A3
-:100350000CF88EDBC46316F4BFD05F14CA230E679B
-:10036000432FF7BC153B85C22957D397D24EA1AB7B
-:10037000DEE8269DD8AF63EF836AE9E7DF2DAE871D
-:1003800000DE328B2BDD9688F3C77705A6BB8B8BFF
-:10039000F213C2744D2CEE09F0AEFE11CB821F5A3F
-:1003A00054FEDAE9394BC5343ADE1F0123B8313C3B
-:1003B0009FC4E5DEA851749E892E03C6D51FB1B82F
-:1003C00057403BDB9C600062CB2612F704410CF7E0
-:1003D000A3EC8FFA1DCC8EAF2F36F856B0F360FC2D
-:1003E000BB1D61FAE8D0D14790D1475B27D247B512
-:1003F000BF93D1475B5D6E343F57033BBA9104C74F
-:10040000C1BA37590A0BA461946E6282F54037B2C3
-:10041000F7B682C228C4EB3A185F8FF5E1E352E6E3
-:10042000D5DBFA361E48FB7106D899070D781EA653
-:10043000E04DA9B7C3C2E246FFCDE67E11FAA99905
-:10044000D4B11F966FEB813F605C87EDE0CC5DD04F
-:10045000DE369BAE9023DC6FE3C115F84E78237F28
-:10046000D73B9604BD20D77BC707DB3F217C80DECE
-:100470009301F8E8C4FDF20ABF6796DD26B840CEC6
-:100480000F8F61EF90BC6E6176F5BB1691A74CAFF4
-:10049000493CB85B04FB2B7B9501EB27429AA19E5C
-:1004A000FF2A5E5FD2F8DD957555E88972D218781B
-:1004B000CFE4F978F71E2DFDC4C7A4A9E029ED1EED
-:1004C000F790A245945026EE5DF010C8554A3F3E85
-:1004D0004DBB317214E02D443F943E23AD0F6D7738
-:1004E00088AD6B7C0CE80B5BF62E15F15D8E7EAE55
-:1004F0006B16BC4749EB67C590DAADB47D562C4D01
-:10050000219FC0F303797E084BD33F741A04FA7D10
-:1005100003F7CB9EE5782592FDBA996320CFF4B816
-:10052000ECE418940BCABE856754E05C5BE2E7DB41
-:1005300069C13403AC9BB28FA5A02160A5422B4DAD
-:10054000721820CEE15D8FBB08CE0B7BE33BB75F1B
-:10055000CBEE81EABF7FCEC7F38DF5EBBFF4B82FAA
-:10056000FE39E0B7CADCF1F84C9AAFBEF632FA6950
-:1005700057C454DFFC55EF68E8C7FFEED5DFC40071
-:100580001DFA3F3345BC3F35CECAE8F180670EB651
-:10059000CBE2EF0492814A1CB22ACE15CAB85E861D
-:1005A0004B9986DF51CFBA055920ACA7578A87F6F9
-:1005B00031A978AE78AB2EAE55392FBB25C0FC8063
-:1005C00059B1BE42ECEFFA74F6F7493E63FA9299DC
-:1005D000FE0FCEA1A6F27333D731FB5E1087590907
-:1005E0008DF9083F3615FD5A3944FBFE41D640AF20
-:1005F0006480F2F454849767D695A713F45B916BEB
-:10060000AEC3F94D252AFD0CE546A313F8F1F4D14C
-:1006100094FEF9F7CBF4BFE126327F86CACEB8CD7F
-:10062000715F51BE466F69C477857EFBB9383F5212
-:10063000FCC563213C1715413C801E8FB90E6195A6
-:10064000D5D113DF7AFCE9F1ADE0518FB79C0F9D56
-:10065000F9F18E9EF8D1E3237C7EE95B0BEB3075DC
-:10066000B488F24BC17B4FFCB0F5FAEDB5B49E00F7
-:10067000F442F10DF84C1730BE272B86D34F6C3A5D
-:10068000E2370B14C001480F98D7E3558FC7AC046D
-:10069000DE3E81D5DF0FF81A89FC00ED2165DDB261
-:1006A000D26BF7C641DEC4E84CD1ABA772BC50BDDB
-:1006B0001AF5E6BC442BFA9B40AF9E9A14C65B5ECB
-:1006C000151B57DE48CB0B609FFE0AFCD1B1080614
-:1006D000DFC5BC95F05FE0563C5FCAE25905DFB765
-:1006E0007EA6D593A7FA0BCE82FE3DDCE45E6505BF
-:1006F0007F8C1087E77914FFC775F8D7B6B36BF313
-:100700007A7CFC0AFE31B927DE147AABB372FD7C29
-:1007100030190AFAF2D8373363817F137F7C44BFE4
-:10072000C4C4634521389C6E919E05E20E7DB7A737
-:100730007F0B3E76904A49151FBB5372AFB3DED88C
-:10074000938F29EB3585AFC714E2DD057EA62944DA
-:10075000FA4BC81E480DCFFF792BF7B30D2143602C
-:100760009E5F581C8CFFF37986E64DD54BE83F9B86
-:10077000F79F6DB6E0FD1B1294BA42784EC3F79313
-:10078000BCC6F8F0386465BD536A09D3E7E6E2FBFE
-:10079000D9142FE4CB98F038B6590509DF0FE2E3FE
-:1007A00038DF6CF6429CDBD392FB0D2BF83D848343
-:1007B00063717E526014C83F7DF9E5B6BDD5504ED9
-:1007C000EB95603D3EFE0A91F91F823B4CBE1752ED
-:1007D0007BD753E9F64639A1D07136DC7BBD01E801
-:1007E0003E28C2B8FDFC5C65E74576CFC145ECAB61
-:1007F000AEA7F0F65D62F702F228DB817A7AFAEDB5
-:100800008B4EF349701EB4D3D3AB22CF1BF8FD5BE4
-:10081000453FBB6875BF0FEBDEC0EFE3FA2F8EBA22
-:100820000ED6E71BD3D5612D5D29F444E9EB38F4EE
-:10083000D39DF9F13A50CBDFCBBC9C04F251D1E30C
-:10084000C3FA8AEB63A8D79B3E3FDCE6EEB27E8517
-:100850003EAFE8357DD92364AF4446D371CEE3EB98
-:1008600033D7DC2EB38BC6418CD36F8856DECB7367
-:1008700044833E39AF21ED95663857AC637EF90766
-:100880006B658D3DEC86DBBED89EBD673B7FB9B600
-:10089000FC238AEF41F1F8CEADD68E86FD91147E11
-:1008A000CFB767BF062FC8C97923A3317E4EDFAF0C
-:1008B0007E7EFA7EF5FD3570FBAAC1D838DAA9D262
-:1008C0004FEC3616477D69CD93CDF0145E6FF8730B
-:1008D0009B87B8D47F6FAEA3217A4EA4F7681478B3
-:1008E0000ABEE7C2CB98E00FA895FF1EE99DDD6C1C
-:1008F00037F313F4D6EF88603EEA8386A70322E835
-:10090000F5238204F5F0ECA0CBB050630F307BB937
-:10091000873D00EFA4D07C65EB2E660FB4D4A15DBB
-:100920005149ED0A903B1BE01D90C17C401968279E
-:1009300084EC5E88AFCA867732B95D0C4FA7A537C5
-:10094000B2FA331F4F37358C00BBD59D0C2F93CE99
-:10095000B45DFBA899DA57F5A9248A50FBAAC8769A
-:10096000ED77D64EA2DC3BDE25C0BBA434FFA865E4
-:1009700072FFEDEC99B6D18F82BF81DA67B7D95497
-:10098000766F6FFBE3669B03F1D9DBFEE8B417CD0E
-:1009900004388ADF82F221E407FE28BEFFA342F476
-:1009A000170B7853E8E5F6E50BD1CE88BAE66A0A6C
-:1009B000C49365733A70DBB85F3686C1A9896170EC
-:1009C000264A6E37F4D3BDFBEA28F03BBF3BFA045E
-:1009D000DA797E2BF3DB1FF49415A9E3DB6B6D0250
-:1009E000A797C010D87F77DCB82701EC956C59C069
-:1009F000F74EFDB2EFE9F199C09F66DB57D2296649
-:100A00004F36E2FD327F5460C8C32A3DCECFDF4D62
-:100A1000F55FDC3F441DFFDC6ECDABB531F822C085
-:100A2000CFCEDC7B0CF480DEE44E58AEB804902BC5
-:100A3000E4EAA1243C5F6ADD67039F68177FE7E073
-:100A40007CEB9EA40534ADDAF29F36B0E3EA383E83
-:100A5000CE4BEDF85E53E57611DF13A1FD263D0088
-:100A60007EEBD68559ECDE1FBBAFA6C8D5F19FEF54
-:100A70001952C49C8978FF4CD137A798BD3E189F66
-:100A8000BF8EFD1DCC29BAF7C96EE5EF93E9F5CF0E
-:100A9000676CB2E22FC3F8A96576D64F6FFB2BFBCC
-:100AA000B304E253EDBF6C2920C2F8B33F4BC2EF51
-:100AB000E70FA43D5508F63D919D2301AC44F6A2F5
-:100AC0007ECBCFA7E86F2FBC7BBE9367DE6EBD3CAD
-:100AD000EB66246E2AD704D0C7DC0398D391C907EC
-:100AE00045FFBBF533ADDF55AF072B7232D73F6EF5
-:100AF000D510027877CCC2FB1307248CF7D2EBC950
-:100B0000538305BDE8C34F207D6D6D4D8F017BFE86
-:100B1000DF609F00DDB65EC6F783AA49E01E78C796
-:100B2000A9BA55B40760FC24F37AD8678A3EA1E0DD
-:100B3000A5EDEA1EF358DA7FF645837D0505F176CB
-:100B4000F02F68574FF8FDC1049067FEA084E707B7
-:100B5000D917F7C62C54F145FF55037E7FFBEA6E8B
-:100B6000EDF760FCF5D06E8B81D9CB7BF7FF3D06AE
-:100B7000F8D4DB572F21BC903ED1536F46FD3BCFBD
-:100B80002A86FCD16ABD9988D98721DE6B6A2C152B
-:100B90006B42EFFA70CE87649595F4D42B42782798
-:100BA0002E09F0D0431F56F0ACD3333EB2713D77DF
-:100BB00018190FEF5EB65D4DA8C07BC7FE18FB0A83
-:100BC00094CF4C8FEADE7BEEC9E9F0FDA0C8DE9D34
-:100BD000B82AE27EDABDB36278876ADF524E8AEBCA
-:100BE0007665D0C50B6FD1FA57F64533FFBAE4BC32
-:100BF0005E7D4F225CDFC7F11518CCCEE9BC83E1E6
-:100C0000BDA86FACCF74F5B0F7FF61433D39580014
-:100C1000E262D4FA4E23ACFFBFD98A3E67FCA52519
-:100C200006F88B97E40E21B4DFB268920B7415AC12
-:100C30002376B033B61F3018605D3237A5625CCFC3
-:100C40002BFC1C73494BA3315545174BF839D81968
-:100C5000D99B12AFFABE3296F19733FBCA7F8171EE
-:100C60001D7F34919111F4D085B14CFE6E337AA77B
-:100C70006F867AC70D78DF68EFFE5FEF877793970F
-:100C80001C738C03BFE09458B60FDA0EBE520F717E
-:100C9000C16D1F82D4A2726663B168A0FDBE451CFF
-:100CA000CCAF7798FDBDD6903F94B812609E37C503
-:100CB00032BEFDD60183E6DCEC2DFEBEEFF5B18C35
-:100CC0000FA5C632BFDAD603B9090B70FFB947C406
-:100CD000821FF064473D6C45C50FA8E86F930F6F06
-:100CE0009D3E86FE737297C10ECBED38FC8208F3F1
-:100CF000759C21244E203DF4390A6FAC1ADE5B5DF1
-:100D00000C1E1DC76ED8AF0AFEA904FE7106CDBF2A
-:100D1000D52EC5433C98827F651E4AFF8E16E2DAC7
-:100D200060C1ADE4DAFA15FE68E5EF314CB013E5C9
-:100D3000EF33205D6EB7B96E89C5726F0AE4CFECF0
-:100D4000637AD2362E4F4972F170C09FB24EF3795A
-:100D5000AA8CA7B7FEEFE7E354D2AF4BD7AFC80ECC
-:100D60002FD2CD76164FEEF006CCE91077D6968EC0
-:100D70007F9F4A15977B3F8EFF8CF6FDC2B60E8390
-:100D800001EE8F55EF10E250DDEDA7BE1DA233A995
-:100D900005E9AFED18C17D5CDEFC5DE68FA4729FB6
-:100DA000BFEB86E7EBB07FF839FB2081A693FD1BF4
-:100DB000560E41FC066CB0AFC278A2FB06D2DA46F2
-:100DC00023D0EB92652C2DE5E7D54B9ADCB83F4B51
-:100DD000D6B378C465B1A94C3E737A2586E8C1F8CC
-:100DE000DEBA4D7B8FF01F5C7E9E6D7D6A0FF44BEB
-:100DF000E9EBFB808F9BDA9E5807C355E8F5EC467C
-:100E000019E194456BCFF33DB1CCCFB8FD30A3F7DA
-:100E1000C91BE55C784F6CB297D8C1BFFDD6C64DF3
-:100E200022F0EFB7809E53D93E07797B66DF6331AE
-:100E3000DF07F9D66920E047DF6624655B54FB6273
-:100E4000EF863734FBB7BCB96E3AFAEB3BE205E00C
-:100E5000F3CABE55F0BECDE8BC0DF7FF9DBAFD9FAD
-:100E6000CFDAB7C2BAD07A4FF1FDFFD434BAFFE976
-:100E7000A7B88D7102C0D9668CFCCEDC4BDF90FE2A
-:100E8000427CB5A3075F7D2996F91F6CE9B4FFEAA0
-:100E90003B2EA1FF21343E4E374FE52B74932A00A1
-:100EA000FE1BE90A8E007C51BC023D533D7AFECC0C
-:100EB0000CDC9507243CFFE1E74B3C2E0477946A59
-:100EC000BF86F999B26FDD6FC038B2F26B57829E60
-:100ED0009F50E845FA3C2BB887C753797616F671D0
-:100EE000047EB08EE3E38AECEEEB7DFFC140CF657C
-:100EF000D46284F990F5821DD6452977AC67EFBDA1
-:100F00001EE6F094EF87BF2DBE833DDE213DCCF081
-:100F10001D34425CEB281F936344C8C5FD400CB7E9
-:100F20000F867DB684CAAFFB55F2EBACDC8874AAA1
-:100F3000E0E123CEB7AEC4B1793FCEC7E9071F5D6C
-:100F4000A20AFF8224096C3F8B02DBE722C03FBB71
-:100F5000EFA6DB90DEEF884CEF76B0B7E2E1EF472B
-:100F60006D40FA8C9B66C77B2F4F49CEA8388D7E8B
-:100F7000E4C374EFA667D0CE03FA85FDDE1BFD97B0
-:100F800001FD930874EFA374AF5A3F850E285DFCF2
-:100F90001DF0A57CD7D385720EA9E0659BEE1C736E
-:100FA000AA9DE1E9FF00528D6EB5008000000000AF
-:100FB0001F8B08000000000000FFBD7D097C54D598
-:100FC000D5F87DF366C93233994C76B230490CA01E
-:100FD0002C0E4980B0D84E08204A88C352D7A0931F
-:100FE00000094B36109556948120068B18152DB6A6
-:100FF000208385EF431B6D10A858832610112D62A6
-:10100000DCB17FA54190454122A81FED87F53BE764
-:10101000DC7B33336F26026AFFE1C7EFE6DE77DF62
-:101020005DCE7ECF39F7C56ED3313684310763AEDE
-:10103000E6018C7D8F3FBFF4978C2DA1E77337CFEE
-:101040005E712482D1CFF7F0BFBA795E50BD76C70A
-:10105000AF571CE9E7AFCFC55F52E0FF71A66789C4
-:101060008C55F147AC4CEF89B525C0FB119DD66C72
-:1010700098B466E2196384039F781983F66F631C42
-:10108000543EAA6FDED32B1FCA31CCE985A6399B0B
-:1010900033158F99B105361BAD67F927D393DDB0B2
-:1010A000DE46C6C6E3BA9BC57C72DDD93685C699D5
-:1010B000E029738F898367664F9E7BA0FFF90766DF
-:1010C0004F966D88BF3EA170BEEA18404B8CC47E1F
-:1010D0006355980CE69FBFC9E4336532B6059FC4DB
-:1010E000C32ADBA37C9B32FDEFD9F4CCA5B73396A2
-:1010F0006BCBA475C1EA5AB1EE58686497C1BCDFE6
-:101100006696B59BE1D1D51DDEE281B08F2D46EF0D
-:10111000D489993898F31A1CFF9A629DED01586A98
-:10112000ACCBA63807D092695EB68FCF9397EDEC23
-:10113000CFB2A1EE70E6B92D8C8D12F862AD30C938
-:10114000703F1C42F1C6E1D9135E17207C86501710
-:101150007A7EE2D5A81B7D66FFF34401BF2F63783A
-:10116000F9ADC1D3DB660E1D27603E554966CCCA7A
-:101170003C4B555CFF2866DBE4F03F778C622E1C0D
-:101180007F9A1857B6CBFA8FA6AFAE10FA9A867828
-:10119000AD8EE822BAEA53D06974C0BC4C19DD8B1D
-:1011A000C1FA98EEDA5EAC80BAEA71BD0048552902
-:1011B000E0EBC7F6848D33D7239ED90113CBC90C3E
-:1011C000DD67B5CDC0E1B6D130FA66E897E065B825
-:1011D00003C08B83E38535DE8AF86BDC686288D7D1
-:1011E0006F6339DCAC53D96803F4B7427F24F7C688
-:1011F000A99E035741BD31D9E850609E13862EC287
-:10120000FB89ABA08DE8C3AD20BE4FBC3AE29ADFAC
-:1012100040BB77A28EE5C08B5B8DB005A4C3BFA792
-:10122000F9362948A72DC427F3C7B2C12678DEBEF8
-:101230006918D1D5ACE22C05E976CEE658059FDBDE
-:10124000C7D8742AF3EF63D84295E813F8A0DE16E6
-:10125000808F61DE3A15E1D53BCE936C8865EC1149
-:10126000DB35E323D281CE3259241BCCD843505FE7
-:1012700009706BB4BB14164BF506730AF121632396
-:1012800008AEAD0CF0D418D55D774560FF2C5E7FBD
-:10129000A4F1EA868634C69E897135229E3E30BB13
-:1012A0001FC1F98726D5A944E782AE7F80CE7E1282
-:1012B000BDD42E2C6287F3E0F70E660EA41B904778
-:1012C000B76E06F895E83D9B705D35BD8E3E8EC3CA
-:1012D000D5B67C65F484A17BB98E782117D8C78CEC
-:1012E000F011EFAE53CBCD7EB9B3C566174CED52BE
-:1012F000265BFCFC8672EB7933973B59509A229817
-:10130000D762C77E3EA223ACC7E4FAE5D1CA62DD4C
-:10131000785F183E7E0D89EB6794CFACE57FFFF2D6
-:101320009BA1D01F7F57899F5EE3FCC4E5F5A3C551
-:101330009F26223C9093F0BDDBC51CEB973ADFEA79
-:101340008B74B95F659BA03ED864F42A31B86DE612
-:10135000B0258AF1900D5B9456CB20A8FF4B612EEF
-:10136000C0C3E97FA954AEBFD73D3E13DEAFD9A1BC
-:10137000732E857E352D0AF183B337F345001D3773
-:101380004759073118AF70B7D96580F6D34A04C9F9
-:10139000659C00D76190EB2FE8CA6882E7F52DC005
-:1013A0007F503D5D08A8C6F5EA9D316C801FBE8365
-:1013B000DE7CB41FEC00DA1B9DC8674F45F2F19F3D
-:1013C0008ACCF081108352BEE788014A6159826E4F
-:1013D000F47AC662004F5078B11CB530DBA5073CEB
-:1013E0002B7AE63500BE4675B5AA089FAC2E878ECF
-:1013F00099FDF3E9BB18ED3B4BEFD03903F4D5D69B
-:10140000BDCFAB7A80EBD0318DF52A9489319E6FB8
-:1014100010DE2346D5D5637B5CB157F540FF7CA534
-:101420006EB705E9EC1AE644B92AF924AE93B5C1C2
-:101430007259EC814E9715DA471C77B50D80FDC7C0
-:10144000B89982E349FD0D7CC662910EE35DCA4402
-:101450001867E83F18C1478EB375EF6805F93EBEBF
-:10146000638CE218104AE76B98E3B738AE779FCEEB
-:1014700089F8753433D70694137FBA620CC24BF6E1
-:10148000EF1DCBF5CA488FA7084415EE2706E71DC8
-:101490007EA36FB701D6336C9677B7D111B09FD9C1
-:1014A0008CC64BEDF4D23E520E780AB1CCB6C6D201
-:1014B00038238EB7B60D807E4975B01F684FEF7820
-:1014C0004F41B8A6D7752888CFAD7B77D17AD33A6C
-:1014D000DA7929F8EB79611774DB03561DED23DB0C
-:1014E000CAF5CDF2535C6F66C77AB2AD09FE7D2CAA
-:1014F0002FF424D7C1F86BF66675EF17E5EE952843
-:10150000E403E4526EAC91C6B9CBEAE98FFBABBD04
-:10151000B1730FD2E0F37BDFB1127FB4C4137E133B
-:10152000F77D4AF8485C48BA98ADD9375F4179B140
-:10153000A61470A684C259CA8D35B87EA21F5BF46A
-:1015400024A0CF27ED9E82D8407BA5CC1E9D1520E0
-:1015500097E47B8F2F66EE19B09061EDE55B59162D
-:10156000C9F77EB101F27DC2C0FB22919E9A2C2E5A
-:1015700017B69F56D88D38CF335842FB33065E9747
-:10158000F07A40E0333B7652B6750887930DE8F861
-:101590009948DE4F2B8FEE8DD509BB83D30BEBE043
-:1015A000F482FB08B4BF66C6723C8C74798AF49CE2
-:1015B0004EA6E2FE8617F87623DD0E1BEFDD8DF4D6
-:1015C0009FCE049D8CE774A2A5F7DB63B97C1D71E7
-:1015D000BC8B21DCF315E60E67EF54C672BB29BE47
-:1015E0006334D10FF04319CE3734B54E35A0DC66E5
-:1015F000B609A87F7E13EBA07E7905AEDD486F3675
-:10160000979BF879BED9C6E92693D307BC3F271C20
-:101610003F6D433E1AE0E7A378A44773283DDE26DA
-:10162000E0F41B01DFD0F13D77E1F8F11D3A9702BC
-:10163000830C3B60F631E83A6C01E849E45306F468
-:101640000F0BB4CFB215229FA5563915C4EB02B3C8
-:10165000FB1EDCD772948DF948CF3A5F3DBC976C86
-:101660007311FE7EB49E6867116C68909DF5402CE6
-:10167000B7E35795A1BC7EFA5B23CA5387E4BFBD8D
-:10168000B9D1E501F4F1C7507C3F120EDF5A39A7FA
-:10169000C5B75F2E04CB3980D75A8E0F6EE7C77758
-:1016A0002C50B97C08966B3DE123443E083CFCC1BC
-:1016B000ECDA84EBCCC64540E91DCDFA617B4FFAEC
-:1016C000F8C558F34FB3672FAC8F5F8C4D08D5C763
-:1016D000BA88AED7158047758BEA50610BF58BEC55
-:1016E0002EC4FFFA66C58976E1EE1695E861FDF233
-:1016F00028D29B72BD5F6E8F19C4AE8452F03F6BCF
-:101700008F257D5A1B2BE65F06BFC0FCA76DBCBAB8
-:10171000DDE6793D500EAD6FF92612E1DC3F5971DF
-:101720001D41BB4AAB8F81851478DF84BF2908D760
-:10173000C10D2A32D6F59EAD2695F0F62E8E378C49
-:1017400075BE330AD6F5A7A6D1BA407BEBEC8EAFB7
-:101750006FDD05EBAF8DE6FAB9369AEBE7D3BBCE7A
-:10176000F7417ABB76E174927BC3F49E8F03E5DC8C
-:101770001BFD0E7339CC4A6D47FBE3D42EE5FB68A5
-:1017800000A135A29F1EED0A35CAA906DB15441C2F
-:10179000F539001F845F5B14C1AF3E07F82E93D666
-:1017A0007902D7D96E31B214683F0BFC88FDE4BAD8
-:1017B0007FC47ACF845F6F9AED68B4A00BD5BFBEAB
-:1017C0006EBC201E607CD5A2A77D9C66514EC4676E
-:1017D000B3D1C510FFDE83C23E1078AB113477BAA7
-:1017E00065C8010FEC6FFD813427BE7F7AC7D948E9
-:1017F0009D19ED478F6A877DA9E95D56D487BB5B4C
-:10180000CE5EDE3980E49BC10EEB3BBBEFB0DD3337
-:10181000E047EDCF6ABF88FDD5EACD0D817622AADB
-:101820005952941A3A525ADAFEA90C22FE63280F32
-:10183000BD19CC570FFB5E3E50D0D354E640BED707
-:10184000E27BBBCD9D610FE0DBCD36B703D785F3DF
-:10185000A4E6D23EB3B03EE8CDE979061DEE6F0CAA
-:1018600043BD29ED3DB94FB4C72373FDFB93F65E2D
-:10187000F7FE73CE0FDAC768DF83EC740E742CC5E5
-:10188000735A2D2885073203F7DF4A78A916FBAC77
-:101890008E30B7AAB02FB6CD70B253CA83ACD07D0C
-:1018A000009E86F37D380F7810CF7F373BEB114ECB
-:1018B000FA0E1BDAAFB0AF91B80F5650968C70F895
-:1018C000C0EC9A8CF2FE99258CE8FAF4B3CCF714AC
-:1018D0006C7A4BBB8EE86603BB82E8FF0ADD995B3E
-:1018E000DD66E2EBB1F87E7E47A30EE56F8ECFA1F9
-:1018F00043B97A7947B34E47F4E0192FE074560F95
-:10190000EBEBDF54A7FE48BA98149E2E42F0F6ABDC
-:1019100040BC49B88D12F4300AE18632B94B7FB22F
-:1019200033C20F37C00B4BB5878EC7586706C2A9A5
-:10193000EDC5637D3A61BC9A978FDD8A70A9F9ABDA
-:10194000898861CC5F2F8F41BAFFB230BC5D737262
-:10195000719D5B0FC478AB3D8BE47B15EB30A2BD72
-:101960000072DDAD0F90EBD28EDB67E828C6F1F791
-:101970000D51D91280F359E7B02416465FC8723F63
-:10198000DA6D39007FF455E1F9E4C5FC186E47DAE9
-:1019900083FC5AB2DCB778967B8CA1E7F1F60D8E0A
-:1019A000247F4EB1C61E7AC8CEED8DA7ED5CCF81E7
-:1019B0006076E13A4FFDC5E2F342D3A9DCF7AD0C06
-:1019C000E0746ADBBB795EA0A353ACE3F69790DFCB
-:1019D000BE36D3B9AE78F0FB794B2C7EFEBC8AFBC9
-:1019E00052D8552FBC697540FFE22DBBE3BD01F015
-:1019F000BB8AE9BFEEA6EB4C9C97EF8FE93BFB203F
-:101A00003ED84B27121D5016BFF86A3CA703383743
-:101A10000D45FF14E78F3F635380DD5DBCB0C63DCD
-:101A2000262FC01F732E92F902EBFA0E231E89ABEC
-:101A3000CF99A9FD76BB259EE44D2FD60BE54D8FA2
-:101A4000F0BA48786ADB253CF70D3E9181F6C597E0
-:101A50003DD8C507ECC17EAF37167BDC6372FCF561
-:101A6000BF7DA7DEE60EF35E8B18FFAC737812DA4B
-:101A70007DC5C6D6CBC2F9E1E439530BA737CE57A3
-:101A800046E3B87F39671A1F6E5DDBEDBA9FE63F0C
-:101A9000D807AB0AB00B4BF49E37EDDC5FB06A326F
-:101AA000D46B2E3F3B8ECED9925E84DCBB8A79DB31
-:101AB000907FB5F421F1FDBEC45B2A4B45BC3D6966
-:101AC0007770BA11FC20F9430B476D39C1C83CE16E
-:101AD000CE03CF75C3359279411EDEBEC1407AFE7A
-:101AE000CDF31F4ECD037A3FB6D6605B0A53CE5A74
-:101AF000B73BED51F4A70D36D914A81F73B45E8619
-:101B00007C5FB94E75233D1C5B7B7BE27428BF0074
-:101B1000FEAD8275546E3050FBAC0D7750FB09C1A1
-:101B2000D795EB12FAA3BC7CB3FD8144C4E3ACEFC0
-:101B3000EEBF1EF1B2C568EB3F18CAAA26C53D2606
-:101B400000DE73364606D5B7E8D82CDC87C42B53A5
-:101B50003CDDCF1DB01E63DC4FC4636B881FD518FE
-:101B6000C7EDCC9229B0EF9A2167C9BEDFBD278AA5
-:101B7000F4C92B6695ECC8D6C1FFF3B72BA15EF470
-:101B80009DDE49369EC0F358816786CE40A08F8A7D
-:101B9000085E2F7A514F766891452578B7825C1D93
-:101BA000434ADE651E0BFD7E21DF5347AD1E0EFD51
-:101BB000C6C61818EAA15FB4CE2966A0277F794E61
-:101BC000FF6967C07E4633971EEDE24266086A5F92
-:101BD00011657D0AED5A184C8FFAB02822F8F9D811
-:101BE000CBAE3D81F6C4585B70BBA4BF9C38A0BF90
-:101BF000FE7EB9B17BCFE78F4C807D56EC53C99EFA
-:101C0000BE905CDE8FFBCA417CBF51DA04EFBD2978
-:101C1000A0F3E6F963CB5290BE0A14867EAE63E76A
-:101C2000C3F3E55C419F8C019EFBF9F13CD139BBCC
-:101C3000BB8E6C7F5DC1BCEE3AAEFFE2E5D90FCB47
-:101C4000AB4E3BF76F68F587967FFE53FAA378F0AB
-:101C5000AB195E0B95FF85E5C92D5CFE6AE58556DF
-:101C60005FC87569D75B7D4E0DD213CF0979E2D776
-:101C700017467AFE339E8F6BE286849E8FC19E212B
-:101C8000787987EAE95C0E76D7EDD86F80D911575D
-:101C9000084B5A66CB8A46B9D664F1DC1917E0972F
-:101CA000EADFD4A843F9D1EDAF3104FB6DE4F9F5D7
-:101CB0009E38BEFFF2385E87F32B9DFB3744799246
-:101CC000F5386F2FA333307E25CBFB85FC9076AFA4
-:101CD000B477A59D2BED597D03B767B363DD417ED6
-:101CE00033D6AF5F903F18ED74E473EFAE28DAE7B8
-:101CF000678A7B10F26915733D1417A007EB0D7C02
-:101D0000FDDAF5BC1627EC13E6263B41B6CF1C1DC9
-:101D10005E9E6F8DD353FFC2C76FCA403BEEB3B612
-:101D20009B3350CE7EA6F1FFF6C40F0F0B7E7D5085
-:101D3000E89358E1277808F908EAC0EDAE2DF0FEE7
-:101D40008AC56EE2ABDF2EBE91CA47172FA4E78F7C
-:101D5000C565D2FCB6C277DCD900A7232B55D217B4
-:101D6000338DEE3EB1F0DE91081DF91B0ED799C7F9
-:101D70006F33633BA3F3E5CCC7276CF206F8011F72
-:101D8000C37D0CE9799FAF09BC5E2A9D56B34E2BEB
-:101D9000EAAD6E7A3D10A2B7DB112FA7596722F684
-:101DA000AB553AFA3429A1F33FC85CAF61BF662353
-:101DB000EB8F7CD31CC5F592B6DF9B027FABD09E28
-:101DC00085F233D45F61E4CC3B825E7B5B5DEFC424
-:101DD00091BC3393DD4EEB56294EF43ECE07E7B46B
-:101DE0000FF139C689D05F976DB575C755F879C7BA
-:101DF000FD715C187F5C4FFE1FED3AEE89E770D5F0
-:101E0000FA856429FD42C7C47E16C5D982FC44E820
-:101E10000F0FE70FBA3ADE48FBDB10D5E9C5B8A8CB
-:101E2000F7667E3E4F1AE555D0DF955ADC5888FE9E
-:101E3000B07FC6713FA67DBC2719CFF1BD928D4EF4
-:101E4000F4E35C2C3F0E6876F138814747EB58D3BA
-:101E5000E18DEC03EB4AECF0141AA134C426D2F85D
-:101E600049AC6E09E20DFA1130F2DBA37C8A3C74B6
-:101E700043973C214761A591C877DBAD1E533CBC1D
-:101E80003774465D3DFAED53AB783CE284E2E96D90
-:101E9000CF0E8D1BCB32395EF0AF88BBE66F34D0EE
-:101EA000BAF2373E46F1D1FC8D57EB950039941FBD
-:101EB0006FA0FE275E9DD39BFC181F858FBF0E88E9
-:101EC000E7F462461FE1108A8786A5BF7EF13F31A5
-:101ED000AEDC09F650B03CEF173F24206FA1FA0C9E
-:101EE000C9737D3CD7237FC07C0558D31F66C87C4F
-:101EF000850DE48FDD6A6CBE06E351DE1A1D43BC1E
-:101F0000B7EFF92BC56B67CD7050BCB6FBFD7DCF2D
-:101F10002CC7F63FCC628311FE29BE8715F4CF7C17
-:101F20001BC9E3C9DF6E32B125B0A5D96F37533C69
-:101F3000784D958EA17CD1EE1B6632E8785CDBA0F3
-:101F40002BE0F8473928F10E0464447C48BC21FC9E
-:101F5000B698316EFC02AD5FAECB807EF004DCC77C
-:101F6000966B904E7A55D915F417C8755D489F4CFD
-:101F70008AFF69FAE467D4C3B7C55F9C1E9E81746B
-:101F8000AED5C35AFDDB64715562BF0BE9E1134264
-:101F9000FE4D89D7C443307E16066FC7841C0CF0F3
-:101FA0008FDF19FF23FCE31FA11C09E31F7FC6C8B5
-:101FB000E56FA39DDD36290CBFBC27E6D7ADEE3219
-:101FC000A2FE8C6F51C2CAB36CAB51C61357E0FA74
-:101FD00064FC442B8FC3C0B711FB5FDED4BA0B7B0C
-:101FE000E5C65E168DE6DB15DFC3B937CC3C6B0466
-:101FF0009F3B16308AA33AEA18C92BA8FBB893B0C6
-:1020000095F223001F4FE0B8178A639DB615921D05
-:1020100024E35686D8E0F3F89E78D9CFF547C46F0D
-:102020007A0F7AE24F625DB0FF67B05FFC02161470
-:102030009F917199F83AAF62CC4775C4C8DFDA3B1B
-:10204000CEB304F33FBA8633E753508F29B515A2B8
-:102050003CB5CF72B661FC66F929EE9F5F3E8FF901
-:10206000962A0179059E2CCA0342BC05FA07760A16
-:10207000F9B653AC1BF4E45FE3F9BA5AE203F4A4F3
-:10208000C4876E75AB4A78ED0AAFA702F0DAFE435B
-:1020900078FD19F9F29D8BE4CB0F2F856EFE7191BF
-:1020A00074F34B8C6F0C093BDF678857ED7C4067FE
-:1020B0004783F8BE073ADB7889F1D2F9E69FA8A7F3
-:1020C00042E1FA5D7C42285C5716EBFA91BC6651FE
-:1020D000CE707AD59660FE4FE791D812865C7A1E54
-:1020E000C9FA7B3B8D8867190791EBD5E68FC8F657
-:1020F0009A16250FCF9F85BBCFD339E074DBBFE89D
-:102100001C109A07C2E79D0FE48DFC39561DD0DCE8
-:102110000AFC77A6C948277595397E370AFDF77BF3
-:102120000DCCE7A0FE11D8FF0AC6FB5FD1B4BC03FB
-:10213000FD575730BD579C4795EFB91D15837C7CE3
-:10214000C55E95F2BFD866FEBC8E452C41FF744C2F
-:10215000818E3902E019EB8A628E0078C68DB7074E
-:10216000D5E53979AE9837C1DD2BE8FDA41BB382E4
-:10217000FAA778AE087A9E3A2B37A89E5E3722A837
-:102180007FEF85A383EA99DE6B83FA67374C0EAA4B
-:10219000E734DE1CD4FF18AB7B7C14ECB33FFA5B56
-:1021A000003FCCEBEAB80CD63B43ACB7EF9AF2A0B9
-:1021B000F781FD5A311E385390C917CF8DDFAB0020
-:1021C0001C6708FFCEE5BE3941E3CF55AB887E677B
-:1021D000361A8E04FA69F4AC6B4F2AC0B9C6A73818
-:1021E0005BA15EB926F8F9EC1D1BE8BDD9BEE0F68F
-:1021F000B99B83EB83DE9CD29FE701B929BF72466E
-:1022000042B0DF8785D08999E4F499B5DCFFA57ADF
-:10221000FB6AE824185FEC27D28D43D08D293998CA
-:102220006E221DC17453F9FAD6A108072DFCA3FB39
-:1022300069E8C90BFF7E00FE1667307D69E14EFB41
-:10224000837556EC50D8EF9550B8CF6A7978792AD3
-:102250000B853B633E23D71FC1ED8F68E0FD81D91D
-:10226000F318CA89B33B16A8188763E3793CFFECDF
-:102270008EAF07ED7384892FE584C497D62504F8C3
-:102280007F647CE934C619AF64171167DCFD4F84A5
-:1022900007C8008F01F3110B9C11DD71C5487F3C0D
-:1022A000492B3F6509FAE3B904D22BFE786C3DBC9B
-:1022B0003D34E60337AE53C6E564BE8ECC2B0A939D
-:1022C0009FFC978404CC0FB447E3F9754BFB7C3A31
-:1022D00077C9BC2226F202C3D8FFA44F9AF1D714C3
-:1022E000B20B762670BDFE0A8ED76D1788BC2FA95B
-:1022F000D77B1A47C6DF7A2A955D2AC513BB942877
-:10230000E75361F4CA47093F51BF85E68F7F14A8A0
-:10231000476AEE38BB07F50BC0FD636CB758406FDA
-:102320002B7EBDFDBB682BD16BD7EBAAAF2F349CA6
-:102330008970C4D8018E2D22DFAF45E4FBC9F5D6E4
-:1023400045A4BAF479D81E9CFF27E38ADAFD8DC232
-:10235000FE71FE3ABC1764972CCFE576DB690187E6
-:102360000D166E271813B99D50AB391FD53670FB6B
-:102370000CA4D7AC9680718C8916EADFDF5C684CC0
-:10238000C47184DF6579A64276C57245217BE47706
-:10239000B6D1F4FCCF09858644E8FF6F31AF1160F8
-:1023A000886563165F8F439317FE92E8FF52C268F9
-:1023B0002A8D8936E17FB65D81F4916A7619A95D2F
-:1023C0000D1FA78A4EE4FB1A29F264B47180714292
-:1023D0006EA2DFDFC4EDD2E2B18941FEFEF78CF1DF
-:1023E000C2DFAFD0EB2E9453BF1478EFC9FFEFEAF2
-:1023F000676B47F1ADF5FFAF8CE4FE7F191F08F165
-:10240000FF3BC785F5FF231EA2ED7EFEE993D82D85
-:102410009FD2503EED307AEAF1FCD5B51DEC7868DC
-:10242000EEE7EBA4B8C0C07DD94E3C672DCF64BBAE
-:102430002C486F4B18433B7F47A76E69243C5FE9EC
-:1024400065367C3E7C2D3FBF55AE7138719B520E78
-:102450005C9DC8FD8706381F5B72F1BDC96D1827EA
-:10246000583995D9510D35B2C6222BDA456B59D85A
-:10247000F3E368414F130A7751FE764217CFB70F47
-:10248000EDA793767E21E2735897E72C8FCF717971
-:10249000422211CFA9ED3A5FB8737DB2ADE86AA4CC
-:1024A000AF81BEF0E78891C24FE632BB27E2F80366
-:1024B000B7F17CD84A297F67E8981EF03E45E07561
-:1024C000CA5A9ED7C1CE7FFFBD2AED4546E333945D
-:1024D0002B95532D3EF41355B6647A695D6EC599FC
-:1024E00083F2A2E56D37D62BF3F36DE89770FD9D6F
-:1024F0002947FB91A9C9B8FCD2B3A3529E901E8F65
-:10250000A738D464416F23F1B09C40727E6534C01B
-:10251000BB72ED925D98D7F3FE1F19C59B0EA85DA7
-:102520004371B05F017016E662A967A5E4B748A6DB
-:1025300071A68A71BCFF827923FCF3FEAAE575DAE5
-:10254000CF0103F346001D9DDE798303EDEEE5091F
-:1025500011E4CF9371DA83AAE73E5242FAAE1A5CD5
-:10256000DA4D2DD136F4839CDEF9613AC64D3EB981
-:10257000E7AC05EDD87FE8BB2C982F7C7CD1BB164F
-:1025800017C0F193452AE59DDD2AF48684FB7D89F9
-:102590001CEE1F27BA1721DC6F5BFCDDD0C03C2A84
-:1025A000B63081E879B64FA5905CB79CDD1C8D16DE
-:1025B0004A77BDBA392EA82EF540B589D5853BBFDF
-:1025C000BC24E86976D30663AA03E7F7AC42FA387D
-:1025D000AEE774747C9BC5E7CDF4AFA7BC69B011BE
-:1025E000ED837FB498582BEA337D8781E749BB8A16
-:1025F00015A00B8FC0BF769D7B5E8EA6F1663EC692
-:10260000E54719CCB510E0EB69994D7241BB8F9944
-:102610009F38C625015C67AE5018FAE3B0FF22C0B0
-:102620009F67E1FD5FA1FDA5DD679937580E48F969
-:102630005529F03CBD21F87965CB6F699C19CC43D5
-:1026400079206027699E5F730CF50AD84741ED67D2
-:10265000F6669B518F6F4914F1EDA16CD8F7F0FE2F
-:10266000AE88EC184F187E92E5C9C53622D6CF1732
-:102670004750797C31A3725122A7E3AA96B7EF4461
-:102680007BA966C716238E73C9F1819613D69B99D1
-:102690005FEF96E83DAF211ED92C25284E50B3E1BF
-:1026A000AC91EC32019F52D15E8AF0003CDCC21C3E
-:1026B000ABF13C505A65F0C7E9E0FF5B72BFC36005
-:1026C000BF80DAD1913917B55FB94FB96FF9BC5AEC
-:1026D000057A0CF3BEE48345421FCDD83869792FC3
-:1026E0000051FDCE63199DFCBC49F67891C06B5139
-:1026F000C4FD648F1785D8E3EC3DDCB7A4C74AE678
-:10270000243DA2A53B4907CC6CA0F72384BDDE4D38
-:102710006F2D0F125C243DCC5C5D68E4E69BC7C85E
-:10272000ED4A6FB2F0D726A3BF16E830C83E06BA0E
-:102730000BAA6BEDF12F0D9D19281FB476B8CCE7CD
-:10274000D4C2E76022CF5F9AE1708DB30DC0738071
-:102750007B39F985F146CA10E4DBC63D7723DF6E8D
-:10276000E47CF30F410FB3923C1149F0DCB3F49ACF
-:102770001AC47FE7125306F2B367698A1A0FFD3D48
-:10278000AB1492C3A397A61811CED3970D1E877CC6
-:102790009DCB5C34FEB43816D66E189CC4E54779E0
-:1027A0009D811963082946F40B9F6A50C82F8C9AA3
-:1027B0006422E06B96C057F58AB7ADA4AF1CF06FEA
-:1027C000285E1FE03FB3EA2A091F70EE08CBC7520C
-:1027D000AF54B166630A8C3B67651BD1319C47825D
-:1027E000FAD7B29584AFEA664D7BDDD5843FD8B980
-:1027F00011CF89B53B829FF74F127682933991BEF4
-:102800003D775A2230AF71B4804FD94AC586726B7A
-:10281000FAB2B6841BA03E7DAFEA84ED74C387850F
-:10282000FA23281FEDCCDE1CF2579C713892B09F22
-:10283000C7CAED5245EF1986EDD3E23CC3D0CFD8DD
-:10284000F59185617EDFA1732A73E411950FA2FCD7
-:102850002A1B1B3429C0BE2F33D812311EE965F361
-:1028600093C53DB88840F8D446AC247EA8457E8800
-:10287000F0F3C3348C7BA1DDF3A24279846C473042
-:10288000BD9F703426C29190B9EF33909C2E6F8A11
-:10289000A5F371F9B22223EAD5F26DB1641FC1F933
-:1028A000F4BDCB86FAF1796859DE9E6418B7BC395D
-:1028B000D3A906E331F4DC19B0CE390D8724FE8E9E
-:1028C000F480BF23E1F007780B6A2F4F127249E0C2
-:1028D0008D2D8A23BD5A3AEFD59C0858D799BA480E
-:1028E000CA93ECE97CC4668CA0FC03E9BF1ADFAB99
-:1028F000DBCF44793E67570E21FC69F136FEDFD30A
-:1029000087A1BDCBFE6E6168674DCB66B74D86F67D
-:10291000DB14CE6FD3EAAF198F76C4DD495C9EBD60
-:102920000572D0D597B1B7410EBA400EBE0BF21169
-:10293000EBEF2F4EA6FA878B1D547EB4B81F954738
-:1029400084BF5FF21D1002D1ED92242E179724C987
-:10295000F8FA82643469C6FFFBDD213A1BDE676C3E
-:102960009B30369DB1EB5CC1FAF7C6A9C1FAB5D36D
-:10297000601B978CE7DB150AD9A3E5EE9141FDE1D9
-:10298000DC64C47B2BAC5F9EBF9DF486C33819E822
-:10299000F1A6E2B8A0FED737A406D59F4872D0FAB8
-:1029A000268DCF0E6ABFB9B47F50BDEC9C9131A487
-:1029B000774701F1CF0291670407778E171BEFFB72
-:1029C00075DDB0A4BB60BD5FEF33D0732D3E245ED8
-:1029D00067AC519907C69BBE06E41F2CF148E3740F
-:1029E000E2AF2F0E58E85CB2BC296F7F01D40F35DF
-:1029F00019280FE8D0B2B85568AF1D6A4AB032281E
-:102A00003DCB5561D7D88C2C40DE152D5B42F9A605
-:102A1000653E9393EC9776EF93B2EEC0F32A2E12B5
-:102A2000F9E43DD5D7AA10FE5C04DF6722E95EE138
-:102A300071B027F12AE1F44EBEAEE30A5B86F513CE
-:102A4000911FF7B90BD6716A6263850EFD15EABE58
-:102A500004929FCFAB0CE9B6749E81F20C66BFAFB7
-:102A60006EC03A53725339BE55CAA366CF98687C7C
-:102A7000D6051402FD163C6D7AEA01AEFF787DFBA7
-:102A800040DF03823E918E8EC732572C2D56A1F522
-:102A90007EFE76C2067CEE87A76F10EE7BBDC1FD81
-:102AA0006612E0EFF30ADF20926F8B1288AFB470EA
-:102AB0003F62E4F2CB8B7CA0F8E5A69FCF96927E96
-:102AC000986E70263A496EE5A7A0DC3AB2D24076FD
-:102AD00030D3BBAC93488F3E4F742CE739A2778C30
-:102AE000C3F51D69C864985F51BE52A5F30AD21F91
-:102AF000EFEFE3E7D487550FD824CCDBA07858520A
-:102B000028DDDC3E6F18E55D6AED6D597E09BCEA93
-:102B100009B04BE6ECE479812CBF533F7560E03E91
-:102B200096F1F93C0541F94A5559AF1D34EBC82ED1
-:102B30008CC173C289F754A2B313598D4393019F7B
-:102B40002775BB86DE05F52F267A8FEAA13E22DAAD
-:102B5000F32F84EB5CDDCA0C250BF3FA0FAF1A09D7
-:102B6000EF7DFEACC1496C2EECFC39CFCCEEFD43C1
-:102B7000F615D81BBDB8DDE14AC1FBCF731DCD1AD8
-:102B80007B80C3C78149200017DB6A056D377678E3
-:102B900088E5013C574FD7314FE079E0B0C8E3B149
-:102BA00024F373A8B41BA6247339335DC7E99BBD16
-:102BB000AC707A03FB2A500F48B93D17F3AA55BFF2
-:102BC0001E9072BB8A3552FE8A2399DB2FB3151FE4
-:102BD000D9DD35988902FD2B6C3C6856B5D9E4F3F4
-:102BE00065D298B640FB607A329727738CCF3E8EC1
-:102BF000E45BC93AF83E35FD3E37F82A3A3243F5F0
-:102C00004F856DC3323B8D6F70A29FB752F06B75CD
-:102C1000A3E26B253B85EB51E9579D29F4A8563F6C
-:102C200085E8258D3E9AA9D1BBAC3158CFC27AE94F
-:102C3000DEB25CAF769DEE680BC1610EAC0BF56F3A
-:102C400085C7B7A784D6AD3801A321EBA964EE31BF
-:102C5000B1B80F78DEEA085D9F765F21EB15FBD4F3
-:102C6000AEBBC2F9552BE6BB543529042FED3E24EB
-:102C70003EB4769CC44B8597C3B7A245217C7ED6D3
-:102C80006D1F32F26F4BBA61CDF02FE07D4947B036
-:102C9000AF12946F95AB411E6786D2D31CD66C459C
-:102CA000BAA961ADCB5390DF5A9BAF1F8E7E86B51C
-:102CB0006FD3F9A9D4DE9AA38B05507A73578EBFD0
-:102CC000CA4FE7178A27FC5CF0C3DDE9A59F1EE029
-:102CD0003573A3EA8A1C14D44FE43F7A098EB3BC3F
-:102CE0005E23FA6367093FE585D659ABE7F75F2EA8
-:102CF000B85E01CF9F7BDD0F27F76477853F17769E
-:102D0000DB5B1A3DFFB181FB5BA57CFE5AEF22FF26
-:102D10002EB40B3BACCEC6E37D1AB99E9E4F72BD5E
-:102D200042E87939CFD1355B295E3013ED8080F6EA
-:102D3000CF566FA578A5F1D99956B4CB8FAE99BE71
-:102D40000AF3528F364D27BD5FF97BA9F73DC64088
-:102D50007BA2684DD9FA7B908E3747525CB1A2DDD9
-:102D600023CE452067A19F630D97AB6C3597B39534
-:102D7000A81F07907EEC8BFDEEACF0F4457E086852
-:102D800027BD79E774CF9F77C2B877FE29DAE925A6
-:102D900050D85A7564CFDB5A513F56CFFFF020DE32
-:102DA000D3017BE0FD5F4B7B00AA45064F5B32EA17
-:102DB00021610754AB1B326C683708BDF11F807F5F
-:102DC0004478F8E712FCCB11FE01F1DB4F1B389C75
-:102DD000A76BE07F7825C7CBF2A66C2B9E2F3F6DAB
-:102DE000C826BBEBD3A61C82FF8C0700FEDC5F1F4E
-:102DF0006C773500FCF17C81F087F596B73B04FCDD
-:102E00009D1CFE0D1CEE6C252F6784C0D94BF95715
-:102E100077FED1E4443BE278642BD957C7B7A8AC1E
-:102E20003EC02E9376D137ACF149B4DF24FC67F76E
-:102E3000E91884F2A7F4E1D7AC8887D95B785031E0
-:102E400004FECC9544F1C7EEF9BBEDA86F115FDD30
-:102E500076D445E2A986B919E9C796D70EE039427A
-:102E60007171BF458DBC6FB623F8BE19E69295DA35
-:102E7000D1C5E28C88C0F5A469EFD37918C6BDBE70
-:102E8000CDF9EAD6F9C4E75D4179B925ACD580FE24
-:102E900036D6ACD03DEDEA0585D6428671B53A5AB4
-:102EA00087334509CACBAE5675644F5619457C44E5
-:102EB000E45524897E4929DC2F909C62A3F2742476
-:102EC000237D70DA62F4E17D2A385F25E3FCDE9D24
-:102ED00026C2DB415C13C05F350A3F33A842A4B76A
-:102EE0005B18A7D35BCC7B29AE07279775A81FA7D4
-:102EF0002D3439C9CE8D8FA1F8D2CD42DEDD625E90
-:102F0000EE463D31CD6C746109E37A31F9D7301A60
-:102F1000A687F90DBD8C74EFB034A2F3593C12DFD3
-:102F2000967CF88E0858EA95608EA31F187EDDF611
-:102F30007D5C285EFCF809F64BD74685F78B0C17AD
-:102F400070505C2EF23F9B60EC2858C7A814076FA6
-:102F500077D8B83F7A2DE0C9E2C7AFB69D7979FC42
-:102F6000B20AF3B1F9F758BC241F545D50BDCAC86A
-:102F70009F4F796243F1EA34C6DE618E8188B72AB9
-:102F8000942178EE2F8BF1617CEF3AF487DBB1D49A
-:102F900013BD4CD633AF8E970D663B0EC7FDE325B0
-:102FA000029EBF2A60AD3100F7D6D783FDF337B458
-:102FB000EA5AFB027CAFD3B7B6217DEA221C061B7E
-:102FC000CCE31EAFE4E239A56AE9C5ADB7E289A654
-:102FD000E2D5A3A0AEE3F9AC5DBFE6FE895B805904
-:102FE000116EB7EA59BB9ACBE900E1526B7778A929
-:102FF000DF3C85E237322E20F13F18860FC4E32DE7
-:10300000627D304E8315DF3786C7D77C812FCC8C0D
-:1030100046B8CF157C3757F25B5330BF3D827804FA
-:103020003E55D02E06B8DD22CA9EF8E2A1146E47A6
-:103030003F94C2CFEFF75CE27CCCDC95417979829A
-:103040005FAA4D7C7C39FF75A27C30C54EE3CBF581
-:1030500000BD7E8AE3E8400220BD1E69AC27FB6804
-:10306000160B88C365FAFB49BA0EAD77CB11DDF7B5
-:10307000581ABB6620E8955F443A518EDE626CCEEA
-:10308000A93387F69371E652D661A0EF03493F99C1
-:10309000D03F635533E535952AFC1EF4E9428B5742
-:1030A0000776E2C722BE7B06EC469CA73456A1FCFD
-:1030B000AF69317796205F975A8D7A2C3F16F1DFF2
-:1030C0005B59178DFF892D2BE60686DF4D5031E6C3
-:1030D000070BF8A4D805FBAD47F9C3EB2B5D69E4FA
-:1030E0008D12F54FF7615C66EA79A003AA1F2E7670
-:1030F000C1BCA75F15CFD991627C7EFA3E41CFDE7D
-:10310000E334DEE9C7E4F353FCF90AF9FC2B5E7FF4
-:10311000508E2FEA0F6B9E2FD13C7F82D75B9FF89A
-:10312000AAD88BF6EB684EDAA523149257462137BE
-:103130004A97B6129C4B75BB78399AB5EAF22FDCE8
-:10314000EF648ADB989280F7CE8F58500FFF33D50B
-:10315000654C817E9F2679FE86E59C498AD78872D8
-:10316000F73D1FE985921EF2278D42AE9FEAE5A644
-:10317000F7A51E8371DEC3F12F759CBB43C7F9E42D
-:10318000C78C734D6AC838477FCCBEFE9CCAE12409
-:10319000C791765171BA4BE985FC3A666490BF706D
-:1031A000EEBDCE18F44B31CC7703D0CF5DDA9C91D5
-:1031B00007E3CF7DEEC58C0AB49B84BEAF39A7323E
-:1031C00017C8A3DA730A955FB47D64C47BB335DB9B
-:1031D000DA8CE3A05F2D944501EBAA12EB047DA7E6
-:1031E0009F1CA0A78DBD74426E3CCCF3329E3BA1C8
-:1031F000477CCED5351FFD3DEAEF114AD8F8F2974E
-:10320000627F077BB81F61EEC5E551616F5734EEF1
-:10321000F314063960FCA2FAF0F902BF12EB28158C
-:10322000FA6FFA504B8403E03CE43D1E5FAF589BBD
-:10323000998BFE6263F2E804825B8F7ED62EEE6786
-:103240006DE17ED6527BC702FC4E99BB57EC83F8EA
-:10325000DDB209BF937C062C0BEF8E37C97ABF898C
-:103260006346713F18D6F37E9FF920F2CDDE286EBB
-:10327000CF4E1B36300AE5436766B4CE06FCAC4F32
-:103280002A73F74AC0F6ABC6617BA1C9D2A78CE00E
-:10329000CB882EF449EEFEB84EEC8FFE118FB1357F
-:1032A000E106D887E70D95EE037806457BC2C5CBCE
-:1032B0002FEFC5E5B9BB978DE0B15707EBCCF5AF64
-:1032C00043CE0F76FD820E18EFC8D294C10F38306E
-:1032D0001E53785DAF04FFFCB3923CA302E73FA20C
-:1032E000637DF06871B1EB182EF0711DC2064AF7CC
-:1032F00028A0B780F3DEE431D141F5A9C571CC1522
-:10330000E8BF9D9A1A54BFB1343BA8FFCD33FA07EA
-:103310003D9F68EAC8AF0BB0677BB697BC049F5A65
-:103320008B250AEDBA4F5ABEF9E016B40337AA4E00
-:10333000B45967EFDCF4C148E87506F01B477E49D5
-:1033400007F9D13E9779747A973E307E748A75502A
-:10335000BEA23CD75E6CDC68AEAD9DF2097FAE7854
-:10336000D1BC5EE2FC9BCB72513F9EA97B9FFC7956
-:103370003566BECF532F1EE2DF2D44BD02747F356C
-:10338000BE88F6E23910FCC0FF453B0E519CCD864D
-:10339000C14DB4F7D3E6E9F1FE642D94A85FC68170
-:1033A000DC8A01BAE9686303B761DE48A685DBE51C
-:1033B000E7A690BF7C6F14F7FBEC4D8CA5EF48CCD3
-:1033C0006DB886DA6BCE45D3F86FA91DE3282FFAC6
-:1033D0000585E2131353A72DC5FDEC8DF20EB81D24
-:1033E000E69DF8E7ABC723DC6AB6F17B0213D5771D
-:1033F000F2E74159D5780DBD3F51657B15B01F628D
-:10340000CEDD42E34E441B00EAEA50CB03A89755B9
-:10341000636B9F3FA0BC315A48DED49E8BA4F72635
-:103420001471FDFD7B214F0C9D7C5D63CF4DA2E7A8
-:10343000922E7CBDB282F2F70D091BF5F8BD214337
-:10344000A742FDAF3DD79F4AB9DF37FAFD91BE2FA6
-:103450006048F87A1CE68DBE11AFD8C82CD1C8E3FD
-:10346000B375C362581879D53DCF399E6F6C3AC792
-:10347000F38FFF3BCDF517E4C392459D7A8C17314E
-:1034800073840DE1555230D85111C067EAAE9B8C60
-:10349000881FC3EAB78DA8AF4D5016053CAF16F98B
-:1034A000585A79DD22E483FC8E9BD43F2C7906D1D7
-:1034B000E7AD3641A0828F9E167C2CDFEFA0330E45
-:1034C000E0713BF7F3B7A679DE4239D151C86E7C83
-:1034D0009EE4674706C6697EAEF5039E2314B21BC1
-:1034E0003B29AFBEA4C0A1C3F8C07BDD7A87F3F34C
-:1034F00085F6D126F6FD96CA16E2B86FFDF2971D45
-:103500002E18AFEDEEBC3CD40B72DECF7AF17B0B04
-:10351000CCD6751ECF87B52F473B90EF27E2E10C45
-:10352000E3A23B4D746E81768A77D4BE6C7A0AEF43
-:10353000BBD55AE1FC0AF317BD12D98A74DCF64AEE
-:10354000A41EF5C71DBD3D9F217C8A5EE93B06CFC9
-:103550008BAE16939E91FDE33A4AF2B687F55E482C
-:103560007E69E94CF2A7A781F34B99A0D372C17F82
-:103570001EC14767EB92880FCF2E8245633C759141
-:1035800032701BDA0B0E0B7D974EF2E5443C1F4167
-:10359000FBC4FEB1748FA1EA5C6C101F569FCB1464
-:1035A000FC1D47ED92DFCA059F98847D3143D0B55D
-:1035B000B45B243FB2744F622AEC63623DF0BD9568
-:1035C000E2FEF9C84F7EBA31DA90BE806E922B02CD
-:1035D000F8A7BEED2686768A29DE4D743303CA40ED
-:1035E0003B6566B79D621B9708EB2F5996A9C37B75
-:1035F0009BF2796AEAA5D17F44AAC82730B7E6A032
-:103600005D6BA88B74E27D9A33F13C1E347F058795
-:10361000E37C83BB08ED8CF94F28E43F43FB03E5D3
-:10362000D2D00375C640BFCA4DE706513C7DCAB92A
-:10363000CBA834267B2E4738949DBB5EE06BD08FA1
-:103640008A3F0E7171BF92C167726EC844BF9247C4
-:10365000453C1F4F67B64703E37D6B54F28FC9B8F3
-:10366000A4F43399F0DE4F803EFD46DF9841DFA39E
-:10367000D1FA9D0AB9FE3FB9D140FABFAAED9DA18A
-:103680003A78FE79A62B09F5C97A83A708F733673C
-:10369000B2EF3903D4E73EB8D53ADCE18767B3BE71
-:1036A0003507F56933C011FD5FCD2BD5F13E6EF7BF
-:1036B00044F3381AA76F49CF5A3A9F732E9BE07391
-:1036C000B6CE447AE82CD02D0BD04352EF48392F98
-:1036D000F58FA4EB6A3D975FD5E618CA23F3EB9DFF
-:1036E00049EE42A4BB7E3C1FD0AF779E5A3502F90B
-:1036F000E0743CE55D4BBD21F9E085C5C9944724E4
-:10370000F592E40329CFA57C97742FF5D6E83FFD09
-:10371000EFD6BFC3AF93D23C77A5027D5DABE7FA8E
-:10372000EB5ABD85E8676CFC243DD2CDC5CBD143B7
-:10373000428E1E0A92A3353DE88145A9527E5E1C49
-:103740001FCC117C33DEC4ED4894F381E3B5A68D24
-:103750007E08F7B13A95EBD99F6BDD3DC9FFD5A93E
-:103760009726FF97A45E9CFCFFEF54FE9D0AADBC1C
-:10377000C70F71A3BC3FBDF3721FEA83830CF40330
-:10378000EAC19668C726A10F485F44C5F87E481F66
-:1037900014F69EFEDFA9E1F5C1666CFFB1FA40D2D6
-:1037A00097E41BC927922FB47C24F962C26FE1BC55
-:1037B00088787A8BDF8FAAD67B9B280EE9881E8CAF
-:1037C000FCD96DC76D5388DF42F484E01F3FBF040E
-:1037D000EB0DC91F925F24FF540BFE9829F843F2AA
-:1037E000C56EB5F9D111980A90E6F908E588E49319
-:1037F000AAE7B5FAA147BA424F239B195FC790AE1B
-:10380000AAA10CA42B530FFC70F012F5C2BE8BA41E
-:10381000A7AFFEF3F4F4550FF474E6A7D053A81D38
-:10382000FB61BE03D673361FE46DA69FDE26FC8DBA
-:1038300071FB219B9F07F646F17DEE35A693FF674E
-:10384000C2F73CCF57DA033385BF41D2691ED80196
-:103850006943FCF8C7F3C0BC8B937B8467537C87B8
-:1038600011CF2733A10CB4037AB27F53D32E4DEE80
-:10387000458AFE17C2F380B49FDD6E1C90161EAF02
-:1038800003D37E025E2762A22AF92BB24B5CA3000F
-:103890003F0F89BAB74F09C2F1FA02F9FCB2552EAF
-:1038A0003DCA07D6FDDD75F477BCA5CA7ACEFE31D8
-:1038B000B09E098F32BF1F1D9E8F1D15D3ED1F5166
-:1038C00098BF7F715AD6FE95A4E71B45DE4AA79E96
-:1038D000C783443D1FEA96807A81A6BE96F7B7EA71
-:1038E0003B59603E09D28D92CBF1EC0EB01F60FACD
-:1038F000F6B3A82F6C0A43FF466DFC8657CFA25C37
-:10390000DBA1506CAA1B0EDE810407FA3E38D507F6
-:10391000EF775DC6D8CDDB78FDF6B54356792F132A
-:10392000E306DC1B32342B2ECA4728507C5999A160
-:10393000F0BE3D4DCA13B91E46F71402DE6798AFBC
-:103940007729EF77E74D67D1FBADA64B98FF8651FE
-:10395000E1EF6FAC10FDC6E4C7847DFE709ACAE14A
-:103960002FFC06343F344D690E7F9FFF09C12F1D88
-:10397000183F21784E5A85FEED0EA384B77B15C201
-:103980007B2C63417E34989FEA1BD7BA4B1AF47C98
-:10399000BB2E0DBC7E68BF77A505DB03F49B065FDD
-:1039A000A61F80F7DD61DE7704BFDFFA43F85A1205
-:1039B000F2BEA0DB59928E5D41F41EA377137DC643
-:1039C000C42B36B4A36BDC912BF1BCE0E7CFD21251
-:1039D000829B8C1384F0DFB4923103C84E12CF6FF8
-:1039E0005B85FCEBD675F7E7FC28E91AAF36015C7E
-:1039F000C9F507EFBF9C76EB2AF44F025DD073AA9E
-:103A0000EB03D6ADE5C7664D7D94867F05FF91FC3F
-:103A1000407D0070CA41F9167FC8E808A0934F04A2
-:103A20009C4E897CF28ED1DC9EECC8E2E577693C45
-:103A30002EF599A0CB53929EA202E09016443FF43B
-:103A4000F72102F64D70BA295EF2F3BD25C5C0BF5D
-:103A50001D76FEFC7FD6FE669537CD5FD78EF7CFFD
-:103A6000B5F796205CBAC7F72EDA8F76C44D026E92
-:103A7000DFADBD67BF7780C073A2FFBBAB401FF453
-:103A80003D9E6AA40F25943E5E0DA52FAFE67DFAFC
-:103A90003B043DBDFFB75079E0D2BCCFF07B10179F
-:103AA000FFBEC05BB106AFE335781DA3A997CABAC4
-:103AB0002F48FE4AB95CBEE3E1FB12E3D1AFA9D0C7
-:103AC00075243F3D3F48F43CD726E97715C1D54FD3
-:103AD000CF0FED47FA9DDC2CE9B591F4CF2494C3C8
-:103AE00023FCF5292887A8FE7009C6C5FCFAEA91CF
-:103AF0005528B76F6890FD1FA5FE372F93E3ADA63D
-:103B0000E7128F8C3D46FAEEA67CA9AF1E27B93F7F
-:103B1000A785BFEF4CFFDDFE1FE487460D5CD66A2C
-:103B2000EA5E4DFFD517D06FCB34EF2FD23C5FA9A3
-:103B3000A9AFD1D41B82DF2F9BA1101F9615F0389F
-:103B4000A5962FB5F4E14AEFB673BAF5B96226FB34
-:103B50002E88AF26D4F3FAB5E91B4B1ACC01F575C4
-:103B60009B4A385FC06C01F79F41E67A55A0074336
-:103B70000F72B320BD07B9D94FABEFF9F37FE0AFB8
-:103B80002914370AB24B76ABC1F53655ACDBBB75A1
-:103B9000FF820181F1D5E74BF05CDD631CC7DB5C84
-:103BA0003226D02E62CD25AE807DCAFEE3BEFB5EFE
-:103BB000C5F93CEBFE5CB2D18C714F11DFB4F3124E
-:103BC000F4A58AFABA56F86FC6611E2FC693A25A98
-:103BD00073E60F08D8276BEE83FB6CBB5BE5DFB7A2
-:103BE000AB07FC009CCA9883F250A73317E5A5B633
-:103BF000C5C42CFC2F786FF7DDEA42D4D30717C673
-:103C0000515ED32BE9FC7CB13BA677E24CA8B745CB
-:103C1000DF46F2B6EDFEB154EE525DCBBB6C8C2D9F
-:103C20005EF74A89F9727C1E4370BA3BFDA5922566
-:103C300040EFF7A63BE87D8FDD96B803EDED070C6E
-:103C40001437040E7892E8E741D3603C6F972DE972
-:103C50004F71B1F2C7268DC37BA4E5F719285ED258
-:103C6000A9B3919FC8F3C058CA939AB14C94DEABE4
-:103C7000A97CE5DF7FACC77BA65DEB14FA4ECD5582
-:103C80005F37FF6D10D42B1BB2E97EC6CBE774946F
-:103C900017FEE99ABE3ECC533E1C5947F9A5D09F6A
-:103CA000EEBB569E77EC2FC9C7FEAA0D53388E4245
-:103CB0003BDACF4757A84FE13DCE32AB250AF3BBE5
-:103CC0008F7EC7C8AF73F43E137DEFE653B3E7D6DC
-:103CD00035F1748F092D7D765471581580C3DAF44F
-:103CE000FD25C929D86E12F8DC6F2D033E2FD37540
-:103CF000D30FE9938A585E5FBBEECD924DB08FA390
-:103D00004FF4A57CB1840CD7BA7480D7E10CD7935B
-:103D1000548AFBD9AFFC9BC7255F3A599E88F4B5FE
-:103D200059D0F5CBE7CA1303FF6E41C5293DD1C178
-:103D30002B46C702FAEE6954BA82E76CA08338F4C6
-:103D40009BCF10E716A0E7855BC3D8574BD3B93D8F
-:103D5000D6F6DB84518E20BAFE98E4299D37A0FE6A
-:103D600062FA47A4E78E9816622E75773E24DB1D13
-:103D70004970323445FA2233D17FEA1AE7A2F34F71
-:103D8000739FC996003E14FD3FF1F2FCDF4FA03F48
-:103D90009EFB3EF1FE3F4B603C43F6AFB45ABC681D
-:103DA0005C1CB358F4888F83FAC547313FAD629DE0
-:103DB00081F440C5BA84455D287F806ED0BFA6DD02
-:103DC0009729C3C0FD183DC6573F2F199316785E3B
-:103DD0003941F2BB27BE7C37FD44C9C6013DF365BE
-:103DE000A58DCBA771EBF8F7752B8758F474BF7BC3
-:103DF000DDAB9BE81EF0BCC85CBC5751B9CE44F8A3
-:103E0000EAB458BCB62BF1BE81451F0BE5A174AED8
-:103E10004FF5190EC24791CAF411B954D23D0A198F
-:103E20003F3CB1F0D1C7311DF373E6BB7E18C0EF44
-:103E30008C8BD3E9996D2AF91FB5F1C4EAD7B71A6B
-:103E40000BD98F8827F61047AC629DE2BBE2E1E315
-:103E500089DA38E2BFD2C5BDB3EE38A281BE875140
-:103E600029E288456B155A7FE542FEBD92A238EEE5
-:103E70003F3EB218E8A02FEDDF6BCBC53C69AE7FAB
-:103E80002A99E28B805FAF5E3B8FFC9975E91C5EDF
-:103E900065E23BB087239D1978DEAF58174970AEB5
-:103EA0007C72F6074FE4E37DC089F181E76B9BA04C
-:103EB0000F189FE13D6839CEB125F7D077678BD6D3
-:103EC000C33919F3B463D973376522DE523230DE59
-:103ED00029FB552EBDBB0FEF07E76CD877D90A95A4
-:103EE0007F0F6BBB89F421F07C320BB82F3E63D976
-:103EF000EB4623D7672C79A8B0B31DFEFB6C9FC29D
-:103F000073FC0441ADB8B726E127EF5B95E9F8F7FC
-:103F1000364B750ADDC3028946F7977E91C1FDA332
-:103F20007919DCCE2DCB70D23D9EEA5526E7D24CD6
-:103F30003E4EF7BD7538E755EB3A2A28AEF9171310
-:103F4000F9576A9745BA22AD3C1FE3F9019477AD62
-:103F500037023CAA1C5C6EFC42D063AD63D2D594A0
-:103F60009FAE6707F0EF07565BB89CAC8E05B89B19
-:103F70003901E986E2F73919E553E2B8298302E607
-:103F800057443B8CE3B0FAC7DDAB630DE8A7C1FE35
-:103F9000970F4238C65D7F23AEEF5995F81A80B46B
-:103FA000AA00EDBF67D53C3C7797ADD83D0EE5F054
-:103FB000DC2D83F146052B7BEE5DD2237305FE3BA2
-:103FC000453E5A39D4F1BB81376470B9E951B9DF44
-:103FD000E806012F4907F279F50A03F7E383BC47A6
-:103FE0000153BDE4431AB7DAD2918872B87ABB8123
-:103FF000EE87DF8CEB0638972F491F7500E8AADCA7
-:104000001043DF51ADF24E3462BDAA51A1BAFFBDDB
-:10401000840CA4D32F96BD6045FA391CD99A83FA33
-:10402000A96B5EA493EE29DAB8DFEE8B653974AF25
-:104030006986ADC382DF6599B120DB8E72FCA0ADCD
-:10404000D588CF0F3667EAB0EEB2D94661DDA5BF9D
-:1040500092EA5F887C17FA41BA52389EAB9A761B77
-:10406000F1EF2FDD2BE8E2D4B3EFF6413F50754678
-:10407000471FD42F40077D5211CECF28A49F6B9AA3
-:10408000781EBCA4831AA403E0BB39820E6AB6BDB5
-:104090007017F2430DE23F37948E809EDBA9FDF945
-:1040A0000DE3187FBF1DE944EA33A82F33A03FCEAC
-:1040B000C8EB8B05FEA17D0C6FF70EE0F975DDF9FD
-:1040C00008417CD0137ED766E8043E4C2477D78A1B
-:1040D000FD76AED86E45FC9D7A76F71E8CB7543FC0
-:1040E0000FDADA11861F043C6A71FF565A3FD9195C
-:1040F000B5B85FAB7FFFDD742FF8B096F1FDC9FD59
-:10410000D6EAC5FEE573F1FE3AB1CF2A26E0B5AD99
-:104110002FE73BC167C8C7F4DD21B13F8F3DF8BB36
-:10412000BABBC5FE9A44C96CCD56840FE217E50FA1
-:10413000D08FCB28E5097439B56503E5F74B7CC909
-:10414000F5BFEFD72B2EFC9354128F9D3D7CF7B615
-:1041500045F0C9A1FB92327600FCBED84C9F0D24DD
-:104160007AD507CC27E946CE57F4A749D7E2BE61F6
-:10417000FC561C5FCE7BD01BADC7710E32CE1F72BA
-:10418000FD922F8BEAA75D3BD88AFD4E59B2D15ED6
-:1041900011787C3FC346EFBBD06E80F75D3B14F2D5
-:1041A0005F1F12E7FD43F7BD602D1FE0A7F777C53E
-:1041B000BA259DE10FFAC9E47AF7DAB93F58BB6E28
-:1041C0002987E4BA8BEEBFE15A6C97EBC7F8512010
-:1041D0009D4A384A7A95F7FAB4744B3427F5AADA2F
-:1041E000337DD7A61DA2FC9D9076ED78C23E3A2C79
-:1041F000F2CDBB9E56F97DE765C9ED41F78E1833C8
-:1042000007EA9F25F3AEB615623CB749A17B1E5263
-:10421000AFC0CF4A7D803E92F6C1F0DE3C7FA5362E
-:10422000DE7502F15975BC631C7E9244DAA5577D98
-:10423000DDAAC6A0FF6A1BCF8393745375B29DF8A5
-:10424000A15ADC932A5BF1EEC46148F74F1B28CEDC
-:104250005376DF5823DAFBB3374D1F8AE0C07B1259
-:1042600028DF4F6C1C9247E061B6C4EBF1BEC4C6B8
-:1042700047AFC7BF5F3A63874ADFA1C171908FCB59
-:10428000EEC8237FEBE1C8CE8923D0AEFFB56A43E9
-:10429000BB7EE4A6218BB0FF484BEF58FA78D0C61E
-:1042A00038AABBF431A427A41D2CF303EBC5BD90A1
-:1042B000ECDE9CAF7A75978AC80BACEF83F1F9AE50
-:1042C0000D91F4DDA852A3A3B915E7DB9944E78E5D
-:1042D0005A382625DBE99E2BD969B38C2C222597E9
-:1042E000DA233045F97543C71DA84F5EBFC33218A6
-:1042F000BF8BCBD4F343CBB97DCDE39071C1DF61EC
-:1043000092EBC8EACDE9573B9E7C7F2F9E2BEC7445
-:104310009F91DE3FB1ECE9EB511F9ED89C63C77DB6
-:104320001FDB1949F70B8E1982BFE778A9F7C2B4D2
-:10433000F7A9E43DD7FCDEC1F69CA4FB0BDECBB9AC
-:10434000ECD2F2984E2E66744FFC5C06E3FEE4E875
-:10435000EFB6627E6145A3C986F7648E20FD637C5B
-:104360006BBB4ADF01A2BBDF80AF23DBF3E83E700B
-:10437000C5C7BC5ED1ACF8F0FE72FBC3F753FEC2FA
-:104380004CB037F16A79B73DBDFAE1EB910DCE380B
-:104390003DCBF13B006736F37C8B90EF3ABCBE75AA
-:1043A0004F8AE3FFBFFD2CFD13D37B07DF4793F05C
-:1043B00096E7AA57802E0A72FDF0FB72F12CB29F8D
-:1043C0004F2EF650795A39B46A24D2B32586EE15A9
-:1043D000BCB4E35115BF7353BD6DF0793C1F8F30F2
-:1043E000C7D0F79FBE5CBC90829A2717D7893F8AB7
-:1043F000B654F8157C545EB5AD8DDEFB72475E0B8E
-:10440000DEEB7DD91CC3C59AAB20E83B9912BF3DBA
-:10441000DD5796FBFAFCD71CCF72DD9F6F9E6EC5F1
-:104420007DB5FD21AE6538E2373AC6867660A5C80F
-:104430002F39BA86DBD9C72362FEAB18F07C7CED3E
-:104440009444FC0ED1CCB6A9D7637BC54EC586E794
-:1044500003E7CE49563CCF7DA6EFB4E23DAACFD6C6
-:10446000C8FB573EFABB7B23C6B329D87F44AB9E1B
-:10447000393229844CF432FCA49EEECB7E01EDE46B
-:104480003F391F45FE13F889C37C92992F72BF4BA9
-:10449000F7F9579CFF468A7DB7F7B6CBF806B517F4
-:1044A00015F0F6636BB796D0DF4FDE68B0E1BABFA8
-:1044B000DC68A0F1E7C0B94D07EB3DBE999F83B022
-:1044C0008EE7E8139BF979674E333FEF54CF33B84B
-:1044D000F8FDD260BA2C0AE847DF2DEBE1BB23736D
-:1044E0005C7C7F73407FE27E2F44BFB1AC99EE9F2E
-:1044F0005D6A3EA9967EFFAA9117DD74DB13BD08A5
-:10450000B822FF23DD4ABA98B386C7F5EDCD830BF9
-:1045100091FE249D68BF03586F64FC3BB2BA28FA31
-:10452000EEF724B3C380FA624A7CE718044F5F07B2
-:1045300097AF6A91CE85F7E458BD29EC77C4DE15B4
-:10454000F2781ABC4BF7BB7ADBF8F7CFC47D315950
-:1045500082BE4A477D3E29DAFE8D03BA74AEFFF271
-:104560003A3DD0F5A491F63BB29D80D7F55FF37A42
-:104570009E7D7B16D43FEF7DF63A3DEC6FD295F6EB
-:104580002106A82F59F2CD7563E0B9C9E13AD83BAD
-:10459000609E139B92D2717FD07E08DBA7277A8E14
-:1045A00060592BEE8F9D56BA062DCCF4F77F7BA772
-:1045B000E5E04B0E7FBDD3C0E8BB3BA77BCBF587C7
-:1045C0002F9D0ED7A9DE09A1EDE58CDD47F97C5EB4
-:1045D0007E6F077EDC118978AF8AD35DB9BCC7D303
-:1045E000A0B9C7E3E4F7D5E4FD2A797FEA72FFFDBD
-:1045F000B3B59772FFECFF0069F3B24F0080000083
-:10460000000000001F8B08000000000000FFE57D97
-:104610000B74545596E8B955B73E492A4925845438
-:1046200025A984AA7C2B90C0257C0C3148E5030485
-:104630008858286AD4A005A2808214011D74F455FC
-:1046400061307C9AE98E9F1722462D10957178DD96
-:10465000D1B16D868F532032FC9A0EB463EB8CD3AC
-:104660001DD0D168631B3138F40C366FEF7DCE4D11
-:10467000EA562A80BEE77B6FAD975EF6619F73EEC8
-:10468000F9ECB3FF67DF5B5F192CEBA564C6240F61
-:1046900063AB53A1745A596319947BFFE9CFD26875
-:1046A000C69A83AC3B2E8FC15FA3F5D35150CF7C0C
-:1046B000BA4B502E4B481ACDC660991362D06F99F1
-:1046C00089B1AE12E8263B6DCCC2D81209FE9D011D
-:1046D000FFF9CA194B676C9515FEED44B84287F097
-:1046E0008366467F9F05983FDFC0D81F4F742539EA
-:1046F000F58C9D9D1D2E0CBB18FB65BCCFE69C0068
-:10470000ED1DCD8EA634C6BE7CC3A4D443FF9ED07F
-:10471000DF27F960FCA57AE6EF84926D1FCED824DE
-:10472000282FEAC353A0DF6157F1B68DF0BCCBA9A7
-:10473000630C9E3FEB0AE7FCF578C6822E93F232BB
-:10474000A37E773280EB1E9F3E1CFB9D7D7D5DFE30
-:104750003DB06E93CC5812EC7B068C590E7830002D
-:10476000AC2FC30742340EB40793A0BEC5F5740E38
-:10477000237C302F9BC8D80D8CEFEB0639BC1FF182
-:10478000C5946419F7379B6F0FDB83328CA33333E7
-:1047900003AEBB9875583F4D0098B18E4BC3607FF8
-:1047A00066C063329680C724C6A6EAA113ACAFE9FF
-:1047B00097FA9009D6D784781470D085237A2CD7AD
-:1047C000C3F88BC5BCCB8EBC6BC4C15810FE07EBC5
-:1047D0005922E65DDC71773D9ECB9290E14CB7C0EB
-:1047E000F525FA7F0F9DC772D1EFFEF2AD469CE230
-:1047F000FE1DDA7ECBD9A6AFF5F0FC52D66DC4FD16
-:104800002EEB8C6AEFA8F90CD7BB7C97B6BEDE996D
-:10481000988674C2C6B2B197F4544DE7BD48F49976
-:10482000AA6F74CAB89FE166C50413373D9F47F469
-:10483000C2DE0CB0C87EAC6318D14F8B4B4FE7B1D2
-:104840006497C49CE318BB7E5716734253FDAE6158
-:1048500054265DC8A0FACF5F3936DE5732705ED776
-:10486000BF6AABC6F55DFF6A1195EA3A9A041D4E20
-:10487000D5977486611DE72CB00E809B8EC0628137
-:104880007E9A6ED68718E19999B1BF572CC76B599C
-:10489000DFA54F42580E8AFD4A97243A84643C1F94
-:1048A000EF613D437A621E03B53B9979CDA55CA0CB
-:1048B0001BBB8E3963E0DF24CE2FCE19CF9CEE8157
-:1048C000763958FCB34A588761AE4109417B735C25
-:1048D000D236E43316F474E5C3730DE2B9AE384E44
-:1048E0003709EE54CDF32A1DDC2AFAAD4B9A76181F
-:1048F000E9B2C1B388E82151C9D4ACC7A45F6A400A
-:10490000FAB9D567F8A43B621CA25F58C70D5E29AF
-:1049100084FC787383B6DD50F975AD4425D4478E99
-:10492000E7D5F6FB29D203D03B107E71243D0C9CC9
-:1049300083C5A3C373F02412BDCBCCB9B912E05B1D
-:104940000E1B18EEDF14CFF7790E319786FD800F1E
-:1049500060E2758817A84F2ED7E237C5A3C5E7B028
-:104960003A2D7E867BB5FBB735E46ADA337C233596
-:10497000ED598BCB3470B6BF42D37FC4EA6A0DECDD
-:104980000ACED4F4CF5B7FA3062E68BD5DD3BFA84B
-:104990007D81A6BD38749FA67DD48E260D5CDAF984
-:1049A00088A6FF985D8F6BDAC786376ADAC71D7EE7
-:1049B0004A034FE8DAA2E97FCD07DB34ED93BA5F13
-:1049C000D3B45FDBF386069EDCBB5BD37FCA850373
-:1049D0001AB88A1DD3F4AF31FF56034FB5FEABA60C
-:1049E000FF74FBC79AF619CE3F6ADA67B9BFD1D216
-:1049F0006B3C9793D72BFFA579EE5993EFDF505F70
-:104A0000344B95DD4186F4EB243EBA354DA7840145
-:104A1000FE832A97041D9E1C612539C1F2598EB769
-:104A200014E9B0328C7C7C6E9744F2E0AB28BD2850
-:104A3000FFD1EB91A09DFD4A525E7622DD415DC41F
-:104A4000FC291E339323D639ACCEAA81877BED9AFD
-:104A5000FEB606A7A63DC3E7D6B4672D563470B69A
-:104A6000BF5CD37FC46A8F067605EB34FDF3D67B3B
-:104A70003570416B83A67F51BB4FD35E1C5AAC6926
-:104A80001FB5C3AF814B3B576BFA8FD915D4B48F89
-:104A90000DAFD7B48F3BDCAA812774B56BFA5FF3F7
-:104AA0004148D33EA97B87A6FDDA9E4E0D3CB977DF
-:104AB00097A6FF940B610D5CC58E68FAD7984F6A74
-:104AC000E0A9D60F35FDA7DB4F6BDA67383FD7B4C7
-:104AD000AB76D02CF7D7DA7A61175DAFFC59F37C4F
-:104AE000B0DAC3903E826F484AB313D6EB02E13F7F
-:104AF0009CE47C779C1EED282F18148C0129AD4175
-:104B0000FD920C420CE90A488C35A6E22840AC2004
-:104B1000B74955C1F3C9684F0090AA73B9FCA01FEB
-:104B200013D85AEBA766B21B1C9740DF5DC2BF29A2
-:104B3000834B94A09FAAEB85F966A14E023A6F724F
-:104B4000F93C2E58CF7D9DAF4FCB626827045B7038
-:104B50001DA00793BB416F9E886377794B068F3703
-:104B6000C30C788998EF485CABA3CC32F4FC33CC0F
-:104B700067A97FFFB8063EAE04FB6B8A18FFA7A0AB
-:104B8000EE65B0FB5A03C037058C3D15B012FC4CE6
-:104B9000C04E705BC049657BC04DE5968042ED1DFF
-:104BA0008172825F0878080E05EAA8DC16F052FDD3
-:104BB000F64003C1AF047C54EE082CA6F2B5809FEA
-:104BC000DA77065613FCF34090CACEC07AAA7F2348
-:104BD000D04AF09B817682DF0A84A8DC15D841E5B3
-:104BE000EE4027B5EF0DEC22F8ED4098E070E03094
-:104BF000C107025D041F0C7C40F0A140379587037C
-:104C00003D541E0DF452FBF1C0058207CE4B6B578D
-:104C10003361572E1274C0D2B83D792F3F52F685BA
-:104C20008E2D46BB7791A04343359887407786CC3D
-:104C3000C26DCD2E3C6AA01337D1C971B42FAF9687
-:104C40004ED070407A0D563337D29B5AB654E9C9CC
-:104C5000FE0CAE90422F73BB88EB6F3353F537B524
-:104C6000373E2885D09E9B0776B211F8E623619FD8
-:104C70007C14C7E5F539BFC18D765FA314AFC0665C
-:104C800001FE77B23BE02F8CA47FD75ED356B49F52
-:104C9000D4F535C2383A18E7BFEC2E5A57233B6C8F
-:104CA000C0F540BD470FFC72C6E6DBE202BABE2F7C
-:104CB0005B17342213594285DE44C68C76DFF348F5
-:104CC000E7E7FCF71CC2C1175995429CE77A537875
-:104CD000F8AD307FEF11BDB2CD39345E96B7CE005E
-:104CE000E17D99F6B73F77A01D5FF717BD0FCFE1C4
-:104CF0008421B1210474DDE99288CF3A5D3A4DD91F
-:104D000066F7FD02D7F96DA2FF4E1DA0F2DBEB5650
-:104D1000BCB212B6D4B8A22019ED55F00F0C685FE2
-:104D2000CF614E03CA879B98E75D1CEA66E623F8CD
-:104D30005616A452B6F976E1BE6E6321827D15A6A1
-:104D40009C58FB8A5ED73B38D8702C759AF290DD60
-:104D50007700C7FB36D143EB3A31697A21EE4B5DE0
-:104D60009739C349FD66B3DE17707DDFEEFBFA535A
-:104D7000296F309DFC88F4618169B03F33C2793777
-:104D800003EFE038CD0F4B21A473953E1AC14CA719
-:104D9000F11F857A29925E804ED07F4BEBCD99939F
-:104DA00048F4D24DF26F923E68047BFA842E542868
-:104DB000E9894E8C12AC73511AD049EED0F4F0C090
-:104DC0007A2823E420D0D91738DE9FFEE11A37E293
-:104DD0006DF9DB939C88B7661D9C07D073F0A89E85
-:104DE000EC042644BBFEDAD210F907B2A2CC29C5E6
-:104DF00073E37271BF9EAD7E3D86DC4DC8E5F474F1
-:104E0000C26EA80BD1B89CEFD5767D2E3F477D2E84
-:104E10003FDFA6159F2DD5C3FA4F1CF8DCE82C8D7B
-:104E2000B18FD53F79283F82AE97EF3A3DCD837E53
-:104E300017EB2EB93171A0BE50CCABD291DE98E801
-:104E4000DB6A895C573F5DC7E7225DA7005DE7111C
-:104E50005D7F8A76F96C9333F95628BB013561285A
-:104E60007D2F5AC97F5CC0142A17322F958B800C76
-:104E7000908EBDC1278D88F7FB5827D53F507E7790
-:104E80003AD2F5BD3A1FF9D94B5917D52F67BDB5A1
-:104E900078B437AF5FF3AE1D567D53EB9353914417
-:104EA0006F0CCD7F17CB39DBA54F834EE293EC5CC3
-:104EB000C047B7E47F2213E6BF7D67D51359503F43
-:104EC0005BCFCF851DE3E7A2CA91E87D035F14E0C5
-:104ED000F3DFA678685FFAA43A0D5F343ECE3C1249
-:104EE0008CD3BBCF14DAE68AE093F2FBFF9085F215
-:104EF0004CEEBD13CF7BF9DBA6543CEFFB18D7FB80
-:104F000092478DAFA8FA9E11BDDFCFE215ECF78571
-:104F1000A0EF2FB219D1F71712388A65037628CB84
-:104F2000F1D9CBF206F4F672DDCED18827D0EB951D
-:104F3000780EF77DDCD932D685FA2094837688E125
-:104F40003593D2ECD2E817762901858D9F213E7FDB
-:104F50008AE38E19BC2EA9FCD09FD1EE301959D00E
-:104F60005C467CCE26227F671A89BF9A11B57938B4
-:104F70008FD7E9B70C1EFF8458EFE1EFB83F1D84CF
-:104F8000FDBC2CC59A87EB2F53FCC03C2447D2199B
-:104F9000CD73472EE763753E66E976A09D7E34C1EA
-:104FA000773B9E8F1A4752FDC8C3AECFF2F17C66A5
-:104FB000576C50E5338DC7AEE372E984C11944F8EC
-:104FC00044954B0109D62F6F6F28FFA70F701D372F
-:104FD000982D618C77B04AC3D97EFF3577401FDFAB
-:104FE000A0EAE3CAA8F88E1AF7618A01D757CC3E27
-:104FF00052F141F11D554E0ED2BFB0B12EC49F8863
-:1050000097F5C779FEB93FCEA3C3798D428E32E6BC
-:10501000777B23F8D4D600AE8BC67F30B37C8DFF70
-:1050200060D5C0D97EBBA6FF88D54E4DBB2BE8D638
-:10503000B4E7AD573470416BB9A67F51BB47031736
-:1050400087EA34FD47EDF06AE0D2CE064DFF31BB72
-:105050007C9AF6B1E1C59AF67187FD1A7842D76A53
-:105060004DFF6B3E086ADA2775AFD7B45FDBD3AA72
-:105070008127F7B66BFA4FB910D2B457B1BFD5B488
-:10508000D7985FD7C02FC6F178E754EB3F689E9B57
-:105090006EDFAF815F88E7F19A19CE23DAE7C5F9B1
-:1050A000066F8B277E98E53EA969DFFFC8C8CD8DC6
-:1050B000C02FA14774E47FB6D5713DC51AAA391D2A
-:1050C000C4F1BED72B1F6AE6CBD1F7BA908E9D7A7A
-:1050D0006B26F2757EF99C034076ACD0B3A21AC55C
-:1050E0009DBBEEC903588EF4BE5E8D6C53D270F238
-:1050F0000096A37D5F570319336571CA3B5896F933
-:10510000C7D6D87089ABE7BC83E5C4E08A1A94B3EC
-:1051100060267EB108D67D3E38926D84752565AADD
-:10512000715E0FD1EDAA0C1DF1F9AADB2C14374BDF
-:10513000BFD622A33EDF1CE81A7910ECDCF4A7D31B
-:10514000D762DC693DD8F9A122B017C0EEC7F25989
-:10515000B0EB43E01C6D04BB1FCB4D60F763FD73E8
-:1051600060F7239CFE74D97A7C6ED5C97BEA7261A4
-:10517000FC110FCA563453D739752B0EC07AEC0F79
-:105180001AAD284B8CAE67E29CB08EEC65B08E0AEF
-:10519000428B0751FDEC52301C32391C07FDEC2BC1
-:1051A000741AB81DFF45B02E588BCF973EE9DEAE7E
-:1051B00030F6F9B6B337198A619F795DB76D4D0145
-:1051C000389779E602BED3F12C60FC93798FCD0934
-:1051D000960C8697147AFF487249EE2C463EB51617
-:1051E0007D9481EBDA50FD85A2B3E23C8FCC390887
-:1051F000EB7E7E78BC58E72373AAF2AF665CCF796A
-:1052000094EF50EFEF8C2147FE53E8FF93795C2F2A
-:10521000C39F15E5938D9308B3819D940CF276F3AB
-:10522000A4D5A7D1A790AD4109E523BB08CF4F1462
-:1052300028C823784AFC441EB247795354E433E724
-:10524000C178361FD84E91F1B1C55A78339CE71911
-:10525000C3C07A0C77E98232ECC1F0925751609E5C
-:105260008E79B05F80371BB5FE65918E917D719F01
-:10527000BAEE8B372968A7DD97C7F5F09680BBECAF
-:105280001303FA7F4AD9274047998BFD920FE4AB6D
-:10529000ADD1AB04A19FE1D2DFEF372261DFC53A88
-:1052A000519F63FD9A08BB27478C6BB8A427BC1994
-:1052B0009ABD4A6AC4FC06BDE4EF8C617795E6C9E5
-:1052C000FCB96646ED86771E969C305F666348BAE9
-:1052D00087C6F14B0AD4DBC2BC3EABB1535A08F0CF
-:1052E0001D794E3A07759CACC5B0FE083CD9E5A0C7
-:1052F0006485E7ED8F0625C483DDEA555822E2DA9E
-:105300004BFCBD52F0B47DF5C4B24F86E1BABD8A04
-:1053100017E79BA5F29BDFCA703D1F2BBFA942BDBB
-:10532000F61B3DC3FB8C6F9C4A725A8C7DA8A5A9C5
-:105330005BCF3C97F16792721EF1939EBCDDE22C2D
-:1053400000FE7DF1364BC3D6187476471EA7B375A1
-:1053500099AADEE2EB49D7733CA9FAEA1B2BA71FF7
-:10536000556EAD4CE1B03ACECAECF12437865A8F77
-:10537000AD3D8EF922D6BB19E6B1E2FDCC772BAC60
-:105380008837F021BC349FCCE5E9D6E7DDE4374629
-:10539000D3CF203E00D19B5C8674D91D6A06BA31FA
-:1053A000CD332A682FDAFE5B8B84722493B54A28AA
-:1053B000476DD9B58765D4E7B2AFD81BC38EBE128F
-:1053C0003FA8E7A9DA2583CFCFF9BB2AB2430D0C5A
-:1053D000E9B6C9E5B4E1F9A974DA746478AA2FE2F0
-:1053E0003CD70B3A2E67AD7AE4D30AD6496525EB54
-:1053F000A2F23AD64BA58759652CAB9942652DF39D
-:1054000052398DF9A9AC63AD54CE649D54D6B32EF8
-:105410002AC1BFA3D2CBACE487DE08760C96739981
-:1054200097CA5B989FCA2D48DF13F0FEA195E0DB79
-:10543000592795BB80FF9D45181F3153B917E43993
-:10544000966F833CC7320CF2DC69C2F8889BCA8332
-:105450000185CA4381722A0F073CD4EF68A08ECA27
-:10546000E3012F9527020D5476057CD4EF5460316B
-:1054700095EF05FC54BE1F584DE507812095FF129E
-:10548000584F659111E40AE2DBDD3D16FD9A9C8FD1
-:105490008D1E27E8A34FF384FFEBD1FDF7E2F178EF
-:1054A0008E3ABA83B1D5AE94901E6D6E9D2704E5F9
-:1054B000467793743794EB4E703BD6644B243BD9BC
-:1054C000D6BE4A72C2B8BBA46E7D029CEDDEBC0F94
-:1054D000E798414F54ED656B1314847FFFA419E8DE
-:1054E00070ABC1DFBB15DA7FF5D2BFCE3183CEAE54
-:1054F000483CF5C7D7384CED930EB2662BC007F287
-:105500004E3F9926F175A0103EFED2C773D6E4E354
-:105510003AB91C79D5058E36FA190F5BC8CF18DB5E
-:105520007E66AC0EE049AB2D65E81F47F4A3B8F5E5
-:1055300050FDA2DBD5E73A56A437231ED67D0AEEEE
-:105540008913E565F7588CCF458EABBBBAF999FE48
-:1055500032F347F6932E335E5191E754DEFF037426
-:105560001E4DDF864B1FBFAEA3F8983515F5FAF632
-:10557000142E777AB3E343DB60DDDB5305BC219F58
-:10558000F6B50E61D8D7BA8DB964C76F8FF3361DE3
-:10559000C1F6BFD129DBA0697BBC6F6331C1F914AF
-:1055A000AF5997EA77A35ECA49E0FAB1CDF1489CBA
-:1055B0003382FFFF22E4EEE6CABEAEADE84FADD7C0
-:1055C000B102786EDBFA051BDC30CE4B9BC02E029D
-:1055D0003879F2C20D05D09EBB4137512F641EAE03
-:1055E000E3A54D0B5FD928E1B823530B61DC3C21C7
-:1055F0003F7386758F5D0974DE66D4C615FAF56350
-:105600003EE7978530CC19D0BF39225EB1D5C01A9C
-:1056100022F566413E97B73545BC344CE1F13CD3A9
-:1056200088F8D0E3B0FFAA113CFE93BED64CF19FA0
-:1056300074C77F9E9C0EEDE91D3A054D5AD9B6748C
-:105640008D01FD9EDB5827F2E356893F1FCCE6769D
-:1056500032182CB97322FC1EB037CAF223E2A7F627
-:1056600086A084718CAA114B258C37A73BEE933012
-:10567000FE91DEE0937C89E827F9A9FDAE229F2BFD
-:105680001FD6676F84E735F7B1BE0C3C5798B781DA
-:10569000F20964561639DFEC228E872764203DB468
-:1056A000DFD71A695DD1F89AE5AE1E993F7CE01C00
-:1056B000A3DBBFCCE7E7B8FD719802F960128F1F3A
-:1056C0009C783993ECE5D96DF11EF4234F3C39B247
-:1056D00096E0A72A3C68FF9E78B9621A96B39F9A13
-:1056E00049FD4E48EC30C605663F75BB8CF53979EF
-:1056F000B02E1CEFB491E871F653F789E71FA9C5E6
-:10570000F6725DF0EFD09F2E6F7E2D01E3051589B7
-:105710006F64617942D7BD6A3FCC7F8395FD1AD50E
-:10572000B57743DADFD4C13FE63C996BC0788C375C
-:105730003F97CEF326E631F07C072FF9B7953BBAB9
-:10574000DE018B8E5DD7D95B83D7BA9E5DD6835839
-:1057500056871534A359ED61EF412CA775F96BD12C
-:10576000BCA9FBA0F52096DD237D5EC4FFABFFED59
-:1057700096375E0578C463ABAC6887E63FDE3D6371
-:105780001BC52F0D0CF9A16092BF558F046CF6A6B6
-:10579000A27C78F6195987FADDE46A8D43D8744FF4
-:1057A000AE0EE34CDB535A17D3BE0BE219E2F128DD
-:1057B000E821A48B82146F2AF213F0259DC39D82E9
-:1057C0003E4D297E6B0AD68B7B8EFE7EF11C5ED809
-:1057D000DFAF354EA27952A5A0C4CD08B423EC4268
-:1057E0009FB7337F06E2C396E8DF8AF1AD822ACE07
-:1057F000FF2C91D305766F99488F50103EBDD53F51
-:105800000BCFC1E6EBCF1BE074076AB0DF3EC925C2
-:1058100098EE7F364B1C063943EBC23F8CE7A45B06
-:10582000D2C9CE51D76F6B80F122EC0EDCC78D96BA
-:1058300081E754BADB20F6F584280BE6F3F1D4F5C2
-:105840006ECCE77A1DD6EDD4E17AF4623DB00F5DFF
-:10585000C47A22FAD1FEFAD7CD143BD205637E89F1
-:1058600097CC2947EE7FA1CE13371AD7FFD65F61B9
-:105870005C2909E508ACF367FB2799914FA3F7F181
-:1058800042BE88FB80BD8CFEC34C1FE7DFE646BFEF
-:1058900084FE940D61DCBF43F6605CD46669920CB3
-:1058A00011FBB539B89E9ED9E8DF8F7265667982A3
-:1058B00082F43D8B75AEB572FE3E980FEB2B62FD08
-:1058C0007F163671C04E7CFE99F74EE2913A5867CA
-:1058D0005531EACFC7EEA5BC89CD8FCC3C8CEBCF40
-:1058E000743FB93F1506F47E2DCE7D3E8F6F6577F0
-:1058F000C89ABC872CBFACC98BC858AC6D077AD08E
-:10590000C02A5DD9A5D529A86F7409253367A09D44
-:1059100092A423F90E724A9A1BD31E8DA22B817F6B
-:10592000F57CDECDCFA773B359F839B05EC57C7373
-:10593000A2D8AC7A4E306F33B07932D07D73AD3EA1
-:1059400024A11F8FFDF132B2970DF7260E3EA7ADB1
-:1059500006E7CC1928A71FD45929AF2A0AAFA06798
-:10596000FE99FC9407D3A81DEA6533C53D23D6AB49
-:105970008F056BCFE34AFD3B5878CE0CD7E0FA4C4D
-:10598000C7DC99A8673397323AFFE8F6A247B5E734
-:105990004A7EEF788CA3B150F8079CE74CC7F65AC3
-:1059A000B4EFA3CF55A5BB9C61B1F5C223055C2F15
-:1059B000E42428A7EAC8AE90C94EF066CBC323FD05
-:1059C000A4EFF2B91F30E55716D243EC6373081FFA
-:1059D00055C25D3F298673A8EED3A1FBC2DE3D7E92
-:1059E000E0E999504EFDF57B4DC7A0DFD4EF2CE3E5
-:1059F000B07E37EB9E8181A0E06103F98D6BBE7CA8
-:105A0000A5150344CD8D4C41BDABCEE328E0FA6E25
-:105A10008F21E425F95A2CB36D2407D9C54B11F415
-:105A200002909EE887B7316F632BF991B6FC12861E
-:105A3000793CCDACF30ED297678D0CE3AF37363897
-:105A40000D55B0FF1B1B9D86F9789F21B33AB423F7
-:105A50006E6A50A8FEA64685D79B79FDDC060FD559
-:105A6000CF6DF4F07A0BD45B300F29D41580716FB1
-:105A7000B6A43A75781FD0E8E5ED174CD47E1CFC2F
-:105A800001CC278C8F0B91BC6FEDD1F17B237F7CF8
-:105A90004882B59A12CB0E3B117FF7E8145017CC11
-:105AA000942D332BC0CF3678437A687F8E853210A1
-:105AB00091BB1736790BA17EB743B6E2FE76837BA6
-:105AC0008BF947C1A532E19DFE00DEBDD841F73A12
-:105AD0005B45FC3EB8C44CF166B07528DECC9664DC
-:105AE0000A3B86B7772CB086D01E033948E7D87BAF
-:105AF0008F4C7600C8C3A36EB48B76E62B189FCA72
-:105B00005CAAE5B7F4850BAA68BC4666453FBDBEF6
-:105B1000918FD7BC5317D2A15D65B97126D241F3DD
-:105B20000EA6A03FFBECC253B5C310EE50142E3F9F
-:105B3000B472A179E153479CB81FBFCE5A40FD799A
-:105B40001CAFD95FBD5D2F0DF0339DB773407E0C48
-:105B50009637CA611C27635EB582F1C174D827C627
-:105B6000F33B8CBC3E78A74CF72DE90BE5B075F400
-:105B7000007F670B14A6231F26917CD1F0D7C89D08
-:105B80005AF879C1A7C0EF32EE2BB89D513E67D1CC
-:105B9000766D3F90933A9457D9EDDAFA5B8BFAE33E
-:105BA000021A3C44E3D9E6E7722F7A9F03FB0AC747
-:105BB00015D1BE747C5F28D7A0BED87280EA8B1B3B
-:105BC00065C5E94479D7790AF75FB453666180EB1C
-:105BD0001796CD447AAADFA4A3F0C8F5AC8BE4C233
-:105BE00095F6ADC63BA2F719BDBFEFF2F55C8EA8E6
-:105BF000F6E01366B207DB1EB6E8F09E15ECAD7852
-:105C00008C2BDC55541D2C407B40C81DC3253D9773
-:105C100027CD16A25383ED517764FCA16554F5138B
-:105C200005D46FD88D753C6E41FB8E96633F17E3AC
-:105C30004DEAD6E6E35DDB131F953FA6CDC79B7209
-:105C400021332A7F2C2F2A7F6C94A67DAA755C5461
-:105C5000FED8B551F963351A78967B96A6FFF5CA3A
-:105C60004D1AF886F23B34FDE778EED6B4DF547770
-:105C7000BFA6FD66EF4A0D7C6BC35F6BFADFE66B78
-:105C8000D6B4DFB1F8279AF668FF492D771570F979
-:105C9000BED9EE3F49016CD0F791F73D6A99DE28F5
-:105CA000F7469E7B5202B7A7A2FBFDB980D3FB8BC0
-:105CB000129F8F05ED9A781CF3D835F1BA7045859F
-:105CC000B91BC6711A95DF21DD62E20EBFBFB66B4C
-:105CD000EED9F63F0EFD60BCA6C45C1BEA3B8CFF10
-:105CE000FA40B9378774745F615BBF4A223DB86977
-:105CF000158FAB5C30523CAF7F1DAC8EC6FB46DCD3
-:105D00006BA9EBEC1071A42D18474285E49941FD75
-:105D100056C6F17E3F4D57E38E3E1A37A3DC18A4DA
-:105D2000FCBC857E09E3C0CD3E66C57B9374CB0287
-:105D30009AFF9B0625995D262EDA16B0330FCC67A5
-:105D40005F155C6384BD7D52D0F7D4B3F0BCDDCF6A
-:105D5000281ED35BF0ED53188FE943E108749D21B1
-:105D6000733C3FF7C0EECF5F81F9DAE6A597A15CFF
-:105D70008D6ECF5ABEF7EB4397697F6ED95B1FDEFE
-:105D80007BB9E71FD875BA25A27DC838694326F3C9
-:105D900044D001E02CE6FD805CC8F5F9F20A23C589
-:105DA000B1AE01FC1502BEBFAAF8CF893BE0B93FF6
-:105DB00039FBEE443B1DEA65AC877E84D73FE59F07
-:105DC000A3FC929C5160DFA3FD1D179B6EC715724B
-:105DD000BA956D8DBD18076A4A343AD1CFCF32BB20
-:105DE000CA3E1907746DE07E75B4FFFE5CBFBFDD6F
-:105DF00049FE779118274B947A2B7F9E99834C4EBE
-:105E000017F71431F0A14F6A97505E652E943F8DBD
-:105E1000E48BFD89468A23A45B44DCC1B258131786
-:105E200050E306FB13EF9590EED3C34B289E8FF102
-:105E3000021C6F5CA193D6111D2FC832E7D3BA861E
-:105E40001E9FF5D7274831E6895A871A9F889E27D3
-:105E500084F604EA9965F1644F44EF7B4961557912
-:105E6000E170E4D7DE93D3517E9F32903E1C8A5E70
-:105E700030CF3C1431FEB442EEDF63FE78643DE681
-:105E8000878722E3D9CC41EF2B100C2A6684B17BA3
-:105E90004311CE7794CF77C2A0D8C91E04B587FE30
-:105EA0005F7D21D703D330976D38F219F7CBDB81B3
-:105EB000AFB1DC12B0927DD601FC87F00B012795C3
-:105EC000A1809BCA6D0185DAB707CA097E25E0214A
-:105ED0007847A08ECAD7025EAADF196820F8E701CA
-:105EE0001F959D81C554FF46C04FF09B81D504BFCF
-:105EF00085F66001C6A9D753B93BD04AED7B03EDC7
-:105F000004BF1D0851190EECA0FA03814E820F0642
-:105F100076117C281026F870E0309547035D547F99
-:105F20003CF001C137E33EC9AE58DF15C078854F5C
-:105F300076A27DF7AC6FA115ED6BFB7C9D15C57945
-:105F4000BB4FB704E31C1D8DFC1E13EF23310E0461
-:105F5000766808ED39FBFC678E4CA5F6B9D4BE19FE
-:105F60008704A7C4B682DBAF6C9991FAD930210AB5
-:105F70009EEB58DA18D203DC5A184FEDB61532F9F9
-:105F80006DCFE9FC2985DCEE22F96D3370FB41A56C
-:105F90008335855CDEAE29E4F75C1F16F1734ACACF
-:105FA0008BAD479E2D54EDA6F587717FF679B03FF6
-:105FB0005CEFBC5566BC97B5DDA3B3727B93DFCBBA
-:105FC0003A60BFB87E580FC585D97C6E2FDBE6AD31
-:105FD000A57539E6DF48EDD6A24753D04F6FF7AF2E
-:105FE0009A43EB6D9429AED9EE3B9082F76CCF8942
-:105FF0007C27DBF0786FA864F07A9E8D5A7F07E3E8
-:106000007E8303ECA5D763EC03D36E49CF3011C771
-:106010007BD41C338ED729E8D72171FE630FCAC405
-:106020007F2F30B0FBE0B92D60DF05510E54BFB6B5
-:1060300002E355BD85BE9D28379F778E3F20039C88
-:106040005AC7C7CF5D25BF8276349CF7E72D50BF76
-:10605000E1BE4D5E5CEAB04DCE35C86EEDF3DFCAF1
-:10606000C0F89743D29E8F5ABE2DF6F982878FB71C
-:1060700065954CF164DB8A375D07F9BCBB91FF3352
-:106080008B3E8AC3304CDE5CA70E4586639EFC3592
-:10609000CE1777FFA63A42CD268F3ADF589CEF6A9B
-:1060A000F134E2B15A9B2FC6BA869227579223BF8A
-:1060B0002914EF8164B12C9423CF19B8DC0A9EE433
-:1060C000F62425054D1A3C8F9A2FA0E60F44E70BC6
-:1060D000FC5EE029CBC462DEE77ED64FBF413AD7F3
-:1060E000173C1BBD9467E3923149873519D8127A62
-:1060F000EFA72ADEBA26063DA8E55328C700C11F30
-:106100001632712E9BEAF8383A3ECE64B682E02A07
-:106110008B3518435EABE533629C7F2BE4749B7533
-:10612000DFCE0D87F07C8F1A28376A8B2EB401FDE5
-:1061300084E0093DC9D74C7DE7D65722D6F51741F3
-:106140009F5B8CA162BC876E87F14A50AE22BF94E0
-:1061500050FC82D547E05D7DEE3F841DF0FCC575A7
-:106160002974FF3C6F6D1CDA47EDCC4CF46033F8BA
-:1061700053C646D0830DE932067D388B8C340EFC35
-:1061800059AA26E2BD0CD7CB35289760DDFB162631
-:10619000913EAC99FFDEAC310057F6C994CFB265A1
-:1061A00029CFD39CF4EF3ACA1379FB31EEF75DF7B0
-:1061B000502DBD9F9421CA67D1CF83B2723D53C287
-:1061C000702E950B2D14BF997C413E13E9A75148C1
-:1061D0007A3CFA173C5E736DAFAC790F6D528FB697
-:1061E0003F60548F764646B7B6DE3EEFCDD353615F
-:1061F0009EF6A5FCE1F68BBF3B827070958EE22483
-:10620000EAFB64509341F14D399881F99B1BCC8C8A
-:10621000E4B96DBED98AF2607F7A3CC9BFF6DB2C47
-:106220006487AECB6F8A433BD9346F550A96238C73
-:10623000C1AD183BBDE6D52D37D92791BC55F355D7
-:1062400082AC1CEC81BB8DDCC8093EF7F45419E527
-:1062500025CF6799F4EA96A783F9D8AD95D6E1D40E
-:10626000B14CBEF97EF876BAB796B8BE701AA11DC9
-:10627000E079A37CD715417B465A703F366DB69CBA
-:1062800069A47C6B4C3282F90D0BFDCC88F58D65D1
-:10629000E6483E57F9E4FBF27F3CC687875F590E1C
-:1062A0005C69DC2BF17B413EE79BA1FC69D310F2DA
-:1062B00054F58F1F29E0FC8B6C4B7AF58C31A67D51
-:1062C000F5AB22CE67E5469EA732BB615A1DDDC302
-:1062D00004BB65CCE77B51DC0BB5A727D23D717BB6
-:1062E0002E0BE3BD4170818EC77BD2F87FED8DB957
-:1062F000141F6A93FC29C13CCC97F0B9F0FCDA0179
-:106300004789307F5B0E97EB2CE4B7E27D358CB389
-:106310003872FDE0EF05B574CCC81EA6F8859E78EE
-:10632000CF698C88B7635C1CE317D1CF4DEED5C223
-:10633000532E68E12A66D0C035662D3CD5AA853734
-:1063400015713B7DBA5D5B3FC3A9851DD907E37419
-:106350003CCFDFC222E249F0F75E7E441C68DD6874
-:10636000FE3E5F76F7528ACBB6E5F0788F639536BE
-:10637000CE91C54212E22F7369543CD6BD663F866A
-:1063800097ED0BA3E341FC5E02F0A1A947318A7CA3
-:10639000F0EA689E87DE3DD2B7BD08CEB3600C5FE1
-:1063A000C7AB1D4D743FC5DAD388AF5C225F69B0BF
-:1063B000BE7C8AE8401D0FF92218B17FE48748F8B7
-:1063C000A151BE37701EE48B60A4FE2CE936D0FBD1
-:1063D000AB62BEA1F843E5CF72718FA2E6DDF4890E
-:1063E000B1D4BC9B55225F705754BE4E9FA3361943
-:1063F000FDE7BEAE95F1B1F810F92E68E27C88E5B4
-:1064000006917F837C182CE27C88F5A6EF56786392
-:10641000D98B0B055DDCBF63C9864F22F6B7AC7321
-:1064200085065EBEEBE10D91F951F7E33F3008BF01
-:106430009E517EED52B19D2F4FFFCB2BCD0CCD4801
-:10644000DF0728CF96159C31F27BA75E239EEB4297
-:1064500061FF99CCB3F2D12FDB11E2F26C9D88374A
-:10646000345B1533C681993B5513C750E3114D4B2F
-:106470005CB654D847727F7CC16BA57CDCE1F91413
-:10648000DF48AAF1DCCEC632D653649C6B0662DDCF
-:106490008EC156C0E9F957D93341C7C0BE4D17F870
-:1064A0007BC9FDB0EC67248F2EE468EADB449CA333
-:1064B0009FBF2D0BAA703E8BDB49FBB031FF1A1E2C
-:1064C00017D4C6D14CE23DE7C1E33B34F56D227EE3
-:1064D00072E5F1B57139D385BC21C62F8C1ADF1A4C
-:1064E00073FC8171B5F1BDABB8374F714F183A2EBF
-:1064F00036D2CDE9699DDDDF85713183E07F6606A7
-:106500003A9988F280FFE9E3797EAEC1A18D8F19B7
-:1065100030AF0BFA3F97B898E48AFA3EB5FD99057B
-:1065200012CACB27F0FDE8A4C1F2245A8ED844DE6B
-:106530007CB41C81F93470D3C35CCF364B8A0FE531
-:1065400073F47EFE7FF1877589E3BBC8AECE8E778C
-:106550009A2E630FB7058263F1B975F1FEC578070E
-:106560007EF78E91694F94E37BEB8CF86CC58E2996
-:1065700073310FB64DF0EB13693AA2A7F4DBD3B732
-:10658000EA23E829DDE873A13D9CAE13F95FF887A3
-:1065900071B427D2B76D8C31BF6AD7A9B0AD01D61F
-:1065A00011718E6DC29EEE9FEF8ECCADFA8871D2C6
-:1065B0004DBEB1345F7FFEA398AFE587CDB759C418
-:1065C000C3D4F96C776AF76733FA697F36A187D449
-:1065D000F936E3FE62F0D515E713FE75FF7C7769A7
-:1065E000F76733F9697F36F53B1BEA7C2D3F6C3E3C
-:1065F000BBE0CF76F1DE973D9E7F3764A8F7239A04
-:10660000FBF3CCBD66942FED6ABC50E8BB7351FA26
-:10661000AE49E83BF5F97369B914FF3D77F8267385
-:106620002C3D87FA8D093B93093B93093B13E1D934
-:1066300035A7570D077AFCBB1D37CF9541AFCFBEAD
-:10664000FFF4F81C80DFD9F18BB932E8A9D9AF9EED
-:106650007E330B1E29FEDBFB38FCF4E93E07B45BFE
-:1066600082CFCCAD05386918D7CFEABAD57977B9DA
-:10667000B95DB97C751E8F6F829C453DD69CE367E2
-:10668000187FFCCAD19B341FFA2FCFEE4D5F100349
-:106690002F6AB97C75217F1EADC08998CFC648AFDF
-:1066A000DDA8BEC752A77D8F25296923D987712C04
-:1066B0006445399660F6D0FB97D71673BD70335397
-:1066C0001AB85FE12C10791CF4DECB4DE5625C6BEF
-:1066D000E52FB1FD669DE709F477FF79D2BCE1684B
-:1066E0003EAB7973A306DE3BDDFE7DDE4F9EFDB142
-:1066F000C46DE5641E8F9936CAC9DF7B8B882BA2D7
-:106700005D3C143E3F7573FF7E009F1E8ECF540F7D
-:10671000C7A7B537690D9CFFF294DEF4C7894FC354
-:1067200031F13508AF51F8FB939BA97EA01EED888F
-:106730002BE15BC5AB9A5FD82C390BC85E67199A01
-:10674000FC60C61467AC7B1EA4CF483D6BB47B19BC
-:10675000DAA38634C58DF9EFCD7FD1C7CCDB7315B5
-:106760008BF85E523CE57D362719C91FDF9F3493B5
-:1067700061FC59B64C23BCD426D5513EA67E18EBFD
-:10678000447F353A0F5D9F7C3BE509E96DE8614048
-:10679000D99FC7EC31235FE93F56925D4800579976
-:1067A000872E5F290F3D7526CF434F323A315ED891
-:1067B0009E688C9987FEAD9BFB5DFB717F69B81F5E
-:1067C00023FF6E88D8976CE5F7EE589F00F546AB2F
-:1067D0008F51FC5DECFF5B6107A9FD4D563F43F90E
-:1067E000A0372A4EB45FF4A95C7FE0775BDC31E22E
-:1067F000285FBB0DF4FCFDA3AC5CCF99B9DD3EFB7B
-:1068000037B1DF27282B9644BC2436DD0D453737BA
-:10681000EA78DE9DCA97732D46CA079C6BB1D3F701
-:106820006CE60221F6A446F4BFEE56FE3EB5ACD8A7
-:10683000919E7E7BED945FFE96E1B50097DBA766A7
-:1068400018E8BDC25312F328A983F35DBDDE94A9F5
-:10685000B8CC1BEA4FAF45762C18C3C84E7A75C129
-:1068600043AD954EF28FEA8A919E7D73A6A20F7773
-:1068700063C3D877B1FFF2042ECFD5FBA5E509FCA1
-:106880007DDE6B64DF6CECFF55C51749D5485F7240
-:106890006F0EAE2BA23FDD3345F49F5B3C81FACFF8
-:1068A000E6AFDDF5D27739CEA59DF9C8C7E87CEC17
-:1068B000B1EC29F4B758E4BD86901FE87745D6A31C
-:1068C000BFC522CE535A506EEB8E214FD432C33EF9
-:1068D0006EE442A0D78C8CB154AAF5CF7AF475A19E
-:1068E00018E7FC9038E71FECF7B4C36A270EF83DB1
-:1068F000E0EF3C84F8F872E1A9F4F1B0A5076ABFB3
-:1069000026BFC76EECFFCE16F97103B0F6BEB32DED
-:10691000D05B8CDF196088878911F98B62BFF625FF
-:106920006B52D0EF81B3F420DD7604BC236B0D03F2
-:10693000CFBF2CE4080B16D2F306B12E475AEB0C4E
-:106940008CBB382C3ACA7360CCAA9167736A53A681
-:10695000A6A10BBB9C291627FAF75DE41764E0FBA0
-:106960000D189F7CE73686F75F59699D12DA75FD31
-:10697000F388F7C657897BE13E5F2DED27C3D6EF3D
-:106980009731F25FD38273506EF53DC35794F19205
-:10699000B6DD91C6F31FEE5D181F7202BD672DEDC7
-:1069A000C24F4FB00C70F830A69F71A9D9D5827232
-:1069B000E657091477D6B7E7B320C8FBB0ECFB1B4A
-:1069C000C277C8F9902E4F6C169E5BB6289EECB924
-:1069D00076A97506F931F7E858AC78D1CE62EEA702
-:1069E000FC8F622BBFCFB54FE4F4631F3F72E1B859
-:1069F000ABE7FF77849EF949B293DE7F52EDA34D5A
-:106A000043F8478E913A215F845E11F833339F1922
-:106A1000F9452F7979B074C76BAFBD96CEE8535B5B
-:106A200048471B84FDA38E139F1FA2C678C543F25F
-:106A300052B27AB8BEB0FAED4138AF75DFE963CE35
-:106A4000FF85A0FB35D90FD9B17FADD3E7C632FAA8
-:106A50003D98969C7BDD783E2D33FBE995ECBA960C
-:106A600033CEDF613E56F028CF37D89F5D68C3EF45
-:106A700041590E1B64D365E2F146D027CECBD8191D
-:106A80004691AFDE7280E799B658CABA30AFA1C559
-:106A90009256466AD8C2F356D5FE16CB21D20716B7
-:106AA00085DFDF5A507F48B84CC04709AEEB10E194
-:106AB00043ED7750C85D8B1266F85E5A9CD24AFD52
-:106AC000CCB2D78379CAE63446F744662BF017E296
-:106AD000355FC7CC31F4C9BE62AE4F5A4ACABAAAB2
-:106AE000697D327EB98EB5D8CBECA4E711EFF07C8E
-:106AF000738696CFBF137857C76916F9B477AE4E31
-:106B000009D68EC33893F71BA4E716CB027310F592
-:106B10005AE2F8CB8E671A39D478FBD78AF1BE4394
-:106B200079AE4F2CB3E27806C6F7158DF7E1629C7B
-:106B3000FFD5FB7BC02CBD474D301D58D81EEB7DCB
-:106B4000ACFEF313F7F2D1CFFD6079BC561B870280
-:106B500079EC1E09FB5A5672E65035D5F0F8D30B86
-:106B6000C29F51FD927431F60B127FBF3F28C52B97
-:106B7000F45D0CE1A7A4C769F130F03E2D3F876FAB
-:106B80001A781EDE37694C7C874ECBD7DF1CFF3866
-:106B900045939F057CEC31713FC623DEA7F588380D
-:106BA0001DC2186FA0179D04FFF7C7891B9C3FC328
-:106BB000EFAC99408EEB605CC9E127FA3639BA5DDB
-:106BC000C8EF39E2FB0FD178FEC9482EAFA5477A4E
-:106BD0005C78AF519BD69B118BDF5F7CF84206EE51
-:106BE000E7C519FD793B74DFF4E269E7E602C4CB3F
-:106BF00011EDFB6FEAF84D47CEA7F822FDA5C0E5E1
-:106C0000DF2F4B3AB37125D98D0BB8DDF87FFA7DB4
-:106C1000B317E6733B7597A495CF4F08B91C14FCC6
-:106C200060BB20D3F743EE2AF2AD403A6A93AC0B37
-:106C3000502EE73CCCF3F29A1E5BD5B328067FB406
-:106C40008CF2FDD5C808BFBA7CBD91E45EB3253790
-:106C5000F972F728439FBB9FE4947ADE558F9879A9
-:106C6000BE8A8FDBD1E9BE7B290F263A3F65A87E1D
-:106C7000D5239D440F6A7F138E8FF2C57223C515ED
-:106C8000CEA18F81713B2BB733A2D75989C898C049
-:106C9000F163067D997460491C8E6B10FEDC0B6AF3
-:106CA0005CA4A1CCEC8978DE705B99B93A824E9AEB
-:106CB00019CF0F8E1EFF372355FB22ACB1630CA8F2
-:106CC0007F31C694269FED973B6478F2FCB4950320
-:106CD0007CCCE30E43E7A3C571BE2D237BAC0DF343
-:106CE000D2C00E5ED3B06004E2B74DF6BD68033C7F
-:106CF000F47E68A23CEADF0B3EED167C3AD4F9053F
-:106D0000D90130D2187B9C1DC497E2804EC6272340
-:106D10005F34E7EBEA4231F6795CECF332F67878EF
-:106D2000E4F7B3C70F89FE1A7B1CED6D4FD4FD4607
-:106D3000248C76B627863D7E4212F105912774C2D7
-:106D4000E0DCD50D7839313999BE975690C0EF5DAA
-:106D50004EA07F52067EC8ABA7F3D17E992DF57F5A
-:106D60001749F8438C60F047FE05F9620EF3BFB691
-:106D700048223EE2F735781B9F7EE573DE3692D1DE
-:106D8000BA36C0F9E1FD46DBC5F93362DD67A48E92
-:106D900052FD37506511EF13333C9D88FBAC41F732
-:106DA0007451F772786DD39F77AC1FDCFF8672ED5C
-:106DB000BDD9868B3C2E625AC2428F4B9897AA6DE2
-:106DC000BFA9CE107D2FA8B94FBBD96B885E0F7DB0
-:106DD00017D421D69BDD711FDDBF4FCDE6F944A648
-:106DE000658CE204D1F76DA6B15D1E3DDACF0D8C46
-:106DF000ECFDE83839E6A952FCB081B12D12E579F5
-:106E00006BDF7379A6FE73FE7D94D63A9CC70E762F
-:106E100010DAD3D1EF49A8F75AEAF751553CABDF66
-:106E20008F4ABF4D47EB63C129D4AEC6FDF17BB895
-:106E300055E911F9E42B587F7F7A7F2B187BDF9B74
-:106E4000DBEA29CF2073BC7F6C189AB2144678C84D
-:106E50005AC8C86F003C68F2094CD9DB699FE71635
-:106E600033364C223C68DA3340D3D3FDC0426D7ECA
-:106E700001EC530347FBAB57F2534DD9F99795F308
-:106E8000578A639AC4BDE49451E2FB97A5AC14ED14
-:106E9000A2F4DB9EA1F33807E781715F749C62DD89
-:106EA0003B6E82F1D18FFC77C12FCDE26E5BFDAEE0
-:106EB0000FF3C8F41E9B54CED72C0DF3F27BE912CE
-:106EC000467C6E8A6766CC8F972A4C1EC4BBC90469
-:106ED000306C5932327306D4EB453C7B8DC46484EC
-:106EE000995531F3F8A3FA5DA1107D5768A879D4BC
-:106EF000EF2BB2207F4E9D67D077F52EF33CF97BC8
-:106F0000D6E8E76B299EA9CE3F14FE87FA8EDEBF36
-:106F1000D5BC3781C7531D44AF8D03F44AF07C4183
-:106F20008FF83CCA85BBD5667B5729FA0F671E4C84
-:106F300050364A11FB08CED2F3EF037EBFF1FAD7E9
-:106F4000617792BCEFDF9718EFFBEE8BFE22E4DA5D
-:106F50003A7C5909F35E1A19E531A4FBAA3F972937
-:106F6000FF00F6A0911311DF4980F1D63DCEEF1F4F
-:106F700036E3773EF0FEE7C040FEED13166CF7D126
-:106F80007736D4BC5CCCA35D5B32F03E72F47D837B
-:106F9000BD11C689986FB2990513409FA4F43105BD
-:106FA000BFF3ECB96854A6037E6C7DA05001BF937B
-:106FB0009989EEA52AAD7E33FF0EE10A166967EFC7
-:106FC000976EA5EFBD86BF6494BF143ECF88EEC315
-:106FD0009FC3C4702EFFF8DDFB7AE4CBA97D5D7AF8
-:106FE000D4F393FBFCA47FF6D94F3DEDE2E7629921
-:106FF00011911F751D5B54CFE98A9F972CEA275F7B
-:10700000306AF8FDDA5EA3461EC8175BBE46FD6512
-:10701000EA89AA67D33FE3E3F928DE2DDBB5ED5318
-:10702000443ED0DB2ADF5FC3AEA173BC981633CFDA
-:107030006EE0DCD5736EE27174C6C7796E94F79F0B
-:10704000464D40FFC04771E864C42FD8172995DD2D
-:10705000CC8E7958E54C998E72BDB2F31DA487E4AD
-:10706000B33C0F3C7AFCFD5FBE95857EC39EC99DF7
-:1070700059682FEDF9F2153D8E57D5D3CBB03E1997
-:107080004A1EA4584C78AA10B43350CFE34491F56B
-:10709000B49E4AE765E5E4CF504E1A876EDF33D9D8
-:1070A000C2C2E4877526A03DC77C7CFE64B3CA5784
-:1070B000EC2F97705E84819FF654EA526A619F7B41
-:1070C0009E91156CDCD3F34602CEBFE7EC39CD7A46
-:1070D00098FE22F345ACFB5A71EE532B7BC9FE7E22
-:1070E0004AAC2BF96C2FC5A15395DE30EADBD4C333
-:1070F0007AFAFE37B3F0BCC8614CA1389ABA5EFC8C
-:107100006E2A3ED78272DE88FBB3325628EC7E2888
-:10711000332A8355988F9ACC764A486B532B7D41FE
-:10712000A4E7E4A59C9E93ADFEC318BF4F5EAFA33A
-:107130003845F259DF06F4CB92CB6505C9E44AF82D
-:10714000EC10F3B78AF9D4F9D5F58CA8F44BE87EA6
-:1071500024B3E362FEAE2A138EBF5ACCEF14EB5970
-:10716000C5E83B2CC967AD55E82F27839D41DF3328
-:10717000B8E2799A35F345B7274FD99945E7E0B199
-:107180001ED90AE3A5645B365441B9CEA123FF3270
-:10719000A987513C3DA9279DE47D524FA128278A0C
-:1071A000FA69420F703993D4F3502DAF6FA1D2A476
-:1071B000CA17873F8CFB98DACBB87C717849BE98A8
-:1071C000D2B87C51E9B856952BCC5A321FEAF70F4A
-:1071D000FFACB5069E7BF773FEFEE5BBD95CBEBC7B
-:1071E000FB25F7FB4D69BFD3A35CAA42C305FA4D4B
-:1071F000BBC0ED33951FABBA25361148639A83E7C0
-:10720000871FBAC89F3B84D9D500AF6312C929959F
-:107210006E6B05DDAEB3EA8349D8FE8189DE773433
-:1072200039CEE598C11EFE83AEF7417CEFF8F73307
-:107230007AEF5D41F5827E434B492E9A846C39E4A6
-:107240005860413E847948AE1E7218E9BC0E083A77
-:107250003E67AFE908C33F5BCCDFFC693ED4FFC1AA
-:107260009EEB40934C3D971E412F5F88F33B2BE8EC
-:10727000A629DD7B53C904FCFE621ECD7BCEFE0D2C
-:10728000BD7FB2DCF61F9FC6FA2EA73A8EFA7C4F5E
-:1072900068A519CFF5D09B1F9F40B4ABE35F237B5C
-:1072A000EFE4E37E339AF8D0123BCF7890FCF3AD55
-:1072B00088967F8B4A860FC8BF7A6691791E12E73F
-:1072C000EB59421E4D55B8DD5E6FE5E7555FB25F85
-:1072D000A6FE8A8BF655AFD28DF2E45AE47F9BF27C
-:1072E00024D14B7D3EA797BD829E0F0A7CCEEC63D6
-:1072F0009DE897ED2F986E190BF83EE2D213FF1C14
-:1073000019BBC65206CF1D2995F04B026C7AC9D61F
-:10731000B5A900CF5224A2A7FA92AD1D4DD07F96F9
-:107320003541A903F8E8F9B31634AF0E05BC8497CC
-:10733000E972F8E354179E1BC7D3CCCAB08CFE4F3A
-:10734000BD63BF8CFAF66DC4AB11E32E1EC1677529
-:10735000041F576A2CB88F23A526212F3DE3515EC9
-:10736000CECA37D58FA1757C7D6C4C1ABE776F5015
-:10737000F8953CA7FFC9827EEACC276B53A0DFCCEF
-:10738000926619D77BD42C91FC3CDAD744F993C789
-:107390003B39ACD22D3D077479BC6F5B7312B66F6D
-:1073A00097483ED52B2F1DE2EA8FD3A73A7E0F0BCD
-:1073B000B6E17730CF29AFB7603EF5B1BE05CFCC8F
-:1073C000013C1C7F533FC4B84D1FADC071DF4C243E
-:1073D0003A9E6D3569F4B18C4E69845EAD1E6FD3F3
-:1073E000C0F54A0DC5D3CF2992E50678DEF35DAD31
-:1073F0007B3991D152DA77BDE87B4CE17C79CCA125
-:1074000023BE3CD6F7B89C8AF05946FB919976DEAC
-:10741000FA921AB2AFCE295BF54467820FD5F154C8
-:107420003A3E8A4F231EED9CFF8FF66DB320BD1DA3
-:1074300075BF23E3395D67891A57D0A1AADFF05DD4
-:1074400071A49FDA51FBF37E86EB5138FE6B94D723
-:107450008F237DD53B64A2A7A3CAFE9A1486BF27BB
-:1074600062D2ECFFFE1DC99AF19775DA3470B45DF3
-:10747000B5CFFDDBA7CBC40E66A447D847F9C23E03
-:10748000D21F77E0FAAE681729EBE8F74906D9452D
-:10749000F9DC2E8AB68754BE6ED689B8AC8EC76525
-:1074A000A3F9DF58FAC3EEF1D82A498EBCBF5BC6F8
-:1074B000BA7390BEE6A31286F11ED075A723FC1501
-:1074C000EB6D8B07397CADCC7669BFBFCABF373F48
-:1074D000BED4771EE59574364CDF6165AB18E507C1
-:1074E000E86B789E115E66AD88D48B25FDF12D8DFD
-:1074F0005DA44BD89B8578AC386BE4F18F9EE8385F
-:1075000097EA1F8525F22BAE522EEA93F9B87BE657
-:10751000F078677F79338F931509FCE5941A695DDC
-:107520008A80F7DC16FB9EB5A454FA41F9A2DF0766
-:10753000DF2980EFAF90E6619E3D55B1D79152CAE9
-:10754000E3B5779778F24AA12C2AF11596225E3D91
-:10755000605FD377C53D649FA9E3BC33CAE316FDE2
-:107560004661C9BCDC0E8FEE07ED63689C86D8E3EC
-:1075700040FB387A7E6EECF643B839FC7D23FB3055
-:10758000D243060C64A6F2522AE3E516FAAE468808
-:10759000FBE70D1ED2F34691AF88371091FCC7F47C
-:1075A000F534BE1C9E41F7582DD82583FBF9917602
-:1075B00094AC846A22E3AD6AB9A894DF73CE28152F
-:1075C000EFF34C6013C8AFA8BCFC3CEAF343CDC357
-:1075D000EC6557C87B5EF363D349FAC3E4275FA524
-:1075E0007D600E4A91DF391F6ABF894A941C8AC2A6
-:1075F000D350F35CED79DC22E8F66AD75D657ACC8E
-:107600004EF9D12ECE076B057DF5DBD53F1E3FBE73
-:107610003F1F86FECAD9FBFE93F87E4A4268A53713
-:10762000C67E5E14FBF931E5C1D370CE1B8CA1FB85
-:10763000D1DE9907A76302D27BC7F2F1F005B09EB5
-:1076400037C5FC2D9695EB6F85475B1CBA98F91EE4
-:107650006FFE787AA20D3FD9FF95E3DCFB6D20A782
-:107660005B1E7DD0ACB08175306BD915CEF947E388
-:1076700013755D6D5B305E624DBDAAF7145A5CAF49
-:1076800024E07D69EDE74D76FC0E46B43DA0C6438F
-:1076900054BDA5C64D54BBA4C2C1E31F33EDFC7B52
-:1076A0003D15F669A4DF0FB2AE1AF2AF303B6D2282
-:1076B000B10AFD19DD5AFBE43ABF57463B2ADA9E70
-:1076C000A84D3345D907BD7A94DF1517B5FD54FE93
-:1076D000F8AC54C45154791765479ACF9F4940BBC1
-:1076E000EBED0B67282E148D9FEB2E5CDE9FBDAE5D
-:1076F0005D4FF783D171ADB72FE4D2FDA011AF1B61
-:10770000C1D4CACC3FC48C80974C7B6B9511EC18CC
-:10771000A38329F8DD36FC5833C60D8D17789C7C81
-:10772000849DFBD7898BC12F85513395A07DC1786E
-:107730007CCE48EFD3995DEF91BDBD09EA86219ECD
-:10774000C79E19A68B110753CF638AC0EF6EE6B7A9
-:10775000E3EF814DB18BF7F72E46DB59FC3C2DA2B0
-:107760007FE2622D3E2DE23C27835B43DF79ECD341
-:107770003E6F11E76B591AFB1CECA3639F43A27A7F
-:107780000E13B6C5E1396C59BC4D8A750E998B2F15
-:107790007F0E5B845FA9D2EFB4AC04B2AFF7A6E86A
-:1077A000E8FB417B13C359CB31FEFDB299DECFAC70
-:1077B000107136B4A4109F6BB797BF8471DB71A3AF
-:1077C000F5748E7B25D1FFBC8EFFFE60CF78EA1F5B
-:1077D00027B383F8BB8007FBAAE9BB1BD1FCBBD353
-:1077E0007A00DD33B6CEB93D6B019C8325FB8099D1
-:1077F000FB9B83CF07EF3F4A05BE4B7BF8B954A6EE
-:107800009DD4A3BD5EF266ECF351E38F7BA49D3A59
-:10781000202B36AAAF8BFC98913BA3ECE9B32D64E7
-:10782000675BC647D5F7C039D1BD8E9FEC16D9A18D
-:107830003DAFEB8738A74A1187307F7D8AE265FB31
-:10784000FA4E717EE9D1C62527F75DFE9C5E13E7EF
-:10785000B453C4A17E2EE2009DC27F7E23E0A4F239
-:10786000CD809BEADF0A2804EF0A940B61C1CF7731
-:10787000563ECB4717AFAA84FBED47CF73BF7D7F42
-:1078800062A883BEEF74DE42DF17A4BD4D14BFDBD8
-:10789000077C722CCE49BF1F7834DB4CF1B3A3A513
-:1078A000BFFB7B8ABB7C6BD1F1B80BC7B37A4EEBC5
-:1078B000704E186F5D858BEEA536E04714A1FFEE84
-:1078C0003289BEFF341B0E04EF45543A37F569F197
-:1078D000590FFF6595F1DF1DC8427F618C8BE8A4CD
-:1078E00042EF73223E37BA4F915F1E57D8EE1B8787
-:1078F0007180F17A26BEFB143445AC3B0E6F42E03A
-:1079000079538944DF731A0ABFD1E58654AE2FA399
-:10791000EBFF7534D7831BDDDBE83C773BBAB25015
-:10792000AFEF13F910B3642948BF5F2877DDB11CAE
-:10793000F65B91651FBB11C02DA35368FDFB4A4F39
-:10794000531CF8D88557C621FD1DB3765A30CE7921
-:10795000CCC9DF53871395F97BB79DF22D31F2A483
-:10796000D5F258E922FAFD957FFC7CEFDAD17CDF75
-:107970004C52F50A8C5B81FB4D42F9DEB202F9C331
-:1079800098B983FCCCE873AA705FB388DEF364FC1B
-:107990007B4FBFB6862C783F1CED67027D6C42FFA3
-:1079A00078F7043D7DAFAD5EE6E782E788E7A41F88
-:1079B000A3137E99767C66653E63FAC079601DDE0E
-:1079C000D7D03AF13EAAEFADBF9262F8B583D6C9DF
-:1079D000FC9E58F9B0D1CFCD76B2209A86B3151659
-:1079E00076A19F70309FC6996DE5E3CC12717C9BA8
-:1079F000A0FF59177594DF81F4D680CF95CC2779F5
-:107A000072CCF550571DACB71ECEC641FE469356FC
-:107A10000E09395B5F5245F7BDC7DC07C6A3BEBF81
-:107A2000BE74E5E13227C29FD45441B729A52FD5B2
-:107A3000205D5A942E8A2F4C76CB745D787DB936B2
-:107A40004ED1AF17A3F44BB4BEA88F923B11F7549D
-:107A50004E43C4F9CF729F4B88A483ABC7CB1C2F76
-:107A60007EAF7BD6051EA71D8C97F7E973A503781B
-:107A7000893EEFD878893EA7013CADEAAACB1D8CA0
-:107A80005F156FBF2E79C91A99E71B8DB71F8AAF93
-:107A9000E6D15641AF5C9E5708BE7D3B3B4471B773
-:107AA000B74BF9EF4B1D73FF96E2BFB358A8630DB8
-:107AB000CA45E0CB3942F9E823E44C341E06F8F419
-:107AC0003F282EBFFBF3B7282EAACA2113F225EABE
-:107AD00013C11FEAB999901F916F2FF0EF875E2DA8
-:107AE0007FA87C45EB213F38A48FCC1FFCDFC55F0E
-:107AF0007B71CD18177616523CB8CAD1A5C77BAC9E
-:107B0000C950D23D92887FD23A9C91F53C6E1C5967
-:107B10004F712FA1F7D4B8A6DABE3EBB2B41185542
-:107B2000A4474DC2DE51FDC47D8E53647FAAFA5432
-:107B300016F7FE57AB4FF7087D3A54FBDE73BB795F
-:107B4000DCE7CB433D0F801C9F9C6FA4EFB84C0E2D
-:107B50003FCCDFA3708449FE6F7437911F0CFB6923
-:107B600046A304E67544E6F3A9E5BEF36D0AD6EF35
-:107B700095BBF40AF507FF16E0038656FA9D860DBD
-:107B80008F737D1357F451D6E5DE83BAB34F99E670
-:107B90004AC2EF616F5F83DF010B2A8CBEEB98B5A1
-:107BA000B48B45EEF7A531DCAF9D9CFFD61D076871
-:107BB000DD1FEA69DD6857039D4F969D0E05E7CFEF
-:107BC000F6DB23FDEC7DD9F7DA9D00B77C696C0804
-:107BD000D17AC3A37E01F3EC33578D074B8DED7340
-:107BE0001F18F50BC0C74673D504CCA3ACB6DFDBBA
-:107BF0003E1FE5DAD95B2660FC1BECBC56D4B7838C
-:107C0000F6DFB7CD8CBF3B5DED789FD631A2AFAB31
-:107C100006BFBF5AEDE0F748BED1BE87C64C407BD9
-:107C200039ECC1734F349F0C22DD4C16EB65172FD6
-:107C300051FC41BD97D9739ED347FFF8400FB88FD1
-:107C40006BBF5C45F722B97DBAF926A0D5757D3C9E
-:107C50007F0CDBF17BE058BF28861D00F35CE74B0F
-:107C6000C6F3EBCABA3786DECDEDFB36E083E7F626
-:107C70006470BC44B76F1EC3ED82B8AFDECF7292A2
-:107C80003DC0F57FB0C012F33B55B7A9FAD21A3BFD
-:107C90000F452D5579A5DA23805FB32102BF9BC61E
-:107CA00070FFFD7CA9A703F1F77DE77F0A710BE563
-:107CB000F152CFF631C391AE045FAD9763C601EECA
-:107CC0001CF3A3C52B6E4113EFABBE73E96FE986BE
-:107CD000A6DB41746550E9F821A2E3FF8BF47BE257
-:107CE000FBD0EF207974FE14DDC347D3B14ABF0344
-:107CF00074C8E69B9206E87928BAC17E8B9206E8A2
-:107D00007AA87EFBCEBF1F93DE07C6E9BD2CDDAB94
-:107D1000F4B759D0917A0F5429CE79FDD78CECFE67
-:107D2000A33D46F577C6357E11E83FCAA3AEB072D3
-:107D3000B97FB43797FB193D66BA9F9AE95E29BEB1
-:107D4000BB0D5D23C6AD11F27EA6DB755939AFEAD6
-:107D50000B55DFFD4F7C774398008000000000004A
-:107D60001F8B08000000000000FFED7D0B7454C75E
-:107D70009560BDEED73FA9919E3E881692A085C022
-:107D8000164640EBFF053D7D10321FA7C1180B9032
-:107D90004C8BE0041B49DD60E2903D9EA131321224
-:107DA0009FCD621FCC7866BD390D038C9DB177C025
-:107DB000561C610BDCE237384BECC671189C4C3C0E
-:107DC000C243086C6CD318C743B24ABCF7DE7A0FC3
-:107DD000F56B750BDB43EBCC6457E740A95EBDAA9E
-:107DE000BA75EBFE6FD5D37A3363CCCED817F85380
-:107DF0003DBCAC081A19CB65F4F305FCDBE2F2EBF1
-:107E0000252B63DFB9EECBB443F9932CDF0A671E51
-:107E100063AF5F35CAAC88B1AEA9E3F6EAB387FABF
-:107E20008F75088C15437B12748676EF54C17700EA
-:107E30001E31D1272E9D1E7DDE9F4CFDAECD958738
-:107E4000B3FA329D63687AAF3E8DB159F89B0ECA82
-:107E500020932D33A0CCED5AC712A0CC2CF9369626
-:107E60004C622EB1843193F29EE9CA6BDF15F03972
-:107E7000931983FEEB95F556307F5D0DC031CFCC65
-:107E8000BCF189387AD3C9C9D05ECD970AE369D7E6
-:107E90001DDE9FFEA529F3E430362E57A0F5CDFB5D
-:107EA0008CF94CF06B756EEB023603E78771CCD121
-:107EB000C7A9601E99E9011DE55EDB2AE83F6BAAB0
-:107EC000C9E1E5AF4BF8DE6CC6DF1B3ECE7AC64A91
-:107ED00086C6D9E209C8FA54C68E494CE92F5B6FB1
-:107EE000C167E7F8C37A85B23E536ECD55C4CBEB7C
-:107EF00092C7E10778670F868D6F1DCB583A63559F
-:107F00009F699F8B0E6D7D385C30FB58FAE54F5FA3
-:107F1000C07C4633C78F395D47F8795D32FA903EB1
-:107F20002AAED4EE6293184B96EC87FCF0DC2A99CB
-:107F30001D3E053633F6537EAFB8020404ED9FC2F2
-:107F4000BF1480739B6EEF5A27D0DD166C4C1FA2B6
-:107F500097250B4C1A38962E49D4D49B9AC769EAB8
-:107F6000CB574FD4EC6F73DBDD9AFA431B666AEA9A
-:107F7000AE274A35F5559DD59AF156EF9CAB69FF72
-:107F8000D6EE6F68EA6B9E7F50537F74FFCA11E98B
-:107F9000221A5F88B691E98979053BD2BF884D3AAC
-:107FA000FCCFC59CD3A3F7F7217FC27EBD6EAFB7D0
-:107FB000AD82FED5573F8DE7FDB4F4C5BC7200F924
-:107FC000A356D91798C72B407B8D52AD95BE45F46B
-:107FD0005E633645E41B95EEB60A5611C7AF66DA06
-:107FE000FDAAB06DBDAE477E2E1AD0EB61BE5937EB
-:107FF000B5FC572135FC06C767CCAFC7F584CBA5C8
-:10800000FFEE18937A399E60B57F01FCC4ACC98C31
-:108010009547C7A34AA7B75D37635F6FDDCAFCEA20
-:108020007A2B58A00EE93EDABA673BFC7A926B5184
-:10803000D61DBE5E15FEEF6F865F81EF5FFF23F3F7
-:10804000ED1310DBB288FCE6DF5DEBCFB52B400211
-:10805000BC27157AA8918227128B900E980365830E
-:108060007190F9510ED433C16F8452961C04AF380D
-:1080700068EF34302AEB717E711086A6D245EB355D
-:108080000ECA8D286F452CA9EE9CC7EB8E065E8725
-:10809000F7A82ED5F2BAE73E5E8792EA5E27AF4395
-:1080A0003FAAEF5A8CF5CEB8C0894401EBBE2558E3
-:1080B000370E1E5ACA4BFF05814A99E49638E85D8F
-:1080C000A7A77EEC22AF073771FAD0F283315EF6B4
-:1080D000F9B3195F3D3C3F81BF4DC2FD5CD76F00D6
-:1080E0003CD48A82C30EEFD50C32873F15F7D5E416
-:1080F00090D997E033A033316D88CF8C2C98B14A5A
-:10810000203E790FF1ADCAEDE1E368E9AB1EF55A07
-:1081100001EC3BFCBE3119E530A7A7FAB2E0122C06
-:10812000F1F913D03E7B32FC4B1E4E1F2A5CA2326B
-:108130005FA5B55F8FAAB6321826B75917D15985F2
-:10814000799D2CD987CB6D7150E52F2E2FC2E1562A
-:10815000E5AD391FF86C1AFB3A7C96B90A6AB3AEE2
-:10816000BEABF0D9BA303E93ADF79684F019103219
-:10817000D3F0D9B7899E6E275F4E09837526184FB5
-:10818000F60CE823CA9954C04342243E9BFB1BB221
-:108190001FA2C89737F01758676E7E989C51F45C01
-:1081A000B5AAE7FEA8B3A2DDE2677A11CB707CC85E
-:1081B0002C3B31D273B53CBE0906BA6BA80EF890C1
-:1081C0000F81BE631F15DC06CF9BC9CE62B85A80F3
-:1081D000C7AAE2318C6EAD712F9D90ECBC05F5EC19
-:1081E00018856E4E66A711DFC376BDC742E49DB504
-:1081F000E8CBF101CD3709C7736622BFD540DBC696
-:1082000082E1FD33B10FF09935C87C3E78CFEA08A2
-:108210000858AF46FD9E8DF4CFEA51FE575F09E83E
-:1082200025EAA5E5975B7400BF3F01A4578B7C51FD
-:10823000309C2E64E6D3E37E7CD5FDAFB61F349030
-:10824000BC0EDBFF9A41B0CF004E39D5E420FA1ABC
-:108250006464CFC84EC1C748BEAC21BCA8F6E3AD2C
-:10826000F6266817E8912E627BB340F6D0A76CB370
-:1082700081F305F3FA557A86E7CBAF303911ED3447
-:10828000CBF3D47E6C1323FAA8B6973C556747B856
-:108290000676CC44B824BD0A973F15C7BD60E2708E
-:1082A000F9DA087FD50AFEE4411D3343BBBF4F69AD
-:1082B0000FA35FFF20B7D3FC4FC42B70DDC8F04382
-:1082C000BF07D04E069368E5DD03FF4384F7DC6902
-:1082D000773FDF015DAE28F0FC6F856E3FDA2451F9
-:1082E000B93ECDF5FD7CA0C77F916E7CE266C80FDC
-:1082F0003944F7D5F6CF27901E52F1D93786F410BE
-:10830000C24DF8E8B34483DBAA107538BC0ABFE558
-:108310008CC8572A9C2A7C577C7AAB0BC67BB3E768
-:108320005F131CF621F84B45E77E84FBCDC14F67F8
-:10833000B888EF9235766634F96652FC88A44C967C
-:108340002BA6A23E8873CC85758CCB74D1BA4C36E3
-:10835000A31DFD024B2793F360487382CF8CF0F787
-:10836000A737ECD243FBD6A92233C1FB5BB3BC36A3
-:108370005AA7FE0986EB9993E96103D6E8F377657E
-:108380003E29119C835047BFC7C6F1A29F68F4F8ED
-:10839000E0B95FC7D61C0AC1CBC102EE8F9DCDE705
-:1083A000E5DA171ED97629843FDA0FADD3D4DDBDC7
-:1083B000DFDB762954DE6E1044DC9736858EDBD900
-:1083C000C004F45F5A453BE1A143379086F56B2C1E
-:1083D000787E0AAE0FE78F00FF3FE75B623DFFD27A
-:1083E000A950F68FE1FE69FF241FF90DEAFC1F2B4F
-:1083F000EBFF385F177338A6011EBAB3BFC5709F75
-:108400006A6C7C3F4D50727AE67243F577869E73B4
-:108410007951A53E0F3ADE73121DE91CA8764C99DE
-:10842000F611E97D27D2BB71A8BEB548D7E88BF01D
-:10843000FE730522C17BC016B93D5BA1979D135CFD
-:10844000DDD9E8DF3FAB736C8625CECBDC3A1EE589
-:10845000FD56DB7AA253E6E2EB58C038BFCECBF430
-:108460007819E8D179FEB782422AD68DCCC286F837
-:1084700057F50BE7893ED101FDBBF2D79971DD5D60
-:10848000B6F5661CCF84D6826E383CEABA0FECE6AD
-:10849000F3CECBF489E0E9B2B9B97BC501A83FA31B
-:1084A000AC7B5EEE3A6AAF6AF49F14097FE06743E3
-:1084B000DDE868F5E23C2687BD46C23A736CC6B279
-:1084C0004F7889EC1355BF0DE94FAD9D72FABA9103
-:1084D000E463D7159DCF44F2535E3007DE9FAFBCF7
-:1084E0006D0D727BBE6BBFA35FC4F71C02F9E3F393
-:1084F00073BF4D769D35772EB7E7B3567991549873
-:108500004FF0A13F314FC55B9E565F191D17B7A0B5
-:10851000FA30DED4EAD1592CC090BE2AC2FCF370E6
-:108520007D3BBB40B1D7725931DA2B2D26DF63C8B2
-:108530000F960D423AC2A1E27545818EE820867CF5
-:10854000B06726945DD965B4AFFACCD31704985FB1
-:1085500017DF6643BED0DB8C7EC41BB38A1F0DA819
-:10856000F34DC2FF3325B2B7B08E842F7D3979FC2D
-:108570006E96C786EBEC32B0A648F2A7B680F3FD44
-:1085800007597E920FD1DA8D1B04D27BAA7C376605
-:1085900032D937C278DB8C5CCE805FD22B40BF3EB5
-:1085A000A417A0FF175AB3F7E905A27B19E5F1ADAF
-:1085B00052B1EF120BB91FFE668189CA93CA7E546D
-:1085C0007F7136C33582FCAFAAF23084DF94CAC70C
-:1085D0003365F2F14C222F7395713F2EE27CDC5C07
-:1085E000147BB95F9A337AFB1C4B7A8D87522890A3
-:1085F000E879DD9887492EC5126F39A38837A35DC6
-:10860000A13F07A713B5FD7345DEFFAA20E674B2AC
-:10861000B47214E5412CE9A4E2CF83DECF97FF7951
-:10862000EC47DA68AEE3A399F2D442E093BF9C2E04
-:10863000DF83E596D723DBBBF3632F77D31E8072EE
-:10864000F104DF3723E9B37985B197FB4BD1BE48FD
-:10865000E1F645F8FCCB153D144B79D20465B31116
-:10866000D61F01FF8F8EC2FCCB7350EF727B81E56A
-:108670009EB9A40FB1DFE167B22EC43E067B141C85
-:1086800041B443053992DDED8DFD7E2D7D483F647B
-:10869000AFCC615C1FA8F32F2CE1F87A7A14E0B01C
-:1086A00000DEEA256EAF9BC2E050CBBF2D8CBD7DB6
-:1086B0002AE943E04805BB1FCB0542447BAFA7D066
-:1086C00018737E1A0B78D9E2608D91E4C9C9D8EF8E
-:1086D0004B9A0DCAAAE9CED328D7964B87E7605CA0
-:1086E000F9FBF81FE61BD279BE61A5C1E545FFAED7
-:1086F0004BB23BBC768C47ACA2FACA7CBB43AF52B0
-:108700003EB6DF947CDB056CD7517DE5EF241FDAA4
-:10871000C3DF17D69DC9C6F136EB1DFB18C69D9564
-:108720007C838DE71BAC369E9F106D3CEF60B529B6
-:1087300079071BCF3B586D4ADEC1C6F30E569B929C
-:1087400077B0F1BC83D5A6E41D6C3CEF60B5297908
-:10875000071BCF3B586D6ADEC1D33815E391369EB7
-:1087600077B0DA78DEC16AE379079897E71D6C3C49
-:10877000EF0070F1BC832D72DEC13A947720FFF1D7
-:108780001896A467B85F7F54A9CF067BDD34637861
-:108790005EB56AE7FE2D1817AB0972FC5539785E95
-:1087A000D914B4770A307E4566B0DF04FE65451102
-:1087B000C3F0D5B0F9C3F313DDD9E7BD02FAA3B016
-:1087C0009729BC03E529EA187F3F7CFE6171573B7E
-:1087D0008FE7D6657E8BF03BBB2C4878C3E71887C4
-:1087E000AD53F213B556ADFF2A7FE6B2F9715F992A
-:1087F000D49908F890456DBB88F92F8CBB5EF1D7F2
-:1088000061DCB76A501B7715331BD4B83CCF4B845F
-:10881000C139DFE11C5F046B6A017F2A01E6CFC129
-:10882000A415AE53127C5EA4B7DD1B88BEBC3B45CD
-:10883000C71468AA0464609EA512206A86D254C632
-:10884000ACD24CF29B389DFED7D4BDF1D9280F0392
-:108850007A46046C233CA8F9850458BF3483FC2B6A
-:10886000F2EF2A33FDBF473A50EB82CCF338825DFA
-:1088700062CD802FF96E265C3693ABCE906FEB45C0
-:10888000E635C37341E9379B05294E2D3389F276CE
-:10889000B5CC4165D174576911F0A3CEEC75E17A7E
-:1088A000AAEC6609F9853DEE3CDB48F1E47AE93251
-:1088B000E04900F6F862DA48768AC82EABF81C4523
-:1088C000BB481F2F7822C9AD8AD8EB61B2832A0A30
-:1088D00019C9C72D2CB2FC7CAC84CBCF374B5DDFE4
-:1088E000443CD7FB16D58F872E8FBED04A799B6D1F
-:1088F00061F1C25BFD8A626F4724E7903DB901E9EF
-:108900007AF1048F0DE18816C7782AF6F0EC491B3E
-:10891000C1AE7B7614EC5AD443B7EC2AFB9993FA98
-:10892000503BCAB10E4FBAD0EFBA929038AADDC30D
-:108930003C14678D1CAF796914E22099A8BF13FE1F
-:108940000B9D63EA3A02FB87E5FBBC54E1F88E42DB
-:1089500087E34B63CF17D3A0D4273E610B8D1B77E2
-:1089600059040E9741D0C0F5B962FFFDA024F678F6
-:108970002A81727DA9FC2EF261D574F96758AA7C10
-:108980003BDFE1BA40FC292DAA4F02F9BC667F7695
-:1089900001EA8906DB5EE32A80F7D552F9FD223A27
-:1089A0006FF41F5B1E6EB11E8F47BCF7B922CBA3BD
-:1089B000BB1109C5E44FDE28E2FEE467848728FE88
-:1089C000E4AF8B63BE2F7BEA7386FCC970FE1F5B2E
-:1089D000CCE39D6347018E06285746F1EBA68CC277
-:1089E000FC8D5ABF6EBF3E44CE104185E6696CDCFB
-:1089F000AF6311FC3D9735BABF377B14D6B110F386
-:108A000071B591F5DA7DC531F7AF967E03CA0733AC
-:108A10005BFDA9D0C4BC306FDA50BEB2C9D5AF0F70
-:108A20008D733F38E1E037E508707EB338E672F2C7
-:108A30007C9C1EF975BD19E1E96A067E8DB05F2543
-:108A400025DCFF9B3BE111968876633A43F711E4FE
-:108A500009CF3736297E6383A27F762A72D4532CBE
-:108A600052E92CE5F5B951E8FAD7CAFB8D4A9CB614
-:108A70005162F22B91F47FECE9E6FC3828E7C671ED
-:108A800038EF0DF3CFDF53F4C49ED8D3CF9E0CA0A4
-:108A900093B9B591F17530F674B17402CCBFD4F6C8
-:108AA000F41C90F8B02F9B0D945F9C2EBF580CEFD8
-:108AB0006D8BC2579F2B7869863E3AB0FB5BA03422
-:108AC00042F91090815440FAED55EC6F018E30144C
-:108AD0002004DEF1E8E7F43AE41E7CCE5C6DE47F2E
-:108AE00084C81BCA9F569939DF74A783FF88FE0E7E
-:108AF00033D33993AE20CF9F7665F2FC68383C6A59
-:108B0000FEF46F458F19CF71776516C485F2DDEBE2
-:108B10009B98266FDC7585E785C14F8AD3FA49C9D2
-:108B2000E427858F9F90B9745EA87F24C8DC1F025C
-:108B30007F26505C3CE417A9FECF987CF95CF17F5E
-:108B400002FD1DCD9F1147490F8B30073EFFDD749D
-:108B5000F9DF108F23D0D31FA3D0D39FB0DF7F3492
-:108B60007A62CC11B768CCF071BBB21EB7B58E700B
-:108B70003F2021D31991CE54FA027A9B503276E8E5
-:108B80007D21F3B44A6F134B8ABF3EBD5DC0BEF07A
-:108B9000EFACE1AFECD649D1FB9DB57ACC280FFA0A
-:108BA00032D79BF19EC4D4992E07CE6B11996C00DD
-:108BB00038BB5C3E339E7B003B2FBF6484BCC1CD81
-:108BC000222E3F7EADECFFDC099CFF2A960BBE7D7A
-:108BD000C07F4D6C9701F74D7DFF5849ECFD887BB8
-:108BE0007248EE35968C20F75E56F8E273055F2BDF
-:108BF000DAD629E7995844FB6755ECFD8C342B9461
-:108C00007352D745A4E35B7487E78522AC6714E20F
-:108C1000E0E7C7E4E03C4CCD2B6D40FC3E56C4F190
-:108C200017CDFE7D6A14FCB38900D74AF69901FD81
-:108C30006959FFC7AC48E7118E15D9399C069003D6
-:108C400080DF9559BAB731FCD995A4B587D4F767B9
-:108C50002BFEAE6714E467520ECEC3F11A7E0E4CA3
-:108C60002DCFC53E1EB0B488FBB9FF80FC0EFC734F
-:108C7000A8A458E3E7FEA864643FF7B57F8FDC1A29
-:108C800050E8A8CB11D99E7D21F6FB40E7E060DDDE
-:108C9000EF7C15B9116E6FAAE59ED8DB7B69597A16
-:108CA0009C87C3D1C8B4E7246EF1DF28E02D5D8F27
-:108CB000F368E97725E3FA5F85C3581AF3738CE705
-:108CC00067E831FFC3F9797DA92BBE94EC368F1983
-:108CD000F537D80714675FB939251FCD2AD8676BD8
-:108CE000A996BE934A47A6EFE4D23B40DFAA9CFC7C
-:108CF00017614C53A8BC99A8C89B69A5B1DFAF29DF
-:108D000018AF488E2CAF2B631FE7DB73774E747957
-:108D1000AC9E37FB47411B4F6EBD258F634E4769A5
-:108D2000A9FA2179ACEA87703C8D865E480CD10B9C
-:108D30000D51E4CC68C03136041FB59D02E5AF98F3
-:108D40008DF9A6C0AF9DD839E4DEC7965188134F80
-:108D50000F8D7FC860AF47A0E3DDA5B1CF7FA3BC77
-:108D6000E9377CDB36D2F947A3D5C5283F6273319A
-:108D70003BEC9FB1B395F2F6C605AD9487669D02B4
-:108D8000E5FD98F42EF979AB6CDEA7307D365C9E5C
-:108D90006C8D395E8B72D897F637C5287ECDEBF88F
-:108DA0004A3AF937AFA33C1524EE47B30DCC4EF742
-:108DB000A4AF7CB9FB582F2012302F9AC4E83E761E
-:108DC000A7E1C77ACC471B053EFE5CE6E7F94F9763
-:108DD00077FCA3F09EE5A0317F3B547F519A4DFB79
-:108DE000DE69E5CFBBF69BF39F84A59EB6159EC1B9
-:108DF000F3E153A727531CECC5038F6BECEC5ABC73
-:108E0000C7807EDF0B1E867EA229D33571243B9C52
-:108E1000317F92AE8C509AA8947A5EFA059D6DF8D7
-:108E2000FB3BF7F748E867BD78C04C727FEA819E4C
-:108E3000F85521E32796713EB6063DFE1900AF3581
-:108E4000D3733209EF1D2BF9739179CED4C22B6302
-:108E5000A4009D0FDF91576B0EA5BB2EA9D64C79B0
-:108E6000E45C9D638A1DEBFC1C43FCF4DAFD82404C
-:108E70007EDD2E1150EF9AE1BA867AEC0D89EBC3B4
-:108E8000A9536B49AB752AE71E76E42D3980EFC7ED
-:108E90004FAFA7F13B59647BCC58C6E5F08B0699E0
-:108EA000E67DF18048E7C855BCDE697CD6CB300F43
-:108EB000E0A3DEA6A77BD8A78D4E11E5D0E93481CB
-:108EC000ED822DDFE97885EE99EC8802EF2F4AB923
-:108ED0009FCA6CA9447FA7F7772E8F747E5FA5BFCA
-:108EE000C93364A90CEDC0499E2694FFCCB6E43684
-:108EF0007CF124DFBF4387E6CF03FCCF7DC17F2217
-:108F00000EF7216BCF785CF707A5766ABF450F1F78
-:108F1000BD42F4B0C5C8EFE37875718E03B08E859D
-:108F2000D60111CF4F18528394E76D2AE3F2748B68
-:108F3000CA0F63811FE03D7D06BF07C526DAA9CEB3
-:108F400026072784DEA39E55A6AC970532F1F9C209
-:108F5000F87737D81D8C15F6A6378BB0FE8589EFCC
-:108F60006EC8867A49EF785ECF78F7B36C89B1B274
-:108F7000DE0C5E9FF6EE6793A05ED19BC9EB953049
-:108F8000D478B09B7AB39ABD7938BEA419BF150FB7
-:108F900072147FFD526FD2458C5F3528EB871F031B
-:108FA000CEE3ECFB473AEFE2345BFD782E83C986D3
-:108FB000B0F8193485DC7760A90924FFD4FB0BF3E2
-:108FC000457F3FF6D799FD84DFBB5927D97380AD24
-:108FD000DD5F147E797B2E5CEE6DD9C85C784E8C9B
-:108FE000B16609EF33084CD67DC1E3784E9C5F85AE
-:108FF000479D7F185CB0B5C89F43703D4FE3A87094
-:109000005DCB377951DE7A6B59AE27044FD784E0B8
-:109010000F186C45DAAC1D0FE13E5D1B139C204020
-:109020003DB97C1BEDDBB5B1C11F088E90BA81EF55
-:10903000635B6F09ED639728B7219D9B8CD66E21EA
-:1090400091B1EEB884190CE6D931D6E5C57B6E40F6
-:109050007774EFD89B65741C0038EB8BB4F9A1C70B
-:10906000153AFB83220FE6987679CE015DBA7B0430
-:1090700086F770DC83378CA8FF16F65D3462BEA4D9
-:10908000A3E7A211E9BE03EB304EC7F3C688F96F20
-:1090900063B95EBD2F4AE791D64B1C4FA7B2EE7A5B
-:1090A0002A15E0E9582DD0BDBCF54792E6607D7DDC
-:1090B0002BAE92B1E55587E720B9B438FB9FC27259
-:1090C000251B38950A24B4CCA567F6103DB9624D2E
-:1090D0003CB387E8C9164F8AA6BE7217ECCE0C289F
-:1090E000376668FA31E5FEEA3236F483E7989A94F7
-:1090F0007D5C66DB19C0B8EE3297C13B1032DEC230
-:10910000BECD6232C2ED111C748DD2CBCF3FADE02B
-:109110002B84521C7A1FCFF7F40AC4EF1D6D7ABA64
-:10912000C7D3DCCBEDAEE63582CF2E201EF8BD0DC9
-:1091300077AF40EDEEDEA7EB9311EF1B000F00477A
-:10914000DAF8847D2C114793E9DCD54A055677DFA0
-:1091500039038EB3E23B02DD6755BF9BA0C2BFB2AD
-:10916000A991CE91017C5EA44F759D4DF647E95CB7
-:10917000D5CA89970DA887617D970634F8D4D65B48
-:109180003CDAFACA8DDAFAD132E59EF234360DF9BC
-:10919000E9789920E23924B5FE51D6F9B7F15EE7B6
-:1091A0006ED1790AE9B3CDE89F81FA7EB7E8A2BA19
-:1091B000DA0ECF3B18F19DF8E100F1B140FCB9C5E2
-:1091C000204B35F83D977681E87605B6ABF3670F0F
-:1091D000BD4F75FDF0FA4D55EE5A9C1BE8BB30476C
-:1091E0000509ED907A511693F3882F229E77F9BDE9
-:1091F000C2076FA3F603B8EE4222857DBAEBFE44A8
-:109200009F17E6BDEBCD563AE7765721D0811DF981
-:109210005E47E7D6E6E3792F28EF03796881F22EDF
-:10922000FDA12692EF338D12C977E59C972A2FE492
-:1092300017B5E7B6E6679E213BEBBEE776D279B578
-:10924000C93972C1D3A80F2D7CFE1D4704DF6618F3
-:10925000A723EF34C9CF71323F2FD76153E4682F72
-:10926000C85175FDB0BFE350AE612269411ECD9B70
-:109270006E56A95D263928F86B75E8FF8E53E6DD3A
-:109280005F6DA775A73D7A48C0756731EF6601E647
-:10929000BB823A7CEC50F955EDD7B5F80BE85D563A
-:1092A000AFB5635B45D7E365305FBB6DC0C8CF2DFD
-:1092B000068DA81FEEE0F8DE48E3C3F27574EE50A9
-:1092C000E2FB30473F988076CEFAA339E3D808F620
-:1092D0008DDEACD3C8118314A79137F373B5F26751
-:1092E000A1432B77BE5196A3695F244FD3B4DFDF30
-:1092F00058A8A93FE0ACD4BCFF60539DA66EB2CD88
-:10930000D3BC6FB12FD6D4E373976BDE1FE358A5A0
-:109310006937BDF5A32601ED71B377C00578E8067E
-:10932000DE284B1ED223D312E06528E30A2D562CEB
-:10933000BBF34D744EB67B3CE89744ECFF1D3A7787
-:10934000694E7CC95C03E5DF0BBE5AFC7E0EA0C9EA
-:1093500085F6DB3D4F68E3F0C7AB385FA96543B9DD
-:10936000EBC10A28F35EB067F07BE9817B707FCCAC
-:10937000718CDB45AF99C92E9A89765388BF71B03D
-:10938000BA667E39F67B42BE17F982F532690ABCAD
-:10939000B7CF083B8B7AEE3523F5CBEB1DD085E6B6
-:1093A000F77F59CEE5C1B3CEDA7B71FC8E3ED0B2E9
-:1093B000C84FCF7D6844BFAEA3AF3F01F5D90CE7DE
-:1093C0008746B4CF879E2B7A4E0CC6619CE31F0E56
-:1093D000E923DE63DD5E6EA4F14F2B72BDE53B7ABF
-:1093E0003A4F8BF7376B4A86E473CBE1A01FEF63EC
-:1093F000B7B4F37B9B788E36929C06F9FC61A8BCCF
-:109400007D361DF4C14C1A4FA30F9697F9E9DE3E45
-:10941000C86FCDFB2B97345CC57C25C871EDF34C30
-:109420007E1E96B10103FA7320D735ED1BCB95FB59
-:109430009CD358DE1720072E3823DFDB7DBB8A9FA5
-:1094400033B8E0AAA37D7816F089E7479F1D863FD1
-:109450008ED7DBE1ED65A48190FD1B66FF5771FFA0
-:10946000EAE52872FBA2B2BFFB8440010A55B7337C
-:109470008EE87785B975EDA542DC97CFB7A2BFDE40
-:10948000F22381EEC1FFB2FFAD343BACDF78F8547C
-:109490001ADE97761F3A9586F789DB0CF6CD68CFF2
-:1094A000037DD03DE48E5E3FC1DF7EA8B01F9FB735
-:1094B000F70A0E14C9EE9EEB0DB44E36B015FDA39F
-:1094C0007D51E03A58CEEDABC3E5762ADD2E9813F8
-:1094D000F57E8FC9E713901E403E215C47C00F8286
-:1094E000FABE6DE6A648F6D46505DF27B71919DE82
-:1094F000FB6D83FEB88ED359A78DF8BD8596C3B09A
-:109500002E01D771EE81781C7F8381A19DA1C2F7C6
-:109510007156E0035CFFFBAB0D0CCF2D6F59AD27EF
-:109520007CBFBF81DB27FA877FBD3503EACB802E66
-:10953000F13B0F2756DF389D01E3BEBF86DB69751F
-:109540000F1B882F97AD136EDD4B0EA56B956EFF2D
-:1095500046A1D370FA0DA7DB61F4BAE6EBD1EBDBE1
-:10956000E5B7EC9019A8F761FFE78C433AFA1E7350
-:109570001C407E1A3C611807704FDA2A39C0C36359
-:10958000D3F5BEA7D2506E9CE0EDF96D7B052E7F22
-:10959000ECCB717D19DD4686F7082E2AFB7651D972
-:1095A000373B0B0AF1C8CF626012CAA96C25CEF90D
-:1095B0008A81351D46FF52E4F267FA8F6D7BB787CB
-:1095C000D0EF7F2BE774ABCAC56946E63A6CC5F7A6
-:1095D0000F8D5F04E3BC6CE0E7352728E34DC90934
-:1095E000362C825257C1E5E46F1538D4FA9F143EE9
-:1095F00060277F43F85C68E6F89FB7D1DF8CEBF813
-:1096000099C975BD1CDE5F30E17C1BEABDEE493FA8
-:10961000C9E3DFB973901DEE56F07FA2FC37CF632C
-:10962000EECF32358EF6D772F46909E9D932A568E2
-:10963000DC48F130F7CD6CE64A01BABA9943A55A35
-:109640005F74FCAA7180FC82EB0DC42F37D3E9B99B
-:10965000DAEF5305EEE9468E07D6974A7A1BE4B651
-:109660005816926750F1A0FAE39629FB69BF1E5B7A
-:10967000C728EECFD8D3848F156DE7845618E741FD
-:10968000836CB002BECF2736ADBD3485B19F6C620E
-:10969000CC050B3ABBC9CC5C77037D6C92A81ED875
-:1096A00064A3FABB9BEC545EB638C7A2FE79E0A473
-:1096B000670AE2ED44D61E672DCC73EDAC81F04114
-:1096C0003B06F4FD98426B37FAF4CC0CED377A94F4
-:1096D000EFAD28F03F743383B940BEFC02E7838EC0
-:1096E000ED1B7F4672CFB1E67A03FA49F96D17B7E1
-:1096F00062DDBDF1770D685F7C00FA04E90CEC7E59
-:109700006613509E9C33DA810E9A6FA6D0382FEBE9
-:10971000820DC877DE630243FAFCA0F7BA711CD74A
-:1097200057742DE1F94D74E69F2DAD4822FCB8FB2E
-:10973000F2757C7F8B74A1F729FAEFF94302EE876B
-:1097400079A3FD9D4AEC7F46CF90AFB7D70613A40F
-:109750000872F8028C8B97A3701D5886B73719BD15
-:1097600053F03C419342C7E1ED8B15FA044C1B9436
-:10977000EF2932218D9F23C19F1658526232F94141
-:10978000FE38E0E796BEBAAB22961E817DA8F5CFE3
-:10979000D88721767C343AFCB2257E43E6C3294340
-:1097A00075F42343EF7FA01F19E9FB82A6ACC9E340
-:1097B000468A77B907C0BE83FDEA00C3C99E82F41A
-:1097C0003E8DCA4F8E74D9917FCC71C13DA82FD8E0
-:1097D0005D3AF23BDABD5A7BA841E18706C51E7AA5
-:1097E000B442EB3F819FD45EC1FDA484E34CE33FD0
-:1097F000853F27FFC98C7C05F34E83FD7925D2FE7A
-:1098000054D5AEC77E13D82EA27306748EF415BE3F
-:10981000CEBFA8E07A54E5EB65C8D748BFBD9CAF82
-:10982000C3C76DA9AAF90B1C775B947B10F757F19E
-:10983000F1DA9F13085FEEE752084F1FB3E79CB5BC
-:1098400040971F031CFB802EAF399DF149D0FF9A32
-:10985000CB199F6C1D92031DCFC553BF6D9317A7E6
-:10986000B442FD19A47B18EF93DE3A8A6F3EF41CD4
-:10987000E73F75BE0FFCCB52909F8A0D41A303DAE0
-:1098800033FB2E26A01D587CE4FE14E4C368706EE2
-:10989000AD54E0DCF8D8DA4B299C1EF01CEE5A459A
-:1098A000BFB99FF41B11FF6B3732A2DFFED77ED901
-:1098B000817CFC495FBC84FAF0E3A3F15E94FFD79E
-:1098C0008E997C3A81FC106F22C8B58F0D03F791F9
-:1098D000BD79442FA1FFE83EF6DB3DC88FEED74CA3
-:1098E00068F9B1B57D5DD751EFB5F5DD7B55C4F2B3
-:1098F000A5D1E587F68D8FD37AD5FA6F3799ED2804
-:10990000473F11B99C58DBFB2AD9BF6B076FCCC00E
-:1099100038EAC747FF4F09CA35F79B374A509EB907
-:10992000DFB85182EDEE1FC77B22D92D71B3F484CD
-:1099300057555F66BF276AE2451B14FAC8EEDCD5AF
-:109940003809F0577C6E8903F3B66A7BF1149D13D6
-:10995000DF2FFE797DCAC321FD3A0322E58D8ACE31
-:10996000D5C7AF0EA1CB47AA0C9AEF947DD5380F7F
-:10997000B6E2F72D6FC575023AFA0EECB680C8BF95
-:109980002FBB46F0A1BF01F64B783FB2A7AE3D9288
-:1099900042F71099E89C3FBD08EB531CDBED2856BD
-:1099A000CCA72687D84BCB023ABF09E8A8A9CFE4B9
-:1099B000277B3F205EA4BA62473D74FD3763B285C2
-:1099C00008719ADC77E7A01C0F8FD7C0CF18845B93
-:1099D000B5AFCEA7F3F851A647D22D04B89A3B995C
-:1099E00084781D16D7699A4BF1A2F0F88E3DB0DB52
-:1099F0008CFDEC937512C2ABDAA5B88F3D11E4C0B3
-:109A00005F567279A6F2576780E7F53A03B5E6C963
-:109A1000507E5769EF9174CC0B78E9ECBBFF00C620
-:109A2000173A071F8C9F0EF374BEB798619EE79A92
-:109A3000546B9E82FD06E79A1FC81BA29BF0F91A81
-:109A40002AB95D34642F44D67FA50A5F8F961E2CF9
-:109A5000ACFCF3D083E09F575472FF7C058F9F705E
-:109A6000FF3C5C7FA872591D77AD82EFE172F92A45
-:109A7000D939E047935C5E5B69A7F732FB16A59086
-:109A80007FFDDE9214BB75F8F839A243979C377CB2
-:109A90007CD59E737BE55366F47B643DF1A77B899F
-:109AA000E0C3FC976AFFB99D02D9E5EE66830FDF3C
-:109AB00053E10A2CE1F1D8076483CF220CD989AA9B
-:109AC0001D79ABDD2150BB6A57AAF663C0C9E3BB61
-:109AD0004B8A78FB658B6B55E5585CA7859E17977D
-:109AE000F3E78C394FA15FF5E05281911C50EC4AAD
-:109AF000954EC3EDCE4FFB7212478A433DAFD0A7C0
-:109B0000CA6713C2F843D563CF54707EEB403D5E05
-:109B1000887AFCF71AFB3C7C5CD0E38F57523F46B7
-:109B2000FD8B7E2E3A23F9EB6665FCADEAFE054E11
-:109B3000D620BC592CB019FDCC68FAF57B8A9D1350
-:109B4000ADFD19C57EBC1D3F1F56E4C868F1F3CBBF
-:109B500095B7F270FFA9F9F9967D688C62BF57D569
-:109B6000BC86FB1FA7F7046A90FFFE9781E2EEE137
-:109B7000EF3DA5FA9F22D3ECCFA92CA30EFD23F72E
-:109B80001A1E3FE84EB2BF437ECC5B7A86E3AC053B
-:109B90007F10EDB8476F2651D986F632942B5E3888
-:109BA00047F988156BB4F077634C17FBAFCBA6F37E
-:109BB000032DAC9EE24C2D7D49D216500ADD630F79
-:109BC0009D46BEF21ED0DB0F84BEFF88FABE99C749
-:109BD000E136A6FB28F71A660FB478C2ED7EAD7D9C
-:109BE00050A9C48DA2D9096FF45BB85C39A3273E94
-:109BF000EFC078D34CC68C7D5C2EB837F23849471D
-:109C0000DFE604FC086ABBD27E450C501C8AF26B6E
-:109C1000F0EAD5BEA7D3E83E97ACCD27B5EFFF3924
-:109C2000C9CBF0BC52720F974BEE36BD92472AA1BA
-:109C3000EF97B7833F390EED4BBBFD1B8877808BC9
-:109C4000F948DEC89AB8CB3E25AFF4E9997F253FA5
-:109C500074C5912879A4EE793C8FA47C2777781E6F
-:109C6000E9F4A90CFBEDF3481DBDE7E81ECBEDF2CE
-:109C700049A6AA5B711C8A3B4E14797C77629F20AF
-:109C800061BC6A621F5F77E9B638B2AF1B7EB53A36
-:109C900005E581BA4F9F2CE2F8FDE4FDCF6AB05F85
-:109CA000C9AF44C902EB7AE3FD0D3FCBE075BBD9E8
-:109CB0008EFD36C4A33FF3C9AFD6C7237EDF801223
-:109CC000F7E7C717C4C8F1C9A178756615C59D9592
-:109CD00078B508FA70CC505C27BCDF8B555C6E748D
-:109CE00083BB4271CD233CEFDF9DEE9A47F5BF9ECB
-:109CF000C4F8DF2990291EFD2AD035C68DA6C16281
-:109D0000312FFD3FE35827E691BAC7BA7E427CF473
-:109D1000D73A3BF211F4A7FC93F7B09DF423866A7F
-:109D200031CF33033F5B40F7315229DF738FB28F5E
-:109D3000E9E0CFA25F09D02CC13CF43425DF332306
-:109D40008E8938FE0E836BFB54CC2FF58B8ECDC4E1
-:109D5000048E143C6F199E7712649E2F57F34F6A3E
-:109D6000DE3C5AFE49C07994EF56F0F396B280F982
-:109D70007435CFC4963A29F9B5A5CC43F7427C8017
-:109D8000B3AF73DE6B84FCCFC31511F23FEB2B989E
-:109D9000629F69F38DDB735F213AFDAA79C6C378B0
-:109DA000AEE28EE6C5ECDC0F0D83BB28E9D334F2BE
-:109DB000BBFEF86F09A467FB6E903EBC1634B10081
-:109DC000C51F0778DCBDCF4071866BE0BF8D0DD11C
-:109DD000B3EF54F0718FF7D511FDF704EAE3F1FD0D
-:109DE000DF2BCFB7BDB7E47EB4F7BD01FE1D0BC6B8
-:109DF000B83FD613108BD16EB983FBF2646584F53E
-:109E000099E3B87E0AE7A35285FF4AAB389EEBDEA2
-:109E1000E77E987B03CFAF488A5C707B785EFD74E9
-:109E2000569AA0C6D3C745CABF1C0992DE687944BA
-:109E3000A0EFC97CD9FCCB33E991F3F12B7A2F4603
-:109E4000CEBF343690FC8C16CF0E8F63FF9D2AFF59
-:109E5000A6F338767A9544EB4EF6E4D78C6343EB61
-:109E6000BF83FBB07456847DB883E36F9C1DDBF128
-:109E7000EBCA633BFE13311E7F7B8CC7FF61796C9D
-:109E8000F3EBBA8AD8C2FFDB18C3DF1F09FEFF5706
-:109E9000CF0784E7FFC3CF0B849F0330BDF5B01716
-:109EA000DBBA849D413FC3EF8DBFD624801C149341
-:109EB000F6D37DCE05E53C1FB6ADDEECDB2B0C9D6D
-:109EC0001B50F1F56835F723A5BCEB5EFC5ED404AE
-:109ED00039509F82F1B272FE7743AE59785E8C8919
-:109EE000523AE6C9E0CDF4C56097745B22E7595356
-:109EF00095F1A2E99183D5358B6715E31F3D8A7CE7
-:109F00000EFF874A1C52EAE5F7E999684F5F4CF368
-:109F1000DAD3D11E4A3CC99F27F899BC97E0B267B3
-:109F20002FE67FDC201BE17B46C9FF26CFBB2B1B26
-:109F3000E3D2C96017625EF069CC0F923F2BD17BF0
-:109F4000EA7C9766713FEA190313309FEB9DCACFF5
-:109F500039B19EDF91FDA6E6F5CE1AFC975A05CAE7
-:109F6000EBB523FC3FD5F9F3F6652B440CF8CDEBAC
-:109F70009128DFF876F9DFE5BA681E9EE77B4CE2B0
-:109F8000AF9C40BF19E078EC6821D1EF8AE3E5FF90
-:109F9000D48CFEC76491F03CCCAF54E205179478A2
-:109FA000871A2F50F35BFFACC4493EC0F80B9403F3
-:109FB000180F8172FB2CDD9DD64FDB6745E0FF67F4
-:109FC000041E1FF2FE94C7870A8D8E9CD0F3947FE7
-:109FD000358BEF63AB9FE72FD478CF0F95F5147EC9
-:109FE0004FEFC7EFA1156E9D6E443D5FB8352B0E48
-:109FF000CB19B24F9706F85EB6FAB04EDDBF487483
-:10A00000B45759E7B63341CAEFBD1A96F7BF348B40
-:10A010009F6768A9E6FB7B09FFA018D41F9B226EEF
-:10A0200041F331B14AD247CA2BB5805F8C70B67606
-:10A0300073B8557CB7F8ED7538CFC553C1AD581618
-:10A04000ACC9AEA3B87BDBF5AD68BFB9076F9CAEFA
-:10A05000A67899D18EFEC44303DAB8DB13D53CFE53
-:10A06000FE2A1AE088B77B45F28F0BEF15897E92A6
-:10A070005B2CE4BF261B98DE8AF545DC2E2A684C53
-:10A08000ADC33A5B9244F660C1197BD2C379437188
-:10A09000B0E47B378C453CDD2ECFAAC6D32E5BE4E3
-:10A0A000E3B89F5F35CFDA7EF63D3A6FAAAE4BC577
-:10A0B0008B9A2F8D966755CF3DB81B3FD39CD3709D
-:10A0C0008BC1068C3F161EBD6854CE5F4AB6ECA10C
-:10A0D0003C6CE191EB947F55F3AD6ECF75B2ABA1C3
-:10A0E0009F11FBF76CE2F9D7D7000E2C7B61DDB234
-:10A0F00009EFA1DBA8EC8375E3F3639B72A9F46F0E
-:10A100007250797C531995F899C9F464CCDB5EA739
-:10A11000BCEDD559C3CE4D525E6FB7E8FC08F115C2
-:10A1200092F7A37A78DE4F1FC7E335EE3306FABE07
-:10A13000A1FBAC99E4774D5FEB44F40F3E3FE79A07
-:10A1400088707760DE2D842E3E911D9624F4839DC9
-:10A150000E0BE6DB0AFBAF1AF13C4C871830623C71
-:10A160000C20CFC0238BEE9EEBFCDC6F5F8D05F1E6
-:10A170007BDBFC58EFFFCF8F7D95FC5877353F2771
-:10A18000ADCA9102A74EDE8BE519D9F270889CD832
-:10A19000E6E4F9946D9327111FEE764E4A5A1D326C
-:10A1A0005E67238F5F24DF3BD912FAFC97D53C1FF3
-:10A1B000962C306724795633FBEBDDC71B416ED7F5
-:10A1C00044B2FB3FF929D0E54CA08B23DF9E3890A9
-:10A1D000C7193F341EB7AD71F5C431289F2E98D8EA
-:10A1E000141EAFD3C4E358585E2E5A5C6E45A34E7E
-:10A1F000B6D079A1E004D4DBE1F13326062770BDA7
-:10A200002E67E0BD1498318395B161F9B95F30DFF5
-:10A21000CF27C3FBCB1A75A42FD43C5D41A3C8360E
-:10A22000017D166C34F8283FD7285EA476C56FEC04
-:10A23000940A3290CE3F386B9430AE161E1F7334A2
-:10A24000EEEF9E04FD1D6D02DD0BBA5D1E4F3D0756
-:10A25000DED2DB3F07E36DF96C57773DF4CF9FAC5F
-:10A2600093F0FCF4F07C1E3FFF5DA0D839E171361D
-:10A27000A433B44BC2E3F01B153AD8389BEBADD7EF
-:10A28000147F531D47ED174E3F3F9DCDF56DB4B87C
-:10A29000FE5165BCCEC6826D93717F17E818EA93B4
-:10A2A000CEC65AF3E490F176CCE6E7DB9EC1FC60C3
-:10A2B0006A687E90E701C3F382AA9C2BECFF7D03C2
-:10A2C000E27B37C86BD4636E1BCF1F141EAB398380
-:10A2D0007263084EAEB777C39E07C8BE732431BE03
-:10A2E0002EFA7B45DEA302C5E70A167C763C1EEA01
-:10A2F000CC9944F7B0DC67276FB1A23C5A2016E333
-:10A30000BD1EB753B89567C27CD2FDEFACA1EFBCC0
-:10A31000163E907F0EF7E58166039D0F54F5DEFD36
-:10A32000EF3435F0F6BD4FC6617BAEE0B0D8F179C1
-:10A33000237D3F76FE4B7EFABB580B113A90E781A6
-:10A34000B39744E49BCB16D7DF231F152E52F24C54
-:10A35000CD5C4F3FD0B7C8C0C8CED3EACD13599F0C
-:10A36000533CE8465F21E58F52F0FC43DE90BE2966
-:10A370003C0A7A6CCC9DD3633F9D2D113E67821EB3
-:10A3800043789217F13C7DF8FEEF50F63F9A5E8AD3
-:10A39000268751FFF0FB63DE0CC1365C8FDB31EEAC
-:10A3A000538AF63A94E3A2D3DF1F6671BA4E8A62EB
-:10A3B000CFFD49A1DFA8E7A77A4727CFF487D97F48
-:10A3C0001E7963D5FF52F34DAABFF6A0620FAB65AD
-:10A3D0009352FEBBEF37A0728D78BF2139F2FD8614
-:10A3E000870E0968A7A8F71B4E1959CDE1543C4FB9
-:10A3F000ABDC77F22D223BE9D4DFFC62EB8BA97852
-:10A40000DF4990501DB51F3A477ABE1DEC23B2A715
-:10A41000FA7ECBE3AD87F8F9F0F6DEC8DFDDDBAD21
-:10A42000D8DFF53223B9D1AE9CB76DE851F244B70D
-:10A43000E2968F8BA1714BB73D30563DC7EB237F22
-:10A440004F1BC78C16B7EC60413AB7DBB14670A022
-:10A450007EB8DD39DC5DCA79DDA8714C79E473B969
-:10A46000E1714CB95A9BC7B96F96C4F7DB250868F0
-:10A47000EF9A75CE363AB77F4C90229DF35E5ACD57
-:10A48000E5F47C250F72D0C8E9E3608540F76FF0F2
-:10A490001E1EEEFBC163FC1ECEC1027E0F47CD7BAC
-:10A4A000A8F76BA60EE53DE8FE9D7A2F47BD67C372
-:10A4B000988FE05AF45C1C7DC76B87E1908DDBBD03
-:10A4C0005E7E3F1A6510E6434DCC13895F6BAB6B24
-:10A4D000C46A7AEF8EDB4F8F5447F07B7D8A1FE989
-:10A4E000AE8EEA2FACAFD6FA0B540FF717EE54DE50
-:10A4F000E38BD9EC4EFBFB87631C8F9E323BB6F19E
-:10A50000C4EC48FBB6C5A2FD1EAF5A5E56E4DFB0F0
-:10A51000EFC50DBB2FC9F57AB760FFA74ACAA71BC5
-:10A52000289FAECAD5EE317CFC1F29E3A9654029DE
-:10A53000BBA37CD7F9974ABCAC4B947B10EE692F38
-:10A5400068E397D30F69E397337B9335F57CFF7806
-:10A55000CDFB85672669DA8B03F768DA4B2F146821
-:10A56000EAE503159AF72BAFD46AEAB382DAF86505
-:10A57000F5CDC561F7387DB4BE1AA0DCD07E75E696
-:10A580006F6ADECB58A35D579647BBAE891BB5EB10
-:10A5900052C7CDF66AD797D3AD5D5F32E6E3F2BE20
-:10A5A0007E3E2E7FB65DC9C7E558B0DF338D932D53
-:10A5B00068B7A9F7A9D5F7FE2F376658DF407F00A7
-:10A5C00000000000000000001F8B080000000000D9
-:10A5D00000FFB3E46660F8510FC17BB918186E72C2
-:10A5E00021F84301CF6786D06A2C0C0C1A40CCC6E8
-:10A5F000C4C0C0CE44BC7E714E047B1D0703C34C57
-:10A6000020DEC831F0FE1A487C9D877E76A9F34291
-:10A610006859C181F73708570A3130B40A3330C45A
-:10A620008840F80CA2A8F2554208B6A924657639EC
-:10A6300002F5030024CC7134800300000000000008
-:10A6400000000000000000001F8B08000000000058
-:10A6500000FFE57D0B7854D5B5F03E731E3393793A
-:10A6600064F2200F02F18400A242180284870827B6
-:10A6700021C4A8018380BC54263C43483211A8BFA2
-:10A680006DBD77260411ADB551691BBCE81D1014D2
-:10A690001575A0D1061CE84014B1DADBA8F8A8D5DE
-:10A6A0007650444048C2CB8B2DD57FAFB5CF49E61D
-:10A6B0009C4C48D4F6BFFFFFFDF1F3DBECB3CFD9E0
-:10A6C0007BEDF5DA6BADBDF61EC1329A244E22E465
-:10A6D0005BF8A365842784F4E92CDB0ADA8F9164A4
-:10A6E00042FC2F8BF2368E10EE778EF0A45184BC94
-:10A6F000B5990B98693DBCCF4608AD9FDE343D60EF
-:10A70000CE2264FF08B302EF9FDE9A8FF5C92FBDFA
-:10A71000E714687BD54BBC0075D3BE13CE889D1063
-:10A72000AFB9E5A16BE9F3F69778B2850E45FC93D6
-:10A730004D2485906316C2FE2EB2FA522BAB566D95
-:10A74000DE7F07F45BDE642656DA4FD5EE65D3AEC6
-:10A75000A5F565874402AF546DAB95FAD2FAF200C5
-:10A760001784FA9A7D7FC671DA0A48797028212702
-:10A770007D16225F49EBCE969459F47945606711B6
-:10A78000BC5FB183739BE8FB159BF67F0CFD5734D0
-:10A790008A0379DAFF8AED36220F61637F4B601EF0
-:10A7A0004BA601BC556F88C44CEBE5975649047025
-:10A7B00024D44BA50E18FF614976C03887701C0D54
-:10A7C0009F55CFD071E877D52F706E985AB589789C
-:10A7D000009ED6DDD6394FDA615EB5D260F87EF7DD
-:10A7E0007D12BCB72C50F6B25506F8364B4500E743
-:10A7F000A6CDD2D2A19DFDADD8FEA60EAE630DD9D9
-:10A80000A99EA8766379D247886CEEAC5710A20453
-:10A81000ED0077409A3EACF3F9792E8190D1D03F8C
-:10A820004F644B67FF9430C807FEF7E83F810FF68F
-:10A830003A02DBB23AE9B5D245FF2D77D2EBAC4B09
-:10A84000A59FD09E17DDBF563E0474A0F0D4FB5CDC
-:10A85000583EE24BC372834F46BCFDCA3704CB0659
-:10A860009F1B9F3FE61B8BE5269F82E513BE622C54
-:10A8700003BE527C6F8B6F0E965B7D1E7CFE94AF89
-:10A880001CCBEDBE1A7CFEACEF6E2C77F8FCF8FC0E
-:10A8900005DF7A2C83BE7A2C77F91AB06CF405F0B8
-:10A8A000BD977DDBB16CF205F1F91E5F1396215F58
-:10A8B00018CB7D405F5A867D2D581EF07D88E5AB14
-:10A8C000BE087E77D0771CCB0755BC3B27907C8198
-:10A8D000E2CDA9101715179258A2E48BB49E58CA5E
-:10A8E000EA29B7F9F3255A4FF1D03AC563DFCA70A8
-:10A8F000BE99D6FBD6B0F6CC7B488185D633FDAC6D
-:10A900007DC0834A8195D607D4B3F6C19BFC0571FF
-:10A91000B43E38C0DAAFDE112EB0D1FAD541D69EA2
-:10A92000132293EDB49E1366F5DCB794C90E5ACF8B
-:10A930006D61F5BC8FFD939DB49E1761DF8F3F1550
-:10A940009E1C4FEBE3DB59FBC44BA4D045EB130932
-:10A9500087F5027B7E6102AD17B858BDA85F9920CC
-:10A96000C7E0BF7D626411A1BCB0DD7FB322A4D378
-:10A97000BA145945DC149FFE39580F8B6431B4BFAB
-:10A98000E52F538471B42E91D5D0FE177F05B61FE5
-:10A9900010656C6FF7AFC2F603928CEDA6DA7BB050
-:10A9A000FEAAA8607B72EDBDF8FEAB9282ED836BD0
-:10A9B0001FC2FA41D183ED636B7F8DEF1F943CD8AA
-:10A9C000FEC8DA805248EBFFC179B6005FD7719EAE
-:10A9D00072920DFC1A4C2BA5FCBA8E2373403E1EBE
-:10A9E00000A6A6F2B02E5D5240BFEDFB47DE933CC1
-:10A9F000A7F27632D4973EF54016F6F31CF623D232
-:10AA00007EF89EFB99F8CD585D3F13BF29D7FA69B0
-:10AA100084F7EAACBDEB67DF37E3F5F07C53A1F5D3
-:10AA2000B317FB71F46E5E13BF9DA087E7DB4AADE1
-:10AA30009F83D84F42EFE0098B6374FD84C5655A4C
-:10AA40003F7FC47EFAF40E1E451AA7EB4791966B22
-:10AA5000FD7C88FDA4F7AE9FB074AD1E1E6985D63F
-:10AA6000CF11ECA77FEFE6A598AFD3C363AED2FAC0
-:10AA7000398974CFEA5D3F071C7AFC1C7074E0E7EB
-:10AA80001CC233A877F32A70EAF153E0ECC0CF255B
-:10AA9000ECE7AADEF573C0A9C7CF0167077E440EB5
-:10AAA000E635AC77F32A88D7E3A720BE033F4E0EE6
-:10AAB000E019D13B785EEDA3C7CFAB7D3AF0938A26
-:10AAC000F08CEE1D3C85297AFC14A674E04746788C
-:10AAD000C6F5AE9F5753F4F87935A5033F57613F4C
-:10AAE000D7F56E5E85A97AFC14A676E02717FBC918
-:10AAF000F76C477808EDC7D17D3F07FBEBF173B0EA
-:10AB00007F077EAEC57EA6D07EB27BEEA728538F90
-:10AB10009FA2CC0EFC14229E6FE85D3F0733F5F830
-:10AB20003998D9819FA9D8CFD4DECDABE80A3D7E34
-:10AB30008AAE60F899248CC07586AE9D6E9E7E723A
-:10AB40007DBF7C85A3EFF32E56E75D6E02760FAFD7
-:10AB5000D933A445E1E9FBF61D09B90F9068BBA6FE
-:10AB6000E076C08F835A79D1764DFCD8389D1D95FB
-:10AB7000A024EAEA49C57D75EFF7291DA06B4F9D1A
-:10AB800073B5AE3DDD93ABAB67948FD7BDDFBFA68A
-:10AB90004057BFE2EE1B75EF67F96FD1D5B3D7CF42
-:10ABA000D3BD3FA87EA1AEFDCA860A5DFB55819547
-:10ABB000BAFA35DB7FA27B7F58708DAE7D78D303E8
-:10ABC000BAF611E14774F591871ED3BD3FBA658B84
-:10ABD000AE7DCC87CFEADAC74576E9EAD71EDFA398
-:10ABE0007BFFBAF603BAFAA48BBFD7BD9F4FDED561
-:10ABF000DBDB963FEBDE9FE2FA4CD77E7DDA9706F1
-:10AC00003BD5EE3A768D5AE741AE08FA25FE740937
-:10AC1000EDD5B043C2BAD4D7CEFC14C752F928E55B
-:10AC20001FE9C0223919F992FE51BB21BF6FF99576
-:10AC300011FAFCAEF19E2B5DF4F95D9267B82B869C
-:10AC40007D43F98D236950CA26288DEDF7898CDF65
-:10AC50000B322E0D3E42BFF79ADA0727D0FA703E2C
-:10AC60003F08F2F1326742BB3A8E2735F05E9C997D
-:10AC7000A0DF745F56DE93FE287958DF9FDA195CF7
-:10AC800067BFEB454F1ADA51B59FF8C1CE59D79F30
-:10AC9000CEAB2F21AF709F84FD03E9F7FD97A67916
-:10ACA000687F6689FA19D1E34B74FCA1387E18E4F9
-:10ACB000E1208C3FBAEBF8E6016375E35B32CB75BC
-:10ACC000E35B243ABE8B90DFD77EAE8E4F89309EF9
-:10ACD0009037B9CF717C7366398E7F9F44FDAEE8A3
-:10ACE000F1E33AC66F81F9BFDFDDFC078CD7CF3FB8
-:10ACF000B3423F7F89CDFFA3DAD3EAF87138FF3F33
-:10AD000073A7D9FC332BD8FCCDACDF8EF19D1DF899
-:10AD10008FC0F8C7BA19DF9C3D413FFF2B2AF5F3DE
-:10AD200037B3F14FD65E50C7B7E3F85F7217D8FC60
-:10AD3000AFA8C4F125B3C70DFC2365C4D504E8F85A
-:10AD4000A41F557CA9C02E741C28872452A12164FD
-:10AD50001B3700E1B82B8EF1DB577194DF509FF960
-:10AD6000F1390950CD9947FD4695D757ECC8974022
-:10AD7000EF613BF5B796A8A02E6EE291BFC90673AE
-:10AD8000601085B7B589F7437DF186EB02A05FBD02
-:10AD900066B2A014BE1348189E7FFECB615BA2E78B
-:10ADA000652C97D48BC72251F2D6E1071690213536
-:10ADB00014BE29C004A33BEB9F523F0E1CE38FA996
-:10ADC000DF43A8FFF399C8C6FB0BF5F7A01EA1FE51
-:10ADD0001E3ACEA416BFA3DD1D4EA3F097AAF07FA6
-:10ADE0002A3079FDF4362EE0A7F2F9D58F47A07FFF
-:10ADF000BDE06E1B457A271C65FE245D9DCECB0F02
-:10AE0000746ADF6D0E6CE110BF32E06B3A8A262166
-:10AE10008BD667505C77BEFFC1BEA907392721B723
-:10AE200012454CA5EFDFBE9AEBEFA2E3CE52CCB9B0
-:10AE30006C1D52324C28D724C33496905B1A478835
-:10AE4000B407325D113F8D448D3BA3585F9F55AAD7
-:10AE5000AFB78A8A68A270B54EE7C866DAEFEC39F8
-:10AE6000FA766D9C81A644466775BC528A9374FA43
-:10AE7000683694B9F0D885749EE362DF6AF078177B
-:10AE800089248C7EBCBF0F01BAFA93F1BD792E36AE
-:10AE90006F23BC73448B524AE739A78C0F007F1B8A
-:10AEA000E1FF689F4D31E5D072FDA32231759D8F82
-:10AEB00011FEB91EE37C8222ACF3F3CB8DCF19DFF8
-:10AEC0001C53E9FF29F0072DBF00FEA0F01F55F924
-:10AED000A353AF32FEF09A3DD3801FDA37F204E974
-:10AEE000AAF2CBAD2ABF2CA9D7F305211E11E8B8D1
-:10AEF0006C0E97FB40141FCC56F96059839E6F6E01
-:10AF0000277E313D065DE66ED87C6F9ADC757E9FAC
-:10AF1000A87C33FFC1FD889FAEF36474BA43A5D308
-:10AF2000ED35FAF65B55BADEAED2754EC3C3AF51FE
-:10AF3000F541E6C90111E4DDFB538D9E111D3D3D38
-:10AF40002A3D8D70DEA1D2F38E1F337A1AE18DA8CF
-:10AF5000F48C349C13C980AEF01AE15B707797F9DA
-:10AF6000605CABCC1F9B9EDEA6FC5547A39E57059D
-:10AF70006F5875344ACE566C9FAEAB2F0FCCD5BDF3
-:10AF8000BFACA14CD7BEA47EB9AE7DD1FA3B75F55E
-:10AF900032FF8F75EF2FB8BB56D77E7BCDFDBAF64B
-:10AFA000F9E50FEBEA733D1B75EFCF9EB359D73E22
-:10AFB000ABF4195DFB8CE29DBAFA7465B7EE7DD3F4
-:10AFC000BEAB6E06FE7CEB3D9E803D71C1FD05C6AD
-:10AFD000332FB84537BC73D427235F1FF30DC1F25D
-:10AFE000B8CF8D7C7FD23716CBD6A6663BAC137418
-:10AFF0005D5C4A12086932CDAB5DDF0FD66982EB2A
-:10B0000069C8E4A9F5D37AB34946792869904878A4
-:10B0100024211C2C362A1CED7C547BA487F606AA1E
-:10B02000F893BAB69744623FF73E527605F06577DB
-:10B03000EB03FDCB00BBA74DB5EB8DED951C298D2A
-:10B040007E4EC81A84C36A627647A5C4E4BF7257AD
-:10B050007A0171423D3CB8E672E3052993A7029F4D
-:10B0600064EBE47859C3353AFD4E209ADC07F86D5D
-:10B07000A4EEF98AEDD7EABE3BB59F47B8AB41577E
-:10B080008C8365B1F43313E8E17073E68C6100A73B
-:10B090007214EB4D7DD02E3CE52B5E757410D0AF55
-:10B0A00014CBE3BE39581EF379B03CEA2BC7F253F8
-:10B0B0005F0D9611DFDD58FEC5E7C7F263DF7A2C1E
-:10B0C0003FF2D563F9A1AF01CBF77D012C0FFBB6A1
-:10B0D00063F98E2F88658BAF09CB569F82A52677A3
-:10B0E0003DF1DD71751D3E09FC1783CFA43A7FED5C
-:10B0F000FA099D7C16C7DF877CA6E1B9A4C1ACF232
-:10B10000438A8E1F12C097433EEBA1BD4154F9B054
-:10B11000BBEF63B77BB7FC6BF86DEA0FE4B74E7E0D
-:10B12000CA30F053764FFC348C8FE2A7A92617B3B0
-:10B130007B547EFA19CC23865F310F8C903E51F6FA
-:10B140009A926F82756CA5BA0F421F60FDAC3A7679
-:10B150001D7DB705EDBAC0105837CE0EF9DB60D8AB
-:10B160004738FB21257E56F7F333F249F77857D05D
-:10B17000BF591AA0444FEADA6E8D6378B59A483108
-:10B18000A1EBDAFD839E722F1C8A758124C2F70120
-:10B19000F774478C7EA9AD0CF8ED09AF758EAF72D0
-:10B1A000A0BF638FFD3D0FCAA926662FC735F36880
-:10B1B000B793F0936EC06FC7BA6476A741BCBD7DEC
-:10B1C00090E442BB814CD6E3CF5FA0C3DFFD1447C0
-:10B1D0002DB8EED6A721FE067E3538BD17F8EB490F
-:10B1E000BFF784CF8530EF7F013E7BD28F3DE945AD
-:10B1F000A2C82F34D1F9B7ED1B96FB800CE35E1E7D
-:10B20000DFDAFE9A119E5F7E473E6E4BD1F8B8257D
-:10B2100093801FA4CACBD9C62BE3812E1DFDF44019
-:10B220004FEE779F6482FF7E3A4BDFDF7DC6FEE202
-:10B2300025C20DA7E33A2489C453BF92F76CE3D12A
-:10B240009F7147FC1037D86773D7C9E0379EFCAFB2
-:10B25000B00C3DEBE30B670F3DE9043F6C651A5FF3
-:10B260007334061DB5B22A9855638FF6579AF4F5D4
-:10B27000B3F55C7110E725C7CF1C06EB8CABE6A8D5
-:10B28000087A3F0D4BAD9F9569128E73727B763CA9
-:10B29000F3FF024C9FEC48407D73D267C1F7FFD9A2
-:10B2A000F074D78F060F218DE4330BE873DA96DD47
-:10B2B000FDFBDDCA83705E82F82909895F81BF6961
-:10B2C000A5FF7F3B00FA15B0AEF5EB0DF27EF370F3
-:10B2D00078BE43371EFD4ED6F68CE1BBEEE54E2020
-:10B2E000C734BEA7F4FBABBABFBD62BBB5466FC7E0
-:10B2F00026E8EADEA6F41A9D5D0BFF00C3BD8613A7
-:10B300006009AB54D9B04DB0AF077EDA03C149F044
-:10B310005F38F65E9525227964149716E0D385632D
-:10B3200035FE9767FF99EAA9136F8A04E48C5CA243
-:10B3300050E5A9AE20F29B8998687D91FAF6C2C6C5
-:10B340001525B06E9D78F926F44316935227F8C759
-:10B35000E5A43E0FE2B5A789A918E4F33479C7390B
-:10B36000324A1EAD82849D2E5AAFB7E3A97FAFABA0
-:10B370002F6BD0D797925B5260DF7EE9069104383D
-:10B38000D01BFAF6AF7917F6BB8CD4AC8375FB579C
-:10B390006ABC6BA18B0819546F55FDF6F1BC320ADB
-:10B3A000874B6071166D1F7A7922F37F2A66062417
-:10B3B00085BEFF59E3C85BA906A2DF07D6C17EBCE4
-:10B3C0007F3A716F235DE9F75DE137C2ABD9035D69
-:10B3D000F6C3553892B7734A20861ECB14382667B9
-:10B3E000AABE2B105CBAB8C73443FD7BF35332D1ED
-:10B3F000F1D31EDE93278C66FC03FCC009ED92E7B7
-:10B4000087F49FD6A5FF827F6AFFFD68FF79BAFEA9
-:10B41000A7FD53FB1FD805FE79B1FAAFFAEDF32F64
-:10B42000FBA93EA978F1974E42D7C913427D8A9B6A
-:10B43000D2B572DBBD4E8596C705BF13F8F54480C3
-:10B440002F8E45EF87054E1542C5CE41DC0DFE49D6
-:10B45000FB3FF9ECCF301EF1D536D185F1B4EDE6E6
-:10B46000B099CA6175E3F2129283F523AC7EDF19BD
-:10B470001EEA4D7AFEAB78FA9729901F4239458D26
-:10B480002F85D19EADDEFA7911AC4F5ED28E7264FB
-:10B49000FC0EC6BF9888FAAF4C8AEFDA4EE1C4388A
-:10B4A0008157C58BB7F16767782794377C01FA829B
-:10B4B0007A22E8C71BBF2B57EDD4358223F9988D2C
-:10B4C000FE7B0C19037A51C30B09303BB5EE995F33
-:10B4D000E71CA1709DDAFAA6938BC297264F67836B
-:10B4E0008BFE738FDCBDDE6DA5F2166D0F69EB96DA
-:10B4F000DCA4DAD72156568A6127E4F3546E16DDB0
-:10B500007EFAB8F2F9279F7A0CE2997F32BB07D115
-:10B51000FE573CFFDAFBE3697DC54E31B9844DC36C
-:10B52000CEA574D2C74BFFBF3BB7931E15BF794D55
-:10B530009287B1E7F72476D265C5CEFD1219D615EC
-:10B540001F9383FBA5883D067D82478AC05EA87B4A
-:10B55000E6BF2588339ED8C791D4AC18F8DCFC1A16
-:10B56000DA038027A4A74AAF0EFA19DEF752BA8091
-:10B57000DE36D2CBF8DE2255BF40BF906741F9FBE3
-:10B58000853D9007F591D90D78287F619513E6F3F5
-:10B590008550C3F8FCF17B53409F958BFE141796A2
-:10B5A000EC79F9133F42FE5BF6F68F5230BE4494BD
-:10B5B0007413AE45FE7498E7924DB3709E4B8907A5
-:10B5C000F9B0FC71BE3440CB0B0229DE19434EACFE
-:10B5D0002293932FB650E2D2797E01FE24E8EF77D2
-:10B5E000F8C036B4BBEF24A00F7EA4CE855A0C5809
-:10B5F000BF6061F4FAABBA2E10B03EA3F977EB7DD1
-:10B600002D40A793FD9554D877F112C1AFE283FB8B
-:10B6100096F6CBBF3D2595D189C8429EFA1D5DF7B0
-:10B6200027C37378BF4554AC39BAEFC8B7599DE307
-:10B63000AF56C7A770C7C17AFD454A6CFB354FD4DA
-:10B64000F4005DB7A3F82C4ADE99FC6FBD9FC9BB1F
-:10B6500026FF81E9C5D07EFE309323F80ED6430A3B
-:10B66000573815DBF7CFE4503F503F3A969C6F15A3
-:10B670005539D7B71BF985C22F70F1517C03E324EC
-:10B68000221D70DF65E906FA7D941EF5C2B8CEAEC4
-:10B69000FD6A72BC4CF35B45BD3E209B981EE8DE04
-:10B6A000AEF2239E2AC5C0538F81FC5279F5CB2080
-:10B6B000BF6229CCFFCB1DCDEFCFA372FB655093AA
-:10B6C0005BBD5E35CA6DF9AED12496DC7E69779399
-:10B6D00098724B9FC7945B7B04F9F9FFB45ED5F079
-:10B6E000380CF0784D271E353DD91D3E8D7AF290ED
-:10B6F00020235E8D7A92FE1D26795DF951E3438DFC
-:10B70000FF2A9EABBA02F451079F6A7CD8C1A71AE0
-:10B710001F7689EFEAF0686CBF00FB3414AEF9962F
-:10B720008DD38E5257D2D24E70DF267F268FFBAA42
-:10B7300096F384E5811011F3433F30D58C063B75B9
-:10B74000E2DF6F3D7D1785773EF18B2C2FA05E44A5
-:10B75000BBFFD2B7DF4EA0F399A7E2793E45FB5479
-:10B760004A973902178EA370CE15883F3E11E2B773
-:10B770001CF9340A8EF9E5FA3AFC4D4CE9ECA7A71E
-:10B78000F7BFAB9FF27DCBB7295D3F1D44C8BB50CF
-:10B790008A38BC10CD57D381AE147FDE515C600077
-:10B7A000EAA988501AE577BD2032FBF3EDC219A350
-:10B7B000C1BEC99F3D2C9EF1FB60F47BBDAA3E3B00
-:10B7C000EB97E341CF9F0D65A37F7BF6D02247AC7B
-:10B7D000BCD06695CF5E53F75DDAEC5C3D4FF9BFA8
-:10B7E0008DB4A37DE3B75BC9B618FB821B454D5FE3
-:10B7F000AB74A37F3C1D7F8ECA8773E9A7F1B95153
-:10B80000749B39F584E0EC4A07F8FB34CA0FFBA1BE
-:10B81000F805BE06FC365B2345A531E279CFA9F8D1
-:10B820009B78E06BCCCF2D0CE50B80C7423BAF8BF8
-:10B83000833CA9C9EB503214E09A7860F9CF4753A2
-:10B840003EF61EE2DD908FEB0D9D913C31FC6123B5
-:10B850003EA17FB0338F882EC4D77B62E912C0EB44
-:10B860007BB3AC04F635DF95DC55B1E02C33B3F592
-:10B87000662E29BD308AFBBF0FBFF9B31DE1028AD6
-:10B880008FB37696F7DD95FF98DC9F7571815A0E20
-:10B89000F89067F5642E0071B422E2F9F9040EE520
-:10B8A0007D52B4FECA6F9AFE3CE4F55487389789FE
-:10B8B000B6570B1109F8D8DBB45300FBFD269928C5
-:10B8C000188F106A86CD8C8A7B1D1105C457F3DF53
-:10B8D000E6DD0EF83D37D34C002E65E81927D80178
-:10B8E000E74223510EBA9BD71F7C645AA108FD1072
-:10B8F000E40F233F1425DB74F55993493F37A5DB4B
-:10B90000447364953B06FDEA24C667BDD66F96FF77
-:10B91000CFF4DB04AADF185F8BD1FAED2689F17D25
-:10B92000947E4B8DA5DF56D6CAA9C0172BF766A704
-:10B93000025D57BEB1A44F2CFDF6BA8FF9F76FA880
-:10B9400079E66DFDA87E1B1EA5DFFA51FD1623AE1C
-:10B950003B5AEAA57EB3FCCFC8DFEBA0DF62CCB7D1
-:10B9600058C59FA6DF8A43B5A8DF8AFBF1BA7CA938
-:10B9700049524FFAADEC97B3B02EBA6D31F807F0DB
-:10B980000AFAED0D55CFC138A0E7FE5D727D273D67
-:10B9900057D55B3DF73F84674DCFADECCFA13DD38D
-:10B9A000950F999E5B99C5F4DCCABD4CCFAD1CC404
-:10B9B000F49C51BF1574D16FECFBEA21F47BF423A6
-:10B9C000B37E7D1B6D2F9923BA2DF4FD12593B9F39
-:10B9D00051333A5ADFFDBBD48DBE739FC1732E3DE8
-:10B9E000E9BB3F82BE1B847A6C20C891913F6E1CDC
-:10B9F00068D3E5D3BDF7F5B1E75E0479F9038FFEAF
-:10BA0000F70726E627EDFBFAD84890BBF7001EAAF9
-:10BA1000EF9E51F9AFD5E7477D3A792893F7AA7B96
-:10BA200018FEAA1B3936DFD57C408675E06F17D12A
-:10BA30008FBE7D2FF3A3679B5BFAD8C0CFFF5F2239
-:10BA4000CA25FD2B298BE28739172B30EEB92BCE77
-:10BA5000B905FCCC3902B1801DBBE0D08D27C07E7A
-:10BA60005D70713DDABD0BE07922E9C8FB98DBA17E
-:10BA700027F5F6EBBCA69DAF6590AEF91013CD8C03
-:10BA80002E13577181CD595DF323A85D86F92DC61C
-:10BA90003C89DFABF39FCD47105FE48F7CCCF8E5AA
-:10BAA000EF8D787233BC54ADE6F578AAE162E28995
-:10BAB00052BAA42CA5132FB7BF14599701EDCB3957
-:10BAC000F4B78CF3D6F0669CBF8647CDBF59A0BEB5
-:10BAD0003F3F7424669E8886E72EF9221ADE0DF811
-:10BAE000784BD333D7906120971F983C3F1F0D7C34
-:10BAF000F47B8A170AE7AD7307E9CE2BBDA3E26595
-:10BB0000AAE748618A0C782435C067F3CA77BE96E5
-:10BB100042E777B392950B21F5597F933C108F68DC
-:10BB2000B6B6A31ED4F8709499C98559D52BEFF5F4
-:10BB30007515E27AD3C4B950BEC2063DA7E699791D
-:10BB4000EF61F2D7CCFDF7BA8C518867582E489137
-:10BB5000B65E015DE83FA786185DBC4017FACF6965
-:10BB6000A4FD20E0BD3A997387E1FDA69DF7023F51
-:10BB7000BD6EA5CF41CECB39F716860E7B7ACA654E
-:10BB8000F95888C5C718CCC8EB5C3F17C07B895DE6
-:10BB9000ED9389E696F7008E89546E36C3C300FD97
-:10BBA0002F8AFE46FBC5C8073DE50375C7EFB92AD6
-:10BBB0009E5F073AD801DFED12D843DE305B7FB4D9
-:10BBC00076AF201722DE343A34D1F56514A38329E9
-:10BBD000069E6FD6EA2A9EBD214E84EF6FA0FE6FAF
-:10BBE0001207BB7E5F1FD4F8DD2C77C513C415D2B6
-:10BBF000A3F406E8B7E87DCDEAA6B7115F37AEA695
-:10BC0000E699DC155F1A7D400F5E0E6FDDCA4FD3DB
-:10BC100091987961DF557E4699F5F2B3CFDAFEE669
-:10BC20007088ABEDE550AF9050822E7E30D3CCECD7
-:10BC30009666AB07F9BCFD0DD1BD45EEAA7FA6A85F
-:10BC400074017F25FA7CE2649808E84D97957CA6FC
-:10BC5000CD7B00E3B7E8F5E075AB07E9D75DFF33CF
-:10BC6000CCCCFEEDCE1ED3EAD7C37890D728EBC755
-:10BC700033AE475A5CA9A77979D471BFEFBCB471D0
-:10BC8000BEEBBE8497B4603C4EDB9FD8C37B768905
-:10BC9000603F1673BA7D100A39EE6FFE13FABF5972
-:10BCA0001ADD7DFF103F0A533CBFBEE3498C639F02
-:10BCB0007EF6C834909F15AFF0C442E5AF75878318
-:10BCC00084599E8804764245238FFB5D4408E7CD66
-:10BCD00088B233A827C3F0F1A203F55EC52E73A086
-:10BCE000847E5FF1F26739107F6B5DC3F49FFF596B
-:10BCF000951FFD911CC807A810D8FEBC913E8FA8C7
-:10BD0000FC796AB76D0EE86F6E3B3BC75B119C2DEB
-:10BD10009AA3E20CF79B4516E7DE6DC33C6CFF333C
-:10BD20001CE631037CD1E748B5FCD053CF30BD5C75
-:10BD3000D12406E03C70C5F69DAD1017AFF8D08C4D
-:10BD4000F6AB77FB1909ECD3C92F3ECFCE1B37F1E9
-:10BD5000BA78689738E4763E6C86F8596315EA013C
-:10BD60005A3F82F5A01AF7FB8E71B2152FEE7DD9DE
-:10BD70004F51B8E2374F3BF15C70CB3627C623B743
-:10BD80005F7E5FA04BDC3178BF1A779CFA05C1F566
-:10BD90002176DCF1A4CA2721B33EEE48B627613CE8
-:10BDA00092C299571A237ED1C1FFCF5F7802F6CD98
-:10BDB0004EEDFAF20980BBF29B734FFC94E2932A9A
-:10BDC0002017ACDBDE67DFC37D06EDBBF7557DD208
-:10BDD000FACCD3B84FD3FA27B31B7A6BDDFB4526D9
-:10BDE000EC53B4EEFC3A05E2B8ABF74E417F6DF58B
-:10BDF0004B9353490C7F402B817F03BDD82732D210
-:10BE0000ADB9B13913E03C4DE90EEB77473C3958F9
-:10BE1000C5E2F4B21A47DE117B5FAE4BDCB871C6E7
-:10BE2000CDD7C13ADE28BA65D28BF8F1614ACFE1AD
-:10BE3000BDA0E30E759F2038F5B2F1E3D3F00F4AB1
-:10BE4000AF0B667D1CFE42E392FF7C0CDA1A93BABC
-:10BE50008D1F877B813F6DDF6FBF59211690A35DDA
-:10BE6000CF61DC1EE8477D0FD2FAFC854C88BB1CF5
-:10BE700017DBEFC0FCEBBD66CCA3AAD8FB01CA530D
-:10BE8000EB4B6FE3BE1A51F7DF5A49C71FDB27514F
-:10BE90007D3AEF56078B3BAB7480B8B4ECC4E76ACD
-:10BEA000FC99F1B51697EE2E1E3DD63280EDBFAB54
-:10BEB000FB91555BFF2C1143BC9F1B0BF43A72D9CD
-:10BEC0007D540D0F2EC0C398E8FD96D8F1FF8EFD6E
-:10BED0001603DD809E608F75ECA7D07A3F88AB0794
-:10BEE000B80F62EDDFB56E66FB34AD62ECBC456D3C
-:10BEF000FF65A4C5B0EF12E8DDBE4B4FF3F8AE7896
-:10BF0000CA0627B44F577C9DBA145BBFDF6AE1D4E1
-:10BF10007B03BEE7BE7E2567CC1B98057C59D57890
-:10BF200044027B4A5BDFB4F99E52FDE753CFF278BF
-:10BF30004E645DB019F5BB517F5413163734C25BA4
-:10BF40006E617AABBA89AD1FA776390276DACFA9CE
-:10BF500003BB91AFAB771C91FCB4BF83DB7F234560
-:10BF6000A2F2AC60FD0844C17FEA85FD396C7F898F
-:10BF7000F9EBC671EE52C7F186628FE3DD71463789
-:10BF8000CE0A7F5062E77E2E3FDE4941990DFD9D2E
-:10BF90006C1109E4FD9F0CF2C58118E3CFB5885AF6
-:10BFA0003C8BC90F5D47F11CA6839DBBE41325B4F0
-:10BFB000BB573BC67E08E7FD573B2419E21775B512
-:10BFC0002C2FB5EEDFDC6940EFBA845B713FAEDE4B
-:10BFD000805F57B22B1FE21AAEC2D251C0AE46BD2F
-:10BFE00093A09874F0AF7614A7CA14CEB5AA9D4654
-:10BFF00004379E0BE59D45C5301FDE65725963EC25
-:10C000003B88F652E289C28BE8D29FE3249746CA66
-:10C01000D08F967F53696939888D2E05538C85B1F1
-:10C02000ECDDFC992E9C77DB0ED57F5088EC4A61C5
-:10C030007964B08EB4ED8ACF21C3F143A2507EB4AF
-:10C04000A9CFB91DFBF7835E5AEB244A0295338AC8
-:10C050005599CF86F3AC232C5C36F0E999FF7A85AD
-:10C06000F66B0DF1E857B4D9B57C522501E4CC4606
-:10C070001EC4BC4160E56F933AE134E613127825A3
-:10C08000EA3E8D29BC1DFDA1B39B587C802757FF3C
-:10C090007A028BCF9100C0AFAE2F2B5438CF12E273
-:10C0A0000EC3FB3B1C180F58F6C622941FA0433446
-:10C0B000BE928AF5E75E1BACCE1CF067365A55BFC0
-:10C0C000C6AFB4C0399BC56ABF7D4AF5E762A918FF
-:10C0D000FA415E97A8F2FAE5D2A243988FE6598A10
-:10C0E0007A3E758EFEDCAC314F4B20AA9F1C60FE61
-:10C0F0007397BCADA6CD08B7317F6BC5767D5DC3A8
-:10C10000E327A037AF027412FBE5E2803DE237324D
-:10C11000F8D713467D77FC9AD3F4F8B5CA7AFCDADF
-:10C120008618F1A7C7AFC3ADC797E6977687DFF844
-:10C13000B1FA73C8FF2AFC8A56D58E54F14AFF4AD9
-:10C140002D294C6503DCE94218E5C2284719F63071
-:10C1500007FFEE9F1CA8C5AFDC0ED4EF69EA7CB8E0
-:10C16000C5EC3B1BC8110FF0BA518EE02420E879D2
-:10C170001BF9D875CC0AC4FA8C7C7B4DF7F45C357E
-:10C18000FDD5230BE9579B807F87233FB0F3BE8902
-:10C190002450970572EA76C1FA1DF459DC8B45B834
-:10C1A000F785B8170F82FB5E5C583EA4E6ABB40D72
-:10C1B00025786E30183E9F02FAE9A1DCF669A0F7F7
-:10C1C000BC4B4829E8C11FC5B1F3030FA865BF38B0
-:10C1D00049D5AB856F4C82EF43A20CE7D5DB42DB40
-:10C1E0002C83A0DEC4E33D2ADE84FAAB60FCD6904B
-:10C1F000C8E05A6C090C8238C85E11C76D5D3C01FD
-:10C20000CF6576D86F21962FD216FACCB9284A9FDF
-:10C21000B7363D7A15C4B9369A62E7A94CB19A7E11
-:10C22000D8FA1BEC92B737C5CAF2EA1E1A40E7519A
-:10C230003DFDACBA0E3379B856A5F3AB4B6FC4F9DC
-:10C24000BF14E26458478AF8DB6E1A46E739EE3DC0
-:10C25000418DCFB078E528F5FD3AD02FA85FEBDF10
-:10C26000E5E9C3DD470502E7F446D52C457FEB152C
-:10C2700027E573CA17794A7024F06D612801EFCD64
-:10C28000F17E4CD0AE1FDD22E8F8334F5D57F3222C
-:10C29000545EC044F950DF3E2E2218ECA0000FFC83
-:10C2A00075ED71FDF38556D5EE729214E0F30D979E
-:10C2B000780EF25EDBDA897B0D85BB6D715F84A33E
-:10C2C000ED3C9CFAA5E525BE38D67ABFCACAF8620D
-:10C2D000A344709DD9B8D48EF1C5034B2BAE80F525
-:10C2E000FDAB1F7BAE88758E3C4A3FC5B37C2C25C9
-:10C2F0009E8C05FE5ECB31BCD7A797C6C8F7D7F892
-:10C3000059E36F8DAFD397C67962E5357E63657665
-:10C310005AC1D2219C04FEDA3E0E8FE3B6AEF15C28
-:10C32000F6DC8D9FACC90078BC4DE7D0EEB6843802
-:10C330002596BDB1C1EAC4FE5BD7F86B218FEF2E05
-:10C340002A9CA027BBEF7703FA5B3F81A02C7C6778
-:10C35000A92FC373BC4B2C640BC4BB85FAF45B1CC4
-:10C36000C0FF936F5847E17DACD484EBEB46D18D91
-:10C37000F0FBAB08C1F8831ACFED378D6C8E3ECF42
-:10C38000FC8435FF592BA5C7B35617D225C9E3E660
-:10C39000007EF73FFEDB09F2DD76D18C74ECABFA60
-:10C3A00043DA77AF5999DD36334ED90ADF93F26419
-:10C3B0009413B7C7E95E3C12EE4DA0788F92A34E5E
-:10C3C000FAF9F1BB440FD571149E44BB09F99228C8
-:10C3D0008AECD2C529FD28479A5C903047208F4DC2
-:10C3E000D3AB5C880B3BA81C8CB2D8C3E0772496F7
-:10C3F000D3795310ACC4C2FA6B114E759CCBC63CBA
-:10C4000079CA977970388A6048141271A17F4DDF1C
-:10C410006A7A7A6D02417959FBB010A8A3FD6C12BB
-:10C42000225688AF64297201A41A250A329E17EF9A
-:10C430005F4E30FFD296FD784287DD42857EC4375D
-:10C44000FC8258FB797C9C862FCF1F406FE41C6ACE
-:10C450003F00E68DDBCAC673BF66413BBD437FA884
-:10C46000F65891BAFE8EFBDCC4F209C29348F43E42
-:10C470009B517F68F6C9B8EB226B60BF68DC9F18E0
-:10C480009CB45B05BE1BADCEB7439FA8EBE69810EE
-:10C49000D527F4FBDCD0C866B8072BF76326C75D49
-:10C4A000F4C9213F0FF8FBBE7AC4C81723C2542E2B
-:10C4B000D5F6A132DCA7E1EAA843FB1983DE499E49
-:10C4C0003E2A15ED5C95DF8C78D6E4DB28F7B9774A
-:10C4D000BB9BCD0C2EE6471AC6215C271C7236E8A2
-:10C4E000A5B778B0F7DBF2291E285CBF02F9A3F4E8
-:10C4F0004B381FB801E6BF2174BD15E4E47BAF27BC
-:10C5000021FA75549EF6D3BC273EAE0FAE274EC01F
-:10C5100043F5FEF3EA7A12467A77C8019593E878F4
-:10C5200089C6FF467ED7E4A30E2EDEC8C673760406
-:10C53000D6599E0BE2653066B2C90578D5ECED3A66
-:10C54000D5BE25FE74B4FF56BB88BA1E6506804F63
-:10C55000EA44CD5E775BA2E353AB1D05A997DB4FA1
-:10C56000F55EA4FE59D4391BAFD08EFE9BF7A28492
-:10C57000CFBF37FE9A2814793AFC8D891BDD157FD1
-:10C58000F17184B0FBC2FE9F9FDF0C237FDC277715
-:10C59000CEEF5AE2792542F547DEAAF57536193F06
-:10C5A000399C96D7552F68FB9FDDE901A3BC8FA965
-:10C5B000AC6FC6704B0FF2EEB5A9F8256406E8B370
-:10C5C000F1616AB7647595FFF3EAFCBC3686F7B68D
-:10C5D0005BDB07833CADE73D3571682F464C26B0E9
-:10C5E0002B7613B47BDCFB8F3A51DE5B9274EB4FFE
-:10C5F00057BBC08FF2A9D9A79A5D6A7CAFC32E55ED
-:10C60000D71B2D3ECA355179A1F03C19E7F1031C27
-:10C61000752EE6BFC20157D0634F583D75C05F36D7
-:10C620003A9738D82F1912CE62F196B04E3EBB938E
-:10C63000479B41DE82143FB0FEF9E9FA3788EB1ED2
-:10C640009EB171090C5EAA85C0BEE99747D860D536
-:10C6500004F3C7FBE5B0FB6BFAE5B2FB3237C73139
-:10C66000FB658BA17CC25AFA18CC4B1488DF9CFB6B
-:10C67000FDE10650210EF9649CD200F8B0142B386D
-:10C680008F0C17717394DE19429083BC89C44A9948
-:10C6900063F147D2B9FF48FBCB2891F3813F3206C3
-:10C6A000123C379A118A7D9EE89538F187D9EB8D37
-:10C6B0005DCEC1BCA2CACF4189CE37A9849D83E992
-:10C6C00088FB50F001BFAD8E5B71B2AD17D83EABA9
-:10C6D0003F81E1D9E8BF01C1605E825ABF57228223
-:10C6E0003511FD2B3FF0AFDF6441FFCA46DC41D07E
-:10C6F000B71FC4B1F8EC3ACEBD1EEABF10DA2D70F8
-:10C70000CF8F26379A3C3C34E116B7405F755E7791
-:10C7100036077C5F2A17EF009E5B279C1DBC1667BF
-:10C72000D29EC9F84EE175F9F61AFD9A441DFDAC8A
-:10C73000105789D6F30E6908D8EDAD5C9C1BFCAA96
-:10C74000D6E51C8397B3A8E71104DD3CD36CCC1F5E
-:10C750006953F5E7DFE3B2901FB5F584CE6F3DC6B0
-:10C760007F0DF3E838876A38776A3C979A96DD112F
-:10C77000074AC77CDC5209EE3223674336B4E3BC78
-:10C78000CEF64C12E3BC646AC41AF35CB05652BCD9
-:10C790007D0D784B156B12401FA7DECEF488111F5C
-:10C7A0006D9C7FC441D847FB8318331F452BD3D2E0
-:10C7B0006E4A584CDF4F4BBF014BED79835D8819B2
-:10C7C000574CB2713FECDC6403B118FCCD241BED77
-:10C7D000EFB4E79DF71514FF768CBB37C431BC3737
-:10C7E000C431BC37481A3EE57890BFCEBA5B97F7A4
-:10C7F000B4C1674910200FD19F8EF2B9C4C5E8DDDE
-:10C80000F9BE82F64D1FA2DC301794C406916C432A
-:10C81000BE67F121ED7CC8AF7CCF2440BE94DB968F
-:10C82000A5FAFB1646DF0406F7F90D5370DC14B2C7
-:10C83000C63A98E27969A9C90D71A3D30B3F72C2B8
-:10C8400091E985192D79200FA7798F1BE6974A98D2
-:10C850005FB86C8E1408D32E931BA8C26274BA0101
-:10C86000F73BCB4C31F3AEC7D8D8FEE9D138179699
-:10C870006969D3904E9DF59204F04B8C7C4AE53566
-:10C880007DF1A8CE73CC946F145B0C796B134913B4
-:10C8900087EB5B18F195ACB1B3AAB7357949063986
-:10C8A000847DAB52AA47353A0F505F4DC1B828FE80
-:10C8B00071A1D7BF067FC3795D01EA454D8EC810CF
-:10C8C000A6E7ADA077A3E2A16D7B3FE80FFB8E9FAB
-:10C8D000FCDB3907EC3BFD556877809E3D7ECFBB86
-:10C8E0000E38C7F4C93D2C2E7287C14F5B6463FAC2
-:10C8F0007F8FAD741EE07781EF1F799E287E2577AC
-:10C90000B3FD93E501DE70DE5D7F6F505530C97079
-:10C910008F901FF15AA5DE1F66A4C7461B8BB72C4C
-:10C92000DFB159CA90617C4F258C7F5CF5438F370E
-:10C930003AD0DFD1E059B8638404BED95F4366754D
-:10C94000FFBD4564EB875202FB671E156F46380F2B
-:10C95000AAF76A2FF925CB8F29A363DD4DF5B02700
-:10C96000C4CE7B18E7B1E413B92895126FC9FD1C3A
-:10C97000FADDF0FE3D743DF3DC7D1FEEB319E7D91F
-:10C98000F55E1F05FDB3652ABD8DE76D9785D83E21
-:10C99000F862E241F9EC72FE36C4CEC518E38D6749
-:10C9A0000F65DB000FBFB0A9F1C43C3206CE6DEFBE
-:10C9B0003A3420FE72F7569F52EF8B827BBBA13C2C
-:10C9C000EE2358CE032390E2BF32F4F65DC05FD56C
-:10C9D0004D3BF13EB4EFAA8FAA42279C904BADE9A4
-:10C9E000256A876E03F9208B399D7D5ABDF99CC459
-:10C9F000FC6A869FDBD4E7B7013E7220DF5BFED97D
-:10CA0000044AEFDB2AC5F3D1F7A53D6FD3EFC3F797
-:10CA100076BEDA3CB5796BED556A5E9CF13B4D0E06
-:10CA2000E6A97CB978EBF4757D298AEAF67E91A9AE
-:10CA30009E93C3F3421A9F2D23A545E931F849A3DC
-:10CA40006F07DF847E8EF3D3E8BAB8BE4CC5833F50
-:10CA50004DDD4F4C837895918F7A3AA7DD2A463287
-:10CA600041BE8D7CD2DACD7D28211BB32F16CB4A57
-:10CA700011C4CFA8F9BBCE1565DF1C17EA0FFE1451
-:10CA8000E46E2BE3FB0E3D084E31E8F737455CFFC3
-:10CA9000573AE454B8FF0FE9370EF213CC7E784FC3
-:10CAA0001BE7984F51068A80FF622C4FFA4A958106
-:10CAB000833ADB976E3CE704FBBB6D08C1B851AB12
-:10CAC000430FEF691B8F7AE3B44A8F4AA1E59B3F7E
-:10CAD00083CEDADA827917C72EA971A74BE6E2581E
-:10CAE000F3B4D839DDBD7877A872A8F9350B54FABC
-:10CAF000DD1162FBE90B374D477A74C9BF54FDA1C4
-:10CB0000B2460EF58E913E4BDCD7633EDAA2403E34
-:10CB10007EDF855EE441A4BB916E77DA5DEC1E3763
-:10CB2000A146827BED8E6DE270FF7185107BFF73F5
-:10CB3000B6DDF49DE6639C4777F02FDB5ABBAE2F42
-:10CB400081F98F9080CF8DF06BF35F4214A6A7D44C
-:10CB5000F976372F1299C4F234D4757F399C5B81F2
-:10CB6000FD93077996CFADC6A134F835788DF328BB
-:10CB7000E22BF17C415B038F79D977F8D97D067779
-:10CB8000ACE570FDED8E4E9A5ED1F67BAA9BCA3065
-:10CB90006FCB43FB013BB6ED63C2F629D67378CF6A
-:10CBA0005BB7F40CB17CA5EEE84908A3DB624A3719
-:10CBB000F03FBBDE9F90AF0C8CDE270ADCA00C8C14
-:10CBC000DEB72241CC5759B17DBAEEF98D76358E5C
-:10CBD000A5EAF59EE48FD424C48C6F69F2A6C99FA0
-:10CBE000268F77DA65666F0A81831959809F87D10E
-:10CBF000BFA1FA7A9E9DF93D0FCDA5AF546F3CA71A
-:10CC0000DBA7583296D16B095F82CFBBD3BB140F21
-:10CC10003ABDBDD8AECFC3F8A1F3D1E6A1C98936DC
-:10CC20003FA39C18BF37D2438BEF19E962A407C01A
-:10CC3000097EC65B7B6D813514CEB73806B77FAFF2
-:10CC400015E16E4D9BACC0B9CDEAF4F958FE013E3A
-:10CC50004C07FBB0B4CE8E76AEEA878DEA5D5C22DF
-:10CC600057B5CB5EB22A23D9B9A7D224E09389B5B0
-:10CC700091191617218F3E585C04F7A44E7C383268
-:10CC80000342F1BF7EF04656DF1679D7E286FBFC01
-:10CC90004B8A0A69FD71D02FA02FFA95DBE0FB6E5D
-:10CCA000EBC473F9BACCDE1F652E9DCFEEB166EDF5
-:10CCB00095D43EB3D0F5AEF2F0E057417E2B5B4AFF
-:10CCC0008A212E54091178BADE5529CEB02D87ADB0
-:10CCD000FBE3E97B1FD93C4FD921EE76712DAE8B5A
-:10CCE000958705942F7288C567053A572BFD6E6DA1
-:10CCF0001CB593297ED7265ADCE017D3E77EF09740
-:10CD0000D7262AB21CF55CA31F7C0770AC35B17C1A
-:10CD100082FD6F0C8E8F5CC62ED8EF2325E0CF34BA
-:10CD2000FB2C581ADBF325179EE7C837B17889B179
-:10CD3000FD6DBB76AE49CE00BEA83E24A1FCC31F4C
-:10CD4000D89F5584C9493561E7D0AA0E133C775363
-:10CD50007DA808CFDDC0B9844F757AE05F73EEA679
-:10CD600093AF189E0A04AE44881AB7D06ED5D5F991
-:10CD700054D310980FE1E3DC706E84CF30D5ECA271
-:10CD8000F3E7AFA025C587E072F370FF4CFDE4899F
-:10CD90003CDC9F5527AA792D26763EBE63DD57E5FC
-:10CDA0004F2BFB394A8F02DD4FFFB125CFC6F6531B
-:10CDB000D0AFD6E65BC72984037FED3582E71972D1
-:10CDC000934933E0CF4694B1C06F1647A2CA976C1F
-:10CDD0003F9BFE6540E9369B7E23537EFFFAC19F51
-:10CDE00022FFBBE34DABB2689D73F8593DC3742E6F
-:10CDF0008BB230EFA865F56B4CE706D0BAE858C3A4
-:10CE0000EAB0F14A173EB3A3AEC83F14C67131BAB7
-:10CE1000EE50AE01FE164C2CAE231C90707F47CB1B
-:10CE200057594B7906F8D1E2607A745D6DC173365B
-:10CE3000889B172832E44FEC51EF41FABEA5865784
-:10CE4000DE66427F094AC07FBC83E153A30B69546D
-:10CE5000AE813C5E1254AE817DBD7E0E4FA2837EBC
-:10CE60003FF2AD9689A0CF1BDFF9280FEF73BF8289
-:10CE7000F533F22DEA43D2F99CFE6DFFCDD1FBE4F0
-:10CE8000FD1CF9A9F01D2503DAAF9CEC22B751393E
-:10CE9000AC53882C65839FADF72F1B09D34F1FD947
-:10CEA0004AAF70A03E09E33AF613BB6700D48D7E0B
-:10CEB000336949EC55DE9D947337EE172566347D52
-:10CEC000B810D685DFB17B4A3845C1FCD3173BEE9D
-:10CED0006B231897B2913837C48D899BA4F953D42A
-:10CEE000F89A89F155725E94FFACCE877E5F08791F
-:10CEF000F2636C2CBF81CE8F07FD3A82C8588E84B6
-:10CF0000385936A0D883F53D24F8E14F69FF8F5892
-:10CF1000597CCAB29DE8E28F650E16B779C0C9E2A6
-:10CF20008F7162F016B02BE2CE1017D8156D8F4BB3
-:10CF300002EECF0BAE9B70DFEEA009E3DC4F8B015E
-:10CF400017EC17B55F25C85B48677F6D2ADDB57E96
-:10CF50001F91E4AB20EEF70B27AB3F9D4F308FBB0B
-:10CF6000FD841480FDDCC40C4B4D743C699E83D958
-:10CF7000BBBF7315CC043A04F7C611187FCCBE387A
-:10CF800013D0E3B91DB956E08B170147140F89661A
-:10CF9000D79DD05FE2390A6F163E67F9FD823C22C9
-:10CFA0009EE277FC8D7619EED17ADA1ABC11F3562F
-:10CFB0009F37E1BDC12F4AEEE9507FF1ACEC023D55
-:10CFC000FC7456300EE7F3BC09E7F3625CFBD52B2B
-:10CFD00029DC0F0C61F12EC14604D0CF82A940BEDE
-:10CFE000933E5FAEF2B1A6AF37811CD1FA231CC1CC
-:10CFF000730C82291FE548CB276A6B27984FD467AB
-:10D00000660B0FFC1C375D8B3B857988174D2825F7
-:10D0100068CF4DB08B78CE05F299E1BCDB44550F5B
-:10D020004FFCB8B284E507BB0FC3BD9ECD76F57E3D
-:10D0300030759F7392CA27D791086FA1EDD75D24F1
-:10D040006E88274DBAA8DF8F78CA605F4E51FB57B4
-:10D05000DA5D85F0389FE8EDBF290D4527603D2C4E
-:10D06000208A00FC34D96268073BD209F7F0EB9FB5
-:10D070003FE050FDDC4C92199DC7A6ED434DE18782
-:10D080006E44FBB55872035E76DA950F203FC0DF21
-:10D090002292CBC5259FF2B17CC321176D04AE2C23
-:10D0A000A4FC6987F95CDD50EFB7D2795F3D90F55C
-:10D0B0000F7C08FAE5CAC7939340DF8F57E9A5951F
-:10D0C0001ADF017FB9E2197FB98677CAE7D38E2CC0
-:10D0D0007C4F9337E03BE8678F18981F6BBF9BF23C
-:10D0E000EBD3C0AF3BED04FDB89FA55BE6809C6928
-:10D0F000E3B4AA7C6D2CD7D5AEDC0FBFFBE4BFC078
-:10D10000D68DC2BE17A5E875BF4F0283D72BD7CFE8
-:10D11000980679687611F3CC52D47351D1FC921EE3
-:10D12000C52F1ADFB5DA599C48E39FC9BBDFE5E19B
-:10D13000F9E40B84B8B24887BFA2F1CF447F18F757
-:10D14000812712E69F18F9675737FC937F5E1640D8
-:10D150006F75E19F438C7FBAE31BDA0FDE6B61E4EE
-:10D160009F771CAABDDD2DFF5CC2F3FCABF74EBE62
-:10D17000EC7E65934F9F9F6A2CC7D962E72FBB5403
-:10D18000BCEF96EA6FCA01BD31D5C4CEEF0924E3E6
-:10D19000160AEFEE38EDDEFC9A6CA8EF14981EDA52
-:10D1A0001932A31EDA69F778307E9B6661E757056E
-:10D1B0004F04CE23B8FB5AE4E8DF21D9EE6076585D
-:10D1C000500C8FFB02ECF137181F8C9D9ACB432A31
-:10D1D0005AFA62A617461D9736C3EFCF3DEACCBF79
-:10D1E000007C9606B8A3DF798F4A78CF52F55109B3
-:10D1F000F5E36FF7BD5D04F1512DCF79CC9EB78B70
-:10D200000A86C2FB8CDFFEA1EA65AD8E4740405F17
-:10D210001AEEDD1FD7711E4B7F6F7E29F0514E67CE
-:10D22000BBF13EF9601CDB3F994D6411869871B4E7
-:10D23000F45EB8DECC78AFFCEC303BFF36F3B027C1
-:10D24000F6BDF22A7F18EF37A7F6778A13ECEFE7DF
-:10D250005AF6416884C86CDD0E4A35D7303FA326A4
-:10D260001BF8499343FCA3F80B7E3244F7BB06B787
-:10D27000A9F37FD02DB0FBA92212EE4BFE9CB0EF9C
-:10D2800082EA3A36CAC9F440EEEA17E6039C23CB99
-:10D290009566A0CBB32E16D7F905095BB2816E6EE9
-:10D2A00001F75382A23CF90BAEF33D22940EB1D3A9
-:10D2B000F63D7DE246C2F88F3A3D639C609F09EDE2
-:10D2C00087E0BB31E37347821EB78F589B04EB9A0C
-:10D2D000063785AB789BBD130E0DAE814EC6978F7A
-:10D2E0003ACBC6001EE03BD04B4D478E59E07B8DBC
-:10D2F0001F827BCF303E88E20BE0834EBEE01640BB
-:10D300005DC383A2AECFB7FD8BF8428B6BF4C81719
-:10D3100010B7707E2FBE980B7835F205B5E73CCE7E
-:10D3200018F65C50627993C6E73FB1E7E3FB6E897C
-:10D3300060DE13D96765BF6BE849C07D90DFB8D860
-:10D34000986D9F1CCBA4A62859E56476BDF63B2AB0
-:10D3500023C21CDA9F23A8A2B80DEDBC7EA827DD4E
-:10D360002AFEC8318E83FB4631373E03ECD0701263
-:10D37000D86B23CC256190875DB68919603FE6DACA
-:10D380002664C3FC5F1EB2FA4D58D25EEE5BFE9B74
-:10D39000AD72A77DA5E9C366B55B6DFC352A7F4CF0
-:10D3A00052D87927D0EBD17068EB039009E0E0C246
-:10D3B000B34DDFDA508F8722146F93000E8A87FDFA
-:10D3C0001C6904FB21DFA4244F063BB04F580038F2
-:10D3D000DBF67E9D09F1CE92D0EB1F02BC25DA3E32
-:10D3E000AC5BBF0F6BB4B7357B48F33F347B49F37D
-:10D3F0007BC1AE82F632D51F7199D9BED884B005F3
-:10D40000EF5378E4AC7C95A2CAB340E751A2CEE3D7
-:10D4100066D2827069F7A94C53F1517288FAAB3920
-:10D42000D04EC8548A87A9EA7D2A53DDFAFB226EC2
-:10D430001E1BFB3E15AD9F9EDE37AE1BD71AF6A313
-:10D440007E6879C8C7EE4FF9BD8FF9C3E307F07E58
-:10D4500001D6DFB159ECFE0917C3C32129F63A768C
-:10D460005195EBF1A6480E9CC7DEBFE7EFB86E1EE4
-:10D47000D8F3F7F7C18E1C77422090973BFEC4A8E3
-:10D4800078CC0F182B235F69FD7A3F6FB411F69C9F
-:10D4900044FFDECC410A8F7225C067C1F295538FDD
-:10D4A0003C0AFD9D3F2A90E8731F45926720C4E522
-:10D4B0008BD4DF1D3AC8317B4A6B3FA8FEDEC71113
-:10D4C000956F212143BB67C51C45E7A9EAFD1F1ADB
-:10D4D0005DA71E2F3E21E474A50FFCFD33E2105A18
-:10D4E000FCE19CAA0F49F39FF07CCEF58D770A6092
-:10D4F000BF5F9FC613256ADC1B64EAE947C5214E5E
-:10D500003A0DF66FF3338F4E83BCE5B7784C81F458
-:10D510008676BE9903F5163EE6BD2A46FC5E1FBA26
-:10D5200013EF55991BCFE4A3A7F1C75F4DF96438FA
-:10D53000D09D303B308FDD4B62A4EF813DFF9114D5
-:10D5400019DA3DBEBBA3BF910EAF9C2AC07DAC9E35
-:10D55000E861E4DB7D749EFE2BE177532DC48FBF21
-:10D560009BEAC2FAABBE34AC6BFCEADDFB6412D8BA
-:10D57000791A9F4E49627C336EF7A349C4DE492F66
-:10D5800023DE86C533FE7FC9AAD925EE59D3E8A389
-:10D5900077E93A848CEA272D903756AAC23AFB7075
-:10D5A00011DA25443DCF625CDF66F3B74D0175DAD1
-:10D5B000D3EFFECC94CB7AF57B39C56FD50BB00E8B
-:10D5C0001609AB991E53ED780D1E239DDF23A50888
-:10D5D0007F77F019F9C008E74B1DF9F60AAE07DAB4
-:10D5E000EFE0CC18982526C69887868F9984AEC719
-:10D5F000D9BD5F8F6F8CD7DBEFE78E17FE11D0DAC6
-:10D600009DBC19E9666CD7F447110C908BA51FECF3
-:10D6100093B9F12948DFA28B1251E83A43FAE9CFD6
-:10D62000F593922B91DF56B9D8B3EEF8ADFA224FAD
-:10D630003C233BF94E6C7AD8067CB75BA8B7411CFB
-:10D64000F53AFBF43A10BDC2CF0B66E2FD1511139B
-:10D6500081D0DA94D099668833783F2478BEA120AF
-:10D66000B47F32F0E9AB420BFA596DE7097938CA59
-:10D67000EE6C0AD5D9C02E6B4A66E7F30E26105D14
-:10D68000FEF4C578A66F9A8E9E9DA6C4681FEE62B2
-:10D69000FC3C8328C939F49F45EB297F801FDCC7F8
-:10D6A00081719242CEFD5A32D82D7339F423DAF6C5
-:10D6B0008E792D99C2DB7A7B02EA99294DF7DDE953
-:10D6C000A28408FE63243E6F2FE3F0FE8422D98DEE
-:10D6D000F5A2C559E8F78DF926694609B4DF20A2FD
-:10D6E000DF3385AF14205E753A8DC3AB3CF6709185
-:10D6F0005AF83D62FF74360E71F993C03F7DA7243E
-:10D700006904FE669EACD507E1EF2E1283FFB6FAE0
-:10D71000A573FBCDB47DF52C0EF38DA7B832883FF1
-:10D720008A7F8AD64B38AF5B42A905C0D7338AF5CA
-:10D73000E71EC3AA3D39ABD44602D1FBF99C0BE5E9
-:10D74000FAA0B5FD56FC1DF1BD2281F969727EA3D8
-:10D75000CAEFB3E724E9BE9B4E98DDA9C9D54DAA0F
-:10D76000FCDDA8FACD733D19BAF14B09B387FE4031
-:10D77000DA0B8164F7B8D87EF4B4F696C3F3E125EA
-:10D78000BEDF68D087370D31F8BD7CE55AE48B34B5
-:10D79000CE8DF7C8B8F5ED378FD5D78DF26BD40F96
-:10D7A000B3208B8FEFAA27347D306B2F2F423C683C
-:10D7B000563EC533DAC57ABBBD277D3126AE1B7D0B
-:10D7C0007149BE17CC902EFAE2E3E2EFA52F7E4B13
-:10D7D000DD96B154AEDF8E57D7CDFEA43FE88D293C
-:10D7E000FC8E47818FDAE8BA698EC147DABAA3C5E1
-:10D7F000018AA81CA31E38C5F663A65C4C27FE91BF
-:10D800009D71800E3D42ED12770C7BA9353E1BE5E4
-:10D81000AB43EF687A25CA2E11F37EB85D3285DA04
-:10D82000A3522EC0D70FE12B52EF252982842B88DB
-:10D830001FA69DC1389057A0FE2CAECF4F227F81EE
-:10D84000FEE3123BE5C368AF6871E80A97664FE9EB
-:10D85000F9A5231E3993DDC3AAF14911E013E47F32
-:10D86000268FFB04FF1BD47F03B300800000000061
-:10D870001F8B08000000000000FFC57C097854558C
-:10D8800096F079F55E2D495592AA6C148BF012B67C
-:10D890008424588480EC165958A314A080CB688146
-:10D8A0000B6B129A719CEE69FFA642024343B78349
-:10D8B000D2DACEE8F457D83A831AB40801039DD0DF
-:10D8C00015504C5834082EF8D91A6D1AD10E4984C7
-:10D8D000D646BBBFCFFF9C73EF4BAA2A854DFFFFF7
-:10D8E0003FDF9FB47DB9EFDE77EFB9673FE79E97E3
-:10D8F000DB9B55B3AD08E0F6998A071400D0F177A9
-:10D9000022C042E07FC3ACAD16F08EC7BED7FC6923
-:10D91000870DF8E73BFC2F9C90FC2CA450CF0B907C
-:10D9200009B054CE5FFC577D333D5E3C277AFE52F2
-:10D9300098FDB9920C701BF8CD301CF7F3C58EFF23
-:10D94000EC4B15C7972E8B7E9EE94C4ABF9087FF04
-:10D95000180123BE5301CAD4BA9DB722BCDD275596
-:10D960008F554C33D1FE0F39C5FE0F35970C807C97
-:10D9700080DF7416A7F8B13DB611211C0DD0BAD1C5
-:10D98000C6ED71EC07F1C5EFE8E7663C9F05FC21A9
-:10D9900007B6B45221B701480518EDC4452760FF0A
-:10D9A0002A9E3F0DC78624C0EF73245CD900AFE7E1
-:10D9B00098E704F1BDC3B85E00D70DE3FA015CF748
-:10D9C000C84627F75FDBE8E6FE0D2E446A06C0FA7C
-:10D9D0001427AF372FF776871FDF5BE3CCE6E750DE
-:10D9E0003EDA44F836E02F7B6A080410DFAF77ACEC
-:10D9F000D09474802AB7E2B166F5D1014FE3588E16
-:10DA0000F3CB25BE2BB72A10C4E7E51FAE2B07C406
-:10DA10005F5733EE87F8A92A558336FC6749D363ED
-:10DA20003B45DF0CD608FADE228E0233B516CD86D2
-:10DA3000FB2CF0281E15F7F13689F76FF52A411DEA
-:10DA4000FF798B279A1E8763E8BE58AEB380FE0F1E
-:10DA5000DF5B30470986719D0593A2DF5B7C75D63D
-:10DA6000E7CAD8FE7CB498E83EB63FBFDC4E74B738
-:10DA7000E33F86C130A2FB958BA56F8D853EBAC56D
-:10DA8000B6B1748E1DBF169DEF273A675C9BCEC65C
-:10DA9000FB7F8BCE0F114E90BE70F41B8B9E04301B
-:10DAA000BBE9071AD179F6558DD7AD32CE3314863E
-:10DAB000D279FED459F86FB742DFFCAAA62F2DFE0B
-:10DAC000826B9FE76FEDBF2245E7FD695F6F7EDFE9
-:10DAD000BEF33480C178CEF939D1F88DA56B2CBD59
-:10DAE00016CAF762E9B535E61C065DA013996860B1
-:10DAF0001CBC5F55198E6BD1AD972E16FF084F7E5B
-:10DB0000FF71805FF3B9FAD693748276CD5720E027
-:10DB10003247C803F2752005E95BDE0AE14404ECF4
-:10DB2000968B733ED7A8F528F069C439E8E753838C
-:10DB3000CE6ADFFA655707B2FC19FB966910B0147C
-:10DB4000D2732197B1F055D23A23697E80F968CB20
-:10DB50002ED3B2109E63BA05EEF5519B28DA034E20
-:10DB6000A1071A9D265EB7FB2B9B096E0478E5F092
-:10DB7000806240F83C56E709D28B2133F0FB45C95F
-:10DB80003ACFDF9C048104DC1FB4769B0FF9442B51
-:10DB900006C84139D306598235B8649D16F691DC22
-:10DBA000757B34A846B9BBD178EF48E02E40926C23
-:10DBB000FE7494A9268BDE0FB74FC57937156AFA24
-:10DBC000369CE2B2EA3FA0F1AE66AB93DEEB3EF8E4
-:10DBD000CF2D665AE72BF02084F05A3332158E4F42
-:10DBE000739883A437CAD493AA09FBDD3D00A48FA0
-:10DBF000A62D0B9700D26D3AB4D738B19D42748CE4
-:10DC000043BFBFD0793384DE1A88749A21E9344344
-:10DC1000EAAB926695F54649921A84AC3EFD74B320
-:10DC2000A4D18C407B490AEE3B43533C35D8BFF925
-:10DC3000AA16C58F2F933EBAB14F1F95C9F5BD3DAA
-:10DC4000BA869601664234FF96350A3D54628B7956
-:10DC50002EED0FBEC97C55E68C1E9F42BA13F9FB10
-:10DC6000628C5E8218FB53A6FE35B903F1F08AC5BB
-:10DC7000FBDE5484BBE7B4199EC5E770113B93FBF0
-:10DC8000E3A731C61EC5B6070F277A7584EB15E2E8
-:10DC90002307F50779F5B1D79E3FB6A3A7988EF174
-:10DCA0004ADD220DB2992DCFBA33FBF0DE0FBF92C1
-:10DCB0000EB178AD977ADEDBE87C8D8EDB0F8FAD11
-:10DCC000B3D89E97FC49D748F5FDBDF834E4E595F7
-:10DCD0000B895EE2FF572E0CF2B2FD4AD2593E0C80
-:10DCE000793878FE7222E951C4A7AE219FF4B86C4E
-:10DCF0009E67999F851C84068E0A6EC3FE8524C18B
-:10DD0000F7AF24F61CCF23BCDF62F23C4BDB68EBA1
-:10DD1000872F2A20FDB975D1793380E205E5872860
-:10DD20004F8AEE84BBB10DA03C11FF055221487211
-:10DD3000628610D0BE355E789ADA19D3F414C2FB2D
-:10DD4000655CB3DD41EBE929C4F7F0D72B137D0502
-:10DD5000FDF15FBF117C1AEED3B0D1E6D3502F1C7A
-:10DD6000D8E8E47EE34637B78736EADC6E3A91FCC2
-:10DD700043F21FAABC169F16A157E6A50AFD300361
-:10DD8000F50EC13503946000796FC623C0F2887226
-:10DD900010DCA410BDF03C397DF844FA5CEE88E854
-:10DDA00043AD563B2193A582E95E9867E2F7D1091E
-:10DDB000083E9FD57F3ED23FAABF8CFC1684C3EF9E
-:10DDC000F296B9B00D397CB35D88DF7A65E9D14B45
-:10DDD000C0FDB9F4BC5EB943BD84EB8F0FCF841F87
-:10DDE000A2BD188F8421BCE2CF5D04FF84160B1006
-:10DDF0007DD0B0B27C161AF2F9B5A25CC0FD4884A1
-:10DE0000BE1B8CEF59CBC3C44F07A0238DF05E64BB
-:10DE1000F3D9497E97B9043F7895DBDD0AAE3739EF
-:10DE2000C3E25109B4E1BEF1EB117F2D19B821CE47
-:10DE30006F69C91CA2E713B7BDF13EC9B7D7E608A1
-:10DE4000AB6C98CC9D1D11F67C003CE3247F927452
-:10DE5000DC7768475A3F4E0EB09EBB6A09925E6BF4
-:10DE60003D93EC09E33ED3AFDAD8BFACA717516EB0
-:10DE70000F27268F653D13420D43F26313E7986D1C
-:10DE8000F6AF233CA0653E7A0ADFFBED6500D2AF1A
-:10DE9000D3DB3F54C90F2D31E50EE840388F2AA35C
-:10DEA00053A87DF2E3E47C6ECF2477127E0E9BECC8
-:10DEB0003AEDFBCE46BD7404F2CBA98D503A02F97F
-:10DEC000E3AD8D366E4F6F74727B66A39BDBA33818
-:10DED0004EFCF33A8E137FBD81E3D46FC3716A4F5A
-:10DEE000E03AD47ADF7298487E67BCE5D0A82DBCB2
-:10DEF0002B89DBFA3B932C748EC3C95067EC4FFC23
-:10DF0000144E0C378007E52ED5FD53DB0D683FAD71
-:10DF1000FE02651CC0D454F75C6D3AAE3B7BE88FC3
-:10DF2000BEC2F119A9C37E6A43786F3BE3683889A2
-:10DF3000FDD2C7F59F3A883F4F24A292243C64B794
-:10DF4000795136C793D218C468F7C224ECA719FDDB
-:10DF5000ECB9A5C80A4B4A3AF2C005B0F3B1E17377
-:10DF60006D88DF2576FF3F51DF12689B533A9DFA9B
-:10DF7000107092BC2BE620CBFB10257D11DABFADD3
-:10DF80000EFFC4D4087FC0ABFC218DF4C344AF02A4
-:10DF9000AE74A67770A4D2F7DC98B7D55136311598
-:10DFA000F9F7D72E95F969C234C51B74F4975F63EE
-:10DFB000DE84F37A29D16FE2C559B5D42E98E3E215
-:10DFC000BE6FD94DB524FFA58E6BBD5FC2EF875CD8
-:10DFD00066D647C51ACE8B63178D79E391C9C8FF02
-:10DFE000EE694B0C3E4B7C7DD65F9384FD327756B9
-:10DFF000A12A753470DFB56B1B8D97BFDEC072E54B
-:10E0000049F2E859C48AEDA569383ED3A178C22403
-:10E010002AD33EA94DA371A7E221B4CDF48E3B557E
-:10E0200044E32354CF4CEA9FD54B9DD89ED1664EF6
-:10E03000BD84F366E7A4786CF8DE99F08FAE10FF2C
-:10E04000CECC49F224E81417049FAEA4BEC7EAA9B7
-:10E05000D6E91C8F9524D33ABAE23161BFFED6923D
-:10E06000FF457014FB52405168DCA5911FFBE4C7CB
-:10E070003F2975E2BCFAA10A90FC9C09E7FE91E0F9
-:10E080009FD99AA8272040F5166729BD576F519C44
-:10E090009BB8EF2BA1F9815166FD795CF7E49D7681
-:10E0A000B607E56FE5B35F74F2CEC16C17CADF9AAD
-:10E0B000564CED4993F0DBCBDF2A9FC3E326089350
-:10E0C0005229BFEB1FF8BD1D253F294DC7F54F0C49
-:10E0D00073B16E413A956A117A0DE78342EFDF55CD
-:10E0E000C1F35B94013F3A8FF3AFE4A7145A71FF79
-:10E0F00059E90951F3E70C7145F5E78D1858AA4520
-:10E10000D8B1F2FCACA8FEAD454AE98888F9BE69F1
-:10E110000951FD45A5AED21111F36F2B1F18D55F24
-:10E12000725B56547FA669B2D01F1BA1BC54C87D38
-:10E130007929FB9BD9AC870A9D62EE1B387E3F8E06
-:10E1400017B6097FAAD085FE14D2A5B4AD88FD808C
-:10E15000367C8FC68BEC528F05A0DD3D91EC80FCA8
-:10E1600009E22FF68B6577663BFA056389AE68B7DF
-:10E1700023E02F7544DBF1FA44E127CC017FAD0B9E
-:10E18000E939A7751EFB5765E9D54561207C46BF77
-:10E190001F0B372AD19D77131FB66AAC37E70C895E
-:10E1A000D9AFADD4C17E8CF4EFE6C8B78C7D21E049
-:10E1B0006D27FFC63887B1FFB5CE33479DC67EE1D8
-:10E1C000DF3AD7AC9C85A5A971E15FCFFE4C2C9CB2
-:10E1D00079A9324F81FE15FB85ADA9EC2FE24F7A6C
-:10E1E0003C3FC1F07FCA51CFB922F59C43495F58EB
-:10E1F000706D3D67AC7B2DFFCF58D7781FEA54DE9A
-:10E20000DF78BFF7B9AEC47FBE1BE727C5799EAEE6
-:10E21000C47FFE5CF4FC199A5EE340793E0E8A27C7
-:10E2200040783FA96BE49A959CF5D6525BF6A15FC6
-:10E2300023B770F6F9402DB5533B8327AD78FEB96F
-:10E2400039AA4EF907C32FEA1767A50A7FE4F855E4
-:10E25000DDAEE3787D40B753DC51FF886EA7F8AAA6
-:10E26000DE0B73288EF40E37ADA738C49B872DF6CE
-:10E27000EF4D15FA7E857CDF680FA9FE15047F85BA
-:10E28000ADE351F2492ABFE9B1105F1C277F2FBFD0
-:10E29000BFBF775C0B3A68BFE38F041DBE087D7E6D
-:10E2A000BDFEDE2262A60CE253C517A94F4A6C09D7
-:10E2B000BE48FD51E67445F5C793FF83EFCD760F59
-:10E2C0008C7A6FAE9E15350FFDD81CF2876A2C90A4
-:10E2D000A3913E35257AC8CF8BC5E3EFE5F93D0E16
-:10E2E00027B951604ED7557F1CFBE42911F88B7D6F
-:10E2F000BE3D55C47383C89EE33A2752756E6B5575
-:10E300009F70E6D07F267E88ED63ACBA8CD6C3952D
-:10E31000DDC4771EBBE90ABAE0F0D2E3F3E76A682E
-:10E32000FF3DE34DFF381CFBC71E5F21FA534DFB39
-:10E33000B2B1DFFAF87DA27FA369BCD983EC19B82A
-:10E340007F6E29F90BE9BE7F27FA759B1D5B15D4FB
-:10E35000039509A8D7B0D54C0A14A6F7C5C7DB2D7D
-:10E36000685F91C0C86C5E17D2C06E15F17465C24B
-:10E37000D020D913ADD8AB13DE2A130C7A77649270
-:10E380009D87DA0951719DDD82EFE1FB6536FF0B58
-:10E39000826FC2C93AEAA5870E960D20FE3891EA2F
-:10E3A000643CE4ED9BEA267D85F0ED21FBFEFF0158
-:10E3B000BEE678F0D59AC53E9DF57925648FF38643
-:10E3C0002179943EFA156A3A3F4F0821EFB0BFEE2B
-:10E3D0007553FEB1C665F190FF7E42F2EFF5B6359A
-:10E3E000328FA1DA051FA929A6F57BB17D5BF2CF9B
-:10E3F00019B92F6ABEA10B913FC0D933745181E87E
-:10E40000137FA86A610FF9E13DFF90E4A1F8F98359
-:10E4100044813F18D2F3D18FF1F97B77E779B6F1D8
-:10E420007381A765C1EC9A0EEC8FB3066FA0FCE375
-:10E43000A134FF4784873BADC191CC878EF549B4A9
-:10E440008FE2058E538CF80FE33CDD32BC7F5C70AD
-:10E45000EDFDC1467665E9648177637FC4B18DE8DF
-:10E46000F1DE24F1DC8007E1E8263E30E0EA8507B2
-:10E470008638398F0022FFD425E38B2E5A8FECA7E4
-:10E48000EA1079DC3F9838FF5245C28AFD7DE74D9E
-:10E490001C0F1A79E02210FB4D3EB54965E003F8E8
-:10E4A0003B51A2965E695CCBF1FD84762D26FEF68B
-:10E4B000B23D9D2ADFBFA9D55FE2A0F6FDE8795302
-:10E4C000651C3F09822AC559933B62C61BE77F46FC
-:10E4D000EB4FBD18FD3C294DDAC3413028324FB215
-:10E4E00041C64D974F66A7101F6B182BA8480F8B7E
-:10E4F000AEC2A4D43E3DD3B011E759499FDAB82D3E
-:10E5000038EBBC8FF669DC880C3F9AF4AA9B5B431E
-:10E51000EE0ACEC2BD3036621F2917061E2FBF2F4E
-:10E52000F038AE23E797D3B06F6E354350EFC3C3D7
-:10E5300014892F0CDF38FEBB7CD1C1F66B62DB6225
-:10E5400095E4D9EA36811E71BE043D11F4087D6C54
-:10E55000CF498DEAAB929EB509D17ECA78B94F9268
-:10E560006750D47A86BF62D0F350EAAC56F263C6E5
-:10E570003B56B1DF9232293B6AFDA293D1F82E04BB
-:10E580009F97E263CF87C071C0C4B35A947F32298A
-:10E59000BC83F963D287D1CFA79C8FEE97A6C9FC25
-:10E5A000562CDDAE854F18FBCB69E97F3F3E5DDE23
-:10E5B000687CA6CD89C667862F1A9F039645E36BB4
-:10E5C000A03F1A1F83578D891ABF617D61547FD880
-:10E5D0000FA744CDCF428319D91FBE755ED4FC91DD
-:10E5E0003B1645F5473F7567D4FCDCE08AA8F1BCD3
-:10E5F000DD6BFE2EFA17843644CD27349BBE87FE92
-:10E600003736FE4BD47EFF53F4AF8DA1FF56D2E7D1
-:10E6100013885EA8370BFBEC19B925A43F5D4D6F3D
-:10E620007C43799B40B1CEF9AAC03CF0D4E0D82F0E
-:10E63000549F427A6E30A2DA847AA3D604ABC81E05
-:10E640003C6A32711ED390F317D3843FF2629AC8AA
-:10E650007B19787B1AED22D94155EA4373FA8E244F
-:10E66000F253549309DAC9FE691ED61FE71C10BE87
-:10E6700019F7550701E7C54A92272D9888FCA8BECF
-:10E68000A972FCA90EF2838EF6A4E6E4CE53849F11
-:10E690002B0E9B4E7CABA6FA0364DFF09CA1E7A196
-:10E6A000BF9FF3DE465849F196D15FE65EBF99E61B
-:10E6B0002FBB7BE6488A7F7B9FDFADAC2C8DA043D0
-:10E6C000E43917C5F1AB0EA409FB67D813C37EDC90
-:10E6D00069D56B3AD03E8C53857D40BB71200DF1DE
-:10E6E000F181F28859F86901339D1FED2ADF27B8BF
-:10E6F000D021DF806D4A9FDDD2BF43E6FA203BDAAE
-:10E700006F7D9300A33844F7F03DE31D86FE5D95D1
-:10E71000CBF8BBEC889E7FF9FEE102AFF720F690C4
-:10E720000EE72CE23C06FC17A55EFE42EAE54ED25F
-:10E73000C711F9EB55BB7626917F7E2E47F8E3C6CD
-:10E74000F3DF493AFF2E4DE5F3AFDD9DB0FE7C04CB
-:10E75000DE2A42AEA87E55E3C0F591F9CDB5C639A3
-:10E76000FC8A46E75827E5A8A2B523F94E607FFE4C
-:10E77000C3345CB772D7957B0ED0FBA69E4C616705
-:10E7800003BCDFD2F780E382A57F8128BFB633CDFB
-:10E79000CC7075A689386109364EE4BB25E803B80C
-:10E7A000A87D63DA2CE23F7C1E56B0BFA015CCA436
-:10E7B000BF16FAB3CC84F433E079673F1EEDCF691E
-:10E7C0003AEF731BF8F87EFBDD7B2A92D80F34D624
-:10E7D00033D64181203FEF3D57C09C49799FE90ADC
-:10E7E000FB17B89F8D9EFBEE1EBC99ECB0B1DFBB52
-:10E7F000E0BFF40EF2C522F0F0BAC6FA40D73411E9
-:10E800007AF9034B2F1DED44BF0D6DA630E585361B
-:10E810009CB3F2BD4A7775CFCB0F239C1FAFF9662F
-:10E82000BF82707FB4BCE7BF0EE0F33B9E5241470E
-:10E83000BEF1D9FD5A7A44BC79EEFE2B2C6FE8AFBD
-:10E840003CFF2429A597AC1E92930FD6BC342A32E4
-:10E850005E484E9F99904EF73B93D2E2DE6FC4C65E
-:10E86000A56B883F597E75F64B0DBE5C2DF972C3C2
-:10E870000BA3F9F986A4DEF388FEF32AE7C1363448
-:10E880005B39AFF18EE487352F7E333132CF578F2E
-:10E890007CA95BA975724BF7A63AFA09FB4E5E1E7E
-:10E8A000CB71ABEACFA2731EBEFA6932F5F7BDF9A0
-:10E8B0002D9F076EBB3EF8BB11799178AE4AEA797D
-:10E8C00097F44AC501AB4EF9AC9203B927EEC27E6C
-:10E8D000652BEA1F3CCF2557C7B1A7291E3BA800CF
-:10E8E000E5B72AC309ACE42B1B9420E5C3D634EE6C
-:10E8F000DD3218FB6BEA161611BB56250B7D5659F7
-:10E90000AF0437B11F3E87E95C2865A3E450EEBF32
-:10E91000E5E378D771B1FE858DB0F63CC69D5DF517
-:10E920005F5E2038D6355A39CF7621296C198CFB99
-:10E930005EDAAB84027A9FDC76B9441CB62AF4987E
-:10E9400085F65DF5DCC211E436761D386D213DB9E2
-:10E95000AAE1B159F2799130FF41968BB5BB9595FB
-:10E960009179ACD5E80E42A4FD42F80213FBEA40CF
-:10E970004E49FA2C6B1A5E43E842BDB6FF6985F535
-:10E98000DA42E2970F0EEFF9DD6F68DF83FF3D9209
-:10E99000F15F747DF8075F80FD8B4AB90F5C3C63C3
-:10E9A000A1F8B2B2C17C21DEFD5263BAEF1EDACF0C
-:10E9B000888F63FDEE2D1610F73FD9107C9EEC82F8
-:10E9C000A3C7B21CE1F9579A80F068CE1ECB0AECBF
-:10E9D000DB48CEC85EB81DC17871F5BE748DF18478
-:10E9E000B1C4FA78F7A021395EA27758289F57E979
-:10E9F000EEB4105F57863F17F7FF8D9FCCF2C689A4
-:10EA0000B75F4E57A4333F274ADE37648C61B93075
-:10EA1000F7DAC3908DE5BE60450FD9A90D07913B8C
-:10EA200014A2B7BF87E00EEC4FD0E97C25073E9FCC
-:10EA3000D811B1CF1FA57CF4E6595EF964AC99F00A
-:10EA4000B9EF93B15A52DFF3AE4CC7AA78799997D0
-:10EA5000D385DDDE9CECBB182D07099E30EE5BD91B
-:10EA600064E77B1494832D2D45917270C7AA5DC411
-:10EA7000E74DAA0725022A1B17FAAB797E9287C8B1
-:10EA8000A336CE0C101FAA4E1FF327FC15F79B28A8
-:10EA9000EF8F50FFCD4DF73F4D72AC396065641E6E
-:10EAA000A4D2D4F1AB1685E8BAC36BA2FD0A81F5F6
-:10EAB00096EAF075703C5594A953DC7B74C22C2007
-:10EAC0003CFDBC59E1BCAF39D5BF358BE87B5CE57B
-:10EAD000F996A32F04E8BEBB6B1C14117CC6797F8A
-:10EAE0003E2E0C2AAEB3B9003CB4EDE6834BDDC438
-:10EAF000BF3FCF38C67E86DD1302D22B35E83F50AC
-:10EB0000DEC79E1F0AD33A0939BE2215F75993EE84
-:10EB100064BEB458FD1ECA273D20FB36CDB78AE03F
-:10EB2000B3A5278AF87BC8F5E5F9BA48FECD746F1E
-:10EB3000E9E77C4B9759F069D70DC07122D7FC4C9F
-:10EB4000A6212FE3CD063BB8AD6A54D646DAD744AA
-:10EB5000F0DBE879D7C1A51E82DF9C2DF93D33910A
-:10EB6000E52276FF8F889FA9CEC0B4626B16E1992B
-:10EB7000F0A6F79FF7A1E47B031FA0F973485E118D
-:10EB8000546FBCFC923FBDF82CD17573AA2FC7956A
-:10EB9000CFD7BCC2297627C6953B9CFF01C9B731A8
-:10EBA000BF95F089EF6FD1FC36C2EF51895FB3C5D5
-:10EBB000A73B59FE7D3AEDDF7BBE41F1CFF78D3C9F
-:10EBC000DF966CFFF79EEFCFF27CE654E4375A2FC6
-:10EBD00019789E39391820FEAB4D82A24DF8F8A85D
-:10EBE0006B969BE46ECB916F8692BCD72679DC4006
-:10EBF00079B1E69B9691DC6F197427F3FF172FE428
-:10EC000016AA11FB24A7177F45E73B2FCFB1C5E21A
-:10EC1000CFA1737C2CCF699C6B49BAEF2FE911F916
-:10EC20002618927E5DFCB3D7B8D794719E47DA61FF
-:10EC30008CF3388FD80D895C7FB657FAE11AF898B3
-:10EC40007FECE0D1D9BFF2C209AA2BA96931C13644
-:10EC50003A3E25B522EEFD925593110C7A6D18B20D
-:10EC6000D335348D3B9FD839AF16E13E080155F8B6
-:10EC700069D1F90CF02A5E25328FF1DA9AEBCB6379
-:10EC80003CE3AF21798DCD634C0E9B965B52AE2356
-:10EC90009FF1DABCB8F98CD119D171514186CEC03F
-:10ECA0008572047F86C28941913783F194BFEA2639
-:10ECB0005B85E39FE39959DE95AE1C9B0BEDE0135A
-:10ECC0004F6CDB3A0DE57084C003F56B88C9F5F134
-:10ECD000EC07F5E6475E1BC37E38EA3D95F3024E2E
-:10ECE000094B0C1D8BD07F1341A5272ABF123EF67E
-:10ECF0006D32F1DB9E54FD2DA24F4F9BCA75280942
-:10ED00005A87C51547EE0E907F8076E09F33843E8C
-:10ED1000B7358A7B4B9BEE653D99E0748E5323E4B7
-:10ED2000242F43D8A58A631F0CB5A02C5D329D4CBF
-:10ED3000CEC7F5D7EDAF4FA634DEDA736F4FA4D24E
-:10ED40009F3B35FF820C3CFF17CAAE5136F25BB7D2
-:10ED500006C7127E42E16CAECF2CD020A015F687FC
-:10ED6000A7EA293C14BA04954FA5715BD0347E25DF
-:10ED7000F15F55589C97F630A38ACC6D54B8DFD517
-:10ED800058934AEB55FDB67910E9AF9732849FF35B
-:10ED9000E2D53CF1BE061ACDBF3FC325992A68A231
-:10EDA0007CE34B324FD97555E579C6FE058D335559
-:10EDB00027F2417E78C711CE8B365975A26FC27388
-:10EDC00020F0D194C07E68D5E1D94076AFDB051E36
-:10EDD00005C7F724F67C44FCD0D36CD5E93E37C197
-:10EDE000B9035271FD3DB21E2C1719B6DED1F7DC06
-:10EDF000D82FA1E997944324BEE07BE5046D074C2E
-:10EE00007744E23B49D859C9577B12C326BA67E910
-:10EE100041DFEF5986AB0F4EE07D0D3873D90EEC14
-:10EE2000B1F45CF8713AC3E5243EC8050127348D7E
-:10EE3000D649AF2638BD7C8E04A7EE0928FDE1AA8D
-:10EE40001A8B8E20CACFA3A4CCA6F4C97755625FD3
-:10EE5000DF86B2B0271BA4FCB76E2B9D16D9478561
-:10EE600033A9EFFDFF78E2F8B6DA219CFF0BA84842
-:10EE70007F3BB649A9744E21572812DE8C42810788
-:10EE8000AA0BB4DBC478EF7CE473472ADB7F9EE7F0
-:10EE9000B13AEDF3B2585EF87ED1F00F1F52C217AF
-:10EEA0006E46D2763EE64BC9C773759A8E3C5C8738
-:10EEB000F3FEB83C342A8CFD16ABFF79E2CF573F06
-:10EEC0005CB1BD80F4EF1EB3A79CF44F47E071F630
-:10EED000CB5F34EBDB22E40E86F46472DD61CC3E62
-:10EEE00055E7363D4EFE76F74145A7FBF46E73CFEE
-:10EEF0005082BBB2E9330BD563561DFC84FDEBB2E7
-:10EF00004CFF5EDA6F526335D7CF4D861D5C3F876D
-:10EF10007A91EB20436EA14F2E9F1DF56C75041D59
-:10EF2000DE93F2063DFE6164BF9AA4BC1EA6381CA7
-:10EF3000DBFD2D770CA7F5F7CBFC80F15E351C19B6
-:10EF40004C78DF04AF716B3CEF0E6A5CBF9CF7AE90
-:10EF5000ED5E6FC4FCD352FE4FCBFD5667FADF2047
-:10EF600078D7B67C6AA1D2C2AAF3A1A114F78634DD
-:10EF70003DC519478FF4CA6F8C3C55693D169A5FA1
-:10EF8000751158AF20BD6B53907E2FBDDB386639AD
-:10EF90003EDF8F3449213B8BF12AD9E3FD66DF60E8
-:10EFA0009A5FFDCED763498F1D2420F07F5F37AF76
-:10EFB0001D467843FE2F4E2439DB0BACD70C39CDE0
-:10EFC0002739C5F7F389FF8BA89FCB7A798FA57D69
-:10EFD0001ECBE57E13905C22FFB33C20FF3BC9DFD4
-:10EFE000CB77A23CF0FBA359CEF7B49BBCEC37A384
-:10EFF0005E1FC9FDE2C5D4DFD35EEA6439A73A8457
-:10F000004292D7F0115E270440D7F2450AF822FD5C
-:10F01000FFBC8C64712F24F1393943D883508E9E04
-:10F02000E2C173D855354A3E22ECA5E84B7B5A9A8B
-:10F03000F9976DBF98465226ED8453DA49FF78D68A
-:10F04000FBFF286DD586D7A72CA8C3736E38A5F211
-:10F05000F86119F785259F1C91F91AB21B7A9AA8B5
-:10F060001FA6E713B04FF5E513BDEB4BC81C4D9A37
-:10F07000B3E328B5537CA11272DBA62D6B3F6A1651
-:10F08000629E47FCD770646E1ED5E3759FB3420243
-:10F0900082D8F06DCF472F221E1E3E8CF88F63A7BB
-:10F0A000F038CC7FE87F0D0677FFF16E45EA91409E
-:10F0B000D27CE2C7AE06B5AF8F8054226353DFFD2A
-:10F0C000A47D7B006DE77F677A0767223ECF0CF057
-:10F0D00073DB7DFADB4C12CBFD67455CDF60F1E64C
-:10F0E00011FF346463A81B874FAD9922EF536485E9
-:10F0F000B8F79C37670A39181580ED0AC7EBAA33B1
-:10F100008874BFD4A07A2DE82F5D84C092A9A46F23
-:10F11000645EF701903F5EFC45FA3C28BB0F90DF30
-:10F120008276EBC15FC4D61178D96F31F25800EB0B
-:10F130004DC45F2B9B14F80FC4C5AA67A2E7AF9319
-:10F1400075F2AB1B771D1B8C745DF35CCC38F92D0D
-:10F150007CFF11E278785D5D743DC3CD99D27F1953
-:10F160000EC3C97F41BE623D61D6A0D58A7CAC602A
-:10F17000144322F69249E00BF52BCB67BE616F8AF0
-:10F18000855EEAB9045CA794BB3B7494EA81A6D47B
-:10F190006579688F299A189FD29825EEA7B4A04A5E
-:10F1A000750C93BCFE59EC7707BC67A9DE6495D457
-:10F1B00097E0C45FCAFBC8D3AF92FEDDEA606C9DE6
-:10F1C000A8C053959C37198235B4EFCADDA2DE6919
-:10F1D000EDEEE8F955124FEB9E3A7D8CD28515A1E4
-:10F1E000987189A7AAC6983A16B138DC9F29EFAD65
-:10F1F000647DFBF5D65BFCD12CFC8DB7E53AC6F8F7
-:10F20000E64C91EFADC463107DD705D520F1D12A2E
-:10F2100025902CFC5E702CC7F3DD67B081ACCFBDB0
-:10F220005FE2E93EC93F7C7E7CBFE219F17DC5FD0E
-:10F230003F8B867F0DF82C83F1F9830D3FB050DEB4
-:10F240003196DF56D599D9FF5D23F113CB5F6B7AE9
-:10F25000F9678785EC5B2C7F55FA956BC02FFCF620
-:10F26000FF5BF80D3AAF91CBAC3587393FB5F60966
-:10F27000C543F9AB6B9DABF73CF27C7FEFB99E3594
-:10F28000E83D06C630BDE7A45D17BD63FDEDBD9644
-:10F29000DEBC26E7052FB766733EDDE0ABD87566AA
-:10F2A00049BF7DF653C27FBDD4586227FFA3FBA49C
-:10F2B000C9A3E89CAF4C2EC0F38F6F5681FC91EE32
-:10F2C000A6E13B03087FE1A9A2C5945F1F7F0AED79
-:10F2D00013DD07B716FD5702DF077BD248EE67B68E
-:10F2E0008D48FBBD83D761FBDE7DB2706739E9E9EC
-:10F2F00093A545B4AE82E3549F5E28ED54F5C94210
-:10F300007B4784BDFA4DA6C8CF6F71FFFE518A1BA3
-:10F3100066EF357B283F32DBECDF9480F015BEA032
-:10F3200078AA71B763ED479EA47551BE28CD8AF3C4
-:10F33000FEE9088D57ED5118FEEEA6B2BC3D643FC4
-:10F3400083AA87EC6277D37DF90F921FD4FC40FE2D
-:10F350007D11FB1D4B15FA66F60D66B6D79D83EC45
-:10F36000BF2EA7BCA87717EB8DCE43FB2CFC7DC32B
-:10F370001E05DC78CE63EEA32F131E3A0F9CB65009
-:10F380001050D270DAD211477F1BED250CF3C29CCE
-:10F39000AFDD61E1FACDFD7FB0D0792B9FFB84F327
-:10F3A0006F6B287E203FEF1995BF773ADAFCAA856C
-:10F3B000F8B4B24E81015991E3661E27FD4AFDCF94
-:10F3C000EA849E36F87F85E47783FF0D795821F52E
-:10F3D000DA7D5BE3F3BBA1FF1E04EF9641B8DE03C9
-:10F3E00075CBB90EE9811DD1F35752FC7A23CD17A5
-:10F3F000FCBEF2A9E8F1D5BD7C1E60FD1FAB47BF86
-:10F4000033F47F2EE4129F5F0EAF18A6A13C7D7DE2
-:10F410007ACD308893AF3C29FD06C36E5F0E9BD832
-:10F42000EEC5CEEB6ABC62217B5BD5FA27F673672B
-:10F43000357DC9F4286F6AE17AD95BC0BF8EF07957
-:10F440004B93DD49FE767987D003F39AACC1A04295
-:10F45000E3A15AA273F761F1BD49E090C2FE1648DC
-:10F46000BDB852E275A5C4E34A8CE306537D8C8C8B
-:10F47000E32B65BCBE3A67D7312A29A994E3EBDABE
-:10F480008E26131EE781D05BF342426F19F431ECF4
-:10F4900050ACBE400B770FD1776D9395EBD6E74B11
-:10F4A000BD35BF0EF596D25F7F740FB48BFCF17E35
-:10F4B0000177ACDDAD6C889EEF1A20FCD8CBD27FF3
-:10F4C0002E1C104D97F21EB0537E7F9EAE7A82FCAA
-:10F4D00056BB46FBB78E457EC3F55BF5E129F1EAE5
-:10F4E000B58CF64D191718FD059467C3F921E70E81
-:10F4F0004764DCFF9F03847FB366B21A20BA46C418
-:10F50000490B0AB3E2C6497309F43786DCF7B371D5
-:10F5100091719277D728E2B77F75EF2CA7BAA6AA88
-:10F520003AA12FBA26E1BA29E4F703FBD15575D6E3
-:10F5300020C53355C82FFC7D1AF109C96393524683
-:10F540007C8271C6EDB4FE42BAEAC4F32F6C44FB70
-:10F550008ECB2F2CFD92F9AB6D843837E26D40BC19
-:10F56000B8C388372AAF0ABFD6785EA97570DC5158
-:10F57000D924EAB51B8E7C33340BE1ED6EFEF3D05B
-:10F58000E5544F3E40D8E786E2D0A75457F4F51E25
-:10F590005B5CFFB557FF2BB52C0F95E68E4CF66BD9
-:10F5A0000EA21F7913EAD1B7BFE038A5E148C2BD6A
-:10F5B00094CFEB5AE11FE6FC1E3A55C326F683377B
-:10F5C000412DB7E41F45FA8D2B9DA24EE941693FBD
-:10F5D000A9FF08F2F583387746617FF937F449854A
-:10F5E000E4EBD510D83255E9AF072AA4DCACCDDF67
-:10F5F000B585AEF663FDA70A294F1831B0BD8CF56D
-:10F600009FFE33865FABDF4E64FFB8BB4D7552AED5
-:10F6100019F1FBAB41E427625C901D275FFB85E499
-:10F62000CF4E797F5C3D4965FC99268BD6F0B710AB
-:10F630008FCC37DDA71D41B26F79875FCD263E584D
-:10F64000BB3BFADE89E8E8E7BAB1A0C84785EC7CA5
-:10F6500017658CBF74F8D531C46FD56F7F3B4AD026
-:10F66000E79B5196F46BC367B48A22E2669322E269
-:10F67000E6FD5A4732C56B5507555F643DBF41EF04
-:10F6800097A53C8126F203F50374E6ABEA26C11F79
-:10F69000A666D1E2FE4B447EC8CCFBF71B2F46BECC
-:10F6A000F91E7B060417F24095B987F9AFEAB489D1
-:10F6B000E1A93A7D397344C47B015A7700E9BFEA76
-:10F6C00075C0FAC40EA46FE7D3F791D89FFF7E02EE
-:10F6D000FB61C7B2B7978BFB2F15487F3DFCF69AAD
-:10F6E000D191F660E200712F0E840737793FBF1089
-:10F6F000FB4B3C6C824532BF20F879AF8C9B302E9F
-:10F700007B73409CB8EC7AFDE9EA662B50FEB9EABF
-:10F71000032BD7197DDDBC92E37EB8EA1F4DFA06B4
-:10F72000FCFE1BA97DF8F0CAD1F4FCEBC3AB6FE47F
-:10F730007CA9B2292ACF1120F8DCE45F7DF5EE5DCB
-:10F74000E47FB669EC9F14B69D7D97EE69F7359816
-:10F75000F9DBD18AFD13760692C8AF2A9C4FDF11E0
-:10F76000ED6BD598FFD0DF32FC2B3BFB57A78AD837
-:10F77000BFC2757C416E8B4E94D3BAA78A8B689AB0
-:10F7800082E3A4D7C6937FE5E8F3B70C783E93F8FD
-:10F79000EC6E49E0BC8B02D982CF604414DCEB1ADA
-:10F7A0005E67FF645DA31AF5FD88F1DE5F06887B66
-:10F7B00087EF0C3E0B295EE6A3BDA25DD7B82F9361
-:10F7C000CEB1D61C623EA9AE338BF13DA205BA077D
-:10F7D0009AC01F4107083F27E811D2659E2538844B
-:10F7E000FCFABDBDF78AB22E2428EAF56A5A87F3DF
-:10F7F000774C975BF7A5C7B34327E99E071DBEE388
-:10F8000059221E8A1DFFAD5BE4418E9F13FAF1F869
-:10F810004CFFE8787A3200C5225FA048FA3588EFBD
-:10F82000ED63E735D37A78FEDD4302C7898F3BF776
-:10F8300026F0FD63A74BE4754BEADB34FA1E666DD8
-:10F84000833281ECD2DA9CF7F87B19EC17919E5C3D
-:10F850001B3EC8F7AF15757B6779E3C0B1DD2DECB2
-:10F86000C33CF99D72ECF87C397E063C19329EDB74
-:10F870004EF73E67CACD4EF1DD9BF8EEF556A9D79F
-:10F8800017DF62663FEA0CE866717F22EE391648A0
-:10F89000BD7DABD4F7B1DF631BFAFD76B9CEC2678D
-:10F8A0006033DD73C47E9F7DBBF40F178197D7EF64
-:10F8B000F75DBDF41363FFFE42895BEAF551308AC0
-:10F8C000F47A08ED0DD75BE426B0DD9E5F3032AEF2
-:10F8D000DF41DFA9EBF23B756A0DFA57E7BEC7F6C9
-:10F8E000F078CBB997F9FB867309901DE79EADCFF1
-:10F8F0001E1A7AE436417779EF51E114301AF4BFD9
-:10F9000084115A647ECDA0FF83920EFFC7754539DE
-:10F91000A045E6630EA9FE07DD195447DDC9FE3890
-:10F920009E80ED219E6BA83CD7506B849DBB3470AC
-:10F93000795C3EEE3B5F6A40D893746E5B72ADECCF
-:10F9400037568414FEEEB0220CA27F9BC2F9CA5136
-:10F950000D2D5CBFB1A454F178855A3C4BF0197C55
-:10F96000B4C026FC03835F7AF125F988C6C95FB865
-:10F9700055FA0BB1FC341ADA67D1FA4BBD8A87EA23
-:10F9800036AFC947CBC6BD4EE1EEB5F808F9D24C4B
-:10F990007A31969F5E73FB1F25FC75B75F5E5280C0
-:10F9A000EB1FCFFD6C28F14FE535E4E84549BFDD9D
-:10F9B0008EC071AE63A9977504F5B98D1D849756F5
-:10F9C00060BFB2D3D5BE6583F0B7B98EA0229CC00C
-:10F9D000F5A5154D76FE6EADA2A13A710CE9E326B0
-:10F9E000D563C77E79C3E952CA239417893A972A07
-:10F9F000BBA8BBABB28BBABBB9E9FEE7DC13F8EF2F
-:10FA00000344D711583A7EB5E17BF83E56DF359373
-:10FA10000F37E17F4E0F354BFC6C68BB923986C4C3
-:10FA200034DD7F88E0EE7EFD450B7D8A5135E6D5DD
-:10FA3000595482D6ECD679DE2D752DB5945636E024
-:10FA4000B7BB9D42EF9A8343D86FCDBFBE7A9BEA86
-:10FA5000836F8C25FBD5D5D236D612C1EF9D1B50B6
-:10FA60006FC7A1633598A41C6BDC2ACA22E9470939
-:10FA7000B9AE6A3E9A49F98B4E92E77C6ADF491E1D
-:10FA8000816DC5DE33C923C99FD92F5A63BD4B4D44
-:10FA90002ACF03AD63D4ED4991F06D66F82E85C48D
-:10FAA0003A001DA31617448ED7FCBFD60717853E14
-:10FAB000E888D207069E4216E0EF880387AD5CA770
-:10FAC00040F73FAE083A6A0305FD6EC2608AE476ED
-:10FAD00032DD7B0F27974F83BBA9AF41584BA5FB66
-:10FAE000E9B02AEAFB86B0BE9F28F7BF490BB750A2
-:10FAF0003DF064795F3A05DA79DE0CE8E1D60B4E29
-:10FB0000FE0EBA183CDC4EB285E7535A2B3F14E286
-:10FB1000EF7BC2999AEB824D7E6F1D87DE7D78D395
-:10FB2000E082810F95EED5443D53EC796E1828FCA8
-:10FB3000BC9BBC420F914B41F5C09320C4F7F9D355
-:10FB4000A143DEEBC73FC7548C0BE91E6F3ABA31B5
-:10FB5000898C8F20CF9F46E751E39DA7633E931981
-:10FB60004A9D049F12CE347D67BFFE7374533528BF
-:10FB7000E5BDEFEBE9FA7151DF3DA8A7E98DF7A9E3
-:10FB80007E59F17AB9BED943DF8D53FC13D63A7B47
-:10FB9000F55936C098812B72064EE8FB6E04FCC006
-:10FBA0007524B1DF8D447C27021723FE2E9251E786
-:10FBB000BB3BB848A73A9165E936FE7B3B85B6A1C9
-:10FBC000E329AF7928CD9F333083EA7DEB46F2629B
-:10FBD0005A7002FBB992BFECE09D447850BCC6F766
-:10FBE0002BC07CD3FBF70B3281BF27B25BC5773EBE
-:10FBF000DB911F6DA92C053AD55FC323253AF9D3B4
-:10FC00005B5C360F7D476C25B8ED7D70D7D8441D01
-:10FC1000488D4DD47918F572B178ADB119794E8F00
-:10FC20008DFDF198EF907E62F3DF42787A28A998F3
-:10FC3000FF0E53DE2BD3DC5C0F25BF7FAA4930F0CB
-:10FC4000506CE3E77DF594EC67D6523D37C259938B
-:10FC5000015CFF783469540AD565D5B4897AEE9A87
-:10FC60008C00EB77B35F617D5FD35AD24AF6E2B284
-:10FC7000C3C275DD352E51071FC880D0F37A343DDD
-:10FC8000A619F4A0FB4B598F64D0655C3A94D07BE5
-:10FC9000E3C2DE91849342DBCB37D0FDC2B87074EF
-:10FCA0007D19D26935D1A9F73B1ECDC9F51E067D58
-:10FCB000907198D99D92EE06BD9CC6DF23F06A51E3
-:10FCC0007F8FC0A0E3F644412F3355E00CE77775F2
-:10FCD0005A37964EFF1BE114C1BAB04B000000002A
-:10FCE00000000000000000001F8B08000000000062
-:10FCF00000FFCB936560F8518FC0F9D20C0CDEBCCD
-:10FD0000A862B4C40C5C0C0C41405C0EC41A407B6D
-:10FD10006F01E9DB401CCECDC01001C4FB81F81F90
-:10FD200010FF07620D20D604E25F407945A81B5BF7
-:10FD3000981818DA80B80388BB805887918141975A
-:10FD40009178FB93841918DE8923F87A120C0CCD74
-:10FD500052F4F3FF60C33156F4B5EF29D03E4E178D
-:10FD6000043FC71998245C50D570BBE03783074D1A
-:10FD70009E178DCF87477F9E212ABF5C0B953F4DF5
-:10FD80008781E123929A0A2DFC6E41C78A460C0CAA
-:10FD90004A46C4ABDF608CCA0F3081D000F9ADB1E8
-:10FDA00009A803000000000000000000000000009F
-:10FDB0001F8B08000000000000FFE57D097C54D582
-:10FDC000F5F07DF3969949662693900D0871028AA5
-:10FDD000A88013086940B4C322A2228E5BC50D26F9
-:10FDE00002D93710FDF0AFFD3210362DD6D0824645
-:10FDF0008B74C0A0C182040D1824E0002EF82FD50A
-:10FE0000D8BF7B5B0C4AC31692801B7EB5E57FCEC4
-:10FE1000B9F725EF4D26806DBF5FFBFDBF69F1E6A9
-:10FE2000BC7BDF5DCE76CF3DF7DCFB14DB2896F89C
-:10FE300063C6CEE00FD2AB2C8CB151DDE96CDBA0F8
-:10FE4000A187FA74E7FF5965D3EA87421EABD06EEB
-:10FE50001ED6FD9CB185547E408C6B38BB1CD3F400
-:10FE6000101B0E8F6DC91696CCD87D6E46BF01094A
-:10FE7000BE742991B1CE1556F7BA0C78AE7A5C08EB
-:10FE8000DFF7C8207750C2F73CC95216E43FA2BA48
-:10FE9000D701CCBE3F23B36CC666DAE06F0FFCC35C
-:10FEA0007AA0BE7CAC6C1063EA699905A07FEA7702
-:10FEB00012A5033436C3EF0078F92D6CDCD0EEFECA
-:10FEC000B913FDEC7380B7E8F9897E5BC0907F09B8
-:10FED00093A8FFECFB4AAA5F6F6FF1F25B6C3E07E1
-:10FEE0003616948DCF3B967FE9C2E78B9B6EA17A45
-:10FEF00018532CD8CF72B7C84FFC5C6396EEFABB90
-:10FF0000F114A27674D8D304EDFE8831E9B5BFB6FA
-:10FF100032C043D556D56305BC4CD8AA867F0C7039
-:10FF2000E95A2984B065979D31C04BFB6A0E879DC5
-:10FF30009A0FCB9FA80518AA28B736FFFC0AC4DB86
-:10FF40005699ADA366FC84F7561BC73B6BE4709EC5
-:10FF50009D83A56B774FC7F70B1AADCC0EF5956E49
-:10FF6000CF9F7A05C0F9FB5486454AD72FD0FA01B6
-:10FF70005C1892EA11EE18CFA8FDE03639B41ECA1B
-:10FF800077B89A936F83F11FABB431CFC5D06F6749
-:10FF900073F2AD8087A2D09649F85ED146C98B2C0A
-:10FFA0003461EBFA37FBC27BA51B24AF15F0525C22
-:10FFB00017CB3C43781FCEC0BFD60639FC63C89F21
-:10FFC0000BE3641948D7EA494CC6F657681E6737F1
-:10FFD0009E8E550E611E6B375CBA01DA81F7CA5EE0
-:10FFE00094BC38C4320B0B205FB66FB74F7BD68101
-:10FFF000E35BA00D76E2B8966A582E3F94BBCDEE37
-:020000022000DC
-:10000000C1FEADD526417ED1EAB55A9E81FEC575A9
-:1000100097318FCDD0AF9A412946FE884C8F019BF6
-:1000200018FB53C498AF1EF94409693719E4A29F1D
-:10003000144FF42EAE934DF50326194B82FF7E002C
-:100040007F02BE823B9D84579D6E73051FE9743B02
-:1000500025E487299DD9C6FAF5F4E74807E84F75E6
-:10006000A59BD25F54A652BAB2D243F47902F107EB
-:10007000E972D16FD758364E81765D3EE646314BF8
-:1000800098E21BA7029CE0E770F2DD01C97396F1CC
-:10009000EBE9136A20176572159BE453FA02AC056D
-:1000A000E6302FB4AFDCE89B389AB1D759E0711C29
-:1000B000FF222950807465AC3ED50F745922811EF1
-:1000C000017C2DC541021E96F4057E063A3D714F16
-:1000D000F6B3B224C69A8870DE738F66503D3554ED
-:1000E0008F0AF50C3A773DC9D3734CF5244F2FD0C6
-:1000F000EB594BF5D8CFAF9E27A68F31F7677A9192
-:100100005ECF0B586E91F3FCC6953C63ACB93F33A0
-:100110004AA89E94BBBD2C00E5659D7F58B34F86D1
-:100120007CC7C6F8118F32231F8DDF86F53941AAAF
-:100130008C7C1497136392A7785F8209EE33B99F82
-:10014000A97C927FA0293F65DAA5117CE970B75E92
-:100150002660E854385EA3FE6AFD34D23BE3FAD948
-:10016000087EA09F83F4CE03630217BBA1DFD8579C
-:1001700006F47F400B5CEE8EC237302E89A562EA12
-:10018000B1601A99BF54E5781BDFFFFBC107E1FDA1
-:10019000724BE7E07880FF4B1AF7218EFB8FA84C5B
-:1001A000816E3132ABC072315646FA6F6946F6B392
-:1001B00041035E970D007E91BAEB5DA60652911F3A
-:1001C0005B821541E4CF253041B07E8C1D6415E182
-:1001D000E085F0FE80BC54C4BF5503FD616C5F83B5
-:1001E000F68752FBADD87E5B2FED5B07E698DAB75A
-:1001F000A51798DAB769D03EC8476770BE681FF088
-:100200003786B1936C3EB56F4D2FA0F6976AACC0A0
-:10021000D47E4C57FBDF60BBDF63FB4951C63F70A8
-:100220008C79FCE945E6F16B7CFC6C4150B41F43D2
-:10023000E397A4201F7F7A111FBF95D7DBD5BEABF4
-:100240000BFF9A04ED3AA45EC63F68AC79FC1794A4
-:1002500098C76FE5EDBB172C13ED3BA8FD78691926
-:100260001FFF0525D4BE660D78918FB4FE31152190
-:100270009C4FD34080524807FA281D92C018E8933B
-:10028000DFB2818487076238DF7D1303FCE6E8D69E
-:10029000A72C041208F37099E0E9E28DE3343E3FA5
-:1002A00007695E9F2DBA3AAB51A6F98CADB4862E84
-:1002B00082FEB637CA418467ADBC3224D37C0A764D
-:1002C00002BEA7B0303EFFF3AA61EB8CE38A4C6715
-:1002D00057ABAD2D06B9EAD2EFE3D9900AE85F0536
-:1002E00032C1A86EB815F434033DFC39E8634C0FF5
-:1002F000ABDC2E39047A9C5D6C949B05DC2E09B234
-:10030000F78740FF7F22FADFAA707CB7CE9342883E
-:10031000FF6F56CCD1509FCDAE8E05A477F7A35C6E
-:10032000D0A973BB3544F6144C07889FDB491419D8
-:10033000FBD3AE1BDE945C303FD6F431BD77370B78
-:100340002D4E85F23397E70E70C3F8EF9A661D21A4
-:10035000E3FCC47CFD2D24C7ACBF2587B1690D2B00
-:10036000D4FE00DC3E4DFDBCC5F0FE1D01337C57C4
-:1003700081196E5743AA05ED994289AD857AEFA997
-:1003800030E7EBED4C9612385D457B3F011CF48560
-:1003900047F7603A021FBB89AED3DDFC5DBD3FE588
-:1003A0000FA92C4CF3714B1223FA2751B9809B8F64
-:1003B0003BB2BFD3559BCF0FFD99FEA04CF88CEC00
-:1003C0007FCBAE589F05ECD9969A2F5564C1C8F1E2
-:1003D00044F67FC6FCC8F1B8359C1F728391CF39B3
-:1003E0009F44F25379E3B85F1E32F05369FDB5BF05
-:1003F0003C6478AFB8EE26135C18BAC3543EBF26EF
-:10040000D7943FBBBAD0943F73D91C139C1B7CD0AC
-:10041000547EC6FC05A6FC7B2A1E31E5DF55B0C222
-:1004200004DF1178CA54FEF6696B4DF9965D97DCCE
-:10043000887254F581CC70DEF8DAD1FA73B437BF24
-:1004400076285EA4C711B057500E8E81BD82697B9D
-:10045000E348B2AB410FE63130A1564BFB83CBC62C
-:10046000A25E66A43F43D2EF83C134C69E973C840C
-:100470003FB94663616061892574F171A76CC86FEB
-:1004800039477E0D08FAC89EF9724BF4E7E5EB7226
-:100490002F40BDD39B3E805F7F9CE73A843D1099FF
-:1004A0005F2231BFF1B9BE7EBA5CE27ABE44AC5382
-:1004B0004A5EEA3B9EB9100E0FAE385B7BF5805466
-:1004C000D49368FD27213F801418E8515C37C82475
-:1004D000DF6DBB65EA5719EA04D0AB99CCBF574230
-:1004E0003D13DE9B7ECB30EC87EF75D4FBAC3189BE
-:1004F000E6F5B6CAC9BF3CA4227DFC941EA99C4661
-:10050000696B6580D2439505947E5E5941694BE5E0
-:100510007C4A0F540629FD63E5324A3FADACA6F490
-:10052000E3CA1A4A3FAC0C51DA5EE9A35497872E0E
-:10053000FDEB17F6B058B7C0036E0F8BB12C82B22B
-:10054000CD24E7DE5494F3538E6F06A3BD7FEA6398
-:1005500060A28CDEF115C96FBDD3D147F64A5E08A3
-:1005600098A74FCF7C7B0CA793DDC22633D0478F53
-:100570005CF49CF7DEA1042BC832C0A9DE9B9C5121
-:10058000EA85B90FE9752E3A315FE7705C67B73ECF
-:10059000FD976CACF77269209F87F7CA340FB3F0F0
-:1005A000B35EA4D70FC59BF4DA9FD25BA0DC892E83
-:1005B000FC35A73348E7486EAAFF5483952988C7BE
-:1005C000A6D8102E8D4FED7BD685F2383755AE3E2E
-:1005D00034B2777C95D667543B0CE3296F34C3A7BC
-:1005E000AAA5C9DC7FE089BB7518F295BBFAD04596
-:1005F00048FF544AF57AE6A66AD4CEB1BA41717C76
-:10060000FE0EF17970633CF12BAC3BA9FC3FBB3F84
-:10061000BDD5A3F787B106F6850DF501E40D3AF7D0
-:10062000FAA807DD95AF343FD2AB49FD06ED85183A
-:10063000F8776620D6AB10ACD75B5E2F07AD97E39B
-:10064000F38DA6F6E03D8FBEA6C7F77AE75B85B5CA
-:10065000EAE3047D75A5F0E714D7D9ABCDF34ABC26
-:10066000092E6FEC5B6D9A67F00F907F562129C8B9
-:100670003F25829B3A14C73209FA976AF150BDE5CB
-:10068000122F576A6BD1021E62C766B433EECDD10A
-:10069000F9CF73FB1F40DF1FFDADCA1EC57CE1D73C
-:1006A00051F56CB06F2DE8E711D0BD0DC55350EF7B
-:1006B0001DDD763DD927B398DF858BA402569D8D2D
-:1006C00076CE0966998CFC7F82FDDE35D2B0DEC81D
-:1006D000B768D49F99CBCCF32CD8672638BFC60C0B
-:1006E000E7B19B9391DFF356AA30B7A05C9AF36F02
-:1006F000B7B849BEF259C5125AEF083FD8BD6EA629
-:10070000F407B92F7DE599ECDCA1E887E0FA5BF707
-:100710000F1426703BA52831A4F920FF8B86913F4A
-:10072000B982E1FBA125A8A7824EE65DCF7AD2EF80
-:1007300087F63FB2BFFA7CD2C34F21FA21D749BE18
-:10074000509475DAC31649D85B414A978B71EB76A2
-:100750006B4D045C1B01D747C07F37BF253213BFE9
-:10076000A55A02359624CE5F682F484AA716F84747
-:10077000EA4FED517FED3FB5FE34A83FDB547FFDDE
-:100780003FB5FE0B7BF4BF295AFDA5AF6CDA16040A
-:100790007D53B479958BC13C7454A94EF602DD4B60
-:1007A000D62F76211F1C51822EE4E7A321797234C3
-:1007B0007EF8D222FCA2CCE790705D857F42FDC717
-:1007C0005EF8D954B4E7BE59AFBA69BD54670D5B42
-:1007D000414ECB1A0AA7A0DF17E0831C5E7A52466F
-:1007E000B8D1CC9F45CFAF4A46FF1E708A584F8480
-:1007F000C95E2AABFDF3249C87CA5927C959E47BFB
-:10080000D8FEE904D28FB95A5CCF7CE827D9F9E544
-:10081000022FE50D3F3B29BB30BDF630EA13B04C4B
-:10082000C80E8F7CAF40D841872CCEC4565842B1F9
-:100830001FB11FA1DED4F1C242DC0EAADAF0E4F04F
-:1008400083D0AFB6DADFBA2403BE74793B553FF3E9
-:10085000D7AF7A7AD7CBED62BDD7FD5E88DEF334B1
-:100860000AFBAD89A7256AD885F671C95AD51B84BC
-:10087000C7259B9E7DEE695CAF7E62F55E04F51731
-:100880006F7AE3C33100176F5113A7F06138A4E406
-:100890006EFA94C3BFF923BAE951F4F21B9A6718B0
-:1008A0007FFE7042375D8AB7ECD6D8B09EF898507C
-:1008B000BF5B6B7144A14FFDC1496867556DF85628
-:1008C000C375E5D15D124BC98882CFB56F90BD80ED
-:1008D00078227A0A7A75D12FA27C39D005F57A244C
-:1008E000BD22CBBD81FA6514AF17FD93C0DF2FBECB
-:1008F0008A7EEC4FAD5EC443C18BF7B9703C8795DF
-:100900000ACEE7CF2C4E463F7D811A4C7653CA9FC4
-:1009100017ACB99FF82FFFBDFB93F9FAD0D7D74298
-:100920007355B02F8E73F6EADB689C792C407C58A7
-:10093000F08CEC0F41FAB5C2266F892227C5329799
-:1009400093C3EB80B830CEC3B84E41BFEEEFE5D0D5
-:100950007AF28FCC61A80FEED7FDF16C2EC15F8BC0
-:10096000FD8471B2455FE7DA4CFC5BBBB419E974F6
-:100970006C802F05FD6AE54C090A7C4867A05EF98A
-:10098000BDAB53389D9847C916EF815D30019F6319
-:10099000F966D5671F6E7A8F9DC9E86E7F9E681FC6
-:1009A000FA1D83F3F9E16456501F657C35B2AE073A
-:1009B000605E37F09941DEB9FCD73EC2E55D97FF36
-:1009C000D04D9331FFABF7B91CE17B385F42BFC21A
-:1009D0002994BFFB5689F4839585A3C979AD2AE490
-:1009E000DC9C1FC92FD07F458A33F00DB69340742D
-:1009F00020BF5ADE4A78DFA857B15D57CF7A7539E4
-:100A0000CE17FA204F067D7059B73E60ABB91EE88D
-:100A1000DDEE0AF2F59B1A7AEE69945F90D7A00793
-:100A2000E557F5E3F88F6FDCFBE19D20B7C7EB7569
-:100A3000B935EBD548B92D7869BD847C1A29B7C77B
-:100A40000BC04A8926B7F03CAADC16B4FC4BF4AACA
-:100A50008EC7C765B35ED5F5646FF88CD49397CA1B
-:100A60009EA87A127EEFB3EC9EFCA8F3A1CE7F4540
-:100A7000BF29BD80FC093A9FEA7CD8C5A73A1FF67A
-:100A8000F0CF98F018997F3BF2040CC1BF5D257F31
-:100A9000624913DF8F83F7DEEC9F45F8F2D134C74C
-:100AA000AADFEC9F68844311707D44795F04EC8F6A
-:100AB000281F88802B4CE54B1AF76A8CF8206C2A8B
-:100AC000679DFF2BF6459475AC3E0F95379CD482FD
-:100AD000C81F699D1AEA3F752198A8E83FDC299351
-:100AE000FFB00370BC04DAE9D898110A821E596C71
-:100AF000E7EBCD0E77A72B01D2C5F11CEE4CD296B9
-:100B0000A01ED49F77DAB91FA4C3DFE98A37F83172
-:100B10000E36C9A4C75B426C72343F09CC3484DF03
-:100B200016D65B3EF78F76E0BE33B687FBCE40CF5E
-:100B3000AB6547FA7C5CBF56CB5E6023366BC1ED7C
-:100B40002E74A177340DBA711A3C9FFDB6CCB76DE7
-:100B5000823EA5AF61DD7184059F182BE17EDE72B8
-:100B6000E29F994D7C1D326B7974792812EFE5393B
-:100B7000E669A87761FDF0B9D10FACD753B03AE27E
-:100B800079D3F5426EAA693D58546BCE0F88F5D4DF
-:100B900037BAFEC96499A47F70A184EB7AA1B7AF7C
-:100BA0009687DE380DE8D3B14F66B8BF7AAA4926DA
-:100BB000FA9CDAC8F753593089E4AF8C7592BED4E9
-:100BC000F1D686F27571EF7AAC6DEB9FB21F423EA3
-:100BD000DAF687E1BF82B46DDB27837720FCCA4752
-:100BE000E97F603DCB4FD865273F73C72E27F17F44
-:100BF000C7CEDFA53F84F0762BF9F73A767D3B1C14
-:100C0000F9B163A1B500F560C700BE7EAADAF9EDBF
-:100C1000F0169A7F17111D33148DE87DAAE92F076E
-:100C2000302EE054138C0AED8B5DB1245FE5AFDA12
-:100C3000C91FD1B1F3DBEC80E39F379E32B1FFD304
-:100C4000E164D35EC2FEC573BF79F98ED1CF2EC0E9
-:100C5000FDF186DDDA4CC89FF0DA5F87A37EED7880
-:100C600089DB4DED6ACB1ADCDF18BA485EA802BDFD
-:100C7000DA51C8FA31B66FD1C4F128473DF1F257C5
-:100C8000F2B39C2F3E26287C3DFBEF8F0FC9C7F5A2
-:100C90009F33649370DCDF1DF803EA895D56E24BF5
-:100CA0007DBCC7EB17903D73AE71DFFB3F6EDC522E
-:100CB000F87CC6BDE0DF9CFFAD8A87FA1729073DA7
-:100CC000F97CE703046F727AA9BFE7C9EF6BFFA74E
-:100CD000D1FD25A0BBEBDCE30EFF3F4BF7B7A70B25
-:100CE000BABB313EA0FCB5BF52FF7EA89E6BF93760
-:100CF000A77B6FE3D7EDFDB72C9EF733A1FC6456BD
-:100D0000ED40C3E2DAD23D6F6742EE5B697BE3B14F
-:100D1000BFE323F67BF4345EE5FEB6F1B8EF03EDF6
-:100D2000B27849AC17F93AABBFB02FFACFCB233B1F
-:100D3000A47FDA63644F30C5B312F72BDF4A9FE913
-:100D4000A5D80B36E2E300C2EE2B056C5E6FFE4ABF
-:100D5000623EDC4AED9F7EFD3EB473D3D264B28323
-:100D60002125FBF775D764FEBC4433AD87AEF598FB
-:100D7000D7479312CDEBA889A2BEAB19EFFFD50ED2
-:100D80002914023C8C1FF0CB44F4A78EBF48651297
-:100D9000C093586011AE3B263ACCF59DC07D6C8364
-:100DA000BFF1EFC5E3C42E3C0E5CE9473C0E90C991
-:100DB000AF7A4E3C62BF096F99218CC7618A97E375
-:100DC00031A1D44B7E6AB11EC76EA21DA3389634E2
-:100DD000A33C2BB89EE678A075B8BE9EEE0DDF4C06
-:100DE000ACCF15D1A48E7F254DF6D9CDF5D1FA5CC7
-:100DF000A7CB0FA5874EC77F942EC9AA992E698EBF
-:100E0000390ACAEB645C3F8CC4F2991C4E0B2AB4BD
-:100E1000DF24D60FD778E628418027A4652A48AF7B
-:100E20007CDBF6228C1FB57925EAC7C56D169A1FA3
-:100E30006C5912E17D488D42F07B16F728A4F7D457
-:100E40002B5E39FE20433FBB4FE306BA9FEF977CF2
-:100E50007FE6CCD86CF4C7F01FC67FDE00EBB75935
-:100E6000AB593806F0345B61C1B804F4934BEC73B2
-:100E7000939FDC0CE3EFAAE4EE7ACE55BE37BDF2C9
-:100E8000CF4E5F013DF6F9458C6DC7946F8A28C639
-:100E9000F5F68F9A38BECAF7B3D0401E8721FB0DF6
-:100EA000FB8A2FABDC3FF3CA1F5F1A89EBDC711D95
-:100EB00043E3B87ECDE271A962BD708A79E2BC0ECF
-:100EC000D4AF83E268BF749FEC8C16E7B841ACBF27
-:100ED0007F83F1289076D4B26A19D757AC93FCBEC1
-:100EE000C15A1B5B1F251E668D6A117E224137F891
-:100EF000C9D9B87FC3DB9F0DAFC619E9D636E5A8BF
-:100F000032BC271DF0F7B961FFEA1FC52FAEF711FC
-:100F1000BF1BEC2D93FC51F447BDC0DFD43DDF91E6
-:100F20009FF4D2A6B516E4DF4B6B2DA6FDD83A553B
-:100F3000F83146B011D8AFA97BECCE2CA4CB3ED96A
-:100F40008BF1A5E54D27B540947DC4487C62FDE852
-:100F50007F6F55DDD4EE0EB57E26E275C7091BC343
-:100F600075F576ADBA385A3FEFB4F27ECE66F5F736
-:100F70000DCFF8F7C3EFB80E47783CAE3F6B99F052
-:100F80008344F21F233E3E55C74238BFE27A15F52F
-:100F9000C2A98D8CE67740C963B8FE0679FFB1D14E
-:100FA000AF7371E396DFA05D50D624B9714BA24CAC
-:100FB00069D1D08F5BDE182FE33C9CE9D1E36FDD74
-:100FC000C36E35C845ABAA10BEF68ED97117B6FBF5
-:100FD000659BC6D04EF1BDDEE9C279FCCBA691245B
-:100FE00007BD8DEBE54A563411E31C843E8CE48743
-:100FF000A11B634CF01572A01FCAD7546BCB3C6F7A
-:1010000014FA2DD324B18F789EFA2DF4FF997E7BAC
-:101010005FD76F01D96F9023BFC09B41BFA544D359
-:101020006F73254F0AE27DEECE412948D7B96FABE9
-:1010300049D1F4DBA64ABE2FBA59C44D7734807E1D
-:10104000BBDCA0DF1A40BF45891F19A3E97EFA73F4
-:10105000E8B7D0BF46FE36A17E8B32DE1B04FE749D
-:10106000FD36BCE920E9B7E10D16533CF0444DF8DC
-:101070009B7AD56F52D2AD681FEF53BDB151F8675F
-:1010800093B0C7378B38466C07F55C95F6C3F45CB4
-:10109000DEF9EAB97F119E753D37772BA3B8E89E3C
-:1010A0007CC8F5DCDCEDA0E724E447AEE7E6EE64BF
-:1010B000DC2F17A1DF86F4D06F8CCA9785F9FBE58A
-:1010C0008D194FDE0DF58DF0A95E1B941FD1ADEF8C
-:1010D0004619F55D95D68BBEDB777EFA6EABD07781
-:1010E000A0C706A27E8DE40F6F9339DE7CC7E8C3EC
-:1010F0001B5F4679F99D4CFB92EF59F8FED13BA35B
-:101100000F67217F7D2AFAF3A2C6E9D95E19A4FAF6
-:1011100027BCCEC757BA91FBCBCB1AB87D58562BFC
-:10112000873CF0E7A431DF69D8FFC29D124B01F87C
-:10113000266BF5130EB4EB9F5799581F4DC934F029
-:10114000C3AC9C62F2FB57D95DEBF0FCD12C85D986
-:10115000D0BF5FEC987414EDE0E21CBE1F502C9ED3
-:10116000EB71B0B3BBF464443C48E39C37FBB39EE3
-:10117000711653AD9CAE539F954218B7DA33EE22E9
-:10118000447AA1B8CEFCFC5D217F37C92D842FF6AF
-:10119000AE1C35EE432FD785A77D024F8017139ED7
-:1011A0004252543C01A5A7642677E3A5F0772D4B66
-:1011B000705FA0F02989F69123C7ADE32D72FC3A48
-:1011C0001E753F77B1A82FBF692D9D6B8AC48B8E8A
-:1011D000E7487C74E13D021FEF695D7EED9118D711
-:1011E000047C437A26F89F801768C73FEE22D3F924
-:1011F0009B8F045E46568F9B80E10F37611C3AE45B
-:10120000E7D5CC79B32FE063D4C79E11389D5E310A
-:10121000C61AC07DDA0DF64ED2833A1F0EB3723E67
-:10122000D4845ED9D1AF623CADF31B2537DA21E51A
-:10123000613BE1B51CF8D10E45F63EF5CD24815752
-:10124000379DAF6A14F313D0C182EB267DBE0AF13D
-:10125000F358239B385DCAEB385DB25827EDC7942D
-:10126000D548DE308CA7AC710EC5A1EBFA197E0E05
-:10127000239DA2F0AF128D7F193A9BB3BBE7CD62DD
-:10128000516EAAB5FA43DCE7990AF2B196D810FE7E
-:101290007716FE3E57FC5024BD2E1378DB847875FC
-:1012A00020FE3AB9FD15FE8ECE69E9F9E54AD084F3
-:1012B000D7094F9FE6FCB753F2A05FAC0B6FC8CFC6
-:1012C000903F4AC71BF233D2A1295746380FF0DDB1
-:1012D00027A3E77871BFD428F7853B0FF2FA9F91D7
-:1012E000BC2CCAB87F307FFF40BEEE4DDE8759C5AB
-:1012F0003A41F0F73BF6CEFD2391BF774ADC2FD180
-:10130000146FDAF7BCC1CAD74D1BEC2007B8DFF663
-:10131000B6EA5DE7E9A91FAEB27239C0F584C7E04D
-:10132000F7BA040782F1A675368A17A47E0CE4F694
-:10133000AA515F6FB2B3A45BB37AAF7F8AA8BF37FD
-:101340007B498787617BA8471BA1BD21DDED45CE89
-:1013500017BAFFE05CE3BA43F0CFDF3B2EBD9D1F21
-:101360001A4F55CE9A695F4C8FAB4AB5045E51D186
-:10137000BE9B2C99E2B7A0E782CEFF70FDB76AA3AF
-:101380007AAF9FA5DAC88ED0CFCB5E2D3B5810F038
-:10139000F6A54F2579012BE383B1387F8C8779102F
-:1013A000922FF78FFAE86ECA97699FEDC6DFF5298D
-:1013B000C57DC81B790C1DBB315322FBE13DAC6CD4
-:1013C00034DAE136E6B38A26213FE747F1213CD7FC
-:1013D00092595B3DC103723DA22E5485A9774267A5
-:1013E000E23B48AF7132437A35FBFA4CC0F9F7BEA5
-:1013F0003FB34CDC8A073B81EA19B18F2561B931D3
-:10140000BE245ACE8C6EF8EAFD5BA07FA3F7CB5EBC
-:101410000F94BB69AFC381723664B585050C78192A
-:10142000C34255E8771A7DC8770BEA8302B07BF098
-:101430007C4941D3DA2A17C2AB257ABF3C1898E41D
-:1014400082FE6DAA3939E932D40B500EAB295FCD3B
-:10145000CB95D74A5E0C71CE6B5A41F14879B512E3
-:101460001D60DC1492988DD71BB241BD9B56C3FB07
-:1014700059387FC1FB586FEDC9F76F41BD03FDA41B
-:10148000F737F2FDFA3C78CF8372523B87EA2B5C48
-:101490002D313C0753B091CF4F05FB552FE637EC6C
-:1014A0007E8AE6DD29D05EDF0C9C8FC213E93CD139
-:1014B00048C94DE7381FBE80F456070E185FF0A5E7
-:1014C000F3F80949C062FDA3DB7FFD6DFC5C539E10
-:1014D0007781D607EA79272729C342FC7492F6E17F
-:1014E0000F01BE03569C37793CCBDE9C2FB416C34C
-:1014F000FC98631B44EFCF6A1C47711EB3999FE2AF
-:101500003CA68EE676E7BB57DA43E8EF7B57ED4C17
-:10151000C3E77BAFB4D2F3F64D5C0FB70F6821BFC2
-:10152000FBE1D52AC3F32F55AB65D2138737AA74D5
-:101530006E577E86C737E46FE276C8DED5BCDEC361
-:1015400075DC7E9BF0CC6D93701ECE5FCFCFF9EA39
-:101550007A5A5F87E6B90B4DF35BA49ED5F570A967
-:10156000C04741F55ADA4F8FD4BBA5FA7C18A16F5A
-:101570004B719F9DF6D3C32447A5F591F1658E6EFF
-:10158000BF0DF243F83BE2EFB2FD2AC3758DF4457F
-:10159000DB248A67C3F91EF24737493E8C7B28F863
-:1015A000D81A227B3C943BE33F709EF9C4CAF0C832
-:1015B000482BD203F4548EB5F38FBF84E747DFB3D3
-:1015C00061E410F04F2EE15F8F13CE5ACFE37EB26D
-:1015D000DE5B998CE78DD9C43EA407F26B641630AC
-:1015E000E88DA392EF963BF9FCE046FB47A76B968C
-:1015F000569D87F36C918DEB47CF7A95CE8BC70BB9
-:1016000018D60B3EB4770AB7AF48D60CFC50B87367
-:101610004532A80EB644C4CB548973E6851A6FA729
-:101620007097E45E6B6847AF47AF57DBCEDF1BB404
-:1016300093A7BDD55F88FDA3717EADA1DE88ACA761
-:1016400047FBBDD493F35FA757E2B9FF9C77650AC8
-:1016500076CFF962CA20E33E8F9EEA7EE6ECF72D54
-:10166000CC67C05FCE1F6398CF40EF865120FF400C
-:10167000BF1B1AB93DD730EAA0569A45B01BE5BD4D
-:101680004CF8A3CB26F2FDBB86CCF716A1FC4FC9C4
-:1016900092881F5830A0F54924FBCD83FB00F959EF
-:1016A000FCFD7C781FE5B2E1292EA7A02F3CA84FB6
-:1016B000CA56AF9844E56B250FD6DFB03697EC924B
-:1016C000821C99517EED41B2930A1A0F26A23C83E7
-:1016D000FCAE447BA06CACD58DEA58974B5DCEDF59
-:1016E00015E76199CD3D0CCF77E0765834F996F740
-:1016F0003361B772B92CCFE172FBEE261547783E05
-:10170000724E72ADCBB18C729CD52DC77B574FD02A
-:1017100050AE0F87248AA399807A00E57C831EE768
-:10172000C4EDD8F395F373D999A520BF385FEA7259
-:10173000AECB75A43C372B2DB7623FEEBBD24EE348
-:101740009870D5F60FEFE3FA8AF65F275CF5603202
-:10175000EAC73C85C779E9782D55785C608F7EAD06
-:101760005CA0F53D9FFE45F4E333ABD95F126F8B70
-:10177000E7F1EFB52AF1FDB9E4B3879C9DA77C9E04
-:10178000AF5C9D4B3EF5F6E59DE67AE2916947F543
-:10179000ACAF1DF018063CBEB5F1598A0F3EF1C240
-:1017A000C1A94887E21DC0E7C85F1B9D2C8C7A4EFB
-:1017B00009D1BC55D420D33903A684B36F711AE57F
-:1017C00098C775156F76123F15BD640D4D81F78B67
-:1017D000B67D319CE26A167652DC5AF005612F071D
-:1017E0005B86A31C14293CBE2C522FFCDAC6EDE705
-:1017F000B6EDB1D3707C521DBFDFA2A8FE76D56ACC
-:10180000D8A778C2A652BB508EF67983C0C778FE9F
-:1018100017FB67BC57418F2B6BDBC0F54451A31AF4
-:10182000C27B328AEAB6B463BC71D1C756F27F95E7
-:10183000D79DA4F31413366F22FF4A79A36CDA8F75
-:10184000EB11DF592787AD1897D8504AFB90001F3E
-:1018500024B85EC453FEC0F8C3E2CD3BB705018592
-:10186000C52F3FEF42FD72AC79BD0BF10EF59E35F1
-:10187000DEBA473C67FD23229EF386C3746F4B2F6D
-:10188000F19CC7F00F1094B76DE6784E56D787ECF1
-:101890004BE867B63FCAFE47977DBEE9EB35781E39
-:1018A000A1EDA5E36BB0DF257FFB720DC689B15DAD
-:1018B000769AF7CA5FF880E2B7F5F7BEB0097FC83D
-:1018C00086E729FEBDFD13AB176B6BDF79381DE38F
-:1018D00006DBB77C978CFECC793BAF267FEFBCADA7
-:1018E0001352589479434F917F43E7117F1F49B7B3
-:1018F000BD0D7B299EED04D01DF560579C6E7D29A2
-:101900008F7FF688F8DC8DD1CF3BF488C76DB8E5C2
-:10191000C62B51FF37707BF29C71B9EF033D2F3F0F
-:101920000F3A6E14F1D7F5379C352EF704FE01F40B
-:10193000B2D8CD74FCBA61F6AF9FC6BC863EBDC6B8
-:10194000E586CF037FFA798A776C3EA71DE5E8A587
-:10195000DF503C34D26F8A07E7A3AFD3F13CCA1102
-:10196000B5733ACE3F9D3BAD74DF4FD1CE8F489ECD
-:10197000DAB7BE477E6A26CE35B4B3AE1F8F3F9727
-:10198000C4786B9D3C9E57D001E37D3D2E7A2EE2BC
-:101990007A395FEBF1BEBDC5F95E6D1F28EE0FE031
-:1019A000F1C8A5B57F10F1B3DD749372905E07CFD7
-:1019B0001A47ADE3C12DF472771C7BF4B8EAAE3858
-:1019C000F608BA213D719EEA8A5307386D04F94939
-:1019D0003E8A762EA27D2D8F7F6F57A39F37D6E349
-:1019E000DA7D11F4D6C7DB9BBCE8727BAE71FC508C
-:1019F0003CD16642524F7CB57D1F5DBFCFB44B7F5B
-:101A0000D7FABEEBBC548914791EEB5EE4CBD286C8
-:101A100083E4CFEC5A7F8BF1B609FF7BDB0B32C539
-:101A2000392FA9DF4BFA3D527F94E1BD2D51FA7B4E
-:101A3000BF5DD8E78D7CFE687BC91972403D6D7B28
-:101A4000B6135F976D3C4871D66FD6BDACB518E242
-:101A50002770FE0819C6D3F6E2EEE1A4CFC5FD302B
-:101A600091ED548976CA9BA2B753BEF1A4A99DE219
-:101A700060BDE6769CBBBD638AEF76ACEF5833B7AA
-:101A8000138FD5CB9343D1F669ECAAD8EFAFE629F3
-:101A9000CCA3740F8E93DF7B23BB62C8EE9CE7CC94
-:101AA000F9382E11538DE2BAAA168838B09F7A53AE
-:101AB00091DE55CEEB18F67731E2D7E0FF51DD012C
-:101AC00086F6AA9AEACF42BF43A4DED1122D2C6437
-:101AD000A0F73CE7E4140FED8B84D3909E07320F00
-:101AE000AB58EF6711FEABCF14B62405FAF7595087
-:101AF000F22E807AD9F75F0CF03B7BD6AFC381879B
-:101B00006593BFA9CCDA7900D72BEC353BED47C8FC
-:101B1000BBEC747F48F91A3B8D77EFD66F9F23BBE0
-:101B2000FBD756C6F787605583F796B9791D87B7F7
-:101B30007EBBE62F6857E3CBD07EFE1A288FEB8959
-:101B40008DB1B4FEE978298EEE51CB7FEDA1A9A825
-:101B5000D7F263393FE66F4E0955417DAD491C6EA2
-:101B6000DD3480EEAB287EC949F1A57BB7BE528635
-:101B7000F354FBE6580C3360EDAF09FBFF37E27E10
-:101B8000AD1AD5638C332F648AC7782EA818615399
-:101B90005C13233F06C911FAB11AE3E83C11D8C51A
-:101BA000A67A4EA89D0F78898F83FDF839AA703FD9
-:101BB000D40791E5F4FCFD767E8EBDDC0AEF39BAE0
-:101BC000CB976B9D791CAEEEC7F5493395FF44E783
-:101BD0007391DFB35E5EFE23BDDEAE7AF8FB65E295
-:101BE0007E9B48FE3DD4A557FE7A71B4FB5BA2F400
-:101BF0009F9EDF2FB1A005ED962D76BAB70BEF674C
-:101C0000C0730EDB34BEFF55E20AD3FD393B843E80
-:101C10002E8909D37D3EFD443FB03CC2CCD6F22292
-:101C2000D2BDF4153BC3F8B3D2D79C3EA477E9B636
-:101C30006F5B7F9585F18BB1E4D72B7DED7F111F15
-:101C4000945AC3D3E9FEBC2D5686F7E7B56D793BB0
-:101C50001DE5B54D0DA7279C655FAFB4DE6ABE5785
-:101C6000408CE35865E842BC77413FAF5BD48B9E24
-:101C7000B93286DBD7F6189F3586E4DD7C4FD4B1C8
-:101C8000CAC641C6F3FB459EE87AB17F8CFA8F9DA8
-:101C90004377F438F7DA3F2609ED99E66474409605
-:101CA000813D8EFABCA8EEE430F41F7C16A3DF6FF2
-:101CB000E089C3F9E833AD7318EABFCFD23B871987
-:101CC000E7992395368FA2925F87D28EB527F3FAD4
-:101CD000318C37B54F8BA6F786C5C412FE8A1E8E8F
-:101CE0008D7A8E7A4C0CE7AB34681F536C17E54342
-:101CF0006FF7332D447AB831C6C3EB490B69F8BC92
-:101D0000B86EFB20231E0A956A2A07724AF82C64D3
-:101D10002BB52C83FED6DB2B9CEFF028743F81F291
-:101D20007FBAF855EEA6333991318E51E014665CD6
-:101D3000F233EBE74814D56F43FC69CCEF5664648B
-:101D4000956A92F718564FA903CC2E7E5F5A054329
-:101D50003D7944ECEFA31F0CD36E7C3D487A3F38AD
-:101D600080B18B32F0BE094F9CDB80BF6B70B33EFD
-:101D700009E3692B18D71753DC688F48C1003B0370
-:101D8000FC5455593788DF03C27C182F49262CF4A0
-:101D9000CFE57EF33BB483804FF93D8457B15015B6
-:101DA000A018C386C9EF3A9EF1FBF3967DCC8CEB6D
-:101DB0008F12410716DC4D7ACCC1BA7F9D00A35A21
-:101DC000457D5B15F7B71CDC9F73B85918EDC358F8
-:101DD000070BC742EA18AA1C33CABF2B0B60035F6C
-:101DE000BAC79AF323E502F45A44BBF5843FA8F737
-:101DF000AB887ABF8AA8F7ABB3D5ABE3A9DC3628AA
-:101E000003EFA5585C592FF0C6DBB309BC017E86F1
-:101E1000E03D7FCC12E315FBE684D718D11B2B964F
-:101E200007BA6E8EC9207EFA59DCAE4E8C97668951
-:101E3000350CD7C38B24FDBE4FE67718DE636E1BCF
-:101E4000C9E123A29DCD02CF8B74BF558FF276B22C
-:101E5000BF7A94B7F7563E267A79676FFD898DDE93
-:101E60009FF85EEAAF8E8D5AFF0FD54B65AF7DF4BC
-:101E70000EEEEF76E92737A0DE6C676E46FD541A4A
-:101E8000DFFAB7167AC2ED4C5B9A99DE31C8DFC033
-:101E90006F31179A9F47F24914FE72F48571DF295A
-:101EA000DABBF3617E5E4DE7835C31BE89B57C9F12
-:101EB000FCEE79DC8F07CB461FE6DF25F2EFAEE1C3
-:101EC000F6E3DD0FCBB40F1B79BFD5C1FFCDEFE13A
-:101ED000B8071F80BCDD335F0A8533A2DDDBC5DEBA
-:101EE0008F877A6788FE44DE8315609E49CBE4685D
-:101EF000F76071BED4CFE145DE7F318BF9C5FD6659
-:101F0000E6E759316EE2DB2225A4550FED9EC7822C
-:101F10002B80EFD1FE04BEC7FD2F599CC7662E8DC6
-:101F2000C7D7DF9A60D27FA78678E270BE66AF8B94
-:101F3000E76EFE7CEEB59E14E37945E574ACE91ED0
-:101F4000A02AD59B8AFA4D3D7D3DF3801C6AA707E8
-:101F5000318F211FEC56127E0CF3243D95AA84503C
-:101F60002F2A6E3FCB47BB379EF3B35E5E4BBCAEB2
-:101F7000CBCE7C17FE1D46E681FFCF5DE1A1F3DFEE
-:101F80005739FCA771FE955D39DE80A3273F04B762
-:101F9000F27157E1B8337A8EA74AF37AC9DEBE0EE2
-:101FA000E645F2CB796DD83FD9EAF9C883FDFBADA0
-:101FB000CAD00FD3133FDE2321C83F15EA4F712447
-:101FC00072DC94C1D8FE72BC6F14F4FF3271BFE8AA
-:101FD000A24A26521E57B708EF1FA53447A43E91C8
-:101FE0004EA6728F8A7B4A97547A29D5F16BF356A5
-:101FF000D33D98B60B79FB36B7A05FA245E02F40E2
-:10200000F6972DB582F61DEDEE8A30DE27C7D26039
-:10201000DEC161B9AB09BF9A9B91BF13CA136C456E
-:102020001852B5660AD1497157B07CC84F7504067D
-:10203000C7A27DE331DF87694D1D71D6FB31BBF847
-:102040006D13C7FB6312E7B748BC3FA6367B306E03
-:10205000E2B16BBBEEAB22BCC37288E3FD3FF97EFD
-:102060006E4FBC374F9B69C0BB337B32E1FD6702CB
-:10207000CF4B055EAB041DAA043EABC4BDAF55E219
-:10208000DEDC2A81DF2AC43BA48F887B7B17233DBB
-:10209000209511EFC0BFD6A14126437B7C0F0F5284
-:1020A00087E05BB785FCA4B2C3EF43BC5B1339DEAA
-:1020B0006D0EA003F135E0DD83F941C2A7EAE078B7
-:1020C00086F29C0E025610EF23F139A707E0FDB609
-:1020D000D824D487634C78D612C79F1FDE9FE2F3C3
-:1020E0005BA290F348FC256AFC5E605DBE7BB38F0B
-:1020F000AB445C7695B89711F18876CD2AC00FBBBA
-:1021000098E3933F1F22602FA54962FD5F0574C0CD
-:10211000FC27853D8478C674672C5FB7245A2A76DD
-:10212000AB88A7047EDF0F4B0CB2B46CC64380F1C2
-:10213000971A641E84F5FDE15A33FFC86E25E27ECE
-:1021400049CF93C86F2BDF562DB87F2FCFBFDE74DA
-:10215000AE5B9EE68BF710FE0312DA353F1372B8C2
-:1021600002F985FAC7D7C38B051F2C15F7063F2246
-:10217000F8E73121CF8FEB7CE3E5E748964FE6F1B6
-:102180008E89991671BF629819E309E3BDF54C83F6
-:102190007ED1DAC64329DD9FC93EB692DCC60E6504
-:1021A0003EE4AFF88F1F0CF1FB70FD7DD11E8AD786
-:1021B000EFBF1DEB89BF830EB4871571CFA4CCD7B9
-:1021C00093CD51EF8DADF2EEB1A15FA6B7FEECBE9F
-:1021D000691BF173DEE5441ED627E0BF6336C08E6F
-:1021E0001A5857C12FD61BC85E8C7AA5C649FCEB7E
-:1021F00080FEE71BF824B617FFCE54C7B51B505F0F
-:10220000BC80062430C12F6A06D911CF80730FFA23
-:10221000B156A9FEBE382FAC8A8FEE8FFB652CDF3E
-:102220008770655D6AF22BAC547DF49E7BAC59EFF0
-:10223000AC14F344C244B39CE8F3C24F457D573914
-:10224000023BB15FC9A727923C27DE1C7D9EA852A6
-:10225000B520DEF751358CCB773057E3F6730FFDA1
-:10226000C3689FE45460F03AF483E97CB690717DD2
-:102270001764DCAED4C7F504F2BD15E70337F13FB0
-:10228000CE0708CB176AFCDEE3BB2DE4875822E4B7
-:10229000ED512167CB857CFD1CE5CB8AF7587B2966
-:1022A000FD8590AB952887901E8FCDE0F6BCB83F9A
-:1022B0004C5FCF2CB48DA0FB22AB1C169A17944F09
-:1022C000AC2107AE0F768F76A3FF477666B9034E33
-:1022D000CCCFA2FBDCA5F82C37F2CD37CE59179C1A
-:1022E0002D1E16C84FF7162B2AF74BEAF7C8578949
-:1022F000FB0854F7CD0CFDD54F2656D829DE359670
-:10230000C787D7E46613DE811E9DB186755ACAB4AD
-:10231000EBBAEEFBC3EA9FECE55E83EF85DE606916
-:102320004176A1414FD488FB249927C88618F4C56B
-:10233000C28B2631F4EFF5D413BDE8CDF55C6F2EDA
-:1023400092A2EB4DDD8ED7F566A47ED1D3C5174C96
-:10235000369DBF541D5E467A6748743F42B2C3CA79
-:10236000F72F99D79B9BD1331FF095EC30E00BED05
-:1023700021DD6FF1E328E389D49347AED3E7D7009B
-:10238000DD3B344BF33C39FAACF3AB795EC83FFD2F
-:1023900008CD4F79A747535A50732DD9230C77692D
-:1023A0000CF72E1C5E7DBF0BE97BB846EC9FAF5649
-:1023B0004318BF74B8667119C1D5760FD266DC2F89
-:1023C0001E74E13D4DB3D6C8B49F7E2426984EF1CD
-:1023D0009FDF9F39231BE26316AC5D9A8EFC386B3E
-:1023E000DD523A377B24C137D86F80599687EC7914
-:1023F000FDFEC6BC67AD3EB4C77BE3DBBCD5D1FDFB
-:102400003D55F827AE53987708AE4376BBC6748621
-:10241000810F8EFCC24EEB822A2DD88E70D5BA5811
-:102420007C83552544BF0F28D571B50FE994EAF098
-:102430005D8B297324D07E4FEF72C4DB6F455F3B09
-:10244000EEBB3E2DEE45023ADD64F2BBF27DD7567F
-:10245000E14763B65EF26344BEA7977C178F936231
-:10246000EEE8F97FB7FF69688FF55D318EBFB4E69E
-:10247000F8924FE889791FA150C48BCF5A171B5A85
-:102480001845CE6689F3C7B3C47E99CE8F85D7EB46
-:10249000F639E7E3483E975EB884F8FACB7D2ACD5B
-:1024A0006B65C0AFA8EFA51746D37D500B9EBBE26E
-:1024B000718C0BFC6ABF4CF925A7EDC4C7ED3FF545
-:1024C000D23982CEDFA9F49D88AFF65D4DE701DAFF
-:1024D000C5FDD33A9ED29C7C3DBCC6C1F550DEE919
-:1024E0009F913C74F15768A686729E77FAE75C5E0E
-:1024F000F0FED93138ECEBDE1C77A1E06B80D72CF5
-:102500009F346921D49BDFC2E58A8D0D96911F7B94
-:102510006DACF7D128F2BFC6E131F9B5F25B96F3A5
-:10252000F7C0AE4C34C499CC12DF7BC83FCDEF6509
-:1025300065EE204B457912FAB05B0ECCF772B7DB33
-:10254000CDE3D4D317BBC6798569FDD63DCEABE8C4
-:10255000799EB053F25B4613DC3D9E5F8D8E369EB6
-:10256000EE718CA5F2EDF1D1DBFF50B4DF5A59C00A
-:102570007CA04F8BC4FDBF79A1FB34D41F79ABE3A2
-:102580001324C3B8F26B8A4DF14F7935B974DF5F0C
-:10259000FEEA5CED5E83BC76D185CD36D1E543475E
-:1025A00080E832D5E1DFE340B97CA1F0814F3D58AE
-:1025B0002FA7D3112D38BC82F4DB7DAE68E7A73E90
-:1025C0008CA4538DA013AC1FB20C74D2E913F97E06
-:1025D000EBFAD2073EC5FD8BA7F8ED45BDEBB10880
-:1025E000FA6544C75FA783F36B2BD80F81F3C2DF73
-:1025F00065A6F8BB5EF127E8ADE3477F0EF6DF5135
-:1026000094FB4E94CD51581FE78773E1ADBB7DC15C
-:102610000FE3A28F27C5A9F3C37C1604013EAA715C
-:10262000FBA3F7F13CC482B6F3184F979C2E36F10A
-:10263000438A7301975341FFA37B1E21BE6E0DC5D4
-:102640007AED19BD8F27C5D90B1F5C186443B3FF02
-:10265000EFF1C111CD37F8299C4760DEC279BDF09A
-:10266000F9C7861BFB97EA1897E6C479A9FAFCF626
-:10267000B783E3BDFB701D1E5C277BAB6048258ED6
-:10268000C0607CBFC8F5F437E8DF5B14FFC4F068B6
-:1026900076F4E2CA7D97A0DFB5AAB2995255D8C5A3
-:1026A0000CEDE20CFE5D8F68F7055E2BF4EBE2CAE1
-:1026B00066EEB7B50599DB70CF003B3292FCD88A45
-:1026C000C36CCF696AC08D7E734DDC83A02A81659F
-:1026D0001959E8674ACC0C1AF0778D93EFD72C4F35
-:1026E000DDE3C6FD102BD48FFE335B9A72CAE4770C
-:1026F0007B5D99E5043AE9D744C7B07A9F24911FDE
-:10270000F254841FF294A91F89CDA67D8A48BC2863
-:1027100036FE1D288509FFB3C087FE9DA4A56E3E29
-:10272000CE95C28FFD04FAAF2F023B36D645F6C1D7
-:10273000920B2C7C7D6853E8BE2B6B3C2FAFC5F110
-:1027400071D871FF43C6F559986027DE1026D3D59E
-:102750008B12C2F1CC2321DC878597E07AA3635CDE
-:10276000CB03F8FC797B20D70978FFA66FF301092A
-:10277000F733FC818B11CF357230D303E57F2D7792
-:102780006662B974C8FA3881A717E0398780619FFB
-:1027900094DFD7DC0DCB3DE10BE62B11FB86DF5F31
-:1027A0006CCCB7C7F82AB01F91DFCB4AFC42A2FD20
-:1027B00041FC4C079FFFFD343F2F77F27505F10771
-:1027C000F2D73E6E3F9D523C71B8EF87D879DDB4A9
-:1027D000EF63F3BC6E684F11EBD85AE057C5B04FAA
-:1027E00077A1E2B3203F5D540DCF8DFD8D62272789
-:1027F00038E8DAF2A876BDDE3F3CAF83F8944F4F5D
-:10280000227B24922F7674ED27F0EF69DDA1339EB1
-:10281000B288C3F14CFFD1FAEE93AEFDAA451C7607
-:1028200073A8FC5EBE3FFE696E1CC599EAFDB8A3A5
-:10283000696933DAC57734F59D89F8BCA3E0E23FD6
-:1028400063BA43EDDC138BFAE27E89CE97DDF9C1E2
-:10285000EB6A2CA45BDF5F47F71F3C2FE4713AEB78
-:102860005491FE01E6D6F87E5788DF47C5BC02AE1C
-:1028700057D15F71773874DB0D00DDF37AE80634E9
-:10288000F7A6EFEB7C03D543A0DE3D89F694F4F781
-:102890001ABD6F7298BFD7357EC546E3E91EAF8D6E
-:1028A000C6AF8F0F7A4AF8EFC28FB8F74DC7C7F897
-:1028B000997CDC77C4DE751D3BCB3AE00EDBB03F84
-:1028C000F3783EDE9F48FC7C8559A01F5F74FAF6C2
-:1028D000203F3EE3F4ED45BD5762EB4C570692BCFA
-:1028E000BC85CFCBE4C005C930FE130302172721F6
-:1028F0001E9AFB9C97BD7FC0CEF9FB809DF3F781AC
-:102900000C9DAF5B9CC8D7EC74228D53FF7EC792A1
-:10291000AD871FBB1DF8FBC4DBFC3EBB52D973E384
-:1029200043E4979699312E3E323D20FC0C2D5D7C80
-:10293000C8C73B43E1F232A32196CEC1CC982F9B6E
-:10294000EEDB9F319FC7C332A579F8ADA675C222D1
-:1029500011D7D2B31EF48344D63373FE04BA17657D
-:102960009BE61E477E91359CCF664EF4C9788E60FB
-:10297000CC3289F6F1471FF234B6003C3314EF45F0
-:10298000319DF9E07F0DC2FB51CA9AB97F34459E53
-:1029900093F9534857EDE1F33DC273104F0E9FC7B3
-:1029A00061D8CF69532B32DDC8CFF7387CA80772C6
-:1029B0006FF57D8274D5FD22FABCFB0AD801181789
-:1029C0009A7BB72707F924B7DEEEA3D4C69418D0B4
-:1029D0006BB90AB3619AA231C58E690CB3619ABD15
-:1029E00050D84F353791FDE0CAF16B78BF796ED37F
-:1029F000F35FE3FBF94A78B764E0ABDCA6B7BFA3AB
-:102A000073763E3FC5FD5E56A799D69FC3EACDF0CB
-:102A1000E58D6638336C8647EE33C36538366867B4
-:102A20008CF81EE19E9D5686DF2B2BDE6CA538F4BC
-:102A30005771AEA0785E3BE9C509C54DD91827711D
-:102A4000FC45A705FD953BFEFA32C559746E8A65B3
-:102A50001867B8FBD318168371BC9BEDEB30BF1819
-:102A60006887FED9E2CDF6B5184FB3ED529D4F43BE
-:102A7000140FB5ED6FFCBC4BE7066B08E32E8E6FB1
-:102A80007FFE45E4CBE31BFA931DF6AA14B4607DE8
-:102A9000C14738DDC708BD3E46E8F5E23AF37AFCA7
-:102AA0000A976EAFBA87E2FC372681E3BBB5B22F37
-:102AB00087C5772574FB6D8CB067DD40CFCF8776F7
-:102AC000D37988D0CF79A17B351FD16B410CEAB384
-:102AD0008EA3DA0CF44B5D5C63C6A3CEDF9784CC87
-:102AE000CF27BA24A1E70CCF33305EC5B32415E756
-:102AF000EF67A3DF537FBD8BDB192FBCA0E9F2206A
-:102B00008B7B2A99C770AEB25BEFB379FD319E081B
-:102B1000E935B0FB797144BB7AFDB12E2ECF5FDA77
-:102B2000F879824481876395FBC86EE8B2232B7DD8
-:102B3000BE890638AF6677722EE16F77F2BD86F9EF
-:102B4000AA64C3DEE4BB304EAE4E418F362BB9E3F0
-:102B5000B99F8F49C4E7723DF613F3118F6DF56F7E
-:102B6000B8B01CD8D9238C7167F93557FB261AE405
-:102B7000FE87F2B94EB71237C7CB2B39CD93F09CF5
-:102B800048710DFF8E6171FD6DB7DC80F85ECDCFB1
-:102B9000D3672BCC2F833C966CB9EDFA61F0BCFC6B
-:102BA00099515EEC0F54712B3E2FDE7892CE153D7D
-:102BB0006AE1FE8E48FA04059F3DFA134701EA399F
-:102BC000A8EF75CB087A7F9F05EC9B23E383EFDCAE
-:102BD00005458EB3FA0F6FA0F830339F02DF4B68C4
-:102BE000BF75AE97BCEBE8E9C2EC9BD154F72DA0C2
-:102BF0007879C88FBA7E290C99EB89A4EF6AC16FE6
-:102C0000F01B62E493C8727DA604E9DC74C97CD031
-:102C10009306FF43C9A16A8ACF8D6C07235898C1D8
-:102C20000EDA81E17528979B789C16FC245BB688A8
-:102C3000631FC461BAC715F91118A2F85236D183BF
-:102C400078BD994DC654D7376D39F5C3B1FCAB5239
-:102C5000CB73BFA2FA9C24E76DEE30DD6FDB4F9C97
-:102C6000476FF37058FFEE8F9E5FD464A7B8AEE352
-:102C70002734D2BF0B309E14CBBF68B758C0683D15
-:102C8000BEA5CF788C536EABE7F7A51FABEF335ED5
-:102C90003BCBBC1EA94FF4F9F620FE391AFD7ABED3
-:102CA0002617CE838B781C774A9F8ACC8A2874D2C9
-:102CB000DF4BD42A3271FDD3798FC3BB8EF014CC95
-:102CC00050C8EF9F4A7E9A5CE19F3AE8F6BFED025A
-:102CD000BA39A1AC0FFE25EC93D7A1DFF30BD9FBDA
-:102CE000807B50F73EFDACAC009DDFA30FF440FBB2
-:102CF0003315165680DF66E23C359C609A4F67AE0E
-:102D000096289E71D672F378F0BE6EE3FC5AC0AA84
-:102D1000A9DE22564F69C16A737E21CE472E3C2719
-:102D2000C7E3768A6ACDF9FAB9C0928D67ACD1F063
-:102D3000F635D3C7E7FB02C727DD6CA3FEDDB72A54
-:102D40008EEF7769CC87F36DE72A27E9FF6216A03B
-:102D50007EDC29E6FDF207737DB320ED983FD33783
-:102D6000AB0F9ECBE7F3232D19499EF9BD7EC5130A
-:102D7000597800BFCF87E1BC5BDC248587216C03D9
-:102D8000511DC19FE3BD26387EE379367DFC386E48
-:102D9000E373F63EA76F119E9B92F9B88DF9250259
-:102DA0001F251BAD267FD1988D52D079399EAF6AF1
-:102DB000A1F7CA1ACE584DF58A791DEC016607BAFB
-:102DC0008D29582BE3605675E9F1D025D1CECB1C67
-:102DD00010785C755B5E5F94DBC7D1BEED27109DFC
-:102DE000437A4AF8A358D806EDC58CEC82293F7B7C
-:102DF000218793E21EBDA6268DBE2F4AFB61336557
-:102E0000FF9B780EB3323ED0370EDA9969F1A52BCD
-:102E100024BFBEC1E46F9DCFF1F0E4888A4B2AA2A3
-:102E2000ACB7753A3F21D5539C40703B9FA79D5945
-:102E30009D6AC0201723E3B8BE8CDBD342E78F3AEC
-:102E4000B74A74FEF929E9209D0F7EEA5A0F43FF25
-:102E5000402AD009F5EF53125B84F7FC6535DC346A
-:102E6000E70DA473568C17E30F4A1BC6C9A50E1AAB
-:102E70003FB7E3622BD6E2BE54CA8C212390DF61B8
-:102E8000DC336E86E7A3E33CD45E5F07A77BEAC230
-:102E900060C6DCA1D8BE7FCE1B288FC362E8BC7C95
-:102EA0000AE0CA9940E932B4CF5259E66EB43353BE
-:102EB000A77846A04F7F958BB793649167DC84F623
-:102EC000E3080E273C2CF9D61113AEA07652ACFCC9
-:102ED000937AF81CED4D1BFA271C067A4FA8C8C43C
-:102EE000F65306F134510BA7613DFBBBE81EA075FC
-:102EF000C83C37237D3DEFBB7129B82EDCDF060BC4
-:102F000075D063FBD3F4FD97B083ECFB0B87F0F235
-:102F1000C24E9997C9CFE724A6EBF6152FD7A1FA91
-:102F2000E246A25E7D8FDBF95F397CE407BF42EBAE
-:102F3000E53C80A053F9E9581632CC0BE5D3BE210D
-:102F4000FBB3FCB4CBF41CEF0935C6959714ECA188
-:102F5000EF3B94B2663A9F505A6F8E83BF22267A17
-:102F6000BB3A9F979F9659306ABB9AF9F9E93E2C74
-:102F7000D8275AB964F3F3D392196EFC569453E8E8
-:102F800039CB6971E1FA710ACE47A8674296A07AF7
-:102F900079375DDADD2DA679A8DDC3E10EB1BFA8D2
-:102FA000E7EBF5B74FD3C4393D7ECF7B5B252820B7
-:102FB000C0CFD34D27C9DF5DD2B49BF0A3F3453713
-:102FC0009E6259D080A7E4AAE6B00564FCE9B8FD8A
-:102FD0004B875E0224D9A3CBF33B4B7D63211FBFFC
-:102FE0006B6190EFD8AC2E792775B3CA220BFDF038
-:102FF000EED289638D302FDFFD7EF3351381B7B2BA
-:1030000086F2F76BE3DE7B6B21C606759D3BE84CD1
-:10301000F73B0DB02D0276003CCC00BB23F213230E
-:10302000F25323E0345EBECD194E97BD8C6D8EFBFE
-:10303000E01A05F45C5BDFF074BC796479D547D79E
-:10304000E0F78E4BB3F8F77BCB9A24AF64D0A3653F
-:103050005E1E87E4F0B6683387221E9ADF447D50F7
-:10306000D228B971FDE0A8DF122618DFF318DEAB15
-:10307000E7EBD392FA83F45EAFF50FB1903C3F3AA1
-:10308000E4732A77AEFD2D36C5FC3DAFDEF6BB52AC
-:103090002D81B750DFEAF7C7B76DF9A8FB7BAA20EF
-:1030A0007FED7D7D7B499F469C5B2FC7FE38BAE54F
-:1030B00045C7E3A3434ED17DBA7F18D6F4019A07E2
-:1030C000B1F34E2EC0AB75FF547A7814DA5F7827CF
-:1030D0002FCE1F4F48A14B705E7A9A052EC176EF16
-:1030E00029BD68377E6AEC80DAF20C5E09F34DDCAC
-:1030F00049C2FF0167CB00FC64DDE9C7FFC2E1A460
-:1031000016BA09E6B6EAEFAFC1EFCD1E18D032C04D
-:1031100002F0F78F5F3A99E08B5A9E41F8C2EA04B9
-:103120000E0F6B1920C3FB03837D2623FDD6BBA3A3
-:10313000CBFD09A16FF4FEC50EF61D8943FBAA84E1
-:10314000CF3B782CDA067A757AD1B14DEB011FD3DB
-:10315000FF2396F4DDFAB65BAEF3131E827E8C6F0E
-:103160004C11F8A67991F4BB42F6445F9C0B13BA5C
-:10317000E9E94C6FF6D0BC7169C516B41F52A60FB1
-:10318000A579E35597EF27EE51DDE9E9249EFEC4CA
-:10319000EDE6FA5BB650BC46CA434EB2AB1E17DF33
-:1031A0006700B923FE7008BA58DC7C3CFF0D197328
-:1031B000D11B0080000000001F8B080000000000F1
-:1031C00000FFDD7D0D7894C5B5F0BCBBEFFEEF26AA
-:1031D000BB9B4DB209F979F343081071139318A9F9
-:1031E000D64D881831B50B22626B7149F84930C948
-:1031F00046AD162DBD5948548208D146040AB8E19F
-:1032000002622BFD82458C1AE88288F62BBDDF72A4
-:10321000EBAD3FBDD71B7E8A884256B45CEA6DEBAE
-:103220009D736626D977935CA87A7B9FE78B8FBEC8
-:10323000CE3BF3CE9C3973FEE69C33B31ABB86902B
-:1032400064428E25DC30C74E9FDF31E6159D4C224F
-:10325000A4BB33F49C494BC87B1221C44548F009F8
-:1032600053687B0E21DFEDD1047589B4DEE14D7327
-:1032700016D1B2447CBD45C3E5BD7FD5DEE5B3D2F2
-:1032800072312DD3E7AB12998BF533BD690E5AFE1F
-:1032900002FEAEA7E51E569FAE25AD589FC3BE7F6A
-:1032A000AA84DCE5A3CFD4763A6E297DAE9DB8B56D
-:1032B0009D8E6B918917CA0BE7166C5D4E616A7320
-:1032C000CC427889D79B2651F84E36E66A56D1769D
-:1032D000BFA7AFC835845C51E0CDB097D1F940FFAE
-:1032E000741CD2442795363CFE1C9837ADAFD77A74
-:1032F000B3643ACFDB1DFE39D0BE5EE39D42B4D04D
-:1033000089B7C07705B423889F39763BB627F2404A
-:1033100019BCFFFF084F95B8EE5F114F77EF34757A
-:103320009D2C24F8F705FDB7B9D7A12A07FAD2BA20
-:103330004E1A87CB77C3FFD07148AD2493143A2C33
-:10334000AB226E8DFF36E8BF79E9077AA28137514B
-:103350003DF42FF0BE4E0AEB52E9FC82FB24CF76FF
-:10336000C2DECFB2119295E8BF13E621E09EF7C30B
-:10337000E6347FD1F07C2C3F78A9E6765A9CB7E4FE
-:10338000CCAEEDF4FB790F59085186DBD31E719D4D
-:10339000DF7FCFB89A5C499FFADEB086E2EBFD1979
-:1033A000C4B39CB67B5F431A00FFEF73BC953F74B8
-:1033B000F7113285905FD9B5F89D49D083E4DBBD24
-:1033C00088E2B753224123D0C34C3DD2C36088D298
-:1033D000C395B0FE747DE8FBEE07278782747D06F7
-:1033E000C90091613E15C4BE5D89A9BFA300EB2948
-:1033F0009D044DB43EDA680E6D95805E28A0A55000
-:103400003F09EB5F95D8FA07EF30E238DD33191D3D
-:1034100076373A43C11C00B68B00DEC6A2A3947671
-:1034200082744864EF9499B6617C6CE372C1523A3D
-:10343000F0E2DBB43FB2DAE4194F1FB0843294BB40
-:1034400052713C4A0FAB91BE640647FD8FD342AB2D
-:10345000705C4F39ACCBA336EF7C781FFD914501F2
-:10346000F83799C84A63097D4AA4C3E8A4EBC0E1D0
-:10347000215D4F13A083BB60008A877F6F386F5335
-:10348000E8FB9FD825840308CD584E481D61F5758B
-:10349000CB2CC7A429F0D4860D09F4DDCA1BBC03CC
-:1034A00082BE72D9D348FBF373BA22EBA336C08332
-:1034B0001FBE4B80FE3FB7295628D3EFA7C0F2D3DB
-:1034C000EF0B87BFFF39F07D19C0C7E0276D166588
-:1034D000BB348C1FF1FCB980AFEB696FEC78629C58
-:1034E000F87E8FD9BDFF07F045F11E4E74015EB422
-:1034F000B8AEF1F0BAF4D1C74DB47E5E9BD6B182BE
-:10350000E2D3BFD486F315F0DE951ABD8EE48DECC0
-:10351000FF94A5A55C86F92F65744F961928E26281
-:10352000F1A21F2E53D25D48A28735D228EFE5F0D5
-:1035300001807F5177CCF7F8DFBF1A62DB09BE212B
-:103540008A14073FA72B459261DDFC125B37BD3E15
-:103550003A0FE4563CDC029FFFC6E58DA08B787CD9
-:10356000FF1BE0BB6C24BE5DFA814CE8D7BFD48062
-:10357000788AEF9F90107EF7B489044D94EED64B75
-:1035800012D2EBFA072D21909B83A6E80EC067604C
-:10359000FF8DB8DEE71ACD0AA14D36EA19BF05F74F
-:1035A000DB181F170C1480DC3B47E7ECA5EB73EE30
-:1035B00037DA9EA0248020A4E537DAAD40FFE75E2D
-:1035C000BE89F5B3DCA2105A0E0086E9B881E07F0F
-:1035D000B6118A57699611C73FB1570A19A0BE8F15
-:1035E000E239465E9EA3FF36940CCB8D41A800388D
-:1035F000FA2C08079D69238EF75D335945C76FD1B3
-:10360000485E0DAD6F593229D4CEE031C6CAD51609
-:103610000DE9904A86F9BF4573BCE0DE225627A724
-:103620007079AC60BB431285B3C9B83AA205FA05FC
-:103630003EA0F54BA03E67781D5A567FF417984779
-:10364000CB1E357D343DAF9EC79258BACA19A61716
-:103650004B29C317A926A1F1145E1B2F5B6A2221F7
-:103660002DE063E93472E22ADAF4E0C074A0235B4F
-:10367000692FA9A3CFC069E20D51B8A7F6F7BC36F0
-:103680008EB677D4443261BA81A5BFCD3B79D5F0EF
-:103690003A0B38AFE97F424BAC381E7E4741F1EE22
-:1036A000B662BB89B3AE887DAEC0EF92354C2F0FAA
-:1036B000C02BE01F99E9CD755C6F52FD8AF27A61EB
-:1036C000D704D4AFA0FF40CE3D95C0F431C83D90A3
-:1036D000336D8EAAAB1C749E6667D51447191BC741
-:1036E0006783E927A1FE88A7EB783D24DAA5E6B534
-:1036F00016B75AC76E47F90CF116DD90C8E4882C4E
-:103700006179D1AF753DAB103E19E9E6DECD3928C0
-:10371000971B48971EE8BC8984F440C78B8C24987B
-:1037200040E962116D96489F8BD71B8812B37E8D3E
-:103730002175B989CB85BB4904BFBF7B675C7D35EB
-:1037400009DB687DB391842DF0EC55D7B7507D8EA1
-:103750007CD6F78521F63DE966F3BD8BAFBBA33A76
-:10376000A4F5D3796F3051DDEA84065DB83E5397F6
-:10377000F5E07A269678731E06BDF22B9D672BA581
-:10378000DB3FF0F512F83966AFAA00BC9BB51A9C76
-:103790007FF46103E2E724D5E3B0FE6B1DE4AE598C
-:1037A000F479AE8D78F37580267BD62CDB483CAF60
-:1037B0007AC5D40074D3E0D0A8E82AD3A1C372F9A3
-:1037C0000A8EFFE596D0D61C44F714A0A7F25CA1A0
-:1037D00057C99499B47C4C47ED3B5A6E9963F543B5
-:1037E0007F03604FD0F2FD0E26CFEE77E8713D45A6
-:1037F00059CC57D00D1D07FB335FC59E028E654324
-:10380000ED9F6074C3F5F0BA46730FEAE121FAD573
-:1038100010A4DF229F1EF0FA0A972BF3C16EA1F8C5
-:103820007E851214C88F602FB35F293EE62DA5E573
-:10383000574E1779562940674CDEBCF21D3359416B
-:10384000877CF3CC4F1FFB275A7FFEB45E31D0FA42
-:1038500005406B74FD5E918817C60BBE680881BE7B
-:103860006CD2337BB469FF15CC9ED1FB372C8471AD
-:103870005ED079C0DE694A083DB703EBD33C94A221
-:10388000C9AB3A86CFE0CB16F6BD39F4B39FBBA0E7
-:103890003ED513A4EDA326FF4658D7748392887AA9
-:1038A000F9D75AC2C6091738285E8F8798DD7D9CE4
-:1038B0005649304EBF0DFBA17C9AB690F673A233E9
-:1038C00015E743E52FDA5927D618B682FC5D373461
-:1038D000AE84ED8FEB7CD3D368F9F88BC59EE5B44D
-:1038E0006AD0A70FEB293D07D632BBAF5EA36C01B0
-:1038F000FC90FD169C87588FC09AC5B5501F58B2D2
-:10390000EC16908F63F139C87B122337CF9168167C
-:10391000F0D3C686DCDE30E895FE891E54AFC44D78
-:10392000179FD28D9DB53DA963F88DEED3213D5FE4
-:103930006EFF40177239D343304E80CA6522F80FAC
-:10394000E5724C593B5A99AD63E095546EDFA9EB93
-:103950005312FC47605D5A9EFC8FF7972A305E1425
-:10396000E522E94A46BE3CA9F3CE03BA755487F571
-:1039700075317AFDA483D999F5066E0792B03E960B
-:103980000F457D79959AEEC5F304A77F5B84C9F74F
-:1039900091F51ACE1FB71A408F4D6520936CD02336
-:1039A00056E85FC1FEA79E0EEBEB69397B5958BF05
-:1039B000883F814F28BEC3463AEF931B6C8CBF29CA
-:1039C0001AA09F451504F5E5222DB5634BE0BDD245
-:1039D0003740D7E5D48B0EA42FF2678A158AEFF90A
-:1039E00084B73350BB97CAB1973AA430EC0BE6AF1B
-:1039F000376C35E5005F7BB53658CFCD12CAB1F9CB
-:103A00001D95051B6879C99E2B70FD132A185D2E24
-:103A10000939502F4EE5F2B1DE10D2A31DFE3389D5
-:103A2000C03E88F68FF67413FD28AD64241E40AEA8
-:103A3000ABE8211453A6F6D1D45E26570995E724A6
-:103A4000C66E12F21EE43889B303D5F41114FA8855
-:103A5000C93DA2A482DC1372F998DD97E8443B3E8D
-:103A60003F15D697AE27939BBB25C46B3369457D25
-:103A700022F4C0D0B85C8F9CD20699BE323C81CF74
-:103A80007C670EAEEB12D28BFA44E895B1E820DFEA
-:103A9000A9E1FB88D1E960BC53C1FE9A4E93F07551
-:103AA00074BCA66524DC3C853D6D53503F323D69B6
-:103AB000647A129EE6CBD097F1FA315E1FC6EBC155
-:103AC000543DD377629D853D933A8DD901539785B7
-:103AD000B4A408FC35DEEA94E461BB26F08ED1A8DC
-:103AE0005C09651FC905F99E50F9622AAD0FC8C46B
-:103AF0000B7C65A178E9A1EF3773FBB72795CDD78C
-:103B0000AD67F4AB937DA4D80AEB12C17D6F3499F5
-:103B1000D8811E053E37DBE87725F01DE3B7A1EF1E
-:103B20008DA4C31CF37DD52B26D43F175EB6850C20
-:103B3000688FF8B31DB4BF94DF1BD04E3DF78A0DDC
-:103B4000F5E939AE0F5DC2EF401E617E16BEAE4193
-:103B500052358E00ED4B33C6810814F659B383D924
-:103B60005923ED215E9F1399C3E8CA80FBCD0B8ECC
-:103B70008107A04CE121A07F6E71327E0FEC995637
-:103B8000FC43FA3EE0B37A18F6FDC540AF06EDF708
-:103B9000E718297D4DD72E8B3E48E7D19C69B58328
-:103BA0007EABCEFED7DFDD41CB1FEED11103ACF3F0
-:103BB000F6697349EED8F2B731A43B3E10C32F77B4
-:103BC000EF54979B7BD5E5409FBA7CBFD3E63A651F
-:103BD00041D9E1F982D2B5C1D07ABA87C26B78D522
-:103BE00080FA6886D3FF9013E4AD267A18F06CC88B
-:103BF000FE780AF83B02FD9F48F03450368A1431B3
-:103C0000FC035F5F30CDCFB68F82B761FC11A30696
-:103C1000F14CAD75F6443917E07CE2D27B3F3C4075
-:103C2000E7BF6896D9BE02DF786BCBCAC19E441845
-:103C30004960FD4D1FC2BE8BB66B84F53F3593B610
-:103C4000A37035AC67FAB0894412806F5BA8DD6958
-:103C5000A44BFC1BCE6F777744CBC3F47FBB9D3561
-:103C600013014EF92FB20FE8E351E837C64EDEEAF2
-:103C70006472FC4BFB993246F899B602FE9A8D03AA
-:103C8000FA4A3AFEF57FF90CE5FDE2A5AFE13E8286
-:103C9000CE633EB3AB4D0AC8A7C50F1EC0F762DFA7
-:103CA000762AD38AFBB6D7361858D9A1C7F2A9CD40
-:103CB0006C5FB9B8570AC13CA55917932A412F6CBC
-:103CC000D6D90D64245EE3F1F8C1A6B713C0EFF5B1
-:103CD00001221DF67B12B3C7ECAD09B87F505A1311
-:103CE000C0BE0CACBFF143908F8B376B3D602F9003
-:103CF0007D36F4CF2CDE7CC3C48556E8E7D3A44AD6
-:103D0000F0136DB9013C54D0CE17627E9EC8F5F415
-:103D1000BDBCE56A05F8F1D06606FF62877107D081
-:103D2000D1F57FD1227FC91AE2073BB95BEF9D082D
-:103D30007CAD6CDA3E1DD6E78399E91A6CBF4B2245
-:103D400076C08B63690ABC5F2CC93EE0E386F58DC3
-:103D5000B5B1764F9D93F9C72AB397A50C5891AF8B
-:103D6000E6803E6DDE4CF908C69FF5DEEFEE700D85
-:103D7000F395346BFD2D53A1FF67751EE0BB217BCE
-:103D800066D3B790BEE02F4CF1B598E3EBABF29958
-:103D9000C122F8A4B500E4EAE215AD05F651EC8CB9
-:103DA000213ED944F9723221A79D12F902FC9319E0
-:103DB0004ED5BE63AC7D9AB550837AC6E821DEED60
-:103DC000F4994AB7C9B01FB725C9586F4BD2237DA4
-:103DD000CB7FBA77E76FE8BC9E74FA2F80BECC2603
-:103DE000DE62D06B4AD45E45CD5A4035DA61641349
-:103DF000B3AF89CCFC85EB92C98E5531FB7353125E
-:103E0000DB4F5039F105F473EEDD3F1F06FCB6645D
-:103E10007D3C05EC85C0C5CFF4E05FB3F64B28DFF1
-:103E2000AD1E1F01BA09F4CF240B8A86E572C0C308
-:103E3000F446FCBCE624E9981C7545B19F4A97827C
-:103E4000E56E07417ADAB8D48CF6FE4657C80440CE
-:103E5000FFAD7C2BECA746EE0F346EFB85570B7441
-:103E60001E92ECE3A1AC30FE186C9817D2D2713ED2
-:103E7000DC9617C4F29E4A8F96D659B7FDE3CA5C0A
-:103E8000C0539FCE03EDAD9E810498DF87DB4E24A7
-:103E9000C0FC1AB66971DE0DA14F5216160DCB0982
-:103EA0009DC65F900476825DB2C2F8425E7CB8ED3A
-:103EB000D3940556E63F407D5A3A3A5ECCCECAC905
-:103EC000F0FDF5DF64EB726697210472F08C89F9DE
-:103ED000F745BB3336A6FFAE4B12FECDDE2CD03FEE
-:103EE000436579A206E4C4F7ED6CFE2E7D6F16F0F3
-:103EF000E54792BA9F252BB52444E552E34A8984CD
-:103F0000A8CC3FF3DC4B5920FF3FDCFE52565D0C42
-:103F10007CF1DF89E78D496A7F9AF0AFBAF4E10C52
-:103F200018AFCE63607ECC31FCABA23D59CFFCA470
-:103F300083946B810EC577830D662FD8BB83C4181D
-:103F400002975B5D3FF7D77ABDF92ED8D788EFE3AC
-:103F5000FA5F0DF444E192FA24F427588AA2289FCC
-:103F6000BFB4FC77D1F58C91FF749D8DB04ECDC65A
-:103F7000E8E17104E9430F78D3B75865D05729EDCC
-:103F80008CBEA2F76B709FE532274C81B8803EDD76
-:103F90006D05F9767D81B9439308EFB342D03E3386
-:103FA000BD10BF0B5631FA0FA610F4C3A5915609E8
-:103FB000FDB476E6E7CFA820F655B4F8B32466E75B
-:103FC000B88967BD360FD75FC23807C78BD00F409F
-:103FD00047202FCF4846A423A95F427B54ABE99DDD
-:103FE00007FD8E45572BC5BA72BA1A2AFF9DE8EA1B
-:103FF0004941C723E8CAAF205DB98DA3D315F72384
-:104000005F767B12F4C1BE3695E36B2D973FD1FBF3
-:104010008DC2AF2EC17C6B797FB5466B580B7AC4CD
-:10402000A3FB38D63FBC89DAC5B07F4A03BB9E3EAE
-:10403000C7B5CF5770DD486400FC0896AB8DA82F3C
-:104040001FD34472C08E499DD4BA1BE823755E51BC
-:10405000493BEE0B331CA01740D7A27F74E9341FF5
-:10406000B323581C283A538FFB9C96072B7DCC8E8C
-:10407000A8417E09AC3629A007A7F5E72C07FA0866
-:104080002C231E03D271CF8645E0CF9D6DF580AC09
-:1040900013F125B252CD779D128B53056F22180F65
-:1040A0001B8E330D6CF921E8FFC622F49B0CF98FAF
-:1040B000F309EA8DCB8D43D6AD3621DE45FC68D0C1
-:1040C00046117425FA91B13F9268647A68A47C40E5
-:1040D000FF734A05117FEBA19C2ECA3CDE23F85FDB
-:1040E000C4A36C45BE1CB0C82B9C39BF32439C0492
-:1040F000FC776CB31684FD00FA8D5919DDCA4F693F
-:104100002820E950FB9FABAA3362CABCFDD0F7C19F
-:104110005537575F8BFA77A81EC0A67A5994BD26EB
-:1041200005E255C3F532B5838D7D12FFBEE2E61B75
-:10413000A8AA1E94C4F87FEEF4821FD14454E3C5AC
-:10414000C227C7F5AFA3FD5B15DE3E38EE26E8EFCC
-:10415000A912517EA0D34BE15BAB53F78728E5DF73
-:1041600043418CF77F530EAF5A9D316C1F507BE15A
-:10417000CF4965C376C2A3EFD5765D49C7B2D83FB4
-:10418000D583FE15FA3EE092D00E89E7D70497F466
-:10419000D5EC6B65847D9DE062F6F5746049BA2FBD
-:1041A00041F91D58E62360DF52BBC4E942BBE4E39A
-:1041B000530768FDB9599F1F1EA740BB7BE6C1BED0
-:1041C0002A705146F91BD8A90D49946F8CFDCCAECD
-:1041D000A6FA1CE305827E96D839FD388204FC9746
-:1041E000DDFBA432A077425AB36EA36BF903973775
-:1041F00013C7E1FBCDF87997BB985F205058B5A164
-:1042000000FADF2611B01756151E4F5980FBA9631F
-:10421000290B63BE6BEC7B0AF1D9B853372A1ECB4E
-:10422000A9E104786C79F9452FC88D3321096542DD
-:10423000831CEA04BBB6A141031621290DCDBF039F
-:10424000E31F73F5643C9D5F06D777819DB706A792
-:10425000C2BCE9BF127DB5D1B708E5C4C6B9462BCB
-:10426000C6910AEBEE413CD8CD5EC0C3AAC2AA34C7
-:1042700018A765E6743BC64DA83D07F52D0F7E07D0
-:10428000FD4502AE557DBA1AB077CAA95DF70B0A93
-:1042900077A673468D87F2F538EDEEE2FBAC10574A
-:1042A0001F5D8EFFBF6446171D922FF8ED52F48FED
-:1042B00092587F67761FB31F6F71E955FEF15B5C03
-:1042C000CCAEBD36189906E4B25F1EB0805D1D20ED
-:1042D000DE4F605F4D7C56653BAE13935FAE360597
-:1042E000FD6646D7C0635742FDB532EE67883CF0A5
-:1042F0006318F75CA7CBB38A703E80F283452190A8
-:10430000C7FB5CFEEFC2FA96737BF5DCCB371683F6
-:104310007F51D85F9DCF99506F76DA94276B404ECE
-:10432000FE49667903C668641AED67C9E74E1CB793
-:10433000D314EA84F50FF668B1BEC9EA5F04F4DB72
-:1043400078EBFA299887600D15801ED5B9BA08D088
-:1043500031DDBEA01FC5E8F21188234F0BCE972593
-:10436000D0177176CD34F063E1BEC5857EDC2ACEF0
-:104370001FE329159C32222B747C91346CE7BCF925
-:10438000E7D932BC14F68FC6C8FCEED573CD04EC69
-:104390005CF248F4B006FCF8AE08017BB8B957C22D
-:1043A000719A0B5FD0C3FEE5EE5EC6DF01BEDFA0F3
-:1043B000F8CBC27894CBC2ED810E46672472781C8C
-:1043C000E0F979B69E84D076317E5742963379C033
-:1043D000FBD3F3F84333F737514D88F5AB5CC2CECE
-:1043E00058A18E5BF071D74911AF16F05A2CA9FC79
-:1043F000E4E2D9C3BF4F3C189D0EFC1BA5F4057E1B
-:10440000A70DD2CC7B5EA7F3DB5036C903A6989BE1
-:104410009293B604DE5352A4782FEDFB643AD00D8C
-:10442000A921C8AF2D7D95DA662B8BEB605E8CA53C
-:10443000B507EA53EF2A44FD0C719359F4FDB31C00
-:10444000AF6956E6C773AF08E6401C34F1A0EF9E93
-:10445000D761FC2BCCE8874DA56B6373E27325F81D
-:10446000BDDCA4F800E86777AD5202F088781FC47D
-:104470000B67160DE7E3383D92772B7DEE76399882
-:10448000DFCE406A005E781FB20EC71FC19F07E3F0
-:10449000427C0F9EE7D2C232FAFFC9C096EDB8EF58
-:1044A00037603E486DDF1BEF80FEAD35925E8CC7F6
-:1044B000C6D92DD589B7BE02F43F78F6D4968701C8
-:1044C000AEDBF67A30EF25CE1EB9FE9BCC3E3FB375
-:1044D000DDA2003F6CE5729BDA8FC827C15D6C3F9F
-:1044E000196F471E75A9F72743E5AFDD8E64F00508
-:1044F000B7B33C0B21DF037CFF37D8703E01F4D704
-:10450000BF0DC113970FB28DE783F48F9E0FF2E6B4
-:104510000E4B10E8E17CAF09FD92328F7B9DB545D3
-:104520001F002475380ECF01791B5872E6E71ACAAE
-:104530007F720F8B23C9128F33FD4A4B585CCC6BB3
-:1045400007FF8B805B764C777B8B403EB27937716F
-:10455000BF5193B34061F12E9637D494102E007B57
-:10456000EA55AE879ACC2C5E35E8D087615DA326EC
-:10457000FF1F5D18D762DF935F1A94D8B8564F8833
-:10458000D975270A35613D9D670FD807B06EAB59C5
-:104590007C6B289F60BFA1C7C0E290581EECCC4145
-:1045A00039592FE256FB993FAE9EC7A74ECC5AF41D
-:1045B0000CA45C7448AD35B03FBBB0AA12FDE80F47
-:1045C0003C39139FF52BD57EFF45E0A7CF1B8E23EB
-:1045D0000BFF7B1DF1E899BD3CEC47D450FB4559DE
-:1045E000295781BECC21F61520FF95205DADABE9A2
-:1045F000B3833EC168973412D83972A7CB0CEBFB5A
-:10460000688706F554B043E3857602CF39C9CC8F6D
-:10461000744D32F36BD0A50AC138E2D9A1E371071A
-:10462000DEDF72A209C35323B1E7A376B966347DF6
-:104630002DFAEBD0B51AC14F17CDD4A0DFFB82DE27
-:104640003B17FDC6CE020279541DB6D69535AC1E79
-:1046500079E78229EAC3FAEB64664812C509F233A6
-:104660003599E7CBC5E16D6197BA1C1F8F690CA91D
-:10467000CBF5C43F212D8FC50F62DFA72633F97517
-:1046800061550EC7B707F3E3C4FC976730BC6932C6
-:10469000D93337B36A2ED0412EC49773E0C9FCAB2F
-:1046A0007426087FEE752E09E9230EDE0E30DA80BF
-:1046B000BE3A593CF46F853F1EEECAE414AE1FBCEF
-:1046C0006E885FD6DBF5188FBE5C3F495DB25A0E2F
-:1046D0000D95BFFEFD2CDB27756A799E8D1DE5507B
-:1046E0009D9DCDE584E4D91186F7566A2FC03C3AEA
-:1046F000B525603F4CBBD58AF368D96F423F70F354
-:10470000B2812CD0E32D55030510B789C72F402B5C
-:104710000BF945DBD5B9E8FE03EC84D8763C5F4B5A
-:104720001D67F5FE20B90CF6392776BF01FA6AB786
-:1047300009F515FDBF0306F0B3BC9C83F6CC8736A4
-:104740007F1BB40B98C35B9ECD01BB85D94DCDFDBE
-:10475000861EB00BEB3A62E27CF09FD5EAB81F5997
-:10476000E944FF3BE956BF6FD814F7DD883860177E
-:10477000AEF33ABD7F22F03BD53B987F70B65183B4
-:104780007903F55ACF2290B7674D6A7BFCAC8DADAB
-:10479000D796A175F6A0BDB565CC75F614C03AD70D
-:1047A0006B883FB69F665867BABE4D7C9DCFBE787A
-:1047B0007501ACF3C7BBAF2E80755EA7EBF202DFCD
-:1047C000B439FC5B9369BF276FF0A13D25F2582FE8
-:1047D000971EF724ABFD2B43E5FF21FFCA58FA30A3
-:1047E0003C04875A1FBAF44A06C8833AA3E1BFD5EE
-:1047F0008BF037AA1FCF68407FC7FE3F7FBA66079E
-:10480000C8817E2DDA23A2BFFDB23F0FECA1FDEFE0
-:10481000B83D4169ECFE1BB95FD86D2441F0AB880F
-:104820007D80B027E3E5F15B7C3E1F257B6F00BBFD
-:10483000E6CBFA8D1BF83B63E85366E76E933CCCFE
-:104840006FDC8B7EE4967DF3EDE0273E1D627EE318
-:1048500096178BD16FDC187A2D0C7965A45FB2C3E3
-:10486000FEA371DBB104C80710FB5CBAAF3D938CAB
-:10487000F4A8DEEF9E0E9D4880FC010A7725E871C2
-:104880008B2BAA07BA6FA1FB3DC8236C91A387A10C
-:10489000DF1617C13C97D23EF5FE4FC47937FAF4C4
-:1048A000287737F64B2190D7297A7F4E06E8359244
-:1048B00061C77820E7B38BC9DED494B2D8F8BAF7D1
-:1048C000F3E4E4E17CB0810D8948BF033AE2B583AB
-:1048D0003CDB60E3F24C46F9F6C74D8E10CB0F631C
-:1048E000EDFF18627642A3C80B934958A6EBB56852
-:1048F000B6F75D586F90F7E138791F5B1671FBBB17
-:104900004918F552331918CA0F8B6D171FD78778BE
-:10491000B8AA1FD25AAC801FEC4EAB07E081F8B8A2
-:10492000BA3EC8F6EB941F96960CD3AF580741BF1A
-:104930002DDC0F1D6838FE08D06FA04FB2837DD7E5
-:10494000E461F4DB44F75B90471BCFEFA4579D373E
-:104950003A16FF97A6A8F5D150F9EFE45FBD3E45A2
-:10496000CDF762FEC26F3F34CF7E89F165DCBCE2D9
-:10497000F7A9F1FE76B1CFBC5C793827452D0F87BA
-:10498000CA7F67795837B42EF1F2501DCFF89BE5F6
-:10499000E1FF705CE3997D4F27C0BE03EC78D8A798
-:1049A000ACDCAE63F91314FDB1F1E2E95AAB97C583
-:1049B0004FB5A25E1D8757A6F3383CE3EBD75ED414
-:1049C000E2BA35F33871F33E9B079A365817639C69
-:1049D000363E7EBA84EC9E0E4B151F476D027ECE8E
-:1049E000BB743C75750A8B8F525872206F213E6FD5
-:1049F000EB35EBA749FE9875AF2AA21B8251E8DB85
-:104A000028078933E6FDC6146657BFC6F38BDC7AE8
-:104A1000768E60ADCDE285FD8C5BC3F29F7EE0F2C9
-:104A20006D82BC18A3C2F1FAF2ED4443F1F28CAEF0
-:104A300017E54AB0D9EA013928FC37A2FF8B3C5E62
-:104A400071D9FA3F8EDEF7FC0FD37B3C7EF68BF1FB
-:104A5000FED6B8DD7A8A1B155F10A4E323105FCA67
-:104A60001949BF63F533161D1F4DF11D496176FECF
-:104A700014CC57B84C3963298D9E003F11D963502F
-:104A8000C0AF097E12D48FABD3783EAAA77C26E6AE
-:104A900069B37325E21CCE5876E40743EBC3ECC838
-:104AA0000FC65C9F2F6747DEEEF07D087476B2D2AA
-:104AB0008BE7011EB551F8617FF89C61D4732EE23B
-:104AC0003CC6A5FC2D5FC4D1D517FF4B72D4923ADA
-:104AD000965DF975CBD1CF13C07F3A763F419EFFEB
-:104AE0001941BC45F749646B8C5F3B1061F97B1938
-:104AF0001C5EF1FE3FF8BEA121D59B994ADF7FFCE9
-:104B0000AED14812A99E2E6572B1C567C5B8424B99
-:104B10002FCB7F695946508EB780DFB408FC8933AC
-:104B200009D87D4F3AFD13208FEED1F7AC416D22AD
-:104B3000F8DB6711B0F3CEBDCBCA339CFEC99867D2
-:104B4000B76C00E318DDB3CE601E56F9179F3E52D6
-:104B5000538AF0A23FC165509F67B93D95C933F1B3
-:104B60009C3D846F2FFAF33F6E60F9DA0197D70E00
-:104B70007E09E10FB728118C2BB4EC61C65BB996A6
-:104B8000CD87FC3003E9A9654F6531F84D49AFA9E0
-:104B900018ECDDF2DF5B71DFF7F183E99827B1CF25
-:104BA000E5AF027CD84A4337817D9A4DC701BBF7F8
-:104BB000E3DD371503DC42FEAD03BF391D7F9D4D9C
-:104BC000ED1727469677BF644726EE339BACFE5A17
-:104BD00098FF3A138323B89D9F4FE1FEF278FE17AA
-:104BE0007C9FAAD5E038A9DF35629C5CC885753A00
-:104BF000E237E60DCB93129E671870F13CC7FE9921
-:104C00002C4F8597AD2E75BEE747C93794003C25DC
-:104C1000A9F2578B675947E40B94A4B27896EA5CE3
-:104C2000A2E522B3A773ED7AA427DB4AC2E254942B
-:104C30009EC0AEBF361A9906E7BCF2BBC3D7029E30
-:104C4000F75FD4209EE49947303E9328B1F1F256A5
-:104C50000F744E007F8CFDADEB6049952E7B15A047
-:104C6000F449A7EF8154E4FFD64218AFEA5F742CF1
-:104C7000BF729F05FD0CDD594D985F79EE3D83EACB
-:104C80007C4EFC334856603E656EDF6F314E60DB14
-:104C9000238D9A27FB44AA15F9A62518998E393633
-:104CA000D7BA50CECAFB7E1F04BB43EE944102919B
-:104CB0000E9D5703E7D382CB09FAF5C777DB35B0F2
-:104CC0005ED93C3F6670FF7F4EF1E3BE45C40542AE
-:104CD0002CBF4937F008ECC7E4E503DF0CC27AECDF
-:104CE00071685AC07FAA8BB6A0DF659F05FDACD95D
-:104CF0007D792BBE41CBD92BED18071B7CE5EE6CE3
-:104D0000CCE7A7F31C3FCA3C1F4A65F948F23E8B2B
-:104D100006F499FC04F1C0A8B223A50AE17E8A96A4
-:104D2000693FDF077A4A1E8E9B823F0AF45443AAEA
-:104D30007F07D0CDD0B9A4A566762E899FA7B52DC3
-:104D40007D6F179CF7D9C2FDB907F74F9E85FEBF4F
-:104D50004E598275B8E060F9952FA4B278E248FC0C
-:104D60001FC43CD6DC7DBF657A8DE202FA97758C54
-:104D70005EE44E570FF8195F49F063DEEE751D6172
-:104D80002DC6CDEC277F5CA3C4EC77D6333DD3B2E0
-:104D900093EDCFE3F73797D22FBF1E92334CBF0C62
-:104DA00095FF4E76CBEFE2F4CADFBC6F21EAFD5EE1
-:104DB000BCFD12BFBF1B618FC7F537961D23F25094
-:104DC000AA86C761F6B44DD84941559E4E95959F28
-:104DD0003B34AAFB5F9F64477A10793B29EDCA7286
-:104DE000C8DB8FFE88A0DF4EE415893CA26015CB9E
-:104DF000F7096A8C782ED14DBA307F681C094B12A6
-:104E0000FAD706F0FC6D2AE411D1EF4FA4E662FF59
-:104E10009B8967A516E5A62201FC26C83F4902B872
-:104E2000431B16C178B759713C13E49F24E13E033C
-:104E3000F939DDC7F256A735B0B8433AD5CF504E51
-:104E4000CF6774699AABC73C56915722F24F045E04
-:104E5000AA38BED3272CCA01B928F254D6993DE509
-:104E60006017C1396838BF1C6C34F3BC13D66F7738
-:104E7000632E9E4FFEB27929F17816F929FA447F04
-:104E8000A6BB6CE43967413731EB89706DDCC7EC48
-:104E9000FCAA063DCE63B07106FA2B071B3504EC65
-:104EA00081AA7E03A3C3B8F136CED59330F42B8705
-:104EB0004C204F053D5CCACEA5EB5B08FEE0836D40
-:104EC0003BF34E52DE3FD4D68BCF4193D4ABBD12D1
-:104ED000CFA1CE03C9F58DB4FC5AF91AC8B78966BB
-:104EE0004994846AD3AFFA964CF5C46072F47D2875
-:104EF000DFBEE17BAC3C3EBA45A2ED9BD33E62ED0A
-:104F00008136D3A9D85EFFEFB541EB57D07F7F261E
-:104F1000F1F91C35EE64F4EB3C12413F12D77FA54A
-:104F20004C3EBAAD7AB49FDC3C1F9554F3FC5488D8
-:104F3000F8D0727B5A31C6EFAD44D91381FA0C0315
-:104F4000B32708E387F6F1CC6F6DE4F4403284BFF9
-:104F50006A2008F2AE3DC781DF0FC9E73D8610F336
-:104F60009BB1F18FBE78059E4B1279B684D833671A
-:104F70005F81F936AAF25A133FA729DB33E1BC7BE4
-:104F8000BB8EDBC1BC7CC4E65F88F304BEA4F6DD47
-:104F9000D11B7E5004FC7476EF0FF341CEDDA8A741
-:104FA000FB8451E45A593A936B833AEB4A897EB7B2
-:104FB000C6E66F013A7CC7326F3A1C319A9B54A9FE
-:104FC0007700BCC1E7B480D7644E278ED90C3E472A
-:104FD000B54F823CD476131B37D92F7BF15C847F8D
-:104FE000B6741B85BB5D62F29B7E94887655A19258
-:104FF0000871C8267EEE55CBE58896CB917F6E1B57
-:10500000C897A9C1784DEF135AB0E77FCBE3E2BF51
-:10501000CD519F9FE87133B8C5739656B902E8CF5A
-:10502000A5AB3A524BE940ABF78470FD326D1837AF
-:105030003E602B770FD0EFA5EC1F95423E777BE6C5
-:105040008F4A21BEA7757ADCBE98728F9BD17F35BF
-:10505000B403BC595A4BC1EFFBB5F59748FB2BFA8B
-:10506000F2FD0DF56360703519A359706EFE59930A
-:105070007F3BACFF85F9C7302EFC40FAD1F721AF5A
-:10508000E3A88ED15D3093E7E393EE690994EE0EC9
-:10509000E739785E0A8BBF1E9EC0FCA8547EB1FC27
-:1050A000D18912E621D6CE66E7626F26918E01FA8B
-:1050B0003D3A5968FDF48A1CB47F6B799EC8F47739
-:1050C0007C09B07ED36F8FCA20F7C7B2E76E74EB4E
-:1050D0009481183EBE4951976F2E5497BFE5519762
-:1050E000BF5DF19709B16593D97B10E8F55589DF6C
-:1050F00047710DB1237FBAA420D85D935F4AE7E7DB
-:1051000089593EE54FF97EF1A50A82F5293B8D5B71
-:105110008D50CFFDEF5A5E3FD94D8CD94EC407EA72
-:10512000E9A8C4F3325D1893227BEFB1333F346DAD
-:10513000ABA7FDEC9DAF201FA75835E49BC0EBA5A6
-:1051400046B4C3045FB49B287D533C968F339A8149
-:10515000DEDB759EF5D097D66C50402F572618B1E0
-:105160006FED3FC8A8D7969B0CC44ECB071F376383
-:10517000B95C263EC823A120CE86E7519D27D40ADC
-:10518000F3A5ED60BEED0E1657D796EB51CFD37E4B
-:10519000715D0F3EA109119C7FA58CF9A61C66C10B
-:1051A0007774247CFF34E76BAD8684518EA5B37B86
-:1051B000390ED1FEA1DF83BFD2F6A0DFAE50B91306
-:1051C000EACF1B27E0B9A8C0D0792F5903C015DA60
-:1051D000B97CE867E7F2043F0BF942A55EBE2B8578
-:1051E000309014F80F053B05EC0482FB0011B7CC9E
-:1051F000348A7AD90BFDA60DB567E7E05278995647
-:1052000085352560A7BCF127A0C3B1E445611A9399
-:1052100013E229E4C516C3C3476AAF196D3D0AEF0F
-:10522000C7F20C9B9DADC7840CE04BAD794206E8FC
-:10523000CD768747F1C5940BE9766AAE13F045DB6E
-:10524000D1F2AD35C7F2E518FD5498C6E4006DE71C
-:105250004DA2F01E342919C0BFA38CDBCCC6B57C8F
-:10526000BDE3BAE9B8B4DD411B1D97B6DB663284F5
-:105270003509A38D5FA1C078971A97A21D913F832E
-:10528000AF03A59320F8C10EDA3448AF3378BEF2ED
-:10529000C164361E2954E7FFE49BE9F8985FA6CE67
-:1052A000F7B951DAD4017AFA6953C256A0CF373828
-:1052B000DD1CB6FC433ED8696FCC2B388472267156
-:1052C000790710D10CD28BF246C8C10B69C7CAA1AD
-:1052D0004CE5E18D6974DE0FE41E9D079D1F723C55
-:1052E0009D8FF6A5D95B935636127E419F026EA024
-:1052F00053E08B213A8D835FD01BB9A51713253757
-:10530000533B179EC2EE25A495E5C52B99C3F3A385
-:10531000443EDDD8CAE6D11844B86F74FC18F3E6F1
-:10532000EE18E7FF1EC035F7CA4FF0BE22E29E3FDF
-:1053300001F67714DE7969C9FF7BF0C6DBF997CAFD
-:105340000F1F8BCFC5F8D2AC9D981F1E986DC57CE2
-:10535000F1693C3F36D0A0C1B800DD0FE23EA28526
-:1053600018432097A772BB5C9C5B784562FED6E031
-:105370008B06457D3F517CDEB88279E9C1652CBF43
-:105380007CC87E6F56D07E1FD273FC9C44773193CD
-:10539000EDDDF728EAFB89E613F5FD440BED2171FD
-:1053A0006F8A94329CBFDFDD4390FEBB6DB9589F7E
-:1053B000AE65FA887C83E9A3EE1CA2BA1F699D3909
-:1053C0003411F394785EC146C83FF86FF20B7E9AB1
-:1053D00026A9FCC243E5AFC92FDCE6F0EF023A5B39
-:1053E00058E4CD92283DD6EB997F98D2EBA6088160
-:1053F00074C5D67CD8A7DD445ADFD2E421BDFE02B5
-:10540000E97532A5D73C15BDEE61FC1544212DE8A8
-:1054100075884E0BE3F300FDFB60DC6E47EFEF5B3E
-:10542000605FD36FF0B03C6896D7192F1F62E059C8
-:105430002033785C5A2DC2F33AF4130FCFE5F04DC8
-:105440002C9DA612C61F63F14FAA4C82B69261FE34
-:105450003199FD6FC1B8437CF408DBCF8E805B6B64
-:10546000457A9A73078B7F052CCC2E8038581A1DED
-:105470007F261F7F4EA7AFDA01ED664A0C0F61FA57
-:105480000F857F16AF9FD9DF8C7970B3AA75C7637C
-:10549000ED20212F45DC6D2E6F7FAB7DA60EF2D265
-:1054A00067D7AAE35D73EF64F1B639B3D5FDCC25B8
-:1054B000AB3FC17C4DD2AA03FCCDBD535DFF49DAA1
-:1054C000509C6C02C4C90E713FD020E513E0A3D7F5
-:1054D00093176FBA87D2F9849F149580DFF0869472
-:1054E000C66D4FD0F2B31B2761F9F594EF7EFF280C
-:1054F000D46F29C072355CE204FB56E043CA67856D
-:10550000E577CCC849007DC2FBBD87E07BB7D9DF1A
-:105510003D93B6734FC9C53CD66AEED7185CC8EA4E
-:105520006FBED2C65295EF52D05F5C6D66F7351DE7
-:10553000297EBB04F2AAAB7379B9E4D549503E2465
-:105540007D82F73A9C6BB6CAB00E2DE9CCCF3EB93E
-:10555000500A4FA478A976F2FE9BD9BC6A4B9E4BA9
-:10556000073EA9AE62FD4CF65476E6413BCD792C60
-:105570009F4B372600FE05BFE5F07D95B02B7D5C87
-:105580004EBCE43DD69144FBF519250F4CD1577123
-:105590008CDD4B6665E7037DDE1C19FCF4D3BC2C67
-:1055A000EFB6CAB83C0DE4E12D7E7D29CCCB6E2C44
-:1055B0003E0479118915956598A76D24B8BE94FEAF
-:1055C000C7A7033F5EFD495602109D554DFF82BEA1
-:1055D000660ABAAF56D337E5DBC9E9659796DF2A85
-:1055E000FA360DD3F758F63E85AB02E1FA865AAF8C
-:1055F0000D8D13C79FF1E38E2537E02F56FE0EC3A6
-:10560000D78B7C9801D98D79C0A75D824F6F023806
-:10561000F49A089E8FCA963C93F0807185C7887A69
-:105620002F8E5F057C99E0332F190917FCC9C26ED4
-:10563000657F2EF0A364F07AFA9D973887E1A2E3A4
-:10564000DF910E7AFC1106CF66A995C919BE2F11FC
-:10565000FE971631DF3EF57CCBCDEC1E0337F8CB41
-:105660003076523C6908EECB5807319F00D7E7B33C
-:105670008D3E9B9ECEED36473DD2CFED54A33A28CA
-:105680005EC274FF0F701ED404F7C17E6F21F162F9
-:10569000FC9CD247203DC66E12F0C6E3A9650CB94A
-:1056A0001A3F9F78FC0CAF5B240D9EE2FCE1D07C9E
-:1056B0002F739EF1F68A4BAFF65B3AB97FD139EC86
-:1056C0004F2C84FA5A62F6A03FD123E17EAF96DADE
-:1056D0001F20A76B6B08FA719C560DFA13851D32BB
-:1056E000169F5CFF4D26B76A9B083FF7C8E6174F29
-:1056F0008FA964E07E78D61A950D0B80FF1BACAAAB
-:105700007306B556168F784EC8113250067A7FA8A8
-:105710003C42EF0F94811C8ABF7FAEF622F37B3BA5
-:105720002F4AF8ACF51C2B03BDEFAC1928037956B2
-:1057300067F7FE14D655DC13198FCFBDE91A919780
-:105740007259741ACF47220E7AC4E67F393DC63F9C
-:1057500075568AA09F75B5CBCEE7E7CF017A76D88C
-:10576000732AC1EF34DBD8AA03BB38D1E13F90CE16
-:10577000E4E8175FC0E6179A523CDE56ED7F5866A4
-:10578000C3221EEEE578B881EBD9F39BB4B80FA91C
-:10579000F6163E0DA1A0C09B3A1242BEF5A27E14A1
-:1057A000F7C69DA7065518DA3F6F437DBBF857F53E
-:1057B00018279BB05E4394187D39316456DD7F32E3
-:1057C00079A75355BEA2375DD5FECABE5C557D7123
-:1057D0007892AAFEAA374B54E5B2C85455FBABDF0A
-:1057E000A95295AF1998A16ABF03F43DC5E3374E9E
-:1057F000CF52BDFF68E3F437213E7D5DF43BAAEF55
-:105800004F703F04097A238574FE0B04BD5EAC53D0
-:105810007D4FCD9AB0540E7CCFFE16AC6679F795CD
-:105820001463B1FD2DEC52DB13379028E62BB684C0
-:10583000244F9840DE9DBABEB1AF07F17AA97B0F25
-:1058400026B8E66BC05497C6513B632220825C0D9C
-:10585000798363F1FBA5D6BF80E47FA9F537B8D57E
-:10586000EB6F52D4EB6F2954AFBFCDA35EFFC40AD8
-:10587000F5FA3BBCEAF54FAA51AF7FB24FBDFEA986
-:1058800073D5EB9FE657AFFFB806F5BA67B6AAD750
-:105890003B7BA97A5D73824B54F5F17420E849C8CB
-:1058A000CFBC95F7AADB53A46862E842D0D9025F67
-:1058B00003E6638DEF7A48355E3C7D4C203C8FF4E7
-:1058C0002BD247E5386E7F72BAA07AA96A5C32DAC9
-:1058D0001937C073EE046EFFFB46B73384FC8AD5DC
-:1058E000EBB1FBE6B1E4DA087DC5F7D163EA2BD86A
-:1058F000479B86F7D163D1EFBB84EA591C7C35FA0C
-:10590000CFEEB033380E9A993DFF29545D43DBD179
-:10591000361514DE77613E74FC77CD93D10FF21DFE
-:10592000D2AB8371EF24117CCE23517CFA895D7553
-:10593000BE6501F1E9B95F6409E0A9C938500E7A82
-:10594000FFC2FCA3EF637CEE48D265DD07721CE268
-:105950003FE30939C5E5C9498803D1F23913F7276F
-:105960007A89E28AC1E729EEF7AC9B26A19E255AE7
-:1059700033E6B1D5DD2EA19EAAFB0FF66C1FC7F44E
-:10598000DA88E75281D72E6E1F303BA10F0EDD6201
-:10599000FC90F8AD688F7AECB0DEB43F1687F9471B
-:1059A000767FB1DBC8E0DC2511B9C289C70671DD9D
-:1059B00061FDE17C9BDBC8E0DBA52346C0EF64E230
-:1059C00047FBF031998A3CD6EF24D6EFD15CF01733
-:1059D0009ACD6F7EAB1AF2A9E5E072F4DF7F8FA853
-:1059E000FDF777B64AE8BFFF1E859B3EDD768F1B2D
-:1059F000F4B228EF02B8211E00EDE8FB5477AB04A7
-:105A0000FEB1AFADBF3D0FB1765FB2BFA17E0883DF
-:105A10000BFE603D857F3683D2B781D2CBB6EF11C6
-:105A2000F41FC6FB6BC769A90681FC311DBB97C07B
-:105A30002DAF67FBE2C31EBBCACF44740E38477A52
-:105A4000297B0EF2BE4FC59CD3A07434EAFDBA1F69
-:105A500065B07CA4F6B6C844884B9EE371D787DB5B
-:105A6000DEC4B256F6605E26DCF7E588F95EEFA28A
-:105A7000F531724EB6D2EF63E48DCEEAC3CB6B1E26
-:105A8000698B60BC53C7EF257B34E35EBB3FC6BF69
-:105A9000F2CE386E271983C49E42B8694FFF4E4F2D
-:105AA00023403F5ABB7C2A761F6D70D3FE62F5EE11
-:105AB000C564121B7F58D9F60EC2FD88E4F7436710
-:105AC000867C1236517C1B6438034DDF6FB811E5BC
-:105AD000AFDE76AF07EEA11A0B7F06B77C21567EAC
-:105AE0007E388EDFCFC5E5E7936DD1C9304E7BDBC5
-:105AF000800A6F5D6D17F1FD9A3652C4EA3FC47A91
-:105B00004D8D82F4738AD24204E27AF2800DFCC198
-:105B1000D43E26107FD6B98D186F30B818BCE4A2D9
-:105B20000BE9639E9DC1003EBF4C4A1FEF2FD5E19C
-:105B3000FEFABE4C2BB6BFEF37E30F7829DFEA2918
-:105B40001AB47FC37C86C761F8D373F94964BF0F69
-:105B5000E4803E5DC63885D33E0BD7F1CBF627F007
-:105B6000AE3711CC47D6675AD15EB85C38DD196ABA
-:105B7000BCC7E38FE209E5FF7D1C4FF73DC8FC93EE
-:105B8000F7DD4FF03C05594AFFCA87E96A1C978741
-:105B9000A9C487CFAE362A080DB05E46E29F40ED1D
-:105BA00011D28B8D4DE0A7827AAFEC80D48827AAE2
-:105BB0005D33E1B9A6E26417B0E3DA6B3F8BC01343
-:105BC0006211802F7B0309C155BC98AB40C777F8A1
-:105BD000593981D727CC65E5445E9FE863E54CEFF2
-:105BE0000B523500161747CBB43A6FCA0779BC8001
-:105BF000B073F1FC7E8DCD84CB0BAB736635D4DFF7
-:105C000049F09C8BA8FF09AF4FB31E5F99077A63D9
-:105C1000B6FAFB0D1C0FA9D6E35DD330DEA6AE1796
-:105C2000F1AC64EBF937F1FB2275FD53FC7B9BF57E
-:105C30007C641AD4E7ABC77F9CD75BAC2CEF8DCAD2
-:105C40007E767F03AF7F8CD79BA01EC62F64F55A4C
-:105C500071DF096FD7C9E118E2331E430C2633BF49
-:105C6000F2963623F2573CBFDD07F773950DF39B91
-:105C70007D2919F5DE86FB3298DC495006BCDE51E1
-:105C8000E4A2A877DA65CC37D0BAF5484F062B974F
-:105C9000279C1F87E489D4EA6144C6E4F4A5E89A06
-:105CA00012F005906B59F40FE83AE3FB1AE28F917A
-:105CB00073E94D66E28FE583054E5539E5CE74559F
-:105CC0007BD7EC5C55BDB57492AA9ECC76229FDC46
-:105CD000CBE9CB5C54A2AA17F765906DBC9D9DB52E
-:105CE000D3E54F55B53B5FA824028D9FBA49DCA38D
-:105CF000E631827CB8D7969B0AFCF8B3B60A444ECC
-:105D00003BE527F6B4F3A71B8C59FA5478B910CBAE
-:105D1000CF3B587E7F7B9B879573089EAF6F6FABA1
-:105D2000C1F22ECA9FF0FC699B179FDB6959A1CF76
-:105D30007FA4FD2BB49F1EDA3F949FA1FDC3733354
-:105D4000ED1F9E3FA1FD43FD06DA2F949FA670C173
-:105D5000F329DA0FBCFF31ED1FCA4FB4F9B0BCB65E
-:105D60006D2E961F6FF3E3F3B1B6067CDFD9D68AAA
-:105D7000E547DB96E2F3E1B6203EDBDB56627D2FA2
-:105D8000A793E7F979DCE72BD9BD03F1EBDF9F217E
-:105D900061BB2F9D9F534A157AB92A3FA73F03FC49
-:105DA00002BDEAFC54C01FC26162788C87E36806BA
-:105DB000B30F2791C8720B931F18071FDFE75961B4
-:105DC000A1FC35AE95AD7B4E5F14EBD31AD8784766
-:105DD000B99D405C419251CE8E9B43BB7352A4CA85
-:105DE000C2F207D00F43DC143FE5EC5A7246E621BD
-:105DF0000DC02557503D1E33AF217C39189C80B70C
-:105E0000D1E0FD578E376D692FBB5FA7A62B0C6CB9
-:105E100066F6B6E2FD3AC6B9BEB04C9F2E9F1FEFA4
-:105E2000E99874713ADD2452F976F19B44A1CF8C44
-:105E300026F5FE317D41896A7FA6BDB8862857D1F7
-:105E40007E8BD4FB3C73FEBDAAEF8C190FA9EAF53B
-:105E5000AE15AAFABABB731E71033EC7B1B89961F9
-:105E6000F5720221E485DD4F205CE64C368F73929B
-:105E7000C27E5F6037FF3D13BE7F79D6CEF1655C91
-:105E80008DFBF2090E562C480C6A400F7DFC8B44AA
-:105E9000947F3B9ED1A09F7E22096940DE4CA6E6FE
-:105EA00024D45F01378C6BF1AA262D948B89A285AF
-:105EB000F255248AFB3ABA7FD164D2F56BD1FA9FAE
-:105EC00031D1F2D94CFFB32CBF308CFABA80AF6716
-:105ED00081D8C7AD97E3FDDCC64CF437A9CF257652
-:105EE000F0FD4B8789F90D973BCA53C10E3E3746EB
-:105EF0003EA8CD7DE28D0514DFB6B463F814EF1F24
-:105F00005734A39ED7CFCB94BE5A5EF77AAA4FD40C
-:105F10007C9307F3385BFACF29E0766BC98F22FFB9
-:105F200074E8843C5312419E0D973D8924661E3BC4
-:105F3000DADEC9935121FA116F325F37315FF94FC1
-:105F40009576C84B2CE079D13BDBD2F2ABC70F7F03
-:105F5000EFE37450482235A05F0B8B349E1074E041
-:105F6000B5ABFC31A6FC2E2F9C0B934B8807C4F2DB
-:105F700044D285F729C87FD5623E9A7CF01AA25098
-:105F8000FBD86A0D9360D170BF84FB75BECFE5FC72
-:105F900067F66A9C8F9C25EC260FE874F299D51B56
-:105FA000013AFCAC5BC7D8F4B8BABED04A50EF2D6A
-:105FB0002AD4871409EECBEBC27B40E52D12C9C869
-:105FC0000138A6B9E7837EDF6B413AB6AC2FC79F95
-:105FD00030B859E3AF40FC0E287B35C2E8A2ED9AF9
-:105FE00027EBB7823D3901F06205BCDC915F0D43C0
-:105FF000E717221E17F2792FE4F3E8C81CC23F838B
-:106000008778BC701FEFA26EE18F52CFF3F1D2AA56
-:106010006FC3BDA2ED112DFF9922353E57E92253E2
-:10602000E64BC37051381766825C01B8AF820FD857
-:10603000FC9A9F91C8C61C946B35686F9469303F79
-:106040003D9E2E9B3299DC8F66D8D97DE4EE534875
-:10605000CFC3E5936F2C48C2FD33B35B6C32CB8F5B
-:10606000F47A9558BFF72AE15FE4E772CC1CDEA111
-:106070007B0527B1BC602B89AC87BCB4B1F6F52B8E
-:10608000327370DCE17D3DB55D203FA5CC88795C45
-:10609000AB443EA172549969634F385765E474FA72
-:1060A000A84D9DF7B39DCF6F3B5F8F41A3C87BF297
-:1060B000D616C79CF3A9EBAF473F9688D30E72FF65
-:1060C000E1A0591D576DE4A43078A8ABCA0CF1C10A
-:1060D0002E16A76DECBF99DD6BBBEFC7782F30EDA7
-:1060E00053017AA8E7EDEB57AAFD580B77FA915FB9
-:1060F000E3FD64F17E318A393DEC1FE3FD625B33E1
-:10610000F97EC2438A210E7B6275DE6133EC7772C1
-:10611000089E0F1FA77D01EFDDA6BB812EB84F970C
-:1061200014B1FBA3E2D7FF54961EF1B253ACEF7843
-:106130002BDAA53BCB981CD879E0FC2DE3693F2BEB
-:106140007324D5F98095393A5CA7B7297DC3B397F5
-:10615000909AD1EE293B94A9F96A72EF5AF5EFC1F2
-:1061600034F70D1CB62828FF5E03BA1F3CFC7942A9
-:1061700011F251147FBFC408C23099C10DE7B37644
-:106180006B3E99174B0F6F67CA58FF36A78B2F0DC1
-:1061900057B51AAEB3456FA5CC6070FD0EE4C6B915
-:1061A000F0F194587B46C0B57B8CDF03F8F0ABE28E
-:1061B000A942AD1F62F074FABFC3D36EFDE8F0FCD4
-:1061C00095C3F3B343EC5E9B91F55F519F75ABE1D3
-:1061D0003DFB7C640E88490AEF5F117FEE9329181E
-:1061E00013E6F8EB2DE5F459CAE58F07CF5091C0BF
-:1061F0007B57631E66AF4C926AA15CBE007FF72C92
-:1062000093EFC3021A3F9EBF21EF1946957FD764D3
-:1062100031BADE9D2E8D8A87D22C36CF0347EAB263
-:10622000C1BFF1D83B0602726133CFBF7ECCDE6BBB
-:10623000847BA6051EA15C429F017D741128BCC70A
-:106240004A3F332AD651C6D3B0F1D6C6F18D184F86
-:106250003CA76415327B553AA48573386BAF7D0B30
-:10626000EF7F5B5B2AA3ECFDD2F85F1D87FFF05B3D
-:1062700029B7307A999245E16B91FE90F06D5A0EF4
-:1062800048D17F2A827C15BD1FE71FA078EC91467C
-:10629000E2292D8BD18B989F98BF80DB76DD025C45
-:1062A00007DBBB06541AA5BCBDD017895CFFC1BC77
-:1062B000505F5C2BB3734C6532AEFBDA8AA978EE83
-:1062C0006C37CF17895EA31FF577441670BC3D76F7
-:1062D000F1B711B84739D8AFC3FB3F883CE0BE15D2
-:1062E000EE1FFF8D8CF789537AAA81FBCC0E1C39E7
-:1062F0009F00FBEBF9593A847B3E97878317B535AE
-:10630000781EECC867766D0CFDD76569B97D12897A
-:10631000C039AF3525EC3C8B95DB03D623271B001A
-:106320007E6BC543062986DE66651910AE35FA68B0
-:106330008A87F617D8A72561E6FFC17B1987CEB3F8
-:10634000DA191E5A4A0FA1BD60ED67F735D66529E7
-:106350004CCE52B8F7D2F7E6899FD9EBA1BE948E06
-:10636000973BFCBDCDCED6D35CC6EE4B5A7BED3F02
-:10637000DBE13EC844F81D47D8EFF2790AB89272C3
-:1063800035BCDF482417F8CB2E63BE5A6FF85E2366
-:10639000D8FB822FDECAD562BB47F93989472B0A61
-:1063A0004370AE4CD0B135DBFF4016CC8FF2C50B3D
-:1063B00068EF447CD3103FF662C833DF2545E632F0
-:1063C0003B446F073E2CD46854FC16E1EB269E54E8
-:1063D000FDA3DD733FA75DA1F73B424602E74DFEFB
-:1063E00078716622D8A71D19C2DEF31A015F9B25BA
-:1063F0005F620E8CF32F5ADC0F1E3872BC01C6EDA3
-:10640000A0F302BE7DF875EB6AB0533AEC5EE4533C
-:1064100031BEECD0F0F560FDECD67BDF047F64D4B8
-:10642000C1EECD3A38758611E89FB6D3403F7FA0C4
-:10643000FBF7F004E8A71AFD060BEDB3A6C3778BB4
-:1064400088FF11B06F17756B55F7833CCCE5C5C25B
-:106450008B16128ED92F2CACF80E9E6B5C78310106
-:10646000DF3FCCCFED3FCCCFBDEDE2F878993F5F79
-:10647000CFFA8AFB6F4F9CDE4AFEDD8E3AC6F7BB31
-:1064800060FD9AA5013DA8FA35533FC7F3647F68C4
-:10649000B393B02106DE11F34C22E1987187DA5DE7
-:1064A00034917052ECFA32FA1D9EAF15EBFFD0E634
-:1064B000463C8EDDFF38151E87FBCF53E17164FF2C
-:1064C0000558FF87B6C24BF43F798CFE7354F00F2A
-:1064D000F79B8FEFCF1DAC7BD642F9EE6078C5C637
-:1064E000574BE1F7F70CF87B1BA4AFB70ACFB9EE17
-:1064F00022780EFA81FD7F7A1FF2521FD8AAF7C0C8
-:106500001883BAE83CCF287A269FD88370EF9C780E
-:10651000BE9D9587EB1CFFDE2887EC90676A2C9464
-:10652000EDA0E78C24125A01FB975223CA3911DFE0
-:1065300012FDFE3453AB92B3E27EA1469E7FD86833
-:1065400061F1AF26ABFF2CACFF124D57CBCF681FCC
-:10655000A70B3BF07C3B210EDCD788F88E0CFBC5EB
-:106560003C707DF9089C0B9B97E3FF0CBEFB091563
-:106570002B10EFD15EB1CD0FF9798FF37DE4E3A657
-:1065800088DB13233F75D9F257B31BBAE2E8B7ECA7
-:10659000773BC28C7E75D940BFDAC8CFEB72E07C06
-:1065A000E300BF674E41FBB9AEF430DE475927FC2C
-:1065B000022BE3F356321D604F8B785402E41782AE
-:1065C000DDB086DD53586F61E5FA5F27E1B917BA90
-:1065D0001FB214819CD9AD65FE221E073BCF611E00
-:1065E00034AEC902FC0EF27C97F3FDAFE1BDA7E724
-:1065F000578E473AA8FFE50FF11EC3DDE94C9F0D0A
-:10660000EEB3A13EAB3778CAE15ECDDDE9CC6EEDED
-:1066100095C309253176ECA3195528A73F5E395E4D
-:10662000131B27199FCDE4C21AE1FF94A3E570CE96
-:10663000EAE3D2F03FA13EDD63C2DF1BD3ECFD53A2
-:1066400039DEBFBAC680BF6351B577E2BAB9B05F71
-:106650004C90311F5BB3D784F09C5DC5EE83836F94
-:1066600041EE35EF1D87BFCB566F8962DE64B3D92B
-:106670005300F1C1FABDDFC0DF9F38F1F8C42C90A0
-:1066800083C793952CBC6FFB718A743AEFE3FB26AA
-:10669000B0F79D57E3B96ADB1A8B7F34FF88D04B84
-:1066A000F1F7CDED4E2F3ED707F89968F4801C5EC8
-:1066B00038E45F67F707D6BF199DA524A0FF06F34E
-:1066C00017EAEDA7F0F71DEBBB8FDD49303EE9423D
-:1066D000FA15FBBCF871EBB9FEDAAD8FCE83DFD5CE
-:1066E000AB6FE7F8E7BFF759AF29C6DF9B14F85F38
-:1066F00013771FF3F738DEC5F3C41119EFB9A47689
-:106700004516F88F4EEC3720BD9D583319EF5710C2
-:10671000E3D55358ED944F8F3B9529B0BE0BB2157E
-:1067200036FF76B67F15EFE9F811F8BDCEE83E2DBD
-:10673000E6AF0DDAA30910C714ED4479683EFD5A9F
-:10674000FCBDB7DDE90770DD295D11A02BCD2F6DF4
-:10675000A8B703BF64BF1BF7712909829F34F88E65
-:1067600001F77B07F719D09E1E7C979DCF1F71EF15
-:106770009F359A05F7DC067E390EE5DA6066740B04
-:10678000B3BF4D78CFE4E051FFD53C5E9CC6EFD15E
-:106790004C03BBEFC23E5318EC3EFAC4B843906CB6
-:1067A00073E3FBFD16BC2F883ED9F924698F1B7F4C
-:1067B000378974F1EF23F8FD0359FE0920A71FC89C
-:1067C000A3FD5BE1FB93D8EE42AEFF4A8C591192D8
-:1067D000CEC74BC77E33FDD9F85EFACCCD7E0FA86D
-:1067E0008BD747B03E60F05F8DF3F8BD8DF48C32EF
-:1067F000CFAF7A5FE47DD949B88E026E8A67B42341
-:10680000E3F1D293CDF69F021FF17439B49E9780C5
-:106810000FFC3278BFC03EB68EAB26EA993CE99CAD
-:106820008CF632DE30149327B87CDF074897833A22
-:10683000EFD3A097A2477584DDC3482D03F05754CA
-:10684000B076F516E6F710709CE1E7071A3B591E83
-:10685000E199E73EC89A6F85F3F31FA8CECF0BFFEF
-:1068600021ED2401FC33568F925057C4EC762DC293
-:10687000C57E8F6E8D4EC1DF0B0C3E3E11FD122783
-:10688000F4CA5EBC0776D5151AA0276D3197BF4FA5
-:10689000B07989FBDDC43D6DF17819C866FAB2990B
-:1068A000F8EF823BFE8F132585074BF1BE4A74FF3C
-:1068B0006B20CD52F69A587E3BEA8591F742EA2F3B
-:1068C000F17B82FFBBE553B05665809F6002E8D53F
-:1068D000D376B67FC45B2240BF6BD93C3BE003B8A4
-:1068E000FF82F84E835EC45B25281E4E4BAC3E9E55
-:1068F000CE84BC1B810FA01BE817BEA37D7F9E9D8D
-:10690000C3F63F76273F9417D4435EAAD057014978
-:10691000D6C07D0F271D4A02D0E5C9CE3CE772C81C
-:10692000F7712829B1F676E010C17B0E1438FF7399
-:1069300035FC2E92770AF805773BD5FE8878785E8D
-:10694000A81C40FDF35F98C6C553008000000000FE
-:106950001F8B08000000000000FFB57D0B7854D5A8
-:10696000B5FF3E73662633794E1E8484409824E436
-:10697000018430090F4141074810156878092885BE
-:10698000930710421E88B6175BDB0C24205AB441D3
-:1069900051D18B76404154B4414141037700A55811
-:1069A0005163D5566DCB0D88BC1F31A897FFADAD97
-:1069B000FFF55BFB9C64CE90A8B5B7F93ED8D967CC
-:1069C000BFD75A7BEDF5DA3BDF7C433FD7096175D2
-:1069D0002B42F41022CE6D11629810A3DC82F34298
-:1069E000D885C811FCF38DCA89DB3A5C8885F88D9F
-:1069F000AAAAF9DAB59EC82BEB2D5C1FE375467782
-:106A0000F1BDF1B5FF50F228B3214C0887FE3D5D82
-:106A1000880F311E8D7BEA90DDA70C461A2EAC093B
-:106A20004254AC75FA451AA56F4ECCBA53E685426E
-:106A300075C76C5C99D84AE3966F2ACA1291B21F47
-:106A400041F3AAD0E7559EEACD52870AD1F6A8EACB
-:106A5000DA84F6EB559E8F6AF3B81EA5EF27D6DBD6
-:106A60005CCBA99F0A7D3E277A6BD1C5B994B70A42
-:106A7000ABBD80F2562DDA45FD2E78542DF677B158
-:106A80003EAAF781B5A00BF8604D893A7C32A81E6A
-:106A9000D66994E3BFF7687257D1FCC2E977CC633B
-:106AA000A3E2F7D1FC4EF4D1E6217FFC9330B18212
-:106AB000F2EADA45D1EEDC2BE17DC2A1457B720121
-:106AC0005FB91E039EA1E318F0BC0878C620BDBACA
-:106AD000C54BF0AB7D48F5A0CEBEE64BD180DF982C
-:106AE0003D4547AEC1F7B561228CDAEC3B9CFECE4A
-:106AF000AD348F8BAB55413D8AD23D198982C6DBBF
-:106B00006EF97C2EE073BF4DCC7A91D2D2B7A747F5
-:106B10005B28FD46A71FF5210927356A7AF47CAE6C
-:106B2000DF3EB998F2C7DC9EC482A07A3FD6E92C3A
-:106B3000145F656BFF168D712AD6D8785D065E2EC0
-:106B4000621D34BF8B8D11FEE504978BBDDBB85FF2
-:106B5000034F46BF15C083414F546FA5DBA58FE39C
-:106B6000B31747115CD3B4E19E2EE864C183342E81
-:106B7000FA5B1FE575E67DFF710D7874E09B962545
-:106B80000CFC038F4FA46DBC97BE59DEB30AD193A2
-:106B9000E0D0787DAA42DFCBF6840985FA2B53DA60
-:106BA0008E28099C77FB14AC7FF13C8C57F67198CA
-:106BB00005E5C7F75E9FC7F30AC12BC129B52B7A3C
-:106BC000BF98D696EA0982DFC53E6D7379BE067D11
-:106BD00074CE9BE751BB374C605F5C4C237C4676A0
-:106BE000C2B101F819C6F55D76A66F6F1EE0D7B188
-:106BF0005E57C87A5D21EBFD40307D0B8FC6EB29D7
-:106C0000FF24CC82EFE50FDC94E5A6718EDF3B8E8E
-:106C1000D7753CCE9B87FD753C95FACFBD729DE53F
-:106C20000FD03A73BF659D8D4EC657B7EB8C6B7B0B
-:106C3000427CCB3A37EA7468ACF333AB3BDA8AFA7E
-:106C4000BB55B19C8A6AFB14DF7F8DCCBB56D0D07C
-:106C5000B536490FB56B23FCC0D78566DB047F6E64
-:106C6000271FA0F1BE273D58981E8E8F753F3C020E
-:106C7000F4759FEAF2B9019721EFFC9CF2C7EF5738
-:106C80005D02F9B1127EC40F2CE00FC7538B27733E
-:106C90007EAFCDB582FAF9B4F16F7F04FD5CDC63A1
-:106CA000730B5E5FF1FDB390A7F982AF115C6EC606
-:106CB000B854CEEB57EF19D68872F1E86057A6BBEF
-:106CC0000BBE1402E78A35AA691FD201C1E3D53E83
-:106CD00090E2C63A0C381387CD9A3AA8131EC84FD3
-:106CE0001FD409975ABBD09AF8FB12FB944141FC80
-:106CF0000CF04997E744FF3CC9C7D2A283F673C89A
-:106D0000FC42F98F51CF48FFD2C157CCFC7851706B
-:106D10009EE05019925F1CC237AA42CAAB43CAB761
-:106D2000F7FA9CF940E8F813D3E4BE31E058AAC35F
-:106D300071BB45917CE43EC5BF897E2DB5BAED4B54
-:106D400069FE2F8E11F3D04F995538AEE57DD9CE1F
-:106D5000EB2BB58A86B0027CF7703D63DDD45F43D0
-:106D6000581CE5C3251FA27A13EC417983DF1AF37F
-:106D7000094F93F030D2C55B9D8DC783E059DD1478
-:106D80006BCAD7EE4A6E3CEEE8CC2FC62FC9F46F23
-:106D900022AD7E38E0227FAA77B51E8C20FA49B258
-:106DA00068E169D4EFC583FF1B9DEB66BC0F2F26FE
-:106DB000FC16A8E92F1DA6F5B6ED563D9BD0EF9B1E
-:106DC000F2FC115F5F7A781B7DAFD99B21EE75775E
-:106DD000AE3F148E17775D8A4EA7EF170ED9C30505
-:106DE000C901A5CDF163EDD1BCBFBA84BB5B87BB44
-:106DF000D1DF056B6BF494A07A17446BF4D4207A3E
-:106E000029DD75A94EE431FC7C6A101FFF744F8F99
-:106E1000B12A7D2FFB7DAFB1164AC7E9FDDE6F7346
-:106E20003FB986E6EDDB1DE6D94CF3BEF0E62C0B50
-:106E3000DA5F78B3424F7FEAE5F4B34F53317EB463
-:106E400045D2BB31DE8834294F95598E3E311AFC2C
-:106E5000FFD59E69F5699DE56596822CE0799BAD2D
-:106E60006D2EE67D4111AB95B8CE7EC6A5B9B9FDB4
-:106E700085DD279F007FF8F4FE3E05602B177667BF
-:106E8000E769547EE1E321592EEAF7C27DC91EF07D
-:106E9000856D36F74F99DEEE89F260DF1BFD619C50
-:106EA00025E87FF755C335A41FCBF9523E4F93E336
-:106EB000FA9482CE7EA32DEE5F8F02BFF8BDCDB3D4
-:106EC0009992A57FCFE8198BF5613F778187B2D57D
-:106ED00061C26DE2272B78DEA5C263871C84721124
-:106EE000445FE5A298BFCF6F347F5F407C02DF171D
-:106EF000AE377FAF108DAB5A697D8BFCE6EF82F623
-:106F00008F2F11FBDAF869E2F37EF1D66FC24CF5F0
-:106F1000844FE70F0EE6C7A5B41FC1C79E57FCFEFE
-:106F200015C0EF3D2AAF33745DCBD3D2781D8F44AB
-:106F3000FC636E6B105E8F59843589E07ACC2E1C11
-:106F40004905E847089CABBE3D61FECDD4E4DEFEBA
-:106F50005FA59632DF4BB2E03CB8C305CE47FDEDEE
-:106F600039998A7ECA5617795B83E677D1E67DE444
-:106F7000E79057DF237E4DF58E8DF5378EA5791D71
-:106F8000BB57F5D47731AF33249FF9E3091EF728B7
-:106F9000C23F84F2CF9C4C2D21BC9CDE7C32B534A8
-:106FA00098FE15312B981E8D9466C2EB82AC89F445
-:106FB00018AD05EB09ADD7895FF37C0D783A55B173
-:106FC000A42B7A7814744FE5397F5705E4CE9A3DA7
-:106FD000363FE83362E3170FDF0AFA6CB6B940DADE
-:106FE000B57B542FE474B15BF567E21C6BFE34BAD9
-:106FF00012E7CCEE212E3568DD740E17E37CB9B0B4
-:10700000EB5262592EF73319F244ED9E873CA0DF14
-:10701000EEE6F15C9AFAAFF13FAF99FF9DCFFD200C
-:10702000F146F0818D27B2C0DF890F3E9786FD992A
-:10703000F5B51D79215A8783FE687E2CBF5FF47FEA
-:10704000C5F2A5A359F5FABBC0C39E343BC3FF07E5
-:10705000CF6F02CD2FB1737E349F3DE0CBC63C6B2A
-:10706000DC6D769CB3171DD179E0A7B4A089F989AE
-:10707000FAF9E4067F2D9B2888BF16EE9EBFC20951
-:1070800079A151F1400F286F56F9DC2ADFA0FADD13
-:107090008497C2ECBBF63B219F3E44E5D474BC3AD6
-:1070A000EA8FB3A8FEC2FB54CEEFDBF8D33FDA8001
-:1070B000D70D3611063C86476FD2C7637968913E7B
-:1070C000BF45CD379D56A0B7EC513D01B4DF1CE55F
-:1070D000C1F7B2D5B663C1F4351FBF507FF3D72BCC
-:1070E000FE401AF884B9FCC2309FCE2742BE6F5CC6
-:1070F00035757F02522BEB898BFCE672FCBC4EF39C
-:10710000A9D57FDF9AB9A617F073C129440BF6AB56
-:10711000B595F51D11684D051E2FECFE2C1578ACAC
-:107120007DF57FB24417F8EBD84FCD510927228463
-:10713000384BE7C63716D0FDA5C9C55DD47FB18FE2
-:10714000DC175B6DBE5E9063F76FFC8AF9C1C5DD2D
-:107150005A5F5717F4DBB95F7D4E4B12D280532034
-:107160001DDAE4BA11FB84E4C17B411F9B564DDD5F
-:107170004479E76B364842A2363392F70BF6C7FCE8
-:10718000A07E8D7DB2157C01E930C91F5EEC23E540
-:1071900084D5BABCB0755FFBE4CC2EE6B33ACD26FD
-:1071A000CFDB3E926FCC4D2B0E4F879C61F1450398
-:1071B0001FC2EB7527107C159DBEEA972D51F03D3F
-:1071C000493472DA5B3471FAB8105A24EA0B8F0B27
-:1071D0007016A24F2CE0C77B9ED7AB31DFFC898EA7
-:1071E0003BF06AD0832F56F837D3EFEA46875063D7
-:1071F00020EDB546A351D4A0A9BFEE4BE5B60F5480
-:10720000D69FD43E063E3D2EE0F7CBC8E931C1F80B
-:10721000DB77B87402FAABDE497A2EF5777E874DBC
-:1072200004A0575969BF503DDBE12FEC69E04BCD1D
-:107230008A80BC5C4B797CAF1D65F5FA83E0929740
-:107240002EE1919A9EC570BB60F51E9A08FA73955F
-:10725000DA21D7DB0E974FC079634B2AB5635EFB0B
-:107260000E8F75A4016FB156DE37AB9A8D715B5CE2
-:10727000E83F2AF6039E6F43AE454453BB868FC258
-:10728000FC0C4C87E443613A5C1B02850E7717F8CF
-:10729000F189C2143182CA77A81330CFF3AE5217E6
-:1072A000F0688B957687309B7702F49AB0D8B878DF
-:1072B000CC6F447A06CFFFABD8253CCFAF48BC801B
-:1072C000BE41F27A31F20DBDCB55867DE323BC8FF2
-:1072D0006B1D72FCA83D2A9FA362A443E7DBEFBBB2
-:1072E000CA689CC8BEDA24D083319FA861AF0BF076
-:1072F000E71C8B85E5B3863722D7802F18E51BD294
-:1073000025BD19F858996075817F3CAED3E74A577F
-:10731000B1A320689DB61E161D5EC50EC069BBBD1B
-:10732000F810CE9736FA8E73737FD25407F414AAEE
-:1073300067413F27EA68C764A3DFE90EC07741428F
-:10734000E978B45B2896ACC27E5BB85E1581203EBE
-:10735000DB6093E32EB81C2102433AC75D40F8E39B
-:10736000F697A3F97B8353D66B8892FBE7CE7429FB
-:107370002FAED4D3B57AFA83F9BAC7CCD7CFC7FE2C
-:10738000714BA9E4EF77A653BFD54AEB788826ABBB
-:1073900092DAED80EF893A97088405CDF78A75C6B1
-:1073A0008B40D0381DF52E3B45203E181F6EC6473A
-:1073B000E77A23B9FC445D12C3B1FBFE534C70EC79
-:1073C000EC3FC304C72BFBCFE2F2137539DFD1FFCB
-:1073D000C06EFA4F33CDBFB3DF7EFC5DECD2FA82D4
-:1073E000BFDCED227EC074D3CA7626BBA2FD067632
-:1073F0002FF1719880DCF79553CB7605F1876DE915
-:10740000765D9F0BA480DFFAC43A4E6B775D1A8FCE
-:10741000F66EE20B6CE7D0CB6B451BCF13FC02FA88
-:10742000BD48B6BAB97C97960DBDC89847873CF35E
-:10743000BB489F85F641D89EBF47631F5FB4B64DDA
-:10744000867DAAA9598D08DED707F4FD31B6CF177E
-:1074500079B0D7D5A01DF1BD9FEE5D9C0DF8D48409
-:10746000B5E561DEFBF7FE2D0FE7C8577B16F7C5C4
-:10747000F7AD549FE50F7B5B8D27A8BF7EC2E5B3B8
-:107480008CE84C9BF5FD1FFA7DEB9EFA5E98C736A3
-:10749000D83D482EAC59F656C6F178B021EF83E0BE
-:1074A0005F82F816EB43BBA6A96320DF7D48320F4D
-:1074B000E587EE9672C3D03EC26F4983DCF7E12CBC
-:1074C000F0899A61761754E1F0FC1696B7C38739B4
-:1074D0005C389F9FED93C1EBB3434EC840FBA2784D
-:1074E000A6E754F1AFC96D1B42F64FE00F35DB68DC
-:1074F000BC6AB575F23885F7D131F0A99AB7BF7873
-:1075000047D75F13819F5A8C4BF0785FEF27214359
-:107510003B897A9AA3F5BEABA8DE8C9B9353A11F3F
-:1075200095E8FA9998484019C9FC6810EC20579ED4
-:10753000DB520F7A4DD134C0C197ECF0E0FC1A98C1
-:10754000221CC971D8D0FEF4A934EE57E916C32E17
-:10755000AA60DE03F4353DDFAB69692C9F93FE38EA
-:10756000D0D13F3BAE25C3FB77F00BA3FE8737DFBF
-:107570003A48EBE2DC30E479BBBDE936CCB3AD3A56
-:1075800092F54798F3D0EEC99BC3022AEC8AB6C89D
-:10759000D5D0E73F8A987BB007C1E3FE282D228330
-:1075A000DACD9A79C32AE495FDF1EEA5A0E792D64B
-:1075B000E1C0E7D34E2D2683C6AF72687D1369897B
-:1075C000E7FB68D93138E48BE3259E44F1A0E22E35
-:1075D000E72FE753A2C8F10F476949E8A7C4D2F2E1
-:1075E000C455F8666D617B8368E8C1FD9CB78B8AE2
-:1075F000AEE47F030E47F475ECB3896B2FD3FAF634
-:10760000AD8DF1D4D37CCBEF9E39B796D2F996E20B
-:10761000C4806A9A7716D655E52BE99B4CF2F3792C
-:107620009B3EEF65FABCADAEACE0FD1C3AEF7A4391
-:107630005EF985C2FA20FF50FE155FACFF5ECA8777
-:10764000592E7D300DE7D6200BDB493684D3DE2260
-:107650003DF25D7D9E8FD3BE73C4F1F7D5F89E14C5
-:107660002EDB273D6CF1C37E503C7637E3E9C99AA7
-:10767000488F4A639508B71D725099F0B25CFCD9E7
-:1076800098BFED69A575156668D7016EF3E22DA95F
-:107690001FF03CB48153206F8D92EBF8167993D78D
-:1076A0003155B86C2C94893516C81F535D7229F377
-:1076B00015B93FA609AF0DE3CD101AD7FBC305BB23
-:1076C00017FAC41FA00BD1BC670A1F7F9F2DFC9C1B
-:1076D000DE2A025CFFC7A295F306BC893EE6254878
-:1076E000FA38D95365F8DF8C79BF1791D76719AD90
-:1076F00063CA23D999AC5FADEBC1F0F9AE794FD134
-:10770000E986F6EF3CF483FD3B9DFA997A63C8FE67
-:107710002DEC61E033F3DBF6514B7B87FE14994C83
-:1077200070B85E47E9F5DEC5AC3F15A991C247F8D0
-:107730006919A5FA21771CF22E4F48A075DCFDB916
-:10774000D4837EB75CBC3D84CA7F374615F5DCD256
-:10775000CBF2D464BD9FC9BDC79F869DF5B00824F8
-:107760000CA5B9175DD65E8FA1F94E56B735C45238
-:10777000F984DEA4C704F1BD1B12B65BA1D7DDD826
-:10778000CFFC7D62AE59DF99241A55C079F250734F
-:10779000BD7D800FD1D78A0CA9B788016280EEDF4A
-:1077A00063B9FB477A1FED132FD9E10B793543BB42
-:1077B00007705C3AE9B3B9185758E57A6ADE51D9CF
-:1077C0009E778CE42C2F9DDFC7EBE8840893F208AA
-:1077D000F2A7486E407AA6CECDE9393AE7517EA1AC
-:1077E000CE23EB67143F807D56BAFA732BF072B745
-:1077F00053C2F96E67AA1F76B58AA6C6F1985EE5F0
-:10780000AEA68348CB03C5E371CC2E38B4E420D2B6
-:10781000BB3BF4B6250EDD5FC0F3BF5DA7D3DBA392
-:10782000A6DE3488F6C9EDBBA5DFEBF63E53A74DC7
-:107830004A40DEC6F9EEE8A8FAB22234DA22CFA82E
-:10784000DECD58B7B7F9E8C1785AE7C9BA113CFF9D
-:10785000D3755E9EFFD9BA099CFE3DA3F839AE27C9
-:107860003E67796CD2B6A3D614AA5FE455BCD8B7EC
-:10787000D77A85DF4F74B1DE26CF81F5740E601F95
-:107880008F1934F5F13B30E90C6D27DACFB871511F
-:1078900011C6993CA2C48A7A33BF16223EAD934EDC
-:1078A000BF8BEE8DF557EBF83BBF5761789EDF1B22
-:1078B000CBF06CDF911103F960E9CE8C9E48896FA3
-:1078C0001A7A6F04E0D77ED9C2F36DFF289CF58E3B
-:1078D000D0F64B770EEC897A6709DF2248DE3CFB55
-:1078E000FC7FB883CF95B3714D5F7D02FEF657C91B
-:1078F000DF48B239F118F85FEF5E1ED0CB055DCEE0
-:10790000263D2302E75F8D6E57047F42FE6CB8B4BC
-:10791000E70E7F21652CF617C673139CC31C19B99B
-:10792000C787707F477E46FDBDFC589207FAEFB9C6
-:10793000ED8FA463FCAD4DF33F798CFA3FEFB7F8C0
-:107940006C744E9D174D175E051F7E2A92ED7B7756
-:107950002B342F9CC39B7B713E47B1862FC3392CA0
-:10796000FCBCCF7314B77519F1ADAA171FED057ADA
-:107970007C8D603082CA5F5B1BC17CED359BE7C8A4
-:1079800032F4F7B8ECEFE9FBEF3CB60BE97DD50537
-:107990007752FA65461CE3A1FC814503D09ECE795F
-:1079A000914CFD3DF78A1280BF6AD0BA7D2B926957
-:1079B0007E83371CB5F4A234FF29A51EE9C03E37EB
-:1079C0001E82FDF96F196E6E3F645B9A9A826DD9C3
-:1079D000CBFFC9757CFE9BE582DC759F8FED253A58
-:1079E000E583014AD3998D34D7B0D48F0A348663A6
-:1079F00023AF6767F3B4F76F155807491E98778967
-:107A0000DDC3E791DFB711783EAFE57858BF2BF6BD
-:107A10003D0A7A3BAF257A703EBD4CFAFCD5A87F73
-:107A2000C4CAEB7CE5A9F7A261DF89213DD909BF72
-:107A3000487EDB78D4AFEEE316F087F579E2FA09F9
-:107A4000804FCD8E9D1BB99F2A8707FA6EC5CE4BFE
-:107A50000753202FDE203C99A0C71D32FFAB42AF59
-:107A600047A5A5566CFC52E65B8A395F4CDA27FCC9
-:107A7000FEA24CCA498FE8E7A068CD637EC924EE18
-:107A8000EEC4D7AFA818E5EBD37CC9B06F1BE727CE
-:107A90009D7BA9FDB065ECB27DCBD85B53192EDF81
-:107AA000F3DCB3EBE797D1DF2376E173523F30DFAE
-:107AB000C09EBEC12ECFEBCDC467402FC6794DE32B
-:107AC000E6F593EDBDE0AF29AA326807C123E59141
-:107AD000309637BEEFF8B36256F1F96DC85BB5E189
-:107AE000922FF2D941ED5F88D2AEEE370C76327923
-:107AF000DE0BAB3B17F2C8E351DE6BFAB1BCD59697
-:107B00008A35D0397A1DE653A392FC9511247F451E
-:107B1000C67DAF733410E52D42FBEF5B7F6C04CD67
-:107B2000330629F1EF68A486DE455A4897FC397D73
-:107B30005B13F8F34361923F470D61BE64AC33744D
-:107B40009C03C40734E23B6FD039A3113F181739A7
-:107B5000C6CA787DDD527590CEE522390208DA1A60
-:107B60003B94F3DE28826361A42AB42EF4472325D4
-:107B7000BCCDC73AC7274498EA1525C4DAB18FBFF0
-:107B8000EFFA551D4F6AB83CBFD47083BFBA137467
-:107B9000BF7DC8FAE57A6F770E63BE3A56F97EEB81
-:107BA0002EB215DF093C8F8BCCE773735CE4942312
-:107BB0009AE075D4E17BE87A43D7251CDF4F8EFA33
-:107BC00089227C16ECC7CFED6C776BB6B53EF75BC0
-:107BD000826BF3A25C0FEC472FD3BE70809F4EB533
-:107BE000B39CDB0CD992EA37F770715CCB6BBADFD0
-:107BF000DC375B6FEF147CBE34CFEEC57EF45E6184
-:107C00003410EC48F5D26FD26C5BF216CEEBE6E5A1
-:107C1000291E9A8150C1EF69CB7CE497FCBC5E09B8
-:107C2000DC0A7F81EF73BB40FD75B1FED5E9945F3F
-:107C3000F78B0C9ECF47A48FD762BC8A70E65BEBB4
-:107C400062BDC971049F97FFA1F279B22E9FF29194
-:107C5000CCD7D96EB36E8A37197EAD041D6FEB3663
-:107C6000CAF25EB093A23C4DB6FFC426EBDFA2D7AA
-:107C70004BD0F1FBB14EA7B4FF993F689323ACA062
-:107C8000FF77FB95BEC6FB467893E1177AAC3C9331
-:107C90006D98B754DE90C6F4A4DBD366E9FCDCE84B
-:107CA000170D1CC3214FCB9FD9F3373B41DF332A3C
-:107CB0009C47211F7E54B1220A7AFD0C4D0D842170
-:107CC000BE6A7A91B743AE4BC7B85E396EB9A11F91
-:107CD00006CA00DFBD6D0E712FCBFF8121C1FA9660
-:107CE00081E745FABEAD6E1AF360B07E5D6927FE8E
-:107CF0003318E5723F57456ABF077DD5EEBAE1C13B
-:107D000060BDFB54F94379BCEFF471CFD5791F3CCA
-:107D10009E09396F02A7C6B81DFA11F049FDF6D5C4
-:107D2000CF73DAEF3E0BF0DAE494FA92B5EDE38527
-:107D300094AF9F3580CFF709531D5ED8F5DA77846D
-:107D4000F961AFAD9F15EEC5BAEAF744F9615798EE
-:107D5000A7EF1BD2BBF8BB6FBB8DE9ADCAEE7F6648
-:107D60000BB5ABDADB9FE989E895ED96BE57236446
-:107D700079B4376DE55094F764FA79CDE68EE1F287
-:107D80003755C1E5E181AC5882779B533B8575132C
-:107D9000BDB2FDBCCA2EBF1FD1E912FA25FBFF966A
-:107DA0004471BF42CF6B3F8F677D4F58BDC9F39180
-:107DB000BF7D20AF47B3CB7D216AA47E78C425E781
-:107DC00075A4399EF785418F478AB7DC939580EF7C
-:107DD00024AFD2FCFEB24C0DC01F6ED09F32F5F224
-:107DE000DB5751BB4F5F55D96F33E7D78B0FE3FBA1
-:107DF0009C15D51339ADBC6B329FCBF51FA7EEA2F6
-:107E0000F284A9A7D8BF6BE07F4E95D99F9A98E9D5
-:107E1000553381DF5CFFF68354FFE1D9271600AFAD
-:107E2000C333354726ECDBF6D697FF4CF36D5DFE8A
-:107E300027D6A336446B11F87E71F7D35CBF66C5B5
-:107E4000FF2C807E50639574639CDBB53A3DBF91F7
-:107E5000A9C5A2FFAA15BF633D2222B745F2D7BB31
-:107E6000BE1F3F3AD3BCF96585DA2D0E6FAEE154E3
-:107E7000F5E7E1FC3BAB04A2950C862BEB75E75CC8
-:107E80008168E047B348B972F1D610BF315092A86B
-:107E9000DB8BA8DDE226558F57F4DB41A7A1F51750
-:107EA000D377AEF73DBF578A26F93D76D7FDD73059
-:107EB000FE4500FEAE33CF646E023D9CDFF9745682
-:107EC000B09F3634BD72BE72FDE7F47D738EBED8AE
-:107ED000406FDBC24CF6850BCF24EBF426E9E9C2F8
-:107EE00033D9ECE74ED4F7D905C5670947BB5F081E
-:107EF0008E67109EA6E11C97E36D1A0EB9FB619D7B
-:107F00002F2E8E6F1A0EBE67F041E168CA63BB4127
-:107F10004E531EF464837F8AE2A62CFEEE6FCA42A3
-:107F2000FB972DD20E63CCA7F2B9148E7BA2B5F0CD
-:107F3000FEAE7C6EE026E48D71EA9D92EFD43B2587
-:107F40007F095DB79629EDE8A44FE61EA7B3A43ECE
-:107F500096F4825CE49365DE29F30B3794D8E16FE5
-:107F6000AFB7C9BC6B7D89FD18E6F73569B5C44F5D
-:107F70007374BFC5027FA9DD0BFBFEFAE5E11C3F70
-:107F800031DB3ECF4B69F67ABB695C030FFDFDE642
-:107F9000EF8BF4F9F40D890BEAA5B6ED0BC339F6B6
-:107FA000A4E8328E6049A6B4E33EFB6C477C91AAFC
-:107FB000EBDBC26DD0A15BEA1B8CD78FED065EEFC9
-:107FC00048A1F92FD6E3A55EB648B8FA9E957CE3A2
-:107FD000E57C2D05E7D505C01DE75C2CE57321EF99
-:107FE00049BC1979035FA1F05DF1F18214D8959F26
-:107FF000C894F6C7507C2C8F1ADE13E5065CCFD4EC
-:108000001DCA00DC8D759DA8F37AE968EBB4BFAF9B
-:10801000CF77688C8F7C47307DD76F1D7288242086
-:10802000716EABD58325D45BFDF743BFA8DFAA36BD
-:10803000F904973B80977391FBDF41BD051B620BF1
-:10804000A00F18ED17AE2FF29607CD7BE056335EEA
-:10805000063599F3837799F35B71060DFBE7DBE552
-:1080600007CCF92187CCF9931FDC7133B64F85EA31
-:10807000BB5F85BEF3E7F187704E9F7AF99568E0A4
-:108080006BF15FCB0F428F0B8D67213C2AD0737C45
-:108090005B14A6972BE25ABAE14346DC06766230BF
-:1080A000DD540ADF416BDA95F5CF8AA69BBD4467A4
-:1080B00055CBDECF907AB3EC7764D35A3BE4CED085
-:1080C00071BBE33B22D2EBC63E2A1921CBAE5E3612
-:1080D0004E7C8AFED6BC371EF458F22B85E59B9267
-:1080E00097B25F07DD1CDD3EFB464E6F9EC0F03051
-:1080F000EC920B9B954014E55D2344877F1FF18B29
-:10810000A50D21F19F6B42E282D699CB17EEDAF7EB
-:10811000FF104750E17882E32EAE8C67F41F805E3B
-:1081200059794AB07DAAF2A96FC2CCE5725DF3F528
-:108130007518E7ADF05DCBF17B57CBAAE238FEA313
-:1081400073E9A84B3B8573CB3877AF5EB75195F297
-:10815000BCB784FDC891768E8BAC76884004CDEB9D
-:108160005094DDEBA2EF97D647B1BCB280E45CE857
-:108170008B940A27C74D7A62D0EEC4BB2ACB65D553
-:10818000F1121ED5BF51FCB01D57C3A88BFC933212
-:10819000BF4804D8BE0B3AF206AD03F80BCE8B46AF
-:1081A000A95F565903FB009F8E7368ABB95E15AD8E
-:1081B000F3A338C87BE6EF35A28DEBD7EEFA262C79
-:1081C000F87B903D9AF55E43FF5675F94AFD653898
-:1081D000CB4F74208483BE6CBADCBEEE1E92236843
-:1081E0007D2B0D7BF85A29DFDDB2519E63249F67FA
-:1081F000014EEBD6927C86EFA46F20CE442C0AF77A
-:108200004BF95EEA0BEB6667B15CF4F23F5E0A4045
-:108210001F697B4861BBD2BA7CD9EFBAFBFA7339CC
-:10822000F8A7C2E384B11CB66E8A51DE87F5914F80
-:1082300030C564C8F9FAF71E6EFEDE4BF566C13E26
-:10824000221E74B27DC490FB0DB9BE2E56CBC91A46
-:10825000D6B9FE75B16D51F0BB898AF8EF25B76CC0
-:10826000D6CFE3365A3FFC2AC795E283F08F19F543
-:108270004666C97365F858EF16BD1EFB5FCA2D53DD
-:10828000EEBD8EE655FEB0C50D7BA18107E1F5661A
-:10829000010EC7D73A0B4077C3C74A7BD9917CC937
-:1082A000E723860A8E371AABF73B36CB624A93C276
-:1082B000891EA99FE345D21E1F35B498ED9624135D
-:1082C000CCEB2A6E65B2DE4FB9BDF8F7A3BB984F71
-:1082D000075D144AF9FBF86DCA26392F2FC7270E00
-:1082E0007FC0C9F6CEE3FA3964E081E86818CB0FA5
-:1082F0003A5F8B0DA19BB5A0079C87A00725986EC0
-:10830000CC74718B22E12BEE93F2F7BA589937E8CF
-:1083100082F43FF1BFA09B22C1F0EF4E0F34D6DBB9
-:108320009D1E4874B00874D0512F840E84D53FEC44
-:10833000DBFC42A52362872B848214ABF021CE178D
-:108340006724C3EB1EAB1FB178BDAD122F7DAC927D
-:10835000EEE8B4F18517707D2FE27D4B1E5C28BCE2
-:1083600054BF2445B07DAD1FC9553171DC4E204549
-:10837000588E0ABB13A5685F1223FB2FE92938FE2C
-:108380008EFAF35AE274E6361CFE5EC17205DA47D5
-:1083900017707B9F45B6F75A29ED9B21F598B69546
-:1083A000611CBF5C72779F2CD0C9C4B1663A39A2F8
-:1083B000D39591DE94EDD68D759E24F083D286FE02
-:1083C0007CDED43B8BAB77029FCF47B0FC59B2EA3F
-:1083D000C79386617E2FC47B80C23393B7B33FA817
-:1083E000B461F64F3E84BEB4D5C9DF2BB2B5F559A2
-:1083F00090FF15F7DC9DF4A174C6017B12B5D79AE6
-:10840000A69C7F95D2C9BEEDEF409E983C5DE5FAF3
-:108410009385B43F8B0639CE24DFE7D624EA6FD2AA
-:108420002885C3698E3A5DA9B7C10FA4E3F7A92CCB
-:1084300045977FE43D8192557DB2D273E13F21C9DA
-:10844000B80B39FD53A3FE186503E4A5BEE3E4FEB3
-:1084500033EAA31FF47B3A4BCA55BFD5E162E40966
-:10846000AE5CBF7C75D8D18C68A4B64036A5E9FD5A
-:10847000C7BE84754E4C17E3D703EE77AA6213CFBD
-:10848000B7AD84F94254961BF4AB9142CDFAE3D6D2
-:10849000FECC278F8E693B7A37E58F6E1E24ED8CDC
-:1084A000BA7D61BE4BB07C70748CE4776D9B239871
-:1084B000FE8FB85AA3E2A43D8EED0D653A497CB615
-:1084C000ACFE7EF8B9CB22ED47717ECC7F681AC72F
-:1084D0002794AD530361B807B0C66C6FA88AD4DE89
-:1084E000C67E08B51B84DA074033A0A3F2350AD351
-:1084F00061DF7A8F3D99F99CE2C2FACA2303FD70CD
-:108500000E947B9C1CC77C85FDE06B82FB70D8B908
-:10851000050789B5676B9F004E258D25ACEF46E4B6
-:108520006ACCBFFAAA0417EC179DFE26C25E0BBEEA
-:10853000646D4DC6BEFC55969BF13031CE9515C984
-:1085400074EDE4FB11476DAE2CCCEFE84AA705E7CC
-:10855000EDC41592BE69DF39708FE11EAB08073F8D
-:10856000D89A25FB9DB3DC5ABC91F2BD1DC21A15E9
-:1085700007FACA67FA5ED85FFB2DE675EA17620450
-:10858000E489B2356BE5BC74FA10D696C2781AE766
-:10859000D4E6B402D8013AE4DBFE63DB01C70EBACD
-:1085A00098AE303DD07A0EC18E9CDEBFF432CAE95F
-:1085B000FB3ED0CBC4B1817E881B2F52AB38BEB6F8
-:1085C0003D4978E0776C176D2C8FB4933C02BE6701
-:1085D000F019839F105D781D899DF8DE5247532264
-:1085E0001EBEB5CEC1E9B3752E6125786FAB4BE2E7
-:1085F000FC0B756E4E9BEA72F8FB8B751ECEEFA8D6
-:108600001BC1F997EBBC9CDF553781D357EB8AF937
-:10861000BBC1AF083ECC970CBE63F02783BE0C3EB7
-:10862000154A577309CCB81741ED991F1A7C10EB06
-:10863000B01474F22703CFE94AB12F09FC50B4CE2D
-:1086400006FF2852CF3DFF0AC1B9BD2292ED22EDAF
-:1086500042F2C1F648079F07A976B10BF689FADB0B
-:10866000BC47EF0E3A876FAD508435888E7FBCC40F
-:1086700029AC41743C6F59AC293F67D9FB6FF4A416
-:10868000FEDF8DD172B3691E477E79E2F13FD1F7EB
-:10869000DFFCF24C26F04EF3D8FC08C6BD2B5C9FE5
-:1086A00047AB9CD75D769697FA864B7DAB6FB8D477
-:1086B000B7F0E3088ACF3DA2E3A3242DF69DA7B12E
-:1086C0006FECAE9B47C04EB452DE4BFA04F8A3F2F7
-:1086D000BFE8F82B5D16C6702D6DD0F76B70DC36D9
-:1086E000C1F558B260F94EF10A01BFD7B15FD803A6
-:1086F000242B88638AC3AF407622E56B0EEC98ABDF
-:108700007FF711E47665D92196B3354724C77F08F2
-:108710009FED5C707FCAB2835C4FB4F636C56F467E
-:108720000CF5DAC13740E3C05F69CE7E81FD2E1AB9
-:1087300015BE7F54AE7F2F5FAD98E2A26764ABF2A7
-:10874000DE459695D3F359423F471AF9BC32E89675
-:10875000F808C7619637E6DB1704F1E752FD7B594D
-:108760008EC514A7797F969DFB398FCD49FDDE9B81
-:10877000936E9FCFFCCFCDF7058CFAA53905AB6082
-:108780004F2E5D83A8A6CEF625D9567D5E2EA97FF5
-:1087900039E85C8BE2F8A22ECF07439E39855F470C
-:1087A000F2FC59EFAA7CE1B917E08FACFC73189F7B
-:1087B00053958375FB4AAE7FF8349683BC91CA709B
-:1087C000C8E112FF85CFFD351A715DB53BA4BD9799
-:1087D000D2A3486BEEAA60FB5E8D87F6491CF8AD0C
-:1087E000D9EFFFFA0B7FE6FB9D84B0143D6E98E352
-:1087F000D46A767CCAF16BB0C7F986727F1C5F1DA4
-:10880000DABE56F99AF557422CC3A768CF97893C30
-:108810008F9D9712C1E76AF7AC4CEC2A8E28B41FE3
-:1088200023CEC1B0FFD58A359FC3CF597BD7849360
-:1088300092DE65FFA1ED1ECA8E4A38315020C6EE89
-:108840002AB6935805C79F2CD5ED38EDFE4CF6633C
-:10885000772777D7AEA7462492B55BDD3188B3BEC4
-:1088600028C484AEF0F449B6946BCFD33E823FFB6C
-:10887000E23695E5CA8BDBA2783FD46C7BF020E230
-:10888000046B9E52D8ED582D5A38CEAF66872A1CFD
-:10889000C1E71DEC47F1DDCF73F173514B405F8BA6
-:1088A0009A14EF669A4FBBC31DD323683EAF80BEB8
-:1088B00088341787350D47FFC6FC9F077F0B92371B
-:1088C00017353FC8F18D54EF02CB37BF8DE0383CF0
-:1088D0003AC9DEC13CCF6E18C2FEF5454DDB6B5880
-:1088E0003ED816E182E9E98CCD7C0FE4803EDE8142
-:1088F0006C298F9CD5EDD1675F50591FC23CB12FB9
-:10890000CFE871B846BB37F5766F664BF9A7265BA3
-:10891000EE4FA3FEA2A6A3D1FDA8FEC95DEF73FA98
-:10892000BEBE6F1645B6F03DCF933B22F89EE0C920
-:108930001DFF39FE351AEF7CD3980425689F9DC82A
-:10894000B6C97DBA41C62FF32517D6139A783D676D
-:10895000B7A528AC2F03DEA4B79FDDF112DF4336A5
-:10896000E4EB1F1C2F384BB186DCA3183D08728D39
-:10897000A355BFD7D1A6DB63FE6FFAAFD1BF27598E
-:108980008AF571E43D0D61C46FB864BD2235B72727
-:10899000F6DDDCC1EE99B8972DDE927197A2B7FB98
-:1089A00011E87F73DF8D67BBCB529BBB27F25F1C47
-:1089B000268595E0337788CE57925A87C1BE7B349F
-:1089C0004DCA15863FAD6AB522BC04BF5E44673E02
-:1089D000E4FDAAD06007C949677C3D5661F1DA71B0
-:1089E0003E46D9992EEAB73B37C1BE75C42E7CEC02
-:1089F0007F7BD129FD27E9D20FF218F617A5557113
-:108A000081AC78D8F174BAA99A4AE541F453B529F2
-:108A1000900539EA9C5DDA2B510EFDA9AA40D6AB30
-:108A2000D7E914FDA0DFA369AE0B2CF7EE8C12D0B2
-:108A30003F2CAF4449BBC8D3CE4D6141E776BF1C44
-:108A40008B1177C7FE4ADF66393FCC0BF2FC227BE5
-:108A50006316E45D63DC45D18D3CDE397DBC45E1C8
-:108A60008DD29FA3C711A23E8F6F13EC776A7B262E
-:108A70008CE5E633C92D2F63FC33CFF4E7B887A329
-:108A800069FE05BBB8DCC9F1E795CF860530DFD3B9
-:108A9000CF44B15DEBB44DCA63A7A312591E3B147A
-:108AA000F5F05CF6633D15A6C02E745A11F62494B9
-:108AB0006FEEC1F24065DD32F6D754127B811C4B5C
-:108AC000E904C87FA737F7677BD1E93755BE5C411A
-:108AD000DF57E3BB261AE7FE8CF58008B6239E79A4
-:108AE000F66FFD83FD3B465AF994D93E66D083511B
-:108AF0005E9423F960518ED4536EC871715A1DD1A2
-:108B0000F4703AAF53F207C203EB81B41F1361EF65
-:108B10003FD2B43B5189049C0359FF09B86F95FAC1
-:108B2000D6996D36F65355BE12E5653BD4DD57F147
-:108B30007DC94A55CAE3951679DF50F9E556B6FF67
-:108B4000D43FE32C003C08DEACDFB66D56F571E493
-:108B5000B8A7B7F4917E8D809E7F7910FB3526C62D
-:108B600089795359CEDA9007B85E7A2A82E3FE6992
-:108B70001C2FE2342A7FF67309CF9805AC27D0C1A9
-:108B8000CDFCB94AE7CFD5775F1383FB10E25D9543
-:108B9000EF795CB27A7A82FF86C2EBD11C9D3FBF2F
-:108BA000FC38F3832ADA37880F5BACFB13173FAB33
-:108BB000B05CB978D5358F30DF7DC726702FE25C89
-:108BC000D383D1C1F8A8CF91FCB0B3BD87EB2FA65A
-:108BD000FAB2FD5BD13C9F2D360FE6138AC7EFDD5D
-:108BE000FE59F507B5AF6C22F922EFCAF55F122DD9
-:108BF0003FFD33F8CB3627FB5109FF7C3FEAACAD94
-:108C00006901D67FF67927F39DB3B172DF9FA4F394
-:108C1000D4978DF9DCF46BB6CBFC619AC039B4D033
-:108C20006FEED798D7EA1C9BA4B7784F0CFC44D5BD
-:108C3000840FF447F8F911B77FD7C6ED43D7B34097
-:108C40006FD7B14F9F8F60BA39DB4BE2E5EC0BD9A0
-:108C50007C9E1D8D95F44EF34D85DE743656A6B878
-:108C600099047AA874497A383BA689ED026795ED94
-:108C70009C1EB5C97695CB747F3BD15F12E807B4D3
-:108C800009BBAA634D0BE419F0F9E1059C06704F8E
-:108C90003BD48E0E3AC5F9D7AAEF33E31D05F6EBA8
-:108CA000B09FA789EFC76BBA3C59B5ED4A7F25F055
-:108CB00054B54D617FDA7F19FDD0AC130C3F00D164
-:108CC000E5629FC2EF222C6EB86D11FBD396ACBD4E
-:108CD00015746FAC63B17E6FFCA8A2F27C8E3A690A
-:108CE000FFE45E399E01DFDFE7281DEF75B88CF3E6
-:108CF0008BF6F03B396E4947946DA4FEAA1A943561
-:108D00003C4E9AA1E7CAF5197022B0D861E73BAA98
-:108D1000DFD3EE6EFDC63CBB9BCF319DCF1F4D9385
-:108D2000F793DBDE96F7CC2F7D3D2426EE5BE44106
-:108D3000BE6160F487B863D020F5F322F81CF635E5
-:108D4000ECEB34CFAC0D66FF4ECE53E6FC806DE607
-:108D50007CEE0E733EAFD99CF7BC6ECEFF09E30EDE
-:108D6000EB8413F46FC43542FF460AFDDB1D26F584
-:108D70006FE4A17F2385FE8DEFD0BF9187FE8D3CF0
-:108D8000F46FE4A17F2385FE8DEFEEFE124E55BAFF
-:108D9000BD1478E0B8BADD4E233E81F7CBC5D98942
-:108DA000CC478555EAA51717E5B2FCD8616F9AE262
-:108DB000607B93118F9518AD85F7471C80D2B22A3E
-:108DC000398DDBB11DBAF6556987AE2A7046C2EE01
-:108DD000D1BAF2E42A883DA7A3B418D4BF686BDBEC
-:108DE00002F8562F3BC07EFFD6E5EE77AF93F863CF
-:108DF000FB8B115F5582730F7C9BF4251977EE7105
-:108E000004DB5343FD44624D501EF2D33A733ED40B
-:108E10002F04BEE635EDAB46C6C76F6C6DC9E0FBEF
-:108E20009F3EE3E0FB699FEAF63B31CBC1F298211C
-:108E3000CF23CE1B70597A9FB209E795A77F1CC339
-:108E4000B9FD50A6E97E61685A767908CBF31DF921
-:108E5000358A05E3944F5FBE8FF56ACDCBE7D2ED3F
-:108E6000FADCB2D75B4CF3EEEF0F37D1D1C0AD7166
-:108E7000217ECC5EA6FA8377A587F8310798CAA72A
-:108E8000AD1962BE8F5F7C8DA9BCAFBD236ECFA133
-:108E9000FBB9E4FC5CB2CEA5C8025E6F68BD54C5E8
-:108EA000F327F86FC5DB524E2DA773C61BAFBF2B40
-:108EB00052007F9D7732E057D1648B859DAD4C3F4A
-:108EC00087C432F3B95C61153E575C27DD55B88421
-:108ED0003796DA7F696D4C653AFAE547A92A8168C9
-:108EE000D180963CE8AF8BDE7C7238E8AA5ADD98D8
-:108EF000EAA2F23B14FF165C203F13B73D712495A4
-:108F000027A95A497FC273AA2D70FF1CF0D1ED1911
-:108F100002EFA47CBAE6A5688E1FD4E92FD5E60A35
-:108F2000071D6C6C54594F81FD4C8DEBA4938D8DB6
-:108F3000F1E1D06B2AC6283EC8C7065C0CFA08854A
-:108F400007C9EFEFBA69BD970EC9F7948C752E75F6
-:108F5000C9FAA241B637DE0730D67B5CD7472B373C
-:108F6000BE91753B7D3FD77F5F9E1B7EDCBA5DBCAB
-:108F7000EEC5966D5B92297DC7A1DD85752D7D7B44
-:108F80005CF4481AE7CB6D32AEFDB3754F3EE1237A
-:108F90007E7A77E39376E80F9556BF9DDFCD7966AD
-:108FA000A31DF10ED76FDDC8DF176C2D617B8071BB
-:108FB000CFEE941197ADC3A362ACB2C145EB3CDEDA
-:108FC0005FCA8515E1329EA6481DF54602D6B55505
-:108FD000C9C7BAA6176FB7E3FD8187F57AA1FBA6CB
-:108FE000FDF0B4A21EB07B35291CC7D4DD3E99111B
-:108FF000E8CFFB64DAE5344EA75F1EC87ADE8782CD
-:10900000B42F9C23B921FAF56155DAF59A55F94E3A
-:10901000983D90300DF2C25EF96E45359D43230AAE
-:10902000A0B70B7135A5C5A354139DD7164698F666
-:10903000C12C11B4AFA8BF9B452F537EFAC40C536B
-:10904000FD99D30786F89D0B3ACB997F5D6D7A8F9A
-:10905000A6FA2E9F5B61BBC758F3774AEF623ABB13
-:10906000D1D4BE5A4C35BD47B3E8A9F718CE4465F4
-:1090700076C4E154E8F758666947F5EFADFC9D16F4
-:1090800062DAAF7D333C7F92E7A58DFD09863D7D99
-:10909000167ECFE8EABC0CEF881745BC30EC1D9A71
-:1090A000591E69613D55483C54EBF6A8EA1C698F8E
-:1090B000AAF6B5D8118F4DF0B7A610486A1A15B6A2
-:1090C00037527D474A9CCCDF85EF3BCCF752D0DF4F
-:1090D00065941F524BB0BF42CB6B68DD38176A6096
-:1090E00047623BD884936C0733C6D1FB37E834F42E
-:1090F0007D80D0FE060C7033FFAEDCBAFD602F829F
-:10910000CFB4E2D87CC49D54354DB195E45E496F2F
-:1091100006FFBF546161BF7EFBE1034C6FED155646
-:109120008F8C4BFF76B8D478A5DD35940E17D0BA66
-:10913000E07F5EB043F1F815590FF0E905FA0C81B4
-:109140004F4A177033E0D501BF90727E3F6E28E220
-:1091500026E47B0A57C025149EFA380B34C17227C7
-:10916000CDCBCFF30AE9578C08DD8FB7DBD9FFB041
-:1091700041112EE5BBE131F5B2B4E3F4CD90EB6FD4
-:10918000DBA97820BFDF7CD9CADF3BE8A758C6D966
-:109190004F9F68DEAF1DF4542CF7CF8CCB89DCEEEB
-:1091A000DF4557DF454F86FF26347EDDB847E61999
-:1091B000A0DFB71A26867DF34FC4E11BF24177E7A3
-:1091C0004CC739E4D2F11099DEE5F9BC342A9DE3AD
-:1091D000CC35DDBE68F0694D6F678C5B42E5EE789B
-:1091E000D07B6F7E67715543466AF0FB37DA4A1BC6
-:1091F000DB815397C7735AE27425E27C29592EDF2D
-:109200006939764FCF44F8298EADB4254CA4AE8F82
-:10921000DD3934550C42BE88D34FD786CD0AB6CF40
-:109220001BE92D03E4F9619CEFE72D87A367613FFC
-:10923000AEDC198D90A1C52BDF1FEEA273BED9A2A3
-:109240002D1AC0FEE08D7CCE0BD7C63CD8E70C397A
-:10925000A37265514FC80355FF38F004E4016DB99E
-:109260002D1172EAE90F5481D01A3AE758BE38E559
-:1092700094F47D6A7304DFAB3CA5082FFC518BD4BA
-:109280007D792ED379DB7C33C68F70D2B8C330AEF4
-:109290007F4B12C6F5F8B230AEB63C33A62BBB8B73
-:1092A00091D6AE97F2DF16C3CEACDBA321F7230F26
-:1092B000B95F644BB91F79C8FD4821F7E37B0DFC0A
-:1092C0000EF01BD7B7E5436FF58D15394BF81C8EA3
-:1092D000CC815C7FBB12EE013FBA5DF1F4E478848F
-:1092E0000F62E5F91B8257231DDD46B25910DD5E82
-:1092F00077D92182E3EBC68858537E9C23D954BF8B
-:10930000C895662ABF3EA9BFA9FC0677BE297F5330
-:10931000CE4853FD499E31A6FC8F46DC60AA3FC56E
-:109320003BC5949F3661B6A9FE8CE21253F9CC5925
-:109330008B4CE5B3B5DB4CF95B2BEE34D5FFF192EA
-:10934000E5A672AF7059710E36431F23B8EF853E04
-:1093500046E9ED6F674606E375D4384B97EF0C3559
-:109360000D90FA5674AEF739D025EE09810EFBE860
-:10937000F780F6E29C1906BF654091FA704B32E81F
-:1093800026B45E68F9A888FD97F09465FFE76E9FA4
-:1093900061253E31EAAAFD4332287FFBC0E619561B
-:1093A000E22FA3AED9FF523AE57FF1DC37B27CF071
-:1093B000FE4B285772F7CBFC34C122C8AF06CE9BB8
-:1093C000E1A3758CBA2E7D8D47DA53BA8C53355292
-:1093D000C001719D8003D200D127D2FD449F485F18
-:1093E00027FA2CB7097190E813E921D24BF1FDF768
-:1093F000A497223D4C7A29D277482F45DA427A2920
-:10940000D23FD4CDE2F4833A8DDBFDB1AE82D38F6F
-:10941000EA96F0F74FEA9671FA973A1F7FFF648059
-:10942000617F08B09DC6F08BD5C01F097BDE2EDBA7
-:10943000B960BFB1E295E7ABE1C7AC5F225A23B098
-:109440004F5BADB1271C9DFEC9EEF9AD559C08924E
-:10945000CB9CE1DECF06F0F8BD5DCCB7F5EF47C49D
-:10946000B43E0584A74FD3B5B3E007330ACA56C646
-:1094700010FFB8EEEB2536D0CB8796AEEFA3EFD535
-:10948000F9DBA703BD6DE8F75AFD5DA66B1D32AE93
-:10949000F05A6B6B3DDBDBBF146EC403ED33ECEFB6
-:1094A000F758F95EB1F285E0FCE804C1F9FA2F5BE8
-:1094B000380EF15A972789CF1D3D6FC40575F8FD09
-:1094C000F11314EF63F8E18D789FC22F5AC7413E24
-:1094D000181D69778785C40DC0DFBE2FEA8FC6BC13
-:1094E000F87D27C3BFFFD4972280F7F20C3FFEB56B
-:1094F0008E9634D81546DFE1F004C73319FE7AE5BD
-:109500008B1615E78911AF648C63CC3BCA4AFD15F5
-:1095100074C6235DEB6ACA475C467D7524F7D79312
-:10952000BEE3DD49AAE755B95D533EECC7A3AB22C4
-:109530003D42E98C13E8A9AF9BEAF13A0BBFD03862
-:109540004E62B41E27817E1CB29CDF011C9D104818
-:10955000C6FB9FA397D83DB0833E8EB8B382CEB8EA
-:1095600005D48F08DAC79827FAEDF715CD17F2BCA6
-:10957000D7CBF09DE692F429DC7A5E3FAF85632C71
-:10958000DBBB543D5F1CE6FA6B04D1CFAD19DA901A
-:1095900081D4DF1F948CCC7CD617327A60DF4F09E0
-:1095A0007947B00BFA1931F0FF847EBC12EFBD058C
-:1095B000DBE142E9C8C08F414F06DEBBA32B830E1F
-:1095C00082E2D018EF1D71657A7FA1F4D61D9D1936
-:1095D000F475AD43D201F08CF82083AE942F9AF845
-:1095E0001EEBE82A079F7F065D85D2C5957425E9A5
-:1095F000B4FE270EEEEF4ABAEAA407C0E587D355BA
-:109600008B8AF3F89FA5A7796D623CEEFF975C7695
-:109610001F44DAAB9FB6177CA64C8C190F12132E81
-:109620007510EC62A1F532BAA9174A7FA1ED6EBCA4
-:10963000A25D466E70BB71FA5919DAAE12ED7A046A
-:10964000B71BC271116FE9F708DE721A712D9E996E
-:1096500090530EB96DF22D2FE18DCC27BA19A7F3D7
-:10966000F34362099FBF24EEFA404F853A698DCBE0
-:109670005DC8FA426164D7710537EAEDC77F5DDCEA
-:1096800080F98C4F30CBE337EAF2FCF5A291FB0F67
-:109690007D47E1C6DCEB59CE0F7D4761F3403DFECF
-:1096A000204DA481DF170A8F9C9FFE0E46A1BECFDE
-:1096B0005374BAC970AB62541CEE9B6A561C32AF2D
-:1096C000E31D8C3C8CEBE3FC0DC2CFE94D22C0FDC9
-:1096D0004CA20309F91F096193EF5FC8FBBA35AAD1
-:1096E000F6DF90578D7BBA4F3BB557B0CF0F444C48
-:1096F0009E83774AC60D19D70FEDF617BA59CEDB00
-:10970000EFC860B913FBD216D7C927DEA473BA5FBE
-:10971000A6BC378A14F746FBD179FA3B3AC791BF0A
-:109720003167B940BBF16E73BC93D1FE26D7386167
-:109730008DEFFE9CBC296F776FD8CDDE8ACD2E04CD
-:109740007EDF8ABDAA10EB7D2BB6A745A661764EBB
-:1097500007BDD2AF2BB9D8A0FBCEF1C6F378DDC1DF
-:10976000D9806B283C0D38FF00B81EEB0AAE7B0792
-:10977000089637AA23245FAD8E907CD580737558E8
-:10978000C77DDE9EC1F127550E09AFF9CBAE11564C
-:1097900012F5172C1BC9F99375C207B89FC69260C2
-:1097A000100FB1F709EB58CE1BEFDC9D7DF8BDE83B
-:1097B000249AE72A87F63F98DFB98240164984E267
-:1097C000E4867ABE8F7FFE05D5037DAA4A75AFF188
-:1097D000C0CEFA962AEF717D7D2015FE58F154D740
-:1097E000F1E8550E095F439F1CD2AF98F7ADB15F0A
-:1097F00085FEBE80215FF50E93F1DCC63DF7EEE4F9
-:10980000ADE1E192AFF50E93FCD8C0EB06BB7EEE66
-:10981000533FC3898FA6FC3A9CF5AB98586F4C2EEA
-:10982000EC8385C2A49F187695F604F97ECAB5220A
-:10983000EB9151942F3C64137E2A6F074340799239
-:10984000F4B3B61FBAA482EF174529FC3E86716FA8
-:10985000292CC922DC417CC2E90E37BD4B1B911378
-:1098600067CA47797A99EAC78C483795C77A0798C3
-:10987000CAE3271498F23D8AAF36D5EF396BAC298D
-:109880009FACDD68AA9F5231D59437F8588AFC24E2
-:10989000FA2CB9C5D4BEEFB25253FD345FA5A95C12
-:1098A000C53B9B3140ABB7252711CF81CA9F8CD5D3
-:1098B0004B43DEE3B508CBF0CE776BFE335ADECBFD
-:1098C0009910B980DFAFC96CFC99799EEA446B2C82
-:1098D000A5D7BBCD7CB128C99C1F17B94F81DF71BB
-:1098E0009CCBCC9F5396584DF91FE5EAFC344FE4CE
-:1098F000B1DDE3BBF0AF0D30E13F144E440FFC7E11
-:10990000683B9DEF3ECCEBCD327E0F077E93E0753A
-:10991000C06F120C07F84D82F3F09B04D787DF2449
-:10992000B81C7E93E0F22187CCF81FD662C6FF55A3
-:109930001F99F16FD06577781AD96AA60FA1299A75
-:10994000F22D78BAE694997E42F1731D895BB109D4
-:10995000C087E209B87F38BE5686E08BF0C3F73780
-:10996000DB7B47317E1ED7D7756D6020DF972E3A9F
-:10997000A40ABC6F63ACF371FDDC3F6DD51A73892B
-:10998000CFFCCE5D90043E769D907EDBF155164F68
-:1099900080BA7F20649CD929DA43A83F2BFE52AAC3
-:1099A0001D74D226DFCF7B0E7C79D895F1B23E12A2
-:1099B0004FF8BEF6CF54BE2775C4D2A8808FAF8EA5
-:1099C000D19E009F9997BB84D79B248AB72F405C78
-:1099D000D47F85A5223FB7AFBCC72D725BF9FE8946
-:1099E000C127E7A6C8B8A92DB9BA7FDD23E3A79E92
-:1099F000C995727794C7C571DE25B9F27E0DA98B22
-:109A0000A97307013E879DD980CF3A0BBFEBD98A56
-:109A10007BE4099DF7C8210F43FEECA3CB7FF51F24
-:109A20003B1C5847F67A613A7FFBFB1DA6F8E281A2
-:109A30005B5DA6FCA0A62453FDC1BBDCA6F2FC40E6
-:109A40008EA97CC8218F293FAC6584A9FE551F795A
-:109A50004DF991AD134CF5AF39556CCAA788B6478F
-:109A600001DFBE8AB4531CCD4D97FAB95B70DCE4BC
-:109A7000DCBB63E57D5FDD7E61C8FB46DCB9A6D358
-:109A800075A81ED1D72EE5E8FA6421F54687AE1FEA
-:109A90000AB33EA1E971E31DF7587CE6B871235E75
-:109AA000BC43EFD0F58A8E7B349DF1E2DEE078F1A5
-:109AB000B9615DBF1F7D5EC77BE8FCFBDAE57AEB31
-:109AC000EFB4F3BD1D635EA1F349C99674BBD9D150
-:109AD000F5BDAABFE54AFB466B66F125D0FD1336FE
-:109AE0004F2BFF6D842BC6F3B4225EB7FE1776CFE3
-:109AF0000AF7778F3777B05CCF1C8B65DE945C8E6E
-:109B00008B33FDDD84884192BEAD8375FB4AC878F6
-:109B1000736364DC9A88B1BB41BFDD8F27E1996430
-:109B2000170D7CFF4BBF67F1E3354DF7A1688EBD84
-:109B3000517F3FCE6F033D4C1C4BF2593EC9135B26
-:109B40007A3D144972CA13CBAC6C9F8A7BFE57379F
-:109B5000FBFA75DE9FE94BFA10E803B20EF4A80792
-:109B6000F25429B70C92EB2B52BFEEB8E7C07E1827
-:109B700021F4F34370BC4F17F4C67468ACE3DF758F
-:109B8000EFC1A0DB503819FAAFD0E33BFB19F3D299
-:109B9000E167EC07037EC6FD13F76DB6E24D917CDD
-:109BA0008F6502E2E50CFC6DC993F6C6053A3C50A0
-:109BB0000FFCA8BB7A456A6E0CECF7EDC21DE3EA18
-:109BC000820E3BEAFF9BE062C0BFBBFB6DDDF1870D
-:109BD00050BEF05DF7DDBAA3D37FF6DE5B109F9039
-:109BE000F14B3A5EFCFD2C1C17707794793F3F32A5
-:109BF00048F2899183F4FDE423FDD6CC2F04FC0FB9
-:109C0000F52B559D5FC8F3BC24AD98DFAFC6F98A2C
-:109C1000FB5BF3374AF94788E2C4AB87C28F6FE337
-:109C2000FBCBD77A05DB6D4A1B153FDEF92AF175B0
-:109C3000AD0FB39FCFCD7207BF3BC8264D6A5746C5
-:109C4000EDF6A55DF9CEFAC248F9EE60E8FBEA0B45
-:109C500075BD192F6A60DF86FABDEE19A4FBB13C11
-:109C6000C2C3F29C1ED750A1D7E9A037BF7C6F0EAC
-:109C70007A32F631A51C1F67C0CD0D3FD490CE3C83
-:109C8000C1373C07E77983B5CBF8C50EF81A7EAB30
-:109C90000EBFEC61BE27111A8F71CE7720BA2B3F11
-:109CA00098E11FEB6E1F74F8C7BEC3EFD61E69891B
-:109CB000C6DFF169DF26DF67E9F45BFD65B8CB221B
-:109CC000FD5331F03FB5EAFD898D795DDD0FD59605
-:109CD000EFE43894668BB67310ADEF2CF58F777B7D
-:109CE000EF89DC9F88771126EA76A92BD7ADCBCDFB
-:109CF000A314E98FF6A98CEFF609F25E3DF15181CC
-:109D00007D67C44F4C118104A4861F4A5B3D92E1DC
-:109D10006FF8A14A0223799E33EA17DAF0E468EB80
-:109D2000A3771585BB3BFD53AD7D645C54777EAA5C
-:109D30006997F3B9BFE997AFE17E3E189426E5B67F
-:109D400086FB6E039D0DD82A6C5867ABADEBBF4BFD
-:109D500051A8F3AB12E89A3D82E2AD962BBC2F9648
-:109D60002AC288BF623E6FE42F35EAF92299BF7D8F
-:109D7000A5CCB7EAEFA76DD1ED20582752AC077AF2
-:109D8000F936DD4E827520C53AF01D7C0D79F0352F
-:109D9000E4C1D790075F430ABE86EFA5A2381576C7
-:109DA0005BF8D30A83F607FC6985417213FC69C12D
-:109DB00079F8D382EBC39F165C0E7F5A7039FC6929
-:109DC000C179F8D382EBC39F169C873F2DB83EFC28
-:109DD00069C179F8D382EBC39F165C0E7F5A703944
-:109DE000FC69C179F8D382EBC39F165C3E6F996220
-:109DF000F2B7CDD3DF7F285B1FCFF45198511C9B66
-:109E000047F8FDEF887FFCC4960E3C372F02DD2E0D
-:109E1000AD0EF7483C374E9078B70889E7B6D98C35
-:109E2000E7BBEC325F24E3B443E9077EAB429BF42B
-:109E30005B2185DF0A29FC5648E1B72ACC947E2BAA
-:109E4000A4F05BE13BFC5648E1B7420ABF1552F86B
-:109E5000AD90C26F85147E2BB483DF0A29FC56F8BF
-:109E60000EBF1552F8ADF0FD08CD03FE2B635E90DA
-:109E7000F3FB99F452A243935EEA32E521E707D758
-:109E8000879C1F5C0E393FB81C727E701E727E70FC
-:109E90007DC8F9C1F94983DCBCBF20EF07B783BC9B
-:109EA0001F9C1FD4E87B03B6AB491B2EBC8EB43578
-:109EB0004A7942710931352F7326FC8BAD4E253519
-:109EC000D623846DF980998594D7F438C73CD16640
-:109ED00001BE39AE80F0A60504C7650FFA7FC95CE4
-:109EE0006EF8B3F987F09EBF43B0DE50A3DFAF3505
-:109EF000DA7B844B456AD4EFCC775D2F747CA31E4C
-:109F0000F3CBA0799062998F7893FCBB220B70AF52
-:109F1000608B4591F1B82B643C74285DADCA93E722
-:109F2000FB16CBF6FDE1885329513CB8EF9165153E
-:109F3000876C0580D392027EF72A2F565FD792ABAB
-:109F4000118765CCDBB04B129FE07B86A3DA84BD22
-:109F50009CC619FD85B0E3EF734CB44B7902EDA0BC
-:109F60006F0EF429DE4D41F4BD2C4F9E7B9AEFB667
-:109F7000ABCBE9FBC06D4BAEC6FDC589E1B2DDD30D
-:109F8000BF8966384E6E50F89ECEA86DC28BFBC955
-:109F9000CB757E3A709BCB5ECEE3BAF8DEA3D16F71
-:109FA000C98654BEA759225A0B710F450C55F83D6E
-:109FB0007C036EB4BED7B1BE2CDA2AB02FFFE0FB13
-:109FC0004F242E7E9FFB4FA387C61621AE5034CB65
-:109FD000F742270D2D59D983E6A5F9E57BA1A3BF4B
-:109FE00058F206E79F92EF8532F90CE7F9F179987C
-:109FF000ED53F8FD95C9BE8D960437EE652FB72554
-:10A00000A2FE36E1815805F508F78A8D75E58A16B6
-:10A010008B5301BD8803F141F4479C633AE825DF87
-:10A0200063E3F759A6585D36F01B43CE2971C9B1D9
-:10A030008BD451317CCF32444EB8D4D083E3627E8E
-:10A04000789C4E3BDFE75FBAD3C97285B65E61BECE
-:10A05000793E5FC6BB56DDF6E1704B7A679CCE99C0
-:10A0600034FF16BC037B267D7BF40885E588BD792B
-:10A0700004D7A30D2FF13DCD92956FF03D944B0D7C
-:10A080000F45CBFB6CD2FF52AEC3CDB03BCDD7F169
-:10A0900053AEC7691DAB93EF3AD339CCEFAE5C6AD0
-:10A0A000B0B19C112A2F1AF2A7F11E9110AE3FC237
-:10A0B000CE53D160E33BC00BD794AC4A1257CA9140
-:10A0C0008B75397351838DE3B22AF4F7D442FF6E56
-:10A0D000CF623D1E6BF156F3F74FF242E450E37D41
-:10A0E0004DBD4EC9DB0766B03CB4C4C6FECD39CB0E
-:10A0F000A57C24B60B3FEE93CC593ECE82F766E6A4
-:10A10000ECF47A942EE8E95D5D4E9AD8EA64F84F53
-:10A11000B91CC1FC65EAE514CEDF7C3999D3999767
-:10A1200065DC2AEE22816E5A8BE43B07EFEBF2D11D
-:10A130000CC4B1C6433EEBC9F4DD4EF48D21F2747C
-:10A14000BE35C0AB1C807838D1A6AD449CECC48D24
-:10A1500082EF834D821C45FDCF825C158FFD9156A9
-:10A16000C4F76126287CBF68D2D0DBF4FD40FB43F6
-:10A17000303FE1F757B4C2297EC439CDD2B65B80F7
-:10A180007F635F68BEA3FC5EEA249F62C73B929A2E
-:10A19000AE6F1B741FBA3FE646E876B2486907EB1C
-:10A1A000B09361B27824C9B76A26E4D3B9B06DF62A
-:10A1B000D20981601F952BCB7BFC76D5CC069241D2
-:10A1C000FF55FBC91C8B45DE3F233990EF0B88966A
-:10A1D000A29E942F59A314403F32E6F5B967EC389C
-:10A1E000CFB04E3A28EDD8A7F21EE5D27B324D7E95
-:10A1F0009BD0B48CE08DFD3437A6F5270A6168F456
-:10A2000060E12D1C81F7EB85F1285400F198B7E847
-:10A21000F9EAC13BFFB43A97E1C4F991BF7D68A662
-:10A220002FF25FE09373146BF0DF1B4BB268570D96
-:10A23000EEC1F750C703BF11B96DFC9E444AB64B3F
-:10A24000F2A9107B4BF56089C750BB4B59AE3C77E8
-:10A2500084D59D7A2BFB7BDC6CB734D67DCC66BE77
-:10A26000E76BA4F307EBE75EDDBFE79ECAC316F911
-:10A27000FEC26316FFF657885E2FF7D06660BD8F6B
-:10A2800021DE9EE7AFF1FA8CF74C3AF895FE6E8925
-:10A29000414F47965DE2FB2AA59176B71A444FE5F8
-:10A2A000AB15BE0F5ABA4CDEE7D6562BF25D846E64
-:10A2B000EC58BF99FDBFFC9ED56F7E112E0B75F833
-:10A2C000CEB1B7BCE148EB84EF9F973D60937C34FF
-:10A2D0009089FB0EB72C71F2BBD99F7B8AAB060F1E
-:10A2E000039E3C8CA771D8E5547F4B8CB604DF4BA2
-:10A2F00045CB41D81DE7FEFC6D7E8FBAB6398DDFA8
-:10A30000BF2CD995BF0AEFD97CEED17E82F5974458
-:10A31000BAEC90476A1A62F97C9EDB53BFCF2BDA06
-:10A32000D8CF67E0E7BEC1D28E777DBE1CE7A2AE74
-:10A330005711C06C534CF5BAB6631AF6D1503B4B6B
-:10A34000E8BB21DF655781DDC41E645F35EC32B6A2
-:10A350009C63B371AECFB177FDF73EF7EAF337F404
-:10A36000DAF91D7A6DEEF89E90FFD72A2ED8D3CB5E
-:10A3700023DD3371BFA1FC900D91B462629C5BBE82
-:10A380001F738F7C3FA6F48E7CE66773809302DC9C
-:10A390003B19C9FBB8DC4FE990EEF7FBAD6B0FF44E
-:10A3A000D90D7A0A78F91D827297D71E17241F9546
-:10A3B000352AA677248CFC0B8355C99748DD00FC11
-:10A3C0007E7C479A1D6F39CD213109F1997B412758
-:10A3D000C33ADB513D8E3F99982E0ECAF7BD14FE4D
-:10A3E000BBE4182FF8EF5B95369ADFC3A0FA2CDF99
-:10A3F000ED1A1CC5FD95B868DD69485D3C4F8203C8
-:10A40000C3A9ED3EEACFCDE3303ECA027E1BEC0786
-:10A410007310F742F95B5C7E1BC6296D90EFD46820
-:10A420006BE438DAEA58FB20C8075697BD4FB05C9A
-:10A43000D820DFBD9EA3FFDD119A2FCBCDE50427E9
-:10A44000DCB333EEDD86C2AB449F7F7963AC59CE7B
-:10A450006C5C6B037E6677F35EC639DD0E5DDA30C9
-:10A4600086DF3728B77AF9BE8AA6C3FBB3DB9CF731
-:10A47000C25F327BDD23B634CAFF65B0946BCFE98F
-:10A48000FB71627A2093DFA9BACDC9F1E3B35D8D88
-:10A49000BCDE0E783F44F081DCE22A6678139DF83A
-:10A4A000106F59BECE8CDFCEF944C977FCD795F03A
-:10A4B000FE5B60D5ECAEE079ACDF9789F8A1D9B44A
-:10A4C000EFF10E9770697C1FF6C44333F9EF056214
-:10A4D0009E1CCFE6718FC7BB5344374CD706FD187F
-:10A4E000F7F38DF1AC1EABB4C77BBE6B9F7A0F4206
-:10A4F0004EAF277CC30FD0DD3EB5E302268D6B2F18
-:10A5000097EF075EC1EFF4FDFAFF016A916CD3008B
-:10A51000800000001F8B08000000000000FFED7DA0
-:10A520007B5C5565BAF0BBD6DA57D8C0668BB051A4
-:10A53000C00D0262116D10101575A1805B736A6306
-:10A540003729C48DB7500191ACA89FF3B10D6FA905
-:10A5500095262A9675B6A68D957570B2461B9BD921
-:10A560006A9A5D0F3A8DD33953B6CD32BB09D234D6
-:10A570009F7DD399BEE779DEB560AF0DA475A6F9CE
-:10A58000CEEFFC3EFCE3F57DD77B7DEECFF35E7630
-:10A5900022634CB23136789883B1818C1918934577
-:10A5A000C83FA177FBED02639571ACBE2D13D22895
-:10A5B00056FF6B0B63DFE3DFF89E74A253642C8FAE
-:10A5C000B1DBA05D1B7CAF10D9ABCCD6F33DD3295A
-:10A5D000D0F78A1436D31DD41EFBC37EE3D5EF1308
-:10A5E000FC698B337BEAABE356D878BBA9D07E9A63
-:10A5F00005EB8BDDF51BA83ECFB3E92691C53236BE
-:10A60000DB04FF87A594487B56C4E632D6B057706A
-:10A610001AA1A8E14189B118489F8BF0B164C6BE68
-:10A6200068F8CD3BB740BDCF376FAF64437BE635AD
-:10A63000C73F8A39463036F75236730C606CDEA558
-:10A640003194560FF364380706D5DBF85CBA07C6B9
-:10A65000BFAD2DFBDC7F305AB79FE530F6FE73BFF0
-:10A66000FDE368E897319FDE7D4DCF3A66AD3EA1B0
-:10A67000AFB204C38DAF734D4657158379CEB6186C
-:10A680001C1214CD5E5EC5649827B333671AE413B9
-:10A6900075CC2B42BF6CFD16D904EBF330FE57B5D9
-:10A6A0005C90A95D63BE4F82F50C867AC61C5EDFA6
-:10A6B0000CF0F7580C678448A8E82D910319BCCD1D
-:10A6C000F7293DF81D0CA921A707EF890A1DCC5ECB
-:10A6D00057066D7BF0050333960FEB651CAEEAFC65
-:10A6E000A72AF3BF6DBD20FBA0DE0D4E07CF572775
-:10A6F0001BE6C17AE7AC4F36CC86B45CF95E3E47C8
-:10A700005BDE8D2FAB8AAFCC9576584F571BC75762
-:10A71000D73A3DE1AB6B4F2F7C2531A9671E7700FF
-:10A72000BED8008E2F3682E30B53C057A5332FA817
-:10A73000DEBF707CCD7EFEED0F5E76D0FAA8FFCE38
-:10A74000078DBE1DD0FFACB6BD84B7F2D51BF4C9D2
-:10A7500050AFCE994C7051DBCFAECFB63280E76DA3
-:10A76000ABB7EB1D16FCEEE893EE219559103F4177
-:10A770009E099067BA40BC3BA2A77E39A47B619C2E
-:10A78000258BCD91ECDA9E71B628F43CBB3EDA867F
-:10A79000E3CDAEAF7A886571FA7767F6E6BFB36648
-:10A7A000CE17B3A03FE4CFB345CE24E48B0A51D4F7
-:10A7B000F09B9A3E847883793D06E03523FEC3DB27
-:10A7C0009E46380C5E14E66C864FA9A9011F8E8B3D
-:10A7D000F48CF33688CC6B827AA935818B388F5410
-:10A7E000A0286C8769848D52160BF91D30ED024844
-:10A7F00053249EEE73F2F5C3773F7E6731813C5C54
-:10A80000BF4ACFA1F46A603B57A700FE0D31CCD9F7
-:10A81000ECE8A14FB51F953E55FAED6F7D7BAE700C
-:10A820007D6793393C598633C904E3563E3CCCB925
-:10A8300046B8FC3A0D61000F5BD07A81580B6C7DF5
-:10A84000AC3735905776CD0FADB7A524B68FF586CA
-:10A85000AE53E5933926CEC3C02751019877D7FA76
-:10A86000A1510CF12D302FCA9DB38BCD22CE5B5D53
-:10A87000D7534D5019E6B6BBC944E9334DC068C340
-:10A88000003E4D76CA3FDFE4A0B4AD2983CADB9D0C
-:10A89000369A3F6381886980A78A3085FFFD3C8FA7
-:10A8A000E56541E5536D9CEE4E5B0311B62039FD25
-:10A8B00071BD790D8B42FA0E3C88FCCC1A87B25DD3
-:10A8C00030D4E9F56723C44CA44F3E3FB5DD127D7B
-:10A8D00027C93F166170EC02969BB124FB7423E0FC
-:10A8E0006BEEF2382790129BD13894E4C20C6FB40F
-:10A8F0009300B07E0B4378CC53E460F892AA952382
-:10A90000B17E6BB2558071E65A9CE75AA9FDD5CE4F
-:10A91000FBF17B4B99212593AACA26906377287275
-:10A920006C89C0DCC88777A09C44FE120FA5A2FEEC
-:10A93000B9A355F01B29CF560B00D721CDEED27805
-:10A9400094135B05E70E6CBB0DE4A9A9479E760D39
-:10A95000737F817A817D07F407FD5F252002715D99
-:10A960006D721CCAF14D827517C379B90D089F0528
-:10A970000A9D9C6E3913E1C8EC81EBA3F85F10656A
-:10A98000CC238B286F1B143D86644079454E0E31D5
-:10A9900070F841CADA113F3AA709E9A0CB9212C573
-:10A9A000FA286F884889C3F239AD12C945959EAA25
-:10A9B000D535287C3317BEA3DE2B912A6291BE5673
-:10A9C000B64CA474CE8692CD5EA0E324C11D3B9A02
-:10A9D000D6A367B89E39B513AF47BC55EF30469B39
-:10A9E000006F497A6F524E103FCED9BE2A8941BBC3
-:10A9F000F3DBCDD351FE175BCB8AA3A1FDBC6DD198
-:10AA0000D952901E49CAE67A6441EDC43806F0ACCA
-:10AA1000F9FB9127ACA08FE7429F56E8FF9BB670E9
-:10AA20009F17AAD434ED4F9280E7DE3179E2B3A1CB
-:10AA3000FE42F1E02DA3501F08BEA7E2A9BE23CE1F
-:10AA4000DA873C50D373C00F0EA0F7DAFFF51EF57E
-:10AA5000F395F8D6F5E5D0BEA6F68548EC67E1A6F5
-:10AA60003FE45BA1FCA0E849C3FE3F17B63F654544
-:10AA7000026CDD9E857A7CEEA6B4284F1FF217F992
-:10AA800000F151BD5F20F8AAE5337C510684BBC7B5
-:10AA9000CF0C564CADCC80F47E5E628D680FA8F66C
-:10AAA0008C5A3E329BCBADF351EB93904EE63FB5C3
-:10AAB0002509F5CC67113C5FF1D4AD6FA0DCF2EC59
-:10AAC000341A10AF1E1D3338519F7941BF221D55D6
-:10AAD00003FFC693DD61AE047A2ACA0E27B8CE6F93
-:10AAE0001D41FA519D177CA7F2CF74CC85F318D283
-:10AAF000DC998D74FF679D7F2EE2F3CFF566A71773
-:10AB0000F199CDF5DB9FD74BA558EE0586417BE447
-:10AB1000CFEB5F8848B5F4D86F25D2FBB28476D6E8
-:10AB20008B4236EAEDF0CC76C32CB21B18D1599D7E
-:10AB300095D359C3017DE9E018B2C7A8A446E73709
-:10AB4000F485AF058ABDD59DDFB7D7807C52B3872A
-:10AB5000DB11356D67C88E50ED925A859F17EE391F
-:10AB6000437685DAAE6E1F874BED3E5E5E9501C87B
-:10AB70001DCDE5800042BA0AF105F9FBFEF5D7D3F9
-:10AB80009769F27B297FDFB5562E0F759D49A8B7CF
-:10AB9000D6649C3420FE6B972BFD425E1F34DEBCD6
-:10ABA000EC81042F2C1F6AC1F60E8DFD50BB2F9A2D
-:10ABB000DAFB6BC356A3BE97EB2C3A4C9B6B2DA4D0
-:10ABC000FFB7D58B19BA5C9C5C9813EDB983619182
-:10ABD000592847072E3C650648026A3B8F8850BEBD
-:10ABE0003ACA732FD2671C03AE90506FF805B45F5A
-:10ABF0003B5EF97404F63F6E48E06B0653D70BBF1B
-:10AC00009B5E0CF26419982D641F670646201D0F89
-:10AC10003CCCE5F4E37AB61AF51BD3B9D93428F75E
-:10AC2000A3DC423C7F1BE6DB05FFFF1DF30FC6FEE6
-:10AC300099C93F14DBBDA4D0A7DB68592DC0BCAEB9
-:10AC40001EEA59834BBE41D05F932D220EA434AC33
-:10AC5000D7A1E7DF557B758222A713C18E40BBC801
-:10AC600030C86E413A6E36F3F509B2CC1A611EF760
-:10AC7000671E9E8D7A7A6DA78919619D133AC3C8A4
-:10AC80007E4D1CE422BDD66C4E22BD2D3874AC0224
-:10AC9000EA1FCE14FD3AACCF4C3EACCF4C2176AE81
-:10ACA0006896B19D70F0B56F51BE0F962E1E8982C9
-:10ACB000F50DBE477036439DCAAE738FFF1BA415BA
-:10ACC0009776ECFD5748FF2DCAB313E17ABACB75DE
-:10ACD000C603A85B6B6D3339B9DE60C1EB3878EF22
-:10ACE000B79136B1677E1D9DE79EFB4D2EA62627A8
-:10ACF000EA9F090725D21FA1F3E9B0C3C487523DDB
-:10AD0000B23B3B2CA24F10B0FE91F7707E134C1655
-:10AD1000BF84F6BA49FF65B07E618EC4E87357936D
-:10AD20004A61DF8391108B93477D74D14276EB3873
-:10AD3000850F553A7B2B9BDB8F6F297255853373BB
-:10AD4000C82C58AFA8F06CD6ABFA2210CE327BF8E4
-:10AD5000769152AFEB9228931D5E6DF431E8B2EB21
-:10AD6000E050D233FDC9D93FA0DD01F6C4F254F959
-:10AD70005D842753F4EECD0AFC54FD2D29FDDFAC94
-:10AD8000C0F1668BC8E1765308DC147A0AA5971ED9
-:10AD90007A8841DBA31BCFECBEF6A351C984DF6BDD
-:10ADA0001EE678FD90F0FAED5B2B80CDD8A0BF4D6C
-:10ADB00021FCFE0C78F58BB93F02AFEDA178F59B35
-:10ADC00087215E37896467A01D8876A307E5C0B533
-:10ADD00094E7F66006233951298539D724E3778033
-:10ADE0004316C987A3281F54B930C415B806F5E91E
-:10ADF0006970E5717E01B18D97E7A4105D24B0F60E
-:10AE0000782C07BCE7A17D279986667E0C72B7E592
-:10AE100001DFDEDF403FCD826FEB3C988FF7668B22
-:10AE200013EDB70E9FE8D5C33C5AA259D67E18BF82
-:10AE300065FE554E2F9633456E4C37F8D07E83EF26
-:10AE4000498DF8BD9C7F7FE9EF671F44FBAC338DD4
-:10AE5000D1BA5AB2593ADA672D6519F4FDB7AADCAE
-:10AE6000793082B72FE3F4DD32DFE6433DF4E8A327
-:10AE7000BEE1A8275AB6CBF136480D519EF81C9872
-:10AE8000FF2089D37D4B329443BA597097CFC57E4A
-:10AE9000AEE1F30D94873DFF1474654E05D106E5D0
-:10AEA000A71B2376A05C55E974F0302EDF8778CF9E
-:10AEB0006C45387927B08C7AE8FF4385DE54F80B6F
-:10AEC000C0368D00F798103CA87417A3C05F58CA0D
-:10AED000E9CF3B41594F1DF3A1BF910053090738FA
-:10AEE000571AC1F0837496D5938DF36F5E0CF89169
-:10AEF000701D1C0FA74556DDD6075F15E628F10D1E
-:10AF00001802F9A69271BEA944BA427A6C04BA0A30
-:10AF1000A2471648883E17AED015CA8308F7B81C5A
-:10AF200058E757C21FF2B1F0ADFF94A6F735CEA493
-:10AF30001C2E2F1E337B4A7348EF4DD0D89D6F6572
-:10AF40007F9A88FAE5F4BDAF25609A14E59E8CEBF4
-:10AF5000D85CFED75214FF1FC607F4B88E0FCBFF84
-:10AF60004F22DA2D954B5F23FABFD2799699983705
-:10AF70001CE01E5D2C38FD00BF792D46E724F81635
-:10AF8000575C750CE159D66A74189156D8628D1CBD
-:10AF90003B2B8F40378A1DDA6A24BA39F74B89F484
-:10AFA000C1B9928BAF0E800FE756084EAC57D63220
-:10AFB0006C2590372B2916A85E9957A07A65A91C95
-:10AFC0005F271A05A23740AF253B28DE31A7F58E53
-:10AFD000A988DF13C55F0FA4F8C17A1847E5632E6F
-:10AFE000DE489E9529F5AB561B9147BBBF97B5AC84
-:10AFF000BA88FC3FD31B52DE3AE953ECB7AC515B45
-:10B00000EEC635821D77574E440CCA07E664CEEF74
-:10B010001148F240F20FFA93BB407144CF300FC297
-:10B02000C389BC617AA4EB990857A0DBE8A57CDD55
-:10B0300033A70ABE49B0CE9916CE671F9609BEFB4C
-:10B04000053EFF0940EF65501E0B745D16C3E438E2
-:10B0500048DD26E60FC7792E1DF609CADBD338D4A2
-:10B0600028AAEF8FB4A15CF7E81189B7322FA5E5C4
-:10B07000CC47E9EDCC4FF398C13A937490AF93FC71
-:10B080002B318EF32BB36703D2D75F8B4E9C16E028
-:10B09000FBDD3942DE2894438D0368DD975B1F702A
-:10B0A000A5807606AA41AC5F96E37E14FBB3CA4C3A
-:10B0B0008F71AB74958E5A993715D617BBDEE29B0C
-:10B0C00004EB8B6BF51CC2F5A64F373810EF8313DA
-:10B0D000F83A1374DC9F3F546E60A3810E363F181C
-:10B0E000E6433ADBBC3520DAA1FEE6038001CC97CB
-:10B0F000AF14BCF0DDEA614E8CD359751E11EDFE24
-:10B10000A2568F1808E2A7E1B241443991BED32379
-:10B11000A29EB45AD7533D355FACD44F3779065908
-:10B12000C94E9E4EF4335CA11FB59FD456835F0475
-:10B13000B817C94A7D99B757FB618A9E56DB6139BA
-:10B14000D2677AABA34F3F454D5B503F838FF808E2
-:10B15000C605D27BCA1F71FDDA84F01B78F3AB36CB
-:10B160004C370321F8711C9DC74CE379F83CD3158B
-:10B17000DA87BFBF7F8FE3631EF0BBB9F5FE22E421
-:10B18000A3CD001FC4F3E69DB3CCD4CFF4599A7974
-:10B1900031A986F22508074BEF753CA2CC2F3DD58F
-:10B1A000235A69BDCE4368E7A5CB8CE2016A3F769E
-:10B1B0001D7405F46A777A857ACCCB905A94B84797
-:10B1C0003A8EB34E40FF315DC157496BFD6133F696
-:10B1D000E366145F4CCF85FEA1FE268483A137FC75
-:10B1E00042E7995ECCE77342A9DF8EF194746CE775
-:10B1F00058114374C5E7D7D5EA14621C97B18FA0E4
-:10B20000FDC9907E9EC2B80CA4CF4E7E6D4A2EB46E
-:10B210007FFED19776B4D0520E3EB30FE556ABF514
-:10B22000E69B709C83229FFF4D72E25D98DF6D204C
-:10B230003D9ABE534EDB44799313FDEBAE56DF557A
-:10B240002F42BD2C18C664EB3D8F130A9CDA153AC9
-:10B25000383979CB205CEF5345772C5802ED875F66
-:10B26000F7388D3B7CCAFC9416C80F9BF8CBAB30EB
-:10B270007F5F8EC73C02E4FEB0D25FDEB60FE56AA8
-:10B28000E9FC1C8297C57645F2A939DAE3F502BFDD
-:10B290003747DC528EFCB8D26670482477EB19FA37
-:10B2A00059CD1177DBB1BFE5D1F9264C0DD6BF36AC
-:10B2B000A19C3C6EC931211E9A2D131896EBAC0A45
-:10B2C0009EBE1B4FFA40528872778473BA4C74E565
-:10B2D0006428270C0906ADBCD671792FD91D3EB460
-:10B2E0009FBAACF54881CC600954A07C935479692D
-:10B2F000717A713CC9E2B4A3BFB44291372C86AFD6
-:10B30000D36039F79F38AF5EFD632E96504B7F8632
-:10B31000B0CC2841F93FDA9BC6103E575383C5BBDA
-:10B3200018F544687F5D2070508EA34F4776337EBA
-:10B3300048EEDD5EB21B347AA45B5E7AA2F521F2A0
-:10B34000521E817AA2582079E961EB0CB8FE120CEA
-:10B35000B2005C3CDBB85E54F97B26CE05F0E549D3
-:10B3600065915C5EE9E473260EC6EFD1AE5C2A45BA
-:10B37000221E025EC9E0E9C39FF778937F501E9DAD
-:10B3800041FA87A90790FE21FD44E10F8F8A076FDC
-:10B39000D9F5A3505FCB12D90395CB8536B4CFE254
-:10B3A000BCD14769BEC5DC2E6897BFA6F51C2A89AB
-:10B3B0004B44797962D999C7EF41BDBE299CF4FF0E
-:10B3C000A4A56756603C6EA657701A21EF591A7DE6
-:10B3D000F77B986F343A5D903FABF081FB974591D6
-:10B3E000684F08B8CE8C9E75561632839BE239F1B1
-:10B3F0003396403B4FA3E0343B7AE0A1C77A52EF4B
-:10B40000F505BC3746FED0FA3FBCD7A8C859773EF1
-:10B41000CAD9A2C6E4870A705DEBF57C9E8DD1D7B0
-:10B4200053DE27393976B91C9EA9D83F9EA5B3575C
-:10B43000C6C3F7C06A41F9CEF156A9C8E540E38812
-:10B4400063183F0D2C17483E79BC52A21FDACD5C21
-:10B450009E4D78EF280A905DD8E53DB4925A2B7244
-:10B46000DEA37436178C58946FA7DFE3FE9F47FE68
-:10B470006325B69BD3A2B5832602FD0C40B8BC67FA
-:10B4800026FDE9F196D1BAEFF04569EA55AD8ED3C4
-:10B49000E43DAB8BAEC7B0E7AC7B27523CAF9239F3
-:10B4A0002291DE2A656E37C19F251BE633579D4FDB
-:10B4B00031B7C72A8BC17EA2EF5A7BB0C7FE893352
-:10B4C00020DFA87854F1133AEF5E7619E376D0AC1A
-:10B4D00075DA7ADD761030168ABACAE5DA76BF32C6
-:10B4E000BB9F45B9E8DE38E01BF2ABAE501E828050
-:10B4F000217F6E26E3711FA6E843D5CE2F597A51DE
-:10B500008F726866E3453DC273E6D21FE6A75F38D7
-:10B51000B5F3BEA1204ABB3E394E93BFD13544534B
-:10B52000FF66F730CDF75BA75FABF95EEE19A9C9EF
-:10B53000DF5E3D5E537F46FD24AD1C7A379AD6A36D
-:10B54000E2A7BF79BFA5E8A37742EC12359D3AE2A6
-:10B550003F1391BF3F2C67E4BF7C7833D3F8311D94
-:10B56000232482E7805C3DF931F7E5C8EF8F20BFE7
-:10B57000C94FF4A1C2F34373A1C928A27F62E47E3C
-:10B5800079A85F729039505ECED4B1FD42548FFFDE
-:10B59000670EF39CC7FEBAE30D4B0FF17843881F8B
-:10B5A00073A578FF7006CCBF0F79794D2EF7C316BF
-:10B5B000EE36AFFF38088EB56DD19AFCA2FDF1EBE7
-:10B5C0003F0ED63B4B041DAEB346E1935A16A07D09
-:10B5D00052BBE8A0FEEAC4402CE63B58676CB4F4CA
-:10B5E0008F838B0A0F808F253728DEA9FAC33F1976
-:10B5F0003E450A9ECBB4701A93CBE3905F8F10291F
-:10B60000DD9C23C7E7FE03F11CB49EF4DCBC7FDCA9
-:10B610007A2247C859089F9F1BAFDFE31E0F94177C
-:10B620008E900B7F26B84CFE47C2A547CF472FD838
-:10B630000DFAA3729D81FBFDDE335CBF3772FDFE08
-:10B640007CB48FF6879BF344E70E07ED97D23EE973
-:10B65000A17B8D611918DF59A1237D797A99908199
-:10B66000FEC226218CFC360FAB4816C8BEB978C87E
-:10B6700048FD31AA07EDFD3A90F351053E6B09E410
-:10B68000DFCCE571B1356E714A8A03F5F61FAC1E49
-:10B690008A8B7AE2111E9EFD30E16B69DF45EE2B4D
-:10B6A0007E12D06BE5D112858F5FCCD5D13A1F2E9B
-:10B6B00014B99D942ABA701F6315D8A968570696C5
-:10B6C000EB285F91C7E9596DF71F0A9DC794DD14F8
-:10B6D00086F388DA24BA7D7D8CFB512E8F0F3D795D
-:10B6E0005718EDB3012A7468EFDBBDD6692E58AF49
-:10B6F000BDD0968DB6DFDADC68EA6F4D469715CF80
-:10B70000A1FC8C7478CA8EFEA0C0FA8C33CD55E6AD
-:10B71000ABEE0F5894FE36E941BFA29D2298281E39
-:10B7200061F11AF9F91567B126DECA1C020B6EA782
-:10B73000D6F328F46AC7421BE197F6EFD578B15DDE
-:10B74000A117A41BC4BB4ACFA1FD8389EC8DCCE912
-:10B7500089F3D915528E1AE5D98D748FFDEA901FA1
-:10B76000BC5CFE076EBEC4E32CDED7DEC37988E185
-:10B770005F529C0CEC4ACE5F4B43E2BE3F914F02BE
-:10B78000660ECF4084561EDEABD0C9DA7F82DE481B
-:10B79000BA02BC3E9CCBE58FABC0FD36CA3BC7B2FC
-:10B7A000D430A2FB1F0B2796604538515EBA723821
-:10B7B00079F33D1F109E74CC6FB4717F0BF9E17269
-:10B7C0007CA4C23149649EBEF4F2883CE5FB1BCAEE
-:10B7D0007EAEB76AC80FD9612877C502C6D22CCC15
-:10B7E00061BCB6FF7A0E9C8F85E86A39D2E5AE96C9
-:10B7F0009430E4CF6465BCCA9BD2A70C77A05F20CD
-:10B8000018D00E04BFC3C0E33FDC4E57E57A4FB9F2
-:10B81000D67EC4724F668F1FA6DAF7EA773C97820E
-:10B82000E3AAF359A5D861FDCD7755124B72A2DC7E
-:10B830005A768F80F0DCB15AD4F87D715E612503B1
-:10B840003F3ECE7FAF13FD8E38B0AFCD28CF75F51C
-:10B850008233085E817B810A381387F82BE04FE240
-:10B860003ABD67895E42C757D7B1AB858F1BE75D8D
-:10B870002CC8909F54512FA0DFB756997F5C05A329
-:10B88000EF69993E01E3219E16568AE3555633032C
-:10B89000C6F52A33995386F2CAC64374DEEDB9025F
-:10B8A00039256F20C94F3A4FE32AF0A4E7011D4D17
-:10B8B0004D28437667B84B86F1897F161DA7B54C96
-:10B8C000F0A2EF59D4E23C84FE01D011C57D3C2D9D
-:10B8D000011A5FE7E571725D8BC1E98075488D657E
-:10B8E000B4FF21551B9C32D43BB629DF8FF1952D37
-:10B8F0008DDCDF0DF59374D6FAD7C3D15FAB109909
-:10B9000044010A792AFA5956852E5630773BEEF7CC
-:10B910003319FE41BB48A5DC5A3D6F2A6622E5D0AB
-:10B920007883DC139F409E6BDC40B2D394AA8D6772
-:10B93000482D2BC9AF33627DA8AC0F897748D5A5B8
-:10B94000141797ACDAF25BF32262088E593C1E9E04
-:10B9500073EF888DB7C27C727F79E31F303D8741DA
-:10B9600033805BFEB23B074C87FF16ACD87823A62A
-:10B970004FBCCEE89CC18FE057668CFAF1FCFAE828
-:10B9800095F2ABB2260FD0B9C2AF7DD2BF1A4F0924
-:10B99000E54F95FE43F94E4DD75E867FD7260512BB
-:10B9A000910F4FDF3B3203DB5736DE73C8C7885F2A
-:10B9B0000507D077A577711123BA605697D05B5EE3
-:10B9C00084370B49ECBF371F3F867C3BFEEFE71304
-:10B9D0007F08DF95098CCE6381FD49F69C9AAADF2A
-:10B9E00023F2B93EBD906724BC4E46C10AAC3B056C
-:10B9F000DAE0BEC778604E2BA47F2EF03C8BE34D7F
-:10BA0000813C9EEF7BFD406B0CAE374BC7F58EA79C
-:10BA1000DB8EE67648B7FFA8D80F59063605EDDC71
-:10BA2000C02611776E59E0C0E73BD6E2BE6BB9C9BC
-:10BA30009906EBCABADF48F484048AF6519668A7DF
-:10BA4000B8E5AEB68FCB699FB1D1C0D2286EE00EFB
-:10BA5000C3736400CFB0AA4CB257C3AC68AF7A8549
-:10BA6000A4AA881E7B08F5220AB42CEFAD53AC3093
-:10BA7000FEAE42B047337BEC1CD5FE599C9F4CEB8D
-:10BA800057ED2068C7B0DD8FE5A74A0B4B22BB19E5
-:10BA9000E683FBF7B64C2690ED1352FFF43223D920
-:10BAA000AF76AF7BCA70B45B97A7E6A0DD0AE39AD6
-:10BAB000246E7FFD3BCA67BB4EF95E28E6E0B949BC
-:10BAC000751F800574D1188753EDAAFEE7A563E7BB
-:10BAD00054B905957F9B2F9FC17EFF5972DD635539
-:10BAE000E84D4D63F879E0E90ABD8DCF37539A9E52
-:10BAF000FFB3DB73A7AE93FE79EBFE39D7E1FA9F74
-:10BB0000B18ED8FF21F8D83CF97FC63A6E99F24F32
-:10BB10005C87375F6EC8CF4379D646E788EC2E7EC8
-:10BB20002E1CE4DE3DBC9CCB398B930964C7FF74AB
-:10BB300079D784FD9D411F1CCFA17877083A1867FB
-:10BB400088A5A188ECCDA58CF681862CE5FB404329
-:10BB5000963A4D22DA03166E270E52ECCE414BB9BF
-:10BB6000DD19A79C2B888B117D32D43FF6CB5BCAA5
-:10BB7000E7C6E0BE9091ECD5E636DDF516D4535E0F
-:10BB800089CE8F86DA89D2D2954A9C5F6B9FAAF6BE
-:10BB9000681AE379FDB2B3B44FA7DAA34394F2B4C1
-:10BBA000A57C3F60488BD61E8DABD6DA8FFA82100B
-:10BBB0003B73A9BA7FD049EBD32DD7E9F1FC7FA81D
-:10BBC000DD897BB0A81407AB7A06B4FE4DD730F6FA
-:10BBD000747EF7F98C1CDC1F9AB95AD0E83955CF1E
-:10BBE0000224287EA4E2E343D473883FF734B55F90
-:10BBF000D26F3EAF48704C2E4FD79C5362EC7E1EE6
-:10BC00002F71733AFAF5EA116BD1AEDDB7EEC63794
-:10BC1000317D69FD9DE1E504AFF5546F7FCBC6EB47
-:10BC200030FF5076BB3D12E6F5D0A853EF09D0EFB8
-:10BC30006A3CE385EBB378298FB6149E8BD0B37A38
-:10BC4000DADFDBA40F4C9F0DE52B12451C91BE23C0
-:10BC50001D9832189D9F3059787EF5358CEEE33073
-:10BC6000E55C9F1A87093DD7B7CAC3C75905F0C419
-:10BC7000733596187E1FA939E1FEE908EF668781C2
-:10BC8000E139398B72EE4F62D5AE2AA877DC7EBFE0
-:10BC90007D16EE0B6718887EA498CE26C493D99E95
-:10BCA00063AFC27142E235CD29E9372059BCB5FBFB
-:10BCB000F09E67207D7BCFC92F319D2AB5EFC3F35E
-:10BCC000255246889FD26BBF9811DC9B87335F4A11
-:10BCD00032963B6E10914E75EB6F9A86FE54C150B2
-:10BCE000E71A584F5802F31B601E61BDF689797B35
-:10BCF000A9209CCED54896F5150DD8DFA808BA7FA7
-:10BD0000C0BE03AECBA7F34DF457F680A8473A0E5A
-:10BD100053F68FC3327BED1FD3FCC2304DE1593B4C
-:10BD2000E4C3157A5F637BCA87FB776B13526E108F
-:10BD30001D3DF5695F19D6BBF2BB1BAB685FFD26E5
-:10BD40009315CF9F8529FBCAA1E374A53A5B67438E
-:10BD50006AB418647316F1550F5F72E0D85383E626
-:10BD600001F5FA9CA73A6E731EC783DA9FD1C264AD
-:10BD7000B42343F7AD43FB817970BE56EAA9FD3188
-:10BD8000D646E70174888B517DB5ABA7B90DDFE9C5
-:10BD900024BB1FFF82E382CC1A43FC35AC55DBCEBB
-:10BDA0009CCACF0DA8F4182A2FA5D0FDF7D47A6F1E
-:10BDB00038E1819F2708AD1F0AD7D0F6F0B7335876
-:10BDC000DEDD60E1FB885DA99DB922AC7BA53D4726
-:10BDD000337F5ABFD0D37FEFFD3C6DBE4C36F6B9F2
-:10BDE0003E94077DCD77824EBB6F596CD1B62F8DB7
-:10BDF000D17E772568F39245E9DF916DA2F31A8E23
-:10BE00007C139EF753F9D818E2EFF78ADF2AFA2E4F
-:10BE100091C9741E7593DE790EE5C4E33340D201F7
-:10BE20007D3C2CF8CC582E55B45B510FC6ADD39346
-:10BE30009C7AFCAE5BCEE0BDA016A06B84E571F7EA
-:10BE4000479B6EC57CB148F10D9BFB7039D251CB3D
-:10BE5000775FBF371BCF9F3A0D74CE5B3DB7B1758F
-:10BE6000AC612B1E0B8ACB94CD69F0FDA12AE68430
-:10BE700099B02363632371FC2DD1A215F5DDF3D1B5
-:10BE8000F5FF8E7194E6198CF61942E15737D246C8
-:10BE900072366E75B680F75B1E1E9B5F8972310627
-:10BEA000FC6594AF90CA7DC517C715F0F8C0B6C53C
-:10BEB0002FC523BE37580FDB699E15A213A7D85292
-:10BEC000C1E57F8B85D13E7BF3A852371E4DEC72C6
-:10BED000C90E3C8BD8E2DE41F35E592D72D9AC9C81
-:10BEE000970158C851399CBE0C364AFD986E34B340
-:10BEF000F839289792C2E87C507FF681B484CB57FA
-:10BF00006C6FCCE9BFDE43118DF1C85CCB67E49F59
-:10BF10009F0BFD6D9DB199F2AA3C8D53E8BBBBDF31
-:10BF2000103DBA1BF04B72361AE42C9EC7638E8705
-:10BF300089B775F5C2B4203AD555807CCDE2E72E9D
-:10BF4000307EBBBEA834E387FC4C9D9BCBE51855E7
-:10BF50001EBBEB9761DC05DAFB515F633F78CE0FC8
-:10BF60005219D7B751A83F447EF30C8303EF39E849
-:10BF70002A400E437B5D82564F1C18C9F135FBC128
-:10BF8000BBCC9EA0384D8C721E66A3BEDE9C06EB19
-:10BF9000D93843746E07786CA96810FA8AC7C455FB
-:10BFA000707E990DF5D16FDE5291131BBC9E668C8D
-:10BFB00073C0D036D70F9FDBD385C8BF5D2379BC54
-:10BFC000BD67DD1CBE71403FA8879A4797AEE66A01
-:10BFD000DA41725567E56D6DAE7A3A07D955C1CF32
-:10BFE0005DAD13F87E82A4C4CB9B8BF249BFF44BAA
-:10BFF0002F152B499F84E2579D3FFDE507E91199D5
-:10C00000F1F119879BB4CE4CFAE107DA3B74F94A97
-:10C010007DD40B1E6D7FBA625136E3F8A85F10AF76
-:10C020003AE6C57B93A1FD952AFC163A1FC969E043
-:10C03000EDB19D8DF88BF4DB6901E0C8E982CEA1FA
-:10C04000B3F7383CB7243A7C6BF8012ED28774AE34
-:10C050002BA5F7788F098E65B8EFE87D5DA2F3E731
-:10C06000A17A4FCDAB7030B136E79C3EEC4D9C0FC2
-:10C07000EA3569A7D789FA01D0978AED362A4B09A4
-:10C08000BBB3D45CE0E8ADD7BA5C6DABAF82729362
-:10C090008399F6033C4C53997F30C079ED33CF1C24
-:10C0A000BF8AF53D0EAE03F899E0BCE6F94733E6EA
-:10C0B000407BF3EDAD26B4B943CFA1F56EEFA47686
-:10C0C000714BAB4CD319C5236554B986080BD9AF56
-:10C0D000CC7486E4B334C9C6EDA7103DB90EF85050
-:10C0E0008FF04A6404AFD03871E8F84905C9FCDE26
-:10C0F000E4E2521A774345A71EE3905DAE7AC54E3F
-:10C10000F2F4A9EF42FBB17B3AA723FF77151AC8D7
-:10C110001E7EF8C1499311CFDE6512C5D17AD17B5D
-:10C12000C8BA3D23F59CAE1C8BCD287FB7CCB9DBBC
-:10C13000ECE8C3FED852318BCE2F5A96703B63A5E4
-:10C14000BD81E488A542B9E7A2D8CB71AABF13A2EA
-:10C1500027B7543798F1DE9B7ADE9085D8DB97EDD0
-:10C16000BF1FBDBB61F98BF1A84FEE2A6988C77963
-:10C170006F89F04F7713DFD5939F02F2381EE5F1F8
-:10C18000A2910E922FDDF27FC6393B0E1E18695523
-:10C19000F88ADB435FE27F41BF668D92A714601C83
-:10C1A0002DB5448E7660BC74DFBBD300AE93BD7AF0
-:10C1B000F2638DFB81F4C12F322638495F9E1E68E1
-:10C1C000B0229DAC6AFC468FF76BCEE2E955E87F62
-:10C1D0005502B78756C51898DF42F3A1454F752E13
-:10C1E00066A8A7F509DC3701BFC58F79162310FDB6
-:10C1F0004C8EF1BAAD00872931BEBB30AD4AACD709
-:10C20000D9609C1247B480F09DA263C5061EAF9D05
-:10C2100085F35C11F311C55927A7C5D17D54A3C57A
-:10C22000ADC3FBC97A67D5F6B58CCE8B51BC15B0C2
-:10C230004AF7E18C18C7BDB6278EABEE13A9F1DC27
-:10C24000750529042F21C1FF2DE223CB1A10F11E01
-:10C250007E983E40F6F8AA4613F941CD093BDA91A3
-:10C260003D3223F83EA47A3E17E063B1027C560CBF
-:10C27000BC9BD6959414BB17E7A5FA91F120AF505B
-:10C28000DE6525CC9B8AEB4B7AC3ED4A867AC60CD9
-:10C290005D366016E0EAB9A278AC1EC6213C58D8DB
-:10C2A000384CFBABBF22D140F1D8D0F2270B785CE1
-:10C2B000320B0521AEEB5E13DDCF5D75E0BEF7AA54
-:10C2C000507E1E3039C967678114BCFFDE1D77665A
-:10C2D0007CFFDDAE9CBFB5DB0D743FA63BBECCF84A
-:10C2E000BEBC1AE7881AE5D98C78F231C721F4C7A9
-:10C2F000FEAB718F1B46CA4F607FAC6DC015C56326
-:10C30000C2C6EA689F2729857982F7055629EB5F1F
-:10C31000D50D877A3BEAF575289407F60F878D3798
-:10C32000E7BB2622DD46EC8847FDDA47BC431317FE
-:10C33000C17B2879B10462FA93AA799C2466EA3C0D
-:10C340008A774853F93ED90A1660FCDCA0C0847C89
-:10C35000BAEA4BFD0D7087E8D7CC7A929391AE90F4
-:10C36000B8482F7F45E6766588DCDBA2F0F9F1025C
-:10C3700025EE91CFF2BFE79325BB2852D9F7891854
-:10C38000954272E811570AD943C41C41F0BE9C9DE6
-:10C390007350B1877EA79C8FF72BE7830F2BE78322
-:10C3A0005FC5770BC0903F86EF16407ABCC949E560
-:10C3B0006F341528CA99E36F45EE9248B21F94F97D
-:10C3C000E994F9ADB04E7325037E566DD3D37958F9
-:10C3D00063C284E968CF32AFDC9E11DB73EF8775EF
-:10C3E000C2BFFC9E73A75D091E3A4F3AC7CAF73F0A
-:10C3F000557C2D54EAAF12B619905FC7766AE136C4
-:10C40000FE52A4C6AE2C62DAF397134D4334F54BBB
-:10C41000ACDAF39793ECD76ABE4F7668CF5F5E973E
-:10C42000313E641F564B570B13806E804EAA337DEE
-:10C4300034FF85D6528A7BCD0DB9C77447AB363FE2
-:10C44000DFA7CD2FDCADCDABE7C9C34629F43092D1
-:10C450008DFC31F14EE4F70C85EF0701BF6FB33A65
-:10C460009911DACF1678BFF81EC6001BED4BC976BE
-:10C470008C23ACE3F79FB05CC7CBBDC395F67ABE07
-:10C480006FC58EDBE8BE1D4BCCE1ED06F0EF7EFC08
-:10C490008EA4F1720EAF87FE12D61BA2F453C3E531
-:10C4A000939C45FE829BEC33236BB3626A01FEC210
-:10C4B000349A39E99E750CAB27BF7590727F325163
-:10C4C000E8A4BC43B086613E4570A6F0F8858FE4D1
-:10C4D000C35049FE752AF1895B7447F4E6970DB99C
-:10C4E000BA07F0AAF8860291E4E2235646EFF9D89B
-:10C4F0005CF713BF6EC316B06E336B8F49157AF8B5
-:10C50000E7EDBC61C45F135C0EDA2FB515240B7820
-:10C510002EA588859CCB364569E8A3C41A17425FCF
-:10C520004342E84B4B7F7F9DECD5453990CE42E8A6
-:10C53000F02FBEE5512C18AF4C8FFA058FD58976B8
-:10C540004A059ECA02964F75469B31EE678BD173A2
-:10C5500079A5D83FA54A9FABE459EBB2E1FB6B56F6
-:10C56000D149E6F6BA2D3DF12518DF9600F635EAF9
-:10C570006399915C7DB0D31F7635D47F04FCFF6551
-:10C580000CFD1BEB64BCEF65B5E4105F3F624979BD
-:10C5900000F35ED0E8587F4331F7AFE5E86C82EFF7
-:10C5A00051A1BE05EFA53DC2F24CA9C1F52DBCFEBF
-:10C5B0007A596451909F183182EABF9D6766F8CE20
-:10C5C0008177A0D98771EC63F2AC77DD41EB7F7B9B
-:10C5D00014D707AF191CF1A80F1E997C77A687D234
-:10C5E000748D5F684B10E4BECE17858F3672BD9296
-:10C5F0005BE2C7787C74C234579903FD1DB70BE921
-:10C6000042E712F1E85B37FD442B7EA8E406C10F38
-:10C610004B9B745D0E43FFE3110B77351E299ED5AE
-:10C620005286F90291EE03D95CE2EBD9B8AE027EF4
-:10C63000FEF04AE571A81E18329ADBBF9386443C8F
-:10C640003014FADF50245AB1FF0D7A2BDDE7F14E9A
-:10C6500066E45717BBEA97E0BC6D09110CCF6FDA9F
-:10C660000A1A78BED8C0CC004F936BBD17F1694A47
-:10C67000F58CC0F647077E7A1CED195B82483A704C
-:10C68000A2CBF9AE1BEB1728F19DE279EB703C9B36
-:10C6900045B49A590F1C54B9BE9EC9CBC9FFB20A02
-:10C6A000F4DECC0A6B430DCEE7918470B2F36DAE2D
-:10C6B000060BE279C3403DD14149227F576A55C2FA
-:10C6C000B40ACCFF62A09171BEF32F1F8AFE815382
-:10C6D000A075355B1A685EC72E8939C1EF96A8A987
-:10C6E000D9A185CFEF46F1F89009E3F1809FB7F526
-:10C6F000CC9C9A8BF4A3A778537F7C6B735DCE7E22
-:10C70000FB61FE2A94030B11BE8597C2984F40FA35
-:10C710003D2961FE777F015B80D6D960C1FE416E05
-:10C72000BBFAA2BF88D19C7E9B0B0E4BF84E82D7E2
-:10C7300021101F345B4E4E443E7828B58CE8E8A1AA
-:10C74000828F9A892F86F3FCDB79F7EE413C7A13CE
-:10C75000C3697FE7A1825931C1F4BE609448F432C5
-:10C76000EE6F614E3FE2639481F8FB9108C7568CEF
-:10C770004F79F3CC64BF4B8275D96C98E7C46228BB
-:10C7800087FEA25D623EF17E75058F0B2B307ED554
-:10C79000653B84F8904A66317EAE4939F71491EFD3
-:10C7A0005C4335B4FA6F952597DECFD892D07042AE
-:10C7B000D9B620BB6A9022570694884528DF0659CF
-:10C7C000B85D65EB940594BBA1FB47AABED729EDE4
-:10C7D0008C325BA6A3541B37D215707D1B6A7FE990
-:10C7E0002CDC5EC33FBC8FAECF353F89E738743158
-:10C7F000DA7A7F19A59C730AB1AF543ADF60E57A03
-:10C800006243AED18774BDA198DB592A1FABF247B2
-:10C8100085BF2A87D47B7EEF28F695514E5E3687FA
-:10C82000E4EA99E5786F07D49E7317C37B8956FABB
-:10C83000FEAE721FF194626FBDA7D85BFFA1D85BFB
-:10C84000EFA3BD05F986518308BF37142E76DD08A6
-:10C85000F31A902011DF143A4E4CC4EDAF71192732
-:10C860002C7DD96111D1A20EE3058F34F27B4936BC
-:10C8700097ED9815F159CF95F92C6B766934BBBCBF
-:10C880007CF2E37AD2D13EE4EB7B55B94F794C99F7
-:10C89000FF7165FE6F28F357ED8F4943BE32A1BC8F
-:10C8A000DF10AFEF477E29FC29A7D0B9A85079B592
-:10C8B00001C408E9EB2291FC9F2078E76AE4BD25DA
-:10C8C00020F7F54E59C9681EBFDB6076572C467CB1
-:10C8D0004E6614A79DE8AA27B96503B94572B3F857
-:10C8E0005CEB6CCA473883E59E518163B1CB5A8EAD
-:10C8F00072BE38464F1F5724A4D0BD5BD5FE0E1D17
-:10C90000F772F00C9567A682F55EE2F3FF47726C52
-:10C910002CE3E38EBD243AFD5CDE1C4F2679239187
-:10C920007C0AED5F95376F63CC6420BE4F64A1FB3A
-:10C9300000770A614E84E79D287C303F97D17DFFC8
-:10C94000C18A3D6757DED1014EA1B8CED84EB0F5B1
-:10C9500083F87AFC2553F71B6CDC8E8FD6E4279A7C
-:10C96000E235F54BACC99AEF93ECC335DF273BB208
-:10C9700035F9EB324669EAFFC259A4C9DF50305994
-:10C9800053BF4C2ED3E46566A577480E36ED1EFAEC
-:10C99000B11EFDA7B6A11FA7F5864FA1F1F00B0EA2
-:10C9A00060E1B5A38B67E80046855187EF4C86FCB4
-:10C9B000C6D19367E880EF0A071FFE3A195868D37B
-:10C9C000E8293C7FF5E1AF5320BF65F4753C3F8615
-:10C9D00091F0DC3A7AEA0C2FE0591CEA797434D0F1
-:10C9E000F12D97EA8FA23DF8C765D3E6264BF84EA6
-:10C9F00040596206CCE76C8AE761FC7E73ECAC15AB
-:10CA0000781176FC77F5748FED37A379BB8E8BFCAC
-:10CA10005D8D8E8BFC1D0DBBC8F1F65353F5BECB5F
-:10CA2000040E9A7EDF5F11647EAF05FDCD3969DCAF
-:10CA3000DFC414FD4D4CD1DFC414FDCD397AEE6F47
-:10CA4000628AFE2696A3BF89E95B4D32A5EF34B911
-:10CA5000286D6F7253DA7DBFE029E76A3D0A38EF2F
-:10CA60004F8B5B98C3E417114EA1E74A3AF49D4FF0
-:10CA7000D07ECA45E6C0FB1287224E3970BFAC3962
-:10CA8000CF44742E74B63B4CF0BD3097E79B2FB665
-:10CA90003B507E611EED9E8EE8B66C94BFCDB51600
-:10CAA00027EEBB355FF4C7239F14D61BE8DE4C711D
-:10CAB0006727C5E90A2DFCBD844311C78E28E39181
-:10CAC0005CDA7991F9457C27C7DCEEB02AE3603F58
-:10CAD000306E32EAB7C225302EF55BBF98FAA9B0A6
-:10CAE000748F2B848C6BFAE171270A41E3A67631AF
-:10CAF0007A1701C77568C6F54B743FFCA25FC27810
-:10CB00006147B4D38E714D355F8CDF21BF45CFDFD8
-:10CB10005F2C74F825D493B8BD89EF5BC681D833F8
-:10CB2000D3790D1FC965A84771B99D5D7C9D179A82
-:10CB3000FC0B909F8A957760C08CA57B9B4C0C73F7
-:10CB4000A2BE2891BE3B363817DF39E3EFA0151B94
-:10CB5000DDDB901FEB745CDEB01833DF57D0B5CF50
-:10CB6000FF15D43B193B98EC9504FB4B2C7504B492
-:10CB70005FE4CA44BBE3245B4F72687594E77F8F20
-:10CB8000067ABE31B35E50F427F5637785EFC0FDBA
-:10CB9000888E5786E5211F4D333A5E64C0BF7F1FE4
-:10CBA000DD44FC3C2DCA91872FACFD7DF40A9E8F9D
-:10CBB00073BC883783ADAC694671FC8F3F2F45F15C
-:10CBC0000D749AA70A3AB47FD4735376D1133606FC
-:10CBD000E054EBFACAC0E7D769C07870D41807C12F
-:10CBE0006FE06146E7983A2747F876E07EDF80FA03
-:10CBF0006C8C87B24C471ED64BD277D27DF28EEF2B
-:10CC0000F8FD27A819795350FCFE898392ABAFF841
-:10CC1000E3C931DC4E5D946A598778A8B39B4C9484
-:10CC20001EBC48E78299CE9D8AF16BD9D0F77BA9CB
-:10CC3000AF8EE1FA2179A54131024174C294E53009
-:10CC4000A6E6BD0CF4D0F6BBC3BADF8B037032434B
-:10CC50009AC8F3DE1D8F17EB34F565ACDFFD1DE3DD
-:10CC6000F4ACA7BDFCDBCD8F2F4F55C6437A99C7D7
-:10CC7000C87F0CD53B6B0B6DEA3B3F84E7C763CCA9
-:10CC8000DBE93D5249798714EA5A314E11CEE83D2D
-:10CC9000AEC1BF37FB9A819E769A393DA78A3CDDAB
-:10CCA00029F2FAEA3BA5EABB6BCF147A6E2BCCA330
-:10CCB0007EFCD48FB4371BDFCB88676D34BEFA6E31
-:10CCC000945A2F01F420092B5D673AE2AB5012FB16
-:10CCD00084E7E7638AE6201D5C68F2B24F82F4CDF8
-:10CCE00085F0C8C660FCD549DAF75A3F1F3381DAB0
-:10CCF000A9ED6B1B27B24F2878E9273AAA4D156991
-:10CD00001FBD4E62AFE23B9C20590DA897D576A778
-:10CD100040DEE278EF82FCC5F43D90BB9FE8D13E57
-:10CD20009D4EE9FB4D1E2A3FDD544D69A0A99ECAC8
-:10CD30003F6A6AA4F496DB2372917F16ED5FC63ECC
-:10CD400009A2F7DA36BD2710943F55D4371DAD51EF
-:10CD5000E8E85472DFDF9F1CC3EDBB53E3383E3B72
-:10CD6000C0DEC0F7DA802E975B6DFDDB1D1DCAFDAE
-:10CD7000AEA3E3F9FE65473CCF2F1FC3FD6E596498
-:10CD8000ADD8FEE87803EF3F45ACC6EFB28DF77B38
-:10CD90002A5DA477A47E35B1E8FE31583F16CA73E8
-:10CDA0007AF2A7AEE2DFE541BC5C9DAFFAFDB64288
-:10CDB000ABFAEE613A7FCF8FDFF7027AA7FED5FAA2
-:10CDC0006326703E0CADEF4BE5E7C943E1F1A9C224
-:10CDD000B7C4176867231F2407F1459D83F842A550
-:10CDE0004395FED6167238A71A153A0FE7E7EE07F5
-:10CDF000A32E847683E3CCB48F20E3BBCBB09E9D7F
-:10CE000082C22FA1FCA0BC63ACF283CA072ABD0F6B
-:10CE1000063EE3EF34F3758C95FA795F5859477BFA
-:10CE20006CC45D84D7837A2BEAADB1127F2F79B0C1
-:10CE3000D8F5CEEDC89FB1110E8C9196ACB2D4F757
-:10CE400025C73EFEAFC243950BFDC0A3171C0CCAFD
-:10CE5000BBC33F120E24E7508E23FDF621B74E8C44
-:10CE6000B1297617A7DFCFC7C86F221D7508661DC9
-:10CE7000DE7BE830F77D5FF0E878BE0E958ED61643
-:10CE8000324A07E33A87F6967BEA7ABAD7790723DC
-:10CE9000F9971AC6CB43F1ACAE2B48FE9DC179A9D8
-:10CEA000F0640CEC1FE827A1C642EFE8DD56E8E08D
-:10CEB000FC36F0D3CA0DAC67FD358A3E7B4C94F846
-:10CEC0007BC88A7EE92E17A49965991ABD4347CF7E
-:10CED0003A5FE1EF8AFB45568DEF72A36F1D1C1779
-:10CEE0001F52C8E543D7F43C11F7132FFCD542F786
-:10CEF0008B2F0CEA3C8DF6CE85563D53DE239B2AC4
-:10CF000080DE9D8B3E130CF9A5F29EF3E7E8F70E49
-:10CF1000837A6D174FA3BDB568ABC44C789E60EBA8
-:10CF200037B7203DCD7B454FE7999A5B371E477A4F
-:10CF30003CB74FC0E76FD9857D02C5316B5B227C62
-:10CF400066A85F0A79AC7FC76EC9C7E38B32C53963
-:10CF50006A94F13E31D7A5A05D3E71EB5D3A84FB4A
-:10CF6000BCED028B837E8FB4DE790CDF1D39B78D6B
-:10CF7000DF2F6B3647EEC0F9974AEB0C83A07CC1DC
-:10CF8000765E5E6329FD0CF743173CCD28FEB36047
-:10CF90006F04F98FF35AF41F0582EC8EEA6DDAFC08
-:10CFA0007CD666403A58B0535B5EB307F241F279E3
-:10CFB00050A1122F19CEB2295ED2C2E307AA7CEF8C
-:10CFC0006D5F7BB91C6D50DEFF667F89A5F70F5F33
-:10CFD000F926E9230BCF9729F93390FFEA1B8E1727
-:10CFE000152E75CAD85FC5B3DC365867DD2B662BA6
-:10CFF000FAED7507CE46E279B04561017A1799BD21
-:10D000002C59D1DE7B60BFE445F8D61E343F89FB46
-:10D0100098752F9E30603CA174DF62B2572631EFC5
-:10D020004AF49BFDA2C8DA898EDAE97D5F2677CEC5
-:10D03000C37E2E1C305BD10EA87BF94FC76EC7FC98
-:10D040008B02DDA7BC9018203A99B755A27B430C00
-:10D050002DB4FC1E3A9110AF88E7B6287A8FE50E02
-:10D06000C43BE219F0EE48463AE171D0794F4BF4F7
-:10D07000BDB9B5D980F5CFF9387E55BC974A4B0973
-:10D08000CF0B1EE7F89CB875D7E630A483A7F564EC
-:10D090008F1F817683783B0D1D185EE1FD5FD8C53B
-:10D0A000CF9177D3C10163371DE03C2F4707C0A75D
-:10D0B000A4F72F47079DE89792BFFFDDB9C7D00EB1
-:10D0C0008FE0E787D5771BD5771A072E3C7514DFDD
-:10D0D000E74AB3BF407677A5ED8BDAC58CDE099DB4
-:10D0E0005388E74B26BFBD02D17772CAB3D9142F3C
-:10D0F000D507766DC178437438C5C73A92CBB6E18F
-:10D10000FB98C5B66F93F6C23A16FDCE48E711EB11
-:10D11000157EC63F3C07A2BE4B0C78A7F319B50796
-:10D120008DFC5CC63EEDFBE11DF19CCE4B0C9D954C
-:10D130008BD14F80FE701C41E6FEE9C283FC1D4589
-:10D14000D59F5CA8BEA7B847FB6E83607D9BEA3D78
-:10D1500050984270181A37D68176797339F3840D56
-:10D16000FD217DC1DFA97C5CF18BFAB527FBD11BCA
-:10D17000AA1DC9BC21F7DA15B97547019FE3D1BBD8
-:10D18000DFD0E17B8C1D3BF9EF3BCC3F08F22A0658
-:10D19000F719F51AB953A7D4FF14E90FE076DE5B4F
-:10D1A000FF922805CB97F78BB19F9AA7793F7548D7
-:10D1B000571457F56F0E83FEBE6CD333E497054CBE
-:10D1C0009137FB23286ED44BBEECDCBE12CDF7505A
-:10D1D000BA5A0876262E2294BEEAF669EB3D5DA87F
-:10D1E000EC7B0E67D7E0F9FFAF31E090D7235FBA51
-:10D1F000DFE9678E28E4EF6E7D2868EFEF0F6B059F
-:10D20000960FEA77B8CFC463A44AFEEADD564DFE16
-:10D210009A36BBA6FEB5FB1D9AEFD9FE0CCDF711D1
-:10D22000C79D9A7C5E7B81A6FEC8F7644D7E54C084
-:10D23000A5A93FE6BC5B93EFCA84F5F461CFA8E9EA
-:10D2400024BBA0A93FD961D6F47F5D46B426DF6533
-:10D2500051E0A3D899AAFDFBA7426EFF86A62A7CBF
-:10D260007FE1D48EA3FAED371468C72B93B5E35D45
-:10D27000295EF01D419D9EFF7E02A6F8FB09BA348F
-:10D28000FEFB0998C7DF4FC0147F3F01CB7FDDE471
-:10D29000A4FCBEA602CABF047E09E6F7839F82E90A
-:10D2A000CBE09F60F9E5E0774C19F7B832EE1BCA86
-:10D2B000B83F154E6F29FDBDA3F487EF0DEAF43D8D
-:10D2C000DF6B5D79E225E0E322DB67745F596E086E
-:10D2D00094621CA3F37589E1F967E6F11D6F8A4139
-:10D2E000FD3680A19DC4DC9D6FE23E6EDD8B43ADBB
-:10D2F00078AEEF81FD7F7807BF5FD82751BCE6F09D
-:10D30000FEB391D8CF9797C2E9300AE945C8D77CD8
-:10D310002B507E0D7CC7736793F74ACABB676DA419
-:10D32000EFBE4C55F33EBA2FEDDEB3D780785AB836
-:10D330007B2F7D7F1DF85AF37DF776CD772BD6872F
-:10D3400074A1CE477185CFF7ABFDF9A97E4D2A7F39
-:10D350003FFEF3DD47568E417DBCB76A00C6B51768
-:10D36000EE39113BFB07F0F1D54BCF66A21EA83D6D
-:10D370002029E7D1787FB507F44A9ECFBF26756F85
-:10D38000299E37637B04BAB3F4255B4FE7C416EEDE
-:10D39000DF5583727661C6ED7A8A7FB5494ABC83D0
-:10D3A000BFD3506365DCAE6BFB3A12DFA9FF7DDBB8
-:10D3B000D1EBF11E74C7C123F45E4CC73E49E34F65
-:10D3C0008D1DCBF13B762CF7FFBEDC772412CF0905
-:10D3D0003ED07684C35DE7A7F51F56F21D9012BCC0
-:10D3E000F74BB4FEF99724CDEF01B8C071A1FBCD86
-:10D3F000FBD322705D27DBF878D3407D50796AD566
-:10D400001C9CFF1BF6F23CE57D32FADDA18EABAE33
-:10D41000DB857276619BD4E779F739D82FCCEF980A
-:10D420009ED3E9EBA92F1C1B04707FC335209B748E
-:10D430008452AF622CD79BA5064F2AEA91931647D8
-:10D4400004D2F9FDAEA11188DFC39862B9EB49BAE5
-:10D4500007BE601F1FEFA4B53D12E9EEE4BE1152F6
-:10D46000F0FECB2DCA7ABAE9BB1B6F5EC253B56F13
-:10D47000BB05FBE9C11F2F9F36D64AF5DFF09DB8EB
-:10D4800005EDAC9319FCDDC0630646FEF5C23DDC3C
-:10D490004E3E7970F0F6E0FB59D3147C7464F07D55
-:10D4A000F50BFBF54ABDDB77314D3D3DC7D74EED62
-:10D4B0007CACBE330FA17D5EF3B844671D6AF4F502
-:10D4C000B1B8FE4FB769E757ADC0B946EF8F8D0DC4
-:10D4D000A2D79A03DD7C63213A3FA0F28983F0A9A9
-:10D4E000E2F16486C4E765E7EFF8D5ECDD4574DD6D
-:10D4F0003BBEC4E3B783EF313929BE74197F5AB5F7
-:10D500001B82FC2DFABD23BD6B689E98D2631F9CC5
-:10D510002E941F1A9B877E989BFCCC930CEC5B1877
-:10D52000B316EDEB28FA1D89CD386ED73E3DBDFF11
-:10D530005F6B3AB000DF23EF7202A3C0BCBBB6E959
-:10D54000BBDF67463B779E62E77EEAF0E44BA07F55
-:10D550006B9789B4BE9A3D920FCF175C50E4DE57AB
-:10D560007B936F407AAD392E59D13F9AD896FC7093
-:10D57000612EE977B257EBDAB89D5CB75B20BB58F8
-:10D58000B5436A153BE49C62079F5BD6C9EDE35740
-:10D5900004B611EAAD0D037B04E65D9B3985ECDA38
-:10D5A0005A69DDCAC10E3C47A5B51BE61F3C44E7DE
-:10D5B000AEC0CED1942FDCADCDD7B669F3AABFF8FB
-:10D5C000D2D86E3B6338FA372552611CF2C39B0AEE
-:10D5D0005E557FE7CE6B9CF4FB270FE81C53D4B855
-:10D5E00004C26BD12B2FCCC779FB6AC29CE47F3479
-:10D5F000FE96E0DAF117EED774E0DE1BF233E3F0CB
-:10D60000EDD8CFE97C915EF0E1EFBA2C425D81FD6F
-:10D610009904DF328C3B7BBB22493E29E7081ACABA
-:10D62000B9FF2A630C18A6B27E2CF7E743F5EA3857
-:10D630005D408A0E921381B12954AFD8C0CF57DE16
-:10D6400019E124FD36C4C4EDF521266EAF0FD17566
-:10D650002EA3DF851824F07D8EAC9769FF606D9D49
-:10D6600085F617047B950EE1B17650950EE97D881D
-:10D67000B52D03FD3A355F8CDF337BEC83528B474E
-:10D6800087E3EC8C17947D04AE4FCB74567D749079
-:10D690007E656C99667EEA3DCC9F7D7E56989FA5FF
-:10D6A000677E80EF286CFF75AE93EC86A432F5F7A9
-:10D6B0001AEA492EA8F0FC12E8BD187045776C8173
-:10D6C0006E6AB61D22FFB296B5AFC476A5917C1DD9
-:10D6D000A506FEBE5169184F75E3B8FC2A51D2A5C4
-:10D6E000E3B4F6C39171B27E1CA43BC6B94DE3F21C
-:10D6F000683F9579617D0D6FF377D643E53E9413CE
-:10D700003D7D0D7C88F26F46BD604DD5D8699CBFCC
-:10D7100016F1A26E3E5AF8F693C427EA39CC6AC6CF
-:10D72000F97B66A3D99A1AC4178B90DFD0DE77C332
-:10D73000BF7C8C13F0BF6AEB7C3A97E9698CB5A289
-:10D740005FB748FA92F6257E2CDF2DDAAFCDFBCD00
-:10D750009CFEFD1102F94919E3BAE30DC48F490A91
-:10D760007F6CF708740E60FB773A1ECFAB10287EF3
-:10D7700077331436DA944962BDEA22BA4F7233E342
-:10D780004763594B8CF2BB3D31B46F7993B2EE9B3A
-:10D7900075FE4328578EEADB92319E74B4D6E4C4FA
-:10D7A000FECB591BBD6F5AC1DA293D155EF7A29F0A
-:10D7B0003AF72622DDFDC963A478D6F6E53B225070
-:10D7C000BE67B1E556DC4F0450ECC6B701FBB3733E
-:10D7D00042F71DD5FBC4602FC7217D02FE27211D06
-:10D7E0009C07DCD8737AB75FF8C71723117F5F2CCB
-:10D7F00079E1965B19FA5F9DE4472DA85F46F75DD6
-:10D80000819CDA33F27BF0AAE25DC55B375E1DF0E6
-:10D810002F18AFB0A6048493F46519C9A57F91E8C9
-:10D820009CD6E5F0AAC27DBC829F3B0E70F9158A9A
-:10D830006F150FB7E2BBF54349EF6E233C3123C9A7
-:10D84000CB507AB81CBE8030E93CD9C41823F9A16A
-:10D8500083452E4F07CF13285E793BF3BC1280F42B
-:10D8600096F0F7F5FCDE0AC75B8582B73F31DF2F04
-:10D870003292FF71783B32CEDD346E606FBE0DE5C3
-:10D88000D3FEF8B2C6E1FC37555FFA18F263083FE1
-:10D8900087F06B371E9DF02F088F9EC648E2CB6E37
-:10D8A0007C4B7BAE4C2FE27F308EB55FF0F993AFAF
-:10D8B000805F0546BFBFF8F838ADDE54F1A6C2A5BB
-:10D8C000BFB8E007CC7FD42AD0BE0AE7E3BB8D7493
-:10D8D000FF43DD5751F74F5E19C7F55C68FA01D871
-:10D8E0004BB85FB526E3E440B4334F19D47EF8FE5D
-:10D8F000EF07CBDA13F1F7B63E28E2E92903FFDDA3
-:10D900000F352F87F1B8E407F1462FC2E90361F81C
-:10D9100004D4331F08F75CCFF3710607E6CBE32688
-:10D92000E03D90537A358E79BF127FF0F179948F74
-:10D930002CA67A02FF5D4A07FEDE1DF62B0836177D
-:10D94000CCE783BBD2E87D9DEE7D8D71DC0E7F46FA
-:10D95000594777DCFF5E81E2FE335135E1FEC48436
-:10D960002D2E7C87F3F47D43B369DFB4413B3EEA5F
-:10D97000FD648A976EE0E7FE2E75EAAB82F45BB732
-:10D98000BE2DBEC8CBE7E4D1EF8CA8BF4727DB860E
-:10D9900073FFDCC77FDF50D5675DC75FB004C77317
-:10D9A0003F53E2DFDDF9E10F2605EBC3434FAD4DF9
-:10D9B000C77EAA0DDE2CA7057F87EEB124B45BAA33
-:10D9C0009F5A954EF6F4530FA4A35F54BD636DBAEE
-:10D9D0004CF9700FF9653ABEEE2F9E1B45E7F3D464
-:10D9E000FEF6CADCAFA8301D2A41BD3DE5EAAF56C0
-:10D9F000E0FE41DA7D02C5FF66B0F615A8672B335D
-:10DA0000385FB11613C97FE88FF66B770DFFC54EEF
-:10DA100094076F649CD5CF817A123E203510DFD5F4
-:10DA2000F2ADA3DF095CCD7F27B0A77E22EDFF56C4
-:10DA30002D17E89DAB19F5FC77F3A4F1D104C75974
-:10DA4000ABB38FD1FB574B79F914A36FDF49EC6768
-:10DA50008B81DF3F64EE94E0FB7092B25F38739D80
-:10DA6000F27B71CA38699B63B707AF5352F61D59F1
-:10DA7000EA7724DF6E50F03275E98957EDD0EF5424
-:10DA8000BDC73C1EBEBFB3E95CAA9F611CF4333A1C
-:10DA90005F9866F03C3A1FD7BDC34871D2DCACC179
-:10DAA000521CD4CF5952B411D3994BAB1E9D8F72D7
-:10DAB000B8D594CD8F35F2F935084E11E5F491EDD6
-:10DAC000B7CE42B89DDFC47FFFAB61FB30FADDC249
-:10DAD000FEE4DEAF9AF8EFF93DDD64A2F4D9262B1F
-:10DAE000C3A3EBCF35D929FFAF4D0E4AD9F43CCDB6
-:10DAF000EFD8F4D7DF884BE1F4BB73B9ABCDF43B7F
-:10DB0000880D4639753CC02BEDAADA1D0F28EBC2F3
-:10DB1000F7B8B2BDC913110EB90F2C3E86A6B37566
-:10DB20003CDF977DF3E4EA2414D6772C3DF3C47CE4
-:10DB3000F87EFB78F7350827D3B68B14A7387260C8
-:10DB40005525C2BB7A8791AF4F59F7F94DE9718FCF
-:10DB5000627CF9753DC50D166D3BF3C4030C7F87E0
-:10DB600077B12198DEAF74BD578FE77EE6E5F8AA5E
-:10DB70003F38FC78BE5A9B44FCB303F82AF3A7F362
-:10DB8000D5A2A5CB087ECBC6BB6F42B89DD77B93F1
-:10DB9000909FCE0F1F4B74EE7D4520F8AB72BCDB1F
-:10DBA000AF56E0BF506C5B5798DC23C7BF61B90428
-:10DBB000DF43073E4D47FBF99BFDE53FB8EE97601D
-:10DBC000DDFE6118AF33511AFA3DDFE019EA84F542
-:10DBD000E5F7F33EE8D2F16AFC9F9F53C03F213640
-:10DBE000F89D21E68D82F9D41C14FC6159A8CF263A
-:10DBF0007DA643BF11FCCF8F34E78C19FB28489FCB
-:10DC0000F737DFCBA575D84F5A8FDC1DF99EC8FCBE
-:10DC1000417A7B54208CF983C6EDF673A0CC40FB8F
-:10DC20004EF12417106F782EECC281E13B30FF9942
-:10DC300081E3F1C24B604FF1781093F27BD6F9D9B2
-:10DC4000812FB250CE86AEB7EEE52F883E6AF6AF92
-:10DC5000BA28D0FA277FA6CBBAFCFA0F3DF54516B5
-:10DC6000E2EF337D201FFDB60B864016E2A1EEB732
-:10DC70005C9EFF5838A8E5F3571BE8F73AEB04130E
-:10DC8000D14989F425C51F2E1CE7F187BA034F92AD
-:10DC90003CED3AC8E3408BC4F6D2388C9BD49F3914
-:10DCA00086F2ACCBCEFD31E89FDE712B1CAAE84199
-:10DCB0005D6712DEF73BD84D0FDC8F3C8FFC3B0CD1
-:10DCC000FB69A3F3BD2C2B9CA15DF139F2F3307CF1
-:10DCD000BF307925D2F979DFC01C948F6F66FDAD16
-:10DCE0008EE286BF0FA77BB2B56D92E69C79F73ABC
-:10DCF0007C123F70C454FB299CC9C1E7B90C8E1B30
-:10DD0000C86E7E83EF132EBA8AF3137B99F353ED1B
-:10DD1000F243067B507FBB157E52EDC829BFFF1B27
-:10DD2000F1E5B38532FD04D54FA5C7FF9FFEF74C43
-:10DD3000FF2F4133EC630080000000001F8B0800C0
-:10DD40000000000000FFA55A0D705455963EEFBD2F
-:10DD5000FE4927DD4913421208840642881A6203ED
-:10DD60008172D6C4E9FC6E2033BB016B2DC4088DD3
-:10DD700022249D7482E8EC6AB96E1A02AC6475368E
-:10DD80008C59471D479B9F8028EC769440C0A00D7E
-:10DD90000ACBA26B45AA263A555B54ABAC0EE0A663
-:10DDA00023823BD6E2B8E73BEFB5DD1DE24FEDA69F
-:10DDB0008ABA7DEECFB9E79E7BCE77CE3D8FB45247
-:10DDC00022CA226ACFCD082A0AFFA66EA245446D58
-:10DDD00029247FF641451FAFD364BC7D40A3C958B9
-:10DDE00093EB08CE9E415447DD269A45B4844265A4
-:10DDF000A471BF29F2CB5B79BCFE0D6D4117936115
-:10DE00001BAD6AB013D5A67A0B3614130DABCAAA94
-:10DE10008662CC0B952E9D4BF40DFE7E4A749B873B
-:10DE2000994F222AD3140FF61B9D9C16DCC95D8BDB
-:10DE300097FB1B494D98A7EAF3984F53087C82A3A0
-:10DE4000254B1DD868B46499233EEF8E37D2D60790
-:10DE5000314EA1D23B12F6F94B8F856821D117CBF9
-:10DE600017AA0F65F279AEDA037433518D76ED2976
-:10DE700085F7DD70CC4C5605FC67BCAFF239026704
-:10DE800034EA65FA52470A79ACCCCE4B1E0FCF1B51
-:10DE9000993B29D8C5E76F3FA09089E7B51DB1EE42
-:10DEA0004CE1796DE648B69BF7DD36F03B8B87DBBE
-:10DEB000F6FEF72CAEB958CF4736439E1415FA6DCF
-:10DEC00077F24F17917F60CEFB77313FFF694DF4BA
-:10DED000ED37BD6721D6D7059E8FFD5A0EF6D58248
-:10DEE0006EA5F05627DAFD3CAF48BF9B6FF8DFE523
-:10DEF0005C5786B3387EBEF8395DA2A718BDF869B5
-:10DF00003EF702D68B46EB437659EE21967B716E37
-:10DF1000CE8E2E25719DAE5F8F76694B0ECB159DF3
-:10DF2000A9B81566154D0D6C76421F858AB39717F3
-:10DF3000475F7FB9742DF49B122CBD9DCF17B59010
-:10DF4000DCC7E2C7B69BB40479160F6A1EDC433403
-:10DF5000959A0EC9BD7BA7E23EA8BC61A96712D6FF
-:10DF60008DBE7B2B6F195579BDFDFA7304CA757987
-:10DF7000CEB0A9C97D1B72D7E7E5ED80FED900C4FC
-:10DF80008E4EA9FAFE1E95C7E7C7D7BF689CA74665
-:10DF90002BCE89F0F806C59DE31C679F58BB87F51B
-:10DFA000BE86EFE945BE6FB42F753869CD6CA2FD12
-:10DFB0001DB942FF73874BDA504791F4BFD2E11687
-:10DFC000FA60C72D421FEAF0083DD05127EDD18EEF
-:10DFD00006E93F0351FF8C70A020ECE2147C6D4AEF
-:10DFE0009C1ECE1C434F499E3F9CA924D353149999
-:10DFF000FF70B83C1860FAA532A79C938DCAD1C0B7
-:10E00000FA684E4B2FA10CB4F9414A67BBB17B03B0
-:10E010001EB6FB3FD4EDDA4333C5CF4B30AF3AF3F6
-:10E02000CE46F8DBE52C2B69ACCFC31EEFDF63DEF9
-:10E03000E9D35505DBD13F68735BF9FE8757DC9464
-:10E0400001BD47FF4D238DB7AE285AB0B994E90AF8
-:10E05000BB2276CCFC6E6EC866BBC64FE65335B8A5
-:10E06000BAD4A4E38473B602FDB7AEC13E1B26DB6F
-:10E07000165879FC4AB9F757D827A6F7DA29EB0AD8
-:10E08000BCD08BD9F5BECAF302FF6EA65E9EF780A8
-:10E09000C39D64DF47CB2B82B09BC545B336CF070A
-:10E0A0007F76BAD9BC3FBBF57EC8E751D3944EC149
-:10E0B000319709B810C4FDF33E952E45EC306C71D4
-:10E0C0009932997F38B5222BC0EB4E19F77DDAB81B
-:10E0D000EF33C67DBFC3FDD5DCBECBFD6887B81F5F
-:10E0E000ED8A989E4DA385D05FF0A70D2F7944EF60
-:10E0F000A3F9A0A3665A0E3B5C023FD3F127BF8170
-:10E10000E578A25C97E36E037F866E6BE8D3D785D4
-:10E11000844F8B85BCB0FF4B589F609FB175F1F564
-:10E1200024EDB29B2990C2E7A0C3B620F4445389E2
-:10E13000805FCB0EE7082E6929B38ACF4F647A013E
-:10E14000099ED2AB567D5EAE6B21FC857524FB8C9F
-:10E1500004D58099EDC49F395498C9F28E187E1663
-:10E16000A30FFD4913FCF6CF679ADBD714FD7CFEA5
-:10E1700065438513B05EB1A9B033FF4E7DFCACE1C1
-:10E1800087FE99063FE33C9412CAC77D448F1DCE9B
-:10E19000BF87E92E7B78AD1E07C28582DF142E5C17
-:10E1A000069C5442E7C84DD477FC7DAFE927D047A1
-:10E1B000E879D0FDC77FAFD34ADF3967E2F8A450D2
-:10E1C000BEE204FD8141F73D3FC19D409B5F398721
-:10E1D00071CBA6DF7BAB27336E5883A73B6037FF3D
-:10E1E000A2DB97ED40FF27D05BCB112BC12E2B0F6D
-:10E1F000F47FF60A8FB7F43BDC80FBA86786E8BBA8
-:10E20000F3C8DEC7616F237D66F187AEFDBF7BFE7D
-:10E2100011996725985BBD35544ABCCFD1E37FE3A4
-:10E2200035619FB4D015D06F579C1739EA27EAFEA5
-:10E230003D54F1A93700BDF51FF86BC4B5FA0C0ABF
-:10E24000C06EE965BE4766E47BF5866A2AE171C760
-:10E25000D04AF06F7BC9EA869DFA5ECDA9841F5F24
-:10E26000F3CC14FB6BBEB13B1F71573DBA6FCF238C
-:10E2700059986723C8DB9EC976C47AF5693B16DDD9
-:10E280002FF7B76BCF6F20F73E1BED643ECDCC036D
-:10E29000FB35EF991D0CF0D15EFBFAE395B8871AB8
-:10E2A000EDB93DE8BFB2DBA6420F672D9E8C72F838
-:10E2B000E159B3BB17EB0CBA7978A22E4F5AA4568A
-:10E2C000EE2FAB3B1F71D737F1E1BF80DCF55AF77A
-:10E2D000F3CFE23C7BAD843871611FEB8DD75DE8F5
-:10E2E00035CFC72D8FEC7398602F9794EE95CF8222
-:10E2F0007FAF3EEF92AD5BF419E89D43D88FE711F5
-:10E30000E2F225657B52FF85DEBD255ED6DFC5972F
-:10E31000EA8BBD09F61BF317DF6E6B527C14246089
-:10E320005CF219BFC919203BC7DF6683BC78E89946
-:10E33000916729BEFEE27E73D8C23A6AB6D2E694ED
-:10E34000CCB83FF8F2FEBC0EE7F3A93B0A91C73404
-:10E350002F88AC845F5CB0514A2ECF7BDB885FBED8
-:10E36000831B972A25DF2D4F4D85EEC75773F53850
-:10E370007675C0160C28DF1D8FFEA3839CEFCC8E14
-:10E38000D377AF677E29717E6F5B42AD6EDEB72DAE
-:10E3900053C78F733C7F3FE35895B1CFAA8792E76D
-:10E3A000DF529129F6D3668914220EC6F82FAC8865
-:10E3B000E15AA4107835765D3DD213E0C8CB8AE0EF
-:10E3C00088EFA0F2A1966EA8343BAE4F5F4A20A81A
-:10E3D000958C7F0FB98B8C7B605EEF55E87EE5DB1B
-:10E3E0006FF3D8984F4B6A241D7953AB23928E7CE0
-:10E3F00068E4A8463B8DEBCB8AF19F19DFAF494615
-:10E40000B83F64F6D8C6DB8F8F433C6F1D7EB32ABE
-:10E410003EA9D0FDA669204DF623676411ECB6E94C
-:10E42000B9E47538A733C11F470676657B13E28FC1
-:10E43000CF903BAA7C287E13FDFAA37CD8814FA500
-:10E44000CD0AABF622AFB1650A4D293A1DB0B1E550
-:10E45000FBBEB4A7C27E2E5E6D153F1E5122827395
-:10E46000B927AE0A3E8C982382738ECAFF11FC181E
-:10E4700099105909DCCAADB4AF96F1C991952E1E19
-:10E48000FFB2C2A0A791E40385273257034FEAB534
-:10E49000D1B711376997D9093F89E97B9DA127A297
-:10E4A000C7863B78FC0F41B30BF1614EA562E40BCC
-:10E4B00096F8F9B5B83F8D90EBC041F86793DDDD74
-:10E4C0002BA3C1FDAF201FBC33DBDDE5BA5E6F328D
-:10E4D00087E5CACAFC6A2DEE293BDDFB8F15CCDF30
-:10E4E0005F1CC907CEB1B54B1C6A7BDDBA13FB4775
-:10E4F000CDA37B805F171CDE272B589FAD96A1AD67
-:10E50000A52CD267E6C829A4F84B606F8223BABD58
-:10E510008D14EFB2089F1E562AEB6797710F944B2C
-:10E52000B403F6A1E8F7FCE6C0ABEF006F468666E1
-:10E53000094E8FF5A70B034FA603373EE0F81E9850
-:10E5400013EFFF60F55E0BFA97BFB8C312E1F69EBA
-:10E55000CDC9E7BB7CEDF60CF80B3D9ED00F7BECF4
-:10E5600049A6C7EA0576194EF28380E8FD9CC729C3
-:10E57000F2B7540EB5410FDFD2CB98D612E8136331
-:10E58000E831F3A941CF1FCE7948F8B64E0B0F43BF
-:10E590006F2307CC047CEFE4B826747F5A10EF1A7F
-:10E5A000F500C7AD2C3D6E215EB4A40FADC4BD8C8B
-:10E5B000F45B9D98BFE9C8A7F9383FDB633ECEDB2B
-:10E5C00072E47036C1CE8DF704C7C76C8CB7F41FE8
-:10E5D000C9C6BB24D6DFAA860A211747B812E0476E
-:10E5E000ACDFAF850B217F8B325482F128E496F9A2
-:10E5F0004C6BA049CED1AAE87E4F4734C1F9B1F7A0
-:10E60000F651856EAF8C0F25C807371DBD5412B16A
-:10E61000C7F1A0D9C09513E82FD6FDDFB9C8C0094E
-:10E620005EDA0CBF1F0727BC31DCA3F516C87DAE30
-:10E6300042973BB65EF8CA3B2320E36DAF5D2A9953
-:10E64000598C75C63C4AC0A359717C010EE40A0E70
-:10E650006C3267F3B97CCF2BEE4E5ED2DCB8B1964C
-:10E66000A7D33AD3FDB5D06B1305E45D3756AEB1F1
-:10E6700076F470857EBF3E557F8FFBF628C14E969F
-:10E68000EB22637DEE7CC19B30F0675DF5C65AF8E6
-:10E69000DF7D597E4BE2BBF987F8AFED49A6D7ADD8
-:10E6A000DF589B338E9FFB1EDA7E6A125DCFAFD997
-:10E6B000BBA336DB757D7F4CEE8BB6989C95E64907
-:10E6C00089FA58BEB17612B7EB52FEAFFAD0CF7DC1
-:10E6D000F188358CB8CBFAB5E0FCB7FD71BD2509E2
-:10E6E000B77F805F33056B9D33BE5BFEB16DAB12B0
-:10E6F0001E56804FEC5FBDE267EC3709FB6DAA1830
-:10E7000053A7685A3D1D793779574F4FAC538C6DDD
-:10E710001928A7A8B788BD49CB7EB8D23D8E3E62E6
-:10E72000F36FAED4649F4D861D4FA96F79E6151E19
-:10E730007FB9CC5356C97E55AEA992BF8FDDA7A62F
-:10E7400052CF0F86B21DBF803D4507CD4EF849B967
-:10E75000A6EB334FBDFC2EFC312FDBE1EA647E35A6
-:10E760005569FABC633627EA40D1635FE57BE0FF79
-:10E770005BECCBA5CE62B2D3641E3F953B57F03D18
-:10E78000B6CFC7C63E69A57ABED35E64FEFE3A53D5
-:10E79000B1E3DB3A93E41BC569C1D91287BF90F896
-:10E7A000161D5CE8D45CC0F7A01DFED6FEF57F67A1
-:10E7B000230E8F0CFE67BA0BB875EDD374D8CFB6A5
-:10E7C000818FD3810F27066639D09E1D7239D01FE5
-:10E7D000ADFBB816F3BA8C365E67308B9CB136F65B
-:10E7E0007E8ED51312DED1CDD06BAF73DB2F4B6194
-:10E7F000EFA9DD8263FC8ECE44FC88D7195C39E337
-:10E80000D56512EB0C05B3F53A035AD4190ACC7A44
-:10E810009D0134EA0C685167403FEA0CA051670043
-:10E820008D3A0368D419D0A2CE80FE2BA86BB1BC60
-:10E83000514EDE50DFAAD1EC82FF0FF46A41E4F5BD
-:10E840000F1CD3747A8712C47D7FC6FB230E46AF9C
-:10E85000E875B028C75379E71F34CBFB201ADA5E7E
-:10E860003713F7D6AFB97155171137D914DBCDA3CC
-:10E8700027511F6AEF53DC1B5DE85F2E726C1B5C37
-:10E88000F87E23FA7BCD6ED585FBBA9A8DFA976F09
-:10E89000B057EA58D539C72C72CFFB15CAE1FDEF46
-:10E8A000B0EAEF64BFC6BD2CF7B045953CDA6F1DEA
-:10E8B00092F74BCB8B8A734D421EDA7ECBE78213E5
-:10E8C0009DB6F49D90D71FB239D724C5578FE47DEC
-:10E8D0007EFC74C18D3C43454CAFD5A790DF5E7B79
-:10E8E000013821F948427EB4D6D9FC33E467A45DEF
-:10E8F00033E1FC7E7EE84E64F9D63D6DFE2892B091
-:10E900007F733099F60DF66DCD23C899DC8F4A03DD
-:10E91000E2B23F94DC1FAA74647D92C63FE6D13C0C
-:10E92000E45B75FFB4E6403FEF77B9DB2AF9CA61D3
-:10E930008FF77025FBF149B347EA2F278FD9E4BD44
-:10E94000757EFB9CA4FA4B8D3655EA1F1BCC8AC4FE
-:10E95000F12BE5DE63B0CBAABA7BA5EE5295EB10A6
-:10E960007F8ED9E1D1F28637C077C35C97D4BF6A76
-:10E97000ACF40BE1C77E2FF73C68167FABE95482FD
-:10E980002AD3ABC96D817FAD62758A3D99ED8F2920
-:10E99000EC0FAB78AFC604BBDAB05D91BC420A1095
-:10E9A000ACE795863E570DFEEB570AFBCBBD563DB7
-:10E9B0000FCE5355E19FD7C5718BE7DF475E0BFC48
-:10E9C000661DC755B41C675F8F70BF376D6ABE9EEA
-:10E9D000E7BB72C07FF51933014F6A727E5EE8951E
-:10E9E000785FEDFC84EF5B09DFA57D73D3F7E1A8C9
-:10E9F000893E49C86B4F9A75FC617DCA7BEB14EC6C
-:10EA000055EA3E5E69CF743449BBA28CC4FF0B3417
-:10EA10003D6F2FE0BB72664ADDA20FEB6BDAED6E45
-:10EA2000E83F860BBB8DFCBE40E596E7ED4ED55B1F
-:10EA30000BD329DC3F8D5BCA147E61E77CD4715C0B
-:10EA4000C23F4F3DBBC0057D7C6977431F3539C749
-:10EA5000E6E1DD31CBE0FF7259C355DC97279D021B
-:10EA6000D89F8F43DDACDF5A1C48415D3DE4D15057
-:10EA7000273FA638F1AEBF1E4FB76F71C2CF0A1441
-:10EA800027EAB7B5A9DD35D9CCBF76E60C37F09CBF
-:10EA9000F155EA6123DCEA76706B5053F4B5A66C4D
-:10EAA000D4F30DFF29F7A6544D8AF7D71B7E141D0A
-:10EAB000FC221DF1F547D46D77837F806CEE5E8379
-:10EAC0003FECA0FEA66952BF8DD9D1E5FD393B616F
-:10EAD0004753ABF4758D8DEF99914F0CDDE6CDC1A9
-:10EAE000FE2BD77CBE255BCE397EBD8C713703B83B
-:10EAF0003BB65E16C3F13D46FD1D786B32EABA2681
-:10EB0000A3AE6B32EABA26A3AE6B32EABA26A3AE44
-:10EB10006B32EABA26A3AE6B32EABA26A913AE97D5
-:10EB2000F6DD8E87A41DEA08C87842BCB8B9EAC7EA
-:10EB3000D55D17558D5377A5145786C45DF67BBDFB
-:10EB4000DE3DA6CECAFEAE26F87BD5E0847B1E4312
-:10EB50005ED26371B338546BF1163C60177CF0548D
-:10EB60008D5B6F8DE9CF2EF5D9CB649B8F7BA82C65
-:10EB70009A655251C734EE2356EF84DFE09CF01BB8
-:10EB8000B4F01BD3ECB8DFFCD6C2AE5DAAE7090136
-:10EB9000C9136C72BF5B3732AE307D2F399370E58D
-:10EBA000B331B8C20F9A159063EDA095BA743F23A4
-:10EBB000F84F25377F9C3F0ECE84749C99961ADAC5
-:10EBC000877DA6B5A5BA9117B3BF8B9D9DDCA6889E
-:10EBD000BFAFA106D9771CBC49479E7CEFC4D17357
-:10EBE000BFE1F9F7FE835DF29DAD93D72EFAFFE00A
-:10EBF0004D4D95AE8F5F77847DE75996EA54B643C5
-:10EC00008E57D5162A92BAB89A2AFE50A33DAE580E
-:10EC100080A377D33CDC77B5B5E139C899C3FE2E24
-:10EC2000EFDF2CA3BE6B1A6ADECBF4D9EC3C37BE07
-:10EC3000AB4DCD3D44050B804775C5B0ABB3D4ADEE
-:10EC400060DD6319DEBF83BFDC5ECCA756E3FE96B2
-:10EC50005397B6B34BEE63CE42DCFB32ABAB1FF542
-:10EC6000862D6F9E907AC2B20CD742D41BB6BC7967
-:10EC70005AA7735CFD8A1BE5B213ABAB7F82F866C3
-:10EC8000EB3E9F1067FDA1094974FBC0E4EEF30958
-:10EC900071AE053FF89D4E3F534CB8AF5643945C60
-:10ECA000D5BB1DF2F9EBFE4B7FCFD3A8C4C9A7AAF1
-:10ECB000745C9C7482C2B0E7D1C50EF9FE973371C3
-:10ECC000FD3CD4DBA8D8B510F338AFFD35ECF8E245
-:10ECD000AD9EA7C127CF38770EF1793558C7900D73
-:10ECE000ED19E3BBE429D5DB88B6363D60927E356D
-:10ECF000588AF66D35F420FAD92F76814FED93F3CB
-:10ED00006E2C623ACF1A9AB7DE8E78E9D98DFE73EF
-:10ED1000659E5EEC37B6EEDF699C8FE5D98779C3D7
-:10ED200085AAE4F9C337EA6DCC2EC2553A0E1D37D9
-:10ED3000FCA8AC93E4FBE758FB395EA51A78F9FD13
-:10ED400072B3BC47204F4C7EEA5E5D0A7958DEA361
-:10ED500086BCAF619CEC99528FF96E7B0DC87EC763
-:10ED60000D3B657C6C39AFE3A3B485A6E004E40DEC
-:10ED7000531E0D4E80BC53768CDA5CDCBE1018B589
-:10ED8000217F78E16F476DE87FC14375E3E1BF56AE
-:10ED9000AD09DFC2B251593F9DF71A9277C2E8041C
-:10EDA000E46F854D6F59026CB7739EE67D93F2B7A1
-:10EDB000228963D30D5B9AFEA84AB087E9CF90E41D
-:10EDC000AB549D25E3BE14DDFF7D8F3EA8C28E6E41
-:10EDD00008B2DC09F637E769D3E54812DFB0AC6B5F
-:10EDE000317083F3B5A4713F3347BE3CC5C023E403
-:10EDF0008F8D8C37FEA6B7BE42BEC879DC187E8CDC
-:10EE00004D311C26C45DEFEB1117FC2079DEDABB17
-:10EE10001ED98AF76D53E3768BBC8FD7F46D45DB33
-:10EE2000DAFA9E258724BF4C9ACFF965127D9D9C06
-:10EE300063E4687BF0F3AD39E3ECCB76702DD10E53
-:10EE40004E9A4337E0BD7AD29FEA0E481C09DD0F87
-:10EE50007CD9D96A7723AEECFA55A5D8D7B7F5A9EE
-:10EE6000328FA9FA47D951A7CC0F545211FCE6872B
-:10EE7000DA11E0E1EC243C0C48DD72894370AEDD30
-:10EE80007807B6AD714A3E12F3EB3653E8C3AD983E
-:10EE900097E590EF110CB745A62C7C6F9AE2EE4AED
-:10EEA000C82BCE2E9915049DDD190A83EFE8CF15E6
-:10EEB00037EAC8D5693AAED6A80DAD7B79FC2D35B9
-:10EEC0002CB8F15BE007F36FB7AC977645D94CB13E
-:10EED000DB5C0A29FAFF67702DC47B3DF63DAD6708
-:10EEE0005BB0EF20DEFB4AF099B5A88FFE955DE49C
-:10EEF0008906D58099CFD3338104B77BEE2C94B8A3
-:10EF000013A586C6FB91FF2C4F953A6ACF04D71301
-:10EF1000F86EDAD37CA3E4F587FEA4C7FBD1A5295C
-:10EF20006EE4713DF35C1B71AE9E475D32FE9AA2AA
-:10EF3000F30B3CA1EBA767A97ECE9EE64C799FC55B
-:10EF4000EEA167876732BEBF5932BCE5D5A803186A
-:10EF5000DF1F7B66703FB74F290D77DE073E737565
-:10EF6000795794B9E4DE4EDE79E3137B747D86F144
-:10EF70001DAC7D8923E9FDFEBFFE80CBB3202200BE
-:10EF80000000000000000000040835000000000040
-:00000001FF
diff --git a/firmware/bnx2x-e1h-5.0.21.0.fw.ihex b/firmware/bnx2x-e1h-5.0.21.0.fw.ihex
new file mode 100644
index 0000000..e78c863
--- /dev/null
+++ b/firmware/bnx2x-e1h-5.0.21.0.fw.ihex
@@ -0,0 +1,12855 @@
+:1000000000003BB8000000600000068800003C20B3
+:100010000000192C000042B0000000AC00005BE0C2
+:1000200000008DC400005C90000000E40000EA586D
+:100030000000E4140000EB40000000940001CF58E1
+:10004000000058E80001CFF0000000C4000228E0E2
+:100050000000F978000229A800000004000323280A
+:10006000020400480000000F020400540000004594
+:1000700002040058000000840204005C0000000636
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000020400CC40100000D0
+:10010000060400D000000003020400DC0010000020
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000020400EC4214000053
+:10013000060400F000000003010401240000000098
+:1001400001040128000000000104012C000000004F
+:100150000104013000000000020401D00000890603
+:1001600002040004000000FF02040008000000FF79
+:100170000204000C000000FF02040010000000FF59
+:1001800002040014000000FF02040018000000FF39
+:100190000204001C000000FF02040020000000FF19
+:1001A000020400240000003E0204002800000000B9
+:1001B0000204002C0000003F020400300000003F59
+:1001C000020400340000003F020400380000003F39
+:1001D0000204003C0000003F020400400000003F19
+:1001E000020400440000003F020404CC00000001AF
+:1001F00002042008000002110204200C000002008A
+:10020000020420100000020402042014000002195D
+:100210000204201C0000FFFF020420200000FFFF5A
+:10022000020420240000FFFF020420280000FFFF3A
+:1002300002042038000000200204203C00000000DE
+:100240000204204000000034020420440000003575
+:10025000060420480000001C020420B80000000131
+:10026000060420BC0000005F0204223807FFFFFFE5
+:100270000204223C0000003F0204224007FFFFFF6F
+:10028000020422440000000F010422480000000084
+:100290000104224C00000000010422500000000074
+:1002A0000104225400000000010422580000000054
+:1002B0000104225C00000000010422600000000034
+:1002C0000104226400000000010422680000000014
+:1002D0000104226C000000000104227000000000F4
+:1002E00001042274000000000104227800000000D4
+:1002F0000104227C000000000C042000000003E840
+:100300000A042000000000010B0420000000000A85
+:1003100002050044000000200205004800000032F1
+:10032000020500900215002002050094021500202D
+:1003300002050098000000300205009C0810000033
+:10034000020500A000000033020500A400000030F8
+:10035000020500A800000031020500AC0000000208
+:10036000020500B000000005020500B40000000610
+:10037000020500B800000002020500BC00000002F7
+:10038000020500C000000000020500C400000005D6
+:10039000020500C800000002020500CC00000002B7
+:1003A000020500D000000002020500D40000000198
+:1003B00002050114000000010205011C00000001FB
+:1003C00002050120000000020205020400000001F5
+:1003D0000205020C0000004002050210000000406F
+:1003E0000205021C0000002002050220000000138C
+:1003F0000205022400000020060502400000000A59
+:1004000004050280002000000205005000000007E3
+:100410000205005400000007020500580000000813
+:100420000205005C000000080205006000000001F9
+:100430000605006400000003020500D80000000665
+:100440000205000400000001020500080000000190
+:100450000205000C00000001020500100000000170
+:100460000205001400000001020500180000000150
+:100470000205001C00000001020500200000000130
+:100480000205002400000001020500280000000110
+:100490000205002C000000010205003000000001F0
+:1004A00002050034000000010205003800000001D0
+:1004B0000205003C000000010205004000000001B0
+:1004C000020500E00000000D020500E80000000742
+:1004D000020500F000000007020500F80000000718
+:1004E000020500E40000002D020500EC00000027DA
+:1004F000020500F400000027020500FC00000027B0
+:10050000020500E00000001D020500E800000017E1
+:10051000020500F000000017020500F800000017B7
+:10052000020500E40000003D020500EC0000003779
+:10053000020500F400000037020500FC000000374F
+:10054000020500E00000004D020500E80000004741
+:10055000020500F000000047020500F80000004717
+:10056000020500E40000006D020500EC00000067D9
+:10057000020500F400000067020500FC00000067AF
+:10058000020500E00000005D020500E800000057E1
+:10059000020500F000000057020500F800000057B7
+:1005A000020500E40000007D020500EC0000007779
+:1005B000020500F400000077020500FC000000774F
+:1005C0000406100002000020020600DC000000010A
+:1005D000010600D80000000004060200000302200B
+:1005E000020600DC00000000010600B80000000068
+:1005F000010600C800000000010600BC0000000069
+:10060000010600CC000000000718040000A900004B
+:10061000081807C800070223071C00002C2D000043
+:10062000071C800038A20B0C071D000028EF1935AD
+:10063000081D681052FE022501180000000000008D
+:10064000011800040000000001180008000000006C
+:100650000118000C0000000001180010000000004C
+:100660000118001400000000021800200000000122
+:1006700002180024000000020218002800000003F5
+:100680000218002C000000000218003000000004D6
+:1006900002180034000000010218003800000000B9
+:1006A0000218003C00000001021800400000000495
+:1006B0000218004400000000021800480000000179
+:1006C0000218004C00000003021800500000000057
+:1006D0000218005400000001021800580000000435
+:1006E0000218005C00000000021800600000000119
+:1006F00002180064000000030218006800000000F7
+:100700000218006C000000010218007000000004D4
+:1007100002180074000000000218007800000004B5
+:100720000218007C00000003061800800000000290
+:10073000021800A400003FFF021800A8000003FFF9
+:100740000218022400000000021802340000000019
+:100750000218024C00000000021802E4000000FF32
+:100760000618100000000400021B8BC000000001EE
+:10077000021B800000000034021B804000000018B3
+:10078000021B80800000000C021B80C000000020C3
+:100790000C1B83000007A1200A1B83000000013806
+:1007A0000B1B830000001388021B83C0000001F4B0
+:1007B000021B1480000000010A1B148000000000CE
+:1007C000061A1000000003B3041A1ECC0001022711
+:1007D000061AA020000000C8061AA00000000002AF
+:1007E000021A1ED000000000061A1ED800000006E3
+:1007F000061A36E800000004061A36E0000000027F
+:10080000061A500000000002061A500800000004FA
+:10081000061A501800000004061A502800000004B0
+:10082000061A503800000004061A50480000000460
+:10083000061A505800000004061A50680000000410
+:10084000061A507800000002041A404000020228F4
+:10085000061A400000000002061A400800000002CC
+:10086000041A62C00020022A061AD1000000000209
+:10087000061A200000000124061AB000000000281B
+:10088000061AB1400000000C061A330000000014E4
+:10089000061A33A000000068061A81080000000252
+:1008A000061AD1C800000002061AD1D800000020A4
+:1008B000061A249000000124061AB0A000000028A7
+:1008C000061AB1700000000C061A33500000001424
+:1008D000061A354000000068061A81100000000268
+:1008E000061AD1D000000002061AD25800000020DB
+:1008F000021A292000000000061A30000000000241
+:10090000041A30080005024A061A301C00000009CB
+:10091000061A320000000008061A5000000000020B
+:10092000061A508000000012061A40000000000263
+:10093000061AD0C000000002021A2924000000009C
+:10094000061A304000000002041A30480005024F29
+:10095000061A305C00000009061A32200000000868
+:10096000061A501000000002061A50C800000012BB
+:10097000061A400800000002061AD0C80000000253
+:10098000021A292800000000061A30800000000228
+:10099000041A308800050254061A309C0000000931
+:1009A000061A324000000008061A5020000000021B
+:1009B000061A511000000012041A401000020259D9
+:1009C000061AD0D000000002021A292C00000000F4
+:1009D000061A30C000000002041A30C80005025B8D
+:1009E000061A30DC00000009061A32600000000818
+:1009F000061A503000000002061A5158000000127A
+:100A0000041A401800020260061AD0D80000000242
+:100A1000021A293000000000061A3100000000020E
+:100A2000041A310800050262061A311C0000000990
+:100A3000061A328000000008061A5040000000022A
+:100A4000061A51A000000012041A4020000202679A
+:100A5000061AD0E000000002021A2934000000004B
+:100A6000061A314000000002041A314800050269EC
+:100A7000061A315C00000009061A32A000000008C6
+:100A8000061A505000000002061A51E80000001239
+:100A9000041A40280002026E061AD0E80000000284
+:100AA000021A293800000000061A318000000002F6
+:100AB000041A318800050270061A319C00000009F2
+:100AC000061A32C000000008061A5060000000023A
+:100AD000061A523000000012041A4030000202755B
+:100AE000061AD0F000000002021A293C00000000A3
+:100AF000061A31C000000002041A31C8000502774E
+:100B0000061A31DC00000009061A32E00000000875
+:100B1000061A507000000002061A527800000012F7
+:100B2000041A40380002027C061AD0F800000002C5
+:100B30000200A294071D29110200A29800000000E3
+:100B40000200A29C009C04240200A2A0000000005D
+:100B50000200A2A4000002090200A270000000002E
+:100B60000200A274000000000200A2700000000059
+:100B70000200A274000000000200A2700000000049
+:100B80000200A274000000000200A2700000000039
+:100B90000200A27400000000020100B40000000185
+:100BA000020100B800000001020100DC00000001A9
+:100BB0000201010000000001020101040000000127
+:100BC0000201007C003000000201008400000028C7
+:100BD0000201008C0000000002010130000000044E
+:100BE0000201025C00000001020103280000000075
+:100BF0000201607000000007020160800000000137
+:100C00000201055400000030020100C40000000190
+:100C1000020100CC00000001020100F80000000108
+:100C2000020100F00000000102010080003000001D
+:100C3000020100880000002802010090000000006E
+:100C40000201013400000004020102DC0000000186
+:100C50000201032C00000000020160740000000784
+:100C60000201608400000001020105640000003000
+:100C7000020100C800000001020100D000000001D4
+:100C8000020100FC00000001020100F4000000016C
+:100C9000020C100000000020020C200800000211CD
+:100CA000020C200C00000200020C201000000204C4
+:100CB000020C201C0000FFFF020C20200000FFFFA0
+:100CC000020C20240000FFFF020C20280000FFFF80
+:100CD000060C203800000002020C20400000003406
+:100CE000020C204400000035020C204800000020C7
+:100CF000020C204C00000021020C205000000022B9
+:100D0000020C205400000023020C20580000002494
+:100D1000020C205C00000025020C20600000002670
+:100D2000020C206400000027020C2068000000284C
+:100D3000020C206C00000029020C20700000002A28
+:100D4000020C20740000002B060C207800000056D6
+:100D5000020C21D000000001020C21D4000000018F
+:100D6000020C21D800000001020C21DC000000016F
+:100D7000020C21E000000001020C21E4000000014F
+:100D8000020C21E800000001020C21EC000000012F
+:100D9000020C21F000000001020C21F4000000010F
+:100DA000060C21F800000010020C223807FFFFFF9C
+:100DB000020C223C0000003F020C224007FFFFFF14
+:100DC000020C22440000000F010C22480000000029
+:100DD000010C224C00000000010C22500000000019
+:100DE000010C225400000000010C225800000000F9
+:100DF000010C225C00000000010C226000000000D9
+:100E0000010C226400000000010C226800000000B8
+:100E1000010C226C00000000010C22700000000098
+:100E2000010C227400000000010C22780000000078
+:100E3000010C227C000000000C0C2000000003E8E4
+:100E40000A0C2000000000010B0C20000000000A2A
+:100E5000020C400800000411020C400C00000400C9
+:100E6000020C401000000404020C40140000042195
+:100E7000020C401C0000FFFF020C40200000FFFF9E
+:100E8000020C40240000FFFF020C40280000FFFF7E
+:100E9000020C403800000046020C403C00000005F7
+:100EA000060C404000000002020C40480000000A0E
+:100EB000020C404C000000F0060C40500000001FE7
+:100EC000020C40CC00000001060C40D00000003AAB
+:100ED000020C41B800000001060C41BC00000003F8
+:100EE000020C41C800000001020C41CC00000001CE
+:100EF000060C41D00000001A020C423807FFFFFF29
+:100F0000020C423C0000003F020C424007FFFFFF82
+:100F1000020C42440000000F010C42480000000097
+:100F2000010C424C00000000010C42500000000087
+:100F3000010C425400000000010C42580000000067
+:100F4000010C425C00000000010C42600000000047
+:100F5000010C426400000000010C42680000000027
+:100F6000010C426C00000000010C42700000000007
+:100F7000010C427400000000010C427800000000E7
+:100F8000010C427C00000000010C428000000000C7
+:100F90000C0C4000000003E80A0C400000000001B7
+:100FA0000B0C40000000000A020D0044000000325B
+:100FB000020D008C02150020020D00900215002089
+:100FC000020D009408100000020D0098000000338C
+:100FD000020D009C00000002020D00A000000000B5
+:100FE000020D00A400000005020D00A8000000058D
+:100FF000060D00AC00000002020D00B4000000026B
+:10100000020D00B800000003020D00BC0000000249
+:10101000020D00C000000001020D00C80000000227
+:10102000020D00CC00000002020D010800000001CA
+:10103000020D015C00000001020D016400000001CE
+:10104000020D016800000002020D02040000000110
+:10105000020D020C00000020020D021000000040F2
+:10106000020D021400000040020D022000000003E7
+:10107000020D022400000018060D0280000000127C
+:10108000040D03000024027E020D004C000000014C
+:10109000020D005000000002020D00540000000884
+:1010A000020D005800000008060D005C000000045E
+:1010B000020D00C400000004020D00040000000145
+:1010C000020D000800000001020D000C00000001EC
+:1010D000020D001000000001020D001400000001CC
+:1010E000020D001800000001020D001C00000001AC
+:1010F000020D002000000001020D0024000000018C
+:10110000020D002800000001020D002C000000016B
+:10111000020D003000000001020D0034000000014B
+:10112000020D003800000001020D003C000000012B
+:10113000020D011400000009020D011C0000000A4C
+:10114000020D012400000007020D012C0000000721
+:10115000020D01340000000C020D013C0000000BE8
+:10116000020D014400000007020D011800000029D3
+:10117000020D01200000002A020D012800000027B6
+:10118000020D013000000027020D01380000002C84
+:10119000020D01400000002B020D01480000002755
+:1011A000020D011400000019020D011C0000001ABC
+:1011B000020D012400000017020D012C0000001791
+:1011C000020D01340000001C020D013C0000001B58
+:1011D000020D014400000017020D01180000003943
+:1011E000020D01200000003A020D01280000003726
+:1011F000020D013000000037020D01380000003CF4
+:10120000020D01400000003B020D014800000037C4
+:10121000020D011400000049020D011C0000004AEB
+:10122000020D012400000047020D012C00000047C0
+:10123000020D01340000004C020D013C0000004B87
+:10124000020D014400000047020D01180000006972
+:10125000020D01200000006A020D01280000006755
+:10126000020D013000000067020D01380000006C23
+:10127000020D01400000006B020D014800000067F4
+:10128000020D011400000059020D011C0000005A5B
+:10129000020D012400000057020D012C0000005730
+:1012A000020D01340000005C020D013C0000005BF7
+:1012B000020D014400000057020D011800000079E2
+:1012C000020D01200000007A020D012800000077C5
+:1012D000020D013000000077020D01380000007C93
+:1012E000020D01400000007B020D01480000007764
+:1012F000020E004C00000032020E00940215002085
+:10130000020E009802150020020E009C0000003022
+:10131000020E00A008100000020E00A4000000331E
+:10132000020E00A800000030020E00AC00000031E8
+:10133000020E00B000000002020E00B40000000423
+:10134000020E00B800000000020E00BC0000000207
+:10135000020E00C000000002020E00C400000000E7
+:10136000020E00C800000002020E00CC00000007C0
+:10137000020E00D000000002020E00D400000002A5
+:10138000020E00D800000001020E00E4000000017F
+:10139000020E014400000001020E014C0000000199
+:1013A000020E015000000002020E020400000001C3
+:1013B000020E020C00000040020E0210000000406D
+:1013C000020E021C00000004020E02200000002099
+:1013D000020E02240000000E020E02280000001B74
+:1013E000060E030000000012040E0280001B02A281
+:1013F000020E00540000000C020E0058000000070E
+:10140000020E005C0000000F020E006000000010E1
+:10141000020E00640000000B060E006800000003CE
+:10142000020E00DC00000003020E000400000001B8
+:10143000020E000800000001020E000C0000000176
+:10144000020E001000000001020E00140000000156
+:10145000020E001800000001020E001C0000000136
+:10146000020E002000000001020E00240000000116
+:10147000020E002800000001020E002C00000001F6
+:10148000020E003000000001020E003400000001D6
+:10149000020E003800000001020E003C00000001B6
+:1014A000020E004000000001020E00440000000196
+:1014B000020E01100000000F020E01180000000EC5
+:1014C000020E012000000000020E012800000000B2
+:1014D000020E01140000002F020E011C0000002E5D
+:1014E000020E012400000000020E012C000000008A
+:1014F000020E01100000001F020E01180000001E65
+:10150000020E012000000000020E01280000000071
+:10151000020E01140000003F020E011C0000003EFC
+:10152000020E012400000000020E012C0000000049
+:10153000020E01100000004F020E01180000004EC4
+:10154000020E012000000000020E01280000000031
+:10155000020E01140000006F020E011C0000006E5C
+:10156000020E012400000000020E012C0000000009
+:10157000020E01100000005F020E01180000005E64
+:10158000020E012000000000020E012800000000F1
+:10159000020E01140000007F020E011C0000007EFC
+:1015A000020E012400000000020E012C00000000C9
+:1015B0000730040000E10000083007D8000502BD34
+:1015C000073400002ECA000007348000311A0BB324
+:1015D00007350000368B17FA0735800039C6259D80
+:1015E0000736000013D5340F0836307039F202BFC9
+:1015F0000130000000000000013000040000000085
+:1016000001300008000000000130000C0000000064
+:101610000130001000000000013000140000000044
+:10162000023000200000000102300024000000020F
+:1016300002300028000000030230002C00000000EF
+:1016400002300030000000040230003400000001CD
+:1016500002300038000000000230003C00000001B1
+:10166000023000400000000402300044000000008E
+:1016700002300048000000010230004C000000036E
+:101680000230005000000000023000540000000151
+:1016900002300058000000040230005C000000002E
+:1016A000023000600000000102300064000000030E
+:1016B00002300068000000000230006C00000001F1
+:1016C00002300070000000040230007400000000CE
+:1016D00002300078000000040230007C00000003AB
+:1016E0000630008000000002023000A400003FFF2E
+:1016F000023000A8000003FF0230022400000000B6
+:1017000002300234000000000230024C00000000F1
+:10171000023002E40000FFFF063020000000080055
+:1017200002338BC000000001023380000000001A69
+:10173000023380400000004E023380800000001021
+:10174000023380C0000000200C3383000007A1207A
+:101750000A338300000001380B3383000000138834
+:10176000023383C0000001F40C3383801DCD65007B
+:101770000A3383800004C4B40B338380004C4B4095
+:101780000A331480000000000233148000000001BE
+:10179000063220000000010206328020000000C84E
+:1017A000063280000000000206323DA8000000045E
+:1017B00006323D800000000904323DA4000102C150
+:1017C00006323D00000000200632500000000400F8
+:1017D000063240000000000204324008000102C24C
+:1017E0000632400C00000003063240D80000000220
+:1017F00006326B680000000204326B70000202C304
+:1018000006326B1000000002043274C0000202C5F0
+:101810000632DA40000000020632E0000000080054
+:10182000023308000100000004330C00001002C75E
+:10183000023308000000000004330C40001002D7FF
+:1018400006322450000000B406322AD00000000204
+:1018500006321000000001A002323DB80000000076
+:101860000632500000000020063251000000002027
+:101870000632520000000020063253000000002013
+:1018800006325400000000200632550000000020FF
+:1018900006325600000000200632570000000020EB
+:1018A00006325800000000200632590000000020D7
+:1018B00006325A000000002006325B0000000020C3
+:1018C00006325C000000002006325D0000000020AF
+:1018D00006325E000000002006325F00000000209B
+:1018E00006326B780000005206326E080000000CD1
+:1018F0000632DA880000000206322720000000B419
+:1019000006322AD80000000206321680000001A02C
+:1019100002323DBC00000000063250800000002072
+:101920000632518000000020063252800000002064
+:101930000632538000000020063254800000002050
+:10194000063255800000002006325680000000203C
+:101950000632578000000020063258800000002028
+:10196000063259800000002006325A800000002014
+:1019700006325B800000002006325C800000002000
+:1019800006325D800000002006325E8000000020EC
+:1019900006325F800000002006326CC0000000525A
+:1019A00006326E380000000C0632DA9000000002A9
+:1019B00002322A3000000000063240180000000207
+:1019C0000632D0000000000602322A340000000077
+:1019D00006324028000000020632D018000000063F
+:1019E00002322A38000000000632403800000002AF
+:1019F0000632D0300000000602322A3C000000000F
+:101A000006324048000000020632D04800000006BE
+:101A100002322A4000000000063240580000000256
+:101A20000632D0600000000602322A4400000000A6
+:101A300006324068000000020632D078000000063E
+:101A400002322A48000000000632407800000002FE
+:101A50000632D0900000000602322A4C000000003E
+:101A600006324088000000020632D0A800000006BE
+:101A7000072004000093000008200780001002E700
+:101A8000072400002ADF0000072480002E050AB882
+:101A90000824E4A061D202E9012000000000000057
+:101AA00001200004000000000120000800000000E8
+:101AB0000120000C000000000120001000000000C8
+:101AC000012000140000000002200020000000019E
+:101AD0000220002400000002022000280000000371
+:101AE0000220002C00000000022000300000000452
+:101AF0000220003400000001022000380000000035
+:101B00000220003C00000001022000400000000410
+:101B100002200044000000000220004800000001F4
+:101B20000220004C000000030220005000000000D2
+:101B300002200054000000010220005800000004B0
+:101B40000220005C00000000022000600000000194
+:101B50000220006400000003022000680000000072
+:101B60000220006C00000001022000700000000450
+:101B70000220007400000000022000780000000431
+:101B80000220007C0000000306200080000000020C
+:101B9000022000A400003FFF022000A8000003FF75
+:101BA0000220022400000000022002340000000095
+:101BB0000220024C00000000022002E40000FFFFAF
+:101BC000062020000000080002238BC00000000156
+:101BD0000223800000000010022380400000001259
+:101BE0000223808000000030022380C00000000E2D
+:101BF000022383C0000001F40223148000000001CE
+:101C00000A23148000000000062210000000004299
+:101C100006227020000000C80622700000000002AA
+:101C2000022211E80000000006223000000000C07F
+:101C3000062240700000008006225280000000044E
+:101C40000622670000000100062290000000040048
+:101C500004226B08002002EB02230800013FFFFF73
+:101C600004230C000010030B0223080000000000F6
+:101C700004230C400010031B06228100000000A07A
+:101C8000062286000000004006228C000000003C76
+:101C90000622B0000000020006228800000000803A
+:101CA00006228DE00000003C0622404000000006B5
+:101CB00006228380000000A006228700000000406A
+:101CC00006228CF00000003C0622B8000000020052
+:101CD00006228A000000008006228ED00000003C10
+:101CE000062240580000000606228000000000087E
+:101CF000022211480000000006223300000000020A
+:101D0000062260400000003006228020000000080B
+:101D10000222114C000000000622330800000002DD
+:101D2000062261000000003006228040000000080A
+:101D300002221150000000000622331000000002B1
+:101D4000062261C00000003006228060000000080A
+:101D50000222115400000000062233180000000285
+:101D60000622628000000030062280800000000809
+:101D70000222115800000000062233200000000259
+:101D80000622634000000030062280A00000000808
+:101D90000222115C0000000006223328000000022D
+:101DA0000622640000000030062280C00000000807
+:101DB0000222116000000000062233300000000201
+:101DC000062264C000000030062280E00000000807
+:101DD00002221164000000000622333800000002D5
+:101DE0000622658000000030021610000000002866
+:101DF00002170008000000020217002C0000000378
+:101E00000217003C00000004021700440000000814
+:101E100002170048000000020217004C000000906A
+:101E2000021700500000009002170054008000903C
+:101E30000217005808140000021700600000008A12
+:101E40000217006400000080021700680000008193
+:101E50000217006C000000800217007000000006EE
+:101E600002170078000007D00217007C0000076C02
+:101E700002170038007C1004021700040000000F55
+:101E80000616402400000002021640700000001CEC
+:101E90000216420800000001021642100000000174
+:101EA0000216422000000001021642280000000134
+:101EB0000216423000000001021642380000000104
+:101EC00002164260000000020C16401C0003D09075
+:101ED0000A16401C0000009C0B16401C000009C4A0
+:101EE0000216403000000008021640340000000CCA
+:101EF0000216403800000010021640440000002086
+:101F00000216400000000001021640D80000000147
+:101F100002164008000000010216400C00000001FB
+:101F200002164010000000010216424000000000AE
+:101F3000021642480000000006164270000000022F
+:101F40000216425000000000021642580000000035
+:101F500006164280000000020216600800000424F9
+:101F60000216600C00000410021660100000041439
+:101F70000216601C0000FFFF021660200000FFFF39
+:101F8000021660240000FFFF021660280000FFFF19
+:101F900002166038000000200216603C000000209D
+:101FA0000216604000000034021660440000003554
+:101FB00002166048000000230216604C0000002456
+:101FC0000216605000000025021660540000002632
+:101FD00002166058000000270216605C000000290D
+:101FE000021660600000002A021660640000002BE8
+:101FF000021660680000002C0216606C0000002DC4
+:102000000616607000000052021661B80000000160
+:10201000061661BC0000001F0216623807FFFFFFB2
+:102020000216623C0000003F0216624007FFFFFFFD
+:10203000021662440000000F011662480000000012
+:102040000116624C00000000011662500000000002
+:1020500001166254000000000116625800000000E2
+:102060000116625C000000000116626000000000C2
+:1020700001166264000000000116626800000000A2
+:102080000116626C00000000011662700000000082
+:102090000116627400000000011662780000000062
+:1020A0000116627C000000000C166000000003E8CE
+:1020B0000A166000000000010B1660000000000A14
+:1020C0000216804000000006021680440000000551
+:1020D000021680480000000A0216804C000000052D
+:1020E0000216805400000002021680CC000000049A
+:1020F000021680D000000004021680D40000000404
+:10210000021680D800000004021680DC00000004E3
+:10211000021680E000000004021680E400000004C3
+:10212000021680E800000004021688040000000483
+:10213000021680300000007C021680340000003D52
+:10214000021680380000003F0216803C0000009C10
+:10215000021680F000000007061680F4000000055B
+:102160000216880C0101010102168108000000001E
+:102170000216810C00000004021681100000000409
+:1021800002168114000000020216881008012004C3
+:1021900002168118000000050216811C00000005CF
+:1021A00002168120000000050216812400000005AF
+:1021B0000216882C20081001021681280000000851
+:1021C0000216812C00000006021681300000000774
+:1021D000021681340000000002168830010101203F
+:1021E000061681380000000402168834010101013E
+:1021F00002168148000000000216814C0000000415
+:1022000002168150000000040216815400000002F2
+:1022100002168838080120040216815800000005C3
+:102220000216815C000000050216816000000005B6
+:1022300002168164000000050216883C2008100187
+:1022400002168168000000080216816C000000067A
+:102250000216817000000007021681740000000160
+:102260000216884001010120021681780000000159
+:102270000216817C0000000102168180000000012E
+:102280000216818400000001021688440101010148
+:1022900002168188000000010216818C00000004F3
+:1022A00002168190000000040216819400000002D2
+:1022B00002168848080120040216819800000005D3
+:1022C0000216819C00000005021681A00000000596
+:1022D000021681A4000000050216881420081001CF
+:1022E000021681A800000008021681AC000000065A
+:1022F000021681B000000007021681B40000000140
+:102300000216881801010120021681B800000001A0
+:10231000021681BC00000001021681C0000000010D
+:10232000021681C4000000010216881C010101018F
+:10233000021681C800000001021681CC00000004D2
+:10234000021681D000000004021681D400000002B1
+:102350000216882008012004021681D8000000051A
+:10236000021681DC00000005021681E00000000575
+:10237000021681E4000000050216882420081001DE
+:10238000021681E800000008021681EC0000000639
+:10239000021681F0000000070216E40C00000000A5
+:1023A00002168828010101200616E410000000042E
+:1023B0000216E000010101010216E4200000000005
+:1023C0000216E424000000040216E42800000004C1
+:1023D0000216E42C000000020216E00408012004AA
+:1023E0000216E430000000050216E4340000000587
+:1023F0000216E438000000050216E43C0000000567
+:102400000216E008200810010216E440000000084F
+:102410000216E444000000060216E448000000072B
+:102420000216E44C000000000216E00C010101203D
+:102430000616E450000000040216E010010101013C
+:102440000216E460000000000216E46400000004CC
+:102450000216E468000000040216E46C00000002AA
+:102460000216E014080120040216E47000000005C2
+:102470000216E474000000050216E478000000056E
+:102480000216E47C000000050216E0182008100186
+:102490000216E480000000080216E4840000000632
+:1024A0000216E488000000070216E48C0000000118
+:1024B0000216E01C010101200216E4900000000158
+:1024C0000216E494000000010216E49800000001E6
+:1024D0000216E49C000000010216E0200101010147
+:1024E0000216E4A0000000010216E4A400000004AB
+:1024F0000216E4A8000000040216E4AC000000028A
+:102500000216E024080120040216E4B000000005D1
+:102510000216E4B4000000050216E4B8000000054D
+:102520000216E4BC000000050216E0282008100195
+:102530000216E4C0000000080216E4C40000000611
+:102540000216E4C8000000070216E4CC00000001F7
+:102550000216E02C010101200216E4D00000000167
+:102560000216E4D4000000010216E4D800000001C5
+:102570000216E4DC000000010216E0300101010156
+:102580000216E4E0000000010216E4E4000000048A
+:102590000216E4E8000000040216E4EC0000000269
+:1025A0000216E034080120040216E4F000000005E1
+:1025B0000216E4F4000000050216E4F8000000052D
+:1025C0000216E4FC000000050216E03820081001A5
+:1025D0000216E500000000080216E50400000006EF
+:1025E0000216E508000000070216E03C0101012088
+:1025F00002168240003F003F0216824400000000A5
+:102600000216E524003F003F0216E5280000000006
+:1026100002168248000000000216824C003F003F74
+:102620000216E52C000000000216E530003F003FD6
+:1026300002168250010001000216825401000100BE
+:102640000216E534010001000216E5380100010020
+:1026500006168258000000020216E53C0000000049
+:102660000216E540000000000216826000C000C0B3
+:102670000216826400C000C00216E54400C000C01B
+:102680000216E54800C000C0021682681E001E0047
+:102690000216826C1E001E000216E54C1E001E0073
+:1026A0000216E5501E001E00021682704000400017
+:1026B00002168274400040000216E55440004000BB
+:1026C0000216E55840004000021682788000800023
+:1026D0000216827C800080000216E55C800080008B
+:1026E0000216E56080008000021682802000200033
+:1026F00002168284200020000216E56420002000DB
+:102700000216E568200020000616828800000002FC
+:102710000216E56C000000000216E57000000000E3
+:102720000216829000000000021682940000000051
+:102730000216E574000000000216E57800000000B3
+:1027400002168298000000000216829C0000000021
+:102750000216E57C000000000216E5800000000083
+:10276000021682A000000000021682A400000001F0
+:10277000061682A80000000A021681F400000C0868
+:10278000021681F800000040021681FC00000100E2
+:1027900002168200000000200216820400000017CA
+:1027A00002168208000000800216820C000002005F
+:1027B00002168210000000000216821801FF01FFBD
+:1027C0000216821401FF01FF0216E51001FF01FF4E
+:1027D0000216E50C01FF01FF0216823C0000001307
+:1027E000021680900000013F021680600000014048
+:1027F0000216806400000140061680680000000296
+:1028000002168070000000C00616807400000007E9
+:102810000216809C00000048021680A000000048BC
+:10282000061680A400000002021680AC00000048DA
+:10283000061680B0000000070216823800008000F3
+:1028400002168234000025E40216809400007FFF07
+:1028500002168220000F000F0216821C000F000FCC
+:102860000216E518000F000F0216E514000F000F06
+:10287000021682280000000002168224FFFFFFFFDC
+:102880000216E520000000000216E51CFFFFFFFF16
+:102890000216E6BC000000000216E6C000000002BE
+:1028A0000216E6C4000000010216E6C8000000039C
+:1028B0000216E6CC000000040216E6D00000000676
+:1028C0000216E6D4000000050216E6D80000000754
+:1028D000021680EC000000FF02140000000000015E
+:1028E0000214000C0000000102140040000000016E
+:1028F0000214004400007FFF0214000C00000000DE
+:1029000002140000000000000214006C000000002F
+:102910000214000400000001021400300000000155
+:1029200002140004000000000214005C000000001B
+:10293000021400080000000102140034000000012D
+:1029400002140008000000000214006000000000F3
+:102950000202005800000032020200A0031500200D
+:10296000020200A403150020020200A801000030AA
+:10297000020200AC08100000020200B000000033A8
+:10298000020200B400000030020200B80000003172
+:10299000020200BC00000003020200C000000006AA
+:1029A000020200C400000003020200C8000000038D
+:1029B000020200CC00000002020200D00000000071
+:1029C000020200D400000002020200DC000000004D
+:1029D000020200E000000006020200E40000000421
+:1029E000020200E800000002020200EC0000000207
+:1029F000020200F000000001020200FC00000006DC
+:102A00000202012000000000020201340000000266
+:102A1000020201B0000000010202020C00000001ED
+:102A2000020202140000000102020218000000026B
+:102A300002020404000000010202040C0000004035
+:102A400002020410000000400202041C0000000406
+:102A50000202042000000020020204240000000200
+:102A600002020428000000200602050000000012F7
+:102A700004020480001F032B020200600000000F0C
+:102A80000202006400000007020200680000000B60
+:102A90000202006C0000000E020200700000000E36
+:102AA0000602007400000003020200F400000004AB
+:102AB0000202000400000001020200080000000100
+:102AC0000202000C000000010202001000000001E0
+:102AD00002020014000000010202001800000001C0
+:102AE0000202001C000000010202002000000001A0
+:102AF0000202002400000001020200280000000180
+:102B00000202002C0000000102020030000000015F
+:102B1000020200340000000102020038000000013F
+:102B20000202003C0000000102020040000000011F
+:102B300002020044000000010202004800000001FF
+:102B40000202004C000000010202005000000001DF
+:102B500002020108000000C8020201180000000281
+:102B6000020201C400000000020201CC00000000CB
+:102B7000020201D400000002020201DC0000000297
+:102B8000020201E4000000FF020201EC000000FF6D
+:102B900002020100000000000202010C000000C857
+:102BA0000202011C00000002020201C80000000035
+:102BB000020201D000000000020201D80000000261
+:102BC000020201E000000002020201E8000000FF32
+:102BD000020201F0000000FF0202010400000000F8
+:102BE00002020108000000C80202011800000002F1
+:102BF000020201C400000000020201CC000000003B
+:102C0000020201D400000002020201DC0000000206
+:102C1000020201E4000000FF020201EC000000FFDC
+:102C200002020100000000000202010C000000C8C6
+:102C30000202011C00000002020201C800000000A4
+:102C4000020201D000000000020201D800000002D0
+:102C5000020201E000000002020201E8000000FFA1
+:102C6000020201F0000000FF020201040000000067
+:102C700002020108000000C8020201180000000260
+:102C8000020201C400000000020201CC00000000AA
+:102C9000020201D400000002020201DC0000000276
+:102CA000020201E4000000FF020201EC000000FF4C
+:102CB00002020100000000000202010C000000C836
+:102CC0000202011C00000002020201C80000000014
+:102CD000020201D000000000020201D80000000240
+:102CE000020201E000000002020201E8000000FF11
+:102CF000020201F0000000FF0202010400000000D7
+:102D000002020108000000C80202011800000002CF
+:102D1000020201C400000000020201CC0000000019
+:102D2000020201D400000002020201DC00000002E5
+:102D3000020201E4000000FF020201EC000000FFBB
+:102D400002020100000000000202010C000000C8A5
+:102D50000202011C00000002020201C80000000083
+:102D6000020201D000000000020201D800000002AF
+:102D7000020201E000000002020201E8000000FF80
+:102D8000020201F0000000FF020201040000000046
+:102D90000728040000C00000082807A8000B034A09
+:102DA000072C000032FD0000072C8000357E0CC08F
+:102DB000072D00003AE41A20072D800039CF28DAC9
+:102DC000072E00001C3C374E082E3710391E034CCE
+:102DD000012800000000000001280004000000009D
+:102DE00001280008000000000128000C000000007D
+:102DF000012800100000000001280014000000005D
+:102E00000228002000000001022800240000000227
+:102E100002280028000000030228002C0000000007
+:102E200002280030000000040228003400000001E5
+:102E300002280038000000000228003C00000001C9
+:102E400002280040000000040228004400000000A6
+:102E500002280048000000010228004C0000000386
+:102E60000228005000000000022800540000000169
+:102E700002280058000000040228005C0000000046
+:102E80000228006000000001022800640000000326
+:102E900002280068000000000228006C0000000109
+:102EA00002280070000000040228007400000000E6
+:102EB00002280078000000040228007C00000003C3
+:102EC0000628008000000002022800A400003FFF46
+:102ED000022800A8000003FF0228022400000000CE
+:102EE00002280234000000000228024C000000000A
+:102EF000022802E40000FFFF06282000000008006E
+:102F0000022B8BC000000001022B8000000000009B
+:102F1000022B804000000018022B80800000000C73
+:102F2000022B80C0000000660C2B83000007A1204C
+:102F30000A2B8300000001380B2B8300000013884C
+:102F4000022B83C0000001F40C2B8340000001F42D
+:102F50000A2B8340000000000B2B8340000000057B
+:102F60000A2B83800004C4B40C2B83801DCD650024
+:102F70000A2B1480000000000B2B8380004C4B4078
+:102F8000022B148000000001062A29C8000000045A
+:102F9000042A29D80002034E062A20800000004897
+:102FA000062A9020000000C8062A900000000002B7
+:102FB000062A21A800000086062A20000000002022
+:102FC000022A23C800000000042A23D00002035074
+:102FD000042A249800040352022A2C500000000006
+:102FE000022A2C1000000000042A2C0800020356BC
+:102FF000042A300000020358062A300800000100AD
+:10300000062A404000000010042A40000010035A25
+:10301000062A6AC000000002062A6B0000000004B5
+:10302000042A84080002036A022B08000000000042
+:10303000042B0C000010036C022B080001000000A0
+:10304000042B0C400008037C022B08000200000047
+:10305000042B0C6000080384062AC000000000D87E
+:10306000062A24A800000014062A2548000000248F
+:10307000062A266800000024062A2788000000246B
+:10308000062A28A800000024062AA0000000002824
+:10309000062AA1400000000C042A29E00002038C4B
+:1030A000062A502000000002062A503000000002CC
+:1030B000062A500000000002062A501000000002FC
+:1030C000022A520800000001042A6AC80002038E86
+:1030D000062A6B1000000042062A6D200000000442
+:1030E000062ABCD000000002062AC360000000D8F7
+:1030F000062A24F800000014062A25D8000000241F
+:10310000062A26F800000024062A281800000024B9
+:10311000062A293800000024062AA0A00000002862
+:10312000062AA1700000000C042A29E8000203907E
+:10313000062A502800000002062A5038000000022B
+:10314000062A500800000002062A5018000000025B
+:10315000022A520C00000001042A6AD000020392E5
+:10316000062A6C1800000042062A6D300000000498
+:10317000062ABCD800000002022AC6C000000000D7
+:10318000042A29F000100394062A50480000000E7B
+:10319000062AB00000000006022AC6C40000000093
+:1031A000042A2A30001003A4062A50800000000ED2
+:1031B000062AB01800000006022AC6C80000000057
+:1031C000042A2A70001003B4062A50B80000000E2A
+:1031D000062AB03000000006022AC6CC000000001B
+:1031E000042A2AB0001003C4062A50F00000000E82
+:1031F000062AB04800000006022AC6D000000000DF
+:10320000042A2AF0001003D4062A51280000000ED8
+:10321000062AB06000000006022AC6D400000000A2
+:10322000042A2B30001003E4062A51600000000E2F
+:10323000062AB07800000006022AC6D80000000066
+:10324000042A2B70001003F4062A51980000000E87
+:10325000062AB09000000006022AC6DC000000002A
+:10326000042A2BB000100404062A51D00000000EDE
+:10327000062AB0A800000006021010080000000195
+:103280000210105000000001021010000003D000D6
+:10329000021010040000003D091018000200041480
+:1032A0000910110000280614061011A000000018D3
+:1032B00006102400000000E00210201C00000000A6
+:1032C0000210202000000001021020C000000002B7
+:1032D000021020040000000102102008000000017C
+:1032E00009103C000005063C0910380000050641A5
+:1032F000091038200005064606104C0000000100A9
+:1033000002104028000000100210404400003FFF5F
+:103310000210405800280000021040840084924AA5
+:1033200002104058000000000210800000001080D1
+:10333000021080AC00000000021080380000001075
+:103340000210810000000000061081200000000231
+:1033500002108008000002B502108010000000007A
+:10336000061082000000004A021081080001FFFFE1
+:1033700006108140000000020210800000001A8048
+:103380000610900000000024061091200000004A62
+:10339000061093700000004A061095C00000004A15
+:1033A0000210800400001080021080B000000001B4
+:1033B0000210803C00000010021081040000000098
+:1033C00006108128000000020210800C000002B5E7
+:1033D0000210801400000000061084000000004A63
+:1033E0000210810C0001FFFF06108148000000025E
+:1033F0000210800400001A80061090900000002443
+:10340000061092480000004A061094980000004AF6
+:10341000061096E80000004A0210800000001080AC
+:10342000021080AC00000002021080380000001082
+:103430000210810000000000061081200000000240
+:1034400002108008000002B5021080100000000089
+:10345000061082000000004A021081080001FFFFF0
+:1034600006108140000000020210800000001A8057
+:103470000610900000000024061091200000004A71
+:10348000061093700000004A061095C00000004A24
+:103490000210800400001080021080B000000003C1
+:1034A0000210803C000000100210810400000000A7
+:1034B00006108128000000020210800C000002B5F6
+:1034C0000210801400000000061084000000004A72
+:1034D0000210810C0001FFFF06108148000000026D
+:1034E0000210800400001A80061090900000002452
+:1034F000061092480000004A061094980000004A06
+:10350000061096E80000004A0210800000001080BB
+:10351000021080AC0000000402108038000000108F
+:10352000021081000000000006108120000000024F
+:1035300002108008000002B5021080100000000098
+:10354000061082000000004A021081080001FFFFFF
+:1035500006108140000000020210800000001A8066
+:103560000610900000000024061091200000004A80
+:10357000061093700000004A061095C00000004A33
+:103580000210800400001080021080B000000005CE
+:103590000210803C000000100210810400000000B6
+:1035A00006108128000000020210800C000002B505
+:1035B0000210801400000000061084000000004A81
+:1035C0000210810C0001FFFF06108148000000027C
+:1035D0000210800400001A80061090900000002461
+:1035E000061092480000004A061094980000004A15
+:1035F000061096E80000004A0210800000001080CB
+:10360000021080AC0000000602108038000000109C
+:10361000021081000000000006108120000000025E
+:1036200002108008000002B50210801000000000A7
+:10363000061082000000004A021081080001FFFF0E
+:1036400006108140000000020210800000001A8075
+:103650000610900000000024061091200000004A8F
+:10366000061093700000004A061095C00000004A42
+:103670000210800400001080021080B000000007DB
+:103680000210803C000000100210810400000000C5
+:1036900006108128000000020210800C000002B514
+:1036A0000210801400000000061084000000004A90
+:1036B0000210810C0001FFFF06108148000000028B
+:1036C0000210800400001A80061090900000002470
+:1036D000061092480000004A061094980000004A24
+:1036E000061096E80000004A021205B00000000132
+:1036F0000212049000E383400212051400003C1003
+:103700000212066C000000010212067000000000A8
+:1037100002120494FFFFFFFF02120498FFFFFFFF55
+:103720000212049CFFFFFFFF021204A0FFFFFFFF35
+:10373000021204A4FFFFFFFF021204A8FFFFFFFF15
+:10374000021204ACFFFFFFFF021204B0FFFFFFFFF5
+:10375000021204BCFFFFFFFF021204C0FFFFFFFFC5
+:10376000021204C4FFFFFFFF021204C8FFFFFFFFA5
+:10377000021204CCFFFFFFFF021204D0FFFFFFFF85
+:10378000021204D8FFFFFFFF021204DCFFFFFFFF5D
+:10379000021204E0FFFFFFFF021204E4FFFFFFFF3D
+:1037A000021204E8FFFFFFFF021204ECFFFFFFFF1D
+:1037B000021204F0FFFFFFFF021204F4FFFFFFFFFD
+:1037C000021204F8FFFFFFFF021204FCFFFFFFFFDD
+:1037D00002120500FFFFFFFF02120504FFFFFFFFBB
+:1037E00002120508FFFFFFFF0212050CFFFFFFFF9B
+:1037F00002120510FFFFFFFF021204D4FF80200019
+:10380000021204B4F0005000021204B8F0001000DC
+:1038100002120390000000080212039C000000083E
+:10382000021203A000000008021203A4000000021C
+:10383000021203BC00000004021203C000000005D5
+:10384000021203C400000004021203D000000000B2
+:103850000212036C00000001021203680000003F26
+:10386000021201BC00000040021201C00000180852
+:10387000021201C400000803021201C8000008037C
+:10388000021201CC00000040021201D0000000032F
+:10389000021201D400000803021201D8000008033C
+:1038A000021201DC00000803021201E00001000323
+:1038B000021201E400000803021201E800000803FC
+:1038C000021201EC00000003021201F000000003EC
+:1038D000021201F400000003021201F800000003CC
+:1038E000021201FC000000030212020000000003AB
+:1038F000021202040000000302120208000000038A
+:103900000212020C00000003021202100000000369
+:103910000212021400000003021202180000000349
+:103920000212021C00000003021202200000000329
+:1039300002120224000000030212022800002403E5
+:103940000212022C0000002F0212023000000009B7
+:103950000212023400000019021202380000018431
+:103960000212023C00000183021202400000030622
+:103970000212024400000019021202480000000670
+:103980000212024C0000030602120250000003065D
+:1039900002120254000003060212025800000C86B4
+:1039A0000212025C0000030602120260000003061D
+:1039B0000212026400000006021202680000000603
+:1039C0000212026C000000060212027000000006E3
+:1039D00002120274000000060212027800000006C3
+:1039E0000212027C000000060212028000000006A3
+:1039F0000212028400000006021202880000000683
+:103A00000212028C00000006021202900000000662
+:103A10000212029400000006021202980000000642
+:103A20000212029C00000006021202A0000003061F
+:103A3000021202A400000013021202A800000006F5
+:103A4000021202B000001004021202B400001004BE
+:103A50000212032400106440021203280010644084
+:103A6000021205B400000001021201B000000001C2
+:103A70000600A000000000160200A0EC5554000053
+:103A80000200A0F0555555550200A0F40000555510
+:103A90000200A0F8F00000000200A0FC5554000055
+:103AA0000200A100555555550200A10400005555CE
+:103AB0000200A108F00000000200A18C5554000093
+:103AC0000200A190555555550200A194000055558E
+:103AD0000200A198F00000000200A19C000000007C
+:103AE0000200A1A0000100000200A1A400005014E7
+:103AF0000200A1A8000000000200A45C00000C006D
+:103B00000200A61C000000030200A06CFF5C000085
+:103B10000200A070FFF55FFF0200A0740000FFFF2D
+:103B20000200A078F00003E00200A07C000000008A
+:103B30000200A0800000A0000600A0840000000594
+:103B40000200A0980FE000000600A09C0000000703
+:103B50000200A0B8000004000600A0BC00000003A2
+:103B60000200A0C8000010000600A0CC0000000366
+:103B70000200A0D8000040000600A0DC0000000306
+:103B80000200A0E8000100000600A22C00000004D2
+:103B90000200A10CFF5C00000200A110FFF55FFF16
+:103BA0000200A1140000FFFF0200A118F00003E0D2
+:103BB0000200A11C000000000200A1200000A000E3
+:103BC0000600A124000000050200A1380FE000005B
+:103BD0000600A13C000000070200A15800000800F8
+:103BE0000600A15C000000030200A16800002000A4
+:103BF0000600A16C000000030200A1780000800014
+:103C00000600A17C000000030200A1880002000061
+:103C10000600A23C000000040000000000000000BC
+:103C20000000003100000000000000000000000063
+:103C30000000000000000000000000000000000084
+:103C40000000000000000000000000000031003211
+:103C50000000000000000000000000000000000064
+:103C60000000000000000000000000000000000054
+:103C700000000000000000000032005600000000BC
+:103C80000000000000000000000000000000000034
+:103C90000000000000000000000000000000000024
+:103CA000000000000056008C000000000000000032
+:103CB000008C009000900094009400980098009C64
+:103CC000009C00A000A000A400A400A800A800ACD4
+:103CD00000AC00B100B100B300B300B500000000BB
+:103CE00000000000000000000000000000000000D4
+:103CF00000000000000000000000000000B501020C
+:103D00000102010A010A01120112011B011B012417
+:103D10000124012D012D01360136013F013F0148EB
+:103D2000014801510151015A00000000000000004B
+:103D30000000000000000000000000000000000083
+:103D40000000000000000000000000000000000073
+:103D50000000000000000000000000000000000063
+:103D60000000000000000000000000000000000053
+:103D70000000000000000000000000000000000043
+:103D80000000000000000000000000000000000033
+:103D90000000000000000000000000000000000023
+:103DA0000000000000000000000000000000000013
+:103DB0000000000000000000000000000000000003
+:103DC00000000000000000000000000000000000F3
+:103DD0000000000000000000015A015F0000000028
+:103DE00000000000015F016001600161016101628A
+:103DF000016201630163016401640165016501669B
+:103E000001660167000000000000000000000000E3
+:103E100000000000000000000000000000000000A2
+:103E20000000000000000000000000000000000092
+:103E30000167016C016C01790179018600000000C5
+:103E40000000000000000000000000000000000072
+:103E50000000000000000000000000000000000062
+:103E60000000000000000000000000000000000052
+:103E70000000000000000000000000000000000042
+:103E80000000000000000000018601870000000023
+:103E90000000000000000000000000000000000022
+:103EA0000000000000000000000000000000000012
+:103EB00000000000018701BE0000000000000000BB
+:103EC00000000000000000000000000000000000F2
+:103ED00000000000000000000000000000000000E2
+:103EE00001BE01E900000000000000000000000029
+:103EF00000000000000000000000000000000000C2
+:103F000000000000000000000000000001E9021AAB
+:103F10000000000000000000021A02210221022815
+:103F20000228022F022F02360236023D023D0244D1
+:103F30000244024B024B02520252028A000000006D
+:103F400000000000028A028E028E02920292029605
+:103F50000296029A029A029E029E02A202A202A661
+:103F600002A602AA02AA02FC02FC03130313032AFC
+:103F7000032A032D032D03300330033303330336A9
+:103F8000033603390339033C033C033F033F034239
+:103F9000034203830383038A038A039103910395F6
+:103FA000039503990399039D039D03A103A103A511
+:103FB00003A503A903A903AD03AD03B103B103B284
+:103FC00000000000000000000000000000000000F1
+:103FD00000000000000000000000000000000000E1
+:103FE000000000000000000003B203C40000000055
+:103FF00000000000000000000000000000000000C1
+:1040000000000000000000000000000000000000B0
+:104010000000000003C403D903D903DC03DC03DF81
+:104020000000000000000000000000000000000090
+:104030000000000000000000000000000000000080
+:1040400003DF040C0000000000000000000000007E
+:104050000000000000000000000000000000000060
+:10406000000000000000000000000000040C050F2C
+:104070000000000000000000000000000000000040
+:104080000000000000000000000000000000000030
+:104090000000000000000000050F05160516051AB7
+:1040A000051A051E000000000000000000000000CE
+:1040B0000000000000000000000000000000000000
+:1040C00000000000051E055E00000000000000006A
+:1040D000055E056705670570057005790579058238
+:1040E0000582058B058B05940594059D059D05A608
+:1040F00005A605FF05FF0611061106230623062760
+:104100000627062B062B062F062F06330633063707
+:104110000637063B063B063F063F06430643064A74
+:10412000000000000000000000000000000000008F
+:10413000000000000000000000000000000000007F
+:104140000000000000000000064A065000000000C9
+:10415000000000000000000000000000000000005F
+:10416000000000000000000000000000000000004F
+:104170000000000006500653000000000000000090
+:10418000000000000000000000000000000000002F
+:10419000000000000000000000000000000000001F
+:1041A0000653065900000000000000000000000057
+:1041B00000000000000000000000000000000000FF
+:1041C00000000000000000000000000000000000EF
+:1041D0000000000000000000065906680668067727
+:1041E0000677068606860695069506A406A406B3F7
+:1041F00006B306C206C206D106D10742000000007F
+:1042000000000000000000000000000000000000AE
+:10421000000000000000000000000000000000009E
+:104220000000000007420755075507660766077735
+:10423000000000000000000000000000000000007E
+:10424000000000000000000000000000000000006E
+:10425000000000000000000000000000000000005E
+:10426000000000000000000000000000000000004E
+:10427000000000000000000000000000000000003E
+:10428000000000000000000000000000000000002E
+:10429000000000000000000000000000000000001E
+:1042A000000000000000000000000000000000000E
+:1042B00000010000000204C00003098000040E4059
+:1042C00000051300000617C000071C8000082140ED
+:1042D00000092600000A2AC0000B2F80000C344081
+:1042E000000D3900000E3DC0000F42800010474015
+:1042F00000114C00001250C00013558000145A40A9
+:1043000000155F00001663C00017688000186D403C
+:1043100000197200001A76C0001B7B80001C8040D0
+:10432000001D8500001E89C0001F8E800020934064
+:10433000000020000000400000006000000080003D
+:104340000000A0000000C0000000E000000100002C
+:104350000001200000014000000160000001800019
+:104360000001A0000001C0000001E0000002000008
+:1043700000022000000240000002600000028000F5
+:104380000002A0000002C0000002E00000030000E4
+:1043900000032000000340000003600000038000D1
+:1043A0000003A0000003C0000003E00000040000C0
+:1043B00000042000000440000004600000048000AD
+:1043C0000004A0000004C0000004E000000500009C
+:1043D0000005200000054000000560000005800089
+:1043E0000005A0000005C0000005E0000006000078
+:1043F0000006200000064000000660000006800065
+:104400000006A0000006C0000006E0000007000053
+:104410000007200000074000000760000007800040
+:104420000007A0000007C0000007E000000800002F
+:10443000000820000008400000086000000880001C
+:104440000008A0000008C0000008E000000900000B
+:1044500000092000000940000009600000098000F8
+:104460000009A0000009C0000009E000000A0000E7
+:10447000000A2000000A4000000A6000000A8000D4
+:10448000000AA000000AC000000AE000000B0000C3
+:10449000000B2000000B4000000B6000000B8000B0
+:1044A000000BA000000BC000000BE000000C00009F
+:1044B000000C2000000C4000000C6000000C80008C
+:1044C000000CA000000CC000000CE000000D00007B
+:1044D000000D2000000D4000000D6000000D800068
+:1044E000000DA000000DC000000DE000000E000057
+:1044F000000E2000000E4000000E6000000E800044
+:10450000000EA000000EC000000EE000000F000032
+:10451000000F2000000F4000000F6000000F80001F
+:10452000000FA000000FC000000FE000001000000E
+:1045300000102000001040000010600000108000FB
+:104540000010A0000010C0000010E00000110000EA
+:1045500000112000001140000011600000118000D7
+:104560000011A0000011C0000011E00000120000C6
+:1045700000122000001240000012600000128000B3
+:104580000012A0000012C0000012E00000130000A2
+:10459000001320000013400000136000001380008F
+:1045A0000013A0000013C0000013E000001400007E
+:1045B000001420000014400000146000001480006B
+:1045C0000014A0000014C0000014E000001500005A
+:1045D0000015200000154000001560000015800047
+:1045E0000015A0000015C0000015E0000016000036
+:1045F0000016200000164000001660000016800023
+:104600000016A0000016C0000016E0000017000011
+:1046100000172000001740000017600000178000FE
+:104620000017A0000017C0000017E00000180000ED
+:1046300000182000001840000018600000188000DA
+:104640000018A0000018C0000018E00000190000C9
+:1046500000192000001940000019600000198000B6
+:104660000019A0000019C0000019E000001A0000A5
+:10467000001A2000001A4000001A6000001A800092
+:10468000001AA000001AC000001AE000001B000081
+:10469000001B2000001B4000001B6000001B80006E
+:1046A000001BA000001BC000001BE000001C00005D
+:1046B000001C2000001C4000001C6000001C80004A
+:1046C000001CA000001CC000001CE000001D000039
+:1046D000001D2000001D4000001D6000001D800026
+:1046E000001DA000001DC000001DE000001E000015
+:1046F000001E2000001E4000001E6000001E800002
+:10470000001EA000001EC000001EE000001F0000F0
+:10471000001F2000001F4000001F6000001F8000DD
+:10472000001FA000001FC000001FE00000200000CC
+:1047300000202000002040000020600000208000B9
+:104740000020A0000020C0000020E00000210000A8
+:104750000021200000214000002160000021800095
+:104760000021A0000021C0000021E0000022000084
+:104770000022200000224000002260000022800071
+:104780000022A0000022C0000022E0000023000060
+:10479000002320000023400000236000002380004D
+:1047A0000023A0000023C0000023E000002400003C
+:1047B0000024200000244000002460000024800029
+:1047C0000024A0000024C0000024E0000025000018
+:1047D0000025200000254000002560000025800005
+:1047E0000025A0000025C0000025E00000260000F4
+:1047F00000262000002640000026600000268000E1
+:104800000026A0000026C0000026E00000270000CF
+:1048100000272000002740000027600000278000BC
+:104820000027A0000027C0000027E00000280000AB
+:104830000028200000284000002860000028800098
+:104840000028A0000028C0000028E0000029000087
+:104850000029200000294000002960000029800074
+:104860000029A0000029C0000029E000002A000063
+:10487000002A2000002A4000002A6000002A800050
+:10488000002AA000002AC000002AE000002B00003F
+:10489000002B2000002B4000002B6000002B80002C
+:1048A000002BA000002BC000002BE000002C00001B
+:1048B000002C2000002C4000002C6000002C800008
+:1048C000002CA000002CC000002CE000002D0000F7
+:1048D000002D2000002D4000002D6000002D8000E4
+:1048E000002DA000002DC000002DE000002E0000D3
+:1048F000002E2000002E4000002E6000002E8000C0
+:10490000002EA000002EC000002EE000002F0000AE
+:10491000002F2000002F4000002F6000002F80009B
+:10492000002FA000002FC000002FE000003000008A
+:104930000030200000304000003060000030800077
+:104940000030A0000030C0000030E0000031000066
+:104950000031200000314000003160000031800053
+:104960000031A0000031C0000031E0000032000042
+:10497000003220000032400000326000003280002F
+:104980000032A0000032C0000032E000003300001E
+:10499000003320000033400000336000003380000B
+:1049A0000033A0000033C0000033E00000340000FA
+:1049B00000342000003440000034600000348000E7
+:1049C0000034A0000034C0000034E00000350000D6
+:1049D00000352000003540000035600000358000C3
+:1049E0000035A0000035C0000035E00000360000B2
+:1049F000003620000036400000366000003680009F
+:104A00000036A0000036C0000036E000003700008D
+:104A1000003720000037400000376000003780007A
+:104A20000037A0000037C0000037E0000038000069
+:104A30000038200000384000003860000038800056
+:104A40000038A0000038C0000038E0000039000045
+:104A50000039200000394000003960000039800032
+:104A60000039A0000039C0000039E000003A000021
+:104A7000003A2000003A4000003A6000003A80000E
+:104A8000003AA000003AC000003AE000003B0000FD
+:104A9000003B2000003B4000003B6000003B8000EA
+:104AA000003BA000003BC000003BE000003C0000D9
+:104AB000003C2000003C4000003C6000003C8000C6
+:104AC000003CA000003CC000003CE000003D0000B5
+:104AD000003D2000003D4000003D6000003D8000A2
+:104AE000003DA000003DC000003DE000003E000091
+:104AF000003E2000003E4000003E6000003E80007E
+:104B0000003EA000003EC000003EE000003F00006C
+:104B1000003F2000003F4000003F6000003F800059
+:104B2000003FA000003FC000003FE000003FE00168
+:104B300000000000000001FF0000020000007FF8FC
+:104B400000007FF800000CDF0000150000000001ED
+:104B50000000000100000001FFFFFFFFFFFFFFFF5B
+:104B6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF55
+:104B7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF45
+:104B8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF35
+:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25
+:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15
+:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05
+:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+:104BD000FFFFFFFFFFFFFFFFFFFFFFFF00000000E1
+:104BE000FFFFFFFF00000000FFFFFFFFFFFFFFFFD1
+:104BF00000000000FFFFFFFF00000000FFFFFFFFBD
+:104C0000FFFFFFFF00000000FFFFFFFF00000000AC
+:104C1000FFFFFFFF0000000300BEBC20FFFFFFFFFF
+:104C200000000000FFFFFFFF00000000FFFFFFFF8C
+:104C30000000000300BEBC20FFFFFFFF00000000DB
+:104C4000FFFFFFFF00000000FFFFFFFF0000000369
+:104C500000BEBC20FFFFFFFF00000000FFFFFFFFC2
+:104C600000000000FFFFFFFF0000000300BEBC20AB
+:104C7000FFFFFFFF00000000FFFFFFFF000000003C
+:104C8000FFFFFFFF0000000300BEBC20FFFFFFFF8F
+:104C900000000000FFFFFFFF00000000FFFFFFFF1C
+:104CA0000000000300BEBC2000002000000040C047
+:104CB00000006180000082400000A3000000C3C02B
+:104CC0000000E4800001054000012600000146C00C
+:104CD00000016780000188400001A9000001C9C0EF
+:104CE0000001EA8000020B4000022C0000024CC0D0
+:104CF00000026D8000028E400002AF000002CFC0B3
+:104D00000002F0800003114000033200000352C093
+:104D100000037380000394400003B5000003D5C076
+:104D20000003F6800004174000043800000458C057
+:104D30000004798000049A40000080000001038094
+:104D40000001870000020A8000028E00000311802B
+:104D5000000395000004188000049C0000051F80DB
+:104D60000005A300000626800006AA0000072D808B
+:104D70000007B100000834800008B80000093B803B
+:104D80000009BF00000A4280000AC600000B4980EB
+:104D9000000BCD00000C5080000CD400000D57809B
+:104DA000000DDB0000007FF800007FF80000193CD8
+:104DB000000015000000190000000028001000008D
+:104DC0000000000000000000FFFFFFFF40000000A7
+:104DD00040000000400000004000000040000000D3
+:104DE00040000000400000004000000040000000C3
+:104DF00040000000400000004000000040000000B3
+:104E000040000000400000004000000040000000A2
+:104E10004000000040000000400000004000000092
+:104E20004000000040000000400000004000000082
+:104E30004000000040000000400000004000000072
+:104E400040000000400000004000000000007FF82B
+:104E500000007FF8000005C700001500FFFFFFFFFE
+:104E6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF52
+:104E7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF42
+:104E8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF32
+:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22
+:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12
+:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02
+:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+:104ED000FFFFFFFFFFFFFFFFFFFFFFFF400000009E
+:104EE00040000000400000004000000040000000C2
+:104EF00040000000400000004000000040000000B2
+:104F000040000000400000004000000040000000A1
+:104F10004000000040000000400000004000000091
+:104F20004000000040000000400000004000000081
+:104F30004000000040000000400000004000000071
+:104F40004000000040000000400000004000000061
+:104F50004000000040000000400000000000100081
+:104F6000000020800000310000004180000052005D
+:104F70000000628000007300000083800000940045
+:104F80000000A4800000B5000000C5800000D6002D
+:104F90000000E6800000F700000107800001180013
+:104FA00000012880000139000001498000015A00F9
+:104FB00000016A8000017B0000018B8000019C00E1
+:104FC0000001AC800001BD000001CD800001DE00C9
+:104FD0000001EE800001FF0000007FF800007FF874
+:104FE0000000112E0000350010000000000028AD68
+:104FF000000000000001000100150005CCCCCCC56C
+:10500000FFFFFFFFFFFFFFFF7058103C0000000094
+:105010000000000000000001CCCC0201CCCCCCCCC4
+:10502000CCCC0201CCCCCCCCCCCC0201CCCCCCCCEA
+:10503000CCCC0201CCCCCCCCCCCC0201CCCCCCCCDA
+:10504000CCCC0201CCCCCCCCCCCC0201CCCCCCCCCA
+:10505000CCCC0201CCCCCCCC00000000FFFFFFFF89
+:105060004000000040000000400000004000000040
+:105070004000000040000000400000004000000030
+:105080004000000040000000400000004000000020
+:105090004000000040000000400000004000000010
+:1050A0004000000040000000400000004000000000
+:1050B00040000000400000004000000040000000F0
+:1050C00040000000400000004000000040000000E0
+:1050D00040000000400000004000000040000000D0
+:1050E000000E0232011600D6001000000000000081
+:1050F00000720236012300F30010000000000000DF
+:105100000000FFFF000000000000FFFF00000000A3
+:105110000000FFFF000000000000FFFF0000000093
+:105120000000FFFF000000000000FFFF0000000083
+:105130000000FFFF000000000000FFFF0000000073
+:105140000000FFFF000000000000FFFF0000000063
+:105150000000FFFF000000000000FFFF0000000053
+:105160000000FFFF000000000000FFFF0000000043
+:105170000000FFFF000000000000FFFF0000000033
+:105180000000FFFF000000000000FFFF0000000023
+:105190000000FFFF000000000000FFFF0000000013
+:1051A0000000FFFF000000000000FFFF0000000003
+:1051B0000000FFFF000000000000FFFF00000000F3
+:1051C0000000FFFF000000000000FFFF00000000E3
+:1051D0000000FFFF000000000000FFFF00000000D3
+:1051E0000000FFFF000000000000FFFF00000000C3
+:1051F0000000FFFF000000000000FFFF00000000B3
+:105200000000FFFF000000000000FFFF00000000A2
+:105210000000FFFF000000000000FFFF0000000092
+:105220000000FFFF000000000000FFFF0000000082
+:105230000000FFFF000000000000FFFF0000000072
+:105240000000FFFF000000000000FFFF0000000062
+:105250000000FFFF000000000000FFFF0000000052
+:105260000000FFFF000000000000FFFF0000000042
+:105270000000FFFF000000000000FFFF0000000032
+:105280000000FFFF000000000000FFFF0000000022
+:105290000000FFFF000000000000FFFF0000000012
+:1052A0000000FFFF000000000000FFFF0000000002
+:1052B0000000FFFF000000000000FFFF00000000F2
+:1052C0000000FFFF000000000000FFFF00000000E2
+:1052D0000000FFFF000000000000FFFF00000000D2
+:1052E0000000FFFF000000000000FFFF00000000C2
+:1052F0000000FFFF000000000000FFFF00000000B2
+:10530000FFFFFFF3318FFFFF0C30C30CC30C30C322
+:10531000CF3CF300F3CF3CF30000CF3CCDCDCDCD5F
+:10532000FFFFFFF130EFFFFF0C30C30CC30C30C3A5
+:10533000CF3CF300F3CF3CF30001CF3CCDCDCDCD3E
+:10534000FFFFFFF6305FFFFF0C30C30CC30C30C310
+:10535000CF3CF300F3CF3CF30002CF3CCDCDCDCD1D
+:10536000FFFFF4061CBFFFFF0C30C305C30C30C3A6
+:10537000CF300014F3CF3CF30004CF3CCDCDCDCDE6
+:10538000FFFFFFF2304FFFFF0C30C30CC30C30C3E4
+:10539000CF3CF300F3CF3CF30008CF3CCDCDCDCDD7
+:1053A000FFFFFFFA302FFFFF0C30C30CC30C30C3DC
+:1053B000CF3CF300F3CF3CF30010CF3CCDCDCDCDAF
+:1053C000FFFFFFF731EFFFFF0C30C30CC30C30C3FE
+:1053D000CF3CF300F3CF3CF30020CF3CCDCDCDCD7F
+:1053E000FFFFFFF5302FFFFF0C30C30CC30C30C3A1
+:1053F000CF3CF300F3CF3CF30040CF3CCDCDCDCD3F
+:10540000FFFFFFF3310FFFFF0C30C30CC30C30C3A1
+:10541000CF3CF300F3CF3CF30000CF3CCDCDCDCD5E
+:10542000FFFFFFF1310FFFFF0C30C30CC30C30C383
+:10543000CF3CF300F3CF3CF30001CF3CCDCDCDCD3D
+:10544000FFFFFFF6305FFFFF0C30C30CC30C30C30F
+:10545000CF3CF300F3CF3CF30002CF3CCDCDCDCD1C
+:10546000FFFFF4061CBFFFFF0C30C305C30C30C3A5
+:10547000CF300014F3CF3CF30004CF3CCDCDCDCDE5
+:10548000FFFFFFF2304FFFFF0C30C30CC30C30C3E3
+:10549000CF3CF300F3CF3CF30008CF3CCDCDCDCDD6
+:1054A000FFFFFFFA302FFFFF0C30C30CC30C30C3DB
+:1054B000CF3CF300F3CF3CF30010CF3CCDCDCDCDAE
+:1054C000FFFFFFF730EFFFFF0C30C30CC30C30C3FE
+:1054D000CF3CF300F3CF3CF30020CF3CCDCDCDCD7E
+:1054E000FFFFFFF5304FFFFF0C30C30CC30C30C380
+:1054F000CF3CF300F3CF3CF30040CF3CCDCDCDCD3E
+:10550000FFFFFFF331EFFFFF0C30C30CC30C30C3C0
+:10551000CF3CF300F3CF3CF30000CF3CCDCDCDCD5D
+:10552000FFFFFFF1310FFFFF0C30C30CC30C30C382
+:10553000CF3CF300F3CF3CF30001CF3CCDCDCDCD3C
+:10554000FFFFFFF6305FFFFF0C30C30CC30C30C30E
+:10555000CF3CF300F3CF3CF30002CF3CCDCDCDCD1B
+:10556000FFFFF4061CBFFFFF0C30C305C30C30C3A4
+:10557000CF300014F3CF3CF30004CF3CCDCDCDCDE4
+:10558000FFFFFFF2304FFFFF0C30C30CC30C30C3E2
+:10559000CF3CF300F3CF3CF30008CF3CCDCDCDCDD5
+:1055A000FFFFFFFA302FFFFF0C30C30CC30C30C3DA
+:1055B000CF3CF300F3CF3CF30010CF3CCDCDCDCDAD
+:1055C000FFFFFF97056FFFFF0C30C30CC30C30C308
+:1055D000CF3CC000F3CF3CF30020CF3CCDCDCDCDB0
+:1055E000FFFFFFF5310FFFFF0C30C30CC30C30C3BE
+:1055F000CF3CF300F3CF3CF30040CF3CCDCDCDCD3D
+:10560000FFFFFFF3320FFFFF0C30C30CC30C30C39E
+:10561000CF3CF300F3CF3CF30000CF3CCDCDCDCD5C
+:10562000FFFFFFF1310FFFFF0C30C30CC30C30C381
+:10563000CF3CF300F3CF3CF30001CF3CCDCDCDCD3B
+:10564000FFFFFFF6305FFFFF0C30C30CC30C30C30D
+:10565000CF3CF300F3CF3CF30002CF3CCDCDCDCD1A
+:10566000FFFFF4061CBFFFFF0C30C305C30C30C3A3
+:10567000CF300014F3CF3CF30004CF3CCDCDCDCDE3
+:10568000FFFFFFF2304FFFFF0C30C30CC30C30C3E1
+:10569000CF3CF300F3CF3CF30008CF3CCDCDCDCDD4
+:1056A000FFFFFF8A042FFFFF0C30C30CC30C30C375
+:1056B000CF3CC000F3CF3CF30010CF3CCDCDCDCDDF
+:1056C000FFFFFF9705CFFFFF0C30C30CC30C30C3A7
+:1056D000CF3CC000F3CF3CF30020CF3CCDCDCDCDAF
+:1056E000FFFFFFF5310FFFFF0C30C30CC30C30C3BD
+:1056F000CF3CF300F3CF3CF30040CF3CCDCDCDCD3C
+:10570000FFFFFFF3316FFFFF0C30C30CC30C30C33E
+:10571000CF3CF300F3CF3CF30000CF3CCDCDCDCD5B
+:10572000FFFFFFF1302FFFFF0C30C30CC30C30C361
+:10573000CF3CF300F3CF3CF30001CF3CCDCDCDCD3A
+:10574000FFFFFFF6305FFFFF0C30C30CC30C30C30C
+:10575000CF3CF300F3CF3CF30002CF3CCDCDCDCD19
+:10576000FFFFFFF630BFFFFF0C30C30CC30C30C38C
+:10577000CF3CF314F3CF3CF30004CF3CCDCDCDCDE3
+:10578000FFFFFFF2304FFFFF0C30C30CC30C30C3E0
+:10579000CF3CF300F3CF3CF30008CF3CCDCDCDCDD3
+:1057A000FFFFFFFA302FFFFF0C30C30CC30C30C3D8
+:1057B000CF3CF300F3CF3CF30010CF3CCDCDCDCDAB
+:1057C000FFFFFFF731CFFFFF0C30C30CC30C30C31A
+:1057D000CF3CF300F3CF3CF30020CF3CCDCDCDCD7B
+:1057E000FFFFFFF0307FFFFF0C30C30CC30C30C352
+:1057F000CF3CF300F3CF3CF30040CF3CCDCDCDCD3B
+:10580000FFFFFFFF30CFFFFF0C30C30CC30C30C3D2
+:10581000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD8E
+:10582000FFFFFFFF30CFFFFF0C30C30CC30C30C3B2
+:10583000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD6D
+:10584000FFFFFFFF30CFFFFF0C30C30CC30C30C392
+:10585000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD4C
+:10586000FFFFFFFF30CFFFFF0C30C30CC30C30C372
+:10587000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2A
+:10588000FFFFFFFF30CFFFFF0C30C30CC30C30C352
+:10589000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD06
+:1058A000FFFFFFFF30CFFFFF0C30C30CC30C30C332
+:1058B000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDDE
+:1058C000FFFFFFFF30CFFFFF0C30C30CC30C30C312
+:1058D000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDAE
+:1058E000FFFFFFFF30CFFFFF0C30C30CC30C30C3F2
+:1058F000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD6E
+:10590000FFFFFFFF30CFFFFF0C30C30CC30C30C3D1
+:10591000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD8D
+:10592000FFFFFFFF30CFFFFF0C30C30CC30C30C3B1
+:10593000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD6C
+:10594000FFFFFFFF30CFFFFF0C30C30CC30C30C391
+:10595000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD4B
+:10596000FFFFFFFF30CFFFFF0C30C30CC30C30C371
+:10597000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD29
+:10598000FFFFFFFF30CFFFFF0C30C30CC30C30C351
+:10599000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD05
+:1059A000FFFFFFFF30CFFFFF0C30C30CC30C30C331
+:1059B000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDDD
+:1059C000FFFFFFFF30CFFFFF0C30C30CC30C30C311
+:1059D000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDAD
+:1059E000FFFFFFFF30CFFFFF0C30C30CC30C30C3F1
+:1059F000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD6D
+:105A0000FFFFFFFF30CFFFFF0C30C30CC30C30C3D0
+:105A1000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD8C
+:105A2000FFFFFFFF30CFFFFF0C30C30CC30C30C3B0
+:105A3000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD6B
+:105A4000FFFFFFFF30CFFFFF0C30C30CC30C30C390
+:105A5000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD4A
+:105A6000FFFFFFFF30CFFFFF0C30C30CC30C30C370
+:105A7000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD28
+:105A8000FFFFFFFF30CFFFFF0C30C30CC30C30C350
+:105A9000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD04
+:105AA000FFFFFFFF30CFFFFF0C30C30CC30C30C330
+:105AB000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDDC
+:105AC000FFFFFFFF30CFFFFF0C30C30CC30C30C310
+:105AD000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDAC
+:105AE000FFFFFFFF30CFFFFF0C30C30CC30C30C3F0
+:105AF000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD6C
+:105B0000000C0000000700C000028130000B81582B
+:105B10000002021000010230000F024000010330B9
+:105B2000000800000008008000028100000B8128AE
+:105B3000000201E0000102000007021000020280E2
+:105B4000000F0000000800F000028170000B819837
+:105B50000002025000010270000B8280000803382E
+:105B6000001000000008010000028180000B81A8E5
+:105B70000002026000018280000E8298000803800B
+:105B8000000B0000000100B0000280C0000580E8AA
+:105B90000002014000010160000E0170000382500C
+:105BA000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC35
+:105BB00000002000CCCCCCCCCCCCCCCCCCCCCCCC35
+:105BC000CCCCCCCC00002000CCCCCCCCCCCCCCCC25
+:105BD000CCCCCCCCCCCCCCCC040020000000000041
+:105BE0001F8B080000000000000BFB51CFC0F0032A
+:105BF0008A59051918F484117C7A607E4ECAF43BE8
+:105C0000F232303803B12B103700F1616E06862373
+:105C1000DCC4EB3F2B8F6007CA3230D402F17E69BF
+:105C200006062B3984B8A10203C312203F0D2AF6C1
+:105C30001A4817CA53E6EEC182555431C51495115E
+:105C40006C552CF2C8580D4DBE411995AF4E40FF12
+:105C500040E3641D54FE042D08FD5E1B42A7A0C94D
+:105C60004F84CABB42FD95AA83DD5C3722FD9DC6E9
+:105C700082CA4F40E3B730A2F2CD38D0DC0F550FC7
+:105C80000000174B67C80300000000000000000080
+:105C90001F8B080000000000000BED7D0D7854D52F
+:105CA000B5E83E3F73E6CCE4CCE4242461C2EF24A3
+:105CB000841034E21022064BEB097F869A7A07AAF9
+:105CC000985AC5012306082452F5E1D37E9948026B
+:105CD000011106B53414D4E14F692FB6918B965A51
+:105CE0008A033E2DB6BEEF059FB57AB57DD152FC35
+:105CF000294ACABB52FBAEAD6FAFB5F74ECE39CC19
+:105D000090E04FDBFBDEA59FDDD9E7EC9FB5D7DF49
+:105D10005E6BEDB5CF78483E29B89C904FE01F2DC3
+:105D2000FF9741087DD4577A7412CFBA98909C3C63
+:105D30002BDE534EC8D03C2B452AE973530B7BA571
+:105D4000FE7EA23C9C332B04EDDAF2AD10A163B4CD
+:105D5000E5CC2331182BD640480121AA4EF09F688C
+:105D6000EF31E7EAA41C1FFDF513F15E21A4DD2C41
+:105D7000CE867EEEF10949127289BD2E1322C6A489
+:105D8000FD7C02DE12FA208F107F959CBCA288C297
+:105D90005D924C41DD0833B80F17BD523386AE63B8
+:105DA0005DB51CF186A1F7AD844C2664058C45EBEE
+:105DB000EB2676D78CC983F76A04DECE54F6B66A32
+:105DC000B4BD5142B07D70623CA5613FCB28A4FDBB
+:105DD00072180824A76C512D091262CED0FAE1C2C4
+:105DE000FFB770FD066FA79738DF1B64FD1F95098D
+:105DF00050EB25D18BE8F8535DEFCB66BD0DE31A70
+:105E0000843E2FE3CFE9BAEE873F0A09F91209E48D
+:105E10009DC8A27F5F4A2E053C909A5C42A69C8D4D
+:105E2000BF7EBCC591BE8430BA68A4EF1FD241E7E3
+:105E300074B862464FA744D7ED8BC8C44B1FCD52F0
+:105E40005ED48B012F4715C4C3BA3A86E77533E495
+:105E5000645CC275D616D2FEA309C363CEF862890C
+:105E60001413B2B185D6C79D8DE7EC928405F4F783
+:105E7000951009F82A9B3E1B42D7953D35857C330A
+:105E8000BA8AE193DCCDF011A7FFFBA4B81F9FD91C
+:105E9000029F1127BEB2393E736A6CF882E755142F
+:105EA0008F13E0BD138F49F883E2AB5EE0319F8C26
+:105EB000453CC67311BF03E1F10A8A832C0ABFFF78
+:105EC000556FD25BD48F57C11702AF26C7EB8699A7
+:105ED000BD3A30C3468BF1392129490EE178925CF5
+:105EE00085EBC3B203F0E6C5FEF85EA7301B7C9ECF
+:105EF000309DC75F9640FCEB141D4324E053435292
+:105F000081AF814FD3CCBB4E4FEA126DBF69AA4C13
+:105F1000805EEB2C998469FD74999A5400EEB8D593
+:105F20001DB2F1A901F8A7F8BA8FE3471B213BF096
+:105F3000A9E6F95D7CEE5CC7A6BEF5597C5D6C1DDB
+:105F4000A43BD901709C99299375D2C0E30E842794
+:105F500031EE80F0F598BE1298F70525B28EF2DA90
+:105F6000BA70B243A6F8DA3883E1E36CFA7EC6F978
+:105F70007A7BF5924ADB7C915EDD2CFF02E62139CB
+:105F8000CE7555993E33ADFE3CBF7988B960743407
+:105F900090991E9F1BFC610ABF0D4F7AD894607CBC
+:105FA0007DFC3D3AA8784276E8A017DDF39C05AF6A
+:105FB0006B5EF73C6A49B3A562CDA987343341D8FB
+:105FC0003C16DBA7087BAE821EA1FAC71F71EA113F
+:105FD000B7FED64638EB6A15D3D72AB13D2F02ED6E
+:105FE0004EF5CB85A45F4F570E4EBF10AB01E17548
+:105FF000EB93315CAEA7EFEDA95329FD4BB6093DFC
+:106000007DF72FCA687D37E8695ADFDD0973D1B2A1
+:10601000CBA9A727F0C1CABFF3920C7A7A47063DF5
+:106020005D9CB0A6819E2E49D08D808E53BC9EE98A
+:10603000E9E28E6619E83481EB097280E149A7FF35
+:10604000B3EBE9623ECF986D4E3C15733D5DBEDF0C
+:10605000F59CEBE962979EDE087F507C154A1C8F09
+:10606000634929E271EA20F73B8E47F77E570C73AC
+:106070008FA1787C90ED7739790C8FED1D3201FD81
+:10608000707A9B8CFA715C51548676424F72D0487C
+:10609000195FFF4EAEAF059C636698D5A04C4B8848
+:1060A000590DF4D1D693482A0C7ABA310EF36C4AC2
+:1060B000303D5D922072CC6607691C9E4DA1DCD9F3
+:1060C00020D7A7136A0496B98B8465BDA81FAF7D3E
+:1060D0007607C7E3D7A095431E9C74CCE17875E39F
+:1060E000675CD2C9DF250FBAE8B1DE59CF71D1E5BF
+:1060F0004AC9657F0C921E5E95C4BDB9504FA25D22
+:10610000A7D3B5E6D3BAF22FCF5AC0D746277BA67E
+:1061100075C8C922CAB7813656F774A8C96A5ABF6A
+:10612000218FF1F5D83849825DA784A204ECCFB164
+:1061300079547FD8F0E9E1F81474833F011F63B804
+:106140007D913D33D707FCBD298FE37B06C33755CF
+:10615000803ED07F02DF1E8E6FA3B21BC023B3C36D
+:106160004E7C4F3AEAD437D7D60D71D4AF890E3F63
+:10617000277D3C9C8E1E4E27C14767E13FEEB20F44
+:106180002B9D758F8B3E2D924BEF0C923EDA115268
+:10619000067C3B4EF64776149DDD2E21C948373AE2
+:1061A00079F2389D7F0135E3B2E9F8CB48CF28403A
+:1061B000D001238CE32C977B0AA07E8AF46E1E39D3
+:1061C000A67FFC512A392051234EA2E85D49411A8D
+:1061D000A693545610C18EEA05B874C48B44FFBB15
+:1061E0001EF94495015FC34DF69CC4B355A887883A
+:1061F000F817463A79F99F852B9FFFB344F128F1B0
+:1062000052013A8E01FCC4506FEA2481753FE9C205
+:10621000D220DD5806A9A686D224A604652E896060
+:10622000492E483E9142FD79B789FCEEFB1DF924C9
+:10623000AB7F3DF7C29F14AFC348F47109FC273A06
+:106240009EAEF4F3A18FF321B5D3906F7593F1ADAA
+:106250005E42F7D372947BF45FDC785ECBF5F28616
+:10626000161DCBF52D262E7268281997297D7CB531
+:106270004C8FE4847A3AC06FF137AB912B68DD6FB5
+:10628000F4BE7A13D87BB76B917B68FDF0CCE74303
+:1062900050EFB8DD60F6611BB353FD1C7B1D637BC3
+:1062A0007B5651B836DCAE47F823873EDA30BEF76E
+:1062B0009D9DA0B76EF34700BF9B4247C2AB405EB7
+:1062C0009A3594176A7B22FDD657FCA208EDB58F4C
+:1062D00029FC943E2842B4BFFE116D3589B61BD10E
+:1062E000DB82767D7377B59287EFE38170FF7A3B2F
+:1062F0008A87E1FEDF71642D09D3973995710BF020
+:10630000E52BA3A62CE5435FA529C50D90CAD8EBC4
+:1063100012E53FFF8C18B128FE0221B3157845E73E
+:1063200074236A2204F2EBC667C7C87868219D37D8
+:106330003E5E8BEC46B632A57969DAF5E17FE61D63
+:10634000D75969ECA96C5942FE3F327E11FABD5E05
+:10635000120B65814E2AD3C86E0AE7BAF18B46C785
+:10636000D2D87B3639E3F64AFA32533F4D21CD5D20
+:106370003678C6CA32F29F24EB4C6E43948FA85CE9
+:10638000E5988C9FB419C44AA681E3720EBFAEC6CD
+:106390008989F6B529819DF545E1EB5D89C1B9563D
+:1063A00022755D69DE6F0778F2413EEE4EC1FE98C0
+:1063B0003D93F135FDCFEAA2F0E7A8AC14ED6B38C0
+:1063C000FC7B78BFF3D043050F027F940FCEFEF223
+:1063D000C2BC69E09DF829E6DD48E79565139F0B8F
+:1063E000BCBBE9294A49F6E1FACE8CDF1C02FB343A
+:1063F000139CE1DB50B79370332D87D2B29697266A
+:106400002BDDF39DEF785F96D93ADCE3925DCC9E6D
+:10641000F2F3FDEBF094572C85D26D749CF0B88AA2
+:10642000537F8C2E93D15FDDB4876EF845A03F5823
+:10643000FD915D24A950549EBEFB1E19E01A49ED42
+:106440007C683F84C464C05B11094B500A3DB88628
+:10645000EBC10F49F43A391FF47417DA45B595B713
+:106460004E4B1737AAE7F2713EFBD45768B9408FFD
+:106470002E82F18DC8318BEEE4447B31BD5CD1EDD1
+:106480002A34D7260F44117CC1E4A99DF33BC8CD23
+:106490001C5A9F777D7A3837CDD48631BBC52C44C2
+:1064A0007F47350BE7DAE471532B952BFA3E09E36E
+:1064B000D9E4E0BB7C7DAD5C1ECE871F6B6869466E
+:1064C0002C4BA1AF6A92891940B7ABA5D86A998EB7
+:1064D00053D11C7956A575634FB7E567CFD7C2F383
+:1064E0007925CDEDC01286D54D40DF3E72F70A0BFF
+:1064F000E8787A045D7A1A3B4194AA253BEC147D36
+:1065000084DF690F0D521E2F8824A601BC65E1634C
+:10651000D5B961A0536C1BD069C4D1C86158A251D0
+:10652000772C956FA357D8646523004DE1D7E2948B
+:106530006E488F6808E8B198447742FF406594C57B
+:106540002B07094726FE0F8798DE0A737E6F8F5050
+:106550007E97FAE5C1CFE5A19DBF3F5D49D0BF68F9
+:10656000CFAB30D3ED1782DF05FF0B7DE86E77F8F8
+:1065700053F0F9785A961213FD9A0F49EC39C0037B
+:106580005D3DCA9F16EA42FF4EC8556DE4D88C2186
+:106590001047AD0C5728B6FDFA7DCE770B74EB97FC
+:1065A000D07FDEF50BDAF3291EC6DD4D22A066AFE3
+:1065B000BD7E01B1F3FBAFFBDA475F42F9BABB1B0B
+:1065C000DDD281FA75F3F55D2D455FB3F3211DE74B
+:1065D000751CA7A43B2EDBF44E0EC7B332B38F3F1E
+:1065E0004D10CD9ADB122AD0A7A236A248B6755C10
+:1065F0005BE7B4E729BFBF03E3BAF9741E69F690FD
+:10660000F3D83F4649B15E80B7B6A4BB0DE0D34294
+:1066100051F4F728DCA7E1F91700F727E782FB1D03
+:10662000887580DE8C545B43C2089FAA5C027E544E
+:10663000AA2D3F0C783FA602DE299E35C586E7C10C
+:10664000CAF9FD7CBF1848DEDBE00FB49763790A16
+:106650006D3F4467724A7A8E11E67739E397C26ECE
+:106660000E8608C659736A7B08F86B171F55D0DE73
+:106670001D5A4B24B0C3845D3BC475DEB001EC668B
+:106680002A3FF7B58450882E367A8FC239C08642A9
+:1066900099D9C753CE0C83FE3FAAEE09813F6856B5
+:1066A0009D59775318ECED30B65FDB12E1FB4F15C7
+:1066B0009689DAB7F6ECA4F36F08F9D15EBEB7A5F8
+:1066C0004CC46B11EE2122DE5BCBEC7B11171670F4
+:1066D000D1FE3A0FB63ADA93900D6FC5B6FE61A6B9
+:1066E0006F06EA9F55E9C47B5F7F6B70FD21DE6F0B
+:1066F000EF5F6DF51C85F89CC9E3FE42EF05791B41
+:10670000B34A46FF59E0D95BE68CCB25F8FC99F8F3
+:10671000C53D1F09FB1DEB27F106846F05978B4CC8
+:10672000E3B473FD28EA1E92DE6E5BA6F07D929FB5
+:106730004B997CAE1F594E7C5C2CE87790E3CF647C
+:10674000F22EFC1A8C0728F6F9D83AB08E719A38D6
+:10675000D3C72EF8457F8DF7CF0487E61EEF381D8F
+:1067600067B26D1C179C99E0739F9391779CE364CB
+:10677000D65FAE7E27074787B3FA119BDC633DD710
+:10678000551FE66A5FEC7A7F81EB7D85AB7E99AB26
+:10679000FD3457FDABAEF6735DF5EB5CED17BADE7D
+:1067A0002F71BD5FE1AAFF5767FBF2C59F0EBFFFC8
+:1067B0009FE149C8D5D978493ACE79DD72554C5216
+:1067C000A352B4DC91F3E22278D5A348EA099847B2
+:1067D000C4B7486A82DD8FFDBD11FB1DEC633B3EF3
+:1067E000B6FC512A57BB122F05617F13CF4F4A6F5A
+:1067F00004C787A97DA8A596B3785002E5C64FD4F3
+:10680000B77ACA804A12C6D174A31E51AE97D0E798
+:10681000367DE52551A4B336C2F99C24981C9640D8
+:10682000808A8E17DFA4A1BD171F499263419EF392
+:10683000D8F8D8BEB81FDE492AD34FA168A21A647F
+:1068400078585DD76128DD780A4D8F4F7C9EEA65C8
+:10685000F200F3CB77CD74FAD5D7F171E6ABE7ED63
+:10686000A7BE3249E91F7FD7B78D482B6DB20B8089
+:10687000A0F5F8B7F524C4374641BC8E1D2260BC94
+:106880006E24E1FF785C6E04FC4DFB8D348E62FC5F
+:106890002DDC601E019DF775B514E17A44EA1D0FE9
+:1068A000F3C9592727B2F3BDBF7E82F1788EAFD0EE
+:1068B000BD937BE2104FD9A845C6229E238867EA84
+:1068C0008FB7792B804D187E57C1EECB9EAB815C84
+:1068D0003877E1F400FD4B4B1FF013EC8B2485F56A
+:1068E00000E9C17A36B773CBD4225C7F0EF7330947
+:1068F0008948607F84AE4CEF9747A5EA32F592FE57
+:10690000B8A51466F14969FDF37F9620AE5546C2DD
+:10691000CC7EE171C2B58AF409C45FCDC1D98BA127
+:106920006F3AE94AD46632C7E65F5EAF0A3F8FE14D
+:106930006B4C88AD3FB4516B06BF66D76C271F8880
+:10694000F6EAF9F3C1E60963BE383EC855C764E00C
+:1069500083EB4D88574B718AB7ACC1E3CD54AC6F14
+:10696000AAB84E82E3FE40B26EB0D75562DDA8E60B
+:10697000F7D77FAD4417C2FBF83452D66CF48F437F
+:106980009FDF0CEDD23C6F48D77E1C8FDBD2FD1908
+:10699000F7F152AE03866E3365B0278B3A57F8EDA8
+:1069A000792EA57CBF7EAC739F0FD6BBB5F1DCF60C
+:1069B000D17D2DC8FC19DB05A5EE28D0835CA29201
+:1069C000DD69CEB17FCAF9BBAFBDCB3E9CD116AF5E
+:1069D00086FEB97532817834DDE7D1BE2BE27EEDDB
+:1069E000E6A97149A372F8C0168276726EDB429FE7
+:1069F0007D3D857C3D9B6B0BFC60B76CAF5FF855B4
+:106A0000F413A8FDAFA0DF1B5B07E317D6B0F37E3E
+:106A1000377CF7F2F525EA199EDCEFB334124B27E9
+:106A2000873F55F9F9834ADDC782FE73947B0FDFF8
+:106A3000F98BF174BED22A39E20BF7C339AECF6EAF
+:106A4000EA417C655DA69AEB400F776A0E7B73FB8B
+:106A5000B6FBB7D4C3B91F7D0EEAE0D12F370F8B39
+:106A600052B81EFBDAA2171603DFB7CB04F49180ED
+:106A7000C32877DABB47FAE4CC392F1DB71AF15295
+:106A80007F6EFFE9D3E2630B97F34C7CE2DE57DDC8
+:106A90007C703EFBC355CA675FDF7E90433A6E0150
+:106AA000F7FB86D685A51EA35F8E849F22E629E08C
+:106AB0007C965B7BBF0FF86C4B5D05CACFE9DA852E
+:106AC00012E8934DD0328D9E10F3658227CB93C090
+:106AD0007C892DF5F74BE9F0561863F122F7F36A3C
+:106AE0000FA3F37A352141FF4CED467BB8BEE67229
+:106AF00055C8D7159A9A8A02BE0A222AB987E2EBAC
+:106B000081DA85D5A5C077540E21BE32A386A0BDFB
+:106B10005068B1732293E2EB69BAEF6DAE2791141E
+:106B20006DB7D9D2F01CC62D876E7EDC5C7F6EFD02
+:106B3000422C5B7BCAFF1E8FC1CE734B4809D853D2
+:106B40000F0CE0BF0D16BFA17A99C54B67540CA07E
+:106B5000CF5BCF378E39EFCBC08F33069907E0D2AA
+:106B600017E4D92DB34BF3201E42F50549871FA723
+:106B70007E18081F6EFC5F0CF8BCF08BC3A7FB7D72
+:106B80009E87C70107898FF575C5FF03522633B568
+:106B900077AF47F41379615F21BD0AC8BF051C3A7E
+:106BA00006BC8A0896334814CB636A2CEAA1ED67C9
+:106BB0009166ACD79004968B5593D199E7C188F331
+:106BC0006E753AE3FB719792249C3B93A973F9612C
+:106BD000B06A9DD00986523F49E35711720F8E3734
+:106BE000DCB51F8B38C5D0C6446D051D77782DCB1D
+:106BF000FB1C5EB5CFB18F05B9FC88F1B6560D6EA2
+:106C00007F7ED4B53F3FAAF6E8409F47ABEE69854B
+:106C1000ED46CD7D2794AEFFB84E275E377CDCE590
+:106C20008BA681676BFD011FE48D6DAD4A9F17EB4D
+:106C30008623D3FB7119CE99BEE265E74C5B73F4F2
+:106C40006FB0649D958EBC04A21845F679B77E4C52
+:106C500072A2E7D4274E79D9E8E1F921011200FEAA
+:106C6000CF840F517ED178786C5AF392689AFEA542
+:106C70005E2637ED39240EE7D28FBDA632FEE37AC9
+:106C800078F237C249B017DA414950FDFB5835E375
+:106C9000CFC939FCFD4361CCAF1ADE49E21ADDCF22
+:106CA00086BF5AFF400E6D775F3DF5206DCFEFAB8D
+:106CB0007CA903CE899F7A59C6B8EE645FB71EA13E
+:106CC000F054F17D706BFD4B989F1CDFA646C6A269
+:106CD0007E97883419BD79A48780F7198FCAE85642
+:106CE00079BF2F0CFB57B8478F50FCDC3EE5253DA4
+:106CF0004CCBFB46A47458E7FAAAFB91CFF7D51703
+:106D00007FBD14D1EACC3B99A54CEDB6E87CEBEB0A
+:106D1000D9B95D4E4F4AF7429CB54E255750F8827F
+:106D2000065BEF7DED24798F047030FA4A640EFA29
+:106D3000C585AEBCAE0257DE9B5939EB5DC86731E5
+:106D4000E19C1F16A1343E7011E8DB2699B95BAEB9
+:106D5000FC68A3D27A17F2036629077D907FB5A558
+:106D60004D3571FF738DEB5E874962872D09C789A9
+:106D7000831FB8E541B64F9A138D483C0C5D39DC52
+:106D800026857B089DB2CD09B7C0AB7B1E77DEF5AB
+:106D9000BB829F8793B1A08744BC59C0EFE6DBBCA0
+:106DA0008AE4FE97281C5B5F3670BFDE5AF5D23747
+:106DB0009B609F2FF362DEC457CFEC69FC112D7FDF
+:106DC000F9C70325505E59B8ABB289B60BF07C0900
+:106DD00011CF2B8091D17EE57A8DF30329DFDEE69A
+:106DE000C9C347984771DF111FD2ABB04D4EFA802F
+:106DF0003E6A8A007FE55D9640BBE9BEEBBA31E9A9
+:106E00002250D725C56D721610F643634C82F3FBF2
+:106E10002BEA12B3810F0D9E47684412681FCD54B0
+:106E20005ED431CECEE966723884DCB9E9525A9F1D
+:106E3000D2212F65789B1A0170873736CB202FA57A
+:106E4000552C6FB9B4B34BE279C2984F3F8E237182
+:106E50005CB481E5156E63F817F9DFC14627DD4C98
+:106E60009EA749FD0C19FCEEA24ED7FB680DE66308
+:106E7000BAE95AACF1BCA8529E47C8F1309CDBB3CA
+:106E8000EB1BF9F99CA127CF65CFEEE3E7734761D0
+:106E9000FDE3CE7E3F2983DEBD0AF42ED5378A9CE2
+:106EA000EA40FFED3219FD37371C1B1A99BEDBA5EE
+:106EB000C90EFBFDB3CE7F03D7FB8ADCD301EBFC0D
+:106EC0005BCFDFD8B7FEBFCFFC77FD9DE75FF777DD
+:106ED000C6FF96BFF3FAF7FC8DD75F532639FCB394
+:106EE0001D909842C7FBB157C4D39C7A5B91D3FBEA
+:106EF000D96F69B2239F58E4294EAFB31668783E24
+:106F00002E137BFE8B186FA6F24607E8D32D5C9FED
+:106F1000523D4A205F207B8AC89761FAAF86EBBF5B
+:106F20001AAEFFF665D0AB15902B96877605DE0777
+:106F3000994412E8C7048FAA9867BC8FD0ED05F476
+:106F40005AD89B362FBB80C3EDD6A7055C9F56BC95
+:106F5000E87ACEF5A87B7F2FEA8B9B128C9BFE777D
+:106F60008DEF8F2EBD2AF0B0A58AD9C97973D3DBF6
+:106F700081EB5D74342A9B31FFC04D8FB734E67FBF
+:106F80000B7A2CD0ADD7B5FCCCF4EEE1F4BE9CD39B
+:106F9000FB571AF33F44BE48267A5779D93C9706E7
+:106FA0008E875A6135D16AA483C2E9A490F5DD18B1
+:106FB000F725B713BB5FB9E1636A7F507A6C358CF4
+:106FC000C83DB47E691E9145D2FDC793FBF3893D50
+:106FD000DD2C7EAAE4692E3FCB6DFFEA9837BED543
+:106FE0009293F122B023766C5D0E76C4CBFE08C47A
+:106FF0000BB6E674BE887E5C62920A70087B91F0E4
+:10700000B82C981204ED26F7B993D3DEDFFA715746
+:107010000AEC2EB348C2785F47F8FEBCB4F7F15CC7
+:1070200076BEE10D38E206E48AC1D9EBAB38BDA9E2
+:107030009F98EFB5C5295705664D62E7E6334C3892
+:10704000DF91AC5932C4D1338D0311DE13B6F3A6F0
+:10705000C5AA3512C693C06F2CEBF71B0919C1E204
+:10706000F262FD83BD3FD0B8989D7B73BCE65DD6D0
+:10707000F5B9F88FC2DF17ED0C6AAFA5BBBFE3F619
+:10708000C36B3CD614EF258387FF116038DAFE8589
+:1070900072A5265DDCA087EBD7C0D1AED973E9FA23
+:1070A0002A5FE4717D6AB6D9CFD3EECB53D3F6FF16
+:1070B0003997935FC1E548D4EBA978BE84F92404DD
+:1070C000D625E4D13DFF443EEFC4CF38FFCB5CAEC4
+:1070D0002772B9262482E73099E6ADE67A43949F79
+:1070E00076DE1EBEEE6ACDE471DF73CF3B87AF73F1
+:1070F000CE675CEF493EEF9C41AE77019F6FC16761
+:107100009CF7233EEF8241CE7B2BC7EFAD9F11CF83
+:10711000AA2EF1710687E7563E5FEB679CD7E4F332
+:10712000B60E72DE4D1CBF9B3E239E47F07937B9E9
+:10713000F09C497E777CC6F9CA74263FBBB8FCBA7E
+:10714000F59A983F502847A1FFD6101DC7A6A7AEB5
+:10715000F4B2F94549529FA0DF3A9C9FE74E597E11
+:10716000C7C27479E1A2BD7B3FCE34CF37799C464C
+:1071700094629E203F079D72199D27CDFA44FB899A
+:107180007058909F79FC251C9E25E7B90ED1BE5AF8
+:10719000637A36D3F8777238EE74C13FD0F8A2FD27
+:1071A0009C01E0EFE070749C27FCA2FD8201C6FF09
+:1071B0002E87E3BBE709BF687FEB00F87994C3F142
+:1071C000E879C22FDAB70E30FE931C8E27CF137EDC
+:1071D000D17ED300F87996C3F1EC79C22FDAEFEAC9
+:1071E0009377A7FC19E2FB06115206F7BC47117F03
+:1071F00004BF6F10E9398CDF3758A985F1FE799704
+:10720000FB5E94ED3E1515F1C37796C6A1FDC38BC9
+:10721000599EF2C31309FA110FE7B3BCFCBE7816EE
+:10722000B7071F9E28633CE9E190338FD9E0FED970
+:10723000C3111E2719C1F2988D72719F964E57C0C7
+:107240004DC430E4D3B0FB55C2DE13F7AC56A97C75
+:107250007E8B245B69FF87CB597DEB0C92948B6C02
+:10726000F7AFCA52780F080C5B88C3F6DF1FB3C8AC
+:10727000CA0A5B1EC6CA14E619A83C5F8422843879
+:10728000F2315CF7B6C4B9E135116B26A8B9A24A50
+:10729000768E571475FA0F8D70998BB6FF2DD79394
+:1072A0006665FA7B357B75169715F99A57F3F50BDA
+:1072B000BC55707A6E98F3C7EEE9749D2F4CF5605B
+:1072C000FEE80B47391EA72A49766E4E3CE9EEE3ED
+:1072D000648AB3199DCD477C143FD7BC482240C671
+:1072E000C036AB3D8C71B58F91FF30AE46E7BD66C1
+:1072F0005B4205FE9BDD199E0EF1C0AB5F0CAF82B9
+:10730000EF0A8CEB24110BD0FBF1B7709CDC36122A
+:10731000493252B59A2CDEE78CCF897BBF3C3E07C1
+:10732000616ABB7F399BAFBBA2CD6C8723BB8A1937
+:107330005E87FD3A9BFB99FF64791D7EE66C7E7F3C
+:107340007AB6CBCFECD49DF13AA3333A13E2DCCA40
+:10735000D5C72C1DE08F4A265C4BB921BA498573ED
+:10736000E4D9DB9AD9BDDA0CE75AD90FCD0DD8EDA7
+:1073700077718EFDAB6DE7B6D7459C41C41D5EE1CC
+:10738000F7F15EE679C57DF9289C3F72AF961C7CCB
+:10739000D2A9333DD2097C92FF9F7CF279F3C96F69
+:1073A0007467FCA113DE51792C8DA43F9F6FD0B57B
+:1073B000FF94D72F800E415F7A3A90C66C471EB17A
+:1073C000C8A772E36D0DC79BA8EB19EEBD8CF0F159
+:1073D0007DD6EDD7BF11AB867589380D2177B9CE33
+:1073E00035A746CE159750C4B98FFC8602EB29F31A
+:1073F00071FDA31215C777AD03E5BE00F20D390C80
+:10740000AEF1DA415F78FBD7E529895A12DE1725FC
+:1074100078CE07F9EAFBCA617F341DEBB67C6CBFFE
+:1074200059C7EF0BAD2B5393592CAFCAF9DDA2927C
+:107430001D7A3ABB4294702FD59EE7E186572B897F
+:10744000C5EDF0681C1EF7387333C2D3E0887F9D0A
+:107450002F3CDEF1847403DFAA948B917FBFE51883
+:107460004F2E4B929E7471283E0EDC55C375B9E8C1
+:1074700092697E7D8433FF49CB73DE4F518D5C571B
+:107480007E948BBFFAE242839B4F7CCF6735E783C4
+:10749000367E1FC5DDDFA72648240DDE7D61771E01
+:1074A0004612E9E00D39BF3BE0315D70BBC65F0FAE
+:1074B000CFD2E4DFB8EF57AE5593686FC5299890E7
+:1074C000E7D9CEF9523593782FEB3B3E29EDFA49B7
+:1074D00024FD7EAB96A487DF7D2F48CBCB75D221D0
+:1074E000C3FDDBB542EECD5D16F00992260CFFE739
+:1074F00096F3839173EDE759426F49BF513EA14B1B
+:10750000DAED737D2F6190F4553F1A029756FBEB2D
+:1075100054AF42BC96CA08E6F1BADB1F13F87B638E
+:1075200007C22FF474D636914FFBE9D601B906ECA9
+:107530007CDCD93FA31C723DA770BE7E6E80F567D0
+:10754000A2AFBFC49D4F3838FAFA40EE61DF532D29
+:107550007E88EE94FB4CF31193ADF77CE5FED3C22D
+:1075600039A42646409F69A11889D17DBE309490E8
+:1075700020CE6048BD71F0C7A84C8581CE1BE1527A
+:107580005DBEB3DD34DACF5324C73DD9207F91C32C
+:10759000D03E1E225DD07E7D9E5AB3A3BCBF9D21EE
+:1075A0009128F0BB91AF46E1B9182F7BAA733C6AD2
+:1075B0002628F67B58EEEF2D78A630FF54A376E808
+:1075C000F674FAC4CFECD0AC677D78AF2F1035924B
+:1075D000C092859549CCE32C6C2011F0E74A3BBB67
+:1075E000498C0EBA96C3515899C0FC80C26D093CB3
+:1075F000B7CFF39266D8970B1B13D202DB3C657EA4
+:10760000C6DFD3E6EAB84F7CAB9ADDDBEB0E2D4C40
+:1076100054C37C55ECDC2B90A79261141F8157BD9D
+:10762000CCFFACEC816F49B07C11FAFE9D16525133
+:107630003F9690F75A742C4FB698589A1FFFCF1068
+:10764000E4B7B45F32390CF90867020DA361DFF8C3
+:10765000A02584EFEFFB76240C7944CA91D7F03B48
+:1076600012FDFC1E574815E4BFF658403FDBFA7781
+:10767000F86CE7FC7DEBA2EB5D40E7B957926F84B5
+:10768000F9A0BE10F95457B4028EEF30C333D89727
+:107690009E76127DA21CBE6792946E2DB73DF75167
+:1076A000BB0DF6D74B4CA47B3F3E93AD1CDF13C103
+:1076B000DF2D7C91E3756ED539CF4DD6B7A4BA676F
+:1076C0008CEDAF1B19EEBBCDF54CBBDC4FE7990938
+:1076D00097D8299F4F9F5B3614F0F5A0C7798F5C30
+:1076E000948A392952026DE38532CA21FFDECA8AA3
+:1076F000F1E1A139B6F16772F895233F41FC669537
+:1077000027C477776A0B6D79FF23620DEC3B7ECD42
+:10771000EC7E8C38871C7D7D4F2B1C498C5EE9BC30
+:1077200037338BDFF32C6A9731EFB5680AEA505292
+:10773000D44A30BF6AA712A900FE7E88BC9C632988
+:10774000B02B1332928A6A51DC39CECE45B5CF4385
+:107750001C40DC1B5DD5C6C61B158E1C0D43FCA44E
+:107760005C467B793489E830FE68432670AF680C4C
+:10777000B18D43EB239B9DE3BAE12D0AC8F8DD02EE
+:1077800001CF28B25FB7F2707C92A4FD4750376FEB
+:10779000781AF8DCF38C11ED2EAAA8489134F392F4
+:1077A000DE5638173A6BFE01C66DF1F7E5DF05418D
+:1077B0009F6F93D8FAE32F2891DD40D75BF760BC29
+:1077C00066C48A4EDCD73BFDCCBE5B4DED01C303E6
+:1077D000760A2DC766E643C5A488CBC6FD232DFFD8
+:1077E0003DE6AFDEE88778987FDA46E043BF1ABE11
+:1077F00016E8E13FEA21708EE9B712287FA484D908
+:1078000019F796176783BCF99BB5B4FE5A9BDF83C3
+:10781000F06DF34B2AE48352DEC275A98DE1EFCE01
+:10782000A2D5FF966F3D02F3BC9F1FC3523C0F2DA4
+:10783000AC0B037F4EBFA51CE35FA73B258C7FBD30
+:107840002D253548D15E7A75F3842B283EE6E4C4B5
+:107850001E857E8D75DDCFB333DAE652F0EB6A21FB
+:10786000CF2F1FA68B337F70C45B1115EE838D5015
+:10787000539E207CCFE7C8ABAC8C5703BFEB7003A3
+:1078800086D2335862BD0B7E5380DF3F52486F5C17
+:1078900002FF682A216FD9E8063E9DBD0E67BAF641
+:1078A0007A26FC0F54D6D3BE6F8D855D3E62496843
+:1078B0001724D97710CCC8048053091D2D28B1EDA9
+:1078C000735EBE3EEFF485FC7B4916F76F22C4EE73
+:1078D000DF7AF9BA4087BF65EBEF0939EB8AF9F92E
+:1078E000AE43D8DDD2337F3901745CF5A407E39E43
+:1078F000D39FF4A42EA7F565DB25DC67E4434CAFEA
+:107900007FB04B42B94F0534D403EF9B3AD69BBCB2
+:10791000DD1BBE44EBBD4F2A6407A2A50EBF2F7529
+:1079200042ECA707587D117790966D3F3C1FC66BC0
+:1079300038E025B04F2CFBC92D577D89D66FA17C2F
+:107940000C4D96ED6ED586D1FAE2A4D405F553D34D
+:1079500008F2593C574B425ECBA96077C13506EE21
+:1079600063243C0ECEB7BB0BAEA6FCB824F9C42CE6
+:10797000E8B764AF049154BA8EDDCF1752B8967D44
+:107980005FC2FD71E99E2C12B6E1F3045DCAE5F415
+:10799000FD0ABA4ED087B790C42CA0D7B2DD9B3475
+:1079A000FB3EF75E4B19A67E88FAB2EFD37968BF2B
+:1079B000E53F9422B0C4E590EF00FBE54F7C753BBA
+:1079C0000D585FAB561A8075ADD1A0DD2DC9054F9E
+:1079D000F9C200DF766D167DBF64DB766D5139E04C
+:1079E0008DDC08FBEAD23D1792B08DAE273A15F434
+:1079F0001756E4E83BF07BA286159A9B261EF25EA2
+:107A00000B71C0B584EB0DEAF769736CED9FCACAC0
+:107A1000413E5DBA4771CC23E81F3F46D83DB49F35
+:107A200005F01E9AA09FD8AF04FD56880FE5A9BDAA
+:107A300093D3C103DFD5027812D4BF81F2FE961032
+:107A4000960FB684914E9B018FE3585E0A3CA77255
+:107A50008BDFF30B5AF0A129B88F625543FE656E98
+:107A600094D50BAE8F49E173D8E9A2DCEC892D00E7
+:107A700023676AD6F766AAD41FDBACC56E8590B5BE
+:107A8000A9EE983983EE798D59D1C959B673BFD50E
+:107A9000FC3B3217678571FDAB0B35C4F7E61B263F
+:107AA000EFE4F127DC2737DFB0E851888FD3FE5FA2
+:107AB000C902FF829FFF65EA5F30BFCAD1BF607E07
+:107AC00083E83F0BFBEBE7EEBF79FE65CEF9E72FCE
+:107AD00011FDAF42F88D73C35F70E354E7FC373696
+:107AE00062FF262FA36F6F8E8E79D66DBE48CA03B4
+:107AF0007456097E875ACD2DDD01EDC4BE432D4B52
+:107B00000BF2B68DBD3915EB889D8FA6CD073802D7
+:107B100054BAEC7C945DE577C8558E95EBA80FA917
+:107B200019E6689F1F2D76BC1F5A77818B2F0DBCDD
+:107B3000B78875000A0C730AA7364C437D543D8CF8
+:107B4000D9C1771CF261FD8ECBD8FAEE1866A01C65
+:107B500003CCE097DFA1C52EB67F2796AE4B82C33C
+:107B60009C9B8DD89DB08EFEE761199EFB79BE93DC
+:107B7000DF4B50DFAD299ABC336EC367C748CA0FCD
+:107B8000B4DE96A531BC733AAC19B92864B7D7579F
+:107B90008FD4EAC0DF80E73719305F7435CCD7A4C3
+:107BA000F59682DDE19EC75B5CE598471FD580F3C3
+:107BB0006CCA62F154318F7754836B1EBD6E077FA0
+:107BC000CEE77900F82CD33C6B8A2F73AE67D412C2
+:107BD0009CE761D73C6B462D71CDE367EBA1CFF9F4
+:107BE0003CC973CDE31D33D5B99ED18D38CF3FBB92
+:107BF000D733BAD1358F81F3C07398871ABE61F835
+:107C00003E96E6ED5D84F47FC687768EE68D3D86F2
+:107C100076CEEB3EB473682B0BBFA355C6FCDBDB03
+:107C2000B272913E67FC94FE869DCE719E7710479E
+:107C3000BFF8660E22495288A87E5BCE79B07EEFEF
+:107C40009C51AD501E981E5A00FEE883018CE37DC6
+:107C50007060BA76531A7D7473C273A2C7C6CF7DA3
+:107C60007A95C7634359EC1C52D44FF0F8CF5B10A0
+:107C700027A2E5DB1E82FED0711E2FEA87B715FB17
+:107C80009DE0E77A27B6B17DEACCA663ECBB3971FB
+:107C9000F272F964F81E0DFB777322CBE18F377116
+:107CA0007AF4FEC49BDC81F4B086E3777F3B8738AF
+:107CB000E285BF39F4B5E759DE1D190EDFCBBBAE47
+:107CC000E389E7A0D92BD282912BE87AEBF66FF209
+:107CD0000CA7F50F3C3DF323866D9C3A0FDEBB17D6
+:107CE0007EC837621E87FDFCCD0667FD06973DFD09
+:107CF0004656B1389F65F386931EA0D73C3863A5DE
+:107D000024BC014A4CBE33915EF34DD657C0D374A8
+:107D10009787A470BFEBC9C738673C1FE33431B104
+:107D20006FB9E09BEFD1AD28A5E7FC3B15C4A31BC1
+:107D3000DE9E4359964CFD9C9ECEFFED81FB3B039E
+:107D4000C17FE34AE77B12F738BE4320F8E0DABA96
+:107D5000EA9DC76DFCF18DD8EC9DC71D789AE3A80C
+:107D6000DFD0FC0D47FB1B572E70BC5F105FEC781B
+:107D70007F53C7AD8EFACD893B1DED6FE96C75BCA5
+:107D80005F9C5CEB78BF74CF26477D59D71647FBC5
+:107D9000A603DB1DEFE543E3FF09FDC05F2978CFB4
+:107DA000F943E3C406B0DF3E34D977FEDFE1E7777D
+:107DB000EFF1EFFD2C07DE9B02F2334907BFA1C9AB
+:107DC0004FE599DA12138CFCD51D53418F10FCA49A
+:107DD0004685317C759C3ABB53F8BD44A55323A915
+:107DE0002170BCD21F87ED55FADFAB3DF4FDA4CC6A
+:107DF000EF954E35ED7BB5474D3BEE29A9B714EC19
+:107E0000C7F86BDEB4F7BFFBE5920C87FD22D3FB0E
+:107E1000933269B0FB6FF30C161F7A3E6BDA3C03AA
+:107E2000FC218DC97BE3BEC269E037346AA9D274F4
+:107E3000E7367DF37549F89DC079069397C549E704
+:107E4000F76F97EE19E390FB57FDB16B0CDAEEE498
+:107E500061857D2F2FF5ECA8AF5F04F35BF3E0396C
+:107E600039908FFBE32B2DD6CEE3D40F78B5A50642
+:107E7000CB7F6D89EE3C4E1DB5375AEAB0FEDB96DE
+:107E800018963D2D0D58BED5D28CEF8FB7ACC4FAE5
+:107E900089963896EFB47460F95E4B02DF9F6CE907
+:107EA000C4FA072D492C851C087B9744B93D290E3F
+:107EB0004C08AB9FE66B500A441C3382DF8F3A6D4F
+:107EC0009C29053BFAF4AB5ECCBBCD842737DF653C
+:107ED000A69F85FBFDA2A433CE2C4A9F9FD1C72726
+:107EE000931AC891583B56C3389AFF990BD11EA7D5
+:107EF000CF55C2BEB71CB17F4FA26F7C481E1E3A41
+:107F0000309D44FB13DFFBF7C90BCB813EC58827AF
+:107F1000FFB34A33A3DBCEC8D72F1A187F68F315F7
+:107F20009E8D47E999DF8C82F8D4FBF9029FDDA38F
+:107F300020B8A51AD12DC087A7F77B715DA70F6662
+:107F4000B17C1408AA0D22FF75E91E5FD2AE1F9600
+:107F500075E5249DFAA23069D717A78FEE0C82DC55
+:107F6000AF0829C9E393803F2CCE1F8CEFC4F8CB18
+:107F7000BA8A9286631C67FD7442AAE9C2B858386F
+:107F8000FBEA34FE87285784349CE7BD3D6330FF0D
+:107F900080FA89C9E32CDE9964F3869276BE6C5C24
+:107FA00099953C3EA41FBE4CE37EDEF011B29FFCCF
+:107FB0004ECF7C0F77A092A8FFA6E1F72D0F7ACEC7
+:107FC000C0BEE3A5FF7D82F9422AD6C5B84D5D4A01
+:107FD000DC0BF778C95EC77CB45F58F8E8F6EFE6CB
+:107FE0009C4D77673EF86F819770DF66F7CA6370C4
+:107FF000AF9C8E774A353AA48BFBEF953771BE5C08
+:10800000A6F76831FAE8FDFD63CE990FF25ECB5119
+:10801000531D0B790409FC604443D7F819A01FDFF6
+:10802000DFBFAA00E2694B95D377A4BB2FFB91C1B8
+:10803000E26C24E9E9EDB1AD47C46708A1E3EAFDCC
+:10804000F003A79FB0D5DDFA5A947280C5DD97EF93
+:108050003D36EB4B14FEE507FEA8011C078C981C6F
+:10806000B0AD5FE2F7EA97EC795383F5BDE389970A
+:10807000DE750E3D75369C46C8711E1A27DD20C779
+:108080000BD96F30003F5DFB3A15CD777FE921F0CA
+:10809000BB0EE2BC42DC7BA827D120E06BE1FEA551
+:1080A000181F7EF7A92BB93D97980CFCF13E916BF8
+:1080B000607DEF939782936CF82B09303F86743084
+:1080C0003B46DC0BA4F6ACC3AEB9A5D3595F44E67E
+:1080D0001680DE58F4A007BEA14A1613DBF797E816
+:1080E000BAF302CCDEBD8534AF067B4EF532FF60BD
+:1080F000A149D4E1549F2EFBF14393C1EEBF30C0A0
+:10810000CE1D451C63712EB3F796E42535384FF824
+:10811000DDFE49F3BE04DCE74DAE867D9964A73FE2
+:10812000FFBBA9C309DF40F0BBE115F7DDCF8AA78C
+:108130007038943D52DAFCB42901CE775C8FDC13A1
+:1081400070DAF96B5CF5DA008FB32A44013ABF6F3D
+:10815000EA71391BDFE3FDDAF83E6F645518BEA7FC
+:10816000158D027F51BB6002B1B5FBBD11C3E7277E
+:10817000A51717E1FD72353501F3F174A2DA7F8F8F
+:1081800041F10727908B214EDA8C4EFD2A5F700754
+:10819000D45707D83DA8269053B83F1D9C7514E2CC
+:1081A000FA3A49A4AC2238FF76C6BF7D61673D0B21
+:1081B000E409F4093C007A4408C68BB2CA9CED027B
+:1081C00011677D491F9E528AFDDE47503752F87B6A
+:1081D0004D55EA49BBDDBC5C67F013F89E2A6D7F04
+:1081E0001BB7E79793701CF316438C0F6E9BCDF271
+:1081F000266E0B84F15EB2A45A783F620D74B5ED21
+:10820000634D1F492469D3EB4D6AAF067CD9F491C5
+:108210008ACF1F3662DF06BC6AC4423B57A7488339
+:10822000F36BD5A871D8BD6404FF2EA02B7F617DB0
+:10823000C074F87B422F78B85EA4FA624D201FF418
+:1082400060EF2C76AEDEA3B1F31DD64EEB6FB71EFA
+:10825000E0C8D4CED7DF6E53BA76CB7EFCF853712C
+:108260002AEF4B7EF49D201CA6BDAB260A20FFA161
+:1082700071777B10F8F81D351E8475BF9B4C9FF7F6
+:10828000FE73AEEF20DF09EEC92FE7747AEF07F730
+:108290005E05783FB3DB83F7EC9BF678535E4AC408
+:1082A000E5FB17337EDAE37D93D5D7E0EF2E341D5F
+:1082B00070CADB92C7BE5310C6C3BD38F31B490A50
+:1082C000EDE7E5BB7E3F0BEC9126D28B7AC2DD0F4A
+:1082D000E6FF2817F7AF0570DFDFFD5EE45B357161
+:1082E000BE6FDA7F2FE65535ED9F8D79544D2E39CF
+:1082F0006FE07EC88180F37736043E4892D9C5ABE3
+:10830000BEFFDD096F52784EEEFA655072C48F9849
+:108310009E38DD75D3234F8733EBF70FB85FDFDF70
+:108320002F89FDC207981D4F0EB2B2D1930A82DF8A
+:10833000D4B8DD13A11A84343EBEF3D1EF017FBF60
+:10834000E6C578C3D2C79F7BE5325A5FFA8427AF70
+:10835000962DC3803C604117B8DB0EF9BA820E4BF4
+:10836000FEE5392D7C117B7E776E3F3D963E715840
+:1083700023179D8DBFE95D8735FC4E909B2E5D6F69
+:10838000CE02BB7BD5F7FFA4817CBD7B4822438B0B
+:10839000CEEEDFB0FD39B4EB004F48474EA73EBAF2
+:1083A0009D45AFD4554F57623B13F6B181E8F53D7B
+:1083B000E0997CE4EB1F3E0DE705FFEA8D001E1AF5
+:1083C0007EF8AD20ACE76DB599F1F743ED05708E01
+:1083D000DEE089179858B2E70D0FDF8E7C77CBB1BE
+:1083E000DB0B581E9455C87F17A010E380DBAEC18D
+:1083F000752E2231E4BF868794289C937DA8929A9B
+:1084000027D2C8C7E541A6C7DEDEE1C58FDEBD0DB8
+:108410000A17FCC5979424BB6FCBF2126F17E71EA7
+:10842000F0DD465AFF5067F4CA0FCAE27B56BA83A2
+:108430006F77ADE9063ABD37D21A0AF14A8A873812
+:10844000C79B047A4839367328A31309AB93793F45
+:10845000AA27A7C37368DFEDB17C131CFDF8BEC665
+:10846000E6BF8DCF4FE1F6837DF67601B577D2ACCE
+:108470006F6950C83FB53F6C7C66937326F7BBD6D7
+:10848000323917729F9C5303EFFFED652647D00FDB
+:10849000F6790A576A28BE3F7CB5847AC14B52E907
+:1084A000E47B9787CBB7F33DF5CAD1BE157C42E19B
+:1084B0005761DFEAE71776CE4BE980F6DBA2076962
+:1084C0007FBB7D0EF3623BADFFB96DBFBF85EB8314
+:1084D000CB82AEDFDDD9963FA8EFE4357A928F7E6E
+:1084E0000FE497CA2BEC3F8D8F7B304FE40F7B9FBF
+:1084F0007DE53ACAE77FE81272EBD4A76EB96DD872
+:1085000077094927B77F302224ADDCD2E769E5D669
+:10851000E8417EFE5BE95381BF8541679E93D08F22
+:1085200099F0E8D68F7F0D84D9EF22B8F423FDF7B8
+:1085300032997C361F0AFE137CB7E49F97E1EF83E4
+:10854000F4F1A7E0BF3EFE14FCE75EAF137FEEF749
+:108550001782A122E2C5B4F4DC43E20188A7FE4CF5
+:10856000C178EA290AD36A4AE7537B8BF01E71BBB4
+:108570008FF9E7A7CCDE606E397EFF06EBBDF9DA36
+:108580006AD017E279AF8FC5BF4F457B83F63C9029
+:10859000370F2A4138EFEA49929A74FE08D5C80885
+:1085A000470FC9F49EC58B4F81FD07F3F94725811D
+:1085B0006E331563D44AF0F313ECBE7C7DEBB5410A
+:1085C000C853387570CC46D05F37BFA010FEBB854E
+:1085D0002AE49BDCC4E9FF0E896F9E4AD779D34118
+:1085E000E657D4AF4FCF2F4B78FB45C66D1AE82521
+:1085F000EA17BC658F872FE1BFC7D4B0CDF5FCE08B
+:1086000095C8574B5C7C15E37EE3E382AF269289E5
+:10861000DC6F93EDF96C3395F28D60979C3ACAE26A
+:1086200090A70F2A488FD37B2596FF04F1E029C03D
+:108630000FBD9A3D8FED24F05F9AEF1BF4BD7FF2E2
+:108640003793EFA24D1A9F7A7DC2565A9E7CEAB5A7
+:10865000D29F42FDC7BF1EF53A39BBFDF4437FC62A
+:10866000F3EC5387BC08C7A9433F1F7517D49FF687
+:10867000E2776A4EDDE365F99F8702C9B1F07E2497
+:10868000CB175AF5B33F4D60DF7F6943BABD1A641B
+:10869000FED8E983FFFE5BC81F3E7DD01B86753484
+:1086A0001DCAC2F3ADA6A77D18A739F5B33F4DB6D5
+:1086B000E7337DD6F52CE7DF413C15207590A77C8C
+:1086C0002A879D1B34FD74CA4EB847B46CFF610DF8
+:1086D000CE63A63FF39709A0774EED63F6C4079EDD
+:1086E0009E87E19CF577C11BD77820BE0BFBF53048
+:1086F000425AB29357C48D747861783845F100EBD3
+:10870000A27869007D99091FFFE71F161F7F9C0F44
+:10871000F3371EBC14E5A61F2F92C59E079270B5B5
+:1087200089AE9F3D3FF4A709601FFDA1AB15F7F986
+:1087300081D65D98FDFFDABAA5D460D65DF50FBB92
+:108740006EC6FF87826196F7E79283B3F9FCC7771D
+:1087500060FD878108C23B48F9AFFB875DFFA7A496
+:10876000FB3E4AF7E0C074FF2FD9EC5CF81F6FDDC9
+:1087700003D1FD054EF780097908A77EF6178CAF67
+:108780008BF50FB4EECDFF41D72DECA175722451BE
+:108790005C0479D8A9EEB004BFC3333701612985E1
+:1087A000E75DBBE17A3E9BF9178AC4E23664248B0D
+:1087B0001F11EE6FF4FD5EACC1EE57A9C66AF63D1F
+:1087C000323582DFD55B77C1C208E676908A57637F
+:1087D000501F31157FE7D6ED77B549C492A8FDA7A4
+:1087E0005EF0D5A360FF7BCAE4947702966F42B92E
+:1087F00086C7BD3CA6E6F0370C979FE00B3BDF7BBE
+:10880000F9783AA948C0EF77EB866A26E9FC463545
+:10881000FBFD68C8ED4CD8CE0DBDC4D69F8EB70306
+:108820007E93C5664F9E2FFEFE94CDFC4F45AAE871
+:1088300086BC58325E66DF3527EC5EF1BA1191E4F2
+:108840003AF443997FD98FCFD5DD80479550FF907B
+:10885000AD0FFD4AC2FD49950FA196C996CFD98E9D
+:10886000FB4B03D287D1635423A7CF0A073D04FEF5
+:10887000D3D0C5410F81DFF3A58B9B1E6EBCFF22B9
+:108880009BC5E7DC7472E483E433BF24450DE49FA9
+:10889000EFDD897191F77FF0E655D07EE94F150243
+:1088A000BF8BF6C1DE004981FCAA490DFCAC25FB5B
+:1088B000158C0BFF5F8242FCFF008000000000006F
+:1088C0001F8B080000000000000BED7D7B7C54D561
+:1088D000B5F03E73CE4C6692493249662633793103
+:1088E00049208246980408A82813020842AF038A48
+:1088F000606FD49167304F90B6B4D51F0389313C77
+:108900006C83220F4B7540545AA90D182928DA415F
+:108910001E62AD5FA3D25B6CB137E203150829ADCF
+:10892000FDE8BDF672D75A7BEFCC399389686F7F2B
+:10893000F7FBE7CB3F27FB9C7DF65E7BBDD7DAEBF1
+:10894000ECB97409FEC63376495C196B66CCC55820
+:10895000EDCF5319733276CF9EA4C8F442B8EEFD22
+:108960006038BB9AB19E55BD4773E17EF8A78AFF78
+:1089700029EC1EEE1E7E0BDCBF476377054B63E3DD
+:10898000C86BA6C3C4D868C6CEEE4F9913B133A640
+:10899000EC3C78278DDB31DB9CA4C4FAD91C669AA9
+:1089A00017FA05F079F8274A6488D27F3CC656F258
+:1089B000F17EA270F8F6992336846FE7364B08E013
+:1089C00068DCF9274B00E0A8FAF9CFD2BA61BEC63D
+:1089D0007D2A8B0E65F47789E173359A349CAEEF6E
+:1089E000E395B1805DA960AC01FFF5C1B5B37E3AF6
+:1089F0004B836BC7DA3FA969F8BEF954B735F67EE9
+:108A0000EDCF5FDE1B06D4D43EFF4C9A0FAE9F75B0
+:108A10003D95C64A69BCBB2DE98C6976CDD01FC790
+:108A2000BD98D97F1C98973137DCE7B75863C76A80
+:108A30003E5FE7374E33848FC138126E58DF67F8D8
+:108A40008F97B1B18E54E7C757C1FF63D8984B2AAF
+:108A50005C776631764D7F3CC5F015E6F4FCD9E7CE
+:108A60008F87013F67F79C791CE1AFFBAF3F3FFE6B
+:108A70007DC01F7BC5E6780AD6DDF8D3DFA6217D51
+:108A8000E57B331D0ABDD793CFC25EE8D7F36E52A4
+:108A9000240CB77A5E3E5DE083F5F6ECFE9BDB07C7
+:108AA000FD97BD3C291BD7BFEC85AA6C661F188EAD
+:108AB0009E158C4592F47045888EBE7D30683634A4
+:108AC0000F886B1C3D0E751E2A4038CF9D48F2273B
+:108AD000219EE0DEF272A40FD069386FDF07F86DD7
+:108AE000D8F5E09FD4E189F01CCE357990AE1F4CCB
+:108AF0004638198BE6320FE2B7B7D561EFDFBF8F8B
+:108B00005EC7819E23BE02DD76ADE6F37600DDD240
+:108B1000FAD3ED1CFE03F46944BAA5C4E8F6390B98
+:108B20003DE12D86766716D13511BEA25F015F3516
+:108B30000A1FFF7A47E07B0E949F3D297DF49A8EB1
+:108B4000F4FAD9E7050CE8FD89B9F74E368AB1DEAB
+:108B500097931CDBE1FE3D2FFF8EE4A4E785B72C45
+:108B60004847F8B32BB0AE1ED6F7D785EB6C50C490
+:108B70003A77A44693D262786F88CC98E24BA3FBF5
+:108B8000EFD3FD08E75FC45F2ED22772F0562501B0
+:108B90003D3A1C45B40E1671D1BAEB77FCC1827C0C
+:108BA00023E984F451C622BDDE9F8CF7259DE4BAEB
+:108BB000E3C773201EC6E8E8B683CB617FBAF65AD6
+:108BC0005871227A01BCF81EC20BED9E6D499A9233
+:108BD000CEEFE7C13A7ACC6C4E07C211517E97882E
+:108BE000BE8CADA2F53C1B2F97627D9793CBCBC17A
+:108BF000FD8FE2E5C70E078D2FF173F68BC4FAF9EE
+:108C000028CA39C0BFCF1E3A82FCC39835F2218CE6
+:108C1000731753587A710C6F12DEB31A23BD7BF6AB
+:108C2000A76A240CEB6FED38447A365EBE615D8135
+:108C30008E04F3FD4ECCD7B0EFE070D443675FDD18
+:108C40004FFCD7B0EB7D4B18C639BAF3794B776937
+:108C50008CDF517F4774FAFBEC73078793BEC5F135
+:108C600013E89B0FC5F88D078CE337EEFA9361FC90
+:108C7000DA7087C561BFFC3C9F6981D9B8DECFBA85
+:108C8000CC0CF5DF671DEA944882795F17F64BE25A
+:108C9000A9F52D0BD9B1516F274792004FCBDE9A22
+:108CA000F28774275E2D3E402DEB5CC9F9AAF3FED6
+:108CB000402ED2A5F3AD6FAA684FF6221EAF888D65
+:108CC0005B71BCA92A15E4B6E2647014B255BC3ECF
+:108CD0001873C264801BE6C946FDDC02E3F8601C21
+:108CE000A6F93D4118574D9B3C05E1511D26872DA6
+:108CF000A15DE5E399ED411602B8CC60B77D3A7EFF
+:108D0000F2CC4C1BCED271795E13EA85A5C05EA869
+:108D10009F3D16365403F89829D9FF148CBB74581C
+:108D2000A0EC08B4972EF0F8C3F0DC7B0B7FEF9C2F
+:108D3000C31E368DC0764104E528E5A2CA7CA0FAA0
+:108D4000CE2ABF5EC84025A408BECAED48213B9389
+:108D5000A2F93655433BA546F30346D947F6507E64
+:108D6000860BDFB3D07BDE0C45FB18D79DC6D250F7
+:108D7000DEE4F8B29F1C9769D1E1B87E66651A03FC
+:108D8000BB92C738DCAA584F31EB5290BF9B67A407
+:108D90006DC7F6D6D41AB2FF05ACF76000E8F664EA
+:108DA000DAE463A8C7E05F13F6CB6F32DAF741CBA2
+:108DB0008DEDC2B01627BF3E5310F8AFB8CD78DFA7
+:108DC0005955B964901FE46C7DE7140DF4B77376C0
+:108DD000E5EE5CC0E9B4356FF3F63395655E681F68
+:108DE0005F5F3755033DE2FC4D655901B4CF3FFC51
+:108DF0009DA9F4BC1690742DA8FEF5574F0D97C68B
+:108E0000E4D60560A6AB24CF37201ECE05CFB6E250
+:108E1000D3FA597FB5C023FC0B221EF2C7723CE483
+:108E2000D94FEE66D07F90A97B25F2E5132FFFDFA7
+:108E30000CECE7630E5AAF83B5383EB6E2E2D9D800
+:108E40004B23BF4C9F69EC63C9876A4C0E5477E88B
+:108E5000E60CE0ABD6B943374D465D5BE727FE82B3
+:108E6000991D640F657F8793E8335FD007E1B402F3
+:108E70009F2DE05DD822356C61346EBB2548F66AC3
+:108E8000A203E753C275EAA5ABBE3E5CF3907F90A8
+:108E90001EA92C15EF6B753E82EFB02BB090F0E65B
+:108EA0000AD155DEF7CC9DE30B019E6FC808D6E0D2
+:108EB0007ABC0B2F16E03AA667301AAF6A913D8054
+:108EC000F6F5C201508309E44B5EB7AF607E6DC812
+:108ED000C0CF8399A16FE3BC45BFF4ED3906E38DA4
+:108EE000986FF1DB608A11CB47F9B52CC61784FE69
+:108EF00087A09F07698AF2F76D1641F93B9FA4048A
+:108F000002D03E7FAF83F473DEFCE9C7D0AE9D4F45
+:108F100029EC88E2FDEFFB482EC11350502EF20FD2
+:108F2000A4476D69C4D77F8DE3EBBF1AF9D838EF3A
+:108F3000F94BBE7DDD349E438C078E113CCF17F478
+:108F40003AAF72FFFCFC0A1FC1016EE441B4BB5F83
+:108F500075BE4733843D15F4B9DF16D8887801FC17
+:108F60006FD6E37FEBC0747C42D0F18944745C68B7
+:108F70006D2A40FD704FB06332686E362323B40310
+:108F8000C73DBDF068AB19D6535FDD54824CDF9FFF
+:108F9000BE0AE973F781BB579AA1DD88F4F1F5A702
+:108FA000E388E565442F1D5D3B108E1107FE64428A
+:108FB000B8253D3729DC0EC4BFFF528622E6AD5BE3
+:108FC00069063C5ED86721FF37BEDF910C1FF59321
+:108FD000EDE1D60ABF06729A6D62A144E31EE9373D
+:108FE000AED59F9400FEBEF11C7C3CC0FB6B7ABCEE
+:108FF000BF21F56F7FBCFF1FEC0778A7EB57C0FBC5
+:109000003B5F8677E96FD70ABD50CBD6919FF95168
+:1090100060A67B30CC3B59B513FF2F7E4A25B98320
+:10902000FED3BDEE981E597C4DD3415CE7E21F2B69
+:10903000C4A7F3435CBF9F5938FD28EAF505ED4608
+:10904000BF69E11CD03300DFA2CDC6FB8B23717159
+:1090500020D3E973E08733317E1DC4F58C87ECA4FF
+:109060002AE4A16A51693AFA49AF987DBF213FFCD1
+:1090700075956D4F80F7FCCC42B2C37DED264086DE
+:10908000CEBEB3F93613EA4939EEC445A5D9E8CFC7
+:109090002C4DF57D69FC3568B9D19E178693994FA3
+:1090A000376E715BA6A13DA43DC7D0FF8ACD458632
+:1090B000E7C322571A9E5FB5B3DCD0BEBAE35A436A
+:1090C000FF11FB2618DA65D19B0CFD471E9B6968D2
+:1090D0008FEEFAA6A1FF9813730DCFAFE9BEC7F0CC
+:1090E000FCBA4F961ADAD7F77ECFE8BF9818E94551
+:1090F00096AC909E3CBCE2938A0F910147291311D4
+:109100009F556379DFC34B2C26471A5E4B4C0EE00C
+:109110008F57174C27FB7F78893BE0A36B4500E313
+:109120001EA68E1B154AE0DF4E727C5AF1A16EDE40
+:109130002AABD9A0D726398CEDF24C11170EE27C60
+:109140003326D328576AD3F4A8059A398B0767E3E7
+:109150007C205FD76672BD46D7AF205FE3B1DFE901
+:10916000B4682BB6A57C31615F2B051FC135602922
+:1091700047864A253B1CC09B3EBA1FD6203E9960BD
+:10918000F5E71DC1F598FC4E64BE89738287CD9CBE
+:1091900003B91D66434D5FC70E4BF9F6987C61B26B
+:1091A0005F998CF2495B1694A4331D5EE764F2FC70
+:1091B00011D87D7E75EC1CA949FC15E9EF4F19AD5E
+:1091C0000D8DDD57164DCF4679F30CA0072D9EE28D
+:1091D000613B40FF5ABC857495F75BE798A6441243
+:1091E000D0B536531170703F6B58CCCFAA257A7822
+:1091F000DEDE3804F0D550DD4B7E96C7D4BEE428C1
+:10920000AEEB572ACF93812785FA6081F09B174CEC
+:109210007D78C951D04B0BDE1C427A49CEB37545DF
+:109220007498DE3FC81B208E7A3A93EBF1C757043F
+:1092300086CD1F4270915E907E7941B87E32C637EE
+:10924000835813C5891B4DAC26D1380F8A71B29152
+:10925000E408AFC34EF2716EE1C9340DD6919C1A89
+:109260007A10D737774457058F0303FE99E07F15AF
+:1092700044EFD888FD0B3C1A8B28FDE7CFAE0EB526
+:1092800015C2FA5A324D7E3BB57B15EC9F741F63B5
+:1092900059D0BFE5BF5482A7E5D56B18C66749F61C
+:1092A00026867EAC5CD7A1CCC7083F6A670AD93D49
+:1092B000862E28E0EF5B82F69F7BE677A17FF1F9AF
+:1092C0000633CDF739ACD101E37FDEA946D0593F53
+:1092D0009A991C35415B6D4B257B5D803E27F45F81
+:1092E000D8991AF115C6F0A26D1EC7A260DF92F2DE
+:1092F000F8FA5B32ED117B21ADFB8799A36370CA4D
+:1093000075E70F1077BE22E06681A1063A7B210641
+:10931000EBC2B93570F6611C758399E2C205197606
+:109320008233B2223C6CBEB9FFFA5A3D336FBE1D88
+:10933000E0693EAE3215C6F175B7133E16023E2205
+:10934000BEFEF83EE72BFCAB4925B85F417AA99BEE
+:1093500027D3BA18FAF1F05EFD130A7BAC10F9328C
+:109360003485E89C63624F1526F00F50DE5C883F21
+:109370009E3FB0784AB89C78060FDB01E3FD2A7364
+:10938000407FEBCD4C6EF7E91AAF97C0FE85118E8A
+:109390000B9B15A2E76925623103CA6A6F8D1AEC2F
+:1093A000BE1A50C9DF88870BF4D8894C9D9FA3A6AD
+:1093B000DF371CC71DD83FDB7DD082FE9983917FAC
+:1093C00026F5E740FE19FA65C87FD22FFB384E0F0D
+:1093D000C3FA3E15EBFB34D1FA12E8DD1ED2BBDF37
+:1093E0008C26F46B5C96C47A29378BEBBB46878559
+:1093F000511E6A80BCBA2B4BFA71DCAF1848CF5DA6
+:109400002EDE285A5B4AFAF642972F3D13AECE0F56
+:1094100094A644E3A8CB9F1D8974596CAB4CCA0237
+:10942000F8EC5946FC6C59DDCF4EA567717CD1B57F
+:109430001FBEEC802F93015FCEAC2FF503B9DECDBC
+:10944000C1BC14CCD723F003FAF722E9DF5B7A6EB4
+:10945000C358B1FE962F449CCBFBBB859E8638F843
+:10946000868F7CD4FFCF48BF583CDC5D817150F3C0
+:109470000B57A4A31F3571EFED0EBC5E700E26BC1A
+:109480009CDB9B14C079CE6582FEB4637BCC51CC4F
+:10949000139C59712C538FD773CFBD55618671CEF4
+:1094A000ED79AB42C37C83C8A7C8E7F597DEA9086E
+:1094B000C2FBE1096C68935D475F2BD7EF1B6C3CE7
+:1094C0001FE1725B5AD908F06B5D19F4FEA36ED3ED
+:1094D0000FF0BE6A7DA7E04394E7B8FCCB06B3AFBC
+:1094E000D90E7C0E31961FF3F84B8705BC0B30FF6D
+:1094F00032C34379936685EBBDF0021E1F3A8BD8C9
+:10950000D04218CF6C52557CAFD7CBFCDBA14BD2ED
+:10951000E1F628AAA9E4AE8E00823F2A3993F07EB4
+:10952000DD598782FEBECCD768557CBCDE5996C813
+:10953000765D9EC63347233B96A27530D4ABB35CB1
+:10954000FC7D99AFA99A39275889703D60A27803AC
+:1095500014A582FA2B57ACA3D0BB67B5F4453437BA
+:10956000B215C3E40C5B0BFC3B18F09CE6330530F2
+:109570003F9A96173D61063F2CB785B1533A7F2F2E
+:1095800005990FD7F3A61AD90EF29FFAC578EB1CEE
+:10959000F0675292B9FCA4055B9760DE1AEFFF6B8F
+:1095A00039D285BF4FF451318DC4C2E90072EA58F7
+:1095B000E3B8927E9D2BACFEC1C0A87B5638E8FA7A
+:1095C000F40A0FC1F5F00A1F5D7FB86228DD1F485D
+:1095D000CE2E777D6805CCABE327E718C00AACD761
+:1095E000A93292C7874657A4CF4DA007E4F5B1151D
+:1095F000C7DC13870804023D72EA1CDBD614129DF7
+:1096000051686075AFAD0E8C63EC0173600903D6D1
+:109610007A20EB8B8998575AAB98288FD49A75701B
+:1096200075380FAF3E4EB743EF32CC477A47B52B74
+:1096300028AFDEBA76E283515D5D2C24EE07A0ED03
+:109640003DCEEF3F60E3785EC7D81484D7AEB0203C
+:109650005E7B6CDC9E7C6CE37AED53712DCC0A3D15
+:109660009C05F7FFE23851F20080672BFD7D01EE8B
+:1096700047A41CFA1BE56BD5E1162BCA87F7C0FB84
+:10968000B44FA19ABA2D0C4CE8F38FBC4BF92FD5EF
+:10969000122CE4ED9FAFC175B8D282DBD0C562E178
+:1096A00077A71EF680DC203F5C4BD808A31CAFB523
+:1096B0008976F8DF080F6BCDBCFDFC23BF5D1DA6CE
+:1096C000767031E205DB2D88978C0E8F09DAF695DE
+:1096D000EFAC3E763DB665FF77A8FF7359DC3E32AE
+:1096E0007BD08BFAA3AFED80F6D5BAB6C6DBCCCA79
+:1096F000AF727DF587FE763417F8B5E180D281A090
+:10970000790FAC57709DDE7DEB09DFF407F281CB5A
+:10971000A03CA6354C79AFA7571C73B4009DB5CCBF
+:109720003637E2FD0A4F281048A0AF7FEE92FE2A9E
+:10973000F4D7E7BF22E6DE6E9DFFEC655C6E580B4A
+:10974000E88704FE4091ABF23D27AC6383125AA335
+:10975000A29EF999D9817A8475713D74568CC5227F
+:1097600039E48FD4D978D3BC2AB46618EA893B345B
+:109770003FC6B9B585ED95688F6BF717FA57B218E4
+:10978000BFD46674B8CB917F328CED669117C9CE89
+:1097900068CAC828C5FD82F50598CF6F60ED777E51
+:1097A0000FE1FDB5CAD0AFFEF4E035E9D741BB1EED
+:1097B000DA68E7EB3BDFB2207F3EE8E4FAB3A113BF
+:1097C000F807C65907F21500C7639BE64846FDF443
+:1097D00074A0E94A74C97A1FF9CB541B3875CF14A9
+:1097E000051C446FE7A5D5566C5B1CC35819B62DF4
+:1097F0006B90DF6ACB4C5C8E98E557014DEC4F4285
+:10980000FBB78F54DD14B6C7EC8D57D8A7C6ADF69D
+:10981000B089DBA7F368D71A369BC2A8BF4CD62EF7
+:109820000BD2D78E7BAF441F07E16D99D4E771FA55
+:109830007AD9D4CC9BB0BDEC812247F84BF28A3563
+:1098400017535844E7CF3CE8E4725CA385699FA3B3
+:10985000E6621A3DFFE7CD676391915F369F9D9E5B
+:10986000CBF9EA62F3115D0F95FF6AE360A0DBB20A
+:10987000DD6653928EEF96ED16FBC9B640368EE349
+:10988000B2308177F0CF01BF5A615F3BAC819C3F22
+:10989000D427E7DE3513C721DD62CFD958831E08F0
+:1098A000607CF850B2D4038589FB27C7F52F92ED71
+:1098B0002BA97F3C3CAEE458DB0AFDB5BF27F5B5CC
+:1098C00011BEF5A6B8F132E5FCE56B26E6C5F8EA6F
+:1098D000B759D7FD2A3C189E67B457627D45EF0201
+:1098E000E643BB8CFCEAD7E9FDDF0ABFAFE662B115
+:1098F00081DE31BC9718EE9F5EE131ECCB2DAA5E84
+:1099000046FB87BF157ABE8685290EAAD99ACB2237
+:10991000BABCC4FF87E31F85E3BA01E0B8E17F1951
+:109920008E42837CC6E0186CB8FF8FC2B1FDB69240
+:109930009B0AA1CBA34AD85A8476E17E13E539D499
+:109940008C89BE95B82F70BF467E1EBA24589F5191
+:10995000A4B1635A39CA4F7B00E372B68AE77BE051
+:109960007E9BB99CEC10F9C1C50792EE463FADA8AD
+:1099700026B018AF2CAF94F61DE4BE1D13792BB999
+:10998000CF30C4C12A3570DE46B8EE263B5514AC44
+:10999000AE45674E4D1D958CF6F15153248CF385E1
+:1099A0001FE6F3B94C910E2BEADEB4C10EB477AECC
+:1099B00034AEFFD89A52B27FDB4D45572E01381E88
+:1099C000502A935F473C6714519E16EF2F85FBDBAF
+:1099D00085DD5233FC0EB453DB85DD6A16FA5DDE9D
+:1099E0004FC90CDE8DFEC44967C34DD66B500F05C1
+:1099F000DAB2C0DEFCC1D9B0C6730DDA1B5F9115B7
+:109A0000ECCB1F36D4AF417BB37DA52FC791116B33
+:109A10000FF93B586BD213F56BD05F69B12FBD07BF
+:109A2000FD1D78FE2B2BACF3994CA177C4F3A23E1D
+:109A30003D057A09F498BAB2AF1D46BD54D4A77754
+:109A4000EA49EFEC785CA5F641980FFD3E5847587F
+:109A5000C5F50ED1C8AFB7012CC9D0B60D2BA2FDEC
+:109A60001B58374B46FF7A187F2EF3EE962126CAF5
+:109A7000BB637FC4A3CDCBFB5B66303FEE3759524F
+:109A8000ED1487C83CBE2AF68F92451D85E298C129
+:109A90002EC1FBD675E54B311EB30E36EE935AE25E
+:109AA000EA2DD4F8FA0B7B94FCAFF79C22FF9EC5FD
+:109AB0003C978A63F719F397E3D57D7B4B25C2BBAF
+:109AC00034953954CC8384A2B40F196FD7AC604756
+:109AD0007D3AF9B0DA5920D17EFF8B2EEED7DA2FFE
+:109AE0006A14DF6C50C0BF413B9ACAF94CFA476612
+:109AF00087E45BA3DD95FE923983AF65D9D409D99C
+:109B0000187FABF68015FD9C838E728AEB55E6BFFD
+:109B1000B952E7EFB444A752BE4C7304C80FCFC686
+:109B20003811F33D0E3FD3FB39AD2B20B0BC82B1D1
+:109B3000272B4A26A03C3C668B5A8B91BE8F9A28D5
+:109B4000DE3B547E4F58C17CD9724672FA64857BE5
+:109B500002E6BBB769C1F43B505E8EC37C3E4E3714
+:109B6000BECFDAAC607EF7736B301DF5C143C8F72A
+:109B70003ABC3CE9E27EFD0527F73B1F3073B9682C
+:109B80000578A2008776F12ACA473DE0E2FAC95279
+:109B90003D91F23516C007E6E3925853D841EBE504
+:109BA000F9B5248FC950B7A75D1C4EEF5F709A0CB2
+:109BB00071751BACD3A7D35F3616A6FC1AE2F8A9C1
+:109BC00004FECB4141372BF8433EF24FE2F6A1FBB6
+:109BD000FB47E4AF48FAF4F9290AF8275F128F35FA
+:109BE00042BCACD7F78D5A2FE9DF468887F17E8FCC
+:109BF000C34AFEA1AC4BB00B7DD6EA09B55F877CAA
+:109C00009E9C361CF3001AEB20A4ACC3BA04D48784
+:109C10001EADB78FFF41E69B6D69DBB15F8BA8532B
+:109C200048F11BE52799B54703289F437572C31078
+:109C3000DF611A37C967BCCF5888619CA179E2EB14
+:109C400018C27DF54A546FA7B12DB8AF2CFDDE5C6C
+:109C5000512F742EE58F1528C7E0F78ECEA2BC4D8C
+:109C60002FC52D325FF375FDE46C1C03E3D1E57F56
+:109C7000AEF810E56CC6E442BC9FA2713E01575C91
+:109C80004B2AC7F06AF2E20C58FF37B238FF39D5D9
+:109C900076AAEB785ED8B1BF38E678298E027C527E
+:109CA0003D4CB2BF9BE245E1A7A97DFAF1DDD501AC
+:109CB000A3DF19D6FB792B1E7D77754B29C52BD4D5
+:109CC0007EFE9117D7603CF8804DB65FA036D8B9BC
+:109CD00028C64B6C6F920FF910DE0FA0BCB1DB4AA7
+:109CE000C8CF568B580EE263629A95F4A6BA3769CC
+:109CF0003BFAC110173F97A5CB739E4B3D5180FE99
+:109D00007082F1C286F10ABEDE78307F27D6CBC8DA
+:109D1000E713D3364755FE9E0FDF63795D7F0CC393
+:109D2000F88FBE90C4D6000A1F331BE55D5E378AEC
+:109D30003813F58DBE5ED1523D3F804C2DE53AC9BA
+:109D400093CCA23A7E9272AE5D1CC6A23A39C97615
+:109D50001512BD342D407924ED62293DBFE0E47C2D
+:109D6000D0BAC27199793207986724E98F81E7A93F
+:109D700010FA85897CA346752F522F0C24E7F1FB3E
+:109D80005AF17A515EA55E4CC1B1E1FA82CB984797
+:109D9000BF6773C75164A1CFECA17DAED158BF742A
+:109DA000320D4D789D293A1CF9F8A3FEF71B70710E
+:109DB00051CC33C0FD929D4B5E45763DEC0A7D8AC9
+:109DC0007ED02B2E919FF5803D54D1DE81BD28E5BC
+:109DD000F96B27E66343BE4D9318CAD36D948F5534
+:109DE000DD419F0BF13BB382720E12EEB52B781D55
+:109DF00099D4B3762D44F8B26A617E7584C08633F7
+:109E0000F6B1EBD24D189B691A97A35F3F7A96FC87
+:109E10000A9B1620BEB2394C3EF40B6C1017A2DE22
+:109E20005DE930F1FD168F95F2F5AD0A4488A03753
+:109E30009666147DE93EB6E5A29BEC2D40E2D1EB9F
+:109E4000ED7FFE3C4E611F8CF3680EEE37B043DCB5
+:109E50000E23123ED0E963E90FC4BF173FBEC4A76B
+:109E6000C4AF15F15A4AF630A1BFF1776137A5FEAC
+:109E7000CC96FAD675A2240A77EB95EE34F46B40B3
+:109E80008FFE1DF9A4E1EADE34938FF4AF9BFB4112
+:109E900061F13EB3EBF95AE6A9E5BA24FC4B5F5FEA
+:109EA00060D5EF97C4C31B6F67EDA5C6FA029BCFC1
+:109EB000585F20EBF6552D487C631E17B0A29CAC72
+:109EC00074943BD0CF69D17CBF0B505D8499FC6DFD
+:109ED000F0DF0DF3CBEB4320FF08C710B7C950F7F5
+:109EE00022AFA9B80F92E0BD496E8EBF870EDE4E3D
+:109EF0007A58F3F37DA178FA31D64EFC925AC21CFF
+:109F0000943F15F0A65D66DC81F8E807076DE4274D
+:109F10006B63AD11ACBB8C9F4F3507030AEADD3292
+:109F2000467EB29ACFE7578730AAD34E1B95C98693
+:109F3000EAF0D8EA9949CF97BA1C0CE9ADA69A8203
+:109F400089F845E2C9E33619F6AD3D926FBCBFA76B
+:109F5000FD151DDF4C74BBFAF38DC7CDF521C2A1F1
+:109F6000A76FABA7283B117D627A91F3D5E5F8A2E4
+:109F7000621CF03BDA79B86E8375746A6CCAEE5273
+:109F8000848B515D7BDD6C3B73805DBBC353799BE0
+:109F90001BC6ABE87A95D78B77BA2868AC13EFC7A6
+:109FA000CFFFB69BEBDBB7DD5C3FA69F083C3B1EBB
+:109FB000F0DCD995EC53E0516766623DFD03B76272
+:109FC000AC37D0BA87A3FF22FB57541BE70B0BFA21
+:109FD000DF2FDF0BDF9C89FEDC74C665A3D8AFF0F2
+:109FE000FA867D29912168575954BB05F0BA53C4AC
+:109FF0008D3B219E9C01E3BA935908D7EDCA827626
+:10A0000029BD1FD86D8F8DF76B8E3236A938B803F6
+:10A01000C79B94ED2D6B2EE4EFE3384792598BB537
+:10A020003C86F79B9380E532F17938674969ECFE0D
+:10A030001150EED8CFEDEE1EAE80FCCF3705DC68B8
+:10A04000473E7CEB7B5427BA88059EFC10E87335AD
+:10A05000DCC4F8AAE244D0827AE1537C08F87EDCC2
+:10A060001E5C8D7CB2A07DEA93FA3A17B6837F8797
+:10A0700022F1D59F1FB8FE0138C3D64C039C6C2C2F
+:10A08000C26DE5EFC5E3575EEF127C2CE909E8B934
+:10A090002A55D0730DA07E6E0AF7973B2D9C4E7DFE
+:10A0A000FCE3B2B4E23ECA592B7FCE0243B97F6FC4
+:10A0B000E5F4999B521041BFBA530BA4A07F3FB760
+:10A0C0006FBF3E40DFF5D4D902E9D720FDDEE2F1D3
+:10A0D000D7E94A7B9B02E39C3607D2516E4FBFA55E
+:10A0E0002A2BA9FE81D747CABAB3D366DFDA2BE1A0
+:10A0F000F9BC1FA98195F4D818579C6581916F62AE
+:10A100009CB54FA57DBBC287EF56AF86FEF321E01D
+:10A1100040BD34B7CA1E467FAEF3F74D7F44BB3611
+:10A12000EFF124DF2A98E7F0E6917FC5F6C7EB52FE
+:10A130007D4994AF2D52BC98475D5FE8A0FDB7E51F
+:10A140004CF8ADF74EAB1ACCD84FF15FB90F026B9C
+:10A15000FE98C9E74FAC9D08EBBCD2D569B2034C61
+:10A1600037643FB1D60AF47E6065D0837988731B6B
+:10A17000BFB516F3106E77A06BBC1FE0DBF49D69D2
+:10A18000D8EE7C4C8C175EBE16F30E2F9942850AD2
+:10A190003C9FB269FD34AA532E96E33FB53600F6D4
+:10A1A0007FEE1357FCF5048CDF90FD8B69E81F00F0
+:10A1B0007D053C0708BE05E364FB604A15F80ECE3A
+:10A1C0001466C8C79A63790DCAF7764A3F9D1D99F0
+:10A1D00086F9D879139AAA34187F53F61B6B4B87EC
+:10A1E0003136A6BDD21180F6D6EC37A7A5009F74F4
+:10A1F000B2402DE64D22D9BF9966BD1EC6CF328E24
+:10A20000EF54455E3FFCCE5A1CAFA23A5086FE4C3E
+:10A21000A9E7C3B55678DF8575AC30DF6D9B87AD98
+:10A2200043BF5EEAD17F117A14F4E61994877A6B02
+:10A23000F7514CF5162CEFB5F0FA66A13FF2385FF6
+:10A24000F7B58776F37A74D9F6F076E7AAC4FAE818
+:10A250002F1ECEF79DC9899FE76673FD23E526FD76
+:10A26000040BEC4A203FA66CFBFF48FEBCD9FF8FD5
+:10A27000F45BC665F45B86D46F029FA5467D0DD363
+:10A2800008BD7F6511EA89636E9FC15E5774CD2456
+:10A290007BF2AE47E8151F7FDF55C5EB817AF7A744
+:10A2A00050BE8B59BB4A904EF2BDD102EF550F4EB6
+:10A2B000DF84FDEABACC8CBEF3D85DF9A57E651DBE
+:10A2C000E6877571489D16A5BC401DE68747E27874
+:10A2D000BFB6A03F84E3E0771CB80F82F95D5773E7
+:10A2E00062FA4BBFAAEE62060B8FEC6F7F63E33B13
+:10A2F000E9F9E5D6151BCF98BFE83F9E45EC27C589
+:10A30000D9494B6238AB259F02BE4D3AFE5A20F820
+:10A310000DB427F9933D7B876D5F53A89F977F5FAF
+:10A3200005FAF9D9F1A82F41DFA3BF59A105A6610C
+:10A33000FF8AAE4CDAA792FC21F942D2B533B38939
+:10A34000F27EBD5B14F2A7E2E19A27E1DAAC703F3E
+:10A35000A43AA4DEAD834FCA038CDF29C61F35960D
+:10A36000E4E7C7DC9F06B9B903E517F7BD711DFE29
+:10A37000EEE133AFEE0FFFAF851F0574E4F87FC148
+:10A3800046750AF1F63286FFDCCBD0B3809E4B7F58
+:10A39000A86E40BB9946EF659F88A6F9A05F97E03D
+:10A3A000FFCE8E0FD2AE43B9D8A732C5C7D78D7AAC
+:10A3B000AB42EAE3F088372668E497C5EC878FFC68
+:10A3C00033A93FA3566BAC7F70E388692DA8BF9378
+:10A3D000B8BC3A55B036E531381ECEE67A6C6C28FA
+:10A3E000717CF303772A3D97F8DEB2BC8A7D00EBDF
+:10A3F0003B21ECFDD8EEB082745920F0D8E7CF08AD
+:10A400007D767352F773E2FB10033FCA36F83B0DBB
+:10A41000A662DD733BD7BB723E80B78561C90A5C1B
+:10A4200015B8DEE62914E370BE3CB5377B1BEA0F96
+:10A430006771A00CF58DE42FB02762BDA6BB66DA6C
+:10A4400039FFCF4C4087E785FE5CB099AFBFF33F43
+:10A45000AAA6211F74BE9D99B14AC7EFA7841F29E0
+:10A46000C795F224DF93CFF78BF15EC94E237C9C16
+:10A4700012F8433812D58BC9F770BDA4AFDBB8BE54
+:10A48000867587914EB0EEB0528EEB560C76A2CF09
+:10A490003E087CD75B00CF80C79DE6700ED631B9F1
+:10A4A000703EFBE5E517D643CF7BF7A792DE891F09
+:10A4B000FF5C368FE7B699789DD51113C833CA99DA
+:10A4C0009DC3DBB3D74BE3760B3EBABC3EFC6AF2CE
+:10A4D000B3CDC2EB62017EAA4FAC7F31779B11FEF8
+:10A4E0009502FE50337E87E7DCC4FCCD8CF0164528
+:10A4F0007CDDEBF171FD640991FFD6BB8551FC3A1F
+:10A5000004FC081FB41B83F672A53026A7251D0A7C
+:10A51000D1B16203D869C49B55E2EDF55DFA793F8C
+:10A52000CF4E357C4F5827E83F04ECFBB300EF10CB
+:10A5300018E739829BC3756A63C77598A7EBB3F7B1
+:10A540009E34C10FF170462DB91C4EAACB407FC777
+:10A55000372A06278E8FF3307B70158EDBF0CE9E68
+:10A560005CFDB8E91ECE6F4E75EE041BEAB1F5A096
+:10A5700057491D840EE17716F30F6438D6308A1BD5
+:10A580004C181FCA79E78B7C2DC865C50C585A49F1
+:10A59000DF3CA03F75FAAFC863E7FDAD5501AA7770
+:10A5A000D3B87D72B59FBE1FF73106B2ABFF2C7ECC
+:10A5B000003AD2BA7B77C3BA7C31FC7576DCBDCA6F
+:10A5C00086FAF204F3A3BE94EB1A52DD9D86753C25
+:10A5D0008D428F025E4CC807CE1FF958B34FA79F1C
+:10A5E00005FD86322E6F323E198A1B2CD0BED63323
+:10A5F0005CEA1BCA179C7AF1E567D7505CC1E9D5C4
+:10A6000058CDE92BE5F50E4FE85E0FCAC1ECFB68AB
+:10A610007F07FA55A0BEABDBC0E7817E1D8CE4B698
+:10A62000ABA01AF0F72F9ED4847473063B6CF4BE73
+:10A63000E0FF73FBAF8E201FBA6EEDADC2FBC00F03
+:10A64000044F67476A04E366F297F1FD97156EBF02
+:10A650005888F032BFDAE1D7F38984AF8FEE0CE887
+:10A660007E75ECFE906A3E6EE33E18978F43F25380
+:10A670007717A37CB3A40F801CC6FCBED43B2EFC72
+:10A680002C3E338647893FF97E03BECF78DE00E358
+:10A69000BD46D64DF9D33A359887F11ACB4EA2EF85
+:10A6A00054210E26FD73C4C6341BBCFF1A5CD1BEF8
+:10A6B0004F5297D0F742938A159273D010326F168B
+:10A6C000453FF2E6F129A41FD817F70EC6F5B85298
+:10A6D00038DFC13856318E95FC54A10F7F5300FAF4
+:10A6E0005089E9F1238A42E31CB9FEAAED549B2963
+:10A6F000D689E3A1DF7044999147FEACC86F00DEB4
+:10A7000086EBFDB318FF86055CDD05F85C1F27614D
+:10A710005CD3176785C7AFBB11E2AC31533AA226B1
+:10A72000074AC384E9DF817927419C6583F5DF8F80
+:10A730007C8CFABE30ACA6215C4360DD70EB6872A5
+:10A74000A8B4C91E9BC72DF25F6E51B78CFE3C5E4C
+:10A75000CD5E6E57D67BB9DDE81657703B12E6CB5F
+:10A76000FE533CFF773BD7E36B2A13D7376FF118C3
+:10A77000F39D378BFD2288B7B620FF40BC25EA77D2
+:10A78000F9FE12F8B584DFAA07AB69DFF4F3AE591E
+:10A79000E9FCBC072EFF0B44FDEC5DF7CFFA21F27C
+:10A7A000DD8758570F74FC48ECEF7DE808A4619DE5
+:10A7B000597D72E23AEA5F7AF83AEB051E4EAFE055
+:10A7C000E7332CC07D4DF083777BB8FD5AD47ECB28
+:10A7D00064A4FB2288E3715F53D64F483AD76C5587
+:10A7E0000DFB130B705F33EB1F8923CA06882346CA
+:10A7F00019E208396F7C3C716A85C7B08F32B7BDEA
+:10A80000589C8FC1FBCF637E827B5E5BAE611F96DF
+:10A81000B5B9BED2B906183F8413C26731DC3FB563
+:10A82000C20A02AE83E393C1547FB2C513FA9DC737
+:10A8300000470A0B1BF2C9E31CB4DF6FE3796CA07D
+:10A840007F58EF57C7C375C6F38FC66BC503E0B912
+:10A85000E47F255EAB18C7F51A6B57A89666CCC483
+:10A8600038FF59D8CB4B9E14431E607EB5B19FEA8A
+:10A87000E5F1BFEA4D31F8CD03E501F47EB3528C2A
+:10A88000FA838FD720EC56E1676F531DEB782FF7D3
+:10A8900033C6E60492BD705D27EAD8D7D9F877FEB3
+:10A8A000DBFE7EC8330FFD8D37CD5477C0F671FEC9
+:10A8B000A9FCF1B2663C37C0DEA138F4DFB57E6397
+:10A8C000B912980FF2E0167AA2CECFD753E78F5A7B
+:10A8D00006DBB1AE99C391D77150D1747A23AF869C
+:10A8E000F7F379CD86FA80C15E7E2E439157E60D4F
+:10A8F0002307A73AB17F40433B93D3A1901DCA6978
+:10A9000062F43D4ECE28EE9F7D63D436655E696C61
+:10A91000BD6DA619A50E78AFCD9DE247BDBD2A2716
+:10A9200074A517E13B198D623A67CCC92E0DE3A7D8
+:10A930000D3981AB100F729D3ED59183F627E5242A
+:10A9400087AFBD2F2FC1F536636B055CDB797CA823
+:10A95000B2638CFBBDB48FEB5E3594EC875C8F3BB0
+:10A9600053E85F370BED21FF9BB591FDB3727BEA96
+:10A970005E55427EB2A46B2C9F32AC1CF329C5EB12
+:10A98000A2DA5C78EFC5ADA684E7584C15788775D8
+:10A990004CD4AFE372F22EFB9907C85349BE4F99CE
+:10A9A0009238FE8308909E57FED8F94D92CF160B31
+:10A9B000C3FCA6C4FF869CE06C8427A7639B82B877
+:10A9C0003925EA234E25F3FCEDA935CF2AE887DDAA
+:10A9D000BB9839543630DC75CBD5C07CBD3CB758FC
+:10A9E000882E320E88C1C3E396262FD7EBAFE7043B
+:10A9F0001721BD1BF6ADA7FCDEE21DEF5BBE74FFA9
+:10AA0000E32BE24DA9E1F14DDD1C2BD55155FE584C
+:10AA100023BAD7B65868BFB26ED76EFA8E8DDDC72F
+:10AA2000FC28FF751DBB95F9306FEDAEDDCA021D28
+:10AA30001E73EB2254377E45AACC5F472DA8CFE387
+:10AA4000F91BF3FF68F78FDAB8FC9FADB487319F2D
+:10AA50007DD61CAAC37E67BD297EDC3F95787F6DBD
+:10AA6000F78D747E40EA9EA4285EDB4CDB3D56E801
+:10AA7000D776A5C58FFCB42127B40EE992A9053B72
+:10AA8000F1FD0C67AA1FF3E1BE24564E76EF2BE2D0
+:10AA9000614C1C5F8CB98FCBCB2B42BFC01FD571D3
+:10AAA0003DEDE5712E6E07A0BE3A6AE6EBD8C338DD
+:10AAB000BC666FE047C4B7C73269DE9CBAA882752E
+:10AAC0001FF1F3C6F82AB0CDEBFA3A70765850CFA2
+:10AAD000D70A7D53F9E31DCA073AB83BBC2AC19790
+:10AAE000B36B9B82F916784EFA06FA33ACB3CAD927
+:10AAF000C5F34CB5F07C814EBFC87524D033BFC0C0
+:10AB0000F5D84F761DE67A26CAF3CB02DE787A1E98
+:10AB1000F2FA68FEC96066E9BE253C14E3D0A3459D
+:10AB2000C9349E94FB78393DE4E5FE58CED61D8AA3
+:10AB3000C94E7978F2CB247CB2DFD89C09AF213C96
+:10AB400063A674111EEAB76AB49E4996E0E0253AFE
+:10AB500079F8AD909B5767FF91CEDBD9F08BB78822
+:10AB60001FEBDB151E0FB4BF6599857626FC131508
+:10AB7000F74DA671D3CE368AF3A8A675723D5CDF79
+:10AB8000B95B9B678FF169E167AFD23956F51D4913
+:10AB90000CF75381FFFE80F48BE753891FA96707E9
+:10ABA000A227E823FEFD43D822F2D7A1C299A931FA
+:10ABB0003D6D167861767EFFA258578C7F42E77014
+:10ABC000FE989EB5915C147E56FE2AD699D6FB154A
+:10ABD0003ABFC359C5F1A9876B46C27D32AE273152
+:10ABE0004FCEF32ADD053375DF93F5E97BF1FE7F68
+:10ABF00022BDB9DD88F2FBAC08EDB7843F9E7E57DD
+:10AC0000E4703F36019F693909EC99B4F3858FEF01
+:10AC1000D1F07B20C93FD390EE3AFEC9CAB1D0B87B
+:10AC200059391AC1B3B192EF5F6D34733BB671A558
+:10AC300095EA425FBB9DD7A9A57ED312C5EB11D380
+:10AC4000DC3A7C7E2487C3D1665A45DFC7815C3AF3
+:10AC5000734623FFA431AE1FB93EDCF03CD76775C5
+:10AC6000617B04CFABA90BDD3A9FEA109C363FD63F
+:10AC7000EFB2D061CBACD4FE7CE5DB73D082F04F79
+:10AC8000EBE0F227E900FA94F84BCA83C46B0C9FFF
+:10AC900011833C497A98FBFC895021F797789C52A4
+:10ACA000CA54DA17AAB1068EE2778C35623F15EFE7
+:10ACB000639DABDC4F9D2BE8F2B83D3812D7D96FBE
+:10ACC0003FF52BFAD9B5CBDFA0B8E61ECFEB7495D4
+:10ACD000720BF1A041BE2708BA0FCBE1F67D6A0ED8
+:10ACE000E79BDA511D2497B51F36913CDBA770BD59
+:10ACF000663F69D4C78C3D24D6BB8EDE9B94D2318F
+:10AD000019F721273DA138304E1E08CE45F81D18F1
+:10AD1000C64B5B0FA5DD8DF8FD02BC75DD7742DF0C
+:10AD2000CC11E743EE048413BF3759BECC1FBFDC00
+:10AD3000782C7A5CA1F342042ECFEEAABAE623DC8B
+:10AD400037D899EEC7EFF3CFECBAE5BB1F01DC674C
+:10AD5000778CF7A39FE06C0E12FFF4BA6CFEED3C0B
+:10AD60001F3A05F33D2B3B0EA5E177459F3E3BA2E5
+:10AD70001CF5F61201E767CFABCB112FAB9EF9F9AB
+:10AD80000DF8BC36A264A1FF7A76E713FF9503E3C2
+:10AD9000D4EC68C413C858F3B3BFA4B8C014D9C660
+:10ADA000EFEF4C273FF7D327D7DF80F86EEE68A68A
+:10ADB000E79F3DB98DDAAF3EF3F357FE03F31FC1B2
+:10ADC00034FA3EFAB3E70F125DEA421AD5C50FC452
+:10ADD000D71B771FE4FA12ED3CCAC11CAEC7245F33
+:10ADE0004BFEFDF499BBAED1DB0D79BF4DE441DAEA
+:10ADF00092B91D3923E4B67682BD0DAF677E66A396
+:10AE0000733B1B2CDD25181FD79572BE5891C3F5D7
+:10AE1000605DC71273839DDEA771FE0DE41DAF5701
+:10AE2000037F62FD19F4DA7189EAA89EA3FED06F50
+:10AE30002CE6496657BFCFBF2B2D6D32D7129CCF62
+:10AE4000F2E7B06AFDF38A6589F735B6E4D80DF903
+:10AE5000D19CCE19793ED20349FE213AFF37A7266D
+:10AE6000D48C7502372D0BF9F13BFA173F797B3201
+:10AE7000E6D39E19AA8C24FAAB0AB773613BCD5373
+:10AE80008FFB0E107F3C2BE4C4ED60CE6B613D93D5
+:10AE900034E6B4E395B1E366D20B4FD1F8E0E79026
+:10AEA000FFE6FBE5ECA7D0EFD9680E7947E3386DF4
+:10AEB000C23EEEE0F0C3FB0E7B398DE7B896FBEBAC
+:10AEC0004BF1BDF32BA73BD1BF8771BBCCBA780C3C
+:10AED00038B200ED238E370AF134253C87EC94CF4D
+:10AEE00042EB93E781C2FA297F2AE5333E4F83FA8A
+:10AEF00009F3ADAFE7541ECE71C5AEEE01F21CD61C
+:10AF00005CFE7C4A6E80AE5FF57CD15767F7703B84
+:10AF1000FFD2FBC4B70DC8B7387FE843839D97F5D0
+:10AF2000111BF7BF4F7C3B7F1FD7C70DFB2A2D1886
+:10AF30006F9D5911601F80A3DB20F86FA3D2BD90D5
+:10AF4000BE4FDB6FA3EF0E7B247FB6BFFF31EA9FBE
+:10AF5000A27D5EAAE7E9D9CFF9F488C944798023B4
+:10AF6000DBAFDAD6ACF4B7ABE06F939C343431E1AD
+:10AF70006F2F7B1BFDB3FA1A5E07DF10C747858F63
+:10AF80009F6A457EC900EF18EB32C09F994CDF6D78
+:10AF9000D6B1D128A7391303FB7369FF9BC7E739E3
+:10AFA00035A04FA07D9373B11F4B073226825F8C73
+:10AFB000FCE7BCDE8FF9A68DF91DADE83F87273190
+:10AFC0003A7775A3B97D02C6C11B27F91C8049C019
+:10AFD000DB0EF2AFD9508BB067F3C92F6FF0FCAB2B
+:10AFE0009FF2C1F1F2BF7F25F9770DBE643F9E83CA
+:10AFF0003B6D9FB294FB337686F037007EB13D2DDA
+:10B00000725D04E13927F027F1D863EEA2F3787B73
+:10B010005E48A2F30DA74DE4FC9A31B183F4C76BEF
+:10B02000FB6F247B2DF932756F12D9ED4CCDA1F851
+:10B03000295F744B12C2334FC0D32EEA8433841D70
+:10B04000295EC7FDB8CC5C2E4F99B92671B518EBB7
+:10B05000AC1C61CA3B9C13F42736D19DFB543F3F87
+:10B060004AF254B78B8FE74C0A94DDABE35FE95F9C
+:10B07000C97A03AC1B989180BFC7E6723B58F8F8B9
+:10B0800052A2FBBC1A713EC43AEE5730E00BC41B0F
+:10B09000D091F8E026E722A2DBBC75CA37898EE1A1
+:10B0A0000ACA1B4AFF2C7EFC71627D3B6DC1515860
+:10B0B00067D8EB4AF5E37ED7CE8C8089F2EE65192E
+:10B0C00094077165717FD125FCC598DC07479960AD
+:10B0D0009E4FDCA99CDE91DF6898179E92EB4BE8AF
+:10B0E000E7F58FF3F978D3DBC3C331EE91F5611245
+:10B0F0001F9195C973F4FA7482A04B64189B837AEC
+:10B1000003E2093BE5AF1D300FE613B65FF724CF2E
+:10B1100027F073A1AFCAE5DF354FCA0A8EA2FDBF83
+:10B12000E2E0326E3FF93AE3F1F1BAB09BAFCEBE46
+:10B13000B30CE3D8865BED7E94BB0D2F297389AFEA
+:10B14000C3563C3C08F89ECB21384C540FC5421ADC
+:10B15000D1A3A1291849CCF73348CE1AC0EFC33880
+:10B16000601AF2B993F83EC2F99EDB3F996F403DF9
+:10B17000A9F7B7A53E907A06ED1BF2B3948B861B18
+:10B18000BA4B90BE5F55AFF498B99CF7001E508E35
+:10B19000A4DCA4BEC8E565CD4A5F253E5F0372AF5F
+:10B1A000A7777C7C867062BC22F5FBAA9CE0B77313
+:10B1B000114E53B495BE7D15FAB8E1C5D52589BEAB
+:10B1C0005F92FAD82ACED3B4465222FA7D06DCB377
+:10B1D0004F2DA76B18ED51CAF2C4F998D5B9D2BE5C
+:10B1E000F6AB775A9DEBEA5FEFE446DB85F2B33DC1
+:10B1F00085BEA393F9A9F871BF2FF84DD245C62992
+:10B20000B85F80FD9F12F2B359C8E973E2AA8B7F41
+:10B2100088FF7DA6D0FBB8DF3F901D93EFFDB3F212
+:10B2200065721E694FE3E92FF73B703D334A07EE25
+:10B23000D77E50C48171FCF882F0A7EECD65746DA5
+:10B2400037473F27B95A92CA689F6D330B64E17E36
+:10B25000D92B57707908F496E0F857E68732F24612
+:10B26000C7F2C2781FE3935A8D85719FAC76A739D8
+:10B27000A2FF8E67277E4809FDCFA75AC32AF0F99F
+:10B28000B8FCD061A4677802FF5E2FFC3D1BEDFF88
+:10B2900080233D1AF54B23EB4E433C37A85D2598A0
+:10B2A000C7DCE20EBD8EFD4F99BA0A78BD05DF9F5F
+:10B2B0003A29F2BE2745DEB7D312CDFF8E3376CEC4
+:10B2C000DD05C6EB752E749932310E7C6FDF3B3F86
+:10B2D0007B09DEBEE3A573777C1FB1B526E5CE1FE3
+:10B2E000C1B5DAAA06F5E7FF9C4C4DAC674F093EA5
+:10B2F000EAABA759999430EFBF278FF34163DCFE87
+:10B30000EF9E3C1FBFDFF75D16DFFF7D6F8073B2DE
+:10B3100026E771FA748A3A9FF8E7D3C43C3BCDAC78
+:10B320006433C2B32D95F6D799C6CF37AB79A4D085
+:10B330008FFB929D45FCFCFCDE4715B20327CD5CDC
+:10B34000FFC0DFADD68A981D453705FDC41A4738C2
+:10B350006A02FD51B32C358AE767C27D6D1CCA5A5B
+:10B36000D841F5A673857D9CD7F4DADF30EF51A381
+:10B3700031EB3878EFB47D7E1A9A8785DFBA178F64
+:10B38000C061D9D5EDA22E519CD71698AE5E4AF970
+:10B3900032BFCEF85DCBDEBCA015F9AC3A9DE3BB65
+:10B3A000FA5E7E4EAFECFF9290DB7EFC86BC0AF02C
+:10B3B000FE51E1F6257E1E77FE84E751BF2DF7048E
+:10B3C000B368FC7BCF19F45A8FD2FDF48F902F977E
+:10B3D000A48A73D45881BE5ECA9FC7ED4B2DEE3749
+:10B3E000816A3C5FD655B2BC10F9BFB7E077987759
+:10B3F0003B904475B1B5B8EFA4AB671B68DF69E05B
+:10B40000FD269F05F9BCE1A2427C32F7C06B2750B4
+:10B41000AF3768DDC43F73AD76A24FC3458D9EB391
+:10B4200036F359FD777AED9EC0705C5FF8C17119F3
+:10B43000B46F950DF709CF43E99C8FA5A21ED99D46
+:10B440001F1A8DFD36A5A4DD85F1E1052B3F97A9D7
+:10B45000D1C2EB8E99F8FE59F209CB4B35F2C1817E
+:10B46000D7FF8670CDB786E81CCB05739AE8DCDC85
+:10B47000EAF4E86847A99EFEE3BED6B9B95EA137F3
+:10B48000DEB3F0FA9CFEFCCFE9B0278FEBAFF7728A
+:10B49000B81CBD57C06AF6E0F54AB8C27BEF158903
+:10B4A00076396FC78FD328E4E8BDE1DC7E8597A6A7
+:10B4B000243C97E46E218F7BF302B723BEE4FDA703
+:10B4C000051CEEFC40759E8BF46348F06D3403C69A
+:10B4D000ABFE25FF1D03D6D24B75257DEB2A11F05F
+:10B4E000BA13C3D5121B77118E07FD02E4C7BF62E2
+:10B4F000A3EFEFD874D0D7A89F97E633D4CF306F9F
+:10B50000631E1F379A41FD92681DAC0DF436F0EFB3
+:10B51000F9D13EA2CB9A4AE0D351E25C7E5F8CAF78
+:10B52000243FC5F3D17D79CA40FBE2F7E17CF1FB12
+:10B53000E28C0D267A13BF7D8DEFD8466471BC80F6
+:10B54000DCB7E691FD8D5EAD973B8967A92FDF4B98
+:10B5500036F245AA80F307A25F1F9EC5395ACE6214
+:10B560006E0765BCF0B8E89F21E82FAFD2AEC5EFFB
+:10B570000F64887133F2D2245D1E13F4CE4848EF75
+:10B58000AD9CDED0EF09EC579DD47B6716D8B3DBBA
+:10B59000C04FC2732FE13D2FDEEF97B798C8ED7013
+:10B5A000E3D254867EC24FF244DE6F542FDFBF1BBE
+:10B5B000DA4BFA682E03BDA35C9E7E9823F0823E90
+:10B5C0007C43D40F2958CF93496AC087E301BE3B1F
+:10B5D000F35C317CC7CF77121F815FF84A9EF8BEBB
+:10B5E000AF8C9521BDEE7CEBCFA977F8F01C74FEF3
+:10B5F0005DF147F6D0AB38CED9EFBE4E71C0494BA6
+:10B60000B4A4DD9EE0B925FAF82625F6FCAE9FA885
+:10B6100061FCDD8BCEAEB38FCE06BE9CDBA5FA718E
+:10B62000CAB9F77DFEE618F4AFBBCCB40F05FEC572
+:10B630003A3C179435717FF4A4C948FF33DF36D6FE
+:10B6400075740B7995DF3B4B7D25FD86C5CCCFF519
+:10B6500054323F87FDD49245F4BDF37C163C8AE713
+:10B66000B07FBA742AF9D38B58887E8F605E9BF1C5
+:10B670003CDEF8737CE3CFEFC5043FE22FFE1CDF16
+:10B68000BE7C7B55623F23359FF3E1198BA82F18B1
+:10B69000C0CFB828F857D61734CAFA8297BFBCBEB5
+:10B6A000A031AEBE20E68FC8FA822F284F68CEF7B1
+:10B6B000D1F8389EBECEE0CC84C4702BF9D2EF49CD
+:10B6C000318C2FC789CD9346CF1BF13C9F84DFABD4
+:10B6D000DBE9FE998589E749CFE7EB6E8CAB67889C
+:10B6E000BDCFEB18649C2FF9A2F1A297ECB16CF7D7
+:10B6F000FD0E43DF7B79F43CFEFB7C99A79772F04B
+:10B7000081C2AC5ECA9BAD177AD13F1CFDDF0FD062
+:10B71000AF4239BCD1F74A378038EFFBD794684540
+:10B720003139895F07F0D367FAEFE087E48B7379EB
+:10B73000FDCC4FDF490A3EBFF3BB93D2719FF5DFCB
+:10B74000EFAB327CFFD6F77DBC45FA7376835D663E
+:10B7500071767BDEBED7C95F9B6F0DD277781FBD38
+:10B76000FC5DB2D70B59D08DFC7DFEE52B0A42FF64
+:10B77000037B2DE1B9257CB799FBE94EF233660ACC
+:10B78000786E39C0FD45933560A67902CCE77053D9
+:10B7900028CEE105A589E7F05DDF077F299DDF3130
+:10B7A0004EC0AFE0FB80DFEBC595CD0D79106E7913
+:10B7B000AE00709307AFCDD7F87D781DAF0435A6E6
+:10B7C000FBDE74326BCAC3FE266BB72ACE3BA3F3F3
+:10B7D000E39362F8A276AA68B7DC7AE1CE0578DF57
+:10B7E000CECF27B6083816E68BEFA8ADCC8AEB4E45
+:10B7F000B2473FA57D40710D4FE0FE77B888D7ED89
+:10B8000026E3790A30AFDD7E2E8C8B7530079D13D1
+:10B8100060735C88621CA2FB1D897BF25DBADF91BC
+:10B8200060519E9F1AE879DCEF4C640AF89A857E95
+:10B83000F3E27987C574AE03E9B7875317D239E4C9
+:10B840002EFB32DA9FDE923685F62FDD8878AC53F8
+:10B850009FA23B97019EBB82C6F318B2E718DBDEBE
+:10B8600090B16D6527A93E4A89063D97B262E74EC1
+:10B870009A85BEB83599C3756B328FD756E71BBF13
+:10B88000130DCADF7FC9E4E736F4B8AD56ACB7C0D4
+:10B89000F83F9FC7FF7F044A435CC87F1FA66C7CAC
+:10B8A00060C8A3A3F0774F54FF2AA0536BAA6FA5DB
+:10B8B00086FEDBEDE277C2B40EAA63D8766706D5C2
+:10B8C00089B6DA1C9598F70CE7F37C4FA3A8F70725
+:10B8D0008AD4EE82F7B6CDCCA57ECEAA5ECA97F604
+:10B8E000AE66E41FF5E3D32F80FF01DF4F621BCF6D
+:10B8F0009398EFEFC2EF88BD0195EA74E5F31DF868
+:10B900001CE054045FE0FDF115B1DF712A3E507672
+:10B9100008CFC36421C5CFD38F3EE2F759C22F6F42
+:10B920003C5079F36880ABB86B24B1F1E00362BF9F
+:10B93000C59924F68DF9F9BDF1FD07637F68A71C51
+:10B94000F3FD6B1D3E32419C8DEF4D48A1751F17D5
+:10B95000F92626F4C39838F9BB2E260FF4BC4CB454
+:10B960001B457D1D9E6111A8E0E90CEAE7E4F2E1C8
+:10B9700067F28FCBEDB52CF687E354C5C6253D3570
+:10B9800031F6382687B0C472ABBFB90EFA1D99C123
+:10B99000F7D7C768D18328EFD7896B99B8B2B9EDCB
+:10B9A00084DF352B032AA3128890BA1EDA63AD5DBB
+:10B9B00059C8DFE3ACDD2B5D30CE3573EEF660BBEE
+:10B9C000A4A098F80DFC2F3A7728C36E8AF0EF28D0
+:10B9D000CBFC2847B3E7F07CECAC3956AA3B9EA5DC
+:10B9E000F1F3A198162ABC0D9EDF56CDF3C0D8AE58
+:10B9F000D6E559E4BEC7718853762788374B0AB815
+:10BA00005D94EF378AFA1FF9BC080F8AC63C59C10A
+:10BA1000E48FF2C99EF0FDDD3352CF0C6543E37E27
+:10BA20006FE67C3EEE5F56BE31909E303E177A62E6
+:10BA300056E01133F9E9425F48BD1C14754D5DE2D3
+:10BA40005C97772770BCBF5DB998F4C5ADAC89F43D
+:10BA5000F96D2C6C467CF7E9FF293ABF06E699158B
+:10BA600034FA39B3E7C4FB3D9C5FE5BCB7878CCFA4
+:10BA7000674AFF758AD17FADFECE17196417B39F51
+:10BA8000AEBF342856BFD41857BFD420EA971AF750
+:10BA90002D39E2D2D52F351EE0F54B0DFB2E57BFC9
+:10BAA000D44BFB48C7CD9183B8BF727C318804C0AA
+:10BAB0007948D4BB1CC67A97F2185FA6CEE47956B3
+:10BAC000605FDA2FC973A4F8D15F6F3395535EB608
+:10BAD0002D2DD5AFCF83AE59199AA4CFC7CA7AA559
+:10BAE000E303C4B7C30BB8FFBA51E179F1F0ED56E7
+:10BAF0008AE75CC541C33E844B652730BFF811FA25
+:10BB000059A3A93FE53D701F6F245C230AAFB3EF33
+:10BB10007B1FBF3BC27C649C3E7265F9691FC09568
+:10BB20007E35E5F3E71C28DB41FAC66EF3E3EF222E
+:10BB3000CAF1E784B6695847D478609B36DF1EE3C4
+:10BB4000BBCA02C1AF292C05F9B52FBFB72789F2AF
+:10BB50007B1FD983930AE0FD3A4B743833F233DD0F
+:10BB60001FC8AE2D12FC629E10BC7D01C073FE4D3D
+:10BB70000BCF73DDC7485E9FDF9F41F9496D2623D8
+:10BB8000FBD252C9F8EFC06CE3DF0B9CCEE0E718A4
+:10BB9000B5CC6064077B322713FD16B3C8513CA7B0
+:10BBA000A866ABD9701ED13D3B8CED3AD641F6A6C6
+:10BBB0006E573F7E26BD25F5633DF3A966DC07E899
+:10BBC00034BECF061BF56399B00723674D6CC67A68
+:10BBD0008D91A6A04AF6F73E7FEE4C8A9FABB91D29
+:10BBE000654FD3F957E7533F51B99C737D3C3AA653
+:10BBF000350D7669B4F0AF6ED0F8EF2A487F69B49E
+:10BC0000F89D85C3A6032AFD768F806794784FFA46
+:10BC100069525FF7D1732CE852E0FB07255D8B5822
+:10BC200011D215C627795030C0C9A4F1E9F71AAE70
+:10BC300013F301DDF9F977266B04F9A85569223D64
+:10BC40006D65425F2BA1667CF917E130E9ED6B5819
+:10BC5000D32DF87B9FE3AC5D29E497DA436B0B5C53
+:10BC6000313E6966D182DD8A815FE8F9D98C37126D
+:10BC7000F28BB42BD177B9BF318D811F08F3067ECB
+:10BC8000CFFDA0C30A8FF3C01F3C8C71DE1BA6A999
+:10BC9000C40F536119D86F92C348E71B3DC6F654D1
+:10BCA0005F3F3E50F5BF5F0112A7213CD3861AFBD0
+:10BCB00005A47E6346FD56C8BEE075E5AB8F7E0BDE
+:10BCC000E3FF94E56C28FA31E039FA13FD1EE973BD
+:10BCD0000503EE933C5790609FE4BCC8F75ECBBA77
+:10BCE00017EE52FAF34DCF91E5AA47C75F929F5FD7
+:10BCF000147515CA2FC57EEC289EF78BD979CE37DF
+:10BD000015A2752DF25D267E7F22F845FCBEC8F592
+:10BD1000FB6C51FCFD9C3231CEB5C83FE531BB1EFA
+:10BD200035D97D9622E4137F9BAAF6F7E7DD993E8D
+:10BD3000E297912669E7FD598CEC7C47B386F0EFDA
+:10BD40001F931BB21BF8E31DAE4F803F282FD5CFAA
+:10BD50003E1A9FC7F18FA4E331E147DFC87C144747
+:10BD60004C117E74B490F34F95FD560DDF7FAD8876
+:10BD7000E70926E206227DEF69B48B5556231FC4DE
+:10BD8000F317CC68D2CF1BCF6F03F1CD20E41B6932
+:10BD900017B32ECF379F0B3F2301DF7C5E307A60D5
+:10BDA000BE89E717A95776DB1C5578A670638D42CC
+:10BDB000FA78E49B839BB17D457D21D5BDECCEF027
+:10BDC0001FA2E74DFCF9A8AE808A7531C5CBC4F33C
+:10BDD000C26015B61B97F37D89D1C779DDCCE0FB36
+:10BDE000F8F3B2554D87F0BBB8C6307FFFC54F5B47
+:10BDF000E97BA148AB78BFB2BD0ADB8D6DFCFDD3FA
+:10BE0000B8BF3402EBDD22CD787FD8BA423F0F4B6A
+:10BE1000B95F3B5EF0E96E65CF217AAF9DBFB7E8B1
+:10BE2000A835997E6750F8AD3788758EDFCAD7E997
+:10BE3000FCE026FADDD105BD61F29F3E36D5559076
+:10BE4000DE1920FEAC54DAF3F07A23EA1315E90781
+:10BE50007C5DC4F71FB7C314658378FE42EEDB61D7
+:10BE60001D81BE6EA06C10B7FBB29F3B937FD7C500
+:10BE70001E4BA5BCAFDC578C6E620ACA19AE51F8D6
+:10BE80000109F7196F2C6EA2FDC51B07C9FDC56E10
+:10BE90000DCF752FBBF4E7C989F22B63C5BC9F8812
+:10BEA000BA0879BF265248BF23B61B9984BEC77E05
+:10BEB000F237D416E79433F11DD8EE42DE9E3CE80B
+:10BEC000891FB6E5017E4D4D1A9EEBC60A14FA0E87
+:10BED000EE5FBA58343DAD3FFC376A2C6AE1DFB102
+:10BEE00011FC0B9B2DDBF9F7885C2FCD926A67DC88
+:10BEF0001092D35B059D6E1924F29223D948D43752
+:10BF0000B304DD6EB382DF4A7AADDD1C27FFB307D1
+:10BF1000A1FDD832A0FF6C7C1EA71F6AC4BC0B8594
+:10BF2000DFBC187FAF54C5F3E6B9FFFCC916EE3786
+:10BF3000DFC33A288F78FE31EE2FD6C3F2905FFA36
+:10BF4000FDAED74E63BBBE23FE7764F9EF10F6FB60
+:10BF50009DD6529E9F3DBFA5BE02F373359BDFA4C5
+:10BF60003C708DD41711A3BE000783EB8B4D575245
+:10BF70005EC764E5BFA33912F405D6978CC4BA51E5
+:10BF8000187FB838876735BEC2CFDFF9EE20B237E9
+:10BF900053A8AE94C653693FF7CD802F461F69372B
+:10BFA000E2F54599CCD70CCEA47C96D41F658CDBEA
+:10BFB0008B78FFE811494F11F7483FA30CFD0CE0C7
+:10BFC0008F2E933D6232E9FD8A08C921C48DD36C5E
+:10BFD00045C83ADC9F1A79FB28ABA03F8BA3EF261C
+:10BFE000A2EFC0F193F1791CFD65FC5221E87F3B83
+:10BFF0000B505CB457D0FFED77F9EFBDCDB22F23D6
+:10C00000FE7BF7F7DCDF94F1D3D78F9B02EA3F1278
+:10C0100037F5D1DB067E640AFE1EC6D4218FE27E90
+:10C0200078A78DFFAEB5C2E9EBBEFD78813EAFF8D3
+:10C0300036FE7E8BEE77259AA72659711FB0D9CC94
+:10C04000E38A99D3DEAB98ABD31B8559952F0D1A94
+:10C050008DF4E8FAF61F30CE785D9CE37AC045F4A3
+:10C06000BED0C5EF5FD87A953F0CB7CF98C579465B
+:10C070004AD3422C8192702C14BFF7F259CA2BB4C8
+:10C080007F3C2323740CE970CF1B7B295F59C7BA0F
+:10C09000F8EF028B7107CE4B86497F595EE5F6B00B
+:10C0A0005749F6F3EF86C325FAFDA4633EAE67C792
+:10C0B000E5078FE33CD2DEC5D7159C5C72237DD7A4
+:10C0C000F9171648C7FD4C45E3BFDF1C3F2FD611BB
+:10C0D000B4E8F2D9276D89BF333D3588E7038A106C
+:10C0E000475807911BF800F1F78988033F11FB5A65
+:10C0F0009FA4F17DAE9EBEFEFCAAF9847E16FB6075
+:10C100009F641AE347D9CF22AE1FAEB0065B74F42A
+:10C11000F46D4A6A8A501D95A81B59C678BCB43F75
+:10C12000C3700E4186AFB2C887FB14C5010BFEBEBB
+:10C1300077EF7E6E8771FF19F7872339A12F10EEF5
+:10C14000061F0BE0FE2AF3755B6EC17D46F17DEBA9
+:10C1500079C12FE76DFC2AE1FA6FC3AFB72E0080DB
+:10C16000000000001F8B080000000000000BD57DC0
+:10C17000097854D5D9F0B9732733133213261B84A9
+:10C180002D4E16B2906DB261D8270920B860C25208
+:10C1900051B661DFB209D88FB6F6CF601090475B19
+:10C1A000A8B6C5CFE51910A8562C1183460D1A94D0
+:10C1B00022585B4704454B75A4CA222189602DF69D
+:10C1C000A3E57FDFF79C93997B3361FBD5E7FFC83D
+:10C1D000F37072EE3DF72CEF79F7F3BE27518E8A9C
+:10C1E00024471C63ED77FB4D4C652C4AD62BA09E53
+:10C1F0008CF5F2244711D4A7C8F7A2FE10AFC33FB5
+:10C2000003EBC5D81CFCCD01A5C5DAA2E6C0EFEB57
+:10C21000C25AFDE9F49E5D4A624C51998745432517
+:10C220009D39CA6DF874B8FD442614E1F01EFAA9D0
+:10C230003159D729B9D4BCDC02FDCD10FDB1FE3691
+:10C2400023F63F9D77C566341FFC5689646CA6852E
+:10C25000ADE907EF6735F736C10CD8A2484FAA3DC4
+:10C260000B5B8CB69F8071154F847A2902FAC67FCA
+:10C27000A3BA968C19D909393F5A8787315CF700E0
+:10C280001FAD6B7D4947C27F1732D6B1C76CDF0245
+:10C29000E35435BF7554817555C9F5356AD797EBA9
+:10C2A00050E87BC62CDECF2D8CDDCE14D613FA6978
+:10C2B000B2BA73115E55163FCD137A349567C368D1
+:10C2C0006B8747D1FA7BC3F7309F17EB5CECEF61CC
+:10C2D00001782EB3F3F58F512BCB4CB18C9D9BC7BE
+:10C2E000EC6678B4ECE0DC7A0BD4973DC0EC7C745F
+:10C2F00097810D86FE05BCBA9B5F5CB981392CA283
+:10C300008EC34EEDC11CE9817A1F77B4A60EFD32B3
+:10C310009CC752D16FBF457D35DF0FA84DD2B4BF4A
+:10C3200061E520CDFB444FBEA69EBC6EA8A6FDC015
+:10C330000DA59A7ADAA69B35EDF358524F06F0AF69
+:10C3400039A0322F8036C33B51F33EF3E9BB34DFD3
+:10C350009F64B5BF190EED1AC3237318E0517D78A1
+:10C36000E4162C99C7E5CB02F8CC13EBC86E98A362
+:10C37000E9E74CE4D803B8AFF37C0B6E658057B99E
+:10C380004D4B34FD2E552BF9BE6D083BEE87EF6A01
+:10C39000E107E199CF3AF6F783F9557B15670BBCB6
+:10C3A0005EB889BF97DF2D6EDA4CDF2DF66A9F2FBE
+:10C3B0007D5A5BF794B2F45A2B63CB1DB658C287F3
+:10C3C000BEACEFA520BA0AE0013482F1CE3DAE7AD0
+:10C3D000CD89089FD4DF0E27F88431AFA3EB7E9D73
+:10C3E00063CCD982ED77D89C1EA82F3C3897E663A2
+:10C3F0008ED7E241B8438B0711E95A3CB039B5FBFF
+:10C40000DEB358BBEF7AF846B9065D16BE31E3B429
+:10C410007821E15A0C3FDF255C9FD0C1B3609FAB10
+:10C42000DE4A7062932D83117E7CBE6656AE229FDB
+:10C4300063B1C067E0B99377C1CEDAAD1E03E0CF38
+:10C44000730EC578C212E827CFD8B217D7B346F11A
+:10C4500030FC2E9C79E3915FD417B724B4C0BEE4BE
+:10C460005B6A71E7D817D6F2E791EE2B4D2D39F8BC
+:10C470005EF6F785D54DCF5B95771630582F33B6DE
+:10C48000E4103FB4301A5FC271700F8EC74B593938
+:10C49000F1E117053E7FFED12282E30256BBDF05A4
+:10C4A000E39DF998C37731F350BBF91BB470E802F0
+:10C4B0003F1DDC006D1C386E8D58F712C6BC86E43B
+:10C4C000AEF0549A95165B0E82A159F26DF7A50253
+:10C4D0008E7608CFA1ACF31FF16F095F68A004F35B
+:10C4E000271CCFDE2B309E84A7E45B721C33AB5538
+:10C4F000E3910E747C8CA56BF709368E617DB0A834
+:10C50000BD023CD4122D06EB85FDE0E419BB518C35
+:10C51000C3E6B8E3114E16B681F66FBDE25CA7C262
+:10C5200038EA0D89F50CE0596077A9B85F45CC373A
+:10C530000D9F175B1AEA8DD0D50DECA2FD04C81330
+:10C54000D67B7BD5A598C03A14B92E8FC28C501FCC
+:10C5500021EA933C8AFFB1445CCF5BDFE2B823441D
+:10C5600039094BD83F58E6DFFF0A1F0F571C0370ED
+:10C57000BC89AFA4C521DEAC516A996E7E475F8548
+:10C580007E5443470CB61BC3DC462E77BD3849F6B4
+:10C5900096E2A779FF88B9EEC752CAB76AD6307655
+:10C5A0001AD4AB1B416E456219DEA242C99A74F0DF
+:10C5B00064C6E35837C04A10BF97625DEE7B62E005
+:10C5C0003DD5D5AEF555B0863ED15796EF1B13ED50
+:10C5D000345F907FA9FC3DE76F8B04BC1649B9E539
+:10C5E000D5CEEF18FED287B13F9A0026F9484716FC
+:10C5F0008FA127A805894097D82E87E560FF40576F
+:10C600008E44E8BF5734D0A1124C77BCBD7CDF8587
+:10C61000EE74EB67B5B0B94300DEB642931B58EE3B
+:10C62000DCE0F55E053CA41E310FDB42F92F878369
+:10C63000D65DD5E3D8072E7C5DE84B40F92FF7A9EE
+:10C64000C6C4DC0DA8B734C4D1B8F2F9E84483D02D
+:10C6500027001FAF024EDDEF430AE943721FAE56BB
+:10C660001FCA451C2F0AC0EFE6AEF09E90181704B3
+:10C670004F06F0CCD6C05BFB5EC05BC2E36C916F33
+:10C680003BEE936A3BDC0BE1BC32BE7C12EECF800A
+:10C69000A3FE138A2130AF316AEBF6C7508E35A95D
+:10C6A0004EA4E5EA119CCF55BFAC12E9B7359BBD4E
+:10C6B0000AF4B3A8E94DD2CF5AEB809186750FA743
+:10C6C000CEF5EAE0DD151E7C1FE57A96EAD63FF34B
+:10C6D000BDF3B6190E5A67CD15E050130A0E677EEA
+:10C6E000CC669567E1FAB27AFAB302E366E1BE037B
+:10C6F0001C7E1E597E0FC2A3F0FDFE91089F316A79
+:10C70000F3FEBE0887158AD30CE38E32334F38EC24
+:10C71000739F9565ECEFB057C5FE5AA71DE011DF7A
+:10C72000DFEA54011E69F7A8E55EE8F76F2B96472C
+:10C73000CF85F2CB3A187A203C570CE5846F6CD742
+:10C74000273F85FED26CD39DEBA136C30CF38171DC
+:10C75000127F1CD1920C7CE27513B320BD8525D5C8
+:10C760001E1A0FFD7644A94ED4836355361AF14B39
+:10C77000C2393682AF433E2F7962ABE2B7069E8F55
+:10C78000AAEF285806654522DF77B9CE51651D0509
+:10C79000A8F74838C726F3F6CCD8913031883E72D6
+:10C7A000053C8EA15E07F0AC8E33AD4139D866E111
+:10C7B00075E64A27FD778585D3C7B1F0042FCAC730
+:10C7C00063B0561FF5D76263D620BE18EEEA792310
+:10C7D000AC9BBDA7B26D507C6D77F58C2278D87973
+:10C7E0003F42DF6A636C1CC269C5F8D2DED150C615
+:10C7F000D573F8E8F1A43191EBFD951780F00A02AA
+:10C80000CF2B8D2D26BB159F9B34CF8F03DC3CE6B1
+:10C81000407DCEA994B18CF88C730DB69FBB2E824F
+:10C820007982F4AB46318FEEE0521D656446804755
+:10C83000B5C2CA2FD7EED5FFA8045FFDFCFF2AF8CA
+:10C840004C5C59E8F51D12EB2B5B7BEB6F51FFAC99
+:10C85000F68531333C5AF172496F16A2BF4E385FEC
+:10C8600018C6BC314175A39FE0517D61243D2F5B0B
+:10C87000DB6A42BCC77E1CF07C45B8ABB7F33270B4
+:10C88000CEC579E07A2F44314F4CF0738E5781FE3C
+:10C8900063E9FDEF118080B79E26D5BB0D3EFDFDFF
+:10C8A00001C3B82DA1E62BD63F28CE48F492D9C2B9
+:10C8B0005C9B438C2FDBF58A067E6DE570AEC8EE7F
+:10C8C0003ABFC652FF4C9CFF8DA3992BD478E74406
+:10C8D0003B39EFC668FF0281F7A915B6A0BA5DBB68
+:10C8E0008F3DC5F88D37FB13B0FFB6F16C6A4388F6
+:10C8F000FEE57ECF88776722DFA9BC031A037E0C92
+:10C9000036D62AF6207AEB6EBF037006BBABE07218
+:10C910007036D17BD9DFE943821E99CBAA001DCDA9
+:10C9200016F26AF6D6A5B702CFECB45F4E6F02FBE3
+:10C93000058638CD6ADFB4617D8342F6C91C37C8ED
+:10C9400000E0370BB615AC41B1353B9EB191D1FC3F
+:10C95000F9BD58AE0E0BC859FADFC582E5A21C7F9F
+:10C96000DE835ABD75117BF02BD47B4E1FE27C0118
+:10C97000D453B2BF173CA2ED6FD1D65B4EE23C1749
+:10C98000E9F49F3454F040FF484B12F6C460361867
+:10C99000F9FFB26DE74D918EEEF1FF4BA0F394815C
+:10C9A000C827ED540E4D72E524A17FE13D3ECFF145
+:10C9B00049EEFC24F4A3BCC7E775AEF21C970F8FB9
+:10C9C000C7925C322313875FCDD32CDE7A98C75A87
+:10C9D0006023E1001FB399EB4152FF53D5E56A2470
+:10C9E000BC1FF2C58A6837F2E1676F1A87FDC53D43
+:10C9F0001BE1C2F5AC2F71E5A1BF607D85D5590F54
+:10CA00005D5AE07B941BDEDF0F79A32F6A070D1BB5
+:10CA10004BFB21BA35EF6D417FCA3AC357FBFB414F
+:10CA2000FB752399B39E05C6A969AE781EE79330BE
+:10CA300099CB97F589AE3C7B50BF4CE873D5027615
+:10CA4000ED7BD27E390CF6F7B103A44EC3FAC09E3B
+:10CA500087F90D627C9FD9458013E0098E1DACB724
+:10CA6000B6829C626981FAA006A5250CD653D5F83A
+:10CA7000BC01E560E57D2DBDA6A13C7AC6E8DC12CF
+:10CA800034BFD8D7FB943A220372689A62273D419B
+:10CA9000EAE57732F92F8BF066AAC09B3B853E3ED4
+:10CAA0002D82C3770E7326E077775958A401486921
+:10CAB0005A594311C9A9A5615128FF712DA1F65BEF
+:10CAC00096DDF995AAB7DB3C0AEC7B9BD2918A9D57
+:10CAD0007C89BE1EEE5FF26E49ECDA4F5D92A0C318
+:10CAE00054A11FA630970DD65DFD5ADAE6F5F0CABF
+:10CAF000DC03F6319FF891A5389FF4630BDA3D8B88
+:10CB00005F0D6F512203706176579E01BEAB99D8BD
+:10CB10003F7F3DEAA44781AF0081B585F913888E38
+:10CB200081DF2820F336258DAD3002DE55F705FD77
+:10CB30000BEAFBB74CAA3002DE5727F91718A0DE24
+:10CB40009654C5EB83FC27B07E216925AFE7FB1720
+:10CB5000A8508F495EC3EB6808026239921FAAF0A1
+:10CB600040FF5F4609B9EEF4CF44FCA97E25CDB065
+:10CB70003E68BDD664CEAFBE0CE7EDBE4C64B326B6
+:10CB800022BCD3FDA9384FD9AE2349EAC31BA8BDA7
+:10CB90005CA7FC8EC587EEFF7749BCFFC565421FC9
+:10CBA0008960EB106EB04D9E4880FFBEE6B42DD874
+:10CBB000FEC1A468DEBF1DFA290CF423E128FB9313
+:10CBC000E32E41798B7C380CF870101F6D4CE2F22B
+:10CBD00012C6594DE3A400FCB1BF89FDF370DF60BC
+:10CBE000BF8C62BF8CDC4EDD4CEDB1DFA81CE2FBDC
+:10CBF000054658C7BE8BD03E31306F3D7EEC15F8F0
+:10CC0000B1B81E1821E967C98447A322B85EC80AD3
+:10CC1000B5EB8849E6F0B32647F17576EE476F85A8
+:10CC2000C6A91770EC0F70CFBEF675BF2FE6F35D87
+:10CC3000AF3B68BF5C2ABE6FCAD812BC1EB02C3591
+:10CC4000FD7CB94AF75D311020AE333A99BE5B1BCB
+:10CC5000CE2CF49C6DE9FC2E3187EBA3A8A75609D6
+:10CC60007D9A79469253A152708DAA753E9303DF47
+:10CC700037282EAF35787DB7168AF5D9C5FAEC7C02
+:10CC80007D5E0D9EB2C31D09936D5DF1B713EE9DE0
+:10CC9000FD65E58BFE34741DAA3FA48FEEF6232CB0
+:10CCA000F93BDE0F394F1D3C3BE1AC9B9F8427D203
+:10CCB000337D97A5C54739CF0B823EBBD075E27552
+:10CCC0008E57C2BFABFA09EC23EA270E2D3E57352B
+:10CCD000261AE66405BE6BC2BD2C0AF8E7D293851E
+:10CCE0009DD79FF547FEED29E57E54CF2EB3B3DEE9
+:10CCF000417EBDACE4B8907E3D7AAEB7F3DAA34C8A
+:10CD00004C21BD48EB67688F73FA5CA89F9E65CE87
+:10CD10006DD0EF309DDED10EFBB9CB1AF82E204F2F
+:10CD2000B4F59F083AE8EA37EA48C0F9159A4B5F2C
+:10CD30007038191B9BFC14F1F7C29EA5CB13A17E82
+:10CD40004BF236E2D785FD4ACFA36BE6B6E4EDBCE5
+:10CD50009E597A3E09EB4F6DE7ED47B95E40FECE36
+:10CD60003CDB2B460F09E80F13921D5CFF28333084
+:10CD7000C423B37AB713E5A484677765A1D9501BA0
+:10CD80004A6FBDA3939EF97946B190CFC5D28EF775
+:10CD90001B35767C7BA4C5A3025CDB519EC27AE77F
+:10CDA00024BBA723FC6B225A67A20A7C5FC42726F8
+:10CDB000D4871417E81BE81771D8D97498A7D2BA8A
+:10CDC000BE9CF4C0254E8B91E029FC54B0F64BD0AC
+:10CDD000CFABAF3DF3B37E7C98729CC71041FF355B
+:10CDE000AF7DFBCD5F518E7E6975A21B7048F3A3AA
+:10CDF000CB51BF1AD2FCA76FB9BCB5D239959CF7FD
+:10CE000010F437C2F3E22633CD7F4873C67C6C3F03
+:10CE1000ECFDE664C48F11C75AEA911DB4EF79A9FD
+:10CE20009F3BF8DC8A9D542E655EBB7ED1098F2F17
+:10CE30004C0CF54B80C7FFE1F0B8B800FD8A6D716E
+:10CE400087D6F8494FEBCFFD98E27BD0CBD391CE7C
+:10CE5000CFB11E4E3C5768B7F17EF4FECDA315B09E
+:10CE60003E783EA2036610A4378FBA60010612A86E
+:10CE700097B0284DBDCCD247D37E8C3D51F3FEA652
+:10CE8000F80CCDFBF18E3C4DFD96F4219AF6B739A6
+:10CE90004B34F5DB8BC76BDA57B82A34F5BC9606F2
+:10CEA0004DFB82034DDAF7871DB40F05C7CACB507F
+:10CEB0009F77FADCF558DED8BAA1ACA78375F1EB01
+:10CEC00016FABDF5F87CD8C5DAA216D6D5BFCB9632
+:10CED000B8E93CC08CFBA2069D0F94F8881EDB0CC1
+:10CEE0004E47B01FF7D15EEE17709FDE5200EC0088
+:10CEF000EC91968E18DCAF31B31E5223715F3A1855
+:10CF0000F9BD1A4DFE5F0C43393F4325BDB7D1C86B
+:10CF1000487F6C9C9AED45DFDF51C5FFE25F914F82
+:10CF2000CD88207E3202345C5A379E812AB84F6EFB
+:10CF3000CDBA4BD862DD3EDDADA98FB1FF44D3FE43
+:10CF4000A6F8559AF7E31D0FE8F669A3A67E9BF3B2
+:10CF500051DD3E6DD6EDD3339AF7233EF7D7231933
+:10CF60008D6AF5A83698FFD0A31BCA705F861DF3A3
+:10CF7000CC407A296C71D7130BD957FB26962D60BC
+:10CF800057A13FEB8DBA782AF7D539C81FB5BF2E08
+:10CF90009DCA03754E7AFE765D3195EFD4B9A8FC33
+:10CFA0004BDD382A7D75E55436D43550FB5D754D23
+:10CFB00054020407A0BC888D11F207EA68E7B7198C
+:10CFC000FCD578E27AFAA96F884FB6F5F0B761FD23
+:10CFD0003EF68F8AD1503F9CC288BF59A14FA4C74B
+:10CFE0007329AECA14A85F48E6CFDBC3ACEB500E82
+:10CFF00034185C79A85FFFFBA9FF6C340E60ECFE6F
+:10D0000055E5F1F6285EB7409D361B0D33CF7F36D0
+:10D01000BA8633F61C8A8CA154AFC07A7B387F7FE6
+:10D02000E1A9FF907E2DCF9B2707CE9BFF9D1CE2A1
+:10D03000BCF9B9530E1BFA590E5D4CB3E1BA0E0997
+:10D04000BF928BE585CD86B2C498178672F1A84E43
+:10D050008F90E5A7D612534A1CCEDF3905F508CFCD
+:10D06000CD616C1BF08B890AB7473BF5C0142ECFFE
+:10D07000DB6F3393BD73D8E09A8F780E7CFA4984C6
+:10D0800057424ACF892857DA6D1D090887FE299132
+:10D09000BC1ED7F1A4E20CAA87F175C6A5D82676E6
+:10D0A000B3CEBE381FFD3A6F4811E70C2DAE0128F4
+:10D0B0007F65FD7085AB0AE5C4E112D7409CCFA126
+:10D0C0007233D18FA7DCE61D884CCEE82A9A12E491
+:10D0D0006F7934258CBE9B6CE274C6EE52BDDB4288
+:10D0E000D8692FA5707D9FF60DEDB93B23480F3F02
+:10D0F0006C608B768580E3BB295CCE9DE911DAFFFD
+:10D10000E213F02B9D64A3FEDA5784D3796F7B7909
+:10D110001AE941EDB50025A08FF653B56777D37BAB
+:10D12000B33C0AA373CD69824F3DD7BCFC1F47A017
+:10D13000FD272B229CC4C3ED83483EDD251ACF88F2
+:10D14000B190DE3263E28052944BD3C4F9D84C9B49
+:10D15000B1171D9319A34C76E8679E356F0D8AFFB2
+:10D1600005B115A628A82FEA7FF71A2C97A46C34CE
+:10D1700045435999F5FC1A541FAB80B48AC85EF236
+:10D18000FFB90EE6356BA5EAE0F693906BAEA5D736
+:10D19000148F21F110E188780AF025BBF03D016F72
+:10D1A000F9DD7B029EB352C4396D36CBBEA43DF788
+:10D1B000998B78D23AE3CFA9DDF8E7B5EF85DEF6B3
+:10D1C00081898FBBF4E9306FB03F498E7B48CCE357
+:10D1D000B089B914D4E3EEB2117EE44C3D7F5F1107
+:10D1E000AC3FA7D96EA0737BC9C77D8CFCF6459F69
+:10D1F000BB89CFDDD8EADF7E84119E37219D5C4953
+:10D200004E4DF2AC22F930E46B903FC8172FBA3F75
+:10D2100039427C7091E083B5C4BFF6D5ADA4FAFE67
+:10D220003A0F9507EAD6093EB881DEBF53B749F0F9
+:10D2300041AFE0834FD3F3E6BAA954BE56E7167C5C
+:10D24000909FAB4E14F8B432DEBD0EF9993CBF9CF2
+:10D250006C718721BCFEF8A899A9782ED16C263C68
+:10D26000050A78F2B1588C9731DBD73BBAC6CDE8C6
+:10D27000F96DE7FEEBCE7937C4BB1EC1F13AE3642A
+:10D28000503FBBA17BFC39C41C36E4273BB64E247F
+:10D29000FE71C8E1B0A1DEFA5CCAA489C8AF0FB9BB
+:10D2A0001CB630A8FF61EB24FEDEEDB099A1BE33C1
+:10D2B00065327FEF71D8C2A1DEB055D4BD8C0EB5FA
+:10D2C000776FBD93F84F0953F6213D9459124703E8
+:10D2D000BB06F958B20FE9E0A6F8D9A3910E525255
+:10D2E0001C840FE31DABF661FD96F4CDC618077ADA
+:10D2F00043F356E377A5B11546FC6E74FFBB57E3C5
+:10D30000776353361A83BF1B97F5FC6AACDFEADC00
+:10D310006C447D3005F9565CA01F5997EF257F4579
+:10D320003B01F134B7B99CF8784E5339F171099744
+:10D33000D2C915F7A39FAEA649B12B388FC94AE7CA
+:10D3400061BD023A44F545A016E0B3FBB6CE8B5E54
+:10D3500005DFD5607D28D57FB52A34DF3D981242A0
+:10D36000BE7C28E814E566057CF721D0CF2EA8679F
+:10D37000E0FAC87F38DB369BFA73DB50BEE6A67056
+:10D38000395920E4E65C512E12CF3FB5BADE47BAD8
+:10D39000FC3845D8635DE9FA1341B70BF83CBAD0C5
+:10D3A000B5F6BDA06BBF940F851D0958AF621BC8B1
+:10D3B0004F78A5F8AEC5C1F65B22C6493450FC854E
+:10D3C0003E4EA292F9787F0DBA380BE637D1796CD0
+:10D3D00053D073E247C2FEE8C1F9DE5464D6809FA1
+:10D3E000DF76CFCFFE8DF0BFCCBAB5EFC5BA17331D
+:10D3F0002FC5B5E9D7C1DC71445B4BAD87693FBB35
+:10D40000AEC71F7A3D5DD6C1ED7719C722FDF2A0E8
+:10D4100007D90616211FB431F4DF04F3892397E1FD
+:10D42000137A7EF45DF1B9CBF09BA48121F88D8C49
+:10D43000CFD297529F83BA07E3F33CAF85939FFE09
+:10D44000A4C39D8DFDB497767C6340FB2CD64F78AA
+:10D45000E6E9E776E273C5C4CFE9E1492AEEDB29C4
+:10D4600083E70FA8170DDFF624F19D36140E408FC9
+:10D47000855047BEE3ED5B3E18BF63E91C7FDA15BC
+:10D480002E1725DD833E48E588815C1E752D395DAC
+:10D49000C9B8C6F6CDDF26901FEB0AF8DE1D1CC604
+:10D4A000A8C3FD1EE4F7C511A4F2B42AAC4501FDE2
+:10D4B000AFB5A417E911AD034C462CBF6B3BB1755A
+:10D4C000402AF5AFB7175BFB145BF8B863C761D9A7
+:10D4D00064726F9A8D76D21033D949EF8A78C00979
+:10D4E000113C7EEA5D3C1F8676138E5F8C45F9A564
+:10D4F000B7375B0F4E2F75E474B53B619DA3719DEB
+:10D50000959F19EEC767D76A8756AEFC86196340A8
+:10D510006EAFBCC88C055763973215D945FE51E7ED
+:10D520009B58167DEE8BCE71A0FD29F507619F5E9D
+:10D53000210EA9B883EB0BA32EB2746321FA997A5A
+:10D54000D0F98D52FC276EB78A529E8B0CE7536040
+:10D55000330D56AF29491387146F8472BAEA1F8CB2
+:10D56000F536E6A37312BD3DFB96F043815DFB0BE0
+:10D57000C4DB35223E09762406F177CC4F3F9AF979
+:10D5800033E203E1A40F75DAB5BB0D145FD0687404
+:10D59000F51C8176EDCA81CE5550FFD417F7EB57B5
+:10D5A000A1ACB17F437093F45BB9F23CC153D65B3D
+:10D5B00085DF774318C81F282BFFA3921CAA646C31
+:10D5C0001DED1B7BC3B42C482EB286AF3AE19F0BF6
+:10D5D0007CAF02014876D6C8492E685721EC0FE689
+:10D5E000799DD785DD0516C52417F45B1127DAB3BD
+:10D5F00087F9FB01F2FD23FCFD40D9DFF989F4BE78
+:10D600008FAC8BFE3264FD4FBC9E28C76BE5F56C7A
+:10D61000590FE7FDD978FB9706364CF26405F8FD03
+:10D620009E81423EE6B13C1197B377E0E5E351B409
+:10D63000EF857C98F58CEA31E5E2FE8C8FF833D2E9
+:10D64000778342B17395F78691BFFB4C7443CEF25A
+:10D65000207B45C6AF9497D95CA8FF55BD98B645C9
+:10D6600015F13CA87FFCCBC1ED9831AA95CE27CE11
+:10D670003DC8F97E77FADB8295AF6AF6B3CB7B556E
+:10D68000E1F6381EDCC178671FEABD99EC8B141FE8
+:10D690009D9B7F2AF85D2FE0ADC5D18178B1D8641C
+:10D6A000E6427B35F625E0CFB8C79FFB881F2F7871
+:10D6B00089FB7FAB1E7D93E4DE1CD541FEDCB159B6
+:10D6C000EE2F106FDB6C3EF22B2E58F91ACDEB9B30
+:10D6D0000CA137D83BB282E179B62BFCBFBA02FC71
+:10D6E000BFFA21E1AFF73B2FB1EEA3F52EB9C6B8D3
+:10D6F000B6361B3F17758A7D3A6E700C16F08A4855
+:10D7000045FFF97C5F6A948A41C7BE5E3C5EE99D35
+:10D7100022B48BCED5DA18EEFBF4E57FCB7187F01F
+:10D72000FBEAED811938665C005E7D52851E14802F
+:10D73000EF001CEF32F0D5BEFF9EE1DBDBE83739AE
+:10D74000F11CF528A37E06FB8E9B82E36246A47241
+:10D75000BCECD9C4CF8DF4F15E23526DDCEF2DCE3D
+:10D7600067AA26BE331CCF67243D8C8A600DE86F04
+:10D7700007BC760ABC76225E4BFC0D9CD3C0772199
+:10D78000E82B80BF5AB88E4EED82B7E3AE00D7715A
+:10D790003F245C1B411FA673CDDDE1E44FD1C3796B
+:10D7A000A980AB84F7BD5780F3BDDF139CEF4D75A7
+:10D7B00068FC1112DEDDC927FDFEC87987A0D3A25F
+:10D7C000EBA1D34B69DC4E64463FC599EAF7BDBE79
+:10D7D0002B3DADBDC2BEAFFD21F75D0F377D592991
+:10D7E000CE3BF5CFB7A576CBEFBE1338FE6FF3A7D0
+:10D7F000CFA8DDAB793F6BE541CDFBD99EF734F582
+:10D80000E17E5F19A2B9F48F8F3CD5F126D6AFD750
+:10D81000CFDE9D7F7DC20B0B0D78FE56ECE3FEFD47
+:10D8200005E9EE7FA5029CDF3578EB6D00D71B8FF5
+:10D8300035A8741EE6CDA373C0E5628EE787FFF3BB
+:10D84000939F01DE9C6766F27FB6ECCD303AB2BBA7
+:10D85000E241C90595B982F4C4124B9411F5A9129D
+:10D86000D09443E1CD258137140F04F43ED5C2C2D4
+:10D870006281CEA74E5528FE692AE3F1D450B6B88E
+:10D88000E1FD04236B3143BDC26A6C31D3B91FCFB4
+:10D890007798C2A7C9CC46E6C1F72C3686ECE0C91A
+:10D8A000F810E6ABBA548A679B52CCCF0BEFB23676
+:10D8B00084A13CBDF3C07D677F06EFD96A4F118F0D
+:10D8C000D796F96B1F1BAEE51CF0522AA7F37645DD
+:10D8D0009C2B2B614E8C6FD57FF77E2AF7974E508D
+:10D8E00057A918FFD2F11E23BD5BD21DACEF8039C2
+:10D8F0009FE7670CC575B2B096B448D49F37966160
+:10D90000FBCAC30E824B4DF1AA1CDCC79AD1CA6771
+:10D91000E69C807D53B3F26BD2D3C7A83BEAB1FD3E
+:10D92000B9A3DC357E63AB47457B25E0BFF4CF442C
+:10D93000BABC921D24E77DACAE85F0E993BA0354DE
+:10D94000BE3BF24F45A867F8EB7C21FD97D7EB2F44
+:10D95000907E02E937907CE0D37BCB7A235E66A48D
+:10D96000093DD0A2F443BEC08CBC94FC3237AD8BD1
+:10D970005C2D48BBBC3EA87DFF3DF3D7ABC5F3CAC9
+:10D98000782E17F5F8ADC76B89CFF0599102E3DE19
+:10D9900005FA1ECAD569CC935D097C76EAC20D6191
+:10D9A000C394EBC7EB25D6CF1358883C956BE7E7BC
+:10D9B0000EDA47B54C25FB40C62BC87D5890D6459E
+:10D9C0002E2EB9C2BE2DF921F7ADAB5CFB7CE6F57E
+:10D9D000C935A6C9EBB8BF2BBE3E9076797D40FB1A
+:10D9E000FE7B5E7750FECC4CD510C817C178628C98
+:10D9F0006B6CF7F27CC845891B222938B3B8231217
+:10DA0000F5C6C57B54C243667419FB00BE2E14F8DC
+:10DA1000DACA5A3E407C5C387C21E5D12D7A3C74D0
+:10DA20005C71B568BFC4DA68C2752ED9AA6D572D6E
+:10DA3000E28A2B7768FDA2D5C36F3A89FD56EBE2E7
+:10DA40007976A689F8E17C96CFE32EB4FAA9BE6C6C
+:10DA5000AB631A7F65DBC53AF207BCF4BBD6873DE2
+:10DA6000FD83ECFFAE78BBF70AFBB7F787DC3F3DE1
+:10DA7000DEAAB6AD945775AD78FBD341AE0F70DE1C
+:10DA8000921F4F47DE04E34E7FD5ECF5E0F9689135
+:10DA900083FB37156F3D9EB7B57FCBC87F3447F802
+:10DAA00039BBCB4B97F106430E7BEB79BC814BC561
+:10DAB0003CD1C107CACBF0B8A2E09D5AD247BA3DCB
+:10DAC000B792F955227EE86AF99AF4EB0D3E554B70
+:10DAD0007A96D367277D68E8858637513E7E57FE64
+:10DAE0006E290F736338DC0AFDE5A4E7B585B5142C
+:10DAF0007D887AC2CBE121F5841EE95C4F98E499D8
+:10DB00001DC6F30DBB9C07F648C7F340C1FF0D16B9
+:10DB10005718C2698CDAFAEB3B107F7C2AF9F7566A
+:10DB2000FCFCFD3F3CE6B8B2DD5F633F4F7A4377D4
+:10DB3000FA7F8D81E75DE4973928CE0FED29F4EF68
+:10DB4000497F9FBE7DF1A0D2FEE971E4AFF6B970C6
+:10DB50003E9BF87CBADB9F9A955F69FC8BDD8D5FFD
+:10DB6000B3A7C83E27880E66A42B12CFED272C81C1
+:10DB7000FDBD5A3C18D13155A3FFFCFF6E574C50E8
+:10DB800041B504F999AD78B9FECAB81E3B9DF9A814
+:10DB90009CC93AA874331E7F3F8739A99C27F29805
+:10DBA000DFCE7057A4533C4C472F8A9F7CF17FB245
+:10DBB000106FCE8E1CB60163EDBE2F3DAE3DCF4142
+:10DBC000E3B7EFFE9F048C83B9125FD810EF9A97EA
+:10DBD0001EE23CE82F252A9DB7B0538F919CA810D8
+:10DBE000B730B0D1FC1CED5F8E44A29B005FECBD52
+:10DBF00059F2453C9FCDFECCC0E349162BDE81D0C7
+:10DC0000B4C96F20D2CA9E9FE855B1DEC8DF6757FE
+:10DC1000457915A8670F09E7EFEF8EF2A21F7D0681
+:10DC2000F3133DCE628CF8DD6CC6F9DE5CE6E2F9FA
+:10DC30000EAC2309F5B0F9CD161EEFCFFC29C8DFD5
+:10DC400073BAB17F5A049DE726717E9E5BAAF55395
+:10DC5000AC49E77CFC6446E967484F67D25D6BB12D
+:10DC6000CC8DF6AD7FB890FCF60CED8793437E42E9
+:10DC7000E78DF2BBC841A50F62BB9D0A8F4FF7EC41
+:10DC800031537C047CD1AB3C28AEFFED8CB25F619C
+:10DC9000BB4711F645DDC315BED3E4CD06E8C9C3C5
+:10DCA000E78F3617F9DFE141318D4BF5DF3F3D61FD
+:10DCB000F26A2BF9F83DA8F7460E723F85FB9A6B86
+:10DCC00062CC8AF37FC2ECDD42FA696D02FA2B174F
+:10DCD0003E6936A0DEF011885BCC43F96B9D85CAA6
+:10DCE000BF811D8CE5A7600763F919D8C158FE1DD7
+:10DCF000EC602CE75FC80361C1D8D80C5733C7EF7D
+:10DD0000D0F959BB053C3BC7DF63A2F14F66B809A8
+:10DD1000BE9DFBFD32F3E2A1CECEA88EBED197C14F
+:10DD2000B7EEF98C47D883A1E3B99E15F3C86934DF
+:10DD3000927CCF69F2472E086AF776BA89DE67EFE0
+:10DD4000FE9CF24FDBEC9DF07529B0E409065E7F86
+:10DD5000FBE979935767E1FC5D9FE1BA81BEFF82E1
+:10DD6000654ED3FBBFC2FC1FE89FE20EDA958EDF43
+:10DD7000901DA05B871E0E725D3BA37CEBF1FB9DAB
+:10DD8000BB937025C06F18A71BC42325D47A57D125
+:10DD90007C6F377714625ECBED97D49071C62733D2
+:10DDA0004A08CE3F97F826E124F6EB7AE9BAF3FC6D
+:10DDB0005BE02993F77720EF74A01CBA1889FA5E0C
+:10DDC0008538DF6F6A4C7917D7E739A0B2810EC268
+:10DDD0005F0DDDC566F0FD9165F61E5339EED3CEBD
+:10DDE0003D2752E659695F52E6437B63C6408DFF8B
+:10DDF000317BC8B7FFFD702CB5B7E35077B2CD6368
+:10DE000030FE649A65EF1F714933EC9F8DC1F89322
+:10DE100059F1CA7E2C673B12C762DC898C8F9F9BAD
+:10DE20005EB21F49E9566705E96925C85C82E4418D
+:10DE30009925020F053BEB63EC319AFA4DF1FD3465
+:10DE4000EDC73B9235EF6F49CFD4BC97E3DEEA2CA8
+:10DE5000D0B4CB8DEE4842FB0CD641F4C0B6A91429
+:10DE6000A797BDFBF0CD99509FB07D8A13D5929DA9
+:10DE7000E2FD845D655EDC8F7680A70914A853C53A
+:10DE80000FFCE661EC4CA7FF57EE796ABFCB710D32
+:10DE9000FA7F377ABFE4B34B9B2D45C867AFD60EE8
+:10DEA000D0EF4F7E86D62EE80E6F3AE9427170BCF5
+:10DEB00039A8B26D21F0062352391EF272C2219E9A
+:10DEC0003F76ADFCEC0BE4673101FAE82C757EB9C6
+:10DED0005C93F3DDE5E8A7FFB3CA281F4FE4F52DF7
+:10DEE000C0DFD500BEB3799BEFEF134BCF3DA8E762
+:10DEF000627EA90BFA5F9221F4A7CABDF7F7290C3D
+:10DF0000BC672B3ED3B467F72A6B34F5D589DAFAB0
+:10DF100083256B82BFEF8E2F2ED834DBE4A6FC4F17
+:10DF2000C5E50DC11FE47CC6BC114E717DB761BC57
+:10DF30000A3CAA2E7CCF88E7B0B775234725FFB9E6
+:10DF40005365B5A1DEDF93C1FDFCB7BE114E713044
+:10DF5000D7DAEF47004B8A337C89CBD18F7AFA8CA2
+:10DF6000C1FBEE11FD9F2DDAF8F36FF07CF46546EE
+:10DF7000719F67A338FFCF693C6930A01CECC1F1E9
+:10DF800025C7EE37A05C695F14E1C1B8FE9AC536BB
+:10DF90008A07CD4DEAF8C0025BBFEE99038F5800A7
+:10DFA000DF3EC624C820B9DA8E4611D437661C205D
+:10DFB000B97ACB1BE12D86EB58CF463C97403958B8
+:10DFC000CAE97C26E28D902FE863AFB99F75CA1B22
+:10DFD000E40BB87EAC1F78E64F871F8179D71CE42D
+:10DFE000748E11767AFB7E5A907DCF1EE77469811C
+:10DFF0001F1EA7A4A3EF7D1B4CD6CBD27903C5DD92
+:10E000005C2D7DEF407A8EB82C3D1FBA05F6A7E651
+:10E01000657E9FC5B9E6819417DB9D3CAFD9A412FC
+:10E020001DCA7A5BB33A0EF1569F7F2EE1CA5C4E51
+:10E03000A24F796FD4B211FF9C887273D91E230F3F
+:10E0400012E96E9C752A73048DB3F335F322CA73FB
+:10E0500013F36F97F27ACF3FA24BB278B92A84DCE0
+:10E0600003391D168B72BA4221BBF2C89EDEA50889
+:10E07000A7230A6B7150DE168F539EC4BBC3E756AD
+:10E08000BAAF243E9DE293A57D29EDCA297BA60C5B
+:10E0900044BDF283C6394760E7D8A719C984E7773A
+:10E0A000300FE9C147A2CA07A05F6282880F381209
+:10E0B000D5D18A7CF9C8880805CFFBA1FFD5D8BF88
+:10E0C0005CD791B0F201FCDE0919973CE8BAEE8901
+:10E0D0001BA3DE5B720B9E6F4F6776B42B6F57B935
+:10E0E0009ECB5EE7F429F95E8DE28BC679BE9D3149
+:10E0F000F1AB0C3C2F5EF90BE157157033F238C4CD
+:10E10000ABD5733BEDD9A7157E1F8A93EBFFD5C323
+:10E11000CFFCFA0ECC9303BB5B81F9CC69DA4BF7E9
+:10E12000FEE8EDEC4E7BE7FFD19FDAD55E2A8F1833
+:10E130005414F093EBEDA64E3D5DEA7BDB789CFC3E
+:10E140009B237EDBB614EA2BB645101C4F3F69F6C5
+:10E15000201F3FBDC54CF6CFE9E88E63CBB1BE2B87
+:10E16000DBE9A1D19C9A7BD1161A1C1FA2FC616F1E
+:10E1700087D17D1E279F30B7E0F9EEE2A732B6A027
+:10E180003D757280E3D91DE80F7C368EEE19606E06
+:10E19000FEFD6D821E91BE1CA07AA8BFB3911EB178
+:10E1A000F8853EC4C7E4FE9D7A229CF2E84F1F9892
+:10E1B000D413FD65AD86E7298F87A9560FF2E3A535
+:10E1C0005BC2490F5C697767E3FACB7E77DB1D059D
+:10E1D00038FEFB710CD7D3DEFC02F92B03FB1B5A74
+:10E1E000BE9F6B4EE67CA053DEF2B8DB5918779BDE
+:10E1F0004C71B70583E2305E55DEBBC8E36EF35564
+:10E20000C54579070F85CE231F3D489CAB4AFF4982
+:10E210000CB3C4231DBA19ADB7FDA1B42D68EF4CE2
+:10E220001F24F29F5987C89794F876ACFA55F29F4D
+:10E230009879BC5F78E873ECF2413CAF7881E56B8C
+:10E240008DFFA67AE5B71ABF4A751623B99B5FEF13
+:10E2500028B81BCAE502CE5549E593107E4B1A3605
+:10E26000BEF80EC1E5F11F7F8CE31EB092DF86BDC4
+:10E27000C3E1A7B7671658BE12F4B459A3079F7835
+:10E28000F4438A3739B13B3307F76D8EEA3B81F7A8
+:10E2900071B5D97C9FFC0CCA5D070ED1BEE8E7DBE7
+:10E2A000E5DC5EE17CA512D71183F12EE58B07D169
+:10E2B000B930A7F7E3EBB3097ED29FDB7E3AB4BD5A
+:10E2C00025E729FB97F393FDCB76FF25F6EBACC949
+:10E2D0009783F2B97FBA4393877D36D2971365C58A
+:10E2E000E7FC1CEA6C34D483F0E6FB3ADFB94BF868
+:10E2F000798E1A56DD6302FC6B6D7838CC1DCC47E5
+:10E30000AFF15C47CE57C695CA3CDA4D83843F7B5C
+:10E31000001BD04DFEEDE38827955DF36FE979771B
+:10E32000F9B79DF9B6FFE0F9B632BFB6B0CC501BD5
+:10E330009C672BF96161263CCFC2737FAD7C2FCCEB
+:10E34000D5B6EF8E3F0ECEE47E95C298D0F9AE7F63
+:10E350001EC4DFD7B3167EFFA0908BC304DCE5BDDF
+:10E360005F524FA9167C5BE6790E6BE6719BC34446
+:10E37000DE0E7001CA73ED72BF5B7C26C955793F12
+:10E380009F027D4D8F0E952FECA3798C641D54BA9E
+:10E3900098DD8825809FCAD1AC9CCAB1AC96CA7161
+:10E3A0006C039537B3062A6F653E2AD9A01611EF84
+:10E3B000792FCF331DBFD080F2B5F08ED07A71FBAC
+:10E3C00015E1E0A1FB03AF150E6319BFE7AF0B3CEE
+:10E3D000FAA7137EEBE1A1CFD71CC1FC7471C92849
+:10E3E00044DC64B4831D14DF5AC65C541F739570FB
+:10E3F00028F6BB8D3CBF57078FB2D0787141C06300
+:10E4000015CACEA2C03E65673AE8B9DC2F30C4E237
+:10E4100091FFEBF7513E2F8C283DEFB0E37D30AB01
+:10E42000A6501E7741E9F264A8A766FE6A0AE5795C
+:10E430000F2B7D01F3BCD39F7D98BFCF2D2D08738B
+:10E44000C2B8AB1E9982F98C6E1137ED16F1D2CCA1
+:10E450009DA7B91FCBBDEA1EBA6FCC3DC0EAC475FB
+:10E46000CABC7035999FAFEEB1BB7B66C27C13C648
+:10E47000F9D6704897F69E0A74DCEA0B6318EFBF72
+:10E48000D6C4DBCBFB6CE4FAE43D37BB76652E5794
+:10E4900092AE3C0F1867008EE35E3590F2E3DCBB72
+:10E4A00015E7E5C60B4F722765A2DE8549F14017D7
+:10E4B000FD841C6EDD959989FB949D29E27E621393
+:10E4C0000B108ED392CAB3B17F99179D2DF6A5BBC1
+:10E4D000724AA62B13DBEB9FCBBCEC9199EE3C1C54
+:10E4E000BF26E222E59BB5E5BDBFC69FD8354FBD2F
+:10E4F000DEC5BC26E22BDAFCF4F6F926BACFA9B0C9
+:10E50000DC5D8F21CA374EEF188CFA31F43B1CC703
+:10E51000AD31F913F2548C42E6F9EFFA7CEF3DAFDE
+:10E520001DD4E4B74B3AEBCC6F3FC7F3DB03F4F5F4
+:10E53000E8721694DF2EE946D2DD50CC6F8FC47A94
+:10E54000C67C6C37E2FD6394DF3EEA985FE4B77FF8
+:10E55000A8CD6F77FDF3BAF2DB4F8AFBDE4E5AF897
+:10E560007D49F23EA965BBF9F9EF3285DF27B5ECAD
+:10E57000397E9F94B40B1789F5551DDCB606CFF98B
+:10E58000163D3E97EEA362E21E5407FC04DB85F2C3
+:10E590005E527D1E4C0DDA83A437B790DEA5CF877F
+:10E5A000A979BC8CECC11A9D1E5D9D29EC4121CF3F
+:10E5B00098D0FF168A6F711D56B2CF4CA4772E7B70
+:10E5C00062B9D38E7541576CC70E3A7793EDD9E394
+:10E5D00031840B92CE16AF53487F95F0CBDD6E762B
+:10E5E000D13DC6DB7B93DE0AFAB6C863F6727B1BAD
+:10E5F0007005E3E177467524A19EBC734FBA1338CA
+:10E600002C7BA5DBFBA777E8EE9F7E4A73FFF439EE
+:10E61000FC0FF5B453062FF63398A5FF12EF252E05
+:10E620003A65747A1D81FB98AF74EFB084BF59ECE2
+:10E63000D7B5DE43ACBFEF59E63FE8EF235E2BEEE4
+:10E64000231ED1CD7DC466B55925FDE16BA3E65EE1
+:10E65000E21BC53A8B1DCC8BF7FC0E6D356AF6BFFD
+:10E66000D8BF81A13E147ED8A8F123981DDA7A8301
+:10E67000C40771BF4857785B3BE1692678A6D03D57
+:10E68000CF45BA7B9E259C3AEF79EE6F25BC1F7A69
+:10E69000F00515F9C1B5DEF7FD43DFEF7DA5FBBC45
+:10E6A000F5F774EBEFE5EEEE9E6FB9EF792DCB3415
+:10E6B000EDF5FB5E70E0A7DA7BA8C57E7BE0E7BBEB
+:10E6C000DCEFB64CE1DF15FBFD355E800674F89794
+:10E6D000C8530F22594E88E07CADD3AE1F1E46763C
+:10E6E000D6BB8E98321BD2BF9053E5424E8115C7E0
+:10E6F000EB025F9C3E1E47907F94DF5F51E8E7F19D
+:10E7000004834F85CE0FBABD58D19CEF76BDB79824
+:10E71000E7190FBBC8E3F4F4E7FE326FA8C215AEE9
+:10E72000BDBFA19B3C22E9C7013D9E99508F37F0A8
+:10E73000FBEC42DC73BC494D0ECE2372937F67B273
+:10E74000C59780F86C4B74C7671505F28D46615EFE
+:10E750009142F6A0104A513FC238CF764CB2ED8BB1
+:10E76000F9A3913FC23C1998BEDD3F989BBBF86F5F
+:10E7700060963B310BE4C971C5BEA600BEFDCBD08F
+:10E780003309289FCC78AE9D4FE7BEC9F85E7F3F26
+:10E79000BFDFE020FDC2F35385EC8733D8D990204A
+:10E7A0007A5D1726F21A757FBF40D853F2EF171C17
+:10E7B000872E1601DF9ED1C4F3A897C6B70A3B8CFB
+:10E7C000DFDF3AB7BF95EE7F62AE0227B7C3A57D04
+:10E7D000D54FBD16B979A5F8A2A5F1A735762EDBE0
+:10E7E000117355E7898175F3FE8F3F1041F2E6F80A
+:10E7F0000303C8CF17E8BF8DECFE19B5DA38E3592B
+:10E800002B3FD2E0DF6CCF679AF7FED88EB07EB098
+:10E810007EFF8B7DC64E03F89DDD6D1E8C7406FB5E
+:10E8200036352BC80EF63F94369AEB01575AE71946
+:10E830009AC73111272AD7F949DD51AAFBEBFCBA57
+:10E84000781E8FC62E95A5E90D46F7E474283D9CE9
+:10E85000A1FC2C9F6671BDFD98C8833C26F2208FD9
+:10E8600089BCC563224FF198C85394F9A3C714E635
+:10E87000C2788AE94AF993B315CA1FBD07F1AF669A
+:10E8800049470EE6DBD5E4FA672A2AE58FAEC4F5E0
+:10E8900087C81FCDC1BCF75D5977FE08F5F8533D19
+:10E8A0003C742FC9EF774CE67513A78F57B246110A
+:10E8B0003D78FBBAEFC37EBE50D416C2E797153A37
+:10E8C0004F652EBF69E265F24B1FC8E2E70BEB759F
+:10E8D000E5D62CCECF5E11E518F5C154CAFBD9643C
+:10E8E000A6BC1F18C765083AFFD7E767E5BF6E6E7D
+:10E8F00041BE21FD304F6425F273CF64EE5F89FD88
+:10E90000A599E76DF97D0998E785F13E786F063B9B
+:10E91000CC5C3C0F8CDFDF27F7E109B10F74917EEF
+:10E9200061204FACEAE0F14F908F8CCD726FC6F54D
+:10E93000CBFCA5AAC8BD1437F1429683BE83F9D299
+:10E94000FA811FAC5608CE5DFC70CFE0FEE8F3DF25
+:10E95000BB5BFFD9F9BEDF642506F2A782F2A65E93
+:10E96000C079C875CB7904FAB93C5E4B7F52C0DFE1
+:10E97000B53615E944DE4F9BAF2AB32686F8FE0371
+:10E98000B16F5549E57B711D4B6AB9BFADD31E57B9
+:10E9900036FCF863DCAF8356E273DD7DAF5F67D58D
+:10E9A0006B07091EB0CE99B8BEA075BE9B15E417C3
+:10E9B0003CBBE7C3DF20A8AF777DD79AC76CEEC119
+:10E9C000EF43ECEA8F860D0DD2A3CCF2FBFEDA7B8F
+:10E9D000C6CCF8F71060BC46617F340AFBA3294C13
+:10E9E000FCBD1A9D3DDAE8E3F13C8DF1268AD76142
+:10E9F000E2EF2B48F9BBE23D1EDFB32291D17B9CB5
+:10EA00001FD281E2DF4FF2A0F3BE2805E41CE0C371
+:10EA100019BBFB02C28FB997937C506FB03A119F1C
+:10EA200077BD7DB3B0ABB8BC2912F2A508FBC175A8
+:10EA300064F524B95328C61D6CA925BD7608F308D2
+:10EA40003F8BF0473CB05F638FFD5F0DF62D3910B3
+:10EA500068000000000000001F8B0800000000009C
+:10EA6000000BFB51CFC0F0038AD7983330385A31AE
+:10EA700030E45933305C07E2307384DC4B71049B23
+:10EA80009AF8A73C65FA374832306C02E22D40BC58
+:10EA90004D9274FDB7B410ECBDAA0C0CB781FC6E9E
+:10EAA00020FD5D9D816117907D07882F83F840CC04
+:10EAB000ACC6C0200EE4AB00693F20D607E2BB40E5
+:10EAC0007E9A1A6EF3EF69E1B77F9B062AFF1D1A43
+:10EAD000FF923A7EFD999AF8E5DF1190C7861FDB19
+:10EAE000911F1FEAF6B44927B4C207D0D2F54E13DE
+:10EAF00006860BA60C0C22D0B4BF17495E0D28B6B3
+:10EB0000CB04C29EAB074C7B66403E8E7C310F2807
+:10EB1000BF11286F648EDF7E056654BE002FA69A53
+:10EB20006F4C08F6042154B9C3C298EAB9441918C5
+:10EB30000065838486D80300000000000000000008
+:10EB40001F8B080000000000000BE57D0D7854D5F8
+:10EB5000B5F63E73CE9C99644E269310C240024E89
+:10EB60007ED0A8098E1030261372263F242401C3BC
+:10EB70004F695A699DA045DA8222DA5E6F2F5F19CC
+:10EB80007E1A2245C516ADDADEDE812A4FDBEB7335
+:10EB90009F60A9E586442610100D3F11ADDE7EB6BC
+:10EBA000DF8DDA8BA10D38C160E9F760F9F65A7B89
+:10EBB000EFCC9C939904D4EFDEEF071F9F9373CEA5
+:10EBC0003E7BAFBDF65A6BBF6BEDB5F758C944E25B
+:10EBD000AA20E40AFCA357DF6442E8A391AB785E65
+:10EBE000692741C72D84A4D9F7F6CEC820649E2694
+:10EBF0007B6B3D844CB2B7F4906242CA89CD63CB43
+:10EC000021A45BFA4DEF0C7A7F34C5EAB511F8F711
+:10EC1000002173085967A77FD2F2472FD22BFDFE40
+:10EC2000E85F2D2122115223371209BEB74BBCBC1D
+:10EC3000AE2DC824A49AB07F732F926A5A8C54BB0D
+:10EC4000EF6D243308A972D15276F6EE0A2B4F08E5
+:10EC50002D5F4658FDBADDF8BE8C6C1F929D701773
+:10EC6000919B8A687D9755E37B77ED07C409E56240
+:10EC70009E433FE00FCA83EB494AC61907FDFB36A6
+:10EC800072DB15995E950984DC1EE58BF94A481004
+:10EC9000F9D6C1BF5748D30CB827E4456C3F5DF0A7
+:10ECA000B1AE9FB869BF334A88B7967670529DDE81
+:10ECB0000D7C29AB563D367ADF5D336772BF46C89F
+:10ECC0000FCFB5679142FA796835F23183F3B1FB22
+:10ECD000DC4BEFDC47BFF7D511AF8DDE1FB07A27D5
+:10ECE00037158EA6C757979E44683D4F341D7260F6
+:10ECF0003D84FCED4A26AF278F90CEA6DCD4409C05
+:10ED0000EFC4F5F10D2E426CD1FB1D3AA96BD7462D
+:10ED1000977B0906733654BF1CE92CE3BCFCA14465
+:10ED20009ADBB1DD661CA7039CFE1EFD90A3BF10FD
+:10ED3000DE871D16DA8FE090853C4FABE81CAC4CAB
+:10ED4000067A37E996303CEF1C5443C00FE26ECF91
+:10ED50005A54349AFE03432B6662BF02AB0DEDFE9C
+:10ED60006090F65783FEBDE89847EBB9306871C9EB
+:10ED7000745C9FE0CF0F04DA1D2EF86E201DC7F3E0
+:10ED8000F10DF4EF1B12F3E3F1B9DFC80D6850CEBB
+:10ED90006EE4C7E085637974DC3A772A5EE8D77859
+:10EDA000FCFC016F47DCA77BC3552E5AAF2FE295C1
+:10EDB000408FD207099990037AD179D809E3DB48CB
+:10EDC000502F7C4D9549D3593FBCB207DE1F974168
+:10EDD0003E7CAE30F663841EA0EF06A0D38DD7A78D
+:10EDE000797B4FC13862FF36255D4FE9BD50A26087
+:10EDF0003DBBF54D7E05EBBB1C96411E573379CAD2
+:10EE0000F004365A81FFF7106FD003F512ECF74F7C
+:10EE100079FF7FC2EB13ED740EA6FB15A0AF9978B6
+:10EE2000414D6AE4F5DDF0BD6F15A37FDAC36B25B4
+:10EE3000E0DF75EBFBF11AE274EE80EF6981ECB56F
+:10EE40001109F836F5A1305E776EFC7D37D097BAA0
+:10EE50008524812D78A2DA9206DF3D316F4A12BCFB
+:10EE6000773651C5A7F6C0E7753DD043FBB3B35A1B
+:10EE7000413A770E52FED372CEA0CB0B7AED0C7ACC
+:10EE8000F8D5EB85F207393F0EF076BB381DCEA0E2
+:10EE9000CECBAD2D8472CE6010AF21DE4FE2598310
+:10EEA00072B78ECBDD416BE026E07BC6207113AAE2
+:10EEB000CF07CED74F867645FDE6F27B9EFD9FB30A
+:10EEC000E0FDC441F2AE75065CC32DD0DE0DD00F5F
+:10EED00027DCF7B54868A742A847FA650B2105511A
+:10EEE0003B9571A969FE1D1EB8AB413D1276A06C21
+:10EEF00050B548A9B17A568D7AB093EB41F56018B8
+:10EF0000E584EAD9610BE553F01CD5332A5F079AF3
+:10EF10002C38DECF4554B4C3A4209CB52865B41E5C
+:10EF2000750EAD9C09FC16FA34DA7EFCBFA15F3B7E
+:10EF3000693F0271EC9A684FE89BF9FDB8FAE60A5E
+:10EF4000A2BE75527D0B023F9B2C49F9A07F6D1626
+:10EF5000D41377757B37D397D5A86F19F7307A26F6
+:10EF60002D0FA11E8CA7773B3D2EBF02F537333DF9
+:10EF7000ED1C7C6FA30DC66339E176E27237DCFBD2
+:10EF80001E667A6DD633B31EA6FAFA503F73B644A6
+:10EF9000085C3D9B1B51AE692B49A87F09F4B01357
+:10EFA000F4B0F8FF1F3DAC82799CEA5D9A766B8FD6
+:10EFB0008BF67B7E84303CA43DD103F3784DB68D37
+:10EFC000CDE353DFBEF37E7A7FCCEA40FE1F9B4841
+:10EFD0001F16C3BD8C7AD79DB3357B1D7D3F3F4344
+:10EFE000C2F784AC42FDAE1578091E51FDF1F74B16
+:10EFF000644E3A947B7F4715FDFED501E28557AFFD
+:10F0000066CB58DFE141C2F498EB672DEFEF61FE6C
+:10F01000FEC2251202FDAC0048429F7F7C3632CDF5
+:10F020004E5F7D68B95C4472E97C2CF8C571460D71
+:10F03000D7FF5733641DECC6E1F529219283F5858E
+:10F0400041DE5E7DD81692697B17F2F35E0813C02D
+:10F050007F91EBD7D1F73DAE8F5262F57380CBEF46
+:10F060009FB8FC0E723CB1E3E6A64512E5EFABF9A2
+:10F0700079A85F17F23F9A4628ABEFCFFBCB19B8C0
+:10F080001212B6025E32D723BE7FD51DF8B244718C
+:10F09000D540E87D278CE7B97D1FCD802B714F408F
+:10F0A000DC351E3EF3091C16E9DB0C388454533959
+:10F0B000991395934991BEC3C037DF30C363A46EE3
+:10F0C0000D8E4BB98BF1A5FBE25B59F05D07E75B59
+:10F0D000D7505F16DAC73A633D5DD6FEE54DAC7E8C
+:10F0E000FCDEE762E32AE87999F7EB6949220C270D
+:10F0F000B2F1F3F1EFE72A7D136EA174CC3D267BCC
+:10F1000037D2477307FAAB491C3BB45B4A4379AD2E
+:10F11000B86494D7AE8B4765E00BA557067ACB232E
+:10F120007D32B3E34CCE7C5CCECA23A70DF65DB432
+:10F13000DF1539DD00ED5F1860F62A115F85FC1CD4
+:10F14000E2E3FCB2D0571272DC42E5E508A57FDBB2
+:10F1500018DFD7B86403DD42FFAAEC0E035EAFB838
+:10F16000946EC2FF467A4B9530F2AB14F8E549CC69
+:10F17000AFF5523AD65F36F0E9F865B62BA2DE2E2F
+:10F18000E063E168BA0808B5A05BFE3F9FAF9DF061
+:10F1900007F35F8E829E92FEBD72530ACC271ADA65
+:10F1A00093B26A89E172DECF46F896365527F4CAE3
+:10F1B00023A19F57EF9342B58037BC3F433FF142B5
+:10F1C000B1CD03766892E709A53F46DEEAF9F72359
+:10F1D0007CDCA0633FBB67BF9D05E5BAA66FCC860C
+:10F1E0007198EF79DBB18EF2FF28D79B8E0D7558A1
+:10F1F000AEEC1279F45618977CA66773795F7A386B
+:10F20000DF0E71BB7190CF9B6F6D08E0F5CD0DAB3C
+:10F21000F07A7AC35ABCBE7AE9450DC6AFB7200F63
+:10F22000E7AF3AA55D89E757950E1AE5E6650FC584
+:10F230003BB47CC3E08AEDB7D27E1FBF6441FB7C48
+:10F24000BC206F4CBC22EC8728F78AFB6755C0B7FF
+:10F25000C6014A6ECEE8F266792D23523BE0BF32FA
+:10F26000EFEB0AA1F67241F12E2D16C71C38975903
+:10F2700004F51E90FEB0649627311D65BE3EECE796
+:10F2800082F0EF144F4AE2722794BEC659E8A732C3
+:10F29000FD2AF3BE5BADD3F66A0B7735A25C0C2B6F
+:10F2A00016908BC6C2BD7C7C5D381E0BC47C562C70
+:10F2B000D785809EC10B48676FA13C11E8DB669142
+:10F2C000512E17786C886713B63FAC9030E89712D0
+:10F2D000C6713A4EEB01B93841ED1E7BDEC7EE69CF
+:10F2E000BDF0BE3BC7A679819F6E118F5865908F88
+:10F2F000C6FC59C7BD94EE5EB78CF8B2F752A59222
+:10F3000046EF4FC0FCEA89CA671997CF1330EE2049
+:10F31000C72119E73F8197457D5D97721F2DA6EDA7
+:10F320009D0859E37EDF546DD4C73BDC0EC37D7569
+:10F33000F604C3FD89C1996F36417B947EC0732466
+:10F34000B8DA407F17D87B68CF25E1FC7FF472F5EF
+:10F35000E0FD502E64A4CB4C47EFA5DC2797D27A72
+:10F360008FEF93514EABDD46BAAA2EBE791CE23820
+:10F370000DD4BE00DF5ED6151DFA7D625F4A68239C
+:10F3800095CB970B5F77006EA0FFB405B49D2AC2A2
+:10F39000C6B732C358CFF1C1F7BE0F76EA825D46D9
+:10F3A0003B57F9D7435B005E9D2A7EB007F87C800F
+:10F3B00048C8A7F273BB65A86F59C8F8FDD2E546E7
+:10F3C000FEAC593AC164FF8DF1A52A0F8B13CDF520
+:10F3D0000E617DA510FFA1F7959A312E34178C414F
+:10F3E0004CBDE5A6B850A987C5854A212E24CAE59B
+:10F3F0009051769FDE63FBE679DDACDF09F5DF42F5
+:10F4000056413C8544168F835B36F1F88AD1DE1273
+:10F4100065A704F250CADBEFB0B63B802EDFADCC5F
+:10F420007E91487ADC7895D98E10F220CA95E02337
+:10F43000710549C61CE83F2F63B67F9C2F6D743859
+:10F44000AEE03C10E4F8C51357DFCDDF67737D9F56
+:10F450003740ED66068C97EC02BB71FC12D1401F61
+:10F460004F5179672DF75F8995DB868176944B5AEA
+:10F470001E469096F7A2FE364D66FADB9D53ABA46E
+:10F4800031FB1957DFCD7A3040824F15D3713D9E45
+:10F490009FF7E452FA5DEF3E61072C3AEAD53E86CB
+:10F4A0007B4F0CAE4379BD40E515D83E5AEF4F6B0C
+:10F4B000B1F3FE7F96BE9BF57C44FF47E93BB35B0F
+:10F4C000C7872DD89FAA8B0AD6D37099E03C6ED6F9
+:10F4D000FF13DC7F7B597F53F3C27C58F83EFAC799
+:10F4E000E453EB3BF3430E0C106CBFFCDC7B32EDC2
+:10F4F000F9E7A6EF42CF85DE5EB3BEFF27E9B9F993
+:10F50000F9B72D1CF727D0D3A8FE07B1DCE61452BB
+:10F510000071B60E29D9BB2907F49DC57DCCE5271E
+:10F52000C8221E6B0FFE91F6AB850A4B2A65F51AB1
+:10F53000D23F0DE461E2640FD6779FA53F13EE3F03
+:10F540002491CC9B65C0CF643FCCBF924EC8C3947E
+:10F5500024C9E322CB6712F2B81CB0CBB43E6920B9
+:10F56000FC5789F2993C443C80076F90020E786EFC
+:10F57000A37CD26879A29C469C48FD37E4D742AE72
+:10F58000740BED5A18E3F025D6C17EC1779C3F96E7
+:10F59000BBCEDC4CEB2561E9CACDD17EEEB186B2A3
+:10F5A000BC1AF433F4E3FB206EF58CEA7D3E0EDFEB
+:10F5B0002D9FB29F607E909F16C6CFA025D9FB7C61
+:10F5C0001CBC35FFDAEB7F2B995ECB808FB78CE6C6
+:10F5D000A33448F9077C50FE7605FCC43237932FDC
+:10F5E000F9435587380D91EDA1E971E858C3E978E1
+:10F5F0005CD66FA3C886C855EDC89F0330FE1AF0CD
+:10F600002F837C3B46BEE6C92AD2253790B538BF4A
+:10F6100090B005ECC878E361558822C338F65D41A7
+:10F62000BBDBCAE9B3D1E7DACCC4E3253778236181
+:10F630003A4EE443364E07E61BE5723DA7FF414EC6
+:10F64000179827A8BF14EAA7FC92FFACAE8D374FDE
+:10F650006C17FCE7FC32973FF025D67F517EABCC90
+:10F66000F42978EDE3B66C525EE27113F22E0D1EB2
+:10F670004D347E6B4371F47B8E6CE1FD0D4A57A3D4
+:10F680000FF3B85CCA5574DCA07F35463E6EE6FDCC
+:10F690005ACEEBBD4BD2FF1EE4E106A9E91FE04ABA
+:10F6A000AAFB50FF40C6A1DCCD44FF6FFCFD06D095
+:10F6B0005352677C4F9F6FC2EF9AFB707D4A3C3F6D
+:10F6C0002CE95B64F6BE15BFD38DEFA91CB6C173E0
+:10F6D0002A2F449E09CF193FA99C103BBD6FDD75B1
+:10F6E000F79781AFF4FBC7B07E72DAF0BD150C441A
+:10F6F0003ABB4A33D9F559903BEE9F6E6ED691AF27
+:10F700002A59CBFD67369FCDE5F399FDAF6C1EBC42
+:10F71000E05231AEA524E9A130BDA6BBC23AC40374
+:10F720002790BE20F863CB96CA063BDF6C9A5FBE7B
+:10F730007C8F71FE5DBE3ACB70FFD587F20CF781EE
+:10F74000F5371BEA5BB16596E1FE9EED6586FB959C
+:10F750003BAB0CDFAFFA4983E1FD379E5B62B85FDC
+:10F76000FDC29D71D737C57CF788E5DDD54DB45F07
+:10F770009BE1550C5E54A2EB971686C78CDF51F1C6
+:10F78000F32873A01CC15084594E15D3FA67FF8823
+:10F79000FEAC33CCB7878239190015F41C4543FC05
+:10F7A0001FD4FBF233A378A0CAB3B231DEFC2BE83E
+:10F7B0005178393FE9AF8271D315633985AFD76A84
+:10F7C000DE08C661CCEBB58A671ECEEF667ADF91A4
+:10F7D0005332C02ED1BA3DB84EAB5DDD7C3A6EFFE0
+:10F7E000A825BCAAFEF1F6FCD0CFBCC4FD9A5B1CD8
+:10F7F0009181BCABED57944E23EE11EBE40B5851C5
+:10F80000529AF31CFA630B803E989F8B19DEB1D39A
+:10F81000FFD83CCBF8DFC0CB373DE4B2023E6EAA46
+:10F8200036D2D9C07114D54305EC446981E93DD085
+:10F830003903CA19F1520F97474DE1EBE573C81C24
+:10F840001C07AEB78B84DED6B0380771C55F47AFF3
+:10F85000BF440BCDC2F651FEC4F3D70AF292E1BB0E
+:10F86000056DC463A3F8E491D91B5D9580F375AB76
+:10F87000B78E96AEF2F278932E239EBDAE80DD3722
+:10F8800056B3F8537DA00FE3808DF78436C275CA56
+:10F89000AAB0827498F8FAAC279486D880F3378B94
+:10F8A000F32B4BF095F351D8F129AB8DE3D8586C7D
+:10F8B000E4D742CE4F339F17723E2E34F1B10BFE88
+:10F8C000A07C999D808F0B381EB5CFE6FEDD707A47
+:10F8D0005CBFF1591E1F13F2A398E635613F46E65F
+:10F8E000372EBF8F831D079CE7E23885CF7B89F4D5
+:10F8F000C89FDFB2C30FF1D60CAB61FD621EEF6B88
+:10F90000693E5BEF28CD9011F797BADF30C4994B71
+:10F9100047E2A3BA5633272A9F5D03CCFF68759F41
+:10F9200096619C1AF219CEDFC2F923E27F07F8BA7A
+:10F930009199AEA3D382D9808F8E5D0C66AF2B8652
+:10F94000F88F8472D279EB03D92C5F80C773797BEF
+:10F95000AF0C05D17F3B3630F6FAA2C0F966B92963
+:10F96000F586709DB174A05D86FED645E81C44BB4B
+:10F970003E2FFC0BD95384716905E86974AF503090
+:10F980005EE66E5120BE5CE7DE5505FCF091D06668
+:10F9900027C4D53C92370C7C2C64FABB8AFE17AB8B
+:10F9A000BF82DEDAC18002FA5EEB31FA353E2E6F9D
+:10F9B000356ED3F3FC5A94379F49DE3609399B4E96
+:10F9C000A6C7CA99885BAB43B95C5FE3CB5927E70D
+:10F9D000C7BFF338EB1F787CFA1DBEAEF7BB0D1E18
+:10F9E000BCBEB2A1009F1FD9E0C5FBB73794E0FDB4
+:10F9F0006F21CE4BEFDFE071DCD73734E1FDA90D8D
+:10FA0000CD78DFCBE3B4428EB7F2F5941AB913E3A5
+:10FA10008B0DDE80DD15234F0D9C6E147DC021857E
+:10FA2000F1E3AFB669FB1590AFD3237A42D05E2CD9
+:10FA30006ECCD9BD8DF2C5F65D12005C693BF4AFAA
+:10FA4000CAF554FE1BEA72AC2BA1BD60BB320BE4BD
+:10FA500031FCAF4A1E3C6FBCD57A779CF6453B899A
+:10FA6000DA37DBB72575463FB854C4D1070241E801
+:10FA7000E7A4814018E82B75AB9E7871E1EEC92BA5
+:10FA8000DD204FAD67036E90A7D6C97B64E6AFB3A8
+:10FA900078B8CAE554942F75EF36E8A1CAE9EEA00C
+:10FAA000CF81DE8E71F4E000E79B28E753C2B24BB2
+:10FAB0004BDC3F9F295EBE458AEFB7265B19AE75CA
+:10FAC000F2F5556A3315D0331051A07F12151BD0B3
+:10FAD0002F4D63710B8737C0EDB2711E4F2B696AD2
+:10FAE00002BBA465106F2D9837ADDF0D722397CC44
+:10FAF0003B0BF32C298CB1DBE0F798FDFFD87B1989
+:10FB0000A7AE604A3A5CCDE5187F352E426DB7321C
+:10FB1000FA1EE3710EC15F8DF3B7D473ECDFC0AE94
+:10FB20003EE665F198C732D8BAEC85921588CB4A83
+:10FB3000B95F60233BB07C3269C7EB66AE67174A9A
+:10FB40004E13D07B59A1B83903E8B18782F47BA763
+:10FB5000C9BE2B9A91DF12E5C972C0D7038AC1DFF3
+:10FB6000904A989DB783BF0E7E0CC72F513F2F4000
+:10FB7000AE00F3AF124F6DB11AFD31711D502C283C
+:10FB80000F2EAB299FEEFF7AFE1DFD5CF927FCC40A
+:10FB9000119C77F8EB04D663443EA128FF8A29DE46
+:10FBA000A466B3751873BD775819DF2BAC1C1F0BF7
+:10FBB0003CE133B79314047EAAD49F4A9246D7936C
+:10FBC000A83D3230739CB8F5466CFF94E262FE04A7
+:10FBD000CF07A26EB964F04FECBA3B76BD7FE47BF1
+:10FBE000B7C5A0A7A3E966FCF9BCE95D401D52B802
+:10FBF0002E1476B884E1C9451E8A27E99F8B3426E6
+:10FC0000A727FD526813CAA96EF0B7EA4A6ACFA2C5
+:10FC10005DA2FE883A87E3744A7F1BD44BEB797D63
+:10FC2000B2F86EC49E58AEDC32BA9EA66A867B4895
+:10FC3000F097F363E3074D545C0A6642BDEC7B5AD0
+:10FC4000B4FB4A3C3AB8DD6A2A7960A1E6847B5D60
+:10FC50007A1AF05E610C3E00BEE6DB8C7C36D9BFC2
+:10FC6000EA5176CF686FE751F9DD4FDBA993D736BC
+:10FC700042C8BBF68915FB5E4572841FE2895BEFC3
+:10FC800071F8E376407F46BC42BC2C8FA32AE8691A
+:10FC900044BE6748249403F41BE998976DF2C3327D
+:10FCA000CCFDD881E37848A1F3081DAF43741C77DD
+:10FCB000A07F1CDF9F127E5E45CE30FA53C2DF2349
+:10FCC000DCDF73D1FF62F158392FEF7FC8A300FE4C
+:10FCD000F5DB4D71E691FC6382FE540531D25BCEBB
+:10FCE000FDBE7293DF27F4FD25612F855FCBEDE12B
+:10FCF0001DC29F2A1F7B7DB9C7944F574D096FBF07
+:10FD0000063D204015AC3791113E19E4AB3BE7FAB4
+:10FD1000F630E5EB1DDE24B6DE42E954843D473E75
+:10FD2000319CBD9097BFC3A3A2FCFB34B67ED138F3
+:10FD30004EDCC257C2D60D4ED925361F04C99B24AE
+:10FD4000263FBCCAC3ECB566928B6C4F5335AC03EF
+:10FD5000698AE40D91D1F25ACDFD39F87E3D6545B1
+:10FD6000753EF5C967C6CB2FEF83D02A29A7343C4F
+:10FD70009B93787C756FA40A86E76AC7979870F69C
+:10FD8000A9C87B98D775A150C2759FEE9C8FD13FB3
+:10FD900010EB3B51FE1DC57C145FC947E8AF8CE4F6
+:10FDA0006DF1FA168AFA4A0EE37ACDF75C87314F85
+:10FDB000E424ACE3D2EF4F2A110DFC90F9025F511D
+:10FDC0008E86053F73204F82D517E67ED529FB1B13
+:10FDD0000EB09B22EFA4CB27D7C58B7356C82CCE71
+:10FDE0002CAE37A96CDE99A3323C27EEC5F88EC83D
+:10FDF000937CBC98F9E1DF318CBBB97E28DF8CF1B4
+:10FE0000C170E158FE68A389CFD3543EEF71BCD1D5
+:10FE100019191BD78A7E9AF960EEA7F93BA7CAE2A7
+:10FE200065F758F59BD5D9D176C47C672EBFC81E1F
+:10FE30003F2FC75F628C4F9AF372EEB1064A55CAE4
+:10FE4000CF2A45DA92EA41BB86FA74E8B28638E6F0
+:10FE500042E4D01618D623C32C3E5A4EE4908DCDE2
+:10FE60000B8DB06E27F446C8BF998EF1DA2F1FEEC6
+:10FE7000477FDC7F29520DF27787AF1BEDEA026ADC
+:10FE80005727C4B1ABF3E4C12D13407FBD6C7FC7CE
+:10FE9000A9DFF755E3BD26613EAC5E9EA74C003955
+:10FEA00070C58F57CDE572327A3D4FD8559702B85D
+:10FEB000C11C6F9BCBF56EAE491E02EA080EBAED6F
+:10FEC0004ADEF8E394481E2E442E3C182F8E2AAEAC
+:10FED0005509C6F73E62E26FA731FE6CAE47C48398
+:10FEE00088DC990DFA2CFC5F73B93695AD7B1C2923
+:10FEF000BA97C4E655097BA096B46B1017EF2D197D
+:10FF00007BBE30E70FFA89314FACCA6E5C8F7D4AF9
+:10FF1000D11F01798CE2A416E6AF96B4A0BFBAB0A7
+:10FF200090EF0B2ABA17FD53E157B7DEBE17F3B9AE
+:10FF300044BE96F04FCD74F74E7E11F379C6A35BA5
+:10FF4000F8F1C76D325B87A07EBB07FD768AFBE2C6
+:10FF50007CF78A8DF1EB578ABE0BF4758B5577B71A
+:10FF6000C03A6391CDFB7C9C7118B031FDEE4DB071
+:10FF7000DEFA0758F8988DFD403E98E71BE1C78AE6
+:10FF80007D4A93DC4C6F1BB81F5B56D882FA98E60B
+:10FF9000A67E2BF0CDCBFC563268F453176A7D5900
+:10FFA00030FEE6F94E1EE67EED55FAAD5B93981CE9
+:10FFB000055CC4EEA6EF93140A4DE9FCF7A45C7946
+:10FFC00018F8B1358DA03F70324D0DED8E136F785E
+:10FFD0009BCB5B8DBCDA206FE51C97A8D5FD1AC4BE
+:10FFE000034E0EB3385EA271DB66C2E9B905C46F79
+:10FFF00073C235E2077ED07BDD86D708E6677FBF18
+:020000021000EC
+:1000000068656EBCFA76B72971E7A53FF3715B2C82
+:10001000F2B5EB583CF2BE4215E3C293EADE3D8AEC
+:1000200072DAC8E574810DFBDD5BA4E0B8F4DE9EF6
+:10003000D30EEB9ABD4576CC47E92EFACDEF215F82
+:10004000BBBC4432E49708F92D075C0DF5DB59BCC5
+:10005000F33E37B3C3BD1AC72F3C6F640D1FD39354
+:10006000FBDE77C6E68D2C1172DFC8E3E426FC4484
+:10007000CD48DC751C91477CBE91C585EF13FDDD35
+:10008000BF770BE85D03979BEE8B2BDDA89FFB5999
+:100090007E5E6B510BC68BBA27BFA5C2FD1AF7193E
+:1000A00015EECDB8428CEB7D25BF62F9917C5CD713
+:1000B000403C9ECAFBCB99375B3DF47E71F8762BB2
+:1000C000C43B457C76D43A145F4FA965DD27B56EF5
+:1000D00086AF8F663A487206F04B0E49C0B7701271
+:1000E0004986FC33B7359444EF1B94FE69805B1C52
+:1000F00026BC78FED77BB341BF8FCCF8408176AF6A
+:100100002B79B715FA31A5642FC6FBB3F6EFED498D
+:10011000A7F52C2C205EDD339A9E1A3E3FDD97C159
+:10012000F285EEF38682B0EFECDC65B69FA2F2D7E3
+:100130006F54C1B4367A5D46278043C4BA8EE2E676
+:10014000EB227C7D825CBE22C58E5B8312B083FD78
+:100150006D2D79C309F42EE67CCBDD27B7807C5763
+:10016000FF7AD657404EC8ED36D774DAE039D76FEC
+:100170009DD76BECFDBDACDEB9015ABEA1706FF628
+:10018000CAA2D1F665447F0AFFB22140E93939FF9E
+:1001900037D980DBDEA076D703ED72BB65F697CC4E
+:1001A000F3AA392FC6DCEF4C65519D6D368CF78F65
+:1001B000DD39317246EDC00AA07FCDD376CCE34A5B
+:1001C000DBFFBA2A837DA3F8BD568ACAD11A2E470F
+:1001D0000D1AB37FAD4524B44902F93BD358067AD2
+:1001E000F72ACB379CB4FF5D963F6A9A1F7AF9BC19
+:1001F00021E6E3DEC9EFA1FE9CDFC7F52568916229
+:10020000E3495A4964298C8BE04FA7C9DEF8ECF129
+:10021000E326EFD8185E2DD7D87B8DDA6F58D73606
+:10022000BFAFE4FE54155C63E685076D0CF78AEBFF
+:1002300035E4213CF55DAAFFDDDB0FB9EF463BA5B8
+:10024000216E5FB37F6F01ACD964EEDB5BCDED0552
+:10025000FA6532EFE724E2413BB550B3B3F50393BF
+:100260009C5B4B7685013E8B791A1C7225336A475D
+:10027000E4D838441C3F8C04F537F363F2BEE8FC45
+:100280004EC0AE54B959FCD52C276925D4EEE020D8
+:1002900050EEC5ACFB9AE5B6410BB8613D9BEACF89
+:1002A00059B6FE49E72B884FC88D5E1C4F2E9F160E
+:1002B000FA1FCC7F0EAF513EAD05AA01AF98E9F809
+:1002C000A9CD88FFC5FC9CE6EE47FA166AEDD9D0A9
+:1002D000FE24773FFA5BD4BE67C355C899B0D723D5
+:1002E000F257745B3DD877906B58223F59322B19E7
+:1002F000EC60839BE114628AA7F7BAC7F6377A4CA1
+:10030000F278D2C5FCAB861292EC4A057D6771A7E4
+:10031000DE47D3773962E272FF640D74D862E2EB94
+:10032000CEC22FD6BB9C606758FE5629355FD6BC1F
+:10033000683C53C44DC57A9F88938E8A671676634E
+:100340007E9755E45DF0F5BF51793F09D61DC5553F
+:10035000C4336D9BDA152F5F2F413CD6C8E370C3C1
+:1003600033C78987B2F803C567BFB54D1C1F9FED22
+:10037000E17EE600180F7A5D6573E155837C144ACF
+:100380006A6F527CDC7690FB6DD7A29FC764F88EB3
+:10039000B5F327937C89E7513CCCF46052C9DE9ECB
+:1003A000583C5CDE467943C7496D23D3486A62B93D
+:1003B0005B3862F77E6590AF117C3C0E2E16F275AD
+:1003C00051D6FF669B98B85C03A723D1FBD6225B6E
+:1003D00033E45BD17264522ABBDE40AF3D33F66634
+:1003E0005BE8F3D7007FC5D0D1FBCC7EECC71F54B0
+:1003F000B6CFA6F7E2CA5CC007A7143DD53EF1EA26
+:10040000E5C7AC4FF6D9BA6723D5BFAE6C3BCECFAC
+:100410005D6E86435E879231F2B44E0D5C679F8DB0
+:10042000104427E9DCC8093907A3597D75FBC4EEE0
+:1004300072F43FD414333F6C875793619D8FC9CDBD
+:10044000236A3FE6E3DC456BB7D1760E6B72E60AB2
+:100450007A3FD3CEE4F170D01A37FF79A69DE1E759
+:10046000756AD34CA093B4AF453D6B91E426D07F21
+:10047000E2BDBAF8DCE68EF879A555D1FAE762FD5F
+:10048000FB68FD801BBC3CFE4E5C9971E3EDBCDF5C
+:100490006142EA405F1E4B33FA9B3E3B9BF7E646C8
+:1004A000EBAF8FAD1FF3B366E3F30538CE2FB0E7A4
+:1004B0000576A617FE3C96D726F828EA5D1AAD6F9A
+:1004C00029D6B79F7D976FE7EB069C6E81F3CDF938
+:1004D0004F35496C3CA2FBFA08DACD528AC3F17C55
+:1004E0008548E830DCFB09DF9729319CDE95C2F6B0
+:1004F00031755987F09C85EE4F3E7E07F66B2A8A50
+:1005000011DFDBB8EC2897F7C850AE34FB8223F636
+:10051000DC8172FEBE7BD8B8AEAA73BC7390F07C4F
+:100520000D5E9F3F419C4BE0F80E5E3EBA0ECCF64E
+:10053000294E1A60FB122B5CFC9C88B46FA35F2DC4
+:10054000F47CEB276B199E9FCAF7AF65EF9163E9C7
+:1005500051383DA5CAFBDFDC0BFD8F1017C659C310
+:10056000BF73E4D07EEBC7646F129436F9193E8EE8
+:100570006BCB396E4D84EF8F4A81E7C22CBE69C0C8
+:10058000F94733FF59061C5A1A66EB4C151CD7570E
+:1005900028A12C981F6AB3593CAAE3625F16E2F9BE
+:1005A0008F3371BEB84ED985FD9EA20C619EC43CAE
+:1005B00013FECF1A20E837F8A9DFA0C7C12D357286
+:1005C0007635ECCF2DF5B0FDB5A55E56BE8BB61FCA
+:1005D000A4E52B2FFEA007E0FA687C6FC429E59EF6
+:1005E000A12A342326DC7FCD783A9BC5A52A4C7EF0
+:1005F000829007CA0FDC37DFA13C68073EE4665BE8
+:10060000987F30D5B21CF846ACCC3FD8EAFA961D9C
+:10061000FD03FA1EFC830AEE1F545C8E64817F602A
+:10062000EE8F90AFDCCB1FA37FD03DF431F239FCCD
+:10063000C99E2CB0CB228F5CE07A513E53F11F0152
+:100640003D2E37E17C9BC0F9C36B09E0FC0AC588ED
+:10065000F36D5CCE2A38CEEF80F52E90D7B399C7D4
+:1006600073683F0E0A9C3FEC32E0FC52CE8783A0B9
+:100670008F3138FFE059B6AFB22B3BD780F347FC40
+:10068000C84F89F37D49CCEE081C5FCBF18278FF1F
+:1006900021B7E3667C6F7E7FADF89E70FC1EC5C5FA
+:1006A00046B9EDDE9E8BEB2AA52E3BCA6DF9406064
+:1006B000F801FA2A7378ED1F9F007EBB1D5EF8CC0F
+:1006C000C6C765DCFC4F13DE9F44228753416FF29F
+:1006D00059BE515AB60BF5A482EA496D3C7D30E310
+:1006E000FF6C366E554A8BC88B1B13E757682EC4B8
+:1006F000D98A527B5538DFAC5775F9B631FDD2AC8B
+:1007000024230EF30BBBA93C1044BBA93C1006FDEF
+:10071000F15F66F933DD9F7CDB1D7B9EC3566EFF68
+:10072000853D17FA78F0938F791E8D49AE958F1C11
+:10073000B1FB8A0F66331CF2332582FA7BF0F2CCD0
+:10074000E4D8389519E71FE438BF82E3FC8ACB4C24
+:100750004F0E8EC6F9B725C5E036E7E56588F3AFDD
+:10076000369F40F8AFB526FFF55DBBD17F4D24D74E
+:10077000FFC1E7F3283F8736239E5586D87CCAF908
+:10078000A9703C6B031C790BCEA3B83F5EE8F1283F
+:10079000BE5A3F32CC937E8EEF0E2A578D679B93C5
+:1007A00066272E57310E9EDDFA89DA8CFCE778B683
+:1007B00042E0D9BF45B262F12CD1180E3BF8CC25EE
+:1007C000ECC7C1348663CD382C31EE60F77E4DE244
+:1007D000EB30463C21EAE94821D9189F93DE46BE1A
+:1007E0007559FF12178F08FC61C61DC4843746EA8D
+:1007F000059C027860F88203F6C1761C93F9BEBAB4
+:10080000CF8A4322722CEE10DF75A5E8E8CF0B5C8F
+:10081000B2F593338833B60E113C3941E0128A3772
+:100820000E833FA7D3F93BC913A55FE01381374679
+:10083000FAA1B0BCD12E17B7FF09E2A09F373E1135
+:10084000B8C4CC9F8356865B3A2EBEF599F08A19C0
+:100850009F98E99DB76B474F2A2D373F7F08ED5092
+:1008600087B70FF799770DE766001FC6C72D7E5C27
+:10087000871F895372FC71ADB825115E4984330E10
+:10088000028ED1A238C68C5FCCFCCCCD262D10F7C1
+:1008900017B82691DE42B97B9D51BC93A81CB5DBED
+:1008A000888312D6733972AD38E84CD298388810E4
+:1008B00026372C3F28113ED9EA7569B1F9AA623E64
+:1008C000E9CEBEF00EEE2B1F50F17C84EEB3CC7E51
+:1008D00026C247874C7A7710EC85169DAF12F265D9
+:1008E000809DF3217054A272578B9FC43CE24B62EF
+:1008F000F344A2F5C9AC6486B31EC965FEB2F97DA6
+:1009000034DFC488A3484611CAF3FD7CDF65225C4E
+:100910004548C4C9E254417CBE8CFB9B181B9CC358
+:10092000F30D28A94DF9241FE685263B1BAF93B391
+:1009300025F40316C1732A4FFE6AB63E74BA88D9ED
+:10094000EB937E1BDAEFE3E7593E62770A8BB39EA7
+:10095000BC35C9BB9B92701EEAA5F3F0E9A4BE6248
+:1009600098F767887EA6B37E2E708457E3FAF8ACBA
+:100970009B2DC19CD1FAFD4832A7235DC375B606F5
+:100980008E3F619D306BE6E8FD04CF24E7209F2079
+:100990004F3E8B96DB62E9FB7E2E7D946461EBAA71
+:1009A00066BEFE99D3038CB1C5F0A131DFAE2751ED
+:1009B000F94FBA89AD4F7555DB301F270996D269BB
+:1009C000BDDB0A7253E2C991E897F9F94F9399FF99
+:1009D0007D7A6A04E7B1533CBF778D22050973B075
+:1009E000B09FCA8429BBB6D1A25F4E66E7D59CFAF8
+:1009F000F5EB18273A91C6F9A04B98C770126C21F5
+:100A0000C4FB5C5A08F665D2EFADCBC6C8FBE8F371
+:100A1000D716B0F53242245847833F7247F37B49DB
+:100A20009D8CFD5EE2DAFE00E8E3E9BA371C70FE59
+:100A3000E4C2610B01BD5BE22ABD179E77A7303986
+:100A4000063E036E5A52FDC56FC2F3C646E3781CDC
+:100A500049CE65E7C8286C3C60FCB2668E6E97CEC6
+:100A60007E01353386FFBEDFFC9D1433AF88BC1595
+:100A70007B823CBE44FD9662EDAF1C8D3B4E2AD975
+:100A8000B503F6C73415B3732F1A3C2408EBBC0D1D
+:100A90005E12CEE1F285F9343DF96C5F10D7AFB448
+:100AA000925D6DB910A71C56D8FAB3693E29A363AD
+:100AB000959D0E7173363E2767CBE8D79595305CD0
+:100AC0005FC6717D83DE82EB7A8D8FF66CCF85F702
+:100AD00072768DDFC3D74763F847F6B338DC2293CD
+:100AE0009CA798E2FC655E537E20CFEBEB2A78CE84
+:100AF00005F2F3483A979F9912EAD1EB92E7D1DCDD
+:100B000098F9A83E59E41F118F35463E46E4818F7F
+:100B1000AF99EF89F869E693592ECCFC3E9962E2D1
+:100B20005702FE27E2775989FFBF94BFE7AC362B07
+:100B3000C86DB7F5836CEE0F1139C69E98F9764EE5
+:100B4000F3A4809D383DCCE69B13533D5FC173B049
+:100B5000A81EE3399E5C1FA2E340F5C119ABCF6F1D
+:100B60004F037DA67266857A1A75494F02FDDBB781
+:100B7000F501EC37E8A933AA4766FE8FD23FFABFEA
+:100B800022E8CD1BAD47E6BCB14FAB7FDF017B0E4A
+:100B9000F182640FF24FD8D346E2FA4AEC3E56B1E6
+:100BA0009EDE9DD3DA04FBCF1B062C78DE4FC7F008
+:100BB0008BCA0AD8D75A27E1B4A6913EA4576B63D3
+:100BC0007911D73FFB3081BCF547A7122FD82BAD49
+:100BD0008DE549D0F798272170BD38BF91BED75910
+:100BE0005E88F19CA514AF31CF67F16025AE2FF47C
+:100BF000F0738F46FC0B22E4D2B8BFA5159E4C8E35
+:100C0000EE876ABB18C2F84C4782FD2EE26AF617DF
+:100C1000CCD723877EF1CDBD905F91AFBA005294BF
+:100C20000F87ED50DFF70B0FD5613E5B9DE48275BA
+:100C3000B7231FB76F86F38E1617BE1737BFE7C0EF
+:100C4000B9A7BCD08F03D61DDE74B00F9BD8BC955E
+:100C50007443E1D41563E0A3409DBF2E6746E27C58
+:100C600092D50E1EF7EFFEFAEE47607D7B50F582BF
+:100C7000FF52CFFD8E066547F30A3A9E3DF325EFFE
+:100C800046FABCE7C627D61E8238EB5915384E7A8D
+:100C90002FEEC9063FE3B567ECE87F1EF978CF4F2A
+:100CA000309F64509D03FD1DA17FBAC6DE9F7FE982
+:100CB00018D899C5058B8BA19D2485EC0079BA6E57
+:100CC000B8FD1D3817A161409D0DF66771DD2EFB43
+:100CD000D7804F75BFB24F07FF63D85303E3999D89
+:100CE0001CD01D541EB30A73BE9701ED7889574777
+:100CF000BEF611E0ABC84310B85EF8931DF3735213
+:100D0000480C5F4F0FE7A6603CB28EE72BCC979B59
+:100D1000C03F3EED9A9E8271C83A96A760E6D762C0
+:100D2000C0E9A9405FCED49571E6EFDCBABF6C088C
+:100D300040DCF7465B733C7E0738BF93FEBC7237DE
+:100D4000F437E9C77617C0EBA4047998790E1E8FA3
+:100D5000735F5D7C44E019CA57BB3526EE47F1FE50
+:100D6000D71C3171976B6DFF4EC8D99E0D718AC02B
+:100D7000FD504F198F8F94F3F84822BA4AC7895B08
+:100D80005039423E2D86B8C52DEC7A03BDF6D4E726
+:100D90004C35C42D88EE063B7B1AD6E1008F298B9B
+:100DA0003638601DEE1C8B5F2492DFC5F97BEE3C6C
+:100DB0001463EF7AAD7A36F8B93D37BE8D7ED2FF37
+:100DC0002EF91D91B3BA5FB5C1F959DB0A174F046B
+:100DD000FB1723C7CF00FDD72AC766FE75CCCF4BC4
+:100DE000215A549E851C8F964B09FD5121DF89C6DF
+:100DF00003CA813F2AE43C51B9D3F36F882BFFD15A
+:100E00007A86C6D4832F38187E0938D8FC524E749F
+:100E100017D8E17959EFA0DFFA0AB7C7237292D247
+:100E200077E7FDD4EE049FB7E37A79D74515CF591C
+:100E3000EF7A6ED5CF60DEE819AE749DC179DCEF34
+:100E40005A42E9BA11FC87421C9F1E25264EF827FC
+:100E500087F01F8C79BDFFE2FA63BA9FCDB39A9FEA
+:100E6000F2FB163E4FDC94F35C32CCE7B7F07D1317
+:100E7000333AD5B8F3328710A430E3750B40FFC284
+:100E80007DC672DAC83EF4760BAC03DEF482E93D2F
+:100E9000DF3F6DCE83FCBDC3B4CFC934DFDA2F8E04
+:100EA000EDF7FE12E6270A255EE079BEFFC2CF0D00
+:100EB0006CE7E706BE08FB59E9751FEC67A5CF5F35
+:100EC00082FDACF47E3FDFCF4AB2AFEE7C7871AEEC
+:100ED00093CAF9D036396488878A7DDE1D706E1218
+:100EE000E001B7CACE9B7351B405F9281C2F5A1CD8
+:100EF0003EBB4AC755FD13C17C946F9DED4379D825
+:100F0000CEE759338E11E73A9AE952A37C54204E2A
+:100F1000D53535D0DC54C8070CE466F6A45DDB6239
+:100F2000F0B4A631B968E57E5BF022093D2F45CBD0
+:100F30009FB848F66C6371B6A00CB803FEA2225CA1
+:100F40003F4010C7D5176F45FF0B7020E0323C675C
+:100F50002C17F6A5BE8478AE7E78CEBD0CB7E8A37C
+:100F600070DC08DF64E413C3E7C5AFE3F9CCF50335
+:100F7000F1E52D9AC7D4DC931FB3FFA07138D0C818
+:100F8000F1912BF67C04D52457E67AD28A251C975A
+:100F900005053CDEC3D73FC4786E5EDB87F91EBD16
+:100FA000C5360FC417CC38D18CF3D562B65F4CB9B7
+:100FB0009DED5BADBF48303F1E0526337A0E9BCAC0
+:100FC000F3793B5C012FC4311BBC26DCCBCF912ACB
+:100FD0002F30E27933DE57075413DE0FB2F9701366
+:100FE0001BCF93E709FA51CFEF64F181036E0F93A2
+:100FF0003F1242BFA7C26DB9759B07D6A9D83ECC98
+:10100000D26182F192D2010FEEABAE1824E1EB6710
+:10101000E079C36D789E90897F1510EA4D877A3C00
+:101020003D13219EA7902D708E4CA6BD45073D50C7
+:10103000DD6B71DF0DE4314C6072648FE5AF9A7C3B
+:101040007C33A840058FAB89DFA79864DF8B7210D3
+:10105000337E63AE87A95CEEC4FA969FD7EF1F6418
+:10106000796D663948B30F613CBE7258C3F39ECDAB
+:10107000E36E1ED74A2DF2FEE3B03FE362B2771370
+:101080008CB39D8DB3184755EE94611F0751D878E6
+:1010900089F52F73FCB5CCB43FCE4C97381761BDA2
+:1010A00066DA2FC6717C25A7AE2D69AFE17CDA4ADE
+:1010B0006E6746E66D7B1E5FC762E7991E181C7B54
+:1010C0001DEB808B9DEF475C8BC7B17B9B98FFCD61
+:1010D000CF11282B21C98073CA060993AF472D2150
+:1010E000474E6CF99061FFB87370593D9EC7E87226
+:1010F00055439CAD8CB0F54A7D80E0FAA54EF6CA0A
+:1011000081987E89751095C7C55489F54BF0C94CF7
+:10111000DF5DC3467FE82B41E3BE873B1F36EED33E
+:10112000F8D2DA2CC3FBDA557986F7359E9B0DF79A
+:101130005F741BCF09FA42C0784ED092E62A43F979
+:10114000454DC67382EEA8339E13D4A0DF69D25FEB
+:10115000DD20DF5D52DF0FA1FF16C7EFF3C68A0760
+:10116000978FB76E1C64E706A11F1867BF8B795F66
+:10117000DB079AC00B463DE809FAD9B93A039E9DB0
+:101180007E7A7F8878157470F9F941358495AB7152
+:10119000B3F596EA8CF8FEBCB083E6F50A71FE5F03
+:1011A000D9601FCA41B9E9BCBF52F7BCB8E779BEE4
+:1011B000A771BC20CEBF4870CEC5A8F9FB6AFBC79B
+:1011C000D799C6ED1F6FB794F41D76E624EEDFD5F0
+:1011D000F66B248F0BCE1DA4FCE8834793D97B8D3F
+:1011E000EADB96B4023CE722C35E29A54C8CC63BE1
+:1011F000893EEBAAF2CEBA791C9FE84BAEEADCD26C
+:101200000CBB87E9BFCEF0D116490FC13979E6751D
+:101210005395CFA79322ECBC0B1F3FEF22690BD154
+:101220000B298B829504D7F183B9F6D06609F2C6F3
+:10123000D97ED2D61B2D38FFB40EE93BE0772DDAEC
+:101240006E54703F638DAC6179359BCD4F3EC8B114
+:10125000877C89D7F466C3391DEE4D2ED013F52750
+:10126000EC7DA2FE744E569BE3F90BC5294CEE4F64
+:10127000294D8529281FBA9BAD4784F0DC33917F27
+:101280009B28EF96024717DA6D22F0011BBFEFC1D2
+:101290007A4A1CFDF5A730BFD8572885AC9047BACD
+:1012A0009484AC63F8959D6E4BDC78C64D29DC5F69
+:1012B000BE7C05CFB353C5F97A59EC7CBD6ED3B96A
+:1012C0009537F17E1E4AB1E3B53B670FDBA76A3A5B
+:1012D0001FBDDEB392C4E25971CE8F1A790FE34C71
+:1012E00027C7395F44AC3F6DE7FB97AB2E5A9AE2B4
+:1012F000D1FF618A82743CAF59E3F6EF5B9CDECE8E
+:10130000695E3C57B5F5490B9EA3EF73B74EC1FD1F
+:10131000DD295F232CDEC5E8AFE77AEA73873693D1
+:10132000145CA77E1A7E27442DB1412C8F9CBCB142
+:1013300005CF85DD0E797339D1FEA58875EB9D87C4
+:10134000EAF28AD9F9F310EFA91D6079E50B4B7623
+:10135000F13C927EDCAF68FE9D92D2BA800EF3F231
+:10136000C2C6F066C43F5E8F1F7FB7847837E2EF56
+:10137000A88CDA57A921EEEA1C6672DFF9736F3781
+:10138000FE0E885BE046BDB126337A3E58F9D0A107
+:101390002DB004633E1FCC7CBE90F0CB5413AE1432
+:1013A000FE5803091D56A4D171E644FED863291CDA
+:1013B0008FDC48FD313AFE77D9583EAD6FBD5402FF
+:1013C0004E63D27A6932D8AF1FF1717AB33C80E7AD
+:1013D000B4B426D8677769A45C18F73375E604DCE3
+:1013E000DE31CADF9422B37D7997D9F91EAA9DE533
+:1013F000718D5C79FE8B90EB594E1B962F7132BD2F
+:10140000A8B8F242D658F367A92F40A03FD4BEC473
+:10141000CD0F7B3185ED4754C3EC9C0AB5EDBDEA99
+:1014200078FA2CF4709DDAB40FECC716696D2809B0
+:10143000EDC0D59F5F798BFCD9EDCD654D3F9C42CA
+:10144000FBFF9AF5471ED08FCD01E3EF4B89EB6B85
+:101450005AC08EFC771F7280BF793E39701CE886B7
+:101460007837EC23EC8CBC68477B6AE2BBB99EB54D
+:101470004EC677D5C3DE937FD33D8B63E224754E92
+:1014800089CF1FFA5B40D74CABFE36B4F34865FCFE
+:1014900075C84CA5F21D785FA935FD01AE9D91DDA3
+:1014A000183F4E4ED6FF077C5FAEE8FF0ECFFFC958
+:1014B000AAF7333B5DED3A5310DDD790689C61E1AC
+:1014C000E24C412CBF3E1B9F33EC4D436C9CF5809E
+:1014D000768DE3ECA4D72FC1DC429FF797C75F6FEF
+:1014E000FF119727AA6798AF20F6BDF8DC448F3725
+:1014F0007F89F274FC6527E6B5079B20AFF3E414FF
+:101500000BD91D63E7C47905AD11E6175E7848DA9B
+:10151000CDFC4282F73FFF7ACE6E58DF5D3A8DEB0D
+:1015200031DF7771F743C6FDD0A2DD39A97CFCC756
+:10153000D1CF365E6E732AD3CF1FA4B278D855EBC5
+:101540006706AB47E8A9AAB0EB5D2E265FEFA7B20E
+:10155000AB2D4D12F9EBD3810F540FFB53AE6D7CC5
+:101560009E5A92F7D9E543E883EA35E6E76DE3FA58
+:1015700022EC15A5B3D4C9EC4520F9DAE8CC2CFD52
+:101580001CE458EC3F901D92211EBEC0C9E3955C3F
+:101590007F4F29FA42A093EAEF1D285F89F57789EA
+:1015A00093E9EF179C46FD5DE664FAFB4527D3DF20
+:1015B00066E767D0DF0FB8FEF8791C9F1C37DA1D8D
+:1015C0008A8BEF81FAEB1589EFE7267F9462FC8F17
+:1015D000FA8100D1D964F95C2C6EA0F855C7FD1BC7
+:1015E0006F1AEB7B8B8F17B563F743BD6F41FBB46D
+:1015F0003F9BFF3BE31FF0F1C5387A29F828DB5AFF
+:10160000DCB0FF35D13CB7C0C9E619BF8DEDAF20C6
+:10161000C768FB4586FE7C17F837D29F20F5ECE2C1
+:10162000F72718B73F7DC6FA62FAF308D42BFA53AE
+:1016300071E5F898FAE813FAE80ACB306FFB94F8F2
+:10164000F342AF93CDDB1F3AF427A17EB37C89EB45
+:101650003F727D48B40FE69452F98FC0EF5285D99E
+:1016600041A285FBE598FE9516B4887E072CB171E2
+:10167000B681F876F217CE11FBF00B94BF9D6CDFAC
+:101680000E95EB5FC2FD5D135CCB709FD747CC6EB0
+:10169000BEF5C97A6B1A6DA739E389EFC1F51D67ED
+:1016A0001AD2DB3294EB8461E82F67FB1F5B27B310
+:1016B00073D35A25E3F969EFF0F66EE2F6E91AF40E
+:1016C000FBAD5CF9D3EBC767B50B943F2784FD4CAA
+:1016D000CABB36BB34FB73687FE93482F8B87597B0
+:1016E0008AE76C09BDB90BC6969D77A0431EC55706
+:1016F000E9BD85DE0F81D30DF62A9B10F74C2C1720
+:1017000054F13C04FD3F983DD2CFC095DAA10FB80B
+:101710001D1A802BB543673F8B1D3AEC6476A88D6C
+:10172000CA501FC8A11262F9BDDC9FAAE77D2D2D0A
+:10173000386C88DB097FAA7360B71684BCC102B617
+:101740001F3551BB61F037207125C1EF5689ABFFC2
+:10175000C91576700236535C077154F13B7A9DD0FF
+:10176000BE06ED59F0777E5E2332AEC39BEB6B9DD8
+:10177000CAE7FD142ECF9357A27F65FE1DBD2A77C1
+:1017800068FB4C5A8FEFD8DD6C9FD5E5BBC9B22200
+:10179000C0270102E76DAAF40AF99B82EE69A9D776
+:1017A00093D8DF235689A4CC2B8CDA91AA08095749
+:1017B0001423BEC1FD5C508F87D7132882F93E4D9C
+:1017C00081F5BED712FC1ED39372607A6A4CFD7EFF
+:1017D00062C42B74FCAF4F9D8DE37F0394A3E35F42
+:1017E00090CAE6A11BE1F95927B37F4FCA4D85F096
+:1017F0003C90C196A069F9225E7E46EAE720279BCD
+:1018000009FBFD5D90DFD8F5EADDDC3E744C0C94FD
+:10181000433BD53F5FD433857EB2BABD05CF39AEE9
+:10182000B82EF2D129C8BFCD52713DB0F551E33C7D
+:10183000F21CFFFE40AA88DF5D1B8EA0F6AF3E15AE
+:10184000E963F62FE866BF33DA3239F731061FA9AC
+:101850008399193DBFB6DAB508CFE7FAC60B39331D
+:10186000E1BC2B95DBE779EE6E75058C6BA43F6EC2
+:10187000BEE95746EC20B5DE86792AFE392FF7A758
+:10188000325C4BF5F8AB7CFCEE023A5F9CA8075249
+:1018900067FFD7D9476187020AB337D46F0A82DF5F
+:1018A000B4ECD2DA23304D3593276A607D83CAE5E4
+:1018B000DF019D5FB6EF3DC27E7A303805DAA5F2D2
+:1018C000F8702AB3477F9FCAECD17752993DFA87C7
+:1018D000CF2267F7A69231F1A7C0E1027F533BBF49
+:1018E0002D95E14F8FF3F3993776F2FA02CE6B9C88
+:1018F00037BEF439B44FF1C6CF505F391F12E1DB68
+:101900005F70B9FA65AA88FBE9BF04FE2FB4EBFF4C
+:101910009C1A8B370A8FFD11F2E4A278A35BE6785C
+:1019200043898D67FB28FEE27975F758E644F54454
+:101930008DC4C721F353477048078EF7768643E678
+:101940008FD0ED1D08811E4EE1FAFE3B668F5BD401
+:10195000FE7BF01CDC7446B794CEC6F128EFC7BB03
+:10196000524ADCF8E6B1687BC7B0BDF5AC3DD97131
+:101970002BFBDD0F6157AC12B623E2C3F3D3D9774B
+:10198000A29D79FC2A70AAB99DDF46DBF92DB6F33A
+:1019900090D807ACBF05F7BE285FC3B17C05FB62DA
+:1019A0009913C34F8EEB12E1B818FEBD8776A08D58
+:1019B000B533C2BF407C3BBBCC250B3919481D4316
+:1019C0003ECE71F9381F958FF35C3E3E4C457CC28C
+:1019D000C6E1AE09C6FDE5C35CAF1EE17C12E3655E
+:1019E000A6BF95BF1FE187E7D873B1B8D65790B6A9
+:1019F000AC19E2966DB2D7E2192D6FF45F3EE0DDCF
+:101A0000FF05CC52B1EF0080000000001F8B0800E2
+:101A100000000000000BE57D0B6014D5B9F0999D26
+:101A2000D9D94DB29B4CDE1B48C226800D1A7009D5
+:101A30002106083A79F20A10111014617985F04AEA
+:101A40002262EBF36731213CD5E8556B5BB40B8226
+:101A5000628B3660AA8801372088EFD02A68F5B6F5
+:101A600041ACA0225950EBDADAF29FEF3B67B23378
+:101A70009B5DC0DAF67AFF3FDEDEC339739EDFFB83
+:101A8000FBCE37B34584FDC927BD923B9790B17E0D
+:101A9000A27A6D849C83BFAB82A555110849266448
+:101AA000995C655586D20165F5CEAA8184B4977498
+:101AB0002EA90AD3FFB604DA9FF69B9EBEA92CD9A5
+:101AC00049FB7B687B0A21C31DF4DF2221D7D5B4F3
+:101AD0008B6EDDB8E99F7E3C4F0D33CF4F124CB873
+:101AE0006EC30CD721673E9DC661726D253DFB35E7
+:101AF000C7CBB8DEA86CAF1447FBBD7986289B69BD
+:101B0000BFEB260BAA979EAB829FCB96C0CE91A52A
+:101B100048D85FE5FB1C2577CE0B778E7CFE7CB426
+:101B200093A82D749ED10A517786E95708FB8479D2
+:101B3000A2C3CF338DCF3386B079429FCFE0FB1A5B
+:101B400055127EFC083EFF34C78EF20402FBD964B6
+:101B500006F8E599D5610A1DB736021E52A4929186
+:101B600080AF280A3A731E2133E958139D6016E0AE
+:101B70009C960F8AEE5278EEA6E070E40125787A02
+:101B8000015E4B6C6A19B44747ABE530FF4849AD7D
+:101B900080F297667514E29FF80829206402A79FD7
+:101BA00009569B4F8CA5FF28349FEAB4B2B673D96F
+:101BB000F0FF67281F5F4688407CC2B9CBA0EE15B6
+:101BC00061FEE1CE43EF0AB4FF706DDC4929645C2D
+:101BD000BAF2710CAF8BB82F84CF6EF34F9D365392
+:101BE000CF736AE56E9BDB0A70381DED9E09FB6CB6
+:101BF000706CB63929BC5F75B7585DB4FD641C4183
+:101C00003876C5A86E7CBE9BD4B4D0763146A86F1A
+:101C1000D1C16FBEC2E05DAD30BCBD25A9D570FE9F
+:101C2000095675018C9B9C49F144E79D95D8B95C98
+:101C30000FF77A8EA7859C6E67CAAC5FE83EABF95A
+:101C4000F32249F0C4C09E6C873E12813F48F75F83
+:101C50003F13AD8F857F51FE293AA94C9D96447163
+:101C6000B6467499685DCE11C2F2E99D7CBF944F6F
+:101C7000EF84FD1227E5533BA50F393C7D7CC5FB66
+:101C80009747A0CB3C7E9E32781E66FCA59CAECBCF
+:101C900092DA4542C717717E0BED373741C47E0D8E
+:101CA0002E323ADC3C0F04E5CB03485F0ADB779E1B
+:101CB000B9EA21A8CF500E97C7D3E6E2BB93A6920C
+:101CC0002480878958B2104E5642E1247138D16D74
+:101CD00012A82FB3B2BA14BD84C4D132D3E15D3F90
+:101CE00008E0D768763969FDC3931F8A84D2D9D6B4
+:101CF00007CE0A84CA8BDD7E4212B3601E19668449
+:101D00003FD339A1E77CF49953D2D6A3A0B9F224EA
+:101D1000512D947EAF2CF44F22B186F1E41C9DCF5F
+:101D2000E6EFF008803F2BF1C45C8E64FC76BF14B4
+:101D30009C15E74BA5EBC279E42F8917CEA33ADCBB
+:101D400095641021F1FECE5FD461BBCD350ACF453D
+:101D50006CC06FC1732E43FED3F625DB3A1FBB97D1
+:101D6000F66FFB2ADA75179CDB5FF109DB0FF1D800
+:101D700081AFC54A17C877422CB83F13FD0FF86CE6
+:101D80006480EE3787EF1716C9D7ED9FF43CCF83F9
+:101D900062D521C0C72C2B5163F3503EBC02F5BE67
+:101DA00066DA81C2B14911BC1EDAAFE981796BB242
+:101DB000405E6F905CFD09D039D925503A1F41D75C
+:101DC000BD85CA1DB990D8145A971DECFC4D7727D4
+:101DD0006D8A11E0B94465212DFDBE6F040A875854
+:101DE0004775A542CF21F3F102051C8C179C0A9977
+:101DF000910774DB2112940F0E8487C63FEA8F8807
+:101E0000F0B115550D01FA2A9388C74AFB0B0E361F
+:101E1000EF95C42F92BE8007AA086859425C58DE2D
+:101E20002BBA3F06BEB1CA14AF74FF5693D5BB524E
+:101E300000FC55BD3E1AE15EA67C9C13946791E4BC
+:101E40001040EE630DAEE2F7977BE5CBC3F3D5DF31
+:101E5000827CF3372697995E9E9CCDE4CE017BE78A
+:101E60000C3DDFAF5298DC59C5C71189F1D9325901
+:101E700035C59F87CFD7F2719782F2017D4CC2F3AF
+:101E8000714B3C930793EFF236F5A2F09B9020B88C
+:101E9000400F976F9F2DF57606FBA5727DA7A4A82E
+:101EA000F1F130DF6ED7496F12681F19F57BD37BD4
+:101EB000641ACC3F9BCBCF009FF72FF16C1FE9BC7E
+:101EC0007E4CB04F0B0797CCF86EB864C2B9889BB4
+:101ED000C1458C19ECF7D175486FBE8E59C075DAC3
+:101EE000B3997CCCE6FBD2D6E9C3E51F95FB97C03E
+:101EF0003E27677AD3A1DFAB66B6BFD0750706D79A
+:101F00001D88EB2E61EB8E05390FFCEF3CF412C8F7
+:101F1000F9224EA763FD6E02760FF0B0A92028EFDC
+:101F200065A74FACA7ED4511E4FCF0E03AC3719D05
+:101F30007A86C73D29EA08D827B50B8AA0BD3D5B44
+:101F40004179F9662F13D94CF972765AF63D20364D
+:101F5000B57976F273B6673539E6507CC97EE2B260
+:101F6000209DD7A0DC2BE2F2A561B79BC0734F2F59
+:101F70002A3375E365FF1C2BB1E151FE714EEB4F27
+:101F8000F9A8C99F1DE70E8317AD5CBF828922E2C5
+:101F90005C8AE396F171A1FD6C0FEE8B81F93740FD
+:101FA000FF1F113291EB1B7A60DCDF58CE3B0DFE38
+:101FB000CD319DB4DFEE9CB986FDE073CA474D3943
+:101FC0008FC580BDD49641F500C8A9574494934D60
+:101FD0007686C7A6B46AA2B7474B1D3EF16398E761
+:101FE000DBB9642AC55F91C34D2EA1F05DC7F751DF
+:101FF000E4AAF60849D8FE6C149D6779FC250847C9
+:1020000039C74D2A72012E5E524DC7CB8A4F74D10B
+:102010007AA99FF8AECA87FE54CE0B6C3EA75D3FEF
+:102020000F698179E45C460FB2BF8500FC769F3C66
+:102030003F1C63724C06F9ADF125B5EB56001D94BB
+:10204000295797C5D3F9176DCFCA13E9FC158E76BA
+:10205000794E2ECA6D0FD0C7CE647565FCFFA03DCA
+:10206000378D78CD80F751994C0F4CA815BC9B2922
+:102070007C9A42EC849FC6333E2C0CCABB9FE1BEC7
+:102080000B353B41FD39D4CF63073F0AF0388F1D34
+:10209000BC059E87B183B7423B85D7E3F1CC0E7E6A
+:1020A00002D6A176F0B6EF03B7090A93A3D40EDDEA
+:1020B00001F3C6837103F6D11F983D1ABAFFDBF80E
+:1020C000F9D7D0B376005D4A5E89D139E3D3E19C7C
+:1020D0004FC79EA4FC92DB93FEDB28FD7B28FD9D71
+:1020E000A576939815999E7C17C997C50F32BE6F38
+:1020F00070EC43BE7B91F3451B5FBF2D47AC047C66
+:10210000BE4A4445147ACED794E176805C0FE53F11
+:10211000F55B233D973ABC1BF2806F0ECD75C1B6BF
+:1021200042F951A665F5C0E0BE8F031F0ED5C92741
+:102130002248C88F17E04398C73D10EC8C7849CDF2
+:10214000053E62EB7A0E89A82722F111A59B5380E8
+:10215000BF6EB800B075FBA774F3393CA77C76FA64
+:10216000FBD0CB1A4E1FD40FF91AE6EB1FCFE8674E
+:102170007604FFE21FF1DD7EC03FA03F99C1F4501D
+:1021800066BC938D234932E81755CCC804F942E761
+:102190003525D0F6B7B87F1469DEA8846EFE8B4A69
+:1021A00080F3DCC2E63D0446F6D09EF38E4AA0F6EC
+:1021B000479879D2B81CBF2E82BF90C5FD1292DB22
+:1021C0006D9FA4C07A599C6F7627AB8E041DDF14D7
+:1021D00071BBE565C1A89773BAFD7DC63F4909ACDF
+:1021E0003F99D73D6F56820E9E9A1D309BCB076D4F
+:1021F0009EFE9CFF9C090A1B5FC3C6C7439D8EAB16
+:10220000E0FE13854B2ECC47ACECF985FCA27B1489
+:1022100019C7CFE5FB12E2154DBF215C4747F2BB62
+:1022200082727038E2C1C5FA5FAA100DEF23711FE8
+:10223000956C1F850AC37B68FC20127E34F8276BDF
+:10224000E7CD61F3134F37DC46EBE92512DCDE8A7C
+:1022500063F6C5280E27D2C8E7099107774B1D56AC
+:1022600025CC39AF8D771AF8D9EE32CA8748F19468
+:10227000BC207C66221CF2D9BE23C5570AF87947D8
+:1022800070FB968E9B8F70B5B1FDDEA374B7D7E05F
+:102290007CE96CBEFA20BC1763BB83F58FE4F7D7EB
+:1022A000F37D5527748F5B86EB24B171A1F104ADEA
+:1022B0005CC2F7B73038EE565CAF1F1B971CDCC70B
+:1022C0001DD83E9AB57FDFF85B32DFEF4F82EBAE71
+:1022D000C1FDAAECFC81B86EB8ACC7F622B66E247C
+:1022E000F9118863E768E270BE12FC623A477C80AD
+:1022F000E44849E03545BB46D12EA901D507FAA3EC
+:10230000E44BD90972BA5CB479042A8F25A715FD6C
+:10231000E42889A8E0D7B67FF56347672ED67DA06D
+:10232000D75747155BC1EF5C9325B9401F16DF27D0
+:1023300031FFFA9409E57D85B804E7D9A76876EE00
+:102340008D063FDAA9382BA3601F56913899FF5F9D
+:10235000399E3EBF8ACBEB7DD64413CC372283C552
+:102360000BAE7256A3BF4EBE657EB44AFF63F25BEE
+:1023700045BD2CF371527A3D11B034FADB32D9707D
+:10238000461C847A01EDA8117EA3FF2D3B2B4EC085
+:10239000FC32D18DA3EB3E9F604F427BAA1FE97FA9
+:1023A0008EF28F25472016EA5F944BEE3D808731F1
+:1023B000CE6AA5849EC792EEB6821CEE67F6F586BD
+:1023C000784263BAECF2001B3E5066CD027FAB99B7
+:1023D000FAE7080735E1EA81413C598A540274481A
+:1023E0007182FCD55DDA589990C8F0F8498205CB26
+:1023F000125ED79E87E27D486234E37F62F57C946B
+:102400000372422071940E9792CE4CA0C7E43426FA
+:102410009F6A4D9D2950EF22FE94245A36344BA3D7
+:10242000C3F93F1B79FC6CAD29BCBDF44BF3980F8D
+:10243000000E12C40D2EC7B880DBD237183FD0EC87
+:10244000552D8E10C96EBD57ACFA18E61114DF3742
+:10245000D0BFA7FDEBC17D48E94C4E6BA5B68F9967
+:10246000898C7F1C895684CFDE3B4AC91C27E2E950
+:102470002CF029C5D3A12B002A59F314C0D32B5912
+:102480000FF583B89435EB8124E0CFD184D9A7E54B
+:10249000748C83960FD9DCDF24E8E4E1987EB3D115
+:1024A0006E2ACAAC477B6A7504BFF4C77C1F12A7AB
+:1024B00093129BDB943814E25FCBAC305E52AAA23D
+:1024C000A1DC1B988425B57BA544DA7F753AAB5F08
+:1024D000080FEF72F91069FFA3402F40BC26BDFB27
+:1024E0001C09303F7DEE91F382E7D0ED2F25DCFE15
+:1024F000CC894C1F69FB92FA71BACC31D2DD784E8F
+:102500008F39899ABF78D17477E462E82EF4BC637E
+:10251000B2968F1E4082FBD7CEAB9D9F9ED705E71C
+:102520002D97D8F9B72A6E15A6A0701E0CED3DCEDA
+:10253000650DAFF733124DDFF53C0F25F4BDF8F311
+:102540007C8779A7267E07381D18A93A409E342635
+:1025500053FAA4786A1458A9F58FE6786AE174FAF8
+:102560005DE444FFEF70BE6287F012E8C3ABDCC7E6
+:102570004A6199B2A2C1A076801FE701BD95E4DE51
+:1025800027CDA1F5A63BE6A2FC3C30B21EF7BDDA92
+:102590006EDCAF5626707C1465AAC87F8D9CFFCA7E
+:1025A00009F323B57E6DFC5CA1FC113A5F285F3F07
+:1025B00064536F06FA484864FA32E8FF75887AFF78
+:1025C000AF84EBAF91D69B0CF18F91DCFF5BFD6587
+:1025D000B6CD430F7A96EAB57F89FFF70D7D027E6F
+:1025E000527A8955EFFF355A4BB17D75863AFAF22A
+:1025F00024D0C7A2EB2E82F0437FD02388CAD630E6
+:10260000FEE0EA0CD977157D6E51C8E3B0BF52AA3F
+:102610002F21FE62515472C9C09E7EE13E6B29811A
+:10262000B8C959853C0BFED885CEF378A2D12F943A
+:10263000C02FE4F3A35FA8D4934E8CF79412B06B31
+:10264000A0DD3910E48E4ADC76D023D42FD4C9A77C
+:10265000B3D69B90DF43D7A372EB69A0A34685F165
+:1026600071A83F28723ED7E46C283D943B18DD44A6
+:10267000D1AD9B99DC782E31B9275D7C77F934AFE9
+:102680000C5C806BC9CA03E0AA4D09F825707996E5
+:10269000273AB15F956D47233CD7E60FC50F3DB98B
+:1026A0000AF174B06758FC86DA6BD48E32537B6DB6
+:1026B0009D105C7F358777247CAC067D1D868FDE80
+:1026C000EE966BA171A29B8CF72F8A872415B0B868
+:1026D0003E09037F91DB496B28BFC0FDCD6AB3CBB8
+:1026E000A1009D6614BDEB067F3E43C6FB0822D5C4
+:1026F0003BAEB6F73CE71A889F85D9DF17890908F2
+:10270000576BBAC9609F1172A7C17E8C746EC2F7F5
+:1027100065E6E712009E397A78869CBB4CC17383CC
+:10272000590FF3C69A5CC447F9223693B85060C576
+:102730009A300EABF1B9C2F95C930736858DAB4C7C
+:10274000EACBEEF7449B5FA4E75F9F44ED693A4F05
+:1027500083BA0FF5AA363E8E9FDF3692C51B6D7683
+:102760009FA28481C3BD9CCF239DB35995E2CBE842
+:10277000FEEE5598FD2D8D345579311EC5E2B50A12
+:10278000879D589C6F05BB7D54523C8B7BA93B15A4
+:102790007DDC4AE4FB89B1D3FD9C474EAE0DD94F99
+:1027A000544E6719EC5FCA529578DDFE4B9234BDEA
+:1027B000D281FC1D69BEBBB99C8FEAE7C2F8ADD5DA
+:1027C000E6F2C1BD56945A5D0062313AC745E6EA69
+:1027D000DAA3D58221161D1D3667C861EF236EE787
+:1027E000EBDB25B50AC6D91589C03D999DDBCB9198
+:1027F000E68DB48F0BAD372D89E9D31EEB39C3DBE2
+:10280000157D9218FF49237756819C260325D23FD8
+:102810008C9E484862F22556EE7482BF4EE9D11D67
+:102820006E3E9224737EFE37F187667717B71ECA15
+:10283000A6FB6DB0492E01E457E1C90EA70E3E5428
+:10284000AFCF4AD2C97DD1E646F9263AD9BDFB6859
+:102850000BF3B70F8C34DE93CDE7F8FA80C33192D7
+:102860005C28E2F0F8779DF3BBE2AF2489C97D0DC7
+:102870002ECD001702FC757F6343187949E1D39090
+:1028800094FCDDE1B396C3E5E90BC067D07F183E49
+:1028900017E2EB209F79C9F130706CB0CB69730DF2
+:1028A000FCDF8C7648B87ED5BAF346E2438D3E20F5
+:1028B0007703E1D0AC1AE2027292A783F995371B35
+:1028C000F59CB8C4C5E533F996C22D9EF78FB711B4
+:1028D0005F4C6C707EB9CC184F684BE27181281246
+:1028E00005F039EB9A24409E82C53463B0920D4BBB
+:1028F000340BA02752609E4184DCC7E567A81E4CBC
+:1029000056999FDC9BD40B4CAFA4E3FE92F83E4259
+:10291000F5601AF56B201E0347047FBA37AD5BC123
+:1029200006212ADE830B1E13FACB0EE21560FE741D
+:10293000D289651F4845A0F367910EA11FC5DF7DB1
+:10294000E5D583417EBF13728E0BD9A35AA9D91F37
+:102950006BFF43F0FEF47F2FBC5796EAE02D267FF5
+:102960003F78CFE77227349E5704F1BC2C88E7F9F3
+:10297000F6039FCADF32FBA3FDEF32C6F71AB35846
+:102980003CAF5CAC7C18EF419D32BA1F524EE77AE7
+:10299000C873D2EC4ED4797D83713FEB99FB2588C7
+:1029A000A310E924C209EF869C28CF329351DE3070
+:1029B0003BE22ABE7F396B9E15EEBD83FE934F64CA
+:1029C000F606B397644E07458E12F45F1ABF3DBFFB
+:1029D000DD71B17ED25EE900DE5F6BFE51837F0E5A
+:1029E000FA4BA1E37C92EF7D38BFCF2F3B21DFA4D0
+:1029F0008DDF8BB59D396888D386FA419A5D751550
+:102A0000DF7FA9DF7DE872B8DF52E61016DF647061
+:102A100090F93A8D8EB3780FFEE2B726F4B7CE72F6
+:102A20007FAB08FC2C3BF377AAED3DCF392139BCB5
+:102A3000FF04E320AFAE54F18960CF69FE13B43BCD
+:102A4000ED3DFDA7D116FF6BB0BF09AF89981712F6
+:102A500009BEA17E53A8FE999ECCF4CE4DC9DCAE32
+:102A60000B81A716EF0BBD976ED2F84FF2087AFED6
+:102A70000F5D5FDE3706F74F145D3C363B184F1491
+:102A8000540FB9252F183F0C13375C0A74A8C50DD5
+:102A9000353DA6D1B185F6B5E23D73F878625BD6D7
+:102AA000C1BECC2F7C2911F8B35C6171236D7FD43A
+:102AB0002FBC2D59878F223FD3DB96FF53DFB9926E
+:102AC000C297241017F30FEA9D565AAF5048E23AC6
+:102AD000E4331BE669152509C877922F0AEB15A781
+:102AE0005CDE285AB7EC7B45149360BD39244A0854
+:102AF000D28F96D7D1E8FF703DE0EFEC29C9753E43
+:102B0000BFBB028268063F293A884F946F0986FA54
+:102B10004392FBA164B4177B05C789900F966DC8DB
+:102B20003F7B46527F0A709D6A551FC6FE3F3CBCE4
+:102B30006F4FC678F1C17F0AEFC175983E009B8D3B
+:102B4000A4E9D6B3D1C661B08E93DD176A71E9E509
+:102B500004EF63B601CE20CEF239F1429CE505F3D5
+:102B6000CB22E8A3263ECF70D2EC94FBB2FD42BF4D
+:102B700027B73A36015DFC2E390BD77FC1E6DE3030
+:102B800098B61FDA220D86B84D83F3192BE4CFEEE9
+:102B9000DBDA94DEA9E3BF434FBAFB84F30FB592AF
+:102BA000FEC5990AF15CB1AC54459303DB45A8F727
+:102BB000B0CFB6B42AB0CE935BADD3C2C535C41482
+:102BC000C6EFC3B730BB76748EC905E2AD8878A472
+:102BD00004B88F7111978F36C40CDCD9813670968A
+:102BE00088F71AB4BE3F96D66386AAE81F0C18B8B9
+:102BF00013C70FF8BCC4C5F2283DB63C5A5F9F53BB
+:102C000032741DADA747BB3F06FAA27AA659427D92
+:102C1000DA1203790031032725AFA3B51881548553
+:102C2000B373FF9ACCECEF27CD1A5C25CC83DCB7CD
+:102C30005546FE3A9426E2FD1385DB12A8FF252DAA
+:102C400086504A2465AAA70CE0584E5A1AC09F2AFB
+:102C5000735EFD522CF927E097BF5301FE5F1FC141
+:102C60000EFF1DDF1F0A114A3F07B7345E47C2E45B
+:102C7000516B74F85C8C2AA5D0FE6BF9BD2E714C9B
+:102C800042FA898CEFBB98BFD9E26B88A6701CBE54
+:102C9000BDB9977EFE2310744DEE896FC87F2697CD
+:102CA00043FEAD1BF3691B4E9A107EAFE60A5E81B0
+:102CB000C2E7608E486D36BAAB7E566F7F5ADFC072
+:102CC000E9B872FBE1C65EC0C22949B8EEAB398FE4
+:102CD00059597EEBC5C7AF87503E5804F953141FAE
+:102CE000A39468AF93E26B314C41EB2315ABD7470C
+:102CF000D76BB77794C6D1255E48165C9B815E7210
+:102D00008802F2035D1013439442EB2032909E92AE
+:102D100008E673AD2FC8DD0C71B175E9CE16C83762
+:102D2000DC33D08AF966A1F9C47B84FA97E2212EBC
+:102D3000152FA0BC3E98F33BBCA73B986E2140AF3B
+:102D400098F04B9F3726303E8DC937DA9FE52959D9
+:102D5000DCCF261E4B41705F31FDAC6A1425A49771
+:102D6000E3D9F843FD042FD0DB2127970FF4BC5B98
+:102D7000C120929AA5A90323E3F595FEA39C9A5D31
+:102D80002C68E734F53CC70B82774D369C63003DD9
+:102D900007ADDB73045CDFAEACBB916059B800EEED
+:102DA0003143F7BF2285F9473225BB1C906F2D6B4D
+:102DB000C6E8F363E4C21B27D862318F09EDCAD499
+:102DC0001C01CF33E624BBCFED919FAD10B76CC093
+:102DD0000FB53A5282F3C57CF9EC4F20FF775CA126
+:102DE000E08B82FDF0FC66FA7FEDA05FE47EB359D4
+:102DF000FE75CE263CCFD842B30BEE72C6DABCCD00
+:102E000025B4FECA2712C6B3C7F51B85F9D5A1EBB9
+:102E1000AF53886F3485EF2BB912C23BEA92C7706B
+:102E20009E37734D286FC6413E36E42FEBF3AA510F
+:102E30001F1AF3B9C7891FA8C5D0EC62FC4A244FFA
+:102E40002F90EF131C46F8D94F1AEF8B2BF32D86DA
+:102E5000FAB85C39440F7B10DE2F6730BA7879807E
+:102E6000E0DD9C15A4B3B12713BC4067F02716180A
+:102E7000E06838678C5F56017E87063CF15F704FD3
+:102E800012E35C7D23DE8373F86B7412C3F16E4F23
+:102E90007FEE27A0A734F887D2C1C5E3FFEAAA6274
+:102EA000C07FBE767F1F82FF107C630C523B47DFE2
+:102EB0009E78C7F5B37AE25BA3831EE7BEBB754D70
+:102EC00036C5EBAB76FA00F0BC49F6DE2504F174AA
+:102ED00041BCF62B46BA59A734DB40EE475D72DCA5
+:102EE00006FE814617446CCBD7DBFBFF2A7C976C30
+:102EF000109833E912BC10D77B0B1E0D0BAEF352AA
+:102F00004A77BECC4B20F74915CBE36850F3D87B0A
+:102F100057F94C9F86CA873FA4B0F73ADACD2FA75E
+:102F20009F2F4FB5D2E626703FD600F976F47CF29B
+:102F300086D9F046039127CF46794936082C0FA150
+:102F4000E8F728DFE739BCAB8430EBA12583FB74BD
+:102F500032BBBF2811FB93695A5E52D507B8FFC92F
+:102F6000AC7EB1FB7AE35FB4AFA3945688CEFF9CEE
+:102F7000C8E3F29ADD3DC1C6F20E271489888F3767
+:102F8000B7085ECC8FA4FD3C944E1671B29DC8ED7F
+:102F9000C0B385CF340D76823DA81AEC4EA1A81D92
+:102FA000EDBEB842A33F18AF461BF09F383AC15060
+:102FB0004FAEEA65E89F3A2DDB1857705F6A78DEFE
+:102FC000BB26CF50CFA81F6EE8DFE79612433DCB5C
+:102FD00033D6D0BFEF9A49867AFFE6EB0CFD7FF43B
+:102FE000F01CC3F301DE4586E7976D5B66A80F6CA6
+:102FF000B9CDD0FFF25D77199E0FF6AD333C1F724D
+:10300000E87E437D68C7CF0DFDAF7877B3E1F9B0B7
+:10301000CE5F199E8F38B9D3501FE9DF6DE87F5519
+:10302000609FA15E4C5E33F42FB5FEDE502F57DE5D
+:1030300037F41FE5386E783EC6F999E1B94607E3E3
+:1030400072BE30B48F77FD2DE43D9D2A16E780785F
+:10305000405F78D48C65346961F73AA403CB850569
+:10306000EEE254E08F473D4D9090D4E0F1FF11AE79
+:10307000A6DF2CEC1BC7EC2795E8E5A7969F4AFD39
+:10308000164F142585D800A5DB2194EE0202964A3E
+:10309000804AD64488F74461991048C4F6C4403C3D
+:1030A000964981DED89E1C48C33225D017CBD44028
+:1030B00016968EC06558A6050660D92B3004C7F554
+:1030C0000E0CC6323D3002DB3302C3B0CC0C94622E
+:1030D0007B9F403196CEC0382CB30263B0CC0E5CDF
+:1030E00083FDFA06AEC6B25FE07A6CEF1F988EE5FC
+:1030F0002581B958FE28301BCB9CC0622C070416D2
+:10310000627969E0261C7759E0462C7303B763FBAC
+:10311000C0C0AD580E0A34607979602596AEC07A89
+:10312000EC3738B016CBBCC07F61FB90C07D58E651
+:10313000077E81ED43033FC3B220F0189657043653
+:10314000615918F83596C3024F62393CF00C8E1B5A
+:1031500011D8816551E0056C1F19781ECB2B03FB3C
+:10316000B1FDAA403B966AE0356C2F0EBC826549E2
+:10317000E0F7D85E1A388C6559E07D6C2F0FBC875C
+:103180006545E03896A302C7B01C1DF80CCB318111
+:103190004FB01C1BF802C78D0B9CC1B232F0376CCC
+:1031A0001F1FF806CB6E7917315FD96D427F96FBF2
+:1031B000A991FD050FCA49337F2F0E72AB31FFBFB6
+:1031C0005EF062BC30A9F325A89B0B2D182FBC81A3
+:1031D000F8F13D81FF269D7690A7EDC34EA443BC38
+:1031E000E9CD645F863EDFC1CCE300E5E22909FC5E
+:1031F000D50949FB92419FDE409B21CF88A8E7304B
+:103200000F7202CF83BC41A20E16DDEA61986118ED
+:10321000F6F359687D462551F368FFA661168CEBDD
+:1032200037E5513F88967767B17CD91DA94C5FFE81
+:103230008A97BB52991DEB2960F7FB336EECCFF8F0
+:10324000A92CF1027E1383C3DF07F23C5B9B3F1383
+:10325000F3632F72DC67297C1CEFDF9C5AD5960A3A
+:10326000FB282139F5B6603FDAFE6284F67DE1DAAB
+:10327000F799183E3C4744EE2754C54D3A8F9FF0CE
+:10328000E68A8E4B5FEA1FACBF15C10F256425EEA1
+:103290003776DF2795D7527D38B1507451C9413EFA
+:1032A00058B16BE447FDD9BA909FE92911317E31BD
+:1032B000A3E8F081445A9FB13C1EF3EEBBF7556280
+:1032C000C6E7131C472E7D891EFD86FAE7477E64FC
+:1032D000888BBAD1EEBA89D32851CD7FEDD49E2305
+:1032E000BDB2B8EF4DB0B813E49F19E7ED50CDDE95
+:1032F000F3E5C710D5425403DD3378AD87FD83EF86
+:103300004FAC26583796F7A17045BDEF8995BD0D96
+:103310000238EFCE38A0BB985C3F395F7C19E029BA
+:1033200061A242A70DEC9848F04C7030FA8B2B52FA
+:103330001D1E8A9FC6BF8B78CFB53FBE4001FABF26
+:10334000C7D62F15F823D9C1E2278DEDEF617C2B6D
+:103350002EDF4F3C36767FEEB4401CDF8AE5AA159F
+:103360002E2C1B571462B92EFD7E2BC44BC464094E
+:1033700032814954C63C8C0769EB9BE3E7588B5D6F
+:10338000946C1D722584904488330C87F736E5CA07
+:1033900095FD08F92695E57DBFE9F8C806FCF04DD6
+:1033A000AA13EBA289DD1BC7E4FB54C84B88712923
+:1033B000259233D88E7F49D8BE19FC913749E786CC
+:1033C0006B008E2A7B1FA381BF6FDA50DC9FC35531
+:1033D0001B1782F7103C8BB20BEFADC568DA3F3795
+:1033E000325E0738E2719F405F12A52F3FDF3751F1
+:1033F000634C309F86DFB3921FF3A91A84F079974C
+:1034000043387E1A155539DF3D0A51A4BFEAE5A9B4
+:103410002D7757083DDB50BE621DF2B9B8BCDA9F6C
+:10342000AA0E73D0F9C75CC9F3EBD313500ED0F6D4
+:1034300001C3219FCE44153AC02D41467EA140884C
+:10344000833C5F6275C64D3A4F1EC4DA150E553285
+:10345000C3FD80330EE0B5969F0FDE50D6CB817F43
+:1034600057BFA0BCF022DD86F66FD1E4408215E59F
+:1034700093C8E1A18D5BE860F2D8945D35D33194B7
+:103480008D033EA27537C08B58697D20D6E7E07367
+:10349000A5BB3E0FEB0ED61F13692E420ED3718BC8
+:1034A000719CD43DCF52ACDBBAD7ADC37593BAEBA8
+:1034B00037623D9DF5BFD875B4B2FBFCBF6372F2B5
+:1034C0004B498D4BA0F43CF696B955A00AC6DFB225
+:1034D000B0AA8CEAEF3FAE785705B9F40195278D75
+:1034E000B41C3B607F22F839E387EE8F71EAE8F580
+:1034F000061ED76CBBC53C1AF45DD1AD62D51684EF
+:10350000F74AC3BDCF1A8799C79BD83E664884DC6B
+:103510009100F2F7F0A58D06BF93F3A1C2DABAF7D6
+:103520007B9B80FBFDA09EC9DB0F960B286FBBF930
+:10353000349E703FDE970C709AB95C27B74918B873
+:10354000D45B88DB20D723C18790BFD2FA97B67EA1
+:103550001897A5969AB52A8C3ED3E014090F3744E4
+:1035600088FF6A70D2E0ADB5FFE98E210AB3ABBD2A
+:103570000638CEBA7328C62B6FE0F17A126FE5FCDD
+:10358000C9FACDA0EBECCC457A7202BD433D6C9EEE
+:103590000D5F7706FDD71D79178507CC97FFA0FE35
+:1035A00080DDADBBFF0C857B443A8C00EF3A0BC14C
+:1035B000F72AFC5BED2C9E94340DE7ADE1EB92A471
+:1035C00019B88F1ABECE4B7B637C26B887DA6ADFC8
+:1035D0000CFE705789276522E06BB319F3DAEEDA37
+:1035E000BBFEC82FE03E789319EF4E167EF14001E6
+:1035F000DCCB76713D4615413B7C47C14DB43F5510
+:1036000080F91710367F97760FB2350EE17AB26CDB
+:103610004BD3085A76EE595A09F197137BC71F040A
+:10362000FF79613491D2C0DEABDF21233C3CE68FD1
+:103630008C768214AC8B3DEB0BA0AE8B232DF49AD1
+:103640008375FABFC5DB8C753DBC4C7A7839CB8C61
+:10365000F072961BE025BC68F7893A78959D792928
+:1036600011F4FB518713E7AB39D39802F0A9D9B312
+:1036700016CBC5DBA23C1FE9D65DDA126FA8D7EDE9
+:103680004AF3E8F5CBD9438FC5C2F9973944CF4700
+:10369000547E9C5AA136001D9F5E31BA414FCF4BDC
+:1036A0005BB23C36C33CC6FAD96601ED14D0339305
+:1036B000CF632F2E73C8B8CEA7DB98DFF9E90AAB2A
+:1036C00007D639B542F1B0751D1E664F31782DB958
+:1036D00025C6F3D190E0FE22CDFBAFDE1F21ADE485
+:1036E000B895E0BB3BE7CEA3BF23F28BF4A58CF2E9
+:1036F000BDCDFC17A01B2BFDDF398CA74A58D7E6A0
+:10370000AD6B113D90574CC876C37A749CF3639DA2
+:103710005D10593F18BF373102626228A7D97D88F2
+:103720001BEE43E87C5D926D0DC413B4FB903A58D8
+:1037300088F65D6AED94DDB4E9F3D6BEE77DDF9CE3
+:10374000E2290BF4738DB55906A55BD332A00CF8B2
+:10375000E9F3D68614B067178B677F1CEEBDAF29DF
+:10376000699C6FBD66BFD16FF46AFBCC920C7C463E
+:103770006CDDE7A6F55311DEF399C5E7ADDD7EB844
+:103780006204DD7FEDAE3332EC2339CD3D2B2D3994
+:10379000787E81DF072DDA760CF9FCA4D973C9EDA8
+:1037A000E7B3F37BECD3E630E41F7A4807F0E79CFD
+:1037B00042A231ECB5EF5379F3C96B6602F788E4A6
+:1037C0005BDA8B3ECFE44FE791AA5880D79CD6C5F1
+:1037D000287F3E7976DC419687D45C00F4F139315C
+:1037E000E1FBEE9F93DFC50ED1C16F5D9A9647C98D
+:1037F000BE73A3E5B9D00DA6619E7A4D5307BC3FB9
+:1038000066219287CB25817DB7C62BA0FD52C3DAF6
+:103810003DC4BA12CFB186C9230FFD0FEAF39B8DC9
+:10382000F269C1C3C67A3599940279DED50F982121
+:1038300093882CD4CB3F0ABF1BD398FFB980D437D1
+:10384000815DF788CCF2BBE72844EA4DF5D1D2E799
+:103850001E29984DEBF7A5317BEC53EE6FC07B8CA6
+:1038600069F4F9A25BBCB29ADBF37CC75B874C1DA1
+:1038700041703EE63F2DD2EC57E284787E6FF857D8
+:1038800076E4F3F76E15F1FEA937B4EBE4F3DC351B
+:10389000C6F35DE8FCA1E725E47E3CC7A26D57A313
+:1038A000FFA69D47C397761EF3B6F0EFFB6E4B1352
+:1038B0000C76DC2E0E3FCDFFDE1352DF97C6EC7A7E
+:1038C000ADFE72485DA36F33E76F4AF77B80EE97DA
+:1038D0005AFD158C4E3A65FDBDA81CECB72F6D68DE
+:1038E000E47E16CE2FB4DFCBE7EB17159CEFF57017
+:1038F000EB2E7DEEA967C12F5DF49B0763E152E8D3
+:1039000013A93905DEB758B275552CC0E9A4E4896E
+:1039100005BAF9C42B8E0E072F532F0D5EAA4DA0AA
+:1039200078AFD5E8BF68E504D0EF7FD96A56C03FCD
+:10393000ACDB66F1C177986A5B17E2BD0DAD1F6322
+:10394000F5D5F87E65DD2EF3877ABC2E7AE2C114B8
+:10395000CCF3209EDEEC5EDDD71B3E2154BBE5CFD1
+:1039600015E02FD7113FD273E838583F9080F27A94
+:10397000B61CD7F3B9163FAD634DA4AE75FD1988DB
+:103980009FD6B58E39017C5F47A40FF5F4540334FC
+:103990004DFD962FD278FEDD15E40A902F1A3C8853
+:1039A0003719E573C3933F1D748CEEE7D496D76245
+:1039B00005BDDFCAEFDDCFB6CCFD53E279F4C369B4
+:1039C0004AA7FAF73234B9EBDC4537904AAB6DAC15
+:1039D0005C62F6C58EA0705DB2C98CEF892E79EA63
+:1039E000B1C77F0EF944EF59F01E64F153078E0CF6
+:1039F000A7F5C53BCC4995EC1836B817D6F0524719
+:103A0000FF07F7141A1E163D734086F768A01DFCC9
+:103A1000040D1F8B77B4CB64604FF895B6B4CB9D83
+:103A2000B6307869395681EF1B3DF9B50C78FF64E3
+:103A3000AF4052B37A8EAFD97400ED188013E29183
+:103A4000E3A91B6F3DF0E59BB03B1FFB2920B72F7F
+:103A500084AF77B85EA574FDF46EBA8F9A3F585C58
+:103A600000879AA76F8A85F39C90EA197D3FB22A56
+:103A700005F2DD6ACC9E14054BD65EF3E8CD48779F
+:103A80000B0EDF9CC2F20FD5349EE79106E79CBF78
+:103A9000710A9EB39AB891FE6A1E11AB201FE62BE5
+:103AA000898CDE11863F6EE3FC716233452E3DE763
+:103AB0000990973ABF477BBFF9E6EE7808BB8FFCC9
+:103AC0008ADF4756F53219F44B37DD6E598D72F5A2
+:103AD000D30C3515EE29291C34398AF2553C5C9EED
+:103AE000CAF0C4E4318EA3F4570AEDD0BFC38CF7FB
+:103AF000C3BA715C7EB2F597F3F5E9BEA3C11E3976
+:103B00009112FEBDA0C77B09DAFE3A888ECE747C86
+:103B1000CEF87ECB5AC6E71ADF7BAF1E0DCFBF7C37
+:103B20009BF1118C037D44F7E54BC5E7ED930594BC
+:103B30000B16E20BC7DF5BCC9CBF8DCFA9C58EF601
+:103B40009C462774FF127C972C482F749D04C40355
+:103B5000DA2BD50FD0F13A3BBB0ED6C57E72B03D05
+:103B60002BC8C70BB83CB8B91795079705E501D91D
+:103B7000987C51F1812566EFE33F07FEA5FCEA71D1
+:103B800002FF9AF1FD9BCFB6EF3F721DA5F3CF5A0E
+:103B900034BE35CAD350BEADD97933C60943F9F620
+:103BA000B3F47A12966FD3F9FB73A17C9BDEF91FF5
+:103BB00095A71AFC1E09811F958FBFDCED8C0CC7E1
+:103BC00050F938AC9733AC7CA47F6F93829E74A875
+:103BD000D19F46778B7EBDB40FC8A16EFAD4E8AFF3
+:103BE0009B3E35FA0B3DAF117EA1CFAB21E9496772
+:103BF0003F98EF221E3BC5B77F8F88DF4DEA72FAF0
+:103C000063210EB42A8ACC023BBC4BE1F57856F70F
+:103C100027CB4D2027B4767F148BAB7555F963E322
+:103C200075F6F5B1363116E2BC9DDEF0DF79C3CC16
+:103C300044BA7E6784EFC0697189AEE8D841B85E46
+:103C400074A617F0552EDA326F81FCD16611BFE7EA
+:103C5000336FE5B5B19027D2D5D677E234DA3EFF9F
+:103C600015FE393F8F2AA55138CFE5783F493C0FE3
+:103C700015D1F3CD6D63F6F3BC0DE1E944BB3FAF65
+:103C8000B62D97411E51BBF5437DFC6811FFDE4206
+:103C9000CDC690F6B671484F8B42E8C9CDFDA3134F
+:103CA000BDB87E1E4C0673FFC4A4CF0B2917732723
+:103CB000C23B1E5D8744CCBB3EDB26922638E776AE
+:103CC000C14B80BF3DC94897B5547EE8E3C0A7808B
+:103CD000EECEF33EDDA9DFFE77C1EDB4CB9267DF18
+:103CE0001FF40B5A9E7AF6BD4B5E80FA734733DFA2
+:103CF000273DFB97EEFD6626C8FFAEBD1682719587
+:103D0000BD2F67DE0EF5DD16CC3FEABACBC2E2C1AD
+:103D10007BED984FD795C1DE8B69D8F3F520CCDFCA
+:103D2000268D88B784DECCEF38DBF6B73FE27BB672
+:103D30006DF454A06FF7C6A03D5EB73BCA0B4E6A48
+:103D4000D79EAF0BF4F718DFF73CB5328BE377D98A
+:103D5000C934887F75C5B33C9BBA17863DB692AE11
+:103D6000BFB4B55D86F7774A5FFCFB2090375D3BBB
+:103D7000991D71DADCF928711192D1FB8EBBCD143B
+:103D80005FA7C1B6A3BCF27CEF3DE3E19EA3275C35
+:103D9000181CBA281CE05C142E35202723C123BF31
+:103DA00037FB4ECF0F0F1E6766C2FA4BDAAEC07BF1
+:103DB00088205C0495B5DBBD5601CFCFDAF77E3D98
+:103DC00008E4F1672D2B51BF5FE8DCD7FC60E9E028
+:103DD0009F3DB7E0BB98732FFBC19E9BD17F00F442
+:103DE00053724F3EE849E7CFFD18EB4FDB5DB8DF7C
+:103DF0008BE4FFFBFF5FA3F79D02E6B15C08EF3B9E
+:103E0000FED7E2FD158E77BB02F9125D7BFE9E495F
+:103E100074E7BFD0B93B7EB0F83EFFB9353BA8C3CD
+:103E200054AFE4D3FDBD479AA764D1F22DF58B249E
+:103E3000705B2D91EE6BD2995F611158FE3799221C
+:103E400068F1A50E43FE537A0DDA1B13D4BBD97764
+:103E50009AA4FA0EC83FED2899EB5A873DF2F0BBC1
+:103E6000021D9347F2BAD1DF7A5320AA40EDDB0955
+:103E700025E30E81BD375115D11EA425DA81EF64EB
+:103E800056B0F642A39F313DC43FB8769AF1F9147B
+:103E90003EDF54B24CC9A7F09A9A2E295E0AA2E9D5
+:103EA000C5F56638CFF41B04D2AC8B6F4E0999EF81
+:103EB0000308A0E9ECC8EF0ABFBC74E6775A846532
+:103EC000080F522CF2F78D2E003FC2E0DD31793021
+:103ED000CB33965C0C7E5397BA306ECAFD50331FBD
+:103EE0006FB6ADE900BE3513A3FFA9F99191E04C7F
+:103EF000B85F8AF36407E16E5645F44B75F3213CD5
+:103F0000347C7C573C68F8FBBEF890D289E15E5562
+:103F10002B175A672F867B082BE4BDD379276E6059
+:103F2000EF91587305846355A119DFE3FAB3A9AA89
+:103F3000000CE7CA2157D4DEC6A675017C1672387C
+:103F400056937AB43BC9B7E7CE1515E0AD1FDAAD8D
+:103F50000B5542C653BFA4BA48F045D3F32F9088FF
+:103F6000272E0FE2A002F9501F07F51AEBF0776534
+:103F70004A709E0BF58F241FFED5E59FA83CFA9052
+:103F800022FD1894983F4324BDFF38AB8DC1B16E1C
+:103F900089E0CD463AF299F5F7C04F70BAFED31DCD
+:103FA0004350CE15DF3B308EF9B5F998D753C7EDA6
+:103FB000FDB31E671CC473CEB6F58D8378CDD9438F
+:103FC000A5B1E1F2790E73BFF2F72BAC58769509E3
+:103FD000CD621CBE7F3201F570591401B9133A6EDF
+:103FE00075BA1697A997318E4F583E7E353FC70256
+:103FF0003A342E4187B70DE33F9106F5C403FC7DAB
+:10400000A8BB57F9BEF0053F16E07A38AAB322DC08
+:10401000770A7FC6E56AE5BE6F64881F4C6ACBC22B
+:10402000EF4C4E2A33BE0F785F3AF7CF879021B01E
+:10403000AFCA7D636287015E0E89AE280ADFBAB619
+:1040400033B23BCCFD5C283C617E88231F37BBAA82
+:10405000019EC7EF8EC2EF00BCC1EF8B72F9F72152
+:10406000E11342103FDB9CCEEE21BE4E6771F46B34
+:104070002A8BCDC974DDDC566530E497F5E2FDBFCF
+:104080004E77E2F3DE7C9CD6AFD712D6EF98ACD455
+:10409000863B7F4626A39F05C4F5E342E18787B7A9
+:1040A000E27BED3E783FEE6C99C0DF9F09A56B8205
+:1040B000FC7176B4E005FD0B7E2CD62B05D4FF6F8A
+:1040C0006879159398BED4E83E14CE6F71FAD5D6B0
+:1040D000EFE2707F9BD38706670DBEA1FBD5FA5335
+:1040E0007975953EDE3271D7E0A7C13EA96D1314F4
+:1040F000139DAA56EA94810FEB76DD6786FB85E96E
+:10410000FC775A885435487FBFFB75BA84F3EDCFEE
+:104110001B81F6E3171B987DACCE3B130B76D01BAF
+:1041200026D75B23801FDF140DDF370F2DDF5FA144
+:104130002C2A33EBE7CD627ED29262338487AE5F66
+:10414000D26E4ED5D1D3D7908F3534D8DE6B89134C
+:10415000F318E97AB80FCF3D1602F94BB92D1D259A
+:1041600031F4F9F5F5F18C0E6B5ADA65ACB3EF0D5D
+:104170006BEB69EB84F2D3E4CA18437D6E69673A4E
+:10418000C0A5D2E25BEE0A43A7F76774C755BF9B91
+:104190009E5029DD0EFAFF414F9CA908F73DD4D966
+:1041A0001C6E3AFD901A4E3F2C5BE94C05F82FDB54
+:1041B000D337159863D92BE529E1F4C33B2BD8FD00
+:1041C000E1519E7FD93599EA87CB75FA617214D295
+:1041D00047E8B87119DA77552EA01F347CFD87E5C2
+:1041E000CC3BA01FC2F0F5CC0CA37E98DA361BF5B1
+:1041F000C3D4C92271EAE27153322EA41F8A53A696
+:1042000063DDEC8A094337EF70BF04E00A25AC0395
+:104210007AE2EE0C26F743F54524799E7DB1F2FC57
+:104220007F08CE9A3C5F3685BDCFDF930E09CAEB7F
+:1042300065D305FC1D93657B983C5F76038F4B86A9
+:10424000C8D72A90AFF97AF9CAC6D7BA993EA8DB7F
+:1042500095F5D319F4F975CD669795F6BF2E286FAD
+:104260000BF4F2F6EE0C498373A61206BFD366C4B4
+:1042700010A7515EF50339757CF0CBB9CF00DDBFD7
+:10428000C1DE37FB33D7E3AF0F7E391FE2E91FF101
+:10429000795B33185E4EAF208BCA281C4AE7317B0E
+:1042A00078E97611E150DBCAECBCDA6D02BED75B6F
+:1042B00091F70DDE1B2EDEC3EE0DE1BBBEC53A3C11
+:1042C0002E7EA3B3A9373CDF24E0BD67B56B317BFD
+:1042D000FFEF611627B6D2FF205F626D74EC668235
+:1042E000793A2AC69B9772B8555AFC07617CE51348
+:1042F000826B13CA35637C7A69BFB19F807FB078C7
+:104300005B48BB6B2DDE672C85B8B3CE1FF93DE74C
+:1043100093F9A22FF719C80F7C4B0CFBBB675ABF50
+:104320006E38D47C4F381CA670C8FFE7E150D776B2
+:104330001FE6DF7CDFF3BF93C1E3ED79241FF8E5CF
+:10434000CF2615F9DFF3AA88EF17CFBBAF7FAA3EC0
+:104350004FE93887C31B2677531AF4AB65EF212F3B
+:10436000D8B8E300BC223EA3850C86B0FD82878DC1
+:104370007AB25B2FB73A51EFCEA8DF21C077FDE7C5
+:104380008B047F0F6C6E9EC50DF7AF87A3FC28CF03
+:10439000343AB467B2DF8F8BC964EB1EEFE52F436D
+:1043A000BF6297A0209FC07735A04EF100DFD5D81F
+:1043B0003FECEB0A0E778CCFD4ED6278AAA378019C
+:1043C0003EABA0F62EE891EBA9DEC1FBB2B6763388
+:1043D000F4AFA1FD1251EEB8D0DFD5F413DCDF1538
+:1043E000A7E8F0B6E718A3DFAD828B84C15B0EFDB2
+:1043F000EF7C788B842FCD7EB858BC69F0B0671AFB
+:10440000F17738AAA37208DE53B1DF03226DF17889
+:10441000AFF251735FC4636F2E6743E91BEC7DA756
+:104420002EBE74356C1C3F601F857972B86E36B332
+:1044300087F4F225D48FAE231D68D724A7B97F9DBA
+:10444000AECB8B9BCAF357BAEF7583FDE6679CA78B
+:104450001F7194E0FD8F96570BBF2085F960BCBE9D
+:104460003FA3E0E80C7ADE2FD688F89EF2B526E767
+:104470009122E0E375660274F9C5EB6695D9A13126
+:10448000288767BF71DC0CA191D9905F40FBCDBE3E
+:1044900093C9DBE330196DFB03D5632A7CBF84B479
+:1044A0000C85FCFDC9AEF672C8DF9E927F7815DCE4
+:1044B000D35D53AA1C3902F05D2B1280EF876B4A43
+:1044C000D15FB9E94601E9FADD15F89B5864CAE401
+:1044D000AC2347E8BA37AC49C67BB619EA8172A06B
+:1044E000B7B913ED36B8A71B972306F37B09BC0FAA
+:1044F000D5B10AE4F78CFA1BA7C07E6BA85E80B822
+:104500006B4DDBE1F254A86F14F0F7D4EA3C6E195E
+:104510005E85EA78F88C0CF18F6ADA0FD053B79188
+:10452000F5ABDB22E07B3ED5543EC0F9AAB70804C8
+:104530005E28E9A0F69F95CDEB850F34756CA4E35A
+:10454000697D018C8779B7C4E3EFDED5BDCEDE137C
+:10455000AA2E5C7910E453351D471F938E2D37E248
+:104560007C0B370A0452836B0AB3EE2984F95E3759
+:10457000E3F7418EB6FF4C867DCFA4EBA5D1F9E7DA
+:104580008A9DE5986F7DBBA0E07B4D65B7211F74C8
+:10459000713E2049B7B2FB6681D7B95DA8E9C7C7AC
+:1045A00032B391BEAB6F59D904E7EAF42467814B6B
+:1045B00054B7EB8C0C76DE472BE00334146F3C0FC2
+:1045C0006EBFE7B8DCA99353BECCBE488FF3761517
+:1045D000239FCF2755782FEE5EC9F4F2B155515E77
+:1045E00001EC11B3827A73FFAA1F3D04E73FFD94EB
+:1045F00019EF4B4F6774627CF6C446337E3FA4616B
+:10460000A38872E4C4761617121F99529106F0A37C
+:104610007200E86EFFC65219E4E109AF80E34B1F58
+:10462000B93985C57D8DF2A3DAB908E5C523514CAA
+:104630003E2C7838FCFD6A4479B1BC82C9F7107908
+:10464000B034BD09E37EA172A28ED834F99007F58B
+:104650000E5F1AD26FEDEB6602F65DADA4CC7C184E
+:10466000E8664614DC2453BEF01D00F9F685577049
+:104670007AE8F3EB673D3F14E0F731C01BF8624383
+:1046800022DEAF567B67235CB57CC4050F1BE9595E
+:10469000CB7B9AEE1683EFFBD0FF5D5F1343545D37
+:1046A000BFA37752BAA4EBCDDA2578E13B4847EFB8
+:1046B0003C76F0E67CAC2B4087B5B770BDBAC18EB6
+:1046C000747BF4D633AB802E67DE21E0FE89C7DD34
+:1046D000047AA5F661C10971CD0577B0F10BE878D0
+:1046E000A097A33F63F443E9D809745EBBF1BE838E
+:1046F000D87F8BE084F98F6E9A8D7AB8C623127CAE
+:10470000BEE518DACB541F60DED07E8F9802745E4F
+:10471000DB685100AF1ABD68F4778C7F879A585DCB
+:1047200083AEA1E36ECC7486A53B715A16D257DDD9
+:104730007633D24B9D87D1D3B1A744A4C3FDABAE92
+:10474000AD00FA39BD5588407F94BEF283F4253E12
+:1047500062C6F10B9E64F185FD1B195D9F6865F6CD
+:1047600069E923FDD1AF59F08699B0F803B1E9EDBD
+:104770008F0BD16128DDF5D04B9C0E23D19DDBDC66
+:104780003215F20F663F4DF7EF0CC2ABB4E9568C11
+:104790000394364DC7F36AFC532DB1BC8D79CD2BF4
+:1047A000593EA3C4F27BBEF3BE42F6715F503FE6B2
+:1047B000817E84FC131FDDC7CBDB1F433BE0F35F2F
+:1047C0001DC3FCC6C52F50FCD3FEA7B7DB890FED78
+:1047D0006C2FCA9945AD22E69712C957708DEE7DB0
+:1047E0000D2D2F63F16FEC08F7453B2DDE4A3A7E25
+:1047F000D1B3C707E13DF95DCC4EF5FC8A7D6F86EC
+:10480000783A075D03F99912CB0F09D5BFD17D58CE
+:104810001CE7D4F331F85D26615B3BDE332D6AB9CA
+:10482000D66CD1C52D853E66AD1FDEDF7828FEE152
+:104830007E11F6A7FF5D092D2FE4D4938C7F16ED32
+:1048400032A37DB468DB268CF7D56D3B83F9B3A525
+:10485000BF792A16E050B74B34E64F6D137D16CC66
+:10486000F3128F59D8F7390C794CB5ADECFD8EDACF
+:10487000169E2714923FB3F8377B9EF550D02C7EBE
+:10488000E68958E0A74F3BB6C6023CE97C987F34E6
+:10489000B130427ED285F2925AD6F2BCA4F1F87BB6
+:1048A0001DA179499FC23FA81E77F531E679926D27
+:1048B0004C6E51EC17847B1F49B35F163FF5D5A3AF
+:1048C00090477B6AE7678FC2FE97FCE38B4721AF77
+:1048D00083EC8D52C09EA8FBD53B987FA88D1BDB37
+:1048E00087FB474F3E81F99BA7DFB3A05D787ACF66
+:1048F000894CB0174EEFF82605F23297EF29C7F82A
+:10490000C4F2DF96E27BA291FC4DA04FEF45E48F0D
+:1049100086E2637FABE8B3D17D7EFEAE05F9BF3B97
+:10492000CFAC6529CBDF73F2FCB2EDE1F374B57C5B
+:10493000A8DAD66B268E0479D7CAF47A777ED48526
+:10494000F2CADEA678BDFC22F0B79DE70FB68C0F49
+:104950009B57F639FC83E2A9A68F31AFECABD6F9B1
+:10496000BFFC393C6B0DFFBEB6C6D717829B9607BE
+:104970003CB48F7A531FE08F9DBFC63C3EC05BA501
+:1049800013F4FF579910DF3C69F663DCD0BFC7A270
+:1049900040BED7A23D47915F4EFFF630E6D9129E4A
+:1049A0008F7B9A74FFB1BC491EBBA8DB6267F968B4
+:1049B0001CFE90AFE68CC5769E97C6E858CB578B09
+:1049C00094A7F6649F6C665FF3FCE4A5CE0E59B124
+:1049D00005F105F8110A015FC70CF97FDAB943E761
+:1049E00053000E57E8F32F23E503723BBD07BE9833
+:1049F0005C3EBD89E76376E75912929E07F9414C08
+:104A00001FD67985A3E1F0ABE55F6E09C1AF76BE35
+:104A1000487CA1F1E785F7FDCFC1E5A13EEC7D0023
+:104A20000D3EA7BE0D2FA75FE4FC4EFD96BD7D7425
+:104A3000EFBDCCE27E8B9677A6EDB7A985E9E5536D
+:104A4000DB98DD18CADFB5117E57EB0DBE4EEDAE1B
+:104A5000F64120874EED7B9ED39D97BF87734CF622
+:104A600070B9EDD5CBED08BF6376B40FF317A9BFCE
+:104A70001B76BEBAED67C2CEF7A9A45E0BFBFFB4EE
+:104A800083D9219FB688617F0FA1BD8FF17DD52687
+:104A9000BB8C7E97181B8DF268B9BDF05DF8BEDB4C
+:104AA00072BB8CF90E0D2B797EC49D2EFC3D8F06BA
+:104AB000FB58FC1D8855001F9D1F6A56DCF8FB1330
+:104AC0006647553EF857A1EF77CA4926E2D5E35F1E
+:104AD000F2A4E3F7BBB2BF9640EF74AC30BE37D25E
+:104AE00021290712E97C1D65820BECDD9E74669C12
+:104AF000FF6A5534C4CF20560DE73AEB62DF45B369
+:104B00009B7C0AED42EC511D0E74F49CEC77ABE1FA
+:104B1000E7BAE03E7CDD0A6B3F788FEBFF022FB6F1
+:104B2000D5840080000000001F8B080000000000FA
+:104B3000000BB57D097C54D5B9F8B973EF4C26CB81
+:104B400024936560202C37FB1E261012D058261B9C
+:104B50000609382255D480376C610B89686D6CFD6D
+:104B600097613145E5B5A12E50A5CF01C1C7A3F886
+:104B70001A166BAC510708142DDAD0E293FA571BC2
+:104B8000942A28981194F25A2CFFF37DE79CCCDCF0
+:104B90009B0984BEFEA3FEAEE7DEB37EFBF79DEF6E
+:104BA0009C89252E89C884D85C8AB7279BE0DF15AD
+:104BB000FA5F1CA1652B2FA7E0E3787A092131EC7D
+:104BC00015FD6EDF6F920889CA26D94A3121761207
+:104BD000E59269F98958F761299690F536AD96D036
+:104BE000E715F89BD4FF495CCA2918CF4AFFB99250
+:104BF0004AFB9B40CBD6E0F8F16E7D3991849471ED
+:104C00003E6E4286C07BFAA7123259A633A3F388C0
+:104C1000AF36F92224FC5E9B312438DF780771F926
+:104C2000E1FBB4189797D68F8961F313F3A5F3F9D5
+:104C300018E6A3D27F703EF93D5E13C1797D1C3A20
+:104C40000FFA27796C38BF8F0DF3FB38747E05AAF5
+:104C50002DE9D3685A50887285C237C6DA4D389C20
+:104C6000CF87C299102F514A009E02AEF43BED2728
+:104C7000457A52B922015CED1249C3F10CED46D8D8
+:104C8000B17F28D37EC7C09A271252E694DCA7C60C
+:104C9000D1FFEF4C22641821A92D95E4135A96DA1E
+:104CA00008C2277D3DF145D0F9A5074C58266BA3D6
+:104CB0007C19B46D84957823C7D27A0AF19AC742D9
+:104CC000AF3E42C62370579B6857CA3A421EA3EDB7
+:104CD0003A0315A60514A8EDF089F63F51754F511A
+:104CE00069BDD6DB34A7A9089693D7D65546081DCB
+:104CF0002E477211625A95DB7D6424214950FF06CC
+:104D0000F89EDBED8EC1EFAC4C889FD075B545F5B4
+:104D100095DD56272DA7B2F29DBEDCB675B4BF0F48
+:104D2000D23D77AA0EFACE6ACF05F8137F02AE778E
+:104D300040FAA270258EE03CB3B7F92BA3E8246EAD
+:104D400009508052FC67D03EBAF3013FDD16209235
+:104D5000ED31A2ECB710FAF4EC3B66E9A1CFC6F650
+:104D600063F8DD0465FA1C9DE8AF4CA6EB7C50BDF2
+:104D7000D1E3CCA1FDEDAB779AEC84AC546FEC564B
+:104D80001CA17098A48383B2FA26031C6EBA2E3835
+:104D9000ACF4DD847018ECBACFA99E1F015EA69614
+:104DA0009B8844072D3D11E393181F477A0A82FD23
+:104DB0006C319145ED31E1FA59C5F0CFEB093A1A62
+:104DC000884ED2883D17E8D4482F747D35ED148E77
+:104DD00053B57A4F5562904E895D1B37A300E63973
+:104DE000F74998A718776AF90A3995CEE7498A23CF
+:104DF000E8D7D1E28DCCA474EA709B5CC0E7E7549D
+:104E0000EDE7503F7656C06FA6554A8976BF941697
+:104E1000EC5FD07DEB6B32D2776BBDC9B71AE54141
+:104E20008F04EB0EE2BDC780F700C37BC749C4FB0C
+:104E3000F2CE930CEF1DAB2AA28AA12CD923545891
+:104E40004FA008F0F92BDF9D1E85E2737474A01546
+:104E5000E8C14CBEEBA9CD41B8BF0874DA0FEE7CB7
+:104E60005E02FE03E1ADED48EAE3F9B4AAF7A8C992
+:104E700095A106E125EA1D572D586F63AAF61B1868
+:104E8000A76942CF61BA52B2E7C81F62353ADFD88C
+:104E9000A333F643FBD89914136A70DCB6A3AB2B8B
+:104EA00080FEDB80FE51CE04BCF698ABC183F14599
+:104EB0001F3CF69D44F898A04CDFEFB430BA29EBC4
+:104EC00090DC3EE08B6872AF873EDF564D38BF9373
+:104ED000AACC9F12C3E3D103B24ADB97AD35617D03
+:104EE000073CF343D7BF16EB9D54152E77183C04AF
+:104EF0005E051D51C289BE8DCE797896F63EAC3FD7
+:104F0000483709D1A9F47B69D7DCFB496AB0DD4F8A
+:104F10005612CF7C73B01EA59F9775F456608E0411
+:104F2000B8F5D10FA54B902F46FCD076A7193F2599
+:104F300044ABB4FEEEAE15B2963F78BC9644906694
+:104F4000987F493469DE43DB97C4D127941379797C
+:104F5000282F27F3E768FE3E8F95D33E7099245A99
+:104F6000DE0270073CA498189C147B2EF0912985D2
+:104F7000C1B9CC198DF25FF0AB42C11997006A88B4
+:104F800078E1991A4835011E05FF2A0193DF46F59D
+:104F90005FAAA29A5CF4FD5B2B354F55C6C0F2E5C3
+:104FA000961CD9E30B232FE25218DEA980F69ECA85
+:104FB00006ED2C91382081615A5C0A9D57A3B5E714
+:104FC0002733E8D7E539172C809FD5D1CB6FD4F2A2
+:104FD000071EC7388FB72EFF361AE8ABF352444D81
+:104FE00038795503EBA7E31F59390BDB3D1A155BE5
+:104FF000C8952ADA2DDF41D1449FE94B6A4921E067
+:10500000C3AB2480FE8B965CDB09E285E9C3A12952
+:10501000BEED29801F5F2D96F3D2C87609F0A4ADAE
+:10502000B141594EC1FA1472C23E92AE4460DFAA39
+:1050300042ED0D44792AE0B3F9A00D847D04ADAFB3
+:10504000C27BBD3D45E7B7958C017CB7552540BD7A
+:1050500038DEEF2566E708BBA83AFD963312CC7719
+:10506000B45701B94AD252703EE5C4ACB38F4AB2CC
+:1050700028C8617E59B93EF85E69357CE77454DD15
+:10508000CF8E6A73CDA0F43E359BD23F7F7F81FEE9
+:10509000373A82DC7B5B7E50BE4F51EFF254E9EC35
+:1050A0008F3617F0E1EFBE9591EF8DF8D8CAE9F190
+:1050B000C84A8FA78AF2DFAF22293EE87A2B5469CB
+:1050C000AD4DBD36FC8C7833C2EF3B9D0BD17E33AA
+:1050D000C2ABFC03575582DA1F3E467808F8D3F579
+:1050E000AD07B85567CBA8AF04BCFBC389D1C3EFEC
+:1050F00072683D89D10FC38744905E04FDC4A52129
+:10510000FC4B80F6E07B740A968DF035C293CA01A1
+:1051100037D6E7F83B0C70CB80AFEEDAEA214138A6
+:1051200050BAEA8A0FA12B01877E72238B9739DE52
+:1051300085BD5CCDFBA1F632DAC3950E9B0BC05F3B
+:10514000D9C8E65B9911B3D59B82F8DA8AFCE3A74C
+:105150001829C17FD9DF2566E752BB94D167E7E400
+:1051600033603F8F8ED0D6027F04A478B29520FCA6
+:105170003F36C05F57AE36D8CB4678FC0AFE676232
+:105180007FB809BAFB790AB5AFF36871381901F62F
+:105190006FE12BC57120C7496702CA63233D969E04
+:1051A000F0F4F5C3E917E953225ADF7B3BB5233A04
+:1051B000B21F7902CC9A1BAD6D32D0E18DC4BDE631
+:1051C0009415D62FE33CC5BCFEEEF4EC4CA1F26680
+:1051D000624FCD9A53A17CC1C717F0BE89C3FB268D
+:1051E000E2DD2FC7C253F9BACF8E0FE96F6F0AF70E
+:1051F00017924932ACC79EA232F9CEFB13EB1B9D2E
+:1052000046FC12C2D9EADB2AC1FC89D792101CCF16
+:10521000CCD1949131E3B51494C7CD04ED656A5EA9
+:105220000212CBF8F7326B8C1FE64302CAD93E3C20
+:1052300020DFD5D901AE142EE44A74707EBF4B91A5
+:10524000944FB383F33BB7C3EA95819F8769BF87C8
+:1052500071CE4A470B916F157F26E841E3F70B1D8E
+:105260005DCBE13BADB710EBF1752D05A791D25D9C
+:10527000E0B508DFD694ABD8A156AAC242E44159A2
+:10528000149327D5242083DDD919C9F8F9F5AF1671
+:10529000213FB8897D6D1EEDEFD0F9C947809F2B66
+:1052A000A978817A932EE9FDB66BD1691509CC8175
+:1052B00076D576B3C10FF4A2BE59CBE59AB0D34CE4
+:1052C000A9DAB9147C3FCA077AA6F3ABC92AE06D04
+:1052D0006BF6F85B6EA7555273C6CD00F7CC64ED44
+:1052E0003683FE9BCDE96B02D097845690A0AF8B9E
+:1052F000D04FDA3A037DD913747EDD2DC48FEB2FA6
+:10530000CB36FF4D373F6E9718EDF5A09DDE16D6D4
+:10531000BF235D0AC9A6709EC3E1BC36DEE205B9B3
+:10532000A6DC27F9480ACC978C5A45E739BBD9AC9B
+:10533000F347E7C42B88C739AB227D84F9DFCE7AE7
+:105340005AD6E8FBC7A098ED7686DA55A425A43D89
+:10535000D0438C8AF43BC7CEDE7D44FB189600FD1B
+:105360009E72A013EF359F0FA553E3F803F66B6809
+:10537000B75622B3C07E5A6B763B5D21F6C7A85460
+:1053800066BF9CB7576D32A50E6C9768D664B7920E
+:10539000182CF7C45B67F9C2D831A23F4127651AC0
+:1053A000F3CB07EA373D50857699E949BF0CF6768D
+:1053B0007A80A07D5C16709BE6E9EC74E69FF6B3FC
+:1053C000D3DBF7A39DBE6CDF7E66A7B7AF427B7FC2
+:1053D00019B5F741BE53BB1164259B503EDAEF7DF2
+:1053E0007E26E52D52D62EF5F9A10A45455A1BAB6E
+:1053F0007FF7D6ECF847D3C14FD49C66EAF7DC9D23
+:105400005AB0C14AFD9ED6141249A8DF332BB5E02D
+:10541000B6F513283525B825128FE50D311307EFA2
+:10542000D7DE9D9ABF01FCDA81FCCBEA54F5AAFED7
+:10543000E507E99EBB5343E202543E86B54732324C
+:105440002AE6403D2137CAA2187F3E6AF2A7FD1422
+:10545000FCADB76402FAF4969679E8074C6B59EC08
+:10546000A9A2F3E93D70399398405E32BC37A63269
+:10547000BBA6299AD9974DD1B41F2A6FDE746A8DC5
+:10548000D07F77F6F3EBC7527EA9EB905DE02F4615
+:10549000665D1E05FC3F6DFCF34F8EA5E37C185046
+:1054A00030FED069A37448DF7F4824B467CB8E45B3
+:1054B00078F651BC7CDF59DE961AE29F7CDF598575
+:1054C00065524B1D2BCA1F2BAC8C2F3F24FBD37E68
+:1054D0004AC7F1364B68079C6F4E89033AE834D3CC
+:1054E000F587D0E3EA5405E96F35A7C7BA4B320612
+:1054F000CD3ACDFEE4665ABF4EF19BC10FACBB6402
+:10550000C1F7300F984F67A4BE9FC7793F8FF7F55B
+:1055100043E1300EEA19FB51D87B89ADCF8887D3A0
+:1055200029953F85F57CDFE96E43BC51F905FAA268
+:10553000ACB8EB04D811D7D64B6E09F452D365C979
+:105540003F9AC2F3EC3E33FAF767C13FA4E39DDB19
+:105550007770C85CFA6CDCFDC758F007B7707C9DAB
+:1055600053BA63617ECB5EA2FE0BDA43FE21F76085
+:10557000FB79258FB161ACA1FA7AECB707933D2C8A
+:1055800078A8427C4ED8A53759BD3E985FE72A19C6
+:10559000E508D5E7226E2A81FC9EB44F7647C6F611
+:1055A000B7575F4E350B796B023DF6809D8D33907A
+:1055B0003C28BB94487C21F2A24CF1CB30FFB24B8B
+:1055C00043F0FDB923A94FD402DD12B30BCD4485BE
+:1055D00074A1BD2C11F1D7954ED7F33A2FBCB1EF82
+:1055E000C2ED37223352BD48EB7CC7AF25A1FD0C7D
+:1055F00021D292A05D38E9923EEE6AB4A3859EADB9
+:10560000E82C5A9B4C00EEEAED37021D1E51907FAC
+:105610008C76767560F200F6F406A4A33DFBD2A268
+:10562000212EB091F379D3BE0B93413E2D27FE3B43
+:105630006E4C82B8836CF793ABC5BBD6FE6E121D61
+:10564000FF8D80A2823C7823D0652DC4B209E31C73
+:10565000656F97E501FF7606941AF05BCBBEEA8A88
+:105660009E971FB46B3A2F9BF0FD1B970FE07BD1E9
+:105670006F6720210FF4F36E13F3B7BB0EFF2D1AE3
+:10568000E4EB1B97CF27A2DF2FEC92FE7635FA01D1
+:105690009536B92F0E1D6ABF13B9ECB815FC8D38BD
+:1056A0003391110FCC1FED67977C40D6DA487FFB12
+:1056B00044C01FC812F8A69F5D1D84B7CEBEBE921F
+:1056C000CAEDE59164EC15B0732F272E057DDDDB67
+:1056D000196D5F8DF1296657F4767DFEB3A9F0FE52
+:1056E000A88CF1B6DECB32F2D581D7978EEE890940
+:1056F000857B2BE2EFE2B0AFBE7C95D6BF78280A5F
+:10570000E3EA4471E5858B9F04E3C9FEE126273C6B
+:10571000BDC34D1390ED305EF09D60BCC09186F12D
+:1057200082C0645057999B4F5A20DEB231D5333432
+:105730000DDBB747C3BA174531F9E42515C9D4784D
+:10574000222F1D315500BD14AF5211EF3BCDD4C4F3
+:1057500002FED8CEFCFB9D54DE825FB4B8BDCD9274
+:105760001282E7C51441B0BED366EFA88490F73B20
+:10577000D2583CE1F4A125CF019CBC7F8A2019615D
+:10578000ECD387D2983CDC6BF14EDD05F53E36114B
+:1057900018AFEBF06F0E0FA7785E7C422D023D3004
+:1057A0002B4DC57A1D4777B60EA7F53A3E00ED4959
+:1057B0004DF26DF5B2898EFB2A5159DCEFB809E73D
+:1057C000DB172725EE4458EF1D694C8EBD7A84D136
+:1057D000AB18FFD528A6EF26A731F95296C6E26E80
+:1057E0007B8E5424CE45BED22601DC9A4EF5B4C63B
+:1057F000AAC138A1B00F271EDF33B580FEEFC4B3B6
+:10580000263BA04F3DBE5586F5AAA7098997FAC742
+:10581000B1687F53D21CC1FE5E3DCBFAA3F33800C2
+:105820007C175845EC5B91EA3C8FE7D3F2ABDD4A3D
+:10583000C2632AE203F581C083588F9887DA4EDC71
+:105840005B629045DC7BAE168FA67E27F0DB382EA0
+:105850003FDF4D75DF95C6ECAC514077A70F45A1F2
+:105860003DB697C7B589B37E34C04FE0E97BFC698C
+:105870009CCF40E337733A10CF9D66D58BF4F0127E
+:10588000D3BB3B6D7E6B1AC8BF57D2B0AC7ABDD1CB
+:1058900085F47B5347864B56919E9B19DD323ABF68
+:1058A00089D3B9DA1EB0A484E06160F9C6E0DE47AE
+:1058B0003F4A3BD255C70982FCB664C77D2C0E49CE
+:1058C000FCC98C9FBCC9C05FC0178CCFFCC324F639
+:1058D0008C053E99D8B9654D326DD700749F1F84F1
+:1058E000830A7C017C26D6696376F2CF78597C6F77
+:1058F0004B6371C76A393FAEE72AF1BB37563A8925
+:105900001212BFFB199FFF62B201EDD3C597DBD026
+:105910006E559BD973F103EC99B9B9DE02FA60F1C7
+:1059200026C91DCEAEB673FC9DE37C404C51C389A5
+:1059300033F8DDC1F9E0CCBE270EC23A29BD3E07DF
+:10594000F0BFA163C3D3002641FF67B699B1BD90F4
+:1059500023A2FD36DEFF4BC719FF4CDC66AEB89BB9
+:10596000C27BA297D8219EFEEAB6ED32C8F75781D6
+:105970003F5298DC00BD7CFAD063D13F003A3869D1
+:105980002210B7DF6B218B7687E0B76BCBCB3A79F0
+:10599000B064C7AAA9D04F694F82047A40C8018178
+:1059A000EFBD16D7149427D30DF2A48AB53F06F0A5
+:1059B000A4EB7A82CB93276AA83CA1AFE2B7C54B90
+:1059C000D0CF5E1E2736C2AF8BE353D0E38D41B9F3
+:1059D000DBC5E46E4F2C74BD7CDA798CD3F68DC3B5
+:1059E000E9EE892A41772912C091DAF9A67458376D
+:1059F000850FD03FB5F3EF9D918F5C7A44C1FD21B7
+:105A0000BEDF44560BFB47C7BF42CEBD9BAA1D87D6
+:105A1000F14BAA9AD780FF9158EB45BA3E2369A370
+:105A200013A8BE3A037C1D462EBCCAE5C845B33652
+:105A3000DA1EE67B908FC870E083454433C13AC8D4
+:105A400066C90E7015DFD5CD8CDE3EE7F011EF3F55
+:105A500037C06B12C02B0DE1F539D753162B9D6F54
+:105A6000A68FE9292255203D12D32DC381DFCE9880
+:105A700009D2CF192A17016E8BA3F4FE8958D737A4
+:105A80009CAF2EC6B375ECE5E3FE097C9EF1580F82
+:105A9000ED0A6FB909F76B813E90DEA627A0DD45C0
+:105AA0001D2605F9BC6F3FC22F4B4C1EC8300F3B63
+:105AB000F8751827DA82FD2EDDB505E926BEC65E2B
+:105AC00004FB474F28AEC8F890786FD7F68DE84FA3
+:105AD000023D015F0E448F8B801E49183AF4513A03
+:105AE000A4ED126A9A118F14BFF674DA6F7C9526B2
+:105AF00003DD18F12BF619053CF61AF62567A633D7
+:105B0000F8A4A433FE54B9FC1A584FE8E52DC59704
+:105B10009AEED0D337E04DF05B4C3A934F03D1F976
+:105B200043E976ECB7F5C3794E9017623F4AEC2F04
+:105B30008BF1C7A6337A1C683FE99CAA15A51BF612
+:105B40003BD5FC209F5473FB71C5F608DCA7DF0D25
+:105B50005F00EE5D51B82FD1270715E2067C96A7AE
+:105B6000A7E07802BF6A8B85A4D3712FA6D477C52E
+:105B7000D04F37777B6B0BE83A765BBC33A7A1DD60
+:105B8000ED9A02FD4FA935D9218E1DEFB64B1007B6
+:105B9000411207BE38CAC621AA4B37EFA91CEE0234
+:105BA0004F020E03E9AB81F0F310878F837F37F24A
+:105BB0007506FF6E4E67F47F6DBEF6CA40F7B144BE
+:105BC0005B2DC3FCCB981CEAE3EB3282FB8D0BD23E
+:105BD000F57C2DCA61F87A417A285F4FE8D1F33518
+:105BE000B570B93E45FE726C33BB993FC9F8EC62A3
+:105BF000249BEF8A74A6871CA03F28FE1C5EB6EF8C
+:105C00003A95D319A5A03900EFB66D11B89F20F8C9
+:105C10003E7626A930C3FE2DE81BA835533B7113F1
+:105C2000ECDB3A2D2AEC239F3107104F67A8A3DA4B
+:105C300086F8F4603ECA994337307930AD4FFFB8EB
+:105C40004D507E7F04EE2754CB9D48D72BAA09EAFE
+:105C50008FAEEDA548078B6A5325A0B3253BE225FF
+:105C6000F89E506537C92172B1B445467AA274BB1B
+:105C70002E3D047EA5DE6619E0323A51739AE3A9FF
+:105C80009EDD367546685CE8495A5EEF0CC685684D
+:105C9000F96731C3061F17DA987ECBCFD68DA04A9D
+:105CA00024CDFD148C7B4EF56C04BC94243763BC6E
+:105CB00073B079104D3CAEF4C1236F6DAFA7EBAE5E
+:105CC0007B34F0087CBD17E2AED9903FC0E2AE4D08
+:105CD0009DC7301EDBC9F9F9EF4ECF0B30EEECE675
+:105CE00029FAF86B6070E32671BE251F10847F923D
+:105CF000A75986B884900BFBD21384FF28C1FE9B62
+:105D0000E007902B607F8A3C088887D9128272193D
+:105D1000CA71217A757D2DB583C2F0D9C1F498B0CE
+:105D2000729074FEFDD73FA0FE7E137C6272F1601C
+:105D30007A88DE7FA2F6E3211A8B7B60BCE97EEED7
+:105D4000433EB7DAF5FB2C9043EFC828FF8B222C9B
+:105D50005E09F687DC44B50FE1FD019B744A7E1BAA
+:105D6000F53F9BFE261137C4CFFE26E3F3B91F791A
+:105D70006A52C09FEF30B9A82500F91448C7AED1C8
+:105D8000C467A5F4D7CEF76BCB0FC6B8CDF47DAF03
+:105D90006445F9D7BB3FCA0B7CDD6B33615CB9EB63
+:105DA000B50884EB85F428EE5FFB747EB8D8FF88D5
+:105DB0008CE8F943196DBF3592F5BB3592C5E9B64C
+:105DC0003E9A1907F6E740FBE3652D6918E713F1E2
+:105DD000C7D4806A6249646C1C2540707D62BF7CB8
+:105DE00013E46B140F9CAFF1D7F4BE7C8D00D0533D
+:105DF000D3AC9EC33047A31F36E4E8C7FBA19F2165
+:105E00002D2C4CB0E9E80A09D6B9A92EBC1F26E80A
+:105E100068138F7B85E4457CABD32FF509D1A9218D
+:105E2000F253B47B9AE7459476CDDD0B761EE5EF11
+:105E300073A1FC3DB5E091C870FBF39E961F625CB8
+:105E40007420FAF79888162EEE373A83CB5B25300C
+:105E50001CEDC1372E46A961F2253CAF991C0017F5
+:105E6000119FE93FFE8F70FC61197DFB7FC307B373
+:105E7000FF679C77B7998C0CA757049E8DE38569C3
+:105E80003FDB15D2DE6321DAEE98FEED84DDEB9187
+:105E9000F8FEEE8704F5ABA0130AF77119F47BE165
+:105EA000DBF3C64541C2A1B559067970A1A32B19F0
+:105EB000E25603F987623EF42F235CBC858EE70926
+:105EC000878769194CBF7ACCCC0E95CA0FDD03F3D6
+:105ED000F27C65912242E86C22AF67DCC7ECFCEAF9
+:105EE000BFC7A19C34FB93C3C1CFB8BF3911829304
+:105EF0004CDFB171395C5ACB49454412C60BC856C8
+:105F000015FC40262FD516827C3E4672E3BAEB2064
+:105F1000E8E2003AEFC63CC80B4765AC57789FEA09
+:105F200003BF89EA85BB017EA544DB6B4A0BC24BEC
+:105F3000D043EB8BD44ED1C5AD18FF08FF75248F2D
+:105F4000FF5055E30EC5DFD059945443E4FE30CDE5
+:105F50004A9490385BF222BBAE3CB2D9A9ABEFF4C5
+:105F6000FA25E02B678BAA7B1F94576CBD23BD6479
+:105F70000BE8FF4DA407D7378ACF678CA4217D5C3F
+:105F800038FA4902C4257FC0F987AEB705D7DBA22E
+:105F90005D08A50FB1DE6BADEB8395743E94EF3FCA
+:105FA00002FF9C3E673F70521A8A70B7833AA07A0C
+:105FB00091B51BF9F031F423473677A31D3FA76550
+:105FC000BF04FA8BCA0D6CB769A5159FCFACB4A3FB
+:105FD0009F2FF03B82D6833C256F05C9867D81814A
+:105FE000F4D3C68C41EBA78D1961F493C91A7813C9
+:105FF000F6C11B3B6515E860CDC30998FFF25CBB99
+:1060000084FB2E073B59FEDF73AD51A847C4B85F30
+:10601000BE1487FB3F5FF27D40D2158FF4DD14CFB5
+:1060200071B2361EF7C97BF93E6447BAF61F1921D3
+:10603000F2E0B9CE6F22417FE4893C5B83DE01410F
+:106040002CD1F6E013011DB7A614AD93615D7768FE
+:10605000E32265E4F7DD8C5E997EFAE5AE0A9316DD
+:10606000829F0B1D5FCF39A0F6DF5F12FB50627F6E
+:10607000EA4DA7F66A4688BC36EE3B19F74BE45862
+:106080002BE669BBE42897ACD7B748876B32983EBC
+:106090005DB33F0AE1B8262306F77BE97C8FC03861
+:1060A0005D360B1946DF5F381183F5C4FCE97C0BC4
+:1060B0008F86996F932930E780A49BEFB1ABCF57C0
+:1060C0009FCF2CE6D7871F1E2F906D0AAEA3974453
+:1060D000B900AFED16D7090DF4EF3B512C7F8AE3E1
+:1060E0006F39E7CD5E8A2F89E2ABB7E34224D0F166
+:1060F000C174ED24CC431E198805FFE560E7851CBB
+:10610000E09781F60D958C8ABF00BE20FF0FF166E7
+:10611000D72EEC228C2FB5ABB4CBC8A8380BF5AF7B
+:10612000033EDF5C0F7C9A949875A1F697C4E5B3A3
+:10613000911EA5CEFDFF03FB01941F311FD53B8AA5
+:10614000F8D650B8B51670BA9C4954169FD1D34BA7
+:1061500047BAC79CE908F2F155E01309F57E99EEBC
+:10616000898627CC23792CCA291B94A95EDB6B492D
+:106170000DDA5BA3D398DC0BC413CC5F31EEF7666A
+:1061800064CC48CAA4704BCD564DF6FCEBE2879127
+:106190009957859F1FE9A291C3A911F619295CC8D7
+:1061A0003EF3595DBE80010E07D33D590C0E413AB6
+:1061B0005BA35E151E790C1E5A21ACC366A6F402C1
+:1061C000409950EFC4BC18D57D37EC7FEE5CC5E03C
+:1061D000D0FB2283C3EE2E13D2F516928BFC996B63
+:1061E0003A3F07FAA7F26702F453DCDD66827CC20D
+:1061F0000C9F6A82B8724E77BBC97475BA2DCB44B6
+:106200007DA14DCA64F6C5FD8087BC5D2C1E73154B
+:10621000BAADCC1C7F5D70AFCD1C3F783944E9CA64
+:10622000134A5783CD4BA2F4419213FAF747480F14
+:10623000C6FDF7BF1281F27EF91E09E5D3F2D73F02
+:106240009B03F05DFE9B0824CAAADF44E2F7F3FB40
+:10625000D8F72FCBC3EF4FDF9599807AB6B1FD3ECB
+:106260004FA87E1776C34FDDE7EDE972709F2F715F
+:106270001A3B6FB22652E49BB2FDBE584E6789238B
+:106280003D6ED05389D52C9E141BB310F7FBFA9F9B
+:106290002B617CEBE0EDEC7615ED07E33913398AE1
+:1062A000E5E539C8FAAF004E8935FAEF8E981ACC79
+:1062B000C77318F6FF04BCBD99DC6EB61027CA5927
+:1062C000C33EBF78FE2593DBEB6BE34DA1F204F4F4
+:1062D00000C07585CD8AEB5EE12089B51057B029E5
+:1062E0002E1CCBD08F78C6BB4D440D3D2F5313458C
+:1062F000D410BBC8E149D09587CE1AAEAB3F4C4B0A
+:10630000D57D4F5E94ABFB3EB279ACAE3CBAE506B0
+:106310005DFD140A80D072DABA5B74F533DA66E890
+:10632000CA599BEED6D5CFF1CDD57DCFDBB144F7A1
+:10633000BDA07D85AE3CA6E307BAFAF200F6B880B0
+:10634000B32CEC715BB1067425DBAC52A8DDF222F4
+:10635000AF571E6B45F83FC2F5F523360BEAEB4706
+:10636000B8BEEE72945C755FE69FF5DFDE16F4C092
+:10637000EDB50A1E2FFBF280C504F4B8FC20A58BF6
+:106380003168AFBD9DC9ECB5E9F5B8FA8005E45EAA
+:10639000F700F920EF65723F43A17E4C187FF09320
+:1063A0004C5517B713FE03956BEF73FDC2FC26D255
+:1063B0002C831C1072A9299AA09DD7146DC73C9FED
+:1063C000DED84B99C04F545E7D0CEDBAB39F683E4A
+:1063D0000072AA3302E5D45BD99FA03F7E4BCB422B
+:1063E0006CFF62A69DE1C5E252ED28A7F4FAF7A87A
+:1063F000B9BB16F07074BC4C56811DE42A1D4AAE20
+:1064000002F777C0DFA676F2B62C82FD5ECB5F3D49
+:10641000BA7211E64D0FD4DFD1A2488C9BD6025D33
+:10642000858C1B9DC5E099C19FD41045BFF3DCAF9F
+:106430006D3E2FF84B63DF8D2536C893F9E3382F77
+:10644000E823D27D3FECDF7BBF8EC1B84E6DD1BB60
+:10645000E35661BEA89BF97D13D89A6F7AF9ED587F
+:10646000F0D76B771F4CF286E0D1E8EF65F0F511BD
+:10647000A52713F34E5F3D3344A5CFDA570E25B160
+:10648000B8923EFFC5E8E7D7B62CD7D167E3A54859
+:106490005D1E4CA3D26D017C345E8AC1F7BD99FAB2
+:1064A00038C080F01A243C8DEF053C8F169D1905ED
+:1064B00071FA2F23C3D3F16DBC9E281BCF2F0C94F0
+:1064C000273F81B7BBE09A3814E24CB5167FFA60DB
+:1064D000E212024E6F5D6EC07311BF1EE05C44514C
+:1064E00016DB37F975F602CC6B9E686DAE04FD3D88
+:1064F00091C73FC3E4355767819D7BE25F93D73CEB
+:106500003D8BE387E70D0FCF52C3E6355FEBDCC968
+:10651000540B954B61F82BB70F7E7F9A398ED2F1D1
+:10652000FDBF30DB615E0DA0F320DEB2C58CF1D77C
+:10653000B72F471088877FB6D9FC3CE4BB2CFAC53F
+:10654000C1114F40FCBB2802F3F11AB69859BCB6F2
+:1065500028D2072187455BBE3704F22EBFA07CBB43
+:106560008CCEABE1170ECC077ABBEBB12180A73301
+:106570009C9F177DFBE33B00FEBB2DF6BC22FA5C23
+:10658000B64BD2E5992FD916A92B8B7C22813F22BD
+:1065900005F3CF552A4F5BB2F4E768C605F7255AD5
+:1065A000B2B85CBD9DCE77F9F80B16C0E3C1C351FC
+:1065B00038EF376264F473FD457FFDDD185AAEFC99
+:1065C00056C1BC7E637E12218874B290E71156BE1C
+:1065D000A2F49D0380B27F6533F2096D17531D92BB
+:1065E0006F5DF973E64F5746B23CE001F3960CF944
+:1065F0004AE29C45BF3CA5E0390B9D9D22E8E6A9F7
+:106600002C3D5F1F3CCCF292161EE576E535E4E6A4
+:106610003BB08E0CC0D75B75B06FF93687C6DB9781
+:106620003F5B3B8C963F9B2041648E7C76393CDF00
+:106630007C26F4129C0FC80EE2679A6B715F19D822
+:10664000F2D609F7E9CE2D0C5EDE5C5D9EDC956529
+:10665000C1F18DF2DD48F7FFBFE47B6DD1A1515E42
+:106660001B3E5F80E7D9DD4C3E1AF9DC28CF730D65
+:10667000723028C7659D1CCFE5722028CF2DF89D6C
+:106680009A69B81E6F89E25B23A1FFF31ED07D7E5D
+:106690008C9A584E9BACB5A7466B57F747FF2FD443
+:1066A000EF4AD13ECAA27C34FA97B955608CE7ED27
+:1066B0006A3301FFF60E608714A41AF282787C48D0
+:1066C0007C3F9B555E00F9AA7B54F614FC594C990B
+:1066D00090EF2F9FCD62FBCB3F01BB67F97F5E44FC
+:1066E000FEDC12A5391558CF708B2B74FF563C2F4A
+:1066F000727E1FF87CAD3EDFF9743A6178CFCED65A
+:10670000EDCF807F8FF90107A2106ECF3ADD9701A0
+:106710000EED4EF7B730AF32A7FB1F59217859CB9A
+:10672000D7A998F4716BF12CCD16F4EF413DBEA0C2
+:1067300022BCFC4DCD6679C1E54FDF350AECCEBFFA
+:10674000ECBF7B14C8C7AEA74AAF6A876EE0FCF9FE
+:106750006F5CEEC7F3B8E34F816F683901E296B41E
+:10676000FD028B27333EA41F73763CDBEF2EFF83A5
+:10677000278DC2E5D47A19E5F7A9181667FC2446D7
+:10678000A9D9C6DB25E9DAB179CA40F7948F951803
+:1067900045775EA21468DA31F03A4BB3991EB51012
+:1067A0009715DA5B0EDC6205FCCA92DBCEF2D219D9
+:1067B0003D4CA423003DFC98CBB1BF3BB5A26C6C13
+:1067C000C7F4ED44AE6F9518837E1D115E9E89E778
+:1067D0004B4E7709F473A7D35D9AED80B817C903C0
+:1067E000BE698F0A9FE77313C7DFDF853D4662D01E
+:1067F0006FC6F164DC577567635CCB5301FDC1BEA6
+:10680000AA59023EB0F3FA6E89C52B3C37C377E232
+:10681000744BD328BC4BFE4CF03CC7DE231512EC66
+:10682000FF2675574920C79238FE8CF3E8E170DBEC
+:10683000C3F325FAF31DF32B6670F8EF513DC85FE3
+:10684000AD299A13FC55C8CB03BC1AF32C7E99CD05
+:10685000F6D5B644F5E0FEA0F76E82F97743CBBCDF
+:1068600012E40F25D7B695538C93F9D9CC9F4FA836
+:10687000D19CE0870F775AF09E8AC1F25B7EBB1BEA
+:10688000E325C51A3BAFBCA9DB1B9949E735A45BDF
+:106890002BB7D0677ACE105CDF50D2BC8AF909AA38
+:1068A0002EBFA958ABC07D7231EF92F9CD6B2C2A67
+:1068B000E6C3ACC80EF16B929779C3E63B19F7B902
+:1068C000D708BEE4F908C53CFFA078DB53984F50C9
+:1068D000BCED66450A91339BB2CDB8FE3387968CEA
+:1068E00086F50F94C7DA96CDF0F0FD6C265F06CAE8
+:1068F0001F5BDF2717FAE58FADCF7684E4D7349E90
+:1069000047F9D798CDE4FCB3905743E1FAEC7C917A
+:1069100057B34582F5EEB5B44FD905F35A6EC23C74
+:10692000A6BEBCA2F92CCFADAF3DE417D1F7CF2E58
+:1069300062F945C37C1B705FE26224CBA3B8B83D0B
+:1069400082C0B9A467B76D1C02E7109FD54C6807D9
+:106950001AE70F0782785EA419F225018F20AF0491
+:10696000FEFAF28F78FE5ED7F69771DE623E9450A3
+:106970002C00F7F41C36AF253B764F01E21FBE2CEE
+:106980004182B89D98D7B5E4FE4B9C2F064B872FCC
+:10699000E430FE08A31F5FCDBE3EFDF806E089EAA5
+:1069A000C703D0EEBAF523D78B424F8AEFDD9C2E7A
+:1069B00066660FA81FBBB3C3E84715F29E31EFC848
+:1069C000E4DA1E065F3378BF37BAB54AE0E7A2348F
+:1069D000ED4FD0CFC409BE8310072DADF11E047E4C
+:1069E0002F96F879EB294C0E24F690FD10838B3FFF
+:1069F000D1E3863CE5AA6C966F71C36937EEB3C7E5
+:106A0000798804EDC53D066D09ECBCB371FC499C69
+:106A10002F4C4F06301F2EA9337C5E6A412AB3D714
+:106A2000A8BC3C0B702D194DE5694A7F791A067F89
+:106A300017A07ECE2EFF01A835363E3D1ACCAAAB5C
+:106A4000E0EFAF0C7FEE4BF014F8CABD22EBE2781A
+:106A5000025F57F8FC6FCD70FF03C639CCF97B207D
+:106A60003CC6E650FC8D07FA66781479C03B0D767B
+:106A70006A450EC3CBE41C7D5C2804DFB139E3FB1F
+:106A8000E35BC8F1BD47F6C880B792AAB635800768
+:106A90008AD7A41CDACF0D65FAFC4F235E853C34FF
+:106AA000E2D78857910748F1313A278CFE12FD183A
+:106AB000F558889CE0FBCE6A5F7E07D8CF224F5CFA
+:106AC000AC43F0CF240E8F1B35ADD2C2E8B410C654
+:106AD0009D38CB77D00C74BAC87BD0124AA78B09EB
+:106AE000DBAFE2F348EEF1E27A869DD0CAE179C3EA
+:106AF000693FDEE331B499AE8704D733B2FB38E6A1
+:106B000063C2BE2CC49BF61E3980F31ED1DDC59E28
+:106B10003C8FC8A86F83F9B7AC9F17B8FC6A3DC714
+:106B2000F2F85ACB99BEBD37C35D99837CECAE8237
+:106B3000F9AFC8705743B92095D14D6C8EFB6628CC
+:106B40008F1C40DFDF9AD3B74F3D1DEA253D40BC87
+:106B5000E21E1488C327412410B6F09BBD9285C263
+:106B600035C94DD0EF1C9DA8AD82BCB7C044E282B0
+:106B70007C80B83A7B39C02B61916B3FC0B3F51C68
+:106B8000BFCFE53E82E7BDFAF2ABB454CCA700FE1E
+:106B90000DE5977A3E8FFA1CC607D4DE9993C3E6BB
+:106BA000A5C1BC84BD23F87220FB2584AF1BA0FDCA
+:106BB00075F0F5F29CEBE3EB15398CAFEF8776D7E8
+:106BC000E2EB1FE4F4F1F543D0EE5A7CFD28E7EB4D
+:106BD00017AEC1D73B78BFFFC5EB87E1EB47C3F1E9
+:106BE000B5CAE94EF0C59E2363A3215F601BEF2F5A
+:106BF000447E6F80F6D792DFFF049F6F867EAF657D
+:106C0000A78A7E05BEAFC527B1B91E8483B0474FA2
+:106C1000A733BC0BBEA7FCF29F007FCA2F3B39BF36
+:106C2000FC92F18B8AF58CFCD5A7EFBA4DFC1E11B6
+:106C30007B7468DCFBCD9C7EFAEEE59C30FA6E241A
+:106C4000E1F0AA61726404F1CAB1D06FAD1DCBF658
+:106C5000B37674F3634F05BC00B7F77298BD513C2F
+:106C6000403CE1779C4F92BA2B50BE50781ECA0927
+:106C7000D16349C43E15FC9CCF73D8BAC64D701F72
+:106C800004B964777B309FDB91CBE022E044DBBF2B
+:106C9000134EEEEE037CE4F7F71B8C7838C8E7FB65
+:106CA00039A71F63FF42FE40FF05D8BF6A82FE4539
+:106CB000FB3F07E5D047B08ED2079A65585712714F
+:106CC0004783FC1172928CA0ED8BFBB7FF34D8FE8A
+:106CD00053584769336D9F1F6C3F92F8315F2761AE
+:106CE00011955304EC7717DAB3EB55CFB91C9C27F9
+:106CF00061F2AADC84F2202BDD8D7C174EFF43FD70
+:106D0000EBD1FFB01ED0FF83911357383D81FE8732
+:106D1000713ECEBA86FECF65EB8ECBBDBA9C88CFD6
+:106D200065FD3A7207D6FFB961E4C41ED58DFC1427
+:106D3000868F12721D10677127423BCA4749501651
+:106D40007A87B61B02EFD7AB0C8EEB6B4DD9685F21
+:106D5000932857387F262D3766B0F945697C9ED732
+:106D600095FFFADC8F7A2C006F91A722C635E6BD1D
+:106D70000A3C2EEF94C6415CAEFCE0658C93F4EEC9
+:106D8000FF1BC649948CB9E360FCAED758BC44E401
+:106D90009588F157703FB25ACE6F8738EDF91D16BE
+:106DA0008C7FCA44DD5846E7D374C44C7C2807D98D
+:106DB000F965B14F6BDED1DA0D71793309B9670727
+:106DC000F59D1A0774693EC2EEBB2149EC7B33B1D5
+:106DD000AE62F730EAF769E3DDFA7DDAC41AFD3E08
+:106DE000AD88232E256C9E0E8F7EDF76E82CFDBEAF
+:106DF000ED304DBF6F9BBC68AC611F57BF6F3BBA96
+:106E0000A5C2B08FABDFB74D5B37C3B08FABDFB779
+:106E1000FD8C343F5D46D79D2BEEFBF1BABBE15CA8
+:106E2000F47C3EDFAC4DFA7DDD2F76D6E07D21F39C
+:106E3000797C3BC7A7DFE75D2A2F433A266DEC9CA0
+:106E40007333FD07E0A690C0E164C83FF0492E3FD0
+:106E5000FDDCB0497F0E7A71C7166CB7D8A77FBF2B
+:106E60007487BEFC402EBF0786C7BDFBD3410CCB49
+:106E700063D8CCE2FDB237CB40077A7CFC6FE942A5
+:106E8000E57411E1D4D345A4AAA78B8637F796C041
+:106E9000BA8DF08DCED6D38B11BE36979E5E045C34
+:106EA000A99EE4F9386E5CEFC20E893C23F587EBAE
+:106EB000A2CE0DAD700EDD0857427CB8EF6C84AFEA
+:106EC000CF00DF73AAF63CF0DF858E07F0BE1FA26D
+:106ED00069E3A0DD55F263FE83D51F747E4C3BD47D
+:106EE0000FFAC9FAFC985EC8E31A430691C775F019
+:106EF0007F20AF2382CED00CF1C6092E6BF8BC2DBB
+:106F0000EDF55CD4336E82F19E3F10D71A5A6B8D2B
+:106F1000AD24EF1A718103B9684769789F466937D4
+:106F2000CB73234AB71DE2BFE1EE6F349C6B3A0A84
+:106F3000EDFFD9FBF184DD48EDF43FE632BDFB2ED9
+:106F40003CFBEC746EB7097B7BA07EFAF25C0678A2
+:106F50004A0764CCB30A4851AE70F70D9DCE95C276
+:106F6000EA0DAA274EE73A42E25BDFBB7018F4074E
+:106F700085F717F0DE66A3FA5B1A94FEEE05386D0E
+:106F80008C8E45BA0EBC29FBB26883F356350ECE03
+:106F90009F1BEF2711794FCD70FF08D52765E7B309
+:106FA000E3AE96675066B89FC6788F47EB589E67EA
+:106FB00092C7D6F96B7E8FA0334FD29D9711F1A85F
+:106FC000A6752CFE0AF70E7686F4E3CC6387566E20
+:106FD00056CB9D790E8877B178616B8A847642AB07
+:106FE00024A1DDB039BDC29947FB3F945B3E14EA52
+:106FF000D9F9B84E88458FC7F33E381FD5705EEC7F
+:1070000018AF7F2CB7029FCE3CE16FD97301FF13FD
+:107010005537F66B91C3EFAB8FCC63F64F35F0B4B9
+:1070200023C84FD7734F8325A9FF3D0DC6FBCFDC87
+:10703000D9F62E5007C67DCF17AF754FC3BEF0F7F8
+:107040003400DCA31382FC5092A7BFE7AC23AA074D
+:10705000F741036FCBAEADA4FFBA6FE6785CCFCF3C
+:10706000853878FEF728BE9FD2BF3E83D39601E2D3
+:10707000BD13D5F26A80F307E99E9B010FE29E9D46
+:107080000E8BB606FC8FC04B04E791ED2307A05C86
+:10709000E055318FBC35C51B8DF7011499D09F5732
+:1070A00037B51D8C4CC273B609921A942766857841
+:1070B0006D94CE16C2655D60DFF5CC3D60A3DF1D2B
+:1070C0009B6F93E0FE9636D256190B76D766123632
+:1070D0003E58CFE9696AF9018CB33B02ECBC5FFF13
+:1070E0007A26E1276AB08ED280364E4A0DCA251420
+:1070F000B9E03F75997CE1E2B559E9950BA15D8155
+:107100008F848DFF55F37B66EA54CF32ACB7CF8FB7
+:107110007E518390EFF34D04EE37BC9DCBF3DB370C
+:10712000B3BC5C72F9CA15B924787E8AF64F403E2A
+:1071300035CCB4E1BDB10D9D2978FF16F14878CF6B
+:107140004B53E7310F941B8A8BED106F76BF4F24A2
+:10715000B8970DCFECA11C54C8A742DFA2FD9084C4
+:10716000FBFD33385D8BFB94A81E591F4DE1DEB04B
+:1071700079D501C8EB7EF779DA07FD7442D64EFC6B
+:1071800090F6FB5DAAC45AC6C2532175188F766269
+:107190003F33793FDEBFD171ADC171BFDBF926AEA0
+:1071A000E7849978AD947ECD156C68F30FE230DFFB
+:1071B00058E4AFDC616DAB063DDB6B0914C2F9A985
+:1071C000DED7DE1B09FBD41FFE9F0B36B08FFFAC52
+:1071D000046CF0FEF4C37FB4C1FDC81F3E2CE3BEB7
+:1071E000DE1CAE7704BC9FE7747E31CFF30CD0E792
+:1071F000BD2BBF2D09CDA3272D0EE49FC53E1953EE
+:107200001E04DF2DDD110D16515FB9B13D5157162A
+:107210007AA411EE6B0D43472738BF2CDEB5C502AB
+:10722000F70B5CCCD376C1F8A715463FA7F7D97CFE
+:10723000707FA298CFDC5D4516B04FFEDC1941FC93
+:10724000A00F956E333B4FE6AE95283D681CEFC608
+:10725000791E7E3D1AFB5BF014934FF574AC160A51
+:1072600057AD7331CA21E33A167CA84E86731C0BC6
+:107270001E9508ECAF40FD8729DEB4961F639EA8DB
+:10728000719DF55EE37D766E948F0D1CBFF3D6E99C
+:10729000BF37743E8EFDCC27EA7AB0A717B419BF6A
+:1072A0004FF90CEC9F06833C7B278FDB5B25A414F6
+:1072B000EE9D39604D8BBBDABDAF6757DA91383F31
+:1072C0005F69C5E7E995049FCFE4A908F7659DC705
+:1072D0001E04FA59DEB1DB02FD1CF48D4F82E3A3DC
+:1072E000533BA72860774DE5FBACB3F9B94E74AAC0
+:1072F000D979CE1EC053558CE13C275F771DC7035B
+:10730000B126229DD5C17A0BE1BDF275E87ACE1F78
+:10731000498BC17D3AB1AE52BA2E79F0EB12EB1126
+:10732000EB13DF1B65763FB0B19DA0F36738DDCD71
+:10733000DF765BEB700A8A35AF7D36AA87F9A968DC
+:10734000DF5772BC555A1F47FBBE92E8EFA5A27FDC
+:10735000C7817F05BD35109702CC6BA42B816712C6
+:1073600063F6F2FBF9D1FEEFA3A7CE7F43B8087C0A
+:10737000537E71F2FD3427ECA751BAD2D9DB948E3B
+:1073800074E5056DFAF297E69E51C0EF0D86FBA1FC
+:10739000BE34E45F88E7A5BC540607D53D19CE0787
+:1073A0002C209E56B6EFCACE1F9D56DA0EFF10F85F
+:1073B000701BE3833F73FCB7E47B46E783FE52DC3C
+:1073C0008520EF2B560F939368BDFAF5921DF86B4D
+:1073D000DEDAA2C9C09763891BFB9B9D18DE7EABDA
+:1073E000C8677A646EB39958A8DD3F978E01726EB4
+:1073F000EE3E19F91EF2A6A60D817B26183E1A1F35
+:10740000DD6D19469F8B9A1B98FDE0637C23EEABE4
+:1074100015F427E4FF92F5FBF1DE0DEAB7E8F8ABCF
+:1074200009F2BD0B818F0DEF9B6F463C3411F6FBCB
+:1074300005027E37E573BBC1455C409FDA83362B7E
+:107440009C17B9D6BA49FFB803C625CE1FC940BBA1
+:10745000F3BCAA0E857A1A1DB31BEC48452B85F7A1
+:10746000145EA8A702ABA2F11ECF939764A2427E3E
+:107470009B5D2B053BAAE7FD9178CE5DD0AB586FA5
+:1074800093753DD26B13D1FBA3F5D4F181FDCFFAF7
+:10749000ED8998D744FB2FEC007B63BB19ED092FD6
+:1074A00059E184F3F69E47CC2827E776C4A33F3CF6
+:1074B000772DDB2798BB2B1ECF07527F14EF1116B9
+:1074C000F838B9B6D2320CF19582F7F3900E3D9DA3
+:1074D0000B3CF5F7270D785AB7FFB053EDEF5F86F9
+:1074E000E0E9D400783A158AA715F95C8E703C91D2
+:1074F00087B9FCB9EF5006DC5F75BE3912CF83182F
+:10750000E950E82932FF06CCBF1271AA9AE10C2F8C
+:107510004471619EE285F5E3116F467CD5FC631EE4
+:10752000E285BC6FC3FB8B67A7B17B5BEE9518BF91
+:10753000CC5E33A506F4F9E3F9CCAEF93D955BEEEC
+:107540002C6A8F53B9E5A672EB8F549E41F9DD95F5
+:107550004E2CBFB752C5E79F5666E3F314DF5715AD
+:107560007C4409C10276E3867C26C736E48BB8E109
+:10757000034E302D6AFEF1C7F1F03B0A0EEF943B4B
+:10758000AA471272AB5BAF0F67CDD4EBBB1EB37DC6
+:10759000B213FCDB47D93D4C733D37EAEA1345B5DE
+:1075A000C07968923D2EF81EF94DB5C07DE977D5BA
+:1075B00026EAEADFB12E5957FECF7C15D77D5B4D09
+:1075C0009AEEFDDD7579BA723DDC9B0874AE4E40D3
+:1075D000BE7980E75552079DE1859F23FCBAB974B7
+:1075E000E8F7E97CBF3E6AC6EF467C08BCCEDF24E4
+:1075F000138DF6376F13955F748AA7DA289E68BBE0
+:107600002F4ED8D00F69DD35EE9D09B47C729719E5
+:10761000E30727D726FE04ECA793BB1CB1843EB535
+:107620005699DB1976BC4F49F45BB976159E87A94C
+:10763000F745B8D09EE8F2FEBB28ABE0B7C2248184
+:107640006F8ECB3EBF84F863F1839D11680F9FA6B8
+:10765000761D5C3D7B5A226BE10907E6E3E8F76F94
+:10766000BA1D3EE0EB9A7FC86E27D0D3CE48767F16
+:107670000838C3F4FBE7C732B63E86F4A5B6FB91E3
+:107680007F23D05F98D7C3D647A4B1C980FFD3F179
+:10769000C41D4F27D1B8E2BD8F148AA7C599DD85D7
+:1076A0007EDAAE2EC5EFB893B63BBBCDCCEE97A33A
+:1076B000FDDA69B9F197115B983C710FBDAD2014EB
+:1076C0009EBE425877D670CF87F9B07FB0D057882A
+:1076D00072ED6107F29511EEA72C1AC2D70B7C2030
+:1076E00005E56490CFD87E10156EC340DECC33BB69
+:1076F0008680BE3AB5DE8C7629D527B1B7611C6687
+:107700000FD2F129459D0CEB3EB52E8580DC12E3AE
+:10771000CE5D2FF37B42285D42FD0DB2466D072200
+:10772000F496779DA491A1FDE9E6FEFB4A312FDC9A
+:1077300068FF8AE7979457B5103B62C96BEC7E7E71
+:1077400052DCA3CC2C085D07FB7D05A24DD0E56B78
+:107750002E4BFDED473126B46BE2209E7EE6B88CC1
+:10776000747626B5ADC44949FFACE940C9F769F95B
+:107770008B69DE4F155ABE6FB416554097B4D4B41A
+:107780007E14F84FBD9D9FFC04EEDDFBFC45331CD1
+:1077900087274B762E1E8D711F6E7FF7975BE2FE5B
+:1077A0003FF730B83F65A9DA8E7A5C854372B87EC0
+:1077B0001FCE53E875FB9312D858E493F1B6C7C0B7
+:1077C0009F9E67389FF28999D909230A989C12FADB
+:1077D000FE1E5E9E6762744D5E97300F9CF07BE5E7
+:1077E000853E10F25AC8FDFC02665F08790D997655
+:1077F00020B716C2ED2D749DCB7644F87C29D8D6DF
+:107800000E705CCCD0441617A8D86E89E5C5A78148
+:10781000971A4837CEFF73B36F61770AB4DFB23679
+:1078200001DB9B5D18A7E5FA05AEB506B9D4C0F932
+:10783000AFB14DF2F9917F989E5CC0FB27A06742E3
+:10784000E4583FFD62D02B0BB85E5D400C71DE3614
+:10785000BDBEF344DB705D4BE8B8A03F83F3A2F6F6
+:107860003385DD42CD77783ACE5B72F9C2CCA38105
+:1078700004FC907FD7B88BC5BD8DF332AE63B0F3F7
+:107880005CE8BAAD2ABE38645CC3BC05BC31501C90
+:10789000820701F7855E06CF859D12E2EB2FDC5E45
+:1078A000A37F189F36E2BF8178A6439E42C39354BC
+:1078B0007EA604E941D0C1E2DD3E0BD8CB5F90B695
+:1078C000D818CA07CB36EDBE63A20AFEF331F443E3
+:1078D000EA12FC19A6784212BD2F3D5D73D3B5E3C1
+:1078E000FCFF2A38C12AE07E5A6C47E1B2609BEC6B
+:1078F0008E2CD4D5E379DA5E84D722AFD70271D04B
+:10790000453CAE78AD793629EC3CEFB5E7CBE0F8F5
+:10791000AF9EF7D3057A3B36681F6584F5B7FAEC5E
+:10792000A26BE8E30FCCFE91A08F032315D4475F31
+:107930002BAEF7CA93403F67A0DF3090BC5DC8F51F
+:10794000F202D0D3F4F9E9A6BD786EEC2F4FEEC564
+:107950007D43CB8B0B62C15EFE74D3BC9F40DEFCCB
+:10796000A7BBE6A15E6E7846E865CD12AAEF2B377D
+:10797000D53FF77F804E7744E20985855D1AB7C70A
+:10798000A9FC03B9B889C93FF224938F0DB1ECDE8D
+:107990006FAABFB2A0DE830BB52CA0F790F7A8D7D3
+:1079A0001E9CA795627B62F7B37B21ED7ED05F4280
+:1079B000BF0ABD7B7498D655007A413EFAEE4374F7
+:1079C000FDE7F6C818D36994B78C82DF4318488E58
+:1079D000FFF3F036F5C13B6510F09E0BF0467B8857
+:1079E000C1FBE3750CCE9FAC67706FDD95160B7E07
+:1079F000F0C7EBD2D00EFA785706C27BFE6314DED6
+:107A00006807AB7A3B681D8537D8FF006F3AEEDC1C
+:107A10002E95C3DBC5E0BD8EEBA1F5EC39BF1F5C35
+:107A2000BD986FFAE0F3112ED0EFA723FD0EF053AF
+:107A30004EEF9609ECE7F7D949DC9E1170FE86B44B
+:107A4000FD3BD855FDEC9B0D11C44EFB5BFC920D2C
+:107A5000CFD57C2E950F05049C6DFB6D2C8C171CCF
+:107A6000BFCFAEB954106AD70C123FCB8907F3DEF3
+:107A70009777FEF604D8F570BD0AF8FDCBC539F846
+:107A80000EFD397849059906210A97D50A7430C246
+:107A9000784F8086BF0F7131E3AB392B909F0399EC
+:107AA000A1FB414D517E33C4A302BB25C477E30340
+:107AB000E5B1E504F6B39A711E8E42A69F25B71B69
+:107AC000E38C11946EA2E878CE4215E72BA97616C6
+:107AD00077DC4CC7B505E76B7C3F1D0411E8F71850
+:107AE00013EA77E3FA27F3711A6513FA21CB2CCC4A
+:107AF0001F11791319FC7B4621F3EBF30AD93E439E
+:107B00006F2441FDD1BB21DAB70AD75785F14F85E4
+:107B100030FA5604DCECCA97BA7BCA797C017EBF86
+:107B2000008CEAF9113CFE4B552DB4BF87B7BFA7B7
+:107B3000ED6DDCCFA39ECC2F40FFCE6E8970813DD2
+:107B4000EB85FBAD28DDFD388AEDBF90A43805F844
+:107B5000EA6E2E67EF697BDC03FA68765BB41B9EE6
+:107B6000741C2FE1F1D662D8BF1D6EC1786B9DB534
+:107B7000E74530AFEF757EF23D2B5DDA2A13B35F38
+:107B8000562510CC3B1943CD7888DFD24FFBAE246D
+:107B90005E8D7EF4F1E46510D765F7B579519EC826
+:107BA000265D7919FF5D81BAC2CC3B9F1C41C81F7D
+:107BB000885A00F85E06B0017AA88FC3F8C0AD10ED
+:107BC0005F4E80A782743643215E137BAE8BC173F8
+:107BD000FE2CDE3C9DAFFBBB13883F8EAED7FFA6CD
+:107BE0003EDE7DA7DFE4CFA278B855F1EF07BA36C5
+:107BF000595533F8079E1A692CF8CDCB560F6EBE37
+:107C00004D854538DF6526139BE74312DECB700FA9
+:107C10006572A0CF390AE992C732FC01FD3525B063
+:107C20007B8003F731FA16717681A722DA7D287CF2
+:107C3000EFE1F3A3FDAC8B85F696F0F1A51F160AD4
+:107C4000BF98D99D4B39BF2E15F4B64BCFA7CF02A5
+:107C5000BF001F819D4BE1760F7F0E44EF9B38BD27
+:107C60006FE2F4DECACB831DAF3182F8437FAF45AC
+:107C70008C7B2B7F3E5D988AFD8979087A263C3E75
+:107C800065A29203E8E854DB1AB49B1619E2C524F6
+:107C9000348E25872BF7C91FD315785A02F3613E1E
+:107CA000D277225D40D7F758DA33D8BD12FA7A621C
+:107CB000FFB70E6EEEC2F33A44F77B0AD5720CE6BC
+:107CC00013D549EC5E99DE729BD744EDC50FF8BD24
+:107CD0000EE79BD9F9D0BA87F8EFA0C43D381DEC68
+:107CE000C3BA588B02CF0FF8FD72F7926E5B4A4A07
+:107CF000D03E692D97F9EF6ECCBDD39D0FF74410A0
+:107D000051DEE81E8151255E6E780FF63B665EA659
+:107D10007480E54577BAA9DCE83DC4BF7B6919F0FA
+:107D2000F888A0E746ECAFF729F1FD3E567E547C7B
+:107D30007F9095FF4DF4CFCB1B0CDF5719BEFF9CF6
+:107D400095DF2C7CF04E2FD8B57C1FA7EE0609E5F9
+:107D50008A95D35BDD6A3FC2B9CE74803D2B881F04
+:107D6000CED75EABDE37851E6BA103EE37386503D9
+:107D7000FDFDADCB8DE5F3F9DAF1425A7FC96D9285
+:107D8000D702F2F2B82F93CBF7B079B9564EBF179E
+:107D9000C6D0FEC607E14DFBF9F09FE96775FF7E8F
+:107DA0003E85795D6F3FD35D6C7D21FDF4FE33FD33
+:107DB000EC75E9E723ECA3A963DD5163403E54DD94
+:107DC000A88BFB2DFD912B0EEC2BF20EFB1D93A52A
+:107DD000ABDB478DA3FD2FFDAF57462D0CF1C797A9
+:107DE0005F92891BEE47B824E1F38BFD7FB2C0F9A7
+:107DF000FCE5FBF65B26E7C3EF2FECB75486CC6BB4
+:107E000099C8B3243DCA8C10FD1E37C6C4E506FBD5
+:107E10001D87A5FF7546017C2E35B57FFA0CC48100
+:107E20006E90C2EED7FE95AFEFA301CE8339C63078
+:107E3000F95756EC4E82755E041944EB57AE09BFF4
+:107E4000CF3F670C8B27D6F17B95E795D8AC2A8579
+:107E5000F3F8E36C7F7AE1E694B110E77514548C83
+:107E60001A03F31D305E1A60F1D24E162FAD4BE8A7
+:107E70007E00EE31BDEB574F6D847B4DA76E147CB9
+:107E800042F0F7726A2204DFEDBAB3AA0CE35F583E
+:107E90002E1BF3C246E09B23FC5EF1D9A5055120C1
+:107EA0001F7A52A24D762A4746E4D7DF05F3985D44
+:107EB0007AD364785F1E61CBAC677177A48B11F9BC
+:107EC0009E62F80EF521DEA15958FC4B7B4BC6F89B
+:107ED000975618AD85DB7F1ECBE170D718764FF132
+:107EE00011139DE7D8E03CC4F8D46079A09BF677E5
+:107EF0006AF5B022B897BF25BF7C16D2131FBF25E5
+:107F00005FAB86B2189F2EB710DE0F761E159C2E23
+:107F1000668D6178F394517A0BF11B675445EBCA77
+:107F2000336B13893B340E3B3359579E5597A6ABA1
+:107F30007FF7FC3CDDF76911DDC5CDD7610737D987
+:107F40006C51608F7DD8F9CD7FDF03F6DD36D92502
+:107F5000D1F52C7E6DFB7FC3EFA39C871F5C60E790
+:107F6000AF301EF6F911F67B7FD4AE5342F775CED3
+:107F7000916ECC2B0CD92F08BB9F2AF60B96DABB3F
+:107F800030FFEF7FBBAFD33286EF178C2563411FE5
+:107F90009E6F7E17E370CB63D8BACEBDC2EF2107C8
+:107FA0003D42E9FC666808F7855D5A85BFEF53C915
+:107FB0007FBF75D81895F90523EE53E0DC77137D64
+:107FC00082FC9F4CE5541CA593EEFDA4601FE45D6C
+:107FD000A4D8309FBCF1D2ED18E73E12E5CDBF8F9B
+:107FE000D65BBA6E0A96975F8AC67E7F2F774FC69A
+:107FF000BCE697D9EF214E4B9EBD1AE60FF5EFA7D1
+:10800000E34DFBD5CD3500A7E5FBD8F9A969F21FF3
+:108010008AA19F656D53B0FD34991C91A8BD10775E
+:10802000E91EEC771AE87A5A964B6C8F81FE952DF3
+:10803000FECC6741AE586C28579A2E4562BBA99575
+:108040004C4FFBC6303BC6DCC3E6557DE936FC2E03
+:10805000F0FFC29854DD3D3266C73605CE27987BC7
+:1080600024AC7FCBA53C7C8A75BE95FD3CDE576277
+:10807000767C3D19F23ADF4A92EC687E18E4EE8590
+:10808000E6D23812462EF58D7389E501475C627998
+:10809000C12F14B93B81BFA73FDCA3C0FE0E89B13D
+:1080A000DA015ED32714A90B43F8493E709705F017
+:1080B000627EF29805F47E047D56867C6F14F9EB9F
+:1080C00006B97C80CB01717E41E819A276E87E5F1B
+:1080D0004DF0CBAF38BF8AF6DD40EB80C79722D09A
+:1080E0009F7AA3487B17E6DB5DCE7E278328DDA33E
+:1080F000605FE55F357F8A67AB84F67E0FE6C54F2C
+:108100009FA09A60BFE0FDBE7530BEBDD63A7ECB63
+:10811000EBFF5E262DD0EFEF274DEA76D3FEF6FF7C
+:1081200070DC3890FF62DC2FC6B073C3C41EB80C7D
+:10813000FE5DD3EBD12AF0F73470968A83762D7DDD
+:108140008FF7E535BD1EB155A2DF9B62A97F4BC7F6
+:10815000AF7C23D20F74BCFF8D48057FA7A858FBC6
+:1081600002E465E51B5955E0CFB93B231482768EB6
+:10817000FB2CCAD501E67B2D3965A433C197DA3AC9
+:10818000C62FF59C4EE772FED3381F5D681E8A7CB1
+:1081900078E1613A69D80F7D582AD80776816AC399
+:1081A000FB89055F4E033F88BEFF7F46E48E2C00AF
+:1081B000800000001F8B080000000000000BC57D40
+:1081C0000B7854D5B5F03E73CEBC9299C9E44942C0
+:1081D0001E9C400841024C26218410601202A2021B
+:1081E0000E501530C88008110909515BACF6CF84D8
+:1081F0002410452D56DB068B74C04751696F406CC7
+:10820000D31661786863F5D368EF6DF1D6DAF8B804
+:10821000888A3582F5A3B728FF5A6BEF9D993349B9
+:1082200010EDBDFF1FE53B5967EFB31F6BADBD5EA2
+:108230007BED9D79E312432D0A63EBCE253296CC7C
+:10824000D83C95752B498CD59DCB65AC98B1F5E79D
+:1082500092E97DFD393B3D579E1B47EFADE754E664
+:108260000378D53985F900BE6AA633684A60EC42C6
+:108270005120D3930AEDB45C3E87B9180B6CCA2821
+:108280000938189B7F57AF664B618C392CEEC7A11C
+:10829000BFF96545E9ABE1FD05FC99C158CB9125D6
+:1082A0004C7742BB297E8B0FDEAF82E7CCA8F29BD6
+:1082B00018F37502CC987B765A097CDF9A6BBA87E3
+:1082C00045CA758F89B14958DE4CCFF9B2BEDEC5BB
+:1082D000581A6337B819FFD90883CB60CC29EAAFA5
+:1082E0007484479BA03D7383DDB309C67526459F03
+:1082F000CD006EBC1B004041A3D93FD309E36EDC27
+:10830000AE7882F0F98DA54E1B8379969E68B004F5
+:108310000A23FD2F393781E9808745E7F2E8993A4A
+:108320003E3001F1B0E2DCB584AF95508E4FA69798
+:1083300099703CB7D9F0771C10C0A58CDD2AC6F720
+:1083400059C3E461DF81FE3F7BD94CE5937CC11BBF
+:10835000703CE690D5B30BC673CA1E50198CE75417
+:1083600036733F08433C65664137D0EBC60E950532
+:10837000A1FD55F00CC0F35422F3257A119F30CFA4
+:1083800002DEF605F8F7776D5B0E1B05F46DFCD386
+:108390005BDA48C66ECEEF991086766B2AC3A9D7F2
+:1083A00041BBA71F337B82D0EFBA23AF979AA0FCC3
+:1083B000C35CDF30A632366678600ECE67EDC2D081
+:1083C0002FCC00DF72DF33AE297A049F9D5A78B438
+:1083D00006DF77021E8330AECE7BD53921A2178B04
+:1083E0005F301E1F803DA83A7B81124C00FCB1EA31
+:1083F000A97CDE363EB6B5E746117ECE3658C71F9D
+:108400008076CEEA4E0FBEAF3BB788DEDFD27E0568
+:108410003DCDBD5708BE8CE7FC9AB96C13F2599D4F
+:108420000695E1BB3A47422808F399F76FC07F8071
+:10843000F2F50716F82B91EF0A14CF6878ACDB76CB
+:1084400085E0F3DDF797035EE77D92E26981F7BF90
+:108450006A4A076445F87FD6B905542FE1DCF5D4A4
+:108460009FE47FABE07733F27F14DFC3778CC17773
+:1084700081A2C09D88A7AAA7FFF9CC7FC2AB2BB56C
+:1084800070FE4F52F0E924FE89AC039BFBF15C5A6D
+:1084900007FAEA283E528F2EB1E8802FF3436FD3BC
+:1084A0003AB0C2736654F97AE4EB42C44CAFB6D02A
+:1084B00019791FFC9AFCBF5ED49F6365CBFDD89EE3
+:1084C000D69313DDDEE1A2AA073D50DEE151787BB1
+:1084D000FF43E3063CD910BF307E1FD26B7E996EFE
+:1084E000BA2717FB91E3E77CF255E36F13F55F556D
+:1084F000D9466CF7D519337A7CD0DE913B8B8B55FE
+:108500003DD2EFD31E0BB5370F6887EBA8EF396B61
+:1085100068772E8A11C614A8FFC9736343F7C01485
+:10852000DF627DE7713CC183F13ACEAFFE503CD5AE
+:10853000AF8F4B0829505EEFEACBF7C378661EB6C3
+:108540008791AF8E1CB66B0CFAAD28B9F169C4D314
+:10855000CCC363AA15E043DF41ABC6A0DEDF27F83A
+:10856000F6221F0C357E39BED8A79CBFE42BB95E1E
+:10857000E4FA90EB2176FDC8F570D5564FC277909E
+:108580004E8098C771FD68C1BD388F3A3DBE08D78F
+:10859000A55C47EB0F28B4CE40E87A46EB917524F2
+:1085A000D74D649D98080FF3849E186A9DD48975F1
+:1085B00071935817723D1C533B1F2C87EF661605AD
+:1085C000FE827892EB62DDFE58BD30245F31E4AB71
+:1085D0009B521A18F2551D3CA3F9CA3AC47A78077F
+:1085E000F923F5D2D743CF25F2D3DF919F26FDAFF4
+:1085F000F2D3DF916F06E1A7CFFF157E8AE597B32F
+:108600000D7F2AD1613C674B40CEE646F8EDAA9734
+:10861000D8F803F09E8D727A907FBAE3F83CBB2DB8
+:10862000D9A116AC778135201EA5FEBF09E99E1C95
+:10863000E153AF3730BC685284FEDD71C1C20D8595
+:10864000974E676B4A8FC55788F4EE31E8FFBA2121
+:10865000E83CA2E8EBD1D929EA7F159D3D455C6E47
+:108660003037D0B184E8A7235D63E98E7445BAD76B
+:108670001FB2EEBE185DD79704A6160D2227988F5D
+:10868000DB0311BA581721DF9C0D83425386A6AB3A
+:10869000B983E35DC26D614DEADB64D4B7C02F15C9
+:1086A000D8DF37E5977933E1D7E1083EB5D89705AC
+:1086B00074FFBE80D92F16237DAE2D93E54F77F83A
+:1086C000F250EEC0EFE5D4838FD908BF1C0EEE3D0B
+:1086D000510DF5AF7AB0BF3C88E5B32A12447BCC8C
+:1086E000A7B048FDEBF73D79E25E9AC736AE0F02C0
+:1086F000BD9A7F7C145C02B0330A2E8B8177F0FA2E
+:108700002EAD97B9A99D105FAFD0BEE2E5FCE38F17
+:10871000B2478092B313D19E3CA0B8EF01FA2FADBF
+:10872000F8C482F48ACCFF00CD7FFD4145C05D27AF
+:1087300070BE4B0F70B879DFC18EA026DA033CAF54
+:10874000136836772A3E15DA5D57A68446E60EC4CE
+:1087500073739151DFE18F66FC9E5952BEDEF7B80C
+:10876000BEE9FB91F47DD8FA35FABFAE82F9428EAC
+:1087700081F51E90EBEB3CC0B27DC0E522985FA86E
+:108780007060FDEDA2DD1E9349E0EBB50EC45F8F76
+:1087900045E2B3A7C35701F4671C7E745FCFE26064
+:1087A000211FBE2F66FE171B7F5BFFBA8FCC5F3782
+:1087B0007E1FBE18FEB60EC09FE09F5A233F25685D
+:1087C000FEE367A19D8414C58D76F17ABFFD5EB48A
+:1087D000FF23FCF167E28F1E3BEBE76723FFBFB986
+:1087E00018F97F3D93F5DFEAC0F5E337F5D7E7EBFE
+:1087F00041F2177C5F00FC8426327EFFDCBEBF7432
+:10880000041D441F2A2738EF22EBA13306AE8859F6
+:108810003F82FF69FDA29C07FC8C1E44CEBC29F060
+:10882000FBB1C216A39CECA9E27662CF48FE3C5F86
+:10883000C4EDC2F7041E4F8BFA3D715178C88AD03F
+:10884000197EC2E88744CD9BF0B42445CEFBCBC54E
+:108850007361DE3D49BCFCF3A2FFEE086645E0D83B
+:10886000F6CE157D497C1369FFFC09C4EB1281B774
+:10887000F3455F9C107CA5E0BAAC230601BE38A08E
+:108880000455F413902F0699F7F1817C158CF9DECD
+:1088900067BEC8F7BF1FB82E7D31DF3373C9D7F964
+:1088A0005ED06D6E0C5DE7C4D0B53A06AE9170C86F
+:1088B00020FFA45C5CD9F5405B1ACCE3963D0AAA84
+:1088C00099287E762CC1F5798B5BF2AFF30DB4BBA2
+:1088D00022FCEC227861A7948709DB511E2E407997
+:1088E000581E8117A1BC20D8BDC437315A5F24520D
+:1088F000F975EDB27E12C14B5B657BC9DB7D5A8495
+:108900008E2C98B204FB5B5222F44530F50DACBFBF
+:10891000F620FF7EE2FEB4372EBA1EB6C5E06547EC
+:108920000C1C8CA9FFD057E897D698EFEF8A29BF87
+:108930003706EE8881DB8DDFAF58A5D03A5C01FCAD
+:108940008084F8AA7539C3DB6FA7F6EB53C541766F
+:108950009B615D5DD5C2E12BF68F5AD2EE8882BD58
+:10896000A397041D91756166FCC79AC2685D9887DC
+:10897000909793BDB1EB42CCA72056DFF2F2BFE255
+:10898000AF19680733835D704C35C2475439EEE246
+:10899000376E2BC49712F62EC1F8CA553F36CE0B50
+:1089A000FC55017B96545744D925C1894B70FDCBAA
+:1089B00079CAFAB3BFB8A0627FCBBD13973C06E576
+:1089C0003555E1D10D30CE9A24FE04BDA6A2DEAC11
+:1089D00017F198D9CFA97ED46B3571E1D18D85512E
+:1089E000F3649DF938CF2377AA449F600BD007F03A
+:1089F000B492814300AED99184848D4F40FD63775A
+:108A0000AA1B518FBEB531390DFD9B835EEE2F1C25
+:108A10004B18917613C047E2975B74A87764CB2C10
+:108A20007A1E557D9BFB60AD7D6FFFF4258EB1589E
+:108A30009E40F8B9C35BBEA419F8FA2EAF4EF80CED
+:108A400024B9D3BAD07EBEC7CC1ED769FE3B896F8E
+:108A5000EEB316A1FFBCA2795C1ADA932B7FB86043
+:108A60007606D45BD966F628548F4DC07107EE990F
+:108A700065C1F255ADE219BC9C9E87BF7CB4C505AB
+:108A8000F5FB1E513CBBA1FEB4CF3A5F9A00F09AB1
+:108A9000F6511E24CDA17326E6867EDEE918135218
+:108AA000811FDFB537BC309FD767587FCD79FD95E3
+:108AB000F925585F756F82FA27E13DDAC327EF5633
+:108AC000772B382E97334E81299DFC427F05ED5A36
+:108AD00028776F82F727DB6E4E433BEBA4A2BB14D3
+:108AE00098FFF6FD7397A403BFACE9B00A7ACECD28
+:108AF0005801F35F61EAE717D21FAB1339BCDD3BC6
+:108B000077C9E330FE93DBC7B810CF89C5BE87BDF8
+:108B100080E7B78A7D3FF1A6E238B99E3AFCA5BA54
+:108B20001CEDF1DF9E5E9986FCF4B8583F87CEAD10
+:108B30004C5B1965EFACFE5823BA1FB6E8B7E138B5
+:108B40000FC7652BE82F03DD9317C0FA5D25FC0FD7
+:108B5000E0DF8DCF0C62F704BD2AB57B646B6A85BC
+:108B60006EE0E3EBDF40BE24BF01E05FEEBF6E3B93
+:108B7000EAB5F7AC1BD9BBB8F8EE828229F03C66A7
+:108B8000A7F89579AF3D64CFC5F8A76F36CA3D9673
+:108B9000DE99BFD019B5EE44FDBF049D54FF2F50A0
+:108BA0001FFDB7BF04FFEC648E8176FC1A973388F3
+:108BB000C6C4FB4EA78674784B6B3A79077CB7FA2C
+:108BC0001133C9FDD58FA4DED587F206F805E3631E
+:108BD000B1F3528BCD34AF21D761B0D6B80E592D39
+:108BE000C9EBA1D661CFFE35175D876B849F32FB41
+:108BF00011B31FD7D19A494E8D81FEA87AE4F9C7E7
+:108C000091DFD76CB07BAD30F0358F58895EBD4EAB
+:108C100067D00DE50197534B84E75B82BEAC98AFFC
+:108C20009B992AD36C5E7AB6629CF40C8C2719E06F
+:108C30000F363EF8A3C950ED4316BA7632E0EF0C7A
+:108C4000120CF072E6804AF143A6F9B479201F6B4A
+:108C500019970B752F3E63A9C4D935AC998B7EDD6E
+:108C6000CD21F33BBDC267BB20A689F2B49EBF02F3
+:108C7000BD6A2CAF67F77EAA4E2036B6E07AACEB21
+:108C80008C296FB8FC7D8CBFD433ED9D5E19AF8508
+:108C9000717CEE75A69C8C4771C8BC802176A6C1FC
+:108CA0009CCF608A6B1CB0AE60BE33772834EE3543
+:108CB0001BD59015EACF4CE671DFF79A80FE63680A
+:108CC000DE4137C06B1EE27A660D534236F8F5F28C
+:108CD0001D1B345C0FEB857C59A1303FF2F7BB764E
+:108CE0004F0EFAEBAB1FB1137ED7ECBCF98FDBE173
+:108CF000BBDEE67929D1FEB143F005B4CF6C4991D2
+:108D000076DE6FFE5E0EF2FFCC9F829F0BF35D93CB
+:108D1000C87EB12417E99591A33B22F5D66CBA33EE
+:108D20009FD7033F19E6BDE26E95E6C19EB592DE80
+:108D300083B59E4E7259E07355EB8B164B21CAE9F1
+:108D40007B7B54A8FF0EC0AA83F0151478B420BE14
+:108D500096E3B719FC9BF4526177EB24470238BFC6
+:108D60001A93B27C21C9F53E0BAEEBF26285C63395
+:108D7000B198DBB32B723C37501CF97EAB07E5147E
+:108D8000FEA8721CE057D5997A56633C97FDD24AEB
+:108D9000F191FA56BBCFEE22BFC3B71FC7A731CDA3
+:108DA00002F858A77379512EF8B05E5F7039F20D52
+:108DB000949FD0707FC5C9E5625D22E09DEB639F03
+:108DC00009FAF9047F1BC5DBCD9810D5BF22DE431D
+:108DD0003BBA2BD26EB789B5639C05EB8F9D80782B
+:108DE0004CBE76318EEFE72AAD6798FCFD6568E7EB
+:108DF000FD5C2D46FF76C5DDC7667720BCAFC88D0C
+:108E00004DAEF8C51F486FDC22E8DF8BF63EEA1155
+:108E100080F7C1735131D7FB0195C77D16097C4995
+:108E20003E90E575779B79FCBDCD4A764C5DF39F0E
+:108E3000A8DD3A674F1ACADFBA67CDA528A7AF15D4
+:108E4000E35ED99C5D7102F86AA539C1ADC0AB750E
+:108E5000C1791684D76D53088E7C979A837CFA511A
+:108E6000EBAF5CC83FEFDAC3A3511FF56DB07B7663
+:108E7000E30444DCEDA3D6D1BB313EB3CADDE354F9
+:108E8000A07CD56DA392507EBFE50E5BB0FCADCE4D
+:108E90005C13C23EB7BB02619F3691E08F40947570
+:108EA0000AFF13F96DBDC2E9BC6EEF31CB48E8EFA4
+:108EB0004E31DF8F7FFE877CD45775393DF9A85737
+:108EC000800FF23311CF4F29A48FD7EF557DF609CC
+:108ED000113E588F7C00EB6EADE083F5077EF51DEB
+:108EE0005C0FEB91FEDE817C047C7A9CDEEFDF354B
+:108EF0009BF1EF8F239F483D0670AB19E369160184
+:108F0000433F08DF85F89C44E5D5BC3C5848F294C3
+:108F1000F55AD0EEACEF32077BA3F67F86A2F3764C
+:108F200041C795CD5692BBDBC5BC7BEF7ED6857421
+:108F3000FCF8E7C75EC0FD92BAFDA0ADF541D6854D
+:108F4000C04B3DE2C145F320FBA21EE7ED8AE0A144
+:108F50009FFFC57AAC677C9E72DEF59AC0832C17A2
+:108F6000DF3F2CF8661D13783B3086AF3FB1DE70D3
+:108F70003DA35C95F30B24F1EF259F1E2EE67A614D
+:108F80008F78AE03BEF01412FFF82C524E40D1C7BA
+:108F9000FB7651FC47D24B8EFBB5883EF12526452A
+:108FA000E8D86B62B59D83C44DBA04FEDE6E1B9695
+:108FB000D30578FB08FC2CB4A7905FB5A8FE24DF8E
+:108FC000C8FE663EBDE04A9C2FB41FC6F665BF6F63
+:108FD00005E3356CE72DC6D707F227CA4FB92E67D0
+:108FE000B62CBBB2C885F53E768E423B46C8B3D799
+:108FF0008ADDF4BD0FED05F8DED7A550FCF96DE173
+:10900000D7BFDDF62BD7CA283CBD2AC62DF90C7F69
+:10901000302E25C7DB9DC4E3B9B1E39672488E7B41
+:10902000E696EBAEC4F772FC925F257F4A3C4A3E5F
+:109030006577A5925D13CBAFC46B52AFAA06794F8B
+:10904000FAF1F2AC4F2D01C7C0F7B1B0B487DEC55D
+:10905000380DCA8F27D510C98FD6F4E379517A1EFF
+:109060007E1CD17AA779C3E5EE4ADC7FDDAB78D0F0
+:10907000E489D22FF76A51FA45DA0525252309EF4D
+:10908000F529BE0F908EEB4EF5CC76E9113B74DAE4
+:1090900067613501E3520772BDD1FA74DDE9E3C4BB
+:1090A000FF75AC6733FA512BEEFEC3BCC9C8E74F5E
+:1090B0009A697F6645DB2C0BDAF5373F7E6329F230
+:1090C000D13BEDA348AE7FF0D8A462E22BE64EBBC5
+:1090D00016F87FD5630F5EBB14DEAFEA523D24DF86
+:1090E000A11D5CB72B6E2F66C837EFDA7BE795A31F
+:1090F000FD7E87EA46FB7DEAE393EEC2FA539D23A9
+:1091000012711EBEC79209F66909A41FA4DDFB9661
+:1091100090932D66CE1739257C1DA59670B9915A6E
+:10912000C2F966664B4B3EEEA7F7ED02F98CFBCA1F
+:1091300016BD338CFD3D378CFC8B7A7087D281EE67
+:10914000A7146E97D55A982DC34BEF6D19F0FE45B5
+:1091500073CFEDA8475EBCDD59D48C0350CF97AEDA
+:10916000E4F634DF3F4CE6FD4BBCC9716497707E7A
+:109170008F6D4F7EDF8D7E04CA5331FE0F5A9FBC28
+:1091800016F5E0077B4627E1BCDF7FCEDE8EF6D406
+:10919000FB662E1765FB60E7BD176DA7815D6780D5
+:1091A000C18E33C0C0BFEF19EDC24D34AE8925600A
+:1091B000C78D63FD769CE4F79A0DA313A2F30862B2
+:1091C000ED779617BB6F3339810D226FE4F374137B
+:1091D000200A18F52CEE1142BFD5F15F3CD383F67F
+:1091E000FE36ABDB0AF37C0FF91FF7A59E5543B89B
+:1091F0000F83B639AE87F7F61585D08F5CFD6660B4
+:1092000036B67FFC812D94677013D897C39428BB22
+:10921000F9A107AE45F63FE3096CCE80EFCEECE155
+:10922000791150EC88B1975FC8D0FF757BF952ED8A
+:1092300064196FA82911F6B2877910CF12BFD26FC7
+:109240003A0C7C50E68DE0EB6F4DB564279F6E0ABB
+:10925000D0F313E5EDFBA722FF3A133CBBE1B3DFEC
+:10926000763DA866229D0F149D47BFB7DC91E0C6EE
+:1092700075FBB7A68DB4F978BAA9819E92CE32DE7D
+:1092800036EDC011FAEE6F5DC507A7C277871C09DE
+:109290005CFE0FD8EFE1F48CCD03B975C3E461F83F
+:1092A0005ECEEBC33B385DE5B83FDC73A30BE775DF
+:1092B000E427C907A7203DE313DC68EFAD11F91FD0
+:1092C000273BB83D7DCA96F0C45CCC1BD9B1288D34
+:1092D000819CBDE9C8B7AEC5F7AB9F53DCE8077802
+:1092E0009E5BE042FFF4BFB45E971B9FF05D18C722
+:1092F000A385549447E57318ED47958735A6E7D2C3
+:10930000562FF1CB94D35A08F3463EC27D2A8C8760
+:109310009C8FA3780813FB4F37FD9AC751FAFD5B6A
+:10932000E1DF4D15F3EE2A4992FB0AF47E66197FC0
+:10933000FFFE8E67E6637B1F3C6676E3B8FFF69818
+:1093400099DA5F0B7E9909C67B6A0FF777D6762A82
+:10935000E4277FB007F435CCAB6E83D9674918C8D2
+:109360008733A1BCD711E1C3B5BE10F13713FC6838
+:1093700083FF2E8C1CC88F89AC7333E2E35FE5CB8F
+:109380005FC4ACFB7E7E1C8A0F04BE701D233F4A67
+:109390007AAFEDE0FBEA499D4595C85792FE524EE3
+:1093A00004AB5801EAD5160B2BC03C9CA029CE83F8
+:1093B000EB7B8143372B80874529BDD5284E33274A
+:1093C0007139ADCE34F94CA85F5AAC240762E5C8B8
+:1093D000EF845C9F8F3C0DFFDE2DE1768499359004
+:1093E0001F229FA077B2517F2F884FFABB0E55FEE8
+:1093F000FD40ED520DC6BF606AD2EDA33C8CBD7935
+:1094000060FD520DF8774171D2B323017EABA48E7B
+:10941000C313932699016E6EAE5F5A0DF5FF59E2A4
+:109420007BBD24AA1FD92EBCFF8F1280378D0B9CC9
+:10943000C067BDC54172FA13A56FC2C6DC48FDD72F
+:1094400014F6D66F9508DC6B663968DFBD5B22C702
+:109450003FF8336F92EFED9241DEAF64AC0DE32A3B
+:109460002B83BF3BA1703FCC6F037A5D2DF86AA5BB
+:10947000CD11267FBEDD7CBA9FDEC8479E040DE974
+:109480003A5FF0D1D55AF8087E3F96B5BA4FDAC8A0
+:1094900084DA71217968F90D0B8F9D94ED01BF7C01
+:1094A0006286F9025F2BC09E1B61C92880E41A9076
+:1094B0005FCAC1DFFD03DB6D09B25E3BD1A1C68D82
+:1094C0007CA6B080E9023CEBE25D13306E52179F40
+:1094D0001342BE6F7CF6E3E3C85E374BFB25504674
+:1094E000FC7E9B9BCF8705CA891F6F17FCF87E13F4
+:1094F0006BC883A577754F8F4B87419F9E1FCEC743
+:10950000F5FE694E206E12FAF93B5AB21A817F3E7F
+:10951000DE6FF5CC85FAA742CF501C6E9DB047D9BF
+:1095200063A962DDABE11950AF3B77EC6ED42F2914
+:1095300093385F9DCE0DE7DC89722397FB3F508FF8
+:10954000F2DCE66CBA3C15EB9DDEB725EF26A09F5A
+:1095500055634167123D990BE67D05B45D06B01970
+:109560006095F67343442FACE7427DAFDF98CEE3BE
+:10957000EDCC8F7245D24BD261007D600868AF9A06
+:109580006CCC8CE31FCB76B8517F483ABD6F033C5F
+:1095900062FCCC067884F53D0B830E25884F1E6F48
+:1095A00069547A5B9311FEB942797303F5E0E316CF
+:1095B0004479ED8E1B49FE48B9A3C37F83C99DAF93
+:1095C0001D37DA317350B9336D92D08345ACE80260
+:1095D000371089BE6BC4B7B3D41A5DC371A7DA3C28
+:1095E000184F6B7C6414E91BD6FA07165D8FED48A3
+:1095F000267ED99CAB12DE6FEE5228BF715E5726D5
+:10960000D3A1686E57323D5DE732E8FD074FBC5489
+:10961000C2E512A7CBBC9F0DABA2BCA29F8DA1A798
+:109620001C47A3E0BB596A616718ED08078C03E08B
+:10963000C617B9DE6ABC46A5B82643119D86C4E4A8
+:109640003F7E473BC57FFCACDFBE572E509C564F3C
+:1096500040BAF8BB5586FC03DE4690E3D9D68C7839
+:10966000B6A69B983E88FD611574B2EB714C8FF2E3
+:109670003BB4E0D8EF57603CF65B664F08CA5BEC42
+:10968000AEDDB89E58D0D783FEC262F15D8F9DF3E8
+:10969000477C4192E1FB2DAED9DDC86F8B7D5CEF3D
+:1096A000383DC30DFD5BD57566643216E0F6A2E465
+:1096B00007E24BE8F76ABF42FAF59AC5501ED5AEED
+:1096C000B9E25392E3E60AA39D69F51BEB7D6F9225
+:1096D000D03B63D9D868FA47F0EEF0A19D7EC6E78B
+:1096E000243E06EDFEE30A80AFED36339CAF358EA7
+:1096F000CFEB0C620AE3A23E3584F1922D88077805
+:109700009F5066C467A2CF88BFE439467CA4FA8D17
+:10971000F31FB678A4A13C237099A13CB3D66B800B
+:10972000B31BCA0DF5476CAC32C0B9C12B0DF54760
+:10973000B52F34C0A3B72D35D41FD3B1D2503E3688
+:10974000B4D6503E6E4FA3011EDFF95D43FD895D27
+:109750009B0CE545E17B0CE5C5DD3F30C0937A1EEF
+:1097600036D49F7C62B7A17C4AEF5386F2A9A7F654
+:109770001BE0697DBF31D49F71EEA801AE642F1943
+:10978000EACFB4FDC100CF72FFD950FFF2F4770DDC
+:10979000E557E81F19CAAF2A386BE4D7382EFFE621
+:1097A00079FE69F84EC90ABC3C096D04F5B4867CA3
+:1097B000DBB24C61C9184FEF5E644339F08A9443C1
+:1097C000820F9F47FD8CF5F3580ECAB3596A4518AE
+:1097D000D7ED992E85D67FACBED33EF2FB309EC727
+:1097E0007EA57830CE96006A4B8BEA3FD16703475F
+:1097F000320227CF711BE0547FBAA1FEB0C5BAA1D7
+:109800003C23506028CFACF518E0EC863243FD11C4
+:109810001B7D06383738C7507F54BBDF008FDEB65C
+:10982000D8507F4C47C0503E36546B281FB7A7C155
+:10983000008FEFDC68A83FB12B68282F0AB71BCA3E
+:109840008BBBB719E0493D1D86FA934F840CE55355
+:109850007AF718CAA79EEA34C0D3FABA0CF5679C07
+:109860000B1BE04AF6A2A1FE4CDB6B067896FB0DC3
+:1098700043FDCBD3DF36945FA17F602897F6CD55AB
+:10988000059F1ADF0B7B679EE71F86EF83553E8699
+:10989000FC11DCAF785A74C60A4B47927D0172BD49
+:1098A000D7AEA27DE4A7B851122608025F26801029
+:1098B00043BE4257A186E24F2914F725D5A463BEC3
+:1098C0000FD8090024997273D19E8E8FD86D5917C5
+:1098D0008A2FDD6E2B2F65C4E73797062696A6A242
+:1098E000BFB26F36DAED37B3E0661C07E8BD845EC1
+:1098F0005C1F76633C433EAFB0015EA2FA7BD1BEF3
+:109900002DCB7B11BFFF0ADB69AADFDFAE8873288E
+:1099100030BFC6A8F6EF07BF4203BB6E5B13AC1B9C
+:1099200070187FD0E426F8A1A674827FD4A4D3B3A4
+:10993000A3A9809E0F3779A87C475319C13B9B7C14
+:1099400004879AE6D07377939FDE3FD6B498E027DA
+:10995000C08FC6E71EF0ABF1F914F8C758BE17FC6C
+:1099600065847FD114A46767533BBDDFDFB48DE00E
+:10997000034D1D04FFB22944CFAEA63DF4FC4D5368
+:1099800027951F6CEA22F8505398E0705337C1476F
+:109990009B7A083EDE7482E0179A7AE9D9DD748AF0
+:1099A0009EBF6FEAA3F2979BCE11FCA188D7AE2988
+:1099B000E5F12289170933564DFC20EDC3F968E71C
+:1099C00023739499FF66B0F363ECED587AC87ECCAC
+:1099D00055181384E7F0FCDD2D517ED6ADA2BF2DC6
+:1099E000712C68077E6F3671BFB63989519E351369
+:1099F000F6EB1AC1972C85DBADABC5B8D688F53030
+:109A000009F9B380F8F3E5AFE35748BFF14C61A023
+:109A100085F833DB1424FFD911CA47FB39757C6004
+:109A200073E924DC6FBCE905EACFEDA17DC779D6E7
+:109A300070EA75181F7951A578DE50FDD58BFCF1C1
+:109A400021CB0F7D9085F6F69C2FD500E2E915B36A
+:109A50007331C60BB69772FF747BA9C9F0FCC9F8C5
+:109A600040078EE77367C30D2618FFE7D3373C71B5
+:109A70006B6EC49FBE1A5D52F0831630DD4CF989BF
+:109A8000CCF77C2E34750D1858085FC782F4CC2AA9
+:109A90000CECC2F92E01431CE140B93567B079C521
+:109AA0008E6BAF18D75E311EF97C717CE0696CEF6C
+:109AB00073A78FC6F5CA94CBF3715E725C71137491
+:109AC000719EA16F278EEFF3E73E3DA98C8AE05F80
+:109AD000FAED9B2B455EC90685C7E5A4BD26F2526B
+:109AE000A4DF5173BB12427B7D19F83BB8BFF4A6CB
+:109AF000B03FDFB473FD7CA6C15C80767D8D12E73C
+:109B0000C17DB8330DFFE540771AEA33DC2769C120
+:109B10009C03286FB943A17CEE1A68C704EDD4609A
+:109B20002010BFBB4B21FEFB627C2E8DAF06CC3FCD
+:109B3000F2B352FA7270BF14F8E545A4C3DA296A89
+:109B4000D002F6F02BA650BE42FBD237591418E7CC
+:109B50009A14E0939143F3C37A71FE40BE073EFB33
+:109B600003B6F7B75F4F2EA038FEA1293AE2ADC584
+:109B7000C4CF23057FAF7A78BE0B17D5EAD4F11492
+:109B8000A7649AC78371A679E2FCCA11956DDC3788
+:109B9000881CFDBBA0DB2BE9E639216AD7B85FF34F
+:109BA000B1A0E3C7A2DEBCA32F66E3F9ABF5DD6687
+:109BB000B24758496FA1DF39C87C366EFD765E1416
+:109BC0007FD777BDCDF335586F61747EBA6B326F36
+:109BD00057F2936A71067639A2C7D7CFDF9F117FFC
+:109BE00027027F8F22FE3E89F6F67CAB9E701D3CDD
+:109BF0007B01456178067EEAA67C239977B48AF9D1
+:109C0000E9B906D801F9D91F7CC082F85FCB3AE9DF
+:109C1000FDFAB21B7310AE677DD5E9E84FB4373F4C
+:109C20009F0EA35CB4ED8159189F5D185AF13C3E1C
+:109C3000173CA69C44FF15D6877932C64F9486B64A
+:109C4000E1D0DFD2BD956D99F07EBECAE9C15EE27A
+:109C5000F400BEF1A94903E709EBC13999E6E1A394
+:109C600079A8AE3986F550B389F9949448FE7CFF03
+:109C7000FA28BBE5AF99E80F697DB4FF5E7FC89A0B
+:109C800084745ECBB8FE8EC43FA4DE66C4E7B7B072
+:109C9000380FD6FB50F0F587D98CF8FA43051C3CF9
+:109CA0006FC49E64398174EFA888FEFDD0142A75B4
+:109CB0008D22FD9C87F37D217D918E71B35B526C6B
+:109CC0001E15CB1343397C1FB55FCEB30BF191B892
+:109CD000D7FD661E878A1D9752F6C23FD07EB05AC6
+:109CE0005810F737607DB3525CD7C32DB4AE5A100D
+:109CF000B5183FABF2EB83B5DF2ADAEDFE82FBC18C
+:109D000041980F9E971CD08F5BF413C7FB917A0488
+:109D1000FB233992C60CFDCDC22417A0CB2B4E1FBE
+:109D20008DBFD9944872E7E311816AA4978CFF48EC
+:109D3000FFB03BF7FD3CF2E3CFB764A19D0EFCCB37
+:109D4000F312A773F9F48A590F22FC4A652EC5FF56
+:109D5000A5DCBDBA8CC7CBAE96F1B18A98F8584C49
+:109D60005C86550C1E2F63CC63C67EC7B237257E3A
+:109D7000281E73B44223BA0781EE186F3E2AFCD422
+:109D8000CA78EE9F774E4E267E4ABA226FD07D1556
+:109D9000F9BC47C457EF053B8845C5D5EF2969B4E1
+:109DA000619EC1964285F6BBEEAB8AAB8DCE73DF6A
+:109DB0003BCDCCF753A757EE44BC153A4255A4AE61
+:109DC0007D9A8EF350C4BCC6B901EF266CDA2FE23F
+:109DD000A41E1B8F4B5593BE96F4BE547DFD941666
+:109DE000DA1487F34E61B4FE9C1D7692A36AA72F06
+:109DF0008C29D75F4E5B7827D151F317603F474AD4
+:109E0000E39803EA7F7EC442FEFD21D3CA9F623EEF
+:109E10007CDF1B5686FB9E9DCE4C0DF545E71797C4
+:109E200055D3D3397536E371CE7813088822377B42
+:109E3000F4DF9058E2DC59A7C2BA19C5DB7CF126E1
+:109E4000F0C13A4DECEC0C18D77E87F7C189C4728B
+:109E50007E15E7D95511B81FD753296B20F83E8BD3
+:109E6000BF7617F47B5F928DF8C45FE17F808F939C
+:109E7000B5CD85F14D9FA9303CC7DB6601B95C8843
+:109E8000719238BE27C5B87DEF3F974FFDEF98CC54
+:109E9000F7F95AD37D3D78606448BCB9B5BEFEB8C9
+:109EA00008F15B16C5F3241EA3E9E52E35D02B601F
+:109EB0008EA65719D06B7C34BD7CCAD7A1D7ED983C
+:109EC0005C3669207F06ABF407AA4BB85EC314B9B1
+:109ED0004A6B7621DAEB47E2320BA3F7F5245F4AAF
+:109EE0003E1D843F371C43F990A5B9317E6A9D170A
+:109EF00047FB2D925F259FFE754A3FBF7ACBE1B9A4
+:109F0000CCE19F853224965F311E16CD973543F202
+:109F10002F7347AFD7F9603F2424A1DD73EAB1CE98
+:109F200028BEAC69F854E3F2E3C28CB8D248FC6EA8
+:109F30007E85C2DE89A62FFC7BA740CC8FEC1E8DD0
+:109F4000FC2D89C74BC5B7F95BCD0568C76DC6F356
+:109F50008980AF76C5E31B8671AD86B76FC5F76D97
+:109F6000E27C70B0D0C2ED2BB14E647B5F4EAB7A19
+:109F700007F9D639F974FC6AA8F7799A4947E4B425
+:109F8000E92BFF8DD6DD897886DFB9927B6A1FA524
+:109F9000753486E1FEE0E7370746E07EFDDD40A749
+:109FA0007728993A34CC447B59BDC3701D0172D3D4
+:109FB000F93390CEDF33511E22F83B53460ABFC31C
+:109FC00027EAF752FDBB2DDB6C71D84FAECDBD3B00
+:109FD0008ADF6788F83A1E23E7FB672D3ADA657A4D
+:109FE00019D7BF0F36ED99F6DE681C4FE7B4F7605E
+:109FF0003CC973432C007C1C5710D43105C4F6E5D2
+:10A000004C05CF2FB0CB5827F20DBE6F1E1F69DF56
+:10A010005CC6D7990DED15A09F6D53504F8A927F66
+:10A02000369312182CDFE58E291AFF6E13A372DB0C
+:10A03000D1ED749E3F39CFA360DEB36DD33686FB7E
+:10A0400031F6307F9F92E7535645B59B3217C61DB8
+:10A05000C517F3F12401C81BDB6E60CC12A4431CAE
+:10A06000C51F63FB9D9F5AD5ADB986E693587E63A5
+:10A0700082DF24DFC879D2C994A873F9D523B93D0A
+:10A08000DCB6D1B20BEDEDF2B244C2EF672955094F
+:10A09000EC227A6527F041D08AFEB18D9EBBC1BF0C
+:10A0A0000E8E41FF389DE027C0BFC6E71EF0AFF11E
+:10A0B000F914F8D758BE17FC6B847F01FE35C29D9A
+:10A0C000E05F23BC1FFC6B840F807F8DF02FC1BF2E
+:10A0D000C66717F8D7F8FC0DF8D7587E10FC6B84CC
+:10A0E0006758813F703E05C1F48540D7F63B2C3E52
+:10A0F000CC17DC20E87ACC3732D903F4B71798288C
+:10A10000F66D7FF9070CE7634F37D1F9AFCDE93F23
+:10A110006037A2DF5AEA24BBA9EDE7DC1EB16B0F62
+:10A1200032943B3B95602DF330B6B86C6C0DEEF37A
+:10A13000E5A56FA84A02F886B2893B6CB03EF2F5FD
+:10A14000058B9BA360DDE95DBBCF1D814714EED27B
+:10A15000C03361377615EDC0A33F380ECC13AE2B5C
+:10A160002BA96906160A8F646457F4E55A283F67DD
+:10A1700015D26B348E9FC70DAF622DE9B86F39428F
+:10A1800007EF47A1FA619672E9F53794E9F43EF6D4
+:10A19000BB8BD533955C523DA65EA43D2C572ED289
+:10A1A0008E4D5964EB81B16F350B3995EA2039D565
+:10A1B0008E711CC07BBB9D3FBBA7F0B8C1AE2955BB
+:10A1C000DE29F0F44EE1746DB707DD55D8FF781342
+:10A1D000E52DB08DB97F1809FD7DFBF71AC3BC4F83
+:10A1E000C99FED820F468F70D2F97B76A78DF6ED71
+:10A1F0002F1FF1F3D62480473FEAF1607EC356E675
+:10A2000089433E09DE6BA2FCC6A74B46252D80EA9A
+:10A21000E3263D9B8472FDA49037219117D4DCB6D0
+:10A220007A04EAB1CF5FE3F2F0C7423EED32F73491
+:10A23000103D2739C8EE606C1BD917CDE9406CD0B2
+:10A2400091A60CFEB498DD4BB19E050C01CCBFB6B7
+:10A250007C31D9867E5DCB39EB1C9E1FDB43768734
+:10A26000C51E7027C2FB6D4113C98516DD41F96C0F
+:10A270005B1DDE6E3CCF1C749B28EF756BA189F0D3
+:10A28000D8EAB83684F6BCA634D7A21E0BB9F7DBE1
+:10A2900072E17DA8D044798C21DFC2390807031A06
+:10A2A000E559D10F960792E81CF756D6F7D2442C01
+:10A2B000AFE176575BDA7F1F8DC738F7356E0FDF5A
+:10A2C00056613AE681514A9809FDEBDE4DF1388E30
+:10A2D000254CF8AD41F2535D564EBFEF1FB9C23D5C
+:10A2E00092EC8AA8FD2B2BC6E43C360F944F707875
+:10A2F000E7A01FA939BD36CCEF6B757B6D2B68FECF
+:10A300003C2F8DF22FA0DD16B789FC592CBFB190E0
+:10A31000D4E1F1BC529172AFE3BC7F7004F1A1DDD6
+:10A32000C458AE8EE3D382D1FB83B65115DD3ACC4F
+:10A33000A37D7512CD43533C04B39B341AF7703D93
+:10A340008ECE2F3F6899D78DF6E170DB2DB48F95B7
+:10A3500051AB19F69986058C70EA62239CCCB4C87F
+:10A360003E15F4FBAEE09B58BCC5E223C3DDFA1AF0
+:10A370008E3F2340876B078C7FBBFBA1C44A86E3DB
+:10A3800074D038D31C2B2BD17E4A65FE66E4BF7F88
+:10A39000759C13DC0B6DB9D0FF84141399471359C6
+:10A3A000DF266C77ABE0F7F65C4ECFC8BA5239BF08
+:10A3B0004FA9CA9C928AFB042670CC22EDE706C105
+:10A3C0004133EC132419E0D1DB861BEA8FE91869CD
+:10A3D000281F1BBACC503E6E8FD7008FEF2C37D47E
+:10A3E0009FD85565808BC2571AEA17772F34C093D0
+:10A3F0007A961AEA4F3EB1D2503EA577ADA17CEADB
+:10A40000A946033CADEFBB86FAD29E8FD58FA953E8
+:10A41000BE991D6F4D1F6EB8C726D64F88B5F36D18
+:10A420005FB6E89B909F5D16E2670DF539EE2BDF76
+:10A43000C1FD21DB748F8EF2255EC8D357A6FB4683
+:10A4400022DD2A5D36D20B9A83D7D31CB3C95EC9ED
+:10A45000E9B0D0FD3A9A9BF597C7A37C6E0A4ECB24
+:10A460001B1D19B7DDBD8DEEA9A874CD61987724A9
+:10A47000BFD7DC3E1670627F3AB793DC41AA67D73C
+:10A48000E1FBA8791C32999803E538F86D181F197B
+:10A49000CA4F93FE99F4CB86F2C7A41F96636271EC
+:10A4A000F8DCA5F4DE8A7E7A61C36B55C318F96BBC
+:10A4B000D5A847EEC3F3D9E8A74DE076565BDA9509
+:10A4C0003AC66DDA733BBB47E278524D141705BBB1
+:10A4D000D9B330CA5E5C2FE8A98D6CEF45FDD798E3
+:10A4E00068D3D15ED26CBBA6BD07F8DA69EE7D12E7
+:10A4F000E310AD8A7B5D27CAC53B1C94EFF1A0C079
+:10A500009BEE34156F82763B9B7D1A9EC3EFBC9BFE
+:10A51000795A717DA4546E4A84F7A3B3569830DCFF
+:10A520003326AF79133E03C25E1E5BB8CB940CE5B5
+:10A53000E34A2A17637C4B75437F178937ABAE0E0E
+:10A5400086F36179DA49E42BB4EE2FC0D02B936CFB
+:10A55000B4FF68477A2BF4243CD8CF39427684F391
+:10A56000385EEC3E2514AF70BB15F3E52A933A88AC
+:10A57000BED29E453B17DBF75704D6231FA5CC352B
+:10A58000D255B33D46F8D86AE2EBA23D517F19F5AA
+:10A59000737B6E5E12EE5BF5CB112157EE10FA5312
+:10A5A000BE9772E523F41D5223F60DF07907C6D944
+:10A5B000ECDA363A7F69BF6B1B43BEB6E36975B20E
+:10A5C000F783BA9FF487DF906F563D72B10DF5F5B2
+:10A5D000D9142FD9B3F68DBFA4F1C5E2CDDECBF3EC
+:10A5E000CE86C2AB2BFF61D2EF2080753CB77334AF
+:10A5F000CD511B1DDF94CF6421F7CD323F083C09BC
+:10A60000D4676765FE912F9E8F2F91C3C7F297D2B3
+:10A61000F86E4DF50EBB98BD6D077F331045F7BB47
+:10A6200035BF0DF1D0767EC11C9AB7468B816DFD8A
+:10A63000A27017C58D85BF942CF0AB233E018F39D6
+:10A64000167E5EC0933297EE2D93718FE7A724514B
+:10A65000B927C8541EAFEBCF4F375D984863D52D4F
+:10A6600052EF9229CBF514FC7F04F35246B56BC62A
+:10A670007C76A1C7A59E1EBDCD583EA6C3088F0DF2
+:10A680000DF8FEDF51CF5FC37F073D602C7F58E898
+:10A69000EB6B505FE3BED5B7785E880D467481EBF7
+:10A6A000D988DE033990DD19AE44B199759B66C82F
+:10A6B00027191EA30FFD153AE1CBDFAD9951CFCA83
+:10A6C000B84CAC1C56EE3CBD01D74B657CBC8EF241
+:10A6D00013E318012BF7CB03E0A7DCA779FE548323
+:10A6E0007E55B74AF952924EB1749D5A2EED5CFFD9
+:10A6F0001FA7907FDC5B8CFE3AF61788EA4FC6579F
+:10A700000E4D0FBC89F5649CE5CC1CED79458FC4DA
+:10A7100051645CC03B85AF9FAD9ED71B8EC1388E08
+:10A720009DB0520C6496FA727713E643656B24BFB2
+:10A73000DC93D7FD14FDEFAA3F4339CCE398AE0F6D
+:10A7400023BBBCDB4C71802AC1C755C2DF92F19696
+:10A75000CF843EE99B22ED9C601CF7EBC37168BF80
+:10A760008EDB03B2D748CF785ECEE36AE33B63CBA0
+:10A770007D94A77499E017CC2FAB4CC3B42E0E7701
+:10A780003225D90D749CB8B8F728BA0E852F3E1F14
+:10A79000877CB8CFCEEDB5A7043FA431C58379F847
+:10A7A000697B1C9E10D473AA6C5F0FCCC3735C339F
+:10A7B000E4934D3868840B59149C8BE330C2F7EA5C
+:10A7C0000DB8C5CCEEAD019B1CA6EC28177947F956
+:10A7D0002C1FF96B96EA2842FFA9B1D2C110AFD65F
+:10A7E000B7C7FCB807E5C56BFC7E2A77BCFE4035D1
+:10A7F0007CEF7E29D9D3AC47E8FF14F8D1A81F7E9F
+:10A8000074C1C35ACD51712DA0671EED23BBA9BCE5
+:10A8100013E88AF07EF0ABF3681FB980DEFF12FC0C
+:10A820006A84BBC0AFC6E76FC0AFC6F707C1AF460B
+:10A83000D837BD722CC6C3DE847AC8177145076C41
+:10A84000A3309EED50E97C4D2C3F6E6978D7711D89
+:10A85000C8AAA91DD97353911F6E53E91CF2D8DF02
+:10A8600064CF45BF353AAE161D578CC4D57A15193D
+:10A8700057B3027D5E98ACF3BC45195F0BF0F8DA74
+:10A8800057B7E393ED50BC72403BFD714B5BF0BD9D
+:10A89000023C9AA5B00478FFF11DFFF904EA99D4AF
+:10A8A0008CC0549C77DDA4772CDCEEE6E7A6B2C41E
+:10A8B0003ADA61E779A35922DF27365E397DE6DB94
+:10A8C000B7A602CAE6978F5986FEFFF45BDE2ECE4E
+:10A8D00001F887E53F588679BDD37FF6F633998036
+:10A8E000A77FFE66112F7FF0EDB3591ECCBBF8DEBB
+:10A8F00032CCF3752573FDB6439C3F92F8BD5EAC38
+:10A90000F7FA8D8F921E073B83213E5AD2FCA45F3B
+:10A910003F49E973AD80FAF5A97D692B2FA20FEAB3
+:10A92000373E41DFEF503CA74238EE29369E5F2A82
+:10A93000F4CD19C1BB52DF34DA3928C7C3583ABD48
+:10A940007F50C481982F93BE4BB673F898AB9CF49C
+:10A95000D2FD55FAAB3ADF9F24FFF898EBB2EF63D4
+:10A96000FE5CCB1C8DF60D1F7478EDA8B7368B7985
+:10A9700041FB41CA539965A3FD1C96B298D67592C6
+:10A98000EC27A586F20E92C4788E97C785313ED00B
+:10A99000526DDB8D72F4078E91D45E4B99258871D0
+:10A9A00019096F2A87F1003E135D49B9D49F90734E
+:10A9B000326ECC70F70CDAAD12D3AE92F90C36F3DE
+:10A9C000E968FBDAC17A887F3C265D45FB3079AACD
+:10A9D0004EF2AB987916E37B8BD2104466C479981B
+:10A9E000A2E7A1571BE7A1CF32CC4369B485D12E92
+:10A9F0006C9905F380FAC79DA534DE58BAC9F97C75
+:10AA0000B79CF373EC3C99D83792E704AADC15079E
+:10AA1000705CB34CBE561CD7F3FFA849C10B23672B
+:10AA2000B3060DDF8F8AE4EDB47E9DBC88E9EF2A82
+:10AA30007C9FEB160BCD6FE7348E87872DA15C3A98
+:10AA4000C0A18532707F77283EEE2AE7723FC2C7E9
+:10AA50003E86EBAB25C9C7F9D8DDE76A463E4EEC2A
+:10AA60004BDB44F30A0F4A9F587E8EA5D731BC13A7
+:10AA700081F4625045FC7F157D255D63F7BD24BFE1
+:10AA8000244F754B7AA7D33CC33986FD4068411FDC
+:10AA90006C1F7C33B4A747ED9F59D2FD64679B536D
+:10AAA0003C05186F6EF9521DF47CE45981A7665776
+:10AAB0001CD9DF2D2E6E7F1F715D69F09BAAC18F9F
+:10AAC000C2FD62359975E2BA521396521C4D1D862D
+:10AAD0009617B185D1AE4D98CBED5AB7F7A2E7A442
+:10AAE000B45ED5707FDA00BB36E94A6ED7BA2C6403
+:10AAF000D7EE705A16EF1A44EEBC54CEFD9F2338A1
+:10AB00008F41FC46F017299E29FD458B3B407E9FD7
+:10AB10009CE74B82DF657DABBB81617C4DB5787472
+:10AB2000B46355718E15F3970BA2EC02D9FF0BE5B8
+:10AB3000FC1CFE33D339FD641EFBF4579586C1F02F
+:10AB4000AE4D9576C9E07CF72FF00DC909AFC3E291
+:10AB500043BBC3EB48A77CEFA1BEC3ADEA53491189
+:10AB600039E3F9B254257DA479287FBFD3DCFBCC2F
+:10AB7000ABE80F3EEF20BD23ED71305629FF18FCE6
+:10AB80005E9F071AD9F74F5889A688BF0BFE57F664
+:10AB9000D4A8FDC7A38D2769FF27D64E8D8D27F436
+:10ABA000AF73D713B97C1CA10C5CB74A63D930E4EE
+:10ABB000A7D8752E9FD9E9C597AD8271656714D165
+:10ABC00053BE7F84A97306BB1FADA41FFF5C3F8FDC
+:10ABD00085CE1254D2CB2553818E1FDFF67A9A4749
+:10ABE000C773B49F927E3ED35096B005F9BC2089BE
+:10ABF000E46A96381F26C79375F391C42407E6E9E3
+:10AC0000F58DC5FCB65093FFB26A33F917BEC1C6C5
+:10AC10001B98CAF5110B8F60D1F7FFE8293D578CBF
+:10AC2000017CEB0E9347A775E526BD27D77FA59638
+:10AC300058ED06FECE6E621E878E5723BB291E96E8
+:10AC40007D41253ECB3EC6EF6F1E91D2A7E0BD5B96
+:10AC5000FDFD883C26B9AFF2594335ADCBEC618C94
+:10AC6000F550DCD24FFB0F9FA58417E0BAFEEC2114
+:10AC70003EA2EC478DE5A06B295EBDFAB6B8900EFA
+:10AC80004D8FB80BC687E3F9A9C2B272711CC772A7
+:10AC9000B760BCE757F114EF513BF2285EB32623AF
+:10ACA0003007F9E1E390FE6DD3283159A857F79D9D
+:10ACB00038BA2F6087D27305E54BDC6E628F0F12B6
+:10ACC0008F5A3395FB89B582CFB3D34B39BDD34B64
+:10ACD0002E5B957CE9EBE887425E6F4D08D1FE9CC8
+:10ACE000CCFBBAD73C385FBD3ED524E89463C8039B
+:10ACF000B3A1F703FCA22AC2DEDBF3D4534FA53184
+:10AD00007E847024DF878CDE2F8ECB0B51619CC735
+:10AD100047724771FBB87C7537A40781BFB77CA128
+:10AD20000EDAFFA3827ECDD9DF4EC7FAD5BA879E51
+:10AD300047B24B4FAC00FC391C16668D92BF924F48
+:10AD400062F57BA373E445FD770BC861FD22F10535
+:10AD50008BC8EFDA7C748A0DEF07DDECF0F6A0DD2E
+:10AD6000B5D991E2A5F8BB03E445543CCAE178812A
+:10AD7000F8D0E1E1713A07CA5D8C47E1FC0B71FC48
+:10AD80002FD0FC65BD26217F1C9E30ED93DA3DDB84
+:10AD9000A89E4DF3D3F9385B0AA3BC059B9BDF2B20
+:10ADA0001A976762B641E4F0C6A9DCFFDB5CE8ED08
+:10ADB000A9A2F169786C8A6D4EF7A6931E443CC334
+:10ADC000F7C79CA509D1F87956C88396237C7EFEE7
+:10ADD0008D19EEEA62F467FD7B511E6C76ACB4E12E
+:10ADE0007D5DAAB3E4A2ED1C12F48AB4B33DAD3A82
+:10ADF00099DA7916F95F757ADDD88E59DC8F3A4089
+:10AE00008F89717CD3381A6090F274082F4498B0FF
+:10AE1000812EB14F07C6C39207FB8ECBC55CE1B74D
+:10AE2000805CFC138EBFAEF09D17F81AE3FE4AD289
+:10AE3000153C0FE80C7036DE4B159B67116BBF4855
+:10AE4000BD23F510B4A3623B0FA3FD3226B28E647E
+:10AE50001C27B3D6CFD74B8A9FF805EC191DD78B8B
+:10AE60002AF2F806E8810A8E3FC555A6A3BEA83E81
+:10AE7000DF9B89DF1D729ECAE4F6AB717FF9F83F54
+:10AE80009EB063F967B55517B553E47EF250FBC821
+:10AE9000AEEF7EB821DA4E196A5FF9ABF6938FBA3E
+:10AEA0002C14B7DBA918CFBF0FABE0F22F49CC6F42
+:10AEB000D79480BD2215EBF93DFC40338FCBBC32DB
+:10AEC0003DE0A8C0385ABB850591EFFE519A1E8817
+:10AED0006AE752F12CE3EFC3851D35DCF18482EB88
+:10AEE00074786D48C1F879666DA7E2BB48BDFF1262
+:10AEF000EB59D6378BF667687D2AEAAB196EAE1729
+:10AF000033CF69AC204AEEF44EE5769459D8EDAED5
+:10AF1000A34FDAB1BDA3267F7B3EEA0797497F3C6A
+:10AF20006ABD9B6FF6DAAAA2E6D782FB4283D0D134
+:10AF30005721F56098F4B7D4B766A9275234839E99
+:10AF4000A88FE77C2CED9DFA72EE07D5C7737FFCC6
+:10AF5000C5F4C014C4F327E51FCE1FA5E339D8B04C
+:10AF60003925F7ABF747FAED1B536885F46390FF7B
+:10AF70003BCD7A572FD9592E3A3F21EDAAA29F29CE
+:10AF8000A3B09E47F191FD37096F1A5171AB96DB63
+:10AF90008360675D5991CAAFE48FE6031673AFE033
+:10AFA00050F3F4E27DA6A9180FECA178ED7DE795AA
+:10AFB00041CF41DC5721EDA5FEFD4143DC3553E88F
+:10AFC000BD4C51AE63DC3517F7BB8C71D1E26E23FB
+:10AFD0003CA9C7084F3E1113670DFAFE03CFF96174
+:10AFE0003E0136BA03D61FCA8F55621F342B18AAEA
+:10AFF000C4F3E1D9AC93F61B336B930CF89EAE8A85
+:10B000003C0CBCDE588E137E32B5791FE0F79BFAFC
+:10B01000E7156486BCFEEA55DFC6AB30D9367EBE86
+:10B02000CF069D23BED65CB17016D27B40FCB6C164
+:10B0300018B7CD8C2E073CACDE613C27E8F71591A4
+:10B040007FB0E85BC6F382321F1DE79BE91DD8FF86
+:10B0500057F70BFF9206F62FDB7D18E412C95D71DE
+:10B060008F703616613B5A58C17DEFE10D8CEE139F
+:10B07000CEBC8DF906DB3F3820F0158B67169C415E
+:10B08000F89B29DE0D77F03CD5E1B799C84E1C0E30
+:10B09000F282FECEC03AF03500CE5CA7939D797562
+:10B0A000AD89A1DE60E79B0CDFC37029BE2AE9FEF3
+:10B0B000B083E7E166D7B19009E7D37019AD331AD1
+:10B0C000D7C8083F00BE0CF7095C5D663CA79B1D16
+:10B0D000733E57F24166CCFB6B2ADC867501FAEFB2
+:10B0E0004005C90FAE1747A35E84217D3CE5C4131C
+:10B0F000986F377D13E3F7D924C6F1FB6C22FB135D
+:10B10000EA05E0D7A3B6990568C76C75C799300FF3
+:10B11000E25062EF4F5822F88D152C589D85F71C90
+:10B12000F68D53007EBDA27E67FB3428B7F73D8DB8
+:10B13000C16587E3DB37CCC98EC02ED73D04B3325F
+:10B14000A6E37D4098738AEB2ECE7DE51EBCE73AE0
+:10B15000AED041C1CA3866BC77A7B55CBF17F3480B
+:10B160005A479BC4F9E8A87298C78C696E99FF4644
+:10B17000F9786C0ECF0B886E1FF3B2876CFF4A68AC
+:10B18000BFE46BB46FE3E34FC357A07FD270FC18EA
+:10B1900017C7F691BE18448AEE5FB4A7B1E02EDC63
+:10B1A000CF81FE1C0AEFCF8D792A69CC9897D0DF2A
+:10B1B0009F1BFA1BFFFF603E8B07D2C37C317A2CAA
+:10B1C000FD7AF46835F968BCC1090EF28FF0FE2AE9
+:10B1D000BCA7CE2EFAB38BFBBA10AFADA511BC82C3
+:10B1E0007D48ED42F5E60B02CF987798E6B6109EC3
+:10B1F00087C2DB5137CF93BADB1D176ACEFDFF4004
+:10B20000AF744EAFE8FED0CEBCE4FE96427F2997E5
+:10B21000DE1FE217D74F3F7E81269BD22E1DBF3007
+:10B22000AAE0A5E0F728B46B8AC26B241F69BB1B98
+:10B23000FD05BBD96FC3FCCCB9D312697C85290B42
+:10B240006D949F90BA90F28DDB0A1DF4F705DAF247
+:10B25000BE653347E9E9B6C21A2A87FA94475518FA
+:10B260008EC3F0051BCF7A283E707745753AFA8B6E
+:10B27000C1069E9725F394A43E64623F94E6051FA1
+:10B28000264C3BD07714EADFDD504279680989FF0C
+:10B290004DF9575B6B3D1E2CFF899DEF6BFE48EC13
+:10B2A0006B21A3527C6D42F9A3B8BFEB1DDDA8D082
+:10B2B0007EE6BA8BEF677A3FEDA9C23C2EB682E7F5
+:10B2C00069A5D76831FAD0B86EB7225E793E554885
+:10B2D000E1F835B4B7695A2AE1EDEEBCDD0CFFDECA
+:10B2E000D033D0966A5C5F26CC6B8A5D8F9AC54757
+:10B2F000F78BB146138D2313530540C579C7CF4D46
+:10B300005F01EFB36ED2E81EDF618577517E13587F
+:10B31000FF646F1416BE5C85F08079AE32CE237662
+:10B320005EB1E396F71B4B7A793FF5C4A3DFE51DC9
+:10B33000BD90F2CFE847AE7735663E6027DB534CD1
+:10B34000740F5C5C5ED4BC98A19EF0EBFE67E106D6
+:10B35000D055B48E62F7C9FE0F3F2F64651E9B85E2
+:10B36000BE93E76BF8FEDB705C3B48F71CC6F3C08E
+:10B3700063BF2FE5DFB374BE1F678D63363C5FA3E9
+:10B38000AC8DA3B8A6D50A309EBF11F78C3D2CE238
+:10B3900070CD0AD332BCD1FD85298F5EB55D95870E
+:10B3A000FEC451DB22379D6B13FE9539D14F798C4A
+:10B3B000AC20C9E0A71E15E7D31A6FCE1D8671BD5C
+:10B3C0000428EB417F5BF3D890DE329EE21AD57BF6
+:10B3D0003DEAF1DF3EF7C90D36D4DBE81C9733D6E2
+:10B3E0003DEDC39D78BFB05C9FD673FC9E8E7E58AA
+:10B3F0006BA03C11EBB91CC3FBB0F0CFFAFD961467
+:10B40000AD9AEE9F127E432573B7E27795801CC3F9
+:10B41000BD00E2DE8F81ED6719DE87C1EF8EDE278A
+:10B4200018BAFD78C3FD0256F083066F3F3FA67D34
+:10B43000F7A0ED47DA4D36B4DBA671B9114C890B94
+:10B440000D16F7FB725AD57BB8A487CA63FB629AC4
+:10B45000C8BFB78144C37D29C13F5BD21B28AF4D14
+:10B460008DE3FBA8661023C84FC79CB53C1F23CBB8
+:10B4700098D726EF1569C3FB42A0BCCA61B4D72B8D
+:10B4800059DFB1890AFAAF467B7D3A4A52DCAF6296
+:10B49000B1767C03ED9B9AB38C72A143AC1793B346
+:10B4A000A487F2E0521D94E73054DCE1CD2646F942
+:10B4B00059E6787F03EABCB4E9DA88B632801338FB
+:10B4C0009FE54DCF588E71DE37053FB7811CA0F345
+:10B4D000A38DC376A951EDD658C2A351AFD498F825
+:10B4E000B900FA81FEDF4C1D4EF1D7D87EE5BD31A3
+:10B4F000125ED6A04CCB8B9ADF9B627DF4F7776B04
+:10B50000E62EB46BFBFBB38627517FFD7946A2BFC5
+:10B51000B46FD6DF5FC4FA96FD2DFBB6717ECB2CDF
+:10B520003D34BF65E2BE52D9DF5F707EB9DFA03F18
+:10B53000911FD6DFDF778CF35B66EDA1F92DEBF77A
+:10B540002F457F69DFAC3F99FF60B536D4223F0DB0
+:10B55000950721F31F2677641AF21F5830736E6522
+:10B560001E630F289C2F561D1AFD53E48BB3731BCB
+:10B570003D64A7087F8FCE0BA9745E88F4E8D55987
+:10B58000DC0E91EDEF692A63BE313C4E84CF820A16
+:10B5900085CE238C2D537CB8EFB603E407DE7FB74E
+:10B5A00013D63996879AD2E9B9BB49A7E763E05F1A
+:10B5B000FA282EE621F887D379DCE5810CF792553D
+:10B5C000687F54C6F17CEC8AA960D946FC37582FB5
+:10B5D00047ED98F7782D2BC27368F91D1C9F29D56C
+:10B5E0006974DF7D5CD1F19E2680B794A93AE69913
+:10B5F0006FD1078FF36C9BCEE3BF5B441E6510CF0A
+:10B60000499252017F12E6BF5C908AA973E9FCCD92
+:10B61000D5DF4924FBA6E65BBD4E378CE306A5E8E3
+:10B620003FF2001F7F15F6CDF29C2B491EC4FAA7EE
+:10B6300029A8A94A30BF500D85E0D745CE45E4DFA3
+:10B640002EBA86B124F8FE6AFC0EF4D4ABC23E7A60
+:10B65000A5D7CAD0FF0B56F3FDEC1BEE32FAA50FAF
+:10B66000D8C36EB40B1F284A61488F9ADB8CE55B08
+:10B670002C7CBD2D8AF153AF8EC90392F71F6EC18A
+:10B680005FA7003EA78B7B5F441ED055D375AEAF3E
+:10B69000B39228E95B9ECFB45AD9A0FB94B2BDBD4A
+:10B6A00028B750CEA6F8080F326F8EA97B8BF07B9F
+:10B6B000D99FFCEE61656FC6C5E2A960079EEC2DBF
+:10B6C000E0FA1EEDF5DDD38DF94A67E78EFC7E3595
+:10B6D0001B8C6FFB348C53C8F1FF6FF16BCD743E44
+:10B6E000DF57677E56C2CFDD65B1E8F376321F6C57
+:10B6F000513FACD17DC2321F90A5F71522BDFF7D11
+:10B700005ABCE71EE23F618F84DF305D88FFFAEDAF
+:10B71000F58F23DD976D38BF2ADA1B0ACF43DD375B
+:10B72000413F51F9922DCD9E743A5F97CAF7DF865B
+:10B73000A7547D80E7B9B0FC1D037F19CF6DB51C00
+:10B74000795241BFE52778DECD1CE917E3C36D0EC2
+:10B750006C37C4E34AE127292E9C551B565A0B230C
+:10B76000E78362E562D63AE3F9B3D87B14E7397A26
+:10B770003545C77D803E3AD7983343ECDB208EB108
+:10B780005E2AB727D54C13CF1F19A173FB32AF2FF9
+:10B79000277A1F449DC1ED8679F1AFDFA683E8FDCE
+:10B7A000C7A1BB96639ED4BC84D76FCB05F8FCA120
+:10B7B000EF2DC73CAA7999AF7F960BF2F6CB43FFEA
+:10B7C00087978F7BFDB39168231E6EE2E5531921A5
+:10B7D000C97438B89CF68766C87B137BE8BC762AA8
+:10B7E0001EAC98F4CD9FAAD534E8BA74CC90714BB6
+:10B7F00046E7B3FD077F7702E5945FC6797DC67D96
+:10B800004F26EE4DBC4AB2578A8BECA52BF177C080
+:10B81000E755E2BE1D932D4C781D13B9CFE4A1AFBF
+:10B8200073DF4EE47C3CBF3FA865230B18EF45F463
+:10B8300009FEE77944723CB2FF01E3C27B0193A2A7
+:10B84000C7B583DA91E3FAA4C81A542646F671E51F
+:10B85000B83E51FA7662D0A3EED82F5720DD3E7164
+:10B86000F6E5E0DF37393EE31DA2E327A97D3B156E
+:10B870004F146CE674F41EDE4EF6544586CF3B231F
+:10B8800015EF0FE0F716B40B3B726B6A20887E3D14
+:10B89000F01BE57106B3F9B986EA12E3DF61AB107C
+:10B8A000FCF59B197CFF7896755BC36B25788FBA86
+:10B8B000C29AA17EFDF9B316F4FBE71DE47FA775DC
+:10B8C000FD81B72DF47719108676D6EFB00CFA7794
+:10B8D000E00ECF5025DD0DFECAF3D9F96D29309E5B
+:10B8E000F5ABF8FDD88DBF4E9C8570E30A9C25FE14
+:10B8F0003DBD7DB3F0B365FE236DF85CCE7A9FC786
+:10B90000737F4B02463FE2FA5AA3DDBFACC168AF7A
+:10B910002FDF06D401BDB67C6366CC3D7EFC7EC0C5
+:10B9200025829E4BD2EFEDC17B0796B098FB018339
+:10B930003C8E743D9F013C8DF19179F8F7A4701E07
+:10B94000EB548AF33E9FBD59C3F370F50DFC5EB214
+:10B95000595D9F5AA81CEAE17E53DA707E0F9E94CF
+:10B960009F52BF5FFFDC2E33C60B62EF095CBE78CF
+:10B970000EDD07BE585FCBF5FB883FCE4A82F7B19C
+:10B98000F7FFD57471FD5EB35109E17DBBD7D71ABE
+:10B99000FD8165ACA70DFD99650DC6F7CB371AE1A2
+:10B9A000EFCD107A6D1C1B87EB63D30C45A373D5C9
+:10B9B000023E9DFDC757C2D07F5586BF6D06F0C9B8
+:10B9C0003A4B7802EAB9AA8C00C1B21CDEAFE77A22
+:10B9D00088EB7F13AC2492BF661EB708D6F17BD9E3
+:10B9E000AE1F600F44D90BEA40B84BCA4FBBFF36BD
+:10B9F000F2C39E53E8EF82576B3E2D29CA4F8EE566
+:10BA0000C35F0BBE7E85F516E2B8F291E9802EF990
+:10BA10008BF8DF7DCE3FBC82F22CF38B158F89D65D
+:10BA2000B1896DC4FBC4405EA05C40FB13EFC9C884
+:10BA3000573B17939C9E6871F3FB76D259F4FAF743
+:10BA40003DC914C4170E1DFBBD2AAB9BEEDB98DF6E
+:10BA500071EFA728E7F246F9BC0FC0F8B68AFBB42D
+:10BA6000B7FE5A217B767DE10B240F87015B60BF17
+:10BA7000EBD3855CEC32DE83310CE5141E68995BF8
+:10BA800048FD66C8FD0799E71BAEA27BA586897EA7
+:10BA90007F3F4BA779A7ADED5470DED92CD88C71C0
+:10BAA000A83D280B53234FB94F704D64FFBC02E9EA
+:10BAB0005997DE4BF7C2C8FDF341EACD46B933A032
+:10BAC0009E8F19F28066A9E75DB8BFDDF8DCA88B10
+:10BAD000E675A836E3FD9066B7F17EC8AB0A8CEB3D
+:10BAE0007B9EC7B8AEAF2E1B65285FE01B67285F43
+:10BAF00034A7D8005FE39F6AA87FDDE299C6384289
+:10BB0000BAF17E48BB6EBC1F32BEC0783FA4D3637F
+:10BB1000BC1F92A574525E9AC516EC0DE878BF0062
+:10BB2000BF8756CAE9712E1B5D2A17576C77E0B3A1
+:10BB3000BDC81A46BAB50FE7FBB9D6176F4F0F232A
+:10BB4000D613F6DA2AE1F9B412AAC2FD289BF01B3B
+:10BB50002FBB8B19E4F89533B91C974FE60BC457EC
+:10BB6000625C768F9EC9F3B67B2EBB587EC5A53E20
+:10BB7000FF2FC2784B6B0080000000001F8B080075
+:10BB800000000000000BED5A7D505457963FB7FB64
+:10BB900075D30D880D281F41F4A1A0262069418C82
+:10BBA0004E6636AFBB81693F3269FC986010D3ECBA
+:10BBB000E816138126D14C91AADDA255863466FE83
+:10BBC00048AC4CC6A452B5AD153399A9711713569C
+:10BBD000DB4DEB362AAEC99AB1DD31194D2A2974F5
+:10BBE000DD4CAC8C0A31E3985D77DD73EE7D8FEE32
+:10BBF000D73C12B23595AA9D5A28EA72DFBB9FE75F
+:10BC0000FBFCCEB3A503C022FC3B680BEF2B01B8B5
+:10BC100097E1FF4B01EED0CF0300A7EB5C16A50622
+:10BC2000A0E2AF9565300DDF45C05186E3F65A417D
+:10BC3000A17EF0A095CFAB880C9B94CCC4BCE7143C
+:10BC40005C683AC04F7DEE65B47E47943900C77595
+:10BC5000ECBE64952BA83F98A5605BE9BB6485CCDE
+:10BC6000E4E717ADF4BC431A497760FBF7FD666F54
+:10BC7000B822B1AED6BA142B5FFF6431B6788EE627
+:10BC800027CDE1343A3B282B5D8B011AE95F199FE0
+:10BC90001F18899971FFE676E60CE2A346F9B19583
+:10BCA0009085FFF82D97866D0036FCBD331BCF596C
+:10BCB00098B517EEE5F301F2001E05F1F3C892986E
+:10BCC000054C004DAD623CFDDCC1BF47D7D45F6180
+:10BCD00095B86E67CAF319BDA3E62C9A2F5D1A9E1C
+:10BCE000AF3E27BA2A53A67D5C8E9D72A8B8330753
+:10BCF000E0BCCF6478AF873C12BFD779BF87D3FB56
+:10BD0000A7483733233AA6D249D0EFABE8B31FCFC9
+:10BD10009ECCA7D4716B3C824FFB1934F6678E7FA3
+:10BD2000FF33958F7B59BC0ACC00011F0ACC54A469
+:10BD300087AD65F3E56AA2FFCD5E46F4FF070669AD
+:10BD4000B8FE07836FE5C95300AC0786F28671BD64
+:10BD500040FF501E2C0068B3C8DBA4695C0E9CDB5E
+:10BD6000902F1D91183F7F7B7FF5203D6F8F30A76F
+:10BD70001D8F1A1818ADE7F784E15E4726ED6B7C3E
+:10BD8000AE66C5C4CFD5AAC8BC0DF871CF69343F23
+:10BD90002D1C66C4F7612B978BC30C9EC5FEDE3E3F
+:10BDA0005B63D8609D75446F94EF137D5690504E41
+:10BDB000DA703EDDE364F149AB8DE4E600DE8BD161
+:10BDC0003DCEAECDA0F5B75A406689F35D2D8E7F8E
+:10BDD00044F7BFB0D102417CBE63A399D3FBC256E6
+:10BDE000335FC7BCE9DF7B8BB0BF0EE52F0D8F7AC9
+:10BDF0007CE38D9345B8EE8556ECE37D3D9B2C5C52
+:10BE0000FFD63DCEF8F854F9D5E4F525553ED7F9DF
+:10BE1000F5F2962AAFE3E4B4F5EBC9690FC96906F8
+:10BE200097D3CA3B66CEF7BA7C929FA7C0B98FF46E
+:10BE3000E7F6714B3E9E7776AFC3B91DFB0BCCE1A5
+:10BE40001FE7915D382EDE2F6CDBC3485FF0F08F6B
+:10BE5000D0BD8A4256D8C9488E04BF7EA6F24B8612
+:10BE6000119641FA2AC567FB503E706B85F8FCBA03
+:10BE7000051A0F54D073615F161C2AD8B333496E6C
+:10BE8000EB5579B499C0DF8FE3CAADE03F9049E349
+:10BE9000FBEF6AC075F6E37C7A3E535DAF6CCE482B
+:10BEA0007D03B687687FE4F31EF51C5AFF0724FF65
+:10BEB000D8C2CB260648F7076D82EECBBB62EBE912
+:10BEC0001E8B66F87F4EF66FE5CCF7DA00ED44681E
+:10BED000F6DB157E3A1F384D44F7804AF7E34B7F77
+:10BEE000F7F216BCAFFDEE74CED786632FC689CFAE
+:10BEF0001DA51210DFED658BF2FD06F2A7B5815B83
+:10BF000025E0CF4DF43BA2A3F58A815E6F50F57515
+:10BF10008155DC1FA248A4426E8FA525558971DA90
+:10BF2000FD01B6F3FBD9CB5EE17CDAF2382C34F3B9
+:10BF3000133FC7D7696A3BCB5A709D872D8A25135B
+:10BF4000E9FCDED4C6CD97CB00DEEE461389173967
+:10BF5000DD6D03FF3C805F773B783FDE5DC0FBFF1C
+:10BF6000DA2DF376DE4CDFDB0AAEB3F6446719D187
+:10BF7000EB78F10B3E37EE73FDB485D301C0CDE90C
+:10BF8000B44595BD1B5133D8F0FD8D01160696388A
+:10BF9000FF865B45E0477BF23EED8713DBBB7EC34C
+:10BFA000ED9CB375B45ECE24B9BAD84BFD40D71F13
+:10BFB000EA01DB8FD04F907C05220C0A709DF5B70B
+:10BFC00072F9FCF6C859AB4C72601AA927FA078FB0
+:10BFD0003220B90C748E72FBF932DE4BC173A7BBF1
+:10BFE000B2395D02D18526C1CF4526E2FF132AFF73
+:10BFF00007EFF98F2CB25FB62EF9CCFDC4C753669C
+:10C00000CEC79DEE912C87015FCEE3BA9026CE4F2E
+:10C010006DEAFB466BB0CC89F31A55B94D7D6F754F
+:10C0200009B9440A5B7C5304AD18D26DBD2A5FCDBB
+:10C030007895A939D88FB0583AEA6D73D47345A270
+:10C04000B693C1259D3D00B8A4E9B37962799B6C94
+:10C05000DB41EB9525D94B3F2E3A3FB15F536B0641
+:10C0600039D1A4FD83FC1E69C5A5F97E837B8EC9E9
+:10C07000FB7011C8C8AF8E100319E5BEFD56396FAD
+:10C08000AF1D7E5A263DB1A58FBC407E01E69A1CAD
+:10C09000FB90BFED415092FDDCA85BE8EDA85BE8AA
+:10C0A000F14C17933EB671BB554EF77617FA4B5CC1
+:10C0B000788EDF17BF97750C1FB759639560FCBC6E
+:10C0C00003D01FDB489F70DF72E4CFEB06E7BEE9C9
+:10C0D00076CFA57933E1592EDF80F24D72957ACF74
+:10C0E000852E712E4D9FD71DBB621D26B98D18EB75
+:10C0F00033F3B816D2BA7D005E233FF747F59EEDC5
+:10C10000BB19A75760772EA7D355D8ED73A35C5EF4
+:10C11000C573EC45B9BCEEF36564E3FCEB7E5F46AA
+:10C120004E6642FF3B7667F0797DA5AB725BB05FF0
+:10C130004F728FFB5D8B786C44E70DBB85DE69FB2E
+:10C140007D145B974BFA536319B13AF1FD8CE8C546
+:10C150002C8AEB6A0EAFCE25FD9BE89C8BDDC22EB0
+:10C16000B5776DD97C3957C88319F569B3EAC70229
+:10C17000DB6356A2FFE62EE0F23B78F0830ED2DFBF
+:10C180006BD10C07F9BDAB47328264EFAF1F4D0B8B
+:10C19000A32586369277B467572DC3DFE3F1E361B9
+:10C1A000B32388E302473F7D81F4317010B511D786
+:10C1B000DD1C7D7A94FC5B5B74D91589DA5F7DB3F5
+:10C1C000FAD0DEF5237E5FADFF69B74D26FB794DD2
+:10C1D00012766273E40D1ECF6EBE7DA3D25741F777
+:10C1E000FCCFC564CF02FF746331D9B1C09B371651
+:10C1F000D3FBC0A18C4EA3F8A4D563E6FCD7FC63A7
+:10C20000C93949491E97ADFAAF929E67BDB3917E79
+:10C210003567D738CD72E27D4D99C947E36BDEAD06
+:10C22000CDDD9434AF272E79E9F9A2B3B5191B936C
+:10C23000E4D2EAB1A87608B51AEDCF3A9586EB0AB2
+:10C240007E123757525F0AAA7104BBC3E36D902573
+:10C25000E47313FD87AAD81797783C136C3587CB06
+:10C26000F07D53DCA4D82BE93DCE4B8A33007C2BE8
+:10C270001610BF7F38DDB953E6FE1EBAA9FF545928
+:10C2800098FC3D046D43A54971D0BAB829968672D1
+:10C29000D3184D8B513CB42E2E5DE47D353EFAC84B
+:10C2A000F1FA8F67038F8F2E27C739180F5DD6C716
+:10C2B0004B3085CEABC54BEF515C85F16CF3D69816
+:10C2C00085FC15C649BAF18F367EF70AA338A94B0B
+:10C2D000FFBC242E991EC47B96A0B92332F4C59FBF
+:10C2E000B7917E687126F16BC040DF2B553DD1F4CC
+:10C2F000A8276EE27CE889BB6DA5D8CE53DF0F3846
+:10C300004C10C4F57BA2ABF7318ACB6E3F9C41F455
+:10C31000EA39B70AB693BE3BDCB6329A77FBBBB6B6
+:10C32000B51509F918673F5CAA7D1C8B078CFDDCED
+:10C33000272E35AEFA86FCDDE53F177FA7F83F25AF
+:10C34000FB5DF19ADC44F121DEE71E8A6753FD8430
+:10C35000667FB5758B543E8FB7BF5778FC82F92F37
+:10C36000B7BF456E998F9B116DC8E579F1B935B9A5
+:10C3700072E6F8F5E7484E534EC5F8F5B5782D103E
+:10C3800054866C94C72866AE9F81352CCCA8EF6389
+:10C390003CCE0EACB784E9BD769EF81AC6C7AD7523
+:10C3A000B2B09D25E23F2D3E1C7BBF08DF9724E203
+:10C3B000452D2E8CFB18CF83D62816FE7EDE4C7FB3
+:10C3C0008EBB86EE67E7CF6B968A75D10E0C517ED9
+:10C3D000F4F0F719703BA0C68B9A7CA6C6939F45D4
+:10C3E000E74C852F892B5E56E552D3AF99297AA168
+:10C3F000F9A97AD54F77909FAE263FFD8595F460D9
+:10C40000A2B81BFDF45C379F077CFEA277259F51E5
+:10C41000DE7D585D77B1C6B7F809179DB718E2DB26
+:10C42000285F9CC87FE6794C3ABB90FABE7E927A30
+:10C43000DCA2C60BDF941E37ABF1D7FF753D1E8B18
+:10C44000FFACC6F7BCE976FD15C96FBAB933EE2269
+:10C45000BDFB17D43B79FCB8222D9F9440C79FA108
+:10C4600062AB89F29E40ABC00142D9F2199E9FBCDB
+:10C4700065065A67F3AD421EA73D762B9BB7A142D6
+:10C48000107EF4C9128EDB3CF6DA598B82F39BB630
+:10C49000B285840735B5EAEF139AAE709C2D788487
+:10C4A000F1783954D87F92F42AB86F8E4CEB37D399
+:10C4B00065090F69CD0EEF20FC82709C7BE9797ACB
+:10C4C000820EB84FBBFAFC7E15DF819438E0CDC1F7
+:10C4D0000B1CEF090C3020FDB546D17E903D39256F
+:10C4E000F08E8EA8B00B9F74D9B93DF94412F708AD
+:10C4F00074B1F036968823AE449FCB233D1B174F73
+:10C5000028184FE425E289F657DEE5F630357EC877
+:10C510001910FB04DACC61C263868A1733EAB76369
+:10C520003E984F71A22C3F5424CE05616E57141DC6
+:10C530004EB2F72EE1F73F3BF56F3C8F6C3ACC20C3
+:10C5400097C71D4ABC342F11773C1A5ACEFDBF162F
+:10C55000673C3AEBE45011ADA7C6190EFC25FC3040
+:10C5600035CEE8889CB5505E302E9E4889235E7794
+:10C57000EB71C15992C05967459983F0A4592A3D7E
+:10C58000EFEB4BE77171FD871B7349CF35FE5C6B99
+:10C5900010FCBA76E17317CD5BFCA1E4207BFBE6CF
+:10C5A00085ADBF29127DD926D3BCAD1994875CFB1C
+:10C5B000F0890CA2E79BD802EAEBA1F392217E2836
+:10C5C000ABF608FDDB3FBB39FE2B17715C4742FF22
+:10C5D000362581BFA4CE7BC023EC4108D30C8E3B13
+:10C5E0001E062EBFA142FF72DE7F7136ECE3B88FCC
+:10C5F00090D737A2D90E8AF7CAF1B25D6827FE2E0E
+:10C600001D7AEC5524CFFEB7B97EBC68E2F28BF3FD
+:10C61000838CFA0764EEEF8864EB717CA515CF522A
+:10C62000056233D4B77B54BE15621E4AF9209E665C
+:10C63000CD1DA453F98C535F101F2BD341A2F59F3E
+:10C64000B1F877DE8D539E19949CDB688EE4CC6D37
+:10C65000C07B3D63174B3D7318E515CF85D2CDCF19
+:10C66000D55171F23CCD67B203D6E3FC8E82CC1873
+:10C67000E16710B1FC7E4C2E510E18ED5329E4ED0C
+:10C68000E3F9141B2AEC0E9A9AB7EB646117BEEF1C
+:10C6900003CA83762CE904CA3B4FD6811A07D98294
+:10C6A0009771FC5A9C31159F4F2FF417525CD15E45
+:10C6B000306C1571C58895E28AB92E6DBCC0ED4C01
+:10C6C000389EECE5CEF9AF73796BA2E749FA0CC955
+:10C6D000F89E797CBFC53DD1FEB2C8E752F65F94A3
+:10C6E000FD591ECF5FFEEB8F59DC9F456F70BF7306
+:10C6F0007D240DE21CB71B163875D4C2F3F5EB98F8
+:10C70000074D4FF2673B5C820EC7A21E2E8F03F1CE
+:10C71000DA0C1AFF4B97D8AFEFDC9AD50F929CC476
+:10C720002567193FA5C86B06E2528D880FC6D1A9AF
+:10C73000CA6D704E5BBAB0E7A9F279C92DE4FA125E
+:10C74000DD1BCFE1B920F295C056513F70A8FA1613
+:10C75000E864DCAE9C2CCE631A8E9C6F545F383C30
+:10C76000C2ED6CF30F9933284F5C5FD8A5E619A989
+:10C7700076A8237240F02D15B7F5D673BB3359DC7C
+:10C7800016281B5E9CB0D3DFF1A8766581C0714F7F
+:10C79000B81DFCBE399D0B5DF990B8BF013DF77B1C
+:10C7A0006AC6D3D3605CB4D680EE06E3FEF0C0E484
+:10C7B000D6AB5626B79E6B92E35A94C9ED7B68922E
+:10C7C000EBED99E47A4F1AE92DB25DC4030E2137DF
+:10C7D00075E6DB5924FF4F1C9993FF65F1AC190DE9
+:10C7E000AD9CC47F8B231DE424BFBF627EAEAEFF31
+:10C7F000A0B34837FEA1257374EF1B9472DDFBD5FF
+:10C80000DE6A5D7FADEF7EDDF8871B3DBA7E5AC1E3
+:10C8100072DD78BBBC4AD7CF98FF886E7C087566FE
+:10C8200009DACF346B6688A1FC4F71FEA56E7C7A65
+:10C83000B53D93F422B4302D46F29EF6D6A620BD27
+:10C840007B9AFD642446D4CD3AD8C85065A5EC57F0
+:10C850006CA4272B978ABA405FAD2DBC87E29CBBA6
+:10C86000B22A69BE46AF7D7522FE72548C06739162
+:10C87000CE3395786D2EEAF3F5A5C0F387EB7651AC
+:10C880001F00C951D8C0F9E7285C85763F6437AEF0
+:10C890003335D6A979F104F6E4749DEB17A42F0E75
+:10C8A0008ACB0DF8A8A878BD23021CB701492E5CDD
+:10C8B000C5F7950BC9DF4C3D219E67C540D9C3CF55
+:10C8C0002597ACE271B45C42E7DBA5D6BF7296CF88
+:10C8D0002D21BC2E07FD2ED5479EA33A09CF031C60
+:10C8E0007C9CB69FB356ECB7CB028CEA59C1BB19FE
+:10C8F0008F53C1315557DF386D895D6E61BCBE7194
+:10C9000082CEFF8E2956B1B744F085E85B31E0E076
+:10C9100075975F2FFDF97C3FDF47D43BB638C49055
+:10C92000E3946FE039B61CA9E6F2DB746CE96FD7CB
+:10C93000535C582A713A8F8BC7D53CEBBC9A276A57
+:10C9400079D630E58B4979C7798F6922BB74DE636C
+:10C95000A057BB98C88383EF883CB8DAEA9CD39988
+:10C96000C4A7CB6A3CDE121378AC96DF562A61531B
+:10C970001ED2A1FA29732C0DFD7575EF022BD9ED8E
+:10C98000EADEE2748E2F6D3C60D2E86DC4F76BEA8C
+:10C9900039FB4E8DF0FAC41B29754A67AD95BFFF70
+:10C9A0005B551E9DB5C0DB2D65D20E72C353BFED26
+:10C9B000301BE1E3CD18FFD3F95A42E2BC5A3DA443
+:10C9C00039267B689F8B4323BDD456B59678387E35
+:10C9D000D836DA4BFE3370FBC6C907381E6095297E
+:10C9E000BE4A5DF7509D99CBC51B149010BD96496A
+:10C9F000611A57BD4CE2FCCE69B6F37C3CC702E637
+:10CA00004CEA37087F56E59DE6A13EACC9E6FEB884
+:10CA1000EA949CBDA92291EFE72CDB3A9DE8F455FE
+:10CA200075220D37983753994A7EE3EBD689DA4F52
+:10CA30009FB3D2BD370CEBEB445ADD67A23A915657
+:10CA4000A70D783FD7D59503D2483DE12BD5472E8A
+:10CA5000F23A7120C21C052589FA516060D4CAE9F6
+:10CA6000ABD68D70BC95E60D748BFAD141DC9FDAA4
+:10CA700008DE57C173FC23DE97DA28DE979E1FED90
+:10CA80009ECFDB58B793B7C7BA97F0B61AC5A63092
+:10CA900087EA4EA3BCEE5453ABAF5B68750977A130
+:10CAA0006F496D8DAE6EC1FBA9750B73BAC8470394
+:10CAB000A72CCEBDF83C70DAC6EDAC2BDA328BE297
+:10CAC000B29B67FDB31CBC0E90CBF3CA31F9559CE9
+:10CAD000F66CCA077C4E3BD50BAA07AF58656E773C
+:10CAE00062455040F853DC4A793FD141E1F19CCB9B
+:10CAF0004E74FD4A7C3FF2FFF8FED7C1F7A37502E2
+:10CB0000DFD7EC4795CFA4ECA1F69462DF94641FC5
+:10CB1000FA7C0227EE2B9DCDF5EF79DFECEC8DC989
+:10CB200078BE57E47139CB4AEDC9CF59BD45C47DB4
+:10CB30000C7C4676ACB776427BDB6B1CDF19D705E5
+:10CB4000FABCC28E68B8FFF83A81F3ADD224BCFFBC
+:10CB5000DA3B28A798B70E1E4EE3FEFCE691B4BD63
+:10CB6000147F577937CE9A82FDAAF3695022FC913F
+:10CB7000AEBED0E43529F62CA37A82526442B91DA8
+:10CB80005737F09AB87D1FAB1B78A58BBCAFC6E9B1
+:10CB90001B467F37A58411FDC321CA33DE6867CEEB
+:10CBA00041185F47C0858B6009DEC27B8ED7959D9B
+:10CBB0009DCC29CB5F5D5FC85371868E48B699E4E2
+:10CBC000BCF904402E33AA337879BC5F05CF866A5E
+:10CBD000E97BAC529383FC592A5E407242FE3F15BA
+:10CBE000278CAA7C8CD60A7F53E711FEA64A8D4B70
+:10CBF000B479A9FCCF56FDD344B82353E39F1E6FED
+:10CC0000551FF12FB8D204E4077ABC6E5B69D27A63
+:10CC1000676AC5774BBBA86E312DB96E21EA13A99F
+:10CC2000F50ACD4E550F7E514FFC7F3E2AF0A440B1
+:10CC300081C037AB8FBA4E91DE27CE29EEF73CF29A
+:10CC400038CEE3286736887B814DE05E1C67A85AA2
+:10CC5000F9F9B10CA29F0FFD15D9A5D3A53B32C997
+:10CC60009EAC946A98CCF1EE31FC9BF0A9D5675A42
+:10CC70009703F9FFB50BCF12DDD7AEB7F0EF9034C5
+:10CC80007FB5FA4C63BD78BF677B3ABD9FCF9C767A
+:10CC9000999E7BDDF47CC5AF6284F4C183747BD440
+:10CCA0009BF8E9CB12E9CBBC99FEEBA43FD50D2A4A
+:10CCB0000EBE5EF8D7B5D1060B648EF777C78B6FC3
+:10CCC000F23CFA46B49AE3DBB9547FAD48F88BEAFC
+:10CCD00023E887A6FCE9FC50769DC807EF453F4452
+:10CCE000E7C9691075C254FE9F51E3C989FCCA4463
+:10CCF0007694FC886989D01B5690F0BF32E5D7F74F
+:10CD000025FCB02382FDFC2FC1BD55B9CE9E200E5F
+:10CD100073ABF23BE1F71B916F0607FF8BBA3F8FB6
+:10CD20007A9696E76878B89617BDA8D2596B5F5285
+:10CD3000DB54BC4CC3C9F21580AE2FC1C9F2094700
+:10CD4000CB21B35DC171BB42F50C63B8592CC774DC
+:10CD5000A71CC7A9B89D869FE56DE86714671443B3
+:10CD6000701BD997212BB80E4CA3EFF6186C23FD3E
+:10CD70000E37F03867E8A5F77B7F41DF1B0E3007E1
+:10CD8000B99FF6FEB3DC4FB7635CC3E3A1E8A7022B
+:10CD9000A7EA17DF9BB647986284830EAAFEB956AE
+:10CDA000016E37DAD5EFFAEA07845E2770A21F49D1
+:10CDB000C93851408E4FD7BE170C0BFF64F85D5F2A
+:10CDC000078CF0EF013B5A993386CF5371A354BCC3
+:10CDD000E859F53BC0097123E5EB7DEFB7BD6EEC7B
+:10CDE0007B3F8E3FEFF308BBD0E8678CD6B7997CCA
+:10CDF0006DFCBBDFA3CC61F4FDE86E55EE57A8F8DF
+:10CE0000EDAB56210FAF7E8B85299E5B0102A77D7E
+:10CE1000F5680BC76F5FAD624E13DD53C56B97AB03
+:10CE2000F4B83B81D73E4F78EDF7D09D104EBB4212
+:10CE3000E53F40989FAB61777A8CE28D672CFD05CA
+:10CE4000A48FDAF7465E15474D4F834E23FDECA9BC
+:10CE50007379EB6A68DC84F1CE2B7506F8CE558FBA
+:10CE600058F7977518A7CF07A3387D7FDD745D9CB1
+:10CE7000CEFBA971FA9F0AAFF5D03D8DCFFFDF93AE
+:10CE8000C4ED1EAF9DDCB84D7506F1DF0E153F49B0
+:10CE9000A56F66BD66876738B83C8D9D1F443D57BA
+:10CEA000C5BD86543F1762F26FEFE7F52F0BAF7FDA
+:10CEB0006976263445ACFF816A5FB4F6A6DA862C23
+:10CEC000C6380DAB177EEADB85CAFBC4C7F2D7F4C0
+:10CED000B8D9827E3D6E766F2447D75F18BB4B373B
+:10CEE000BEFAD46CDDFB9AF83DBAF7F79DAFD2F5E8
+:10CEF000970E7F4B37FEFE4FDCBAFE7746F4B8D96B
+:10CF000003B7F4B89926DF2E9488E4791EDB0F74FA
+:10CF1000E38A5AF5F72AEED4DF6B5697FE5EDABA4B
+:10CF20002541FDFDE684F4F7CB215CBFE27F8FEB6A
+:10CF3000FF4DADCCE97F2C3AC74EF376794BED141B
+:10CF4000C74C2F14F2AA8DFB1FAC27E8D970300014
+:10CF500000000000000000001F8B0800000000001F
+:10CF6000000BE3146060F8510FC1D3F9191836F3C0
+:10CF700023F8F4C0C79819188E83302303C33E20CA
+:10CF8000DE0AC46B80F83D0303C352203D078827A7
+:10CF900003711710BF048AD5B1623787858D8181EF
+:10CFA0000D884F02CD3AC54CBCFD8A7C08F6215E47
+:10CFB0000686B5407C9497BE6130D8F00C41FAD912
+:10CFC000F50C6AD76ED181F73708B38A3330304A0F
+:10CFD00020F8FD12A8F26CE20876960C65769501B1
+:10CFE000F50300295128158003000000000000000F
+:10CFF0001F8B080000000000000BED7D09785445F0
+:10D00000B670DDEE7B7B49BA3B9D90952574802000
+:10D010002A4BCB1201113B2189010306440928D276
+:10D020006C2184249D01661E3EFDFF6E0842C4D122
+:10D03000898A1AFC195F83E004079DE0A0139DC054
+:10D04000348B8833E804C70597795F401E2042126D
+:10D05000A338E8F3C9AB73AA6EBAEB763769B7FFAA
+:10D06000F97FFF840F8ABA55F7D4A9B3D5A95375B0
+:10D070004F14924292FA1372097E6E20E455851085
+:10D08000FAA8BBEC903A87CB0383ED6BBD2EE2325E
+:10D0900012F280D784E57A6F3A715D419F8FD61581
+:10D0A000F92D84DCEFB5E3F3C7BD25583EEA2DC565
+:10D0B000F211AF1BFB3DE42DC7F257DE1A2CEFF542
+:10D0C00016617B9D7715D66F5416A4C1B884B84CF1
+:10D0D00059C984785E1E387203ADADCF1C9F208F76
+:10D0E000A6F5BFEA893E8BBE375A2EF20FA50D7208
+:10D0F0004951D6E8603F15CF1B95BCBE00E7F1B1A2
+:10D100003AD6CF54F35A76E47E59640CC573AC8C8E
+:10D11000F8134BC9E4ECE488FD0603BC4786B279FA
+:10D1200012BBF3B54191E15D0DF01E1ACAF14BB689
+:10D130004F1E14199E13FAFDCAC9E1A5771E1E18C9
+:10D14000B9DF18E857E7E4F0FAFA4C03228F3B1EE8
+:10D15000FAC5C0278A1321BE16A33F3BEBFBF38B16
+:10D16000B8E85F8A4FC75EF3D60D12F26F1AD06926
+:10D17000AD7DF9992D749CF696614EBD8390CF5C80
+:10D18000CE04BB2526BEDD02F388816FA5304E0C90
+:10D190007C9B1B23DF1640BF18F8B604FAC5C0B746
+:10D1A000CA18F9F6B39F08DFEE053CBE07DF36C4A8
+:10D1B000A86FBF8A916F1B63E4DBA618F5EDC91851
+:10D1C000F9F65428DFD4E76AB9834868176F544AE0
+:10D1D00076403F4F669B6D40D64F827F7BBEA7DE79
+:10D1E000ED8F917FAFC6C8BF23409F18F8773446B4
+:10D1F000FEBD1323FF3E8851EFDA709DB1C85FB5C5
+:10D200000D21F8736900FC6BB19FBA9AD7F580774E
+:10D21000122119E172A09694A3280F3271B7B37549
+:10D22000ABE09B4B3984AC30D1FFD2F77D7924A0A1
+:10D23000A7E3FB6CC45F2B09FD3F073C09C9FFE670
+:10D2400052AAD0DFA78BD89FE8A0FD61902BCAFF20
+:10D25000CDDE2158D67339DA5CA44379F0251B5012
+:10D26000BE9EF03AB1BDC13B16CBC7B85C6EE4724E
+:10D27000F400C8DD152087A55CAE98DC1152E228C9
+:10D28000A774EDD8134F363850AECC12E02933795D
+:10D29000BB77CF955B3750F89B6B74576E0B91B390
+:10D2A000278A54F9A292991CECF744F909DB82A170
+:10D2B000486F1BC06928D6A9FD7CA1FD1ADCDDFDE5
+:10D2C0007A41BFC78AB97CC924103AEE63A5DDFD57
+:10D2D000D2254A977B2552DA6409E7CB1489E929DC
+:10D2E0005514E487CCE9BB3FEF2C69A3EFDBEC23BB
+:10D2F000D3082D9F04FD44FD7360A9BE5F4FE9EC88
+:10D30000A6F4C834929A26C097B44A0AC5571EEBB1
+:10D310004804397A689C8B485642FA433B1DBFCF7C
+:10D32000E8369245CBC4F16D441A06FD683BADA7C3
+:10D33000F0F68CA1B49DC27908DAADC1F654DE9E38
+:10D34000E6E0EF5FC7DA1FF6121C5FED771FE5B36B
+:10D350009BE2B78EE28BCF8B890BE8285376FA439A
+:10D36000E63F5BD2E3BC2B79A9E27F5FF6A98CF99B
+:10D370004383F89A075FCC981F82DF7D83E7605D67
+:10D38000C5C77C4525D6FBAFEA4D3D31AE0F249C89
+:10D39000CEA9330708ED0ED9897E9AE3889EF82836
+:10D3A000BF1C543C23F1E70B2ACE3FA8FEB9183D21
+:10D3B000B4ED776BE8B02E43A483A1B7488775BD61
+:10D3C000453A18FA5C9E0E532407C28F460F75DC4F
+:10D3D0000D578AE3C65D258EBBE12A71DCB8AB7FB1
+:10D3E0009871D7F713C735668AE3AECF14C735F601
+:10D3F000FF7EE312D9491F3273411CF0CF3CC1BEFE
+:10D400005D20EE8741BFC1CEE99383764EB697107B
+:10D41000B725C84F22D3977342E1DC29D8550AE7D4
+:10D42000FF7038AECBC3B16BE0CCD5C2D9C6E190AA
+:10D43000503B1D0687DCA19DC76FF97B015DC8F8D5
+:10D44000747D2525D6D0F79C9AF16FD78EBF1BEC43
+:10D4500018CC4377D9F11D1ABACED1E2B387C321D4
+:10D46000BACBD183D83570666BE11CE27002D2650D
+:10D47000E1946AE7F1BACA574958BF283D8605DFEB
+:10D48000EBC8EB3C857ED08B8A633B6D97FE640DC9
+:10D49000DC40FB1FD922F98DB41ED81B8FEBC7F9D6
+:10D4A0006DD3B1BEEF1A23AE13E79D93FD466A4FCD
+:10D4B00026BDF0B60DEC4BD50B7A19EABABD1FDBD1
+:10D4C000DA285E1E63EB83D7D1E79D2FE8C9569417
+:10D4D000C6421DD0FD14974DB28AD5CBCCAC5AB5FF
+:10D4E00065DF9D00B7BCD948CC144ED54B4BA65D2B
+:10D4F00047EB4B0E2B04BA546D5F6DE84DEB4BFDC3
+:10D500005213D43BF24839E8D39ABDFFD90EEBD180
+:10D51000F9DD4A368C7F96AE130E6A8F8F585B53B7
+:10D5200067523C2AFCBB0AE1BD8A9D92935A388A15
+:10D53000EFF6431980EF0EC969A4F45ED6184F1CAC
+:10D54000AABDA37F4FEDD6E3FC97D3F9130A6F0969
+:10D55000A92F047A560171607CA7D16F9682FA7662
+:10D56000D67B18C753EB553BE878F4FDEAE7242750
+:10D570004CB55A47DC8067FB4BE6D2A72C30CFD5A1
+:10D5800086C15698DF7A03F45BE29FFFA2D9017847
+:10D590006E311402BE9BB718CA8602FDC8BC92A1A8
+:10D5A00080DF5F44FC1AF42E98EFF26B8C5BF5C0C1
+:10D5B0004F4B60D00C6BB89D3D4BD72B47C8FA59E9
+:10D5C0004198DD27B2DF307D58F0F94BFA4494835F
+:10D5D000658D7AE208B51B5C3E7C4709F363F6581B
+:10D5E000FDDBB3827C5C6EE7F2CAF9B83C91F3557F
+:10D5F000EECC99312C1C9F07812F46E61F41F93054
+:10D600005D371DE8FF38907E8F51FFC981FE911371
+:10D610009F3F41FD242837533F09CA27A99F04A5EE
+:10D620009FFA49D06F2BF593A0DC46FD2478FE3499
+:10D63000F5CFA16CA4FE393C7F86FAE550EEF4FAF2
+:10D64000F0F973DE3A2C9BBCF5583EEF6DC072B713
+:10D65000D78FFD5EF43662D9EC6DC2E72F7B9BB1AC
+:10D660006CF106B0DC0B7CA665C0DB8AE57EEF3191
+:10D670002C0F7ADBF0BD43DE3358FE92D3DD3681CA
+:10D68000E4CA545E6C2E6207362515BB72C15F4931
+:10D690002A61F5D43B7CB9065A4F75D33AA563EF9E
+:10D6A000CA40AE91D67BD7B0F6CC7B489E89D633A4
+:10D6B0007DAC7DC02F5D79665A1F50CFDA076FF6BB
+:10D6C000E5C5D1FA603F6BBF6A67202F9ED6AF6A6F
+:10D6D00062EDC35BC8240BAD0F0FB0FAC823AE498F
+:10D6E000565A1FD9CAEA391FFA26D9683DA78DBDF7
+:10D6F0003FFE5C605202AD8FEF64ED13BF26F976FA
+:10D700005A9F4824ACE75972F313693DCFCEEA859E
+:10D710007DE7CB8E08EBFB5EA56D2198B49FEB7285
+:10D720007265EA27EC35B4AD0093BB5E7743AE3C3F
+:10D730008ED24F218BA07D93AE88D50D6425B4FF8A
+:10D7400056371DEBFB1507B6EFD1CD61758303DBB3
+:10D75000FFAA5B88F5838A0BDB8FEB2A59DDE0C2D9
+:10D76000F6CF743FC7F10E296E6C57F4FF9BD50DB1
+:10D770006E6C7F585E9F9B4FFB57EADD1E1D95EB3D
+:10D780005AC95D4E0682BC36A5833D5CC7FDD6599D
+:10D790003A07CAFDBA0C03EAD9DEFFCA790AF50CCA
+:10D7A0007E92A15EF634F8BD14CE2A84A35038FAD6
+:10D7B0009EE14CFC66AC0067E237E52A9CD508C7C1
+:10D7C0001C1B9CBDDF8C17F1F9A64285B34147EDC8
+:10D7D0007DAD35B6794DBC3441C4E752A50AE71199
+:10D7E000C42731367C02CAB5029C80B24485B31985
+:10D7F000E1A4C4868FCB304E80E3322C55E16C47D8
+:10D800003819B1C10918AE13F1312C53E13C87F43A
+:10D81000E917DBBC5CC6EB457C8C552A9C3F203E5F
+:10D8200059B1C1D96F15E9B3DFDA4D9F00C2C98E76
+:10D830006D5E7936913E79B66EFABC8670AE8C0D0F
+:10D84000CE7E9B489FFDB66EFABC897086C536AF0A
+:10D85000BC04913E7909DDF4F900E15C131B3E073D
+:10D860005344FA1C4CE9A6CF49843326367CF25344
+:10D8700045FAE4A776D3E73CC219171B9C83A9227B
+:10D880007D0EA676D3E70B84737D6CF3CA4F13E944
+:10D89000939FD64D9F4B0827D7DD88F8100AC71AEB
+:10D8A0001DCEA17E227D0EF5EBA68F490F700A28B2
+:10D8B0009C813DC329CC14E95398D94D9F443DE840
+:10D8C000C5E4D8E01CCA14E97328B39B3EBD119F80
+:10D8D000A9B1CDABB0BF489FC2FE8C3E1E63E7240A
+:10D8E0003BF88D89C4B995BE3229F9670761DD51CE
+:10D8F0002CC409608F48816D009FAEADE897CA4E79
+:10D90000D50F7212F0738B6D0E27C403F4AABF43B8
+:10D910005A713F62D99928C49B5ED2E70D077CAD4E
+:10D92000D42B0CF57B12C6C609FE56A22B49A8F7CC
+:10D930002AEA2DF44F291920B4A7955E25B467B8BB
+:10D94000470AF53EE5E385FEFD6AF2847AFF55530A
+:10D9500084FE59BE19427D60DD1CA17F76FD02A1C7
+:10D96000FD8A860AA1FD4AFF72A17E75E3BF0AFD0A
+:10D970008735AD11DA47346F10DAAF093C2CD44744
+:10D980001D7E42E83FA675ABD07EEDB16784F6718F
+:10D990006DCF0BF5EBCEBC2CF4BFBE73BF50BFE117
+:10D9A000E29F85FEB9E46F427D92E903A17F81FD8C
+:10D9B00023A1FDC6F44F347EAC18BFA8CD25CC9F63
+:10D9C000CD30A03F1BB01AB06ED86B66FB1BA827EA
+:10D9D000431CA218EB86FD0B1DC9100F0000D49F3D
+:10D9E000C8ED5D7E05C4AB7E31DE7D05C4717F610F
+:10D9F000708FB047F083DA65F73D7A8C27B64A24FA
+:10DA00001D4A870ECA383D8F271899FCAECFCA79B8
+:10DA1000CA17A20775FDA87F41EBEBF5148F3141C2
+:10DA2000FD59DFAF2C7D7EC838EBFA194AB70E6579
+:10DA3000CF175A60BC92FB603C8FA17330E0A51DEC
+:10DA4000C73860AC308E29B31CC7D908E3A404C71B
+:10DA50003166966BC631956EE5CFF9388F81DE441D
+:10DA60001B67FD80F1E27C322B709C2D9A71D6678A
+:10DA70005668C68963F3A1CFF9384F5D6E1CE3C0C9
+:10DA800009E27CFA57E238CF69E7D3BF52338E05FB
+:10DA9000C781E7300EE94B77316994CFC6CE329417
+:10DAA000833F99314E66E853F11BA8930FCC241B9A
+:10DAB000C671D071693F3224890A3521FFA24F42D5
+:10DAC000FE7C1147F91F124F0BEEC77DB8AF5FCC3C
+:10DAD00051247E8A11DD275573D95CB4737AE60A26
+:10DAE000072D9B0F0C7A04C6D9687566D37A7BF331
+:10DAF00024C3C208F2B4B85E39D51622E7DDFBB301
+:10DB00003C32A4868EBF22CE8EF8A875B54CD28941
+:10DB1000CF4FD07D17A1FB930FE93E85D0FDCA47BB
+:10DB20000ADB67FE3BDD9F41BD8DEECFA09D90D50A
+:10DB3000F8DE091E673EF14BC90FF4FEE2AE9F29E5
+:10DB4000B84EF8C85BE9A9104D603FF356C553269F
+:10DB500004F19BEFEB25D4A939EEA34BC77D2DC66D
+:10DB60000F3A5F32FAB7025DEBFA509AF27E030881
+:10DB70007977EFD443920DAB7D746309995933BD26
+:10DB8000200DB548EAB79CE23963F7350A7D83B4C6
+:10DB90002B6D773A2D41B8C4A59C00FA98E81F80F8
+:10DBA000734B11AD878C7F6B89589F45E4609DF264
+:10DBB000FBA47E0061F17F3EAEC3A5005F4BE81C75
+:10DBC0003328AB674139129A59BCA6D4CEDE55F141
+:10DBD000F12C544800F7D7BE148863135F32F69BCC
+:10DBE000A3EE9335F8952A265709A56BE97C3DD21B
+:10DBF000558BEFFB7BE35DBAE1B4AC7B4481D06C29
+:10DC00004FF8CF768BEDA49C8DA7D2559597539C5A
+:10DC1000BF2780FFB43C0DFCA7789FE4FC0FCA31FE
+:10DC2000E3BFC7E89E06FCEFDCA427C82FCEF7DBD6
+:10DC300038DF17D78B7CBF0DCEE368FFDB5666B1AC
+:10DC40007853432F81BF74E2221DEA1F2AA0663554
+:10DC50000CFFBF73399853B7EB1560EFEDE59AF9F8
+:10DC6000713EDCC9F93057438FDB38DFE672BE2DD9
+:10DC700021BE7B33307EE15720AE37BB5C22602F64
+:10DC80003C77AB7C6B13F8E656F9A6C1F74ECEB7DE
+:10DC90003BEF627CD3E2DDC6F9D6D6F0994206842A
+:10DCA000E3ADC573DE2ACDBC7C5ABED573B9B41BB7
+:10DCB000C09F9AEECA5D7132A4FF2D4593579C0C0C
+:10DCC000B10BB7964C17EAB34A670BFD67BBE70B7E
+:10DCD000EDB7972F15DAE7D6FC4CA8CF5B7597D038
+:10DCE0007FBE6FB5D0BEB0EE3EA17D71FD43427DDB
+:10DCF00049C326A1FF52FF16A17D59E30EA1BDAA7B
+:10DD0000699750F734BF24F4D7EDBDF26690AF2386
+:10DD10006FEB09C4FB2E384F639CF1825371429F15
+:10DD2000935E07CAF129EF102CCF789D28E767BDD5
+:10DD300063B1AC06991C0776F68005E2A79E386AA7
+:10DD4000F713E93A2E8F5B533701D61BDA3E9E90CC
+:10DD50007F956F58E3EB4BB500E2DE94FEC50D06F0
+:10DD6000121845A874F7EE96E74E7D487B5B0FEDE1
+:10DD70000D3209F40A6F2F6E8BFCBC43EA1C9C0128
+:10DD800071D9F78C647B48BC31FCBC85F401BF229F
+:10DD90005AFB391D290F3DEFD92AB3739E23FABCD4
+:10DDA000AD32C5ABD2C0F4BFF2F98C3C62837A606D
+:10DDB000708DE532E3355164D280CF0305BD5FD26B
+:10DDC000707550CF098CC3ECE952FF28E1F9B2C657
+:10DDD000EB84F7DE90DC5B008F73FBF4B85E93C0DE
+:10DDE00081CC5B86017EAEAD32ACA3CD29E877B5A0
+:10DDF0007A5D2B4E2A84BCE92DC2F22D6F0996EF75
+:10DE0000784BB13CE67563F9BEB71CCB0FBD3558F6
+:10DE1000FEBB7715966D5E1F9627BC75589EF4D68F
+:10DE20006379CADB80E519AF1FCBB3DE462CCF790F
+:10DE30009BB06CF73663A9DACF9EE4EF0C5F5FCF3F
+:10DE4000821C1AC3E5ECE0DA796BEAFA06E5ECB07D
+:10DE50005C8672A6D2B7B8C1C8E521559087BFC20B
+:10DE60003A9C02F2D2437B83C2E530DAFB91DB417C
+:10DE7000DE7AFF08F246C81A94030BC8DDF7903724
+:10DE800002A70829204F7D34F224CAA12A47AA9E5E
+:10DE9000BF21959C03F952E5CA22337F4895ABFB1D
+:10DEA000C14F8CE06FF55624BEFE31FF88047275B9
+:10DEB00040B2E5FCBC82F85C58EFE263D75270AD2B
+:10DEC000D04FF60F8175A46BC8578321BEDF758CC8
+:10DED0000A4156F4F969E5253ADD5DB87F28F35328
+:10DEE000E6F70A6F37C731BA9A75A4888C84F3E5D0
+:10DEF0009C636ECACFB83F5D3D12F6CDF4B94C922B
+:10DF0000008EDF393DC27901194490CE3DD157EDE5
+:10DF10007FEA89FFCC81737F0BE8399D7BDC017D33
+:10DF20000DD3DFA79CB7849C2F798CCE7488837720
+:10DF3000661BECCC7F9824D2914CC2F303958E07DC
+:10DF4000B2BF180CE733F7513904FDEA1A343881AF
+:10DF50005C463E7AB2F73DD17301CC37267A1A0877
+:10DF60009C73517A6E85FB8EB1D2B3273BD9937DDA
+:10DF70003CB181D1F908F74FA3D1593D0FD3E271DC
+:10DF80008B22733E7039267768E85F2AD0BFAFD501
+:10DF900081FD0FEEFD2013CEF1BA765F91408686AB
+:10DFA000BE5FC0CE7BBADFCF17F440FAD3DF336158
+:10DFB0007F7CF08577B15C4B981E6EB494CC55C6CF
+:10DFC00004E1C57A8F20DABC3C8A24CEAB07FDEC95
+:10DFD0004855F5B33513E46937B70361F3EB413EB8
+:10DFE000D5F91D80F951385341A6E93CF2E592BBC1
+:10DFF00084F98D4EC179F7343F4F82814823287EC2
+:10E0000056838124507954DC6B15DCD739DB7C10C6
+:10E01000A7D81BEFACA52CF1D8CEBE1170C07B6287
+:10E020003C6359A3B946F49F126B44FF29A326D43D
+:10E030007FEA3AFC94CD4DF15B9EAEAF39D90BD659
+:10E0400039175FE7D8BAAAE257D594556311E0882B
+:10E05000F5AE7AA988DDC37124CC8C70DEA796CB8F
+:10E06000D30D38CED9C6810930EE59AFA986ADAFF0
+:10E07000F61A366E7A4DE8FA5AB92ABEE6E4A820B6
+:10E080007ED1E0FED0F85189201F99605DA46D0318
+:10E09000A3F78FCA4FF973039EABB7285F80FF6E5B
+:10E0A0001EA2FAEF32D655B89E26BDCF38029EEF9B
+:10E0B00014C6A3EF39D4B371782FBADCC8E494CA7C
+:10E0C0004F3D9C7711BE3F30219FDD14620285D702
+:10E0D000215BEA40AEFC0AD3670F97D32A539BC15A
+:10E0E000ED4072B7825C2F18ABCAB963D607D44E25
+:10E0F0007FFC1705EF9991AF29F49CE0558745A463
+:10E10000C40641D505BB9715C3BAFDF18B37F17D28
+:10E110007A7D0ECCFB3CD115815D3A4FDEB48D0A81
+:10E12000D1D7D30A8B63913AB6CFF1D13F30BFC577
+:10E13000F5E2BE674983582F233352C1DE966D54F2
+:10E14000889FE2BE14F64DEABCA9FD7D57B123724B
+:10E150004B48CD3AD8A73FA6B078CF023B91FB50B1
+:10E160007B5DF5875FE740DCA75D61FEAE7A1EBE92
+:10E170003489ED072B66FA0D2EDAFFA3DDA36EA31B
+:10E180001697BEEF5F87FECF74E2DC4EC2E9BEB0E9
+:10E190004EC4AF27FCB5F8AA7E50D8B93CC723B906
+:10E1A000518A785FEA6B6EE754FD4832D885B84FE4
+:10E1B0009AA6AECA81C2E5C0AFB8AD8614C677E0F4
+:10E1C000A324771ADC21FD0CC17E498631D1FB19CD
+:10E1D000A19F1EFBA5B17E9D85B83F26549E860655
+:10E1E000FB9983F0FAB271C57E557F78F6451F958D
+:10E1F000978ADF3D6A2374DDFC58AE4F75D2E795F0
+:10E20000DBEFB5B9687946F6D9809F1FFBF511EFB2
+:10E21000FBDE6250E9E1B248104FE3F249EA7C18B4
+:10E22000A7F862BB62C773844663C048E5B37AF758
+:10E23000D262321CEBC7597DFDA77AA8378BFCAAA6
+:10E24000F8CDA3A90E764F88C5934800FDDCEA6D92
+:10E25000FF5108EB858774A29C69DF83F12F26A10B
+:10E260005ECF372484B7E3C5E054789FFD7876DF2E
+:10E27000FFA9DE06E5E4D3A0471E8D9C9473BF156D
+:10E28000E805FBFD7C833519EDFDB5E45AD07795A3
+:10E290002EC4CFFCD7DA1D8F0F3F4EF13AB7ED2FCA
+:10E2A000366968A89D60F2D6D5B4F0DF4CBAE8F6BE
+:10E2B000A49DCA63A89F4401E37B8E66EE77B7B046
+:10E2C000B25209D8E03E4EE516C5492591543EAB01
+:10E2D00027703F81BC67F4437C74D9B3AFBC339ED5
+:10E2E000D27FD92E25B9984DC722A506F9E3A17F83
+:10E2F000578D0CF2A3E2F7AF181CC3D8F37B9282C0
+:10E300007C59B66B9F810C0BA7E3A4A67D86364B88
+:10E3100004FE341D2F84F5B676C73F0C1057FC78E9
+:10E32000AF44D2B2C2DF2FDFF20AAE7B4027E42730
+:10E33000E75737FFC2F81698F6F268EC67077BD804
+:10E3400013DFB2613F9782F2FDDCCB708FE97DA3D2
+:10E3500013E850FEDC0A1BCCE7B45CC3E4FCD7F73F
+:10E36000A682BE972BBE543B96EC79F9933F47F9B2
+:10E370005B72F4E7A9E83F1057860E6DB32F03E6F2
+:10E38000B978F3AD38CF32E246392CFFB5BE04EE92
+:10E39000995E9049D1AE087AF21703DBBF9CDE4A42
+:10E3A000994BE7791AF003FBF6A6DEBF1DE3E63FC3
+:10E3B000C37B703FE773A62B21D62F9818BFB618E2
+:10E3C000746A3CD424C8EFB6F5ADC0A7B3FD5C6950
+:10E3D00070EE41E9E0E374932E51B8FAA305698C1D
+:10E3E0004FC421E7F0F7A8BD9F04CFA17FABE23275
+:10E3F0000F17DEE3F6918DBF928F4FF18E83F5EB11
+:10E40000746A64FFEF1F7C7EF4A79584C85988BEA8
+:10E4100033FDDF761FD37755FFFDD38BA0FDF3B718
+:10E42000981EC17BB05E50BC0269D8BE6FA684F650
+:10E4300081EEB323E9F93685EBB9D84E7738B8FECB
+:10E44000AB7242F197A5845079A1E324211F707F1C
+:10E450005CB691BE1FE29779605CEC67083E0F598D
+:10E46000379670BB7048630FC8E69498FCE84AC5BD
+:10E47000FFF413A0BFEF199D3E07E8AF5202F3FF70
+:10E4800064E78177E65039FFA449D55BD1AE6AF5E0
+:10E49000B6FCF9312492DE7E62A1FBAE487A4B9F36
+:10E4A00047D45B4B1BCAF3FF2DBBAAD2AF5D433FE2
+:10E4B000B08F2F3BA2D3516B1F37181C11ED23FDDA
+:10E4C000798BE484CBA12A7FAADC55FCB6AA3FD87D
+:10E4D000A16EF954E5AF5B3E55F9D3CE57A49FB674
+:10E4E000FD0FA0DF14AFDB4D9BA681FF6CEA241863
+:10E4F00087CF9DA9C77B9AA6CF09BBA771473CD6FA
+:10E5000067E9DB7E0F3EE10755B386C13A7F3BF1F9
+:10E5100029ECDCBE5E413FF6EB4B9726D0F9CCE10F
+:10E52000F4BD9D927B2AE547A92C05E2289EB365A0
+:10E53000E24B488278B2444E84E0717BB958879FA1
+:10E5400089A941383DF5FFB67EF7772D8F52BE9EE3
+:10E55000C826E46F50E2FE833AD621F234BD859D91
+:10E560006378464BFE01A8876D7249C83EC263645A
+:10E57000F6E768FE2D63807EB9B3862530391F8C9F
+:10E58000FB450FB7635D3E4702D8F7AE9681B82FC3
+:10E59000EC3ABCD0EA8E60CF0E70397B859FC37495
+:10E5A00058A47A3D95FB0ED2897E8DCF628E189746
+:10E5B0009B6354ED34E71BFDD1D3F14BB91CCEA6C0
+:10E5C000AF268C0CE1DBCCA91FCBB6703EC0CF8947
+:10E5D000907DC5F7A52FC835D0F780B9ADB02442DE
+:10E5E000FCA692D36FE2FE2F0DB0EEE5B7E4CA4071
+:10E5F000C77C8B5E88872C32727D1D4A86025E1333
+:10E60000F72F7D600C9563CF61BDD34CE7E769F9C7
+:10E61000D4E08EB0BFD3D213E0837FB9D5C8FCE578
+:10E62000B79592C540D7B76F65E7BD7F3338AB224A
+:10E63000E1996E66FEE66C527261B4F4D3A36FEE9C
+:10E640002C6B208FD2A3CBC2EE6B87CB1FD3FB2EBC
+:10E65000BBE45F2D811CEA593D99DD6F2E24EE0746
+:10E660002648A8EF3784DAAFDCE6E9CFC27D9AEA24
+:10E6700016C9AEA3EDD5729B01E4D8D3BC4B06BF3F
+:10E68000FD260771E1FE5AAE19363324FE45973D4B
+:10E69000A4D781AFE6CC05FA7E36D348002FD7D079
+:10E6A0004F6DB0FE7FD6320AF520DABC5EF7926974
+:10E6B000F90AC061F64C2B0F85C9F142FDD649A479
+:10E6C0002F9C034F34B6AD7046E05FBE89C959CC6C
+:10E6D000F6CDF4FF997D9B40ED1B936B25D4BE597D
+:10E6E0004C61F62D2D927D5BBEDA910672B17CCF26
+:10E6F00040FC7E6BF96B8B5322D9B757F9BEF735C7
+:10E700007E0FBCA32FB56F2342EC5B5F6ADF22C490
+:10E71000C9BF88D5BE99FE67F4EF55B06F11E66B9F
+:10E720003689F6ADA86535DAB7A2BE7AE1BE1231F8
+:10E7300051FB167F39FB36FFD15BB1AE38E323C8FE
+:10E740000FD015ECDB6BDCCEC13860E76E30B1F872
+:10E7500066AC76AE5FAC76EE7F88CEAA9D5BDE4F70
+:10E7600042FF255C0E999D5B9EC5ECDCF23DCCCE54
+:10E770002DCF66764E6BDFF2C2EC1B7BBF7A087D35
+:10E780001FF78F598FDF01F7094B15A789F62F76F1
+:10E79000A8DF4FD48C09B577379864A47398BD73FC
+:10E7A0007E8ADFC1F464EFFE0AF62E1BEDD820D07E
+:10E7B00023AD7C4C19142FDC677BFBCB53BFFD1DB5
+:10E7C000E8CBEB7ABC2FF4AE8EED8FF67E796A142F
+:10E7D000E8DD4326667F9798183FDBBD3EB4A793DC
+:10E7E00086327DAFBA87D1AF7AB7C4E6BB52EF7736
+:10E7F000C03AF0D545DC3FCFDDC3F6CFB38CAD29B1
+:10E80000F1702FE95F14C2BEFB20C5F343E4A1F40D
+:10E810006205C6019F8FB36D85FD65A94C4CE0C7AD
+:10E82000CE3B3CE563F05FE75DAC43BF771E3C87C2
+:10E8300073127E4F42BD4731A779D72B7D48F8FD33
+:10E84000888946C687892B24FF962CB88F20B6CF9F
+:10E85000D3F8F5EBF83CA93F8B74217FD5478CDFCB
+:10E86000ADD3D2C3C9E65FB5522FD2A3468A480FB3
+:10E87000CAD1E2F9A9C1F9CF7DA16D5D1F685F2AF8
+:10E88000E17E4AA587769E2A7DD4FDCA3CAE239EB2
+:10E89000965D0AF04B3B7F957E61F356E9A9997F1F
+:10E8A0009D6A3FAE26C340DFDED5B91F1803F2F1E3
+:10E8B000674A078AD76DB3B3D342EDF183DC2E4D9F
+:10E8C000751FCF4F7500DDD8778973CA77BD924A1F
+:10E8D000E773B32B6B247C3F7CEB570637C4170ED2
+:10E8E000983BD1BEA9F2F50997F70087F3766F7BC5
+:10E8F0003EAE23CD921DF526A0B15FFCFE98E71E2B
+:10E90000A65707A47FACEB331AE90ACB002954D7EA
+:10E9100021E003FDEFD416C6070FF081FE771AE958
+:10E920003C0474AE4E969C01E8DFBCEB5E909B57B6
+:10E93000CDF439E86FB9E464DF97114B46EA65E539
+:10E94000538E249F189CC809AE8BF3A05F52B8DF8A
+:10E9500031D1D8FA36E03191EAC31612EE87A87C9D
+:10E960001F42FF5C8A74EFA70739FE98CBE7AB40E4
+:10E970006F0BD0B5D300FE8C27C0D60FB5DD233B7F
+:10E98000F2913E2ABD9BE9FA309AD15B17819E37FE
+:10E99000AB754E4F4F8BA4C0FB93E9FEB59704A710
+:10E9A0005B5F1E52E518BE87D3D203E20119217ABC
+:10E9B0000FF629F47CB2BAF928D265CA4AEA5E8514
+:10E9C000D01DECD6E5E8134D2FAA9B7F18BDF84467
+:10E9D000A3177BCD9D7F1901F1AF3D12DA07D292CB
+:10E9E00028ECF7E3CDCCCF386076A3FC76BEA6E06A
+:10E9F000FD73AD1DF99ACB3DEC2F42BFFB9B041379
+:10EA0000013B6737938F543C0630390AB5DFAF9A24
+:10EA1000DDC8AF68F0E3F83A1CCD7F52EB37C2781F
+:10EA2000701FD1218E17E65FF0F84F4FF34AE3E3F2
+:10EA30007ED779759F6792560361F1FF15C6907373
+:10EA4000A9DBF8B940779C2CD8CF6EBA4C3F88BF71
+:10EA500004E8BC5FDDF914C67FCF3F737C1AC8EFB2
+:10EA6000B23FEA8989F2B97DA79504D8BD0B03AC02
+:10EA7000B315BBF511CF5108A965DF39FECE8AF673
+:10EA8000A5E279A3BF98BE5FF1E247C3216ED5BE70
+:10EA900086D919DF335C3E7C6DC3E17CBD4266E7FD
+:10EAA000C25A78D7717939F7527C29D849A9917D12
+:10EAB000BF5AD1344B3186ECD3479A151C97F6C315
+:10EAC0007BCBBE1D12C6CBC3F15BCDE0ED60F6AFD4
+:10EAD000A259F1C377B0158D5B707FEB69FCD40050
+:10EAE0007EDDA4DF3DCBBEAF6DD68BF1C3467DC0CE
+:10EAF00088714EFD71E370A6B792108FAA42BDAC2B
+:10EB00006EE271324DFC68D9EFF6BCE8A3A459F669
+:10EB1000FBDFD8C0DE9C6DDD6EC3F85C238BBFC904
+:10EB20001639727CAEA7B85CD37D3C2E37F534190C
+:10EB30001E1E973B0BFFA17A38DFCCF5558D6B3647
+:10EB4000F68AE9FC7CD9B3179E84F3A473CF7FF2D5
+:10EB500024E05FF9CD674FDE0DE7127BCD7658FFDD
+:10EB60003CCFBC8DF177F5BDBBB99CB7EFF8CDD3E9
+:10EB70004F503D6C7FCF88F7B6DAF79CCE84EF1903
+:10EB8000DB777D990AF1CD957B0A703FB3F2854919
+:10EB90006997BB7F02F2E98FE1FC44CB8F03BBF5A1
+:10EBA00004BEE73C7FCC88FE47779CB5A98AC5AFF9
+:10EBB0001D3CBEBA33F279951A0FACDE7DCBCDD7B2
+:10EBC000C33AB85B713AF0398F0FF614577D8BF268
+:10EBD00075440CFCDBC9E3E74D5323C655CFC37F17
+:10EBE000289F3699C5B8EA85DD8BFFED0968DBDD26
+:10EBF0002B6A5C351003DDD4F3B032B36B9B19F490
+:10EC0000E3F9DF621C1BF8467D72D2FEEC854C886E
+:10EC1000479C513AEFC47BCA7B8C78CFA862CFBBAC
+:10EC2000A82FED2F1CC57326C2CFA3DA49F70F3BDF
+:10EC300037E07B1DCF362B8BC772FA43BCD661C33E
+:10EC4000E73C2ECBE4588DD7468BD3BE6F66F7A139
+:10EC5000D4F3B9AA6D1F188826FE2D8D057E1D17C9
+:10EC6000CE15D5796BE1D9810ED7869E3F448B872F
+:10EC700073BB1AC62F76EED0BE859F47749F3310A4
+:10EC8000D277249C8FB373738F5F7A37127FD5F35B
+:10EC900087B7B5FAE98FEDDCA167BCBF1B5D5E35B8
+:10ECA000B3FDAD4A9F735F47B6D39D5CDFE93AD3AE
+:10ECB00061C67363B6CECCE3EB4C35A51BFBEE8D82
+:10ECC000E17B8EEF03CF3DA3F7C37E795DD301B423
+:10ECD000B75A3DAF262CFEA51D4F8A63FE4175F342
+:10ECE000BEE1608FCEED7F09E5AF7AE771838FC219
+:10ECF00039D4F87B43DBD0A0BC831DF787D8F173F0
+:10ED0000CFED1BCECE4522E769B171F89E1611BE3C
+:10ED100067E7A702FC65BE2683DDD2F3386765D7B7
+:10ED20002C98EFD95685C07DF6B34DFA227F8471B9
+:10ED30003F83756C4C904EEBACEC3B3E7D9201FDFD
+:10ED4000CC95D6B1C7E0FBF195568303F6DBB5ABA6
+:10ED5000D9BDCADAFFE54C07BED426DE86E746F504
+:10ED60001A3ADA93EDB9B00FB7E7978C06B1D2DA59
+:10ED70008344974EC07BA5B528CD6181BC5ECC4F46
+:10ED800021B213BF33D4DB0A8B601E7ABBCE6E8EEA
+:10ED9000B8BE32788A85E5CD50ECE2777FDF210F6F
+:10EDA00006817C1CDF3A0F46A7260F46F98DFFAF80
+:10EDB000E5C1F0C1383F813C18018CEFA879309251
+:10EDC0007FE43C18105F1A1D9207A353930783F347
+:10EDD000F19F7930FE9907034A350FC63B1BCA0ADB
+:10EDE000204F859A07E3CC064F01E4A550F3607CE1
+:10EDF000B56115ABF33C1896FB571784E6C1C8BC48
+:10EE00007F03B6AB79309CF73F52109A0723EFFE91
+:10EE1000CD05A1793066DEBFBD20340F46D9FDCFC8
+:10EE200015087930D6FEA100F260BC1EEF6E8D4B46
+:10EE3000899E07A339CE11531E0C0AE73D84132582
+:10EE40000F86164EB43C1814CE89B831D1F36084C5
+:10EE5000E113250F0685F309C2899207230C9F2829
+:10EE60007930289CCF715E51F26068E144CB8341D8
+:10EE7000E1FC17C2899207430B275A1E0C0AC710E0
+:10EE80009F123D0F46183E51F26050380908274A3C
+:10EE90001E8C307CA2E4C1A070D2114E943C185A52
+:10EEA00038D1F26050385908274A1E0C2D9C6879D9
+:10EEB00030289CABE2C744CF8311864F943C181492
+:10EEC000CE28C4274A1E8C307CA2E4C1A070262024
+:10EED0009C287930B470A2E5C1A0700A705E51F22E
+:10EEE0006068E144CB8341E14C437CA2E4C108C3A8
+:10EEF000274A1E0C0A6716E213250F46183E51F2E8
+:10EF00006050386EC4274A1E0C2D9C687930289CAE
+:10EF1000A508274A1E0C2D9C687930289CE50827F7
+:10EF20004A1E8C307CA2E4C1A070EE463851F260DB
+:10EF300084E1F35DF360980383A481980703F37180
+:10EF400076E7C148FED679307E05F8FE330FC63F1E
+:10EF5000F360FC1879306EB5BAFF1E8FFBC6EF96D2
+:10EF600007E34CBC266F440F79306EB5969C05794B
+:10EF7000FEB679302EC47FBB3C18749C7F5C6E9CBF
+:10EF800068793074966F9707838E235BC65C663E04
+:10EF900051F2602458C4FC213F561E8C63F149385D
+:10EFA0009F6879307E72F926E8360BF669D35114E2
+:10EFB000C94F26FFC4680B8F1BFE50F92760D2395A
+:10EFC0003FA5FC136A1E832605D6C3F739DFDFE1B0
+:10EFD00072F101CF43712C6A1E0AFF548CEF2E157B
+:10EFE000F3504CE17C9CED16E5610A61E72853F291
+:10EFF000B3FCB5B05F2FD7E4A118229ED317BB8F07
+:10F00000E6537064AA539CC7512E0FD34A3F3D0864
+:10F01000ECB9796CE43C1433383FA66BE83285F3E5
+:10F020006D3A2F6F874F73A83C17971F9581AED30A
+:10F030001C6D32C6E96F52F9E710F83793C3D5E279
+:10F040003B83F36FC664C63F2DDE6F01FF28DE6F82
+:10F05000958F42FE69F1D6E2A9E53F09E57748FEC2
+:10F06000905C22E69F986412F34F14D8C5FC1337C6
+:10F07000A68BF927263BC4FC13370D11F34F4C75B3
+:10F080008AF9276E1E2BE69F98EE5AADC97F719FB5
+:10F0900026FFC5439AFC179B34F92FB668F25FEC44
+:10F0A000D0E4BFD8A5C97FF19226FFC53EA1BEB06E
+:10F0B000EE35A1FFE2FAA3427D49C37B42FFA5FEE4
+:10F0C000E342FBB2C68F85F6AAA64F85BAA7F94BD5
+:10F0D000A17F4FF907DEE2DF43BFC3BF873EC6BF54
+:10F0E000877EBF87FC17EF5896AE0BCD7FF1BEC56C
+:10F0F000B30EF2121CB738785E81C8F92DBADBA3C3
+:10F10000E4BF08BEFFEDF35FA424FFF0F9087456D6
+:10F11000F63D606F4B9ECE9AF2DDF311DC5A227EF3
+:10F12000D73DAB54FCAE5B6765DF6BCF768BDF778B
+:10F13000DF5E2E7EDF3D22CE2D011EDAFC17BD2DB7
+:10F140002E9D15EC25CF531080EF74B321DE56842D
+:10F15000E541C87F910DF1B6522C0F43FE0B5AFECC
+:10F1600019F25FD0F208E4BFA0E51B90FF221BF26A
+:10F1700067F878FE8C3A9E3FA39EE7CF68E0F933AC
+:10F18000FC3C7F4623CF9FD1C4F36734F3FC1901C5
+:10F190008473C27B18CB93DE562C4F798F6179C66E
+:10F1A000DB86E559EF192CCF793BB16CF75EC432A1
+:10F1B000D6FC19AA5C7E087EC315303E9367554E77
+:10F1C000AF7EE09175A1F933463CB009E5345ADED3
+:10F1D0008C1CF8A62F257ADE8CEEF628793382EF88
+:10F1E00047CF9B9136FAC7CB9B31D7F2C3E4CD987A
+:10F1F0005B23E67598B7EAF2793346C495DC82F270
+:10F20000C7E571AE25B6BC193EABC4BFCBA7740130
+:10F21000BF8BD205D7EB1EF20E1CB43E3D04F61395
+:10F220005D43AEBA6CBE07AD5C44A737CBEF30E7A9
+:10F2300047CE97D1135DD5FEEF57B03C0E732DDF4F
+:10F24000325F460FF9160E667F817632D67C193D05
+:10F25000AD0F3DD173C68F9C2FA327BBDA933D7DA5
+:10F26000730AA373EF1EE8AC7E2F5D696A3D842F9D
+:10F27000DB5DA8DA32FF1E3E77A61DE3331D3BF9A6
+:10F28000BD381771D853D9F7FAE06F763C9F309CA0
+:10F29000E077FC76E2A2FC89E7CFA59DFBF6C1BD35
+:10F2A00080B536E24A4C02678F38F403611F768DD1
+:10F2B00009E23555BB3F7DE38F14AEB9458FF7E5C5
+:10F2C0003A280EADE8F7B912816FF1E497B84F878D
+:10F2D00033BA4BBD42BFEBD6FC1E0EE8921A3C7F00
+:10F2E0002AD05B70DFD4B599DD67D593AB1E9F90B4
+:10F2F0008CF7C689DF81FC433F7519C7B38B106754
+:10F3000000FAEFB4E2FDD525AF2D34C0A070DE1AAF
+:10F310001A37E85524C6811ACCB6E1706F2F5DBD4F
+:10F32000BFE773B5821FBE88C34D2911E3449F2CEC
+:10F33000283A0CFEF3227719DEAB482B15E34684FE
+:10F340007F470FDB32F03365C2EF75FAD97DCFB05E
+:10F35000EFEA9BB7209E4BFD9AFB4B8D625DA5DBD0
+:10F36000392BBF9762219698E8D636F8F109A3BFEA
+:10F370003DDD8CE922DDCC0E916EF14344BA68E9A3
+:10F3800066758A74D1D22D61AC185F53E9A6DEA7E9
+:10F39000FCA1E89664E3F73C82F42A31A5A2C947B0
+:10F3A0003C33E400CAB7561FFA5802F01B7E48BF30
+:10F3B00064FF6A7CCB6995C16EA533D0445AC4DE24
+:10F3C0008B077D80FCBDC489FAA0FE3E8A78F221BD
+:10F3D00097FB8FC8255AAE987EF0F802DABA19E486
+:10F3E0006D04FB3D1A18AF4A22B89F5388D30EFB19
+:10F3F000A826AFC9B94881734DE25C940DE79976B0
+:10F400002C1FE4DF3B770C25B8EF6F0A7C9E0AF7D0
+:10F41000061E1CD9390DE20F9EC5A404D6AF5909AA
+:10F420006C7D5DC64B5B028BCF6C28D111D768F821
+:10F430007D4A7ABF44C76BB7BB5EBB01FCD1167671
+:10F440003F80D83BDFB81DDB47E1F7E119BAFA6B23
+:10F45000001FDA1FBF2BEE68F9C8B630C40EB737ED
+:10F460003F7225DC6BDDA48BFC3D73818DFFFE1D9F
+:10F470007E3F654430DF42816D0CE6657870001D8B
+:10F48000A77A7A17F25195CBEB38FD0F964D41FCD8
+:10F490005E68911C10AF2BD4DF71D3308ADFB8B710
+:10F4A000657EAF97DD5F1FCDFBD79AA9FEA2FDAAAF
+:10F4B000FF1BFC9E95974ECA980F71744D19DE1371
+:10F4C000FCA3ADF030F02BC7D5340AE429BF2511D9
+:10F4D000CF713D1F12277E9AD52ADE07CCE1F7B601
+:10F4E00073DA881F84E2DA6362FBB836B17E9D6608
+:10F4F000FF39DFC6F5D4465241EE367EAD9760FD4A
+:10F50000E8E824CE3514DF8E45BD71FC8ECF09FAB4
+:10F51000891D5FEB8B22DD8F596E63FCDB642068F5
+:10F52000BF379559F0DEF9FEB28AFEE05F7C719735
+:10F53000BB7FA43865889F96C0BEBB772590B1205D
+:10F54000876B2546EFFA8C9208EB962A77AA1CAABD
+:10F55000F2975116E78E740FF5339B8472965736E7
+:10F56000443280FCEC9530FCD5BE86E2759975DBA3
+:10F5700047D6F4017C3CCD9FE17D32538BE48A7405
+:10F580004FE7619B8DDD6F5CE35B0DF7467E419538
+:10F5900008EC5486A13E2B127C1FD9887EE95D368B
+:10F5A000077BCFC4F320C9F519709FA2BD79D2E4BF
+:10F5B0007514CF27A83EC07AB5497122DEBE2A4213
+:10F5C000F09E2C8FD7F59D46B66C08F17F37DB7225
+:10F5D0001B6D145EA38D7D6FD9CBED94006FE77F1B
+:10F5E000FDC306F03B2E1A917FBDB9BFA9BE77803F
+:10F5F000D3675C826B2BBC4FE0979F51E3E374DBD6
+:10F600009C8B46415C9ED23BC40E06F9E663F951E1
+:10F61000DC04CF3F922C3A9443E27239ECC27D76FF
+:10F620001FEA8DAA07242011C853A0DA37A9450A7A
+:10F6300058A9DC8F365902708F2EA99CCE3B19F247
+:10F640009A9818BC56F99C18D7A2F29803CE3DC1DF
+:10F65000ABF3104805F8AADD53EDE5DA44668FD622
+:10F660003E24635ED4CD729B19E2A9592E471EA495
+:10F67000884C921D78AFA65F3971520C49FCC05F6F
+:10F680002776FB0154C9AFF9463F2FD2775B176D40
+:10F69000CCDF1E97E0FE33D06BF8E1CEFDE02E38D4
+:10F6A000CDA417BBFFC5ED04F76B0AF97A37EE3F1F
+:10F6B00074EC7BD1C00D24F43B2AAD9DD86466EB7D
+:10F6C000FCB8EBD9BA37EEBC05D7BD6E3B515688B6
+:10F6D000EBD4C8965107E09EC5C80F997E126E1FE5
+:10F6E000ECF40FD029E7B04F0FF4F9B67641CB6FA9
+:10F6F000123075D787EAE01C86EA5BC8FB6735766F
+:10F7000064C5F441B5185EE672D4FF1EA7DE1D4243
+:10F7100047EDFBDD714AC9D4FDDC3110ECC8113D69
+:10F72000DC0BE9C8A5F3A3F3DFC8F525F173FF648B
+:10F7300098D7C6961BCD20DF6B0379F662FA4EA2EE
+:10F74000A9049997485C18CF19493D32C88F518B4D
+:10F750004241FD41A58424A4C03DB42221DE432CB6
+:10F76000493CFF4B00F9D22DA7548E43EFE5AAF296
+:10F77000A99547557E6BE1A005CE0721624E4BBD92
+:10F78000D484878146B2D90EEBBBEA5FD6727FAED6
+:10F79000D69CE9C7EF977C19E81FADE4FE51ADA5F3
+:10F7A000D084E6605F32AEEB2B217E42E9B0328539
+:10F7B000D979753E5AB9F45CD4137FC83EC123771A
+:10F7C000E27D44CF45033E5FA7B807C0FC55FA5C15
+:10F7D000C3E9A3A58794C0F79D9C2E3DE39B638757
+:10F7E0007BC1892617598FF8E6E13DEEA6C0481384
+:10F7F000ACBFF76AF08D01CF6B13C684E3295BA21F
+:10F80000E099CCF0BC8EB8FFD846E53767455D6D12
+:10F810003CEA15792B3D275CAFB47AA4EA8D1AE750
+:10F82000BDB6B2FE005EBBED416F3CF18C2E4EA525
+:10F8300004EF5739F7C4A31DD1EAD3E77CFE9E78C5
+:10F8400046BF058A7B06CCCFA3EBCC043919EE204A
+:10F85000BD8A2992C39BF5A8E7A435B67BF8AA7F99
+:10F86000A5FA55DA7EAA5FA5DA63F51EFCDA04F77D
+:10F870007C9003A999CA2DC5A7D6CEF64B9B6DEEF9
+:10F880004580573CC53D0EF68D430259ECFB5F5158
+:10F890002FA2E941BC46CE9B0232AE0B3EBA2E648B
+:10F8A0004BE178A8E30F4A48647CA45A0EEB7DDF55
+:10F8B0001CC206AB269837A7EF70E28675ABEF48FF
+:10F8C000769F714D02B3BFB5096CDD52CBCDB692B8
+:10F8D000BB51BF65E2338EFCEE7803AA70DF7C6D0E
+:10F8E00082EB2EA087A9C885F3E863274EF04BFB77
+:10F8F000C84D127C379A54E990D83D7312FC7E8B28
+:10F90000C2EB53ECC8057DED03FB6BE8DF1239CF8A
+:10F91000D8A309EAFD5EE67F3A49771EAF47139800
+:10F92000FF7908529FF42A56F382A9E7394E09E875
+:10F93000D46EBD0D916EBF20313F3D91D14BBB4F79
+:10F9400000C287FEFEBD7B0D44362791E0EF59D5FE
+:10F9500099D0BF8F27CE26B057BB1206F0734C67E5
+:10F960001DD47F25779A128706E55D95E30727CC9E
+:10F9700070422A52DBF55DC3614F45E57A27D0BF5F
+:10F980007D42D760CC41493A3399FCB8F442BE205D
+:10F99000950FCD8AC00733ECC343EDA4D53004FCEA
+:10F9A000D17629CE09F72CDA974A0C5FC9C4F3291E
+:10F9B000C9C23CD3E3997FDDC1EDD53B0959282766
+:10F9C000AA3DA6F3AB83523B0F8F11EF7490CE3D4F
+:10F9D000F1FEAD706EA5C93FA9CD4F3969A105EF04
+:10F9E0007F6CDC63C6FD6B57093BC7EF6A31A27DB4
+:10F9F0008EA6B7696DE688711CB5A4F47B0BE897F9
+:10FA0000A6D424823D4C9B7BD2067CD7D2A543F260
+:10FA10005D7308F645AF2B11BFBB55CBF4F49B12B9
+:10FA200017D1FEE91993B1549F3758E488F7CD4FA9
+:10FA300073BD52E5F14A3A22DF0F9D06793CEF7E15
+:10FA4000F31D1709DEDF6F8863746C886374EC72D2
+:10FA50008F4F781AE4CD9781FAB0583D07E5FB7FC8
+:10FA600035CF943ADE46AF2951A62AD0B0608A1924
+:10FA7000D68914E29A3C1B9475A342E03BA2C7BC12
+:10FA80003B12F3318E6D12EFF9DAD9BDE1CF3716A3
+:10FA9000E077DEA9648D7930A5475989CE09F183D5
+:10FAA000F30BDEB7E9A83C2DE8D39A03F2FBBAE2E8
+:10FAB00026F63118EAC2FDC99252833F40F996DC1E
+:10FAC000400D05A5CB7F03F4A15473008000000016
+:10FAD0001F8B080000000000000BB57D0B7854D58B
+:10FAE000B5F03E73CE3C92992433794E1EC009E1A5
+:10FAF0009D108724BC1F4E9E448830BC0485EA803C
+:10FB000028CF2488D6DFB6DECBC444F4A2B745E9BB
+:10FB1000AFF4D6DB7FB0A2A8200182069AA41340DE
+:10FB2000E4113408A8A8AD5129620BC908EAC5D66A
+:10FB30007BFDD75A7B9FCCCC4922D8DE4E3EBFED11
+:10FB40003E8FBDD75EEFB5F6DA872EC977134B64CB
+:10FB5000CCB7D8C0B64A8C7D87BF1B43ADD96E6089
+:10FB60002C89B196383BB54EE70CC7D284F07E8520
+:10FB700063693E63D5D6D85C16876D7F3F8B85F170
+:10FB80008A58EAD202685BACAE5A95B12546AFDD21
+:10FB90000ECF774EBA3CA48EE12FD8DF3392B12E30
+:10FBA000236B94E2B01F606C0C4350F8CFED56ED20
+:10FBB000D097F0FFE1FD448B2D20C3B8CCA35CECC3
+:10FBC000B0F047BE1B281E4D66CC285E939ADEF827
+:10FBD00046CA652C7672116370DFCA5C8FB22CB88E
+:10FBE000318CA99E18C6A2D833F6F3D98C19F07DB2
+:10FBF000584757F3BBFD7C00C71FFEE54A0C83FB4B
+:10FC00001F29C118570E63171E3C15E3B6C1F5072F
+:10FC1000E5723FF46F4740C687F0926F870BA319D8
+:10FC20007BC4EE1981EBBA63DD7F8FF1DA42F7D93D
+:10FC300003703195B1157E19E7E6F0C27FABB65976
+:10FC400019B384FA95F509117DC018E1B5D2CCD667
+:10FC5000D4DB7AD26305D203E65DB17D8B295DC525
+:10FC6000F9BD93ECD0BFA0C0AB80EF0B0D317E5F30
+:10FC700066089E25DB4799D2E1D6474D661680750A
+:10FC800030A5DDC86C84B50A09F0E61578D3C379D0
+:10FC9000B8C54AE3DDF57F65BF1996BA18E67A2044
+:10FCA0001E9E6F5A51C1727BAEE3AE3FA8652940DC
+:10FCB000BCBBFE4D623E953FFF601E3CFFC0235F14
+:10FCC00020DDF4EB5CEC337ED211B16E376300CFF4
+:10FCD0003241EF3B1F8DBCBFACE9311A6729F39A63
+:10FCE000909E776DD4DFBFE933E4BB654C095D07B7
+:10FCF0003C5C3E9265453CDC618F493C0F20038FA4
+:10FD00008DFD0EDEDF7D64609C37A7277EB5F6E2B1
+:10FD10003AE06F33637F5E67A1F6C23A46ED08BBF7
+:10FD20004AF459DD74F27EE4AFAAC65D261CA7C56D
+:10FD3000FFA78409F04861D3373232572173DF7B44
+:10FD40000EF0F92326B3EF007FBB19E79FF546CFEE
+:10FD50003D48AF1BAF96D37DFDFA1769FC7F249E0B
+:10FD6000F86711AE3B17AF2B5FF6B6AE9FE2BA80D5
+:10FD70009FD95858977CFDEBD2D6A3AD4FBB5F29D6
+:10FD800003DFF5F2BEC6EF23843E58FADCACF5691A
+:10FD9000808ADAE6CFFA77103FB1D328BF1A3F2D19
+:10FDA0001374D2F38D46C76EFE68FA775A9F463FAA
+:10FDB000E07FA7C1896DC06918D7934FF47CA1E794
+:10FDC000834E63477F945F3D1F744A6C416FEBFA2B
+:10FDD00037FB405AD752D55D6687FB7731CF7A3BE8
+:10FDE000AD67235DBFA06C3CFC3394ABE7385F7715
+:10FDF000EB3933973776DCE847BDB936464D71D8D5
+:10FE000004FD80CE9DBBCC3E7C4E9BE7FC3AB77B8D
+:10FE10009011F15E4EED9FD779DC830687EEDFFD12
+:10FE2000AB2BB12ABCDF358C95A3DC77C644C2BBB3
+:10FE3000CF2E133CFB900EC87F4AFBFF7C803AE933
+:10FE4000B9F631A847CF7FFB5FB11E78BEEB5B737D
+:10FE5000796FEB3C2DE807EAE5B413F8EC762167FF
+:10FE6000B73755125D963C33CB84FCCC1EE0F8B41A
+:10FE7000C01FEAD7B6A8D867711D8B1B24D2237A7E
+:10FE80007ADCE59AFA39EADB3BFD85F47E0FFAB0BD
+:10FE9000C789BE77213D8685E831D6A1727854F8AE
+:10FEA00003BEB943F0CD79658DC9007AE4FC338097
+:10FEB0006F007995C2DCBDE9C1FE0ECE877DAD47EE
+:10FEC000BF8EBEE05FF65CCDFA3486EB1F654AEB71
+:10FED00045EF68EBBF8BB96249EF88F5B28E1B49DD
+:10FEE0005EAB2D7C5E6D9D2B9AEE9C817C51B5198D
+:10FEF000E895D973DDA87717F7026F997CD16881EF
+:10FF0000F7BA1E905CA86FFBA283A627EE12F85AE0
+:10FF1000B96DF10C349A8B613E3913F5D1176FC668
+:10FF200024A25C415FFA1E7A35C91F9B711D8CE3C8
+:10FF30007B09E07B8374FDF45BB6B9D03D28ECB956
+:10FF400015FE9BDC83C2F5998EAE6CDBACD0F364FE
+:10FF5000B7DD26B4C7F10EA1BF845EEE5BBE60E1E3
+:10FF600000E7DA1D0EB26F6C8D83F46375D3165300
+:10FF7000B8DDD5E44B93B7B10E3BF15955E313F41B
+:10FF80001CE85FD501FD4A4BC7CF6F55C3F0394E12
+:10FF9000D051AE30A1FEEE4B7F82BEF9B2236C9DF4
+:10FFA000231CC2AE08FD7B2DFDA0C1AD1F57D3079A
+:10FFB0001ADC1ADF6BEBD1F37D5FF0E9E9C2989FA1
+:10FFC000FB0B3AFAAC427A84F5115E05F0DBD66C95
+:10FFD000F53F04F0B6491C7E5F7314C1DFE92C764F
+:10FFE0009F033FAF2A7521B527F0C554F4EB3CD3EE
+:10FFF000109F9A3FC70A1222FC247DABF93779C2C1
+:020000022000DC
+:100000009FDA1BE5CE0713093F4F02F2C3949A8E85
+:10001000391620D9AD8EEDE50A8C3FE5898E395130
+:10002000D05FE8D8C1FB5B3B4E595C8CD5B057CA5A
+:100030004BA07F3BA013C7BB565B60F62C44F95D19
+:100040000D7E9205ECD1EAD3430EA1DCAD6EAF2854
+:1000500097C0EEAC068323813DAA74C706ACB9D421
+:100060006713E0B9E7EDDE65C42F57EBC86EAD3E10
+:10007000AD70B9399248EB5700F62878AF2E1AFCCC
+:1000800055C0575DBCC5559B49D77D51F1D877AB5D
+:100090006AD8758D1EF81EC25167606E07B4AD47F1
+:1000A00087C4757C8FDD6E5DC72A14E08383EB2CDB
+:1000B000D4EAEF179AEC83D0EE151A98B7377DF98A
+:1000C000A483FB8DC0E4E948E7AA23269277FCA12C
+:1000D0001F5829F4511510280EE0A93CCD02D1B1CA
+:1000E000F85CD9E70AB60D12FB24C25F61A1BEDC41
+:1000F00037DCD7DB56E17883C3F984E3A948912A3A
+:1001000094B0794B6C51117D39C5300CD7C3E4687C
+:10011000D756C0AF9C6E58B31BD62F0F8016F0A1D8
+:10012000D85DF2626837164F9197405B6BE476B505
+:10013000D6C09687E3E905811FADFDC0E1D98A7479
+:10014000BFF456FB182BE9AB0C3BC9B9586FADE4B3
+:100150000A50DCD4CA5C5BE15A9DEC619C8FEB19C0
+:10016000F2F11B621C97D9B047057E6D747C40FC90
+:10017000EB8A33DC9B09FDC0131FF17EBAE14A26EE
+:10018000F0F781273ACA15900757B6E1CA40E81F31
+:100190007AE2637E7F220C0906EAF0139F94FB6CDF
+:1001A000382ED7676CBB3B1BE7510C12C9A972C034
+:1001B000E4AF85FFAD8BE5FC54073C82FCF786B0CD
+:1001C000B3EB6B8A5EB602FF2B456E750D8CE3C7F1
+:1001D0008069F4DFDF6A7894AD068A53B0457CBF4E
+:1001E00029D6ADD18135B8B367A15EA87767CF8E28
+:1001F00041BC7A4F225EF3DBDAA7A03E6E78FBFDAE
+:1002000031E8AF22BD709CFC3688DD603D975EEB27
+:10021000B7450E8B473F7014BEE3003996DCDC9F78
+:1002200094543B5B047257EB66AA09D695A28BEBFC
+:100230001A18D72FCFDB3D7FC4F7584680EC4DA16D
+:10024000C3FB31CEAF8F57597B7CAF7A59AFB74CD8
+:10025000B90FC8E8E7C4A737BEB704F5FBEFCDAECA
+:10026000C12AC2E5660F003C3B0D4C61F1C426C3B8
+:1002700094028C3FA35D1B50EE5DCCE90339C33083
+:100280008D80845FE298B0B855AC07DE2F61D08EC8
+:1002900045F86EA0F5C9C857A3984746FD3586F9BD
+:1002A000ADD87635BFE644BC3D19C5EE40BFCFB2F0
+:1002B0008DB9FD61FA63403CF7F726251809EE6811
+:1002C00063FD6CE4D7E82F981DFDAAAEFF342938F2
+:1002D0003E08C874BCEE3A6C6008E70B46BF3D0EA2
+:1002E000FAC1E18AFA2C0B8DD725E8AD8DFBA44924
+:1002F0001DEE407D93C0FB2F1472FB1CFCDCE47FE1
+:100300003613F16359E30F932F673CF75BBD494503
+:10031000F1F1D0D63747339C7F6C4BB401E9F0F252
+:10032000F6BC28E4879D881B587FBCD97E0F8E17AA
+:100330007F05E0CDA4EB6EC2ABA28E8A03BC4E98C3
+:1003400066533700DE5F88AA9F86FC1FDC6160CFA2
+:10035000C2143B4DAE59D8DF7959B5A3BE7D21B348
+:100360003E9AD6B3C340EBD9191D1CB116E0DE305E
+:100370004C2947F8142B53500F2B8622F51EB83EFC
+:10038000349EDB574D2F2F88E7F2F3A404F3E7E107
+:100390007385243FA5B28DE4AE2BC8FC669827690F
+:1003A0006EBB8CF4889E05AC847CAF046406FD496A
+:1003B0001E46498D4936A35F257DEBB62D06BA4F03
+:1003C00011FA76CA87AB2B78DCE33A3D11C63B685D
+:1003D00033325CD764D621A33F38F92A7305907F66
+:1003E000AEF278C60E7FE83F3DAFF3074BC578EE1F
+:1003F000A0BD042F17B2483FAE7473D9E712CDA346
+:100400002A68A78B2DBAFBE8E7C5621B193795C58B
+:100410000BFFA63FEBFF1DE937E05E98EF3E3B9FE9
+:10042000AF54CEF915AEAFABDCE4423CECB2B9DF71
+:100430009D887AB1DDC8B6B2BEE5E979883FFDE0B6
+:10044000730CBB6A65FE7CE2471BAE67C4E68DBEDB
+:100450002858F788417C7CE43BD42343FF333101A7
+:10046000F5F855A15FB456E333E4277B1CE727FB7F
+:100470000D2139BC333E939ED3E40AF90CC7D96FE2
+:10048000F42FF4F46227813FEF44FEDC65631447E8
+:100490003D966A598072A5CDF3BCE0637DBBBE6614
+:1004A0006DAB11D7FD15D80380BB24EDAA29DC9EC6
+:1004B000EF49E27C552A7F4BFE766793C4D0CF4F3D
+:1004C0006EE2FA3B9C3F527BE78F5F225EAFC51F17
+:1004D0005ABCB0FB87F2C791BF8F3F365C933FBEDB
+:1004E0008D453CDCD75C9CC2BEC7BF6914FCD0D72D
+:1004F000FDF156AEE7F4D75F1178DD67DA383D17C6
+:10050000F5C0CD0617CA39503F7D36AC635F347FE6
+:100510008F296BB2B0BF4BE17A65579399F4CA2E1D
+:100520009BD74B76DC6961E83F30C5DBF133D4877C
+:100530006916754318FF2E8DE7FC566F0C8CFF0C67
+:10054000FDE2A39CCEE36ECE934DF05CEA522EE723
+:1005500005174C5B300E2B4D28DC817C7402751620
+:10056000B4D5E7E029407CD53913E9BBD75A4E967C
+:10057000617E11FC1E37F2D9D8FD27CB8A72F07943
+:10058000AE4FF78A56EB8FC735C5B3EE78D723EC5D
+:10059000C678C6F59207F92437D4676E23C56B1A5F
+:1005A0003FD447033F805CCC67AA3116869C73CE4C
+:1005B000F330984336A73C92CEF303D3283E9C7B7E
+:1005C000BAFD55D0CC6C9E47775FF0C17C1D1F8073
+:1005D0009D3D1E8FFED2F180C980F399D664737F52
+:1005E000684D16F293264FF4033CD5FF61D8B31B38
+:1005F000C2EC7B6C0297A3C75D0ADDF77598FC839C
+:10060000E1D2BF33FE5EBDB03F9FA33C63FC70DF11
+:100610002B0BD18EE62F771F44FC4F4F92E9FA2F18
+:1006200058C09285F47129E497D51BD5E2CFA4D0A8
+:10063000734CF10CB3C1FDFD49D1F9387F6982F7E4
+:1006400022D28929C123F8DED80979F9285FB65169
+:100650007509688F34B801AEF2ADB6101C1A5C672C
+:10066000055F94262CBE88EBC7F750BF347E7CDE36
+:1006700082EF6B74AF6FFE82D33B8CFE48EF10FDB0
+:10068000A53BB0AFE1E12BA157B4FE3F4A7F2D7FE0
+:10069000704DFA637E20F6EFA2BF352129447FF02A
+:1006A000B3E2B1AFF7B3EA4DE077E7F4BC5EE82818
+:1006B000A4E75D265821FA552D1077A23C7A1DB487
+:1006C0002FB0C7CEE7EAFAC3F9FEE022B2C109F1C2
+:1006D00084F76A537008FA21A30212F985A340F047
+:1006E0001791FF95417ACF25F0C4CE4BD2F961DC4A
+:1006F00045FF2E1DFDC34002FA51A3CC1501E4F7BE
+:10070000DDD629E9E8D7E5592765215FBD3AECBE7A
+:10071000E368825E4D5BBEE73935E4FF68FAEDA021
+:1007200018569BBF2081EBA11B41DDA21F882E63C1
+:10073000381C9A3E47F2201C5260BEE13B2BE9E593
+:10074000A60EA0C78D0807E0A155620DA8CF0B0D1E
+:10075000EEC462F4D392020AF7F7BEE98FF9C18AB8
+:10076000A637DE43782B703F04E35097F162773E63
+:1007700062604F3F58F357B4B840F367B4F813FDC5
+:100780001EBC3F405CB79B0140B447018BBF06E6EF
+:100790007FF2B23ADC2DE4568175548875CC64ED55
+:1007A0000417FBF6BBEF26017D66087C541C81B85C
+:1007B0003117EF337633E0E16685C79337BB207E90
+:1007C0000CE3A399E322FBF89B921C1AE75ACFEBA8
+:1007D000EDC044DDFECC3FDA1E017BF409B8CEC784
+:1007E000D6F1B874C240D9A7A0E11C9769407EAC8D
+:1007F00016F60DC2E85EEDD24BC22F9E60E8C875BA
+:10080000017E5BF7FF8DECE081FD7F7B07FDBCF196
+:100810009F2BCC0CEF4FF8BC200EF5041BA7125FEA
+:1008200069E356FFA9C1CAF875E2FF2AB1F6C30011
+:100830008F7B28C267A1F677179FDC84E37D794E12
+:10084000E1BC2DE62F337907611EBBCCC4F30187D1
+:1008500025EEFF68F70F1B016EB8BE2941CB0BB424
+:1008600093DDC79F398CCE37633E202F44D79B2F13
+:10087000947FAEE4F6A40FFEFE37F2015A1E60AB81
+:10088000C01F3B78D6A4025C531BEE51D0BF9EEA3A
+:1008900094993B6CDE9B542B7387E5039E49D0F9FA
+:1008A00023075FDC3403EC49759BEC8A42796DDAEF
+:1008B000753C17FBEDB2CBDA0B1FE9F13BB5E91E36
+:1008C00005F9DF98A8927C5F6BFE0923804F6E408C
+:1008D000BA33F2EB3AC74824477AFA1ED8FFEB84C2
+:1008E0008E9CBEF1DD17FDF574F8DDC522DAEFB997
+:1008F000163DF47CDB02EBF4C1FA02B04E1FF85D4A
+:1009000007D6D9A97F689D93FA1ABF5637FF3601DB
+:10091000FD368D4F4B1338DF8CDFB72981D942F478
+:10092000D2F0F5A1B0577BA3347FC3356F065C3A94
+:1009300005768718D4C7DA9D6342F66BFEE932F27A
+:100940003734FB355F5E544A6A53D82F4C23A35E7D
+:10095000D3DBA9B9EA6223EBCD3E2D88EC97B76DC6
+:100960005462A867203A4992C087F0B33538CE3038
+:100970000FC1A9A7A706971E1E6D7D9A7F3D5FD068
+:100980006FCEA04C23C2DFC3AE8A75E2409887B811
+:100990005EBBFAB58E9FAF5C28792BB717BEED8B87
+:1009A0007FF5F7357D508613E451EB43BFC298982D
+:1009B0004C742BBB6A626EB01B2C238A7D1A66575F
+:1009C00058C550E29F7B851DEE8B7FAAAECACC9B9B
+:1009D0001FE22363E31356E4A37DCA462BE62727D1
+:1009E000DB66D5C6019E4AFE543417FDBCEA0E03F1
+:1009F000C3145669D3170731AEAF7E8FB9502F1687
+:100A000035B51623DF1D52DA658AB3BF64EC893031
+:100A10007FB1B1A9D68AFE5463A24C71FC6107E78D
+:100A20004BEDFE9644AE3F1ACF5D9EE1EEE5FE191A
+:100A300071BFE4E33CE2A3B24741AE310E4D8AA15F
+:100A4000BC4489649F53817EC84D46F2F3218EF9E0
+:100A500023EE035E6A34EFC2D47E69E323F7D881C4
+:100A600010F5FFFD698D19F30BB324D7B3F05C9932
+:100A70001A6CC57ED9DC4CAA7B18FB3F32F9B3C196
+:100A80005B25CA8B9401BB60BF6C51A61FF313FB9F
+:100A900025DEF735F37D0266F725CC8079DEAE489A
+:100AA00018B581784AEB0FCEDBC0042387C557F712
+:100AB000ED9549CFDC572AF971BFA9D49ECE7C6150
+:100AC0007C55F6A889D635BB29A508F9784EB9CC4E
+:100AD000FC61FC1D107EE13C0FC4E161EF1D8EE264
+:100AE00070051703DC52486EA7093E9FC5B89F38B2
+:100AF0007F4142C47BF0C62D688F6E6D8238157AB7
+:100B0000D344FC7AAB373D625E0FE37ECD09162CF1
+:100B10008983F1FB250D24FE9B11B48F0EA8A877C5
+:100B2000CE24A25E63C3B89C6872572AAFAE237E00
+:100B300070F27DB2791248938CFA2F529E668E8B9A
+:100B4000ECCF72F7A83788907FBD5ED7E47E5EB3A6
+:100B50004CFB72F30A2517EB453FE8FDECB1D17D64
+:100B6000E8856FD587E37AD30B1F96FF5D7AE13571
+:100B7000082BC681FCFE3451E8877EAC1FEA875201
+:100B800079FB26E4972EB077E65EF845B3175A3C1A
+:100B90005E06F24AF27E91EF67945E4D65BEFC50B0
+:100BA0003CDEAD2FC09F70F5E2E73C9D984572D4C6
+:100BB000AD5F34FD11E64F18C7FCE3FE4429F89100
+:100BC000A63C842F83E02B633C1F5886854398976F
+:100BD000737E41F9966A88F329DE67BF25B850CF46
+:100BE00049F12139D0FB195A5ED72AF2087ABEE8BA
+:100BF000CEF3CD35521D8CC61765762E1F657365F5
+:100C0000CABBEBF9449B4FCF1F015D5EE69AFC2106
+:100C1000E4EC87F24773A2D8571DC4065D0F5F68E6
+:100C2000FCA0F187DE8E1CD3E567FAB2236FA21D0C
+:100C300019DDB71D797D9891F4B5DE7E68F6E2770F
+:100C4000495C2F6724F27D8E69C3E7D9D0EFB026C7
+:100C5000F13A0DCD0E75E79736737E78BD63892224
+:100C6000A13D41BD9019867F916FD5F8AFEA5189BA
+:100C7000F28D15422F7536F3FC5B7589ECB7C0FF1A
+:100C800016373DB189F78D949F2B545A150B8C3B29
+:100C9000D325B930AFE316F9BA196E89E7EB5C9149
+:100CA000FBF42D3AFACE117C349305EBD01FD7EB31
+:100CB000A53957B95FA0D74F73C4BEFB1CDDBEFB7F
+:100CC000554DDE07B001FF4C7FC09CF4FDFE80F661
+:100CD000BE46478D7E2AEEC5A11C1DFCC6A4C6706B
+:100CE000FF19E937F5AA42E3D893045F0A7FE6CB00
+:100CF0008B79BFA0984F3C5FDDF485C93BB26FF89C
+:100D0000AFE5B7C6A29F3E3AE4B76BF34E53184B1C
+:100D100047C74C674F6689EB3FD47E0CD7AD43A3E2
+:100D200083A6477BE059E8D9BEE8742D3DABE9B313
+:100D30007FB69ED5C6D7EC8036AF5EFFF615B76995
+:100D4000FA74FD1603E54B268BF878B2C8C3CE4F74
+:100D5000E2F1C1AD493CEEECFACA62407BB9B38521
+:100D6000FB272EB3FD38FA05A17C1FA7E7C331CCC2
+:100D700087FBEC4C69B7D0BE67119012F73DD3F8F2
+:100D8000BEE77625E0213DED52580DC8C9397C0FEC
+:100D9000E679F8806F21EAE9873F1962A0FD77259F
+:100DA000D08EFEC9D83C85F68F1C6695F2C19DCDCC
+:100DB000663BBED7B5EFFFB41A719CAF980B43B832
+:100DC00043CDE6EEFD1BD407A5729B8CF9FBAE204C
+:100DD000C8083C3F6941A018E3A0C9ACBD16E57B3B
+:100DE00002D2B117FAFD2A498BB37BCFEF173773C5
+:100DF0003FAE3846263F6E8AAFBD18F7ADA62892A3
+:100E0000AB169FD5E5F75FD1C51FA1FCBEAAF0FACE
+:100E1000435DFEBE91EB99EBCDEB4F40DD067CBC14
+:100E20005EE373A16F581FF9FD9D26BEEF133C6969
+:100E300064E807B30B89BDE663AE95E7DFD712ED33
+:100E40005663719F8EFBEBFB5AD2DC6A6EDFCFE7F5
+:100E500076048BD03CEEDC3E5BA1FA35911FEDB100
+:100E60007FD2C7FE88BBD17E08D5695FFB21C55FF5
+:100E7000AA94F6B95EBC69750B4CD43FDDC8B49F2B
+:100E80009BE474E7F96837F2F9CEF3696E84EB7985
+:100E9000C1A71ADFEF3B77399AF6414D6E15F78FF0
+:100EA000830E8BEB59E25BCEEFF5A943FCB84FFB09
+:100EB0001B21173BA383C7B213C3F73DF83E47CBB3
+:100EC000BA47679F33D27EB984F9486D7FD90772DC
+:100ED00043753DF18CE20F23AB67386FAD9BFD1A74
+:100EE000DB2993D438C4FBE5446D1F538DA33CC468
+:100EF000B757A8CE508FFFDDEB9807EB511AD659A4
+:100F00003C0AC8FFABEBECD46F5CE7A476FF3A95E4
+:100F1000DA878EC73E8076BFDA6DF22861FAE39DEC
+:100F200064EE77E5657F524CC5DF7F6354873EE50D
+:100F3000C10E19F5C58D57611D117527CA65C437D6
+:100F4000E537B342FD4C69710CF66FBC0AFDB0E7A2
+:100F5000AF2439B83DAA53EA462793B4105FFC2D5D
+:100F6000C9DD9104D7EF71783EC176B734FFE02533
+:100F700046FD73BC7FAB7C099ECB0F14525E391FBC
+:100F8000F3CA7934EC42C4DFE85613ED976BF9DD10
+:100F90003C4DFEBE8ECC33E78BBCEEABAC83F2CDCA
+:100FA000051608B40C0817A79F5B9AE794301F98A2
+:100FB000647261BDC3E82C4F3EE6635B9318C5477E
+:100FC000ADADC9196A0E720FCFFBBAB5BC2FFBFECF
+:100FD000BCEF918F627DA4B7AE9A687FFAC8A9581A
+:100FE0005780F60B2DE4FF69F5C82DD1BCCE806586
+:100FF0002CA03CD38DA29ED162F69A93495F050E38
+:101000009E80F77E7F99F17DC7F60F695FBBD83070
+:101010003C05EB7E0F4A43E3B07DEAA3D81C6A4F40
+:10102000C55E44FCB418AC2ACE7B669D5A82756DB1
+:1010300027D6B112AC637B6B9D85DA93EBECD49E23
+:101040005AE7A4F675B88EFC731C9E477E71BF6587
+:10105000A37D92296FD9146CF316C650BBFBB6184A
+:1010600013C2DB12CBB66BF360BD5A203AD080C9F5
+:10107000FED6A7BC8F59FA81DD337B474AA3186B94
+:101080007BCA3B5D990CE34EEDFF93AFE0FE9BC93D
+:10109000CB1EB3005C734FD91ADAA0FF76F2F2C709
+:1010A0006CA86F8F4783D2C3F5AE38EE1E0474432D
+:1010B000A590C605978D837E82D65F31BD6412638D
+:1010C000B71477643360ADECE495D32D80C75BAC87
+:1010D000DE1F63DFE44B9A5ED20FFBCC87F56041E5
+:1010E000C948713FCB9012B1FE65A6C3FB4672584A
+:1010F000FD9E5BFA13ED338D714BCC41871F8CB491
+:10110000EFC5EC1F2784CBDB4C47E91B488F89C90F
+:10111000BC0E78F424C91D5E5FA17F6EF439B5045E
+:10112000E934E642591DB633CB1DD4F72C185B8742
+:10113000F25C62EBEBFD627ABF3C99D78D142952C9
+:10114000445D89FEB97C6026F48F8347A3294F3024
+:10115000FAB4B716EB4F4B9D9979B2A6FAA8EFD81F
+:1011600082FB6DA32BCE9424A0FCD824179A89313E
+:10117000ACA32E01EE17DAB1A00AD7F54431D6FFA1
+:101180008C562517A2ADD0DDDA80EF17BA625C85E8
+:10119000E88F9F564BD0F49C52469D2880E7A60EC0
+:1011A000925D1618E854E0A68997A05F382C8EF25D
+:1011B000BC85CA9A2B27A81FE3AA51711D5B7E5DCF
+:1011C00045E398C9AEEF9E51FC2FC83F459E38CAF3
+:1011D00009023E4AC2EBCA60DD0477A15DF64749C9
+:1011E000C8DFFF5A6287FEEEFE1296CBC37CC3FFB8
+:1011F00042F78F44AB5100E86E93BD04C7DB6D929C
+:10120000EC0F51DF538CCFFB861855CC1F9525462C
+:10121000458C3FB5441A7F0EE1CF891B85D7CA3371
+:101220001C11F7DB6EB3929DA8782B87FCA2B6DB6E
+:10123000D2C95E54BC35A908DB3603F7D32BDEAA2E
+:1012400028A7FB061E07572CFC915BF429EEAD582E
+:101250005849FD5629E52738DF959CB83CCCAF4D61
+:101260001B945AA244F8810349FEF3447EAFD03068
+:101270007CD32480FFDEA37C9FA2222733E2F919CE
+:1012800005524978FDA8675254447F7689A324BC4F
+:101290000E756E456A44FF96B99911FD92A30564D7
+:1012A000BF410F5494801E380AED5260C1025107AD
+:1012B000A5E59F0A054B15B68BBCACC2E3EB61F00C
+:1012C000877AB0C41669A77747733B5FCED6D0063E
+:1012D00049F911BEBF5D9668FC24DC4E94CB1536EF
+:1012E0005E97158987BCA346B2977931921FE3FABE
+:1012F00092A34BEBD0F4966744BEAFF961E5023E92
+:101300006D5EE673B7A33FA2C1ADCDAFC15F2E2F17
+:101310002AA17CF735D6A18797C17A503FE8E168CA
+:101320004A16FE1AF81FE4AF897324F04BECCD7E09
+:101330006BFE7A05E82B47B8BEB2498958B7D797F4
+:10134000BED2C6EDCB2FD3C69DE9F0D0FBEE1D9FDC
+:101350009E9A2087F5333F4E880FEFBFF8E9A688A5
+:10136000FB491FCF7184F7B77E3A07EF4F51D45A2C
+:101370001BF0E53126B97CC8076DAA1203F4283E9C
+:10138000EDAEC3B6F4432F96ABB2A9E77C75D84E49
+:10139000BCE86F33C3BA6E1A26AB18BF6B7E881ECB
+:1013A000DEBF26F3BCC3B1ABAA15F75977FB542BAC
+:1013B000FAF3BB1F54ADE887EC76F37319EE2C03F8
+:1013C0009D8F7167F37AC5BF24F3BA834EF1BED601
+:1013D000FA8DDE4E841BEBCCD137A8FA264875E592
+:1013E000C7D0BFCAE9E95F1D53FC369CEFD8837EA6
+:1013F0005BF87EE2F5FA577F041E43380A99E40948
+:10140000D723C596284FB8DC96DA1D11FD93C20F7D
+:1014100099EA4C8D78EF263533E239F01B87A15FCE
+:10142000526B62546FEB33F07A5B3D1E57A4F0F8B9
+:10143000CE65B3A33B83FB66726FE7915CC5865EA6
+:10144000CFB7A5A4707FF03F5218C1352B85C3A735
+:10145000AFAFD5F76BF17C0FE293B99CC8E72EAB29
+:10146000E10AB8BCACE0E927A6535D6DBEE1DE2C15
+:10147000E8573CBD753AAFAB35ECC13ADB194F3F8D
+:10148000CFEFDF60C837823FB0CDF7C274AC2BAF6F
+:101490008AE2F5095551A23EB46E7444DCA3183EAD
+:1014A0007E6A21C69FFB8D0CF3FC8F99C00EE685EA
+:1014B000F6D9AD661EAF5A4DBC0E7C7DE6A9F5A8E7
+:1014C0003F3E8BF2E6A5509EB148453C5EB45BA81A
+:1014D0003EF4BE7DA529C807B35278DE2B7BCF44EE
+:1014E000279D2FFBE7C151FC7D7060FD308E73712D
+:1014F0007736F9E5D903189D27D1E801E1335D8FEF
+:1015000082F081CE6330B713F36FB50E138D332B9A
+:1015100085F3E3F5B63DEA89E30C6B7641BB2085A4
+:10152000C7CDB7E2BC046FB0FF2CDCD0B307FBCF54
+:101530001EC9FB486F59CE0BA27F1BFC510CEDC39B
+:10154000BC1FCDF1C63282B46FF3EEA26CD706BADF
+:10155000CEF1B8C03FB0B643C5FA0F7F3FACB71865
+:10156000E8F42E457CDC66F60F26BEB2AD89C17963
+:10157000AEB7DEB8EFF921E0047B327F3CA79736A7
+:101580003FE0D882747C579C3BD1E001387E8C7060
+:10159000687075C3A3AB3FEF147E7B278E971BCA81
+:1015A0005357FFC940798A6A09F424F4F77CC85C70
+:1015B0003E95E8437950DCD2C2F9C69F58526C83FD
+:1015C000B6A071158F8FDB9588BC9866CF268AE709
+:1015D000C7BEA744D8A38922FE1DAFCB4F4E6C9C3B
+:1015E0004EE7F826EAE2E25FA488BC651A4B0BCF0F
+:1015F00023AC15F1C6E5B68171E89F2A10E7CA80D1
+:101600006F932AB371F121BDD0B08E459C53D4F8AD
+:1016100070E469FB9D38DFC8D3EC0EF207B471BBF0
+:10162000F3131C2F97DFE37819D531ECE949D03754
+:101630001E3132BF1A5AE7040E2A833087E2A4CB48
+:10164000176C645FC61C9D43F5DE66A781A961EB3C
+:101650008F52A3991AA62FADC3E223FAB2A04F5D11
+:1016600054A41F902FE68971A5458CB73FBEEC08A6
+:10167000FA05F9B6E5E417C48D1B18311E6B532229
+:10168000FC833CE67163DCE802FAE27ED998D34A37
+:10169000841F302EB091CEA18EFB30F2FA8473916C
+:1016A000FD037DD1A52FFCB1DCA7D12FFCA1F873E0
+:1016B000B823F197501E89BF244F24FE521644E2EE
+:1016C00027D51B898FF4E52322EEF75B9317D11FF3
+:1016D000F0C08488E733C18085F7B31E9D16F1FC06
+:1016E000E08DB323FA4337DF16F1FC70FF9288FBDD
+:1016F000D9DB56FE207A8FAC5F1BF1BC9EDE3734FF
+:10170000FE34627C8DDE3EF8FBDFA437730AFF50A7
+:10171000D03B51D859879BD7AD75196D8FE2797C35
+:101720003C3682FACE81E7E963D1FEAB5497E79B62
+:10173000C6685FFB97B24742BD940EA8356451BDA1
+:101740003CD5F5FDDC6088D867B73BB93F6477725C
+:101750003DFE6B133F2F950EFE26D929030BC5D9ED
+:1017600016AC77648299AC8F639C5DE7E818A63A63
+:10177000306F07FDC921BDAAE9D1DBCC6A6D07E84E
+:10178000975132D793A03FFB39619EF7A5078DDCB7
+:10179000FFF019D1FF48B7305F6C1ED919CA433B1F
+:1017A00058A284E700E2427A5CFD0E8875706536C7
+:1017B0009DC37A134140BF5975D17ED3AD9A9E5ACD
+:1017C0003E9CF4D4655BA4FF767969165D3F7BBBD4
+:1017D00099EA07CE8A3A470D0FFAF3D6DA396CED5B
+:1017E000FEF22D9B62D0EF3C2BCEFF6AD7270BFC7D
+:1017F0004D76CAC2FE59D6603E6C1118F138C07BD6
+:10180000E5918ED8DB18F99B9370DD555BAEDCFE5D
+:101810002AF4AB0DC1646E377CF4DEFC77F9B9EEC7
+:10182000F97F8BFCAE408593C7F91562FC5BA0B1D4
+:10183000039E6E013A38B07D635219F2275CA7F31C
+:1018400071338F3023CAF32C6F26D54D9C62AE3393
+:101850007B01C4F94E95E09CCB3C46CC5BBD737BD1
+:10186000650C3ED73D9E360E300CFA25EF3A7CC60D
+:1018700064CC1B4CE67513309F05AF7B16A53F8CDF
+:1018800076499BEF1DE6BD7406E83B9BB9685C6D2D
+:101890007C86E9F9303DB57BF9AA8F1260BEB54769
+:1018A0000D948F58DB6CA678AD6BE57FED780AEE72
+:1018B000DF91DED10FEDF6FB2BFF3604F9E1D6CD3B
+:1018C000325381DEAADD7BA7336C5FE5ECD22B318E
+:1018D000781FECEED6A7D058BE6CA63AE2F757BEFA
+:1018E0003C24DC8FAD74162EC7F7D8B8EB3BEF580D
+:1018F000FCD2F014AAF712FCB442F0D3DA178792A4
+:10190000BFB536A69B9F787F2BAF1BD1D67146F013
+:10191000E3CA97BE89F8CEC46EE023D5CCF7C5D410
+:10192000A160EFDB2EE7D2771F8CDE7F75C2BC2D66
+:10193000573F89C5FE9E37FF4AF0B3B9D7072FCA74
+:10194000A26F4C687F5A3BEFB9A029211FE90E72A4
+:10195000B601C7BFED772F5EFA00F1D3FCF2D69F38
+:10196000E133D779FE7397967714F6C625F001F622
+:1019700086E28B2E16CDCF9308FF46C11DF92CFAB7
+:101980009E874A7CED66C7711FA7B6D5407526B104
+:10199000B8091496AF8B950D9A51725B9CA0AF85D8
+:1019A0009EF97FCEDB2AEAA83E20D21F2A38B43225
+:1019B000C20FF2C05FAF7ED033DE5ACC2FE9FDA15B
+:1019C000F101C36253DCF7F84587A6F5EA174140F9
+:1019D000ED96C688AD21F835E8F4F37E2157F53849
+:1019E00016E6FF03D1FCFC33980EF47B7F9ACAF510
+:1019F000B72D83F1F36952E7300BE8CB16E7A2C7A6
+:101A00001F856B96417CDDD8AFA53335F9C47FDDEA
+:101A10007ED7A111A4B7D8B7301BE243E43DF474DC
+:101A20002BC0F3ECF9617227DE0F1CFE6B2CE67DF8
+:101A300077C4AB6F213D824765DAFF89523A4C8EFD
+:101A40005EE2BB57510F029FCAA9DC1E581A797E6D
+:101A5000D1A2BA19C60F5176FBA8F0737F8D4E1E26
+:101A60004F561E7EBFBF09E871C9D0169B03E3AF76
+:101A7000DEBB3B16DDFF0C93F703E4C35567DF1EA7
+:101A800063A7FCCD96FE180FD607F87730462ACC10
+:101A9000A7E4F584A37A332C2601CFE927503BB283
+:101AA000297F19F2597580AF13C7C642BEE18D1266
+:101AB000F53B1B6BE371BCEADF37A7A13CBD9CC4BF
+:101AC000E3CD97AE66F3F715A6E0F341A74310D335
+:101AD0006FC0F8E46511D7745E95E9396DFE918D9C
+:101AE00085B21DF82127B0F100C5514D6615E91AE0
+:101AF000F51CE378688A22B9AF6E99CAD0EE7739BF
+:101B0000984B82FB3BA2837FA4F36ECD6615F3ADA9
+:101B100051F68D2C1EC6DF21F659870347E179293E
+:101B2000EDBA365F54D3D31873203F50DE374AD90D
+:101B3000C826DBC2F11C437876A4723EDA111D3050
+:101B4000609E253898B16709AE109C8CE6D5E01CE4
+:101B5000EEC7F3843B4CC1F3786E06E0B223FD87F9
+:101B6000330E276B1AAA629E20CAEEA67544D95579
+:101B7000974FEA0957752EF3A35DFFF943AC5B6EEF
+:101B8000518EABA3437D0BC8C08E814CC8F9CF1FCB
+:101B90002FC908EF836219177A7FC8AF363E5E37C8
+:101BA00089E2099F8CF12FB431F1B84E95D6A76028
+:101BB0008A298FE301F7DBAD167EBFFB79E06F1B4F
+:101BC000F66DFC39579CDD3A4D2239E1F5B8421FDC
+:101BD000DC2705CEDF08A4FD2A702057055856BF24
+:101BE000B19FF87495A1E9A99170FFEE28AF2B156C
+:101BF000E67BED43039D6BFDF38B51FE0AC0C7B03E
+:101C00007D5B92DDBDC8877EFC47DE7BE8C974A49E
+:101C1000FF3E49C53C6C973148DF37A96AFACC448E
+:101C2000F50D8D1F53DDD39BA9DE4938CFB8C61AF9
+:101C3000DA8F1ECF36D27E74B6380F5EEFE4FAE349
+:101C4000F2E921CFD684E17F492A972F16F40E407E
+:101C5000B96912F2D9827E0AB47B85BFB4B7F5D6D2
+:101C60002C352C7F58C30EA423BE1F6287A8D5AE87
+:101C700077F9F9B9CAEC772C77B8C3F86F9190F778
+:101C800045A9224F96EA9D8DF0AE6AFDC414ABE2E1
+:101C90003999FAFE6857EAC19FB2F782976EB9D5B3
+:101CA000C951B51234E1F3D517F8F957A0731D9E49
+:101CB0003778F99DC6118BE1FA5EC035D695FACE1C
+:101CC0009AA9BE72AFD1938ECFD79CF93A17F55629
+:101CD000090201F07CDDBC6A00E20DF8BE281AE5BD
+:101CE0006B17233DA6C9670ECA27BC9F837C5F8004
+:101CF000FDE1A4877798DAF9F9D3BDFCFC29F03D22
+:101D0000C901F0BD1DFD861C3BC801BD3F94E47BAD
+:101D100047BB81CEC9FA408F0FA67ED11CECEF687D
+:101D20002FB1937C635E3F0FE5347080C6A987D8DE
+:101D3000044927314FB83FD9E88C25BA69FAF1B088
+:101D400093093BA1C6E17903AB2C47C845983DE414
+:101D50007D612F4FFC2AF0F82FD176B8855D10FEFB
+:101D600014F3E6939EBF57D8AAB5AF4F98B91DD6C6
+:101D7000B9F684DC5D3F8EFE6B40F0C901E1CFA275
+:101D80009D5013783D0E5E1FBD99D7D58E71AF293A
+:101D9000C6B3CFE3CA371EC47682A7BE18CF3E4F64
+:101DA0005AD07E909F81E6E7D91B0EDC948DFBDE36
+:101DB0005D67CD0CF75D1AFE1AFCE34B8087FB5B79
+:101DC00000FFBDD825580EF11F58EC74E6EC79BF22
+:101DD0004BD2F4C7A90AE4C7CE0639D40740AA807B
+:101DE000C1B1FFDBD4938FFBA09F95E67E3E15FD2E
+:101DF000ED742FB55D27FF9A8CB660EF69EE47351D
+:101E000098DCD9C83F0D0323BF1FA0B54FA61A8980
+:101E10000E057D7CBFEB482ACF6F0EF1B1C7908FC6
+:101E2000AA1A64BB1FE87EA941769BC01F3AEFF651
+:101E300026E3D99C0BCC77CB44B4F3228ED4BEF7E7
+:101E40007217FA2960A7EEFE65EFFB0FAB99F65B00
+:101E50006340BE5AD624B1FF001C2C7F26F2F9D570
+:101E6000DAF76A1AB71CC6EF88AD7C4E771FFD15EE
+:101E7000FA0E46A41F732455F827592C0BFD13E0C6
+:101E800023D20F46851D3103DFAE48F7EE437BFCBE
+:101E9000B2F8BE02E85192C77D4E615744FD4170D1
+:101EA00007AF2B1EBECD2F1BE0FD098A5F467BC509
+:101EB000A0C57D87716E6F197D87C9E73E8DFB3E9A
+:101EC000CB853E5CAEF9697EBE3F026637C24FAB42
+:101ED00016AB1FCFFCB5B1B8FE6D12C5CBABB64586
+:101EE000EEA7548BF5AFDE7CF2309ABCCA7ADD7D6A
+:101EF000B1FE6ADDFAB57DF3CF5323EBBFAE773F7A
+:101F0000E42F46EE37BC2DC6D1EE9BD2B87EAC8214
+:101F10006520DD56FB65BF9FFB7936FC5ED09D6278
+:101F20005D770AFAD33AE1B9CA6D923F803CFE78F8
+:101F3000649DE95DF58BCB90AE7A3E5929D6BD7C88
+:101F4000BB91FC55FCFE0FCA9D9E3F568AF5AFD44F
+:101F5000ADBFCA2BE9E0E37E744FF8EA6F413A5710
+:101F60006E37B2DEE0D3E8B552E3EB3EE0D5E0D425
+:101F7000E0FEA1F0F64F13F9AD116C04D1A93CE1DC
+:101F8000BAE8A4F773771D1E41DF5BBB7C6420C5F4
+:101F9000FB1A1FE8DF2F137EF2D4CDDC6FBCD458C0
+:101FA0006C1D89F14C9BC125A9149FC58E04BCE40E
+:101FB00037CBAC02FA5D4D599BF0FB8379270AE6DB
+:101FC00060FC9F7FC240E7EFF61C29A07DE7FCA3E1
+:101FD0008312B228CFEDA2EFE3C038645FBBDAF220
+:101FE00036E1F984AEB692021C5782E7D00FC813CF
+:101FF00076A2A62DCF1A7EFE7C4C1A8FEFD73B3FE0
+:10200000FD39FAE9537719E99CC55463F04DACDB0F
+:10201000DA7344A17DF2D527963C1485F47D51A254
+:102020007DF2C3ED6B1317229F3519EDB8EFDDD5A7
+:10203000F4E30378DFB75DA2EF5E54379766EF8075
+:102040007EDE967C57F8F9B33C874AF0B1542BC535
+:10205000CF53FB19C96E5E4CB3FE16FD9F95EE2D56
+:1020600024DF17F7EF3151DDDE0E89A1293BEC3C6F
+:10207000F80AE2E3E2AB274DE88417379C34757C1D
+:102080008F3F70C92FB300C5CD1B4D18C7546ED1FB
+:10209000FA1D26A49347F84755CF7D4CFD95E8CF10
+:1020A000C37C2B9F91A97EF760F36B26E4E7AAED32
+:1020B000124BC90CBBBF598AF85EC312C6F96089BE
+:1020C000D03FAB987F7D1A3CB76A23AF5B608F46E9
+:1020D000D6016BFCBD42F0F7AAEDB3E8FB533DBE61
+:1020E0005B8871E30DF81CE7EF659B23EFAF107C75
+:1020F000BD42C7D73F4913FA67381B8E7CFD75A1D7
+:102100001A9703D7BF3EB972406FE7ECDB84BDD6A8
+:10211000ECE5E58081EC8DFEB9CEC62B046775DB5E
+:102120006513FAA7654D5F10FE2B9A5AA97EE466E7
+:10213000E65D8DF8BAB9C96A47B9AEE8E07A685A7F
+:1021400093D9EF97F07E3DD53977B5F0BA49DF7E68
+:1021500089FC1C4D8F69DF775C26F0B80C14787A07
+:102160001EFABB3C6EAE1271F28A615B0EE33E7BDF
+:1021700095B8BFFAE8C158F40FA7B12F6E47FAC05F
+:102180007C0CE763CF44E27DBAD08BD3B773BDA894
+:10219000B76B5DA9D933298F09712AC2B57A7B241F
+:1021A000BEAB74F1F963693C3FF6820EDF15416600
+:1021B000CD413854D9E5A7A7DB159CF7482ED85B4D
+:1021C000B4936AD6F77E87F14DE1676BFD99E21C07
+:1021D00078BD7DA32D3C6E8E4AE7FEC2CAF1B20FD8
+:1021E000E9D51D6F0C3A98AB1A42F106C419CD69B6
+:1021F000493CEEC082923732649698188A371E7135
+:102200006EAAC8837EF5762EF79DE3603C3C7FADD9
+:1022100030F247ABB79BE99C6235D09FE28A267EBD
+:102220009EC2D3249522DDC15F3F9A86FBB19852AE
+:102230008575CF6AE47C3FABE40BE297A383F87A21
+:102240002F2B6A4A6FFEBBE6B7E3F93035CC7FAF80
+:102250000239C5E7AB9A783D52C3816FFA67A29EF7
+:102260006BFEAFFE8BA1FD5AD845CD2F0C825F3897
+:1022700090FB45F4BDC9BB857C2DB3F37DBABB850E
+:10228000FD61521DF17995B1FE503CFA593B78BD84
+:1022900000DB871F8503FDF8F64B75F1B0EECE9796
+:1022A00024AA87C3F7F17B949D4BEA3F41BFFBEB28
+:1022B0001D16F237EF06BF654A5E4FB9D4E45BFBEB
+:1022C0006E560D7B88FCCF87581DB595829F3B1BB2
+:1022D0006BE9FBA09ABF42EF0FECE98F540ABEAF47
+:1022E000D4F15F547A24DFD5BC1D4D7E63D751D91C
+:1022F0008EFB3180AFDFA485E345F8210D07A2886E
+:10230000AE5D276D6447FE2CF8EDA2C83FD78C93D5
+:10231000090F86F1BCCD6E796D20D211F18EF5F7E3
+:102320002FB7BC36829FFBF613FE576D9323BE0F6B
+:102330005B591FF9FDD79AB76FA3EF0855EFEF86EA
+:102340006B88293104575F7220493C8E3448917163
+:1023500064F53ED9135E7706EBB903F551BA9007E1
+:10236000A6049331FF35009D0680AFA689D3D5D052
+:10237000CC5B98FF169E2731D2FC3DEE17F956E351
+:10238000FDAF33AD7CFFFAAAAF02FBF70F94A9AE05
+:10239000F3FEB7570E0DD7A30CE104BA561B83C941
+:1023A000146F9E34107CD5272F270FB2A15EDA520E
+:1023B00082DF0F9D2EF4DFE181D6E5C8CF3E9C374A
+:1023C0002534CECB69BC7E8FE17A9DE86DFC928F7F
+:1023D0002BD6FB109B2DE26ACE4F39697CBD108F46
+:1023E0008C4BEF251EB95EBF13ECC3A98512D63303
+:1023F000293E8C87F7BCC7F5424DF3B28F90DFAB17
+:10240000DF37539DD7FD2DCB8652BDAFD77B03FA67
+:102410001B5FB7ACB881F283D24304970FE173A27C
+:102420005F732619EB522B9BCF2493DDDD3B7A9310
+:102430002F06FD97BCE9781DFC09E23FF06B88FF91
+:10244000F6B415687E8C15C7AD3CAA78103F954749
+:102450000B8E57A07F71A2A800D5B974A280FC98FA
+:102460007CF4636C21BFA65B4FA6733FA6AB358A95
+:10247000F20B121BC8F9870D8AE09FD50DAF93BDF3
+:102480005FDD2847D42F6AEFDD99AED038CB34FE1C
+:10249000A997DCC41FBB78BBBA710FAD6F95B19E15
+:1024A000E85DB3DDC8EFEFE0ADF67D581F8BF72197
+:1024B0003E8EE325A0C334933F03F3D3C732B99FC5
+:1024C000AFA7C7E7E93CFF71ECAC7700F2CBB142B4
+:1024D000EF507B2F76C2C78A785C2B097C37F0736C
+:1024E00053FAE73E4B97C4774222CFB76AEDA974FF
+:1024F000AE3FA7997AFF2EE06FD2B57309EC314356
+:102500000146C546FB06E1D7A7867DD761CECD46FD
+:10251000F2174E31FBEB58EF3843D3B3E3B87DD518
+:10252000E7CBE789F73C9B55BE5FA43B3F334F3B6E
+:10253000DFA43BEF364FF83BF374FECED3E9C28FF6
+:102540001FC286A01EAC17E7EFD60E8FF287E7B347
+:10255000F4ED61B12F82E787B0AD19FE2EE57D8ED7
+:10256000B59E7D85EADDCE46B1813CAF47F9EFCA25
+:102570003EF2DF35DD72393782CF34BA5C12DF8349
+:10258000D1D365B7A6AFC4BE5DB4D8B7F31BBDBB8E
+:10259000519E2B2D174DBCEE3068427D56339CFB6F
+:1025A0004D974A25DA6F0738FB9BC3F4FBA5541EF1
+:1025B0007FDD7F8B4479D7567C1EE3AC7A89EABCF9
+:1025C0002B03ED26E4A7210D8B1F26B9F5B1D32CE3
+:1025D000ECBB1A332DDC4E76D34F5B77B71D8BF7F0
+:1025E000717D9C482D3E8F767186B083FA7351437E
+:1025F000597B593AC033DF2DB9B01EA02F3ACF5EB8
+:1026000030EA7544C3F5D2BB33DDFB4E3ACA79FBE1
+:10261000E55B308F7A6CF867FDD18E56F5C1C71F28
+:102620000B3CEBBF2BE31AAAD6E2F7556A9DDE0EF0
+:10263000D29F866F6347301CA7E3376B25A4132313
+:10264000FEEF4B7E3E13E37E96CEBF770FB8A77D9D
+:102650009755E9BC4EEB98D19F41798A9CEBDBF70B
+:10266000AAD9F7462EEAB3CED6A3B9A630BA5E5C95
+:102670000B7A00ED4AF3C164D516CE7706E23749EE
+:10268000D2F84F11F632920F2F221FE6607B26768A
+:1026900010EAE35DA76207E3787B79DBCDAF4DFC01
+:1026A0007BF6101F0D9917130EDFC304DFA57A3ECA
+:1026B0000E631D43E68C0CBF5FDB171F5B33888FF7
+:1026C0003B22F8585B6F3D7ECF07E38016337DCF0A
+:1026D00007F3D78E3039199AC1F5CF58F1FD9EF125
+:1026E000CC47DF391C2BBEE3335E6101251EF7CDDD
+:1026F0000232DFF7E5E72DC6087E1EAB045AB18E25
+:1027000062BCD8E799C0DAE9B9292C48AD9BD9E970
+:102710001C451173513BCE12988EEE544E7D3DD523
+:1027200025069215C7798B38AFD10BDD42EB57E800
+:10273000BB3DC49F329ED7E9FDBB2FB333B8DCD37A
+:10274000C74590BE9718E5B9F07B6D38C9448595AB
+:10275000637DD3648559A201DE5D870C24CF2D1DD6
+:10276000AA1FEB535D09E2BDCF19D5E18E757379D0
+:10277000459383F518DA7AF5789800E3619E6DAC9D
+:10278000029128E13140F3DDC8F8399242A652FDAA
+:10279000736946A6D0F7418AA38A218E427D6FB025
+:1027A000F8081FD33354BA8FFB25B130CE848D1275
+:1027B0007B0FF73FB2F87AB5F1270023E0F9C2E9C1
+:1027C00019DC9E614AF5BD78BE8F124B05CD25768A
+:1027D000FE9DA364FACED1F5E2B52B997FEF32F6D8
+:1027E000CE60E7CF0A42FB492EFCEE516CE83B9BE2
+:1027F0002EEDDF830844FE7B1077642CF911F2A3E1
+:1028000056AFC7BCFCDF7DD0D7EB85D5E7B10B61F8
+:10281000E7B0B5BA926DFED92A9EF35B9068A173BA
+:10282000BF7996FEF968C7063ABD34FEFBD2F6C101
+:102830003498E21FED8909F1BB95B9C721BE4375F4
+:1028400083FC3B50DDE7AE92199D57B49A797DE544
+:1028500063201FF81D26902E15EB68D883C5548F72
+:10286000B9DE6171E1790933C26D0DC15D6B11DFB4
+:1028700005B5F07D717D3D68ADCD40DF1DAD65D105
+:10288000740E3D29DABB2E03E0BA2FA688CE7767F7
+:10289000EF9CE444BF317CFD93B4F51B7AD647C26C
+:1028A0007A1FC9E8A51E515BA7F6EF76D805FEB4DE
+:1028B00075DBB5734A6E25E29C92868FC7A2F9BA82
+:1028C0008DB8F39F45EFAAA837F4EBFDFFDC29BCD8
+:1028D00016A06400000000000000000000000000DE
+:1028E0001F8B080000000000000BD3D76660F85172
+:1028F0008FC02E9A0C0C5DD2A862B4C41D120C0CB1
+:102900009780F80B106702EDF5926460F006E26DB7
+:1029100040BC1D88C5A518180280381088FB80FCB3
+:102920007E204E07E224A81BB30519187281381FB8
+:10293000880B815848808141588078FBCB15191845
+:102940005EAB22F85A6A0C0CC91AF4F3FF60C38E0E
+:10295000B6F4B5EF14D0BEE56E08BE0490BDC20D4E
+:1029600055CD4A37FC66AC42935F8DC65F83477F87
+:10297000A20D2A7F99292A7F9D3903C3432435CB91
+:102980004DF1BB051D0B02FD2784274C9730A2F2A9
+:102990002732A1F2F9A17C00BA0B8074A8030000D1
+:1029A00000000000000000001F8B08000000000075
+:1029B000000BED7D0D7854D599F0B93F73672699DA
+:1029C00099DC24433260126E7ED0A001879860B0FB
+:1029D000586E20E147A30E082CB440262888166DB7
+:1029E000C49FC6DD500609BF0921E14F70D11D10FB
+:1029F0005DEA63FBC5565B75BB7682D646AB356830
+:102A0000D787767765A015BFBA761BD96D976EBB51
+:102A1000F57BDFF79CCBCCBD9900FEECB7BBDFF3B9
+:102A2000C5C7E770EE3D3FEF79CFFB7FDE73C7C5CB
+:102A300046B1E058C63EC6BF698C4DCC658CD5A664
+:102A4000CA160F8B65E73096DB213156C3D8CA769C
+:102A5000253E0BFE59D8D1F20AD697B7B90D772982
+:102A600063FD0FB8FD35503FBD5D09BBA16BA3E20F
+:102A7000A3FAB22E57D86DC0F3AD1FBD9C8FEF37B0
+:102A80004A610675C6EE666C32636B3CF04FA82F48
+:102A9000AB4876E0FB77B748E118BE66A66F12BC7C
+:102AA000BF95F1F7CD0F281A93A1BEEFB626369148
+:102AB000B15B7A60160F35641FF3F68C153016E1A2
+:102AC0008F58CB16785F997A1F615D1F29D0AF3977
+:102AD000E678BE6FD6FB2C80EFB5D47358CF31FCAF
+:102AE000C714C62E65FEE0E96CF87798853F56A0BE
+:102AF0006CC8676C740A5FCE9231807E1463731960
+:102B000073B17218A7F632172B83F559786CE378F6
+:102B10005CD624111E97F918D5DF9D2BC51F2CA557
+:102B20007E6C7A3594F0BC200FCA20330BA18C78D0
+:102B300058221BE09FDB76D97BB8FE0D38D5686A3A
+:102B40009F08C0FB052CEA6200DF9FB118958B59E6
+:102B50009CCA2FB304C1B1940D95A850BF4B496CCA
+:102B600062304F38149D8EFBFBBBFA63EF4AF0FED8
+:102B7000FE6AA9760A94CC9747EBBED0FAACF95519
+:102B800016B90EC7614C7645FC8C8DB7D67998C5C1
+:102B90002A828CE93D3E4E2F87593F83FAF8064141
+:102BA0002F8DEFCB215877CFF32C8CF5106CE614DA
+:102BB000A887BAB2E21BA0DEF378AC1EF172AC05B6
+:102BC000300FFD8F35BAA56815942EDD158132A41E
+:102BD00032A6009EEA1BD64B0AB49B1BE5E38C375A
+:102BE00035995D09F5C3314915CFB1BFAEC7241D75
+:102BF000EAE3A1FEA084EF751783711A1A725DC90A
+:102C00002AC477CF181DCA8AC35A4206FCD69B3AFB
+:102C10003D676C11D1D578416B734DDE6FEEE13CB1
+:102C20003FA3F7EC4F1F5BEF01BF9714F17D3B769D
+:102C3000B82C07E165517BFF2295C53C79293CEF13
+:102C40005C072FDC29FCEE3A5CB615F176AC4F0D33
+:102C50000B52B68D0FE3F636C0FB335572583190E8
+:102C6000CF8A38FC15BA5FF7A5C6D9B90EDA5F96D8
+:102C700082A35199DA4FF83019F1E3DC1A685F95B5
+:102C80006AFF04B60738F6203CD46FCD512FCE131F
+:102C90006134CF48F4F0C23A9DFA0D8A755CF3BFF7
+:102CA000C3B44F731B5A243EAF80AFC10E9F555A19
+:102CB000F08D34FE31019735BE35DF13EB425436CB
+:102CC0002A558FDC8BEB3AA2F175CD371EDF8DF8DC
+:102CD0003BE209C7A0FEE4757F33E65E18E28AE9AD
+:102CE000CF5FFE0CC3F9963F7C3BAEEBB92C5AD7B5
+:102CF000531F9E79ED46367CDEB7041E7E7A6EFE4B
+:102D000010D5ADF9E79AD21809E8ACD294122EA0EA
+:102D10009763F55F79F85E03EBFD26CA934AF39853
+:102D20002941391186A1FD66EA9F3E06795609DDE3
+:102D3000911F2735482DD8EE891B1FFAD27DF0E868
+:102D4000A72E0EF7157FC9E1BEECFAB54F22BC974E
+:102D5000DDB8F6E7CF40FD0A1482C07797DEB47F76
+:102D6000CDDFC13FBFB1F02F97EF61241762D900CB
+:102D700047AE2931DCDF65DF77DBE4CAB1E7FD244C
+:102D8000570ACDD218F2DFB23E89E4737FA39B05C8
+:102D9000F1FDCFDC7137F2D7039249ED9F75C75132
+:102DA0003E1C733186F278D9716F1CF985AD5A4695
+:102DB000F23A62C96B337FE9BD30DEBB0D963CE76A
+:102DC000744AEF617DEF9ABFD87E35F43F63BAC293
+:102DD00028362D79E1C4F3BB02BF91FA72A2836554
+:102DE0006AD215CE400FCD6D8A4D6ED7379C24BA6E
+:102DF0005A06254BE3D3B982CF9635FC42F0A74E55
+:102E000072C909CF1BB585C599E8EE94802729E8DA
+:102E1000ED5DDCEFCB103EE88574D3A5C495343965
+:102E20000D7FAEC804AAC790A56FD96287D392DB85
+:102E30002DB16C9BBE02F9FB2F28379BDBF26DCFC7
+:102E4000E7E6B0DAA99F4E0EFF81E4705222784087
+:102E5000FFD2FE47E2521CE5A2B53F7788FD8954B8
+:102E6000305ACFAF0E48F118ECEFAF8E88F5ED93E6
+:102E7000E28A44F46A9EF6E0B83067796AFF6F1719
+:102E8000FB9FDA3F8E1F0B5F293D97BB290920B4BA
+:102E9000F8222528AF2DFEB1F0DBBFE74725B87F2C
+:102EA000856DA5DD7508E70185F8F7C3FA93C5B808
+:102EB0006FEFBA00AFD03F72F8B100F3A5E06F1129
+:102EC00072F0830EA017782E219C9569700AB85D68
+:102ED000588776B737487DC8A7BF14F35AFD7EB42C
+:102EE00065C64CC4CF1D3D1243FCDC7EA477D99F40
+:102EF000C3FA57C7B3C338C5AF1A8B0397003C2B2F
+:102F00007AECFB796ACBCD01A49B0FFBF20B709C92
+:102F1000DBA72634847375E255CD003A9B65F66ACB
+:102F2000C90C74F561DF8600B6FF50EDB9F11A9C4B
+:102F3000679F125E0FE3AF3E523AD3E4744AF4BB8C
+:102F40005AE0F7A4DA33730CC0D7F28D729207EF10
+:102F5000F529B3E319E4E7D72585E860759B5BC6DF
+:102F6000758E442F1F76B85802E7511384CF91DA3B
+:102F70007DD0D742EFFB1F28BC01EDB7DBDB5D2422
+:102F80002F6E6F73133DAD6E90E24C4AF1DB0A0178
+:102F9000EFEADD0ABD3F694A243FACFDBA5DD0DBF4
+:102FA000C9C357BD82FAFE0CC81F94BB3336FE500E
+:102FB000BB04F0B0620B97472777E72EBD07E58883
+:102FC000D0977788716F8B2B36FE58D99E6DDB8F2B
+:102FD0006857BEAD7EFA48FE8D7548D75D0AE9CFC9
+:102FE0005B363EA685483ED9ED4DE4B0490529FB48
+:102FF000F2041B5A708D94A2278B7E6E6D037B3377
+:1030000030DCDE6C3922913D7AD176661BD899137B
+:1030100087DB99961C89A07D569E922396DCB84B3F
+:10302000898E0D021CBF76452FCB2F27B9F1805416
+:103030008B74A2FF16ED4A16536A51BE5DACBCA05C
+:10304000C55A7C047FEF75005D65A0D719485730DD
+:10305000CFCC9EFE8CF43C433268BC14DDDC1220E5
+:10306000BEC541018E668FD985705E02137BABA908
+:10307000644A1E2F55A86F4698811E4EAD95E28773
+:103080004A793B1FCA5380EB1A78DEDC75797C9B4A
+:10309000847621FCA1FE6CE37637B433FD79F4DC51
+:1030A00094A02C6A2F7D19F7E71210005A356F8F04
+:1030B000F3809D452881F6097735758D05A02C860E
+:1030C0007E32EF4FEFB15D80E4789CD68BE3E3383E
+:1030D000154A7C0DCA198B8E9709B90372B5520532
+:1030E000FA6A665961D49BCD6DE5E7B55F6E08DB82
+:1030F000E5C74D75763D30D7B4CBFF9B675F626BFC
+:10310000BF20526E7BFF678BAEB0BD5F1CBDCA5641
+:10311000FFF2AA2FD8DA2F6D9D61F7937E9A4BEBC1
+:103120005923F87224B85F17F2F2270EFBD42A9BBA
+:10313000AE4FD4BC0DFBC4D6B9C38F4371620E5BD6
+:10314000D49726577CB244F8FC0DB009F70FFEF473
+:1031500031E131C4E76DFA0B776B26BAD3443F34C3
+:1031600097D05E72B63FB118E649EBF76F924474A0
+:1031700078AE1FF3F4FC12406E014ECE01D4DFC9CD
+:103180009225B86FEE5C83DEDF25270BB0FE1B3681
+:10319000B4371FF7D7972C46FE6956D973520EF6EF
+:1031A0000B7BDC301F5843AC0DE8A3A5ED47C7D11E
+:1031B0008E938C205B82758F2F81FCCD3A5C1F260D
+:1031C0002DBC031FF686A21F4A0087D4DEFF7B09B1
+:1031D000DF7F9F19A88759B22817FD479C2A9D0FAA
+:1031E0009B66B056C4D789463BDEBC621D3F9764E0
+:1031F0006AF71C337F8B7C7452D2F9FA04BCDB244F
+:10320000F32CCE67C1FD6EAEAEB14F07B722D72209
+:10321000DC3F22B837B4B264B63232DC5730D32D3B
+:103220008F1A0ECF596666657A3E0BD835D3F3CB2D
+:10323000DDAC12EDD5135256787D299643FFF83553
+:10324000E0ABD8377CE1C78DE1743155CEA5F99B51
+:1032500085BD5BD82E25B2D13E651EB25F59CF43E6
+:10326000A607E59A10712D6DD2495C3FEB68349347
+:103270009ED47A9921B1F476E7F6BDCD4DED2D7946
+:1032800063C92D0B9F965CB1E4978557E7F823C976
+:10329000191C4FCD43F8A393E4743AD1011F1310C6
+:1032A0001EB31AF7CFDA377023639EEA91F7CD92F7
+:1032B00053D08EA1FF3FD27E019EC8AE738519E127
+:1032C000E9DDE0D0D2A760DD036D5C5FBF5BC4C801
+:1032D0003E3CD376D5400EE2C7E3A940FC14F2A9E8
+:1032E000586170681DCA579F9AE847B80A85FEF270
+:1032F00032AEBF0A99B1E36AF4EFDB4F2EC176D646
+:10330000FEE48AFD6986FD417FA4D937548C76920C
+:103310001BF51AB47383DC45B95CD8FEFE7FA05E52
+:103320002C74E8458484A5C39155B5E36A237DFCDC
+:103330008F36A27D698D4B1DD2F73FA89D44FC16A8
+:10334000B66FBE5B09D8C6973E463C08B98D66D7B6
+:10335000B9794AD15E9513EE408A2E9C7059FD468C
+:10336000A213963E4FB9AD4EF684B3EE0E6B36F90E
+:10337000FCEE1FCB735A7DE7A137E7784EFA76F261
+:1033800081C0C3A7A0D34D9C4EB95CB0F8F63F8B6B
+:103390004EA3D6BEC672EF3882FAB54B0BCF32D0F1
+:1033A0004E18FA21B713DCC621A4B398945509EF3F
+:1033B000A31D2AD98D965DD1BFF6AFB794C1F31383
+:1033C000B532F91127D673BADFF300B7472DBD1D0B
+:1033D000157A1BED02C42BD80D036E5E7A701CFFAC
+:1033E000FA9B4B2580DB630CF5BBB17D9B41F66AF4
+:1033F0004E5D5C6F84325E71C833CE48C9A5642CC3
+:103400003F6F39ECD7B7728D6511B2AFA3A3E7FA5E
+:1034100053EF7F2C73FD34AD84E5CD86F1925BE5EF
+:10342000F083D03FE9B2EB31AB5CA3707D99F4B28D
+:1034300012F483476A37A4587A55D7685FE60F1CA1
+:10344000C77D1A691F6007748A639EA3438E7798AD
+:1034500087C64FFAED7AE8A4D04316FC9F40AF2E02
+:103460002C06FAD82B6586FB23315EF4390000F672
+:103470003BAA3233533BE7BAFF41F44BC82ACDB7DE
+:10348000A362E76CDCEF584C09A7EF8755FE85C2B5
+:10349000F567CEDC86DC4668C7D6676E9727DA3DCF
+:1034A000765FD622F4AF00752AC66B42317DDE6CA2
+:1034B0008C474ECD9B843EF68F51FFC0BCBB23672B
+:1034C000F416DF27C247414819191F6FCA32DF4778
+:1034D00007DFEE01770DE56752F250FCA525E6CE39
+:1034E000C8C7969C72CA23A79E934C93B5550F9755
+:1034F0002BD6B89F549F817CC85246A5ECF673FA30
+:10350000EC62E97104395022B3685F06FFF46A8502
+:10351000E3A93FC6E314AA2993DE9AA9343109F03E
+:10352000B421C8481EE4E15E23DF36B038A080E550
+:10353000B3F0800FE549506609F25B9D7EA0D98407
+:103540007E609083C6F45165FD85F03C387F259DF3
+:1035500033B00897B73AFCC7F9C8247DE116788DD7
+:10356000C626519C33AFC92EC7DDE807827CD41B29
+:103570001CCFE7CFA4F306374B7B0EEBB84AF1071D
+:103580004F8369CFAA590DF267F5FEAB762D86F110
+:103590006B1EB9F96D2C271FBC27FF4B50D63DBEC3
+:1035A000EB662C4B5E8B8ECD144FB54AE01426D7BC
+:1035B000017C3E66B873466E67AC57226857C33EBF
+:1035C00076203D2463E55948DFAB14CEFFFD0BB4F4
+:1035D00000C667D42D5CAEAAF3017944FFDC4F6FBF
+:1035E0004EF9D3E457A8C24F52DA158A2324F53294
+:1035F0008AB71CDA226B58829C8DE13CD6FCBD2236
+:103600004EDD29E2AD4EF87A4B868A510E9E58FF68
+:1036100011D9878A9E159E0DF375F95909C121E2CA
+:1036200005CD62FF926BEB3DE9F12245F8391D476C
+:10363000E70C184807034AD86B10DF68386E74CB64
+:103640007486F197597A98A13DD129FC1EC567323D
+:10365000DCD76C9DCD44BF165E6921EC5FC5C20905
+:10366000ECDFDE8FB885F59AB7231FFCE05A6E8732
+:103670009C28B5CB6D20A12ED85336AB68BD8AB43B
+:10368000D9149C7415D2FCEF9502215739BDBE5157
+:103690003BE5B16D4007CFB9CD7B94519F808F1C26
+:1036A00072FD07C026B86F8F4A76796E95079D7CAC
+:1036B000D426915DA89A7C9D33950F1B514F6E04C3
+:1036C000BBB1D018CE2F1B5F6764376E04FE8B959D
+:1036D00066E29F6A0965C4C5F24F5E7BAE84718C59
+:1036E000CFCA3F7FA988733AC13F406709B4631EC0
+:1036F000958CCE29B0BEEFEC6BFCF11478FDEC811B
+:1037000015D9D740F9BDF8C6EBAF81F96F7F7C4F73
+:1037100036EEF3A3AF023F9DC78FB7F8A9196DD856
+:10372000F3C4D98CB5767E32D657103FBDA570FD57
+:10373000D5BFE0776F5CFDFFF9E97CFCF4B602F4DD
+:1037400039ED4F678BA3E7916FCD454C437B0BDA87
+:103750009848E7D1A0BDF4A95984EF752E2EC7FC77
+:103760002E2FB73B42FCBD73BCBF513F79FC60417B
+:10377000F967E7D3753EF3A3CF83DF41EE90BC3901
+:1037800031CECEF79D2E4E77BF727DE2F5BDF3852B
+:10379000CF617D60D7937D779DCA0CF40326BEE090
+:1037A0002161F1EAB88D479025A6C1F3501E7FEF45
+:1037B000CE237919473B6648A9A4FE26E3767C53BD
+:1037C000CDE623FC5C62B06211F8CB73E05F688FDA
+:1037D0005CE7E37E058CC34230FE6A6FB4581D453A
+:1037E000E3917FF9EAF3FB82285F5EF79825F89C66
+:1037F00025D55C3C1FB0EC8E91F95D65A7D3FCAC80
+:10380000A73546709CBA54A378258AB100D4B796E0
+:103810005E4A714A168E1D97B03E4A6728C795606A
+:103820006431D9216D6E6316D4B78201150B12DD98
+:1038300092DC54DA7B430194036097E07B3536D702
+:10384000A3A1FF324AC6203473B77D447EF7896254
+:103850002E6F3BA6303AA71978E0DF96CA68EFB41E
+:10386000BBE9DC02EC46E2D7A8901BC9E0F4500BA0
+:10387000FA19455A5882FAA6D82F8E7F8DCB13D3CA
+:1038800033393D3EC2E31D2D21EEEF3AEDBECD5F53
+:10389000BFEC4D03C7FBE16B5D9743F9FA933F7FA4
+:1038A000FD7278F7C6B75EABC1B8B7BB4EB3C51DE6
+:1038B000DDCC7813ED2DF099121ACAE7D8C925B8D6
+:1038C0009929BF4E8A217EA235FE38AE17791BF1A9
+:1038D000939CA2F0F345F80B017C01015F77F05453
+:1038E00015CD137BFF3F32C97BFA9B2CF408B4DB68
+:1038F0009C777F1CE5486ABE49249FA2209FD08FF9
+:103900008CFA7A96ACA1F9FCE107B1CF1F61572779
+:10391000A7CE0B0F6D99D782789EBBC0A3239DB90C
+:10392000639BEF463A77AEF38CEFC14B3134679B24
+:103930001FF8C45DA1995EB27FD961DA0FD1C4824C
+:103940005B0705827107E8BF6C05CBD0DF80FEB84E
+:103950004E9067686F5BFD808C4D5CEF19DFF44B18
+:1039600029DE2FE21556BF9B62129D13DC540E6CAC
+:10397000503E1C4F1B7CF24FBE86E72E3145573818
+:103980001D842AD2F0867FF6B819A78BCBF6D9F51D
+:103990002ECCBFB014DFC714A21727BF8C8FDBDB80
+:1039A0006FF09DFF5C7FF87E723C4F14FC66F5B7AC
+:1039B000E02378A54CF175FBB9CC4D75F6FADC61C6
+:1039C000F8383F5CD355FBB94D83CF3EDECCA0FD2C
+:1039D000FDEC227B7D03C66F3EC9BA1D7CF7F4184F
+:1039E000F33BEA67F0EB2DB9FBBE27F2B7348E1A32
+:1039F00066384EFF82BDF3E7011D14EADCEE289C19
+:103A0000BFB021B706E51413792699ED8F42A1EFD7
+:103A100095F697941CF4474DDE3EB9E4AD1939781C
+:103A20005E5CC7E83C3DAADE13CB3152F648BF5A74
+:103A30009E8578FEFCED91BBBDE97937297BE48159
+:103A4000578D9A0CF6887A8F64C238B396803D52AF
+:103A5000956E8FB44A2883B297803D427647F43DF5
+:103A6000C4D74876C98F2DFBDE9FD9AEFE83CAF539
+:103A70002CE8997FFA2C7A669CD7FC17F573B0076F
+:103A8000A695182B2319E8F00395C73B2CFDD918F0
+:103A90004C2878760E7A5375C1F36BEB922FA138D0
+:103AA000EED0770671DDB01E97ABF6D3AFE78CCAC8
+:103AB000E199A8F23C9891FA7D6B047FC5AB7985BA
+:103AC000DD62DFEFFE05EFE832FA2FE0C7A0FF92DC
+:103AD000F4956DC3B8E099984AF13A75FECADD7362
+:103AE000919EC0CEE6F47C7EFBFADA21D9C6C7D31C
+:103AF000CE66D9F8BE9ED9CFE96678ECE7748DBA68
+:103B0000FD9C6E56C87E4E37C7B09FD35D5F693F40
+:103B1000A773DAF73347BBFE7BDAF7A14646FC749E
+:103B200001FB1EF8E926A4A791F8E9BA7CE3FE4858
+:103B300086FDAED6B89DBADA1B59807437CDE076D3
+:103B40005D34B69EF201F3A2206F4A296E48712FB0
+:103B50002BAE65C5BDACBC402B9EE58C5F59712F6B
+:103B60002B8E25C578DCAAD9135D81F036B79F94DA
+:103B7000518EE8CFC13CC808D639DEB0F81C970793
+:103B80002DED99E372CEF8DB88ED3E255F7D0EFAD0
+:103B9000613DAED7D20FC0E70F7E163E07B9B50D17
+:103BA000C7FB17E4F751244FBA69FF2A00D768A76B
+:103BB000C33E6818A75F707A3FC6E3D4E36EE2DBCA
+:103BC0008BF57F31D141864D8B820F8EF1AC68AC85
+:103BD00094F48BC537169F38FDE361FCF15FCD3F50
+:103BE00017E91F03FF7CCF751E7D04FCF13CE27BCF
+:103BF0005A25C7AF931F2CFA07924848D5B8DFD192
+:103C000004B6B7E89DBD183611CE89C2AF39315A16
+:103C100023FFE2C4F3FFCECF619FF784C78935E26B
+:103C2000FB89DD05F16DA5293EB3F8A9DD13FDB1D2
+:103C30002B2D0FC4CA773CEC315FC7E721B52F812C
+:103C4000FE4A68360B6F3088CF8EF1E79C4F7D615E
+:103C500046F1D3CFEC97ED75C5F17CA8451A5ACA49
+:103C6000C86F651AF2AD2AE4C98B59D19388CFE6A3
+:103C7000E991124E4F43E37C00D72F3A14F2D73E1E
+:103C80002B3F358F84FF73F8880EB96A87E707A446
+:103C9000CB2D946FA19016DF20659057025F7116AF
+:103CA0001E83EB83FDFC77C4635E15936839828FB6
+:103CB0009B3DE61F5C9FCDFE50B4DA141F03DE3C33
+:103CC0001ACAC56AC05BF970BC9D74F1F53BE92F57
+:103CD000A42665A4FF10C8D10D52DA39A9C08BB54E
+:103CE0009E91E4B345A769E70D212D7DBDFF8FCAE5
+:103CF000654B5E5EEE894EC67D709B1121FF4CDAEE
+:103D00005FA79C196E07C974CE7806EC1EEC76B1DD
+:103D1000F275DA592F1E96B0A967152AAF3D4B8769
+:103D200027EC8B67B3A934CFE653597F3697CAE99E
+:103D3000672FA172C6D9D154369C0560C0C4693CB6
+:103D40005B4AE5CCB3575039EBEC782A679FBD8AC4
+:103D5000DACD393B89CAEBCE7E81CAEBCF4EA1D2F8
+:103D600069FF18EB5592DF96FCB2E4BB537E5BF221
+:103D7000EFFF9AFC8E355C94FD03FAEFABDA79E441
+:103D8000F748F202F8FA3E2D5D4EA4F4F3FDDA672F
+:103D9000E0EBE3824F817FDFC3388C07BC388A5366
+:103DA00085799C2A606806E669ECC326B0A5FED238
+:103DB000C8498C1B342FF0E831807BA05423F9B420
+:103DC0002DA8D1B9DB66491FCDE5413281F4B73367
+:103DD000A4D178DBFEA878317FE1A55105019CA72D
+:103DE000DB2FEBD8FE5BB9C97DB7E039FE14163E78
+:103DF00004E3ADD8B3C793EE87EF47E300E00BC40D
+:103E00009E660CF87AE3A8DF2DC5F97C5319C563CB
+:103E1000A03433E58B7DD32DCEA7D5A110E269ABBD
+:103E20004F267DD0AD7B441E6A72A005FDDC3A9919
+:103E30006D8379378C7E670B82AD8E2BDB5106F557
+:103E40009D75655EDCA4A75FF92044F604BC435071
+:103E5000A04C88D2CC81FDE9F4868DF39DB729C6AC
+:103E6000D03A2456ECEFAE1EB9DD26FF4008E9A398
+:103E700063D2E4CA5B60FEDE4905A371FEED3547FF
+:103E80006DF850747B3C45C18023FAE175498AABDB
+:103E90006D908D1D65B0BE80C8B706302B23697943
+:103EA00007161C4A18D6C1E14A287C3DAC009EE7A3
+:103EB000D6256249BE5E13E3AE3E5F3284FEA25257
+:103EC000779AE26D9DFEE422AA3BE0B0C6FFAD66A4
+:103ED000E50570BEF109BE699EF4ED4594475EA507
+:103EE000D1BE75BB8616603DB6D6C51ECF10BFD9F4
+:103EF00020F8795BE5F9E332AACF0E47B7D7EE2F6A
+:103F00005AF0BC2F4A271CCDAEA15199F6EFD3CE63
+:103F10007FA1757FDEF3758E903F70B9DBBE0F0118
+:103F200021CF9BA77C3B84E7E2163C9D12EC43CD5E
+:103F3000E7BF0FCD53B8BCFEBCD7FB3F6DDCDF6BDA
+:103F40003CAE027C3ABB1CE38C632687305EEBB34D
+:103F5000E2D1E138E52705301E4DBD0CD243AACE93
+:103F6000C7505496403E94B33F4CE03E29D59AA1A9
+:103F7000909CCDBCEF4A7813E5B539F9D3829BFE0E
+:103F8000260BD381CE0FBD567CDA5027F3FB1218D7
+:103F9000FF5598753ECBE3D3567FB542A6783405DE
+:103FA000B2D3C651410FE3398E8271EABCE1F37F8F
+:103FB00037458FF6F98B787C5C51B91FF89EC4F1B8
+:103FC000117B55A17CCFAEE7B97C63C719C9EFAEB1
+:103FD0005A83CE5576C0FFE83FC46A7D71A45BC5A5
+:103FE000918F77A6727A08E5A81517A7F9F8F90056
+:103FF000C5B9314F91E2E606ABC0F7DD02346B1C68
+:10400000D58ACB57AE9984EDFC06F33C07EBF3D78A
+:10401000B1C425006FD0DDBAF5F2D20CF1F0CA358B
+:10402000DF7812E6DDFDD4F45F3D09F55D72F8D569
+:104030003A6897FFE53AC2AB331EBEAD523675946F
+:104040000F3EDF21DC57B0A1892E6EED9162F83C66
+:10405000DBE73BC8F7BB35A4205E404F225EBCCEF9
+:10406000BCC8747C97211C3B07E6C1BFBD5BE72D34
+:10407000C379116ECCAF5CD15BAFA19E092EB19F0D
+:104080005FF89BEC756F951DCEAD62FF2E44FFCEA1
+:104090003CC41E73DE22A4DB33418DA1BCD9B8F62B
+:1040A000EA1B49EE6F57D8B8D20CF4EB5857A7E685
+:1040B00022FDDF6DD4EFAD40BDD1A0515E4F77DC66
+:1040C0001BC714EFED75A973139BFD6E68FC1CAB49
+:1040D000464EB833D9F1E27C2C209E31C73958F7CF
+:1040E0006C99EC9AEE1E3E8F355E77DD5B1E941365
+:1040F000238DFBF418F3881BEDA968DE45DDBBB802
+:104100006FA38BD3F5142D2E95A23DAA2F5C04F539
+:10411000CDE364B28798F0FFBAAFE5E7890F6B860D
+:10412000ED7EC5A6292BC96EB8C9AD0BFE02BB70CA
+:1041300042EABEC501AFF9821B9EABCFC148600FFA
+:10414000BC971BBE11E9A231F811D951B716C93A73
+:10415000D2D78A3D8DB4AECDBACC1268F7AAAD6481
+:10416000A436B15613CF03305113E96E0EBC91E95A
+:104170005E44F25027C039675CE1A46D507317B5F7
+:10418000521E4BA321911F761D6006E5414B7144E1
+:1041900095AAB0DFFC77D0EE9B132C95D1DFBF4EF4
+:1041A000650D5A9A7D0E76F13177DABA4E8CDB13B3
+:1041B00094AB707E9807E75FE4A1FB046EB48FAF09
+:1041C0004CD9C71311916976F2AFD1A8C478465182
+:1041D000E2F794E7FDFDA48CF3B21758F536E993A6
+:1041E000FBD5E05FFE12F733CE8C7E4C35FCAC7114
+:1041F00089AF6B629FC4BD95C39EC86F707C2B1E38
+:104200003051E3F79B37B7B0702C2DAEB2F9F93FC0
+:104210003F8EF6AA157F39977727E0B4E0DE24B108
+:104220002CD2F39EE81FDCE97E314B96CD9DF0F950
+:10423000C19D215FCE570BFC3456F04F5E6D851744
+:10424000E5E658CCF7C17D68E7F2C484FFD2F37D80
+:1042500014C17CC1706BBF6C0C974B8AB837057466
+:104260002DA11DEBCC075230EF67E270B97140D041
+:10427000FF251E91FF33994DE67EB8FDFCCABF9421
+:10428000EB7DD69A97F11EEAF785DE7F51F8950906
+:1042900071AFF1A8B8B7F8F23A83FCBC57D65552C3
+:1042A00039B02E4CCF5F5B574765EA7E159F375F6D
+:1042B000D8612A06D5F09CDFC7E206C0EB1FB566C1
+:1042C000A014F9BC8EDFEFEE6E3AB5A59CEC467EED
+:1042D0006EB1B9A83A5188FE0BC09A0F7597AFCF4F
+:1042E000C3EF79998395055CCD21DEFFABCF2B9C85
+:1042F00074A15BFBEFD86F1F6B6528EF02A67DBF33
+:10430000B3C34EFF86EFBFABE8E2F6BD17FF01FB7C
+:10431000F8256BDFAF6657F3EF335C9C3C463EAA53
+:104320001472600CF0D301F0E7DD0ACF57CFE779C4
+:10433000AE6688F39BA9F27A6CBC68EFE224C406EF
+:10434000F2785E7B313F4FA07E98578EEF312CF98B
+:10435000028F6FB11C91FF3E568CB35A8C3BB19AC1
+:10436000EEEDF2F37FD6A763E96349AAE7021F6087
+:104370001964AD1222730C1B247FBB581AA2BA21F8
+:10438000E959582F93C265DC0F8F93FE2C57CC6FE1
+:104390005710F223328F172517933D097A19E562DA
+:1043A0005C8D2C42F9B2A14D0B0326CEE5C9E1FD8F
+:1043B000392C37F4D50CE0F9472C2693FC519E6339
+:1043C00059FA9564EF91FEDAB03EEF6036E56B2462
+:1043D00029CF7DBFA7D4A6A726FA165EA7C37E6DF8
+:1043E00014F9742EE8CF32E49F5AF974306E49A65E
+:1043F000F756B9D1AF2DCAE4F73FEC91443C2339CD
+:104400009AE280625FE353E58CF719F779B85DF3C0
+:104410006869667B9AB10769BCFD1EDD316EB285A5
+:10442000EECFE83CBE91E53229BF66631BBFA76FA4
+:10443000E16F34D8B5680F6FEC9B3F1BF93B56A971
+:1044400052BE39ACDF87F87389BCE48DE38307B3D0
+:10445000795CA214E5743FE2AF360D7FC1954D88BB
+:10446000BF8E57797E2FE8731FCB906F68E1CFE541
+:10447000635FCCF4DE2A3B46698B32DD1B3EEAB13A
+:10448000ECF46429A7138EBFAC6BD548A6F609815E
+:10449000EF9232163D1FFEFA3DBA6D5CEBDC571908
+:1044A00021DE25F91214E79AA8713B63C3628ED707
+:1044B0000DCF5F733C9A760EF14B1C724A2A1E6C2C
+:1044C000C58D2DBDD9EE89FEA367544A5FB2EF3387
+:1044D00092BBEC05CF41DCB70CE710A73CB519CE79
+:1044E000217A2EEEFB2E6305DF1EDA72741ECEF3E8
+:1044F00057758CECABC0337CDE5C9DC5E552FC4E41
+:104500008129619CE59A885E8FF69BAB9D99983FC7
+:104510003356C46D0ADBFB14A48B20EC65A184F731
+:104520009A9231FC9EC9D8DD8CFC44B570E6AAF5A0
+:104530008610A569F9510A1BEAA7F5B56BC6E3A574
+:1045400004D64F513F8C11EF03ED337F8572734CCE
+:10455000244A79B8D02FE647FB42E0B1C0CBF976C8
+:1045600079435892A07D3098A4F8A453AE8F01FCF3
+:104570005C9266BF05449DADE2725A86FF50CFE75C
+:1045800047EC727B9CE35E74C091F792EB15F9EEF9
+:1045900096DC2EE29B3A411D9433F9E529FDEA8031
+:1045A0000F655875AA7FC0AA7F46F88010889E2D97
+:1045B00078F02A25CADD3D2EFD2B4FA17EAED7789F
+:1045C0001E99B82F972DF0EE438719DA0D4C79C557
+:1045D000C47DDD11E6DFA53933751EF9A1D975D685
+:1045E0007D3A7E5F19CA18C6E9B2C5FCD6BDBA6C61
+:1045F00066BC590EF4906D26E95E9D6E7D57C164D0
+:1046000009CCC3D17D32E5D1E9BE08C9A79E051EFC
+:104610001DBFF3A1897B7A2E717F3CDB3C4DF7EB0C
+:10462000B287AD8FDFAFB3E0CECEAA7AB3DCB0CD28
+:10463000B31EE3DBB0F6D119EFD7D5713F29DBE428
+:104640007188B4F1E97EDD8EA965B6FB75340FFA89
+:104650007182FEAC7B764EB8CEF5ABC96CA74D0827
+:10466000DBED880BDDAF7385ECED775C203FEB1362
+:10467000DFAF137818D6CE610FBA2C3B7494CC7090
+:10468000FFCE34C8F41D91DC8F92911912C52548D4
+:10469000DF5B765E1E1FEABF9D9D9767E5F53BECED
+:1046A0003CCB7ECB9D6DC7B7D3EE735745A8CFC526
+:1046B000DA79BBF01F402F0F791D765E5366FA70D2
+:1046C000CA8B7C36B8FB4A18E768ED8F14CC57DBF1
+:1046D00095CBBF7FC486F9076FCDA07DF1F1EF1DAB
+:1046E000ED9AD2AFE2F76F7EB794919D64C511DC6D
+:1046F00002E65D45F27A0ABB773D44F8090A3C348C
+:10470000E107C86A0857F171C467A617F316F29B50
+:1047100018352AAC08D3BEE3670964BAB4155351FF
+:104720008FD72356D2F034C363FF4E40A39EEFD8F9
+:1047300047FB3E9F3B077F907F4F618E61DF77CBCA
+:104740004F427316E7BBBED24E0727A4C8A0025D36
+:104750009ECE2A15F6CFA08EFAB27BAD8BECC68723
+:1047600096946DBD12FDD5A0ACF3E3C8A171681F8E
+:10477000351F35BD68E76D8F4CF78E83F70F7528B1
+:1047800061340F9F5AB2E655ACC776BBC80E7AAA01
+:104790006F5EC18A34BEDBBC7BC1C2C5F8BEC345F7
+:1047A000FA7DC59EFB064A83D8DF559BFEBDA996C0
+:1047B0008DF7E9E8B7BD51EBCD68C75C9DC5ED92BB
+:1047C0008D5A92E24F1BE7690C5DAE8D25F5A3571C
+:1047D000A0FD708D96F13EF95D596E7E9FCFD52A72
+:1047E000A17C2F8C66BE1760B51B5BF35B3AC708D4
+:1047F000CE9619FA71AEEBE7C9587F08F655975275
+:10480000F49427E86963D1BD5B2B707D0399EF1D9C
+:104810005AE5DAAC719C4E23763E7715368DC67517
+:10482000BBDC91817A24AE4259C7B888CBDD1AB976
+:1048300019EDD1AB5D48E16C73C70F1B16E1BE8467
+:10484000255D8279826A6415D159308BA13E685802
+:10485000126945BC1482FEC3D05E61D12FE99CA2CF
+:10486000B04E635EA87B96F4245CF0DE5311BD0A63
+:10487000F1FED25AFE9D97C2A08FEE051546F8397B
+:104880005C61BB9BA1C9B0115C6017F90712C589B7
+:104890009C7C64ADAB792997E3BBD7FE7654A6EF39
+:1048A000CD546495115EBD867DDD1ED4BB30CE54E3
+:1048B000737009E1BBC6CDE2C4BF6EA2EF5DB52E39
+:1048C000826BD794935F41B87EF7FB2CDAEF6B993C
+:1048D00029215CF943FC9CD59A27BF6950E1F1700E
+:1048E000CE874EBEB3F8C109DFCED9F3E83C6E33B4
+:1048F0001B9C8FF88E9D95898E3617ADF1A6C74506
+:104900005B05FDC13E907C89E98CF65BF957B61ECC
+:10491000F361377E315289FCF1B697DF5BBD6FA939
+:1049200046EB7868AE46F1C687FCAD44F7A736BAC9
+:10493000C287101C555F88FBB9BBB8228CF1B6BF8B
+:10494000C3C3E734FF60F7A82F55223EBFF8872C7A
+:104950003ECE14D51AE76744EFB55E827386D2FE69
+:10496000B31568872E912753EEF4AA2524BF5C4225
+:104970008EBFBC24AF1EFD94C00DCB1997873C4E53
+:1049800011585BCDEF3338E47EA24EDD3D8376894E
+:10499000C77FEA85BC1B7BC3F47A5C67BDD00BA6DE
+:1049A0009AF9BB8CB9A27DE150044DB261F19F5CD4
+:1049B000A13FC6EE763C177A2177581C7CB0E266A0
+:1049C000903F5FCA1276E408719F5D4BE6113F9CF1
+:1049D000017EA0B874C949A2FF18C809B49BDF9032
+:1049E00092A11569E761D677E67E22E24111B39480
+:1049F000F284DF12F1A09F8AEFCEBD23E241C745CA
+:104A00003CE8E7221EF40F180FC2EF87792FA77D2D
+:104A10001B57F7513FC67176D62CF01830CE547D17
+:104A2000F02504F28BE6A04FE4DF13BC414B0FCD21
+:104A30003D7F9C2A8170B9312EC5E17C597C8FEE77
+:104A40001501D78080EB350197A507516E209DB1E8
+:104A5000B1AA9E491E06D55609CF7B515EF407497F
+:104A60005EF03CF1E01AC998305C4EC078A3D3EDFB
+:104A7000748BFE4E8DF2111D3BC77F348BDF3B7C68
+:104A800069EDACFD2C98268F220B5721DDE5C3FE86
+:104A9000A03C8A3671391EC57B176972D58AA7C1B9
+:104AA0008E8449EFDCC0F134927CB9905C2974C8E3
+:104AB00095DD2857A0BE1BE54A305DAEB4F6E3BADB
+:104AC000832857584A0F05239F4CAEFCCC5B668B5E
+:104AD0009358F2E56A6063B213C3A04FFD9F5E9FD7
+:104AE000BE2DE4C485F4AA95FF113019E9F53D986F
+:104AF0001782FECC7846F770147390F28972DB5DF2
+:104B00000CF341B66297D1E8CF2CA47C901DF33D05
+:104B10003AD2C5C3522284F8DC27F578F9BEE8FD05
+:104B2000682F6C9BC0E3243BFE788F17EDEC976EEB
+:104B30002F08E0394E6FAE9507A22FBE15EAA71ACF
+:104B400019D1C98A3D2B6C790F3FCFCA237CE4C6AB
+:104B500040FE003E1EBE9DEB1FDDE079205066CC7E
+:104B60000371FB443C488D85903EB649510FC561A9
+:104B70001A65D253BD619EBFD20B7E399E0FF636A9
+:104B8000EC9C83FA79C3AD32A37CF1CA9E7B50CEF4
+:104B9000744C5868205FBA4697BD89E6F8069FECCA
+:104BA0004DCF23C5E304AD9A9F1B8AD2CC01903729
+:104BB0007B4DE37CF74755E1F7617FF779F2E03B06
+:104BC0007343A3314ED0DBB83084F3F68E8A84F27F
+:104BD000283F650CD9031B476D5A8CF1A78EE51A47
+:104BE0004BB79386CD17B4DBD7569C516DE0F923B4
+:104BF0001D32F72F73C5F934F05525E22D7D9D0840
+:104C0000A76AF2FC115CAFC2D74BDF37CD6D00FF56
+:104C1000B08AAF1FFD57DDA78F46F9A136F0FC9192
+:104C2000CD7E7D31FA8D4E38ACF1AFCD966CFE91D4
+:104C30006EE52DD4AFE1E788453C6FA1D775FEBC8A
+:104C4000850E210F2DBF71247CB81CE7D4BD5E7B7F
+:104C50001CD082E74A513AE118295FE0D3CE7FA108
+:104C6000757FDEF38D9447B0265BB2DDAFC8B5F239
+:104C7000591AD784504E58F06CBE40FEC8A785AB79
+:104C8000B991B7FFBCD7FB3F6DDCFA6CAE1F814F0B
+:104C900007F01E65C7C499219443A978CCD0403948
+:104CA000DA73E23EA3953FE2D2F93F55957FE74E96
+:104CB000CE2EA2EF2CABD379FE08FD65C803D9C474
+:104CC000D86CF4775411BF71F2E985E077E68DDC9A
+:104CD000EC137E63D4319FC813618EBC1335C4F3CB
+:104CE0004BAC7C922E09D6174CE5838C38AF036F02
+:104CF000E385DC7FCFD17FD8BAC3FC7EA5957F3218
+:104D00002C8F64AABC1FB760581E89C847E9C935F3
+:104D1000E23C4F9CE795A0DAC478DEB03C92A9D380
+:104D200043F84DC96925A2DF0D8CBEBFDBE3E5F575
+:104D3000DE392C8EDF3BEBC53AF2532DA3BC9661D6
+:104D4000F92553D7109E341659C6CF77F879BF8509
+:104D500007677EC905E9ED027924419FF53D8A0880
+:104D6000CDD3E30FFFA48EE093E93CBEE04BC7C375
+:104D7000E9E35FE2E372B247E4E1F5E4DAF3F1EE8E
+:104D800013FB5221DA39F7572FE274DD55AF53DCAC
+:104D9000DDDDC0E395C3BE035163F7079CF1BC138F
+:104DA000425E5F68FDCEB8DEB611EE9B2DF0F13CA1
+:104DB000AE87961CA2BCD833AB40CF02BE1EC67CC9
+:104DC000969A8BCF67793D8BE7B3F41AF50B2F4595
+:104DD0003D16D518CAD35ECC6781F71B1A46C86743
+:104DE00011F1442B3E3A523E4BEEB9F3787B3E4BE9
+:104DF000EFAD3C9FA5B787CF638DD7DB504D76D6FF
+:104E000048E33E3DC6947DB8FF1517777E3AAD2442
+:104E1000F26798BFD253AAE90F1A482F9C9EBB1A7B
+:104E200035A2EF2E17F76363A3B9DFCCD4786821DE
+:104E3000B4D9E24F2CA278B2C8CBE815F7E7FF3E11
+:104E4000CBB0D9C79D8DDF0DA15D0F74F8B2CEF93F
+:104E500084C6C9574BD7830DC8DC7A8B893EE540A1
+:104E6000368F23B842C706EAD2E8748BD077881F02
+:104E700019F0932B9DC357542EA0E83EFDAD11F4BD
+:104E8000F946369FDFA243A64E0AF3F33F568172DE
+:104E9000C4F25F87B5F3F076C3E48F438EF4607E8F
+:104EA0001B562C797283254FEC7469C90FE6903339
+:104EB000E7E4C91C6EA79F9327203FF053674E3944
+:104EC000D4EBE5FAC282C78D8219E4C87BAEB02D5F
+:104ED0004EE3943B17E2A3CF5BEEBC949D2FEC0F07
+:104EE0002E7782481BC837D9D63922BFF77066EAB9
+:104EF00083240F3D2A5FB727C2E87702B08EF2DC29
+:104F000083E72819E57AB544F106712E922FBE3F4A
+:104F1000F8B02B4CF9690F033FA39F37C170DA67D4
+:104F2000E73F57709E273DBCF66BDC3F037CA3DF59
+:104F300075B172C892131F66F3759FA32F93C3694F
+:104F4000D1571A3DD3F7052CFAB5C6B5E898218399
+:104F5000169C875E055D63389AE2D431298E711004
+:104F60002B8FCC1AEF0D1FB74746BA5F65B5FB8E86
+:104F7000E5779D8B07EB019DF2C97AE8BE39EBE23C
+:104F8000F43787ED56D754513E81CA289F2052826C
+:104F9000FECC619FDD2FB6F2C1A69584432827364B
+:104FA000083BDDCA23B3F2D20EFB72AD73665B7EA3
+:104FB000DA8611EE67BF790E3F17FFFD13FC6EDB3B
+:104FC0006AAFF938CA45C09729BEE7447968D6B8B0
+:104FD000DF15787ADD633EE9FB0CF7275FCCB2E79B
+:104FE0005D75FA0C475C80E375A21EABA7FB785198
+:104FF0007EAFCA79AE3ED2FD57E7BDBD73F75FC540
+:10500000F97BB327FA32C1FF22CF7FD3C3D1839D6F
+:10501000ECF35BCF01AFF9131CBF53F0F7B420BF23
+:10502000B7F3BE27FA363EBF8E71BFDAB2730E6396
+:105030003BE8EF7F19A436D0CBA65A4EAF45958CEE
+:10504000BE3F3EBD95D7772CE5DF35ED7F9DDFFB7D
+:10505000D816E5DF33857E7D32E065C778AE0FF781
+:1050600057F17EFBF17E13F26905B7BBF2307AAFE0
+:10507000A0B88E5239BDA6C73B01DE1F582A535C2B
+:10508000748FE08B003329CEB1AD92CFB3AB427EAB
+:10509000427C8F66D12D50EF9CBD7232DE2FD92E0F
+:1050A000E229FB16AF7C02F3FA3E08940BBA4BD010
+:1050B000BDD79EE3B7517CE4A12579D24A58E3BE1F
+:1050C0008399F35BAAFCAAE817738B789228131ACA
+:1050D000965B4D91B7DACAC4F7D8631AC69F9E197A
+:1050E000E479ABDDAB9F393613F571A54C79665D7C
+:1050F0008347BD97E1BAEB785E4F919A90D2FD1746
+:10510000AFDFC5EDB49AA31EA36A78FB67068F12C2
+:10511000DD6D07BC2B69FE9F2CE0EC467F02FAEDAB
+:1051200075F50CCC84767BC7E5493123D56EB49FE9
+:10513000F35FF712597C879ED1771C3ACD531E94AA
+:105140009B9D78FE01EDBB6BACBCD41EBA97B577C6
+:10515000CEE4399827BEED061E2CED0A1F223FB97A
+:105160006736B7CBF64AD00EF6655F8B763DDD63CA
+:105170006AE571222833C6897A311118F12ACEEDF9
+:1051800028F505E6ED6CE81BC0798AEAF8F72D8A68
+:105190006A32F77F21E0A6FEFB5C318A7F8EB47F06
+:1051A000FFEAE3F8ECACE2E7058CC5292EB55BF825
+:1051B0005D4C8D1AE9DF096D0970FCEC743113E365
+:1051C00065BE3A8DF4BA1C36C80EF583FD88F1B879
+:1051D0006D526C31E687C42669EC71C288E91D877F
+:1051E000F1BB097961A4BF4D522284DF558E8DE356
+:1051F000F1EDA3919D74EFEA00D8D1140E6609D2A7
+:1052000053DDD13CBA0F7534523D48FD7D15BADBF4
+:10521000D22898374F1F8A646CD2659BB6A25DD3A3
+:105220003945D6316FB353AA8FE278B15C0FC5917F
+:105230005D53E6D1FEB946E549E9FAE8463FD70BAA
+:105240002727446EF4C3BA42534EE562DC727BED0D
+:105250002BFB70FF1EB9DF4374F448EDE0DD38CF5F
+:10526000FEB3571D8F125FF2F3BA476B4F97A2DD63
+:10527000B3ABE9542EE2AF18E373A00F8B2B781C6D
+:105280000D3520D9676A0FBB19F058DCA631234DC4
+:105290001F7B193FCFC33FDF64927BF4F7CCE0293B
+:1052A0004F0B8EB784252E0DD0730FC6B32C3953F8
+:1052B0005CC71205200FF7AF78278679728F4C2CC8
+:1052C000A07B9445E23D494E18AF448CD7FFC62BD6
+:1052D000EBB1DDA3D50506CA8BE281A179A8248AAA
+:1052E000AB4E539C2D64DDFF881AFB6F25FA94E9C1
+:1052F0003B95C5E177FE02D711F0F5919E83F61438
+:105300003773AEE3E309E67D88BF6F4AADAF8E0B1E
+:10531000A6FC31FA437EBC97DFCB2ECEFA87B94A82
+:105320005ABE6D89880B6C920667935DFA00B7C30D
+:10533000C7B238C9B9E2AAD8DD3CDF364AF9B6CEE1
+:1053400079B7FBCFE95789EE51E737897B25FC77A1
+:105350006C4AC4EFD838E93E14CAAFEAB82A55DF20
+:10536000173D45F4FFB466DC95E97B0FFB845CD800
+:1053700024FC316BFCB1B97C7CABFEA8CEE9F1E931
+:1053800097F3AEAF82F5FC555BD9248C7FEE18C144
+:105390008F5B19E0F4973D00160EE881FED75EF3AF
+:1053A000623ECBD3325B8572AABE2AE14956093CE4
+:1053B000C2F8E48BC1F807C2DFF6A05CFA6AA092DB
+:1053C000E05A3195C70D3AAB1EA473A090CEF50EEE
+:1053D000F227CA775F282661DC7B790DD30F8978A5
+:1053E0004B0CF04F77E76596CAEBDF9E4B7E0EF0D5
+:1053F0000ABF5783B94993C5EF4F94E339D1A6BB90
+:1054000045FEAC8CF8EE14F300DFD23C078AC438BA
+:10541000F771FB1FFD0BEC5F2EE629AFFBEED750BB
+:105420008F17E99C2E52F0F57908BE5699117C6AC7
+:10543000E255F443B74F2A30906E0E84C26F374165
+:105440007DF92295E2F1E5351C8E03AD32FD1E900B
+:10545000BF4E3B48F7C74CD01769F832C4BC45353E
+:105460000909CFB58C56BE2E68E745B96884011E80
+:10547000A81B625DE7E09FA411FC459E41CC2D3A3C
+:10548000878795381ED0EFCA3ADECF1FEADB8272DB
+:105490006C791D871BF43BC15314D60EA2BE2F0A94
+:1054A000F1F196037E0E4929B8B22DB8EA64CABF5D
+:1054B0002AAAD10EA21F9C2DE05B19E6F0F4BF7E54
+:1054C0006A40E2E319385EB680375BAC9F12760B18
+:1054D000847E80F19E7225EAF15ECEA929CC38C483
+:1054E00067A37896F57E572BE001F0E317F3B0DD64
+:1054F0006EE2275862EC6399FF7E889116B7A8D8B0
+:10550000ADD9EA7EB17FAC8B3F273F8E5422AFCB23
+:10551000C2AF5B5965EFC76AD2EA6578BF8CD3FB2F
+:10552000FA6BF979C78109DC3E42BFE31C7F239DFA
+:105530004F311EEB0AE27B8DF45D49BB7DDCE2D688
+:1055400082E9281F8A071E9E27C37A8AEE65B292D7
+:1055500043F42C9D937F30DFB7D724E8FE6CF640F0
+:10556000240FE55D496BDE74FCFE5BF64094EAD9DE
+:1055700003AD26CF3F0317260FF3F5D2E6294539B1
+:10558000CDF3E958ABD68772AD361D4E785FF27217
+:10559000CF5CECBFF9EE574623FF1638FA7B72B8A2
+:1055A000FF50FC32B40AE0FCA7D7627B2BBE938D80
+:1055B00010E751F93296C53E90C7509688FC3B4B98
+:1055C0005E744E786752D427E887F2F15822DDCE18
+:1055D0007796D07EBC681F93CEDBEE34B51B29DEF8
+:1055E0003410E0F1A680B0577B98B19FF47B0DCFCB
+:1055F000F7F0E173D01F7D3547A7D37EF6B130D2E7
+:105600007371DB9FDCE9F2FAE640A9B8079D20BA86
+:10561000D74AB2E87C0FF898BE6F7A406DA573D672
+:10562000BE227EAE7974CE2B12E2B3E8399EA76D0E
+:10563000D9CBD36B12217CDEF56AF432E2CF11ECC8
+:105640004FCBDE74AEE792FA07491E8C8D322F9E47
+:10565000AFF957AB94C75A1205B8AA502E00491794
+:1056600002FC35B1F548374694D78DD5A25C05E5E7
+:10567000D560DFAE1B28FFA52B35EED60AB06BD167
+:105680007E1ADCEDB901ED9556B0460CB4174F7992
+:10569000F07B2ADDADD3F311CFCF442CFB3221E1D7
+:1056A000F8453F35C95EACD5351DE33013DC89D1F3
+:1056B000E9E77407E6BC534DDF139B7F71F9642360
+:1056C000E91384454ED323FD554749BF3CE11F4FA5
+:1056D0007AC8D22B961EA11141BEDC22F8A8CB4875
+:1056E00078249257C0BB00E72D2847808EFD455C8B
+:1056F0009E831CE672CED2277773BD6FC9CF0A3165
+:10570000CE2D286FA15F77ED13B937A05C1172D64B
+:105710001F3266E2F95C8590AF4C8D4938DF8129F4
+:10572000FC7B9501873CAD68E5E3748518D113E8EF
+:10573000A1834837078A12744FFC40EB5129FD9E24
+:10574000A9A5EF02AD4986FB3FAE8ECBC17142AE3B
+:105750007EC76F70FAF470B97A4EEF0979BBD53C09
+:10576000CAC4776133E661FDBDD0E73D1587C82F18
+:10577000D876EB29C2A7150F0D89786877D55BF429
+:105780007E7B94DF03D8654E9F43F047966B947FF2
+:105790005A73744E19FA1B4DCB35B4EB4E060AAC56
+:1057A000F32FEF42B4275B5791FDEB13FBF85098B2
+:1057B00009BF53233FEBBEA5DF1EC0FE21F08B24A3
+:1057C000031BF579DC48E7F83D05C47774903AFB94
+:1057D0006A0CFA0E84731DDF0BF0EFD2FAA3C981B5
+:1057E00071B4AF325DE9F1D530F23B97835F87C387
+:1057F000EE56C3DE09F07E7793ACAF67A9FEFF2BB0
+:10580000C0F3D126FAF93D859D8B4F6FC138DFCEAD
+:10581000A5E23B670EF8EF6BECF328340FC60428C3
+:105820008F39E3F7F6ABFC59FCFB0B357D0368CFF2
+:1058300007AA385C2F060C8EF7418EC79E884C7CD9
+:10584000B46BB0DA8BFACE69373E92FDEE249ED768
+:1058500062D73717AA173BE4FE0477DF7524EFBE43
+:105860002993BC628CCB3B89C906FEAE464B80D3E4
+:10587000539590D71DAEC47ECC2BE878D6C7D61BE7
+:1058800029BA28126376B6CA197F3FED5040E1FB72
+:105890003F7CDFB9FD20F6FD4981870BED3F86593E
+:1058A000D09EEE8B6F1A7307CAF156EE3FF725DED6
+:1058B000A2BCA3A2D90BC9EF3972F052F2078AAA8F
+:1058C0004CDBEF6B668FE0B756E478CE1B0F1849C0
+:1058D0001EEF5BDD417EF6BEC1CCF7620A72785ED8
+:1058E0005A1FC84BFCBEC948F3EB399CFFFE292068
+:1058F000E86ECE3BF4BD8C343DFBB2D0B3A46F8BCD
+:10590000551653D2F21C2608FC39F52753E39E4B5B
+:105910006B88CE097FFBC4F9C543A64C78B7E81C59
+:10592000CF0F10AFB00E53D0219D6FF4B0B807F970
+:1059300026D6C4F33C9C704FF0CB17B5BE600EF773
+:1059400043CECD27FCF5897E0EF7CEDAFBE99E2308
+:10595000CC1742FA907EF01FA7E93ED4B32EFA3D51
+:10596000DB19CFBA1218D3BAF320FFBD45F9452F82
+:10597000C1F9CF87F9F7D5137E6E8FFD5AE7BF5770
+:10598000F455F760F717A03EF4ACC2C89E8C83E2D2
+:10599000027A3D2DE8953DC7EB2BBDBC7AE7C1FEF1
+:1059A0006538DEAAE7781EE69DCFDF76E317A07E96
+:1059B000DB808BEE0CDCF9F87A6D0CD46F8F4B7DAD
+:1059C00058FFCD7446BFF719CBD328CEF59BC060E6
+:1059D000C102C0F707EB3CCCB80CE3A48305F3018C
+:1059E0000F77C49F9E89FDEE784A0A23DBCE78F6B6
+:1059F000F15746035C777E43A2FCAFAF1CC9B6D912
+:105A000085A76129D3E0FD9A83FC77236F633D333B
+:105A1000111F773EDE4BBF7F68E1F3837595CC485D
+:105A2000FBDDB03BBFF134FD9EE15DDF92E8F71591
+:105A3000EF92F93DA27F7EDEBBE8311FAE6FBD76EF
+:105A4000A91FD7B559C376B7C55BBE8B294D77C49F
+:105A50000F6A33E1FD1D070E6A2BD12F73B366D495
+:105A60003F5F3972854DEE9CDEA7907FB026D7430D
+:105A7000F7EB99CF0CCD9B307C9F3F58C76C70DD06
+:105A800061C509D4B83637ADBD4BE7FEEF578E2858
+:105A9000B6792C3B20768CEB85D8DFFA297E6EED2B
+:105AA000DF1AE1775BFBB7C60AC4AB439333C1D3BC
+:105AB0008DFB01F0F4ACD3A9DCB92E44E5EE7506FC
+:105AC000EDD35EC423945D02EEC054568FDFE70F22
+:105AD000983CED38AFC9ACC7BB6579115E2F581241
+:105AE000253F64243BC62AF7BAA22DE84376EEE8A8
+:105AF0009FA582DDB3578BDE8D912FBDE3D5590D68
+:105B000050FF9B9CC8C61C92376103F9CEF2CFBFF1
+:105B10009EC3E5EEA6D11AE17BEFD2C98F2996FF8D
+:105B20008571BFA52B9F407B02FA6FCF21BE0DD39D
+:105B300077BA46EA5FB0ACCED6BF60D92AABFF1EBB
+:105B4000EAEF397FFFBDCBAEB1CFBFEC0EABFF2389
+:105B500004BFEFFCF017344FB5CFDFBC9AFA7FD506
+:105B6000CDF77728D743F9F41DDE70C245FE33A385
+:105B7000EF73A879971EA2EF279D8B330D9AA86724
+:105B80007D4FE556A31C4BD1D1F46FE23AFCC05DCA
+:105B9000E97494539765E3AB5C33CF56CF9F3DC612
+:105BA000D67E54A4CCF6BE70D1E50EBAF4E99407C3
+:105BB000CBB83E3531CE09706A63F8F79AEAC778F8
+:105BC000687DF7BFE8A5FAFDD7F0F5DD3FC6477C55
+:105BD0004CBA0BF6FD7E2D7A65BA7D0CEB9230E463
+:105BE000F58C1E1DC8A94D7F6EC8F83C4BE1BF6304
+:105BF00097E5E6FA7273E9E4C76269F8DC520CF4DF
+:105C000000F5B773345B9C6773F1CA504BDA3C9B69
+:105C10008AB54587AAF8F35BD08ED7237F87F37DBB
+:105C2000551BBA14ED57E73CEEB23ADB3C9E925559
+:105C3000344FD2318FBB6495631ECFA243E2B99833
+:105C4000E714D2C948F36C2EBBC6BE9E923B689E39
+:105C50005FE33CB569EB29B9C3314F165F0F3C17C1
+:105C6000F3FCE6BCEB299F6A5FCFD8D534CFBF3BAE
+:105C7000E6718F5DED98C747F3E0739C8715713F20
+:105C80004A730FADA4FDFF8197611C487347FF9ACB
+:105C90002EA9FCBD97E2C2D0CAC476FF07FE2263DC
+:105CA00096008000000000001F8B0800000000002C
+:105CB000000BE57D09785445B670DDBE4B7727DDD6
+:105CC0009DCEBE10C20D288B86D88190015CA6594E
+:105CD000E4A122065770810E4BF6A4A3E23C1C758A
+:105CE000D2104554D446518306A6C1A0E0800626B2
+:105CF0006880800DA883332E719EE3320B368804B2
+:105D000021260DA2E29BC5BFCEA9BAE97B3B1D604F
+:105D1000DECCFFBF79EF8FDF4C51B7EAD6AD3AFB4F
+:105D20003975AA9A0C4F22641C21FB12683986909F
+:105D30006FE33C17396D84FC007F3F26F4CF474862
+:105D40002A2FD3085940F85F60A9408A08A9B5B046
+:105D5000EAFC4D33721643D93629A3A490FE63A5FD
+:105D6000DD75BE4A4877DB24655E5E643CAD5CE071
+:105D7000978F8486B3777F2091EFF82692E175F4B0
+:105D8000FB65094E9C8F563F524FEB66420ED51372
+:105D90002C3B6532A7983E3F5C4F27304C3FDFC518
+:105DA000F8DE1189FE3385964D42C027D075ADF8D7
+:105DB000402643F0331F0EA7EBB8912F63813F9E1F
+:105DC000104B641E5E3371C37BE1EDE6C03A019E69
+:105DD000BA07983268D1984C8836DFC184FC69F7DD
+:105DE000D56F090EAC0E308D25E4E6655BDE846E62
+:105DF0001F092503EFA0EB9DD9BA421E40EBDD72CF
+:105E000068B6CBA61B67A67C08D66DA1FFC138B3C8
+:105E10003CB4AEFBFE2DE5C6FA6D448AD47309B9D5
+:105E2000D03998E3837F570DC880AF1BE99A322998
+:105E30000A6F837214343B115FB39DEC5D6D3EDEDF
+:105E40007B641284F948A15492072DA9D8CF03FD91
+:105E5000D4BEF39B2D5BDCC5149FB3EF16118ED11E
+:105E6000F30DED8E779BF269D9F8B54C069F7DFE58
+:105E7000731619DB898F7D4F83AB460737CD9CF0B6
+:105E8000E4611D7DCCF25CF1E461039C6618EAB725
+:105E9000D5CD32F49FB3A8C4D05EE2AB30B4CF5BB3
+:105EA00076BBA1BEC07FB7A17F59E362437B45E0CB
+:105EB00021437BD58615867A4DCB2A437F6FDB5AEB
+:105EC00043BB69F7886B088563C3EF4462A670FC27
+:105ED000C676E4B18B53A0945C00F7A3F51948D7BC
+:105EE000C7EA552C6B81F6C601FF8CB678289EBC9C
+:105EF00071E1529248C87DFE4B962DBB84D615DACF
+:105F00003E9E52BB7FE2325F3621CB9C2AD2BDD867
+:105F1000A8902025558124F5D27558D4B587CED2C6
+:105F2000DE2891E0E8BEED6228F6F31E213C348BBA
+:105F3000AEC3F7A999AC17FAF279842FC90092D1B0
+:105F40007F7B978994B7E8E4CE7AA709E793EA9C28
+:105F5000B8DE49E9A15A61FC5EBD35732271403D4E
+:105F600038B4CE7686EFB5D0C9A4C3388C5F2A0288
+:105F70000322FC8BF81B62E0FB61099E6627FD5E35
+:105F8000D71E7126CC8304F7E55C3712BEEF5E0F97
+:105F9000CF491B1D2493F277BDFBC9C3E713F24918
+:105FA000FD542C7F5F5FFCE46199903FD6CFC4FA2B
+:105FB000817A0F96A1FA722C0FD5D761FBE1FA45D1
+:105FC000583F52EFC3F268FD322C8FD5FBB1BDAB09
+:105FD000BE11EBDDF5012C353EA0F2684E31F069C3
+:105FE00071B109F8F40E2BE17FAC7E92AF41A4FFB2
+:105FF000EE40BE7665005F9FB47D3B348BD2DBC93B
+:106000004F2831E5F60FA768BAEB1F7F6E13E0AF9C
+:1060100034408927B96FBB358EE1C76A2253099591
+:106020003F0F9DAF10897E3FEEF50BD789B9F85C25
+:1060300002D2A18AC335C31E63FCF308E2EB6C787D
+:10604000D2FA1F79F6CF4573F3003F83914EE2F603
+:1060500089750C6FCFBB006F67839FC4F92B1A8EB5
+:10606000C2EB7FCA09D1FE5FA56AF0ECC821B4BCBF
+:10607000CE597C14E8E064AB19D775B23D3E406060
+:106080000C670AD245FF7063F3A8DA60F5EBE543CD
+:106090004D4BA2DF282F32FD7A797172FFF30EE0AB
+:1060A000FB3B3244FFE1D1401F6E4E1F8CEEB4F13A
+:1060B0006B5A72FD36C338C6FA49BF30B505E5BC28
+:1060C0009A70FDC8FEE779478682DF39B6614802DB
+:1060D0007CF758BDC50FDFE9AA77FAD97733FC7A88
+:1060E000BAAC5E14EF3F9C1C995F7FE3FEB3E747B9
+:1060F000482BF9DC4210F43F0CE9BF7FBFF8904E0B
+:1061000029C5401FEDF2B7A077E2866B7A47C2BA85
+:1061100036AEB745F4992F82E79B0CDFA3EFA94772
+:10612000343C0D3E13DE2572445B27959323A9EC86
+:10613000063AA5C48C78F6D01113E8783D926D9993
+:1061400040BF634E54B1DD0B1FA2F4546309291EF6
+:1061500015C1DD0176D6DCB11ADFAB37FD8192DCEB
+:1061600097BF91C9C3D0FE173A3A6D9779EB7C522D
+:10617000EC20F47B735BABA6819CFCF2D5ABB89DA5
+:10618000E22F82757F454C53814FBE22BF758CD65E
+:10619000D965D3131536BF654C3FFBE87FB03E6A27
+:1061A000A719F47559A3B15E4AAE4D037E285D2947
+:1061B00093009D7B05E87B6DDD94EF2F4B64765C4F
+:1061C00019A95B0A76CAC3329909F89EEB24D2005A
+:1061D0002A276A5E5B5D5442EB37249A90AE8E515B
+:1061E000FB4EA572A82289D931952901C54DDB3F07
+:1061F0006F1D7DE3C504DE0F2C05B9E6B313D77A16
+:10620000D217EEF39619E777B6F947CF979025386E
+:106210005F6D1EDAB8DA3CC40D823B10C39E9D97B9
+:106220002844EC645ADE9968B45F17415D67DFDE8D
+:1062300017555F1255D7E844E674624EF42C4A4C69
+:1062400005BA084F413B8D50FAC88BF45322FDEE3E
+:106250003B533F33F413B1DF9233F5B346C67B3083
+:1062600056BF9AD736BFEAA3F454F9CA530E42E593
+:10627000F997923FCD459F57AF7FC001703A2AF9F9
+:106280001C80EF2F03E2D458F0DADD0B2FB74D005E
+:106290003F02499BC2FDA547A6839DF4ED7AD9290B
+:1062A000D22EDE0DE6A099D26F6D6BC534928FF5BC
+:1062B00083ACFEE00911EA6D467C56BEF8549A6A3A
+:1062C000473C307B9B04D1EEA86DFE620AC8712F5B
+:1062D00009231D46BF07DF3F9D847C5FA224F46D28
+:1062E000A7F3443BD9CBF9CCDBFAC809D101E515BA
+:1062F0009DC067DE283A2AEFD52F21A598CEE795D5
+:10630000447BCA910B69F547E447200F34B89000ED
+:10631000B32B1A363E937F90CEABABF9370E214F9D
+:106320002F47183D9E6C99F7F31D6AFFF2A69BFB61
+:106330004591F702F89EDAC6EC20D2CECA6A39E857
+:1063400000BBB37AADECA2944AAA373FFFC2B3E0D8
+:10635000AF7D6A467FAD6AF39B1F8DA7F5AA2D72AC
+:10636000CA34B61C9B9016C18F97FE6FD1A8083E09
+:106370002A7FF9A6A28E64CFEF4D8AE0A56ACB1ED4
+:10638000858CEC0BC7492D7B94902D067E5A0E4EC2
+:1063900001BBA561E3770AF85F5FEE16487A6EDF0E
+:1063A000F7CBD7BE897A11E084F8E4F8EAC55F1F1D
+:1063B000BC05A7EF28C47E4E909767C39B9FCBE98F
+:1063C0009AD7EC2491CEA3FCF7E6C034C0E7CB7794
+:1063D0003A603D9D521DA3F3D50FA4B9E9F7CB65F3
+:1063E0005F9A134BF6BC7CCD5D487F65425D9A1386
+:1063F000F9C99D6942D9EDCB84752E68BA01D75988
+:106400004A3C4887E5ABC5E2002DBF91C8D42D3189
+:10641000F8A42889F149E73A8A5CBACE4EB0FBC1AC
+:10642000DEFEAD18588FFEE9ED04E4FF5D7CCD542F
+:106430005362FD1B0BC3972DC9A4F98B1603FD36C0
+:106440003FD801783A36D09D0EF3A470F071B809A8
+:106450003FD071C50F2E4F677822AA54C4DFA3FA2C
+:1064600060123C87FE1DB2DB9A6F788FCB4FF6FD32
+:1064700085FCFB74DE71A0DF3AD3A87D1F637D73BA
+:10648000617DA817A99ED3D1998EDF19FF373FC42C
+:10649000F85DE3FFC08CA9D07EEA43C647F01EE852
+:1064A000133AAF603AB6EFB95E40F96026C1587C46
+:1064B000DE2C733E37B67B29BF429C40A3133A7F44
+:1064C0004948D0D30BFD4E12E201FD95D295F47DE3
+:1064D000BD7D03DFC57E4AE4B94EAF9471B95090DB
+:1064E00044E5417C441E90A6D473B223AB65E2031D
+:1064F00093B3FA5333FAE3D59BE56258FFF14DFBB2
+:106500003EBA99D2F9F1168D6F8D72359A6FCBB76D
+:10651000AE17804EA3F9F67839D5E2B1F8963E8FE2
+:10652000C9B7E5A1FFA7725583DFAC24A33CA5F250
+:1065300071109810FDC1315A3E7E03F6566A5FF91C
+:1065400048FF3E24457DE950A33F8DEEA80537085E
+:10655000E47A2F7D6AF4D74B9F1AFD45AFD708BF69
+:10656000E8F6C1E023513A29DE4E2D3A8ACFEA7689
+:106570002160463EF7BD35A010E1E446F546FC6FCC
+:106580000D48D1D70351F596A8FEEEA87A71547F35
+:106590004F54BDCED0BFBA6D9F4210FF41433FF371
+:1065A000A2E7C8E731FC414DFF785B4F283EA08B46
+:1065B000ECB002724F5E424D3788AFED1231BED65D
+:1065C000A3861D49F4F90356E6A7F538793D91D520
+:1065D000C3A9CA52907BDAF3B095A07FDE531C7634
+:1065E00024EAFCFF83EDA243A5EDA10099AA8F2325
+:1065F00044E6D380F80E91FEDA59DCB027CE918FB5
+:10660000DF8BCB0900FD5D2EDA721681BFE7175DC7
+:10661000947CC8FCC5373908A5B39EF621D7CCA415
+:10662000CF17BC2D82B94DD1E3963229DDCCE3746E
+:106630007C94F89EBE84AE6F5E3BB3C3E72F8F4D54
+:10664000F795BC7FA96DA102F295DAD187F471D1DB
+:106650004AB21CE9AEBC29EA79FB55C81F9551FC2A
+:10666000E1E1FEC32E8D3F0A4801CA174298FFCBD5
+:10667000E5F2E562DE3533291E7AF68BC4AC823F43
+:106680002B92A5B0CE4D4200E205C4978A7C564BB2
+:10669000C2280F353875011F0DEB5F4E756DFB532A
+:1066A000D13D402FAFFE21FF395A76BDFAE9D09D8A
+:1066B000507FEDE39C3F90BEFD27EDFE7E36E8B3B4
+:1066C0009EDD668C8BF5ECFE55CE3D50DF61C6B885
+:1066D00058CF12B31BF8C0B7DB1E381FDA0732FFE2
+:1066E000A161D777F921D4AFF723DE8E2631FFE5FC
+:1066F00064FB9F0F082950D25581FDB03B1EF9C89D
+:10670000BBC38AFE7ACFAEEF8A3CB67FDE7A6A15CB
+:10671000E2417AB493995B817E1359FCD8BB73DC58
+:10672000F38BE9F76B5AF728F368FBA4D7FF9A0FAE
+:10673000F2B3672BB38BBAE5D01AE222E4EBA4B232
+:10674000876488F301336511F278F2862B7C79B186
+:10675000E0C2E0D043E100EBA2702907B9DF1F3CA3
+:10676000E29215A4F77F3D789C98CDE4DA8F08C4B7
+:1067700085227011DCECB93D601170FDECF9EEEF93
+:10678000F241EE1C6F598CF6CAD9D63D22F95F95BD
+:106790000EFEABEB1682E7B2EEA9FFB2F866F4FF8D
+:1067A0005E928AF38CE683BE74FEDA4FB0FEB2DDF1
+:1067B00085F33D47FE2FFFDF86F7AD14EF8EB3E381
+:1067C000FDC1FFB1787F9BE3DDEE34833CDBF55701
+:1067D0008CB36AEB3FDBBA5FF81FBA6ECD8EFF95C4
+:1067E00049FDB080F67F9BF83F1C4AE7D994BDEF86
+:1067F0008302DA3A5120C5B1EC938F92991F385138
+:1068000030A1FF471205EEFF31BF6900B723062C08
+:106810002C457B6340F6A3683710495D09FB77BFC1
+:10682000CA99E77A187B8CFAC40375E7A5BC6EF4A5
+:106830001F9F13885BA036E8809CABF683FD9A9D72
+:106840002DA27D4B4BB46BDF704C65CFAB1583DF56
+:106850007405D1D5E9BAA6A418FDA2C97CBCCBC9E0
+:10686000E00F0BE8FC2FB7C8CE0005D115133C1282
+:10687000ACE78A4C81F875FB4793A3FCA7ADD4C65F
+:10688000D4C7D7FE5EF85952989F395118BCB21838
+:10689000E03750C4F8E159E107C61EC2AB20F03022
+:1068A000D845928BC12FA9C685F157EE57C37633D1
+:1068B000D82B926D6907F0AD44A85FCCE68FFEB48B
+:1068C000E617F70767C2FD6C897F5283BB942DBA28
+:1068D000ADC6F1101E1A3EFE5E3C68F8FB47F1F1B2
+:1068E0007BC0C798083EB24F3925E0CF49DC1F98DE
+:1068F0007CAA43C47AB64BC2FD17EE0F4CB0254AB2
+:10690000E00F5C2A7D20025F9659B657C23E82C5D1
+:1069100025205D0FEB32A1BF63291410EEC31B25A8
+:10692000AC7F60728E01437BFAC5AF1DBF9B403CBC
+:10693000D9AD30C3BB98C5F3FFF2C30F9714415CC8
+:1069400085FD95D1FF5D4DFDB1F94D241847E1B4AA
+:1069500040223E487158401775C8100F36D6E1EFF7
+:10696000B2B4C83867EBDF9F1CF96797AF51B975B0
+:10697000E87C42B643C982FD92DE6FFE513B8397AD
+:10698000F71D12188CF106B758ACDB67FBF714261D
+:106990003F5EFBE3D6D1103F9BD09397C0E469A143
+:1069A00009E8D2CBFD8293444D807C8593ED431260
+:1069B000701F71BF68F7C488DB6CE4FEF42FEA3106
+:1069C000A84C7A9A895F04BF8984317EEB6BB6C488
+:1069D000DC0F9E9B62E274C3F146FFC422D8B7600D
+:1069E000DF5F405F4DD0E3AD6BDA97527E5F3CC016
+:1069F000DF21DDFECA3F0A5FF0DF01BE1BADA1292A
+:106A0000C531E4C7420EBFE97BBFC778E705ED6B30
+:106A10004D40BF17349B0CFB93D529DCEF1A45463C
+:106A2000C1BCA6EFB5DA0B012FFB459795AECFDBC6
+:106A30007E42F1C4D8E78A86278C0F71F49752D82A
+:106A4000BEC04EB9651EC075E75716E2A3F8DDAEAD
+:106A5000F8AB62CD33258DC9B905A4E5CEFCDC7F4A
+:106A60003DF84EE8B10527829FD94C785C239AFE09
+:106A700008D2F1C90D2400FA14FC52900B273711EB
+:106A8000D4E714248F825F4DF9FDC7FA38CDB0B634
+:106A90002DBF003BA0B65D709A687BAD1452201EDE
+:106AA000EB6D4B1441EF16A8C48DFBC39273E4F554
+:106AB0003ABE78294542F8EE1BBFF316F8EED75DD3
+:106AC0000A017BC4FD46D8017AFBEBF6D1C807FD6D
+:106AD000ADEB97F5A472B20CE33079184D0F799BAA
+:106AE000E20CF58B454F16F0D7747368A12B06FEA8
+:106AF000A6A5323A3B67F916F8FF4CBE7DA8C93708
+:106B00008F58ACE3A3945446F73AF9961E4BBEDD7A
+:106B100021A8E900F73B760D4907BCDEF1B69C1AC7
+:106B20004BBE6DAE67FB7FAF507E84B2A795CAB7F0
+:106B30008B74F2AD95CAB7DCBEEFFDED5CE55BE0B2
+:106B4000BF87FF36837C8BB1DE440E3F4DBEE5B779
+:106B50001F44F996DF6A22AACE7EB0A49E4DBE09DC
+:106B6000A9D7833DBC5F76C5C7A09FCDDCFE7E85DF
+:106B7000E7EDC17740CEFD5B2ADB2F3D5739979972
+:106B8000C6F8E4AC72EEBF09CE9A9CBB631B95734A
+:106B9000B9B1E890C9B93BB6533927003D323977CE
+:106BA000C72EC2E26F51F26D781FF946B07F6D902B
+:106BB000BDEF6DCB7DE6563ADE28B7ECB2D0FEA332
+:106BC00022F26E8C5EDEFD5BAA8470EE23EFF69FF0
+:106BD0009BBCDBC6E51D95638341BE46D387AB3DB9
+:106BE000CE50DF39AE73D32F815FDE15717FF10395
+:106BF00013DB077A6F5C6721D0D72A3E1F2FA7BF10
+:106C0000EE7A1F8E3FE90DB6BE9A4D2CFE5DDBCAB3
+:106C1000ECC3DA6631A0D27F4E19FFBD02F3AFD8C4
+:106C20002590745A9F61F63F6D0319FCA24CB85F22
+:106C300034AD40470FF3C756611CBFC1EA5847281F
+:106C40001FCF978805E2F555B6295F821D5C359602
+:106C5000C5F7ABF873C2F306B43CC8D2B6DBDF1A93
+:106C600040FAE60F4C37333C4E7F5E08ACCD85FCD6
+:106C700025637B5554FEE3637C9D33C410C285BC01
+:106C80002FC6CC63782C1A1EFB393CE8FA0DF008AD
+:106C90000831E141313AAD202DB2FE8A77434B21D4
+:106CA0009E5FB14AC07D5F0D1ED1EBD4E0A3C5A7A6
+:106CB000ABF8FBDEF6DB71DF3F7AFD1AFCFAAC5B6A
+:106CC0008367D4FAFDA97CDFAB808C867C1A4A0FDF
+:106CD000283F7CBFA670A0DF299E707EBA5E1E3F53
+:106CE000CDE130DA3F61522601B8913AA09FD2C679
+:106CF000DBDFCAA4EB1FF3893A0AD4E4C5E3CD1E57
+:106D0000D847DD680DA37CD3E8AB53A3773ECECE46
+:106D1000ACBA89E8AFB7094EB02FBC412BC2D14BFA
+:106D2000E9CC4ABBEC5BF5ED140E47A719F98AEBE9
+:106D30001D0A7713F8539A1EA27007BE19DD7E0252
+:106D4000F7730B4918F74B6A1B055790AEA3B68D26
+:106D5000C14B93B7F4CFA6C7470C7A9462D1238175
+:106D6000207151440F56F17ED3CDFE8F601F663ADD
+:106D7000A5F7B52482C7E1F43FC063349E34789E02
+:106D80008D3EBFE0F6C76680A30DE0156676549091
+:106D9000EA057BA4DD2BF90C709CF4EC69465FBB23
+:106DA0000415F6137AE104F44ADBC7B4337A05B864
+:106DB000A900F7F61211EAA514BEC9B97DD709FBDF
+:106DC000977AFEADD875908DBF5A709118F4ABAD1F
+:106DD000BB3FFAFD47E9B6338A6EDFB386DF190D94
+:106DE00074BB4B607184F644C3BEA3398DEDBB6F99
+:106DF000B452FA86FDAEB765D73AB52F9F9FE6F03D
+:106E000004FB5FD5C5A546C002602F708305F3CF94
+:106E1000701E83997DA997AF9BAD24F5FAC2FEC77A
+:106E200057B83FD09F7DA3D547C2F740EEB5D1EF0D
+:106E30000D8F7C2F5ABE6BFEFED9D6959CF68FAD7A
+:106E4000AB377F9374E0FE9339D1734F0AC67F58F6
+:106E50007ED28D3C3F89CE00ED2C5DBF8CD431FDC0
+:106E6000F7231916D4C377F2BCF8CB451BF1D175C3
+:106E70007CED96914EA996FEDD25209727523D4246
+:106E80008BAFDF19F3F1ADD82EE27ED435EF26D7E4
+:106E9000C03EDD35208CE8F36B0A04D4BF1FC06010
+:106EA000E3C08EB510B79993306D1FFBA3C4C0C368
+:106EB000B4BDA0D93F49A5FC346A43A0014AD7A478
+:106EC00070CA7B00BF092201F875B8932781FEBA0A
+:106ED000F30B5220AAA867719C51FB492AF41BEFBF
+:106EE0004E4577605CEBCA49101F9DB1CF66033AEF
+:106EF0001FDE64221E1DFD8E278106D8871F77D8CE
+:106F00007D1DF05F39B51720EE5CDEBEB6C101F520
+:106F100026C1A5D2F1BD3ECF14079DD7E6C61353B7
+:106F20002E043EA4FD60186F13EBE76D165C902AEB
+:106F30005BDABE02F3714A9B05E284FE018158D8F8
+:106F4000B8010B1D7773137D9FD6CBE07D18B7F981
+:106F5000C487D7019FBF23B2F737B17DEB52FA9EAA
+:106F60000AF4DA7C3B8E57D124900C3A5EF926263F
+:106F7000FFCBDF915DD0DEBA6715EAB169F47B998A
+:106F8000B920EF8393A14E460B4EB0B749F6CDC85A
+:106F9000D73D9CAF49D74C2637045EE77E836637E2
+:106FA000ED4D63F9C1A5AEC54A321DE7BDB1A9B922
+:106FB0009026E06D3B81FBD187299C3D14CE1FF0CC
+:106FC0007C8E7D633F57423AFDF359DA10A4C3F932
+:106FD0006D1330CF610129C63C87E9E398BDF6FE09
+:106FE000A5D68040E7F5BE1CCE86E7FB2E35A3FD77
+:106FF000DBBD59C6FDE2EE81218C4F7736C904F224
+:10700000351A9A44948B9D9B981E1757DF30251391
+:10701000E0B75E7081DCDCD7344901BDD61910F0D1
+:10702000FD49ABEF4A637E0C93879ADF56EAAC309A
+:10703000E88F68F9A6C9BF1A0E87683957A3E9997E
+:1070400028395703FBCD0E288DCFBDC4C6E41FD809
+:10705000FD80F7E0F748BFB5EFC804EC7EE1F3AE82
+:107060002998B7057A93B68F6B17DCB0CF5FFE898E
+:107070003980F66AA064CE4F417E7F6A26820A7903
+:10708000F014EE542E8C3587FFF8247DFEE50716AC
+:10709000C890A174528270D6F2450BD7B3FC96C249
+:1070A0000F56A695021C2627A39C2D6B14894727F3
+:1070B0002FBE14DCD7DDCCE4B173BD4E1E152AFE05
+:1070C00052D05FCE742607D5F532E48C906D5C3ECD
+:1070D000517BDA0D7643C5F615690AEDB794E7835F
+:1070E00054EC5A914645036900BD45FB57286CFC9A
+:1070F0008ADD8273AD6E7CED7D6D3C6D1C65BB7170
+:107100009C21BB78FD1CC7D1E6A17DBF3F7B7CECF9
+:107110007F9C5E29D0F1C6BE2F6292F2D8CFA70D18
+:10712000D1EF7768A5167F2DFAD044DC3AB88DFDF3
+:10713000631C71EBE8A2750CE56F8AB7ABDB983D79
+:10714000D43AE6A05253887527F0732D8FD3D64ECC
+:1071500066FB56AD051FDC0FFC3DAD50403A203EAE
+:107160008F929C8276900AF1F1B242F67E197D1FD1
+:10717000F8AE7515E3432A0F549017B54D2BA66052
+:10718000FF664185F15BD796A09E2F1F2B126C6F77
+:107190003E88764779DBC114E057CA9F2B41EFD672
+:1071A0005E6276027F687CA7F1F1FB32CB0F21167D
+:1071B000E74838075096A6C6E45FF11DC2FCD44DDF
+:1071C00032F29D772CE3CBF7378BC8CFFB2EBD690E
+:1071D0000AF061F77AA11F3EA67C5A18E153713577
+:1071E000CBD729DBC8FC957D4D4C3E74B6323B7144
+:1071F000D26AF96AA897BD2B1316F762F6E0B9F2C6
+:10720000731F3B65436C7EEE8F7FA7CB2D1FDD493F
+:10721000E777CDCB74FE6A045E932EBBDB8171FAF7
+:10722000CB66E17A3539542AB17CA6F9FEC52CDF4C
+:107230005762796F7FF7BCA2E6F1609A3D2247441E
+:10724000A0F7449627DD2C23BD47F3E33FCA47FF51
+:107250002CBEDEC6E9489B8FB88BBD0F7965410A0D
+:10726000C75F6D7A1EF35ABF7AE9E074C073D54EDA
+:107270004ABF74BDDD9BEC2408724B0AA0BEA96C0A
+:1072800015317F9C48C1A2EBEC7AFE64F94955AFF9
+:10729000D8916E2AB7B2BCD3CA573FCFC77C9125CD
+:1072A00061CCBBF2BDC4ED4D5F281FE8BB526279D3
+:1072B00052D1FC3E219DD99F5DDBE367C23A840D2C
+:1072C0007B70BFB5B2E52619E8AF577EA4CB5A3F15
+:1072D000DCC7F451FA857D7698DF8C91FAF92D465A
+:1072E0003C756D64FC5FD92607AC30BF0D6B319ED9
+:1072F000EDDD7002F3E327BDB219E308DE36D19865
+:1073000017B9410C9A317F533C6846BFC6989F58C5
+:10731000DB5A83FB6EB52D3CFF2F2A2FAEEA955D1D
+:10732000AFFA2868AA7EF9A203E4C1B18EF50E80F7
+:10733000271D0FF30A2F3B2519F2A3FACF07761B5F
+:10734000F30D5B1EE2F986577792FCBEF986C7E023
+:107350001FA06FD2A3F2353724F3FCEE6051718C7D
+:10736000787EEFB99FCDDFAC813CF9AEADC7D7C019
+:10737000FCABFFF6F51AC86F22BBADA8A7BC2FFD6A
+:107380000EF38AB5F716A7337AEBDEF822E66577B7
+:107390007F6A467FA77B57670EE4B7756FF93E0D8E
+:1073A000E2730B775D8EF1CB85DB26A59318F25E39
+:1073B0002B813E03E790171E8D8F7DADFB300FEBC9
+:1073C000AB4FCC28DF7AF3475B6A585EAECAF34610
+:1073D00037C5CEC3D7F21C6B5BAFBBE65290D7ADBF
+:1073E000CCBEEBCD7B3C5BBEE88714AF179D03FEA4
+:1073F00036F1BCE096AB63E68B7E05FFA078FA79A8
+:10740000BA315FF49BD6053F7F16DA5A93FBCD174E
+:107410000D9E03DCB43CFFEA74F74BE9C0475BE325
+:107420007D190C6F816902D881DFE4C0F988A372ED
+:1074300018F340C2BBCC4EC87BACDCF531F24BF745
+:10744000B60F30DE4A789E7D37E9FD63F9D0025FE2
+:1074500067B39DE59972F8431EAAEAC0E73CDF9442
+:10746000D1B19687DA5FFE69289D9F1FE6E70E6A15
+:10747000A8DFC4F2D42379A9C258C0D741435EAF74
+:10748000B6EEE8F19C5C8E46F2AA63E7F96A79846D
+:107490007DF1C5F48A9637DDBD96E75BD3E7D9A3C6
+:1074A000204F8EE9736F40F838167EB5BCEA3F4432
+:1074B000E1575B5F7F7CA1F1E7D9E6FD5F85CBBB40
+:1074C000E92C9EADC1A7EB2FB1E5F4B79CDFA9DF96
+:1074D000FA4DBACEBF9DC3FD560D6EDA7C97B6301D
+:1074E000BBA26B03F31FA2F99BAEC71D2BCF5ECAD5
+:1074F00060F66F6DDB9E7C90435D7BB773BA6374FF
+:107500005DBBE920CBD3A5723BA097DB84C591A3DB
+:10751000C773F0F1BCEDB1C7F36E3A1173BC63925F
+:10752000FB2698FFB10E66471D6B11A706628C7F84
+:107530009AEBA5DE75DB15CC97121D71684F2DB443
+:107540008FFD2421054A05F37E1A16F33CA1FB5C4E
+:107550001900E706FB9504E6F300C047177F909DEE
+:107560001E02769C9C515C28AA91F96AED4A8A8990
+:1075700004F4F89782D920DF0F1474CA30DE675103
+:107580007193CF24B2349DCEEB339FE05AACF66FAB
+:10759000776B75CFBDA221CE516B0E1F00FB9DBC3A
+:1075A0006EC5B8B5B8DBEAC3B8D91A2BAE73DFB66F
+:1075B000EF5E007875FFDC4CD83E02250C2A17CA16
+:1075C00078FCA273DB776BFE0C7626BC4CBF5FB6F3
+:1075D00086F607FB7A533CFA033D5B13F2D19E7C9F
+:1075E000FD9EE92037CA4087819DF74A7AA0818EA7
+:1075F000772495D58F6C1E88E709AAB6DA31DF703B
+:10760000DFB6D76A41FE77BF120FDBD1E42B39F426
+:1076100037A87B772690B52ADA81AA5EDF56104913
+:10762000D5DB79555037E4BF10F4D3311E47E9B9A3
+:10763000AA2D01CF8FE8FA717EF665B1F332C12C25
+:10764000E03B6A4F1ABEA3B55F9F31989FEF0DFFD5
+:1076500084DDAFC0FA7B957029ABFBB318DF766091
+:10766000FF128D5E797BDF7159FF3919830DFDB4EF
+:10767000F76BCDA42E161F546708FC7CEF5F87C5FF
+:10768000BACF22C6FCF1F95D02F199C00ED8620DA5
+:10769000405CA35A090E85FCF65715B63F52ED081B
+:1076A0000E85FCF69D5CFE55C7D13A7D9EC5E7016F
+:1076B000FDA14E2CA19701DF35AF5909E427D5BCB8
+:1076C0006E77039E6B5EFDEEC8738590CF168F714B
+:1076D000AB9AD7FF1DF15F630ECE06FA0F6F3193A1
+:1076E00075B47FD796B773C08EE89283394967D84F
+:1076F000F7A969311BF6B1B5751CAB0F9C07E7D72D
+:10770000B5738B95FDC88B5D19CC1E5D91E17E3CF8
+:1077100003F9DAE644790DE389304EDB10FDB9E672
+:107720004A35B61C6BCA900DE768C5C839C526181E
+:10773000F72B125A9A455152238471FFBC72C389A8
+:1077400091E00F7FF6B30B715FEB33253C12E4F64B
+:107750006739E1917A797CB4DEA24A32C625B0EC71
+:10776000597BA2348B40FEA075662CF9B439231ED8
+:10777000E751796F7CCCF3A03B38BDAD061A4C6560
+:10778000DF853884F6DDCF948002F3C8CB54B1BDD9
+:10779000323BA0C0F3AA0DDB8718EE9D90FCD88F7A
+:1077A000F217C2A382AC540A6D7DE54AC5229B2A1A
+:1077B000E1F968E93F7BE94D8CE009839C90A7C61D
+:1077C00071483513C641B5F300925C6C017829A469
+:1077D000D82989806A3FF2691C69C1D246CD11A6B9
+:1077E00087EA08E4151DE5FBB766497D1CE4877947
+:1077F000BF88F2FC6C70FB558603E76D96EA880B38
+:10780000ED8E694EB0AB059F87FC40E9A1A17EC318
+:1078100090C36CFFDF0DF9700EC2E6E770BEF53D58
+:10782000D80794CED0CFF65D46020DF47B92C2EA23
+:10783000642209C4DA8FEFE27820BE3D287F6C24F1
+:10784000F217A6F5789450F4BB097F1B0B7EAECDE2
+:1078500049826037C5DB48309E96B63CE9989E7FEA
+:107860001D84D507537206B9E6BCC4D81E4DD7C4D3
+:10787000259DEA958B22BE7F2AEAFD53677A5F83B6
+:1078800087D73224979D7F677089E36BF04D749D95
+:107890000E013CF21DAE06C0A3123E700FC023DFE6
+:1078A000C6FCC49446A2F7E38664327975BFC0F47F
+:1078B00025FD2BB6E9C6234E0BC64F1FE270EFED38
+:1078C000AFC555FAF4B74A00D73EFDADFDF58F8B35
+:1078D000DDDFDEDF7CE263CF27B19FF17DB1FBD737
+:1078E000BEFEF17B41151E32B9211193760E7A4806
+:1078F00026F85B0907D24A1855B07D8228BCC5011D
+:10790000FD517A883B4FF71CFE2F4F87BFC131F0E6
+:107910004F824877257C3EB46ECBA4F3BB994F775A
+:107920007233DBC7BC75218B23DD7C2F3B2F74F0BA
+:1079300067ECDCFEAD8DCCDFBE7511DB3723E5ECEB
+:107940001C9093FE07DFBB0D06A1F8BECD2F04826D
+:10795000B9700F4E94FDDA7BDFCE5D12F42F898A69
+:10796000C768F4A49D5B9AC7EDEB5C4E9F0B48D8AB
+:107970000E7C1F7D8EBE3583E5A55177CC0DEBBB0C
+:1079800085AF4FD303BE156438DC0B209AE25CB0A0
+:107990003F22F273ABC4A1B0BCE5EB930CF2E7E479
+:1079A000703501F41D79833FE7F711DD71859AAEDB
+:1079B0003FE7259D8EC7FB471A645706C845F9F473
+:1079C0005544A57CA19C1E4254DD39346ADF21B3A5
+:1079D000CB4E82711CC9594CCAC02E4CE4749672AD
+:1079E00065AF1DF63E85CB1D2B543C077B5326D33C
+:1079F0002F0F67152F00BA101D635D1E5B5FBCFA69
+:107A0000B6B1F535C0FA72FBCEBB4171B9D00EBD2F
+:107A1000925A1018EF7159603EA259FD5805FEFCAC
+:107A20008D4CC0FFEF0B0786CF93294901C87F9982
+:107A3000EF78F800D0EDF27A27EEA32DAB1F8EE59C
+:107A4000C3F51968872EAD7761A9C1C5E2F2BB45C0
+:107A50000A67CB796C3C8BD3C3EC0CAA8720FF421E
+:107A600072D605A16EC9AE2360FF5A7BE1E347F8E9
+:107A700028BD750FD6CD50A7A5DC380DE14BDF270B
+:107A8000651047CDF22C07F858D50B88AAA30B73C5
+:107A9000C62843BD0FDC34FAD8CCE0F7A8C0E823F1
+:107AA0001A7E8FCA1D2AEC3F3F7A45EFBD36083F4C
+:107AB0006AEE33F8FD9AEDCFF50B3F6712DAB3F3B8
+:107AC0008B96CE6EA08F1EE1FB900FD68F45783D32
+:107AD00004795DC3C03F70632902FC281D99F37CC3
+:107AE00044A4EF9B553667B3ADD86D2A64B40BF050
+:107AF000136D0C9EE68C3ADC8FB3D818BC449B0FF8
+:107B0000E122DB18BC441BA33785D72580DF687CC6
+:107B10001F9F53F8B5668E013C8C37C04B4999784E
+:107B20006EF05B45E147E791C2F92B1A0E29704EC2
+:107B3000212FC257FDD9754FD1F5831E7F86C2070D
+:107B4000CAD47EFCC7D42C2647534C757B6480472F
+:107B500012E1FAC547B28B084B5584BF0C1F51A1E7
+:107B60002EB0799066235E45A71475EF9BFA0CD072
+:107B7000C1CAB76513EC938A8BAE329C271567BADE
+:107B8000135584A74700FDFC48BD8AF85B01781CAB
+:107B900006FA91F9630F707C3E087C82F865FCF16F
+:107BA00028E797C7399F34B8D8F989E553595E5605
+:107BB0004A8189DF871624FABCA744570B51E8BCD9
+:107BC000D0C656B10CA29DF18939703E7D2F3E8FF3
+:107BD000B8814E123FB93B806B25C599601725725D
+:107BE000FB975CA226CEC283B44189F9215414A22A
+:107BF0005FD3618A750F56836BAF05E2A6FDCD6733
+:107C0000CF8C57912E4B2FC2F46092EC299EB580F9
+:107C1000D66D8DF1181F8C77798A1E003E6FB423C4
+:107C20009DDAE8FCCB74788FEF07AFCF665D61CA51
+:107C3000A2742882D146F1FB44E3102BC0F929B984
+:107C40003813E4EB535CCF521CA8FA7DA82E2E27E4
+:107C50001D851718FCD995B21BDF735E6294032B48
+:107C6000B9DC4D9A6CA4774DEE7ED42B773DA930CC
+:107C70009FB4D393911F53AE8D2D7F1B64C507F71F
+:107C80000A348C64FCEE2B51D0FE8B210F30AE7D7C
+:107C9000D233741DC8538DBE9610267F7C24CE85AA
+:107CA000FA88DFA3A3D9C7CBE0BE412E67A114CFCA
+:107CB00053906ED26E35617EDE727E5FD66394BE67
+:107CC000A0F453FA82F2D22CB69FB1C4320AEF6DFF
+:107CD0006BB099505E489F9A0336B057F78C734249
+:107CE0001C41925D1D6E8807DAA5967504FA155A37
+:107CF000E03E0921B1D00974F0AD7DFEA033E5E18D
+:107D000051740A4047CE946272280F770FF05CB32B
+:107D1000ECBC96405CF199943A2BC02D2F8BF95D09
+:107D20008D254508470ADF8959A99171D2675ED927
+:107D30007BDF160CFB4C3FE7A3A767713B3ADB47A1
+:107D4000CED3F17BA3C0ED30D54786EBF87EC9F9E1
+:107D50005308EC2BF5E5F77EE4D97A26CFEE1762CF
+:107D6000CB33CDFED4E4991C2527B472E9A0A986B3
+:107D7000F35D4A8A0B68174A9F89A248F25DF4E8CE
+:107D80002D890887790007927165AF5FFBE3C160B9
+:107D90005716C5A4B7683936BF57AFBBD3004F4796
+:107DA00065357D16D0D3DBFDE9757729D2A17F80BB
+:107DB0000A7A69CF1357615CE7F0137615E450D95E
+:107DC000E987503F949E1E876579E315A8CF8527E4
+:107DD000AF2E027AE86CBA3CFF5388F3F8EDA8B7EF
+:107DE0003B1B270DC5FD487FBC0AF91D9D8DB4BD09
+:107DF00030D20EF9E2A22E5F8040F45D77FE9B1434
+:107E0000AA68976AF79E51BFCE311EE242AB453C4D
+:107E1000D754FAA4DD0DF6677FF457DA143B1E0041
+:107E2000BA16E2AEF483C3C18EDEE3181F0ED27120
+:107E3000E7AF63FB080D8AFB4810ECA627ACB80F30
+:107E4000D99014FB5E900559972F0739B020CBFDD0
+:107E500014E2C9C6EE29ED9F1FD8F78FC02633EC78
+:107E6000633DCBEF47913C8E19867D36B68F758486
+:107E7000C75988A59FF638DEAEF6D3EE60F922C466
+:107E800019BB5DF333E2237E460BACA3A6F1F8D217
+:107E90004F115EDCCFE0F33E2AB3791F7DC11C5841
+:107EA0001283FE8FF2FC940A81C157E383A3BDF6CF
+:107EB0009107EFC389A65361DD8867C6D171BFDE24
+:107EC0002FA3DEA8A6F48574B56E1CE6C70B4F8CF5
+:107ED0007B1CF2864FBD23627BE5692BB677DDE71D
+:107EE0007A06F29EC2EFCA04E4D3A9FD9727B03800
+:107EF00091318E7DDB0026170E71F9507AFA11A4AC
+:107F0000DF5E3AF12F5080FF4A4F3FC6E87B838007
+:107F1000F756125FF5BB13CEE3F4391EDEAFB87A25
+:107F200009C0FB123FEE9394AD37BBC01E88C6F369
+:107F3000A12CD510F7280B2DC77109B5BF5274FBC2
+:107F4000E947799E71D969765F2171FA4806F00395
+:107F5000974F113A36DE43DB658D1DA73FC9ED9F74
+:107F6000D2D3171BFC8CC8FA2EC3E7A55CFF9785FC
+:107F7000C6613DB29E67C6C55A4F641D9760FFAE8D
+:107F8000C4D8DFCFE4703E525F4EDC54BE952BACBC
+:107F90005FA9FF2E05E44E69536292A05B575963B7
+:107FA0009521CFA3ACA94499AB1B378287A5EF4E8F
+:107FB000902278C87C6EF1D54B6C601714CB03808F
+:107FC0009FD65514FD5485F1987CFA52F6E780BC93
+:107FD000EE6CBCD311EBDC44E68028FC3472FC5020
+:107FE000BBBA50871F0D2FD1EF1F595B56F4538832
+:107FF00047AF62B790F42F7FA2F0961B1B6EA37A57
+:10800000E1361CF38DCE0EB70B0D79457DE0C6F140
+:10801000ABC1457B4EEDA80B078C81EF11767EA797
+:1080200091E1FF6CF08A7C97E37F42EC75CCEC5DCC
+:10803000C722E2A38C3AFFACEBB887F82C675887CD
+:10804000867FF28201FF339F5B8B7CA8E17BFEDEA3
+:108050005548BFF3293FC27E7FA7FF2E47ACFCA245
+:1080600099FDE1FD3C1FC92BFABF87F72F655F0E15
+:10807000E495F95658D11F39BAEE911C3D9C17640E
+:108080004DB80DF0429A53CF497FF826BAF6837F58
+:10809000E97B42C678DA962C4F19BC5FCEFDF0FB27
+:1080A00013A70C8D651F3C50BF7F04C4E91AEA3B3F
+:1080B000B094B97D49C0BECC457BC91DEB7EAF6590
+:1080C00003985C79A0BE83C53D2D3EE2D49F272650
+:1080D000CC7EFA4FC2E235DA7B8AEC7142FC54E185
+:1080E000E79D65C9B32CB710E21E29053E1DFC961D
+:1080F0000E60E7919667EC75C2B962331D1FE239D5
+:10810000966CE9A4719F93D50B844F45C86F965325
+:108110005A08C643F3E8731DBC95940E437C3A1A83
+:108120000E92C581FB4D1261F69CB67EFA04F5D223
+:10813000835C2FADE471CDA7EB5B30EEBF24DE8115
+:10814000FA6FE92013F3A72C12DE57634E64FD95F6
+:1081500004366F2BC4BD45D0AB41ACDBE1461F11EB
+:10816000AF4613A09E485401EAC924B814EF4999B8
+:1081700010FA093C7765780280C76F333B0E081010
+:10818000C72EF60C03FDDB28FA0A54DAFFE762B8C3
+:1081900000FAE5D0A64F92583908F2A13DBA7D2DDC
+:1081A000764FA8AA8F0B46D7072D92A2F67BFE32F8
+:1081B0004CDFBE22C3FD0ACCA3C1CAEE194AF95C4A
+:1081C000C0FD9C062BBB6FA8C17E6302E8F15F0F68
+:1081D00060763BD201D0D17E66CF9C94D4842416A5
+:1081E0002755DF30C4F92DEA1BBAEF48DCDF6BA658
+:1081F0007429E9F655CE93DC26A09BF3FDF4B97EF5
+:108200009E31E2714936BC9637E67E8E363FC8DB3A
+:1082100007388AA7A7A0BF164D0F3B7BE3CC3E11C2
+:10822000F0394BBBBF58BA9FD51389F687FED7A745
+:10823000BDF6E8FDACCEF739BD73D93E66434902C1
+:10824000E6C769F398D5FE6007D8A9B3DA33E7C16A
+:10825000FED62CDBD02FA0DC2987F7C6831D7897AC
+:1082600080E74A6EFEDD1B723C2DB77DB80ECF3322
+:108270007FC1E5E96C12C67BE13DC4C9F7D903F8BB
+:108280007C2E71F17A8B0C7EFDADC1C00D57D3DA17
+:108290006D6F04AE06B36DF6FEF09B20063C2DCE4E
+:1082A00029B887A0BDD7E67A8BD5D97BBDEB972CB3
+:1082B000B89EC87A2DB87E6D7D74A608FF5EF8F072
+:1082C000FB9A34788873E9BA29BDCC4AB8F14A726E
+:1082D00006BB7C966DF8176CD384CD271A3EA7A0F9
+:1082E00089DA8F5D03DC249BE2EF0F03DC0294D577
+:1082F00096708E3418F944867AADE81904A9CF5FD8
+:108300000DF40C4B053874249F93FC3C6065FC7F96
+:1083100000E819F2BC4EA7E0BAB47BE8F7DDDD69EE
+:1083200007BB73E9B68FF19EE51A31F4E84D180FDB
+:1083300015D16F3AD93AEC8CE7CF0E409C8AEABF50
+:1083400081D9DA394BB6CE3912E39339ADF1988F32
+:108350003F679168B8477ACE2296CF47A48EFCEB50
+:108360000DF6FAFDFD8E03F182E871E62D9A443E8A
+:108370001F0DFBB4CE09183F58C3E86BDE64B70885
+:10838000F9CEE39709B8DF3AEEB0DA16A2F57981B3
+:108390004417B0E7BCBBFF6308DC7350DBC1E2816C
+:1083A000E9E2ED05F7419C652FD3E350BF1DE8C41A
+:1083B000E6566DBAFD822EB9AE00EEFBF3DD6673B4
+:1083C00003FF975CEFFE14EFF3E5F10A4DAFBED665
+:1083D000588279B225B7AA6301FF252D5637961624
+:1083E00022C551395622110B94E90A91AC50C6119D
+:1083F0000B94454BD8BDDDA58D33D03E708C2D56EA
+:10840000E03EDE92F617BF81F7CBA4E01E763F0573
+:10841000834F49FBDBDF035E17B88B319FF1C20D41
+:108420008AC10F1CD962AC5FD466AC17048DF5D13C
+:10843000FB8DF5F5D904E968AEE5BA3C80D7DE5D81
+:1084400066AA8B20FFCF8CF92E8704861FDF462B70
+:10845000CAC34955ED45E0071F7FD96E023F7AE751
+:108460005F7F89FBE1E1CDF104F2ACF6FC3E8EC406
+:1084700041BEE22BD675D05E457107F1CBAA57AC51
+:108480006BC10F7FF502CD8F0FE4C37A5EFD1BCB6E
+:10849000AF096F3407607FFCF8F6175F86FDB4E321
+:1084A0001B07A07D7548F099E2E0FB5FB2F8678892
+:1084B000DF1717E2F7C5556D30FAC5776433391306
+:1084C0005A7271422CBB492B876724E74DA673EB88
+:1084D00079C83C07E240C31A8D70D1FA8D08189F05
+:1084E000DFC3C71F4F94089DE6429E40A0C101FA1A
+:1084F000F7F9D8F7242FE1FCF3D24BBDEF89FC9EAE
+:1085000038A2EACE4D45E437593800F23700FE83F1
+:1085100023CFAB886E3E3AFB642A1FFF6B0BCB6701
+:108520004EE1F7F71FABDF8F7ABFD7EEAB77BB27F4
+:10853000EBEAA58D7BD24AC07F6ADA93365707AF44
+:10854000EA8DFBD26EC1BC270922B8A47AD60B8F64
+:1085500041BCA27AA3D802F38476805B57CB9B0EF2
+:10856000E847EDE151100789D8A397BB27EBF8F84E
+:10857000EFA55B8DDFAAB9FDF2DAD88E2990A75E50
+:10858000D528B8A05B55CB0DD75D0DF06E62E75CCA
+:108590008B24522C52FEAADE72C35523216F66F53E
+:1085A0001817CC870E713D3CAFDA7402CF333C1CF8
+:1085B000F5BB075AB9239BD985B47FD044FB3F7CD8
+:1085C000A3AD1CE4171DF70DA8EF1DBE0EEF5771EC
+:1085D0001C65FB0FF4F927266AB71C9DE87BEF1694
+:1085E000FAEA71D2F2D1D510576A34D223A56F01BD
+:1085F000ECB2F07AC1B50E9F2E29BA164C6EF76216
+:10860000CCF7A5ED73629DB7AE0818C789C6FB47C6
+:108610007CBEF46FB89E7EA2FB254FF3613E79F5D8
+:10862000222A0F757182EAC37EBC5F32FA3B444F47
+:10863000D7CC9E202AC8C3CD2C6F86FE0996229ED9
+:10864000A73B84D5F15E45A0534A28551790C92A07
+:10865000C0FB5A3215CAF12057E03EFDB12DF9D0CA
+:108660007F87107AE1391CCF8E72BCCB19C47B2670
+:10867000B3F839D32E95D57B789C536BAF6CB7622A
+:108680009ECDF1AF1494B38B5BF6611E7DD7CB56B4
+:108690009389CA83E35B9227423E66570BBBA7F8D8
+:1086A000584BF244E50C7A3B5A6E68FAF420FC937E
+:1086B000EADD3F67BBBFCD063D753FCB574D4FAEA3
+:1086C0002B88F5FB17DA7B294A5D01F831E1DB6C79
+:1086D000AE7508275FAE8471F00C17E40995086C3D
+:1086E000DCB841C5E240DADF4EFB423C3A69BF8864
+:1086F000BFD7F0B9E8FA897308DE278F76D0FC423D
+:108700000FDE4F49EE677995F324129428BDCD030F
+:108710007D948F7594CBF39A04CC2B9BBFDCB81E51
+:10872000B82757AF472B4880DD6FA18F230E867C7B
+:1087300017AA6FE05E4B0BCBBFA86C36BE574582C5
+:10874000389FEA4D3F9863C1EB1BA2ADCB9D0DEB6B
+:1087500012AEB5E0BCEE7C2A81EDF728C40DFA34E8
+:10876000FC941DE57B15F1E0783773BDEEBDBBC40D
+:108770003D1FE4F0A279EEF9C970DE96E93F74F985
+:1087800090BFD9BD5B5593497020BB7783805EADA8
+:108790006A178223A16E213EC728F61CEE1F807542
+:1087A000EBCFD794133F7EAFBCC9F89C7CC8F05A7E
+:1087B000CDCF3192665DFB60B0CF183CAA37990DE2
+:1087C000719DF19B049F1DCFBB061AD2E8FC6A8FF6
+:1087D000525941204FF507B3617CC8E719837A9F4E
+:1087E0005829DE9EEA95EB8111B1F2FC0F70383EFC
+:1087F00075436926F0EBE360B76671408F45B9C5F4
+:10880000E3072468A1DF891BDD5BC7F6A225AC3E28
+:108810007DF50BD31B2FA17E9EECC17DA17962F16A
+:108820005B701EECC5419E6B013FF34CEE1C09F9D9
+:10883000D63D14E3A18B181C9E195537A22E861D18
+:10884000A8E1F969A12508FBB2BEEDCCFEB21786FE
+:1088500065BD7EAD1EC8E451C2DE109E9B086F133D
+:10886000F09CE52AE1209E475C75854AC0BFCFA0F9
+:10887000780279BC4A20F7C37D5C85AD336E7F13E7
+:10888000F05C18E7829FBBA8699D20D6D870FDCC0C
+:108890004E8BAF5B0BFB39E973868F023AA7EB9ED9
+:1088A000732D7D7EFB4015BF97696378CF58E2CB6F
+:1088B00085DF814AD85B7CFB9BC08723E3F09C6CFF
+:1088C0003A85953D09CB65607F6590C502F47BCA0A
+:1088D000C1C64F35897366407D14AB27DD2BB8D7F1
+:1088E00021F1ADC0F1D3CD642ACC139E831D6981E3
+:1088F000B802B607187E27D515C078E9435899A263
+:1089000004B3619C777AF1ED41BF6221D7630BB765
+:108910004C48073FEF9D2EEA7053B9F54E86660F1F
+:10892000056DF8FB50E70D67FDB95FB8B0809D3766
+:1089300048C931F6EB91DD09A3418E7EC0ECF853B6
+:108940003637C6A72F5662C7B39E1BC8EC16EF6911
+:108950008104747AC03BF35BB42BBDA725C3F3AE8F
+:108960007A8B21CFB9BA7C2F9EBBAF211D98875D32
+:10897000D3126FC8DBBD382EF67735FAF69E16890E
+:108980002FE67715E3F3D3C9C4971CAB5F9AF1398F
+:108990005D87A1DEF65DEF3AE039191B72803F3842
+:1089A0008DDBB53D01934FBE2882976E67C8A077D7
+:1089B000BA5556EFE1FB715ABB367EF74C859F2BBB
+:1089C00062F72A037C7CC30879B6FD04C6A3ABDB3F
+:1089D000F74C61BFEFC5E8420F279F4E7EA4357468
+:1089E000044D94B77F3BF0E86379232889EDD5F8EF
+:1089F000F8D8636ECAB769A2C9C0D7F185BD7C8EAD
+:108A0000E2E52993C8E5C2F1C7265FA2AFB3FE91A4
+:108A1000F7BBA64FA6B67D611E7BFF8F03BF7A6FA3
+:108A2000C97911B944D791536CD7D52D51751BAD68
+:108A30008FD4D59D51ED2951ED1951F56CD6BFCB91
+:108A40001ECC115D84740E3C315D1A07FBD8C1D970
+:108A500070A3C0F286AFA74FA6F59AC20ECC9FA90D
+:108A60006D175CB8ADAFE5C7BB989D657385F0F732
+:108A7000ECE20B3BDE023950DD2638054AEFB696B4
+:108A80002D9857530DEFA9BAF75A98DF59DD721098
+:108A9000DFEB77FCE126E4E787871FC27EDAFED1B1
+:108AA0004DA4F7F73A4E0F043CB674323D1CB57F27
+:108AB000D49DE9DE87F230EAFCAB17C6B545E85E27
+:108AC000EBFF8791EDBF8361E2179E582CD1FE7FAB
+:108AD000AAE91C03F612DC710972FF69213002F465
+:108AE000F3B3C43302F4D16D35E7EF31D17E07E43F
+:108AF000D06AB8AA61688EF51A89CAE903F6D0402F
+:108B000081CA92E16B92AF01781E480DE10D0D3FD5
+:108B10005B93C2DA078606C2BE6B5ECE8F59FDFC40
+:108B2000D06AA85FBFE602561F191A28D2F707FBC2
+:108B30002EBC06E0BFDE199B6F07E63079AECD6F25
+:108B400066813B2307ECCD6AA62FE0F8A585CAC550
+:108B5000D995C736AFA77098FDD3789457EBBBAEC5
+:108B6000BBB218D7EF2B863C3776C53BD767289723
+:108B700025B4033241872545F061CFE95051DE5FCE
+:108B800050B705F47EFAEC3C94F7A7B2DDF53963F3
+:108B900022E59F87B0B23E879DF748174D986F90AA
+:108BA0007E8F1DEDA0C7F97E12E51BC4AF8DE36378
+:108BB000540E937FA372989F9435F0F27A58CFCDDC
+:108BC000DC3E5DF95060A395C2FFF740242918DF11
+:108BD000467BF796B5546E24403E853B13E4C12D89
+:108BE00010FFCD8BD435FB7D6501ADDB227EDACA6B
+:108BF00019EE4C7D1ED0CAB5AC5D93372B73D9FBF3
+:108C00009ADE496F60F0497F7CC43A5847BC44F013
+:108C1000FCC5829943D72D46FD7D2DAE9BB8DD99CD
+:108C2000E07F1FAE186C02BB52C3CFA202F7345CC8
+:108C30008FC8F2D5353C69DFAFE7EB9E2752FD4F79
+:108C4000D7593FC883EBA7F6403E4B2E60F6403D18
+:108C500004625323F02552680C3CFF5F04A7DBA19C
+:108C6000FD1F85530C79F133E857B388CA0B934E37
+:108C70005E70F83D2D04E5F442DDFD25F439F88100
+:108C8000370DF43C90A3DBC7997D4F0DDA7FDABC3A
+:108C9000E2FFFDB5A93791BE7C166D9F1DF8BD653D
+:108CA00039C6019516948B07AE24AEC5203FF8BE99
+:108CB000AC665F16FDB4EA1DF0A34EE688F89E553B
+:108CC000C3AB50BCA594C2E921AA56E13CBA6F06D9
+:108CD000CBEFD1F4E64A7EEFEECABB2FC43CBF1EF9
+:108CE00012C2DF65F38D2528FF7ADB670DC5768A12
+:108CF0006F9F15F8BD220E7F77606501C173362B1B
+:108D0000675D80ED3BB5B8D22C0B7E67E50C464F16
+:108D10002B2B581E26E811805B7FF490D6C0E21BF7
+:108D20004472E7EBF301DEE5F88B2F0C6DFB18ECDA
+:108D3000CAE556B42B4177E2FE883F1DBF47F1BA22
+:108D40000DE599E6473D99C9EE9B252EF4CF1FB45A
+:108D5000BB4B505EDD17AFC2FC9BAC64996514B889
+:108D600023E47E947B7C3EC4FF0CE679CCE1F6DA0A
+:108D700067E527ED600FBCC1E50D100CF8CB73095A
+:108D80006B9F7B6FFC41F06FE6DECBEE9B25CB2E1D
+:108D9000771BF73BE85CD3203ECEFF1AC376808377
+:108DA00007DE73C0F8FF6987FB4C3CF7B2F3BDC424
+:108DB00047DFD7E5437F0CFC0B717691CD9FD4C77D
+:108DC000ABB1EE05FD98CB773A7FB7FE7BDA77A2A1
+:108DD000C7A5FEDD2740A714EE41380716BE4FE4B5
+:108DE000BFD76A9C6F8A127ED44ADB67D78B894BC8
+:108DF000283C3D8BECB85E6DBE73D2C397B2DF8565
+:108E0000358E7F24BEB608E2E19A3F42EE35FA6322
+:108E10001097E8AD8B98278D7E4D9FE7DC9F8DF6F0
+:108E20000309F99B59DFAFF79C862A44CD9FD39560
+:108E30002A4880370FCF5F5094F06CBC572A6ADE07
+:108E40001A3C9541260E774617D1F05606717A885E
+:108E500082778A121A08E37A1699114ED1E36BFAD7
+:108E6000F1192BF1811FD9280848AF8D77C7A3BE10
+:108E7000231686676F659C0AF4FBAC12C63C27DF9D
+:108E80000EF6FBA03DD6F0AB28B7CE63F1869EF779
+:108E9000C4B5D0AF3B95D17DF77699F31B61F74C04
+:108EA000BC27AEC376818DDBBD381EF3A7E07CA85E
+:108EB00002E7367D7FAE87F88BE6E77FFE2ABB6F41
+:108EC000017ED747EF27C3B9DAF25111F981F7C70D
+:108ED00000BFB7C5F33892A702BF774B1C813C8D0A
+:108EE0005A938079BFB59517E03913C2EF79AEE692
+:108EF00053AB35517F7154440ED49A0E0D057FABA0
+:108F0000DAB21CEF7FA6ED6F809F063FC3DBFB3B11
+:108F10001FB97DF150BBFCF85FF1DC7BAB913EAA41
+:108F2000237484E7E72AF574951BA117B4C7418E13
+:108F30004C26786EDFCEEBF1533B0210C7F1F2B84E
+:108F400046EA5E76AFADBDB085405CD57B94D92353
+:108F5000E3DBD7EE03FF38716A077864B43F8BCB4D
+:108F6000459F2F1AD7BE4204BF4FB363747EE78874
+:108F70006B47EA4B761E17FC58F85E081E01FF4847
+:108F80004CFF3DCDF51FD59328AF17F887A19E0460
+:108F90003D06724EF38341EE819C7971D0C45B072C
+:108FA000A5C27D86136F1AC4F66946A0DDEF3BB7F4
+:108FB000FD28AD1FF8C3678E9731B8855725303926
+:108FC000023F100A71E4DFC86B1FC6F949ECBEC648
+:108FD000D5B92897B5384E358F6395F2B84F298F9C
+:108FE000FB40DC559F170B714D7DBD9ACB851AF860
+:108FF000BD29BC4FC01CC98B8578CF6412B4433BDC
+:10900000C47D1CECFC9DFE7D2F094C9290CE7F30E0
+:109010001BEECD5AC9D63B87E37D9595C57BC6DF50
+:10902000BB5664412CB6DE8451EEDC070A23F77789
+:109030007DC1F1A4C1256ED0C412807B9CC8EE3FD7
+:109040000F3FC07E0FFB30D5DF5B783CE45A1B9EA0
+:109050003F769F07790B9233E7DA18BFEBFAF00EF1
+:109060002BDEE3EFE7F2487B3E6510CBF7C5381106
+:10907000C07D713CDAE114CCF940474583357D4A27
+:10908000F2213E7590E77FD6DE68F3C078211E3767
+:109090005F3D88E98DD583D8EF3F68F55EBF8FD3FC
+:1090A0008BB6CF05F11A7D7CBBB9B73F8BAF68FAA1
+:1090B000F7E98AB8B5ECBE778D6E4D78BE323EAF1B
+:1090C000588138D30E2E474AB83FBF033670419EB1
+:1090D000B4F0B8B4E49C0DBF1BB4E3681EE653A61D
+:1090E000284CBEECB8398E407EDFFE632F3DF21E69
+:1090F0006D3F7954C1FBF2E6F378EC0EB8171EE42D
+:10910000E53633C619AB15664F56EF1EC9EC18C5C8
+:10911000B30AF2BE7D5B658C7B553B021B5FC0F6DC
+:109120004C17C52C9C176576F0F678F67E5CE01738
+:109130002F835FBA3BDDE5A3FD176578F6021F6557
+:1091400099D504A2EDBB0A91F3A48702CC6E3E042C
+:109150008207BED36EE7BF33E0CE5C40C7F9FCA107
+:10916000745C0F95B7685F7DFE9819F7D59EEEFD8C
+:109170002E8B8F1E928BF13E9943DB0A5CD4F32435
+:109180003DC54A10E2DFDEC799BD37CFA4AE01F876
+:1091900090DDF12E83BFFA5819BB5FA2F2DEE967BA
+:1091A000DAE706F9AE8FFF7693700EFAABE5835BD4
+:1091B00020DFB4BB7D848B6D6765E0264A2DDF7FA1
+:1091C0003E2C33F88677C948CFE73A3ED045EFEFDB
+:1091D000E089047FDF4DBFDF16BD4FD1B7CEF0E889
+:1091E000DD91CEED3A63FB75D99E53C06FB54F7CD0
+:1091F0007760910ADF0BA33C247E166F3F2CBB6780
+:1092000003DD264E0E1AF2B86C2AF70FCCDCFE23D3
+:109210004145CF875A7BD14412735FE7FF002E3F51
+:10922000E0290080000000001F8B08000000000003
+:10923000000BC57D0B7854D5B5F03E73CEBC92992A
+:1092400064663209931739790792C01043448B3A08
+:10925000090103469D002A5A8BC31B943C046D638D
+:109260004B9B814408881A2E01010127084AAFD878
+:10927000062F20D64807448AADDE3F3EDA8B7A2F90
+:109280005F508A6805225A7EDAABF55F6BED7D92FE
+:10929000394322D8DBDB3F7CB0D967BFD65E6BEDAC
+:1092A000B5D65E7BED9D5855622C91317B37F385A9
+:1092B0008A18FB067F6EE84F635503953336C5CC9D
+:1092C0009218BB96F19F8CD350DFC6984D55191B51
+:1092D0000DDF4F874DB3209FB1246C9A2BD200A491
+:1092E000278D2C6C298574A33DB42D135BFA18F6D9
+:1092F00033770CFC179ACE95598BA504BFABFB7B3B
+:10930000DC8C9DDAEBF4AE82EFECAB6F6456C6D822
+:109310000C26EA9959ABC5C5D88B2D52D802F566F3
+:109320006C306FB3427F65CB7CB21DF2BD5B24EF26
+:1093300036A837A3A53C6F23E4EFDD53EC95A16974
+:109340001C8E83F990332443FD6B1BC7B18FAE6233
+:109350006C96396452E03B7B4E623B18F5DF82FD30
+:109360002F8446C92597E261DE063363163EF76F08
+:10937000F09F50443E0BFAEDEC9019CC97ED84EF42
+:1093800005FDDF172AE183521C63B59D51EDD9DF3E
+:10939000CC7DF5105016243CBB4DEC1EBF8D263DF8
+:1093A000A4A698B13FE27F93198BC9F05FAD121D5F
+:1093B00072864CB6C3BC2BF8BC7A774B84D75AD68E
+:1093C0006062D84F7B0263D7448C6B61E158484F91
+:1093D000C9412A9F6B5E4369B59A4974BB97F5985A
+:1093E0005836F6DB6BF2170FCE07D597E1839B0556
+:1093F0001F2C3CCDC2D7C1780B97B070ED089EDA18
+:10940000219DABB0601CE0752EE0205EA431251CD0
+:10941000AF6A413F5E1684F479C4A71A8167C463BA
+:109420006479FDFE6FCC91F92126C6ACAE7E3A037D
+:10943000A108AE21E31A4635009CD72E09C90CE6D7
+:109440009792EEBB3107BEC796F2F9D61FB358D438
+:109450009198F7B32CA8F7655AF90BB930DF7A85E4
+:10946000F93AA13C16F0D201DFB7585910FB7F2A18
+:1094700097CFD763E2FC6B54FC6C940DE9D21D3698
+:10948000205D129903F951C3E7163BB42BC1761244
+:10949000B5EB6B6F612D3111ED2B7E65650CD6CB75
+:1094A0008597EC213354654A20C309FD257D60660C
+:1094B000AB207FF657F6F9D8DF59239BD609F5DDA7
+:1094C000326BE8247E594EF4F919D23511B9A9222C
+:1094D0009521EF4B93529907CB97D178B54EE0AFDA
+:1094E00001E8DB579ED97D3BE72BB3BA0DC6BBE045
+:1094F000ECF921E6011E1684FC0F91CE88973DE31E
+:1095000046FD04BED7FB6D5E8EFDC028E457B3FC5C
+:10951000C0ED16E0AF09F292DE87601EB5E936872E
+:10952000199A5466FCE71FEE84FC277B8CCC8C7464
+:10953000DE316E1ACBBA140E2D5D10327ED813B107
+:109540005EEEDBA9CFD776EAF3F54CF9B047E3033B
+:1095500040C116D5EE3E5548B2C3FB0DF0B7D9DC7D
+:1095600070BA03E035BF6CF62E85CF8BD4C0365C65
+:109570004F7586DE23886773C667230280978A8CBF
+:10958000AF8EA422FE7FCABC08F7056BF90CA2C7F8
+:1095900046AB1A8C905FF582FFDB87565379FB262A
+:1095A000B32AF1F2EAD120B7E6D312A62A1603E0D5
+:1095B000BF7EC3C44FA411546E417AB4039F52BB03
+:1095C00017A4D05268377FC3BC6A06E56758C864E1
+:1095D00001783ED1F02C774DB0C07FDB5D55C35094
+:1095E000BE285F2B7EA4FF0AECEA9A7E7CFDBA6F50
+:1095F0007D5ADA4E025E6E62128BC7793B03BFC69C
+:1096000079D65A7A4CE5D0CF0D5F7F4972795EE307
+:10961000ABD927AF4279E39B41F486F9A11C99F7B6
+:10962000D041FA2E4DB6107CA7D26D21337C7F75C8
+:10963000A399E79D26CA9FDA22517E5EA714B264E1
+:1096400062FD8B09E528BFB7181D6676299EA2F139
+:10965000F2F1E6FF886300F2C78C55E1FA628E866C
+:1096600038BF1DCB1AE2261723BE6EFC04E5D7BC1B
+:109670002DB2378C72FA15BB3797617EFCB0393644
+:109680006CFF454239E26FEB78874CDF653FCA21BA
+:10969000A6F8BA6F80EFCAD6AB555C2F87B770B803
+:1096A000E7392DCF209D6FF85A26FE570C2CB0DBE2
+:1096B0008674F00DC375A76EDE3101F1FB714D8A22
+:1096C00081EA3F2F3107E2C3D99884DFE7498A1F37
+:1096D000D7D9FC0D0BAA595C3FDE57A932AD9BF2DE
+:1096E0008C25493D36E2FBDB51DFD56E013EC7F1EB
+:1096F00027BFFF873BDDFD7C2F4DDE70CBB5D8FF4C
+:10970000B346E22FAD9FFACD370BFE602C0C789A52
+:1097100027F064CE589287E35F6E3DCC5BD690E72E
+:10972000B05D7E5DF4ADF7CD7C7D489912C955964C
+:10973000E6223D33D87AD4F493ADC040F2DEE26540
+:10974000BE1D900E31339F04F22B2F53213CE46554
+:109750009AA89EF297453BDF04F8F7A981F84CF8E8
+:109760009EC17CA350CFA8BD8E8A78E8CD860C52CE
+:109770008A7098433B48CE411EF0B43E913DB32AD7
+:1097800002CE2CEC6F34AD574F26F47BF6BDAF8E76
+:10979000201EEB867E3602F576FDC52F4D2AD0D3EE
+:1097A000D625919CB579FD0CF9A3BEAB86CD2EEAEA
+:1097B000978FF55E2EBFA3E7559B69E4EBCCDD4B9D
+:1097C000FDDC9CC5D75DBB93AFCF4D8D3121947B24
+:1097D0009BDC212B021D5B1A6428DF6F2995BD08D5
+:1097E000B666A7F82D9C5E16DFAB4C467EF5CA5ECA
+:1097F00014F1DDBE8F5A1220FF66E978AF0C799B19
+:10980000EFE9D62C9CB7D728CAB38338EF37C69672
+:1098100093BD728B4FA671D9FCB810AA8A6EDF3B3C
+:10982000EED930EEADCCB7F624D0B10A9437D2B130
+:109830001BC7067A9D7104C6225EB4F9DCEC9DB8A4
+:10984000F664A49DE1E3F6007CE27AAC74603C949B
+:10985000A8E51548A71BAEE774F8F4797368198C6E
+:10986000FFA915F44C84BEF8D4CEF5CED44CAEC7C7
+:1098700018EB1C8A72BF2FAF0C33E0BA7FC0C1F166
+:10988000E136750EC5F5F62749DFCFBDAD320B8148
+:109890009C59D02AB11080F8E9CF5F1C8AF2F79367
+:1098A0001D2F0E9D19015F743B2D9DAE8DD7F68443
+:1098B000CF02E3CD64DA78E1341C6FA6D77C02E5F1
+:1098C000076B1DEFEB89B01F484246D4671B7C2411
+:1098D000BFCFC16A44BED3DA9D9B1FE3433BF31C59
+:1098E000B38424186A66971C36637F3E5F8E1BE83C
+:1098F0005DA7B58FEA7F03F20FC025ED97C276A86A
+:109900001F5BD44BF27681C57F24158A16201DA1DA
+:10991000FE44A4A384FCEA33E1BC1589CBF3330EE7
+:10992000FF834887396D7A3A66663AB87C77B8899A
+:10993000EEA63A9B82FA22A999713BF0414308F5C1
+:10994000B53B266E04033BC694E2B1A19CBA212F1D
+:10995000A6C5108FDF8786B07E7A4A01B50B567098
+:10996000FE0E26B150B3845D364864073A7A9802F9
+:10997000DFD3C630C72A944599DC4EF430EF069900
+:10998000ECC44E09ED440D0F9A7C47BE41B9F7A9CE
+:109990006421BE91BA24B2FB6443E774EC77303E95
+:1099A000DA12C5475BFEC97CF4ECA07C1450898FA9
+:1099B0003C9681F908F64DDFA93E0BFA15C0D71089
+:1099C00081AFC7857CE97DD04274831F09E75B2D99
+:1099D000FAABB6D8C2F20892139FF5C96FE86733A5
+:1099E000D89FB84F4946FB19D2D4E6192AB7DFBB36
+:1099F0007B24E82FF66A0BE9BD470CDD9968E70F79
+:109A000019DEB01BF963C8F4A29266B24FD29C284B
+:109A1000F751D6E0FCEB1AC7F9B91D00FD221FD59E
+:109A200098683F51F750B99FDB0155B43EEA575B48
+:109A300055D467E3BA3297227FD42F01FB08E5EFB4
+:109A4000FE8E8D73215F37D5E6453BC56A995284FA
+:109A5000ED58AB7E9DAD943AC92E0E4E645E94DBFC
+:109A6000E74286A07124CAD99EAD3F413DBEA0C841
+:109A70001B5471BD09BECC61A417DA9DBE6417E00A
+:109A800075DFDF64DA17B58F823CA42F0B7AB6D767
+:109A9000F8929D909FB9DA4A786FEFE0E5E7EC80A5
+:109AA00020E83F45E6FDB1780BD73397CA030BE2B8
+:109AB0003D690CD37E36603E45CBB73D41768CB6D2
+:109AC000DEDB33393CF6227F265ABE017574770CF3
+:109AD000F04F926CD0364541B4BB63714C9EF7E1B8
+:109AE00070EB0C00480A66BF5E53393632CFEBF795
+:109AF000B77F6472651AE9D7BE72041BF4AE96F79D
+:109B000059018E15F6FE7205EC49CB7E49B4BF763D
+:109B1000F2F81C98BF24C60F9AD6F800DEC7AD4CE9
+:109B2000375E247C4A54FF4615F7F5A27E70A47F69
+:109B30003C545857A2B56F6EF301FC8F1BF5FD1115
+:109B40004A457BCC68E3FD2EE7776B568FEDD7FF58
+:109B5000600F38B346F7DB012BDEAF6E1B0963C520
+:109B60003ABE30A17ED5F479BD5B223B237ABDA6F7
+:109B700066717F05D8B5A95911F66E35DABB32D9B1
+:109B8000B9137069D52FF133B42FC16EC8C0F1CEAF
+:109B9000BEF7D9A983F0BD7DF2A764E7D75F54C8AB
+:109BA000FEA807FB03ED764B17B767D97E23E95D67
+:109BB0008DEEF70AF9D3EE04BD8F7CFA8A341AF9D8
+:109BC00094B186A1B7010D9AB37CC3100E6D3F16F8
+:109BD0000D6F4516B7CBEB0B2A36E661FFDB25860A
+:109BE0007A7F55C18749689FD4779D489A13D16E73
+:109BF000C1FE758487053B8D03CEBF228BDB9B7531
+:109C00002FEDF5E17AFF3424D15A9EAF8456A25D40
+:109C1000397FBE012D35561A9A7127AE7B36CDC4D9
+:109C200072617E05C2AEA9DF3925782DEEDBE0AF8B
+:109C3000049F36F9E7D2FADE34CD62639908E7CCA7
+:109C4000FB090F8E181FE261554145328E53573381
+:109C5000C181FE937AB0B3B0BCEEA1BBC89FD267FE
+:109C600007EF3756A1FD5506F6D6BF01DCE9AE4930
+:109C7000555E588FA9F2EE518B21BF7E10F9FB5E25
+:109C800036A7678BE40FDE8AEBFE2589ED50FBCB10
+:109C900033F673BBEEAE2C6E076ADFEFCA52A8DD57
+:109CA000D860F738E4BD034A4F2CDABFF5CCF7395A
+:109CB000EE3B99DFA6EE203A71B9E36E52C9AF646C
+:109CC00071F73C3212CBC72AB49F604ACF5A1CF7B7
+:109CD000EC4AB7771513FC8BF9878A4228478F66C1
+:109CE00005E621FF94093BF2EC4B378E9A59D46F6D
+:109CF00027ADECB08696011E56DAD57FA942F9F65B
+:109D00001785E41BB3F4768F437AFCD545FDAEB4DA
+:109D1000865622FD836B8C54BE3B25B008F9E67451
+:109D20004D551EEE83992D985703FC6474B731B4DA
+:109D30001760FB407E068BDBCF54C88F0BCE5024C0
+:109D400094F351F6C738F4F3D0BE010687EF1542FD
+:109D50006CE502179CB2D01268F926A1DF1E39FA11
+:109D6000D554053F6A768AC11258804D2BA7C5305D
+:109D700019F97E79EF1103CC27D6DD4D766C6DA7EE
+:109D800044E3D416BC6042BFC97D9D7C5DD68B7D0B
+:109D900000E06F28DA038F64C58AFD670BF55BCF9F
+:109DA000BA691FCD76717A3206F5EC91FB89A5541C
+:109DB0004FEBCFB48CFBBD6A853F067AA4F2F56207
+:109DC000BD6BFE095898C23EE0E3AE97BA7D32E221
+:109DD0007594E48DE41B2D7D3E8BEBF7F843BD13AA
+:109DE00070FDF6027FA15F66A35473FF6B30BF8DD9
+:109DF000A3877BD184F2003BC925F81D5811F05E82
+:109E0000BAFFF309C8376070D37AADDB5F2ED7DABB
+:109E1000486FD3FE71486C4307960FB9A780F46A68
+:109E2000CC55EC9EC9F0FD05B1CE926DDCCFE55965
+:109E300016CC5C5484E3FBEF7F0DC72F8E213FE5EA
+:109E400010A08DDD45692BFA853C6CA984F5D6C53B
+:109E5000F1FE130DF23D3545247729EFF24ABE6D30
+:109E600090766539A97FD87755219CF89DF663C017
+:109E700019B89F453F17F633249BA76793C30A0A77
+:109E8000884DAC67EB0EE4CFFD6607E2A97AFF6F61
+:109E90008EA1BEACB6B04E19ED95283B6349FA943D
+:109EA000D7903FCF9D39B5F561F8B6EEB67DDE00AF
+:109EB000D1456F3F44EF17B66195E4C1EDBD0FFA90
+:109EC000E8C9EDBDBEFC3FDCDEE3767D7047ACBA91
+:109ED00023429ED78B7DDAB9F9E7E350CF7CDC07CC
+:109EE0000FE8E9B27E7B65E6F6D813B8AEFAECFE71
+:109EF00028BBE1E833B141A4FFF94E2BF9E914B4D2
+:109F00007B009E33F6DE1F2272DC26BF4FC2FDC3EC
+:109F10006EA37719F4577FEFA7BF30C0BA533AC08A
+:109F2000EE89477B5F8D2739FBBACC76A05DA6F81A
+:109F30001CE8F7D0E0579C133CA8B75BC4FC179A09
+:109F4000C279640799D87CCAC785F3D0EE7959E8FD
+:109F50009D85319087EF8D9EC0D748B714339757B2
+:109F6000D80EBF77087BAB0350E240BC1C837D77E3
+:109F7000A6D0DFB8FF79343DB48AFC3816A2E74793
+:109F800007CCDBD0CFF35181216CE27E09F263A9CB
+:109F9000AD0A4B86FAEA316B48E5FE2E8B01F4FFE1
+:109FA000ACC7EF7B03F715B30E703FD6AC7B97DCE5
+:109FB00082FB8F8F264F30A1BC99C302E4779EC7E6
+:109FC000B81F7A010B717F35731870BCFB406C6C45
+:109FD00042511304EC5F0D9F2583847685DA027964
+:109FE000329A7D6D5530EECC1603ED4B66B5EAFD29
+:109FF000E91756DD5F857A7C458B81DB8FAD12E9F1
+:10A00000F159CCE741BB43C36B617602C983608BD6
+:10A01000C187E38CCBE67A054814A2F989B4C52838
+:10A02000FCF0028EA5CC10C6D420F1748543A91A89
+:10A03000483F6BFDB5181B2CE80FEB4D37901FF810
+:10A0400082C9378DFCA8AE3C867EC4167B436B1557
+:10A050002FA73573C1DAEBA7F2EB146EF031D5857B
+:10A06000F23233DB40FD45CF774E9B3E1F7D3EB144
+:10A0700020A4CFCF6281FCE46CF41BE9BF67667358
+:10A080003D706155A63807F0D239408B517D3B13A6
+:10A09000E5D54A85E4E5D2348E2F433A4FB39C95FB
+:10A0A000D3887F9D605F10BC1CFEACEBDC12EACD58
+:10A0B0001627E7CBFF29DCD1F0DE949DC7F18B4654
+:10A0C0001E8CD7B2520A717C71B8AFD47FB1305BAD
+:10A0D000BFEFECCBFFE3F79D9C1F57CA62BD394829
+:10A0E0000ECD74F0397D24799F09E3771BD80700E2
+:10A0F000F7AC957209DA29E3A6D8681E7507ACE4B7
+:10A100006FAD5DD23314D7515D454F5EC3007845C6
+:10A1100068154D7E41BD996ED827E0BA6DD59F5325
+:10A1200081A66591E74E53D27C4BB313713FF2D1B8
+:10A13000EEDF20BD775B493FC1FF0E9A517EBD9493
+:10A140004976535E5A606536EAF598F0D66733D1A2
+:10A150004EE176526D97B903EDC0992D11E75EF887
+:10A16000CF6AFD39186B75917F83B5EBBFCFDF1CCC
+:10A17000D5EE927331AEEFD79B02C3D0BEBBE17A6E
+:10A180005F32CAD5330B0C0CE93B4BF6CE45397226
+:10A19000C6AAB7BFCFD839BD76666BF2DD9B877490
+:10A1A000EECB5F42676F1ED27996810522FBA945EF
+:10A1B0003A037D170A3A9FD97B751ED2F9B3DD5752
+:10A1C000E7219DD71BDB7CB86E9ECD08EC423C9E00
+:10A1D0001CEF27FB09E455DE77E1C70351FC78E06B
+:10A1E0007F8F1FA9DD60FAF0B77D70E8F5A1DBA4D1
+:10A1F000A6A13C9C69317FAB5EC49F01FD6B163309
+:10A20000F9250E7CF5C563CFA01DD225931DA2F5BF
+:10A2100077400964A35FE1C0318F37280DDEFF83EB
+:10A22000C26EF5585810FD1F9ADDAFD98FD1F2F8E4
+:10A23000B898CFD96C5F0DED1785BF76BEE8D31205
+:10A24000FA82DBA9DB25F2C75AD44E1FDABD75AFFF
+:10A25000CC70A0BFF67488FB67EBF68E22FFED8210
+:10A26000D0ABE154B40BBB2407EE1F166C3F118733
+:10A27000E7DDB01F3D934D78E3FBD1F1623F7A3AC1
+:10A28000F4511C9E8BC3F837E33E22D6DD6B42FEB1
+:10A29000AD837D1A5461754AEF11ECAFCECDBC4150
+:10A2A0001415FBF5FB36EDFC7293DF44F26E539709
+:10A2B00014C27D5A9229909986FA89A5394EC5F61D
+:10A2C000AF97FFCEF6A5E0B966FFB9B1EF6B84CBCF
+:10A2D0008DE74DD0BE67633CF1618F91F9C80ED810
+:10A2E000681772492139F5E7CD4EDAF7D00FD4FF60
+:10A2F000732893F29ABE9EABB0B002789F3BD5F71D
+:10A300001ED20DE577384A7E47E6FBCEA35937D7F4
+:10A310002F20CFC3039D8F8B736A3CDF8D6C5FC78B
+:10A320007AA91D9EF3EAFAD5F601AC61940A70DFB2
+:10A3300077B7CD8BF64B3DF07563493F1F2E145315
+:10A34000D1F8B04EF879EBE77F48FB81FAFD920334
+:10A35000FDBB0BBD9C0F17C23EC93CE2D275CB3A88
+:10A36000810F23E01E6C1D5F9DA35FC77DF97F9267
+:10A370003FB322476FCF6AF3D7FCE27DF3EC92F84C
+:10A38000FA8A9A57F4FE32DA9FADED0FAF54AEDD84
+:10A39000D9070FC7475FFE9F2CD7E644E165B0F3AE
+:10A3A00082EF2CD7A2CF0D72B81F1CCF0DF05CF737
+:10A3B0007F7A6EF089DA9664203DE8D39DA7A29D4E
+:10A3C0008EE3B46E91C93E9820F373E85ABB99FCB2
+:10A3D000B4D1E7ADF5EA0471BED8FD876B507FEECE
+:10A3E0003132D4EBF36DF3E83CB35EDE6572A80363
+:10A3F0009C332A07C97EFFAEE7EF8FE6F49DBF6767
+:10A40000E2F97B59855E3EBF6AFB22211041E78A53
+:10A410002230FC07E0678B1264AE88EF4FE6707B5A
+:10A42000F8551127E331B1568CBF78DC1EEBC37DA4
+:10A4300087C7C0E3789AB3FC5B500E5A548EC7A707
+:10A440005EBA8319607E4F193B495E046B6D5E9462
+:10A450007B9A9F45EBDF2EFC0557CADF7BA3D6FB1B
+:10A46000DE7FF27AFFB536DE773D07DB00B8D1AD8F
+:10A470000346E75D6FE0F94DE6A5FC3A583F83F1EE
+:10A48000EDDB39FE377368BDF946D0B9FE15CA95C4
+:10A49000D8D2DE8FD09FC3F69855DC57A05F83F4E7
+:10A4A000E1EA64AEA7146F19E219ECB9328C833A71
+:10A4B0008EFFBD6670FBEF74DFBAE7F6DFE941E5BA
+:10A4C000CFDF67FF3565F83FC5799E2CF7E5A17EA4
+:10A4D0005C6107F8715FF7731E3FB3D9CAF973B3B4
+:10A4E000C4F992352668FE119A57F0797EFE1DCD8B
+:10A4F000572C57CF577DF97FB2DCB4F5C1F1BF2C93
+:10A5000037E7FF350EFD9C83F71324BA9555741376
+:10A51000DE7A5F91D8B608FF737D378F434B17F013
+:10A520006ADFFF2AECBFB9B9BEA118CFF5D97B16F7
+:10A530000B8B075307790CED2EBF8DFCFF759D3CEF
+:10A540004EA46E09A3F3DE3AF46F16A1DFAF86A125
+:10A550007DB74F0D1460FB15EFDB82723CFAC52707
+:10A5600033B2EBDEE3F9456AA088E2C596F4E8CEA3
+:10A5700019CABEF96239FA2D005EF203B8D12F1361
+:10A5800041A769B9FC7C404B6F8B821FFDF4C4FF6F
+:10A590009D7208EDC158B59BFCFE757BB89156269F
+:10A5A000FBC83FCFEE7331E4A3BA3DE5A35EA3FA47
+:10A5B000D65168CF967D50ED403FC467D7B929BECC
+:10A5C00060A8DCB300EDA9A359817108AFBD343494
+:10A5D00011EDD10CB047D1BEFD6CF7C45108B726C0
+:10A5E000FFD6A37F1BFA5D6FD7FBAF99C597F930F4
+:10A5F000FAB7B70DA1FDE1EE94C0CDB9B84FB37273
+:10A6000078836BAC7CBD0ABF76F4FAD7D6FD10D93F
+:10A6100040E30CF9BE85CEA135B9B0DEC80296EC98
+:10A620007E7972958897037CF078BDAE1A1EE7217B
+:10A63000F236B73E6EF16CF6F8AB707E57E5F2B8C5
+:10A640009439965E09FDEC73C4F9FB8D228E428B22
+:10A65000A33AE3F0CFC6FA6C4955FFB97B16B6773B
+:10A6600070FE17F131B117B99D9CE53011DFD85B51
+:10A67000193F3702BE41FA8CEDED1E170FF3C96981
+:10A680000F8F457C1EB868207C28356FD079493CF7
+:10A69000920DFAC95EDDB3321FFD258E77AF43BA46
+:10A6A000A86D8E0A44DD3ED5FF00C1A13414E0FE42
+:10A6B000B1E2F7461E0FF84A2CE9F9F6A10B291E64
+:10A6C000F0ECFBC0AF9997EA032D0DB26514FF972C
+:10A6D000B5FF1DF2DBDBF74803C6753E9E6BE3E773
+:10A6E00049C16E8A336363DD840FE5950F82685F2D
+:10A6F000282B15F254B4187D062BD27529233F7BE5
+:10A700006EBBC38074C9107125E70EFCF78800ED9D
+:10A7100047343F7D8852C5D8B31CF757CAD29EEB49
+:10A720006105B3DA3D4E431DFA358DBD75E41779E9
+:10A730002596FC9F19FBB3977D0FF219AD0E26A14C
+:10A74000FCF9D57D19C8D7419867EE00F36CCCE5CC
+:10A75000713BCA2BB106D45BCA1A4671888A33A9E9
+:10A7600082E05E0779E86791E01BEDFC11C0F5A07F
+:10A770003E9A9B1BD88E788E15728035C690BFD0BE
+:10A78000AE70BF86BDF1FDE797427EABF0B71E3AD3
+:10A79000503899FC732B1509E970C13923C301DFC7
+:10A7A0007F99CBED11BBD2CD1CB648FC1FA2B8CB14
+:10A7B000AC57785C9A62E47CA2AC7477A0FFEFCBD4
+:10A7C000B400C5975ED71296E9FCCA71726D951AEE
+:10A7D000B17FD9C0F548DD4EBE6F8EDEAF5C4E7FD7
+:10A7E0001CCDD5DBDD7DF97F925DF24EDFF87FE792
+:10A7F0003E84E9F76FD1F649F47EED12FB3AAABF29
+:10A80000C1EC142D8EA3A27F1CE28757ED9A1D1474
+:10A81000D4C5B954D8F8B8CCA2EFFFF94C2E27B460
+:10A82000B897A4667529C697F7FE94913F4D8BCBD8
+:10A83000D1E27082157C9F103480DCCBC4F39F364C
+:10A840008ABF49656149227BBF8761FB2118870365
+:10A85000ED7B72B3A8FF2DCCDB2A935C542584DFFB
+:10A860008AF11B09087768E35C1CEF361B8D67C50E
+:10A87000F88D04DA27D03A4EF1F3B8CD71F379BCF4
+:10A88000670AE85FCCA7E470BEB44E33511CA7162C
+:10A8900097A1C56F6878A910F84EC99F9B89FB01E5
+:10A8A0002DCE637D4CE8E75619E33B84DC5F6020E6
+:10A8B000B9AFC5CFB5E7AA21E4F77318E769BBF2D2
+:10A8C000788E68FC6A711D37A40792F346535C07C3
+:10A8D000E9512D1E43E397083A06AD30FEA657B85E
+:10A8E000FD5E31DF44F09F5B3089FC87E716181866
+:10A8F000AEA38A2E33E7BFA8F1364D33B130F6ABA5
+:10A9000084AC283F353EB89CFD0A742D40FFECA175
+:10A91000A69DD92761CD1F6EEAA4F49C55EA944701
+:10A9200062DA3B1D25D58867874E51AEC13895DE6A
+:10A93000A112B04EC9CE9CA9944FEC3D8EF949F9B5
+:10A94000374F55404F9CCBEDDD2A619C49FE89294C
+:10A9500094479E4C616CCC33BF9F12A479737FD314
+:10A9600038E16F323B03D7E525E27D809EE5DDE4EB
+:10A97000D7E171FD18F787F4F0D84C64DF7844BC58
+:10A9800025AB14F19778F202F9E6E451745E6D6339
+:10A99000EA9E6E2C4F33737DCF383F37E7727F309E
+:10A9A000A948949D699AFFA82788F2AA39D349ED4E
+:10A9B000FBE4EA1E7388FBB1F8F86FED2DA6732651
+:10A9C0002D8E943147FAD4628A37D1E51FB7F273DE
+:10A9D0004FA638D2D17E68360A3B55E463D202775F
+:10A9E000E545D8496F8DFF5111AE8733FB7E9283C9
+:10A9F00072EA4613D8F103C8A5D4022E97CE196D7A
+:10AA0000AD12D86D6FA4066621BE8EC54E9FE08440
+:10AA1000794D4B28373911DEE0CF6594938982DE7A
+:10AA2000CEA91C3E67A55F9A03FD365B613D43FBE3
+:10AA3000C480E2237B3D3055BA0DE06E9684FDCE96
+:10AA4000D478B2DB0BD4783CD75BD8F80EC555CBA5
+:10AA5000420EC8420EBCDDD493A3E482CAED5C234F
+:10AA6000A3BDFD8E385F7E2793DD5333803F737D1A
+:10AA70001EB70F27CB6A31F291FBE1B1EF54035FB0
+:10AA8000C8266F88E8976E5791DF0FDACB3C3DD030
+:10AA90008F94F1D3528C4B6E4EFF6929C695C82E08
+:10AAA000AFC71F915F9FC7F9B812EB21DE621B4A47
+:10AAB000518FFDC3FA8B87FE8AFEFEFEFAFA3173D0
+:10AAC000B8165A7A872AB03EBD9EC026A4DB8519E7
+:10AAD00027E8BCF587296F1DC7F888B78C6DE3E2BE
+:10AAE000500E654A826FB9BD76245FF36BF2B8F6FB
+:10AAF0002385DCAF097288C74F16F37B34D5531911
+:10AB0000ADE76A115731C1C1EF254D28CDF436C3E9
+:10AB1000D46E61BD0ACAE909C7FC71483F36355099
+:10AB2000EA2F1EDC0E631EA31A295726AA1179F8F4
+:10AB30007B53813E7FB3579FBF75CCD7F991F935D1
+:10AB40001EDF8B38EF97251EA719BC8639689E6ECD
+:10AB50002988F652E18B291DC27F4BF184FF2AF62A
+:10AB6000732F8E61549EB4D3B20DEF17687E705967
+:10AB700094177A9825C345F8203DDB2B89B84437D4
+:10AB80009DF5B07DF73B38FEA0AE09FAD93743A555
+:10AB9000759C6433B0EB71AD975AC87ED2D645B37D
+:10ABA00015F81BF058966A89417E6F367A37605FD8
+:10ABB000728C5945BD5A1E67A1BEE59F29A4979680
+:10ABC0005ACD14DA7AE8D118CA9729CC8FF1180037
+:10ABD000E2544CDF327A430D385FA887F36D76324A
+:10ABE0009257729989F434F44B743DB4C6106234B0
+:10ABF000FF7285E22D05CCDABA8391E8FB13625D22
+:10AC0000CB06162639966221397618FAC77E0FBD13
+:10AC10002E77901FAD40BD1BCBCF5BF2E9FE4D7D83
+:10AC2000DFBD22C580C015083BCAD9C5EF7F69EBDF
+:10AC300059932FD1EB19A4608E3B89711055FC07F5
+:10AC4000A691847A9F913DAF9D0FA65BB472C58794
+:10AC5000E324F7D5E7F7AF92443E353F93D61B5434
+:10AC6000091B4AD0FEF8CD5F906F35F9B075C5CF9E
+:10AC7000483E5C8AFF8207293FC9EEE0F8CF4FC308
+:10AC80007528C7E4A7A1BE6B767A557F44BE0096AF
+:10AC9000D13417E207EA417E4AD5891C25C2FF97C5
+:10ACA0009AAF92B0847ABE0480E390554DC3F53AD2
+:10ACB000C0B8B57CDCD87FECB81E1817EA1DB2C34B
+:10ACC000B8506FBBD51C36C40D34FE1815C7BBDC9D
+:10ACD000B8804E42EA248167E08B20FAA50ED90D98
+:10ACE000C49F93447CEEA1443E1E2BD0C7CFE4C446
+:10ACF000C0F8E46FD5C7CBDC286D6E41BDFC843550
+:10AD00006E1BF2E36F049F1C89FD590EDA55BF9943
+:10AD10009E7718E5CA84F8A52DC824935827C91B27
+:10AD20004DEE5D483E518679907FD7E603DD7F98F2
+:10AD3000F5D674ECFCB0F3891CD47F201FBE979F1E
+:10AD40007829FC1A3F6A70231FE23AE8E3C328F827
+:10AD5000353E62B7745280E116B04B31D5EC54C623
+:10AD60001A781CB89ADE3F3F60E20996063E8FA52E
+:10AD70004182FB46E75A8A371B312CE047B8A68D43
+:10AD8000FC7CA882953D33F2711F06F0D6FCFF844F
+:10AD900037DA2EBF5C3CB40657F43AD6C69726EF96
+:10ADA000A478E8FAA9368A8F1E27E24AEBE71B2827
+:10ADB0004E08F66F64F7D7314B08E5F0B5C28ED672
+:10ADC000E2F47F2571FF6770AF59DD11618F5F1A63
+:10ADD00027AD521C7670098FA7EEB3B76BB9BDDDF6
+:10ADE000A7D7C4BD80F6515C96B7DFAF52BCC4CBC9
+:10ADF00012AF1F9CC1B8BD5E23CAE738443C05CCE6
+:10AE000025A93F5EBDBD8311FFB7DBB3A83C45E676
+:10AE1000FA877D8FEB9FF64C6E4FB6DF9947E5B012
+:10AE20002F1886789F2583FDCCCFE7F9FE20978FDA
+:10AE300017EDA75D9FCFEDB23E3B47E4A3FDB2CF38
+:10AE400066043622DFCF29F20D9580AF6699B8DF10
+:10AE500015F86E33DE89A9620DDB956CBC5FD1F00D
+:10AE6000AE219BF8EE29E2BB42E0BB6C1DDF85F210
+:10AE70004773F98BC254E3BB3E7E2B888E870BFC55
+:10AE80001CFB6977767E5087FB8A2E33D1418B6B12
+:10AE90008C5EE711F09C347278DCB24CF0EC1E084A
+:10AEA0009E2BE1FF487E1BC2389F0FB60E86282CD2
+:10AEB000682FE95F076B3C81308EDBB71E96F37D10
+:10AEC000E42570CB36E28BDBEF9439BFC6727D8E02
+:10AED000E749C9307E8D18FFF695FE4A27D6AB911B
+:10AEE000080F355DB514F7C52AF9B99017FE203C57
+:10AEF000CD42CE69E757D344FB298E1A23FAE3A645
+:10AF000056EBCF91A6D9F839D5ED538D1F46DA3DD2
+:10AF1000D3D8EACF314E711A9E3369F5818FDECFD7
+:10AF2000B7BBE9FC5B65F978CE7458F859CE015F80
+:10AF300023DFBF96386FF3FDC077F94F1695A03F1A
+:10AF40006E7CD282ED6B20FFECA6E1947F2DE9FBB5
+:10AF50000FBC85E55BF3285F6990884FCFD5F2F68B
+:10AF60000565774ECA8C43F92FFAC5F584FBF59831
+:10AF7000407B0DD4F38CC82AC1F8D14AE137387729
+:10AF80003FA3F29B46DA7948EE3C95FC7E9531A2D0
+:10AF9000FC07BCDF3746FD4709C6115766F54E472B
+:10AFA000FE7EA3E4E5E1983F2C7D3E7DA03886C27D
+:10AFB00002293C0CF052E9E2F5AB4B7E9E827E9872
+:10AFC000CA0A9E2FF496AFCCC672C3F9E903DDEF2F
+:10AFD0008D11FB9EBEFB6A625DBFE83B41F7D3FC6F
+:10AFE00016C98B53F48F39417E0766931CE83AF3F8
+:10AFF000FB3215F4738FF3F138D30ACBD264945F2C
+:10B00000B7044CA5182FECB08C3A8C7104F163CACC
+:10B0100047235DC75918D115F83CAE00D6D7B4AB5D
+:10B020003F1F1A87CC65D3F3B9C647351A7F57EA55
+:10B03000F918D6A71BDB5F4EDE0EC6C730FED00266
+:10B040005C67DFD3EB9BBEFEA2D65B74FF83C901B6
+:10B05000FC89948BFD7074D2BA4AC3E8BD6C5C77EE
+:10B060006DDABA1B89F33019BAE99E4E86E41D4E9B
+:10B070001756C7782DA48FA2E0D6E04B07D9C64A51
+:10B080002E850B7F14CD5EE43F6EF44BA48972686D
+:10B09000E763AE7EB860FC1B100F6C3987678BD4FA
+:10B0A000C0E586D81F68FE8C3A6DBEFBF5F32D8B8C
+:10B0B000E1F7D63DE877C276EE51C3BF0DEE7AA137
+:10B0C0004FA75AFC8F9A610EB73967113FDC011AFE
+:10B0D000CD09F3FF5B6AA006F1D12C055FE9C92415
+:10B0E0007F3CC57700BD271744D8011A5CD1F8A86A
+:10B0F0001B441E46C31D8D877EFA742763AADD7725
+:10B10000EB9B57D47CA2ED02B749EFCF7309BF9BED
+:10B11000ABDFCF5680E5D52CC64B7E36AF44FBA8BF
+:10B120006AD0F32847ABAB18F9475C3603F9D9343A
+:10B130007D3F187FDF703D9737D50B99B84FC7E734
+:10B1400011CD5F4358CF83F49E8345DD381BD7ED87
+:10B150007C9B2E0EBEDAC6FDF32B0B24E197EF1974
+:10B160008D7E89BEFC25FEE09ED1283FA6CBFA73DA
+:10B17000AAEA8BDC1FECBA28515AED3D311AFD2C9E
+:10B18000AEAA9ED128871E19EA5B85743D6EE0FE4B
+:10B19000F24BFC160506CD1F7C457C174D0FEDFCD0
+:10B1A0002F26CDBF01C73923759761E1862C713EEB
+:10B1B000C30299C8974E476639FA7140CE7DF30DA8
+:10B1C0006E1EB108F035262310C2767730FF78BCAA
+:10B1D0006BE9AA0A18F97905A3F92F12F31F2FF4C6
+:10B1E000DFF9CD3CAEA2D257F0041E89D41F35B290
+:10B1F00010AD3F1FE9B1FB04FCE741D585B1FE2E40
+:10B200003BE9C179AFCFA27889FC0D86FE772BE0B0
+:10B21000EFB0508CEEDD8AC29D2E5DBEB83345572F
+:10B220007FE4FE2C5DF9A8F0705DF955474B74F989
+:10B23000D1DDD7EAEA5F7DAC4297BFA66792AEFE4A
+:10B24000F74E4FD6E5AFEBBD4B57FFA3BE7DBCD04D
+:10B25000DF415F7701CC7BB6C69F1767EADAFF292B
+:10B260006EC251E4CFD9AB79FC77396048F78E478D
+:10B270001BD7F30DF007E93B9EF552DC5D5D48F20C
+:10B280008619C691E9ED8005FB3B088F97BBF79EB9
+:10B29000EF9E6140D3F78302116F7235BB9AC78D61
+:10B2A0007E3B5DF358CEDF4557B3474F57ABAAA758
+:10B2B0006B6C819EAE76AF9EAEF163F47475FAF45A
+:10B2C000744DA8D2D335D1AFA7EB90697ABA2607CF
+:10B2D000F4744D9DAFA76B7A839EAE198D7ABA65D3
+:10B2E00006EFD5950F466F4D1E66B72ED2D5EFA34C
+:10B2F000BB7F3EC511E5B6FD58D7BF46F720FC41E0
+:10B30000BAE73311EFF83FA47BF2303DBD417FA493
+:10B310000C1B4D7A3F1DD369F9C2BEF60FACF73551
+:10B32000F913A96723F79783C9A54BF48AD86F0E41
+:10B33000AA57A2F69BEF31D07B34C86AF21FDD29F1
+:10B34000F8F3500CC7FB1758740DD4833A6300AE62
+:10B35000F7106E18E7BD9842F20BDCC53A8DD8FFA6
+:10B36000DDAC9BD2E9AC97D20073901E9DC9BC9412
+:10B37000CE667E93F013DC302C11FD073D65A88767
+:10B380002FCC78EB389D2FBD917045EF3D7C88E741
+:10B3900018B98C9D12F2E0249E6740FEAC55F8D39C
+:10B3A0007C4C7547E0ED94F0FBCD1C27913E647218
+:10B3B0000CC559CDBC43227D32F3FFF2F48E61DC23
+:10B3C0001E8D4E9B1B35FCF17DCADA612AC9F7340C
+:10B3D000D629F41E0BD8B2A91F7EFEF0B489F693CD
+:10B3E0001E0B87EF798929635C74ED8CE8EAB170F4
+:10B3F000789E37320BE2F339165091188F2820A22D
+:10B40000F87D87E1C81F33FFEF5B59E82F8B59B5F3
+:10B410007B6AE535783E125C4AFEEA1F30BDBFFA12
+:10B42000EE0689FCD53F003821F538BC1ED4975A6A
+:10B430003E88F0C23C2AB11E7C1FE26990D03FF4E6
+:10B440000FEB6FCF8F79BDBFB3BFBE7E18870B7F69
+:10B45000907E9AFFB1C0C0E3157AEFE7FB94ED3F11
+:10B4600060DC8FD6182C0FE2F9A40C1B4A8C6732D3
+:10B47000F27BE86B8765F2FB6EAC9BF6F9EC8866B5
+:10B480005F0648FE16897B0E67C5F9DEDC0E0BC32E
+:10B490007899A2DD075D789E371778B01BF5B0125A
+:10B4A000A077568A36BEE6E2FE37A313EF2F6AFA7C
+:10B4B0007F703E55D8A988FB02C0770D03D91F7B4A
+:10B4C00086F373FAE6A6EE61781EA7C1F370D35136
+:10B4D000CACB8A97E20CF11D2667447B931BCA23D3
+:10B4E000E49D6283F61172C868F3D36326CB9BBADE
+:10B4F000E99CCF28DE8B5A91B6C81188D8C7BD30D9
+:10B500008C8FCF2C41E64862C204C754398572ED56
+:10B51000AF8CEF67CD1EE827527E5E4C64917EFAB9
+:10B52000D6A66304EF722910C04ECC392C6C05FAF4
+:10B530009815BC730BDF37DE7814E3A94CF645DEB3
+:10B54000B03A38DECC1EE542A43C7D7598D8470B56
+:10B5500079FA2F4DBD85384E73538F862F86E7A617
+:10B56000C1647E8FBEB9E913FA6EA85289DF5EDD31
+:10B57000987F5085F2E3F017DFB531BB395CECA260
+:10B580009BF4EA74C107E8134B07FE39DE68243EDA
+:10B590005B9C6E237FFDE237730FFA603D9B60BAC0
+:10B5A000F27780BB7F1C8E279390A7C04F7E940FAD
+:10B5B000A61485FCF62EC764A2D3DFDB9F865F93BB
+:10B5C00095D17B44A6741BD905570AE7B9287D0598
+:10B5D0007821F9BF58E0457B5FE9F8038CF60B8BC7
+:10B5E0001FE2FEBBC5B58CE2FD5923FC94F5F38D3B
+:10B5F000A66712F12518F8D8D6042B0EBA78ACC974
+:10B60000C202F96087607C7C763F1DDB7C8A138FE9
+:10B61000FAD754BA6B307D6CCCC936147F8F8FFD4E
+:10B62000B21B53F4D5E3F88E061642FB98CEE061C8
+:10B630007CE77CC8C3F871A23C2EC0F3F1A23C7E2B
+:10B640001ACFA7FB5E902A11B0A873A5749B6B62FA
+:10B650000ECAE9D98CDFB716EF2D6C11FA22D5E6A8
+:10B66000AAA9C4F2BB19DDBFD0CA9F14E5C9B60FA1
+:10B670005BB3518F4CD5B7DF28F030C4F661DB38AF
+:10B680003A7FD2976BE73B89B6F347A97D91BE7CA1
+:10B690009D686FB79DEF1E87E539FAF11F15E5B17B
+:10B6A000362E0F999FF1770144F923A2DC8AE53801
+:10B6B000BE9797CBDAFB17A2DE4A0107C6B691FF09
+:10B6C0007318F77F6E6DB214115D9A2E127D1E6B8A
+:10B6D00062949F34DCC5EF6557717CBBDC9C1F1CFA
+:10B6E0008D6CC0F700260DE7FBAA38B5C7E71B40F5
+:10B6F000EE69E52E077FEF40F698889FCC3621371C
+:10B70000C47AEC931B5283973319F7975F8EAF611E
+:10B71000A15D40FB6828FC205FA73D60608108793F
+:10B7200099B230860522EA7B66BB74F9A4BB5374D8
+:10B73000F5DD53B374E5B6D2E1BA7236D545EB66A2
+:10B7400091E0AF98A2125DB9F60E03DB2EEA89F5FF
+:10B750006BCCB95657EF7C811A8F3C7E6A22E81F6A
+:10B760008A2BF05A503E2CB2670D41FDF35CD31882
+:10B7700042CEF3B0AEC06865BB9C3CDE7C179EE356
+:10B7800041F9BF36F9E8FB0E2857217D1AD69D0AEC
+:10B79000F53B9A1C947FAAC943E9962695D2279B2C
+:10B7A0000AA87C639397F24F40FF98AE837EF0FB2C
+:10B7B000DAA62ACAAF69F253FEF1A669947FB429CA
+:10B7C00040E9234DF3E9FBCAA606CAAF686AA4F4B0
+:10B7D000E1A620A5CD4DAD541E14F4DE25EEAFEE4E
+:10B7E0002AE7F7D2A3E9F8F07049F75E9CBD3F7EE7
+:10B7F000E4E1E1183FD2D94376B8163F82F3A6FEC2
+:10B80000AC7CFED1FD6D1ACEFD09C359F7D258BEEE
+:10B810009EE99C3677BF77592CF07D6A03A743E6F3
+:10B82000FE5E2A4F9ECF69B149E865E60EB2B4329A
+:10B830003AADA77A67A5EE8A587EBE4DFE0CE6812A
+:10B84000799689779288ED4206844B19C3F5A7460D
+:10B85000D7BE793B399C38FF81E0DD21E0954B3B39
+:10B86000F9FB27556D6164FB185F03BD7F6299E6A4
+:10B870000F2B90BAFD017A8F61F8C509B0390379B1
+:10B8800073F17AA6429AB650BF6F4B995DA2DB174F
+:10B89000C9171F632AC8015B917E7F1593B348D7F0
+:10B8A000CE92F6635DB9C9BD4C573EF3BECCE51EE2
+:10B8B000C4672A3FE731AF5ECA9201AE39ED6B082B
+:10B8C000AE77041DCF4A2ADDE30EEED6E21EF8FE67
+:10B8D000E259A15F986535D963F94E9ECD8B0F1A59
+:10B8E000503F7CF66FF124979E79CA10427F2E88D4
+:10B8F0002703AEFF4230FBB0BC98F5501E435630D4
+:10B900003F8AA932E6AF62BDB4BF82FDC5EF866350
+:10B91000FCA81C78CA0AF933E9816779FC5A98F4C3
+:10B92000679EA0679EB69FDAA044FB79DF1A4E7C23
+:10B93000A8BFC7D622F6172D56EE7F5BEA2C1B82D6
+:10B9400076EBD941E20DED9E578FCC067CDB930F51
+:10B9500052AA7D7F54350C784FFB8F51FC3F0C98D9
+:10B960005DF0FF1F119E33A56F27A11BAA2EA7977D
+:10B97000D6C159C9E79981F87D5DE6FC083B2E9C4C
+:10B980009F22F0ABEC2EF7CC003C2A6F667B83AC99
+:10B990007F9C679A8E65633C8096CF13F1B23B9B88
+:10B9A00092732A23BE3B0B393C05ACBB0AF55541CB
+:10B9B00091C11BC28E7D0E9D1FC39AD3E6C377072C
+:10B9C0009412E64531378CB52D43DDADFC4DA6789C
+:10B9D00027E5D0354C85FD8CCD1666181FA6F5CB16
+:10B9E000843FE4012137BF7454C6D37B92297DF292
+:10B9F0000F7524FBD2E6EB463EFAB2DDC8E7754888
+:10BA00005F5E60E3715C730B4C2155C2F7CBDAE8E3
+:10BA1000BD4465ABC4D232118E718407B62F96F83F
+:10BA20003076C3081684F552EA0CFC05F9E44C584C
+:10BA3000DD67C8163C09F56A0B4DDBD03ECB47BC31
+:10BA4000D8102F77E654E2D0390584DF3962DE79E9
+:10BA5000857CBDB6A447C1C3BC3E7C57746EBBE6B3
+:10BA6000C7D1CFF3D1D28A5BF1FDC5E66E99ABB5F4
+:10BA7000287CAE32768F98015D9FE901B8648233ED
+:10BA8000AF10E5C2863216243DCEE757FB94C4368C
+:10BA900065925CAA223D3EDAC022CF31B5B4B8909F
+:10BAA000CBDF9786F3F7DAEC9E23C48FFDF9C3470B
+:10BAB00066033E9E33B0023ABF35F0FDB116372320
+:10BAC000A31F00D29F146AFED2163609F5B6D340E2
+:10BAD00071A072470CDD4F959D0AC59FB7D82A1DEE
+:10BAE000F7623F0E85CE6B26C863BBD18E363B0D09
+:10BAF00057A11D7E78DB8FBB317E474E5718FABDAC
+:10BB00005A1C0AB743D20C1497A7382B2D78BE9332
+:10BB1000673B598EF83CD8F1437A8F417E50C4CEB2
+:10BB200008BF985190AC853550FFC13445BCEBE25D
+:10BB3000AB1E95248E2654DC0F557D82FBEDC38E03
+:10BB4000F356DC17A8B6B9E40FAC2BE4FB44239EF4
+:10BB5000E341FEA925E79D28BF5EEF58EECA447B6E
+:10BB60003AA4902D52F075730ABD3BD061A27711B3
+:10BB700034BC660415DD79607AA33E6F8E3A1734C3
+:10BB800046DD479B85E3939F781A0B47CCC7E8E1D6
+:10BB9000FB37E6B6D1FEA7AE50BC8729F273300F53
+:10BBA000A4D8690CA678013F873AE666E0BC2EBCB3
+:10BBB00014A0F8EFC1ECFFD242558C17B41AE8FD7F
+:10BBC000DDB015E3C1B737312FDA79969042F1F83D
+:10BBD0003B843CCBB171FEF717713E8F4E73DAF8A0
+:10BBE000BA5376C58462916E8ECE9220ACF3C25762
+:10BBF000273215F4608EC367407F7C4EA3C98BF655
+:10BC0000E7845FDA884FCEDB783C95D2F8888ADF0C
+:10BC10009BB7951544DEB30B3539BC289FB6355913
+:10BC2000BC18A31E1A44BE663B0D14C7AE1A785C3E
+:10BC300065BB588FED85B194AE1572E6692538194C
+:10BC4000E17C1AE889F1F3075773FB78D1520BC1F5
+:10BC5000B1E8F56CB2AF06C3DB334D1E6F0EC2B355
+:10BC6000DA9082FEAAF29539ABF09D8C4576FE8E75
+:10BC7000B01C3F9CFCB6EC774686F67C73DCB5DEE8
+:10BC80005911F25D8E1F5B807C25CBC114F4E7FC5B
+:10BC9000BCF0DC6D18570BF4DB84F9DDCFFDE13629
+:10BCA0008CA3DD690FA6609CED4BCFBDCFCB13837A
+:10BCB0009B30CEF6E073C779797A30C500F9D79F0B
+:10BCC000FB9097E7063761FEADE74EF1723C030348
+:10BCD000D9F9DE739FDE16447F8BC93B1F05F22F17
+:10BCE00000FE2258629D22FD40E0452B7F01BFC32C
+:10BCF000066C8F48A3CBF78976FB0729FF9528EFC1
+:10BD00001AA4FF03A25D7890F68744BBC383B43FB7
+:10BD100022DA1D1DA4FCB7A2FC8D41FAFF77D1AE3B
+:10BD20007B90F66F8B76EF0ED2FE0FA2DDB141CA8B
+:10BD3000DF17E5FF19D5FF7151BF477CCFB2AF7E4A
+:10BD40001FFDF7592047502E15D857BB709D6F6BBC
+:10BD50002D25FE6F2EE3E7541ABF67498CDEF7AD41
+:10BD60002EE2EF8A551771F9FB67D13FF0E1E3C886
+:10BD7000778BDE9429AEA7D9E03D1D4239BACA407F
+:10BD8000F6C0A2D7F97E7DD14A2514792FE7CF518D
+:10BD9000F02F47F880715B3085F576A690C7F59B4C
+:10BDA0003D1E6F75843C333AF47990170CE52EC82C
+:10BDB0006F8ADF2E5859D15A00F95497812C10A55B
+:10BDC000D612C6F73A14BBD00B8ED2B60284CFA6D9
+:10BDD000D03B059A9C67368FCEAFD16253E8DD36F3
+:10BDE000D9CECB27FC72AC03EDAC1616E8F6617B1E
+:10BDF0008F4276FCC1D61207CA3D937DB603D7EFBA
+:10BE0000BBC57C5E9575053128AFE5470D24BF0F96
+:10BE10003BF87ADFEAE1F14EA057E89E13C86B2F9A
+:10BE2000EA887C165E8A7273E763FB66703F1FB315
+:10BE30008F2AA37B44DAF9B6A444EC03AE2BE2F8D4
+:10BE4000C9107A4441FD02E9D3A5E2FE4B90FBA361
+:10BE50003214E6498DB8C77B5D91CCEF1F2988234A
+:10BE6000E84BAEA6F7AB862E5174E708690FE8F3EE
+:10BE7000A628BDA144E995EC569093BAF313872EFA
+:10BE80005F5424FC3C5EE6453B76C22F57933C3C16
+:10BE90008FFA4D1A5CEEF5C95F218F9F4604A01CF6
+:10BEA0000DF27BE4075797FC16E9BD68A581DE8D8E
+:10BEB000BE5239FA678405F0901B90482FC0845217
+:10BEC00070DF74393CE41AFD2E7A57E332F8C85D0E
+:10BED00057EA42799B1B50A8FF4BF4C665F0F5BCAE
+:10BEE000E43D16403A3A63845D0D0C807E3B574C2E
+:10BEF00007C6179B843F458B17568628FC5D7C71CF
+:10BF00005F55167CFC30F3A9AE6C7C17A881FCFB56
+:10BF10008B773FE041BB7D8521E0C0FC51D7A45E1B
+:10BF20001C67116CFA117F3BB10F7A1FF3B7B7FB97
+:10BF300000FECE90497BBF328CFFECC63820ED7DF1
+:10BF40004C0FD96BA2FEB5B75702DE3B1547219ABD
+:10BF5000A04B775DB7DE781DD437B1BEFA78EFEE2F
+:10BF6000B9C306F17EE6B8F595209776C730DDFBBC
+:10BF7000A0BBD1CF4EFD4D588FEF81C27837C9B0ED
+:10BF8000375B5B74F37A5B723F3CEB8AA7AC5F8AEA
+:10BF90000E3BB14F7132FEAEFB19B5270E970FEC79
+:10BFA000577E5204F4ADED389914B95FD7EAC78BC8
+:10BFB000FA755DBD75BB54AABF94EAEFEF8D2B22D5
+:10BFC0007CF79645D68F137E8088FA2BBEAD7E8196
+:10BFD00006CFAEB76F2FE2F51FC5FA67D59E248A4C
+:10BFE000AD898227E1D2FED77E5BFFC345FD33E1F9
+:10BFF000B7A9FE59D693549C49ED3661BB736FBC0B
+:10C000005D26E69D84E738EFDA7C4F16815C6AC0D6
+:10C010003ED07E561A54FCDE696973A0FD6635B6C3
+:10C02000F9510EE7E03B5F63FAD3ADA83C465FFAF7
+:10C030003D9A9F3B2D2CA11AF9B5D140FB9BFD3DAC
+:10C040008647902FB7A68D75E0FE79B7A9BBA408E7
+:10C05000EDD7BD36B25F0D199F59D16F6ECEE7EBAC
+:10C06000DFEA6CF01641DE9A5E44EF74CA0F2DEAE7
+:10C07000A4F7C27FCADFD1527E660A6C477E0C2FBE
+:10C080002A9813B1BED7151B09BE95AFD956E3FE4A
+:10C0900060A5D1DB968F76B85DA1F84BE567FB26EE
+:10C0A000917DF80B0323F90FF3AC807E5B6628F4D7
+:10C0B000FB0E4E14CF3C5844F8F0FB2BA0DED044CE
+:10C0C00045C27B3A0F2B7E0B9E7798855DB7D5CB0B
+:10C0D000EF6969E37E2CECCF8F8BF8BBEE5BD32E40
+:10C0E000BC37CF8DEF3098E87EA56DA1216C8AC357
+:10C0F000FB66DB4ECF437AC6F6ACC4FBC631298A59
+:10C1000003E7F7643594D1B95C277D0FD61A68DF51
+:10C1100090B0D0E043FF634C8E49E7EFB0C1389157
+:10C12000FE906F8A03C710EEABDE546E423C7BEE8E
+:10C1300037D03BA48F7ADEB51800CEB8527D7BC7CE
+:10C14000587D7B57A5BEDC5DAD2F4F9AAA2FF7DC3B
+:10C150006D8AF2EBE8F33334BE029960033D15C3F8
+:10C160008B588CED4213EE7B56BC16C3883E4BD6E3
+:10C17000B7E5E3FA8CED257CC50C8F21BFC08A643E
+:10C1800013C9F515C5DCAF7F28DD7413E5615EC802
+:10C190001F5BD38ED07EE412BCD84E7F8DFDDB5862
+:10C1A000C477B4338A7D7F291ACDF39E32F4E3310C
+:10C1B0009287CF4B3EEF41C4F75BDC5FB1B591FB9B
+:10C1C000B11F9DCAE311690665B8DE79FD38CBEA77
+:10C1D0006EDC97C5D95AEFC738CB68BC2689F38681
+:10C1E000AD78CB16F92EC0DF675EAEDD77C2EF65A6
+:10C1F000747B81DE1F1B3F82F38B53D809F19E8431
+:10C20000A296887B1349C26FF2F8D89956D41FBB07
+:10C21000C57B1E7DFDA934280F3D45BF72B124F6B4
+:10C2200053BCFD7AED9C47E4139D3CBFFBB0EB266D
+:10C230005C5FEBA7BA4A70BFBF42D877F16926DFCF
+:10C240003098D7DAA3A6A03412F20A3B6C04BB6084
+:10C25000B78B8F6B7A3D2688F7F3D67A4AE9BEDF33
+:10C260007562BC17CABDEFE07AEF857584715F6BAC
+:10C27000DD5E6B8938370D027C685AE03EE56075FB
+:10C2800009ED77D7FABC56D49B6BD3BC568C97B6C6
+:10C29000262B0E8C077579147A8F6DAD25E040FB47
+:10C2A000C7058AD484E749E96D13E99E1BE0DA509B
+:10C2B000C68F1A988833C438BF0481CFAD9ED90E7B
+:10C2C0007C1FC19DB3E747E8A74FC0FEE2783BC49F
+:10C2D0009353E0697CB14A70BB45FF09B35FA0FA94
+:10C2E000F8D35216D19FA0A369220BE13E4D1B5FEC
+:10C2F000EBA7AF7FE6A37380E5BFE5785B9ACEDF5F
+:10C30000A132DDC7683FF742796027F2596F720C9E
+:10C31000C9BB144F4A05F251CAD14D93F1FEC3F285
+:10C32000DFC6F071E6707E4F5198E57A9C7762C067
+:10C3300081788C5EAFC987DB6A902935BA44AFDF5C
+:10C340006485B5CAAE4BD771B2C75D91376280F5CF
+:10C350001CB55E928FF63E88FD47AFEB2DB1C74707
+:10C36000713D12F15DBE7CBE45EA5949723859A152
+:10C3700075961E351EBE6787798919548C4F5E5796
+:10C38000ECD4DEAD5211AFBB4D8E71367EDE4EFC6D
+:10C3900055F1E2EABB7E07F90BF87B73A056EAD1B0
+:10C3A000B66ED28BFB03F9587FB312780AFDE99B76
+:10C3B0008F0DA17722CDB1FC9D4F53D4BB259ABEE2
+:10C3C0005857CCF7316AD4FB96DF35ED4C4B2B74C4
+:10C3D00000CFAC7BFEB77FB024FEE3ED9FB4C39DDE
+:10C3E0004B6DB0A6B7ECBA653DC6475ADFE4E59B96
+:10C3F000211F54102F0BC9EF7268E8BD34FFE6F718
+:10C40000CCE4CF2A96BD1B30CF3EB0923F6EE7DE24
+:10C41000B1D3709D34DBCB54B4F79F11F267BB5896
+:10C42000CFD1F3924DDE00DA03D1DFB7168B73095B
+:10C43000E63DD601F42D7EDA44EF25F5C547745864
+:10C44000F9EF331376E86C21CF66EF5B35F420C348
+:10C45000F7306AF615C3B8B3ED9549084FEA458938
+:10C460000540FE6D16E7B3A9EE1724943369EEC3B9
+:10C47000E528EFD359F752941BE90DFAF3B2D48BA8
+:10C480000AB5DB9DE2A3FEF007EF399B9858D3AEC7
+:10C49000005B8A723E859FB7981C31FC7EBAA7521A
+:10C4A000779F597B47F655810F13E0D45802A94D69
+:10C4B000E1F7E7A3EA1F15F892D16F8FCE7FC791FE
+:10C4C00063D4AF4DF92CF25D16DC9792D05AC8CFE9
+:10C4D0003F014F41DC87B278173F2FF5F9D4C8B838
+:10C4E000D65490BBE6128C3F09529C48B2B89FA02C
+:10C4F000C5F500069CE877D3E23EB631BD3DA2A566
+:10C50000DAFE3CA751A67D47E1AB56BE3F686521E8
+:10C51000AB84FE3046722767353F9FD6FC62D5B8A4
+:10C5200098683D380C3CFEA793E29935BB0AE84B6E
+:10C53000726765D47B4FDA7BD55F88F5B4B9C941A2
+:10C5400074D4CAD302D174D49F736AF5522FA6B2A1
+:10C55000404264BF21EA37B5710FF143EAC5A154E7
+:10C56000BEB949BD4CFF5983F49F4CFC3278FF693A
+:10C5700054BE25FCAEF31640C593BD7B9C7E15E5ED
+:10C580004A78A277003CA73EA0979323F7EBE5AE4D
+:10C590008697CD8ACF5D03F8DEFC80C1DBC130FE1B
+:10C5A000545FAF2AF3F74EFE7EB4563FEC9E82F501
+:10C5B00017F2FADF3BADAFEF2FDF1B5D9FE0BBE172
+:10C5C00062947D18459F687801AEC4DB22E01A674B
+:10C5D000D1FFFEB869332E812BF18E08B86EF4E8D6
+:10C5E000EB07960E0CD74D05E66F854BAB77EB98B6
+:10C5F0002BAB173D8F2955E641F0CEEBDF31EDCA6D
+:10C60000FAFDFEFC6FAF774F63F43841EDFC4867ED
+:10C610008F243472FBDDC17A29CE44B33B5CCC213C
+:10C62000E2BFB8DDF00EFE17F6B34B46F86F1D31D2
+:10C630001AF1EFBB7B9D8AF754B8BE62D5FC7D48EA
+:10C64000D8971447BE7FDD0FD732EAF7658C772283
+:10C650003D6BF1A2DD5998CA2CC9687C794259F822
+:10C660000ED8F4119ABCE6F1E5C305EE9E4FE95CE5
+:10C67000E4A4751E72213CDF75DC7B47F8E68C482C
+:10C68000ECAF3F98BF45C393C9D449BF3FA1B7D6CC
+:10C69000E645FDF02E1641BBA76F3787D1AED6E237
+:10C6A000508FC54E3F92A8D2FB038BB1FF69774CE8
+:10C6B0005C8E79E95082BAC886F7977AB47B9E3F40
+:10C6C00042BC2DB40432920C74BE9A8FFB61E64FCB
+:10C6D000109782FDC503C56968F0544A1CFF316993
+:10C6E0008120F65369E8DEEAC76F4A37DF673B12FD
+:10C6F000F9FB47F8CECD00EB5FC34385E8E7A0D157
+:10C70000FB552FCCEFE09A78BA0F3F3BE18EE9F86A
+:10C7100036CA1C833F090FD023E07E8CE0B6CDC81B
+:10C720004846B88D026E4BA2C0BB2FE7DBE0EE8B14
+:10C7300097F9A9A4BD534EF917834EBA776E367C8C
+:10C74000F1EE14D4C3C5062FDA9D9BC1BEC077D6C7
+:10C75000FE8FC0F7163C6371D1777A7FCD23EE5FF1
+:10C7600079D61BE8BD157FC54B44A7A7EB6C5EDCF3
+:10C77000B7CF602ABD6F3A4BDC47F963F97FBFD270
+:10C7800003F3DB3522F02CD2E79E04C3D077098E69
+:10C790004021BD6735F6CAE267B573F8C9C23E9855
+:10C7A00023F03885F9286EF7361630E2B86F9F35DA
+:10C7B000F9D02E7D5BC423DFC182F4FD4E16A2F4B6
+:10C7C000FB2C4CF57F802FB742FEADD811E98D00D0
+:10C7D0005FCD13F9B9B81E23F0FE8AE0977BDC9C8D
+:10C7E0005F3E1E82786F4FBC22FEAD9138FE968C64
+:10C7F000081CC1798FB3A86E2FC2E41897867E9467
+:10C80000BEF55399C8F94F71E47EDBFAE93EAFDD1E
+:10C81000BBF7D992CBF0DD2DFE73A3EF3E8A17C78D
+:10C82000B87C37D0A15BE5F70D416CD88340A7AA4F
+:10C830007299E2F6567C2EEE49A31303EAFD669444
+:10C840004CEF8469E792B788FE6E49E3F706ABCBFD
+:10C85000A7B4C4035E267CD5531A86B42A4D7F8FB5
+:10C8600070A2BB839E0E9F94A3FF7E136BA303E273
+:10C87000EA227D9CF92D51FECF833836F0D527234F
+:10C8800044BCE470363CF2BEC1ADA2EDF9EA2F4CD7
+:10C89000E760FCF491815EC4E3A29BFF389DF675CE
+:10C8A0000A7BF32A985FDDBFCB644F7ED80433C97F
+:10C8B000C7B86A0BF381C17F0AEC0ACC9F6EF250B5
+:10C8C000FA29D801987ED65440E5679BBC941F3F57
+:10C8D000D2FF17A4F3CCD6CF15D4472BB4786C0174
+:10C8E000871657B842C44F2CB62F3A86F10B8B29C6
+:10C8F000E09DC1626F9B80E0DFBBBFF308A6F05DE7
+:10C90000C67DC8E23512F975E61C0E2C4732CF7B86
+:10C91000A3E7161413A37F7F3209F7E9B568C702AE
+:10C92000EB2F76F92C23617C5FD789230950FFE335
+:10C93000A63104DF274D3E82EF4F4D55944E1FE93F
+:10C940008FA37AEC737A6FE9E65D2714FC3D68E308
+:10C950007D12F9EFAFF7B15008F0BAC1C8E5FB0698
+:10C9600090EFB83ECB8B276F7900E11B11F08C0460
+:10C97000FCDDE69A353E01BEDF32668682F5EEF8D2
+:10C980000A7450663F1F5E8EAFCF1C90083F670E43
+:10C9900038091F1A9E6A05BDCEEC2BBC15DF1F3B64
+:10C9A0007054A6F8D3F3170D04DFF96331149F1AFE
+:10C9B000DD7ED1DEEC21688FFD09E887071F8BF64D
+:10C9C00016923FFE4FCFFF488D8CFBFD93ABF3C219
+:10C9D000FB28A7FE8BCB29B0374F6D423996964284
+:10C9E000EFE8F4C5ABB18658D4637526B1BE40CE2E
+:10C9F00060FE4F317C1F5CF68BD40A5C2F381EC65C
+:10CA00007B99C5EF9B80FE8EFF18FADBB7C943EF19
+:10CA1000EE7CB6FB892C1C7F67E79CF73741FF67EC
+:10CA200042FCF74D9C619D677F85F274BB8DFC963F
+:10CA30002B24800BF5E98E14CA17484A4C2339334E
+:10CA400042B46E0B2455C177C816BEB03105F90B40
+:10CA5000EF8B635CFDCB6B62494EBD6CF41E6FC403
+:10CA6000FEB6F0FE9E7DECA10FF763FA686DC94338
+:10CA700090DE3ED245789FFD2F0B86637BD0D7F4A6
+:10CA80007B959F7B510AA31FA4B8FDE0328C631AEB
+:10CA9000B9F9842105D251DBA5664C0BD3271D457E
+:10CAA000FFC1DD235582E3AA5D9932C6A60F4F0967
+:10CAB000BD7F038F1BD1E9F7A2F6CF2B709BA9E9AD
+:10CAC000F9E152E7A71DB82F1E7AAC84DFEFE2EF41
+:10CAD00044EFED9AF2CEF719CE032C08847B8689B9
+:10CAE000E22E5828D881743E1328F0D2FB26FEE0AF
+:10CAF00046E4AF3381247A4F7A9F211887BF2F29CC
+:10CB0000789CFF5E9F17B7BF1587F114F17B8C0CE3
+:10CB10007FFF74EDA8DE09141F92AED27E3C7DEB40
+:10CB20008D55889FBA3D7B3BA89F85162FFA63E7FA
+:10CB3000EFFD82EEBDB0893C0EF5CC1E9E7FA4D2E7
+:10CB400047EF8ACFEFF833CF77FB29EF97839974BC
+:10CB50007F6216B7779E10FA8CF58C6091EF1269A0
+:10CB6000F47A048AB17C43663019DF9FD2F420E85E
+:10CB7000AF265C7FE876A4F68E29FCBEFA15EA2F74
+:10CB800093D0475A7F4F98F87BB92846F0F7CF6C7F
+:10CB90003671BDBB03E40DF28BA67761DCC7715C17
+:10CBA00093B82F930A4A7614CC27F5093397DF57A9
+:10CBB000387EF4BD52CD0E9996D04CF7473F4B0DC1
+:10CBC0003C89F241BB47CA142FBDEFF741AA6FF36E
+:10CBD000C8D1FCDD0C9C03E8C510D6AB93C18ECA4E
+:10CBE0008EB0A32C57A617FF96EA7B06DB5F69FD84
+:10CBF00068393C56C0BFD86E203C2C5E67267FD873
+:10CC00005871BF74ECF963B1284F16FFB984E44A38
+:10CC1000336303E2E795261EE7FD6BF423407ADDDC
+:10CC2000973D32ED470E1B161E01FD4A2090FFB0C6
+:10CC3000B739BE94F23E24F7F55F1A06DC2F6A2955
+:10CC4000D0EB359C9FEF2BBDFFE186AF1CF4FB2999
+:10CC500099CD7545F3EE7F67473F7FEDBD2B985F1C
+:10CC60000FEAF7C59F1B887F177F5E4272B3EB0AFE
+:10CC7000E76B75FBFE03E91A3D1F80FFBF0682BF0D
+:10CC80008FDF7BAF0CFE072546BFD707D415F9B75A
+:10CC9000BBC47B025D0B8AE85D8B7DF82E08CACD94
+:10CCA000C9FCDE5117F60DF5BB121DF4EEC6CB46DE
+:10CCB0009E0FDE29DA8B771ABBEE4CE1EF66981BEC
+:10CCC0007E578CFD37F3F8B82E63887E1F6CD74FE4
+:10CCD00013E83E81163F7E4CC8ED6629FC7D7A0F35
+:10CCE000E47313E3EFEA8553EB4BF11D90E154FF3E
+:10CCF00098F8FDC957FAAEDE5D823EED1DA11DEB31
+:10CD0000018EFF07358A15A9008000000000000091
+:10CD10001F8B080000000000000BED7D0B7894D500
+:10CD2000B5E8FEE79F99CC24936412421E8484C91F
+:10CD3000831024E0E40501421820A1A8680308023A
+:10CD4000C638212184BC0848CF492D3583090F15E9
+:10CD50006B38468D8A3A58A0A0600705440D9E01A5
+:10CD6000D4521F35D5EAB1DA6202880F1E0941FD9F
+:10CD7000B0D7DBDEB5D6DE3B33FF2451DB73FDEEEF
+:10CD800077BEEFA65FDDEC7FBFD75A7BEDB5D763EB
+:10CD90004FDBBC74BBCBC6D80895357832186B4BCB
+:10CDA00072C44542FAA1812DC6FC9F19FCC531F61B
+:10CDB0009881B9CC918C5D655F166D1FCE98F38616
+:10CDC000103D0BC742479C92C3D82315A3D9DD0A57
+:10CDD000645B1F622C9AB1C526467F4B83C326B085
+:10CDE000ABE99F0ED344C616F2CF6CC9F29D66A77D
+:10CDF00005F255E66E6502631F54DD196A83F1166C
+:10CE00003A556F501854B8B1C8D195CEEBFE2319DE
+:10CE1000C775D0B8AC6218639321D57BCB198CFB56
+:10CE200072AF89DD9D0475F06FBA2F65CCC518D43B
+:10CE3000FFCCCCC7AFF3CCB8FF8CEC0FFE5F65B472
+:10CE40006C56C2B13CD1CD60FCFD239CA3EDB98CE6
+:10CE5000AD3A7CCDFD674CBE7A15CB8BD298CE37E0
+:10CE60006EE03881E335BB752E038C37CAB420E3FE
+:10CE70000C346986021DCCD3E531BB7726E1BC7B3F
+:10CE8000FFBC02F2CD8BAFB2DF0DD939F34D0E25C9
+:10CE90008AB1BE0341EE2005BF073B705DCD47421E
+:10CEA000DD3AC8DFAA70F8372B8CBEBBF61BDC3B23
+:10CEB000E15BADD1BD6717B4AB7D79AC1D4666872C
+:10CEC0008CF01F2C7F31849787399236E460790C7F
+:10CED000E1F725832D9CCA7FAF322A0FF6A64500C5
+:10CEE000BC1B639DB310AE238200FF16EC977F3FFF
+:10CEF00089EB00F89C846E11BFAE8650EA9789BC1E
+:10CF0000F317C3DC77D37A1C71CB317FDB385A8FB0
+:10CF100013E701F362F50AADF7A4D57D571A949F84
+:10CF2000EC184EF38812F470B2F8EBB72641BD93BB
+:10CF300087553BF6F99746D56B0CC3728E0F65BECD
+:10CF400029AD1DDA9D7E31D41E04E525F7D5BC89B7
+:10CF5000DF4BEEAC9B4B69F5BA1B18D4EFBAF3A3C9
+:10CF60004467C6407C94D4422B3F3CAEB23B4A114E
+:10CF7000BFF7D89D65B8DE55195D950CE8EAA2B1FA
+:10CF8000F371A632F6FE4867057EEF79E1D35DF8CE
+:10CF90001DF094563C1E96A1073A41FAED9A407452
+:10CFA000BD4AD0EFB04C6735F607702C65298C85EB
+:10CFB00064741A711E6CDDF01F44275F74EC3CA48E
+:10CFC000C03835C11DF594AAEE09D8CF39C51BA6C6
+:10CFD000A4101C9DB8FFCE5BBD61880FA70EF28028
+:10CFE0009F9ADDDA75E19F1EE65583FF8076351E38
+:10CFF000D561C6FDC3DC469C7F0D33FAEA27F17D7F
+:10D00000887400FD3C49FBD5F297D25F001EAAF759
+:10D010008CCDBA1BF0531371F85753A91EB493FB70
+:10D02000451D9897EB19381FBEBEF3621F9C872FD2
+:10D0300006A49FBD419CFE19A78F8B7BE204FD7067
+:10D04000BABDB8678C1BE7132DF6CD45C5A50BC639
+:10D0500076BF64F69D302F66F74C9C371E67EF99BC
+:10D06000383F94B10715CE9F6A86792622BF92FC7D
+:10D070008B993C13E641394BF74C980FF55F12F54D
+:10D0800058B1278DBEBB3D69D8FE908E55213CE539
+:10D090007CAA9F8EDF4EF030F1FD5AFDF438828F6E
+:10D0A0001CA719F94838A6409F6103D7FD5BBBC296
+:10D0B000F77FE8C418E46B43E13F3D765806B2922F
+:10D0C0008B4B8CB73AA0DF31ED464D3FB2DE58B7FF
+:10D0D000F6FB61D1FFA8007C8E507B8F06C17CD906
+:10D0E000AF014E6CE078FF89ED804E9F7AAA1F7FDA
+:10D0F0002AC72763364937368213C7D39F8D124F0D
+:10D100006BE3815FD7204C927DF03A94E98C8F8459
+:10D11000F422E661FE8722200F69BD80BFCC4BB8A8
+:10D1200007D2DF9D7FAE8CEF82F6E7ED3A9A57206B
+:10D130005CD703FCB0BCD9C06E2D86F65F349D4829
+:10D140003963F0ADE76C93C301474D7FBEB23DD369
+:10D1500084FB6EC5B64CD3323FB837EFCE3E610389
+:10D16000BC9EDFADC79158B3DEFDAB2951F85DF52C
+:10D17000B818959B1C380FCBB13F60BDCA6D1159D3
+:10D18000AACDD77E457B91A3C20FFEE3766BF1312A
+:10D19000DEA3CD5F7D589BFF1AB95AEE3FDF2ED339
+:10D1A000ABCD679FD0E63FFDD3DA45B80D9ECFE308
+:10D1B000FBE63377A8DB0470ADFA68F6093C473F1D
+:10D1C0003BF47C18E2ABE6AF15AFC5335C87964EF7
+:10D1D000018F8A1ED6EBDAA510BDAC7407EE5FC1D5
+:10D1E0003706ECEBF5B41EDC59FE741388DF73CC04
+:10D1F000B3C801F455DBF86ECA996C98D75C20640B
+:10D2000098CF64CF5623B30C1C6F28FEC12C0E1B85
+:10D2100003FA2BCBE365531A67B1D3D01FDBF2C7F8
+:10D22000D9B85FCBEE5148DE287B6ECC2B4837DD7A
+:10D23000FB975C4BE9A239048772E630223F5CD150
+:10D24000A17843216FCDB31DEE8276CBDD8A1DE739
+:10D25000BDAC25C8C7CFE0FF155B02E6D1E6570E8F
+:10D26000F35F71F8E8370AF45FB54DDB6E25C00B4C
+:10D27000CF8FEA1DFF08F2FF0E8210C16B4AC776FE
+:10D2800015D7BD5CCC5F9E7FCC55C0707D537813A5
+:10D290007606FF03E746F028676E66AEEF1C9CD269
+:10D2A000C6DB03E32BC375D7598C365C779D897930
+:10D2B00043603E27428D0E2B7CBFDC1E4AF2436545
+:10D2C000107399B22865E62C6C670FC77667DF5636
+:10D2D000494EAA03DE43FD3CA1B89BB11F55E1F9BD
+:10D2E0005FF3FC4AE6A5F520DD38FCD7E9D6E65920
+:10D2F000EB30924B6AF5DEA308976AD645F066805C
+:10D300004F878423C0AD16D6F94124CA5FDAF6AB45
+:10D310009887EAAF3AFC8F20FFEF20673213D4DF03
+:10D32000160C29CDDF4D70548DCCA18379AA7704DA
+:10D33000BB5D24871407239D1AF0BC00B8B6DDE559
+:10D3400048C3796F501C6956E4635BCD76E4634B48
+:10D35000B7F373A82D02E45768DFB6F22A6ABF1448
+:10D36000E529945396707ED716E1F122DF6F7B207A
+:10D3700089CB537F57092EBDF79ADD4F42FDB64C3E
+:10D380002EF7B46D1D43ED915F923C756F286F3F92
+:10D390008FC3B56DB8D5ED82FC873845804FDB76FD
+:10D3A000479A89DA819C96E43BA7A43CFD9B51CE29
+:10D3B000DB10DF72BD52FE66553F4CDEDC29CECF5E
+:10D3C000DEAD304FE8FF8C52FC9ACE4F1E6EC9E4A2
+:10D3D000FC7FE24CC72E51CF8EF52A74F3EE9E0EE1
+:10D3E000F3AD7850676B4EF2C19D391C6908E73385
+:10D3F0005BCD5948671367021F06FA3B99C9F97953
+:10D40000480E73B821BD57F47B6FA64E93C6060332
+:10D41000FD413F678ABC06C46F684EB111CF4338E7
+:10D42000C3899F07AEE361D14F85B1F8F56983CC1D
+:10D43000A79F0E0AB9DC7266B5F2249F17C7F3C422
+:10D44000FF30DB9B69DD7C7E12EE4037B974DE0B6A
+:10D45000BE15D14F27EE3D6640ED56294F23FE15F0
+:10D460000D9D103CDBEE1D4F785C2AF0CCEE350BA9
+:10D470003A61EC6F585E64A372A013824F5B26E0A2
+:10D48000CDE23BF7DAE639E222FCCE23A0032A07FD
+:10D490007CEFCF1C3EF0BE25F1CDF4EEDCE2D0A156
+:10D4A000F1BD2C2F62A202A08ED7335710C005CF3A
+:10D4B0003C82CB5D7AF79D309F917A0EFF043DA7A9
+:10D4C0002FE0CEAEE02CAAEF3042BEECFE15CC0130
+:10D4D000F5CBE2995DE1F55938D6876E5448F1CC29
+:10D4E000C07665E1BCDFB218E6BE53C8FDC8AF52D6
+:10D4F000314DA67E1DBA48DE3E2C8BDABB74BCBD16
+:10D50000430FE9A814BE5F7A3704D1FE29DB94905B
+:10D5100086743077A6960E52B338DDC8B435CB2664
+:10D52000CE197B2CEEEF652D63E9DC683617D71D2D
+:10D53000447CED0B2179B06CE32DD7E7E2FC9E191A
+:10D5400086120EFBE286FD1391DE96B52CF9D97B8F
+:10D55000781FD96DA6EFFBB29C1FE3FEFA42B1958E
+:10D560001E840FCB161E37C6427BA767DE851721A8
+:10D57000BDC1B5FF0F2817DC70A34AF56F609EAFE1
+:10D580003F44BED0C2C7B9DE75491F0BFD5D9FAFDA
+:10D59000302CEF365B1357C3FCCB04FECE09FA6D7B
+:10D5A00036B3C5CF5A705E0969C9F0FD7A94540745
+:10D5B0009103C76609397186B20DE59E51B3F8FE35
+:10D5C00092F5B11FECF76A8407D4FB5AEC2B99074C
+:10D5D000B852FD8ACD41DD2961981ABC63205D9463
+:10D5E00033F36FB8CEB9C96C36DE9B7A7FAEB22703
+:10D5F00069BEBD65B4EF43D36CB8EF9D8C7989EFFC
+:10D60000B9C712DD77CFE8EDDE04F9EEED63ECCDBE
+:10D61000C4D7F9FD7DB995D1F9DE3D83F335C95FF6
+:10D620004E5ABB42895EC57DBE5C90C6278DB31E37
+:10D630009C04F5CB2DC66E3C0F963FB020CC06F374
+:10D640002C6F83FB3C9C636C8BF63E0FF7EDA8AC14
+:10D65000DC81F7F2C0FB37D20CD251C51685E870D9
+:10D6600054B3DD18477C4CB1E2FA2A2CDE543CFF5F
+:10D670002AEC663B969F6F72DC7F06E4C38B4D738A
+:10D680002865DF02DC619E5721F260DFA7673B93CC
+:10D69000B2008E65AD65749F0CC970127F720ABAB4
+:10D6A0009B0B605690DFE8BBE2701FBE9329BE471C
+:10D6B0005AD32C44CF668670E83658D3705EDD1B93
+:10D6C000CC3A3C37E7DEC9E91AF699490FEDEFD2BB
+:10D6D000B360DCEF3DD81EC62B59AF2FDE0EF9919B
+:10D6E00026A60F8D44BACA24BA6ECF717E8DFCE097
+:10D6F000B35FB23C940BCAB76CA5F948BA60FACED6
+:10D70000C26128E7ED4CCAC2FBB5A4A3F69C997987
+:10D7100008BF7E7AB851213A80F4680AD1C3FC6907
+:10D72000583E77A637750DCCAB48AD650ED433C4E3
+:10D73000327B10CCBF8FF5923CD107F2049E6792EA
+:10D740009F48BE0174E03045FBF0BBAB09A6023C2C
+:10D7500079779389D2A79AAC4C0FF0DDDB144BF9A3
+:10D76000679A6C947A9AD2E9FBB34D76CA1F68CA5D
+:10D77000A3FCA12607E50F37CDA1F4C5A662FA2EBA
+:10D78000F912C085F890E42B921F497A927C299077
+:10D790008E4A01BC0559D49EF89EE477B80E5D967A
+:10D7A0008F1F49FC262BC5AED824E4635D4B905FE8
+:10D7B00014A9E7F73D0FF0EDABB2D8836C0817CE94
+:10D7C000F7FA2C263AE7138DEC30DEFF9B573BBA75
+:10D7D00037F99DAB3757294CEF47B7B7349899DEE7
+:10D7E0008F6E6F6D8CD0E44B1ADF7D3506FAFF47E4
+:10D7F000827335D2DFC93BCE3EF65FF0FD893BBE7A
+:10D80000188DF88679EC7C08C75D17DC3F8F48CC13
+:10D81000B718E89C1915CCEF49A382F93D09FF1010
+:10D820003FCB18DFA74FDCF137DAE7DD8D41361546
+:10D83000E50FC417C0F72F025FCB1A83088E651B54
+:10D840004EEF7B1EF7FB3A23F1BB652D627F6E0620
+:10D85000B8FAC96DA7E218C9678A83B14680DFA903
+:10D860005F1ABD70F6B3538AC9AD4043052E4D25EE
+:10D8700008D7CDBFFB00E56DA5F104C9C74E93C520
+:10D88000ABE2FC5C86F3FEFD298DAF513DD635320F
+:10D89000E26C086D4586700CC97118914F206D239C
+:10D8A000FE96A51F63B8BF59AB621D0DEBAA10DF32
+:10D8B0002B362B247748F83F92A5D2BE7A2F534FB0
+:10D8C0006936EED9E1C4C0E89C92740B7CC3E1C612
+:10D8D000FDD19A69ACF4E3C7CBC4F7F2741DA5F28D
+:10D8E000FB7BB02D914EB2114990DE9D9E6C5C4E3B
+:10D8F000FCCE66447E20EB2F4BCFDA989C83FDCC88
+:10D9000088627EFB7257969EDABD9769E5F331C156
+:10D910003906ED6A87380FA47CF219FE7332CD9F69
+:10D92000EE5FD5CF3CFDCC8BA897F82888F0547DCE
+:10D93000B5D06F64B8272E20B9C66151609DF5023D
+:10D94000FF854FFF35AC0BCA571DE0FA5348BB317A
+:10D95000AD5F5745FAB27AB88F1644227F359CEAFC
+:10D96000F2A3CB579EF928AC8BEE17AE785D2CA6B0
+:10D97000DE780669FD81D3B319F6C77A375A2D03CD
+:10D98000DBAD52BEA57BA65C47D191AFA2697CE519
+:10D990004A34D53FB2217A303DC82AA63FD5BF7F51
+:10D9A00049CFE0D0E8D556B12D975498EFAA7573BA
+:10D9B0003E453A0FACFF41566814D20F9BC42691E6
+:10D9C0001E43CF7488EF35260E873EF7E870F61DAC
+:10D9D000FA9755EDD00844AD3EBD2DDC0EF3ED6158
+:10D9E0006CCE607849C8E6E7F405D8470CEE523DA6
+:10D9F0007B55BA2FF4EC0D25FAAFDF7BFF6B53217B
+:10DA00005FBF43C161591DEB2438D51F5099C9FF31
+:10DA10003C43FDCEB0A1E759F3746803D2D34A8FDB
+:10DA2000E2D809F3E933D9C287FBCDE76F829E6A5A
+:10DA3000823C1309AE62FEBD829FC97A2B3BEE3752
+:10DA400022BEA0DE45925F7E1BC2486FC67AFF8071
+:10DA5000F33CB72DDB8EFABD959EFDF574FEEF0D00
+:10DA6000B18E86757C21F4FCB21F6336DF4FC66C25
+:10DA70002E6F9C13FADC73CFA8C487709EB80FBFBB
+:10DA80004039D76F9E16D1CE22E0F61CEEC75C5F00
+:10DA9000FD959EEEB054A8FFE9E177298DCEE6EB27
+:10DAA0005A69E99C80E7E6A70742E6B8297D74F643
+:10DAB0004B30DE05CF8C28C56F5FA5641B383EB6A2
+:10DAC000A973105ECC3D4CC8F91E5ACFB9BDF10AFE
+:10DAD000DD6F11DE20E79F3BF05C988EF6AD4B8347
+:10DAE000479D89EB6983226C42CE34B5A2BCB11448
+:10DAF000A4BB70E07775072ED1F91BF85DD6A7FDA2
+:10DB00001687F7EF5ED26BC09F0EE9B7CECA715E83
+:10DB1000A466C4E03E28BDDA76D3CDC8C7DE307037
+:10DB20003C8CB43D84F7AAD2B78791DE628DC116D2
+:10DB300083F92FDF848B20CCBB345BECEFD8AE5C59
+:10DB4000D4737627F173BD76335C54603D2300EFC8
+:10DB50002E5872AD5B654EC8ABE23E734D7632AD6A
+:10DB6000EF912A9DC34876166F1AEA3D4F1A994BDA
+:10DB70004579F95933B7072473BDFE2348EF90D692
+:10DB8000467AD386A1FE4BE0B1763E94FBE1B3F634
+:10DB9000496F1ACA2FE78D5CCF87E5564CB378BD25
+:10DBA000664137D80FF6DB9D64BD4872E6C15086EA
+:10DBB000F2BEEEF950AE57F88DF9C920BF737389E4
+:10DBC000A02B90995CB87ED74E3E3F9C17CACF2BB6
+:10DBD0008DAD69285FCA715786B5D278E7C5782BB5
+:10DBE000835BB97DC2C8F591589FC63730B2A3F4A4
+:10DBF000EE092239F58BB8CE4338FE177BC6323C8E
+:10DC0000C7BB93DC9587A91CE437C047F553415E39
+:10DC10009CEFE77B42DD0CEA7F6EE0F2D0E7A1D11A
+:10DC2000240F9D087DB094EC323B8214D4AB7CAEC3
+:10DC300030632C96EFE4768CEAA646B23F54C37666
+:10DC4000675994CE6191583E96F42D9FFF1EF6A918
+:10DC500042DF37E377276B2DBD1DF7DDEE10D2BB1A
+:10DC60007DF1D4FF1A3B98DDA27A8756BF24E940A4
+:10DC700096DF9ECDEF1BB767F37BC11DD9FC9CA936
+:10DC80000BF13C984CEBE4FB15F040F72ED81FD17C
+:10DC9000A8EF3EE979215AB1209CBD698F22DC773B
+:10DCA000F3FBCD177B0D6477A97E3ED4417A9C4D62
+:10DCB0009374785E54AB5C0EAED601F82055EED866
+:10DCC0009D867276F31E7316C203E04DF7C8DE9D83
+:10DCD000AA18878FFBF9AE04AED7F78AFCA1F1A48E
+:10DCE000D79F1BC96E9D4F72CEB60908D7CB3B425A
+:10DCF000744817308E4301F854DFFE0B0ECFF04A04
+:10DD000092CB61FF11BFAC15FCB26ED3D4F0A9B8B1
+:10DD10009FDE5619CA0597F5F618E48781F07A4B0D
+:10DD2000F0959A438F19D16E570BFBC609FBA64697
+:10DD3000D8C76A9E5248AEABD938F521E2837F300E
+:10DD4000B0D1308FF39EFBC3FCF1F1BCE067BEF6AF
+:10DD500076AA5F03F579FB37C2683EBB0C769C4F11
+:10DD6000201E7F70FBA7D41FD4BE9F3E3C70AE4FD9
+:10DD700018B8EECBACF3DF3E427EB2D74CFA2BC0E4
+:10DD80007B22CA1DE70C9E4A5CF7B97D66E233E749
+:10DD900022F87EFF14F8A16B0CCEE3BAFB48BFF16A
+:10DDA000CE0286E7C10AB7B65F396E87E0BF75C39A
+:10DDB000ECE1A827AB033C607F80979F52FBB70D37
+:10DDC000D43E701D8F8A76FDFB735F08D1CBB911ED
+:10DDD0001C1FE79E1943E74A7704A773986F22DE5A
+:10DDE00057CE45F094A1300274502DEEA3E766782B
+:10DDF000E8FE7D4ED94F69B781B7AB6E147663A04C
+:10DE0000BB58A41BA449B48799B674A23C81FAEA12
+:10DE10008959947A832207EA9D913EF11C8ACAE1CE
+:10DE2000FB8BE178D1C2FE41728AC7887CD929E494
+:10DE3000B8DABD03ED7088DFDABD0AD9912E8B7395
+:10DE400010671D25F5E5408F352EC561C6F9B4ACC8
+:10DE50005E4976A486AD3723BDCB75D4E8D91CBC0A
+:10DE60000F752B2ACDA7DB0CFB06E1E03F9E9FDC64
+:10DE7000F577C10FF0CF1A4D722609D7BA1C1BA730
+:10DE80001FC8B6427FB52DCA161A2749DE2BF9FAEC
+:10DE9000249C002C46D497C17D9F970FB17E39CF2B
+:10DEA000C0F5CBF944E770FEDE9D64BB2F1FF1FD8A
+:10DEB000966AC77BFAE56FB3C323BF432EC39B5B50
+:10DEC000BFDE18E69F823405EB3A8BFC0DF733EA90
+:10DED000A5619E69DBB4F690F41DDAFC557BB5F9BB
+:10DEE0008C03DAFC840E6DDEFE8A361F22C6957026
+:10DEF000C27BAF6D0CBFF7628AF75E5B10BFF76243
+:10DF00001EEFBD98E2BD17BFE3BD17F378EFC53C28
+:10DF1000DE7B318FF75E4CF1DE8BDF6F1470AA155C
+:10DF20007A47C403DA65D80B666967A7FDD2B324C4
+:10DF30009AF8A7B493F6ACCCA07CBF5E679E89F438
+:10DF40003AA4BB01B964C1486741CE70B49F766EF4
+:10DF50008C43BCE9BB489FBBEA45AECFADCD325B3D
+:10DF600050CFD0B5E1D38D283EA58D74CECA81F5B2
+:10DF7000F6187A77111DE8BDC437BAD6DBDE9ECE1F
+:10DF8000F147FA0E6689A4FB49199E779143E33164
+:10DF9000D0AEC2B668ED28817695407B4A201D48F8
+:10DFA0003BCA1386DE38E4F7A7F798B6E0FC4F0BC0
+:10DFB0003D195B6C22F94BCAD545AA85E0B4E65EF3
+:10DFC000E5493CA72A7222A97DDF0990B707396F7E
+:10DFD000655A7E259BE4EAFEFC164547761AA78320
+:10DFE000CEA1DBC49C1295DEEE4D4823A13A3AC780
+:10DFF0002F5B74742FB8FC2795E48831ED3ACD7A05
+:10E00000C6BA8335F4356E7764803D7084A6FED53C
+:10E01000879303EC815769ED5437AE3F8AF7EB05E0
+:10E020005BB235F52A8AA706C051CC5BC8A5CDEBFB
+:10E03000DA1391FFDC16DA47F3BFEDA099FC2E2A24
+:10E04000E07C71C0BAAB3003FCB1CAE4B801E1575F
+:10E05000E53144A05EAB5C9C3FAC517B1E57E99917
+:10E06000CB1AE9A3BB2A2B734440FB0B99ADBB74BD
+:10E0700080B70BBA6D0FE6DBD0BEB43DD10A74B5E4
+:10E0800056F1444F86FE4E4738FF03E933D1E0FD99
+:10E090005509F2CBFD296C3DD43BBDE5B93092BBAF
+:10E0A000059D251AACC188EFEDAD2ADD0B503F85EB
+:10E0B000FA20490FDB5B8705A75A7CEBF4E1FF5B95
+:10E0C0005A1FE085FC46FA2CC746DE86729C87AF55
+:10E0D000B76A86E2223959AC678D3857580BEF671B
+:10E0E000ADC89F11F705B9BEF3638F4EB0A15DB304
+:10E0F000E970A28A7C5CB777571CCA1731CE7DB80D
+:10E100007FAAB68FFEAF7C18B7FA3D95A11DF99393
+:10E11000B659619351FEDC67B0CF85FCA6D65F1B74
+:10E12000F15E50AD771BF1DE59B567BB11EDFF3FD6
+:10E13000D9BD9DBE57EE2EA3FBF60AD640F7C8CF39
+:10E140000CFC9C96F0A89AA96CB3C2BC87E772B984
+:10E15000AF2A98FB8314A9F9AF46E17A772B99B8D7
+:10E16000DE1B8BF71BCBE0FBEF047F09DC1F7D6F11
+:10E170002E281A8E7A250FB7830EB51F167AC7D2AE
+:10E180007E58702589D21BAF8CA37BD57BAC783CA5
+:10E19000F1898C80FBEC9B2AD79B75F07D5065F450
+:10E1A000462DC07DF2B281F6491DF0AFBC2CBC27D4
+:10E1B000333605D2E27C5543AFAB0A4334F4BC9806
+:10E1C000456AECCA8BD8084DFEC6B9299AFA37DDE4
+:10E1D000382E80FEB37CE5C447A668FC57EAD6B962
+:10E1E0006C0AE9D1666ABF43BA8EE8EC5A4DFB3A35
+:10E1F00036DF570FEFC13BFE487066ACD388F7ADF2
+:10E200002A1DF7D759ECEC16DFBBE83B2C44B30FC3
+:10E2100047A5D8FF8B9F8B06D2CF4BFDF462FC77CE
+:10E22000CA60E722205A8C1BAE72FD82532B777492
+:10E23000D2FD93713CD4097D4F5D3AD7F7D4B93AFA
+:10E240008D0D1682BF3E1E4052DFAA903E0FEA9B04
+:10E25000E223797E1D7E3F60F0E95918EFEF0A96C0
+:10E260009F50CB70BF0496D7C3BA51CEA8477D0D3F
+:10E27000E999E67C4A7A26398EE85FD2E98A76AD5A
+:10E28000FEA81EF53A7EF85C9A6B237AADDEBDFFE0
+:10E29000B511009F05C51199B88F6A3DF30C65193A
+:10E2A00003E94DF2F9CB553AB27BF7BD799CE8AD65
+:10E2B000AF4A4F74FD7D70A97770BD66201D56C2B0
+:10E2C000BA4C307EE501C5EE56783D84CF08A4CF28
+:10E2D00000F8C40F023709AF7EF80594AFC07FE4A1
+:10E2E000A03F81E2F6260D06970078CA7102E0C5CC
+:10E2F000F2B4F0A874DADE46FE53794265EE1FB040
+:10E30000FE15B84E9C07AC13E731FF0AD79B487B3C
+:10E31000C2A22B7ACAF7D34D31C02B0BF79D769F43
+:10E32000F6D35131DF370BAF4453BB1F8B9EBE8FEB
+:10E330008EE4FC25DFF6EDA33B896F3A7343A3CE51
+:10E3400002AB807FE7125F10FC7568B9D4C5F9A8ED
+:10E35000537BCE8CBA238FFC8EFA2CC92457F49FA2
+:10E3600043566DF99AD0E4182C770ABD9DE4C74E48
+:10E37000514F8E5306E5B66148D723A3511FBBB159
+:10E380002525B1CB4F5E716E3044A3BE3071FD3098
+:10E390004ACBCCD6683C47CAD6ABC5783E9EBA2B92
+:10E3A000263A0FF5F31B0C5173A1EB533FCF496491
+:10E3B000E3315F44E9E9AD418BFDF5DC32BD4B9CB7
+:10E3C0002775777C40E7DA05DD9B618B71DF6D385F
+:10E3D0001886AE37351BDE9D6805916453847373D0
+:10E3E0002ED951B7EFB222DCACDB27A09EBA1DEFCD
+:10E3F0001EC37DF243F586A218D48BD5FEFDF8E34B
+:10E4000078EE3BD71BA251FEFCFC4F702E2A74AE57
+:10E4100091DCF09999D17DE9B39D216EB4DF7FA69F
+:10E420003007DA7756AA47275835E76CC7229CC7CA
+:10E43000EE18673B1FDFBD2B16C7B7BBC83FD3B96C
+:10E440007E74F8607A1499AE6AE772DD2EA9C7155A
+:10E45000FA5E94E7318FF23C1BC3E579CCA33C8F85
+:10E4600029CAF3F8FD90D0E38F6AEECDC4FBA86B08
+:10E47000264B6FA073D7928EF2FA6D4AB01DF9CF7A
+:10E480006D8A3D06F563EC4F11FCBC0DC0AF4CA787
+:10E49000F582CCE547F7D3AF9898BF9FD90C16A16A
+:10E4A000C9CF32C569EA17599334E53F891DAB29B5
+:10E4B000BFC696A9C95F973E5953FF7AFB0C4DFE24
+:10E4C000A779D768EACF73CCD3E417CC59A2A9BFF8
+:10E4D000B0B84C537ED3E2959AF225CED59AFCCDB6
+:10E4E000553FD7D4BFA561BDA6DCC1AC7A3CF73A95
+:10E4F000F09E05707F19EF5990DEF6D6688B3F5E6F
+:10E50000F367E91A06D3D37F2CE8376392E343A479
+:10E510008F041DA743481D28425C10E74A3CF32A9C
+:10E52000FC9EDB19877413582FB03C3FE4D8651B61
+:10E53000E0F0A6892137EB813FE44F3A969D02F93E
+:10E54000270ECDE3F9A9C79E4B86FC6F26DEC7F3E5
+:10E55000571FBB8CE5A39E5F74B31EF84EFE0246A8
+:10E5600022C77387BE5EEA8275E44F4FDE62E77AA8
+:10E570009241FD34FBF52C0007F46F443860EA0546
+:10E58000FAC4F418D027A6AF007D5618187B0DE802
+:10E5900013D31370DFC4EFAFC37D13D337E1BE894C
+:10E5A000E91FE0BE896927DC37317DA76931A57F86
+:10E5B0006A7252BBF79BAA28FDA0A981BE7FD8D45E
+:10E5C00048E95F9A5CF4DD3C51EA2FBCA47F917668
+:10E5D000A67AB4EFA17EEEB0E1BCBF1D56DA09A564
+:10E5E0005DB0B9817585E03EEDD2479C35F9EC7D93
+:10E5F00043F3593D3BEB27876D8D75444D24BDC6D4
+:10E60000482BD97BC4F799CA820434FDCD9DE01C08
+:10E6100081E50BB3CA378403FF98FE6D8301E9E5FA
+:10E620003DE1A71AD8FF855C2E0F1B2639464D8485
+:10E63000B4C0C4FDF00A4CDCCFAE40DFD58CFCA8E2
+:10E64000F92B66433F9AA3A146E24FCD77E9DDA8B7
+:10E65000A754BE64949F16C528DFFC5527F9E5151D
+:10E6600058EDB174DE887CBFFD1CFFFCFC65A43D49
+:10E670005BFAC9147ED9350BE5806916A32D28C035
+:10E68000FE8E76EBA3A1EFCBF9301C4FDAC9777C75
+:10E69000C5BCBA093E7B7881A93309F504D3D69A63
+:10E6A000ECFEFE3FD2EEAD7CD9A9E27922FD7CE4FE
+:10E6B0003872BEA17AE82FCBE7C75360F564A25F3A
+:10E6C00043739D85FA8B81EFC62CAAE750A99D273D
+:10E6D00013F5C0D36A2D76D46F4B7B7B8C5837D41F
+:10E6E000A375167EE9247F8369C2DF00FB31F172D6
+:10E6F00017F6332DCA1BA7C7F53718EDA80F7D4CA9
+:10E7000081F6593EFB3FD60FF1DBBF384FEC37F5B2
+:10E710006B982FCAED0E07C17781BCBFD9445E9CB0
+:10E72000CFCC3493F457AAC81F9BE07422DE8B83AE
+:10E73000AC7F0DA17D9E92807A8E79426EFF0E7A1B
+:10E74000598E74F6DFA71707C7F74846FAB440BAE0
+:10E75000917891781E8A8E24DEFDFCB508CFFDFEEF
+:10E7600057A29F40FA1A8AAE243D159838DE11AFA1
+:10E77000E84723E948F9D2B39DD6516BA2734ED234
+:10E7800051201D0CA4234E97CD3F33517F03E9C880
+:10E79000877F84C7BF4E479D2A9EBBFF2CFDDCDAD6
+:10E7A000CB668743D12FAE765EC8457FA02BB6D708
+:10E7B000305FCE66CC469292E52D439407D297AC5B
+:10E7C000FF34D6CF1D58DFF965AF21DC8F2EA78926
+:10E7D00033F0F521FA7F43F8C5BF6196FE1E0E4B5C
+:10E7E00026D0C12CC1876F2BE2F4352749257BC683
+:10E7F000AC8C1524DF330B978F6DF03FD2B709FB3C
+:10E80000FAB5A2DDEC6F8B5B709CD9515AF9FB5ABB
+:10E810002177CF09B0B75F9BF11392C3AF0D90B3CF
+:10E820007F3F51C8D1492C89DFAFB790FC5B28F6F8
+:10E8300063BCC0778A4D65F900F722E6D4E321F086
+:10E84000CA45A303FBFB097351FE1AE6A6F43AE698
+:10E850002539E07A383030FF53D87A983F1E72431A
+:10E86000C92AE86F56F6AC54FC5E6BEA4D34EAD028
+:10E870003BD0F921EEE77AD5F931CA9917129C639A
+:10E88000F07E7CACD04672D831530AC985B89F0C53
+:10E890007EFACADFC3399A0AE7DC713867317D1521
+:10E8A000CED95438EF7E07E72CE6AF4D5FCFB0DD11
+:10E8B0006C9BD6BF47B6BFCE3A8BE9870D7D8E5D88
+:10E8C00037E18591A8C77A23624C21E2ED8D884912
+:10E8D00085B8DE372262743C0D32523AFEF9D4C15B
+:10E8E000E45649AFBEF166D37881F095F00C84A36D
+:10E8F00084EFBF004FFDA4DC81F0BC806730EA4F9D
+:10E900004DEF86C526A39D51C4D385703E58F7FCB4
+:10E91000F8185C47AD89C3655AE3544A0B1A27338C
+:10E920007D36D9995C08DFCF7109A8700ED0B3315C
+:10E93000FD4CCAFF4CD0567A8C331AE7713ECB9B04
+:10E94000061219FB745B7318FA675E7846B5E3BD6F
+:10E95000A656B56DB1A39EFC0D95C7057D7B3C11F8
+:10E96000ED9B6CC7E0FED2B526093F17C1B5ED6A35
+:10E9700007ED3786D6D9689F5C333288FB199379C7
+:10E98000216B6839676230E7332383387F94F882DC
+:10E9900076FCDC857E26025F8BBF2F98EE3579A34F
+:10E9A0001CE3713DAC9069EE05527FD117A5D2F9F9
+:10E9B00050C0D21EC2FB7BE10903DDDFFB0A192F29
+:10E9C0008FE5F6CABE139755DCEF45A10A1B96E406
+:10E9D0008B9B098AD5319B9F3C6DB605339B1FDD10
+:10E9E00086A4476AF2A1F6119AFAE179C99AF20867
+:10E9F000C7559AF26173B234F9E1C55334F5631621
+:10EA0000CFD4E4E39CD76AEAC757CDD7E4253F8A41
+:10EA1000E79F5842C3524DFB518DCB34F5935CD5E3
+:10EA20009A723538EC498A3B75393AD3A3915FF134
+:10EA3000BF94CD6B34F51E0DE37120732C9573716B
+:10EA40001F8E6EBD5D3B2FF54D85E23A6D9C0FBA72
+:10EA5000E07F88DFA2582D5F9C65D5EA1BE21BF49E
+:10EA60009A7CF524E18F34814D203EF87D78765EE6
+:10EA7000A5C173203C00EF762FD68773D505F9A288
+:10EA8000DF97EBF1DC47BB82FFFCD1AEE0BF5EB4A9
+:10EA90002BF8E7D1AEE05F1FED0AFEE56857F02FD7
+:10EAA000CF3EA1C5736EA716CF933ED0E259D2DFF9
+:10EAB00050F898DCA5A583407C4CFD2C802E041ECC
+:10EAC00016C3FF06C3035D1180FE673530D29B7D00
+:10EAD0001F5E1E9B24CE278117C003C5F5F58D0C44
+:10EAE000253C3C26E65FE01D4771B145A8374BF257
+:10EAF000ADE73171EEFE769873F724D8DFBFB365CA
+:10EB0000C5223F9ACEB85D7376ADCEEE85EE9F0AF4
+:10EB1000C0FF84B1CE7D587FF1B0CB8946A4875E1B
+:10EB2000E718BC4F7E28F424817E9C2E1007280E07
+:10EB3000E17695E26F4EEA5A15E4CBDE04E721E474
+:10EB40001BB76634109DC6B2E2FD9530BFD2FF0CF4
+:10EB5000223B4EE9281EAFCB32BA28CE41F2BBD2BF
+:10EB600078EE47F4F2246117B6737FA2A393B83C02
+:10EB70001B6AB792DF7159068FE3806B5762E978A1
+:10EB800084CF9BE631089F366E37E9C278E1285F73
+:10EB9000BC30CA9B28DF2508F9AAF9CF2613AE633B
+:10EBA0004C3BD39C9363DD268DDFEBB8DD564D7E69
+:10EBB000BC275653FFEAC3364D79A6375D539E7D79
+:10EBC000C2AEC9E776E669EA4FFAC0A1C94FEE9A2C
+:10EBD000A3A93FF5B3624D3E9EF53E8CF01DA5F016
+:10EBE000FBFE3793B8FF14EC55B2E3956E8AE071E3
+:10EBF000A0420F20E569E90FED14F41D28A78F321C
+:10EC00007239B5398EF17B9849DCB798565E770A30
+:10EC10007F6629A73297D69F59FA31F7CBF5426E16
+:10EC200097F2B19F1FB3C3DF8FB954C46F079E7FA4
+:10EC3000863CAE1F099CFF28235F6FF3CF8D1437EE
+:10EC400022E715381F6716A7DB9DA6C1E37786E587
+:10EC5000713DC1F8CCE2903C481F37D8DDA447197C
+:10EC6000309EBDCB85F7CA5F1AED77DABE7FBCD286
+:10EC7000ABF97A4A74BA5BE76590BFD8E267FDC624
+:10EC80004F11E3064D51065D5F6938F7E762E146D3
+:10EC90001BD2EFD0E37178C61A590BC51909BFFF13
+:10ECA0005BB678EE1D034525C65603292F98DB80F9
+:10ECB000F4307726C853998C1DDAFFEC2316906741
+:10ECC0001E6FD4939EE7AAC33125AE545F1CC7289C
+:10ECD000B86F207DA0CC82F7944727737FE5EBF2D5
+:10ECE000F8FA8AD46FFBFDEFC97EC198382718F96E
+:10ECF000C30C426F4487721D3F963FBEA4DB403871
+:10ED0000C9FB2513FE8EA9625E127E723F48F8C9C8
+:10ED10007808DB6A43F193168AAB98837E64127F8E
+:10ED2000BF9DCCF9D12F053CB01EF2A3A1EA15A9D5
+:10ED300019E1A80FEF63B670EB77E87B7FC4380565
+:10ED400082FF50F15543F187017C618878ABA1E8DF
+:10ED500093FEFE89B82B3FFEC0FD7A043EDCA93A43
+:10ED6000B2A36F0AD5EEE3A7047F9827F6139CE3BE
+:10ED7000964C2D9F60A8BF6FDEA00A3EC1CF6F9456
+:10ED80006BF0FBF20D063A4F192B7E10E3883E69BB
+:10ED900033907F6B81C336DBCEEDF324DF90DD0B48
+:10EDA000A656E6D29EDB20473C89F789E9CCBE1106
+:10EDB000ED19E59BB5E52B2CB33F47B96179C0BD93
+:10EDC0007485B8AFAE08B8976ECB13E7B19DD9493B
+:10EDD0001E1376FE2A51A79F8EDC29E142EF42FBEB
+:10EDE0001352F20B9370B1A1BD26DB9707F805A76C
+:10EDF000E339DDA21FD45FAF1F7E43F8239C477F1A
+:10EE0000041BEEF73E8AB7EA3B60E6764A690F12CA
+:10EE1000F5CFBB2E5339D6C7DE2E64764E4079A788
+:10EE2000DF7E146087EAB3E8C2F2B0BFBD06EA4FE6
+:10EE3000FA5B54FFCD3DC1EA674F7676A91AFF967B
+:10EE4000C0D4B9FE20F95F6C8A70BE8A7CFC9CDE5F
+:10EE50006E42FCDD6539168D71F27385DE2670BE5B
+:10EE6000FDF26DBEC2EDB02E1E37DB3747213F00ED
+:10EE7000E0830CF78DF41B98C7BC51984A7B8C73C8
+:10EE8000F36482B3B4C7947927D33C1736AF300408
+:10EE90004395AE87D71505DB7C769AAE04EEF73343
+:10EEA00094BD66C1954CEAEFC62B53A99F337949AF
+:10EEB0005CEE6AB97735D2D155BB9901D7D915E047
+:10EEC000F72ED31B27F3FDB01A633172FDFC89D6F0
+:10EED0002B44E76B1426FD8B884FCBFCE556912F16
+:10EEE000E2F9DB36F07C9781BF33B34BE81B709DB2
+:10EEF00098E27AF05EBC57E823701D98E23AF03B46
+:10EF0000F225CC235FC23CF225CC235FC214F91258
+:10EF10007E5FC68A1333556E572AF4DB3768572A4B
+:10EF2000F4937BD0AEE49F47BB927F7DB42BF997DF
+:10EF3000A35DC9BF1CED4AFE79B42BF9D747BB923C
+:10EF40007F9EE55DE3CB231F73CCD3E417809C5FEA
+:10EF5000E8B76FD1AEE4DF3FDA9534FD39576BDAAD
+:10EF6000DFCC1A35EDD1AEE45FFFD646456377BA04
+:10EF700055BC0750DE3E8CE863EF84E2A4C980DF15
+:10EF80008F43FEFE3303DE37D48E9548B76BEA829B
+:10EF9000ED1CCFAD7338DE758CE3B97709E1799D4F
+:10EFA00091E78BB8FFF160F69B4203B7DF608AF60A
+:10EFB0001B4CD17E8329DA6F0A4773FB0DA668BF0D
+:10EFC000C1EF68BFC114ED3798A2FD0653B4DF60EE
+:10EFD0008AF61B4CD17E83EDD07E8329DA6FF03B1D
+:10EFE000DA6F3045FB0D7E3F897624BF7733504E74
+:10EFF0004FD5DC1F810E35F747AB268F72BA7F7D68
+:10F0000094D3FDCB514EF72F4739DD3F8F72BA7F36
+:10F010007D94D3FDF3CBF36CB4BF505EF76F87F2F2
+:10F02000BA7F7E7CABEB55D41D5DBFEDE22B9876AD
+:10F03000852A8F2BC00A964DDE578276B62EB39264
+:10F0400018019CD2B0FED99242D8B34EE1C73781A5
+:10F05000F5EA10DF646707BC39BD8CFC8EC77F13EF
+:10F0600047E5D2AE4B7F80F7CC038CE4FE43225EB3
+:10F0700053B6B733AB8AA9ACEFCB0F5E2F707C5978
+:10F080008FF8A5DF3CE06298897E2699EB2C59E841
+:10F090002FBF4BA7707FD33BB9BF6F205D3D28E4E6
+:10F0A000A05DBAFDC782D17FA84CB1631C439A9E74
+:10F0B0009D3064219C1AB2503EB8637284F0076E92
+:10F0C0009882FE4772DE520F087C82E2D7F27B996B
+:10F0D000B102C699F625332E47FE6EE47201B6C31F
+:10F0E000FBE23897E278D28FBE374FE6E79BD3B585
+:10F0F0007A4A057C1FB7B7610AC6C5CD0DE6ED7E1D
+:10F10000F34418C1F18616E5498C3FCCDFCB1C18BF
+:10F11000EFBA55F0D3717BADC60A1AD74AF174B273
+:10F12000DFB26D8914FF57C6BA0A31BE82E5280CDA
+:10F13000EDA3126EB0BE57707D69B0550C247FF2FE
+:10F14000B89C60119723E37182228A17E6E5FAE200
+:10F1500072A6E54414A15F1CEB60760C03BE3EA7CB
+:10F160006CC370E8DFE976D8D1AF68DA970DAF529B
+:10F170007E4731E5890C26D23874AE8D7129F4BEF4
+:10F18000C60DAEEDBA281BC6EBAE374463FDBDCC51
+:10F190008EE20E1C3514772AE797C13A756605F1A1
+:10F1A000CE8E0FF3A323E0003722DE33ED067A7F05
+:10F1B000639EDE6A40BE11788E0FF45B0C901302E2
+:10F1C000FC4B9AD77D90A826A37F89CEEE45BE75CD
+:10F1D0003084E40529EF94097FB3CB2DAF0EBF092E
+:10F1E000CACBF673F9C0D9AE10FF93FE267529EE8F
+:10F1F000441DCA0B23B64F8854F9F98F7CF19CEB60
+:10F20000B945B845CB36BC4A7111651B72C3795CF0
+:10F2100014B7435408385508BF2296618D4639F318
+:10F2200014F01DC718F24B0CA7B8C2562ECF49BD1B
+:10F230008E9407E5FB31656F65BF86782F7B4CBCEC
+:10F24000CBB2B98CE2AF02FD7C6A84BCB7B2C540D8
+:10F25000FE432B03E4C11AE12F5413200F9E9C2C74
+:10F26000F440521E14F717E9CF5BF6D6F18524AFB0
+:10F270003418C82E57B29ECB2F6C3F73633C43C9E2
+:10F28000FA593A7C37A4E4A0C3AE0C42276F0B397D
+:10F29000666E9799E03AFF4A3CA58BAEC4517AD38B
+:10F2A00015EE4789B12F48075D2F3092A3DF157205
+:10F2B000CB42F4ABC478445790F09F642437653256
+:10F2C0006B11F28FAB1CCA7114FBE61A9C1BD06F3A
+:10F2D00073EE7646F147D7A37C03FD2F467907F5F9
+:10F2E000EE39494514873147A17896EB73560BFAEE
+:10F2F000067A6748EF2E41BFC594EF3F17049D3B48
+:10F300005DDD7A84FBF52EC588EFF039C53D56D218
+:10F310007120BD978608FD9385EB97FAF54F385914
+:10F320007AD4C6740BFAB796A26E7004E388079875
+:10F330008766F0F2D829A65B5AF052F3DFD44B94DB
+:10F34000E8743CDE09E42DE4ABB7ACCD342EF3E336
+:10F350002F9F4C9D39696AAE0FEFCB02E2F4D6DCE9
+:10F36000353AE6BBE245CB01CEB84F4AC3BB7E0679
+:10F3700014CAF2A6304721889E4B985C27F3A25FFF
+:10F38000E052915F3E25F3AF9B33083E94CF793135
+:10F39000FA1617F155CEB76E46BEA522BF72664D5E
+:10F3A000217ED5351BF11192D12BDE21E0F10E81AA
+:10F3B0007A88E553381E02F511E5199C9F33BD2D5F
+:10F3C000F1668A0BB6913E4FCEFF94411BA729D31D
+:10F3D0005BA670BEFC63C537FCAF14E70DB8BE0773
+:10F3E000753C6E7E84DACA845E88F6BFE41F4CBC2E
+:10F3F00023E1C33FC869644757ACFEF8776E56787F
+:10F400009CFA10FA1B96DEFBF04ED4DF351919C6B4
+:10F41000B93E91C6E9E889DB8D248797183B5FC523
+:10F4200077B2241C3F6AFC0F03E9FF997734BEFFD3
+:10F43000B5B4C16C47FEFCC9D4E28A29C3111F765A
+:10F44000C2C724D866D8FFC984E215F8BD6ECBD1F7
+:10F45000C7316E7F554712C591961DCEDC88EF8966
+:10F460007C32D5598BEB2DB3588D788ED7B744D0DD
+:10F47000B9561A23E23A592FD9A924FC5BA6F0F316
+:10F48000744A3EEFBF47DC479061CED3D4137EDC95
+:10F4900001FB44EA0503F50B81EF380CB57FA41E90
+:10F4A00001F506463FBDA2D44B18D24F2DC173B40F
+:10F4B000C4A88D3F94E941A97713F7C1E5FDE7584A
+:10F4C000C6EC18949BB72A563CC72A2CB69B2643F9
+:10F4D000BEE284013D30D9DC481B7FBFE32EFE7EB7
+:10F4E000C732D8AFC86F4A843F5645FB64DA6F1500
+:10F4F0006E48B387DE97376F3D9EF002D28FD741BB
+:10F5000071F915568731D26FDF97B72A9AB87E996D
+:10F51000DF3945A5799780988EF0BB656D9211DF34
+:10F52000D02901F102FDFB0E4EB169E2AAA11EF93C
+:10F5300035CC4D66AFF1F79360DE497CBC2CBFFE45
+:10F5400097B56ADF2780FA2417FD764A28E1AFCC09
+:10F550000AEB4EC2D44AF30438109C7AEF85FE6C55
+:10F56000340EE1A3DCEB36E0BDBB04FD2920BFD4A3
+:10F57000EA36E038CB5AF87B21CE2D7C1CE7E60832
+:10F58000E378949BF4566302C20F2FCB51343FE2D1
+:10F59000831500178CB792719781F02913F3AD682A
+:10F5A0008DD0CA63AD5B0D888F2543BC57D02DE845
+:10F5B0007659CB0C8A37AFD03B289EC129E0FBC9D6
+:10F5C0006AF3DD681758D2F6902109F27F14F4DB54
+:10F5D0002DF6DDDC64EF687A1768B5D98EF35C62CE
+:10F5E0006DA5F5F5C3F701808782EFCF14137C81F9
+:10F5F0002E5CE89F57D1A6C5A76F3E1CBE156D6552
+:10F60000B4DF2AF54EA3D57F1EED4747A31FCA12CC
+:10F61000D8DFF8DE11B33A29BEE9EC033725D23A38
+:10F62000619EE40765B7CDC6777E804E888E25BD86
+:10F63000C8B86C39DE3753785CE637DFBB2F1D2442
+:10F64000D734037E51DF3DD4BE346260178C6BAC7F
+:10F65000E0EFAF05EE53B93FFBED07629FCAFDFB3C
+:10F66000B8A1D81BABF8F80C9CB70DCF0E02A74978
+:10F6700053F97C970ABC025C5FF18FE3B24DE578E9
+:10F680002D49D6EE77EC0FFB0D93E533BDA331EE9C
+:10F6900052D697E39644F27648F7486F61623CACE5
+:10F6A000BF86EA6BE351CAFBF9C5DE0DD1C82FF660
+:10F6B0002B24F7AEB9F778C2BFA33CBB8FCBB3E71F
+:10F6C0006A77D6C7A1DCA87727FABF8B55E1E5FC9E
+:10F6D0006139C83FC82F2AC539BD2FCB9930D5CF46
+:10F6E0007FA2E2FE7D694ECE5FBCC85FFEB2EFA591
+:10F6F000F7A6D87CE7A79CFFB2CD7F349459FCE1F4
+:10F70000C5D777777A1FC5D9955B8C36F45F2E6F96
+:10F7100029237ECB62E15EA1F8F01D4807652D0A22
+:10F72000BD2F56DE38D1ADFE5FE4CBE55BE6D19B65
+:10F7300048124FF2BD13799ECAF93BC4FC970A3AAE
+:10F740009E3595EFBFA55549C64ADAF749C672A45A
+:10F750007F51BEA442FBBD1F4FFD76EC8C8DB83FA0
+:10F76000306E88EE275B0C5CCFB73794E4D5736BB3
+:10F770009EFFC322A8F7C583DB13513E91F35821A6
+:10F78000F479CB855EAE52C8AD80A7F953FDF8EC95
+:10F790008A27389ECA9F79EBAFF82E5749B2E067A7
+:10F7A000F7F278FE659EFD84B7259BB71A92105F2D
+:10F7B000F848AD5FFBF206B8E8023C976EDE6E409B
+:10F7C0003EB04CAE3780DE4B84BFAF842B9E3B8A6D
+:10F7D0009FDD42D647FEB71FC659BBDA1C86FA69C1
+:10F7E00039CE3D53B9DC54DE101189E3953794FDD1
+:10F7F0000AEF1D92DF07EEBBD366BE1F96417FB8AE
+:10F800002F4FCFB0535C33DAB5063B57EF9CCACFCE
+:10F81000D5470DFCFDC6F810CF1E8443FCAA603B03
+:10F82000F287D4D42EB21B233DE3BC8D3AFEDE63B7
+:10F830006A6DD7259C0788D4E49F8229BE33852230
+:10F840007634E49FD4F1F8AB6495A7BB057CA0DCCB
+:10F850008BE52CAA8BDE9DEB7F3729805E8D6CC7F4
+:10F86000667CEFC618C5ECCD361F7DCA7E247D4A66
+:10F87000FA1D6A7DEE1FB8BED349421F916E4FC478
+:10F880003895D2FBC6D8513FF37DEB348AF707FB9E
+:10F89000D70BC49A1739C87A53F9BD65E8F5B61580
+:10F8A000450FB2DEC075CA7D227DDAFBED0BADDC03
+:10F8B000BE705A81F30BDA9D5E6D26FF2FB92EA91B
+:10F8C000FFFEA17108AF4C8D147A9DAE5094234B6E
+:10F8D00082C5FEF7F23C7E9FE7F75D9EFBF2BD36E8
+:10F8E000C99FCF3488739175DD8BFB9935A6D0FB0A
+:10F8F00024275B4F87E27B29A767F0F9C9766B0D58
+:10F900003CCE98851A6DF8FE21DCAF4E36A2DDA7FD
+:10F910002586EE91B734A6105FB8C515C1F50F4224
+:10F92000BEAF147C30646DD9467CE77B797B925501
+:10F930008171965BEC67DBA9FD383BCA83216DF3CF
+:10F940008CC924F7F27B80B413AD555831C58D2195
+:10F950009FC4FDA53B9A8AE7CE8A767E0F98AB635B
+:10F960009BD14E38AAB978761CF28987158A3367FD
+:10F97000DBB4EF58A567177F4CF7BF8077E0D61A46
+:10F980003C8E18E4E3206FA0BE69B9A598E4F65256
+:10F99000412727DBBAE93D7A09D701F13F461E0727
+:10F9A000DC1BAA233DDC0F8D03AA1076254937D234
+:10F9B0002EF508FE6732C249A573AD482DA1F79414
+:10F9C00036B6CDA2B4626BD183AEF1187F5C1C3D1C
+:10F9D00085E66D203D5945DD2C1EAFFB645004DEED
+:10F9E0006F120DAE447FB9B462FB268AFFF96CBB7F
+:10F9F00099E27F0AADF30A23A2E8BD638AAF93F5CB
+:10FA0000C2F3F979515D374B13BFB31CFAC4773693
+:10FA1000BFF284901F9A8CCBA98D7106E7E7F2F8AC
+:10FA20009CC9361E971347F56D83EAC5657AB6897A
+:10FA3000C779F8C51BDDB004DAD7D63D1786FDD4EB
+:10FA40003CF0EE44AB8EF450D1F9C3FDE28DDA798F
+:10FA5000BC518CB82FCD8D2C5EB404E1FF7B95E0BA
+:10FA60003FD4785587158D1DEF167738C9AD4E2FC9
+:10FA700033A21DD9696524177FA6B2469403A4FC5E
+:10FA800022BF5F95CFF9D567E1AD89481F2B773D40
+:10FA90009488E7CBE7A13C5FB2EBA6D7915F3977BB
+:10FAA0000471F95CCF481E2E7771F99A5545CAF753
+:10FAB00048CDA5404739F921FCDDA3766DBCB97C62
+:10FAC000E7F6733D7F9F07E38D90DE3FD27B972360
+:10FAD0007E3F02F915EFB1E1F99C3E3F6A5567930D
+:10FAE000DF106C1494433E6A7D2E14E3A1A5BC562E
+:10FAF000A4FEC581EFFFAC39C8E382F17D7A7A2B91
+:10FB000054E841EA851E64CD0B86D9F151247FD19A
+:10FB1000975ABDD73818FEAA857CD59F3FB09FEE77
+:10FB20006DB57BB9FC50EBE926F941CA2332EEB042
+:10FB3000666F37C913B25DFD010E97BA03FC7B599E
+:10FB4000BA4EEA511C4A2ADEA715CAAF9E9251BA94
+:10FB50005E931F57BA5E8FA9D0DBEB7B491EBC3B7F
+:10FB6000FD1DBA87D7B5887E216FF01B6F0912D1B2
+:10FB700070FE3DC582ED6D1AFFDABA0311D4DE5B6B
+:10FB800017BC19CF7947BD458F69739D85CEFD6D33
+:10FB90000DBA74F4537728C17694E33A84FFD6F013
+:10FBA0009AF7CDA83F8863BDC7F1BD5D6F82B316DC
+:10FBB000F7430CBEEEA2FAE2897A8E7C9A8DFD178D
+:10FBC0008CEABA8C6F6A18D64F2A453BC5DA7CB1ED
+:10FBD0008E8CAE6CA4EBE1C7387F7ECCC036D3BB35
+:10FBE000CDFA6286FA7BAFB02FBABED1D1FBB31D7E
+:10FBF0008AF7D7FEF2D51EB16F8B83B89DF1FE094F
+:10FC0000CE5FE23C7EAA18C667927FA33A1AFBEF4A
+:10FC100011764829A7CE14FC3941DCAF8C23622D24
+:10FC200048C7D2AF4F713828DEF3CE8C63E5783EFB
+:10FC3000DFD36BA2788199BDC124B7268C9843E7A6
+:10FC4000997CB75DB1E95909D43F96A1F3625CDCB8
+:10FC50003DCCC4FD024C01F2ADCE4CFEC94AC7EF0B
+:10FC6000BE41BE1EAF5E3A1E8EFEB2FFAED0FBA3FB
+:10FC7000A57D671F7B9BE17DD89D49F1D009CE878B
+:10FC8000108527FBE6743B0175F7583D263B3F2F57
+:10FC900098FF3A3A7EFE4D58A4CE37BF9EDEB3F4AD
+:10FCA000AE634FAF89F4B6333BC43B8701F3E989B8
+:10FCB000B5919F34D42379B3C7A2A3F7DD66761C30
+:10FCC000A7F70A67CAF70C4DDAF70C992D2102F550
+:10FCD000CAA44B05E120BA99E3AF205C7B5FECC876
+:10FCE000E7F26287E02381EFDDCBB81579AEBC6C1B
+:10FCF000D9750BD74BF17DBA4ADAF9AF24933CD1D1
+:10FD0000D791F29DEF58BC8B7205C80BA7AE76BC9D
+:10FD1000923FDC77AE2E147092E7B38C5B5828E0EC
+:10FD2000B5D0A2E3F009F8DD1549378174E1C33B92
+:10FD30008FF792F864B777BE8AF15880C7F1F73130
+:10FD4000C2DFDB488F27BF7973033EBB3042757437
+:10FD50003B937E14FCD1FBDD3F187F9D81F8F39A25
+:10FD6000C7A01CF1808EE408E9EFE814EFB54BBFA3
+:10FD70004796CE881F94AAC1A42F748A77DA810F80
+:10FD8000BC8A7C40EEFF5173BAC6E3397A12AEE802
+:10FD900038BF2E9D87BE874FE3FE862359679CF0B0
+:10FDA000CFC945F94DF5BD4F4D74DFACB81FAE441A
+:10FDB000FFCB8516F273EF7107BC4F2DDE31EF617B
+:10FDC000823F2C96EF98C37E86766D4B7879FF3B09
+:10FDD000E6A319DDA3DA32591ACA5F6DE2777F868E
+:10FDE0007CC77C6524E94D1F79C43D16CF03F97E9D
+:10FDF000F5F404A779DAF081EF573FA8142FC1DF9B
+:10FE000081718DE7F3ED5A12FCCC2E0E6E2FEA7B3A
+:10FE10004E3686D2BBDD924EA59E7B94ABFB6184B1
+:10FE2000938CABFD58D09B84BF8C2B8C0AC083A4D1
+:10FE3000BBFEDF8B59C7E9AFDF9FB69E913E6524BD
+:10FE40004C2584FC23ED3684EB3D89CE249C7FF346
+:10FE50006A8033E9D1B99FE749F17B1681FB2963B9
+:10FE60009A4EDA89295EA0549C6BA5323EA0511BA4
+:10FE70001F10F8BE69F0C8E209D3609D1794772778
+:10FE8000E2C737FFB73AA8DFC9A4699C8FA7C63A73
+:10FE9000274EA3F36DA6468E7C33F3D304FA7D99E7
+:10FEA0006F8F8FC473EFA684E2C9D8AF3995DB0D8D
+:10FEB0003E8EEBA2F88E8F97FC2D81F4CEEBF8BB33
+:10FEC000AC3F749E03E399391DDCB69CFB23C6B39B
+:10FED00006A2DF585F9CAC19E7F13F2D9ED9176F42
+:10FEE000BC9B7E57E4E5264FCA99D103F1911F745C
+:10FEF000EC391BDC681A8E1C2AA5F8DEF063B725E6
+:10FF000041BEF1C84B3C1F7FEC7212E0E6F6231DA8
+:10FF10003C3FEED8658C075E77E44829C5FFA2DD3B
+:10FF2000600463771C79B9D405F8A89EE06C427C24
+:10FF30002DBAD2F02A1EC3EFAD9FBF3C89E259E72C
+:10FF400025A4F378D6B558BE307AD98670C517CFB8
+:10FF5000BA6D1AB4037AE8B9C4E9BFE712A7F7206B
+:10FF6000E403C3FFF554C6F54AFE3B149F94FBEF30
+:10FF7000C78A4B96FB98EDB26F362031BAFEE57812
+:10FF8000E14768DF04C40BF7187A1F277BD2256688
+:10FF9000C338C4A3A1EFDBF09C68CEE5F18C4A6FB7
+:10FFA000A70DFD30F27378BEF952A70DF93BE6516B
+:10FFB000AFD513C1E31C653C6CF3256F1CEE937C3D
+:10FFC0008C5B84FA85BDBDA5C86FF2D18F3709FB64
+:10FFD0007FEDB8188F617F3B2EF178C31E73A7CDDC
+:10FFE0002AC6C17E60DC24E48BF96B4DE46FD47CBF
+:10FFF000A96135F55362E91F570918D7F4DDE3CE3F
+:020000023000CC
+:1000000052FCC64DEDE3719D38AE4D33AE97E281A3
+:10001000A13F8A3BED89B0C7E27D5FE60BB11CF2E0
+:100020000F89DFA7C8B77955E4FF323E2AC628DE1C
+:10003000E116F715A847F1983BFAF83A2F3679AB55
+:10004000713F150A7E5D68E4E725D305DBD10FBB60
+:1000500048FDF6B578BC97BCC0EF258541C5DB707F
+:100060003FD6EB39BF6151F277D23A57FE06EABD6F
+:10007000131D4FBF2B3632F6104BC57BF1AA391931
+:10008000785E80BCFD11E2FB1DD6AAF0DFDFE2ED59
+:1000900017CC0921FF939E23637271FFCC0FB21D11
+:1000A00064B06F4F4DBB44FB747EB82D176F3AA7F9
+:1000B0008E5CE6F918DB41B4EB9AD8A5D242BAA718
+:1000C000713BED4D3E3BEDA7B82FEBE65C3072B9CE
+:1000D000AC97DE673E378D9F5F20B793DCD17B8D79
+:1000E000786F33C3968BE58986DE30845BCFB77A31
+:1000F000FE5E2DEB0DBBD1CF2EFB78077FC7369070
+:10010000AEF715F0736055AA85DE39AB8F359928A7
+:10011000EDB8349B7E07465F9C8AF7028771707D3D
+:10012000E313055CDE4CDA68F4D9DDE1FC700433DE
+:100130009977B13CC6B6FF5B70FFBD0B8F18E368C3
+:10014000710F73599F284CD5D47760FDFE72C69FFE
+:100150006793ED47BEAC7F02EDF8341EE2B992FB27
+:100160004D049E17A5D32335FE568F4599C9DF2A26
+:1001700055157A3CA86B257D20B7DBC6FFA799E211
+:10018000E77698391DA6EA78BA4327E27C859E4F28
+:10019000DE5F7E31DD397E7A2EF5E3A57ED4FD99D2
+:1001A000284FC4310F8D2FE532590FE42F33311909
+:1001B000F13B6FF9AA6E5078BE5230C351908B74E8
+:1001C000ED629FF89D131743C21AFDF157AF6AF510
+:1001D0009DAF14CCA476B27D5DE32CF609C5217ADF
+:1001E000897EEA5275745FAD57D92BF47B03AC93CB
+:1001F000EC98B2DDFBC0273FA1F71A1C947E00FCEF
+:10020000F213F2F35B4CE95F9A9CF4FD645315A57D
+:100210005D4D0DF4FD545323A58B6E0ECD41FA5F59
+:1002200075783DFBC4EF7CACF3189CFE7E35EFCFB8
+:10023000189C8E2A051DBD9F3478795301978BDE5B
+:100240002FE0F8EC59CEE54BA0CB166BE4D0F24290
+:100250004F28F747786926A7F39E389E7716F077E0
+:10026000421D3AD68EED5F9AC9DF617F3F5947EF55
+:1002700039382279BFEFA7E9484EBB76F68C528415
+:1002800093231ABE67F9F2EF5FC5CB1D23F87739C8
+:100290005F593E7E7ABFFE208DDF8BB9DD1DE89D64
+:1002A000FAEFC76F219F5F607DE9471F088FA36248
+:1002B000DFD2BE40B91DF74192DFBEA8B7D1BE90D4
+:1002C0007428E9AF743A87736A90A07338BB087ECC
+:1002D0007886E1BD38C64C72AC03ED16B09E1D2287
+:1002E000CE7DC07E107600B91FE43E90F41E0FFB59
+:1002F0008CDB39F83AA6A983EBE73715F07B6A6700
+:1003000074E8CF08AF1D062B9E37D3546E6FE8E913
+:10031000589883FEE0459B2C0D83F1AF9745FB7FFA
+:10032000190E921F0C018701EB370A7DFD3FB97E44
+:10033000E26FC8B797737FCC407ADD5B20F915A7D1
+:10034000DB570A1CBB907E7A14B31EEF273DE6C133
+:10035000FDC75F9AC9F785A49FD2E94CBC3F03EB68
+:100360004C19C8EFE47AFAD7B98211DF4B1571C680
+:1003700081F895EBF2E37B1D057E7A27C6405E810E
+:100380007E46D65AE87E2AE9F7E2F06F2AF1FC9A17
+:100390005360E3F6179D2ADE81E5E749FF7745A51F
+:1003A000782BBF7386A1DCD27B84DBE1BC704F422B
+:1003B0003B16EA9EFDE3ADBF16FCA26F71AE0EF5D3
+:1003C0000317BFB6B8F0DCBA38A2F724CA2517DB8A
+:1003D000F93BE7D0E35C05FD4530EEC786BFD7C2E9
+:1003E000ED1FEAC35F9D4479A8F26195E4978B788D
+:1003F0005D8676AB1EE0BF6F27FD066B45BBE6F65C
+:10040000CB8BE877CD803E51FEF9C45C9F8C72F1B6
+:10041000AC871F3881EFAE571E5450CDCC8EA3BE93
+:100420001DF26777ABFCF75545BCC96CE1D75FBDE2
+:1004300093FBF5D7629C09CA2F07B63F88BF3B598B
+:10044000B7DBC0CCF07D36BE8F06E3ACF084C205CE
+:1004500012FA6DD3C6A5FE84B936A21EB96A9BF600
+:100460007BF50E6DBE36C05FF15281F04B1CCB3276
+:10047000C92FB18DEB8925DF1E28EFBA387F5C23A9
+:10048000FD74BFA477BDD5235F259EB2F0FC3C91DF
+:10049000EF86FC85AF38FC25DCEA05CFBF10C772BC
+:1004A0003CB0BEFA23662BDEFFEB5FE0FA818B9E49
+:1004B0007082F3AAE02EB227B017552BCA61771DC0
+:1004C00056499F50D761FE35FE1E6DFD4185DEA960
+:1004D000AD3B1CE4E6F0B95489E52B0E9BAD362C00
+:1004E0007F3188A1DEF922E00DFD612F267411FE17
+:1004F00011AFA88F80BFB9F8BB1512FFEAC3DC8E1D
+:100500005CB947E0A7FD363DE1D5ADB098A4817850
+:100510009278FE9DEEE97E3C61BB590FBFF79AC011
+:100520003BC3389BE3EDE5F47B1812DFC6239F2421
+:10053000A2DC2BF1AC029E7F21DBDBC43B78DF81A8
+:10054000E72AC4B3E59FC7F3EB054CC6FB9D7D14BA
+:10055000E5DE5023D9CFA53E43EA2F86D7BCFF6AFC
+:10056000140C3C3AF63992734B23CFD5AD66A43FB9
+:100570009B341DF59FD7BC853FE7CBDEB9F6E94C30
+:10058000A48F664317FD5E8C2B82BF27DF93346FE9
+:10059000DBF3305E61E43789FB71DFBC1C4466939A
+:1005A0005982AFE29FC9FF3DC00E33E9D9EA3A82D2
+:1005B000B85EED80D66ED613C77F9FAFC8D85BBA42
+:1005C0001AE572E80FC791F7C19A0EF1BB2FE2FE50
+:1005D0005623F50C7B03DE85B2BE45F54AA627D32C
+:1005E0003C5262A6D9900F352F61CEE094EFE2F72E
+:1005F0005C7F237F276F48397008BE2FE53FE6D226
+:10060000EA3924FF59217E57B27F7F887CD57A57FB
+:10061000984925BAA378F1DAC7F8EF2A7E8A7417C9
+:10062000E6A3A77A1197F6EABFBDAEC7DF67EAD99E
+:10063000C1FD2280433E88FEF9E73D3C0EAE3AA75D
+:100640007BA2D786BFCFC1F9D0CABD8ADB9634085A
+:100650001D31F746FE9E7D003DEDFDEEF70E6F9FCE
+:100660002EE2DDC6B2F1FF00786EC7F8A35C1FBFB3
+:10067000088C9BEC3FBF027EBFE37F5A1C775F066E
+:10068000ACE73BEC8C3F89D5BEDF728D4DFBFB4C5C
+:10069000D7A56B7F9FA9CF22E023E44129A7EE9E37
+:1006A000CEE599C054C2F77ABB761C792FFE699EBD
+:1006B00076BC790EED783F142F3F563CEBF7C1EF37
+:1006C0003531EE0931EEEB62DC7F154E321D6ABC2E
+:1006D000FF9FFEBF49FF0F426139640080000000A8
+:1006E0001F8B080000000000000BB55B0B7C94D54D
+:1006F00095BFDF7CF3CC7308210904C22424216058
+:10070000880324542B96C9D300D6065C2D68840137
+:1007100052C83B80B5D2167F190411105BA8D1A234
+:10072000224E82E1A1619D08C144431D14B288D6C6
+:100730008D748BFDFD56DCF828F23213A374E55757
+:100740002D7BFEE77E1F990CA1DAEE6EF2D3937338
+:100750005FDFB9E77DCFBDD414E718BE9A22446E9F
+:10076000CC59734F8410AE953D4589D942F4BDA94B
+:100770008A268710C2ED3D561F2B446DC770B129E4
+:1007800099F092BEB70CC0DBC6D93751FFC6F63F11
+:10079000BC83FEDE03AAC342FDAFB77F1C85752E66
+:1007A0007C152EC470CCFB384A105E7D49617C13E9
+:1007B000F53B089FD9AA0A7F26AD67F499D17F211E
+:1007C00055C7BD6641B0A4A5D5DC43B06A4F2BF731
+:1007D000BFE9330DEEDFD338A8DF8EF104AB8CDE3A
+:1007E000283BC173EDFA7A7E1E5F9DAAB8BC68DF14
+:1007F000F387B8A518D7F26EDC128297F133E36A5B
+:10080000F8D9C11732DD34AFA683D6891858A7A608
+:10081000C3A4E192EEEAD4D6A218E2976851441A32
+:10082000810B628B5845FCAC6A6FAE16D45E957135
+:10083000B749105F023EB518DFA71F8388A37976FA
+:10084000FA8BF877C1F745D4125AF735DFD1DB5C64
+:1008500004039D6F44E1BB8103343E73809EE92E07
+:10086000E25F0EA059881134EFC01B510EEADFE899
+:100870007B43F2DBE8E77DBFAEE10182CCE7769512
+:10088000F75DF195CAFCD7D7BBC5A5F23A33DBD3E8
+:1008900022B1AF133EF9BD392E876C4F5D5406FA75
+:1008A0008F27CCCF5193996E17F0C0C4D9CD9B88B8
+:1008B000942A1FAD9B7935DF9668EB7699C43C1F6F
+:1008C000E496BABF6B14E9C7F1E2E193A9E7CAB8AD
+:1008D000BB5D061E576476A72EA77127221C917652
+:1008E0005AEFC1E2719190EBEB80682FDE697613CD
+:1008F000AC3C20BF77C2DE1D057D3B7160AAEA518A
+:1009000006D6BB43FBAE101E860372F3B09CCABD75
+:100910008D115867407EB27D8ECBCEE38F7BDFBDDD
+:10092000F36EDADF898C7027E4D26516E53ED613C4
+:10093000FA08BED799D8083EE8DF9B0379D0BC40BF
+:100940008681E5DADB6ED2C6DDDD2C068D33B1DCC7
+:100950002E3C37981EBBF7C35FDD4DE3AB9F51853F
+:10096000859AAB4DCBE3B0FF4FB70FA6AF5CE373F7
+:10097000B5C91F1717A4AFD51D57EC2582F5BB438A
+:10098000B70F07CB5397E3890C55D29560F10A2234
+:10099000B9BAB599F59ACCCD639BC250D8092686D1
+:1009A00077272BB4FFC4FBADCEB544FF738AD66F57
+:1009B000201843B841E266825682CF98643BCC1639
+:1009C000F3C7903815C24DC5E3720C29B48EDA3ADC
+:1009D00019727D7186EB5117EDFF97334A26CD20B2
+:1009E0007842F42D15F4CD9A8B111E112D44A1FAE5
+:1009F000FE13F86EFF019380FFA8B176547E427A11
+:100A0000DAEF244321BAFBB79BBC1ED63F57843292
+:100A10004D88A53748BBF9D4E19EA68EA3F16B0C97
+:100A2000BCBFEA16D56BA371BDF5C40262F967AD10
+:100A3000C93F82BE561F53ED56DA77BE2FF9D7D382
+:100A400081B7989C169A5FEBA346C26BF7285E8726
+:100A50005C5FC02E6B6E605D17A76DB529228BE0C1
+:100A60009A3E33C69D3EA488C768DC2361514DA0E1
+:100A7000BB2673D659258AA0BA797D22ADB76C9B67
+:100A8000E9A31EAB9C7B99FEABEBDCCA7A5BE11D54
+:100A9000DC5EB567305E238C0338ADDF8C3F6E14AF
+:100AA000A2CD15197BFA3AFA7B82987059059FA658
+:100AB000C7C31E8E43AEC447D140CC1E29C4BD93CC
+:100AC0009CF1B0FB8D46C72CF021D069B2835F75D5
+:100AD00087F657806E6F7598D3405BAD5DF52AF34E
+:100AE00035F025F1FD7A820982F71F1092BF8176D9
+:100AF000A9E77526C56BC57CE221AF6755BC6BA81D
+:100B00002BE0E98F62FF244431EC62E5FC1C03FC1E
+:100B10001CCC581029BFD6ED41B11995684069FF2A
+:100B20003F30F6A8C382FCC47FB95298FE02B3706E
+:100B3000FBA8FDDE486734F47EAC352A0B748DB516
+:100B40002679C1F7B1C6BE35F8FE23A314C783B416
+:100B5000F4E1AC57262BC06B239CD0132561911177
+:100B6000FC7864D42223F47DACDD97519239801750
+:100B7000A01FF620BCFCBDA208B711DF796EA4E26D
+:100B800037D0FA011BD1073B31DA4DA02F6092B864
+:100B9000106B06D1471E89F1FF77FAEC445FC40061
+:100BA0007D24EF68CCFF229BF84330698E10DDEC8A
+:100BB0001796B35FD0F97981F4BD806495A648BDDE
+:100BC000A9DE7EB808FD35A27B3DE61545C97D143A
+:100BD000613FC0C3245473A5BC7235785FAE8C2FBF
+:100BE000BAFFECC8751973096ECB2D310316AA999B
+:100BF000F13D43F8FB958A95F5E40BB23FF8E37BB2
+:100C0000962BF6D48C01FDD6EDAA4E365DB19FAA87
+:100C1000DFEF348B147CCED59D41FDE542DAF5C281
+:100C200055367B6AB01DC1CE881FE5F68A5B05D9B3
+:100C30009B7B559C3D752AB5AB17CC02BAA7D957FB
+:100C40002CFD5E4E19C2BE7C2176D93E18F7DBA47E
+:100C50009EFB2315EF5AA23F3577B0DD256976D08C
+:100C6000E856787F8D5F1B19F7942A5EF0FC0E6AB8
+:100C70005C15A36D0EE3CA73BD888F77105A8AF690
+:100C80008658B653EE24FFF52FDA3EEF30FA0FC345
+:100C90007F1C35F992EDD475B4C6EAC4FAF3052584
+:100CA0003AE4D74A4537C393E1B56D7E5EDC33063F
+:100CB000FAF59EDBE2441ED6B8AE29127E3C4BAC60
+:100CC000B39FCE405221F65C9E7AED7C8614479C01
+:100CD000D6E582404C790AE4ADCB755BAE2B2F375D
+:100CE000E7DAF3ABFED876DBF7E0BFEE6B36C74B47
+:100CF00035E9CE983620375DAE75C2C374EBF2BAD3
+:100D0000223FA27D34F8A15E98C37EE65955705EFD
+:100D1000A1C9CF4ABF43C94FE7EF0C4D0ECB3AA450
+:100D20003F0A95ABCEEF1FD382F83EC5D1ED2C0F15
+:100D30006161FF172AF76F930B6598A5E8CA8FB515
+:100D400008C833D120FD63E252D213A2FB6EE13E0C
+:100D5000D443F0CEF0B74DAC879A7CEE817C68E846
+:100D60007BC2FBC38CE4FF3BF974E496DC1F6C8709
+:100D7000A176772D3BAB7638FF5D8F7BE469C8BEEB
+:100D800042EC33C4FE7479B95745B19D5D91A3DA45
+:100D900022ED55935704FD0E696FF883BE57D3AE0D
+:100DA00078FDC9DFC1FE14229CE4F65888DDE9F223
+:100DB000B996DFD1FDD429E13F6AA7FD9F4C917917
+:100DC00080E767166F33F0744339FCDEC98912EE91
+:100DD000D7FC5B283C45798E42716C53C6891188DB
+:100DE000D727CDFA3A366F33D17F6A4DF79815344D
+:100DF000FF54AE8427911706E1AE30B1107EFDD4CA
+:100E0000488B077C3AA54CC8437C38A5DC7F9BC443
+:100E1000E3CD0EE0F3E3F3EC849F34C9F17A5CD1C7
+:100E2000FDFFA9F9DF2BE0718A38027E381451C228
+:100E3000DF51949862A2E7D47D6953D68A81FD3749
+:100E4000E51A789E57F3DF4407F3BDEFE78AB789C9
+:100E50009A1622A410FDC979BF2D4EA1F60F7E313E
+:100E60006E32E4EB5A39F8FB88D7C9D703DFCAEBF7
+:100E7000FCE0AB3ED3A2A0B874254E167C2EDBCB93
+:100E8000720CB097724D86AE9809D1904FBF775CC7
+:100E900034E28E1E87FA8FED8F7007C9ED2CC529BD
+:100EA000313E089FF06852701C3BBCEB9174AC5310
+:100EB0006EF66439A9FD4CE3D349C837CA773D9C27
+:100EC000CE79F0AE8DE938CF94373D92EE623CDCBE
+:100ED000CDE729A3DCF7F97D37EEDC14947757E5ED
+:100EE000AB4C7FA9F57021E2EDACEB3E7BC84EE345
+:100EF000D27EA1D8A15EF788EE87101F17203FC6CB
+:100F0000F9ADC1CAFE9CD67341FECD137EF81CEC30
+:100F1000F878C6C7A6321A7729D7C8FC5920BC9BD7
+:100F2000E3A95F6C50ECCD2278FC98468C5FB44E00
+:100F30003127C00F2C1F36597560DE30A663F1864D
+:100F4000C95D685FB05AB6CFB2780F9CC03ABF3562
+:100F50003B9B1DEC6F524A260DD07F29D7CCF31650
+:100F60006E5638FFD7BF93F6445C63F03E2F69F2AC
+:100F7000175F5B14C8E5479A5C6E5DFDEE91045AFD
+:100F8000D71EEBBE0CBFF1CEE3A753FDD45E1073AA
+:100F900036137A9E66763F55817D37599CD84776C1
+:100FA00056A21A4FE3A7FC34F731C085AB173D5565
+:100FB000017FBBCDCAE7369DBE958AD3007FFC4634
+:100FC000E38F17836F671EB772DEBEB2717CBC18E9
+:100FD000C24E75B89BE4EFA083CEDE7A2BC317EA2E
+:100FE000EDC241FAB0AF3E81F117EB1D0CC53CA933
+:100FF0005F2BB5F3F1B5D69BFA55B870503E9BBD4B
+:10100000C1261CE4A792E25CA3F2689F69136B9A65
+:10101000366AFB4AA3F9933DC9F9E043F6C6155D6C
+:101020004879CD79F23CF6D6890D4970CACB567F06
+:10103000B8A382FAE7E4958CCBA376EBF6CFB9AEF2
+:10104000F046C7C30BC0EFF2268BDC9FB6EF338FA1
+:10105000A7C73F45EB7BDE34F179BF6EFB873B369C
+:10106000125CB279853958DFBFEB7E93357ABECDFD
+:10107000AEAEC5877FDCAE1E4962FB6922BBCAFCEF
+:10108000E7EDAA6EF51AE6DFFD7925B3C0F7332642
+:101090004F12ECE9CC849B59CF3D8714E6BFEEC7D5
+:1010A000F5F9C5DA7EAB0CBECDD39307FCF84591BC
+:1010B000CDFC3DDCF1693AF2DE8BEDF3FFEEBE0FC5
+:1010C000D2BEFDB4EF76E2AF7FFCD5FDD3CCEE719E
+:1010D0004EDADF3483CC77AFCA5BF30C5ABDA0DBAA
+:1010E0005C122979AEA02EA3C54F8A639E68A2A781
+:1010F000BA53F18765219EDD72D688F31E9D1B3F92
+:101100000ACE23E8E7A3A0B87D2D7ABF0DD6629D55
+:10111000B401BFFBBD3F19843F284EDFD81326FC26
+:1011200041DFBD723EA13633C9A9B76324FB05C8B0
+:10113000CD887A5CC78426E067CD528EBD07296FC3
+:1011400092751CA14E1BD8E7D98EF359F0B3A1FBC1
+:10115000AD7DE53CEB4775FBC39F2BBCFF99678DCD
+:1011600059DFBEFFC3BBCE67417E674D3DD370DE06
+:10117000EA35F764410EB5AF4A7FFE8FF2416FAF9B
+:10118000D8401B213BAF55ACAC2785EA05AE1BF41C
+:101190001E937583DA8E9DEC4FFB3B65FDA6CED08A
+:1011A0005D148F7AC7F20FBBE0CFFA13E4398AD609
+:1011B00077816FD3C76971D0D8973487FCDA4B57E2
+:1011C000F4419EFFCEC07EC7631D5F35FC80C80A18
+:1011D00017C82BCEC19EA97DC1AAE4F5D0F333DE9A
+:1011E0001153E01FDFCAFA6B2DD7FB5E0BB7AB9C28
+:1011F000F7506B90FCAEECC3AB0AD7A07A40B87046
+:10120000058DAB333B7EC4F9F1715520AFAB9B2804
+:10121000ED49BC22EDA966DD617342D07A3B604F97
+:101220004CB7CC1767BDF657B6CBD5335C9DB0CB6A
+:1012300070F842AC9710ED55146D1CC9BF56A32130
+:10124000A2533BF717ABDC5FD7AE8A91989310E9B6
+:101250004DA37D148B2D46E4D3B3846F3AEA36C296
+:10126000D8F3AB9BA87FF66BEAD44D82CF4F0B4BE4
+:10127000F85CE94E5D89FCC8A0687CF565CF098EF5
+:101280006779324E4D57158E637D23C3394F993997
+:10129000AFA614F4EAE3B286C971B40EE759C2DB13
+:1012A000973507F6E9EFCB9A1B3930EECED7C297C8
+:1012B000735C14BEEC3B83BE13962FEBA35F501CF4
+:1012C000819ED45D94F58E42F5EB27909FAF3C4410
+:1012D000FA82FCD090FC9E017E9CF80CB99E27B946
+:1012E000BA107FDCC2E582FD4C1AE185FDD4ED53D6
+:1012F000841175A20E4B13EA48B5A69E38E8F3C6D2
+:10130000F63F9AA1CF756DEF9A1D93305FD69DC8B9
+:1013100020D98FD769F1ABA67DFC7BA8F3D51C93B0
+:1013200051B4C6F82E9FDFAB0EB4F239BD5AF8F9AE
+:101330009C5EDD32585FFA131C5C1709B58FB07CD8
+:10134000C720BB98B94DDAC59DAA580E3F27B43ABD
+:10135000EDCC8478CE4706E6C97CD7A59E7F08F9F8
+:101360004B2045712AB45420CCB30E7991275DE609
+:101370003381DFBD90BD94FD8A37FB76DA5740CBD1
+:1013800077676ED86A5483E899D929EB92813051F6
+:101390007E90E5ED1E0D39085749447E0EDB55164B
+:1013A000FC6AC020EBA8A1FBA8D7EA45C7514FCAE9
+:1013B0001CA07B7662A2F463C2CBFAD36590DF7780
+:1013C00019A87FCAC0FCC5F972FEC07948D6C1AE63
+:1013D000E55776917CCA483E7B48CE80CF533C2E61
+:1013E000233FD342F118F8BF523C06F4D56770FB97
+:1013F0004BF54EC60FD4DFC0F8C17A17E3EDF5C543
+:101400000C5FA92FE1F6E320F5FBF8DFD38DD08741
+:101410002ED8D8A801FC644C083E6AF0F89331CA73
+:10142000607C94C2E3B3F39F6EF464A26E6AD7EC5F
+:10143000DB1189FCEB8C4DD6A1CED8641DAA759426
+:10144000FBA67CEA2F9BB976973C87BAD231AE20B7
+:10145000663E9F5FFBE9FC0A7FB422DF9D07B91C53
+:101460003B969FBA95FDA48DEBA027EFBA2E9AEB81
+:10147000806FD2799C3E9D9B31755D36E1B9110A32
+:10148000EB2FF98BEB4BF47325AD93DF29EF510A6A
+:10149000D5EA32ACBF72A46D2AFCEF172EF7ADA0CF
+:1014A00043E777D1A865A9C887BA4C8EF750C7F52E
+:1014B000FCDE24709ED2EB7DFAB80E57EE5D9837B5
+:1014C0003363DCBA29F03B6464F0732EB368015DCA
+:1014D0002E43B8B296FD96C3083F7097A6C7790E03
+:1014E0009917FBCD0E630CEA3761B9B11E9AD7A5E7
+:1014F000C9F99826E7E39A9CDF469D8CE03BD40E21
+:10150000D84DED809374FE1AFB986F4FE49594B11B
+:10151000FE8ABE24E07A5D7016EC4BFA9B24E8F557
+:10152000664D7F13347FD3955B5225E7F9789D2A6A
+:10153000ADDE765EBB07D1F7ABCF1B982F18CEBDC3
+:101540005E78ACF0F32FCB73A7184DF908E1735F09
+:101550008E673FA45A6FCFFC84EC7CEE54790E105A
+:10156000FB2D725C82230776B256ABB7F67A0D1E5E
+:1015700013EAD331DDE93188BF9A7DE9F8C1BFA90B
+:10158000ECAF6BA6104EF05545EEAF666E77FA30B5
+:10159000CC576C06AE6F37C9FE139AFDD5A468EB25
+:1015A00069FB11565F12E41138F472D262C23745FA
+:1015B000F8974ABFEF4F677F2DFCE973E11715DFFE
+:1015C00007C2497965C1D4C5C691E0876F07F0EAC3
+:1015D000829CC5C61BD1DFFA813DB87F842F49B1FB
+:1015E00003CF96FD235A770C7306E1A6973E40BFC2
+:1015F000D990B3B880F0D916EFB17AE8CD8B52BF4D
+:101600006CFBDA4E836F551D326FCFDBD776E12549
+:10161000C4E5B64827DCFBDEFC64E6F7DA8EDD9B2A
+:10162000A16FBDADF23E6053CB1F77FC92C75970DE
+:101630004D42EBFAB2057D67C591FF5804BA668743
+:10164000FBBE04FEE091194CE7ECE1D2AE1F3E92E6
+:10165000B71876DADBB6EF67B0BFD9D194D0829EE7
+:10166000176C5C87A8DC3FA10076DA1BD9BD00EBC4
+:10167000D73E6F71424F2BF7C7E7A13E70305FD660
+:10168000C32B266E49429C35BCB277D72F71BFFA67
+:10169000BC8DEF85EA62649E57A9364E5BC1F2DBD2
+:1016A000B9EB69D0BDD7C6F7B315A855115EB12BFC
+:1016B0008DEBF8AF7EF3F102C8A150DDBE0BED5FFC
+:1016C0003E6733800F27CCAEE89B6187274C7CDEDA
+:1016D000ACD0F08A93C3253DE13D452CBFD82D49C0
+:1016E00088B395C37F7E1BE89EAD6ED981F38ED8FB
+:1016F0006DE1BB89B37B896F34EF6CB3690AA4DCFD
+:10170000BB37D2087D39AF6C59F014D66F96E3CE53
+:10171000DBB6303F3DCDE305BE47E304FCD679653B
+:10172000EBA0F6B3CDBBB3701E3DF7FC6C3E97EA61
+:10173000FAABDB4BE573964171913D01F9A34AED9C
+:101740006F61F788088AB7151A7AEEE093BD4F8962
+:1017500081F9E75A4C7E33F1A8C222D6596306ECD0
+:10176000A132F19662ECAFD2D0988EBCA5626ACF5E
+:1017700002D8C5599BB026D0B8B7B4B8557960CD5A
+:101780001CE4BFD7A2E7B2E68F2E26C8F875B1DDFC
+:10179000E60DBE970C85EFD70BFBDB6903F83DCB5D
+:1017A0002D9CC3EBEBBD65F655E39C561B23FDC793
+:1017B0000734BE85FCD8375ABC5BB86AF0F8FEFC2B
+:1017C00018FE7EADB9271DF14F5F3F90AFFBB59E70
+:1017D00074F8ABD079B3918EC08FBCA0B01FA93C78
+:1017E000A07CA8129F2AAD1EAF0ABE08B3BE4FE36D
+:1017F0006545CE4B98A6F19DE66E2848E6EF56B6B5
+:10180000D85C369A5715D61385BCA83AB2270AF980
+:101810004EEF2BAA68D2C4151BA7C92745135950F0
+:10182000BDB1C26772D9B2869033F2271AB70C7F66
+:10183000D3F79F2948E1FD94B787F3F784BD671A72
+:10184000F4B47CFBE079D8973DC8FE7ADB77C60517
+:101850009FCB5334BA03CA876C27816F3E4A82DC20
+:101860002B0D621DEE2FCFD11CDC6B122EAC12E7BC
+:101870007BCFCABF4484415FCE5DAC66BBED557A79
+:10188000D8AFBD533087FD52AFA987FDDA1B47EEB5
+:1018900064FFD03BAC6701FCD43B05CB64FFC89E22
+:1018A000050EEADFA7E36304C7FDF78FD4B0FF9806
+:1018B000ADCA771562A7C92EEB411B4ED6F3F9C20C
+:1018C000E4083E7F9F2AD0EA3D03F2E173976E372A
+:1018D000BDC2B1EF00ECB03C82EB3A9447B5BC849A
+:1018E0007C6F7E9C13EF35CA314FEA8139F8BE31E7
+:1018F00036E6D252C8E7F6D1EEA2821CDC6FF6F0D3
+:101900003982B49AE34DEDEF2C7C9E0C98FA76C1A7
+:101910004FA58F76CF2A203AAACDDDEBB389A40B51
+:10192000A69E2E94C867A9D21F89DD52AF7A33775D
+:10193000CA7B1AEDBEF22E8DFF820E318DD00B4583
+:10194000CAF78DF6FD6FC3AFF4768F637F1C6A37DD
+:1019500067DB1F8B827FF813C5714FD079FF4F8BE8
+:1019600076F33DEB3CBC0721B878DD607DE8FFFAFB
+:10197000763EF789CD41EDD0C386C178A81E411FC0
+:10198000FD83FC8E87F9BE4DB3ABAABCEE5AF0E1E5
+:101990000A3E977035087F3D040F192F4A649EB0A8
+:1019A0000DF19FF8513DC67F92CFE9FB4C027E7C42
+:1019B0002DC52FC6DBC2BD38AF18F6517C8A95F114
+:1019C0000971A12AAA9BEB53BD6D16BEEF7DB0E352
+:1019D000D324EC9FF490EB30551D2FC7E1FCBE578C
+:1019E0003B2F501C8CE3F7316D1D713877E8EDD536
+:1019F000065F3AE8A28C88F375BDBD46F5A783FE65
+:101A00002AA53B0BFD7B41378F275C052E781FD520
+:101A10008AB477D1A1B23F0F95DB939ABE925FC88B
+:101A2000E2F71DAFC8FA80EE072A347FF23ADA33C4
+:101A3000A5DDDBF57B259A5A017B1FC23F2414E804
+:101A400079F172AEDF3C5EE090B8369FD795F52510
+:101A5000EEAF7DF57C564A26E669E382FDD0B801FB
+:101A6000BF02FB4F60FB7FD01447FBAADCA138D735
+:101A7000C24F95AE29A2E16299714511D7CD8487F5
+:101A8000CF6DA17485EAD1E402C9A74AC3B0C2D818
+:101A9000A0F5CE914F4F98C27EC60FBFF393D847A3
+:101AA0008B50A7F871A97C377025DE04DB39F6B3BB
+:101AB0005DFA7198CD65C3D57ABC6C79E3FAF821EB
+:101AC000E808A5B3C2DD5814E7B8BA5DA7F79C4D86
+:101AD000A72FCF3422980FF3D6148D20B8CCFACF8D
+:101AE000F241EEF75C87C58FB85A51BA627DF410A7
+:101AF0007A73553CD81E14BF52205F2FDF6F5C8B6A
+:101B0000FE5058ADF84FA25E24C8AE9AD9BEC85E4A
+:101B100082E2C28D05217587F2456391570BF7A2CA
+:101B2000B1883364570B9C439C2FC9418E32F09B84
+:101B3000110FC3507AFE5C20DF25DD5820ED7CF5C7
+:101B40000C57007EF366D5C07978E87A5F15C87CBB
+:101B5000A23B2EF23EFD3D07847DB32AF99668E84C
+:101B60007F07F6961817E9C07D50617EB81C77C8CC
+:101B70006647FD2670E812D777030F45CC93F7062A
+:101B8000116224F577254C6A0A8E23BF2994FB0D38
+:101B9000CF96794B5D86E9EFD7873223AFD487386C
+:101BA0006FC80CE7FB92DEF62F386E053A73ECB87F
+:101BB000D7E8EDA6D321D953DD37FF1D87F8DADB4F
+:101BC000F9677E87D6FBF5A7FC3E6DA3F63EF0F5E0
+:101BD00076ED7D57B72312ED81E28F8B306E930641
+:101BE00007EA04B25EAC43FDFCABD70382CEC1A3CF
+:101BF0000B873E07C7B82382EB048EF8A1EA2AC1FF
+:101C00007582D434592700449D20D524EB04C0515B
+:101C10002700449D00EDA81300479D0038EA04C04A
+:101C2000512700449D00ED5FCE93EF6502A4C4B23E
+:101C30007E19C1FEFDDE66D58BFCFCDE43F21EEA9A
+:101C4000DE4685DF695DA0EF23CE5DF55EE780F6B9
+:101C50005EC7B795EFF5EADA5427445567EA3B8A41
+:101C6000BA4E5DABE25C03FF523F8FBFBFB133E7BB
+:101C7000BD52B4379B9C0607E474310EF5AACACE58
+:101C800066AE3F15C41F32B37C5B14817AE99D16A2
+:101C900079CEAD51A9750ADF87721E5C63E9E6F360
+:101CA00047D51EC55E167C9F7BC3E7EC07D6DAA23C
+:101CB0009A40678DCF662F1BE2FD07DF0B3BC49573
+:101CC000FBE6A57288A88928E2FBE6A5B867262866
+:101CD000D4AF8D7C7F4C07D3E1D047BCABCA805BCF
+:101CE000B74BBB0F794F55D9D9BA3E515C7D0F8D9B
+:101CF000CA00E41F7AFFEC2E8C8C3D1D0E47212676
+:101D0000236F2A7EBC6C5F1B7DAF7F8B85F38E15A6
+:101D1000F9EE65D0A3A32617D7498E1EB2F1F9E8D4
+:101D200093ADE307D549BE70B9AB0BF97E7E34D7CE
+:101D30002D569A148ECBF9C5E3E2F9DDC03113C7F5
+:101D40009F0E57492DC6AD9CE4E0FA54A145DCC76F
+:101D5000EB68EFB408B23D15AE55BC06C21709A733
+:101D600019F6B390D8C6FA628AD880F7540B857CEE
+:101D7000DFA0EBCDCAAD0AE7055C2888C3BDA4E4AB
+:101D8000EFC2CE7FBB84F70B4B2C327F4D34C8FBA8
+:101D9000ECC44DF27DCB4F84DB8C78BB8CE22220EF
+:101DA000C5C9DFF550BB3B7C7492CCCF1DF1587F89
+:101DB000D17113BFF72D8CFF61BA9BE37501BF632F
+:101DC00050FC77AB97AFBBB6FD84BE63386A92FE1A
+:101DD00085F8C8E7A22EE825D767DC0C8FD79733A4
+:101DE0009C3443FAC72BEF12494676D01FDEF70129
+:101DF000CE8B89F1914EF83BDDEEAF7A9F1826A18C
+:101E0000FE3E710C4111F43E71B3CBC1FE2ED17078
+:101E100062AA03FCF84B8413FCD0DF29AE9E51B2BA
+:101E200013727245090FBE8B7B942DC4D7226C446C
+:101E3000419DDBE75251B73EA4D8F95DF4557E725F
+:101E4000EB4378C75397AAD81507EAE15B0AE38802
+:101E5000EEA29464A6BBAE5DD64B994371A8A76B66
+:101E6000F6E072B7158E18689FADD9452F8D977A19
+:101E7000729317FAF61DEAA8CF61BC47D89CCDDA59
+:101E8000790D729F7DDD18AEA7EA7AD3DF12DF04E9
+:101E9000BD79B350C699D2D2774DC803BA72DD4727
+:101EA000B0FF05659F3F14C7FB1BBA8E457E94EFBC
+:101EB0002543EB58BA5FDEA5D5C1E13F8D5A9DD5CC
+:101EC000A8D5598D5A9DD5A8D5598D5A9DD5A8D537
+:101ED000598D5A9DD5A8D5598D5A9DD5C8F5BBE5C4
+:101EE0000CDFA95FC5B0BBDEC3FD41FEFFFD6BF893
+:101EF000FFD03AE8C718175A0715564734C751B2EA
+:101F00006F597F0EA97B160F5FBC81F897DF607653
+:101F1000A249AF83E2FDF2BD11EC0F2E140E59FF62
+:101F2000D4F916C1F5D27E619B02FEE7658C331AA7
+:101F3000A8FF2F9A1CF4FA23EC03FB837D00C23E1A
+:101F40008C6903F6F18C994C385BC67B0FC77B1B01
+:101F5000CB75FD1AF21F842F11F641FEE34288FF74
+:101F6000A083C75DA06369A77CD7A4BFDFCC23F0A3
+:101F7000D59421FC894FFA933161BEBDF8CE98DA31
+:101F8000307E1F7C547B8F7574A37C1757264AF8CC
+:101F9000BB43F89528C863C9F0BE0F9EA6F14B1E3F
+:101FA00089E0BC65FDC8A5D3FE377EE5F342C98F45
+:101FB000DFD6FB2B3F215A0AC2A4FE15984506EE38
+:101FC0006B84218CEDA050DDACE07E74E53D623287
+:101FD000E45C6029D90E3AE3B5FB6D11ABD55B8D9E
+:101FE000DD15BB093F1197E8C4BDD6E8848302EF35
+:101FF0009F0AEB8A33E117FD63DC138A72F07E7966
+:102000008B82F9E19972FFB717873741AF0287C614
+:10201000E740DE732D8E36D4019C45094B70CE9F70
+:102020001BEDC8411DC0D9354AE2F18E36C5895431
+:1020300036614901BF3FB36EF9C48A776B8A88A6BF
+:102040007D5986B973F09D9AE2CFE4B959F4711CB9
+:10205000BBB1489EBF46BC2EFCB8B7EA9B19C9F776
+:102060006722D391837ECA2BBF5F44FA77E407AE21
+:102070009B0013353AE3718BA842AADD36C0E3DA40
+:102080007D5E97C15D0A5814E53172BBC19B0DF8A6
+:1020900096C1F753B4933E17619DA2C7264FCC203B
+:1020A0003CD1E2633FD9E172DD02FA5E9CE12A068F
+:1020B0000CAD9F43B638E7133DB7A23FF41D962EF3
+:1020C000CF254552EFCB8AA4FF98BE56DEC786CAFD
+:1020D000BDACC8A0F9B7BF4F37D15B8AEFE9F48B2D
+:1020E0002D8BB2410FD17B0FF641F42E001411312C
+:1020F0005CEFB8B69E79F87B654552BFC89F557DA9
+:1021000022FD19C374A37718F2C7510F788781DEB7
+:10211000518D7D36FC3B8C673D7D36C4F76757F7A4
+:10212000D9D0FEAC4BBE930E5DBFB148BE9F489F59
+:10213000DEC7F3C7D2B7BA394FEF1B863C2ABDFCC6
+:1021400093F5F2DE2583E3CB582DBE8C7D20A5BD13
+:1021500087F46DEC93D17CBF2D0A62B9BFD22AED12
+:10216000B4F281B2836D04C76F237A83F2AF095E44
+:10217000A27B505E64EC97EF2D09079FF6981887B5
+:10218000CE22BFAA11F2BDE528CD6F206F2B25BF4F
+:1021900050537EE412BF03C07CAC8F3B5BE85FBB57
+:1021A00049E214AE711E5D366F4D179F0FB75D6922
+:1021B000D7CE9BADEB717EA6FC6D507B65D9E12E31
+:1021C000C49BAA3D83DB6B967FCEE758CADF06B57A
+:1021D000DFF3D30FF99D4D5DFBE07692EF5390BF97
+:1021E0002EDFA326DF049CF78ED68439E5BF1FF0CF
+:1021F000AD80BD375547F0FBD99DBFC963BDD1E563
+:102200004DF39BBE9B7EACE5F19E3C91017BF83685
+:10221000D80BFF9436C83F79B8CE372B92FD4E9D30
+:1022200076BEAA2DB3739C4FACB5B2FF2A54C39CA3
+:10223000C06B8DD2CF886255F3533EB6FF13B70DF6
+:10224000E37A1E6F0078CC247E771CB756E27D239C
+:102250002CEC1F0A0D25D5BB091E312C673F908041
+:10226000179724F767E01F54D8AFBC7FA833FB143F
+:1022700079BFEFC8C17957BF6F6AD8E86D3D80F369
+:10228000B2E27D7229EA8A7744F0FD4100F546DA30
+:102290004FC330E9471BE6A7731C088892D215C8C4
+:1022A00043E68571FDB16198E351DC2736544CE477
+:1022B0003CFAE0DF64DCED9B6375228F6A98EC5892
+:1022C00083F72A0D0F38B8FF5545AEE77954F2A7CA
+:1022D000618EDC7F43450C9F7B74393434BA46E20F
+:1022E0007E6AC618F77F426EA3B4FBB986646A277C
+:1022F000F8845232FF27586792A477D20C07CBEDAF
+:10230000E8FC898FEE727038F1E39EA86E56E4A067
+:1023100073F1FF008751D9F610370000000000006C
+:102320000000000000000000050015000000000093
+:00000001FF
diff --git a/firmware/cis/MT5634ZLX.cis.ihex b/firmware/cis/MT5634ZLX.cis.ihex
new file mode 100644
index 0000000..72500b9
--- /dev/null
+++ b/firmware/cis/MT5634ZLX.cis.ihex
@@ -0,0 +1,11 @@
+:100000000101FF152204014D756C74695465636824
+:100010000050434D4349412035364B2044617461C3
+:10002000466178000000FF20040002010021020266
+:10003000001A05012780FF671B0FCF418B01550177
+:10004000550155AA60F80307281B08970108AA6004
+:10005000F802071B089F0108AA60E803071B08A70E
+:0B0060000108AA60E802071400FF007E
+:00000001FF
+#
+# Replacement CIS for Multitech MT5634ZLX modems
+#
diff --git a/firmware/cis/PCMLM28.cis.ihex b/firmware/cis/PCMLM28.cis.ihex
new file mode 100644
index 0000000..ffdfe85
--- /dev/null
+++ b/firmware/cis/PCMLM28.cis.ihex
@@ -0,0 +1,18 @@
+:1000000001030000FF151504014C494E4B53595391
+:100010000050434D4C4D3238000000FF2004430196
+:10002000ABC0210200001A05012FF803031B10E4E6
+:1000300001190155E06100031FF8020730FFFF1BA3
+:100040000BA50108E06120031FF802071B0BA601A6
+:1000500008E06140031FF802071B0BA70108E061DD
+:1000600060031FF802071B0BA80108E06100031FD3
+:10007000E803071B0BA90108E06120031FE8030741
+:100080001B0BAA0108E06140031FE803071B0BAB31
+:100090000108E06160031FE803071B0BAC0108E0E7
+:1000A0006100031FE802071B0BAD0108E06120039C
+:1000B0001FE802071B0BAE0108E06140031FE802C6
+:1000C000071B0BAF0108E06160031FE80207140083
+:0200D000FF002F
+:00000001FF
+#
+# The on-card CIS says it is MFC-compliant, but it is not
+#
diff --git a/firmware/cis/RS-COM-2P.cis.ihex b/firmware/cis/RS-COM-2P.cis.ihex
new file mode 100644
index 0000000..0801ca5
--- /dev/null
+++ b/firmware/cis/RS-COM-2P.cis.ihex
@@ -0,0 +1,10 @@
+:1000000001030000FF1516040150434D4349410010
+:1000100052532D434F4D203250000000FF21020269
+:10002000011A0501030001011B0EC18118AA61E834
+:100030000307E8020730B89E1B0B820108AA615033
+:1000400002075802071B0B830108AA6160020768B8
+:0600500002071400FF008E
+:00000001FF
+#
+# Replacement CIS for dual-serial-port IO card
+#
diff --git a/firmware/cxgb3/ael2005_opt_edc.bin.ihex b/firmware/cxgb3/ael2005_opt_edc.bin.ihex
new file mode 100644
index 0000000..c1d6e5d
--- /dev/null
+++ b/firmware/cxgb3/ael2005_opt_edc.bin.ihex
@@ -0,0 +1,69 @@
+:10000000CC002FF4CC013CD4CC022015CC0331051C
+:10001000CC046524CC0527FFCC06300FCC072C8BF5
+:10002000CC08300BCC094009CC0A400ECC0B2F7207
+:10003000CC0C3002CC0D1002CC0E2172CC0F301241
+:10004000CC101002CC1125D2CC123012CC131002DD
+:10005000CC14D01ECC1527D2CC163012CC171002DF
+:10006000CC182004CC193C84CC1A6436CC1B200755
+:10007000CC1C3F87CC1D8676CC1E40B7CC1FA74634
+:10008000CC204047CC215673CC222982CC2330028D
+:10009000CC2413D2CC258BBDCC262862CC273012A1
+:1000A000CC281002CC292092CC2A3012CC2B100262
+:1000B000CC2C5CC3CC2D0314CC2E2942CC2F300287
+:1000C000CC301002CC31D019CC322032CC333012AB
+:1000D000CC341002CC352A04CC363C74CC37643591
+:1000E000CC382FA4CC393CD4CC3A6624CC3B5563D5
+:1000F000CC3C2D42CC3D3002CC3E13D2CC3F464DC1
+:10010000CC402862CC413012CC421002CC43203289
+:10011000CC443012CC451002CC462FB4CC473CD452
+:10012000CC486624CC495563CC4A2D42CC4B300296
+:10013000CC4C13D2CC4D2ED2CC4E3002CC4F100230
+:10014000CC502FD2CC513002CC521002CC530004F0
+:10015000CC542942CC553002CC561002CC572092B8
+:10016000CC583012CC591002CC5A5CC3CC5B03176C
+:10017000CC5C2F72CC5D3002CC5E1002CC5F294289
+:10018000CC603002CC611002CC6222CDCC63301D39
+:10019000CC642862CC653012CC661002CC672ED2BB
+:1001A000CC683002CC691002CC6A2D72CC6B300264
+:1001B000CC6C1002CC6D628FCC6E2112CC6F3012E1
+:1001C000CC701002CC715AA3CC722DC2CC73300209
+:1001D000CC741312CC756F72CC761002CC772807D2
+:1001E000CC7831A7CC7920C4CC7A3C24CC7B672452
+:1001F000CC7C1002CC7D2807CC7E3187CC7F20C4FC
+:10020000CC803C24CC816724CC821002CC83251482
+:10021000CC843C64CC856436CC86DFF4CC876436F1
+:10022000CC881002CC8940A4CC8A643CCC8B40168C
+:10023000CC8C8C6CCC8D2B24CC8E3C24CC8F643518
+:10024000CC901002CC912B24CC923C24CC93643AD9
+:10025000CC944025CC958A5ACC961002CC97273165
+:10026000CC983011CC991001CC9AC7A0CC9B01003E
+:10027000CC9CC502CC9D53ACCC9EC503CC9FD5D5A0
+:10028000CCA0C600CCA12A6DCCA2C601CCA32A4C1E
+:10029000CCA4C602CCA50111CCA6C60CCCA7590093
+:1002A000CCA8C710CCA90700CCAAC718CCAB0700B4
+:1002B000CCACC720CCAD4700CCAEC801CCAF7F5092
+:1002C000CCB0C802CCB17760CCB2C803CCB37FCE7F
+:1002D000CCB4C804CCB55700CCB6C805CCB75F11B8
+:1002E000CCB8C806CCB94751CCBAC807CCBB57E18B
+:1002F000CCBCC808CCBD2700CCBEC809CCBF000010
+:10030000CCC0C821CCC10002CCC2C822CCC30014CE
+:10031000CCC4C832CCC51186CCC6C847CCC71E02D7
+:10032000CCC8C013CCC9F341CCCAC01ACCCB04464C
+:10033000CCCCC024CCCD1000CCCEC025CCCF0A0074
+:10034000CCD0C026CCD10C0CCCD2C027CCD30C0C3A
+:10035000CCD4C029CCD500A0CCD6C030CCD70A0094
+:10036000CCD8C03CCCD9001CCCDAC005CCDB7A069A
+:10037000CCDC0000CCDD2731CCDE3011CCDF10012D
+:10038000CCE0C620CCE10000CCE2C621CCE3003FAB
+:10039000CCE4C622CCE50000CCE6C623CCE70000C6
+:1003A000CCE8C624CCE90000CCEAC625CCEB0000A2
+:1003B000CCECC627CCED0000CCEEC628CCEF00007C
+:1003C000CCF0C62CCCF10000CCF20000CCF3280617
+:1003D000CCF43CB6CCF5C161CCF66134CCF76135D8
+:1003E000CCF85443CCF90303CCFA6524CCFB000BC6
+:1003F000CCFC1002CCFD2104CCFE3C24CCFF21051A
+:10040000CD003805CD016524CD02DFF4CD034005D4
+:10041000CD046524CD051002CD065DD3CD070306BE
+:10042000CD082FF7CD0938F7CD0A60B7CD0BDFFD2A
+:10043000CD0C000ACD0D1002CD0E00007CC7AE59C8
+:00000001FF
diff --git a/firmware/cxgb3/ael2005_twx_edc.bin.ihex b/firmware/cxgb3/ael2005_twx_edc.bin.ihex
new file mode 100644
index 0000000..9b5e9e5
--- /dev/null
+++ b/firmware/cxgb3/ael2005_twx_edc.bin.ihex
@@ -0,0 +1,93 @@
+:10000000CC004009CC0127FFCC02300FCC0340AA22
+:10001000CC04401CCC05401ECC062FF4CC073CD4AD
+:10002000CC082035CC093145CC0A6524CC0B26A25E
+:10003000CC0C3012CC0D1002CC0E29C2CC0F3002E9
+:10004000CC101002CC112072CC123012CC13100242
+:10005000CC1422CDCC15301DCC162E52CC1730121C
+:10006000CC181002CC1928E2CC1A3002CC1B10029A
+:10007000CC1C628FCC1D2AC2CC1E3012CC1F1002A9
+:10008000CC205553CC212AE2CC223002CC231302BF
+:10009000CC24401ECC252BE2CC263012CC271002DB
+:1000A000CC282DA2CC293012CC2A1002CC2B2BA28A
+:1000B000CC2C3002CC2D1002CC2E5EE3CC2F0305CD
+:1000C000CC30400ECC312BC2CC323002CC331002BB
+:1000D000CC342B82CC353012CC361002CC37566360
+:1000E000CC380302CC39401ECC3A6F72CC3B1002A4
+:1000F000CC3C628FCC3D2BE2CC3E3012CC3F100288
+:10010000CC4022CDCC41301DCC422E52CC433012BB
+:10011000CC441002CC452522CC463012CC471002EC
+:10012000CC482DA2CC493012CC4A1002CC4B2CA288
+:10013000CC4C3012CC4D1002CC4E2FA4CC4F3CD422
+:10014000CC506624CC51410BCC5256B3CC5303C493
+:10015000CC542FB2CC553002CC561002CC57220BC7
+:10016000CC58303BCC5956B3CC5A03C3CC5B866BCE
+:10017000CC5C400CCC5D23A2CC5E3012CC5F100274
+:10018000CC602DA2CC613012CC621002CC632CA2C8
+:10019000CC643012CC651002CC662FB4CC673CD452
+:1001A000CC686624CC6956B3CC6A03C3CC6B866B2F
+:1001B000CC6C401CCC6D2205CC6E3035CC6F5B53C3
+:1001C000CC702C52CC713002CC7213C2CC735CC395
+:1001D000CC740317CC752522CC763012CC77100264
+:1001E000CC782DA2CC793012CC7A1002CC7B2B8229
+:1001F000CC7C3012CC7D1002CC7E5663CC7F0303C6
+:10020000CC80401ECC810004CC822C42CC833012A6
+:10021000CC841002CC856F72CC861002CC87628FA2
+:10022000CC882304CC893C84CC8A6436CC8BDFF424
+:10023000CC8C6436CC8D2FF5CC8E3005CC8F865689
+:10024000CC90DFBACC9156A3CC92D05ACC9321C299
+:10025000CC943012CC951392CC96D05ACC9756A30E
+:10026000CC98DFBACC990383CC9A6F72CC9B1002E6
+:10027000CC9C28C5CC9D3005CC9E4178CC9F565354
+:10028000CCA00384CCA122B2CCA23012CCA3100209
+:10029000CCA42BE5CCA53005CCA641E8CCA7565381
+:1002A000CCA80382CCA90002CCAA4258CCAB2474BF
+:1002B000CCAC3C84CCAD6437CCAEDFF4CCAF64378F
+:1002C000CCB02FF5CCB13C05CCB28757CCB3B888B5
+:1002D000CCB49787CCB5DFF4CCB66724CCB7866AAC
+:1002E000CCB86F72CCB91002CCBA2D01CCBB301196
+:1002F000CCBC1001CCBDC620CCBE14E5CCBFC62101
+:10030000CCC0C53DCCC1C622CCC23CBECCC3C623EA
+:10031000CCC44452CCC5C624CCC6C5C5CCC7C625A2
+:10032000CCC8E01ECCC9C627CCCA0000CCCBC6289E
+:10033000CCCC0000CCCDC62BCCCE0000CCCFC62C74
+:10034000CCD00000CCD10000CCD22D01CCD33011C8
+:10035000CCD41001CCD5C620CCD60000CCD7C62139
+:10036000CCD80000CCD9C622CCDA00CECCDBC62358
+:10037000CCDC007FCCDDC624CCDE0032CCDFC62551
+:10038000CCE00000CCE1C627CCE20000CCE3C628DC
+:10039000CCE40000CCE5C62BCCE60000CCE7C62CB4
+:1003A000CCE80000CCE90000CCEA2D01CCEB301108
+:1003B000CCEC1001CCEDC502CCEE609FCCEFC600BA
+:1003C000CCF02A6ECCF1C601CCF22A2CCCF3C60CB0
+:1003D000CCF45400CCF5C710CCF60700CCF7C71806
+:1003E000CCF80700CCF9C720CCFA4700CCFBC728D3
+:1003F000CCFC0700CCFDC729CCFE1207CCFFC801FE
+:10040000CD007F50CD01C802CD027760CD03C80377
+:10041000CD047FCECD05C804CD06520ECD07C8054C
+:10042000CD085C11CD09C806CD0A3C51CD0BC807DB
+:10043000CD0C4061CD0DC808CD0E49C1CD0FC80906
+:10044000CD103840CD11C80ACD120000CD13C821FF
+:10045000CD140002CD15C822CD160046CD17C844D4
+:10046000CD18182FCD19C013CD1AF341CD1BC01ACA
+:10047000CD1C0446CD1DC024CD1E1000CD1FC025AF
+:10048000CD200A00CD21C026CD220C0CCD23C027C3
+:10049000CD240C0CCD25C029CD2600A0CD27C03001
+:1004A000CD280A00CD29C03CCD2A001CCD2B000050
+:1004B000CD2C2B84CD2D3C74CD2E6435CD2FDFF487
+:1004C000CD306435CD312806CD323006CD3385654B
+:1004D000CD342B24CD353C24CD366436CD371002B7
+:1004E000CD382B24CD393C24CD3A6436CD3B404524
+:1004F000CD3C8656CD3D1002CD3E2807CD3F31A7DD
+:10050000CD4020C4CD413C24CD426724CD431002D0
+:10051000CD442807CD453187CD4620C4CD473C2466
+:10052000CD486724CD491002CD4A2514CD4B3C64FB
+:10053000CD4C6436CD4DDFF4CD4E6436CD4F100238
+:10054000CD502806CD513CB6CD52C161CD5361345A
+:10055000CD546135CD555443CD560303CD57652455
+:10056000CD58000BCD591002CD5AD019CD5B2104C6
+:10057000CD5C3C24CD5D2105CD5E3805CD5F652485
+:10058000CD60DFF4CD614005CD626524CD632E8D55
+:10059000CD64303DCD655DD3CD660306CD672FF7C5
+:1005A000CD6838F7CD6960B7CD6ADFFDCD6B000A45
+:0C05B000CD6C1002CD6D000052A76B0E48
+:00000001FF
diff --git a/firmware/cxgb3/ael2020_twx_edc.bin.ihex b/firmware/cxgb3/ael2020_twx_edc.bin.ihex
new file mode 100644
index 0000000..8b1337f
--- /dev/null
+++ b/firmware/cxgb3/ael2020_twx_edc.bin.ihex
@@ -0,0 +1,100 @@
+:10000000D8004009D8012FFFD802300FD80340AAEA
+:10001000D804401CD805401ED8062FF4D8073DC48C
+:10002000D8082035D8093035D80A6524D80B2CB229
+:10003000D80C3012D80D1002D80E26E2D80F30227C
+:10004000D8101002D81127D2D8123022D81310029B
+:10005000D8142822D8153012D8161002D817249296
+:10006000D8183022D8191002D81A2772D81B30128B
+:10007000D81C1002D81D23D2D81E3022D81F10023F
+:10008000D82022CDD821301DD82227F2D8233022E3
+:10009000D8241002D8255553D8260307D82725225F
+:1000A000D8283022D8291002D82A2142D82B301241
+:1000B000D82C1002D82D4016D82E5E63D82F0344BA
+:1000C000D8302142D8313012D8321002D833400E05
+:1000D000D8342522D8353022D8361002D8372B52C2
+:1000E000D8383012D8391002D83A2742D83B3022BB
+:1000F000D83C1002D83D25E2D83E3022D83F10022D
+:10010000D8402FA4D8413DC4D8426624D843414B9F
+:10011000D84456B3D84503C6D846866BD847400C5A
+:10012000D8482712D8493012D84A1002D84B2C4B45
+:10013000D84C309BD84D56B3D84E03C3D84F866B9E
+:10014000D850400CD8512272D8523022D8531002C5
+:10015000D8542742D8553022D8561002D85725E215
+:10016000D8583022D8591002D85A2FB4D85B3DC481
+:10017000D85C6624D85D56B3D85E03C3D85F866B5F
+:10018000D860401CD8612C45D8623095D8635B5349
+:10019000D8642372D8653012D86613C2D8675CC39E
+:1001A000D8682712D8693012D86A1312D86B2B522C
+:1001B000D86C3012D86D1002D86E2742D86F30221A
+:1001C000D8701002D8712582D8723022D8731002EC
+:1001D000D8742142D8753012D8761002D877628F41
+:1001E000D8782985D87933A5D87A25E2D87B3022EA
+:1001F000D87C1002D87D5653D87E03D2D87F401EBB
+:10020000D8806F72D8811002D882628FD88323047D
+:10021000D8843C84D8856436D886DFF4D8876436A1
+:10022000D8882FF5D8893005D88A8656D88BDFBA7A
+:10023000D88C56A3D88DD05AD88E2972D88F301228
+:10024000D8901392D891D05AD89256A3D893DFBAA7
+:10025000D8940383D8956F72D8961002D8972B45FF
+:10026000D8983005D8994178D89A5653D89B0384AA
+:10027000D89C2A62D89D3012D89E1002D89F2F0594
+:10028000D8A03005D8A141C8D8A25653D8A303821C
+:10029000D8A40002D8A54218D8A62474D8A73C84B4
+:1002A000D8A86437D8A9DFF4D8AA6437D8AB2FF51B
+:1002B000D8AC3C05D8AD8757D8AEB888D8AF9787AB
+:1002C000D8B0DFF4D8B16724D8B2866AD8B36F72D9
+:1002D000D8B41002D8B52641D8B63021D8B710010D
+:1002E000D8B8C620D8B90000D8BAC621D8BB0000FB
+:1002F000D8BCC622D8BD00CED8BEC623D8BF007F8A
+:10030000D8C0C624D8C10032D8C2C625D8C3000080
+:10031000D8C4C627D8C50000D8C6C628D8C700008C
+:10032000D8C8C62CD8C90000D8CA0000D8CB2641EE
+:10033000D8CC3021D8CD1001D8CEC502D8CF53ACFF
+:10034000D8D0C503D8D12CD3D8D2C600D8D32A6EE2
+:10035000D8D4C601D8D52A2CD8D6C605D8D7555753
+:10036000D8D8C60CD8D95400D8DAC710D8DB0700C3
+:10037000D8DCC711D8DD0F06D8DEC718D8DF0700D4
+:10038000D8E0C719D8E10F06D8E2C720D8E3470064
+:10039000D8E4C721D8E50F06D8E6C728D8E7070074
+:1003A000D8E8C729D8E91207D8EAC801D8EB7F50A6
+:1003B000D8ECC802D8ED7760D8EEC803D8EF7FCE6E
+:1003C000D8F0C804D8F1520ED8F2C805D8F35C11A1
+:1003D000D8F4C806D8F53C51D8F6C807D8F740611C
+:1003E000D8F8C808D8F949C1D8FAC809D8FB3840A4
+:1003F000D8FCC80AD8FD0000D8FEC821D8FF0002EA
+:10040000D900C822D9010046D902C844D903182FFF
+:10041000D904C013D905F341D906C084D9070030E7
+:10042000D908C904D9091401D90ACB0CD90B000485
+:10043000D90CCB0ED90DA00AD90ECB0FD90FC0C045
+:10044000D910CB10D911C0C0D912CB11D91300A02B
+:10045000D914CB12D9150007D916C241D917A0005B
+:10046000D918C243D9197FE0D91AC604D91B000E86
+:10047000D91CC609D91D00F5D91EC611D91F000EF9
+:10048000D920C660D9219600D922C687D923000475
+:10049000D924C60AD92504F5D9260000D927264132
+:1004A000D9283021D9291001D92AC620D92B14E501
+:1004B000D92CC621D92DC53DD92EC622D92F3CBE57
+:1004C000D930C623D9314452D932C624D933C5C50F
+:1004D000D934C625D935E01ED936C627D93700000C
+:1004E000D938C628D9390000D93AC62CD93B0000E2
+:1004F000D93C0000D93D2B84D93E3C74D93F6435AA
+:10050000D940DFF4D9416435D9422806D9433006B1
+:10051000D9448565D9452B24D9463C24D94764362E
+:10052000D9481002D9492B24D94A3C24D94B6436E6
+:10053000D94C4045D94D8656D94E5663D94F030202
+:10054000D950401ED9511002D9522807D95331A78A
+:10055000D95420C4D9553C24D9566724D957100200
+:10056000D9582807D9593187D95A20C4D95B3C2496
+:10057000D95C6724D95D1002D95E24F4D95F3C644C
+:10058000D9606436D961DFF4D9626436D963100268
+:10059000D9642006D9653D76D966C161D9676134D1
+:1005A000D9686135D9695443D96A0303D96B652485
+:1005B000D96C00FBD96D1002D96E20D4D96F3C24C0
+:1005C000D9702025D9713005D9726524D9731002EC
+:1005D000D974D019D9752104D9763C24D97721054D
+:1005E000D9783805D9796524D97ADFF4D97B4005E3
+:1005F000D97C6524D97D2E8DD97E303DD97F2408C4
+:10060000D98035D8D9815DD3D9820307D98388872A
+:10061000D98463A7D9858887D98663A7D987DFFD61
+:10062000D98800F9D9891002D98A0000878C30D97D
+:00000001FF
diff --git a/firmware/matrox/g200_warp.H16 b/firmware/matrox/g200_warp.H16
new file mode 100644
index 0000000..5064b6f
--- /dev/null
+++ b/firmware/matrox/g200_warp.H16
@@ -0,0 +1,28 @@
+/*
+ * WARP pipes are named according to the functions they perform, where
+ *
+ *   - T stands for computation of texture stage 0
+ *   - T2 stands for computation of both texture stage 0 and texture stage 1
+ *   - G stands for computation of triangle intensity (Gouraud interpolation)
+ *   - Z stands for computation of Z buffer interpolation
+ *   - S stands for computation of specular highlight
+ *   - A stands for computation of the alpha channel
+ *   - F stands for computation of vertex fog interpolation
+ */
+/* TGZ */
+:04B8000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9728007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2608015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E803800AEA17C12BBD008000E8008000E8B3689725008000E833C033AF3C274FE9573920E9281960EC2B3220E91D3B20E9B30500E0162820E9233B33AD1E2B20E91C8020E9573620E90080A0E94040D8ECFF80C0E990E200E085FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E884FF0AEA008000E8C941C8EC42E100E082FF20EA008000E8008000E8008000E8C840C0EC008000E87FFF20EA008000E8008000E8008000E871
+/* TGZF */
+:0548000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE91750569F008000E8370F5C9F00E02F20008000E8281960ECB30500E0008000E8233B33AD008000E8172617DF35174FE9008000E8008000E8008000E839374FE92F2F17AF008000E8008000E8008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E078FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E877FF0AEA008000E8C941C8EC42E100E075FF20EA008000E8008000E8008000E8C840C0EC008000E872FF20EA008000E8008000E8008000E8BB
+/* TGZA */
+:04E80000000098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97D8007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D444CB6254454B603802AEA17C12BBD2D20252007C044C6B3689725008000E833C033AF3C274FE91F62579F008000E83F3D5D9F00E00720008000E8281960ECB30500E0008000E8233B33AD008000E81F261FDF9D1F4FE9008000E8008000E8008000E89E3F4FE907071FAF008000E8008000E8008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E07AFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E879FF0AEA008000E8C941C8EC42E100E077FF20EA008000E8008000E8008000E8C840C0EC008000E874FF20EA008000E8008000E8008000E8D9
+/* TGZAF */
+:0568000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9838007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26F8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B62D444CB6254454B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE900E0252007C044C61750569F00E02D20370F5C9F00E02F201F62579F00E007203F3D5D9F008000E8008000E8281960ECB30500E0172617DF233B33AD35174FE91F261FDF9D1F4FE99E3F4FE939374FE92F2F17AF008000E807071FAF008000E831804FE9008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E074FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E873FF0AEA008000E8C941C8EC42E100E071FF20EA008000E8008000E8008000E8C840C0EC008000E86EFF20EA008000E8008000E8008000E830
+/* TGZS */
+:05C0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98B8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2778015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F3F2F5D9F00E08F20A5374FE90F170FAF06C021C4008000E8008000E8A3804FE9062000E01F261FDFA11F4FE9A23F4FE9008000E8008000E806061FAF008000E8008000E8008000E8A0804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E06CFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E86BFF0AEA008000E8C941C8EC42E100E069FF20EA008000E8008000E8008000E8C840C0EC008000E866FF20EA008000E8008000E8008000E85C
+/* TGZSF */
+:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C63F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82F2000E0A3804FE9062000E01F261FDF172617DF35174FE9A11F4FE9A23F4FE906061FAF39374FE92F2F17AF008000E8A0804FE9008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E8F9
+/* TGZSA */
+:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D444CB6054454B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D200520008000E83F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82FC044C6A3804FE9062000E01F261FDF172617DF9D174FE9A11F4FE9A23F4FE906061FAF00E0AF209E374FE92F172FAFA0804FE9008000E8008000E89C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E883
+/* TGZAF */
+:05B8000000008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9948007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2808015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C62D444CB6254454B63F2F5D9F00E00F202D20252007C044C61750569FA5374FE906C021C40F170FAF370F5C9F008000E81E62579F008000E83E3D5D9F00E007202F2000E0A30F4FE9062000E01F261FDF172617DFA11F4FE91E261EDF9D1E4FE935174FE9A23F4FE906061FAF39374FE92F2F17AF07071EAFA0804FE99E3E4FE931804FE99C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E063FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E862FF0AEA008000E8C941C8EC42E100E060FF20EA008000E8008000E8008000E8C840C0EC008000E85DFF20EA008000E8008000E8008000E8D8
+:0000000001FF
diff --git a/firmware/matrox/g400_warp.H16 b/firmware/matrox/g400_warp.H16
new file mode 100644
index 0000000..b432d10
--- /dev/null
+++ b/firmware/matrox/g400_warp.H16
@@ -0,0 +1,44 @@
+/*
+ * WARP pipes are named according to the functions they perform, where
+ *
+ *   - T stands for computation of texture stage 0
+ *   - T2 stands for computation of both texture stage 0 and texture stage 1
+ *   - G stands for computation of triangle intensity (Gouraud interpolation)
+ *   - Z stands for computation of Z buffer interpolation
+ *   - S stands for computation of specular highlight
+ *   - A stands for computation of the alpha channel
+ *   - F stands for computation of vertex fog interpolation
+ */
+/* TGZ */
+:0338000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900588015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4A8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A444CB0024454B02A444CB21A4454B21D803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A444CB41A4454B439E52C9F383D20E988735EE92A201A202A464EBF1A4656BF31532F9F3E304FE939E52C9F3F384FE90A474FBF024757BF31532F9F3A314FE939E52C9F3B394FE92A434BBF1A4353BF30502E9F36314FE938212C9F37394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AFFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD6FF20EA008000E84E334ECF573B57CF9DFF20EA57C0BFEA0080A0E90000D8EC59
+/* TGZF */
+:0360000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005D8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4F8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E827CF75C63C3D20E90A444CB0024454B02A444CB21A4454B220803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F312720E90A444CB4024454B42A454DB61A4555B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AAFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF98FF20EA57C0BFEA0080A0E90000D8EC90
+/* TGZA */
+:0358000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005C8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4E8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E927CF74C63DCF74C20A444CB0024454B02A444CB21A4454B220803AEA0A20022088735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9ABFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF99FF20EA57C0BFEA0080A0E90000D8EC35
+/* TGZAF */
+:0380000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900618015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF538007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C40A444CB0024454B031532F9F343720E939E52C9F3C3D20E92A444CB21A4454B226803AEA0A20022088735EE92A201A203DCF74C227CF74C630502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A454DB6024555B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A464EBF1A4656BF0A474FBF024757BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A6FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCDFF20EA008000E84E334ECF573B57CF94FF20EA57C0BFEA0080A0E90000D8EC89
+/* TGZS */
+:03A0000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900658015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF578007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B229803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A454DB21A4555B20A454DB4024555B438212C9F3B394FE90A2002202A201A202A464EBF1A4656BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A474FBF024757BF31532F9FA4314FE939E52C9FA5394FE92A434BBF1A4353BF30502E9FA1304FE938212C9FA2384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A2FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCAFF20EA008000E84E334ECF573B57CF90FF20EA57C0BFEA0080A0E90000D8ECD8
+/* TGZSF */
+:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF75C62A201A20A7304FE90A20022031532F9F312720E939E52C9FA8384FE92A454DB61A4555B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECD3
+/* TGZSA */
+:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECA0
+/* TGZSAF */
+:03E8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006E8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF608007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B232803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE90A454DB6024555B63DCF75C62A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A474FBF024757BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E999FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC1FF20EA008000E84E334ECF573B57CF87FF20EA57C0BFEA0080A0E90000D8EC83
+/* T2GZ */
+:0438000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900788015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF698007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B225803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A4454B41A4464B439E52C9F383D20E988735EE92A201A202A4656BF1A4666BF31532F9F3E304FE939E52C9F3F384FE90A4757BF024767BF31532F9F3A314FE939E52C9F3B394FE92A4353BF1A4363BF30502E9F36314FE938212C9F37394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99FFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBEFF20EA008000E8583358CF693B69CF7DFF20EA57C0BFEA0080A0E90000D8ECAC
+/* T2GZF */
+:0460000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007D8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6E8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E80FCF75C63C3D20E90A4454B0024464B02A4454B21A4464B228803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F310F20E90A4454B4024464B42A4555B61A4565B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99AFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBBFF20EA008000E8583358CF693B69CF78FF20EA57C0BFEA0080A0E90000D8ECFB
+/* T2GZA */
+:0458000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007C8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6D8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B229803AEA0A2002200FCF74C63DCF74C288735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99BFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBAFF20EA008000E8583358CF693B69CF79FF20EA57C0BFEA0080A0E90000D8ECA0
+/* T2GZAF */
+:0480000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900818015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF728007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C40A4454B0024464B031532F9F343720E939E52C9F3C3D20E92A4454B21A4464B22E803AEA0A20022088735EE92A201A203DCF74C20FCF74C630502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A4555B6024565B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A4656BF1A4666BF0A4757BF024767BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E996FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB5FF20EA008000E8583358CF693B69CF74FF20EA57C0BFEA0080A0E90000D8ECDC
+/* T2GZS */
+:04A0000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900858015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF768007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B231803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A4555B21A4565B20A4555B4024565B438212C9F3B394FE92A201A200A2002202A4656BF1A4666BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A4757BF024767BF31532F9FA4314FE939E52C9FA5394FE92A4353BF1A4363BF30502E9FA1304FE938212C9FA2384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E992FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB2FF20EA008000E8583358CF693B69CF70FF20EA57C0BFEA0080A0E90000D8EC43
+/* T2GZSF */
+:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF75C62A201A20A7304FE90A20022031532F9F310F20E939E52C9FA8384FE92A4555B61A4565B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC56
+/* T2GZSA */
+:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC23
+/* T2GZSAF */
+:04E8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008E8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7F8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B23A803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE90A4555B6024565B63DCF75C62A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A4757BF024767BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E989FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFA9FF20EA008000E8583358CF693B69CF67FF20EA57C0BFEA0080A0E90000D8ECEE
+:0000000001FF
diff --git a/firmware/r128/r128_cce.bin.ihex b/firmware/r128/r128_cce.bin.ihex
new file mode 100644
index 0000000..4831315
--- /dev/null
+++ b/firmware/r128/r128_cce.bin.ihex
@@ -0,0 +1,129 @@
+:1000000000000000108038000000000010003800E0
+:10001000000000020000008E0000000200000091BD
+:1000200000000000402E2423000000006062124FF8
+:10003000000000002E2B596D000000007677753E01
+:1000400000000000898984820000000023BC8B0D21
+:10005000000000002323232300000000238DABB405
+:1000600000000000232323230000000100B028002B
+:100070000000000100032800000000010004C0008F
+:100080000000000100030800000000023660300E8E
+:100090000000000B00040000000000000000000051
+:1000A000000000010200151D0000000100001D0EEF
+:1000B00000000001000039D900000001000019D73C
+:1000C0000000000C0000001C00000001000019D618
+:1000D0000000000C0000001C0000000200000017DF
+:1000E0000000000B01200000000000000100358A24
+:1000F0000000000100064000000000090000001E92
+:100100000000000108D015B4000000101910100004
+:100110000000000300002000000000000000280094
+:1001200000000001000308000000000100003D0E77
+:10013000000000010000C8000000000A0000882A3A
+:10014000000000090000002A000000010200150F55
+:1001500000000002000028240000000100003D65AE
+:100160000000000100003D66000000020000002BBE
+:100170000000000100F32DB4000000012200D8BFF0
+:100180000000000100E088BF0000000C1333383786
+:1001900000000001020615650000000C0000003799
+:1001A00000000001020015640000000100003D662F
+:1001B000000000020000002E000000040020083AA9
+:1001C0000000000100080800000000010006C0FF58
+:1001D000000000040040003D000000010007C800CE
+:1001E00000000001000700FF000000030000000005
+:1001F0000000000C0000005C000000020000002E67
+:100200000000000C000000B00000000100003D767E
+:100210000000000100032800000000010000480069
+:1002200000000001000208000000000106001D0E91
+:1002300000000001000248000000000100028800E8
+:100240000000000100F3C5F80000000100100000EC
+:10025000000000060030004E0000000100003D6379
+:100260000000001080303DF0000000021000384314
+:1002700000000002000028430000000C000000B055
+:100280000000000100003D760000000100003D7705
+:100290000000000100003D0E0000000100003D0FC5
+:1002A000000000010050280000000006003000524D
+:1002B0000000001080303DF00000000100003DF81B
+:1002C00000000002000000520000000100053D0E89
+:1002D0000000000100103D0F00000002003000553A
+:1002E0000000000100003D700000000100001E89B8
+:1002F0000000000100003D710000000300003D729D
+:100300000000000C0000005C000000020000006221
+:100310000000000100003F280000000100003F270E
+:100320000000000100003E820000000100003E8845
+:100330000000000100003E660000000100003E6772
+:100340000000000100003E760000000100003E6851
+:100350000000000100003E690000000100003E6C4A
+:100360000000000000003E6D0000000100002800B9
+:1003700000000001005028000000000100003D685E
+:100380000000000100030800000000060000006EED
+:10039000000000010002C0000000000106303D62C4
+:1003A0000000000200000070000000020030006F3A
+:1003B00000000000200038C0000000010001C0C0A3
+:1003C0000000000E0000007D0000000C0003287FEC
+:1003D00000000001020015BB0000000C00030880B3
+:1003E0000000000002003DBC0000000100003DBB19
+:1003F0000000000000003DBC00000003000480007D
+:100400000000000100048000000000030006C0029C
+:100410000000000100B0280000000000306038003B
+:100420000000000100C028000000000100B008002A
+:100430000000000100D600000000000712801086B6
+:10044000000000000000280000000001000039CC7E
+:1004500000000001000039CD00000001000039C992
+:1004600000000001000039CA00000000000039CB84
+:10047000000000011003B80000000001009000001F
+:100480000000000110003800000000010003080017
+:100490000000000100903D1B0000000140203D0ACB
+:1004A0000000000140203D0B00000001000880001A
+:1004B000000000010001C0C00000000E0000009F0D
+:1004C0000000000C000308800000000142203DBD38
+:1004D0000000000C0003087F0000000142003DBB4B
+:1004E0000000000C000308800000000142203DBC19
+:1004F00000000002000000A20000000140203DBDFD
+:100500000000000140003DBB0000000140203DBC58
+:1005100000000001000840000000000100A00000F1
+:1005200000000006003000A6000000101060380037
+:1005300000000009000000A80000000300400000C7
+:100540000000000300403D1D00000000000000000E
+:1005500000000000000001000000000E000000AEDE
+:10056000000000010001C0A900000001020015C741
+:100570000000000C000000B0000000000000280097
+:10058000000000010001C0AA00000001020015D215
+:10059000000000010001C0A900000003020015C70F
+:1005A0000000000100003E88000000010001C0BA08
+:1005B0000000000102001728000000010001C0BB7C
+:1005C000000000010200165A0000000000003E5B1F
+:1005D000000000000000010000000000000010000A
+:1005E000000000010006400B00000009000000BCF4
+:1005F00000000000000028000000000000000000D3
+:1006000000000000000000000000000000000000EA
+:1006100000000000000000000000000000000000DA
+:1006200000000000000000000000000000000000CA
+:1006300000000000000000000000000000000000BA
+:1006400000000000000000000000000000000000AA
+:10065000000000000000000000000000000000009A
+:10066000000000000000000000000000000000008A
+:10067000000000000000000000000000000000007A
+:10068000000000000000000000000000000000006A
+:10069000000000000000000000000000000000005A
+:1006A000000000000000000000000000000000004A
+:1006B000000000000000000000000000000000003A
+:1006C000000000000000000000000000000000002A
+:1006D000000000000000000000000000000000001A
+:1006E000000000000000000000000000000000000A
+:1006F00000000000000000000000000000000000FA
+:1007000000000000000000000000000000000000E9
+:1007100000000000000000000000000000000000D9
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:00000001FF
diff --git a/firmware/radeon/R100_cp.bin.ihex b/firmware/radeon/R100_cp.bin.ihex
new file mode 100644
index 0000000..151647b
--- /dev/null
+++ b/firmware/radeon/R100_cp.bin.ihex
@@ -0,0 +1,130 @@
+:1000000000000000210070000000000020007000CF
+:1000100000000004000000B400000004000000B86C
+:10002000000000006F5B4D4C000000004C4C427F14
+:10003000000000005B568A92000000004CA09C6DFE
+:1000400000000000AD4C4C4C000000004CE1AF3D06
+:1000500000000000D8AFAFAF00000000D64C4CDC71
+:10006000000000004CD10D1000000016000F000031
+:1000700000000000362F242D0000000400000012B4
+:1000800000000016000F000000000000362F282D91
+:1000900000000002000380E70000000204002C972B
+:1000A00000000016000F000100000000333A373056
+:1000B00000000002000077EF0000000200061000C0
+:1000C0000000001A000000210000001E0000400097
+:1000D00000000002000610000000001A00000021CD
+:1000E0000000001E0000400000000002000610009A
+:1000F0000000001A000000210000001E0000400067
+:100100000000000400000017000000020003802B24
+:1001100000000002040067E0000000040000001777
+:1001200000000002000077E000000002000650001E
+:1001300000000002000037E100000006040067E153
+:1001400000000002000077E000000002000077E1FC
+:1001500000000006000077E100000000FFFFFFFF45
+:100160000000000010000000000000020003802BCF
+:1001700000000006040067E0000000020000767541
+:100180000000000200007676000000020000767792
+:100190000000000600007678000000020003802CBA
+:1001A00000000002040026760000000200007677BE
+:1001B0000000000600007678000000180000002F04
+:1001C000000000180000002F0000000600000000E2
+:1001D000000000180000003000000018000000308F
+:1001E0000000000600000000000000020160500056
+:1001F000000000020006500000000002000980001C
+:1002000000000002000610000000000464C0603E10
+:1002100000000002000380E600000002040025C583
+:1002200000000016000800000000000000000000B0
+:10023000000000020400251D00000002000075807F
+:100240000000000200067581000000020400258005
+:100250000000000200067581000000040000004953
+:10026000000000000000500000000002000380E6D3
+:1002700000000002040025C5000000020006100076
+:10028000000000020000750E000000020001900056
+:10029000000000140001105500000012000000557D
+:1002A000000000020400250F000000040000504F71
+:1002B00000000002000380E600000002040025C5E3
+:1002C0000000000200007565000000020000756675
+:1002D000000000040000005800000002000380E657
+:1002E00000000002040025C50000000201E655B42C
+:1002F000000000024401B0E40000000201C110E46B
+:10030000000000182666706600000002040C2565D7
+:1003100000000018000000660000000204002564D0
+:100320000000000200007566000000040000005D8F
+:1003300000000008004010690000000200101000DA
+:1003400000000002000D80FF000000080080006C2B
+:1003500000000002000F900000000002000E00FFED
+:100360000000000600000000000000180000008FE0
+:10037000000000040000005B00000002000380E6B3
+:1003800000000002040025C5000000020000757690
+:100390000000000200065000000000020000900073
+:1003A0000000000200041000000000020C00350EE6
+:1003B0000000000200049000000000020005100090
+:1003C0000000000201E785F80000000200200000A4
+:1003D0000000000C0060007E000000020000756359
+:1003E00000000021006075F0000000042000707320
+:1003F000000000040000507300000002000380E6CB
+:1004000000000002040025C500000002000075760F
+:100410000000000200007577000000020000750E69
+:10042000000000020000750F0000000200A0500054
+:100430000000000C0060008300000021006075F0E7
+:1004400000000002000075F80000000400000083B6
+:1004500000000002000A750E00000002000380E6A2
+:1004600000000002040025C5000000020020750FF6
+:1004700000000004006000860000000200007570AB
+:100480000000000200007571000000060000757297
+:1004900000000002000380E600000002040025C501
+:1004A00000000002000050000000000200A0500008
+:1004B0000000000200007568000000020006100045
+:1004C0000000000C00000095000000020005800004
+:1004D000000000020C60756200000004000000973C
+:1004E00000000002000380E600000002040025C5B1
+:1004F000000000040060009600000000400070E56D
+:1005000000000002000380E600000002040025C590
+:1005100000000002000380E50000001C000000A8AD
+:1005200000000018000650AA00000002040025BBCD
+:1005300000000018000610AB00000000040075BCAD
+:1005400000000002000075BB00000000000075BC48
+:100550000000000600090000000000020009000081
+:1005600000000006000D800200000002000078324A
+:10057000000000020000500000000002000380E7BD
+:100580000000000204002C97000000020000782008
+:100590000000000200007821000000000000780048
+:1005A000000000020120000000000002200770008F
+:1005B0000000000201200000000000022000700086
+:1005C0000000000200061000000000020120751B60
+:1005D000000000028040750A000000028040750B98
+:1005E000000000020011000000000002000380E58E
+:1005F0000000001C000000C600000018000610AB40
+:1006000000000002844075BD00000018000610AA1A
+:1006100000000002840075BB00000018000610AB4B
+:1006200000000002844075BC00000004000000C906
+:1006300000000002804075BD00000002800075BB14
+:1006400000000002804075BC000000020010800025
+:1006500000000002014000000000000C006000CD1E
+:100660000000002020C0700000000012000000CF39
+:100670000000000600800000000000060080751DDC
+:100680000000000000000000000000020000775C95
+:100690000000000200A050000000000200661000F0
+:1006A000000000200460275D000000000000400002
+:1006B0000000000201E0083000000000210070008E
+:1006C000000000006464614D00000000696874204F
+:1006D00000000000000000730000000000000000A7
+:1006E000000000020000500000000002000380D063
+:1006F00000000002040025E000000000000075E199
+:10070000000000000000000100000002000380E083
+:1007100000000002040023940000000000005000CC
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000080000000000000004AD
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:00000001FF
+/* production radeon ucode r1xx-r6xx */
diff --git a/firmware/radeon/R200_cp.bin.ihex b/firmware/radeon/R200_cp.bin.ihex
new file mode 100644
index 0000000..3a0bd73
--- /dev/null
+++ b/firmware/radeon/R200_cp.bin.ihex
@@ -0,0 +1,130 @@
+:1000000000000000210070000000000020007000CF
+:1000100000000004000000BF00000004000000C356
+:10002000000000007A685E5D000000005D5D55889C
+:100030000000000068659197000000005DA19F78B6
+:10004000000000005D5D5D5D000000005DEE5D5044
+:1000500000000000F2ACACAC00000000E75DF9E984
+:1000600000000000B1DD0E1100000000E2AFAFAFF4
+:1000700000000016000F000000000000452F232D97
+:10008000000000040000001300000016000F000034
+:1000900000000000452F272D00000016000F000172
+:1000A000000000003E4D4A3700000002000077EFDC
+:1000B00000000002000610000000001A00000020EE
+:1000C0000000001E000040000000000200061000BA
+:1000D0000000001A000000200000001E0000400088
+:1000E00000000002000610000000001A00000020BE
+:1000F0000000001E00004000000000040000001688
+:10010000000000020003802A00000002040067E0F3
+:10011000000000040000001600000002000077E06C
+:10012000000000020006500000000002000037E15D
+:1001300000000006040067E100000002000077E014
+:1001400000000002000077E100000006000077E1F7
+:1001500000000000FFFFFFFF000000001000000093
+:100160000000000007F007F0000000020003802AF2
+:1001700000000006040067E0000000020003802C7D
+:100180000000000204002741000000020400274193
+:100190000000000204002743000000020000767502
+:1001A0000000000200007676000000020000767772
+:1001B0000000000600007678000000020003802C9A
+:1001C0000000000204002741000000020400274153
+:1001D00000000002040027430000000200007676C1
+:1001E000000000020000767700000006000076782C
+:1001F000000000020003802B0000000204002676AD
+:100200000000000200007677000000020003802C4E
+:100210000000000204002741000000020400274300
+:100220000000000600007678000000020003802C29
+:1002300000000002040027410000000204002741E2
+:10024000000000020400274300000006000076784A
+:10025000000000180000002F000000180000002F10
+:100260000000000600000000000000180000003739
+:100270000000001800000037000000060000000029
+:100280000000000201605000000000020006500063
+:1002900000000002000980000000000200061000BB
+:1002A0000000000464C06051000000160008000057
+:1002B0000000000000000000000000020400251DF6
+:1002C0000000000200007580000000020006758139
+:1002D0000000000204002580000000020006758175
+:1002E000000000040000005A000000000000500060
+:1002F0000000000200061000000000020000750E61
+:1003000000000002000190000000001400011064D1
+:100310000000001200000064000000020400250F2D
+:10032000000000040000505E00000002000075653F
+:100330000000000200007566000000040000006577
+:100340000000000201E655B4000000024401B0F0D4
+:100350000000000201C110F0000000182666707154
+:1003600000000002040C2565000000180000007168
+:100370000000000204002564000000020000756611
+:100380000000000400000068000000080040107435
+:10039000000000020010100000000002000D80FFAD
+:1003A000000000080080007700000002000F9000AD
+:1003B00000000002000E00FF000000060000000028
+:1003C0000000001800000094000000040000006815
+:1003D00000000002000075760000000200065000D8
+:1003E0000000000200009000000000020004100065
+:1003F000000000020C00350E000000020004900016
+:1004000000000002000510000000000201E785F86E
+:1004100000000002002000000000000C00600087C7
+:10042000000000020000756300000021006075F00C
+:10043000000000042000707C000000040000507CDC
+:1004400000000002000075760000000200007577D1
+:10045000000000020000750E000000020000750F91
+:100460000000000200A050000000000C0060008AA4
+:1004700000000021006075F000000002000075F827
+:10048000000000040000008A00000002000A750E4F
+:10049000000000020020750F000000040060008DC5
+:1004A000000000020000757000000002000075717D
+:1004B00000000006000075720000000200005000FD
+:1004C0000000000200A0500000000002000075685B
+:1004D00000000002000610000000000C0000009860
+:1004E0000000000200058000000000020C60756240
+:1004F000000000040000009A000000040060009961
+:1005000000000000400070F100000002000380F1D4
+:100510000000001C000000A700000018000650A901
+:1005200000000002040025BB00000018000610AA0D
+:1005300000000000040075BC00000002000075BB54
+:1005400000000000000075BC00000006000900006B
+:10055000000000020009000000000006000D8002FB
+:10056000000000020000500000000002000078219E
+:100570000000000000007800000000020000782168
+:10058000000000000000780000000002016650003A
+:1005900000000002000A000000000002000671CC0A
+:1005A000000000020286F1CD00000010000000B73C
+:1005B00000000000210070000000001C000000BED0
+:1005C000000000020006500000000002000A0000C7
+:1005D000000000020006100000000002000B0000F6
+:1005E000000000023806700000000004000A00BA93
+:1005F0000000000020007000000000020120000048
+:10060000000000022007700000000002012000002E
+:100610000000000020007000000000020006100032
+:10062000000000020120751B000000028040750AD6
+:10063000000000028040750B000000020011000065
+:1006400000000002000380F10000001C000000D147
+:1006500000000018000610AA00000002844075BDCA
+:1006600000000018000610A900000002840075BBFD
+:1006700000000018000610AA00000002844075BCAB
+:1006800000000004000000D400000002804075BD9E
+:1006900000000002800075BB00000002804075BCB5
+:1006A0000000000200108000000000020140000075
+:1006B0000000000C006000D80000002020C0700086
+:1006C00000000012000000DA0000000600800000B8
+:1006D000000000060080751D00000002000025BB20
+:1006E00000000004000040D4000000020000775C1D
+:1006F0000000000200A05000000000020066100090
+:10070000000000200460275D0000000000004000A1
+:1007100000000002000079990000000200A05000D3
+:100720000000000200661000000000200460299B09
+:1007300000000000000040000000000201E008305E
+:1007400000000000210070000000000200005000C6
+:10075000000000020003805600000002040025E0B3
+:1007600000000000000075E1000000000000000132
+:1007700000000002000380ED0000000004007394FC
+:100780000000000000000000000000000000000069
+:1007900000000002000078C400000002000078C5DC
+:1007A00000000002000078C600000002000079246A
+:1007B00000000002000079250000000200007926F8
+:1007C00000000004000000F2000000020000792494
+:1007D00000000002000079250000000200007926D8
+:1007E00000000004000000F900000000000000000C
+:1007F00000000000000000000000000000000000F9
+:00000001FF
+/* production radeon ucode r1xx-r6xx */
diff --git a/firmware/radeon/R300_cp.bin.ihex b/firmware/radeon/R300_cp.bin.ihex
new file mode 100644
index 0000000..d307d56
--- /dev/null
+++ b/firmware/radeon/R300_cp.bin.ihex
@@ -0,0 +1,130 @@
+:10000000000000004200E000000000004000E000AE
+:1000100000000008000000AE00000008000000B270
+:100020000000000067554B4A000000004A4A447532
+:100030000000000055527D83000000004A8C8B6553
+:10004000000000004AEF4AF6000000004AE14A4A78
+:1000500000000000E497979700000000DB4AEBDD0A
+:10006000000000009CCC4A4A00000000D1989898FB
+:10007000000000004A0F9AD600000004000CA00007
+:1000800000000038000D0012000000040000E8B479
+:1000900000000038000D0014000000040000E8B665
+:1000A00000000038000D0016000000040000E854B5
+:1000B00000000038000D0018000000040000E855A2
+:1000C00000000038000D001A000000040000E8568F
+:1000D00000000038000D001C000000040000E8577C
+:1000E00000000038000D001E000000040000E8249D
+:1000F00000000038000D0020000000040000E8258A
+:1001000000000038000D0022000000040000E8306C
+:1001100000000038000D0024000000040000F0C0C2
+:1001200000000038000D0026000000040000F0C1AF
+:1001300000000038000D0028000000040000F0411D
+:1001400000000038000D002A000000040000F184C7
+:1001500000000038000D002C000000040000F185B4
+:1001600000000038000D002E000000040000F186A1
+:1001700000000038000D0030000000040000F1878E
+:1001800000000038000D0032000000040000F18083
+:1001900000000038000D0034000000040000F3935C
+:1001A00000000038000D0036000000040000F38A53
+:1001B00000000038000D0038000000040000F38E3D
+:1001C000000000040000E821000000040140A0003D
+:1001D00000000018000000430000000400CCE8000C
+:1001E00000000004001B000100000004080048009B
+:1001F00000000004001B000100000004080048008B
+:1002000000000004001B000100000004080048007A
+:10021000000000080000003A000000000000A000FC
+:10022000000000042000451D000000040000E580DF
+:1002300000000004000CE581000000040800458077
+:1002400000000004000CE5810000000800000047E9
+:10025000000000000000A00000000004000C2000CE
+:10026000000000040000E50E000000040003200070
+:10027000000000280002205100000024000000516E
+:10028000000000040800450F000000080000A04B1B
+:10029000000000040000E565000000040000E566C1
+:1002A00000000008000000520000000403CCA5B4C8
+:1002B00000000004054320000000000400022000AC
+:1002C000000000304CCCE05E0000000408274565CB
+:1002D000000000300000005E0000000408004564DB
+:1002E000000000040000E566000000080000005562
+:1002F00000000010008020610000000400202000A9
+:1003000000000004001B00FF00000010010000645A
+:1003100000000004001F200000000004001C00FF7B
+:100320000000000C00000000000000300000008011
+:100330000000000800000055000000040000E57601
+:1003400000000004000CA0000000000400012000D8
+:100350000000000400082000000000041800650EE2
+:10036000000000040009200000000004000A200032
+:1003700000000004000F0000000000040040000026
+:100380000000001800000074000000040000E56395
+:10039000000000C200C0E5F900000008000000698C
+:1003A000000000080000A069000000040000E576DD
+:1003B000000000040000E577000000040000E50EE6
+:1003C000000000040000E50F000000040140A00050
+:1003D0000000001800000077000000C200C0E5F92E
+:1003E0000000000800000077000000040014E50E83
+:1003F000000000040040E50F0000000800C0007A83
+:10040000000000040000E570000000040000E57139
+:100410000000000C0000E572000000040000A000D5
+:10042000000000040140A000000000040000E56896
+:1004300000000004000C20000000001800000084F0
+:1004400000000004000B00000000000418C0E5627A
+:1004500000000008000000860000000800C00085C1
+:1004600000000004000700E30000003800000092D4
+:1004700000000030000CA09400000004080045BB00
+:1004800000000030000C2095000000000800E5BCD2
+:10049000000000040000E5BB000000000000E5BC17
+:1004A0000000000C00120000000000040012000018
+:1004B0000000000C001B0002000000040000A0006F
+:1004C000000000040000E821000000000000E80037
+:1004D000000000040000E821000000000000E82EF9
+:1004E0000000000402CCA000000000040014000082
+:1004F00000000004000CE1CC00000004050DE1CD7B
+:10050000000000040040000000000018000000A4EB
+:100510000000000400C0A00000000008000000A1CE
+:1005200000000020000000A6000000004200E000E3
+:1005300000000038000000AD00000004000CA00026
+:10054000000000040014000000000004000C200063
+:10055000000000040016000000000004700CE00021
+:1005600000000008001400A9000000004000E000A6
+:10057000000000040240000000000004400EE00003
+:100580000000000402400000000000004000E00005
+:1005900000000004000C2000000000040240E51BE5
+:1005A000000000050080E50A000000050080E50B62
+:1005B000000000040022000000000004000700E327
+:1005C00000000038000000C000000030000C209542
+:1005D000000000050880E5BD00000030000C2094FC
+:1005E000000000050800E5BB00000030000C20956D
+:1005F000000000050880E5BC00000008000000C302
+:10060000000000050080E5BD000000050000E5BB1E
+:10061000000000050080E5BC00000004002100008F
+:1006200000000004028000000000001800C000C7A5
+:10063000000000404180E00000000024000000C9EC
+:100640000000000C010000000000000C0100E51D8E
+:1006500000000004000045BB00000008000080C34B
+:10066000000000040000F3CE000000040140A000E0
+:100670000000000400CC20000000004008C053CF60
+:100680000000000000008000000000040000F3D221
+:10069000000000040140A0000000000400CC200085
+:1006A0000000004008C053D300000000000080009C
+:1006B000000000040000F39D000000040140A000C1
+:1006C0000000000400CC20000000004008C0539E41
+:1006D00000000000000080000000000403C008309B
+:1006E000000000004200E000000000040000A00044
+:1006F00000000004200045E0000000000000E5E1EB
+:10070000000000000000000100000004000700E0FD
+:10071000000000000800E39400000000000000005A
+:10072000000000040000E8C4000000040000E8C568
+:10073000000000040000E8C6000000040000E928F2
+:10074000000000040000E929000000040000E92A7C
+:1007500000000008000000E4000000040000E92898
+:10076000000000040000E929000000040000E92A5C
+:1007700000000008000000EB0000000402C02000A0
+:10078000000000040006000000000034000000F338
+:1007900000000008000000F00000000400008000DD
+:1007A00000000000C000E0000000000000000000A9
+:1007B00000000004000C200000000004001D0018D0
+:1007C00000000004001A000100000034000000FBDB
+:1007D000000000080000004A000000080500A04AD0
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:00000001FF
+/* production radeon ucode r1xx-r6xx */
diff --git a/firmware/radeon/R420_cp.bin.ihex b/firmware/radeon/R420_cp.bin.ihex
new file mode 100644
index 0000000..3815891
--- /dev/null
+++ b/firmware/radeon/R420_cp.bin.ihex
@@ -0,0 +1,130 @@
+:10000000000000004200E000000000004000E000AE
+:100010000000000800000099000000080000009D9A
+:10002000000000004A554B4A000000004A4A44675D
+:100030000000000055526F75000000004A7E7D658B
+:1000400000000000D9D3DFF6000000004AC54A4A8C
+:1000500000000000C882828200000000BF4ACFC1B9
+:100060000000000087B04A4A00000000B583838387
+:10007000000000004A0F85BA00000004000CA00038
+:1000800000000038000D0012000000040000E8B479
+:1000900000000038000D0014000000040000E8B665
+:1000A00000000038000D0016000000040000E854B5
+:1000B00000000038000D0018000000040000E855A2
+:1000C00000000038000D001A000000040000E8568F
+:1000D00000000038000D001C000000040000E8577C
+:1000E00000000038000D001E000000040000E8249D
+:1000F00000000038000D0020000000040000E8258A
+:1001000000000038000D0022000000040000E8306C
+:1001100000000038000D0024000000040000F0C0C2
+:1001200000000038000D0026000000040000F0C1AF
+:1001300000000038000D0028000000040000F0411D
+:1001400000000038000D002A000000040000F184C7
+:1001500000000038000D002C000000040000F185B4
+:1001600000000038000D002E000000040000F186A1
+:1001700000000038000D0030000000040000F1878E
+:1001800000000038000D0032000000040000F18083
+:1001900000000038000D0034000000040000F3935C
+:1001A00000000038000D0036000000040000F38A53
+:1001B00000000038000D0038000000040000F38E3D
+:1001C000000000040000E821000000040140A0003D
+:1001D00000000018000000430000000400CCE8000C
+:1001E00000000004001B000100000004080048009B
+:1001F00000000004001B000100000004080048008B
+:1002000000000004001B000100000004080048007A
+:10021000000000080000003A000000000000A000FC
+:10022000000000042000451D000000040000E580DF
+:1002300000000004000CE581000000040800458077
+:1002400000000004000CE5810000000800000047E9
+:10025000000000000000A00000000004000C2000CE
+:10026000000000040000E50E000000040003200070
+:10027000000000280002205100000024000000516E
+:10028000000000040800450F000000080000A04B1B
+:10029000000000040000E565000000040000E566C1
+:1002A00000000008000000520000000403CCA5B4C8
+:1002B00000000004054320000000000400022000AC
+:1002C000000000304CCCE05E0000000408274565CB
+:1002D000000000300000005E0000000408004564DB
+:1002E000000000040000E566000000080000005562
+:1002F00000000010008020610000000400202000A9
+:1003000000000004001B00FF00000010010000645A
+:1003100000000004001F200000000004001C00FF7B
+:100320000000000C0000000000000030000000721F
+:100330000000000800000055000000040000E57601
+:10034000000000040000E577000000040000E50E56
+:10035000000000040000E50F000000040140A000C0
+:100360000000001800000069000000C200C0E5F9AC
+:100370000000000800000069000000040014E50E01
+:10038000000000040040E50F0000000800C0006C01
+:10039000000000040000E570000000040000E571AA
+:1003A0000000000C0000E572000000040000A00046
+:1003B000000000040140A000000000040000E56807
+:1003C00000000004000C200000000018000000766F
+:1003D00000000004000B00000000000418C0E562EB
+:1003E00000000008000000780000000800C000774E
+:1003F00000000004000700C7000000380000008073
+:10040000000000040000E5BB000000000000E5BCA7
+:10041000000000040000A000000000040000E8212B
+:10042000000000000000E800000000040000E821D7
+:10043000000000000000E82E0000000402CCA00034
+:10044000000000040014000000000004000CE1CCD7
+:1004500000000004050DE1CD000000040040000094
+:10046000000000180000008F0000000400C0A00081
+:10047000000000080000008C000000200000009137
+:10048000000000004200E00000000038000000987A
+:1004900000000004000CA000000000040014000094
+:1004A00000000004000C2000000000040016000002
+:1004B00000000004700CE00000000008001400942C
+:1004C000000000004000E0000000000402400000C6
+:1004D00000000004400EE0000000000402400000A4
+:1004E000000000004000E00000000004000C2000BC
+:1004F000000000040240E51B000000050080E50A42
+:10050000000000050080E50B000000040022000050
+:1005100000000004000700C700000038000000A42D
+:10052000000000050080E5BD000000050000E5BBFF
+:10053000000000050080E5BC000000040021000070
+:1005400000000004028000000000001800C000ABA2
+:10055000000000404180E00000000024000000ADE9
+:100560000000000C010000000000000C0100E51D6F
+:1005700000000004000045BB00000008000080A748
+:10058000000000040000F3CE000000040140A000C1
+:100590000000000400CC20000000004008C053CF41
+:1005A0000000000000008000000000040000F3D202
+:1005B000000000040140A0000000000400CC200066
+:1005C0000000004008C053D300000000000080007D
+:1005D000000000040000F39D000000040140A000A2
+:1005E0000000000400CC20000000004008C0539E22
+:1005F00000000000000080000000000403C008307C
+:10060000000000004200E000000000040000A00024
+:1006100000000004200045E0000000000000E5E1CB
+:10062000000000000000000100000004000700C4FA
+:10063000000000000800E39400000000000000003B
+:10064000000000040000E8C4000000040000E8C549
+:10065000000000040000E8C6000000040000E928D3
+:10066000000000040000E929000000040000E92A5D
+:1006700000000008000000C8000000040000E92895
+:10068000000000040000E929000000040000E92A3D
+:1006900000000008000000CF0000000402C020009D
+:1006A000000000040006000000000034000000D735
+:1006B00000000008000000D40000000400008000DA
+:1006C00000000000C000E000000000040000E1CCD9
+:1006D000000000040500E1CD00000004000CA000B3
+:1006E00000000034000000DE00000008000000DA16
+:1006F000000000000000A000000000040019E1CC90
+:1007000000000004001B0001000000040500A00020
+:1007100000000004080041CD00000004000CA0000F
+:1007200000000034000000FB000000080000004A48
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B00000000004000C200000000004001D0018D0
+:1007C00000000004001A000100000034000000FBDB
+:1007D000000000080000004A000000080500A04AD0
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:00000001FF
+/* production radeon ucode r1xx-r6xx */
diff --git a/firmware/radeon/R520_cp.bin.ihex b/firmware/radeon/R520_cp.bin.ihex
new file mode 100644
index 0000000..372ff82
--- /dev/null
+++ b/firmware/radeon/R520_cp.bin.ihex
@@ -0,0 +1,130 @@
+:10000000000000004200E000000000004000E000AE
+:100010000000000800000099000000080000009D9A
+:10002000000000004A554B4A000000004A4A44675D
+:100030000000000055526F75000000004A7E7D658B
+:1000400000000000E0DAE6F6000000004AC54A4A77
+:1000500000000000C882828200000000BF4ACFC1B9
+:100060000000000087B04AD500000000B5838383FC
+:10007000000000004A0F85BA00000004000CA00038
+:1000800000000038000D0012000000040000E8B479
+:1000900000000038000D0014000000040000E8B665
+:1000A00000000038000D0016000000040000E854B5
+:1000B00000000038000D0018000000040000E855A2
+:1000C00000000038000D001A000000040000E8568F
+:1000D00000000038000D001C000000040000E8577C
+:1000E00000000038000D001E000000040000E8249D
+:1000F00000000038000D0020000000040000E8258A
+:1001000000000038000D0022000000040000E8306C
+:1001100000000038000D0024000000040000F0C0C2
+:1001200000000038000D0026000000040000F0C1AF
+:1001300000000038000D0028000000040000E0006E
+:1001400000000038000D002A000000040000E0005C
+:1001500000000038000D002C000000040000E0004A
+:1001600000000038000D002E000000040000E00038
+:1001700000000038000D0030000000040000E00026
+:1001800000000038000D0032000000040000F18083
+:1001900000000038000D0034000000040000F3935C
+:1001A00000000038000D0036000000040000F38A53
+:1001B00000000038000D0038000000040000F38E3D
+:1001C000000000040000E821000000040140A0003D
+:1001D00000000018000000430000000400CCE8000C
+:1001E00000000004001B000100000004080048009B
+:1001F00000000004001B000100000004080048008B
+:1002000000000004001B000100000004080048007A
+:10021000000000080000003A000000000000A000FC
+:10022000000000042000451D000000040000E580DF
+:1002300000000004000CE581000000040800458077
+:1002400000000004000CE5810000000800000047E9
+:10025000000000000000A00000000004000C2000CE
+:10026000000000040000E50E000000040003200070
+:10027000000000280002205100000024000000516E
+:10028000000000040800450F000000080000A04B1B
+:10029000000000040000E565000000040000E566C1
+:1002A00000000008000000520000000403CCA5B4C8
+:1002B00000000004054320000000000400022000AC
+:1002C000000000304CCCE05E0000000408274565CB
+:1002D000000000300000005E0000000408004564DB
+:1002E000000000040000E566000000080000005562
+:1002F00000000010008020610000000400202000A9
+:1003000000000004001B00FF00000010010000645A
+:1003100000000004001F200000000004001C00FF7B
+:100320000000000C0000000000000030000000721F
+:100330000000000800000055000000040000E57601
+:10034000000000040000E577000000040000E50E56
+:10035000000000040000E50F000000040140A000C0
+:100360000000001800000069000000C200C0E5F9AC
+:100370000000000800000069000000040014E50E01
+:10038000000000040040E50F0000000800C0006C01
+:10039000000000040000E570000000040000E571AA
+:1003A0000000000C0000E572000000040000A00046
+:1003B000000000040140A000000000040000E56807
+:1003C00000000004000C200000000018000000766F
+:1003D00000000004000B00000000000418C0E562EB
+:1003E00000000008000000780000000800C000774E
+:1003F00000000004000700C7000000380000008073
+:10040000000000040000E5BB000000000000E5BCA7
+:10041000000000040000A000000000040000E8212B
+:10042000000000000000E800000000040000E821D7
+:10043000000000000000E82E0000000402CCA00034
+:10044000000000040014000000000004000CE1CCD7
+:1004500000000004050DE1CD000000040040000094
+:10046000000000180000008F0000000400C0A00081
+:10047000000000080000008C000000200000009137
+:10048000000000004200E00000000038000000987A
+:1004900000000004000CA000000000040014000094
+:1004A00000000004000C2000000000040016000002
+:1004B00000000004700CE00000000008001400942C
+:1004C000000000004000E0000000000402400000C6
+:1004D00000000004400EE0000000000402400000A4
+:1004E000000000004000E00000000004000C2000BC
+:1004F000000000040240E51B000000050080E50A42
+:10050000000000050080E50B000000040022000050
+:1005100000000004000700C700000038000000A42D
+:10052000000000050080E5BD000000050000E5BBFF
+:10053000000000050080E5BC000000040021000070
+:1005400000000004028000000000001800C000ABA2
+:10055000000000404180E00000000024000000ADE9
+:100560000000000C010000000000000C0100E51D6F
+:1005700000000004000045BB00000008000080A748
+:10058000000000040000F3CE000000040140A000C1
+:100590000000000400CC20000000004008C053CF41
+:1005A0000000000000008000000000040000F3D202
+:1005B000000000040140A0000000000400CC200066
+:1005C0000000004008C053D300000000000080007D
+:1005D000000000040000F39D000000040140A000A2
+:1005E0000000000400CC20000000004008C0539E22
+:1005F00000000000000080000000000403C008307C
+:10060000000000004200E000000000040000A00024
+:1006100000000004200045E0000000000000E5E1CB
+:10062000000000000000000100000004000700C4FA
+:10063000000000000800E39400000000000000003B
+:10064000000000040000E8C4000000040000E8C549
+:10065000000000040000E8C6000000040000E928D3
+:10066000000000040000E929000000040000E92A5D
+:1006700000000008000000C8000000040000E92895
+:10068000000000040000E929000000040000E92A3D
+:1006900000000008000000CF00000000DEADBEEF4B
+:1006A000000000000000011600000004000700D355
+:1006B00000000004080050E700000004000700D418
+:1006C000000000040800401C000000000000E01DC5
+:1006D0000000000402C0200000000004000600002A
+:1006E00000000034000000DE00000008000000DB15
+:1006F000000000040000800000000000C000E000D6
+:10070000000000040000E1CC000000040500E1CD81
+:1007100000000004000CA00000000034000000E510
+:1007200000000008000000E1000000000000A00040
+:10073000000000040019E1CC00000004001B0001CF
+:10074000000000040500A00000000004080041CDE6
+:1007500000000004000CA00000000034000000FBBA
+:10076000000000080000004A000000000000000037
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B00000000004000C200000000004001D0018D0
+:1007C00000000004001A000100000034000000FBDB
+:1007D000000000080000004A000000080500A04AD0
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:00000001FF
+/* production radeon ucode r1xx-r6xx */
diff --git a/firmware/radeon/R600_me.bin.ihex b/firmware/radeon/R600_me.bin.ihex
new file mode 100644
index 0000000..30d4c14
--- /dev/null
+++ b/firmware/radeon/R600_me.bin.ihex
@@ -0,0 +1,1345 @@
+:1000000000000000C020040000000000000000000C
+:1000100000A0000A000000000000FFFF00284621A9
+:100020000000000000000000D900480000000000AF
+:1000300000000000C02004000000000000000000DC
+:1000400000A0000A000000000000000000E0000026
+:100050000000000000010000C02946200000000050
+:1000600000000000D900480000000000000000006F
+:10007000C0200400000000000000000000A0000AF2
+:10008000000000008100000000204411000000007A
+:1000900000000001002048110000000000042004BE
+:1000A0000060441100000614000000000060000021
+:1000B000000005B20000000000600000000005C55F
+:1000C00000000000C02008000000000000000F0039
+:1000D000002816220000000000000008002116255C
+:1000E0000000000000000020002036250000000075
+:1000F0008D000000002044110000000000000004FA
+:10010000002F022500000000000000000CE00000AD
+:1001100000000018004120000040481100000019B4
+:100120000042200000204811000000008E00000066
+:1001300000204411000000000000003100204A2D82
+:1001400000000000900000000020441100000000AA
+:100150000000000000204805000000000000000C26
+:1001600000211622000000000000000300281625D0
+:10017000000000000000001900211A220000000009
+:100180000000000400281A26000000000000000003
+:10019000002914C5000000000000002100203625C1
+:1001A0000000000000000000003A140200000000FF
+:1001B00000000016002116250000000000000003CA
+:1001C00000281625000000000000001D00200E2D54
+:1001D00000000000FFFFFFFC00280E2300000000CD
+:1001E00000000000002914A3000000000000001D12
+:1001F00000203625000000000000800000280E22AC
+:10020000000000000000000700220E230000000094
+:10021000000000000029386E0000000020000000EF
+:1002200000280E22000000000000000600210E231E
+:1002300000000000000000000029386E00000000EF
+:100240000000000000220222000000000000000068
+:1002500014E0000000000038000000002EE0000064
+:1002600000000035000000002CE000000000003716
+:100270000000000000400E2D0000003900000008C2
+:1002800000200E2D00000000000000090040122D8B
+:10029000000000460000000100400E2D0000003963
+:1002A00000000000C0200C0000000000003FFFFC28
+:1002B0000028122300000000000000020022122487
+:1002C000000000000000001F00211E2300000000AD
+:1002D0000000000014E000000000003E00000008E4
+:1002E00000401C11000000410000000D00201E2DE8
+:1002F000000000000000000F00281E270000000082
+:100300000000000300221E27000000007FC0000044
+:1003100000281A23000000000000001400211A2603
+:10032000000000000000000100331A260000000059
+:100330000000000800221A26000000000000000053
+:1003400000290CC700000000000000300020362407
+:100350000000000000007F000028122100000000C3
+:1003600000001400002F0224000000000000000024
+:100370000CE000000000004B0000000100290E23EB
+:1003800000000000000000100020362300000000E4
+:100390000000E0000020441100000000FFF8000011
+:1003A00000294A230000000000000000003A2C024F
+:1003B000000000000000000200220E2B00000000E0
+:1003C000FC00000000280E230000000000000011C7
+:1003D000002036230000000000001FFF00294A23F0
+:1003E000000000000000003000204A2D0000000046
+:1003F0000000000000204811000000000000003252
+:1004000000200E2D00000000060A020000294A23E9
+:100410000000000000000000002048110000000063
+:100420000000000000204811000000000000000152
+:1004300000210222000000000000000014E0000083
+:1004400000000061000000002EE000000000005FDE
+:10045000000000002CE000000000005E0000000032
+:1004600000400E2D000000620000000100400E2D33
+:10047000000000620000000A00200E2D00000000B5
+:100480000000000B0040122D0000006A0000000078
+:10049000C0200C0000000000003FFFFC00281223D9
+:1004A00000000000000000020022122400000000F2
+:1004B0007FC0000000281623000000000000001488
+:1004C0000021162500000000000000010033162561
+:1004D000000000008000000000280E230000000043
+:1004E0000000000000290CA3000000003FFFFC00FA
+:1004F00000290E23000000000000001F00211E2321
+:10050000000000000000000014E000000000006D8A
+:100510000000010000401C11000000700000000DF0
+:1005200000201E2D00000000000000F000281E2703
+:10053000000000000000000400221E270000000050
+:100540008100000000204411000000000000000DA8
+:100550000020481100000000FFFFF0FF00281A30C3
+:10056000000000000000A02800204411000000004E
+:1005700000000000002948E6000000000000A0186C
+:1005800000204411000000003FFFFFFF00284A2325
+:10059000000000000000A010002044110000000036
+:1005A0000000000000204804000000000000002DB2
+:1005B0000020162D0000000000000000002F00A306
+:1005C00000000000000000000CC0000000000080DF
+:1005D0000000002E0020162D00000000000000008A
+:1005E000002F00A400000000000000000CC000006C
+:1005F00000000081000000000040000000000087B3
+:100600000000002D00203623000000000000002E16
+:1006100000203624000000000000001D00201E2DD8
+:10062000000000000000000200210227000000007E
+:100630000000000014E0000000000087000000003F
+:1006400000600000000005ED0000000000600000F8
+:10065000000005E10000000200210E220000000061
+:100660000000000014C000000000008A0000001814
+:10067000C040362000000090000000002EE0000086
+:100680000000008E000000002CE000000000008D43
+:100690000000000200400E2D0000008F000000034B
+:1006A00000400E2D0000008F0000000C00200E2DD9
+:1006B00000000000000000180020362300000000A9
+:1006C0000000000300210E220000000000000000D6
+:1006D00014C00000000000950000A00C0020441190
+:1006E0000000000000000000C020480000000000E2
+:1006F00000000000C04048000000009D0000A00C69
+:1007000000204411000000000000000000204811FB
+:1007100000000000000000002EE000000000009B30
+:10072000000000002CE000000000009A0000000221
+:1007300000400E2D0000009C0000000300400E2D24
+:100740000000009C0000000C00200E2D00000000A6
+:10075000000000000020480300000000000000002E
+:10076000003A0C0200000000003F000000280E23A9
+:10077000000000000000001000210E230000000017
+:100780000000001300203623000000000000001EBF
+:100790000021022B000000000000000014C0000037
+:1007A000000000A40000001CC02036200000000053
+:1007B0000000001F0021022B0000000000000000CC
+:1007C00014C00000000000A70000001BC02036205D
+:1007D000000000000000000800210E2B00000000B7
+:1007E0000000007F00280E23000000000000000031
+:1007F000002F022300000000000000000CE00000B9
+:10080000000000DB000000002700000000000000E6
+:1008100000000000006000000000028C8100000069
+:1008200000204411000000000000000600204811D4
+:10083000000000000000000C00221E30000000003C
+:100840009980000000204411000000000000000416
+:100850000020122D000000000000000800221224D9
+:10086000000000000000001000201811000000002F
+:100870000000000000291CE400000000000000004F
+:1008800000604807000001289B0000000020441180
+:1008900000000000000000000020480200000000EE
+:1008A0009C00000000204411000000000000000037
+:1008B0000033146F000000000000000100333E23ED
+:1008C0000000000000000000D90048000000000007
+:1008D0000000000000203C05000000008100000036
+:1008E00000204411000000000000000E002048110C
+:1008F00000000000000000000020101000000000B8
+:100900000000E00700204411000000000000000F7C
+:100910000021022B000000000000000014C00000B5
+:10092000000000C500F8FF0800204811000000008A
+:100930009800000000404811000000D6000000F0C0
+:1009400000280E2200000000000000A0002F02235B
+:1009500000000000000000000CC00000000000D4F7
+:100960000000001300200E2D000000000000000118
+:10097000002F022300000000000000000CE0000037
+:10098000000000CF00000002002F02230000000042
+:10099000000000000CE00000000000CE00003F005E
+:1009A00000400C11000000D000001F0000400C119E
+:1009B000000000D000000F0000200C11000000001B
+:1009C0000038000900294A23000000003F00000011
+:1009D00000280E2B000000000000000200220E2361
+:1009E000000000000000000700494A23000000D674
+:1009F00000380F09002048110000000068000007BF
+:100A000000204811000000000000000800214A27D3
+:100A1000000000000000000000204811000000005D
+:100A2000060A020000294A2400000000000000001D
+:100A300000204811000000000000000000204811C4
+:100A4000000000000000A20200204411000000008D
+:100A500000FF000000284A220000000000000030D3
+:100A600000200E2D000000000000002E0020122D9E
+:100A70000000000000000000002F008300000000C4
+:100A8000000000000CE00000000000E30000000097
+:100A900000600000000005E70000000000400000CA
+:100AA000000000E40000000000600000000005EA13
+:100AB000000000070020222D0000000000000005BB
+:100AC00000220E22000000000010000000280E236B
+:100AD0000000000000000000002920680000000065
+:100AE00000000000003A0C0200000000000000EFCF
+:100AF00000280E23000000000000000000292068EC
+:100B0000000000000000001D00200E2D000000006D
+:100B1000000000030021022300000000000000008C
+:100B200014E00000000000F10000000B002102288A
+:100B3000000000000000000014C00000000000F1F0
+:100B40000000040000292228000000000000001A14
+:100B500000203628000000000000001C00210E22AA
+:100B6000000000000000000014C00000000000F6BB
+:100B70000000A30C00204411000000000000000051
+:100B800000204811000000000000001E00210E227D
+:100B9000000000000000000014C00000000001047C
+:100BA0000000A30F0020441100000000000000130B
+:100BB00000200E2D0000000000000001002F022385
+:100BC00000000000000000000CC00000000000FD5C
+:100BD000FFFFFFFF00404811000001040000000279
+:100BE000002F022300000000000000000CC00000E5
+:100BF000000001000000FFFF004048110000010458
+:100C000000000004002F022300000000000000008C
+:100C10000CC0000000000103000000FF004048116C
+:100C20000000010400000001002048110000000045
+:100C30000002C40000204411000000000000001F5A
+:100C400000210E22000000000000000014C000007F
+:100C50000000010B0000001040210E2000000000E9
+:100C600000000019002036230000000000000018DA
+:100C700040224A200000000000000010C0424A202C
+:100C80000000010D0000000000200C110000000019
+:100C900000000019002036230000000000000000C2
+:100CA0000020481100000000000000000020481152
+:100CB000000000000000000A0020101100000000E9
+:100CC00000000000002F02240000000000000000CF
+:100CD0000CE000000000011400000000002048119A
+:100CE0000000000000000001005312240000011069
+:100CF000FFBFFFFF00283A2E000000000000001B8D
+:100D000000210222000000000000000014C00000CA
+:100D100000000127810000000020441100000000B5
+:100D20000000000D00204811000000000000001825
+:100D300000220E3000000000FC00000000280E23FE
+:100D400000000000810000000020441100000000AD
+:100D50000000000E0020481100000000000000000C
+:100D600000201010000000000000E00E00204411E0
+:100D70000000000007F8FF080020481100000000F4
+:100D80000000000000294A230000000000000024A9
+:100D900000201E2D000000000000000800214A274E
+:100DA00000000000000000000020481100000000CA
+:100DB000060A020000294A2400000000000000008A
+:100DC0000020481100000000000000000020481131
+:100DD0000000000000000000008000000000000093
+:100DE000810000000020441100000000000000010C
+:100DF00000204811000000000000217C0020441168
+:100E000000000000008000000020481100000000E9
+:100E1000000000000020480600000000000000085C
+:100E200000214A2700000000000000001700000019
+:100E3000000000000004217F00604411000006143F
+:100E40000000001F00210230000000000000000030
+:100E500014C00000000006130000000400404C1104
+:100E60000000012E00000000006000000000000BE8
+:100E70000000000000600411000002FE00000000FD
+:100E800000200411000000000000000000600811B4
+:100E90000000019F00000000006000000000015100
+:100EA0000000FFFF40280E2000000000000000109E
+:100EB000C0211220000000000000FFFF4028062093
+:100EC0000000000000000010C0210A200000000007
+:100ED0000000000000341461000000000000000069
+:100EE00000741882000002A40001A1FD00604411FA
+:100EF000000002C900003FFF002F022F0000000089
+:100F0000000000000CC000000000013800000000DC
+:100F1000C04004000000000100000000006000006C
+:100F20000000000B0000000000600411000002FE41
+:100F3000000000000020041100000000000000007C
+:100F4000006008110000019F00003FFF002F022FEA
+:100F500000000000000000000CE0000000000000A5
+:100F600000000000006000000000015100000010BF
+:100F700040210E20000000000000FFFFC0281220CA
+:100F800000000000000000104021162000000000BA
+:100F90000000FFFFC0681A20000002A40001A1FDAC
+:100FA00000604411000002C900003FFF002F022F23
+:100FB00000000000000000000CC00000000001491B
+:100FC00000000000C0400400000000010000225C9E
+:100FD00000204411000000000000000100300A2F32
+:100FE000000000000000000100210A2200000000B3
+:100FF0000000000300384A220000000000002256D2
+:1010000000204411000000000000001A00204811D8
+:10101000000000000000A1FC0020441100000000BE
+:1010200000000001008048110000000000000000E6
+:10103000006000000000000B0000000000600000E5
+:101040000000017C00000000006000000000018D35
+:1010500000003FFF002F022F0000000000000000F2
+:101060000CE00000000000000000000000202C0840
+:10107000000000000000000000202411000000001B
+:10108000000000000020281100000000000022568F
+:10109000002044110000000000000016002048114C
+:1010A000000000000000225C00204411000000004D
+:1010B00000000003002048110000000093800000A1
+:1010C00000204411000000000000000200221E2940
+:1010D0000000000000000000007048EB00000189E3
+:1010E0000000000000600000000002A400000001F9
+:1010F000403306200000000000000000C03024093A
+:101100000000000000003FFF002F022F0000000041
+:10111000000000000CE000000000000000000000E3
+:10112000006000000000028C9500000000204411C7
+:101130000000000000000000002F0221000000005D
+:10114000000000000CE0000000000173000000003F
+:10115000C0204800000000000000000100530621EC
+:101160000000016F92000000002044110000000008
+:1011700000000000C0604800000001840001A1FDE3
+:101180000020441100000000000000130020062D84
+:1011900000000000000000000078042A000002E4C3
+:1011A00000000000002028090000000000003FFFB0
+:1011B000002F022F00000000000000000CC0000003
+:1011C0000000016500000000C040040000000001B4
+:1011D0000000021000600411000002FE00003FFF4A
+:1011E000002F022F00000000000000000CE00000B3
+:1011F000000001810000001BC0203620000000001C
+:101200000000001CC0203620000000003F800000CD
+:1012100000200411000000004600000000600811DA
+:101220000000019F0000000000800000000000009E
+:101230000000A1FC002044110000000000003FFF5E
+:10124000002F022F00000000000000000CC0000072
+:10125000000001880000000100804811000000002B
+:101260000000002100804811000000000000FFFF86
+:1012700040280E200000000000000010C0211220B5
+:10128000000000000000FFFF4028162000000000C2
+:1012900000000010C0811A20000000008100000042
+:1012A000002044110000000000000006002048114A
+:1012B000000000000000000800221E3000000000B6
+:1012C0000000003200201A2D000000000000E000A5
+:1012D0000020441100000000FFFBFF09002048111E
+:1012E00000000000000000110020222D000000007E
+:1012F00000001FFF00294A2800000000000000062F
+:101300000020222D0000000000000000002920E83D
+:10131000000000000000000000204808000000005D
+:10132000000000000020481100000000060A020032
+:1013300000294A260000000000000000002048119B
+:101340000000000000000000002048110000000024
+:10135000000001000020181100000000000000083B
+:1013600000621E28000001280000000800822228D8
+:10137000000000000002C000002044110000000036
+:101380000000001B00600E2D000001AA0000001CE0
+:1013900000600E2D000001AA0000C00800204411CA
+:1013A000000000000000001D00200E2D00000000C5
+:1013B0000000000014C00000000001A600000000B2
+:1013C000002004110000000000000000002048017F
+:1013D000000000003900000000204811000000005B
+:1013E0000000000000204811000000000000000084
+:1013F00000804802000000000000002000202E2D88
+:101400000000000000000000003B0D630000000031
+:101410000000000800224A23000000000000001025
+:1014200000224A23000000000000001800224A2386
+:1014300000000000000000000080480300000000E1
+:1014400000000000006000000000000B0000100021
+:1014500000600411000002FE0000000000200411E2
+:101460000000000000000000006008110000019F63
+:10147000000000070021062F0000000000000019F6
+:1014800000200A2D000000000000000100202C11A7
+:10149000000000000000FFFF4028222000000000A4
+:1014A0000000000F002622280000000000000010AD
+:1014B00040212620000000000000000F0026262901
+:1014C00000000000000000000020280200000000D2
+:1014D0000000225600204411000000000000001B04
+:1014E000002048110000000000000000002F022131
+:1014F00000000000000000000CE00000000001CD32
+:101500000000225C00204411000000000000008167
+:1015100000204811000000000000A1FC0020441140
+:101520000000000000000001002048110000000041
+:101530000000008000201C110000000000000000DE
+:10154000002F022700000000000000000CE0000057
+:10155000000001C90000000000600000000001D68A
+:101560000000000100531E27000001C5000000011B
+:1015700000202C11000000000000001F00280A229B
+:10158000000000000000001F00282A2A00000000C0
+:101590000000000100530621000001BE0000225C93
+:1015A00000204411000000000000000200304A2F1B
+:1015B000000000000000A1FC002044110000000019
+:1015C00000000001002048110000000000000001A0
+:1015D00000301E2F0000000000000000002F022736
+:1015E00000000000000000000CE00000000000000F
+:1015F0000000000000600000000001D600000001B3
+:1016000000531E27000001D20000FFFF40280E20DB
+:10161000000000000000000F00260E230000000064
+:1016200000000010C0211220000000000000000F88
+:101630000026122400000000000000000020141109
+:10164000000000000000000000601811000002A46B
+:101650000001A1FD00204411000000000000000076
+:10166000002F022B00000000000000000CE0000032
+:10167000000001E500000010002216280000000014
+:10168000FFFF000000281625000000000000FFFFFB
+:1016900000281A290000000000000000002948C5A9
+:1016A00000000000000000000020480A00000000C8
+:1016B0000000000000202C110000000000000010BD
+:1016C0000022162300000000FFFF0000002816255E
+:1016D000000000000000FFFF00281A2400000000A6
+:1016E00000000000002948C50000000000000000C4
+:1016F00000731503000001F200000000002018052F
+:10170000000000000000000000731524000001F23A
+:1017100000000000002D14C50000000000000000C3
+:10172000003008A200000000000000000020480275
+:10173000000000000000000000202802000000005F
+:101740000000000000202003000000000000000056
+:1017500000802404000000000000000F002102258A
+:10176000000000000000000014C00000000006138C
+:1017700000000000002B1405000000000000000124
+:10178000009016250000000000000000006000002E
+:101790000000000B0000000000600411000002FEC9
+:1017A0000000000000200411000000000000000004
+:1017B000006008110000019F000022560020441123
+:1017C000000000000000001A00294A22000000006A
+:1017D00000000000C02000000000000000003FFFEB
+:1017E000002F022F00000000000000000CE00000AD
+:1017F0000000000000000000C02004000000000005
+:101800000000225C002044110000000000000003E2
+:1018100000384A21000000000000A1FC0020441113
+:10182000000000000000000100204811000000003E
+:101830000000FFFF40281220000000000000001000
+:10184000C0211A20000000000000FFFF40280E20E9
+:101850000000000000000010C02116200000000061
+:101860000000000000741465000002A40001A1FD46
+:1018700000604411000002C900000001003306218D
+:101880000000000000000000002F02210000000006
+:10189000000000000CC000000000020600003FFF36
+:1018A000002F022F00000000000000000CC000000C
+:1018B000000001FF00000000C04004000000000123
+:1018C0000000000000600000000005C500000000EE
+:1018D0000040040F00000200000000000060000053
+:1018E000000005B20000000000600000000005C517
+:1018F0000000021000600411000002FE0000000061
+:10190000006000000000018D000000000060000089
+:10191000000001890000000000600000000002A437
+:1019200000000000006000000000028C93800000B6
+:1019300000204411000000000000000000204808C2
+:10194000000000009500000000204411000000008D
+:1019500000000000002F022F000000000000000027
+:101960000CE000000000021F00000000C040480022
+:101970000000021C92000000002044110000000042
+:1019800000000000C02048000000000000002256B7
+:101990000020441100000000000000160020481143
+:1019A000000000000000225C002044110000000044
+:1019B0000000000300204811000000000000A1FC0E
+:1019C0000020441100000000000000010020481128
+:1019D000000000000001A1FD0020441100000000F3
+:1019E0000000000000600411000002E4000000009C
+:1019F000C040040000000001000000000060000082
+:101A0000000005B20000A00C0020441100000000FE
+:101A100000000000C020480000000000000000009E
+:101A2000C04048000000000000000000006000000E
+:101A30000000000B0000001840210A2000000000F8
+:101A400000000003002F0222000000000000000040
+:101A50000AE00000000002350000001A0020222DDC
+:101A600000000000000801010029222800000000F9
+:101A70000000001A00203628000000000000A30C1F
+:101A8000002044110000000000000000C0204800B9
+:101A90000000000000000000C0204800000000001E
+:101AA00000000000C04048000000023A00000000B2
+:101AB000006000000000000B000000100060041136
+:101AC000000002FE3F800000002004110000000022
+:101AD00000000000006008110000019F0000225C6F
+:101AE0000020441100000000000000030020481105
+:101AF000000000000000000000600000000002651F
+:101B00000000001D00201E2D00000000000000014C
+:101B100000211E27000000000000000014E000006B
+:101B2000000002530000001800201E2D00000000DD
+:101B30000000FFFF00281E2700000000000000003A
+:101B400000341C27000000000000000012C000004C
+:101B5000000002480000000000201C1100000000EE
+:101B600000000000002F00E5000000000000000061
+:101B700008C000000000024B000000000020140715
+:101B8000000000000000001800201E2D00000000D2
+:101B90000000001000211E270000000000000000CF
+:101BA00000341C47000000000000000012C00000CC
+:101BB000000002500000000000201C110000000086
+:101BC00000000000002F00E6000000000000000000
+:101BD00008C00000000002530000000000201807A9
+:101BE000000000000000000000600000000002AAE9
+:101BF00000002256002044110000000000000000F8
+:101C000000342023000000000000000012C000008B
+:101C10000000025B000000000034204400000000CF
+:101C20000000000012C000000000025A0000001670
+:101C3000004048110000025F0000001800404811F9
+:101C40000000025F0000000000342044000000009B
+:101C50000000000012C000000000025E000000173B
+:101C6000004048110000025F0000001900204811E8
+:101C7000000000000000A1FC002044110000000052
+:101C80000000000100204811000000000001A1FD3B
+:101C900000604411000002D200003FFF002F022F1D
+:101CA00000000000000000000CC000000000023F27
+:101CB00000000000C040040000000001000000100F
+:101CC00040210620000000000000FFFFC0280A207D
+:101CD000000000000000001040210E200000000065
+:101CE0000000FFFFC02812200000000000000010CC
+:101CF00040211620000000000000FFFFC0881A20CD
+:101D000000000000810000000020441100000000DD
+:101D10000000000100204811000000000004200421
+:101D20000060441100000614000000000060000084
+:101D3000000005B200000000C06000000000028C3E
+:101D40000000000500200A2D00000000000000082F
+:101D500000220A22000000000000003400201A2D9A
+:101D6000000000000000002400201E2D00000000E4
+:101D70000000700000281E27000000000000000086
+:101D800000311CE6000000000000003300201A2D86
+:101D9000000000000000000C00221A2600000000D5
+:101DA00000000000002F00E600000000000000001E
+:101DB00006E000000000027B0000000000201C1173
+:101DC000000000000000000000200C1100000000D6
+:101DD0000000003400203623000000000000001046
+:101DE00000201811000000000000000000691CE243
+:101DF0000000012893800000002044110000000032
+:101E000000000000002048070000000095000000CE
+:101E1000002044110000000000000000002F022FED
+:101E200000000000000000000CE00000000002863E
+:101E30000000000100333E2F000000000000000001
+:101E4000D90048000000000092000000002044116A
+:101E50000000000000000000C0204800000000005A
+:101E60000000002400403627000000000000000CA5
+:101E7000C0220A20000000000000003200203622AC
+:101E80000000000000000031C040362000000000CB
+:101E90000000A2A40020441100000000000000097E
+:101EA0000020481100000000A100000000204411A3
+:101EB0000000000000000001008048110000000048
+:101EC0000000002900201E2D00000000000000007E
+:101ED000002C1CE300000000000000290020362731
+:101EE000000000000000002A00201E2D000000005D
+:101EF00000000000002C1CE4000000000000002A8C
+:101F000000203627000000000000002B00201E2DBE
+:101F10000000000000000000003120A300000000CD
+:101F200000000000002D1D07000000000000002B35
+:101F300000203627000000000000002C00201E2D8D
+:101F40000000000000000000003120C4000000007C
+:101F500000000000002D1D07000000000000002C04
+:101F600000803627000000000000002900203623F2
+:101F7000000000000000002A0020362400000000BD
+:101F80000000000000311CA3000000000000002B36
+:101F900000203627000000000000000000311CC4B3
+:101FA000000000000000002C008036270000000028
+:101FB000000000220020362700000000000000235F
+:101FC00000203628000000000000001D00201E2D0B
+:101FD00000000000000000020021022700000000B5
+:101FE0000000000014C00000000002C50000000056
+:101FF00000400000000002C200000022002036273E
+:10200000000000000000002300203628000000002F
+:102010000000001D00201E2D000000000000000236
+:1020200000210227000000000000000014E0000072
+:10203000000002C20000000300210227000000008F
+:102040000000000014E00000000002C50000002BAA
+:1020500000201E2D0000000000000000002E00E106
+:10206000000000000000000002C00000000002C5E7
+:102070000000002900201E2D0000000000000000CC
+:10208000003120A10000000000000000002E00E848
+:10209000000000000000000006C00000000002C5B3
+:1020A0000000002C00201E2D000000000000000099
+:1020B000002E00E2000000000000000002C000004E
+:1020C000000002C50000002A00201E2D00000000B4
+:1020D00000000000003120C20000000000000000ED
+:1020E000002E00E8000000000000000006C0000014
+:1020F000000002C50000000000600000000005EDC7
+:1021000000000000006000000000029E00000000CF
+:1021100000400000000002C7000000000060000056
+:102120000000029E0000000000600000000005E4C6
+:102130000000000000400000000002C70000000096
+:10214000006000000000029000000000004000005D
+:10215000000002C70000002200201E2D0000000029
+:10216000000000230080222D00000000000000106D
+:1021700000221E2300000000000000000029488704
+:10218000000000000000000000311CA3000000005F
+:102190000000001000221E270000000000000000C8
+:1021A00000294887000000000000001000221E23C4
+:1021B0000000000000000000003120C4000000000A
+:1021C0000000FFFF0028222800000000000000009F
+:1021D00000894907000000000000001000221E23B3
+:1021E00000000000000000000029488700000000F7
+:1021F0000000001000221E2100000000000000006E
+:1022000000294847000000000000000000311CA326
+:10221000000000000000001000221E270000000047
+:1022200000000000002948870000000000000000B6
+:1022300000311CA1000000000000001000221E2739
+:1022400000000000000000000029484700000000D6
+:102250000000001000221E2300000000000000000B
+:10226000003120C4000000000000FFFF00282228E9
+:1022700000000000000000000029490700000000E5
+:102280000000001000221E210000000000000000DD
+:10229000003120C2000000000000FFFF00282228BB
+:1022A0000000000000000000008949070000000055
+:1022B0000000001000221E230000000000000000AB
+:1022C00000294887000000000000000100220A21C8
+:1022D0000000000000000000003308A20000000021
+:1022E0000000001000221E2200000000000000106C
+:1022F0000021222200000000000000000029490700
+:10230000000000000000000000311CA300000000DD
+:102310000000001000221E27000000000000000046
+:1023200000294887000000000000000100220A2167
+:102330000000000000000000003008A200000000C3
+:102340000000001000221E2200000000000000100B
+:10235000002122220000000000000000002949079F
+:10236000000000000000001000221E2300000000FA
+:1023700000000000003120C4000000000000FFFF4A
+:102380000028222800000000000000000029490762
+:102390000000000000000000003808C50000000038
+:1023A00000000000003008410000000000000001B3
+:1023B00000220A220000000000000000003308A2F2
+:1023C000000000000000001000221E22000000009B
+:1023D0000000001000212222000000000000000088
+:1023E00000894907000000000000001D0020222D88
+:1023F000000000000000000014C000000000030105
+:10240000FFFFFFEF00280621000000000000001A77
+:102410000020222D000000000000F8E00020441100
+:102420000000000000000000002949010000000039
+:1024300000000000008949010000000000000000C9
+:10244000002048110000000000000000002048119A
+:1024500000000000060A0200008048110000000091
+:1024600000000000C02000000000000097000000F5
+:10247000C02044110000000000000000C0204811EE
+:10248000000000008A00000000204411000000004D
+:102490000000000000204811000000000000225C45
+:1024A000002044110000000000000000C02048008F
+:1024B000000000000000A1FC00204411000000000A
+:1024C00000000000C02048000000000000000000E4
+:1024D000C0200400000000000000000000A0000A6E
+:1024E00000000000970000000020441100000000E0
+:1024F0000000000000204811000000008A000000D9
+:1025000000204411000000000000000000204811DD
+:10251000000000000000225C0020441100000000C8
+:1025200000000000C0204800000000000000A1FCE6
+:10253000002044110000000000000000C0204800FE
+:102540000000000000000000C020040000000000A7
+:102550000000000000A0000A00000000970000003A
+:10256000002044110000000000000000002048117D
+:10257000000000008A00000000204411000000005C
+:102580000000000000204811000000000000225C54
+:10259000002044110000000000000000C02048009E
+:1025A000000000000000A1FC002044110000000019
+:1025B00000000000C0204800000000000001A1FD54
+:1025C000002044110000000000000000D900480075
+:1025D0000000000000000000C02004000000000017
+:1025E0000000000000A0000A0000000000002257C8
+:1025F000002044110000000000000003C0484A20F1
+:10260000000000000000225D0020441100000000D6
+:1026100000000000C0404800000000000000000072
+:1026200000600000000005C500000000C020080098
+:10263000000000000000225C0020441100000000A7
+:102640000000000300384A22000000000000A1FC46
+:10265000002044110000000000000000C0204800DD
+:10266000000000000001A1FD002044110000000056
+:1026700000000000002F0222000000000000000007
+:102680000CE00000000000000000000040204800B6
+:10269000000000000000000140304A20000000005F
+:1026A00000000002C0304A200000000000000001CD
+:1026B00000530A22000003340000003FC0280A2013
+:1026C0000000000081000000002044110000000014
+:1026D000000000010020481100000000000021F867
+:1026E00000204411000000000000001700204811E5
+:1026F00000000000000421F90060441100000614ED
+:102700000000001100210230000000000000000065
+:1027100014E000000000033D00000014002F02221E
+:1027200000000000000000000CC000000000035189
+:102730000000201000204411000000000000800074
+:1027400000204811000000000001A2A40020441154
+:102750000000000000000000002048110000000000
+:1027600000000016006048110000035E0000210018
+:10277000002044110000000000000000C0204800BC
+:102780000000000000000000C02048000000000021
+:1027900000000000C0204800000000000000000011
+:1027A000C0204800000000000001A2A40020441145
+:1027B00000000000000000000020481100000000A0
+:1027C000000000000040480200000000000000047B
+:1027D000002F022200000000000000000CC00000DA
+:1027E00000000355000020100020441100000000EC
+:1027F000000080000040481100000349000000284C
+:10280000002F022200000000000000000CE0000089
+:1028100000000349000021040020441100000000D2
+:1028200000000000C0204800000000000000000080
+:10283000C02048000000000000000000C020480048
+:102840000000000000000000C02048000000000060
+:102850000000A2A4002044110000000000000000BD
+:10286000004048020000000000000035002036262D
+:1028700000000000000000490020181100000000C6
+:1028800000000000002048110000000000000001CE
+:1028900000331A260000000000000000002F02266E
+:1028A00000000000000000000CC0000000000360F9
+:1028B0000000003500801A2D000000000000003FDD
+:1028C000C0280A200000000000000015002F02228E
+:1028D00000000000000000000CE000000000037693
+:1028E0000000001E002F0222000000000000000077
+:1028F0000CE000000000038000000020002F0222F6
+:1029000000000000000000000CE000000000038C4C
+:102910000000000F002F0222000000000000000055
+:102920000CE000000000039800000010002F0222BD
+:1029300000000000000000000CE000000000039810
+:1029400000000006002F022200000000000000002E
+:102950000CE000000000039A00000016002F022285
+:1029600000000000000000000CE000000000039FD9
+:102970000000A2A40020441100000000000000009C
+:1029800000404802000000000800000000290A2260
+:10299000000000000000000340210E2000000000A5
+:1029A0000000000CC0211220000000000008000000
+:1029B000002812240000000000000014C02216208D
+:1029C0000000000000000000002914A40000000026
+:1029D0000000A2A40020441100000000000000003C
+:1029E000002948A2000000000000A1FE00204411C0
+:1029F000000000000000000000404803000000004C
+:102A000081000000002044110000000000000001CF
+:102A10000020481100000000000021F800204411AF
+:102A20000000000000000015002048110000000018
+:102A3000000421F900604411000006140000001594
+:102A400000210230000000000000000014E000003F
+:102A5000000003820000210E00204411000000004D
+:102A600000000000C020480000000000000000003E
+:102A7000C0204800000000000000A2A40020441173
+:102A800000000000000000000040480200000000BC
+:102A9000810000000020441100000000000000013F
+:102AA0000020481100000000000021F8002044111F
+:102AB0000000000000000016002048110000000087
+:102AC000000421F900604411000006140000000316
+:102AD00000210230000000000000000014E00000AF
+:102AE0000000038E000021080020441100000000B7
+:102AF00000000000C02048000000000000000000AE
+:102B0000C0204800000000000000A2A400204411E2
+:102B1000000000000000000000404802000000002B
+:102B20000000201000204411000000000000800080
+:102B30000040481100000000000020100020441157
+:102B4000000000000000800000204811000000008C
+:102B50000001A2A4002044110000000000000000B9
+:102B6000002048110000000000000006004048114D
+:102B700000000000000020100020441100000000B0
+:102B80000000800000204811000000000001A2A405
+:102B90000020441100000000000000000020481147
+:102BA0000000000000000016006048110000035EF5
+:102BB0000000001600404811000000000000000066
+:102BC000C02008000000000000000000C0200C0031
+:102BD000000000000000001D002102230000000092
+:102BE0000000000014E00000000003B981000000B4
+:102BF00000204411000000000000000100204811E6
+:102C000000000000000021F8002044110000000036
+:102C1000000000170020481100000000000421F906
+:102C20000060441100000614000000110021023071
+:102C3000000000000000000014E00000000003ABF2
+:102C400000002100002044110000000000000000EE
+:102C5000002048020000000000000000002048039F
+:102C600000000000BABECAFE0020481100000000AB
+:102C7000CAFEBABE0020481100000000000020106B
+:102C800000204411000000000000800000204811D6
+:102C9000000000000000A2A4002044110000000079
+:102CA00000000004004048110000000000002170F6
+:102CB0000020441100000000000000000020480235
+:102CC0000000000000000000002048030000000099
+:102CD0008100000000204411000000000000000AF4
+:102CE000002048110000000000000000002000103B
+:102CF000000000000000000014C00000000003BE3F
+:102D00008C0000000020441100000000CAFEBABE82
+:102D10000040481100000000810000000020441124
+:102D20000000000000000001002048110000000029
+:102D300000003FFF40280A20000000008000000043
+:102D400040280E200000000040000000C028122093
+:102D50000000000000040000006946220000061484
+:102D6000000000000020141000000000000000001F
+:102D7000002F022300000000000000000CC0000033
+:102D8000000003CC00000000C0401800000003CF8A
+:102D900000003FFFC0281A200000000000040000CF
+:102DA00000694626000006140000000000201810EC
+:102DB0000000000000000000002F022400000000BE
+:102DC000000000000CC00000000003D20000000062
+:102DD000C0401C00000003D500003FFFC0281E209B
+:102DE00000000000000400000069462700000614EF
+:102DF0000000000000201C10000000000000000087
+:102E0000002044020000000000000000002820C54F
+:102E10000000000000000000004948E80000000039
+:102E2000A580000000200811000000000000200024
+:102E300000200C110000000083000000006044111D
+:102E4000000003FD0000000000204402000000001C
+:102E500000000000C020480000000000000000004A
+:102E600040204800000000000000001FC021022098
+:102E7000000000000000000014C00000000003E299
+:102E8000000020100020441100000000000080001D
+:102E900000204811000000000000FFFFC048122081
+:102EA000000003EAA78000000020081100000000D5
+:102EB0000000A00000200C110000000083000000B2
+:102EC00000604411000003FD0000000000204402E7
+:102ED0000000000000000000C020480000000000CA
+:102EE00000000000C0204800000000000000FFFFBC
+:102EF000C0281220000000008300000000204411C0
+:102F000000000000000000000030488300000000C6
+:102F100084000000002044110000000000000000B8
+:102F2000C020480000000000000000001D0000005C
+:102F3000000000008300000000604411000003FD59
+:102F400000000000C040040000000001A980000053
+:102F500000200811000000000000C00000400C111B
+:102F6000000003E5AB800000002008110000000015
+:102F70000000F8E000400C11000003E5AD80000007
+:102F800000200811000000000000F88000400C1133
+:102F9000000003E5B38000000020081100000000DD
+:102FA0000000F3FC00400C11000003E5AF800000BE
+:102FB00000200811000000000000E00000400C119B
+:102FC000000003E5B18000000020081100000000AF
+:102FD0000000F00000400C11000003E58300000039
+:102FE000002044110000000000002148002048118A
+:102FF00000000000840000000020441100000000D8
+:1030000000000000C0204800000000000000000098
+:103010001D00000000000000000000000080000013
+:103020000000000000182000C03046200000000012
+:1030300000000000D900480000000000000000006F
+:10304000C0200400000000000000000000A0000AF2
+:10305000000000000018A000C03046200000000062
+:1030600000000000D900480000000000000000003F
+:10307000C0200400000000000000000000A0000AC2
+:10308000000000000018C000C03046200000000012
+:1030900000000000D900480000000000000000000F
+:1030A000C0200400000000000000000000A0000A92
+:1030B000000000000018F8E0C030462000000000CA
+:1030C00000000000D90048000000000000000000DF
+:1030D000C0200400000000000000000000A0000A62
+:1030E000000000000018F880C030462000000000FA
+:1030F00000000000D90048000000000000000000AF
+:10310000C0200400000000000000000000A0000A31
+:10311000000000000018E000C03046200000000061
+:1031200000000000D900480000000000000000007E
+:10313000C0200400000000000000000000A0000A01
+:10314000000000000018F000C03046200000000021
+:1031500000000000D900480000000000000000004E
+:10316000C0200400000000000000000000A0000AD1
+:10317000000000000018F3FCC030462000000000F2
+:1031800000000000D900480000000000000000001E
+:10319000C0200400000000000000000000A0000AA1
+:1031A0000000000086000000002044110000000024
+:1031B0000000000000404801000000008500000001
+:1031C0000020441100000000000000000040480101
+:1031D000000000000000217C0020441100000000DD
+:1031E00000000000C02048000000000000000000B7
+:1031F000C02048000000000000000000C02048007F
+:1032000000000000810000000020441100000000C8
+:103210000000000100204811000000000000000034
+:10322000C02008000000000000000000170000009F
+:10323000000000000004217F00604411000006141B
+:103240000000001F0021023000000000000000000C
+:1032500014C00000000000000000000000404C020C
+:103260000000042E00000000C0200C000000000040
+:1032700000000000C020100000000000000000005E
+:10328000C02014000000000000000000C020180052
+:103290000000000000000000C0201C000000000032
+:1032A00000007F0000280A21000000000000450007
+:1032B000002F022200000000000000000CE00000CF
+:1032C0000000043C00000000C020200000000000BE
+:1032D00000000000170000000000000000000010C7
+:1032E00000280A230000000000000010002F022226
+:1032F00000000000000000000CE00000000004449A
+:1033000081000000002044110000000000000001C6
+:10331000002048110000000000040000006946245D
+:103320000000061400000000004000000000044DF2
+:103330008100000000204411000000000000000097
+:1033400000204811000000000000216D0020441101
+:103350000000000000000000002048040000000001
+:1033600000000000002048050000000000000000F0
+:103370001AC00000000004499E0000000020441113
+:1033800000000000CAFEBABE002048110000000084
+:10339000000000001AE000000000044C00000000E3
+:1033A000002824F0000000000000000700280A2385
+:1033B0000000000000000001002F022200000000B9
+:1033C000000000000AE000000000045400000000BB
+:1033D000002F00C9000000000000000004E0000011
+:1033E0000000046D00000000004000000000047AAE
+:1033F00000000002002F0222000000000000000078
+:103400000AE000000000045900000000002F00C97D
+:10341000000000000000000002E000000000046D59
+:1034200000000000004000000000047A00000003DB
+:10343000002F022200000000000000000AE000004F
+:103440000000045E00000000002F00C90000000022
+:10345000000000000CE000000000046D000000000F
+:10346000004000000000047A00000004002F022247
+:1034700000000000000000000AE0000000000463FB
+:1034800000000000002F00C9000000000000000044
+:103490000AE000000000046D000000000040000091
+:1034A0000000047A00000005002F02220000000046
+:1034B000000000000AE000000000046800000000B6
+:1034C000002F00C9000000000000000006E000001E
+:1034D0000000046D00000000004000000000047ABD
+:1034E00000000006002F0222000000000000000083
+:1034F0000AE000000000046D00000000002F00C979
+:10350000000000000000000008E000000000046D62
+:1035100000000000004000000000047A00007F006E
+:1035200000280A210000000000004500002F0222B0
+:1035300000000000000000000AE0000000000000A1
+:103540000000000800210A23000000000000000025
+:1035500014C000000000047700002169002044111D
+:103560000000000000000000C02048000000000033
+:1035700000000000C0204800000000000000000023
+:10358000C020480000000000CAFEBABE004048113A
+:103590000000000000000000C02044000000000007
+:1035A00000000000C020000000000000000000003B
+:1035B000C04048000000000000007F0000280A21F1
+:1035C0000000000000004500002F02220000000063
+:1035D000000000000AE0000000000480000000007D
+:1035E000C02000000000000000000000C02000001B
+:1035F0000000000000000000C040000000000000CB
+:103600000000000000404C080000043C00000000E6
+:10361000C0200800000000000000001040210E2023
+:1036200000000000000000114021122000000000F6
+:103630000000001240211620000000000000216957
+:10364000002044110000000000000000002048029B
+:103650000000000000000000002102250000000022
+:103660000000000014E000000000048A00040000D4
+:10367000C0494A200000048BFFFBFFFFC0284A20FE
+:1036800000000000000000000021022300000000F4
+:103690000000000014E0000000000497000000009B
+:1036A000C02048000000000000000000C0204800CA
+:1036B00000000000000000000021022400000000C3
+:1036C0000000000014C000000000000081000000A5
+:1036D00000204411000000000000000C00204811F0
+:1036E00000000000000000000020001000000000AA
+:1036F0000000000014C0000000000493A0000000BF
+:103700000020441100000000CAFEBABE004048116B
+:1037100000000000810000000020441100000000B3
+:103720000000000400204811000000000000216B90
+:10373000002044110000000000000000C0204810DC
+:103740000000000081000000002044110000000083
+:103750000000000500204811000000000000216C5E
+:10376000002044110000000000000000C0204810AC
+:103770000000000000000000002F022400000000F4
+:10378000000000000CE0000000000000000000004D
+:10379000004000000000049100000000C0210A2049
+:1037A000000000000000000014C00000000004AE93
+:1037B0008100000000204411000000000000000013
+:1037C00000204811000000000000216D002044117D
+:1037D0000000000000000000C020480000000000C1
+:1037E00000000000C02048000000000000000000B1
+:1037F0001AC00000000004A99E000000002044112F
+:1038000000000000CAFEBABE0020481100000000FF
+:10381000000000001AE00000000004AC00000000FE
+:1038200000400000000004B28100000000204411AC
+:10383000000000000000000100204811000000000E
+:1038400000040000C0294620000000000000000025
+:10385000C0600000000006140000000100210222E8
+:10386000000000000000000014C00000000004B9C7
+:103870000000216900204411000000000000000049
+:10388000C02048000000000000000000C0204800E8
+:1038900000000000000000000020481000000000B0
+:1038A000CAFEBABE0040481100000000000000003F
+:1038B000C02044000000000000000000C04048108C
+:1038C0000000000081000000002044110000000002
+:1038D000000000010020481100000000000021F855
+:1038E00000204411000000000000000D00204811DD
+:1038F00000000000000421F90060441100000614DB
+:103900000000000000210230000000000000000064
+:1039100014C00000000004BB0000218000204411FE
+:103920000000000000000000C0204800000000006F
+:1039300000000000C02000000000000000000000A7
+:10394000C02048000000000000000000C02000006F
+:103950000000000000000000C0404800000000001F
+:103960000000000300333E2F0000000000000001B3
+:1039700000210221000000000000000014E000000F
+:10398000000004EB0000003500200A2D00000000BC
+:103990000004000018E00C11000004DA000000012F
+:1039A00000333E2F00000000000021690020441178
+:1039B000000000000000000000204802000000009D
+:1039C0000000000000204803000000000000000884
+:1039D00000300A220000000000000000C020480063
+:1039E0000000000000000000C020480000000000AF
+:1039F00000002169002044110000000000000000C8
+:103A000000204802000000000000000000204803E1
+:103A1000000000000000000800300A220000000042
+:103A200000000000C020480000000000000000006E
+:103A3000D8C04800000004CE0000216900204411D5
+:103A4000000000000000000000204802000000000C
+:103A500000000000002048030000000000000008F3
+:103A600000300A220000000000000000C0204800D2
+:103A70000000000000000000C0204800000000001E
+:103A8000000000360020122D0000000000000000A1
+:103A900000290C830000000000002169002044116F
+:103AA00000000000000000000020480200000000AC
+:103AB0000000000000204803000000000000000893
+:103AC00000300A220000000000000000C020480072
+:103AD0000000000000000000C020480000000000BE
+:103AE000000000110021022400000000000000007E
+:103AF00014C00000000000000000000000400000B2
+:103B00000000049100000035C020362000000000B5
+:103B100000000036C0403620000000000000304A9F
+:103B20000020441100000000E0000000C0484A20CE
+:103B3000000000000000000F002102210000000032
+:103B40000000000014C00000000004F200000000AB
+:103B5000006000000000000B00000000D900000021
+:103B60000000000000000000C04004000000000150
+:103B7000810000000020441100000000000000024D
+:103B80000020481100000000000000FF00280E3057
+:103B90000000000000000000002F022300000000D1
+:103BA000000000000CC00000000004F6000000004F
+:103BB000C0200800000000000000000014C0000049
+:103BC0000000050B0000000000200C1100000000A8
+:103BD0000000002400203623000000000000003414
+:103BE00000203623000000000000003200203623B1
+:103BF000000000000000003100203623000000001B
+:103C00000000001D00203623000000000000002DF1
+:103C100000203623000000000000002E0020362384
+:103C2000000000000000001B002036230000000000
+:103C30000000001C0020362300000000FFFFE00011
+:103C400000200C1100000000000000290020362395
+:103C5000000000000000002A0020362300000000C1
+:103C600000001FFF00200C11000000000000002BCE
+:103C700000203623000000000000002C0020362326
+:103C800000000000F1FFFFFF00283A2E00000000B6
+:103C90000000001AC0220E200000000000000000FA
+:103CA0000029386E0000000081000000002044114F
+:103CB0000000000000000006002048110000000085
+:103CC0000000003340203620000000008700000084
+:103CD000002044110000000000000000C020480047
+:103CE000000000000000A1F40020441100000000CA
+:103CF0000000000000204810000000009D000000AF
+:103D000000204411000000000000001F40214A2054
+:103D10000000000096000000002044110000000098
+:103D200000000000C020480000000000000000006B
+:103D3000C0200C000000000000000000C0201000A7
+:103D4000000000000000001F0021162400000000F9
+:103D50000000000014C0000000000000000000256A
+:103D600000203623000000000000000300281E236E
+:103D700000000000000000080022222300000000D4
+:103D8000FFFFF000002822280000000000000000D3
+:103D9000002920E80000000000000027002036284D
+:103DA000000000000000001800211E230000000099
+:103DB000000000280020362700000000000000025C
+:103DC000002216240000000000000000003014A8AB
+:103DD0000000000000000026002036250000000042
+:103DE0000000000300211A24000000001000000061
+:103DF00000281A2600000000EFFFFFFF00283A2EDF
+:103E00000000000000000000004938CE000006025B
+:103E10000000000140280A20000000000000000609
+:103E200040280E200000000000000300C0281220DF
+:103E30000000000000000008002112240000000023
+:103E400000000000C020162000000000000000005C
+:103E5000C0201A2000000000000000000021022203
+:103E6000000000000000000014C000000000054138
+:103E7000810000000020441100000000000000014B
+:103E800000204811000000000000225800300A24E1
+:103E90000000000000040000006946220000061433
+:103EA0000000216900204411000000000000000013
+:103EB00000204805000000000002000000294A26FA
+:103EC000000000000000000000204810000000007A
+:103ED000CAFEBABE00204811000000000000000227
+:103EE000002F022300000000000000000CC00000B2
+:103EF0000000054900000000C0201C100000000068
+:103F000000000000C04000000000055B000000024F
+:103F1000002F022300000000000000000CC0000081
+:103F2000000005498100000000204411000000004D
+:103F3000000000010020481100000000000022588D
+:103F400000300A240000000000040000006946223E
+:103F50000000061400000000C0201C10000000003B
+:103F600000000000C04000000000055B00000000F1
+:103F7000002F022300000000000000000CC0000021
+:103F80000000054D00000000C0201C0000000000E3
+:103F900000000000C04000000000055B00000004BD
+:103FA000002F022300000000000000000CC00000F1
+:103FB00000000559810000000020441100000000AD
+:103FC0000000000000204811000000000000216DEA
+:103FD000002044110000000000000000C020480044
+:103FE0000000000000000000C020480000000000A9
+:103FF000000000001AC00000000005549E000000F0
+:104000000020441100000000CAFEBABE0020481182
+:1040100000000000000000001AE00000000005574A
+:104020000000000000401C100000055B00000000C4
+:10403000C02000000000000000000000C0400000A0
+:1040400000000000000000000EE000000000055D20
+:104050000000000000600000000005A40000000057
+:10406000002F022400000000000000000CC000002F
+:104070000000056D0000A2B7002044110000000000
+:104080000000000000204807000000008100000040
+:104090000020441100000000000000010020481131
+:1040A000000000000004A2B60060441100000614E5
+:1040B0000000001A0021223000000000000000066D
+:1040C00000222630000000000000A2C4002044119D
+:1040D0000000000000000000003048E9000000007F
+:1040E0000000000000E000000000056B0000A2D10D
+:1040F00000204411000000000000000000404808BB
+:10410000000000000000A2D10020441100000000C7
+:104110000000000100504A280000000000000001DB
+:10412000002F022400000000000000000CC000006E
+:104130000000057D0000A2BB00204411000000002B
+:10414000000000000020480700000000810000007F
+:104150000020441100000000000000010020481170
+:10416000000000000004A2BA006044110000061420
+:104170000000001A002122300000000000000006AC
+:1041800000222630000000000000A2C500204411DB
+:104190000000000000000000003048E900000000BE
+:1041A0000000000000E000000000057B0000A2D23B
+:1041B00000204411000000000000000000404808FA
+:1041C000000000000000A2D2002044110000000006
+:1041D0000000000100504A2800000000000000021A
+:1041E000002F022400000000000000000CC00000AE
+:1041F0000000058D0000A2BF002044110000000057
+:1042000000000000002048070000000081000000BE
+:1042100000204411000000000000000100204811AF
+:10422000000000000004A2BE00604411000006145B
+:104230000000001A002122300000000000000006EB
+:1042400000222630000000000000A2C60020441119
+:104250000000000000000000003048E900000000FD
+:104260000000000000E000000000058B0000A2D369
+:104270000020441100000000000000000040480839
+:10428000000000000000A2D3002044110000000044
+:104290000000000100504A28000000000000A2C3F6
+:1042A000002044110000000000000000002048072A
+:1042B0000000000081000000002044110000000008
+:1042C0000000000100204811000000000004A2C20C
+:1042D00000604411000006140000001A0021223082
+:1042E0000000000000000006002226300000000050
+:1042F0000000A2C7002044110000000000000000E0
+:10430000003048E9000000000000000000E000006C
+:10431000000005990000A2D4002044110000000014
+:104320000000000000404808000000000000A2D487
+:1043300000204411000000000000000100504A2845
+:104340000000000085000000002044110000000073
+:104350000000000000204801000000000000304A7A
+:10436000002044110000000001000000002048115E
+:104370000000000000000000004000000000059F59
+:10438000A4000000C0204411000000000000000054
+:10439000C04048000000000000000000C0600000B5
+:1043A000000005A400000000C0400400000000015F
+:1043B0000001A2A400204411000000000000000041
+:1043C00000204811000000000000000000204811FB
+:1043D0000000000000000000002048110000000064
+:1043E000000000000020481100000000000000054F
+:1043F00000204811000000000000A1F4002044113A
+:104400000000000000000000002048110000000033
+:10441000880000000020441100000000000000019E
+:104420000020481100000000FF000000002044119F
+:104430000000000000000000002048110000000003
+:1044400000000001002048110000000000000002F0
+:104450000080481100000000000000000EE0000095
+:10446000000005B700001000002008110000000047
+:104470000000003400203622000000000000000090
+:1044800000600000000005BB0000000000600000AC
+:10449000000005A498000000002044110000000066
+:1044A0000000000000804811000000000000000033
+:1044B000C0600000000005BB00000000C040040018
+:1044C000000000010000A2A4002044110000000030
+:1044D00000000022002048110000000089000000B8
+:1044E00000204411000000000000000100204811DD
+:1044F00000000000FF000000002044110000000048
+:104500000000000000204811000000000000000131
+:104510000020481100000000000000020080481147
+:10452000000000000000217AC020441100000000BB
+:10453000000000000040481100000000970000004B
+:10454000002044110000000000000000002048117D
+:10455000000000008A00000000204411000000005C
+:10456000000000000020481100000000FF000000D3
+:10457000002044110000000000000000002048114D
+:1045800000000000000000010020481100000000B1
+:104590000000000200804811000000000000000040
+:1045A00000600000000005E1000020100020441120
+:1045B0000000000000008000002048110000000002
+:1045C0000001A2A4C020441100000000000000006F
+:1045D0000020481100000000000000160060481193
+:1045E0000000035E000000160020481100000000DB
+:1045F0000000201000204411000000000001000015
+:10460000002048110000000081000000002044113B
+:104610000000000000000001002048110000000020
+:104620000000217C002044110000000009800000EF
+:104630000020481100000000FFFFFFFF002048118C
+:1046400000000000000000000020481100000000F1
+:104650000000000017000000000000000004217F9F
+:1046600000604411000006140000001F0021023009
+:10467000000000000000000014C000000000000066
+:104680000000000400404C11000005DC0000001D8B
+:1046900000201E2D000000000000000400291E273D
+:1046A000000000000000001D008036270000000010
+:1046B0000000001D00201E2D00000000FFFFFFFB7A
+:1046C00000281E27000000000000001D0080362783
+:1046D000000000000000001D00201E2D0000000052
+:1046E0000000000800291E27000000000000001D37
+:1046F00000803627000000000000001D00201E2D55
+:1047000000000000FFFFFFF700281E270000000048
+:104710000000001D0080362700000000000020106F
+:10472000002044110000000000008000002048111B
+:10473000000000000001A2A40020441100000000BD
+:1047400000000000002048110000000000000016DA
+:10475000006048110000035E0000001600204811B0
+:1047600000000000000020100020441100000000A4
+:104770000001000000204811000000000000217C22
+:1047800000204411000000000180000000204811BA
+:104790000000000000FFFFFF0020481100000000A3
+:1047A0000000000000204811000000000000000090
+:1047B00017000000000000008100000000204411EC
+:1047C000000000000000000100204811000000006F
+:1047D0000004217F00604411000006140000000066
+:1047E00000200010000000000000000014C00000C5
+:1047F000000006130000001000404C11000005F9F5
+:1048000000000000C02004000000000000000000C4
+:1048100038C00000000000000000002500200A2D24
+:10482000000000000000002600200E2D0000000007
+:10483000000000270020122D0000000000000028CA
+:104840000020162D00000000000021690020441106
+:1048500000000000000000000020480400000000EC
+:1048600000000000002048050000000000000000DB
+:104870000020480100000000CAFEBABE0020481116
+:1048800000000000000000040030122400000000BE
+:1048900000000000002F0064000000000000000085
+:1048A0000CC00000000006120000000300281A22BD
+:1048B000000000000000000800221222000000009A
+:1048C000FFFFF0000028122400000000000000009C
+:1048D000002910C40000000000000027004036241A
+:1048E0000000000000000000008000000000000048
+:1048F000000000001AC00000000006149F00000025
+:104900000020441100000000CAFEBABE0020481179
+:1049100000000000000000001AE000000000061780
+:104920000000000000800000000000000000000007
+:10493000006000000000000B000010000060041187
+:10494000000002FE00000000002004110000000032
+:1049500000000000006008110000019F0000225CC0
+:104960000020441100000000000000030020481156
+:10497000000000000000225600204411000000004A
+:104980000000001B00204811000000000000A1FCF6
+:104990000020441100000000000000010020481128
+:1049A000000000000001A1FDC02044110000000033
+:1049B0000000002900201E2D000000000000001053
+:1049C00000221E27000000000000002C0020222DE5
+:1049D000000000000000FFFF002822280000000067
+:1049E000000000000029490700000000000000004E
+:1049F00000204811000000000000002A0020222DA5
+:104A0000000000000000FFFF002822280000000036
+:104A1000000000000029490700000000000000001D
+:104A200000204811000000000000002B00201E2D77
+:104A3000000000000000001000221E2700000000FF
+:104A400000000000002949070000000000000000ED
+:104A500000404811000000000000000000000000BD
+:104A60000000000000000000000000000000000046
+:104A70000000000000000000000000000000000036
+:104A80000000000000000000000000000000000026
+:104A90000000000000000000000000000000000016
+:104AA0000000000000000000000000000000000006
+:104AB00000000000000000000000000000000000F6
+:104AC00000000000000000000000000000000000E6
+:104AD00000000000000000000000000000000000D6
+:104AE00000000000000000000000000000000000C6
+:104AF00000000000000000000000000000000000B6
+:104B000000000000000000000000000000000000A5
+:104B10000000000000000000000000000000000095
+:104B20000000000000000000000000000000000085
+:104B30000000000000000000000000000000000075
+:104B40000000000000000000000000000000000065
+:104B50000000000000000000000000000000000055
+:104B60000000000000000000000000000000000045
+:104B70000000000000000000000000000000000035
+:104B80000000000000000000000000000000000025
+:104B90000000000000000000000000000000000015
+:104BA0000000000000000000000000000000000005
+:104BB00000000000000000000000000000000000F5
+:104BC00000000000000000000000000000000000E5
+:104BD00000000000000000000000000000000000D5
+:104BE00000000000000000000000000000000000C5
+:104BF00000000000000000000000000000000000B5
+:104C000000000000000000000000000000000000A4
+:104C10000000000000000000000000000000000094
+:104C20000000000000000000000000000000000084
+:104C30000000000000000000000000000000000074
+:104C40000000000000000000000000000000000064
+:104C50000000000000000000000000000000000054
+:104C60000000000000000000000000000000000044
+:104C70000000000000000000000000000000000034
+:104C80000000000000000000000000000000000024
+:104C90000000000000000000000000000000000014
+:104CA0000000000000000000000000000000000004
+:104CB00000000000000000000000000000000000F4
+:104CC00000000000000000000000000000000000E4
+:104CD00000000000000000000000000000000000D4
+:104CE00000000000000000000000000000000000C4
+:104CF00000000000000000000000000000000000B4
+:104D000000000000000000000000000000000000A3
+:104D10000000000000000000000000000000000093
+:104D20000000000000000000000000000000000083
+:104D30000000000000000000000000000000000073
+:104D40000000000000000000000000000000000063
+:104D50000000000000000000000000000000000053
+:104D60000000000000000000000000000000000043
+:104D70000000000000000000000000000000000033
+:104D80000000000000000000000000000000000023
+:104D90000000000000000000000000000000000013
+:104DA0000000000000000000000000000000000003
+:104DB00000000000000000000000000000000000F3
+:104DC00000000000000000000000000000000000E3
+:104DD00000000000000000000000000000000000D3
+:104DE00000000000000000000000000000000000C3
+:104DF00000000000000000000000000000000000B3
+:104E000000000000000000000000000000000000A2
+:104E10000000000000000000000000000000000092
+:104E20000000000000000000000000000000000082
+:104E30000000000000000000000000000000000072
+:104E40000000000000000000000000000000000062
+:104E50000000000000000000000000000000000052
+:104E60000000000000000000000000000000000042
+:104E70000000000000000000000000000000000032
+:104E80000000000000000000000000000000000022
+:104E90000000000000000000000000000000000012
+:104EA0000000000000000000000000000000000002
+:104EB00000000000000000000000000000000000F2
+:104EC00000000000000000000000000000000000E2
+:104ED00000000000000000000000000000000000D2
+:104EE00000000000000000000000000000000000C2
+:104EF00000000000000000000000000000000000B2
+:104F000000000000000000000000000000000000A1
+:104F10000000000000000000000000000000000091
+:104F20000000000000000000000000000000000081
+:104F30000000000000000000000000000000000071
+:104F40000000000000000000000000000000000061
+:104F50000000000000000000000000000000000051
+:104F60000000000000000000000000000000000041
+:104F70000000000000000000000000000000000031
+:104F80000000000000000000000000000000000021
+:104F90000000000000000000000000000000000011
+:104FA0000000000000000000000000000000000001
+:104FB00000000000000000000000000000000000F1
+:104FC00000000000000000000000000000000000E1
+:104FD00000000000000000000000000000000000D1
+:104FE00000000000000000000000000000000000C1
+:104FF00000000000000000000000000000000000B1
+:1050000000000000000000000000000000000000A0
+:105010000000000000000000000000000000000090
+:105020000000000000000000000000000000000080
+:105030000000000000000000000000000000000070
+:105040000000000000000000000000000000000060
+:105050000000000000000000000000000000000050
+:105060000000000000000000000000000000000040
+:105070000000000000000000000000000000000030
+:105080000000000000000000000000000000000020
+:105090000000000000000000000000000000000010
+:1050A0000000000000000000000000000000000000
+:1050B00000000000000000000000000000000000F0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:10517000000000000000000000000000000000002F
+:10518000000000000000000000000000000000001F
+:10519000000000000000000000000000000000000F
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000000000000000000DF
+:1051D00000000000000000000000000000000000CF
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:10522000000000000000000000000000000000007E
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000000000005E
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000000000000000000002E
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000000000000000000000000000FE
+:1052B000013304EF059B02390000000001B00159E1
+:1052C0000425059B00000000021201F6023901428C
+:1052D000000000000210022E0289022A00000000D5
+:1052E00003C2059B059B059B0000000005CD05CE74
+:1052F0000308059B00000000059B05A00309032986
+:10530000000000000313026B032B031D00000000CC
+:10531000059B059B059B059B00000000059B052C3C
+:10532000059B059B0000000003A5059B04A2032D1F
+:1053300000000000048104330423059B00000000EA
+:1053400004BB04ED042704C800000000043304F487
+:10535000033A036500000000059B059B059B059B28
+:1053600000000000059B059B059B059B00000000BD
+:10537000059B059B05B905A200000000059B059B48
+:105380000007059B00000000059B059B059B059BF6
+:1053900000000000059B059B059B059B000000008D
+:1053A00003E303D803F303F10000000003F903F55E
+:1053B00003F703FB0000000004070403040F040BC1
+:1053C0000000000004170413041F041B0000000069
+:1053D000059B059B059B059B00000000059B059B0D
+:1053E000059B059B00000000059B059B059B059BFD
+:1053F0000000000000020600061900060000000080
+:00000001FF
diff --git a/firmware/radeon/R600_pfp.bin.ihex b/firmware/radeon/R600_pfp.bin.ihex
new file mode 100644
index 0000000..5236108
--- /dev/null
+++ b/firmware/radeon/R600_pfp.bin.ihex
@@ -0,0 +1,145 @@
+:1000000000D4007100D4007200CA040000A00000F7
+:10001000007E828B0080000300CA040000D4401ED2
+:1000200000EE001E00CA040000A00000007E828BCB
+:1000300000C4183800CA240000CA2800009581A80E
+:1000400000C41C3A00C3C00000CA080000CA0C006B
+:10005000007C744B00C200050099C00000C41C3A2B
+:10006000007C744C00C0FFF000042C0400309002AF
+:10007000007D250000351402007D350B002554035A
+:10008000007CD58000259C030095C00400D5001B92
+:10009000007EDDC1007D9D8000D6801B00D5801BC9
+:1000A00000D4401E00D5401E00D6401E00D6801E43
+:1000B00000D4801E00D4C01E009783D400D5C01E7B
+:1000C00000CA08000080001B00CA0C0000E4011EEA
+:1000D00000D4001E0080000D00C4183800E4013E6A
+:1000E00000D4001E0080000D00C4183800D4401E4B
+:1000F00000EE001E00CA040000A00000007E828BFB
+:1001000000E4011E00D4001E00D4401E00EE001EBC
+:1001100000CA040000A00000007E828B00E4013EC3
+:1001200000D4001E00D4401E00EE001E00CA0400D1
+:1001300000A00000007E828B00CA180000D4401E80
+:1001400000D5801E0080005400D4007300D4401EEF
+:1001500000CA080000CA0C0000CA100000D48019B0
+:1001600000D4C01800D5001700D4801E00D4C01ED3
+:1001700000D5001E00E2001E00CA040000A000001E
+:10018000007E828B00CA080000D4806000D4401E2C
+:100190000080000200D4801E00CA080000D48061E4
+:1001A00000D4401E0080000200D4801E00CA080057
+:1001B00000CA0C0000D4401E00D4801600D4C01623
+:1001C00000D4801E008001B900D4C01E00C6083EC5
+:1001D00000CA0C0000CA10000094800400CA140079
+:1001E00000E420F300D4201300D5606500D4E01CA7
+:1001F00000D5201C00D5601C0080000200062001F4
+:1002000000C6083E00CA0C0000CA1000009483F724
+:1002100000CA140000E420F30080007A00D4201308
+:1002200000C6083E00CA0C0000CA1000009883EF08
+:1002300000CA140000D400640080008E000000009A
+:1002400000C4143200C6183E00C4082F00954005B3
+:1002500000C40C3000D4401E0080000200EE001EDE
+:10026000009583F500C4103100D4403300D52065DB
+:1002700000D4A01C00D4E01C00D5201C00D40073C6
+:1002800000E4015E00D4001E008001B900062001D8
+:10029000000A200100D6007400C4083600C61040D1
+:1002A0000098800700CC38350095010F00D4001F5E
+:1002B00000D460620080000200D4206200CC1433BD
+:1002C000008401BC00D4007000D5401E00800002F4
+:1002D00000EE001E00CA0C0000CA100000D4C01AB4
+:1002E000008401BC00D5001A00CC04430035101F67
+:1002F000002C9401007D098B00984005007D15CBF2
+:1003000000D4001A008001B900D4006D003444010B
+:1003100000CC0C440098403A00CC2C460095800458
+:1003200000CC0445008001B900D4001A00D4C01AE2
+:1003300000282801008400F300CC10030098801BE3
+:100340000004380C008400F300CC100300988017E0
+:1003500000043808008400F300CC100300988013D8
+:1003600000043804008400F300CC100300988014CB
+:1003700000CC1047009A800900CC1448009840DA5D
+:1003800000D4006D00CC184400D5001A00D5401AE6
+:10039000008000CC00D5801A0096C0D300D4006D38
+:1003A000008001B900D4006E009AC00300D4006D33
+:1003B00000D4006E0080000200EC007F009AC0CAEA
+:1003C00000D4006D008001B900D4006E00CC14038D
+:1003D00000CC180300CC1C03007D9103007DD58365
+:1003E000007D190C0035CC1F0035701F007CF0CB50
+:1003F000007CD08B00880000007E8E8B0095C004AE
+:1004000000D4006E008001B900D4001A00D4C01AD4
+:1004100000CC080300CC0C0300CC100300CC140368
+:1004200000CC180300CC1C0300CC240300CC280310
+:100430000035C41F0036B01F007C704B0034F01F25
+:10044000007C704B0035701F007C704B007D8881F4
+:10045000007DCCC1007E5101007E9541007C9082E0
+:10046000007CD4C2007C848B009AC003007C8C8BFF
+:10047000002C88010098809C00D4006D0098409A60
+:1004800000D4006E00CC084700CC0C4800CC1044CF
+:1004900000D4801A00D4C01A0080010400D5001ACC
+:1004A00000CC083200D40032009482D800CA0C007C
+:1004B00000D4401E0080000200D4001E00E4011E93
+:1004C00000D4001E00CA080000CA0C0000CA1000B8
+:1004D00000D4401E00CA140000D4801E00D4C01EE8
+:1004E00000D5001E00D5401E00D54034008000021B
+:1004F00000EE001E0028040400E2001A00E2001AC8
+:1005000000D4401A00CA380000CC080300CC0C0309
+:1005100000CC0C0300CC0C03009882BC000000004F
+:10052000008401BC00D7806F0080000200EE001F35
+:1005300000CA040000C2FF0000CC083400C13FFF25
+:10054000007C74CB007CC90B007D010F009902AFC9
+:10055000007C738B008401BC00D7806F0080000298
+:1005600000EE001F00CA080000281900007D898BDA
+:10057000009580140028140400CA0C0000CA100062
+:1005800000CA1C0000CA240000E2001F00D4C01AE8
+:1005900000D5001A00D5401A00CC180300CC2C035B
+:1005A00000CC2C0300CC2C03007DA58B007D9C4748
+:1005B00000984296000000000080016400D4C01A38
+:1005C00000D4401E00D4801E0080000200EE001EF9
+:1005D00000E4011E00D4001E00D4401E00EE001EE8
+:1005E00000CA040000A00000007E828B00E4013EEF
+:1005F00000D4001E00D4401E00EE001E00CA0400FD
+:1006000000A00000007E828B00CA080000248C0637
+:10061000000CCC060098C00600CC104900990004DC
+:1006200000D4007100E4011E00D4001E00D4401E5E
+:1006300000D4801E0080000200EE001E00CA0800E8
+:1006400000CA0C000034D018002510010095001FCE
+:1006500000C17FFF00CA100000CA140000CA1800C1
+:1006600000D4801D00D4C01D007DB18B00C14202AA
+:1006700000C2C00100D5801D0034DC0E007D5D4C41
+:10068000007F734C00D7401E00D5001E00D5401ED1
+:1006900000C1420000C2C00000099C010031DC1012
+:1006A000007F5F4C007F734C007D838000D5806F9E
+:1006B00000D5806600D7401E00EC005E00C8240212
+:1006C000008001B900D6007400D4401E00D4801E02
+:1006D00000D4C01E0080000200EE001E0080000258
+:1006E00000EE001F00D4001F0080000200D4001F95
+:1006F00000D4001F0088000000D4001F000000008C
+:1007000000000000000000000000000000000000E9
+:1007100000000000000000000000000000000000D9
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:10080000000101740002017B0003009000040080DD
+:100810000005000500060040000700330008012F16
+:1008200000090047000A0037001001B7001700A4B4
+:100830000022013D0023014C002000B500240128C6
+:100840000027004E0028006B002A0061002B005397
+:10085000002F00660032008800340182003C0159FC
+:10086000003F00730041018F0044013100550176C3
+:100870000056017D0060000C006100350062003907
+:1008800000630039006400390065003900660039F2
+:10089000006700390068003B00690042006A0049B7
+:1008A000006B0049006C0049006D0049006E004972
+:1008B000006F0049007301B7000000070000000747
+:1008C000000000070000000700000007000000070C
+:1008D00000000007000000070000000700000007FC
+:1008E00000000007000000070000000700000007EC
+:1008F00000000007000000070000000700000007DC
+:00000001FF
diff --git a/firmware/radeon/RS600_cp.bin.ihex b/firmware/radeon/RS600_cp.bin.ihex
new file mode 100644
index 0000000..4a89501
--- /dev/null
+++ b/firmware/radeon/RS600_cp.bin.ihex
@@ -0,0 +1,130 @@
+:10000000000000004200E000000000004000E000AE
+:1000100000000008000000A000000008000000A48C
+:10002000000000004A554B4A000000004A4A44675D
+:100030000000000055526F75000000004A7E7D658B
+:10004000000000004AE74AF6000000004AD34A4A8E
+:1000500000000000D689898900000000CD4ADDCF6C
+:10006000000000008EBE4AE200000000C38A8A8AB7
+:10007000000000004A0F8CC800000004000CA00023
+:1000800000000038000D0012000000040000E8B479
+:1000900000000038000D0014000000040000E8B665
+:1000A00000000038000D0016000000040000E854B5
+:1000B00000000038000D0018000000040000E855A2
+:1000C00000000038000D001A000000040000E8568F
+:1000D00000000038000D001C000000040000E8577C
+:1000E00000000038000D001E000000040000E8249D
+:1000F00000000038000D0020000000040000E8258A
+:1001000000000038000D0022000000040000E8306C
+:1001100000000038000D0024000000040000F0C0C2
+:1001200000000038000D0026000000040000F0C1AF
+:1001300000000038000D0028000000040000F0411D
+:1001400000000038000D002A000000040000F184C7
+:1001500000000038000D002C000000040000F185B4
+:1001600000000038000D002E000000040000F186A1
+:1001700000000038000D0030000000040000F1878E
+:1001800000000038000D0032000000040000F18083
+:1001900000000038000D0034000000040000F3935C
+:1001A00000000038000D0036000000040000F38A53
+:1001B00000000038000D0038000000040000F38E3D
+:1001C000000000040000E821000000040140A0003D
+:1001D00000000018000000430000000400CCE8000C
+:1001E00000000004001B000100000004080048009B
+:1001F00000000004001B000100000004080048008B
+:1002000000000004001B000100000004080048007A
+:10021000000000080000003A000000000000A000FC
+:10022000000000042000451D000000040000E580DF
+:1002300000000004000CE581000000040800458077
+:1002400000000004000CE5810000000800000047E9
+:10025000000000000000A00000000004000C2000CE
+:10026000000000040000E50E000000040003200070
+:10027000000000280002205100000024000000516E
+:10028000000000040800450F000000080000A04B1B
+:10029000000000040000E565000000040000E566C1
+:1002A00000000008000000520000000403CCA5B4C8
+:1002B00000000004054320000000000400022000AC
+:1002C000000000304CCCE05E0000000408274565CB
+:1002D000000000300000005E0000000408004564DB
+:1002E000000000040000E566000000080000005562
+:1002F00000000010008020610000000400202000A9
+:1003000000000004001B00FF00000010010000645A
+:1003100000000004001F200000000004001C00FF7B
+:100320000000000C0000000000000030000000721F
+:100330000000000800000055000000040000E57601
+:10034000000000040000E577000000040000E50E56
+:10035000000000040000E50F000000040140A000C0
+:100360000000001800000069000000C200C0E5F9AC
+:100370000000000800000069000000040014E50E01
+:10038000000000040040E50F0000000800C0006C01
+:10039000000000040000E570000000040000E571AA
+:1003A0000000000C0000E572000000040000A00046
+:1003B000000000040140A000000000040000E56807
+:1003C00000000004000C200000000018000000766F
+:1003D00000000004000B00000000000418C0E562EB
+:1003E00000000008000000780000000800C000774E
+:1003F00000000004000700D5000000380000008461
+:1004000000000030000CA08600000004080045BB7E
+:1004100000000030000C2087000000000800E5BC50
+:10042000000000040000E5BB000000000000E5BC87
+:100430000000000C00120000000000040012000088
+:100440000000000C001B0002000000040000A000DF
+:10045000000000040000E821000000000000E800A7
+:10046000000000040000E821000000000000E82E69
+:100470000000000402CCA0000000000400140000F2
+:1004800000000004000CE1CC00000004050DE1CDEB
+:10049000000000040040000000000018000000966A
+:1004A0000000000400C0A00000000008000000934D
+:1004B0000000002000000098000000004200E00062
+:1004C000000000380000009F00000004000CA000A5
+:1004D000000000040014000000000004000C2000D4
+:1004E000000000040016000000000004700CE00092
+:1004F000000000080014009B000000004000E00025
+:10050000000000040240000000000004400EE00073
+:100510000000000402400000000000004000E00075
+:1005200000000004000C2000000000040240E51B55
+:10053000000000050080E50A000000050080E50BD2
+:10054000000000040022000000000004000700D5A5
+:1005500000000038000000B200000030000C2087CE
+:10056000000000050880E5BD00000030000C20867A
+:10057000000000050800E5BB00000030000C2087EB
+:10058000000000050880E5BC00000008000000B580
+:10059000000000050080E5BD000000050000E5BB8F
+:1005A000000000050080E5BC000000040021000000
+:1005B00000000004028000000000001800C000B924
+:1005C000000000404180E00000000024000000BB6B
+:1005D0000000000C010000000000000C0100E51DFF
+:1005E00000000004000045BB00000008000080B5CA
+:1005F000000000040000F3CE000000040140A00051
+:100600000000000400CC20000000004008C053CFD0
+:100610000000000000008000000000040000F3D291
+:10062000000000040140A0000000000400CC2000F5
+:100630000000004008C053D300000000000080000C
+:10064000000000040000F39D000000040140A00031
+:100650000000000400CC20000000004008C0539EB1
+:1006600000000000000080000000000403C008300B
+:10067000000000004200E000000000040000A000B4
+:1006800000000004200045E0000000000000E5E15B
+:10069000000000000000000100000004000700D27C
+:1006A000000000000800E3940000000000000000CB
+:1006B000000000040000E8C4000000040000E8C5D9
+:1006C000000000040000E8C6000000040000E92863
+:1006D000000000040000E929000000040000E92AED
+:1006E00000000008000000D6000000040000E92817
+:1006F000000000040000E929000000040000E92ACD
+:1007000000000008000000DD0000000000E001160D
+:1007100000000004000700E1000000040800401C85
+:1007200000000004200050E7000000040000E01D6D
+:1007300000000008000000E40000000402C02000E7
+:10074000000000040006000000000034000000EB80
+:1007500000000008000000E8000000040000800025
+:1007600000000000C000E0000000000000000000E9
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B00000000004000C200000000004001D0018D0
+:1007C00000000004001A000100000034000000FBDB
+:1007D000000000080000004A000000080500A04AD0
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:00000001FF
+/* production radeon ucode r1xx-r6xx */
diff --git a/firmware/radeon/RS690_cp.bin.ihex b/firmware/radeon/RS690_cp.bin.ihex
new file mode 100644
index 0000000..6896274
--- /dev/null
+++ b/firmware/radeon/RS690_cp.bin.ihex
@@ -0,0 +1,130 @@
+:1000000000000008000000DD00000008000000DF24
+:1000100000000008000000A000000008000000A48C
+:10002000000000004A554B4A000000004A4A44675D
+:100030000000000055526F75000000004A7E7D658B
+:10004000000000004AD74AF6000000004AC94A4AA8
+:1000500000000000CC89898900000000C34AD3C594
+:10006000000000008E4A4A4A000000004A8A8A8A3C
+:10007000000000004A0F8C4A00000004000CA000A1
+:1000800000000038000D0012000000040000E8B479
+:1000900000000038000D0014000000040000E8B665
+:1000A00000000038000D0016000000040000E854B5
+:1000B00000000038000D0018000000040000E855A2
+:1000C00000000038000D001A000000040000E8568F
+:1000D00000000038000D001C000000040000E8577C
+:1000E00000000038000D001E000000040000E8249D
+:1000F00000000038000D0020000000040000E8258A
+:1001000000000038000D0022000000040000E8306C
+:1001100000000038000D0024000000040000F0C0C2
+:1001200000000038000D0026000000040000F0C1AF
+:1001300000000038000D0028000000040000F0411D
+:1001400000000038000D002A000000040000F184C7
+:1001500000000038000D002C000000040000F185B4
+:1001600000000038000D002E000000040000F186A1
+:1001700000000038000D0030000000040000F1878E
+:1001800000000038000D0032000000040000F18083
+:1001900000000038000D0034000000040000F3935C
+:1001A00000000038000D0036000000040000F38A53
+:1001B00000000038000D0038000000040000F38E3D
+:1001C000000000040000E821000000040140A0003D
+:1001D00000000018000000430000000400CCE8000C
+:1001E00000000004001B000100000004080048009B
+:1001F00000000004001B000100000004080048008B
+:1002000000000004001B000100000004080048007A
+:10021000000000080000003A000000000000A000FC
+:10022000000000042000451D000000040000E580DF
+:1002300000000004000CE581000000040800458077
+:1002400000000004000CE5810000000800000047E9
+:10025000000000000000A00000000004000C2000CE
+:10026000000000040000E50E000000040003200070
+:10027000000000280002205100000024000000516E
+:10028000000000040800450F000000080000A04B1B
+:10029000000000040000E565000000040000E566C1
+:1002A00000000008000000520000000403CCA5B4C8
+:1002B00000000004054320000000000400022000AC
+:1002C000000000304CCCE05E0000000408274565CB
+:1002D000000000300000005E0000000408004564DB
+:1002E000000000040000E566000000080000005562
+:1002F00000000010008020610000000400202000A9
+:1003000000000004001B00FF00000010010000645A
+:1003100000000004001F200000000004001C00FF7B
+:100320000000000C0000000000000030000000721F
+:100330000000000800000055000000040000E57601
+:10034000000000040000E577000000040000E50E56
+:10035000000000040000E50F000000040140A000C0
+:100360000000001800000069000000C200C0E5F9AC
+:100370000000000800000069000000040014E50E01
+:10038000000000040040E50F0000000800C0006C01
+:10039000000000040000E570000000040000E571AA
+:1003A0000000000C0000E572000000040000A00046
+:1003B000000000040140A000000000040000E56807
+:1003C00000000004000C200000000018000000766F
+:1003D00000000004000B00000000000418C0E562EB
+:1003E00000000008000000780000000800C000774E
+:1003F00000000004000700CB00000038000000846B
+:1004000000000030000CA08600000004080045BB7E
+:1004100000000030000C2087000000000800E5BC50
+:10042000000000040000E5BB000000000000E5BC87
+:100430000000000C00120000000000040012000088
+:100440000000000C001B0002000000040000A000DF
+:10045000000000040000E821000000000000E800A7
+:10046000000000040000E821000000000000E82E69
+:100470000000000402CCA0000000000400140000F2
+:1004800000000004000CE1CC00000004050DE1CDEB
+:10049000000000040040000000000018000000966A
+:1004A0000000000400C0A00000000008000000934D
+:1004B0000000002000000098000000004200E00062
+:1004C000000000380000009F00000004000CA000A5
+:1004D000000000040014000000000004000C2000D4
+:1004E000000000040016000000000004700CE00092
+:1004F000000000080014009B000000004000E00025
+:10050000000000040240000000000004400EE00073
+:100510000000000402400000000000004000E00075
+:100520000000002C0010000000000000000040004F
+:1005300000000004080045C8000000040024000575
+:100540000000000408004D0B00000004000C200017
+:10055000000000040240E51B000000050080E50AE1
+:10056000000000050080E50B0000000400220000F0
+:1005700000000004000700CB00000038000000B7B6
+:1005800000000030000C2087000000050880E5BD59
+:1005900000000030000C2086000000050800E5BBCC
+:1005A00000000030000C2087000000050880E5BC3A
+:1005B00000000008000000BA000000050080E5BD52
+:1005C000000000050000E5BB000000050080E5BC60
+:1005D0000000000400210000000000040280000070
+:1005E0000000001800C000BE000000404180E00094
+:1005F00000000024000000C00000000C010000000A
+:100600000000000C0100E51D00000004000045BBD7
+:1006100000000008000080BA0000000403C0083099
+:10062000000000004200E000000000040000A00004
+:1006300000000004200045E0000000000000E5E1AB
+:10064000000000000000000100000004000700C8D6
+:10065000000000000800E39400000000000000001B
+:10066000000000040000E8C4000000040000E8C529
+:10067000000000040000E8C6000000040000E928B3
+:10068000000000040000E929000000040000E92A3D
+:1006900000000008000000CC000000040000E92871
+:1006A000000000040000E929000000040000E92A1D
+:1006B00000000008000000D30000000402C0200079
+:1006C000000000040006000000000034000000DB11
+:1006D00000000008000000D80000000400008000B6
+:1006E00000000000C000E00000000030000000E159
+:1006F000000000004200E00000000030000000E1C7
+:10070000000000004000E000000000040025001B85
+:100710000000000400230000000000040025000584
+:1007200000000034000000E60000000C00000000A3
+:10073000000000040024400000000004080045C838
+:1007400000000004002400050000000C08004D0B10
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B00000000004000C200000000004001D0018D0
+:1007C00000000004001A000100000034000000FBDB
+:1007D000000000080000004A000000080500A04AD0
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:00000001FF
+/* production radeon ucode r1xx-r6xx */
diff --git a/firmware/radeon/RS780_me.bin.ihex b/firmware/radeon/RS780_me.bin.ihex
new file mode 100644
index 0000000..6479c10
--- /dev/null
+++ b/firmware/radeon/RS780_me.bin.ihex
@@ -0,0 +1,1345 @@
+:1000000000000000C020040000000000000000000C
+:1000100000A0000A000000000000FFFF00284621A9
+:100020000000000000000000D900480000000000AF
+:1000300000000000C02004000000000000000000DC
+:1000400000A0000A000000000000000000E0000026
+:100050000000000000010000C02946200000000050
+:1000600000000000D900480000000000000000006F
+:10007000C0200400000000000000000000A0000AF2
+:10008000000000008100000000204411000000007A
+:1000900000000001002048110000000000042004BE
+:1000A0000060441100000622000000000060000013
+:1000B000000005D10000000000600000000005DE27
+:1000C00000000000C02008000000000000000F0039
+:1000D000002816220000000000000008002116255C
+:1000E000000000000000001800203625000000007D
+:1000F0008D000000002044110000000000000004FA
+:10010000002F022500000000000000000CE00000AD
+:1001100000000018004120000040481100000019B4
+:100120000042200000204811000000008E00000066
+:1001300000204411000000000000002800204A2D8B
+:1001400000000000900000000020441100000000AA
+:100150000000000000204805000000000000000C26
+:1001600000211622000000000000000300281625D0
+:10017000000000000000001900211A220000000009
+:100180000000000400281A26000000000000000003
+:10019000002914C5000000000000001900203625C9
+:1001A0000000000000000000003A140200000000FF
+:1001B00000000016002116250000000000000003CA
+:1001C00000281625000000000000001700200E2D5A
+:1001D00000000000FFFFFFFC00280E2300000000CD
+:1001E00000000000002914A3000000000000001718
+:1001F00000203625000000000000800000280E22AC
+:10020000000000000000000700220E230000000094
+:10021000000000000029386E0000000020000000EF
+:1002200000280E22000000000000000600210E231E
+:1002300000000000000000000029386E00000000EF
+:100240000000000000220222000000000000000068
+:1002500014E0000000000038000000002EE0000064
+:1002600000000035000000002CE000000000003716
+:100270000000000000400E2D0000003900000008C2
+:1002800000200E2D00000000000000090040122D8B
+:10029000000000460000000100400E2D0000003963
+:1002A00000000000C0200C0000000000003FFFFC28
+:1002B0000028122300000000000000020022122487
+:1002C000000000000000001F00211E2300000000AD
+:1002D0000000000014E000000000003E00000008E4
+:1002E00000401C11000000410000000D00201E2DE8
+:1002F000000000000000000F00281E270000000082
+:100300000000000300221E27000000007FC0000044
+:1003100000281A23000000000000001400211A2603
+:10032000000000000000000100331A260000000059
+:100330000000000800221A26000000000000000053
+:1003400000290CC700000000000000270020362410
+:100350000000000000007F000028122100000000C3
+:1003600000001400002F0224000000000000000024
+:100370000CE000000000004B0000000100290E23EB
+:10038000000000000000000E0020362300000000E6
+:100390000000E0000020441100000000FFF8000011
+:1003A00000294A230000000000000000003A2C024F
+:1003B000000000000000000200220E2B00000000E0
+:1003C000FC00000000280E23000000000000000FC9
+:1003D000002036230000000000001FFF00294A23F0
+:1003E000000000000000002700204A2D000000004F
+:1003F000000000000020481100000000000000295B
+:1004000000200E2D00000000060A020000294A23E9
+:100410000000000000000000002048110000000063
+:100420000000000000204811000000000000000152
+:1004300000210222000000000000000014E0000083
+:1004400000000061000000002EE000000000005FDE
+:10045000000000002CE000000000005E0000000032
+:1004600000400E2D000000620000000100400E2D33
+:10047000000000620000000A00200E2D00000000B5
+:100480000000000B0040122D0000006A0000000078
+:10049000C0200C0000000000003FFFFC00281223D9
+:1004A00000000000000000020022122400000000F2
+:1004B0007FC0000000281623000000000000001488
+:1004C0000021162500000000000000010033162561
+:1004D000000000008000000000280E230000000043
+:1004E0000000000000290CA3000000003FFFFC00FA
+:1004F00000290E23000000000000001F00211E2321
+:10050000000000000000000014E000000000006D8A
+:100510000000010000401C11000000700000000DF0
+:1005200000201E2D00000000000000F000281E2703
+:10053000000000000000000400221E270000000050
+:100540008100000000204411000000000000000DA8
+:100550000020481100000000FFFFF0FF00281A30C3
+:10056000000000000000A02800204411000000004E
+:1005700000000000002948E6000000000000A0186C
+:1005800000204411000000003FFFFFFF00284A2325
+:10059000000000000000A010002044110000000036
+:1005A00000000000002048040000000000000030AF
+:1005B0000020162D00000000000000020029162572
+:1005C0000000000000000030002036250000000080
+:1005D000000000250020162D000000000000000093
+:1005E000002F00A300000000000000000CC000006D
+:1005F00000000083000000260020162D00000000EF
+:1006000000000000002F00A4000000000000000017
+:100610000CC000000000008400000000004000004A
+:100620000000008A000000250020362300000000A2
+:100630000000002600203624000000000000001703
+:1006400000201E2D000000000000000200210227F3
+:10065000000000000000000014E000000000008A1C
+:100660000000000000600000000005FF0000000026
+:1006700000600000000005F30000000200210E22CF
+:10068000000000000000000014C000000000008D09
+:1006900000000012C040362000000093000000005F
+:1006A0002EE0000000000091000000002CE000009F
+:1006B000000000900000000200400E2D000000929B
+:1006C0000000000300400E2D000000920000000C0E
+:1006D00000200E2D00000000000000120020362334
+:1006E000000000000000000300210E2200000000B6
+:1006F0000000000014C00000000000980000A00CE2
+:10070000002044110000000000000000C02048004C
+:100710000000000000000000C0404800000000A0F1
+:100720000000A00C002044110000000000000000A8
+:100730000020481100000000000000002EE0000032
+:100740000000009E000000002CE000000000009D62
+:100750000000000200400E2D0000009F000000037A
+:1007600000400E2D0000009F0000000C00200E2D08
+:10077000000000000000000000204803000000000E
+:1007800000000000003A0C0200000000003F0000E2
+:1007900000280E23000000000000001000210E239E
+:1007A00000000000000000110020362300000000BF
+:1007B0000000001E0021022B0000000000000000CD
+:1007C00014C00000000000A700000016C020362062
+:1007D000000000000000001F0021022B00000000AC
+:1007E0000000000014C00000000000AA0000001576
+:1007F000C0203620000000000000000800210E2B61
+:10080000000000000000007F00280E230000000010
+:1008100000000000002F0223000000000000000084
+:100820000CE00000000000E10000000027000000D4
+:10083000000000000000000000600000000002A3B3
+:1008400000000001002F0223000000000000000053
+:100850000AE00000000000B300000000006000009B
+:100860000000013A81000000002044110000000057
+:100870000000000600204811000000000000000CED
+:1008800000221E300000000099800000002044116A
+:1008900000000000000000040020122D00000000F5
+:1008A00000000008002212240000000000000010D8
+:1008B00000201811000000000000000000291CE4C6
+:1008C0000000000000000000006048070000012F49
+:1008D0009B00000000204411000000000000000008
+:1008E00000204802000000009C000000002044118D
+:1008F00000000000000000000033146F0000000042
+:100900000000000100333E23000000000000000052
+:10091000D9004800000000000000000000203C0555
+:1009200000000000810000000020441100000000D1
+:100930000000000E00204811000000000000000030
+:1009400000201010000000000000E007002044110B
+:10095000000000000000000F0021022B000000003A
+:100960000000000014C00000000000CB00F8FF08E9
+:1009700000204811000000009800000000404811CD
+:10098000000000DC000000F000280E220000000043
+:10099000000000A0002F0223000000000000000063
+:1009A0000CC00000000000DA0000001100200E2D35
+:1009B0000000000000000001002F022300000000E2
+:1009C000000000000CE00000000000D50000000264
+:1009D000002F022300000000000000000CE00000D7
+:1009E000000000D400003F0000400C11000000D6C1
+:1009F00000001F0000400C11000000D600000F0096
+:100A000000200C11000000000038000900294A23D2
+:100A1000000000003F00000000280E2B0000000036
+:100A20000000000200220E2300000000000000076A
+:100A300000494A23000000DC00380F09002048115B
+:100A400000000000680000070020481100000000BE
+:100A50000000000800214A270000000000000000FC
+:100A60000020481100000000060A020000294A2464
+:100A700000000000000000000020481100000000FD
+:100A80000000000000204811000000000000A20249
+:100A9000002044110000000000FF000000280E228A
+:100AA000000000000000008000294A230000000030
+:100AB0000000002700200E2D00000000000000268E
+:100AC0000020122D0000000000000000002F008315
+:100AD00000000000000000000CE00000000000EA40
+:100AE0000000000000600000000005F900000000A8
+:100AF00000400000000000EB00000000006000006B
+:100B0000000005FC000000070020222D000000006E
+:100B10000000000500220E2200000000001000006E
+:100B200000280E23000000000000000000292068BB
+:100B30000000000000000000003A0C02000000006D
+:100B4000000000EF00280E2300000000000000005D
+:100B500000292068000000000000001700200E2D72
+:100B6000000000000000000300210223000000003C
+:100B70000000000014E00000000000F80000000B7E
+:100B800000210228000000000000000014C0000046
+:100B9000000000F8000004000029222800000000E6
+:100BA0000000001400203628000000000000001C97
+:100BB00000210E22000000000000000014C0000010
+:100BC000000000FD0000A30C002044110000000004
+:100BD0000000000000204811000000000000001E7E
+:100BE00000210E22000000000000000014C00000E0
+:100BF0000000010B0000A30F0020441100000000C2
+:100C00000000001100200E2D000000000000000177
+:100C1000002F022300000000000000000CC00000B4
+:100C200000000104FFFFFFFF004048110000010B1E
+:100C300000000002002F022300000000000000005E
+:100C40000CC00000000001070000FFFF0040481139
+:100C50000000010B00000004002F02230000000030
+:100C6000000000000CC000000000010A000000FFAE
+:100C7000004048110000010B000000010020481155
+:100C8000000000000002C400002044110000000029
+:100C90000000001F00210E220000000000000000E4
+:100CA00014C00000000001120000001040210E20BE
+:100CB00000000000000000130020362300000000A8
+:100CC0000000001840224A20000000000000001030
+:100CD000C0424A20000001140000000000200C1156
+:100CE0000000000000000013002036230000000078
+:100CF000000000000020481100000000000000007B
+:100D000000204811000000000000000A002010111F
+:100D10000000000000000000002F0224000000007E
+:100D2000000000000CE000000000011B00000000BB
+:100D300000204811000000000000000100531224B0
+:100D400000000117FFBFFFFF00283A2E000000003F
+:100D50000000001B00210222000000000000000033
+:100D600014C000000000012E81000000002044118A
+:100D7000000000000000000D0020481100000000ED
+:100D80000000001800220E3000000000FC000000EF
+:100D900000280E2300000000810000000020441104
+:100DA000000000000000000E0020481100000000BC
+:100DB0000000000000201010000000000000E00E05
+:100DC000002044110000000007F8FF08002048112F
+:100DD000000000000000000000294A23000000007D
+:100DE0000000001C00201E2D000000000000000874
+:100DF00000214A27000000000000000000204811E8
+:100E000000000000060A020000294A240000000039
+:100E10000000000000204811000000000000000059
+:100E200000204811000000000000000000800000C9
+:100E300000000000810000000020441100000000BC
+:100E40000000000100204811000000000000217C8B
+:100E50000020441100000000008000000020481124
+:100E60000000000000000000002048060000000014
+:100E70000000000800214A270000000000000000D8
+:100E800017000000000000000004217F00604411F2
+:100E9000000006220000001F0021023000000000B8
+:100EA0000000000014C00000000006210000000443
+:100EB00000404C1100000135810000000020441169
+:100EC00000000000000000010020481100000000A8
+:100ED000000021F800204411000000000000001C68
+:100EE0000020481100000000000421F900604411B6
+:100EF0000000062200000011002102300000000066
+:100F00000000000014E000000000013C00000000B0
+:100F100000800000000000000000000000600000F1
+:100F20000000000B00000000006004110000031529
+:100F3000000000000020041100000000000000007C
+:100F400000600811000001B2000000000060000015
+:100F5000000001600000FFFF40280E20000000009C
+:100F600000000010C0211220000000000000FFFF60
+:100F7000402806200000000000000010C0210A20C8
+:100F800000000000000000000034146100000000B8
+:100F90000000000000741882000002BB0001A1FDE7
+:100FA00000604411000002E000003FFF002F022F0C
+:100FB00000000000000000000CC00000000001471D
+:100FC00000000000C040040000000001000000001C
+:100FD000006000000000000B000000000060041131
+:100FE00000000315000000000020041100000000B4
+:100FF0000000000000600811000001B200003FFF87
+:10100000002F022F00000000000000000CE0000094
+:10101000000000000000000000600000000001600F
+:101020000000001040210E20000000000000FFFF23
+:10103000C0281220000000000000001040211620EF
+:10104000000000000000FFFFC0681A20000002BB83
+:101050000001A1FD00604411000002E000003FFF1C
+:10106000002F022F00000000000000000CC0000054
+:101070000000015800000000C04004000000000112
+:101080000000225C0020441100000000000000016C
+:1010900000300A2F000000000000000100210A2299
+:1010A000000000000000000300384A220000000099
+:1010B0000000225600204411000000000000001A29
+:1010C00000204811000000000000A1FC0020441195
+:1010D0000000000000000001008048110000000036
+:1010E00000000000006000000000000B0000000095
+:1010F000006000000000018F0000000000600000A0
+:10110000000001A000003FFF002F022F00000000A0
+:10111000000000000CE000000000000000000000E3
+:1011200000202C0800000000000000000020241116
+:101130000000000000000000002028110000000056
+:10114000000022560020441100000000000000169C
+:1011500000204811000000000000225C0020441123
+:101160000000000000000003002048110000000003
+:1011700093800000002044110000000000000002E5
+:1011800000221E290000000000000000007048EB53
+:101190000000019C0000000000600000000002BB95
+:1011A00000000001403306200000000000000000A5
+:1011B000C03024090000000000003FFF002F022F74
+:1011C00000000000000000000CE000000000000033
+:1011D0000000000000600000000002A3000000000A
+:1011E000002F022100000000000000000AE00000C3
+:1011F0000000018100000000006000000000013AD2
+:101200000000000000400000000001869500000082
+:10121000002044110000000000000000002F022107
+:1012200000000000000000000CE00000000001864B
+:1012300000000000C0204800000000000000000185
+:10124000005306210000018292000000002044119A
+:101250000000000000000000C0604800000001978E
+:101260000001A1FD00204411000000000000001159
+:101270000020062D00000000000000000078042A75
+:10128000000002FB00000000002028090000000010
+:1012900000003FFF002F022F0000000000000000B0
+:1012A0000CC000000000017400000000C0400400F9
+:1012B000000000010000021000600411000003158E
+:1012C00000003FFF002F022F000000000000000080
+:1012D0000CE000000000019400000015C020362042
+:1012E0000000000000000016C020362000000000B2
+:1012F0003F800000002004110000000046000000B4
+:1013000000600811000001B2000000000080000031
+:10131000000000000000A1FC0020441100000000BB
+:1013200000003FFF002F022F00000000000000001F
+:101330000CC000000000019B00000001008048116B
+:1013400000000000000000210080481100000000A3
+:101350000000FFFF40280E200000000000000010E9
+:10136000C0211220000000000000FFFF40281620CE
+:101370000000000000000010C0811A2000000000E2
+:101380008100000000204411000000000000000661
+:1013900000204811000000000000000800221E305C
+:1013A000000000000000002900201A2D00000000AD
+:1013B0000000E0000020441100000000FFFBFF09D6
+:1013C00000204811000000000000000F0020222D26
+:1013D0000000000000001FFF00294A280000000054
+:1013E000000000060020222D000000000000000088
+:1013F000002920E80000000000000000002048084C
+:101400000000000000000000002048110000000063
+:10141000060A020000294A26000000000000000021
+:1014200000204811000000000000000000204811CA
+:101430000000000000000100002018110000000062
+:101440000000000800621E280000012F00000008B4
+:1014500000822228000000000002C0000020441189
+:10146000000000000000001500600E2D000001BD0E
+:101470000000001600600E2D000001BD0000C00835
+:1014800000204411000000000000001700200E2D75
+:10149000000000000000000014C00000000001B9BE
+:1014A0000000000000200411000000000000000007
+:1014B0000020480100000000390000000020481111
+:1014C00000000000000000000020481100000000A3
+:1014D000000000000080480200000000000000182A
+:1014E00000202E2D0000000000000000003B0D63D6
+:1014F000000000000000000800224A230000000055
+:101500000000001000224A23000000000000001824
+:1015100000224A2300000000000000000080480371
+:101520000000000000000000006000000000000B50
+:10153000000010000060041100000315000000000E
+:1015400000200411000000000000000000600811ED
+:10155000000001B2000000070021062F000000007B
+:101560000000001300200A2D000000000000000110
+:1015700000202C11000000000000FFFF4028222066
+:10158000000000000000000F0026222800000000DC
+:101590000000001040212620000000000000000F85
+:1015A000002626290000000000000000002028027C
+:1015B000000000000000225600204411000000003E
+:1015C0000000001B00204811000000000000000087
+:1015D000002F022100000000000000000CE00000CD
+:1015E000000001E00000225C002044110000000027
+:1015F0000000008100204811000000000000A1FC54
+:1016000000204411000000000000000100204811EB
+:10161000000000000000008000201C1100000000FD
+:1016200000000000002F0227000000000000000062
+:101630000CE00000000001DC000000000060000081
+:10164000000001E90000000100531E27000001D83E
+:101650000000000100202C11000000000000001F0D
+:1016600000280A22000000000000001F00282A2A8B
+:10167000000000000000000100530621000001D11D
+:101680000000225C00204411000000000000000265
+:1016900000304A2F000000000000A1FC002044118F
+:1016A00000000000000000010020481100000000C0
+:1016B0000000000100301E2F0000000000000000AC
+:1016C000002F022700000000000000000CE00000D6
+:1016D000000000000000000000600000000001E9C0
+:1016E0000000000100531E27000001E50000FFFF7D
+:1016F00040280E20000000000000000F00260E23EE
+:101700000000000000000010C021122000000000B6
+:101710000000000F0026122400000000000000005E
+:1017200000201411000000000000000000601811EB
+:10173000000002BB0001A1FD0020441100000000D8
+:1017400000000000002F022B00000000000000003D
+:101750000CE00000000001F8000000100022162834
+:1017600000000000FFFF0000002816250000000018
+:101770000000FFFF00281A29000000000000000000
+:10178000002948C500000000000000000020480AB1
+:10179000000000000000000000202C1100000000EC
+:1017A000000000100022162300000000FFFF0000D0
+:1017B00000281625000000000000FFFF00281A2462
+:1017C0000000000000000000002948C500000000E3
+:1017D0000000000000731503000002050000000077
+:1017E0000020180500000000000000000073152410
+:1017F0000000020500000000002D14C500000000DC
+:1018000000000000003008A20000000000000000FE
+:101810000020480200000000000000000020280214
+:101820000000000000000000002020030000000075
+:101830000000000000802404000000000000000FF1
+:1018400000210225000000000000000014C000007C
+:101850000000062100000000002B1405000000001D
+:1018600000000001009016250000000000000000AC
+:10187000006000000000000B000000000060041188
+:10188000000003150000000000200411000000000B
+:101890000000000000600811000001B200002256A4
+:1018A00000204411000000000000001A00294A2214
+:1018B0000000000000000000C02000000000000048
+:1018C00000003FFF002F022F00000000000000007A
+:1018D0000CE000000000000000000000C020040038
+:1018E000000000000000225C002044110000000005
+:1018F0000000000300384A21000000000000A1FCA5
+:1019000000204411000000000000000100204811E8
+:10191000000000000000FFFF40281220000000002F
+:1019200000000010C0211A20000000000000FFFF8E
+:1019300040280E200000000000000010C0211620EA
+:10194000000000000000000000741465000002BBED
+:101950000001A1FD00604411000002E00000000150
+:10196000003306210000000000000000002F0221CB
+:1019700000000000000000000CC000000000021980
+:1019800000003FFF002F022F0000000000000000B9
+:101990000CC000000000021200000000C040040063
+:1019A000000000010000000000600000000005DEF3
+:1019B000000000000040040F0000021300000000BF
+:1019C00000600000000005D1000000000060000081
+:1019D000000005DE00000210006004110000031585
+:1019E0000000000000600000000001A000000000F6
+:1019F000006000000000019C00000000006000008A
+:101A0000000002BB0000000000600000000002A314
+:101A1000938000000020441100000000000000003E
+:101A2000002048080000000000000000002F022FE6
+:101A300000000000000000000AE000000000023288
+:101A400000000000006000000000013A00000000FB
+:101A50000040000000000236950000000020441104
+:101A60000000000000000000002F022F0000000016
+:101A7000000000000CE00000000002360000000042
+:101A8000C0404800000002339200000000204411D2
+:101A90000000000000000000C0204800000000001E
+:101AA0000000225600204411000000000000001633
+:101AB00000204811000000000000225C00204411BA
+:101AC000000000000000000300204811000000009A
+:101AD0000000A1FC002044110000000000000001F3
+:101AE00000204811000000000001A1FD0020441169
+:101AF000000000000000000000600411000002FB74
+:101B000000000000C04004000000000100000000D0
+:101B100000600000000005D10000A00C002044116E
+:101B20000000000000000000C0204800000000008D
+:101B300000000000C040480000000000000000005D
+:101B4000006000000000000B0000001840210A2087
+:101B50000000000000000003002F0222000000002F
+:101B6000000000000AE000000000024C0000001429
+:101B70000020222D00000000000801010029222879
+:101B800000000000000000140020362800000000C3
+:101B90000000A30C00204411000000000000000021
+:101BA000C02048000000000000000000C0204800E5
+:101BB0000000000000000000C0404800000002518A
+:101BC00000000000006000000000000B000000109A
+:101BD00000600411000003153F8000000020041184
+:101BE000000000000000000000600811000001B2C9
+:101BF0000000225C002044110000000000000003EF
+:101C000000204811000000000000000000600000FB
+:101C10000000027C0000001700201E2D00000000C4
+:101C20000000000100211E2700000000000000004D
+:101C300014E000000000026A0000001200201E2DC7
+:101C4000000000000000FFFF00281E270000000029
+:101C50000000000000341C2700000000000000000D
+:101C600012C000000000025F0000000000201C11F4
+:101C70000000000000000000002F00E50000000050
+:101C80000000000008C00000000002620000000028
+:101C900000201407000000000000001200201E2D8C
+:101CA000000000000000001000211E2700000000BE
+:101CB0000000000000341C4700000000000000008D
+:101CC00012C00000000002670000000000201C118C
+:101CD0000000000000000000002F00E600000000EF
+:101CE0000000000008C000000000026A00000000C0
+:101CF0000020180700000000000000000060000045
+:101D0000000002C100002256002044110000000023
+:101D1000000000000034202300000000000000004C
+:101D200012C00000000002720000000000342044D5
+:101D3000000000000000000012C00000000002715E
+:101D40000000001600404811000002760000001854
+:101D500000404811000002760000000000342044DA
+:101D6000000000000000000012C00000000002752A
+:101D70000000001700404811000002760000001922
+:101D800000204811000000000000A1FC00204411C8
+:101D900000000000000000010020481100000000C9
+:101DA0000001A1FD00604411000002E900003FFFB6
+:101DB000002F022F00000000000000000CC00000F7
+:101DC0000000025600000000C040040000000001B6
+:101DD0000000001040210620000000000000FFFF6E
+:101DE000C0280A20000000000000001040210E2042
+:101DF000000000000000FFFFC028122000000000CB
+:101E00000000001040211620000000000000FFFF2D
+:101E1000C0881A200000000081000000002044114A
+:101E20000000000000000001002048110000000038
+:101E3000000420040060441100000622000000009D
+:101E400000600000000005D100000000C06000003C
+:101E5000000002A30000000500200A2D0000000081
+:101E60000000000800220A22000000000000002BF1
+:101E700000201A2D000000000000001C00201E2D74
+:101E8000000000000000700000281E270000000075
+:101E90000000000000311CE6000000000000002AE5
+:101EA00000201A2D000000000000000C00221A265D
+:101EB0000000000000000000002F00E6000000000D
+:101EC0000000000006E00000000002920000000098
+:101ED00000201C11000000000000000000200C1178
+:101EE000000000000000002B00203623000000004E
+:101EF0000000001000201811000000000000000089
+:101F000000691CE20000012F9380000000204411B2
+:101F10000000000000000000002048070000000052
+:101F200095000000002044110000000000000000A7
+:101F3000002F022F00000000000000000CE0000055
+:101F40000000029D0000000100333E2F0000000051
+:101F500000000000D90048000000000092000000CE
+:101F6000002044110000000000000000C0204800D4
+:101F7000000000000000001C0040362700000000A8
+:101F80000000000CC0220A20000000000000002910
+:101F9000002036220000000000000028C04036204B
+:101FA000000000000000A2A4002044110000000076
+:101FB000000000090020481100000000A1000000FE
+:101FC00000204411000000000000000100804811C2
+:101FD000000000000000002100201E2D0000000075
+:101FE00000000000002C1CE30000000000000021A5
+:101FF00000203627000000000000002200201E2DD7
+:102000000000000000000000002C1CE400000000A4
+:1020100000000022002036270000000000000023FE
+:1020200000201E2D0000000000000000003120A351
+:102030000000000000000000002D1D07000000004F
+:1020400000000023002036270000000000000024CC
+:1020500000201E2D0000000000000000003120C400
+:102060000000000000000000002D1D07000000001F
+:10207000000000240080362700000000000000213E
+:10208000002036230000000000000022002036243B
+:10209000000000000000000000311CA30000000050
+:1020A0000000002300203627000000000000000090
+:1020B00000311CC40000000000000024008036270E
+:1020C000000000000000001A002036270000000079
+:1020D0000000001B00203628000000000000001750
+:1020E00000201E2D00000000000000020021022739
+:1020F000000000000000000014C00000000002DC2E
+:102100000000000000400000000002D90000001A9A
+:1021100000203627000000000000001B00203628A9
+:10212000000000000000001700201E2D000000002D
+:102130000000000200210227000000000000000053
+:1021400014E00000000002D9000000030021022773
+:10215000000000000000000014E00000000002DCAD
+:102160000000002300201E2D0000000000000000E1
+:10217000002E00E1000000000000000002C000008E
+:10218000000002DC0000002100201E2D00000000E5
+:1021900000000000003120A100000000000000004D
+:1021A000002E00E8000000000000000006C0000053
+:1021B000000002DC0000002400201E2D00000000B2
+:1021C00000000000002E00E20000000000000000FF
+:1021D00002C00000000002DC0000002200201E2DD2
+:1021E0000000000000000000003120C200000000DC
+:1021F00000000000002E00E80000000000000000C9
+:1022000006C00000000002DC0000000000600000CA
+:10221000000005FF0000000000600000000002B5A3
+:102220000000000000400000000002DE000000008E
+:1022300000600000000002B5000000000060000027
+:10224000000005F60000000000400000000002DE73
+:102250000000000000600000000002A70000000075
+:1022600000400000000002DE0000001A00201E2DC9
+:10227000000000000000001B0080222D0000000074
+:102280000000001000221E230000000000000000DB
+:1022900000294887000000000000000000311CA356
+:1022A000000000000000001000221E2700000000B7
+:1022B0000000000000294887000000000000001016
+:1022C00000221E230000000000000000003120C496
+:1022D000000000000000FFFF00282228000000008E
+:1022E0000000000000894907000000000000001005
+:1022F00000221E2300000000000000000029488783
+:10230000000000000000001000221E21000000005C
+:102310000000000000294847000000000000000005
+:1023200000311CA3000000000000001000221E2746
+:1023300000000000000000000029488700000000A5
+:102340000000000000311CA100000000000000108F
+:1023500000221E270000000000000000002948475E
+:10236000000000000000001000221E2300000000FA
+:1023700000000000003120C4000000000000FFFF4A
+:102380000028222800000000000000000029490762
+:10239000000000000000001000221E2100000000CC
+:1023A00000000000003120C2000000000000FFFF1C
+:1023B00000282228000000000000000000894907D2
+:1023C000000000000000001000221E23000000009A
+:1023D0000000000000294887000000000000000104
+:1023E00000220A210000000000000000003308A2C3
+:1023F000000000000000001000221E22000000006B
+:102400000000001000212222000000000000000057
+:1024100000294907000000000000000000311CA353
+:10242000000000000000001000221E270000000035
+:1024300000000000002948870000000000000001A3
+:1024400000220A210000000000000000003008A265
+:10245000000000000000001000221E22000000000A
+:1024600000000010002122220000000000000000F7
+:1024700000294907000000000000001000221E2370
+:102480000000000000000000003120C40000000037
+:102490000000FFFF002822280000000000000000CC
+:1024A000002949070000000000000000003808C5AE
+:1024B00000000000000000000030084100000000A3
+:1024C0000000000100220A220000000000000000BD
+:1024D000003308A2000000000000001000221E22AD
+:1024E0000000000000000010002122220000000077
+:1024F00000000000008949070000000000000017EC
+:102500000020222D000000000000000014C0000088
+:1025100000000318FFFFFFEF002806210000000065
+:10252000000000140020222D000000000000F8E050
+:1025300000204411000000000000000000294901B3
+:1025400000000000000000000089490100000000B8
+:102550000000000000204811000000000000000002
+:102560000020481100000000060A02000080481107
+:102570000000000000000000C0200000000000007B
+:1025800097000000C020441100000000000000007F
+:10259000C0204811000000008A0000000020441103
+:1025A00000000000000000000020481100000000B2
+:1025B0000000225C00204411000000000000000028
+:1025C000C0204800000000000000A1FC00204411D1
+:1025D0000000000000000000C020480000000000D3
+:1025E00000000000C0200400000000000000000007
+:1025F00000A0000A0000000097000000C020441165
+:102600000000000000000000C02048110000000091
+:102610008A000000C02044110000000000000000FB
+:1026200000204811000000000000225C002044113E
+:102630000000000000000000C02048000000000072
+:102640000000A1FC00204411000000000000000078
+:10265000C02048000000000000000000C02004006E
+:10266000000000000000000000A0000A00000000C0
+:10267000970000000020441100000000000000004E
+:1026800000204811000000008A00000000204411D2
+:1026900000000000000000000020481100000000C1
+:1026A0000000225C00204411000000000000000037
+:1026B000C0204800000000000000A1FC00204411E0
+:1026C0000000000000000000C020480000000000E2
+:1026D00000000000C0200400000000000000000016
+:1026E00000A0000A00000000970000000020441134
+:1026F0000000000000000000002048110000000061
+:102700008A000000002044110000000000000000CA
+:1027100000204811000000000000225C002044114D
+:102720000000000000000000C02048000000000081
+:102730000000A1FC00204411000000000000000087
+:10274000C0204800000000000001A1FD002044114D
+:102750000000000000000000D90048000000000058
+:1027600000000000C0200400000000000000000085
+:1027700000A0000A000000000000225700204411C1
+:102780000000000000000003C0484A2000000000D4
+:102790000000225D00204411000000000000000045
+:1027A000C040480000000000000000000060000081
+:1027B000000005DE00000000C0200800000000004E
+:1027C0000000225C00204411000000000000000313
+:1027D00000384A22000000000000A1FC0020441143
+:1027E0000000000000000000C020480000000000C1
+:1027F0000001A1FD002044110000000000000000C5
+:10280000002F022200000000000000000CE0000089
+:102810000000000000000000402048000000000010
+:102820000000000140304A200000000000000002CB
+:10283000C0304A20000000000000000100530A22BE
+:10284000000003550000003FC0280A2000000000DF
+:102850008100000000204411000000000000000181
+:102860000020481100000000000021F80020441161
+:1028700000000000000000180020481100000000C7
+:10288000000421F90060441100000622000000113C
+:1028900000210230000000000000000014E00000F1
+:1028A0000000035E00000014002F02220000000060
+:1028B000000000000CC000000000036C0001A2A496
+:1028C00000204411000000000000000000604802E9
+:1028D00000000374000021000020441100000000EB
+:1028E00000000000C02048000000000000000000C0
+:1028F000C02048000000000000000000C020480088
+:102900000000000000000000C0404800000000007F
+:1029100000000004002F0222000000000000000060
+:102920000CC00000000003700001A2A400204411AC
+:1029300000000000000000000040480200000367A3
+:1029400000000028002F022200000000000000000C
+:102950000CC00000000005BA0001A2A40020441130
+:102960000000000000000000004048020000036773
+:102970000000002C00203626000000000000004966
+:1029800000201811000000000000003F0020481146
+:10299000000000000000000100331A2600000000C3
+:1029A00000000000002F02260000000000000000D0
+:1029B0000CC00000000003760000002C00801A2DDF
+:1029C000000000000000003FC0280A2000000000B6
+:1029D00000000015002F022200000000000000008F
+:1029E0000CE000000000038C00000006002F022213
+:1029F00000000000000000000CE00000000003B731
+:102A000000000016002F022200000000000000005D
+:102A10000CE00000000003B900000020002F02229B
+:102A200000000000000000000CE00000000003A215
+:102A30000000000F002F0222000000000000000034
+:102A40000CE00000000003AE00000010002F022286
+:102A500000000000000000000CE00000000003AED9
+:102A60000000001E002F02220000000000000000F5
+:102A70000CE00000000003960000A2A40020441116
+:102A800000000000000000000040480200000000BC
+:102A90000800000000290A220000000000000003D6
+:102AA00040210E20000000000000000CC021122078
+:102AB00000000000000800000028122400000000B0
+:102AC00000000014C02216200000000000000000DA
+:102AD000002914A4000000000000A2A4002044115A
+:102AE0000000000000000000002948A200000000D3
+:102AF0000000A1FE002044110000000000000000C2
+:102B00000040480300000000810000000020441144
+:102B1000000000000000000100204811000000003B
+:102B2000000021F800204411000000000000001601
+:102B30000020481100000000000421F90060441149
+:102B400000000622000000150021023000000000F5
+:102B50000000000014E00000000003980000210EB7
+:102B6000002044110000000000000000C0204800C8
+:102B70000000000000000000C0204800000000002D
+:102B80000000A2A40020441100000000000000008A
+:102B900000404802000000008100000000204411B5
+:102BA00000000000000000010020481100000000AB
+:102BB000000021F800204411000000000000001770
+:102BC0000020481100000000000421F900604411B9
+:102BD0000000062200000003002102300000000077
+:102BE0000000000014E00000000003A40000210821
+:102BF000002044110000000000000000C020480038
+:102C00000000000000000000C0204800000000009C
+:102C10000000A2A4002044110000000000000000F9
+:102C200000404802000000000000A2A4002044115F
+:102C3000000000000000000000204802000000002A
+:102C4000800000000020441100000000000000008F
+:102C50000020481100000000810000000020441105
+:102C600000000000000000100020481100000000DB
+:102C70000000000000200010000000000000000024
+:102C800014C00000000003B4000000000040000079
+:102C9000000000000001A2A4002044110000000078
+:102CA0000000000600404811000000000001A2A43E
+:102CB00000204411000000000000001600604811D0
+:102CC000000003740000000000400000000000004D
+:102CD00000000000C020080000000000000000000C
+:102CE000C0200C00000000000000001D0021022395
+:102CF000000000000000000014E00000000003CE0F
+:102D000081000000002044110000000000000001CC
+:102D10000020481100000000000021F800204411AC
+:102D20000000000000000018002048110000000012
+:102D3000000421F900604411000006220000001187
+:102D400000210230000000000000000014E000003C
+:102D5000000003C200002100002044110000000018
+:102D600000000000002048020000000000000000F9
+:102D70000020480300000000BABECAFE002048112F
+:102D800000000000CAFEBABE00204811000000008A
+:102D90000000A2A400204411000000000000000474
+:102DA0000040481100000000000021700020441184
+:102DB00000000000000000000020480200000000A9
+:102DC0000000000000204803000000008100000017
+:102DD00000204411000000000000000A00204811FB
+:102DE00000000000000000000020001000000000B3
+:102DF0000000000014C00000000003D38C0000009D
+:102E00000020441100000000CAFEBABE0040481174
+:102E100000000000810000000020441100000000BC
+:102E200000000001002048110000000000003FFFEA
+:102E300040280A20000000008000000040280E20EA
+:102E40000000000040000000C02812200000000028
+:102E50000004000000694622000006220000000075
+:102E6000002014100000000000000000002F0223CA
+:102E700000000000000000000CC00000000003E1A2
+:102E800000000000C0401800000003E400003FFF05
+:102E9000C0281A2000000000000400000069462637
+:102EA00000000622000000000020181000000000B2
+:102EB00000000000002F02240000000000000000BD
+:102EC0000CC00000000003E700000000C0401C0030
+:102ED000000003EA00003FFFC0281E2000000000A1
+:102EE00000040000006946270000062200000000E0
+:102EF00000201C1000000000000000000020440220
+:102F00000000000000000000002820C500000000B4
+:102F100000000000004948E800000000A580000013
+:102F200000200811000000000000200000200C110B
+:102F30000000000083000000006044110000041243
+:102F4000000000000020440200000000000000001B
+:102F5000C0204800000000000000000040204800A1
+:102F6000000000000000001FC0210220000000003F
+:102F70000000000014C00000000003F70000201053
+:102F800000204411000000000000800000204811D3
+:102F9000000000000000FFFFC0481220000003FFF7
+:102FA000A780000000200811000000000000A00021
+:102FB00000200C110000000083000000006044119C
+:102FC0000000041200000000002044020000000085
+:102FD00000000000C02048000000000000000000C9
+:102FE000C0204800000000000000FFFFC0281220A1
+:102FF00000000000830000000020441100000000D9
+:103000000000000000304883000000008400000041
+:10301000002044110000000000000000C020480013
+:1030200000000000000000001D0000000000000083
+:103030008300000000604411000004120000000042
+:10304000C040040000000001A98000000020081119
+:10305000000000000000C00000400C11000003FA56
+:10306000AB80000000200811000000000000F8E024
+:1030700000400C11000003FAAD8000000020081190
+:10308000000000000000F88000400C11000003FA6E
+:10309000B380000000200811000000000000F3FCD5
+:1030A00000400C11000003FAAF800000002008115E
+:1030B000000000000000E00000400C11000003FAD6
+:1030C000B180000000200811000000000000F000A6
+:1030D00000400C11000003FA83000000002044119E
+:1030E00000000000000021480020481100000000FE
+:1030F00084000000002044110000000000000000D7
+:10310000C020480000000000000000001D0000007A
+:10311000000000000000000000800000000000002F
+:1031200001182000C0304620000000000000000010
+:10313000D90048000000000000000000C02004008A
+:10314000000000000000000000A0000A00000000D5
+:103150000218A000C030462000000000000000005F
+:10316000D90048000000000000000000C02004005A
+:10317000000000000000000000A0000A00000000A5
+:103180000318C000C030462000000000000000000E
+:10319000D90048000000000000000000C02004002A
+:1031A000000000000000000000A0000A0000000075
+:1031B0000418F8E0C03046200000000000000000C5
+:1031C000D90048000000000000000000C0200400FA
+:1031D000000000000000000000A0000A0000000045
+:1031E0000518F880C03046200000000000000000F4
+:1031F000D90048000000000000000000C0200400CA
+:10320000000000000000000000A0000A0000000014
+:103210000618E000C030462000000000000000005A
+:10322000D90048000000000000000000C020040099
+:10323000000000000000000000A0000A00000000E4
+:103240000718F000C0304620000000000000000019
+:10325000D90048000000000000000000C020040069
+:10326000000000000000000000A0000A00000000B4
+:103270000818F3FCC03046200000000000000000E9
+:10328000D90048000000000000000000C020040039
+:10329000000000000000000000A0000A0000000084
+:1032A00000000033C0300A200000000000000000D1
+:1032B000C0403440000000000000003000200A2D13
+:1032C0000000000000000000C0290C4000000000C9
+:1032D0000000003000203623000000000000000045
+:1032E000C0200400000000000000000000A0000A50
+:1032F00000000000860000000020441100000000D3
+:1033000000000000004048010000000085000000AF
+:10331000C0204411000000000000000000404801EF
+:10332000000000000000217C00204411000000008B
+:1033300000000018402102200000000000000000F2
+:1033400014C000000000044700800000C0494A206B
+:103350000000044800000000C020480000000000F9
+:1033600000000000C0204800000000000000000035
+:10337000C02048000000000081000000002044112F
+:1033800000000000000000010020481100000000C3
+:1033900000000000C0200800000000000000000441
+:1033A000002F0222000000000000000006E00000E4
+:1033B000000004500000000400200811000000007C
+:1033C0000000000017000000000000000004217F42
+:1033D00000604411000006220000001F002102309E
+:1033E000000000000000000014C000000000000009
+:1033F0000000000000404C020000045000000000EB
+:10340000C0200C000000000000000000C0201000E0
+:103410000000000000000000C020140000000000B8
+:1034200000000000C02018000000000000000000A4
+:10343000C0201C000000000000007F0000280A21BE
+:103440000000000000004500002F022200000000E4
+:10345000000000000CE0000000000461000000001B
+:10346000C02020000000000000000004002F0228FF
+:10347000000000000000000006E000000000046101
+:1034800000000004002020110000000000000000E7
+:1034900017000000000000000000001000280A23B0
+:1034A0000000000000000010002F022200000000B9
+:1034B000000000000CE00000000004698100000032
+:1034C000002044110000000000000001002048110D
+:1034D00000000000000400000069462400000622ED
+:1034E00000000000004000000000046E81000000A9
+:1034F00000204411000000000000000000204811DE
+:10350000000000000000216D0020441100000000B8
+:10351000000000000020480400000000000000003F
+:10352000006048050000062700000000002824F085
+:10353000000000000000000700280A23000000002F
+:1035400000000001002F0222000000000000000027
+:103550000AE000000000047500000000002F00C910
+:10356000000000000000000004E000000000048EE5
+:1035700000000000004000000000049B000000026A
+:10358000002F022200000000000000000AE00000FE
+:103590000000047A00000000002F00C900000000B5
+:1035A0000000000002E000000000048E00000000A7
+:1035B000004000000000049B00000003002F0222D6
+:1035C00000000000000000000AE000000000047F8E
+:1035D00000000000002F00C90000000000000000F3
+:1035E0000CE000000000048E00000000004000001D
+:1035F0000000049B00000004002F022200000000D5
+:10360000000000000AE00000000004840000000048
+:10361000002F00C900000000000000000AE00000C8
+:103620000000048E00000000004000000000049B29
+:1036300000000005002F0222000000000000000032
+:103640000AE000000000048900000000002F00C90B
+:10365000000000000000000006E000000000048EF2
+:1036600000000000004000000000049B0000000675
+:10367000002F022200000000000000000AE000000D
+:103680000000048E00000000002F00C900000000B0
+:103690000000000008E000000000048E00000000B0
+:1036A000004000000000049B00007F0000280A2169
+:1036B0000000000000004500002F02220000000072
+:1036C000000000000AE00000000000000000000808
+:1036D00000210A23000000000000000014C00000C8
+:1036E000000004980000216900204411000000003F
+:1036F00000000000C02048000000000000000000A2
+:10370000C02048000000000000000000C020480069
+:1037100000000000CAFEBABE0040481100000000D0
+:1037200000000000C0204400000000000000000075
+:10373000C02000000000000000000000C040480061
+:103740000000000000007F0000280A2100000000A7
+:1037500000004500002F02220000000000000000D1
+:103760000AE00000000004A100000000C0200000EA
+:103770000000000000000000C02000000000000069
+:1037800000000000C0400000000000000000000039
+:1037900000404C080000046100000000C020080048
+:1037A000000000000000001040210E20000000007A
+:1037B0000000001140211220000000000000001253
+:1037C0004021162000000000000021690020441163
+:1037D000000000000000000000204802000000007F
+:1037E0000000000000210225000000000000000091
+:1037F00014E00000000004AB00040000C0494A20AF
+:10380000000004ACFFFBFFFFC0284A2000000000BE
+:103810000000000000210223000000000000000062
+:1038200014E00000000004B800000000C0204800C0
+:103830000000000000000000C02048000000000060
+:103840000000000000210224000000000000000031
+:1038500014C000000000000081000000002044119E
+:10386000000000000000000C0020481100000000D3
+:103870000000000000200010000000000000000018
+:1038800014C00000000004B4A00000000020441197
+:1038900000000000CAFEBABE00404811000000004F
+:1038A000810000000020441100000000000000041E
+:1038B00000204811000000000000216B002044118E
+:1038C0000000000000000000C020481000000000C0
+:1038D00081000000002044110000000000000005ED
+:1038E00000204811000000000000216C002044115D
+:1038F0000000000000000000C02048100000000090
+:1039000000000000002F0224000000000000000062
+:103910000CE000000000000000000000004000007B
+:10392000000004B200000000C0210A2000000000D6
+:103930000000000014C00000000004CB8100000063
+:103940000020441100000000000000000020481189
+:10395000000000000000216D002044110000000064
+:1039600000000000C020480000000000000000002F
+:10397000C060480000000627000000000040000072
+:10398000000004CF8100000000204411000000006E
+:1039900000000001002048110000000000040000A9
+:1039A000C02946200000000000000000C0600000A8
+:1039B0000000062200000001002102220000000099
+:1039C0000000000014C00000000004D600002169BF
+:1039D000002044110000000000000000C02048004A
+:1039E0000000000000000000C020480000000000AF
+:1039F000000000000020481000000000CAFEBABE0F
+:103A0000004048110000000000000000C0204400F9
+:103A10000000000000000000C0404810000000004E
+:103A2000810000000020441100000000000000019F
+:103A30000020481100000000000021F8002044117F
+:103A4000000000000000000E0020481100000000EF
+:103A5000000421F90060441100000622000000006B
+:103A600000210230000000000000000014C000002F
+:103A7000000004D800002180002044110000000054
+:103A800000000000C020480000000000000000000E
+:103A9000C02000000000000000000000C02048001E
+:103AA0000000000000000000C02000000000000036
+:103AB00000000000C04048000000000000000003BB
+:103AC00000333E2F00000000000000010021022111
+:103AD000000000000000000014E0000000000508E5
+:103AE0000000002C00200A2D00000000000400004F
+:103AF00018E00C11000004F70000000100333E2F15
+:103B000000000000000021690020441100000000B6
+:103B1000000000000020480200000000000000003B
+:103B200000204803000000000000000800300A22C6
+:103B30000000000000000000C0204800000000005D
+:103B400000000000C02048000000000000002169C3
+:103B50000020441100000000000000000020480286
+:103B600000000000000000000020480300000000EA
+:103B70000000000800300A220000000000000000E1
+:103B8000C02048000000000000000000D8C048002D
+:103B9000000004EB00002169002044110000000037
+:103BA00000000000002048020000000000000000AB
+:103BB00000204803000000000000000800300A2236
+:103BC0000000000000000000C020480000000000CD
+:103BD00000000000C0204800000000000000002D90
+:103BE0000020122D000000000000000000290C83BE
+:103BF00000000000000021690020441100000000C6
+:103C0000000000000020480200000000000000004A
+:103C100000204803000000000000000800300A22D5
+:103C20000000000000000000C0204800000000006C
+:103C300000000000C020480000000000000000114B
+:103C400000210224000000000000000014C0000059
+:103C5000000000000000000000400000000004B26E
+:103C60000000002CC0203620000000000000002DC5
+:103C7000C0403620000000000000000F002102219B
+:103C8000000000000000000014C000000000050D4E
+:103C900000000000006000000000000B00000000B9
+:103CA000D90000000000000000000000C040040037
+:103CB00000000001B50000000020441100000000D9
+:103CC000000020000020481100000000B6000000A5
+:103CD00000204411000000000000A0000020481156
+:103CE00000000000B70000000020441100000000A8
+:103CF0000000C0000020481100000000B8000000D3
+:103D000000204411000000000000F8E000204811ED
+:103D100000000000B9000000002044110000000075
+:103D20000000F8800020481100000000BA000000E8
+:103D300000204411000000000000E00000204811B5
+:103D400000000000BB000000002044110000000043
+:103D50000000F0000020481100000000BC0000003E
+:103D600000204411000000000000F3FC0020481176
+:103D7000000000008100000000204411000000004D
+:103D8000000000020020481100000000000000FFB9
+:103D900000280E300000000000000000002F022369
+:103DA00000000000000000000CC000000000052121
+:103DB00000000000C020080000000000000000001B
+:103DC00014C00000000005360000000000200C11A7
+:103DD000000000000000001C00203623000000004E
+:103DE0000000002B00203623000000000000002906
+:103DF00000203623000000000000002800203623A9
+:103E00000000000000000017002036230000000022
+:103E100000000025002036230000000000000026DE
+:103E2000002036230000000000000015002036238B
+:103E300000000000000000160020362300000000F3
+:103E4000FFFFE00000200C11000000000000002136
+:103E5000002036230000000000000022002036234E
+:103E60000000000000001FFF00200C1100000000F7
+:103E70000000002300203623000000000000002482
+:103E80000020362300000000F1FFFFFF00283A2E3B
+:103E9000000000000000001AC0220E2000000000F8
+:103EA000000000000029386E0000000081000000C2
+:103EB000002044110000000000000006002048110E
+:103EC000000000000000002A402036200000000012
+:103ED00087000000002044110000000000000000E6
+:103EE000C0204800000000000000A1F400204411A0
+:103EF000000000000000000000204810000000004A
+:103F00009D00000000204411000000000000001F80
+:103F100040214A20000000009600000000204411CB
+:103F20000000000000000000C02048000000000069
+:103F300000000000C0200C00000000000000000095
+:103F4000C0201000000000000000001F0021162407
+:103F5000000000000000000014C00000000000008D
+:103F60000000001D002036230000000000000003B8
+:103F700000281E2300000000000000080022222369
+:103F800000000000FFFFF0000028222800000000D1
+:103F900000000000002920E8000000000000001FD1
+:103FA00000203628000000000000001800211E2319
+:103FB0000000000000000020002036270000000064
+:103FC0000000000200221624000000000000000093
+:103FD000003014A8000000000000001E002036255C
+:103FE000000000000000000300211A24000000006F
+:103FF0001000000000281A2600000000EFFFFFFF5D
+:1040000000283A2E0000000000000000004938CED1
+:10401000000006100000000140280A2000000000F7
+:104020000000000640280E200000000000000300F1
+:10403000C028122000000000000000080021122407
+:104040000000000000000000C0201620000000005A
+:1040500000000000C0201A20000000000000000046
+:1040600000210222000000000000000014C0000037
+:104070000000056C810000000020441100000000D9
+:10408000000000010020481100000000000022583C
+:1040900000300A24000000000004000000694622ED
+:1040A00000000622000021690020441100000000E9
+:1040B0000000000000204805000000000002000091
+:1040C00000294A26000000000000000000204810DF
+:1040D00000000000CAFEBABE002048110000000027
+:1040E00000000002002F022300000000000000007A
+:1040F0000CC000000000057400000000C0201C106F
+:104100000000000000000000C04000000000058228
+:1041100000000002002F0223000000000000000049
+:104120000CC0000000000574810000000020441154
+:104130000000000000000001002048110000000005
+:104140000000225800300A24000000000004000093
+:10415000006946220000062200000000C0201C105A
+:104160000000000000000000C040000000000582C8
+:1041700000000000002F02230000000000000000EB
+:104180000CC000000000057800000000C0201C00EA
+:104190000000000000000000C04000000000058298
+:1041A00000000004002F02230000000000000000B7
+:1041B0000CC00000000005808100000000204411B8
+:1041C0000000000000000000002048110000000076
+:1041D0000000216D002044110000000000000000DC
+:1041E000C02048000000000000000000C06048003F
+:1041F000000006270000000000401C10000005829F
+:1042000000000000C02000000000000000000000CE
+:10421000C040000000000000000000000EE00000B0
+:10422000000005840000000000600000000005C3DD
+:1042300000000000002F0224000000000000000029
+:104240000CC00000000005920000A2B7002044113D
+:1042500000000000000000000020480700000000EF
+:10426000000000330020262D000000000000001A8E
+:10427000002122290000000000000006002226295B
+:10428000000000000000A2C4002044110000000053
+:1042900000000000003048E90000000000000000BD
+:1042A00000E00000000005900000A2D100204411B1
+:1042B000000000000000000000404808000000006E
+:1042C0000000A2D100204411000000000000000105
+:1042D00000504A280000000000000001002F0224C6
+:1042E00000000000000000000CC00000000005A05D
+:1042F0000000A2BB002044110000000000000000EC
+:104300000020480700000000000000340020262D97
+:10431000000000000000001A002122290000000017
+:104320000000000600222629000000000000A2C5AF
+:10433000002044110000000000000000003048E9A7
+:10434000000000000000000000E000000000059EEA
+:104350000000A2D200204411000000000000000074
+:1043600000404808000000000000A2D200204411D4
+:10437000000000000000000100504A28000000007A
+:1043800000000002002F02240000000000000000D6
+:104390000CC00000000005AE0000A2BF00204411C8
+:1043A000000000000000000000204807000000009E
+:1043B000000000350020262D000000000000001A3B
+:1043C000002122290000000000000006002226290A
+:1043D000000000000000A2C6002044110000000000
+:1043E00000000000003048E900000000000000006C
+:1043F00000E00000000005AC0000A2D30020441142
+:10440000000000000000000000404808000000001C
+:104410000000A2D3002044110000000000000001B1
+:1044200000504A28000000000000A2C300204411F0
+:10443000000000000000000000204807000000000D
+:10444000000000360020262D000000000000001AA9
+:104450000021222900000000000000060022262979
+:10446000000000000000A2C700204411000000006E
+:1044700000000000003048E90000000000000000DB
+:1044800000E00000000005B80000A2D400204411A4
+:10449000000000000000000000404808000000008C
+:1044A0000000A2D400204411000000000000000120
+:1044B00000504A2800000000850000000020441140
+:1044C0000000000000000000002048010000000083
+:1044D0000000304A002044110000000001000000EC
+:1044E0000020481100000000000000000040000013
+:1044F000000005BEA4000000C02044110000000020
+:1045000000000000C0404800000000000000000063
+:10451000C0600000000005C300000000C0400400AF
+:10452000000000010001A2A40020441100000000CE
+:104530000000003F00204811000000000000003F84
+:1045400000204811000000000000003F002048113A
+:10455000000000000000003F0020481100000000A3
+:104560000000000500204811000000000000A1F438
+:10457000002044110000000000000000002048114D
+:10458000000000008800000000204411000000002E
+:10459000000000010020481100000000FF000000A2
+:1045A000002044110000000000000000002048111D
+:1045B0000000000000000001002048110000000081
+:1045C0000000000200804811000000000000000010
+:1045D0000EE00000000005D60000100000200811C9
+:1045E000000000000000002B002036220000000028
+:1045F0000000000000600000000005DA000000007C
+:1046000000600000000005C3980000000020441175
+:1046100000000000000000000080481100000000C1
+:1046200000000000C0600000000005DA000000008B
+:10463000C0400400000000010000A2A400204411BA
+:1046400000000000000000220020481100000000CF
+:10465000890000000020441100000000000000015B
+:1046600000404811000005CD9700000000204411D3
+:1046700000000000000000000020481100000000C1
+:104680008A0000000020441100000000000000002B
+:1046900000404811000005CD00000000006000004F
+:1046A000000005F30001A2A4C02044110000000096
+:1046B0000000001600604811000003740000201084
+:1046C00000204411000000000001000000204811FB
+:1046D00000000000810000000020441100000000E4
+:1046E0000000000100204811000000000000217CB3
+:1046F0000020441100000000098000000020481143
+:1047000000000000FFFFFFFF002048110000000034
+:104710000000000000204811000000000000000020
+:1047200017000000000000000004217F0060441119
+:10473000000006220000001F0021023000000000DF
+:104740000000000014C00000000000000000000491
+:1047500000404C11000005ED00000000004000008A
+:10476000000000000000001700201E2D00000000C7
+:104770000000000400291E270000000000000017B0
+:1047800000803627000000000000001700201E2DCA
+:1047900000000000FFFFFFFB00281E2700000000B4
+:1047A00000000017008036270000000000000017FE
+:1047B00000201E2D000000000000000800291E2718
+:1047C00000000000000000170080362700000000F5
+:1047D0000000001700201E2D00000000FFFFFFF763
+:1047E00000281E2700000000000000170080362768
+:1047F000000000000001A2A40020441100000000FD
+:104800000000001600604811000003740000201032
+:1048100000204411000000000001000000204811A9
+:10482000000000000000217C002044110000000076
+:10483000018000000020481100000000FFFFFFFF82
+:104840000020481100000000000000000020481176
+:104850000000000000000000170000000000000041
+:104860008100000000204411000000000000000151
+:1048700000204811000000000004217F0060441166
+:10488000000006220000001F00210230000000008E
+:104890000000000014C0000000000621000000100D
+:1048A00000404C110000060700000000C02004007A
+:1048B000000000000000000038C000000000000000
+:1048C0000000001D00200A2D000000000000001E56
+:1048D00000200E2D000000000000001F0020122DFF
+:1048E00000000000000000200020162D0000000045
+:1048F00000002169002044110000000000000000B9
+:1049000000204804000000000000000000204805CE
+:10491000000000000000000000204801000000002E
+:10492000CAFEBABE002048110000000000000004CA
+:10493000003012240000000000000000002F00647E
+:1049400000000000000000000CC000000000062075
+:104950000000000300281A220000000000000008E8
+:104960000022122200000000FFFFF00000281224A5
+:104970000000000000000000002910C4000000003A
+:104980000000001F0040362400000000000000006E
+:104990000080000000000000000000001AC00000BD
+:1049A000000006229F0000000020441100000000CB
+:1049B000CAFEBABE0020481100000000000000003E
+:1049C0001AE0000000000625000000000080000042
+:1049D00000000000000000001AC0000000000627D0
+:1049E0009E0000000020441100000000CAFEBABE74
+:1049F0000020481100000000000000001AE0000044
+:104A00000000062A000000000080000000000000F6
+:104A100000000000006000000000000B000010001B
+:104A200000600411000003150000000000200411C4
+:104A3000000000000000000000600811000001B24A
+:104A40000000225C00204411000000000000000370
+:104A500000204811000000000000225600204411F0
+:104A6000000000000000001B0020481100000000B2
+:104A70000000A1FC00204411000000000000000123
+:104A800000204811000000000001A1FDC0204411D9
+:104A9000000000000000002100201E2D000000008A
+:104AA0000000001000221E2700000000000000246B
+:104AB0000020222D000000000000FFFF0028222817
+:104AC000000000000000000000294907000000006D
+:104AD000000000000020481100000000000000223B
+:104AE0000020222D000000000000FFFF00282228E7
+:104AF000000000000000000000294907000000003D
+:104B00000000000000204811000000000000002309
+:104B100000201E2D000000000000001000221E27B3
+:104B2000000000000000000000294907000000000C
+:104B300000000000004048110000000000000000DC
+:104B40000000000000000000000000000000000065
+:104B50000000000000000000000000000000000055
+:104B60000000000000000000000000000000000045
+:104B70000000000000000000000000000000000035
+:104B80000000000000000000000000000000000025
+:104B90000000000000000000000000000000000015
+:104BA0000000000000000000000000000000000005
+:104BB00000000000000000000000000000000000F5
+:104BC00000000000000000000000000000000000E5
+:104BD00000000000000000000000000000000000D5
+:104BE00000000000000000000000000000000000C5
+:104BF00000000000000000000000000000000000B5
+:104C000000000000000000000000000000000000A4
+:104C10000000000000000000000000000000000094
+:104C20000000000000000000000000000000000084
+:104C30000000000000000000000000000000000074
+:104C40000000000000000000000000000000000064
+:104C50000000000000000000000000000000000054
+:104C60000000000000000000000000000000000044
+:104C70000000000000000000000000000000000034
+:104C80000000000000000000000000000000000024
+:104C90000000000000000000000000000000000014
+:104CA0000000000000000000000000000000000004
+:104CB00000000000000000000000000000000000F4
+:104CC00000000000000000000000000000000000E4
+:104CD00000000000000000000000000000000000D4
+:104CE00000000000000000000000000000000000C4
+:104CF00000000000000000000000000000000000B4
+:104D000000000000000000000000000000000000A3
+:104D10000000000000000000000000000000000093
+:104D20000000000000000000000000000000000083
+:104D30000000000000000000000000000000000073
+:104D40000000000000000000000000000000000063
+:104D50000000000000000000000000000000000053
+:104D60000000000000000000000000000000000043
+:104D70000000000000000000000000000000000033
+:104D80000000000000000000000000000000000023
+:104D90000000000000000000000000000000000013
+:104DA0000000000000000000000000000000000003
+:104DB00000000000000000000000000000000000F3
+:104DC00000000000000000000000000000000000E3
+:104DD00000000000000000000000000000000000D3
+:104DE00000000000000000000000000000000000C3
+:104DF00000000000000000000000000000000000B3
+:104E000000000000000000000000000000000000A2
+:104E10000000000000000000000000000000000092
+:104E20000000000000000000000000000000000082
+:104E30000000000000000000000000000000000072
+:104E40000000000000000000000000000000000062
+:104E50000000000000000000000000000000000052
+:104E60000000000000000000000000000000000042
+:104E70000000000000000000000000000000000032
+:104E80000000000000000000000000000000000022
+:104E90000000000000000000000000000000000012
+:104EA0000000000000000000000000000000000002
+:104EB00000000000000000000000000000000000F2
+:104EC00000000000000000000000000000000000E2
+:104ED00000000000000000000000000000000000D2
+:104EE00000000000000000000000000000000000C2
+:104EF00000000000000000000000000000000000B2
+:104F000000000000000000000000000000000000A1
+:104F10000000000000000000000000000000000091
+:104F20000000000000000000000000000000000081
+:104F30000000000000000000000000000000000071
+:104F40000000000000000000000000000000000061
+:104F50000000000000000000000000000000000051
+:104F60000000000000000000000000000000000041
+:104F70000000000000000000000000000000000031
+:104F80000000000000000000000000000000000021
+:104F90000000000000000000000000000000000011
+:104FA0000000000000000000000000000000000001
+:104FB00000000000000000000000000000000000F1
+:104FC00000000000000000000000000000000000E1
+:104FD00000000000000000000000000000000000D1
+:104FE00000000000000000000000000000000000C1
+:104FF00000000000000000000000000000000000B1
+:1050000000000000000000000000000000000000A0
+:105010000000000000000000000000000000000090
+:105020000000000000000000000000000000000080
+:105030000000000000000000000000000000000070
+:105040000000000000000000000000000000000060
+:105050000000000000000000000000000000000050
+:105060000000000000000000000000000000000040
+:105070000000000000000000000000000000000030
+:105080000000000000000000000000000000000020
+:105090000000000000000000000000000000000010
+:1050A0000000000000000000000000000000000000
+:1050B00000000000000000000000000000000000F0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:10517000000000000000000000000000000000002F
+:10518000000000000000000000000000000000001F
+:10519000000000000000000000000000000000000F
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000000000000000000DF
+:1051D00000000000000000000000000000000000CF
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:10522000000000000000000000000000000000007E
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000000000005E
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000000000000000000002E
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000000000000000000000000000FE
+:1052B0000142050A05BA02500000000001C301685E
+:1052C000044105BA00000000022502090250015104
+:1052D000000000000223024502A00241000000007D
+:1052E00003D705BA05BA05BA0000000005E205E3D8
+:1052F000031F05BA00000000032005BF0320034A76
+:105300000000000003340282034C033E0000000052
+:1053100005BA05BA05BA05BA0000000005BA055776
+:1053200005BA032A0000000003BC05BA04C3034EFB
+:105330000000000004A20455043F05BA000000006C
+:1053400004D805BA044304E5000000000455050F25
+:10535000035B037B0000000005BA05BA05BA05BA75
+:105360000000000005BA05BA05BA05BA0000000041
+:1053700005BA05BA05D805C10000000005BA05BA8E
+:10538000000705BA0000000005BA05BA05BA05BA5B
+:105390000000000005BA05BA05BA05BA0000000011
+:1053A00003F803ED0408040600000000040E040ADC
+:1053B000040C041000000000041C04180424042041
+:1053C00000000000042C0428043404300000000015
+:1053D00005BA05BA043A04380000000005BA05BA57
+:1053E00005BA05BA0000000005BA05BA05BA05BA43
+:1053F000000000000002060E062C0006000000005F
+:00000001FF
diff --git a/firmware/radeon/RS780_pfp.bin.ihex b/firmware/radeon/RS780_pfp.bin.ihex
new file mode 100644
index 0000000..4088041
--- /dev/null
+++ b/firmware/radeon/RS780_pfp.bin.ihex
@@ -0,0 +1,145 @@
+:1000000000CA040000A00000007E828B007C038BED
+:10001000008001DB007C038B00D4401E00EE001E3C
+:1000200000CA040000A00000007E828B00C41838C3
+:1000300000CA240000CA2800009581CB00C41C3AE5
+:1000400000C3C00000CA080000CA0C00007C744B4A
+:1000500000C200050099C00000C41C3A007C744C2A
+:1000600000C0FFE000042C0800309002007D250055
+:1000700000351402007D350B00255407007CD58027
+:1000800000259C070095C00400D5001B007EDDC143
+:10009000007D9D8000D6801B00D5801B00D4401EB3
+:1000A00000D5401E00D6401E00D6801E00D4801E03
+:1000B00000D4C01E009783D300D5C01E00CA08001C
+:1000C0000080001A00CA0C0000E4011E00D4001ECB
+:1000D0000080000C00C4183800E4013E00D4001E6B
+:1000E0000080000C00C4183800D4401E00EE001E32
+:1000F00000CA040000A00000007E828B00E4011E04
+:1001000000D4001E00D4401E00EE001E00CA0400F1
+:1001100000A00000007E828B00E4013E00D4001E9F
+:1001200000D4401E00EE001E00CA040000A0000023
+:10013000007E828B00CA080000CA0C00008001DB30
+:1001400000D4802400CA0800007C00C000C8142528
+:1001500000C81824007C9488007C988000C20003AA
+:1001600000D40075007C744C0080006400D4401EF4
+:1001700000CA180000D4401E00D5801E0080006216
+:1001800000D4007500D4401E00CA080000CA0C004C
+:1001900000CA100000D4801900D4C01800D5001780
+:1001A00000D4801E00D4C01E00D5001E00E2001E38
+:1001B00000CA040000A00000007E828B00D40075FD
+:1001C00000D4401E00CA080000CA0C0000CA10007B
+:1001D00000D4801900D4C01800D5001700D4801EA8
+:1001E00000D4C01E00D5001E00EE001E00CA040090
+:1001F00000A00000007E828B00CA080000248C0151
+:1002000000D480600094C0030004100100041002B8
+:1002100000D5002500D4401E0080000000D4801EC0
+:1002200000CA080000D4806100D4401E0080000095
+:1002300000D4801E00CA080000CA0C0000D4401E72
+:1002400000D4801600D4C01600D4801E008001DBCC
+:1002500000D4C01E00C6084300CA0C0000CA10002B
+:100260000094800400CA140000E420F300D420139A
+:1002700000D5606500D4E01C00D5201C00D5601CB2
+:10028000008000000006200100C6084300CA0C00E0
+:1002900000CA1000009483F700CA140000E420F3A1
+:1002A0000080009C00D4201300C6084300CA0C0044
+:1002B00000CA1000009883EF00CA140000D4006444
+:1002C000008000B00000000000C4143200C61843D3
+:1002D00000C4082F0095400500C40C3000D4401E17
+:1002E0000080000000EE001E009583F500C4103170
+:1002F00000D4403300D5206500D4A01C00D4E01CFD
+:1003000000D5201C00E4015E00D4001E0080000027
+:100310000006200100CA1800000A200100D600765D
+:1003200000C408360098800700C6104500950110EB
+:1003300000D4001F00D460620080000000D420625E
+:1003400000CC383500CC1433008401DE00D40072B8
+:1003500000D5401E0080000000EE001E00E2001AE2
+:10036000008401DE00E2001A00CC104B00CC0447F0
+:10037000002C9401007D098B00984005007D15CB71
+:1003800000D4001A008001DB00D4006D0034440169
+:1003900000CC0C480098403A00CC2C4A00958004D0
+:1003A00000CC0449008001DB00D4001A00D4C01A3C
+:1003B000002828010084011300CC10030098801B42
+:1003C0000004380C0084011300CC1003009880173F
+:1003D000000438080084011300CC10030098801337
+:1003E000000438040084011300CC1003009880142A
+:1003F00000CC104C009A800900CC144D009840DCD1
+:1004000000D4006D00CC184800D5001A00D5401A61
+:10041000008000EC00D5801A0096C0D500D4006D95
+:10042000008001DB00D4006E009AC00300D4006D90
+:1004300000D4006E0080000000EC007F009AC0CC69
+:1004400000D4006D008001DB00D4006E00CC1403EA
+:1004500000CC180300CC1C03007D9103007DD583E4
+:10046000007D190C0035CC1F0035701F007CF0CBCF
+:10047000007CD08B00880000007E8E8B0095C0042D
+:1004800000D4006E008001DB00D4001A00D4C01A32
+:1004900000CC080300CC0C0300CC100300CC1403E8
+:1004A00000CC180300CC1C0300CC240300CC280390
+:1004B0000035C41F0036B01F007C704B0034F01FA5
+:1004C000007C704B0035701F007C704B007D888174
+:1004D000007DCCC1007E5101007E9541007C908260
+:1004E000007CD4C2007C848B009AC003007C8C8B7F
+:1004F000002C88010098809E00D4006D0098409CDC
+:1005000000D4006E00CC084C00CC0C4D00CC104840
+:1005100000D4801A00D4C01A0080012400D5001A2B
+:1005200000CC083200D40032009482B600CA0C001D
+:1005300000D4401E0080000000D4001E00E4011E14
+:1005400000D4001E00CA080000CA0C0000CA100037
+:1005500000D4401E00CA140000D4801E00D4C01E67
+:1005600000D5001E00D5401E00D54034008000009C
+:1005700000EE001E0028040400E2001A00E2001A47
+:1005800000D4401A00CA380000CC080300CC0C0389
+:1005900000CC0C0300CC0C030098829A00000000F1
+:1005A000008401DE00D7A06F0080000000EE001F75
+:1005B00000CA040000C2FF0000CC083400C13FFFA5
+:1005C000007C74CB007CC90B007D010F0099028D6B
+:1005D000007C738B008401DE00D7A06F00800000D8
+:1005E00000EE001F00CA080000281900007D898B5A
+:1005F000009580140028140400CA0C0000CA1000E2
+:1006000000CA1C0000CA240000E2001F00D4C01A67
+:1006100000D5001A00D5401A00CC180300CC2C03DA
+:1006200000CC2C0300CC2C03007DA58B007D9C47C7
+:1006300000984274000000000080018400D4C01AB9
+:1006400000D4401E00D4801E0080000000EE001E7A
+:1006500000E4011E00D4001E00D4401E00EE001E67
+:1006600000CA040000A00000007E828B00E4013E6E
+:1006700000D4001E00D4401E00EE001E00CA04007C
+:1006800000A00000007E828B00CA080000248C06B7
+:10069000000CCC060098C00600CC104E0099000457
+:1006A00000D4007300E4011E00D4001E00D4401EDC
+:1006B00000D4801E0080000000EE001E00CA08006A
+:1006C00000CA0C000034D01800251001009500214C
+:1006D00000C17FFF00CA100000CA140000CA180041
+:1006E00000D4801D00D4C01D007DB18B00C142022A
+:1006F00000C2C00100D5801D0034DC0E007D5D4CC1
+:10070000007F734C00D7401E00D5001E00D5401E50
+:1007100000C1420000C2C00000099C010031DC1091
+:10072000007F5F4C007F734C00042802007D8380B3
+:1007300000D5A86F00D5806600D7401E00EC005E93
+:1007400000C8240200C82402008001DB00D6007625
+:1007500000D4401E00D4801E00D4C01E00800000C3
+:1007600000EE001E0080000000EE001F00D4001FFD
+:100770000080000000D4001F00D4001F008800008B
+:1007800000D4001F00000000000000000000000076
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:10080000000101940002019B000300B2000400A259
+:10081000000500030006003F000700320008014FFA
+:1008200000090046000A0036001001D9001700C573
+:100830000022015D0023016C002000D70024014844
+:100840000026004D0027005C0028008D0029005183
+:10085000002A007E002B0061002F0088003200AAD1
+:10086000003401A20036006F003C0179003F009582
+:10087000004101AF00440151005501960056019D11
+:100880000060000B00610034006200380063003833
+:1008900000640038006500380066003800670038E2
+:1008A0000068003A00690041006A0048006B004897
+:1008B000006C0048006D0048006E0048006F004862
+:1008C000007301D9000000060000000600000006C9
+:1008D0000000000600000006000000060000000600
+:1008E00000000006000000060000000600000006F0
+:1008F00000000006000000060000000600000006E0
+:00000001FF
diff --git a/firmware/radeon/RV610_me.bin.ihex b/firmware/radeon/RV610_me.bin.ihex
new file mode 100644
index 0000000..ba19ed8
--- /dev/null
+++ b/firmware/radeon/RV610_me.bin.ihex
@@ -0,0 +1,1345 @@
+:1000000000000000C020040000000000000000000C
+:1000100000A0000A000000000000FFFF00284621A9
+:100020000000000000000000D900480000000000AF
+:1000300000000000C02004000000000000000000DC
+:1000400000A0000A000000000000000000E0000026
+:100050000000000000010000C02946200000000050
+:1000600000000000D900480000000000000000006F
+:10007000C0200400000000000000000000A0000AF2
+:10008000000000008100000000204411000000007A
+:1000900000000001002048110000000000042004BE
+:1000A000006044110000068D0000000000600000A8
+:1000B000000006310000000000600000000006455E
+:1000C00000000000C02008000000000000000F0039
+:1000D000002816220000000000000008002116255C
+:1000E000000000000000001800203625000000007D
+:1000F0008D000000002044110000000000000004FA
+:10010000002F022500000000000000000CE00000AD
+:1001100000000018004120000040481100000019B4
+:100120000042200000204811000000008E00000066
+:1001300000204411000000000000002800204A2D8B
+:1001400000000000900000000020441100000000AA
+:100150000000000000204805000000000000000C26
+:1001600000211622000000000000000300281625D0
+:10017000000000000000001900211A220000000009
+:100180000000000400281A26000000000000000003
+:10019000002914C5000000000000001900203625C9
+:1001A0000000000000000000003A140200000000FF
+:1001B00000000016002116250000000000000003CA
+:1001C00000281625000000000000001700200E2D5A
+:1001D00000000000FFFFFFFC00280E2300000000CD
+:1001E00000000000002914A3000000000000001718
+:1001F00000203625000000000000800000280E22AC
+:10020000000000000000000700220E230000000094
+:10021000000000000029386E0000000020000000EF
+:1002200000280E22000000000000000600210E231E
+:1002300000000000000000000029386E00000000EF
+:100240000000000000220222000000000000000068
+:1002500014E0000000000038000000002EE0000064
+:1002600000000035000000002CE000000000003716
+:100270000000000000400E2D0000003900000008C2
+:1002800000200E2D00000000000000090040122D8B
+:10029000000000460000000100400E2D0000003963
+:1002A00000000000C0200C0000000000003FFFFC28
+:1002B0000028122300000000000000020022122487
+:1002C000000000000000001F00211E2300000000AD
+:1002D0000000000014E000000000003E00000008E4
+:1002E00000401C11000000410000000D00201E2DE8
+:1002F000000000000000000F00281E270000000082
+:100300000000000300221E27000000007FC0000044
+:1003100000281A23000000000000001400211A2603
+:10032000000000000000000100331A260000000059
+:100330000000000800221A26000000000000000053
+:1003400000290CC700000000000000270020362410
+:100350000000000000007F000028122100000000C3
+:1003600000001400002F0224000000000000000024
+:100370000CE000000000004B0000000100290E23EB
+:10038000000000000000000E0020362300000000E6
+:100390000000E0000020441100000000FFF8000011
+:1003A00000294A230000000000000000003A2C024F
+:1003B000000000000000000200220E2B00000000E0
+:1003C000FC00000000280E23000000000000000FC9
+:1003D000002036230000000000001FFF00294A23F0
+:1003E000000000000000002700204A2D000000004F
+:1003F000000000000020481100000000000000295B
+:1004000000200E2D00000000060A020000294A23E9
+:100410000000000000000000002048110000000063
+:100420000000000000204811000000000000000152
+:1004300000210222000000000000000014E0000083
+:1004400000000061000000002EE000000000005FDE
+:10045000000000002CE000000000005E0000000032
+:1004600000400E2D000000620000000100400E2D33
+:10047000000000620000000A00200E2D00000000B5
+:100480000000000B0040122D0000006A0000000078
+:10049000C0200C0000000000003FFFFC00281223D9
+:1004A00000000000000000020022122400000000F2
+:1004B0007FC0000000281623000000000000001488
+:1004C0000021162500000000000000010033162561
+:1004D000000000008000000000280E230000000043
+:1004E0000000000000290CA3000000003FFFFC00FA
+:1004F00000290E23000000000000001F00211E2321
+:10050000000000000000000014E000000000006D8A
+:100510000000010000401C11000000700000000DF0
+:1005200000201E2D00000000000000F000281E2703
+:10053000000000000000000400221E270000000050
+:100540008100000000204411000000000000000DA8
+:100550000020481100000000FFFFF0FF00281A30C3
+:10056000000000000000A02800204411000000004E
+:1005700000000000002948E6000000000000A0186C
+:1005800000204411000000003FFFFFFF00284A2325
+:10059000000000000000A010002044110000000036
+:1005A00000000000002048040000000000000030AF
+:1005B0000020162D00000000000000020029162572
+:1005C0000000000000000030002036250000000080
+:1005D000000000250020162D000000000000000093
+:1005E000002F00A300000000000000000CC000006D
+:1005F00000000083000000260020162D00000000EF
+:1006000000000000002F00A4000000000000000017
+:100610000CC000000000008400000000004000004A
+:100620000000008A000000250020362300000000A2
+:100630000000002600203624000000000000001703
+:1006400000201E2D000000000000000200210227F3
+:10065000000000000000000014E000000000008A1C
+:1006600000000000006000000000066800000000BC
+:10067000006000000000065C0000000200210E2265
+:10068000000000000000000014C000000000008D09
+:1006900000000012C040362000000093000000005F
+:1006A0002EE0000000000091000000002CE000009F
+:1006B000000000900000000200400E2D000000929B
+:1006C0000000000300400E2D000000920000000C0E
+:1006D00000200E2D00000000000000120020362334
+:1006E000000000000000000300210E2200000000B6
+:1006F0000000000014C00000000000980000A00CE2
+:10070000002044110000000000000000C02048004C
+:100710000000000000000000C0404800000000A0F1
+:100720000000A00C002044110000000000000000A8
+:100730000020481100000000000000002EE0000032
+:100740000000009E000000002CE000000000009D62
+:100750000000000200400E2D0000009F000000037A
+:1007600000400E2D0000009F0000000C00200E2D08
+:10077000000000000000000000204803000000000E
+:1007800000000000003A0C0200000000003F0000E2
+:1007900000280E23000000000000001000210E239E
+:1007A00000000000000000110020362300000000BF
+:1007B0000000001E0021022B0000000000000000CD
+:1007C00014C00000000000A700000016C020362062
+:1007D000000000000000001F0021022B00000000AC
+:1007E0000000000014C00000000000AA0000001576
+:1007F000C0203620000000000000000800210E2B61
+:10080000000000000000007F00280E230000000010
+:1008100000000000002F0223000000000000000084
+:100820000CE00000000000E10000000027000000D4
+:10083000000000000000000000600000000002A3B3
+:1008400000000001002F0223000000000000000053
+:100850000AE00000000000B300000000006000009B
+:100860000000013A81000000002044110000000057
+:100870000000000600204811000000000000000CED
+:1008800000221E300000000099800000002044116A
+:1008900000000000000000040020122D00000000F5
+:1008A00000000008002212240000000000000010D8
+:1008B00000201811000000000000000000291CE4C6
+:1008C0000000000000000000006048070000012F49
+:1008D0009B00000000204411000000000000000008
+:1008E00000204802000000009C000000002044118D
+:1008F00000000000000000000033146F0000000042
+:100900000000000100333E23000000000000000052
+:10091000D9004800000000000000000000203C0555
+:1009200000000000810000000020441100000000D1
+:100930000000000E00204811000000000000000030
+:1009400000201010000000000000E007002044110B
+:10095000000000000000000F0021022B000000003A
+:100960000000000014C00000000000CB00F8FF08E9
+:1009700000204811000000009800000000404811CD
+:10098000000000DC000000F000280E220000000043
+:10099000000000A0002F0223000000000000000063
+:1009A0000CC00000000000DA0000001100200E2D35
+:1009B0000000000000000001002F022300000000E2
+:1009C000000000000CE00000000000D50000000264
+:1009D000002F022300000000000000000CE00000D7
+:1009E000000000D400003F0000400C11000000D6C1
+:1009F00000001F0000400C11000000D600000F0096
+:100A000000200C11000000000038000900294A23D2
+:100A1000000000003F00000000280E2B0000000036
+:100A20000000000200220E2300000000000000076A
+:100A300000494A23000000DC00380F09002048115B
+:100A400000000000680000070020481100000000BE
+:100A50000000000800214A270000000000000000FC
+:100A60000020481100000000060A020000294A2464
+:100A700000000000000000000020481100000000FD
+:100A80000000000000204811000000000000A20249
+:100A9000002044110000000000FF000000280E228A
+:100AA000000000000000008000294A230000000030
+:100AB0000000002700200E2D00000000000000268E
+:100AC0000020122D0000000000000000002F008315
+:100AD00000000000000000000CE00000000000EA40
+:100AE000000000000060000000000662000000003E
+:100AF00000400000000000EB00000000006000006B
+:100B000000000665000000070020222D0000000004
+:100B10000000000500220E2200000000001000006E
+:100B200000280E23000000000000000000292068BB
+:100B30000000000000000000003A0C02000000006D
+:100B4000000000EF00280E2300000000000000005D
+:100B500000292068000000000000001700200E2D72
+:100B6000000000000000000300210223000000003C
+:100B70000000000014E00000000000F80000000B7E
+:100B800000210228000000000000000014C0000046
+:100B9000000000F8000004000029222800000000E6
+:100BA0000000001400203628000000000000001C97
+:100BB00000210E22000000000000000014C0000010
+:100BC000000000FD0000A30C002044110000000004
+:100BD0000000000000204811000000000000001E7E
+:100BE00000210E22000000000000000014C00000E0
+:100BF0000000010B0000A30F0020441100000000C2
+:100C00000000001100200E2D000000000000000177
+:100C1000002F022300000000000000000CC00000B4
+:100C200000000104FFFFFFFF004048110000010B1E
+:100C300000000002002F022300000000000000005E
+:100C40000CC00000000001070000FFFF0040481139
+:100C50000000010B00000004002F02230000000030
+:100C6000000000000CC000000000010A000000FFAE
+:100C7000004048110000010B000000010020481155
+:100C8000000000000002C400002044110000000029
+:100C90000000001F00210E220000000000000000E4
+:100CA00014C00000000001120000001040210E20BE
+:100CB00000000000000000130020362300000000A8
+:100CC0000000001840224A20000000000000001030
+:100CD000C0424A20000001140000000000200C1156
+:100CE0000000000000000013002036230000000078
+:100CF000000000000020481100000000000000007B
+:100D000000204811000000000000000A002010111F
+:100D10000000000000000000002F0224000000007E
+:100D2000000000000CE000000000011B00000000BB
+:100D300000204811000000000000000100531224B0
+:100D400000000117FFBFFFFF00283A2E000000003F
+:100D50000000001B00210222000000000000000033
+:100D600014C000000000012E81000000002044118A
+:100D7000000000000000000D0020481100000000ED
+:100D80000000001800220E3000000000FC000000EF
+:100D900000280E2300000000810000000020441104
+:100DA000000000000000000E0020481100000000BC
+:100DB0000000000000201010000000000000E00E05
+:100DC000002044110000000007F8FF08002048112F
+:100DD000000000000000000000294A23000000007D
+:100DE0000000001C00201E2D000000000000000874
+:100DF00000214A27000000000000000000204811E8
+:100E000000000000060A020000294A240000000039
+:100E10000000000000204811000000000000000059
+:100E200000204811000000000000000000800000C9
+:100E300000000000810000000020441100000000BC
+:100E40000000000100204811000000000000217C8B
+:100E50000020441100000000008000000020481124
+:100E60000000000000000000002048060000000014
+:100E70000000000800214A270000000000000000D8
+:100E800017000000000000000004217F00604411F2
+:100E90000000068D0000001F00210230000000004D
+:100EA0000000000014C000000000068C00000004D8
+:100EB00000404C1100000135810000000020441169
+:100EC00000000000000000010020481100000000A8
+:100ED000000021F800204411000000000000001C68
+:100EE0000020481100000000000421F900604411B6
+:100EF0000000068D000000110021023000000000FB
+:100F00000000000014E000000000013C00000000B0
+:100F100000800000000000000000000000600000F1
+:100F20000000000B00000000006004110000031529
+:100F3000000000000020041100000000000000007C
+:100F400000600811000001B2000000000060000015
+:100F5000000001600000FFFF40280E20000000009C
+:100F600000000010C0211220000000000000FFFF60
+:100F7000402806200000000000000010C0210A20C8
+:100F800000000000000000000034146100000000B8
+:100F90000000000000741882000002BB0001A1FDE7
+:100FA00000604411000002E000003FFF002F022F0C
+:100FB00000000000000000000CC00000000001471D
+:100FC00000000000C040040000000001000000001C
+:100FD000006000000000000B000000000060041131
+:100FE00000000315000000000020041100000000B4
+:100FF0000000000000600811000001B200003FFF87
+:10100000002F022F00000000000000000CE0000094
+:10101000000000000000000000600000000001600F
+:101020000000001040210E20000000000000FFFF23
+:10103000C0281220000000000000001040211620EF
+:10104000000000000000FFFFC0681A20000002BB83
+:101050000001A1FD00604411000002E000003FFF1C
+:10106000002F022F00000000000000000CC0000054
+:101070000000015800000000C04004000000000112
+:101080000000225C0020441100000000000000016C
+:1010900000300A2F000000000000000100210A2299
+:1010A000000000000000000300384A220000000099
+:1010B0000000225600204411000000000000001A29
+:1010C00000204811000000000000A1FC0020441195
+:1010D0000000000000000001008048110000000036
+:1010E00000000000006000000000000B0000000095
+:1010F000006000000000018F0000000000600000A0
+:10110000000001A000003FFF002F022F00000000A0
+:10111000000000000CE000000000000000000000E3
+:1011200000202C0800000000000000000020241116
+:101130000000000000000000002028110000000056
+:10114000000022560020441100000000000000169C
+:1011500000204811000000000000225C0020441123
+:101160000000000000000003002048110000000003
+:1011700093800000002044110000000000000002E5
+:1011800000221E290000000000000000007048EB53
+:101190000000019C0000000000600000000002BB95
+:1011A00000000001403306200000000000000000A5
+:1011B000C03024090000000000003FFF002F022F74
+:1011C00000000000000000000CE000000000000033
+:1011D0000000000000600000000002A3000000000A
+:1011E000002F022100000000000000000AE00000C3
+:1011F0000000018100000000006000000000013AD2
+:101200000000000000400000000001869500000082
+:10121000002044110000000000000000002F022107
+:1012200000000000000000000CE00000000001864B
+:1012300000000000C0204800000000000000000185
+:10124000005306210000018292000000002044119A
+:101250000000000000000000C0604800000001978E
+:101260000001A1FD00204411000000000000001159
+:101270000020062D00000000000000000078042A75
+:10128000000002FB00000000002028090000000010
+:1012900000003FFF002F022F0000000000000000B0
+:1012A0000CC000000000017400000000C0400400F9
+:1012B000000000010000021000600411000003158E
+:1012C00000003FFF002F022F000000000000000080
+:1012D0000CE000000000019400000015C020362042
+:1012E0000000000000000016C020362000000000B2
+:1012F0003F800000002004110000000046000000B4
+:1013000000600811000001B2000000000080000031
+:10131000000000000000A1FC0020441100000000BB
+:1013200000003FFF002F022F00000000000000001F
+:101330000CC000000000019B00000001008048116B
+:1013400000000000000000210080481100000000A3
+:101350000000FFFF40280E200000000000000010E9
+:10136000C0211220000000000000FFFF40281620CE
+:101370000000000000000010C0811A2000000000E2
+:101380008100000000204411000000000000000661
+:1013900000204811000000000000000800221E305C
+:1013A000000000000000002900201A2D00000000AD
+:1013B0000000E0000020441100000000FFFBFF09D6
+:1013C00000204811000000000000000F0020222D26
+:1013D0000000000000001FFF00294A280000000054
+:1013E000000000060020222D000000000000000088
+:1013F000002920E80000000000000000002048084C
+:101400000000000000000000002048110000000063
+:10141000060A020000294A26000000000000000021
+:1014200000204811000000000000000000204811CA
+:101430000000000000000100002018110000000062
+:101440000000000800621E280000012F00000008B4
+:1014500000822228000000000002C0000020441189
+:10146000000000000000001500600E2D000001BD0E
+:101470000000001600600E2D000001BD0000C00835
+:1014800000204411000000000000001700200E2D75
+:10149000000000000000000014C00000000001B9BE
+:1014A0000000000000200411000000000000000007
+:1014B0000020480100000000390000000020481111
+:1014C00000000000000000000020481100000000A3
+:1014D000000000000080480200000000000000182A
+:1014E00000202E2D0000000000000000003B0D63D6
+:1014F000000000000000000800224A230000000055
+:101500000000001000224A23000000000000001824
+:1015100000224A2300000000000000000080480371
+:101520000000000000000000006000000000000B50
+:10153000000010000060041100000315000000000E
+:1015400000200411000000000000000000600811ED
+:10155000000001B2000000070021062F000000007B
+:101560000000001300200A2D000000000000000110
+:1015700000202C11000000000000FFFF4028222066
+:10158000000000000000000F0026222800000000DC
+:101590000000001040212620000000000000000F85
+:1015A000002626290000000000000000002028027C
+:1015B000000000000000225600204411000000003E
+:1015C0000000001B00204811000000000000000087
+:1015D000002F022100000000000000000CE00000CD
+:1015E000000001E00000225C002044110000000027
+:1015F0000000008100204811000000000000A1FC54
+:1016000000204411000000000000000100204811EB
+:10161000000000000000008000201C1100000000FD
+:1016200000000000002F0227000000000000000062
+:101630000CE00000000001DC000000000060000081
+:10164000000001E90000000100531E27000001D83E
+:101650000000000100202C11000000000000001F0D
+:1016600000280A22000000000000001F00282A2A8B
+:10167000000000000000000100530621000001D11D
+:101680000000225C00204411000000000000000265
+:1016900000304A2F000000000000A1FC002044118F
+:1016A00000000000000000010020481100000000C0
+:1016B0000000000100301E2F0000000000000000AC
+:1016C000002F022700000000000000000CE00000D6
+:1016D000000000000000000000600000000001E9C0
+:1016E0000000000100531E27000001E50000FFFF7D
+:1016F00040280E20000000000000000F00260E23EE
+:101700000000000000000010C021122000000000B6
+:101710000000000F0026122400000000000000005E
+:1017200000201411000000000000000000601811EB
+:10173000000002BB0001A1FD0020441100000000D8
+:1017400000000000002F022B00000000000000003D
+:101750000CE00000000001F8000000100022162834
+:1017600000000000FFFF0000002816250000000018
+:101770000000FFFF00281A29000000000000000000
+:10178000002948C500000000000000000020480AB1
+:10179000000000000000000000202C1100000000EC
+:1017A000000000100022162300000000FFFF0000D0
+:1017B00000281625000000000000FFFF00281A2462
+:1017C0000000000000000000002948C500000000E3
+:1017D0000000000000731503000002050000000077
+:1017E0000020180500000000000000000073152410
+:1017F0000000020500000000002D14C500000000DC
+:1018000000000000003008A20000000000000000FE
+:101810000020480200000000000000000020280214
+:101820000000000000000000002020030000000075
+:101830000000000000802404000000000000000FF1
+:1018400000210225000000000000000014C000007C
+:101850000000068C00000000002B140500000000B2
+:1018600000000001009016250000000000000000AC
+:10187000006000000000000B000000000060041188
+:10188000000003150000000000200411000000000B
+:101890000000000000600811000001B200002256A4
+:1018A00000204411000000000000001A00294A2214
+:1018B0000000000000000000C02000000000000048
+:1018C00000003FFF002F022F00000000000000007A
+:1018D0000CE000000000000000000000C020040038
+:1018E000000000000000225C002044110000000005
+:1018F0000000000300384A21000000000000A1FCA5
+:1019000000204411000000000000000100204811E8
+:10191000000000000000FFFF40281220000000002F
+:1019200000000010C0211A20000000000000FFFF8E
+:1019300040280E200000000000000010C0211620EA
+:10194000000000000000000000741465000002BBED
+:101950000001A1FD00604411000002E00000000150
+:10196000003306210000000000000000002F0221CB
+:1019700000000000000000000CC000000000021980
+:1019800000003FFF002F022F0000000000000000B9
+:101990000CC000000000021200000000C040040063
+:1019A000000000010000000000600000000006458B
+:1019B000000000000040040F0000021300000000BF
+:1019C0000060000000000631000000000060000020
+:1019D000000006450000021000600411000003151D
+:1019E0000000000000600000000001A000000000F6
+:1019F000006000000000019C00000000006000008A
+:101A0000000002BB0000000000600000000002A314
+:101A1000938000000020441100000000000000003E
+:101A2000002048080000000000000000002F022FE6
+:101A300000000000000000000AE000000000023288
+:101A400000000000006000000000013A00000000FB
+:101A50000040000000000236950000000020441104
+:101A60000000000000000000002F022F0000000016
+:101A7000000000000CE00000000002360000000042
+:101A8000C0404800000002339200000000204411D2
+:101A90000000000000000000C0204800000000001E
+:101AA0000000225600204411000000000000001633
+:101AB00000204811000000000000225C00204411BA
+:101AC000000000000000000300204811000000009A
+:101AD0000000A1FC002044110000000000000001F3
+:101AE00000204811000000000001A1FD0020441169
+:101AF000000000000000000000600411000002FB74
+:101B000000000000C04004000000000100000000D0
+:101B100000600000000006310000A00C002044110D
+:101B20000000000000000000C0204800000000008D
+:101B300000000000C040480000000000000000005D
+:101B4000006000000000000B0000001840210A2087
+:101B50000000000000000003002F0222000000002F
+:101B6000000000000AE000000000024C0000001429
+:101B70000020222D00000000000801010029222879
+:101B800000000000000000140020362800000000C3
+:101B90000000A30C00204411000000000000000021
+:101BA000C02048000000000000000000C0204800E5
+:101BB0000000000000000000C0404800000002518A
+:101BC00000000000006000000000000B000000109A
+:101BD00000600411000003153F8000000020041184
+:101BE000000000000000000000600811000001B2C9
+:101BF0000000225C002044110000000000000003EF
+:101C000000204811000000000000000000600000FB
+:101C10000000027C0000001700201E2D00000000C4
+:101C20000000000100211E2700000000000000004D
+:101C300014E000000000026A0000001200201E2DC7
+:101C4000000000000000FFFF00281E270000000029
+:101C50000000000000341C2700000000000000000D
+:101C600012C000000000025F0000000000201C11F4
+:101C70000000000000000000002F00E50000000050
+:101C80000000000008C00000000002620000000028
+:101C900000201407000000000000001200201E2D8C
+:101CA000000000000000001000211E2700000000BE
+:101CB0000000000000341C4700000000000000008D
+:101CC00012C00000000002670000000000201C118C
+:101CD0000000000000000000002F00E600000000EF
+:101CE0000000000008C000000000026A00000000C0
+:101CF0000020180700000000000000000060000045
+:101D0000000002C100002256002044110000000023
+:101D1000000000000034202300000000000000004C
+:101D200012C00000000002720000000000342044D5
+:101D3000000000000000000012C00000000002715E
+:101D40000000001600404811000002760000001854
+:101D500000404811000002760000000000342044DA
+:101D6000000000000000000012C00000000002752A
+:101D70000000001700404811000002760000001922
+:101D800000204811000000000000A1FC00204411C8
+:101D900000000000000000010020481100000000C9
+:101DA0000001A1FD00604411000002E900003FFFB6
+:101DB000002F022F00000000000000000CC00000F7
+:101DC0000000025600000000C040040000000001B6
+:101DD0000000001040210620000000000000FFFF6E
+:101DE000C0280A20000000000000001040210E2042
+:101DF000000000000000FFFFC028122000000000CB
+:101E00000000001040211620000000000000FFFF2D
+:101E1000C0881A200000000081000000002044114A
+:101E20000000000000000001002048110000000038
+:101E300000042004006044110000068D0000000032
+:101E4000006000000000063100000000C0600000DB
+:101E5000000002A30000000500200A2D0000000081
+:101E60000000000800220A22000000000000002BF1
+:101E700000201A2D000000000000001C00201E2D74
+:101E8000000000000000700000281E270000000075
+:101E90000000000000311CE6000000000000002AE5
+:101EA00000201A2D000000000000000C00221A265D
+:101EB0000000000000000000002F00E6000000000D
+:101EC0000000000006E00000000002920000000098
+:101ED00000201C11000000000000000000200C1178
+:101EE000000000000000002B00203623000000004E
+:101EF0000000001000201811000000000000000089
+:101F000000691CE20000012F9380000000204411B2
+:101F10000000000000000000002048070000000052
+:101F200095000000002044110000000000000000A7
+:101F3000002F022F00000000000000000CE0000055
+:101F40000000029D0000000100333E2F0000000051
+:101F500000000000D90048000000000092000000CE
+:101F6000002044110000000000000000C0204800D4
+:101F7000000000000000001C0040362700000000A8
+:101F80000000000CC0220A20000000000000002910
+:101F9000002036220000000000000028C04036204B
+:101FA000000000000000A2A4002044110000000076
+:101FB000000000090020481100000000A1000000FE
+:101FC00000204411000000000000000100804811C2
+:101FD000000000000000002100201E2D0000000075
+:101FE00000000000002C1CE30000000000000021A5
+:101FF00000203627000000000000002200201E2DD7
+:102000000000000000000000002C1CE400000000A4
+:1020100000000022002036270000000000000023FE
+:1020200000201E2D0000000000000000003120A351
+:102030000000000000000000002D1D07000000004F
+:1020400000000023002036270000000000000024CC
+:1020500000201E2D0000000000000000003120C400
+:102060000000000000000000002D1D07000000001F
+:10207000000000240080362700000000000000213E
+:10208000002036230000000000000022002036243B
+:10209000000000000000000000311CA30000000050
+:1020A0000000002300203627000000000000000090
+:1020B00000311CC40000000000000024008036270E
+:1020C000000000000000001A002036270000000079
+:1020D0000000001B00203628000000000000001750
+:1020E00000201E2D00000000000000020021022739
+:1020F000000000000000000014C00000000002DC2E
+:102100000000000000400000000002D90000001A9A
+:1021100000203627000000000000001B00203628A9
+:10212000000000000000001700201E2D000000002D
+:102130000000000200210227000000000000000053
+:1021400014E00000000002D9000000030021022773
+:10215000000000000000000014E00000000002DCAD
+:102160000000002300201E2D0000000000000000E1
+:10217000002E00E1000000000000000002C000008E
+:10218000000002DC0000002100201E2D00000000E5
+:1021900000000000003120A100000000000000004D
+:1021A000002E00E8000000000000000006C0000053
+:1021B000000002DC0000002400201E2D00000000B2
+:1021C00000000000002E00E20000000000000000FF
+:1021D00002C00000000002DC0000002200201E2DD2
+:1021E0000000000000000000003120C200000000DC
+:1021F00000000000002E00E80000000000000000C9
+:1022000006C00000000002DC0000000000600000CA
+:10221000000006680000000000600000000002B539
+:102220000000000000400000000002DE000000008E
+:1022300000600000000002B5000000000060000027
+:102240000000065F0000000000400000000002DE09
+:102250000000000000600000000002A70000000075
+:1022600000400000000002DE0000001A00201E2DC9
+:10227000000000000000001B0080222D0000000074
+:102280000000001000221E230000000000000000DB
+:1022900000294887000000000000000000311CA356
+:1022A000000000000000001000221E2700000000B7
+:1022B0000000000000294887000000000000001016
+:1022C00000221E230000000000000000003120C496
+:1022D000000000000000FFFF00282228000000008E
+:1022E0000000000000894907000000000000001005
+:1022F00000221E2300000000000000000029488783
+:10230000000000000000001000221E21000000005C
+:102310000000000000294847000000000000000005
+:1023200000311CA3000000000000001000221E2746
+:1023300000000000000000000029488700000000A5
+:102340000000000000311CA100000000000000108F
+:1023500000221E270000000000000000002948475E
+:10236000000000000000001000221E2300000000FA
+:1023700000000000003120C4000000000000FFFF4A
+:102380000028222800000000000000000029490762
+:10239000000000000000001000221E2100000000CC
+:1023A00000000000003120C2000000000000FFFF1C
+:1023B00000282228000000000000000000894907D2
+:1023C000000000000000001000221E23000000009A
+:1023D0000000000000294887000000000000000104
+:1023E00000220A210000000000000000003308A2C3
+:1023F000000000000000001000221E22000000006B
+:102400000000001000212222000000000000000057
+:1024100000294907000000000000000000311CA353
+:10242000000000000000001000221E270000000035
+:1024300000000000002948870000000000000001A3
+:1024400000220A210000000000000000003008A265
+:10245000000000000000001000221E22000000000A
+:1024600000000010002122220000000000000000F7
+:1024700000294907000000000000001000221E2370
+:102480000000000000000000003120C40000000037
+:102490000000FFFF002822280000000000000000CC
+:1024A000002949070000000000000000003808C5AE
+:1024B00000000000000000000030084100000000A3
+:1024C0000000000100220A220000000000000000BD
+:1024D000003308A2000000000000001000221E22AD
+:1024E0000000000000000010002122220000000077
+:1024F00000000000008949070000000000000017EC
+:102500000020222D000000000000000014C0000088
+:1025100000000318FFFFFFEF002806210000000065
+:10252000000000140020222D000000000000F8E050
+:1025300000204411000000000000000000294901B3
+:1025400000000000000000000089490100000000B8
+:102550000000000000204811000000000000000002
+:102560000020481100000000060A02000080481107
+:102570000000000000000000C0200000000000007B
+:1025800097000000C020441100000000000000007F
+:10259000C0204811000000008A0000000020441103
+:1025A00000000000000000000020481100000000B2
+:1025B0000000225C00204411000000000000000028
+:1025C000C0204800000000000000A1FC00204411D1
+:1025D0000000000000000000C020480000000000D3
+:1025E00000000000C0200400000000000000000007
+:1025F00000A0000A00000000970000000020441125
+:102600000000000000000000002048110000000051
+:102610008A000000002044110000000000000000BB
+:1026200000204811000000000000225C002044113E
+:102630000000000000000000C02048000000000072
+:102640000000A1FC00204411000000000000000078
+:10265000C02048000000000000000000C02004006E
+:10266000000000000000000000A0000A00000000C0
+:10267000970000000020441100000000000000004E
+:1026800000204811000000008A00000000204411D2
+:1026900000000000000000000020481100000000C1
+:1026A0000000225C00204411000000000000000037
+:1026B000C0204800000000000000A1FC00204411E0
+:1026C0000000000000000000C020480000000000E2
+:1026D0000001A1FD002044110000000000000000E6
+:1026E000D90048000000000000000000C0200400E5
+:1026F000000000000000000000A0000A0000000030
+:1027000000002257002044110000000000000003D8
+:10271000C0484A20000000000000225D0020441153
+:102720000000000000000000C04048000000000061
+:1027300000000000006000000000064500000000EE
+:10274000C0200800000000000000225C00204411AE
+:10275000000000000000000300384A2200000000D2
+:102760000000A1FC00204411000000000000000057
+:10277000C0204800000000000001A1FD002044111D
+:102780000000000000000000002F022200000000F6
+:10279000000000000CE0000000000000000000004D
+:1027A00040204800000000000000000140304A20A6
+:1027B0000000000000000002C0304A2000000000BD
+:1027C0000000000100530A220000034B0000003FFC
+:1027D000C0280A20000000008100000000204411F1
+:1027E000000000000000000100204811000000006F
+:1027F000000021F800204411000000000000001833
+:102800000020481100000000000421F9006044117C
+:102810000000068D000000110021023000000000C1
+:102820000000000014E00000000003540000001449
+:10283000002F022200000000000000000CC0000079
+:10284000000003640000201000204411000000007C
+:102850000000800000204811000000000001A2A438
+:102860000020441100000000000000000060480249
+:102870000000036E00002100002044110000000051
+:1028800000000000C0204800000000000000000020
+:10289000C02048000000000000000000C0204800E8
+:1028A0000000000000000000C040480000000000E0
+:1028B00000000004002F02220000000000000000C1
+:1028C0000CC000000000036A00002010002044112A
+:1028D00000000000000080000020481100000000FF
+:1028E0000001A2A40020441100000000000000002C
+:1028F000004048020000035F00000028002F022271
+:1029000000000000000000000CC00000000005C036
+:102910000001A2A4002044110000000000000000FB
+:10292000004048020000035F0000002C0020362613
+:102930000000000000000049002018110000000005
+:102940000000003F002048110000000000000001CE
+:1029500000331A260000000000000000002F0226AD
+:1029600000000000000000000CC000000000037028
+:102970000000002C00801A2D000000000000003F25
+:10298000C0280A200000000000000015002F0222CD
+:1029900000000000000000000CE0000000000386C2
+:1029A00000000006002F02220000000000000000CE
+:1029B0000CE00000000003B100000016002F02220E
+:1029C00000000000000000000CE00000000003B563
+:1029D00000000020002F0222000000000000000084
+:1029E0000CE000000000039C0000000F002F0222FA
+:1029F00000000000000000000CE00000000003A840
+:102A000000000010002F0222000000000000000063
+:102A10000CE00000000003A80000001E002F0222AE
+:102A200000000000000000000CE000000000039027
+:102A30000000A2A4002044110000000000000000DB
+:102A400000404802000000000800000000290A229F
+:102A5000000000000000000340210E2000000000E4
+:102A60000000000CC021122000000000000800003F
+:102A7000002812240000000000000014C0221620CC
+:102A80000000000000000000002914A40000000065
+:102A90000000A2A40020441100000000000000007B
+:102AA000002948A2000000000000A1FE00204411FF
+:102AB000000000000000000000404803000000008B
+:102AC000810000000020441100000000000000010F
+:102AD0000020481100000000000021F800204411EF
+:102AE0000000000000000016002048110000000057
+:102AF000000421F9006044110000068D000000155B
+:102B000000210230000000000000000014E000007E
+:102B1000000003920000210E00204411000000007C
+:102B200000000000C020480000000000000000007D
+:102B3000C0204800000000000000A2A400204411B2
+:102B400000000000000000000040480200000000FB
+:102B5000810000000020441100000000000000017E
+:102B60000020481100000000000021F8002044115E
+:102B700000000000000000170020481100000000C5
+:102B8000000421F9006044110000068D00000003DC
+:102B900000210230000000000000000014E00000EE
+:102BA0000000039E000021080020441100000000E6
+:102BB00000000000C02048000000000000000000ED
+:102BC000C0204800000000000000A2A40020441122
+:102BD000000000000000000000404802000000006B
+:102BE0000000A2A40020441100000000000000002A
+:102BF0000020480200000000800000000020441176
+:102C0000000000000000000000204811000000004B
+:102C100081000000002044110000000000000010AE
+:102C200000204811000000000000000000200010FB
+:102C3000000000000000000014C00000000003AE0F
+:102C40000000000000400000000000000000201014
+:102C50000020441100000000000080000020481106
+:102C6000000000000001A2A40020441100000000A8
+:102C70000000000600404811000000000000201085
+:102C800000204411000000000000800000204811D6
+:102C9000000000000001A2A4002044110000000078
+:102CA00000000016006048110000036E00000000E4
+:102CB000004000000000000000000000C0200800EC
+:102CC0000000000000000000C0200C000000000018
+:102CD0000000001D00210223000000000000000091
+:102CE00014E00000000003CE810000000020441129
+:102CF000000000000000000100204811000000005A
+:102D0000000021F80020441100000000000000181D
+:102D10000020481100000000000421F90060441167
+:102D20000000068D000000110021023000000000AC
+:102D30000000000014E00000000003C000002100BB
+:102D400000204411000000000000000000204802A4
+:102D50000000000000000000002048030000000008
+:102D6000BABECAFE0020481100000000CAFEBABE6A
+:102D70000020481100000000000020100020441135
+:102D8000000000000000800000204811000000004A
+:102D90000000A2A400204411000000000000000474
+:102DA0000040481100000000000021700020441184
+:102DB00000000000000000000020480200000000A9
+:102DC0000000000000204803000000008100000017
+:102DD00000204411000000000000000A00204811FB
+:102DE00000000000000000000020001000000000B3
+:102DF0000000000014C00000000003D38C0000009D
+:102E00000020441100000000CAFEBABE0040481174
+:102E100000000000810000000020441100000000BC
+:102E200000000001002048110000000000003FFFEA
+:102E300040280A20000000008000000040280E20EA
+:102E40000000000040000000C02812200000000028
+:102E500000040000006946220000068D000000000A
+:102E6000002014100000000000000000002F0223CA
+:102E700000000000000000000CC00000000003E1A2
+:102E800000000000C0401800000003E400003FFF05
+:102E9000C0281A2000000000000400000069462637
+:102EA0000000068D00000000002018100000000047
+:102EB00000000000002F02240000000000000000BD
+:102EC0000CC00000000003E700000000C0401C0030
+:102ED000000003EA00003FFFC0281E2000000000A1
+:102EE00000040000006946270000068D0000000075
+:102EF00000201C1000000000000000000020440220
+:102F00000000000000000000002820C500000000B4
+:102F100000000000004948E800000000A580000013
+:102F200000200811000000000000200000200C110B
+:102F30000000000083000000006044110000041243
+:102F4000000000000020440200000000000000001B
+:102F5000C0204800000000000000000040204800A1
+:102F6000000000000000001FC0210220000000003F
+:102F70000000000014C00000000003F70000201053
+:102F800000204411000000000000800000204811D3
+:102F9000000000000000FFFFC0481220000003FFF7
+:102FA000A780000000200811000000000000A00021
+:102FB00000200C110000000083000000006044119C
+:102FC0000000041200000000002044020000000085
+:102FD00000000000C02048000000000000000000C9
+:102FE000C0204800000000000000FFFFC0281220A1
+:102FF00000000000830000000020441100000000D9
+:103000000000000000304883000000008400000041
+:10301000002044110000000000000000C020480013
+:1030200000000000000000001D0000000000000083
+:103030008300000000604411000004120000000042
+:10304000C040040000000001A98000000020081119
+:10305000000000000000C00000400C11000003FA56
+:10306000AB80000000200811000000000000F8E024
+:1030700000400C11000003FAAD8000000020081190
+:10308000000000000000F88000400C11000003FA6E
+:10309000B380000000200811000000000000F3FCD5
+:1030A00000400C11000003FAAF800000002008115E
+:1030B000000000000000E00000400C11000003FAD6
+:1030C000B180000000200811000000000000F000A6
+:1030D00000400C11000003FA83000000002044119E
+:1030E00000000000000021480020481100000000FE
+:1030F00084000000002044110000000000000000D7
+:10310000C020480000000000000000001D0000007A
+:10311000000000000000000000800000000000002F
+:1031200001182000C0304620000000000000000010
+:10313000D90048000000000000000000C02004008A
+:10314000000000000000000000A0000A00000000D5
+:103150000218A000C030462000000000000000005F
+:10316000D90048000000000000000000C02004005A
+:10317000000000000000000000A0000A00000000A5
+:103180000318C000C030462000000000000000000E
+:10319000D90048000000000000000000C02004002A
+:1031A000000000000000000000A0000A0000000075
+:1031B0000418F8E0C03046200000000000000000C5
+:1031C000D90048000000000000000000C0200400FA
+:1031D000000000000000000000A0000A0000000045
+:1031E0000518F880C03046200000000000000000F4
+:1031F000D90048000000000000000000C0200400CA
+:10320000000000000000000000A0000A0000000014
+:103210000618E000C030462000000000000000005A
+:10322000D90048000000000000000000C020040099
+:10323000000000000000000000A0000A00000000E4
+:103240000718F000C0304620000000000000000019
+:10325000D90048000000000000000000C020040069
+:10326000000000000000000000A0000A00000000B4
+:103270000818F3FCC03046200000000000000000E9
+:10328000D90048000000000000000000C020040039
+:10329000000000000000000000A0000A0000000084
+:1032A0000000003000200A2D000000000000000097
+:1032B000C0290C4000000000000000300020362330
+:1032C0000000000000000000C0200400000000001A
+:1032D0000000000000A0000A0000000086000000BE
+:1032E00000204411000000000000000000404801E0
+:1032F0000000000085000000C02044110000000014
+:103300000000000000404801000000000000217C97
+:10331000002044110000000000000018402102209D
+:10332000000000000000000014C000000000044580
+:1033300000800000C0494A20000004460000000050
+:10334000C02048000000000000000000C02048002D
+:103350000000000000000000C02048000000000045
+:103360008100000000204411000000000000000166
+:10337000002048110000000000000000C0200800EC
+:103380000000000000000000170000000000000026
+:103390000004217F006044110000068D0000001F22
+:1033A00000210230000000000000000014C00000F6
+:1033B000000000000000000000404C020000044B30
+:1033C00000000000C0200C00000000000000000011
+:1033D000C02010000000000000000000C020140009
+:1033E0000000000000000000C020180000000000E5
+:1033F00000000000C0201C000000000000007F0052
+:1034000000280A210000000000004500002F0222D1
+:1034100000000000000000000CE000000000045963
+:1034200000000000C020200000000000000000009C
+:1034300017000000000000000000001000280A2310
+:103440000000000000000010002F02220000000019
+:10345000000000000CE0000000000461810000009A
+:10346000002044110000000000000001002048116D
+:103470000000000000040000006946240000068DE2
+:103480000000000000400000000004668100000011
+:10349000002044110000000000000000002048113E
+:1034A000000000000000216D002044110000000019
+:1034B00000000000002048040000000000000000A0
+:1034C000006048050000069200000000002824F07B
+:1034D000000000000000000700280A230000000090
+:1034E00000000001002F0222000000000000000088
+:1034F0000AE000000000046D00000000002F00C979
+:10350000000000000000000004E00000000004864D
+:1035100000000000004000000000049300000002D2
+:10352000002F022200000000000000000AE000005E
+:103530000000047200000000002F00C9000000001D
+:103540000000000002E0000000000486000000000F
+:10355000004000000000049300000003002F02223E
+:1035600000000000000000000AE0000000000477F6
+:1035700000000000002F00C9000000000000000053
+:103580000CE0000000000486000000000040000085
+:103590000000049300000004002F0222000000003D
+:1035A000000000000AE000000000047C00000000B1
+:1035B000002F00C900000000000000000AE0000029
+:1035C000000004860000000000400000000004939A
+:1035D00000000005002F0222000000000000000093
+:1035E0000AE000000000048100000000002F00C974
+:1035F000000000000000000006E00000000004865B
+:1036000000000000004000000000049300000006DD
+:10361000002F022200000000000000000AE000006D
+:103620000000048600000000002F00C90000000018
+:103630000000000008E00000000004860000000018
+:10364000004000000000049300007F0000280A21D1
+:103650000000000000004500002F022200000000D2
+:10366000000000000AE00000000000000000000868
+:1036700000210A23000000000000000014C0000028
+:1036800000000490000021690020441100000000A7
+:1036900000000000C0204800000000000000000002
+:1036A000C02048000000000000000000C0204800CA
+:1036B00000000000CAFEBABE004048110000000031
+:1036C00000000000C02044000000000000000000D6
+:1036D000C02000000000000000000000C0404800C2
+:1036E0000000000000007F0000280A210000000008
+:1036F00000004500002F0222000000000000000032
+:103700000AE000000000049900000000C020000052
+:103710000000000000000000C020000000000000C9
+:1037200000000000C0400000000000000000000099
+:1037300000404C080000045900000000C0200800B0
+:10374000000000000000001040210E2000000000DA
+:1037500000000011402112200000000000000012B3
+:1037600040211620000000000000216900204411C3
+:1037700000000000000000000020480200000000DF
+:1037800000000000002102250000000000000000F1
+:1037900014E00000000004A300040000C0494A2017
+:1037A000000004A4FFFBFFFFC0284A200000000027
+:1037B00000000000002102230000000000000000C3
+:1037C00014E00000000004B000000000C020480029
+:1037D0000000000000000000C020480000000000C1
+:1037E0000000000000210224000000000000000092
+:1037F00014C00000000000008100000000204411FF
+:10380000000000000000000C002048110000000033
+:103810000000000000200010000000000000000078
+:1038200014C00000000004ACA000000000204411FF
+:1038300000000000CAFEBABE0040481100000000AF
+:10384000810000000020441100000000000000047E
+:1038500000204811000000000000216B00204411EE
+:103860000000000000000000C02048100000000020
+:10387000810000000020441100000000000000054D
+:1038800000204811000000000000216C00204411BD
+:103890000000000000000000C020481000000000F0
+:1038A00000000000002F02240000000000000000C3
+:1038B0000CE00000000000000000000000400000DC
+:1038C000000004AA00000000C0210A20000000003F
+:1038D0000000000014C00000000004C381000000CC
+:1038E00000204411000000000000000000204811EA
+:1038F000000000000000216D0020441100000000C5
+:1039000000000000C020480000000000000000008F
+:10391000C060480000000692000000000040000067
+:10392000000004C7810000000020441100000000D6
+:103930000000000100204811000000000004000009
+:10394000C02946200000000000000000C060000008
+:103950000000068D0000000100210222000000008E
+:103960000000000014C00000000004CE0000216927
+:10397000002044110000000000000000C0204800AA
+:103980000000000000000000C0204800000000000F
+:10399000000000000020481000000000CAFEBABE6F
+:1039A000004048110000000000000000C02044005A
+:1039B0000000000000000000C040481000000000AF
+:1039C0008100000000204411000000000000000100
+:1039D0000020481100000000000021F800204411E0
+:1039E000000000000000000E002048110000000050
+:1039F000000421F9006044110000068D0000000061
+:103A000000210230000000000000000014C000008F
+:103A1000000004D0000021800020441100000000BC
+:103A200000000000C020480000000000000000006E
+:103A3000C02000000000000000000000C02048007E
+:103A40000000000000000000C02000000000000096
+:103A500000000000C040480000000000000000031B
+:103A600000333E2F00000000000000010021022171
+:103A7000000000000000000014E00000000005004D
+:103A80000000002C00200A2D0000000000040000AF
+:103A900018E00C11000004EF0000000100333E2F7D
+:103AA0000000000000002169002044110000000017
+:103AB000000000000020480200000000000000009C
+:103AC00000204803000000000000000800300A2227
+:103AD0000000000000000000C020480000000000BE
+:103AE00000000000C0204800000000000000216924
+:103AF00000204411000000000000000000204802E7
+:103B0000000000000000000000204803000000004A
+:103B10000000000800300A22000000000000000041
+:103B2000C02048000000000000000000D8C048008D
+:103B3000000004E30000216900204411000000009F
+:103B4000000000000020480200000000000000000B
+:103B500000204803000000000000000800300A2296
+:103B60000000000000000000C0204800000000002D
+:103B700000000000C0204800000000000000002DF0
+:103B80000020122D000000000000000000290C831E
+:103B90000000000000002169002044110000000026
+:103BA00000000000002048020000000000000000AB
+:103BB00000204803000000000000000800300A2236
+:103BC0000000000000000000C020480000000000CD
+:103BD00000000000C02048000000000000000011AC
+:103BE00000210224000000000000000014C00000BA
+:103BF000000000000000000000400000000004AAD7
+:103C00000000002CC0203620000000000000002D25
+:103C1000C0403620000000000000000F00210221FB
+:103C2000000000000000000014C0000000000505B6
+:103C300000000000006000000000000B0000000019
+:103C4000D90000000000000000000000C040040097
+:103C500000000001B5000000002044110000000039
+:103C6000000020000020481100000000B600000005
+:103C700000204411000000000000A00000204811B6
+:103C800000000000B7000000002044110000000008
+:103C90000000C0000020481100000000B800000033
+:103CA00000204411000000000000F8E0002048114E
+:103CB00000000000B90000000020441100000000D6
+:103CC0000000F8800020481100000000BA00000049
+:103CD00000204411000000000000E0000020481116
+:103CE00000000000BB0000000020441100000000A4
+:103CF0000000F0000020481100000000BC0000009F
+:103D000000204411000000000000F3FC00204811D6
+:103D100000000000810000000020441100000000AD
+:103D2000000000020020481100000000000000FF19
+:103D300000280E300000000000000000002F0223C9
+:103D400000000000000000000CC000000000051989
+:103D500000000000C020080000000000000000007B
+:103D600014C000000000052E0000000000200C110F
+:103D7000000000000000001C0020362300000000AE
+:103D80000000002B00203623000000000000002966
+:103D90000020362300000000000000280020362309
+:103DA0000000000000000017002036230000000083
+:103DB000000000250020362300000000000000263F
+:103DC00000203623000000000000001500203623EC
+:103DD0000000000000000016002036230000000054
+:103DE000FFFFE00000200C11000000000000002197
+:103DF00000203623000000000000002200203623AF
+:103E00000000000000001FFF00200C110000000057
+:103E100000000023002036230000000000000024E2
+:103E20000020362300000000F1FFFFFF00283A2E9B
+:103E3000000000000000001AC0220E200000000058
+:103E4000000000000029386E000000008100000022
+:103E5000002044110000000000000006002048116E
+:103E6000000000000000002A402036200000000072
+:103E70008700000000204411000000000000000046
+:103E8000C0204800000000000000A1F40020441100
+:103E900000000000000000000020481000000000AA
+:103EA0000000000000200C110000000000000030A5
+:103EB00000203623000000009D0000000020441177
+:103EC000000000000000001F40214A200000000008
+:103ED00096000000002044110000000000000000D7
+:103EE000C02048000000000000000000C0200C00BE
+:103EF0000000000000000000C020100000000000D2
+:103F00000000001F00211624000000000000000037
+:103F100014C00000000000000000001D0020362337
+:103F2000000000000000000300281E230000000025
+:103F3000000000080022222300000000FFFFF00024
+:103F4000002822280000000000000000002920E8CE
+:103F5000000000000000001F0020362800000000C4
+:103F60000000001800211E230000000000000020B7
+:103F70000020362700000000000000020022162466
+:103F80000000000000000000003014A80000000045
+:103F90000000001E00203625000000000000000385
+:103FA00000211A24000000001000000000281A263A
+:103FB00000000000EFFFFFFF00283A2E0000000085
+:103FC00000000000004938CE0000067B0000000120
+:103FD00040280A20000000000000000640280E20B3
+:103FE0000000000000000300C028122000000000B4
+:103FF0000000000800211224000000000000000062
+:10400000C02016200000000000000000C0201A2080
+:10401000000000000000000000210222000000005B
+:104020000000000014C000000000056681000000D0
+:104030000020441100000000000000010020481191
+:10404000000000000000225800300A240000000098
+:1040500000040000006946220000068D000021696E
+:10406000002044110000000000000000002048056E
+:10407000000000000002000000294A2600000000A5
+:10408000000000000020481000000000CAFEBABE78
+:10409000002048110000000000000002002F022351
+:1040A00000000000000000000CC000000000056ED1
+:1040B00000000000C0201C100000000000000000F4
+:1040C000C04000000000057C00000002002F022319
+:1040D00000000000000000000CC000000000056EA1
+:1040E00081000000002044110000000000000001D9
+:1040F00000204811000000000000225800300A246F
+:104100000000000000040000006946220000068D47
+:1041100000000000C0201C10000000000000000093
+:10412000C04000000000057C00000000002F0223BA
+:1041300000000000000000000CC00000000005723C
+:1041400000000000C0201C00000000000000000073
+:10415000C04000000000057C00000004002F022386
+:1041600000000000000000000CC000000000057A04
+:104170008100000000204411000000000000000049
+:1041800000204811000000000000216D00204411B3
+:104190000000000000000000C020480000000000F7
+:1041A00000000000C060480000000692000000000F
+:1041B00000401C100000057C00000000C020000032
+:1041C0000000000000000000C040000000000000EF
+:1041D000000000000EE000000000057E000000006E
+:1041E00000600000000005C900000000002F02244C
+:1041F00000000000000000000CC000000000058F5F
+:104200000000A2B7002044110000000000000000E0
+:104210000020480700000000810000000020441139
+:104220000000000000000001002048110000000014
+:104230000004A2B6006044110000068D0000001AC0
+:10424000002122300000000000000006002226307D
+:104250000000000000042004006044110000068DEE
+:104260000000A2C400204411000000000000000073
+:10427000003048E9000000000000000000E00000FD
+:104280000000058D0000A2D10020441100000000B4
+:104290000000000000404808000000000000A2D11B
+:1042A00000204411000000000000000100504A28D6
+:1042B0000000000000000001002F022400000000A8
+:1042C000000000000CC00000000005A00000A2BB20
+:1042D00000204411000000000000000000204807FA
+:1042E00000000000810000000020441100000000D8
+:1042F0000000000100204811000000000004A2BAE4
+:10430000006044110000068D0000001A00212230D8
+:10431000000000000000000600222630000000001F
+:1043200000042004006044110000068D0000A2C5B6
+:10433000002044110000000000000000003048E9A7
+:10434000000000000000000000E000000000059EEA
+:104350000000A2D200204411000000000000000074
+:1043600000404808000000000000A2D200204411D4
+:10437000000000000000000100504A28000000007A
+:1043800000000002002F02240000000000000000D6
+:104390000CC00000000005B10000A2BF00204411C5
+:1043A000000000000000000000204807000000009E
+:1043B0008100000000204411000000000000000106
+:1043C00000204811000000000004A2BE006044115B
+:1043D0000000068D0000001A0021223000000000BD
+:1043E0000000000600222630000000000004200427
+:1043F000006044110000068D0000A2C60020441198
+:104400000000000000000000003048E9000000004B
+:104410000000000000E00000000005AF0000A2D393
+:104420000020441100000000000000000040480887
+:10443000000000000000A2D3002044110000000092
+:104440000000000100504A28000000000000A2C344
+:104450000020441100000000000000000020480778
+:104460000000000081000000002044110000000056
+:104470000000000100204811000000000004A2C25A
+:10448000006044110000068D0000001A0021223057
+:10449000000000000000000600222630000000009E
+:1044A00000042004006044110000068D0000A2C733
+:1044B000002044110000000000000000003048E926
+:1044C000000000000000000000E00000000005BE49
+:1044D0000000A2D4002044110000000000000000F1
+:1044E00000404808000000000000A2D40020441151
+:1044F000000000000000000100504A2800000000F9
+:1045000085000000002044110000000000000000B1
+:1045100000204801000000000000304A0020441143
+:104520000000000001000000002048110000000011
+:104530000000000000400000000005C4A4000000CE
+:10454000C02044110000000000000000C0404800EE
+:104550000000000000000000C0600000000005C96D
+:1045600000000000C0400400000000010000002C1A
+:1045700000203621000000008100000000204411CE
+:1045800000000000000000060020481100000000AC
+:1045900000000000002F02300000000000000000BA
+:1045A0000CC00000000005D0000000000020041135
+:1045B000000000000000003000403621000005E34C
+:1045C000000000300020062D0000000000007E00EA
+:1045D000002806210000000000000000002F02213A
+:1045E00000000000000000000CE00000000005E3F7
+:1045F00081000000002044110000000000000001C4
+:1046000000204811000000000004A0920060441146
+:104610000000068D00000031002036300000000050
+:104620000004A093006044110000068D00000032D9
+:1046300000203630000000000004A2B600604411E3
+:104640000000068D0000003300203630000000001E
+:104650000004A2BA006044110000068D000000347E
+:1046600000203630000000000004A2BE00604411AB
+:104670000000068D000000350020363000000000EC
+:104680000004A2C2006044110000068D0000003644
+:1046900000203630000000000004200400604411B7
+:1046A0000000068D0001A2A40020441100000000BB
+:1046B0000000003F00204811000000000000003F03
+:1046C00000204811000000000000003F00204811B9
+:1046D000000000000000003F002048110000000022
+:1046E0000000000500204811000000000000A1F4B7
+:1046F00000204411000000000000000000204811CC
+:1047000000000000880000000020441100000000AC
+:10471000000000010020481100000000810000009E
+:104720000020441100000000000000060020481195
+:104730000000000000000001002F02300000000017
+:10474000000000000CE000000000062C000000301B
+:104750000020062D0000000000000000002F0221B4
+:1047600000000000000000000CE000000000062C2B
+:104770008100000000204411000000000000000142
+:10478000002048110000000000007E0000280621E3
+:104790000000000000000000002F022100000000C7
+:1047A000000000000CE00000000006050000A092E0
+:1047B00000204411000000000000003100204A2DBC
+:1047C000000000000000A093002044110000000041
+:1047D0000000003200204A2D000000000000A2B6B8
+:1047E00000204411000000000000003300204A2D8A
+:1047F000000000000000A2BA0020441100000000E8
+:104800000000003400204A2D000000000000A2BE7D
+:1048100000204411000000000000003500204A2D57
+:10482000000000000000A2C20020441100000000AF
+:104830000000003600204A2D00000000000000307B
+:104840000020062D00000000000001FF00280621C6
+:104850000000000000000000002F02210000000006
+:10486000000000000CE000000000062B000000002B
+:1048700000210221000000000000000014C0000020
+:104880000000060E0004A003006044110000068D25
+:104890000000A00300204411000000000000000000
+:1048A0000020481000000000000000010021062147
+:1048B000000000000000000014C00000000006130B
+:1048C0000004A010006044110000068D0000A0103C
+:1048D00000204411000000000000000000204810EB
+:1048E000000000000000000100210621000000007F
+:1048F00000000000002F0221000000000000000066
+:104900000CE000000000062B0004A0110060441120
+:104910000000068D0000A0110020441100000000DE
+:104920000000000000204810000000000004A01259
+:10493000006044110000068D0000A0120020441108
+:1049400000000000000000000020481000000000EF
+:104950000004A013006044110000068D0000A013A5
+:10496000002044110000000000000000002048105A
+:10497000000000000004A014006044110000068D37
+:104980000000A014002044110000000000000000FE
+:1049900000204810000000000004A0150060441131
+:1049A0000000068D0000A01500204411000000004A
+:1049B0000000000000204810000000000004A016C5
+:1049C000006044110000068D0000A0160020441174
+:1049D000000000000000000000204810000000005F
+:1049E0000004A017006044110000068D0000A0170D
+:1049F00000204411000000000000000000204810CA
+:104A00000000000000042004006044110000068D36
+:104A10000000002C0080062D00000000FF000000B8
+:104A20000020441100000000000000000020481198
+:104A300000000000000000010020481100000000FC
+:104A4000000000020080481100000000000000008B
+:104A50000EE000000000063D000000300020062DA2
+:104A600000000000000000020028062100000000F5
+:104A700000000000002F02210000000000000000E4
+:104A80000CE000000000063B810000000020441103
+:104A9000000000000000000100204811000000009C
+:104AA00000042004006044110000068D0000100086
+:104AB00000200811000000000000002B002036221A
+:104AC000000000000000000000600000000006413F
+:104AD0000000000000600000000005C99800000010
+:104AE0000020441100000000000000000080481178
+:104AF0000000000000000000C0600000000006414F
+:104B000000000000C0400400000000010000A2A45A
+:104B10000020441100000000000000220020481185
+:104B20000000000089000000002044110000000087
+:104B300000000001004048110000062D9700000011
+:104B40000020441100000000000000000020481177
+:104B5000000000008A000000002044110000000056
+:104B600000000000004048110000062D0000000079
+:104B7000006000000000065C0000201000204411CE
+:104B8000000000000000800000204811000000002C
+:104B90000001A2A4C0204411000000000000001683
+:104BA000006048110000036E000020100020441136
+:104BB000000000000001000000204811000000007B
+:104BC00081000000002044110000000000000001EE
+:104BD00000204811000000000000217C002044114A
+:104BE00000000000098000000020481100000000C3
+:104BF000FFFFFFFF00204811000000000000000040
+:104C00000020481100000000000000001700000014
+:104C1000000000000004217F006044110000068DA8
+:104C20000000001F00210230000000000000000012
+:104C300014C00000000000000000000400404C11FF
+:104C400000000656000000000040000000000000C8
+:104C50000000001700201E2D0000000000000004CE
+:104C600000291E27000000000000001700803627E2
+:104C7000000000000000001700201E2D00000000B2
+:104C8000FFFFFFFB00281E270000000000000017A8
+:104C900000803627000000000000001700201E2DB5
+:104CA000000000000000000800291E27000000008E
+:104CB00000000017008036270000000000000017E9
+:104CC00000201E2D00000000FFFFFFF700281E2718
+:104CD00000000000000000170080362700000000E0
+:104CE000000020100020441100000000000080009F
+:104CF00000204811000000000001A2A4002044117F
+:104D00000000000000000016006048110000036E63
+:104D100000002010002044110000000000010000ED
+:104D200000204811000000000000217C00204411F8
+:104D30000000000001800000002048110000000079
+:104D4000FFFFFFFF002048110000000000000000EE
+:104D500000204811000000000000000017000000C3
+:104D6000000000008100000000204411000000004D
+:104D70000000000100204811000000000004217F15
+:104D8000006044110000068D0000001F0021023069
+:104D9000000000000000000014C000000000068CAD
+:104DA0000000001000404C110000067200000000DE
+:104DB000C0200400000000000000000038C0000017
+:104DC000000000000000001D00200A2D000000006F
+:104DD0000000001E00200E2D000000000000001F3B
+:104DE0000020122D00000000000000200020162DE1
+:104DF00000000000000021690020441100000000B4
+:104E00000000000000204804000000000000000036
+:104E100000204805000000000000000000204801BC
+:104E200000000000CAFEBABE0020481100000000C9
+:104E30000000000400301224000000000000000008
+:104E4000002F006400000000000000000CC0000003
+:104E50000000068B0000000300281A22000000005A
+:104E6000000000080022122200000000FFFFF000F6
+:104E7000002812240000000000000000002910C4D7
+:104E8000000000000000001F004036240000000069
+:104E90000000000000800000000000000000000092
+:104EA0001AC000000000068D9F0000000020441181
+:104EB00000000000CAFEBABE002048110000000039
+:104EC000000000001AE00000000006900000000052
+:104ED0000080000000000000000000001AC0000078
+:104EE000000006929E000000002044110000000017
+:104EF000CAFEBABE002048110000000000000000F9
+:104F00001AE000000000069500000000008000008C
+:104F10000000000000000000006000000000000B26
+:104F200000001000006004110000031500000000E4
+:104F300000200411000000000000000000600811C3
+:104F4000000001B20000225C0020441100000000BB
+:104F5000000000030020481100000000000022565D
+:104F600000204411000000000000001B0020481138
+:104F7000000000000000A1FC00204411000000001F
+:104F80000000000100204811000000000001A1FD08
+:104F9000C0204411000000000000002100201E2D50
+:104FA000000000000000001000221E27000000008A
+:104FB000000000240020222D000000000000FFFF60
+:104FC00000282228000000000000000000294907F6
+:104FD0000000000000000000002048110000000058
+:104FE000000000220020222D000000000000FFFF32
+:104FF00000282228000000000000000000294907C6
+:105000000000000000000000002048110000000027
+:105010000000002300201E2D0000000000000010F2
+:1050200000221E27000000000000000000294907A0
+:1050300000000000000000000040481100000000D7
+:105040000000000000000000000000000000000060
+:105050000000000000000000000000000000000050
+:105060000000000000000000000000000000000040
+:105070000000000000000000000000000000000030
+:105080000000000000000000000000000000000020
+:105090000000000000000000000000000000000010
+:1050A0000000000000000000000000000000000000
+:1050B00000000000000000000000000000000000F0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:10517000000000000000000000000000000000002F
+:10518000000000000000000000000000000000001F
+:10519000000000000000000000000000000000000F
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000000000000000000DF
+:1051D00000000000000000000000000000000000CF
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:10522000000000000000000000000000000000007E
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000000000005E
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000000000000000000002E
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000000000000000000000000000FE
+:1052B0000142050205C002500000000001C3016860
+:1052C000043F05C000000000022502090250015100
+:1052D000000000000223024502A00241000000007D
+:1052E00003D705C005C005C0000000000649064AF6
+:1052F000031F05C00000000005C005C503200340D2
+:1053000000000000032A0282034203340000000070
+:1053100005C005C005C005C00000000005C005515E
+:1053200005C005C00000000003BA05C004BB03446B
+:1053300000000000049A0450043D05C00000000075
+:1053400004D005C0044104DD00000000045005073E
+:10535000035103750000000005C005C005C005C06D
+:105360000000000005C005C005C005C00000000029
+:1053700005C005C0063F05C70000000005C005C008
+:10538000000705C00000000005C005C005C005C03D
+:105390000000000005C005C005C005C000000000F9
+:1053A00003F803ED0408040600000000040E040ADC
+:1053B000040C041000000000041C04180424042041
+:1053C00000000000042C0428043404300000000015
+:1053D00005C005C0043805C00000000005C005C0B8
+:1053E00005C005C00000000005C005C005C005C01F
+:1053F0000000000000020679069700060000000089
+:00000001FF
diff --git a/firmware/radeon/RV610_pfp.bin.ihex b/firmware/radeon/RV610_pfp.bin.ihex
new file mode 100644
index 0000000..f55292c
--- /dev/null
+++ b/firmware/radeon/RV610_pfp.bin.ihex
@@ -0,0 +1,145 @@
+:1000000000CA040000A00000007E828B007C038BED
+:10001000008001B8007C038B00D4401E00EE001E5F
+:1000200000CA040000A00000007E828B00C41838C3
+:1000300000CA240000CA2800009581A800C41C3A08
+:1000400000C3C00000CA080000CA0C00007C744B4A
+:1000500000C200050099C00000C41C3A007C744C2A
+:1000600000C0FFF000042C0400309002007D250049
+:1000700000351402007D350B00255403007CD5802B
+:1000800000259C030095C00400D5001B007EDDC147
+:10009000007D9D8000D6801B00D5801B00D4401EB3
+:1000A00000D5401E00D6401E00D6801E00D4801E03
+:1000B00000D4C01E009783D300D5C01E00CA08001C
+:1000C0000080001A00CA0C0000E4011E00D4001ECB
+:1000D0000080000C00C4183800E4013E00D4001E6B
+:1000E0000080000C00C4183800D4401E00EE001E32
+:1000F00000CA040000A00000007E828B00E4011E04
+:1001000000D4001E00D4401E00EE001E00CA0400F1
+:1001100000A00000007E828B00E4013E00D4001E9F
+:1001200000D4401E00EE001E00CA040000A0000023
+:10013000007E828B00CA180000D4401E00D5801EAD
+:100140000080005300D4007500D4401E00CA08008F
+:1001500000CA0C0000CA100000D4801900D4C018D6
+:1001600000D5001700D4801E00D4C01E00D5001E8C
+:1001700000E2001E00CA040000A00000007E828B86
+:1001800000CA080000D4806000D4401E0080000037
+:1001900000D4801E00CA080000D4806100D4401E34
+:1001A0000080000000D4801E00CA080000CA0C00B5
+:1001B00000D4401E00D4801600D4C01600D4801E87
+:1001C000008001B800D4C01E00C6084300CA0C005D
+:1001D00000CA10000094800400CA140000E420F358
+:1001E00000D4201300D5606500D4E01C00D5201C8D
+:1001F00000D5601C008000000006200100C60843F6
+:1002000000CA0C0000CA1000009483F700CA140052
+:1002100000E420F30080007900D4201300C60843D6
+:1002200000CA0C0000CA1000009883EF00CA140036
+:1002300000D400640080008D0000000000C414326F
+:1002400000C6184300C4082F0095400500C40C30B8
+:1002500000D4401E0080000000EE001E009583F5D3
+:1002600000C4103100D4403300D5206500D4A01C58
+:1002700000D4E01C00D5201C00E4015E00D4001E68
+:10028000008000000006200100CA1800000A2001BA
+:1002900000D6007600C408360098800700C61045D6
+:1002A0000095011000D4001F00D46062008000009F
+:1002B00000D4206200CC383500CC1433008401BB5C
+:1002C00000D4007200D5401E0080000000EE001E29
+:1002D00000E2001A008401BB00E2001A00CC104BBF
+:1002E00000CC0447002C9401007D098B0098400548
+:1002F000007D15CB00D4001A008001B800D4006D39
+:100300000034440100CC0C480098403A00CC2C4A00
+:100310000095800400CC0449008001B800D4001A84
+:1003200000D4C01A00282801008400F000CC10037B
+:100330000098801B0004380C008400F000CC1003EF
+:100340000098801700043808008400F000CC1003E7
+:100350000098801300043804008400F000CC1003DF
+:100360000098801400CC104C009A800900CC144DE9
+:10037000009840DC00D4006D00CC184800D5001A6D
+:1003800000D5401A008000C900D5801A0096C0D55B
+:1003900000D4006D008001B800D4006E009AC00344
+:1003A00000D4006D00D4006E0080000000EC007FDF
+:1003B000009AC0CC00D4006D008001B800D4006E5B
+:1003C00000CC140300CC180300CC1C03007D910367
+:1003D000007DD583007D190C0035CC1F0035701FC2
+:1003E000007CF0CB007CD08B00880000007E8E8BE0
+:1003F0000095C00400D4006E008001B800D4001A3B
+:1004000000D4C01A00CC080300CC0C0300CC1003AD
+:1004100000CC140300CC180300CC1C0300CC240334
+:1004200000CC28030035C41F0036B01F007C704B81
+:100430000034F01F007C704B0035701F007C704B47
+:10044000007D8881007DCCC1007E5101007E9541F8
+:10045000007C9082007CD4C2007C848B009AC00314
+:10046000007C8C8B002C88010098809E00D4006D4D
+:100470000098409C00D4006E00CC084C00CC0C4D81
+:1004800000CC104800D4801A00D4C01A00800101AA
+:1004900000D5001A00CC083200D40032009482D972
+:1004A00000CA0C0000D4401E0080000000D4001ED2
+:1004B00000E4011E00D4001E00CA080000CA0C009F
+:1004C00000CA100000D4401E00CA140000D4801ED0
+:1004D00000D4C01E00D5001E00D5401E00D54034FB
+:1004E0000080000000EE001E0028040400E2001A54
+:1004F00000E2001A00D4401A00CA380000CC0803F9
+:1005000000CC0C0300CC0C0300CC0C03009882BD83
+:1005100000000000008401BB00D7A06F0080000035
+:1005200000EE001F00CA040000C2FF0000CC083427
+:1005300000C13FFF007C74CB007CC90B007D010F24
+:10054000009902B0007C738B008401BB00D7A06FC0
+:100550000080000000EE001F00CA080000281900FB
+:10056000007D898B009580140028140400CA0C00BB
+:1005700000CA100000CA1C0000CA240000E2001FCC
+:1005800000D4C01A00D5001A00D5401A00CC1803B8
+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
+:1005A000007D9C4700984297000000000080016198
+:1005B00000D4C01A00D4401E00D4801E0080000069
+:1005C00000EE001E00E4011E00D4001E00D4401EF8
+:1005D00000EE001E00CA040000A00000007E828B16
+:1005E00000E4013E00D4001E00D4401E00EE001EB8
+:1005F00000CA040000A00000007E828B00CA080030
+:1006000000248C06000CCC060098C00600CC104ECE
+:100610000099000400D4007300E4011E00D4001E01
+:1006200000D4401E00D4801E0080000000EE001E9A
+:1006300000CA080000CA0C000034D01800251001C0
+:100640000095002100C17FFF00CA100000CA1400FD
+:1006500000CA180000D4801D00D4C01D007DB18BDD
+:1006600000C1420200C2C00100D5801D0034DC0E72
+:10067000007D5D4C007F734C00D7401E00D5001EEE
+:1006800000D5401E00C1420000C2C00000099C010C
+:100690000031DC10007F5F4C007F734C00042802A7
+:1006A000007D838000D5A86F00D5806600D7401EEE
+:1006B00000EC005E00C8240200C82402008001B8DB
+:1006C00000D6007600D4401E00D4801E00D4C01E88
+:1006D0000080000000EE001E0080000000EE001F01
+:1006E00000D4001F0080000000D4001F00D4001FB1
+:1006F0000088000000D4001F00000000000000007F
+:1007000000000000000000000000000000000000E9
+:1007100000000000000000000000000000000000D9
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:1008000000010171000201780003008F0004007FE5
+:10081000000500030006003F000700320008012C1D
+:1008200000090046000A0036001001B6001700A2B9
+:100830000022013A00230149002000B400240125D0
+:100840000027004D0028006A002A0060002B00529B
+:10085000002F0065003200870034017F003C015604
+:10086000003F00720041018C0044012E00550173CD
+:100870000056017A0060000B00610034006200380D
+:1008800000630038006400380065003800660038F6
+:10089000006700380068003A00690041006A0048BB
+:1008A000006B0048006C0048006D0048006E004876
+:1008B000006F00480000000600000006000000066F
+:1008C0000000000600000006000000060000000610
+:1008D0000000000600000006000000060000000600
+:1008E00000000006000000060000000600000006F0
+:1008F00000000006000000060000000600000006E0
+:00000001FF
diff --git a/firmware/radeon/RV620_me.bin.ihex b/firmware/radeon/RV620_me.bin.ihex
new file mode 100644
index 0000000..ba19ed8
--- /dev/null
+++ b/firmware/radeon/RV620_me.bin.ihex
@@ -0,0 +1,1345 @@
+:1000000000000000C020040000000000000000000C
+:1000100000A0000A000000000000FFFF00284621A9
+:100020000000000000000000D900480000000000AF
+:1000300000000000C02004000000000000000000DC
+:1000400000A0000A000000000000000000E0000026
+:100050000000000000010000C02946200000000050
+:1000600000000000D900480000000000000000006F
+:10007000C0200400000000000000000000A0000AF2
+:10008000000000008100000000204411000000007A
+:1000900000000001002048110000000000042004BE
+:1000A000006044110000068D0000000000600000A8
+:1000B000000006310000000000600000000006455E
+:1000C00000000000C02008000000000000000F0039
+:1000D000002816220000000000000008002116255C
+:1000E000000000000000001800203625000000007D
+:1000F0008D000000002044110000000000000004FA
+:10010000002F022500000000000000000CE00000AD
+:1001100000000018004120000040481100000019B4
+:100120000042200000204811000000008E00000066
+:1001300000204411000000000000002800204A2D8B
+:1001400000000000900000000020441100000000AA
+:100150000000000000204805000000000000000C26
+:1001600000211622000000000000000300281625D0
+:10017000000000000000001900211A220000000009
+:100180000000000400281A26000000000000000003
+:10019000002914C5000000000000001900203625C9
+:1001A0000000000000000000003A140200000000FF
+:1001B00000000016002116250000000000000003CA
+:1001C00000281625000000000000001700200E2D5A
+:1001D00000000000FFFFFFFC00280E2300000000CD
+:1001E00000000000002914A3000000000000001718
+:1001F00000203625000000000000800000280E22AC
+:10020000000000000000000700220E230000000094
+:10021000000000000029386E0000000020000000EF
+:1002200000280E22000000000000000600210E231E
+:1002300000000000000000000029386E00000000EF
+:100240000000000000220222000000000000000068
+:1002500014E0000000000038000000002EE0000064
+:1002600000000035000000002CE000000000003716
+:100270000000000000400E2D0000003900000008C2
+:1002800000200E2D00000000000000090040122D8B
+:10029000000000460000000100400E2D0000003963
+:1002A00000000000C0200C0000000000003FFFFC28
+:1002B0000028122300000000000000020022122487
+:1002C000000000000000001F00211E2300000000AD
+:1002D0000000000014E000000000003E00000008E4
+:1002E00000401C11000000410000000D00201E2DE8
+:1002F000000000000000000F00281E270000000082
+:100300000000000300221E27000000007FC0000044
+:1003100000281A23000000000000001400211A2603
+:10032000000000000000000100331A260000000059
+:100330000000000800221A26000000000000000053
+:1003400000290CC700000000000000270020362410
+:100350000000000000007F000028122100000000C3
+:1003600000001400002F0224000000000000000024
+:100370000CE000000000004B0000000100290E23EB
+:10038000000000000000000E0020362300000000E6
+:100390000000E0000020441100000000FFF8000011
+:1003A00000294A230000000000000000003A2C024F
+:1003B000000000000000000200220E2B00000000E0
+:1003C000FC00000000280E23000000000000000FC9
+:1003D000002036230000000000001FFF00294A23F0
+:1003E000000000000000002700204A2D000000004F
+:1003F000000000000020481100000000000000295B
+:1004000000200E2D00000000060A020000294A23E9
+:100410000000000000000000002048110000000063
+:100420000000000000204811000000000000000152
+:1004300000210222000000000000000014E0000083
+:1004400000000061000000002EE000000000005FDE
+:10045000000000002CE000000000005E0000000032
+:1004600000400E2D000000620000000100400E2D33
+:10047000000000620000000A00200E2D00000000B5
+:100480000000000B0040122D0000006A0000000078
+:10049000C0200C0000000000003FFFFC00281223D9
+:1004A00000000000000000020022122400000000F2
+:1004B0007FC0000000281623000000000000001488
+:1004C0000021162500000000000000010033162561
+:1004D000000000008000000000280E230000000043
+:1004E0000000000000290CA3000000003FFFFC00FA
+:1004F00000290E23000000000000001F00211E2321
+:10050000000000000000000014E000000000006D8A
+:100510000000010000401C11000000700000000DF0
+:1005200000201E2D00000000000000F000281E2703
+:10053000000000000000000400221E270000000050
+:100540008100000000204411000000000000000DA8
+:100550000020481100000000FFFFF0FF00281A30C3
+:10056000000000000000A02800204411000000004E
+:1005700000000000002948E6000000000000A0186C
+:1005800000204411000000003FFFFFFF00284A2325
+:10059000000000000000A010002044110000000036
+:1005A00000000000002048040000000000000030AF
+:1005B0000020162D00000000000000020029162572
+:1005C0000000000000000030002036250000000080
+:1005D000000000250020162D000000000000000093
+:1005E000002F00A300000000000000000CC000006D
+:1005F00000000083000000260020162D00000000EF
+:1006000000000000002F00A4000000000000000017
+:100610000CC000000000008400000000004000004A
+:100620000000008A000000250020362300000000A2
+:100630000000002600203624000000000000001703
+:1006400000201E2D000000000000000200210227F3
+:10065000000000000000000014E000000000008A1C
+:1006600000000000006000000000066800000000BC
+:10067000006000000000065C0000000200210E2265
+:10068000000000000000000014C000000000008D09
+:1006900000000012C040362000000093000000005F
+:1006A0002EE0000000000091000000002CE000009F
+:1006B000000000900000000200400E2D000000929B
+:1006C0000000000300400E2D000000920000000C0E
+:1006D00000200E2D00000000000000120020362334
+:1006E000000000000000000300210E2200000000B6
+:1006F0000000000014C00000000000980000A00CE2
+:10070000002044110000000000000000C02048004C
+:100710000000000000000000C0404800000000A0F1
+:100720000000A00C002044110000000000000000A8
+:100730000020481100000000000000002EE0000032
+:100740000000009E000000002CE000000000009D62
+:100750000000000200400E2D0000009F000000037A
+:1007600000400E2D0000009F0000000C00200E2D08
+:10077000000000000000000000204803000000000E
+:1007800000000000003A0C0200000000003F0000E2
+:1007900000280E23000000000000001000210E239E
+:1007A00000000000000000110020362300000000BF
+:1007B0000000001E0021022B0000000000000000CD
+:1007C00014C00000000000A700000016C020362062
+:1007D000000000000000001F0021022B00000000AC
+:1007E0000000000014C00000000000AA0000001576
+:1007F000C0203620000000000000000800210E2B61
+:10080000000000000000007F00280E230000000010
+:1008100000000000002F0223000000000000000084
+:100820000CE00000000000E10000000027000000D4
+:10083000000000000000000000600000000002A3B3
+:1008400000000001002F0223000000000000000053
+:100850000AE00000000000B300000000006000009B
+:100860000000013A81000000002044110000000057
+:100870000000000600204811000000000000000CED
+:1008800000221E300000000099800000002044116A
+:1008900000000000000000040020122D00000000F5
+:1008A00000000008002212240000000000000010D8
+:1008B00000201811000000000000000000291CE4C6
+:1008C0000000000000000000006048070000012F49
+:1008D0009B00000000204411000000000000000008
+:1008E00000204802000000009C000000002044118D
+:1008F00000000000000000000033146F0000000042
+:100900000000000100333E23000000000000000052
+:10091000D9004800000000000000000000203C0555
+:1009200000000000810000000020441100000000D1
+:100930000000000E00204811000000000000000030
+:1009400000201010000000000000E007002044110B
+:10095000000000000000000F0021022B000000003A
+:100960000000000014C00000000000CB00F8FF08E9
+:1009700000204811000000009800000000404811CD
+:10098000000000DC000000F000280E220000000043
+:10099000000000A0002F0223000000000000000063
+:1009A0000CC00000000000DA0000001100200E2D35
+:1009B0000000000000000001002F022300000000E2
+:1009C000000000000CE00000000000D50000000264
+:1009D000002F022300000000000000000CE00000D7
+:1009E000000000D400003F0000400C11000000D6C1
+:1009F00000001F0000400C11000000D600000F0096
+:100A000000200C11000000000038000900294A23D2
+:100A1000000000003F00000000280E2B0000000036
+:100A20000000000200220E2300000000000000076A
+:100A300000494A23000000DC00380F09002048115B
+:100A400000000000680000070020481100000000BE
+:100A50000000000800214A270000000000000000FC
+:100A60000020481100000000060A020000294A2464
+:100A700000000000000000000020481100000000FD
+:100A80000000000000204811000000000000A20249
+:100A9000002044110000000000FF000000280E228A
+:100AA000000000000000008000294A230000000030
+:100AB0000000002700200E2D00000000000000268E
+:100AC0000020122D0000000000000000002F008315
+:100AD00000000000000000000CE00000000000EA40
+:100AE000000000000060000000000662000000003E
+:100AF00000400000000000EB00000000006000006B
+:100B000000000665000000070020222D0000000004
+:100B10000000000500220E2200000000001000006E
+:100B200000280E23000000000000000000292068BB
+:100B30000000000000000000003A0C02000000006D
+:100B4000000000EF00280E2300000000000000005D
+:100B500000292068000000000000001700200E2D72
+:100B6000000000000000000300210223000000003C
+:100B70000000000014E00000000000F80000000B7E
+:100B800000210228000000000000000014C0000046
+:100B9000000000F8000004000029222800000000E6
+:100BA0000000001400203628000000000000001C97
+:100BB00000210E22000000000000000014C0000010
+:100BC000000000FD0000A30C002044110000000004
+:100BD0000000000000204811000000000000001E7E
+:100BE00000210E22000000000000000014C00000E0
+:100BF0000000010B0000A30F0020441100000000C2
+:100C00000000001100200E2D000000000000000177
+:100C1000002F022300000000000000000CC00000B4
+:100C200000000104FFFFFFFF004048110000010B1E
+:100C300000000002002F022300000000000000005E
+:100C40000CC00000000001070000FFFF0040481139
+:100C50000000010B00000004002F02230000000030
+:100C6000000000000CC000000000010A000000FFAE
+:100C7000004048110000010B000000010020481155
+:100C8000000000000002C400002044110000000029
+:100C90000000001F00210E220000000000000000E4
+:100CA00014C00000000001120000001040210E20BE
+:100CB00000000000000000130020362300000000A8
+:100CC0000000001840224A20000000000000001030
+:100CD000C0424A20000001140000000000200C1156
+:100CE0000000000000000013002036230000000078
+:100CF000000000000020481100000000000000007B
+:100D000000204811000000000000000A002010111F
+:100D10000000000000000000002F0224000000007E
+:100D2000000000000CE000000000011B00000000BB
+:100D300000204811000000000000000100531224B0
+:100D400000000117FFBFFFFF00283A2E000000003F
+:100D50000000001B00210222000000000000000033
+:100D600014C000000000012E81000000002044118A
+:100D7000000000000000000D0020481100000000ED
+:100D80000000001800220E3000000000FC000000EF
+:100D900000280E2300000000810000000020441104
+:100DA000000000000000000E0020481100000000BC
+:100DB0000000000000201010000000000000E00E05
+:100DC000002044110000000007F8FF08002048112F
+:100DD000000000000000000000294A23000000007D
+:100DE0000000001C00201E2D000000000000000874
+:100DF00000214A27000000000000000000204811E8
+:100E000000000000060A020000294A240000000039
+:100E10000000000000204811000000000000000059
+:100E200000204811000000000000000000800000C9
+:100E300000000000810000000020441100000000BC
+:100E40000000000100204811000000000000217C8B
+:100E50000020441100000000008000000020481124
+:100E60000000000000000000002048060000000014
+:100E70000000000800214A270000000000000000D8
+:100E800017000000000000000004217F00604411F2
+:100E90000000068D0000001F00210230000000004D
+:100EA0000000000014C000000000068C00000004D8
+:100EB00000404C1100000135810000000020441169
+:100EC00000000000000000010020481100000000A8
+:100ED000000021F800204411000000000000001C68
+:100EE0000020481100000000000421F900604411B6
+:100EF0000000068D000000110021023000000000FB
+:100F00000000000014E000000000013C00000000B0
+:100F100000800000000000000000000000600000F1
+:100F20000000000B00000000006004110000031529
+:100F3000000000000020041100000000000000007C
+:100F400000600811000001B2000000000060000015
+:100F5000000001600000FFFF40280E20000000009C
+:100F600000000010C0211220000000000000FFFF60
+:100F7000402806200000000000000010C0210A20C8
+:100F800000000000000000000034146100000000B8
+:100F90000000000000741882000002BB0001A1FDE7
+:100FA00000604411000002E000003FFF002F022F0C
+:100FB00000000000000000000CC00000000001471D
+:100FC00000000000C040040000000001000000001C
+:100FD000006000000000000B000000000060041131
+:100FE00000000315000000000020041100000000B4
+:100FF0000000000000600811000001B200003FFF87
+:10100000002F022F00000000000000000CE0000094
+:10101000000000000000000000600000000001600F
+:101020000000001040210E20000000000000FFFF23
+:10103000C0281220000000000000001040211620EF
+:10104000000000000000FFFFC0681A20000002BB83
+:101050000001A1FD00604411000002E000003FFF1C
+:10106000002F022F00000000000000000CC0000054
+:101070000000015800000000C04004000000000112
+:101080000000225C0020441100000000000000016C
+:1010900000300A2F000000000000000100210A2299
+:1010A000000000000000000300384A220000000099
+:1010B0000000225600204411000000000000001A29
+:1010C00000204811000000000000A1FC0020441195
+:1010D0000000000000000001008048110000000036
+:1010E00000000000006000000000000B0000000095
+:1010F000006000000000018F0000000000600000A0
+:10110000000001A000003FFF002F022F00000000A0
+:10111000000000000CE000000000000000000000E3
+:1011200000202C0800000000000000000020241116
+:101130000000000000000000002028110000000056
+:10114000000022560020441100000000000000169C
+:1011500000204811000000000000225C0020441123
+:101160000000000000000003002048110000000003
+:1011700093800000002044110000000000000002E5
+:1011800000221E290000000000000000007048EB53
+:101190000000019C0000000000600000000002BB95
+:1011A00000000001403306200000000000000000A5
+:1011B000C03024090000000000003FFF002F022F74
+:1011C00000000000000000000CE000000000000033
+:1011D0000000000000600000000002A3000000000A
+:1011E000002F022100000000000000000AE00000C3
+:1011F0000000018100000000006000000000013AD2
+:101200000000000000400000000001869500000082
+:10121000002044110000000000000000002F022107
+:1012200000000000000000000CE00000000001864B
+:1012300000000000C0204800000000000000000185
+:10124000005306210000018292000000002044119A
+:101250000000000000000000C0604800000001978E
+:101260000001A1FD00204411000000000000001159
+:101270000020062D00000000000000000078042A75
+:10128000000002FB00000000002028090000000010
+:1012900000003FFF002F022F0000000000000000B0
+:1012A0000CC000000000017400000000C0400400F9
+:1012B000000000010000021000600411000003158E
+:1012C00000003FFF002F022F000000000000000080
+:1012D0000CE000000000019400000015C020362042
+:1012E0000000000000000016C020362000000000B2
+:1012F0003F800000002004110000000046000000B4
+:1013000000600811000001B2000000000080000031
+:10131000000000000000A1FC0020441100000000BB
+:1013200000003FFF002F022F00000000000000001F
+:101330000CC000000000019B00000001008048116B
+:1013400000000000000000210080481100000000A3
+:101350000000FFFF40280E200000000000000010E9
+:10136000C0211220000000000000FFFF40281620CE
+:101370000000000000000010C0811A2000000000E2
+:101380008100000000204411000000000000000661
+:1013900000204811000000000000000800221E305C
+:1013A000000000000000002900201A2D00000000AD
+:1013B0000000E0000020441100000000FFFBFF09D6
+:1013C00000204811000000000000000F0020222D26
+:1013D0000000000000001FFF00294A280000000054
+:1013E000000000060020222D000000000000000088
+:1013F000002920E80000000000000000002048084C
+:101400000000000000000000002048110000000063
+:10141000060A020000294A26000000000000000021
+:1014200000204811000000000000000000204811CA
+:101430000000000000000100002018110000000062
+:101440000000000800621E280000012F00000008B4
+:1014500000822228000000000002C0000020441189
+:10146000000000000000001500600E2D000001BD0E
+:101470000000001600600E2D000001BD0000C00835
+:1014800000204411000000000000001700200E2D75
+:10149000000000000000000014C00000000001B9BE
+:1014A0000000000000200411000000000000000007
+:1014B0000020480100000000390000000020481111
+:1014C00000000000000000000020481100000000A3
+:1014D000000000000080480200000000000000182A
+:1014E00000202E2D0000000000000000003B0D63D6
+:1014F000000000000000000800224A230000000055
+:101500000000001000224A23000000000000001824
+:1015100000224A2300000000000000000080480371
+:101520000000000000000000006000000000000B50
+:10153000000010000060041100000315000000000E
+:1015400000200411000000000000000000600811ED
+:10155000000001B2000000070021062F000000007B
+:101560000000001300200A2D000000000000000110
+:1015700000202C11000000000000FFFF4028222066
+:10158000000000000000000F0026222800000000DC
+:101590000000001040212620000000000000000F85
+:1015A000002626290000000000000000002028027C
+:1015B000000000000000225600204411000000003E
+:1015C0000000001B00204811000000000000000087
+:1015D000002F022100000000000000000CE00000CD
+:1015E000000001E00000225C002044110000000027
+:1015F0000000008100204811000000000000A1FC54
+:1016000000204411000000000000000100204811EB
+:10161000000000000000008000201C1100000000FD
+:1016200000000000002F0227000000000000000062
+:101630000CE00000000001DC000000000060000081
+:10164000000001E90000000100531E27000001D83E
+:101650000000000100202C11000000000000001F0D
+:1016600000280A22000000000000001F00282A2A8B
+:10167000000000000000000100530621000001D11D
+:101680000000225C00204411000000000000000265
+:1016900000304A2F000000000000A1FC002044118F
+:1016A00000000000000000010020481100000000C0
+:1016B0000000000100301E2F0000000000000000AC
+:1016C000002F022700000000000000000CE00000D6
+:1016D000000000000000000000600000000001E9C0
+:1016E0000000000100531E27000001E50000FFFF7D
+:1016F00040280E20000000000000000F00260E23EE
+:101700000000000000000010C021122000000000B6
+:101710000000000F0026122400000000000000005E
+:1017200000201411000000000000000000601811EB
+:10173000000002BB0001A1FD0020441100000000D8
+:1017400000000000002F022B00000000000000003D
+:101750000CE00000000001F8000000100022162834
+:1017600000000000FFFF0000002816250000000018
+:101770000000FFFF00281A29000000000000000000
+:10178000002948C500000000000000000020480AB1
+:10179000000000000000000000202C1100000000EC
+:1017A000000000100022162300000000FFFF0000D0
+:1017B00000281625000000000000FFFF00281A2462
+:1017C0000000000000000000002948C500000000E3
+:1017D0000000000000731503000002050000000077
+:1017E0000020180500000000000000000073152410
+:1017F0000000020500000000002D14C500000000DC
+:1018000000000000003008A20000000000000000FE
+:101810000020480200000000000000000020280214
+:101820000000000000000000002020030000000075
+:101830000000000000802404000000000000000FF1
+:1018400000210225000000000000000014C000007C
+:101850000000068C00000000002B140500000000B2
+:1018600000000001009016250000000000000000AC
+:10187000006000000000000B000000000060041188
+:10188000000003150000000000200411000000000B
+:101890000000000000600811000001B200002256A4
+:1018A00000204411000000000000001A00294A2214
+:1018B0000000000000000000C02000000000000048
+:1018C00000003FFF002F022F00000000000000007A
+:1018D0000CE000000000000000000000C020040038
+:1018E000000000000000225C002044110000000005
+:1018F0000000000300384A21000000000000A1FCA5
+:1019000000204411000000000000000100204811E8
+:10191000000000000000FFFF40281220000000002F
+:1019200000000010C0211A20000000000000FFFF8E
+:1019300040280E200000000000000010C0211620EA
+:10194000000000000000000000741465000002BBED
+:101950000001A1FD00604411000002E00000000150
+:10196000003306210000000000000000002F0221CB
+:1019700000000000000000000CC000000000021980
+:1019800000003FFF002F022F0000000000000000B9
+:101990000CC000000000021200000000C040040063
+:1019A000000000010000000000600000000006458B
+:1019B000000000000040040F0000021300000000BF
+:1019C0000060000000000631000000000060000020
+:1019D000000006450000021000600411000003151D
+:1019E0000000000000600000000001A000000000F6
+:1019F000006000000000019C00000000006000008A
+:101A0000000002BB0000000000600000000002A314
+:101A1000938000000020441100000000000000003E
+:101A2000002048080000000000000000002F022FE6
+:101A300000000000000000000AE000000000023288
+:101A400000000000006000000000013A00000000FB
+:101A50000040000000000236950000000020441104
+:101A60000000000000000000002F022F0000000016
+:101A7000000000000CE00000000002360000000042
+:101A8000C0404800000002339200000000204411D2
+:101A90000000000000000000C0204800000000001E
+:101AA0000000225600204411000000000000001633
+:101AB00000204811000000000000225C00204411BA
+:101AC000000000000000000300204811000000009A
+:101AD0000000A1FC002044110000000000000001F3
+:101AE00000204811000000000001A1FD0020441169
+:101AF000000000000000000000600411000002FB74
+:101B000000000000C04004000000000100000000D0
+:101B100000600000000006310000A00C002044110D
+:101B20000000000000000000C0204800000000008D
+:101B300000000000C040480000000000000000005D
+:101B4000006000000000000B0000001840210A2087
+:101B50000000000000000003002F0222000000002F
+:101B6000000000000AE000000000024C0000001429
+:101B70000020222D00000000000801010029222879
+:101B800000000000000000140020362800000000C3
+:101B90000000A30C00204411000000000000000021
+:101BA000C02048000000000000000000C0204800E5
+:101BB0000000000000000000C0404800000002518A
+:101BC00000000000006000000000000B000000109A
+:101BD00000600411000003153F8000000020041184
+:101BE000000000000000000000600811000001B2C9
+:101BF0000000225C002044110000000000000003EF
+:101C000000204811000000000000000000600000FB
+:101C10000000027C0000001700201E2D00000000C4
+:101C20000000000100211E2700000000000000004D
+:101C300014E000000000026A0000001200201E2DC7
+:101C4000000000000000FFFF00281E270000000029
+:101C50000000000000341C2700000000000000000D
+:101C600012C000000000025F0000000000201C11F4
+:101C70000000000000000000002F00E50000000050
+:101C80000000000008C00000000002620000000028
+:101C900000201407000000000000001200201E2D8C
+:101CA000000000000000001000211E2700000000BE
+:101CB0000000000000341C4700000000000000008D
+:101CC00012C00000000002670000000000201C118C
+:101CD0000000000000000000002F00E600000000EF
+:101CE0000000000008C000000000026A00000000C0
+:101CF0000020180700000000000000000060000045
+:101D0000000002C100002256002044110000000023
+:101D1000000000000034202300000000000000004C
+:101D200012C00000000002720000000000342044D5
+:101D3000000000000000000012C00000000002715E
+:101D40000000001600404811000002760000001854
+:101D500000404811000002760000000000342044DA
+:101D6000000000000000000012C00000000002752A
+:101D70000000001700404811000002760000001922
+:101D800000204811000000000000A1FC00204411C8
+:101D900000000000000000010020481100000000C9
+:101DA0000001A1FD00604411000002E900003FFFB6
+:101DB000002F022F00000000000000000CC00000F7
+:101DC0000000025600000000C040040000000001B6
+:101DD0000000001040210620000000000000FFFF6E
+:101DE000C0280A20000000000000001040210E2042
+:101DF000000000000000FFFFC028122000000000CB
+:101E00000000001040211620000000000000FFFF2D
+:101E1000C0881A200000000081000000002044114A
+:101E20000000000000000001002048110000000038
+:101E300000042004006044110000068D0000000032
+:101E4000006000000000063100000000C0600000DB
+:101E5000000002A30000000500200A2D0000000081
+:101E60000000000800220A22000000000000002BF1
+:101E700000201A2D000000000000001C00201E2D74
+:101E8000000000000000700000281E270000000075
+:101E90000000000000311CE6000000000000002AE5
+:101EA00000201A2D000000000000000C00221A265D
+:101EB0000000000000000000002F00E6000000000D
+:101EC0000000000006E00000000002920000000098
+:101ED00000201C11000000000000000000200C1178
+:101EE000000000000000002B00203623000000004E
+:101EF0000000001000201811000000000000000089
+:101F000000691CE20000012F9380000000204411B2
+:101F10000000000000000000002048070000000052
+:101F200095000000002044110000000000000000A7
+:101F3000002F022F00000000000000000CE0000055
+:101F40000000029D0000000100333E2F0000000051
+:101F500000000000D90048000000000092000000CE
+:101F6000002044110000000000000000C0204800D4
+:101F7000000000000000001C0040362700000000A8
+:101F80000000000CC0220A20000000000000002910
+:101F9000002036220000000000000028C04036204B
+:101FA000000000000000A2A4002044110000000076
+:101FB000000000090020481100000000A1000000FE
+:101FC00000204411000000000000000100804811C2
+:101FD000000000000000002100201E2D0000000075
+:101FE00000000000002C1CE30000000000000021A5
+:101FF00000203627000000000000002200201E2DD7
+:102000000000000000000000002C1CE400000000A4
+:1020100000000022002036270000000000000023FE
+:1020200000201E2D0000000000000000003120A351
+:102030000000000000000000002D1D07000000004F
+:1020400000000023002036270000000000000024CC
+:1020500000201E2D0000000000000000003120C400
+:102060000000000000000000002D1D07000000001F
+:10207000000000240080362700000000000000213E
+:10208000002036230000000000000022002036243B
+:10209000000000000000000000311CA30000000050
+:1020A0000000002300203627000000000000000090
+:1020B00000311CC40000000000000024008036270E
+:1020C000000000000000001A002036270000000079
+:1020D0000000001B00203628000000000000001750
+:1020E00000201E2D00000000000000020021022739
+:1020F000000000000000000014C00000000002DC2E
+:102100000000000000400000000002D90000001A9A
+:1021100000203627000000000000001B00203628A9
+:10212000000000000000001700201E2D000000002D
+:102130000000000200210227000000000000000053
+:1021400014E00000000002D9000000030021022773
+:10215000000000000000000014E00000000002DCAD
+:102160000000002300201E2D0000000000000000E1
+:10217000002E00E1000000000000000002C000008E
+:10218000000002DC0000002100201E2D00000000E5
+:1021900000000000003120A100000000000000004D
+:1021A000002E00E8000000000000000006C0000053
+:1021B000000002DC0000002400201E2D00000000B2
+:1021C00000000000002E00E20000000000000000FF
+:1021D00002C00000000002DC0000002200201E2DD2
+:1021E0000000000000000000003120C200000000DC
+:1021F00000000000002E00E80000000000000000C9
+:1022000006C00000000002DC0000000000600000CA
+:10221000000006680000000000600000000002B539
+:102220000000000000400000000002DE000000008E
+:1022300000600000000002B5000000000060000027
+:102240000000065F0000000000400000000002DE09
+:102250000000000000600000000002A70000000075
+:1022600000400000000002DE0000001A00201E2DC9
+:10227000000000000000001B0080222D0000000074
+:102280000000001000221E230000000000000000DB
+:1022900000294887000000000000000000311CA356
+:1022A000000000000000001000221E2700000000B7
+:1022B0000000000000294887000000000000001016
+:1022C00000221E230000000000000000003120C496
+:1022D000000000000000FFFF00282228000000008E
+:1022E0000000000000894907000000000000001005
+:1022F00000221E2300000000000000000029488783
+:10230000000000000000001000221E21000000005C
+:102310000000000000294847000000000000000005
+:1023200000311CA3000000000000001000221E2746
+:1023300000000000000000000029488700000000A5
+:102340000000000000311CA100000000000000108F
+:1023500000221E270000000000000000002948475E
+:10236000000000000000001000221E2300000000FA
+:1023700000000000003120C4000000000000FFFF4A
+:102380000028222800000000000000000029490762
+:10239000000000000000001000221E2100000000CC
+:1023A00000000000003120C2000000000000FFFF1C
+:1023B00000282228000000000000000000894907D2
+:1023C000000000000000001000221E23000000009A
+:1023D0000000000000294887000000000000000104
+:1023E00000220A210000000000000000003308A2C3
+:1023F000000000000000001000221E22000000006B
+:102400000000001000212222000000000000000057
+:1024100000294907000000000000000000311CA353
+:10242000000000000000001000221E270000000035
+:1024300000000000002948870000000000000001A3
+:1024400000220A210000000000000000003008A265
+:10245000000000000000001000221E22000000000A
+:1024600000000010002122220000000000000000F7
+:1024700000294907000000000000001000221E2370
+:102480000000000000000000003120C40000000037
+:102490000000FFFF002822280000000000000000CC
+:1024A000002949070000000000000000003808C5AE
+:1024B00000000000000000000030084100000000A3
+:1024C0000000000100220A220000000000000000BD
+:1024D000003308A2000000000000001000221E22AD
+:1024E0000000000000000010002122220000000077
+:1024F00000000000008949070000000000000017EC
+:102500000020222D000000000000000014C0000088
+:1025100000000318FFFFFFEF002806210000000065
+:10252000000000140020222D000000000000F8E050
+:1025300000204411000000000000000000294901B3
+:1025400000000000000000000089490100000000B8
+:102550000000000000204811000000000000000002
+:102560000020481100000000060A02000080481107
+:102570000000000000000000C0200000000000007B
+:1025800097000000C020441100000000000000007F
+:10259000C0204811000000008A0000000020441103
+:1025A00000000000000000000020481100000000B2
+:1025B0000000225C00204411000000000000000028
+:1025C000C0204800000000000000A1FC00204411D1
+:1025D0000000000000000000C020480000000000D3
+:1025E00000000000C0200400000000000000000007
+:1025F00000A0000A00000000970000000020441125
+:102600000000000000000000002048110000000051
+:102610008A000000002044110000000000000000BB
+:1026200000204811000000000000225C002044113E
+:102630000000000000000000C02048000000000072
+:102640000000A1FC00204411000000000000000078
+:10265000C02048000000000000000000C02004006E
+:10266000000000000000000000A0000A00000000C0
+:10267000970000000020441100000000000000004E
+:1026800000204811000000008A00000000204411D2
+:1026900000000000000000000020481100000000C1
+:1026A0000000225C00204411000000000000000037
+:1026B000C0204800000000000000A1FC00204411E0
+:1026C0000000000000000000C020480000000000E2
+:1026D0000001A1FD002044110000000000000000E6
+:1026E000D90048000000000000000000C0200400E5
+:1026F000000000000000000000A0000A0000000030
+:1027000000002257002044110000000000000003D8
+:10271000C0484A20000000000000225D0020441153
+:102720000000000000000000C04048000000000061
+:1027300000000000006000000000064500000000EE
+:10274000C0200800000000000000225C00204411AE
+:10275000000000000000000300384A2200000000D2
+:102760000000A1FC00204411000000000000000057
+:10277000C0204800000000000001A1FD002044111D
+:102780000000000000000000002F022200000000F6
+:10279000000000000CE0000000000000000000004D
+:1027A00040204800000000000000000140304A20A6
+:1027B0000000000000000002C0304A2000000000BD
+:1027C0000000000100530A220000034B0000003FFC
+:1027D000C0280A20000000008100000000204411F1
+:1027E000000000000000000100204811000000006F
+:1027F000000021F800204411000000000000001833
+:102800000020481100000000000421F9006044117C
+:102810000000068D000000110021023000000000C1
+:102820000000000014E00000000003540000001449
+:10283000002F022200000000000000000CC0000079
+:10284000000003640000201000204411000000007C
+:102850000000800000204811000000000001A2A438
+:102860000020441100000000000000000060480249
+:102870000000036E00002100002044110000000051
+:1028800000000000C0204800000000000000000020
+:10289000C02048000000000000000000C0204800E8
+:1028A0000000000000000000C040480000000000E0
+:1028B00000000004002F02220000000000000000C1
+:1028C0000CC000000000036A00002010002044112A
+:1028D00000000000000080000020481100000000FF
+:1028E0000001A2A40020441100000000000000002C
+:1028F000004048020000035F00000028002F022271
+:1029000000000000000000000CC00000000005C036
+:102910000001A2A4002044110000000000000000FB
+:10292000004048020000035F0000002C0020362613
+:102930000000000000000049002018110000000005
+:102940000000003F002048110000000000000001CE
+:1029500000331A260000000000000000002F0226AD
+:1029600000000000000000000CC000000000037028
+:102970000000002C00801A2D000000000000003F25
+:10298000C0280A200000000000000015002F0222CD
+:1029900000000000000000000CE0000000000386C2
+:1029A00000000006002F02220000000000000000CE
+:1029B0000CE00000000003B100000016002F02220E
+:1029C00000000000000000000CE00000000003B563
+:1029D00000000020002F0222000000000000000084
+:1029E0000CE000000000039C0000000F002F0222FA
+:1029F00000000000000000000CE00000000003A840
+:102A000000000010002F0222000000000000000063
+:102A10000CE00000000003A80000001E002F0222AE
+:102A200000000000000000000CE000000000039027
+:102A30000000A2A4002044110000000000000000DB
+:102A400000404802000000000800000000290A229F
+:102A5000000000000000000340210E2000000000E4
+:102A60000000000CC021122000000000000800003F
+:102A7000002812240000000000000014C0221620CC
+:102A80000000000000000000002914A40000000065
+:102A90000000A2A40020441100000000000000007B
+:102AA000002948A2000000000000A1FE00204411FF
+:102AB000000000000000000000404803000000008B
+:102AC000810000000020441100000000000000010F
+:102AD0000020481100000000000021F800204411EF
+:102AE0000000000000000016002048110000000057
+:102AF000000421F9006044110000068D000000155B
+:102B000000210230000000000000000014E000007E
+:102B1000000003920000210E00204411000000007C
+:102B200000000000C020480000000000000000007D
+:102B3000C0204800000000000000A2A400204411B2
+:102B400000000000000000000040480200000000FB
+:102B5000810000000020441100000000000000017E
+:102B60000020481100000000000021F8002044115E
+:102B700000000000000000170020481100000000C5
+:102B8000000421F9006044110000068D00000003DC
+:102B900000210230000000000000000014E00000EE
+:102BA0000000039E000021080020441100000000E6
+:102BB00000000000C02048000000000000000000ED
+:102BC000C0204800000000000000A2A40020441122
+:102BD000000000000000000000404802000000006B
+:102BE0000000A2A40020441100000000000000002A
+:102BF0000020480200000000800000000020441176
+:102C0000000000000000000000204811000000004B
+:102C100081000000002044110000000000000010AE
+:102C200000204811000000000000000000200010FB
+:102C3000000000000000000014C00000000003AE0F
+:102C40000000000000400000000000000000201014
+:102C50000020441100000000000080000020481106
+:102C6000000000000001A2A40020441100000000A8
+:102C70000000000600404811000000000000201085
+:102C800000204411000000000000800000204811D6
+:102C9000000000000001A2A4002044110000000078
+:102CA00000000016006048110000036E00000000E4
+:102CB000004000000000000000000000C0200800EC
+:102CC0000000000000000000C0200C000000000018
+:102CD0000000001D00210223000000000000000091
+:102CE00014E00000000003CE810000000020441129
+:102CF000000000000000000100204811000000005A
+:102D0000000021F80020441100000000000000181D
+:102D10000020481100000000000421F90060441167
+:102D20000000068D000000110021023000000000AC
+:102D30000000000014E00000000003C000002100BB
+:102D400000204411000000000000000000204802A4
+:102D50000000000000000000002048030000000008
+:102D6000BABECAFE0020481100000000CAFEBABE6A
+:102D70000020481100000000000020100020441135
+:102D8000000000000000800000204811000000004A
+:102D90000000A2A400204411000000000000000474
+:102DA0000040481100000000000021700020441184
+:102DB00000000000000000000020480200000000A9
+:102DC0000000000000204803000000008100000017
+:102DD00000204411000000000000000A00204811FB
+:102DE00000000000000000000020001000000000B3
+:102DF0000000000014C00000000003D38C0000009D
+:102E00000020441100000000CAFEBABE0040481174
+:102E100000000000810000000020441100000000BC
+:102E200000000001002048110000000000003FFFEA
+:102E300040280A20000000008000000040280E20EA
+:102E40000000000040000000C02812200000000028
+:102E500000040000006946220000068D000000000A
+:102E6000002014100000000000000000002F0223CA
+:102E700000000000000000000CC00000000003E1A2
+:102E800000000000C0401800000003E400003FFF05
+:102E9000C0281A2000000000000400000069462637
+:102EA0000000068D00000000002018100000000047
+:102EB00000000000002F02240000000000000000BD
+:102EC0000CC00000000003E700000000C0401C0030
+:102ED000000003EA00003FFFC0281E2000000000A1
+:102EE00000040000006946270000068D0000000075
+:102EF00000201C1000000000000000000020440220
+:102F00000000000000000000002820C500000000B4
+:102F100000000000004948E800000000A580000013
+:102F200000200811000000000000200000200C110B
+:102F30000000000083000000006044110000041243
+:102F4000000000000020440200000000000000001B
+:102F5000C0204800000000000000000040204800A1
+:102F6000000000000000001FC0210220000000003F
+:102F70000000000014C00000000003F70000201053
+:102F800000204411000000000000800000204811D3
+:102F9000000000000000FFFFC0481220000003FFF7
+:102FA000A780000000200811000000000000A00021
+:102FB00000200C110000000083000000006044119C
+:102FC0000000041200000000002044020000000085
+:102FD00000000000C02048000000000000000000C9
+:102FE000C0204800000000000000FFFFC0281220A1
+:102FF00000000000830000000020441100000000D9
+:103000000000000000304883000000008400000041
+:10301000002044110000000000000000C020480013
+:1030200000000000000000001D0000000000000083
+:103030008300000000604411000004120000000042
+:10304000C040040000000001A98000000020081119
+:10305000000000000000C00000400C11000003FA56
+:10306000AB80000000200811000000000000F8E024
+:1030700000400C11000003FAAD8000000020081190
+:10308000000000000000F88000400C11000003FA6E
+:10309000B380000000200811000000000000F3FCD5
+:1030A00000400C11000003FAAF800000002008115E
+:1030B000000000000000E00000400C11000003FAD6
+:1030C000B180000000200811000000000000F000A6
+:1030D00000400C11000003FA83000000002044119E
+:1030E00000000000000021480020481100000000FE
+:1030F00084000000002044110000000000000000D7
+:10310000C020480000000000000000001D0000007A
+:10311000000000000000000000800000000000002F
+:1031200001182000C0304620000000000000000010
+:10313000D90048000000000000000000C02004008A
+:10314000000000000000000000A0000A00000000D5
+:103150000218A000C030462000000000000000005F
+:10316000D90048000000000000000000C02004005A
+:10317000000000000000000000A0000A00000000A5
+:103180000318C000C030462000000000000000000E
+:10319000D90048000000000000000000C02004002A
+:1031A000000000000000000000A0000A0000000075
+:1031B0000418F8E0C03046200000000000000000C5
+:1031C000D90048000000000000000000C0200400FA
+:1031D000000000000000000000A0000A0000000045
+:1031E0000518F880C03046200000000000000000F4
+:1031F000D90048000000000000000000C0200400CA
+:10320000000000000000000000A0000A0000000014
+:103210000618E000C030462000000000000000005A
+:10322000D90048000000000000000000C020040099
+:10323000000000000000000000A0000A00000000E4
+:103240000718F000C0304620000000000000000019
+:10325000D90048000000000000000000C020040069
+:10326000000000000000000000A0000A00000000B4
+:103270000818F3FCC03046200000000000000000E9
+:10328000D90048000000000000000000C020040039
+:10329000000000000000000000A0000A0000000084
+:1032A0000000003000200A2D000000000000000097
+:1032B000C0290C4000000000000000300020362330
+:1032C0000000000000000000C0200400000000001A
+:1032D0000000000000A0000A0000000086000000BE
+:1032E00000204411000000000000000000404801E0
+:1032F0000000000085000000C02044110000000014
+:103300000000000000404801000000000000217C97
+:10331000002044110000000000000018402102209D
+:10332000000000000000000014C000000000044580
+:1033300000800000C0494A20000004460000000050
+:10334000C02048000000000000000000C02048002D
+:103350000000000000000000C02048000000000045
+:103360008100000000204411000000000000000166
+:10337000002048110000000000000000C0200800EC
+:103380000000000000000000170000000000000026
+:103390000004217F006044110000068D0000001F22
+:1033A00000210230000000000000000014C00000F6
+:1033B000000000000000000000404C020000044B30
+:1033C00000000000C0200C00000000000000000011
+:1033D000C02010000000000000000000C020140009
+:1033E0000000000000000000C020180000000000E5
+:1033F00000000000C0201C000000000000007F0052
+:1034000000280A210000000000004500002F0222D1
+:1034100000000000000000000CE000000000045963
+:1034200000000000C020200000000000000000009C
+:1034300017000000000000000000001000280A2310
+:103440000000000000000010002F02220000000019
+:10345000000000000CE0000000000461810000009A
+:10346000002044110000000000000001002048116D
+:103470000000000000040000006946240000068DE2
+:103480000000000000400000000004668100000011
+:10349000002044110000000000000000002048113E
+:1034A000000000000000216D002044110000000019
+:1034B00000000000002048040000000000000000A0
+:1034C000006048050000069200000000002824F07B
+:1034D000000000000000000700280A230000000090
+:1034E00000000001002F0222000000000000000088
+:1034F0000AE000000000046D00000000002F00C979
+:10350000000000000000000004E00000000004864D
+:1035100000000000004000000000049300000002D2
+:10352000002F022200000000000000000AE000005E
+:103530000000047200000000002F00C9000000001D
+:103540000000000002E0000000000486000000000F
+:10355000004000000000049300000003002F02223E
+:1035600000000000000000000AE0000000000477F6
+:1035700000000000002F00C9000000000000000053
+:103580000CE0000000000486000000000040000085
+:103590000000049300000004002F0222000000003D
+:1035A000000000000AE000000000047C00000000B1
+:1035B000002F00C900000000000000000AE0000029
+:1035C000000004860000000000400000000004939A
+:1035D00000000005002F0222000000000000000093
+:1035E0000AE000000000048100000000002F00C974
+:1035F000000000000000000006E00000000004865B
+:1036000000000000004000000000049300000006DD
+:10361000002F022200000000000000000AE000006D
+:103620000000048600000000002F00C90000000018
+:103630000000000008E00000000004860000000018
+:10364000004000000000049300007F0000280A21D1
+:103650000000000000004500002F022200000000D2
+:10366000000000000AE00000000000000000000868
+:1036700000210A23000000000000000014C0000028
+:1036800000000490000021690020441100000000A7
+:1036900000000000C0204800000000000000000002
+:1036A000C02048000000000000000000C0204800CA
+:1036B00000000000CAFEBABE004048110000000031
+:1036C00000000000C02044000000000000000000D6
+:1036D000C02000000000000000000000C0404800C2
+:1036E0000000000000007F0000280A210000000008
+:1036F00000004500002F0222000000000000000032
+:103700000AE000000000049900000000C020000052
+:103710000000000000000000C020000000000000C9
+:1037200000000000C0400000000000000000000099
+:1037300000404C080000045900000000C0200800B0
+:10374000000000000000001040210E2000000000DA
+:1037500000000011402112200000000000000012B3
+:1037600040211620000000000000216900204411C3
+:1037700000000000000000000020480200000000DF
+:1037800000000000002102250000000000000000F1
+:1037900014E00000000004A300040000C0494A2017
+:1037A000000004A4FFFBFFFFC0284A200000000027
+:1037B00000000000002102230000000000000000C3
+:1037C00014E00000000004B000000000C020480029
+:1037D0000000000000000000C020480000000000C1
+:1037E0000000000000210224000000000000000092
+:1037F00014C00000000000008100000000204411FF
+:10380000000000000000000C002048110000000033
+:103810000000000000200010000000000000000078
+:1038200014C00000000004ACA000000000204411FF
+:1038300000000000CAFEBABE0040481100000000AF
+:10384000810000000020441100000000000000047E
+:1038500000204811000000000000216B00204411EE
+:103860000000000000000000C02048100000000020
+:10387000810000000020441100000000000000054D
+:1038800000204811000000000000216C00204411BD
+:103890000000000000000000C020481000000000F0
+:1038A00000000000002F02240000000000000000C3
+:1038B0000CE00000000000000000000000400000DC
+:1038C000000004AA00000000C0210A20000000003F
+:1038D0000000000014C00000000004C381000000CC
+:1038E00000204411000000000000000000204811EA
+:1038F000000000000000216D0020441100000000C5
+:1039000000000000C020480000000000000000008F
+:10391000C060480000000692000000000040000067
+:10392000000004C7810000000020441100000000D6
+:103930000000000100204811000000000004000009
+:10394000C02946200000000000000000C060000008
+:103950000000068D0000000100210222000000008E
+:103960000000000014C00000000004CE0000216927
+:10397000002044110000000000000000C0204800AA
+:103980000000000000000000C0204800000000000F
+:10399000000000000020481000000000CAFEBABE6F
+:1039A000004048110000000000000000C02044005A
+:1039B0000000000000000000C040481000000000AF
+:1039C0008100000000204411000000000000000100
+:1039D0000020481100000000000021F800204411E0
+:1039E000000000000000000E002048110000000050
+:1039F000000421F9006044110000068D0000000061
+:103A000000210230000000000000000014C000008F
+:103A1000000004D0000021800020441100000000BC
+:103A200000000000C020480000000000000000006E
+:103A3000C02000000000000000000000C02048007E
+:103A40000000000000000000C02000000000000096
+:103A500000000000C040480000000000000000031B
+:103A600000333E2F00000000000000010021022171
+:103A7000000000000000000014E00000000005004D
+:103A80000000002C00200A2D0000000000040000AF
+:103A900018E00C11000004EF0000000100333E2F7D
+:103AA0000000000000002169002044110000000017
+:103AB000000000000020480200000000000000009C
+:103AC00000204803000000000000000800300A2227
+:103AD0000000000000000000C020480000000000BE
+:103AE00000000000C0204800000000000000216924
+:103AF00000204411000000000000000000204802E7
+:103B0000000000000000000000204803000000004A
+:103B10000000000800300A22000000000000000041
+:103B2000C02048000000000000000000D8C048008D
+:103B3000000004E30000216900204411000000009F
+:103B4000000000000020480200000000000000000B
+:103B500000204803000000000000000800300A2296
+:103B60000000000000000000C0204800000000002D
+:103B700000000000C0204800000000000000002DF0
+:103B80000020122D000000000000000000290C831E
+:103B90000000000000002169002044110000000026
+:103BA00000000000002048020000000000000000AB
+:103BB00000204803000000000000000800300A2236
+:103BC0000000000000000000C020480000000000CD
+:103BD00000000000C02048000000000000000011AC
+:103BE00000210224000000000000000014C00000BA
+:103BF000000000000000000000400000000004AAD7
+:103C00000000002CC0203620000000000000002D25
+:103C1000C0403620000000000000000F00210221FB
+:103C2000000000000000000014C0000000000505B6
+:103C300000000000006000000000000B0000000019
+:103C4000D90000000000000000000000C040040097
+:103C500000000001B5000000002044110000000039
+:103C6000000020000020481100000000B600000005
+:103C700000204411000000000000A00000204811B6
+:103C800000000000B7000000002044110000000008
+:103C90000000C0000020481100000000B800000033
+:103CA00000204411000000000000F8E0002048114E
+:103CB00000000000B90000000020441100000000D6
+:103CC0000000F8800020481100000000BA00000049
+:103CD00000204411000000000000E0000020481116
+:103CE00000000000BB0000000020441100000000A4
+:103CF0000000F0000020481100000000BC0000009F
+:103D000000204411000000000000F3FC00204811D6
+:103D100000000000810000000020441100000000AD
+:103D2000000000020020481100000000000000FF19
+:103D300000280E300000000000000000002F0223C9
+:103D400000000000000000000CC000000000051989
+:103D500000000000C020080000000000000000007B
+:103D600014C000000000052E0000000000200C110F
+:103D7000000000000000001C0020362300000000AE
+:103D80000000002B00203623000000000000002966
+:103D90000020362300000000000000280020362309
+:103DA0000000000000000017002036230000000083
+:103DB000000000250020362300000000000000263F
+:103DC00000203623000000000000001500203623EC
+:103DD0000000000000000016002036230000000054
+:103DE000FFFFE00000200C11000000000000002197
+:103DF00000203623000000000000002200203623AF
+:103E00000000000000001FFF00200C110000000057
+:103E100000000023002036230000000000000024E2
+:103E20000020362300000000F1FFFFFF00283A2E9B
+:103E3000000000000000001AC0220E200000000058
+:103E4000000000000029386E000000008100000022
+:103E5000002044110000000000000006002048116E
+:103E6000000000000000002A402036200000000072
+:103E70008700000000204411000000000000000046
+:103E8000C0204800000000000000A1F40020441100
+:103E900000000000000000000020481000000000AA
+:103EA0000000000000200C110000000000000030A5
+:103EB00000203623000000009D0000000020441177
+:103EC000000000000000001F40214A200000000008
+:103ED00096000000002044110000000000000000D7
+:103EE000C02048000000000000000000C0200C00BE
+:103EF0000000000000000000C020100000000000D2
+:103F00000000001F00211624000000000000000037
+:103F100014C00000000000000000001D0020362337
+:103F2000000000000000000300281E230000000025
+:103F3000000000080022222300000000FFFFF00024
+:103F4000002822280000000000000000002920E8CE
+:103F5000000000000000001F0020362800000000C4
+:103F60000000001800211E230000000000000020B7
+:103F70000020362700000000000000020022162466
+:103F80000000000000000000003014A80000000045
+:103F90000000001E00203625000000000000000385
+:103FA00000211A24000000001000000000281A263A
+:103FB00000000000EFFFFFFF00283A2E0000000085
+:103FC00000000000004938CE0000067B0000000120
+:103FD00040280A20000000000000000640280E20B3
+:103FE0000000000000000300C028122000000000B4
+:103FF0000000000800211224000000000000000062
+:10400000C02016200000000000000000C0201A2080
+:10401000000000000000000000210222000000005B
+:104020000000000014C000000000056681000000D0
+:104030000020441100000000000000010020481191
+:10404000000000000000225800300A240000000098
+:1040500000040000006946220000068D000021696E
+:10406000002044110000000000000000002048056E
+:10407000000000000002000000294A2600000000A5
+:10408000000000000020481000000000CAFEBABE78
+:10409000002048110000000000000002002F022351
+:1040A00000000000000000000CC000000000056ED1
+:1040B00000000000C0201C100000000000000000F4
+:1040C000C04000000000057C00000002002F022319
+:1040D00000000000000000000CC000000000056EA1
+:1040E00081000000002044110000000000000001D9
+:1040F00000204811000000000000225800300A246F
+:104100000000000000040000006946220000068D47
+:1041100000000000C0201C10000000000000000093
+:10412000C04000000000057C00000000002F0223BA
+:1041300000000000000000000CC00000000005723C
+:1041400000000000C0201C00000000000000000073
+:10415000C04000000000057C00000004002F022386
+:1041600000000000000000000CC000000000057A04
+:104170008100000000204411000000000000000049
+:1041800000204811000000000000216D00204411B3
+:104190000000000000000000C020480000000000F7
+:1041A00000000000C060480000000692000000000F
+:1041B00000401C100000057C00000000C020000032
+:1041C0000000000000000000C040000000000000EF
+:1041D000000000000EE000000000057E000000006E
+:1041E00000600000000005C900000000002F02244C
+:1041F00000000000000000000CC000000000058F5F
+:104200000000A2B7002044110000000000000000E0
+:104210000020480700000000810000000020441139
+:104220000000000000000001002048110000000014
+:104230000004A2B6006044110000068D0000001AC0
+:10424000002122300000000000000006002226307D
+:104250000000000000042004006044110000068DEE
+:104260000000A2C400204411000000000000000073
+:10427000003048E9000000000000000000E00000FD
+:104280000000058D0000A2D10020441100000000B4
+:104290000000000000404808000000000000A2D11B
+:1042A00000204411000000000000000100504A28D6
+:1042B0000000000000000001002F022400000000A8
+:1042C000000000000CC00000000005A00000A2BB20
+:1042D00000204411000000000000000000204807FA
+:1042E00000000000810000000020441100000000D8
+:1042F0000000000100204811000000000004A2BAE4
+:10430000006044110000068D0000001A00212230D8
+:10431000000000000000000600222630000000001F
+:1043200000042004006044110000068D0000A2C5B6
+:10433000002044110000000000000000003048E9A7
+:10434000000000000000000000E000000000059EEA
+:104350000000A2D200204411000000000000000074
+:1043600000404808000000000000A2D200204411D4
+:10437000000000000000000100504A28000000007A
+:1043800000000002002F02240000000000000000D6
+:104390000CC00000000005B10000A2BF00204411C5
+:1043A000000000000000000000204807000000009E
+:1043B0008100000000204411000000000000000106
+:1043C00000204811000000000004A2BE006044115B
+:1043D0000000068D0000001A0021223000000000BD
+:1043E0000000000600222630000000000004200427
+:1043F000006044110000068D0000A2C60020441198
+:104400000000000000000000003048E9000000004B
+:104410000000000000E00000000005AF0000A2D393
+:104420000020441100000000000000000040480887
+:10443000000000000000A2D3002044110000000092
+:104440000000000100504A28000000000000A2C344
+:104450000020441100000000000000000020480778
+:104460000000000081000000002044110000000056
+:104470000000000100204811000000000004A2C25A
+:10448000006044110000068D0000001A0021223057
+:10449000000000000000000600222630000000009E
+:1044A00000042004006044110000068D0000A2C733
+:1044B000002044110000000000000000003048E926
+:1044C000000000000000000000E00000000005BE49
+:1044D0000000A2D4002044110000000000000000F1
+:1044E00000404808000000000000A2D40020441151
+:1044F000000000000000000100504A2800000000F9
+:1045000085000000002044110000000000000000B1
+:1045100000204801000000000000304A0020441143
+:104520000000000001000000002048110000000011
+:104530000000000000400000000005C4A4000000CE
+:10454000C02044110000000000000000C0404800EE
+:104550000000000000000000C0600000000005C96D
+:1045600000000000C0400400000000010000002C1A
+:1045700000203621000000008100000000204411CE
+:1045800000000000000000060020481100000000AC
+:1045900000000000002F02300000000000000000BA
+:1045A0000CC00000000005D0000000000020041135
+:1045B000000000000000003000403621000005E34C
+:1045C000000000300020062D0000000000007E00EA
+:1045D000002806210000000000000000002F02213A
+:1045E00000000000000000000CE00000000005E3F7
+:1045F00081000000002044110000000000000001C4
+:1046000000204811000000000004A0920060441146
+:104610000000068D00000031002036300000000050
+:104620000004A093006044110000068D00000032D9
+:1046300000203630000000000004A2B600604411E3
+:104640000000068D0000003300203630000000001E
+:104650000004A2BA006044110000068D000000347E
+:1046600000203630000000000004A2BE00604411AB
+:104670000000068D000000350020363000000000EC
+:104680000004A2C2006044110000068D0000003644
+:1046900000203630000000000004200400604411B7
+:1046A0000000068D0001A2A40020441100000000BB
+:1046B0000000003F00204811000000000000003F03
+:1046C00000204811000000000000003F00204811B9
+:1046D000000000000000003F002048110000000022
+:1046E0000000000500204811000000000000A1F4B7
+:1046F00000204411000000000000000000204811CC
+:1047000000000000880000000020441100000000AC
+:10471000000000010020481100000000810000009E
+:104720000020441100000000000000060020481195
+:104730000000000000000001002F02300000000017
+:10474000000000000CE000000000062C000000301B
+:104750000020062D0000000000000000002F0221B4
+:1047600000000000000000000CE000000000062C2B
+:104770008100000000204411000000000000000142
+:10478000002048110000000000007E0000280621E3
+:104790000000000000000000002F022100000000C7
+:1047A000000000000CE00000000006050000A092E0
+:1047B00000204411000000000000003100204A2DBC
+:1047C000000000000000A093002044110000000041
+:1047D0000000003200204A2D000000000000A2B6B8
+:1047E00000204411000000000000003300204A2D8A
+:1047F000000000000000A2BA0020441100000000E8
+:104800000000003400204A2D000000000000A2BE7D
+:1048100000204411000000000000003500204A2D57
+:10482000000000000000A2C20020441100000000AF
+:104830000000003600204A2D00000000000000307B
+:104840000020062D00000000000001FF00280621C6
+:104850000000000000000000002F02210000000006
+:10486000000000000CE000000000062B000000002B
+:1048700000210221000000000000000014C0000020
+:104880000000060E0004A003006044110000068D25
+:104890000000A00300204411000000000000000000
+:1048A0000020481000000000000000010021062147
+:1048B000000000000000000014C00000000006130B
+:1048C0000004A010006044110000068D0000A0103C
+:1048D00000204411000000000000000000204810EB
+:1048E000000000000000000100210621000000007F
+:1048F00000000000002F0221000000000000000066
+:104900000CE000000000062B0004A0110060441120
+:104910000000068D0000A0110020441100000000DE
+:104920000000000000204810000000000004A01259
+:10493000006044110000068D0000A0120020441108
+:1049400000000000000000000020481000000000EF
+:104950000004A013006044110000068D0000A013A5
+:10496000002044110000000000000000002048105A
+:10497000000000000004A014006044110000068D37
+:104980000000A014002044110000000000000000FE
+:1049900000204810000000000004A0150060441131
+:1049A0000000068D0000A01500204411000000004A
+:1049B0000000000000204810000000000004A016C5
+:1049C000006044110000068D0000A0160020441174
+:1049D000000000000000000000204810000000005F
+:1049E0000004A017006044110000068D0000A0170D
+:1049F00000204411000000000000000000204810CA
+:104A00000000000000042004006044110000068D36
+:104A10000000002C0080062D00000000FF000000B8
+:104A20000020441100000000000000000020481198
+:104A300000000000000000010020481100000000FC
+:104A4000000000020080481100000000000000008B
+:104A50000EE000000000063D000000300020062DA2
+:104A600000000000000000020028062100000000F5
+:104A700000000000002F02210000000000000000E4
+:104A80000CE000000000063B810000000020441103
+:104A9000000000000000000100204811000000009C
+:104AA00000042004006044110000068D0000100086
+:104AB00000200811000000000000002B002036221A
+:104AC000000000000000000000600000000006413F
+:104AD0000000000000600000000005C99800000010
+:104AE0000020441100000000000000000080481178
+:104AF0000000000000000000C0600000000006414F
+:104B000000000000C0400400000000010000A2A45A
+:104B10000020441100000000000000220020481185
+:104B20000000000089000000002044110000000087
+:104B300000000001004048110000062D9700000011
+:104B40000020441100000000000000000020481177
+:104B5000000000008A000000002044110000000056
+:104B600000000000004048110000062D0000000079
+:104B7000006000000000065C0000201000204411CE
+:104B8000000000000000800000204811000000002C
+:104B90000001A2A4C0204411000000000000001683
+:104BA000006048110000036E000020100020441136
+:104BB000000000000001000000204811000000007B
+:104BC00081000000002044110000000000000001EE
+:104BD00000204811000000000000217C002044114A
+:104BE00000000000098000000020481100000000C3
+:104BF000FFFFFFFF00204811000000000000000040
+:104C00000020481100000000000000001700000014
+:104C1000000000000004217F006044110000068DA8
+:104C20000000001F00210230000000000000000012
+:104C300014C00000000000000000000400404C11FF
+:104C400000000656000000000040000000000000C8
+:104C50000000001700201E2D0000000000000004CE
+:104C600000291E27000000000000001700803627E2
+:104C7000000000000000001700201E2D00000000B2
+:104C8000FFFFFFFB00281E270000000000000017A8
+:104C900000803627000000000000001700201E2DB5
+:104CA000000000000000000800291E27000000008E
+:104CB00000000017008036270000000000000017E9
+:104CC00000201E2D00000000FFFFFFF700281E2718
+:104CD00000000000000000170080362700000000E0
+:104CE000000020100020441100000000000080009F
+:104CF00000204811000000000001A2A4002044117F
+:104D00000000000000000016006048110000036E63
+:104D100000002010002044110000000000010000ED
+:104D200000204811000000000000217C00204411F8
+:104D30000000000001800000002048110000000079
+:104D4000FFFFFFFF002048110000000000000000EE
+:104D500000204811000000000000000017000000C3
+:104D6000000000008100000000204411000000004D
+:104D70000000000100204811000000000004217F15
+:104D8000006044110000068D0000001F0021023069
+:104D9000000000000000000014C000000000068CAD
+:104DA0000000001000404C110000067200000000DE
+:104DB000C0200400000000000000000038C0000017
+:104DC000000000000000001D00200A2D000000006F
+:104DD0000000001E00200E2D000000000000001F3B
+:104DE0000020122D00000000000000200020162DE1
+:104DF00000000000000021690020441100000000B4
+:104E00000000000000204804000000000000000036
+:104E100000204805000000000000000000204801BC
+:104E200000000000CAFEBABE0020481100000000C9
+:104E30000000000400301224000000000000000008
+:104E4000002F006400000000000000000CC0000003
+:104E50000000068B0000000300281A22000000005A
+:104E6000000000080022122200000000FFFFF000F6
+:104E7000002812240000000000000000002910C4D7
+:104E8000000000000000001F004036240000000069
+:104E90000000000000800000000000000000000092
+:104EA0001AC000000000068D9F0000000020441181
+:104EB00000000000CAFEBABE002048110000000039
+:104EC000000000001AE00000000006900000000052
+:104ED0000080000000000000000000001AC0000078
+:104EE000000006929E000000002044110000000017
+:104EF000CAFEBABE002048110000000000000000F9
+:104F00001AE000000000069500000000008000008C
+:104F10000000000000000000006000000000000B26
+:104F200000001000006004110000031500000000E4
+:104F300000200411000000000000000000600811C3
+:104F4000000001B20000225C0020441100000000BB
+:104F5000000000030020481100000000000022565D
+:104F600000204411000000000000001B0020481138
+:104F7000000000000000A1FC00204411000000001F
+:104F80000000000100204811000000000001A1FD08
+:104F9000C0204411000000000000002100201E2D50
+:104FA000000000000000001000221E27000000008A
+:104FB000000000240020222D000000000000FFFF60
+:104FC00000282228000000000000000000294907F6
+:104FD0000000000000000000002048110000000058
+:104FE000000000220020222D000000000000FFFF32
+:104FF00000282228000000000000000000294907C6
+:105000000000000000000000002048110000000027
+:105010000000002300201E2D0000000000000010F2
+:1050200000221E27000000000000000000294907A0
+:1050300000000000000000000040481100000000D7
+:105040000000000000000000000000000000000060
+:105050000000000000000000000000000000000050
+:105060000000000000000000000000000000000040
+:105070000000000000000000000000000000000030
+:105080000000000000000000000000000000000020
+:105090000000000000000000000000000000000010
+:1050A0000000000000000000000000000000000000
+:1050B00000000000000000000000000000000000F0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:10517000000000000000000000000000000000002F
+:10518000000000000000000000000000000000001F
+:10519000000000000000000000000000000000000F
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000000000000000000DF
+:1051D00000000000000000000000000000000000CF
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:10522000000000000000000000000000000000007E
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000000000005E
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000000000000000000002E
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000000000000000000000000000FE
+:1052B0000142050205C002500000000001C3016860
+:1052C000043F05C000000000022502090250015100
+:1052D000000000000223024502A00241000000007D
+:1052E00003D705C005C005C0000000000649064AF6
+:1052F000031F05C00000000005C005C503200340D2
+:1053000000000000032A0282034203340000000070
+:1053100005C005C005C005C00000000005C005515E
+:1053200005C005C00000000003BA05C004BB03446B
+:1053300000000000049A0450043D05C00000000075
+:1053400004D005C0044104DD00000000045005073E
+:10535000035103750000000005C005C005C005C06D
+:105360000000000005C005C005C005C00000000029
+:1053700005C005C0063F05C70000000005C005C008
+:10538000000705C00000000005C005C005C005C03D
+:105390000000000005C005C005C005C000000000F9
+:1053A00003F803ED0408040600000000040E040ADC
+:1053B000040C041000000000041C04180424042041
+:1053C00000000000042C0428043404300000000015
+:1053D00005C005C0043805C00000000005C005C0B8
+:1053E00005C005C00000000005C005C005C005C01F
+:1053F0000000000000020679069700060000000089
+:00000001FF
diff --git a/firmware/radeon/RV620_pfp.bin.ihex b/firmware/radeon/RV620_pfp.bin.ihex
new file mode 100644
index 0000000..f55292c
--- /dev/null
+++ b/firmware/radeon/RV620_pfp.bin.ihex
@@ -0,0 +1,145 @@
+:1000000000CA040000A00000007E828B007C038BED
+:10001000008001B8007C038B00D4401E00EE001E5F
+:1000200000CA040000A00000007E828B00C41838C3
+:1000300000CA240000CA2800009581A800C41C3A08
+:1000400000C3C00000CA080000CA0C00007C744B4A
+:1000500000C200050099C00000C41C3A007C744C2A
+:1000600000C0FFF000042C0400309002007D250049
+:1000700000351402007D350B00255403007CD5802B
+:1000800000259C030095C00400D5001B007EDDC147
+:10009000007D9D8000D6801B00D5801B00D4401EB3
+:1000A00000D5401E00D6401E00D6801E00D4801E03
+:1000B00000D4C01E009783D300D5C01E00CA08001C
+:1000C0000080001A00CA0C0000E4011E00D4001ECB
+:1000D0000080000C00C4183800E4013E00D4001E6B
+:1000E0000080000C00C4183800D4401E00EE001E32
+:1000F00000CA040000A00000007E828B00E4011E04
+:1001000000D4001E00D4401E00EE001E00CA0400F1
+:1001100000A00000007E828B00E4013E00D4001E9F
+:1001200000D4401E00EE001E00CA040000A0000023
+:10013000007E828B00CA180000D4401E00D5801EAD
+:100140000080005300D4007500D4401E00CA08008F
+:1001500000CA0C0000CA100000D4801900D4C018D6
+:1001600000D5001700D4801E00D4C01E00D5001E8C
+:1001700000E2001E00CA040000A00000007E828B86
+:1001800000CA080000D4806000D4401E0080000037
+:1001900000D4801E00CA080000D4806100D4401E34
+:1001A0000080000000D4801E00CA080000CA0C00B5
+:1001B00000D4401E00D4801600D4C01600D4801E87
+:1001C000008001B800D4C01E00C6084300CA0C005D
+:1001D00000CA10000094800400CA140000E420F358
+:1001E00000D4201300D5606500D4E01C00D5201C8D
+:1001F00000D5601C008000000006200100C60843F6
+:1002000000CA0C0000CA1000009483F700CA140052
+:1002100000E420F30080007900D4201300C60843D6
+:1002200000CA0C0000CA1000009883EF00CA140036
+:1002300000D400640080008D0000000000C414326F
+:1002400000C6184300C4082F0095400500C40C30B8
+:1002500000D4401E0080000000EE001E009583F5D3
+:1002600000C4103100D4403300D5206500D4A01C58
+:1002700000D4E01C00D5201C00E4015E00D4001E68
+:10028000008000000006200100CA1800000A2001BA
+:1002900000D6007600C408360098800700C61045D6
+:1002A0000095011000D4001F00D46062008000009F
+:1002B00000D4206200CC383500CC1433008401BB5C
+:1002C00000D4007200D5401E0080000000EE001E29
+:1002D00000E2001A008401BB00E2001A00CC104BBF
+:1002E00000CC0447002C9401007D098B0098400548
+:1002F000007D15CB00D4001A008001B800D4006D39
+:100300000034440100CC0C480098403A00CC2C4A00
+:100310000095800400CC0449008001B800D4001A84
+:1003200000D4C01A00282801008400F000CC10037B
+:100330000098801B0004380C008400F000CC1003EF
+:100340000098801700043808008400F000CC1003E7
+:100350000098801300043804008400F000CC1003DF
+:100360000098801400CC104C009A800900CC144DE9
+:10037000009840DC00D4006D00CC184800D5001A6D
+:1003800000D5401A008000C900D5801A0096C0D55B
+:1003900000D4006D008001B800D4006E009AC00344
+:1003A00000D4006D00D4006E0080000000EC007FDF
+:1003B000009AC0CC00D4006D008001B800D4006E5B
+:1003C00000CC140300CC180300CC1C03007D910367
+:1003D000007DD583007D190C0035CC1F0035701FC2
+:1003E000007CF0CB007CD08B00880000007E8E8BE0
+:1003F0000095C00400D4006E008001B800D4001A3B
+:1004000000D4C01A00CC080300CC0C0300CC1003AD
+:1004100000CC140300CC180300CC1C0300CC240334
+:1004200000CC28030035C41F0036B01F007C704B81
+:100430000034F01F007C704B0035701F007C704B47
+:10044000007D8881007DCCC1007E5101007E9541F8
+:10045000007C9082007CD4C2007C848B009AC00314
+:10046000007C8C8B002C88010098809E00D4006D4D
+:100470000098409C00D4006E00CC084C00CC0C4D81
+:1004800000CC104800D4801A00D4C01A00800101AA
+:1004900000D5001A00CC083200D40032009482D972
+:1004A00000CA0C0000D4401E0080000000D4001ED2
+:1004B00000E4011E00D4001E00CA080000CA0C009F
+:1004C00000CA100000D4401E00CA140000D4801ED0
+:1004D00000D4C01E00D5001E00D5401E00D54034FB
+:1004E0000080000000EE001E0028040400E2001A54
+:1004F00000E2001A00D4401A00CA380000CC0803F9
+:1005000000CC0C0300CC0C0300CC0C03009882BD83
+:1005100000000000008401BB00D7A06F0080000035
+:1005200000EE001F00CA040000C2FF0000CC083427
+:1005300000C13FFF007C74CB007CC90B007D010F24
+:10054000009902B0007C738B008401BB00D7A06FC0
+:100550000080000000EE001F00CA080000281900FB
+:10056000007D898B009580140028140400CA0C00BB
+:1005700000CA100000CA1C0000CA240000E2001FCC
+:1005800000D4C01A00D5001A00D5401A00CC1803B8
+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
+:1005A000007D9C4700984297000000000080016198
+:1005B00000D4C01A00D4401E00D4801E0080000069
+:1005C00000EE001E00E4011E00D4001E00D4401EF8
+:1005D00000EE001E00CA040000A00000007E828B16
+:1005E00000E4013E00D4001E00D4401E00EE001EB8
+:1005F00000CA040000A00000007E828B00CA080030
+:1006000000248C06000CCC060098C00600CC104ECE
+:100610000099000400D4007300E4011E00D4001E01
+:1006200000D4401E00D4801E0080000000EE001E9A
+:1006300000CA080000CA0C000034D01800251001C0
+:100640000095002100C17FFF00CA100000CA1400FD
+:1006500000CA180000D4801D00D4C01D007DB18BDD
+:1006600000C1420200C2C00100D5801D0034DC0E72
+:10067000007D5D4C007F734C00D7401E00D5001EEE
+:1006800000D5401E00C1420000C2C00000099C010C
+:100690000031DC10007F5F4C007F734C00042802A7
+:1006A000007D838000D5A86F00D5806600D7401EEE
+:1006B00000EC005E00C8240200C82402008001B8DB
+:1006C00000D6007600D4401E00D4801E00D4C01E88
+:1006D0000080000000EE001E0080000000EE001F01
+:1006E00000D4001F0080000000D4001F00D4001FB1
+:1006F0000088000000D4001F00000000000000007F
+:1007000000000000000000000000000000000000E9
+:1007100000000000000000000000000000000000D9
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:1008000000010171000201780003008F0004007FE5
+:10081000000500030006003F000700320008012C1D
+:1008200000090046000A0036001001B6001700A2B9
+:100830000022013A00230149002000B400240125D0
+:100840000027004D0028006A002A0060002B00529B
+:10085000002F0065003200870034017F003C015604
+:10086000003F00720041018C0044012E00550173CD
+:100870000056017A0060000B00610034006200380D
+:1008800000630038006400380065003800660038F6
+:10089000006700380068003A00690041006A0048BB
+:1008A000006B0048006C0048006D0048006E004876
+:1008B000006F00480000000600000006000000066F
+:1008C0000000000600000006000000060000000610
+:1008D0000000000600000006000000060000000600
+:1008E00000000006000000060000000600000006F0
+:1008F00000000006000000060000000600000006E0
+:00000001FF
diff --git a/firmware/radeon/RV630_me.bin.ihex b/firmware/radeon/RV630_me.bin.ihex
new file mode 100644
index 0000000..ba3a7e6
--- /dev/null
+++ b/firmware/radeon/RV630_me.bin.ihex
@@ -0,0 +1,1345 @@
+:1000000000000000C020040000000000000000000C
+:1000100000A0000A000000000000FFFF00284621A9
+:100020000000000000000000D900480000000000AF
+:1000300000000000C02004000000000000000000DC
+:1000400000A0000A000000000000000000E0000026
+:100050000000000000010000C02946200000000050
+:1000600000000000D900480000000000000000006F
+:10007000C0200400000000000000000000A0000AF2
+:10008000000000008100000000204411000000007A
+:1000900000000001002048110000000000042004BE
+:1000A000006044110000068A0000000000600000AB
+:1000B0000000062E00000000006000000000064264
+:1000C00000000000C02008000000000000000F0039
+:1000D000002816220000000000000008002116255C
+:1000E000000000000000001800203625000000007D
+:1000F0008D000000002044110000000000000004FA
+:10010000002F022500000000000000000CE00000AD
+:1001100000000018004120000040481100000019B4
+:100120000042200000204811000000008E00000066
+:1001300000204411000000000000002800204A2D8B
+:1001400000000000900000000020441100000000AA
+:100150000000000000204805000000000000000C26
+:1001600000211622000000000000000300281625D0
+:10017000000000000000001900211A220000000009
+:100180000000000400281A26000000000000000003
+:10019000002914C5000000000000001900203625C9
+:1001A0000000000000000000003A140200000000FF
+:1001B00000000016002116250000000000000003CA
+:1001C00000281625000000000000001700200E2D5A
+:1001D00000000000FFFFFFFC00280E2300000000CD
+:1001E00000000000002914A3000000000000001718
+:1001F00000203625000000000000800000280E22AC
+:10020000000000000000000700220E230000000094
+:10021000000000000029386E0000000020000000EF
+:1002200000280E22000000000000000600210E231E
+:1002300000000000000000000029386E00000000EF
+:100240000000000000220222000000000000000068
+:1002500014E0000000000038000000002EE0000064
+:1002600000000035000000002CE000000000003716
+:100270000000000000400E2D0000003900000008C2
+:1002800000200E2D00000000000000090040122D8B
+:10029000000000460000000100400E2D0000003963
+:1002A00000000000C0200C0000000000003FFFFC28
+:1002B0000028122300000000000000020022122487
+:1002C000000000000000001F00211E2300000000AD
+:1002D0000000000014E000000000003E00000008E4
+:1002E00000401C11000000410000000D00201E2DE8
+:1002F000000000000000000F00281E270000000082
+:100300000000000300221E27000000007FC0000044
+:1003100000281A23000000000000001400211A2603
+:10032000000000000000000100331A260000000059
+:100330000000000800221A26000000000000000053
+:1003400000290CC700000000000000270020362410
+:100350000000000000007F000028122100000000C3
+:1003600000001400002F0224000000000000000024
+:100370000CE000000000004B0000000100290E23EB
+:10038000000000000000000E0020362300000000E6
+:100390000000E0000020441100000000FFF8000011
+:1003A00000294A230000000000000000003A2C024F
+:1003B000000000000000000200220E2B00000000E0
+:1003C000FC00000000280E23000000000000000FC9
+:1003D000002036230000000000001FFF00294A23F0
+:1003E000000000000000002700204A2D000000004F
+:1003F000000000000020481100000000000000295B
+:1004000000200E2D00000000060A020000294A23E9
+:100410000000000000000000002048110000000063
+:100420000000000000204811000000000000000152
+:1004300000210222000000000000000014E0000083
+:1004400000000061000000002EE000000000005FDE
+:10045000000000002CE000000000005E0000000032
+:1004600000400E2D000000620000000100400E2D33
+:10047000000000620000000A00200E2D00000000B5
+:100480000000000B0040122D0000006A0000000078
+:10049000C0200C0000000000003FFFFC00281223D9
+:1004A00000000000000000020022122400000000F2
+:1004B0007FC0000000281623000000000000001488
+:1004C0000021162500000000000000010033162561
+:1004D000000000008000000000280E230000000043
+:1004E0000000000000290CA3000000003FFFFC00FA
+:1004F00000290E23000000000000001F00211E2321
+:10050000000000000000000014E000000000006D8A
+:100510000000010000401C11000000700000000DF0
+:1005200000201E2D00000000000000F000281E2703
+:10053000000000000000000400221E270000000050
+:100540008100000000204411000000000000000DA8
+:100550000020481100000000FFFFF0FF00281A30C3
+:10056000000000000000A02800204411000000004E
+:1005700000000000002948E6000000000000A0186C
+:1005800000204411000000003FFFFFFF00284A2325
+:10059000000000000000A010002044110000000036
+:1005A00000000000002048040000000000000030AF
+:1005B0000020162D00000000000000020029162572
+:1005C0000000000000000030002036250000000080
+:1005D000000000250020162D000000000000000093
+:1005E000002F00A300000000000000000CC000006D
+:1005F00000000083000000260020162D00000000EF
+:1006000000000000002F00A4000000000000000017
+:100610000CC000000000008400000000004000004A
+:100620000000008A000000250020362300000000A2
+:100630000000002600203624000000000000001703
+:1006400000201E2D000000000000000200210227F3
+:10065000000000000000000014E000000000008A1C
+:1006600000000000006000000000066500000000BF
+:1006700000600000000006590000000200210E2268
+:10068000000000000000000014C000000000008D09
+:1006900000000012C040362000000093000000005F
+:1006A0002EE0000000000091000000002CE000009F
+:1006B000000000900000000200400E2D000000929B
+:1006C0000000000300400E2D000000920000000C0E
+:1006D00000200E2D00000000000000120020362334
+:1006E000000000000000000300210E2200000000B6
+:1006F0000000000014C00000000000980000A00CE2
+:10070000002044110000000000000000C02048004C
+:100710000000000000000000C0404800000000A0F1
+:100720000000A00C002044110000000000000000A8
+:100730000020481100000000000000002EE0000032
+:100740000000009E000000002CE000000000009D62
+:100750000000000200400E2D0000009F000000037A
+:1007600000400E2D0000009F0000000C00200E2D08
+:10077000000000000000000000204803000000000E
+:1007800000000000003A0C0200000000003F0000E2
+:1007900000280E23000000000000001000210E239E
+:1007A00000000000000000110020362300000000BF
+:1007B0000000001E0021022B0000000000000000CD
+:1007C00014C00000000000A700000016C020362062
+:1007D000000000000000001F0021022B00000000AC
+:1007E0000000000014C00000000000AA0000001576
+:1007F000C0203620000000000000000800210E2B61
+:10080000000000000000007F00280E230000000010
+:1008100000000000002F0223000000000000000084
+:100820000CE00000000000E10000000027000000D4
+:10083000000000000000000000600000000002A3B3
+:1008400000000001002F0223000000000000000053
+:100850000AE00000000000B300000000006000009B
+:100860000000013A81000000002044110000000057
+:100870000000000600204811000000000000000CED
+:1008800000221E300000000099800000002044116A
+:1008900000000000000000040020122D00000000F5
+:1008A00000000008002212240000000000000010D8
+:1008B00000201811000000000000000000291CE4C6
+:1008C0000000000000000000006048070000012F49
+:1008D0009B00000000204411000000000000000008
+:1008E00000204802000000009C000000002044118D
+:1008F00000000000000000000033146F0000000042
+:100900000000000100333E23000000000000000052
+:10091000D9004800000000000000000000203C0555
+:1009200000000000810000000020441100000000D1
+:100930000000000E00204811000000000000000030
+:1009400000201010000000000000E007002044110B
+:10095000000000000000000F0021022B000000003A
+:100960000000000014C00000000000CB00F8FF08E9
+:1009700000204811000000009800000000404811CD
+:10098000000000DC000000F000280E220000000043
+:10099000000000A0002F0223000000000000000063
+:1009A0000CC00000000000DA0000001100200E2D35
+:1009B0000000000000000001002F022300000000E2
+:1009C000000000000CE00000000000D50000000264
+:1009D000002F022300000000000000000CE00000D7
+:1009E000000000D400003F0000400C11000000D6C1
+:1009F00000001F0000400C11000000D600000F0096
+:100A000000200C11000000000038000900294A23D2
+:100A1000000000003F00000000280E2B0000000036
+:100A20000000000200220E2300000000000000076A
+:100A300000494A23000000DC00380F09002048115B
+:100A400000000000680000070020481100000000BE
+:100A50000000000800214A270000000000000000FC
+:100A60000020481100000000060A020000294A2464
+:100A700000000000000000000020481100000000FD
+:100A80000000000000204811000000000000A20249
+:100A9000002044110000000000FF000000280E228A
+:100AA000000000000000008000294A230000000030
+:100AB0000000002700200E2D00000000000000268E
+:100AC0000020122D0000000000000000002F008315
+:100AD00000000000000000000CE00000000000EA40
+:100AE00000000000006000000000065F0000000041
+:100AF00000400000000000EB00000000006000006B
+:100B000000000662000000070020222D0000000007
+:100B10000000000500220E2200000000001000006E
+:100B200000280E23000000000000000000292068BB
+:100B30000000000000000000003A0C02000000006D
+:100B4000000000EF00280E2300000000000000005D
+:100B500000292068000000000000001700200E2D72
+:100B6000000000000000000300210223000000003C
+:100B70000000000014E00000000000F80000000B7E
+:100B800000210228000000000000000014C0000046
+:100B9000000000F8000004000029222800000000E6
+:100BA0000000001400203628000000000000001C97
+:100BB00000210E22000000000000000014C0000010
+:100BC000000000FD0000A30C002044110000000004
+:100BD0000000000000204811000000000000001E7E
+:100BE00000210E22000000000000000014C00000E0
+:100BF0000000010B0000A30F0020441100000000C2
+:100C00000000001100200E2D000000000000000177
+:100C1000002F022300000000000000000CC00000B4
+:100C200000000104FFFFFFFF004048110000010B1E
+:100C300000000002002F022300000000000000005E
+:100C40000CC00000000001070000FFFF0040481139
+:100C50000000010B00000004002F02230000000030
+:100C6000000000000CC000000000010A000000FFAE
+:100C7000004048110000010B000000010020481155
+:100C8000000000000002C400002044110000000029
+:100C90000000001F00210E220000000000000000E4
+:100CA00014C00000000001120000001040210E20BE
+:100CB00000000000000000130020362300000000A8
+:100CC0000000001840224A20000000000000001030
+:100CD000C0424A20000001140000000000200C1156
+:100CE0000000000000000013002036230000000078
+:100CF000000000000020481100000000000000007B
+:100D000000204811000000000000000A002010111F
+:100D10000000000000000000002F0224000000007E
+:100D2000000000000CE000000000011B00000000BB
+:100D300000204811000000000000000100531224B0
+:100D400000000117FFBFFFFF00283A2E000000003F
+:100D50000000001B00210222000000000000000033
+:100D600014C000000000012E81000000002044118A
+:100D7000000000000000000D0020481100000000ED
+:100D80000000001800220E3000000000FC000000EF
+:100D900000280E2300000000810000000020441104
+:100DA000000000000000000E0020481100000000BC
+:100DB0000000000000201010000000000000E00E05
+:100DC000002044110000000007F8FF08002048112F
+:100DD000000000000000000000294A23000000007D
+:100DE0000000001C00201E2D000000000000000874
+:100DF00000214A27000000000000000000204811E8
+:100E000000000000060A020000294A240000000039
+:100E10000000000000204811000000000000000059
+:100E200000204811000000000000000000800000C9
+:100E300000000000810000000020441100000000BC
+:100E40000000000100204811000000000000217C8B
+:100E50000020441100000000008000000020481124
+:100E60000000000000000000002048060000000014
+:100E70000000000800214A270000000000000000D8
+:100E800017000000000000000004217F00604411F2
+:100E90000000068A0000001F002102300000000050
+:100EA0000000000014C000000000068900000004DB
+:100EB00000404C1100000135810000000020441169
+:100EC00000000000000000010020481100000000A8
+:100ED000000021F800204411000000000000001C68
+:100EE0000020481100000000000421F900604411B6
+:100EF0000000068A000000110021023000000000FE
+:100F00000000000014E000000000013C00000000B0
+:100F100000800000000000000000000000600000F1
+:100F20000000000B00000000006004110000031529
+:100F3000000000000020041100000000000000007C
+:100F400000600811000001B2000000000060000015
+:100F5000000001600000FFFF40280E20000000009C
+:100F600000000010C0211220000000000000FFFF60
+:100F7000402806200000000000000010C0210A20C8
+:100F800000000000000000000034146100000000B8
+:100F90000000000000741882000002BB0001A1FDE7
+:100FA00000604411000002E000003FFF002F022F0C
+:100FB00000000000000000000CC00000000001471D
+:100FC00000000000C040040000000001000000001C
+:100FD000006000000000000B000000000060041131
+:100FE00000000315000000000020041100000000B4
+:100FF0000000000000600811000001B200003FFF87
+:10100000002F022F00000000000000000CE0000094
+:10101000000000000000000000600000000001600F
+:101020000000001040210E20000000000000FFFF23
+:10103000C0281220000000000000001040211620EF
+:10104000000000000000FFFFC0681A20000002BB83
+:101050000001A1FD00604411000002E000003FFF1C
+:10106000002F022F00000000000000000CC0000054
+:101070000000015800000000C04004000000000112
+:101080000000225C0020441100000000000000016C
+:1010900000300A2F000000000000000100210A2299
+:1010A000000000000000000300384A220000000099
+:1010B0000000225600204411000000000000001A29
+:1010C00000204811000000000000A1FC0020441195
+:1010D0000000000000000001008048110000000036
+:1010E00000000000006000000000000B0000000095
+:1010F000006000000000018F0000000000600000A0
+:10110000000001A000003FFF002F022F00000000A0
+:10111000000000000CE000000000000000000000E3
+:1011200000202C0800000000000000000020241116
+:101130000000000000000000002028110000000056
+:10114000000022560020441100000000000000169C
+:1011500000204811000000000000225C0020441123
+:101160000000000000000003002048110000000003
+:1011700093800000002044110000000000000002E5
+:1011800000221E290000000000000000007048EB53
+:101190000000019C0000000000600000000002BB95
+:1011A00000000001403306200000000000000000A5
+:1011B000C03024090000000000003FFF002F022F74
+:1011C00000000000000000000CE000000000000033
+:1011D0000000000000600000000002A3000000000A
+:1011E000002F022100000000000000000AE00000C3
+:1011F0000000018100000000006000000000013AD2
+:101200000000000000400000000001869500000082
+:10121000002044110000000000000000002F022107
+:1012200000000000000000000CE00000000001864B
+:1012300000000000C0204800000000000000000185
+:10124000005306210000018292000000002044119A
+:101250000000000000000000C0604800000001978E
+:101260000001A1FD00204411000000000000001159
+:101270000020062D00000000000000000078042A75
+:10128000000002FB00000000002028090000000010
+:1012900000003FFF002F022F0000000000000000B0
+:1012A0000CC000000000017400000000C0400400F9
+:1012B000000000010000021000600411000003158E
+:1012C00000003FFF002F022F000000000000000080
+:1012D0000CE000000000019400000015C020362042
+:1012E0000000000000000016C020362000000000B2
+:1012F0003F800000002004110000000046000000B4
+:1013000000600811000001B2000000000080000031
+:10131000000000000000A1FC0020441100000000BB
+:1013200000003FFF002F022F00000000000000001F
+:101330000CC000000000019B00000001008048116B
+:1013400000000000000000210080481100000000A3
+:101350000000FFFF40280E200000000000000010E9
+:10136000C0211220000000000000FFFF40281620CE
+:101370000000000000000010C0811A2000000000E2
+:101380008100000000204411000000000000000661
+:1013900000204811000000000000000800221E305C
+:1013A000000000000000002900201A2D00000000AD
+:1013B0000000E0000020441100000000FFFBFF09D6
+:1013C00000204811000000000000000F0020222D26
+:1013D0000000000000001FFF00294A280000000054
+:1013E000000000060020222D000000000000000088
+:1013F000002920E80000000000000000002048084C
+:101400000000000000000000002048110000000063
+:10141000060A020000294A26000000000000000021
+:1014200000204811000000000000000000204811CA
+:101430000000000000000100002018110000000062
+:101440000000000800621E280000012F00000008B4
+:1014500000822228000000000002C0000020441189
+:10146000000000000000001500600E2D000001BD0E
+:101470000000001600600E2D000001BD0000C00835
+:1014800000204411000000000000001700200E2D75
+:10149000000000000000000014C00000000001B9BE
+:1014A0000000000000200411000000000000000007
+:1014B0000020480100000000390000000020481111
+:1014C00000000000000000000020481100000000A3
+:1014D000000000000080480200000000000000182A
+:1014E00000202E2D0000000000000000003B0D63D6
+:1014F000000000000000000800224A230000000055
+:101500000000001000224A23000000000000001824
+:1015100000224A2300000000000000000080480371
+:101520000000000000000000006000000000000B50
+:10153000000010000060041100000315000000000E
+:1015400000200411000000000000000000600811ED
+:10155000000001B2000000070021062F000000007B
+:101560000000001300200A2D000000000000000110
+:1015700000202C11000000000000FFFF4028222066
+:10158000000000000000000F0026222800000000DC
+:101590000000001040212620000000000000000F85
+:1015A000002626290000000000000000002028027C
+:1015B000000000000000225600204411000000003E
+:1015C0000000001B00204811000000000000000087
+:1015D000002F022100000000000000000CE00000CD
+:1015E000000001E00000225C002044110000000027
+:1015F0000000008100204811000000000000A1FC54
+:1016000000204411000000000000000100204811EB
+:10161000000000000000008000201C1100000000FD
+:1016200000000000002F0227000000000000000062
+:101630000CE00000000001DC000000000060000081
+:10164000000001E90000000100531E27000001D83E
+:101650000000000100202C11000000000000001F0D
+:1016600000280A22000000000000001F00282A2A8B
+:10167000000000000000000100530621000001D11D
+:101680000000225C00204411000000000000000265
+:1016900000304A2F000000000000A1FC002044118F
+:1016A00000000000000000010020481100000000C0
+:1016B0000000000100301E2F0000000000000000AC
+:1016C000002F022700000000000000000CE00000D6
+:1016D000000000000000000000600000000001E9C0
+:1016E0000000000100531E27000001E50000FFFF7D
+:1016F00040280E20000000000000000F00260E23EE
+:101700000000000000000010C021122000000000B6
+:101710000000000F0026122400000000000000005E
+:1017200000201411000000000000000000601811EB
+:10173000000002BB0001A1FD0020441100000000D8
+:1017400000000000002F022B00000000000000003D
+:101750000CE00000000001F8000000100022162834
+:1017600000000000FFFF0000002816250000000018
+:101770000000FFFF00281A29000000000000000000
+:10178000002948C500000000000000000020480AB1
+:10179000000000000000000000202C1100000000EC
+:1017A000000000100022162300000000FFFF0000D0
+:1017B00000281625000000000000FFFF00281A2462
+:1017C0000000000000000000002948C500000000E3
+:1017D0000000000000731503000002050000000077
+:1017E0000020180500000000000000000073152410
+:1017F0000000020500000000002D14C500000000DC
+:1018000000000000003008A20000000000000000FE
+:101810000020480200000000000000000020280214
+:101820000000000000000000002020030000000075
+:101830000000000000802404000000000000000FF1
+:1018400000210225000000000000000014C000007C
+:101850000000068900000000002B140500000000B5
+:1018600000000001009016250000000000000000AC
+:10187000006000000000000B000000000060041188
+:10188000000003150000000000200411000000000B
+:101890000000000000600811000001B200002256A4
+:1018A00000204411000000000000001A00294A2214
+:1018B0000000000000000000C02000000000000048
+:1018C00000003FFF002F022F00000000000000007A
+:1018D0000CE000000000000000000000C020040038
+:1018E000000000000000225C002044110000000005
+:1018F0000000000300384A21000000000000A1FCA5
+:1019000000204411000000000000000100204811E8
+:10191000000000000000FFFF40281220000000002F
+:1019200000000010C0211A20000000000000FFFF8E
+:1019300040280E200000000000000010C0211620EA
+:10194000000000000000000000741465000002BBED
+:101950000001A1FD00604411000002E00000000150
+:10196000003306210000000000000000002F0221CB
+:1019700000000000000000000CC000000000021980
+:1019800000003FFF002F022F0000000000000000B9
+:101990000CC000000000021200000000C040040063
+:1019A000000000010000000000600000000006428E
+:1019B000000000000040040F0000021300000000BF
+:1019C000006000000000062E000000000060000023
+:1019D0000000064200000210006004110000031520
+:1019E0000000000000600000000001A000000000F6
+:1019F000006000000000019C00000000006000008A
+:101A0000000002BB0000000000600000000002A314
+:101A1000938000000020441100000000000000003E
+:101A2000002048080000000000000000002F022FE6
+:101A300000000000000000000AE000000000023288
+:101A400000000000006000000000013A00000000FB
+:101A50000040000000000236950000000020441104
+:101A60000000000000000000002F022F0000000016
+:101A7000000000000CE00000000002360000000042
+:101A8000C0404800000002339200000000204411D2
+:101A90000000000000000000C0204800000000001E
+:101AA0000000225600204411000000000000001633
+:101AB00000204811000000000000225C00204411BA
+:101AC000000000000000000300204811000000009A
+:101AD0000000A1FC002044110000000000000001F3
+:101AE00000204811000000000001A1FD0020441169
+:101AF000000000000000000000600411000002FB74
+:101B000000000000C04004000000000100000000D0
+:101B1000006000000000062E0000A00C0020441110
+:101B20000000000000000000C0204800000000008D
+:101B300000000000C040480000000000000000005D
+:101B4000006000000000000B0000001840210A2087
+:101B50000000000000000003002F0222000000002F
+:101B6000000000000AE000000000024C0000001429
+:101B70000020222D00000000000801010029222879
+:101B800000000000000000140020362800000000C3
+:101B90000000A30C00204411000000000000000021
+:101BA000C02048000000000000000000C0204800E5
+:101BB0000000000000000000C0404800000002518A
+:101BC00000000000006000000000000B000000109A
+:101BD00000600411000003153F8000000020041184
+:101BE000000000000000000000600811000001B2C9
+:101BF0000000225C002044110000000000000003EF
+:101C000000204811000000000000000000600000FB
+:101C10000000027C0000001700201E2D00000000C4
+:101C20000000000100211E2700000000000000004D
+:101C300014E000000000026A0000001200201E2DC7
+:101C4000000000000000FFFF00281E270000000029
+:101C50000000000000341C2700000000000000000D
+:101C600012C000000000025F0000000000201C11F4
+:101C70000000000000000000002F00E50000000050
+:101C80000000000008C00000000002620000000028
+:101C900000201407000000000000001200201E2D8C
+:101CA000000000000000001000211E2700000000BE
+:101CB0000000000000341C4700000000000000008D
+:101CC00012C00000000002670000000000201C118C
+:101CD0000000000000000000002F00E600000000EF
+:101CE0000000000008C000000000026A00000000C0
+:101CF0000020180700000000000000000060000045
+:101D0000000002C100002256002044110000000023
+:101D1000000000000034202300000000000000004C
+:101D200012C00000000002720000000000342044D5
+:101D3000000000000000000012C00000000002715E
+:101D40000000001600404811000002760000001854
+:101D500000404811000002760000000000342044DA
+:101D6000000000000000000012C00000000002752A
+:101D70000000001700404811000002760000001922
+:101D800000204811000000000000A1FC00204411C8
+:101D900000000000000000010020481100000000C9
+:101DA0000001A1FD00604411000002E900003FFFB6
+:101DB000002F022F00000000000000000CC00000F7
+:101DC0000000025600000000C040040000000001B6
+:101DD0000000001040210620000000000000FFFF6E
+:101DE000C0280A20000000000000001040210E2042
+:101DF000000000000000FFFFC028122000000000CB
+:101E00000000001040211620000000000000FFFF2D
+:101E1000C0881A200000000081000000002044114A
+:101E20000000000000000001002048110000000038
+:101E300000042004006044110000068A0000000035
+:101E4000006000000000062E00000000C0600000DE
+:101E5000000002A30000000500200A2D0000000081
+:101E60000000000800220A22000000000000002BF1
+:101E700000201A2D000000000000001C00201E2D74
+:101E8000000000000000700000281E270000000075
+:101E90000000000000311CE6000000000000002AE5
+:101EA00000201A2D000000000000000C00221A265D
+:101EB0000000000000000000002F00E6000000000D
+:101EC0000000000006E00000000002920000000098
+:101ED00000201C11000000000000000000200C1178
+:101EE000000000000000002B00203623000000004E
+:101EF0000000001000201811000000000000000089
+:101F000000691CE20000012F9380000000204411B2
+:101F10000000000000000000002048070000000052
+:101F200095000000002044110000000000000000A7
+:101F3000002F022F00000000000000000CE0000055
+:101F40000000029D0000000100333E2F0000000051
+:101F500000000000D90048000000000092000000CE
+:101F6000002044110000000000000000C0204800D4
+:101F7000000000000000001C0040362700000000A8
+:101F80000000000CC0220A20000000000000002910
+:101F9000002036220000000000000028C04036204B
+:101FA000000000000000A2A4002044110000000076
+:101FB000000000090020481100000000A1000000FE
+:101FC00000204411000000000000000100804811C2
+:101FD000000000000000002100201E2D0000000075
+:101FE00000000000002C1CE30000000000000021A5
+:101FF00000203627000000000000002200201E2DD7
+:102000000000000000000000002C1CE400000000A4
+:1020100000000022002036270000000000000023FE
+:1020200000201E2D0000000000000000003120A351
+:102030000000000000000000002D1D07000000004F
+:1020400000000023002036270000000000000024CC
+:1020500000201E2D0000000000000000003120C400
+:102060000000000000000000002D1D07000000001F
+:10207000000000240080362700000000000000213E
+:10208000002036230000000000000022002036243B
+:10209000000000000000000000311CA30000000050
+:1020A0000000002300203627000000000000000090
+:1020B00000311CC40000000000000024008036270E
+:1020C000000000000000001A002036270000000079
+:1020D0000000001B00203628000000000000001750
+:1020E00000201E2D00000000000000020021022739
+:1020F000000000000000000014C00000000002DC2E
+:102100000000000000400000000002D90000001A9A
+:1021100000203627000000000000001B00203628A9
+:10212000000000000000001700201E2D000000002D
+:102130000000000200210227000000000000000053
+:1021400014E00000000002D9000000030021022773
+:10215000000000000000000014E00000000002DCAD
+:102160000000002300201E2D0000000000000000E1
+:10217000002E00E1000000000000000002C000008E
+:10218000000002DC0000002100201E2D00000000E5
+:1021900000000000003120A100000000000000004D
+:1021A000002E00E8000000000000000006C0000053
+:1021B000000002DC0000002400201E2D00000000B2
+:1021C00000000000002E00E20000000000000000FF
+:1021D00002C00000000002DC0000002200201E2DD2
+:1021E0000000000000000000003120C200000000DC
+:1021F00000000000002E00E80000000000000000C9
+:1022000006C00000000002DC0000000000600000CA
+:10221000000006650000000000600000000002B53C
+:102220000000000000400000000002DE000000008E
+:1022300000600000000002B5000000000060000027
+:102240000000065C0000000000400000000002DE0C
+:102250000000000000600000000002A70000000075
+:1022600000400000000002DE0000001A00201E2DC9
+:10227000000000000000001B0080222D0000000074
+:102280000000001000221E230000000000000000DB
+:1022900000294887000000000000000000311CA356
+:1022A000000000000000001000221E2700000000B7
+:1022B0000000000000294887000000000000001016
+:1022C00000221E230000000000000000003120C496
+:1022D000000000000000FFFF00282228000000008E
+:1022E0000000000000894907000000000000001005
+:1022F00000221E2300000000000000000029488783
+:10230000000000000000001000221E21000000005C
+:102310000000000000294847000000000000000005
+:1023200000311CA3000000000000001000221E2746
+:1023300000000000000000000029488700000000A5
+:102340000000000000311CA100000000000000108F
+:1023500000221E270000000000000000002948475E
+:10236000000000000000001000221E2300000000FA
+:1023700000000000003120C4000000000000FFFF4A
+:102380000028222800000000000000000029490762
+:10239000000000000000001000221E2100000000CC
+:1023A00000000000003120C2000000000000FFFF1C
+:1023B00000282228000000000000000000894907D2
+:1023C000000000000000001000221E23000000009A
+:1023D0000000000000294887000000000000000104
+:1023E00000220A210000000000000000003308A2C3
+:1023F000000000000000001000221E22000000006B
+:102400000000001000212222000000000000000057
+:1024100000294907000000000000000000311CA353
+:10242000000000000000001000221E270000000035
+:1024300000000000002948870000000000000001A3
+:1024400000220A210000000000000000003008A265
+:10245000000000000000001000221E22000000000A
+:1024600000000010002122220000000000000000F7
+:1024700000294907000000000000001000221E2370
+:102480000000000000000000003120C40000000037
+:102490000000FFFF002822280000000000000000CC
+:1024A000002949070000000000000000003808C5AE
+:1024B00000000000000000000030084100000000A3
+:1024C0000000000100220A220000000000000000BD
+:1024D000003308A2000000000000001000221E22AD
+:1024E0000000000000000010002122220000000077
+:1024F00000000000008949070000000000000017EC
+:102500000020222D000000000000000014C0000088
+:1025100000000318FFFFFFEF002806210000000065
+:10252000000000140020222D000000000000F8E050
+:1025300000204411000000000000000000294901B3
+:1025400000000000000000000089490100000000B8
+:102550000000000000204811000000000000000002
+:102560000020481100000000060A02000080481107
+:102570000000000000000000C0200000000000007B
+:1025800097000000C020441100000000000000007F
+:10259000C0204811000000008A0000000020441103
+:1025A00000000000000000000020481100000000B2
+:1025B0000000225C00204411000000000000000028
+:1025C000C0204800000000000000A1FC00204411D1
+:1025D0000000000000000000C020480000000000D3
+:1025E00000000000C0200400000000000000000007
+:1025F00000A0000A00000000970000000020441125
+:102600000000000000000000002048110000000051
+:102610008A000000002044110000000000000000BB
+:1026200000204811000000000000225C002044113E
+:102630000000000000000000C02048000000000072
+:102640000000A1FC00204411000000000000000078
+:10265000C02048000000000000000000C02004006E
+:10266000000000000000000000A0000A00000000C0
+:10267000970000000020441100000000000000004E
+:1026800000204811000000008A00000000204411D2
+:1026900000000000000000000020481100000000C1
+:1026A0000000225C00204411000000000000000037
+:1026B000C0204800000000000000A1FC00204411E0
+:1026C0000000000000000000C020480000000000E2
+:1026D0000001A1FD002044110000000000000000E6
+:1026E000D90048000000000000000000C0200400E5
+:1026F000000000000000000000A0000A0000000030
+:1027000000002257002044110000000000000003D8
+:10271000C0484A20000000000000225D0020441153
+:102720000000000000000000C04048000000000061
+:1027300000000000006000000000064200000000F1
+:10274000C0200800000000000000225C00204411AE
+:10275000000000000000000300384A2200000000D2
+:102760000000A1FC00204411000000000000000057
+:10277000C0204800000000000001A1FD002044111D
+:102780000000000000000000002F022200000000F6
+:10279000000000000CE0000000000000000000004D
+:1027A00040204800000000000000000140304A20A6
+:1027B0000000000000000002C0304A2000000000BD
+:1027C0000000000100530A220000034B0000003FFC
+:1027D000C0280A20000000008100000000204411F1
+:1027E000000000000000000100204811000000006F
+:1027F000000021F800204411000000000000001833
+:102800000020481100000000000421F9006044117C
+:102810000000068A000000110021023000000000C4
+:102820000000000014E00000000003540000001449
+:10283000002F022200000000000000000CC0000079
+:10284000000003640000201000204411000000007C
+:102850000000800000204811000000000001A2A438
+:102860000020441100000000000000000060480249
+:102870000000036E00002100002044110000000051
+:1028800000000000C0204800000000000000000020
+:10289000C02048000000000000000000C0204800E8
+:1028A0000000000000000000C040480000000000E0
+:1028B00000000004002F02220000000000000000C1
+:1028C0000CC000000000036A00002010002044112A
+:1028D00000000000000080000020481100000000FF
+:1028E0000001A2A40020441100000000000000002C
+:1028F000004048020000035F00000028002F022271
+:1029000000000000000000000CC00000000005BD39
+:102910000001A2A4002044110000000000000000FB
+:10292000004048020000035F0000002C0020362613
+:102930000000000000000049002018110000000005
+:102940000000003F002048110000000000000001CE
+:1029500000331A260000000000000000002F0226AD
+:1029600000000000000000000CC000000000037028
+:102970000000002C00801A2D000000000000003F25
+:10298000C0280A200000000000000015002F0222CD
+:1029900000000000000000000CE0000000000386C2
+:1029A00000000006002F02220000000000000000CE
+:1029B0000CE00000000003B100000016002F02220E
+:1029C00000000000000000000CE00000000003B563
+:1029D00000000020002F0222000000000000000084
+:1029E0000CE000000000039C0000000F002F0222FA
+:1029F00000000000000000000CE00000000003A840
+:102A000000000010002F0222000000000000000063
+:102A10000CE00000000003A80000001E002F0222AE
+:102A200000000000000000000CE000000000039027
+:102A30000000A2A4002044110000000000000000DB
+:102A400000404802000000000800000000290A229F
+:102A5000000000000000000340210E2000000000E4
+:102A60000000000CC021122000000000000800003F
+:102A7000002812240000000000000014C0221620CC
+:102A80000000000000000000002914A40000000065
+:102A90000000A2A40020441100000000000000007B
+:102AA000002948A2000000000000A1FE00204411FF
+:102AB000000000000000000000404803000000008B
+:102AC000810000000020441100000000000000010F
+:102AD0000020481100000000000021F800204411EF
+:102AE0000000000000000016002048110000000057
+:102AF000000421F9006044110000068A000000155E
+:102B000000210230000000000000000014E000007E
+:102B1000000003920000210E00204411000000007C
+:102B200000000000C020480000000000000000007D
+:102B3000C0204800000000000000A2A400204411B2
+:102B400000000000000000000040480200000000FB
+:102B5000810000000020441100000000000000017E
+:102B60000020481100000000000021F8002044115E
+:102B700000000000000000170020481100000000C5
+:102B8000000421F9006044110000068A00000003DF
+:102B900000210230000000000000000014E00000EE
+:102BA0000000039E000021080020441100000000E6
+:102BB00000000000C02048000000000000000000ED
+:102BC000C0204800000000000000A2A40020441122
+:102BD000000000000000000000404802000000006B
+:102BE0000000A2A40020441100000000000000002A
+:102BF0000020480200000000800000000020441176
+:102C0000000000000000000000204811000000004B
+:102C100081000000002044110000000000000010AE
+:102C200000204811000000000000000000200010FB
+:102C3000000000000000000014C00000000003AE0F
+:102C40000000000000400000000000000000201014
+:102C50000020441100000000000080000020481106
+:102C6000000000000001A2A40020441100000000A8
+:102C70000000000600404811000000000000201085
+:102C800000204411000000000000800000204811D6
+:102C9000000000000001A2A4002044110000000078
+:102CA00000000016006048110000036E00000000E4
+:102CB000004000000000000000000000C0200800EC
+:102CC0000000000000000000C0200C000000000018
+:102CD0000000001D00210223000000000000000091
+:102CE00014E00000000003CE810000000020441129
+:102CF000000000000000000100204811000000005A
+:102D0000000021F80020441100000000000000181D
+:102D10000020481100000000000421F90060441167
+:102D20000000068A000000110021023000000000AF
+:102D30000000000014E00000000003C000002100BB
+:102D400000204411000000000000000000204802A4
+:102D50000000000000000000002048030000000008
+:102D6000BABECAFE0020481100000000CAFEBABE6A
+:102D70000020481100000000000020100020441135
+:102D8000000000000000800000204811000000004A
+:102D90000000A2A400204411000000000000000474
+:102DA0000040481100000000000021700020441184
+:102DB00000000000000000000020480200000000A9
+:102DC0000000000000204803000000008100000017
+:102DD00000204411000000000000000A00204811FB
+:102DE00000000000000000000020001000000000B3
+:102DF0000000000014C00000000003D38C0000009D
+:102E00000020441100000000CAFEBABE0040481174
+:102E100000000000810000000020441100000000BC
+:102E200000000001002048110000000000003FFFEA
+:102E300040280A20000000008000000040280E20EA
+:102E40000000000040000000C02812200000000028
+:102E500000040000006946220000068A000000000D
+:102E6000002014100000000000000000002F0223CA
+:102E700000000000000000000CC00000000003E1A2
+:102E800000000000C0401800000003E400003FFF05
+:102E9000C0281A2000000000000400000069462637
+:102EA0000000068A0000000000201810000000004A
+:102EB00000000000002F02240000000000000000BD
+:102EC0000CC00000000003E700000000C0401C0030
+:102ED000000003EA00003FFFC0281E2000000000A1
+:102EE00000040000006946270000068A0000000078
+:102EF00000201C1000000000000000000020440220
+:102F00000000000000000000002820C500000000B4
+:102F100000000000004948E800000000A580000013
+:102F200000200811000000000000200000200C110B
+:102F30000000000083000000006044110000041243
+:102F4000000000000020440200000000000000001B
+:102F5000C0204800000000000000000040204800A1
+:102F6000000000000000001FC0210220000000003F
+:102F70000000000014C00000000003F70000201053
+:102F800000204411000000000000800000204811D3
+:102F9000000000000000FFFFC0481220000003FFF7
+:102FA000A780000000200811000000000000A00021
+:102FB00000200C110000000083000000006044119C
+:102FC0000000041200000000002044020000000085
+:102FD00000000000C02048000000000000000000C9
+:102FE000C0204800000000000000FFFFC0281220A1
+:102FF00000000000830000000020441100000000D9
+:103000000000000000304883000000008400000041
+:10301000002044110000000000000000C020480013
+:1030200000000000000000001D0000000000000083
+:103030008300000000604411000004120000000042
+:10304000C040040000000001A98000000020081119
+:10305000000000000000C00000400C11000003FA56
+:10306000AB80000000200811000000000000F8E024
+:1030700000400C11000003FAAD8000000020081190
+:10308000000000000000F88000400C11000003FA6E
+:10309000B380000000200811000000000000F3FCD5
+:1030A00000400C11000003FAAF800000002008115E
+:1030B000000000000000E00000400C11000003FAD6
+:1030C000B180000000200811000000000000F000A6
+:1030D00000400C11000003FA83000000002044119E
+:1030E00000000000000021480020481100000000FE
+:1030F00084000000002044110000000000000000D7
+:10310000C020480000000000000000001D0000007A
+:10311000000000000000000000800000000000002F
+:1031200001182000C0304620000000000000000010
+:10313000D90048000000000000000000C02004008A
+:10314000000000000000000000A0000A00000000D5
+:103150000218A000C030462000000000000000005F
+:10316000D90048000000000000000000C02004005A
+:10317000000000000000000000A0000A00000000A5
+:103180000318C000C030462000000000000000000E
+:10319000D90048000000000000000000C02004002A
+:1031A000000000000000000000A0000A0000000075
+:1031B0000418F8E0C03046200000000000000000C5
+:1031C000D90048000000000000000000C0200400FA
+:1031D000000000000000000000A0000A0000000045
+:1031E0000518F880C03046200000000000000000F4
+:1031F000D90048000000000000000000C0200400CA
+:10320000000000000000000000A0000A0000000014
+:103210000618E000C030462000000000000000005A
+:10322000D90048000000000000000000C020040099
+:10323000000000000000000000A0000A00000000E4
+:103240000718F000C0304620000000000000000019
+:10325000D90048000000000000000000C020040069
+:10326000000000000000000000A0000A00000000B4
+:103270000818F3FCC03046200000000000000000E9
+:10328000D90048000000000000000000C020040039
+:10329000000000000000000000A0000A0000000084
+:1032A0000000003000200A2D000000000000000097
+:1032B000C0290C4000000000000000300020362330
+:1032C0000000000000000000C0200400000000001A
+:1032D0000000000000A0000A0000000086000000BE
+:1032E00000204411000000000000000000404801E0
+:1032F0000000000085000000C02044110000000014
+:103300000000000000404801000000000000217C97
+:10331000002044110000000000000000C020480010
+:103320000000000000000000C02048000000000075
+:1033300000000000C02048000000000081000000E4
+:10334000002044110000000000000001002048118E
+:103350000000000000000000C02008000000000085
+:103360000000000017000000000000000004217FA2
+:10337000006044110000068A0000001F0021023096
+:10338000000000000000000014C000000000000069
+:103390000000000000404C02000004480000000053
+:1033A000C0200C000000000000000000C020100041
+:1033B0000000000000000000C02014000000000019
+:1033C00000000000C0201800000000000000000005
+:1033D000C0201C000000000000007F0000280A211F
+:1033E0000000000000004500002F02220000000045
+:1033F000000000000CE00000000004560000000087
+:10340000C0202000000000000000000017000000A5
+:10341000000000000000001000280A230000000047
+:1034200000000010002F0222000000000000000039
+:103430000CE000000000045E810000000020441148
+:103440000000000000000001002048110000000002
+:1034500000040000006946240000068A0000000005
+:1034600000400000000004638100000000204411BF
+:1034700000000000000000000020481100000000D3
+:103480000000216D00204411000000000000000039
+:103490000020480400000000000000000060480513
+:1034A0000000068F00000000002824F0000000004B
+:1034B0000000000700280A230000000000000001AF
+:1034C000002F022200000000000000000AE00000BF
+:1034D0000000046A00000000002F00C90000000086
+:1034E0000000000004E00000000004830000000071
+:1034F000004000000000049000000002002F0222A3
+:1035000000000000000000000AE000000000046F5E
+:1035100000000000002F00C90000000000000000B3
+:1035200002E00000000004830000000000400000F2
+:103530000000049000000003002F022200000000A1
+:10354000000000000AE00000000004740000000019
+:10355000002F00C900000000000000000CE0000087
+:103560000000048300000000004000000000049000
+:1035700000000004002F02220000000000000000F4
+:103580000AE000000000047900000000002F00C9DC
+:1035900000000000000000000AE0000000000483BA
+:1035A0000000000000400000000004900000000542
+:1035B000002F022200000000000000000AE00000CE
+:1035C0000000047E00000000002F00C90000000081
+:1035D0000000000006E0000000000483000000007E
+:1035E000004000000000049000000006002F0222AE
+:1035F00000000000000000000AE00000000004835A
+:1036000000000000002F00C90000000000000000C2
+:1036100008E00000000004830000000000400000FB
+:103620000000049000007F0000280A210000000034
+:1036300000004500002F02220000000000000000F2
+:103640000AE00000000000000000000800210A233A
+:10365000000000000000000014C000000000048D05
+:10366000000021690020441100000000000000005B
+:10367000C02048000000000000000000C0204800FA
+:103680000000000000000000C02048000000000012
+:10369000CAFEBABE00404811000000000000000051
+:1036A000C02044000000000000000000C020000016
+:1036B0000000000000000000C040480000000000C2
+:1036C00000007F0000280A210000000000004500E3
+:1036D000002F022200000000000000000AE00000AD
+:1036E0000000049600000000C02000000000000060
+:1036F00000000000C02000000000000000000000EA
+:10370000C0400000000000000000000000404C0825
+:103710000000045600000000C02008000000000067
+:103720000000001040210E200000000000000011E9
+:10373000402112200000000000000012402116204D
+:10374000000000000000216900204411000000007A
+:1037500000000000002048020000000000000000FF
+:1037600000210225000000000000000014E000001D
+:10377000000004A000040000C0494A20000004A189
+:10378000FFFBFFFFC0284A200000000000000000EF
+:1037900000210223000000000000000014E00000EF
+:1037A000000004AD00000000C02048000000000040
+:1037B00000000000C02048000000000000000000E1
+:1037C00000210224000000000000000014C00000DE
+:1037D00000000000810000000020441100000000F3
+:1037E0000000000C00204811000000000000000054
+:1037F00000200010000000000000000014C00000C5
+:10380000000004A9A00000000020441100000000F6
+:10381000CAFEBABE0040481100000000810000004E
+:1038200000204411000000000000000400204811A6
+:10383000000000000000216B002044110000000087
+:1038400000000000C02048100000000081000000BF
+:103850000020441100000000000000050020481175
+:10386000000000000000216C002044110000000056
+:1038700000000000C0204810000000000000000010
+:10388000002F022400000000000000000CE00000F7
+:10389000000000000000000000400000000004A73D
+:1038A00000000000C0210A2000000000000000000D
+:1038B00014C00000000004C081000000002044117A
+:1038C000000000000000000000204811000000007F
+:1038D0000000216D002044110000000000000000E5
+:1038E000C02048000000000000000000C060480048
+:1038F0000000068F0000000000400000000004C42B
+:1039000081000000002044110000000000000001C0
+:10391000002048110000000000040000C0294620DB
+:103920000000000000000000C06000000000068AE7
+:103930000000000100210222000000000000000041
+:1039400014C00000000004CB0000216900204411D5
+:103950000000000000000000C0204800000000003F
+:1039600000000000C020480000000000000000002F
+:103970000020481000000000CAFEBABE00404811F6
+:103980000000000000000000C02044000000000013
+:1039900000000000C040481000000000810000004E
+:1039A0000020441100000000000000010020481128
+:1039B00000000000000021F8002044110000000079
+:1039C0000000000E0020481100000000000421F952
+:1039D000006044110000068A00000000002102304F
+:1039E000000000000000000014C00000000004CD32
+:1039F00000002180002044110000000000000000B1
+:103A0000C02048000000000000000000C0200000AE
+:103A10000000000000000000C0204800000000007E
+:103A200000000000C02000000000000000000000B6
+:103A3000C0404800000000000000000300333E2F9B
+:103A40000000000000000001002102210000000031
+:103A50000000000014E00000000004FD0000002C45
+:103A600000200A2D000000000004000018E00C11E6
+:103A7000000004EC0000000100333E2F00000000B5
+:103A80000000216900204411000000000000000037
+:103A90000020480200000000000000000020480351
+:103AA000000000000000000800300A2200000000B2
+:103AB00000000000C02048000000000000000000DE
+:103AC000C0204800000000000000216900204411CF
+:103AD000000000000000000000204802000000007C
+:103AE0000000000000204803000000000000000863
+:103AF00000300A220000000000000000C020480042
+:103B00000000000000000000D8C04800000004E0F1
+:103B100000002169002044110000000000000000A6
+:103B200000204802000000000000000000204803C0
+:103B3000000000000000000800300A220000000021
+:103B400000000000C020480000000000000000004D
+:103B5000C0204800000000000000002D0020122DB1
+:103B6000000000000000000000290C83000000009D
+:103B70000000216900204411000000000000000046
+:103B80000020480200000000000000000020480360
+:103B9000000000000000000800300A2200000000C1
+:103BA00000000000C02048000000000000000000ED
+:103BB000C020480000000000000000110021022485
+:103BC000000000000000000014C000000000000021
+:103BD0000000000000400000000004A70000002CCE
+:103BE000C0203620000000000000002DC04036201C
+:103BF000000000000000000F002102210000000072
+:103C00000000000014C000000000050200000000D9
+:103C1000006000000000000B00000000D900000060
+:103C20000000000000000000C0400400000000018F
+:103C3000B50000000020441100000000000020003A
+:103C40000020481100000000B600000000204411D0
+:103C5000000000000000A00000204811000000004B
+:103C6000B700000000204411000000000000C00068
+:103C70000020481100000000B8000000002044119E
+:103C8000000000000000F8E00020481100000000E3
+:103C9000B900000000204411000000000000F8807E
+:103CA0000020481100000000BA000000002044116C
+:103CB000000000000000E0000020481100000000AB
+:103CC000BB00000000204411000000000000F000D4
+:103CD0000020481100000000BC000000002044113A
+:103CE000000000000000F3FC00204811000000006C
+:103CF00081000000002044110000000000000002CC
+:103D00000020481100000000000000FF00280E30D5
+:103D10000000000000000000002F0223000000004F
+:103D2000000000000CC000000000051600000000AC
+:103D3000C0200800000000000000000014C00000C7
+:103D40000000052B0000000000200C110000000006
+:103D50000000001C00203623000000000000002BA3
+:103D60000020362300000000000000290020362338
+:103D700000000000000000280020362300000000A2
+:103D8000000000170020362300000000000000257E
+:103D9000002036230000000000000026002036230B
+:103DA0000000000000000015002036230000000085
+:103DB000000000160020362300000000FFFFE00096
+:103DC00000200C110000000000000021002036231C
+:103DD0000000000000000022002036230000000048
+:103DE00000001FFF00200C11000000000000002355
+:103DF00000203623000000000000002400203623AD
+:103E000000000000F1FFFFFF00283A2E0000000034
+:103E10000000001AC0220E20000000000000000078
+:103E20000029386E000000008100000000204411CD
+:103E30000000000000000006002048110000000003
+:103E40000000002A4020362000000000870000000B
+:103E5000002044110000000000000000C0204800C5
+:103E6000000000000000A1F4002044110000000048
+:103E700000000000002048100000000000000000CA
+:103E800000200C110000000000000030002036234C
+:103E9000000000009D000000002044110000000010
+:103EA0000000001F40214A20000000009600000092
+:103EB000002044110000000000000000C020480065
+:103EC0000000000000000000C0200C000000000006
+:103ED00000000000C0201000000000000000001FD3
+:103EE00000211624000000000000000014C00000A3
+:103EF000000000000000001D00203623000000002C
+:103F00000000000300281E2300000000000000083D
+:103F10000022222300000000FFFFF00000282228DA
+:103F20000000000000000000002920E80000000060
+:103F30000000001F002036280000000000000018CC
+:103F400000211E2300000000000000200020362772
+:103F50000000000000000002002216240000000003
+:103F600000000000003014A8000000000000001E47
+:103F700000203625000000000000000300211A2464
+:103F8000000000001000000000281A2600000000B9
+:103F9000EFFFFFFF00283A2E0000000000000000A5
+:103FA000004938CE000006780000000140280A20B1
+:103FB000000000000000000640280E200000000065
+:103FC00000000300C02812200000000000000008CC
+:103FD000002112240000000000000000C020162074
+:103FE0000000000000000000C0201A2000000000B7
+:103FF000000000000021022200000000000000007C
+:1040000014C000000000056381000000002044117E
+:104010000000000000000001002048110000000026
+:104020000000225800300A240000000000040000B4
+:10403000006946220000068A000021690020441120
+:104040000000000000000000002048050000000003
+:104050000002000000294A260000000000000000C5
+:104060000020481000000000CAFEBABE002048111F
+:104070000000000000000002002F022300000000EA
+:10408000000000000CC000000000056B00000000F4
+:10409000C0201C100000000000000000C040000014
+:1040A0000000057900000002002F0223000000003C
+:1040B000000000000CC000000000056B8100000043
+:1040C0000020441100000000000000010020481101
+:1040D000000000000000225800300A240000000008
+:1040E00000040000006946220000068A000000006B
+:1040F000C0201C100000000000000000C0400000B4
+:104100000000057900000000002F022300000000DD
+:10411000000000000CC000000000056F000000005F
+:10412000C0201C000000000000000000C040000093
+:104130000000057900000004002F022300000000A9
+:10414000000000000CC000000000057781000000A6
+:104150000020441100000000000000000020481171
+:10416000000000000000216D00204411000000004C
+:1041700000000000C0204800000000000000000017
+:10418000C06048000000068F0000000000401C10C6
+:104190000000057900000000C020000000000000C1
+:1041A00000000000C040000000000000000000000F
+:1041B0000EE000000000057B000000000060000031
+:1041C000000005C600000000002F022400000000CF
+:1041D000000000000CC000000000058C0000A2B729
+:1041E00000204411000000000000000000204807EB
+:1041F00000000000810000000020441100000000C9
+:104200000000000100204811000000000004A2B6D8
+:10421000006044110000068A0000001A00212230CC
+:104220000000000000000006002226300000000010
+:1042300000042004006044110000068A0000A2C4AB
+:10424000002044110000000000000000003048E998
+:10425000000000000000000000E000000000058AEF
+:104260000000A2D100204411000000000000000066
+:1042700000404808000000000000A2D100204411C6
+:10428000000000000000000100504A28000000006B
+:1042900000000001002F02240000000000000000C8
+:1042A0000CC000000000059D0000A2BB00204411CE
+:1042B000000000000000000000204807000000008F
+:1042C00081000000002044110000000000000001F7
+:1042D00000204811000000000004A2BA0060441150
+:1042E0000000068A0000001A0021223000000000B1
+:1042F0000000000600222630000000000004200418
+:10430000006044110000068A0000A2C5002044118C
+:104310000000000000000000003048E9000000003C
+:104320000000000000E000000000059B0000A2D299
+:104330000020441100000000000000000040480878
+:10434000000000000000A2D2002044110000000084
+:104350000000000100504A28000000000000000298
+:10436000002F022400000000000000000CC000002C
+:10437000000005AE0000A2BF0020441100000000B4
+:10438000000000000020480700000000810000003D
+:10439000002044110000000000000001002048112E
+:1043A000000000000004A2BE006044110000068A64
+:1043B0000000001A0021223000000000000000066A
+:1043C0000022263000000000000420040060441198
+:1043D0000000068A0000A2C6002044110000000070
+:1043E00000000000003048E900000000000000006C
+:1043F00000E00000000005AC0000A2D30020441142
+:10440000000000000000000000404808000000001C
+:104410000000A2D3002044110000000000000001B1
+:1044200000504A28000000000000A2C300204411F0
+:10443000000000000000000000204807000000000D
+:104440008100000000204411000000000000000175
+:1044500000204811000000000004A2C200604411C6
+:104460000000068A0000001A00212230000000002F
+:104470000000000600222630000000000004200496
+:10448000006044110000068A0000A2C70020441109
+:104490000000000000000000003048E900000000BB
+:1044A0000000000000E00000000005BB0000A2D4F6
+:1044B00000204411000000000000000000404808F7
+:1044C000000000000000A2D4002044110000000001
+:1044D0000000000100504A28000000008500000094
+:1044E00000204411000000000000000000204801EE
+:1044F000000000000000304A0020441100000000CD
+:104500000100000000204811000000000000000031
+:1045100000400000000005C1A4000000C0204411BC
+:104520000000000000000000C04048000000000043
+:1045300000000000C0600000000005C60000000090
+:10454000C0400400000000010000002C00203621C3
+:104550000000000081000000002044110000000065
+:1045600000000006002048110000000000000000CC
+:10457000002F023000000000000000000CC000000E
+:10458000000005CD00000000002004110000000024
+:104590000000003000403621000005E0000000303F
+:1045A0000020062D0000000000007E0000280621EB
+:1045B0000000000000000000002F022100000000A9
+:1045C000000000000CE00000000005E08100000099
+:1045D00000204411000000000000000100204811EC
+:1045E000000000000004A092006044110000068A50
+:1045F0000000003100203630000000000004A093CD
+:10460000006044110000068A0000003200203630AD
+:10461000000000000004A2B6006044110000068AF9
+:104620000000003300203630000000000004A2BA71
+:10463000006044110000068A00000034002036307B
+:10464000000000000004A2BE006044110000068AC1
+:104650000000003500203630000000000004A2C237
+:10466000006044110000068A000000360020363049
+:104670000000000000042004006044110000068ACD
+:104680000001A2A400204411000000000000003F2F
+:1046900000204811000000000000003F00204811E9
+:1046A000000000000000003F002048110000000052
+:1046B0000000003F0020481100000000000000053D
+:1046C00000204811000000000000A1F40020441167
+:1046D0000000000000000000002048110000000061
+:1046E00088000000002044110000000000000001CC
+:1046F000002048110000000081000000002044114B
+:10470000000000000000000600204811000000002A
+:1047100000000001002F0230000000000000000037
+:104720000CE0000000000629000000300020062DEB
+:104730000000000000000000002F02210000000027
+:10474000000000000CE000000000062981000000CD
+:10475000002044110000000000000001002048116A
+:104760000000000000007E0000280621000000007C
+:1047700000000000002F02210000000000000000E7
+:104780000CE00000000006020000A092002044118E
+:10479000000000000000003100204A2D0000000051
+:1047A0000000A0930020441100000000000000322F
+:1047B00000204A2D000000000000A2B60020441195
+:1047C000000000000000003300204A2D000000001F
+:1047D0000000A2BA002044110000000000000034D4
+:1047E00000204A2D000000000000A2BE002044115D
+:1047F000000000000000003500204A2D00000000ED
+:104800000000A2C200204411000000000000003699
+:1048100000204A2D00000000000000300020062D7E
+:1048200000000000000001FF002806210000000039
+:1048300000000000002F0221000000000000000026
+:104840000CE000000000062800000000002102210A
+:10485000000000000000000014C000000000060B73
+:104860000004A003006044110000068A0000A003B9
+:10487000002044110000000000000000002048104B
+:1048800000000000000000010021062100000000DF
+:104890000000000014C00000000006100004A0107A
+:1048A000006044110000068A0000A010002044119E
+:1048B0000000000000000000002048100000000080
+:1048C000000000010021062100000000000000009F
+:1048D000002F022100000000000000000CE000009A
+:1048E000000006280004A011006044110000068AA0
+:1048F0000000A01100204411000000000000000092
+:1049000000204810000000000004A01200604411C4
+:104910000000068A0000A0120020441100000000E0
+:104920000000000000204810000000000004A01358
+:10493000006044110000068A0000A013002044110A
+:1049400000000000000000000020481000000000EF
+:104950000004A014006044110000068A0000A014A6
+:10496000002044110000000000000000002048105A
+:10497000000000000004A015006044110000068A39
+:104980000000A015002044110000000000000000FD
+:1049900000204810000000000004A0160060441130
+:1049A0000000068A0000A01600204411000000004C
+:1049B0000000000000204810000000000004A017C4
+:1049C000006044110000068A0000A0170020441176
+:1049D000000000000000000000204810000000005F
+:1049E00000042004006044110000068A0000002C2E
+:1049F0000080062D00000000FF0000000020441190
+:104A0000000000000000000000204811000000002D
+:104A1000000000010020481100000000000000021A
+:104A20000080481100000000000000000EE00000BF
+:104A30000000063A000000300020062D00000000B3
+:104A40000000000200280621000000000000000015
+:104A5000002F022100000000000000000CE0000018
+:104A60000000063881000000002044110000000012
+:104A70000000000100204811000000000004200494
+:104A8000006044110000068A000010000020081198
+:104A9000000000000000002B002036220000000073
+:104AA00000000000006000000000063E0000000062
+:104AB00000600000000005C69800000000204411BE
+:104AC000000000000000000000804811000000000D
+:104AD00000000000C06000000000063E0000000072
+:104AE000C0400400000000010000A2A40020441106
+:104AF000000000000000002200204811000000001B
+:104B000089000000002044110000000000000001A6
+:104B1000004048110000062A9700000000204411C0
+:104B2000000000000000000000204811000000000C
+:104B30008A00000000204411000000000000000076
+:104B4000004048110000062A00000000006000003C
+:104B50000000065900002010002044110000000051
+:104B60000000800000204811000000000001A2A405
+:104B7000C020441100000000000000160060481131
+:104B80000000036E0000201000204411000000000F
+:104B9000000100000020481100000000810000001A
+:104BA0000020441100000000000000010020481116
+:104BB000000000000000217C0020441100000000E3
+:104BC000098000000020481100000000FFFFFFFFE7
+:104BD00000204811000000000000000000204811E3
+:104BE00000000000000000001700000000000000AE
+:104BF0000004217F006044110000068A0000001FAD
+:104C000000210230000000000000000014C000007D
+:104C1000000000000000000400404C11000006539A
+:104C2000000000000040000000000000000000172D
+:104C300000201E2D000000000000000400291E2797
+:104C40000000000000000017008036270000000070
+:104C50000000001700201E2D00000000FFFFFFFBDA
+:104C600000281E27000000000000001700803627E3
+:104C7000000000000000001700201E2D00000000B2
+:104C80000000000800291E27000000000000001797
+:104C900000803627000000000000001700201E2DB5
+:104CA00000000000FFFFFFF700281E2700000000A3
+:104CB00000000017008036270000000000002010D0
+:104CC0000020441100000000000080000020481176
+:104CD000000000000001A2A4002044110000000018
+:104CE00000000016006048110000036E0000201054
+:104CF00000204411000000000001000000204811C5
+:104D0000000000000000217C002044110000000091
+:104D1000018000000020481100000000FFFFFFFF9D
+:104D20000020481100000000000000000020481191
+:104D3000000000000000000017000000000000005C
+:104D4000810000000020441100000000000000016C
+:104D500000204811000000000004217F0060441181
+:104D60000000068A0000001F002102300000000041
+:104D70000000000014C000000000068900000010C0
+:104D800000404C110000066F00000000C02004002D
+:104D9000000000000000000038C00000000000001B
+:104DA0000000001D00200A2D000000000000001E71
+:104DB00000200E2D000000000000001F0020122D1A
+:104DC00000000000000000200020162D0000000060
+:104DD00000002169002044110000000000000000D4
+:104DE00000204804000000000000000000204805EA
+:104DF000000000000000000000204801000000004A
+:104E0000CAFEBABE002048110000000000000004E5
+:104E1000003012240000000000000000002F006499
+:104E200000000000000000000CC000000000068828
+:104E30000000000300281A22000000000000000803
+:104E40000022122200000000FFFFF00000281224C0
+:104E50000000000000000000002910C40000000055
+:104E60000000001F00403624000000000000000089
+:104E70000080000000000000000000001AC00000D8
+:104E80000000068A9F00000000204411000000007E
+:104E9000CAFEBABE00204811000000000000000059
+:104EA0001AE000000000068D0000000000800000F5
+:104EB00000000000000000001AC000000000068F83
+:104EC0009E0000000020441100000000CAFEBABE8F
+:104ED0000020481100000000000000001AE000005F
+:104EE00000000692000000000080000000000000AA
+:104EF00000000000006000000000000B0000100037
+:104F000000600411000003150000000000200411DF
+:104F1000000000000000000000600811000001B265
+:104F20000000225C0020441100000000000000038B
+:104F3000002048110000000000002256002044110B
+:104F4000000000000000001B0020481100000000CD
+:104F50000000A1FC0020441100000000000000013E
+:104F600000204811000000000001A1FDC0204411F4
+:104F7000000000000000002100201E2D00000000A5
+:104F80000000001000221E27000000000000002486
+:104F90000020222D000000000000FFFF0028222832
+:104FA0000000000000000000002949070000000088
+:104FB0000000000000204811000000000000002256
+:104FC0000020222D000000000000FFFF0028222802
+:104FD0000000000000000000002949070000000058
+:104FE0000000000000204811000000000000002325
+:104FF00000201E2D000000000000001000221E27CF
+:105000000000000000000000002949070000000027
+:1050100000000000004048110000000000000000F7
+:105020000000000000000000000000000000000080
+:105030000000000000000000000000000000000070
+:105040000000000000000000000000000000000060
+:105050000000000000000000000000000000000050
+:105060000000000000000000000000000000000040
+:105070000000000000000000000000000000000030
+:105080000000000000000000000000000000000020
+:105090000000000000000000000000000000000010
+:1050A0000000000000000000000000000000000000
+:1050B00000000000000000000000000000000000F0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:10517000000000000000000000000000000000002F
+:10518000000000000000000000000000000000001F
+:10519000000000000000000000000000000000000F
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000000000000000000DF
+:1051D00000000000000000000000000000000000CF
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:10522000000000000000000000000000000000007E
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000000000005E
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000000000000000000002E
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000000000000000000000000000FE
+:1052B000014204FF05BD02500000000001C3016867
+:1052C000043F05BD00000000022502090250015103
+:1052D000000000000223024502A00241000000007D
+:1052E00003D705BD05BD05BD000000000646064705
+:1052F000031F05BD0000000005BD05C203200340DB
+:1053000000000000032A0282034203340000000070
+:1053100005BD05BD05BD05BD0000000005BD054E70
+:1053200005BD05BD0000000003BA05BD04B8034477
+:10533000000000000497044D043D05BD000000007E
+:1053400004CD05BD044104DA00000000044D05044D
+:10535000035103750000000005BD05BD05BD05BD79
+:105360000000000005BD05BD05BD05BD0000000035
+:1053700005BD05BD063C05C40000000005BD05BD1A
+:10538000000705BD0000000005BD05BD05BD05BD4C
+:105390000000000005BD05BD05BD05BD0000000005
+:1053A00003F803ED0408040600000000040E040ADC
+:1053B000040C041000000000041C04180424042041
+:1053C00000000000042C0428043404300000000015
+:1053D00005BD05BD043805BD0000000005BD05BDC7
+:1053E00005BD05BD0000000005BD05BD05BD05BD31
+:1053F000000000000002067606940006000000008F
+:00000001FF
diff --git a/firmware/radeon/RV630_pfp.bin.ihex b/firmware/radeon/RV630_pfp.bin.ihex
new file mode 100644
index 0000000..f55292c
--- /dev/null
+++ b/firmware/radeon/RV630_pfp.bin.ihex
@@ -0,0 +1,145 @@
+:1000000000CA040000A00000007E828B007C038BED
+:10001000008001B8007C038B00D4401E00EE001E5F
+:1000200000CA040000A00000007E828B00C41838C3
+:1000300000CA240000CA2800009581A800C41C3A08
+:1000400000C3C00000CA080000CA0C00007C744B4A
+:1000500000C200050099C00000C41C3A007C744C2A
+:1000600000C0FFF000042C0400309002007D250049
+:1000700000351402007D350B00255403007CD5802B
+:1000800000259C030095C00400D5001B007EDDC147
+:10009000007D9D8000D6801B00D5801B00D4401EB3
+:1000A00000D5401E00D6401E00D6801E00D4801E03
+:1000B00000D4C01E009783D300D5C01E00CA08001C
+:1000C0000080001A00CA0C0000E4011E00D4001ECB
+:1000D0000080000C00C4183800E4013E00D4001E6B
+:1000E0000080000C00C4183800D4401E00EE001E32
+:1000F00000CA040000A00000007E828B00E4011E04
+:1001000000D4001E00D4401E00EE001E00CA0400F1
+:1001100000A00000007E828B00E4013E00D4001E9F
+:1001200000D4401E00EE001E00CA040000A0000023
+:10013000007E828B00CA180000D4401E00D5801EAD
+:100140000080005300D4007500D4401E00CA08008F
+:1001500000CA0C0000CA100000D4801900D4C018D6
+:1001600000D5001700D4801E00D4C01E00D5001E8C
+:1001700000E2001E00CA040000A00000007E828B86
+:1001800000CA080000D4806000D4401E0080000037
+:1001900000D4801E00CA080000D4806100D4401E34
+:1001A0000080000000D4801E00CA080000CA0C00B5
+:1001B00000D4401E00D4801600D4C01600D4801E87
+:1001C000008001B800D4C01E00C6084300CA0C005D
+:1001D00000CA10000094800400CA140000E420F358
+:1001E00000D4201300D5606500D4E01C00D5201C8D
+:1001F00000D5601C008000000006200100C60843F6
+:1002000000CA0C0000CA1000009483F700CA140052
+:1002100000E420F30080007900D4201300C60843D6
+:1002200000CA0C0000CA1000009883EF00CA140036
+:1002300000D400640080008D0000000000C414326F
+:1002400000C6184300C4082F0095400500C40C30B8
+:1002500000D4401E0080000000EE001E009583F5D3
+:1002600000C4103100D4403300D5206500D4A01C58
+:1002700000D4E01C00D5201C00E4015E00D4001E68
+:10028000008000000006200100CA1800000A2001BA
+:1002900000D6007600C408360098800700C61045D6
+:1002A0000095011000D4001F00D46062008000009F
+:1002B00000D4206200CC383500CC1433008401BB5C
+:1002C00000D4007200D5401E0080000000EE001E29
+:1002D00000E2001A008401BB00E2001A00CC104BBF
+:1002E00000CC0447002C9401007D098B0098400548
+:1002F000007D15CB00D4001A008001B800D4006D39
+:100300000034440100CC0C480098403A00CC2C4A00
+:100310000095800400CC0449008001B800D4001A84
+:1003200000D4C01A00282801008400F000CC10037B
+:100330000098801B0004380C008400F000CC1003EF
+:100340000098801700043808008400F000CC1003E7
+:100350000098801300043804008400F000CC1003DF
+:100360000098801400CC104C009A800900CC144DE9
+:10037000009840DC00D4006D00CC184800D5001A6D
+:1003800000D5401A008000C900D5801A0096C0D55B
+:1003900000D4006D008001B800D4006E009AC00344
+:1003A00000D4006D00D4006E0080000000EC007FDF
+:1003B000009AC0CC00D4006D008001B800D4006E5B
+:1003C00000CC140300CC180300CC1C03007D910367
+:1003D000007DD583007D190C0035CC1F0035701FC2
+:1003E000007CF0CB007CD08B00880000007E8E8BE0
+:1003F0000095C00400D4006E008001B800D4001A3B
+:1004000000D4C01A00CC080300CC0C0300CC1003AD
+:1004100000CC140300CC180300CC1C0300CC240334
+:1004200000CC28030035C41F0036B01F007C704B81
+:100430000034F01F007C704B0035701F007C704B47
+:10044000007D8881007DCCC1007E5101007E9541F8
+:10045000007C9082007CD4C2007C848B009AC00314
+:10046000007C8C8B002C88010098809E00D4006D4D
+:100470000098409C00D4006E00CC084C00CC0C4D81
+:1004800000CC104800D4801A00D4C01A00800101AA
+:1004900000D5001A00CC083200D40032009482D972
+:1004A00000CA0C0000D4401E0080000000D4001ED2
+:1004B00000E4011E00D4001E00CA080000CA0C009F
+:1004C00000CA100000D4401E00CA140000D4801ED0
+:1004D00000D4C01E00D5001E00D5401E00D54034FB
+:1004E0000080000000EE001E0028040400E2001A54
+:1004F00000E2001A00D4401A00CA380000CC0803F9
+:1005000000CC0C0300CC0C0300CC0C03009882BD83
+:1005100000000000008401BB00D7A06F0080000035
+:1005200000EE001F00CA040000C2FF0000CC083427
+:1005300000C13FFF007C74CB007CC90B007D010F24
+:10054000009902B0007C738B008401BB00D7A06FC0
+:100550000080000000EE001F00CA080000281900FB
+:10056000007D898B009580140028140400CA0C00BB
+:1005700000CA100000CA1C0000CA240000E2001FCC
+:1005800000D4C01A00D5001A00D5401A00CC1803B8
+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
+:1005A000007D9C4700984297000000000080016198
+:1005B00000D4C01A00D4401E00D4801E0080000069
+:1005C00000EE001E00E4011E00D4001E00D4401EF8
+:1005D00000EE001E00CA040000A00000007E828B16
+:1005E00000E4013E00D4001E00D4401E00EE001EB8
+:1005F00000CA040000A00000007E828B00CA080030
+:1006000000248C06000CCC060098C00600CC104ECE
+:100610000099000400D4007300E4011E00D4001E01
+:1006200000D4401E00D4801E0080000000EE001E9A
+:1006300000CA080000CA0C000034D01800251001C0
+:100640000095002100C17FFF00CA100000CA1400FD
+:1006500000CA180000D4801D00D4C01D007DB18BDD
+:1006600000C1420200C2C00100D5801D0034DC0E72
+:10067000007D5D4C007F734C00D7401E00D5001EEE
+:1006800000D5401E00C1420000C2C00000099C010C
+:100690000031DC10007F5F4C007F734C00042802A7
+:1006A000007D838000D5A86F00D5806600D7401EEE
+:1006B00000EC005E00C8240200C82402008001B8DB
+:1006C00000D6007600D4401E00D4801E00D4C01E88
+:1006D0000080000000EE001E0080000000EE001F01
+:1006E00000D4001F0080000000D4001F00D4001FB1
+:1006F0000088000000D4001F00000000000000007F
+:1007000000000000000000000000000000000000E9
+:1007100000000000000000000000000000000000D9
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:1008000000010171000201780003008F0004007FE5
+:10081000000500030006003F000700320008012C1D
+:1008200000090046000A0036001001B6001700A2B9
+:100830000022013A00230149002000B400240125D0
+:100840000027004D0028006A002A0060002B00529B
+:10085000002F0065003200870034017F003C015604
+:10086000003F00720041018C0044012E00550173CD
+:100870000056017A0060000B00610034006200380D
+:1008800000630038006400380065003800660038F6
+:10089000006700380068003A00690041006A0048BB
+:1008A000006B0048006C0048006D0048006E004876
+:1008B000006F00480000000600000006000000066F
+:1008C0000000000600000006000000060000000610
+:1008D0000000000600000006000000060000000600
+:1008E00000000006000000060000000600000006F0
+:1008F00000000006000000060000000600000006E0
+:00000001FF
diff --git a/firmware/radeon/RV635_me.bin.ihex b/firmware/radeon/RV635_me.bin.ihex
new file mode 100644
index 0000000..ba3a7e6
--- /dev/null
+++ b/firmware/radeon/RV635_me.bin.ihex
@@ -0,0 +1,1345 @@
+:1000000000000000C020040000000000000000000C
+:1000100000A0000A000000000000FFFF00284621A9
+:100020000000000000000000D900480000000000AF
+:1000300000000000C02004000000000000000000DC
+:1000400000A0000A000000000000000000E0000026
+:100050000000000000010000C02946200000000050
+:1000600000000000D900480000000000000000006F
+:10007000C0200400000000000000000000A0000AF2
+:10008000000000008100000000204411000000007A
+:1000900000000001002048110000000000042004BE
+:1000A000006044110000068A0000000000600000AB
+:1000B0000000062E00000000006000000000064264
+:1000C00000000000C02008000000000000000F0039
+:1000D000002816220000000000000008002116255C
+:1000E000000000000000001800203625000000007D
+:1000F0008D000000002044110000000000000004FA
+:10010000002F022500000000000000000CE00000AD
+:1001100000000018004120000040481100000019B4
+:100120000042200000204811000000008E00000066
+:1001300000204411000000000000002800204A2D8B
+:1001400000000000900000000020441100000000AA
+:100150000000000000204805000000000000000C26
+:1001600000211622000000000000000300281625D0
+:10017000000000000000001900211A220000000009
+:100180000000000400281A26000000000000000003
+:10019000002914C5000000000000001900203625C9
+:1001A0000000000000000000003A140200000000FF
+:1001B00000000016002116250000000000000003CA
+:1001C00000281625000000000000001700200E2D5A
+:1001D00000000000FFFFFFFC00280E2300000000CD
+:1001E00000000000002914A3000000000000001718
+:1001F00000203625000000000000800000280E22AC
+:10020000000000000000000700220E230000000094
+:10021000000000000029386E0000000020000000EF
+:1002200000280E22000000000000000600210E231E
+:1002300000000000000000000029386E00000000EF
+:100240000000000000220222000000000000000068
+:1002500014E0000000000038000000002EE0000064
+:1002600000000035000000002CE000000000003716
+:100270000000000000400E2D0000003900000008C2
+:1002800000200E2D00000000000000090040122D8B
+:10029000000000460000000100400E2D0000003963
+:1002A00000000000C0200C0000000000003FFFFC28
+:1002B0000028122300000000000000020022122487
+:1002C000000000000000001F00211E2300000000AD
+:1002D0000000000014E000000000003E00000008E4
+:1002E00000401C11000000410000000D00201E2DE8
+:1002F000000000000000000F00281E270000000082
+:100300000000000300221E27000000007FC0000044
+:1003100000281A23000000000000001400211A2603
+:10032000000000000000000100331A260000000059
+:100330000000000800221A26000000000000000053
+:1003400000290CC700000000000000270020362410
+:100350000000000000007F000028122100000000C3
+:1003600000001400002F0224000000000000000024
+:100370000CE000000000004B0000000100290E23EB
+:10038000000000000000000E0020362300000000E6
+:100390000000E0000020441100000000FFF8000011
+:1003A00000294A230000000000000000003A2C024F
+:1003B000000000000000000200220E2B00000000E0
+:1003C000FC00000000280E23000000000000000FC9
+:1003D000002036230000000000001FFF00294A23F0
+:1003E000000000000000002700204A2D000000004F
+:1003F000000000000020481100000000000000295B
+:1004000000200E2D00000000060A020000294A23E9
+:100410000000000000000000002048110000000063
+:100420000000000000204811000000000000000152
+:1004300000210222000000000000000014E0000083
+:1004400000000061000000002EE000000000005FDE
+:10045000000000002CE000000000005E0000000032
+:1004600000400E2D000000620000000100400E2D33
+:10047000000000620000000A00200E2D00000000B5
+:100480000000000B0040122D0000006A0000000078
+:10049000C0200C0000000000003FFFFC00281223D9
+:1004A00000000000000000020022122400000000F2
+:1004B0007FC0000000281623000000000000001488
+:1004C0000021162500000000000000010033162561
+:1004D000000000008000000000280E230000000043
+:1004E0000000000000290CA3000000003FFFFC00FA
+:1004F00000290E23000000000000001F00211E2321
+:10050000000000000000000014E000000000006D8A
+:100510000000010000401C11000000700000000DF0
+:1005200000201E2D00000000000000F000281E2703
+:10053000000000000000000400221E270000000050
+:100540008100000000204411000000000000000DA8
+:100550000020481100000000FFFFF0FF00281A30C3
+:10056000000000000000A02800204411000000004E
+:1005700000000000002948E6000000000000A0186C
+:1005800000204411000000003FFFFFFF00284A2325
+:10059000000000000000A010002044110000000036
+:1005A00000000000002048040000000000000030AF
+:1005B0000020162D00000000000000020029162572
+:1005C0000000000000000030002036250000000080
+:1005D000000000250020162D000000000000000093
+:1005E000002F00A300000000000000000CC000006D
+:1005F00000000083000000260020162D00000000EF
+:1006000000000000002F00A4000000000000000017
+:100610000CC000000000008400000000004000004A
+:100620000000008A000000250020362300000000A2
+:100630000000002600203624000000000000001703
+:1006400000201E2D000000000000000200210227F3
+:10065000000000000000000014E000000000008A1C
+:1006600000000000006000000000066500000000BF
+:1006700000600000000006590000000200210E2268
+:10068000000000000000000014C000000000008D09
+:1006900000000012C040362000000093000000005F
+:1006A0002EE0000000000091000000002CE000009F
+:1006B000000000900000000200400E2D000000929B
+:1006C0000000000300400E2D000000920000000C0E
+:1006D00000200E2D00000000000000120020362334
+:1006E000000000000000000300210E2200000000B6
+:1006F0000000000014C00000000000980000A00CE2
+:10070000002044110000000000000000C02048004C
+:100710000000000000000000C0404800000000A0F1
+:100720000000A00C002044110000000000000000A8
+:100730000020481100000000000000002EE0000032
+:100740000000009E000000002CE000000000009D62
+:100750000000000200400E2D0000009F000000037A
+:1007600000400E2D0000009F0000000C00200E2D08
+:10077000000000000000000000204803000000000E
+:1007800000000000003A0C0200000000003F0000E2
+:1007900000280E23000000000000001000210E239E
+:1007A00000000000000000110020362300000000BF
+:1007B0000000001E0021022B0000000000000000CD
+:1007C00014C00000000000A700000016C020362062
+:1007D000000000000000001F0021022B00000000AC
+:1007E0000000000014C00000000000AA0000001576
+:1007F000C0203620000000000000000800210E2B61
+:10080000000000000000007F00280E230000000010
+:1008100000000000002F0223000000000000000084
+:100820000CE00000000000E10000000027000000D4
+:10083000000000000000000000600000000002A3B3
+:1008400000000001002F0223000000000000000053
+:100850000AE00000000000B300000000006000009B
+:100860000000013A81000000002044110000000057
+:100870000000000600204811000000000000000CED
+:1008800000221E300000000099800000002044116A
+:1008900000000000000000040020122D00000000F5
+:1008A00000000008002212240000000000000010D8
+:1008B00000201811000000000000000000291CE4C6
+:1008C0000000000000000000006048070000012F49
+:1008D0009B00000000204411000000000000000008
+:1008E00000204802000000009C000000002044118D
+:1008F00000000000000000000033146F0000000042
+:100900000000000100333E23000000000000000052
+:10091000D9004800000000000000000000203C0555
+:1009200000000000810000000020441100000000D1
+:100930000000000E00204811000000000000000030
+:1009400000201010000000000000E007002044110B
+:10095000000000000000000F0021022B000000003A
+:100960000000000014C00000000000CB00F8FF08E9
+:1009700000204811000000009800000000404811CD
+:10098000000000DC000000F000280E220000000043
+:10099000000000A0002F0223000000000000000063
+:1009A0000CC00000000000DA0000001100200E2D35
+:1009B0000000000000000001002F022300000000E2
+:1009C000000000000CE00000000000D50000000264
+:1009D000002F022300000000000000000CE00000D7
+:1009E000000000D400003F0000400C11000000D6C1
+:1009F00000001F0000400C11000000D600000F0096
+:100A000000200C11000000000038000900294A23D2
+:100A1000000000003F00000000280E2B0000000036
+:100A20000000000200220E2300000000000000076A
+:100A300000494A23000000DC00380F09002048115B
+:100A400000000000680000070020481100000000BE
+:100A50000000000800214A270000000000000000FC
+:100A60000020481100000000060A020000294A2464
+:100A700000000000000000000020481100000000FD
+:100A80000000000000204811000000000000A20249
+:100A9000002044110000000000FF000000280E228A
+:100AA000000000000000008000294A230000000030
+:100AB0000000002700200E2D00000000000000268E
+:100AC0000020122D0000000000000000002F008315
+:100AD00000000000000000000CE00000000000EA40
+:100AE00000000000006000000000065F0000000041
+:100AF00000400000000000EB00000000006000006B
+:100B000000000662000000070020222D0000000007
+:100B10000000000500220E2200000000001000006E
+:100B200000280E23000000000000000000292068BB
+:100B30000000000000000000003A0C02000000006D
+:100B4000000000EF00280E2300000000000000005D
+:100B500000292068000000000000001700200E2D72
+:100B6000000000000000000300210223000000003C
+:100B70000000000014E00000000000F80000000B7E
+:100B800000210228000000000000000014C0000046
+:100B9000000000F8000004000029222800000000E6
+:100BA0000000001400203628000000000000001C97
+:100BB00000210E22000000000000000014C0000010
+:100BC000000000FD0000A30C002044110000000004
+:100BD0000000000000204811000000000000001E7E
+:100BE00000210E22000000000000000014C00000E0
+:100BF0000000010B0000A30F0020441100000000C2
+:100C00000000001100200E2D000000000000000177
+:100C1000002F022300000000000000000CC00000B4
+:100C200000000104FFFFFFFF004048110000010B1E
+:100C300000000002002F022300000000000000005E
+:100C40000CC00000000001070000FFFF0040481139
+:100C50000000010B00000004002F02230000000030
+:100C6000000000000CC000000000010A000000FFAE
+:100C7000004048110000010B000000010020481155
+:100C8000000000000002C400002044110000000029
+:100C90000000001F00210E220000000000000000E4
+:100CA00014C00000000001120000001040210E20BE
+:100CB00000000000000000130020362300000000A8
+:100CC0000000001840224A20000000000000001030
+:100CD000C0424A20000001140000000000200C1156
+:100CE0000000000000000013002036230000000078
+:100CF000000000000020481100000000000000007B
+:100D000000204811000000000000000A002010111F
+:100D10000000000000000000002F0224000000007E
+:100D2000000000000CE000000000011B00000000BB
+:100D300000204811000000000000000100531224B0
+:100D400000000117FFBFFFFF00283A2E000000003F
+:100D50000000001B00210222000000000000000033
+:100D600014C000000000012E81000000002044118A
+:100D7000000000000000000D0020481100000000ED
+:100D80000000001800220E3000000000FC000000EF
+:100D900000280E2300000000810000000020441104
+:100DA000000000000000000E0020481100000000BC
+:100DB0000000000000201010000000000000E00E05
+:100DC000002044110000000007F8FF08002048112F
+:100DD000000000000000000000294A23000000007D
+:100DE0000000001C00201E2D000000000000000874
+:100DF00000214A27000000000000000000204811E8
+:100E000000000000060A020000294A240000000039
+:100E10000000000000204811000000000000000059
+:100E200000204811000000000000000000800000C9
+:100E300000000000810000000020441100000000BC
+:100E40000000000100204811000000000000217C8B
+:100E50000020441100000000008000000020481124
+:100E60000000000000000000002048060000000014
+:100E70000000000800214A270000000000000000D8
+:100E800017000000000000000004217F00604411F2
+:100E90000000068A0000001F002102300000000050
+:100EA0000000000014C000000000068900000004DB
+:100EB00000404C1100000135810000000020441169
+:100EC00000000000000000010020481100000000A8
+:100ED000000021F800204411000000000000001C68
+:100EE0000020481100000000000421F900604411B6
+:100EF0000000068A000000110021023000000000FE
+:100F00000000000014E000000000013C00000000B0
+:100F100000800000000000000000000000600000F1
+:100F20000000000B00000000006004110000031529
+:100F3000000000000020041100000000000000007C
+:100F400000600811000001B2000000000060000015
+:100F5000000001600000FFFF40280E20000000009C
+:100F600000000010C0211220000000000000FFFF60
+:100F7000402806200000000000000010C0210A20C8
+:100F800000000000000000000034146100000000B8
+:100F90000000000000741882000002BB0001A1FDE7
+:100FA00000604411000002E000003FFF002F022F0C
+:100FB00000000000000000000CC00000000001471D
+:100FC00000000000C040040000000001000000001C
+:100FD000006000000000000B000000000060041131
+:100FE00000000315000000000020041100000000B4
+:100FF0000000000000600811000001B200003FFF87
+:10100000002F022F00000000000000000CE0000094
+:10101000000000000000000000600000000001600F
+:101020000000001040210E20000000000000FFFF23
+:10103000C0281220000000000000001040211620EF
+:10104000000000000000FFFFC0681A20000002BB83
+:101050000001A1FD00604411000002E000003FFF1C
+:10106000002F022F00000000000000000CC0000054
+:101070000000015800000000C04004000000000112
+:101080000000225C0020441100000000000000016C
+:1010900000300A2F000000000000000100210A2299
+:1010A000000000000000000300384A220000000099
+:1010B0000000225600204411000000000000001A29
+:1010C00000204811000000000000A1FC0020441195
+:1010D0000000000000000001008048110000000036
+:1010E00000000000006000000000000B0000000095
+:1010F000006000000000018F0000000000600000A0
+:10110000000001A000003FFF002F022F00000000A0
+:10111000000000000CE000000000000000000000E3
+:1011200000202C0800000000000000000020241116
+:101130000000000000000000002028110000000056
+:10114000000022560020441100000000000000169C
+:1011500000204811000000000000225C0020441123
+:101160000000000000000003002048110000000003
+:1011700093800000002044110000000000000002E5
+:1011800000221E290000000000000000007048EB53
+:101190000000019C0000000000600000000002BB95
+:1011A00000000001403306200000000000000000A5
+:1011B000C03024090000000000003FFF002F022F74
+:1011C00000000000000000000CE000000000000033
+:1011D0000000000000600000000002A3000000000A
+:1011E000002F022100000000000000000AE00000C3
+:1011F0000000018100000000006000000000013AD2
+:101200000000000000400000000001869500000082
+:10121000002044110000000000000000002F022107
+:1012200000000000000000000CE00000000001864B
+:1012300000000000C0204800000000000000000185
+:10124000005306210000018292000000002044119A
+:101250000000000000000000C0604800000001978E
+:101260000001A1FD00204411000000000000001159
+:101270000020062D00000000000000000078042A75
+:10128000000002FB00000000002028090000000010
+:1012900000003FFF002F022F0000000000000000B0
+:1012A0000CC000000000017400000000C0400400F9
+:1012B000000000010000021000600411000003158E
+:1012C00000003FFF002F022F000000000000000080
+:1012D0000CE000000000019400000015C020362042
+:1012E0000000000000000016C020362000000000B2
+:1012F0003F800000002004110000000046000000B4
+:1013000000600811000001B2000000000080000031
+:10131000000000000000A1FC0020441100000000BB
+:1013200000003FFF002F022F00000000000000001F
+:101330000CC000000000019B00000001008048116B
+:1013400000000000000000210080481100000000A3
+:101350000000FFFF40280E200000000000000010E9
+:10136000C0211220000000000000FFFF40281620CE
+:101370000000000000000010C0811A2000000000E2
+:101380008100000000204411000000000000000661
+:1013900000204811000000000000000800221E305C
+:1013A000000000000000002900201A2D00000000AD
+:1013B0000000E0000020441100000000FFFBFF09D6
+:1013C00000204811000000000000000F0020222D26
+:1013D0000000000000001FFF00294A280000000054
+:1013E000000000060020222D000000000000000088
+:1013F000002920E80000000000000000002048084C
+:101400000000000000000000002048110000000063
+:10141000060A020000294A26000000000000000021
+:1014200000204811000000000000000000204811CA
+:101430000000000000000100002018110000000062
+:101440000000000800621E280000012F00000008B4
+:1014500000822228000000000002C0000020441189
+:10146000000000000000001500600E2D000001BD0E
+:101470000000001600600E2D000001BD0000C00835
+:1014800000204411000000000000001700200E2D75
+:10149000000000000000000014C00000000001B9BE
+:1014A0000000000000200411000000000000000007
+:1014B0000020480100000000390000000020481111
+:1014C00000000000000000000020481100000000A3
+:1014D000000000000080480200000000000000182A
+:1014E00000202E2D0000000000000000003B0D63D6
+:1014F000000000000000000800224A230000000055
+:101500000000001000224A23000000000000001824
+:1015100000224A2300000000000000000080480371
+:101520000000000000000000006000000000000B50
+:10153000000010000060041100000315000000000E
+:1015400000200411000000000000000000600811ED
+:10155000000001B2000000070021062F000000007B
+:101560000000001300200A2D000000000000000110
+:1015700000202C11000000000000FFFF4028222066
+:10158000000000000000000F0026222800000000DC
+:101590000000001040212620000000000000000F85
+:1015A000002626290000000000000000002028027C
+:1015B000000000000000225600204411000000003E
+:1015C0000000001B00204811000000000000000087
+:1015D000002F022100000000000000000CE00000CD
+:1015E000000001E00000225C002044110000000027
+:1015F0000000008100204811000000000000A1FC54
+:1016000000204411000000000000000100204811EB
+:10161000000000000000008000201C1100000000FD
+:1016200000000000002F0227000000000000000062
+:101630000CE00000000001DC000000000060000081
+:10164000000001E90000000100531E27000001D83E
+:101650000000000100202C11000000000000001F0D
+:1016600000280A22000000000000001F00282A2A8B
+:10167000000000000000000100530621000001D11D
+:101680000000225C00204411000000000000000265
+:1016900000304A2F000000000000A1FC002044118F
+:1016A00000000000000000010020481100000000C0
+:1016B0000000000100301E2F0000000000000000AC
+:1016C000002F022700000000000000000CE00000D6
+:1016D000000000000000000000600000000001E9C0
+:1016E0000000000100531E27000001E50000FFFF7D
+:1016F00040280E20000000000000000F00260E23EE
+:101700000000000000000010C021122000000000B6
+:101710000000000F0026122400000000000000005E
+:1017200000201411000000000000000000601811EB
+:10173000000002BB0001A1FD0020441100000000D8
+:1017400000000000002F022B00000000000000003D
+:101750000CE00000000001F8000000100022162834
+:1017600000000000FFFF0000002816250000000018
+:101770000000FFFF00281A29000000000000000000
+:10178000002948C500000000000000000020480AB1
+:10179000000000000000000000202C1100000000EC
+:1017A000000000100022162300000000FFFF0000D0
+:1017B00000281625000000000000FFFF00281A2462
+:1017C0000000000000000000002948C500000000E3
+:1017D0000000000000731503000002050000000077
+:1017E0000020180500000000000000000073152410
+:1017F0000000020500000000002D14C500000000DC
+:1018000000000000003008A20000000000000000FE
+:101810000020480200000000000000000020280214
+:101820000000000000000000002020030000000075
+:101830000000000000802404000000000000000FF1
+:1018400000210225000000000000000014C000007C
+:101850000000068900000000002B140500000000B5
+:1018600000000001009016250000000000000000AC
+:10187000006000000000000B000000000060041188
+:10188000000003150000000000200411000000000B
+:101890000000000000600811000001B200002256A4
+:1018A00000204411000000000000001A00294A2214
+:1018B0000000000000000000C02000000000000048
+:1018C00000003FFF002F022F00000000000000007A
+:1018D0000CE000000000000000000000C020040038
+:1018E000000000000000225C002044110000000005
+:1018F0000000000300384A21000000000000A1FCA5
+:1019000000204411000000000000000100204811E8
+:10191000000000000000FFFF40281220000000002F
+:1019200000000010C0211A20000000000000FFFF8E
+:1019300040280E200000000000000010C0211620EA
+:10194000000000000000000000741465000002BBED
+:101950000001A1FD00604411000002E00000000150
+:10196000003306210000000000000000002F0221CB
+:1019700000000000000000000CC000000000021980
+:1019800000003FFF002F022F0000000000000000B9
+:101990000CC000000000021200000000C040040063
+:1019A000000000010000000000600000000006428E
+:1019B000000000000040040F0000021300000000BF
+:1019C000006000000000062E000000000060000023
+:1019D0000000064200000210006004110000031520
+:1019E0000000000000600000000001A000000000F6
+:1019F000006000000000019C00000000006000008A
+:101A0000000002BB0000000000600000000002A314
+:101A1000938000000020441100000000000000003E
+:101A2000002048080000000000000000002F022FE6
+:101A300000000000000000000AE000000000023288
+:101A400000000000006000000000013A00000000FB
+:101A50000040000000000236950000000020441104
+:101A60000000000000000000002F022F0000000016
+:101A7000000000000CE00000000002360000000042
+:101A8000C0404800000002339200000000204411D2
+:101A90000000000000000000C0204800000000001E
+:101AA0000000225600204411000000000000001633
+:101AB00000204811000000000000225C00204411BA
+:101AC000000000000000000300204811000000009A
+:101AD0000000A1FC002044110000000000000001F3
+:101AE00000204811000000000001A1FD0020441169
+:101AF000000000000000000000600411000002FB74
+:101B000000000000C04004000000000100000000D0
+:101B1000006000000000062E0000A00C0020441110
+:101B20000000000000000000C0204800000000008D
+:101B300000000000C040480000000000000000005D
+:101B4000006000000000000B0000001840210A2087
+:101B50000000000000000003002F0222000000002F
+:101B6000000000000AE000000000024C0000001429
+:101B70000020222D00000000000801010029222879
+:101B800000000000000000140020362800000000C3
+:101B90000000A30C00204411000000000000000021
+:101BA000C02048000000000000000000C0204800E5
+:101BB0000000000000000000C0404800000002518A
+:101BC00000000000006000000000000B000000109A
+:101BD00000600411000003153F8000000020041184
+:101BE000000000000000000000600811000001B2C9
+:101BF0000000225C002044110000000000000003EF
+:101C000000204811000000000000000000600000FB
+:101C10000000027C0000001700201E2D00000000C4
+:101C20000000000100211E2700000000000000004D
+:101C300014E000000000026A0000001200201E2DC7
+:101C4000000000000000FFFF00281E270000000029
+:101C50000000000000341C2700000000000000000D
+:101C600012C000000000025F0000000000201C11F4
+:101C70000000000000000000002F00E50000000050
+:101C80000000000008C00000000002620000000028
+:101C900000201407000000000000001200201E2D8C
+:101CA000000000000000001000211E2700000000BE
+:101CB0000000000000341C4700000000000000008D
+:101CC00012C00000000002670000000000201C118C
+:101CD0000000000000000000002F00E600000000EF
+:101CE0000000000008C000000000026A00000000C0
+:101CF0000020180700000000000000000060000045
+:101D0000000002C100002256002044110000000023
+:101D1000000000000034202300000000000000004C
+:101D200012C00000000002720000000000342044D5
+:101D3000000000000000000012C00000000002715E
+:101D40000000001600404811000002760000001854
+:101D500000404811000002760000000000342044DA
+:101D6000000000000000000012C00000000002752A
+:101D70000000001700404811000002760000001922
+:101D800000204811000000000000A1FC00204411C8
+:101D900000000000000000010020481100000000C9
+:101DA0000001A1FD00604411000002E900003FFFB6
+:101DB000002F022F00000000000000000CC00000F7
+:101DC0000000025600000000C040040000000001B6
+:101DD0000000001040210620000000000000FFFF6E
+:101DE000C0280A20000000000000001040210E2042
+:101DF000000000000000FFFFC028122000000000CB
+:101E00000000001040211620000000000000FFFF2D
+:101E1000C0881A200000000081000000002044114A
+:101E20000000000000000001002048110000000038
+:101E300000042004006044110000068A0000000035
+:101E4000006000000000062E00000000C0600000DE
+:101E5000000002A30000000500200A2D0000000081
+:101E60000000000800220A22000000000000002BF1
+:101E700000201A2D000000000000001C00201E2D74
+:101E8000000000000000700000281E270000000075
+:101E90000000000000311CE6000000000000002AE5
+:101EA00000201A2D000000000000000C00221A265D
+:101EB0000000000000000000002F00E6000000000D
+:101EC0000000000006E00000000002920000000098
+:101ED00000201C11000000000000000000200C1178
+:101EE000000000000000002B00203623000000004E
+:101EF0000000001000201811000000000000000089
+:101F000000691CE20000012F9380000000204411B2
+:101F10000000000000000000002048070000000052
+:101F200095000000002044110000000000000000A7
+:101F3000002F022F00000000000000000CE0000055
+:101F40000000029D0000000100333E2F0000000051
+:101F500000000000D90048000000000092000000CE
+:101F6000002044110000000000000000C0204800D4
+:101F7000000000000000001C0040362700000000A8
+:101F80000000000CC0220A20000000000000002910
+:101F9000002036220000000000000028C04036204B
+:101FA000000000000000A2A4002044110000000076
+:101FB000000000090020481100000000A1000000FE
+:101FC00000204411000000000000000100804811C2
+:101FD000000000000000002100201E2D0000000075
+:101FE00000000000002C1CE30000000000000021A5
+:101FF00000203627000000000000002200201E2DD7
+:102000000000000000000000002C1CE400000000A4
+:1020100000000022002036270000000000000023FE
+:1020200000201E2D0000000000000000003120A351
+:102030000000000000000000002D1D07000000004F
+:1020400000000023002036270000000000000024CC
+:1020500000201E2D0000000000000000003120C400
+:102060000000000000000000002D1D07000000001F
+:10207000000000240080362700000000000000213E
+:10208000002036230000000000000022002036243B
+:10209000000000000000000000311CA30000000050
+:1020A0000000002300203627000000000000000090
+:1020B00000311CC40000000000000024008036270E
+:1020C000000000000000001A002036270000000079
+:1020D0000000001B00203628000000000000001750
+:1020E00000201E2D00000000000000020021022739
+:1020F000000000000000000014C00000000002DC2E
+:102100000000000000400000000002D90000001A9A
+:1021100000203627000000000000001B00203628A9
+:10212000000000000000001700201E2D000000002D
+:102130000000000200210227000000000000000053
+:1021400014E00000000002D9000000030021022773
+:10215000000000000000000014E00000000002DCAD
+:102160000000002300201E2D0000000000000000E1
+:10217000002E00E1000000000000000002C000008E
+:10218000000002DC0000002100201E2D00000000E5
+:1021900000000000003120A100000000000000004D
+:1021A000002E00E8000000000000000006C0000053
+:1021B000000002DC0000002400201E2D00000000B2
+:1021C00000000000002E00E20000000000000000FF
+:1021D00002C00000000002DC0000002200201E2DD2
+:1021E0000000000000000000003120C200000000DC
+:1021F00000000000002E00E80000000000000000C9
+:1022000006C00000000002DC0000000000600000CA
+:10221000000006650000000000600000000002B53C
+:102220000000000000400000000002DE000000008E
+:1022300000600000000002B5000000000060000027
+:102240000000065C0000000000400000000002DE0C
+:102250000000000000600000000002A70000000075
+:1022600000400000000002DE0000001A00201E2DC9
+:10227000000000000000001B0080222D0000000074
+:102280000000001000221E230000000000000000DB
+:1022900000294887000000000000000000311CA356
+:1022A000000000000000001000221E2700000000B7
+:1022B0000000000000294887000000000000001016
+:1022C00000221E230000000000000000003120C496
+:1022D000000000000000FFFF00282228000000008E
+:1022E0000000000000894907000000000000001005
+:1022F00000221E2300000000000000000029488783
+:10230000000000000000001000221E21000000005C
+:102310000000000000294847000000000000000005
+:1023200000311CA3000000000000001000221E2746
+:1023300000000000000000000029488700000000A5
+:102340000000000000311CA100000000000000108F
+:1023500000221E270000000000000000002948475E
+:10236000000000000000001000221E2300000000FA
+:1023700000000000003120C4000000000000FFFF4A
+:102380000028222800000000000000000029490762
+:10239000000000000000001000221E2100000000CC
+:1023A00000000000003120C2000000000000FFFF1C
+:1023B00000282228000000000000000000894907D2
+:1023C000000000000000001000221E23000000009A
+:1023D0000000000000294887000000000000000104
+:1023E00000220A210000000000000000003308A2C3
+:1023F000000000000000001000221E22000000006B
+:102400000000001000212222000000000000000057
+:1024100000294907000000000000000000311CA353
+:10242000000000000000001000221E270000000035
+:1024300000000000002948870000000000000001A3
+:1024400000220A210000000000000000003008A265
+:10245000000000000000001000221E22000000000A
+:1024600000000010002122220000000000000000F7
+:1024700000294907000000000000001000221E2370
+:102480000000000000000000003120C40000000037
+:102490000000FFFF002822280000000000000000CC
+:1024A000002949070000000000000000003808C5AE
+:1024B00000000000000000000030084100000000A3
+:1024C0000000000100220A220000000000000000BD
+:1024D000003308A2000000000000001000221E22AD
+:1024E0000000000000000010002122220000000077
+:1024F00000000000008949070000000000000017EC
+:102500000020222D000000000000000014C0000088
+:1025100000000318FFFFFFEF002806210000000065
+:10252000000000140020222D000000000000F8E050
+:1025300000204411000000000000000000294901B3
+:1025400000000000000000000089490100000000B8
+:102550000000000000204811000000000000000002
+:102560000020481100000000060A02000080481107
+:102570000000000000000000C0200000000000007B
+:1025800097000000C020441100000000000000007F
+:10259000C0204811000000008A0000000020441103
+:1025A00000000000000000000020481100000000B2
+:1025B0000000225C00204411000000000000000028
+:1025C000C0204800000000000000A1FC00204411D1
+:1025D0000000000000000000C020480000000000D3
+:1025E00000000000C0200400000000000000000007
+:1025F00000A0000A00000000970000000020441125
+:102600000000000000000000002048110000000051
+:102610008A000000002044110000000000000000BB
+:1026200000204811000000000000225C002044113E
+:102630000000000000000000C02048000000000072
+:102640000000A1FC00204411000000000000000078
+:10265000C02048000000000000000000C02004006E
+:10266000000000000000000000A0000A00000000C0
+:10267000970000000020441100000000000000004E
+:1026800000204811000000008A00000000204411D2
+:1026900000000000000000000020481100000000C1
+:1026A0000000225C00204411000000000000000037
+:1026B000C0204800000000000000A1FC00204411E0
+:1026C0000000000000000000C020480000000000E2
+:1026D0000001A1FD002044110000000000000000E6
+:1026E000D90048000000000000000000C0200400E5
+:1026F000000000000000000000A0000A0000000030
+:1027000000002257002044110000000000000003D8
+:10271000C0484A20000000000000225D0020441153
+:102720000000000000000000C04048000000000061
+:1027300000000000006000000000064200000000F1
+:10274000C0200800000000000000225C00204411AE
+:10275000000000000000000300384A2200000000D2
+:102760000000A1FC00204411000000000000000057
+:10277000C0204800000000000001A1FD002044111D
+:102780000000000000000000002F022200000000F6
+:10279000000000000CE0000000000000000000004D
+:1027A00040204800000000000000000140304A20A6
+:1027B0000000000000000002C0304A2000000000BD
+:1027C0000000000100530A220000034B0000003FFC
+:1027D000C0280A20000000008100000000204411F1
+:1027E000000000000000000100204811000000006F
+:1027F000000021F800204411000000000000001833
+:102800000020481100000000000421F9006044117C
+:102810000000068A000000110021023000000000C4
+:102820000000000014E00000000003540000001449
+:10283000002F022200000000000000000CC0000079
+:10284000000003640000201000204411000000007C
+:102850000000800000204811000000000001A2A438
+:102860000020441100000000000000000060480249
+:102870000000036E00002100002044110000000051
+:1028800000000000C0204800000000000000000020
+:10289000C02048000000000000000000C0204800E8
+:1028A0000000000000000000C040480000000000E0
+:1028B00000000004002F02220000000000000000C1
+:1028C0000CC000000000036A00002010002044112A
+:1028D00000000000000080000020481100000000FF
+:1028E0000001A2A40020441100000000000000002C
+:1028F000004048020000035F00000028002F022271
+:1029000000000000000000000CC00000000005BD39
+:102910000001A2A4002044110000000000000000FB
+:10292000004048020000035F0000002C0020362613
+:102930000000000000000049002018110000000005
+:102940000000003F002048110000000000000001CE
+:1029500000331A260000000000000000002F0226AD
+:1029600000000000000000000CC000000000037028
+:102970000000002C00801A2D000000000000003F25
+:10298000C0280A200000000000000015002F0222CD
+:1029900000000000000000000CE0000000000386C2
+:1029A00000000006002F02220000000000000000CE
+:1029B0000CE00000000003B100000016002F02220E
+:1029C00000000000000000000CE00000000003B563
+:1029D00000000020002F0222000000000000000084
+:1029E0000CE000000000039C0000000F002F0222FA
+:1029F00000000000000000000CE00000000003A840
+:102A000000000010002F0222000000000000000063
+:102A10000CE00000000003A80000001E002F0222AE
+:102A200000000000000000000CE000000000039027
+:102A30000000A2A4002044110000000000000000DB
+:102A400000404802000000000800000000290A229F
+:102A5000000000000000000340210E2000000000E4
+:102A60000000000CC021122000000000000800003F
+:102A7000002812240000000000000014C0221620CC
+:102A80000000000000000000002914A40000000065
+:102A90000000A2A40020441100000000000000007B
+:102AA000002948A2000000000000A1FE00204411FF
+:102AB000000000000000000000404803000000008B
+:102AC000810000000020441100000000000000010F
+:102AD0000020481100000000000021F800204411EF
+:102AE0000000000000000016002048110000000057
+:102AF000000421F9006044110000068A000000155E
+:102B000000210230000000000000000014E000007E
+:102B1000000003920000210E00204411000000007C
+:102B200000000000C020480000000000000000007D
+:102B3000C0204800000000000000A2A400204411B2
+:102B400000000000000000000040480200000000FB
+:102B5000810000000020441100000000000000017E
+:102B60000020481100000000000021F8002044115E
+:102B700000000000000000170020481100000000C5
+:102B8000000421F9006044110000068A00000003DF
+:102B900000210230000000000000000014E00000EE
+:102BA0000000039E000021080020441100000000E6
+:102BB00000000000C02048000000000000000000ED
+:102BC000C0204800000000000000A2A40020441122
+:102BD000000000000000000000404802000000006B
+:102BE0000000A2A40020441100000000000000002A
+:102BF0000020480200000000800000000020441176
+:102C0000000000000000000000204811000000004B
+:102C100081000000002044110000000000000010AE
+:102C200000204811000000000000000000200010FB
+:102C3000000000000000000014C00000000003AE0F
+:102C40000000000000400000000000000000201014
+:102C50000020441100000000000080000020481106
+:102C6000000000000001A2A40020441100000000A8
+:102C70000000000600404811000000000000201085
+:102C800000204411000000000000800000204811D6
+:102C9000000000000001A2A4002044110000000078
+:102CA00000000016006048110000036E00000000E4
+:102CB000004000000000000000000000C0200800EC
+:102CC0000000000000000000C0200C000000000018
+:102CD0000000001D00210223000000000000000091
+:102CE00014E00000000003CE810000000020441129
+:102CF000000000000000000100204811000000005A
+:102D0000000021F80020441100000000000000181D
+:102D10000020481100000000000421F90060441167
+:102D20000000068A000000110021023000000000AF
+:102D30000000000014E00000000003C000002100BB
+:102D400000204411000000000000000000204802A4
+:102D50000000000000000000002048030000000008
+:102D6000BABECAFE0020481100000000CAFEBABE6A
+:102D70000020481100000000000020100020441135
+:102D8000000000000000800000204811000000004A
+:102D90000000A2A400204411000000000000000474
+:102DA0000040481100000000000021700020441184
+:102DB00000000000000000000020480200000000A9
+:102DC0000000000000204803000000008100000017
+:102DD00000204411000000000000000A00204811FB
+:102DE00000000000000000000020001000000000B3
+:102DF0000000000014C00000000003D38C0000009D
+:102E00000020441100000000CAFEBABE0040481174
+:102E100000000000810000000020441100000000BC
+:102E200000000001002048110000000000003FFFEA
+:102E300040280A20000000008000000040280E20EA
+:102E40000000000040000000C02812200000000028
+:102E500000040000006946220000068A000000000D
+:102E6000002014100000000000000000002F0223CA
+:102E700000000000000000000CC00000000003E1A2
+:102E800000000000C0401800000003E400003FFF05
+:102E9000C0281A2000000000000400000069462637
+:102EA0000000068A0000000000201810000000004A
+:102EB00000000000002F02240000000000000000BD
+:102EC0000CC00000000003E700000000C0401C0030
+:102ED000000003EA00003FFFC0281E2000000000A1
+:102EE00000040000006946270000068A0000000078
+:102EF00000201C1000000000000000000020440220
+:102F00000000000000000000002820C500000000B4
+:102F100000000000004948E800000000A580000013
+:102F200000200811000000000000200000200C110B
+:102F30000000000083000000006044110000041243
+:102F4000000000000020440200000000000000001B
+:102F5000C0204800000000000000000040204800A1
+:102F6000000000000000001FC0210220000000003F
+:102F70000000000014C00000000003F70000201053
+:102F800000204411000000000000800000204811D3
+:102F9000000000000000FFFFC0481220000003FFF7
+:102FA000A780000000200811000000000000A00021
+:102FB00000200C110000000083000000006044119C
+:102FC0000000041200000000002044020000000085
+:102FD00000000000C02048000000000000000000C9
+:102FE000C0204800000000000000FFFFC0281220A1
+:102FF00000000000830000000020441100000000D9
+:103000000000000000304883000000008400000041
+:10301000002044110000000000000000C020480013
+:1030200000000000000000001D0000000000000083
+:103030008300000000604411000004120000000042
+:10304000C040040000000001A98000000020081119
+:10305000000000000000C00000400C11000003FA56
+:10306000AB80000000200811000000000000F8E024
+:1030700000400C11000003FAAD8000000020081190
+:10308000000000000000F88000400C11000003FA6E
+:10309000B380000000200811000000000000F3FCD5
+:1030A00000400C11000003FAAF800000002008115E
+:1030B000000000000000E00000400C11000003FAD6
+:1030C000B180000000200811000000000000F000A6
+:1030D00000400C11000003FA83000000002044119E
+:1030E00000000000000021480020481100000000FE
+:1030F00084000000002044110000000000000000D7
+:10310000C020480000000000000000001D0000007A
+:10311000000000000000000000800000000000002F
+:1031200001182000C0304620000000000000000010
+:10313000D90048000000000000000000C02004008A
+:10314000000000000000000000A0000A00000000D5
+:103150000218A000C030462000000000000000005F
+:10316000D90048000000000000000000C02004005A
+:10317000000000000000000000A0000A00000000A5
+:103180000318C000C030462000000000000000000E
+:10319000D90048000000000000000000C02004002A
+:1031A000000000000000000000A0000A0000000075
+:1031B0000418F8E0C03046200000000000000000C5
+:1031C000D90048000000000000000000C0200400FA
+:1031D000000000000000000000A0000A0000000045
+:1031E0000518F880C03046200000000000000000F4
+:1031F000D90048000000000000000000C0200400CA
+:10320000000000000000000000A0000A0000000014
+:103210000618E000C030462000000000000000005A
+:10322000D90048000000000000000000C020040099
+:10323000000000000000000000A0000A00000000E4
+:103240000718F000C0304620000000000000000019
+:10325000D90048000000000000000000C020040069
+:10326000000000000000000000A0000A00000000B4
+:103270000818F3FCC03046200000000000000000E9
+:10328000D90048000000000000000000C020040039
+:10329000000000000000000000A0000A0000000084
+:1032A0000000003000200A2D000000000000000097
+:1032B000C0290C4000000000000000300020362330
+:1032C0000000000000000000C0200400000000001A
+:1032D0000000000000A0000A0000000086000000BE
+:1032E00000204411000000000000000000404801E0
+:1032F0000000000085000000C02044110000000014
+:103300000000000000404801000000000000217C97
+:10331000002044110000000000000000C020480010
+:103320000000000000000000C02048000000000075
+:1033300000000000C02048000000000081000000E4
+:10334000002044110000000000000001002048118E
+:103350000000000000000000C02008000000000085
+:103360000000000017000000000000000004217FA2
+:10337000006044110000068A0000001F0021023096
+:10338000000000000000000014C000000000000069
+:103390000000000000404C02000004480000000053
+:1033A000C0200C000000000000000000C020100041
+:1033B0000000000000000000C02014000000000019
+:1033C00000000000C0201800000000000000000005
+:1033D000C0201C000000000000007F0000280A211F
+:1033E0000000000000004500002F02220000000045
+:1033F000000000000CE00000000004560000000087
+:10340000C0202000000000000000000017000000A5
+:10341000000000000000001000280A230000000047
+:1034200000000010002F0222000000000000000039
+:103430000CE000000000045E810000000020441148
+:103440000000000000000001002048110000000002
+:1034500000040000006946240000068A0000000005
+:1034600000400000000004638100000000204411BF
+:1034700000000000000000000020481100000000D3
+:103480000000216D00204411000000000000000039
+:103490000020480400000000000000000060480513
+:1034A0000000068F00000000002824F0000000004B
+:1034B0000000000700280A230000000000000001AF
+:1034C000002F022200000000000000000AE00000BF
+:1034D0000000046A00000000002F00C90000000086
+:1034E0000000000004E00000000004830000000071
+:1034F000004000000000049000000002002F0222A3
+:1035000000000000000000000AE000000000046F5E
+:1035100000000000002F00C90000000000000000B3
+:1035200002E00000000004830000000000400000F2
+:103530000000049000000003002F022200000000A1
+:10354000000000000AE00000000004740000000019
+:10355000002F00C900000000000000000CE0000087
+:103560000000048300000000004000000000049000
+:1035700000000004002F02220000000000000000F4
+:103580000AE000000000047900000000002F00C9DC
+:1035900000000000000000000AE0000000000483BA
+:1035A0000000000000400000000004900000000542
+:1035B000002F022200000000000000000AE00000CE
+:1035C0000000047E00000000002F00C90000000081
+:1035D0000000000006E0000000000483000000007E
+:1035E000004000000000049000000006002F0222AE
+:1035F00000000000000000000AE00000000004835A
+:1036000000000000002F00C90000000000000000C2
+:1036100008E00000000004830000000000400000FB
+:103620000000049000007F0000280A210000000034
+:1036300000004500002F02220000000000000000F2
+:103640000AE00000000000000000000800210A233A
+:10365000000000000000000014C000000000048D05
+:10366000000021690020441100000000000000005B
+:10367000C02048000000000000000000C0204800FA
+:103680000000000000000000C02048000000000012
+:10369000CAFEBABE00404811000000000000000051
+:1036A000C02044000000000000000000C020000016
+:1036B0000000000000000000C040480000000000C2
+:1036C00000007F0000280A210000000000004500E3
+:1036D000002F022200000000000000000AE00000AD
+:1036E0000000049600000000C02000000000000060
+:1036F00000000000C02000000000000000000000EA
+:10370000C0400000000000000000000000404C0825
+:103710000000045600000000C02008000000000067
+:103720000000001040210E200000000000000011E9
+:10373000402112200000000000000012402116204D
+:10374000000000000000216900204411000000007A
+:1037500000000000002048020000000000000000FF
+:1037600000210225000000000000000014E000001D
+:10377000000004A000040000C0494A20000004A189
+:10378000FFFBFFFFC0284A200000000000000000EF
+:1037900000210223000000000000000014E00000EF
+:1037A000000004AD00000000C02048000000000040
+:1037B00000000000C02048000000000000000000E1
+:1037C00000210224000000000000000014C00000DE
+:1037D00000000000810000000020441100000000F3
+:1037E0000000000C00204811000000000000000054
+:1037F00000200010000000000000000014C00000C5
+:10380000000004A9A00000000020441100000000F6
+:10381000CAFEBABE0040481100000000810000004E
+:1038200000204411000000000000000400204811A6
+:10383000000000000000216B002044110000000087
+:1038400000000000C02048100000000081000000BF
+:103850000020441100000000000000050020481175
+:10386000000000000000216C002044110000000056
+:1038700000000000C0204810000000000000000010
+:10388000002F022400000000000000000CE00000F7
+:10389000000000000000000000400000000004A73D
+:1038A00000000000C0210A2000000000000000000D
+:1038B00014C00000000004C081000000002044117A
+:1038C000000000000000000000204811000000007F
+:1038D0000000216D002044110000000000000000E5
+:1038E000C02048000000000000000000C060480048
+:1038F0000000068F0000000000400000000004C42B
+:1039000081000000002044110000000000000001C0
+:10391000002048110000000000040000C0294620DB
+:103920000000000000000000C06000000000068AE7
+:103930000000000100210222000000000000000041
+:1039400014C00000000004CB0000216900204411D5
+:103950000000000000000000C0204800000000003F
+:1039600000000000C020480000000000000000002F
+:103970000020481000000000CAFEBABE00404811F6
+:103980000000000000000000C02044000000000013
+:1039900000000000C040481000000000810000004E
+:1039A0000020441100000000000000010020481128
+:1039B00000000000000021F8002044110000000079
+:1039C0000000000E0020481100000000000421F952
+:1039D000006044110000068A00000000002102304F
+:1039E000000000000000000014C00000000004CD32
+:1039F00000002180002044110000000000000000B1
+:103A0000C02048000000000000000000C0200000AE
+:103A10000000000000000000C0204800000000007E
+:103A200000000000C02000000000000000000000B6
+:103A3000C0404800000000000000000300333E2F9B
+:103A40000000000000000001002102210000000031
+:103A50000000000014E00000000004FD0000002C45
+:103A600000200A2D000000000004000018E00C11E6
+:103A7000000004EC0000000100333E2F00000000B5
+:103A80000000216900204411000000000000000037
+:103A90000020480200000000000000000020480351
+:103AA000000000000000000800300A2200000000B2
+:103AB00000000000C02048000000000000000000DE
+:103AC000C0204800000000000000216900204411CF
+:103AD000000000000000000000204802000000007C
+:103AE0000000000000204803000000000000000863
+:103AF00000300A220000000000000000C020480042
+:103B00000000000000000000D8C04800000004E0F1
+:103B100000002169002044110000000000000000A6
+:103B200000204802000000000000000000204803C0
+:103B3000000000000000000800300A220000000021
+:103B400000000000C020480000000000000000004D
+:103B5000C0204800000000000000002D0020122DB1
+:103B6000000000000000000000290C83000000009D
+:103B70000000216900204411000000000000000046
+:103B80000020480200000000000000000020480360
+:103B9000000000000000000800300A2200000000C1
+:103BA00000000000C02048000000000000000000ED
+:103BB000C020480000000000000000110021022485
+:103BC000000000000000000014C000000000000021
+:103BD0000000000000400000000004A70000002CCE
+:103BE000C0203620000000000000002DC04036201C
+:103BF000000000000000000F002102210000000072
+:103C00000000000014C000000000050200000000D9
+:103C1000006000000000000B00000000D900000060
+:103C20000000000000000000C0400400000000018F
+:103C3000B50000000020441100000000000020003A
+:103C40000020481100000000B600000000204411D0
+:103C5000000000000000A00000204811000000004B
+:103C6000B700000000204411000000000000C00068
+:103C70000020481100000000B8000000002044119E
+:103C8000000000000000F8E00020481100000000E3
+:103C9000B900000000204411000000000000F8807E
+:103CA0000020481100000000BA000000002044116C
+:103CB000000000000000E0000020481100000000AB
+:103CC000BB00000000204411000000000000F000D4
+:103CD0000020481100000000BC000000002044113A
+:103CE000000000000000F3FC00204811000000006C
+:103CF00081000000002044110000000000000002CC
+:103D00000020481100000000000000FF00280E30D5
+:103D10000000000000000000002F0223000000004F
+:103D2000000000000CC000000000051600000000AC
+:103D3000C0200800000000000000000014C00000C7
+:103D40000000052B0000000000200C110000000006
+:103D50000000001C00203623000000000000002BA3
+:103D60000020362300000000000000290020362338
+:103D700000000000000000280020362300000000A2
+:103D8000000000170020362300000000000000257E
+:103D9000002036230000000000000026002036230B
+:103DA0000000000000000015002036230000000085
+:103DB000000000160020362300000000FFFFE00096
+:103DC00000200C110000000000000021002036231C
+:103DD0000000000000000022002036230000000048
+:103DE00000001FFF00200C11000000000000002355
+:103DF00000203623000000000000002400203623AD
+:103E000000000000F1FFFFFF00283A2E0000000034
+:103E10000000001AC0220E20000000000000000078
+:103E20000029386E000000008100000000204411CD
+:103E30000000000000000006002048110000000003
+:103E40000000002A4020362000000000870000000B
+:103E5000002044110000000000000000C0204800C5
+:103E6000000000000000A1F4002044110000000048
+:103E700000000000002048100000000000000000CA
+:103E800000200C110000000000000030002036234C
+:103E9000000000009D000000002044110000000010
+:103EA0000000001F40214A20000000009600000092
+:103EB000002044110000000000000000C020480065
+:103EC0000000000000000000C0200C000000000006
+:103ED00000000000C0201000000000000000001FD3
+:103EE00000211624000000000000000014C00000A3
+:103EF000000000000000001D00203623000000002C
+:103F00000000000300281E2300000000000000083D
+:103F10000022222300000000FFFFF00000282228DA
+:103F20000000000000000000002920E80000000060
+:103F30000000001F002036280000000000000018CC
+:103F400000211E2300000000000000200020362772
+:103F50000000000000000002002216240000000003
+:103F600000000000003014A8000000000000001E47
+:103F700000203625000000000000000300211A2464
+:103F8000000000001000000000281A2600000000B9
+:103F9000EFFFFFFF00283A2E0000000000000000A5
+:103FA000004938CE000006780000000140280A20B1
+:103FB000000000000000000640280E200000000065
+:103FC00000000300C02812200000000000000008CC
+:103FD000002112240000000000000000C020162074
+:103FE0000000000000000000C0201A2000000000B7
+:103FF000000000000021022200000000000000007C
+:1040000014C000000000056381000000002044117E
+:104010000000000000000001002048110000000026
+:104020000000225800300A240000000000040000B4
+:10403000006946220000068A000021690020441120
+:104040000000000000000000002048050000000003
+:104050000002000000294A260000000000000000C5
+:104060000020481000000000CAFEBABE002048111F
+:104070000000000000000002002F022300000000EA
+:10408000000000000CC000000000056B00000000F4
+:10409000C0201C100000000000000000C040000014
+:1040A0000000057900000002002F0223000000003C
+:1040B000000000000CC000000000056B8100000043
+:1040C0000020441100000000000000010020481101
+:1040D000000000000000225800300A240000000008
+:1040E00000040000006946220000068A000000006B
+:1040F000C0201C100000000000000000C0400000B4
+:104100000000057900000000002F022300000000DD
+:10411000000000000CC000000000056F000000005F
+:10412000C0201C000000000000000000C040000093
+:104130000000057900000004002F022300000000A9
+:10414000000000000CC000000000057781000000A6
+:104150000020441100000000000000000020481171
+:10416000000000000000216D00204411000000004C
+:1041700000000000C0204800000000000000000017
+:10418000C06048000000068F0000000000401C10C6
+:104190000000057900000000C020000000000000C1
+:1041A00000000000C040000000000000000000000F
+:1041B0000EE000000000057B000000000060000031
+:1041C000000005C600000000002F022400000000CF
+:1041D000000000000CC000000000058C0000A2B729
+:1041E00000204411000000000000000000204807EB
+:1041F00000000000810000000020441100000000C9
+:104200000000000100204811000000000004A2B6D8
+:10421000006044110000068A0000001A00212230CC
+:104220000000000000000006002226300000000010
+:1042300000042004006044110000068A0000A2C4AB
+:10424000002044110000000000000000003048E998
+:10425000000000000000000000E000000000058AEF
+:104260000000A2D100204411000000000000000066
+:1042700000404808000000000000A2D100204411C6
+:10428000000000000000000100504A28000000006B
+:1042900000000001002F02240000000000000000C8
+:1042A0000CC000000000059D0000A2BB00204411CE
+:1042B000000000000000000000204807000000008F
+:1042C00081000000002044110000000000000001F7
+:1042D00000204811000000000004A2BA0060441150
+:1042E0000000068A0000001A0021223000000000B1
+:1042F0000000000600222630000000000004200418
+:10430000006044110000068A0000A2C5002044118C
+:104310000000000000000000003048E9000000003C
+:104320000000000000E000000000059B0000A2D299
+:104330000020441100000000000000000040480878
+:10434000000000000000A2D2002044110000000084
+:104350000000000100504A28000000000000000298
+:10436000002F022400000000000000000CC000002C
+:10437000000005AE0000A2BF0020441100000000B4
+:10438000000000000020480700000000810000003D
+:10439000002044110000000000000001002048112E
+:1043A000000000000004A2BE006044110000068A64
+:1043B0000000001A0021223000000000000000066A
+:1043C0000022263000000000000420040060441198
+:1043D0000000068A0000A2C6002044110000000070
+:1043E00000000000003048E900000000000000006C
+:1043F00000E00000000005AC0000A2D30020441142
+:10440000000000000000000000404808000000001C
+:104410000000A2D3002044110000000000000001B1
+:1044200000504A28000000000000A2C300204411F0
+:10443000000000000000000000204807000000000D
+:104440008100000000204411000000000000000175
+:1044500000204811000000000004A2C200604411C6
+:104460000000068A0000001A00212230000000002F
+:104470000000000600222630000000000004200496
+:10448000006044110000068A0000A2C70020441109
+:104490000000000000000000003048E900000000BB
+:1044A0000000000000E00000000005BB0000A2D4F6
+:1044B00000204411000000000000000000404808F7
+:1044C000000000000000A2D4002044110000000001
+:1044D0000000000100504A28000000008500000094
+:1044E00000204411000000000000000000204801EE
+:1044F000000000000000304A0020441100000000CD
+:104500000100000000204811000000000000000031
+:1045100000400000000005C1A4000000C0204411BC
+:104520000000000000000000C04048000000000043
+:1045300000000000C0600000000005C60000000090
+:10454000C0400400000000010000002C00203621C3
+:104550000000000081000000002044110000000065
+:1045600000000006002048110000000000000000CC
+:10457000002F023000000000000000000CC000000E
+:10458000000005CD00000000002004110000000024
+:104590000000003000403621000005E0000000303F
+:1045A0000020062D0000000000007E0000280621EB
+:1045B0000000000000000000002F022100000000A9
+:1045C000000000000CE00000000005E08100000099
+:1045D00000204411000000000000000100204811EC
+:1045E000000000000004A092006044110000068A50
+:1045F0000000003100203630000000000004A093CD
+:10460000006044110000068A0000003200203630AD
+:10461000000000000004A2B6006044110000068AF9
+:104620000000003300203630000000000004A2BA71
+:10463000006044110000068A00000034002036307B
+:10464000000000000004A2BE006044110000068AC1
+:104650000000003500203630000000000004A2C237
+:10466000006044110000068A000000360020363049
+:104670000000000000042004006044110000068ACD
+:104680000001A2A400204411000000000000003F2F
+:1046900000204811000000000000003F00204811E9
+:1046A000000000000000003F002048110000000052
+:1046B0000000003F0020481100000000000000053D
+:1046C00000204811000000000000A1F40020441167
+:1046D0000000000000000000002048110000000061
+:1046E00088000000002044110000000000000001CC
+:1046F000002048110000000081000000002044114B
+:10470000000000000000000600204811000000002A
+:1047100000000001002F0230000000000000000037
+:104720000CE0000000000629000000300020062DEB
+:104730000000000000000000002F02210000000027
+:10474000000000000CE000000000062981000000CD
+:10475000002044110000000000000001002048116A
+:104760000000000000007E0000280621000000007C
+:1047700000000000002F02210000000000000000E7
+:104780000CE00000000006020000A092002044118E
+:10479000000000000000003100204A2D0000000051
+:1047A0000000A0930020441100000000000000322F
+:1047B00000204A2D000000000000A2B60020441195
+:1047C000000000000000003300204A2D000000001F
+:1047D0000000A2BA002044110000000000000034D4
+:1047E00000204A2D000000000000A2BE002044115D
+:1047F000000000000000003500204A2D00000000ED
+:104800000000A2C200204411000000000000003699
+:1048100000204A2D00000000000000300020062D7E
+:1048200000000000000001FF002806210000000039
+:1048300000000000002F0221000000000000000026
+:104840000CE000000000062800000000002102210A
+:10485000000000000000000014C000000000060B73
+:104860000004A003006044110000068A0000A003B9
+:10487000002044110000000000000000002048104B
+:1048800000000000000000010021062100000000DF
+:104890000000000014C00000000006100004A0107A
+:1048A000006044110000068A0000A010002044119E
+:1048B0000000000000000000002048100000000080
+:1048C000000000010021062100000000000000009F
+:1048D000002F022100000000000000000CE000009A
+:1048E000000006280004A011006044110000068AA0
+:1048F0000000A01100204411000000000000000092
+:1049000000204810000000000004A01200604411C4
+:104910000000068A0000A0120020441100000000E0
+:104920000000000000204810000000000004A01358
+:10493000006044110000068A0000A013002044110A
+:1049400000000000000000000020481000000000EF
+:104950000004A014006044110000068A0000A014A6
+:10496000002044110000000000000000002048105A
+:10497000000000000004A015006044110000068A39
+:104980000000A015002044110000000000000000FD
+:1049900000204810000000000004A0160060441130
+:1049A0000000068A0000A01600204411000000004C
+:1049B0000000000000204810000000000004A017C4
+:1049C000006044110000068A0000A0170020441176
+:1049D000000000000000000000204810000000005F
+:1049E00000042004006044110000068A0000002C2E
+:1049F0000080062D00000000FF0000000020441190
+:104A0000000000000000000000204811000000002D
+:104A1000000000010020481100000000000000021A
+:104A20000080481100000000000000000EE00000BF
+:104A30000000063A000000300020062D00000000B3
+:104A40000000000200280621000000000000000015
+:104A5000002F022100000000000000000CE0000018
+:104A60000000063881000000002044110000000012
+:104A70000000000100204811000000000004200494
+:104A8000006044110000068A000010000020081198
+:104A9000000000000000002B002036220000000073
+:104AA00000000000006000000000063E0000000062
+:104AB00000600000000005C69800000000204411BE
+:104AC000000000000000000000804811000000000D
+:104AD00000000000C06000000000063E0000000072
+:104AE000C0400400000000010000A2A40020441106
+:104AF000000000000000002200204811000000001B
+:104B000089000000002044110000000000000001A6
+:104B1000004048110000062A9700000000204411C0
+:104B2000000000000000000000204811000000000C
+:104B30008A00000000204411000000000000000076
+:104B4000004048110000062A00000000006000003C
+:104B50000000065900002010002044110000000051
+:104B60000000800000204811000000000001A2A405
+:104B7000C020441100000000000000160060481131
+:104B80000000036E0000201000204411000000000F
+:104B9000000100000020481100000000810000001A
+:104BA0000020441100000000000000010020481116
+:104BB000000000000000217C0020441100000000E3
+:104BC000098000000020481100000000FFFFFFFFE7
+:104BD00000204811000000000000000000204811E3
+:104BE00000000000000000001700000000000000AE
+:104BF0000004217F006044110000068A0000001FAD
+:104C000000210230000000000000000014C000007D
+:104C1000000000000000000400404C11000006539A
+:104C2000000000000040000000000000000000172D
+:104C300000201E2D000000000000000400291E2797
+:104C40000000000000000017008036270000000070
+:104C50000000001700201E2D00000000FFFFFFFBDA
+:104C600000281E27000000000000001700803627E3
+:104C7000000000000000001700201E2D00000000B2
+:104C80000000000800291E27000000000000001797
+:104C900000803627000000000000001700201E2DB5
+:104CA00000000000FFFFFFF700281E2700000000A3
+:104CB00000000017008036270000000000002010D0
+:104CC0000020441100000000000080000020481176
+:104CD000000000000001A2A4002044110000000018
+:104CE00000000016006048110000036E0000201054
+:104CF00000204411000000000001000000204811C5
+:104D0000000000000000217C002044110000000091
+:104D1000018000000020481100000000FFFFFFFF9D
+:104D20000020481100000000000000000020481191
+:104D3000000000000000000017000000000000005C
+:104D4000810000000020441100000000000000016C
+:104D500000204811000000000004217F0060441181
+:104D60000000068A0000001F002102300000000041
+:104D70000000000014C000000000068900000010C0
+:104D800000404C110000066F00000000C02004002D
+:104D9000000000000000000038C00000000000001B
+:104DA0000000001D00200A2D000000000000001E71
+:104DB00000200E2D000000000000001F0020122D1A
+:104DC00000000000000000200020162D0000000060
+:104DD00000002169002044110000000000000000D4
+:104DE00000204804000000000000000000204805EA
+:104DF000000000000000000000204801000000004A
+:104E0000CAFEBABE002048110000000000000004E5
+:104E1000003012240000000000000000002F006499
+:104E200000000000000000000CC000000000068828
+:104E30000000000300281A22000000000000000803
+:104E40000022122200000000FFFFF00000281224C0
+:104E50000000000000000000002910C40000000055
+:104E60000000001F00403624000000000000000089
+:104E70000080000000000000000000001AC00000D8
+:104E80000000068A9F00000000204411000000007E
+:104E9000CAFEBABE00204811000000000000000059
+:104EA0001AE000000000068D0000000000800000F5
+:104EB00000000000000000001AC000000000068F83
+:104EC0009E0000000020441100000000CAFEBABE8F
+:104ED0000020481100000000000000001AE000005F
+:104EE00000000692000000000080000000000000AA
+:104EF00000000000006000000000000B0000100037
+:104F000000600411000003150000000000200411DF
+:104F1000000000000000000000600811000001B265
+:104F20000000225C0020441100000000000000038B
+:104F3000002048110000000000002256002044110B
+:104F4000000000000000001B0020481100000000CD
+:104F50000000A1FC0020441100000000000000013E
+:104F600000204811000000000001A1FDC0204411F4
+:104F7000000000000000002100201E2D00000000A5
+:104F80000000001000221E27000000000000002486
+:104F90000020222D000000000000FFFF0028222832
+:104FA0000000000000000000002949070000000088
+:104FB0000000000000204811000000000000002256
+:104FC0000020222D000000000000FFFF0028222802
+:104FD0000000000000000000002949070000000058
+:104FE0000000000000204811000000000000002325
+:104FF00000201E2D000000000000001000221E27CF
+:105000000000000000000000002949070000000027
+:1050100000000000004048110000000000000000F7
+:105020000000000000000000000000000000000080
+:105030000000000000000000000000000000000070
+:105040000000000000000000000000000000000060
+:105050000000000000000000000000000000000050
+:105060000000000000000000000000000000000040
+:105070000000000000000000000000000000000030
+:105080000000000000000000000000000000000020
+:105090000000000000000000000000000000000010
+:1050A0000000000000000000000000000000000000
+:1050B00000000000000000000000000000000000F0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:10517000000000000000000000000000000000002F
+:10518000000000000000000000000000000000001F
+:10519000000000000000000000000000000000000F
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000000000000000000DF
+:1051D00000000000000000000000000000000000CF
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:10522000000000000000000000000000000000007E
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000000000005E
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000000000000000000002E
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000000000000000000000000000FE
+:1052B000014204FF05BD02500000000001C3016867
+:1052C000043F05BD00000000022502090250015103
+:1052D000000000000223024502A00241000000007D
+:1052E00003D705BD05BD05BD000000000646064705
+:1052F000031F05BD0000000005BD05C203200340DB
+:1053000000000000032A0282034203340000000070
+:1053100005BD05BD05BD05BD0000000005BD054E70
+:1053200005BD05BD0000000003BA05BD04B8034477
+:10533000000000000497044D043D05BD000000007E
+:1053400004CD05BD044104DA00000000044D05044D
+:10535000035103750000000005BD05BD05BD05BD79
+:105360000000000005BD05BD05BD05BD0000000035
+:1053700005BD05BD063C05C40000000005BD05BD1A
+:10538000000705BD0000000005BD05BD05BD05BD4C
+:105390000000000005BD05BD05BD05BD0000000005
+:1053A00003F803ED0408040600000000040E040ADC
+:1053B000040C041000000000041C04180424042041
+:1053C00000000000042C0428043404300000000015
+:1053D00005BD05BD043805BD0000000005BD05BDC7
+:1053E00005BD05BD0000000005BD05BD05BD05BD31
+:1053F000000000000002067606940006000000008F
+:00000001FF
diff --git a/firmware/radeon/RV635_pfp.bin.ihex b/firmware/radeon/RV635_pfp.bin.ihex
new file mode 100644
index 0000000..f55292c
--- /dev/null
+++ b/firmware/radeon/RV635_pfp.bin.ihex
@@ -0,0 +1,145 @@
+:1000000000CA040000A00000007E828B007C038BED
+:10001000008001B8007C038B00D4401E00EE001E5F
+:1000200000CA040000A00000007E828B00C41838C3
+:1000300000CA240000CA2800009581A800C41C3A08
+:1000400000C3C00000CA080000CA0C00007C744B4A
+:1000500000C200050099C00000C41C3A007C744C2A
+:1000600000C0FFF000042C0400309002007D250049
+:1000700000351402007D350B00255403007CD5802B
+:1000800000259C030095C00400D5001B007EDDC147
+:10009000007D9D8000D6801B00D5801B00D4401EB3
+:1000A00000D5401E00D6401E00D6801E00D4801E03
+:1000B00000D4C01E009783D300D5C01E00CA08001C
+:1000C0000080001A00CA0C0000E4011E00D4001ECB
+:1000D0000080000C00C4183800E4013E00D4001E6B
+:1000E0000080000C00C4183800D4401E00EE001E32
+:1000F00000CA040000A00000007E828B00E4011E04
+:1001000000D4001E00D4401E00EE001E00CA0400F1
+:1001100000A00000007E828B00E4013E00D4001E9F
+:1001200000D4401E00EE001E00CA040000A0000023
+:10013000007E828B00CA180000D4401E00D5801EAD
+:100140000080005300D4007500D4401E00CA08008F
+:1001500000CA0C0000CA100000D4801900D4C018D6
+:1001600000D5001700D4801E00D4C01E00D5001E8C
+:1001700000E2001E00CA040000A00000007E828B86
+:1001800000CA080000D4806000D4401E0080000037
+:1001900000D4801E00CA080000D4806100D4401E34
+:1001A0000080000000D4801E00CA080000CA0C00B5
+:1001B00000D4401E00D4801600D4C01600D4801E87
+:1001C000008001B800D4C01E00C6084300CA0C005D
+:1001D00000CA10000094800400CA140000E420F358
+:1001E00000D4201300D5606500D4E01C00D5201C8D
+:1001F00000D5601C008000000006200100C60843F6
+:1002000000CA0C0000CA1000009483F700CA140052
+:1002100000E420F30080007900D4201300C60843D6
+:1002200000CA0C0000CA1000009883EF00CA140036
+:1002300000D400640080008D0000000000C414326F
+:1002400000C6184300C4082F0095400500C40C30B8
+:1002500000D4401E0080000000EE001E009583F5D3
+:1002600000C4103100D4403300D5206500D4A01C58
+:1002700000D4E01C00D5201C00E4015E00D4001E68
+:10028000008000000006200100CA1800000A2001BA
+:1002900000D6007600C408360098800700C61045D6
+:1002A0000095011000D4001F00D46062008000009F
+:1002B00000D4206200CC383500CC1433008401BB5C
+:1002C00000D4007200D5401E0080000000EE001E29
+:1002D00000E2001A008401BB00E2001A00CC104BBF
+:1002E00000CC0447002C9401007D098B0098400548
+:1002F000007D15CB00D4001A008001B800D4006D39
+:100300000034440100CC0C480098403A00CC2C4A00
+:100310000095800400CC0449008001B800D4001A84
+:1003200000D4C01A00282801008400F000CC10037B
+:100330000098801B0004380C008400F000CC1003EF
+:100340000098801700043808008400F000CC1003E7
+:100350000098801300043804008400F000CC1003DF
+:100360000098801400CC104C009A800900CC144DE9
+:10037000009840DC00D4006D00CC184800D5001A6D
+:1003800000D5401A008000C900D5801A0096C0D55B
+:1003900000D4006D008001B800D4006E009AC00344
+:1003A00000D4006D00D4006E0080000000EC007FDF
+:1003B000009AC0CC00D4006D008001B800D4006E5B
+:1003C00000CC140300CC180300CC1C03007D910367
+:1003D000007DD583007D190C0035CC1F0035701FC2
+:1003E000007CF0CB007CD08B00880000007E8E8BE0
+:1003F0000095C00400D4006E008001B800D4001A3B
+:1004000000D4C01A00CC080300CC0C0300CC1003AD
+:1004100000CC140300CC180300CC1C0300CC240334
+:1004200000CC28030035C41F0036B01F007C704B81
+:100430000034F01F007C704B0035701F007C704B47
+:10044000007D8881007DCCC1007E5101007E9541F8
+:10045000007C9082007CD4C2007C848B009AC00314
+:10046000007C8C8B002C88010098809E00D4006D4D
+:100470000098409C00D4006E00CC084C00CC0C4D81
+:1004800000CC104800D4801A00D4C01A00800101AA
+:1004900000D5001A00CC083200D40032009482D972
+:1004A00000CA0C0000D4401E0080000000D4001ED2
+:1004B00000E4011E00D4001E00CA080000CA0C009F
+:1004C00000CA100000D4401E00CA140000D4801ED0
+:1004D00000D4C01E00D5001E00D5401E00D54034FB
+:1004E0000080000000EE001E0028040400E2001A54
+:1004F00000E2001A00D4401A00CA380000CC0803F9
+:1005000000CC0C0300CC0C0300CC0C03009882BD83
+:1005100000000000008401BB00D7A06F0080000035
+:1005200000EE001F00CA040000C2FF0000CC083427
+:1005300000C13FFF007C74CB007CC90B007D010F24
+:10054000009902B0007C738B008401BB00D7A06FC0
+:100550000080000000EE001F00CA080000281900FB
+:10056000007D898B009580140028140400CA0C00BB
+:1005700000CA100000CA1C0000CA240000E2001FCC
+:1005800000D4C01A00D5001A00D5401A00CC1803B8
+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
+:1005A000007D9C4700984297000000000080016198
+:1005B00000D4C01A00D4401E00D4801E0080000069
+:1005C00000EE001E00E4011E00D4001E00D4401EF8
+:1005D00000EE001E00CA040000A00000007E828B16
+:1005E00000E4013E00D4001E00D4401E00EE001EB8
+:1005F00000CA040000A00000007E828B00CA080030
+:1006000000248C06000CCC060098C00600CC104ECE
+:100610000099000400D4007300E4011E00D4001E01
+:1006200000D4401E00D4801E0080000000EE001E9A
+:1006300000CA080000CA0C000034D01800251001C0
+:100640000095002100C17FFF00CA100000CA1400FD
+:1006500000CA180000D4801D00D4C01D007DB18BDD
+:1006600000C1420200C2C00100D5801D0034DC0E72
+:10067000007D5D4C007F734C00D7401E00D5001EEE
+:1006800000D5401E00C1420000C2C00000099C010C
+:100690000031DC10007F5F4C007F734C00042802A7
+:1006A000007D838000D5A86F00D5806600D7401EEE
+:1006B00000EC005E00C8240200C82402008001B8DB
+:1006C00000D6007600D4401E00D4801E00D4C01E88
+:1006D0000080000000EE001E0080000000EE001F01
+:1006E00000D4001F0080000000D4001F00D4001FB1
+:1006F0000088000000D4001F00000000000000007F
+:1007000000000000000000000000000000000000E9
+:1007100000000000000000000000000000000000D9
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:1008000000010171000201780003008F0004007FE5
+:10081000000500030006003F000700320008012C1D
+:1008200000090046000A0036001001B6001700A2B9
+:100830000022013A00230149002000B400240125D0
+:100840000027004D0028006A002A0060002B00529B
+:10085000002F0065003200870034017F003C015604
+:10086000003F00720041018C0044012E00550173CD
+:100870000056017A0060000B00610034006200380D
+:1008800000630038006400380065003800660038F6
+:10089000006700380068003A00690041006A0048BB
+:1008A000006B0048006C0048006D0048006E004876
+:1008B000006F00480000000600000006000000066F
+:1008C0000000000600000006000000060000000610
+:1008D0000000000600000006000000060000000600
+:1008E00000000006000000060000000600000006F0
+:1008F00000000006000000060000000600000006E0
+:00000001FF
diff --git a/firmware/radeon/RV670_me.bin.ihex b/firmware/radeon/RV670_me.bin.ihex
new file mode 100644
index 0000000..9fbfc0e
--- /dev/null
+++ b/firmware/radeon/RV670_me.bin.ihex
@@ -0,0 +1,1345 @@
+:1000000000000000C020040000000000000000000C
+:1000100000A0000A000000000000FFFF00284621A9
+:100020000000000000000000D900480000000000AF
+:1000300000000000C02004000000000000000000DC
+:1000400000A0000A000000000000000000E0000026
+:100050000000000000010000C02946200000000050
+:1000600000000000D900480000000000000000006F
+:10007000C0200400000000000000000000A0000AF2
+:10008000000000008100000000204411000000007A
+:1000900000000001002048110000000000042004BE
+:1000A000006044110000067C0000000000600000B9
+:1000B0000000062400000000006000000000063878
+:1000C00000000000C02008000000000000000F0039
+:1000D000002816220000000000000008002116255C
+:1000E000000000000000001800203625000000007D
+:1000F0008D000000002044110000000000000004FA
+:10010000002F022500000000000000000CE00000AD
+:1001100000000018004120000040481100000019B4
+:100120000042200000204811000000008E00000066
+:1001300000204411000000000000002800204A2D8B
+:1001400000000000900000000020441100000000AA
+:100150000000000000204805000000000000000C26
+:1001600000211622000000000000000300281625D0
+:10017000000000000000001900211A220000000009
+:100180000000000400281A26000000000000000003
+:10019000002914C5000000000000001900203625C9
+:1001A0000000000000000000003A140200000000FF
+:1001B00000000016002116250000000000000003CA
+:1001C00000281625000000000000001700200E2D5A
+:1001D00000000000FFFFFFFC00280E2300000000CD
+:1001E00000000000002914A3000000000000001718
+:1001F00000203625000000000000800000280E22AC
+:10020000000000000000000700220E230000000094
+:10021000000000000029386E0000000020000000EF
+:1002200000280E22000000000000000600210E231E
+:1002300000000000000000000029386E00000000EF
+:100240000000000000220222000000000000000068
+:1002500014E0000000000038000000002EE0000064
+:1002600000000035000000002CE000000000003716
+:100270000000000000400E2D0000003900000008C2
+:1002800000200E2D00000000000000090040122D8B
+:10029000000000460000000100400E2D0000003963
+:1002A00000000000C0200C0000000000003FFFFC28
+:1002B0000028122300000000000000020022122487
+:1002C000000000000000001F00211E2300000000AD
+:1002D0000000000014E000000000003E00000008E4
+:1002E00000401C11000000410000000D00201E2DE8
+:1002F000000000000000000F00281E270000000082
+:100300000000000300221E27000000007FC0000044
+:1003100000281A23000000000000001400211A2603
+:10032000000000000000000100331A260000000059
+:100330000000000800221A26000000000000000053
+:1003400000290CC700000000000000270020362410
+:100350000000000000007F000028122100000000C3
+:1003600000001400002F0224000000000000000024
+:100370000CE000000000004B0000000100290E23EB
+:10038000000000000000000E0020362300000000E6
+:100390000000E0000020441100000000FFF8000011
+:1003A00000294A230000000000000000003A2C024F
+:1003B000000000000000000200220E2B00000000E0
+:1003C000FC00000000280E23000000000000000FC9
+:1003D000002036230000000000001FFF00294A23F0
+:1003E000000000000000002700204A2D000000004F
+:1003F000000000000020481100000000000000295B
+:1004000000200E2D00000000060A020000294A23E9
+:100410000000000000000000002048110000000063
+:100420000000000000204811000000000000000152
+:1004300000210222000000000000000014E0000083
+:1004400000000061000000002EE000000000005FDE
+:10045000000000002CE000000000005E0000000032
+:1004600000400E2D000000620000000100400E2D33
+:10047000000000620000000A00200E2D00000000B5
+:100480000000000B0040122D0000006A0000000078
+:10049000C0200C0000000000003FFFFC00281223D9
+:1004A00000000000000000020022122400000000F2
+:1004B0007FC0000000281623000000000000001488
+:1004C0000021162500000000000000010033162561
+:1004D000000000008000000000280E230000000043
+:1004E0000000000000290CA3000000003FFFFC00FA
+:1004F00000290E23000000000000001F00211E2321
+:10050000000000000000000014E000000000006D8A
+:100510000000010000401C11000000700000000DF0
+:1005200000201E2D00000000000000F000281E2703
+:10053000000000000000000400221E270000000050
+:100540008100000000204411000000000000000DA8
+:100550000020481100000000FFFFF0FF00281A30C3
+:10056000000000000000A02800204411000000004E
+:1005700000000000002948E6000000000000A0186C
+:1005800000204411000000003FFFFFFF00284A2325
+:10059000000000000000A010002044110000000036
+:1005A00000000000002048040000000000000030AF
+:1005B0000020162D00000000000000020029162572
+:1005C0000000000000000030002036250000000080
+:1005D000000000250020162D000000000000000093
+:1005E000002F00A300000000000000000CC000006D
+:1005F00000000083000000260020162D00000000EF
+:1006000000000000002F00A4000000000000000017
+:100610000CC000000000008400000000004000004A
+:100620000000008A000000250020362300000000A2
+:100630000000002600203624000000000000001703
+:1006400000201E2D000000000000000200210227F3
+:10065000000000000000000014E000000000008A1C
+:1006600000000000006000000000065900000000CB
+:10067000006000000000064D0000000200210E2274
+:10068000000000000000000014C000000000008D09
+:1006900000000012C040362000000093000000005F
+:1006A0002EE0000000000091000000002CE000009F
+:1006B000000000900000000200400E2D000000929B
+:1006C0000000000300400E2D000000920000000C0E
+:1006D00000200E2D00000000000000120020362334
+:1006E000000000000000000300210E2200000000B6
+:1006F0000000000014C00000000000980000A00CE2
+:10070000002044110000000000000000C02048004C
+:100710000000000000000000C0404800000000A0F1
+:100720000000A00C002044110000000000000000A8
+:100730000020481100000000000000002EE0000032
+:100740000000009E000000002CE000000000009D62
+:100750000000000200400E2D0000009F000000037A
+:1007600000400E2D0000009F0000000C00200E2D08
+:10077000000000000000000000204803000000000E
+:1007800000000000003A0C0200000000003F0000E2
+:1007900000280E23000000000000001000210E239E
+:1007A00000000000000000110020362300000000BF
+:1007B0000000001E0021022B0000000000000000CD
+:1007C00014C00000000000A700000016C020362062
+:1007D000000000000000001F0021022B00000000AC
+:1007E0000000000014C00000000000AA0000001576
+:1007F000C0203620000000000000000800210E2B61
+:10080000000000000000007F00280E230000000010
+:1008100000000000002F0223000000000000000084
+:100820000CE00000000000E10000000027000000D4
+:10083000000000000000000000600000000002A3B3
+:1008400000000001002F0223000000000000000053
+:100850000AE00000000000B300000000006000009B
+:100860000000013A81000000002044110000000057
+:100870000000000600204811000000000000000CED
+:1008800000221E300000000099800000002044116A
+:1008900000000000000000040020122D00000000F5
+:1008A00000000008002212240000000000000010D8
+:1008B00000201811000000000000000000291CE4C6
+:1008C0000000000000000000006048070000012F49
+:1008D0009B00000000204411000000000000000008
+:1008E00000204802000000009C000000002044118D
+:1008F00000000000000000000033146F0000000042
+:100900000000000100333E23000000000000000052
+:10091000D9004800000000000000000000203C0555
+:1009200000000000810000000020441100000000D1
+:100930000000000E00204811000000000000000030
+:1009400000201010000000000000E007002044110B
+:10095000000000000000000F0021022B000000003A
+:100960000000000014C00000000000CB00F8FF08E9
+:1009700000204811000000009800000000404811CD
+:10098000000000DC000000F000280E220000000043
+:10099000000000A0002F0223000000000000000063
+:1009A0000CC00000000000DA0000001100200E2D35
+:1009B0000000000000000001002F022300000000E2
+:1009C000000000000CE00000000000D50000000264
+:1009D000002F022300000000000000000CE00000D7
+:1009E000000000D400003F0000400C11000000D6C1
+:1009F00000001F0000400C11000000D600000F0096
+:100A000000200C11000000000038000900294A23D2
+:100A1000000000003F00000000280E2B0000000036
+:100A20000000000200220E2300000000000000076A
+:100A300000494A23000000DC00380F09002048115B
+:100A400000000000680000070020481100000000BE
+:100A50000000000800214A270000000000000000FC
+:100A60000020481100000000060A020000294A2464
+:100A700000000000000000000020481100000000FD
+:100A80000000000000204811000000000000A20249
+:100A9000002044110000000000FF000000280E228A
+:100AA000000000000000008000294A230000000030
+:100AB0000000002700200E2D00000000000000268E
+:100AC0000020122D0000000000000000002F008315
+:100AD00000000000000000000CE00000000000EA40
+:100AE000000000000060000000000653000000004D
+:100AF00000400000000000EB00000000006000006B
+:100B000000000656000000070020222D0000000013
+:100B10000000000500220E2200000000001000006E
+:100B200000280E23000000000000000000292068BB
+:100B30000000000000000000003A0C02000000006D
+:100B4000000000EF00280E2300000000000000005D
+:100B500000292068000000000000001700200E2D72
+:100B6000000000000000000300210223000000003C
+:100B70000000000014E00000000000F80000000B7E
+:100B800000210228000000000000000014C0000046
+:100B9000000000F8000004000029222800000000E6
+:100BA0000000001400203628000000000000001C97
+:100BB00000210E22000000000000000014C0000010
+:100BC000000000FD0000A30C002044110000000004
+:100BD0000000000000204811000000000000001E7E
+:100BE00000210E22000000000000000014C00000E0
+:100BF0000000010B0000A30F0020441100000000C2
+:100C00000000001100200E2D000000000000000177
+:100C1000002F022300000000000000000CC00000B4
+:100C200000000104FFFFFFFF004048110000010B1E
+:100C300000000002002F022300000000000000005E
+:100C40000CC00000000001070000FFFF0040481139
+:100C50000000010B00000004002F02230000000030
+:100C6000000000000CC000000000010A000000FFAE
+:100C7000004048110000010B000000010020481155
+:100C8000000000000002C400002044110000000029
+:100C90000000001F00210E220000000000000000E4
+:100CA00014C00000000001120000001040210E20BE
+:100CB00000000000000000130020362300000000A8
+:100CC0000000001840224A20000000000000001030
+:100CD000C0424A20000001140000000000200C1156
+:100CE0000000000000000013002036230000000078
+:100CF000000000000020481100000000000000007B
+:100D000000204811000000000000000A002010111F
+:100D10000000000000000000002F0224000000007E
+:100D2000000000000CE000000000011B00000000BB
+:100D300000204811000000000000000100531224B0
+:100D400000000117FFBFFFFF00283A2E000000003F
+:100D50000000001B00210222000000000000000033
+:100D600014C000000000012E81000000002044118A
+:100D7000000000000000000D0020481100000000ED
+:100D80000000001800220E3000000000FC000000EF
+:100D900000280E2300000000810000000020441104
+:100DA000000000000000000E0020481100000000BC
+:100DB0000000000000201010000000000000E00E05
+:100DC000002044110000000007F8FF08002048112F
+:100DD000000000000000000000294A23000000007D
+:100DE0000000001C00201E2D000000000000000874
+:100DF00000214A27000000000000000000204811E8
+:100E000000000000060A020000294A240000000039
+:100E10000000000000204811000000000000000059
+:100E200000204811000000000000000000800000C9
+:100E300000000000810000000020441100000000BC
+:100E40000000000100204811000000000000217C8B
+:100E50000020441100000000008000000020481124
+:100E60000000000000000000002048060000000014
+:100E70000000000800214A270000000000000000D8
+:100E800017000000000000000004217F00604411F2
+:100E90000000067C0000001F00210230000000005E
+:100EA0000000000014C000000000067B00000004E9
+:100EB00000404C1100000135810000000020441169
+:100EC00000000000000000010020481100000000A8
+:100ED000000021F800204411000000000000001C68
+:100EE0000020481100000000000421F900604411B6
+:100EF0000000067C0000001100210230000000000C
+:100F00000000000014E000000000013C00000000B0
+:100F100000800000000000000000000000600000F1
+:100F20000000000B00000000006004110000031529
+:100F3000000000000020041100000000000000007C
+:100F400000600811000001B2000000000060000015
+:100F5000000001600000FFFF40280E20000000009C
+:100F600000000010C0211220000000000000FFFF60
+:100F7000402806200000000000000010C0210A20C8
+:100F800000000000000000000034146100000000B8
+:100F90000000000000741882000002BB0001A1FDE7
+:100FA00000604411000002E000003FFF002F022F0C
+:100FB00000000000000000000CC00000000001471D
+:100FC00000000000C040040000000001000000001C
+:100FD000006000000000000B000000000060041131
+:100FE00000000315000000000020041100000000B4
+:100FF0000000000000600811000001B200003FFF87
+:10100000002F022F00000000000000000CE0000094
+:10101000000000000000000000600000000001600F
+:101020000000001040210E20000000000000FFFF23
+:10103000C0281220000000000000001040211620EF
+:10104000000000000000FFFFC0681A20000002BB83
+:101050000001A1FD00604411000002E000003FFF1C
+:10106000002F022F00000000000000000CC0000054
+:101070000000015800000000C04004000000000112
+:101080000000225C0020441100000000000000016C
+:1010900000300A2F000000000000000100210A2299
+:1010A000000000000000000300384A220000000099
+:1010B0000000225600204411000000000000001A29
+:1010C00000204811000000000000A1FC0020441195
+:1010D0000000000000000001008048110000000036
+:1010E00000000000006000000000000B0000000095
+:1010F000006000000000018F0000000000600000A0
+:10110000000001A000003FFF002F022F00000000A0
+:10111000000000000CE000000000000000000000E3
+:1011200000202C0800000000000000000020241116
+:101130000000000000000000002028110000000056
+:10114000000022560020441100000000000000169C
+:1011500000204811000000000000225C0020441123
+:101160000000000000000003002048110000000003
+:1011700093800000002044110000000000000002E5
+:1011800000221E290000000000000000007048EB53
+:101190000000019C0000000000600000000002BB95
+:1011A00000000001403306200000000000000000A5
+:1011B000C03024090000000000003FFF002F022F74
+:1011C00000000000000000000CE000000000000033
+:1011D0000000000000600000000002A3000000000A
+:1011E000002F022100000000000000000AE00000C3
+:1011F0000000018100000000006000000000013AD2
+:101200000000000000400000000001869500000082
+:10121000002044110000000000000000002F022107
+:1012200000000000000000000CE00000000001864B
+:1012300000000000C0204800000000000000000185
+:10124000005306210000018292000000002044119A
+:101250000000000000000000C0604800000001978E
+:101260000001A1FD00204411000000000000001159
+:101270000020062D00000000000000000078042A75
+:10128000000002FB00000000002028090000000010
+:1012900000003FFF002F022F0000000000000000B0
+:1012A0000CC000000000017400000000C0400400F9
+:1012B000000000010000021000600411000003158E
+:1012C00000003FFF002F022F000000000000000080
+:1012D0000CE000000000019400000015C020362042
+:1012E0000000000000000016C020362000000000B2
+:1012F0003F800000002004110000000046000000B4
+:1013000000600811000001B2000000000080000031
+:10131000000000000000A1FC0020441100000000BB
+:1013200000003FFF002F022F00000000000000001F
+:101330000CC000000000019B00000001008048116B
+:1013400000000000000000210080481100000000A3
+:101350000000FFFF40280E200000000000000010E9
+:10136000C0211220000000000000FFFF40281620CE
+:101370000000000000000010C0811A2000000000E2
+:101380008100000000204411000000000000000661
+:1013900000204811000000000000000800221E305C
+:1013A000000000000000002900201A2D00000000AD
+:1013B0000000E0000020441100000000FFFBFF09D6
+:1013C00000204811000000000000000F0020222D26
+:1013D0000000000000001FFF00294A280000000054
+:1013E000000000060020222D000000000000000088
+:1013F000002920E80000000000000000002048084C
+:101400000000000000000000002048110000000063
+:10141000060A020000294A26000000000000000021
+:1014200000204811000000000000000000204811CA
+:101430000000000000000100002018110000000062
+:101440000000000800621E280000012F00000008B4
+:1014500000822228000000000002C0000020441189
+:10146000000000000000001500600E2D000001BD0E
+:101470000000001600600E2D000001BD0000C00835
+:1014800000204411000000000000001700200E2D75
+:10149000000000000000000014C00000000001B9BE
+:1014A0000000000000200411000000000000000007
+:1014B0000020480100000000390000000020481111
+:1014C00000000000000000000020481100000000A3
+:1014D000000000000080480200000000000000182A
+:1014E00000202E2D0000000000000000003B0D63D6
+:1014F000000000000000000800224A230000000055
+:101500000000001000224A23000000000000001824
+:1015100000224A2300000000000000000080480371
+:101520000000000000000000006000000000000B50
+:10153000000010000060041100000315000000000E
+:1015400000200411000000000000000000600811ED
+:10155000000001B2000000070021062F000000007B
+:101560000000001300200A2D000000000000000110
+:1015700000202C11000000000000FFFF4028222066
+:10158000000000000000000F0026222800000000DC
+:101590000000001040212620000000000000000F85
+:1015A000002626290000000000000000002028027C
+:1015B000000000000000225600204411000000003E
+:1015C0000000001B00204811000000000000000087
+:1015D000002F022100000000000000000CE00000CD
+:1015E000000001E00000225C002044110000000027
+:1015F0000000008100204811000000000000A1FC54
+:1016000000204411000000000000000100204811EB
+:10161000000000000000008000201C1100000000FD
+:1016200000000000002F0227000000000000000062
+:101630000CE00000000001DC000000000060000081
+:10164000000001E90000000100531E27000001D83E
+:101650000000000100202C11000000000000001F0D
+:1016600000280A22000000000000001F00282A2A8B
+:10167000000000000000000100530621000001D11D
+:101680000000225C00204411000000000000000265
+:1016900000304A2F000000000000A1FC002044118F
+:1016A00000000000000000010020481100000000C0
+:1016B0000000000100301E2F0000000000000000AC
+:1016C000002F022700000000000000000CE00000D6
+:1016D000000000000000000000600000000001E9C0
+:1016E0000000000100531E27000001E50000FFFF7D
+:1016F00040280E20000000000000000F00260E23EE
+:101700000000000000000010C021122000000000B6
+:101710000000000F0026122400000000000000005E
+:1017200000201411000000000000000000601811EB
+:10173000000002BB0001A1FD0020441100000000D8
+:1017400000000000002F022B00000000000000003D
+:101750000CE00000000001F8000000100022162834
+:1017600000000000FFFF0000002816250000000018
+:101770000000FFFF00281A29000000000000000000
+:10178000002948C500000000000000000020480AB1
+:10179000000000000000000000202C1100000000EC
+:1017A000000000100022162300000000FFFF0000D0
+:1017B00000281625000000000000FFFF00281A2462
+:1017C0000000000000000000002948C500000000E3
+:1017D0000000000000731503000002050000000077
+:1017E0000020180500000000000000000073152410
+:1017F0000000020500000000002D14C500000000DC
+:1018000000000000003008A20000000000000000FE
+:101810000020480200000000000000000020280214
+:101820000000000000000000002020030000000075
+:101830000000000000802404000000000000000FF1
+:1018400000210225000000000000000014C000007C
+:101850000000067B00000000002B140500000000C3
+:1018600000000001009016250000000000000000AC
+:10187000006000000000000B000000000060041188
+:10188000000003150000000000200411000000000B
+:101890000000000000600811000001B200002256A4
+:1018A00000204411000000000000001A00294A2214
+:1018B0000000000000000000C02000000000000048
+:1018C00000003FFF002F022F00000000000000007A
+:1018D0000CE000000000000000000000C020040038
+:1018E000000000000000225C002044110000000005
+:1018F0000000000300384A21000000000000A1FCA5
+:1019000000204411000000000000000100204811E8
+:10191000000000000000FFFF40281220000000002F
+:1019200000000010C0211A20000000000000FFFF8E
+:1019300040280E200000000000000010C0211620EA
+:10194000000000000000000000741465000002BBED
+:101950000001A1FD00604411000002E00000000150
+:10196000003306210000000000000000002F0221CB
+:1019700000000000000000000CC000000000021980
+:1019800000003FFF002F022F0000000000000000B9
+:101990000CC000000000021200000000C040040063
+:1019A0000000000100000000006000000000063898
+:1019B000000000000040040F0000021300000000BF
+:1019C000006000000000062400000000006000002D
+:1019D000000006380000021000600411000003152A
+:1019E0000000000000600000000001A000000000F6
+:1019F000006000000000019C00000000006000008A
+:101A0000000002BB0000000000600000000002A314
+:101A1000938000000020441100000000000000003E
+:101A2000002048080000000000000000002F022FE6
+:101A300000000000000000000AE000000000023288
+:101A400000000000006000000000013A00000000FB
+:101A50000040000000000236950000000020441104
+:101A60000000000000000000002F022F0000000016
+:101A7000000000000CE00000000002360000000042
+:101A8000C0404800000002339200000000204411D2
+:101A90000000000000000000C0204800000000001E
+:101AA0000000225600204411000000000000001633
+:101AB00000204811000000000000225C00204411BA
+:101AC000000000000000000300204811000000009A
+:101AD0000000A1FC002044110000000000000001F3
+:101AE00000204811000000000001A1FD0020441169
+:101AF000000000000000000000600411000002FB74
+:101B000000000000C04004000000000100000000D0
+:101B100000600000000006240000A00C002044111A
+:101B20000000000000000000C0204800000000008D
+:101B300000000000C040480000000000000000005D
+:101B4000006000000000000B0000001840210A2087
+:101B50000000000000000003002F0222000000002F
+:101B6000000000000AE000000000024C0000001429
+:101B70000020222D00000000000801010029222879
+:101B800000000000000000140020362800000000C3
+:101B90000000A30C00204411000000000000000021
+:101BA000C02048000000000000000000C0204800E5
+:101BB0000000000000000000C0404800000002518A
+:101BC00000000000006000000000000B000000109A
+:101BD00000600411000003153F8000000020041184
+:101BE000000000000000000000600811000001B2C9
+:101BF0000000225C002044110000000000000003EF
+:101C000000204811000000000000000000600000FB
+:101C10000000027C0000001700201E2D00000000C4
+:101C20000000000100211E2700000000000000004D
+:101C300014E000000000026A0000001200201E2DC7
+:101C4000000000000000FFFF00281E270000000029
+:101C50000000000000341C2700000000000000000D
+:101C600012C000000000025F0000000000201C11F4
+:101C70000000000000000000002F00E50000000050
+:101C80000000000008C00000000002620000000028
+:101C900000201407000000000000001200201E2D8C
+:101CA000000000000000001000211E2700000000BE
+:101CB0000000000000341C4700000000000000008D
+:101CC00012C00000000002670000000000201C118C
+:101CD0000000000000000000002F00E600000000EF
+:101CE0000000000008C000000000026A00000000C0
+:101CF0000020180700000000000000000060000045
+:101D0000000002C100002256002044110000000023
+:101D1000000000000034202300000000000000004C
+:101D200012C00000000002720000000000342044D5
+:101D3000000000000000000012C00000000002715E
+:101D40000000001600404811000002760000001854
+:101D500000404811000002760000000000342044DA
+:101D6000000000000000000012C00000000002752A
+:101D70000000001700404811000002760000001922
+:101D800000204811000000000000A1FC00204411C8
+:101D900000000000000000010020481100000000C9
+:101DA0000001A1FD00604411000002E900003FFFB6
+:101DB000002F022F00000000000000000CC00000F7
+:101DC0000000025600000000C040040000000001B6
+:101DD0000000001040210620000000000000FFFF6E
+:101DE000C0280A20000000000000001040210E2042
+:101DF000000000000000FFFFC028122000000000CB
+:101E00000000001040211620000000000000FFFF2D
+:101E1000C0881A200000000081000000002044114A
+:101E20000000000000000001002048110000000038
+:101E300000042004006044110000067C0000000043
+:101E4000006000000000062400000000C0600000E8
+:101E5000000002A30000000500200A2D0000000081
+:101E60000000000800220A22000000000000002BF1
+:101E700000201A2D000000000000001C00201E2D74
+:101E8000000000000000700000281E270000000075
+:101E90000000000000311CE6000000000000002AE5
+:101EA00000201A2D000000000000000C00221A265D
+:101EB0000000000000000000002F00E6000000000D
+:101EC0000000000006E00000000002920000000098
+:101ED00000201C11000000000000000000200C1178
+:101EE000000000000000002B00203623000000004E
+:101EF0000000001000201811000000000000000089
+:101F000000691CE20000012F9380000000204411B2
+:101F10000000000000000000002048070000000052
+:101F200095000000002044110000000000000000A7
+:101F3000002F022F00000000000000000CE0000055
+:101F40000000029D0000000100333E2F0000000051
+:101F500000000000D90048000000000092000000CE
+:101F6000002044110000000000000000C0204800D4
+:101F7000000000000000001C0040362700000000A8
+:101F80000000000CC0220A20000000000000002910
+:101F9000002036220000000000000028C04036204B
+:101FA000000000000000A2A4002044110000000076
+:101FB000000000090020481100000000A1000000FE
+:101FC00000204411000000000000000100804811C2
+:101FD000000000000000002100201E2D0000000075
+:101FE00000000000002C1CE30000000000000021A5
+:101FF00000203627000000000000002200201E2DD7
+:102000000000000000000000002C1CE400000000A4
+:1020100000000022002036270000000000000023FE
+:1020200000201E2D0000000000000000003120A351
+:102030000000000000000000002D1D07000000004F
+:1020400000000023002036270000000000000024CC
+:1020500000201E2D0000000000000000003120C400
+:102060000000000000000000002D1D07000000001F
+:10207000000000240080362700000000000000213E
+:10208000002036230000000000000022002036243B
+:10209000000000000000000000311CA30000000050
+:1020A0000000002300203627000000000000000090
+:1020B00000311CC40000000000000024008036270E
+:1020C000000000000000001A002036270000000079
+:1020D0000000001B00203628000000000000001750
+:1020E00000201E2D00000000000000020021022739
+:1020F000000000000000000014C00000000002DC2E
+:102100000000000000400000000002D90000001A9A
+:1021100000203627000000000000001B00203628A9
+:10212000000000000000001700201E2D000000002D
+:102130000000000200210227000000000000000053
+:1021400014E00000000002D9000000030021022773
+:10215000000000000000000014E00000000002DCAD
+:102160000000002300201E2D0000000000000000E1
+:10217000002E00E1000000000000000002C000008E
+:10218000000002DC0000002100201E2D00000000E5
+:1021900000000000003120A100000000000000004D
+:1021A000002E00E8000000000000000006C0000053
+:1021B000000002DC0000002400201E2D00000000B2
+:1021C00000000000002E00E20000000000000000FF
+:1021D00002C00000000002DC0000002200201E2DD2
+:1021E0000000000000000000003120C200000000DC
+:1021F00000000000002E00E80000000000000000C9
+:1022000006C00000000002DC0000000000600000CA
+:10221000000006590000000000600000000002B548
+:102220000000000000400000000002DE000000008E
+:1022300000600000000002B5000000000060000027
+:10224000000006500000000000400000000002DE18
+:102250000000000000600000000002A70000000075
+:1022600000400000000002DE0000001A00201E2DC9
+:10227000000000000000001B0080222D0000000074
+:102280000000001000221E230000000000000000DB
+:1022900000294887000000000000000000311CA356
+:1022A000000000000000001000221E2700000000B7
+:1022B0000000000000294887000000000000001016
+:1022C00000221E230000000000000000003120C496
+:1022D000000000000000FFFF00282228000000008E
+:1022E0000000000000894907000000000000001005
+:1022F00000221E2300000000000000000029488783
+:10230000000000000000001000221E21000000005C
+:102310000000000000294847000000000000000005
+:1023200000311CA3000000000000001000221E2746
+:1023300000000000000000000029488700000000A5
+:102340000000000000311CA100000000000000108F
+:1023500000221E270000000000000000002948475E
+:10236000000000000000001000221E2300000000FA
+:1023700000000000003120C4000000000000FFFF4A
+:102380000028222800000000000000000029490762
+:10239000000000000000001000221E2100000000CC
+:1023A00000000000003120C2000000000000FFFF1C
+:1023B00000282228000000000000000000894907D2
+:1023C000000000000000001000221E23000000009A
+:1023D0000000000000294887000000000000000104
+:1023E00000220A210000000000000000003308A2C3
+:1023F000000000000000001000221E22000000006B
+:102400000000001000212222000000000000000057
+:1024100000294907000000000000000000311CA353
+:10242000000000000000001000221E270000000035
+:1024300000000000002948870000000000000001A3
+:1024400000220A210000000000000000003008A265
+:10245000000000000000001000221E22000000000A
+:1024600000000010002122220000000000000000F7
+:1024700000294907000000000000001000221E2370
+:102480000000000000000000003120C40000000037
+:102490000000FFFF002822280000000000000000CC
+:1024A000002949070000000000000000003808C5AE
+:1024B00000000000000000000030084100000000A3
+:1024C0000000000100220A220000000000000000BD
+:1024D000003308A2000000000000001000221E22AD
+:1024E0000000000000000010002122220000000077
+:1024F00000000000008949070000000000000017EC
+:102500000020222D000000000000000014C0000088
+:1025100000000318FFFFFFEF002806210000000065
+:10252000000000140020222D000000000000F8E050
+:1025300000204411000000000000000000294901B3
+:1025400000000000000000000089490100000000B8
+:102550000000000000204811000000000000000002
+:102560000020481100000000060A02000080481107
+:102570000000000000000000C0200000000000007B
+:1025800097000000C020441100000000000000007F
+:10259000C0204811000000008A0000000020441103
+:1025A00000000000000000000020481100000000B2
+:1025B0000000225C00204411000000000000000028
+:1025C000C0204800000000000000A1FC00204411D1
+:1025D0000000000000000000C020480000000000D3
+:1025E00000000000C0200400000000000000000007
+:1025F00000A0000A00000000970000000020441125
+:102600000000000000000000002048110000000051
+:102610008A000000002044110000000000000000BB
+:1026200000204811000000000000225C002044113E
+:102630000000000000000000C02048000000000072
+:102640000000A1FC00204411000000000000000078
+:10265000C02048000000000000000000C02004006E
+:10266000000000000000000000A0000A00000000C0
+:10267000970000000020441100000000000000004E
+:1026800000204811000000008A00000000204411D2
+:1026900000000000000000000020481100000000C1
+:1026A0000000225C00204411000000000000000037
+:1026B000C0204800000000000000A1FC00204411E0
+:1026C0000000000000000000C020480000000000E2
+:1026D0000001A1FD002044110000000000000000E6
+:1026E000D90048000000000000000000C0200400E5
+:1026F000000000000000000000A0000A0000000030
+:1027000000002257002044110000000000000003D8
+:10271000C0484A20000000000000225D0020441153
+:102720000000000000000000C04048000000000061
+:1027300000000000006000000000063800000000FB
+:10274000C0200800000000000000225C00204411AE
+:10275000000000000000000300384A2200000000D2
+:102760000000A1FC00204411000000000000000057
+:10277000C0204800000000000001A1FD002044111D
+:102780000000000000000000002F022200000000F6
+:10279000000000000CE0000000000000000000004D
+:1027A00040204800000000000000000140304A20A6
+:1027B0000000000000000002C0304A2000000000BD
+:1027C0000000000100530A220000034B0000003FFC
+:1027D000C0280A20000000008100000000204411F1
+:1027E000000000000000000100204811000000006F
+:1027F000000021F800204411000000000000001833
+:102800000020481100000000000421F9006044117C
+:102810000000067C000000110021023000000000D2
+:102820000000000014E00000000003540000001449
+:10283000002F022200000000000000000CC0000079
+:10284000000003620001A2A4002044110000000067
+:1028500000000000006048020000036A0000210040
+:10286000002044110000000000000000C0204800CB
+:102870000000000000000000C02048000000000030
+:1028800000000000C0204800000000000000000020
+:10289000C04048000000000000000004002F022299
+:1028A00000000000000000000CC0000000000366F3
+:1028B0000001A2A40020441100000000000000005C
+:1028C000004048020000035D00000028002F0222A3
+:1028D00000000000000000000CC00000000005B374
+:1028E0000001A2A40020441100000000000000002C
+:1028F000004048020000035D0000002C0020362646
+:102900000000000000000049002018110000000035
+:102910000000003F002048110000000000000001FE
+:1029200000331A260000000000000000002F0226DD
+:1029300000000000000000000CC000000000036C5C
+:102940000000002C00801A2D000000000000003F55
+:10295000C0280A200000000000000015002F0222FD
+:1029600000000000000000000CE0000000000382F6
+:1029700000000006002F02220000000000000000FE
+:102980000CE00000000003AD00000016002F022242
+:1029900000000000000000000CE00000000003AF99
+:1029A00000000020002F02220000000000000000B4
+:1029B0000CE00000000003980000000F002F02222E
+:1029C00000000000000000000CE00000000003A474
+:1029D00000000010002F0222000000000000000094
+:1029E0000CE00000000003A40000001E002F0222E3
+:1029F00000000000000000000CE000000000038C5C
+:102A00000000A2A40020441100000000000000000B
+:102A100000404802000000000800000000290A22CF
+:102A2000000000000000000340210E200000000014
+:102A30000000000CC021122000000000000800006F
+:102A4000002812240000000000000014C0221620FC
+:102A50000000000000000000002914A40000000095
+:102A60000000A2A4002044110000000000000000AB
+:102A7000002948A2000000000000A1FE002044112F
+:102A800000000000000000000040480300000000BB
+:102A9000810000000020441100000000000000013F
+:102AA0000020481100000000000021F8002044111F
+:102AB0000000000000000016002048110000000087
+:102AC000000421F9006044110000067C000000159C
+:102AD00000210230000000000000000014E00000AF
+:102AE0000000038E0000210E0020441100000000B1
+:102AF00000000000C02048000000000000000000AE
+:102B0000C0204800000000000000A2A400204411E2
+:102B1000000000000000000000404802000000002B
+:102B200081000000002044110000000000000001AE
+:102B30000020481100000000000021F8002044118E
+:102B400000000000000000170020481100000000F5
+:102B5000000421F9006044110000067C000000031D
+:102B600000210230000000000000000014E000001E
+:102B70000000039A0000210800204411000000001A
+:102B800000000000C020480000000000000000001D
+:102B9000C0204800000000000000A2A40020441152
+:102BA000000000000000000000404802000000009B
+:102BB0000000A2A40020441100000000000000005A
+:102BC00000204802000000008000000000204411A6
+:102BD000000000000000000000204811000000007C
+:102BE00081000000002044110000000000000010DF
+:102BF000002048110000000000000000002000102C
+:102C0000000000000000000014C00000000003AA43
+:102C10000000000000400000000000000001A2A42D
+:102C20000020441100000000000000060040481190
+:102C3000000000000001A2A40020441100000000D8
+:102C400000000016006048110000036A0000000048
+:102C5000004000000000000000000000C02008004C
+:102C60000000000000000000C0200C000000000078
+:102C70000000001D002102230000000000000000F1
+:102C800014E00000000003C4810000000020441193
+:102C900000000000000000010020481100000000BA
+:102CA000000021F80020441100000000000000187E
+:102CB0000020481100000000000421F900604411C8
+:102CC0000000067C0000001100210230000000001E
+:102CD0000000000014E00000000003B80000210024
+:102CE0000020441100000000000000000020480205
+:102CF0000000000000000000002048030000000069
+:102D0000BABECAFE0020481100000000CAFEBABECA
+:102D100000204811000000000000A2A4002044117F
+:102D20000000000000000004004048110000000006
+:102D3000000021700020441100000000000000008D
+:102D400000204802000000000000000000204803AE
+:102D5000000000008100000000204411000000007D
+:102D60000000000A002048110000000000000000E0
+:102D700000200010000000000000000014C000004F
+:102D8000000003C98C000000002044110000000076
+:102D9000CAFEBABE004048110000000081000000D9
+:102DA0000020441100000000000000010020481134
+:102DB0000000000000003FFF40280A200000000043
+:102DC0008000000040280E200000000040000000AD
+:102DD000C028122000000000000400000069462204
+:102DE0000000067C0000000000201410000000001D
+:102DF00000000000002F022300000000000000007F
+:102E00000CC00000000003D700000000C040180004
+:102E1000000003DA00003FFFC0281A200000000075
+:102E200000040000006946260000067C0000000047
+:102E3000002018100000000000000000002F0224F5
+:102E400000000000000000000CC00000000003DDD6
+:102E500000000000C0401C00000003E000003FFF35
+:102E6000C0281E2000000000000400000069462762
+:102E70000000067C0000000000201C100000000084
+:102E800000000000002044020000000000000000DC
+:102E9000002820C50000000000000000004948E8AC
+:102EA00000000000A58000000020081100000000C4
+:102EB0000000200000200C11000000008300000032
+:102EC00000604411000004080000000000204402DB
+:102ED0000000000000000000C020480000000000CA
+:102EE0000000000040204800000000000000001F1B
+:102EF000C0210220000000000000000014C00000FB
+:102F0000000003ED0000201000204411000000002C
+:102F10000000800000204811000000000000FFFFBA
+:102F2000C0481220000003F5A7800000002008110F
+:102F3000000000000000A00000200C1100000000B4
+:102F4000830000000060441100000408000000003D
+:102F5000002044020000000000000000C0204800E3
+:102F60000000000000000000C02048000000000039
+:102F70000000FFFFC02812200000000083000000B6
+:102F800000204411000000000000000000304883D1
+:102F90000000000084000000002044110000000038
+:102FA00000000000C02048000000000000000000F9
+:102FB0001D000000000000008300000000604411BC
+:102FC0000000040800000000C040040000000001F0
+:102FD000A980000000200811000000000000C000CF
+:102FE00000400C11000003F0AB800000002008112D
+:102FF000000000000000F8E000400C11000003F0A9
+:10300000AD80000000200811000000000000F880E2
+:1030100000400C11000003F0B380000000200811F4
+:10302000000000000000F3FC00400C11000003F061
+:10303000AF80000000200811000000000000E00048
+:1030400000400C11000003F0B180000000200811C6
+:10305000000000000000F00000400C11000003F030
+:1030600083000000002044110000000000002148FF
+:1030700000204811000000008400000000204411DE
+:103080000000000000000000C02048000000000018
+:10309000000000001D000000000000000000000013
+:1030A000008000000000000001182000C030462011
+:1030B0000000000000000000D900480000000000EF
+:1030C00000000000C020040000000000000000001C
+:1030D00000A0000A000000000218A000C030462036
+:1030E0000000000000000000D900480000000000BF
+:1030F00000000000C02004000000000000000000EC
+:1031000000A0000A000000000318C000C0304620E4
+:103110000000000000000000D9004800000000008E
+:1031200000000000C02004000000000000000000BB
+:1031300000A0000A000000000418F8E0C03046209B
+:103140000000000000000000D9004800000000005E
+:1031500000000000C020040000000000000000008B
+:1031600000A0000A000000000518F880C0304620CA
+:103170000000000000000000D9004800000000002E
+:1031800000000000C020040000000000000000005B
+:1031900000A0000A000000000618E000C030462031
+:1031A0000000000000000000D900480000000000FE
+:1031B00000000000C020040000000000000000002B
+:1031C00000A0000A000000000718F000C0304620F0
+:1031D0000000000000000000D900480000000000CE
+:1031E00000000000C02004000000000000000000FB
+:1031F00000A0000A000000000818F3FCC0304620C0
+:103200000000000000000000D9004800000000009D
+:1032100000000000C02004000000000000000000CA
+:1032200000A0000A000000000000003000200A2D6D
+:103230000000000000000000C0290C400000000059
+:1032400000000030002036230000000000000000D5
+:10325000C0200400000000000000000000A0000AE0
+:103260000000000086000000002044110000000063
+:103270000000000000404801000000008500000040
+:10328000C020441100000000000000000040480180
+:10329000000000000000217C00204411000000001C
+:1032A00000000000C02048000000000000000000F6
+:1032B000C02048000000000000000000C0204800BE
+:1032C0000000000081000000002044110000000008
+:1032D0000000000100204811000000000000000074
+:1032E000C0200800000000000000000017000000DF
+:1032F000000000000004217F006044110000067CF3
+:103300000000001F0021023000000000000000004B
+:1033100014C00000000000000000000000404C024B
+:103320000000043E00000000C0200C00000000006F
+:1033300000000000C020100000000000000000009D
+:10334000C02014000000000000000000C020180091
+:103350000000000000000000C0201C000000000071
+:1033600000007F0000280A21000000000000450046
+:10337000002F022200000000000000000CE000000E
+:103380000000044C00000000C020200000000000ED
+:103390000000000017000000000000000000001006
+:1033A00000280A230000000000000010002F022265
+:1033B00000000000000000000CE0000000000454C9
+:1033C0008100000000204411000000000000000106
+:1033D000002048110000000000040000006946249D
+:1033E0000000067C000000000040000000000459BE
+:1033F00081000000002044110000000000000000D7
+:1034000000204811000000000000216D0020441140
+:103410000000000000000000002048040000000040
+:103420000000000000604805000006810000000068
+:10343000002824F0000000000000000700280A23F4
+:103440000000000000000001002F02220000000028
+:10345000000000000AE0000000000460000000001E
+:10346000002F00C9000000000000000004E0000080
+:103470000000047900000000004000000000048605
+:1034800000000002002F02220000000000000000E7
+:103490000AE000000000046500000000002F00C9E1
+:1034A000000000000000000002E0000000000479BD
+:1034B000000000000040000000000486000000033F
+:1034C000002F022200000000000000000AE00000BF
+:1034D0000000046A00000000002F00C90000000086
+:1034E000000000000CE00000000004790000000073
+:1034F000004000000000048600000004002F0222AB
+:1035000000000000000000000AE000000000046F5E
+:1035100000000000002F00C90000000000000000B3
+:103520000AE00000000004790000000000400000F4
+:103530000000048600000005002F022200000000A9
+:10354000000000000AE00000000004740000000019
+:10355000002F00C9000000000000000006E000008D
+:103560000000047900000000004000000000048614
+:1035700000000006002F02220000000000000000F2
+:103580000AE000000000047900000000002F00C9DC
+:10359000000000000000000008E0000000000479C6
+:1035A00000000000004000000000048600007F00D2
+:1035B00000280A210000000000004500002F022220
+:1035C00000000000000000000AE000000000000011
+:1035D0000000000800210A23000000000000000095
+:1035E00014C0000000000483000021690020441181
+:1035F0000000000000000000C020480000000000A3
+:1036000000000000C0204800000000000000000092
+:10361000C020480000000000CAFEBABE00404811A9
+:103620000000000000000000C02044000000000076
+:1036300000000000C02000000000000000000000AA
+:10364000C04048000000000000007F0000280A2160
+:103650000000000000004500002F022200000000D2
+:10366000000000000AE000000000048C00000000E0
+:10367000C02000000000000000000000C02000008A
+:103680000000000000000000C0400000000000003A
+:103690000000000000404C080000044C0000000046
+:1036A000C0200800000000000000001040210E2093
+:1036B0000000000000000011402112200000000066
+:1036C00000000012402116200000000000002169C7
+:1036D000002044110000000000000000002048020B
+:1036E0000000000000000000002102250000000092
+:1036F0000000000014E00000000004960004000038
+:10370000C0494A2000000497FFFBFFFFC0284A2061
+:103710000000000000000000002102230000000063
+:103720000000000014E00000000004A300000000FE
+:10373000C02048000000000000000000C020480039
+:103740000000000000000000002102240000000032
+:103750000000000014C00000000000008100000014
+:1037600000204411000000000000000C002048115F
+:103770000000000000000000002000100000000019
+:103780000000000014C000000000049FA000000022
+:103790000020441100000000CAFEBABE00404811DB
+:1037A0000000000081000000002044110000000023
+:1037B0000000000400204811000000000000216B00
+:1037C000002044110000000000000000C02048104C
+:1037D00000000000810000000020441100000000F3
+:1037E0000000000500204811000000000000216CCE
+:1037F000002044110000000000000000C02048101C
+:103800000000000000000000002F02240000000063
+:10381000000000000CE000000000000000000000BC
+:10382000004000000000049D00000000C0210A20AC
+:10383000000000000000000014C00000000004B6FA
+:103840008100000000204411000000000000000082
+:1038500000204811000000000000216D00204411EC
+:103860000000000000000000C02048000000000030
+:1038700000000000C0604800000006810000000059
+:1038800000400000000004BA810000000020441144
+:1038900000000000000000010020481100000000AE
+:1038A00000040000C02946200000000000000000C5
+:1038B000C06000000000067C000000010021022220
+:1038C000000000000000000014C00000000004C15F
+:1038D00000002169002044110000000000000000E9
+:1038E000C02048000000000000000000C020480088
+:1038F0000000000000000000002048100000000050
+:10390000CAFEBABE004048110000000000000000DE
+:10391000C02044000000000000000000C04048102B
+:1039200000000000810000000020441100000000A1
+:10393000000000010020481100000000000021F8F4
+:1039400000204411000000000000000E002048117B
+:1039500000000000000421F9006044110000067C12
+:103960000000000000210230000000000000000004
+:1039700014C00000000004C3000021800020441196
+:103980000000000000000000C0204800000000000F
+:1039900000000000C0200000000000000000000047
+:1039A000C02048000000000000000000C02000000F
+:1039B0000000000000000000C040480000000000BF
+:1039C0000000000300333E2F000000000000000153
+:1039D00000210221000000000000000014E00000AF
+:1039E000000004F30000002C00200A2D000000005D
+:1039F0000004000018E00C11000004E200000001C7
+:103A000000333E2F00000000000021690020441117
+:103A1000000000000000000000204802000000003C
+:103A20000000000000204803000000000000000823
+:103A300000300A220000000000000000C020480002
+:103A40000000000000000000C0204800000000004E
+:103A50000000216900204411000000000000000067
+:103A60000020480200000000000000000020480381
+:103A7000000000000000000800300A2200000000E2
+:103A800000000000C020480000000000000000000E
+:103A9000D8C04800000004D600002169002044116D
+:103AA00000000000000000000020480200000000AC
+:103AB0000000000000204803000000000000000893
+:103AC00000300A220000000000000000C020480072
+:103AD0000000000000000000C020480000000000BE
+:103AE0000000002D0020122D00000000000000004A
+:103AF00000290C830000000000002169002044110F
+:103B0000000000000000000000204802000000004B
+:103B10000000000000204803000000000000000832
+:103B200000300A220000000000000000C020480011
+:103B30000000000000000000C0204800000000005D
+:103B4000000000110021022400000000000000001D
+:103B500014C0000000000000000000000040000051
+:103B60000000049D0000002CC02036200000000052
+:103B70000000002DC0403620000000000000000FB3
+:103B800000210221000000000000000014C000001D
+:103B9000000004F800000000006000000000000BBE
+:103BA00000000000D900000000000000000000003C
+:103BB000C040040000000001B500000000204411D6
+:103BC000000000000000200000204811000000005C
+:103BD000B600000000204411000000000000A0001A
+:103BE0000020481100000000B70000000020441130
+:103BF000000000000000C00000204811000000008C
+:103C0000B800000000204411000000000000F8E0AF
+:103C10000020481100000000B900000000204411FD
+:103C2000000000000000F8800020481100000000A3
+:103C3000BA00000000204411000000000000E00075
+:103C40000020481100000000BB00000000204411CB
+:103C5000000000000000F0000020481100000000FB
+:103C6000BC00000000204411000000000000F3FC34
+:103C700000204811000000008100000000204411D5
+:103C800000000000000000020020481100000000B9
+:103C9000000000FF00280E300000000000000000BF
+:103CA000002F022300000000000000000CC00000F4
+:103CB0000000050C00000000C0200800000000000B
+:103CC0000000000014C000000000052100000000FA
+:103CD00000200C11000000000000001C0020362312
+:103CE000000000000000002B002036230000000030
+:103CF00000000029002036230000000000000028FA
+:103D000000203623000000000000001700203623AA
+:103D10000000000000000025002036230000000005
+:103D200000000026002036230000000000000015DF
+:103D3000002036230000000000000016002036237B
+:103D400000000000FFFFE00000200C110000000058
+:103D500000000021002036230000000000000022A7
+:103D6000002036230000000000001FFF00200C117F
+:103D700000000000000000230020362300000000A7
+:103D8000000000240020362300000000F1FFFFFFA8
+:103D900000283A2E000000000000001AC0220E2069
+:103DA00000000000000000000029386E0000000044
+:103DB0008100000000204411000000000000000607
+:103DC00000204811000000000000002A402036209A
+:103DD00000000000870000000020441100000000E7
+:103DE00000000000C0204800000000000000A1F416
+:103DF00000204411000000000000000000204810D6
+:103E0000000000000000000000200C110000000075
+:103E10000000003000203623000000009D0000005C
+:103E200000204411000000000000001F40214A2033
+:103E30000000000096000000002044110000000077
+:103E400000000000C020480000000000000000004A
+:103E5000C0200C000000000000000000C020100086
+:103E6000000000000000001F0021162400000000D8
+:103E70000000000014C00000000000000000001D51
+:103E800000203623000000000000000300281E234D
+:103E900000000000000000080022222300000000B3
+:103EA000FFFFF000002822280000000000000000B2
+:103EB000002920E8000000000000001F0020362834
+:103EC000000000000000001800211E230000000078
+:103ED0000000002000203627000000000000000243
+:103EE000002216240000000000000000003014A88A
+:103EF000000000000000001E002036250000000029
+:103F00000000000300211A2400000000100000003F
+:103F100000281A2600000000EFFFFFFF00283A2EBD
+:103F20000000000000000000004938CE0000066AD2
+:103F30000000000140280A200000000000000006E8
+:103F400040280E200000000000000300C0281220BE
+:103F50000000000000000008002112240000000002
+:103F600000000000C020162000000000000000003B
+:103F7000C0201A20000000000000000000210222E2
+:103F8000000000000000000014C0000000000559FF
+:103F9000810000000020441100000000000000012A
+:103FA00000204811000000000000225800300A24C0
+:103FB0000000000000040000006946220000067CAA
+:103FC00000002169002044110000000000000000F2
+:103FD00000204805000000000002000000294A26D9
+:103FE0000000000000000000002048100000000059
+:103FF000CAFEBABE00204811000000000000000206
+:10400000002F022300000000000000000CC0000090
+:104010000000056100000000C0201C10000000002E
+:1040200000000000C04000000000056F000000021A
+:10403000002F022300000000000000000CC0000060
+:104040000000056181000000002044110000000014
+:10405000000000010020481100000000000022586C
+:1040600000300A240000000000040000006946221D
+:104070000000067C00000000C0201C1000000000B2
+:1040800000000000C04000000000056F00000000BC
+:10409000002F022300000000000000000CC0000000
+:1040A0000000056500000000C0201C0000000000AA
+:1040B00000000000C04000000000056F0000000488
+:1040C000002F022300000000000000000CC00000D0
+:1040D0000000056D81000000002044110000000078
+:1040E0000000000000204811000000000000216DC9
+:1040F000002044110000000000000000C020480023
+:104100000000000000000000C060480000000681C0
+:104110000000000000401C100000056F00000000BF
+:10412000C02000000000000000000000C0400000AF
+:1041300000000000000000000EE00000000005711B
+:104140000000000000600000000005BC000000004E
+:10415000002F022400000000000000000CC000003E
+:10416000000005820000A2B70020441100000000FA
+:10417000000000000020480700000000810000004F
+:104180000020441100000000000000010020481140
+:10419000000000000004A2B6006044110000067C8C
+:1041A0000000001A0021223000000000000000067C
+:1041B00000222630000000000004200400604411AA
+:1041C0000000067C0000A2C4002044110000000092
+:1041D00000000000003048E900000000000000007E
+:1041E00000E00000000005800000A2D10020441182
+:1041F000000000000000000000404808000000002F
+:104200000000A2D1002044110000000000000001C5
+:1042100000504A280000000000000001002F022486
+:1042200000000000000000000CC00000000005932A
+:104230000000A2BB002044110000000000000000AC
+:104240000020480700000000810000000020441109
+:1042500000000000000000010020481100000000E4
+:104260000004A2BA006044110000067C0000001A9D
+:10427000002122300000000000000006002226304D
+:104280000000000000042004006044110000067CCF
+:104290000000A2C500204411000000000000000042
+:1042A000003048E9000000000000000000E00000CD
+:1042B000000005910000A2D200204411000000007F
+:1042C0000000000000404808000000000000A2D2EA
+:1042D00000204411000000000000000100504A28A6
+:1042E0000000000000000002002F02240000000077
+:1042F000000000000CC00000000005A40000A2BFE8
+:1043000000204411000000000000000000204807C9
+:1043100000000000810000000020441100000000A7
+:104320000000000100204811000000000004A2BEAF
+:10433000006044110000067C0000001A00212230B9
+:1043400000000000000000060022263000000000EF
+:1043500000042004006044110000067C0000A2C696
+:10436000002044110000000000000000003048E977
+:10437000000000000000000000E00000000005A2B6
+:104380000000A2D300204411000000000000000043
+:1043900000404808000000000000A2D300204411A3
+:1043A000000000000000000100504A28000000004A
+:1043B0000000A2C300204411000000000000000023
+:1043C0000020480700000000810000000020441188
+:1043D0000000000000000001002048110000000063
+:1043E0000004A2C2006044110000067C0000001A14
+:1043F00000212230000000000000000600222630CC
+:104400000000000000042004006044110000067C4D
+:104410000000A2C7002044110000000000000000BE
+:10442000003048E9000000000000000000E000004B
+:10443000000005B10000A2D40020441100000000DB
+:104440000000000000404808000000000000A2D466
+:1044500000204411000000000000000100504A2824
+:104460000000000085000000002044110000000052
+:104470000000000000204801000000000000304A59
+:10448000002044110000000001000000002048113D
+:10449000000000000000000000400000000005B720
+:1044A000A4000000C0204411000000000000000033
+:1044B000C04048000000000000000000C060000094
+:1044C000000005BC00000000C04004000000000126
+:1044D0000000002C002036210000000081000000B8
+:1044E00000204411000000000000000600204811D8
+:1044F0000000000000000000002F0230000000005B
+:10450000000000000CC00000000005C30000000017
+:10451000002004110000000000000030004036219F
+:10452000000005D6000000300020062D000000002D
+:1045300000007E00002806210000000000000000AE
+:10454000002F022100000000000000000CE000002D
+:10455000000005D68100000000204411000000008A
+:104560000000000100204811000000000004A0929B
+:10457000006044110000067C00000031002036304D
+:10458000000000000004A093006044110000067CBD
+:104590000000003200203630000000000004A2B607
+:1045A000006044110000067C00000033002036301B
+:1045B000000000000004A2BA006044110000067C64
+:1045C0000000003400203630000000000004A2BECD
+:1045D000006044110000067C0000003500203630E9
+:1045E000000000000004A2C2006044110000067C2C
+:1045F00000000036002036300000000000042004D7
+:10460000006044110000067C0001A2A400204411B7
+:10461000000000000000003F0020481100000000E2
+:104620000000003F00204811000000000000003F93
+:1046300000204811000000000000003F0020481149
+:1046400000000000000000050020481100000000EC
+:104650000000A1F400204411000000000000000050
+:1046600000204811000000008800000000204411D4
+:1046700000000000000000010020481100000000C0
+:10468000810000000020441100000000000000062E
+:10469000002048110000000000000001002F02303F
+:1046A00000000000000000000CE000000000061FF9
+:1046B000000000300020062D000000000000000077
+:1046C000002F022100000000000000000CE00000AC
+:1046D0000000061F810000000020441100000000BF
+:1046E00000000001002048110000000000007E00D2
+:1046F000002806210000000000000000002F022119
+:1047000000000000000000000CE00000000005F8C0
+:104710000000A092002044110000000000000031C1
+:1047200000204A2D000000000000A093002044114A
+:10473000000000000000003200204A2D00000000B0
+:104740000000A2B600204411000000000000003369
+:1047500000204A2D000000000000A2BA00204411F1
+:10476000000000000000003400204A2D000000007E
+:104770000000A2BE0020441100000000000000352F
+:1047800000204A2D000000000000A2C200204411B9
+:10479000000000000000003600204A2D000000004C
+:1047A000000000300020062D00000000000001FF86
+:1047B000002806210000000000000000002F022158
+:1047C00000000000000000000CE000000000061ED9
+:1047D0000000000000210221000000000000000095
+:1047E00014C00000000006010004A0030060441192
+:1047F0000000067C0000A00300204411000000001F
+:10480000000000000020481000000000000000012F
+:1048100000210621000000000000000014C000007C
+:10482000000006060004A010006044110000067C91
+:104830000000A01000204411000000000000000053
+:1048400000204810000000000000000100210621A7
+:104850000000000000000000002F02210000000006
+:10486000000000000CE000000000061E0004A01183
+:10487000006044110000067C0000A01100204411DB
+:1048800000000000000000000020481000000000B0
+:104890000004A012006044110000067C0000A01279
+:1048A000002044110000000000000000002048101B
+:1048B000000000000004A013006044110000067C0A
+:1048C0000000A013002044110000000000000000C0
+:1048D00000204810000000000004A01400604411F3
+:1048E0000000067C0000A01400204411000000001D
+:1048F0000000000000204810000000000004A01587
+:10490000006044110000067C0000A0150020441146
+:10491000000000000000000000204810000000001F
+:104920000004A016006044110000067C0000A016E0
+:10493000002044110000000000000000002048108A
+:10494000000000000004A017006044110000067C75
+:104950000000A0170020441100000000000000002B
+:1049600000204810000000000004200400604411F2
+:104970000000067C0000002C0080062D00000000D6
+:10498000FF000000002044110000000000000000B3
+:104990000020481100000000000000010020481124
+:1049A000000000000000000200804811000000002C
+:1049B000000000000EE000000000063000000030A3
+:1049C0000020062D00000000000000020028062143
+:1049D0000000000000000000002F02210000000085
+:1049E000000000000CE000000000062E8100000026
+:1049F00000204411000000000000000100204811C8
+:104A00000000000000042004006044110000067C47
+:104A10000000100000200811000000000000002B22
+:104A200000203622000000000000000000600000AE
+:104A3000000006340000000000600000000005BC1B
+:104A40009800000000204411000000000000000059
+:104A5000008048110000000000000000C06000005D
+:104A60000000063400000000C04004000000000107
+:104A70000000A2A400204411000000000000002259
+:104A800000204811000000008900000000204411AF
+:104A90000000000000000001004048110000062056
+:104AA00097000000002044110000000000000000FA
+:104AB00000204811000000008A000000002044117E
+:104AC0000000000000000000004048110000062027
+:104AD00000000000006000000000064D0001A2A4DC
+:104AE000C0204411000000000000001600604811C2
+:104AF0000000036A000020100020441100000000A4
+:104B000000010000002048110000000081000000AA
+:104B100000204411000000000000000100204811A6
+:104B2000000000000000217C002044110000000073
+:104B3000098000000020481100000000FFFFFFFF77
+:104B40000020481100000000000000000020481173
+:104B5000000000000000000017000000000000003E
+:104B60000004217F006044110000067C0000001F4B
+:104B700000210230000000000000000014C000000E
+:104B8000000000000000000400404C110000064737
+:104B900000000000004000000000000000000017BE
+:104BA00000201E2D000000000000000400291E2728
+:104BB0000000000000000017008036270000000001
+:104BC0000000001700201E2D00000000FFFFFFFB6B
+:104BD00000281E2700000000000000170080362774
+:104BE000000000000000001700201E2D0000000043
+:104BF0000000000800291E27000000000000001728
+:104C000000803627000000000000001700201E2D45
+:104C100000000000FFFFFFF700281E270000000033
+:104C20000000001700803627000000000001A2A449
+:104C30000020441100000000000000160060481130
+:104C40000000036A00002010002044110000000052
+:104C50000001000000204811000000000000217C3D
+:104C600000204411000000000180000000204811D5
+:104C700000000000FFFFFFFF0020481100000000BF
+:104C800000000000002048110000000000000000AB
+:104C90001700000000000000810000000020441107
+:104CA000000000000000000100204811000000008A
+:104CB0000004217F006044110000067C0000001FFA
+:104CC00000210230000000000000000014C00000BD
+:104CD0000000067B0000001000404C11000006613F
+:104CE00000000000C02004000000000000000000E0
+:104CF00038C00000000000000000001D00200A2D48
+:104D0000000000000000001E00200E2D000000002A
+:104D10000000001F0020122D0000000000000020F5
+:104D20000020162D00000000000021690020441121
+:104D30000000000000000000002048040000000007
+:104D400000000000002048050000000000000000F6
+:104D50000020480100000000CAFEBABE0020481131
+:104D600000000000000000040030122400000000D9
+:104D700000000000002F00640000000000000000A0
+:104D80000CC000000000067A0000000300281A2270
+:104D900000000000000000080022122200000000B5
+:104DA000FFFFF000002812240000000000000000B7
+:104DB000002910C4000000000000001F004036243D
+:104DC0000000000000000000008000000000000063
+:104DD000000000001AC000000000067C9F000000D8
+:104DE0000020441100000000CAFEBABE0020481195
+:104DF00000000000000000001AE000000000067F34
+:104E00000000000000800000000000000000000022
+:104E10001AC00000000006819E000000002044111E
+:104E200000000000CAFEBABE0020481100000000C9
+:104E3000000000001AE000000000068400000000EE
+:104E40000080000000000000000000000060000082
+:104E50000000000B000010000060041100000315AA
+:104E6000000000000020041100000000000000000D
+:104E700000600811000001B20000225C0020441113
+:104E800000000000000000030020481100000000A6
+:104E90000000225600204411000000000000001B0A
+:104EA00000204811000000000000A1FC0020441177
+:104EB0000000000000000001002048110000000078
+:104EC0000001A1FDC02044110000000000000021ED
+:104ED00000201E2D000000000000001000221E27F0
+:104EE00000000000000000240020222D000000002F
+:104EF0000000FFFF00282228000000000000000042
+:104F000000294907000000000000000000204811AF
+:104F100000000000000000220020222D0000000000
+:104F20000000FFFF00282228000000000000000011
+:104F3000002949070000000000000000002048117F
+:104F4000000000000000002300201E2D00000000D3
+:104F50000000001000221E270000000000000000DA
+:104F6000002949070000000000000000004048112F
+:104F70000000000000000000000000000000000031
+:104F80000000000000000000000000000000000021
+:104F90000000000000000000000000000000000011
+:104FA0000000000000000000000000000000000001
+:104FB00000000000000000000000000000000000F1
+:104FC00000000000000000000000000000000000E1
+:104FD00000000000000000000000000000000000D1
+:104FE00000000000000000000000000000000000C1
+:104FF00000000000000000000000000000000000B1
+:1050000000000000000000000000000000000000A0
+:105010000000000000000000000000000000000090
+:105020000000000000000000000000000000000080
+:105030000000000000000000000000000000000070
+:105040000000000000000000000000000000000060
+:105050000000000000000000000000000000000050
+:105060000000000000000000000000000000000040
+:105070000000000000000000000000000000000030
+:105080000000000000000000000000000000000020
+:105090000000000000000000000000000000000010
+:1050A0000000000000000000000000000000000000
+:1050B00000000000000000000000000000000000F0
+:1050C00000000000000000000000000000000000E0
+:1050D00000000000000000000000000000000000D0
+:1050E00000000000000000000000000000000000C0
+:1050F00000000000000000000000000000000000B0
+:10510000000000000000000000000000000000009F
+:10511000000000000000000000000000000000008F
+:10512000000000000000000000000000000000007F
+:10513000000000000000000000000000000000006F
+:10514000000000000000000000000000000000005F
+:10515000000000000000000000000000000000004F
+:10516000000000000000000000000000000000003F
+:10517000000000000000000000000000000000002F
+:10518000000000000000000000000000000000001F
+:10519000000000000000000000000000000000000F
+:1051A00000000000000000000000000000000000FF
+:1051B00000000000000000000000000000000000EF
+:1051C00000000000000000000000000000000000DF
+:1051D00000000000000000000000000000000000CF
+:1051E00000000000000000000000000000000000BF
+:1051F00000000000000000000000000000000000AF
+:10520000000000000000000000000000000000009E
+:10521000000000000000000000000000000000008E
+:10522000000000000000000000000000000000007E
+:10523000000000000000000000000000000000006E
+:10524000000000000000000000000000000000005E
+:10525000000000000000000000000000000000004E
+:10526000000000000000000000000000000000003E
+:10527000000000000000000000000000000000002E
+:10528000000000000000000000000000000000001E
+:10529000000000000000000000000000000000000E
+:1052A00000000000000000000000000000000000FE
+:1052B000014204F505B302500000000001C301687B
+:1052C000043505B300000000022502090250015117
+:1052D000000000000223024502A00241000000007D
+:1052E00003CD05B305B305B300000000063C063D41
+:1052F000031F05B30000000005B305B803200340F9
+:1053000000000000032A0282034203340000000070
+:1053100005B305B305B305B30000000005B30544AC
+:1053200005B305B30000000003B205B304AE0344A7
+:1053300000000000048D0443043305B300000000A6
+:1053400004C305B3043704D000000000044304FA8A
+:10535000035103710000000005B305B305B305B3A5
+:105360000000000005B305B305B305B3000000005D
+:1053700005B305B3063205BA0000000005B305B356
+:10538000000705B30000000005B305B305B305B37E
+:105390000000000005B305B305B305B3000000002D
+:1053A00003EE03E303FE03FC00000000040404001A
+:1053B00004020406000000000412040E041A04167D
+:1053C000000000000422041E042A0426000000003D
+:1053D00005B305B3042E05B30000000005B305B303
+:1053E00005B305B30000000005B305B305B305B36D
+:1053F00000000000000206680686000600000000AB
+:00000001FF
diff --git a/firmware/radeon/RV670_pfp.bin.ihex b/firmware/radeon/RV670_pfp.bin.ihex
new file mode 100644
index 0000000..f55292c
--- /dev/null
+++ b/firmware/radeon/RV670_pfp.bin.ihex
@@ -0,0 +1,145 @@
+:1000000000CA040000A00000007E828B007C038BED
+:10001000008001B8007C038B00D4401E00EE001E5F
+:1000200000CA040000A00000007E828B00C41838C3
+:1000300000CA240000CA2800009581A800C41C3A08
+:1000400000C3C00000CA080000CA0C00007C744B4A
+:1000500000C200050099C00000C41C3A007C744C2A
+:1000600000C0FFF000042C0400309002007D250049
+:1000700000351402007D350B00255403007CD5802B
+:1000800000259C030095C00400D5001B007EDDC147
+:10009000007D9D8000D6801B00D5801B00D4401EB3
+:1000A00000D5401E00D6401E00D6801E00D4801E03
+:1000B00000D4C01E009783D300D5C01E00CA08001C
+:1000C0000080001A00CA0C0000E4011E00D4001ECB
+:1000D0000080000C00C4183800E4013E00D4001E6B
+:1000E0000080000C00C4183800D4401E00EE001E32
+:1000F00000CA040000A00000007E828B00E4011E04
+:1001000000D4001E00D4401E00EE001E00CA0400F1
+:1001100000A00000007E828B00E4013E00D4001E9F
+:1001200000D4401E00EE001E00CA040000A0000023
+:10013000007E828B00CA180000D4401E00D5801EAD
+:100140000080005300D4007500D4401E00CA08008F
+:1001500000CA0C0000CA100000D4801900D4C018D6
+:1001600000D5001700D4801E00D4C01E00D5001E8C
+:1001700000E2001E00CA040000A00000007E828B86
+:1001800000CA080000D4806000D4401E0080000037
+:1001900000D4801E00CA080000D4806100D4401E34
+:1001A0000080000000D4801E00CA080000CA0C00B5
+:1001B00000D4401E00D4801600D4C01600D4801E87
+:1001C000008001B800D4C01E00C6084300CA0C005D
+:1001D00000CA10000094800400CA140000E420F358
+:1001E00000D4201300D5606500D4E01C00D5201C8D
+:1001F00000D5601C008000000006200100C60843F6
+:1002000000CA0C0000CA1000009483F700CA140052
+:1002100000E420F30080007900D4201300C60843D6
+:1002200000CA0C0000CA1000009883EF00CA140036
+:1002300000D400640080008D0000000000C414326F
+:1002400000C6184300C4082F0095400500C40C30B8
+:1002500000D4401E0080000000EE001E009583F5D3
+:1002600000C4103100D4403300D5206500D4A01C58
+:1002700000D4E01C00D5201C00E4015E00D4001E68
+:10028000008000000006200100CA1800000A2001BA
+:1002900000D6007600C408360098800700C61045D6
+:1002A0000095011000D4001F00D46062008000009F
+:1002B00000D4206200CC383500CC1433008401BB5C
+:1002C00000D4007200D5401E0080000000EE001E29
+:1002D00000E2001A008401BB00E2001A00CC104BBF
+:1002E00000CC0447002C9401007D098B0098400548
+:1002F000007D15CB00D4001A008001B800D4006D39
+:100300000034440100CC0C480098403A00CC2C4A00
+:100310000095800400CC0449008001B800D4001A84
+:1003200000D4C01A00282801008400F000CC10037B
+:100330000098801B0004380C008400F000CC1003EF
+:100340000098801700043808008400F000CC1003E7
+:100350000098801300043804008400F000CC1003DF
+:100360000098801400CC104C009A800900CC144DE9
+:10037000009840DC00D4006D00CC184800D5001A6D
+:1003800000D5401A008000C900D5801A0096C0D55B
+:1003900000D4006D008001B800D4006E009AC00344
+:1003A00000D4006D00D4006E0080000000EC007FDF
+:1003B000009AC0CC00D4006D008001B800D4006E5B
+:1003C00000CC140300CC180300CC1C03007D910367
+:1003D000007DD583007D190C0035CC1F0035701FC2
+:1003E000007CF0CB007CD08B00880000007E8E8BE0
+:1003F0000095C00400D4006E008001B800D4001A3B
+:1004000000D4C01A00CC080300CC0C0300CC1003AD
+:1004100000CC140300CC180300CC1C0300CC240334
+:1004200000CC28030035C41F0036B01F007C704B81
+:100430000034F01F007C704B0035701F007C704B47
+:10044000007D8881007DCCC1007E5101007E9541F8
+:10045000007C9082007CD4C2007C848B009AC00314
+:10046000007C8C8B002C88010098809E00D4006D4D
+:100470000098409C00D4006E00CC084C00CC0C4D81
+:1004800000CC104800D4801A00D4C01A00800101AA
+:1004900000D5001A00CC083200D40032009482D972
+:1004A00000CA0C0000D4401E0080000000D4001ED2
+:1004B00000E4011E00D4001E00CA080000CA0C009F
+:1004C00000CA100000D4401E00CA140000D4801ED0
+:1004D00000D4C01E00D5001E00D5401E00D54034FB
+:1004E0000080000000EE001E0028040400E2001A54
+:1004F00000E2001A00D4401A00CA380000CC0803F9
+:1005000000CC0C0300CC0C0300CC0C03009882BD83
+:1005100000000000008401BB00D7A06F0080000035
+:1005200000EE001F00CA040000C2FF0000CC083427
+:1005300000C13FFF007C74CB007CC90B007D010F24
+:10054000009902B0007C738B008401BB00D7A06FC0
+:100550000080000000EE001F00CA080000281900FB
+:10056000007D898B009580140028140400CA0C00BB
+:1005700000CA100000CA1C0000CA240000E2001FCC
+:1005800000D4C01A00D5001A00D5401A00CC1803B8
+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD
+:1005A000007D9C4700984297000000000080016198
+:1005B00000D4C01A00D4401E00D4801E0080000069
+:1005C00000EE001E00E4011E00D4001E00D4401EF8
+:1005D00000EE001E00CA040000A00000007E828B16
+:1005E00000E4013E00D4001E00D4401E00EE001EB8
+:1005F00000CA040000A00000007E828B00CA080030
+:1006000000248C06000CCC060098C00600CC104ECE
+:100610000099000400D4007300E4011E00D4001E01
+:1006200000D4401E00D4801E0080000000EE001E9A
+:1006300000CA080000CA0C000034D01800251001C0
+:100640000095002100C17FFF00CA100000CA1400FD
+:1006500000CA180000D4801D00D4C01D007DB18BDD
+:1006600000C1420200C2C00100D5801D0034DC0E72
+:10067000007D5D4C007F734C00D7401E00D5001EEE
+:1006800000D5401E00C1420000C2C00000099C010C
+:100690000031DC10007F5F4C007F734C00042802A7
+:1006A000007D838000D5A86F00D5806600D7401EEE
+:1006B00000EC005E00C8240200C82402008001B8DB
+:1006C00000D6007600D4401E00D4801E00D4C01E88
+:1006D0000080000000EE001E0080000000EE001F01
+:1006E00000D4001F0080000000D4001F00D4001FB1
+:1006F0000088000000D4001F00000000000000007F
+:1007000000000000000000000000000000000000E9
+:1007100000000000000000000000000000000000D9
+:1007200000000000000000000000000000000000C9
+:1007300000000000000000000000000000000000B9
+:1007400000000000000000000000000000000000A9
+:100750000000000000000000000000000000000099
+:100760000000000000000000000000000000000089
+:100770000000000000000000000000000000000079
+:100780000000000000000000000000000000000069
+:100790000000000000000000000000000000000059
+:1007A0000000000000000000000000000000000049
+:1007B0000000000000000000000000000000000039
+:1007C0000000000000000000000000000000000029
+:1007D0000000000000000000000000000000000019
+:1007E0000000000000000000000000000000000009
+:1007F00000000000000000000000000000000000F9
+:1008000000010171000201780003008F0004007FE5
+:10081000000500030006003F000700320008012C1D
+:1008200000090046000A0036001001B6001700A2B9
+:100830000022013A00230149002000B400240125D0
+:100840000027004D0028006A002A0060002B00529B
+:10085000002F0065003200870034017F003C015604
+:10086000003F00720041018C0044012E00550173CD
+:100870000056017A0060000B00610034006200380D
+:1008800000630038006400380065003800660038F6
+:10089000006700380068003A00690041006A0048BB
+:1008A000006B0048006C0048006D0048006E004876
+:1008B000006F00480000000600000006000000066F
+:1008C0000000000600000006000000060000000610
+:1008D0000000000600000006000000060000000600
+:1008E00000000006000000060000000600000006F0
+:1008F00000000006000000060000000600000006E0
+:00000001FF
diff --git a/firmware/radeon/RV710_me.bin.ihex b/firmware/radeon/RV710_me.bin.ihex
new file mode 100644
index 0000000..5cdfe30
--- /dev/null
+++ b/firmware/radeon/RV710_me.bin.ihex
@@ -0,0 +1,341 @@
+:10000000CC0003EA04080003CC8000437C4080005D
+:10001000A0000000CC80006280000003D040007F80
+:1000200080000003CC4000417C40C000C0160004AA
+:1000300030D03FFF7D15000CCC11000028D8001EE9
+:100040003198000128DC001FC820000495C000067C
+:100050007C424000CC0000627E56800CCC2900001F
+:10006000C82400047E26000B958000067C42C00058
+:10007000CC0000627ED7000CCC310000C82C0004FC
+:100080007E2E000CCC00006231103FFF8000000388
+:10009000CE1100007C40C00080000003CC40004036
+:1000A00080000003CC4122577C418000CC400045B9
+:1000B000CC400048CC41225CCC41A1FC7C4080007B
+:1000C000A0000000CC800062CC400045CC4000483D
+:1000D0007C40C000CC41225CCC41A1FC7C40800033
+:1000E000A0000000CC800062CC000045CC0000489D
+:1000F000CC41225CCC41A1FC7C408000A0000000EF
+:10010000CC800062040CA1FDC0120001CC000045AF
+:10011000CC0000487CD0C00CCC41225CCC41A1FC7E
+:10012000D04D00007C408000A0000000CC80006228
+:1001300080000003CC41225D7C4080007C40C000F8
+:10014000C02A00027C4100007D29000C309400018F
+:1001500030980006309C030029DC00087C42000037
+:100160007C4240009540000FC02E000405F022584C
+:100170007F2F000CCC310000C8280004CCC12169BD
+:10018000CD01216ACE81216B0DB40002CC01216C1E
+:100190009740000E0DB400008000007DC834000AB6
+:1001A0000DB40002974000090DB40000C02E0004F9
+:1001B00005F022587F2F000CCC310000C828000425
+:1001C0008000007DC834000A974000047E02800051
+:1001D0008000007DC834000A0DB400049740FF8CF5
+:1001E00000000000CE01216DCE41216EC828000321
+:1001F000C834000A9B400004043C00058400026DE2
+:10020000CC0000620DF400009740000BC82C03E600
+:10021000CE81A2B7C03000067EF34028C030002057
+:100220007F6B80207FB3C029CF81A2C480000003F0
+:10023000CFC1A2D10DF400019740000BC82C03E7F9
+:10024000CE81A2BBC03000067EF34028C030002023
+:100250007F6B80207FB3C029CF81A2C580000003BF
+:10026000CFC1A2D20DF400029740000BC82C03E8C6
+:10027000CE81A2BFC03000067EF34028C0300020EF
+:100280007F6B80207FB3C029CF81A2C6800000038E
+:10029000CFC1A2D3C82C03E9CE81A2C3C0300006CF
+:1002A0007EF34028C03000207F6B80207FB3C029C0
+:1002B000CF81A2C780000003CFC1A2D48000000379
+:1002C000CC4000427C40C0007C4100002914001D4D
+:1002D000315400019940000C31181000C81C001165
+:1002E00095C00000C81C0011CCC12100CD01210126
+:1002F000CCC12102CD012103041800048000037E3B
+:10030000CD81A2A4C02A00049580000836A821A3AC
+:10031000CC290000C8280004C81C00110DE40040CE
+:100320009640FFFFC81C0011CCC12170CD01217186
+:10033000C820001296000000C82000128000037E32
+:10034000CC0000647C40C0007C410000CC00004533
+:10035000CC00004840D40003CD41225CCD01A1FC7B
+:10036000C01A0001041CA1FD7DD9C00C7C42000014
+:1003700008CC00010624000106280002CE1D000062
+:10038000CE5D000098C0FFFACE9D00007C4080004A
+:10039000A0000000CC8000627C40C00030D0000192
+:1003A00028CC00017C414000950000067C41800083
+:1003B000CD41216DCD81216E800000F4C81C000369
+:1003C000C02200047E16000CCC210000C81C0004D2
+:1003D0007C42400098C000047C4280008000000302
+:1003E000CDE50000CE412169CE81216ACDC1216BCE
+:1003F00080000003CC01216C7C40C0007C410000E7
+:100400007C4140007C4180007C41C00028A4000861
+:10041000326400FF0E68003C9680000A7C020000F7
+:100420007C4200001E300003CC00006A9B000003E9
+:100430004220000504200040800001117C024000A1
+:100440007E0240009A4000000A64000130EC001077
+:100450009AC0000ACC000062C02A0004C82C002107
+:100460007E92800CCC000041CC290000CEC000213F
+:1004700080000121C8300004CD01216DCD41216EE5
+:10048000C83000037F1F000B30F4000727780001FD
+:100490009740002A07B801269F8000000000000056
+:1004A000800001367F1B80048000013A7F1B80059D
+:1004B0008000013E7F1B8002800001427F1B800381
+:1004C000800001467F1B80078000014A7F1B800659
+:1004D0008000014F28A400089B80001928A4000870
+:1004E0008000015F326400FF9B80001528A4000893
+:1004F0008000015F326400FF9B80001128A4000887
+:100500008000015F326400FF9B80000D28A400087A
+:100510008000015F326400FF9B80000928A400086E
+:100520008000015F326400FF9B80000528A4000862
+:100530008000015F326400FF28A40008326400FFDD
+:100540000E68003C9A80FEB228EC00087C43400014
+:100550007C4380007C43C00096C00007CC00006252
+:10056000CF412169CF81216ACFC1216B8000000377
+:10057000CC01216C80000003CFF50000CC00006BA3
+:10058000840003810E68003C9A800004C82800158E
+:1005900080000003D040007F9680FFAB7E024000C9
+:1005A0008400023BC00E0002CC00004180000239F2
+:1005B000CCC1304A7C40C0007C410000C01E00011C
+:1005C00029240012C022000296400005C026000423
+:1005D000C027FFFB7D25000BC02600007DD2800BCD
+:1005E0007E12C00B7D25000C7C4140007C418000C8
+:1005F000CCC121699A80000ACD01216ACD41216BCD
+:1006000096C0FE83CD81216CC83000189700000091
+:10061000C830001880000003CC000018840003815B
+:10062000CC00007FC8140013C8180014CD41216B02
+:1006300096C0FE77CD81216C80000183C830001800
+:10064000C80C000898C00000C80C00087C410000DD
+:1006500095000002000000007C414000C820000915
+:10066000CC400043CE01A1F4CC400044C00E800039
+:100670007C4240007C4280002AAC001F96C0FE6491
+:10068000C035F000CE4003E232780003267C00083B
+:100690007FF7C00B7FFBC00C2A780018CFC003E3A4
+:1006A000CF8003E426B000027F3F0000CF0003E5C7
+:1006B0008000031F7C80C0007C40C00028D0000860
+:1006C0003110000F9500000F2528000106A801B485
+:1006D0009E80000000000000800001D5C0120800CC
+:1006E000800001E3C814000F800001EAC814001064
+:1006F000800001F1CCC1A2A4800001FAC81400114D
+:1007000030D0003F0D2800159A8000120D28001EE1
+:100710009A80001E0D2800209A8000230D24000FCF
+:100720000D2800107E6A800C9A8000260D2000049F
+:100730000D2400140D2800287E62400C7EA6800C3B
+:100740009A80002AC814001180000003CCC1A2A422
+:10075000C01208007C4140007D0CC00CC012000893
+:1007600029580003295C000C7C4200007DD1C00B9D
+:10077000262000147E1E400C7E4E800CCE81A2A44A
+:1007800080000003CD81A1FEC814000F0410210ECB
+:1007900095400000C814000FD051000080000003F5
+:1007A000CCC1A2A4C8140010041021089540000078
+:1007B000C8140010D051000080000003CCC1A2A4D6
+:1007C000CCC1A2A404100001CD0000198400038153
+:1007D000CC00007FC810001999000000C810001953
+:1007E000800000047C40800004102100954000003F
+:1007F000C8140011D05100008000037ECCC1A2A417
+:100800007C40C000CC40000D94C0FE01CC40000EE6
+:100810007C4100009500000508CC0001C8140005CB
+:10082000994000140000000098C0FFFB7C410000CC
+:10083000800000047D008000C81400057C40C000DA
+:100840009940000CC818000C7C4100009580FDF018
+:10085000C820000EC81C000D662000207E1E002C43
+:10086000252400027E62402080000003CCE60000C8
+:100870007C410000CC00006CCC00006DC818001F4B
+:10088000C81C001E659800207DD9C02C7CD4C00CEB
+:10089000CCDE000045DC0004C82800179680000F5D
+:1008A000C00E0001286800082AAC001632A800FF1C
+:1008B0000EB000497F2F000B9700000600000000DB
+:1008C000C81400057C40C000800002237C41000069
+:1008D00080000226D040007F8400023BCC00004113
+:1008E000CCC1304A94000000C83C001A043C00050A
+:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8
+:100900007F7B400CCF41217CCFC1217DCC01217E5A
+:10091000C03A00040434217F7F7B400CCC350000BA
+:10092000C83C00042BFC001F0438002097C00005C1
+:10093000CC0000629B8000000BB8000180000247E1
+:10094000CC000071CC01A1F404380016C0360002BE
+:10095000CF81A2A488000000CF4120107C40C000BD
+:1009600028D0001C9500000504D40001CD4000658E
+:1009700080000003CD40006809540002800000039D
+:10098000CD4000668400026CC81803EA7C40C000B9
+:100990009980FD9FC814001608D000019940002BD3
+:1009A000CD0000687C408000A0000000CC80006288
+:1009B000043C0005CFC1A2A4CC01A1F484000381B2
+:1009C000CC00004688000000CC00007F8400027E3E
+:1009D000C81803EA7C40C0009980FD8DC814001639
+:1009E00008D0000199400019CD0000687C408000CB
+:1009F000A0000000CC800062043C0022CFC1A2A471
+:100A000084000381CC00004788000000CC00007FF8
+:100A1000C81000169900000DCC400067800000044B
+:100A20007C408000C81803EA9980FD797C40C000B2
+:100A300094C00003C810001699000004CCC00068E0
+:100A4000800000047C4080008400023BC0148000D1
+:100A5000CC000041CD41304AC01480009900000014
+:100A6000C8100016800000047C408000C012000105
+:100A70007C51400C80000003D05500007C40C00039
+:100A80007C4100007C4140007C418000291C001F0B
+:100A9000CCC0004ACD00004B95C00003C01C8000B4
+:100AA000CDC12010DD830000055C2000CC00006279
+:100AB00080000003D81F41007C40C0007C41000042
+:100AC0007C4140007C418000CCC0004CCD00004DFA
+:100AD000DD830000055CA00080000003D81F4100FA
+:100AE0007C40C0007C4100007C4140007C41800093
+:100AF000CCC0004ECD00004FDD830000055CC0007F
+:100B000080000003D81F41007C40C0007C410000F1
+:100B10007C4140007C418000CCC00050CD000051A1
+:100B2000DD830000055CF8E080000003D81F410071
+:100B30007C40C0007C4100007C4140007C41800042
+:100B4000CCC00052CD000053DD830000055CF8806E
+:100B500080000003D81F41007C40C0007C410000A1
+:100B60007C4140007C418000CCC00054CD00005549
+:100B7000DD830000055CE00080000003D81F410019
+:100B80007C40C0007C4100007C4140007C418000F2
+:100B9000CCC00056CD000057DD830000055CF0009E
+:100BA00080000003D81F41007C40C0007C41000051
+:100BB0007C4140007C418000CCC00058CD000059F1
+:100BC000DD830000055CF3FC80000003D81F4100BA
+:100BD000D04320007C408000A0000000CC80006258
+:100BE000D043A0007C408000A0000000CC800062C8
+:100BF000D043C0007C408000A0000000CC80006298
+:100C0000D043F8E07C408000A0000000CC8000626F
+:100C1000D043F8807C408000A0000000CC800062BF
+:100C2000D043E0007C408000A0000000CC80006247
+:100C3000D043F0007C408000A0000000CC80006227
+:100C4000D043F3FC7C408000A0000000CC80006218
+:100C5000C81403E0CC430000CC430000CC430000A8
+:100C60007D45C000CDC30000D04300007C40800023
+:100C7000A0000000CC8000627C40C000C81003E2ED
+:100C8000C81403E5C81803E3C81C03E4CD81216937
+:100C9000CDC1216ACCC1216BCC01216C04200004A0
+:100CA0007DA180007D9640029640FCD9CD8003E373
+:100CB00031280003C02DF000251800087DAD800B01
+:100CC0007DA9800C80000003CD8003E3308CFFFF02
+:100CD000D04D00007C408000A0000000CC8000626D
+:100CE000C8140020155800029580FFFFC81400208A
+:100CF000CC00006ECC4121807C40C000CCC1218D55
+:100D0000CC41218128D0001F34588000CD81218C16
+:100D10009500FCBFCC412182C81400209940FFFF00
+:100D2000C8140020800000047C4080007C40C0008B
+:100D300028D0001831100001C01600809500000373
+:100D4000C02A00047CD4C00CCCC1217CCC41217DC4
+:100D5000CC41217E7C4180001DB0000336A0217F64
+:100D60009B000003419C0005041C004099C000004A
+:100D700009DC0001CC210000C82400042A6C001FFB
+:100D8000419C00059AC0FFFACC80006280000004FC
+:100D90007C4080007C40C00004D403E68000000357
+:100DA000CC5400008000037ECC4003EAC01C8000CD
+:100DB000044CA000CDC120107C410000C8140009E3
+:100DC00004180000041C0008CD80007109DC00013B
+:100DD00005980001CD0D000099C0FFFCCC80006299
+:100DE0008000037ECD400071C00E0100CC000041A8
+:100DF000CCC1304AC83C007FCC00007F800000039B
+:100E0000CC00007FCC00007F88000000CC00007F79
+:100E100000000000000000000000000000000000D2
+:100E200000000000000000000000000000000000C2
+:100E300000000000000000000000000000000000B2
+:100E400000000000000000000000000000000000A2
+:100E50000000000000000000000000000000000092
+:100E60000000000000000000000000000000000082
+:100E70000000000000000000000000000000000072
+:100E80000000000000000000000000000000000062
+:100E90000000000000000000000000000000000052
+:100EA0000000000000000000000000000000000042
+:100EB0000000000000000000000000000000000032
+:100EC0000000000000000000000000000000000022
+:100ED0000000000000000000000000000000000012
+:100EE0000000000000000000000000000000000002
+:100EF00000000000000000000000000000000000F2
+:100F000000000000000000000000000000000000E1
+:100F100000000000000000000000000000000000D1
+:100F200000000000000000000000000000000000C1
+:100F300000000000000000000000000000000000B1
+:100F400000000000000000000000000000000000A1
+:100F50000000000000000000000000000000000091
+:100F60000000000000000000000000000000000081
+:100F70000000000000000000000000000000000071
+:100F80000000000000000000000000000000000061
+:100F90000000000000000000000000000000000051
+:100FA0000000000000000000000000000000000041
+:100FB0000000000000000000000000000000000031
+:100FC0000000000000000000000000000000000021
+:100FD0000000000000000000000000000000000011
+:100FE0000000000000000000000000000000000001
+:100FF00000000000000000000000000000000000F1
+:1010000000000000000000000000000000000000E0
+:1010100000000000000000000000000000000000D0
+:1010200000000000000000000000000000000000C0
+:1010300000000000000000000000000000000000B0
+:1010400000000000000000000000000000000000A0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:101070000000000000000000000000000000000070
+:101080000000000000000000000000000000000060
+:101090000000000000000000000000000000000050
+:1010A0000000000000000000000000000000000040
+:1010B0000000000000000000000000000000000030
+:1010C0000000000000000000000000000000000020
+:1010D0000000000000000000000000000000000010
+:1010E0000000000000000000000000000000000000
+:1010F00000000000000000000000000000000000F0
+:1011000000000000000000000000000000000000DF
+:1011100000000000000000000000000000000000CF
+:1011200000000000000000000000000000000000BF
+:1011300000000000000000000000000000000000AF
+:10114000000000000000000000000000000000009F
+:10115000000000000000000000000000000000008F
+:10116000000000000000000000000000000000007F
+:10117000000000000000000000000000000000006F
+:10118000000000000000000000000000000000005F
+:10119000000000000000000000000000000000004F
+:1011A000000000000000000000000000000000003F
+:1011B000000000000000000000000000000000002F
+:1011C000000000000000000000000000000000001F
+:1011D000000000000000000000000000000000000F
+:1011E00000000000000000000000000000000000FF
+:1011F00000000000000000000000000000000000EF
+:1012000000000000000000000000000000000000DE
+:1012100000000000000000000000000000000000CE
+:1012200000000000000000000000000000000000BE
+:1012300000000000000000000000000000000000AE
+:10124000000000000000000000000000000000009E
+:10125000000000000000000000000000000000008E
+:10126000000000000000000000000000000000007E
+:10127000000000000000000000000000000000006E
+:10128000000000000000000000000000000000005E
+:10129000000000000000000000000000000000004E
+:1012A000000000000000000000000000000000003E
+:1012B000000000000000000000000000000000002E
+:1012C000000000000000000000000000000000001E
+:1012D000000000000000000000000000000000000E
+:1012E00000000000000000000000000000000000FE
+:1012F00000000000000000000000000000000000EE
+:1013000000000000000000000000000000000000DD
+:1013100000000000000000000000000000000000CD
+:1013200000000000000000000000000000000000BD
+:1013300000000000000000000000000000000000AD
+:10134000000000000000000000000000000000009D
+:10135000000000000000000000000000000000008D
+:10136000000000000000000000000000000000007D
+:10137000000000000000000000000000000000006D
+:10138000000000000000000000000000000000005D
+:10139000000000000000000000000000000000004D
+:1013A000000000000000000000000000000000003D
+:1013B000000000000000000000000000000000002D
+:1013C000000000000000000000000000000000001D
+:1013D000000000000000000000000000000000000D
+:1013E00000000000000000000000000000000000FD
+:1013F00000000000000000000000000000000000ED
+:101400000001033300100006001700080021000A45
+:101410000027002A002800250029002B002A002888
+:10142000002B002B002D003A002E0041002F004C15
+:101430000034004E00360032003900B1003A00D1CD
+:10144000003B00E6003C00FE003D016D003F00AFA8
+:10145000004103380043034B00440190004500FE67
+:10146000004601AE004701AE004802000049020EEE
+:10147000004A0257004B028400520261005302737B
+:10148000005402890057029B0060029F006102AE77
+:10149000006202B8006302C2006402CC006502D69A
+:1014A000006602E0006702EA006802F4006902F8E0
+:1014B000006A02FC006B0300006C0304006D03086B
+:1014C000006E030C006F03100070031400720365BC
+:1014D0000074036B00790369007C031E000F037A1C
+:1014E000000F037A000F037A000F037A000F037ACC
+:1014F000000F037A000F037A000F037A000F037ABC
+:10150000000F037A000F037A000F037A000F037AAB
+:10151000000F037A000F037A000F037A000F037A9B
+:10152000000F037A000F037A000F037A000F037A8B
+:10153000000F037A000F037A000F037A000F037A7B
+:00000001FF
diff --git a/firmware/radeon/RV710_pfp.bin.ihex b/firmware/radeon/RV710_pfp.bin.ihex
new file mode 100644
index 0000000..3d811ff
--- /dev/null
+++ b/firmware/radeon/RV710_pfp.bin.ihex
@@ -0,0 +1,213 @@
+:100000007C408000A00000007E82800B8000000009
+:10001000DC030000CC800040D04000407C408000E9
+:10002000A00000007E82800BC818000E31980001ED
+:100030007C4240009580023A7C428000C81C001C33
+:10004000C037C0007C40C0007C4100007CB4800B05
+:10005000C036000399C00000C81C001C7CB4800C92
+:1000600024D400027D654000CD400043CE80004393
+:10007000CD000043CC800040CE400040CE80004008
+:10008000CCC00040DC3A00009780FFDECD0000408D
+:100090007C40C000800000187C410000D400034078
+:1000A000D4000FC0D4000FA2C818000E8000000CAE
+:1000B00031980002D40003C0D4000FC0D4000FA2B6
+:1000C000C818000E288C000830CC000F3410000136
+:1000D0007D0D00088000000C7D91800BCC800040DD
+:1000E000D04000407C408000A00000007E82800B59
+:1000F000D4000340D4000FC0D4000FA2CC80004035
+:10010000D04000407C408000A00000007E82800B38
+:10011000D40003C0D4000FC0D4000FA2CC80004094
+:10012000D04000407C408000A00000007E82800B18
+:10013000CC4003F980000249CC4003F8C037FFFFF0
+:100140007C414000CF41A29EC82003F8C81C03F99F
+:1001500066200020C81803FB7DE1C02C7D58C00834
+:100160007CDCC02069100020C0360003CC000054A5
+:100170007CB4800C80000069CC8000407C41800011
+:10018000CD81A29ECC80004080000067CD800040E1
+:10019000C019FFFFCC800040CD81A29E7C40C000F2
+:1001A0007C4100007C414000CCC1A1FACD01A1F905
+:1001B000CD41A29DCCC00040CD000040CD400040CC
+:1001C000CC4000407C408000A00000007E82800B7C
+:1001D000CC000054CC8000407C40C0007C4100003A
+:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35
+:1001F000CCC00040CD000040CD400040D040004089
+:100200007C408000A00000007E82800B7C40C0000B
+:1002100030D00001CCC1A29F95000003041400015E
+:1002200004140002CD4003FBCC800040800000009D
+:10023000CCC000407C40C000CC800040CCC1A2A219
+:1002400080000000CCC000407C40C00028D4001FCB
+:10025000CC800040954000037C410000CCC000579A
+:100260002918001FCCC0004095800003CD0000403D
+:10027000CD00005880000249CC00007FC820001744
+:10028000C83000229A0000060E280001C824001E73
+:100290000A640001D4001240CE400040C036C000C5
+:1002A0009680000737747900041C0001CF4000409D
+:1002B000CDC00040CF0003FA7C030000CA0C001040
+:1002C0007C41000094C000047C414000D42002C462
+:1002D000CDE000449B00000B7C418000CC00004B33
+:1002E000CDA00049CD200041CD600041CDA000410E
+:1002F00006200001CE00005680000249CC00007F9D
+:10030000C8280020C82C0021CC0000637EEA4001F0
+:10031000657400207F53402C269C00027DF5C02090
+:1003200069F80020CE80004BCE600049CDE000414E
+:10033000CFA00041CE600041271C00027DF5C02007
+:1003400069F800207DB24001CF00004BCE6000492B
+:10035000CDE00041CFA00041800000BCCE60004154
+:10036000C8200017C83000229A0000060E2800019D
+:10037000C824001E0A640001D4001240CE40004090
+:10038000CA0C00107C41000094C0000BC036C000B5
+:100390009680000737747900041C0001CF400040AC
+:1003A000CDC00040CF0003FA7C030000800000B500
+:1003B0007C414000CC000048800000EE00000000BE
+:1003C000C8200017C81C00230E24000299C0001585
+:1003D0007C4180000A200001CE000056D400044079
+:1003E000CC000040C036C000CA140013964000077D
+:1003F00037747900CF400040CC000040C83003FA89
+:1004000080000103CF000022CC000022954001466D
+:10041000CC00007FCCA0004680000000CC2000462D
+:1004200080000249CC000064C8200017C810001FDB
+:100430009600000509100001D4000440CD000040E2
+:10044000CD000022CC800040D0400040C80C0025E8
+:1004500094C0FEECC8100008CD000040D4000FC0CE
+:1004600080000000D4000FA27C40C0007C4100004E
+:10047000CCC003FDCD0003FCCCC00042CD00004247
+:100480002914001F29180010319800073B5C000157
+:100490007D76000B998000057D5E400BCC0000420C
+:1004A00080000249CC00004D29980001292C000849
+:1004B0009980003D32EC0001960000042930000CC8
+:1004C00080000249CC00004204140010CD400042DC
+:1004D00033300001342800018400015DC81400039A
+:1004E0009B40001B0438000C8400015DC81400030D
+:1004F0009B400017043800088400015DC814000305
+:100500009B400013043800048400015DC8140003FC
+:100510009B400015C80C03FD9A800009C81003FC1D
+:100520009B000101CC00004D04140010CCC000421F
+:10053000CD00004280000135CD40004296C000FA57
+:10054000CC00004D80000249CC00004E9AC0000350
+:10055000CC00004DCC00004EDF8300008000000086
+:10056000D80301FF9AC000F0CC00004D8000024982
+:10057000CC00004EC8180003C81C0003C8200003AC
+:100580007D5D40037DA1C0037D5D400C2A10001FEE
+:10059000299C001F7D1D000B7D17400B880000006B
+:1005A0007E92800B96400004CC00004E80000249F1
+:1005B000CC00004204380008CF800042C808000385
+:1005C000C80C0003C8100003C8140003C8180003B7
+:1005D000C81C0003C8240003C828000329FC001F0E
+:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61
+:1005F0002970001F7FF3C00B7D8880017DCCC00176
+:100600007E5100017E9540017C9080027CD4C00226
+:100610007CBC800B9AC000037C8F400B38B4000177
+:100620009B4000C1CC00004D9BC000BFCC00004EE1
+:10063000C80C03FDC81003FCCCC000428000016E52
+:10064000CD000042D4000340D4000FC0D4000FA25C
+:10065000CC800040CC400040CC400040CC4000402A
+:100660007C40C000CCC00040CCC0000D8000000029
+:10067000D04000407C40C0007C4100006514002058
+:100680007D4D402C245800027D5980207C41C000C3
+:10069000CD80004269980020CD800042CDC000424C
+:1006A000C023C00005E400027CA0800B266400107B
+:1006B0007CA4800CCC800040CDC00040CCC0004069
+:1006C00095C0000ECD00004009DC0001C8280003E1
+:1006D00096800008CE800040C834001D974000007E
+:1006E000C834001D26A800088400024CCC2B000052
+:1006F00099C0FFF709DC0001DC3A00009780000494
+:100700007C418000800001A225980002A00000002A
+:100710007D808000C818001D7C40C00064D00008A7
+:1007200095800000C818001DCC130000CC8000404C
+:10073000CCC0004080000000CC400040C810001F2A
+:100740007C40C000CC8000407CD1400CCD400040BB
+:100750000518000180000000CD8000227C40C00010
+:10076000645000208400024CCC0000617CD0C02C7E
+:10077000C8200017C8D60000994000087C438000BC
+:10078000DF830000CFA0004F8400024CCC00006249
+:1007900080000000D040007F80000249CC00006251
+:1007A0008400024CCC000061C82000177C40C000CF
+:1007B000C036FF00C810000DC0303FFF7CF5400B75
+:1007C0007D51800B7D81800F998000087CF3800B28
+:1007D000DF830000CFA0004F8400024CCC000062F9
+:1007E00080000000D040007F80000249CC00006201
+:1007F0008400024C7C40C00028DC000895C0001931
+:1008000030DC00107C41000099C0000464540020DA
+:1008100080000208C91D00007D15002CC91E0000C3
+:100820007C4200007C4240007C4180007DE5C00BA2
+:100830007DE280079A80000E41AC00059AC000005E
+:100840000AEC000130DC001099C000040000000038
+:100850008000020BC91D00008000020BC91E0000B1
+:10086000CC800040CCC00040D0400040C80C0025E7
+:1008700094C0FDE4C8100008CD000040D4000FC0B3
+:1008800080000000D4000FA2D4000340D4000FC0A9
+:10089000D4000FA2CC800040D04000407C408000BB
+:1008A000A00000007E82800BD40003C0D4000FC0E3
+:1008B000D4000FA2CC800040D04000407C4080009B
+:1008C000A00000007E82800B7C40C00030D000067B
+:1008D0000D10000699000007C81400159940000586
+:1008E000CC000052D4000340D4000FC0D4000FA2AB
+:1008F000CC800040CCC0004080000000D0400040D0
+:100900007C40C000CC4D0000DC3A00009780FDBD6B
+:1009100004CC000180000242CC4D000080000000A9
+:10092000D040007FCC00007F80000000CC00007F22
+:10093000CC00007F88000000CC00007F0000000099
+:1009400000000000000000000000000000000000A7
+:100950000000000000000000000000000000000097
+:100960000000000000000000000000000000000087
+:100970000000000000000000000000000000000077
+:100980000000000000000000000000000000000067
+:100990000000000000000000000000000000000057
+:1009A0000000000000000000000000000000000047
+:1009B0000000000000000000000000000000000037
+:1009C0000000000000000000000000000000000027
+:1009D0000000000000000000000000000000000017
+:1009E0000000000000000000000000000000000007
+:1009F00000000000000000000000000000000000F7
+:100A000000000000000000000000000000000000E6
+:100A100000000000000000000000000000000000D6
+:100A200000000000000000000000000000000000C6
+:100A300000000000000000000000000000000000B6
+:100A400000000000000000000000000000000000A6
+:100A50000000000000000000000000000000000096
+:100A60000000000000000000000000000000000086
+:100A70000000000000000000000000000000000076
+:100A80000000000000000000000000000000000066
+:100A90000000000000000000000000000000000056
+:100AA0000000000000000000000000000000000046
+:100AB0000000000000000000000000000000000036
+:100AC0000000000000000000000000000000000026
+:100AD0000000000000000000000000000000000016
+:100AE0000000000000000000000000000000000006
+:100AF00000000000000000000000000000000000F6
+:100B000000000000000000000000000000000000E5
+:100B100000000000000000000000000000000000D5
+:100B200000000000000000000000000000000000C5
+:100B300000000000000000000000000000000000B5
+:100B400000000000000000000000000000000000A5
+:100B50000000000000000000000000000000000095
+:100B60000000000000000000000000000000000085
+:100B70000000000000000000000000000000000075
+:100B80000000000000000000000000000000000065
+:100B90000000000000000000000000000000000055
+:100BA0000000000000000000000000000000000045
+:100BB0000000000000000000000000000000000035
+:100BC0000000000000000000000000000000000025
+:100BD0000000000000000000000000000000000015
+:100BE0000000000000000000000000000000000005
+:100BF00000000000000000000000000000000000F5
+:100C0000000302220004022A0005009F00020003E4
+:100C10000006003C0007002700080191000900447D
+:100C2000000A002D00100247001700F0002201D733
+:100C3000002301E80026004C0027005F0020011A75
+:100C4000002800920029004F002A0083002B006436
+:100C5000002F008D003200D80034023200360074BC
+:100C60000039010A003C01FC003F009F00410005E3
+:100C7000004401940048019D004901C5004A01CF8C
+:100C8000005502250056022D0060000A0061002A6E
+:100C90000062003000630030006400300065003006
+:100CA0000066003000670030006800370069003FD0
+:100CB000006A0047006B0047006C0047006D00476A
+:100CC000006E0047006F0047007000470073024746
+:100CD000007B024000000005000000050000000548
+:100CE00000000005000000050000000500000005F0
+:100CF00000000005000000050000000500000005E0
+:100D000000000005000000050000000500000005CF
+:100D100000000005000000050000000500000005BF
+:100D200000000005000000050000000500000005AF
+:100D3000000000050000000500000005000000059F
+:00000001FF
diff --git a/firmware/radeon/RV730_me.bin.ihex b/firmware/radeon/RV730_me.bin.ihex
new file mode 100644
index 0000000..390c18e
--- /dev/null
+++ b/firmware/radeon/RV730_me.bin.ihex
@@ -0,0 +1,341 @@
+:10000000CC0003EA7C408000A0000000CC800062AD
+:1000100080000001D040007F80000001CC40004102
+:100020007C40C000C016000430D03FFF7D15000C9E
+:10003000CC11000028D8001E3198000128DC001FD8
+:10004000C820000495C000067C424000CC0000623D
+:100050007E56800CCC290000C82400047E26000BAC
+:10006000958000067C42C000CC0000627ED7000C68
+:10007000CC310000C82C00047E2E000CCC000062A5
+:1000800031103FFF80000001CE1100007C40C00015
+:1000900080000001CC40004080000001CC4122578C
+:1000A0007C418000CC400045CC400048CC41225CE3
+:1000B000CC41A1FC7C408000A0000000CC8000620C
+:1000C000CC400045CC4000487C40C000CC41225C84
+:1000D000CC41A1FC7C408000A0000000CC800062EC
+:1000E000CC000045CC000048CC41225CCC41A1FCB6
+:1000F0007C408000A0000000CC800062040CA1FDC8
+:10010000C0120001CC000045CC0000487CD0C00CDF
+:10011000CC41225CCC41A1FCD04D00007C40800051
+:10012000A0000000CC80006280000001CC41225D74
+:100130007C4080007C40C000C02A00027C4100005E
+:100140007D29000C3094000130980006309C03009B
+:1001500029DC00087C4200007C4240009540000FF2
+:10016000C02E000405F022587F2F000CCC31000077
+:10017000C8280004CCC12169CD01216ACE81216B40
+:100180000DB40002CC01216C9740000E0DB40000AC
+:100190008000007BC834000A0DB4000297400009BB
+:1001A0000DB40000C02E000405F022587F2F000C73
+:1001B000CC310000C82800048000007BC834000A4D
+:1001C000974000047E0280008000007BC834000A53
+:1001D0000DB400049740FF8C00000000CE01216D9B
+:1001E000CE41216EC8280003C834000A9B40000499
+:1001F000043C00058400026BCC0000620DF400009A
+:100200009740000BC82C03E6CE81A2B7C030000691
+:100210007EF34028C03000207F6B80207FB3C02950
+:10022000CF81A2C480000001CFC1A2D10DF4000192
+:100230009740000BC82C03E7CE81A2BBC03000065C
+:100240007EF34028C03000207F6B80207FB3C02920
+:10025000CF81A2C580000001CFC1A2D20DF400025F
+:100260009740000BC82C03E8CE81A2BFC030000627
+:100270007EF34028C03000207F6B80207FB3C029F0
+:10028000CF81A2C680000001CFC1A2D3C82C03E950
+:10029000CE81A2C3C03000067EF34028C0300020CB
+:1002A0007F6B80207FB3C029CF81A2C7800000016F
+:1002B000CFC1A2D480000001CC4000427C40C000ED
+:1002C0007C4100002914001D315400019940000CAC
+:1002D00031181000C81C001195C00000C81C001186
+:1002E000CCC12100CD012101CCC12102CD012103CE
+:1002F000041800048000037CCD81A2A4C02A00045D
+:100300009580000836A821A3CC290000C828000445
+:10031000C81C00110DE400409640FFFFC81C0011EE
+:10032000CCC12170CD012171C820001296000000BF
+:10033000C82000128000037CCC0000647C40C00018
+:100340007C410000CC000045CC00004840D40003B4
+:10035000CD41225CCD01A1FCC01A0001041CA1FD0D
+:100360007DD9C00C7C42000008CC000106240001AD
+:1003700006280002CE1D0000CE5D000098C0FFFAE6
+:10038000CE9D00007C408000A0000000CC80006278
+:100390007C40C00030D0000128CC00017C414000EE
+:1003A000950000067C418000CD41216DCD81216EFC
+:1003B000800000F2C81C0003C02200047E16000C5E
+:1003C000CC210000C81C00047C42400098C00004FE
+:1003D0007C42800080000001CDE50000CE41216913
+:1003E000CE81216ACDC1216B80000001CC01216C3E
+:1003F0007C40C0007C4100007C4140007C4180008A
+:100400007C41C00028A40008326400FF0E68003C54
+:100410009680000A7C0200007C4200001E3000032F
+:10042000CC00006A9B00000342200005042000402D
+:100430008000010F7C0240007E0240009A400000D4
+:100440000A64000130EC00109AC0000ACC0000627F
+:10045000C02A0004C82C00217E92800CCC000041F0
+:10046000CC290000CEC000218000011FC83000044C
+:10047000CD01216DCD41216EC83000037F1F000BDF
+:1004800030F40007277800019740002A07B80124BC
+:100490009F80000000000000800001347F1B80046A
+:1004A000800001387F1B80058000013C7F1B80029B
+:1004B000800001407F1B8003800001447F1B800778
+:1004C000800001487F1B80068000014D28A40008A1
+:1004D0009B80001928A400088000015D326400FFA1
+:1004E0009B80001528A400088000015D326400FF95
+:1004F0009B80001128A400088000015D326400FF89
+:100500009B80000D28A400088000015D326400FF7C
+:100510009B80000928A400088000015D326400FF70
+:100520009B80000528A400088000015D326400FF64
+:1005300028A40008326400FF0E68003C9A80FEB2D6
+:1005400028EC00087C4340007C4380007C43C000D2
+:1005500096C00007CC000062CF412169CF81216A9B
+:10056000CFC1216B80000001CC01216C8000000113
+:10057000CFF50000CC00006B8400037F0E68003CC8
+:100580009A800004C828001580000001D040007F38
+:100590009680FFAB7E02400084000239C00E00024C
+:1005A000CC00004180000237CCC1304A7C40C00002
+:1005B0007C410000C01E000129240012C02200025C
+:1005C00096400005C0260004C027FFFB7D25000BD8
+:1005D000C02600007DD2800B7E12C00B7D25000C52
+:1005E0007C4140007C418000CCC121699A80000A96
+:1005F000CD01216ACD41216B96C0FE83CD81216C56
+:10060000C830001897000000C830001880000001B2
+:10061000CC0000188400037FCC00007FC8140013B6
+:10062000C8180014CD41216B96C0FE77CD81216C96
+:1006300080000181C8300018C80C000898C0000074
+:10064000C80C00087C41000095000002000000007A
+:100650007C414000C8200009CC400043CE01A1F4F9
+:10066000CC400044C00E80007C4240007C428000B0
+:100670002AAC001F96C0FE64C035F000CE4003E2F5
+:1006800032780003267C00087FF7C00B7FFBC00C8C
+:100690002A780018CFC003E3CF8003E426B000021D
+:1006A0007F3F0000CF0003E58000031D7C80C00079
+:1006B0007C40C00028D000083110000F9500000FCA
+:1006C0002528000106A801B29E800000000000005D
+:1006D000800001D3C0120800800001E1C814000F9F
+:1006E000800001E8C8140010800001EFCCC1A2A472
+:1006F000800001F8C814001130D0003F0D2800150B
+:100700009A8000120D28001E9A80001E0D280020DD
+:100710009A8000230D24000F0D2800107E6A800CA3
+:100720009A8000260D2000040D2400140D280028B6
+:100730007E62400C7EA6800C9A80002AC8140011AC
+:1007400080000001CCC1A2A4C01208007C4140007E
+:100750007D0CC00CC012000829580003295C000C55
+:100760007C4200007DD1C00B262000147E1E400C70
+:100770007E4E800CCE81A2A480000001CD81A1FE1E
+:10078000C814000F0410210E95400000C814000F7B
+:10079000D051000080000001CCC1A2A4C8140010F8
+:1007A0000410210895400000C8140010D05100002A
+:1007B00080000001CCC1A2A4CCC1A2A404100001FD
+:1007C000CD0000198400037FCC00007FC810001901
+:1007D00099000000C8100019800000027C408000D1
+:1007E0000410210095400000C8140011D0510000F1
+:1007F0008000037CCCC1A2A47C40C000CC40000D92
+:1008000094C0FE01CC40000E7C4100009500000524
+:1008100008CC0001C8140005994000140000000035
+:1008200098C0FFFB7C410000800000027D0080003A
+:10083000C81400057C40C0009940000CC818000C8A
+:100840007C4100009580FDF0C820000EC81C000D02
+:10085000662000207E1E002C252400027E6240209F
+:1008600080000001CCE600007C410000CC00006C60
+:10087000CC00006DC818001FC81C001E6598002021
+:100880007DD9C02C7CD4C00CCCDE000045DC00043B
+:10089000C82800179680000FC00E000128680008C5
+:1008A0002AAC001632A800FF0EB000497F2F000BC3
+:1008B0009700000600000000C81400057C40C0003E
+:1008C000800002217C41000080000224D040007F93
+:1008D00084000239CC000041CCC1304A94000000B1
+:1008E000C83C001A043C0005CFC1A2A4C0361F902A
+:1008F000C0387FFF7C03C0107F7B400CCF41217C40
+:10090000CFC1217DCC01217EC03A00040434217F77
+:100910007F7B400CCC350000C83C00042BFC001F42
+:100920000438002097C00005CC0000629B800000C6
+:100930000BB8000180000245CC000071CC01A1F48D
+:1009400004380016C0360002CF81A2A4880000003F
+:10095000CF4120107C40C00028D0001C950000052D
+:1009600004D40001CD40006580000001CD40006846
+:100970000954000280000001CD4000668400026A34
+:10098000C81803EA7C40C0009980FD9FC814001677
+:1009900008D000019940002BCD0000687C40800009
+:1009A000A0000000CC800062043C0005CFC1A2A4DE
+:1009B000CC01A1F48400037FCC0000468800000035
+:1009C000CC00007F8400027CC81803EA7C40C00091
+:1009D0009980FD8DC814001608D0000199400019B7
+:1009E000CD0000687C408000A0000000CC80006248
+:1009F000043C0022CFC1A2A48400037FCC000047A6
+:100A000088000000CC00007FC81000169900000D7F
+:100A1000CC400067800000027C408000C81803EAD8
+:100A20009980FD797C40C00094C00003C810001676
+:100A300099000004CCC00068800000027C40800067
+:100A400084000239C0148000CC000041CD41304AFE
+:100A5000C014800099000000C81000168000000239
+:100A60007C408000C01200017C51400C80000001DD
+:100A7000D05500007C40C0007C4100007C4140001B
+:100A80007C418000291C001FCCC0004ACD00004BD7
+:100A900095C00003C01C8000CDC12010DD83000084
+:100AA000055C2000CC00006280000001D81F4100DE
+:100AB0007C40C0007C4100007C4140007C418000C3
+:100AC000CCC0004CCD00004DDD830000055CA000D3
+:100AD00080000001D81F41007C40C0007C41000024
+:100AE0007C4140007C418000CCC0004ECD00004FD6
+:100AF000DD830000055CC00080000001D81F4100BC
+:100B00007C40C0007C4100007C4140007C41800072
+:100B1000CCC00050CD000051DD830000055CF8E042
+:100B200080000001D81F41007C40C0007C410000D3
+:100B30007C4140007C418000CCC00052CD0000537D
+:100B4000DD830000055CF88080000001D81F4100B3
+:100B50007C40C0007C4100007C4140007C41800022
+:100B6000CCC00054CD000055DD830000055CE000E2
+:100B700080000001D81F41007C40C0007C41000083
+:100B80007C4140007C418000CCC00056CD00005725
+:100B9000DD830000055CF00080000001D81F4100EB
+:100BA0007C40C0007C4100007C4140007C418000D2
+:100BB000CCC00058CD000059DD830000055CF3FC7B
+:100BC00080000001D81F4100D04320007C408000FD
+:100BD000A0000000CC800062D043A0007C408000D8
+:100BE000A0000000CC800062D043C0007C408000A8
+:100BF000A0000000CC800062D043F8E07C40800080
+:100C0000A0000000CC800062D043F8807C408000CF
+:100C1000A0000000CC800062D043E0007C40800057
+:100C2000A0000000CC800062D043F0007C40800037
+:100C3000A0000000CC800062D043F3FC7C40800028
+:100C4000A0000000CC800062C81403E0CC43000088
+:100C5000CC430000CC4300007D45C000CDC3000064
+:100C6000D04300007C408000A0000000CC800062E7
+:100C70007C40C000C81003E2C81403E5C81803E3B1
+:100C8000C81C03E4CD812169CDC1216ACCC1216B8F
+:100C9000CC01216C042000047DA180007D964002DF
+:100CA0009640FCD9CD8003E331280003C02DF0002D
+:100CB000251800087DAD800B7DA9800C8000000107
+:100CC000CD8003E3308CFFFFD04D00007C408000DE
+:100CD000A0000000CC800062C8140020155800025B
+:100CE0009580FFFFC8140020CC00006ECC4121800D
+:100CF0007C40C000CCC1218DCC41218128D0001F77
+:100D000034588000CD81218C9500FCBFCC412182DC
+:100D1000C81400209940FFFFC81400208000000282
+:100D20007C4080007C40C00028D0001831100001B9
+:100D3000C016008095000003C02A00047CD4C00CBB
+:100D4000CCC1217CCC41217DCC41217E7C418000E5
+:100D50001DB0000336A0217F9B000003419C0005CD
+:100D6000041C004099C0000009DC0001CC210000F7
+:100D7000C82400042A6C001F419C00059AC0FFFA99
+:100D8000CC800062800000027C4080007C40C0007B
+:100D900004D403E680000001CC5400008000037CF2
+:100DA000CC4003EAC01C8000044CA000CDC1201040
+:100DB0007C410000C814000904180000041C00084D
+:100DC000CD80007109DC000105980001CD0D000007
+:100DD00099C0FFFCCC8000628000037CCD40007194
+:100DE000C00E0100CC000041CCC1304AC83C007F9D
+:100DF000CC00007F80000001CC00007FCC00007F91
+:100E000088000000CC00007F00000000000000000F
+:100E100000000000000000000000000000000000D2
+:100E200000000000000000000000000000000000C2
+:100E300000000000000000000000000000000000B2
+:100E400000000000000000000000000000000000A2
+:100E50000000000000000000000000000000000092
+:100E60000000000000000000000000000000000082
+:100E70000000000000000000000000000000000072
+:100E80000000000000000000000000000000000062
+:100E90000000000000000000000000000000000052
+:100EA0000000000000000000000000000000000042
+:100EB0000000000000000000000000000000000032
+:100EC0000000000000000000000000000000000022
+:100ED0000000000000000000000000000000000012
+:100EE0000000000000000000000000000000000002
+:100EF00000000000000000000000000000000000F2
+:100F000000000000000000000000000000000000E1
+:100F100000000000000000000000000000000000D1
+:100F200000000000000000000000000000000000C1
+:100F300000000000000000000000000000000000B1
+:100F400000000000000000000000000000000000A1
+:100F50000000000000000000000000000000000091
+:100F60000000000000000000000000000000000081
+:100F70000000000000000000000000000000000071
+:100F80000000000000000000000000000000000061
+:100F90000000000000000000000000000000000051
+:100FA0000000000000000000000000000000000041
+:100FB0000000000000000000000000000000000031
+:100FC0000000000000000000000000000000000021
+:100FD0000000000000000000000000000000000011
+:100FE0000000000000000000000000000000000001
+:100FF00000000000000000000000000000000000F1
+:1010000000000000000000000000000000000000E0
+:1010100000000000000000000000000000000000D0
+:1010200000000000000000000000000000000000C0
+:1010300000000000000000000000000000000000B0
+:1010400000000000000000000000000000000000A0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:101070000000000000000000000000000000000070
+:101080000000000000000000000000000000000060
+:101090000000000000000000000000000000000050
+:1010A0000000000000000000000000000000000040
+:1010B0000000000000000000000000000000000030
+:1010C0000000000000000000000000000000000020
+:1010D0000000000000000000000000000000000010
+:1010E0000000000000000000000000000000000000
+:1010F00000000000000000000000000000000000F0
+:1011000000000000000000000000000000000000DF
+:1011100000000000000000000000000000000000CF
+:1011200000000000000000000000000000000000BF
+:1011300000000000000000000000000000000000AF
+:10114000000000000000000000000000000000009F
+:10115000000000000000000000000000000000008F
+:10116000000000000000000000000000000000007F
+:10117000000000000000000000000000000000006F
+:10118000000000000000000000000000000000005F
+:10119000000000000000000000000000000000004F
+:1011A000000000000000000000000000000000003F
+:1011B000000000000000000000000000000000002F
+:1011C000000000000000000000000000000000001F
+:1011D000000000000000000000000000000000000F
+:1011E00000000000000000000000000000000000FF
+:1011F00000000000000000000000000000000000EF
+:1012000000000000000000000000000000000000DE
+:1012100000000000000000000000000000000000CE
+:1012200000000000000000000000000000000000BE
+:1012300000000000000000000000000000000000AE
+:10124000000000000000000000000000000000009E
+:10125000000000000000000000000000000000008E
+:10126000000000000000000000000000000000007E
+:10127000000000000000000000000000000000006E
+:10128000000000000000000000000000000000005E
+:10129000000000000000000000000000000000004E
+:1012A000000000000000000000000000000000003E
+:1012B000000000000000000000000000000000002E
+:1012C000000000000000000000000000000000001E
+:1012D000000000000000000000000000000000000E
+:1012E00000000000000000000000000000000000FE
+:1012F00000000000000000000000000000000000EE
+:1013000000000000000000000000000000000000DD
+:1013100000000000000000000000000000000000CD
+:1013200000000000000000000000000000000000BD
+:1013300000000000000000000000000000000000AD
+:10134000000000000000000000000000000000009D
+:10135000000000000000000000000000000000008D
+:10136000000000000000000000000000000000007D
+:10137000000000000000000000000000000000006D
+:10138000000000000000000000000000000000005D
+:10139000000000000000000000000000000000004D
+:1013A000000000000000000000000000000000003D
+:1013B000000000000000000000000000000000002D
+:1013C000000000000000000000000000000000001D
+:1013D000000000000000000000000000000000000D
+:1013E00000000000000000000000000000000000FD
+:1013F00000000000000000000000000000000000ED
+:10140000000103310010000400170006002100084D
+:10141000002700280028002300290029002A002690
+:10142000002B0029002D0038002E003F002F004A1D
+:101430000034004C00360030003900AF003A00CFD5
+:10144000003B00E4003C00FC003D016B003F00ADB0
+:1014500000410336004303490044018E004500FC6F
+:10146000004601AC004701AC004801FE0049020CF7
+:10147000004A0255004B02820052025F0053027183
+:1014800000540287005702990060029D006102AC7F
+:10149000006202B6006302C0006402CA006502D4A2
+:1014A000006602DE006702E8006802F2006902F6E8
+:1014B000006A02FA006B02FE006C0302006D030674
+:1014C000006E030A006F030E0070031200720363C4
+:1014D0000074036900790367007C031C000F037824
+:1014E000000F0378000F0378000F0378000F0378D4
+:1014F000000F0378000F0378000F0378000F0378C4
+:10150000000F0378000F0378000F0378000F0378B3
+:10151000000F0378000F0378000F0378000F0378A3
+:10152000000F0378000F0378000F0378000F037893
+:10153000000F0378000F0378000F0378000F037883
+:00000001FF
diff --git a/firmware/radeon/RV730_pfp.bin.ihex b/firmware/radeon/RV730_pfp.bin.ihex
new file mode 100644
index 0000000..3d811ff
--- /dev/null
+++ b/firmware/radeon/RV730_pfp.bin.ihex
@@ -0,0 +1,213 @@
+:100000007C408000A00000007E82800B8000000009
+:10001000DC030000CC800040D04000407C408000E9
+:10002000A00000007E82800BC818000E31980001ED
+:100030007C4240009580023A7C428000C81C001C33
+:10004000C037C0007C40C0007C4100007CB4800B05
+:10005000C036000399C00000C81C001C7CB4800C92
+:1000600024D400027D654000CD400043CE80004393
+:10007000CD000043CC800040CE400040CE80004008
+:10008000CCC00040DC3A00009780FFDECD0000408D
+:100090007C40C000800000187C410000D400034078
+:1000A000D4000FC0D4000FA2C818000E8000000CAE
+:1000B00031980002D40003C0D4000FC0D4000FA2B6
+:1000C000C818000E288C000830CC000F3410000136
+:1000D0007D0D00088000000C7D91800BCC800040DD
+:1000E000D04000407C408000A00000007E82800B59
+:1000F000D4000340D4000FC0D4000FA2CC80004035
+:10010000D04000407C408000A00000007E82800B38
+:10011000D40003C0D4000FC0D4000FA2CC80004094
+:10012000D04000407C408000A00000007E82800B18
+:10013000CC4003F980000249CC4003F8C037FFFFF0
+:100140007C414000CF41A29EC82003F8C81C03F99F
+:1001500066200020C81803FB7DE1C02C7D58C00834
+:100160007CDCC02069100020C0360003CC000054A5
+:100170007CB4800C80000069CC8000407C41800011
+:10018000CD81A29ECC80004080000067CD800040E1
+:10019000C019FFFFCC800040CD81A29E7C40C000F2
+:1001A0007C4100007C414000CCC1A1FACD01A1F905
+:1001B000CD41A29DCCC00040CD000040CD400040CC
+:1001C000CC4000407C408000A00000007E82800B7C
+:1001D000CC000054CC8000407C40C0007C4100003A
+:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35
+:1001F000CCC00040CD000040CD400040D040004089
+:100200007C408000A00000007E82800B7C40C0000B
+:1002100030D00001CCC1A29F95000003041400015E
+:1002200004140002CD4003FBCC800040800000009D
+:10023000CCC000407C40C000CC800040CCC1A2A219
+:1002400080000000CCC000407C40C00028D4001FCB
+:10025000CC800040954000037C410000CCC000579A
+:100260002918001FCCC0004095800003CD0000403D
+:10027000CD00005880000249CC00007FC820001744
+:10028000C83000229A0000060E280001C824001E73
+:100290000A640001D4001240CE400040C036C000C5
+:1002A0009680000737747900041C0001CF4000409D
+:1002B000CDC00040CF0003FA7C030000CA0C001040
+:1002C0007C41000094C000047C414000D42002C462
+:1002D000CDE000449B00000B7C418000CC00004B33
+:1002E000CDA00049CD200041CD600041CDA000410E
+:1002F00006200001CE00005680000249CC00007F9D
+:10030000C8280020C82C0021CC0000637EEA4001F0
+:10031000657400207F53402C269C00027DF5C02090
+:1003200069F80020CE80004BCE600049CDE000414E
+:10033000CFA00041CE600041271C00027DF5C02007
+:1003400069F800207DB24001CF00004BCE6000492B
+:10035000CDE00041CFA00041800000BCCE60004154
+:10036000C8200017C83000229A0000060E2800019D
+:10037000C824001E0A640001D4001240CE40004090
+:10038000CA0C00107C41000094C0000BC036C000B5
+:100390009680000737747900041C0001CF400040AC
+:1003A000CDC00040CF0003FA7C030000800000B500
+:1003B0007C414000CC000048800000EE00000000BE
+:1003C000C8200017C81C00230E24000299C0001585
+:1003D0007C4180000A200001CE000056D400044079
+:1003E000CC000040C036C000CA140013964000077D
+:1003F00037747900CF400040CC000040C83003FA89
+:1004000080000103CF000022CC000022954001466D
+:10041000CC00007FCCA0004680000000CC2000462D
+:1004200080000249CC000064C8200017C810001FDB
+:100430009600000509100001D4000440CD000040E2
+:10044000CD000022CC800040D0400040C80C0025E8
+:1004500094C0FEECC8100008CD000040D4000FC0CE
+:1004600080000000D4000FA27C40C0007C4100004E
+:10047000CCC003FDCD0003FCCCC00042CD00004247
+:100480002914001F29180010319800073B5C000157
+:100490007D76000B998000057D5E400BCC0000420C
+:1004A00080000249CC00004D29980001292C000849
+:1004B0009980003D32EC0001960000042930000CC8
+:1004C00080000249CC00004204140010CD400042DC
+:1004D00033300001342800018400015DC81400039A
+:1004E0009B40001B0438000C8400015DC81400030D
+:1004F0009B400017043800088400015DC814000305
+:100500009B400013043800048400015DC8140003FC
+:100510009B400015C80C03FD9A800009C81003FC1D
+:100520009B000101CC00004D04140010CCC000421F
+:10053000CD00004280000135CD40004296C000FA57
+:10054000CC00004D80000249CC00004E9AC0000350
+:10055000CC00004DCC00004EDF8300008000000086
+:10056000D80301FF9AC000F0CC00004D8000024982
+:10057000CC00004EC8180003C81C0003C8200003AC
+:100580007D5D40037DA1C0037D5D400C2A10001FEE
+:10059000299C001F7D1D000B7D17400B880000006B
+:1005A0007E92800B96400004CC00004E80000249F1
+:1005B000CC00004204380008CF800042C808000385
+:1005C000C80C0003C8100003C8140003C8180003B7
+:1005D000C81C0003C8240003C828000329FC001F0E
+:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61
+:1005F0002970001F7FF3C00B7D8880017DCCC00176
+:100600007E5100017E9540017C9080027CD4C00226
+:100610007CBC800B9AC000037C8F400B38B4000177
+:100620009B4000C1CC00004D9BC000BFCC00004EE1
+:10063000C80C03FDC81003FCCCC000428000016E52
+:10064000CD000042D4000340D4000FC0D4000FA25C
+:10065000CC800040CC400040CC400040CC4000402A
+:100660007C40C000CCC00040CCC0000D8000000029
+:10067000D04000407C40C0007C4100006514002058
+:100680007D4D402C245800027D5980207C41C000C3
+:10069000CD80004269980020CD800042CDC000424C
+:1006A000C023C00005E400027CA0800B266400107B
+:1006B0007CA4800CCC800040CDC00040CCC0004069
+:1006C00095C0000ECD00004009DC0001C8280003E1
+:1006D00096800008CE800040C834001D974000007E
+:1006E000C834001D26A800088400024CCC2B000052
+:1006F00099C0FFF709DC0001DC3A00009780000494
+:100700007C418000800001A225980002A00000002A
+:100710007D808000C818001D7C40C00064D00008A7
+:1007200095800000C818001DCC130000CC8000404C
+:10073000CCC0004080000000CC400040C810001F2A
+:100740007C40C000CC8000407CD1400CCD400040BB
+:100750000518000180000000CD8000227C40C00010
+:10076000645000208400024CCC0000617CD0C02C7E
+:10077000C8200017C8D60000994000087C438000BC
+:10078000DF830000CFA0004F8400024CCC00006249
+:1007900080000000D040007F80000249CC00006251
+:1007A0008400024CCC000061C82000177C40C000CF
+:1007B000C036FF00C810000DC0303FFF7CF5400B75
+:1007C0007D51800B7D81800F998000087CF3800B28
+:1007D000DF830000CFA0004F8400024CCC000062F9
+:1007E00080000000D040007F80000249CC00006201
+:1007F0008400024C7C40C00028DC000895C0001931
+:1008000030DC00107C41000099C0000464540020DA
+:1008100080000208C91D00007D15002CC91E0000C3
+:100820007C4200007C4240007C4180007DE5C00BA2
+:100830007DE280079A80000E41AC00059AC000005E
+:100840000AEC000130DC001099C000040000000038
+:100850008000020BC91D00008000020BC91E0000B1
+:10086000CC800040CCC00040D0400040C80C0025E7
+:1008700094C0FDE4C8100008CD000040D4000FC0B3
+:1008800080000000D4000FA2D4000340D4000FC0A9
+:10089000D4000FA2CC800040D04000407C408000BB
+:1008A000A00000007E82800BD40003C0D4000FC0E3
+:1008B000D4000FA2CC800040D04000407C4080009B
+:1008C000A00000007E82800B7C40C00030D000067B
+:1008D0000D10000699000007C81400159940000586
+:1008E000CC000052D4000340D4000FC0D4000FA2AB
+:1008F000CC800040CCC0004080000000D0400040D0
+:100900007C40C000CC4D0000DC3A00009780FDBD6B
+:1009100004CC000180000242CC4D000080000000A9
+:10092000D040007FCC00007F80000000CC00007F22
+:10093000CC00007F88000000CC00007F0000000099
+:1009400000000000000000000000000000000000A7
+:100950000000000000000000000000000000000097
+:100960000000000000000000000000000000000087
+:100970000000000000000000000000000000000077
+:100980000000000000000000000000000000000067
+:100990000000000000000000000000000000000057
+:1009A0000000000000000000000000000000000047
+:1009B0000000000000000000000000000000000037
+:1009C0000000000000000000000000000000000027
+:1009D0000000000000000000000000000000000017
+:1009E0000000000000000000000000000000000007
+:1009F00000000000000000000000000000000000F7
+:100A000000000000000000000000000000000000E6
+:100A100000000000000000000000000000000000D6
+:100A200000000000000000000000000000000000C6
+:100A300000000000000000000000000000000000B6
+:100A400000000000000000000000000000000000A6
+:100A50000000000000000000000000000000000096
+:100A60000000000000000000000000000000000086
+:100A70000000000000000000000000000000000076
+:100A80000000000000000000000000000000000066
+:100A90000000000000000000000000000000000056
+:100AA0000000000000000000000000000000000046
+:100AB0000000000000000000000000000000000036
+:100AC0000000000000000000000000000000000026
+:100AD0000000000000000000000000000000000016
+:100AE0000000000000000000000000000000000006
+:100AF00000000000000000000000000000000000F6
+:100B000000000000000000000000000000000000E5
+:100B100000000000000000000000000000000000D5
+:100B200000000000000000000000000000000000C5
+:100B300000000000000000000000000000000000B5
+:100B400000000000000000000000000000000000A5
+:100B50000000000000000000000000000000000095
+:100B60000000000000000000000000000000000085
+:100B70000000000000000000000000000000000075
+:100B80000000000000000000000000000000000065
+:100B90000000000000000000000000000000000055
+:100BA0000000000000000000000000000000000045
+:100BB0000000000000000000000000000000000035
+:100BC0000000000000000000000000000000000025
+:100BD0000000000000000000000000000000000015
+:100BE0000000000000000000000000000000000005
+:100BF00000000000000000000000000000000000F5
+:100C0000000302220004022A0005009F00020003E4
+:100C10000006003C0007002700080191000900447D
+:100C2000000A002D00100247001700F0002201D733
+:100C3000002301E80026004C0027005F0020011A75
+:100C4000002800920029004F002A0083002B006436
+:100C5000002F008D003200D80034023200360074BC
+:100C60000039010A003C01FC003F009F00410005E3
+:100C7000004401940048019D004901C5004A01CF8C
+:100C8000005502250056022D0060000A0061002A6E
+:100C90000062003000630030006400300065003006
+:100CA0000066003000670030006800370069003FD0
+:100CB000006A0047006B0047006C0047006D00476A
+:100CC000006E0047006F0047007000470073024746
+:100CD000007B024000000005000000050000000548
+:100CE00000000005000000050000000500000005F0
+:100CF00000000005000000050000000500000005E0
+:100D000000000005000000050000000500000005CF
+:100D100000000005000000050000000500000005BF
+:100D200000000005000000050000000500000005AF
+:100D3000000000050000000500000005000000059F
+:00000001FF
diff --git a/firmware/radeon/RV770_me.bin.ihex b/firmware/radeon/RV770_me.bin.ihex
new file mode 100644
index 0000000..a0e1699
--- /dev/null
+++ b/firmware/radeon/RV770_me.bin.ihex
@@ -0,0 +1,341 @@
+:10000000CC0003EA7C408000A0000000CC800062AD
+:1000100080000001D040007F80000001CC40004102
+:100020007C40C000C016000430D03FFF7D15000C9E
+:10003000CC11000028D8001E3198000128DC001FD8
+:10004000C820000495C000067C424000CC0000623D
+:100050007E56800CCC290000C82400047E26000BAC
+:10006000958000067C42C000CC0000627ED7000C68
+:10007000CC310000C82C00047E2E000CCC000062A5
+:1000800031103FFF80000001CE1100007C40C00015
+:1000900080000001CC40004080000001CC4122578C
+:1000A0007C418000CC400045CC400048CC41225CE3
+:1000B000CC41A1FC7C408000A0000000CC8000620C
+:1000C000CC400045CC4000487C40C000CC41225C84
+:1000D000CC41A1FC7C408000A0000000CC800062EC
+:1000E000CC000045CC000048CC41225CCC41A1FCB6
+:1000F0007C408000A0000000CC800062040CA1FDC8
+:10010000C0120001CC000045CC0000487CD0C00CDF
+:10011000CC41225CCC41A1FCD04D00007C40800051
+:10012000A0000000CC80006280000001CC41225D74
+:100130007C4080007C40C000C02A00027C4100005E
+:100140007D29000C3094000130980006309C03009B
+:1001500029DC00087C4200007C4240009540000FF2
+:10016000C02E000405F022587F2F000CCC31000077
+:10017000C8280004CCC12169CD01216ACE81216B40
+:100180000DB40002CC01216C9740000E0DB40000AC
+:100190008000007BC834000A0DB4000297400009BB
+:1001A0000DB40000C02E000405F022587F2F000C73
+:1001B000CC310000C82800048000007BC834000A4D
+:1001C000974000047E0280008000007BC834000A53
+:1001D0000DB400049740FF8C00000000CE01216D9B
+:1001E000CE41216EC8280003C834000A9B40000499
+:1001F000043C00058400026DCC0000620DF4000098
+:100200009740000BC82C03E6CE81A2B7C030000691
+:100210007EF34028C03000207F6B80207FB3C02950
+:10022000CF81A2C480000001CFC1A2D10DF4000192
+:100230009740000BC82C03E7CE81A2BBC03000065C
+:100240007EF34028C03000207F6B80207FB3C02920
+:10025000CF81A2C580000001CFC1A2D20DF400025F
+:100260009740000BC82C03E8CE81A2BFC030000627
+:100270007EF34028C03000207F6B80207FB3C029F0
+:10028000CF81A2C680000001CFC1A2D3C82C03E950
+:10029000CE81A2C3C03000067EF34028C0300020CB
+:1002A0007F6B80207FB3C029CF81A2C7800000016F
+:1002B000CFC1A2D480000001CC4000427C40C000ED
+:1002C0007C4100002914001D315400019940000DAB
+:1002D00031181000C81C001109DC000195C0FFFF97
+:1002E000C81C0011CCC12100CD012101CCC12102CB
+:1002F000CD012103041800048000039FCD81A2A436
+:10030000C02A00049580000836A821A3CC2900004B
+:10031000C8280004C81C00110DE400409640FFFFEF
+:10032000C81C0011CCC12170CD012171C820001260
+:1003300096000000C82000128000039FCC000064DB
+:100340007C40C0007C410000CC000045CC0000484F
+:1003500040D40003CD41225CCD01A1FCC01A0001B4
+:10036000041CA1FD7DD9C00C7C42000008CC00011A
+:100370000624000106280002CE1D0000CE5D00000C
+:1003800098C0FFFACE9D00007C408000A0000000D5
+:10039000CC8000627C40C00030D0000128CC00013D
+:1003A0007C414000950000067C418000CD41216DDC
+:1003B000CD81216E800000F3C81C0003C022000420
+:1003C0007E16000CCC210000C81C00047C424000BA
+:1003D00098C000047C42800080000001CDE5000050
+:1003E000CE412169CE81216ACDC1216B80000001FF
+:1003F000CC01216C7C40C0007C4100007C4140006D
+:100400007C4180007C41C00028A40008326400FFC9
+:100410000E68003C9680000A7C0200007C420000CE
+:100420001E300003CC00006A9B0000034220000540
+:1004300004200040800001107C0240007E02400049
+:100440009A4000000A64000130EC00109AC0000AD3
+:10045000CC000062C02A0004C82C00217E92800CCF
+:10046000CC000041CC290000CEC00021800001203A
+:10047000C8300004CD01216DCD41216EC83000038C
+:100480007F1F000B30F40007277800019740002AF7
+:1004900007B801259F8000000000000080000135A2
+:1004A0007F1B8004800001397F1B80058000013D97
+:1004B0007F1B8002800001417F1B8003800001457B
+:1004C0007F1B8007800001497F1B80068000014E52
+:1004D00028A400089B80001928A400088000015E61
+:1004E000326400FF9B80001528A400088000015E94
+:1004F000326400FF9B80001128A400088000015E88
+:10050000326400FF9B80000D28A400088000015E7B
+:10051000326400FF9B80000928A400088000015E6F
+:10052000326400FF9B80000528A400088000015E63
+:10053000326400FF28A40008326400FF0E68003C0B
+:100540009A80FEB128EC00087C4340007C43800088
+:100550007C43C00096C00007CC000062CF412169F7
+:10056000CF81216ACFC1216B80000001CC01216CB9
+:1005700080000001CFF50000CC00006B840003A2D6
+:100580000E68003C9A800004C82800158000000115
+:10059000D040007F9680FFAB7E0240008400023B8B
+:1005A000C00E0002CC00004180000239CCC1304AAC
+:1005B0007C40C0007C410000C01E000129240012C4
+:1005C000C022000296400005C0260004C027FFFBA1
+:1005D0007D25000BC02600007DD2800B7E12C00B53
+:1005E0007D25000C7C4140007C418000CCC121690C
+:1005F0009A80000ACD01216ACD41216B96C0FE820E
+:10060000CD81216CC830001897000000C830001858
+:1006100080000001CC000018840003A2CC00007F01
+:10062000C8140013C8180014CD41216B96C0FE7683
+:10063000CD81216C80000182C8300018C80C0008F0
+:1006400098C00000C80C00087C4100009500000222
+:10065000000000007C414000C8200009CC4000435D
+:10066000CE01A1F4CC400044C00E80007C4240008A
+:100670007C4280002AAC001F96C0FE63C035F000AB
+:10068000CE4003E232780003267C00087FF7C00BDF
+:100690007FFBC00C2A780018CFC003E3CF8003E4AF
+:1006A00026B000027F3F0000CF0003E58000031F5B
+:1006B0007C80C0007C40C00028D000083110000FB2
+:1006C0009500000F2528000106A801B39E800000B8
+:1006D00000000000800001D4C0120800800001E288
+:1006E000C814000F800001E9C8140010800001F058
+:1006F000CCC1A2A4800001F9C814001130D0003F81
+:100700000D2800159A8000120D28001E9A80001EE8
+:100710000D2800209A8000230D24000F0D280010C2
+:100720007E6A800C9A8000260D2000040D2400149F
+:100730000D2800287E62400C7EA6800C9A80002A3C
+:10074000C814001180000001CCC1A2A4C01208008E
+:100750007C4140007D0CC00CC012000829580003E9
+:10076000295C000C7C4200007DD1C00B26200014C7
+:100770007E1E400C7E4E800CCE81A2A48000000123
+:10078000CD81A1FEC814000F0410210E9540000079
+:10079000C814000FD051000080000001CCC1A2A4F9
+:1007A000C81400100410210895400000C81400105F
+:1007B000D051000080000001CCC1A2A4CCC1A2A4F1
+:1007C00004100001CD000019840003A2CC00007FBA
+:1007D000C810001999000000C8100019800000021C
+:1007E0007C40800004102100095400019540FFFF67
+:1007F000C8140011D05100008000039FCCC1A2A4F6
+:100800007C40C000CC40000D94C0FDFFCC40000EE9
+:100810007C4100009500000508CC0001C8140005CB
+:10082000994000140000000098C0FFFB7C410000CC
+:10083000800000027D008000C81400057C40C000DC
+:100840009940000CC818000C7C4100009580FDEE1A
+:10085000C820000EC81C000D662000207E1E002C43
+:10086000252400027E62402080000001CCE60000CA
+:100870007C410000CC00006CCC00006DC818001F4B
+:10088000C81C001E659800207DD9C02C7CD4C00CEB
+:10089000CCDE000045DC0004C82800179680000F5D
+:1008A000C00E0001286800082AAC001632A800FF1C
+:1008B0000EB000497F2F000B9700000600000000DB
+:1008C000C81400057C40C000800002237C41000069
+:1008D00080000226D040007F8400023BCC00004113
+:1008E000CCC1304A94000000C83C001A043C00050A
+:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8
+:100900007F7B400CCF41217CCFC1217DCC01217E5A
+:10091000C03A00040434217F7F7B400CCC350000BA
+:10092000C83C00042BFC001F0438002097C00005C1
+:10093000CC0000629B8000000BB8000180000247E1
+:10094000CC000071CC01A1F404380016C0360002BE
+:10095000CF81A2A488000000CF4120107C40C000BD
+:1009600028D0001C9500000504D40001CD4000658E
+:1009700080000001CD4000680954000280000001A1
+:10098000CD4000668400026CC81803EA7C40C000B9
+:100990009980FD9DC814001608D000019940002BD5
+:1009A000CD0000687C408000A0000000CC80006288
+:1009B000043C0005CFC1A2A4CC01A1F4840003A291
+:1009C000CC00004688000000CC00007F8400027E3E
+:1009D000C81803EA7C40C0009980FD8BC81400163B
+:1009E00008D0000199400019CD0000687C408000CB
+:1009F000A0000000CC800062043C0022CFC1A2A471
+:100A0000840003A2CC00004788000000CC00007FD7
+:100A1000C81000169900000DCC400067800000024D
+:100A20007C408000C81803EA9980FD777C40C000B4
+:100A300094C00003C810001699000004CCC00068E0
+:100A4000800000027C4080008400023BC0148000D3
+:100A5000CC000041CD41304AC01480009900000014
+:100A6000C8100016800000027C408000C012000107
+:100A70007C51400C80000001D05500007C40C0003B
+:100A80007C4100007C4140007C418000291C001F0B
+:100A9000CCC0004ACD00004B95C00003C01C8000B4
+:100AA000CDC12010DD830000055C2000CC00006279
+:100AB00080000001D81F41007C40C0007C41000044
+:100AC0007C4140007C418000CCC0004CCD00004DFA
+:100AD000DD830000055CA00080000001D81F4100FC
+:100AE0007C40C0007C4100007C4140007C41800093
+:100AF000CCC0004ECD00004FDD830000055CC0007F
+:100B000080000001D81F41007C40C0007C410000F3
+:100B10007C4140007C418000CCC00050CD000051A1
+:100B2000DD830000055CF8E080000001D81F410073
+:100B30007C40C0007C4100007C4140007C41800042
+:100B4000CCC00052CD000053DD830000055CF8806E
+:100B500080000001D81F41007C40C0007C410000A3
+:100B60007C4140007C418000CCC00054CD00005549
+:100B7000DD830000055CE00080000001D81F41001B
+:100B80007C40C0007C4100007C4140007C418000F2
+:100B9000CCC00056CD000057DD830000055CF0009E
+:100BA00080000001D81F41007C40C0007C41000053
+:100BB0007C4140007C418000CCC00058CD000059F1
+:100BC000DD830000055CF3FC80000001D81F4100BC
+:100BD000D04320007C408000A0000000CC80006258
+:100BE000D043A0007C408000A0000000CC800062C8
+:100BF000D043C0007C408000A0000000CC80006298
+:100C0000D043F8E07C408000A0000000CC8000626F
+:100C1000D043F8807C408000A0000000CC800062BF
+:100C2000D043E0007C408000A0000000CC80006247
+:100C3000D043F0007C408000A0000000CC80006227
+:100C4000D043F3FC7C408000A0000000CC80006218
+:100C5000C81403E0CC430000CC430000CC430000A8
+:100C60007D45C000CDC30000D04300007C40800023
+:100C7000A0000000CC8000627C40C000C81003E2ED
+:100C8000C81403E5C81803E3C81C03E4CD81216937
+:100C9000CDC1216ACCC1216BCC01216C04200004A0
+:100CA0007DA180007D9640029640FCD7CD8003E375
+:100CB00031280003C02DF000251800087DAD800B01
+:100CC0007DA9800C80000001CD8003E3308CFFFF04
+:100CD000D04D00007C408000A0000000CC8000626D
+:100CE0007C40C0007C4100002924001832640001CF
+:100CF0009A400013C8140020155800029580FFFF89
+:100D0000C8140020CC00006ECCC12180CD01218D03
+:100D1000CC4121812914001F34588000CD81218CC1
+:100D20009540FCB9CC412182C81400209940FFFFB6
+:100D3000C8140020800000027C4080007C414000FC
+:100D40007C4180007C41C00065B400207F57402C6E
+:100D5000D437810047740004D437810047740004FD
+:100D6000D43781004774000409DC0004D4378100C3
+:100D700099C0FFF8477400042924001FC0380019E7
+:100D80009640FCA1C03E0004CF8121F837E021F954
+:100D9000CC210000C82000042A20001832200001C5
+:100DA0009A00FFFBCF8121F8800000027C40800088
+:100DB0007C40C00028D0001831100001C01600800F
+:100DC00095000003C02A00047CD4C00CCCC1217C57
+:100DD000CC41217DCC41217E7C4180001DB00003AF
+:100DE00036A0217F9B000003419C0005041C0040AD
+:100DF00099C0000009DC0001CC210000C8240004D7
+:100E00002A6C001F419C00059AC0FFFACC8000624A
+:100E1000800000027C4080007C40C00004D403E6D7
+:100E200080000001CC5400008000039FCC4003EA06
+:100E3000C01C8000044CA000CDC120107C410000EB
+:100E4000C814000904180000041C0008CD800071BB
+:100E500009DC000105980001CD0D000099C0FFFCE0
+:100E6000CC8000628000039FCD400071C00E010065
+:100E7000CC000041CCC1304AC83C007FCC00007F90
+:100E800080000001CC00007FCC00007F88000000C3
+:100E9000CC00007F00000000000000000000000007
+:100EA0000000000000000000000000000000000042
+:100EB0000000000000000000000000000000000032
+:100EC0000000000000000000000000000000000022
+:100ED0000000000000000000000000000000000012
+:100EE0000000000000000000000000000000000002
+:100EF00000000000000000000000000000000000F2
+:100F000000000000000000000000000000000000E1
+:100F100000000000000000000000000000000000D1
+:100F200000000000000000000000000000000000C1
+:100F300000000000000000000000000000000000B1
+:100F400000000000000000000000000000000000A1
+:100F50000000000000000000000000000000000091
+:100F60000000000000000000000000000000000081
+:100F70000000000000000000000000000000000071
+:100F80000000000000000000000000000000000061
+:100F90000000000000000000000000000000000051
+:100FA0000000000000000000000000000000000041
+:100FB0000000000000000000000000000000000031
+:100FC0000000000000000000000000000000000021
+:100FD0000000000000000000000000000000000011
+:100FE0000000000000000000000000000000000001
+:100FF00000000000000000000000000000000000F1
+:1010000000000000000000000000000000000000E0
+:1010100000000000000000000000000000000000D0
+:1010200000000000000000000000000000000000C0
+:1010300000000000000000000000000000000000B0
+:1010400000000000000000000000000000000000A0
+:101050000000000000000000000000000000000090
+:101060000000000000000000000000000000000080
+:101070000000000000000000000000000000000070
+:101080000000000000000000000000000000000060
+:101090000000000000000000000000000000000050
+:1010A0000000000000000000000000000000000040
+:1010B0000000000000000000000000000000000030
+:1010C0000000000000000000000000000000000020
+:1010D0000000000000000000000000000000000010
+:1010E0000000000000000000000000000000000000
+:1010F00000000000000000000000000000000000F0
+:1011000000000000000000000000000000000000DF
+:1011100000000000000000000000000000000000CF
+:1011200000000000000000000000000000000000BF
+:1011300000000000000000000000000000000000AF
+:10114000000000000000000000000000000000009F
+:10115000000000000000000000000000000000008F
+:10116000000000000000000000000000000000007F
+:10117000000000000000000000000000000000006F
+:10118000000000000000000000000000000000005F
+:10119000000000000000000000000000000000004F
+:1011A000000000000000000000000000000000003F
+:1011B000000000000000000000000000000000002F
+:1011C000000000000000000000000000000000001F
+:1011D000000000000000000000000000000000000F
+:1011E00000000000000000000000000000000000FF
+:1011F00000000000000000000000000000000000EF
+:1012000000000000000000000000000000000000DE
+:1012100000000000000000000000000000000000CE
+:1012200000000000000000000000000000000000BE
+:1012300000000000000000000000000000000000AE
+:10124000000000000000000000000000000000009E
+:10125000000000000000000000000000000000008E
+:10126000000000000000000000000000000000007E
+:10127000000000000000000000000000000000006E
+:10128000000000000000000000000000000000005E
+:10129000000000000000000000000000000000004E
+:1012A000000000000000000000000000000000003E
+:1012B000000000000000000000000000000000002E
+:1012C000000000000000000000000000000000001E
+:1012D000000000000000000000000000000000000E
+:1012E00000000000000000000000000000000000FE
+:1012F00000000000000000000000000000000000EE
+:1013000000000000000000000000000000000000DD
+:1013100000000000000000000000000000000000CD
+:1013200000000000000000000000000000000000BD
+:1013300000000000000000000000000000000000AD
+:10134000000000000000000000000000000000009D
+:10135000000000000000000000000000000000008D
+:10136000000000000000000000000000000000007D
+:10137000000000000000000000000000000000006D
+:10138000000000000000000000000000000000005D
+:10139000000000000000000000000000000000004D
+:1013A000000000000000000000000000000000003D
+:1013B000000000000000000000000000000000002D
+:1013C000000000000000000000000000000000001D
+:1013D000000000000000000000000000000000000D
+:1013E00000000000000000000000000000000000FD
+:1013F00000000000000000000000000000000000ED
+:10140000000103330010000400170006002100084B
+:10141000002700280028002300290029002A002690
+:10142000002B0029002D0038002E003F002F004A1D
+:101430000034004C00360030003900AF003A00D0D4
+:10144000003B00E5003C00FD003D016C003F00ADAD
+:10145000004103380043036C0044018F004500FD48
+:10146000004601AD004701AD004802000049020EF0
+:10147000004A0257004B028400520261005302737B
+:10148000005402890057029B0060029F006102AE77
+:10149000006202B8006302C2006402CC006502D69A
+:1014A000006602E0006702EA006802F4006902F8E0
+:1014B000006A02FC006B0300006C0304006D03086B
+:1014C000006E030C006F031000700314007203869B
+:1014D0000074038C0079038A007C031E000F039BB9
+:1014E000000F039B000F039B000F039B000F039B48
+:1014F000000F039B000F039B000F039B000F039B38
+:10150000000F039B000F039B000F039B000F039B27
+:10151000000F039B000F039B000F039B000F039B17
+:10152000000F039B000F039B000F039B000F039B07
+:10153000000F039B000F039B000F039B000F039BF7
+:00000001FF
diff --git a/firmware/radeon/RV770_pfp.bin.ihex b/firmware/radeon/RV770_pfp.bin.ihex
new file mode 100644
index 0000000..a2d1619
--- /dev/null
+++ b/firmware/radeon/RV770_pfp.bin.ihex
@@ -0,0 +1,213 @@
+:100000007C408000A00000007E82800B8000000009
+:10001000DC030000CC800040D04000407C408000E9
+:10002000A00000007E82800BC818000E31980001ED
+:100030007C424000958002527C428000C81C001C1B
+:10004000C037C0007C40C0007C4100007CB4800B05
+:10005000C036000399C00000C81C001C7CB4800C92
+:1000600024D400027D654000CD400043CE80004393
+:10007000CD000043CC800040CE400040CE80004008
+:10008000CCC00040DC3A00009780FFDECD0000408D
+:100090007C40C000800000187C410000D400034078
+:1000A000D4000FC0D4000FA2C818000E8000000CAE
+:1000B00031980002D40003C0D4000FC0D4000FA2B6
+:1000C000C818000E288C000830CC000F3410000136
+:1000D0007D0D00088000000C7D91800BCC800040DD
+:1000E000D04000407C408000A00000007E82800B59
+:1000F000D4000340D4000FC0D4000FA2CC80004035
+:10010000D04000407C408000A00000007E82800B38
+:10011000D40003C0D4000FC0D4000FA2CC80004094
+:10012000D04000407C408000A00000007E82800B18
+:10013000CC4003F980000261CC4003F8C82003F8EA
+:10014000C81C03F9C81803FBC037FFFF7C414000FF
+:10015000CF41A29E662000207DE1C02C7D58C008C2
+:100160007CDCC02068D00020C0360003CC000054E6
+:100170007CB4800C8000006ACC8000407C41800010
+:10018000CD81A29ECC800040CD80004080000068E0
+:10019000CC000054C019FFFFCC800040CD81A29E4E
+:1001A0007C40C0007C4100007C414000CCC1A1FAF1
+:1001B000CD01A1F9CD41A29DCCC00040CD000040B1
+:1001C000CD400040CC4000407C408000A0000000BA
+:1001D0007E82800BCC000054CC8000407C40C0006C
+:1001E0007C4100007C414000CCC1A1FACD01A1F9C5
+:1001F000CD41A29DCCC00040CD000040CD4000408C
+:10020000D04000407C408000A00000007E82800B37
+:100210007C40C00030D00001CCC1A29F95000003FB
+:100220000414000104140002CD4003FBCC80004004
+:1002300080000000CCC000407C40C000CC8000406A
+:10024000CCC1A2A280000000CCC000407C40C00015
+:1002500028D4001FCC800040954000037C41000062
+:10026000CCC000572918001FCCC000409580000367
+:10027000CD000040CD00005880000261CC00007F1E
+:10028000C8200017C83000229A0000060E2800017E
+:10029000C824001E0A640001D4001240CE40004071
+:1002A000C036C0009680000737747900041C000136
+:1002B000CF400040CDC00040CF0003FA7C030000D7
+:1002C000CA0C00107C41000094C000047C41400036
+:1002D000D42002C4CDE000449B00000B7C41800090
+:1002E000CC00004BCDA00049CD200041CD600041A5
+:1002F000CDA0004106200001CE0000568000026122
+:10030000CC00007FC8280020C82C0021CC0000634E
+:100310007EEA4001657400207F53402C269C000239
+:100320007DF5C02069F80020CE80004BCE600049EA
+:10033000CDE00041CFA00041CE600041271C00026B
+:100340007DF5C02069F800207DB24001CF00004B50
+:10035000CE600049CDE00041CFA00041800000BD4B
+:10036000CE600041C8200017C83000229A00000665
+:100370000E280001C824001E0A640001D4001240A7
+:10038000CE400040CA0C00107C41000094C0000B1D
+:10039000C036C0009680000737747900041C000145
+:1003A000CF400040CDC00040CF0003FA7C030000E6
+:1003B000800000B67C414000CC000048800000EF87
+:1003C00000000000C8200017C81C00230E240002F3
+:1003D00099C000157C4180000A200001CE00005623
+:1003E000D4000440CC000040C036C000CA14001342
+:1003F0009640000737747900CF400040CC000040A1
+:10040000C83003FA80000104CF000022CC00002293
+:100410009540015DCC00007FCCA00046800000002C
+:10042000CC20004680000261CC000064C820001788
+:10043000C810001F9600000509100001D4000440F8
+:10044000CD000040CD000022CC800040D0400040D4
+:10045000C80C002594C0FEEBC8100008CD00004079
+:10046000D4000FC080000000D4000FA27C40C00068
+:100470007C410000CCC003FDCD0003FCCCC0004299
+:10048000CD0000422914001F2918001031980007E0
+:100490003B5C00017D76000B998000057D5E400B82
+:1004A000CC00004280000261CC00004D2998000180
+:1004B000292C00089980003D32EC000196000004D0
+:1004C0002930000C80000261CC00004204140010AE
+:1004D000CD40004233300001342800018400015E29
+:1004E000C81400039B40001B0438000C8400015E0C
+:1004F000C81400039B400017043800088400015E04
+:10050000C81400039B400013043800048400015EFB
+:10051000C81400039B400015C80C03FD9A80000915
+:10052000C81003FC9B000118CC00004D04140010FF
+:10053000CCC00042CD00004280000136CD400042D8
+:1005400096C00111CC00004D80000261CC00004E2D
+:100550009AC00003CC00004DCC00004EDF830000A9
+:1005600080000000D80301FF9AC00107CC00004DB5
+:1005700080000261CC00004EC8180003C81C0003B4
+:10058000C82000037D5D40037DA1C0037D5D400C5C
+:100590002A10001F299C001F7D1D000B7D17400B9A
+:1005A000880000007E92800B96400004CC00004E34
+:1005B00080000261CC00004204380008CF80004275
+:1005C000C8080003C80C0003C8100003C8140003C7
+:1005D000C8180003C81C0003C8240003C82800036F
+:1005E00029FC001F2AB0001F7FF3C00B28F0001F5A
+:1005F0007FF3C00B2970001F7FF3C00B7D88800143
+:100600007DCCC0017E5100017E9540017C9080022E
+:100610007CD4C0027CBC800B9AC000037C8F400B52
+:1006200038B400019B4000D8CC00004D9BC000D6E0
+:10063000CC00004EC80C03FDC81003FCCCC0004227
+:100640008000016FCD000042D4000340D4000FC0F1
+:10065000D4000FA2CC800040CC400040CC400040F1
+:10066000CC4000407C40C000CCC00040CCC0000D5D
+:1006700080000000D04000407C40C0007C41000071
+:10068000651400207D4D402C245800027D598020A7
+:100690007C41C000CD80004269980020CD8000429E
+:1006A000CDC00042C023C00005E400027CA0800B46
+:1006B000266400107CA4800CCC800040CDC000409B
+:1006C000CCC0004095C0000ECD00004009DC000108
+:1006D000C828000396800008CE800040C834001D62
+:1006E00097400000C834001D26A80008840002645A
+:1006F000CC2B000099C0FFF709DC0001DC3A0000B8
+:10070000978000047C418000800001A325980002AE
+:10071000A00000007D808000C818001D7C40C00043
+:1007200064D0000895800000C818001DCC1300009C
+:10073000CC800040CCC0004080000000CC40004095
+:10074000C810001F7C40C000CC8000407CD1400C11
+:10075000CD4000400518000180000000CD8000223F
+:100760007C40C0006450002084000264CC00006122
+:100770007CD0C02CC8200017C8D6000099400008C3
+:100780007C438000DF830000CFA0004F8400026420
+:10079000CC00006280000000D040007F8000026139
+:1007A000CC00006284000264CC000061C820001705
+:1007B0007C40C000C036FF00C810000DC0303FFFB5
+:1007C0007CF5400B7D51800B7D81800F9980000866
+:1007D0007CF3800BDF830000CFA0004F8400026415
+:1007E000CC00006280000000D040007F80000261E9
+:1007F000CC000062840002647C40C00028DC000859
+:1008000095C0001930DC00107C41000099C0000444
+:100810006454002080000209C91D00007D15002CD1
+:10082000C91E00007C4200007C4240007C418000E8
+:100830007DE5C00B7DE280079A80000E41AC00058B
+:100840009AC000000AEC000130DC001099C00004DE
+:10085000000000008000020CC91D00008000020C96
+:10086000C91E0000CC800040CCC00040D0400040F9
+:10087000C80C002594C0FDE3C8100008CD0000405E
+:10088000D4000FC080000000D4000FA2D4000340A9
+:10089000D4000FC0D4000FA2CC800040D040004054
+:1008A0007C408000A00000007E82800BD40003C04A
+:1008B000D4000FC0D4000FA2CC800040D040004034
+:1008C0007C408000A00000007E82800B7C40C00045
+:1008D00030D000060D10000699000007C81400155E
+:1008E00099400005CC000052D4000340D4000FC052
+:1008F000D4000FA2CC800040CCC00040800000009B
+:10090000D04000407C40C000CC4D0000DC3A0000EC
+:100910009780FDBC04CC000180000243CC4D000058
+:100920007C40C0007C410000292400183264000192
+:100930009640000FCC8000407C4140007C4180000C
+:100940007C41C000CCC00043CD00004331DC7FFFC0
+:10095000CDC00043CCC00040CD000040CD400040A1
+:10096000CD80004080000000CDC00040CCC00040E1
+:10097000CD00004080000000D0400040800000001A
+:10098000D040007FCC00007F80000000CC00007FC2
+:10099000CC00007F88000000CC00007F0000000039
+:1009A0000000000000000000000000000000000047
+:1009B0000000000000000000000000000000000037
+:1009C0000000000000000000000000000000000027
+:1009D0000000000000000000000000000000000017
+:1009E0000000000000000000000000000000000007
+:1009F00000000000000000000000000000000000F7
+:100A000000000000000000000000000000000000E6
+:100A100000000000000000000000000000000000D6
+:100A200000000000000000000000000000000000C6
+:100A300000000000000000000000000000000000B6
+:100A400000000000000000000000000000000000A6
+:100A50000000000000000000000000000000000096
+:100A60000000000000000000000000000000000086
+:100A70000000000000000000000000000000000076
+:100A80000000000000000000000000000000000066
+:100A90000000000000000000000000000000000056
+:100AA0000000000000000000000000000000000046
+:100AB0000000000000000000000000000000000036
+:100AC0000000000000000000000000000000000026
+:100AD0000000000000000000000000000000000016
+:100AE0000000000000000000000000000000000006
+:100AF00000000000000000000000000000000000F6
+:100B000000000000000000000000000000000000E5
+:100B100000000000000000000000000000000000D5
+:100B200000000000000000000000000000000000C5
+:100B300000000000000000000000000000000000B5
+:100B400000000000000000000000000000000000A5
+:100B50000000000000000000000000000000000095
+:100B60000000000000000000000000000000000085
+:100B70000000000000000000000000000000000075
+:100B80000000000000000000000000000000000065
+:100B90000000000000000000000000000000000055
+:100BA0000000000000000000000000000000000045
+:100BB0000000000000000000000000000000000035
+:100BC0000000000000000000000000000000000025
+:100BD0000000000000000000000000000000000015
+:100BE0000000000000000000000000000000000005
+:100BF00000000000000000000000000000000000F5
+:100C0000000302230004022B000500A000020003E1
+:100C10000006003C0007002700080192000900447C
+:100C2000000A002D0010025F001700F1002201D819
+:100C3000002301E90026004C0027005F0020011B73
+:100C4000002800930029004F002A0084002B006533
+:100C5000002F008E003200D90034023300360075B8
+:100C60000039010B003C01FD003F00A0004102489B
+:100C7000004401950048019E004901C6004A01D088
+:100C8000005502260056022E0060000A0061002A6C
+:100C90000062003000630030006400300065003006
+:100CA0000066003000670030006800370069003FD0
+:100CB000006A0047006B0047006C0047006D00476A
+:100CC000006E0047006F0047007000470073025F2E
+:100CD000007B024100000005000000050000000547
+:100CE00000000005000000050000000500000005F0
+:100CF00000000005000000050000000500000005E0
+:100D000000000005000000050000000500000005CF
+:100D100000000005000000050000000500000005BF
+:100D200000000005000000050000000500000005AF
+:100D3000000000050000000500000005000000059F
+:00000001FF
diff --git a/fs/Kconfig b/fs/Kconfig
index 0e7da7b..455aa20 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -43,6 +43,7 @@ source "fs/xfs/Kconfig"
 source "fs/gfs2/Kconfig"
 source "fs/ocfs2/Kconfig"
 source "fs/btrfs/Kconfig"
+source "fs/nilfs2/Kconfig"
 
 endif # BLOCK
 
@@ -186,7 +187,6 @@ source "fs/romfs/Kconfig"
 source "fs/sysv/Kconfig"
 source "fs/ufs/Kconfig"
 source "fs/exofs/Kconfig"
-source "fs/nilfs2/Kconfig"
 
 endif # MISC_FILESYSTEMS
 
diff --git a/fs/afs/write.c b/fs/afs/write.c
index c2e7a7f..c63a3c8 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -712,7 +712,6 @@ int afs_writeback_all(struct afs_vnode *vnode)
 		.bdi		= mapping->backing_dev_info,
 		.sync_mode	= WB_SYNC_ALL,
 		.nr_to_write	= LONG_MAX,
-		.for_writepages = 1,
 		.range_cyclic	= 1,
 	};
 	int ret;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 94dfda2..71e7e03 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -420,7 +420,6 @@ static void bdev_destroy_inode(struct inode *inode)
 {
 	struct bdev_inode *bdi = BDEV_I(inode);
 
-	bdi->bdev.bd_inode_backing_dev_info = NULL;
 	kmem_cache_free(bdev_cachep, bdi);
 }
 
@@ -1405,6 +1404,33 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 }
 
 /*
+ * Write data to the block device.  Only intended for the block device itself
+ * and the raw driver which basically is a fake block device.
+ *
+ * Does not take i_mutex for the write and thus is not for general purpose
+ * use.
+ */
+ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
+			 unsigned long nr_segs, loff_t pos)
+{
+	struct file *file = iocb->ki_filp;
+	ssize_t ret;
+
+	BUG_ON(iocb->ki_pos != pos);
+
+	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
+	if (ret > 0 || ret == -EIOCBQUEUED) {
+		ssize_t err;
+
+		err = generic_write_sync(file, pos, ret);
+		if (err < 0 && ret > 0)
+			ret = err;
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(blkdev_aio_write);
+
+/*
  * Try to release a page associated with block device when the system
  * is under memory pressure.
  */
@@ -1436,7 +1462,7 @@ const struct file_operations def_blk_fops = {
 	.read		= do_sync_read,
 	.write		= do_sync_write,
   	.aio_read	= generic_file_aio_read,
-  	.aio_write	= generic_file_aio_write_nolock,
+	.aio_write	= blkdev_aio_write,
 	.mmap		= generic_file_mmap,
 	.fsync		= block_fsync,
 	.unlocked_ioctl	= block_ioctl,
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 15831d5..8b81927 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1600,6 +1600,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
 
 	sb->s_blocksize = 4096;
 	sb->s_blocksize_bits = blksize_bits(4096);
+	sb->s_bdi = &fs_info->bdi;
 
 	/*
 	 * we set the i_size on the btree inode to the max possible int.
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 72a2b9c..535f85b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1511,7 +1511,8 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
 static void btrfs_issue_discard(struct block_device *bdev,
 				u64 start, u64 len)
 {
-	blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL);
+	blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL,
+			     DISCARD_FL_BARRIER);
 }
 #endif
 
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index d6f0806..7b2f401 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -740,7 +740,6 @@ int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start,
 		.nr_to_write = mapping->nrpages * 2,
 		.range_start = start,
 		.range_end = end,
-		.for_writepages = 1,
 	};
 	return btrfs_writepages(mapping, &wbc);
 }
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 5dbefd1..5cf405b 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -260,7 +260,7 @@ loop_lock:
 		num_run++;
 		batch_run++;
 
-		if (bio_sync(cur))
+		if (bio_rw_flagged(cur, BIO_RW_SYNCIO))
 			num_sync_run++;
 
 		if (need_resched()) {
@@ -2903,7 +2903,7 @@ static noinline int schedule_bio(struct btrfs_root *root,
 	bio->bi_rw |= rw;
 
 	spin_lock(&device->io_lock);
-	if (bio_sync(bio))
+	if (bio_rw_flagged(bio, BIO_RW_SYNCIO))
 		pending_bios = &device->pending_sync_bios;
 	else
 		pending_bios = &device->pending_bios;
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index e85b1e4..145540a 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -3,7 +3,10 @@ Version 1.60
 Fix memory leak in reconnect.  Fix oops in DFS mount error path.
 Set s_maxbytes to smaller (the max that vfs can handle) so that
 sendfile will now work over cifs mounts again.  Add noforcegid
-and noforceuid mount parameters.
+and noforceuid mount parameters. Fix small mem leak when using
+ntlmv2. Fix 2nd mount to same server but with different port to
+be allowed (rather than reusing the 1st port) - only when the
+user explicitly overrides the port on the 2nd mount.
 
 Version 1.59
 ------------
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 051caec..8ec7736 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -125,7 +125,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
 	if (server->addr.sockAddr.sin_family == AF_INET)
 		sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr);
 	else if (server->addr.sockAddr.sin_family == AF_INET6)
-		sprintf(dp, "ip6=%pi6", &server->addr.sockAddr6.sin6_addr);
+		sprintf(dp, "ip6=%pI6", &server->addr.sockAddr6.sin6_addr);
 	else
 		goto out;
 
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 6941c22..7dfe084 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -607,7 +607,7 @@ static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
 		return get_cifs_acl_by_path(cifs_sb, path, pacllen);
 
 	pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
-	atomic_dec(&open_file->wrtPending);
+	cifsFileInfo_put(open_file);
 	return pntsd;
 }
 
@@ -665,7 +665,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
 		return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
 
 	rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen);
-	atomic_dec(&open_file->wrtPending);
+	cifsFileInfo_put(open_file);
 	return rc;
 }
 
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 7c98095..7efe174 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -373,6 +373,7 @@ calc_exit_2:
 	   compare with the NTLM example */
 	hmac_md5_final(ses->server->ntlmv2_hash, pctxt);
 
+	kfree(pctxt);
 	return rc;
 }
 
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 84b7525..3610e99 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -361,13 +361,10 @@ cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
 static int
 cifs_show_options(struct seq_file *s, struct vfsmount *m)
 {
-	struct cifs_sb_info *cifs_sb;
-	struct cifsTconInfo *tcon;
-
-	cifs_sb = CIFS_SB(m->mnt_sb);
-	tcon = cifs_sb->tcon;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
+	struct cifsTconInfo *tcon = cifs_sb->tcon;
 
-	seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
+	seq_printf(s, ",unc=%s", tcon->treeName);
 	if (tcon->ses->userName)
 		seq_printf(s, ",username=%s", tcon->ses->userName);
 	if (tcon->ses->domainName)
@@ -989,19 +986,19 @@ static int cifs_oplock_thread(void *dummyarg)
 		if (try_to_freeze())
 			continue;
 
-		spin_lock(&GlobalMid_Lock);
-		if (list_empty(&GlobalOplock_Q)) {
-			spin_unlock(&GlobalMid_Lock);
+		spin_lock(&cifs_oplock_lock);
+		if (list_empty(&cifs_oplock_list)) {
+			spin_unlock(&cifs_oplock_lock);
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(39*HZ);
 		} else {
-			oplock_item = list_entry(GlobalOplock_Q.next,
+			oplock_item = list_entry(cifs_oplock_list.next,
 						struct oplock_q_entry, qhead);
 			cFYI(1, ("found oplock item to write out"));
 			pTcon = oplock_item->tcon;
 			inode = oplock_item->pinode;
 			netfid = oplock_item->netfid;
-			spin_unlock(&GlobalMid_Lock);
+			spin_unlock(&cifs_oplock_lock);
 			DeleteOplockQEntry(oplock_item);
 			/* can not grab inode sem here since it would
 				deadlock when oplock received on delete
@@ -1058,7 +1055,7 @@ init_cifs(void)
 	int rc = 0;
 	cifs_proc_init();
 	INIT_LIST_HEAD(&cifs_tcp_ses_list);
-	INIT_LIST_HEAD(&GlobalOplock_Q);
+	INIT_LIST_HEAD(&cifs_oplock_list);
 #ifdef CONFIG_CIFS_EXPERIMENTAL
 	INIT_LIST_HEAD(&GlobalDnotifyReqList);
 	INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
@@ -1087,6 +1084,7 @@ init_cifs(void)
 	rwlock_init(&GlobalSMBSeslock);
 	rwlock_init(&cifs_tcp_ses_lock);
 	spin_lock_init(&GlobalMid_Lock);
+	spin_lock_init(&cifs_oplock_lock);
 
 	if (cifs_max_pending < 2) {
 		cifs_max_pending = 2;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 6c17094..094325e 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -113,5 +113,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.60"
+#define CIFS_VERSION   "1.61"
 #endif				/* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 6084d63..6cfc81a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -351,11 +351,24 @@ struct cifsFileInfo {
 	bool closePend:1;	/* file is marked to close */
 	bool invalidHandle:1;	/* file closed via session abend */
 	bool messageMode:1;	/* for pipes: message vs byte mode */
-	atomic_t wrtPending;   /* handle in use - defer close */
+	atomic_t count;		/* reference count */
 	struct mutex fh_mutex; /* prevents reopen race after dead ses*/
 	struct cifs_search_info srch_inf;
 };
 
+/* Take a reference on the file private data */
+static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
+{
+	atomic_inc(&cifs_file->count);
+}
+
+/* Release a reference on the file private data */
+static inline void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
+{
+	if (atomic_dec_and_test(&cifs_file->count))
+		kfree(cifs_file);
+}
+
 /*
  * One of these for each file inode
  */
@@ -656,7 +669,11 @@ GLOBAL_EXTERN rwlock_t		cifs_tcp_ses_lock;
  */
 GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;
 
-GLOBAL_EXTERN struct list_head GlobalOplock_Q;
+/* Global list of oplocks */
+GLOBAL_EXTERN struct list_head cifs_oplock_list;
+
+/* Protects the cifs_oplock_list */
+GLOBAL_EXTERN spinlock_t cifs_oplock_lock;
 
 /* Outstanding dir notify requests */
 GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 1866bc2..301e307 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -100,110 +100,138 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
 	   to this tcon */
 }
 
-/* Allocate and return pointer to an SMB request buffer, and set basic
-   SMB information in the SMB header.  If the return code is zero, this
-   function must have filled in request_buf pointer */
+/* reconnect the socket, tcon, and smb session if needed */
 static int
-small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
-		void **request_buf)
+cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
 {
 	int rc = 0;
+	struct cifsSesInfo *ses;
+	struct TCP_Server_Info *server;
+	struct nls_table *nls_codepage;
 
-	/* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
-	   check for tcp and smb session status done differently
-	   for those three - in the calling routine */
-	if (tcon) {
-		if (tcon->tidStatus == CifsExiting) {
-			/* only tree disconnect, open, and write,
-			(and ulogoff which does not have tcon)
-			are allowed as we start force umount */
-			if ((smb_command != SMB_COM_WRITE_ANDX) &&
-			   (smb_command != SMB_COM_OPEN_ANDX) &&
-			   (smb_command != SMB_COM_TREE_DISCONNECT)) {
-				cFYI(1, ("can not send cmd %d while umounting",
-					smb_command));
-				return -ENODEV;
-			}
+	/*
+	 * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
+	 * tcp and smb session status done differently for those three - in the
+	 * calling routine
+	 */
+	if (!tcon)
+		return 0;
+
+	ses = tcon->ses;
+	server = ses->server;
+
+	/*
+	 * only tree disconnect, open, and write, (and ulogoff which does not
+	 * have tcon) are allowed as we start force umount
+	 */
+	if (tcon->tidStatus == CifsExiting) {
+		if (smb_command != SMB_COM_WRITE_ANDX &&
+		    smb_command != SMB_COM_OPEN_ANDX &&
+		    smb_command != SMB_COM_TREE_DISCONNECT) {
+			cFYI(1, ("can not send cmd %d while umounting",
+				smb_command));
+			return -ENODEV;
 		}
-		if ((tcon->ses) && (tcon->ses->status != CifsExiting) &&
-				  (tcon->ses->server)) {
-			struct nls_table *nls_codepage;
-				/* Give Demultiplex thread up to 10 seconds to
-				   reconnect, should be greater than cifs socket
-				   timeout which is 7 seconds */
-			while (tcon->ses->server->tcpStatus ==
-							 CifsNeedReconnect) {
-				wait_event_interruptible_timeout(tcon->ses->server->response_q,
-					(tcon->ses->server->tcpStatus ==
-							CifsGood), 10 * HZ);
-				if (tcon->ses->server->tcpStatus ==
-							CifsNeedReconnect) {
-					/* on "soft" mounts we wait once */
-					if (!tcon->retry ||
-					   (tcon->ses->status == CifsExiting)) {
-						cFYI(1, ("gave up waiting on "
-						      "reconnect in smb_init"));
-						return -EHOSTDOWN;
-					} /* else "hard" mount - keep retrying
-					     until process is killed or server
-					     comes back on-line */
-				} else /* TCP session is reestablished now */
-					break;
-			}
+	}
 
-			nls_codepage = load_nls_default();
-		/* need to prevent multiple threads trying to
-		simultaneously reconnect the same SMB session */
-			down(&tcon->ses->sesSem);
-			if (tcon->ses->need_reconnect)
-				rc = cifs_setup_session(0, tcon->ses,
-							nls_codepage);
-			if (!rc && (tcon->need_reconnect)) {
-				mark_open_files_invalid(tcon);
-				rc = CIFSTCon(0, tcon->ses, tcon->treeName,
-					      tcon, nls_codepage);
-				up(&tcon->ses->sesSem);
-				/* BB FIXME add code to check if wsize needs
-				   update due to negotiated smb buffer size
-				   shrinking */
-				if (rc == 0) {
-					atomic_inc(&tconInfoReconnectCount);
-					/* tell server Unix caps we support */
-					if (tcon->ses->capabilities & CAP_UNIX)
-						reset_cifs_unix_caps(
-						0 /* no xid */,
-						tcon,
-						NULL /* we do not know sb */,
-						NULL /* no vol info */);
-				}
+	if (ses->status == CifsExiting)
+		return -EIO;
 
-				cFYI(1, ("reconnect tcon rc = %d", rc));
-				/* Removed call to reopen open files here.
-				   It is safer (and faster) to reopen files
-				   one at a time as needed in read and write */
-
-				/* Check if handle based operation so we
-				   know whether we can continue or not without
-				   returning to caller to reset file handle */
-				switch (smb_command) {
-					case SMB_COM_READ_ANDX:
-					case SMB_COM_WRITE_ANDX:
-					case SMB_COM_CLOSE:
-					case SMB_COM_FIND_CLOSE2:
-					case SMB_COM_LOCKING_ANDX: {
-						unload_nls(nls_codepage);
-						return -EAGAIN;
-					}
-				}
-			} else {
-				up(&tcon->ses->sesSem);
-			}
-			unload_nls(nls_codepage);
+	/*
+	 * Give demultiplex thread up to 10 seconds to reconnect, should be
+	 * greater than cifs socket timeout which is 7 seconds
+	 */
+	while (server->tcpStatus == CifsNeedReconnect) {
+		wait_event_interruptible_timeout(server->response_q,
+			(server->tcpStatus == CifsGood), 10 * HZ);
 
-		} else {
-			return -EIO;
+		/* is TCP session is reestablished now ?*/
+		if (server->tcpStatus != CifsNeedReconnect)
+			break;
+
+		/*
+		 * on "soft" mounts we wait once. Hard mounts keep
+		 * retrying until process is killed or server comes
+		 * back on-line
+		 */
+		if (!tcon->retry || ses->status == CifsExiting) {
+			cFYI(1, ("gave up waiting on reconnect in smb_init"));
+			return -EHOSTDOWN;
 		}
 	}
+
+	if (!ses->need_reconnect && !tcon->need_reconnect)
+		return 0;
+
+	nls_codepage = load_nls_default();
+
+	/*
+	 * need to prevent multiple threads trying to simultaneously
+	 * reconnect the same SMB session
+	 */
+	down(&ses->sesSem);
+	if (ses->need_reconnect)
+		rc = cifs_setup_session(0, ses, nls_codepage);
+
+	/* do we need to reconnect tcon? */
+	if (rc || !tcon->need_reconnect) {
+		up(&ses->sesSem);
+		goto out;
+	}
+
+	mark_open_files_invalid(tcon);
+	rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
+	up(&ses->sesSem);
+	cFYI(1, ("reconnect tcon rc = %d", rc));
+
+	if (rc)
+		goto out;
+
+	/*
+	 * FIXME: check if wsize needs updated due to negotiated smb buffer
+	 * 	  size shrinking
+	 */
+	atomic_inc(&tconInfoReconnectCount);
+
+	/* tell server Unix caps we support */
+	if (ses->capabilities & CAP_UNIX)
+		reset_cifs_unix_caps(0, tcon, NULL, NULL);
+
+	/*
+	 * Removed call to reopen open files here. It is safer (and faster) to
+	 * reopen files one at a time as needed in read and write.
+	 *
+	 * FIXME: what about file locks? don't we need to reclaim them ASAP?
+	 */
+
+out:
+	/*
+	 * Check if handle based operation so we know whether we can continue
+	 * or not without returning to caller to reset file handle
+	 */
+	switch (smb_command) {
+	case SMB_COM_READ_ANDX:
+	case SMB_COM_WRITE_ANDX:
+	case SMB_COM_CLOSE:
+	case SMB_COM_FIND_CLOSE2:
+	case SMB_COM_LOCKING_ANDX:
+		rc = -EAGAIN;
+	}
+
+	unload_nls(nls_codepage);
+	return rc;
+}
+
+/* Allocate and return pointer to an SMB request buffer, and set basic
+   SMB information in the SMB header.  If the return code is zero, this
+   function must have filled in request_buf pointer */
+static int
+small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+		void **request_buf)
+{
+	int rc = 0;
+
+	rc = cifs_reconnect_tcon(tcon, smb_command);
 	if (rc)
 		return rc;
 
@@ -256,101 +284,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
 {
 	int rc = 0;
 
-	/* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
-	   check for tcp and smb session status done differently
-	   for those three - in the calling routine */
-	if (tcon) {
-		if (tcon->tidStatus == CifsExiting) {
-			/* only tree disconnect, open, and write,
-			  (and ulogoff which does not have tcon)
-			  are allowed as we start force umount */
-			if ((smb_command != SMB_COM_WRITE_ANDX) &&
-			   (smb_command != SMB_COM_OPEN_ANDX) &&
-			   (smb_command != SMB_COM_TREE_DISCONNECT)) {
-				cFYI(1, ("can not send cmd %d while umounting",
-					smb_command));
-				return -ENODEV;
-			}
-		}
-
-		if ((tcon->ses) && (tcon->ses->status != CifsExiting) &&
-				  (tcon->ses->server)) {
-			struct nls_table *nls_codepage;
-				/* Give Demultiplex thread up to 10 seconds to
-				   reconnect, should be greater than cifs socket
-				   timeout which is 7 seconds */
-			while (tcon->ses->server->tcpStatus ==
-							CifsNeedReconnect) {
-				wait_event_interruptible_timeout(tcon->ses->server->response_q,
-					(tcon->ses->server->tcpStatus ==
-							CifsGood), 10 * HZ);
-				if (tcon->ses->server->tcpStatus ==
-						CifsNeedReconnect) {
-					/* on "soft" mounts we wait once */
-					if (!tcon->retry ||
-					   (tcon->ses->status == CifsExiting)) {
-						cFYI(1, ("gave up waiting on "
-						      "reconnect in smb_init"));
-						return -EHOSTDOWN;
-					} /* else "hard" mount - keep retrying
-					     until process is killed or server
-					     comes on-line */
-				} else /* TCP session is reestablished now */
-					break;
-			}
-			nls_codepage = load_nls_default();
-		/* need to prevent multiple threads trying to
-		simultaneously reconnect the same SMB session */
-			down(&tcon->ses->sesSem);
-			if (tcon->ses->need_reconnect)
-				rc = cifs_setup_session(0, tcon->ses,
-							nls_codepage);
-			if (!rc && (tcon->need_reconnect)) {
-				mark_open_files_invalid(tcon);
-				rc = CIFSTCon(0, tcon->ses, tcon->treeName,
-					      tcon, nls_codepage);
-				up(&tcon->ses->sesSem);
-				/* BB FIXME add code to check if wsize needs
-				update due to negotiated smb buffer size
-				shrinking */
-				if (rc == 0) {
-					atomic_inc(&tconInfoReconnectCount);
-					/* tell server Unix caps we support */
-					if (tcon->ses->capabilities & CAP_UNIX)
-						reset_cifs_unix_caps(
-						0 /* no xid */,
-						tcon,
-						NULL /* do not know sb */,
-						NULL /* no vol info */);
-				}
-
-				cFYI(1, ("reconnect tcon rc = %d", rc));
-				/* Removed call to reopen open files here.
-				   It is safer (and faster) to reopen files
-				   one at a time as needed in read and write */
-
-				/* Check if handle based operation so we
-				   know whether we can continue or not without
-				   returning to caller to reset file handle */
-				switch (smb_command) {
-					case SMB_COM_READ_ANDX:
-					case SMB_COM_WRITE_ANDX:
-					case SMB_COM_CLOSE:
-					case SMB_COM_FIND_CLOSE2:
-					case SMB_COM_LOCKING_ANDX: {
-						unload_nls(nls_codepage);
-						return -EAGAIN;
-					}
-				}
-			} else {
-				up(&tcon->ses->sesSem);
-			}
-			unload_nls(nls_codepage);
-
-		} else {
-			return -EIO;
-		}
-	}
+	rc = cifs_reconnect_tcon(tcon, smb_command);
 	if (rc)
 		return rc;
 
@@ -3961,6 +3895,10 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
 		if (is_unicode) {
 			__le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
 						GFP_KERNEL);
+			if (tmp == NULL) {
+				rc = -ENOMEM;
+				goto parse_DFS_referrals_exit;
+			}
 			cifsConvertToUCS((__le16 *) tmp, searchName,
 					PATH_MAX, nls_codepage, remap);
 			node->path_consumed = cifs_ucs2_bytes(tmp,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 1f3345d..d496824 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1377,7 +1377,7 @@ cifs_parse_mount_options(char *options, const char *devname,
 }
 
 static struct TCP_Server_Info *
-cifs_find_tcp_session(struct sockaddr_storage *addr)
+cifs_find_tcp_session(struct sockaddr_storage *addr, unsigned short int port)
 {
 	struct list_head *tmp;
 	struct TCP_Server_Info *server;
@@ -1397,16 +1397,37 @@ cifs_find_tcp_session(struct sockaddr_storage *addr)
 		if (server->tcpStatus == CifsNew)
 			continue;
 
-		if (addr->ss_family == AF_INET &&
-		    (addr4->sin_addr.s_addr !=
-		     server->addr.sockAddr.sin_addr.s_addr))
-			continue;
-		else if (addr->ss_family == AF_INET6 &&
-			 (!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
-					   &addr6->sin6_addr) ||
-			  server->addr.sockAddr6.sin6_scope_id !=
-					   addr6->sin6_scope_id))
-			continue;
+		switch (addr->ss_family) {
+		case AF_INET:
+			if (addr4->sin_addr.s_addr ==
+			    server->addr.sockAddr.sin_addr.s_addr) {
+				addr4->sin_port = htons(port);
+				/* user overrode default port? */
+				if (addr4->sin_port) {
+					if (addr4->sin_port !=
+					    server->addr.sockAddr.sin_port)
+						continue;
+				}
+				break;
+			} else
+				continue;
+
+		case AF_INET6:
+			if (ipv6_addr_equal(&addr6->sin6_addr,
+			    &server->addr.sockAddr6.sin6_addr) &&
+			    (addr6->sin6_scope_id ==
+			    server->addr.sockAddr6.sin6_scope_id)) {
+				addr6->sin6_port = htons(port);
+				/* user overrode default port? */
+				if (addr6->sin6_port) {
+					if (addr6->sin6_port !=
+					   server->addr.sockAddr6.sin6_port)
+						continue;
+				}
+				break;
+			} else
+				continue;
+		}
 
 		++server->srv_count;
 		write_unlock(&cifs_tcp_ses_lock);
@@ -1475,7 +1496,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 	}
 
 	/* see if we already have a matching tcp_ses */
-	tcp_ses = cifs_find_tcp_session(&addr);
+	tcp_ses = cifs_find_tcp_session(&addr, volume_info->port);
 	if (tcp_ses)
 		return tcp_ses;
 
@@ -2636,9 +2657,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
 		return -EIO;
 
 	smb_buffer = cifs_buf_get();
-	if (smb_buffer == NULL) {
+	if (smb_buffer == NULL)
 		return -ENOMEM;
-	}
+
 	smb_buffer_response = smb_buffer;
 
 	header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 4326ffd..a6424cf 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -153,7 +153,7 @@ cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
 	mutex_init(&pCifsFile->fh_mutex);
 	mutex_init(&pCifsFile->lock_mutex);
 	INIT_LIST_HEAD(&pCifsFile->llist);
-	atomic_set(&pCifsFile->wrtPending, 0);
+	atomic_set(&pCifsFile->count, 1);
 
 	/* set the following in open now
 			pCifsFile->pfile = file; */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index c34b7f8..fa7beac 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -53,11 +53,9 @@ static inline struct cifsFileInfo *cifs_init_private(
 	private_data->pInode = inode;
 	private_data->invalidHandle = false;
 	private_data->closePend = false;
-	/* we have to track num writers to the inode, since writepages
-	does not tell us which handle the write is for so there can
-	be a close (overlapping with write) of the filehandle that
-	cifs_writepages chose to use */
-	atomic_set(&private_data->wrtPending, 0);
+	/* Initialize reference count to one.  The private data is
+	freed on the release of the last reference */
+	atomic_set(&private_data->count, 1);
 
 	return private_data;
 }
@@ -643,7 +641,7 @@ int cifs_close(struct inode *inode, struct file *file)
 			if (!pTcon->need_reconnect) {
 				write_unlock(&GlobalSMBSeslock);
 				timeout = 2;
-				while ((atomic_read(&pSMBFile->wrtPending) != 0)
+				while ((atomic_read(&pSMBFile->count) != 1)
 					&& (timeout <= 2048)) {
 					/* Give write a better chance to get to
 					server ahead of the close.  We do not
@@ -657,8 +655,6 @@ int cifs_close(struct inode *inode, struct file *file)
 					msleep(timeout);
 					timeout *= 4;
 				}
-				if (atomic_read(&pSMBFile->wrtPending))
-					cERROR(1, ("close with pending write"));
 				if (!pTcon->need_reconnect &&
 				    !pSMBFile->invalidHandle)
 					rc = CIFSSMBClose(xid, pTcon,
@@ -681,24 +677,7 @@ int cifs_close(struct inode *inode, struct file *file)
 		list_del(&pSMBFile->flist);
 		list_del(&pSMBFile->tlist);
 		write_unlock(&GlobalSMBSeslock);
-		timeout = 10;
-		/* We waited above to give the SMBWrite a chance to issue
-		   on the wire (so we do not get SMBWrite returning EBADF
-		   if writepages is racing with close.  Note that writepages
-		   does not specify a file handle, so it is possible for a file
-		   to be opened twice, and the application close the "wrong"
-		   file handle - in these cases we delay long enough to allow
-		   the SMBWrite to get on the wire before the SMB Close.
-		   We allow total wait here over 45 seconds, more than
-		   oplock break time, and more than enough to allow any write
-		   to complete on the server, or to time out on the client */
-		while ((atomic_read(&pSMBFile->wrtPending) != 0)
-				&& (timeout <= 50000)) {
-			cERROR(1, ("writes pending, delay free of handle"));
-			msleep(timeout);
-			timeout *= 8;
-		}
-		kfree(file->private_data);
+		cifsFileInfo_put(file->private_data);
 		file->private_data = NULL;
 	} else
 		rc = -EBADF;
@@ -1236,7 +1215,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)
 			if (!open_file->invalidHandle) {
 				/* found a good file */
 				/* lock it so it will not be closed on us */
-				atomic_inc(&open_file->wrtPending);
+				cifsFileInfo_get(open_file);
 				read_unlock(&GlobalSMBSeslock);
 				return open_file;
 			} /* else might as well continue, and look for
@@ -1276,7 +1255,7 @@ refind_writable:
 		if (open_file->pfile &&
 		    ((open_file->pfile->f_flags & O_RDWR) ||
 		     (open_file->pfile->f_flags & O_WRONLY))) {
-			atomic_inc(&open_file->wrtPending);
+			cifsFileInfo_get(open_file);
 
 			if (!open_file->invalidHandle) {
 				/* found a good writable file */
@@ -1293,7 +1272,7 @@ refind_writable:
 				else { /* start over in case this was deleted */
 				       /* since the list could be modified */
 					read_lock(&GlobalSMBSeslock);
-					atomic_dec(&open_file->wrtPending);
+					cifsFileInfo_put(open_file);
 					goto refind_writable;
 				}
 			}
@@ -1309,7 +1288,7 @@ refind_writable:
 			read_lock(&GlobalSMBSeslock);
 			/* can not use this handle, no write
 			   pending on this one after all */
-			atomic_dec(&open_file->wrtPending);
+			cifsFileInfo_put(open_file);
 
 			if (open_file->closePend) /* list could have changed */
 				goto refind_writable;
@@ -1373,7 +1352,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
 	if (open_file) {
 		bytes_written = cifs_write(open_file->pfile, write_data,
 					   to-from, &offset);
-		atomic_dec(&open_file->wrtPending);
+		cifsFileInfo_put(open_file);
 		/* Does mm or vfs already set times? */
 		inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
 		if ((bytes_written > 0) && (offset))
@@ -1562,7 +1541,7 @@ retry:
 						   bytes_to_write, offset,
 						   &bytes_written, iov, n_iov,
 						   long_op);
-				atomic_dec(&open_file->wrtPending);
+				cifsFileInfo_put(open_file);
 				cifs_update_eof(cifsi, offset, bytes_written);
 
 				if (rc || bytes_written < bytes_to_write) {
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 82d8383..1f09c76 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -800,7 +800,7 @@ set_via_filehandle:
 	if (open_file == NULL)
 		CIFSSMBClose(xid, pTcon, netfid);
 	else
-		atomic_dec(&open_file->wrtPending);
+		cifsFileInfo_put(open_file);
 out:
 	return rc;
 }
@@ -1635,7 +1635,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
 		__u32 npid = open_file->pid;
 		rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
 					npid, false);
-		atomic_dec(&open_file->wrtPending);
+		cifsFileInfo_put(open_file);
 		cFYI(1, ("SetFSize for attrs rc = %d", rc));
 		if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
 			unsigned int bytes_written;
@@ -1790,7 +1790,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
 		u16 nfid = open_file->netfid;
 		u32 npid = open_file->pid;
 		rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
-		atomic_dec(&open_file->wrtPending);
+		cifsFileInfo_put(open_file);
 	} else {
 		rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
 				    cifs_sb->local_nls,
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 0ad3e2d..1da4ab2 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -119,20 +119,19 @@ AllocOplockQEntry(struct inode *pinode, __u16 fid, struct cifsTconInfo *tcon)
 		temp->pinode = pinode;
 		temp->tcon = tcon;
 		temp->netfid = fid;
-		spin_lock(&GlobalMid_Lock);
-		list_add_tail(&temp->qhead, &GlobalOplock_Q);
-		spin_unlock(&GlobalMid_Lock);
+		spin_lock(&cifs_oplock_lock);
+		list_add_tail(&temp->qhead, &cifs_oplock_list);
+		spin_unlock(&cifs_oplock_lock);
 	}
 	return temp;
-
 }
 
 void DeleteOplockQEntry(struct oplock_q_entry *oplockEntry)
 {
-	spin_lock(&GlobalMid_Lock);
+	spin_lock(&cifs_oplock_lock);
     /* should we check if list empty first? */
 	list_del(&oplockEntry->qhead);
-	spin_unlock(&GlobalMid_Lock);
+	spin_unlock(&cifs_oplock_lock);
 	kmem_cache_free(cifs_oplock_cachep, oplockEntry);
 }
 
@@ -144,14 +143,14 @@ void DeleteTconOplockQEntries(struct cifsTconInfo *tcon)
 	if (tcon == NULL)
 		return;
 
-	spin_lock(&GlobalMid_Lock);
-	list_for_each_entry(temp, &GlobalOplock_Q, qhead) {
+	spin_lock(&cifs_oplock_lock);
+	list_for_each_entry(temp, &cifs_oplock_list, qhead) {
 		if ((temp->tcon) && (temp->tcon == tcon)) {
 			list_del(&temp->qhead);
 			kmem_cache_free(cifs_oplock_cachep, temp);
 		}
 	}
-	spin_unlock(&GlobalMid_Lock);
+	spin_unlock(&cifs_oplock_lock);
 }
 
 static int
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
index 618a60f..240cef1 100644
--- a/fs/dlm/lowcomms.c
+++ b/fs/dlm/lowcomms.c
@@ -106,6 +106,7 @@ struct connection {
 #define CF_CONNECT_PENDING 3
 #define CF_INIT_PENDING 4
 #define CF_IS_OTHERCON 5
+#define CF_CLOSE 6
 	struct list_head writequeue;  /* List of outgoing writequeue_entries */
 	spinlock_t writequeue_lock;
 	int (*rx_action) (struct connection *);	/* What to do when active */
@@ -299,6 +300,8 @@ static void lowcomms_write_space(struct sock *sk)
 
 static inline void lowcomms_connect_sock(struct connection *con)
 {
+	if (test_bit(CF_CLOSE, &con->flags))
+		return;
 	if (!test_and_set_bit(CF_CONNECT_PENDING, &con->flags))
 		queue_work(send_workqueue, &con->swork);
 }
@@ -926,10 +929,8 @@ static void tcp_connect_to_sock(struct connection *con)
 		goto out_err;
 
 	memset(&saddr, 0, sizeof(saddr));
-	if (dlm_nodeid_to_addr(con->nodeid, &saddr)) {
-		sock_release(sock);
+	if (dlm_nodeid_to_addr(con->nodeid, &saddr))
 		goto out_err;
-	}
 
 	sock->sk->sk_user_data = con;
 	con->rx_action = receive_from_sock;
@@ -1284,7 +1285,6 @@ out:
 static void send_to_sock(struct connection *con)
 {
 	int ret = 0;
-	ssize_t(*sendpage) (struct socket *, struct page *, int, size_t, int);
 	const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
 	struct writequeue_entry *e;
 	int len, offset;
@@ -1293,8 +1293,6 @@ static void send_to_sock(struct connection *con)
 	if (con->sock == NULL)
 		goto out_connect;
 
-	sendpage = con->sock->ops->sendpage;
-
 	spin_lock(&con->writequeue_lock);
 	for (;;) {
 		e = list_entry(con->writequeue.next, struct writequeue_entry,
@@ -1309,8 +1307,8 @@ static void send_to_sock(struct connection *con)
 
 		ret = 0;
 		if (len) {
-			ret = sendpage(con->sock, e->page, offset, len,
-				       msg_flags);
+			ret = kernel_sendpage(con->sock, e->page, offset, len,
+					      msg_flags);
 			if (ret == -EAGAIN || ret == 0) {
 				cond_resched();
 				goto out;
@@ -1370,6 +1368,13 @@ int dlm_lowcomms_close(int nodeid)
 	log_print("closing connection to node %d", nodeid);
 	con = nodeid2con(nodeid, 0);
 	if (con) {
+		clear_bit(CF_CONNECT_PENDING, &con->flags);
+		clear_bit(CF_WRITE_PENDING, &con->flags);
+		set_bit(CF_CLOSE, &con->flags);
+		if (cancel_work_sync(&con->swork))
+			log_print("canceled swork for node %d", nodeid);
+		if (cancel_work_sync(&con->rwork))
+			log_print("canceled rwork for node %d", nodeid);
 		clean_one_writequeue(con);
 		close_connection(con, true);
 	}
@@ -1395,9 +1400,10 @@ static void process_send_sockets(struct work_struct *work)
 
 	if (test_and_clear_bit(CF_CONNECT_PENDING, &con->flags)) {
 		con->connect_action(con);
+		set_bit(CF_WRITE_PENDING, &con->flags);
 	}
-	clear_bit(CF_WRITE_PENDING, &con->flags);
-	send_to_sock(con);
+	if (test_and_clear_bit(CF_WRITE_PENDING, &con->flags))
+		send_to_sock(con);
 }
 
 
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c
index ccc9d62..55ea369 100644
--- a/fs/dlm/netlink.c
+++ b/fs/dlm/netlink.c
@@ -63,7 +63,7 @@ static int send_data(struct sk_buff *skb)
 		return rv;
 	}
 
-	return genlmsg_unicast(skb, listener_nlpid);
+	return genlmsg_unicast(&init_net, skb, listener_nlpid);
 }
 
 static int user_cmd(struct sk_buff *skb, struct genl_info *info)
diff --git a/fs/exec.c b/fs/exec.c
index 172ceb6..434dba7 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -33,7 +33,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/pagemap.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/key.h>
@@ -923,7 +923,7 @@ void set_task_comm(struct task_struct *tsk, char *buf)
 	task_lock(tsk);
 	strlcpy(tsk->comm, buf, sizeof(tsk->comm));
 	task_unlock(tsk);
-	perf_counter_comm(tsk);
+	perf_event_comm(tsk);
 }
 
 int flush_old_exec(struct linux_binprm * bprm)
@@ -997,7 +997,7 @@ int flush_old_exec(struct linux_binprm * bprm)
 	 * security domain:
 	 */
 	if (!get_dumpable(current->mm))
-		perf_counter_exit_task(current);
+		perf_event_exit_task(current);
 
 	/* An exec changes our domain. We are no longer part of the thread
 	   group */
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index e271303..1c1638f 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -482,7 +482,7 @@ static int ext2_alloc_branch(struct inode *inode,
 		unlock_buffer(bh);
 		mark_buffer_dirty_inode(bh, inode);
 		/* We used to sync bh here if IS_SYNC(inode).
-		 * But we now rely upon generic_osync_inode()
+		 * But we now rely upon generic_write_sync()
 		 * and b_inode_buffers.  But not for directories.
 		 */
 		if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode))
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 2992532..388bbdf 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -51,71 +51,12 @@ static int ext3_release_file (struct inode * inode, struct file * filp)
 	return 0;
 }
 
-static ssize_t
-ext3_file_write(struct kiocb *iocb, const struct iovec *iov,
-		unsigned long nr_segs, loff_t pos)
-{
-	struct file *file = iocb->ki_filp;
-	struct inode *inode = file->f_path.dentry->d_inode;
-	ssize_t ret;
-	int err;
-
-	ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
-
-	/*
-	 * Skip flushing if there was an error, or if nothing was written.
-	 */
-	if (ret <= 0)
-		return ret;
-
-	/*
-	 * If the inode is IS_SYNC, or is O_SYNC and we are doing data
-	 * journalling then we need to make sure that we force the transaction
-	 * to disk to keep all metadata uptodate synchronously.
-	 */
-	if (file->f_flags & O_SYNC) {
-		/*
-		 * If we are non-data-journaled, then the dirty data has
-		 * already been flushed to backing store by generic_osync_inode,
-		 * and the inode has been flushed too if there have been any
-		 * modifications other than mere timestamp updates.
-		 *
-		 * Open question --- do we care about flushing timestamps too
-		 * if the inode is IS_SYNC?
-		 */
-		if (!ext3_should_journal_data(inode))
-			return ret;
-
-		goto force_commit;
-	}
-
-	/*
-	 * So we know that there has been no forced data flush.  If the inode
-	 * is marked IS_SYNC, we need to force one ourselves.
-	 */
-	if (!IS_SYNC(inode))
-		return ret;
-
-	/*
-	 * Open question #2 --- should we force data to disk here too?  If we
-	 * don't, the only impact is that data=writeback filesystems won't
-	 * flush data to disk automatically on IS_SYNC, only metadata (but
-	 * historically, that is what ext2 has done.)
-	 */
-
-force_commit:
-	err = ext3_force_commit(inode->i_sb);
-	if (err)
-		return err;
-	return ret;
-}
-
 const struct file_operations ext3_file_operations = {
 	.llseek		= generic_file_llseek,
 	.read		= do_sync_read,
 	.write		= do_sync_write,
 	.aio_read	= generic_file_aio_read,
-	.aio_write	= ext3_file_write,
+	.aio_write	= generic_file_aio_write,
 	.unlocked_ioctl	= ext3_ioctl,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= ext3_compat_ioctl,
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c
index d336341..451d166 100644
--- a/fs/ext3/fsync.c
+++ b/fs/ext3/fsync.c
@@ -23,6 +23,7 @@
  */
 
 #include <linux/time.h>
+#include <linux/blkdev.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/writeback.h>
@@ -73,7 +74,7 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
 	}
 
 	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
-		goto out;
+		goto flush;
 
 	/*
 	 * The VFS has written the file data.  If the inode is unaltered
@@ -85,7 +86,16 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
 			.nr_to_write = 0, /* sys_fsync did this */
 		};
 		ret = sync_inode(inode, &wbc);
+		goto out;
 	}
+flush:
+	/*
+	 * In case we didn't commit a transaction, we have to flush
+	 * disk caches manually so that data really is on persistent
+	 * storage
+	 */
+	if (test_opt(inode->i_sb, BARRIER))
+		blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
 out:
 	return ret;
 }
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index b49908a..cd098a7 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -172,10 +172,21 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
  * so before we call here everything must be consistently dirtied against
  * this transaction.
  */
-static int ext3_journal_test_restart(handle_t *handle, struct inode *inode)
+static int truncate_restart_transaction(handle_t *handle, struct inode *inode)
 {
+	int ret;
+
 	jbd_debug(2, "restarting handle %p\n", handle);
-	return ext3_journal_restart(handle, blocks_for_truncate(inode));
+	/*
+	 * Drop truncate_mutex to avoid deadlock with ext3_get_blocks_handle
+	 * At this moment, get_block can be called only for blocks inside
+	 * i_size since page cache has been already dropped and writes are
+	 * blocked by i_mutex. So we can safely drop the truncate_mutex.
+	 */
+	mutex_unlock(&EXT3_I(inode)->truncate_mutex);
+	ret = ext3_journal_restart(handle, blocks_for_truncate(inode));
+	mutex_lock(&EXT3_I(inode)->truncate_mutex);
+	return ret;
 }
 
 /*
@@ -2072,7 +2083,7 @@ static void ext3_clear_blocks(handle_t *handle, struct inode *inode,
 			ext3_journal_dirty_metadata(handle, bh);
 		}
 		ext3_mark_inode_dirty(handle, inode);
-		ext3_journal_test_restart(handle, inode);
+		truncate_restart_transaction(handle, inode);
 		if (bh) {
 			BUFFER_TRACE(bh, "retaking write access");
 			ext3_journal_get_write_access(handle, bh);
@@ -2282,7 +2293,7 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode,
 				return;
 			if (try_to_extend_transaction(handle, inode)) {
 				ext3_mark_inode_dirty(handle, inode);
-				ext3_journal_test_restart(handle, inode);
+				truncate_restart_transaction(handle, inode);
 			}
 
 			ext3_free_blocks(handle, inode, nr, 1);
@@ -2892,6 +2903,10 @@ static int ext3_do_update_inode(handle_t *handle,
 	struct buffer_head *bh = iloc->bh;
 	int err = 0, rc, block;
 
+again:
+	/* we can't allow multiple procs in here at once, its a bit racey */
+	lock_buffer(bh);
+
 	/* For fields not not tracking in the in-memory inode,
 	 * initialise them to zero for new inodes. */
 	if (ei->i_state & EXT3_STATE_NEW)
@@ -2951,16 +2966,20 @@ static int ext3_do_update_inode(handle_t *handle,
 			       /* If this is the first large file
 				* created, add a flag to the superblock.
 				*/
+				unlock_buffer(bh);
 				err = ext3_journal_get_write_access(handle,
 						EXT3_SB(sb)->s_sbh);
 				if (err)
 					goto out_brelse;
+
 				ext3_update_dynamic_rev(sb);
 				EXT3_SET_RO_COMPAT_FEATURE(sb,
 					EXT3_FEATURE_RO_COMPAT_LARGE_FILE);
 				handle->h_sync = 1;
 				err = ext3_journal_dirty_metadata(handle,
 						EXT3_SB(sb)->s_sbh);
+				/* get our lock and start over */
+				goto again;
 			}
 		}
 	}
@@ -2983,6 +3002,7 @@ static int ext3_do_update_inode(handle_t *handle,
 		raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
 
 	BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+	unlock_buffer(bh);
 	rc = ext3_journal_dirty_metadata(handle, bh);
 	if (!err)
 		err = rc;
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 418b6f3..d5c0ea2 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -37,7 +37,7 @@ config EXT4DEV_COMPAT
 
 	  To enable backwards compatibility so that systems that are
 	  still expecting to mount ext4 filesystems using ext4dev,
-	  chose Y here.   This feature will go away by 2.6.31, so
+	  choose Y here.   This feature will go away by 2.6.31, so
 	  please arrange to get your userspace programs fixed!
 
 config EXT4_FS_XATTR
@@ -77,3 +77,12 @@ config EXT4_FS_SECURITY
 
 	  If you are not using a security module that requires using
 	  extended attributes for file security labels, say N.
+
+config EXT4_DEBUG
+	bool "EXT4 debugging support"
+	depends on EXT4_FS
+	help
+	  Enables run-time debugging support for the ext4 filesystem.
+
+	  If you select Y here, then you will be able to turn on debugging
+	  with a command such as "echo 1 > /sys/kernel/debug/ext4/mballoc-debug"
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index e2126d7..1d04189 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -478,7 +478,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
 	 * new bitmap information
 	 */
 	set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
-	ext4_mb_update_group_info(grp, blocks_freed);
+	grp->bb_free += blocks_freed;
 	up_write(&grp->alloc_sem);
 
 	/* We dirtied the bitmap block */
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 9714db3..e227eea 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -67,27 +67,29 @@ typedef unsigned int ext4_group_t;
 
 
 /* prefer goal again. length */
-#define EXT4_MB_HINT_MERGE		1
+#define EXT4_MB_HINT_MERGE		0x0001
 /* blocks already reserved */
-#define EXT4_MB_HINT_RESERVED		2
+#define EXT4_MB_HINT_RESERVED		0x0002
 /* metadata is being allocated */
-#define EXT4_MB_HINT_METADATA		4
+#define EXT4_MB_HINT_METADATA		0x0004
 /* first blocks in the file */
-#define EXT4_MB_HINT_FIRST		8
+#define EXT4_MB_HINT_FIRST		0x0008
 /* search for the best chunk */
-#define EXT4_MB_HINT_BEST		16
+#define EXT4_MB_HINT_BEST		0x0010
 /* data is being allocated */
-#define EXT4_MB_HINT_DATA		32
+#define EXT4_MB_HINT_DATA		0x0020
 /* don't preallocate (for tails) */
-#define EXT4_MB_HINT_NOPREALLOC		64
+#define EXT4_MB_HINT_NOPREALLOC		0x0040
 /* allocate for locality group */
-#define EXT4_MB_HINT_GROUP_ALLOC	128
+#define EXT4_MB_HINT_GROUP_ALLOC	0x0080
 /* allocate goal blocks or none */
-#define EXT4_MB_HINT_GOAL_ONLY		256
+#define EXT4_MB_HINT_GOAL_ONLY		0x0100
 /* goal is meaningful */
-#define EXT4_MB_HINT_TRY_GOAL		512
+#define EXT4_MB_HINT_TRY_GOAL		0x0200
 /* blocks already pre-reserved by delayed allocation */
-#define EXT4_MB_DELALLOC_RESERVED      1024
+#define EXT4_MB_DELALLOC_RESERVED	0x0400
+/* We are doing stream allocation */
+#define EXT4_MB_STREAM_ALLOC		0x0800
 
 
 struct ext4_allocation_request {
@@ -112,6 +114,21 @@ struct ext4_allocation_request {
 };
 
 /*
+ * For delayed allocation tracking
+ */
+struct mpage_da_data {
+	struct inode *inode;
+	sector_t b_blocknr;		/* start block number of extent */
+	size_t b_size;			/* size of extent */
+	unsigned long b_state;		/* state of the extent */
+	unsigned long first_page, next_page;	/* extent of pages */
+	struct writeback_control *wbc;
+	int io_done;
+	int pages_written;
+	int retval;
+};
+
+/*
  * Special inodes numbers
  */
 #define	EXT4_BAD_INO		 1	/* Bad blocks inode */
@@ -251,7 +268,6 @@ struct flex_groups {
 #define EXT4_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
 #define EXT4_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
 #define EXT4_EXTENTS_FL			0x00080000 /* Inode uses extents */
-#define EXT4_EXT_MIGRATE		0x00100000 /* Inode is migrating */
 #define EXT4_RESERVED_FL		0x80000000 /* reserved for ext4 lib */
 
 #define EXT4_FL_USER_VISIBLE		0x000BDFFF /* User visible flags */
@@ -289,6 +305,7 @@ static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)
 #define EXT4_STATE_XATTR		0x00000004 /* has in-inode xattrs */
 #define EXT4_STATE_NO_EXPAND		0x00000008 /* No space for expansion */
 #define EXT4_STATE_DA_ALLOC_CLOSE	0x00000010 /* Alloc DA blks on close */
+#define EXT4_STATE_EXT_MIGRATE		0x00000020 /* Inode is migrating */
 
 /* Used to pass group descriptor data when online resize is done */
 struct ext4_new_group_input {
@@ -386,6 +403,9 @@ struct ext4_mount_options {
 #endif
 };
 
+/* Max physical block we can addres w/o extents */
+#define EXT4_MAX_BLOCK_FILE_PHYS	0xFFFFFFFF
+
 /*
  * Structure of an inode on the disk
  */
@@ -456,7 +476,6 @@ struct move_extent {
 	__u64 len;		/* block length to be moved */
 	__u64 moved_len;	/* moved block length */
 };
-#define MAX_DEFRAG_SIZE         ((1UL<<31) - 1)
 
 #define EXT4_EPOCH_BITS 2
 #define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1)
@@ -694,7 +713,6 @@ struct ext4_inode_info {
 #define EXT4_MOUNT_QUOTA		0x80000 /* Some quota option set */
 #define EXT4_MOUNT_USRQUOTA		0x100000 /* "old" user quota */
 #define EXT4_MOUNT_GRPQUOTA		0x200000 /* "old" group quota */
-#define EXT4_MOUNT_JOURNAL_CHECKSUM	0x800000 /* Journal checksums */
 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT	0x1000000 /* Journal Async Commit */
 #define EXT4_MOUNT_I_VERSION            0x2000000 /* i_version support */
 #define EXT4_MOUNT_DELALLOC		0x8000000 /* Delalloc support */
@@ -841,6 +859,7 @@ struct ext4_sb_info {
 	unsigned long s_gdb_count;	/* Number of group descriptor blocks */
 	unsigned long s_desc_per_block;	/* Number of group descriptors per block */
 	ext4_group_t s_groups_count;	/* Number of groups in the fs */
+	ext4_group_t s_blockfile_groups;/* Groups acceptable for non-extent files */
 	unsigned long s_overhead_last;  /* Last calculated overhead */
 	unsigned long s_blocks_last;    /* Last seen block count */
 	loff_t s_bitmap_maxbytes;	/* max bytes for bitmap files */
@@ -950,6 +969,7 @@ struct ext4_sb_info {
 	atomic_t s_mb_lost_chunks;
 	atomic_t s_mb_preallocated;
 	atomic_t s_mb_discarded;
+	atomic_t s_lock_busy;
 
 	/* locality groups */
 	struct ext4_locality_group *s_locality_groups;
@@ -1340,8 +1360,6 @@ extern void ext4_mb_free_blocks(handle_t *, struct inode *,
 		ext4_fsblk_t, unsigned long, int, unsigned long *);
 extern int ext4_mb_add_groupinfo(struct super_block *sb,
 		ext4_group_t i, struct ext4_group_desc *desc);
-extern void ext4_mb_update_group_info(struct ext4_group_info *grp,
-		ext4_grpblk_t add);
 extern int ext4_mb_get_buddy_cache_lock(struct super_block *, ext4_group_t);
 extern void ext4_mb_put_buddy_cache_lock(struct super_block *,
 						ext4_group_t, int);
@@ -1367,6 +1385,7 @@ extern int ext4_change_inode_journal_flag(struct inode *, int);
 extern int ext4_get_inode_loc(struct inode *, struct ext4_iloc *);
 extern int ext4_can_truncate(struct inode *inode);
 extern void ext4_truncate(struct inode *);
+extern int ext4_truncate_restart_trans(handle_t *, struct inode *, int nblocks);
 extern void ext4_set_inode_flags(struct inode *);
 extern void ext4_get_inode_flags(struct ext4_inode_info *);
 extern int ext4_alloc_da_blocks(struct inode *inode);
@@ -1575,15 +1594,18 @@ static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize)
 struct ext4_group_info {
 	unsigned long   bb_state;
 	struct rb_root  bb_free_root;
-	unsigned short  bb_first_free;
-	unsigned short  bb_free;
-	unsigned short  bb_fragments;
+	ext4_grpblk_t	bb_first_free;	/* first free block */
+	ext4_grpblk_t	bb_free;	/* total free blocks */
+	ext4_grpblk_t	bb_fragments;	/* nr of freespace fragments */
 	struct          list_head bb_prealloc_list;
 #ifdef DOUBLE_CHECK
 	void            *bb_bitmap;
 #endif
 	struct rw_semaphore alloc_sem;
-	unsigned short  bb_counters[];
+	ext4_grpblk_t	bb_counters[];	/* Nr of free power-of-two-block
+					 * regions, index is order.
+					 * bb_counters[3] = 5 means
+					 * 5 free 8-block regions. */
 };
 
 #define EXT4_GROUP_INFO_NEED_INIT_BIT	0
@@ -1591,15 +1613,42 @@ struct ext4_group_info {
 #define EXT4_MB_GRP_NEED_INIT(grp)	\
 	(test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state)))
 
+#define EXT4_MAX_CONTENTION		8
+#define EXT4_CONTENTION_THRESHOLD	2
+
 static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb,
 					      ext4_group_t group)
 {
 	return bgl_lock_ptr(EXT4_SB(sb)->s_blockgroup_lock, group);
 }
 
+/*
+ * Returns true if the filesystem is busy enough that attempts to
+ * access the block group locks has run into contention.
+ */
+static inline int ext4_fs_is_busy(struct ext4_sb_info *sbi)
+{
+	return (atomic_read(&sbi->s_lock_busy) > EXT4_CONTENTION_THRESHOLD);
+}
+
 static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
 {
-	spin_lock(ext4_group_lock_ptr(sb, group));
+	spinlock_t *lock = ext4_group_lock_ptr(sb, group);
+	if (spin_trylock(lock))
+		/*
+		 * We're able to grab the lock right away, so drop the
+		 * lock contention counter.
+		 */
+		atomic_add_unless(&EXT4_SB(sb)->s_lock_busy, -1, 0);
+	else {
+		/*
+		 * The lock is busy, so bump the contention counter,
+		 * and then wait on the spin lock.
+		 */
+		atomic_add_unless(&EXT4_SB(sb)->s_lock_busy, 1,
+				  EXT4_MAX_CONTENTION);
+		spin_lock(lock);
+	}
 }
 
 static inline void ext4_unlock_group(struct super_block *sb,
diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h
index 20a8410..61652f1 100644
--- a/fs/ext4/ext4_extents.h
+++ b/fs/ext4/ext4_extents.h
@@ -43,8 +43,7 @@
 #define CHECK_BINSEARCH__
 
 /*
- * If EXT_DEBUG is defined you can use the 'extdebug' mount option
- * to get lots of info about what's going on.
+ * Turn on EXT_DEBUG to get lots of info about extents operations.
  */
 #define EXT_DEBUG__
 #ifdef EXT_DEBUG
@@ -138,6 +137,7 @@ typedef int (*ext_prepare_callback)(struct inode *, struct ext4_ext_path *,
 #define EXT_BREAK      1
 #define EXT_REPEAT     2
 
+/* Maximum logical block in a file; ext4_extent's ee_block is __le32 */
 #define EXT_MAX_BLOCK	0xffffffff
 
 /*
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
index eb27fd0..6a94099 100644
--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -44,7 +44,7 @@ int __ext4_journal_forget(const char *where, handle_t *handle,
 						  handle, err);
 	}
 	else
-		brelse(bh);
+		bforget(bh);
 	return err;
 }
 
@@ -60,7 +60,7 @@ int __ext4_journal_revoke(const char *where, handle_t *handle,
 						  handle, err);
 	}
 	else
-		brelse(bh);
+		bforget(bh);
 	return err;
 }
 
@@ -89,7 +89,10 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
 			ext4_journal_abort_handle(where, __func__, bh,
 						  handle, err);
 	} else {
-		mark_buffer_dirty(bh);
+		if (inode && bh)
+			mark_buffer_dirty_inode(bh, inode);
+		else
+			mark_buffer_dirty(bh);
 		if (inode && inode_needs_sync(inode)) {
 			sync_dirty_buffer(bh);
 			if (buffer_req(bh) && !buffer_uptodate(bh)) {
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 73ebfb4..7a38325 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -93,7 +93,9 @@ static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
 	ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff);
 }
 
-static int ext4_ext_journal_restart(handle_t *handle, int needed)
+static int ext4_ext_truncate_extend_restart(handle_t *handle,
+					    struct inode *inode,
+					    int needed)
 {
 	int err;
 
@@ -104,7 +106,14 @@ static int ext4_ext_journal_restart(handle_t *handle, int needed)
 	err = ext4_journal_extend(handle, needed);
 	if (err <= 0)
 		return err;
-	return ext4_journal_restart(handle, needed);
+	err = ext4_truncate_restart_trans(handle, inode, needed);
+	/*
+	 * We have dropped i_data_sem so someone might have cached again
+	 * an extent we are going to truncate.
+	 */
+	ext4_ext_invalidate_cache(inode);
+
+	return err;
 }
 
 /*
@@ -220,57 +229,65 @@ ext4_ext_new_meta_block(handle_t *handle, struct inode *inode,
 	return newblock;
 }
 
-static int ext4_ext_space_block(struct inode *inode)
+static inline int ext4_ext_space_block(struct inode *inode, int check)
 {
 	int size;
 
 	size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
 			/ sizeof(struct ext4_extent);
+	if (!check) {
 #ifdef AGGRESSIVE_TEST
-	if (size > 6)
-		size = 6;
+		if (size > 6)
+			size = 6;
 #endif
+	}
 	return size;
 }
 
-static int ext4_ext_space_block_idx(struct inode *inode)
+static inline int ext4_ext_space_block_idx(struct inode *inode, int check)
 {
 	int size;
 
 	size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
 			/ sizeof(struct ext4_extent_idx);
+	if (!check) {
 #ifdef AGGRESSIVE_TEST
-	if (size > 5)
-		size = 5;
+		if (size > 5)
+			size = 5;
 #endif
+	}
 	return size;
 }
 
-static int ext4_ext_space_root(struct inode *inode)
+static inline int ext4_ext_space_root(struct inode *inode, int check)
 {
 	int size;
 
 	size = sizeof(EXT4_I(inode)->i_data);
 	size -= sizeof(struct ext4_extent_header);
 	size /= sizeof(struct ext4_extent);
+	if (!check) {
 #ifdef AGGRESSIVE_TEST
-	if (size > 3)
-		size = 3;
+		if (size > 3)
+			size = 3;
 #endif
+	}
 	return size;
 }
 
-static int ext4_ext_space_root_idx(struct inode *inode)
+static inline int ext4_ext_space_root_idx(struct inode *inode, int check)
 {
 	int size;
 
 	size = sizeof(EXT4_I(inode)->i_data);
 	size -= sizeof(struct ext4_extent_header);
 	size /= sizeof(struct ext4_extent_idx);
+	if (!check) {
 #ifdef AGGRESSIVE_TEST
-	if (size > 4)
-		size = 4;
+		if (size > 4)
+			size = 4;
 #endif
+	}
 	return size;
 }
 
@@ -284,9 +301,9 @@ int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks)
 	int lcap, icap, rcap, leafs, idxs, num;
 	int newextents = blocks;
 
-	rcap = ext4_ext_space_root_idx(inode);
-	lcap = ext4_ext_space_block(inode);
-	icap = ext4_ext_space_block_idx(inode);
+	rcap = ext4_ext_space_root_idx(inode, 0);
+	lcap = ext4_ext_space_block(inode, 0);
+	icap = ext4_ext_space_block_idx(inode, 0);
 
 	/* number of new leaf blocks needed */
 	num = leafs = (newextents + lcap - 1) / lcap;
@@ -311,14 +328,14 @@ ext4_ext_max_entries(struct inode *inode, int depth)
 
 	if (depth == ext_depth(inode)) {
 		if (depth == 0)
-			max = ext4_ext_space_root(inode);
+			max = ext4_ext_space_root(inode, 1);
 		else
-			max = ext4_ext_space_root_idx(inode);
+			max = ext4_ext_space_root_idx(inode, 1);
 	} else {
 		if (depth == 0)
-			max = ext4_ext_space_block(inode);
+			max = ext4_ext_space_block(inode, 1);
 		else
-			max = ext4_ext_space_block_idx(inode);
+			max = ext4_ext_space_block_idx(inode, 1);
 	}
 
 	return max;
@@ -437,8 +454,9 @@ static void ext4_ext_show_path(struct inode *inode, struct ext4_ext_path *path)
 		  ext_debug("  %d->%llu", le32_to_cpu(path->p_idx->ei_block),
 			    idx_pblock(path->p_idx));
 		} else if (path->p_ext) {
-			ext_debug("  %d:%d:%llu ",
+			ext_debug("  %d:[%d]%d:%llu ",
 				  le32_to_cpu(path->p_ext->ee_block),
+				  ext4_ext_is_uninitialized(path->p_ext),
 				  ext4_ext_get_actual_len(path->p_ext),
 				  ext_pblock(path->p_ext));
 		} else
@@ -460,8 +478,11 @@ static void ext4_ext_show_leaf(struct inode *inode, struct ext4_ext_path *path)
 	eh = path[depth].p_hdr;
 	ex = EXT_FIRST_EXTENT(eh);
 
+	ext_debug("Displaying leaf extents for inode %lu\n", inode->i_ino);
+
 	for (i = 0; i < le16_to_cpu(eh->eh_entries); i++, ex++) {
-		ext_debug("%d:%d:%llu ", le32_to_cpu(ex->ee_block),
+		ext_debug("%d:[%d]%d:%llu ", le32_to_cpu(ex->ee_block),
+			  ext4_ext_is_uninitialized(ex),
 			  ext4_ext_get_actual_len(ex), ext_pblock(ex));
 	}
 	ext_debug("\n");
@@ -580,9 +601,10 @@ ext4_ext_binsearch(struct inode *inode,
 	}
 
 	path->p_ext = l - 1;
-	ext_debug("  -> %d:%llu:%d ",
+	ext_debug("  -> %d:%llu:[%d]%d ",
 			le32_to_cpu(path->p_ext->ee_block),
 			ext_pblock(path->p_ext),
+			ext4_ext_is_uninitialized(path->p_ext),
 			ext4_ext_get_actual_len(path->p_ext));
 
 #ifdef CHECK_BINSEARCH
@@ -612,7 +634,7 @@ int ext4_ext_tree_init(handle_t *handle, struct inode *inode)
 	eh->eh_depth = 0;
 	eh->eh_entries = 0;
 	eh->eh_magic = EXT4_EXT_MAGIC;
-	eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode));
+	eh->eh_max = cpu_to_le16(ext4_ext_space_root(inode, 0));
 	ext4_mark_inode_dirty(handle, inode);
 	ext4_ext_invalidate_cache(inode);
 	return 0;
@@ -837,7 +859,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 
 	neh = ext_block_hdr(bh);
 	neh->eh_entries = 0;
-	neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode));
+	neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode, 0));
 	neh->eh_magic = EXT4_EXT_MAGIC;
 	neh->eh_depth = 0;
 	ex = EXT_FIRST_EXTENT(neh);
@@ -850,9 +872,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 	path[depth].p_ext++;
 	while (path[depth].p_ext <=
 			EXT_MAX_EXTENT(path[depth].p_hdr)) {
-		ext_debug("move %d:%llu:%d in new leaf %llu\n",
+		ext_debug("move %d:%llu:[%d]%d in new leaf %llu\n",
 				le32_to_cpu(path[depth].p_ext->ee_block),
 				ext_pblock(path[depth].p_ext),
+				ext4_ext_is_uninitialized(path[depth].p_ext),
 				ext4_ext_get_actual_len(path[depth].p_ext),
 				newblock);
 		/*memmove(ex++, path[depth].p_ext++,
@@ -912,7 +935,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 		neh = ext_block_hdr(bh);
 		neh->eh_entries = cpu_to_le16(1);
 		neh->eh_magic = EXT4_EXT_MAGIC;
-		neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode));
+		neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode, 0));
 		neh->eh_depth = cpu_to_le16(depth - i);
 		fidx = EXT_FIRST_INDEX(neh);
 		fidx->ei_block = border;
@@ -1037,9 +1060,9 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
 	/* old root could have indexes or leaves
 	 * so calculate e_max right way */
 	if (ext_depth(inode))
-	  neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode));
+		neh->eh_max = cpu_to_le16(ext4_ext_space_block_idx(inode, 0));
 	else
-	  neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode));
+		neh->eh_max = cpu_to_le16(ext4_ext_space_block(inode, 0));
 	neh->eh_magic = EXT4_EXT_MAGIC;
 	set_buffer_uptodate(bh);
 	unlock_buffer(bh);
@@ -1054,7 +1077,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
 		goto out;
 
 	curp->p_hdr->eh_magic = EXT4_EXT_MAGIC;
-	curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode));
+	curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode, 0));
 	curp->p_hdr->eh_entries = cpu_to_le16(1);
 	curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);
 
@@ -1580,9 +1603,11 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
 
 	/* try to insert block into found extent and return */
 	if (ex && ext4_can_extents_be_merged(inode, ex, newext)) {
-		ext_debug("append %d block to %d:%d (from %llu)\n",
+		ext_debug("append [%d]%d block to %d:[%d]%d (from %llu)\n",
+				ext4_ext_is_uninitialized(newext),
 				ext4_ext_get_actual_len(newext),
 				le32_to_cpu(ex->ee_block),
+				ext4_ext_is_uninitialized(ex),
 				ext4_ext_get_actual_len(ex), ext_pblock(ex));
 		err = ext4_ext_get_access(handle, inode, path + depth);
 		if (err)
@@ -1651,9 +1676,10 @@ has_space:
 
 	if (!nearex) {
 		/* there is no extent in this leaf, create first one */
-		ext_debug("first extent in the leaf: %d:%llu:%d\n",
+		ext_debug("first extent in the leaf: %d:%llu:[%d]%d\n",
 				le32_to_cpu(newext->ee_block),
 				ext_pblock(newext),
+				ext4_ext_is_uninitialized(newext),
 				ext4_ext_get_actual_len(newext));
 		path[depth].p_ext = EXT_FIRST_EXTENT(eh);
 	} else if (le32_to_cpu(newext->ee_block)
@@ -1663,10 +1689,11 @@ has_space:
 			len = EXT_MAX_EXTENT(eh) - nearex;
 			len = (len - 1) * sizeof(struct ext4_extent);
 			len = len < 0 ? 0 : len;
-			ext_debug("insert %d:%llu:%d after: nearest 0x%p, "
+			ext_debug("insert %d:%llu:[%d]%d after: nearest 0x%p, "
 					"move %d from 0x%p to 0x%p\n",
 					le32_to_cpu(newext->ee_block),
 					ext_pblock(newext),
+					ext4_ext_is_uninitialized(newext),
 					ext4_ext_get_actual_len(newext),
 					nearex, len, nearex + 1, nearex + 2);
 			memmove(nearex + 2, nearex + 1, len);
@@ -1676,10 +1703,11 @@ has_space:
 		BUG_ON(newext->ee_block == nearex->ee_block);
 		len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext4_extent);
 		len = len < 0 ? 0 : len;
-		ext_debug("insert %d:%llu:%d before: nearest 0x%p, "
+		ext_debug("insert %d:%llu:[%d]%d before: nearest 0x%p, "
 				"move %d from 0x%p to 0x%p\n",
 				le32_to_cpu(newext->ee_block),
 				ext_pblock(newext),
+				ext4_ext_is_uninitialized(newext),
 				ext4_ext_get_actual_len(newext),
 				nearex, len, nearex + 1, nearex + 2);
 		memmove(nearex + 1, nearex, len);
@@ -2094,7 +2122,8 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
 		else
 			uninitialized = 0;
 
-		ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len);
+		ext_debug("remove ext %u:[%d]%d\n", ex_ee_block,
+			 uninitialized, ex_ee_len);
 		path[depth].p_ext = ex;
 
 		a = ex_ee_block > start ? ex_ee_block : start;
@@ -2138,7 +2167,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
 		}
 		credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
 
-		err = ext4_ext_journal_restart(handle, credits);
+		err = ext4_ext_truncate_extend_restart(handle, inode, credits);
 		if (err)
 			goto out;
 
@@ -2327,7 +2356,7 @@ static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start)
 		if (err == 0) {
 			ext_inode_hdr(inode)->eh_depth = 0;
 			ext_inode_hdr(inode)->eh_max =
-				cpu_to_le16(ext4_ext_space_root(inode));
+				cpu_to_le16(ext4_ext_space_root(inode, 0));
 			err = ext4_ext_dirty(handle, inode, path);
 		}
 	}
@@ -2743,6 +2772,7 @@ insert:
 	} else if (err)
 		goto fix_extent_len;
 out:
+	ext4_ext_show_leaf(inode, path);
 	return err ? err : allocated;
 
 fix_extent_len:
@@ -2786,7 +2816,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 	struct ext4_allocation_request ar;
 
 	__clear_bit(BH_New, &bh_result->b_state);
-	ext_debug("blocks %u/%u requested for inode %u\n",
+	ext_debug("blocks %u/%u requested for inode %lu\n",
 			iblock, max_blocks, inode->i_ino);
 
 	/* check in cache */
@@ -2849,7 +2879,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 			newblock = iblock - ee_block + ee_start;
 			/* number of remaining blocks in the extent */
 			allocated = ee_len - (iblock - ee_block);
-			ext_debug("%u fit into %lu:%d -> %llu\n", iblock,
+			ext_debug("%u fit into %u:%d -> %llu\n", iblock,
 					ee_block, ee_len, newblock);
 
 			/* Do not put uninitialized extent in the cache */
@@ -2950,7 +2980,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
 	newblock = ext4_mb_new_blocks(handle, &ar, &err);
 	if (!newblock)
 		goto out2;
-	ext_debug("allocate new block: goal %llu, found %llu/%lu\n",
+	ext_debug("allocate new block: goal %llu, found %llu/%u\n",
 		  ar.goal, newblock, allocated);
 
 	/* try to insert new extent into found leaf and return */
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 27f3c53..5ca3eca 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -58,10 +58,7 @@ static ssize_t
 ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
 		unsigned long nr_segs, loff_t pos)
 {
-	struct file *file = iocb->ki_filp;
-	struct inode *inode = file->f_path.dentry->d_inode;
-	ssize_t ret;
-	int err;
+	struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
 
 	/*
 	 * If we have encountered a bitmap-format file, the size limit
@@ -81,53 +78,7 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
 		}
 	}
 
-	ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
-	/*
-	 * Skip flushing if there was an error, or if nothing was written.
-	 */
-	if (ret <= 0)
-		return ret;
-
-	/*
-	 * If the inode is IS_SYNC, or is O_SYNC and we are doing data
-	 * journalling then we need to make sure that we force the transaction
-	 * to disk to keep all metadata uptodate synchronously.
-	 */
-	if (file->f_flags & O_SYNC) {
-		/*
-		 * If we are non-data-journaled, then the dirty data has
-		 * already been flushed to backing store by generic_osync_inode,
-		 * and the inode has been flushed too if there have been any
-		 * modifications other than mere timestamp updates.
-		 *
-		 * Open question --- do we care about flushing timestamps too
-		 * if the inode is IS_SYNC?
-		 */
-		if (!ext4_should_journal_data(inode))
-			return ret;
-
-		goto force_commit;
-	}
-
-	/*
-	 * So we know that there has been no forced data flush.  If the inode
-	 * is marked IS_SYNC, we need to force one ourselves.
-	 */
-	if (!IS_SYNC(inode))
-		return ret;
-
-	/*
-	 * Open question #2 --- should we force data to disk here too?  If we
-	 * don't, the only impact is that data=writeback filesystems won't
-	 * flush data to disk automatically on IS_SYNC, only metadata (but
-	 * historically, that is what ext2 has done.)
-	 */
-
-force_commit:
-	err = ext4_force_commit(inode->i_sb);
-	if (err)
-		return err;
-	return ret;
+	return generic_file_aio_write(iocb, iov, nr_segs, pos);
 }
 
 static struct vm_operations_struct ext4_file_vm_ops = {
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 83cf641..0747574 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -50,7 +50,7 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
 {
 	struct inode *inode = dentry->d_inode;
 	journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
-	int ret = 0;
+	int err, ret = 0;
 
 	J_ASSERT(ext4_journal_current_handle() == NULL);
 
@@ -79,6 +79,9 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
 		goto out;
 	}
 
+	if (!journal)
+		ret = sync_mapping_buffers(inode->i_mapping);
+
 	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
 		goto out;
 
@@ -91,10 +94,12 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
 			.sync_mode = WB_SYNC_ALL,
 			.nr_to_write = 0, /* sys_fsync did this */
 		};
-		ret = sync_inode(inode, &wbc);
-		if (journal && (journal->j_flags & JBD2_BARRIER))
-			blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
+		err = sync_inode(inode, &wbc);
+		if (ret == 0)
+			ret = err;
 	}
 out:
+	if (journal && (journal->j_flags & JBD2_BARRIER))
+		blkdev_issue_flush(inode->i_sb->s_bdev, NULL);
 	return ret;
 }
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 29e6dc7..f3624ea 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -1189,7 +1189,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb)
 
 		x = ext4_count_free(bitmap_bh, EXT4_INODES_PER_GROUP(sb) / 8);
 		printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
-			i, ext4_free_inodes_count(sb, gdp), x);
+			(unsigned long) i, ext4_free_inodes_count(sb, gdp), x);
 		bitmap_count += x;
 	}
 	brelse(bitmap_bh);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index f9c642b..4abd683 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -192,11 +192,24 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode)
  * so before we call here everything must be consistently dirtied against
  * this transaction.
  */
-static int ext4_journal_test_restart(handle_t *handle, struct inode *inode)
+ int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
+				 int nblocks)
 {
+	int ret;
+
+	/*
+	 * Drop i_data_sem to avoid deadlock with ext4_get_blocks At this
+	 * moment, get_block can be called only for blocks inside i_size since
+	 * page cache has been already dropped and writes are blocked by
+	 * i_mutex. So we can safely drop the i_data_sem here.
+	 */
 	BUG_ON(EXT4_JOURNAL(inode) == NULL);
 	jbd_debug(2, "restarting handle %p\n", handle);
-	return ext4_journal_restart(handle, blocks_for_truncate(inode));
+	up_write(&EXT4_I(inode)->i_data_sem);
+	ret = ext4_journal_restart(handle, blocks_for_truncate(inode));
+	down_write(&EXT4_I(inode)->i_data_sem);
+
+	return ret;
 }
 
 /*
@@ -341,9 +354,7 @@ static int ext4_block_to_path(struct inode *inode,
 	int n = 0;
 	int final = 0;
 
-	if (i_block < 0) {
-		ext4_warning(inode->i_sb, "ext4_block_to_path", "block < 0");
-	} else if (i_block < direct_blocks) {
+	if (i_block < direct_blocks) {
 		offsets[n++] = i_block;
 		final = direct_blocks;
 	} else if ((i_block -= direct_blocks) < indirect_blocks) {
@@ -551,15 +562,21 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind)
  *
  *	Normally this function find the preferred place for block allocation,
  *	returns it.
+ *	Because this is only used for non-extent files, we limit the block nr
+ *	to 32 bits.
  */
 static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block,
 				   Indirect *partial)
 {
+	ext4_fsblk_t goal;
+
 	/*
 	 * XXX need to get goal block from mballoc's data structures
 	 */
 
-	return ext4_find_near(inode, partial);
+	goal = ext4_find_near(inode, partial);
+	goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
+	return goal;
 }
 
 /**
@@ -640,6 +657,8 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
 		if (*err)
 			goto failed_out;
 
+		BUG_ON(current_block + count > EXT4_MAX_BLOCK_FILE_PHYS);
+
 		target -= count;
 		/* allocate blocks for indirect blocks */
 		while (index < indirect_blks && count) {
@@ -674,6 +693,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode,
 		ar.flags = EXT4_MB_HINT_DATA;
 
 	current_block = ext4_mb_new_blocks(handle, &ar, err);
+	BUG_ON(current_block + ar.len > EXT4_MAX_BLOCK_FILE_PHYS);
 
 	if (*err && (target == blks)) {
 		/*
@@ -762,8 +782,9 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
 		BUFFER_TRACE(bh, "call get_create_access");
 		err = ext4_journal_get_create_access(handle, bh);
 		if (err) {
+			/* Don't brelse(bh) here; it's done in
+			 * ext4_journal_forget() below */
 			unlock_buffer(bh);
-			brelse(bh);
 			goto failed;
 		}
 
@@ -1109,16 +1130,15 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
 		ext4_discard_preallocations(inode);
 }
 
-static int check_block_validity(struct inode *inode, sector_t logical,
-				sector_t phys, int len)
+static int check_block_validity(struct inode *inode, const char *msg,
+				sector_t logical, sector_t phys, int len)
 {
 	if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), phys, len)) {
-		ext4_error(inode->i_sb, "check_block_validity",
+		ext4_error(inode->i_sb, msg,
 			   "inode #%lu logical block %llu mapped to %llu "
 			   "(size %d)", inode->i_ino,
 			   (unsigned long long) logical,
 			   (unsigned long long) phys, len);
-		WARN_ON(1);
 		return -EIO;
 	}
 	return 0;
@@ -1170,8 +1190,8 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
 	up_read((&EXT4_I(inode)->i_data_sem));
 
 	if (retval > 0 && buffer_mapped(bh)) {
-		int ret = check_block_validity(inode, block,
-					       bh->b_blocknr, retval);
+		int ret = check_block_validity(inode, "file system corruption",
+					       block, bh->b_blocknr, retval);
 		if (ret != 0)
 			return ret;
 	}
@@ -1235,8 +1255,7 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
 			 * i_data's format changing.  Force the migrate
 			 * to fail by clearing migrate flags
 			 */
-			EXT4_I(inode)->i_flags = EXT4_I(inode)->i_flags &
-							~EXT4_EXT_MIGRATE;
+			EXT4_I(inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE;
 		}
 	}
 
@@ -1252,8 +1271,9 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
 
 	up_write((&EXT4_I(inode)->i_data_sem));
 	if (retval > 0 && buffer_mapped(bh)) {
-		int ret = check_block_validity(inode, block,
-					       bh->b_blocknr, retval);
+		int ret = check_block_validity(inode, "file system "
+					       "corruption after allocation",
+					       block, bh->b_blocknr, retval);
 		if (ret != 0)
 			return ret;
 	}
@@ -1863,18 +1883,6 @@ static void ext4_da_page_release_reservation(struct page *page,
  * Delayed allocation stuff
  */
 
-struct mpage_da_data {
-	struct inode *inode;
-	sector_t b_blocknr;		/* start block number of extent */
-	size_t b_size;			/* size of extent */
-	unsigned long b_state;		/* state of the extent */
-	unsigned long first_page, next_page;	/* extent of pages */
-	struct writeback_control *wbc;
-	int io_done;
-	int pages_written;
-	int retval;
-};
-
 /*
  * mpage_da_submit_io - walks through extent of pages and try to write
  * them with writepage() call back
@@ -2737,6 +2745,7 @@ static int ext4_da_writepages(struct address_space *mapping,
 	long pages_skipped;
 	int range_cyclic, cycled = 1, io_done = 0;
 	int needed_blocks, ret = 0, nr_to_writebump = 0;
+	loff_t range_start = wbc->range_start;
 	struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
 
 	trace_ext4_da_writepages(inode, wbc);
@@ -2850,6 +2859,7 @@ retry:
 			mpd.io_done = 1;
 			ret = MPAGE_DA_EXTENT_TAIL;
 		}
+		trace_ext4_da_write_pages(inode, &mpd);
 		wbc->nr_to_write -= mpd.pages_written;
 
 		ext4_journal_stop(handle);
@@ -2905,6 +2915,7 @@ out_writepages:
 	if (!no_nrwrite_index_update)
 		wbc->no_nrwrite_index_update = 0;
 	wbc->nr_to_write -= nr_to_writebump;
+	wbc->range_start = range_start;
 	trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
 	return ret;
 }
@@ -3117,6 +3128,8 @@ out:
  */
 int ext4_alloc_da_blocks(struct inode *inode)
 {
+	trace_ext4_alloc_da_blocks(inode);
+
 	if (!EXT4_I(inode)->i_reserved_data_blocks &&
 	    !EXT4_I(inode)->i_reserved_meta_blocks)
 		return 0;
@@ -3659,7 +3672,8 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode,
 			ext4_handle_dirty_metadata(handle, inode, bh);
 		}
 		ext4_mark_inode_dirty(handle, inode);
-		ext4_journal_test_restart(handle, inode);
+		ext4_truncate_restart_trans(handle, inode,
+					    blocks_for_truncate(inode));
 		if (bh) {
 			BUFFER_TRACE(bh, "retaking write access");
 			ext4_journal_get_write_access(handle, bh);
@@ -3870,7 +3884,8 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
 				return;
 			if (try_to_extend_transaction(handle, inode)) {
 				ext4_mark_inode_dirty(handle, inode);
-				ext4_journal_test_restart(handle, inode);
+				ext4_truncate_restart_trans(handle, inode,
+					    blocks_for_truncate(inode));
 			}
 
 			ext4_free_blocks(handle, inode, nr, 1, 1);
@@ -3958,8 +3973,7 @@ void ext4_truncate(struct inode *inode)
 	if (!ext4_can_truncate(inode))
 		return;
 
-	if (ei->i_disksize && inode->i_size == 0 &&
-	    !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
+	if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
 		ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE;
 
 	if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
@@ -4533,7 +4547,8 @@ static int ext4_inode_blocks_set(handle_t *handle,
  */
 static int ext4_do_update_inode(handle_t *handle,
 				struct inode *inode,
-				struct ext4_iloc *iloc)
+				struct ext4_iloc *iloc,
+				int do_sync)
 {
 	struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
 	struct ext4_inode_info *ei = EXT4_I(inode);
@@ -4581,8 +4596,7 @@ static int ext4_do_update_inode(handle_t *handle,
 	if (ext4_inode_blocks_set(handle, raw_inode, ei))
 		goto out_brelse;
 	raw_inode->i_dtime = cpu_to_le32(ei->i_dtime);
-	/* clear the migrate flag in the raw_inode */
-	raw_inode->i_flags = cpu_to_le32(ei->i_flags & ~EXT4_EXT_MIGRATE);
+	raw_inode->i_flags = cpu_to_le32(ei->i_flags);
 	if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=
 	    cpu_to_le32(EXT4_OS_HURD))
 		raw_inode->i_file_acl_high =
@@ -4635,10 +4649,22 @@ static int ext4_do_update_inode(handle_t *handle,
 		raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
 	}
 
-	BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
-	rc = ext4_handle_dirty_metadata(handle, inode, bh);
-	if (!err)
-		err = rc;
+	/*
+	 * If we're not using a journal and we were called from
+	 * ext4_write_inode() to sync the inode (making do_sync true),
+	 * we can just use sync_dirty_buffer() directly to do our dirty
+	 * work.  Testing s_journal here is a bit redundant but it's
+	 * worth it to avoid potential future trouble.
+	 */
+	if (EXT4_SB(inode->i_sb)->s_journal == NULL && do_sync) {
+		BUFFER_TRACE(bh, "call sync_dirty_buffer");
+		sync_dirty_buffer(bh);
+	} else {
+		BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+		rc = ext4_handle_dirty_metadata(handle, inode, bh);
+		if (!err)
+			err = rc;
+	}
 	ei->i_state &= ~EXT4_STATE_NEW;
 
 out_brelse:
@@ -4684,19 +4710,32 @@ out_brelse:
  */
 int ext4_write_inode(struct inode *inode, int wait)
 {
+	int err;
+
 	if (current->flags & PF_MEMALLOC)
 		return 0;
 
-	if (ext4_journal_current_handle()) {
-		jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
-		dump_stack();
-		return -EIO;
-	}
+	if (EXT4_SB(inode->i_sb)->s_journal) {
+		if (ext4_journal_current_handle()) {
+			jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
+			dump_stack();
+			return -EIO;
+		}
 
-	if (!wait)
-		return 0;
+		if (!wait)
+			return 0;
+
+		err = ext4_force_commit(inode->i_sb);
+	} else {
+		struct ext4_iloc iloc;
 
-	return ext4_force_commit(inode->i_sb);
+		err = ext4_get_inode_loc(inode, &iloc);
+		if (err)
+			return err;
+		err = ext4_do_update_inode(EXT4_NOJOURNAL_HANDLE,
+					   inode, &iloc, wait);
+	}
+	return err;
 }
 
 /*
@@ -4990,7 +5029,7 @@ int ext4_mark_iloc_dirty(handle_t *handle,
 	get_bh(iloc->bh);
 
 	/* ext4_do_update_inode() does jbd2_journal_dirty_metadata */
-	err = ext4_do_update_inode(handle, inode, iloc);
+	err = ext4_do_update_inode(handle, inode, iloc, 0);
 	put_bh(iloc->bh);
 	return err;
 }
@@ -5281,12 +5320,21 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 	else
 		len = PAGE_CACHE_SIZE;
 
+	lock_page(page);
+	/*
+	 * return if we have all the buffers mapped. This avoid
+	 * the need to call write_begin/write_end which does a
+	 * journal_start/journal_stop which can block and take
+	 * long time
+	 */
 	if (page_has_buffers(page)) {
-		/* return if we have all the buffers mapped */
 		if (!walk_page_buffers(NULL, page_buffers(page), 0, len, NULL,
-				       ext4_bh_unmapped))
+					ext4_bh_unmapped)) {
+			unlock_page(page);
 			goto out_unlock;
+		}
 	}
+	unlock_page(page);
 	/*
 	 * OK, we need to fill the hole... Do write_begin write_end
 	 * to do block allocation/reservation.We are not holding
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 7050a9c..c1cdf61 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -243,10 +243,9 @@ setversion_out:
 					me.donor_start, me.len, &me.moved_len);
 		fput(donor_filp);
 
-		if (!err)
-			if (copy_to_user((struct move_extent *)arg,
-				&me, sizeof(me)))
-				return -EFAULT;
+		if (copy_to_user((struct move_extent *)arg, &me, sizeof(me)))
+			return -EFAULT;
+
 		return err;
 	}
 
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index cd25846..e9c6189 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -22,6 +22,7 @@
  */
 
 #include "mballoc.h"
+#include <linux/debugfs.h>
 #include <trace/events/ext4.h>
 
 /*
@@ -622,13 +623,13 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file,
 
 /* FIXME!! need more doc */
 static void ext4_mb_mark_free_simple(struct super_block *sb,
-				void *buddy, unsigned first, int len,
+				void *buddy, ext4_grpblk_t first, ext4_grpblk_t len,
 					struct ext4_group_info *grp)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	unsigned short min;
-	unsigned short max;
-	unsigned short chunk;
+	ext4_grpblk_t min;
+	ext4_grpblk_t max;
+	ext4_grpblk_t chunk;
 	unsigned short border;
 
 	BUG_ON(len > EXT4_BLOCKS_PER_GROUP(sb));
@@ -662,10 +663,10 @@ void ext4_mb_generate_buddy(struct super_block *sb,
 				void *buddy, void *bitmap, ext4_group_t group)
 {
 	struct ext4_group_info *grp = ext4_get_group_info(sb, group);
-	unsigned short max = EXT4_BLOCKS_PER_GROUP(sb);
-	unsigned short i = 0;
-	unsigned short first;
-	unsigned short len;
+	ext4_grpblk_t max = EXT4_BLOCKS_PER_GROUP(sb);
+	ext4_grpblk_t i = 0;
+	ext4_grpblk_t first;
+	ext4_grpblk_t len;
 	unsigned free = 0;
 	unsigned fragments = 0;
 	unsigned long long period = get_cycles();
@@ -743,7 +744,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 	char *data;
 	char *bitmap;
 
-	mb_debug("init page %lu\n", page->index);
+	mb_debug(1, "init page %lu\n", page->index);
 
 	inode = page->mapping->host;
 	sb = inode->i_sb;
@@ -822,7 +823,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 		set_bitmap_uptodate(bh[i]);
 		bh[i]->b_end_io = end_buffer_read_sync;
 		submit_bh(READ, bh[i]);
-		mb_debug("read bitmap for group %u\n", first_group + i);
+		mb_debug(1, "read bitmap for group %u\n", first_group + i);
 	}
 
 	/* wait for I/O completion */
@@ -862,12 +863,13 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 		if ((first_block + i) & 1) {
 			/* this is block of buddy */
 			BUG_ON(incore == NULL);
-			mb_debug("put buddy for group %u in page %lu/%x\n",
+			mb_debug(1, "put buddy for group %u in page %lu/%x\n",
 				group, page->index, i * blocksize);
 			grinfo = ext4_get_group_info(sb, group);
 			grinfo->bb_fragments = 0;
 			memset(grinfo->bb_counters, 0,
-			       sizeof(unsigned short)*(sb->s_blocksize_bits+2));
+			       sizeof(*grinfo->bb_counters) *
+				(sb->s_blocksize_bits+2));
 			/*
 			 * incore got set to the group block bitmap below
 			 */
@@ -878,7 +880,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
 		} else {
 			/* this is block of bitmap */
 			BUG_ON(incore != NULL);
-			mb_debug("put bitmap for group %u in page %lu/%x\n",
+			mb_debug(1, "put bitmap for group %u in page %lu/%x\n",
 				group, page->index, i * blocksize);
 
 			/* see comments in ext4_mb_put_pa() */
@@ -908,6 +910,100 @@ out:
 	return err;
 }
 
+static noinline_for_stack
+int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
+{
+
+	int ret = 0;
+	void *bitmap;
+	int blocks_per_page;
+	int block, pnum, poff;
+	int num_grp_locked = 0;
+	struct ext4_group_info *this_grp;
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct inode *inode = sbi->s_buddy_cache;
+	struct page *page = NULL, *bitmap_page = NULL;
+
+	mb_debug(1, "init group %u\n", group);
+	blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
+	this_grp = ext4_get_group_info(sb, group);
+	/*
+	 * This ensures that we don't reinit the buddy cache
+	 * page which map to the group from which we are already
+	 * allocating. If we are looking at the buddy cache we would
+	 * have taken a reference using ext4_mb_load_buddy and that
+	 * would have taken the alloc_sem lock.
+	 */
+	num_grp_locked =  ext4_mb_get_buddy_cache_lock(sb, group);
+	if (!EXT4_MB_GRP_NEED_INIT(this_grp)) {
+		/*
+		 * somebody initialized the group
+		 * return without doing anything
+		 */
+		ret = 0;
+		goto err;
+	}
+	/*
+	 * the buddy cache inode stores the block bitmap
+	 * and buddy information in consecutive blocks.
+	 * So for each group we need two blocks.
+	 */
+	block = group * 2;
+	pnum = block / blocks_per_page;
+	poff = block % blocks_per_page;
+	page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+	if (page) {
+		BUG_ON(page->mapping != inode->i_mapping);
+		ret = ext4_mb_init_cache(page, NULL);
+		if (ret) {
+			unlock_page(page);
+			goto err;
+		}
+		unlock_page(page);
+	}
+	if (page == NULL || !PageUptodate(page)) {
+		ret = -EIO;
+		goto err;
+	}
+	mark_page_accessed(page);
+	bitmap_page = page;
+	bitmap = page_address(page) + (poff * sb->s_blocksize);
+
+	/* init buddy cache */
+	block++;
+	pnum = block / blocks_per_page;
+	poff = block % blocks_per_page;
+	page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
+	if (page == bitmap_page) {
+		/*
+		 * If both the bitmap and buddy are in
+		 * the same page we don't need to force
+		 * init the buddy
+		 */
+		unlock_page(page);
+	} else if (page) {
+		BUG_ON(page->mapping != inode->i_mapping);
+		ret = ext4_mb_init_cache(page, bitmap);
+		if (ret) {
+			unlock_page(page);
+			goto err;
+		}
+		unlock_page(page);
+	}
+	if (page == NULL || !PageUptodate(page)) {
+		ret = -EIO;
+		goto err;
+	}
+	mark_page_accessed(page);
+err:
+	ext4_mb_put_buddy_cache_lock(sb, group, num_grp_locked);
+	if (bitmap_page)
+		page_cache_release(bitmap_page);
+	if (page)
+		page_cache_release(page);
+	return ret;
+}
+
 static noinline_for_stack int
 ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
 					struct ext4_buddy *e4b)
@@ -922,7 +1018,7 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct inode *inode = sbi->s_buddy_cache;
 
-	mb_debug("load group %u\n", group);
+	mb_debug(1, "load group %u\n", group);
 
 	blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
 	grp = ext4_get_group_info(sb, group);
@@ -941,8 +1037,26 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
 	 * groups mapped by the page is blocked
 	 * till we are done with allocation
 	 */
+repeat_load_buddy:
 	down_read(e4b->alloc_semp);
 
+	if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
+		/* we need to check for group need init flag
+		 * with alloc_semp held so that we can be sure
+		 * that new blocks didn't get added to the group
+		 * when we are loading the buddy cache
+		 */
+		up_read(e4b->alloc_semp);
+		/*
+		 * we need full data about the group
+		 * to make a good selection
+		 */
+		ret = ext4_mb_init_group(sb, group);
+		if (ret)
+			return ret;
+		goto repeat_load_buddy;
+	}
+
 	/*
 	 * the buddy cache inode stores the block bitmap
 	 * and buddy information in consecutive blocks.
@@ -1360,7 +1474,7 @@ static void ext4_mb_use_best_found(struct ext4_allocation_context *ac,
 	ac->alloc_semp =  e4b->alloc_semp;
 	e4b->alloc_semp = NULL;
 	/* store last allocated for subsequent stream allocation */
-	if ((ac->ac_flags & EXT4_MB_HINT_DATA)) {
+	if (ac->ac_flags & EXT4_MB_STREAM_ALLOC) {
 		spin_lock(&sbi->s_md_lock);
 		sbi->s_mb_last_group = ac->ac_f_ex.fe_group;
 		sbi->s_mb_last_start = ac->ac_f_ex.fe_start;
@@ -1837,97 +1951,6 @@ void ext4_mb_put_buddy_cache_lock(struct super_block *sb,
 
 }
 
-static noinline_for_stack
-int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
-{
-
-	int ret;
-	void *bitmap;
-	int blocks_per_page;
-	int block, pnum, poff;
-	int num_grp_locked = 0;
-	struct ext4_group_info *this_grp;
-	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	struct inode *inode = sbi->s_buddy_cache;
-	struct page *page = NULL, *bitmap_page = NULL;
-
-	mb_debug("init group %lu\n", group);
-	blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize;
-	this_grp = ext4_get_group_info(sb, group);
-	/*
-	 * This ensures we don't add group
-	 * to this buddy cache via resize
-	 */
-	num_grp_locked =  ext4_mb_get_buddy_cache_lock(sb, group);
-	if (!EXT4_MB_GRP_NEED_INIT(this_grp)) {
-		/*
-		 * somebody initialized the group
-		 * return without doing anything
-		 */
-		ret = 0;
-		goto err;
-	}
-	/*
-	 * the buddy cache inode stores the block bitmap
-	 * and buddy information in consecutive blocks.
-	 * So for each group we need two blocks.
-	 */
-	block = group * 2;
-	pnum = block / blocks_per_page;
-	poff = block % blocks_per_page;
-	page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
-	if (page) {
-		BUG_ON(page->mapping != inode->i_mapping);
-		ret = ext4_mb_init_cache(page, NULL);
-		if (ret) {
-			unlock_page(page);
-			goto err;
-		}
-		unlock_page(page);
-	}
-	if (page == NULL || !PageUptodate(page)) {
-		ret = -EIO;
-		goto err;
-	}
-	mark_page_accessed(page);
-	bitmap_page = page;
-	bitmap = page_address(page) + (poff * sb->s_blocksize);
-
-	/* init buddy cache */
-	block++;
-	pnum = block / blocks_per_page;
-	poff = block % blocks_per_page;
-	page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS);
-	if (page == bitmap_page) {
-		/*
-		 * If both the bitmap and buddy are in
-		 * the same page we don't need to force
-		 * init the buddy
-		 */
-		unlock_page(page);
-	} else if (page) {
-		BUG_ON(page->mapping != inode->i_mapping);
-		ret = ext4_mb_init_cache(page, bitmap);
-		if (ret) {
-			unlock_page(page);
-			goto err;
-		}
-		unlock_page(page);
-	}
-	if (page == NULL || !PageUptodate(page)) {
-		ret = -EIO;
-		goto err;
-	}
-	mark_page_accessed(page);
-err:
-	ext4_mb_put_buddy_cache_lock(sb, group, num_grp_locked);
-	if (bitmap_page)
-		page_cache_release(bitmap_page);
-	if (page)
-		page_cache_release(page);
-	return ret;
-}
-
 static noinline_for_stack int
 ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
 {
@@ -1938,11 +1961,14 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
 	struct ext4_sb_info *sbi;
 	struct super_block *sb;
 	struct ext4_buddy e4b;
-	loff_t size, isize;
 
 	sb = ac->ac_sb;
 	sbi = EXT4_SB(sb);
 	ngroups = ext4_get_groups_count(sb);
+	/* non-extent files are limited to low blocks/groups */
+	if (!(EXT4_I(ac->ac_inode)->i_flags & EXT4_EXTENTS_FL))
+		ngroups = sbi->s_blockfile_groups;
+
 	BUG_ON(ac->ac_status == AC_STATUS_FOUND);
 
 	/* first, try the goal */
@@ -1974,20 +2000,16 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac)
 	}
 
 	bsbits = ac->ac_sb->s_blocksize_bits;
-	/* if stream allocation is enabled, use global goal */
-	size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
-	isize = i_size_read(ac->ac_inode) >> bsbits;
-	if (size < isize)
-		size = isize;
 
-	if (size < sbi->s_mb_stream_request &&
-			(ac->ac_flags & EXT4_MB_HINT_DATA)) {
+	/* if stream allocation is enabled, use global goal */
+	if (ac->ac_flags & EXT4_MB_STREAM_ALLOC) {
 		/* TBD: may be hot point */
 		spin_lock(&sbi->s_md_lock);
 		ac->ac_g_ex.fe_group = sbi->s_mb_last_group;
 		ac->ac_g_ex.fe_start = sbi->s_mb_last_start;
 		spin_unlock(&sbi->s_md_lock);
 	}
+
 	/* Let's just scan groups to find more-less suitable blocks */
 	cr = ac->ac_2order ? 0 : 1;
 	/*
@@ -2015,27 +2037,6 @@ repeat:
 			if (grp->bb_free == 0)
 				continue;
 
-			/*
-			 * if the group is already init we check whether it is
-			 * a good group and if not we don't load the buddy
-			 */
-			if (EXT4_MB_GRP_NEED_INIT(grp)) {
-				/*
-				 * we need full data about the group
-				 * to make a good selection
-				 */
-				err = ext4_mb_init_group(sb, group);
-				if (err)
-					goto out;
-			}
-
-			/*
-			 * If the particular group doesn't satisfy our
-			 * criteria we continue with the next group
-			 */
-			if (!ext4_mb_good_group(ac, group, cr))
-				continue;
-
 			err = ext4_mb_load_buddy(sb, group, &e4b);
 			if (err)
 				goto out;
@@ -2156,7 +2157,7 @@ static int ext4_mb_seq_history_show(struct seq_file *seq, void *v)
 
 	if (v == SEQ_START_TOKEN) {
 		seq_printf(seq, "%-5s %-8s %-23s %-23s %-23s %-5s "
-				"%-5s %-2s %-5s %-5s %-5s %-6s\n",
+				"%-5s %-2s %-6s %-5s %-5s %-6s\n",
 			  "pid", "inode", "original", "goal", "result", "found",
 			   "grps", "cr", "flags", "merge", "tail", "broken");
 		return 0;
@@ -2164,7 +2165,7 @@ static int ext4_mb_seq_history_show(struct seq_file *seq, void *v)
 
 	if (hs->op == EXT4_MB_HISTORY_ALLOC) {
 		fmt = "%-5u %-8u %-23s %-23s %-23s %-5u %-5u %-2u "
-			"%-5u %-5s %-5u %-6u\n";
+			"0x%04x %-5s %-5u %-6u\n";
 		sprintf(buf2, "%u/%d/%u@%u", hs->result.fe_group,
 			hs->result.fe_start, hs->result.fe_len,
 			hs->result.fe_logical);
@@ -2205,7 +2206,7 @@ static void ext4_mb_seq_history_stop(struct seq_file *seq, void *v)
 {
 }
 
-static struct seq_operations ext4_mb_seq_history_ops = {
+static const struct seq_operations ext4_mb_seq_history_ops = {
 	.start  = ext4_mb_seq_history_start,
 	.next   = ext4_mb_seq_history_next,
 	.stop   = ext4_mb_seq_history_stop,
@@ -2287,7 +2288,7 @@ static ssize_t ext4_mb_seq_history_write(struct file *file,
 	return count;
 }
 
-static struct file_operations ext4_mb_seq_history_fops = {
+static const struct file_operations ext4_mb_seq_history_fops = {
 	.owner		= THIS_MODULE,
 	.open		= ext4_mb_seq_history_open,
 	.read		= seq_read,
@@ -2328,7 +2329,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
 	struct ext4_buddy e4b;
 	struct sg {
 		struct ext4_group_info info;
-		unsigned short counters[16];
+		ext4_grpblk_t counters[16];
 	} sg;
 
 	group--;
@@ -2366,7 +2367,7 @@ static void ext4_mb_seq_groups_stop(struct seq_file *seq, void *v)
 {
 }
 
-static struct seq_operations ext4_mb_seq_groups_ops = {
+static const struct seq_operations ext4_mb_seq_groups_ops = {
 	.start  = ext4_mb_seq_groups_start,
 	.next   = ext4_mb_seq_groups_next,
 	.stop   = ext4_mb_seq_groups_stop,
@@ -2387,7 +2388,7 @@ static int ext4_mb_seq_groups_open(struct inode *inode, struct file *file)
 
 }
 
-static struct file_operations ext4_mb_seq_groups_fops = {
+static const struct file_operations ext4_mb_seq_groups_fops = {
 	.owner		= THIS_MODULE,
 	.open		= ext4_mb_seq_groups_open,
 	.read		= seq_read,
@@ -2532,7 +2533,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
 
 	INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list);
 	init_rwsem(&meta_group_info[i]->alloc_sem);
-	meta_group_info[i]->bb_free_root.rb_node = NULL;;
+	meta_group_info[i]->bb_free_root.rb_node = NULL;
 
 #ifdef DOUBLE_CHECK
 	{
@@ -2558,26 +2559,15 @@ exit_meta_group_info:
 	return -ENOMEM;
 } /* ext4_mb_add_groupinfo */
 
-/*
- * Update an existing group.
- * This function is used for online resize
- */
-void ext4_mb_update_group_info(struct ext4_group_info *grp, ext4_grpblk_t add)
-{
-	grp->bb_free += add;
-}
-
 static int ext4_mb_init_backend(struct super_block *sb)
 {
 	ext4_group_t ngroups = ext4_get_groups_count(sb);
 	ext4_group_t i;
-	int metalen;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_super_block *es = sbi->s_es;
 	int num_meta_group_infos;
 	int num_meta_group_infos_max;
 	int array_size;
-	struct ext4_group_info **meta_group_info;
 	struct ext4_group_desc *desc;
 
 	/* This is the number of blocks used by GDT */
@@ -2622,22 +2612,6 @@ static int ext4_mb_init_backend(struct super_block *sb)
 		goto err_freesgi;
 	}
 	EXT4_I(sbi->s_buddy_cache)->i_disksize = 0;
-
-	metalen = sizeof(*meta_group_info) << EXT4_DESC_PER_BLOCK_BITS(sb);
-	for (i = 0; i < num_meta_group_infos; i++) {
-		if ((i + 1) == num_meta_group_infos)
-			metalen = sizeof(*meta_group_info) *
-				(ngroups -
-					(i << EXT4_DESC_PER_BLOCK_BITS(sb)));
-		meta_group_info = kmalloc(metalen, GFP_KERNEL);
-		if (meta_group_info == NULL) {
-			printk(KERN_ERR "EXT4-fs: can't allocate mem for a "
-			       "buddy group\n");
-			goto err_freemeta;
-		}
-		sbi->s_group_info[i] = meta_group_info;
-	}
-
 	for (i = 0; i < ngroups; i++) {
 		desc = ext4_get_group_desc(sb, i, NULL);
 		if (desc == NULL) {
@@ -2655,7 +2629,6 @@ err_freebuddy:
 	while (i-- > 0)
 		kfree(ext4_get_group_info(sb, i));
 	i = num_meta_group_infos;
-err_freemeta:
 	while (i-- > 0)
 		kfree(sbi->s_group_info[i]);
 	iput(sbi->s_buddy_cache);
@@ -2672,14 +2645,14 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
 	unsigned max;
 	int ret;
 
-	i = (sb->s_blocksize_bits + 2) * sizeof(unsigned short);
+	i = (sb->s_blocksize_bits + 2) * sizeof(*sbi->s_mb_offsets);
 
 	sbi->s_mb_offsets = kmalloc(i, GFP_KERNEL);
 	if (sbi->s_mb_offsets == NULL) {
 		return -ENOMEM;
 	}
 
-	i = (sb->s_blocksize_bits + 2) * sizeof(unsigned int);
+	i = (sb->s_blocksize_bits + 2) * sizeof(*sbi->s_mb_maxs);
 	sbi->s_mb_maxs = kmalloc(i, GFP_KERNEL);
 	if (sbi->s_mb_maxs == NULL) {
 		kfree(sbi->s_mb_offsets);
@@ -2758,7 +2731,7 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp)
 		kmem_cache_free(ext4_pspace_cachep, pa);
 	}
 	if (count)
-		mb_debug("mballoc: %u PAs left\n", count);
+		mb_debug(1, "mballoc: %u PAs left\n", count);
 
 }
 
@@ -2839,7 +2812,7 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
 	list_for_each_safe(l, ltmp, &txn->t_private_list) {
 		entry = list_entry(l, struct ext4_free_data, list);
 
-		mb_debug("gonna free %u blocks in group %u (0x%p):",
+		mb_debug(1, "gonna free %u blocks in group %u (0x%p):",
 			 entry->count, entry->group, entry);
 
 		err = ext4_mb_load_buddy(sb, entry->group, &e4b);
@@ -2874,9 +2847,43 @@ static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
 		ext4_mb_release_desc(&e4b);
 	}
 
-	mb_debug("freed %u blocks in %u structures\n", count, count2);
+	mb_debug(1, "freed %u blocks in %u structures\n", count, count2);
+}
+
+#ifdef CONFIG_EXT4_DEBUG
+u8 mb_enable_debug __read_mostly;
+
+static struct dentry *debugfs_dir;
+static struct dentry *debugfs_debug;
+
+static void __init ext4_create_debugfs_entry(void)
+{
+	debugfs_dir = debugfs_create_dir("ext4", NULL);
+	if (debugfs_dir)
+		debugfs_debug = debugfs_create_u8("mballoc-debug",
+						  S_IRUGO | S_IWUSR,
+						  debugfs_dir,
+						  &mb_enable_debug);
+}
+
+static void ext4_remove_debugfs_entry(void)
+{
+	debugfs_remove(debugfs_debug);
+	debugfs_remove(debugfs_dir);
 }
 
+#else
+
+static void __init ext4_create_debugfs_entry(void)
+{
+}
+
+static void ext4_remove_debugfs_entry(void)
+{
+}
+
+#endif
+
 int __init init_ext4_mballoc(void)
 {
 	ext4_pspace_cachep =
@@ -2904,6 +2911,7 @@ int __init init_ext4_mballoc(void)
 		kmem_cache_destroy(ext4_ac_cachep);
 		return -ENOMEM;
 	}
+	ext4_create_debugfs_entry();
 	return 0;
 }
 
@@ -2917,6 +2925,7 @@ void exit_ext4_mballoc(void)
 	kmem_cache_destroy(ext4_pspace_cachep);
 	kmem_cache_destroy(ext4_ac_cachep);
 	kmem_cache_destroy(ext4_free_ext_cachep);
+	ext4_remove_debugfs_entry();
 }
 
 
@@ -3061,7 +3070,7 @@ static void ext4_mb_normalize_group_request(struct ext4_allocation_context *ac)
 		ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_stripe;
 	else
 		ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_mb_group_prealloc;
-	mb_debug("#%u: goal %u blocks for locality group\n",
+	mb_debug(1, "#%u: goal %u blocks for locality group\n",
 		current->pid, ac->ac_g_ex.fe_len);
 }
 
@@ -3180,23 +3189,18 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
 		BUG_ON(!(ac->ac_o_ex.fe_logical >= pa_end ||
 			ac->ac_o_ex.fe_logical < pa->pa_lstart));
 
-		/* skip PA normalized request doesn't overlap with */
-		if (pa->pa_lstart >= end) {
-			spin_unlock(&pa->pa_lock);
-			continue;
-		}
-		if (pa_end <= start) {
+		/* skip PAs this normalized request doesn't overlap with */
+		if (pa->pa_lstart >= end || pa_end <= start) {
 			spin_unlock(&pa->pa_lock);
 			continue;
 		}
 		BUG_ON(pa->pa_lstart <= start && pa_end >= end);
 
+		/* adjust start or end to be adjacent to this pa */
 		if (pa_end <= ac->ac_o_ex.fe_logical) {
 			BUG_ON(pa_end < start);
 			start = pa_end;
-		}
-
-		if (pa->pa_lstart > ac->ac_o_ex.fe_logical) {
+		} else if (pa->pa_lstart > ac->ac_o_ex.fe_logical) {
 			BUG_ON(pa->pa_lstart > end);
 			end = pa->pa_lstart;
 		}
@@ -3251,7 +3255,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac,
 		ac->ac_flags |= EXT4_MB_HINT_TRY_GOAL;
 	}
 
-	mb_debug("goal: %u(was %u) blocks at %u\n", (unsigned) size,
+	mb_debug(1, "goal: %u(was %u) blocks at %u\n", (unsigned) size,
 		(unsigned) orig_size, (unsigned) start);
 }
 
@@ -3300,7 +3304,7 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac,
 	BUG_ON(pa->pa_free < len);
 	pa->pa_free -= len;
 
-	mb_debug("use %llu/%u from inode pa %p\n", start, len, pa);
+	mb_debug(1, "use %llu/%u from inode pa %p\n", start, len, pa);
 }
 
 /*
@@ -3324,7 +3328,7 @@ static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac,
 	 * in on-disk bitmap -- see ext4_mb_release_context()
 	 * Other CPUs are prevented from allocating from this pa by lg_mutex
 	 */
-	mb_debug("use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa);
+	mb_debug(1, "use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa);
 }
 
 /*
@@ -3382,6 +3386,11 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
 			ac->ac_o_ex.fe_logical >= pa->pa_lstart + pa->pa_len)
 			continue;
 
+		/* non-extent files can't have physical blocks past 2^32 */
+		if (!(EXT4_I(ac->ac_inode)->i_flags & EXT4_EXTENTS_FL) &&
+			pa->pa_pstart + pa->pa_len > EXT4_MAX_BLOCK_FILE_PHYS)
+			continue;
+
 		/* found preallocated blocks, use them */
 		spin_lock(&pa->pa_lock);
 		if (pa->pa_deleted == 0 && pa->pa_free) {
@@ -3503,7 +3512,7 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
 		preallocated += len;
 		count++;
 	}
-	mb_debug("prellocated %u for group %u\n", preallocated, group);
+	mb_debug(1, "prellocated %u for group %u\n", preallocated, group);
 }
 
 static void ext4_mb_pa_callback(struct rcu_head *head)
@@ -3638,7 +3647,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
 	pa->pa_deleted = 0;
 	pa->pa_type = MB_INODE_PA;
 
-	mb_debug("new inode pa %p: %llu/%u for %u\n", pa,
+	mb_debug(1, "new inode pa %p: %llu/%u for %u\n", pa,
 			pa->pa_pstart, pa->pa_len, pa->pa_lstart);
 	trace_ext4_mb_new_inode_pa(ac, pa);
 
@@ -3698,7 +3707,7 @@ ext4_mb_new_group_pa(struct ext4_allocation_context *ac)
 	pa->pa_deleted = 0;
 	pa->pa_type = MB_GROUP_PA;
 
-	mb_debug("new group pa %p: %llu/%u for %u\n", pa,
+	mb_debug(1, "new group pa %p: %llu/%u for %u\n", pa,
 			pa->pa_pstart, pa->pa_len, pa->pa_lstart);
 	trace_ext4_mb_new_group_pa(ac, pa);
 
@@ -3777,7 +3786,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
 		next = mb_find_next_bit(bitmap_bh->b_data, end, bit);
 		start = group * EXT4_BLOCKS_PER_GROUP(sb) + bit +
 				le32_to_cpu(sbi->s_es->s_first_data_block);
-		mb_debug("    free preallocated %u/%u in group %u\n",
+		mb_debug(1, "    free preallocated %u/%u in group %u\n",
 				(unsigned) start, (unsigned) next - bit,
 				(unsigned) group);
 		free += next - bit;
@@ -3868,7 +3877,7 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
 	int busy = 0;
 	int free = 0;
 
-	mb_debug("discard preallocation for group %u\n", group);
+	mb_debug(1, "discard preallocation for group %u\n", group);
 
 	if (list_empty(&grp->bb_prealloc_list))
 		return 0;
@@ -3992,7 +4001,7 @@ void ext4_discard_preallocations(struct inode *inode)
 		return;
 	}
 
-	mb_debug("discard preallocation for inode %lu\n", inode->i_ino);
+	mb_debug(1, "discard preallocation for inode %lu\n", inode->i_ino);
 	trace_ext4_discard_preallocations(inode);
 
 	INIT_LIST_HEAD(&list);
@@ -4097,7 +4106,7 @@ static void ext4_mb_return_to_preallocation(struct inode *inode,
 {
 	BUG_ON(!list_empty(&EXT4_I(inode)->i_prealloc_list));
 }
-#ifdef MB_DEBUG
+#ifdef CONFIG_EXT4_DEBUG
 static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
 {
 	struct super_block *sb = ac->ac_sb;
@@ -4139,14 +4148,14 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac)
 			ext4_get_group_no_and_offset(sb, pa->pa_pstart,
 						     NULL, &start);
 			spin_unlock(&pa->pa_lock);
-			printk(KERN_ERR "PA:%lu:%d:%u \n", i,
-							start, pa->pa_len);
+			printk(KERN_ERR "PA:%u:%d:%u \n", i,
+			       start, pa->pa_len);
 		}
 		ext4_unlock_group(sb, i);
 
 		if (grp->bb_free == 0)
 			continue;
-		printk(KERN_ERR "%lu: %d/%d \n",
+		printk(KERN_ERR "%u: %d/%d \n",
 		       i, grp->bb_free, grp->bb_fragments);
 	}
 	printk(KERN_ERR "\n");
@@ -4174,16 +4183,26 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
 	if (!(ac->ac_flags & EXT4_MB_HINT_DATA))
 		return;
 
+	if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
+		return;
+
 	size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
-	isize = i_size_read(ac->ac_inode) >> bsbits;
+	isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1)
+		>> bsbits;
 	size = max(size, isize);
 
-	/* don't use group allocation for large files */
-	if (size >= sbi->s_mb_stream_request)
+	if ((size == isize) &&
+	    !ext4_fs_is_busy(sbi) &&
+	    (atomic_read(&ac->ac_inode->i_writecount) == 0)) {
+		ac->ac_flags |= EXT4_MB_HINT_NOPREALLOC;
 		return;
+	}
 
-	if (unlikely(ac->ac_flags & EXT4_MB_HINT_GOAL_ONLY))
+	/* don't use group allocation for large files */
+	if (size >= sbi->s_mb_stream_request) {
+		ac->ac_flags |= EXT4_MB_STREAM_ALLOC;
 		return;
+	}
 
 	BUG_ON(ac->ac_lg != NULL);
 	/*
@@ -4246,7 +4265,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
 	 * locality group. this is a policy, actually */
 	ext4_mb_group_or_file(ac);
 
-	mb_debug("init ac: %u blocks @ %u, goal %u, flags %x, 2^%d, "
+	mb_debug(1, "init ac: %u blocks @ %u, goal %u, flags %x, 2^%d, "
 			"left: %u/%u, right %u/%u to %swritable\n",
 			(unsigned) ar->len, (unsigned) ar->logical,
 			(unsigned) ar->goal, ac->ac_flags, ac->ac_2order,
@@ -4268,7 +4287,7 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
 	struct ext4_prealloc_space *pa, *tmp;
 	struct ext4_allocation_context *ac;
 
-	mb_debug("discard locality group preallocation\n");
+	mb_debug(1, "discard locality group preallocation\n");
 
 	INIT_LIST_HEAD(&discard_list);
 	ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index c96bb19..188d3d7 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -37,11 +37,19 @@
 
 /*
  */
-#define MB_DEBUG__
-#ifdef MB_DEBUG
-#define mb_debug(fmt, a...)	printk(fmt, ##a)
+#ifdef CONFIG_EXT4_DEBUG
+extern u8 mb_enable_debug;
+
+#define mb_debug(n, fmt, a...)	                                        \
+	do {								\
+		if ((n) <= mb_enable_debug) {		        	\
+			printk(KERN_DEBUG "(%s, %d): %s: ",		\
+			       __FILE__, __LINE__, __func__);		\
+			printk(fmt, ## a);				\
+		}							\
+	} while (0)
 #else
-#define mb_debug(fmt, a...)
+#define mb_debug(n, fmt, a...)
 #endif
 
 /*
@@ -128,8 +136,8 @@ struct ext4_prealloc_space {
 	unsigned		pa_deleted;
 	ext4_fsblk_t		pa_pstart;	/* phys. block */
 	ext4_lblk_t		pa_lstart;	/* log. block */
-	unsigned short		pa_len;		/* len of preallocated chunk */
-	unsigned short		pa_free;	/* how many blocks are free */
+	ext4_grpblk_t		pa_len;		/* len of preallocated chunk */
+	ext4_grpblk_t		pa_free;	/* how many blocks are free */
 	unsigned short		pa_type;	/* pa type. inode or group */
 	spinlock_t		*pa_obj_lock;
 	struct inode		*pa_inode;	/* hack, for history only */
@@ -144,7 +152,7 @@ struct ext4_free_extent {
 	ext4_lblk_t fe_logical;
 	ext4_grpblk_t fe_start;
 	ext4_group_t fe_group;
-	int fe_len;
+	ext4_grpblk_t fe_len;
 };
 
 /*
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index 313a50b..bf519f2 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -353,17 +353,16 @@ static int ext4_ext_swap_inode_data(handle_t *handle, struct inode *inode,
 
 	down_write(&EXT4_I(inode)->i_data_sem);
 	/*
-	 * if EXT4_EXT_MIGRATE is cleared a block allocation
+	 * if EXT4_STATE_EXT_MIGRATE is cleared a block allocation
 	 * happened after we started the migrate. We need to
 	 * fail the migrate
 	 */
-	if (!(EXT4_I(inode)->i_flags & EXT4_EXT_MIGRATE)) {
+	if (!(EXT4_I(inode)->i_state & EXT4_STATE_EXT_MIGRATE)) {
 		retval = -EAGAIN;
 		up_write(&EXT4_I(inode)->i_data_sem);
 		goto err_out;
 	} else
-		EXT4_I(inode)->i_flags = EXT4_I(inode)->i_flags &
-							~EXT4_EXT_MIGRATE;
+		EXT4_I(inode)->i_state &= ~EXT4_STATE_EXT_MIGRATE;
 	/*
 	 * We have the extent map build with the tmp inode.
 	 * Now copy the i_data across
@@ -517,14 +516,15 @@ int ext4_ext_migrate(struct inode *inode)
 	 * when we add extents we extent the journal
 	 */
 	/*
-	 * Even though we take i_mutex we can still cause block allocation
-	 * via mmap write to holes. If we have allocated new blocks we fail
-	 * migrate.  New block allocation will clear EXT4_EXT_MIGRATE flag.
-	 * The flag is updated with i_data_sem held to prevent racing with
-	 * block allocation.
+	 * Even though we take i_mutex we can still cause block
+	 * allocation via mmap write to holes. If we have allocated
+	 * new blocks we fail migrate.  New block allocation will
+	 * clear EXT4_STATE_EXT_MIGRATE flag.  The flag is updated
+	 * with i_data_sem held to prevent racing with block
+	 * allocation.
 	 */
 	down_read((&EXT4_I(inode)->i_data_sem));
-	EXT4_I(inode)->i_flags = EXT4_I(inode)->i_flags | EXT4_EXT_MIGRATE;
+	EXT4_I(inode)->i_state |= EXT4_STATE_EXT_MIGRATE;
 	up_read((&EXT4_I(inode)->i_data_sem));
 
 	handle = ext4_journal_start(inode, 1);
@@ -618,7 +618,7 @@ err_out:
 	tmp_inode->i_nlink = 0;
 
 	ext4_journal_stop(handle);
-
+	unlock_new_inode(tmp_inode);
 	iput(tmp_inode);
 
 	return retval;
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index bbf2dd9..c07a291 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -19,14 +19,31 @@
 #include "ext4_extents.h"
 #include "ext4.h"
 
-#define get_ext_path(path, inode, block, ret)		\
-	do {								\
-		path = ext4_ext_find_extent(inode, block, path);	\
-		if (IS_ERR(path)) {					\
-			ret = PTR_ERR(path);				\
-			path = NULL;					\
-		}							\
-	} while (0)
+/**
+ * get_ext_path - Find an extent path for designated logical block number.
+ *
+ * @inode:	an inode which is searched
+ * @lblock:	logical block number to find an extent path
+ * @path:	pointer to an extent path pointer (for output)
+ *
+ * ext4_ext_find_extent wrapper. Return 0 on success, or a negative error value
+ * on failure.
+ */
+static inline int
+get_ext_path(struct inode *inode, ext4_lblk_t lblock,
+		struct ext4_ext_path **path)
+{
+	int ret = 0;
+
+	*path = ext4_ext_find_extent(inode, lblock, *path);
+	if (IS_ERR(*path)) {
+		ret = PTR_ERR(*path);
+		*path = NULL;
+	} else if ((*path)[ext_depth(inode)].p_ext == NULL)
+		ret = -ENODATA;
+
+	return ret;
+}
 
 /**
  * copy_extent_status - Copy the extent's initialization status
@@ -113,6 +130,31 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
 }
 
 /**
+ * mext_check_null_inode - NULL check for two inodes
+ *
+ * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
+ */
+static int
+mext_check_null_inode(struct inode *inode1, struct inode *inode2,
+		const char *function)
+{
+	int ret = 0;
+
+	if (inode1 == NULL) {
+		ext4_error(inode2->i_sb, function,
+			"Both inodes should not be NULL: "
+			"inode1 NULL inode2 %lu", inode2->i_ino);
+		ret = -EIO;
+	} else if (inode2 == NULL) {
+		ext4_error(inode1->i_sb, function,
+			"Both inodes should not be NULL: "
+			"inode1 %lu inode2 NULL", inode1->i_ino);
+		ret = -EIO;
+	}
+	return ret;
+}
+
+/**
  * mext_double_down_read - Acquire two inodes' read semaphore
  *
  * @orig_inode:		original inode structure
@@ -124,8 +166,6 @@ mext_double_down_read(struct inode *orig_inode, struct inode *donor_inode)
 {
 	struct inode *first = orig_inode, *second = donor_inode;
 
-	BUG_ON(orig_inode == NULL || donor_inode == NULL);
-
 	/*
 	 * Use the inode number to provide the stable locking order instead
 	 * of its address, because the C language doesn't guarantee you can
@@ -152,8 +192,6 @@ mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode)
 {
 	struct inode *first = orig_inode, *second = donor_inode;
 
-	BUG_ON(orig_inode == NULL || donor_inode == NULL);
-
 	/*
 	 * Use the inode number to provide the stable locking order instead
 	 * of its address, because the C language doesn't guarantee you can
@@ -178,8 +216,6 @@ mext_double_down_write(struct inode *orig_inode, struct inode *donor_inode)
 static void
 mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode)
 {
-	BUG_ON(orig_inode == NULL || donor_inode == NULL);
-
 	up_read(&EXT4_I(orig_inode)->i_data_sem);
 	up_read(&EXT4_I(donor_inode)->i_data_sem);
 }
@@ -194,8 +230,6 @@ mext_double_up_read(struct inode *orig_inode, struct inode *donor_inode)
 static void
 mext_double_up_write(struct inode *orig_inode, struct inode *donor_inode)
 {
-	BUG_ON(orig_inode == NULL || donor_inode == NULL);
-
 	up_write(&EXT4_I(orig_inode)->i_data_sem);
 	up_write(&EXT4_I(donor_inode)->i_data_sem);
 }
@@ -283,8 +317,8 @@ mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
 	}
 
 	if (new_flag) {
-		get_ext_path(orig_path, orig_inode, eblock, err);
-		if (orig_path == NULL)
+		err = get_ext_path(orig_inode, eblock, &orig_path);
+		if (err)
 			goto out;
 
 		if (ext4_ext_insert_extent(handle, orig_inode,
@@ -293,9 +327,9 @@ mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
 	}
 
 	if (end_flag) {
-		get_ext_path(orig_path, orig_inode,
-				      le32_to_cpu(end_ext->ee_block) - 1, err);
-		if (orig_path == NULL)
+		err = get_ext_path(orig_inode,
+				le32_to_cpu(end_ext->ee_block) - 1, &orig_path);
+		if (err)
 			goto out;
 
 		if (ext4_ext_insert_extent(handle, orig_inode,
@@ -519,7 +553,15 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
 	 * oext      |-----------|
 	 * new_ext       |-------|
 	 */
-	BUG_ON(le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end);
+	if (le32_to_cpu(oext->ee_block) + oext_alen - 1 < new_ext_end) {
+		ext4_error(orig_inode->i_sb, __func__,
+			"new_ext_end(%u) should be less than or equal to "
+			"oext->ee_block(%u) + oext_alen(%d) - 1",
+			new_ext_end, le32_to_cpu(oext->ee_block),
+			oext_alen);
+		ret = -EIO;
+		goto out;
+	}
 
 	/*
 	 * Case: new_ext is smaller than original extent
@@ -543,6 +585,7 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
 
 	ret = mext_insert_extents(handle, orig_inode, orig_path, o_start,
 				o_end, &start_ext, &new_ext, &end_ext);
+out:
 	return ret;
 }
 
@@ -554,8 +597,10 @@ mext_leaf_block(handle_t *handle, struct inode *orig_inode,
  * @orig_off:		block offset of original inode
  * @donor_off:		block offset of donor inode
  * @max_count:		the maximun length of extents
+ *
+ * Return 0 on success, or a negative error value on failure.
  */
-static void
+static int
 mext_calc_swap_extents(struct ext4_extent *tmp_dext,
 			      struct ext4_extent *tmp_oext,
 			      ext4_lblk_t orig_off, ext4_lblk_t donor_off,
@@ -564,6 +609,19 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
 	ext4_lblk_t diff, orig_diff;
 	struct ext4_extent dext_old, oext_old;
 
+	BUG_ON(orig_off != donor_off);
+
+	/* original and donor extents have to cover the same block offset */
+	if (orig_off < le32_to_cpu(tmp_oext->ee_block) ||
+	    le32_to_cpu(tmp_oext->ee_block) +
+			ext4_ext_get_actual_len(tmp_oext) - 1 < orig_off)
+		return -ENODATA;
+
+	if (orig_off < le32_to_cpu(tmp_dext->ee_block) ||
+	    le32_to_cpu(tmp_dext->ee_block) +
+			ext4_ext_get_actual_len(tmp_dext) - 1 < orig_off)
+		return -ENODATA;
+
 	dext_old = *tmp_dext;
 	oext_old = *tmp_oext;
 
@@ -591,6 +649,8 @@ mext_calc_swap_extents(struct ext4_extent *tmp_dext,
 
 	copy_extent_status(&oext_old, tmp_dext);
 	copy_extent_status(&dext_old, tmp_oext);
+
+	return 0;
 }
 
 /**
@@ -631,13 +691,13 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
 	mext_double_down_write(orig_inode, donor_inode);
 
 	/* Get the original extent for the block "orig_off" */
-	get_ext_path(orig_path, orig_inode, orig_off, err);
-	if (orig_path == NULL)
+	err = get_ext_path(orig_inode, orig_off, &orig_path);
+	if (err)
 		goto out;
 
 	/* Get the donor extent for the head */
-	get_ext_path(donor_path, donor_inode, donor_off, err);
-	if (donor_path == NULL)
+	err = get_ext_path(donor_inode, donor_off, &donor_path);
+	if (err)
 		goto out;
 	depth = ext_depth(orig_inode);
 	oext = orig_path[depth].p_ext;
@@ -647,13 +707,28 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
 	dext = donor_path[depth].p_ext;
 	tmp_dext = *dext;
 
-	mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
+	err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
 				      donor_off, count);
+	if (err)
+		goto out;
 
 	/* Loop for the donor extents */
 	while (1) {
 		/* The extent for donor must be found. */
-		BUG_ON(!dext || donor_off != le32_to_cpu(tmp_dext.ee_block));
+		if (!dext) {
+			ext4_error(donor_inode->i_sb, __func__,
+				   "The extent for donor must be found");
+			err = -EIO;
+			goto out;
+		} else if (donor_off != le32_to_cpu(tmp_dext.ee_block)) {
+			ext4_error(donor_inode->i_sb, __func__,
+				"Donor offset(%u) and the first block of donor "
+				"extent(%u) should be equal",
+				donor_off,
+				le32_to_cpu(tmp_dext.ee_block));
+			err = -EIO;
+			goto out;
+		}
 
 		/* Set donor extent to orig extent */
 		err = mext_leaf_block(handle, orig_inode,
@@ -678,8 +753,8 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
 
 		if (orig_path)
 			ext4_ext_drop_refs(orig_path);
-		get_ext_path(orig_path, orig_inode, orig_off, err);
-		if (orig_path == NULL)
+		err = get_ext_path(orig_inode, orig_off, &orig_path);
+		if (err)
 			goto out;
 		depth = ext_depth(orig_inode);
 		oext = orig_path[depth].p_ext;
@@ -692,9 +767,8 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
 
 		if (donor_path)
 			ext4_ext_drop_refs(donor_path);
-		get_ext_path(donor_path, donor_inode,
-				      donor_off, err);
-		if (donor_path == NULL)
+		err = get_ext_path(donor_inode, donor_off, &donor_path);
+		if (err)
 			goto out;
 		depth = ext_depth(donor_inode);
 		dext = donor_path[depth].p_ext;
@@ -705,9 +779,10 @@ mext_replace_branches(handle_t *handle, struct inode *orig_inode,
 		}
 		tmp_dext = *dext;
 
-		mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
-					      donor_off,
-					      count - replaced_count);
+		err = mext_calc_swap_extents(&tmp_dext, &tmp_oext, orig_off,
+					   donor_off, count - replaced_count);
+		if (err)
+			goto out;
 	}
 
 out:
@@ -740,7 +815,7 @@ out:
  * on success, or a negative error value on failure.
  */
 static int
-move_extent_par_page(struct file *o_filp, struct inode *donor_inode,
+move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
 		  pgoff_t orig_page_offset, int data_offset_in_page,
 		  int block_len_in_page, int uninit)
 {
@@ -871,6 +946,7 @@ out:
 		if (PageLocked(page))
 			unlock_page(page);
 		page_cache_release(page);
+		ext4_journal_stop(handle);
 	}
 out2:
 	ext4_journal_stop(handle);
@@ -897,6 +973,10 @@ mext_check_arguments(struct inode *orig_inode,
 			  struct inode *donor_inode, __u64 orig_start,
 			  __u64 donor_start, __u64 *len, __u64 moved_len)
 {
+	ext4_lblk_t orig_blocks, donor_blocks;
+	unsigned int blkbits = orig_inode->i_blkbits;
+	unsigned int blocksize = 1 << blkbits;
+
 	/* Regular file check */
 	if (!S_ISREG(orig_inode->i_mode) || !S_ISREG(donor_inode->i_mode)) {
 		ext4_debug("ext4 move extent: The argument files should be "
@@ -960,54 +1040,58 @@ mext_check_arguments(struct inode *orig_inode,
 		return -EINVAL;
 	}
 
-	if ((orig_start > MAX_DEFRAG_SIZE) ||
-	    (donor_start > MAX_DEFRAG_SIZE) ||
-	    (*len > MAX_DEFRAG_SIZE) ||
-	    (orig_start + *len > MAX_DEFRAG_SIZE))  {
-		ext4_debug("ext4 move extent: Can't handle over [%lu] blocks "
-			"[ino:orig %lu, donor %lu]\n", MAX_DEFRAG_SIZE,
+	if ((orig_start > EXT_MAX_BLOCK) ||
+	    (donor_start > EXT_MAX_BLOCK) ||
+	    (*len > EXT_MAX_BLOCK) ||
+	    (orig_start + *len > EXT_MAX_BLOCK))  {
+		ext4_debug("ext4 move extent: Can't handle over [%u] blocks "
+			"[ino:orig %lu, donor %lu]\n", EXT_MAX_BLOCK,
 			orig_inode->i_ino, donor_inode->i_ino);
 		return -EINVAL;
 	}
 
 	if (orig_inode->i_size > donor_inode->i_size) {
-		if (orig_start >= donor_inode->i_size) {
+		donor_blocks = (donor_inode->i_size + blocksize - 1) >> blkbits;
+		/* TODO: eliminate this artificial restriction */
+		if (orig_start >= donor_blocks) {
 			ext4_debug("ext4 move extent: orig start offset "
-			"[%llu] should be less than donor file size "
-			"[%lld] [ino:orig %lu, donor_inode %lu]\n",
-			orig_start, donor_inode->i_size,
+			"[%llu] should be less than donor file blocks "
+			"[%u] [ino:orig %lu, donor %lu]\n",
+			orig_start, donor_blocks,
 			orig_inode->i_ino, donor_inode->i_ino);
 			return -EINVAL;
 		}
 
-		if (orig_start + *len > donor_inode->i_size) {
+		/* TODO: eliminate this artificial restriction */
+		if (orig_start + *len > donor_blocks) {
 			ext4_debug("ext4 move extent: End offset [%llu] should "
-				"be less than donor file size [%lld]."
-				"So adjust length from %llu to %lld "
+				"be less than donor file blocks [%u]."
+				"So adjust length from %llu to %llu "
 				"[ino:orig %lu, donor %lu]\n",
-				orig_start + *len, donor_inode->i_size,
-				*len, donor_inode->i_size - orig_start,
+				orig_start + *len, donor_blocks,
+				*len, donor_blocks - orig_start,
 				orig_inode->i_ino, donor_inode->i_ino);
-			*len = donor_inode->i_size - orig_start;
+			*len = donor_blocks - orig_start;
 		}
 	} else {
-		if (orig_start >= orig_inode->i_size) {
+		orig_blocks = (orig_inode->i_size + blocksize - 1) >> blkbits;
+		if (orig_start >= orig_blocks) {
 			ext4_debug("ext4 move extent: start offset [%llu] "
-				"should be less than original file size "
-				"[%lld] [inode:orig %lu, donor %lu]\n",
-				 orig_start, orig_inode->i_size,
+				"should be less than original file blocks "
+				"[%u] [ino:orig %lu, donor %lu]\n",
+				 orig_start, orig_blocks,
 				orig_inode->i_ino, donor_inode->i_ino);
 			return -EINVAL;
 		}
 
-		if (orig_start + *len > orig_inode->i_size) {
+		if (orig_start + *len > orig_blocks) {
 			ext4_debug("ext4 move extent: Adjust length "
-				"from %llu to %lld. Because it should be "
-				"less than original file size "
+				"from %llu to %llu. Because it should be "
+				"less than original file blocks "
 				"[ino:orig %lu, donor %lu]\n",
-				*len, orig_inode->i_size - orig_start,
+				*len, orig_blocks - orig_start,
 				orig_inode->i_ino, donor_inode->i_ino);
-			*len = orig_inode->i_size - orig_start;
+			*len = orig_blocks - orig_start;
 		}
 	}
 
@@ -1027,18 +1111,23 @@ mext_check_arguments(struct inode *orig_inode,
  * @inode1:	the inode structure
  * @inode2:	the inode structure
  *
- * Lock two inodes' i_mutex by i_ino order. This function is moved from
- * fs/inode.c.
+ * Lock two inodes' i_mutex by i_ino order.
+ * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
  */
-static void
+static int
 mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
 {
-	if (inode1 == NULL || inode2 == NULL || inode1 == inode2) {
-		if (inode1)
-			mutex_lock(&inode1->i_mutex);
-		else if (inode2)
-			mutex_lock(&inode2->i_mutex);
-		return;
+	int ret = 0;
+
+	BUG_ON(inode1 == NULL && inode2 == NULL);
+
+	ret = mext_check_null_inode(inode1, inode2, __func__);
+	if (ret < 0)
+		goto out;
+
+	if (inode1 == inode2) {
+		mutex_lock(&inode1->i_mutex);
+		goto out;
 	}
 
 	if (inode1->i_ino < inode2->i_ino) {
@@ -1048,6 +1137,9 @@ mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
 		mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
 		mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
 	}
+
+out:
+	return ret;
 }
 
 /**
@@ -1056,17 +1148,28 @@ mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
  * @inode1:     the inode that is released first
  * @inode2:     the inode that is released second
  *
- * This function is moved from fs/inode.c.
+ * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
  */
 
-static void
+static int
 mext_inode_double_unlock(struct inode *inode1, struct inode *inode2)
 {
+	int ret = 0;
+
+	BUG_ON(inode1 == NULL && inode2 == NULL);
+
+	ret = mext_check_null_inode(inode1, inode2, __func__);
+	if (ret < 0)
+		goto out;
+
 	if (inode1)
 		mutex_unlock(&inode1->i_mutex);
 
 	if (inode2 && inode2 != inode1)
 		mutex_unlock(&inode2->i_mutex);
+
+out:
+	return ret;
 }
 
 /**
@@ -1123,70 +1226,76 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
 	ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
 	ext4_lblk_t rest_blocks;
 	pgoff_t orig_page_offset = 0, seq_end_page;
-	int ret, depth, last_extent = 0;
+	int ret1, ret2, depth, last_extent = 0;
 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 	int data_offset_in_page;
 	int block_len_in_page;
 	int uninit;
 
 	/* protect orig and donor against a truncate */
-	mext_inode_double_lock(orig_inode, donor_inode);
+	ret1 = mext_inode_double_lock(orig_inode, donor_inode);
+	if (ret1 < 0)
+		return ret1;
 
 	mext_double_down_read(orig_inode, donor_inode);
 	/* Check the filesystem environment whether move_extent can be done */
-	ret = mext_check_arguments(orig_inode, donor_inode, orig_start,
+	ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
 					donor_start, &len, *moved_len);
 	mext_double_up_read(orig_inode, donor_inode);
-	if (ret)
-		goto out2;
+	if (ret1)
+		goto out;
 
 	file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits;
 	block_end = block_start + len - 1;
 	if (file_end < block_end)
 		len -= block_end - file_end;
 
-	get_ext_path(orig_path, orig_inode, block_start, ret);
-	if (orig_path == NULL)
-		goto out2;
+	ret1 = get_ext_path(orig_inode, block_start, &orig_path);
+	if (ret1)
+		goto out;
 
 	/* Get path structure to check the hole */
-	get_ext_path(holecheck_path, orig_inode, block_start, ret);
-	if (holecheck_path == NULL)
+	ret1 = get_ext_path(orig_inode, block_start, &holecheck_path);
+	if (ret1)
 		goto out;
 
 	depth = ext_depth(orig_inode);
 	ext_cur = holecheck_path[depth].p_ext;
-	if (ext_cur == NULL) {
-		ret = -EINVAL;
-		goto out;
-	}
 
 	/*
-	 * Get proper extent whose ee_block is beyond block_start
-	 * if block_start was within the hole.
+	 * Get proper starting location of block replacement if block_start was
+	 * within the hole.
 	 */
 	if (le32_to_cpu(ext_cur->ee_block) +
 		ext4_ext_get_actual_len(ext_cur) - 1 < block_start) {
+		/*
+		 * The hole exists between extents or the tail of
+		 * original file.
+		 */
 		last_extent = mext_next_extent(orig_inode,
 					holecheck_path, &ext_cur);
 		if (last_extent < 0) {
-			ret = last_extent;
+			ret1 = last_extent;
 			goto out;
 		}
 		last_extent = mext_next_extent(orig_inode, orig_path,
 							&ext_dummy);
 		if (last_extent < 0) {
-			ret = last_extent;
+			ret1 = last_extent;
 			goto out;
 		}
-	}
-	seq_start = block_start;
+		seq_start = le32_to_cpu(ext_cur->ee_block);
+	} else if (le32_to_cpu(ext_cur->ee_block) > block_start)
+		/* The hole exists at the beginning of original file. */
+		seq_start = le32_to_cpu(ext_cur->ee_block);
+	else
+		seq_start = block_start;
 
 	/* No blocks within the specified range. */
 	if (le32_to_cpu(ext_cur->ee_block) > block_end) {
 		ext4_debug("ext4 move extent: The specified range of file "
 							"may be the hole\n");
-		ret = -EINVAL;
+		ret1 = -EINVAL;
 		goto out;
 	}
 
@@ -1206,7 +1315,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
 		last_extent = mext_next_extent(orig_inode, holecheck_path,
 						&ext_cur);
 		if (last_extent < 0) {
-			ret = last_extent;
+			ret1 = last_extent;
 			break;
 		}
 		add_blocks = ext4_ext_get_actual_len(ext_cur);
@@ -1258,16 +1367,23 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
 		while (orig_page_offset <= seq_end_page) {
 
 			/* Swap original branches with new branches */
-			ret = move_extent_par_page(o_filp, donor_inode,
+			ret1 = move_extent_per_page(o_filp, donor_inode,
 						orig_page_offset,
 						data_offset_in_page,
 						block_len_in_page, uninit);
-			if (ret < 0)
+			if (ret1 < 0)
 				goto out;
 			orig_page_offset++;
 			/* Count how many blocks we have exchanged */
 			*moved_len += block_len_in_page;
-			BUG_ON(*moved_len > len);
+			if (*moved_len > len) {
+				ext4_error(orig_inode->i_sb, __func__,
+					"We replaced blocks too much! "
+					"sum of replaced: %llu requested: %llu",
+					*moved_len, len);
+				ret1 = -EIO;
+				goto out;
+			}
 
 			data_offset_in_page = 0;
 			rest_blocks -= block_len_in_page;
@@ -1280,17 +1396,16 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
 		/* Decrease buffer counter */
 		if (holecheck_path)
 			ext4_ext_drop_refs(holecheck_path);
-		get_ext_path(holecheck_path, orig_inode,
-				      seq_start, ret);
-		if (holecheck_path == NULL)
+		ret1 = get_ext_path(orig_inode, seq_start, &holecheck_path);
+		if (ret1)
 			break;
 		depth = holecheck_path->p_depth;
 
 		/* Decrease buffer counter */
 		if (orig_path)
 			ext4_ext_drop_refs(orig_path);
-		get_ext_path(orig_path, orig_inode, seq_start, ret);
-		if (orig_path == NULL)
+		ret1 = get_ext_path(orig_inode, seq_start, &orig_path);
+		if (ret1)
 			break;
 
 		ext_cur = holecheck_path[depth].p_ext;
@@ -1307,14 +1422,13 @@ out:
 		ext4_ext_drop_refs(holecheck_path);
 		kfree(holecheck_path);
 	}
-out2:
-	mext_inode_double_unlock(orig_inode, donor_inode);
 
-	if (ret)
-		return ret;
+	ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
 
-	/* All of the specified blocks must be exchanged in succeed */
-	BUG_ON(*moved_len != len);
+	if (ret1)
+		return ret1;
+	else if (ret2)
+		return ret2;
 
 	return 0;
 }
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 114abe5..42f81d2 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1518,8 +1518,12 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
 			return retval;
 
 		if (blocks == 1 && !dx_fallback &&
-		    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
-			return make_indexed_dir(handle, dentry, inode, bh);
+		    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
+			retval = make_indexed_dir(handle, dentry, inode, bh);
+			if (retval == -ENOSPC)
+				brelse(bh);
+			return retval;
+		}
 		brelse(bh);
 	}
 	bh = ext4_append(handle, dir, &block, &retval);
@@ -1528,7 +1532,10 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
 	de = (struct ext4_dir_entry_2 *) bh->b_data;
 	de->inode = 0;
 	de->rec_len = ext4_rec_len_to_disk(blocksize, blocksize);
-	return add_dirent_to_buf(handle, dentry, inode, de, bh);
+	retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
+	if (retval == -ENOSPC)
+		brelse(bh);
+	return retval;
 }
 
 /*
@@ -1590,9 +1597,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
 			goto cleanup;
 		node2 = (struct dx_node *)(bh2->b_data);
 		entries2 = node2->entries;
+		memset(&node2->fake, 0, sizeof(struct fake_dirent));
 		node2->fake.rec_len = ext4_rec_len_to_disk(sb->s_blocksize,
 							   sb->s_blocksize);
-		node2->fake.inode = 0;
 		BUFFER_TRACE(frame->bh, "get_write_access");
 		err = ext4_journal_get_write_access(handle, frame->bh);
 		if (err)
@@ -1657,7 +1664,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
 	if (!de)
 		goto cleanup;
 	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
-	bh = NULL;
+	if (err != -ENOSPC)
+		bh = NULL;
 	goto cleanup;
 
 journal_error:
@@ -2310,7 +2318,7 @@ static int ext4_link(struct dentry *old_dentry,
 	struct inode *inode = old_dentry->d_inode;
 	int err, retries = 0;
 
-	if (EXT4_DIR_LINK_MAX(inode))
+	if (inode->i_nlink >= EXT4_LINK_MAX)
 		return -EMLINK;
 
 	/*
@@ -2413,7 +2421,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
 			goto end_rename;
 		retval = -EMLINK;
 		if (!new_inode && new_dir != old_dir &&
-				new_dir->i_nlink >= EXT4_LINK_MAX)
+		    EXT4_DIR_LINK_MAX(new_dir))
 			goto end_rename;
 	}
 	if (!new_bh) {
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 68b0351..3cfc343 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -746,7 +746,6 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 	struct inode *inode = NULL;
 	handle_t *handle;
 	int gdb_off, gdb_num;
-	int num_grp_locked = 0;
 	int err, err2;
 
 	gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
@@ -856,7 +855,6 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
          * using the new disk blocks.
          */
 
-	num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, input->group);
 	/* Update group descriptor block for new group */
 	gdp = (struct ext4_group_desc *)((char *)primary->b_data +
 					 gdb_off * EXT4_DESC_SIZE(sb));
@@ -875,10 +873,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 	 * descriptor
 	 */
 	err = ext4_mb_add_groupinfo(sb, input->group, gdp);
-	if (err) {
-		ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked);
+	if (err)
 		goto exit_journal;
-	}
 
 	/*
 	 * Make the new blocks and inodes valid next.  We do this before
@@ -920,7 +916,6 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 
 	/* Update the global fs size fields */
 	sbi->s_groups_count++;
-	ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked);
 
 	ext4_handle_dirty_metadata(handle, NULL, primary);
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 8f4f079..a6b1ab7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -45,6 +45,7 @@
 #include "ext4_jbd2.h"
 #include "xattr.h"
 #include "acl.h"
+#include "mballoc.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/ext4.h>
@@ -344,7 +345,8 @@ static const char *ext4_decode_error(struct super_block *sb, int errno,
 		errstr = "Out of memory";
 		break;
 	case -EROFS:
-		if (!sb || EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT)
+		if (!sb || (EXT4_SB(sb)->s_journal &&
+			    EXT4_SB(sb)->s_journal->j_flags & JBD2_ABORT))
 			errstr = "Journal has aborted";
 		else
 			errstr = "Readonly filesystem";
@@ -1279,11 +1281,9 @@ static int parse_options(char *options, struct super_block *sb,
 			*journal_devnum = option;
 			break;
 		case Opt_journal_checksum:
-			set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
-			break;
+			break;	/* Kept for backwards compatibility */
 		case Opt_journal_async_commit:
 			set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT);
-			set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM);
 			break;
 		case Opt_noload:
 			set_opt(sbi->s_mount_opt, NOLOAD);
@@ -1695,12 +1695,12 @@ static int ext4_fill_flex_info(struct super_block *sb)
 		gdp = ext4_get_group_desc(sb, i, NULL);
 
 		flex_group = ext4_flex_group(sbi, i);
-		atomic_set(&sbi->s_flex_groups[flex_group].free_inodes,
-			   ext4_free_inodes_count(sb, gdp));
-		atomic_set(&sbi->s_flex_groups[flex_group].free_blocks,
-			   ext4_free_blks_count(sb, gdp));
-		atomic_set(&sbi->s_flex_groups[flex_group].used_dirs,
-			   ext4_used_dirs_count(sb, gdp));
+		atomic_add(ext4_free_inodes_count(sb, gdp),
+			   &sbi->s_flex_groups[flex_group].free_inodes);
+		atomic_add(ext4_free_blks_count(sb, gdp),
+			   &sbi->s_flex_groups[flex_group].free_blocks);
+		atomic_add(ext4_used_dirs_count(sb, gdp),
+			   &sbi->s_flex_groups[flex_group].used_dirs);
 	}
 
 	return 1;
@@ -2253,6 +2253,49 @@ static struct kobj_type ext4_ktype = {
 	.release	= ext4_sb_release,
 };
 
+/*
+ * Check whether this filesystem can be mounted based on
+ * the features present and the RDONLY/RDWR mount requested.
+ * Returns 1 if this filesystem can be mounted as requested,
+ * 0 if it cannot be.
+ */
+static int ext4_feature_set_ok(struct super_block *sb, int readonly)
+{
+	if (EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP)) {
+		ext4_msg(sb, KERN_ERR,
+			"Couldn't mount because of "
+			"unsupported optional features (%x)",
+			(le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_incompat) &
+			~EXT4_FEATURE_INCOMPAT_SUPP));
+		return 0;
+	}
+
+	if (readonly)
+		return 1;
+
+	/* Check that feature set is OK for a read-write mount */
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP)) {
+		ext4_msg(sb, KERN_ERR, "couldn't mount RDWR because of "
+			 "unsupported optional features (%x)",
+			 (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) &
+				~EXT4_FEATURE_RO_COMPAT_SUPP));
+		return 0;
+	}
+	/*
+	 * Large file size enabled file system can only be mounted
+	 * read-write on 32-bit systems if kernel is built with CONFIG_LBDAF
+	 */
+	if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
+		if (sizeof(blkcnt_t) < sizeof(u64)) {
+			ext4_msg(sb, KERN_ERR, "Filesystem with huge files "
+				 "cannot be mounted RDWR without "
+				 "CONFIG_LBDAF");
+			return 0;
+		}
+	}
+	return 1;
+}
+
 static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 				__releases(kernel_lock)
 				__acquires(kernel_lock)
@@ -2274,7 +2317,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	unsigned int db_count;
 	unsigned int i;
 	int needs_recovery, has_huge_files;
-	int features;
 	__u64 blocks_count;
 	int err;
 	unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
@@ -2401,39 +2443,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 	 * previously didn't change the revision level when setting the flags,
 	 * so there is a chance incompat flags are set on a rev 0 filesystem.
 	 */
-	features = EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP);
-	if (features) {
-		ext4_msg(sb, KERN_ERR,
-			"Couldn't mount because of "
-			"unsupported optional features (%x)",
-			(le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_incompat) &
-			~EXT4_FEATURE_INCOMPAT_SUPP));
-		goto failed_mount;
-	}
-	features = EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP);
-	if (!(sb->s_flags & MS_RDONLY) && features) {
-		ext4_msg(sb, KERN_ERR,
-			"Couldn't mount RDWR because of "
-			"unsupported optional features (%x)",
-			(le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) &
-			~EXT4_FEATURE_RO_COMPAT_SUPP));
+	if (!ext4_feature_set_ok(sb, (sb->s_flags & MS_RDONLY)))
 		goto failed_mount;
-	}
-	has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb,
-				    EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
-	if (has_huge_files) {
-		/*
-		 * Large file size enabled file system can only be
-		 * mount if kernel is build with CONFIG_LBDAF
-		 */
-		if (sizeof(root->i_blocks) < sizeof(u64) &&
-				!(sb->s_flags & MS_RDONLY)) {
-			ext4_msg(sb, KERN_ERR, "Filesystem with huge "
-					"files cannot be mounted read-write "
-					"without CONFIG_LBDAF");
-			goto failed_mount;
-		}
-	}
+
 	blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size);
 
 	if (blocksize < EXT4_MIN_BLOCK_SIZE ||
@@ -2469,6 +2481,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		}
 	}
 
+	has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb,
+				EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
 	sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits,
 						      has_huge_files);
 	sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
@@ -2549,12 +2563,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		goto failed_mount;
 	}
 
-	if (ext4_blocks_count(es) >
-		    (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) {
+	/*
+	 * Test whether we have more sectors than will fit in sector_t,
+	 * and whether the max offset is addressable by the page cache.
+	 */
+	if ((ext4_blocks_count(es) >
+	     (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) ||
+	    (ext4_blocks_count(es) >
+	     (pgoff_t)(~0ULL) >> (PAGE_CACHE_SHIFT - sb->s_blocksize_bits))) {
 		ext4_msg(sb, KERN_ERR, "filesystem"
-			" too large to mount safely");
+			 " too large to mount safely on this system");
 		if (sizeof(sector_t) < 8)
 			ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled");
+		ret = -EFBIG;
 		goto failed_mount;
 	}
 
@@ -2595,6 +2616,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		goto failed_mount;
 	}
 	sbi->s_groups_count = blocks_count;
+	sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count,
+			(EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb)));
 	db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
 		   EXT4_DESC_PER_BLOCK(sb);
 	sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *),
@@ -2729,20 +2752,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		goto failed_mount4;
 	}
 
-	if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) {
-		jbd2_journal_set_features(sbi->s_journal,
-				JBD2_FEATURE_COMPAT_CHECKSUM, 0,
+	jbd2_journal_set_features(sbi->s_journal,
+				  JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0);
+	if (test_opt(sb, JOURNAL_ASYNC_COMMIT))
+		jbd2_journal_set_features(sbi->s_journal, 0, 0,
 				JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
-	} else if (test_opt(sb, JOURNAL_CHECKSUM)) {
-		jbd2_journal_set_features(sbi->s_journal,
-				JBD2_FEATURE_COMPAT_CHECKSUM, 0, 0);
+	else
 		jbd2_journal_clear_features(sbi->s_journal, 0, 0,
 				JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
-	} else {
-		jbd2_journal_clear_features(sbi->s_journal,
-				JBD2_FEATURE_COMPAT_CHECKSUM, 0,
-				JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT);
-	}
 
 	/* We have now updated the journal if required, so we can
 	 * validate the data journaling mode. */
@@ -3208,7 +3225,18 @@ static int ext4_commit_super(struct super_block *sb, int sync)
 		clear_buffer_write_io_error(sbh);
 		set_buffer_uptodate(sbh);
 	}
-	es->s_wtime = cpu_to_le32(get_seconds());
+	/*
+	 * If the file system is mounted read-only, don't update the
+	 * superblock write time.  This avoids updating the superblock
+	 * write time when we are mounting the root file system
+	 * read/only but we need to replay the journal; at that point,
+	 * for people who are east of GMT and who make their clock
+	 * tick in localtime for Windows bug-for-bug compatibility,
+	 * the clock is set in the future, and this will cause e2fsck
+	 * to complain and force a full file system check.
+	 */
+	if (!(sb->s_flags & MS_RDONLY))
+		es->s_wtime = cpu_to_le32(get_seconds());
 	es->s_kbytes_written =
 		cpu_to_le64(EXT4_SB(sb)->s_kbytes_written + 
 			    ((part_stat_read(sb->s_bdev->bd_part, sectors[1]) -
@@ -3477,18 +3505,11 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
 			if (sbi->s_journal)
 				ext4_mark_recovery_complete(sb, es);
 		} else {
-			int ret;
-			if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb,
-					~EXT4_FEATURE_RO_COMPAT_SUPP))) {
-				ext4_msg(sb, KERN_WARNING, "couldn't "
-				       "remount RDWR because of unsupported "
-				       "optional features (%x)",
-				(le32_to_cpu(sbi->s_es->s_feature_ro_compat) &
-					~EXT4_FEATURE_RO_COMPAT_SUPP));
+			/* Make sure we can mount this feature set readwrite */
+			if (!ext4_feature_set_ok(sb, 0)) {
 				err = -EROFS;
 				goto restore_opts;
 			}
-
 			/*
 			 * Make sure the group descriptor checksums
 			 * are sane.  If they aren't, refuse to remount r/w.
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 62b31c2..fed5b01 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -810,12 +810,23 @@ inserted:
 			get_bh(new_bh);
 		} else {
 			/* We need to allocate a new block */
-			ext4_fsblk_t goal = ext4_group_first_block_no(sb,
+			ext4_fsblk_t goal, block;
+
+			goal = ext4_group_first_block_no(sb,
 						EXT4_I(inode)->i_block_group);
-			ext4_fsblk_t block = ext4_new_meta_blocks(handle, inode,
+
+			/* non-extent files can't have physical blocks past 2^32 */
+			if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
+				goal = goal & EXT4_MAX_BLOCK_FILE_PHYS;
+
+			block = ext4_new_meta_blocks(handle, inode,
 						  goal, NULL, &error);
 			if (error)
 				goto cleanup;
+
+			if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
+				BUG_ON(block > EXT4_MAX_BLOCK_FILE_PHYS);
+
 			ea_idebug(inode, "creating block %d", block);
 
 			new_bh = sb_getblk(sb, block);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index f042b96..e8c159d 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -176,8 +176,26 @@ static int fat_cont_expand(struct inode *inode, loff_t size)
 
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
-	if (IS_SYNC(inode))
-		err = sync_page_range_nolock(inode, mapping, start, count);
+	if (IS_SYNC(inode)) {
+		int err2;
+
+		/*
+		 * Opencode syncing since we don't have a file open to use
+		 * standard fsync path.
+		 */
+		err = filemap_fdatawrite_range(mapping, start,
+					       start + count - 1);
+		err2 = sync_mapping_buffers(mapping);
+		if (!err)
+			err = err2;
+		err2 = write_inode_now(inode, 1);
+		if (!err)
+			err = err2;
+		if (!err) {
+			err =  filemap_fdatawait_range(mapping, start,
+						       start + count - 1);
+		}
+	}
 out:
 	return err;
 }
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index a6c2047..4e35be8 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -119,8 +119,8 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster)
 		MSDOS_I(inode)->i_start = new_dclus;
 		MSDOS_I(inode)->i_logstart = new_dclus;
 		/*
-		 * Since generic_osync_inode() synchronize later if
-		 * this is not directory, we don't here.
+		 * Since generic_write_sync() synchronizes regular files later,
+		 * we sync here only directories.
 		 */
 		if (S_ISDIR(inode->i_mode) && IS_DIRSYNC(inode)) {
 			ret = fat_sync_inode(inode);
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index da86ef5..8e1e5e1 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -35,21 +35,29 @@
 int nr_pdflush_threads;
 
 /*
+ * Passed into wb_writeback(), essentially a subset of writeback_control
+ */
+struct wb_writeback_args {
+	long nr_pages;
+	struct super_block *sb;
+	enum writeback_sync_modes sync_mode;
+	int for_kupdate;
+	int range_cyclic;
+};
+
+/*
  * Work items for the bdi_writeback threads
  */
 struct bdi_work {
-	struct list_head list;
-	struct list_head wait_list;
-	struct rcu_head rcu_head;
+	struct list_head list;		/* pending work list */
+	struct rcu_head rcu_head;	/* for RCU free/clear of work */
 
-	unsigned long seen;
-	atomic_t pending;
+	unsigned long seen;		/* threads that have seen this work */
+	atomic_t pending;		/* number of threads still to do work */
 
-	struct super_block *sb;
-	unsigned long nr_pages;
-	enum writeback_sync_modes sync_mode;
+	struct wb_writeback_args args;	/* writeback arguments */
 
-	unsigned long state;
+	unsigned long state;		/* flag bits, see WS_* */
 };
 
 enum {
@@ -66,22 +74,13 @@ static inline bool bdi_work_on_stack(struct bdi_work *work)
 }
 
 static inline void bdi_work_init(struct bdi_work *work,
-				 struct writeback_control *wbc)
+				 struct wb_writeback_args *args)
 {
 	INIT_RCU_HEAD(&work->rcu_head);
-	work->sb = wbc->sb;
-	work->nr_pages = wbc->nr_to_write;
-	work->sync_mode = wbc->sync_mode;
+	work->args = *args;
 	work->state = WS_USED;
 }
 
-static inline void bdi_work_init_on_stack(struct bdi_work *work,
-					  struct writeback_control *wbc)
-{
-	bdi_work_init(work, wbc);
-	work->state |= WS_ONSTACK;
-}
-
 /**
  * writeback_in_progress - determine whether there is writeback in progress
  * @bdi: the device's backing_dev_info structure.
@@ -98,6 +97,11 @@ static void bdi_work_clear(struct bdi_work *work)
 {
 	clear_bit(WS_USED_B, &work->state);
 	smp_mb__after_clear_bit();
+	/*
+	 * work can have disappeared at this point. bit waitq functions
+	 * should be able to tolerate this, provided bdi_sched_wait does
+	 * not dereference it's pointer argument.
+	*/
 	wake_up_bit(&work->state, WS_USED_B);
 }
 
@@ -113,7 +117,8 @@ static void bdi_work_free(struct rcu_head *head)
 
 static void wb_work_complete(struct bdi_work *work)
 {
-	const enum writeback_sync_modes sync_mode = work->sync_mode;
+	const enum writeback_sync_modes sync_mode = work->args.sync_mode;
+	int onstack = bdi_work_on_stack(work);
 
 	/*
 	 * For allocated work, we can clear the done/seen bit right here.
@@ -121,9 +126,9 @@ static void wb_work_complete(struct bdi_work *work)
 	 * to after the RCU grace period, since the stack could be invalidated
 	 * as soon as bdi_work_clear() has done the wakeup.
 	 */
-	if (!bdi_work_on_stack(work))
+	if (!onstack)
 		bdi_work_clear(work);
-	if (sync_mode == WB_SYNC_NONE || bdi_work_on_stack(work))
+	if (sync_mode == WB_SYNC_NONE || onstack)
 		call_rcu(&work->rcu_head, bdi_work_free);
 }
 
@@ -146,21 +151,19 @@ static void wb_clear_pending(struct bdi_writeback *wb, struct bdi_work *work)
 
 static void bdi_queue_work(struct backing_dev_info *bdi, struct bdi_work *work)
 {
-	if (work) {
-		work->seen = bdi->wb_mask;
-		BUG_ON(!work->seen);
-		atomic_set(&work->pending, bdi->wb_cnt);
-		BUG_ON(!bdi->wb_cnt);
-
-		/*
-		 * Make sure stores are seen before it appears on the list
-		 */
-		smp_mb();
+	work->seen = bdi->wb_mask;
+	BUG_ON(!work->seen);
+	atomic_set(&work->pending, bdi->wb_cnt);
+	BUG_ON(!bdi->wb_cnt);
 
-		spin_lock(&bdi->wb_lock);
-		list_add_tail_rcu(&work->list, &bdi->work_list);
-		spin_unlock(&bdi->wb_lock);
-	}
+	/*
+	 * list_add_tail_rcu() contains the necessary barriers to
+	 * make sure the above stores are seen before the item is
+	 * noticed on the list
+	 */
+	spin_lock(&bdi->wb_lock);
+	list_add_tail_rcu(&work->list, &bdi->work_list);
+	spin_unlock(&bdi->wb_lock);
 
 	/*
 	 * If the default thread isn't there, make sure we add it. When
@@ -171,15 +174,7 @@ static void bdi_queue_work(struct backing_dev_info *bdi, struct bdi_work *work)
 	else {
 		struct bdi_writeback *wb = &bdi->wb;
 
-		/*
-		 * If we failed allocating the bdi work item, wake up the wb
-		 * thread always. As a safety precaution, it'll flush out
-		 * everything
-		 */
-		if (!wb_has_dirty_io(wb)) {
-			if (work)
-				wb_clear_pending(wb, work);
-		} else if (wb->task)
+		if (wb->task)
 			wake_up_process(wb->task);
 	}
 }
@@ -194,48 +189,75 @@ static void bdi_wait_on_work_clear(struct bdi_work *work)
 		    TASK_UNINTERRUPTIBLE);
 }
 
-static struct bdi_work *bdi_alloc_work(struct writeback_control *wbc)
+static void bdi_alloc_queue_work(struct backing_dev_info *bdi,
+				 struct wb_writeback_args *args)
 {
 	struct bdi_work *work;
 
+	/*
+	 * This is WB_SYNC_NONE writeback, so if allocation fails just
+	 * wakeup the thread for old dirty data writeback
+	 */
 	work = kmalloc(sizeof(*work), GFP_ATOMIC);
-	if (work)
-		bdi_work_init(work, wbc);
+	if (work) {
+		bdi_work_init(work, args);
+		bdi_queue_work(bdi, work);
+	} else {
+		struct bdi_writeback *wb = &bdi->wb;
 
-	return work;
+		if (wb->task)
+			wake_up_process(wb->task);
+	}
 }
 
-void bdi_start_writeback(struct writeback_control *wbc)
+/**
+ * bdi_sync_writeback - start and wait for writeback
+ * @bdi: the backing device to write from
+ * @sb: write inodes from this super_block
+ *
+ * Description:
+ *   This does WB_SYNC_ALL data integrity writeback and waits for the
+ *   IO to complete. Callers must hold the sb s_umount semaphore for
+ *   reading, to avoid having the super disappear before we are done.
+ */
+static void bdi_sync_writeback(struct backing_dev_info *bdi,
+			       struct super_block *sb)
 {
-	const bool must_wait = wbc->sync_mode == WB_SYNC_ALL;
-	struct bdi_work work_stack, *work = NULL;
+	struct wb_writeback_args args = {
+		.sb		= sb,
+		.sync_mode	= WB_SYNC_ALL,
+		.nr_pages	= LONG_MAX,
+		.range_cyclic	= 0,
+	};
+	struct bdi_work work;
 
-	if (!must_wait)
-		work = bdi_alloc_work(wbc);
+	bdi_work_init(&work, &args);
+	work.state |= WS_ONSTACK;
 
-	if (!work) {
-		work = &work_stack;
-		bdi_work_init_on_stack(work, wbc);
-	}
+	bdi_queue_work(bdi, &work);
+	bdi_wait_on_work_clear(&work);
+}
 
-	bdi_queue_work(wbc->bdi, work);
+/**
+ * bdi_start_writeback - start writeback
+ * @bdi: the backing device to write from
+ * @nr_pages: the number of pages to write
+ *
+ * Description:
+ *   This does WB_SYNC_NONE opportunistic writeback. The IO is only
+ *   started when this function returns, we make no guarentees on
+ *   completion. Caller need not hold sb s_umount semaphore.
+ *
+ */
+void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages)
+{
+	struct wb_writeback_args args = {
+		.sync_mode	= WB_SYNC_NONE,
+		.nr_pages	= nr_pages,
+		.range_cyclic	= 1,
+	};
 
-	/*
-	 * If the sync mode is WB_SYNC_ALL, block waiting for the work to
-	 * complete. If not, we only need to wait for the work to be started,
-	 * if we allocated it on-stack. We use the same mechanism, if the
-	 * wait bit is set in the bdi_work struct, then threads will not
-	 * clear pending until after they are done.
-	 *
-	 * Note that work == &work_stack if must_wait is true, so we don't
-	 * need to do call_rcu() here ever, since the completion path will
-	 * have done that for us.
-	 */
-	if (must_wait || work == &work_stack) {
-		bdi_wait_on_work_clear(work);
-		if (work != &work_stack)
-			call_rcu(&work->rcu_head, bdi_work_free);
-	}
+	bdi_alloc_queue_work(bdi, &args);
 }
 
 /*
@@ -671,17 +693,16 @@ static inline bool over_bground_thresh(void)
  * older_than_this takes precedence over nr_to_write.  So we'll only write back
  * all dirty pages if they are all attached to "old" mappings.
  */
-static long wb_writeback(struct bdi_writeback *wb, long nr_pages,
-			 struct super_block *sb,
-			 enum writeback_sync_modes sync_mode, int for_kupdate)
+static long wb_writeback(struct bdi_writeback *wb,
+			 struct wb_writeback_args *args)
 {
 	struct writeback_control wbc = {
 		.bdi			= wb->bdi,
-		.sb			= sb,
-		.sync_mode		= sync_mode,
+		.sb			= args->sb,
+		.sync_mode		= args->sync_mode,
 		.older_than_this	= NULL,
-		.for_kupdate		= for_kupdate,
-		.range_cyclic		= 1,
+		.for_kupdate		= args->for_kupdate,
+		.range_cyclic		= args->range_cyclic,
 	};
 	unsigned long oldest_jif;
 	long wrote = 0;
@@ -691,13 +712,18 @@ static long wb_writeback(struct bdi_writeback *wb, long nr_pages,
 		oldest_jif = jiffies -
 				msecs_to_jiffies(dirty_expire_interval * 10);
 	}
+	if (!wbc.range_cyclic) {
+		wbc.range_start = 0;
+		wbc.range_end = LLONG_MAX;
+	}
 
 	for (;;) {
 		/*
 		 * Don't flush anything for non-integrity writeback where
 		 * no nr_pages was given
 		 */
-		if (!for_kupdate && nr_pages <= 0 && sync_mode == WB_SYNC_NONE)
+		if (!args->for_kupdate && args->nr_pages <= 0 &&
+		     args->sync_mode == WB_SYNC_NONE)
 			break;
 
 		/*
@@ -705,7 +731,8 @@ static long wb_writeback(struct bdi_writeback *wb, long nr_pages,
 		 * periodic background writeout and we are below the
 		 * background dirty threshold, don't do anything
 		 */
-		if (for_kupdate && nr_pages <= 0 && !over_bground_thresh())
+		if (args->for_kupdate && args->nr_pages <= 0 &&
+		    !over_bground_thresh())
 			break;
 
 		wbc.more_io = 0;
@@ -713,7 +740,7 @@ static long wb_writeback(struct bdi_writeback *wb, long nr_pages,
 		wbc.nr_to_write = MAX_WRITEBACK_PAGES;
 		wbc.pages_skipped = 0;
 		writeback_inodes_wb(wb, &wbc);
-		nr_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
+		args->nr_pages -= MAX_WRITEBACK_PAGES - wbc.nr_to_write;
 		wrote += MAX_WRITEBACK_PAGES - wbc.nr_to_write;
 
 		/*
@@ -731,7 +758,11 @@ static long wb_writeback(struct bdi_writeback *wb, long nr_pages,
 
 /*
  * Return the next bdi_work struct that hasn't been processed by this
- * wb thread yet
+ * wb thread yet. ->seen is initially set for each thread that exists
+ * for this device, when a thread first notices a piece of work it
+ * clears its bit. Depending on writeback type, the thread will notify
+ * completion on either receiving the work (WB_SYNC_NONE) or after
+ * it is done (WB_SYNC_ALL).
  */
 static struct bdi_work *get_next_work_item(struct backing_dev_info *bdi,
 					   struct bdi_writeback *wb)
@@ -741,8 +772,9 @@ static struct bdi_work *get_next_work_item(struct backing_dev_info *bdi,
 	rcu_read_lock();
 
 	list_for_each_entry_rcu(work, &bdi->work_list, list) {
-		if (!test_and_clear_bit(wb->nr, &work->seen))
+		if (!test_bit(wb->nr, &work->seen))
 			continue;
+		clear_bit(wb->nr, &work->seen);
 
 		ret = work;
 		break;
@@ -767,8 +799,16 @@ static long wb_check_old_data_flush(struct bdi_writeback *wb)
 			global_page_state(NR_UNSTABLE_NFS) +
 			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
 
-	if (nr_pages)
-		return wb_writeback(wb, nr_pages, NULL, WB_SYNC_NONE, 1);
+	if (nr_pages) {
+		struct wb_writeback_args args = {
+			.nr_pages	= nr_pages,
+			.sync_mode	= WB_SYNC_NONE,
+			.for_kupdate	= 1,
+			.range_cyclic	= 1,
+		};
+
+		return wb_writeback(wb, &args);
+	}
 
 	return 0;
 }
@@ -780,35 +820,31 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait)
 {
 	struct backing_dev_info *bdi = wb->bdi;
 	struct bdi_work *work;
-	long nr_pages, wrote = 0;
+	long wrote = 0;
 
 	while ((work = get_next_work_item(bdi, wb)) != NULL) {
-		enum writeback_sync_modes sync_mode;
-
-		nr_pages = work->nr_pages;
+		struct wb_writeback_args args = work->args;
 
 		/*
 		 * Override sync mode, in case we must wait for completion
 		 */
 		if (force_wait)
-			work->sync_mode = sync_mode = WB_SYNC_ALL;
-		else
-			sync_mode = work->sync_mode;
+			work->args.sync_mode = args.sync_mode = WB_SYNC_ALL;
 
 		/*
 		 * If this isn't a data integrity operation, just notify
 		 * that we have seen this work and we are now starting it.
 		 */
-		if (sync_mode == WB_SYNC_NONE)
+		if (args.sync_mode == WB_SYNC_NONE)
 			wb_clear_pending(wb, work);
 
-		wrote += wb_writeback(wb, nr_pages, work->sb, sync_mode, 0);
+		wrote += wb_writeback(wb, &args);
 
 		/*
 		 * This is a data integrity writeback, so only do the
 		 * notification when we have completed the work.
 		 */
-		if (sync_mode == WB_SYNC_ALL)
+		if (args.sync_mode == WB_SYNC_ALL)
 			wb_clear_pending(wb, work);
 	}
 
@@ -849,8 +885,7 @@ int bdi_writeback_task(struct bdi_writeback *wb)
 		}
 
 		wait_jiffies = msecs_to_jiffies(dirty_writeback_interval * 10);
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(wait_jiffies);
+		schedule_timeout_interruptible(wait_jiffies);
 		try_to_freeze();
 	}
 
@@ -858,67 +893,28 @@ int bdi_writeback_task(struct bdi_writeback *wb)
 }
 
 /*
- * Schedule writeback for all backing devices. Expensive! If this is a data
- * integrity operation, writeback will be complete when this returns. If
- * we are simply called for WB_SYNC_NONE, then writeback will merely be
- * scheduled to run.
+ * Schedule writeback for all backing devices. This does WB_SYNC_NONE
+ * writeback, for integrity writeback see bdi_sync_writeback().
  */
-static void bdi_writeback_all(struct writeback_control *wbc)
+static void bdi_writeback_all(struct super_block *sb, long nr_pages)
 {
-	const bool must_wait = wbc->sync_mode == WB_SYNC_ALL;
+	struct wb_writeback_args args = {
+		.sb		= sb,
+		.nr_pages	= nr_pages,
+		.sync_mode	= WB_SYNC_NONE,
+	};
 	struct backing_dev_info *bdi;
-	struct bdi_work *work;
-	LIST_HEAD(list);
 
-restart:
-	spin_lock(&bdi_lock);
-
-	list_for_each_entry(bdi, &bdi_list, bdi_list) {
-		struct bdi_work *work;
+	rcu_read_lock();
 
+	list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) {
 		if (!bdi_has_dirty_io(bdi))
 			continue;
 
-		/*
-		 * If work allocation fails, do the writes inline. We drop
-		 * the lock and restart the list writeout. This should be OK,
-		 * since this happens rarely and because the writeout should
-		 * eventually make more free memory available.
-		 */
-		work = bdi_alloc_work(wbc);
-		if (!work) {
-			struct writeback_control __wbc;
-
-			/*
-			 * Not a data integrity writeout, just continue
-			 */
-			if (!must_wait)
-				continue;
-
-			spin_unlock(&bdi_lock);
-			__wbc = *wbc;
-			__wbc.bdi = bdi;
-			writeback_inodes_wbc(&__wbc);
-			goto restart;
-		}
-		if (must_wait)
-			list_add_tail(&work->wait_list, &list);
-
-		bdi_queue_work(bdi, work);
+		bdi_alloc_queue_work(bdi, &args);
 	}
 
-	spin_unlock(&bdi_lock);
-
-	/*
-	 * If this is for WB_SYNC_ALL, wait for pending work to complete
-	 * before returning.
-	 */
-	while (!list_empty(&list)) {
-		work = list_entry(list.next, struct bdi_work, wait_list);
-		list_del(&work->wait_list);
-		bdi_wait_on_work_clear(work);
-		call_rcu(&work->rcu_head, bdi_work_free);
-	}
+	rcu_read_unlock();
 }
 
 /*
@@ -927,17 +923,10 @@ restart:
  */
 void wakeup_flusher_threads(long nr_pages)
 {
-	struct writeback_control wbc = {
-		.sync_mode	= WB_SYNC_NONE,
-		.older_than_this = NULL,
-		.range_cyclic	= 1,
-	};
-
 	if (nr_pages == 0)
 		nr_pages = global_page_state(NR_FILE_DIRTY) +
 				global_page_state(NR_UNSTABLE_NFS);
-	wbc.nr_to_write = nr_pages;
-	bdi_writeback_all(&wbc);
+	bdi_writeback_all(NULL, nr_pages);
 }
 
 static noinline void block_dump___mark_inode_dirty(struct inode *inode)
@@ -1084,7 +1073,7 @@ EXPORT_SYMBOL(__mark_inode_dirty);
  * on the writer throttling path, and we get decent balancing between many
  * throttled threads: we don't want them all piling up on inode_sync_wait.
  */
-static void wait_sb_inodes(struct writeback_control *wbc)
+static void wait_sb_inodes(struct super_block *sb)
 {
 	struct inode *inode, *old_inode = NULL;
 
@@ -1092,7 +1081,7 @@ static void wait_sb_inodes(struct writeback_control *wbc)
 	 * We need to be protected against the filesystem going from
 	 * r/o to r/w or vice versa.
 	 */
-	WARN_ON(!rwsem_is_locked(&wbc->sb->s_umount));
+	WARN_ON(!rwsem_is_locked(&sb->s_umount));
 
 	spin_lock(&inode_lock);
 
@@ -1103,7 +1092,7 @@ static void wait_sb_inodes(struct writeback_control *wbc)
 	 * In which case, the inode may not be on the dirty list, but
 	 * we still have to wait for that writeout.
 	 */
-	list_for_each_entry(inode, &wbc->sb->s_inodes, i_sb_list) {
+	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
 		struct address_space *mapping;
 
 		if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
@@ -1143,14 +1132,8 @@ static void wait_sb_inodes(struct writeback_control *wbc)
  * for IO completion of submitted IO. The number of pages submitted is
  * returned.
  */
-long writeback_inodes_sb(struct super_block *sb)
+void writeback_inodes_sb(struct super_block *sb)
 {
-	struct writeback_control wbc = {
-		.sb		= sb,
-		.sync_mode	= WB_SYNC_NONE,
-		.range_start	= 0,
-		.range_end	= LLONG_MAX,
-	};
 	unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
 	unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
 	long nr_to_write;
@@ -1158,9 +1141,7 @@ long writeback_inodes_sb(struct super_block *sb)
 	nr_to_write = nr_dirty + nr_unstable +
 			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
 
-	wbc.nr_to_write = nr_to_write;
-	bdi_writeback_all(&wbc);
-	return nr_to_write - wbc.nr_to_write;
+	bdi_writeback_all(sb, nr_to_write);
 }
 EXPORT_SYMBOL(writeback_inodes_sb);
 
@@ -1171,20 +1152,10 @@ EXPORT_SYMBOL(writeback_inodes_sb);
  * This function writes and waits on any dirty inode belonging to this
  * super_block. The number of pages synced is returned.
  */
-long sync_inodes_sb(struct super_block *sb)
+void sync_inodes_sb(struct super_block *sb)
 {
-	struct writeback_control wbc = {
-		.sb		= sb,
-		.sync_mode	= WB_SYNC_ALL,
-		.range_start	= 0,
-		.range_end	= LLONG_MAX,
-	};
-	long nr_to_write = LONG_MAX; /* doesn't actually matter */
-
-	wbc.nr_to_write = nr_to_write;
-	bdi_writeback_all(&wbc);
-	wait_sb_inodes(&wbc);
-	return nr_to_write - wbc.nr_to_write;
+	bdi_sync_writeback(sb->s_bdi, sb);
+	wait_sb_inodes(sb);
 }
 EXPORT_SYMBOL(sync_inodes_sb);
 
@@ -1242,57 +1213,3 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
 	return ret;
 }
 EXPORT_SYMBOL(sync_inode);
-
-/**
- * generic_osync_inode - flush all dirty data for a given inode to disk
- * @inode: inode to write
- * @mapping: the address_space that should be flushed
- * @what:  what to write and wait upon
- *
- * This can be called by file_write functions for files which have the
- * O_SYNC flag set, to flush dirty writes to disk.
- *
- * @what is a bitmask, specifying which part of the inode's data should be
- * written and waited upon.
- *
- *    OSYNC_DATA:     i_mapping's dirty data
- *    OSYNC_METADATA: the buffers at i_mapping->private_list
- *    OSYNC_INODE:    the inode itself
- */
-
-int generic_osync_inode(struct inode *inode, struct address_space *mapping, int what)
-{
-	int err = 0;
-	int need_write_inode_now = 0;
-	int err2;
-
-	if (what & OSYNC_DATA)
-		err = filemap_fdatawrite(mapping);
-	if (what & (OSYNC_METADATA|OSYNC_DATA)) {
-		err2 = sync_mapping_buffers(mapping);
-		if (!err)
-			err = err2;
-	}
-	if (what & OSYNC_DATA) {
-		err2 = filemap_fdatawait(mapping);
-		if (!err)
-			err = err2;
-	}
-
-	spin_lock(&inode_lock);
-	if ((inode->i_state & I_DIRTY) &&
-	    ((what & OSYNC_INODE) || (inode->i_state & I_DIRTY_DATASYNC)))
-		need_write_inode_now = 1;
-	spin_unlock(&inode_lock);
-
-	if (need_write_inode_now) {
-		err2 = write_inode_now(inode, 1);
-		if (!err)
-			err = err2;
-	}
-	else
-		inode_sync_wait(inode);
-
-	return err;
-}
-EXPORT_SYMBOL(generic_osync_inode);
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index 99c99df..3773fd6 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -61,6 +61,121 @@ static ssize_t fuse_conn_waiting_read(struct file *file, char __user *buf,
 	return simple_read_from_buffer(buf, len, ppos, tmp, size);
 }
 
+static ssize_t fuse_conn_limit_read(struct file *file, char __user *buf,
+				    size_t len, loff_t *ppos, unsigned val)
+{
+	char tmp[32];
+	size_t size = sprintf(tmp, "%u\n", val);
+
+	return simple_read_from_buffer(buf, len, ppos, tmp, size);
+}
+
+static ssize_t fuse_conn_limit_write(struct file *file, const char __user *buf,
+				     size_t count, loff_t *ppos, unsigned *val,
+				     unsigned global_limit)
+{
+	unsigned long t;
+	char tmp[32];
+	unsigned limit = (1 << 16) - 1;
+	int err;
+
+	if (*ppos || count >= sizeof(tmp) - 1)
+		return -EINVAL;
+
+	if (copy_from_user(tmp, buf, count))
+		return -EINVAL;
+
+	tmp[count] = '\0';
+
+	err = strict_strtoul(tmp, 0, &t);
+	if (err)
+		return err;
+
+	if (!capable(CAP_SYS_ADMIN))
+		limit = min(limit, global_limit);
+
+	if (t > limit)
+		return -EINVAL;
+
+	*val = t;
+
+	return count;
+}
+
+static ssize_t fuse_conn_max_background_read(struct file *file,
+					     char __user *buf, size_t len,
+					     loff_t *ppos)
+{
+	struct fuse_conn *fc;
+	unsigned val;
+
+	fc = fuse_ctl_file_conn_get(file);
+	if (!fc)
+		return 0;
+
+	val = fc->max_background;
+	fuse_conn_put(fc);
+
+	return fuse_conn_limit_read(file, buf, len, ppos, val);
+}
+
+static ssize_t fuse_conn_max_background_write(struct file *file,
+					      const char __user *buf,
+					      size_t count, loff_t *ppos)
+{
+	unsigned val;
+	ssize_t ret;
+
+	ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
+				    max_user_bgreq);
+	if (ret > 0) {
+		struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
+		if (fc) {
+			fc->max_background = val;
+			fuse_conn_put(fc);
+		}
+	}
+
+	return ret;
+}
+
+static ssize_t fuse_conn_congestion_threshold_read(struct file *file,
+						   char __user *buf, size_t len,
+						   loff_t *ppos)
+{
+	struct fuse_conn *fc;
+	unsigned val;
+
+	fc = fuse_ctl_file_conn_get(file);
+	if (!fc)
+		return 0;
+
+	val = fc->congestion_threshold;
+	fuse_conn_put(fc);
+
+	return fuse_conn_limit_read(file, buf, len, ppos, val);
+}
+
+static ssize_t fuse_conn_congestion_threshold_write(struct file *file,
+						    const char __user *buf,
+						    size_t count, loff_t *ppos)
+{
+	unsigned val;
+	ssize_t ret;
+
+	ret = fuse_conn_limit_write(file, buf, count, ppos, &val,
+				    max_user_congthresh);
+	if (ret > 0) {
+		struct fuse_conn *fc = fuse_ctl_file_conn_get(file);
+		if (fc) {
+			fc->congestion_threshold = val;
+			fuse_conn_put(fc);
+		}
+	}
+
+	return ret;
+}
+
 static const struct file_operations fuse_ctl_abort_ops = {
 	.open = nonseekable_open,
 	.write = fuse_conn_abort_write,
@@ -71,6 +186,18 @@ static const struct file_operations fuse_ctl_waiting_ops = {
 	.read = fuse_conn_waiting_read,
 };
 
+static const struct file_operations fuse_conn_max_background_ops = {
+	.open = nonseekable_open,
+	.read = fuse_conn_max_background_read,
+	.write = fuse_conn_max_background_write,
+};
+
+static const struct file_operations fuse_conn_congestion_threshold_ops = {
+	.open = nonseekable_open,
+	.read = fuse_conn_congestion_threshold_read,
+	.write = fuse_conn_congestion_threshold_write,
+};
+
 static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
 					  struct fuse_conn *fc,
 					  const char *name,
@@ -127,9 +254,14 @@ int fuse_ctl_add_conn(struct fuse_conn *fc)
 		goto err;
 
 	if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 1,
-				NULL, &fuse_ctl_waiting_ops) ||
+				 NULL, &fuse_ctl_waiting_ops) ||
 	    !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 1,
-				 NULL, &fuse_ctl_abort_ops))
+				 NULL, &fuse_ctl_abort_ops) ||
+	    !fuse_ctl_add_dentry(parent, fc, "max_background", S_IFREG | 0600,
+				 1, NULL, &fuse_conn_max_background_ops) ||
+	    !fuse_ctl_add_dentry(parent, fc, "congestion_threshold",
+				 S_IFREG | 0600, 1, NULL,
+				 &fuse_conn_congestion_threshold_ops))
 		goto err;
 
 	return 0;
@@ -156,7 +288,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc)
 		d_drop(dentry);
 		dput(dentry);
 	}
-	fuse_control_sb->s_root->d_inode->i_nlink--;
+	drop_nlink(fuse_control_sb->s_root->d_inode);
 }
 
 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 6484eb7..51d9e33 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -250,7 +250,7 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
 
 static void flush_bg_queue(struct fuse_conn *fc)
 {
-	while (fc->active_background < FUSE_MAX_BACKGROUND &&
+	while (fc->active_background < fc->max_background &&
 	       !list_empty(&fc->bg_queue)) {
 		struct fuse_req *req;
 
@@ -280,11 +280,11 @@ __releases(&fc->lock)
 	list_del(&req->intr_entry);
 	req->state = FUSE_REQ_FINISHED;
 	if (req->background) {
-		if (fc->num_background == FUSE_MAX_BACKGROUND) {
+		if (fc->num_background == fc->max_background) {
 			fc->blocked = 0;
 			wake_up_all(&fc->blocked_waitq);
 		}
-		if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
+		if (fc->num_background == fc->congestion_threshold &&
 		    fc->connected && fc->bdi_initialized) {
 			clear_bdi_congested(&fc->bdi, BLK_RW_SYNC);
 			clear_bdi_congested(&fc->bdi, BLK_RW_ASYNC);
@@ -410,9 +410,9 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
 {
 	req->background = 1;
 	fc->num_background++;
-	if (fc->num_background == FUSE_MAX_BACKGROUND)
+	if (fc->num_background == fc->max_background)
 		fc->blocked = 1;
-	if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
+	if (fc->num_background == fc->congestion_threshold &&
 	    fc->bdi_initialized) {
 		set_bdi_congested(&fc->bdi, BLK_RW_SYNC);
 		set_bdi_congested(&fc->bdi, BLK_RW_ASYNC);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 52b641f..fc9c79f 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -25,12 +25,6 @@
 /** Max number of pages that can be used in a single read request */
 #define FUSE_MAX_PAGES_PER_REQ 32
 
-/** Maximum number of outstanding background requests */
-#define FUSE_MAX_BACKGROUND 12
-
-/** Congestion starts at 75% of maximum */
-#define FUSE_CONGESTION_THRESHOLD (FUSE_MAX_BACKGROUND * 75 / 100)
-
 /** Bias for fi->writectr, meaning new writepages must not be sent */
 #define FUSE_NOWRITE INT_MIN
 
@@ -38,7 +32,7 @@
 #define FUSE_NAME_MAX 1024
 
 /** Number of dentries for each connection in the control filesystem */
-#define FUSE_CTL_NUM_DENTRIES 3
+#define FUSE_CTL_NUM_DENTRIES 5
 
 /** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
     module will check permissions based on the file mode.  Otherwise no
@@ -55,6 +49,10 @@ extern struct list_head fuse_conn_list;
 /** Global mutex protecting fuse_conn_list and the control filesystem */
 extern struct mutex fuse_mutex;
 
+/** Module parameters */
+extern unsigned max_user_bgreq;
+extern unsigned max_user_congthresh;
+
 /** FUSE inode */
 struct fuse_inode {
 	/** Inode data */
@@ -349,6 +347,12 @@ struct fuse_conn {
 	/** rbtree of fuse_files waiting for poll events indexed by ph */
 	struct rb_root polled_files;
 
+	/** Maximum number of outstanding background requests */
+	unsigned max_background;
+
+	/** Number of background requests at which congestion starts */
+	unsigned congestion_threshold;
+
 	/** Number of requests currently in the background */
 	unsigned num_background;
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 4567db6..6da947d 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -14,6 +14,7 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/parser.h>
 #include <linux/statfs.h>
 #include <linux/random.h>
@@ -28,10 +29,34 @@ static struct kmem_cache *fuse_inode_cachep;
 struct list_head fuse_conn_list;
 DEFINE_MUTEX(fuse_mutex);
 
+static int set_global_limit(const char *val, struct kernel_param *kp);
+
+unsigned max_user_bgreq;
+module_param_call(max_user_bgreq, set_global_limit, param_get_uint,
+		  &max_user_bgreq, 0644);
+__MODULE_PARM_TYPE(max_user_bgreq, "uint");
+MODULE_PARM_DESC(max_user_bgreq,
+ "Global limit for the maximum number of backgrounded requests an "
+ "unprivileged user can set");
+
+unsigned max_user_congthresh;
+module_param_call(max_user_congthresh, set_global_limit, param_get_uint,
+		  &max_user_congthresh, 0644);
+__MODULE_PARM_TYPE(max_user_congthresh, "uint");
+MODULE_PARM_DESC(max_user_congthresh,
+ "Global limit for the maximum congestion threshold an "
+ "unprivileged user can set");
+
 #define FUSE_SUPER_MAGIC 0x65735546
 
 #define FUSE_DEFAULT_BLKSIZE 512
 
+/** Maximum number of outstanding background requests */
+#define FUSE_DEFAULT_MAX_BACKGROUND 12
+
+/** Congestion starts at 75% of maximum */
+#define FUSE_DEFAULT_CONGESTION_THRESHOLD (FUSE_DEFAULT_MAX_BACKGROUND * 3 / 4)
+
 struct fuse_mount_data {
 	int fd;
 	unsigned rootmode;
@@ -517,6 +542,8 @@ void fuse_conn_init(struct fuse_conn *fc)
 	INIT_LIST_HEAD(&fc->bg_queue);
 	INIT_LIST_HEAD(&fc->entry);
 	atomic_set(&fc->num_waiting, 0);
+	fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND;
+	fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD;
 	fc->khctr = 0;
 	fc->polled_files = RB_ROOT;
 	fc->reqctr = 0;
@@ -727,6 +754,54 @@ static const struct super_operations fuse_super_operations = {
 	.show_options	= fuse_show_options,
 };
 
+static void sanitize_global_limit(unsigned *limit)
+{
+	if (*limit == 0)
+		*limit = ((num_physpages << PAGE_SHIFT) >> 13) /
+			 sizeof(struct fuse_req);
+
+	if (*limit >= 1 << 16)
+		*limit = (1 << 16) - 1;
+}
+
+static int set_global_limit(const char *val, struct kernel_param *kp)
+{
+	int rv;
+
+	rv = param_set_uint(val, kp);
+	if (rv)
+		return rv;
+
+	sanitize_global_limit((unsigned *)kp->arg);
+
+	return 0;
+}
+
+static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg)
+{
+	int cap_sys_admin = capable(CAP_SYS_ADMIN);
+
+	if (arg->minor < 13)
+		return;
+
+	sanitize_global_limit(&max_user_bgreq);
+	sanitize_global_limit(&max_user_congthresh);
+
+	if (arg->max_background) {
+		fc->max_background = arg->max_background;
+
+		if (!cap_sys_admin && fc->max_background > max_user_bgreq)
+			fc->max_background = max_user_bgreq;
+	}
+	if (arg->congestion_threshold) {
+		fc->congestion_threshold = arg->congestion_threshold;
+
+		if (!cap_sys_admin &&
+		    fc->congestion_threshold > max_user_congthresh)
+			fc->congestion_threshold = max_user_congthresh;
+	}
+}
+
 static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
 {
 	struct fuse_init_out *arg = &req->misc.init_out;
@@ -736,6 +811,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
 	else {
 		unsigned long ra_pages;
 
+		process_init_limits(fc, arg);
+
 		if (arg->minor >= 6) {
 			ra_pages = arg->max_readahead / PAGE_CACHE_SIZE;
 			if (arg->flags & FUSE_ASYNC_READ)
@@ -894,6 +971,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 	if (err)
 		goto err_put_conn;
 
+	sb->s_bdi = &fc->bdi;
+
 	/* Handle umasking inside the fuse code */
 	if (sb->s_flags & MS_POSIXACL)
 		fc->dont_mask = 1;
@@ -1148,6 +1227,9 @@ static int __init fuse_init(void)
 	if (res)
 		goto err_sysfs_cleanup;
 
+	sanitize_global_limit(&max_user_bgreq);
+	sanitize_global_limit(&max_user_congthresh);
+
 	return 0;
 
  err_sysfs_cleanup:
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile
index 3da2f1f..21f7e46 100644
--- a/fs/gfs2/Makefile
+++ b/fs/gfs2/Makefile
@@ -1,6 +1,6 @@
 EXTRA_CFLAGS := -I$(src)
 obj-$(CONFIG_GFS2_FS) += gfs2.o
-gfs2-y := acl.o bmap.o dir.o eaops.o eattr.o glock.o \
+gfs2-y := acl.o bmap.o dir.o xattr.o glock.o \
 	glops.o inode.o log.o lops.o main.o meta_io.o \
 	aops.o dentry.o export.o file.o \
 	ops_fstype.o ops_inode.o quota.o \
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index fa881bd..3fc4e3a 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -19,8 +19,7 @@
 #include "gfs2.h"
 #include "incore.h"
 #include "acl.h"
-#include "eaops.h"
-#include "eattr.h"
+#include "xattr.h"
 #include "glock.h"
 #include "inode.h"
 #include "meta_io.h"
@@ -31,8 +30,7 @@
 #define ACL_DEFAULT 0
 
 int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
-		      struct gfs2_ea_request *er,
-		      int *remove, mode_t *mode)
+			  struct gfs2_ea_request *er, int *remove, mode_t *mode)
 {
 	struct posix_acl *acl;
 	int error;
@@ -83,30 +81,20 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
 	return 0;
 }
 
-static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl,
-		   struct gfs2_ea_location *el, char **data, unsigned int *len)
+static int acl_get(struct gfs2_inode *ip, const char *name,
+		   struct posix_acl **acl, struct gfs2_ea_location *el,
+		   char **datap, unsigned int *lenp)
 {
-	struct gfs2_ea_request er;
-	struct gfs2_ea_location el_this;
+	char *data;
+	unsigned int len;
 	int error;
 
+	el->el_bh = NULL;
+
 	if (!ip->i_eattr)
 		return 0;
 
-	memset(&er, 0, sizeof(struct gfs2_ea_request));
-	if (access) {
-		er.er_name = GFS2_POSIX_ACL_ACCESS;
-		er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN;
-	} else {
-		er.er_name = GFS2_POSIX_ACL_DEFAULT;
-		er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN;
-	}
-	er.er_type = GFS2_EATYPE_SYS;
-
-	if (!el)
-		el = &el_this;
-
-	error = gfs2_ea_find(ip, &er, el);
+	error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, el);
 	if (error)
 		return error;
 	if (!el->el_ea)
@@ -114,32 +102,31 @@ static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl,
 	if (!GFS2_EA_DATA_LEN(el->el_ea))
 		goto out;
 
-	er.er_data_len = GFS2_EA_DATA_LEN(el->el_ea);
-	er.er_data = kmalloc(er.er_data_len, GFP_NOFS);
+	len = GFS2_EA_DATA_LEN(el->el_ea);
+	data = kmalloc(len, GFP_NOFS);
 	error = -ENOMEM;
-	if (!er.er_data)
+	if (!data)
 		goto out;
 
-	error = gfs2_ea_get_copy(ip, el, er.er_data);
-	if (error)
+	error = gfs2_ea_get_copy(ip, el, data, len);
+	if (error < 0)
 		goto out_kfree;
+	error = 0;
 
 	if (acl) {
-		*acl = posix_acl_from_xattr(er.er_data, er.er_data_len);
+		*acl = posix_acl_from_xattr(data, len);
 		if (IS_ERR(*acl))
 			error = PTR_ERR(*acl);
 	}
 
 out_kfree:
-	if (error || !data)
-		kfree(er.er_data);
-	else {
-		*data = er.er_data;
-		*len = er.er_data_len;
+	if (error || !datap) {
+		kfree(data);
+	} else {
+		*datap = data;
+		*lenp = len;
 	}
 out:
-	if (error || el == &el_this)
-		brelse(el->el_bh);
 	return error;
 }
 
@@ -153,10 +140,12 @@ out:
 
 int gfs2_check_acl(struct inode *inode, int mask)
 {
+	struct gfs2_ea_location el;
 	struct posix_acl *acl = NULL;
 	int error;
 
-	error = acl_get(GFS2_I(inode), ACL_ACCESS, &acl, NULL, NULL, NULL);
+	error = acl_get(GFS2_I(inode), GFS2_POSIX_ACL_ACCESS, &acl, &el, NULL, NULL);
+	brelse(el.el_bh);
 	if (error)
 		return error;
 
@@ -196,10 +185,12 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode)
 
 int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
 {
+	struct gfs2_ea_location el;
 	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct posix_acl *acl = NULL, *clone;
-	struct gfs2_ea_request er;
 	mode_t mode = ip->i_inode.i_mode;
+	char *data = NULL;
+	unsigned int len;
 	int error;
 
 	if (!sdp->sd_args.ar_posix_acl)
@@ -207,11 +198,8 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
 	if (S_ISLNK(ip->i_inode.i_mode))
 		return 0;
 
-	memset(&er, 0, sizeof(struct gfs2_ea_request));
-	er.er_type = GFS2_EATYPE_SYS;
-
-	error = acl_get(dip, ACL_DEFAULT, &acl, NULL,
-			&er.er_data, &er.er_data_len);
+	error = acl_get(dip, GFS2_POSIX_ACL_DEFAULT, &acl, &el, &data, &len);
+	brelse(el.el_bh);
 	if (error)
 		return error;
 	if (!acl) {
@@ -229,9 +217,8 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
 	acl = clone;
 
 	if (S_ISDIR(ip->i_inode.i_mode)) {
-		er.er_name = GFS2_POSIX_ACL_DEFAULT;
-		er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN;
-		error = gfs2_system_eaops.eo_set(ip, &er);
+		error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
+				       GFS2_POSIX_ACL_DEFAULT, data, len, 0);
 		if (error)
 			goto out;
 	}
@@ -239,21 +226,19 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
 	error = posix_acl_create_masq(acl, &mode);
 	if (error < 0)
 		goto out;
-	if (error > 0) {
-		er.er_name = GFS2_POSIX_ACL_ACCESS;
-		er.er_name_len = GFS2_POSIX_ACL_ACCESS_LEN;
-		posix_acl_to_xattr(acl, er.er_data, er.er_data_len);
-		er.er_mode = mode;
-		er.er_flags = GFS2_ERF_MODE;
-		error = gfs2_system_eaops.eo_set(ip, &er);
-		if (error)
-			goto out;
-	} else
-		munge_mode(ip, mode);
+	if (error == 0)
+		goto munge;
 
+	posix_acl_to_xattr(acl, data, len);
+	error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
+			       GFS2_POSIX_ACL_ACCESS, data, len, 0);
+	if (error)
+		goto out;
+munge:
+	error = munge_mode(ip, mode);
 out:
 	posix_acl_release(acl);
-	kfree(er.er_data);
+	kfree(data);
 	return error;
 }
 
@@ -265,9 +250,9 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
 	unsigned int len;
 	int error;
 
-	error = acl_get(ip, ACL_ACCESS, &acl, &el, &data, &len);
+	error = acl_get(ip, GFS2_POSIX_ACL_ACCESS, &acl, &el, &data, &len);
 	if (error)
-		return error;
+		goto out_brelse;
 	if (!acl)
 		return gfs2_setattr_simple(ip, attr);
 
@@ -286,8 +271,9 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
 
 out:
 	posix_acl_release(acl);
-	brelse(el.el_bh);
 	kfree(data);
+out_brelse:
+	brelse(el.el_bh);
 	return error;
 }
 
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c
index 022c66c..91bedda 100644
--- a/fs/gfs2/dentry.c
+++ b/fs/gfs2/dentry.c
@@ -107,8 +107,26 @@ static int gfs2_dhash(struct dentry *dentry, struct qstr *str)
 	return 0;
 }
 
+static int gfs2_dentry_delete(struct dentry *dentry)
+{
+	struct gfs2_inode *ginode;
+
+	if (!dentry->d_inode)
+		return 0;
+
+	ginode = GFS2_I(dentry->d_inode);
+	if (!ginode->i_iopen_gh.gh_gl)
+		return 0;
+
+	if (test_bit(GLF_DEMOTE, &ginode->i_iopen_gh.gh_gl->gl_flags))
+		return 1;
+
+	return 0;
+}
+
 const struct dentry_operations gfs2_dops = {
 	.d_revalidate = gfs2_drevalidate,
 	.d_hash = gfs2_dhash,
+	.d_delete = gfs2_dentry_delete,
 };
 
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c
deleted file mode 100644
index dee9b03..0000000
--- a/fs/gfs2/eaops.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License version 2.
- */
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/buffer_head.h>
-#include <linux/capability.h>
-#include <linux/xattr.h>
-#include <linux/gfs2_ondisk.h>
-#include <asm/uaccess.h>
-
-#include "gfs2.h"
-#include "incore.h"
-#include "acl.h"
-#include "eaops.h"
-#include "eattr.h"
-#include "util.h"
-
-/**
- * gfs2_ea_name2type - get the type of the ea, and truncate type from the name
- * @namep: ea name, possibly with type appended
- *
- * Returns: GFS2_EATYPE_XXX
- */
-
-unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name)
-{
-	unsigned int type;
-
-	if (strncmp(name, "system.", 7) == 0) {
-		type = GFS2_EATYPE_SYS;
-		if (truncated_name)
-			*truncated_name = name + sizeof("system.") - 1;
-	} else if (strncmp(name, "user.", 5) == 0) {
-		type = GFS2_EATYPE_USR;
-		if (truncated_name)
-			*truncated_name = name + sizeof("user.") - 1;
-	} else if (strncmp(name, "security.", 9) == 0) {
-		type = GFS2_EATYPE_SECURITY;
-		if (truncated_name)
-			*truncated_name = name + sizeof("security.") - 1;
-	} else {
-		type = GFS2_EATYPE_UNUSED;
-		if (truncated_name)
-			*truncated_name = NULL;
-	}
-
-	return type;
-}
-
-static int system_eo_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	if (!GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) &&
-	    !GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len) &&
-	    !capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	if (GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl == 0 &&
-	    (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len) ||
-	     GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)))
-		return -EOPNOTSUPP;
-
-	return gfs2_ea_get_i(ip, er);
-}
-
-static int system_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	int remove = 0;
-	int error;
-
-	if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
-		if (!(er->er_flags & GFS2_ERF_MODE)) {
-			er->er_mode = ip->i_inode.i_mode;
-			er->er_flags |= GFS2_ERF_MODE;
-		}
-		error = gfs2_acl_validate_set(ip, 1, er,
-					      &remove, &er->er_mode);
-		if (error)
-			return error;
-		error = gfs2_ea_set_i(ip, er);
-		if (error)
-			return error;
-		if (remove)
-			gfs2_ea_remove_i(ip, er);
-		return 0;
-
-	} else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
-		error = gfs2_acl_validate_set(ip, 0, er,
-					      &remove, NULL);
-		if (error)
-			return error;
-		if (!remove)
-			error = gfs2_ea_set_i(ip, er);
-		else {
-			error = gfs2_ea_remove_i(ip, er);
-			if (error == -ENODATA)
-				error = 0;
-		}
-		return error;
-	}
-
-	return -EPERM;
-}
-
-static int system_eo_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) {
-		int error = gfs2_acl_validate_remove(ip, 1);
-		if (error)
-			return error;
-
-	} else if (GFS2_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) {
-		int error = gfs2_acl_validate_remove(ip, 0);
-		if (error)
-			return error;
-
-	} else
-		return -EPERM;
-
-	return gfs2_ea_remove_i(ip, er);
-}
-
-static const struct gfs2_eattr_operations gfs2_user_eaops = {
-	.eo_get = gfs2_ea_get_i,
-	.eo_set = gfs2_ea_set_i,
-	.eo_remove = gfs2_ea_remove_i,
-	.eo_name = "user",
-};
-
-const struct gfs2_eattr_operations gfs2_system_eaops = {
-	.eo_get = system_eo_get,
-	.eo_set = system_eo_set,
-	.eo_remove = system_eo_remove,
-	.eo_name = "system",
-};
-
-static const struct gfs2_eattr_operations gfs2_security_eaops = {
-	.eo_get = gfs2_ea_get_i,
-	.eo_set = gfs2_ea_set_i,
-	.eo_remove = gfs2_ea_remove_i,
-	.eo_name = "security",
-};
-
-const struct gfs2_eattr_operations *gfs2_ea_ops[] = {
-	NULL,
-	&gfs2_user_eaops,
-	&gfs2_system_eaops,
-	&gfs2_security_eaops,
-};
-
diff --git a/fs/gfs2/eaops.h b/fs/gfs2/eaops.h
deleted file mode 100644
index da2f7fb..0000000
--- a/fs/gfs2/eaops.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License version 2.
- */
-
-#ifndef __EAOPS_DOT_H__
-#define __EAOPS_DOT_H__
-
-struct gfs2_ea_request;
-struct gfs2_inode;
-
-struct gfs2_eattr_operations {
-	int (*eo_get) (struct gfs2_inode *ip, struct gfs2_ea_request *er);
-	int (*eo_set) (struct gfs2_inode *ip, struct gfs2_ea_request *er);
-	int (*eo_remove) (struct gfs2_inode *ip, struct gfs2_ea_request *er);
-	char *eo_name;
-};
-
-unsigned int gfs2_ea_name2type(const char *name, const char **truncated_name);
-
-extern const struct gfs2_eattr_operations gfs2_system_eaops;
-
-extern const struct gfs2_eattr_operations *gfs2_ea_ops[];
-
-#endif /* __EAOPS_DOT_H__ */
-
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
deleted file mode 100644
index 07ea952..0000000
--- a/fs/gfs2/eattr.c
+++ /dev/null
@@ -1,1505 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License version 2.
- */
-
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/buffer_head.h>
-#include <linux/xattr.h>
-#include <linux/gfs2_ondisk.h>
-#include <asm/uaccess.h>
-
-#include "gfs2.h"
-#include "incore.h"
-#include "acl.h"
-#include "eaops.h"
-#include "eattr.h"
-#include "glock.h"
-#include "inode.h"
-#include "meta_io.h"
-#include "quota.h"
-#include "rgrp.h"
-#include "trans.h"
-#include "util.h"
-
-/**
- * ea_calc_size - returns the acutal number of bytes the request will take up
- *                (not counting any unstuffed data blocks)
- * @sdp:
- * @er:
- * @size:
- *
- * Returns: 1 if the EA should be stuffed
- */
-
-static int ea_calc_size(struct gfs2_sbd *sdp, struct gfs2_ea_request *er,
-			unsigned int *size)
-{
-	*size = GFS2_EAREQ_SIZE_STUFFED(er);
-	if (*size <= sdp->sd_jbsize)
-		return 1;
-
-	*size = GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er);
-
-	return 0;
-}
-
-static int ea_check_size(struct gfs2_sbd *sdp, struct gfs2_ea_request *er)
-{
-	unsigned int size;
-
-	if (er->er_data_len > GFS2_EA_MAX_DATA_LEN)
-		return -ERANGE;
-
-	ea_calc_size(sdp, er, &size);
-
-	/* This can only happen with 512 byte blocks */
-	if (size > sdp->sd_jbsize)
-		return -ERANGE;
-
-	return 0;
-}
-
-typedef int (*ea_call_t) (struct gfs2_inode *ip, struct buffer_head *bh,
-			  struct gfs2_ea_header *ea,
-			  struct gfs2_ea_header *prev, void *private);
-
-static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
-			ea_call_t ea_call, void *data)
-{
-	struct gfs2_ea_header *ea, *prev = NULL;
-	int error = 0;
-
-	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_EA))
-		return -EIO;
-
-	for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
-		if (!GFS2_EA_REC_LEN(ea))
-			goto fail;
-		if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
-						  bh->b_data + bh->b_size))
-			goto fail;
-		if (!GFS2_EATYPE_VALID(ea->ea_type))
-			goto fail;
-
-		error = ea_call(ip, bh, ea, prev, data);
-		if (error)
-			return error;
-
-		if (GFS2_EA_IS_LAST(ea)) {
-			if ((char *)GFS2_EA2NEXT(ea) !=
-			    bh->b_data + bh->b_size)
-				goto fail;
-			break;
-		}
-	}
-
-	return error;
-
-fail:
-	gfs2_consist_inode(ip);
-	return -EIO;
-}
-
-static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
-{
-	struct buffer_head *bh, *eabh;
-	__be64 *eablk, *end;
-	int error;
-
-	error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &bh);
-	if (error)
-		return error;
-
-	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT)) {
-		error = ea_foreach_i(ip, bh, ea_call, data);
-		goto out;
-	}
-
-	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_IN)) {
-		error = -EIO;
-		goto out;
-	}
-
-	eablk = (__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header));
-	end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs;
-
-	for (; eablk < end; eablk++) {
-		u64 bn;
-
-		if (!*eablk)
-			break;
-		bn = be64_to_cpu(*eablk);
-
-		error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, &eabh);
-		if (error)
-			break;
-		error = ea_foreach_i(ip, eabh, ea_call, data);
-		brelse(eabh);
-		if (error)
-			break;
-	}
-out:
-	brelse(bh);
-	return error;
-}
-
-struct ea_find {
-	struct gfs2_ea_request *ef_er;
-	struct gfs2_ea_location *ef_el;
-};
-
-static int ea_find_i(struct gfs2_inode *ip, struct buffer_head *bh,
-		     struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
-		     void *private)
-{
-	struct ea_find *ef = private;
-	struct gfs2_ea_request *er = ef->ef_er;
-
-	if (ea->ea_type == GFS2_EATYPE_UNUSED)
-		return 0;
-
-	if (ea->ea_type == er->er_type) {
-		if (ea->ea_name_len == er->er_name_len &&
-		    !memcmp(GFS2_EA2NAME(ea), er->er_name, ea->ea_name_len)) {
-			struct gfs2_ea_location *el = ef->ef_el;
-			get_bh(bh);
-			el->el_bh = bh;
-			el->el_ea = ea;
-			el->el_prev = prev;
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-int gfs2_ea_find(struct gfs2_inode *ip, struct gfs2_ea_request *er,
-		 struct gfs2_ea_location *el)
-{
-	struct ea_find ef;
-	int error;
-
-	ef.ef_er = er;
-	ef.ef_el = el;
-
-	memset(el, 0, sizeof(struct gfs2_ea_location));
-
-	error = ea_foreach(ip, ea_find_i, &ef);
-	if (error > 0)
-		return 0;
-
-	return error;
-}
-
-/**
- * ea_dealloc_unstuffed -
- * @ip:
- * @bh:
- * @ea:
- * @prev:
- * @private:
- *
- * Take advantage of the fact that all unstuffed blocks are
- * allocated from the same RG.  But watch, this may not always
- * be true.
- *
- * Returns: errno
- */
-
-static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
-				struct gfs2_ea_header *ea,
-				struct gfs2_ea_header *prev, void *private)
-{
-	int *leave = private;
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	struct gfs2_rgrpd *rgd;
-	struct gfs2_holder rg_gh;
-	struct buffer_head *dibh;
-	__be64 *dataptrs;
-	u64 bn = 0;
-	u64 bstart = 0;
-	unsigned int blen = 0;
-	unsigned int blks = 0;
-	unsigned int x;
-	int error;
-
-	if (GFS2_EA_IS_STUFFED(ea))
-		return 0;
-
-	dataptrs = GFS2_EA2DATAPTRS(ea);
-	for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
-		if (*dataptrs) {
-			blks++;
-			bn = be64_to_cpu(*dataptrs);
-		}
-	}
-	if (!blks)
-		return 0;
-
-	rgd = gfs2_blk2rgrpd(sdp, bn);
-	if (!rgd) {
-		gfs2_consist_inode(ip);
-		return -EIO;
-	}
-
-	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
-	if (error)
-		return error;
-
-	error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE +
-				 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
-	if (error)
-		goto out_gunlock;
-
-	gfs2_trans_add_bh(ip->i_gl, bh, 1);
-
-	dataptrs = GFS2_EA2DATAPTRS(ea);
-	for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
-		if (!*dataptrs)
-			break;
-		bn = be64_to_cpu(*dataptrs);
-
-		if (bstart + blen == bn)
-			blen++;
-		else {
-			if (bstart)
-				gfs2_free_meta(ip, bstart, blen);
-			bstart = bn;
-			blen = 1;
-		}
-
-		*dataptrs = 0;
-		gfs2_add_inode_blocks(&ip->i_inode, -1);
-	}
-	if (bstart)
-		gfs2_free_meta(ip, bstart, blen);
-
-	if (prev && !leave) {
-		u32 len;
-
-		len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
-		prev->ea_rec_len = cpu_to_be32(len);
-
-		if (GFS2_EA_IS_LAST(ea))
-			prev->ea_flags |= GFS2_EAFLAG_LAST;
-	} else {
-		ea->ea_type = GFS2_EATYPE_UNUSED;
-		ea->ea_num_ptrs = 0;
-	}
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (!error) {
-		ip->i_inode.i_ctime = CURRENT_TIME;
-		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-		gfs2_dinode_out(ip, dibh->b_data);
-		brelse(dibh);
-	}
-
-	gfs2_trans_end(sdp);
-
-out_gunlock:
-	gfs2_glock_dq_uninit(&rg_gh);
-	return error;
-}
-
-static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
-			       struct gfs2_ea_header *ea,
-			       struct gfs2_ea_header *prev, int leave)
-{
-	struct gfs2_alloc *al;
-	int error;
-
-	al = gfs2_alloc_get(ip);
-	if (!al)
-		return -ENOMEM;
-
-	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
-	if (error)
-		goto out_alloc;
-
-	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
-	if (error)
-		goto out_quota;
-
-	error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL);
-
-	gfs2_glock_dq_uninit(&al->al_ri_gh);
-
-out_quota:
-	gfs2_quota_unhold(ip);
-out_alloc:
-	gfs2_alloc_put(ip);
-	return error;
-}
-
-struct ea_list {
-	struct gfs2_ea_request *ei_er;
-	unsigned int ei_size;
-};
-
-static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
-		     struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
-		     void *private)
-{
-	struct ea_list *ei = private;
-	struct gfs2_ea_request *er = ei->ei_er;
-	unsigned int ea_size = gfs2_ea_strlen(ea);
-
-	if (ea->ea_type == GFS2_EATYPE_UNUSED)
-		return 0;
-
-	if (er->er_data_len) {
-		char *prefix = NULL;
-		unsigned int l = 0;
-		char c = 0;
-
-		if (ei->ei_size + ea_size > er->er_data_len)
-			return -ERANGE;
-
-		switch (ea->ea_type) {
-		case GFS2_EATYPE_USR:
-			prefix = "user.";
-			l = 5;
-			break;
-		case GFS2_EATYPE_SYS:
-			prefix = "system.";
-			l = 7;
-			break;
-		case GFS2_EATYPE_SECURITY:
-			prefix = "security.";
-			l = 9;
-			break;
-		}
-
-		BUG_ON(l == 0);
-
-		memcpy(er->er_data + ei->ei_size, prefix, l);
-		memcpy(er->er_data + ei->ei_size + l, GFS2_EA2NAME(ea),
-		       ea->ea_name_len);
-		memcpy(er->er_data + ei->ei_size + ea_size - 1, &c, 1);
-	}
-
-	ei->ei_size += ea_size;
-
-	return 0;
-}
-
-/**
- * gfs2_ea_list -
- * @ip:
- * @er:
- *
- * Returns: actual size of data on success, -errno on error
- */
-
-int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	struct gfs2_holder i_gh;
-	int error;
-
-	if (!er->er_data || !er->er_data_len) {
-		er->er_data = NULL;
-		er->er_data_len = 0;
-	}
-
-	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
-	if (error)
-		return error;
-
-	if (ip->i_eattr) {
-		struct ea_list ei = { .ei_er = er, .ei_size = 0 };
-
-		error = ea_foreach(ip, ea_list_i, &ei);
-		if (!error)
-			error = ei.ei_size;
-	}
-
-	gfs2_glock_dq_uninit(&i_gh);
-
-	return error;
-}
-
-/**
- * ea_get_unstuffed - actually copies the unstuffed data into the
- *                    request buffer
- * @ip: The GFS2 inode
- * @ea: The extended attribute header structure
- * @data: The data to be copied
- *
- * Returns: errno
- */
-
-static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
-			    char *data)
-{
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	struct buffer_head **bh;
-	unsigned int amount = GFS2_EA_DATA_LEN(ea);
-	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
-	__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
-	unsigned int x;
-	int error = 0;
-
-	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
-	if (!bh)
-		return -ENOMEM;
-
-	for (x = 0; x < nptrs; x++) {
-		error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
-				       bh + x);
-		if (error) {
-			while (x--)
-				brelse(bh[x]);
-			goto out;
-		}
-		dataptrs++;
-	}
-
-	for (x = 0; x < nptrs; x++) {
-		error = gfs2_meta_wait(sdp, bh[x]);
-		if (error) {
-			for (; x < nptrs; x++)
-				brelse(bh[x]);
-			goto out;
-		}
-		if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
-			for (; x < nptrs; x++)
-				brelse(bh[x]);
-			error = -EIO;
-			goto out;
-		}
-
-		memcpy(data, bh[x]->b_data + sizeof(struct gfs2_meta_header),
-		       (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
-
-		amount -= sdp->sd_jbsize;
-		data += sdp->sd_jbsize;
-
-		brelse(bh[x]);
-	}
-
-out:
-	kfree(bh);
-	return error;
-}
-
-int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
-		     char *data)
-{
-	if (GFS2_EA_IS_STUFFED(el->el_ea)) {
-		memcpy(data, GFS2_EA2DATA(el->el_ea), GFS2_EA_DATA_LEN(el->el_ea));
-		return 0;
-	} else
-		return ea_get_unstuffed(ip, el->el_ea, data);
-}
-
-/**
- * gfs2_ea_get_i -
- * @ip: The GFS2 inode
- * @er: The request structure
- *
- * Returns: actual size of data on success, -errno on error
- */
-
-int gfs2_ea_get_i(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	struct gfs2_ea_location el;
-	int error;
-
-	if (!ip->i_eattr)
-		return -ENODATA;
-
-	error = gfs2_ea_find(ip, er, &el);
-	if (error)
-		return error;
-	if (!el.el_ea)
-		return -ENODATA;
-
-	if (er->er_data_len) {
-		if (GFS2_EA_DATA_LEN(el.el_ea) > er->er_data_len)
-			error =  -ERANGE;
-		else
-			error = gfs2_ea_get_copy(ip, &el, er->er_data);
-	}
-	if (!error)
-		error = GFS2_EA_DATA_LEN(el.el_ea);
-
-	brelse(el.el_bh);
-
-	return error;
-}
-
-/**
- * gfs2_ea_get -
- * @ip: The GFS2 inode
- * @er: The request structure
- *
- * Returns: actual size of data on success, -errno on error
- */
-
-int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	struct gfs2_holder i_gh;
-	int error;
-
-	if (!er->er_name_len ||
-	    er->er_name_len > GFS2_EA_MAX_NAME_LEN)
-		return -EINVAL;
-	if (!er->er_data || !er->er_data_len) {
-		er->er_data = NULL;
-		er->er_data_len = 0;
-	}
-
-	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
-	if (error)
-		return error;
-
-	error = gfs2_ea_ops[er->er_type]->eo_get(ip, er);
-
-	gfs2_glock_dq_uninit(&i_gh);
-
-	return error;
-}
-
-/**
- * ea_alloc_blk - allocates a new block for extended attributes.
- * @ip: A pointer to the inode that's getting extended attributes
- * @bhp: Pointer to pointer to a struct buffer_head
- *
- * Returns: errno
- */
-
-static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
-{
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	struct gfs2_ea_header *ea;
-	unsigned int n = 1;
-	u64 block;
-	int error;
-
-	error = gfs2_alloc_block(ip, &block, &n);
-	if (error)
-		return error;
-	gfs2_trans_add_unrevoke(sdp, block, 1);
-	*bhp = gfs2_meta_new(ip->i_gl, block);
-	gfs2_trans_add_bh(ip->i_gl, *bhp, 1);
-	gfs2_metatype_set(*bhp, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
-	gfs2_buffer_clear_tail(*bhp, sizeof(struct gfs2_meta_header));
-
-	ea = GFS2_EA_BH2FIRST(*bhp);
-	ea->ea_rec_len = cpu_to_be32(sdp->sd_jbsize);
-	ea->ea_type = GFS2_EATYPE_UNUSED;
-	ea->ea_flags = GFS2_EAFLAG_LAST;
-	ea->ea_num_ptrs = 0;
-
-	gfs2_add_inode_blocks(&ip->i_inode, 1);
-
-	return 0;
-}
-
-/**
- * ea_write - writes the request info to an ea, creating new blocks if
- *            necessary
- * @ip: inode that is being modified
- * @ea: the location of the new ea in a block
- * @er: the write request
- *
- * Note: does not update ea_rec_len or the GFS2_EAFLAG_LAST bin of ea_flags
- *
- * returns : errno
- */
-
-static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
-		    struct gfs2_ea_request *er)
-{
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	int error;
-
-	ea->ea_data_len = cpu_to_be32(er->er_data_len);
-	ea->ea_name_len = er->er_name_len;
-	ea->ea_type = er->er_type;
-	ea->__pad = 0;
-
-	memcpy(GFS2_EA2NAME(ea), er->er_name, er->er_name_len);
-
-	if (GFS2_EAREQ_SIZE_STUFFED(er) <= sdp->sd_jbsize) {
-		ea->ea_num_ptrs = 0;
-		memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len);
-	} else {
-		__be64 *dataptr = GFS2_EA2DATAPTRS(ea);
-		const char *data = er->er_data;
-		unsigned int data_len = er->er_data_len;
-		unsigned int copy;
-		unsigned int x;
-
-		ea->ea_num_ptrs = DIV_ROUND_UP(er->er_data_len, sdp->sd_jbsize);
-		for (x = 0; x < ea->ea_num_ptrs; x++) {
-			struct buffer_head *bh;
-			u64 block;
-			int mh_size = sizeof(struct gfs2_meta_header);
-			unsigned int n = 1;
-
-			error = gfs2_alloc_block(ip, &block, &n);
-			if (error)
-				return error;
-			gfs2_trans_add_unrevoke(sdp, block, 1);
-			bh = gfs2_meta_new(ip->i_gl, block);
-			gfs2_trans_add_bh(ip->i_gl, bh, 1);
-			gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);
-
-			gfs2_add_inode_blocks(&ip->i_inode, 1);
-
-			copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
-							   data_len;
-			memcpy(bh->b_data + mh_size, data, copy);
-			if (copy < sdp->sd_jbsize)
-				memset(bh->b_data + mh_size + copy, 0,
-				       sdp->sd_jbsize - copy);
-
-			*dataptr++ = cpu_to_be64(bh->b_blocknr);
-			data += copy;
-			data_len -= copy;
-
-			brelse(bh);
-		}
-
-		gfs2_assert_withdraw(sdp, !data_len);
-	}
-
-	return 0;
-}
-
-typedef int (*ea_skeleton_call_t) (struct gfs2_inode *ip,
-				   struct gfs2_ea_request *er, void *private);
-
-static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
-			     unsigned int blks,
-			     ea_skeleton_call_t skeleton_call, void *private)
-{
-	struct gfs2_alloc *al;
-	struct buffer_head *dibh;
-	int error;
-
-	al = gfs2_alloc_get(ip);
-	if (!al)
-		return -ENOMEM;
-
-	error = gfs2_quota_lock_check(ip);
-	if (error)
-		goto out;
-
-	al->al_requested = blks;
-
-	error = gfs2_inplace_reserve(ip);
-	if (error)
-		goto out_gunlock_q;
-
-	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
-				 blks + al->al_rgd->rd_length +
-				 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
-	if (error)
-		goto out_ipres;
-
-	error = skeleton_call(ip, er, private);
-	if (error)
-		goto out_end_trans;
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (!error) {
-		if (er->er_flags & GFS2_ERF_MODE) {
-			gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
-					    (ip->i_inode.i_mode & S_IFMT) ==
-					    (er->er_mode & S_IFMT));
-			ip->i_inode.i_mode = er->er_mode;
-		}
-		ip->i_inode.i_ctime = CURRENT_TIME;
-		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-		gfs2_dinode_out(ip, dibh->b_data);
-		brelse(dibh);
-	}
-
-out_end_trans:
-	gfs2_trans_end(GFS2_SB(&ip->i_inode));
-out_ipres:
-	gfs2_inplace_release(ip);
-out_gunlock_q:
-	gfs2_quota_unlock(ip);
-out:
-	gfs2_alloc_put(ip);
-	return error;
-}
-
-static int ea_init_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
-		     void *private)
-{
-	struct buffer_head *bh;
-	int error;
-
-	error = ea_alloc_blk(ip, &bh);
-	if (error)
-		return error;
-
-	ip->i_eattr = bh->b_blocknr;
-	error = ea_write(ip, GFS2_EA_BH2FIRST(bh), er);
-
-	brelse(bh);
-
-	return error;
-}
-
-/**
- * ea_init - initializes a new eattr block
- * @ip:
- * @er:
- *
- * Returns: errno
- */
-
-static int ea_init(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
-	unsigned int blks = 1;
-
-	if (GFS2_EAREQ_SIZE_STUFFED(er) > jbsize)
-		blks += DIV_ROUND_UP(er->er_data_len, jbsize);
-
-	return ea_alloc_skeleton(ip, er, blks, ea_init_i, NULL);
-}
-
-static struct gfs2_ea_header *ea_split_ea(struct gfs2_ea_header *ea)
-{
-	u32 ea_size = GFS2_EA_SIZE(ea);
-	struct gfs2_ea_header *new = (struct gfs2_ea_header *)((char *)ea +
-				     ea_size);
-	u32 new_size = GFS2_EA_REC_LEN(ea) - ea_size;
-	int last = ea->ea_flags & GFS2_EAFLAG_LAST;
-
-	ea->ea_rec_len = cpu_to_be32(ea_size);
-	ea->ea_flags ^= last;
-
-	new->ea_rec_len = cpu_to_be32(new_size);
-	new->ea_flags = last;
-
-	return new;
-}
-
-static void ea_set_remove_stuffed(struct gfs2_inode *ip,
-				  struct gfs2_ea_location *el)
-{
-	struct gfs2_ea_header *ea = el->el_ea;
-	struct gfs2_ea_header *prev = el->el_prev;
-	u32 len;
-
-	gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
-
-	if (!prev || !GFS2_EA_IS_STUFFED(ea)) {
-		ea->ea_type = GFS2_EATYPE_UNUSED;
-		return;
-	} else if (GFS2_EA2NEXT(prev) != ea) {
-		prev = GFS2_EA2NEXT(prev);
-		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), GFS2_EA2NEXT(prev) == ea);
-	}
-
-	len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
-	prev->ea_rec_len = cpu_to_be32(len);
-
-	if (GFS2_EA_IS_LAST(ea))
-		prev->ea_flags |= GFS2_EAFLAG_LAST;
-}
-
-struct ea_set {
-	int ea_split;
-
-	struct gfs2_ea_request *es_er;
-	struct gfs2_ea_location *es_el;
-
-	struct buffer_head *es_bh;
-	struct gfs2_ea_header *es_ea;
-};
-
-static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
-				 struct gfs2_ea_header *ea, struct ea_set *es)
-{
-	struct gfs2_ea_request *er = es->es_er;
-	struct buffer_head *dibh;
-	int error;
-
-	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
-	if (error)
-		return error;
-
-	gfs2_trans_add_bh(ip->i_gl, bh, 1);
-
-	if (es->ea_split)
-		ea = ea_split_ea(ea);
-
-	ea_write(ip, ea, er);
-
-	if (es->es_el)
-		ea_set_remove_stuffed(ip, es->es_el);
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (error)
-		goto out;
-
-	if (er->er_flags & GFS2_ERF_MODE) {
-		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
-			(ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT));
-		ip->i_inode.i_mode = er->er_mode;
-	}
-	ip->i_inode.i_ctime = CURRENT_TIME;
-	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-	gfs2_dinode_out(ip, dibh->b_data);
-	brelse(dibh);
-out:
-	gfs2_trans_end(GFS2_SB(&ip->i_inode));
-	return error;
-}
-
-static int ea_set_simple_alloc(struct gfs2_inode *ip,
-			       struct gfs2_ea_request *er, void *private)
-{
-	struct ea_set *es = private;
-	struct gfs2_ea_header *ea = es->es_ea;
-	int error;
-
-	gfs2_trans_add_bh(ip->i_gl, es->es_bh, 1);
-
-	if (es->ea_split)
-		ea = ea_split_ea(ea);
-
-	error = ea_write(ip, ea, er);
-	if (error)
-		return error;
-
-	if (es->es_el)
-		ea_set_remove_stuffed(ip, es->es_el);
-
-	return 0;
-}
-
-static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
-			 struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
-			 void *private)
-{
-	struct ea_set *es = private;
-	unsigned int size;
-	int stuffed;
-	int error;
-
-	stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er, &size);
-
-	if (ea->ea_type == GFS2_EATYPE_UNUSED) {
-		if (GFS2_EA_REC_LEN(ea) < size)
-			return 0;
-		if (!GFS2_EA_IS_STUFFED(ea)) {
-			error = ea_remove_unstuffed(ip, bh, ea, prev, 1);
-			if (error)
-				return error;
-		}
-		es->ea_split = 0;
-	} else if (GFS2_EA_REC_LEN(ea) - GFS2_EA_SIZE(ea) >= size)
-		es->ea_split = 1;
-	else
-		return 0;
-
-	if (stuffed) {
-		error = ea_set_simple_noalloc(ip, bh, ea, es);
-		if (error)
-			return error;
-	} else {
-		unsigned int blks;
-
-		es->es_bh = bh;
-		es->es_ea = ea;
-		blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
-					GFS2_SB(&ip->i_inode)->sd_jbsize);
-
-		error = ea_alloc_skeleton(ip, es->es_er, blks,
-					  ea_set_simple_alloc, es);
-		if (error)
-			return error;
-	}
-
-	return 1;
-}
-
-static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
-			void *private)
-{
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	struct buffer_head *indbh, *newbh;
-	__be64 *eablk;
-	int error;
-	int mh_size = sizeof(struct gfs2_meta_header);
-
-	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
-		__be64 *end;
-
-		error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT,
-				       &indbh);
-		if (error)
-			return error;
-
-		if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
-			error = -EIO;
-			goto out;
-		}
-
-		eablk = (__be64 *)(indbh->b_data + mh_size);
-		end = eablk + sdp->sd_inptrs;
-
-		for (; eablk < end; eablk++)
-			if (!*eablk)
-				break;
-
-		if (eablk == end) {
-			error = -ENOSPC;
-			goto out;
-		}
-
-		gfs2_trans_add_bh(ip->i_gl, indbh, 1);
-	} else {
-		u64 blk;
-		unsigned int n = 1;
-		error = gfs2_alloc_block(ip, &blk, &n);
-		if (error)
-			return error;
-		gfs2_trans_add_unrevoke(sdp, blk, 1);
-		indbh = gfs2_meta_new(ip->i_gl, blk);
-		gfs2_trans_add_bh(ip->i_gl, indbh, 1);
-		gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
-		gfs2_buffer_clear_tail(indbh, mh_size);
-
-		eablk = (__be64 *)(indbh->b_data + mh_size);
-		*eablk = cpu_to_be64(ip->i_eattr);
-		ip->i_eattr = blk;
-		ip->i_diskflags |= GFS2_DIF_EA_INDIRECT;
-		gfs2_add_inode_blocks(&ip->i_inode, 1);
-
-		eablk++;
-	}
-
-	error = ea_alloc_blk(ip, &newbh);
-	if (error)
-		goto out;
-
-	*eablk = cpu_to_be64((u64)newbh->b_blocknr);
-	error = ea_write(ip, GFS2_EA_BH2FIRST(newbh), er);
-	brelse(newbh);
-	if (error)
-		goto out;
-
-	if (private)
-		ea_set_remove_stuffed(ip, private);
-
-out:
-	brelse(indbh);
-	return error;
-}
-
-static int ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
-		    struct gfs2_ea_location *el)
-{
-	struct ea_set es;
-	unsigned int blks = 2;
-	int error;
-
-	memset(&es, 0, sizeof(struct ea_set));
-	es.es_er = er;
-	es.es_el = el;
-
-	error = ea_foreach(ip, ea_set_simple, &es);
-	if (error > 0)
-		return 0;
-	if (error)
-		return error;
-
-	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT))
-		blks++;
-	if (GFS2_EAREQ_SIZE_STUFFED(er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
-		blks += DIV_ROUND_UP(er->er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
-
-	return ea_alloc_skeleton(ip, er, blks, ea_set_block, el);
-}
-
-static int ea_set_remove_unstuffed(struct gfs2_inode *ip,
-				   struct gfs2_ea_location *el)
-{
-	if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
-		el->el_prev = GFS2_EA2NEXT(el->el_prev);
-		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
-				     GFS2_EA2NEXT(el->el_prev) == el->el_ea);
-	}
-
-	return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev,0);
-}
-
-int gfs2_ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	struct gfs2_ea_location el;
-	int error;
-
-	if (!ip->i_eattr) {
-		if (er->er_flags & XATTR_REPLACE)
-			return -ENODATA;
-		return ea_init(ip, er);
-	}
-
-	error = gfs2_ea_find(ip, er, &el);
-	if (error)
-		return error;
-
-	if (el.el_ea) {
-		if (ip->i_diskflags & GFS2_DIF_APPENDONLY) {
-			brelse(el.el_bh);
-			return -EPERM;
-		}
-
-		error = -EEXIST;
-		if (!(er->er_flags & XATTR_CREATE)) {
-			int unstuffed = !GFS2_EA_IS_STUFFED(el.el_ea);
-			error = ea_set_i(ip, er, &el);
-			if (!error && unstuffed)
-				ea_set_remove_unstuffed(ip, &el);
-		}
-
-		brelse(el.el_bh);
-	} else {
-		error = -ENODATA;
-		if (!(er->er_flags & XATTR_REPLACE))
-			error = ea_set_i(ip, er, NULL);
-	}
-
-	return error;
-}
-
-int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	struct gfs2_holder i_gh;
-	int error;
-
-	if (!er->er_name_len || er->er_name_len > GFS2_EA_MAX_NAME_LEN)
-		return -EINVAL;
-	if (!er->er_data || !er->er_data_len) {
-		er->er_data = NULL;
-		er->er_data_len = 0;
-	}
-	error = ea_check_size(GFS2_SB(&ip->i_inode), er);
-	if (error)
-		return error;
-
-	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
-	if (error)
-		return error;
-
-	if (IS_IMMUTABLE(&ip->i_inode))
-		error = -EPERM;
-	else
-		error = gfs2_ea_ops[er->er_type]->eo_set(ip, er);
-
-	gfs2_glock_dq_uninit(&i_gh);
-
-	return error;
-}
-
-static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
-{
-	struct gfs2_ea_header *ea = el->el_ea;
-	struct gfs2_ea_header *prev = el->el_prev;
-	struct buffer_head *dibh;
-	int error;
-
-	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
-	if (error)
-		return error;
-
-	gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
-
-	if (prev) {
-		u32 len;
-
-		len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
-		prev->ea_rec_len = cpu_to_be32(len);
-
-		if (GFS2_EA_IS_LAST(ea))
-			prev->ea_flags |= GFS2_EAFLAG_LAST;
-	} else
-		ea->ea_type = GFS2_EATYPE_UNUSED;
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (!error) {
-		ip->i_inode.i_ctime = CURRENT_TIME;
-		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-		gfs2_dinode_out(ip, dibh->b_data);
-		brelse(dibh);
-	}
-
-	gfs2_trans_end(GFS2_SB(&ip->i_inode));
-
-	return error;
-}
-
-int gfs2_ea_remove_i(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	struct gfs2_ea_location el;
-	int error;
-
-	if (!ip->i_eattr)
-		return -ENODATA;
-
-	error = gfs2_ea_find(ip, er, &el);
-	if (error)
-		return error;
-	if (!el.el_ea)
-		return -ENODATA;
-
-	if (GFS2_EA_IS_STUFFED(el.el_ea))
-		error = ea_remove_stuffed(ip, &el);
-	else
-		error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev,
-					    0);
-
-	brelse(el.el_bh);
-
-	return error;
-}
-
-/**
- * gfs2_ea_remove - sets (or creates or replaces) an extended attribute
- * @ip: pointer to the inode of the target file
- * @er: request information
- *
- * Returns: errno
- */
-
-int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er)
-{
-	struct gfs2_holder i_gh;
-	int error;
-
-	if (!er->er_name_len || er->er_name_len > GFS2_EA_MAX_NAME_LEN)
-		return -EINVAL;
-
-	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
-	if (error)
-		return error;
-
-	if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
-		error = -EPERM;
-	else
-		error = gfs2_ea_ops[er->er_type]->eo_remove(ip, er);
-
-	gfs2_glock_dq_uninit(&i_gh);
-
-	return error;
-}
-
-static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
-				  struct gfs2_ea_header *ea, char *data)
-{
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	struct buffer_head **bh;
-	unsigned int amount = GFS2_EA_DATA_LEN(ea);
-	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
-	__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
-	unsigned int x;
-	int error;
-
-	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
-	if (!bh)
-		return -ENOMEM;
-
-	error = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
-	if (error)
-		goto out;
-
-	for (x = 0; x < nptrs; x++) {
-		error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
-				       bh + x);
-		if (error) {
-			while (x--)
-				brelse(bh[x]);
-			goto fail;
-		}
-		dataptrs++;
-	}
-
-	for (x = 0; x < nptrs; x++) {
-		error = gfs2_meta_wait(sdp, bh[x]);
-		if (error) {
-			for (; x < nptrs; x++)
-				brelse(bh[x]);
-			goto fail;
-		}
-		if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
-			for (; x < nptrs; x++)
-				brelse(bh[x]);
-			error = -EIO;
-			goto fail;
-		}
-
-		gfs2_trans_add_bh(ip->i_gl, bh[x], 1);
-
-		memcpy(bh[x]->b_data + sizeof(struct gfs2_meta_header), data,
-		       (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
-
-		amount -= sdp->sd_jbsize;
-		data += sdp->sd_jbsize;
-
-		brelse(bh[x]);
-	}
-
-out:
-	kfree(bh);
-	return error;
-
-fail:
-	gfs2_trans_end(sdp);
-	kfree(bh);
-	return error;
-}
-
-int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
-		      struct iattr *attr, char *data)
-{
-	struct buffer_head *dibh;
-	int error;
-
-	if (GFS2_EA_IS_STUFFED(el->el_ea)) {
-		error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
-		if (error)
-			return error;
-
-		gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
-		memcpy(GFS2_EA2DATA(el->el_ea), data,
-		       GFS2_EA_DATA_LEN(el->el_ea));
-	} else
-		error = ea_acl_chmod_unstuffed(ip, el->el_ea, data);
-
-	if (error)
-		return error;
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (!error) {
-		error = inode_setattr(&ip->i_inode, attr);
-		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
-		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-		gfs2_dinode_out(ip, dibh->b_data);
-		brelse(dibh);
-	}
-
-	gfs2_trans_end(GFS2_SB(&ip->i_inode));
-
-	return error;
-}
-
-static int ea_dealloc_indirect(struct gfs2_inode *ip)
-{
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	struct gfs2_rgrp_list rlist;
-	struct buffer_head *indbh, *dibh;
-	__be64 *eablk, *end;
-	unsigned int rg_blocks = 0;
-	u64 bstart = 0;
-	unsigned int blen = 0;
-	unsigned int blks = 0;
-	unsigned int x;
-	int error;
-
-	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
-
-	error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh);
-	if (error)
-		return error;
-
-	if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
-		error = -EIO;
-		goto out;
-	}
-
-	eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
-	end = eablk + sdp->sd_inptrs;
-
-	for (; eablk < end; eablk++) {
-		u64 bn;
-
-		if (!*eablk)
-			break;
-		bn = be64_to_cpu(*eablk);
-
-		if (bstart + blen == bn)
-			blen++;
-		else {
-			if (bstart)
-				gfs2_rlist_add(sdp, &rlist, bstart);
-			bstart = bn;
-			blen = 1;
-		}
-		blks++;
-	}
-	if (bstart)
-		gfs2_rlist_add(sdp, &rlist, bstart);
-	else
-		goto out;
-
-	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
-
-	for (x = 0; x < rlist.rl_rgrps; x++) {
-		struct gfs2_rgrpd *rgd;
-		rgd = rlist.rl_ghs[x].gh_gl->gl_object;
-		rg_blocks += rgd->rd_length;
-	}
-
-	error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
-	if (error)
-		goto out_rlist_free;
-
-	error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + RES_INDIRECT +
-				 RES_STATFS + RES_QUOTA, blks);
-	if (error)
-		goto out_gunlock;
-
-	gfs2_trans_add_bh(ip->i_gl, indbh, 1);
-
-	eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
-	bstart = 0;
-	blen = 0;
-
-	for (; eablk < end; eablk++) {
-		u64 bn;
-
-		if (!*eablk)
-			break;
-		bn = be64_to_cpu(*eablk);
-
-		if (bstart + blen == bn)
-			blen++;
-		else {
-			if (bstart)
-				gfs2_free_meta(ip, bstart, blen);
-			bstart = bn;
-			blen = 1;
-		}
-
-		*eablk = 0;
-		gfs2_add_inode_blocks(&ip->i_inode, -1);
-	}
-	if (bstart)
-		gfs2_free_meta(ip, bstart, blen);
-
-	ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT;
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (!error) {
-		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-		gfs2_dinode_out(ip, dibh->b_data);
-		brelse(dibh);
-	}
-
-	gfs2_trans_end(sdp);
-
-out_gunlock:
-	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
-out_rlist_free:
-	gfs2_rlist_free(&rlist);
-out:
-	brelse(indbh);
-	return error;
-}
-
-static int ea_dealloc_block(struct gfs2_inode *ip)
-{
-	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-	struct gfs2_alloc *al = ip->i_alloc;
-	struct gfs2_rgrpd *rgd;
-	struct buffer_head *dibh;
-	int error;
-
-	rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr);
-	if (!rgd) {
-		gfs2_consist_inode(ip);
-		return -EIO;
-	}
-
-	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
-				   &al->al_rgd_gh);
-	if (error)
-		return error;
-
-	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_DINODE + RES_STATFS +
-				 RES_QUOTA, 1);
-	if (error)
-		goto out_gunlock;
-
-	gfs2_free_meta(ip, ip->i_eattr, 1);
-
-	ip->i_eattr = 0;
-	gfs2_add_inode_blocks(&ip->i_inode, -1);
-
-	error = gfs2_meta_inode_buffer(ip, &dibh);
-	if (!error) {
-		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-		gfs2_dinode_out(ip, dibh->b_data);
-		brelse(dibh);
-	}
-
-	gfs2_trans_end(sdp);
-
-out_gunlock:
-	gfs2_glock_dq_uninit(&al->al_rgd_gh);
-	return error;
-}
-
-/**
- * gfs2_ea_dealloc - deallocate the extended attribute fork
- * @ip: the inode
- *
- * Returns: errno
- */
-
-int gfs2_ea_dealloc(struct gfs2_inode *ip)
-{
-	struct gfs2_alloc *al;
-	int error;
-
-	al = gfs2_alloc_get(ip);
-	if (!al)
-		return -ENOMEM;
-
-	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
-	if (error)
-		goto out_alloc;
-
-	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
-	if (error)
-		goto out_quota;
-
-	error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
-	if (error)
-		goto out_rindex;
-
-	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
-		error = ea_dealloc_indirect(ip);
-		if (error)
-			goto out_rindex;
-	}
-
-	error = ea_dealloc_block(ip);
-
-out_rindex:
-	gfs2_glock_dq_uninit(&al->al_ri_gh);
-out_quota:
-	gfs2_quota_unhold(ip);
-out_alloc:
-	gfs2_alloc_put(ip);
-	return error;
-}
-
diff --git a/fs/gfs2/eattr.h b/fs/gfs2/eattr.h
deleted file mode 100644
index c82dbe0..0000000
--- a/fs/gfs2/eattr.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
- *
- * This copyrighted material is made available to anyone wishing to use,
- * modify, copy, or redistribute it subject to the terms and conditions
- * of the GNU General Public License version 2.
- */
-
-#ifndef __EATTR_DOT_H__
-#define __EATTR_DOT_H__
-
-struct gfs2_inode;
-struct iattr;
-
-#define GFS2_EA_REC_LEN(ea) be32_to_cpu((ea)->ea_rec_len)
-#define GFS2_EA_DATA_LEN(ea) be32_to_cpu((ea)->ea_data_len)
-
-#define GFS2_EA_SIZE(ea) \
-ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \
-      ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \
-                                  (sizeof(__be64) * (ea)->ea_num_ptrs)), 8)
-
-#define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs)
-#define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST)
-
-#define GFS2_EAREQ_SIZE_STUFFED(er) \
-ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + (er)->er_data_len, 8)
-
-#define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \
-ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \
-      sizeof(__be64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8)
-
-#define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1))
-#define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len)
-
-#define GFS2_EA2DATAPTRS(ea) \
-((__be64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8)))
-
-#define GFS2_EA2NEXT(ea) \
-((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea)))
-
-#define GFS2_EA_BH2FIRST(bh) \
-((struct gfs2_ea_header *)((bh)->b_data + sizeof(struct gfs2_meta_header)))
-
-#define GFS2_ERF_MODE 0x80000000
-
-struct gfs2_ea_request {
-	const char *er_name;
-	char *er_data;
-	unsigned int er_name_len;
-	unsigned int er_data_len;
-	unsigned int er_type; /* GFS2_EATYPE_... */
-	int er_flags;
-	mode_t er_mode;
-};
-
-struct gfs2_ea_location {
-	struct buffer_head *el_bh;
-	struct gfs2_ea_header *el_ea;
-	struct gfs2_ea_header *el_prev;
-};
-
-int gfs2_ea_get_i(struct gfs2_inode *ip, struct gfs2_ea_request *er);
-int gfs2_ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er);
-int gfs2_ea_remove_i(struct gfs2_inode *ip, struct gfs2_ea_request *er);
-
-int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er);
-int gfs2_ea_get(struct gfs2_inode *ip, struct gfs2_ea_request *er);
-int gfs2_ea_set(struct gfs2_inode *ip, struct gfs2_ea_request *er);
-int gfs2_ea_remove(struct gfs2_inode *ip, struct gfs2_ea_request *er);
-
-int gfs2_ea_dealloc(struct gfs2_inode *ip);
-
-/* Exported to acl.c */
-
-int gfs2_ea_find(struct gfs2_inode *ip,
-		 struct gfs2_ea_request *er,
-		 struct gfs2_ea_location *el);
-int gfs2_ea_get_copy(struct gfs2_inode *ip,
-		     struct gfs2_ea_location *el,
-		     char *data);
-int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
-		      struct iattr *attr, char *data);
-
-static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea)
-{
-	switch (ea->ea_type) {
-	case GFS2_EATYPE_USR:
-		return 5 + ea->ea_name_len + 1;
-	case GFS2_EATYPE_SYS:
-		return 7 + ea->ea_name_len + 1;
-	case GFS2_EATYPE_SECURITY:
-		return 9 + ea->ea_name_len + 1;
-	default:
-		return 0;
-	}
-}
-
-#endif /* __EATTR_DOT_H__ */
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index 9200ef2..d15876e 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -143,17 +143,14 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
 }
 
 static struct dentry *gfs2_get_dentry(struct super_block *sb,
-		struct gfs2_inum_host *inum)
+				      struct gfs2_inum_host *inum)
 {
 	struct gfs2_sbd *sdp = sb->s_fs_info;
-	struct gfs2_holder i_gh, ri_gh, rgd_gh;
-	struct gfs2_rgrpd *rgd;
+	struct gfs2_holder i_gh;
 	struct inode *inode;
 	struct dentry *dentry;
 	int error;
 
-	/* System files? */
-
 	inode = gfs2_ilookup(sb, inum->no_addr);
 	if (inode) {
 		if (GFS2_I(inode)->i_no_formal_ino != inum->no_formal_ino) {
@@ -168,29 +165,11 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb,
 	if (error)
 		return ERR_PTR(error);
 
-	error = gfs2_rindex_hold(sdp, &ri_gh);
+	error = gfs2_check_blk_type(sdp, inum->no_addr, GFS2_BLKST_DINODE);
 	if (error)
 		goto fail;
 
-	error = -EINVAL;
-	rgd = gfs2_blk2rgrpd(sdp, inum->no_addr);
-	if (!rgd)
-		goto fail_rindex;
-
-	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh);
-	if (error)
-		goto fail_rindex;
-
-	error = -ESTALE;
-	if (gfs2_get_block_type(rgd, inum->no_addr) != GFS2_BLKST_DINODE)
-		goto fail_rgd;
-
-	gfs2_glock_dq_uninit(&rgd_gh);
-	gfs2_glock_dq_uninit(&ri_gh);
-
-	inode = gfs2_inode_lookup(sb, DT_UNKNOWN,
-					inum->no_addr,
-					0, 0);
+	inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0, 0);
 	if (IS_ERR(inode)) {
 		error = PTR_ERR(inode);
 		goto fail;
@@ -224,13 +203,6 @@ out_inode:
 	if (!IS_ERR(dentry))
 		dentry->d_op = &gfs2_dops;
 	return dentry;
-
-fail_rgd:
-	gfs2_glock_dq_uninit(&rgd_gh);
-
-fail_rindex:
-	gfs2_glock_dq_uninit(&ri_gh);
-
 fail:
 	gfs2_glock_dq_uninit(&i_gh);
 	return ERR_PTR(error);
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 73318a3..166f38f 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -38,7 +38,6 @@
 #include "rgrp.h"
 #include "trans.h"
 #include "util.h"
-#include "eaops.h"
 
 /**
  * gfs2_llseek - seek to a location in a file
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 61801ad..6edb423 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -406,6 +406,12 @@ struct gfs2_statfs_change_host {
 #define GFS2_DATA_WRITEBACK	1
 #define GFS2_DATA_ORDERED	2
 
+#define GFS2_ERRORS_DEFAULT     GFS2_ERRORS_WITHDRAW
+#define GFS2_ERRORS_WITHDRAW    0
+#define GFS2_ERRORS_CONTINUE    1 /* place holder for future feature */
+#define GFS2_ERRORS_RO          2 /* place holder for future feature */
+#define GFS2_ERRORS_PANIC       3
+
 struct gfs2_args {
 	char ar_lockproto[GFS2_LOCKNAME_LEN];	/* Name of the Lock Protocol */
 	char ar_locktable[GFS2_LOCKNAME_LEN];	/* Name of the Lock Table */
@@ -422,6 +428,7 @@ struct gfs2_args {
 	unsigned int ar_data:2;			/* ordered/writeback */
 	unsigned int ar_meta:1;			/* mount metafs */
 	unsigned int ar_discard:1;		/* discard requests */
+	unsigned int ar_errors:2;               /* errors=withdraw | panic */
 	int ar_commit;				/* Commit interval */
 };
 
@@ -489,7 +496,6 @@ struct gfs2_sb_host {
  */
 
 struct lm_lockstruct {
-	u32 ls_id;
 	unsigned int ls_jid;
 	unsigned int ls_first;
 	unsigned int ls_first_done;
@@ -541,18 +547,12 @@ struct gfs2_sbd {
 	struct dentry *sd_root_dir;
 
 	struct inode *sd_jindex;
-	struct inode *sd_inum_inode;
 	struct inode *sd_statfs_inode;
-	struct inode *sd_ir_inode;
 	struct inode *sd_sc_inode;
 	struct inode *sd_qc_inode;
 	struct inode *sd_rindex;
 	struct inode *sd_quota_inode;
 
-	/* Inum stuff */
-
-	struct mutex sd_inum_mutex;
-
 	/* StatFS stuff */
 
 	spinlock_t sd_statfs_spin;
@@ -580,7 +580,6 @@ struct gfs2_sbd {
 	struct gfs2_holder sd_journal_gh;
 	struct gfs2_holder sd_jinode_gh;
 
-	struct gfs2_holder sd_ir_gh;
 	struct gfs2_holder sd_sc_gh;
 	struct gfs2_holder sd_qc_gh;
 
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 2f94bd7..fb15d3b 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -24,7 +24,7 @@
 #include "acl.h"
 #include "bmap.h"
 #include "dir.h"
-#include "eattr.h"
+#include "xattr.h"
 #include "glock.h"
 #include "glops.h"
 #include "inode.h"
@@ -519,139 +519,6 @@ out:
 	return inode ? inode : ERR_PTR(error);
 }
 
-static void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf)
-{
-	const struct gfs2_inum_range *str = buf;
-
-	ir->ir_start = be64_to_cpu(str->ir_start);
-	ir->ir_length = be64_to_cpu(str->ir_length);
-}
-
-static void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf)
-{
-	struct gfs2_inum_range *str = buf;
-
-	str->ir_start = cpu_to_be64(ir->ir_start);
-	str->ir_length = cpu_to_be64(ir->ir_length);
-}
-
-static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino)
-{
-	struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
-	struct buffer_head *bh;
-	struct gfs2_inum_range_host ir;
-	int error;
-
-	error = gfs2_trans_begin(sdp, RES_DINODE, 0);
-	if (error)
-		return error;
-	mutex_lock(&sdp->sd_inum_mutex);
-
-	error = gfs2_meta_inode_buffer(ip, &bh);
-	if (error) {
-		mutex_unlock(&sdp->sd_inum_mutex);
-		gfs2_trans_end(sdp);
-		return error;
-	}
-
-	gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));
-
-	if (ir.ir_length) {
-		*formal_ino = ir.ir_start++;
-		ir.ir_length--;
-		gfs2_trans_add_bh(ip->i_gl, bh, 1);
-		gfs2_inum_range_out(&ir,
-				    bh->b_data + sizeof(struct gfs2_dinode));
-		brelse(bh);
-		mutex_unlock(&sdp->sd_inum_mutex);
-		gfs2_trans_end(sdp);
-		return 0;
-	}
-
-	brelse(bh);
-
-	mutex_unlock(&sdp->sd_inum_mutex);
-	gfs2_trans_end(sdp);
-
-	return 1;
-}
-
-static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino)
-{
-	struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode);
-	struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode);
-	struct gfs2_holder gh;
-	struct buffer_head *bh;
-	struct gfs2_inum_range_host ir;
-	int error;
-
-	error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
-	if (error)
-		return error;
-
-	error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
-	if (error)
-		goto out;
-	mutex_lock(&sdp->sd_inum_mutex);
-
-	error = gfs2_meta_inode_buffer(ip, &bh);
-	if (error)
-		goto out_end_trans;
-
-	gfs2_inum_range_in(&ir, bh->b_data + sizeof(struct gfs2_dinode));
-
-	if (!ir.ir_length) {
-		struct buffer_head *m_bh;
-		u64 x, y;
-		__be64 z;
-
-		error = gfs2_meta_inode_buffer(m_ip, &m_bh);
-		if (error)
-			goto out_brelse;
-
-		z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode));
-		x = y = be64_to_cpu(z);
-		ir.ir_start = x;
-		ir.ir_length = GFS2_INUM_QUANTUM;
-		x += GFS2_INUM_QUANTUM;
-		if (x < y)
-			gfs2_consist_inode(m_ip);
-		z = cpu_to_be64(x);
-		gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1);
-		*(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z;
-
-		brelse(m_bh);
-	}
-
-	*formal_ino = ir.ir_start++;
-	ir.ir_length--;
-
-	gfs2_trans_add_bh(ip->i_gl, bh, 1);
-	gfs2_inum_range_out(&ir, bh->b_data + sizeof(struct gfs2_dinode));
-
-out_brelse:
-	brelse(bh);
-out_end_trans:
-	mutex_unlock(&sdp->sd_inum_mutex);
-	gfs2_trans_end(sdp);
-out:
-	gfs2_glock_dq_uninit(&gh);
-	return error;
-}
-
-static int pick_formal_ino(struct gfs2_sbd *sdp, u64 *inum)
-{
-	int error;
-
-	error = pick_formal_ino_1(sdp, inum);
-	if (error <= 0)
-		return error;
-
-	error = pick_formal_ino_2(sdp, inum);
-
-	return error;
-}
-
 /**
  * create_ok - OK to create a new on-disk inode here?
  * @dip:  Directory in which dinode is to be created
@@ -731,7 +598,7 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
 	if (error)
 		goto out_ipreserv;
 
-	*no_addr = gfs2_alloc_di(dip, generation);
+	error = gfs2_alloc_di(dip, no_addr, generation);
 
 	gfs2_trans_end(sdp);
 
@@ -924,7 +791,6 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)
 	size_t len;
 	void *value;
 	char *name;
-	struct gfs2_ea_request er;
 
 	err = security_inode_init_security(&ip->i_inode, &dip->i_inode,
 					   &name, &value, &len);
@@ -935,16 +801,7 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)
 		return err;
 	}
 
-	memset(&er, 0, sizeof(struct gfs2_ea_request));
-
-	er.er_type = GFS2_EATYPE_SECURITY;
-	er.er_name = name;
-	er.er_data = value;
-	er.er_name_len = strlen(name);
-	er.er_data_len = len;
-
-	err = gfs2_ea_set_i(ip, &er);
-
+	err = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SECURITY, name, value, len, 0);
 	kfree(value);
 	kfree(name);
 
@@ -991,13 +848,10 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 	if (error)
 		goto fail_gunlock;
 
-	error = pick_formal_ino(sdp, &inum.no_formal_ino);
-	if (error)
-		goto fail_gunlock;
-
 	error = alloc_dinode(dip, &inum.no_addr, &generation);
 	if (error)
 		goto fail_gunlock;
+	inum.no_formal_ino = generation;
 
 	error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops,
 				  LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
@@ -1008,9 +862,8 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
 	if (error)
 		goto fail_gunlock2;
 
-	inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode),
-					inum.no_addr,
-					inum.no_formal_ino, 0);
+	inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr,
+				  inum.no_formal_ino, 0);
 	if (IS_ERR(inode))
 		goto fail_gunlock2;
 
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 7bc3c45..52fb6c0 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -84,7 +84,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
 
 	gfs2_tune_init(&sdp->sd_tune);
 
-	mutex_init(&sdp->sd_inum_mutex);
 	spin_lock_init(&sdp->sd_statfs_spin);
 
 	spin_lock_init(&sdp->sd_rindex_spin);
@@ -833,21 +832,12 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
 	if (error)
 		goto fail;
 
-	/* Read in the master inode number inode */
-	sdp->sd_inum_inode = gfs2_lookup_simple(master, "inum");
-	if (IS_ERR(sdp->sd_inum_inode)) {
-		error = PTR_ERR(sdp->sd_inum_inode);
-		fs_err(sdp, "can't read in inum inode: %d\n", error);
-		goto fail_journal;
-	}
-
-
 	/* Read in the master statfs inode */
 	sdp->sd_statfs_inode = gfs2_lookup_simple(master, "statfs");
 	if (IS_ERR(sdp->sd_statfs_inode)) {
 		error = PTR_ERR(sdp->sd_statfs_inode);
 		fs_err(sdp, "can't read in statfs inode: %d\n", error);
-		goto fail_inum;
+		goto fail_journal;
 	}
 
 	/* Read in the resource index inode */
@@ -876,8 +866,6 @@ fail_rindex:
 	iput(sdp->sd_rindex);
 fail_statfs:
 	iput(sdp->sd_statfs_inode);
-fail_inum:
-	iput(sdp->sd_inum_inode);
 fail_journal:
 	init_journal(sdp, UNDO);
 fail:
@@ -905,20 +893,12 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
 		return error;
 	}
 
-	sprintf(buf, "inum_range%u", sdp->sd_jdesc->jd_jid);
-	sdp->sd_ir_inode = gfs2_lookup_simple(pn, buf);
-	if (IS_ERR(sdp->sd_ir_inode)) {
-		error = PTR_ERR(sdp->sd_ir_inode);
-		fs_err(sdp, "can't find local \"ir\" file: %d\n", error);
-		goto fail;
-	}
-
 	sprintf(buf, "statfs_change%u", sdp->sd_jdesc->jd_jid);
 	sdp->sd_sc_inode = gfs2_lookup_simple(pn, buf);
 	if (IS_ERR(sdp->sd_sc_inode)) {
 		error = PTR_ERR(sdp->sd_sc_inode);
 		fs_err(sdp, "can't find local \"sc\" file: %d\n", error);
-		goto fail_ir_i;
+		goto fail;
 	}
 
 	sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid);
@@ -932,27 +912,16 @@ static int init_per_node(struct gfs2_sbd *sdp, int undo)
 	iput(pn);
 	pn = NULL;
 
-	ip = GFS2_I(sdp->sd_ir_inode);
-	error = gfs2_glock_nq_init(ip->i_gl,
-				   LM_ST_EXCLUSIVE, 0,
-				   &sdp->sd_ir_gh);
-	if (error) {
-		fs_err(sdp, "can't lock local \"ir\" file: %d\n", error);
-		goto fail_qc_i;
-	}
-
 	ip = GFS2_I(sdp->sd_sc_inode);
-	error = gfs2_glock_nq_init(ip->i_gl,
-				   LM_ST_EXCLUSIVE, 0,
+	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0,
 				   &sdp->sd_sc_gh);
 	if (error) {
 		fs_err(sdp, "can't lock local \"sc\" file: %d\n", error);
-		goto fail_ir_gh;
+		goto fail_qc_i;
 	}
 
 	ip = GFS2_I(sdp->sd_qc_inode);
-	error = gfs2_glock_nq_init(ip->i_gl,
-				   LM_ST_EXCLUSIVE, 0,
+	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0,
 				   &sdp->sd_qc_gh);
 	if (error) {
 		fs_err(sdp, "can't lock local \"qc\" file: %d\n", error);
@@ -965,14 +934,10 @@ fail_qc_gh:
 	gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
 fail_ut_gh:
 	gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
-fail_ir_gh:
-	gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
 fail_qc_i:
 	iput(sdp->sd_qc_inode);
 fail_ut_i:
 	iput(sdp->sd_sc_inode);
-fail_ir_i:
-	iput(sdp->sd_ir_inode);
 fail:
 	if (pn)
 		iput(pn);
@@ -1063,7 +1028,6 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
 
 	ls->ls_ops = lm;
 	ls->ls_first = 1;
-	ls->ls_id = 0;
 
 	for (options = args->ar_hostdata; (o = strsep(&options, ":")); ) {
 		substring_t tmp[MAX_OPT_ARGS];
@@ -1081,10 +1045,7 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
 			ls->ls_jid = option;
 			break;
 		case Opt_id:
-			ret = match_int(&tmp[0], &option);
-			if (ret)
-				goto hostdata_error;
-			ls->ls_id = option;
+			/* Obsolete, but left for backward compat purposes */
 			break;
 		case Opt_first:
 			ret = match_int(&tmp[0], &option);
@@ -1133,6 +1094,17 @@ void gfs2_lm_unmount(struct gfs2_sbd *sdp)
 		lm->lm_unmount(sdp);
 }
 
+void gfs2_online_uevent(struct gfs2_sbd *sdp)
+{
+	struct super_block *sb = sdp->sd_vfs;
+	char ro[20];
+	char spectator[20];
+	char *envp[] = { ro, spectator, NULL };
+	sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0);
+	sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0);
+	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ONLINE, envp);
+}
+
 /**
  * fill_super - Read in superblock
  * @sb: The VFS superblock
@@ -1157,6 +1129,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
 	sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT;
 	sdp->sd_args.ar_data = GFS2_DATA_DEFAULT;
 	sdp->sd_args.ar_commit = 60;
+	sdp->sd_args.ar_errors = GFS2_ERRORS_DEFAULT;
 
 	error = gfs2_mount_args(sdp, &sdp->sd_args, data);
 	if (error) {
@@ -1174,6 +1147,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
 	sb->s_magic = GFS2_MAGIC;
 	sb->s_op = &gfs2_super_ops;
 	sb->s_export_op = &gfs2_export_ops;
+	sb->s_xattr = gfs2_xattr_handlers;
 	sb->s_time_gran = 1;
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 
@@ -1236,7 +1210,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
 	}
 
 	gfs2_glock_dq_uninit(&mount_gh);
-
+	gfs2_online_uevent(sdp);
 	return 0;
 
 fail_threads:
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index f8bd20b..c3ac180 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -26,8 +26,7 @@
 #include "acl.h"
 #include "bmap.h"
 #include "dir.h"
-#include "eaops.h"
-#include "eattr.h"
+#include "xattr.h"
 #include "glock.h"
 #include "inode.h"
 #include "meta_io.h"
@@ -349,7 +348,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
 
 	error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0);
 	if (error)
-		goto out_rgrp;
+		goto out_gunlock;
 
 	error = gfs2_dir_del(dip, &dentry->d_name);
         if (error)
@@ -1302,60 +1301,53 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name,
 			 const void *data, size_t size, int flags)
 {
 	struct inode *inode = dentry->d_inode;
-	struct gfs2_ea_request er;
-
-	memset(&er, 0, sizeof(struct gfs2_ea_request));
-	er.er_type = gfs2_ea_name2type(name, &er.er_name);
-	if (er.er_type == GFS2_EATYPE_UNUSED)
-		return -EOPNOTSUPP;
-	er.er_data = (char *)data;
-	er.er_name_len = strlen(er.er_name);
-	er.er_data_len = size;
-	er.er_flags = flags;
-
-	gfs2_assert_warn(GFS2_SB(inode), !(er.er_flags & GFS2_ERF_MODE));
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_holder gh;
+	int ret;
 
-	return gfs2_ea_set(GFS2_I(inode), &er);
+	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+	ret = gfs2_glock_nq(&gh);
+	if (ret == 0) {
+		ret = generic_setxattr(dentry, name, data, size, flags);
+		gfs2_glock_dq(&gh);
+	}
+	gfs2_holder_uninit(&gh);
+	return ret;
 }
 
 static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
 			     void *data, size_t size)
 {
-	struct gfs2_ea_request er;
-
-	memset(&er, 0, sizeof(struct gfs2_ea_request));
-	er.er_type = gfs2_ea_name2type(name, &er.er_name);
-	if (er.er_type == GFS2_EATYPE_UNUSED)
-		return -EOPNOTSUPP;
-	er.er_data = data;
-	er.er_name_len = strlen(er.er_name);
-	er.er_data_len = size;
-
-	return gfs2_ea_get(GFS2_I(dentry->d_inode), &er);
-}
-
-static ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
-{
-	struct gfs2_ea_request er;
-
-	memset(&er, 0, sizeof(struct gfs2_ea_request));
-	er.er_data = (size) ? buffer : NULL;
-	er.er_data_len = size;
+	struct inode *inode = dentry->d_inode;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_holder gh;
+	int ret;
 
-	return gfs2_ea_list(GFS2_I(dentry->d_inode), &er);
+	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
+	ret = gfs2_glock_nq(&gh);
+	if (ret == 0) {
+		ret = generic_getxattr(dentry, name, data, size);
+		gfs2_glock_dq(&gh);
+	}
+	gfs2_holder_uninit(&gh);
+	return ret;
 }
 
 static int gfs2_removexattr(struct dentry *dentry, const char *name)
 {
-	struct gfs2_ea_request er;
-
-	memset(&er, 0, sizeof(struct gfs2_ea_request));
-	er.er_type = gfs2_ea_name2type(name, &er.er_name);
-	if (er.er_type == GFS2_EATYPE_UNUSED)
-		return -EOPNOTSUPP;
-	er.er_name_len = strlen(er.er_name);
+	struct inode *inode = dentry->d_inode;
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_holder gh;
+	int ret;
 
-	return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er);
+	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
+	ret = gfs2_glock_nq(&gh);
+	if (ret == 0) {
+		ret = generic_removexattr(dentry, name);
+		gfs2_glock_dq(&gh);
+	}
+	gfs2_holder_uninit(&gh);
+	return ret;
 }
 
 static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index fba7957..28c590b 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -857,7 +857,8 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
 					goto start_new_extent;
 				if ((start + nr_sects) != blk) {
 					rv = blkdev_issue_discard(bdev, start,
-							    nr_sects, GFP_NOFS);
+							    nr_sects, GFP_NOFS,
+							    DISCARD_FL_BARRIER);
 					if (rv)
 						goto fail;
 					nr_sects = 0;
@@ -871,7 +872,8 @@ start_new_extent:
 		}
 	}
 	if (nr_sects) {
-		rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS);
+		rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS,
+					 DISCARD_FL_BARRIER);
 		if (rv)
 			goto fail;
 	}
@@ -1256,7 +1258,7 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
  * Returns: The block type (GFS2_BLKST_*)
  */
 
-unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
+static unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
 {
 	struct gfs2_bitmap *bi = NULL;
 	u32 length, rgrp_block, buf_block;
@@ -1459,6 +1461,16 @@ int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl)
 	return 0;
 }
 
+static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd)
+{
+	struct gfs2_sbd *sdp = rgd->rd_sbd;
+	fs_warn(sdp, "rgrp %llu has an error, marking it readonly until umount\n",
+		(unsigned long long)rgd->rd_addr);
+	fs_warn(sdp, "umount on all nodes and run fsck.gfs2 to fix the error\n");
+	gfs2_rgrp_dump(NULL, rgd->rd_gl);
+	rgd->rd_flags |= GFS2_RDF_ERROR;
+}
+
 /**
  * gfs2_alloc_block - Allocate one or more blocks
  * @ip: the inode to allocate the block for
@@ -1520,22 +1532,20 @@ int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n)
 	return 0;
 
 rgrp_error:
-	fs_warn(sdp, "rgrp %llu has an error, marking it readonly until umount\n",
-	        (unsigned long long)rgd->rd_addr);
-	fs_warn(sdp, "umount on all nodes and run fsck.gfs2 to fix the error\n");
-	gfs2_rgrp_dump(NULL, rgd->rd_gl);
-	rgd->rd_flags |= GFS2_RDF_ERROR;
+	gfs2_rgrp_error(rgd);
 	return -EIO;
 }
 
 /**
  * gfs2_alloc_di - Allocate a dinode
  * @dip: the directory that the inode is going in
+ * @bn: the block number which is allocated
+ * @generation: the generation number of the inode
  *
- * Returns: the block allocated
+ * Returns: 0 on success or error
  */
 
-u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation)
+int gfs2_alloc_di(struct gfs2_inode *dip, u64 *bn, u64 *generation)
 {
 	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
 	struct gfs2_alloc *al = dip->i_alloc;
@@ -1546,16 +1556,21 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation)
 
 	blk = rgblk_search(rgd, rgd->rd_last_alloc,
 			   GFS2_BLKST_FREE, GFS2_BLKST_DINODE, &n);
-	BUG_ON(blk == BFITNOENT);
 
-	rgd->rd_last_alloc = blk;
+	/* Since all blocks are reserved in advance, this shouldn't happen */
+	if (blk == BFITNOENT)
+		goto rgrp_error;
 
+	rgd->rd_last_alloc = blk;
 	block = rgd->rd_data0 + blk;
+	if (rgd->rd_free == 0)
+		goto rgrp_error;
 
-	gfs2_assert_withdraw(sdp, rgd->rd_free);
 	rgd->rd_free--;
 	rgd->rd_dinodes++;
 	*generation = rgd->rd_igeneration++;
+	if (*generation == 0)
+		*generation = rgd->rd_igeneration++;
 	gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1);
 	gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data);
 
@@ -1568,7 +1583,12 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation)
 	rgd->rd_free_clone--;
 	spin_unlock(&sdp->sd_rindex_spin);
 	trace_gfs2_block_alloc(dip, block, 1, GFS2_BLKST_DINODE);
-	return block;
+	*bn = block;
+	return 0;
+
+rgrp_error:
+	gfs2_rgrp_error(rgd);
+	return -EIO;
 }
 
 /**
@@ -1676,6 +1696,46 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
 }
 
 /**
+ * gfs2_check_blk_type - Check the type of a block
+ * @sdp: The superblock
+ * @no_addr: The block number to check
+ * @type: The block type we are looking for
+ *
+ * Returns: 0 if the block type matches the expected type
+ *          -ESTALE if it doesn't match
+ *          or -ve errno if something went wrong while checking
+ */
+
+int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
+{
+	struct gfs2_rgrpd *rgd;
+	struct gfs2_holder ri_gh, rgd_gh;
+	int error;
+
+	error = gfs2_rindex_hold(sdp, &ri_gh);
+	if (error)
+		goto fail;
+
+	error = -EINVAL;
+	rgd = gfs2_blk2rgrpd(sdp, no_addr);
+	if (!rgd)
+		goto fail_rindex;
+
+	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh);
+	if (error)
+		goto fail_rindex;
+
+	if (gfs2_get_block_type(rgd, no_addr) != type)
+		error = -ESTALE;
+
+	gfs2_glock_dq_uninit(&rgd_gh);
+fail_rindex:
+	gfs2_glock_dq_uninit(&ri_gh);
+fail:
+	return error;
+}
+
+/**
  * gfs2_rlist_add - add a RG to a list of RGs
  * @sdp: the filesystem
  * @rlist: the list of resource groups
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h
index 1e76ff0..b4106dd 100644
--- a/fs/gfs2/rgrp.h
+++ b/fs/gfs2/rgrp.h
@@ -44,15 +44,15 @@ gfs2_inplace_reserve_i((ip), __FILE__, __LINE__)
 
 extern void gfs2_inplace_release(struct gfs2_inode *ip);
 
-extern unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block);
-
 extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n);
-extern u64 gfs2_alloc_di(struct gfs2_inode *ip, u64 *generation);
+extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation);
 
 extern void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen);
 extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen);
 extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip);
 extern void gfs2_unlink_di(struct inode *inode);
+extern int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr,
+			       unsigned int type);
 
 struct gfs2_rgrp_list {
 	unsigned int rl_rgrps;
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index f522bb0..0ec3ec6 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -38,7 +38,7 @@
 #include "trans.h"
 #include "util.h"
 #include "sys.h"
-#include "eattr.h"
+#include "xattr.h"
 
 #define args_neq(a1, a2, x) ((a1)->ar_##x != (a2)->ar_##x)
 
@@ -68,6 +68,8 @@ enum {
 	Opt_discard,
 	Opt_nodiscard,
 	Opt_commit,
+	Opt_err_withdraw,
+	Opt_err_panic,
 	Opt_error,
 };
 
@@ -97,6 +99,8 @@ static const match_table_t tokens = {
 	{Opt_discard, "discard"},
 	{Opt_nodiscard, "nodiscard"},
 	{Opt_commit, "commit=%d"},
+	{Opt_err_withdraw, "errors=withdraw"},
+	{Opt_err_panic, "errors=panic"},
 	{Opt_error, NULL}
 };
 
@@ -152,6 +156,11 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
 			args->ar_localcaching = 1;
 			break;
 		case Opt_debug:
+			if (args->ar_errors == GFS2_ERRORS_PANIC) {
+				fs_info(sdp, "-o debug and -o errors=panic "
+				       "are mutually exclusive.\n");
+				return -EINVAL;
+			}
 			args->ar_debug = 1;
 			break;
 		case Opt_nodebug:
@@ -205,6 +214,17 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
 				return rv ? rv : -EINVAL;
 			}
 			break;
+		case Opt_err_withdraw:
+			args->ar_errors = GFS2_ERRORS_WITHDRAW;
+			break;
+		case Opt_err_panic:
+			if (args->ar_debug) {
+				fs_info(sdp, "-o debug and -o errors=panic "
+					"are mutually exclusive.\n");
+				return -EINVAL;
+			}
+			args->ar_errors = GFS2_ERRORS_PANIC;
+			break;
 		case Opt_error:
 		default:
 			fs_info(sdp, "invalid mount option: %s\n", o);
@@ -768,7 +788,6 @@ restart:
 	/*  Release stuff  */
 
 	iput(sdp->sd_jindex);
-	iput(sdp->sd_inum_inode);
 	iput(sdp->sd_statfs_inode);
 	iput(sdp->sd_rindex);
 	iput(sdp->sd_quota_inode);
@@ -779,10 +798,8 @@ restart:
 	if (!sdp->sd_args.ar_spectator) {
 		gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
 		gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
-		gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
 		gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
 		gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
-		iput(sdp->sd_ir_inode);
 		iput(sdp->sd_sc_inode);
 		iput(sdp->sd_qc_inode);
 	}
@@ -1084,6 +1101,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
 	gt->gt_log_flush_secs = args.ar_commit;
 	spin_unlock(&gt->gt_spin);
 
+	gfs2_online_uevent(sdp);
 	return 0;
 }
 
@@ -1225,6 +1243,22 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
 	lfsecs = sdp->sd_tune.gt_log_flush_secs;
 	if (lfsecs != 60)
 		seq_printf(s, ",commit=%d", lfsecs);
+	if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
+		const char *state;
+
+		switch (args->ar_errors) {
+		case GFS2_ERRORS_WITHDRAW:
+			state = "withdraw";
+			break;
+		case GFS2_ERRORS_PANIC:
+			state = "panic";
+			break;
+		default:
+			state = "unknown";
+			break;
+		}
+		seq_printf(s, ",errors=%s", state);
+	}
 	return 0;
 }
 
@@ -1252,6 +1286,10 @@ static void gfs2_delete_inode(struct inode *inode)
 		goto out;
 	}
 
+	error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED);
+	if (error)
+		goto out_truncate;
+
 	gfs2_glock_dq_wait(&ip->i_iopen_gh);
 	gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
 	error = gfs2_glock_nq(&ip->i_iopen_gh);
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h
index 22e0417..235db36 100644
--- a/fs/gfs2/super.h
+++ b/fs/gfs2/super.h
@@ -25,7 +25,7 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
 	return x;
 }
 
-void gfs2_jindex_free(struct gfs2_sbd *sdp);
+extern void gfs2_jindex_free(struct gfs2_sbd *sdp);
 
 extern int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *data);
 
@@ -36,7 +36,7 @@ extern int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename,
 				     struct gfs2_inode **ipp);
 
 extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp);
-
+extern void gfs2_online_uevent(struct gfs2_sbd *sdp);
 extern int gfs2_statfs_init(struct gfs2_sbd *sdp);
 extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
 			       s64 dinodes);
@@ -54,6 +54,7 @@ extern struct file_system_type gfs2meta_fs_type;
 extern const struct export_operations gfs2_export_ops;
 extern const struct super_operations gfs2_super_ops;
 extern const struct dentry_operations gfs2_dops;
+extern struct xattr_handler *gfs2_xattr_handlers[];
 
 #endif /* __SUPER_DOT_H__ */
 
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index a7cbfbd..4463297 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -16,6 +16,7 @@
 #include <linux/kobject.h>
 #include <asm/uaccess.h>
 #include <linux/gfs2_ondisk.h>
+#include <linux/genhd.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -319,12 +320,6 @@ static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
 	return ret;
 }
 
-static ssize_t lkid_show(struct gfs2_sbd *sdp, char *buf)
-{
-	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
-	return sprintf(buf, "%u\n", ls->ls_id);
-}
-
 static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf)
 {
 	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
@@ -389,7 +384,6 @@ static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
 GDLM_ATTR(proto_name,		0444, proto_name_show,		NULL);
 GDLM_ATTR(block,		0644, block_show,		block_store);
 GDLM_ATTR(withdraw,		0644, withdraw_show,		withdraw_store);
-GDLM_ATTR(id,			0444, lkid_show,		NULL);
 GDLM_ATTR(jid,			0444, jid_show,			NULL);
 GDLM_ATTR(first,		0444, lkfirst_show,		NULL);
 GDLM_ATTR(first_done,		0444, first_done_show,		NULL);
@@ -401,7 +395,6 @@ static struct attribute *lock_module_attrs[] = {
 	&gdlm_attr_proto_name.attr,
 	&gdlm_attr_block.attr,
 	&gdlm_attr_withdraw.attr,
-	&gdlm_attr_id.attr,
 	&gdlm_attr_jid.attr,
 	&gdlm_attr_first.attr,
 	&gdlm_attr_first_done.attr,
@@ -519,7 +512,14 @@ static struct attribute_group lock_module_group = {
 
 int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
 {
+	struct super_block *sb = sdp->sd_vfs;
 	int error;
+	char ro[20];
+	char spectator[20];
+	char *envp[] = { ro, spectator, NULL };
+
+	sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0);
+	sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0);
 
 	sdp->sd_kobj.kset = gfs2_kset;
 	error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL,
@@ -535,9 +535,17 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
 	if (error)
 		goto fail_tune;
 
-	kobject_uevent(&sdp->sd_kobj, KOBJ_ADD);
+	error = sysfs_create_link(&sdp->sd_kobj,
+				  &disk_to_dev(sb->s_bdev->bd_disk)->kobj,
+				  "device");
+	if (error)
+		goto fail_lock_module;
+
+	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp);
 	return 0;
 
+fail_lock_module:
+	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
 fail_tune:
 	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
 fail_reg:
@@ -549,12 +557,12 @@ fail:
 
 void gfs2_sys_fs_del(struct gfs2_sbd *sdp)
 {
+	sysfs_remove_link(&sdp->sd_kobj, "device");
 	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
 	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
 	kobject_put(&sdp->sd_kobj);
 }
 
-
 static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
 		       struct kobj_uevent_env *env)
 {
@@ -563,6 +571,8 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
 
 	add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
 	add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
+	if (!sdp->sd_args.ar_spectator)
+		add_uevent_var(env, "JOURNALID=%u", sdp->sd_lockstruct.ls_jid);
 	if (gfs2_uuid_valid(uuid)) {
 		add_uevent_var(env, "UUID=%02X%02X%02X%02X-%02X%02X-%02X%02X-"
 			       "%02X%02X-%02X%02X%02X%02X%02X%02X",
@@ -578,7 +588,6 @@ static struct kset_uevent_ops gfs2_uevent_ops = {
 	.uevent = gfs2_uevent,
 };
 
-
 int gfs2_sys_init(void)
 {
 	gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj);
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 9d12b11..f6a7efa 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -38,24 +38,30 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...)
 	const struct lm_lockops *lm = ls->ls_ops;
 	va_list args;
 
-	if (test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
+	if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
+	    test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
 		return 0;
 
 	va_start(args, fmt);
 	vprintk(fmt, args);
 	va_end(args);
 
-	fs_err(sdp, "about to withdraw this file system\n");
-	BUG_ON(sdp->sd_args.ar_debug);
+	if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) {
+		fs_err(sdp, "about to withdraw this file system\n");
+		BUG_ON(sdp->sd_args.ar_debug);
 
-	kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE);
+		kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE);
 
-	if (lm->lm_unmount) {
-		fs_err(sdp, "telling LM to unmount\n");
-		lm->lm_unmount(sdp);
+		if (lm->lm_unmount) {
+			fs_err(sdp, "telling LM to unmount\n");
+			lm->lm_unmount(sdp);
+		}
+		fs_err(sdp, "withdrawn\n");
+		dump_stack();
 	}
-	fs_err(sdp, "withdrawn\n");
-	dump_stack();
+
+	if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
+		panic("GFS2: fsid=%s: panic requested.\n", sdp->sd_fsname);
 
 	return -1;
 }
@@ -93,17 +99,24 @@ int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
 			gfs2_tune_get(sdp, gt_complain_secs) * HZ))
 		return -2;
 
-	printk(KERN_WARNING
-	       "GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
-	       "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
-	       sdp->sd_fsname, assertion,
-	       sdp->sd_fsname, function, file, line);
+	if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW)
+		printk(KERN_WARNING
+		       "GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
+		       "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
+		       sdp->sd_fsname, assertion,
+		       sdp->sd_fsname, function, file, line);
 
 	if (sdp->sd_args.ar_debug)
 		BUG();
 	else
 		dump_stack();
 
+	if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
+		panic("GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
+		      "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
+		      sdp->sd_fsname, assertion,
+		      sdp->sd_fsname, function, file, line);
+
 	sdp->sd_last_warning = jiffies;
 
 	return -1;
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
new file mode 100644
index 0000000..8a0f8ef
--- /dev/null
+++ b/fs/gfs2/xattr.c
@@ -0,0 +1,1558 @@
+/*
+ * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
+ * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License version 2.
+ */
+
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/buffer_head.h>
+#include <linux/xattr.h>
+#include <linux/gfs2_ondisk.h>
+#include <asm/uaccess.h>
+
+#include "gfs2.h"
+#include "incore.h"
+#include "acl.h"
+#include "xattr.h"
+#include "glock.h"
+#include "inode.h"
+#include "meta_io.h"
+#include "quota.h"
+#include "rgrp.h"
+#include "trans.h"
+#include "util.h"
+
+/**
+ * ea_calc_size - returns the acutal number of bytes the request will take up
+ *                (not counting any unstuffed data blocks)
+ * @sdp:
+ * @er:
+ * @size:
+ *
+ * Returns: 1 if the EA should be stuffed
+ */
+
+static int ea_calc_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize,
+			unsigned int *size)
+{
+	unsigned int jbsize = sdp->sd_jbsize;
+
+	/* Stuffed */
+	*size = ALIGN(sizeof(struct gfs2_ea_header) + nsize + dsize, 8);
+
+	if (*size <= jbsize)
+		return 1;
+
+	/* Unstuffed */
+	*size = ALIGN(sizeof(struct gfs2_ea_header) + nsize +
+		      (sizeof(__be64) * DIV_ROUND_UP(dsize, jbsize)), 8);
+
+	return 0;
+}
+
+static int ea_check_size(struct gfs2_sbd *sdp, unsigned int nsize, size_t dsize)
+{
+	unsigned int size;
+
+	if (dsize > GFS2_EA_MAX_DATA_LEN)
+		return -ERANGE;
+
+	ea_calc_size(sdp, nsize, dsize, &size);
+
+	/* This can only happen with 512 byte blocks */
+	if (size > sdp->sd_jbsize)
+		return -ERANGE;
+
+	return 0;
+}
+
+typedef int (*ea_call_t) (struct gfs2_inode *ip, struct buffer_head *bh,
+			  struct gfs2_ea_header *ea,
+			  struct gfs2_ea_header *prev, void *private);
+
+static int ea_foreach_i(struct gfs2_inode *ip, struct buffer_head *bh,
+			ea_call_t ea_call, void *data)
+{
+	struct gfs2_ea_header *ea, *prev = NULL;
+	int error = 0;
+
+	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_EA))
+		return -EIO;
+
+	for (ea = GFS2_EA_BH2FIRST(bh);; prev = ea, ea = GFS2_EA2NEXT(ea)) {
+		if (!GFS2_EA_REC_LEN(ea))
+			goto fail;
+		if (!(bh->b_data <= (char *)ea && (char *)GFS2_EA2NEXT(ea) <=
+						  bh->b_data + bh->b_size))
+			goto fail;
+		if (!GFS2_EATYPE_VALID(ea->ea_type))
+			goto fail;
+
+		error = ea_call(ip, bh, ea, prev, data);
+		if (error)
+			return error;
+
+		if (GFS2_EA_IS_LAST(ea)) {
+			if ((char *)GFS2_EA2NEXT(ea) !=
+			    bh->b_data + bh->b_size)
+				goto fail;
+			break;
+		}
+	}
+
+	return error;
+
+fail:
+	gfs2_consist_inode(ip);
+	return -EIO;
+}
+
+static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
+{
+	struct buffer_head *bh, *eabh;
+	__be64 *eablk, *end;
+	int error;
+
+	error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &bh);
+	if (error)
+		return error;
+
+	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT)) {
+		error = ea_foreach_i(ip, bh, ea_call, data);
+		goto out;
+	}
+
+	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_IN)) {
+		error = -EIO;
+		goto out;
+	}
+
+	eablk = (__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header));
+	end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs;
+
+	for (; eablk < end; eablk++) {
+		u64 bn;
+
+		if (!*eablk)
+			break;
+		bn = be64_to_cpu(*eablk);
+
+		error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, &eabh);
+		if (error)
+			break;
+		error = ea_foreach_i(ip, eabh, ea_call, data);
+		brelse(eabh);
+		if (error)
+			break;
+	}
+out:
+	brelse(bh);
+	return error;
+}
+
+struct ea_find {
+	int type;
+	const char *name;
+	size_t namel;
+	struct gfs2_ea_location *ef_el;
+};
+
+static int ea_find_i(struct gfs2_inode *ip, struct buffer_head *bh,
+		     struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
+		     void *private)
+{
+	struct ea_find *ef = private;
+
+	if (ea->ea_type == GFS2_EATYPE_UNUSED)
+		return 0;
+
+	if (ea->ea_type == ef->type) {
+		if (ea->ea_name_len == ef->namel &&
+		    !memcmp(GFS2_EA2NAME(ea), ef->name, ea->ea_name_len)) {
+			struct gfs2_ea_location *el = ef->ef_el;
+			get_bh(bh);
+			el->el_bh = bh;
+			el->el_ea = ea;
+			el->el_prev = prev;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
+		 struct gfs2_ea_location *el)
+{
+	struct ea_find ef;
+	int error;
+
+	ef.type = type;
+	ef.name = name;
+	ef.namel = strlen(name);
+	ef.ef_el = el;
+
+	memset(el, 0, sizeof(struct gfs2_ea_location));
+
+	error = ea_foreach(ip, ea_find_i, &ef);
+	if (error > 0)
+		return 0;
+
+	return error;
+}
+
+/**
+ * ea_dealloc_unstuffed -
+ * @ip:
+ * @bh:
+ * @ea:
+ * @prev:
+ * @private:
+ *
+ * Take advantage of the fact that all unstuffed blocks are
+ * allocated from the same RG.  But watch, this may not always
+ * be true.
+ *
+ * Returns: errno
+ */
+
+static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
+				struct gfs2_ea_header *ea,
+				struct gfs2_ea_header *prev, void *private)
+{
+	int *leave = private;
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct gfs2_rgrpd *rgd;
+	struct gfs2_holder rg_gh;
+	struct buffer_head *dibh;
+	__be64 *dataptrs;
+	u64 bn = 0;
+	u64 bstart = 0;
+	unsigned int blen = 0;
+	unsigned int blks = 0;
+	unsigned int x;
+	int error;
+
+	if (GFS2_EA_IS_STUFFED(ea))
+		return 0;
+
+	dataptrs = GFS2_EA2DATAPTRS(ea);
+	for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
+		if (*dataptrs) {
+			blks++;
+			bn = be64_to_cpu(*dataptrs);
+		}
+	}
+	if (!blks)
+		return 0;
+
+	rgd = gfs2_blk2rgrpd(sdp, bn);
+	if (!rgd) {
+		gfs2_consist_inode(ip);
+		return -EIO;
+	}
+
+	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
+	if (error)
+		return error;
+
+	error = gfs2_trans_begin(sdp, rgd->rd_length + RES_DINODE +
+				 RES_EATTR + RES_STATFS + RES_QUOTA, blks);
+	if (error)
+		goto out_gunlock;
+
+	gfs2_trans_add_bh(ip->i_gl, bh, 1);
+
+	dataptrs = GFS2_EA2DATAPTRS(ea);
+	for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) {
+		if (!*dataptrs)
+			break;
+		bn = be64_to_cpu(*dataptrs);
+
+		if (bstart + blen == bn)
+			blen++;
+		else {
+			if (bstart)
+				gfs2_free_meta(ip, bstart, blen);
+			bstart = bn;
+			blen = 1;
+		}
+
+		*dataptrs = 0;
+		gfs2_add_inode_blocks(&ip->i_inode, -1);
+	}
+	if (bstart)
+		gfs2_free_meta(ip, bstart, blen);
+
+	if (prev && !leave) {
+		u32 len;
+
+		len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
+		prev->ea_rec_len = cpu_to_be32(len);
+
+		if (GFS2_EA_IS_LAST(ea))
+			prev->ea_flags |= GFS2_EAFLAG_LAST;
+	} else {
+		ea->ea_type = GFS2_EATYPE_UNUSED;
+		ea->ea_num_ptrs = 0;
+	}
+
+	error = gfs2_meta_inode_buffer(ip, &dibh);
+	if (!error) {
+		ip->i_inode.i_ctime = CURRENT_TIME;
+		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+		gfs2_dinode_out(ip, dibh->b_data);
+		brelse(dibh);
+	}
+
+	gfs2_trans_end(sdp);
+
+out_gunlock:
+	gfs2_glock_dq_uninit(&rg_gh);
+	return error;
+}
+
+static int ea_remove_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh,
+			       struct gfs2_ea_header *ea,
+			       struct gfs2_ea_header *prev, int leave)
+{
+	struct gfs2_alloc *al;
+	int error;
+
+	al = gfs2_alloc_get(ip);
+	if (!al)
+		return -ENOMEM;
+
+	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	if (error)
+		goto out_alloc;
+
+	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
+	if (error)
+		goto out_quota;
+
+	error = ea_dealloc_unstuffed(ip, bh, ea, prev, (leave) ? &error : NULL);
+
+	gfs2_glock_dq_uninit(&al->al_ri_gh);
+
+out_quota:
+	gfs2_quota_unhold(ip);
+out_alloc:
+	gfs2_alloc_put(ip);
+	return error;
+}
+
+struct ea_list {
+	struct gfs2_ea_request *ei_er;
+	unsigned int ei_size;
+};
+
+static inline unsigned int gfs2_ea_strlen(struct gfs2_ea_header *ea)
+{
+	switch (ea->ea_type) {
+	case GFS2_EATYPE_USR:
+		return 5 + ea->ea_name_len + 1;
+	case GFS2_EATYPE_SYS:
+		return 7 + ea->ea_name_len + 1;
+	case GFS2_EATYPE_SECURITY:
+		return 9 + ea->ea_name_len + 1;
+	default:
+		return 0;
+	}
+}
+
+static int ea_list_i(struct gfs2_inode *ip, struct buffer_head *bh,
+		     struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
+		     void *private)
+{
+	struct ea_list *ei = private;
+	struct gfs2_ea_request *er = ei->ei_er;
+	unsigned int ea_size = gfs2_ea_strlen(ea);
+
+	if (ea->ea_type == GFS2_EATYPE_UNUSED)
+		return 0;
+
+	if (er->er_data_len) {
+		char *prefix = NULL;
+		unsigned int l = 0;
+		char c = 0;
+
+		if (ei->ei_size + ea_size > er->er_data_len)
+			return -ERANGE;
+
+		switch (ea->ea_type) {
+		case GFS2_EATYPE_USR:
+			prefix = "user.";
+			l = 5;
+			break;
+		case GFS2_EATYPE_SYS:
+			prefix = "system.";
+			l = 7;
+			break;
+		case GFS2_EATYPE_SECURITY:
+			prefix = "security.";
+			l = 9;
+			break;
+		}
+
+		BUG_ON(l == 0);
+
+		memcpy(er->er_data + ei->ei_size, prefix, l);
+		memcpy(er->er_data + ei->ei_size + l, GFS2_EA2NAME(ea),
+		       ea->ea_name_len);
+		memcpy(er->er_data + ei->ei_size + ea_size - 1, &c, 1);
+	}
+
+	ei->ei_size += ea_size;
+
+	return 0;
+}
+
+/**
+ * gfs2_listxattr - List gfs2 extended attributes
+ * @dentry: The dentry whose inode we are interested in
+ * @buffer: The buffer to write the results
+ * @size: The size of the buffer
+ *
+ * Returns: actual size of data on success, -errno on error
+ */
+
+ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
+	struct gfs2_ea_request er;
+	struct gfs2_holder i_gh;
+	int error;
+
+	memset(&er, 0, sizeof(struct gfs2_ea_request));
+	if (size) {
+		er.er_data = buffer;
+		er.er_data_len = size;
+	}
+
+	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
+	if (error)
+		return error;
+
+	if (ip->i_eattr) {
+		struct ea_list ei = { .ei_er = &er, .ei_size = 0 };
+
+		error = ea_foreach(ip, ea_list_i, &ei);
+		if (!error)
+			error = ei.ei_size;
+	}
+
+	gfs2_glock_dq_uninit(&i_gh);
+
+	return error;
+}
+
+/**
+ * ea_get_unstuffed - actually copies the unstuffed data into the
+ *                    request buffer
+ * @ip: The GFS2 inode
+ * @ea: The extended attribute header structure
+ * @data: The data to be copied
+ *
+ * Returns: errno
+ */
+
+static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
+			    char *data)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct buffer_head **bh;
+	unsigned int amount = GFS2_EA_DATA_LEN(ea);
+	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
+	__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
+	unsigned int x;
+	int error = 0;
+
+	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
+	if (!bh)
+		return -ENOMEM;
+
+	for (x = 0; x < nptrs; x++) {
+		error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
+				       bh + x);
+		if (error) {
+			while (x--)
+				brelse(bh[x]);
+			goto out;
+		}
+		dataptrs++;
+	}
+
+	for (x = 0; x < nptrs; x++) {
+		error = gfs2_meta_wait(sdp, bh[x]);
+		if (error) {
+			for (; x < nptrs; x++)
+				brelse(bh[x]);
+			goto out;
+		}
+		if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
+			for (; x < nptrs; x++)
+				brelse(bh[x]);
+			error = -EIO;
+			goto out;
+		}
+
+		memcpy(data, bh[x]->b_data + sizeof(struct gfs2_meta_header),
+		       (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
+
+		amount -= sdp->sd_jbsize;
+		data += sdp->sd_jbsize;
+
+		brelse(bh[x]);
+	}
+
+out:
+	kfree(bh);
+	return error;
+}
+
+int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
+		     char *data, size_t size)
+{
+	int ret;
+	size_t len = GFS2_EA_DATA_LEN(el->el_ea);
+	if (len > size)
+		return -ERANGE;
+
+	if (GFS2_EA_IS_STUFFED(el->el_ea)) {
+		memcpy(data, GFS2_EA2DATA(el->el_ea), len);
+		return len;
+	}
+	ret = ea_get_unstuffed(ip, el->el_ea, data);
+	if (ret < 0)
+		return ret;
+	return len;
+}
+
+/**
+ * gfs2_xattr_get - Get a GFS2 extended attribute
+ * @inode: The inode
+ * @type: The type of extended attribute
+ * @name: The name of the extended attribute
+ * @buffer: The buffer to write the result into
+ * @size: The size of the buffer
+ *
+ * Returns: actual size of data on success, -errno on error
+ */
+
+int gfs2_xattr_get(struct inode *inode, int type, const char *name,
+		   void *buffer, size_t size)
+{
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_ea_location el;
+	int error;
+
+	if (!ip->i_eattr)
+		return -ENODATA;
+	if (strlen(name) > GFS2_EA_MAX_NAME_LEN)
+		return -EINVAL;
+
+	error = gfs2_ea_find(ip, type, name, &el);
+	if (error)
+		return error;
+	if (!el.el_ea)
+		return -ENODATA;
+	if (size)
+		error = gfs2_ea_get_copy(ip, &el, buffer, size);
+	else
+		error = GFS2_EA_DATA_LEN(el.el_ea);
+	brelse(el.el_bh);
+
+	return error;
+}
+
+/**
+ * ea_alloc_blk - allocates a new block for extended attributes.
+ * @ip: A pointer to the inode that's getting extended attributes
+ * @bhp: Pointer to pointer to a struct buffer_head
+ *
+ * Returns: errno
+ */
+
+static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct gfs2_ea_header *ea;
+	unsigned int n = 1;
+	u64 block;
+	int error;
+
+	error = gfs2_alloc_block(ip, &block, &n);
+	if (error)
+		return error;
+	gfs2_trans_add_unrevoke(sdp, block, 1);
+	*bhp = gfs2_meta_new(ip->i_gl, block);
+	gfs2_trans_add_bh(ip->i_gl, *bhp, 1);
+	gfs2_metatype_set(*bhp, GFS2_METATYPE_EA, GFS2_FORMAT_EA);
+	gfs2_buffer_clear_tail(*bhp, sizeof(struct gfs2_meta_header));
+
+	ea = GFS2_EA_BH2FIRST(*bhp);
+	ea->ea_rec_len = cpu_to_be32(sdp->sd_jbsize);
+	ea->ea_type = GFS2_EATYPE_UNUSED;
+	ea->ea_flags = GFS2_EAFLAG_LAST;
+	ea->ea_num_ptrs = 0;
+
+	gfs2_add_inode_blocks(&ip->i_inode, 1);
+
+	return 0;
+}
+
+/**
+ * ea_write - writes the request info to an ea, creating new blocks if
+ *            necessary
+ * @ip: inode that is being modified
+ * @ea: the location of the new ea in a block
+ * @er: the write request
+ *
+ * Note: does not update ea_rec_len or the GFS2_EAFLAG_LAST bin of ea_flags
+ *
+ * returns : errno
+ */
+
+static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
+		    struct gfs2_ea_request *er)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	int error;
+
+	ea->ea_data_len = cpu_to_be32(er->er_data_len);
+	ea->ea_name_len = er->er_name_len;
+	ea->ea_type = er->er_type;
+	ea->__pad = 0;
+
+	memcpy(GFS2_EA2NAME(ea), er->er_name, er->er_name_len);
+
+	if (GFS2_EAREQ_SIZE_STUFFED(er) <= sdp->sd_jbsize) {
+		ea->ea_num_ptrs = 0;
+		memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len);
+	} else {
+		__be64 *dataptr = GFS2_EA2DATAPTRS(ea);
+		const char *data = er->er_data;
+		unsigned int data_len = er->er_data_len;
+		unsigned int copy;
+		unsigned int x;
+
+		ea->ea_num_ptrs = DIV_ROUND_UP(er->er_data_len, sdp->sd_jbsize);
+		for (x = 0; x < ea->ea_num_ptrs; x++) {
+			struct buffer_head *bh;
+			u64 block;
+			int mh_size = sizeof(struct gfs2_meta_header);
+			unsigned int n = 1;
+
+			error = gfs2_alloc_block(ip, &block, &n);
+			if (error)
+				return error;
+			gfs2_trans_add_unrevoke(sdp, block, 1);
+			bh = gfs2_meta_new(ip->i_gl, block);
+			gfs2_trans_add_bh(ip->i_gl, bh, 1);
+			gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED);
+
+			gfs2_add_inode_blocks(&ip->i_inode, 1);
+
+			copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize :
+							   data_len;
+			memcpy(bh->b_data + mh_size, data, copy);
+			if (copy < sdp->sd_jbsize)
+				memset(bh->b_data + mh_size + copy, 0,
+				       sdp->sd_jbsize - copy);
+
+			*dataptr++ = cpu_to_be64(bh->b_blocknr);
+			data += copy;
+			data_len -= copy;
+
+			brelse(bh);
+		}
+
+		gfs2_assert_withdraw(sdp, !data_len);
+	}
+
+	return 0;
+}
+
+typedef int (*ea_skeleton_call_t) (struct gfs2_inode *ip,
+				   struct gfs2_ea_request *er, void *private);
+
+static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er,
+			     unsigned int blks,
+			     ea_skeleton_call_t skeleton_call, void *private)
+{
+	struct gfs2_alloc *al;
+	struct buffer_head *dibh;
+	int error;
+
+	al = gfs2_alloc_get(ip);
+	if (!al)
+		return -ENOMEM;
+
+	error = gfs2_quota_lock_check(ip);
+	if (error)
+		goto out;
+
+	al->al_requested = blks;
+
+	error = gfs2_inplace_reserve(ip);
+	if (error)
+		goto out_gunlock_q;
+
+	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode),
+				 blks + al->al_rgd->rd_length +
+				 RES_DINODE + RES_STATFS + RES_QUOTA, 0);
+	if (error)
+		goto out_ipres;
+
+	error = skeleton_call(ip, er, private);
+	if (error)
+		goto out_end_trans;
+
+	error = gfs2_meta_inode_buffer(ip, &dibh);
+	if (!error) {
+		ip->i_inode.i_ctime = CURRENT_TIME;
+		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+		gfs2_dinode_out(ip, dibh->b_data);
+		brelse(dibh);
+	}
+
+out_end_trans:
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
+out_ipres:
+	gfs2_inplace_release(ip);
+out_gunlock_q:
+	gfs2_quota_unlock(ip);
+out:
+	gfs2_alloc_put(ip);
+	return error;
+}
+
+static int ea_init_i(struct gfs2_inode *ip, struct gfs2_ea_request *er,
+		     void *private)
+{
+	struct buffer_head *bh;
+	int error;
+
+	error = ea_alloc_blk(ip, &bh);
+	if (error)
+		return error;
+
+	ip->i_eattr = bh->b_blocknr;
+	error = ea_write(ip, GFS2_EA_BH2FIRST(bh), er);
+
+	brelse(bh);
+
+	return error;
+}
+
+/**
+ * ea_init - initializes a new eattr block
+ * @ip:
+ * @er:
+ *
+ * Returns: errno
+ */
+
+static int ea_init(struct gfs2_inode *ip, int type, const char *name,
+		   const void *data, size_t size)
+{
+	struct gfs2_ea_request er;
+	unsigned int jbsize = GFS2_SB(&ip->i_inode)->sd_jbsize;
+	unsigned int blks = 1;
+
+	er.er_type = type;
+	er.er_name = name;
+	er.er_name_len = strlen(name);
+	er.er_data = (void *)data;
+	er.er_data_len = size;
+
+	if (GFS2_EAREQ_SIZE_STUFFED(&er) > jbsize)
+		blks += DIV_ROUND_UP(er.er_data_len, jbsize);
+
+	return ea_alloc_skeleton(ip, &er, blks, ea_init_i, NULL);
+}
+
+static struct gfs2_ea_header *ea_split_ea(struct gfs2_ea_header *ea)
+{
+	u32 ea_size = GFS2_EA_SIZE(ea);
+	struct gfs2_ea_header *new = (struct gfs2_ea_header *)((char *)ea +
+				     ea_size);
+	u32 new_size = GFS2_EA_REC_LEN(ea) - ea_size;
+	int last = ea->ea_flags & GFS2_EAFLAG_LAST;
+
+	ea->ea_rec_len = cpu_to_be32(ea_size);
+	ea->ea_flags ^= last;
+
+	new->ea_rec_len = cpu_to_be32(new_size);
+	new->ea_flags = last;
+
+	return new;
+}
+
+static void ea_set_remove_stuffed(struct gfs2_inode *ip,
+				  struct gfs2_ea_location *el)
+{
+	struct gfs2_ea_header *ea = el->el_ea;
+	struct gfs2_ea_header *prev = el->el_prev;
+	u32 len;
+
+	gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
+
+	if (!prev || !GFS2_EA_IS_STUFFED(ea)) {
+		ea->ea_type = GFS2_EATYPE_UNUSED;
+		return;
+	} else if (GFS2_EA2NEXT(prev) != ea) {
+		prev = GFS2_EA2NEXT(prev);
+		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), GFS2_EA2NEXT(prev) == ea);
+	}
+
+	len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
+	prev->ea_rec_len = cpu_to_be32(len);
+
+	if (GFS2_EA_IS_LAST(ea))
+		prev->ea_flags |= GFS2_EAFLAG_LAST;
+}
+
+struct ea_set {
+	int ea_split;
+
+	struct gfs2_ea_request *es_er;
+	struct gfs2_ea_location *es_el;
+
+	struct buffer_head *es_bh;
+	struct gfs2_ea_header *es_ea;
+};
+
+static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh,
+				 struct gfs2_ea_header *ea, struct ea_set *es)
+{
+	struct gfs2_ea_request *er = es->es_er;
+	struct buffer_head *dibh;
+	int error;
+
+	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + 2 * RES_EATTR, 0);
+	if (error)
+		return error;
+
+	gfs2_trans_add_bh(ip->i_gl, bh, 1);
+
+	if (es->ea_split)
+		ea = ea_split_ea(ea);
+
+	ea_write(ip, ea, er);
+
+	if (es->es_el)
+		ea_set_remove_stuffed(ip, es->es_el);
+
+	error = gfs2_meta_inode_buffer(ip, &dibh);
+	if (error)
+		goto out;
+	ip->i_inode.i_ctime = CURRENT_TIME;
+	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+	gfs2_dinode_out(ip, dibh->b_data);
+	brelse(dibh);
+out:
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
+	return error;
+}
+
+static int ea_set_simple_alloc(struct gfs2_inode *ip,
+			       struct gfs2_ea_request *er, void *private)
+{
+	struct ea_set *es = private;
+	struct gfs2_ea_header *ea = es->es_ea;
+	int error;
+
+	gfs2_trans_add_bh(ip->i_gl, es->es_bh, 1);
+
+	if (es->ea_split)
+		ea = ea_split_ea(ea);
+
+	error = ea_write(ip, ea, er);
+	if (error)
+		return error;
+
+	if (es->es_el)
+		ea_set_remove_stuffed(ip, es->es_el);
+
+	return 0;
+}
+
+static int ea_set_simple(struct gfs2_inode *ip, struct buffer_head *bh,
+			 struct gfs2_ea_header *ea, struct gfs2_ea_header *prev,
+			 void *private)
+{
+	struct ea_set *es = private;
+	unsigned int size;
+	int stuffed;
+	int error;
+
+	stuffed = ea_calc_size(GFS2_SB(&ip->i_inode), es->es_er->er_name_len,
+			       es->es_er->er_data_len, &size);
+
+	if (ea->ea_type == GFS2_EATYPE_UNUSED) {
+		if (GFS2_EA_REC_LEN(ea) < size)
+			return 0;
+		if (!GFS2_EA_IS_STUFFED(ea)) {
+			error = ea_remove_unstuffed(ip, bh, ea, prev, 1);
+			if (error)
+				return error;
+		}
+		es->ea_split = 0;
+	} else if (GFS2_EA_REC_LEN(ea) - GFS2_EA_SIZE(ea) >= size)
+		es->ea_split = 1;
+	else
+		return 0;
+
+	if (stuffed) {
+		error = ea_set_simple_noalloc(ip, bh, ea, es);
+		if (error)
+			return error;
+	} else {
+		unsigned int blks;
+
+		es->es_bh = bh;
+		es->es_ea = ea;
+		blks = 2 + DIV_ROUND_UP(es->es_er->er_data_len,
+					GFS2_SB(&ip->i_inode)->sd_jbsize);
+
+		error = ea_alloc_skeleton(ip, es->es_er, blks,
+					  ea_set_simple_alloc, es);
+		if (error)
+			return error;
+	}
+
+	return 1;
+}
+
+static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
+			void *private)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct buffer_head *indbh, *newbh;
+	__be64 *eablk;
+	int error;
+	int mh_size = sizeof(struct gfs2_meta_header);
+
+	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
+		__be64 *end;
+
+		error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT,
+				       &indbh);
+		if (error)
+			return error;
+
+		if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
+			error = -EIO;
+			goto out;
+		}
+
+		eablk = (__be64 *)(indbh->b_data + mh_size);
+		end = eablk + sdp->sd_inptrs;
+
+		for (; eablk < end; eablk++)
+			if (!*eablk)
+				break;
+
+		if (eablk == end) {
+			error = -ENOSPC;
+			goto out;
+		}
+
+		gfs2_trans_add_bh(ip->i_gl, indbh, 1);
+	} else {
+		u64 blk;
+		unsigned int n = 1;
+		error = gfs2_alloc_block(ip, &blk, &n);
+		if (error)
+			return error;
+		gfs2_trans_add_unrevoke(sdp, blk, 1);
+		indbh = gfs2_meta_new(ip->i_gl, blk);
+		gfs2_trans_add_bh(ip->i_gl, indbh, 1);
+		gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN);
+		gfs2_buffer_clear_tail(indbh, mh_size);
+
+		eablk = (__be64 *)(indbh->b_data + mh_size);
+		*eablk = cpu_to_be64(ip->i_eattr);
+		ip->i_eattr = blk;
+		ip->i_diskflags |= GFS2_DIF_EA_INDIRECT;
+		gfs2_add_inode_blocks(&ip->i_inode, 1);
+
+		eablk++;
+	}
+
+	error = ea_alloc_blk(ip, &newbh);
+	if (error)
+		goto out;
+
+	*eablk = cpu_to_be64((u64)newbh->b_blocknr);
+	error = ea_write(ip, GFS2_EA_BH2FIRST(newbh), er);
+	brelse(newbh);
+	if (error)
+		goto out;
+
+	if (private)
+		ea_set_remove_stuffed(ip, private);
+
+out:
+	brelse(indbh);
+	return error;
+}
+
+static int ea_set_i(struct gfs2_inode *ip, int type, const char *name,
+		    const void *value, size_t size, struct gfs2_ea_location *el)
+{
+	struct gfs2_ea_request er;
+	struct ea_set es;
+	unsigned int blks = 2;
+	int error;
+
+	er.er_type = type;
+	er.er_name = name;
+	er.er_data = (void *)value;
+	er.er_name_len = strlen(name);
+	er.er_data_len = size;
+
+	memset(&es, 0, sizeof(struct ea_set));
+	es.es_er = &er;
+	es.es_el = el;
+
+	error = ea_foreach(ip, ea_set_simple, &es);
+	if (error > 0)
+		return 0;
+	if (error)
+		return error;
+
+	if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT))
+		blks++;
+	if (GFS2_EAREQ_SIZE_STUFFED(&er) > GFS2_SB(&ip->i_inode)->sd_jbsize)
+		blks += DIV_ROUND_UP(er.er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize);
+
+	return ea_alloc_skeleton(ip, &er, blks, ea_set_block, el);
+}
+
+static int ea_set_remove_unstuffed(struct gfs2_inode *ip,
+				   struct gfs2_ea_location *el)
+{
+	if (el->el_prev && GFS2_EA2NEXT(el->el_prev) != el->el_ea) {
+		el->el_prev = GFS2_EA2NEXT(el->el_prev);
+		gfs2_assert_withdraw(GFS2_SB(&ip->i_inode),
+				     GFS2_EA2NEXT(el->el_prev) == el->el_ea);
+	}
+
+	return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev, 0);
+}
+
+static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)
+{
+	struct gfs2_ea_header *ea = el->el_ea;
+	struct gfs2_ea_header *prev = el->el_prev;
+	struct buffer_head *dibh;
+	int error;
+
+	error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
+	if (error)
+		return error;
+
+	gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
+
+	if (prev) {
+		u32 len;
+
+		len = GFS2_EA_REC_LEN(prev) + GFS2_EA_REC_LEN(ea);
+		prev->ea_rec_len = cpu_to_be32(len);
+
+		if (GFS2_EA_IS_LAST(ea))
+			prev->ea_flags |= GFS2_EAFLAG_LAST;
+	} else {
+		ea->ea_type = GFS2_EATYPE_UNUSED;
+	}
+
+	error = gfs2_meta_inode_buffer(ip, &dibh);
+	if (!error) {
+		ip->i_inode.i_ctime = CURRENT_TIME;
+		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+		gfs2_dinode_out(ip, dibh->b_data);
+		brelse(dibh);
+	}
+
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
+
+	return error;
+}
+
+/**
+ * gfs2_xattr_remove - Remove a GFS2 extended attribute
+ * @inode: The inode
+ * @type: The type of the extended attribute
+ * @name: The name of the extended attribute
+ *
+ * This is not called directly by the VFS since we use the (common)
+ * scheme of making a "set with NULL data" mean a remove request. Note
+ * that this is different from a set with zero length data.
+ *
+ * Returns: 0, or errno on failure
+ */
+
+static int gfs2_xattr_remove(struct inode *inode, int type, const char *name)
+{
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_ea_location el;
+	int error;
+
+	if (!ip->i_eattr)
+		return -ENODATA;
+
+	error = gfs2_ea_find(ip, type, name, &el);
+	if (error)
+		return error;
+	if (!el.el_ea)
+		return -ENODATA;
+
+	if (GFS2_EA_IS_STUFFED(el.el_ea))
+		error = ea_remove_stuffed(ip, &el);
+	else
+		error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, 0);
+
+	brelse(el.el_bh);
+
+	return error;
+}
+
+/**
+ * gfs2_xattr_set - Set (or remove) a GFS2 extended attribute
+ * @inode: The inode
+ * @type: The type of the extended attribute
+ * @name: The name of the extended attribute
+ * @value: The value of the extended attribute (NULL for remove)
+ * @size: The size of the @value argument
+ * @flags: Create or Replace
+ *
+ * See gfs2_xattr_remove() for details of the removal of xattrs.
+ *
+ * Returns: 0 or errno on failure
+ */
+
+int gfs2_xattr_set(struct inode *inode, int type, const char *name,
+		   const void *value, size_t size, int flags)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(inode);
+	struct gfs2_inode *ip = GFS2_I(inode);
+	struct gfs2_ea_location el;
+	unsigned int namel = strlen(name);
+	int error;
+
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (namel > GFS2_EA_MAX_NAME_LEN)
+		return -ERANGE;
+
+	if (value == NULL)
+		return gfs2_xattr_remove(inode, type, name);
+
+	if (ea_check_size(sdp, namel, size))
+		return -ERANGE;
+
+	if (!ip->i_eattr) {
+		if (flags & XATTR_REPLACE)
+			return -ENODATA;
+		return ea_init(ip, type, name, value, size);
+	}
+
+	error = gfs2_ea_find(ip, type, name, &el);
+	if (error)
+		return error;
+
+	if (el.el_ea) {
+		if (ip->i_diskflags & GFS2_DIF_APPENDONLY) {
+			brelse(el.el_bh);
+			return -EPERM;
+		}
+
+		error = -EEXIST;
+		if (!(flags & XATTR_CREATE)) {
+			int unstuffed = !GFS2_EA_IS_STUFFED(el.el_ea);
+			error = ea_set_i(ip, type, name, value, size, &el);
+			if (!error && unstuffed)
+				ea_set_remove_unstuffed(ip, &el);
+		}
+
+		brelse(el.el_bh);
+		return error;
+	}
+
+	error = -ENODATA;
+	if (!(flags & XATTR_REPLACE))
+		error = ea_set_i(ip, type, name, value, size, NULL);
+
+	return error;
+}
+
+static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
+				  struct gfs2_ea_header *ea, char *data)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct buffer_head **bh;
+	unsigned int amount = GFS2_EA_DATA_LEN(ea);
+	unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
+	__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
+	unsigned int x;
+	int error;
+
+	bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
+	if (!bh)
+		return -ENOMEM;
+
+	error = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
+	if (error)
+		goto out;
+
+	for (x = 0; x < nptrs; x++) {
+		error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
+				       bh + x);
+		if (error) {
+			while (x--)
+				brelse(bh[x]);
+			goto fail;
+		}
+		dataptrs++;
+	}
+
+	for (x = 0; x < nptrs; x++) {
+		error = gfs2_meta_wait(sdp, bh[x]);
+		if (error) {
+			for (; x < nptrs; x++)
+				brelse(bh[x]);
+			goto fail;
+		}
+		if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
+			for (; x < nptrs; x++)
+				brelse(bh[x]);
+			error = -EIO;
+			goto fail;
+		}
+
+		gfs2_trans_add_bh(ip->i_gl, bh[x], 1);
+
+		memcpy(bh[x]->b_data + sizeof(struct gfs2_meta_header), data,
+		       (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
+
+		amount -= sdp->sd_jbsize;
+		data += sdp->sd_jbsize;
+
+		brelse(bh[x]);
+	}
+
+out:
+	kfree(bh);
+	return error;
+
+fail:
+	gfs2_trans_end(sdp);
+	kfree(bh);
+	return error;
+}
+
+int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
+		      struct iattr *attr, char *data)
+{
+	struct buffer_head *dibh;
+	int error;
+
+	if (GFS2_EA_IS_STUFFED(el->el_ea)) {
+		error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
+		if (error)
+			return error;
+
+		gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
+		memcpy(GFS2_EA2DATA(el->el_ea), data,
+		       GFS2_EA_DATA_LEN(el->el_ea));
+	} else
+		error = ea_acl_chmod_unstuffed(ip, el->el_ea, data);
+
+	if (error)
+		return error;
+
+	error = gfs2_meta_inode_buffer(ip, &dibh);
+	if (!error) {
+		error = inode_setattr(&ip->i_inode, attr);
+		gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
+		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+		gfs2_dinode_out(ip, dibh->b_data);
+		brelse(dibh);
+	}
+
+	gfs2_trans_end(GFS2_SB(&ip->i_inode));
+
+	return error;
+}
+
+static int ea_dealloc_indirect(struct gfs2_inode *ip)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct gfs2_rgrp_list rlist;
+	struct buffer_head *indbh, *dibh;
+	__be64 *eablk, *end;
+	unsigned int rg_blocks = 0;
+	u64 bstart = 0;
+	unsigned int blen = 0;
+	unsigned int blks = 0;
+	unsigned int x;
+	int error;
+
+	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
+
+	error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh);
+	if (error)
+		return error;
+
+	if (gfs2_metatype_check(sdp, indbh, GFS2_METATYPE_IN)) {
+		error = -EIO;
+		goto out;
+	}
+
+	eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
+	end = eablk + sdp->sd_inptrs;
+
+	for (; eablk < end; eablk++) {
+		u64 bn;
+
+		if (!*eablk)
+			break;
+		bn = be64_to_cpu(*eablk);
+
+		if (bstart + blen == bn)
+			blen++;
+		else {
+			if (bstart)
+				gfs2_rlist_add(sdp, &rlist, bstart);
+			bstart = bn;
+			blen = 1;
+		}
+		blks++;
+	}
+	if (bstart)
+		gfs2_rlist_add(sdp, &rlist, bstart);
+	else
+		goto out;
+
+	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
+
+	for (x = 0; x < rlist.rl_rgrps; x++) {
+		struct gfs2_rgrpd *rgd;
+		rgd = rlist.rl_ghs[x].gh_gl->gl_object;
+		rg_blocks += rgd->rd_length;
+	}
+
+	error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
+	if (error)
+		goto out_rlist_free;
+
+	error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + RES_INDIRECT +
+				 RES_STATFS + RES_QUOTA, blks);
+	if (error)
+		goto out_gunlock;
+
+	gfs2_trans_add_bh(ip->i_gl, indbh, 1);
+
+	eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header));
+	bstart = 0;
+	blen = 0;
+
+	for (; eablk < end; eablk++) {
+		u64 bn;
+
+		if (!*eablk)
+			break;
+		bn = be64_to_cpu(*eablk);
+
+		if (bstart + blen == bn)
+			blen++;
+		else {
+			if (bstart)
+				gfs2_free_meta(ip, bstart, blen);
+			bstart = bn;
+			blen = 1;
+		}
+
+		*eablk = 0;
+		gfs2_add_inode_blocks(&ip->i_inode, -1);
+	}
+	if (bstart)
+		gfs2_free_meta(ip, bstart, blen);
+
+	ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT;
+
+	error = gfs2_meta_inode_buffer(ip, &dibh);
+	if (!error) {
+		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+		gfs2_dinode_out(ip, dibh->b_data);
+		brelse(dibh);
+	}
+
+	gfs2_trans_end(sdp);
+
+out_gunlock:
+	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
+out_rlist_free:
+	gfs2_rlist_free(&rlist);
+out:
+	brelse(indbh);
+	return error;
+}
+
+static int ea_dealloc_block(struct gfs2_inode *ip)
+{
+	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+	struct gfs2_alloc *al = ip->i_alloc;
+	struct gfs2_rgrpd *rgd;
+	struct buffer_head *dibh;
+	int error;
+
+	rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr);
+	if (!rgd) {
+		gfs2_consist_inode(ip);
+		return -EIO;
+	}
+
+	error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0,
+				   &al->al_rgd_gh);
+	if (error)
+		return error;
+
+	error = gfs2_trans_begin(sdp, RES_RG_BIT + RES_DINODE + RES_STATFS +
+				 RES_QUOTA, 1);
+	if (error)
+		goto out_gunlock;
+
+	gfs2_free_meta(ip, ip->i_eattr, 1);
+
+	ip->i_eattr = 0;
+	gfs2_add_inode_blocks(&ip->i_inode, -1);
+
+	error = gfs2_meta_inode_buffer(ip, &dibh);
+	if (!error) {
+		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+		gfs2_dinode_out(ip, dibh->b_data);
+		brelse(dibh);
+	}
+
+	gfs2_trans_end(sdp);
+
+out_gunlock:
+	gfs2_glock_dq_uninit(&al->al_rgd_gh);
+	return error;
+}
+
+/**
+ * gfs2_ea_dealloc - deallocate the extended attribute fork
+ * @ip: the inode
+ *
+ * Returns: errno
+ */
+
+int gfs2_ea_dealloc(struct gfs2_inode *ip)
+{
+	struct gfs2_alloc *al;
+	int error;
+
+	al = gfs2_alloc_get(ip);
+	if (!al)
+		return -ENOMEM;
+
+	error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
+	if (error)
+		goto out_alloc;
+
+	error = gfs2_rindex_hold(GFS2_SB(&ip->i_inode), &al->al_ri_gh);
+	if (error)
+		goto out_quota;
+
+	error = ea_foreach(ip, ea_dealloc_unstuffed, NULL);
+	if (error)
+		goto out_rindex;
+
+	if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
+		error = ea_dealloc_indirect(ip);
+		if (error)
+			goto out_rindex;
+	}
+
+	error = ea_dealloc_block(ip);
+
+out_rindex:
+	gfs2_glock_dq_uninit(&al->al_ri_gh);
+out_quota:
+	gfs2_quota_unhold(ip);
+out_alloc:
+	gfs2_alloc_put(ip);
+	return error;
+}
+
+static int gfs2_xattr_user_get(struct inode *inode, const char *name,
+			       void *buffer, size_t size)
+{
+	return gfs2_xattr_get(inode, GFS2_EATYPE_USR, name, buffer, size);
+}
+
+static int gfs2_xattr_user_set(struct inode *inode, const char *name,
+			       const void *value, size_t size, int flags)
+{
+	return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags);
+}
+
+static int gfs2_xattr_system_get(struct inode *inode, const char *name,
+				 void *buffer, size_t size)
+{
+	return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
+}
+
+static int gfs2_xattr_system_set(struct inode *inode, const char *name,
+				 const void *value, size_t size, int flags)
+{
+	return gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, flags);
+}
+
+static int gfs2_xattr_security_get(struct inode *inode, const char *name,
+				   void *buffer, size_t size)
+{
+	return gfs2_xattr_get(inode, GFS2_EATYPE_SECURITY, name, buffer, size);
+}
+
+static int gfs2_xattr_security_set(struct inode *inode, const char *name,
+				   const void *value, size_t size, int flags)
+{
+	return gfs2_xattr_set(inode, GFS2_EATYPE_SECURITY, name, value, size, flags);
+}
+
+static struct xattr_handler gfs2_xattr_user_handler = {
+	.prefix = XATTR_USER_PREFIX,
+	.get    = gfs2_xattr_user_get,
+	.set    = gfs2_xattr_user_set,
+};
+
+static struct xattr_handler gfs2_xattr_security_handler = {
+	.prefix = XATTR_SECURITY_PREFIX,
+	.get    = gfs2_xattr_security_get,
+	.set    = gfs2_xattr_security_set,
+};
+
+static struct xattr_handler gfs2_xattr_system_handler = {
+	.prefix = XATTR_SYSTEM_PREFIX,
+	.get    = gfs2_xattr_system_get,
+	.set    = gfs2_xattr_system_set,
+};
+
+struct xattr_handler *gfs2_xattr_handlers[] = {
+	&gfs2_xattr_user_handler,
+	&gfs2_xattr_security_handler,
+	&gfs2_xattr_system_handler,
+	NULL,
+};
+
diff --git a/fs/gfs2/xattr.h b/fs/gfs2/xattr.h
new file mode 100644
index 0000000..cbdfd77
--- /dev/null
+++ b/fs/gfs2/xattr.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
+ * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License version 2.
+ */
+
+#ifndef __EATTR_DOT_H__
+#define __EATTR_DOT_H__
+
+struct gfs2_inode;
+struct iattr;
+
+#define GFS2_EA_REC_LEN(ea) be32_to_cpu((ea)->ea_rec_len)
+#define GFS2_EA_DATA_LEN(ea) be32_to_cpu((ea)->ea_data_len)
+
+#define GFS2_EA_SIZE(ea) \
+ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \
+      ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \
+				  (sizeof(__be64) * (ea)->ea_num_ptrs)), 8)
+
+#define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs)
+#define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST)
+
+#define GFS2_EAREQ_SIZE_STUFFED(er) \
+ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + (er)->er_data_len, 8)
+
+#define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1))
+#define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len)
+
+#define GFS2_EA2DATAPTRS(ea) \
+((__be64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8)))
+
+#define GFS2_EA2NEXT(ea) \
+((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea)))
+
+#define GFS2_EA_BH2FIRST(bh) \
+((struct gfs2_ea_header *)((bh)->b_data + sizeof(struct gfs2_meta_header)))
+
+struct gfs2_ea_request {
+	const char *er_name;
+	char *er_data;
+	unsigned int er_name_len;
+	unsigned int er_data_len;
+	unsigned int er_type; /* GFS2_EATYPE_... */
+};
+
+struct gfs2_ea_location {
+	struct buffer_head *el_bh;
+	struct gfs2_ea_header *el_ea;
+	struct gfs2_ea_header *el_prev;
+};
+
+extern int gfs2_xattr_get(struct inode *inode, int type, const char *name,
+			  void *buffer, size_t size);
+extern int gfs2_xattr_set(struct inode *inode, int type, const char *name,
+			  const void *value, size_t size, int flags);
+extern ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size);
+extern int gfs2_ea_dealloc(struct gfs2_inode *ip);
+
+/* Exported to acl.c */
+
+extern int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
+			struct gfs2_ea_location *el);
+extern int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
+			    char *data, size_t size);
+extern int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
+			     struct iattr *attr, char *data);
+
+#endif /* __EATTR_DOT_H__ */
diff --git a/fs/inode.c b/fs/inode.c
index ae7b67e..b2ba83d 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -182,9 +182,7 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 	if (sb->s_bdev) {
 		struct backing_dev_info *bdi;
 
-		bdi = sb->s_bdev->bd_inode_backing_dev_info;
-		if (!bdi)
-			bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
+		bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
 		mapping->backing_dev_info = bdi;
 	}
 	inode->i_private = NULL;
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 61f32f3..b0435dd 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -456,7 +456,7 @@ int cleanup_journal_tail(journal_t *journal)
 {
 	transaction_t * transaction;
 	tid_t		first_tid;
-	unsigned long	blocknr, freed;
+	unsigned int	blocknr, freed;
 
 	if (is_journal_aborted(journal))
 		return 1;
@@ -502,8 +502,8 @@ int cleanup_journal_tail(journal_t *journal)
 		freed = freed + journal->j_last - journal->j_first;
 
 	jbd_debug(1,
-		  "Cleaning journal tail from %d to %d (offset %lu), "
-		  "freeing %lu\n",
+		  "Cleaning journal tail from %d to %d (offset %u), "
+		  "freeing %u\n",
 		  journal->j_tail_sequence, first_tid, blocknr, freed);
 
 	journal->j_free += freed;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 618e21c..4bd8825 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -308,7 +308,7 @@ void journal_commit_transaction(journal_t *journal)
 	int bufs;
 	int flags;
 	int err;
-	unsigned long blocknr;
+	unsigned int blocknr;
 	ktime_t start_time;
 	u64 commit_time;
 	char *tagp = NULL;
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index f96f850..bd3c073 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -276,7 +276,7 @@ static void journal_kill_thread(journal_t *journal)
 int journal_write_metadata_buffer(transaction_t *transaction,
 				  struct journal_head  *jh_in,
 				  struct journal_head **jh_out,
-				  unsigned long blocknr)
+				  unsigned int blocknr)
 {
 	int need_copy_out = 0;
 	int done_copy_out = 0;
@@ -567,9 +567,9 @@ int log_wait_commit(journal_t *journal, tid_t tid)
  * Log buffer allocation routines:
  */
 
-int journal_next_log_block(journal_t *journal, unsigned long *retp)
+int journal_next_log_block(journal_t *journal, unsigned int *retp)
 {
-	unsigned long blocknr;
+	unsigned int blocknr;
 
 	spin_lock(&journal->j_state_lock);
 	J_ASSERT(journal->j_free > 1);
@@ -590,11 +590,11 @@ int journal_next_log_block(journal_t *journal, unsigned long *retp)
  * this is a no-op.  If needed, we can use j_blk_offset - everything is
  * ready.
  */
-int journal_bmap(journal_t *journal, unsigned long blocknr,
-		 unsigned long *retp)
+int journal_bmap(journal_t *journal, unsigned int blocknr,
+		 unsigned int *retp)
 {
 	int err = 0;
-	unsigned long ret;
+	unsigned int ret;
 
 	if (journal->j_inode) {
 		ret = bmap(journal->j_inode, blocknr);
@@ -604,7 +604,7 @@ int journal_bmap(journal_t *journal, unsigned long blocknr,
 			char b[BDEVNAME_SIZE];
 
 			printk(KERN_ALERT "%s: journal block not found "
-					"at offset %lu on %s\n",
+					"at offset %u on %s\n",
 				__func__,
 				blocknr,
 				bdevname(journal->j_dev, b));
@@ -630,7 +630,7 @@ int journal_bmap(journal_t *journal, unsigned long blocknr,
 struct journal_head *journal_get_descriptor_buffer(journal_t *journal)
 {
 	struct buffer_head *bh;
-	unsigned long blocknr;
+	unsigned int blocknr;
 	int err;
 
 	err = journal_next_log_block(journal, &blocknr);
@@ -774,7 +774,7 @@ journal_t * journal_init_inode (struct inode *inode)
 	journal_t *journal = journal_init_common();
 	int err;
 	int n;
-	unsigned long blocknr;
+	unsigned int blocknr;
 
 	if (!journal)
 		return NULL;
@@ -846,12 +846,12 @@ static void journal_fail_superblock (journal_t *journal)
 static int journal_reset(journal_t *journal)
 {
 	journal_superblock_t *sb = journal->j_superblock;
-	unsigned long first, last;
+	unsigned int first, last;
 
 	first = be32_to_cpu(sb->s_first);
 	last = be32_to_cpu(sb->s_maxlen);
 	if (first + JFS_MIN_JOURNAL_BLOCKS > last + 1) {
-		printk(KERN_ERR "JBD: Journal too short (blocks %lu-%lu).\n",
+		printk(KERN_ERR "JBD: Journal too short (blocks %u-%u).\n",
 		       first, last);
 		journal_fail_superblock(journal);
 		return -EINVAL;
@@ -885,7 +885,7 @@ static int journal_reset(journal_t *journal)
  **/
 int journal_create(journal_t *journal)
 {
-	unsigned long blocknr;
+	unsigned int blocknr;
 	struct buffer_head *bh;
 	journal_superblock_t *sb;
 	int i, err;
@@ -969,14 +969,14 @@ void journal_update_superblock(journal_t *journal, int wait)
 	if (sb->s_start == 0 && journal->j_tail_sequence ==
 				journal->j_transaction_sequence) {
 		jbd_debug(1,"JBD: Skipping superblock update on recovered sb "
-			"(start %ld, seq %d, errno %d)\n",
+			"(start %u, seq %d, errno %d)\n",
 			journal->j_tail, journal->j_tail_sequence,
 			journal->j_errno);
 		goto out;
 	}
 
 	spin_lock(&journal->j_state_lock);
-	jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n",
+	jbd_debug(1,"JBD: updating superblock (start %u, seq %d, errno %d)\n",
 		  journal->j_tail, journal->j_tail_sequence, journal->j_errno);
 
 	sb->s_sequence = cpu_to_be32(journal->j_tail_sequence);
@@ -1371,7 +1371,7 @@ int journal_flush(journal_t *journal)
 {
 	int err = 0;
 	transaction_t *transaction = NULL;
-	unsigned long old_tail;
+	unsigned int old_tail;
 
 	spin_lock(&journal->j_state_lock);
 
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index db5e982..cb1a49a 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -70,7 +70,7 @@ static int do_readahead(journal_t *journal, unsigned int start)
 {
 	int err;
 	unsigned int max, nbufs, next;
-	unsigned long blocknr;
+	unsigned int blocknr;
 	struct buffer_head *bh;
 
 	struct buffer_head * bufs[MAXBUF];
@@ -132,7 +132,7 @@ static int jread(struct buffer_head **bhp, journal_t *journal,
 		 unsigned int offset)
 {
 	int err;
-	unsigned long blocknr;
+	unsigned int blocknr;
 	struct buffer_head *bh;
 
 	*bhp = NULL;
@@ -314,7 +314,7 @@ static int do_one_pass(journal_t *journal,
 			struct recovery_info *info, enum passtype pass)
 {
 	unsigned int		first_commit_ID, next_commit_ID;
-	unsigned long		next_log_block;
+	unsigned int		next_log_block;
 	int			err, success = 0;
 	journal_superblock_t *	sb;
 	journal_header_t *	tmp;
@@ -367,14 +367,14 @@ static int do_one_pass(journal_t *journal,
 			if (tid_geq(next_commit_ID, info->end_transaction))
 				break;
 
-		jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n",
+		jbd_debug(2, "Scanning for sequence ID %u at %u/%u\n",
 			  next_commit_ID, next_log_block, journal->j_last);
 
 		/* Skip over each chunk of the transaction looking
 		 * either the next descriptor block or the final commit
 		 * record. */
 
-		jbd_debug(3, "JBD: checking block %ld\n", next_log_block);
+		jbd_debug(3, "JBD: checking block %u\n", next_log_block);
 		err = jread(&bh, journal, next_log_block);
 		if (err)
 			goto failed;
@@ -429,7 +429,7 @@ static int do_one_pass(journal_t *journal,
 			tagp = &bh->b_data[sizeof(journal_header_t)];
 			while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
 			       <= journal->j_blocksize) {
-				unsigned long io_block;
+				unsigned int io_block;
 
 				tag = (journal_block_tag_t *) tagp;
 				flags = be32_to_cpu(tag->t_flags);
@@ -443,10 +443,10 @@ static int do_one_pass(journal_t *journal,
 					success = err;
 					printk (KERN_ERR
 						"JBD: IO error %d recovering "
-						"block %ld in log\n",
+						"block %u in log\n",
 						err, io_block);
 				} else {
-					unsigned long blocknr;
+					unsigned int blocknr;
 
 					J_ASSERT(obh != NULL);
 					blocknr = be32_to_cpu(tag->t_blocknr);
@@ -581,7 +581,7 @@ static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
 	max = be32_to_cpu(header->r_count);
 
 	while (offset < max) {
-		unsigned long blocknr;
+		unsigned int blocknr;
 		int err;
 
 		blocknr = be32_to_cpu(* ((__be32 *) (bh->b_data+offset)));
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index da6cd9b..ad71732 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -101,7 +101,7 @@ struct jbd_revoke_record_s
 {
 	struct list_head  hash;
 	tid_t		  sequence;	/* Used for recovery only */
-	unsigned long	  blocknr;
+	unsigned int	  blocknr;
 };
 
 
@@ -126,7 +126,7 @@ static void flush_descriptor(journal_t *, struct journal_head *, int, int);
 /* Utility functions to maintain the revoke table */
 
 /* Borrowed from buffer.c: this is a tried and tested block hash function */
-static inline int hash(journal_t *journal, unsigned long block)
+static inline int hash(journal_t *journal, unsigned int block)
 {
 	struct jbd_revoke_table_s *table = journal->j_revoke;
 	int hash_shift = table->hash_shift;
@@ -136,7 +136,7 @@ static inline int hash(journal_t *journal, unsigned long block)
 		(block << (hash_shift - 12))) & (table->hash_size - 1);
 }
 
-static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
+static int insert_revoke_hash(journal_t *journal, unsigned int blocknr,
 			      tid_t seq)
 {
 	struct list_head *hash_list;
@@ -166,7 +166,7 @@ oom:
 /* Find a revoke record in the journal's hash table. */
 
 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
-						      unsigned long blocknr)
+						      unsigned int blocknr)
 {
 	struct list_head *hash_list;
 	struct jbd_revoke_record_s *record;
@@ -332,7 +332,7 @@ void journal_destroy_revoke(journal_t *journal)
  * by one.
  */
 
-int journal_revoke(handle_t *handle, unsigned long blocknr,
+int journal_revoke(handle_t *handle, unsigned int blocknr,
 		   struct buffer_head *bh_in)
 {
 	struct buffer_head *bh = NULL;
@@ -401,7 +401,7 @@ int journal_revoke(handle_t *handle, unsigned long blocknr,
 		}
 	}
 
-	jbd_debug(2, "insert revoke for block %lu, bh_in=%p\n", blocknr, bh_in);
+	jbd_debug(2, "insert revoke for block %u, bh_in=%p\n", blocknr, bh_in);
 	err = insert_revoke_hash(journal, blocknr,
 				handle->h_transaction->t_tid);
 	BUFFER_TRACE(bh_in, "exit");
@@ -644,7 +644,7 @@ static void flush_descriptor(journal_t *journal,
  */
 
 int journal_set_revoke(journal_t *journal,
-		       unsigned long blocknr,
+		       unsigned int blocknr,
 		       tid_t sequence)
 {
 	struct jbd_revoke_record_s *record;
@@ -668,7 +668,7 @@ int journal_set_revoke(journal_t *journal,
  */
 
 int journal_test_revoke(journal_t *journal,
-			unsigned long blocknr,
+			unsigned int blocknr,
 			tid_t sequence)
 {
 	struct jbd_revoke_record_s *record;
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index c03ac11..006f9ad 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -56,7 +56,8 @@ get_transaction(journal_t *journal, transaction_t *transaction)
 	spin_lock_init(&transaction->t_handle_lock);
 
 	/* Set up the commit timer for the new transaction. */
-	journal->j_commit_timer.expires = round_jiffies(transaction->t_expires);
+	journal->j_commit_timer.expires =
+				round_jiffies_up(transaction->t_expires);
 	add_timer(&journal->j_commit_timer);
 
 	J_ASSERT(journal->j_running_transaction == NULL);
@@ -228,6 +229,8 @@ repeat_locked:
 		  __log_space_left(journal));
 	spin_unlock(&transaction->t_handle_lock);
 	spin_unlock(&journal->j_state_lock);
+
+	lock_map_acquire(&handle->h_lockdep_map);
 out:
 	if (unlikely(new_transaction))		/* It's usually NULL */
 		kfree(new_transaction);
@@ -292,9 +295,6 @@ handle_t *journal_start(journal_t *journal, int nblocks)
 		handle = ERR_PTR(err);
 		goto out;
 	}
-
-	lock_map_acquire(&handle->h_lockdep_map);
-
 out:
 	return handle;
 }
@@ -416,6 +416,7 @@ int journal_restart(handle_t *handle, int nblocks)
 	__log_start_commit(journal, transaction->t_tid);
 	spin_unlock(&journal->j_state_lock);
 
+	lock_map_release(&handle->h_lockdep_map);
 	handle->h_buffer_credits = nblocks;
 	ret = start_this_handle(journal, handle);
 	return ret;
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 7b4088b..26d991d 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -25,6 +25,7 @@
 #include <linux/writeback.h>
 #include <linux/backing-dev.h>
 #include <linux/bio.h>
+#include <linux/blkdev.h>
 #include <trace/events/jbd2.h>
 
 /*
@@ -133,8 +134,8 @@ static int journal_submit_commit_record(journal_t *journal,
 	bh->b_end_io = journal_end_buffer_io_sync;
 
 	if (journal->j_flags & JBD2_BARRIER &&
-		!JBD2_HAS_INCOMPAT_FEATURE(journal,
-					 JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+	    !JBD2_HAS_INCOMPAT_FEATURE(journal,
+				       JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
 		set_buffer_ordered(bh);
 		barrier_done = 1;
 	}
@@ -220,7 +221,6 @@ static int journal_submit_inode_data_buffers(struct address_space *mapping)
 		.nr_to_write = mapping->nrpages * 2,
 		.range_start = 0,
 		.range_end = i_size_read(mapping->host),
-		.for_writepages = 1,
 	};
 
 	ret = generic_writepages(mapping, &wbc);
@@ -707,11 +707,13 @@ start_journal_io:
 	/* Done it all: now write the commit record asynchronously. */
 
 	if (JBD2_HAS_INCOMPAT_FEATURE(journal,
-		JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+				      JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
 		err = journal_submit_commit_record(journal, commit_transaction,
 						 &cbh, crc32_sum);
 		if (err)
 			__jbd2_journal_abort_hard(journal);
+		if (journal->j_flags & JBD2_BARRIER)
+			blkdev_issue_flush(journal->j_dev, NULL);
 	}
 
 	/*
@@ -834,7 +836,7 @@ wait_for_iobuf:
 	jbd_debug(3, "JBD: commit phase 5\n");
 
 	if (!JBD2_HAS_INCOMPAT_FEATURE(journal,
-		JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
+				       JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) {
 		err = journal_submit_commit_record(journal, commit_transaction,
 						&cbh, crc32_sum);
 		if (err)
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index e378cb3..a8a358b 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1187,6 +1187,12 @@ static int journal_reset(journal_t *journal)
 
 	first = be32_to_cpu(sb->s_first);
 	last = be32_to_cpu(sb->s_maxlen);
+	if (first + JBD2_MIN_JOURNAL_BLOCKS > last + 1) {
+		printk(KERN_ERR "JBD: Journal too short (blocks %llu-%llu).\n",
+		       first, last);
+		journal_fail_superblock(journal);
+		return -EINVAL;
+	}
 
 	journal->j_first = first;
 	journal->j_last = last;
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 6213ac7..a051270 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -57,7 +57,7 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction)
 	INIT_LIST_HEAD(&transaction->t_private_list);
 
 	/* Set up the commit timer for the new transaction. */
-	journal->j_commit_timer.expires = round_jiffies(transaction->t_expires);
+	journal->j_commit_timer.expires = round_jiffies_up(transaction->t_expires);
 	add_timer(&journal->j_commit_timer);
 
 	J_ASSERT(journal->j_running_transaction == NULL);
@@ -238,6 +238,8 @@ repeat_locked:
 		  __jbd2_log_space_left(journal));
 	spin_unlock(&transaction->t_handle_lock);
 	spin_unlock(&journal->j_state_lock);
+
+	lock_map_acquire(&handle->h_lockdep_map);
 out:
 	if (unlikely(new_transaction))		/* It's usually NULL */
 		kfree(new_transaction);
@@ -303,8 +305,6 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
 		handle = ERR_PTR(err);
 		goto out;
 	}
-
-	lock_map_acquire(&handle->h_lockdep_map);
 out:
 	return handle;
 }
@@ -426,6 +426,7 @@ int jbd2_journal_restart(handle_t *handle, int nblocks)
 	__jbd2_log_start_commit(journal, transaction->t_tid);
 	spin_unlock(&journal->j_state_lock);
 
+	lock_map_release(&handle->h_lockdep_map);
 	handle->h_buffer_credits = nblocks;
 	ret = start_this_handle(journal, handle);
 	return ret;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index e350bd6..a7ce15d 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -933,10 +933,6 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
 		goto out_error;
 
 	nfs_server_set_fsinfo(server, &fsinfo);
-	error = bdi_init(&server->backing_dev_info);
-	if (error)
-		goto out_error;
-
 
 	/* Get some general file system info */
 	if (server->namelen == 0) {
@@ -995,6 +991,12 @@ static struct nfs_server *nfs_alloc_server(void)
 		return NULL;
 	}
 
+	if (bdi_init(&server->backing_dev_info)) {
+		nfs_free_iostats(server->io_stats);
+		kfree(server);
+		return NULL;
+	}
+
 	return server;
 }
 
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 867f705..f1cc058 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -1918,6 +1918,8 @@ static inline void nfs_initialise_sb(struct super_block *sb)
 	if (server->flags & NFS_MOUNT_NOAC)
 		sb->s_flags |= MS_SYNCHRONOUS;
 
+	sb->s_bdi = &server->backing_dev_info;
+
 	nfs_super_set_maxbytes(sb, server->maxfilesize);
 }
 
@@ -2188,8 +2190,8 @@ static void nfs_kill_super(struct super_block *s)
 {
 	struct nfs_server *server = NFS_SB(s);
 
-	bdi_unregister(&server->backing_dev_info);
 	kill_anon_super(s);
+	bdi_unregister(&server->backing_dev_info);
 	nfs_fscache_release_super_cookie(s);
 	nfs_free_server(server);
 }
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 120acad..53eb26c 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1490,7 +1490,6 @@ static int nfs_write_mapping(struct address_space *mapping, int how)
 		.nr_to_write = LONG_MAX,
 		.range_start = 0,
 		.range_end = LLONG_MAX,
-		.for_writepages = 1,
 	};
 
 	return __nfs_write_mapping(mapping, &wbc, how);
diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig
index 72da095..251da07 100644
--- a/fs/nilfs2/Kconfig
+++ b/fs/nilfs2/Kconfig
@@ -1,6 +1,6 @@
 config NILFS2_FS
 	tristate "NILFS2 file system support (EXPERIMENTAL)"
-	depends on BLOCK && EXPERIMENTAL
+	depends on EXPERIMENTAL
 	select CRC32
 	help
 	  NILFS2 is a log-structured file system (LFS) supporting continuous
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 99d58a0..08834df 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -36,6 +36,26 @@ struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
 	return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
 }
 
+/**
+ * nilfs_bmap_lookup_at_level - find a data block or node block
+ * @bmap: bmap
+ * @key: key
+ * @level: level
+ * @ptrp: place to store the value associated to @key
+ *
+ * Description: nilfs_bmap_lookup_at_level() finds a record whose key
+ * matches @key in the block at @level of the bmap.
+ *
+ * Return Value: On success, 0 is returned and the record associated with @key
+ * is stored in the place pointed by @ptrp. On error, one of the following
+ * negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - A record associated with @key does not exist.
+ */
 int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
 			       __u64 *ptrp)
 {
@@ -69,39 +89,6 @@ int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
 	return ret;
 }
 
-/**
- * nilfs_bmap_lookup - find a record
- * @bmap: bmap
- * @key: key
- * @recp: pointer to record
- *
- * Description: nilfs_bmap_lookup() finds a record whose key matches @key in
- * @bmap.
- *
- * Return Value: On success, 0 is returned and the record associated with @key
- * is stored in the place pointed by @recp. On error, one of the following
- * negative error codes is returned.
- *
- * %-EIO - I/O error.
- *
- * %-ENOMEM - Insufficient amount of memory available.
- *
- * %-ENOENT - A record associated with @key does not exist.
- */
-int nilfs_bmap_lookup(struct nilfs_bmap *bmap,
-		      unsigned long key,
-		      unsigned long *recp)
-{
-	__u64 ptr;
-	int ret;
-
-	/* XXX: use macro for level 1 */
-	ret = nilfs_bmap_lookup_at_level(bmap, key, 1, &ptr);
-	if (recp != NULL)
-		*recp = ptr;
-	return ret;
-}
-
 static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
 {
 	__u64 keys[NILFS_BMAP_SMALL_HIGH + 1];
@@ -469,104 +456,6 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
 		(entries_per_group / NILFS_BMAP_GROUP_DIV);
 }
 
-int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
-				 union nilfs_bmap_ptr_req *req)
-{
-	return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
-				 union nilfs_bmap_ptr_req *req)
-{
-	nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
-			      union nilfs_bmap_ptr_req *req)
-{
-	nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-int nilfs_bmap_start_v(struct nilfs_bmap *bmap, union nilfs_bmap_ptr_req *req,
-		       sector_t blocknr)
-{
-	struct inode *dat = nilfs_bmap_get_dat(bmap);
-	int ret;
-
-	ret = nilfs_dat_prepare_start(dat, &req->bpr_req);
-	if (likely(!ret))
-		nilfs_dat_commit_start(dat, &req->bpr_req, blocknr);
-	return ret;
-}
-
-int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
-			     union nilfs_bmap_ptr_req *req)
-{
-	return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
-			     union nilfs_bmap_ptr_req *req)
-{
-	nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req,
-			     bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
-}
-
-void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
-			    union nilfs_bmap_ptr_req *req)
-{
-	nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-int nilfs_bmap_move_v(const struct nilfs_bmap *bmap, __u64 vblocknr,
-		      sector_t blocknr)
-{
-	return nilfs_dat_move(nilfs_bmap_get_dat(bmap), vblocknr, blocknr);
-}
-
-int nilfs_bmap_mark_dirty(const struct nilfs_bmap *bmap, __u64 vblocknr)
-{
-	return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr);
-}
-
-int nilfs_bmap_prepare_update_v(struct nilfs_bmap *bmap,
-				union nilfs_bmap_ptr_req *oldreq,
-				union nilfs_bmap_ptr_req *newreq)
-{
-	struct inode *dat = nilfs_bmap_get_dat(bmap);
-	int ret;
-
-	ret = nilfs_dat_prepare_end(dat, &oldreq->bpr_req);
-	if (ret < 0)
-		return ret;
-	ret = nilfs_dat_prepare_alloc(dat, &newreq->bpr_req);
-	if (ret < 0)
-		nilfs_dat_abort_end(dat, &oldreq->bpr_req);
-
-	return ret;
-}
-
-void nilfs_bmap_commit_update_v(struct nilfs_bmap *bmap,
-				union nilfs_bmap_ptr_req *oldreq,
-				union nilfs_bmap_ptr_req *newreq)
-{
-	struct inode *dat = nilfs_bmap_get_dat(bmap);
-
-	nilfs_dat_commit_end(dat, &oldreq->bpr_req,
-			     bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
-	nilfs_dat_commit_alloc(dat, &newreq->bpr_req);
-}
-
-void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap,
-			       union nilfs_bmap_ptr_req *oldreq,
-			       union nilfs_bmap_ptr_req *newreq)
-{
-	struct inode *dat = nilfs_bmap_get_dat(bmap);
-
-	nilfs_dat_abort_end(dat, &oldreq->bpr_req);
-	nilfs_dat_abort_alloc(dat, &newreq->bpr_req);
-}
-
 static struct lock_class_key nilfs_bmap_dat_lock_key;
 static struct lock_class_key nilfs_bmap_mdt_lock_key;
 
diff --git a/fs/nilfs2/bmap.h b/fs/nilfs2/bmap.h
index b2890cd..9980d7d 100644
--- a/fs/nilfs2/bmap.h
+++ b/fs/nilfs2/bmap.h
@@ -28,6 +28,7 @@
 #include <linux/buffer_head.h>
 #include <linux/nilfs2_fs.h>
 #include "alloc.h"
+#include "dat.h"
 
 #define NILFS_BMAP_INVALID_PTR	0
 
@@ -141,7 +142,6 @@ struct nilfs_bmap {
 int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *);
 int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *);
 void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *);
-int nilfs_bmap_lookup(struct nilfs_bmap *, unsigned long, unsigned long *);
 int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned);
 int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long);
 int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long);
@@ -160,90 +160,76 @@ void nilfs_bmap_init_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
 void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
 
 
+static inline int nilfs_bmap_lookup(struct nilfs_bmap *bmap, __u64 key,
+				    __u64 *ptr)
+{
+	return nilfs_bmap_lookup_at_level(bmap, key, 1, ptr);
+}
+
 /*
  * Internal use only
  */
 struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *);
-int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *,
-			       union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *,
-			       union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *,
-			      union nilfs_bmap_ptr_req *);
 
 static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap,
-					       union nilfs_bmap_ptr_req *req)
+					       union nilfs_bmap_ptr_req *req,
+					       struct inode *dat)
 {
-	if (NILFS_BMAP_USE_VBN(bmap))
-		return nilfs_bmap_prepare_alloc_v(bmap, req);
+	if (dat)
+		return nilfs_dat_prepare_alloc(dat, &req->bpr_req);
 	/* ignore target ptr */
 	req->bpr_ptr = bmap->b_last_allocated_ptr++;
 	return 0;
 }
 
 static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap,
-					       union nilfs_bmap_ptr_req *req)
+					       union nilfs_bmap_ptr_req *req,
+					       struct inode *dat)
 {
-	if (NILFS_BMAP_USE_VBN(bmap))
-		nilfs_bmap_commit_alloc_v(bmap, req);
+	if (dat)
+		nilfs_dat_commit_alloc(dat, &req->bpr_req);
 }
 
 static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap,
-					      union nilfs_bmap_ptr_req *req)
+					      union nilfs_bmap_ptr_req *req,
+					      struct inode *dat)
 {
-	if (NILFS_BMAP_USE_VBN(bmap))
-		nilfs_bmap_abort_alloc_v(bmap, req);
+	if (dat)
+		nilfs_dat_abort_alloc(dat, &req->bpr_req);
 	else
 		bmap->b_last_allocated_ptr--;
 }
 
-int nilfs_bmap_prepare_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
-
 static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap,
-					     union nilfs_bmap_ptr_req *req)
+					     union nilfs_bmap_ptr_req *req,
+					     struct inode *dat)
 {
-	return NILFS_BMAP_USE_VBN(bmap) ?
-		nilfs_bmap_prepare_end_v(bmap, req) : 0;
+	return dat ? nilfs_dat_prepare_end(dat, &req->bpr_req) : 0;
 }
 
 static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap,
-					     union nilfs_bmap_ptr_req *req)
+					     union nilfs_bmap_ptr_req *req,
+					     struct inode *dat)
 {
-	if (NILFS_BMAP_USE_VBN(bmap))
-		nilfs_bmap_commit_end_v(bmap, req);
+	if (dat)
+		nilfs_dat_commit_end(dat, &req->bpr_req,
+				     bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
 }
 
 static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap,
-					    union nilfs_bmap_ptr_req *req)
+					    union nilfs_bmap_ptr_req *req,
+					    struct inode *dat)
 {
-	if (NILFS_BMAP_USE_VBN(bmap))
-		nilfs_bmap_abort_end_v(bmap, req);
+	if (dat)
+		nilfs_dat_abort_end(dat, &req->bpr_req);
 }
 
-int nilfs_bmap_start_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *,
-		       sector_t);
-int nilfs_bmap_move_v(const struct nilfs_bmap *, __u64, sector_t);
-int nilfs_bmap_mark_dirty(const struct nilfs_bmap *, __u64);
-
-
 __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
 			      const struct buffer_head *);
 
 __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64);
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *);
 
-int nilfs_bmap_prepare_update_v(struct nilfs_bmap *,
-				union nilfs_bmap_ptr_req *,
-				union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_update_v(struct nilfs_bmap *,
-				union nilfs_bmap_ptr_req *,
-				union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_update_v(struct nilfs_bmap *,
-			       union nilfs_bmap_ptr_req *,
-			       union nilfs_bmap_ptr_req *);
-
 void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int);
 void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int);
 
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index aa41272..e25b507 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -71,21 +71,17 @@ void nilfs_btree_path_cache_destroy(void)
 	kmem_cache_destroy(nilfs_btree_path_cache);
 }
 
-static inline struct nilfs_btree_path *
-nilfs_btree_alloc_path(const struct nilfs_btree *btree)
+static inline struct nilfs_btree_path *nilfs_btree_alloc_path(void)
 {
-	return (struct nilfs_btree_path *)
-		kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
+	return kmem_cache_alloc(nilfs_btree_path_cache, GFP_NOFS);
 }
 
-static inline void nilfs_btree_free_path(const struct nilfs_btree *btree,
-					 struct nilfs_btree_path *path)
+static inline void nilfs_btree_free_path(struct nilfs_btree_path *path)
 {
 	kmem_cache_free(nilfs_btree_path_cache, path);
 }
 
-static void nilfs_btree_init_path(const struct nilfs_btree *btree,
-				  struct nilfs_btree_path *path)
+static void nilfs_btree_init_path(struct nilfs_btree_path *path)
 {
 	int level;
 
@@ -101,26 +97,13 @@ static void nilfs_btree_init_path(const struct nilfs_btree *btree,
 	}
 }
 
-static void nilfs_btree_clear_path(const struct nilfs_btree *btree,
-				   struct nilfs_btree_path *path)
+static void nilfs_btree_release_path(struct nilfs_btree_path *path)
 {
 	int level;
 
-	for (level = NILFS_BTREE_LEVEL_DATA;
-	     level < NILFS_BTREE_LEVEL_MAX;
-	     level++) {
-		if (path[level].bp_bh != NULL) {
-			brelse(path[level].bp_bh);
-			path[level].bp_bh = NULL;
-		}
-		/* sib_bh is released or deleted by prepare or commit
-		 * operations. */
-		path[level].bp_sib_bh = NULL;
-		path[level].bp_index = 0;
-		path[level].bp_oldreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
-		path[level].bp_newreq.bpr_ptr = NILFS_BMAP_INVALID_PTR;
-		path[level].bp_op = NULL;
-	}
+	for (level = NILFS_BTREE_LEVEL_DATA; level < NILFS_BTREE_LEVEL_MAX;
+	     level++)
+		brelse(path[level].bp_bh);
 }
 
 /*
@@ -148,129 +131,110 @@ static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
 }
 
 static inline int
-nilfs_btree_node_get_flags(const struct nilfs_btree *btree,
-			   const struct nilfs_btree_node *node)
+nilfs_btree_node_get_flags(const struct nilfs_btree_node *node)
 {
 	return node->bn_flags;
 }
 
 static inline void
-nilfs_btree_node_set_flags(struct nilfs_btree *btree,
-			   struct nilfs_btree_node *node,
-			   int flags)
+nilfs_btree_node_set_flags(struct nilfs_btree_node *node, int flags)
 {
 	node->bn_flags = flags;
 }
 
-static inline int nilfs_btree_node_root(const struct nilfs_btree *btree,
-					const struct nilfs_btree_node *node)
+static inline int nilfs_btree_node_root(const struct nilfs_btree_node *node)
 {
-	return nilfs_btree_node_get_flags(btree, node) & NILFS_BTREE_NODE_ROOT;
+	return nilfs_btree_node_get_flags(node) & NILFS_BTREE_NODE_ROOT;
 }
 
 static inline int
-nilfs_btree_node_get_level(const struct nilfs_btree *btree,
-			   const struct nilfs_btree_node *node)
+nilfs_btree_node_get_level(const struct nilfs_btree_node *node)
 {
 	return node->bn_level;
 }
 
 static inline void
-nilfs_btree_node_set_level(struct nilfs_btree *btree,
-			   struct nilfs_btree_node *node,
-			   int level)
+nilfs_btree_node_set_level(struct nilfs_btree_node *node, int level)
 {
 	node->bn_level = level;
 }
 
 static inline int
-nilfs_btree_node_get_nchildren(const struct nilfs_btree *btree,
-			       const struct nilfs_btree_node *node)
+nilfs_btree_node_get_nchildren(const struct nilfs_btree_node *node)
 {
 	return le16_to_cpu(node->bn_nchildren);
 }
 
 static inline void
-nilfs_btree_node_set_nchildren(struct nilfs_btree *btree,
-			       struct nilfs_btree_node *node,
-			       int nchildren)
+nilfs_btree_node_set_nchildren(struct nilfs_btree_node *node, int nchildren)
 {
 	node->bn_nchildren = cpu_to_le16(nchildren);
 }
 
-static inline int
-nilfs_btree_node_size(const struct nilfs_btree *btree)
+static inline int nilfs_btree_node_size(const struct nilfs_btree *btree)
 {
 	return 1 << btree->bt_bmap.b_inode->i_blkbits;
 }
 
 static inline int
-nilfs_btree_node_nchildren_min(const struct nilfs_btree *btree,
-			       const struct nilfs_btree_node *node)
+nilfs_btree_node_nchildren_min(const struct nilfs_btree_node *node,
+			       const struct nilfs_btree *btree)
 {
-	return nilfs_btree_node_root(btree, node) ?
+	return nilfs_btree_node_root(node) ?
 		NILFS_BTREE_ROOT_NCHILDREN_MIN :
 		NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree));
 }
 
 static inline int
-nilfs_btree_node_nchildren_max(const struct nilfs_btree *btree,
-			       const struct nilfs_btree_node *node)
+nilfs_btree_node_nchildren_max(const struct nilfs_btree_node *node,
+			       const struct nilfs_btree *btree)
 {
-	return nilfs_btree_node_root(btree, node) ?
+	return nilfs_btree_node_root(node) ?
 		NILFS_BTREE_ROOT_NCHILDREN_MAX :
 		NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(btree));
 }
 
 static inline __le64 *
-nilfs_btree_node_dkeys(const struct nilfs_btree *btree,
-		       const struct nilfs_btree_node *node)
+nilfs_btree_node_dkeys(const struct nilfs_btree_node *node)
 {
 	return (__le64 *)((char *)(node + 1) +
-			  (nilfs_btree_node_root(btree, node) ?
+			  (nilfs_btree_node_root(node) ?
 			   0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE));
 }
 
 static inline __le64 *
-nilfs_btree_node_dptrs(const struct nilfs_btree *btree,
-		       const struct nilfs_btree_node *node)
+nilfs_btree_node_dptrs(const struct nilfs_btree_node *node,
+		       const struct nilfs_btree *btree)
 {
-	return (__le64 *)(nilfs_btree_node_dkeys(btree, node) +
-			  nilfs_btree_node_nchildren_max(btree, node));
+	return (__le64 *)(nilfs_btree_node_dkeys(node) +
+			  nilfs_btree_node_nchildren_max(node, btree));
 }
 
 static inline __u64
-nilfs_btree_node_get_key(const struct nilfs_btree *btree,
-			 const struct nilfs_btree_node *node, int index)
+nilfs_btree_node_get_key(const struct nilfs_btree_node *node, int index)
 {
-	return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(btree, node) +
-					index));
+	return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(node) + index));
 }
 
 static inline void
-nilfs_btree_node_set_key(struct nilfs_btree *btree,
-			 struct nilfs_btree_node *node, int index, __u64 key)
+nilfs_btree_node_set_key(struct nilfs_btree_node *node, int index, __u64 key)
 {
-	*(nilfs_btree_node_dkeys(btree, node) + index) =
-		nilfs_bmap_key_to_dkey(key);
+	*(nilfs_btree_node_dkeys(node) + index) = nilfs_bmap_key_to_dkey(key);
 }
 
 static inline __u64
 nilfs_btree_node_get_ptr(const struct nilfs_btree *btree,
-			 const struct nilfs_btree_node *node,
-			 int index)
+			 const struct nilfs_btree_node *node, int index)
 {
-	return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(btree, node) +
+	return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(node, btree) +
 					index));
 }
 
 static inline void
 nilfs_btree_node_set_ptr(struct nilfs_btree *btree,
-			 struct nilfs_btree_node *node,
-			 int index,
-			 __u64 ptr)
+			 struct nilfs_btree_node *node, int index, __u64 ptr)
 {
-	*(nilfs_btree_node_dptrs(btree, node) + index) =
+	*(nilfs_btree_node_dptrs(node, btree) + index) =
 		nilfs_bmap_ptr_to_dptr(ptr);
 }
 
@@ -283,12 +247,12 @@ static void nilfs_btree_node_init(struct nilfs_btree *btree,
 	__le64 *dptrs;
 	int i;
 
-	nilfs_btree_node_set_flags(btree, node, flags);
-	nilfs_btree_node_set_level(btree, node, level);
-	nilfs_btree_node_set_nchildren(btree, node, nchildren);
+	nilfs_btree_node_set_flags(node, flags);
+	nilfs_btree_node_set_level(node, level);
+	nilfs_btree_node_set_nchildren(node, nchildren);
 
-	dkeys = nilfs_btree_node_dkeys(btree, node);
-	dptrs = nilfs_btree_node_dptrs(btree, node);
+	dkeys = nilfs_btree_node_dkeys(node);
+	dptrs = nilfs_btree_node_dptrs(node, btree);
 	for (i = 0; i < nchildren; i++) {
 		dkeys[i] = nilfs_bmap_key_to_dkey(keys[i]);
 		dptrs[i] = nilfs_bmap_ptr_to_dptr(ptrs[i]);
@@ -305,13 +269,13 @@ static void nilfs_btree_node_move_left(struct nilfs_btree *btree,
 	__le64 *ldptrs, *rdptrs;
 	int lnchildren, rnchildren;
 
-	ldkeys = nilfs_btree_node_dkeys(btree, left);
-	ldptrs = nilfs_btree_node_dptrs(btree, left);
-	lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+	ldkeys = nilfs_btree_node_dkeys(left);
+	ldptrs = nilfs_btree_node_dptrs(left, btree);
+	lnchildren = nilfs_btree_node_get_nchildren(left);
 
-	rdkeys = nilfs_btree_node_dkeys(btree, right);
-	rdptrs = nilfs_btree_node_dptrs(btree, right);
-	rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+	rdkeys = nilfs_btree_node_dkeys(right);
+	rdptrs = nilfs_btree_node_dptrs(right, btree);
+	rnchildren = nilfs_btree_node_get_nchildren(right);
 
 	memcpy(ldkeys + lnchildren, rdkeys, n * sizeof(*rdkeys));
 	memcpy(ldptrs + lnchildren, rdptrs, n * sizeof(*rdptrs));
@@ -320,8 +284,8 @@ static void nilfs_btree_node_move_left(struct nilfs_btree *btree,
 
 	lnchildren += n;
 	rnchildren -= n;
-	nilfs_btree_node_set_nchildren(btree, left, lnchildren);
-	nilfs_btree_node_set_nchildren(btree, right, rnchildren);
+	nilfs_btree_node_set_nchildren(left, lnchildren);
+	nilfs_btree_node_set_nchildren(right, rnchildren);
 }
 
 /* Assume that the buffer heads corresponding to left and right are locked. */
@@ -334,13 +298,13 @@ static void nilfs_btree_node_move_right(struct nilfs_btree *btree,
 	__le64 *ldptrs, *rdptrs;
 	int lnchildren, rnchildren;
 
-	ldkeys = nilfs_btree_node_dkeys(btree, left);
-	ldptrs = nilfs_btree_node_dptrs(btree, left);
-	lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+	ldkeys = nilfs_btree_node_dkeys(left);
+	ldptrs = nilfs_btree_node_dptrs(left, btree);
+	lnchildren = nilfs_btree_node_get_nchildren(left);
 
-	rdkeys = nilfs_btree_node_dkeys(btree, right);
-	rdptrs = nilfs_btree_node_dptrs(btree, right);
-	rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+	rdkeys = nilfs_btree_node_dkeys(right);
+	rdptrs = nilfs_btree_node_dptrs(right, btree);
+	rnchildren = nilfs_btree_node_get_nchildren(right);
 
 	memmove(rdkeys + n, rdkeys, rnchildren * sizeof(*rdkeys));
 	memmove(rdptrs + n, rdptrs, rnchildren * sizeof(*rdptrs));
@@ -349,8 +313,8 @@ static void nilfs_btree_node_move_right(struct nilfs_btree *btree,
 
 	lnchildren -= n;
 	rnchildren += n;
-	nilfs_btree_node_set_nchildren(btree, left, lnchildren);
-	nilfs_btree_node_set_nchildren(btree, right, rnchildren);
+	nilfs_btree_node_set_nchildren(left, lnchildren);
+	nilfs_btree_node_set_nchildren(right, rnchildren);
 }
 
 /* Assume that the buffer head corresponding to node is locked. */
@@ -362,9 +326,9 @@ static void nilfs_btree_node_insert(struct nilfs_btree *btree,
 	__le64 *dptrs;
 	int nchildren;
 
-	dkeys = nilfs_btree_node_dkeys(btree, node);
-	dptrs = nilfs_btree_node_dptrs(btree, node);
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
+	dkeys = nilfs_btree_node_dkeys(node);
+	dptrs = nilfs_btree_node_dptrs(node, btree);
+	nchildren = nilfs_btree_node_get_nchildren(node);
 	if (index < nchildren) {
 		memmove(dkeys + index + 1, dkeys + index,
 			(nchildren - index) * sizeof(*dkeys));
@@ -374,7 +338,7 @@ static void nilfs_btree_node_insert(struct nilfs_btree *btree,
 	dkeys[index] = nilfs_bmap_key_to_dkey(key);
 	dptrs[index] = nilfs_bmap_ptr_to_dptr(ptr);
 	nchildren++;
-	nilfs_btree_node_set_nchildren(btree, node, nchildren);
+	nilfs_btree_node_set_nchildren(node, nchildren);
 }
 
 /* Assume that the buffer head corresponding to node is locked. */
@@ -388,11 +352,11 @@ static void nilfs_btree_node_delete(struct nilfs_btree *btree,
 	__le64 *dptrs;
 	int nchildren;
 
-	dkeys = nilfs_btree_node_dkeys(btree, node);
-	dptrs = nilfs_btree_node_dptrs(btree, node);
+	dkeys = nilfs_btree_node_dkeys(node);
+	dptrs = nilfs_btree_node_dptrs(node, btree);
 	key = nilfs_bmap_dkey_to_key(dkeys[index]);
 	ptr = nilfs_bmap_dptr_to_ptr(dptrs[index]);
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
+	nchildren = nilfs_btree_node_get_nchildren(node);
 	if (keyp != NULL)
 		*keyp = key;
 	if (ptrp != NULL)
@@ -405,11 +369,10 @@ static void nilfs_btree_node_delete(struct nilfs_btree *btree,
 			(nchildren - index - 1) * sizeof(*dptrs));
 	}
 	nchildren--;
-	nilfs_btree_node_set_nchildren(btree, node, nchildren);
+	nilfs_btree_node_set_nchildren(node, nchildren);
 }
 
-static int nilfs_btree_node_lookup(const struct nilfs_btree *btree,
-				   const struct nilfs_btree_node *node,
+static int nilfs_btree_node_lookup(const struct nilfs_btree_node *node,
 				   __u64 key, int *indexp)
 {
 	__u64 nkey;
@@ -417,12 +380,12 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree *btree,
 
 	/* binary search */
 	low = 0;
-	high = nilfs_btree_node_get_nchildren(btree, node) - 1;
+	high = nilfs_btree_node_get_nchildren(node) - 1;
 	index = 0;
 	s = 0;
 	while (low <= high) {
 		index = (low + high) / 2;
-		nkey = nilfs_btree_node_get_key(btree, node, index);
+		nkey = nilfs_btree_node_get_key(node, index);
 		if (nkey == key) {
 			s = 0;
 			goto out;
@@ -436,9 +399,8 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree *btree,
 	}
 
 	/* adjust index */
-	if (nilfs_btree_node_get_level(btree, node) >
-	    NILFS_BTREE_LEVEL_NODE_MIN) {
-		if ((s > 0) && (index > 0))
+	if (nilfs_btree_node_get_level(node) > NILFS_BTREE_LEVEL_NODE_MIN) {
+		if (s > 0 && index > 0)
 			index--;
 	} else if (s < 0)
 		index++;
@@ -456,25 +418,20 @@ nilfs_btree_get_root(const struct nilfs_btree *btree)
 }
 
 static inline struct nilfs_btree_node *
-nilfs_btree_get_nonroot_node(const struct nilfs_btree *btree,
-			     const struct nilfs_btree_path *path,
-			     int level)
+nilfs_btree_get_nonroot_node(const struct nilfs_btree_path *path, int level)
 {
 	return (struct nilfs_btree_node *)path[level].bp_bh->b_data;
 }
 
 static inline struct nilfs_btree_node *
-nilfs_btree_get_sib_node(const struct nilfs_btree *btree,
-			 const struct nilfs_btree_path *path,
-			 int level)
+nilfs_btree_get_sib_node(const struct nilfs_btree_path *path, int level)
 {
 	return (struct nilfs_btree_node *)path[level].bp_sib_bh->b_data;
 }
 
 static inline int nilfs_btree_height(const struct nilfs_btree *btree)
 {
-	return nilfs_btree_node_get_level(btree, nilfs_btree_get_root(btree))
-		+ 1;
+	return nilfs_btree_node_get_level(nilfs_btree_get_root(btree)) + 1;
 }
 
 static inline struct nilfs_btree_node *
@@ -484,7 +441,7 @@ nilfs_btree_get_node(const struct nilfs_btree *btree,
 {
 	return (level == nilfs_btree_height(btree) - 1) ?
 		nilfs_btree_get_root(btree) :
-		nilfs_btree_get_nonroot_node(btree, path, level);
+		nilfs_btree_get_nonroot_node(path, level);
 }
 
 static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
@@ -496,12 +453,11 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
 	int level, index, found, ret;
 
 	node = nilfs_btree_get_root(btree);
-	level = nilfs_btree_node_get_level(btree, node);
-	if ((level < minlevel) ||
-	    (nilfs_btree_node_get_nchildren(btree, node) <= 0))
+	level = nilfs_btree_node_get_level(node);
+	if (level < minlevel || nilfs_btree_node_get_nchildren(node) <= 0)
 		return -ENOENT;
 
-	found = nilfs_btree_node_lookup(btree, node, key, &index);
+	found = nilfs_btree_node_lookup(node, key, &index);
 	ptr = nilfs_btree_node_get_ptr(btree, node, index);
 	path[level].bp_bh = NULL;
 	path[level].bp_index = index;
@@ -510,14 +466,13 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
 		ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
 		if (ret < 0)
 			return ret;
-		node = nilfs_btree_get_nonroot_node(btree, path, level);
-		BUG_ON(level != nilfs_btree_node_get_level(btree, node));
+		node = nilfs_btree_get_nonroot_node(path, level);
+		BUG_ON(level != nilfs_btree_node_get_level(node));
 		if (!found)
-			found = nilfs_btree_node_lookup(btree, node, key,
-							&index);
+			found = nilfs_btree_node_lookup(node, key, &index);
 		else
 			index = 0;
-		if (index < nilfs_btree_node_nchildren_max(btree, node))
+		if (index < nilfs_btree_node_nchildren_max(node, btree))
 			ptr = nilfs_btree_node_get_ptr(btree, node, index);
 		else {
 			WARN_ON(found || level != NILFS_BTREE_LEVEL_NODE_MIN);
@@ -544,10 +499,10 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
 	int index, level, ret;
 
 	node = nilfs_btree_get_root(btree);
-	index = nilfs_btree_node_get_nchildren(btree, node) - 1;
+	index = nilfs_btree_node_get_nchildren(node) - 1;
 	if (index < 0)
 		return -ENOENT;
-	level = nilfs_btree_node_get_level(btree, node);
+	level = nilfs_btree_node_get_level(node);
 	ptr = nilfs_btree_node_get_ptr(btree, node, index);
 	path[level].bp_bh = NULL;
 	path[level].bp_index = index;
@@ -556,15 +511,15 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
 		ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
 		if (ret < 0)
 			return ret;
-		node = nilfs_btree_get_nonroot_node(btree, path, level);
-		BUG_ON(level != nilfs_btree_node_get_level(btree, node));
-		index = nilfs_btree_node_get_nchildren(btree, node) - 1;
+		node = nilfs_btree_get_nonroot_node(path, level);
+		BUG_ON(level != nilfs_btree_node_get_level(node));
+		index = nilfs_btree_node_get_nchildren(node) - 1;
 		ptr = nilfs_btree_node_get_ptr(btree, node, index);
 		path[level].bp_index = index;
 	}
 
 	if (keyp != NULL)
-		*keyp = nilfs_btree_node_get_key(btree, node, index);
+		*keyp = nilfs_btree_node_get_key(node, index);
 	if (ptrp != NULL)
 		*ptrp = ptr;
 
@@ -580,18 +535,18 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
 	int ret;
 
 	btree = (struct nilfs_btree *)bmap;
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 
 	ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
 
 	if (ptrp != NULL)
 		*ptrp = ptr;
 
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 
 	return ret;
 }
@@ -608,10 +563,10 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
 	int level = NILFS_BTREE_LEVEL_NODE_MIN;
 	int ret, cnt, index, maxlevel;
 
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 	ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
 	if (ret < 0)
 		goto out;
@@ -631,8 +586,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
 	node = nilfs_btree_get_node(btree, path, level);
 	index = path[level].bp_index + 1;
 	for (;;) {
-		while (index < nilfs_btree_node_get_nchildren(btree, node)) {
-			if (nilfs_btree_node_get_key(btree, node, index) !=
+		while (index < nilfs_btree_node_get_nchildren(node)) {
+			if (nilfs_btree_node_get_key(node, index) !=
 			    key + cnt)
 				goto end;
 			ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
@@ -653,8 +608,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
 		/* look-up right sibling node */
 		node = nilfs_btree_get_node(btree, path, level + 1);
 		index = path[level + 1].bp_index + 1;
-		if (index >= nilfs_btree_node_get_nchildren(btree, node) ||
-		    nilfs_btree_node_get_key(btree, node, index) != key + cnt)
+		if (index >= nilfs_btree_node_get_nchildren(node) ||
+		    nilfs_btree_node_get_key(node, index) != key + cnt)
 			break;
 		ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
 		path[level + 1].bp_index = index;
@@ -664,7 +619,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
 		ret = nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh);
 		if (ret < 0)
 			goto out;
-		node = nilfs_btree_get_nonroot_node(btree, path, level);
+		node = nilfs_btree_get_nonroot_node(path, level);
 		index = 0;
 		path[level].bp_index = index;
 	}
@@ -672,8 +627,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
 	*ptrp = ptr;
 	ret = cnt;
  out:
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 	return ret;
 }
 
@@ -685,9 +640,7 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree,
 		do {
 			lock_buffer(path[level].bp_bh);
 			nilfs_btree_node_set_key(
-				btree,
-				nilfs_btree_get_nonroot_node(
-					btree, path, level),
+				nilfs_btree_get_nonroot_node(path, level),
 				path[level].bp_index, key);
 			if (!buffer_dirty(path[level].bp_bh))
 				nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -698,8 +651,7 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree,
 
 	/* root */
 	if (level == nilfs_btree_height(btree) - 1) {
-		nilfs_btree_node_set_key(btree,
-					 nilfs_btree_get_root(btree),
+		nilfs_btree_node_set_key(nilfs_btree_get_root(btree),
 					 path[level].bp_index, key);
 	}
 }
@@ -712,7 +664,7 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree,
 
 	if (level < nilfs_btree_height(btree) - 1) {
 		lock_buffer(path[level].bp_bh);
-		node = nilfs_btree_get_nonroot_node(btree, path, level);
+		node = nilfs_btree_get_nonroot_node(path, level);
 		nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
 					path[level].bp_index);
 		if (!buffer_dirty(path[level].bp_bh))
@@ -721,8 +673,8 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree,
 
 		if (path[level].bp_index == 0)
 			nilfs_btree_promote_key(btree, path, level + 1,
-						nilfs_btree_node_get_key(
-							btree, node, 0));
+						nilfs_btree_node_get_key(node,
+									 0));
 	} else {
 		node = nilfs_btree_get_root(btree);
 		nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
@@ -740,10 +692,10 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_bh);
 	lock_buffer(path[level].bp_sib_bh);
 
-	node = nilfs_btree_get_nonroot_node(btree, path, level);
-	left = nilfs_btree_get_sib_node(btree, path, level);
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
-	lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+	node = nilfs_btree_get_nonroot_node(path, level);
+	left = nilfs_btree_get_sib_node(path, level);
+	nchildren = nilfs_btree_node_get_nchildren(node);
+	lnchildren = nilfs_btree_node_get_nchildren(left);
 	move = 0;
 
 	n = (nchildren + lnchildren + 1) / 2 - lnchildren;
@@ -764,7 +716,7 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
 	unlock_buffer(path[level].bp_sib_bh);
 
 	nilfs_btree_promote_key(btree, path, level + 1,
-				nilfs_btree_node_get_key(btree, node, 0));
+				nilfs_btree_node_get_key(node, 0));
 
 	if (move) {
 		brelse(path[level].bp_bh);
@@ -791,10 +743,10 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_bh);
 	lock_buffer(path[level].bp_sib_bh);
 
-	node = nilfs_btree_get_nonroot_node(btree, path, level);
-	right = nilfs_btree_get_sib_node(btree, path, level);
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
-	rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+	node = nilfs_btree_get_nonroot_node(path, level);
+	right = nilfs_btree_get_sib_node(path, level);
+	nchildren = nilfs_btree_node_get_nchildren(node);
+	rnchildren = nilfs_btree_node_get_nchildren(right);
 	move = 0;
 
 	n = (nchildren + rnchildren + 1) / 2 - rnchildren;
@@ -816,15 +768,14 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
 
 	path[level + 1].bp_index++;
 	nilfs_btree_promote_key(btree, path, level + 1,
-				nilfs_btree_node_get_key(btree, right, 0));
+				nilfs_btree_node_get_key(right, 0));
 	path[level + 1].bp_index--;
 
 	if (move) {
 		brelse(path[level].bp_bh);
 		path[level].bp_bh = path[level].bp_sib_bh;
 		path[level].bp_sib_bh = NULL;
-		path[level].bp_index -=
-			nilfs_btree_node_get_nchildren(btree, node);
+		path[level].bp_index -= nilfs_btree_node_get_nchildren(node);
 		path[level + 1].bp_index++;
 	} else {
 		brelse(path[level].bp_sib_bh);
@@ -846,9 +797,9 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_bh);
 	lock_buffer(path[level].bp_sib_bh);
 
-	node = nilfs_btree_get_nonroot_node(btree, path, level);
-	right = nilfs_btree_get_sib_node(btree, path, level);
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
+	node = nilfs_btree_get_nonroot_node(path, level);
+	right = nilfs_btree_get_sib_node(path, level);
+	nchildren = nilfs_btree_node_get_nchildren(node);
 	move = 0;
 
 	n = (nchildren + 1) / 2;
@@ -867,16 +818,15 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
 	unlock_buffer(path[level].bp_bh);
 	unlock_buffer(path[level].bp_sib_bh);
 
-	newkey = nilfs_btree_node_get_key(btree, right, 0);
+	newkey = nilfs_btree_node_get_key(right, 0);
 	newptr = path[level].bp_newreq.bpr_ptr;
 
 	if (move) {
-		path[level].bp_index -=
-			nilfs_btree_node_get_nchildren(btree, node);
+		path[level].bp_index -= nilfs_btree_node_get_nchildren(node);
 		nilfs_btree_node_insert(btree, right, *keyp, *ptrp,
 					path[level].bp_index);
 
-		*keyp = nilfs_btree_node_get_key(btree, right, 0);
+		*keyp = nilfs_btree_node_get_key(right, 0);
 		*ptrp = path[level].bp_newreq.bpr_ptr;
 
 		brelse(path[level].bp_bh);
@@ -885,7 +835,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
 	} else {
 		nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
 
-		*keyp = nilfs_btree_node_get_key(btree, right, 0);
+		*keyp = nilfs_btree_node_get_key(right, 0);
 		*ptrp = path[level].bp_newreq.bpr_ptr;
 
 		brelse(path[level].bp_sib_bh);
@@ -905,12 +855,12 @@ static void nilfs_btree_grow(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_sib_bh);
 
 	root = nilfs_btree_get_root(btree);
-	child = nilfs_btree_get_sib_node(btree, path, level);
+	child = nilfs_btree_get_sib_node(path, level);
 
-	n = nilfs_btree_node_get_nchildren(btree, root);
+	n = nilfs_btree_node_get_nchildren(root);
 
 	nilfs_btree_node_move_right(btree, root, child, n);
-	nilfs_btree_node_set_level(btree, root, level + 1);
+	nilfs_btree_node_set_level(root, level + 1);
 
 	if (!buffer_dirty(path[level].bp_sib_bh))
 		nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
@@ -922,7 +872,7 @@ static void nilfs_btree_grow(struct nilfs_btree *btree,
 
 	nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
 
-	*keyp = nilfs_btree_node_get_key(btree, child, 0);
+	*keyp = nilfs_btree_node_get_key(child, 0);
 	*ptrp = path[level].bp_newreq.bpr_ptr;
 }
 
@@ -990,26 +940,29 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 	struct nilfs_btree_node *node, *parent, *sib;
 	__u64 sibptr;
 	int pindex, level, ret;
+	struct inode *dat = NULL;
 
 	stats->bs_nblocks = 0;
 	level = NILFS_BTREE_LEVEL_DATA;
 
 	/* allocate a new ptr for data block */
-	if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
+	if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) {
 		path[level].bp_newreq.bpr_ptr =
 			nilfs_btree_find_target_v(btree, path, key);
+		dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+	}
 
 	ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
-					   &path[level].bp_newreq);
+					   &path[level].bp_newreq, dat);
 	if (ret < 0)
 		goto err_out_data;
 
 	for (level = NILFS_BTREE_LEVEL_NODE_MIN;
 	     level < nilfs_btree_height(btree) - 1;
 	     level++) {
-		node = nilfs_btree_get_nonroot_node(btree, path, level);
-		if (nilfs_btree_node_get_nchildren(btree, node) <
-		    nilfs_btree_node_nchildren_max(btree, node)) {
+		node = nilfs_btree_get_nonroot_node(path, level);
+		if (nilfs_btree_node_get_nchildren(node) <
+		    nilfs_btree_node_nchildren_max(node, btree)) {
 			path[level].bp_op = nilfs_btree_do_insert;
 			stats->bs_nblocks++;
 			goto out;
@@ -1026,8 +979,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 			if (ret < 0)
 				goto err_out_child_node;
 			sib = (struct nilfs_btree_node *)bh->b_data;
-			if (nilfs_btree_node_get_nchildren(btree, sib) <
-			    nilfs_btree_node_nchildren_max(btree, sib)) {
+			if (nilfs_btree_node_get_nchildren(sib) <
+			    nilfs_btree_node_nchildren_max(sib, btree)) {
 				path[level].bp_sib_bh = bh;
 				path[level].bp_op = nilfs_btree_carry_left;
 				stats->bs_nblocks++;
@@ -1038,15 +991,15 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
 		/* right sibling */
 		if (pindex <
-		    nilfs_btree_node_get_nchildren(btree, parent) - 1) {
+		    nilfs_btree_node_get_nchildren(parent) - 1) {
 			sibptr = nilfs_btree_node_get_ptr(btree, parent,
 							  pindex + 1);
 			ret = nilfs_btree_get_block(btree, sibptr, &bh);
 			if (ret < 0)
 				goto err_out_child_node;
 			sib = (struct nilfs_btree_node *)bh->b_data;
-			if (nilfs_btree_node_get_nchildren(btree, sib) <
-			    nilfs_btree_node_nchildren_max(btree, sib)) {
+			if (nilfs_btree_node_get_nchildren(sib) <
+			    nilfs_btree_node_nchildren_max(sib, btree)) {
 				path[level].bp_sib_bh = bh;
 				path[level].bp_op = nilfs_btree_carry_right;
 				stats->bs_nblocks++;
@@ -1059,7 +1012,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 		path[level].bp_newreq.bpr_ptr =
 			path[level - 1].bp_newreq.bpr_ptr + 1;
 		ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
-						   &path[level].bp_newreq);
+						   &path[level].bp_newreq, dat);
 		if (ret < 0)
 			goto err_out_child_node;
 		ret = nilfs_btree_get_new_block(btree,
@@ -1081,8 +1034,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
 	/* root */
 	node = nilfs_btree_get_root(btree);
-	if (nilfs_btree_node_get_nchildren(btree, node) <
-	    nilfs_btree_node_nchildren_max(btree, node)) {
+	if (nilfs_btree_node_get_nchildren(node) <
+	    nilfs_btree_node_nchildren_max(node, btree)) {
 		path[level].bp_op = nilfs_btree_do_insert;
 		stats->bs_nblocks++;
 		goto out;
@@ -1091,7 +1044,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 	/* grow */
 	path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1;
 	ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
-					   &path[level].bp_newreq);
+					   &path[level].bp_newreq, dat);
 	if (ret < 0)
 		goto err_out_child_node;
 	ret = nilfs_btree_get_new_block(btree, path[level].bp_newreq.bpr_ptr,
@@ -1119,16 +1072,18 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
 	/* error */
  err_out_curr_node:
-	nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
+	nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq,
+				   dat);
  err_out_child_node:
 	for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) {
 		nilfs_btnode_delete(path[level].bp_sib_bh);
 		nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap,
-					   &path[level].bp_newreq);
+					   &path[level].bp_newreq, dat);
 
 	}
 
-	nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
+	nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq,
+				   dat);
  err_out_data:
 	*levelp = level;
 	stats->bs_nblocks = 0;
@@ -1139,16 +1094,19 @@ static void nilfs_btree_commit_insert(struct nilfs_btree *btree,
 				      struct nilfs_btree_path *path,
 				      int maxlevel, __u64 key, __u64 ptr)
 {
+	struct inode *dat = NULL;
 	int level;
 
 	set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
 	ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr;
-	if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
+	if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) {
 		nilfs_btree_set_target_v(btree, key, ptr);
+		dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+	}
 
 	for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
 		nilfs_bmap_commit_alloc_ptr(&btree->bt_bmap,
-					    &path[level - 1].bp_newreq);
+					    &path[level - 1].bp_newreq, dat);
 		path[level].bp_op(btree, path, level, &key, &ptr);
 	}
 
@@ -1164,10 +1122,10 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
 	int level, ret;
 
 	btree = (struct nilfs_btree *)bmap;
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 
 	ret = nilfs_btree_do_lookup(btree, path, key, NULL,
 				    NILFS_BTREE_LEVEL_NODE_MIN);
@@ -1184,8 +1142,8 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
 	nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
 
  out:
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 	return ret;
 }
 
@@ -1197,7 +1155,7 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree,
 
 	if (level < nilfs_btree_height(btree) - 1) {
 		lock_buffer(path[level].bp_bh);
-		node = nilfs_btree_get_nonroot_node(btree, path, level);
+		node = nilfs_btree_get_nonroot_node(path, level);
 		nilfs_btree_node_delete(btree, node, keyp, ptrp,
 					path[level].bp_index);
 		if (!buffer_dirty(path[level].bp_bh))
@@ -1205,7 +1163,7 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree,
 		unlock_buffer(path[level].bp_bh);
 		if (path[level].bp_index == 0)
 			nilfs_btree_promote_key(btree, path, level + 1,
-				nilfs_btree_node_get_key(btree, node, 0));
+				nilfs_btree_node_get_key(node, 0));
 	} else {
 		node = nilfs_btree_get_root(btree);
 		nilfs_btree_node_delete(btree, node, keyp, ptrp,
@@ -1225,10 +1183,10 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_bh);
 	lock_buffer(path[level].bp_sib_bh);
 
-	node = nilfs_btree_get_nonroot_node(btree, path, level);
-	left = nilfs_btree_get_sib_node(btree, path, level);
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
-	lnchildren = nilfs_btree_node_get_nchildren(btree, left);
+	node = nilfs_btree_get_nonroot_node(path, level);
+	left = nilfs_btree_get_sib_node(path, level);
+	nchildren = nilfs_btree_node_get_nchildren(node);
+	lnchildren = nilfs_btree_node_get_nchildren(left);
 
 	n = (nchildren + lnchildren) / 2 - nchildren;
 
@@ -1243,7 +1201,7 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
 	unlock_buffer(path[level].bp_sib_bh);
 
 	nilfs_btree_promote_key(btree, path, level + 1,
-				nilfs_btree_node_get_key(btree, node, 0));
+				nilfs_btree_node_get_key(node, 0));
 
 	brelse(path[level].bp_sib_bh);
 	path[level].bp_sib_bh = NULL;
@@ -1262,10 +1220,10 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_bh);
 	lock_buffer(path[level].bp_sib_bh);
 
-	node = nilfs_btree_get_nonroot_node(btree, path, level);
-	right = nilfs_btree_get_sib_node(btree, path, level);
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
-	rnchildren = nilfs_btree_node_get_nchildren(btree, right);
+	node = nilfs_btree_get_nonroot_node(path, level);
+	right = nilfs_btree_get_sib_node(path, level);
+	nchildren = nilfs_btree_node_get_nchildren(node);
+	rnchildren = nilfs_btree_node_get_nchildren(right);
 
 	n = (nchildren + rnchildren) / 2 - nchildren;
 
@@ -1281,7 +1239,7 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
 
 	path[level + 1].bp_index++;
 	nilfs_btree_promote_key(btree, path, level + 1,
-				nilfs_btree_node_get_key(btree, right, 0));
+				nilfs_btree_node_get_key(right, 0));
 	path[level + 1].bp_index--;
 
 	brelse(path[level].bp_sib_bh);
@@ -1300,10 +1258,10 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_bh);
 	lock_buffer(path[level].bp_sib_bh);
 
-	node = nilfs_btree_get_nonroot_node(btree, path, level);
-	left = nilfs_btree_get_sib_node(btree, path, level);
+	node = nilfs_btree_get_nonroot_node(path, level);
+	left = nilfs_btree_get_sib_node(path, level);
 
-	n = nilfs_btree_node_get_nchildren(btree, node);
+	n = nilfs_btree_node_get_nchildren(node);
 
 	nilfs_btree_node_move_left(btree, left, node, n);
 
@@ -1316,7 +1274,7 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
 	nilfs_btnode_delete(path[level].bp_bh);
 	path[level].bp_bh = path[level].bp_sib_bh;
 	path[level].bp_sib_bh = NULL;
-	path[level].bp_index += nilfs_btree_node_get_nchildren(btree, left);
+	path[level].bp_index += nilfs_btree_node_get_nchildren(left);
 }
 
 static void nilfs_btree_concat_right(struct nilfs_btree *btree,
@@ -1331,10 +1289,10 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree,
 	lock_buffer(path[level].bp_bh);
 	lock_buffer(path[level].bp_sib_bh);
 
-	node = nilfs_btree_get_nonroot_node(btree, path, level);
-	right = nilfs_btree_get_sib_node(btree, path, level);
+	node = nilfs_btree_get_nonroot_node(path, level);
+	right = nilfs_btree_get_sib_node(path, level);
 
-	n = nilfs_btree_node_get_nchildren(btree, right);
+	n = nilfs_btree_node_get_nchildren(right);
 
 	nilfs_btree_node_move_left(btree, node, right, n);
 
@@ -1360,11 +1318,11 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
 
 	lock_buffer(path[level].bp_bh);
 	root = nilfs_btree_get_root(btree);
-	child = nilfs_btree_get_nonroot_node(btree, path, level);
+	child = nilfs_btree_get_nonroot_node(path, level);
 
 	nilfs_btree_node_delete(btree, root, NULL, NULL, 0);
-	nilfs_btree_node_set_level(btree, root, level);
-	n = nilfs_btree_node_get_nchildren(btree, child);
+	nilfs_btree_node_set_level(root, level);
+	n = nilfs_btree_node_get_nchildren(child);
 	nilfs_btree_node_move_left(btree, root, child, n);
 	unlock_buffer(path[level].bp_bh);
 
@@ -1376,7 +1334,8 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
 static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 				      struct nilfs_btree_path *path,
 				      int *levelp,
-				      struct nilfs_bmap_stats *stats)
+				      struct nilfs_bmap_stats *stats,
+				      struct inode *dat)
 {
 	struct buffer_head *bh;
 	struct nilfs_btree_node *node, *parent, *sib;
@@ -1388,17 +1347,17 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 	for (level = NILFS_BTREE_LEVEL_NODE_MIN;
 	     level < nilfs_btree_height(btree) - 1;
 	     level++) {
-		node = nilfs_btree_get_nonroot_node(btree, path, level);
+		node = nilfs_btree_get_nonroot_node(path, level);
 		path[level].bp_oldreq.bpr_ptr =
 			nilfs_btree_node_get_ptr(btree, node,
 						 path[level].bp_index);
 		ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
-						 &path[level].bp_oldreq);
+						 &path[level].bp_oldreq, dat);
 		if (ret < 0)
 			goto err_out_child_node;
 
-		if (nilfs_btree_node_get_nchildren(btree, node) >
-		    nilfs_btree_node_nchildren_min(btree, node)) {
+		if (nilfs_btree_node_get_nchildren(node) >
+		    nilfs_btree_node_nchildren_min(node, btree)) {
 			path[level].bp_op = nilfs_btree_do_delete;
 			stats->bs_nblocks++;
 			goto out;
@@ -1415,8 +1374,8 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 			if (ret < 0)
 				goto err_out_curr_node;
 			sib = (struct nilfs_btree_node *)bh->b_data;
-			if (nilfs_btree_node_get_nchildren(btree, sib) >
-			    nilfs_btree_node_nchildren_min(btree, sib)) {
+			if (nilfs_btree_node_get_nchildren(sib) >
+			    nilfs_btree_node_nchildren_min(sib, btree)) {
 				path[level].bp_sib_bh = bh;
 				path[level].bp_op = nilfs_btree_borrow_left;
 				stats->bs_nblocks++;
@@ -1428,7 +1387,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 				/* continue; */
 			}
 		} else if (pindex <
-			   nilfs_btree_node_get_nchildren(btree, parent) - 1) {
+			   nilfs_btree_node_get_nchildren(parent) - 1) {
 			/* right sibling */
 			sibptr = nilfs_btree_node_get_ptr(btree, parent,
 							  pindex + 1);
@@ -1436,8 +1395,8 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 			if (ret < 0)
 				goto err_out_curr_node;
 			sib = (struct nilfs_btree_node *)bh->b_data;
-			if (nilfs_btree_node_get_nchildren(btree, sib) >
-			    nilfs_btree_node_nchildren_min(btree, sib)) {
+			if (nilfs_btree_node_get_nchildren(sib) >
+			    nilfs_btree_node_nchildren_min(sib, btree)) {
 				path[level].bp_sib_bh = bh;
 				path[level].bp_op = nilfs_btree_borrow_right;
 				stats->bs_nblocks++;
@@ -1452,7 +1411,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 			/* no siblings */
 			/* the only child of the root node */
 			WARN_ON(level != nilfs_btree_height(btree) - 2);
-			if (nilfs_btree_node_get_nchildren(btree, node) - 1 <=
+			if (nilfs_btree_node_get_nchildren(node) - 1 <=
 			    NILFS_BTREE_ROOT_NCHILDREN_MAX) {
 				path[level].bp_op = nilfs_btree_shrink;
 				stats->bs_nblocks += 2;
@@ -1471,7 +1430,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 		nilfs_btree_node_get_ptr(btree, node, path[level].bp_index);
 
 	ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
-					 &path[level].bp_oldreq);
+					 &path[level].bp_oldreq, dat);
 	if (ret < 0)
 		goto err_out_child_node;
 
@@ -1486,12 +1445,12 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 
 	/* error */
  err_out_curr_node:
-	nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq);
+	nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq, dat);
  err_out_child_node:
 	for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) {
 		brelse(path[level].bp_sib_bh);
 		nilfs_bmap_abort_end_ptr(&btree->bt_bmap,
-					 &path[level].bp_oldreq);
+					 &path[level].bp_oldreq, dat);
 	}
 	*levelp = level;
 	stats->bs_nblocks = 0;
@@ -1500,13 +1459,13 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 
 static void nilfs_btree_commit_delete(struct nilfs_btree *btree,
 				      struct nilfs_btree_path *path,
-				      int maxlevel)
+				      int maxlevel, struct inode *dat)
 {
 	int level;
 
 	for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
 		nilfs_bmap_commit_end_ptr(&btree->bt_bmap,
-					  &path[level].bp_oldreq);
+					  &path[level].bp_oldreq, dat);
 		path[level].bp_op(btree, path, level, NULL, NULL);
 	}
 
@@ -1520,27 +1479,32 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
 	struct nilfs_btree *btree;
 	struct nilfs_btree_path *path;
 	struct nilfs_bmap_stats stats;
+	struct inode *dat;
 	int level, ret;
 
 	btree = (struct nilfs_btree *)bmap;
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 	ret = nilfs_btree_do_lookup(btree, path, key, NULL,
 				    NILFS_BTREE_LEVEL_NODE_MIN);
 	if (ret < 0)
 		goto out;
 
-	ret = nilfs_btree_prepare_delete(btree, path, &level, &stats);
+
+	dat = NILFS_BMAP_USE_VBN(&btree->bt_bmap) ?
+		nilfs_bmap_get_dat(&btree->bt_bmap) : NULL;
+
+	ret = nilfs_btree_prepare_delete(btree, path, &level, &stats, dat);
 	if (ret < 0)
 		goto out;
-	nilfs_btree_commit_delete(btree, path, level);
+	nilfs_btree_commit_delete(btree, path, level, dat);
 	nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
 
 out:
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 	return ret;
 }
 
@@ -1551,15 +1515,15 @@ static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
 	int ret;
 
 	btree = (struct nilfs_btree *)bmap;
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 
 	ret = nilfs_btree_do_lookup_last(btree, path, keyp, NULL);
 
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 
 	return ret;
 }
@@ -1581,7 +1545,7 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
 		node = root;
 		break;
 	case 3:
-		nchildren = nilfs_btree_node_get_nchildren(btree, root);
+		nchildren = nilfs_btree_node_get_nchildren(root);
 		if (nchildren > 1)
 			return 0;
 		ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
@@ -1594,10 +1558,10 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
 		return 0;
 	}
 
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
-	maxkey = nilfs_btree_node_get_key(btree, node, nchildren - 1);
+	nchildren = nilfs_btree_node_get_nchildren(node);
+	maxkey = nilfs_btree_node_get_key(node, nchildren - 1);
 	nextmaxkey = (nchildren > 1) ?
-		nilfs_btree_node_get_key(btree, node, nchildren - 2) : 0;
+		nilfs_btree_node_get_key(node, nchildren - 2) : 0;
 	if (bh != NULL)
 		brelse(bh);
 
@@ -1623,7 +1587,7 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
 		node = root;
 		break;
 	case 3:
-		nchildren = nilfs_btree_node_get_nchildren(btree, root);
+		nchildren = nilfs_btree_node_get_nchildren(root);
 		WARN_ON(nchildren > 1);
 		ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
 		ret = nilfs_btree_get_block(btree, ptr, &bh);
@@ -1636,11 +1600,11 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
 		return -EINVAL;
 	}
 
-	nchildren = nilfs_btree_node_get_nchildren(btree, node);
+	nchildren = nilfs_btree_node_get_nchildren(node);
 	if (nchildren < nitems)
 		nitems = nchildren;
-	dkeys = nilfs_btree_node_dkeys(btree, node);
-	dptrs = nilfs_btree_node_dptrs(btree, node);
+	dkeys = nilfs_btree_node_dkeys(node);
+	dptrs = nilfs_btree_node_dptrs(node, btree);
 	for (i = 0; i < nitems; i++) {
 		keys[i] = nilfs_bmap_dkey_to_key(dkeys[i]);
 		ptrs[i] = nilfs_bmap_dptr_to_ptr(dptrs[i]);
@@ -1660,18 +1624,20 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 				       struct nilfs_bmap_stats *stats)
 {
 	struct buffer_head *bh;
-	struct nilfs_btree *btree;
+	struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
+	struct inode *dat = NULL;
 	int ret;
 
-	btree = (struct nilfs_btree *)bmap;
 	stats->bs_nblocks = 0;
 
 	/* for data */
 	/* cannot find near ptr */
-	if (NILFS_BMAP_USE_VBN(bmap))
+	if (NILFS_BMAP_USE_VBN(bmap)) {
 		dreq->bpr_ptr = nilfs_btree_find_target_v(btree, NULL, key);
+		dat = nilfs_bmap_get_dat(bmap);
+	}
 
-	ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq);
+	ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq, dat);
 	if (ret < 0)
 		return ret;
 
@@ -1679,7 +1645,7 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 	stats->bs_nblocks++;
 	if (nreq != NULL) {
 		nreq->bpr_ptr = dreq->bpr_ptr + 1;
-		ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq);
+		ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq, dat);
 		if (ret < 0)
 			goto err_out_dreq;
 
@@ -1696,9 +1662,9 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 
 	/* error */
  err_out_nreq:
-	nilfs_bmap_abort_alloc_ptr(bmap, nreq);
+	nilfs_bmap_abort_alloc_ptr(bmap, nreq, dat);
  err_out_dreq:
-	nilfs_bmap_abort_alloc_ptr(bmap, dreq);
+	nilfs_bmap_abort_alloc_ptr(bmap, dreq, dat);
 	stats->bs_nblocks = 0;
 	return ret;
 
@@ -1713,8 +1679,9 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
 				      union nilfs_bmap_ptr_req *nreq,
 				      struct buffer_head *bh)
 {
-	struct nilfs_btree *btree;
+	struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
 	struct nilfs_btree_node *node;
+	struct inode *dat;
 	__u64 tmpptr;
 
 	/* free resources */
@@ -1725,11 +1692,11 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
 	set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
 
 	/* convert and insert */
-	btree = (struct nilfs_btree *)bmap;
+	dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
 	nilfs_btree_init(bmap);
 	if (nreq != NULL) {
-		nilfs_bmap_commit_alloc_ptr(bmap, dreq);
-		nilfs_bmap_commit_alloc_ptr(bmap, nreq);
+		nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat);
+		nilfs_bmap_commit_alloc_ptr(bmap, nreq, dat);
 
 		/* create child node at level 1 */
 		lock_buffer(bh);
@@ -1751,7 +1718,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
 		nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
 				      2, 1, &keys[0], &tmpptr);
 	} else {
-		nilfs_bmap_commit_alloc_ptr(bmap, dreq);
+		nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat);
 
 		/* create root node at level 1 */
 		node = nilfs_btree_get_root(btree);
@@ -1822,7 +1789,7 @@ static int nilfs_btree_propagate_p(struct nilfs_btree *btree,
 
 static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
 					struct nilfs_btree_path *path,
-					int level)
+					int level, struct inode *dat)
 {
 	struct nilfs_btree_node *parent;
 	int ret;
@@ -1832,9 +1799,8 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
 		nilfs_btree_node_get_ptr(btree, parent,
 					 path[level + 1].bp_index);
 	path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1;
-	ret = nilfs_bmap_prepare_update_v(&btree->bt_bmap,
-					  &path[level].bp_oldreq,
-					  &path[level].bp_newreq);
+	ret = nilfs_dat_prepare_update(dat, &path[level].bp_oldreq.bpr_req,
+				       &path[level].bp_newreq.bpr_req);
 	if (ret < 0)
 		return ret;
 
@@ -1846,9 +1812,9 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
 			&NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
 			&path[level].bp_ctxt);
 		if (ret < 0) {
-			nilfs_bmap_abort_update_v(&btree->bt_bmap,
-						  &path[level].bp_oldreq,
-						  &path[level].bp_newreq);
+			nilfs_dat_abort_update(dat,
+					       &path[level].bp_oldreq.bpr_req,
+					       &path[level].bp_newreq.bpr_req);
 			return ret;
 		}
 	}
@@ -1858,13 +1824,13 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
 
 static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
 					struct nilfs_btree_path *path,
-					int level)
+					int level, struct inode *dat)
 {
 	struct nilfs_btree_node *parent;
 
-	nilfs_bmap_commit_update_v(&btree->bt_bmap,
-				   &path[level].bp_oldreq,
-				   &path[level].bp_newreq);
+	nilfs_dat_commit_update(dat, &path[level].bp_oldreq.bpr_req,
+				&path[level].bp_newreq.bpr_req,
+				btree->bt_bmap.b_ptr_type == NILFS_BMAP_PTR_VS);
 
 	if (buffer_nilfs_node(path[level].bp_bh)) {
 		nilfs_btnode_commit_change_key(
@@ -1881,11 +1847,10 @@ static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
 
 static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
 				       struct nilfs_btree_path *path,
-				       int level)
+				       int level, struct inode *dat)
 {
-	nilfs_bmap_abort_update_v(&btree->bt_bmap,
-				  &path[level].bp_oldreq,
-				  &path[level].bp_newreq);
+	nilfs_dat_abort_update(dat, &path[level].bp_oldreq.bpr_req,
+			       &path[level].bp_newreq.bpr_req);
 	if (buffer_nilfs_node(path[level].bp_bh))
 		nilfs_btnode_abort_change_key(
 			&NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
@@ -1894,14 +1859,14 @@ static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
 
 static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
 					   struct nilfs_btree_path *path,
-					   int minlevel,
-					   int *maxlevelp)
+					   int minlevel, int *maxlevelp,
+					   struct inode *dat)
 {
 	int level, ret;
 
 	level = minlevel;
 	if (!buffer_nilfs_volatile(path[level].bp_bh)) {
-		ret = nilfs_btree_prepare_update_v(btree, path, level);
+		ret = nilfs_btree_prepare_update_v(btree, path, level, dat);
 		if (ret < 0)
 			return ret;
 	}
@@ -1909,7 +1874,7 @@ static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
 	       !buffer_dirty(path[level].bp_bh)) {
 
 		WARN_ON(buffer_nilfs_volatile(path[level].bp_bh));
-		ret = nilfs_btree_prepare_update_v(btree, path, level);
+		ret = nilfs_btree_prepare_update_v(btree, path, level, dat);
 		if (ret < 0)
 			goto out;
 	}
@@ -1921,39 +1886,40 @@ static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
 	/* error */
  out:
 	while (--level > minlevel)
-		nilfs_btree_abort_update_v(btree, path, level);
+		nilfs_btree_abort_update_v(btree, path, level, dat);
 	if (!buffer_nilfs_volatile(path[level].bp_bh))
-		nilfs_btree_abort_update_v(btree, path, level);
+		nilfs_btree_abort_update_v(btree, path, level, dat);
 	return ret;
 }
 
 static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree,
 					   struct nilfs_btree_path *path,
-					   int minlevel,
-					   int maxlevel,
-					   struct buffer_head *bh)
+					   int minlevel, int maxlevel,
+					   struct buffer_head *bh,
+					   struct inode *dat)
 {
 	int level;
 
 	if (!buffer_nilfs_volatile(path[minlevel].bp_bh))
-		nilfs_btree_commit_update_v(btree, path, minlevel);
+		nilfs_btree_commit_update_v(btree, path, minlevel, dat);
 
 	for (level = minlevel + 1; level <= maxlevel; level++)
-		nilfs_btree_commit_update_v(btree, path, level);
+		nilfs_btree_commit_update_v(btree, path, level, dat);
 }
 
 static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
 				   struct nilfs_btree_path *path,
-				   int level,
-				   struct buffer_head *bh)
+				   int level, struct buffer_head *bh)
 {
 	int maxlevel, ret;
 	struct nilfs_btree_node *parent;
+	struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
 	__u64 ptr;
 
 	get_bh(bh);
 	path[level].bp_bh = bh;
-	ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel);
+	ret = nilfs_btree_prepare_propagate_v(btree, path, level, &maxlevel,
+					      dat);
 	if (ret < 0)
 		goto out;
 
@@ -1961,12 +1927,12 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
 		parent = nilfs_btree_get_node(btree, path, level + 1);
 		ptr = nilfs_btree_node_get_ptr(btree, parent,
 					       path[level + 1].bp_index);
-		ret = nilfs_bmap_mark_dirty(&btree->bt_bmap, ptr);
+		ret = nilfs_dat_mark_dirty(dat, ptr);
 		if (ret < 0)
 			goto out;
 	}
 
-	nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh);
+	nilfs_btree_commit_propagate_v(btree, path, level, maxlevel, bh, dat);
 
  out:
 	brelse(path[level].bp_bh);
@@ -1986,15 +1952,15 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
 	WARN_ON(!buffer_dirty(bh));
 
 	btree = (struct nilfs_btree *)bmap;
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 
 	if (buffer_nilfs_node(bh)) {
 		node = (struct nilfs_btree_node *)bh->b_data;
-		key = nilfs_btree_node_get_key(btree, node, 0);
-		level = nilfs_btree_node_get_level(btree, node);
+		key = nilfs_btree_node_get_key(node, 0);
+		level = nilfs_btree_node_get_level(node);
 	} else {
 		key = nilfs_bmap_data_get_key(bmap, bh);
 		level = NILFS_BTREE_LEVEL_DATA;
@@ -2013,8 +1979,8 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
 		nilfs_btree_propagate_p(btree, path, level, bh);
 
  out:
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 
 	return ret;
 }
@@ -2022,7 +1988,7 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
 static int nilfs_btree_propagate_gc(const struct nilfs_bmap *bmap,
 				    struct buffer_head *bh)
 {
-	return nilfs_bmap_mark_dirty(bmap, bh->b_blocknr);
+	return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), bh->b_blocknr);
 }
 
 static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
@@ -2037,12 +2003,12 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
 
 	get_bh(bh);
 	node = (struct nilfs_btree_node *)bh->b_data;
-	key = nilfs_btree_node_get_key(btree, node, 0);
-	level = nilfs_btree_node_get_level(btree, node);
+	key = nilfs_btree_node_get_key(node, 0);
+	level = nilfs_btree_node_get_level(node);
 	list_for_each(head, &lists[level]) {
 		cbh = list_entry(head, struct buffer_head, b_assoc_buffers);
 		cnode = (struct nilfs_btree_node *)cbh->b_data;
-		ckey = nilfs_btree_node_get_key(btree, cnode, 0);
+		ckey = nilfs_btree_node_get_key(cnode, 0);
 		if (key < ckey)
 			break;
 	}
@@ -2120,8 +2086,7 @@ static int nilfs_btree_assign_p(struct nilfs_btree *btree,
 	nilfs_btree_node_set_ptr(btree, parent,
 				 path[level + 1].bp_index, blocknr);
 
-	key = nilfs_btree_node_get_key(btree, parent,
-				       path[level + 1].bp_index);
+	key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index);
 	/* on-disk format */
 	binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key);
 	binfo->bi_dat.bi_level = level;
@@ -2137,6 +2102,7 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
 				union nilfs_binfo *binfo)
 {
 	struct nilfs_btree_node *parent;
+	struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
 	__u64 key;
 	__u64 ptr;
 	union nilfs_bmap_ptr_req req;
@@ -2146,12 +2112,12 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
 	ptr = nilfs_btree_node_get_ptr(btree, parent,
 				       path[level + 1].bp_index);
 	req.bpr_ptr = ptr;
-	ret = nilfs_bmap_start_v(&btree->bt_bmap, &req, blocknr);
-	if (unlikely(ret < 0))
+	ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
+	if (ret < 0)
 		return ret;
+	nilfs_dat_commit_start(dat, &req.bpr_req, blocknr);
 
-	key = nilfs_btree_node_get_key(btree, parent,
-				       path[level + 1].bp_index);
+	key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index);
 	/* on-disk format */
 	binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
 	binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
@@ -2171,15 +2137,15 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
 	int level, ret;
 
 	btree = (struct nilfs_btree *)bmap;
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 
 	if (buffer_nilfs_node(*bh)) {
 		node = (struct nilfs_btree_node *)(*bh)->b_data;
-		key = nilfs_btree_node_get_key(btree, node, 0);
-		level = nilfs_btree_node_get_level(btree, node);
+		key = nilfs_btree_node_get_key(node, 0);
+		level = nilfs_btree_node_get_level(node);
 	} else {
 		key = nilfs_bmap_data_get_key(bmap, *bh);
 		level = NILFS_BTREE_LEVEL_DATA;
@@ -2196,8 +2162,8 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
 		nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo);
 
  out:
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 
 	return ret;
 }
@@ -2207,19 +2173,18 @@ static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap,
 				 sector_t blocknr,
 				 union nilfs_binfo *binfo)
 {
-	struct nilfs_btree *btree;
 	struct nilfs_btree_node *node;
 	__u64 key;
 	int ret;
 
-	btree = (struct nilfs_btree *)bmap;
-	ret = nilfs_bmap_move_v(bmap, (*bh)->b_blocknr, blocknr);
+	ret = nilfs_dat_move(nilfs_bmap_get_dat(bmap), (*bh)->b_blocknr,
+			     blocknr);
 	if (ret < 0)
 		return ret;
 
 	if (buffer_nilfs_node(*bh)) {
 		node = (struct nilfs_btree_node *)(*bh)->b_data;
-		key = nilfs_btree_node_get_key(btree, node, 0);
+		key = nilfs_btree_node_get_key(node, 0);
 	} else
 		key = nilfs_bmap_data_get_key(bmap, *bh);
 
@@ -2239,10 +2204,10 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
 	int ret;
 
 	btree = (struct nilfs_btree *)bmap;
-	path = nilfs_btree_alloc_path(btree);
+	path = nilfs_btree_alloc_path();
 	if (path == NULL)
 		return -ENOMEM;
-	nilfs_btree_init_path(btree, path);
+	nilfs_btree_init_path(path);
 
 	ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level + 1);
 	if (ret < 0) {
@@ -2262,8 +2227,8 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
 		nilfs_bmap_set_dirty(&btree->bt_bmap);
 
  out:
-	nilfs_btree_clear_path(btree, path);
-	nilfs_btree_free_path(btree, path);
+	nilfs_btree_release_path(path);
+	nilfs_btree_free_path(path);
 	return ret;
 }
 
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index aec942c..1c6cfb5 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -815,8 +815,10 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno)
 	void *kaddr;
 	int ret;
 
-	if (cno == 0)
-		return -ENOENT; /* checkpoint number 0 is invalid */
+	/* CP number is invalid if it's zero or larger than the
+	largest	exist one.*/
+	if (cno == 0 || cno >= nilfs_mdt_cno(cpfile))
+		return -ENOENT;
 	down_read(&NILFS_MDT(cpfile)->mi_sem);
 
 	ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &bh);
@@ -824,7 +826,10 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno)
 		goto out;
 	kaddr = kmap_atomic(bh->b_page, KM_USER0);
 	cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
-	ret = nilfs_checkpoint_snapshot(cp);
+	if (nilfs_checkpoint_invalid(cp))
+		ret = -ENOENT;
+	else
+		ret = nilfs_checkpoint_snapshot(cp);
 	kunmap_atomic(kaddr, KM_USER0);
 	brelse(bh);
 
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h
index 788a459..debea89 100644
--- a/fs/nilfs2/cpfile.h
+++ b/fs/nilfs2/cpfile.h
@@ -27,8 +27,6 @@
 #include <linux/buffer_head.h>
 #include <linux/nilfs2_fs.h>
 
-#define NILFS_CPFILE_GFP	NILFS_MDT_GFP
-
 
 int nilfs_cpfile_get_checkpoint(struct inode *, __u64, int,
 				struct nilfs_checkpoint **,
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 8927ca2..1ff8e15 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -109,12 +109,6 @@ void nilfs_dat_commit_free(struct inode *dat, struct nilfs_palloc_req *req)
 	nilfs_palloc_commit_free_entry(dat, req);
 }
 
-void nilfs_dat_abort_free(struct inode *dat, struct nilfs_palloc_req *req)
-{
-	nilfs_dat_abort_entry(dat, req);
-	nilfs_palloc_abort_free_entry(dat, req);
-}
-
 int nilfs_dat_prepare_start(struct inode *dat, struct nilfs_palloc_req *req)
 {
 	int ret;
@@ -140,11 +134,6 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req,
 	nilfs_dat_commit_entry(dat, req);
 }
 
-void nilfs_dat_abort_start(struct inode *dat, struct nilfs_palloc_req *req)
-{
-	nilfs_dat_abort_entry(dat, req);
-}
-
 int nilfs_dat_prepare_end(struct inode *dat, struct nilfs_palloc_req *req)
 {
 	struct nilfs_dat_entry *entry;
@@ -222,6 +211,37 @@ void nilfs_dat_abort_end(struct inode *dat, struct nilfs_palloc_req *req)
 	nilfs_dat_abort_entry(dat, req);
 }
 
+int nilfs_dat_prepare_update(struct inode *dat,
+			     struct nilfs_palloc_req *oldreq,
+			     struct nilfs_palloc_req *newreq)
+{
+	int ret;
+
+	ret = nilfs_dat_prepare_end(dat, oldreq);
+	if (!ret) {
+		ret = nilfs_dat_prepare_alloc(dat, newreq);
+		if (ret < 0)
+			nilfs_dat_abort_end(dat, oldreq);
+	}
+	return ret;
+}
+
+void nilfs_dat_commit_update(struct inode *dat,
+			     struct nilfs_palloc_req *oldreq,
+			     struct nilfs_palloc_req *newreq, int dead)
+{
+	nilfs_dat_commit_end(dat, oldreq, dead);
+	nilfs_dat_commit_alloc(dat, newreq);
+}
+
+void nilfs_dat_abort_update(struct inode *dat,
+			    struct nilfs_palloc_req *oldreq,
+			    struct nilfs_palloc_req *newreq)
+{
+	nilfs_dat_abort_end(dat, oldreq);
+	nilfs_dat_abort_alloc(dat, newreq);
+}
+
 /**
  * nilfs_dat_mark_dirty -
  * @dat: DAT file inode
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h
index d328b81..406070d 100644
--- a/fs/nilfs2/dat.h
+++ b/fs/nilfs2/dat.h
@@ -27,7 +27,6 @@
 #include <linux/buffer_head.h>
 #include <linux/fs.h>
 
-#define NILFS_DAT_GFP	NILFS_MDT_GFP
 
 struct nilfs_palloc_req;
 
@@ -39,10 +38,15 @@ void nilfs_dat_abort_alloc(struct inode *, struct nilfs_palloc_req *);
 int nilfs_dat_prepare_start(struct inode *, struct nilfs_palloc_req *);
 void nilfs_dat_commit_start(struct inode *, struct nilfs_palloc_req *,
 			    sector_t);
-void nilfs_dat_abort_start(struct inode *, struct nilfs_palloc_req *);
 int nilfs_dat_prepare_end(struct inode *, struct nilfs_palloc_req *);
 void nilfs_dat_commit_end(struct inode *, struct nilfs_palloc_req *, int);
 void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *);
+int nilfs_dat_prepare_update(struct inode *, struct nilfs_palloc_req *,
+			     struct nilfs_palloc_req *);
+void nilfs_dat_commit_update(struct inode *, struct nilfs_palloc_req *,
+			     struct nilfs_palloc_req *, int);
+void nilfs_dat_abort_update(struct inode *, struct nilfs_palloc_req *,
+			    struct nilfs_palloc_req *);
 
 int nilfs_dat_mark_dirty(struct inode *, __u64);
 int nilfs_dat_freev(struct inode *, __u64 *, size_t);
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
index 342d976..d369ac7 100644
--- a/fs/nilfs2/direct.c
+++ b/fs/nilfs2/direct.c
@@ -125,106 +125,64 @@ static void nilfs_direct_set_target_v(struct nilfs_direct *direct,
 	direct->d_bmap.b_last_allocated_ptr = ptr;
 }
 
-static int nilfs_direct_prepare_insert(struct nilfs_direct *direct,
-				       __u64 key,
-				       union nilfs_bmap_ptr_req *req,
-				       struct nilfs_bmap_stats *stats)
-{
-	int ret;
-
-	if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
-		req->bpr_ptr = nilfs_direct_find_target_v(direct, key);
-	ret = nilfs_bmap_prepare_alloc_ptr(&direct->d_bmap, req);
-	if (ret < 0)
-		return ret;
-
-	stats->bs_nblocks = 1;
-	return 0;
-}
-
-static void nilfs_direct_commit_insert(struct nilfs_direct *direct,
-				       union nilfs_bmap_ptr_req *req,
-				       __u64 key, __u64 ptr)
-{
-	struct buffer_head *bh;
-
-	/* ptr must be a pointer to a buffer head. */
-	bh = (struct buffer_head *)((unsigned long)ptr);
-	set_buffer_nilfs_volatile(bh);
-
-	nilfs_bmap_commit_alloc_ptr(&direct->d_bmap, req);
-	nilfs_direct_set_ptr(direct, key, req->bpr_ptr);
-
-	if (!nilfs_bmap_dirty(&direct->d_bmap))
-		nilfs_bmap_set_dirty(&direct->d_bmap);
-
-	if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
-		nilfs_direct_set_target_v(direct, key, req->bpr_ptr);
-}
-
 static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
 {
-	struct nilfs_direct *direct;
+	struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
 	union nilfs_bmap_ptr_req req;
-	struct nilfs_bmap_stats stats;
+	struct inode *dat = NULL;
+	struct buffer_head *bh;
 	int ret;
 
-	direct = (struct nilfs_direct *)bmap;
 	if (key > NILFS_DIRECT_KEY_MAX)
 		return -ENOENT;
 	if (nilfs_direct_get_ptr(direct, key) != NILFS_BMAP_INVALID_PTR)
 		return -EEXIST;
 
-	ret = nilfs_direct_prepare_insert(direct, key, &req, &stats);
-	if (ret < 0)
-		return ret;
-	nilfs_direct_commit_insert(direct, &req, key, ptr);
-	nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
+	if (NILFS_BMAP_USE_VBN(bmap)) {
+		req.bpr_ptr = nilfs_direct_find_target_v(direct, key);
+		dat = nilfs_bmap_get_dat(bmap);
+	}
+	ret = nilfs_bmap_prepare_alloc_ptr(bmap, &req, dat);
+	if (!ret) {
+		/* ptr must be a pointer to a buffer head. */
+		bh = (struct buffer_head *)((unsigned long)ptr);
+		set_buffer_nilfs_volatile(bh);
 
-	return 0;
-}
+		nilfs_bmap_commit_alloc_ptr(bmap, &req, dat);
+		nilfs_direct_set_ptr(direct, key, req.bpr_ptr);
 
-static int nilfs_direct_prepare_delete(struct nilfs_direct *direct,
-				       union nilfs_bmap_ptr_req *req,
-				       __u64 key,
-				       struct nilfs_bmap_stats *stats)
-{
-	int ret;
+		if (!nilfs_bmap_dirty(bmap))
+			nilfs_bmap_set_dirty(bmap);
 
-	req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
-	ret = nilfs_bmap_prepare_end_ptr(&direct->d_bmap, req);
-	if (!ret)
-		stats->bs_nblocks = 1;
-	return ret;
-}
+		if (NILFS_BMAP_USE_VBN(bmap))
+			nilfs_direct_set_target_v(direct, key, req.bpr_ptr);
 
-static void nilfs_direct_commit_delete(struct nilfs_direct *direct,
-				       union nilfs_bmap_ptr_req *req,
-				       __u64 key)
-{
-	nilfs_bmap_commit_end_ptr(&direct->d_bmap, req);
-	nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
+		nilfs_bmap_add_blocks(bmap, 1);
+	}
+	return ret;
 }
 
 static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
 {
-	struct nilfs_direct *direct;
+	struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
 	union nilfs_bmap_ptr_req req;
-	struct nilfs_bmap_stats stats;
+	struct inode *dat;
 	int ret;
 
-	direct = (struct nilfs_direct *)bmap;
-	if ((key > NILFS_DIRECT_KEY_MAX) ||
+	if (key > NILFS_DIRECT_KEY_MAX ||
 	    nilfs_direct_get_ptr(direct, key) == NILFS_BMAP_INVALID_PTR)
 		return -ENOENT;
 
-	ret = nilfs_direct_prepare_delete(direct, &req, key, &stats);
-	if (ret < 0)
-		return ret;
-	nilfs_direct_commit_delete(direct, &req, key);
-	nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
+	dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
+	req.bpr_ptr = nilfs_direct_get_ptr(direct, key);
 
-	return 0;
+	ret = nilfs_bmap_prepare_end_ptr(bmap, &req, dat);
+	if (!ret) {
+		nilfs_bmap_commit_end_ptr(bmap, &req, dat);
+		nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
+		nilfs_bmap_sub_blocks(bmap, 1);
+	}
+	return ret;
 }
 
 static int nilfs_direct_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
@@ -310,59 +268,56 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
 	return 0;
 }
 
-static int nilfs_direct_propagate_v(struct nilfs_direct *direct,
-				    struct buffer_head *bh)
+static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
+				  struct buffer_head *bh)
 {
-	union nilfs_bmap_ptr_req oldreq, newreq;
+	struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
+	struct nilfs_palloc_req oldreq, newreq;
+	struct inode *dat;
 	__u64 key;
 	__u64 ptr;
 	int ret;
 
-	key = nilfs_bmap_data_get_key(&direct->d_bmap, bh);
+	if (!NILFS_BMAP_USE_VBN(bmap))
+		return 0;
+
+	dat = nilfs_bmap_get_dat(bmap);
+	key = nilfs_bmap_data_get_key(bmap, bh);
 	ptr = nilfs_direct_get_ptr(direct, key);
 	if (!buffer_nilfs_volatile(bh)) {
-		oldreq.bpr_ptr = ptr;
-		newreq.bpr_ptr = ptr;
-		ret = nilfs_bmap_prepare_update_v(&direct->d_bmap, &oldreq,
-						  &newreq);
+		oldreq.pr_entry_nr = ptr;
+		newreq.pr_entry_nr = ptr;
+		ret = nilfs_dat_prepare_update(dat, &oldreq, &newreq);
 		if (ret < 0)
 			return ret;
-		nilfs_bmap_commit_update_v(&direct->d_bmap, &oldreq, &newreq);
+		nilfs_dat_commit_update(dat, &oldreq, &newreq,
+					bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
 		set_buffer_nilfs_volatile(bh);
-		nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr);
+		nilfs_direct_set_ptr(direct, key, newreq.pr_entry_nr);
 	} else
-		ret = nilfs_bmap_mark_dirty(&direct->d_bmap, ptr);
+		ret = nilfs_dat_mark_dirty(dat, ptr);
 
 	return ret;
 }
 
-static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
-				  struct buffer_head *bh)
-{
-	struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
-
-	return NILFS_BMAP_USE_VBN(bmap) ?
-		nilfs_direct_propagate_v(direct, bh) : 0;
-}
-
 static int nilfs_direct_assign_v(struct nilfs_direct *direct,
 				 __u64 key, __u64 ptr,
 				 struct buffer_head **bh,
 				 sector_t blocknr,
 				 union nilfs_binfo *binfo)
 {
+	struct inode *dat = nilfs_bmap_get_dat(&direct->d_bmap);
 	union nilfs_bmap_ptr_req req;
 	int ret;
 
 	req.bpr_ptr = ptr;
-	ret = nilfs_bmap_start_v(&direct->d_bmap, &req, blocknr);
-	if (unlikely(ret < 0))
-		return ret;
-
-	binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
-	binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
-
-	return 0;
+	ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
+	if (!ret) {
+		nilfs_dat_commit_start(dat, &req.bpr_req, blocknr);
+		binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
+		binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+	}
+	return ret;
 }
 
 static int nilfs_direct_assign_p(struct nilfs_direct *direct,
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h
index 5d30a35..ecc3ba7 100644
--- a/fs/nilfs2/ifile.h
+++ b/fs/nilfs2/ifile.h
@@ -31,7 +31,6 @@
 #include "mdt.h"
 #include "alloc.h"
 
-#define NILFS_IFILE_GFP  NILFS_MDT_GFP
 
 static inline struct nilfs_inode *
 nilfs_ifile_map_inode(struct inode *ifile, ino_t ino, struct buffer_head *ibh)
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index fe9d8f2..807e584 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -430,7 +430,8 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
 
 	raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh);
 
-	if (nilfs_read_inode_common(inode, raw_inode))
+	err = nilfs_read_inode_common(inode, raw_inode);
+	if (err)
 		goto failed_unmap;
 
 	if (S_ISREG(inode->i_mode)) {
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 6ea5f87..6572ea4 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -442,12 +442,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
 	const char *msg;
 	int ret;
 
-	ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]);
-	if (ret < 0) {
-		msg = "cannot read source blocks";
-		goto failed;
-	}
-
 	ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
 	if (ret < 0) {
 		/*
@@ -548,7 +542,25 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
 		}
 	}
 
-	ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+	/*
+	 * nilfs_ioctl_move_blocks() will call nilfs_gc_iget(),
+	 * which will operates an inode list without blocking.
+	 * To protect the list from concurrent operations,
+	 * nilfs_ioctl_move_blocks should be atomic operation.
+	 */
+	if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) {
+		ret = -EBUSY;
+		goto out_free;
+	}
+
+	ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]);
+	if (ret < 0)
+		printk(KERN_ERR "NILFS: GC failed during preparation: "
+			"cannot read source blocks: err=%d\n", ret);
+	else
+		ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+
+	clear_nilfs_gc_running(nilfs);
 
  out_free:
 	while (--n >= 0)
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 2dfd477..156bf60 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -103,15 +103,12 @@ static int nilfs_mdt_create_block(struct inode *inode, unsigned long block,
 		goto failed_unlock;
 
 	err = -EEXIST;
-	if (buffer_uptodate(bh) || buffer_mapped(bh))
+	if (buffer_uptodate(bh))
 		goto failed_bh;
-#if 0
-	/* The uptodate flag is not protected by the page lock, but
-	   the mapped flag is.  Thus, we don't have to wait the buffer. */
+
 	wait_on_buffer(bh);
 	if (buffer_uptodate(bh))
 		goto failed_bh;
-#endif
 
 	bh->b_bdev = nilfs->ns_bdev;
 	err = nilfs_mdt_insert_new_block(inode, block, bh, init_block);
@@ -139,7 +136,7 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
 		       int mode, struct buffer_head **out_bh)
 {
 	struct buffer_head *bh;
-	unsigned long blknum = 0;
+	__u64 blknum = 0;
 	int ret = -ENOMEM;
 
 	bh = nilfs_grab_buffer(inode, inode->i_mapping, blkoff, 0);
@@ -162,17 +159,15 @@ nilfs_mdt_submit_block(struct inode *inode, unsigned long blkoff,
 		unlock_buffer(bh);
 		goto out;
 	}
-	if (!buffer_mapped(bh)) { /* unused buffer */
-		ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff,
-					&blknum);
-		if (unlikely(ret)) {
-			unlock_buffer(bh);
-			goto failed_bh;
-		}
-		bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev;
-		bh->b_blocknr = blknum;
-		set_buffer_mapped(bh);
+
+	ret = nilfs_bmap_lookup(NILFS_I(inode)->i_bmap, blkoff, &blknum);
+	if (unlikely(ret)) {
+		unlock_buffer(bh);
+		goto failed_bh;
 	}
+	bh->b_bdev = NILFS_MDT(inode)->mi_nilfs->ns_bdev;
+	bh->b_blocknr = (sector_t)blknum;
+	set_buffer_mapped(bh);
 
 	bh->b_end_io = end_buffer_read_sync;
 	get_bh(bh);
@@ -402,6 +397,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
 	struct inode *inode = container_of(page->mapping,
 					   struct inode, i_data);
 	struct super_block *sb = inode->i_sb;
+	struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs;
 	struct nilfs_sb_info *writer = NULL;
 	int err = 0;
 
@@ -411,9 +407,10 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
 	if (page->mapping->assoc_mapping)
 		return 0; /* Do not request flush for shadow page cache */
 	if (!sb) {
-		writer = nilfs_get_writer(NILFS_MDT(inode)->mi_nilfs);
+		down_read(&nilfs->ns_writer_sem);
+		writer = nilfs->ns_writer;
 		if (!writer) {
-			nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs);
+			up_read(&nilfs->ns_writer_sem);
 			return -EROFS;
 		}
 		sb = writer->s_super;
@@ -425,7 +422,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
 		nilfs_flush_segment(sb, inode->i_ino);
 
 	if (writer)
-		nilfs_put_writer(NILFS_MDT(inode)->mi_nilfs);
+		up_read(&nilfs->ns_writer_sem);
 	return err;
 }
 
@@ -516,9 +513,10 @@ nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
 }
 
 struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb,
-			    ino_t ino, gfp_t gfp_mask)
+			    ino_t ino)
 {
-	struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino, gfp_mask);
+	struct inode *inode = nilfs_mdt_new_common(nilfs, sb, ino,
+						   NILFS_MDT_GFP);
 
 	if (!inode)
 		return NULL;
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h
index df683e0..4315997 100644
--- a/fs/nilfs2/mdt.h
+++ b/fs/nilfs2/mdt.h
@@ -74,8 +74,7 @@ int nilfs_mdt_forget_block(struct inode *, unsigned long);
 int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);
 int nilfs_mdt_fetch_dirty(struct inode *);
 
-struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t,
-			    gfp_t);
+struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t);
 struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *,
 				   ino_t, gfp_t);
 void nilfs_mdt_destroy(struct inode *);
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index d80cc71..6dc8359 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -552,7 +552,8 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
 		printk(KERN_WARNING
 		       "NILFS warning: error recovering data block "
 		       "(err=%d, ino=%lu, block-offset=%llu)\n",
-		       err, rb->ino, (unsigned long long)rb->blkoff);
+		       err, (unsigned long)rb->ino,
+		       (unsigned long long)rb->blkoff);
 		if (!err2)
 			err2 = err;
  next:
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 9e3fe17..e6d9e37 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -316,10 +316,10 @@ static struct bio *nilfs_alloc_seg_bio(struct super_block *sb, sector_t start,
 {
 	struct bio *bio;
 
-	bio = bio_alloc(GFP_NOWAIT, nr_vecs);
+	bio = bio_alloc(GFP_NOIO, nr_vecs);
 	if (bio == NULL) {
 		while (!bio && (nr_vecs >>= 1))
-			bio = bio_alloc(GFP_NOWAIT, nr_vecs);
+			bio = bio_alloc(GFP_NOIO, nr_vecs);
 	}
 	if (likely(bio)) {
 		bio->bi_bdev = sb->s_bdev;
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 51ff3d0..683df89 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2501,7 +2501,8 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci,
 		if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
 		    nilfs_discontinued(nilfs)) {
 			down_write(&nilfs->ns_sem);
-			req->sb_err = nilfs_commit_super(sbi, 0);
+			req->sb_err = nilfs_commit_super(sbi,
+					nilfs_altsb_need_update(nilfs));
 			up_write(&nilfs->ns_sem);
 		}
 	}
@@ -2689,6 +2690,7 @@ static int nilfs_segctor_thread(void *arg)
 	} else {
 		DEFINE_WAIT(wait);
 		int should_sleep = 1;
+		struct the_nilfs *nilfs;
 
 		prepare_to_wait(&sci->sc_wait_daemon, &wait,
 				TASK_INTERRUPTIBLE);
@@ -2709,6 +2711,9 @@ static int nilfs_segctor_thread(void *arg)
 		finish_wait(&sci->sc_wait_daemon, &wait);
 		timeout = ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
 			   time_after_eq(jiffies, sci->sc_timer->expires));
+		nilfs = sci->sc_sbi->s_nilfs;
+		if (sci->sc_super->s_dirt && nilfs_sb_need_update(nilfs))
+			set_nilfs_discontinued(nilfs);
 	}
 	goto loop;
 
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
index a2c4d76..0e99e5c 100644
--- a/fs/nilfs2/sufile.h
+++ b/fs/nilfs2/sufile.h
@@ -28,7 +28,6 @@
 #include <linux/nilfs2_fs.h>
 #include "mdt.h"
 
-#define NILFS_SUFILE_GFP	NILFS_MDT_GFP
 
 static inline unsigned long nilfs_sufile_get_nsegments(struct inode *sufile)
 {
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 151964f..55f3d6b 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -50,6 +50,8 @@
 #include <linux/writeback.h>
 #include <linux/kobject.h>
 #include <linux/exportfs.h>
+#include <linux/seq_file.h>
+#include <linux/mount.h>
 #include "nilfs.h"
 #include "mdt.h"
 #include "alloc.h"
@@ -65,7 +67,6 @@ MODULE_DESCRIPTION("A New Implementation of the Log-structured Filesystem "
 		   "(NILFS)");
 MODULE_LICENSE("GPL");
 
-static void nilfs_write_super(struct super_block *sb);
 static int nilfs_remount(struct super_block *sb, int *flags, char *data);
 
 /**
@@ -311,9 +312,6 @@ static void nilfs_put_super(struct super_block *sb)
 
 	lock_kernel();
 
-	if (sb->s_dirt)
-		nilfs_write_super(sb);
-
 	nilfs_detach_segment_constructor(sbi);
 
 	if (!(sb->s_flags & MS_RDONLY)) {
@@ -336,63 +334,21 @@ static void nilfs_put_super(struct super_block *sb)
 	unlock_kernel();
 }
 
-/**
- * nilfs_write_super - write super block(s) of NILFS
- * @sb: super_block
- *
- * nilfs_write_super() gets a fs-dependent lock, writes super block(s), and
- * clears s_dirt.  This function is called in the section protected by
- * lock_super().
- *
- * The s_dirt flag is managed by each filesystem and we protect it by ns_sem
- * of the struct the_nilfs.  Lock order must be as follows:
- *
- *   1. lock_super()
- *   2.    down_write(&nilfs->ns_sem)
- *
- * Inside NILFS, locking ns_sem is enough to protect s_dirt and the buffer
- * of the super block (nilfs->ns_sbp[]).
- *
- * In most cases, VFS functions call lock_super() before calling these
- * methods.  So we must be careful not to bring on deadlocks when using
- * lock_super();  see generic_shutdown_super(), write_super(), and so on.
- *
- * Note that order of lock_kernel() and lock_super() depends on contexts
- * of VFS.  We should also note that lock_kernel() can be used in its
- * protective section and only the outermost one has an effect.
- */
-static void nilfs_write_super(struct super_block *sb)
+static int nilfs_sync_fs(struct super_block *sb, int wait)
 {
 	struct nilfs_sb_info *sbi = NILFS_SB(sb);
 	struct the_nilfs *nilfs = sbi->s_nilfs;
-
-	down_write(&nilfs->ns_sem);
-	if (!(sb->s_flags & MS_RDONLY)) {
-		struct nilfs_super_block **sbp = nilfs->ns_sbp;
-		u64 t = get_seconds();
-		int dupsb;
-
-		if (!nilfs_discontinued(nilfs) && t >= nilfs->ns_sbwtime[0] &&
-		    t < nilfs->ns_sbwtime[0] + NILFS_SB_FREQ) {
-			up_write(&nilfs->ns_sem);
-			return;
-		}
-		dupsb = sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
-		nilfs_commit_super(sbi, dupsb);
-	}
-	sb->s_dirt = 0;
-	up_write(&nilfs->ns_sem);
-}
-
-static int nilfs_sync_fs(struct super_block *sb, int wait)
-{
 	int err = 0;
 
-	nilfs_write_super(sb);
-
 	/* This function is called when super block should be written back */
 	if (wait)
 		err = nilfs_construct_segment(sb);
+
+	down_write(&nilfs->ns_sem);
+	if (sb->s_dirt)
+		nilfs_commit_super(sbi, 1);
+	up_write(&nilfs->ns_sem);
+
 	return err;
 }
 
@@ -407,8 +363,7 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno)
 	list_add(&sbi->s_list, &nilfs->ns_supers);
 	up_write(&nilfs->ns_super_sem);
 
-	sbi->s_ifile = nilfs_mdt_new(
-		nilfs, sbi->s_super, NILFS_IFILE_INO, NILFS_IFILE_GFP);
+	sbi->s_ifile = nilfs_mdt_new(nilfs, sbi->s_super, NILFS_IFILE_INO);
 	if (!sbi->s_ifile)
 		return -ENOMEM;
 
@@ -529,6 +484,26 @@ static int nilfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 	return 0;
 }
 
+static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+	struct super_block *sb = vfs->mnt_sb;
+	struct nilfs_sb_info *sbi = NILFS_SB(sb);
+
+	if (!nilfs_test_opt(sbi, BARRIER))
+		seq_printf(seq, ",barrier=off");
+	if (nilfs_test_opt(sbi, SNAPSHOT))
+		seq_printf(seq, ",cp=%llu",
+			   (unsigned long long int)sbi->s_snapshot_cno);
+	if (nilfs_test_opt(sbi, ERRORS_RO))
+		seq_printf(seq, ",errors=remount-ro");
+	if (nilfs_test_opt(sbi, ERRORS_PANIC))
+		seq_printf(seq, ",errors=panic");
+	if (nilfs_test_opt(sbi, STRICT_ORDER))
+		seq_printf(seq, ",order=strict");
+
+	return 0;
+}
+
 static struct super_operations nilfs_sops = {
 	.alloc_inode    = nilfs_alloc_inode,
 	.destroy_inode  = nilfs_destroy_inode,
@@ -538,7 +513,7 @@ static struct super_operations nilfs_sops = {
 	/* .drop_inode	  = nilfs_drop_inode, */
 	.delete_inode   = nilfs_delete_inode,
 	.put_super      = nilfs_put_super,
-	.write_super    = nilfs_write_super,
+	/* .write_super    = nilfs_write_super, */
 	.sync_fs        = nilfs_sync_fs,
 	/* .write_super_lockfs */
 	/* .unlockfs */
@@ -546,7 +521,7 @@ static struct super_operations nilfs_sops = {
 	.remount_fs     = nilfs_remount,
 	.clear_inode    = nilfs_clear_inode,
 	/* .umount_begin */
-	/* .show_options */
+	.show_options = nilfs_show_options
 };
 
 static struct inode *
@@ -816,10 +791,15 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
 
 	if (sb->s_flags & MS_RDONLY) {
 		if (nilfs_test_opt(sbi, SNAPSHOT)) {
+			down_read(&nilfs->ns_segctor_sem);
 			err = nilfs_cpfile_is_snapshot(nilfs->ns_cpfile,
 						       sbi->s_snapshot_cno);
-			if (err < 0)
+			up_read(&nilfs->ns_segctor_sem);
+			if (err < 0) {
+				if (err == -ENOENT)
+					err = -EINVAL;
 				goto failed_sbi;
+			}
 			if (!err) {
 				printk(KERN_ERR
 				       "NILFS: The specified checkpoint is "
@@ -1127,10 +1107,6 @@ nilfs_get_sb(struct file_system_type *fs_type, int flags,
 	 */
 	sd.sbi = nilfs_find_sbinfo(nilfs, !(flags & MS_RDONLY), sd.cno);
 
-	if (!sd.cno)
-		/* trying to get the latest checkpoint.  */
-		sd.cno = nilfs_last_cno(nilfs);
-
 	/*
 	 * Get super block instance holding the nilfs_sb_info struct.
 	 * A new instance is allocated if no existing mount is present or
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 8b88898..ad391a8 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -68,12 +68,11 @@ static struct the_nilfs *alloc_nilfs(struct block_device *bdev)
 
 	nilfs->ns_bdev = bdev;
 	atomic_set(&nilfs->ns_count, 1);
-	atomic_set(&nilfs->ns_writer_refcount, -1);
 	atomic_set(&nilfs->ns_ndirtyblks, 0);
 	init_rwsem(&nilfs->ns_sem);
 	init_rwsem(&nilfs->ns_super_sem);
 	mutex_init(&nilfs->ns_mount_mutex);
-	mutex_init(&nilfs->ns_writer_mutex);
+	init_rwsem(&nilfs->ns_writer_sem);
 	INIT_LIST_HEAD(&nilfs->ns_list);
 	INIT_LIST_HEAD(&nilfs->ns_supers);
 	spin_lock_init(&nilfs->ns_last_segment_lock);
@@ -188,23 +187,19 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
 	inode_size = nilfs->ns_inode_size;
 
 	err = -ENOMEM;
-	nilfs->ns_dat = nilfs_mdt_new(
-		nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP);
+	nilfs->ns_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO);
 	if (unlikely(!nilfs->ns_dat))
 		goto failed;
 
-	nilfs->ns_gc_dat = nilfs_mdt_new(
-		nilfs, NULL, NILFS_DAT_INO, NILFS_DAT_GFP);
+	nilfs->ns_gc_dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO);
 	if (unlikely(!nilfs->ns_gc_dat))
 		goto failed_dat;
 
-	nilfs->ns_cpfile = nilfs_mdt_new(
-		nilfs, NULL, NILFS_CPFILE_INO, NILFS_CPFILE_GFP);
+	nilfs->ns_cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO);
 	if (unlikely(!nilfs->ns_cpfile))
 		goto failed_gc_dat;
 
-	nilfs->ns_sufile = nilfs_mdt_new(
-		nilfs, NULL, NILFS_SUFILE_INO, NILFS_SUFILE_GFP);
+	nilfs->ns_sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO);
 	if (unlikely(!nilfs->ns_sufile))
 		goto failed_cpfile;
 
@@ -596,9 +591,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
 
 	nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
 
-	bdi = nilfs->ns_bdev->bd_inode_backing_dev_info;
-	if (!bdi)
-		bdi = nilfs->ns_bdev->bd_inode->i_mapping->backing_dev_info;
+	bdi = nilfs->ns_bdev->bd_inode->i_mapping->backing_dev_info;
 	nilfs->ns_bdi = bdi ? : &default_backing_dev_info;
 
 	/* Finding last segment */
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 1b9caaf..20abd55 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -37,6 +37,7 @@ enum {
 	THE_NILFS_LOADED,       /* Roll-back/roll-forward has done and
 				   the latest checkpoint was loaded */
 	THE_NILFS_DISCONTINUED,	/* 'next' pointer chain has broken */
+	THE_NILFS_GC_RUNNING,	/* gc process is running */
 };
 
 /**
@@ -50,8 +51,7 @@ enum {
  * @ns_sem: semaphore for shared states
  * @ns_super_sem: semaphore for global operations across super block instances
  * @ns_mount_mutex: mutex protecting mount process of nilfs
- * @ns_writer_mutex: mutex protecting ns_writer attach/detach
- * @ns_writer_refcount: number of referrers on ns_writer
+ * @ns_writer_sem: semaphore protecting ns_writer attach/detach
  * @ns_current: back pointer to current mount
  * @ns_sbh: buffer heads of on-disk super blocks
  * @ns_sbp: pointers to super block data
@@ -100,8 +100,7 @@ struct the_nilfs {
 	struct rw_semaphore	ns_sem;
 	struct rw_semaphore	ns_super_sem;
 	struct mutex		ns_mount_mutex;
-	struct mutex		ns_writer_mutex;
-	atomic_t		ns_writer_refcount;
+	struct rw_semaphore	ns_writer_sem;
 
 	/*
 	 * components protected by ns_super_sem
@@ -197,11 +196,26 @@ static inline int nilfs_##name(struct the_nilfs *nilfs)			\
 THE_NILFS_FNS(INIT, init)
 THE_NILFS_FNS(LOADED, loaded)
 THE_NILFS_FNS(DISCONTINUED, discontinued)
+THE_NILFS_FNS(GC_RUNNING, gc_running)
 
 /* Minimum interval of periodical update of superblocks (in seconds) */
 #define NILFS_SB_FREQ		10
 #define NILFS_ALTSB_FREQ	60  /* spare superblock */
 
+static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
+{
+	u64 t = get_seconds();
+	return t < nilfs->ns_sbwtime[0] ||
+		 t > nilfs->ns_sbwtime[0] + NILFS_SB_FREQ;
+}
+
+static inline int nilfs_altsb_need_update(struct the_nilfs *nilfs)
+{
+	u64 t = get_seconds();
+	struct nilfs_super_block **sbp = nilfs->ns_sbp;
+	return sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
+}
+
 void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
 struct the_nilfs *find_or_create_nilfs(struct block_device *);
 void put_nilfs(struct the_nilfs *);
@@ -221,34 +235,21 @@ static inline void get_nilfs(struct the_nilfs *nilfs)
 	atomic_inc(&nilfs->ns_count);
 }
 
-static inline struct nilfs_sb_info *nilfs_get_writer(struct the_nilfs *nilfs)
-{
-	if (atomic_inc_and_test(&nilfs->ns_writer_refcount))
-		mutex_lock(&nilfs->ns_writer_mutex);
-	return nilfs->ns_writer;
-}
-
-static inline void nilfs_put_writer(struct the_nilfs *nilfs)
-{
-	if (atomic_add_negative(-1, &nilfs->ns_writer_refcount))
-		mutex_unlock(&nilfs->ns_writer_mutex);
-}
-
 static inline void
 nilfs_attach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
 {
-	mutex_lock(&nilfs->ns_writer_mutex);
+	down_write(&nilfs->ns_writer_sem);
 	nilfs->ns_writer = sbi;
-	mutex_unlock(&nilfs->ns_writer_mutex);
+	up_write(&nilfs->ns_writer_sem);
 }
 
 static inline void
 nilfs_detach_writer(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
 {
-	mutex_lock(&nilfs->ns_writer_mutex);
+	down_write(&nilfs->ns_writer_sem);
 	if (sbi == nilfs->ns_writer)
 		nilfs->ns_writer = NULL;
-	mutex_unlock(&nilfs->ns_writer_mutex);
+	up_write(&nilfs->ns_writer_sem);
 }
 
 static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi)
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 3140a44..4350d49 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2076,14 +2076,6 @@ err_out:
 	*ppos = pos;
 	if (cached_page)
 		page_cache_release(cached_page);
-	/* For now, when the user asks for O_SYNC, we actually give O_DSYNC. */
-	if (likely(!status)) {
-		if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(vi))) {
-			if (!mapping->a_ops->writepage || !is_sync_kiocb(iocb))
-				status = generic_osync_inode(vi, mapping,
-						OSYNC_METADATA|OSYNC_DATA);
-		}
-  	}
 	pagevec_lru_add_file(&lru_pvec);
 	ntfs_debug("Done.  Returning %s (written 0x%lx, status %li).",
 			written ? "written" : "status", (unsigned long)written,
@@ -2145,8 +2137,8 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	mutex_lock(&inode->i_mutex);
 	ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
-	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-		int err = sync_page_range(inode, mapping, pos, ret);
+	if (ret > 0) {
+		int err = generic_write_sync(file, pos, ret);
 		if (err < 0)
 			ret = err;
 	}
@@ -2173,8 +2165,8 @@ static ssize_t ntfs_file_writev(struct file *file, const struct iovec *iov,
 	if (ret == -EIOCBQUEUED)
 		ret = wait_on_sync_kiocb(&kiocb);
 	mutex_unlock(&inode->i_mutex);
-	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-		int err = sync_page_range(inode, mapping, *ppos - ret, ret);
+	if (ret > 0) {
+		int err = generic_write_sync(file, *ppos - ret, ret);
 		if (err < 0)
 			ret = err;
 	}
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 23bf684..1caa0ef 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -384,13 +384,12 @@ unm_err_out:
  * it is dirty in the inode meta data rather than the data page cache of the
  * inode, and thus there are no data pages that need writing out.  Therefore, a
  * full mark_inode_dirty() is overkill.  A mark_inode_dirty_sync(), on the
- * other hand, is not sufficient, because I_DIRTY_DATASYNC needs to be set to
- * ensure ->write_inode is called from generic_osync_inode() and this needs to
- * happen or the file data would not necessarily hit the device synchronously,
- * even though the vfs inode has the O_SYNC flag set.  Also, I_DIRTY_DATASYNC
- * simply "feels" better than just I_DIRTY_SYNC, since the file data has not
- * actually hit the block device yet, which is not what I_DIRTY_SYNC on its own
- * would suggest.
+ * other hand, is not sufficient, because ->write_inode needs to be called even
+ * in case of fdatasync. This needs to happen or the file data would not
+ * necessarily hit the device synchronously, even though the vfs inode has the
+ * O_SYNC flag set.  Also, I_DIRTY_DATASYNC simply "feels" better than just
+ * I_DIRTY_SYNC, since the file data has not actually hit the block device yet,
+ * which is not what I_DIRTY_SYNC on its own would suggest.
  */
 void __mark_mft_record_dirty(ntfs_inode *ni)
 {
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index aa501d3..221c5e9 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1871,8 +1871,7 @@ relock:
 			goto out_dio;
 		}
 	} else {
-		written = generic_file_aio_write_nolock(iocb, iov, nr_segs,
-							*ppos);
+		written = __generic_file_aio_write(iocb, iov, nr_segs, ppos);
 	}
 
 out_dio:
@@ -1880,18 +1879,21 @@ out_dio:
 	BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
 
 	if ((file->f_flags & O_SYNC && !direct_io) || IS_SYNC(inode)) {
-		/*
-		 * The generic write paths have handled getting data
-		 * to disk, but since we don't make use of the dirty
-		 * inode list, a manual journal commit is necessary
-		 * here.
-		 */
-		if (old_size != i_size_read(inode) ||
-		    old_clusters != OCFS2_I(inode)->ip_clusters) {
+		ret = filemap_fdatawrite_range(file->f_mapping, pos,
+					       pos + count - 1);
+		if (ret < 0)
+			written = ret;
+
+		if (!ret && (old_size != i_size_read(inode) ||
+		    old_clusters != OCFS2_I(inode)->ip_clusters)) {
 			ret = jbd2_journal_force_commit(osb->journal->j_journal);
 			if (ret < 0)
 				written = ret;
 		}
+
+		if (!ret)
+			ret = filemap_fdatawait_range(file->f_mapping, pos,
+						      pos + count - 1);
 	}
 
 	/* 
@@ -1991,31 +1993,16 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
 
 	if (ret > 0) {
 		unsigned long nr_pages;
+		int err;
 
-		*ppos += ret;
 		nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
-		/*
-		 * If file or inode is SYNC and we actually wrote some data,
-		 * sync it.
-		 */
-		if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
-			int err;
-
-			mutex_lock(&inode->i_mutex);
-			err = ocfs2_rw_lock(inode, 1);
-			if (err < 0) {
-				mlog_errno(err);
-			} else {
-				err = generic_osync_inode(inode, mapping,
-						  OSYNC_METADATA|OSYNC_DATA);
-				ocfs2_rw_unlock(inode, 1);
-			}
-			mutex_unlock(&inode->i_mutex);
+		err = generic_write_sync(out, *ppos, ret);
+		if (err)
+			ret = err;
+		else
+			*ppos += ret;
 
-			if (err)
-				ret = err;
-		}
 		balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
 	}
 
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index ea4e6cb..fbeaddf 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -248,11 +248,19 @@ ssize_t part_stat_show(struct device *dev,
 		part_stat_read(p, merges[WRITE]),
 		(unsigned long long)part_stat_read(p, sectors[WRITE]),
 		jiffies_to_msecs(part_stat_read(p, ticks[WRITE])),
-		p->in_flight,
+		part_in_flight(p),
 		jiffies_to_msecs(part_stat_read(p, io_ticks)),
 		jiffies_to_msecs(part_stat_read(p, time_in_queue)));
 }
 
+ssize_t part_inflight_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct hd_struct *p = dev_to_part(dev);
+
+	return sprintf(buf, "%8u %8u\n", p->in_flight[0], p->in_flight[1]);
+}
+
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 ssize_t part_fail_show(struct device *dev,
 		       struct device_attribute *attr, char *buf)
@@ -281,6 +289,7 @@ static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
 static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
 static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL);
 static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
+static DEVICE_ATTR(inflight, S_IRUGO, part_inflight_show, NULL);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 static struct device_attribute dev_attr_fail =
 	__ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
@@ -292,6 +301,7 @@ static struct attribute *part_attrs[] = {
 	&dev_attr_size.attr,
 	&dev_attr_alignment_offset.attr,
 	&dev_attr_stat.attr,
+	&dev_attr_inflight.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 	&dev_attr_fail.attr,
 #endif
@@ -302,7 +312,7 @@ static struct attribute_group part_attr_group = {
 	.attrs = part_attrs,
 };
 
-static struct attribute_group *part_attr_groups[] = {
+static const struct attribute_group *part_attr_groups[] = {
 	&part_attr_group,
 #ifdef CONFIG_BLK_DEV_IO_TRACE
 	&blk_trace_attr_group,
diff --git a/fs/splice.c b/fs/splice.c
index 73766d2..7394e9e 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -502,8 +502,10 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
 		len = left;
 
 	ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
-	if (ret > 0)
+	if (ret > 0) {
 		*ppos += ret;
+		file_accessed(in);
+	}
 
 	return ret;
 }
@@ -963,8 +965,10 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 
 		mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
 		ret = file_remove_suid(out);
-		if (!ret)
+		if (!ret) {
+			file_update_time(out);
 			ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file);
+		}
 		mutex_unlock(&inode->i_mutex);
 	} while (ret > 0);
 	splice_from_pipe_end(pipe, &sd);
@@ -976,25 +980,15 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
 
 	if (ret > 0) {
 		unsigned long nr_pages;
+		int err;
 
-		*ppos += ret;
 		nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
-		/*
-		 * If file or inode is SYNC and we actually wrote some data,
-		 * sync it.
-		 */
-		if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
-			int err;
-
-			mutex_lock(&inode->i_mutex);
-			err = generic_osync_inode(inode, mapping,
-						  OSYNC_METADATA|OSYNC_DATA);
-			mutex_unlock(&inode->i_mutex);
-
-			if (err)
-				ret = err;
-		}
+		err = generic_write_sync(out, *ppos, ret);
+		if (err)
+			ret = err;
+		else
+			*ppos += ret;
 		balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
 	}
 
diff --git a/fs/super.c b/fs/super.c
index 9cda337..b03fea8 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -707,6 +707,12 @@ static int set_bdev_super(struct super_block *s, void *data)
 {
 	s->s_bdev = data;
 	s->s_dev = s->s_bdev->bd_dev;
+
+	/*
+	 * We set the bdi here to the queue backing, file systems can
+	 * overwrite this in ->fill_super()
+	 */
+	s->s_bdi = &bdev_get_queue(s->s_bdev)->backing_dev_info;
 	return 0;
 }
 
diff --git a/fs/sync.c b/fs/sync.c
index 103cc7f..c08467a 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -27,6 +27,13 @@
  */
 static int __sync_filesystem(struct super_block *sb, int wait)
 {
+	/*
+	 * This should be safe, as we require bdi backing to actually
+	 * write out data in the first place
+	 */
+	if (!sb->s_bdi)
+		return 0;
+
 	/* Avoid doing twice syncing and cache pruning for quota sync */
 	if (!wait) {
 		writeout_quota_sb(sb, -1);
@@ -101,7 +108,7 @@ restart:
 		spin_unlock(&sb_lock);
 
 		down_read(&sb->s_umount);
-		if (!(sb->s_flags & MS_RDONLY) && sb->s_root)
+		if (!(sb->s_flags & MS_RDONLY) && sb->s_root && sb->s_bdi)
 			__sync_filesystem(sb, wait);
 		up_read(&sb->s_umount);
 
@@ -178,19 +185,23 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync)
 }
 
 /**
- * vfs_fsync - perform a fsync or fdatasync on a file
+ * vfs_fsync_range - helper to sync a range of data & metadata to disk
  * @file:		file to sync
  * @dentry:		dentry of @file
- * @data:		only perform a fdatasync operation
+ * @start:		offset in bytes of the beginning of data range to sync
+ * @end:		offset in bytes of the end of data range (inclusive)
+ * @datasync:		perform only datasync
  *
- * Write back data and metadata for @file to disk.  If @datasync is
- * set only metadata needed to access modified file data is written.
+ * Write back data in range @start..@end and metadata for @file to disk.  If
+ * @datasync is set only metadata needed to access modified file data is
+ * written.
  *
  * In case this function is called from nfsd @file may be %NULL and
  * only @dentry is set.  This can only happen when the filesystem
  * implements the export_operations API.
  */
-int vfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+int vfs_fsync_range(struct file *file, struct dentry *dentry, loff_t start,
+		    loff_t end, int datasync)
 {
 	const struct file_operations *fop;
 	struct address_space *mapping;
@@ -214,7 +225,7 @@ int vfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 		goto out;
 	}
 
-	ret = filemap_fdatawrite(mapping);
+	ret = filemap_write_and_wait_range(mapping, start, end);
 
 	/*
 	 * We need to protect against concurrent writers, which could cause
@@ -225,12 +236,29 @@ int vfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 	if (!ret)
 		ret = err;
 	mutex_unlock(&mapping->host->i_mutex);
-	err = filemap_fdatawait(mapping);
-	if (!ret)
-		ret = err;
+
 out:
 	return ret;
 }
+EXPORT_SYMBOL(vfs_fsync_range);
+
+/**
+ * vfs_fsync - perform a fsync or fdatasync on a file
+ * @file:		file to sync
+ * @dentry:		dentry of @file
+ * @datasync:		only perform a fdatasync operation
+ *
+ * Write back data and metadata for @file to disk.  If @datasync is
+ * set only metadata needed to access modified file data is written.
+ *
+ * In case this function is called from nfsd @file may be %NULL and
+ * only @dentry is set.  This can only happen when the filesystem
+ * implements the export_operations API.
+ */
+int vfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+	return vfs_fsync_range(file, dentry, 0, LLONG_MAX, datasync);
+}
 EXPORT_SYMBOL(vfs_fsync);
 
 static int do_fsync(unsigned int fd, int datasync)
@@ -256,6 +284,23 @@ SYSCALL_DEFINE1(fdatasync, unsigned int, fd)
 	return do_fsync(fd, 1);
 }
 
+/**
+ * generic_write_sync - perform syncing after a write if file / inode is sync
+ * @file:	file to which the write happened
+ * @pos:	offset where the write started
+ * @count:	length of the write
+ *
+ * This is just a simple wrapper about our general syncing function.
+ */
+int generic_write_sync(struct file *file, loff_t pos, loff_t count)
+{
+	if (!(file->f_flags & O_SYNC) && !IS_SYNC(file->f_mapping->host))
+		return 0;
+	return vfs_fsync_range(file, file->f_path.dentry, pos,
+			       pos + count - 1, 1);
+}
+EXPORT_SYMBOL(generic_write_sync);
+
 /*
  * sys_sync_file_range() permits finely controlled syncing over a segment of
  * a file in the range offset .. (offset+nbytes-1) inclusive.  If nbytes is
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 1c8991b..076ca50 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -54,29 +54,15 @@
  * @nr_to_write: how many dirty pages to write-back
  *
  * This function shrinks UBIFS liability by means of writing back some amount
- * of dirty inodes and their pages. Returns the amount of pages which were
- * written back. The returned value does not include dirty inodes which were
- * synchronized.
+ * of dirty inodes and their pages.
  *
  * Note, this function synchronizes even VFS inodes which are locked
  * (@i_mutex) by the caller of the budgeting function, because write-back does
  * not touch @i_mutex.
  */
-static int shrink_liability(struct ubifs_info *c, int nr_to_write)
+static void shrink_liability(struct ubifs_info *c, int nr_to_write)
 {
-	int nr_written;
-
-	nr_written = writeback_inodes_sb(c->vfs_sb);
-	if (!nr_written) {
-		/*
-		 * Re-try again but wait on pages/inodes which are being
-		 * written-back concurrently (e.g., by pdflush).
-		 */
-		nr_written = sync_inodes_sb(c->vfs_sb);
-	}
-
-	dbg_budg("%d pages were written back", nr_written);
-	return nr_written;
+	writeback_inodes_sb(c->vfs_sb);
 }
 
 /**
@@ -729,7 +715,7 @@ long long ubifs_get_free_space_nolock(struct ubifs_info *c)
  * ubifs_get_free_space - return amount of free space.
  * @c: UBIFS file-system description object
  *
- * This function calculates and retuns amount of free space to report to
+ * This function calculates and returns amount of free space to report to
  * user-space.
  */
 long long ubifs_get_free_space(struct ubifs_info *c)
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index f3a7945..4775af4 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -510,7 +510,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
 	int lnum, offs, len, err = 0, uninitialized_var(last_level), child_cnt;
 	int first = 1, iip;
 	struct ubifs_debug_info *d = c->dbg;
-	union ubifs_key lower_key, upper_key, l_key, u_key;
+	union ubifs_key uninitialized_var(lower_key), upper_key, l_key, u_key;
 	unsigned long long uninitialized_var(last_sqnum);
 	struct ubifs_idx_node *idx;
 	struct list_head list;
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index ce2cd83..dbc093a 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -210,6 +210,20 @@ const char *dbg_cstate(int cmt_state)
 	}
 }
 
+const char *dbg_jhead(int jhead)
+{
+	switch (jhead) {
+	case GCHD:
+		return "0 (GC)";
+	case BASEHD:
+		return "1 (base)";
+	case DATAHD:
+		return "2 (data)";
+	default:
+		return "unknown journal head";
+	}
+}
+
 static void dump_ch(const struct ubifs_ch *ch)
 {
 	printk(KERN_DEBUG "\tmagic          %#x\n", le32_to_cpu(ch->magic));
@@ -623,8 +637,9 @@ void dbg_dump_budg(struct ubifs_info *c)
 	/* If we are in R/O mode, journal heads do not exist */
 	if (c->jheads)
 		for (i = 0; i < c->jhead_cnt; i++)
-			printk(KERN_DEBUG "\tjhead %d\t LEB %d\n",
-			       c->jheads[i].wbuf.jhead, c->jheads[i].wbuf.lnum);
+			printk(KERN_DEBUG "\tjhead %s\t LEB %d\n",
+			       dbg_jhead(c->jheads[i].wbuf.jhead),
+			       c->jheads[i].wbuf.lnum);
 	for (rb = rb_first(&c->buds); rb; rb = rb_next(rb)) {
 		bud = rb_entry(rb, struct ubifs_bud, rb);
 		printk(KERN_DEBUG "\tbud LEB %d\n", bud->lnum);
@@ -648,9 +663,90 @@ void dbg_dump_budg(struct ubifs_info *c)
 
 void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp)
 {
-	printk(KERN_DEBUG "LEB %d lprops: free %d, dirty %d (used %d), "
-	       "flags %#x\n", lp->lnum, lp->free, lp->dirty,
-	       c->leb_size - lp->free - lp->dirty, lp->flags);
+	int i, spc, dark = 0, dead = 0;
+	struct rb_node *rb;
+	struct ubifs_bud *bud;
+
+	spc = lp->free + lp->dirty;
+	if (spc < c->dead_wm)
+		dead = spc;
+	else
+		dark = ubifs_calc_dark(c, spc);
+
+	if (lp->flags & LPROPS_INDEX)
+		printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d "
+		       "free + dirty %-8d flags %#x (", lp->lnum, lp->free,
+		       lp->dirty, c->leb_size - spc, spc, lp->flags);
+	else
+		printk(KERN_DEBUG "LEB %-7d free %-8d dirty %-8d used %-8d "
+		       "free + dirty %-8d dark %-4d dead %-4d nodes fit %-3d "
+		       "flags %#-4x (", lp->lnum, lp->free, lp->dirty,
+		       c->leb_size - spc, spc, dark, dead,
+		       (int)(spc / UBIFS_MAX_NODE_SZ), lp->flags);
+
+	if (lp->flags & LPROPS_TAKEN) {
+		if (lp->flags & LPROPS_INDEX)
+			printk(KERN_CONT "index, taken");
+		else
+			printk(KERN_CONT "taken");
+	} else {
+		const char *s;
+
+		if (lp->flags & LPROPS_INDEX) {
+			switch (lp->flags & LPROPS_CAT_MASK) {
+			case LPROPS_DIRTY_IDX:
+				s = "dirty index";
+				break;
+			case LPROPS_FRDI_IDX:
+				s = "freeable index";
+				break;
+			default:
+				s = "index";
+			}
+		} else {
+			switch (lp->flags & LPROPS_CAT_MASK) {
+			case LPROPS_UNCAT:
+				s = "not categorized";
+				break;
+			case LPROPS_DIRTY:
+				s = "dirty";
+				break;
+			case LPROPS_FREE:
+				s = "free";
+				break;
+			case LPROPS_EMPTY:
+				s = "empty";
+				break;
+			case LPROPS_FREEABLE:
+				s = "freeable";
+				break;
+			default:
+				s = NULL;
+				break;
+			}
+		}
+		printk(KERN_CONT "%s", s);
+	}
+
+	for (rb = rb_first((struct rb_root *)&c->buds); rb; rb = rb_next(rb)) {
+		bud = rb_entry(rb, struct ubifs_bud, rb);
+		if (bud->lnum == lp->lnum) {
+			int head = 0;
+			for (i = 0; i < c->jhead_cnt; i++) {
+				if (lp->lnum == c->jheads[i].wbuf.lnum) {
+					printk(KERN_CONT ", jhead %s",
+					       dbg_jhead(i));
+					head = 1;
+				}
+			}
+			if (!head)
+				printk(KERN_CONT ", bud of jhead %s",
+				       dbg_jhead(bud->jhead));
+		}
+	}
+	if (lp->lnum == c->gc_lnum)
+		printk(KERN_CONT ", GC LEB");
+	printk(KERN_CONT ")\n");
 }
 
 void dbg_dump_lprops(struct ubifs_info *c)
@@ -724,7 +820,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
 
 	printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
 	       current->pid, lnum);
-	sleb = ubifs_scan(c, lnum, 0, c->dbg->buf);
+	sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0);
 	if (IS_ERR(sleb)) {
 		ubifs_err("scan error %d", (int)PTR_ERR(sleb));
 		return;
@@ -909,8 +1005,10 @@ out:
 	ubifs_msg("saved lprops statistics dump");
 	dbg_dump_lstats(&d->saved_lst);
 	ubifs_get_lp_stats(c, &lst);
+
 	ubifs_msg("current lprops statistics dump");
-	dbg_dump_lstats(&d->saved_lst);
+	dbg_dump_lstats(&lst);
+
 	spin_lock(&c->space_lock);
 	dbg_dump_budg(c);
 	spin_unlock(&c->space_lock);
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index c1cd73b..29d9601 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -271,6 +271,7 @@ void ubifs_debugging_exit(struct ubifs_info *c);
 /* Dump functions */
 const char *dbg_ntype(int type);
 const char *dbg_cstate(int cmt_state);
+const char *dbg_jhead(int jhead);
 const char *dbg_get_key_dump(const struct ubifs_info *c,
 			     const union ubifs_key *key);
 void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode);
@@ -321,6 +322,8 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
 int dbg_check_lprops(struct ubifs_info *c);
 int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
 			int row, int col);
+int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
+			 loff_t size);
 
 /* Force the use of in-the-gaps method for testing */
 
@@ -425,6 +428,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
 
 #define dbg_ntype(type)                        ""
 #define dbg_cstate(cmt_state)                  ""
+#define dbg_jhead(jhead)                       ""
 #define dbg_get_key_dump(c, key)               ({})
 #define dbg_dump_inode(c, inode)               ({})
 #define dbg_dump_node(c, node)                 ({})
@@ -460,6 +464,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
 #define dbg_check_heap(c, heap, cat, add_pos)      ({})
 #define dbg_check_lprops(c)                        0
 #define dbg_check_lpt_nodes(c, cnode, row, col)    0
+#define dbg_check_inode_size(c, inode, size)       0
 #define dbg_force_in_the_gaps_enabled              0
 #define dbg_force_in_the_gaps()                    0
 #define dbg_failure_mode                           0
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 6d34dc7..2e6481a 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -21,34 +21,32 @@
  */
 
 /*
- * This file implements VFS file and inode operations of regular files, device
+ * This file implements VFS file and inode operations for regular files, device
  * nodes and symlinks as well as address space operations.
  *
- * UBIFS uses 2 page flags: PG_private and PG_checked. PG_private is set if the
- * page is dirty and is used for budgeting purposes - dirty pages should not be
- * budgeted. The PG_checked flag is set if full budgeting is required for the
- * page e.g., when it corresponds to a file hole or it is just beyond the file
- * size. The budgeting is done in 'ubifs_write_begin()', because it is OK to
- * fail in this function, and the budget is released in 'ubifs_write_end()'. So
- * the PG_private and PG_checked flags carry the information about how the page
- * was budgeted, to make it possible to release the budget properly.
+ * UBIFS uses 2 page flags: @PG_private and @PG_checked. @PG_private is set if
+ * the page is dirty and is used for optimization purposes - dirty pages are
+ * not budgeted so the flag shows that 'ubifs_write_end()' should not release
+ * the budget for this page. The @PG_checked flag is set if full budgeting is
+ * required for the page e.g., when it corresponds to a file hole or it is
+ * beyond the file size. The budgeting is done in 'ubifs_write_begin()', because
+ * it is OK to fail in this function, and the budget is released in
+ * 'ubifs_write_end()'. So the @PG_private and @PG_checked flags carry
+ * information about how the page was budgeted, to make it possible to release
+ * the budget properly.
  *
- * A thing to keep in mind: inode's 'i_mutex' is locked in most VFS operations
- * we implement. However, this is not true for '->writepage()', which might be
- * called with 'i_mutex' unlocked. For example, when pdflush is performing
- * write-back, it calls 'writepage()' with unlocked 'i_mutex', although the
- * inode has 'I_LOCK' flag in this case. At "normal" work-paths 'i_mutex' is
- * locked in '->writepage', e.g. in "sys_write -> alloc_pages -> direct reclaim
- * path'. So, in '->writepage()' we are only guaranteed that the page is
- * locked.
+ * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we
+ * implement. However, this is not true for 'ubifs_writepage()', which may be
+ * called with @i_mutex unlocked. For example, when pdflush is doing background
+ * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal"
+ * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the
+ * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()'
+ * we are only guaranteed that the page is locked.
  *
- * Similarly, 'i_mutex' does not have to be locked in readpage(), e.g.,
- * readahead path does not have it locked ("sys_read -> generic_file_aio_read
- * -> ondemand_readahead -> readpage"). In case of readahead, 'I_LOCK' flag is
- * not set as well. However, UBIFS disables readahead.
- *
- * This, for example means that there might be 2 concurrent '->writepage()'
- * calls for the same inode, but different inode dirty pages.
+ * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the
+ * read-ahead path does not lock it ("sys_read -> generic_file_aio_read ->
+ * ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not
+ * set as well. However, UBIFS disables readahead.
  */
 
 #include "ubifs.h"
@@ -449,9 +447,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 			/*
 			 * We change whole page so no need to load it. But we
 			 * have to set the @PG_checked flag to make the further
-			 * code the page is new. This might be not true, but it
-			 * is better to budget more that to read the page from
-			 * the media.
+			 * code know that the page is new. This might be not
+			 * true, but it is better to budget more than to read
+			 * the page from the media.
 			 */
 			SetPageChecked(page);
 			skipped_read = 1;
@@ -497,8 +495,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping,
 	}
 
 	/*
-	 * Whee, we aquired budgeting quickly - without involving
-	 * garbage-collection, committing or forceing write-back. We return
+	 * Whee, we acquired budgeting quickly - without involving
+	 * garbage-collection, committing or forcing write-back. We return
 	 * with @ui->ui_mutex locked if we are appending pages, and unlocked
 	 * otherwise. This is an optimization (slightly hacky though).
 	 */
@@ -562,7 +560,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping,
 
 		/*
 		 * Return 0 to force VFS to repeat the whole operation, or the
-		 * error code if 'do_readpage()' failes.
+		 * error code if 'do_readpage()' fails.
 		 */
 		copied = do_readpage(page);
 		goto out;
@@ -1175,11 +1173,11 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
 	ui->ui_size = inode->i_size;
 	/* Truncation changes inode [mc]time */
 	inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
-	/* The other attributes may be changed at the same time as well */
+	/* Other attributes may be changed at the same time as well */
 	do_attr_changes(inode, attr);
-
 	err = ubifs_jnl_truncate(c, inode, old_size, new_size);
 	mutex_unlock(&ui->ui_mutex);
+
 out_budg:
 	if (budgeted)
 		ubifs_release_budget(c, &req);
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index f0f5f15..618c270 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -529,7 +529,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
 	 * We scan the entire LEB even though we only really need to scan up to
 	 * (c->leb_size - lp->free).
 	 */
-	sleb = ubifs_scan(c, lnum, 0, c->sbuf);
+	sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0);
 	if (IS_ERR(sleb))
 		return PTR_ERR(sleb);
 
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 762a7d6..e589fed 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -297,7 +297,7 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer)
 {
 	struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer);
 
-	dbg_io("jhead %d", wbuf->jhead);
+	dbg_io("jhead %s", dbg_jhead(wbuf->jhead));
 	wbuf->need_sync = 1;
 	wbuf->c->need_wbuf_sync = 1;
 	ubifs_wake_up_bgt(wbuf->c);
@@ -314,7 +314,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf)
 
 	if (wbuf->no_timer)
 		return;
-	dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead,
+	dbg_io("set timer for jhead %s, %llu-%llu millisecs",
+	       dbg_jhead(wbuf->jhead),
 	       div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC),
 	       div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta,
 		       USEC_PER_SEC));
@@ -351,8 +352,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
 		/* Write-buffer is empty or not seeked */
 		return 0;
 
-	dbg_io("LEB %d:%d, %d bytes, jhead %d",
-	       wbuf->lnum, wbuf->offs, wbuf->used, wbuf->jhead);
+	dbg_io("LEB %d:%d, %d bytes, jhead %s",
+	       wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead));
 	ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY));
 	ubifs_assert(!(wbuf->avail & 7));
 	ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size);
@@ -401,7 +402,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
 {
 	const struct ubifs_info *c = wbuf->c;
 
-	dbg_io("LEB %d:%d, jhead %d", lnum, offs, wbuf->jhead);
+	dbg_io("LEB %d:%d, jhead %s", lnum, offs, dbg_jhead(wbuf->jhead));
 	ubifs_assert(lnum >= 0 && lnum < c->leb_cnt);
 	ubifs_assert(offs >= 0 && offs <= c->leb_size);
 	ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7));
@@ -508,9 +509,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
 	struct ubifs_info *c = wbuf->c;
 	int err, written, n, aligned_len = ALIGN(len, 8), offs;
 
-	dbg_io("%d bytes (%s) to jhead %d wbuf at LEB %d:%d", len,
-	       dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->jhead,
-	       wbuf->lnum, wbuf->offs + wbuf->used);
+	dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len,
+	       dbg_ntype(((struct ubifs_ch *)buf)->node_type),
+	       dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs + wbuf->used);
 	ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt);
 	ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0);
 	ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size);
@@ -535,8 +536,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
 		memcpy(wbuf->buf + wbuf->used, buf, len);
 
 		if (aligned_len == wbuf->avail) {
-			dbg_io("flush jhead %d wbuf to LEB %d:%d",
-			       wbuf->jhead, wbuf->lnum, wbuf->offs);
+			dbg_io("flush jhead %s wbuf to LEB %d:%d",
+			       dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
 			err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf,
 					    wbuf->offs, c->min_io_size,
 					    wbuf->dtype);
@@ -564,8 +565,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
 	 * minimal I/O unit. We have to fill and flush write-buffer and switch
 	 * to the next min. I/O unit.
 	 */
-	dbg_io("flush jhead %d wbuf to LEB %d:%d",
-	       wbuf->jhead, wbuf->lnum, wbuf->offs);
+	dbg_io("flush jhead %s wbuf to LEB %d:%d",
+	       dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
 	memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail);
 	err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs,
 			    c->min_io_size, wbuf->dtype);
@@ -698,8 +699,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
 	int err, rlen, overlap;
 	struct ubifs_ch *ch = buf;
 
-	dbg_io("LEB %d:%d, %s, length %d, jhead %d", lnum, offs,
-	       dbg_ntype(type), len, wbuf->jhead);
+	dbg_io("LEB %d:%d, %s, length %d, jhead %s", lnum, offs,
+	       dbg_ntype(type), len, dbg_jhead(wbuf->jhead));
 	ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
 	ubifs_assert(!(offs & 7) && offs < c->leb_size);
 	ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index 64b5f3a..d321bae 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -158,7 +158,7 @@ again:
 	 * some. But the write-buffer mutex has to be unlocked because
 	 * GC also takes it.
 	 */
-	dbg_jnl("no free space  jhead %d, run GC", jhead);
+	dbg_jnl("no free space in jhead %s, run GC", dbg_jhead(jhead));
 	mutex_unlock(&wbuf->io_mutex);
 
 	lnum = ubifs_garbage_collect(c, 0);
@@ -173,7 +173,8 @@ again:
 		 * because we dropped @wbuf->io_mutex, so try once
 		 * again.
 		 */
-		dbg_jnl("GC couldn't make a free LEB for jhead %d", jhead);
+		dbg_jnl("GC couldn't make a free LEB for jhead %s",
+			dbg_jhead(jhead));
 		if (retries++ < 2) {
 			dbg_jnl("retry (%d)", retries);
 			goto again;
@@ -184,7 +185,7 @@ again:
 	}
 
 	mutex_lock_nested(&wbuf->io_mutex, wbuf->jhead);
-	dbg_jnl("got LEB %d for jhead %d", lnum, jhead);
+	dbg_jnl("got LEB %d for jhead %s", lnum, dbg_jhead(jhead));
 	avail = c->leb_size - wbuf->offs - wbuf->used;
 
 	if (wbuf->lnum != -1 && avail >= len) {
@@ -255,7 +256,8 @@ static int write_node(struct ubifs_info *c, int jhead, void *node, int len,
 	*lnum = c->jheads[jhead].wbuf.lnum;
 	*offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;
 
-	dbg_jnl("jhead %d, LEB %d:%d, len %d", jhead, *lnum, *offs, len);
+	dbg_jnl("jhead %s, LEB %d:%d, len %d",
+		dbg_jhead(jhead), *lnum, *offs, len);
 	ubifs_prepare_node(c, node, len, 0);
 
 	return ubifs_wbuf_write_nolock(wbuf, node, len);
@@ -285,7 +287,8 @@ static int write_head(struct ubifs_info *c, int jhead, void *buf, int len,
 
 	*lnum = c->jheads[jhead].wbuf.lnum;
 	*offs = c->jheads[jhead].wbuf.offs + c->jheads[jhead].wbuf.used;
-	dbg_jnl("jhead %d, LEB %d:%d, len %d", jhead, *lnum, *offs, len);
+	dbg_jnl("jhead %s, LEB %d:%d, len %d",
+		dbg_jhead(jhead), *lnum, *offs, len);
 
 	err = ubifs_wbuf_write_nolock(wbuf, buf, len);
 	if (err)
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h
index 5fa27ea..0f530c6 100644
--- a/fs/ubifs/key.h
+++ b/fs/ubifs/key.h
@@ -229,23 +229,6 @@ static inline void xent_key_init(const struct ubifs_info *c,
 }
 
 /**
- * xent_key_init_hash - initialize extended attribute entry key without
- *                      re-calculating hash function.
- * @c: UBIFS file-system description object
- * @key: key to initialize
- * @inum: host inode number
- * @hash: extended attribute entry name hash
- */
-static inline void xent_key_init_hash(const struct ubifs_info *c,
-				      union ubifs_key *key, ino_t inum,
-				      uint32_t hash)
-{
-	ubifs_assert(!(hash & ~UBIFS_S_KEY_HASH_MASK));
-	key->u32[0] = inum;
-	key->u32[1] = hash | (UBIFS_XENT_KEY << UBIFS_S_KEY_HASH_BITS);
-}
-
-/**
  * xent_key_init_flash - initialize on-flash extended attribute entry key.
  * @c: UBIFS file-system description object
  * @k: key to initialize
@@ -295,22 +278,15 @@ static inline void data_key_init(const struct ubifs_info *c,
 }
 
 /**
- * data_key_init_flash - initialize on-flash data key.
+ * highest_data_key - get the highest possible data key for an inode.
  * @c: UBIFS file-system description object
- * @k: key to initialize
+ * @key: key to initialize
  * @inum: inode number
- * @block: block number
  */
-static inline void data_key_init_flash(const struct ubifs_info *c, void *k,
-				       ino_t inum, unsigned int block)
+static inline void highest_data_key(const struct ubifs_info *c,
+				   union ubifs_key *key, ino_t inum)
 {
-	union ubifs_key *key = k;
-
-	ubifs_assert(!(block & ~UBIFS_S_KEY_BLOCK_MASK));
-	key->j32[0] = cpu_to_le32(inum);
-	key->j32[1] = cpu_to_le32(block |
-				  (UBIFS_DATA_KEY << UBIFS_S_KEY_BLOCK_BITS));
-	memset(k + 8, 0, UBIFS_MAX_KEY_LEN - 8);
+	data_key_init(c, key, inum, UBIFS_S_KEY_BLOCK_MASK);
 }
 
 /**
@@ -554,4 +530,5 @@ static inline unsigned long long key_max_inode_size(const struct ubifs_info *c)
 		return 0;
 	}
 }
+
 #endif /* !__UBIFS_KEY_H__ */
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index 56e3377..c345e12 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -169,8 +169,8 @@ void ubifs_add_bud(struct ubifs_info *c, struct ubifs_bud *bud)
 	 */
 	c->bud_bytes += c->leb_size - bud->start;
 
-	dbg_log("LEB %d:%d, jhead %d, bud_bytes %lld", bud->lnum,
-		bud->start, bud->jhead, c->bud_bytes);
+	dbg_log("LEB %d:%d, jhead %s, bud_bytes %lld", bud->lnum,
+		bud->start, dbg_jhead(bud->jhead), c->bud_bytes);
 	spin_unlock(&c->buds_lock);
 }
 
@@ -355,16 +355,16 @@ static void remove_buds(struct ubifs_info *c)
 			 * heads (non-closed buds).
 			 */
 			c->cmt_bud_bytes += wbuf->offs - bud->start;
-			dbg_log("preserve %d:%d, jhead %d, bud bytes %d, "
+			dbg_log("preserve %d:%d, jhead %s, bud bytes %d, "
 				"cmt_bud_bytes %lld", bud->lnum, bud->start,
-				bud->jhead, wbuf->offs - bud->start,
+				dbg_jhead(bud->jhead), wbuf->offs - bud->start,
 				c->cmt_bud_bytes);
 			bud->start = wbuf->offs;
 		} else {
 			c->cmt_bud_bytes += c->leb_size - bud->start;
-			dbg_log("remove %d:%d, jhead %d, bud bytes %d, "
+			dbg_log("remove %d:%d, jhead %s, bud bytes %d, "
 				"cmt_bud_bytes %lld", bud->lnum, bud->start,
-				bud->jhead, c->leb_size - bud->start,
+				dbg_jhead(bud->jhead), c->leb_size - bud->start,
 				c->cmt_bud_bytes);
 			rb_erase(p1, &c->buds);
 			/*
@@ -429,7 +429,8 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum)
 		if (lnum == -1 || offs == c->leb_size)
 			continue;
 
-		dbg_log("add ref to LEB %d:%d for jhead %d", lnum, offs, i);
+		dbg_log("add ref to LEB %d:%d for jhead %s",
+			lnum, offs, dbg_jhead(i));
 		ref = buf + len;
 		ref->ch.node_type = UBIFS_REF_NODE;
 		ref->lnum = cpu_to_le32(lnum);
@@ -695,7 +696,7 @@ int ubifs_consolidate_log(struct ubifs_info *c)
 	lnum = c->ltail_lnum;
 	write_lnum = lnum;
 	while (1) {
-		sleb = ubifs_scan(c, lnum, 0, c->sbuf);
+		sleb = ubifs_scan(c, lnum, 0, c->sbuf, 0);
 		if (IS_ERR(sleb)) {
 			err = PTR_ERR(sleb);
 			goto out_free;
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index 4cdd284..4d4ca38 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -281,7 +281,7 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
 	case LPROPS_FREE:
 		if (add_to_lpt_heap(c, lprops, cat))
 			break;
-		/* No more room on heap so make it uncategorized */
+		/* No more room on heap so make it un-categorized */
 		cat = LPROPS_UNCAT;
 		/* Fall through */
 	case LPROPS_UNCAT:
@@ -375,8 +375,8 @@ void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops,
  * @lprops: LEB properties
  *
  * A LEB may have fallen off of the bottom of a heap, and ended up as
- * uncategorized even though it has enough space for us now. If that is the case
- * this function will put the LEB back onto a heap.
+ * un-categorized even though it has enough space for us now. If that is the
+ * case this function will put the LEB back onto a heap.
  */
 void ubifs_ensure_cat(struct ubifs_info *c, struct ubifs_lprops *lprops)
 {
@@ -436,10 +436,10 @@ int ubifs_categorize_lprops(const struct ubifs_info *c,
 /**
  * change_category - change LEB properties category.
  * @c: UBIFS file-system description object
- * @lprops: LEB properties to recategorize
+ * @lprops: LEB properties to re-categorize
  *
  * LEB properties are categorized to enable fast find operations. When the LEB
- * properties change they must be recategorized.
+ * properties change they must be re-categorized.
  */
 static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops)
 {
@@ -461,21 +461,18 @@ static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops)
 }
 
 /**
- * calc_dark - calculate LEB dark space size.
+ * ubifs_calc_dark - calculate LEB dark space size.
  * @c: the UBIFS file-system description object
  * @spc: amount of free and dirty space in the LEB
  *
- * This function calculates amount of dark space in an LEB which has @spc bytes
- * of free and dirty space. Returns the calculations result.
+ * This function calculates and returns amount of dark space in an LEB which
+ * has @spc bytes of free and dirty space.
  *
- * Dark space is the space which is not always usable - it depends on which
- * nodes are written in which order. E.g., if an LEB has only 512 free bytes,
- * it is dark space, because it cannot fit a large data node. So UBIFS cannot
- * count on this LEB and treat these 512 bytes as usable because it is not true
- * if, for example, only big chunks of uncompressible data will be written to
- * the FS.
+ * UBIFS is trying to account the space which might not be usable, and this
+ * space is called "dark space". For example, if an LEB has only %512 free
+ * bytes, it is dark space, because it cannot fit a large data node.
  */
-static int calc_dark(struct ubifs_info *c, int spc)
+int ubifs_calc_dark(const struct ubifs_info *c, int spc)
 {
 	ubifs_assert(!(spc & 7));
 
@@ -518,7 +515,7 @@ static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops)
  * @free: new free space amount
  * @dirty: new dirty space amount
  * @flags: new flags
- * @idx_gc_cnt: change to the count of idx_gc list
+ * @idx_gc_cnt: change to the count of @idx_gc list
  *
  * This function changes LEB properties (@free, @dirty or @flag). However, the
  * property which has the %LPROPS_NC value is not changed. Returns a pointer to
@@ -535,7 +532,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
 {
 	/*
 	 * This is the only function that is allowed to change lprops, so we
-	 * discard the const qualifier.
+	 * discard the "const" qualifier.
 	 */
 	struct ubifs_lprops *lprops = (struct ubifs_lprops *)lp;
 
@@ -575,7 +572,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
 		if (old_spc < c->dead_wm)
 			c->lst.total_dead -= old_spc;
 		else
-			c->lst.total_dark -= calc_dark(c, old_spc);
+			c->lst.total_dark -= ubifs_calc_dark(c, old_spc);
 
 		c->lst.total_used -= c->leb_size - old_spc;
 	}
@@ -616,7 +613,7 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
 		if (new_spc < c->dead_wm)
 			c->lst.total_dead += new_spc;
 		else
-			c->lst.total_dark += calc_dark(c, new_spc);
+			c->lst.total_dark += ubifs_calc_dark(c, new_spc);
 
 		c->lst.total_used += c->leb_size - new_spc;
 	}
@@ -1096,7 +1093,7 @@ static int scan_check_cb(struct ubifs_info *c,
 		}
 	}
 
-	sleb = ubifs_scan(c, lnum, 0, c->dbg->buf);
+	sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0);
 	if (IS_ERR(sleb)) {
 		/*
 		 * After an unclean unmount, empty and freeable LEBs
@@ -1107,7 +1104,7 @@ static int scan_check_cb(struct ubifs_info *c,
 				  "- continuing checking");
 			lst->empty_lebs += 1;
 			lst->total_free += c->leb_size;
-			lst->total_dark += calc_dark(c, c->leb_size);
+			lst->total_dark += ubifs_calc_dark(c, c->leb_size);
 			return LPT_SCAN_CONTINUE;
 		}
 
@@ -1117,7 +1114,7 @@ static int scan_check_cb(struct ubifs_info *c,
 				  "- continuing checking");
 			lst->total_free  += lp->free;
 			lst->total_dirty += lp->dirty;
-			lst->total_dark  +=  calc_dark(c, c->leb_size);
+			lst->total_dark  +=  ubifs_calc_dark(c, c->leb_size);
 			return LPT_SCAN_CONTINUE;
 		}
 		data->err = PTR_ERR(sleb);
@@ -1235,7 +1232,7 @@ static int scan_check_cb(struct ubifs_info *c,
 		if (spc < c->dead_wm)
 			lst->total_dead += spc;
 		else
-			lst->total_dark += calc_dark(c, spc);
+			lst->total_dark += ubifs_calc_dark(c, spc);
 	}
 
 	ubifs_scan_destroy(sleb);
diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c
index a88f338..28beaee 100644
--- a/fs/ubifs/master.c
+++ b/fs/ubifs/master.c
@@ -29,7 +29,8 @@
  * @c: UBIFS file-system description object
  *
  * This function scans the master node LEBs and search for the latest master
- * node. Returns zero in case of success and a negative error code in case of
+ * node. Returns zero in case of success, %-EUCLEAN if there master area is
+ * corrupted and requires recovery, and a negative error code in case of
  * failure.
  */
 static int scan_for_master(struct ubifs_info *c)
@@ -40,7 +41,7 @@ static int scan_for_master(struct ubifs_info *c)
 
 	lnum = UBIFS_MST_LNUM;
 
-	sleb = ubifs_scan(c, lnum, 0, c->sbuf);
+	sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
 	if (IS_ERR(sleb))
 		return PTR_ERR(sleb);
 	nodes_cnt = sleb->nodes_cnt;
@@ -48,7 +49,7 @@ static int scan_for_master(struct ubifs_info *c)
 		snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node,
 				  list);
 		if (snod->type != UBIFS_MST_NODE)
-			goto out;
+			goto out_dump;
 		memcpy(c->mst_node, snod->node, snod->len);
 		offs = snod->offs;
 	}
@@ -56,7 +57,7 @@ static int scan_for_master(struct ubifs_info *c)
 
 	lnum += 1;
 
-	sleb = ubifs_scan(c, lnum, 0, c->sbuf);
+	sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
 	if (IS_ERR(sleb))
 		return PTR_ERR(sleb);
 	if (sleb->nodes_cnt != nodes_cnt)
@@ -65,7 +66,7 @@ static int scan_for_master(struct ubifs_info *c)
 		goto out;
 	snod = list_entry(sleb->nodes.prev, struct ubifs_scan_node, list);
 	if (snod->type != UBIFS_MST_NODE)
-		goto out;
+		goto out_dump;
 	if (snod->offs != offs)
 		goto out;
 	if (memcmp((void *)c->mst_node + UBIFS_CH_SZ,
@@ -78,6 +79,12 @@ static int scan_for_master(struct ubifs_info *c)
 
 out:
 	ubifs_scan_destroy(sleb);
+	return -EUCLEAN;
+
+out_dump:
+	ubifs_err("unexpected node type %d master LEB %d:%d",
+		  snod->type, lnum, snod->offs);
+	ubifs_scan_destroy(sleb);
 	return -EINVAL;
 }
 
@@ -256,7 +263,8 @@ int ubifs_read_master(struct ubifs_info *c)
 
 	err = scan_for_master(c);
 	if (err) {
-		err = ubifs_recover_master_node(c);
+		if (err == -EUCLEAN)
+			err = ubifs_recover_master_node(c);
 		if (err)
 			/*
 			 * Note, we do not free 'c->mst_node' here because the
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index 152a7b3..82009c7 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -670,9 +670,10 @@ static int kill_orphans(struct ubifs_info *c)
 		struct ubifs_scan_leb *sleb;
 
 		dbg_rcvry("LEB %d", lnum);
-		sleb = ubifs_scan(c, lnum, 0, c->sbuf);
+		sleb = ubifs_scan(c, lnum, 0, c->sbuf, 1);
 		if (IS_ERR(sleb)) {
-			sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0);
+			if (PTR_ERR(sleb) == -EUCLEAN)
+				sleb = ubifs_recover_leb(c, lnum, 0, c->sbuf, 0);
 			if (IS_ERR(sleb)) {
 				err = PTR_ERR(sleb);
 				break;
@@ -899,7 +900,7 @@ static int dbg_scan_orphans(struct ubifs_info *c, struct check_info *ci)
 	for (lnum = c->orph_first; lnum <= c->orph_last; lnum++) {
 		struct ubifs_scan_leb *sleb;
 
-		sleb = ubifs_scan(c, lnum, 0, c->dbg->buf);
+		sleb = ubifs_scan(c, lnum, 0, c->dbg->buf, 0);
 		if (IS_ERR(sleb)) {
 			err = PTR_ERR(sleb);
 			break;
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index e5f6cf8..f94ddf7 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -286,7 +286,7 @@ int ubifs_recover_master_node(struct ubifs_info *c)
 		mst = mst2;
 	}
 
-	dbg_rcvry("recovered master node from LEB %d",
+	ubifs_msg("recovered master node from LEB %d",
 		  (mst == mst1 ? UBIFS_MST_LNUM : UBIFS_MST_LNUM + 1));
 
 	memcpy(c->mst_node, mst, UBIFS_MST_NODE_SZ);
@@ -790,7 +790,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
 		 * We can only recover at the end of the log, so check that the
 		 * next log LEB is empty or out of date.
 		 */
-		sleb = ubifs_scan(c, next_lnum, 0, sbuf);
+		sleb = ubifs_scan(c, next_lnum, 0, sbuf, 0);
 		if (IS_ERR(sleb))
 			return sleb;
 		if (sleb->nodes_cnt) {
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 2970500..5c2d6d7 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -506,7 +506,7 @@ static int replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead,
 	if (c->need_recovery)
 		sleb = ubifs_recover_leb(c, lnum, offs, c->sbuf, jhead != GCHD);
 	else
-		sleb = ubifs_scan(c, lnum, offs, c->sbuf);
+		sleb = ubifs_scan(c, lnum, offs, c->sbuf, 0);
 	if (IS_ERR(sleb))
 		return PTR_ERR(sleb);
 
@@ -836,8 +836,8 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf)
 	const struct ubifs_cs_node *node;
 
 	dbg_mnt("replay log LEB %d:%d", lnum, offs);
-	sleb = ubifs_scan(c, lnum, offs, sbuf);
-	if (IS_ERR(sleb) ) {
+	sleb = ubifs_scan(c, lnum, offs, sbuf, c->need_recovery);
+	if (IS_ERR(sleb)) {
 		if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery)
 			return PTR_ERR(sleb);
 		sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf);
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c
index 892ebfe..96c5253 100644
--- a/fs/ubifs/scan.c
+++ b/fs/ubifs/scan.c
@@ -108,10 +108,9 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
 
 		/* Make the node pads to 8-byte boundary */
 		if ((node_len + pad_len) & 7) {
-			if (!quiet) {
+			if (!quiet)
 				dbg_err("bad padding length %d - %d",
 					offs, offs + node_len + pad_len);
-			}
 			return SCANNED_A_BAD_PAD_NODE;
 		}
 
@@ -253,15 +252,19 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
  * @c: UBIFS file-system description object
  * @lnum: logical eraseblock number
  * @offs: offset to start at (usually zero)
- * @sbuf: scan buffer (must be c->leb_size)
+ * @sbuf: scan buffer (must be of @c->leb_size bytes in size)
+ * @quiet: print no messages
  *
  * This function scans LEB number @lnum and returns complete information about
  * its contents. Returns the scaned information in case of success and,
  * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case
  * of failure.
+ *
+ * If @quiet is non-zero, this function does not print large and scary
+ * error messages and flash dumps in case of errors.
  */
 struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
-				  int offs, void *sbuf)
+				  int offs, void *sbuf, int quiet)
 {
 	void *buf = sbuf + offs;
 	int err, len = c->leb_size - offs;
@@ -280,7 +283,7 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
 
 		cond_resched();
 
-		ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0);
+		ret = ubifs_scan_a_node(c, buf, len, lnum, offs, quiet);
 		if (ret > 0) {
 			/* Padding bytes or a valid padding node */
 			offs += ret;
@@ -320,7 +323,9 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
 	}
 
 	if (offs % c->min_io_size) {
-		ubifs_err("empty space starts at non-aligned offset %d", offs);
+		if (!quiet)
+			ubifs_err("empty space starts at non-aligned offset %d",
+				  offs);
 		goto corrupted;;
 	}
 
@@ -331,18 +336,25 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
 			break;
 	for (; len; offs++, buf++, len--)
 		if (*(uint8_t *)buf != 0xff) {
-			ubifs_err("corrupt empty space at LEB %d:%d",
-				  lnum, offs);
+			if (!quiet)
+				ubifs_err("corrupt empty space at LEB %d:%d",
+					  lnum, offs);
 			goto corrupted;
 		}
 
 	return sleb;
 
 corrupted:
-	ubifs_scanned_corruption(c, lnum, offs, buf);
+	if (!quiet) {
+		ubifs_scanned_corruption(c, lnum, offs, buf);
+		ubifs_err("LEB %d scanning failed", lnum);
+	}
 	err = -EUCLEAN;
+	ubifs_scan_destroy(sleb);
+	return ERR_PTR(err);
+
 error:
-	ubifs_err("LEB %d scanning failed", lnum);
+	ubifs_err("LEB %d scanning failed, error %d", lnum, err);
 	ubifs_scan_destroy(sleb);
 	return ERR_PTR(err);
 }
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 51763aa..333e181 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -36,7 +36,6 @@
 #include <linux/mount.h>
 #include <linux/math64.h>
 #include <linux/writeback.h>
-#include <linux/smp_lock.h>
 #include "ubifs.h"
 
 /*
@@ -318,6 +317,8 @@ static int ubifs_write_inode(struct inode *inode, int wait)
 		if (err)
 			ubifs_err("can't write inode %lu, error %d",
 				  inode->i_ino, err);
+		else
+			err = dbg_check_inode_size(c, inode, ui->ui_size);
 	}
 
 	ui->dirty = 0;
@@ -448,17 +449,6 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
 		return 0;
 
 	/*
-	 * VFS calls '->sync_fs()' before synchronizing all dirty inodes and
-	 * pages, so synchronize them first, then commit the journal. Strictly
-	 * speaking, it is not necessary to commit the journal here,
-	 * synchronizing write-buffers would be enough. But committing makes
-	 * UBIFS free space predictions much more accurate, so we want to let
-	 * the user be able to get more accurate results of 'statfs()' after
-	 * they synchronize the file system.
-	 */
-	sync_inodes_sb(sb);
-
-	/*
 	 * Synchronize write buffers, because 'ubifs_run_commit()' does not
 	 * do this if it waits for an already running commit.
 	 */
@@ -468,6 +458,13 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
 			return err;
 	}
 
+	/*
+	 * Strictly speaking, it is not necessary to commit the journal here,
+	 * synchronizing write-buffers would be enough. But committing makes
+	 * UBIFS free space predictions much more accurate, so we want to let
+	 * the user be able to get more accurate results of 'statfs()' after
+	 * they synchronize the file system.
+	 */
 	err = ubifs_run_commit(c);
 	if (err)
 		return err;
@@ -1720,8 +1717,6 @@ static void ubifs_put_super(struct super_block *sb)
 	ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num,
 		  c->vi.vol_id);
 
-	lock_kernel();
-
 	/*
 	 * The following asserts are only valid if there has not been a failure
 	 * of the media. For example, there will be dirty inodes if we failed
@@ -1786,8 +1781,6 @@ static void ubifs_put_super(struct super_block *sb)
 	ubi_close_volume(c->ubi);
 	mutex_unlock(&c->umount_mutex);
 	kfree(c);
-
-	unlock_kernel();
 }
 
 static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
@@ -1803,22 +1796,17 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 		return err;
 	}
 
-	lock_kernel();
 	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
 		if (c->ro_media) {
 			ubifs_msg("cannot re-mount due to prior errors");
-			unlock_kernel();
 			return -EROFS;
 		}
 		err = ubifs_remount_rw(c);
-		if (err) {
-			unlock_kernel();
+		if (err)
 			return err;
-		}
 	} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
 		if (c->ro_media) {
 			ubifs_msg("cannot re-mount due to prior errors");
-			unlock_kernel();
 			return -EROFS;
 		}
 		ubifs_remount_ro(c);
@@ -1833,7 +1821,6 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
 	}
 
 	ubifs_assert(c->lst.taken_empty_lebs > 0);
-	unlock_kernel();
 	return 0;
 }
 
@@ -1980,6 +1967,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 	if (err)
 		goto out_bdi;
 
+	sb->s_bdi = &c->bdi;
 	sb->s_fs_info = c;
 	sb->s_magic = UBIFS_SUPER_MAGIC;
 	sb->s_blocksize = UBIFS_BLOCK_SIZE;
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index f249f7b..e5b1a7d 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -1159,8 +1159,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
  *   o exact match, i.e. the found zero-level znode contains key @key, then %1
  *     is returned and slot number of the matched branch is stored in @n;
  *   o not exact match, which means that zero-level znode does not contain
- *     @key, then %0 is returned and slot number of the closed branch is stored
- *     in  @n;
+ *     @key, then %0 is returned and slot number of the closest branch is stored
+ *     in @n;
  *   o @key is so small that it is even less than the lowest key of the
  *     leftmost zero-level node, then %0 is returned and %0 is stored in @n.
  *
@@ -1433,7 +1433,7 @@ static int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1)
  * @lnum: LEB number is returned here
  * @offs: offset is returned here
  *
- * This function look up and reads node with key @key. The caller has to make
+ * This function looks up and reads node with key @key. The caller has to make
  * sure the @node buffer is large enough to fit the node. Returns zero in case
  * of success, %-ENOENT if the node was not found, and a negative error code in
  * case of failure. The node location can be returned in @lnum and @offs.
@@ -3268,3 +3268,73 @@ out_unlock:
 	mutex_unlock(&c->tnc_mutex);
 	return err;
 }
+
+#ifdef CONFIG_UBIFS_FS_DEBUG
+
+/**
+ * dbg_check_inode_size - check if inode size is correct.
+ * @c: UBIFS file-system description object
+ * @inum: inode number
+ * @size: inode size
+ *
+ * This function makes sure that the inode size (@size) is correct and it does
+ * not have any pages beyond @size. Returns zero if the inode is OK, %-EINVAL
+ * if it has a data page beyond @size, and other negative error code in case of
+ * other errors.
+ */
+int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
+			 loff_t size)
+{
+	int err, n;
+	union ubifs_key from_key, to_key, *key;
+	struct ubifs_znode *znode;
+	unsigned int block;
+
+	if (!S_ISREG(inode->i_mode))
+		return 0;
+	if (!(ubifs_chk_flags & UBIFS_CHK_GEN))
+		return 0;
+
+	block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
+	data_key_init(c, &from_key, inode->i_ino, block);
+	highest_data_key(c, &to_key, inode->i_ino);
+
+	mutex_lock(&c->tnc_mutex);
+	err = ubifs_lookup_level0(c, &from_key, &znode, &n);
+	if (err < 0)
+		goto out_unlock;
+
+	if (err) {
+		err = -EINVAL;
+		key = &from_key;
+		goto out_dump;
+	}
+
+	err = tnc_next(c, &znode, &n);
+	if (err == -ENOENT) {
+		err = 0;
+		goto out_unlock;
+	}
+	if (err < 0)
+		goto out_unlock;
+
+	ubifs_assert(err == 0);
+	key = &znode->zbranch[n].key;
+	if (!key_in_range(c, key, &from_key, &to_key))
+		goto out_unlock;
+
+out_dump:
+	block = key_block(c, key);
+	ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
+		  "(data key %s)", (unsigned long)inode->i_ino, size,
+		  ((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
+	dbg_dump_inode(c, inode);
+	dbg_dump_stack();
+	err = -EINVAL;
+
+out_unlock:
+	mutex_unlock(&c->tnc_mutex);
+	return err;
+}
+
+#endif /* CONFIG_UBIFS_FS_DEBUG */
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index fde8d12..53288e5 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -245,7 +245,7 @@ static int layout_leb_in_gaps(struct ubifs_info *c, int *p)
 	 * it is more comprehensive and less efficient than is needed for this
 	 * purpose.
 	 */
-	sleb = ubifs_scan(c, lnum, 0, c->ileb_buf);
+	sleb = ubifs_scan(c, lnum, 0, c->ileb_buf, 0);
 	c->ileb_len = 0;
 	if (IS_ERR(sleb))
 		return PTR_ERR(sleb);
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index 3eee07e..191ca78 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -135,6 +135,13 @@
 /* The key is always at the same position in all keyed nodes */
 #define UBIFS_KEY_OFFSET offsetof(struct ubifs_ino_node, key)
 
+/* Garbage collector journal head number */
+#define UBIFS_GC_HEAD   0
+/* Base journal head number */
+#define UBIFS_BASE_HEAD 1
+/* Data journal head number */
+#define UBIFS_DATA_HEAD 2
+
 /*
  * LEB Properties Tree node types.
  *
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index a293490..b2d9763 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -105,12 +105,10 @@
 /* Number of non-data journal heads */
 #define NONDATA_JHEADS_CNT 2
 
-/* Garbage collector head */
-#define GCHD   0
-/* Base journal head number */
-#define BASEHD 1
-/* First "general purpose" journal head */
-#define DATAHD 2
+/* Shorter names for journal head numbers for internal usage */
+#define GCHD   UBIFS_GC_HEAD
+#define BASEHD UBIFS_BASE_HEAD
+#define DATAHD UBIFS_DATA_HEAD
 
 /* 'No change' value for 'ubifs_change_lp()' */
 #define LPROPS_NC 0x80000001
@@ -1451,7 +1449,7 @@ int ubifs_sync_wbufs_by_inode(struct ubifs_info *c, struct inode *inode);
 
 /* scan.c */
 struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum,
-				  int offs, void *sbuf);
+				  int offs, void *sbuf, int quiet);
 void ubifs_scan_destroy(struct ubifs_scan_leb *sleb);
 int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
 		      int offs, int quiet);
@@ -1676,6 +1674,7 @@ const struct ubifs_lprops *ubifs_fast_find_free(struct ubifs_info *c);
 const struct ubifs_lprops *ubifs_fast_find_empty(struct ubifs_info *c);
 const struct ubifs_lprops *ubifs_fast_find_freeable(struct ubifs_info *c);
 const struct ubifs_lprops *ubifs_fast_find_frdi_idx(struct ubifs_info *c);
+int ubifs_calc_dark(const struct ubifs_info *c, int spc);
 
 /* file.c */
 int ubifs_fsync(struct file *file, struct dentry *dentry, int datasync);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index adafcf5..7998cc3 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -78,9 +78,9 @@ enum {
 	SECURITY_XATTR,
 };
 
-static struct inode_operations none_inode_operations;
+static const struct inode_operations none_inode_operations;
 static struct address_space_operations none_address_operations;
-static struct file_operations none_file_operations;
+static const struct file_operations none_file_operations;
 
 /**
  * create_xattr - create an extended attribute.
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 1d2c570..2ffdb67 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -18,59 +18,6 @@
 #include <linux/string.h>
 #include <linux/buffer_head.h>
 
-#if 0
-static uint8_t *udf_filead_read(struct inode *dir, uint8_t *tmpad,
-				uint8_t ad_size, struct kernel_lb_addr fe_loc,
-				int *pos, int *offset, struct buffer_head **bh,
-				int *error)
-{
-	int loffset = *offset;
-	int block;
-	uint8_t *ad;
-	int remainder;
-
-	*error = 0;
-
-	ad = (uint8_t *)(*bh)->b_data + *offset;
-	*offset += ad_size;
-
-	if (!ad) {
-		brelse(*bh);
-		*error = 1;
-		return NULL;
-	}
-
-	if (*offset == dir->i_sb->s_blocksize) {
-		brelse(*bh);
-		block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
-		if (!block)
-			return NULL;
-		*bh = udf_tread(dir->i_sb, block);
-		if (!*bh)
-			return NULL;
-	} else if (*offset > dir->i_sb->s_blocksize) {
-		ad = tmpad;
-
-		remainder = dir->i_sb->s_blocksize - loffset;
-		memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
-
-		brelse(*bh);
-		block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
-		if (!block)
-			return NULL;
-		(*bh) = udf_tread(dir->i_sb, block);
-		if (!*bh)
-			return NULL;
-
-		memcpy((uint8_t *)ad + remainder, (*bh)->b_data,
-			ad_size - remainder);
-		*offset = ad_size - remainder;
-	}
-
-	return ad;
-}
-#endif
-
 struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
 					 struct udf_fileident_bh *fibh,
 					 struct fileIdentDesc *cfi,
@@ -248,39 +195,6 @@ struct fileIdentDesc *udf_get_fileident(void *buffer, int bufsize, int *offset)
 	return fi;
 }
 
-#if 0
-static struct extent_ad *udf_get_fileextent(void *buffer, int bufsize, int *offset)
-{
-	struct extent_ad *ext;
-	struct fileEntry *fe;
-	uint8_t *ptr;
-
-	if ((!buffer) || (!offset)) {
-		printk(KERN_ERR "udf: udf_get_fileextent() invalidparms\n");
-		return NULL;
-	}
-
-	fe = (struct fileEntry *)buffer;
-
-	if (fe->descTag.tagIdent != cpu_to_le16(TAG_IDENT_FE)) {
-		udf_debug("0x%x != TAG_IDENT_FE\n",
-			  le16_to_cpu(fe->descTag.tagIdent));
-		return NULL;
-	}
-
-	ptr = (uint8_t *)(fe->extendedAttr) +
-		le32_to_cpu(fe->lengthExtendedAttr);
-
-	if ((*offset > 0) && (*offset < le32_to_cpu(fe->lengthAllocDescs)))
-		ptr += *offset;
-
-	ext = (struct extent_ad *)ptr;
-
-	*offset = *offset + sizeof(struct extent_ad);
-	return ext;
-}
-#endif
-
 struct short_ad *udf_get_fileshortad(uint8_t *ptr, int maxoffset, uint32_t *offset,
 			      int inc)
 {
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 7464305..b80cbd7 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -193,9 +193,11 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 static int udf_release_file(struct inode *inode, struct file *filp)
 {
 	if (filp->f_mode & FMODE_WRITE) {
+		mutex_lock(&inode->i_mutex);
 		lock_kernel();
 		udf_discard_prealloc(inode);
 		unlock_kernel();
+		mutex_unlock(&inode->i_mutex);
 	}
 	return 0;
 }
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index e7533f7..6d24c2c 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -90,19 +90,16 @@ no_delete:
 }
 
 /*
- * If we are going to release inode from memory, we discard preallocation and
- * truncate last inode extent to proper length. We could use drop_inode() but
- * it's called under inode_lock and thus we cannot mark inode dirty there.  We
- * use clear_inode() but we have to make sure to write inode as it's not written
- * automatically.
+ * If we are going to release inode from memory, we truncate last inode extent
+ * to proper length. We could use drop_inode() but it's called under inode_lock
+ * and thus we cannot mark inode dirty there.  We use clear_inode() but we have
+ * to make sure to write inode as it's not written automatically.
  */
 void udf_clear_inode(struct inode *inode)
 {
 	struct udf_inode_info *iinfo;
 	if (!(inode->i_sb->s_flags & MS_RDONLY)) {
 		lock_kernel();
-		/* Discard preallocation for directories, symlinks, etc. */
-		udf_discard_prealloc(inode);
 		udf_truncate_tail_extent(inode);
 		unlock_kernel();
 		write_inode_now(inode, 0);
@@ -664,8 +661,12 @@ static struct buffer_head *inode_getblk(struct inode *inode, sector_t block,
 	udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
 
 #ifdef UDF_PREALLOCATE
-	/* preallocate blocks */
-	udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
+	/* We preallocate blocks only for regular files. It also makes sense
+	 * for directories but there's a problem when to drop the
+	 * preallocation. We might use some delayed work for that but I feel
+	 * it's overengineering for a filesystem like UDF. */
+	if (S_ISREG(inode->i_mode))
+		udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
 #endif
 
 	/* merge any continuous blocks in laarr */
diff --git a/fs/udf/lowlevel.c b/fs/udf/lowlevel.c
index 1b88fd5..43e24a3 100644
--- a/fs/udf/lowlevel.c
+++ b/fs/udf/lowlevel.c
@@ -36,14 +36,10 @@ unsigned int udf_get_last_session(struct super_block *sb)
 	ms_info.addr_format = CDROM_LBA;
 	i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info);
 
-#define WE_OBEY_THE_WRITTEN_STANDARDS 1
-
 	if (i == 0) {
 		udf_debug("XA disk: %s, vol_desc_start=%d\n",
 			  (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba);
-#if WE_OBEY_THE_WRITTEN_STANDARDS
 		if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
-#endif
 			vol_desc_start = ms_info.addr.lba;
 	} else {
 		udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 6a29fa3..21dad8c 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -943,7 +943,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
 		pc->componentType = 1;
 		pc->lengthComponentIdent = 0;
 		pc->componentFileVersionNum = 0;
-		pc += sizeof(struct pathComponent);
 		elen += sizeof(struct pathComponent);
 	}
 
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index aecf251..d5e5559 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -216,7 +216,6 @@ xfs_setfilesize(
 	if (ip->i_d.di_size < isize) {
 		ip->i_d.di_size = isize;
 		ip->i_update_core = 1;
-		ip->i_update_size = 1;
 		xfs_mark_inode_dirty_sync(ip);
 	}
 
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 0542fd5..988d8f8 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -172,12 +172,21 @@ xfs_file_release(
  */
 STATIC int
 xfs_file_fsync(
-	struct file	*filp,
-	struct dentry	*dentry,
-	int		datasync)
+	struct file		*file,
+	struct dentry		*dentry,
+	int			datasync)
 {
-	xfs_iflags_clear(XFS_I(dentry->d_inode), XFS_ITRUNCATED);
-	return -xfs_fsync(XFS_I(dentry->d_inode));
+	struct inode		*inode = dentry->d_inode;
+	struct xfs_inode	*ip = XFS_I(inode);
+	int			error;
+
+	/* capture size updates in I/O completion before writing the inode. */
+	error = filemap_fdatawait(inode->i_mapping);
+	if (error)
+		return error;
+
+	xfs_iflags_clear(ip, XFS_ITRUNCATED);
+	return -xfs_fsync(ip);
 }
 
 STATIC int
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 6c32f1d..da0159d 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -43,7 +43,6 @@
 #include "xfs_error.h"
 #include "xfs_itable.h"
 #include "xfs_rw.h"
-#include "xfs_acl.h"
 #include "xfs_attr.h"
 #include "xfs_buf_item.h"
 #include "xfs_utils.h"
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 7078974..49e4a6a 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -812,18 +812,21 @@ write_retry:
 
 	/* Handle various SYNC-type writes */
 	if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
+		loff_t end = pos + ret - 1;
 		int error2;
 
 		xfs_iunlock(xip, iolock);
 		if (need_i_mutex)
 			mutex_unlock(&inode->i_mutex);
-		error2 = sync_page_range(inode, mapping, pos, ret);
+
+		error2 = filemap_write_and_wait_range(mapping, pos, end);
 		if (!error)
 			error = error2;
 		if (need_i_mutex)
 			mutex_lock(&inode->i_mutex);
 		xfs_ilock(xip, iolock);
-		error2 = xfs_write_sync_logforce(mp, xip);
+
+		error2 = xfs_fsync(xip);
 		if (!error)
 			error = error2;
 	}
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c
index c3526d4..76fdc58 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/linux-2.6/xfs_stats.c
@@ -20,16 +20,9 @@
 
 DEFINE_PER_CPU(struct xfsstats, xfsstats);
 
-STATIC int
-xfs_read_xfsstats(
-	char		*buffer,
-	char		**start,
-	off_t		offset,
-	int		count,
-	int		*eof,
-	void		*data)
+static int xfs_stat_proc_show(struct seq_file *m, void *v)
 {
-	int		c, i, j, len, val;
+	int		c, i, j, val;
 	__uint64_t	xs_xstrat_bytes = 0;
 	__uint64_t	xs_write_bytes = 0;
 	__uint64_t	xs_read_bytes = 0;
@@ -60,18 +53,18 @@ xfs_read_xfsstats(
 	};
 
 	/* Loop over all stats groups */
-	for (i=j=len = 0; i < ARRAY_SIZE(xstats); i++) {
-		len += sprintf(buffer + len, "%s", xstats[i].desc);
+	for (i=j = 0; i < ARRAY_SIZE(xstats); i++) {
+		seq_printf(m, "%s", xstats[i].desc);
 		/* inner loop does each group */
 		while (j < xstats[i].endpoint) {
 			val = 0;
 			/* sum over all cpus */
 			for_each_possible_cpu(c)
 				val += *(((__u32*)&per_cpu(xfsstats, c) + j));
-			len += sprintf(buffer + len, " %u", val);
+			seq_printf(m, " %u", val);
 			j++;
 		}
-		buffer[len++] = '\n';
+		seq_putc(m, '\n');
 	}
 	/* extra precision counters */
 	for_each_possible_cpu(i) {
@@ -80,36 +73,38 @@ xfs_read_xfsstats(
 		xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
 	}
 
-	len += sprintf(buffer + len, "xpc %Lu %Lu %Lu\n",
+	seq_printf(m, "xpc %Lu %Lu %Lu\n",
 			xs_xstrat_bytes, xs_write_bytes, xs_read_bytes);
-	len += sprintf(buffer + len, "debug %u\n",
+	seq_printf(m, "debug %u\n",
 #if defined(DEBUG)
 		1);
 #else
 		0);
 #endif
+	return 0;
+}
 
-	if (offset >= len) {
-		*start = buffer;
-		*eof = 1;
-		return 0;
-	}
-	*start = buffer + offset;
-	if ((len -= offset) > count)
-		return count;
-	*eof = 1;
-
-	return len;
+static int xfs_stat_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xfs_stat_proc_show, NULL);
 }
 
+static const struct file_operations xfs_stat_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= xfs_stat_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 int
 xfs_init_procfs(void)
 {
 	if (!proc_mkdir("fs/xfs", NULL))
 		goto out;
 
-	if (!create_proc_read_entry("fs/xfs/stat", 0, NULL,
-			xfs_read_xfsstats, NULL))
+	if (!proc_create("fs/xfs/stat", 0, NULL,
+			 &xfs_stat_proc_fops))
 		goto out_remove_entry;
 	return 0;
 
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index a220d36..5d7c60a 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -579,15 +579,19 @@ xfs_showargs(
 	else if (mp->m_qflags & XFS_UQUOTA_ACCT)
 		seq_puts(m, "," MNTOPT_UQUOTANOENF);
 
-	if (mp->m_qflags & (XFS_PQUOTA_ACCT|XFS_OQUOTA_ENFD))
-		seq_puts(m, "," MNTOPT_PRJQUOTA);
-	else if (mp->m_qflags & XFS_PQUOTA_ACCT)
-		seq_puts(m, "," MNTOPT_PQUOTANOENF);
-
-	if (mp->m_qflags & (XFS_GQUOTA_ACCT|XFS_OQUOTA_ENFD))
-		seq_puts(m, "," MNTOPT_GRPQUOTA);
-	else if (mp->m_qflags & XFS_GQUOTA_ACCT)
-		seq_puts(m, "," MNTOPT_GQUOTANOENF);
+	/* Either project or group quotas can be active, not both */
+
+	if (mp->m_qflags & XFS_PQUOTA_ACCT) {
+		if (mp->m_qflags & XFS_OQUOTA_ENFD)
+			seq_puts(m, "," MNTOPT_PRJQUOTA);
+		else
+			seq_puts(m, "," MNTOPT_PQUOTANOENF);
+	} else if (mp->m_qflags & XFS_GQUOTA_ACCT) {
+		if (mp->m_qflags & XFS_OQUOTA_ENFD)
+			seq_puts(m, "," MNTOPT_GRPQUOTA);
+		else
+			seq_puts(m, "," MNTOPT_GQUOTANOENF);
+	}
 
 	if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
 		seq_puts(m, "," MNTOPT_NOQUOTA);
@@ -687,7 +691,7 @@ xfs_barrier_test(
 	return error;
 }
 
-void
+STATIC void
 xfs_mountfs_check_barriers(xfs_mount_t *mp)
 {
 	int error;
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 98ef624..320be6a 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -749,21 +749,6 @@ __xfs_inode_clear_reclaim_tag(
 			XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
 }
 
-void
-xfs_inode_clear_reclaim_tag(
-	xfs_inode_t	*ip)
-{
-	xfs_mount_t	*mp = ip->i_mount;
-	xfs_perag_t	*pag = xfs_get_perag(mp, ip->i_ino);
-
-	read_lock(&pag->pag_ici_lock);
-	spin_lock(&ip->i_flags_lock);
-	__xfs_inode_clear_reclaim_tag(mp, pag, ip);
-	spin_unlock(&ip->i_flags_lock);
-	read_unlock(&pag->pag_ici_lock);
-	xfs_put_perag(mp, pag);
-}
-
 STATIC int
 xfs_reclaim_inode_now(
 	struct xfs_inode	*ip,
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index 5912060..27920eb 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -49,7 +49,6 @@ int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
 
 void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
 void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip);
-void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip);
 void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
 				struct xfs_inode *ip);
 
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c
index 21b08c0..83e7ea3 100644
--- a/fs/xfs/quota/xfs_qm_stats.c
+++ b/fs/xfs/quota/xfs_qm_stats.c
@@ -48,50 +48,34 @@
 
 struct xqmstats xqmstats;
 
-STATIC int
-xfs_qm_read_xfsquota(
-	char		*buffer,
-	char		**start,
-	off_t		offset,
-	int		count,
-	int		*eof,
-	void		*data)
+static int xqm_proc_show(struct seq_file *m, void *v)
 {
-	int		len;
-
 	/* maximum; incore; ratio free to inuse; freelist */
-	len = sprintf(buffer, "%d\t%d\t%d\t%u\n",
+	seq_printf(m, "%d\t%d\t%d\t%u\n",
 			ndquot,
 			xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0,
 			xfs_Gqm? xfs_Gqm->qm_dqfree_ratio : 0,
 			xfs_Gqm? xfs_Gqm->qm_dqfreelist.qh_nelems : 0);
-
-	if (offset >= len) {
-		*start = buffer;
-		*eof = 1;
-		return 0;
-	}
-	*start = buffer + offset;
-	if ((len -= offset) > count)
-		return count;
-	*eof = 1;
-
-	return len;
+	return 0;
 }
 
-STATIC int
-xfs_qm_read_stats(
-	char		*buffer,
-	char		**start,
-	off_t		offset,
-	int		count,
-	int		*eof,
-	void		*data)
+static int xqm_proc_open(struct inode *inode, struct file *file)
 {
-	int		len;
+	return single_open(file, xqm_proc_show, NULL);
+}
+
+static const struct file_operations xqm_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= xqm_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
+static int xqmstat_proc_show(struct seq_file *m, void *v)
+{
 	/* quota performance statistics */
-	len = sprintf(buffer, "qm %u %u %u %u %u %u %u %u\n",
+	seq_printf(m, "qm %u %u %u %u %u %u %u %u\n",
 			xqmstats.xs_qm_dqreclaims,
 			xqmstats.xs_qm_dqreclaim_misses,
 			xqmstats.xs_qm_dquot_dups,
@@ -100,25 +84,27 @@ xfs_qm_read_stats(
 			xqmstats.xs_qm_dqwants,
 			xqmstats.xs_qm_dqshake_reclaims,
 			xqmstats.xs_qm_dqinact_reclaims);
+	return 0;
+}
 
-	if (offset >= len) {
-		*start = buffer;
-		*eof = 1;
-		return 0;
-	}
-	*start = buffer + offset;
-	if ((len -= offset) > count)
-		return count;
-	*eof = 1;
-
-	return len;
+static int xqmstat_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, xqmstat_proc_show, NULL);
 }
 
+static const struct file_operations xqmstat_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= xqmstat_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 void
 xfs_qm_init_procfs(void)
 {
-	create_proc_read_entry("fs/xfs/xqmstat", 0, NULL, xfs_qm_read_stats, NULL);
-	create_proc_read_entry("fs/xfs/xqm", 0, NULL, xfs_qm_read_xfsquota, NULL);
+	proc_create("fs/xfs/xqmstat", 0, NULL, &xqmstat_proc_fops);
+	proc_create("fs/xfs/xqm", 0, NULL, &xqm_proc_fops);
 }
 
 void
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index f24b50b..a5d54bf 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -198,6 +198,15 @@ typedef struct xfs_perag
 	xfs_agino_t	pagi_count;	/* number of allocated inodes */
 	int		pagb_count;	/* pagb slots in use */
 	xfs_perag_busy_t *pagb_list;	/* unstable blocks */
+
+	/*
+	 * Inode allocation search lookup optimisation.
+	 * If the pagino matches, the search for new inodes
+	 * doesn't need to search the near ones again straight away
+	 */
+	xfs_agino_t	pagl_pagino;
+	xfs_agino_t	pagl_leftrec;
+	xfs_agino_t	pagl_rightrec;
 #ifdef __KERNEL__
 	spinlock_t	pagb_lock;	/* lock for pagb_list */
 
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 8ee5b5a..8971fb0 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -3713,7 +3713,7 @@ done:
  * entry (null if none).  Else, *lastxp will be set to the index
  * of the found entry; *gotp will contain the entry.
  */
-xfs_bmbt_rec_host_t *			/* pointer to found extent entry */
+STATIC xfs_bmbt_rec_host_t *		/* pointer to found extent entry */
 xfs_bmap_search_multi_extents(
 	xfs_ifork_t	*ifp,		/* inode fork pointer */
 	xfs_fileoff_t	bno,		/* block number searched for */
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 1b8ff92..56f62d2 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -392,17 +392,6 @@ xfs_bmap_count_blocks(
 	int			whichfork,
 	int			*count);
 
-/*
- * Search the extent records for the entry containing block bno.
- * If bno lies in a hole, point to the next entry.  If bno lies
- * past eof, *eofp will be set, and *prevp will contain the last
- * entry (null if none).  Else, *lastxp will be set to the index
- * of the found entry; *gotp will contain the entry.
- */
-xfs_bmbt_rec_host_t *
-xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
-			xfs_extnum_t *, xfs_bmbt_irec_t *, xfs_bmbt_irec_t *);
-
 #endif	/* __KERNEL__ */
 
 #endif	/* __XFS_BMAP_H__ */
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 5c1ade0..eb7b702 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -202,16 +202,6 @@ xfs_bmbt_get_state(
 				ext_flag);
 }
 
-/* Endian flipping versions of the bmbt extraction functions */
-void
-xfs_bmbt_disk_get_all(
-	xfs_bmbt_rec_t	*r,
-	xfs_bmbt_irec_t *s)
-{
-	__xfs_bmbt_get_all(get_unaligned_be64(&r->l0),
-				get_unaligned_be64(&r->l1), s);
-}
-
 /*
  * Extract the blockcount field from an on disk bmap extent record.
  */
@@ -816,6 +806,16 @@ xfs_bmbt_trace_key(
 	*l1 = 0;
 }
 
+/* Endian flipping versions of the bmbt extraction functions */
+STATIC void
+xfs_bmbt_disk_get_all(
+	xfs_bmbt_rec_t	*r,
+	xfs_bmbt_irec_t *s)
+{
+	__xfs_bmbt_get_all(get_unaligned_be64(&r->l0),
+				get_unaligned_be64(&r->l1), s);
+}
+
 STATIC void
 xfs_bmbt_trace_record(
 	struct xfs_btree_cur	*cur,
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 0e8df00..5549d49 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -220,7 +220,6 @@ extern xfs_fsblock_t xfs_bmbt_get_startblock(xfs_bmbt_rec_host_t *r);
 extern xfs_fileoff_t xfs_bmbt_get_startoff(xfs_bmbt_rec_host_t *r);
 extern xfs_exntst_t xfs_bmbt_get_state(xfs_bmbt_rec_host_t *r);
 
-extern void xfs_bmbt_disk_get_all(xfs_bmbt_rec_t *r, xfs_bmbt_irec_t *s);
 extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
 extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
 
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 2671738..52b5f14 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -646,46 +646,6 @@ xfs_btree_read_bufl(
 }
 
 /*
- * Get a buffer for the block, return it read in.
- * Short-form addressing.
- */
-int					/* error */
-xfs_btree_read_bufs(
-	xfs_mount_t	*mp,		/* file system mount point */
-	xfs_trans_t	*tp,		/* transaction pointer */
-	xfs_agnumber_t	agno,		/* allocation group number */
-	xfs_agblock_t	agbno,		/* allocation group block number */
-	uint		lock,		/* lock flags for read_buf */
-	xfs_buf_t	**bpp,		/* buffer for agno/agbno */
-	int		refval)		/* ref count value for buffer */
-{
-	xfs_buf_t	*bp;		/* return value */
-	xfs_daddr_t	d;		/* real disk block address */
-	int		error;
-
-	ASSERT(agno != NULLAGNUMBER);
-	ASSERT(agbno != NULLAGBLOCK);
-	d = XFS_AGB_TO_DADDR(mp, agno, agbno);
-	if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
-					mp->m_bsize, lock, &bp))) {
-		return error;
-	}
-	ASSERT(!bp || !XFS_BUF_GETERROR(bp));
-	if (bp != NULL) {
-		switch (refval) {
-		case XFS_ALLOC_BTREE_REF:
-			XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval);
-			break;
-		case XFS_INO_BTREE_REF:
-			XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, refval);
-			break;
-		}
-	}
-	*bpp = bp;
-	return 0;
-}
-
-/*
  * Read-ahead the block, don't wait for it, don't return a buffer.
  * Long-form addressing.
  */
@@ -2951,7 +2911,7 @@ error0:
  * inode we have to copy the single block it was pointing to into the
  * inode.
  */
-int
+STATIC int
 xfs_btree_kill_iroot(
 	struct xfs_btree_cur	*cur)
 {
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 4f852b7..7fa0706 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -379,20 +379,6 @@ xfs_btree_read_bufl(
 	int			refval);/* ref count value for buffer */
 
 /*
- * Get a buffer for the block, return it read in.
- * Short-form addressing.
- */
-int					/* error */
-xfs_btree_read_bufs(
-	struct xfs_mount	*mp,	/* file system mount point */
-	struct xfs_trans	*tp,	/* transaction pointer */
-	xfs_agnumber_t		agno,	/* allocation group number */
-	xfs_agblock_t		agbno,	/* allocation group block number */
-	uint			lock,	/* lock flags for read_buf */
-	struct xfs_buf		**bpp,	/* buffer for agno/agbno */
-	int			refval);/* ref count value for buffer */
-
-/*
  * Read-ahead the block, don't wait for it, don't return a buffer.
  * Long-form addressing.
  */
@@ -432,7 +418,6 @@ int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);
 int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *);
-int xfs_btree_kill_iroot(struct xfs_btree_cur *);
 int xfs_btree_insert(struct xfs_btree_cur *, int *);
 int xfs_btree_delete(struct xfs_btree_cur *, int *);
 int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 3120a3a..ab64f3e 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -57,75 +57,35 @@ xfs_ialloc_cluster_alignment(
 }
 
 /*
- * Lookup the record equal to ino in the btree given by cur.
- */
-STATIC int				/* error */
-xfs_inobt_lookup_eq(
-	struct xfs_btree_cur	*cur,	/* btree cursor */
-	xfs_agino_t		ino,	/* starting inode of chunk */
-	__int32_t		fcnt,	/* free inode count */
-	xfs_inofree_t		free,	/* free inode mask */
-	int			*stat)	/* success/failure */
-{
-	cur->bc_rec.i.ir_startino = ino;
-	cur->bc_rec.i.ir_freecount = fcnt;
-	cur->bc_rec.i.ir_free = free;
-	return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat);
-}
-
-/*
- * Lookup the first record greater than or equal to ino
- * in the btree given by cur.
+ * Lookup a record by ino in the btree given by cur.
  */
 int					/* error */
-xfs_inobt_lookup_ge(
+xfs_inobt_lookup(
 	struct xfs_btree_cur	*cur,	/* btree cursor */
 	xfs_agino_t		ino,	/* starting inode of chunk */
-	__int32_t		fcnt,	/* free inode count */
-	xfs_inofree_t		free,	/* free inode mask */
+	xfs_lookup_t		dir,	/* <=, >=, == */
 	int			*stat)	/* success/failure */
 {
 	cur->bc_rec.i.ir_startino = ino;
-	cur->bc_rec.i.ir_freecount = fcnt;
-	cur->bc_rec.i.ir_free = free;
-	return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat);
+	cur->bc_rec.i.ir_freecount = 0;
+	cur->bc_rec.i.ir_free = 0;
+	return xfs_btree_lookup(cur, dir, stat);
 }
 
 /*
- * Lookup the first record less than or equal to ino
- * in the btree given by cur.
- */
-int					/* error */
-xfs_inobt_lookup_le(
-	struct xfs_btree_cur	*cur,	/* btree cursor */
-	xfs_agino_t		ino,	/* starting inode of chunk */
-	__int32_t		fcnt,	/* free inode count */
-	xfs_inofree_t		free,	/* free inode mask */
-	int			*stat)	/* success/failure */
-{
-	cur->bc_rec.i.ir_startino = ino;
-	cur->bc_rec.i.ir_freecount = fcnt;
-	cur->bc_rec.i.ir_free = free;
-	return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat);
-}
-
-/*
- * Update the record referred to by cur to the value given
- * by [ino, fcnt, free].
+ * Update the record referred to by cur to the value given.
  * This either works (return 0) or gets an EFSCORRUPTED error.
  */
 STATIC int				/* error */
 xfs_inobt_update(
 	struct xfs_btree_cur	*cur,	/* btree cursor */
-	xfs_agino_t		ino,	/* starting inode of chunk */
-	__int32_t		fcnt,	/* free inode count */
-	xfs_inofree_t		free)	/* free inode mask */
+	xfs_inobt_rec_incore_t	*irec)	/* btree record */
 {
 	union xfs_btree_rec	rec;
 
-	rec.inobt.ir_startino = cpu_to_be32(ino);
-	rec.inobt.ir_freecount = cpu_to_be32(fcnt);
-	rec.inobt.ir_free = cpu_to_be64(free);
+	rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino);
+	rec.inobt.ir_freecount = cpu_to_be32(irec->ir_freecount);
+	rec.inobt.ir_free = cpu_to_be64(irec->ir_free);
 	return xfs_btree_update(cur, &rec);
 }
 
@@ -135,9 +95,7 @@ xfs_inobt_update(
 int					/* error */
 xfs_inobt_get_rec(
 	struct xfs_btree_cur	*cur,	/* btree cursor */
-	xfs_agino_t		*ino,	/* output: starting inode of chunk */
-	__int32_t		*fcnt,	/* output: number of free inodes */
-	xfs_inofree_t		*free,	/* output: free inode mask */
+	xfs_inobt_rec_incore_t	*irec,	/* btree record */
 	int			*stat)	/* output: success/failure */
 {
 	union xfs_btree_rec	*rec;
@@ -145,14 +103,136 @@ xfs_inobt_get_rec(
 
 	error = xfs_btree_get_rec(cur, &rec, stat);
 	if (!error && *stat == 1) {
-		*ino = be32_to_cpu(rec->inobt.ir_startino);
-		*fcnt = be32_to_cpu(rec->inobt.ir_freecount);
-		*free = be64_to_cpu(rec->inobt.ir_free);
+		irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino);
+		irec->ir_freecount = be32_to_cpu(rec->inobt.ir_freecount);
+		irec->ir_free = be64_to_cpu(rec->inobt.ir_free);
 	}
 	return error;
 }
 
 /*
+ * Verify that the number of free inodes in the AGI is correct.
+ */
+#ifdef DEBUG
+STATIC int
+xfs_check_agi_freecount(
+	struct xfs_btree_cur	*cur,
+	struct xfs_agi		*agi)
+{
+	if (cur->bc_nlevels == 1) {
+		xfs_inobt_rec_incore_t rec;
+		int		freecount = 0;
+		int		error;
+		int		i;
+
+		error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
+		if (error)
+			return error;
+
+		do {
+			error = xfs_inobt_get_rec(cur, &rec, &i);
+			if (error)
+				return error;
+
+			if (i) {
+				freecount += rec.ir_freecount;
+				error = xfs_btree_increment(cur, 0, &i);
+				if (error)
+					return error;
+			}
+		} while (i == 1);
+
+		if (!XFS_FORCED_SHUTDOWN(cur->bc_mp))
+			ASSERT(freecount == be32_to_cpu(agi->agi_freecount));
+	}
+	return 0;
+}
+#else
+#define xfs_check_agi_freecount(cur, agi)	0
+#endif
+
+/*
+ * Initialise a new set of inodes.
+ */
+STATIC void
+xfs_ialloc_inode_init(
+	struct xfs_mount	*mp,
+	struct xfs_trans	*tp,
+	xfs_agnumber_t		agno,
+	xfs_agblock_t		agbno,
+	xfs_agblock_t		length,
+	unsigned int		gen)
+{
+	struct xfs_buf		*fbuf;
+	struct xfs_dinode	*free;
+	int			blks_per_cluster, nbufs, ninodes;
+	int			version;
+	int			i, j;
+	xfs_daddr_t		d;
+
+	/*
+	 * Loop over the new block(s), filling in the inodes.
+	 * For small block sizes, manipulate the inodes in buffers
+	 * which are multiples of the blocks size.
+	 */
+	if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
+		blks_per_cluster = 1;
+		nbufs = length;
+		ninodes = mp->m_sb.sb_inopblock;
+	} else {
+		blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /
+				   mp->m_sb.sb_blocksize;
+		nbufs = length / blks_per_cluster;
+		ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;
+	}
+
+	/*
+	 * Figure out what version number to use in the inodes we create.
+	 * If the superblock version has caught up to the one that supports
+	 * the new inode format, then use the new inode version.  Otherwise
+	 * use the old version so that old kernels will continue to be
+	 * able to use the file system.
+	 */
+	if (xfs_sb_version_hasnlink(&mp->m_sb))
+		version = 2;
+	else
+		version = 1;
+
+	for (j = 0; j < nbufs; j++) {
+		/*
+		 * Get the block.
+		 */
+		d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster));
+		fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
+					 mp->m_bsize * blks_per_cluster,
+					 XFS_BUF_LOCK);
+		ASSERT(fbuf);
+		ASSERT(!XFS_BUF_GETERROR(fbuf));
+
+		/*
+		 * 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
+		 *	individual transactions causing a lot of log traffic.
+		 */
+		xfs_biozero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog);
+		for (i = 0; i < ninodes; i++) {
+			int	ioffset = i << mp->m_sb.sb_inodelog;
+			uint	isize = sizeof(struct xfs_dinode);
+
+			free = xfs_make_iptr(mp, fbuf, i);
+			free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
+			free->di_version = version;
+			free->di_gen = cpu_to_be32(gen);
+			free->di_next_unlinked = cpu_to_be32(NULLAGINO);
+			xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);
+		}
+		xfs_trans_inode_alloc_buf(tp, fbuf);
+	}
+}
+
+/*
  * Allocate new inodes in the allocation group specified by agbp.
  * Return 0 for success, else error code.
  */
@@ -164,24 +244,15 @@ xfs_ialloc_ag_alloc(
 {
 	xfs_agi_t	*agi;		/* allocation group header */
 	xfs_alloc_arg_t	args;		/* allocation argument structure */
-	int		blks_per_cluster;  /* fs blocks per inode cluster */
 	xfs_btree_cur_t	*cur;		/* inode btree cursor */
-	xfs_daddr_t	d;		/* disk addr of buffer */
 	xfs_agnumber_t	agno;
 	int		error;
-	xfs_buf_t	*fbuf;		/* new free inodes' buffer */
-	xfs_dinode_t	*free;		/* new free inode structure */
-	int		i;		/* inode counter */
-	int		j;		/* block counter */
-	int		nbufs;		/* num bufs of new inodes */
+	int		i;
 	xfs_agino_t	newino;		/* new first inode's number */
 	xfs_agino_t	newlen;		/* new number of inodes */
-	int		ninodes;	/* num inodes per buf */
 	xfs_agino_t	thisino;	/* current inode number, for loop */
-	int		version;	/* inode version number to use */
 	int		isaligned = 0;	/* inode allocation at stripe unit */
 					/* boundary */
-	unsigned int	gen;
 
 	args.tp = tp;
 	args.mp = tp->t_mountp;
@@ -202,12 +273,12 @@ xfs_ialloc_ag_alloc(
  	 */
 	agi = XFS_BUF_TO_AGI(agbp);
 	newino = be32_to_cpu(agi->agi_newino);
+	agno = be32_to_cpu(agi->agi_seqno);
 	args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
 			XFS_IALLOC_BLOCKS(args.mp);
 	if (likely(newino != NULLAGINO &&
 		  (args.agbno < be32_to_cpu(agi->agi_length)))) {
-		args.fsbno = XFS_AGB_TO_FSB(args.mp,
-				be32_to_cpu(agi->agi_seqno), args.agbno);
+		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
 		args.type = XFS_ALLOCTYPE_THIS_BNO;
 		args.mod = args.total = args.wasdel = args.isfl =
 			args.userdata = args.minalignslop = 0;
@@ -258,8 +329,7 @@ xfs_ialloc_ag_alloc(
 		 * For now, just allocate blocks up front.
 		 */
 		args.agbno = be32_to_cpu(agi->agi_root);
-		args.fsbno = XFS_AGB_TO_FSB(args.mp,
-				be32_to_cpu(agi->agi_seqno), args.agbno);
+		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
 		/*
 		 * Allocate a fixed-size extent of inodes.
 		 */
@@ -282,8 +352,7 @@ xfs_ialloc_ag_alloc(
 	if (isaligned && args.fsbno == NULLFSBLOCK) {
 		args.type = XFS_ALLOCTYPE_NEAR_BNO;
 		args.agbno = be32_to_cpu(agi->agi_root);
-		args.fsbno = XFS_AGB_TO_FSB(args.mp,
-				be32_to_cpu(agi->agi_seqno), args.agbno);
+		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
 		args.alignment = xfs_ialloc_cluster_alignment(&args);
 		if ((error = xfs_alloc_vextent(&args)))
 			return error;
@@ -294,85 +363,30 @@ xfs_ialloc_ag_alloc(
 		return 0;
 	}
 	ASSERT(args.len == args.minlen);
-	/*
-	 * Convert the results.
-	 */
-	newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
-	/*
-	 * Loop over the new block(s), filling in the inodes.
-	 * For small block sizes, manipulate the inodes in buffers
-	 * which are multiples of the blocks size.
-	 */
-	if (args.mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(args.mp)) {
-		blks_per_cluster = 1;
-		nbufs = (int)args.len;
-		ninodes = args.mp->m_sb.sb_inopblock;
-	} else {
-		blks_per_cluster = XFS_INODE_CLUSTER_SIZE(args.mp) /
-				   args.mp->m_sb.sb_blocksize;
-		nbufs = (int)args.len / blks_per_cluster;
-		ninodes = blks_per_cluster * args.mp->m_sb.sb_inopblock;
-	}
-	/*
-	 * Figure out what version number to use in the inodes we create.
-	 * If the superblock version has caught up to the one that supports
-	 * the new inode format, then use the new inode version.  Otherwise
-	 * use the old version so that old kernels will continue to be
-	 * able to use the file system.
-	 */
-	if (xfs_sb_version_hasnlink(&args.mp->m_sb))
-		version = 2;
-	else
-		version = 1;
 
 	/*
+	 * Stamp and write the inode buffers.
+	 *
 	 * Seed the new inode cluster with a random generation number. This
 	 * prevents short-term reuse of generation numbers if a chunk is
 	 * freed and then immediately reallocated. We use random numbers
 	 * rather than a linear progression to prevent the next generation
 	 * number from being easily guessable.
 	 */
-	gen = random32();
-	for (j = 0; j < nbufs; j++) {
-		/*
-		 * Get the block.
-		 */
-		d = XFS_AGB_TO_DADDR(args.mp, be32_to_cpu(agi->agi_seqno),
-				     args.agbno + (j * blks_per_cluster));
-		fbuf = xfs_trans_get_buf(tp, args.mp->m_ddev_targp, d,
-					 args.mp->m_bsize * blks_per_cluster,
-					 XFS_BUF_LOCK);
-		ASSERT(fbuf);
-		ASSERT(!XFS_BUF_GETERROR(fbuf));
+	xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno, args.len,
+			      random32());
 
-		/*
-		 * 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 individual
-		 *      transactions causing a lot of log traffic.
-		 */
-		xfs_biozero(fbuf, 0, ninodes << args.mp->m_sb.sb_inodelog);
-		for (i = 0; i < ninodes; i++) {
-			int	ioffset = i << args.mp->m_sb.sb_inodelog;
-			uint	isize = sizeof(struct xfs_dinode);
-
-			free = xfs_make_iptr(args.mp, fbuf, i);
-			free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
-			free->di_version = version;
-			free->di_gen = cpu_to_be32(gen);
-			free->di_next_unlinked = cpu_to_be32(NULLAGINO);
-			xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);
-		}
-		xfs_trans_inode_alloc_buf(tp, fbuf);
-	}
+	/*
+	 * Convert the results.
+	 */
+	newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
 	be32_add_cpu(&agi->agi_count, newlen);
 	be32_add_cpu(&agi->agi_freecount, newlen);
-	agno = be32_to_cpu(agi->agi_seqno);
 	down_read(&args.mp->m_peraglock);
 	args.mp->m_perag[agno].pagi_freecount += newlen;
 	up_read(&args.mp->m_peraglock);
 	agi->agi_newino = cpu_to_be32(newino);
+
 	/*
 	 * Insert records describing the new inode chunk into the btree.
 	 */
@@ -380,13 +394,17 @@ xfs_ialloc_ag_alloc(
 	for (thisino = newino;
 	     thisino < newino + newlen;
 	     thisino += XFS_INODES_PER_CHUNK) {
-		if ((error = xfs_inobt_lookup_eq(cur, thisino,
-				XFS_INODES_PER_CHUNK, XFS_INOBT_ALL_FREE, &i))) {
+		cur->bc_rec.i.ir_startino = thisino;
+		cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK;
+		cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE;
+		error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i);
+		if (error) {
 			xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
 			return error;
 		}
 		ASSERT(i == 0);
-		if ((error = xfs_btree_insert(cur, &i))) {
+		error = xfs_btree_insert(cur, &i);
+		if (error) {
 			xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
 			return error;
 		}
@@ -539,6 +557,62 @@ nextag:
 }
 
 /*
+ * Try to retrieve the next record to the left/right from the current one.
+ */
+STATIC int
+xfs_ialloc_next_rec(
+	struct xfs_btree_cur	*cur,
+	xfs_inobt_rec_incore_t	*rec,
+	int			*done,
+	int			left)
+{
+	int                     error;
+	int			i;
+
+	if (left)
+		error = xfs_btree_decrement(cur, 0, &i);
+	else
+		error = xfs_btree_increment(cur, 0, &i);
+
+	if (error)
+		return error;
+	*done = !i;
+	if (i) {
+		error = xfs_inobt_get_rec(cur, rec, &i);
+		if (error)
+			return error;
+		XFS_WANT_CORRUPTED_RETURN(i == 1);
+	}
+
+	return 0;
+}
+
+STATIC int
+xfs_ialloc_get_rec(
+	struct xfs_btree_cur	*cur,
+	xfs_agino_t		agino,
+	xfs_inobt_rec_incore_t	*rec,
+	int			*done,
+	int			left)
+{
+	int                     error;
+	int			i;
+
+	error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_EQ, &i);
+	if (error)
+		return error;
+	*done = !i;
+	if (i) {
+		error = xfs_inobt_get_rec(cur, rec, &i);
+		if (error)
+			return error;
+		XFS_WANT_CORRUPTED_RETURN(i == 1);
+	}
+
+	return 0;
+}
+
+/*
  * Visible inode allocation functions.
  */
 
@@ -592,8 +666,8 @@ xfs_dialloc(
 	int		j;		/* result code */
 	xfs_mount_t	*mp;		/* file system mount structure */
 	int		offset;		/* index of inode in chunk */
-	xfs_agino_t	pagino;		/* parent's a.g. relative inode # */
-	xfs_agnumber_t	pagno;		/* parent's allocation group number */
+	xfs_agino_t	pagino;		/* parent's AG relative inode # */
+	xfs_agnumber_t	pagno;		/* parent's AG number */
 	xfs_inobt_rec_incore_t rec;	/* inode allocation record */
 	xfs_agnumber_t	tagno;		/* testing allocation group number */
 	xfs_btree_cur_t	*tcur;		/* temp cursor */
@@ -716,6 +790,8 @@ nextag:
 	 */
 	agno = tagno;
 	*IO_agbp = NULL;
+
+ restart_pagno:
 	cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));
 	/*
 	 * If pagino is 0 (this is the root inode allocation) use newino.
@@ -723,220 +799,199 @@ nextag:
 	 */
 	if (!pagino)
 		pagino = be32_to_cpu(agi->agi_newino);
-#ifdef DEBUG
-	if (cur->bc_nlevels == 1) {
-		int	freecount = 0;
 
-		if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-			goto error0;
-		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-		do {
-			if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-					&rec.ir_freecount, &rec.ir_free, &i)))
-				goto error0;
-			XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-			freecount += rec.ir_freecount;
-			if ((error = xfs_btree_increment(cur, 0, &i)))
-				goto error0;
-		} while (i == 1);
+	error = xfs_check_agi_freecount(cur, agi);
+	if (error)
+		goto error0;
 
-		ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-		       XFS_FORCED_SHUTDOWN(mp));
-	}
-#endif
 	/*
-	 * If in the same a.g. as the parent, try to get near the parent.
+	 * If in the same AG as the parent, try to get near the parent.
 	 */
 	if (pagno == agno) {
-		if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i)))
+		xfs_perag_t	*pag = &mp->m_perag[agno];
+		int		doneleft;	/* done, to the left */
+		int		doneright;	/* done, to the right */
+		int		searchdistance = 10;
+
+		error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);
+		if (error)
+			goto error0;
+		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+		error = xfs_inobt_get_rec(cur, &rec, &j);
+		if (error)
 			goto error0;
-		if (i != 0 &&
-		    (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-			    &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
-		    j == 1 &&
-		    rec.ir_freecount > 0) {
+		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+		if (rec.ir_freecount > 0) {
 			/*
 			 * Found a free inode in the same chunk
-			 * as parent, done.
+			 * as the parent, done.
 			 */
+			goto alloc_inode;
 		}
+
+
+		/*
+		 * In the same AG as parent, but parent's chunk is full.
+		 */
+
+		/* duplicate the cursor, search left & right simultaneously */
+		error = xfs_btree_dup_cursor(cur, &tcur);
+		if (error)
+			goto error0;
+
 		/*
-		 * In the same a.g. as parent, but parent's chunk is full.
+		 * Skip to last blocks looked up if same parent inode.
 		 */
-		else {
-			int	doneleft;	/* done, to the left */
-			int	doneright;	/* done, to the right */
+		if (pagino != NULLAGINO &&
+		    pag->pagl_pagino == pagino &&
+		    pag->pagl_leftrec != NULLAGINO &&
+		    pag->pagl_rightrec != NULLAGINO) {
+			error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,
+						   &trec, &doneleft, 1);
+			if (error)
+				goto error1;
 
+			error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,
+						   &rec, &doneright, 0);
 			if (error)
-				goto error0;
-			ASSERT(i == 1);
-			ASSERT(j == 1);
-			/*
-			 * Duplicate the cursor, search left & right
-			 * simultaneously.
-			 */
-			if ((error = xfs_btree_dup_cursor(cur, &tcur)))
-				goto error0;
-			/*
-			 * Search left with tcur, back up 1 record.
-			 */
-			if ((error = xfs_btree_decrement(tcur, 0, &i)))
 				goto error1;
-			doneleft = !i;
-			if (!doneleft) {
-				if ((error = xfs_inobt_get_rec(tcur,
-						&trec.ir_startino,
-						&trec.ir_freecount,
-						&trec.ir_free, &i)))
-					goto error1;
-				XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
-			}
-			/*
-			 * Search right with cur, go forward 1 record.
-			 */
-			if ((error = xfs_btree_increment(cur, 0, &i)))
+		} else {
+			/* search left with tcur, back up 1 record */
+			error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1);
+			if (error)
 				goto error1;
-			doneright = !i;
-			if (!doneright) {
-				if ((error = xfs_inobt_get_rec(cur,
-						&rec.ir_startino,
-						&rec.ir_freecount,
-						&rec.ir_free, &i)))
-					goto error1;
-				XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
-			}
-			/*
-			 * Loop until we find the closest inode chunk
-			 * with a free one.
-			 */
-			while (!doneleft || !doneright) {
-				int	useleft;  /* using left inode
-						     chunk this time */
 
+			/* search right with cur, go forward 1 record. */
+			error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0);
+			if (error)
+				goto error1;
+		}
+
+		/*
+		 * Loop until we find an inode chunk with a free inode.
+		 */
+		while (!doneleft || !doneright) {
+			int	useleft;  /* using left inode chunk this time */
+
+			if (!--searchdistance) {
 				/*
-				 * Figure out which block is closer,
-				 * if both are valid.
-				 */
-				if (!doneleft && !doneright)
-					useleft =
-						pagino -
-						(trec.ir_startino +
-						 XFS_INODES_PER_CHUNK - 1) <
-						 rec.ir_startino - pagino;
-				else
-					useleft = !doneleft;
-				/*
-				 * If checking the left, does it have
-				 * free inodes?
-				 */
-				if (useleft && trec.ir_freecount) {
-					/*
-					 * Yes, set it up as the chunk to use.
-					 */
-					rec = trec;
-					xfs_btree_del_cursor(cur,
-						XFS_BTREE_NOERROR);
-					cur = tcur;
-					break;
-				}
-				/*
-				 * If checking the right, does it have
-				 * free inodes?
-				 */
-				if (!useleft && rec.ir_freecount) {
-					/*
-					 * Yes, it's already set up.
-					 */
-					xfs_btree_del_cursor(tcur,
-						XFS_BTREE_NOERROR);
-					break;
-				}
-				/*
-				 * If used the left, get another one
-				 * further left.
-				 */
-				if (useleft) {
-					if ((error = xfs_btree_decrement(tcur, 0,
-							&i)))
-						goto error1;
-					doneleft = !i;
-					if (!doneleft) {
-						if ((error = xfs_inobt_get_rec(
-							    tcur,
-							    &trec.ir_startino,
-							    &trec.ir_freecount,
-							    &trec.ir_free, &i)))
-							goto error1;
-						XFS_WANT_CORRUPTED_GOTO(i == 1,
-							error1);
-					}
-				}
-				/*
-				 * If used the right, get another one
-				 * further right.
+				 * Not in range - save last search
+				 * location and allocate a new inode
 				 */
-				else {
-					if ((error = xfs_btree_increment(cur, 0,
-							&i)))
-						goto error1;
-					doneright = !i;
-					if (!doneright) {
-						if ((error = xfs_inobt_get_rec(
-							    cur,
-							    &rec.ir_startino,
-							    &rec.ir_freecount,
-							    &rec.ir_free, &i)))
-							goto error1;
-						XFS_WANT_CORRUPTED_GOTO(i == 1,
-							error1);
-					}
-				}
+				pag->pagl_leftrec = trec.ir_startino;
+				pag->pagl_rightrec = rec.ir_startino;
+				pag->pagl_pagino = pagino;
+				goto newino;
+			}
+
+			/* figure out the closer block if both are valid. */
+			if (!doneleft && !doneright) {
+				useleft = pagino -
+				 (trec.ir_startino + XFS_INODES_PER_CHUNK - 1) <
+				  rec.ir_startino - pagino;
+			} else {
+				useleft = !doneleft;
 			}
-			ASSERT(!doneleft || !doneright);
+
+			/* free inodes to the left? */
+			if (useleft && trec.ir_freecount) {
+				rec = trec;
+				xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
+				cur = tcur;
+
+				pag->pagl_leftrec = trec.ir_startino;
+				pag->pagl_rightrec = rec.ir_startino;
+				pag->pagl_pagino = pagino;
+				goto alloc_inode;
+			}
+
+			/* free inodes to the right? */
+			if (!useleft && rec.ir_freecount) {
+				xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
+
+				pag->pagl_leftrec = trec.ir_startino;
+				pag->pagl_rightrec = rec.ir_startino;
+				pag->pagl_pagino = pagino;
+				goto alloc_inode;
+			}
+
+			/* get next record to check */
+			if (useleft) {
+				error = xfs_ialloc_next_rec(tcur, &trec,
+								 &doneleft, 1);
+			} else {
+				error = xfs_ialloc_next_rec(cur, &rec,
+								 &doneright, 0);
+			}
+			if (error)
+				goto error1;
 		}
+
+		/*
+		 * We've reached the end of the btree. because
+		 * we are only searching a small chunk of the
+		 * btree each search, there is obviously free
+		 * inodes closer to the parent inode than we
+		 * are now. restart the search again.
+		 */
+		pag->pagl_pagino = NULLAGINO;
+		pag->pagl_leftrec = NULLAGINO;
+		pag->pagl_rightrec = NULLAGINO;
+		xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
+		xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
+		goto restart_pagno;
 	}
+
 	/*
-	 * In a different a.g. from the parent.
+	 * In a different AG from the parent.
 	 * See if the most recently allocated block has any free.
 	 */
-	else if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {
-		if ((error = xfs_inobt_lookup_eq(cur,
-				be32_to_cpu(agi->agi_newino), 0, 0, &i)))
+newino:
+	if (be32_to_cpu(agi->agi_newino) != NULLAGINO) {
+		error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
+					 XFS_LOOKUP_EQ, &i);
+		if (error)
 			goto error0;
-		if (i == 1 &&
-		    (error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-			    &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
-		    j == 1 &&
-		    rec.ir_freecount > 0) {
-			/*
-			 * The last chunk allocated in the group still has
-			 * a free inode.
-			 */
-		}
-		/*
-		 * None left in the last group, search the whole a.g.
-		 */
-		else {
+
+		if (i == 1) {
+			error = xfs_inobt_get_rec(cur, &rec, &j);
 			if (error)
 				goto error0;
-			if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-				goto error0;
-			ASSERT(i == 1);
-			for (;;) {
-				if ((error = xfs_inobt_get_rec(cur,
-						&rec.ir_startino,
-						&rec.ir_freecount, &rec.ir_free,
-						&i)))
-					goto error0;
-				XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-				if (rec.ir_freecount > 0)
-					break;
-				if ((error = xfs_btree_increment(cur, 0, &i)))
-					goto error0;
-				XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+			if (j == 1 && rec.ir_freecount > 0) {
+				/*
+				 * The last chunk allocated in the group
+				 * still has a free inode.
+				 */
+				goto alloc_inode;
 			}
 		}
 	}
+
+	/*
+	 * None left in the last group, search the whole AG
+	 */
+	error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
+	if (error)
+		goto error0;
+	XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+
+	for (;;) {
+		error = xfs_inobt_get_rec(cur, &rec, &i);
+		if (error)
+			goto error0;
+		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+		if (rec.ir_freecount > 0)
+			break;
+		error = xfs_btree_increment(cur, 0, &i);
+		if (error)
+			goto error0;
+		XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
+	}
+
+alloc_inode:
 	offset = xfs_ialloc_find_free(&rec.ir_free);
 	ASSERT(offset >= 0);
 	ASSERT(offset < XFS_INODES_PER_CHUNK);
@@ -945,33 +1000,19 @@ nextag:
 	ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + 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)))
+	error = xfs_inobt_update(cur, &rec);
+	if (error)
 		goto error0;
 	be32_add_cpu(&agi->agi_freecount, -1);
 	xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
 	down_read(&mp->m_peraglock);
 	mp->m_perag[tagno].pagi_freecount--;
 	up_read(&mp->m_peraglock);
-#ifdef DEBUG
-	if (cur->bc_nlevels == 1) {
-		int	freecount = 0;
 
-		if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-			goto error0;
-		do {
-			if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-					&rec.ir_freecount, &rec.ir_free, &i)))
-				goto error0;
-			XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-			freecount += rec.ir_freecount;
-			if ((error = xfs_btree_increment(cur, 0, &i)))
-				goto error0;
-		} while (i == 1);
-		ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-		       XFS_FORCED_SHUTDOWN(mp));
-	}
-#endif
+	error = xfs_check_agi_freecount(cur, agi);
+	if (error)
+		goto error0;
+
 	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
 	xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
 	*inop = ino;
@@ -1062,38 +1103,23 @@ xfs_difree(
 	 * Initialize the cursor.
 	 */
 	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
-#ifdef DEBUG
-	if (cur->bc_nlevels == 1) {
-		int freecount = 0;
 
-		if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-			goto error0;
-		do {
-			if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino,
-					&rec.ir_freecount, &rec.ir_free, &i)))
-				goto error0;
-			if (i) {
-				freecount += rec.ir_freecount;
-				if ((error = xfs_btree_increment(cur, 0, &i)))
-					goto error0;
-			}
-		} while (i == 1);
-		ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-		       XFS_FORCED_SHUTDOWN(mp));
-	}
-#endif
+	error = xfs_check_agi_freecount(cur, agi);
+	if (error)
+		goto error0;
+
 	/*
 	 * Look for the entry describing this inode.
 	 */
-	if ((error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i))) {
+	if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) {
 		cmn_err(CE_WARN,
-			"xfs_difree: xfs_inobt_lookup_le returned()  an error %d on %s.  Returning error.",
+			"xfs_difree: xfs_inobt_lookup returned()  an error %d on %s.  Returning error.",
 			error, mp->m_fsname);
 		goto error0;
 	}
 	XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-	if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, &rec.ir_freecount,
-			&rec.ir_free, &i))) {
+	error = xfs_inobt_get_rec(cur, &rec, &i);
+	if (error) {
 		cmn_err(CE_WARN,
 			"xfs_difree: xfs_inobt_get_rec()  returned an error %d on %s.  Returning error.",
 			error, mp->m_fsname);
@@ -1148,12 +1174,14 @@ xfs_difree(
 	} else {
 		*delete = 0;
 
-		if ((error = xfs_inobt_update(cur, rec.ir_startino, rec.ir_freecount, rec.ir_free))) {
+		error = xfs_inobt_update(cur, &rec);
+		if (error) {
 			cmn_err(CE_WARN,
-				"xfs_difree: xfs_inobt_update()  returned an error %d on %s.  Returning error.",
+	"xfs_difree: xfs_inobt_update returned an error %d on %s.",
 				error, mp->m_fsname);
 			goto error0;
 		}
+
 		/* 
 		 * Change the inode free counts and log the ag/sb changes.
 		 */
@@ -1165,28 +1193,10 @@ xfs_difree(
 		xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
 	}
 
-#ifdef DEBUG
-	if (cur->bc_nlevels == 1) {
-		int freecount = 0;
+	error = xfs_check_agi_freecount(cur, agi);
+	if (error)
+		goto error0;
 
-		if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
-			goto error0;
-		do {
-			if ((error = xfs_inobt_get_rec(cur,
-					&rec.ir_startino,
-					&rec.ir_freecount,
-					&rec.ir_free, &i)))
-				goto error0;
-			if (i) {
-				freecount += rec.ir_freecount;
-				if ((error = xfs_btree_increment(cur, 0, &i)))
-					goto error0;
-			}
-		} while (i == 1);
-		ASSERT(freecount == be32_to_cpu(agi->agi_freecount) ||
-		       XFS_FORCED_SHUTDOWN(mp));
-	}
-#endif
 	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
 	return 0;
 
@@ -1297,9 +1307,7 @@ xfs_imap(
 		chunk_agbno = agbno - offset_agbno;
 	} else {
 		xfs_btree_cur_t	*cur;	/* inode btree cursor */
-		xfs_agino_t	chunk_agino; /* first agino in inode chunk */
-		__int32_t	chunk_cnt; /* count of free inodes in chunk */
-		xfs_inofree_t	chunk_free; /* mask of free inodes in chunk */
+		xfs_inobt_rec_incore_t chunk_rec;
 		xfs_buf_t	*agbp;	/* agi buffer */
 		int		i;	/* temp state */
 
@@ -1315,15 +1323,14 @@ xfs_imap(
 		}
 
 		cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
-		error = xfs_inobt_lookup_le(cur, agino, 0, 0, &i);
+		error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
 		if (error) {
 			xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
-					"xfs_inobt_lookup_le() failed");
+					"xfs_inobt_lookup() failed");
 			goto error0;
 		}
 
-		error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt,
-				&chunk_free, &i);
+		error = xfs_inobt_get_rec(cur, &chunk_rec, &i);
 		if (error) {
 			xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
 					"xfs_inobt_get_rec() failed");
@@ -1341,7 +1348,7 @@ xfs_imap(
 		xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
 		if (error)
 			return error;
-		chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino);
+		chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino);
 		offset_agbno = agbno - chunk_agbno;
 	}
 
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h
index aeee827..bb53854 100644
--- a/fs/xfs/xfs_ialloc.h
+++ b/fs/xfs/xfs_ialloc.h
@@ -150,23 +150,15 @@ xfs_ialloc_pagi_init(
         xfs_agnumber_t  agno);		/* allocation group number */
 
 /*
- * Lookup the first record greater than or equal to ino
- * in the btree given by cur.
+ * Lookup a record by ino in the btree given by cur.
  */
-int xfs_inobt_lookup_ge(struct xfs_btree_cur *cur, xfs_agino_t ino,
-		__int32_t fcnt,	xfs_inofree_t free, int *stat);
-
-/*
- * Lookup the first record less than or equal to ino
- * in the btree given by cur.
- */
-int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino,
-		__int32_t fcnt,	xfs_inofree_t free, int *stat);
+int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,
+		xfs_lookup_t dir, int *stat);
 
 /*
  * Get the data from the pointed-to record.
  */
-extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino,
-			     __int32_t *fcnt, xfs_inofree_t *free, int *stat);
+extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur,
+		xfs_inobt_rec_incore_t *rec, int *stat);
 
 #endif	/* __XFS_IALLOC_H__ */
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index ecbf8b4..80e5264 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -82,7 +82,6 @@ xfs_inode_alloc(
 	memset(&ip->i_df, 0, sizeof(xfs_ifork_t));
 	ip->i_flags = 0;
 	ip->i_update_core = 0;
-	ip->i_update_size = 0;
 	ip->i_delayed_blks = 0;
 	memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
 	ip->i_size = 0;
@@ -456,32 +455,6 @@ out_error_or_again:
 	return error;
 }
 
-
-/*
- * Look for the inode corresponding to the given ino in the hash table.
- * If it is there and its i_transp pointer matches tp, return it.
- * Otherwise, return NULL.
- */
-xfs_inode_t *
-xfs_inode_incore(xfs_mount_t	*mp,
-		 xfs_ino_t	ino,
-		 xfs_trans_t	*tp)
-{
-	xfs_inode_t	*ip;
-	xfs_perag_t	*pag;
-
-	pag = xfs_get_perag(mp, ino);
-	read_lock(&pag->pag_ici_lock);
-	ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ino));
-	read_unlock(&pag->pag_ici_lock);
-	xfs_put_perag(mp, pag);
-
-	/* the returned inode must match the transaction */
-	if (ip && (ip->i_transp != tp))
-		return NULL;
-	return ip;
-}
-
 /*
  * Decrement reference count of an inode structure and unlock it.
  *
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index da428b3..c1dc7ef 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -651,7 +651,7 @@ xfs_iformat_btree(
 	return 0;
 }
 
-void
+STATIC void
 xfs_dinode_from_disk(
 	xfs_icdinode_t		*to,
 	xfs_dinode_t		*from)
@@ -1247,7 +1247,7 @@ xfs_isize_check(
  * In that case the pages will still be in memory, but the inode size
  * will never have been updated.
  */
-xfs_fsize_t
+STATIC xfs_fsize_t
 xfs_file_last_byte(
 	xfs_inode_t	*ip)
 {
@@ -3837,7 +3837,7 @@ xfs_iext_inline_to_direct(
 /*
  * Resize an extent indirection array to new_size bytes.
  */
-void
+STATIC void
 xfs_iext_realloc_indirect(
 	xfs_ifork_t	*ifp,		/* inode fork pointer */
 	int		new_size)	/* new indirection array size */
@@ -3862,7 +3862,7 @@ xfs_iext_realloc_indirect(
 /*
  * Switch from indirection array to linear (direct) extent allocations.
  */
-void
+STATIC void
 xfs_iext_indirect_to_direct(
 	 xfs_ifork_t	*ifp)		/* inode fork pointer */
 {
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 65f24a3..0b38b9a 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -261,7 +261,6 @@ typedef struct xfs_inode {
 	/* Miscellaneous state. */
 	unsigned short		i_flags;	/* see defined flags below */
 	unsigned char		i_update_core;	/* timestamps/size is dirty */
-	unsigned char		i_update_size;	/* di_size field is dirty */
 	unsigned int		i_delayed_blks;	/* count of delay alloc blks */
 
 	xfs_icdinode_t		i_d;		/* most of ondisk inode */
@@ -468,8 +467,6 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
 /*
  * xfs_iget.c prototypes.
  */
-xfs_inode_t	*xfs_inode_incore(struct xfs_mount *, xfs_ino_t,
-				  struct xfs_trans *);
 int		xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
 			 uint, uint, xfs_inode_t **, xfs_daddr_t);
 void		xfs_iput(xfs_inode_t *, uint);
@@ -504,7 +501,6 @@ void		xfs_ipin(xfs_inode_t *);
 void		xfs_iunpin(xfs_inode_t *);
 int		xfs_iflush(xfs_inode_t *, uint);
 void		xfs_ichgtime(xfs_inode_t *, int);
-xfs_fsize_t	xfs_file_last_byte(xfs_inode_t *);
 void		xfs_lock_inodes(xfs_inode_t **, int, uint);
 void		xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
 
@@ -572,8 +568,6 @@ int		xfs_itobp(struct xfs_mount *, struct xfs_trans *,
 			  struct xfs_buf **, uint);
 int		xfs_iread(struct xfs_mount *, struct xfs_trans *,
 			  struct xfs_inode *, xfs_daddr_t, uint);
-void		xfs_dinode_from_disk(struct xfs_icdinode *,
-				     struct xfs_dinode *);
 void		xfs_dinode_to_disk(struct xfs_dinode *,
 				   struct xfs_icdinode *);
 void		xfs_idestroy_fork(struct xfs_inode *, int);
@@ -592,8 +586,6 @@ void		xfs_iext_remove_inline(xfs_ifork_t *, xfs_extnum_t, int);
 void		xfs_iext_remove_direct(xfs_ifork_t *, xfs_extnum_t, int);
 void		xfs_iext_remove_indirect(xfs_ifork_t *, xfs_extnum_t, int);
 void		xfs_iext_realloc_direct(xfs_ifork_t *, int);
-void		xfs_iext_realloc_indirect(xfs_ifork_t *, int);
-void		xfs_iext_indirect_to_direct(xfs_ifork_t *);
 void		xfs_iext_direct_to_inline(xfs_ifork_t *, xfs_extnum_t);
 void		xfs_iext_inline_to_direct(xfs_ifork_t *, int);
 void		xfs_iext_destroy(xfs_ifork_t *);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 977c4ae..47d5b66 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -263,14 +263,6 @@ xfs_inode_item_format(
 	}
 
 	/*
-	 * We don't have to worry about re-ordering here because
-	 * the update_size field is protected by the inode lock
-	 * and we have that held in exclusive mode.
-	 */
-	if (ip->i_update_size)
-		ip->i_update_size = 0;
-
-	/*
 	 * Make sure to get the latest atime from the Linux inode.
 	 */
 	xfs_synchronize_atime(ip);
@@ -712,8 +704,6 @@ xfs_inode_item_unlock(
 	 * Clear out the fields of the inode log item particular
 	 * to the current transaction.
 	 */
-	iip->ili_ilock_recur = 0;
-	iip->ili_iolock_recur = 0;
 	iip->ili_flags = 0;
 
 	/*
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index a52ac12..65bae4c 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -137,8 +137,6 @@ typedef struct xfs_inode_log_item {
 	struct xfs_inode	*ili_inode;	   /* inode ptr */
 	xfs_lsn_t		ili_flush_lsn;	   /* lsn at last flush */
 	xfs_lsn_t		ili_last_lsn;	   /* lsn at last transaction */
-	unsigned short		ili_ilock_recur;   /* lock recursion count */
-	unsigned short		ili_iolock_recur;  /* lock recursion count */
 	unsigned short		ili_flags;	   /* misc flags */
 	unsigned short		ili_logged;	   /* flushed logged data */
 	unsigned int		ili_last_fields;   /* fields when flushed */
diff --git a/fs/xfs/xfs_inum.h b/fs/xfs/xfs_inum.h
index 7a28191..b8e4ee4 100644
--- a/fs/xfs/xfs_inum.h
+++ b/fs/xfs/xfs_inum.h
@@ -72,7 +72,6 @@ struct xfs_mount;
 
 #if XFS_BIG_INUMS
 #define	XFS_MAXINUMBER		((xfs_ino_t)((1ULL << 56) - 1ULL))
-#define	XFS_INO64_OFFSET	((xfs_ino_t)(1ULL << 32))
 #else
 #define	XFS_MAXINUMBER		((xfs_ino_t)((1ULL << 32) - 1ULL))
 #endif
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index aeb2d22..b68f910 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -39,7 +39,7 @@
 #include "xfs_error.h"
 #include "xfs_btree.h"
 
-int
+STATIC int
 xfs_internal_inum(
 	xfs_mount_t	*mp,
 	xfs_ino_t	ino)
@@ -353,9 +353,6 @@ xfs_bulkstat(
 	int			end_of_ag; /* set if we've seen the ag end */
 	int			error;	/* error code */
 	int                     fmterror;/* bulkstat formatter result */
-	__int32_t		gcnt;	/* current btree rec's count */
-	xfs_inofree_t		gfree;	/* current btree rec's free mask */
-	xfs_agino_t		gino;	/* current btree rec's start inode */
 	int			i;	/* loop index */
 	int			icount;	/* count of inodes good in irbuf */
 	size_t			irbsize; /* size of irec buffer in bytes */
@@ -442,40 +439,43 @@ xfs_bulkstat(
 		 * we need to get the remainder of the chunk we're in.
 		 */
 		if (agino > 0) {
+			xfs_inobt_rec_incore_t r;
+
 			/*
 			 * Lookup the inode chunk that this inode lives in.
 			 */
-			error = xfs_inobt_lookup_le(cur, agino, 0, 0, &tmp);
+			error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE,
+						 &tmp);
 			if (!error &&	/* no I/O error */
 			    tmp &&	/* lookup succeeded */
 					/* got the record, should always work */
-			    !(error = xfs_inobt_get_rec(cur, &gino, &gcnt,
-				    &gfree, &i)) &&
+			    !(error = xfs_inobt_get_rec(cur, &r, &i)) &&
 			    i == 1 &&
 					/* this is the right chunk */
-			    agino < gino + XFS_INODES_PER_CHUNK &&
+			    agino < r.ir_startino + XFS_INODES_PER_CHUNK &&
 					/* lastino was not last in chunk */
-			    (chunkidx = agino - gino + 1) <
+			    (chunkidx = agino - r.ir_startino + 1) <
 				    XFS_INODES_PER_CHUNK &&
 					/* there are some left allocated */
 			    xfs_inobt_maskn(chunkidx,
-				    XFS_INODES_PER_CHUNK - chunkidx) & ~gfree) {
+				    XFS_INODES_PER_CHUNK - chunkidx) &
+				    ~r.ir_free) {
 				/*
 				 * Grab the chunk record.  Mark all the
 				 * uninteresting inodes (because they're
 				 * before our start point) free.
 				 */
 				for (i = 0; i < chunkidx; i++) {
-					if (XFS_INOBT_MASK(i) & ~gfree)
-						gcnt++;
+					if (XFS_INOBT_MASK(i) & ~r.ir_free)
+						r.ir_freecount++;
 				}
-				gfree |= xfs_inobt_maskn(0, chunkidx);
-				irbp->ir_startino = gino;
-				irbp->ir_freecount = gcnt;
-				irbp->ir_free = gfree;
+				r.ir_free |= xfs_inobt_maskn(0, chunkidx);
+				irbp->ir_startino = r.ir_startino;
+				irbp->ir_freecount = r.ir_freecount;
+				irbp->ir_free = r.ir_free;
 				irbp++;
-				agino = gino + XFS_INODES_PER_CHUNK;
-				icount = XFS_INODES_PER_CHUNK - gcnt;
+				agino = r.ir_startino + XFS_INODES_PER_CHUNK;
+				icount = XFS_INODES_PER_CHUNK - r.ir_freecount;
 			} else {
 				/*
 				 * If any of those tests failed, bump the
@@ -493,7 +493,7 @@ xfs_bulkstat(
 			/*
 			 * Start of ag.  Lookup the first inode chunk.
 			 */
-			error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &tmp);
+			error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &tmp);
 			icount = 0;
 		}
 		/*
@@ -501,6 +501,8 @@ xfs_bulkstat(
 		 * until we run out of inodes or space in the buffer.
 		 */
 		while (irbp < irbufend && icount < ubcount) {
+			xfs_inobt_rec_incore_t r;
+
 			/*
 			 * Loop as long as we're unable to read the
 			 * inode btree.
@@ -510,51 +512,55 @@ xfs_bulkstat(
 				if (XFS_AGINO_TO_AGBNO(mp, agino) >=
 						be32_to_cpu(agi->agi_length))
 					break;
-				error = xfs_inobt_lookup_ge(cur, agino, 0, 0,
-							    &tmp);
+				error = xfs_inobt_lookup(cur, agino,
+							 XFS_LOOKUP_GE, &tmp);
 				cond_resched();
 			}
 			/*
 			 * If ran off the end of the ag either with an error,
 			 * or the normal way, set end and stop collecting.
 			 */
-			if (error ||
-			    (error = xfs_inobt_get_rec(cur, &gino, &gcnt,
-				    &gfree, &i)) ||
-			    i == 0) {
+			if (error) {
 				end_of_ag = 1;
 				break;
 			}
+
+			error = xfs_inobt_get_rec(cur, &r, &i);
+			if (error || i == 0) {
+				end_of_ag = 1;
+				break;
+			}
+
 			/*
 			 * If this chunk has any allocated inodes, save it.
 			 * Also start read-ahead now for this chunk.
 			 */
-			if (gcnt < XFS_INODES_PER_CHUNK) {
+			if (r.ir_freecount < XFS_INODES_PER_CHUNK) {
 				/*
 				 * Loop over all clusters in the next chunk.
 				 * Do a readahead if there are any allocated
 				 * inodes in that cluster.
 				 */
-				for (agbno = XFS_AGINO_TO_AGBNO(mp, gino),
-				     chunkidx = 0;
+				agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino);
+				for (chunkidx = 0;
 				     chunkidx < XFS_INODES_PER_CHUNK;
 				     chunkidx += nicluster,
 				     agbno += nbcluster) {
-					if (xfs_inobt_maskn(chunkidx,
-							    nicluster) & ~gfree)
+					if (xfs_inobt_maskn(chunkidx, nicluster)
+							& ~r.ir_free)
 						xfs_btree_reada_bufs(mp, agno,
 							agbno, nbcluster);
 				}
-				irbp->ir_startino = gino;
-				irbp->ir_freecount = gcnt;
-				irbp->ir_free = gfree;
+				irbp->ir_startino = r.ir_startino;
+				irbp->ir_freecount = r.ir_freecount;
+				irbp->ir_free = r.ir_free;
 				irbp++;
-				icount += XFS_INODES_PER_CHUNK - gcnt;
+				icount += XFS_INODES_PER_CHUNK - r.ir_freecount;
 			}
 			/*
 			 * Set agino to after this chunk and bump the cursor.
 			 */
-			agino = gino + XFS_INODES_PER_CHUNK;
+			agino = r.ir_startino + XFS_INODES_PER_CHUNK;
 			error = xfs_btree_increment(cur, 0, &tmp);
 			cond_resched();
 		}
@@ -820,9 +826,7 @@ xfs_inumbers(
 	int		bufidx;
 	xfs_btree_cur_t	*cur;
 	int		error;
-	__int32_t	gcnt;
-	xfs_inofree_t	gfree;
-	xfs_agino_t	gino;
+	xfs_inobt_rec_incore_t r;
 	int		i;
 	xfs_ino_t	ino;
 	int		left;
@@ -855,7 +859,8 @@ xfs_inumbers(
 				continue;
 			}
 			cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno);
-			error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp);
+			error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE,
+						 &tmp);
 			if (error) {
 				xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
 				cur = NULL;
@@ -870,9 +875,8 @@ xfs_inumbers(
 				continue;
 			}
 		}
-		if ((error = xfs_inobt_get_rec(cur, &gino, &gcnt, &gfree,
-			&i)) ||
-		    i == 0) {
+		error = xfs_inobt_get_rec(cur, &r, &i);
+		if (error || i == 0) {
 			xfs_buf_relse(agbp);
 			agbp = NULL;
 			xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
@@ -881,10 +885,12 @@ xfs_inumbers(
 			agino = 0;
 			continue;
 		}
-		agino = gino + XFS_INODES_PER_CHUNK - 1;
-		buffer[bufidx].xi_startino = XFS_AGINO_TO_INO(mp, agno, gino);
-		buffer[bufidx].xi_alloccount = XFS_INODES_PER_CHUNK - gcnt;
-		buffer[bufidx].xi_allocmask = ~gfree;
+		agino = r.ir_startino + XFS_INODES_PER_CHUNK - 1;
+		buffer[bufidx].xi_startino =
+			XFS_AGINO_TO_INO(mp, agno, r.ir_startino);
+		buffer[bufidx].xi_alloccount =
+			XFS_INODES_PER_CHUNK - r.ir_freecount;
+		buffer[bufidx].xi_allocmask = ~r.ir_free;
 		bufidx++;
 		left--;
 		if (bufidx == bcount) {
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 1fb04e7..20792bf 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -99,11 +99,6 @@ xfs_bulkstat_one(
 	void			*dibuff,
 	int			*stat);
 
-int
-xfs_internal_inum(
-	xfs_mount_t		*mp,
-	xfs_ino_t		ino);
-
 typedef int (*inumbers_fmt_pf)(
 	void			__user *ubuffer, /* buffer to write to */
 	const xfs_inogrp_t	*buffer,	/* buffer to read from */
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index bcad5f4..679c7c4 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -451,8 +451,6 @@ extern int	 xlog_find_tail(xlog_t	*log,
 extern int	 xlog_recover(xlog_t *log);
 extern int	 xlog_recover_finish(xlog_t *log);
 extern void	 xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
-extern void	 xlog_recover_process_iunlinks(xlog_t *log);
-
 extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
 extern void	 xlog_put_bp(struct xfs_buf *);
 
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 47da2fb..1099395 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3263,7 +3263,7 @@ xlog_recover_process_one_iunlink(
  * freeing of the inode and its removal from the list must be
  * atomic.
  */
-void
+STATIC void
 xlog_recover_process_iunlinks(
 	xlog_t		*log)
 {
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 5c6f092..8b6c9e8 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1568,7 +1568,7 @@ xfs_mod_sb(xfs_trans_t *tp, __int64_t fields)
  *
  * The m_sb_lock must be held when this routine is called.
  */
-int
+STATIC int
 xfs_mod_incore_sb_unlocked(
 	xfs_mount_t	*mp,
 	xfs_sb_field_t	field,
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a512238..a6c023b 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -414,13 +414,10 @@ typedef struct xfs_mod_sb {
 
 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);
 
 extern void	xfs_unmountfs(xfs_mount_t *);
 extern int	xfs_unmountfs_writesb(xfs_mount_t *);
 extern int	xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int);
-extern int	xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,
-			int64_t, int);
 extern int	xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
 			uint, int);
 extern int	xfs_mount_log_sb(xfs_mount_t *, __int64_t);
diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c
index afee7eb..4b0613d 100644
--- a/fs/xfs/xfs_mru_cache.c
+++ b/fs/xfs/xfs_mru_cache.c
@@ -564,35 +564,6 @@ xfs_mru_cache_lookup(
 }
 
 /*
- * To look up an element using its key, but leave its location in the internal
- * lists alone, call xfs_mru_cache_peek().  If the element isn't found, this
- * function returns NULL.
- *
- * See the comments above the declaration of the xfs_mru_cache_lookup() function
- * for important locking information pertaining to this call.
- */
-void *
-xfs_mru_cache_peek(
-	xfs_mru_cache_t	*mru,
-	unsigned long	key)
-{
-	xfs_mru_cache_elem_t *elem;
-
-	ASSERT(mru && mru->lists);
-	if (!mru || !mru->lists)
-		return NULL;
-
-	spin_lock(&mru->lock);
-	elem = radix_tree_lookup(&mru->store, key);
-	if (!elem)
-		spin_unlock(&mru->lock);
-	else
-		__release(mru_lock); /* help sparse not be stupid */
-
-	return elem ? elem->value : NULL;
-}
-
-/*
  * To release the internal data structure spinlock after having performed an
  * xfs_mru_cache_lookup() or an xfs_mru_cache_peek(), call xfs_mru_cache_done()
  * with the data store pointer.
diff --git a/fs/xfs/xfs_mru_cache.h b/fs/xfs/xfs_mru_cache.h
index dd58ea1..5d439f3 100644
--- a/fs/xfs/xfs_mru_cache.h
+++ b/fs/xfs/xfs_mru_cache.h
@@ -49,7 +49,6 @@ int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key,
 void * xfs_mru_cache_remove(struct xfs_mru_cache *mru, unsigned long key);
 void xfs_mru_cache_delete(struct xfs_mru_cache *mru, unsigned long key);
 void *xfs_mru_cache_lookup(struct xfs_mru_cache *mru, unsigned long key);
-void *xfs_mru_cache_peek(struct xfs_mru_cache *mru, unsigned long key);
 void xfs_mru_cache_done(struct xfs_mru_cache *mru);
 
 #endif /* __XFS_MRU_CACHE_H__ */
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index fea6861..3f816ad 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -88,90 +88,6 @@ xfs_write_clear_setuid(
 }
 
 /*
- * Handle logging requirements of various synchronous types of write.
- */
-int
-xfs_write_sync_logforce(
-	xfs_mount_t	*mp,
-	xfs_inode_t	*ip)
-{
-	int		error = 0;
-
-	/*
-	 * If we're treating this as O_DSYNC and we have not updated the
-	 * size, force the log.
-	 */
-	if (!(mp->m_flags & XFS_MOUNT_OSYNCISOSYNC) &&
-	    !(ip->i_update_size)) {
-		xfs_inode_log_item_t	*iip = ip->i_itemp;
-
-		/*
-		 * If an allocation transaction occurred
-		 * without extending the size, then we have to force
-		 * the log up the proper point to ensure that the
-		 * allocation is permanent.  We can't count on
-		 * the fact that buffered writes lock out direct I/O
-		 * writes - the direct I/O write could have extended
-		 * the size nontransactionally, then finished before
-		 * we started.  xfs_write_file will think that the file
-		 * didn't grow but the update isn't safe unless the
-		 * size change is logged.
-		 *
-		 * Force the log if we've committed a transaction
-		 * against the inode or if someone else has and
-		 * the commit record hasn't gone to disk (e.g.
-		 * the inode is pinned).  This guarantees that
-		 * all changes affecting the inode are permanent
-		 * when we return.
-		 */
-		if (iip && iip->ili_last_lsn) {
-			error = _xfs_log_force(mp, iip->ili_last_lsn,
-					XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);
-		} else if (xfs_ipincount(ip) > 0) {
-			error = _xfs_log_force(mp, (xfs_lsn_t)0,
-					XFS_LOG_FORCE | XFS_LOG_SYNC, NULL);
-		}
-
-	} else {
-		xfs_trans_t	*tp;
-
-		/*
-		 * O_SYNC or O_DSYNC _with_ a size update are handled
-		 * the same way.
-		 *
-		 * If the write was synchronous then we need to make
-		 * sure that the inode modification time is permanent.
-		 * We'll have updated the timestamp above, so here
-		 * we use a synchronous transaction to log the inode.
-		 * It's not fast, but it's necessary.
-		 *
-		 * If this a dsync write and the size got changed
-		 * non-transactionally, then we need to ensure that
-		 * the size change gets logged in a synchronous
-		 * transaction.
-		 */
-		tp = xfs_trans_alloc(mp, XFS_TRANS_WRITE_SYNC);
-		if ((error = xfs_trans_reserve(tp, 0,
-						XFS_SWRITE_LOG_RES(mp),
-						0, 0, 0))) {
-			/* Transaction reserve failed */
-			xfs_trans_cancel(tp, 0);
-		} else {
-			/* Transaction reserve successful */
-			xfs_ilock(ip, XFS_ILOCK_EXCL);
-			xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
-			xfs_trans_ihold(tp, ip);
-			xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-			xfs_trans_set_sync(tp);
-			error = xfs_trans_commit(tp, 0);
-			xfs_iunlock(ip, XFS_ILOCK_EXCL);
-		}
-	}
-
-	return error;
-}
-
-/*
  * Force a shutdown of the filesystem instantly while keeping
  * the filesystem consistent. We don't do an unmount here; just shutdown
  * the shop, make sure that absolutely nothing persistent happens to
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h
index f76c003..f5e4874 100644
--- a/fs/xfs/xfs_rw.h
+++ b/fs/xfs/xfs_rw.h
@@ -68,7 +68,6 @@ xfs_get_extsz_hint(
  * Prototypes for functions in xfs_rw.c.
  */
 extern int xfs_write_clear_setuid(struct xfs_inode *ip);
-extern int xfs_write_sync_logforce(struct xfs_mount *mp, struct xfs_inode *ip);
 extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp);
 extern int xfs_bioerror(struct xfs_buf *bp);
 extern int xfs_bioerror_relse(struct xfs_buf *bp);
@@ -78,10 +77,4 @@ extern int xfs_read_buf(struct xfs_mount *mp, xfs_buftarg_t *btp,
 extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp,
 				xfs_buf_t *bp, xfs_daddr_t blkno);
 
-/*
- * Prototypes for functions in xfs_vnodeops.c.
- */
-extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip,
-			int flags);
-
 #endif /* __XFS_RW_H__ */
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 775249a..ed47fc7 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -68,7 +68,7 @@ typedef struct xfs_trans_header {
 #define XFS_TRANS_GROWFS		14
 #define XFS_TRANS_STRAT_WRITE		15
 #define XFS_TRANS_DIOSTRAT		16
-#define	XFS_TRANS_WRITE_SYNC		17
+/* 17 was XFS_TRANS_WRITE_SYNC */
 #define	XFS_TRANS_WRITEID		18
 #define	XFS_TRANS_ADDAFORK		19
 #define	XFS_TRANS_ATTRINVAL		20
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 8ee2f8c..218829e 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -307,7 +307,7 @@ xfs_trans_read_buf(
 			return (flags & XFS_BUF_TRYLOCK) ?
 					EAGAIN : XFS_ERROR(ENOMEM);
 
-		if ((bp != NULL) && (XFS_BUF_GETERROR(bp) != 0)) {
+		if (XFS_BUF_GETERROR(bp) != 0) {
 			xfs_ioerror_alert("xfs_trans_read_buf", mp,
 					  bp, blkno);
 			error = XFS_BUF_GETERROR(bp);
@@ -315,7 +315,7 @@ xfs_trans_read_buf(
 			return error;
 		}
 #ifdef DEBUG
-		if (xfs_do_error && (bp != NULL)) {
+		if (xfs_do_error) {
 			if (xfs_error_target == target) {
 				if (((xfs_req_num++) % xfs_error_mod) == 0) {
 					xfs_buf_relse(bp);
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 23d276a..785ff10 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -49,30 +49,7 @@ xfs_trans_inode_broot_debug(
 
 
 /*
- * Get and lock the inode for the caller if it is not already
- * locked within the given transaction.  If it is already locked
- * within the transaction, just increment its lock recursion count
- * and return a pointer to it.
- *
- * For an inode to be locked in a transaction, the inode lock, as
- * opposed to the io lock, must be taken exclusively.  This ensures
- * that the inode can be involved in only 1 transaction at a time.
- * Lock recursion is handled on the io lock, but only for lock modes
- * of equal or lesser strength.  That is, you can recur on the io lock
- * held EXCL with a SHARED request but not vice versa.  Also, if
- * the inode is already a part of the transaction then you cannot
- * go from not holding the io lock to having it EXCL or SHARED.
- *
- * Use the inode cache routine xfs_inode_incore() to find the inode
- * if it is already owned by this transaction.
- *
- * If we don't already own the inode, use xfs_iget() to get it.
- * Since the inode log item structure is embedded in the incore
- * inode structure and is initialized when the inode is brought
- * into memory, there is nothing to do with it here.
- *
- * If the given transaction pointer is NULL, just call xfs_iget().
- * This simplifies code which must handle both cases.
+ * Get an inode and join it to the transaction.
  */
 int
 xfs_trans_iget(
@@ -84,62 +61,11 @@ xfs_trans_iget(
 	xfs_inode_t	**ipp)
 {
 	int			error;
-	xfs_inode_t		*ip;
-
-	/*
-	 * If the transaction pointer is NULL, just call the normal
-	 * xfs_iget().
-	 */
-	if (tp == NULL)
-		return xfs_iget(mp, NULL, ino, flags, lock_flags, ipp, 0);
-
-	/*
-	 * If we find the inode in core with this transaction
-	 * pointer in its i_transp field, then we know we already
-	 * have it locked.  In this case we just increment the lock
-	 * recursion count and return the inode to the caller.
-	 * Assert that the inode is already locked in the mode requested
-	 * by the caller.  We cannot do lock promotions yet, so
-	 * die if someone gets this wrong.
-	 */
-	if ((ip = xfs_inode_incore(tp->t_mountp, ino, tp)) != NULL) {
-		/*
-		 * Make sure that the inode lock is held EXCL and
-		 * that the io lock is never upgraded when the inode
-		 * is already a part of the transaction.
-		 */
-		ASSERT(ip->i_itemp != NULL);
-		ASSERT(lock_flags & XFS_ILOCK_EXCL);
-		ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-		ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||
-		       xfs_isilocked(ip, XFS_IOLOCK_EXCL));
-		ASSERT((!(lock_flags & XFS_IOLOCK_EXCL)) ||
-		       (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_EXCL));
-		ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||
-		       xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED));
-		ASSERT((!(lock_flags & XFS_IOLOCK_SHARED)) ||
-		       (ip->i_itemp->ili_flags & XFS_ILI_IOLOCKED_ANY));
-
-		if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
-			ip->i_itemp->ili_iolock_recur++;
-		}
-		if (lock_flags & XFS_ILOCK_EXCL) {
-			ip->i_itemp->ili_ilock_recur++;
-		}
-		*ipp = ip;
-		return 0;
-	}
-
-	ASSERT(lock_flags & XFS_ILOCK_EXCL);
-	error = xfs_iget(tp->t_mountp, tp, ino, flags, lock_flags, &ip, 0);
-	if (error) {
-		return error;
-	}
-	ASSERT(ip != NULL);
 
-	xfs_trans_ijoin(tp, ip, lock_flags);
-	*ipp = ip;
-	return 0;
+	error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp, 0);
+	if (!error && tp)
+		xfs_trans_ijoin(tp, *ipp, lock_flags);
+	return error;
 }
 
 /*
@@ -163,8 +89,6 @@ xfs_trans_ijoin(
 		xfs_inode_item_init(ip, ip->i_mount);
 	iip = ip->i_itemp;
 	ASSERT(iip->ili_flags == 0);
-	ASSERT(iip->ili_ilock_recur == 0);
-	ASSERT(iip->ili_iolock_recur == 0);
 
 	/*
 	 * Get a log_item_desc to point at the new item.
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 492d75b..a434f28 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -611,7 +611,7 @@ xfs_fsync(
 	xfs_inode_t	*ip)
 {
 	xfs_trans_t	*tp;
-	int		error;
+	int		error = 0;
 	int		log_flushed = 0, changed = 1;
 
 	xfs_itrace_entry(ip);
@@ -619,14 +619,9 @@ xfs_fsync(
 	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
 		return XFS_ERROR(EIO);
 
-	/* capture size updates in I/O completion before writing the inode. */
-	error = xfs_wait_on_pages(ip, 0, -1);
-	if (error)
-		return XFS_ERROR(error);
-
 	/*
 	 * We always need to make sure that the required inode state is safe on
-	 * disk.  The vnode might be clean but we still might need to force the
+	 * disk.  The inode might be clean but we still might need to force the
 	 * log because of committed transactions that haven't hit the disk yet.
 	 * Likewise, there could be unflushed non-transactional changes to the
 	 * inode core that have to go to disk and this requires us to issue
@@ -638,7 +633,7 @@ xfs_fsync(
 	 */
 	xfs_ilock(ip, XFS_ILOCK_SHARED);
 
-	if (!(ip->i_update_size || ip->i_update_core)) {
+	if (!ip->i_update_core) {
 		/*
 		 * Timestamps/size haven't changed since last inode flush or
 		 * inode transaction commit.  That means either nothing got
@@ -718,7 +713,7 @@ xfs_fsync(
  * when the link count isn't zero and by xfs_dm_punch_hole() when
  * punching a hole to EOF.
  */
-int
+STATIC int
 xfs_free_eofblocks(
 	xfs_mount_t	*mp,
 	xfs_inode_t	*ip,
@@ -1476,8 +1471,8 @@ xfs_create(
 	if (error == ENOSPC) {
 		/* flush outstanding delalloc blocks and retry */
 		xfs_flush_inodes(dp);
-		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) {
 		/* No space at all so try a "no-allocation" reservation */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c65e4ce..1b3b360 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -248,7 +248,6 @@ struct acpi_device_perf {
 /* Wakeup Management */
 struct acpi_device_wakeup_flags {
 	u8 valid:1;		/* Can successfully enable wakeup? */
-	u8 prepared:1;		/* Has the wake-up capability been enabled? */
 	u8 run_wake:1;		/* Run-Wake GPE devices */
 };
 
@@ -263,6 +262,7 @@ struct acpi_device_wakeup {
 	struct acpi_handle_list resources;
 	struct acpi_device_wakeup_state state;
 	struct acpi_device_wakeup_flags flags;
+	int prepare_count;
 };
 
 /* Device */
@@ -356,7 +356,6 @@ void acpi_remove_dir(struct acpi_device *);
 /*
  * Bind physical devices with ACPI devices
  */
-#include <linux/device.h>
 struct acpi_bus_type {
 	struct list_head list;
 	struct bus_type *bus;
@@ -369,10 +368,26 @@ int register_acpi_bus_type(struct acpi_bus_type *);
 int unregister_acpi_bus_type(struct acpi_bus_type *);
 struct device *acpi_get_physical_device(acpi_handle);
 
+struct acpi_pci_root {
+	struct list_head node;
+	struct acpi_device * device;
+	struct acpi_pci_id id;
+	struct pci_bus *bus;
+	u16 segment;
+	u8 bus_nr;
+
+	u32 osc_support_set;	/* _OSC state of support bits */
+	u32 osc_control_set;	/* _OSC state of control bits */
+	u32 osc_control_qry;	/* the latest _OSC query result */
+
+	u32 osc_queried:1;	/* has _OSC control been queried? */
+};
+
 /* helper */
 acpi_handle acpi_get_child(acpi_handle, acpi_integer);
 int acpi_is_root_bridge(acpi_handle);
 acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
+struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
 #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle))
 
 #ifdef CONFIG_PM_SLEEP
diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm
index 290910e..96d7c98 100644
--- a/include/asm-generic/Kbuild.asm
+++ b/include/asm-generic/Kbuild.asm
@@ -3,6 +3,11 @@ ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
 header-y  += kvm.h
 endif
 
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \
+		  $(srctree)/include/asm-$(SRCARCH)/kvm_para.h),)
+header-y  += kvm_para.h
+endif
+
 ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \
       		  $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
 unifdef-y += a.out.h
diff --git a/include/asm-generic/device.h b/include/asm-generic/device.h
index c17c960..d7c76bb 100644
--- a/include/asm-generic/device.h
+++ b/include/asm-generic/device.h
@@ -9,4 +9,7 @@
 struct dev_archdata {
 };
 
+struct pdev_archdata {
+};
+
 #endif /* _ASM_GENERIC_DEVICE_H */
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index b4326b5..26373cf 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -30,7 +30,18 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 	res->end = region->end;
 }
 
-#define pcibios_scan_all_fns(a, b)	0
+static inline struct resource *
+pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+{
+	struct resource *root = NULL;
+
+	if (res->flags & IORESOURCE_IO)
+		root = &ioport_resource;
+	if (res->flags & IORESOURCE_MEM)
+		root = &iomem_resource;
+
+	return root;
+}
 
 #ifndef HAVE_ARCH_PCI_GET_LEGACY_IDE_IRQ
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index aa00800..90079c3 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -81,14 +81,17 @@ extern void setup_per_cpu_areas(void);
 
 #ifdef MODULE
 #define PER_CPU_SHARED_ALIGNED_SECTION ""
+#define PER_CPU_ALIGNED_SECTION ""
 #else
 #define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
+#define PER_CPU_ALIGNED_SECTION ".shared_aligned"
 #endif
 #define PER_CPU_FIRST_SECTION ".first"
 
 #else
 
 #define PER_CPU_SHARED_ALIGNED_SECTION ""
+#define PER_CPU_ALIGNED_SECTION ".shared_aligned"
 #define PER_CPU_FIRST_SECTION ""
 
 #endif
diff --git a/include/asm-generic/socket.h b/include/asm-generic/socket.h
index 5d79e40..538991c 100644
--- a/include/asm-generic/socket.h
+++ b/include/asm-generic/socket.h
@@ -60,4 +60,7 @@
 #define SO_TIMESTAMPING		37
 #define SCM_TIMESTAMPING	SO_TIMESTAMPING
 
+#define SO_PROTOCOL		38
+#define SO_DOMAIN		39
+
 #endif /* __ASM_GENERIC_SOCKET_H */
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
index 1125e5a..d76b66a 100644
--- a/include/asm-generic/unistd.h
+++ b/include/asm-generic/unistd.h
@@ -620,8 +620,8 @@ __SYSCALL(__NR_move_pages, sys_move_pages)
 
 #define __NR_rt_tgsigqueueinfo 240
 __SYSCALL(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo)
-#define __NR_perf_counter_open 241
-__SYSCALL(__NR_perf_counter_open, sys_perf_counter_open)
+#define __NR_perf_event_open 241
+__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
 
 #undef __NR_syscalls
 #define __NR_syscalls 242
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 6ad76bf..29ca8f5 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -33,13 +33,10 @@
  *	BSS_SECTION(0, 0, 0)
  *	_end = .;
  *
- *	/DISCARD/ : {
- *		EXIT_TEXT
- *		EXIT_DATA
- *		EXIT_CALL
- *	}
  *	STABS_DEBUG
  *	DWARF_DEBUG
+ *
+ *	DISCARDS		// must be the last
  * }
  *
  * [__init_begin, __init_end] is the init section that may be freed after init
@@ -91,7 +88,8 @@
 #endif
 
 #ifdef CONFIG_FTRACE_MCOUNT_RECORD
-#define MCOUNT_REC()	VMLINUX_SYMBOL(__start_mcount_loc) = .; \
+#define MCOUNT_REC()	. = ALIGN(8);				\
+			VMLINUX_SYMBOL(__start_mcount_loc) = .; \
 			*(__mcount_loc)				\
 			VMLINUX_SYMBOL(__stop_mcount_loc) = .;
 #else
@@ -331,7 +329,6 @@
 	/* __*init sections */						\
 	__init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) {		\
 		*(.ref.rodata)						\
-		MCOUNT_REC()						\
 		DEV_KEEP(init.rodata)					\
 		DEV_KEEP(exit.rodata)					\
 		CPU_KEEP(init.rodata)					\
@@ -455,6 +452,7 @@
 	MEM_DISCARD(init.data)						\
 	KERNEL_CTORS()							\
 	*(.init.rodata)							\
+	MCOUNT_REC()							\
 	DEV_DISCARD(init.rodata)					\
 	CPU_DISCARD(init.rodata)					\
 	MEM_DISCARD(init.rodata)
@@ -626,6 +624,23 @@
 #define INIT_RAM_FS
 #endif
 
+/*
+ * Default discarded sections.
+ *
+ * Some archs want to discard exit text/data at runtime rather than
+ * link time due to cross-section references such as alt instructions,
+ * bug table, eh_frame, etc.  DISCARDS must be the last of output
+ * section definitions so that such archs put those in earlier section
+ * definitions.
+ */
+#define DISCARDS							\
+	/DISCARD/ : {							\
+	EXIT_TEXT							\
+	EXIT_DATA							\
+	EXIT_CALL							\
+	*(.discard)							\
+	}
+
 /**
  * PERCPU_VADDR - define output section for percpu area
  * @vaddr: explicit base address (optional)
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 45b67d9..c8e64bb 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -88,7 +88,37 @@ struct drm_device;
 #define DRM_UT_CORE 		0x01
 #define DRM_UT_DRIVER		0x02
 #define DRM_UT_KMS		0x04
-#define DRM_UT_MODE		0x08
+/*
+ * Three debug levels are defined.
+ * drm_core, drm_driver, drm_kms
+ * drm_core level can be used in the generic drm code. For example:
+ * 	drm_ioctl, drm_mm, drm_memory
+ * The macro definiton of DRM_DEBUG is used.
+ * 	DRM_DEBUG(fmt, args...)
+ * 	The debug info by using the DRM_DEBUG can be obtained by adding
+ * 	the boot option of "drm.debug=1".
+ *
+ * drm_driver level can be used in the specific drm driver. It is used
+ * to add the debug info related with the drm driver. For example:
+ * i915_drv, i915_dma, i915_gem, radeon_drv,
+ * 	The macro definition of DRM_DEBUG_DRIVER can be used.
+ * 	DRM_DEBUG_DRIVER(fmt, args...)
+ * 	The debug info by using the DRM_DEBUG_DRIVER can be obtained by
+ * 	adding the boot option of "drm.debug=0x02"
+ *
+ * drm_kms level can be used in the KMS code related with specific drm driver.
+ * It is used to add the debug info related with KMS mode. For example:
+ * the connector/crtc ,
+ * 	The macro definition of DRM_DEBUG_KMS can be used.
+ * 	DRM_DEBUG_KMS(fmt, args...)
+ * 	The debug info by using the DRM_DEBUG_KMS can be obtained by
+ * 	adding the boot option of "drm.debug=0x04"
+ *
+ * If we add the boot option of "drm.debug=0x06", we can get the debug info by
+ * using the DRM_DEBUG_KMS and DRM_DEBUG_DRIVER.
+ * If we add the boot option of "drm.debug=0x05", we can get the debug info by
+ * using the DRM_DEBUG_KMS and DRM_DEBUG.
+ */
 
 extern void drm_ut_debug_printk(unsigned int request_level,
 				const char *prefix,
@@ -174,19 +204,14 @@ extern void drm_ut_debug_printk(unsigned int request_level,
 					__func__, fmt, ##args);		\
 	} while (0)
 
-#define DRM_DEBUG_DRIVER(prefix, fmt, args...)				\
+#define DRM_DEBUG_DRIVER(fmt, args...)					\
 	do {								\
-		drm_ut_debug_printk(DRM_UT_DRIVER, prefix,		\
+		drm_ut_debug_printk(DRM_UT_DRIVER, DRM_NAME,		\
 					__func__, fmt, ##args);		\
 	} while (0)
-#define DRM_DEBUG_KMS(prefix, fmt, args...)				\
+#define DRM_DEBUG_KMS(fmt, args...)				\
 	do {								\
-		drm_ut_debug_printk(DRM_UT_KMS, prefix, 		\
-					 __func__, fmt, ##args);	\
-	} while (0)
-#define DRM_DEBUG_MODE(prefix, fmt, args...)				\
-	do {								\
-		drm_ut_debug_printk(DRM_UT_MODE, prefix, 		\
+		drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, 		\
 					 __func__, fmt, ##args);	\
 	} while (0)
 #define DRM_LOG(fmt, args...)						\
@@ -210,9 +235,8 @@ extern void drm_ut_debug_printk(unsigned int request_level,
 					NULL, fmt, ##args);		\
 	} while (0)
 #else
-#define DRM_DEBUG_DRIVER(prefix, fmt, args...) do { } while (0)
-#define DRM_DEBUG_KMS(prefix, fmt, args...)	do { } while (0)
-#define DRM_DEBUG_MODE(prefix, fmt, args...)	do { } while (0)
+#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0)
+#define DRM_DEBUG_KMS(fmt, args...)	do { } while (0)
 #define DRM_DEBUG(fmt, arg...)		 do { } while (0)
 #define DRM_LOG(fmt, arg...)		do { } while (0)
 #define DRM_LOG_KMS(fmt, args...) do { } while (0)
@@ -786,6 +810,9 @@ struct drm_driver {
 	int (*gem_init_object) (struct drm_gem_object *obj);
 	void (*gem_free_object) (struct drm_gem_object *obj);
 
+	/* vga arb irq handler */
+	void (*vgaarb_irq)(struct drm_device *dev, bool state);
+
 	/* Driver private ops for this object */
 	struct vm_operations_struct *gem_vm_ops;
 
@@ -1417,7 +1444,7 @@ drm_gem_object_unreference(struct drm_gem_object *obj)
 
 int drm_gem_handle_create(struct drm_file *file_priv,
 			  struct drm_gem_object *obj,
-			  int *handlep);
+			  u32 *handlep);
 
 static inline void
 drm_gem_object_handle_reference(struct drm_gem_object *obj)
@@ -1443,7 +1470,7 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj)
 
 struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
 					     struct drm_file *filp,
-					     int handle);
+					     u32 handle);
 int drm_gem_close_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file_priv);
 int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
diff --git a/include/drm/drm_cache.h b/include/drm/drm_cache.h
new file mode 100644
index 0000000..7bfb063
--- /dev/null
+++ b/include/drm/drm_cache.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Red Hat Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ **************************************************************************/
+/*
+ * Authors:
+ * Dave Airlie <airlied@redhat.com>
+ */
+
+#ifndef _DRM_CACHE_H_
+#define _DRM_CACHE_H_
+
+void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
+
+#endif
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 7300fb8..ae1e9e1 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -259,6 +259,8 @@ struct drm_framebuffer {
 	void *fbdev;
 	u32 pseudo_palette[17];
 	struct list_head filp_head;
+	/* if you are using the helper */
+	void *helper_private;
 };
 
 struct drm_property_blob {
@@ -572,6 +574,12 @@ struct drm_mode_config {
 	struct drm_property *tv_right_margin_property;
 	struct drm_property *tv_top_margin_property;
 	struct drm_property *tv_bottom_margin_property;
+	struct drm_property *tv_brightness_property;
+	struct drm_property *tv_contrast_property;
+	struct drm_property *tv_flicker_reduction_property;
+	struct drm_property *tv_overscan_property;
+	struct drm_property *tv_saturation_property;
+	struct drm_property *tv_hue_property;
 
 	/* Optional properties */
 	struct drm_property *scaling_mode_property;
@@ -736,4 +744,12 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev,
 extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
 				    void *data, struct drm_file *file_priv);
 extern bool drm_detect_hdmi_monitor(struct edid *edid);
+extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
+				int hdisplay, int vdisplay, int vrefresh,
+				bool reduced, bool interlaced);
+extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
+				int hdisplay, int vdisplay, int vrefresh,
+				bool interlaced, int margins);
+extern int drm_add_modes_noedid(struct drm_connector *connector,
+				int hdisplay, int vdisplay);
 #endif /* __DRM_CRTC_H__ */
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 6769ff6..4c8daca 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -79,6 +79,8 @@ struct drm_encoder_helper_funcs {
 	/* detect for DAC style encoders */
 	enum drm_connector_status (*detect)(struct drm_encoder *encoder,
 					    struct drm_connector *connector);
+	/* disable encoder when not in use - more explicit than dpms off */
+	void (*disable)(struct drm_encoder *encoder);
 };
 
 struct drm_connector_helper_funcs {
@@ -98,6 +100,7 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 				     int x, int y,
 				     struct drm_framebuffer *old_fb);
 extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
+extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
 
 extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
 
diff --git a/include/drm/drm_encoder_slave.h b/include/drm/drm_encoder_slave.h
new file mode 100644
index 0000000..2f65633
--- /dev/null
+++ b/include/drm/drm_encoder_slave.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2009 Francisco Jerez.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __DRM_ENCODER_SLAVE_H__
+#define __DRM_ENCODER_SLAVE_H__
+
+#include "drmP.h"
+#include "drm_crtc.h"
+
+/**
+ * struct drm_encoder_slave_funcs - Entry points exposed by a slave encoder driver
+ * @set_config:	Initialize any encoder-specific modesetting parameters.
+ *		The meaning of the @params parameter is implementation
+ *		dependent. It will usually be a structure with DVO port
+ *		data format settings or timings. It's not required for
+ *		the new parameters to take effect until the next mode
+ *		is set.
+ *
+ * Most of its members are analogous to the function pointers in
+ * &drm_encoder_helper_funcs and they can optionally be used to
+ * initialize the latter. Connector-like methods (e.g. @get_modes and
+ * @set_property) will typically be wrapped around and only be called
+ * if the encoder is the currently selected one for the connector.
+ */
+struct drm_encoder_slave_funcs {
+	void (*set_config)(struct drm_encoder *encoder,
+			   void *params);
+
+	void (*destroy)(struct drm_encoder *encoder);
+	void (*dpms)(struct drm_encoder *encoder, int mode);
+	void (*save)(struct drm_encoder *encoder);
+	void (*restore)(struct drm_encoder *encoder);
+	bool (*mode_fixup)(struct drm_encoder *encoder,
+			   struct drm_display_mode *mode,
+			   struct drm_display_mode *adjusted_mode);
+	int (*mode_valid)(struct drm_encoder *encoder,
+			  struct drm_display_mode *mode);
+	void (*mode_set)(struct drm_encoder *encoder,
+			 struct drm_display_mode *mode,
+			 struct drm_display_mode *adjusted_mode);
+
+	enum drm_connector_status (*detect)(struct drm_encoder *encoder,
+					    struct drm_connector *connector);
+	int (*get_modes)(struct drm_encoder *encoder,
+			 struct drm_connector *connector);
+	int (*create_resources)(struct drm_encoder *encoder,
+				 struct drm_connector *connector);
+	int (*set_property)(struct drm_encoder *encoder,
+			    struct drm_connector *connector,
+			    struct drm_property *property,
+			    uint64_t val);
+
+};
+
+/**
+ * struct drm_encoder_slave - Slave encoder struct
+ * @base: DRM encoder object.
+ * @slave_funcs: Slave encoder callbacks.
+ * @slave_priv: Slave encoder private data.
+ * @bus_priv: Bus specific data.
+ *
+ * A &drm_encoder_slave has two sets of callbacks, @slave_funcs and the
+ * ones in @base. The former are never actually called by the common
+ * CRTC code, it's just a convenience for splitting the encoder
+ * functions in an upper, GPU-specific layer and a (hopefully)
+ * GPU-agnostic lower layer: It's the GPU driver responsibility to
+ * call the slave methods when appropriate.
+ *
+ * drm_i2c_encoder_init() provides a way to get an implementation of
+ * this.
+ */
+struct drm_encoder_slave {
+	struct drm_encoder base;
+
+	struct drm_encoder_slave_funcs *slave_funcs;
+	void *slave_priv;
+	void *bus_priv;
+};
+#define to_encoder_slave(x) container_of((x), struct drm_encoder_slave, base)
+
+int drm_i2c_encoder_init(struct drm_device *dev,
+			 struct drm_encoder_slave *encoder,
+			 struct i2c_adapter *adap,
+			 const struct i2c_board_info *info);
+
+
+/**
+ * struct drm_i2c_encoder_driver
+ *
+ * Describes a device driver for an encoder connected to the GPU
+ * through an I2C bus. In addition to the entry points in @i2c_driver
+ * an @encoder_init function should be provided. It will be called to
+ * give the driver an opportunity to allocate any per-encoder data
+ * structures and to initialize the @slave_funcs and (optionally)
+ * @slave_priv members of @encoder.
+ */
+struct drm_i2c_encoder_driver {
+	struct i2c_driver i2c_driver;
+
+	int (*encoder_init)(struct i2c_client *client,
+			    struct drm_device *dev,
+			    struct drm_encoder_slave *encoder);
+
+};
+#define to_drm_i2c_encoder_driver(x) container_of((x),			\
+						  struct drm_i2c_encoder_driver, \
+						  i2c_driver)
+
+/**
+ * drm_i2c_encoder_get_client - Get the I2C client corresponding to an encoder
+ */
+static inline struct i2c_client *drm_i2c_encoder_get_client(struct drm_encoder *encoder)
+{
+	return (struct i2c_client *)to_encoder_slave(encoder)->bus_priv;
+}
+
+/**
+ * drm_i2c_encoder_register - Register an I2C encoder driver
+ * @owner:	Module containing the driver.
+ * @driver:	Driver to be registered.
+ */
+static inline int drm_i2c_encoder_register(struct module *owner,
+					   struct drm_i2c_encoder_driver *driver)
+{
+	return i2c_register_driver(owner, &driver->i2c_driver);
+}
+
+/**
+ * drm_i2c_encoder_unregister - Unregister an I2C encoder driver
+ * @driver:	Driver to be unregistered.
+ */
+static inline void drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver *driver)
+{
+	i2c_del_driver(&driver->i2c_driver);
+}
+
+void drm_i2c_encoder_destroy(struct drm_encoder *encoder);
+
+#endif
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
new file mode 100644
index 0000000..88fffbd
--- /dev/null
+++ b/include/drm/drm_fb_helper.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006-2009 Red Hat Inc.
+ * Copyright (c) 2006-2008 Intel Corporation
+ * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
+ *
+ * DRM framebuffer helper functions
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Authors:
+ *      Dave Airlie <airlied@linux.ie>
+ *      Jesse Barnes <jesse.barnes@intel.com>
+ */
+#ifndef DRM_FB_HELPER_H
+#define DRM_FB_HELPER_H
+
+struct drm_fb_helper_crtc {
+	uint32_t crtc_id;
+	struct drm_mode_set mode_set;
+};
+
+struct drm_fb_helper_funcs {
+	void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
+			  u16 blue, int regno);
+};
+
+struct drm_fb_helper {
+	struct drm_framebuffer *fb;
+	struct drm_device *dev;
+	struct drm_display_mode *mode;
+	int crtc_count;
+	struct drm_fb_helper_crtc *crtc_info;
+	struct drm_fb_helper_funcs *funcs;
+	int conn_limit;
+	struct list_head kernel_fb_list;
+};
+
+int drm_fb_helper_single_fb_probe(struct drm_device *dev,
+				  int (*fb_create)(struct drm_device *dev,
+						   uint32_t fb_width,
+						   uint32_t fb_height,
+						   uint32_t surface_width,
+						   uint32_t surface_height,
+						   struct drm_framebuffer **fb_ptr));
+int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count,
+				  int max_conn);
+void drm_fb_helper_free(struct drm_fb_helper *helper);
+int drm_fb_helper_blank(int blank, struct fb_info *info);
+int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
+			      struct fb_info *info);
+int drm_fb_helper_set_par(struct fb_info *info);
+int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
+			    struct fb_info *info);
+int drm_fb_helper_setcolreg(unsigned regno,
+			    unsigned red,
+			    unsigned green,
+			    unsigned blue,
+			    unsigned transp,
+			    struct fb_info *info);
+
+void drm_fb_helper_restore(void);
+void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
+			    uint32_t fb_width, uint32_t fb_height);
+void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch);
+
+#endif
diff --git a/include/drm/drm_memory.h b/include/drm/drm_memory.h
index 63e425b..15af9b3 100644
--- a/include/drm/drm_memory.h
+++ b/include/drm/drm_memory.h
@@ -44,8 +44,6 @@
 
 #if __OS_HAS_AGP
 
-#include <linux/vmalloc.h>
-
 #ifdef HAVE_PAGE_AGP
 #include <asm/agp.h>
 #else
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index f833207..62329f9 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -37,6 +37,9 @@
  * Generic range manager structs
  */
 #include <linux/list.h>
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+#endif
 
 struct drm_mm_node {
 	struct list_head fl_entry;
@@ -96,4 +99,8 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
 	return block->mm;
 }
 
+#ifdef CONFIG_DEBUG_FS
+int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
+#endif
+
 #endif
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index ae304cc..1f90841 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -68,10 +68,11 @@
 #define DRM_MODE_DPMS_OFF	3
 
 /* Scaling mode options */
-#define DRM_MODE_SCALE_NON_GPU		0
-#define DRM_MODE_SCALE_FULLSCREEN	1
-#define DRM_MODE_SCALE_NO_SCALE		2
-#define DRM_MODE_SCALE_ASPECT		3
+#define DRM_MODE_SCALE_NONE		0 /* Unmodified timing (display or
+					     software can still scale) */
+#define DRM_MODE_SCALE_FULLSCREEN	1 /* Full screen, ignore aspect */
+#define DRM_MODE_SCALE_CENTER		2 /* Centered, no scaling */
+#define DRM_MODE_SCALE_ASPECT		3 /* Full screen, preserve aspect */
 
 /* Dithering mode options */
 #define DRM_MODE_DITHERING_OFF	0
@@ -141,6 +142,7 @@ struct drm_mode_get_encoder {
 #define DRM_MODE_SUBCONNECTOR_Composite	5
 #define DRM_MODE_SUBCONNECTOR_SVIDEO	6
 #define DRM_MODE_SUBCONNECTOR_Component	8
+#define DRM_MODE_SUBCONNECTOR_SCART	9
 
 #define DRM_MODE_CONNECTOR_Unknown	0
 #define DRM_MODE_CONNECTOR_VGA		1
@@ -155,6 +157,7 @@ struct drm_mode_get_encoder {
 #define DRM_MODE_CONNECTOR_DisplayPort	10
 #define DRM_MODE_CONNECTOR_HDMIA	11
 #define DRM_MODE_CONNECTOR_HDMIB	12
+#define DRM_MODE_CONNECTOR_TV		13
 
 struct drm_mode_get_connector {
 
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
new file mode 100644
index 0000000..1d8e033
--- /dev/null
+++ b/include/drm/drm_sysfs.h
@@ -0,0 +1,12 @@
+#ifndef _DRM_SYSFS_H_
+#define _DRM_SYSFS_H_
+
+/**
+ * This minimalistic include file is intended for users (read TTM) that
+ * don't want to include the full drmP.h file.
+ */
+
+extern int drm_class_device_register(struct device *dev);
+extern void drm_class_device_unregister(struct device *dev);
+
+#endif
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h
index 2ba61e1..3b9932a 100644
--- a/include/drm/radeon_drm.h
+++ b/include/drm/radeon_drm.h
@@ -802,11 +802,12 @@ struct drm_radeon_gem_create {
 	uint32_t	flags;
 };
 
-#define RADEON_TILING_MACRO 0x1
-#define RADEON_TILING_MICRO 0x2
-#define RADEON_TILING_SWAP  0x4
-#define RADEON_TILING_SURFACE  0x8 /* this object requires a surface
-				    * when mapped - i.e. front buffer */
+#define RADEON_TILING_MACRO       0x1
+#define RADEON_TILING_MICRO       0x2
+#define RADEON_TILING_SWAP_16BIT  0x4
+#define RADEON_TILING_SWAP_32BIT  0x8
+#define RADEON_TILING_SURFACE     0x10 /* this object requires a surface
+					* when mapped - i.e. front buffer */
 
 struct drm_radeon_gem_set_tiling {
 	uint32_t	handle;
@@ -899,6 +900,7 @@ struct drm_radeon_cs {
 #define RADEON_INFO_DEVICE_ID		0x00
 #define RADEON_INFO_NUM_GB_PIPES	0x01
 #define RADEON_INFO_NUM_Z_PIPES 	0x02
+#define RADEON_INFO_ACCEL_WORKING	0x03
 
 struct drm_radeon_info {
 	uint32_t		request;
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index cd22ab4..4911461 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -155,6 +155,7 @@ struct ttm_buffer_object {
 	 * Members constant at init.
 	 */
 
+	struct ttm_bo_global *glob;
 	struct ttm_bo_device *bdev;
 	unsigned long buffer_start;
 	enum ttm_bo_type type;
@@ -245,14 +246,15 @@ struct ttm_buffer_object {
  * premapped region.
  */
 
+#define TTM_BO_MAP_IOMEM_MASK 0x80
 struct ttm_bo_kmap_obj {
 	void *virtual;
 	struct page *page;
 	enum {
-		ttm_bo_map_iomap,
-		ttm_bo_map_vmap,
-		ttm_bo_map_kmap,
-		ttm_bo_map_premapped,
+		ttm_bo_map_iomap        = 1 | TTM_BO_MAP_IOMEM_MASK,
+		ttm_bo_map_vmap         = 2,
+		ttm_bo_map_kmap         = 3,
+		ttm_bo_map_premapped    = 4 | TTM_BO_MAP_IOMEM_MASK,
 	} bo_kmap_type;
 };
 
@@ -522,8 +524,7 @@ extern int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type);
 static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map,
 					 bool *is_iomem)
 {
-	*is_iomem = (map->bo_kmap_type == ttm_bo_map_iomap ||
-		     map->bo_kmap_type == ttm_bo_map_premapped);
+	*is_iomem = !!(map->bo_kmap_type & TTM_BO_MAP_IOMEM_MASK);
 	return map->virtual;
 }
 
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index a68829d..e8cd6d2 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -32,6 +32,7 @@
 
 #include "ttm/ttm_bo_api.h"
 #include "ttm/ttm_memory.h"
+#include "ttm/ttm_module.h"
 #include "drm_mm.h"
 #include "linux/workqueue.h"
 #include "linux/fs.h"
@@ -161,7 +162,7 @@ struct ttm_tt {
 	long last_lomem_page;
 	uint32_t page_flags;
 	unsigned long num_pages;
-	struct ttm_bo_device *bdev;
+	struct ttm_bo_global *glob;
 	struct ttm_backend *be;
 	struct task_struct *tsk;
 	unsigned long start;
@@ -364,24 +365,73 @@ struct ttm_bo_driver {
 	void (*fault_reserve_notify)(struct ttm_buffer_object *bo);
 };
 
-#define TTM_NUM_MEM_TYPES 8
+/**
+ * struct ttm_bo_global_ref - Argument to initialize a struct ttm_bo_global.
+ */
+
+struct ttm_bo_global_ref {
+	struct ttm_global_reference ref;
+	struct ttm_mem_global *mem_glob;
+};
 
-#define TTM_BO_PRIV_FLAG_MOVING  0	/* Buffer object is moving and needs
-					   idling before CPU mapping */
-#define TTM_BO_PRIV_FLAG_MAX 1
 /**
- * struct ttm_bo_device - Buffer object driver device-specific data.
+ * struct ttm_bo_global - Buffer object driver global data.
  *
  * @mem_glob: Pointer to a struct ttm_mem_global object for accounting.
- * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver.
- * @count: Current number of buffer object.
- * @pages: Current number of pinned pages.
  * @dummy_read_page: Pointer to a dummy page used for mapping requests
  * of unpopulated pages.
- * @shrink: A shrink callback object used for buffre object swap.
+ * @shrink: A shrink callback object used for buffer object swap.
  * @ttm_bo_extra_size: Extra size (sizeof(struct ttm_buffer_object) excluded)
  * used by a buffer object. This is excluding page arrays and backing pages.
  * @ttm_bo_size: This is @ttm_bo_extra_size + sizeof(struct ttm_buffer_object).
+ * @device_list_mutex: Mutex protecting the device list.
+ * This mutex is held while traversing the device list for pm options.
+ * @lru_lock: Spinlock protecting the bo subsystem lru lists.
+ * @device_list: List of buffer object devices.
+ * @swap_lru: Lru list of buffer objects used for swapping.
+ */
+
+struct ttm_bo_global {
+
+	/**
+	 * Constant after init.
+	 */
+
+	struct kobject kobj;
+	struct ttm_mem_global *mem_glob;
+	struct page *dummy_read_page;
+	struct ttm_mem_shrink shrink;
+	size_t ttm_bo_extra_size;
+	size_t ttm_bo_size;
+	struct mutex device_list_mutex;
+	spinlock_t lru_lock;
+
+	/**
+	 * Protected by device_list_mutex.
+	 */
+	struct list_head device_list;
+
+	/**
+	 * Protected by the lru_lock.
+	 */
+	struct list_head swap_lru;
+
+	/**
+	 * Internal protection.
+	 */
+	atomic_t bo_count;
+};
+
+
+#define TTM_NUM_MEM_TYPES 8
+
+#define TTM_BO_PRIV_FLAG_MOVING  0	/* Buffer object is moving and needs
+					   idling before CPU mapping */
+#define TTM_BO_PRIV_FLAG_MAX 1
+/**
+ * struct ttm_bo_device - Buffer object driver device-specific data.
+ *
+ * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver.
  * @man: An array of mem_type_managers.
  * @addr_space_mm: Range manager for the device address space.
  * lru_lock: Spinlock that protects the buffer+device lru lists and
@@ -399,32 +449,21 @@ struct ttm_bo_device {
 	/*
 	 * Constant after bo device init / atomic.
 	 */
-
-	struct ttm_mem_global *mem_glob;
+	struct list_head device_list;
+	struct ttm_bo_global *glob;
 	struct ttm_bo_driver *driver;
-	struct page *dummy_read_page;
-	struct ttm_mem_shrink shrink;
-
-	size_t ttm_bo_extra_size;
-	size_t ttm_bo_size;
-
 	rwlock_t vm_lock;
+	struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES];
 	/*
 	 * Protected by the vm lock.
 	 */
-	struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES];
 	struct rb_root addr_space_rb;
 	struct drm_mm addr_space_mm;
 
 	/*
-	 * Might want to change this to one lock per manager.
-	 */
-	spinlock_t lru_lock;
-	/*
-	 * Protected by the lru lock.
+	 * Protected by the global:lru lock.
 	 */
 	struct list_head ddestroy;
-	struct list_head swap_lru;
 
 	/*
 	 * Protected by load / firstopen / lastclose /unload sync.
@@ -640,6 +679,9 @@ extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev,
 			     unsigned long *bus_offset,
 			     unsigned long *bus_size);
 
+extern void ttm_bo_global_release(struct ttm_global_reference *ref);
+extern int ttm_bo_global_init(struct ttm_global_reference *ref);
+
 extern int ttm_bo_device_release(struct ttm_bo_device *bdev);
 
 /**
@@ -657,7 +699,7 @@ extern int ttm_bo_device_release(struct ttm_bo_device *bdev);
  * !0: Failure.
  */
 extern int ttm_bo_device_init(struct ttm_bo_device *bdev,
-			      struct ttm_mem_global *mem_glob,
+			      struct ttm_bo_global *glob,
 			      struct ttm_bo_driver *driver,
 			      uint64_t file_page_offset, bool need_dma32);
 
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index d8b8f04..6983a7c 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -32,6 +32,7 @@
 #include <linux/spinlock.h>
 #include <linux/wait.h>
 #include <linux/errno.h>
+#include <linux/kobject.h>
 
 /**
  * struct ttm_mem_shrink - callback to shrink TTM memory usage.
@@ -60,34 +61,33 @@ struct ttm_mem_shrink {
  * @queue: Wait queue for processes suspended waiting for memory.
  * @lock: Lock to protect the @shrink - and the memory accounting members,
  * that is, essentially the whole structure with some exceptions.
- * @emer_memory: Lowmem memory limit available for root.
- * @max_memory: Lowmem memory limit available for non-root.
- * @swap_limit: Lowmem memory limit where the shrink workqueue kicks in.
- * @used_memory: Currently used lowmem memory.
- * @used_total_memory: Currently used total (lowmem + highmem) memory.
- * @total_memory_swap_limit: Total memory limit where the shrink workqueue
- * kicks in.
- * @max_total_memory: Total memory available to non-root processes.
- * @emer_total_memory: Total memory available to root processes.
+ * @zones: Array of pointers to accounting zones.
+ * @num_zones: Number of populated entries in the @zones array.
+ * @zone_kernel: Pointer to the kernel zone.
+ * @zone_highmem: Pointer to the highmem zone if there is one.
+ * @zone_dma32: Pointer to the dma32 zone if there is one.
  *
  * Note that this structure is not per device. It should be global for all
  * graphics devices.
  */
 
+#define TTM_MEM_MAX_ZONES 2
+struct ttm_mem_zone;
 struct ttm_mem_global {
+	struct kobject kobj;
 	struct ttm_mem_shrink *shrink;
 	struct workqueue_struct *swap_queue;
 	struct work_struct work;
 	wait_queue_head_t queue;
 	spinlock_t lock;
-	uint64_t emer_memory;
-	uint64_t max_memory;
-	uint64_t swap_limit;
-	uint64_t used_memory;
-	uint64_t used_total_memory;
-	uint64_t total_memory_swap_limit;
-	uint64_t max_total_memory;
-	uint64_t emer_total_memory;
+	struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
+	unsigned int num_zones;
+	struct ttm_mem_zone *zone_kernel;
+#ifdef CONFIG_HIGHMEM
+	struct ttm_mem_zone *zone_highmem;
+#else
+	struct ttm_mem_zone *zone_dma32;
+#endif
 };
 
 /**
@@ -146,8 +146,13 @@ static inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob,
 extern int ttm_mem_global_init(struct ttm_mem_global *glob);
 extern void ttm_mem_global_release(struct ttm_mem_global *glob);
 extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
-				bool no_wait, bool interruptible, bool himem);
+				bool no_wait, bool interruptible);
 extern void ttm_mem_global_free(struct ttm_mem_global *glob,
-				uint64_t amount, bool himem);
+				uint64_t amount);
+extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
+				     struct page *page,
+				     bool no_wait, bool interruptible);
+extern void ttm_mem_global_free_page(struct ttm_mem_global *glob,
+				     struct page *page);
 extern size_t ttm_round_pot(size_t size);
 #endif
diff --git a/include/drm/ttm/ttm_module.h b/include/drm/ttm/ttm_module.h
index d1d4338..cf416ae 100644
--- a/include/drm/ttm/ttm_module.h
+++ b/include/drm/ttm/ttm_module.h
@@ -32,6 +32,7 @@
 #define _TTM_MODULE_H_
 
 #include <linux/kernel.h>
+struct kobject;
 
 #define TTM_PFX "[TTM] "
 
@@ -54,5 +55,6 @@ extern void ttm_global_init(void);
 extern void ttm_global_release(void);
 extern int ttm_global_item_ref(struct ttm_global_reference *ref);
 extern void ttm_global_item_unref(struct ttm_global_reference *ref);
+extern struct kobject *ttm_get_kobj(void);
 
 #endif /* _TTM_MODULE_H_ */
diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h
index 7609365..5cb86c3 100644
--- a/include/keys/rxrpc-type.h
+++ b/include/keys/rxrpc-type.h
@@ -21,4 +21,111 @@ extern struct key_type key_type_rxrpc;
 
 extern struct key *rxrpc_get_null_key(const char *);
 
+/*
+ * RxRPC key for Kerberos IV (type-2 security)
+ */
+struct rxkad_key {
+	u32	vice_id;
+	u32	start;			/* time at which ticket starts */
+	u32	expiry;			/* time at which ticket expires */
+	u32	kvno;			/* key version number */
+	u8	primary_flag;		/* T if key for primary cell for this user */
+	u16	ticket_len;		/* length of ticket[] */
+	u8	session_key[8];		/* DES session key */
+	u8	ticket[0];		/* the encrypted ticket */
+};
+
+/*
+ * Kerberos 5 principal
+ *	name/name/name@realm
+ */
+struct krb5_principal {
+	u8	n_name_parts;		/* N of parts of the name part of the principal */
+	char	**name_parts;		/* parts of the name part of the principal */
+	char	*realm;			/* parts of the realm part of the principal */
+};
+
+/*
+ * Kerberos 5 tagged data
+ */
+struct krb5_tagged_data {
+	/* for tag value, see /usr/include/krb5/krb5.h
+	 * - KRB5_AUTHDATA_* for auth data
+	 * - 
+	 */
+	s32		tag;
+	u32		data_len;
+	u8		*data;
+};
+
+/*
+ * RxRPC key for Kerberos V (type-5 security)
+ */
+struct rxk5_key {
+	u64			authtime;	/* time at which auth token generated */
+	u64			starttime;	/* time at which auth token starts */
+	u64			endtime;	/* time at which auth token expired */
+	u64			renew_till;	/* time to which auth token can be renewed */
+	s32			is_skey;	/* T if ticket is encrypted in another ticket's
+						 * skey */
+	s32			flags;		/* mask of TKT_FLG_* bits (krb5/krb5.h) */
+	struct krb5_principal	client;		/* client principal name */
+	struct krb5_principal	server;		/* server principal name */
+	u16			ticket_len;	/* length of ticket */
+	u16			ticket2_len;	/* length of second ticket */
+	u8			n_authdata;	/* number of authorisation data elements */
+	u8			n_addresses;	/* number of addresses */
+	struct krb5_tagged_data	session;	/* session data; tag is enctype */
+	struct krb5_tagged_data *addresses;	/* addresses */
+	u8			*ticket;	/* krb5 ticket */
+	u8			*ticket2;	/* second krb5 ticket, if related to ticket (via
+						 * DUPLICATE-SKEY or ENC-TKT-IN-SKEY) */
+	struct krb5_tagged_data *authdata;	/* authorisation data */
+};
+
+/*
+ * list of tokens attached to an rxrpc key
+ */
+struct rxrpc_key_token {
+	u16	security_index;		/* RxRPC header security index */
+	struct rxrpc_key_token *next;	/* the next token in the list */
+	union {
+		struct rxkad_key *kad;
+		struct rxk5_key *k5;
+	};
+};
+
+/*
+ * structure of raw payloads passed to add_key() or instantiate key
+ */
+struct rxrpc_key_data_v1 {
+	u32		kif_version;		/* 1 */
+	u16		security_index;
+	u16		ticket_length;
+	u32		expiry;			/* time_t */
+	u32		kvno;
+	u8		session_key[8];
+	u8		ticket[0];
+};
+
+/*
+ * AF_RXRPC key payload derived from XDR format
+ * - based on openafs-1.4.10/src/auth/afs_token.xg
+ */
+#define AFSTOKEN_LENGTH_MAX		16384	/* max payload size */
+#define AFSTOKEN_STRING_MAX		256	/* max small string length */
+#define AFSTOKEN_DATA_MAX		64	/* max small data length */
+#define AFSTOKEN_CELL_MAX		64	/* max cellname length */
+#define AFSTOKEN_MAX			8	/* max tokens per payload */
+#define AFSTOKEN_BDATALN_MAX		16384	/* max big data length */
+#define AFSTOKEN_RK_TIX_MAX		12000	/* max RxKAD ticket size */
+#define AFSTOKEN_GK_KEY_MAX		64	/* max GSSAPI key size */
+#define AFSTOKEN_GK_TOKEN_MAX		16384	/* max GSSAPI token size */
+#define AFSTOKEN_K5_COMPONENTS_MAX	16	/* max K5 components */
+#define AFSTOKEN_K5_NAME_MAX		128	/* max K5 name length */
+#define AFSTOKEN_K5_REALM_MAX		64	/* max K5 realm name length */
+#define AFSTOKEN_K5_TIX_MAX		16384	/* max K5 ticket size */
+#define AFSTOKEN_K5_ADDRESSES_MAX	16	/* max K5 addresses */
+#define AFSTOKEN_K5_AUTHDATA_MAX	16	/* max K5 pieces of auth data */
+
 #endif /* _KEYS_RXRPC_TYPE_H */
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 334a359..cff4a10 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -268,6 +268,10 @@ ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \
       		  $(srctree)/include/asm-$(SRCARCH)/kvm.h),)
 unifdef-y += kvm.h
 endif
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \
+		  $(srctree)/include/asm-$(SRCARCH)/kvm_para.h),)
+unifdef-y += kvm_para.h
+endif
 unifdef-y += llc.h
 unifdef-y += loop.h
 unifdef-y += lp.h
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h
index 76fa794..880130f 100644
--- a/include/linux/agp_backend.h
+++ b/include/linux/agp_backend.h
@@ -79,9 +79,12 @@ struct agp_memory {
 	u32 physical;
 	bool is_bound;
 	bool is_flushed;
-        bool vmalloc_flag;
+	bool vmalloc_flag;
 	/* list of agp_memory mapped to the aperture */
 	struct list_head mapped_list;
+	/* DMA-mapped addresses */
+	struct scatterlist *sg_list;
+	int num_sg;
 };
 
 #define AGP_NORMAL_MEMORY 0
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 47f7d93..aea219d 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -225,8 +225,6 @@ static inline void exit_aio(struct mm_struct *mm) { }
 
 #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
 
-#include <linux/aio_abi.h>
-
 static inline struct kiocb *list_kiocb(struct list_head *h)
 {
 	return list_entry(h, struct kiocb, ki_list);
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index 9b93caf..ab94335 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -36,6 +36,11 @@ struct amba_driver {
 	struct amba_id		*id_table;
 };
 
+enum amba_vendor {
+	AMBA_VENDOR_ARM = 0x41,
+	AMBA_VENDOR_ST = 0x80,
+};
+
 #define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
 #define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
 
diff --git a/include/linux/amba/pl093.h b/include/linux/amba/pl093.h
new file mode 100644
index 0000000..2983e36
--- /dev/null
+++ b/include/linux/amba/pl093.h
@@ -0,0 +1,80 @@
+/* linux/amba/pl093.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ *	http://armlinux.simtec.co.uk/
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * AMBA PL093 SSMC (synchronous static memory controller)
+ *  See DDI0236.pdf (r0p4) for more details
+ *
+ * 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.
+*/
+
+#define SMB_BANK(x)	((x) * 0x20) /* each bank control set is 0x20 apart */
+
+/* Offsets for SMBxxxxRy registers */
+
+#define SMBIDCYR	(0x00)
+#define SMBWSTRDR	(0x04)
+#define SMBWSTWRR	(0x08)
+#define SMBWSTOENR	(0x0C)
+#define SMBWSTWENR	(0x10)
+#define SMBCR		(0x14)
+#define SMBSR		(0x18)
+#define SMBWSTBRDR	(0x1C)
+
+/* Masks for SMB registers */
+#define IDCY_MASK	(0xf)
+#define WSTRD_MASK	(0xf)
+#define WSTWR_MASK	(0xf)
+#define WSTOEN_MASK	(0xf)
+#define WSTWEN_MASK	(0xf)
+
+/* Notes from datasheet:
+ *	WSTOEN <= WSTRD
+ *	WSTWEN <= WSTWR
+ *
+ * WSTOEN is not used with nWAIT
+ */
+
+/* SMBCR bit definitions */
+#define SMBCR_BIWRITEEN		(1 << 21)
+#define SMBCR_ADDRVALIDWRITEEN	(1 << 20)
+#define SMBCR_SYNCWRITE		(1 << 17)
+#define SMBCR_BMWRITE		(1 << 16)
+#define SMBCR_WRAPREAD		(1 << 14)
+#define SMBCR_BIREADEN		(1 << 13)
+#define SMBCR_ADDRVALIDREADEN	(1 << 12)
+#define SMBCR_SYNCREAD		(1 << 9)
+#define SMBCR_BMREAD		(1 << 8)
+#define SMBCR_SMBLSPOL		(1 << 6)
+#define SMBCR_WP		(1 << 3)
+#define SMBCR_WAITEN		(1 << 2)
+#define SMBCR_WAITPOL		(1 << 1)
+#define SMBCR_RBLE		(1 << 0)
+
+#define SMBCR_BURSTLENWRITE_MASK	(3 << 18)
+#define SMBCR_BURSTLENWRITE_4		(0 << 18)
+#define SMBCR_BURSTLENWRITE_8		(1 << 18)
+#define SMBCR_BURSTLENWRITE_RESERVED	(2 << 18)
+#define SMBCR_BURSTLENWRITE_CONTINUOUS	(3 << 18)
+
+#define SMBCR_BURSTLENREAD_MASK		(3 << 10)
+#define SMBCR_BURSTLENREAD_4		(0 << 10)
+#define SMBCR_BURSTLENREAD_8		(1 << 10)
+#define SMBCR_BURSTLENREAD_16		(2 << 10)
+#define SMBCR_BURSTLENREAD_CONTINUOUS	(3 << 10)
+
+#define SMBCR_MW_MASK			(3 << 4)
+#define SMBCR_MW_8BIT			(0 << 4)
+#define SMBCR_MW_16BIT			(1 << 4)
+#define SMBCR_MW_M32BIT			(2 << 4)
+
+/* SSMC status registers */
+#define SSMCCSR		(0x200)
+#define SSMCCR		(0x204)
+#define SSMCITCR	(0x208)
+#define SSMCITIP	(0x20C)
+#define SSMCITIOP	(0x210)
diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h
index cd4bcb6..7d650a0 100644
--- a/include/linux/arcdevice.h
+++ b/include/linux/arcdevice.h
@@ -337,7 +337,8 @@ struct net_device *alloc_arcdev(const char *name);
 
 int arcnet_open(struct net_device *dev);
 int arcnet_close(struct net_device *dev);
-int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t arcnet_send_packet(struct sk_buff *skb,
+				     struct net_device *dev);
 void arcnet_timeout(struct net_device *dev);
 
 #endif				/* __KERNEL__ */
diff --git a/include/linux/attribute_container.h b/include/linux/attribute_container.h
index 794ad74..c3ab814 100644
--- a/include/linux/attribute_container.h
+++ b/include/linux/attribute_container.h
@@ -17,7 +17,7 @@ struct attribute_container {
 	struct list_head	node;
 	struct klist		containers;
 	struct class		*class;
-	struct attribute_group	*grp;
+	const struct attribute_group *grp;
 	struct device_attribute **attrs;
 	int (*match)(struct attribute_container *, struct device *);
 #define	ATTRIBUTE_CONTAINER_NO_CLASSDEVS	0x01
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index f169bcb..0ee33c2 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -59,6 +59,7 @@ struct bdi_writeback {
 
 struct backing_dev_info {
 	struct list_head bdi_list;
+	struct rcu_head rcu_head;
 	unsigned long ra_pages;	/* max readahead in PAGE_CACHE_SIZE units */
 	unsigned long state;	/* Always use atomic bitops on this */
 	unsigned int capabilities; /* Device capabilities */
@@ -100,7 +101,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
 		const char *fmt, ...);
 int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
 void bdi_unregister(struct backing_dev_info *bdi);
-void bdi_start_writeback(struct writeback_control *wbc);
+void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages);
 int bdi_writeback_task(struct bdi_writeback *wb);
 int bdi_has_dirty_io(struct backing_dev_info *bdi);
 
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 2892b71..5be93f1 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -142,56 +142,51 @@ struct bio {
  *
  * bit 0 -- data direction
  *	If not set, bio is a read from device. If set, it's a write to device.
- * bit 1 -- rw-ahead when set
- * bit 2 -- barrier
+ * bit 1 -- fail fast device errors
+ * bit 2 -- fail fast transport errors
+ * bit 3 -- fail fast driver errors
+ * bit 4 -- rw-ahead when set
+ * bit 5 -- 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.
- * bit 4 -- Unplug the device immediately after submitting this bio.
- * bit 5 -- metadata request
+ * bit 6 -- synchronous I/O hint.
+ * bit 7 -- Unplug the device immediately after submitting this bio.
+ * bit 8 -- metadata request
  *	Used for tracing to differentiate metadata and data IO. May also
  *	get some preferential treatment in the IO scheduler
- * bit 6 -- discard sectors
+ * bit 9 -- 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 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 */
-#define BIO_RW_BARRIER	2
-#define BIO_RW_SYNCIO	3
-#define BIO_RW_UNPLUG	4
-#define BIO_RW_META	5
-#define BIO_RW_DISCARD	6
-#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)))
+enum bio_rw_flags {
+	BIO_RW,
+	BIO_RW_FAILFAST_DEV,
+	BIO_RW_FAILFAST_TRANSPORT,
+	BIO_RW_FAILFAST_DRIVER,
+	/* above flags must match REQ_* */
+	BIO_RW_AHEAD,
+	BIO_RW_BARRIER,
+	BIO_RW_SYNCIO,
+	BIO_RW_UNPLUG,
+	BIO_RW_META,
+	BIO_RW_DISCARD,
+	BIO_RW_NOIDLE,
+};
 
 /*
- * Old defines, these should eventually be replaced by direct usage of
- * bio_rw_flagged()
+ * First four bits must match between bio->bi_rw and rq->cmd_flags, make
+ * that explicit here.
  */
-#define bio_barrier(bio)	bio_rw_flagged(bio, BIO_RW_BARRIER)
-#define bio_sync(bio)		bio_rw_flagged(bio, BIO_RW_SYNCIO)
-#define bio_unplug(bio)		bio_rw_flagged(bio, BIO_RW_UNPLUG)
-#define bio_failfast_dev(bio)	bio_rw_flagged(bio, BIO_RW_FAILFAST_DEV)
-#define bio_failfast_transport(bio)	\
-		bio_rw_flagged(bio, BIO_RW_FAILFAST_TRANSPORT)
-#define bio_failfast_driver(bio) 	\
-		bio_rw_flagged(bio, BIO_RW_FAILFAST_DRIVER)
-#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)
+#define BIO_RW_RQ_MASK		0xf
+
+static inline bool bio_rw_flagged(struct bio *bio, enum bio_rw_flags flag)
+{
+	return (bio->bi_rw & (1 << flag)) != 0;
+}
 
 /*
  * upper 16 bits of bi_rw define the io priority of this bio
@@ -216,7 +211,7 @@ struct bio {
 #define bio_offset(bio)		bio_iovec((bio))->bv_offset
 #define bio_segments(bio)	((bio)->bi_vcnt - (bio)->bi_idx)
 #define bio_sectors(bio)	((bio)->bi_size >> 9)
-#define bio_empty_barrier(bio)	(bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio))
+#define bio_empty_barrier(bio)	(bio_rw_flagged(bio, BIO_RW_BARRIER) && !bio_has_data(bio) && !bio_rw_flagged(bio, BIO_RW_DISCARD))
 
 static inline unsigned int bio_cur_bytes(struct bio *bio)
 {
diff --git a/include/linux/blk-iopoll.h b/include/linux/blk-iopoll.h
new file mode 100644
index 0000000..308734d
--- /dev/null
+++ b/include/linux/blk-iopoll.h
@@ -0,0 +1,48 @@
+#ifndef BLK_IOPOLL_H
+#define BLK_IOPOLL_H
+
+struct blk_iopoll;
+typedef int (blk_iopoll_fn)(struct blk_iopoll *, int);
+
+struct blk_iopoll {
+	struct list_head list;
+	unsigned long state;
+	unsigned long data;
+	int weight;
+	int max;
+	blk_iopoll_fn *poll;
+};
+
+enum {
+	IOPOLL_F_SCHED		= 0,
+	IOPOLL_F_DISABLE	= 1,
+};
+
+/*
+ * Returns 0 if we successfully set the IOPOLL_F_SCHED bit, indicating
+ * that we were the first to acquire this iop for scheduling. If this iop
+ * is currently disabled, return "failure".
+ */
+static inline int blk_iopoll_sched_prep(struct blk_iopoll *iop)
+{
+	if (!test_bit(IOPOLL_F_DISABLE, &iop->state))
+		return test_and_set_bit(IOPOLL_F_SCHED, &iop->state);
+
+	return 1;
+}
+
+static inline int blk_iopoll_disable_pending(struct blk_iopoll *iop)
+{
+	return test_bit(IOPOLL_F_DISABLE, &iop->state);
+}
+
+extern void blk_iopoll_sched(struct blk_iopoll *);
+extern void blk_iopoll_init(struct blk_iopoll *, int, blk_iopoll_fn *);
+extern void blk_iopoll_complete(struct blk_iopoll *);
+extern void __blk_iopoll_complete(struct blk_iopoll *);
+extern void blk_iopoll_enable(struct blk_iopoll *);
+extern void blk_iopoll_disable(struct blk_iopoll *);
+
+extern int blk_iopoll_enabled;
+
+#endif
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 69103e0..e23a86c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -86,13 +86,14 @@ enum {
 };
 
 /*
- * request type modified bits. first two bits match BIO_RW* bits, important
+ * request type modified bits. first four bits match BIO_RW* bits, important
  */
 enum rq_flag_bits {
 	__REQ_RW,		/* not set, read. set, write */
 	__REQ_FAILFAST_DEV,	/* no driver retries of device errors */
 	__REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
 	__REQ_FAILFAST_DRIVER,	/* no driver retries of driver errors */
+	/* above flags must match BIO_RW_* */
 	__REQ_DISCARD,		/* request to discard sectors */
 	__REQ_SORTED,		/* elevator knows about this request */
 	__REQ_SOFTBARRIER,	/* may not be passed by ioscheduler */
@@ -114,6 +115,7 @@ enum rq_flag_bits {
 	__REQ_INTEGRITY,	/* integrity metadata has been remapped */
 	__REQ_NOIDLE,		/* Don't anticipate more IO after this one */
 	__REQ_IO_STAT,		/* account I/O stat */
+	__REQ_MIXED_MERGE,	/* merge of different types, fail separately */
 	__REQ_NR_BITS,		/* stops here */
 };
 
@@ -142,6 +144,10 @@ enum rq_flag_bits {
 #define REQ_INTEGRITY	(1 << __REQ_INTEGRITY)
 #define REQ_NOIDLE	(1 << __REQ_NOIDLE)
 #define REQ_IO_STAT	(1 << __REQ_IO_STAT)
+#define REQ_MIXED_MERGE	(1 << __REQ_MIXED_MERGE)
+
+#define REQ_FAILFAST_MASK	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | \
+				 REQ_FAILFAST_DRIVER)
 
 #define BLK_MAX_CDB	16
 
@@ -453,10 +459,12 @@ struct request_queue
 #define QUEUE_FLAG_NONROT      14	/* non-rotational device (SSD) */
 #define QUEUE_FLAG_VIRT        QUEUE_FLAG_NONROT /* paravirt device */
 #define QUEUE_FLAG_IO_STAT     15	/* do IO stats */
+#define QUEUE_FLAG_CQ	       16	/* hardware does queuing */
 
 #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
 				 (1 << QUEUE_FLAG_CLUSTER) |		\
-				 (1 << QUEUE_FLAG_STACKABLE))
+				 (1 << QUEUE_FLAG_STACKABLE)	|	\
+				 (1 << QUEUE_FLAG_SAME_COMP))
 
 static inline int queue_is_locked(struct request_queue *q)
 {
@@ -575,6 +583,7 @@ enum {
 
 #define blk_queue_plugged(q)	test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
 #define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
+#define blk_queue_queuing(q)	test_bit(QUEUE_FLAG_CQ, &(q)->queue_flags)
 #define blk_queue_stopped(q)	test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
 #define blk_queue_nomerges(q)	test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
 #define blk_queue_nonrot(q)	test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags)
@@ -828,11 +837,13 @@ static inline void blk_run_address_space(struct address_space *mapping)
 }
 
 /*
- * blk_rq_pos()		: the current sector
- * blk_rq_bytes()	: bytes left in the entire request
- * blk_rq_cur_bytes()	: bytes left in the current segment
- * blk_rq_sectors()	: sectors left in the entire request
- * blk_rq_cur_sectors()	: sectors left in the current segment
+ * blk_rq_pos()			: the current sector
+ * blk_rq_bytes()		: bytes left in the entire request
+ * blk_rq_cur_bytes()		: bytes left in the current segment
+ * blk_rq_err_bytes()		: bytes left till the next error boundary
+ * blk_rq_sectors()		: sectors left in the entire request
+ * blk_rq_cur_sectors()		: sectors left in the current segment
+ * blk_rq_err_sectors()		: sectors left till the next error boundary
  */
 static inline sector_t blk_rq_pos(const struct request *rq)
 {
@@ -849,6 +860,8 @@ static inline int blk_rq_cur_bytes(const struct request *rq)
 	return rq->bio ? bio_cur_bytes(rq->bio) : 0;
 }
 
+extern unsigned int blk_rq_err_bytes(const struct request *rq);
+
 static inline unsigned int blk_rq_sectors(const struct request *rq)
 {
 	return blk_rq_bytes(rq) >> 9;
@@ -859,6 +872,11 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
 	return blk_rq_cur_bytes(rq) >> 9;
 }
 
+static inline unsigned int blk_rq_err_sectors(const struct request *rq)
+{
+	return blk_rq_err_bytes(rq) >> 9;
+}
+
 /*
  * Request issue related functions.
  */
@@ -885,10 +903,12 @@ extern bool blk_end_request(struct request *rq, int error,
 			    unsigned int nr_bytes);
 extern void blk_end_request_all(struct request *rq, int error);
 extern bool blk_end_request_cur(struct request *rq, int error);
+extern bool blk_end_request_err(struct request *rq, int error);
 extern bool __blk_end_request(struct request *rq, int error,
 			      unsigned int nr_bytes);
 extern void __blk_end_request_all(struct request *rq, int error);
 extern bool __blk_end_request_cur(struct request *rq, int error);
+extern bool __blk_end_request_err(struct request *rq, int error);
 
 extern void blk_complete_request(struct request *);
 extern void __blk_complete_request(struct request *);
@@ -915,6 +935,7 @@ extern void blk_queue_alignment_offset(struct request_queue *q,
 				       unsigned int alignment);
 extern void blk_limits_io_min(struct queue_limits *limits, unsigned int min);
 extern void blk_queue_io_min(struct request_queue *q, unsigned int min);
+extern void blk_limits_io_opt(struct queue_limits *limits, unsigned int opt);
 extern void blk_queue_io_opt(struct request_queue *q, unsigned int opt);
 extern void blk_set_default_limits(struct queue_limits *lim);
 extern int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
@@ -977,15 +998,18 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
 }
 
 extern int blkdev_issue_flush(struct block_device *, sector_t *);
-extern int blkdev_issue_discard(struct block_device *,
-				sector_t sector, sector_t nr_sects, gfp_t);
+#define DISCARD_FL_WAIT		0x01	/* wait for completion */
+#define DISCARD_FL_BARRIER	0x02	/* issue DISCARD_BARRIER request */
+extern int blkdev_issue_discard(struct block_device *, sector_t sector,
+		sector_t nr_sects, gfp_t, int flags);
 
 static inline int sb_issue_discard(struct super_block *sb,
 				   sector_t block, sector_t nr_blocks)
 {
 	block <<= (sb->s_blocksize_bits - 9);
 	nr_blocks <<= (sb->s_blocksize_bits - 9);
-	return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL);
+	return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL,
+				    DISCARD_FL_BARRIER);
 }
 
 extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm);
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 4a37a56..5824b20 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -66,5 +66,6 @@ void can_bus_off(struct net_device *dev);
 
 void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx);
 void can_get_echo_skb(struct net_device *dev, int idx);
+void can_free_echo_skb(struct net_device *dev, int idx);
 
 #endif /* CAN_DEV_H */
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 1219be4..83d2fbd 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/cache.h>
 #include <linux/timer.h>
+#include <linux/init.h>
 #include <asm/div64.h>
 #include <asm/io.h>
 
@@ -148,14 +149,11 @@ extern u64 timecounter_cyc2time(struct timecounter *tc,
  * @disable:		optional function to disable the clocksource
  * @mask:		bitmask for two's complement
  *			subtraction of non 64 bit counters
- * @mult:		cycle to nanosecond multiplier (adjusted by NTP)
- * @mult_orig:		cycle to nanosecond multiplier (unadjusted by NTP)
+ * @mult:		cycle to nanosecond multiplier
  * @shift:		cycle to nanosecond divisor (power of two)
  * @flags:		flags describing special properties
  * @vread:		vsyscall based read
  * @resume:		resume function for the clocksource, if necessary
- * @cycle_interval:	Used internally by timekeeping core, please ignore.
- * @xtime_interval:	Used internally by timekeeping core, please ignore.
  */
 struct clocksource {
 	/*
@@ -169,7 +167,6 @@ struct clocksource {
 	void (*disable)(struct clocksource *cs);
 	cycle_t mask;
 	u32 mult;
-	u32 mult_orig;
 	u32 shift;
 	unsigned long flags;
 	cycle_t (*vread)(void);
@@ -181,19 +178,12 @@ struct clocksource {
 #define CLKSRC_FSYS_MMIO_SET(mmio, addr)      do { } while (0)
 #endif
 
-	/* timekeeping specific data, ignore */
-	cycle_t cycle_interval;
-	u64	xtime_interval;
-	u32	raw_interval;
 	/*
 	 * Second part is written at each timer interrupt
 	 * Keep it in a different cache line to dirty no
 	 * more than one cache line.
 	 */
 	cycle_t cycle_last ____cacheline_aligned_in_smp;
-	u64 xtime_nsec;
-	s64 error;
-	struct timespec raw_time;
 
 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
 	/* Watchdog related data, used by the framework */
@@ -202,8 +192,6 @@ struct clocksource {
 #endif
 };
 
-extern struct clocksource *clock;	/* current clocksource */
-
 /*
  * Clock source flags bits::
  */
@@ -212,6 +200,7 @@ extern struct clocksource *clock;	/* current clocksource */
 
 #define CLOCK_SOURCE_WATCHDOG			0x10
 #define CLOCK_SOURCE_VALID_FOR_HRES		0x20
+#define CLOCK_SOURCE_UNSTABLE			0x40
 
 /* simplify initialization of mask field */
 #define CLOCKSOURCE_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
@@ -268,108 +257,15 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
 }
 
 /**
- * clocksource_read: - Access the clocksource's current cycle value
- * @cs:		pointer to clocksource being read
- *
- * Uses the clocksource to return the current cycle_t value
- */
-static inline cycle_t clocksource_read(struct clocksource *cs)
-{
-	return cs->read(cs);
-}
-
-/**
- * clocksource_enable: - enable clocksource
- * @cs:		pointer to clocksource
- *
- * Enables the specified clocksource. The clocksource callback
- * function should start up the hardware and setup mult and field
- * members of struct clocksource to reflect hardware capabilities.
- */
-static inline int clocksource_enable(struct clocksource *cs)
-{
-	int ret = 0;
-
-	if (cs->enable)
-		ret = cs->enable(cs);
-
-	/*
-	 * The frequency may have changed while the clocksource
-	 * was disabled. If so the code in ->enable() must update
-	 * the mult value to reflect the new frequency. Make sure
-	 * mult_orig follows this change.
-	 */
-	cs->mult_orig = cs->mult;
-
-	return ret;
-}
-
-/**
- * clocksource_disable: - disable clocksource
- * @cs:		pointer to clocksource
- *
- * Disables the specified clocksource. The clocksource callback
- * function should power down the now unused hardware block to
- * save power.
- */
-static inline void clocksource_disable(struct clocksource *cs)
-{
-	/*
-	 * Save mult_orig in mult so clocksource_enable() can
-	 * restore the value regardless if ->enable() updates
-	 * the value of mult or not.
-	 */
-	cs->mult = cs->mult_orig;
-
-	if (cs->disable)
-		cs->disable(cs);
-}
-
-/**
- * cyc2ns - converts clocksource cycles to nanoseconds
- * @cs:		Pointer to clocksource
- * @cycles:	Cycles
+ * clocksource_cyc2ns - converts clocksource cycles to nanoseconds
  *
- * Uses the clocksource and ntp ajdustment to convert cycle_ts to nanoseconds.
+ * Converts cycles to nanoseconds, using the given mult and shift.
  *
  * XXX - This could use some mult_lxl_ll() asm optimization
  */
-static inline s64 cyc2ns(struct clocksource *cs, cycle_t cycles)
-{
-	u64 ret = (u64)cycles;
-	ret = (ret * cs->mult) >> cs->shift;
-	return ret;
-}
-
-/**
- * clocksource_calculate_interval - Calculates a clocksource interval struct
- *
- * @c:		Pointer to clocksource.
- * @length_nsec: Desired interval length in nanoseconds.
- *
- * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment
- * pair and interval request.
- *
- * Unless you're the timekeeping code, you should not be using this!
- */
-static inline void clocksource_calculate_interval(struct clocksource *c,
-					  	  unsigned long length_nsec)
+static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift)
 {
-	u64 tmp;
-
-	/* Do the ns -> cycle conversion first, using original mult */
-	tmp = length_nsec;
-	tmp <<= c->shift;
-	tmp += c->mult_orig/2;
-	do_div(tmp, c->mult_orig);
-
-	c->cycle_interval = (cycle_t)tmp;
-	if (c->cycle_interval == 0)
-		c->cycle_interval = 1;
-
-	/* Go back from cycles -> shifted ns, this time use ntp adjused mult */
-	c->xtime_interval = (u64)c->cycle_interval * c->mult;
-	c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
+	return ((u64) cycles * mult) >> shift;
 }
 
 
@@ -380,6 +276,8 @@ extern void clocksource_touch_watchdog(void);
 extern struct clocksource* clocksource_get_next(void);
 extern void clocksource_change_rating(struct clocksource *cs, int rating);
 extern void clocksource_resume(void);
+extern struct clocksource * __init __weak clocksource_default_clock(void);
+extern void clocksource_mark_unstable(struct clocksource *cs);
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL
 extern void update_vsyscall(struct timespec *ts, struct clocksource *c);
@@ -394,4 +292,6 @@ static inline void update_vsyscall_tz(void)
 }
 #endif
 
+extern void timekeeping_notify(struct clocksource *clock);
+
 #endif /* _LINUX_CLOCKSOURCE_H */
diff --git a/include/linux/connector.h b/include/linux/connector.h
index b68d278..47ebf41 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -136,7 +136,7 @@ struct cn_callback_data {
 	void *ddata;
 	
 	void *callback_priv;
-	void (*callback) (void *);
+	void (*callback) (struct cn_msg *);
 
 	void *free;
 };
@@ -167,11 +167,11 @@ struct cn_dev {
 	struct cn_queue_dev *cbdev;
 };
 
-int cn_add_callback(struct cb_id *, char *, void (*callback) (void *));
+int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *));
 void cn_del_callback(struct cb_id *);
 int cn_netlink_send(struct cn_msg *, u32, gfp_t);
 
-int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(void *));
+int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *));
 void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
 
 int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 1610427..44717eb 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -65,6 +65,9 @@ static inline int cpufreq_unregister_notifier(struct notifier_block *nb,
 
 struct cpufreq_governor;
 
+/* /sys/devices/system/cpu/cpufreq: entry point for global variables */
+extern struct kobject *cpufreq_global_kobject;
+
 #define CPUFREQ_ETERNAL			(-1)
 struct cpufreq_cpuinfo {
 	unsigned int		max_freq;
@@ -274,6 +277,13 @@ struct freq_attr {
 	ssize_t (*store)(struct cpufreq_policy *, const char *, size_t count);
 };
 
+struct global_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct kobject *kobj,
+			struct attribute *attr, char *buf);
+	ssize_t (*store)(struct kobject *a, struct attribute *b,
+			 const char *c, size_t count);
+};
 
 /*********************************************************************
  *                        CPUFREQ 2.6. INTERFACE                     *
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 24520a5..fb37160 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -15,6 +15,7 @@
 #include <linux/capability.h>
 #include <linux/init.h>
 #include <linux/key.h>
+#include <linux/selinux.h>
 #include <asm/atomic.h>
 
 struct user_struct;
@@ -182,11 +183,13 @@ static inline bool creds_are_invalid(const struct cred *cred)
 	if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
 		return true;
 #ifdef CONFIG_SECURITY_SELINUX
-	if ((unsigned long) cred->security < PAGE_SIZE)
-		return true;
-	if ((*(u32*)cred->security & 0xffffff00) ==
-	    (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
-		return true;
+	if (selinux_is_enabled()) {
+		if ((unsigned long) cred->security < PAGE_SIZE)
+			return true;
+		if ((*(u32 *)cred->security & 0xffffff00) ==
+		    (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
+			return true;
+	}
 #endif
 	return false;
 }
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h
index 1fbdea4..a5049ea 100644
--- a/include/linux/cyclades.h
+++ b/include/linux/cyclades.h
@@ -499,6 +499,7 @@ struct cyclades_card {
 		void __iomem *p9050;
 		struct RUNTIME_9060 __iomem *p9060;
 	} ctl_addr;
+	struct BOARD_CTRL __iomem *board_ctrl;	/* cyz specific */
 	int irq;
 	unsigned int num_chips;	/* 0 if card absent, -1 if Z/PCI, else Y */
 	unsigned int first_line;	/* minor number of first channel on card */
@@ -541,6 +542,15 @@ struct cyclades_port {
 	int                     magic;
 	struct tty_port		port;
 	struct cyclades_card	*card;
+	union {
+		struct {
+			void __iomem *base_addr;
+		} cyy;
+		struct {
+			struct CH_CTRL __iomem	*ch_ctrl;
+			struct BUF_CTRL __iomem	*buf_ctrl;
+		} cyz;
+	} u;
 	int			line;
 	int			flags; 		/* defined in tty.h */
 	int                     type;		/* UART type */
@@ -568,7 +578,6 @@ struct cyclades_port {
 	struct cyclades_idle_stats	idle_stats;
 	struct cyclades_icount	icount;
 	struct completion       shutdown_wait;
-	wait_queue_head_t       delta_msr_wait;
 	int throttle;
 };
 
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 7d2e100..b7cdbb4 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -50,6 +50,8 @@ struct dcbmsg {
  * @DCB_CMD_SNUMTCS: set the number of traffic classes
  * @DCB_CMD_GBCN: set backward congestion notification configuration
  * @DCB_CMD_SBCN: get backward congestion notification configration.
+ * @DCB_CMD_GAPP: get application protocol configuration
+ * @DCB_CMD_SAPP: set application protocol configuration
  */
 enum dcbnl_commands {
 	DCB_CMD_UNDEFINED,
@@ -80,6 +82,9 @@ enum dcbnl_commands {
 	DCB_CMD_BCN_GCFG,
 	DCB_CMD_BCN_SCFG,
 
+	DCB_CMD_GAPP,
+	DCB_CMD_SAPP,
+
 	__DCB_CMD_ENUM_MAX,
 	DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
 };
@@ -114,6 +119,7 @@ enum dcbnl_attrs {
 	DCB_ATTR_CAP,
 	DCB_ATTR_NUMTCS,
 	DCB_ATTR_BCN,
+	DCB_ATTR_APP,
 
 	__DCB_ATTR_ENUM_MAX,
 	DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1,
@@ -338,5 +344,17 @@ enum dcb_general_attr_values {
 	DCB_ATTR_VALUE_UNDEFINED = 0xff
 };
 
+#define DCB_APP_IDTYPE_ETHTYPE	0x00
+#define DCB_APP_IDTYPE_PORTNUM	0x01
+enum dcbnl_app_attrs {
+	DCB_APP_ATTR_UNDEFINED,
+
+	DCB_APP_ATTR_IDTYPE,
+	DCB_APP_ATTR_ID,
+	DCB_APP_ATTR_PRIORITY,
+
+	__DCB_APP_ATTR_ENUM_MAX,
+	DCB_APP_ATTR_MAX = __DCB_APP_ATTR_ENUM_MAX - 1,
+};
 
 #endif /* __LINUX_DCBNL_H__ */
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
index f352f06..5076fe0 100644
--- a/include/linux/delayacct.h
+++ b/include/linux/delayacct.h
@@ -18,7 +18,6 @@
 #define _LINUX_DELAYACCT_H
 
 #include <linux/sched.h>
-#include <linux/taskstats_kern.h>
 
 /*
  * Per-task flags relevant to delay accounting
diff --git a/include/linux/device.h b/include/linux/device.h
index aebb810..aca31bf 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -2,7 +2,8 @@
  * device.h - generic, centralized driver model
  *
  * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
- * Copyright (c) 2004-2007 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (c) 2004-2009 Greg Kroah-Hartman <gregkh@suse.de>
+ * Copyright (c) 2008-2009 Novell Inc.
  *
  * This file is released under the GPLv2
  *
@@ -62,7 +63,7 @@ struct bus_type {
 	int (*suspend)(struct device *dev, pm_message_t state);
 	int (*resume)(struct device *dev);
 
-	struct dev_pm_ops *pm;
+	const struct dev_pm_ops *pm;
 
 	struct bus_type_private *p;
 };
@@ -130,9 +131,9 @@ struct device_driver {
 	void (*shutdown) (struct device *dev);
 	int (*suspend) (struct device *dev, pm_message_t state);
 	int (*resume) (struct device *dev);
-	struct attribute_group **groups;
+	const struct attribute_group **groups;
 
-	struct dev_pm_ops *pm;
+	const struct dev_pm_ops *pm;
 
 	struct driver_private *p;
 };
@@ -192,7 +193,7 @@ struct class {
 	struct kobject			*dev_kobj;
 
 	int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
-	char *(*nodename)(struct device *dev);
+	char *(*devnode)(struct device *dev, mode_t *mode);
 
 	void (*class_release)(struct class *class);
 	void (*dev_release)(struct device *dev);
@@ -200,7 +201,8 @@ struct class {
 	int (*suspend)(struct device *dev, pm_message_t state);
 	int (*resume)(struct device *dev);
 
-	struct dev_pm_ops *pm;
+	const struct dev_pm_ops *pm;
+
 	struct class_private *p;
 };
 
@@ -223,6 +225,14 @@ extern void class_unregister(struct class *class);
 	__class_register(class, &__key);	\
 })
 
+struct class_compat;
+struct class_compat *class_compat_register(const char *name);
+void class_compat_unregister(struct class_compat *cls);
+int class_compat_create_link(struct class_compat *cls, struct device *dev,
+			     struct device *device_link);
+void class_compat_remove_link(struct class_compat *cls, struct device *dev,
+			      struct device *device_link);
+
 extern void class_dev_iter_init(struct class_dev_iter *iter,
 				struct class *class,
 				struct device *start,
@@ -286,12 +296,12 @@ extern void class_destroy(struct class *cls);
  */
 struct device_type {
 	const char *name;
-	struct attribute_group **groups;
+	const struct attribute_group **groups;
 	int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
-	char *(*nodename)(struct device *dev);
+	char *(*devnode)(struct device *dev, mode_t *mode);
 	void (*release)(struct device *dev);
 
-	struct dev_pm_ops *pm;
+	const struct dev_pm_ops *pm;
 };
 
 /* interface for exporting device attributes */
@@ -380,7 +390,6 @@ struct device {
 	struct bus_type	*bus;		/* type of bus device is on */
 	struct device_driver *driver;	/* which driver has allocated this
 					   device */
-	void		*driver_data;	/* data private to the driver */
 	void		*platform_data;	/* Platform specific data, device
 					   core doesn't touch it */
 	struct dev_pm_info	power;
@@ -411,7 +420,7 @@ struct device {
 
 	struct klist_node	knode_class;
 	struct class		*class;
-	struct attribute_group	**groups;	/* optional groups */
+	const struct attribute_group **groups;	/* optional groups */
 
 	void	(*release)(struct device *dev);
 };
@@ -446,16 +455,6 @@ static inline void set_dev_node(struct device *dev, int node)
 }
 #endif
 
-static inline void *dev_get_drvdata(const struct device *dev)
-{
-	return dev->driver_data;
-}
-
-static inline void dev_set_drvdata(struct device *dev, void *data)
-{
-	dev->driver_data = data;
-}
-
 static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
 {
 	return dev->kobj.uevent_suppress;
@@ -488,7 +487,10 @@ extern struct device *device_find_child(struct device *dev, void *data,
 extern int device_rename(struct device *dev, char *new_name);
 extern int device_move(struct device *dev, struct device *new_parent,
 		       enum dpm_order dpm_order);
-extern const char *device_get_nodename(struct device *dev, const char **tmp);
+extern const char *device_get_devnode(struct device *dev,
+				      mode_t *mode, const char **tmp);
+extern void *dev_get_drvdata(const struct device *dev);
+extern void dev_set_drvdata(struct device *dev, void *data);
 
 /*
  * Root device objects for grouping under /sys/devices
@@ -501,6 +503,11 @@ static inline struct device *root_device_register(const char *name)
 }
 extern void root_device_unregister(struct device *root);
 
+static inline void *dev_get_platdata(const struct device *dev)
+{
+	return dev->platform_data;
+}
+
 /*
  * Manual binding of a device to driver. See drivers/base/bus.c
  * for information on use.
@@ -546,6 +553,16 @@ extern void put_device(struct device *dev);
 
 extern void wait_for_device_probe(void);
 
+#ifdef CONFIG_DEVTMPFS
+extern int devtmpfs_create_node(struct device *dev);
+extern int devtmpfs_delete_node(struct device *dev);
+extern int devtmpfs_mount(const char *mountpoint);
+#else
+static inline int devtmpfs_create_node(struct device *dev) { return 0; }
+static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
+static inline int devtmpfs_mount(const char *mountpoint) { return 0; }
+#endif
+
 /* drivers/base/power/shutdown.c */
 extern void device_shutdown(void);
 
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index c0f6c3c..91b7618 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -58,6 +58,7 @@ struct dma_map_ops {
 				   enum dma_data_direction dir);
 	int (*mapping_error)(struct device *dev, dma_addr_t dma_addr);
 	int (*dma_supported)(struct device *dev, u64 mask);
+	int (*set_dma_mask)(struct device *dev, u64 mask);
 	int is_phys;
 };
 
diff --git a/include/linux/dtlk.h b/include/linux/dtlk.h
index 2896d90..22a7b9a 100644
--- a/include/linux/dtlk.h
+++ b/include/linux/dtlk.h
@@ -1,22 +1,3 @@
-#if 0
-
-#define TRACE_TXT(text) \
-	{ \
-	  if(dtlk_trace) \
-	  { \
-	    console_print(text); \
-	    console_print("\n"); \
-	  } \
-	}
-
-#define TRACE_CHR(chr) \
-	{ \
-	  if(dtlk_trace) \
-	    console_print(chr); \
-	} \
-
-#endif
-
 #define DTLK_MINOR	0
 #define DTLK_IO_EXTENT	0x02
 
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
index fef9437..f078f3a 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/linux/dvb/dmx.h
@@ -151,5 +151,7 @@ struct dmx_stc {
 #define DMX_GET_CAPS             _IOR('o', 48, dmx_caps_t)
 #define DMX_SET_SOURCE           _IOW('o', 49, dmx_source_t)
 #define DMX_GET_STC              _IOWR('o', 50, struct dmx_stc)
+#define DMX_ADD_PID              _IOW('o', 51, __u16)
+#define DMX_REMOVE_PID           _IOW('o', 52, __u16)
 
 #endif /*_DVBDMX_H_*/
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index 51c8d2d..b6cb542 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -173,7 +173,8 @@ typedef enum fe_modulation {
 typedef enum fe_transmit_mode {
 	TRANSMISSION_MODE_2K,
 	TRANSMISSION_MODE_8K,
-	TRANSMISSION_MODE_AUTO
+	TRANSMISSION_MODE_AUTO,
+	TRANSMISSION_MODE_4K
 } fe_transmit_mode_t;
 
 typedef enum fe_bandwidth {
@@ -268,15 +269,42 @@ struct dvb_frontend_event {
 #define DTV_FE_CAPABILITY	16
 #define DTV_DELIVERY_SYSTEM	17
 
-#define DTV_API_VERSION				35
-#define DTV_API_VERSION				35
-#define DTV_CODE_RATE_HP			36
-#define DTV_CODE_RATE_LP			37
-#define DTV_GUARD_INTERVAL			38
-#define DTV_TRANSMISSION_MODE			39
-#define DTV_HIERARCHY				40
+/* ISDB-T and ISDB-Tsb */
+#define DTV_ISDBT_PARTIAL_RECEPTION	18
+#define DTV_ISDBT_SOUND_BROADCASTING	19
 
-#define DTV_MAX_COMMAND				DTV_HIERARCHY
+#define DTV_ISDBT_SB_SUBCHANNEL_ID	20
+#define DTV_ISDBT_SB_SEGMENT_IDX	21
+#define DTV_ISDBT_SB_SEGMENT_COUNT	22
+
+#define DTV_ISDBT_LAYERA_FEC			23
+#define DTV_ISDBT_LAYERA_MODULATION		24
+#define DTV_ISDBT_LAYERA_SEGMENT_COUNT		25
+#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING	26
+
+#define DTV_ISDBT_LAYERB_FEC			27
+#define DTV_ISDBT_LAYERB_MODULATION		28
+#define DTV_ISDBT_LAYERB_SEGMENT_COUNT		29
+#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING	30
+
+#define DTV_ISDBT_LAYERC_FEC			31
+#define DTV_ISDBT_LAYERC_MODULATION		32
+#define DTV_ISDBT_LAYERC_SEGMENT_COUNT		33
+#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING	34
+
+#define DTV_API_VERSION		35
+
+#define DTV_CODE_RATE_HP	36
+#define DTV_CODE_RATE_LP	37
+#define DTV_GUARD_INTERVAL	38
+#define DTV_TRANSMISSION_MODE	39
+#define DTV_HIERARCHY		40
+
+#define DTV_ISDBT_LAYER_ENABLED	41
+
+#define DTV_ISDBS_TS_ID		42
+
+#define DTV_MAX_COMMAND				DTV_ISDBS_TS_ID
 
 typedef enum fe_pilot {
 	PILOT_ON,
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
index 25b823b..540b058 100644
--- a/include/linux/dvb/version.h
+++ b/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
 #define _DVBVERSION_H_
 
 #define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 0
+#define DVB_API_VERSION_MINOR 1
 
 #endif /*_DVBVERSION_H_*/
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index 4332442..90d1c21 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -122,8 +122,9 @@ enclosure_component_register(struct enclosure_device *, unsigned int,
 				 enum enclosure_component_type, const char *);
 int enclosure_add_device(struct enclosure_device *enclosure, int component,
 			 struct device *dev);
-int enclosure_remove_device(struct enclosure_device *enclosure, int component);
-struct enclosure_device *enclosure_find(struct device *dev);
+int enclosure_remove_device(struct enclosure_device *, struct device *);
+struct enclosure_device *enclosure_find(struct device *dev,
+					struct enclosure_device *start);
 int enclosure_for_each_device(int (*fn)(struct enclosure_device *, void *),
 			      void *data);
 
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 9b660bd..15e4eb7 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -362,12 +362,25 @@ struct ethtool_rxnfc {
 	__u32				rule_locs[0];
 };
 
+#define ETHTOOL_FLASH_MAX_FILENAME	128
+enum ethtool_flash_op_type {
+	ETHTOOL_FLASH_ALL_REGIONS	= 0,
+};
+
+/* for passing firmware flashing related parameters */
+struct ethtool_flash {
+	__u32	cmd;
+	__u32	region;
+	char	data[ETHTOOL_FLASH_MAX_FILENAME];
+};
+
 #ifdef __KERNEL__
 
 struct net_device;
 
 /* Some generic methods drivers may use in their ethtool_ops */
 u32 ethtool_op_get_link(struct net_device *dev);
+u32 ethtool_op_get_rx_csum(struct net_device *dev);
 u32 ethtool_op_get_tx_csum(struct net_device *dev);
 int ethtool_op_set_tx_csum(struct net_device *dev, u32 data);
 int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data);
@@ -488,6 +501,7 @@ struct ethtool_ops {
 	int	(*get_stats_count)(struct net_device *);/* use get_sset_count */
 	int	(*get_rxnfc)(struct net_device *, struct ethtool_rxnfc *, void *);
 	int	(*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
+	int     (*flash_device)(struct net_device *, struct ethtool_flash *);
 };
 #endif /* __KERNEL__ */
 
@@ -544,6 +558,7 @@ struct ethtool_ops {
 #define	ETHTOOL_GRXCLSRLALL	0x00000030 /* Get all RX classification rule */
 #define	ETHTOOL_SRXCLSRLDEL	0x00000031 /* Delete RX classification rule */
 #define	ETHTOOL_SRXCLSRLINS	0x00000032 /* Insert RX classification rule */
+#define	ETHTOOL_FLASHDEV	0x00000033 /* Flash firmware to device */
 
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a79f483..90162fb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -161,8 +161,8 @@ struct inodes_stat_t {
  * These aren't really reads or writes, they pass down information about
  * parts of device that are now unused by the file system.
  */
-#define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD)
-#define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER))
+#define DISCARD_NOBARRIER (WRITE | (1 << BIO_RW_DISCARD))
+#define DISCARD_BARRIER (DISCARD_NOBARRIER | (1 << BIO_RW_BARRIER))
 
 #define SEL_IN		1
 #define SEL_OUT		2
@@ -655,7 +655,6 @@ struct block_device {
 	int			bd_invalidated;
 	struct gendisk *	bd_disk;
 	struct list_head	bd_list;
-	struct backing_dev_info *bd_inode_backing_dev_info;
 	/*
 	 * Private data.  You must have bd_claim'ed the block_device
 	 * to use this.  NOTE:  bd_claim allows an owner to claim
@@ -1343,6 +1342,7 @@ struct super_block {
 	int			s_nr_dentry_unused;	/* # of dentry on lru */
 
 	struct block_device	*s_bdev;
+	struct backing_dev_info *s_bdi;
 	struct mtd_info		*s_mtd;
 	struct list_head	s_instances;
 	struct quota_info	s_dquot;	/* Diskquota specific options */
@@ -1455,11 +1455,6 @@ int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags);
 #define DT_SOCK		12
 #define DT_WHT		14
 
-#define OSYNC_METADATA	(1<<0)
-#define OSYNC_DATA	(1<<1)
-#define OSYNC_INODE	(1<<2)
-int generic_osync_inode(struct inode *, struct address_space *, int);
-
 /*
  * This is the "filldir" function type, used by readdir() to let
  * the kernel specify what kind of dirent layout it wants to have.
@@ -2086,6 +2081,8 @@ extern int write_inode_now(struct inode *, int);
 extern int filemap_fdatawrite(struct address_space *);
 extern int filemap_flush(struct address_space *);
 extern int filemap_fdatawait(struct address_space *);
+extern int filemap_fdatawait_range(struct address_space *, loff_t lstart,
+				   loff_t lend);
 extern int filemap_write_and_wait(struct address_space *mapping);
 extern int filemap_write_and_wait_range(struct address_space *mapping,
 				        loff_t lstart, loff_t lend);
@@ -2096,7 +2093,10 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping,
 extern int filemap_fdatawrite_range(struct address_space *mapping,
 				loff_t start, loff_t end);
 
+extern int vfs_fsync_range(struct file *file, struct dentry *dentry,
+			   loff_t start, loff_t end, int datasync);
 extern int vfs_fsync(struct file *file, struct dentry *dentry, int datasync);
+extern int generic_write_sync(struct file *file, loff_t pos, loff_t count);
 extern void sync_supers(void);
 extern void emergency_sync(void);
 extern void emergency_remount(void);
@@ -2202,9 +2202,9 @@ extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
 extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
 int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
 extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
+extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long,
+		loff_t *);
 extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
-extern ssize_t generic_file_aio_write_nolock(struct kiocb *, const struct iovec *,
-		unsigned long, loff_t);
 extern ssize_t generic_file_direct_write(struct kiocb *, const struct iovec *,
 		unsigned long *, loff_t, loff_t *, size_t, size_t);
 extern ssize_t generic_file_buffered_write(struct kiocb *, const struct iovec *,
@@ -2214,6 +2214,10 @@ extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t l
 extern int generic_segment_checks(const struct iovec *iov,
 		unsigned long *nr_segs, size_t *count, int access_flags);
 
+/* fs/block_dev.c */
+extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
+				unsigned long nr_segs, loff_t pos);
+
 /* fs/splice.c */
 extern ssize_t generic_file_splice_read(struct file *, loff_t *,
 		struct pipe_inode_info *, size_t, unsigned int);
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index dc3b132..3c0924a 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -446,7 +446,6 @@ static inline void unpause_graph_tracing(void) { }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
 #ifdef CONFIG_TRACING
-#include <linux/sched.h>
 
 /* flags for current->trace */
 enum {
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 23f7179..4ec5e67 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -1,9 +1,10 @@
 #ifndef _LINUX_FTRACE_EVENT_H
 #define _LINUX_FTRACE_EVENT_H
 
-#include <linux/trace_seq.h>
 #include <linux/ring_buffer.h>
+#include <linux/trace_seq.h>
 #include <linux/percpu.h>
+#include <linux/hardirq.h>
 
 struct trace_array;
 struct tracer;
@@ -34,7 +35,7 @@ struct trace_entry {
 	unsigned char		flags;
 	unsigned char		preempt_count;
 	int			pid;
-	int			tgid;
+	int			lock_depth;
 };
 
 #define FTRACE_MAX_EVENT						\
@@ -130,12 +131,17 @@ struct ftrace_event_call {
 	void			*data;
 
 	atomic_t		profile_count;
-	int			(*profile_enable)(struct ftrace_event_call *);
-	void			(*profile_disable)(struct ftrace_event_call *);
+	int			(*profile_enable)(void);
+	void			(*profile_disable)(void);
 };
 
+#define FTRACE_MAX_PROFILE_SIZE	2048
+
+extern char			*trace_profile_buf;
+extern char			*trace_profile_buf_nmi;
+
 #define MAX_FILTER_PRED		32
-#define MAX_FILTER_STR_VAL	128
+#define MAX_FILTER_STR_VAL	256	/* Should handle KSYM_SYMBOL_LEN */
 
 extern void destroy_preds(struct ftrace_event_call *call);
 extern int filter_match_preds(struct ftrace_event_call *call, void *rec);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index cf593bf..3e2925a 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -30,6 +30,10 @@
  *  - add umask flag to input argument of open, mknod and mkdir
  *  - add notification messages for invalidation of inodes and
  *    directory entries
+ *
+ * 7.13
+ *  - make max number of background requests and congestion threshold
+ *    tunables
  */
 
 #ifndef _LINUX_FUSE_H
@@ -37,11 +41,31 @@
 
 #include <linux/types.h>
 
+/*
+ * Version negotiation:
+ *
+ * Both the kernel and userspace send the version they support in the
+ * INIT request and reply respectively.
+ *
+ * If the major versions match then both shall use the smallest
+ * of the two minor versions for communication.
+ *
+ * If the kernel supports a larger major version, then userspace shall
+ * reply with the major version it supports, ignore the rest of the
+ * INIT message and expect a new INIT message from the kernel with a
+ * matching major version.
+ *
+ * If the library supports a larger major version, then it shall fall
+ * back to the major protocol version sent by the kernel for
+ * communication and reply with that major version (and an arbitrary
+ * supported minor version).
+ */
+
 /** Version number of this interface */
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 12
+#define FUSE_KERNEL_MINOR_VERSION 13
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -427,7 +451,8 @@ struct fuse_init_out {
 	__u32	minor;
 	__u32	max_readahead;
 	__u32	flags;
-	__u32	unused;
+	__u16   max_background;
+	__u16   congestion_threshold;
 	__u32	max_write;
 };
 
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 45fc320..109d179 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -98,7 +98,7 @@ struct hd_struct {
 	int make_it_fail;
 #endif
 	unsigned long stamp;
-	int in_flight;
+	int in_flight[2];
 #ifdef	CONFIG_SMP
 	struct disk_stats *dkstats;
 #else
@@ -142,7 +142,7 @@ struct gendisk {
                                          * disks that can't be partitioned. */
 
 	char disk_name[DISK_NAME_LEN];	/* name of major driver */
-	char *(*nodename)(struct gendisk *gd);
+	char *(*devnode)(struct gendisk *gd, mode_t *mode);
 	/* Array of pointers to partitions indexed by partno.
 	 * Protected with matching bdev lock but stat and other
 	 * non-critical accesses use RCU.  Always access through
@@ -322,18 +322,23 @@ static inline void free_part_stats(struct hd_struct *part)
 #define part_stat_sub(cpu, gendiskp, field, subnd)			\
 	part_stat_add(cpu, gendiskp, field, -subnd)
 
-static inline void part_inc_in_flight(struct hd_struct *part)
+static inline void part_inc_in_flight(struct hd_struct *part, int rw)
 {
-	part->in_flight++;
+	part->in_flight[rw]++;
 	if (part->partno)
-		part_to_disk(part)->part0.in_flight++;
+		part_to_disk(part)->part0.in_flight[rw]++;
 }
 
-static inline void part_dec_in_flight(struct hd_struct *part)
+static inline void part_dec_in_flight(struct hd_struct *part, int rw)
 {
-	part->in_flight--;
+	part->in_flight[rw]--;
 	if (part->partno)
-		part_to_disk(part)->part0.in_flight--;
+		part_to_disk(part)->part0.in_flight[rw]--;
+}
+
+static inline int part_in_flight(struct hd_struct *part)
+{
+	return part->in_flight[0] + part->in_flight[1];
 }
 
 /* block/blk-core.c */
@@ -546,6 +551,8 @@ extern ssize_t part_size_show(struct device *dev,
 			      struct device_attribute *attr, char *buf);
 extern ssize_t part_stat_show(struct device *dev,
 			      struct device_attribute *attr, char *buf);
+extern ssize_t part_inflight_show(struct device *dev,
+			      struct device_attribute *attr, char *buf);
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 extern ssize_t part_fail_show(struct device *dev,
 			      struct device_attribute *attr, char *buf);
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index c56b4bc..b80c88d 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -333,6 +333,28 @@ struct gfs2_leaf {
 
 /*
  * Extended attribute header format
+ *
+ * This works in a similar way to dirents. There is a fixed size header
+ * followed by a variable length section made up of the name and the
+ * associated data. In the case of a "stuffed" entry, the value is
+ * inline directly after the name, the ea_num_ptrs entry will be
+ * zero in that case. For non-"stuffed" entries, there will be
+ * a set of pointers (aligned to 8 byte boundary) to the block(s)
+ * containing the value.
+ *
+ * The blocks containing the values and the blocks containing the
+ * extended attribute headers themselves all start with the common
+ * metadata header. Each inode, if it has extended attributes, will
+ * have either a single block containing the extended attribute headers
+ * or a single indirect block pointing to blocks containing the
+ * extended attribure headers.
+ *
+ * The maximim size of the data part of an extended attribute is 64k
+ * so the number of blocks required depends upon block size. Since the
+ * block size also determines the number of pointers in an indirect
+ * block, its a fairly complicated calculation to work out the maximum
+ * number of blocks that an inode may have relating to extended attributes.
+ *
  */
 
 #define GFS2_EA_MAX_NAME_LEN	255
diff --git a/include/linux/hayesesp.h b/include/linux/hayesesp.h
index 940aeb5..92b08cf 100644
--- a/include/linux/hayesesp.h
+++ b/include/linux/hayesesp.h
@@ -96,7 +96,6 @@ struct esp_struct {
 	int			xmit_head;
 	int			xmit_tail;
 	int			xmit_cnt;
-	wait_queue_head_t	delta_msr_wait;
 	wait_queue_head_t	break_wait;
 	struct async_icount	icount;	/* kernel counters for the 4 input interrupts */
 	struct hayes_esp_config config; /* port configuration */
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index 6a6e701..ee275c8 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -38,7 +38,7 @@ struct hdlc_proto {
 	int (*ioctl)(struct net_device *dev, struct ifreq *ifr);
 	__be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev);
 	int (*netif_rx)(struct sk_buff *skb);
-	int (*xmit)(struct sk_buff *skb, struct net_device *dev);
+	netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
 	struct module *module;
 	struct hdlc_proto *next; /* next protocol in the list */
 };
@@ -51,7 +51,7 @@ typedef struct hdlc_device {
 		      unsigned short encoding, unsigned short parity);
 
 	/* hardware driver must handle this instead of dev->hard_start_xmit */
-	int (*xmit)(struct sk_buff *skb, struct net_device *dev);
+	netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
 
 	/* Things below are for HDLC layer internal use only */
 	const struct hdlc_proto *proto;
@@ -60,7 +60,7 @@ typedef struct hdlc_device {
 	spinlock_t state_lock;
 	void *state;
 	void *priv;
-}hdlc_device;
+} hdlc_device;
 
 
 
@@ -106,7 +106,7 @@ void hdlc_close(struct net_device *dev);
 /* May be used by hardware driver */
 int hdlc_change_mtu(struct net_device *dev, int new_mtu);
 /* Must be pointed to by hw driver's dev->netdev_ops->ndo_start_xmit */
-int hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev);
 
 int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
 			 size_t size);
diff --git a/include/linux/hid-debug.h b/include/linux/hid-debug.h
index 50d568e..53744fa 100644
--- a/include/linux/hid-debug.h
+++ b/include/linux/hid-debug.h
@@ -2,7 +2,7 @@
 #define __HID_DEBUG_H
 
 /*
- *  Copyright (c) 2007	Jiri Kosina
+ *  Copyright (c) 2007-2009	Jiri Kosina
  */
 
 /*
@@ -22,24 +22,44 @@
  *
  */
 
-#ifdef CONFIG_HID_DEBUG
+#define HID_DEBUG_BUFSIZE 512
 
-void hid_dump_input(struct hid_usage *, __s32);
-void hid_dump_device(struct hid_device *);
-void hid_dump_field(struct hid_field *, int);
-void hid_resolv_usage(unsigned);
-void hid_resolv_event(__u8, __u16);
+#ifdef CONFIG_DEBUG_FS
+
+void hid_dump_input(struct hid_device *, struct hid_usage *, __s32);
+void hid_dump_device(struct hid_device *, struct seq_file *);
+void hid_dump_field(struct hid_field *, int, struct seq_file *);
+char *hid_resolv_usage(unsigned, struct seq_file *);
+void hid_debug_register(struct hid_device *, const char *);
+void hid_debug_unregister(struct hid_device *);
+void hid_debug_init(void);
+void hid_debug_exit(void);
+void hid_debug_event(struct hid_device *, char *);
 
-#else
 
-#define hid_dump_input(a,b)     do { } while (0)
-#define hid_dump_device(c)      do { } while (0)
-#define hid_dump_field(a,b)     do { } while (0)
-#define hid_resolv_usage(a)         do { } while (0)
-#define hid_resolv_event(a,b)       do { } while (0)
+struct hid_debug_list {
+	char *hid_debug_buf;
+	int head;
+	int tail;
+	struct fasync_struct *fasync;
+	struct hid_device *hdev;
+	struct list_head node;
+	struct mutex read_mutex;
+};
 
-#endif /* CONFIG_HID_DEBUG */
+#else
 
+#define hid_dump_input(a,b,c)		do { } while (0)
+#define hid_dump_device(a,b)		do { } while (0)
+#define hid_dump_field(a,b,c)		do { } while (0)
+#define hid_resolv_usage(a,b)		do { } while (0)
+#define hid_debug_register(a, b)	do { } while (0)
+#define hid_debug_unregister(a)		do { } while (0)
+#define hid_debug_init()		do { } while (0)
+#define hid_debug_exit()		do { } while (0)
+#define hid_debug_event(a,b)		do { } while (0)
+
+#endif
 
 #endif
 
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 53489fd..a0ebdac 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -500,6 +500,14 @@ struct hid_device {							/* device report descriptor */
 
 	/* handler for raw output data, used by hidraw */
 	int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
+
+	/* debugging support via debugfs */
+	unsigned short debug;
+	struct dentry *debug_dir;
+	struct dentry *debug_rdesc;
+	struct dentry *debug_events;
+	struct list_head debug_list;
+	wait_queue_head_t debug_wait;
 };
 
 static inline void *hid_get_drvdata(struct hid_device *hdev)
@@ -657,9 +665,7 @@ struct hid_ll_driver {
 
 /* HID core API */
 
-#ifdef CONFIG_HID_DEBUG
 extern int hid_debug;
-#endif
 
 extern int hid_add_device(struct hid_device *);
 extern void hid_destroy_device(struct hid_device *);
@@ -815,21 +821,9 @@ int hid_pidff_init(struct hid_device *hid);
 #define hid_pidff_init NULL
 #endif
 
-#ifdef CONFIG_HID_DEBUG
 #define dbg_hid(format, arg...) if (hid_debug) \
 				printk(KERN_DEBUG "%s: " format ,\
 				__FILE__ , ## arg)
-#define dbg_hid_line(format, arg...) if (hid_debug) \
-				printk(format, ## arg)
-#else
-static inline int __attribute__((format(printf, 1, 2)))
-dbg_hid(const char *fmt, ...)
-{
-	return 0;
-}
-#define dbg_hid_line dbg_hid
-#endif /* HID_DEBUG */
-
 #define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \
 		__FILE__ , ## arg)
 #endif /* HID_FF */
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 4759917..ff037f0 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -91,7 +91,6 @@ enum hrtimer_restart {
  * @function:	timer expiry callback function
  * @base:	pointer to the timer base (per cpu and per clock)
  * @state:	state information (See bit values above)
- * @cb_entry:	list head to enqueue an expired timer into the callback list
  * @start_site:	timer statistics field to store the site where the timer
  *		was started
  * @start_comm: timer statistics field to store the name of the process which
@@ -108,7 +107,6 @@ struct hrtimer {
 	enum hrtimer_restart		(*function)(struct hrtimer *);
 	struct hrtimer_clock_base	*base;
 	unsigned long			state;
-	struct list_head		cb_entry;
 #ifdef CONFIG_TIMER_STATS
 	int				start_pid;
 	void				*start_site;
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
index 0dc80ef..2d02dfd 100644
--- a/include/linux/i2c/twl4030.h
+++ b/include/linux/i2c/twl4030.h
@@ -25,6 +25,9 @@
 #ifndef __TWL4030_H_
 #define __TWL4030_H_
 
+#include <linux/types.h>
+#include <linux/input/matrix_keypad.h>
+
 /*
  * Using the twl4030 core we address registers using a pair
  *	{ module id, relative register offset }
@@ -220,19 +223,28 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
 
 /* Power bus message definitions */
 
-#define DEV_GRP_NULL		0x0
-#define DEV_GRP_P1		0x1
-#define DEV_GRP_P2		0x2
-#define DEV_GRP_P3		0x4
+/* The TWL4030/5030 splits its power-management resources (the various
+ * regulators, clock and reset lines) into 3 processor groups - P1, P2 and
+ * P3. These groups can then be configured to transition between sleep, wait-on
+ * and active states by sending messages to the power bus.  See Section 5.4.2
+ * Power Resources of TWL4030 TRM
+ */
 
-#define RES_GRP_RES		0x0
-#define RES_GRP_PP		0x1
-#define RES_GRP_RC		0x2
+/* Processor groups */
+#define DEV_GRP_NULL		0x0
+#define DEV_GRP_P1		0x1	/* P1: all OMAP devices */
+#define DEV_GRP_P2		0x2	/* P2: all Modem devices */
+#define DEV_GRP_P3		0x4	/* P3: all peripheral devices */
+
+/* Resource groups */
+#define RES_GRP_RES		0x0	/* Reserved */
+#define RES_GRP_PP		0x1	/* Power providers */
+#define RES_GRP_RC		0x2	/* Reset and control */
 #define RES_GRP_PP_RC		0x3
-#define RES_GRP_PR		0x4
+#define RES_GRP_PR		0x4	/* Power references */
 #define RES_GRP_PP_PR		0x5
 #define RES_GRP_RC_PR		0x6
-#define RES_GRP_ALL		0x7
+#define RES_GRP_ALL		0x7	/* All resource groups */
 
 #define RES_TYPE2_R0		0x0
 
@@ -243,6 +255,41 @@ int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
 #define RES_STATE_SLEEP		0x8
 #define RES_STATE_OFF		0x0
 
+/* Power resources */
+
+/* Power providers */
+#define RES_VAUX1               1
+#define RES_VAUX2               2
+#define RES_VAUX3               3
+#define RES_VAUX4               4
+#define RES_VMMC1               5
+#define RES_VMMC2               6
+#define RES_VPLL1               7
+#define RES_VPLL2               8
+#define RES_VSIM                9
+#define RES_VDAC                10
+#define RES_VINTANA1            11
+#define RES_VINTANA2            12
+#define RES_VINTDIG             13
+#define RES_VIO                 14
+#define RES_VDD1                15
+#define RES_VDD2                16
+#define RES_VUSB_1V5            17
+#define RES_VUSB_1V8            18
+#define RES_VUSB_3V1            19
+#define RES_VUSBCP              20
+#define RES_REGEN               21
+/* Reset and control */
+#define RES_NRES_PWRON          22
+#define RES_CLKEN               23
+#define RES_SYSEN               24
+#define RES_HFCLKOUT            25
+#define RES_32KCLKOUT           26
+#define RES_RESET               27
+/* Power Reference */
+#define RES_Main_Ref            28
+
+#define TOTAL_RESOURCES		28
 /*
  * Power Bus Message Format ... these can be sent individually by Linux,
  * but are usually part of downloaded scripts that are run when various
@@ -302,13 +349,17 @@ struct twl4030_madc_platform_data {
 	int		irq_line;
 };
 
+/* Boards have uniqe mappings of {col, row} --> keycode.
+ * Column and row are 4 bits, but range only from 0..7.
+ * a PERSISTENT_KEY is "always on" and never reported.
+ */
+#define PERSISTENT_KEY(c, r)	KEY((c), (r), KEY_RESERVED)
+
 struct twl4030_keypad_data {
-	int rows;
-	int cols;
-	int *keymap;
-	int irq;
-	unsigned int keymapsize;
-	unsigned int rep:1;
+	const struct matrix_keymap_data *keymap_data;
+	unsigned rows;
+	unsigned cols;
+	bool rep;
 };
 
 enum twl4030_usb_mode {
@@ -320,6 +371,36 @@ struct twl4030_usb_data {
 	enum twl4030_usb_mode	usb_mode;
 };
 
+struct twl4030_ins {
+	u16 pmb_message;
+	u8 delay;
+};
+
+struct twl4030_script {
+	struct twl4030_ins *script;
+	unsigned size;
+	u8 flags;
+#define TWL4030_WRST_SCRIPT	(1<<0)
+#define TWL4030_WAKEUP12_SCRIPT	(1<<1)
+#define TWL4030_WAKEUP3_SCRIPT	(1<<2)
+#define TWL4030_SLEEP_SCRIPT	(1<<3)
+};
+
+struct twl4030_resconfig {
+	u8 resource;
+	u8 devgroup;	/* Processor group that Power resource belongs to */
+	u8 type;	/* Power resource addressed, 6 / broadcast message */
+	u8 type2;	/* Power resource addressed, 3 / broadcast message */
+};
+
+struct twl4030_power_data {
+	struct twl4030_script **scripts;
+	unsigned num;
+	struct twl4030_resconfig *resource_config;
+};
+
+extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
+
 struct twl4030_platform_data {
 	unsigned				irq_base, irq_end;
 	struct twl4030_bci_platform_data	*bci;
@@ -327,6 +408,7 @@ struct twl4030_platform_data {
 	struct twl4030_madc_platform_data	*madc;
 	struct twl4030_keypad_data		*keypad;
 	struct twl4030_usb_data			*usb;
+	struct twl4030_power_data		*power;
 
 	/* LDO regulators */
 	struct regulator_init_data		*vdac;
@@ -357,7 +439,6 @@ int twl4030_sih_setup(int module);
 #define TWL4030_VAUX3_DEV_GRP		0x1F
 #define TWL4030_VAUX3_DEDICATED		0x22
 
-
 #if defined(CONFIG_TWL4030_BCI_BATTERY) || \
 	defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
 	extern int twl4030charger_usb_en(int enable);
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index b6a8518..c0d8357 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -171,8 +171,6 @@ struct icmp6_filter {
 #ifdef __KERNEL__
 
 #include <linux/netdevice.h>
-#include <linux/skbuff.h>
-
 
 extern void				icmpv6_send(struct sk_buff *skb,
 						    u8 type, u8 code,
diff --git a/include/linux/ide.h b/include/linux/ide.h
index edc93a6..e4135d6 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -258,6 +258,7 @@ enum {
 	IDE_TFLAG_DYN			= (1 << 5),
 	IDE_TFLAG_FS			= (1 << 6),
 	IDE_TFLAG_MULTI_PIO		= (1 << 7),
+	IDE_TFLAG_SET_XFER		= (1 << 8),
 };
 
 enum {
@@ -294,7 +295,7 @@ struct ide_cmd {
 		} out, in;
 	} valid;
 
-	u8			tf_flags;
+	u16			tf_flags;
 	u8			ftf_flags;	/* for TASKFILE ioctl */
 	int			protocol;
 
@@ -918,8 +919,7 @@ __IDE_PROC_DEVSET(_name, _min, _max, NULL, NULL)
 typedef struct {
 	const char	*name;
 	mode_t		mode;
-	read_proc_t	*read_proc;
-	write_proc_t	*write_proc;
+	const struct file_operations *proc_fops;
 } ide_proc_entry_t;
 
 void proc_ide_create(void);
@@ -931,24 +931,8 @@ void ide_proc_unregister_port(ide_hwif_t *);
 void ide_proc_register_driver(ide_drive_t *, struct ide_driver *);
 void ide_proc_unregister_driver(ide_drive_t *, struct ide_driver *);
 
-read_proc_t proc_ide_read_capacity;
-read_proc_t proc_ide_read_geometry;
-
-/*
- * Standard exit stuff:
- */
-#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) \
-{					\
-	len -= off;			\
-	if (len < count) {		\
-		*eof = 1;		\
-		if (len <= 0)		\
-			return 0;	\
-	} else				\
-		len = count;		\
-	*start = page + off;		\
-	return len;			\
-}
+extern const struct file_operations ide_capacity_proc_fops;
+extern const struct file_operations ide_geometry_proc_fops;
 #else
 static inline void proc_ide_create(void) { ; }
 static inline void proc_ide_destroy(void) { ; }
@@ -960,7 +944,6 @@ static inline void ide_proc_register_driver(ide_drive_t *drive,
 					    struct ide_driver *driver) { ; }
 static inline void ide_proc_unregister_driver(ide_drive_t *drive,
 					      struct ide_driver *driver) { ; }
-#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0;
 #endif
 
 enum {
@@ -1081,6 +1064,7 @@ extern void ide_fixstring(u8 *, const int, const int);
 
 int ide_busy_sleep(ide_drive_t *, unsigned long, int);
 
+int __ide_wait_stat(ide_drive_t *, u8, u8, unsigned long, u8 *);
 int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
 
 ide_startstop_t ide_do_park_unpark(ide_drive_t *, struct request *);
@@ -1169,7 +1153,7 @@ int ide_no_data_taskfile(ide_drive_t *, struct ide_cmd *);
 
 int ide_taskfile_ioctl(ide_drive_t *, unsigned long);
 
-int ide_dev_read_id(ide_drive_t *, u8, u16 *);
+int ide_dev_read_id(ide_drive_t *, u8, u16 *, int);
 
 extern int ide_driveid_update(ide_drive_t *);
 extern int ide_config_drive_speed(ide_drive_t *, u8);
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index a9173d5..52e15e0 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -115,7 +115,7 @@
 #define IEEE80211_MAX_SSID_LEN		32
 
 #define IEEE80211_MAX_MESH_ID_LEN	32
-#define IEEE80211_MESH_CONFIG_LEN	19
+#define IEEE80211_MESH_CONFIG_LEN	24
 
 #define IEEE80211_QOS_CTL_LEN		2
 #define IEEE80211_QOS_CTL_TID_MASK	0x000F
@@ -802,6 +802,31 @@ struct ieee80211_ht_cap {
 #define IEEE80211_HT_AMPDU_PARM_FACTOR		0x03
 #define IEEE80211_HT_AMPDU_PARM_DENSITY		0x1C
 
+/*
+ * Maximum length of AMPDU that the STA can receive.
+ * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+enum ieee80211_max_ampdu_length_exp {
+	IEEE80211_HT_MAX_AMPDU_8K = 0,
+	IEEE80211_HT_MAX_AMPDU_16K = 1,
+	IEEE80211_HT_MAX_AMPDU_32K = 2,
+	IEEE80211_HT_MAX_AMPDU_64K = 3
+};
+
+#define IEEE80211_HT_MAX_AMPDU_FACTOR 13
+
+/* Minimum MPDU start spacing */
+enum ieee80211_min_mpdu_spacing {
+	IEEE80211_HT_MPDU_DENSITY_NONE = 0,	/* No restriction */
+	IEEE80211_HT_MPDU_DENSITY_0_25 = 1,	/* 1/4 usec */
+	IEEE80211_HT_MPDU_DENSITY_0_5 = 2,	/* 1/2 usec */
+	IEEE80211_HT_MPDU_DENSITY_1 = 3,	/* 1 usec */
+	IEEE80211_HT_MPDU_DENSITY_2 = 4,	/* 2 usec */
+	IEEE80211_HT_MPDU_DENSITY_4 = 5,	/* 4 usec */
+	IEEE80211_HT_MPDU_DENSITY_8 = 6,	/* 8 usec */
+	IEEE80211_HT_MPDU_DENSITY_16 = 7	/* 16 usec */
+};
+
 /**
  * struct ieee80211_ht_info - HT information
  *
@@ -1196,6 +1221,10 @@ enum ieee80211_sa_query_action {
 #define WLAN_CIPHER_SUITE_WEP104	0x000FAC05
 #define WLAN_CIPHER_SUITE_AES_CMAC	0x000FAC06
 
+/* AKM suite selectors */
+#define WLAN_AKM_SUITE_8021X		0x000FAC01
+#define WLAN_AKM_SUITE_PSK		0x000FAC02
+
 #define WLAN_MAX_KEY_LEN		32
 
 /**
diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h
index a60c821..fd97404 100644
--- a/include/linux/if_addr.h
+++ b/include/linux/if_addr.h
@@ -41,6 +41,7 @@ enum
 
 #define	IFA_F_NODAD		0x02
 #define IFA_F_OPTIMISTIC	0x04
+#define IFA_F_DADFAILED		0x08
 #define	IFA_F_HOMEADDRESS	0x10
 #define IFA_F_DEPRECATED	0x20
 #define IFA_F_TENTATIVE		0x40
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h
index b554300..282eb37 100644
--- a/include/linux/if_arp.h
+++ b/include/linux/if_arp.h
@@ -87,7 +87,6 @@
 #define ARPHRD_IEEE80211_PRISM 802	/* IEEE 802.11 + Prism2 header  */
 #define ARPHRD_IEEE80211_RADIOTAP 803	/* IEEE 802.11 + radiotap header */
 #define ARPHRD_IEEE802154	  804
-#define ARPHRD_IEEE802154_PHY	  805
 
 #define ARPHRD_PHONET	820		/* PhoNet media type		*/
 #define ARPHRD_PHONET_PIPE 821		/* PhoNet pipe header		*/
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 70fdba2..580b600 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -139,10 +139,10 @@ extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
 /*
  *	Display a 6 byte device address (MAC) in a readable format.
  */
-extern char *print_mac(char *buf, const unsigned char *addr);
+extern char *print_mac(char *buf, const unsigned char *addr) __deprecated;
 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
 #define MAC_BUF_SIZE	18
-#define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused
+#define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE]
 
 #endif
 
diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h
index 673f220..80b3a10 100644
--- a/include/linux/if_frad.h
+++ b/include/linux/if_frad.h
@@ -69,11 +69,6 @@ struct dlci_conf {
 
 #define DLCI_VALID_FLAGS	0x000B
 
-/* FRAD driver uses these to indicate what it did with packet */
-#define DLCI_RET_OK		0x00
-#define DLCI_RET_ERR		0x01
-#define DLCI_RET_DROP		0x02
-
 /* defines for the actual Frame Relay hardware */
 #define FRAD_GET_CONF	(SIOCDEVPRIVATE)
 #define FRAD_SET_CONF	(SIOCDEVPRIVATE + 1)
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 915ba57..3f5fd52 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -62,6 +62,7 @@
 #define TUN_F_TSO4	0x02	/* I can handle TSO for IPv4 packets */
 #define TUN_F_TSO6	0x04	/* I can handle TSO for IPv6 packets */
 #define TUN_F_TSO_ECN	0x08	/* I can handle TSO with ECN bits. */
+#define TUN_F_UFO	0x10	/* I can handle UFO packets */
 
 /* Protocol info prepended to the packets (when IFF_NO_PI is not set) */
 #define TUN_PKT_STRIP	0x0001
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 92fbd8c..fe158e0 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -233,6 +233,8 @@ extern void ip_mc_init_dev(struct in_device *);
 extern void ip_mc_destroy_dev(struct in_device *);
 extern void ip_mc_up(struct in_device *);
 extern void ip_mc_down(struct in_device *);
+extern void ip_mc_unmap(struct in_device *);
+extern void ip_mc_remap(struct in_device *);
 extern void ip_mc_dec_group(struct in_device *in_dev, __be32 addr);
 extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
 extern void ip_mc_rejoin_group(struct ip_mc_list *im);
diff --git a/include/linux/init.h b/include/linux/init.h
index 13b633e..400adbb 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -103,8 +103,8 @@
 #define __INIT		.section	".init.text","ax"
 #define __FINIT		.previous
 
-#define __INITDATA	.section	".init.data","aw"
-#define __INITRODATA	.section	".init.rodata","a"
+#define __INITDATA	.section	".init.data","aw",%progbits
+#define __INITRODATA	.section	".init.rodata","a",%progbits
 #define __FINITDATA	.previous
 
 #define __DEVINIT        .section	".devinit.text", "ax"
@@ -305,9 +305,17 @@ void __init parse_early_options(char *cmdline);
 #ifdef CONFIG_MODULES
 #define __init_or_module
 #define __initdata_or_module
+#define __initconst_or_module
+#define __INIT_OR_MODULE	.text
+#define __INITDATA_OR_MODULE	.data
+#define __INITRODATA_OR_MODULE	.section ".rodata","a",%progbits
 #else
 #define __init_or_module __init
 #define __initdata_or_module __initdata
+#define __initconst_or_module __initconst
+#define __INIT_OR_MODULE __INIT
+#define __INITDATA_OR_MODULE __INITDATA
+#define __INITRODATA_OR_MODULE __INITRODATA
 #endif /*CONFIG_MODULES*/
 
 /* Functions marked as __devexit may be discarded at kernel link time, depending
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 9e7f2e8..21a6f5d 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -106,13 +106,13 @@ extern struct group_info init_groups;
 
 extern struct cred init_cred;
 
-#ifdef CONFIG_PERF_COUNTERS
-# define INIT_PERF_COUNTERS(tsk)					\
-	.perf_counter_mutex = 						\
-		 __MUTEX_INITIALIZER(tsk.perf_counter_mutex),		\
-	.perf_counter_list = LIST_HEAD_INIT(tsk.perf_counter_list),
+#ifdef CONFIG_PERF_EVENTS
+# define INIT_PERF_EVENTS(tsk)					\
+	.perf_event_mutex = 						\
+		 __MUTEX_INITIALIZER(tsk.perf_event_mutex),		\
+	.perf_event_list = LIST_HEAD_INIT(tsk.perf_event_list),
 #else
-# define INIT_PERF_COUNTERS(tsk)
+# define INIT_PERF_EVENTS(tsk)
 #endif
 
 /*
@@ -178,7 +178,7 @@ extern struct cred init_cred;
 	},								\
 	.dirties = INIT_PROP_LOCAL_SINGLE(dirties),			\
 	INIT_IDS							\
-	INIT_PERF_COUNTERS(tsk)						\
+	INIT_PERF_EVENTS(tsk)						\
 	INIT_TRACE_IRQFLAGS						\
 	INIT_LOCKDEP							\
 	INIT_FTRACE_GRAPH						\
diff --git a/include/linux/input/eeti_ts.h b/include/linux/input/eeti_ts.h
new file mode 100644
index 0000000..f875b31
--- /dev/null
+++ b/include/linux/input/eeti_ts.h
@@ -0,0 +1,9 @@
+#ifndef LINUX_INPUT_EETI_TS_H
+#define LINUX_INPUT_EETI_TS_H
+
+struct eeti_ts_platform_data {
+	unsigned int irq_active_high;
+};
+
+#endif /* LINUX_INPUT_EETI_TS_H */
+
diff --git a/include/linux/input/matrix_keypad.h b/include/linux/input/matrix_keypad.h
index 15d5903..b3cd42d 100644
--- a/include/linux/input/matrix_keypad.h
+++ b/include/linux/input/matrix_keypad.h
@@ -63,4 +63,36 @@ struct matrix_keypad_platform_data {
 	bool		wakeup;
 };
 
+/**
+ * matrix_keypad_build_keymap - convert platform keymap into matrix keymap
+ * @keymap_data: keymap supplied by the platform code
+ * @row_shift: number of bits to shift row value by to advance to the next
+ * line in the keymap
+ * @keymap: expanded version of keymap that is suitable for use by
+ * matrix keyboad driver
+ * @keybit: pointer to bitmap of keys supported by input device
+ *
+ * This function converts platform keymap (encoded with KEY() macro) into
+ * an array of keycodes that is suitable for using in a standard matrix
+ * keyboard driver that uses row and col as indices.
+ */
+static inline void
+matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
+			   unsigned int row_shift,
+			   unsigned short *keymap, unsigned long *keybit)
+{
+	int i;
+
+	for (i = 0; i < keymap_data->keymap_size; i++) {
+		unsigned int key = keymap_data->keymap[i];
+		unsigned int row = KEY_ROW(key);
+		unsigned int col = KEY_COL(key);
+		unsigned short code = KEY_VAL(key);
+
+		keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code;
+		__set_bit(code, keybit);
+	}
+	__clear_bit(KEY_RESERVED, keybit);
+}
+
 #endif /* _MATRIX_KEYPAD_H */
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 1ac57e5..8e9e151 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -348,6 +348,7 @@ enum
 	NET_TX_SOFTIRQ,
 	NET_RX_SOFTIRQ,
 	BLOCK_SOFTIRQ,
+	BLOCK_IOPOLL_SOFTIRQ,
 	TASKLET_SOFTIRQ,
 	SCHED_SOFTIRQ,
 	HRTIMER_SOFTIRQ,
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h
index 0adb0f9..97eb928 100644
--- a/include/linux/io-mapping.h
+++ b/include/linux/io-mapping.h
@@ -49,23 +49,30 @@ static inline struct io_mapping *
 io_mapping_create_wc(resource_size_t base, unsigned long size)
 {
 	struct io_mapping *iomap;
-
-	if (!is_io_mapping_possible(base, size))
-		return NULL;
+	pgprot_t prot;
 
 	iomap = kmalloc(sizeof(*iomap), GFP_KERNEL);
 	if (!iomap)
-		return NULL;
+		goto out_err;
+
+	if (iomap_create_wc(base, size, &prot))
+		goto out_free;
 
 	iomap->base = base;
 	iomap->size = size;
-	iomap->prot = pgprot_writecombine(__pgprot(__PAGE_KERNEL));
+	iomap->prot = prot;
 	return iomap;
+
+out_free:
+	kfree(iomap);
+out_err:
+	return NULL;
 }
 
 static inline void
 io_mapping_free(struct io_mapping *mapping)
 {
+	iomap_free(mapping->base, mapping->size);
 	kfree(mapping);
 }
 
diff --git a/include/linux/isdn/hdlc.h b/include/linux/isdn/hdlc.h
new file mode 100644
index 0000000..4b3ecc4
--- /dev/null
+++ b/include/linux/isdn/hdlc.h
@@ -0,0 +1,82 @@
+/*
+ * hdlc.h  --  General purpose ISDN HDLC decoder.
+ *
+ * Implementation of a HDLC decoder/encoder in software.
+ * Neccessary because some ISDN devices don't have HDLC
+ * controllers.
+ *
+ * Copyright (C)
+ *	2009	Karsten Keil		<keil@b1-systems.de>
+ *	2002	Wolfgang MÃ¼es		<wolfgang@iksw-muees.de>
+ *	2001	Frode Isaksen		<fisaksen@bewan.com>
+ *	2001	Kai Germaschewski	<kai.germaschewski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __ISDNHDLC_H__
+#define __ISDNHDLC_H__
+
+struct isdnhdlc_vars {
+	int bit_shift;
+	int hdlc_bits1;
+	int data_bits;
+	int ffbit_shift;	/* encoding only */
+	int state;
+	int dstpos;
+
+	u16 crc;
+
+	u8 cbin;
+	u8 shift_reg;
+	u8 ffvalue;
+
+	/* set if transferring data */
+	u32 data_received:1;
+	/* set if D channel (send idle instead of flags) */
+	u32 dchannel:1;
+	/* set if 56K adaptation */
+	u32 do_adapt56:1;
+	/* set if in closing phase (need to send CRC + flag) */
+	u32 do_closing:1;
+	/* set if data is bitreverse */
+	u32 do_bitreverse:1;
+};
+
+/* Feature Flags */
+#define HDLC_56KBIT	0x01
+#define HDLC_DCHANNEL	0x02
+#define HDLC_BITREVERSE	0x04
+
+/*
+  The return value from isdnhdlc_decode is
+  the frame length, 0 if no complete frame was decoded,
+  or a negative error number
+*/
+#define HDLC_FRAMING_ERROR     1
+#define HDLC_CRC_ERROR         2
+#define HDLC_LENGTH_ERROR      3
+
+extern void	isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features);
+
+extern int	isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src,
+			int slen, int *count, u8 *dst, int dsize);
+
+extern void	isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features);
+
+extern int	isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src,
+			u16 slen, int *count, u8 *dst, int dsize);
+
+#endif /* __ISDNHDLC_H__ */
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index c2049a0..a1187a0 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -446,7 +446,7 @@ struct transaction_s
 	/*
 	 * Where in the log does this transaction's commit start? [no locking]
 	 */
-	unsigned long		t_log_start;
+	unsigned int		t_log_start;
 
 	/* Number of buffers on the t_buffers list [j_list_lock] */
 	int			t_nr_buffers;
@@ -701,26 +701,26 @@ struct journal_s
 	 * Journal head: identifies the first unused block in the journal.
 	 * [j_state_lock]
 	 */
-	unsigned long		j_head;
+	unsigned int		j_head;
 
 	/*
 	 * Journal tail: identifies the oldest still-used block in the journal.
 	 * [j_state_lock]
 	 */
-	unsigned long		j_tail;
+	unsigned int		j_tail;
 
 	/*
 	 * Journal free: how many free blocks are there in the journal?
 	 * [j_state_lock]
 	 */
-	unsigned long		j_free;
+	unsigned int		j_free;
 
 	/*
 	 * Journal start and end: the block numbers of the first usable block
 	 * and one beyond the last usable block in the journal. [j_state_lock]
 	 */
-	unsigned long		j_first;
-	unsigned long		j_last;
+	unsigned int		j_first;
+	unsigned int		j_last;
 
 	/*
 	 * Device, blocksize and starting block offset for the location where we
@@ -728,7 +728,7 @@ struct journal_s
 	 */
 	struct block_device	*j_dev;
 	int			j_blocksize;
-	unsigned long		j_blk_offset;
+	unsigned int		j_blk_offset;
 
 	/*
 	 * Device which holds the client fs.  For internal journal this will be
@@ -859,7 +859,7 @@ extern void __journal_clean_data_list(transaction_t *transaction);
 
 /* Log buffer allocation */
 extern struct journal_head * journal_get_descriptor_buffer(journal_t *);
-int journal_next_log_block(journal_t *, unsigned long *);
+int journal_next_log_block(journal_t *, unsigned int *);
 
 /* Commit management */
 extern void journal_commit_transaction(journal_t *);
@@ -874,7 +874,7 @@ extern int
 journal_write_metadata_buffer(transaction_t	  *transaction,
 			      struct journal_head  *jh_in,
 			      struct journal_head **jh_out,
-			      unsigned long	   blocknr);
+			      unsigned int blocknr);
 
 /* Transaction locking */
 extern void		__wait_on_journal (journal_t *);
@@ -942,7 +942,7 @@ extern void	   journal_abort      (journal_t *, int);
 extern int	   journal_errno      (journal_t *);
 extern void	   journal_ack_err    (journal_t *);
 extern int	   journal_clear_err  (journal_t *);
-extern int	   journal_bmap(journal_t *, unsigned long, unsigned long *);
+extern int	   journal_bmap(journal_t *, unsigned int, unsigned int *);
 extern int	   journal_force_commit(journal_t *);
 
 /*
@@ -976,14 +976,14 @@ extern int	   journal_init_revoke_caches(void);
 
 extern void	   journal_destroy_revoke(journal_t *);
 extern int	   journal_revoke (handle_t *,
-				unsigned long, struct buffer_head *);
+				unsigned int, struct buffer_head *);
 extern int	   journal_cancel_revoke(handle_t *, struct journal_head *);
 extern void	   journal_write_revoke_records(journal_t *,
 						transaction_t *, int);
 
 /* Recovery revoke support */
-extern int	journal_set_revoke(journal_t *, unsigned long, tid_t);
-extern int	journal_test_revoke(journal_t *, unsigned long, tid_t);
+extern int	journal_set_revoke(journal_t *, unsigned int, tid_t);
+extern int	journal_test_revoke(journal_t *, unsigned int, tid_t);
 extern void	journal_clear_revoke(journal_t *);
 extern void	journal_switch_revoke_table(journal_t *journal);
 
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index d97eb65..52695d3 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -652,7 +652,7 @@ struct transaction_s
 	 * This transaction is being forced and some process is
 	 * waiting for it to finish.
 	 */
-	int t_synchronous_commit:1;
+	unsigned int t_synchronous_commit:1;
 
 	/*
 	 * For use by the filesystem to store fs-specific data
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index 29f62e1..ad6bdf5 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -38,7 +38,7 @@ extern struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask,
 				 spinlock_t *lock);
 extern void kfifo_free(struct kfifo *fifo);
 extern unsigned int __kfifo_put(struct kfifo *fifo,
-				unsigned char *buffer, unsigned int len);
+				const unsigned char *buffer, unsigned int len);
 extern unsigned int __kfifo_get(struct kfifo *fifo,
 				unsigned char *buffer, unsigned int len);
 
@@ -77,7 +77,7 @@ static inline void kfifo_reset(struct kfifo *fifo)
  * bytes copied.
  */
 static inline unsigned int kfifo_put(struct kfifo *fifo,
-				     unsigned char *buffer, unsigned int len)
+				const unsigned char *buffer, unsigned int len)
 {
 	unsigned long flags;
 	unsigned int ret;
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index bcd9c07..3a46b7b 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -48,13 +48,13 @@
 #define KPROBE_HIT_SSDONE	0x00000008
 
 /* Attach to insert probes on any functions which should be ignored*/
-#define __kprobes	__attribute__((__section__(".kprobes.text"))) notrace
+#define __kprobes	__attribute__((__section__(".kprobes.text")))
 #else /* CONFIG_KPROBES */
 typedef int kprobe_opcode_t;
 struct arch_specific_insn {
 	int dummy;
 };
-#define __kprobes	notrace
+#define __kprobes
 #endif /* CONFIG_KPROBES */
 
 struct kprobe;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 3db5d8d..f8f8900 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -14,7 +14,7 @@
 
 #define KVM_API_VERSION 12
 
-/* for KVM_TRACE_ENABLE */
+/* for KVM_TRACE_ENABLE, deprecated */
 struct kvm_user_trace_setup {
 	__u32 buf_size; /* sub_buffer size of each per-cpu */
 	__u32 buf_nr; /* the number of sub_buffers of each per-cpu */
@@ -70,6 +70,14 @@ struct kvm_irqchip {
 	} chip;
 };
 
+/* for KVM_CREATE_PIT2 */
+struct kvm_pit_config {
+	__u32 flags;
+	__u32 pad[15];
+};
+
+#define KVM_PIT_SPEAKER_DUMMY     1
+
 #define KVM_EXIT_UNKNOWN          0
 #define KVM_EXIT_EXCEPTION        1
 #define KVM_EXIT_IO               2
@@ -87,6 +95,10 @@ struct kvm_irqchip {
 #define KVM_EXIT_S390_RESET       14
 #define KVM_EXIT_DCR              15
 #define KVM_EXIT_NMI              16
+#define KVM_EXIT_INTERNAL_ERROR   17
+
+/* For KVM_EXIT_INTERNAL_ERROR */
+#define KVM_INTERNAL_ERROR_EMULATION 1
 
 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
 struct kvm_run {
@@ -173,6 +185,9 @@ struct kvm_run {
 			__u32 data;
 			__u8  is_write;
 		} dcr;
+		struct {
+			__u32 suberror;
+		} internal;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -292,6 +307,28 @@ struct kvm_guest_debug {
 	struct kvm_guest_debug_arch arch;
 };
 
+enum {
+	kvm_ioeventfd_flag_nr_datamatch,
+	kvm_ioeventfd_flag_nr_pio,
+	kvm_ioeventfd_flag_nr_deassign,
+	kvm_ioeventfd_flag_nr_max,
+};
+
+#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
+#define KVM_IOEVENTFD_FLAG_PIO       (1 << kvm_ioeventfd_flag_nr_pio)
+#define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+
+#define KVM_IOEVENTFD_VALID_FLAG_MASK  ((1 << kvm_ioeventfd_flag_nr_max) - 1)
+
+struct kvm_ioeventfd {
+	__u64 datamatch;
+	__u64 addr;        /* legal pio/mmio address */
+	__u32 len;         /* 1, 2, 4, or 8 bytes    */
+	__s32 fd;
+	__u32 flags;
+	__u8  pad[36];
+};
+
 #define KVM_TRC_SHIFT           16
 /*
  * kvm trace categories
@@ -310,35 +347,6 @@ struct kvm_guest_debug {
 #define KVM_TRC_CYCLE_SIZE      8
 #define KVM_TRC_EXTRA_MAX       7
 
-/* This structure represents a single trace buffer record. */
-struct kvm_trace_rec {
-	/* variable rec_val
-	 * is split into:
-	 * bits 0 - 27  -> event id
-	 * bits 28 -30  -> number of extra data args of size u32
-	 * bits 31      -> binary indicator for if tsc is in record
-	 */
-	__u32 rec_val;
-	__u32 pid;
-	__u32 vcpu_id;
-	union {
-		struct {
-			__u64 timestamp;
-			__u32 extra_u32[KVM_TRC_EXTRA_MAX];
-		} __attribute__((packed)) timestamp;
-		struct {
-			__u32 extra_u32[KVM_TRC_EXTRA_MAX];
-		} notimestamp;
-	} u;
-};
-
-#define TRACE_REC_EVENT_ID(val) \
-		(0x0fffffff & (val))
-#define TRACE_REC_NUM_DATA_ARGS(val) \
-		(0x70000000 & ((val) << 28))
-#define TRACE_REC_TCS(val) \
-		(0x80000000 & ((val) << 31))
-
 #define KVMIO 0xAE
 
 /*
@@ -415,6 +423,19 @@ struct kvm_trace_rec {
 #define KVM_CAP_ASSIGN_DEV_IRQ 29
 /* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */
 #define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30
+#ifdef __KVM_HAVE_MCE
+#define KVM_CAP_MCE 31
+#endif
+#define KVM_CAP_IRQFD 32
+#ifdef __KVM_HAVE_PIT
+#define KVM_CAP_PIT2 33
+#endif
+#define KVM_CAP_SET_BOOT_CPU_ID 34
+#ifdef __KVM_HAVE_PIT_STATE2
+#define KVM_CAP_PIT_STATE2 35
+#endif
+#define KVM_CAP_IOEVENTFD 36
+#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -454,15 +475,32 @@ struct kvm_irq_routing {
 
 #endif
 
+#ifdef KVM_CAP_MCE
+/* x86 MCE */
+struct kvm_x86_mce {
+	__u64 status;
+	__u64 addr;
+	__u64 misc;
+	__u64 mcg_status;
+	__u8 bank;
+	__u8 pad1[7];
+	__u64 pad2[3];
+};
+#endif
+
+#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
+
+struct kvm_irqfd {
+	__u32 fd;
+	__u32 gsi;
+	__u32 flags;
+	__u8  pad[20];
+};
+
 /*
  * ioctls for VM fds
  */
 #define KVM_SET_MEMORY_REGION     _IOW(KVMIO, 0x40, struct kvm_memory_region)
-#define KVM_SET_NR_MMU_PAGES      _IO(KVMIO, 0x44)
-#define KVM_GET_NR_MMU_PAGES      _IO(KVMIO, 0x45)
-#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46,\
-					struct kvm_userspace_memory_region)
-#define KVM_SET_TSS_ADDR          _IO(KVMIO, 0x47)
 /*
  * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns
  * a vcpu fd.
@@ -470,6 +508,12 @@ struct kvm_irq_routing {
 #define KVM_CREATE_VCPU           _IO(KVMIO,  0x41)
 #define KVM_GET_DIRTY_LOG         _IOW(KVMIO, 0x42, struct kvm_dirty_log)
 #define KVM_SET_MEMORY_ALIAS      _IOW(KVMIO, 0x43, struct kvm_memory_alias)
+#define KVM_SET_NR_MMU_PAGES      _IO(KVMIO, 0x44)
+#define KVM_GET_NR_MMU_PAGES      _IO(KVMIO, 0x45)
+#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46,\
+					struct kvm_userspace_memory_region)
+#define KVM_SET_TSS_ADDR          _IO(KVMIO, 0x47)
+#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64)
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP	  _IO(KVMIO,  0x60)
 #define KVM_IRQ_LINE		  _IOW(KVMIO, 0x61, struct kvm_irq_level)
@@ -498,6 +542,10 @@ struct kvm_irq_routing {
 #define KVM_ASSIGN_SET_MSIX_ENTRY \
 			_IOW(KVMIO, 0x74, struct kvm_assigned_msix_entry)
 #define KVM_DEASSIGN_DEV_IRQ       _IOW(KVMIO, 0x75, struct kvm_assigned_irq)
+#define KVM_IRQFD                  _IOW(KVMIO, 0x76, struct kvm_irqfd)
+#define KVM_CREATE_PIT2		   _IOW(KVMIO, 0x77, struct kvm_pit_config)
+#define KVM_SET_BOOT_CPU_ID        _IO(KVMIO, 0x78)
+#define KVM_IOEVENTFD             _IOW(KVMIO, 0x79, struct kvm_ioeventfd)
 
 /*
  * ioctls for vcpu fds
@@ -541,6 +589,10 @@ struct kvm_irq_routing {
 #define KVM_NMI                   _IO(KVMIO,  0x9a)
 /* Available with KVM_CAP_SET_GUEST_DEBUG */
 #define KVM_SET_GUEST_DEBUG       _IOW(KVMIO,  0x9b, struct kvm_guest_debug)
+/* MCE for x86 */
+#define KVM_X86_SETUP_MCE         _IOW(KVMIO,  0x9c, __u64)
+#define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO,  0x9d, __u64)
+#define KVM_X86_SET_MCE           _IOW(KVMIO,  0x9e, struct kvm_x86_mce)
 
 /*
  * Deprecated interfaces
@@ -563,6 +615,9 @@ struct kvm_debug_guest {
 #define KVM_IA64_VCPU_GET_STACK   _IOR(KVMIO,  0x9a, void *)
 #define KVM_IA64_VCPU_SET_STACK   _IOW(KVMIO,  0x9b, void *)
 
+#define KVM_GET_PIT2   _IOR(KVMIO,   0x9f, struct kvm_pit_state2)
+#define KVM_SET_PIT2   _IOW(KVMIO,   0xa0, struct kvm_pit_state2)
+
 #define KVM_TRC_INJ_VIRQ         (KVM_TRC_HANDLER + 0x02)
 #define KVM_TRC_REDELIVER_EVT    (KVM_TRC_HANDLER + 0x03)
 #define KVM_TRC_PEND_INTR        (KVM_TRC_HANDLER + 0x04)
@@ -633,7 +688,7 @@ struct kvm_assigned_msix_nr {
 	__u16 padding;
 };
 
-#define KVM_MAX_MSIX_PER_DEV		512
+#define KVM_MAX_MSIX_PER_DEV		256
 struct kvm_assigned_msix_entry {
 	__u32 assigned_dev_id;
 	__u32 gsi;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 3060bdc..b7bbb5d 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -15,7 +15,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/preempt.h>
-#include <linux/marker.h>
 #include <linux/msi.h>
 #include <asm/signal.h>
 
@@ -42,6 +41,7 @@
 
 #define KVM_USERSPACE_IRQ_SOURCE_ID	0
 
+struct kvm;
 struct kvm_vcpu;
 extern struct kmem_cache *kvm_vcpu_cache;
 
@@ -59,10 +59,18 @@ struct kvm_io_bus {
 
 void kvm_io_bus_init(struct kvm_io_bus *bus);
 void kvm_io_bus_destroy(struct kvm_io_bus *bus);
-struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus,
-					  gpa_t addr, int len, int is_write);
-void kvm_io_bus_register_dev(struct kvm_io_bus *bus,
-			     struct kvm_io_device *dev);
+int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr, int len,
+		     const void *val);
+int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len,
+		    void *val);
+int __kvm_io_bus_register_dev(struct kvm_io_bus *bus,
+			       struct kvm_io_device *dev);
+int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus,
+			    struct kvm_io_device *dev);
+void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
+				 struct kvm_io_device *dev);
+void kvm_io_bus_unregister_dev(struct kvm *kvm, struct kvm_io_bus *bus,
+			       struct kvm_io_device *dev);
 
 struct kvm_vcpu {
 	struct kvm *kvm;
@@ -103,7 +111,7 @@ struct kvm_memory_slot {
 	struct {
 		unsigned long rmap_pde;
 		int write_count;
-	} *lpage_info;
+	} *lpage_info[KVM_NR_PAGE_SIZES - 1];
 	unsigned long userspace_addr;
 	int user_alloc;
 };
@@ -124,7 +132,6 @@ struct kvm_kernel_irq_routing_entry {
 };
 
 struct kvm {
-	struct mutex lock; /* protects the vcpus array and APIC accesses */
 	spinlock_t mmu_lock;
 	spinlock_t requests_lock;
 	struct rw_semaphore slots_lock;
@@ -132,10 +139,23 @@ struct kvm {
 	int nmemslots;
 	struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS +
 					KVM_PRIVATE_MEM_SLOTS];
+#ifdef CONFIG_KVM_APIC_ARCHITECTURE
+	u32 bsp_vcpu_id;
+	struct kvm_vcpu *bsp_vcpu;
+#endif
 	struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
+	atomic_t online_vcpus;
 	struct list_head vm_list;
+	struct mutex lock;
 	struct kvm_io_bus mmio_bus;
 	struct kvm_io_bus pio_bus;
+#ifdef CONFIG_HAVE_KVM_EVENTFD
+	struct {
+		spinlock_t        lock;
+		struct list_head  items;
+	} irqfds;
+	struct list_head ioeventfds;
+#endif
 	struct kvm_vm_stat stat;
 	struct kvm_arch arch;
 	atomic_t users_count;
@@ -144,6 +164,7 @@ struct kvm {
 	struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
 #endif
 
+	struct mutex irq_lock;
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 	struct list_head irq_routing; /* of kvm_kernel_irq_routing_entry */
 	struct hlist_head mask_notifier_list;
@@ -167,6 +188,17 @@ struct kvm {
 #define kvm_printf(kvm, fmt ...) printk(KERN_DEBUG fmt)
 #define vcpu_printf(vcpu, fmt...) kvm_printf(vcpu->kvm, fmt)
 
+static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
+{
+	smp_rmb();
+	return kvm->vcpus[i];
+}
+
+#define kvm_for_each_vcpu(idx, vcpup, kvm) \
+	for (idx = 0, vcpup = kvm_get_vcpu(kvm, idx); \
+	     idx < atomic_read(&kvm->online_vcpus) && vcpup; \
+	     vcpup = kvm_get_vcpu(kvm, ++idx))
+
 int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id);
 void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
 
@@ -201,6 +233,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
 				struct kvm_userspace_memory_region *mem,
 				struct kvm_memory_slot old,
 				int user_alloc);
+void kvm_disable_largepages(void);
 void kvm_arch_flush_shadow(struct kvm *kvm);
 gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn);
 struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
@@ -243,8 +276,6 @@ long kvm_arch_dev_ioctl(struct file *filp,
 			unsigned int ioctl, unsigned long arg);
 long kvm_arch_vcpu_ioctl(struct file *filp,
 			 unsigned int ioctl, unsigned long arg);
-void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
-void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu);
 
 int kvm_dev_ioctl_check_extension(long ext);
 
@@ -300,7 +331,6 @@ int kvm_arch_hardware_setup(void);
 void kvm_arch_hardware_unsetup(void);
 void kvm_arch_check_processor_compat(void *rtn);
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu);
-int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
 
 void kvm_free_physmem(struct kvm *kvm);
 
@@ -309,8 +339,6 @@ void kvm_arch_destroy_vm(struct kvm *kvm);
 void kvm_free_all_assigned_devices(struct kvm *kvm);
 void kvm_arch_sync_events(struct kvm *kvm);
 
-int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
-int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
 int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu);
 void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
 
@@ -366,7 +394,8 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level);
 void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin);
 void kvm_register_irq_ack_notifier(struct kvm *kvm,
 				   struct kvm_irq_ack_notifier *kian);
-void kvm_unregister_irq_ack_notifier(struct kvm_irq_ack_notifier *kian);
+void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
+				   struct kvm_irq_ack_notifier *kian);
 int kvm_request_irq_source_id(struct kvm *kvm);
 void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
 
@@ -459,37 +488,6 @@ struct kvm_stats_debugfs_item {
 extern struct kvm_stats_debugfs_item debugfs_entries[];
 extern struct dentry *kvm_debugfs_dir;
 
-#define KVMTRACE_5D(evt, vcpu, d1, d2, d3, d4, d5, name) \
-	trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-						vcpu, 5, d1, d2, d3, d4, d5)
-#define KVMTRACE_4D(evt, vcpu, d1, d2, d3, d4, name) \
-	trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-						vcpu, 4, d1, d2, d3, d4, 0)
-#define KVMTRACE_3D(evt, vcpu, d1, d2, d3, name) \
-	trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-						vcpu, 3, d1, d2, d3, 0, 0)
-#define KVMTRACE_2D(evt, vcpu, d1, d2, name) \
-	trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-						vcpu, 2, d1, d2, 0, 0, 0)
-#define KVMTRACE_1D(evt, vcpu, d1, name) \
-	trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-						vcpu, 1, d1, 0, 0, 0, 0)
-#define KVMTRACE_0D(evt, vcpu, name) \
-	trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
-						vcpu, 0, 0, 0, 0, 0, 0)
-
-#ifdef CONFIG_KVM_TRACE
-int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg);
-void kvm_trace_cleanup(void);
-#else
-static inline
-int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg)
-{
-	return -EINVAL;
-}
-#define kvm_trace_cleanup() ((void)0)
-#endif
-
 #ifdef KVM_ARCH_WANT_MMU_NOTIFIER
 static inline int mmu_notifier_retry(struct kvm_vcpu *vcpu, unsigned long mmu_seq)
 {
@@ -525,4 +523,33 @@ static inline void kvm_free_irq_routing(struct kvm *kvm) {}
 
 #endif
 
+#ifdef CONFIG_HAVE_KVM_EVENTFD
+
+void kvm_eventfd_init(struct kvm *kvm);
+int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags);
+void kvm_irqfd_release(struct kvm *kvm);
+int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args);
+
+#else
+
+static inline void kvm_eventfd_init(struct kvm *kvm) {}
+static inline int kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags)
+{
+	return -EINVAL;
+}
+
+static inline void kvm_irqfd_release(struct kvm *kvm) {}
+static inline int kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
+{
+	return -ENOSYS;
+}
+
+#endif /* CONFIG_HAVE_KVM_EVENTFD */
+
+#ifdef CONFIG_KVM_APIC_ARCHITECTURE
+static inline bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu)
+{
+	return vcpu->kvm->bsp_vcpu_id == vcpu->vcpu_id;
+}
+#endif
 #endif
diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h
index 3ddce03..d731092 100644
--- a/include/linux/kvm_para.h
+++ b/include/linux/kvm_para.h
@@ -13,6 +13,7 @@
 #define KVM_ENOSYS		1000
 #define KVM_EFAULT		EFAULT
 #define KVM_E2BIG		E2BIG
+#define KVM_EPERM		EPERM
 
 #define KVM_HC_VAPIC_POLL_IRQ		1
 #define KVM_HC_MMU_OP			2
diff --git a/include/linux/libps2.h b/include/linux/libps2.h
index b94534b..fcf5fbe 100644
--- a/include/linux/libps2.h
+++ b/include/linux/libps2.h
@@ -44,6 +44,7 @@ struct ps2dev {
 void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
 int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
 void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
+int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
 int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
 int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
 int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data);
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h
index 7f9831d..4af8414 100644
--- a/include/linux/mISDNhw.h
+++ b/include/linux/mISDNhw.h
@@ -168,6 +168,7 @@ struct bchannel {
 extern int	mISDN_initdchannel(struct dchannel *, int, void *);
 extern int	mISDN_initbchannel(struct bchannel *, int);
 extern int	mISDN_freedchannel(struct dchannel *);
+extern void	mISDN_clear_bchannel(struct bchannel *);
 extern int	mISDN_freebchannel(struct bchannel *);
 extern void	queue_ch_frame(struct mISDNchannel *, u_int,
 			int, struct sk_buff *);
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index 45100b3..536ca12 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -37,7 +37,7 @@
  */
 #define	MISDN_MAJOR_VERSION	1
 #define	MISDN_MINOR_VERSION	1
-#define MISDN_RELEASE		20
+#define MISDN_RELEASE		21
 
 /* primitives for information exchange
  * generell format
@@ -153,6 +153,18 @@
 #define HFC_VOL_CHANGE_RX	0x2602
 #define HFC_SPL_LOOP_ON		0x2603
 #define HFC_SPL_LOOP_OFF	0x2604
+/* for T30 FAX and analog modem */
+#define HW_MOD_FRM		0x4000
+#define HW_MOD_FRH		0x4001
+#define HW_MOD_FTM		0x4002
+#define HW_MOD_FTH		0x4003
+#define HW_MOD_FTS		0x4004
+#define HW_MOD_CONNECT		0x4010
+#define HW_MOD_OK		0x4011
+#define HW_MOD_NOCARR		0x4012
+#define HW_MOD_FCERROR		0x4013
+#define HW_MOD_READY		0x4014
+#define HW_MOD_LASTDATA		0x4015
 
 /* DSP_TONE_PATT_ON parameter */
 #define TONE_OFF			0x0000
@@ -224,6 +236,8 @@
 #define ISDN_P_B_L2DTMF		0x24
 #define ISDN_P_B_L2DSP		0x25
 #define ISDN_P_B_L2DSPHDLC	0x26
+#define ISDN_P_B_T30_FAX	0x27
+#define ISDN_P_B_MODEM_ASYNC	0x28
 
 #define OPTION_L2_PMX		1
 #define OPTION_L2_PTP		2
diff --git a/include/linux/marker.h b/include/linux/marker.h
deleted file mode 100644
index b85e74c..0000000
--- a/include/linux/marker.h
+++ /dev/null
@@ -1,221 +0,0 @@
-#ifndef _LINUX_MARKER_H
-#define _LINUX_MARKER_H
-
-/*
- * Code markup for dynamic and static tracing.
- *
- * See Documentation/marker.txt.
- *
- * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
- *
- * This file is released under the GPLv2.
- * See the file COPYING for more details.
- */
-
-#include <stdarg.h>
-#include <linux/types.h>
-
-struct module;
-struct marker;
-
-/**
- * marker_probe_func - Type of a marker probe function
- * @probe_private: probe private data
- * @call_private: call site private data
- * @fmt: format string
- * @args: variable argument list pointer. Use a pointer to overcome C's
- *        inability to pass this around as a pointer in a portable manner in
- *        the callee otherwise.
- *
- * Type of marker probe functions. They receive the mdata and need to parse the
- * format string to recover the variable argument list.
- */
-typedef void marker_probe_func(void *probe_private, void *call_private,
-		const char *fmt, va_list *args);
-
-struct marker_probe_closure {
-	marker_probe_func *func;	/* Callback */
-	void *probe_private;		/* Private probe data */
-};
-
-struct marker {
-	const char *name;	/* Marker name */
-	const char *format;	/* Marker format string, describing the
-				 * variable argument list.
-				 */
-	char state;		/* Marker state. */
-	char ptype;		/* probe type : 0 : single, 1 : multi */
-				/* Probe wrapper */
-	void (*call)(const struct marker *mdata, void *call_private, ...);
-	struct marker_probe_closure single;
-	struct marker_probe_closure *multi;
-	const char *tp_name;	/* Optional tracepoint name */
-	void *tp_cb;		/* Optional tracepoint callback */
-} __attribute__((aligned(8)));
-
-#ifdef CONFIG_MARKERS
-
-#define _DEFINE_MARKER(name, tp_name_str, tp_cb, format)		\
-		static const char __mstrtab_##name[]			\
-		__attribute__((section("__markers_strings")))		\
-		= #name "\0" format;					\
-		static struct marker __mark_##name			\
-		__attribute__((section("__markers"), aligned(8))) =	\
-		{ __mstrtab_##name, &__mstrtab_##name[sizeof(#name)],	\
-		  0, 0, marker_probe_cb, { __mark_empty_function, NULL},\
-		  NULL, tp_name_str, tp_cb }
-
-#define DEFINE_MARKER(name, format)					\
-		_DEFINE_MARKER(name, NULL, NULL, format)
-
-#define DEFINE_MARKER_TP(name, tp_name, tp_cb, format)			\
-		_DEFINE_MARKER(name, #tp_name, tp_cb, format)
-
-/*
- * Note : the empty asm volatile with read constraint is used here instead of a
- * "used" attribute to fix a gcc 4.1.x bug.
- * Make sure the alignment of the structure in the __markers section will
- * not add unwanted padding between the beginning of the section and the
- * structure. Force alignment to the same alignment as the section start.
- *
- * The "generic" argument controls which marker enabling mechanism must be used.
- * If generic is true, a variable read is used.
- * If generic is false, immediate values are used.
- */
-#define __trace_mark(generic, name, call_private, format, args...)	\
-	do {								\
-		DEFINE_MARKER(name, format);				\
-		__mark_check_format(format, ## args);			\
-		if (unlikely(__mark_##name.state)) {			\
-			(*__mark_##name.call)				\
-				(&__mark_##name, call_private, ## args);\
-		}							\
-	} while (0)
-
-#define __trace_mark_tp(name, call_private, tp_name, tp_cb, format, args...) \
-	do {								\
-		void __check_tp_type(void)				\
-		{							\
-			register_trace_##tp_name(tp_cb);		\
-		}							\
-		DEFINE_MARKER_TP(name, tp_name, tp_cb, format);		\
-		__mark_check_format(format, ## args);			\
-		(*__mark_##name.call)(&__mark_##name, call_private,	\
-					## args);			\
-	} while (0)
-
-extern void marker_update_probe_range(struct marker *begin,
-	struct marker *end);
-
-#define GET_MARKER(name)	(__mark_##name)
-
-#else /* !CONFIG_MARKERS */
-#define DEFINE_MARKER(name, tp_name, tp_cb, format)
-#define __trace_mark(generic, name, call_private, format, args...) \
-		__mark_check_format(format, ## args)
-#define __trace_mark_tp(name, call_private, tp_name, tp_cb, format, args...) \
-	do {								\
-		void __check_tp_type(void)				\
-		{							\
-			register_trace_##tp_name(tp_cb);		\
-		}							\
-		__mark_check_format(format, ## args);			\
-	} while (0)
-static inline void marker_update_probe_range(struct marker *begin,
-	struct marker *end)
-{ }
-#define GET_MARKER(name)
-#endif /* CONFIG_MARKERS */
-
-/**
- * trace_mark - Marker using code patching
- * @name: marker name, not quoted.
- * @format: format string
- * @args...: variable argument list
- *
- * Places a marker using optimized code patching technique (imv_read())
- * to be enabled when immediate values are present.
- */
-#define trace_mark(name, format, args...) \
-	__trace_mark(0, name, NULL, format, ## args)
-
-/**
- * _trace_mark - Marker using variable read
- * @name: marker name, not quoted.
- * @format: format string
- * @args...: variable argument list
- *
- * Places a marker using a standard memory read (_imv_read()) to be
- * enabled. Should be used for markers in code paths where instruction
- * modification based enabling is not welcome. (__init and __exit functions,
- * lockdep, some traps, printk).
- */
-#define _trace_mark(name, format, args...) \
-	__trace_mark(1, name, NULL, format, ## args)
-
-/**
- * trace_mark_tp - Marker in a tracepoint callback
- * @name: marker name, not quoted.
- * @tp_name: tracepoint name, not quoted.
- * @tp_cb: tracepoint callback. Should have an associated global symbol so it
- *         is not optimized away by the compiler (should not be static).
- * @format: format string
- * @args...: variable argument list
- *
- * Places a marker in a tracepoint callback.
- */
-#define trace_mark_tp(name, tp_name, tp_cb, format, args...)	\
-	__trace_mark_tp(name, NULL, tp_name, tp_cb, format, ## args)
-
-/**
- * MARK_NOARGS - Format string for a marker with no argument.
- */
-#define MARK_NOARGS " "
-
-/* To be used for string format validity checking with gcc */
-static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...)
-{
-}
-
-#define __mark_check_format(format, args...)				\
-	do {								\
-		if (0)							\
-			___mark_check_format(format, ## args);		\
-	} while (0)
-
-extern marker_probe_func __mark_empty_function;
-
-extern void marker_probe_cb(const struct marker *mdata,
-	void *call_private, ...);
-
-/*
- * Connect a probe to a marker.
- * private data pointer must be a valid allocated memory address, or NULL.
- */
-extern int marker_probe_register(const char *name, const char *format,
-				marker_probe_func *probe, void *probe_private);
-
-/*
- * Returns the private data given to marker_probe_register.
- */
-extern int marker_probe_unregister(const char *name,
-	marker_probe_func *probe, void *probe_private);
-/*
- * Unregister a marker by providing the registered private data.
- */
-extern int marker_probe_unregister_private_data(marker_probe_func *probe,
-	void *probe_private);
-
-extern void *marker_get_private_data(const char *name, marker_probe_func *probe,
-	int num);
-
-/*
- * marker_synchronize_unregister must be called between the last marker probe
- * unregistration and the first one of
- * - the end of module exit function
- * - the free of any resource used by the probes
- * to ensure the code and data are valid for any possibly running probes.
- */
-#define marker_synchronize_unregister() synchronize_sched()
-
-#endif
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index cfdf1df..c779b49 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -304,7 +304,7 @@ static inline __u16 mdio_phy_id_devad(int phy_id)
  */
 struct mdio_if_info {
 	int prtad;
-	u32 __bitwise mmds;
+	u32 mmds;
 	unsigned mode_support;
 
 	struct net_device *dev;
diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h
index 7a3f316..e9aa4c9 100644
--- a/include/linux/mfd/ab3100.h
+++ b/include/linux/mfd/ab3100.h
@@ -6,6 +6,8 @@
  */
 
 #include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/regulator/machine.h>
 
 #ifndef MFD_AB3100_H
 #define MFD_AB3100_H
@@ -56,6 +58,14 @@
 #define AB3100_STR_BATT_REMOVAL				(0x40)
 #define AB3100_STR_VBUS					(0x80)
 
+/*
+ * AB3100 contains 8 regulators, one external regulator controller
+ * and a buck converter, further the LDO E and buck converter can
+ * have separate settings if they are in sleep mode, this is
+ * modeled as a separate regulator.
+ */
+#define AB3100_NUM_REGULATORS				10
+
 /**
  * struct ab3100
  * @access_mutex: lock out concurrent accesses to the AB3100 registers
@@ -86,11 +96,30 @@ struct ab3100 {
 	bool startup_events_read;
 };
 
-int ab3100_set_register(struct ab3100 *ab3100, u8 reg, u8 regval);
-int ab3100_get_register(struct ab3100 *ab3100, u8 reg, u8 *regval);
-int ab3100_get_register_page(struct ab3100 *ab3100,
+/**
+ * struct ab3100_platform_data
+ * Data supplied to initialize board connections to the AB3100
+ * @reg_constraints: regulator constraints for target board
+ *     the order of these constraints are: LDO A, C, D, E,
+ *     F, G, H, K, EXT and BUCK.
+ * @reg_initvals: initial values for the regulator registers
+ *     plus two sleep settings for LDO E and the BUCK converter.
+ *     exactly AB3100_NUM_REGULATORS+2 values must be sent in.
+ *     Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK,
+ *     BUCK sleep, LDO D. (LDO D need to be initialized last.)
+ * @external_voltage: voltage level of the external regulator.
+ */
+struct ab3100_platform_data {
+	struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS];
+	u8 reg_initvals[AB3100_NUM_REGULATORS+2];
+	int external_voltage;
+};
+
+int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval);
+int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval);
+int ab3100_get_register_page_interruptible(struct ab3100 *ab3100,
 			     u8 first_reg, u8 *regvals, u8 numregs);
-int ab3100_mask_and_set_register(struct ab3100 *ab3100,
+int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100,
 				 u8 reg, u8 andmask, u8 ormask);
 u8 ab3100_get_chip_type(struct ab3100 *ab3100);
 int ab3100_event_register(struct ab3100 *ab3100,
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index 49ef857..11d740b 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -23,6 +23,7 @@
  */
 struct mfd_cell {
 	const char		*name;
+	int			id;
 
 	int			(*enable)(struct platform_device *dev);
 	int			(*disable)(struct platform_device *dev);
diff --git a/include/linux/mfd/ezx-pcap.h b/include/linux/mfd/ezx-pcap.h
index c12c3c0..e5124ce 100644
--- a/include/linux/mfd/ezx-pcap.h
+++ b/include/linux/mfd/ezx-pcap.h
@@ -25,9 +25,12 @@ struct pcap_chip;
 
 int ezx_pcap_write(struct pcap_chip *, u8, u32);
 int ezx_pcap_read(struct pcap_chip *, u8, u32 *);
+int ezx_pcap_set_bits(struct pcap_chip *, u8, u32, u32);
 int pcap_to_irq(struct pcap_chip *, int);
+int irq_to_pcap(struct pcap_chip *, int);
 int pcap_adc_async(struct pcap_chip *, u8, u32, u8[], void *, void *);
 int pcap_adc_sync(struct pcap_chip *, u8, u32, u8[], u16[]);
+void pcap_set_ts_bits(struct pcap_chip *, u32);
 
 #define PCAP_SECOND_PORT	1
 #define PCAP_CS_AH		2
@@ -224,7 +227,6 @@ int pcap_adc_sync(struct pcap_chip *, u8, u32, u8[], u16[]);
 #define PCAP_LED1		1
 #define PCAP_BL0		2
 #define PCAP_BL1		3
-#define PCAP_VIB		4
 #define PCAP_LED_3MA		0
 #define PCAP_LED_4MA		1
 #define PCAP_LED_5MA		2
@@ -243,9 +245,6 @@ int pcap_adc_sync(struct pcap_chip *, u8, u32, u8[], u16[]);
 #define PCAP_LED0_C_SHIFT	15
 #define PCAP_LED1_C_SHIFT	17
 #define PCAP_BL1_SHIFT		20
-#define PCAP_VIB_MASK		0x3
-#define PCAP_VIB_SHIFT		20
-#define PCAP_VIB_EN		(1 << 19)
 
 /* RTC */
 #define PCAP_RTC_DAY_MASK	0x3fff
diff --git a/include/linux/mfd/mc13783-private.h b/include/linux/mfd/mc13783-private.h
new file mode 100644
index 0000000..47e698c
--- /dev/null
+++ b/include/linux/mfd/mc13783-private.h
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __LINUX_MFD_MC13783_PRIV_H
+#define __LINUX_MFD_MC13783_PRIV_H
+
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+
+struct mc13783_irq {
+	void (*handler)(int, void *);
+	void *data;
+};
+
+#define MC13783_NUM_IRQ		2
+#define MC13783_IRQ_TS		0
+#define MC13783_IRQ_REGULATOR	1
+
+#define MC13783_ADC_MODE_TS		1
+#define MC13783_ADC_MODE_SINGLE_CHAN	2
+#define MC13783_ADC_MODE_MULT_CHAN	3
+
+struct mc13783 {
+	int revision;
+	struct device *dev;
+	struct spi_device *spi_device;
+
+	int (*read_dev)(void *data, char reg, int count, u32 *dst);
+	int (*write_dev)(void *data, char reg, int count, const u32 *src);
+
+	struct mutex io_lock;
+	void *io_data;
+	int irq;
+	unsigned int flags;
+
+	struct mc13783_irq irq_handler[MC13783_NUM_IRQ];
+	struct work_struct work;
+	struct completion adc_done;
+	unsigned int ts_active;
+	struct mutex adc_conv_lock;
+
+	struct mc13783_regulator_init_data *regulators;
+	int num_regulators;
+};
+
+int mc13783_reg_read(struct mc13783 *, int reg_num, u32 *);
+int mc13783_reg_write(struct mc13783 *, int, u32);
+int mc13783_set_bits(struct mc13783 *, int, u32, u32);
+int mc13783_free_irq(struct mc13783 *mc13783, int irq);
+int mc13783_register_irq(struct mc13783 *mc13783, int irq,
+		void (*handler) (int, void *), void *data);
+
+#define MC13783_REG_INTERRUPT_STATUS_0		 0
+#define MC13783_REG_INTERRUPT_MASK_0		 1
+#define MC13783_REG_INTERRUPT_SENSE_0		 2
+#define MC13783_REG_INTERRUPT_STATUS_1		 3
+#define MC13783_REG_INTERRUPT_MASK_1		 4
+#define MC13783_REG_INTERRUPT_SENSE_1		 5
+#define MC13783_REG_POWER_UP_MODE_SENSE		 6
+#define MC13783_REG_REVISION			 7
+#define MC13783_REG_SEMAPHORE			 8
+#define MC13783_REG_ARBITRATION_PERIPHERAL_AUDIO 9
+#define MC13783_REG_ARBITRATION_SWITCHERS	10
+#define MC13783_REG_ARBITRATION_REGULATORS_0	11
+#define MC13783_REG_ARBITRATION_REGULATORS_1	12
+#define MC13783_REG_POWER_CONTROL_0		13
+#define MC13783_REG_POWER_CONTROL_1		14
+#define MC13783_REG_POWER_CONTROL_2		15
+#define MC13783_REG_REGEN_ASSIGNMENT		16
+#define MC13783_REG_CONTROL_SPARE		17
+#define MC13783_REG_MEMORY_A			18
+#define MC13783_REG_MEMORY_B			19
+#define MC13783_REG_RTC_TIME			20
+#define MC13783_REG_RTC_ALARM			21
+#define MC13783_REG_RTC_DAY			22
+#define MC13783_REG_RTC_DAY_ALARM		23
+#define MC13783_REG_SWITCHERS_0			24
+#define MC13783_REG_SWITCHERS_1			25
+#define MC13783_REG_SWITCHERS_2			26
+#define MC13783_REG_SWITCHERS_3			27
+#define MC13783_REG_SWITCHERS_4			28
+#define MC13783_REG_SWITCHERS_5			29
+#define MC13783_REG_REGULATOR_SETTING_0		30
+#define MC13783_REG_REGULATOR_SETTING_1		31
+#define MC13783_REG_REGULATOR_MODE_0		32
+#define MC13783_REG_REGULATOR_MODE_1		33
+#define MC13783_REG_POWER_MISCELLANEOUS		34
+#define MC13783_REG_POWER_SPARE			35
+#define MC13783_REG_AUDIO_RX_0			36
+#define MC13783_REG_AUDIO_RX_1			37
+#define MC13783_REG_AUDIO_TX			38
+#define MC13783_REG_AUDIO_SSI_NETWORK		39
+#define MC13783_REG_AUDIO_CODEC			40
+#define MC13783_REG_AUDIO_STEREO_DAC		41
+#define MC13783_REG_AUDIO_SPARE			42
+#define MC13783_REG_ADC_0			43
+#define MC13783_REG_ADC_1			44
+#define MC13783_REG_ADC_2			45
+#define MC13783_REG_ADC_3			46
+#define MC13783_REG_ADC_4			47
+#define MC13783_REG_CHARGER			48
+#define MC13783_REG_USB				49
+#define MC13783_REG_CHARGE_USB_SPARE		50
+#define MC13783_REG_LED_CONTROL_0		51
+#define MC13783_REG_LED_CONTROL_1		52
+#define MC13783_REG_LED_CONTROL_2		53
+#define MC13783_REG_LED_CONTROL_3		54
+#define MC13783_REG_LED_CONTROL_4		55
+#define MC13783_REG_LED_CONTROL_5		56
+#define MC13783_REG_SPARE			57
+#define MC13783_REG_TRIM_0			58
+#define MC13783_REG_TRIM_1			59
+#define MC13783_REG_TEST_0			60
+#define MC13783_REG_TEST_1			61
+#define MC13783_REG_TEST_2			62
+#define MC13783_REG_TEST_3			63
+#define MC13783_REG_NB				64
+
+
+/*
+ * Interrupt Status
+ */
+#define MC13783_INT_STAT_ADCDONEI	(1 << 0)
+#define MC13783_INT_STAT_ADCBISDONEI	(1 << 1)
+#define MC13783_INT_STAT_TSI		(1 << 2)
+#define MC13783_INT_STAT_WHIGHI		(1 << 3)
+#define MC13783_INT_STAT_WLOWI		(1 << 4)
+#define MC13783_INT_STAT_CHGDETI	(1 << 6)
+#define MC13783_INT_STAT_CHGOVI		(1 << 7)
+#define MC13783_INT_STAT_CHGREVI	(1 << 8)
+#define MC13783_INT_STAT_CHGSHORTI	(1 << 9)
+#define MC13783_INT_STAT_CCCVI		(1 << 10)
+#define MC13783_INT_STAT_CHGCURRI	(1 << 11)
+#define MC13783_INT_STAT_BPONI		(1 << 12)
+#define MC13783_INT_STAT_LOBATLI	(1 << 13)
+#define MC13783_INT_STAT_LOBATHI	(1 << 14)
+#define MC13783_INT_STAT_UDPI		(1 << 15)
+#define MC13783_INT_STAT_USBI		(1 << 16)
+#define MC13783_INT_STAT_IDI		(1 << 19)
+#define MC13783_INT_STAT_Unused		(1 << 20)
+#define MC13783_INT_STAT_SE1I		(1 << 21)
+#define MC13783_INT_STAT_CKDETI		(1 << 22)
+#define MC13783_INT_STAT_UDMI		(1 << 23)
+
+/*
+ * Interrupt Mask
+ */
+#define MC13783_INT_MASK_ADCDONEM	(1 << 0)
+#define MC13783_INT_MASK_ADCBISDONEM	(1 << 1)
+#define MC13783_INT_MASK_TSM		(1 << 2)
+#define MC13783_INT_MASK_WHIGHM		(1 << 3)
+#define MC13783_INT_MASK_WLOWM		(1 << 4)
+#define MC13783_INT_MASK_CHGDETM	(1 << 6)
+#define MC13783_INT_MASK_CHGOVM		(1 << 7)
+#define MC13783_INT_MASK_CHGREVM	(1 << 8)
+#define MC13783_INT_MASK_CHGSHORTM	(1 << 9)
+#define MC13783_INT_MASK_CCCVM		(1 << 10)
+#define MC13783_INT_MASK_CHGCURRM	(1 << 11)
+#define MC13783_INT_MASK_BPONM		(1 << 12)
+#define MC13783_INT_MASK_LOBATLM	(1 << 13)
+#define MC13783_INT_MASK_LOBATHM	(1 << 14)
+#define MC13783_INT_MASK_UDPM		(1 << 15)
+#define MC13783_INT_MASK_USBM		(1 << 16)
+#define MC13783_INT_MASK_IDM		(1 << 19)
+#define MC13783_INT_MASK_SE1M		(1 << 21)
+#define MC13783_INT_MASK_CKDETM		(1 << 22)
+
+/*
+ * Reg Regulator Mode 0
+ */
+#define MC13783_REGCTRL_VAUDIO_EN	(1 << 0)
+#define MC13783_REGCTRL_VAUDIO_STBY	(1 << 1)
+#define MC13783_REGCTRL_VAUDIO_MODE	(1 << 2)
+#define MC13783_REGCTRL_VIOHI_EN	(1 << 3)
+#define MC13783_REGCTRL_VIOHI_STBY	(1 << 4)
+#define MC13783_REGCTRL_VIOHI_MODE	(1 << 5)
+#define MC13783_REGCTRL_VIOLO_EN	(1 << 6)
+#define MC13783_REGCTRL_VIOLO_STBY 	(1 << 7)
+#define MC13783_REGCTRL_VIOLO_MODE	(1 << 8)
+#define MC13783_REGCTRL_VDIG_EN		(1 << 9)
+#define MC13783_REGCTRL_VDIG_STBY	(1 << 10)
+#define MC13783_REGCTRL_VDIG_MODE	(1 << 11)
+#define MC13783_REGCTRL_VGEN_EN		(1 << 12)
+#define MC13783_REGCTRL_VGEN_STBY	(1 << 13)
+#define MC13783_REGCTRL_VGEN_MODE	(1 << 14)
+#define MC13783_REGCTRL_VRFDIG_EN	(1 << 15)
+#define MC13783_REGCTRL_VRFDIG_STBY	(1 << 16)
+#define MC13783_REGCTRL_VRFDIG_MODE	(1 << 17)
+#define MC13783_REGCTRL_VRFREF_EN	(1 << 18)
+#define MC13783_REGCTRL_VRFREF_STBY	(1 << 19)
+#define MC13783_REGCTRL_VRFREF_MODE	(1 << 20)
+#define MC13783_REGCTRL_VRFCP_EN	(1 << 21)
+#define MC13783_REGCTRL_VRFCP_STBY	(1 << 22)
+#define MC13783_REGCTRL_VRFCP_MODE	(1 << 23)
+
+/*
+ * Reg Regulator Mode 1
+ */
+#define MC13783_REGCTRL_VSIM_EN		(1 << 0)
+#define MC13783_REGCTRL_VSIM_STBY	(1 << 1)
+#define MC13783_REGCTRL_VSIM_MODE	(1 << 2)
+#define MC13783_REGCTRL_VESIM_EN	(1 << 3)
+#define MC13783_REGCTRL_VESIM_STBY	(1 << 4)
+#define MC13783_REGCTRL_VESIM_MODE	(1 << 5)
+#define MC13783_REGCTRL_VCAM_EN		(1 << 6)
+#define MC13783_REGCTRL_VCAM_STBY	(1 << 7)
+#define MC13783_REGCTRL_VCAM_MODE	(1 << 8)
+#define	MC13783_REGCTRL_VRFBG_EN	(1 << 9)
+#define MC13783_REGCTRL_VRFBG_STBY	(1 << 10)
+#define MC13783_REGCTRL_VVIB_EN		(1 << 11)
+#define MC13783_REGCTRL_VRF1_EN		(1 << 12)
+#define MC13783_REGCTRL_VRF1_STBY	(1 << 13)
+#define MC13783_REGCTRL_VRF1_MODE	(1 << 14)
+#define MC13783_REGCTRL_VRF2_EN		(1 << 15)
+#define MC13783_REGCTRL_VRF2_STBY	(1 << 16)
+#define MC13783_REGCTRL_VRF2_MODE	(1 << 17)
+#define MC13783_REGCTRL_VMMC1_EN	(1 << 18)
+#define MC13783_REGCTRL_VMMC1_STBY	(1 << 19)
+#define MC13783_REGCTRL_VMMC1_MODE	(1 << 20)
+#define MC13783_REGCTRL_VMMC2_EN	(1 << 21)
+#define MC13783_REGCTRL_VMMC2_STBY	(1 << 22)
+#define MC13783_REGCTRL_VMMC2_MODE	(1 << 23)
+
+/*
+ * Reg Regulator Misc.
+ */
+#define MC13783_REGCTRL_GPO1_EN		(1 << 6)
+#define MC13783_REGCTRL_GPO2_EN		(1 << 8)
+#define MC13783_REGCTRL_GPO3_EN		(1 << 10)
+#define MC13783_REGCTRL_GPO4_EN		(1 << 12)
+#define MC13783_REGCTRL_VIBPINCTRL	(1 << 14)
+
+/*
+ * Reg Switcher 4
+ */
+#define MC13783_SWCTRL_SW1A_MODE	(1 << 0)
+#define MC13783_SWCTRL_SW1A_STBY_MODE	(1 << 2)
+#define MC13783_SWCTRL_SW1A_DVS_SPEED	(1 << 6)
+#define MC13783_SWCTRL_SW1A_PANIC_MODE	(1 << 8)
+#define MC13783_SWCTRL_SW1A_SOFTSTART	(1 << 9)
+#define MC13783_SWCTRL_SW1B_MODE	(1 << 10)
+#define MC13783_SWCTRL_SW1B_STBY_MODE	(1 << 12)
+#define MC13783_SWCTRL_SW1B_DVS_SPEED	(1 << 14)
+#define MC13783_SWCTRL_SW1B_PANIC_MODE	(1 << 16)
+#define MC13783_SWCTRL_SW1B_SOFTSTART	(1 << 17)
+#define MC13783_SWCTRL_PLL_EN		(1 << 18)
+#define MC13783_SWCTRL_PLL_FACTOR	(1 << 19)
+
+/*
+ * Reg Switcher 5
+ */
+#define MC13783_SWCTRL_SW2A_MODE	(1 << 0)
+#define MC13783_SWCTRL_SW2A_STBY_MODE	(1 << 2)
+#define MC13783_SWCTRL_SW2A_DVS_SPEED	(1 << 6)
+#define MC13783_SWCTRL_SW2A_PANIC_MODE	(1 << 8)
+#define MC13783_SWCTRL_SW2A_SOFTSTART	(1 << 9)
+#define MC13783_SWCTRL_SW2B_MODE	(1 << 10)
+#define MC13783_SWCTRL_SW2B_STBY_MODE	(1 << 12)
+#define MC13783_SWCTRL_SW2B_DVS_SPEED	(1 << 14)
+#define MC13783_SWCTRL_SW2B_PANIC_MODE	(1 << 16)
+#define MC13783_SWCTRL_SW2B_SOFTSTART	(1 << 17)
+#define MC13783_SWSET_SW3		(1 << 18)
+#define MC13783_SWCTRL_SW3_EN		(1 << 20)
+#define MC13783_SWCTRL_SW3_STBY		(1 << 21)
+#define MC13783_SWCTRL_SW3_MODE		(1 << 22)
+
+/*
+ * ADC/Touch
+ */
+#define MC13783_ADC0_LICELLCON		(1 << 0)
+#define MC13783_ADC0_CHRGICON		(1 << 1)
+#define MC13783_ADC0_BATICON		(1 << 2)
+#define MC13783_ADC0_RTHEN 		(1 << 3)
+#define MC13783_ADC0_DTHEN		(1 << 4)
+#define MC13783_ADC0_UIDEN		(1 << 5)
+#define MC13783_ADC0_ADOUTEN 		(1 << 6)
+#define MC13783_ADC0_ADOUTPER		(1 << 7)
+#define MC13783_ADC0_ADREFEN		(1 << 10)
+#define MC13783_ADC0_ADREFMODE		(1 << 11)
+#define MC13783_ADC0_TSMOD0		(1 << 12)
+#define MC13783_ADC0_TSMOD1		(1 << 13)
+#define MC13783_ADC0_TSMOD2		(1 << 14)
+#define MC13783_ADC0_CHRGRAWDIV		(1 << 15)
+#define MC13783_ADC0_ADINC1		(1 << 16)
+#define MC13783_ADC0_ADINC2		(1 << 17)
+#define MC13783_ADC0_WCOMP		(1 << 18)
+#define MC13783_ADC0_ADCBIS0		(1 << 23)
+
+#define MC13783_ADC1_ADEN		(1 << 0)
+#define MC13783_ADC1_RAND		(1 << 1)
+#define MC13783_ADC1_ADSEL		(1 << 3)
+#define MC13783_ADC1_TRIGMASK		(1 << 4)
+#define MC13783_ADC1_ADA10		(1 << 5)
+#define MC13783_ADC1_ADA11		(1 << 6)
+#define MC13783_ADC1_ADA12		(1 << 7)
+#define MC13783_ADC1_ADA20		(1 << 8)
+#define MC13783_ADC1_ADA21		(1 << 9)
+#define MC13783_ADC1_ADA22		(1 << 10)
+#define MC13783_ADC1_ATO0		(1 << 11)
+#define MC13783_ADC1_ATO1		(1 << 12)
+#define MC13783_ADC1_ATO2		(1 << 13)
+#define MC13783_ADC1_ATO3		(1 << 14)
+#define MC13783_ADC1_ATO4		(1 << 15)
+#define MC13783_ADC1_ATO5		(1 << 16)
+#define MC13783_ADC1_ATO6		(1 << 17)
+#define MC13783_ADC1_ATO7		(1 << 18)
+#define MC13783_ADC1_ATOX		(1 << 19)
+#define MC13783_ADC1_ASC		(1 << 20)
+#define MC13783_ADC1_ADTRIGIGN		(1 << 21)
+#define MC13783_ADC1_ADONESHOT		(1 << 22)
+#define MC13783_ADC1_ADCBIS1		(1 << 23)
+
+#define MC13783_ADC1_CHAN0_SHIFT	5
+#define MC13783_ADC1_CHAN1_SHIFT	8
+
+#define MC13783_ADC2_ADD10		(1 << 2)
+#define MC13783_ADC2_ADD11		(1 << 3)
+#define MC13783_ADC2_ADD12		(1 << 4)
+#define MC13783_ADC2_ADD13		(1 << 5)
+#define MC13783_ADC2_ADD14		(1 << 6)
+#define MC13783_ADC2_ADD15		(1 << 7)
+#define MC13783_ADC2_ADD16		(1 << 8)
+#define MC13783_ADC2_ADD17		(1 << 9)
+#define MC13783_ADC2_ADD18		(1 << 10)
+#define MC13783_ADC2_ADD19		(1 << 11)
+#define MC13783_ADC2_ADD20		(1 << 14)
+#define MC13783_ADC2_ADD21		(1 << 15)
+#define MC13783_ADC2_ADD22		(1 << 16)
+#define MC13783_ADC2_ADD23		(1 << 17)
+#define MC13783_ADC2_ADD24		(1 << 18)
+#define MC13783_ADC2_ADD25		(1 << 19)
+#define MC13783_ADC2_ADD26		(1 << 20)
+#define MC13783_ADC2_ADD27		(1 << 21)
+#define MC13783_ADC2_ADD28		(1 << 22)
+#define MC13783_ADC2_ADD29		(1 << 23)
+
+#define MC13783_ADC3_WHIGH0		(1 << 0)
+#define MC13783_ADC3_WHIGH1		(1 << 1)
+#define MC13783_ADC3_WHIGH2		(1 << 2)
+#define MC13783_ADC3_WHIGH3		(1 << 3)
+#define MC13783_ADC3_WHIGH4		(1 << 4)
+#define MC13783_ADC3_WHIGH5		(1 << 5)
+#define MC13783_ADC3_ICID0		(1 << 6)
+#define MC13783_ADC3_ICID1		(1 << 7)
+#define MC13783_ADC3_ICID2		(1 << 8)
+#define MC13783_ADC3_WLOW0		(1 << 9)
+#define MC13783_ADC3_WLOW1		(1 << 10)
+#define MC13783_ADC3_WLOW2		(1 << 11)
+#define MC13783_ADC3_WLOW3		(1 << 12)
+#define MC13783_ADC3_WLOW4		(1 << 13)
+#define MC13783_ADC3_WLOW5		(1 << 14)
+#define MC13783_ADC3_ADCBIS2		(1 << 23)
+
+#define MC13783_ADC4_ADDBIS10		(1 << 2)
+#define MC13783_ADC4_ADDBIS11		(1 << 3)
+#define MC13783_ADC4_ADDBIS12		(1 << 4)
+#define MC13783_ADC4_ADDBIS13		(1 << 5)
+#define MC13783_ADC4_ADDBIS14		(1 << 6)
+#define MC13783_ADC4_ADDBIS15		(1 << 7)
+#define MC13783_ADC4_ADDBIS16		(1 << 8)
+#define MC13783_ADC4_ADDBIS17		(1 << 9)
+#define MC13783_ADC4_ADDBIS18		(1 << 10)
+#define MC13783_ADC4_ADDBIS19		(1 << 11)
+#define MC13783_ADC4_ADDBIS20		(1 << 14)
+#define MC13783_ADC4_ADDBIS21		(1 << 15)
+#define MC13783_ADC4_ADDBIS22		(1 << 16)
+#define MC13783_ADC4_ADDBIS23		(1 << 17)
+#define MC13783_ADC4_ADDBIS24		(1 << 18)
+#define MC13783_ADC4_ADDBIS25		(1 << 19)
+#define MC13783_ADC4_ADDBIS26		(1 << 20)
+#define MC13783_ADC4_ADDBIS27		(1 << 21)
+#define MC13783_ADC4_ADDBIS28		(1 << 22)
+#define MC13783_ADC4_ADDBIS29		(1 << 23)
+
+#endif /* __LINUX_MFD_MC13783_PRIV_H */
+
diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
new file mode 100644
index 0000000..b3a2a72
--- /dev/null
+++ b/include/linux/mfd/mc13783.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU 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 __INCLUDE_LINUX_MFD_MC13783_H
+#define __INCLUDE_LINUX_MFD_MC13783_H
+
+struct mc13783;
+struct regulator_init_data;
+
+struct mc13783_regulator_init_data {
+	int id;
+	struct regulator_init_data *init_data;
+};
+
+struct mc13783_platform_data {
+	struct mc13783_regulator_init_data *regulators;
+	int num_regulators;
+	unsigned int flags;
+};
+
+/* mc13783_platform_data flags */
+#define MC13783_USE_TOUCHSCREEN (1 << 0)
+#define MC13783_USE_CODEC	(1 << 1)
+#define MC13783_USE_ADC		(1 << 2)
+#define MC13783_USE_RTC		(1 << 3)
+#define MC13783_USE_REGULATOR	(1 << 4)
+
+int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
+		unsigned int channel, unsigned int *sample);
+
+void mc13783_adc_set_ts_status(struct mc13783 *mc13783, unsigned int status);
+
+#define	MC13783_SW_SW1A		0
+#define	MC13783_SW_SW1B		1
+#define	MC13783_SW_SW2A		2
+#define	MC13783_SW_SW2B		3
+#define	MC13783_SW_SW3		4
+#define	MC13783_SW_PLL		5
+#define	MC13783_REGU_VAUDIO	6
+#define	MC13783_REGU_VIOHI	7
+#define	MC13783_REGU_VIOLO	8
+#define	MC13783_REGU_VDIG	9
+#define	MC13783_REGU_VGEN	10
+#define	MC13783_REGU_VRFDIG	11
+#define	MC13783_REGU_VRFREF	12
+#define	MC13783_REGU_VRFCP	13
+#define	MC13783_REGU_VSIM	14
+#define	MC13783_REGU_VESIM	15
+#define	MC13783_REGU_VCAM	16
+#define	MC13783_REGU_VRFBG	17
+#define	MC13783_REGU_VVIB	18
+#define	MC13783_REGU_VRF1	19
+#define	MC13783_REGU_VRF2	20
+#define	MC13783_REGU_VMMC1	21
+#define	MC13783_REGU_VMMC2	22
+#define	MC13783_REGU_GPO1	23
+#define	MC13783_REGU_GPO2	24
+#define	MC13783_REGU_GPO3	25
+#define	MC13783_REGU_GPO4	26
+#define	MC13783_REGU_V1		27
+#define	MC13783_REGU_V2		28
+#define	MC13783_REGU_V3		29
+#define	MC13783_REGU_V4		30
+
+#endif /* __INCLUDE_LINUX_MFD_MC13783_H */
+
diff --git a/include/linux/mfd/pcf50633/adc.h b/include/linux/mfd/pcf50633/adc.h
index 56669b4..b35e628 100644
--- a/include/linux/mfd/pcf50633/adc.h
+++ b/include/linux/mfd/pcf50633/adc.h
@@ -25,7 +25,8 @@
 #define PCF50633_REG_ADCS3		0x57
 
 #define PCF50633_ADCC1_ADCSTART		0x01
-#define PCF50633_ADCC1_RES_10BIT	0x02
+#define PCF50633_ADCC1_RES_8BIT		0x02
+#define PCF50633_ADCC1_RES_10BIT	0x00
 #define PCF50633_ADCC1_AVERAGE_NO	0x00
 #define PCF50633_ADCC1_AVERAGE_4	0x04
 #define PCF50633_ADCC1_AVERAGE_8	0x08
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
index c8f51c3..9aba7b7 100644
--- a/include/linux/mfd/pcf50633/core.h
+++ b/include/linux/mfd/pcf50633/core.h
@@ -136,6 +136,7 @@ struct pcf50633 {
 	int irq;
 	struct pcf50633_irq irq_handler[PCF50633_NUM_IRQ];
 	struct work_struct irq_work;
+	struct workqueue_struct *work_queue;
 	struct mutex lock;
 
 	u8 mask_regs[5];
diff --git a/include/linux/mfd/wm831x/auxadc.h b/include/linux/mfd/wm831x/auxadc.h
new file mode 100644
index 0000000..b132067
--- /dev/null
+++ b/include/linux/mfd/wm831x/auxadc.h
@@ -0,0 +1,216 @@
+/*
+ * include/linux/mfd/wm831x/auxadc.h -- Auxiliary ADC interface for WM831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_AUXADC_H__
+#define __MFD_WM831X_AUXADC_H__
+
+/*
+ * R16429 (0x402D) - AuxADC Data
+ */
+#define WM831X_AUX_DATA_SRC_MASK                0xF000  /* AUX_DATA_SRC - [15:12] */
+#define WM831X_AUX_DATA_SRC_SHIFT                   12  /* AUX_DATA_SRC - [15:12] */
+#define WM831X_AUX_DATA_SRC_WIDTH                    4  /* AUX_DATA_SRC - [15:12] */
+#define WM831X_AUX_DATA_MASK                    0x0FFF  /* AUX_DATA - [11:0] */
+#define WM831X_AUX_DATA_SHIFT                        0  /* AUX_DATA - [11:0] */
+#define WM831X_AUX_DATA_WIDTH                       12  /* AUX_DATA - [11:0] */
+
+/*
+ * R16430 (0x402E) - AuxADC Control
+ */
+#define WM831X_AUX_ENA                          0x8000  /* AUX_ENA */
+#define WM831X_AUX_ENA_MASK                     0x8000  /* AUX_ENA */
+#define WM831X_AUX_ENA_SHIFT                        15  /* AUX_ENA */
+#define WM831X_AUX_ENA_WIDTH                         1  /* AUX_ENA */
+#define WM831X_AUX_CVT_ENA                      0x4000  /* AUX_CVT_ENA */
+#define WM831X_AUX_CVT_ENA_MASK                 0x4000  /* AUX_CVT_ENA */
+#define WM831X_AUX_CVT_ENA_SHIFT                    14  /* AUX_CVT_ENA */
+#define WM831X_AUX_CVT_ENA_WIDTH                     1  /* AUX_CVT_ENA */
+#define WM831X_AUX_SLPENA                       0x1000  /* AUX_SLPENA */
+#define WM831X_AUX_SLPENA_MASK                  0x1000  /* AUX_SLPENA */
+#define WM831X_AUX_SLPENA_SHIFT                     12  /* AUX_SLPENA */
+#define WM831X_AUX_SLPENA_WIDTH                      1  /* AUX_SLPENA */
+#define WM831X_AUX_FRC_ENA                      0x0800  /* AUX_FRC_ENA */
+#define WM831X_AUX_FRC_ENA_MASK                 0x0800  /* AUX_FRC_ENA */
+#define WM831X_AUX_FRC_ENA_SHIFT                    11  /* AUX_FRC_ENA */
+#define WM831X_AUX_FRC_ENA_WIDTH                     1  /* AUX_FRC_ENA */
+#define WM831X_AUX_RATE_MASK                    0x003F  /* AUX_RATE - [5:0] */
+#define WM831X_AUX_RATE_SHIFT                        0  /* AUX_RATE - [5:0] */
+#define WM831X_AUX_RATE_WIDTH                        6  /* AUX_RATE - [5:0] */
+
+/*
+ * R16431 (0x402F) - AuxADC Source
+ */
+#define WM831X_AUX_CAL_SEL                      0x8000  /* AUX_CAL_SEL */
+#define WM831X_AUX_CAL_SEL_MASK                 0x8000  /* AUX_CAL_SEL */
+#define WM831X_AUX_CAL_SEL_SHIFT                    15  /* AUX_CAL_SEL */
+#define WM831X_AUX_CAL_SEL_WIDTH                     1  /* AUX_CAL_SEL */
+#define WM831X_AUX_BKUP_BATT_SEL                0x0400  /* AUX_BKUP_BATT_SEL */
+#define WM831X_AUX_BKUP_BATT_SEL_MASK           0x0400  /* AUX_BKUP_BATT_SEL */
+#define WM831X_AUX_BKUP_BATT_SEL_SHIFT              10  /* AUX_BKUP_BATT_SEL */
+#define WM831X_AUX_BKUP_BATT_SEL_WIDTH               1  /* AUX_BKUP_BATT_SEL */
+#define WM831X_AUX_WALL_SEL                     0x0200  /* AUX_WALL_SEL */
+#define WM831X_AUX_WALL_SEL_MASK                0x0200  /* AUX_WALL_SEL */
+#define WM831X_AUX_WALL_SEL_SHIFT                    9  /* AUX_WALL_SEL */
+#define WM831X_AUX_WALL_SEL_WIDTH                    1  /* AUX_WALL_SEL */
+#define WM831X_AUX_BATT_SEL                     0x0100  /* AUX_BATT_SEL */
+#define WM831X_AUX_BATT_SEL_MASK                0x0100  /* AUX_BATT_SEL */
+#define WM831X_AUX_BATT_SEL_SHIFT                    8  /* AUX_BATT_SEL */
+#define WM831X_AUX_BATT_SEL_WIDTH                    1  /* AUX_BATT_SEL */
+#define WM831X_AUX_USB_SEL                      0x0080  /* AUX_USB_SEL */
+#define WM831X_AUX_USB_SEL_MASK                 0x0080  /* AUX_USB_SEL */
+#define WM831X_AUX_USB_SEL_SHIFT                     7  /* AUX_USB_SEL */
+#define WM831X_AUX_USB_SEL_WIDTH                     1  /* AUX_USB_SEL */
+#define WM831X_AUX_SYSVDD_SEL                   0x0040  /* AUX_SYSVDD_SEL */
+#define WM831X_AUX_SYSVDD_SEL_MASK              0x0040  /* AUX_SYSVDD_SEL */
+#define WM831X_AUX_SYSVDD_SEL_SHIFT                  6  /* AUX_SYSVDD_SEL */
+#define WM831X_AUX_SYSVDD_SEL_WIDTH                  1  /* AUX_SYSVDD_SEL */
+#define WM831X_AUX_BATT_TEMP_SEL                0x0020  /* AUX_BATT_TEMP_SEL */
+#define WM831X_AUX_BATT_TEMP_SEL_MASK           0x0020  /* AUX_BATT_TEMP_SEL */
+#define WM831X_AUX_BATT_TEMP_SEL_SHIFT               5  /* AUX_BATT_TEMP_SEL */
+#define WM831X_AUX_BATT_TEMP_SEL_WIDTH               1  /* AUX_BATT_TEMP_SEL */
+#define WM831X_AUX_CHIP_TEMP_SEL                0x0010  /* AUX_CHIP_TEMP_SEL */
+#define WM831X_AUX_CHIP_TEMP_SEL_MASK           0x0010  /* AUX_CHIP_TEMP_SEL */
+#define WM831X_AUX_CHIP_TEMP_SEL_SHIFT               4  /* AUX_CHIP_TEMP_SEL */
+#define WM831X_AUX_CHIP_TEMP_SEL_WIDTH               1  /* AUX_CHIP_TEMP_SEL */
+#define WM831X_AUX_AUX4_SEL                     0x0008  /* AUX_AUX4_SEL */
+#define WM831X_AUX_AUX4_SEL_MASK                0x0008  /* AUX_AUX4_SEL */
+#define WM831X_AUX_AUX4_SEL_SHIFT                    3  /* AUX_AUX4_SEL */
+#define WM831X_AUX_AUX4_SEL_WIDTH                    1  /* AUX_AUX4_SEL */
+#define WM831X_AUX_AUX3_SEL                     0x0004  /* AUX_AUX3_SEL */
+#define WM831X_AUX_AUX3_SEL_MASK                0x0004  /* AUX_AUX3_SEL */
+#define WM831X_AUX_AUX3_SEL_SHIFT                    2  /* AUX_AUX3_SEL */
+#define WM831X_AUX_AUX3_SEL_WIDTH                    1  /* AUX_AUX3_SEL */
+#define WM831X_AUX_AUX2_SEL                     0x0002  /* AUX_AUX2_SEL */
+#define WM831X_AUX_AUX2_SEL_MASK                0x0002  /* AUX_AUX2_SEL */
+#define WM831X_AUX_AUX2_SEL_SHIFT                    1  /* AUX_AUX2_SEL */
+#define WM831X_AUX_AUX2_SEL_WIDTH                    1  /* AUX_AUX2_SEL */
+#define WM831X_AUX_AUX1_SEL                     0x0001  /* AUX_AUX1_SEL */
+#define WM831X_AUX_AUX1_SEL_MASK                0x0001  /* AUX_AUX1_SEL */
+#define WM831X_AUX_AUX1_SEL_SHIFT                    0  /* AUX_AUX1_SEL */
+#define WM831X_AUX_AUX1_SEL_WIDTH                    1  /* AUX_AUX1_SEL */
+
+/*
+ * R16432 (0x4030) - Comparator Control
+ */
+#define WM831X_DCOMP4_STS                       0x0800  /* DCOMP4_STS */
+#define WM831X_DCOMP4_STS_MASK                  0x0800  /* DCOMP4_STS */
+#define WM831X_DCOMP4_STS_SHIFT                     11  /* DCOMP4_STS */
+#define WM831X_DCOMP4_STS_WIDTH                      1  /* DCOMP4_STS */
+#define WM831X_DCOMP3_STS                       0x0400  /* DCOMP3_STS */
+#define WM831X_DCOMP3_STS_MASK                  0x0400  /* DCOMP3_STS */
+#define WM831X_DCOMP3_STS_SHIFT                     10  /* DCOMP3_STS */
+#define WM831X_DCOMP3_STS_WIDTH                      1  /* DCOMP3_STS */
+#define WM831X_DCOMP2_STS                       0x0200  /* DCOMP2_STS */
+#define WM831X_DCOMP2_STS_MASK                  0x0200  /* DCOMP2_STS */
+#define WM831X_DCOMP2_STS_SHIFT                      9  /* DCOMP2_STS */
+#define WM831X_DCOMP2_STS_WIDTH                      1  /* DCOMP2_STS */
+#define WM831X_DCOMP1_STS                       0x0100  /* DCOMP1_STS */
+#define WM831X_DCOMP1_STS_MASK                  0x0100  /* DCOMP1_STS */
+#define WM831X_DCOMP1_STS_SHIFT                      8  /* DCOMP1_STS */
+#define WM831X_DCOMP1_STS_WIDTH                      1  /* DCOMP1_STS */
+#define WM831X_DCMP4_ENA                        0x0008  /* DCMP4_ENA */
+#define WM831X_DCMP4_ENA_MASK                   0x0008  /* DCMP4_ENA */
+#define WM831X_DCMP4_ENA_SHIFT                       3  /* DCMP4_ENA */
+#define WM831X_DCMP4_ENA_WIDTH                       1  /* DCMP4_ENA */
+#define WM831X_DCMP3_ENA                        0x0004  /* DCMP3_ENA */
+#define WM831X_DCMP3_ENA_MASK                   0x0004  /* DCMP3_ENA */
+#define WM831X_DCMP3_ENA_SHIFT                       2  /* DCMP3_ENA */
+#define WM831X_DCMP3_ENA_WIDTH                       1  /* DCMP3_ENA */
+#define WM831X_DCMP2_ENA                        0x0002  /* DCMP2_ENA */
+#define WM831X_DCMP2_ENA_MASK                   0x0002  /* DCMP2_ENA */
+#define WM831X_DCMP2_ENA_SHIFT                       1  /* DCMP2_ENA */
+#define WM831X_DCMP2_ENA_WIDTH                       1  /* DCMP2_ENA */
+#define WM831X_DCMP1_ENA                        0x0001  /* DCMP1_ENA */
+#define WM831X_DCMP1_ENA_MASK                   0x0001  /* DCMP1_ENA */
+#define WM831X_DCMP1_ENA_SHIFT                       0  /* DCMP1_ENA */
+#define WM831X_DCMP1_ENA_WIDTH                       1  /* DCMP1_ENA */
+
+/*
+ * R16433 (0x4031) - Comparator 1
+ */
+#define WM831X_DCMP1_SRC_MASK                   0xE000  /* DCMP1_SRC - [15:13] */
+#define WM831X_DCMP1_SRC_SHIFT                      13  /* DCMP1_SRC - [15:13] */
+#define WM831X_DCMP1_SRC_WIDTH                       3  /* DCMP1_SRC - [15:13] */
+#define WM831X_DCMP1_GT                         0x1000  /* DCMP1_GT */
+#define WM831X_DCMP1_GT_MASK                    0x1000  /* DCMP1_GT */
+#define WM831X_DCMP1_GT_SHIFT                       12  /* DCMP1_GT */
+#define WM831X_DCMP1_GT_WIDTH                        1  /* DCMP1_GT */
+#define WM831X_DCMP1_THR_MASK                   0x0FFF  /* DCMP1_THR - [11:0] */
+#define WM831X_DCMP1_THR_SHIFT                       0  /* DCMP1_THR - [11:0] */
+#define WM831X_DCMP1_THR_WIDTH                      12  /* DCMP1_THR - [11:0] */
+
+/*
+ * R16434 (0x4032) - Comparator 2
+ */
+#define WM831X_DCMP2_SRC_MASK                   0xE000  /* DCMP2_SRC - [15:13] */
+#define WM831X_DCMP2_SRC_SHIFT                      13  /* DCMP2_SRC - [15:13] */
+#define WM831X_DCMP2_SRC_WIDTH                       3  /* DCMP2_SRC - [15:13] */
+#define WM831X_DCMP2_GT                         0x1000  /* DCMP2_GT */
+#define WM831X_DCMP2_GT_MASK                    0x1000  /* DCMP2_GT */
+#define WM831X_DCMP2_GT_SHIFT                       12  /* DCMP2_GT */
+#define WM831X_DCMP2_GT_WIDTH                        1  /* DCMP2_GT */
+#define WM831X_DCMP2_THR_MASK                   0x0FFF  /* DCMP2_THR - [11:0] */
+#define WM831X_DCMP2_THR_SHIFT                       0  /* DCMP2_THR - [11:0] */
+#define WM831X_DCMP2_THR_WIDTH                      12  /* DCMP2_THR - [11:0] */
+
+/*
+ * R16435 (0x4033) - Comparator 3
+ */
+#define WM831X_DCMP3_SRC_MASK                   0xE000  /* DCMP3_SRC - [15:13] */
+#define WM831X_DCMP3_SRC_SHIFT                      13  /* DCMP3_SRC - [15:13] */
+#define WM831X_DCMP3_SRC_WIDTH                       3  /* DCMP3_SRC - [15:13] */
+#define WM831X_DCMP3_GT                         0x1000  /* DCMP3_GT */
+#define WM831X_DCMP3_GT_MASK                    0x1000  /* DCMP3_GT */
+#define WM831X_DCMP3_GT_SHIFT                       12  /* DCMP3_GT */
+#define WM831X_DCMP3_GT_WIDTH                        1  /* DCMP3_GT */
+#define WM831X_DCMP3_THR_MASK                   0x0FFF  /* DCMP3_THR - [11:0] */
+#define WM831X_DCMP3_THR_SHIFT                       0  /* DCMP3_THR - [11:0] */
+#define WM831X_DCMP3_THR_WIDTH                      12  /* DCMP3_THR - [11:0] */
+
+/*
+ * R16436 (0x4034) - Comparator 4
+ */
+#define WM831X_DCMP4_SRC_MASK                   0xE000  /* DCMP4_SRC - [15:13] */
+#define WM831X_DCMP4_SRC_SHIFT                      13  /* DCMP4_SRC - [15:13] */
+#define WM831X_DCMP4_SRC_WIDTH                       3  /* DCMP4_SRC - [15:13] */
+#define WM831X_DCMP4_GT                         0x1000  /* DCMP4_GT */
+#define WM831X_DCMP4_GT_MASK                    0x1000  /* DCMP4_GT */
+#define WM831X_DCMP4_GT_SHIFT                       12  /* DCMP4_GT */
+#define WM831X_DCMP4_GT_WIDTH                        1  /* DCMP4_GT */
+#define WM831X_DCMP4_THR_MASK                   0x0FFF  /* DCMP4_THR - [11:0] */
+#define WM831X_DCMP4_THR_SHIFT                       0  /* DCMP4_THR - [11:0] */
+#define WM831X_DCMP4_THR_WIDTH                      12  /* DCMP4_THR - [11:0] */
+
+#define WM831X_AUX_CAL_FACTOR  0xfff
+#define WM831X_AUX_CAL_NOMINAL 0x222
+
+enum wm831x_auxadc {
+	WM831X_AUX_CAL = 15,
+	WM831X_AUX_BKUP_BATT = 10,
+	WM831X_AUX_WALL = 9,
+	WM831X_AUX_BATT = 8,
+	WM831X_AUX_USB = 7,
+	WM831X_AUX_SYSVDD = 6,
+	WM831X_AUX_BATT_TEMP = 5,
+	WM831X_AUX_CHIP_TEMP = 4,
+	WM831X_AUX_AUX4 = 3,
+	WM831X_AUX_AUX3 = 2,
+	WM831X_AUX_AUX2 = 1,
+	WM831X_AUX_AUX1 = 0,
+};
+
+int wm831x_auxadc_read(struct wm831x *wm831x, enum wm831x_auxadc input);
+int wm831x_auxadc_read_uv(struct wm831x *wm831x, enum wm831x_auxadc input);
+
+#endif
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
new file mode 100644
index 0000000..91eb493
--- /dev/null
+++ b/include/linux/mfd/wm831x/core.h
@@ -0,0 +1,289 @@
+/*
+ * include/linux/mfd/wm831x/core.h -- Core interface for WM831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_CORE_H__
+#define __MFD_WM831X_CORE_H__
+
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+
+/*
+ * Register values.
+ */
+#define WM831X_RESET_ID                         0x00
+#define WM831X_REVISION                         0x01
+#define WM831X_PARENT_ID                        0x4000
+#define WM831X_SYSVDD_CONTROL                   0x4001
+#define WM831X_THERMAL_MONITORING               0x4002
+#define WM831X_POWER_STATE                      0x4003
+#define WM831X_WATCHDOG                         0x4004
+#define WM831X_ON_PIN_CONTROL                   0x4005
+#define WM831X_RESET_CONTROL                    0x4006
+#define WM831X_CONTROL_INTERFACE                0x4007
+#define WM831X_SECURITY_KEY                     0x4008
+#define WM831X_SOFTWARE_SCRATCH                 0x4009
+#define WM831X_OTP_CONTROL                      0x400A
+#define WM831X_GPIO_LEVEL                       0x400C
+#define WM831X_SYSTEM_STATUS                    0x400D
+#define WM831X_ON_SOURCE                        0x400E
+#define WM831X_OFF_SOURCE                       0x400F
+#define WM831X_SYSTEM_INTERRUPTS                0x4010
+#define WM831X_INTERRUPT_STATUS_1               0x4011
+#define WM831X_INTERRUPT_STATUS_2               0x4012
+#define WM831X_INTERRUPT_STATUS_3               0x4013
+#define WM831X_INTERRUPT_STATUS_4               0x4014
+#define WM831X_INTERRUPT_STATUS_5               0x4015
+#define WM831X_IRQ_CONFIG                       0x4017
+#define WM831X_SYSTEM_INTERRUPTS_MASK           0x4018
+#define WM831X_INTERRUPT_STATUS_1_MASK          0x4019
+#define WM831X_INTERRUPT_STATUS_2_MASK          0x401A
+#define WM831X_INTERRUPT_STATUS_3_MASK          0x401B
+#define WM831X_INTERRUPT_STATUS_4_MASK          0x401C
+#define WM831X_INTERRUPT_STATUS_5_MASK          0x401D
+#define WM831X_RTC_WRITE_COUNTER                0x4020
+#define WM831X_RTC_TIME_1                       0x4021
+#define WM831X_RTC_TIME_2                       0x4022
+#define WM831X_RTC_ALARM_1                      0x4023
+#define WM831X_RTC_ALARM_2                      0x4024
+#define WM831X_RTC_CONTROL                      0x4025
+#define WM831X_RTC_TRIM                         0x4026
+#define WM831X_TOUCH_CONTROL_1                  0x4028
+#define WM831X_TOUCH_CONTROL_2                  0x4029
+#define WM831X_TOUCH_DATA_X                     0x402A
+#define WM831X_TOUCH_DATA_Y                     0x402B
+#define WM831X_TOUCH_DATA_Z                     0x402C
+#define WM831X_AUXADC_DATA                      0x402D
+#define WM831X_AUXADC_CONTROL                   0x402E
+#define WM831X_AUXADC_SOURCE                    0x402F
+#define WM831X_COMPARATOR_CONTROL               0x4030
+#define WM831X_COMPARATOR_1                     0x4031
+#define WM831X_COMPARATOR_2                     0x4032
+#define WM831X_COMPARATOR_3                     0x4033
+#define WM831X_COMPARATOR_4                     0x4034
+#define WM831X_GPIO1_CONTROL                    0x4038
+#define WM831X_GPIO2_CONTROL                    0x4039
+#define WM831X_GPIO3_CONTROL                    0x403A
+#define WM831X_GPIO4_CONTROL                    0x403B
+#define WM831X_GPIO5_CONTROL                    0x403C
+#define WM831X_GPIO6_CONTROL                    0x403D
+#define WM831X_GPIO7_CONTROL                    0x403E
+#define WM831X_GPIO8_CONTROL                    0x403F
+#define WM831X_GPIO9_CONTROL                    0x4040
+#define WM831X_GPIO10_CONTROL                   0x4041
+#define WM831X_GPIO11_CONTROL                   0x4042
+#define WM831X_GPIO12_CONTROL                   0x4043
+#define WM831X_GPIO13_CONTROL                   0x4044
+#define WM831X_GPIO14_CONTROL                   0x4045
+#define WM831X_GPIO15_CONTROL                   0x4046
+#define WM831X_GPIO16_CONTROL                   0x4047
+#define WM831X_CHARGER_CONTROL_1                0x4048
+#define WM831X_CHARGER_CONTROL_2                0x4049
+#define WM831X_CHARGER_STATUS                   0x404A
+#define WM831X_BACKUP_CHARGER_CONTROL           0x404B
+#define WM831X_STATUS_LED_1                     0x404C
+#define WM831X_STATUS_LED_2                     0x404D
+#define WM831X_CURRENT_SINK_1                   0x404E
+#define WM831X_CURRENT_SINK_2                   0x404F
+#define WM831X_DCDC_ENABLE                      0x4050
+#define WM831X_LDO_ENABLE                       0x4051
+#define WM831X_DCDC_STATUS                      0x4052
+#define WM831X_LDO_STATUS                       0x4053
+#define WM831X_DCDC_UV_STATUS                   0x4054
+#define WM831X_LDO_UV_STATUS                    0x4055
+#define WM831X_DC1_CONTROL_1                    0x4056
+#define WM831X_DC1_CONTROL_2                    0x4057
+#define WM831X_DC1_ON_CONFIG                    0x4058
+#define WM831X_DC1_SLEEP_CONTROL                0x4059
+#define WM831X_DC1_DVS_CONTROL                  0x405A
+#define WM831X_DC2_CONTROL_1                    0x405B
+#define WM831X_DC2_CONTROL_2                    0x405C
+#define WM831X_DC2_ON_CONFIG                    0x405D
+#define WM831X_DC2_SLEEP_CONTROL                0x405E
+#define WM831X_DC2_DVS_CONTROL                  0x405F
+#define WM831X_DC3_CONTROL_1                    0x4060
+#define WM831X_DC3_CONTROL_2                    0x4061
+#define WM831X_DC3_ON_CONFIG                    0x4062
+#define WM831X_DC3_SLEEP_CONTROL                0x4063
+#define WM831X_DC4_CONTROL                      0x4064
+#define WM831X_DC4_SLEEP_CONTROL                0x4065
+#define WM831X_EPE1_CONTROL                     0x4066
+#define WM831X_EPE2_CONTROL                     0x4067
+#define WM831X_LDO1_CONTROL                     0x4068
+#define WM831X_LDO1_ON_CONTROL                  0x4069
+#define WM831X_LDO1_SLEEP_CONTROL               0x406A
+#define WM831X_LDO2_CONTROL                     0x406B
+#define WM831X_LDO2_ON_CONTROL                  0x406C
+#define WM831X_LDO2_SLEEP_CONTROL               0x406D
+#define WM831X_LDO3_CONTROL                     0x406E
+#define WM831X_LDO3_ON_CONTROL                  0x406F
+#define WM831X_LDO3_SLEEP_CONTROL               0x4070
+#define WM831X_LDO4_CONTROL                     0x4071
+#define WM831X_LDO4_ON_CONTROL                  0x4072
+#define WM831X_LDO4_SLEEP_CONTROL               0x4073
+#define WM831X_LDO5_CONTROL                     0x4074
+#define WM831X_LDO5_ON_CONTROL                  0x4075
+#define WM831X_LDO5_SLEEP_CONTROL               0x4076
+#define WM831X_LDO6_CONTROL                     0x4077
+#define WM831X_LDO6_ON_CONTROL                  0x4078
+#define WM831X_LDO6_SLEEP_CONTROL               0x4079
+#define WM831X_LDO7_CONTROL                     0x407A
+#define WM831X_LDO7_ON_CONTROL                  0x407B
+#define WM831X_LDO7_SLEEP_CONTROL               0x407C
+#define WM831X_LDO8_CONTROL                     0x407D
+#define WM831X_LDO8_ON_CONTROL                  0x407E
+#define WM831X_LDO8_SLEEP_CONTROL               0x407F
+#define WM831X_LDO9_CONTROL                     0x4080
+#define WM831X_LDO9_ON_CONTROL                  0x4081
+#define WM831X_LDO9_SLEEP_CONTROL               0x4082
+#define WM831X_LDO10_CONTROL                    0x4083
+#define WM831X_LDO10_ON_CONTROL                 0x4084
+#define WM831X_LDO10_SLEEP_CONTROL              0x4085
+#define WM831X_LDO11_ON_CONTROL                 0x4087
+#define WM831X_LDO11_SLEEP_CONTROL              0x4088
+#define WM831X_POWER_GOOD_SOURCE_1              0x408E
+#define WM831X_POWER_GOOD_SOURCE_2              0x408F
+#define WM831X_CLOCK_CONTROL_1                  0x4090
+#define WM831X_CLOCK_CONTROL_2                  0x4091
+#define WM831X_FLL_CONTROL_1                    0x4092
+#define WM831X_FLL_CONTROL_2                    0x4093
+#define WM831X_FLL_CONTROL_3                    0x4094
+#define WM831X_FLL_CONTROL_4                    0x4095
+#define WM831X_FLL_CONTROL_5                    0x4096
+#define WM831X_UNIQUE_ID_1                      0x7800
+#define WM831X_UNIQUE_ID_2                      0x7801
+#define WM831X_UNIQUE_ID_3                      0x7802
+#define WM831X_UNIQUE_ID_4                      0x7803
+#define WM831X_UNIQUE_ID_5                      0x7804
+#define WM831X_UNIQUE_ID_6                      0x7805
+#define WM831X_UNIQUE_ID_7                      0x7806
+#define WM831X_UNIQUE_ID_8                      0x7807
+#define WM831X_FACTORY_OTP_ID                   0x7808
+#define WM831X_FACTORY_OTP_1                    0x7809
+#define WM831X_FACTORY_OTP_2                    0x780A
+#define WM831X_FACTORY_OTP_3                    0x780B
+#define WM831X_FACTORY_OTP_4                    0x780C
+#define WM831X_FACTORY_OTP_5                    0x780D
+#define WM831X_CUSTOMER_OTP_ID                  0x7810
+#define WM831X_DC1_OTP_CONTROL                  0x7811
+#define WM831X_DC2_OTP_CONTROL                  0x7812
+#define WM831X_DC3_OTP_CONTROL                  0x7813
+#define WM831X_LDO1_2_OTP_CONTROL               0x7814
+#define WM831X_LDO3_4_OTP_CONTROL               0x7815
+#define WM831X_LDO5_6_OTP_CONTROL               0x7816
+#define WM831X_LDO7_8_OTP_CONTROL               0x7817
+#define WM831X_LDO9_10_OTP_CONTROL              0x7818
+#define WM831X_LDO11_EPE_CONTROL                0x7819
+#define WM831X_GPIO1_OTP_CONTROL                0x781A
+#define WM831X_GPIO2_OTP_CONTROL                0x781B
+#define WM831X_GPIO3_OTP_CONTROL                0x781C
+#define WM831X_GPIO4_OTP_CONTROL                0x781D
+#define WM831X_GPIO5_OTP_CONTROL                0x781E
+#define WM831X_GPIO6_OTP_CONTROL                0x781F
+#define WM831X_DBE_CHECK_DATA                   0x7827
+
+/*
+ * R0 (0x00) - Reset ID
+ */
+#define WM831X_CHIP_ID_MASK                     0xFFFF  /* CHIP_ID - [15:0] */
+#define WM831X_CHIP_ID_SHIFT                         0  /* CHIP_ID - [15:0] */
+#define WM831X_CHIP_ID_WIDTH                        16  /* CHIP_ID - [15:0] */
+
+/*
+ * R1 (0x01) - Revision
+ */
+#define WM831X_PARENT_REV_MASK                  0xFF00  /* PARENT_REV - [15:8] */
+#define WM831X_PARENT_REV_SHIFT                      8  /* PARENT_REV - [15:8] */
+#define WM831X_PARENT_REV_WIDTH                      8  /* PARENT_REV - [15:8] */
+#define WM831X_CHILD_REV_MASK                   0x00FF  /* CHILD_REV - [7:0] */
+#define WM831X_CHILD_REV_SHIFT                       0  /* CHILD_REV - [7:0] */
+#define WM831X_CHILD_REV_WIDTH                       8  /* CHILD_REV - [7:0] */
+
+/*
+ * R16384 (0x4000) - Parent ID
+ */
+#define WM831X_PARENT_ID_MASK                   0xFFFF  /* PARENT_ID - [15:0] */
+#define WM831X_PARENT_ID_SHIFT                       0  /* PARENT_ID - [15:0] */
+#define WM831X_PARENT_ID_WIDTH                      16  /* PARENT_ID - [15:0] */
+
+/*
+ * R16389 (0x4005) - ON Pin Control
+ */
+#define WM831X_ON_PIN_SECACT_MASK               0x0300  /* ON_PIN_SECACT - [9:8] */
+#define WM831X_ON_PIN_SECACT_SHIFT                   8  /* ON_PIN_SECACT - [9:8] */
+#define WM831X_ON_PIN_SECACT_WIDTH                   2  /* ON_PIN_SECACT - [9:8] */
+#define WM831X_ON_PIN_PRIMACT_MASK              0x0030  /* ON_PIN_PRIMACT - [5:4] */
+#define WM831X_ON_PIN_PRIMACT_SHIFT                  4  /* ON_PIN_PRIMACT - [5:4] */
+#define WM831X_ON_PIN_PRIMACT_WIDTH                  2  /* ON_PIN_PRIMACT - [5:4] */
+#define WM831X_ON_PIN_STS                       0x0008  /* ON_PIN_STS */
+#define WM831X_ON_PIN_STS_MASK                  0x0008  /* ON_PIN_STS */
+#define WM831X_ON_PIN_STS_SHIFT                      3  /* ON_PIN_STS */
+#define WM831X_ON_PIN_STS_WIDTH                      1  /* ON_PIN_STS */
+#define WM831X_ON_PIN_TO_MASK                   0x0003  /* ON_PIN_TO - [1:0] */
+#define WM831X_ON_PIN_TO_SHIFT                       0  /* ON_PIN_TO - [1:0] */
+#define WM831X_ON_PIN_TO_WIDTH                       2  /* ON_PIN_TO - [1:0] */
+
+struct regulator_dev;
+
+struct wm831x {
+	struct mutex io_lock;
+
+	struct device *dev;
+	int (*read_dev)(struct wm831x *wm831x, unsigned short reg,
+			int bytes, void *dest);
+	int (*write_dev)(struct wm831x *wm831x, unsigned short reg,
+			 int bytes, void *src);
+
+	void *control_data;
+
+	int irq;  /* Our chip IRQ */
+	struct mutex irq_lock;
+	struct workqueue_struct *irq_wq;
+	struct work_struct irq_work;
+	unsigned int irq_base;
+	int irq_masks[5];
+
+	struct mutex auxadc_lock;
+
+	/* The WM831x has a security key blocking access to certain
+	 * registers.  The mutex is taken by the accessors for locking
+	 * and unlocking the security key, locked is used to fail
+	 * writes if the lock is held.
+	 */
+	struct mutex key_lock;
+	unsigned int locked:1;
+};
+
+/* Device I/O API */
+int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg);
+int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
+		 unsigned short val);
+void wm831x_reg_lock(struct wm831x *wm831x);
+int wm831x_reg_unlock(struct wm831x *wm831x);
+int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
+		    unsigned short mask, unsigned short val);
+int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
+		     int count, u16 *buf);
+
+int wm831x_irq_init(struct wm831x *wm831x, int irq);
+void wm831x_irq_exit(struct wm831x *wm831x);
+
+int __must_check wm831x_request_irq(struct wm831x *wm831x,
+				    unsigned int irq, irq_handler_t handler,
+				    unsigned long flags, const char *name,
+				    void *dev);
+void wm831x_free_irq(struct wm831x *wm831x, unsigned int, void *);
+void wm831x_disable_irq(struct wm831x *wm831x, int irq);
+void wm831x_enable_irq(struct wm831x *wm831x, int irq);
+
+#endif
diff --git a/include/linux/mfd/wm831x/gpio.h b/include/linux/mfd/wm831x/gpio.h
new file mode 100644
index 0000000..2835614
--- /dev/null
+++ b/include/linux/mfd/wm831x/gpio.h
@@ -0,0 +1,55 @@
+/*
+ * include/linux/mfd/wm831x/gpio.h -- GPIO for WM831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_GPIO_H__
+#define __MFD_WM831X_GPIO_H__
+
+/*
+ * R16440-16455 (0x4038-0x4047) - GPIOx Control
+ */
+#define WM831X_GPN_DIR                          0x8000  /* GPN_DIR */
+#define WM831X_GPN_DIR_MASK                     0x8000  /* GPN_DIR */
+#define WM831X_GPN_DIR_SHIFT                        15  /* GPN_DIR */
+#define WM831X_GPN_DIR_WIDTH                         1  /* GPN_DIR */
+#define WM831X_GPN_PULL_MASK                    0x6000  /* GPN_PULL - [14:13] */
+#define WM831X_GPN_PULL_SHIFT                       13  /* GPN_PULL - [14:13] */
+#define WM831X_GPN_PULL_WIDTH                        2  /* GPN_PULL - [14:13] */
+#define WM831X_GPN_INT_MODE                     0x1000  /* GPN_INT_MODE */
+#define WM831X_GPN_INT_MODE_MASK                0x1000  /* GPN_INT_MODE */
+#define WM831X_GPN_INT_MODE_SHIFT                   12  /* GPN_INT_MODE */
+#define WM831X_GPN_INT_MODE_WIDTH                    1  /* GPN_INT_MODE */
+#define WM831X_GPN_PWR_DOM                      0x0800  /* GPN_PWR_DOM */
+#define WM831X_GPN_PWR_DOM_MASK                 0x0800  /* GPN_PWR_DOM */
+#define WM831X_GPN_PWR_DOM_SHIFT                    11  /* GPN_PWR_DOM */
+#define WM831X_GPN_PWR_DOM_WIDTH                     1  /* GPN_PWR_DOM */
+#define WM831X_GPN_POL                          0x0400  /* GPN_POL */
+#define WM831X_GPN_POL_MASK                     0x0400  /* GPN_POL */
+#define WM831X_GPN_POL_SHIFT                        10  /* GPN_POL */
+#define WM831X_GPN_POL_WIDTH                         1  /* GPN_POL */
+#define WM831X_GPN_OD                           0x0200  /* GPN_OD */
+#define WM831X_GPN_OD_MASK                      0x0200  /* GPN_OD */
+#define WM831X_GPN_OD_SHIFT                          9  /* GPN_OD */
+#define WM831X_GPN_OD_WIDTH                          1  /* GPN_OD */
+#define WM831X_GPN_TRI                          0x0080  /* GPN_TRI */
+#define WM831X_GPN_TRI_MASK                     0x0080  /* GPN_TRI */
+#define WM831X_GPN_TRI_SHIFT                         7  /* GPN_TRI */
+#define WM831X_GPN_TRI_WIDTH                         1  /* GPN_TRI */
+#define WM831X_GPN_FN_MASK                      0x000F  /* GPN_FN - [3:0] */
+#define WM831X_GPN_FN_SHIFT                          0  /* GPN_FN - [3:0] */
+#define WM831X_GPN_FN_WIDTH                          4  /* GPN_FN - [3:0] */
+
+#define WM831X_GPIO_PULL_NONE (0 << WM831X_GPN_PULL_SHIFT)
+#define WM831X_GPIO_PULL_DOWN (1 << WM831X_GPN_PULL_SHIFT)
+#define WM831X_GPIO_PULL_UP   (2 << WM831X_GPN_PULL_SHIFT)
+#endif
diff --git a/include/linux/mfd/wm831x/irq.h b/include/linux/mfd/wm831x/irq.h
new file mode 100644
index 0000000..3a8c976
--- /dev/null
+++ b/include/linux/mfd/wm831x/irq.h
@@ -0,0 +1,764 @@
+/*
+ * include/linux/mfd/wm831x/irq.h -- Interrupt controller for WM831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_IRQ_H__
+#define __MFD_WM831X_IRQ_H__
+
+/* Interrupt number assignments within Linux */
+#define WM831X_IRQ_TEMP_THW 0
+#define WM831X_IRQ_GPIO_1   1
+#define WM831X_IRQ_GPIO_2   2
+#define WM831X_IRQ_GPIO_3   3
+#define WM831X_IRQ_GPIO_4   4
+#define WM831X_IRQ_GPIO_5   5
+#define WM831X_IRQ_GPIO_6   6
+#define WM831X_IRQ_GPIO_7   7
+#define WM831X_IRQ_GPIO_8   8
+#define WM831X_IRQ_GPIO_9   9
+#define WM831X_IRQ_GPIO_10  10
+#define WM831X_IRQ_GPIO_11  11
+#define WM831X_IRQ_GPIO_12  12
+#define WM831X_IRQ_GPIO_13  13
+#define WM831X_IRQ_GPIO_14  14
+#define WM831X_IRQ_GPIO_15  15
+#define WM831X_IRQ_GPIO_16  16
+#define WM831X_IRQ_ON           17
+#define WM831X_IRQ_PPM_SYSLO    18
+#define WM831X_IRQ_PPM_PWR_SRC  19
+#define WM831X_IRQ_PPM_USB_CURR 20
+#define WM831X_IRQ_WDOG_TO      21
+#define WM831X_IRQ_RTC_PER      22
+#define WM831X_IRQ_RTC_ALM      23
+#define WM831X_IRQ_CHG_BATT_HOT  24
+#define WM831X_IRQ_CHG_BATT_COLD 25
+#define WM831X_IRQ_CHG_BATT_FAIL 26
+#define WM831X_IRQ_CHG_OV        27
+#define WM831X_IRQ_CHG_END       29
+#define WM831X_IRQ_CHG_TO        30
+#define WM831X_IRQ_CHG_MODE      31
+#define WM831X_IRQ_CHG_START     32
+#define WM831X_IRQ_TCHDATA       33
+#define WM831X_IRQ_TCHPD         34
+#define WM831X_IRQ_AUXADC_DATA   35
+#define WM831X_IRQ_AUXADC_DCOMP1 36
+#define WM831X_IRQ_AUXADC_DCOMP2 37
+#define WM831X_IRQ_AUXADC_DCOMP3 38
+#define WM831X_IRQ_AUXADC_DCOMP4 39
+#define WM831X_IRQ_CS1           40
+#define WM831X_IRQ_CS2           41
+#define WM831X_IRQ_HC_DC1        42
+#define WM831X_IRQ_HC_DC2        43
+#define WM831X_IRQ_UV_LDO1       44
+#define WM831X_IRQ_UV_LDO2       45
+#define WM831X_IRQ_UV_LDO3       46
+#define WM831X_IRQ_UV_LDO4       47
+#define WM831X_IRQ_UV_LDO5       48
+#define WM831X_IRQ_UV_LDO6       49
+#define WM831X_IRQ_UV_LDO7       50
+#define WM831X_IRQ_UV_LDO8       51
+#define WM831X_IRQ_UV_LDO9       52
+#define WM831X_IRQ_UV_LDO10      53
+#define WM831X_IRQ_UV_DC1        54
+#define WM831X_IRQ_UV_DC2        55
+#define WM831X_IRQ_UV_DC3        56
+#define WM831X_IRQ_UV_DC4        57
+
+#define WM831X_NUM_IRQS     58
+
+/*
+ * R16400 (0x4010) - System Interrupts
+ */
+#define WM831X_PS_INT                           0x8000  /* PS_INT */
+#define WM831X_PS_INT_MASK                      0x8000  /* PS_INT */
+#define WM831X_PS_INT_SHIFT                         15  /* PS_INT */
+#define WM831X_PS_INT_WIDTH                          1  /* PS_INT */
+#define WM831X_TEMP_INT                         0x4000  /* TEMP_INT */
+#define WM831X_TEMP_INT_MASK                    0x4000  /* TEMP_INT */
+#define WM831X_TEMP_INT_SHIFT                       14  /* TEMP_INT */
+#define WM831X_TEMP_INT_WIDTH                        1  /* TEMP_INT */
+#define WM831X_GP_INT                           0x2000  /* GP_INT */
+#define WM831X_GP_INT_MASK                      0x2000  /* GP_INT */
+#define WM831X_GP_INT_SHIFT                         13  /* GP_INT */
+#define WM831X_GP_INT_WIDTH                          1  /* GP_INT */
+#define WM831X_ON_PIN_INT                       0x1000  /* ON_PIN_INT */
+#define WM831X_ON_PIN_INT_MASK                  0x1000  /* ON_PIN_INT */
+#define WM831X_ON_PIN_INT_SHIFT                     12  /* ON_PIN_INT */
+#define WM831X_ON_PIN_INT_WIDTH                      1  /* ON_PIN_INT */
+#define WM831X_WDOG_INT                         0x0800  /* WDOG_INT */
+#define WM831X_WDOG_INT_MASK                    0x0800  /* WDOG_INT */
+#define WM831X_WDOG_INT_SHIFT                       11  /* WDOG_INT */
+#define WM831X_WDOG_INT_WIDTH                        1  /* WDOG_INT */
+#define WM831X_TCHDATA_INT                      0x0400  /* TCHDATA_INT */
+#define WM831X_TCHDATA_INT_MASK                 0x0400  /* TCHDATA_INT */
+#define WM831X_TCHDATA_INT_SHIFT                    10  /* TCHDATA_INT */
+#define WM831X_TCHDATA_INT_WIDTH                     1  /* TCHDATA_INT */
+#define WM831X_TCHPD_INT                        0x0200  /* TCHPD_INT */
+#define WM831X_TCHPD_INT_MASK                   0x0200  /* TCHPD_INT */
+#define WM831X_TCHPD_INT_SHIFT                       9  /* TCHPD_INT */
+#define WM831X_TCHPD_INT_WIDTH                       1  /* TCHPD_INT */
+#define WM831X_AUXADC_INT                       0x0100  /* AUXADC_INT */
+#define WM831X_AUXADC_INT_MASK                  0x0100  /* AUXADC_INT */
+#define WM831X_AUXADC_INT_SHIFT                      8  /* AUXADC_INT */
+#define WM831X_AUXADC_INT_WIDTH                      1  /* AUXADC_INT */
+#define WM831X_PPM_INT                          0x0080  /* PPM_INT */
+#define WM831X_PPM_INT_MASK                     0x0080  /* PPM_INT */
+#define WM831X_PPM_INT_SHIFT                         7  /* PPM_INT */
+#define WM831X_PPM_INT_WIDTH                         1  /* PPM_INT */
+#define WM831X_CS_INT                           0x0040  /* CS_INT */
+#define WM831X_CS_INT_MASK                      0x0040  /* CS_INT */
+#define WM831X_CS_INT_SHIFT                          6  /* CS_INT */
+#define WM831X_CS_INT_WIDTH                          1  /* CS_INT */
+#define WM831X_RTC_INT                          0x0020  /* RTC_INT */
+#define WM831X_RTC_INT_MASK                     0x0020  /* RTC_INT */
+#define WM831X_RTC_INT_SHIFT                         5  /* RTC_INT */
+#define WM831X_RTC_INT_WIDTH                         1  /* RTC_INT */
+#define WM831X_OTP_INT                          0x0010  /* OTP_INT */
+#define WM831X_OTP_INT_MASK                     0x0010  /* OTP_INT */
+#define WM831X_OTP_INT_SHIFT                         4  /* OTP_INT */
+#define WM831X_OTP_INT_WIDTH                         1  /* OTP_INT */
+#define WM831X_CHILD_INT                        0x0008  /* CHILD_INT */
+#define WM831X_CHILD_INT_MASK                   0x0008  /* CHILD_INT */
+#define WM831X_CHILD_INT_SHIFT                       3  /* CHILD_INT */
+#define WM831X_CHILD_INT_WIDTH                       1  /* CHILD_INT */
+#define WM831X_CHG_INT                          0x0004  /* CHG_INT */
+#define WM831X_CHG_INT_MASK                     0x0004  /* CHG_INT */
+#define WM831X_CHG_INT_SHIFT                         2  /* CHG_INT */
+#define WM831X_CHG_INT_WIDTH                         1  /* CHG_INT */
+#define WM831X_HC_INT                           0x0002  /* HC_INT */
+#define WM831X_HC_INT_MASK                      0x0002  /* HC_INT */
+#define WM831X_HC_INT_SHIFT                          1  /* HC_INT */
+#define WM831X_HC_INT_WIDTH                          1  /* HC_INT */
+#define WM831X_UV_INT                           0x0001  /* UV_INT */
+#define WM831X_UV_INT_MASK                      0x0001  /* UV_INT */
+#define WM831X_UV_INT_SHIFT                          0  /* UV_INT */
+#define WM831X_UV_INT_WIDTH                          1  /* UV_INT */
+
+/*
+ * R16401 (0x4011) - Interrupt Status 1
+ */
+#define WM831X_PPM_SYSLO_EINT                   0x8000  /* PPM_SYSLO_EINT */
+#define WM831X_PPM_SYSLO_EINT_MASK              0x8000  /* PPM_SYSLO_EINT */
+#define WM831X_PPM_SYSLO_EINT_SHIFT                 15  /* PPM_SYSLO_EINT */
+#define WM831X_PPM_SYSLO_EINT_WIDTH                  1  /* PPM_SYSLO_EINT */
+#define WM831X_PPM_PWR_SRC_EINT                 0x4000  /* PPM_PWR_SRC_EINT */
+#define WM831X_PPM_PWR_SRC_EINT_MASK            0x4000  /* PPM_PWR_SRC_EINT */
+#define WM831X_PPM_PWR_SRC_EINT_SHIFT               14  /* PPM_PWR_SRC_EINT */
+#define WM831X_PPM_PWR_SRC_EINT_WIDTH                1  /* PPM_PWR_SRC_EINT */
+#define WM831X_PPM_USB_CURR_EINT                0x2000  /* PPM_USB_CURR_EINT */
+#define WM831X_PPM_USB_CURR_EINT_MASK           0x2000  /* PPM_USB_CURR_EINT */
+#define WM831X_PPM_USB_CURR_EINT_SHIFT              13  /* PPM_USB_CURR_EINT */
+#define WM831X_PPM_USB_CURR_EINT_WIDTH               1  /* PPM_USB_CURR_EINT */
+#define WM831X_ON_PIN_EINT                      0x1000  /* ON_PIN_EINT */
+#define WM831X_ON_PIN_EINT_MASK                 0x1000  /* ON_PIN_EINT */
+#define WM831X_ON_PIN_EINT_SHIFT                    12  /* ON_PIN_EINT */
+#define WM831X_ON_PIN_EINT_WIDTH                     1  /* ON_PIN_EINT */
+#define WM831X_WDOG_TO_EINT                     0x0800  /* WDOG_TO_EINT */
+#define WM831X_WDOG_TO_EINT_MASK                0x0800  /* WDOG_TO_EINT */
+#define WM831X_WDOG_TO_EINT_SHIFT                   11  /* WDOG_TO_EINT */
+#define WM831X_WDOG_TO_EINT_WIDTH                    1  /* WDOG_TO_EINT */
+#define WM831X_TCHDATA_EINT                     0x0400  /* TCHDATA_EINT */
+#define WM831X_TCHDATA_EINT_MASK                0x0400  /* TCHDATA_EINT */
+#define WM831X_TCHDATA_EINT_SHIFT                   10  /* TCHDATA_EINT */
+#define WM831X_TCHDATA_EINT_WIDTH                    1  /* TCHDATA_EINT */
+#define WM831X_TCHPD_EINT                       0x0200  /* TCHPD_EINT */
+#define WM831X_TCHPD_EINT_MASK                  0x0200  /* TCHPD_EINT */
+#define WM831X_TCHPD_EINT_SHIFT                      9  /* TCHPD_EINT */
+#define WM831X_TCHPD_EINT_WIDTH                      1  /* TCHPD_EINT */
+#define WM831X_AUXADC_DATA_EINT                 0x0100  /* AUXADC_DATA_EINT */
+#define WM831X_AUXADC_DATA_EINT_MASK            0x0100  /* AUXADC_DATA_EINT */
+#define WM831X_AUXADC_DATA_EINT_SHIFT                8  /* AUXADC_DATA_EINT */
+#define WM831X_AUXADC_DATA_EINT_WIDTH                1  /* AUXADC_DATA_EINT */
+#define WM831X_AUXADC_DCOMP4_EINT               0x0080  /* AUXADC_DCOMP4_EINT */
+#define WM831X_AUXADC_DCOMP4_EINT_MASK          0x0080  /* AUXADC_DCOMP4_EINT */
+#define WM831X_AUXADC_DCOMP4_EINT_SHIFT              7  /* AUXADC_DCOMP4_EINT */
+#define WM831X_AUXADC_DCOMP4_EINT_WIDTH              1  /* AUXADC_DCOMP4_EINT */
+#define WM831X_AUXADC_DCOMP3_EINT               0x0040  /* AUXADC_DCOMP3_EINT */
+#define WM831X_AUXADC_DCOMP3_EINT_MASK          0x0040  /* AUXADC_DCOMP3_EINT */
+#define WM831X_AUXADC_DCOMP3_EINT_SHIFT              6  /* AUXADC_DCOMP3_EINT */
+#define WM831X_AUXADC_DCOMP3_EINT_WIDTH              1  /* AUXADC_DCOMP3_EINT */
+#define WM831X_AUXADC_DCOMP2_EINT               0x0020  /* AUXADC_DCOMP2_EINT */
+#define WM831X_AUXADC_DCOMP2_EINT_MASK          0x0020  /* AUXADC_DCOMP2_EINT */
+#define WM831X_AUXADC_DCOMP2_EINT_SHIFT              5  /* AUXADC_DCOMP2_EINT */
+#define WM831X_AUXADC_DCOMP2_EINT_WIDTH              1  /* AUXADC_DCOMP2_EINT */
+#define WM831X_AUXADC_DCOMP1_EINT               0x0010  /* AUXADC_DCOMP1_EINT */
+#define WM831X_AUXADC_DCOMP1_EINT_MASK          0x0010  /* AUXADC_DCOMP1_EINT */
+#define WM831X_AUXADC_DCOMP1_EINT_SHIFT              4  /* AUXADC_DCOMP1_EINT */
+#define WM831X_AUXADC_DCOMP1_EINT_WIDTH              1  /* AUXADC_DCOMP1_EINT */
+#define WM831X_RTC_PER_EINT                     0x0008  /* RTC_PER_EINT */
+#define WM831X_RTC_PER_EINT_MASK                0x0008  /* RTC_PER_EINT */
+#define WM831X_RTC_PER_EINT_SHIFT                    3  /* RTC_PER_EINT */
+#define WM831X_RTC_PER_EINT_WIDTH                    1  /* RTC_PER_EINT */
+#define WM831X_RTC_ALM_EINT                     0x0004  /* RTC_ALM_EINT */
+#define WM831X_RTC_ALM_EINT_MASK                0x0004  /* RTC_ALM_EINT */
+#define WM831X_RTC_ALM_EINT_SHIFT                    2  /* RTC_ALM_EINT */
+#define WM831X_RTC_ALM_EINT_WIDTH                    1  /* RTC_ALM_EINT */
+#define WM831X_TEMP_THW_EINT                    0x0002  /* TEMP_THW_EINT */
+#define WM831X_TEMP_THW_EINT_MASK               0x0002  /* TEMP_THW_EINT */
+#define WM831X_TEMP_THW_EINT_SHIFT                   1  /* TEMP_THW_EINT */
+#define WM831X_TEMP_THW_EINT_WIDTH                   1  /* TEMP_THW_EINT */
+
+/*
+ * R16402 (0x4012) - Interrupt Status 2
+ */
+#define WM831X_CHG_BATT_HOT_EINT                0x8000  /* CHG_BATT_HOT_EINT */
+#define WM831X_CHG_BATT_HOT_EINT_MASK           0x8000  /* CHG_BATT_HOT_EINT */
+#define WM831X_CHG_BATT_HOT_EINT_SHIFT              15  /* CHG_BATT_HOT_EINT */
+#define WM831X_CHG_BATT_HOT_EINT_WIDTH               1  /* CHG_BATT_HOT_EINT */
+#define WM831X_CHG_BATT_COLD_EINT               0x4000  /* CHG_BATT_COLD_EINT */
+#define WM831X_CHG_BATT_COLD_EINT_MASK          0x4000  /* CHG_BATT_COLD_EINT */
+#define WM831X_CHG_BATT_COLD_EINT_SHIFT             14  /* CHG_BATT_COLD_EINT */
+#define WM831X_CHG_BATT_COLD_EINT_WIDTH              1  /* CHG_BATT_COLD_EINT */
+#define WM831X_CHG_BATT_FAIL_EINT               0x2000  /* CHG_BATT_FAIL_EINT */
+#define WM831X_CHG_BATT_FAIL_EINT_MASK          0x2000  /* CHG_BATT_FAIL_EINT */
+#define WM831X_CHG_BATT_FAIL_EINT_SHIFT             13  /* CHG_BATT_FAIL_EINT */
+#define WM831X_CHG_BATT_FAIL_EINT_WIDTH              1  /* CHG_BATT_FAIL_EINT */
+#define WM831X_CHG_OV_EINT                      0x1000  /* CHG_OV_EINT */
+#define WM831X_CHG_OV_EINT_MASK                 0x1000  /* CHG_OV_EINT */
+#define WM831X_CHG_OV_EINT_SHIFT                    12  /* CHG_OV_EINT */
+#define WM831X_CHG_OV_EINT_WIDTH                     1  /* CHG_OV_EINT */
+#define WM831X_CHG_END_EINT                     0x0800  /* CHG_END_EINT */
+#define WM831X_CHG_END_EINT_MASK                0x0800  /* CHG_END_EINT */
+#define WM831X_CHG_END_EINT_SHIFT                   11  /* CHG_END_EINT */
+#define WM831X_CHG_END_EINT_WIDTH                    1  /* CHG_END_EINT */
+#define WM831X_CHG_TO_EINT                      0x0400  /* CHG_TO_EINT */
+#define WM831X_CHG_TO_EINT_MASK                 0x0400  /* CHG_TO_EINT */
+#define WM831X_CHG_TO_EINT_SHIFT                    10  /* CHG_TO_EINT */
+#define WM831X_CHG_TO_EINT_WIDTH                     1  /* CHG_TO_EINT */
+#define WM831X_CHG_MODE_EINT                    0x0200  /* CHG_MODE_EINT */
+#define WM831X_CHG_MODE_EINT_MASK               0x0200  /* CHG_MODE_EINT */
+#define WM831X_CHG_MODE_EINT_SHIFT                   9  /* CHG_MODE_EINT */
+#define WM831X_CHG_MODE_EINT_WIDTH                   1  /* CHG_MODE_EINT */
+#define WM831X_CHG_START_EINT                   0x0100  /* CHG_START_EINT */
+#define WM831X_CHG_START_EINT_MASK              0x0100  /* CHG_START_EINT */
+#define WM831X_CHG_START_EINT_SHIFT                  8  /* CHG_START_EINT */
+#define WM831X_CHG_START_EINT_WIDTH                  1  /* CHG_START_EINT */
+#define WM831X_CS2_EINT                         0x0080  /* CS2_EINT */
+#define WM831X_CS2_EINT_MASK                    0x0080  /* CS2_EINT */
+#define WM831X_CS2_EINT_SHIFT                        7  /* CS2_EINT */
+#define WM831X_CS2_EINT_WIDTH                        1  /* CS2_EINT */
+#define WM831X_CS1_EINT                         0x0040  /* CS1_EINT */
+#define WM831X_CS1_EINT_MASK                    0x0040  /* CS1_EINT */
+#define WM831X_CS1_EINT_SHIFT                        6  /* CS1_EINT */
+#define WM831X_CS1_EINT_WIDTH                        1  /* CS1_EINT */
+#define WM831X_OTP_CMD_END_EINT                 0x0020  /* OTP_CMD_END_EINT */
+#define WM831X_OTP_CMD_END_EINT_MASK            0x0020  /* OTP_CMD_END_EINT */
+#define WM831X_OTP_CMD_END_EINT_SHIFT                5  /* OTP_CMD_END_EINT */
+#define WM831X_OTP_CMD_END_EINT_WIDTH                1  /* OTP_CMD_END_EINT */
+#define WM831X_OTP_ERR_EINT                     0x0010  /* OTP_ERR_EINT */
+#define WM831X_OTP_ERR_EINT_MASK                0x0010  /* OTP_ERR_EINT */
+#define WM831X_OTP_ERR_EINT_SHIFT                    4  /* OTP_ERR_EINT */
+#define WM831X_OTP_ERR_EINT_WIDTH                    1  /* OTP_ERR_EINT */
+#define WM831X_PS_POR_EINT                      0x0004  /* PS_POR_EINT */
+#define WM831X_PS_POR_EINT_MASK                 0x0004  /* PS_POR_EINT */
+#define WM831X_PS_POR_EINT_SHIFT                     2  /* PS_POR_EINT */
+#define WM831X_PS_POR_EINT_WIDTH                     1  /* PS_POR_EINT */
+#define WM831X_PS_SLEEP_OFF_EINT                0x0002  /* PS_SLEEP_OFF_EINT */
+#define WM831X_PS_SLEEP_OFF_EINT_MASK           0x0002  /* PS_SLEEP_OFF_EINT */
+#define WM831X_PS_SLEEP_OFF_EINT_SHIFT               1  /* PS_SLEEP_OFF_EINT */
+#define WM831X_PS_SLEEP_OFF_EINT_WIDTH               1  /* PS_SLEEP_OFF_EINT */
+#define WM831X_PS_ON_WAKE_EINT                  0x0001  /* PS_ON_WAKE_EINT */
+#define WM831X_PS_ON_WAKE_EINT_MASK             0x0001  /* PS_ON_WAKE_EINT */
+#define WM831X_PS_ON_WAKE_EINT_SHIFT                 0  /* PS_ON_WAKE_EINT */
+#define WM831X_PS_ON_WAKE_EINT_WIDTH                 1  /* PS_ON_WAKE_EINT */
+
+/*
+ * R16403 (0x4013) - Interrupt Status 3
+ */
+#define WM831X_UV_LDO10_EINT                    0x0200  /* UV_LDO10_EINT */
+#define WM831X_UV_LDO10_EINT_MASK               0x0200  /* UV_LDO10_EINT */
+#define WM831X_UV_LDO10_EINT_SHIFT                   9  /* UV_LDO10_EINT */
+#define WM831X_UV_LDO10_EINT_WIDTH                   1  /* UV_LDO10_EINT */
+#define WM831X_UV_LDO9_EINT                     0x0100  /* UV_LDO9_EINT */
+#define WM831X_UV_LDO9_EINT_MASK                0x0100  /* UV_LDO9_EINT */
+#define WM831X_UV_LDO9_EINT_SHIFT                    8  /* UV_LDO9_EINT */
+#define WM831X_UV_LDO9_EINT_WIDTH                    1  /* UV_LDO9_EINT */
+#define WM831X_UV_LDO8_EINT                     0x0080  /* UV_LDO8_EINT */
+#define WM831X_UV_LDO8_EINT_MASK                0x0080  /* UV_LDO8_EINT */
+#define WM831X_UV_LDO8_EINT_SHIFT                    7  /* UV_LDO8_EINT */
+#define WM831X_UV_LDO8_EINT_WIDTH                    1  /* UV_LDO8_EINT */
+#define WM831X_UV_LDO7_EINT                     0x0040  /* UV_LDO7_EINT */
+#define WM831X_UV_LDO7_EINT_MASK                0x0040  /* UV_LDO7_EINT */
+#define WM831X_UV_LDO7_EINT_SHIFT                    6  /* UV_LDO7_EINT */
+#define WM831X_UV_LDO7_EINT_WIDTH                    1  /* UV_LDO7_EINT */
+#define WM831X_UV_LDO6_EINT                     0x0020  /* UV_LDO6_EINT */
+#define WM831X_UV_LDO6_EINT_MASK                0x0020  /* UV_LDO6_EINT */
+#define WM831X_UV_LDO6_EINT_SHIFT                    5  /* UV_LDO6_EINT */
+#define WM831X_UV_LDO6_EINT_WIDTH                    1  /* UV_LDO6_EINT */
+#define WM831X_UV_LDO5_EINT                     0x0010  /* UV_LDO5_EINT */
+#define WM831X_UV_LDO5_EINT_MASK                0x0010  /* UV_LDO5_EINT */
+#define WM831X_UV_LDO5_EINT_SHIFT                    4  /* UV_LDO5_EINT */
+#define WM831X_UV_LDO5_EINT_WIDTH                    1  /* UV_LDO5_EINT */
+#define WM831X_UV_LDO4_EINT                     0x0008  /* UV_LDO4_EINT */
+#define WM831X_UV_LDO4_EINT_MASK                0x0008  /* UV_LDO4_EINT */
+#define WM831X_UV_LDO4_EINT_SHIFT                    3  /* UV_LDO4_EINT */
+#define WM831X_UV_LDO4_EINT_WIDTH                    1  /* UV_LDO4_EINT */
+#define WM831X_UV_LDO3_EINT                     0x0004  /* UV_LDO3_EINT */
+#define WM831X_UV_LDO3_EINT_MASK                0x0004  /* UV_LDO3_EINT */
+#define WM831X_UV_LDO3_EINT_SHIFT                    2  /* UV_LDO3_EINT */
+#define WM831X_UV_LDO3_EINT_WIDTH                    1  /* UV_LDO3_EINT */
+#define WM831X_UV_LDO2_EINT                     0x0002  /* UV_LDO2_EINT */
+#define WM831X_UV_LDO2_EINT_MASK                0x0002  /* UV_LDO2_EINT */
+#define WM831X_UV_LDO2_EINT_SHIFT                    1  /* UV_LDO2_EINT */
+#define WM831X_UV_LDO2_EINT_WIDTH                    1  /* UV_LDO2_EINT */
+#define WM831X_UV_LDO1_EINT                     0x0001  /* UV_LDO1_EINT */
+#define WM831X_UV_LDO1_EINT_MASK                0x0001  /* UV_LDO1_EINT */
+#define WM831X_UV_LDO1_EINT_SHIFT                    0  /* UV_LDO1_EINT */
+#define WM831X_UV_LDO1_EINT_WIDTH                    1  /* UV_LDO1_EINT */
+
+/*
+ * R16404 (0x4014) - Interrupt Status 4
+ */
+#define WM831X_HC_DC2_EINT                      0x0200  /* HC_DC2_EINT */
+#define WM831X_HC_DC2_EINT_MASK                 0x0200  /* HC_DC2_EINT */
+#define WM831X_HC_DC2_EINT_SHIFT                     9  /* HC_DC2_EINT */
+#define WM831X_HC_DC2_EINT_WIDTH                     1  /* HC_DC2_EINT */
+#define WM831X_HC_DC1_EINT                      0x0100  /* HC_DC1_EINT */
+#define WM831X_HC_DC1_EINT_MASK                 0x0100  /* HC_DC1_EINT */
+#define WM831X_HC_DC1_EINT_SHIFT                     8  /* HC_DC1_EINT */
+#define WM831X_HC_DC1_EINT_WIDTH                     1  /* HC_DC1_EINT */
+#define WM831X_UV_DC4_EINT                      0x0008  /* UV_DC4_EINT */
+#define WM831X_UV_DC4_EINT_MASK                 0x0008  /* UV_DC4_EINT */
+#define WM831X_UV_DC4_EINT_SHIFT                     3  /* UV_DC4_EINT */
+#define WM831X_UV_DC4_EINT_WIDTH                     1  /* UV_DC4_EINT */
+#define WM831X_UV_DC3_EINT                      0x0004  /* UV_DC3_EINT */
+#define WM831X_UV_DC3_EINT_MASK                 0x0004  /* UV_DC3_EINT */
+#define WM831X_UV_DC3_EINT_SHIFT                     2  /* UV_DC3_EINT */
+#define WM831X_UV_DC3_EINT_WIDTH                     1  /* UV_DC3_EINT */
+#define WM831X_UV_DC2_EINT                      0x0002  /* UV_DC2_EINT */
+#define WM831X_UV_DC2_EINT_MASK                 0x0002  /* UV_DC2_EINT */
+#define WM831X_UV_DC2_EINT_SHIFT                     1  /* UV_DC2_EINT */
+#define WM831X_UV_DC2_EINT_WIDTH                     1  /* UV_DC2_EINT */
+#define WM831X_UV_DC1_EINT                      0x0001  /* UV_DC1_EINT */
+#define WM831X_UV_DC1_EINT_MASK                 0x0001  /* UV_DC1_EINT */
+#define WM831X_UV_DC1_EINT_SHIFT                     0  /* UV_DC1_EINT */
+#define WM831X_UV_DC1_EINT_WIDTH                     1  /* UV_DC1_EINT */
+
+/*
+ * R16405 (0x4015) - Interrupt Status 5
+ */
+#define WM831X_GP16_EINT                        0x8000  /* GP16_EINT */
+#define WM831X_GP16_EINT_MASK                   0x8000  /* GP16_EINT */
+#define WM831X_GP16_EINT_SHIFT                      15  /* GP16_EINT */
+#define WM831X_GP16_EINT_WIDTH                       1  /* GP16_EINT */
+#define WM831X_GP15_EINT                        0x4000  /* GP15_EINT */
+#define WM831X_GP15_EINT_MASK                   0x4000  /* GP15_EINT */
+#define WM831X_GP15_EINT_SHIFT                      14  /* GP15_EINT */
+#define WM831X_GP15_EINT_WIDTH                       1  /* GP15_EINT */
+#define WM831X_GP14_EINT                        0x2000  /* GP14_EINT */
+#define WM831X_GP14_EINT_MASK                   0x2000  /* GP14_EINT */
+#define WM831X_GP14_EINT_SHIFT                      13  /* GP14_EINT */
+#define WM831X_GP14_EINT_WIDTH                       1  /* GP14_EINT */
+#define WM831X_GP13_EINT                        0x1000  /* GP13_EINT */
+#define WM831X_GP13_EINT_MASK                   0x1000  /* GP13_EINT */
+#define WM831X_GP13_EINT_SHIFT                      12  /* GP13_EINT */
+#define WM831X_GP13_EINT_WIDTH                       1  /* GP13_EINT */
+#define WM831X_GP12_EINT                        0x0800  /* GP12_EINT */
+#define WM831X_GP12_EINT_MASK                   0x0800  /* GP12_EINT */
+#define WM831X_GP12_EINT_SHIFT                      11  /* GP12_EINT */
+#define WM831X_GP12_EINT_WIDTH                       1  /* GP12_EINT */
+#define WM831X_GP11_EINT                        0x0400  /* GP11_EINT */
+#define WM831X_GP11_EINT_MASK                   0x0400  /* GP11_EINT */
+#define WM831X_GP11_EINT_SHIFT                      10  /* GP11_EINT */
+#define WM831X_GP11_EINT_WIDTH                       1  /* GP11_EINT */
+#define WM831X_GP10_EINT                        0x0200  /* GP10_EINT */
+#define WM831X_GP10_EINT_MASK                   0x0200  /* GP10_EINT */
+#define WM831X_GP10_EINT_SHIFT                       9  /* GP10_EINT */
+#define WM831X_GP10_EINT_WIDTH                       1  /* GP10_EINT */
+#define WM831X_GP9_EINT                         0x0100  /* GP9_EINT */
+#define WM831X_GP9_EINT_MASK                    0x0100  /* GP9_EINT */
+#define WM831X_GP9_EINT_SHIFT                        8  /* GP9_EINT */
+#define WM831X_GP9_EINT_WIDTH                        1  /* GP9_EINT */
+#define WM831X_GP8_EINT                         0x0080  /* GP8_EINT */
+#define WM831X_GP8_EINT_MASK                    0x0080  /* GP8_EINT */
+#define WM831X_GP8_EINT_SHIFT                        7  /* GP8_EINT */
+#define WM831X_GP8_EINT_WIDTH                        1  /* GP8_EINT */
+#define WM831X_GP7_EINT                         0x0040  /* GP7_EINT */
+#define WM831X_GP7_EINT_MASK                    0x0040  /* GP7_EINT */
+#define WM831X_GP7_EINT_SHIFT                        6  /* GP7_EINT */
+#define WM831X_GP7_EINT_WIDTH                        1  /* GP7_EINT */
+#define WM831X_GP6_EINT                         0x0020  /* GP6_EINT */
+#define WM831X_GP6_EINT_MASK                    0x0020  /* GP6_EINT */
+#define WM831X_GP6_EINT_SHIFT                        5  /* GP6_EINT */
+#define WM831X_GP6_EINT_WIDTH                        1  /* GP6_EINT */
+#define WM831X_GP5_EINT                         0x0010  /* GP5_EINT */
+#define WM831X_GP5_EINT_MASK                    0x0010  /* GP5_EINT */
+#define WM831X_GP5_EINT_SHIFT                        4  /* GP5_EINT */
+#define WM831X_GP5_EINT_WIDTH                        1  /* GP5_EINT */
+#define WM831X_GP4_EINT                         0x0008  /* GP4_EINT */
+#define WM831X_GP4_EINT_MASK                    0x0008  /* GP4_EINT */
+#define WM831X_GP4_EINT_SHIFT                        3  /* GP4_EINT */
+#define WM831X_GP4_EINT_WIDTH                        1  /* GP4_EINT */
+#define WM831X_GP3_EINT                         0x0004  /* GP3_EINT */
+#define WM831X_GP3_EINT_MASK                    0x0004  /* GP3_EINT */
+#define WM831X_GP3_EINT_SHIFT                        2  /* GP3_EINT */
+#define WM831X_GP3_EINT_WIDTH                        1  /* GP3_EINT */
+#define WM831X_GP2_EINT                         0x0002  /* GP2_EINT */
+#define WM831X_GP2_EINT_MASK                    0x0002  /* GP2_EINT */
+#define WM831X_GP2_EINT_SHIFT                        1  /* GP2_EINT */
+#define WM831X_GP2_EINT_WIDTH                        1  /* GP2_EINT */
+#define WM831X_GP1_EINT                         0x0001  /* GP1_EINT */
+#define WM831X_GP1_EINT_MASK                    0x0001  /* GP1_EINT */
+#define WM831X_GP1_EINT_SHIFT                        0  /* GP1_EINT */
+#define WM831X_GP1_EINT_WIDTH                        1  /* GP1_EINT */
+
+/*
+ * R16407 (0x4017) - IRQ Config
+ */
+#define WM831X_IRQ_OD                           0x0002  /* IRQ_OD */
+#define WM831X_IRQ_OD_MASK                      0x0002  /* IRQ_OD */
+#define WM831X_IRQ_OD_SHIFT                          1  /* IRQ_OD */
+#define WM831X_IRQ_OD_WIDTH                          1  /* IRQ_OD */
+#define WM831X_IM_IRQ                           0x0001  /* IM_IRQ */
+#define WM831X_IM_IRQ_MASK                      0x0001  /* IM_IRQ */
+#define WM831X_IM_IRQ_SHIFT                          0  /* IM_IRQ */
+#define WM831X_IM_IRQ_WIDTH                          1  /* IM_IRQ */
+
+/*
+ * R16408 (0x4018) - System Interrupts Mask
+ */
+#define WM831X_IM_PS_INT                        0x8000  /* IM_PS_INT */
+#define WM831X_IM_PS_INT_MASK                   0x8000  /* IM_PS_INT */
+#define WM831X_IM_PS_INT_SHIFT                      15  /* IM_PS_INT */
+#define WM831X_IM_PS_INT_WIDTH                       1  /* IM_PS_INT */
+#define WM831X_IM_TEMP_INT                      0x4000  /* IM_TEMP_INT */
+#define WM831X_IM_TEMP_INT_MASK                 0x4000  /* IM_TEMP_INT */
+#define WM831X_IM_TEMP_INT_SHIFT                    14  /* IM_TEMP_INT */
+#define WM831X_IM_TEMP_INT_WIDTH                     1  /* IM_TEMP_INT */
+#define WM831X_IM_GP_INT                        0x2000  /* IM_GP_INT */
+#define WM831X_IM_GP_INT_MASK                   0x2000  /* IM_GP_INT */
+#define WM831X_IM_GP_INT_SHIFT                      13  /* IM_GP_INT */
+#define WM831X_IM_GP_INT_WIDTH                       1  /* IM_GP_INT */
+#define WM831X_IM_ON_PIN_INT                    0x1000  /* IM_ON_PIN_INT */
+#define WM831X_IM_ON_PIN_INT_MASK               0x1000  /* IM_ON_PIN_INT */
+#define WM831X_IM_ON_PIN_INT_SHIFT                  12  /* IM_ON_PIN_INT */
+#define WM831X_IM_ON_PIN_INT_WIDTH                   1  /* IM_ON_PIN_INT */
+#define WM831X_IM_WDOG_INT                      0x0800  /* IM_WDOG_INT */
+#define WM831X_IM_WDOG_INT_MASK                 0x0800  /* IM_WDOG_INT */
+#define WM831X_IM_WDOG_INT_SHIFT                    11  /* IM_WDOG_INT */
+#define WM831X_IM_WDOG_INT_WIDTH                     1  /* IM_WDOG_INT */
+#define WM831X_IM_TCHDATA_INT                   0x0400  /* IM_TCHDATA_INT */
+#define WM831X_IM_TCHDATA_INT_MASK              0x0400  /* IM_TCHDATA_INT */
+#define WM831X_IM_TCHDATA_INT_SHIFT                 10  /* IM_TCHDATA_INT */
+#define WM831X_IM_TCHDATA_INT_WIDTH                  1  /* IM_TCHDATA_INT */
+#define WM831X_IM_TCHPD_INT                     0x0200  /* IM_TCHPD_INT */
+#define WM831X_IM_TCHPD_INT_MASK                0x0200  /* IM_TCHPD_INT */
+#define WM831X_IM_TCHPD_INT_SHIFT                    9  /* IM_TCHPD_INT */
+#define WM831X_IM_TCHPD_INT_WIDTH                    1  /* IM_TCHPD_INT */
+#define WM831X_IM_AUXADC_INT                    0x0100  /* IM_AUXADC_INT */
+#define WM831X_IM_AUXADC_INT_MASK               0x0100  /* IM_AUXADC_INT */
+#define WM831X_IM_AUXADC_INT_SHIFT                   8  /* IM_AUXADC_INT */
+#define WM831X_IM_AUXADC_INT_WIDTH                   1  /* IM_AUXADC_INT */
+#define WM831X_IM_PPM_INT                       0x0080  /* IM_PPM_INT */
+#define WM831X_IM_PPM_INT_MASK                  0x0080  /* IM_PPM_INT */
+#define WM831X_IM_PPM_INT_SHIFT                      7  /* IM_PPM_INT */
+#define WM831X_IM_PPM_INT_WIDTH                      1  /* IM_PPM_INT */
+#define WM831X_IM_CS_INT                        0x0040  /* IM_CS_INT */
+#define WM831X_IM_CS_INT_MASK                   0x0040  /* IM_CS_INT */
+#define WM831X_IM_CS_INT_SHIFT                       6  /* IM_CS_INT */
+#define WM831X_IM_CS_INT_WIDTH                       1  /* IM_CS_INT */
+#define WM831X_IM_RTC_INT                       0x0020  /* IM_RTC_INT */
+#define WM831X_IM_RTC_INT_MASK                  0x0020  /* IM_RTC_INT */
+#define WM831X_IM_RTC_INT_SHIFT                      5  /* IM_RTC_INT */
+#define WM831X_IM_RTC_INT_WIDTH                      1  /* IM_RTC_INT */
+#define WM831X_IM_OTP_INT                       0x0010  /* IM_OTP_INT */
+#define WM831X_IM_OTP_INT_MASK                  0x0010  /* IM_OTP_INT */
+#define WM831X_IM_OTP_INT_SHIFT                      4  /* IM_OTP_INT */
+#define WM831X_IM_OTP_INT_WIDTH                      1  /* IM_OTP_INT */
+#define WM831X_IM_CHILD_INT                     0x0008  /* IM_CHILD_INT */
+#define WM831X_IM_CHILD_INT_MASK                0x0008  /* IM_CHILD_INT */
+#define WM831X_IM_CHILD_INT_SHIFT                    3  /* IM_CHILD_INT */
+#define WM831X_IM_CHILD_INT_WIDTH                    1  /* IM_CHILD_INT */
+#define WM831X_IM_CHG_INT                       0x0004  /* IM_CHG_INT */
+#define WM831X_IM_CHG_INT_MASK                  0x0004  /* IM_CHG_INT */
+#define WM831X_IM_CHG_INT_SHIFT                      2  /* IM_CHG_INT */
+#define WM831X_IM_CHG_INT_WIDTH                      1  /* IM_CHG_INT */
+#define WM831X_IM_HC_INT                        0x0002  /* IM_HC_INT */
+#define WM831X_IM_HC_INT_MASK                   0x0002  /* IM_HC_INT */
+#define WM831X_IM_HC_INT_SHIFT                       1  /* IM_HC_INT */
+#define WM831X_IM_HC_INT_WIDTH                       1  /* IM_HC_INT */
+#define WM831X_IM_UV_INT                        0x0001  /* IM_UV_INT */
+#define WM831X_IM_UV_INT_MASK                   0x0001  /* IM_UV_INT */
+#define WM831X_IM_UV_INT_SHIFT                       0  /* IM_UV_INT */
+#define WM831X_IM_UV_INT_WIDTH                       1  /* IM_UV_INT */
+
+/*
+ * R16409 (0x4019) - Interrupt Status 1 Mask
+ */
+#define WM831X_IM_PPM_SYSLO_EINT                0x8000  /* IM_PPM_SYSLO_EINT */
+#define WM831X_IM_PPM_SYSLO_EINT_MASK           0x8000  /* IM_PPM_SYSLO_EINT */
+#define WM831X_IM_PPM_SYSLO_EINT_SHIFT              15  /* IM_PPM_SYSLO_EINT */
+#define WM831X_IM_PPM_SYSLO_EINT_WIDTH               1  /* IM_PPM_SYSLO_EINT */
+#define WM831X_IM_PPM_PWR_SRC_EINT              0x4000  /* IM_PPM_PWR_SRC_EINT */
+#define WM831X_IM_PPM_PWR_SRC_EINT_MASK         0x4000  /* IM_PPM_PWR_SRC_EINT */
+#define WM831X_IM_PPM_PWR_SRC_EINT_SHIFT            14  /* IM_PPM_PWR_SRC_EINT */
+#define WM831X_IM_PPM_PWR_SRC_EINT_WIDTH             1  /* IM_PPM_PWR_SRC_EINT */
+#define WM831X_IM_PPM_USB_CURR_EINT             0x2000  /* IM_PPM_USB_CURR_EINT */
+#define WM831X_IM_PPM_USB_CURR_EINT_MASK        0x2000  /* IM_PPM_USB_CURR_EINT */
+#define WM831X_IM_PPM_USB_CURR_EINT_SHIFT           13  /* IM_PPM_USB_CURR_EINT */
+#define WM831X_IM_PPM_USB_CURR_EINT_WIDTH            1  /* IM_PPM_USB_CURR_EINT */
+#define WM831X_IM_ON_PIN_EINT                   0x1000  /* IM_ON_PIN_EINT */
+#define WM831X_IM_ON_PIN_EINT_MASK              0x1000  /* IM_ON_PIN_EINT */
+#define WM831X_IM_ON_PIN_EINT_SHIFT                 12  /* IM_ON_PIN_EINT */
+#define WM831X_IM_ON_PIN_EINT_WIDTH                  1  /* IM_ON_PIN_EINT */
+#define WM831X_IM_WDOG_TO_EINT                  0x0800  /* IM_WDOG_TO_EINT */
+#define WM831X_IM_WDOG_TO_EINT_MASK             0x0800  /* IM_WDOG_TO_EINT */
+#define WM831X_IM_WDOG_TO_EINT_SHIFT                11  /* IM_WDOG_TO_EINT */
+#define WM831X_IM_WDOG_TO_EINT_WIDTH                 1  /* IM_WDOG_TO_EINT */
+#define WM831X_IM_TCHDATA_EINT                  0x0400  /* IM_TCHDATA_EINT */
+#define WM831X_IM_TCHDATA_EINT_MASK             0x0400  /* IM_TCHDATA_EINT */
+#define WM831X_IM_TCHDATA_EINT_SHIFT                10  /* IM_TCHDATA_EINT */
+#define WM831X_IM_TCHDATA_EINT_WIDTH                 1  /* IM_TCHDATA_EINT */
+#define WM831X_IM_TCHPD_EINT                    0x0200  /* IM_TCHPD_EINT */
+#define WM831X_IM_TCHPD_EINT_MASK               0x0200  /* IM_TCHPD_EINT */
+#define WM831X_IM_TCHPD_EINT_SHIFT                   9  /* IM_TCHPD_EINT */
+#define WM831X_IM_TCHPD_EINT_WIDTH                   1  /* IM_TCHPD_EINT */
+#define WM831X_IM_AUXADC_DATA_EINT              0x0100  /* IM_AUXADC_DATA_EINT */
+#define WM831X_IM_AUXADC_DATA_EINT_MASK         0x0100  /* IM_AUXADC_DATA_EINT */
+#define WM831X_IM_AUXADC_DATA_EINT_SHIFT             8  /* IM_AUXADC_DATA_EINT */
+#define WM831X_IM_AUXADC_DATA_EINT_WIDTH             1  /* IM_AUXADC_DATA_EINT */
+#define WM831X_IM_AUXADC_DCOMP4_EINT            0x0080  /* IM_AUXADC_DCOMP4_EINT */
+#define WM831X_IM_AUXADC_DCOMP4_EINT_MASK       0x0080  /* IM_AUXADC_DCOMP4_EINT */
+#define WM831X_IM_AUXADC_DCOMP4_EINT_SHIFT           7  /* IM_AUXADC_DCOMP4_EINT */
+#define WM831X_IM_AUXADC_DCOMP4_EINT_WIDTH           1  /* IM_AUXADC_DCOMP4_EINT */
+#define WM831X_IM_AUXADC_DCOMP3_EINT            0x0040  /* IM_AUXADC_DCOMP3_EINT */
+#define WM831X_IM_AUXADC_DCOMP3_EINT_MASK       0x0040  /* IM_AUXADC_DCOMP3_EINT */
+#define WM831X_IM_AUXADC_DCOMP3_EINT_SHIFT           6  /* IM_AUXADC_DCOMP3_EINT */
+#define WM831X_IM_AUXADC_DCOMP3_EINT_WIDTH           1  /* IM_AUXADC_DCOMP3_EINT */
+#define WM831X_IM_AUXADC_DCOMP2_EINT            0x0020  /* IM_AUXADC_DCOMP2_EINT */
+#define WM831X_IM_AUXADC_DCOMP2_EINT_MASK       0x0020  /* IM_AUXADC_DCOMP2_EINT */
+#define WM831X_IM_AUXADC_DCOMP2_EINT_SHIFT           5  /* IM_AUXADC_DCOMP2_EINT */
+#define WM831X_IM_AUXADC_DCOMP2_EINT_WIDTH           1  /* IM_AUXADC_DCOMP2_EINT */
+#define WM831X_IM_AUXADC_DCOMP1_EINT            0x0010  /* IM_AUXADC_DCOMP1_EINT */
+#define WM831X_IM_AUXADC_DCOMP1_EINT_MASK       0x0010  /* IM_AUXADC_DCOMP1_EINT */
+#define WM831X_IM_AUXADC_DCOMP1_EINT_SHIFT           4  /* IM_AUXADC_DCOMP1_EINT */
+#define WM831X_IM_AUXADC_DCOMP1_EINT_WIDTH           1  /* IM_AUXADC_DCOMP1_EINT */
+#define WM831X_IM_RTC_PER_EINT                  0x0008  /* IM_RTC_PER_EINT */
+#define WM831X_IM_RTC_PER_EINT_MASK             0x0008  /* IM_RTC_PER_EINT */
+#define WM831X_IM_RTC_PER_EINT_SHIFT                 3  /* IM_RTC_PER_EINT */
+#define WM831X_IM_RTC_PER_EINT_WIDTH                 1  /* IM_RTC_PER_EINT */
+#define WM831X_IM_RTC_ALM_EINT                  0x0004  /* IM_RTC_ALM_EINT */
+#define WM831X_IM_RTC_ALM_EINT_MASK             0x0004  /* IM_RTC_ALM_EINT */
+#define WM831X_IM_RTC_ALM_EINT_SHIFT                 2  /* IM_RTC_ALM_EINT */
+#define WM831X_IM_RTC_ALM_EINT_WIDTH                 1  /* IM_RTC_ALM_EINT */
+#define WM831X_IM_TEMP_THW_EINT                 0x0002  /* IM_TEMP_THW_EINT */
+#define WM831X_IM_TEMP_THW_EINT_MASK            0x0002  /* IM_TEMP_THW_EINT */
+#define WM831X_IM_TEMP_THW_EINT_SHIFT                1  /* IM_TEMP_THW_EINT */
+#define WM831X_IM_TEMP_THW_EINT_WIDTH                1  /* IM_TEMP_THW_EINT */
+
+/*
+ * R16410 (0x401A) - Interrupt Status 2 Mask
+ */
+#define WM831X_IM_CHG_BATT_HOT_EINT             0x8000  /* IM_CHG_BATT_HOT_EINT */
+#define WM831X_IM_CHG_BATT_HOT_EINT_MASK        0x8000  /* IM_CHG_BATT_HOT_EINT */
+#define WM831X_IM_CHG_BATT_HOT_EINT_SHIFT           15  /* IM_CHG_BATT_HOT_EINT */
+#define WM831X_IM_CHG_BATT_HOT_EINT_WIDTH            1  /* IM_CHG_BATT_HOT_EINT */
+#define WM831X_IM_CHG_BATT_COLD_EINT            0x4000  /* IM_CHG_BATT_COLD_EINT */
+#define WM831X_IM_CHG_BATT_COLD_EINT_MASK       0x4000  /* IM_CHG_BATT_COLD_EINT */
+#define WM831X_IM_CHG_BATT_COLD_EINT_SHIFT          14  /* IM_CHG_BATT_COLD_EINT */
+#define WM831X_IM_CHG_BATT_COLD_EINT_WIDTH           1  /* IM_CHG_BATT_COLD_EINT */
+#define WM831X_IM_CHG_BATT_FAIL_EINT            0x2000  /* IM_CHG_BATT_FAIL_EINT */
+#define WM831X_IM_CHG_BATT_FAIL_EINT_MASK       0x2000  /* IM_CHG_BATT_FAIL_EINT */
+#define WM831X_IM_CHG_BATT_FAIL_EINT_SHIFT          13  /* IM_CHG_BATT_FAIL_EINT */
+#define WM831X_IM_CHG_BATT_FAIL_EINT_WIDTH           1  /* IM_CHG_BATT_FAIL_EINT */
+#define WM831X_IM_CHG_OV_EINT                   0x1000  /* IM_CHG_OV_EINT */
+#define WM831X_IM_CHG_OV_EINT_MASK              0x1000  /* IM_CHG_OV_EINT */
+#define WM831X_IM_CHG_OV_EINT_SHIFT                 12  /* IM_CHG_OV_EINT */
+#define WM831X_IM_CHG_OV_EINT_WIDTH                  1  /* IM_CHG_OV_EINT */
+#define WM831X_IM_CHG_END_EINT                  0x0800  /* IM_CHG_END_EINT */
+#define WM831X_IM_CHG_END_EINT_MASK             0x0800  /* IM_CHG_END_EINT */
+#define WM831X_IM_CHG_END_EINT_SHIFT                11  /* IM_CHG_END_EINT */
+#define WM831X_IM_CHG_END_EINT_WIDTH                 1  /* IM_CHG_END_EINT */
+#define WM831X_IM_CHG_TO_EINT                   0x0400  /* IM_CHG_TO_EINT */
+#define WM831X_IM_CHG_TO_EINT_MASK              0x0400  /* IM_CHG_TO_EINT */
+#define WM831X_IM_CHG_TO_EINT_SHIFT                 10  /* IM_CHG_TO_EINT */
+#define WM831X_IM_CHG_TO_EINT_WIDTH                  1  /* IM_CHG_TO_EINT */
+#define WM831X_IM_CHG_MODE_EINT                 0x0200  /* IM_CHG_MODE_EINT */
+#define WM831X_IM_CHG_MODE_EINT_MASK            0x0200  /* IM_CHG_MODE_EINT */
+#define WM831X_IM_CHG_MODE_EINT_SHIFT                9  /* IM_CHG_MODE_EINT */
+#define WM831X_IM_CHG_MODE_EINT_WIDTH                1  /* IM_CHG_MODE_EINT */
+#define WM831X_IM_CHG_START_EINT                0x0100  /* IM_CHG_START_EINT */
+#define WM831X_IM_CHG_START_EINT_MASK           0x0100  /* IM_CHG_START_EINT */
+#define WM831X_IM_CHG_START_EINT_SHIFT               8  /* IM_CHG_START_EINT */
+#define WM831X_IM_CHG_START_EINT_WIDTH               1  /* IM_CHG_START_EINT */
+#define WM831X_IM_CS2_EINT                      0x0080  /* IM_CS2_EINT */
+#define WM831X_IM_CS2_EINT_MASK                 0x0080  /* IM_CS2_EINT */
+#define WM831X_IM_CS2_EINT_SHIFT                     7  /* IM_CS2_EINT */
+#define WM831X_IM_CS2_EINT_WIDTH                     1  /* IM_CS2_EINT */
+#define WM831X_IM_CS1_EINT                      0x0040  /* IM_CS1_EINT */
+#define WM831X_IM_CS1_EINT_MASK                 0x0040  /* IM_CS1_EINT */
+#define WM831X_IM_CS1_EINT_SHIFT                     6  /* IM_CS1_EINT */
+#define WM831X_IM_CS1_EINT_WIDTH                     1  /* IM_CS1_EINT */
+#define WM831X_IM_OTP_CMD_END_EINT              0x0020  /* IM_OTP_CMD_END_EINT */
+#define WM831X_IM_OTP_CMD_END_EINT_MASK         0x0020  /* IM_OTP_CMD_END_EINT */
+#define WM831X_IM_OTP_CMD_END_EINT_SHIFT             5  /* IM_OTP_CMD_END_EINT */
+#define WM831X_IM_OTP_CMD_END_EINT_WIDTH             1  /* IM_OTP_CMD_END_EINT */
+#define WM831X_IM_OTP_ERR_EINT                  0x0010  /* IM_OTP_ERR_EINT */
+#define WM831X_IM_OTP_ERR_EINT_MASK             0x0010  /* IM_OTP_ERR_EINT */
+#define WM831X_IM_OTP_ERR_EINT_SHIFT                 4  /* IM_OTP_ERR_EINT */
+#define WM831X_IM_OTP_ERR_EINT_WIDTH                 1  /* IM_OTP_ERR_EINT */
+#define WM831X_IM_PS_POR_EINT                   0x0004  /* IM_PS_POR_EINT */
+#define WM831X_IM_PS_POR_EINT_MASK              0x0004  /* IM_PS_POR_EINT */
+#define WM831X_IM_PS_POR_EINT_SHIFT                  2  /* IM_PS_POR_EINT */
+#define WM831X_IM_PS_POR_EINT_WIDTH                  1  /* IM_PS_POR_EINT */
+#define WM831X_IM_PS_SLEEP_OFF_EINT             0x0002  /* IM_PS_SLEEP_OFF_EINT */
+#define WM831X_IM_PS_SLEEP_OFF_EINT_MASK        0x0002  /* IM_PS_SLEEP_OFF_EINT */
+#define WM831X_IM_PS_SLEEP_OFF_EINT_SHIFT            1  /* IM_PS_SLEEP_OFF_EINT */
+#define WM831X_IM_PS_SLEEP_OFF_EINT_WIDTH            1  /* IM_PS_SLEEP_OFF_EINT */
+#define WM831X_IM_PS_ON_WAKE_EINT               0x0001  /* IM_PS_ON_WAKE_EINT */
+#define WM831X_IM_PS_ON_WAKE_EINT_MASK          0x0001  /* IM_PS_ON_WAKE_EINT */
+#define WM831X_IM_PS_ON_WAKE_EINT_SHIFT              0  /* IM_PS_ON_WAKE_EINT */
+#define WM831X_IM_PS_ON_WAKE_EINT_WIDTH              1  /* IM_PS_ON_WAKE_EINT */
+
+/*
+ * R16411 (0x401B) - Interrupt Status 3 Mask
+ */
+#define WM831X_IM_UV_LDO10_EINT                 0x0200  /* IM_UV_LDO10_EINT */
+#define WM831X_IM_UV_LDO10_EINT_MASK            0x0200  /* IM_UV_LDO10_EINT */
+#define WM831X_IM_UV_LDO10_EINT_SHIFT                9  /* IM_UV_LDO10_EINT */
+#define WM831X_IM_UV_LDO10_EINT_WIDTH                1  /* IM_UV_LDO10_EINT */
+#define WM831X_IM_UV_LDO9_EINT                  0x0100  /* IM_UV_LDO9_EINT */
+#define WM831X_IM_UV_LDO9_EINT_MASK             0x0100  /* IM_UV_LDO9_EINT */
+#define WM831X_IM_UV_LDO9_EINT_SHIFT                 8  /* IM_UV_LDO9_EINT */
+#define WM831X_IM_UV_LDO9_EINT_WIDTH                 1  /* IM_UV_LDO9_EINT */
+#define WM831X_IM_UV_LDO8_EINT                  0x0080  /* IM_UV_LDO8_EINT */
+#define WM831X_IM_UV_LDO8_EINT_MASK             0x0080  /* IM_UV_LDO8_EINT */
+#define WM831X_IM_UV_LDO8_EINT_SHIFT                 7  /* IM_UV_LDO8_EINT */
+#define WM831X_IM_UV_LDO8_EINT_WIDTH                 1  /* IM_UV_LDO8_EINT */
+#define WM831X_IM_UV_LDO7_EINT                  0x0040  /* IM_UV_LDO7_EINT */
+#define WM831X_IM_UV_LDO7_EINT_MASK             0x0040  /* IM_UV_LDO7_EINT */
+#define WM831X_IM_UV_LDO7_EINT_SHIFT                 6  /* IM_UV_LDO7_EINT */
+#define WM831X_IM_UV_LDO7_EINT_WIDTH                 1  /* IM_UV_LDO7_EINT */
+#define WM831X_IM_UV_LDO6_EINT                  0x0020  /* IM_UV_LDO6_EINT */
+#define WM831X_IM_UV_LDO6_EINT_MASK             0x0020  /* IM_UV_LDO6_EINT */
+#define WM831X_IM_UV_LDO6_EINT_SHIFT                 5  /* IM_UV_LDO6_EINT */
+#define WM831X_IM_UV_LDO6_EINT_WIDTH                 1  /* IM_UV_LDO6_EINT */
+#define WM831X_IM_UV_LDO5_EINT                  0x0010  /* IM_UV_LDO5_EINT */
+#define WM831X_IM_UV_LDO5_EINT_MASK             0x0010  /* IM_UV_LDO5_EINT */
+#define WM831X_IM_UV_LDO5_EINT_SHIFT                 4  /* IM_UV_LDO5_EINT */
+#define WM831X_IM_UV_LDO5_EINT_WIDTH                 1  /* IM_UV_LDO5_EINT */
+#define WM831X_IM_UV_LDO4_EINT                  0x0008  /* IM_UV_LDO4_EINT */
+#define WM831X_IM_UV_LDO4_EINT_MASK             0x0008  /* IM_UV_LDO4_EINT */
+#define WM831X_IM_UV_LDO4_EINT_SHIFT                 3  /* IM_UV_LDO4_EINT */
+#define WM831X_IM_UV_LDO4_EINT_WIDTH                 1  /* IM_UV_LDO4_EINT */
+#define WM831X_IM_UV_LDO3_EINT                  0x0004  /* IM_UV_LDO3_EINT */
+#define WM831X_IM_UV_LDO3_EINT_MASK             0x0004  /* IM_UV_LDO3_EINT */
+#define WM831X_IM_UV_LDO3_EINT_SHIFT                 2  /* IM_UV_LDO3_EINT */
+#define WM831X_IM_UV_LDO3_EINT_WIDTH                 1  /* IM_UV_LDO3_EINT */
+#define WM831X_IM_UV_LDO2_EINT                  0x0002  /* IM_UV_LDO2_EINT */
+#define WM831X_IM_UV_LDO2_EINT_MASK             0x0002  /* IM_UV_LDO2_EINT */
+#define WM831X_IM_UV_LDO2_EINT_SHIFT                 1  /* IM_UV_LDO2_EINT */
+#define WM831X_IM_UV_LDO2_EINT_WIDTH                 1  /* IM_UV_LDO2_EINT */
+#define WM831X_IM_UV_LDO1_EINT                  0x0001  /* IM_UV_LDO1_EINT */
+#define WM831X_IM_UV_LDO1_EINT_MASK             0x0001  /* IM_UV_LDO1_EINT */
+#define WM831X_IM_UV_LDO1_EINT_SHIFT                 0  /* IM_UV_LDO1_EINT */
+#define WM831X_IM_UV_LDO1_EINT_WIDTH                 1  /* IM_UV_LDO1_EINT */
+
+/*
+ * R16412 (0x401C) - Interrupt Status 4 Mask
+ */
+#define WM831X_IM_HC_DC2_EINT                   0x0200  /* IM_HC_DC2_EINT */
+#define WM831X_IM_HC_DC2_EINT_MASK              0x0200  /* IM_HC_DC2_EINT */
+#define WM831X_IM_HC_DC2_EINT_SHIFT                  9  /* IM_HC_DC2_EINT */
+#define WM831X_IM_HC_DC2_EINT_WIDTH                  1  /* IM_HC_DC2_EINT */
+#define WM831X_IM_HC_DC1_EINT                   0x0100  /* IM_HC_DC1_EINT */
+#define WM831X_IM_HC_DC1_EINT_MASK              0x0100  /* IM_HC_DC1_EINT */
+#define WM831X_IM_HC_DC1_EINT_SHIFT                  8  /* IM_HC_DC1_EINT */
+#define WM831X_IM_HC_DC1_EINT_WIDTH                  1  /* IM_HC_DC1_EINT */
+#define WM831X_IM_UV_DC4_EINT                   0x0008  /* IM_UV_DC4_EINT */
+#define WM831X_IM_UV_DC4_EINT_MASK              0x0008  /* IM_UV_DC4_EINT */
+#define WM831X_IM_UV_DC4_EINT_SHIFT                  3  /* IM_UV_DC4_EINT */
+#define WM831X_IM_UV_DC4_EINT_WIDTH                  1  /* IM_UV_DC4_EINT */
+#define WM831X_IM_UV_DC3_EINT                   0x0004  /* IM_UV_DC3_EINT */
+#define WM831X_IM_UV_DC3_EINT_MASK              0x0004  /* IM_UV_DC3_EINT */
+#define WM831X_IM_UV_DC3_EINT_SHIFT                  2  /* IM_UV_DC3_EINT */
+#define WM831X_IM_UV_DC3_EINT_WIDTH                  1  /* IM_UV_DC3_EINT */
+#define WM831X_IM_UV_DC2_EINT                   0x0002  /* IM_UV_DC2_EINT */
+#define WM831X_IM_UV_DC2_EINT_MASK              0x0002  /* IM_UV_DC2_EINT */
+#define WM831X_IM_UV_DC2_EINT_SHIFT                  1  /* IM_UV_DC2_EINT */
+#define WM831X_IM_UV_DC2_EINT_WIDTH                  1  /* IM_UV_DC2_EINT */
+#define WM831X_IM_UV_DC1_EINT                   0x0001  /* IM_UV_DC1_EINT */
+#define WM831X_IM_UV_DC1_EINT_MASK              0x0001  /* IM_UV_DC1_EINT */
+#define WM831X_IM_UV_DC1_EINT_SHIFT                  0  /* IM_UV_DC1_EINT */
+#define WM831X_IM_UV_DC1_EINT_WIDTH                  1  /* IM_UV_DC1_EINT */
+
+/*
+ * R16413 (0x401D) - Interrupt Status 5 Mask
+ */
+#define WM831X_IM_GP16_EINT                     0x8000  /* IM_GP16_EINT */
+#define WM831X_IM_GP16_EINT_MASK                0x8000  /* IM_GP16_EINT */
+#define WM831X_IM_GP16_EINT_SHIFT                   15  /* IM_GP16_EINT */
+#define WM831X_IM_GP16_EINT_WIDTH                    1  /* IM_GP16_EINT */
+#define WM831X_IM_GP15_EINT                     0x4000  /* IM_GP15_EINT */
+#define WM831X_IM_GP15_EINT_MASK                0x4000  /* IM_GP15_EINT */
+#define WM831X_IM_GP15_EINT_SHIFT                   14  /* IM_GP15_EINT */
+#define WM831X_IM_GP15_EINT_WIDTH                    1  /* IM_GP15_EINT */
+#define WM831X_IM_GP14_EINT                     0x2000  /* IM_GP14_EINT */
+#define WM831X_IM_GP14_EINT_MASK                0x2000  /* IM_GP14_EINT */
+#define WM831X_IM_GP14_EINT_SHIFT                   13  /* IM_GP14_EINT */
+#define WM831X_IM_GP14_EINT_WIDTH                    1  /* IM_GP14_EINT */
+#define WM831X_IM_GP13_EINT                     0x1000  /* IM_GP13_EINT */
+#define WM831X_IM_GP13_EINT_MASK                0x1000  /* IM_GP13_EINT */
+#define WM831X_IM_GP13_EINT_SHIFT                   12  /* IM_GP13_EINT */
+#define WM831X_IM_GP13_EINT_WIDTH                    1  /* IM_GP13_EINT */
+#define WM831X_IM_GP12_EINT                     0x0800  /* IM_GP12_EINT */
+#define WM831X_IM_GP12_EINT_MASK                0x0800  /* IM_GP12_EINT */
+#define WM831X_IM_GP12_EINT_SHIFT                   11  /* IM_GP12_EINT */
+#define WM831X_IM_GP12_EINT_WIDTH                    1  /* IM_GP12_EINT */
+#define WM831X_IM_GP11_EINT                     0x0400  /* IM_GP11_EINT */
+#define WM831X_IM_GP11_EINT_MASK                0x0400  /* IM_GP11_EINT */
+#define WM831X_IM_GP11_EINT_SHIFT                   10  /* IM_GP11_EINT */
+#define WM831X_IM_GP11_EINT_WIDTH                    1  /* IM_GP11_EINT */
+#define WM831X_IM_GP10_EINT                     0x0200  /* IM_GP10_EINT */
+#define WM831X_IM_GP10_EINT_MASK                0x0200  /* IM_GP10_EINT */
+#define WM831X_IM_GP10_EINT_SHIFT                    9  /* IM_GP10_EINT */
+#define WM831X_IM_GP10_EINT_WIDTH                    1  /* IM_GP10_EINT */
+#define WM831X_IM_GP9_EINT                      0x0100  /* IM_GP9_EINT */
+#define WM831X_IM_GP9_EINT_MASK                 0x0100  /* IM_GP9_EINT */
+#define WM831X_IM_GP9_EINT_SHIFT                     8  /* IM_GP9_EINT */
+#define WM831X_IM_GP9_EINT_WIDTH                     1  /* IM_GP9_EINT */
+#define WM831X_IM_GP8_EINT                      0x0080  /* IM_GP8_EINT */
+#define WM831X_IM_GP8_EINT_MASK                 0x0080  /* IM_GP8_EINT */
+#define WM831X_IM_GP8_EINT_SHIFT                     7  /* IM_GP8_EINT */
+#define WM831X_IM_GP8_EINT_WIDTH                     1  /* IM_GP8_EINT */
+#define WM831X_IM_GP7_EINT                      0x0040  /* IM_GP7_EINT */
+#define WM831X_IM_GP7_EINT_MASK                 0x0040  /* IM_GP7_EINT */
+#define WM831X_IM_GP7_EINT_SHIFT                     6  /* IM_GP7_EINT */
+#define WM831X_IM_GP7_EINT_WIDTH                     1  /* IM_GP7_EINT */
+#define WM831X_IM_GP6_EINT                      0x0020  /* IM_GP6_EINT */
+#define WM831X_IM_GP6_EINT_MASK                 0x0020  /* IM_GP6_EINT */
+#define WM831X_IM_GP6_EINT_SHIFT                     5  /* IM_GP6_EINT */
+#define WM831X_IM_GP6_EINT_WIDTH                     1  /* IM_GP6_EINT */
+#define WM831X_IM_GP5_EINT                      0x0010  /* IM_GP5_EINT */
+#define WM831X_IM_GP5_EINT_MASK                 0x0010  /* IM_GP5_EINT */
+#define WM831X_IM_GP5_EINT_SHIFT                     4  /* IM_GP5_EINT */
+#define WM831X_IM_GP5_EINT_WIDTH                     1  /* IM_GP5_EINT */
+#define WM831X_IM_GP4_EINT                      0x0008  /* IM_GP4_EINT */
+#define WM831X_IM_GP4_EINT_MASK                 0x0008  /* IM_GP4_EINT */
+#define WM831X_IM_GP4_EINT_SHIFT                     3  /* IM_GP4_EINT */
+#define WM831X_IM_GP4_EINT_WIDTH                     1  /* IM_GP4_EINT */
+#define WM831X_IM_GP3_EINT                      0x0004  /* IM_GP3_EINT */
+#define WM831X_IM_GP3_EINT_MASK                 0x0004  /* IM_GP3_EINT */
+#define WM831X_IM_GP3_EINT_SHIFT                     2  /* IM_GP3_EINT */
+#define WM831X_IM_GP3_EINT_WIDTH                     1  /* IM_GP3_EINT */
+#define WM831X_IM_GP2_EINT                      0x0002  /* IM_GP2_EINT */
+#define WM831X_IM_GP2_EINT_MASK                 0x0002  /* IM_GP2_EINT */
+#define WM831X_IM_GP2_EINT_SHIFT                     1  /* IM_GP2_EINT */
+#define WM831X_IM_GP2_EINT_WIDTH                     1  /* IM_GP2_EINT */
+#define WM831X_IM_GP1_EINT                      0x0001  /* IM_GP1_EINT */
+#define WM831X_IM_GP1_EINT_MASK                 0x0001  /* IM_GP1_EINT */
+#define WM831X_IM_GP1_EINT_SHIFT                     0  /* IM_GP1_EINT */
+#define WM831X_IM_GP1_EINT_WIDTH                     1  /* IM_GP1_EINT */
+
+
+#endif
diff --git a/include/linux/mfd/wm831x/otp.h b/include/linux/mfd/wm831x/otp.h
new file mode 100644
index 0000000..ce1f81a
--- /dev/null
+++ b/include/linux/mfd/wm831x/otp.h
@@ -0,0 +1,162 @@
+/*
+ * include/linux/mfd/wm831x/otp.h -- OTP interface for WM831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_OTP_H__
+#define __MFD_WM831X_OTP_H__
+
+int wm831x_otp_init(struct wm831x *wm831x);
+void wm831x_otp_exit(struct wm831x *wm831x);
+
+/*
+ * R30720 (0x7800) - Unique ID 1
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30721 (0x7801) - Unique ID 2
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30722 (0x7802) - Unique ID 3
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30723 (0x7803) - Unique ID 4
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30724 (0x7804) - Unique ID 5
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30725 (0x7805) - Unique ID 6
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30726 (0x7806) - Unique ID 7
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30727 (0x7807) - Unique ID 8
+ */
+#define WM831X_UNIQUE_ID_MASK                   0xFFFF  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_SHIFT                       0  /* UNIQUE_ID - [15:0] */
+#define WM831X_UNIQUE_ID_WIDTH                      16  /* UNIQUE_ID - [15:0] */
+
+/*
+ * R30728 (0x7808) - Factory OTP ID
+ */
+#define WM831X_OTP_FACT_ID_MASK                 0xFFFE  /* OTP_FACT_ID - [15:1] */
+#define WM831X_OTP_FACT_ID_SHIFT                     1  /* OTP_FACT_ID - [15:1] */
+#define WM831X_OTP_FACT_ID_WIDTH                    15  /* OTP_FACT_ID - [15:1] */
+#define WM831X_OTP_FACT_FINAL                   0x0001  /* OTP_FACT_FINAL */
+#define WM831X_OTP_FACT_FINAL_MASK              0x0001  /* OTP_FACT_FINAL */
+#define WM831X_OTP_FACT_FINAL_SHIFT                  0  /* OTP_FACT_FINAL */
+#define WM831X_OTP_FACT_FINAL_WIDTH                  1  /* OTP_FACT_FINAL */
+
+/*
+ * R30729 (0x7809) - Factory OTP 1
+ */
+#define WM831X_DC3_TRIM_MASK                    0xF000  /* DC3_TRIM - [15:12] */
+#define WM831X_DC3_TRIM_SHIFT                       12  /* DC3_TRIM - [15:12] */
+#define WM831X_DC3_TRIM_WIDTH                        4  /* DC3_TRIM - [15:12] */
+#define WM831X_DC2_TRIM_MASK                    0x0FC0  /* DC2_TRIM - [11:6] */
+#define WM831X_DC2_TRIM_SHIFT                        6  /* DC2_TRIM - [11:6] */
+#define WM831X_DC2_TRIM_WIDTH                        6  /* DC2_TRIM - [11:6] */
+#define WM831X_DC1_TRIM_MASK                    0x003F  /* DC1_TRIM - [5:0] */
+#define WM831X_DC1_TRIM_SHIFT                        0  /* DC1_TRIM - [5:0] */
+#define WM831X_DC1_TRIM_WIDTH                        6  /* DC1_TRIM - [5:0] */
+
+/*
+ * R30730 (0x780A) - Factory OTP 2
+ */
+#define WM831X_CHIP_ID_MASK                     0xFFFF  /* CHIP_ID - [15:0] */
+#define WM831X_CHIP_ID_SHIFT                         0  /* CHIP_ID - [15:0] */
+#define WM831X_CHIP_ID_WIDTH                        16  /* CHIP_ID - [15:0] */
+
+/*
+ * R30731 (0x780B) - Factory OTP 3
+ */
+#define WM831X_OSC_TRIM_MASK                    0x0780  /* OSC_TRIM - [10:7] */
+#define WM831X_OSC_TRIM_SHIFT                        7  /* OSC_TRIM - [10:7] */
+#define WM831X_OSC_TRIM_WIDTH                        4  /* OSC_TRIM - [10:7] */
+#define WM831X_BG_TRIM_MASK                     0x0078  /* BG_TRIM - [6:3] */
+#define WM831X_BG_TRIM_SHIFT                         3  /* BG_TRIM - [6:3] */
+#define WM831X_BG_TRIM_WIDTH                         4  /* BG_TRIM - [6:3] */
+#define WM831X_LPBG_TRIM_MASK                   0x0007  /* LPBG_TRIM - [2:0] */
+#define WM831X_LPBG_TRIM_SHIFT                       0  /* LPBG_TRIM - [2:0] */
+#define WM831X_LPBG_TRIM_WIDTH                       3  /* LPBG_TRIM - [2:0] */
+
+/*
+ * R30732 (0x780C) - Factory OTP 4
+ */
+#define WM831X_CHILD_I2C_ADDR_MASK              0x00FE  /* CHILD_I2C_ADDR - [7:1] */
+#define WM831X_CHILD_I2C_ADDR_SHIFT                  1  /* CHILD_I2C_ADDR - [7:1] */
+#define WM831X_CHILD_I2C_ADDR_WIDTH                  7  /* CHILD_I2C_ADDR - [7:1] */
+#define WM831X_CH_AW                            0x0001  /* CH_AW */
+#define WM831X_CH_AW_MASK                       0x0001  /* CH_AW */
+#define WM831X_CH_AW_SHIFT                           0  /* CH_AW */
+#define WM831X_CH_AW_WIDTH                           1  /* CH_AW */
+
+/*
+ * R30733 (0x780D) - Factory OTP 5
+ */
+#define WM831X_CHARGE_TRIM_MASK                 0x003F  /* CHARGE_TRIM - [5:0] */
+#define WM831X_CHARGE_TRIM_SHIFT                     0  /* CHARGE_TRIM - [5:0] */
+#define WM831X_CHARGE_TRIM_WIDTH                     6  /* CHARGE_TRIM - [5:0] */
+
+/*
+ * R30736 (0x7810) - Customer OTP ID
+ */
+#define WM831X_OTP_AUTO_PROG                    0x8000  /* OTP_AUTO_PROG */
+#define WM831X_OTP_AUTO_PROG_MASK               0x8000  /* OTP_AUTO_PROG */
+#define WM831X_OTP_AUTO_PROG_SHIFT                  15  /* OTP_AUTO_PROG */
+#define WM831X_OTP_AUTO_PROG_WIDTH                   1  /* OTP_AUTO_PROG */
+#define WM831X_OTP_CUST_ID_MASK                 0x7FFE  /* OTP_CUST_ID - [14:1] */
+#define WM831X_OTP_CUST_ID_SHIFT                     1  /* OTP_CUST_ID - [14:1] */
+#define WM831X_OTP_CUST_ID_WIDTH                    14  /* OTP_CUST_ID - [14:1] */
+#define WM831X_OTP_CUST_FINAL                   0x0001  /* OTP_CUST_FINAL */
+#define WM831X_OTP_CUST_FINAL_MASK              0x0001  /* OTP_CUST_FINAL */
+#define WM831X_OTP_CUST_FINAL_SHIFT                  0  /* OTP_CUST_FINAL */
+#define WM831X_OTP_CUST_FINAL_WIDTH                  1  /* OTP_CUST_FINAL */
+
+/*
+ * R30759 (0x7827) - DBE CHECK DATA
+ */
+#define WM831X_DBE_VALID_DATA_MASK              0xFFFF  /* DBE_VALID_DATA - [15:0] */
+#define WM831X_DBE_VALID_DATA_SHIFT                  0  /* DBE_VALID_DATA - [15:0] */
+#define WM831X_DBE_VALID_DATA_WIDTH                 16  /* DBE_VALID_DATA - [15:0] */
+
+
+#endif
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
new file mode 100644
index 0000000..90d8202
--- /dev/null
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -0,0 +1,113 @@
+/*
+ * include/linux/mfd/wm831x/pdata.h -- Platform data for WM831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_PDATA_H__
+#define __MFD_WM831X_PDATA_H__
+
+struct wm831x;
+struct regulator_init_data;
+
+struct wm831x_backlight_pdata {
+	int isink;     /** ISINK to use, 1 or 2 */
+	int max_uA;    /** Maximum current to allow */
+};
+
+struct wm831x_backup_pdata {
+	int charger_enable;
+	int no_constant_voltage;  /** Disable constant voltage charging */
+	int vlim;   /** Voltage limit in milivolts */
+	int ilim;   /** Current limit in microamps */
+};
+
+struct wm831x_battery_pdata {
+	int enable;         /** Enable charging */
+	int fast_enable;    /** Enable fast charging */
+	int off_mask;       /** Mask OFF while charging */
+	int trickle_ilim;   /** Trickle charge current limit, in mA */
+	int vsel;           /** Target voltage, in mV */
+	int eoc_iterm;      /** End of trickle charge current, in mA */
+	int fast_ilim;      /** Fast charge current limit, in mA */
+	int timeout;        /** Charge cycle timeout, in minutes */
+};
+
+/* Sources for status LED configuration.  Values are register values
+ * plus 1 to allow for a zero default for preserve.
+ */
+enum wm831x_status_src {
+	WM831X_STATUS_PRESERVE = 0,  /* Keep the current hardware setting */
+	WM831X_STATUS_OTP = 1,
+	WM831X_STATUS_POWER = 2,
+	WM831X_STATUS_CHARGER = 3,
+	WM831X_STATUS_MANUAL = 4,
+};
+
+struct wm831x_status_pdata {
+	enum wm831x_status_src default_src;
+	const char *name;
+	const char *default_trigger;
+};
+
+struct wm831x_touch_pdata {
+	int fivewire;          /** 1 for five wire mode, 0 for 4 wire */
+	int isel;              /** Current for pen down (uA) */
+	int rpu;               /** Pen down sensitivity resistor divider */
+	int pressure;          /** Report pressure (boolean) */
+	int data_irq;          /** Touch data ready IRQ */
+};
+
+enum wm831x_watchdog_action {
+	WM831X_WDOG_NONE = 0,
+	WM831X_WDOG_INTERRUPT = 1,
+	WM831X_WDOG_RESET = 2,
+	WM831X_WDOG_WAKE = 3,
+};
+
+struct wm831x_watchdog_pdata {
+	enum wm831x_watchdog_action primary, secondary;
+	int update_gpio;
+	unsigned int software:1;
+};
+
+#define WM831X_MAX_STATUS 2
+#define WM831X_MAX_DCDC   4
+#define WM831X_MAX_EPE    2
+#define WM831X_MAX_LDO    11
+#define WM831X_MAX_ISINK  2
+
+struct wm831x_pdata {
+	/** Called before subdevices are set up */
+	int (*pre_init)(struct wm831x *wm831x);
+	/** Called after subdevices are set up */
+	int (*post_init)(struct wm831x *wm831x);
+
+	int gpio_base;
+	struct wm831x_backlight_pdata *backlight;
+	struct wm831x_backup_pdata *backup;
+	struct wm831x_battery_pdata *battery;
+	struct wm831x_touch_pdata *touch;
+	struct wm831x_watchdog_pdata *watchdog;
+
+	/** LED1 = 0 and so on */
+	struct wm831x_status_pdata *status[WM831X_MAX_STATUS];
+	/** DCDC1 = 0 and so on */
+	struct regulator_init_data *dcdc[WM831X_MAX_DCDC];
+	/** EPE1 = 0 and so on */
+	struct regulator_init_data *epe[WM831X_MAX_EPE];
+	/** LDO1 = 0 and so on */
+	struct regulator_init_data *ldo[WM831X_MAX_LDO];
+	/** ISINK1 = 0 and so on*/
+	struct regulator_init_data *isink[WM831X_MAX_ISINK];
+};
+
+#endif
diff --git a/include/linux/mfd/wm831x/regulator.h b/include/linux/mfd/wm831x/regulator.h
new file mode 100644
index 0000000..f954663
--- /dev/null
+++ b/include/linux/mfd/wm831x/regulator.h
@@ -0,0 +1,1218 @@
+/*
+ * linux/mfd/wm831x/regulator.h -- Regulator definitons for wm831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_REGULATOR_H__
+#define __MFD_WM831X_REGULATOR_H__
+
+/*
+ * R16462 (0x404E) - Current Sink 1
+ */
+#define WM831X_CS1_ENA                          0x8000  /* CS1_ENA */
+#define WM831X_CS1_ENA_MASK                     0x8000  /* CS1_ENA */
+#define WM831X_CS1_ENA_SHIFT                        15  /* CS1_ENA */
+#define WM831X_CS1_ENA_WIDTH                         1  /* CS1_ENA */
+#define WM831X_CS1_DRIVE                        0x4000  /* CS1_DRIVE */
+#define WM831X_CS1_DRIVE_MASK                   0x4000  /* CS1_DRIVE */
+#define WM831X_CS1_DRIVE_SHIFT                      14  /* CS1_DRIVE */
+#define WM831X_CS1_DRIVE_WIDTH                       1  /* CS1_DRIVE */
+#define WM831X_CS1_SLPENA                       0x1000  /* CS1_SLPENA */
+#define WM831X_CS1_SLPENA_MASK                  0x1000  /* CS1_SLPENA */
+#define WM831X_CS1_SLPENA_SHIFT                     12  /* CS1_SLPENA */
+#define WM831X_CS1_SLPENA_WIDTH                      1  /* CS1_SLPENA */
+#define WM831X_CS1_OFF_RAMP_MASK                0x0C00  /* CS1_OFF_RAMP - [11:10] */
+#define WM831X_CS1_OFF_RAMP_SHIFT                   10  /* CS1_OFF_RAMP - [11:10] */
+#define WM831X_CS1_OFF_RAMP_WIDTH                    2  /* CS1_OFF_RAMP - [11:10] */
+#define WM831X_CS1_ON_RAMP_MASK                 0x0300  /* CS1_ON_RAMP - [9:8] */
+#define WM831X_CS1_ON_RAMP_SHIFT                     8  /* CS1_ON_RAMP - [9:8] */
+#define WM831X_CS1_ON_RAMP_WIDTH                     2  /* CS1_ON_RAMP - [9:8] */
+#define WM831X_CS1_ISEL_MASK                    0x003F  /* CS1_ISEL - [5:0] */
+#define WM831X_CS1_ISEL_SHIFT                        0  /* CS1_ISEL - [5:0] */
+#define WM831X_CS1_ISEL_WIDTH                        6  /* CS1_ISEL - [5:0] */
+
+/*
+ * R16463 (0x404F) - Current Sink 2
+ */
+#define WM831X_CS2_ENA                          0x8000  /* CS2_ENA */
+#define WM831X_CS2_ENA_MASK                     0x8000  /* CS2_ENA */
+#define WM831X_CS2_ENA_SHIFT                        15  /* CS2_ENA */
+#define WM831X_CS2_ENA_WIDTH                         1  /* CS2_ENA */
+#define WM831X_CS2_DRIVE                        0x4000  /* CS2_DRIVE */
+#define WM831X_CS2_DRIVE_MASK                   0x4000  /* CS2_DRIVE */
+#define WM831X_CS2_DRIVE_SHIFT                      14  /* CS2_DRIVE */
+#define WM831X_CS2_DRIVE_WIDTH                       1  /* CS2_DRIVE */
+#define WM831X_CS2_SLPENA                       0x1000  /* CS2_SLPENA */
+#define WM831X_CS2_SLPENA_MASK                  0x1000  /* CS2_SLPENA */
+#define WM831X_CS2_SLPENA_SHIFT                     12  /* CS2_SLPENA */
+#define WM831X_CS2_SLPENA_WIDTH                      1  /* CS2_SLPENA */
+#define WM831X_CS2_OFF_RAMP_MASK                0x0C00  /* CS2_OFF_RAMP - [11:10] */
+#define WM831X_CS2_OFF_RAMP_SHIFT                   10  /* CS2_OFF_RAMP - [11:10] */
+#define WM831X_CS2_OFF_RAMP_WIDTH                    2  /* CS2_OFF_RAMP - [11:10] */
+#define WM831X_CS2_ON_RAMP_MASK                 0x0300  /* CS2_ON_RAMP - [9:8] */
+#define WM831X_CS2_ON_RAMP_SHIFT                     8  /* CS2_ON_RAMP - [9:8] */
+#define WM831X_CS2_ON_RAMP_WIDTH                     2  /* CS2_ON_RAMP - [9:8] */
+#define WM831X_CS2_ISEL_MASK                    0x003F  /* CS2_ISEL - [5:0] */
+#define WM831X_CS2_ISEL_SHIFT                        0  /* CS2_ISEL - [5:0] */
+#define WM831X_CS2_ISEL_WIDTH                        6  /* CS2_ISEL - [5:0] */
+
+/*
+ * R16464 (0x4050) - DCDC Enable
+ */
+#define WM831X_EPE2_ENA                         0x0080  /* EPE2_ENA */
+#define WM831X_EPE2_ENA_MASK                    0x0080  /* EPE2_ENA */
+#define WM831X_EPE2_ENA_SHIFT                        7  /* EPE2_ENA */
+#define WM831X_EPE2_ENA_WIDTH                        1  /* EPE2_ENA */
+#define WM831X_EPE1_ENA                         0x0040  /* EPE1_ENA */
+#define WM831X_EPE1_ENA_MASK                    0x0040  /* EPE1_ENA */
+#define WM831X_EPE1_ENA_SHIFT                        6  /* EPE1_ENA */
+#define WM831X_EPE1_ENA_WIDTH                        1  /* EPE1_ENA */
+#define WM831X_DC4_ENA                          0x0008  /* DC4_ENA */
+#define WM831X_DC4_ENA_MASK                     0x0008  /* DC4_ENA */
+#define WM831X_DC4_ENA_SHIFT                         3  /* DC4_ENA */
+#define WM831X_DC4_ENA_WIDTH                         1  /* DC4_ENA */
+#define WM831X_DC3_ENA                          0x0004  /* DC3_ENA */
+#define WM831X_DC3_ENA_MASK                     0x0004  /* DC3_ENA */
+#define WM831X_DC3_ENA_SHIFT                         2  /* DC3_ENA */
+#define WM831X_DC3_ENA_WIDTH                         1  /* DC3_ENA */
+#define WM831X_DC2_ENA                          0x0002  /* DC2_ENA */
+#define WM831X_DC2_ENA_MASK                     0x0002  /* DC2_ENA */
+#define WM831X_DC2_ENA_SHIFT                         1  /* DC2_ENA */
+#define WM831X_DC2_ENA_WIDTH                         1  /* DC2_ENA */
+#define WM831X_DC1_ENA                          0x0001  /* DC1_ENA */
+#define WM831X_DC1_ENA_MASK                     0x0001  /* DC1_ENA */
+#define WM831X_DC1_ENA_SHIFT                         0  /* DC1_ENA */
+#define WM831X_DC1_ENA_WIDTH                         1  /* DC1_ENA */
+
+/*
+ * R16465 (0x4051) - LDO Enable
+ */
+#define WM831X_LDO11_ENA                        0x0400  /* LDO11_ENA */
+#define WM831X_LDO11_ENA_MASK                   0x0400  /* LDO11_ENA */
+#define WM831X_LDO11_ENA_SHIFT                      10  /* LDO11_ENA */
+#define WM831X_LDO11_ENA_WIDTH                       1  /* LDO11_ENA */
+#define WM831X_LDO10_ENA                        0x0200  /* LDO10_ENA */
+#define WM831X_LDO10_ENA_MASK                   0x0200  /* LDO10_ENA */
+#define WM831X_LDO10_ENA_SHIFT                       9  /* LDO10_ENA */
+#define WM831X_LDO10_ENA_WIDTH                       1  /* LDO10_ENA */
+#define WM831X_LDO9_ENA                         0x0100  /* LDO9_ENA */
+#define WM831X_LDO9_ENA_MASK                    0x0100  /* LDO9_ENA */
+#define WM831X_LDO9_ENA_SHIFT                        8  /* LDO9_ENA */
+#define WM831X_LDO9_ENA_WIDTH                        1  /* LDO9_ENA */
+#define WM831X_LDO8_ENA                         0x0080  /* LDO8_ENA */
+#define WM831X_LDO8_ENA_MASK                    0x0080  /* LDO8_ENA */
+#define WM831X_LDO8_ENA_SHIFT                        7  /* LDO8_ENA */
+#define WM831X_LDO8_ENA_WIDTH                        1  /* LDO8_ENA */
+#define WM831X_LDO7_ENA                         0x0040  /* LDO7_ENA */
+#define WM831X_LDO7_ENA_MASK                    0x0040  /* LDO7_ENA */
+#define WM831X_LDO7_ENA_SHIFT                        6  /* LDO7_ENA */
+#define WM831X_LDO7_ENA_WIDTH                        1  /* LDO7_ENA */
+#define WM831X_LDO6_ENA                         0x0020  /* LDO6_ENA */
+#define WM831X_LDO6_ENA_MASK                    0x0020  /* LDO6_ENA */
+#define WM831X_LDO6_ENA_SHIFT                        5  /* LDO6_ENA */
+#define WM831X_LDO6_ENA_WIDTH                        1  /* LDO6_ENA */
+#define WM831X_LDO5_ENA                         0x0010  /* LDO5_ENA */
+#define WM831X_LDO5_ENA_MASK                    0x0010  /* LDO5_ENA */
+#define WM831X_LDO5_ENA_SHIFT                        4  /* LDO5_ENA */
+#define WM831X_LDO5_ENA_WIDTH                        1  /* LDO5_ENA */
+#define WM831X_LDO4_ENA                         0x0008  /* LDO4_ENA */
+#define WM831X_LDO4_ENA_MASK                    0x0008  /* LDO4_ENA */
+#define WM831X_LDO4_ENA_SHIFT                        3  /* LDO4_ENA */
+#define WM831X_LDO4_ENA_WIDTH                        1  /* LDO4_ENA */
+#define WM831X_LDO3_ENA                         0x0004  /* LDO3_ENA */
+#define WM831X_LDO3_ENA_MASK                    0x0004  /* LDO3_ENA */
+#define WM831X_LDO3_ENA_SHIFT                        2  /* LDO3_ENA */
+#define WM831X_LDO3_ENA_WIDTH                        1  /* LDO3_ENA */
+#define WM831X_LDO2_ENA                         0x0002  /* LDO2_ENA */
+#define WM831X_LDO2_ENA_MASK                    0x0002  /* LDO2_ENA */
+#define WM831X_LDO2_ENA_SHIFT                        1  /* LDO2_ENA */
+#define WM831X_LDO2_ENA_WIDTH                        1  /* LDO2_ENA */
+#define WM831X_LDO1_ENA                         0x0001  /* LDO1_ENA */
+#define WM831X_LDO1_ENA_MASK                    0x0001  /* LDO1_ENA */
+#define WM831X_LDO1_ENA_SHIFT                        0  /* LDO1_ENA */
+#define WM831X_LDO1_ENA_WIDTH                        1  /* LDO1_ENA */
+
+/*
+ * R16466 (0x4052) - DCDC Status
+ */
+#define WM831X_EPE2_STS                         0x0080  /* EPE2_STS */
+#define WM831X_EPE2_STS_MASK                    0x0080  /* EPE2_STS */
+#define WM831X_EPE2_STS_SHIFT                        7  /* EPE2_STS */
+#define WM831X_EPE2_STS_WIDTH                        1  /* EPE2_STS */
+#define WM831X_EPE1_STS                         0x0040  /* EPE1_STS */
+#define WM831X_EPE1_STS_MASK                    0x0040  /* EPE1_STS */
+#define WM831X_EPE1_STS_SHIFT                        6  /* EPE1_STS */
+#define WM831X_EPE1_STS_WIDTH                        1  /* EPE1_STS */
+#define WM831X_DC4_STS                          0x0008  /* DC4_STS */
+#define WM831X_DC4_STS_MASK                     0x0008  /* DC4_STS */
+#define WM831X_DC4_STS_SHIFT                         3  /* DC4_STS */
+#define WM831X_DC4_STS_WIDTH                         1  /* DC4_STS */
+#define WM831X_DC3_STS                          0x0004  /* DC3_STS */
+#define WM831X_DC3_STS_MASK                     0x0004  /* DC3_STS */
+#define WM831X_DC3_STS_SHIFT                         2  /* DC3_STS */
+#define WM831X_DC3_STS_WIDTH                         1  /* DC3_STS */
+#define WM831X_DC2_STS                          0x0002  /* DC2_STS */
+#define WM831X_DC2_STS_MASK                     0x0002  /* DC2_STS */
+#define WM831X_DC2_STS_SHIFT                         1  /* DC2_STS */
+#define WM831X_DC2_STS_WIDTH                         1  /* DC2_STS */
+#define WM831X_DC1_STS                          0x0001  /* DC1_STS */
+#define WM831X_DC1_STS_MASK                     0x0001  /* DC1_STS */
+#define WM831X_DC1_STS_SHIFT                         0  /* DC1_STS */
+#define WM831X_DC1_STS_WIDTH                         1  /* DC1_STS */
+
+/*
+ * R16467 (0x4053) - LDO Status
+ */
+#define WM831X_LDO11_STS                        0x0400  /* LDO11_STS */
+#define WM831X_LDO11_STS_MASK                   0x0400  /* LDO11_STS */
+#define WM831X_LDO11_STS_SHIFT                      10  /* LDO11_STS */
+#define WM831X_LDO11_STS_WIDTH                       1  /* LDO11_STS */
+#define WM831X_LDO10_STS                        0x0200  /* LDO10_STS */
+#define WM831X_LDO10_STS_MASK                   0x0200  /* LDO10_STS */
+#define WM831X_LDO10_STS_SHIFT                       9  /* LDO10_STS */
+#define WM831X_LDO10_STS_WIDTH                       1  /* LDO10_STS */
+#define WM831X_LDO9_STS                         0x0100  /* LDO9_STS */
+#define WM831X_LDO9_STS_MASK                    0x0100  /* LDO9_STS */
+#define WM831X_LDO9_STS_SHIFT                        8  /* LDO9_STS */
+#define WM831X_LDO9_STS_WIDTH                        1  /* LDO9_STS */
+#define WM831X_LDO8_STS                         0x0080  /* LDO8_STS */
+#define WM831X_LDO8_STS_MASK                    0x0080  /* LDO8_STS */
+#define WM831X_LDO8_STS_SHIFT                        7  /* LDO8_STS */
+#define WM831X_LDO8_STS_WIDTH                        1  /* LDO8_STS */
+#define WM831X_LDO7_STS                         0x0040  /* LDO7_STS */
+#define WM831X_LDO7_STS_MASK                    0x0040  /* LDO7_STS */
+#define WM831X_LDO7_STS_SHIFT                        6  /* LDO7_STS */
+#define WM831X_LDO7_STS_WIDTH                        1  /* LDO7_STS */
+#define WM831X_LDO6_STS                         0x0020  /* LDO6_STS */
+#define WM831X_LDO6_STS_MASK                    0x0020  /* LDO6_STS */
+#define WM831X_LDO6_STS_SHIFT                        5  /* LDO6_STS */
+#define WM831X_LDO6_STS_WIDTH                        1  /* LDO6_STS */
+#define WM831X_LDO5_STS                         0x0010  /* LDO5_STS */
+#define WM831X_LDO5_STS_MASK                    0x0010  /* LDO5_STS */
+#define WM831X_LDO5_STS_SHIFT                        4  /* LDO5_STS */
+#define WM831X_LDO5_STS_WIDTH                        1  /* LDO5_STS */
+#define WM831X_LDO4_STS                         0x0008  /* LDO4_STS */
+#define WM831X_LDO4_STS_MASK                    0x0008  /* LDO4_STS */
+#define WM831X_LDO4_STS_SHIFT                        3  /* LDO4_STS */
+#define WM831X_LDO4_STS_WIDTH                        1  /* LDO4_STS */
+#define WM831X_LDO3_STS                         0x0004  /* LDO3_STS */
+#define WM831X_LDO3_STS_MASK                    0x0004  /* LDO3_STS */
+#define WM831X_LDO3_STS_SHIFT                        2  /* LDO3_STS */
+#define WM831X_LDO3_STS_WIDTH                        1  /* LDO3_STS */
+#define WM831X_LDO2_STS                         0x0002  /* LDO2_STS */
+#define WM831X_LDO2_STS_MASK                    0x0002  /* LDO2_STS */
+#define WM831X_LDO2_STS_SHIFT                        1  /* LDO2_STS */
+#define WM831X_LDO2_STS_WIDTH                        1  /* LDO2_STS */
+#define WM831X_LDO1_STS                         0x0001  /* LDO1_STS */
+#define WM831X_LDO1_STS_MASK                    0x0001  /* LDO1_STS */
+#define WM831X_LDO1_STS_SHIFT                        0  /* LDO1_STS */
+#define WM831X_LDO1_STS_WIDTH                        1  /* LDO1_STS */
+
+/*
+ * R16468 (0x4054) - DCDC UV Status
+ */
+#define WM831X_DC2_OV_STS                       0x2000  /* DC2_OV_STS */
+#define WM831X_DC2_OV_STS_MASK                  0x2000  /* DC2_OV_STS */
+#define WM831X_DC2_OV_STS_SHIFT                     13  /* DC2_OV_STS */
+#define WM831X_DC2_OV_STS_WIDTH                      1  /* DC2_OV_STS */
+#define WM831X_DC1_OV_STS                       0x1000  /* DC1_OV_STS */
+#define WM831X_DC1_OV_STS_MASK                  0x1000  /* DC1_OV_STS */
+#define WM831X_DC1_OV_STS_SHIFT                     12  /* DC1_OV_STS */
+#define WM831X_DC1_OV_STS_WIDTH                      1  /* DC1_OV_STS */
+#define WM831X_DC2_HC_STS                       0x0200  /* DC2_HC_STS */
+#define WM831X_DC2_HC_STS_MASK                  0x0200  /* DC2_HC_STS */
+#define WM831X_DC2_HC_STS_SHIFT                      9  /* DC2_HC_STS */
+#define WM831X_DC2_HC_STS_WIDTH                      1  /* DC2_HC_STS */
+#define WM831X_DC1_HC_STS                       0x0100  /* DC1_HC_STS */
+#define WM831X_DC1_HC_STS_MASK                  0x0100  /* DC1_HC_STS */
+#define WM831X_DC1_HC_STS_SHIFT                      8  /* DC1_HC_STS */
+#define WM831X_DC1_HC_STS_WIDTH                      1  /* DC1_HC_STS */
+#define WM831X_DC4_UV_STS                       0x0008  /* DC4_UV_STS */
+#define WM831X_DC4_UV_STS_MASK                  0x0008  /* DC4_UV_STS */
+#define WM831X_DC4_UV_STS_SHIFT                      3  /* DC4_UV_STS */
+#define WM831X_DC4_UV_STS_WIDTH                      1  /* DC4_UV_STS */
+#define WM831X_DC3_UV_STS                       0x0004  /* DC3_UV_STS */
+#define WM831X_DC3_UV_STS_MASK                  0x0004  /* DC3_UV_STS */
+#define WM831X_DC3_UV_STS_SHIFT                      2  /* DC3_UV_STS */
+#define WM831X_DC3_UV_STS_WIDTH                      1  /* DC3_UV_STS */
+#define WM831X_DC2_UV_STS                       0x0002  /* DC2_UV_STS */
+#define WM831X_DC2_UV_STS_MASK                  0x0002  /* DC2_UV_STS */
+#define WM831X_DC2_UV_STS_SHIFT                      1  /* DC2_UV_STS */
+#define WM831X_DC2_UV_STS_WIDTH                      1  /* DC2_UV_STS */
+#define WM831X_DC1_UV_STS                       0x0001  /* DC1_UV_STS */
+#define WM831X_DC1_UV_STS_MASK                  0x0001  /* DC1_UV_STS */
+#define WM831X_DC1_UV_STS_SHIFT                      0  /* DC1_UV_STS */
+#define WM831X_DC1_UV_STS_WIDTH                      1  /* DC1_UV_STS */
+
+/*
+ * R16469 (0x4055) - LDO UV Status
+ */
+#define WM831X_INTLDO_UV_STS                    0x8000  /* INTLDO_UV_STS */
+#define WM831X_INTLDO_UV_STS_MASK               0x8000  /* INTLDO_UV_STS */
+#define WM831X_INTLDO_UV_STS_SHIFT                  15  /* INTLDO_UV_STS */
+#define WM831X_INTLDO_UV_STS_WIDTH                   1  /* INTLDO_UV_STS */
+#define WM831X_LDO10_UV_STS                     0x0200  /* LDO10_UV_STS */
+#define WM831X_LDO10_UV_STS_MASK                0x0200  /* LDO10_UV_STS */
+#define WM831X_LDO10_UV_STS_SHIFT                    9  /* LDO10_UV_STS */
+#define WM831X_LDO10_UV_STS_WIDTH                    1  /* LDO10_UV_STS */
+#define WM831X_LDO9_UV_STS                      0x0100  /* LDO9_UV_STS */
+#define WM831X_LDO9_UV_STS_MASK                 0x0100  /* LDO9_UV_STS */
+#define WM831X_LDO9_UV_STS_SHIFT                     8  /* LDO9_UV_STS */
+#define WM831X_LDO9_UV_STS_WIDTH                     1  /* LDO9_UV_STS */
+#define WM831X_LDO8_UV_STS                      0x0080  /* LDO8_UV_STS */
+#define WM831X_LDO8_UV_STS_MASK                 0x0080  /* LDO8_UV_STS */
+#define WM831X_LDO8_UV_STS_SHIFT                     7  /* LDO8_UV_STS */
+#define WM831X_LDO8_UV_STS_WIDTH                     1  /* LDO8_UV_STS */
+#define WM831X_LDO7_UV_STS                      0x0040  /* LDO7_UV_STS */
+#define WM831X_LDO7_UV_STS_MASK                 0x0040  /* LDO7_UV_STS */
+#define WM831X_LDO7_UV_STS_SHIFT                     6  /* LDO7_UV_STS */
+#define WM831X_LDO7_UV_STS_WIDTH                     1  /* LDO7_UV_STS */
+#define WM831X_LDO6_UV_STS                      0x0020  /* LDO6_UV_STS */
+#define WM831X_LDO6_UV_STS_MASK                 0x0020  /* LDO6_UV_STS */
+#define WM831X_LDO6_UV_STS_SHIFT                     5  /* LDO6_UV_STS */
+#define WM831X_LDO6_UV_STS_WIDTH                     1  /* LDO6_UV_STS */
+#define WM831X_LDO5_UV_STS                      0x0010  /* LDO5_UV_STS */
+#define WM831X_LDO5_UV_STS_MASK                 0x0010  /* LDO5_UV_STS */
+#define WM831X_LDO5_UV_STS_SHIFT                     4  /* LDO5_UV_STS */
+#define WM831X_LDO5_UV_STS_WIDTH                     1  /* LDO5_UV_STS */
+#define WM831X_LDO4_UV_STS                      0x0008  /* LDO4_UV_STS */
+#define WM831X_LDO4_UV_STS_MASK                 0x0008  /* LDO4_UV_STS */
+#define WM831X_LDO4_UV_STS_SHIFT                     3  /* LDO4_UV_STS */
+#define WM831X_LDO4_UV_STS_WIDTH                     1  /* LDO4_UV_STS */
+#define WM831X_LDO3_UV_STS                      0x0004  /* LDO3_UV_STS */
+#define WM831X_LDO3_UV_STS_MASK                 0x0004  /* LDO3_UV_STS */
+#define WM831X_LDO3_UV_STS_SHIFT                     2  /* LDO3_UV_STS */
+#define WM831X_LDO3_UV_STS_WIDTH                     1  /* LDO3_UV_STS */
+#define WM831X_LDO2_UV_STS                      0x0002  /* LDO2_UV_STS */
+#define WM831X_LDO2_UV_STS_MASK                 0x0002  /* LDO2_UV_STS */
+#define WM831X_LDO2_UV_STS_SHIFT                     1  /* LDO2_UV_STS */
+#define WM831X_LDO2_UV_STS_WIDTH                     1  /* LDO2_UV_STS */
+#define WM831X_LDO1_UV_STS                      0x0001  /* LDO1_UV_STS */
+#define WM831X_LDO1_UV_STS_MASK                 0x0001  /* LDO1_UV_STS */
+#define WM831X_LDO1_UV_STS_SHIFT                     0  /* LDO1_UV_STS */
+#define WM831X_LDO1_UV_STS_WIDTH                     1  /* LDO1_UV_STS */
+
+/*
+ * R16470 (0x4056) - DC1 Control 1
+ */
+#define WM831X_DC1_RATE_MASK                    0xC000  /* DC1_RATE - [15:14] */
+#define WM831X_DC1_RATE_SHIFT                       14  /* DC1_RATE - [15:14] */
+#define WM831X_DC1_RATE_WIDTH                        2  /* DC1_RATE - [15:14] */
+#define WM831X_DC1_PHASE                        0x1000  /* DC1_PHASE */
+#define WM831X_DC1_PHASE_MASK                   0x1000  /* DC1_PHASE */
+#define WM831X_DC1_PHASE_SHIFT                      12  /* DC1_PHASE */
+#define WM831X_DC1_PHASE_WIDTH                       1  /* DC1_PHASE */
+#define WM831X_DC1_FREQ_MASK                    0x0300  /* DC1_FREQ - [9:8] */
+#define WM831X_DC1_FREQ_SHIFT                        8  /* DC1_FREQ - [9:8] */
+#define WM831X_DC1_FREQ_WIDTH                        2  /* DC1_FREQ - [9:8] */
+#define WM831X_DC1_FLT                          0x0080  /* DC1_FLT */
+#define WM831X_DC1_FLT_MASK                     0x0080  /* DC1_FLT */
+#define WM831X_DC1_FLT_SHIFT                         7  /* DC1_FLT */
+#define WM831X_DC1_FLT_WIDTH                         1  /* DC1_FLT */
+#define WM831X_DC1_SOFT_START_MASK              0x0030  /* DC1_SOFT_START - [5:4] */
+#define WM831X_DC1_SOFT_START_SHIFT                  4  /* DC1_SOFT_START - [5:4] */
+#define WM831X_DC1_SOFT_START_WIDTH                  2  /* DC1_SOFT_START - [5:4] */
+#define WM831X_DC1_CAP_MASK                     0x0003  /* DC1_CAP - [1:0] */
+#define WM831X_DC1_CAP_SHIFT                         0  /* DC1_CAP - [1:0] */
+#define WM831X_DC1_CAP_WIDTH                         2  /* DC1_CAP - [1:0] */
+
+/*
+ * R16471 (0x4057) - DC1 Control 2
+ */
+#define WM831X_DC1_ERR_ACT_MASK                 0xC000  /* DC1_ERR_ACT - [15:14] */
+#define WM831X_DC1_ERR_ACT_SHIFT                    14  /* DC1_ERR_ACT - [15:14] */
+#define WM831X_DC1_ERR_ACT_WIDTH                     2  /* DC1_ERR_ACT - [15:14] */
+#define WM831X_DC1_HWC_SRC_MASK                 0x1800  /* DC1_HWC_SRC - [12:11] */
+#define WM831X_DC1_HWC_SRC_SHIFT                    11  /* DC1_HWC_SRC - [12:11] */
+#define WM831X_DC1_HWC_SRC_WIDTH                     2  /* DC1_HWC_SRC - [12:11] */
+#define WM831X_DC1_HWC_VSEL                     0x0400  /* DC1_HWC_VSEL */
+#define WM831X_DC1_HWC_VSEL_MASK                0x0400  /* DC1_HWC_VSEL */
+#define WM831X_DC1_HWC_VSEL_SHIFT                   10  /* DC1_HWC_VSEL */
+#define WM831X_DC1_HWC_VSEL_WIDTH                    1  /* DC1_HWC_VSEL */
+#define WM831X_DC1_HWC_MODE_MASK                0x0300  /* DC1_HWC_MODE - [9:8] */
+#define WM831X_DC1_HWC_MODE_SHIFT                    8  /* DC1_HWC_MODE - [9:8] */
+#define WM831X_DC1_HWC_MODE_WIDTH                    2  /* DC1_HWC_MODE - [9:8] */
+#define WM831X_DC1_HC_THR_MASK                  0x0070  /* DC1_HC_THR - [6:4] */
+#define WM831X_DC1_HC_THR_SHIFT                      4  /* DC1_HC_THR - [6:4] */
+#define WM831X_DC1_HC_THR_WIDTH                      3  /* DC1_HC_THR - [6:4] */
+#define WM831X_DC1_HC_IND_ENA                   0x0001  /* DC1_HC_IND_ENA */
+#define WM831X_DC1_HC_IND_ENA_MASK              0x0001  /* DC1_HC_IND_ENA */
+#define WM831X_DC1_HC_IND_ENA_SHIFT                  0  /* DC1_HC_IND_ENA */
+#define WM831X_DC1_HC_IND_ENA_WIDTH                  1  /* DC1_HC_IND_ENA */
+
+/*
+ * R16472 (0x4058) - DC1 ON Config
+ */
+#define WM831X_DC1_ON_SLOT_MASK                 0xE000  /* DC1_ON_SLOT - [15:13] */
+#define WM831X_DC1_ON_SLOT_SHIFT                    13  /* DC1_ON_SLOT - [15:13] */
+#define WM831X_DC1_ON_SLOT_WIDTH                     3  /* DC1_ON_SLOT - [15:13] */
+#define WM831X_DC1_ON_MODE_MASK                 0x0300  /* DC1_ON_MODE - [9:8] */
+#define WM831X_DC1_ON_MODE_SHIFT                     8  /* DC1_ON_MODE - [9:8] */
+#define WM831X_DC1_ON_MODE_WIDTH                     2  /* DC1_ON_MODE - [9:8] */
+#define WM831X_DC1_ON_VSEL_MASK                 0x007F  /* DC1_ON_VSEL - [6:0] */
+#define WM831X_DC1_ON_VSEL_SHIFT                     0  /* DC1_ON_VSEL - [6:0] */
+#define WM831X_DC1_ON_VSEL_WIDTH                     7  /* DC1_ON_VSEL - [6:0] */
+
+/*
+ * R16473 (0x4059) - DC1 SLEEP Control
+ */
+#define WM831X_DC1_SLP_SLOT_MASK                0xE000  /* DC1_SLP_SLOT - [15:13] */
+#define WM831X_DC1_SLP_SLOT_SHIFT                   13  /* DC1_SLP_SLOT - [15:13] */
+#define WM831X_DC1_SLP_SLOT_WIDTH                    3  /* DC1_SLP_SLOT - [15:13] */
+#define WM831X_DC1_SLP_MODE_MASK                0x0300  /* DC1_SLP_MODE - [9:8] */
+#define WM831X_DC1_SLP_MODE_SHIFT                    8  /* DC1_SLP_MODE - [9:8] */
+#define WM831X_DC1_SLP_MODE_WIDTH                    2  /* DC1_SLP_MODE - [9:8] */
+#define WM831X_DC1_SLP_VSEL_MASK                0x007F  /* DC1_SLP_VSEL - [6:0] */
+#define WM831X_DC1_SLP_VSEL_SHIFT                    0  /* DC1_SLP_VSEL - [6:0] */
+#define WM831X_DC1_SLP_VSEL_WIDTH                    7  /* DC1_SLP_VSEL - [6:0] */
+
+/*
+ * R16474 (0x405A) - DC1 DVS Control
+ */
+#define WM831X_DC1_DVS_SRC_MASK                 0x1800  /* DC1_DVS_SRC - [12:11] */
+#define WM831X_DC1_DVS_SRC_SHIFT                    11  /* DC1_DVS_SRC - [12:11] */
+#define WM831X_DC1_DVS_SRC_WIDTH                     2  /* DC1_DVS_SRC - [12:11] */
+#define WM831X_DC1_DVS_VSEL_MASK                0x007F  /* DC1_DVS_VSEL - [6:0] */
+#define WM831X_DC1_DVS_VSEL_SHIFT                    0  /* DC1_DVS_VSEL - [6:0] */
+#define WM831X_DC1_DVS_VSEL_WIDTH                    7  /* DC1_DVS_VSEL - [6:0] */
+
+/*
+ * R16475 (0x405B) - DC2 Control 1
+ */
+#define WM831X_DC2_RATE_MASK                    0xC000  /* DC2_RATE - [15:14] */
+#define WM831X_DC2_RATE_SHIFT                       14  /* DC2_RATE - [15:14] */
+#define WM831X_DC2_RATE_WIDTH                        2  /* DC2_RATE - [15:14] */
+#define WM831X_DC2_PHASE                        0x1000  /* DC2_PHASE */
+#define WM831X_DC2_PHASE_MASK                   0x1000  /* DC2_PHASE */
+#define WM831X_DC2_PHASE_SHIFT                      12  /* DC2_PHASE */
+#define WM831X_DC2_PHASE_WIDTH                       1  /* DC2_PHASE */
+#define WM831X_DC2_FREQ_MASK                    0x0300  /* DC2_FREQ - [9:8] */
+#define WM831X_DC2_FREQ_SHIFT                        8  /* DC2_FREQ - [9:8] */
+#define WM831X_DC2_FREQ_WIDTH                        2  /* DC2_FREQ - [9:8] */
+#define WM831X_DC2_FLT                          0x0080  /* DC2_FLT */
+#define WM831X_DC2_FLT_MASK                     0x0080  /* DC2_FLT */
+#define WM831X_DC2_FLT_SHIFT                         7  /* DC2_FLT */
+#define WM831X_DC2_FLT_WIDTH                         1  /* DC2_FLT */
+#define WM831X_DC2_SOFT_START_MASK              0x0030  /* DC2_SOFT_START - [5:4] */
+#define WM831X_DC2_SOFT_START_SHIFT                  4  /* DC2_SOFT_START - [5:4] */
+#define WM831X_DC2_SOFT_START_WIDTH                  2  /* DC2_SOFT_START - [5:4] */
+#define WM831X_DC2_CAP_MASK                     0x0003  /* DC2_CAP - [1:0] */
+#define WM831X_DC2_CAP_SHIFT                         0  /* DC2_CAP - [1:0] */
+#define WM831X_DC2_CAP_WIDTH                         2  /* DC2_CAP - [1:0] */
+
+/*
+ * R16476 (0x405C) - DC2 Control 2
+ */
+#define WM831X_DC2_ERR_ACT_MASK                 0xC000  /* DC2_ERR_ACT - [15:14] */
+#define WM831X_DC2_ERR_ACT_SHIFT                    14  /* DC2_ERR_ACT - [15:14] */
+#define WM831X_DC2_ERR_ACT_WIDTH                     2  /* DC2_ERR_ACT - [15:14] */
+#define WM831X_DC2_HWC_SRC_MASK                 0x1800  /* DC2_HWC_SRC - [12:11] */
+#define WM831X_DC2_HWC_SRC_SHIFT                    11  /* DC2_HWC_SRC - [12:11] */
+#define WM831X_DC2_HWC_SRC_WIDTH                     2  /* DC2_HWC_SRC - [12:11] */
+#define WM831X_DC2_HWC_VSEL                     0x0400  /* DC2_HWC_VSEL */
+#define WM831X_DC2_HWC_VSEL_MASK                0x0400  /* DC2_HWC_VSEL */
+#define WM831X_DC2_HWC_VSEL_SHIFT                   10  /* DC2_HWC_VSEL */
+#define WM831X_DC2_HWC_VSEL_WIDTH                    1  /* DC2_HWC_VSEL */
+#define WM831X_DC2_HWC_MODE_MASK                0x0300  /* DC2_HWC_MODE - [9:8] */
+#define WM831X_DC2_HWC_MODE_SHIFT                    8  /* DC2_HWC_MODE - [9:8] */
+#define WM831X_DC2_HWC_MODE_WIDTH                    2  /* DC2_HWC_MODE - [9:8] */
+#define WM831X_DC2_HC_THR_MASK                  0x0070  /* DC2_HC_THR - [6:4] */
+#define WM831X_DC2_HC_THR_SHIFT                      4  /* DC2_HC_THR - [6:4] */
+#define WM831X_DC2_HC_THR_WIDTH                      3  /* DC2_HC_THR - [6:4] */
+#define WM831X_DC2_HC_IND_ENA                   0x0001  /* DC2_HC_IND_ENA */
+#define WM831X_DC2_HC_IND_ENA_MASK              0x0001  /* DC2_HC_IND_ENA */
+#define WM831X_DC2_HC_IND_ENA_SHIFT                  0  /* DC2_HC_IND_ENA */
+#define WM831X_DC2_HC_IND_ENA_WIDTH                  1  /* DC2_HC_IND_ENA */
+
+/*
+ * R16477 (0x405D) - DC2 ON Config
+ */
+#define WM831X_DC2_ON_SLOT_MASK                 0xE000  /* DC2_ON_SLOT - [15:13] */
+#define WM831X_DC2_ON_SLOT_SHIFT                    13  /* DC2_ON_SLOT - [15:13] */
+#define WM831X_DC2_ON_SLOT_WIDTH                     3  /* DC2_ON_SLOT - [15:13] */
+#define WM831X_DC2_ON_MODE_MASK                 0x0300  /* DC2_ON_MODE - [9:8] */
+#define WM831X_DC2_ON_MODE_SHIFT                     8  /* DC2_ON_MODE - [9:8] */
+#define WM831X_DC2_ON_MODE_WIDTH                     2  /* DC2_ON_MODE - [9:8] */
+#define WM831X_DC2_ON_VSEL_MASK                 0x007F  /* DC2_ON_VSEL - [6:0] */
+#define WM831X_DC2_ON_VSEL_SHIFT                     0  /* DC2_ON_VSEL - [6:0] */
+#define WM831X_DC2_ON_VSEL_WIDTH                     7  /* DC2_ON_VSEL - [6:0] */
+
+/*
+ * R16478 (0x405E) - DC2 SLEEP Control
+ */
+#define WM831X_DC2_SLP_SLOT_MASK                0xE000  /* DC2_SLP_SLOT - [15:13] */
+#define WM831X_DC2_SLP_SLOT_SHIFT                   13  /* DC2_SLP_SLOT - [15:13] */
+#define WM831X_DC2_SLP_SLOT_WIDTH                    3  /* DC2_SLP_SLOT - [15:13] */
+#define WM831X_DC2_SLP_MODE_MASK                0x0300  /* DC2_SLP_MODE - [9:8] */
+#define WM831X_DC2_SLP_MODE_SHIFT                    8  /* DC2_SLP_MODE - [9:8] */
+#define WM831X_DC2_SLP_MODE_WIDTH                    2  /* DC2_SLP_MODE - [9:8] */
+#define WM831X_DC2_SLP_VSEL_MASK                0x007F  /* DC2_SLP_VSEL - [6:0] */
+#define WM831X_DC2_SLP_VSEL_SHIFT                    0  /* DC2_SLP_VSEL - [6:0] */
+#define WM831X_DC2_SLP_VSEL_WIDTH                    7  /* DC2_SLP_VSEL - [6:0] */
+
+/*
+ * R16479 (0x405F) - DC2 DVS Control
+ */
+#define WM831X_DC2_DVS_SRC_MASK                 0x1800  /* DC2_DVS_SRC - [12:11] */
+#define WM831X_DC2_DVS_SRC_SHIFT                    11  /* DC2_DVS_SRC - [12:11] */
+#define WM831X_DC2_DVS_SRC_WIDTH                     2  /* DC2_DVS_SRC - [12:11] */
+#define WM831X_DC2_DVS_VSEL_MASK                0x007F  /* DC2_DVS_VSEL - [6:0] */
+#define WM831X_DC2_DVS_VSEL_SHIFT                    0  /* DC2_DVS_VSEL - [6:0] */
+#define WM831X_DC2_DVS_VSEL_WIDTH                    7  /* DC2_DVS_VSEL - [6:0] */
+
+/*
+ * R16480 (0x4060) - DC3 Control 1
+ */
+#define WM831X_DC3_PHASE                        0x1000  /* DC3_PHASE */
+#define WM831X_DC3_PHASE_MASK                   0x1000  /* DC3_PHASE */
+#define WM831X_DC3_PHASE_SHIFT                      12  /* DC3_PHASE */
+#define WM831X_DC3_PHASE_WIDTH                       1  /* DC3_PHASE */
+#define WM831X_DC3_FLT                          0x0080  /* DC3_FLT */
+#define WM831X_DC3_FLT_MASK                     0x0080  /* DC3_FLT */
+#define WM831X_DC3_FLT_SHIFT                         7  /* DC3_FLT */
+#define WM831X_DC3_FLT_WIDTH                         1  /* DC3_FLT */
+#define WM831X_DC3_SOFT_START_MASK              0x0030  /* DC3_SOFT_START - [5:4] */
+#define WM831X_DC3_SOFT_START_SHIFT                  4  /* DC3_SOFT_START - [5:4] */
+#define WM831X_DC3_SOFT_START_WIDTH                  2  /* DC3_SOFT_START - [5:4] */
+#define WM831X_DC3_STNBY_LIM_MASK               0x000C  /* DC3_STNBY_LIM - [3:2] */
+#define WM831X_DC3_STNBY_LIM_SHIFT                   2  /* DC3_STNBY_LIM - [3:2] */
+#define WM831X_DC3_STNBY_LIM_WIDTH                   2  /* DC3_STNBY_LIM - [3:2] */
+#define WM831X_DC3_CAP_MASK                     0x0003  /* DC3_CAP - [1:0] */
+#define WM831X_DC3_CAP_SHIFT                         0  /* DC3_CAP - [1:0] */
+#define WM831X_DC3_CAP_WIDTH                         2  /* DC3_CAP - [1:0] */
+
+/*
+ * R16481 (0x4061) - DC3 Control 2
+ */
+#define WM831X_DC3_ERR_ACT_MASK                 0xC000  /* DC3_ERR_ACT - [15:14] */
+#define WM831X_DC3_ERR_ACT_SHIFT                    14  /* DC3_ERR_ACT - [15:14] */
+#define WM831X_DC3_ERR_ACT_WIDTH                     2  /* DC3_ERR_ACT - [15:14] */
+#define WM831X_DC3_HWC_SRC_MASK                 0x1800  /* DC3_HWC_SRC - [12:11] */
+#define WM831X_DC3_HWC_SRC_SHIFT                    11  /* DC3_HWC_SRC - [12:11] */
+#define WM831X_DC3_HWC_SRC_WIDTH                     2  /* DC3_HWC_SRC - [12:11] */
+#define WM831X_DC3_HWC_VSEL                     0x0400  /* DC3_HWC_VSEL */
+#define WM831X_DC3_HWC_VSEL_MASK                0x0400  /* DC3_HWC_VSEL */
+#define WM831X_DC3_HWC_VSEL_SHIFT                   10  /* DC3_HWC_VSEL */
+#define WM831X_DC3_HWC_VSEL_WIDTH                    1  /* DC3_HWC_VSEL */
+#define WM831X_DC3_HWC_MODE_MASK                0x0300  /* DC3_HWC_MODE - [9:8] */
+#define WM831X_DC3_HWC_MODE_SHIFT                    8  /* DC3_HWC_MODE - [9:8] */
+#define WM831X_DC3_HWC_MODE_WIDTH                    2  /* DC3_HWC_MODE - [9:8] */
+#define WM831X_DC3_OVP                          0x0080  /* DC3_OVP */
+#define WM831X_DC3_OVP_MASK                     0x0080  /* DC3_OVP */
+#define WM831X_DC3_OVP_SHIFT                         7  /* DC3_OVP */
+#define WM831X_DC3_OVP_WIDTH                         1  /* DC3_OVP */
+
+/*
+ * R16482 (0x4062) - DC3 ON Config
+ */
+#define WM831X_DC3_ON_SLOT_MASK                 0xE000  /* DC3_ON_SLOT - [15:13] */
+#define WM831X_DC3_ON_SLOT_SHIFT                    13  /* DC3_ON_SLOT - [15:13] */
+#define WM831X_DC3_ON_SLOT_WIDTH                     3  /* DC3_ON_SLOT - [15:13] */
+#define WM831X_DC3_ON_MODE_MASK                 0x0300  /* DC3_ON_MODE - [9:8] */
+#define WM831X_DC3_ON_MODE_SHIFT                     8  /* DC3_ON_MODE - [9:8] */
+#define WM831X_DC3_ON_MODE_WIDTH                     2  /* DC3_ON_MODE - [9:8] */
+#define WM831X_DC3_ON_VSEL_MASK                 0x007F  /* DC3_ON_VSEL - [6:0] */
+#define WM831X_DC3_ON_VSEL_SHIFT                     0  /* DC3_ON_VSEL - [6:0] */
+#define WM831X_DC3_ON_VSEL_WIDTH                     7  /* DC3_ON_VSEL - [6:0] */
+
+/*
+ * R16483 (0x4063) - DC3 SLEEP Control
+ */
+#define WM831X_DC3_SLP_SLOT_MASK                0xE000  /* DC3_SLP_SLOT - [15:13] */
+#define WM831X_DC3_SLP_SLOT_SHIFT                   13  /* DC3_SLP_SLOT - [15:13] */
+#define WM831X_DC3_SLP_SLOT_WIDTH                    3  /* DC3_SLP_SLOT - [15:13] */
+#define WM831X_DC3_SLP_MODE_MASK                0x0300  /* DC3_SLP_MODE - [9:8] */
+#define WM831X_DC3_SLP_MODE_SHIFT                    8  /* DC3_SLP_MODE - [9:8] */
+#define WM831X_DC3_SLP_MODE_WIDTH                    2  /* DC3_SLP_MODE - [9:8] */
+#define WM831X_DC3_SLP_VSEL_MASK                0x007F  /* DC3_SLP_VSEL - [6:0] */
+#define WM831X_DC3_SLP_VSEL_SHIFT                    0  /* DC3_SLP_VSEL - [6:0] */
+#define WM831X_DC3_SLP_VSEL_WIDTH                    7  /* DC3_SLP_VSEL - [6:0] */
+
+/*
+ * R16484 (0x4064) - DC4 Control
+ */
+#define WM831X_DC4_ERR_ACT_MASK                 0xC000  /* DC4_ERR_ACT - [15:14] */
+#define WM831X_DC4_ERR_ACT_SHIFT                    14  /* DC4_ERR_ACT - [15:14] */
+#define WM831X_DC4_ERR_ACT_WIDTH                     2  /* DC4_ERR_ACT - [15:14] */
+#define WM831X_DC4_HWC_SRC_MASK                 0x1800  /* DC4_HWC_SRC - [12:11] */
+#define WM831X_DC4_HWC_SRC_SHIFT                    11  /* DC4_HWC_SRC - [12:11] */
+#define WM831X_DC4_HWC_SRC_WIDTH                     2  /* DC4_HWC_SRC - [12:11] */
+#define WM831X_DC4_HWC_MODE                     0x0100  /* DC4_HWC_MODE */
+#define WM831X_DC4_HWC_MODE_MASK                0x0100  /* DC4_HWC_MODE */
+#define WM831X_DC4_HWC_MODE_SHIFT                    8  /* DC4_HWC_MODE */
+#define WM831X_DC4_HWC_MODE_WIDTH                    1  /* DC4_HWC_MODE */
+#define WM831X_DC4_RANGE_MASK                   0x000C  /* DC4_RANGE - [3:2] */
+#define WM831X_DC4_RANGE_SHIFT                       2  /* DC4_RANGE - [3:2] */
+#define WM831X_DC4_RANGE_WIDTH                       2  /* DC4_RANGE - [3:2] */
+#define WM831X_DC4_FBSRC                        0x0001  /* DC4_FBSRC */
+#define WM831X_DC4_FBSRC_MASK                   0x0001  /* DC4_FBSRC */
+#define WM831X_DC4_FBSRC_SHIFT                       0  /* DC4_FBSRC */
+#define WM831X_DC4_FBSRC_WIDTH                       1  /* DC4_FBSRC */
+
+/*
+ * R16485 (0x4065) - DC4 SLEEP Control
+ */
+#define WM831X_DC4_SLPENA                       0x0100  /* DC4_SLPENA */
+#define WM831X_DC4_SLPENA_MASK                  0x0100  /* DC4_SLPENA */
+#define WM831X_DC4_SLPENA_SHIFT                      8  /* DC4_SLPENA */
+#define WM831X_DC4_SLPENA_WIDTH                      1  /* DC4_SLPENA */
+
+/*
+ * R16488 (0x4068) - LDO1 Control
+ */
+#define WM831X_LDO1_ERR_ACT_MASK                0xC000  /* LDO1_ERR_ACT - [15:14] */
+#define WM831X_LDO1_ERR_ACT_SHIFT                   14  /* LDO1_ERR_ACT - [15:14] */
+#define WM831X_LDO1_ERR_ACT_WIDTH                    2  /* LDO1_ERR_ACT - [15:14] */
+#define WM831X_LDO1_HWC_SRC_MASK                0x1800  /* LDO1_HWC_SRC - [12:11] */
+#define WM831X_LDO1_HWC_SRC_SHIFT                   11  /* LDO1_HWC_SRC - [12:11] */
+#define WM831X_LDO1_HWC_SRC_WIDTH                    2  /* LDO1_HWC_SRC - [12:11] */
+#define WM831X_LDO1_HWC_VSEL                    0x0400  /* LDO1_HWC_VSEL */
+#define WM831X_LDO1_HWC_VSEL_MASK               0x0400  /* LDO1_HWC_VSEL */
+#define WM831X_LDO1_HWC_VSEL_SHIFT                  10  /* LDO1_HWC_VSEL */
+#define WM831X_LDO1_HWC_VSEL_WIDTH                   1  /* LDO1_HWC_VSEL */
+#define WM831X_LDO1_HWC_MODE_MASK               0x0300  /* LDO1_HWC_MODE - [9:8] */
+#define WM831X_LDO1_HWC_MODE_SHIFT                   8  /* LDO1_HWC_MODE - [9:8] */
+#define WM831X_LDO1_HWC_MODE_WIDTH                   2  /* LDO1_HWC_MODE - [9:8] */
+#define WM831X_LDO1_FLT                         0x0080  /* LDO1_FLT */
+#define WM831X_LDO1_FLT_MASK                    0x0080  /* LDO1_FLT */
+#define WM831X_LDO1_FLT_SHIFT                        7  /* LDO1_FLT */
+#define WM831X_LDO1_FLT_WIDTH                        1  /* LDO1_FLT */
+#define WM831X_LDO1_SWI                         0x0040  /* LDO1_SWI */
+#define WM831X_LDO1_SWI_MASK                    0x0040  /* LDO1_SWI */
+#define WM831X_LDO1_SWI_SHIFT                        6  /* LDO1_SWI */
+#define WM831X_LDO1_SWI_WIDTH                        1  /* LDO1_SWI */
+#define WM831X_LDO1_LP_MODE                     0x0001  /* LDO1_LP_MODE */
+#define WM831X_LDO1_LP_MODE_MASK                0x0001  /* LDO1_LP_MODE */
+#define WM831X_LDO1_LP_MODE_SHIFT                    0  /* LDO1_LP_MODE */
+#define WM831X_LDO1_LP_MODE_WIDTH                    1  /* LDO1_LP_MODE */
+
+/*
+ * R16489 (0x4069) - LDO1 ON Control
+ */
+#define WM831X_LDO1_ON_SLOT_MASK                0xE000  /* LDO1_ON_SLOT - [15:13] */
+#define WM831X_LDO1_ON_SLOT_SHIFT                   13  /* LDO1_ON_SLOT - [15:13] */
+#define WM831X_LDO1_ON_SLOT_WIDTH                    3  /* LDO1_ON_SLOT - [15:13] */
+#define WM831X_LDO1_ON_MODE                     0x0100  /* LDO1_ON_MODE */
+#define WM831X_LDO1_ON_MODE_MASK                0x0100  /* LDO1_ON_MODE */
+#define WM831X_LDO1_ON_MODE_SHIFT                    8  /* LDO1_ON_MODE */
+#define WM831X_LDO1_ON_MODE_WIDTH                    1  /* LDO1_ON_MODE */
+#define WM831X_LDO1_ON_VSEL_MASK                0x001F  /* LDO1_ON_VSEL - [4:0] */
+#define WM831X_LDO1_ON_VSEL_SHIFT                    0  /* LDO1_ON_VSEL - [4:0] */
+#define WM831X_LDO1_ON_VSEL_WIDTH                    5  /* LDO1_ON_VSEL - [4:0] */
+
+/*
+ * R16490 (0x406A) - LDO1 SLEEP Control
+ */
+#define WM831X_LDO1_SLP_SLOT_MASK               0xE000  /* LDO1_SLP_SLOT - [15:13] */
+#define WM831X_LDO1_SLP_SLOT_SHIFT                  13  /* LDO1_SLP_SLOT - [15:13] */
+#define WM831X_LDO1_SLP_SLOT_WIDTH                   3  /* LDO1_SLP_SLOT - [15:13] */
+#define WM831X_LDO1_SLP_MODE                    0x0100  /* LDO1_SLP_MODE */
+#define WM831X_LDO1_SLP_MODE_MASK               0x0100  /* LDO1_SLP_MODE */
+#define WM831X_LDO1_SLP_MODE_SHIFT                   8  /* LDO1_SLP_MODE */
+#define WM831X_LDO1_SLP_MODE_WIDTH                   1  /* LDO1_SLP_MODE */
+#define WM831X_LDO1_SLP_VSEL_MASK               0x001F  /* LDO1_SLP_VSEL - [4:0] */
+#define WM831X_LDO1_SLP_VSEL_SHIFT                   0  /* LDO1_SLP_VSEL - [4:0] */
+#define WM831X_LDO1_SLP_VSEL_WIDTH                   5  /* LDO1_SLP_VSEL - [4:0] */
+
+/*
+ * R16491 (0x406B) - LDO2 Control
+ */
+#define WM831X_LDO2_ERR_ACT_MASK                0xC000  /* LDO2_ERR_ACT - [15:14] */
+#define WM831X_LDO2_ERR_ACT_SHIFT                   14  /* LDO2_ERR_ACT - [15:14] */
+#define WM831X_LDO2_ERR_ACT_WIDTH                    2  /* LDO2_ERR_ACT - [15:14] */
+#define WM831X_LDO2_HWC_SRC_MASK                0x1800  /* LDO2_HWC_SRC - [12:11] */
+#define WM831X_LDO2_HWC_SRC_SHIFT                   11  /* LDO2_HWC_SRC - [12:11] */
+#define WM831X_LDO2_HWC_SRC_WIDTH                    2  /* LDO2_HWC_SRC - [12:11] */
+#define WM831X_LDO2_HWC_VSEL                    0x0400  /* LDO2_HWC_VSEL */
+#define WM831X_LDO2_HWC_VSEL_MASK               0x0400  /* LDO2_HWC_VSEL */
+#define WM831X_LDO2_HWC_VSEL_SHIFT                  10  /* LDO2_HWC_VSEL */
+#define WM831X_LDO2_HWC_VSEL_WIDTH                   1  /* LDO2_HWC_VSEL */
+#define WM831X_LDO2_HWC_MODE_MASK               0x0300  /* LDO2_HWC_MODE - [9:8] */
+#define WM831X_LDO2_HWC_MODE_SHIFT                   8  /* LDO2_HWC_MODE - [9:8] */
+#define WM831X_LDO2_HWC_MODE_WIDTH                   2  /* LDO2_HWC_MODE - [9:8] */
+#define WM831X_LDO2_FLT                         0x0080  /* LDO2_FLT */
+#define WM831X_LDO2_FLT_MASK                    0x0080  /* LDO2_FLT */
+#define WM831X_LDO2_FLT_SHIFT                        7  /* LDO2_FLT */
+#define WM831X_LDO2_FLT_WIDTH                        1  /* LDO2_FLT */
+#define WM831X_LDO2_SWI                         0x0040  /* LDO2_SWI */
+#define WM831X_LDO2_SWI_MASK                    0x0040  /* LDO2_SWI */
+#define WM831X_LDO2_SWI_SHIFT                        6  /* LDO2_SWI */
+#define WM831X_LDO2_SWI_WIDTH                        1  /* LDO2_SWI */
+#define WM831X_LDO2_LP_MODE                     0x0001  /* LDO2_LP_MODE */
+#define WM831X_LDO2_LP_MODE_MASK                0x0001  /* LDO2_LP_MODE */
+#define WM831X_LDO2_LP_MODE_SHIFT                    0  /* LDO2_LP_MODE */
+#define WM831X_LDO2_LP_MODE_WIDTH                    1  /* LDO2_LP_MODE */
+
+/*
+ * R16492 (0x406C) - LDO2 ON Control
+ */
+#define WM831X_LDO2_ON_SLOT_MASK                0xE000  /* LDO2_ON_SLOT - [15:13] */
+#define WM831X_LDO2_ON_SLOT_SHIFT                   13  /* LDO2_ON_SLOT - [15:13] */
+#define WM831X_LDO2_ON_SLOT_WIDTH                    3  /* LDO2_ON_SLOT - [15:13] */
+#define WM831X_LDO2_ON_MODE                     0x0100  /* LDO2_ON_MODE */
+#define WM831X_LDO2_ON_MODE_MASK                0x0100  /* LDO2_ON_MODE */
+#define WM831X_LDO2_ON_MODE_SHIFT                    8  /* LDO2_ON_MODE */
+#define WM831X_LDO2_ON_MODE_WIDTH                    1  /* LDO2_ON_MODE */
+#define WM831X_LDO2_ON_VSEL_MASK                0x001F  /* LDO2_ON_VSEL - [4:0] */
+#define WM831X_LDO2_ON_VSEL_SHIFT                    0  /* LDO2_ON_VSEL - [4:0] */
+#define WM831X_LDO2_ON_VSEL_WIDTH                    5  /* LDO2_ON_VSEL - [4:0] */
+
+/*
+ * R16493 (0x406D) - LDO2 SLEEP Control
+ */
+#define WM831X_LDO2_SLP_SLOT_MASK               0xE000  /* LDO2_SLP_SLOT - [15:13] */
+#define WM831X_LDO2_SLP_SLOT_SHIFT                  13  /* LDO2_SLP_SLOT - [15:13] */
+#define WM831X_LDO2_SLP_SLOT_WIDTH                   3  /* LDO2_SLP_SLOT - [15:13] */
+#define WM831X_LDO2_SLP_MODE                    0x0100  /* LDO2_SLP_MODE */
+#define WM831X_LDO2_SLP_MODE_MASK               0x0100  /* LDO2_SLP_MODE */
+#define WM831X_LDO2_SLP_MODE_SHIFT                   8  /* LDO2_SLP_MODE */
+#define WM831X_LDO2_SLP_MODE_WIDTH                   1  /* LDO2_SLP_MODE */
+#define WM831X_LDO2_SLP_VSEL_MASK               0x001F  /* LDO2_SLP_VSEL - [4:0] */
+#define WM831X_LDO2_SLP_VSEL_SHIFT                   0  /* LDO2_SLP_VSEL - [4:0] */
+#define WM831X_LDO2_SLP_VSEL_WIDTH                   5  /* LDO2_SLP_VSEL - [4:0] */
+
+/*
+ * R16494 (0x406E) - LDO3 Control
+ */
+#define WM831X_LDO3_ERR_ACT_MASK                0xC000  /* LDO3_ERR_ACT - [15:14] */
+#define WM831X_LDO3_ERR_ACT_SHIFT                   14  /* LDO3_ERR_ACT - [15:14] */
+#define WM831X_LDO3_ERR_ACT_WIDTH                    2  /* LDO3_ERR_ACT - [15:14] */
+#define WM831X_LDO3_HWC_SRC_MASK                0x1800  /* LDO3_HWC_SRC - [12:11] */
+#define WM831X_LDO3_HWC_SRC_SHIFT                   11  /* LDO3_HWC_SRC - [12:11] */
+#define WM831X_LDO3_HWC_SRC_WIDTH                    2  /* LDO3_HWC_SRC - [12:11] */
+#define WM831X_LDO3_HWC_VSEL                    0x0400  /* LDO3_HWC_VSEL */
+#define WM831X_LDO3_HWC_VSEL_MASK               0x0400  /* LDO3_HWC_VSEL */
+#define WM831X_LDO3_HWC_VSEL_SHIFT                  10  /* LDO3_HWC_VSEL */
+#define WM831X_LDO3_HWC_VSEL_WIDTH                   1  /* LDO3_HWC_VSEL */
+#define WM831X_LDO3_HWC_MODE_MASK               0x0300  /* LDO3_HWC_MODE - [9:8] */
+#define WM831X_LDO3_HWC_MODE_SHIFT                   8  /* LDO3_HWC_MODE - [9:8] */
+#define WM831X_LDO3_HWC_MODE_WIDTH                   2  /* LDO3_HWC_MODE - [9:8] */
+#define WM831X_LDO3_FLT                         0x0080  /* LDO3_FLT */
+#define WM831X_LDO3_FLT_MASK                    0x0080  /* LDO3_FLT */
+#define WM831X_LDO3_FLT_SHIFT                        7  /* LDO3_FLT */
+#define WM831X_LDO3_FLT_WIDTH                        1  /* LDO3_FLT */
+#define WM831X_LDO3_SWI                         0x0040  /* LDO3_SWI */
+#define WM831X_LDO3_SWI_MASK                    0x0040  /* LDO3_SWI */
+#define WM831X_LDO3_SWI_SHIFT                        6  /* LDO3_SWI */
+#define WM831X_LDO3_SWI_WIDTH                        1  /* LDO3_SWI */
+#define WM831X_LDO3_LP_MODE                     0x0001  /* LDO3_LP_MODE */
+#define WM831X_LDO3_LP_MODE_MASK                0x0001  /* LDO3_LP_MODE */
+#define WM831X_LDO3_LP_MODE_SHIFT                    0  /* LDO3_LP_MODE */
+#define WM831X_LDO3_LP_MODE_WIDTH                    1  /* LDO3_LP_MODE */
+
+/*
+ * R16495 (0x406F) - LDO3 ON Control
+ */
+#define WM831X_LDO3_ON_SLOT_MASK                0xE000  /* LDO3_ON_SLOT - [15:13] */
+#define WM831X_LDO3_ON_SLOT_SHIFT                   13  /* LDO3_ON_SLOT - [15:13] */
+#define WM831X_LDO3_ON_SLOT_WIDTH                    3  /* LDO3_ON_SLOT - [15:13] */
+#define WM831X_LDO3_ON_MODE                     0x0100  /* LDO3_ON_MODE */
+#define WM831X_LDO3_ON_MODE_MASK                0x0100  /* LDO3_ON_MODE */
+#define WM831X_LDO3_ON_MODE_SHIFT                    8  /* LDO3_ON_MODE */
+#define WM831X_LDO3_ON_MODE_WIDTH                    1  /* LDO3_ON_MODE */
+#define WM831X_LDO3_ON_VSEL_MASK                0x001F  /* LDO3_ON_VSEL - [4:0] */
+#define WM831X_LDO3_ON_VSEL_SHIFT                    0  /* LDO3_ON_VSEL - [4:0] */
+#define WM831X_LDO3_ON_VSEL_WIDTH                    5  /* LDO3_ON_VSEL - [4:0] */
+
+/*
+ * R16496 (0x4070) - LDO3 SLEEP Control
+ */
+#define WM831X_LDO3_SLP_SLOT_MASK               0xE000  /* LDO3_SLP_SLOT - [15:13] */
+#define WM831X_LDO3_SLP_SLOT_SHIFT                  13  /* LDO3_SLP_SLOT - [15:13] */
+#define WM831X_LDO3_SLP_SLOT_WIDTH                   3  /* LDO3_SLP_SLOT - [15:13] */
+#define WM831X_LDO3_SLP_MODE                    0x0100  /* LDO3_SLP_MODE */
+#define WM831X_LDO3_SLP_MODE_MASK               0x0100  /* LDO3_SLP_MODE */
+#define WM831X_LDO3_SLP_MODE_SHIFT                   8  /* LDO3_SLP_MODE */
+#define WM831X_LDO3_SLP_MODE_WIDTH                   1  /* LDO3_SLP_MODE */
+#define WM831X_LDO3_SLP_VSEL_MASK               0x001F  /* LDO3_SLP_VSEL - [4:0] */
+#define WM831X_LDO3_SLP_VSEL_SHIFT                   0  /* LDO3_SLP_VSEL - [4:0] */
+#define WM831X_LDO3_SLP_VSEL_WIDTH                   5  /* LDO3_SLP_VSEL - [4:0] */
+
+/*
+ * R16497 (0x4071) - LDO4 Control
+ */
+#define WM831X_LDO4_ERR_ACT_MASK                0xC000  /* LDO4_ERR_ACT - [15:14] */
+#define WM831X_LDO4_ERR_ACT_SHIFT                   14  /* LDO4_ERR_ACT - [15:14] */
+#define WM831X_LDO4_ERR_ACT_WIDTH                    2  /* LDO4_ERR_ACT - [15:14] */
+#define WM831X_LDO4_HWC_SRC_MASK                0x1800  /* LDO4_HWC_SRC - [12:11] */
+#define WM831X_LDO4_HWC_SRC_SHIFT                   11  /* LDO4_HWC_SRC - [12:11] */
+#define WM831X_LDO4_HWC_SRC_WIDTH                    2  /* LDO4_HWC_SRC - [12:11] */
+#define WM831X_LDO4_HWC_VSEL                    0x0400  /* LDO4_HWC_VSEL */
+#define WM831X_LDO4_HWC_VSEL_MASK               0x0400  /* LDO4_HWC_VSEL */
+#define WM831X_LDO4_HWC_VSEL_SHIFT                  10  /* LDO4_HWC_VSEL */
+#define WM831X_LDO4_HWC_VSEL_WIDTH                   1  /* LDO4_HWC_VSEL */
+#define WM831X_LDO4_HWC_MODE_MASK               0x0300  /* LDO4_HWC_MODE - [9:8] */
+#define WM831X_LDO4_HWC_MODE_SHIFT                   8  /* LDO4_HWC_MODE - [9:8] */
+#define WM831X_LDO4_HWC_MODE_WIDTH                   2  /* LDO4_HWC_MODE - [9:8] */
+#define WM831X_LDO4_FLT                         0x0080  /* LDO4_FLT */
+#define WM831X_LDO4_FLT_MASK                    0x0080  /* LDO4_FLT */
+#define WM831X_LDO4_FLT_SHIFT                        7  /* LDO4_FLT */
+#define WM831X_LDO4_FLT_WIDTH                        1  /* LDO4_FLT */
+#define WM831X_LDO4_SWI                         0x0040  /* LDO4_SWI */
+#define WM831X_LDO4_SWI_MASK                    0x0040  /* LDO4_SWI */
+#define WM831X_LDO4_SWI_SHIFT                        6  /* LDO4_SWI */
+#define WM831X_LDO4_SWI_WIDTH                        1  /* LDO4_SWI */
+#define WM831X_LDO4_LP_MODE                     0x0001  /* LDO4_LP_MODE */
+#define WM831X_LDO4_LP_MODE_MASK                0x0001  /* LDO4_LP_MODE */
+#define WM831X_LDO4_LP_MODE_SHIFT                    0  /* LDO4_LP_MODE */
+#define WM831X_LDO4_LP_MODE_WIDTH                    1  /* LDO4_LP_MODE */
+
+/*
+ * R16498 (0x4072) - LDO4 ON Control
+ */
+#define WM831X_LDO4_ON_SLOT_MASK                0xE000  /* LDO4_ON_SLOT - [15:13] */
+#define WM831X_LDO4_ON_SLOT_SHIFT                   13  /* LDO4_ON_SLOT - [15:13] */
+#define WM831X_LDO4_ON_SLOT_WIDTH                    3  /* LDO4_ON_SLOT - [15:13] */
+#define WM831X_LDO4_ON_MODE                     0x0100  /* LDO4_ON_MODE */
+#define WM831X_LDO4_ON_MODE_MASK                0x0100  /* LDO4_ON_MODE */
+#define WM831X_LDO4_ON_MODE_SHIFT                    8  /* LDO4_ON_MODE */
+#define WM831X_LDO4_ON_MODE_WIDTH                    1  /* LDO4_ON_MODE */
+#define WM831X_LDO4_ON_VSEL_MASK                0x001F  /* LDO4_ON_VSEL - [4:0] */
+#define WM831X_LDO4_ON_VSEL_SHIFT                    0  /* LDO4_ON_VSEL - [4:0] */
+#define WM831X_LDO4_ON_VSEL_WIDTH                    5  /* LDO4_ON_VSEL - [4:0] */
+
+/*
+ * R16499 (0x4073) - LDO4 SLEEP Control
+ */
+#define WM831X_LDO4_SLP_SLOT_MASK               0xE000  /* LDO4_SLP_SLOT - [15:13] */
+#define WM831X_LDO4_SLP_SLOT_SHIFT                  13  /* LDO4_SLP_SLOT - [15:13] */
+#define WM831X_LDO4_SLP_SLOT_WIDTH                   3  /* LDO4_SLP_SLOT - [15:13] */
+#define WM831X_LDO4_SLP_MODE                    0x0100  /* LDO4_SLP_MODE */
+#define WM831X_LDO4_SLP_MODE_MASK               0x0100  /* LDO4_SLP_MODE */
+#define WM831X_LDO4_SLP_MODE_SHIFT                   8  /* LDO4_SLP_MODE */
+#define WM831X_LDO4_SLP_MODE_WIDTH                   1  /* LDO4_SLP_MODE */
+#define WM831X_LDO4_SLP_VSEL_MASK               0x001F  /* LDO4_SLP_VSEL - [4:0] */
+#define WM831X_LDO4_SLP_VSEL_SHIFT                   0  /* LDO4_SLP_VSEL - [4:0] */
+#define WM831X_LDO4_SLP_VSEL_WIDTH                   5  /* LDO4_SLP_VSEL - [4:0] */
+
+/*
+ * R16500 (0x4074) - LDO5 Control
+ */
+#define WM831X_LDO5_ERR_ACT_MASK                0xC000  /* LDO5_ERR_ACT - [15:14] */
+#define WM831X_LDO5_ERR_ACT_SHIFT                   14  /* LDO5_ERR_ACT - [15:14] */
+#define WM831X_LDO5_ERR_ACT_WIDTH                    2  /* LDO5_ERR_ACT - [15:14] */
+#define WM831X_LDO5_HWC_SRC_MASK                0x1800  /* LDO5_HWC_SRC - [12:11] */
+#define WM831X_LDO5_HWC_SRC_SHIFT                   11  /* LDO5_HWC_SRC - [12:11] */
+#define WM831X_LDO5_HWC_SRC_WIDTH                    2  /* LDO5_HWC_SRC - [12:11] */
+#define WM831X_LDO5_HWC_VSEL                    0x0400  /* LDO5_HWC_VSEL */
+#define WM831X_LDO5_HWC_VSEL_MASK               0x0400  /* LDO5_HWC_VSEL */
+#define WM831X_LDO5_HWC_VSEL_SHIFT                  10  /* LDO5_HWC_VSEL */
+#define WM831X_LDO5_HWC_VSEL_WIDTH                   1  /* LDO5_HWC_VSEL */
+#define WM831X_LDO5_HWC_MODE_MASK               0x0300  /* LDO5_HWC_MODE - [9:8] */
+#define WM831X_LDO5_HWC_MODE_SHIFT                   8  /* LDO5_HWC_MODE - [9:8] */
+#define WM831X_LDO5_HWC_MODE_WIDTH                   2  /* LDO5_HWC_MODE - [9:8] */
+#define WM831X_LDO5_FLT                         0x0080  /* LDO5_FLT */
+#define WM831X_LDO5_FLT_MASK                    0x0080  /* LDO5_FLT */
+#define WM831X_LDO5_FLT_SHIFT                        7  /* LDO5_FLT */
+#define WM831X_LDO5_FLT_WIDTH                        1  /* LDO5_FLT */
+#define WM831X_LDO5_SWI                         0x0040  /* LDO5_SWI */
+#define WM831X_LDO5_SWI_MASK                    0x0040  /* LDO5_SWI */
+#define WM831X_LDO5_SWI_SHIFT                        6  /* LDO5_SWI */
+#define WM831X_LDO5_SWI_WIDTH                        1  /* LDO5_SWI */
+#define WM831X_LDO5_LP_MODE                     0x0001  /* LDO5_LP_MODE */
+#define WM831X_LDO5_LP_MODE_MASK                0x0001  /* LDO5_LP_MODE */
+#define WM831X_LDO5_LP_MODE_SHIFT                    0  /* LDO5_LP_MODE */
+#define WM831X_LDO5_LP_MODE_WIDTH                    1  /* LDO5_LP_MODE */
+
+/*
+ * R16501 (0x4075) - LDO5 ON Control
+ */
+#define WM831X_LDO5_ON_SLOT_MASK                0xE000  /* LDO5_ON_SLOT - [15:13] */
+#define WM831X_LDO5_ON_SLOT_SHIFT                   13  /* LDO5_ON_SLOT - [15:13] */
+#define WM831X_LDO5_ON_SLOT_WIDTH                    3  /* LDO5_ON_SLOT - [15:13] */
+#define WM831X_LDO5_ON_MODE                     0x0100  /* LDO5_ON_MODE */
+#define WM831X_LDO5_ON_MODE_MASK                0x0100  /* LDO5_ON_MODE */
+#define WM831X_LDO5_ON_MODE_SHIFT                    8  /* LDO5_ON_MODE */
+#define WM831X_LDO5_ON_MODE_WIDTH                    1  /* LDO5_ON_MODE */
+#define WM831X_LDO5_ON_VSEL_MASK                0x001F  /* LDO5_ON_VSEL - [4:0] */
+#define WM831X_LDO5_ON_VSEL_SHIFT                    0  /* LDO5_ON_VSEL - [4:0] */
+#define WM831X_LDO5_ON_VSEL_WIDTH                    5  /* LDO5_ON_VSEL - [4:0] */
+
+/*
+ * R16502 (0x4076) - LDO5 SLEEP Control
+ */
+#define WM831X_LDO5_SLP_SLOT_MASK               0xE000  /* LDO5_SLP_SLOT - [15:13] */
+#define WM831X_LDO5_SLP_SLOT_SHIFT                  13  /* LDO5_SLP_SLOT - [15:13] */
+#define WM831X_LDO5_SLP_SLOT_WIDTH                   3  /* LDO5_SLP_SLOT - [15:13] */
+#define WM831X_LDO5_SLP_MODE                    0x0100  /* LDO5_SLP_MODE */
+#define WM831X_LDO5_SLP_MODE_MASK               0x0100  /* LDO5_SLP_MODE */
+#define WM831X_LDO5_SLP_MODE_SHIFT                   8  /* LDO5_SLP_MODE */
+#define WM831X_LDO5_SLP_MODE_WIDTH                   1  /* LDO5_SLP_MODE */
+#define WM831X_LDO5_SLP_VSEL_MASK               0x001F  /* LDO5_SLP_VSEL - [4:0] */
+#define WM831X_LDO5_SLP_VSEL_SHIFT                   0  /* LDO5_SLP_VSEL - [4:0] */
+#define WM831X_LDO5_SLP_VSEL_WIDTH                   5  /* LDO5_SLP_VSEL - [4:0] */
+
+/*
+ * R16503 (0x4077) - LDO6 Control
+ */
+#define WM831X_LDO6_ERR_ACT_MASK                0xC000  /* LDO6_ERR_ACT - [15:14] */
+#define WM831X_LDO6_ERR_ACT_SHIFT                   14  /* LDO6_ERR_ACT - [15:14] */
+#define WM831X_LDO6_ERR_ACT_WIDTH                    2  /* LDO6_ERR_ACT - [15:14] */
+#define WM831X_LDO6_HWC_SRC_MASK                0x1800  /* LDO6_HWC_SRC - [12:11] */
+#define WM831X_LDO6_HWC_SRC_SHIFT                   11  /* LDO6_HWC_SRC - [12:11] */
+#define WM831X_LDO6_HWC_SRC_WIDTH                    2  /* LDO6_HWC_SRC - [12:11] */
+#define WM831X_LDO6_HWC_VSEL                    0x0400  /* LDO6_HWC_VSEL */
+#define WM831X_LDO6_HWC_VSEL_MASK               0x0400  /* LDO6_HWC_VSEL */
+#define WM831X_LDO6_HWC_VSEL_SHIFT                  10  /* LDO6_HWC_VSEL */
+#define WM831X_LDO6_HWC_VSEL_WIDTH                   1  /* LDO6_HWC_VSEL */
+#define WM831X_LDO6_HWC_MODE_MASK               0x0300  /* LDO6_HWC_MODE - [9:8] */
+#define WM831X_LDO6_HWC_MODE_SHIFT                   8  /* LDO6_HWC_MODE - [9:8] */
+#define WM831X_LDO6_HWC_MODE_WIDTH                   2  /* LDO6_HWC_MODE - [9:8] */
+#define WM831X_LDO6_FLT                         0x0080  /* LDO6_FLT */
+#define WM831X_LDO6_FLT_MASK                    0x0080  /* LDO6_FLT */
+#define WM831X_LDO6_FLT_SHIFT                        7  /* LDO6_FLT */
+#define WM831X_LDO6_FLT_WIDTH                        1  /* LDO6_FLT */
+#define WM831X_LDO6_SWI                         0x0040  /* LDO6_SWI */
+#define WM831X_LDO6_SWI_MASK                    0x0040  /* LDO6_SWI */
+#define WM831X_LDO6_SWI_SHIFT                        6  /* LDO6_SWI */
+#define WM831X_LDO6_SWI_WIDTH                        1  /* LDO6_SWI */
+#define WM831X_LDO6_LP_MODE                     0x0001  /* LDO6_LP_MODE */
+#define WM831X_LDO6_LP_MODE_MASK                0x0001  /* LDO6_LP_MODE */
+#define WM831X_LDO6_LP_MODE_SHIFT                    0  /* LDO6_LP_MODE */
+#define WM831X_LDO6_LP_MODE_WIDTH                    1  /* LDO6_LP_MODE */
+
+/*
+ * R16504 (0x4078) - LDO6 ON Control
+ */
+#define WM831X_LDO6_ON_SLOT_MASK                0xE000  /* LDO6_ON_SLOT - [15:13] */
+#define WM831X_LDO6_ON_SLOT_SHIFT                   13  /* LDO6_ON_SLOT - [15:13] */
+#define WM831X_LDO6_ON_SLOT_WIDTH                    3  /* LDO6_ON_SLOT - [15:13] */
+#define WM831X_LDO6_ON_MODE                     0x0100  /* LDO6_ON_MODE */
+#define WM831X_LDO6_ON_MODE_MASK                0x0100  /* LDO6_ON_MODE */
+#define WM831X_LDO6_ON_MODE_SHIFT                    8  /* LDO6_ON_MODE */
+#define WM831X_LDO6_ON_MODE_WIDTH                    1  /* LDO6_ON_MODE */
+#define WM831X_LDO6_ON_VSEL_MASK                0x001F  /* LDO6_ON_VSEL - [4:0] */
+#define WM831X_LDO6_ON_VSEL_SHIFT                    0  /* LDO6_ON_VSEL - [4:0] */
+#define WM831X_LDO6_ON_VSEL_WIDTH                    5  /* LDO6_ON_VSEL - [4:0] */
+
+/*
+ * R16505 (0x4079) - LDO6 SLEEP Control
+ */
+#define WM831X_LDO6_SLP_SLOT_MASK               0xE000  /* LDO6_SLP_SLOT - [15:13] */
+#define WM831X_LDO6_SLP_SLOT_SHIFT                  13  /* LDO6_SLP_SLOT - [15:13] */
+#define WM831X_LDO6_SLP_SLOT_WIDTH                   3  /* LDO6_SLP_SLOT - [15:13] */
+#define WM831X_LDO6_SLP_MODE                    0x0100  /* LDO6_SLP_MODE */
+#define WM831X_LDO6_SLP_MODE_MASK               0x0100  /* LDO6_SLP_MODE */
+#define WM831X_LDO6_SLP_MODE_SHIFT                   8  /* LDO6_SLP_MODE */
+#define WM831X_LDO6_SLP_MODE_WIDTH                   1  /* LDO6_SLP_MODE */
+#define WM831X_LDO6_SLP_VSEL_MASK               0x001F  /* LDO6_SLP_VSEL - [4:0] */
+#define WM831X_LDO6_SLP_VSEL_SHIFT                   0  /* LDO6_SLP_VSEL - [4:0] */
+#define WM831X_LDO6_SLP_VSEL_WIDTH                   5  /* LDO6_SLP_VSEL - [4:0] */
+
+/*
+ * R16506 (0x407A) - LDO7 Control
+ */
+#define WM831X_LDO7_ERR_ACT_MASK                0xC000  /* LDO7_ERR_ACT - [15:14] */
+#define WM831X_LDO7_ERR_ACT_SHIFT                   14  /* LDO7_ERR_ACT - [15:14] */
+#define WM831X_LDO7_ERR_ACT_WIDTH                    2  /* LDO7_ERR_ACT - [15:14] */
+#define WM831X_LDO7_HWC_SRC_MASK                0x1800  /* LDO7_HWC_SRC - [12:11] */
+#define WM831X_LDO7_HWC_SRC_SHIFT                   11  /* LDO7_HWC_SRC - [12:11] */
+#define WM831X_LDO7_HWC_SRC_WIDTH                    2  /* LDO7_HWC_SRC - [12:11] */
+#define WM831X_LDO7_HWC_VSEL                    0x0400  /* LDO7_HWC_VSEL */
+#define WM831X_LDO7_HWC_VSEL_MASK               0x0400  /* LDO7_HWC_VSEL */
+#define WM831X_LDO7_HWC_VSEL_SHIFT                  10  /* LDO7_HWC_VSEL */
+#define WM831X_LDO7_HWC_VSEL_WIDTH                   1  /* LDO7_HWC_VSEL */
+#define WM831X_LDO7_HWC_MODE_MASK               0x0300  /* LDO7_HWC_MODE - [9:8] */
+#define WM831X_LDO7_HWC_MODE_SHIFT                   8  /* LDO7_HWC_MODE - [9:8] */
+#define WM831X_LDO7_HWC_MODE_WIDTH                   2  /* LDO7_HWC_MODE - [9:8] */
+#define WM831X_LDO7_FLT                         0x0080  /* LDO7_FLT */
+#define WM831X_LDO7_FLT_MASK                    0x0080  /* LDO7_FLT */
+#define WM831X_LDO7_FLT_SHIFT                        7  /* LDO7_FLT */
+#define WM831X_LDO7_FLT_WIDTH                        1  /* LDO7_FLT */
+#define WM831X_LDO7_SWI                         0x0040  /* LDO7_SWI */
+#define WM831X_LDO7_SWI_MASK                    0x0040  /* LDO7_SWI */
+#define WM831X_LDO7_SWI_SHIFT                        6  /* LDO7_SWI */
+#define WM831X_LDO7_SWI_WIDTH                        1  /* LDO7_SWI */
+
+/*
+ * R16507 (0x407B) - LDO7 ON Control
+ */
+#define WM831X_LDO7_ON_SLOT_MASK                0xE000  /* LDO7_ON_SLOT - [15:13] */
+#define WM831X_LDO7_ON_SLOT_SHIFT                   13  /* LDO7_ON_SLOT - [15:13] */
+#define WM831X_LDO7_ON_SLOT_WIDTH                    3  /* LDO7_ON_SLOT - [15:13] */
+#define WM831X_LDO7_ON_MODE                     0x0100  /* LDO7_ON_MODE */
+#define WM831X_LDO7_ON_MODE_MASK                0x0100  /* LDO7_ON_MODE */
+#define WM831X_LDO7_ON_MODE_SHIFT                    8  /* LDO7_ON_MODE */
+#define WM831X_LDO7_ON_MODE_WIDTH                    1  /* LDO7_ON_MODE */
+#define WM831X_LDO7_ON_VSEL_MASK                0x001F  /* LDO7_ON_VSEL - [4:0] */
+#define WM831X_LDO7_ON_VSEL_SHIFT                    0  /* LDO7_ON_VSEL - [4:0] */
+#define WM831X_LDO7_ON_VSEL_WIDTH                    5  /* LDO7_ON_VSEL - [4:0] */
+
+/*
+ * R16508 (0x407C) - LDO7 SLEEP Control
+ */
+#define WM831X_LDO7_SLP_SLOT_MASK               0xE000  /* LDO7_SLP_SLOT - [15:13] */
+#define WM831X_LDO7_SLP_SLOT_SHIFT                  13  /* LDO7_SLP_SLOT - [15:13] */
+#define WM831X_LDO7_SLP_SLOT_WIDTH                   3  /* LDO7_SLP_SLOT - [15:13] */
+#define WM831X_LDO7_SLP_MODE                    0x0100  /* LDO7_SLP_MODE */
+#define WM831X_LDO7_SLP_MODE_MASK               0x0100  /* LDO7_SLP_MODE */
+#define WM831X_LDO7_SLP_MODE_SHIFT                   8  /* LDO7_SLP_MODE */
+#define WM831X_LDO7_SLP_MODE_WIDTH                   1  /* LDO7_SLP_MODE */
+#define WM831X_LDO7_SLP_VSEL_MASK               0x001F  /* LDO7_SLP_VSEL - [4:0] */
+#define WM831X_LDO7_SLP_VSEL_SHIFT                   0  /* LDO7_SLP_VSEL - [4:0] */
+#define WM831X_LDO7_SLP_VSEL_WIDTH                   5  /* LDO7_SLP_VSEL - [4:0] */
+
+/*
+ * R16509 (0x407D) - LDO8 Control
+ */
+#define WM831X_LDO8_ERR_ACT_MASK                0xC000  /* LDO8_ERR_ACT - [15:14] */
+#define WM831X_LDO8_ERR_ACT_SHIFT                   14  /* LDO8_ERR_ACT - [15:14] */
+#define WM831X_LDO8_ERR_ACT_WIDTH                    2  /* LDO8_ERR_ACT - [15:14] */
+#define WM831X_LDO8_HWC_SRC_MASK                0x1800  /* LDO8_HWC_SRC - [12:11] */
+#define WM831X_LDO8_HWC_SRC_SHIFT                   11  /* LDO8_HWC_SRC - [12:11] */
+#define WM831X_LDO8_HWC_SRC_WIDTH                    2  /* LDO8_HWC_SRC - [12:11] */
+#define WM831X_LDO8_HWC_VSEL                    0x0400  /* LDO8_HWC_VSEL */
+#define WM831X_LDO8_HWC_VSEL_MASK               0x0400  /* LDO8_HWC_VSEL */
+#define WM831X_LDO8_HWC_VSEL_SHIFT                  10  /* LDO8_HWC_VSEL */
+#define WM831X_LDO8_HWC_VSEL_WIDTH                   1  /* LDO8_HWC_VSEL */
+#define WM831X_LDO8_HWC_MODE_MASK               0x0300  /* LDO8_HWC_MODE - [9:8] */
+#define WM831X_LDO8_HWC_MODE_SHIFT                   8  /* LDO8_HWC_MODE - [9:8] */
+#define WM831X_LDO8_HWC_MODE_WIDTH                   2  /* LDO8_HWC_MODE - [9:8] */
+#define WM831X_LDO8_FLT                         0x0080  /* LDO8_FLT */
+#define WM831X_LDO8_FLT_MASK                    0x0080  /* LDO8_FLT */
+#define WM831X_LDO8_FLT_SHIFT                        7  /* LDO8_FLT */
+#define WM831X_LDO8_FLT_WIDTH                        1  /* LDO8_FLT */
+#define WM831X_LDO8_SWI                         0x0040  /* LDO8_SWI */
+#define WM831X_LDO8_SWI_MASK                    0x0040  /* LDO8_SWI */
+#define WM831X_LDO8_SWI_SHIFT                        6  /* LDO8_SWI */
+#define WM831X_LDO8_SWI_WIDTH                        1  /* LDO8_SWI */
+
+/*
+ * R16510 (0x407E) - LDO8 ON Control
+ */
+#define WM831X_LDO8_ON_SLOT_MASK                0xE000  /* LDO8_ON_SLOT - [15:13] */
+#define WM831X_LDO8_ON_SLOT_SHIFT                   13  /* LDO8_ON_SLOT - [15:13] */
+#define WM831X_LDO8_ON_SLOT_WIDTH                    3  /* LDO8_ON_SLOT - [15:13] */
+#define WM831X_LDO8_ON_MODE                     0x0100  /* LDO8_ON_MODE */
+#define WM831X_LDO8_ON_MODE_MASK                0x0100  /* LDO8_ON_MODE */
+#define WM831X_LDO8_ON_MODE_SHIFT                    8  /* LDO8_ON_MODE */
+#define WM831X_LDO8_ON_MODE_WIDTH                    1  /* LDO8_ON_MODE */
+#define WM831X_LDO8_ON_VSEL_MASK                0x001F  /* LDO8_ON_VSEL - [4:0] */
+#define WM831X_LDO8_ON_VSEL_SHIFT                    0  /* LDO8_ON_VSEL - [4:0] */
+#define WM831X_LDO8_ON_VSEL_WIDTH                    5  /* LDO8_ON_VSEL - [4:0] */
+
+/*
+ * R16511 (0x407F) - LDO8 SLEEP Control
+ */
+#define WM831X_LDO8_SLP_SLOT_MASK               0xE000  /* LDO8_SLP_SLOT - [15:13] */
+#define WM831X_LDO8_SLP_SLOT_SHIFT                  13  /* LDO8_SLP_SLOT - [15:13] */
+#define WM831X_LDO8_SLP_SLOT_WIDTH                   3  /* LDO8_SLP_SLOT - [15:13] */
+#define WM831X_LDO8_SLP_MODE                    0x0100  /* LDO8_SLP_MODE */
+#define WM831X_LDO8_SLP_MODE_MASK               0x0100  /* LDO8_SLP_MODE */
+#define WM831X_LDO8_SLP_MODE_SHIFT                   8  /* LDO8_SLP_MODE */
+#define WM831X_LDO8_SLP_MODE_WIDTH                   1  /* LDO8_SLP_MODE */
+#define WM831X_LDO8_SLP_VSEL_MASK               0x001F  /* LDO8_SLP_VSEL - [4:0] */
+#define WM831X_LDO8_SLP_VSEL_SHIFT                   0  /* LDO8_SLP_VSEL - [4:0] */
+#define WM831X_LDO8_SLP_VSEL_WIDTH                   5  /* LDO8_SLP_VSEL - [4:0] */
+
+/*
+ * R16512 (0x4080) - LDO9 Control
+ */
+#define WM831X_LDO9_ERR_ACT_MASK                0xC000  /* LDO9_ERR_ACT - [15:14] */
+#define WM831X_LDO9_ERR_ACT_SHIFT                   14  /* LDO9_ERR_ACT - [15:14] */
+#define WM831X_LDO9_ERR_ACT_WIDTH                    2  /* LDO9_ERR_ACT - [15:14] */
+#define WM831X_LDO9_HWC_SRC_MASK                0x1800  /* LDO9_HWC_SRC - [12:11] */
+#define WM831X_LDO9_HWC_SRC_SHIFT                   11  /* LDO9_HWC_SRC - [12:11] */
+#define WM831X_LDO9_HWC_SRC_WIDTH                    2  /* LDO9_HWC_SRC - [12:11] */
+#define WM831X_LDO9_HWC_VSEL                    0x0400  /* LDO9_HWC_VSEL */
+#define WM831X_LDO9_HWC_VSEL_MASK               0x0400  /* LDO9_HWC_VSEL */
+#define WM831X_LDO9_HWC_VSEL_SHIFT                  10  /* LDO9_HWC_VSEL */
+#define WM831X_LDO9_HWC_VSEL_WIDTH                   1  /* LDO9_HWC_VSEL */
+#define WM831X_LDO9_HWC_MODE_MASK               0x0300  /* LDO9_HWC_MODE - [9:8] */
+#define WM831X_LDO9_HWC_MODE_SHIFT                   8  /* LDO9_HWC_MODE - [9:8] */
+#define WM831X_LDO9_HWC_MODE_WIDTH                   2  /* LDO9_HWC_MODE - [9:8] */
+#define WM831X_LDO9_FLT                         0x0080  /* LDO9_FLT */
+#define WM831X_LDO9_FLT_MASK                    0x0080  /* LDO9_FLT */
+#define WM831X_LDO9_FLT_SHIFT                        7  /* LDO9_FLT */
+#define WM831X_LDO9_FLT_WIDTH                        1  /* LDO9_FLT */
+#define WM831X_LDO9_SWI                         0x0040  /* LDO9_SWI */
+#define WM831X_LDO9_SWI_MASK                    0x0040  /* LDO9_SWI */
+#define WM831X_LDO9_SWI_SHIFT                        6  /* LDO9_SWI */
+#define WM831X_LDO9_SWI_WIDTH                        1  /* LDO9_SWI */
+
+/*
+ * R16513 (0x4081) - LDO9 ON Control
+ */
+#define WM831X_LDO9_ON_SLOT_MASK                0xE000  /* LDO9_ON_SLOT - [15:13] */
+#define WM831X_LDO9_ON_SLOT_SHIFT                   13  /* LDO9_ON_SLOT - [15:13] */
+#define WM831X_LDO9_ON_SLOT_WIDTH                    3  /* LDO9_ON_SLOT - [15:13] */
+#define WM831X_LDO9_ON_MODE                     0x0100  /* LDO9_ON_MODE */
+#define WM831X_LDO9_ON_MODE_MASK                0x0100  /* LDO9_ON_MODE */
+#define WM831X_LDO9_ON_MODE_SHIFT                    8  /* LDO9_ON_MODE */
+#define WM831X_LDO9_ON_MODE_WIDTH                    1  /* LDO9_ON_MODE */
+#define WM831X_LDO9_ON_VSEL_MASK                0x001F  /* LDO9_ON_VSEL - [4:0] */
+#define WM831X_LDO9_ON_VSEL_SHIFT                    0  /* LDO9_ON_VSEL - [4:0] */
+#define WM831X_LDO9_ON_VSEL_WIDTH                    5  /* LDO9_ON_VSEL - [4:0] */
+
+/*
+ * R16514 (0x4082) - LDO9 SLEEP Control
+ */
+#define WM831X_LDO9_SLP_SLOT_MASK               0xE000  /* LDO9_SLP_SLOT - [15:13] */
+#define WM831X_LDO9_SLP_SLOT_SHIFT                  13  /* LDO9_SLP_SLOT - [15:13] */
+#define WM831X_LDO9_SLP_SLOT_WIDTH                   3  /* LDO9_SLP_SLOT - [15:13] */
+#define WM831X_LDO9_SLP_MODE                    0x0100  /* LDO9_SLP_MODE */
+#define WM831X_LDO9_SLP_MODE_MASK               0x0100  /* LDO9_SLP_MODE */
+#define WM831X_LDO9_SLP_MODE_SHIFT                   8  /* LDO9_SLP_MODE */
+#define WM831X_LDO9_SLP_MODE_WIDTH                   1  /* LDO9_SLP_MODE */
+#define WM831X_LDO9_SLP_VSEL_MASK               0x001F  /* LDO9_SLP_VSEL - [4:0] */
+#define WM831X_LDO9_SLP_VSEL_SHIFT                   0  /* LDO9_SLP_VSEL - [4:0] */
+#define WM831X_LDO9_SLP_VSEL_WIDTH                   5  /* LDO9_SLP_VSEL - [4:0] */
+
+/*
+ * R16515 (0x4083) - LDO10 Control
+ */
+#define WM831X_LDO10_ERR_ACT_MASK               0xC000  /* LDO10_ERR_ACT - [15:14] */
+#define WM831X_LDO10_ERR_ACT_SHIFT                  14  /* LDO10_ERR_ACT - [15:14] */
+#define WM831X_LDO10_ERR_ACT_WIDTH                   2  /* LDO10_ERR_ACT - [15:14] */
+#define WM831X_LDO10_HWC_SRC_MASK               0x1800  /* LDO10_HWC_SRC - [12:11] */
+#define WM831X_LDO10_HWC_SRC_SHIFT                  11  /* LDO10_HWC_SRC - [12:11] */
+#define WM831X_LDO10_HWC_SRC_WIDTH                   2  /* LDO10_HWC_SRC - [12:11] */
+#define WM831X_LDO10_HWC_VSEL                   0x0400  /* LDO10_HWC_VSEL */
+#define WM831X_LDO10_HWC_VSEL_MASK              0x0400  /* LDO10_HWC_VSEL */
+#define WM831X_LDO10_HWC_VSEL_SHIFT                 10  /* LDO10_HWC_VSEL */
+#define WM831X_LDO10_HWC_VSEL_WIDTH                  1  /* LDO10_HWC_VSEL */
+#define WM831X_LDO10_HWC_MODE_MASK              0x0300  /* LDO10_HWC_MODE - [9:8] */
+#define WM831X_LDO10_HWC_MODE_SHIFT                  8  /* LDO10_HWC_MODE - [9:8] */
+#define WM831X_LDO10_HWC_MODE_WIDTH                  2  /* LDO10_HWC_MODE - [9:8] */
+#define WM831X_LDO10_FLT                        0x0080  /* LDO10_FLT */
+#define WM831X_LDO10_FLT_MASK                   0x0080  /* LDO10_FLT */
+#define WM831X_LDO10_FLT_SHIFT                       7  /* LDO10_FLT */
+#define WM831X_LDO10_FLT_WIDTH                       1  /* LDO10_FLT */
+#define WM831X_LDO10_SWI                        0x0040  /* LDO10_SWI */
+#define WM831X_LDO10_SWI_MASK                   0x0040  /* LDO10_SWI */
+#define WM831X_LDO10_SWI_SHIFT                       6  /* LDO10_SWI */
+#define WM831X_LDO10_SWI_WIDTH                       1  /* LDO10_SWI */
+
+/*
+ * R16516 (0x4084) - LDO10 ON Control
+ */
+#define WM831X_LDO10_ON_SLOT_MASK               0xE000  /* LDO10_ON_SLOT - [15:13] */
+#define WM831X_LDO10_ON_SLOT_SHIFT                  13  /* LDO10_ON_SLOT - [15:13] */
+#define WM831X_LDO10_ON_SLOT_WIDTH                   3  /* LDO10_ON_SLOT - [15:13] */
+#define WM831X_LDO10_ON_MODE                    0x0100  /* LDO10_ON_MODE */
+#define WM831X_LDO10_ON_MODE_MASK               0x0100  /* LDO10_ON_MODE */
+#define WM831X_LDO10_ON_MODE_SHIFT                   8  /* LDO10_ON_MODE */
+#define WM831X_LDO10_ON_MODE_WIDTH                   1  /* LDO10_ON_MODE */
+#define WM831X_LDO10_ON_VSEL_MASK               0x001F  /* LDO10_ON_VSEL - [4:0] */
+#define WM831X_LDO10_ON_VSEL_SHIFT                   0  /* LDO10_ON_VSEL - [4:0] */
+#define WM831X_LDO10_ON_VSEL_WIDTH                   5  /* LDO10_ON_VSEL - [4:0] */
+
+/*
+ * R16517 (0x4085) - LDO10 SLEEP Control
+ */
+#define WM831X_LDO10_SLP_SLOT_MASK              0xE000  /* LDO10_SLP_SLOT - [15:13] */
+#define WM831X_LDO10_SLP_SLOT_SHIFT                 13  /* LDO10_SLP_SLOT - [15:13] */
+#define WM831X_LDO10_SLP_SLOT_WIDTH                  3  /* LDO10_SLP_SLOT - [15:13] */
+#define WM831X_LDO10_SLP_MODE                   0x0100  /* LDO10_SLP_MODE */
+#define WM831X_LDO10_SLP_MODE_MASK              0x0100  /* LDO10_SLP_MODE */
+#define WM831X_LDO10_SLP_MODE_SHIFT                  8  /* LDO10_SLP_MODE */
+#define WM831X_LDO10_SLP_MODE_WIDTH                  1  /* LDO10_SLP_MODE */
+#define WM831X_LDO10_SLP_VSEL_MASK              0x001F  /* LDO10_SLP_VSEL - [4:0] */
+#define WM831X_LDO10_SLP_VSEL_SHIFT                  0  /* LDO10_SLP_VSEL - [4:0] */
+#define WM831X_LDO10_SLP_VSEL_WIDTH                  5  /* LDO10_SLP_VSEL - [4:0] */
+
+/*
+ * R16519 (0x4087) - LDO11 ON Control
+ */
+#define WM831X_LDO11_ON_SLOT_MASK               0xE000  /* LDO11_ON_SLOT - [15:13] */
+#define WM831X_LDO11_ON_SLOT_SHIFT                  13  /* LDO11_ON_SLOT - [15:13] */
+#define WM831X_LDO11_ON_SLOT_WIDTH                   3  /* LDO11_ON_SLOT - [15:13] */
+#define WM831X_LDO11_OFFENA                     0x1000  /* LDO11_OFFENA */
+#define WM831X_LDO11_OFFENA_MASK                0x1000  /* LDO11_OFFENA */
+#define WM831X_LDO11_OFFENA_SHIFT                   12  /* LDO11_OFFENA */
+#define WM831X_LDO11_OFFENA_WIDTH                    1  /* LDO11_OFFENA */
+#define WM831X_LDO11_VSEL_SRC                   0x0080  /* LDO11_VSEL_SRC */
+#define WM831X_LDO11_VSEL_SRC_MASK              0x0080  /* LDO11_VSEL_SRC */
+#define WM831X_LDO11_VSEL_SRC_SHIFT                  7  /* LDO11_VSEL_SRC */
+#define WM831X_LDO11_VSEL_SRC_WIDTH                  1  /* LDO11_VSEL_SRC */
+#define WM831X_LDO11_ON_VSEL_MASK               0x000F  /* LDO11_ON_VSEL - [3:0] */
+#define WM831X_LDO11_ON_VSEL_SHIFT                   0  /* LDO11_ON_VSEL - [3:0] */
+#define WM831X_LDO11_ON_VSEL_WIDTH                   4  /* LDO11_ON_VSEL - [3:0] */
+
+/*
+ * R16520 (0x4088) - LDO11 SLEEP Control
+ */
+#define WM831X_LDO11_SLP_SLOT_MASK              0xE000  /* LDO11_SLP_SLOT - [15:13] */
+#define WM831X_LDO11_SLP_SLOT_SHIFT                 13  /* LDO11_SLP_SLOT - [15:13] */
+#define WM831X_LDO11_SLP_SLOT_WIDTH                  3  /* LDO11_SLP_SLOT - [15:13] */
+#define WM831X_LDO11_SLP_VSEL_MASK              0x000F  /* LDO11_SLP_VSEL - [3:0] */
+#define WM831X_LDO11_SLP_VSEL_SHIFT                  0  /* LDO11_SLP_VSEL - [3:0] */
+#define WM831X_LDO11_SLP_VSEL_WIDTH                  4  /* LDO11_SLP_VSEL - [3:0] */
+
+/*
+ * R16526 (0x408E) - Power Good Source 1
+ */
+#define WM831X_DC4_OK                           0x0008  /* DC4_OK */
+#define WM831X_DC4_OK_MASK                      0x0008  /* DC4_OK */
+#define WM831X_DC4_OK_SHIFT                          3  /* DC4_OK */
+#define WM831X_DC4_OK_WIDTH                          1  /* DC4_OK */
+#define WM831X_DC3_OK                           0x0004  /* DC3_OK */
+#define WM831X_DC3_OK_MASK                      0x0004  /* DC3_OK */
+#define WM831X_DC3_OK_SHIFT                          2  /* DC3_OK */
+#define WM831X_DC3_OK_WIDTH                          1  /* DC3_OK */
+#define WM831X_DC2_OK                           0x0002  /* DC2_OK */
+#define WM831X_DC2_OK_MASK                      0x0002  /* DC2_OK */
+#define WM831X_DC2_OK_SHIFT                          1  /* DC2_OK */
+#define WM831X_DC2_OK_WIDTH                          1  /* DC2_OK */
+#define WM831X_DC1_OK                           0x0001  /* DC1_OK */
+#define WM831X_DC1_OK_MASK                      0x0001  /* DC1_OK */
+#define WM831X_DC1_OK_SHIFT                          0  /* DC1_OK */
+#define WM831X_DC1_OK_WIDTH                          1  /* DC1_OK */
+
+/*
+ * R16527 (0x408F) - Power Good Source 2
+ */
+#define WM831X_LDO10_OK                         0x0200  /* LDO10_OK */
+#define WM831X_LDO10_OK_MASK                    0x0200  /* LDO10_OK */
+#define WM831X_LDO10_OK_SHIFT                        9  /* LDO10_OK */
+#define WM831X_LDO10_OK_WIDTH                        1  /* LDO10_OK */
+#define WM831X_LDO9_OK                          0x0100  /* LDO9_OK */
+#define WM831X_LDO9_OK_MASK                     0x0100  /* LDO9_OK */
+#define WM831X_LDO9_OK_SHIFT                         8  /* LDO9_OK */
+#define WM831X_LDO9_OK_WIDTH                         1  /* LDO9_OK */
+#define WM831X_LDO8_OK                          0x0080  /* LDO8_OK */
+#define WM831X_LDO8_OK_MASK                     0x0080  /* LDO8_OK */
+#define WM831X_LDO8_OK_SHIFT                         7  /* LDO8_OK */
+#define WM831X_LDO8_OK_WIDTH                         1  /* LDO8_OK */
+#define WM831X_LDO7_OK                          0x0040  /* LDO7_OK */
+#define WM831X_LDO7_OK_MASK                     0x0040  /* LDO7_OK */
+#define WM831X_LDO7_OK_SHIFT                         6  /* LDO7_OK */
+#define WM831X_LDO7_OK_WIDTH                         1  /* LDO7_OK */
+#define WM831X_LDO6_OK                          0x0020  /* LDO6_OK */
+#define WM831X_LDO6_OK_MASK                     0x0020  /* LDO6_OK */
+#define WM831X_LDO6_OK_SHIFT                         5  /* LDO6_OK */
+#define WM831X_LDO6_OK_WIDTH                         1  /* LDO6_OK */
+#define WM831X_LDO5_OK                          0x0010  /* LDO5_OK */
+#define WM831X_LDO5_OK_MASK                     0x0010  /* LDO5_OK */
+#define WM831X_LDO5_OK_SHIFT                         4  /* LDO5_OK */
+#define WM831X_LDO5_OK_WIDTH                         1  /* LDO5_OK */
+#define WM831X_LDO4_OK                          0x0008  /* LDO4_OK */
+#define WM831X_LDO4_OK_MASK                     0x0008  /* LDO4_OK */
+#define WM831X_LDO4_OK_SHIFT                         3  /* LDO4_OK */
+#define WM831X_LDO4_OK_WIDTH                         1  /* LDO4_OK */
+#define WM831X_LDO3_OK                          0x0004  /* LDO3_OK */
+#define WM831X_LDO3_OK_MASK                     0x0004  /* LDO3_OK */
+#define WM831X_LDO3_OK_SHIFT                         2  /* LDO3_OK */
+#define WM831X_LDO3_OK_WIDTH                         1  /* LDO3_OK */
+#define WM831X_LDO2_OK                          0x0002  /* LDO2_OK */
+#define WM831X_LDO2_OK_MASK                     0x0002  /* LDO2_OK */
+#define WM831X_LDO2_OK_SHIFT                         1  /* LDO2_OK */
+#define WM831X_LDO2_OK_WIDTH                         1  /* LDO2_OK */
+#define WM831X_LDO1_OK                          0x0001  /* LDO1_OK */
+#define WM831X_LDO1_OK_MASK                     0x0001  /* LDO1_OK */
+#define WM831X_LDO1_OK_SHIFT                         0  /* LDO1_OK */
+#define WM831X_LDO1_OK_WIDTH                         1  /* LDO1_OK */
+
+#define WM831X_ISINK_MAX_ISEL 56
+extern int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL];
+
+#endif
diff --git a/include/linux/mfd/wm831x/watchdog.h b/include/linux/mfd/wm831x/watchdog.h
new file mode 100644
index 0000000..97a99b5
--- /dev/null
+++ b/include/linux/mfd/wm831x/watchdog.h
@@ -0,0 +1,52 @@
+/*
+ * include/linux/mfd/wm831x/watchdog.h -- Watchdog for WM831x
+ *
+ * Copyright 2009 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 __MFD_WM831X_WATCHDOG_H__
+#define __MFD_WM831X_WATCHDOG_H__
+
+
+/*
+ * R16388 (0x4004) - Watchdog
+ */
+#define WM831X_WDOG_ENA                         0x8000  /* WDOG_ENA */
+#define WM831X_WDOG_ENA_MASK                    0x8000  /* WDOG_ENA */
+#define WM831X_WDOG_ENA_SHIFT                       15  /* WDOG_ENA */
+#define WM831X_WDOG_ENA_WIDTH                        1  /* WDOG_ENA */
+#define WM831X_WDOG_DEBUG                       0x4000  /* WDOG_DEBUG */
+#define WM831X_WDOG_DEBUG_MASK                  0x4000  /* WDOG_DEBUG */
+#define WM831X_WDOG_DEBUG_SHIFT                     14  /* WDOG_DEBUG */
+#define WM831X_WDOG_DEBUG_WIDTH                      1  /* WDOG_DEBUG */
+#define WM831X_WDOG_RST_SRC                     0x2000  /* WDOG_RST_SRC */
+#define WM831X_WDOG_RST_SRC_MASK                0x2000  /* WDOG_RST_SRC */
+#define WM831X_WDOG_RST_SRC_SHIFT                   13  /* WDOG_RST_SRC */
+#define WM831X_WDOG_RST_SRC_WIDTH                    1  /* WDOG_RST_SRC */
+#define WM831X_WDOG_SLPENA                      0x1000  /* WDOG_SLPENA */
+#define WM831X_WDOG_SLPENA_MASK                 0x1000  /* WDOG_SLPENA */
+#define WM831X_WDOG_SLPENA_SHIFT                    12  /* WDOG_SLPENA */
+#define WM831X_WDOG_SLPENA_WIDTH                     1  /* WDOG_SLPENA */
+#define WM831X_WDOG_RESET                       0x0800  /* WDOG_RESET */
+#define WM831X_WDOG_RESET_MASK                  0x0800  /* WDOG_RESET */
+#define WM831X_WDOG_RESET_SHIFT                     11  /* WDOG_RESET */
+#define WM831X_WDOG_RESET_WIDTH                      1  /* WDOG_RESET */
+#define WM831X_WDOG_SECACT_MASK                 0x0300  /* WDOG_SECACT - [9:8] */
+#define WM831X_WDOG_SECACT_SHIFT                     8  /* WDOG_SECACT - [9:8] */
+#define WM831X_WDOG_SECACT_WIDTH                     2  /* WDOG_SECACT - [9:8] */
+#define WM831X_WDOG_PRIMACT_MASK                0x0030  /* WDOG_PRIMACT - [5:4] */
+#define WM831X_WDOG_PRIMACT_SHIFT                    4  /* WDOG_PRIMACT - [5:4] */
+#define WM831X_WDOG_PRIMACT_WIDTH                    2  /* WDOG_PRIMACT - [5:4] */
+#define WM831X_WDOG_TO_MASK                     0x0007  /* WDOG_TO - [2:0] */
+#define WM831X_WDOG_TO_SHIFT                         0  /* WDOG_TO - [2:0] */
+#define WM831X_WDOG_TO_WIDTH                         3  /* WDOG_TO - [2:0] */
+
+#endif
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
index 42cca67..1d595de 100644
--- a/include/linux/mfd/wm8350/core.h
+++ b/include/linux/mfd/wm8350/core.h
@@ -605,6 +605,11 @@ struct wm8350_irq {
 	void *data;
 };
 
+struct wm8350_hwmon {
+	struct platform_device *pdev;
+	struct device *classdev;
+};
+
 struct wm8350 {
 	struct device *dev;
 
@@ -621,7 +626,6 @@ struct wm8350 {
 	struct mutex auxadc_mutex;
 
 	/* Interrupt handling */
-	struct work_struct irq_work;
 	struct mutex irq_mutex; /* IRQ table mutex */
 	struct wm8350_irq irq[WM8350_NUM_IRQ];
 	int chip_irq;
@@ -629,6 +633,7 @@ struct wm8350 {
 	/* Client devices */
 	struct wm8350_codec codec;
 	struct wm8350_gpio gpio;
+	struct wm8350_hwmon hwmon;
 	struct wm8350_pmic pmic;
 	struct wm8350_power power;
 	struct wm8350_rtc rtc;
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 0521177..adaf3c1 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -41,7 +41,8 @@ struct miscdevice  {
 	struct list_head list;
 	struct device *parent;
 	struct device *this_device;
-	const char *devnode;
+	const char *nodename;
+	mode_t mode;
 };
 
 extern int misc_register(struct miscdevice * misc);
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 39751c8..2dbfb5a 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -22,6 +22,12 @@
 /*
  * Vendors and devices.  Sort key: vendor first, device next.
  */
+#define SDIO_VENDOR_ID_INTEL			0x0089
+#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX	0x1402
+#define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI	0x1403
+#define SDIO_DEVICE_ID_INTEL_IWMC3200TOP	0x1404
+#define SDIO_DEVICE_ID_INTEL_IWMC3200GPS	0x1405
+#define SDIO_DEVICE_ID_INTEL_IWMC3200BT		0x1406
 
 #define SDIO_VENDOR_ID_MARVELL			0x02df
 #define SDIO_DEVICE_ID_MARVELL_LIBERTAS		0x9103
diff --git a/include/linux/module.h b/include/linux/module.h
index f8f92d0..1c755b2 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -15,7 +15,6 @@
 #include <linux/stringify.h>
 #include <linux/kobject.h>
 #include <linux/moduleparam.h>
-#include <linux/marker.h>
 #include <linux/tracepoint.h>
 
 #include <asm/local.h>
@@ -327,10 +326,6 @@ struct module
 	/* The command line arguments (may be mangled).  People like
 	   keeping pointers to this stuff */
 	char *args;
-#ifdef CONFIG_MARKERS
-	struct marker *markers;
-	unsigned int num_markers;
-#endif
 #ifdef CONFIG_TRACEPOINTS
 	struct tracepoint *tracepoints;
 	unsigned int num_tracepoints;
@@ -535,8 +530,6 @@ int unregister_module_notifier(struct notifier_block * nb);
 
 extern void print_modules(void);
 
-extern void module_update_markers(void);
-
 extern void module_update_tracepoints(void);
 extern int module_get_iter_tracepoints(struct tracepoint_iter *iter);
 
@@ -651,10 +644,6 @@ static inline void print_modules(void)
 {
 }
 
-static inline void module_update_markers(void)
-{
-}
-
 static inline void module_update_tracepoints(void)
 {
 }
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index b70313d..274b619 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -1,7 +1,7 @@
 /*
  * MTD partitioning layer definitions
  *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
+ * (C) 2000 Nicolas Pitre <nico@fluxnic.net>
  *
  * This code is GPL
  */
diff --git a/include/linux/net.h b/include/linux/net.h
index 4fc2ffd..9040a10 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -57,6 +57,7 @@ typedef enum {
 #include <linux/random.h>
 #include <linux/wait.h>
 #include <linux/fcntl.h>	/* For O_CLOEXEC and O_NONBLOCK */
+#include <linux/kmemcheck.h>
 
 struct poll_table_struct;
 struct pipe_inode_info;
@@ -127,7 +128,11 @@ enum sock_shutdown_cmd {
  */
 struct socket {
 	socket_state		state;
+
+	kmemcheck_bitfield_begin(type);
 	short			type;
+	kmemcheck_bitfield_end(type);
+
 	unsigned long		flags;
 	/*
 	 * Please keep fasync_list & wait fields in the same cache line
diff --git a/include/linux/net_dropmon.h b/include/linux/net_dropmon.h
index 3ceb0cc..2a73946 100644
--- a/include/linux/net_dropmon.h
+++ b/include/linux/net_dropmon.h
@@ -3,7 +3,6 @@
 
 #include <linux/types.h>
 #include <linux/netlink.h>
-#include <linux/types.h>
 
 struct net_dm_drop_point {
 	__u8 pc[8];
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d4a4d98..94958c1 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -72,10 +72,6 @@ struct wireless_dev;
 /* Backlog congestion levels */
 #define NET_RX_SUCCESS		0   /* keep 'em coming, baby */
 #define NET_RX_DROP		1  /* packet dropped */
-#define NET_RX_CN_LOW		2   /* storm alert, just in case */
-#define NET_RX_CN_MOD		3   /* Storm on its way! */
-#define NET_RX_CN_HIGH		4   /* The storm is here */
-#define NET_RX_BAD		5  /* packet dropped due to kernel error */
 
 /* NET_XMIT_CN is special. It does not guarantee that this packet is lost. It
  * indicates that the device will soon be dropping packets, or already drops
@@ -83,17 +79,19 @@ struct wireless_dev;
 #define net_xmit_eval(e)	((e) == NET_XMIT_CN? 0 : (e))
 #define net_xmit_errno(e)	((e) != NET_XMIT_CN ? -ENOBUFS : 0)
 
+/* Driver transmit return codes */
+enum netdev_tx {
+	NETDEV_TX_OK = 0,	/* driver took care of packet */
+	NETDEV_TX_BUSY,		/* driver tx path was busy*/
+	NETDEV_TX_LOCKED = -1,	/* driver tx lock was already taken */
+};
+typedef enum netdev_tx netdev_tx_t;
+
 #endif
 
 #define MAX_ADDR_LEN	32		/* Largest hardware address length */
 
-/* Driver transmit return codes */
-#define NETDEV_TX_OK 0		/* driver took care of packet */
-#define NETDEV_TX_BUSY 1	/* driver tx path was busy*/
-#define NETDEV_TX_LOCKED -1	/* driver tx lock was already taken */
-
 #ifdef  __KERNEL__
-
 /*
  *	Compute the worst case header length according to the protocols
  *	used.
@@ -511,9 +509,11 @@ struct netdev_queue {
  *     This function is called when network device transistions to the down
  *     state.
  *
- * int (*ndo_start_xmit)(struct sk_buff *skb, struct net_device *dev);
+ * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,
+ *                               struct net_device *dev);
  *	Called when a packet needs to be transmitted.
- *	Must return NETDEV_TX_OK , NETDEV_TX_BUSY, or NETDEV_TX_LOCKED,
+ *	Must return NETDEV_TX_OK , NETDEV_TX_BUSY.
+ *        (can also return NETDEV_TX_LOCKED iff NETIF_F_LLTX)
  *	Required can not be NULL.
  *
  * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb);
@@ -584,7 +584,7 @@ struct net_device_ops {
 	void			(*ndo_uninit)(struct net_device *dev);
 	int			(*ndo_open)(struct net_device *dev);
 	int			(*ndo_stop)(struct net_device *dev);
-	int			(*ndo_start_xmit) (struct sk_buff *skb,
+	netdev_tx_t		(*ndo_start_xmit) (struct sk_buff *skb,
 						   struct net_device *dev);
 	u16			(*ndo_select_queue)(struct net_device *dev,
 						    struct sk_buff *skb);
@@ -627,6 +627,8 @@ struct net_device_ops {
 	void                    (*ndo_poll_controller)(struct net_device *dev);
 #endif
 #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+	int			(*ndo_fcoe_enable)(struct net_device *dev);
+	int			(*ndo_fcoe_disable)(struct net_device *dev);
 	int			(*ndo_fcoe_ddp_setup)(struct net_device *dev,
 						      u16 xid,
 						      struct scatterlist *sgl,
@@ -705,6 +707,7 @@ struct net_device
 /* the GSO_MASK reserves bits 16 through 23 */
 #define NETIF_F_FCOE_CRC	(1 << 24) /* FCoE CRC32 */
 #define NETIF_F_SCTP_CSUM	(1 << 25) /* SCTP checksum offload */
+#define NETIF_F_FCOE_MTU	(1 << 26) /* Supports max FCoE MTU, 2158 bytes*/
 
 	/* Segmentation offload features */
 #define NETIF_F_GSO_SHIFT	16
@@ -829,6 +832,9 @@ struct net_device
 	/* Number of TX queues currently active in device  */
 	unsigned int		real_num_tx_queues;
 
+	/* root qdisc from userspace point of view */
+	struct Qdisc		*qdisc;
+
 	unsigned long		tx_queue_len;	/* Max frames per queue allowed */
 	spinlock_t		tx_global_lock;
 /*
@@ -889,7 +895,7 @@ struct net_device
 	/* class/net/name entry */
 	struct device		dev;
 	/* space for optional statistics and wireless sysfs groups */
-	struct attribute_group  *sysfs_groups[3];
+	const struct attribute_group *sysfs_groups[3];
 
 	/* rtnetlink link ops */
 	const struct rtnl_link_ops *rtnl_link_ops;
@@ -992,6 +998,12 @@ static inline void *netdev_priv(const struct net_device *dev)
  */
 #define SET_NETDEV_DEV(net, pdev)	((net)->dev.parent = (pdev))
 
+/* Set the sysfs device type for the network logical device to allow
+ * fin grained indentification of different network device types. For
+ * example Ethernet, Wirelss LAN, Bluetooth, WiMAX etc.
+ */
+#define SET_NETDEV_DEVTYPE(net, devtype)	((net)->dev.type = (devtype))
+
 /**
  *	netif_napi_add - initialize a napi context
  *	@dev:  network device
@@ -1260,7 +1272,7 @@ static inline void netif_tx_wake_queue(struct netdev_queue *dev_queue)
 {
 #ifdef CONFIG_NETPOLL_TRAP
 	if (netpoll_trap()) {
-		clear_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
+		netif_tx_start_queue(dev_queue);
 		return;
 	}
 #endif
@@ -1366,7 +1378,8 @@ static inline int netif_running(const struct net_device *dev)
 static inline void netif_start_subqueue(struct net_device *dev, u16 queue_index)
 {
 	struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index);
-	clear_bit(__QUEUE_STATE_XOFF, &txq->state);
+
+	netif_tx_start_queue(txq);
 }
 
 /**
@@ -1383,7 +1396,7 @@ static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index)
 	if (netpoll_trap())
 		return;
 #endif
-	set_bit(__QUEUE_STATE_XOFF, &txq->state);
+	netif_tx_stop_queue(txq);
 }
 
 /**
@@ -1397,7 +1410,8 @@ static inline int __netif_subqueue_stopped(const struct net_device *dev,
 					 u16 queue_index)
 {
 	struct netdev_queue *txq = netdev_get_tx_queue(dev, queue_index);
-	return test_bit(__QUEUE_STATE_XOFF, &txq->state);
+
+	return netif_tx_queue_stopped(txq);
 }
 
 static inline int netif_subqueue_stopped(const struct net_device *dev,
@@ -1749,8 +1763,7 @@ static inline void netif_tx_unlock(struct net_device *dev)
 		 * force a schedule.
 		 */
 		clear_bit(__QUEUE_STATE_FROZEN, &txq->state);
-		if (!test_bit(__QUEUE_STATE_XOFF, &txq->state))
-			__netif_schedule(txq->qdisc);
+		netif_schedule_queue(txq);
 	}
 	spin_unlock(&dev->tx_global_lock);
 }
@@ -1860,7 +1873,8 @@ extern void		__dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct
 extern int		dev_set_promiscuity(struct net_device *dev, int inc);
 extern int		dev_set_allmulti(struct net_device *dev, int inc);
 extern void		netdev_state_change(struct net_device *dev);
-extern void		netdev_bonding_change(struct net_device *dev);
+extern void		netdev_bonding_change(struct net_device *dev,
+					      unsigned long event);
 extern void		netdev_features_change(struct net_device *dev);
 /* Load a device via the kmod */
 extern void		dev_load(struct net *net, const char *name);
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index bff4d57..9f00da2 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -58,7 +58,8 @@ struct nfgenmsg {
 struct nfnl_callback
 {
 	int (*call)(struct sock *nl, struct sk_buff *skb, 
-		struct nlmsghdr *nlh, struct nlattr *cda[]);
+		    const struct nlmsghdr *nlh,
+		    const struct nlattr * const cda[]);
 	const struct nla_policy *policy;	/* netlink attribute policy */
 	const u_int16_t attr_count;		/* number of nlattr's */
 };
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 1030b75..812cb15 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -238,9 +238,9 @@ struct xt_mtdtor_param {
  */
 struct xt_target_param {
 	const struct net_device *in, *out;
-	unsigned int hooknum;
 	const struct xt_target *target;
 	const void *targinfo;
+	unsigned int hooknum;
 	u_int8_t family;
 };
 
@@ -407,7 +407,7 @@ extern int xt_check_target(struct xt_tgchk_param *,
 			   unsigned int size, u_int8_t proto, bool inv_proto);
 
 extern struct xt_table *xt_register_table(struct net *net,
-					  struct xt_table *table,
+					  const struct xt_table *table,
 					  struct xt_table_info *bootstrap,
 					  struct xt_table_info *newinfo);
 extern void *xt_unregister_table(struct xt_table *table);
diff --git a/include/linux/netfilter/xt_CONNMARK.h b/include/linux/netfilter/xt_CONNMARK.h
index 7635c8f..0a85458 100644
--- a/include/linux/netfilter/xt_CONNMARK.h
+++ b/include/linux/netfilter/xt_CONNMARK.h
@@ -18,12 +18,6 @@ enum {
 	XT_CONNMARK_RESTORE
 };
 
-struct xt_connmark_target_info {
-	unsigned long mark;
-	unsigned long mask;
-	__u8 mode;
-};
-
 struct xt_connmark_tginfo1 {
 	__u32 ctmark, ctmask, nfmask;
 	__u8 mode;
diff --git a/include/linux/netfilter/xt_MARK.h b/include/linux/netfilter/xt_MARK.h
index 028304b..bc9561b 100644
--- a/include/linux/netfilter/xt_MARK.h
+++ b/include/linux/netfilter/xt_MARK.h
@@ -3,23 +3,6 @@
 
 #include <linux/types.h>
 
-/* Version 0 */
-struct xt_mark_target_info {
-	unsigned long mark;
-};
-
-/* Version 1 */
-enum {
-	XT_MARK_SET=0,
-	XT_MARK_AND,
-	XT_MARK_OR,
-};
-
-struct xt_mark_target_info_v1 {
-	unsigned long mark;
-	__u8 mode;
-};
-
 struct xt_mark_tginfo2 {
 	__u32 mark, mask;
 };
diff --git a/include/linux/netfilter/xt_connmark.h b/include/linux/netfilter/xt_connmark.h
index 571e266..619e47c 100644
--- a/include/linux/netfilter/xt_connmark.h
+++ b/include/linux/netfilter/xt_connmark.h
@@ -12,11 +12,6 @@
  * (at your option) any later version.
  */
 
-struct xt_connmark_info {
-	unsigned long mark, mask;
-	__u8 invert;
-};
-
 struct xt_connmark_mtinfo1 {
 	__u32 mark, mask;
 	__u8 invert;
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index 7ae0533..54f47a2 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -32,42 +32,6 @@ enum {
 	XT_CONNTRACK_DIRECTION    = 1 << 12,
 };
 
-/* This is exposed to userspace, so remains frozen in time. */
-struct ip_conntrack_old_tuple
-{
-	struct {
-		__be32 ip;
-		union {
-			__u16 all;
-		} u;
-	} src;
-
-	struct {
-		__be32 ip;
-		union {
-			__u16 all;
-		} u;
-
-		/* The protocol. */
-		__u16 protonum;
-	} dst;
-};
-
-struct xt_conntrack_info
-{
-	unsigned int statemask, statusmask;
-
-	struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
-	struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
-
-	unsigned long expires_min, expires_max;
-
-	/* Flags word */
-	__u8 flags;
-	/* Inverse flags */
-	__u8 invflags;
-};
-
 struct xt_conntrack_mtinfo1 {
 	union nf_inet_addr origsrc_addr, origsrc_mask;
 	union nf_inet_addr origdst_addr, origdst_mask;
diff --git a/include/linux/netfilter/xt_mark.h b/include/linux/netfilter/xt_mark.h
index 6fa460a..6607c8f 100644
--- a/include/linux/netfilter/xt_mark.h
+++ b/include/linux/netfilter/xt_mark.h
@@ -3,11 +3,6 @@
 
 #include <linux/types.h>
 
-struct xt_mark_info {
-    unsigned long mark, mask;
-    __u8 invert;
-};
-
 struct xt_mark_mtinfo1 {
 	__u32 mark, mask;
 	__u8 invert;
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index 590ac3d..6fe3e6a 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -265,7 +265,7 @@ struct arpt_error
 }
 
 extern struct xt_table *arpt_register_table(struct net *net,
-					    struct xt_table *table,
+					    const struct xt_table *table,
 					    const struct arpt_replace *repl);
 extern void arpt_unregister_table(struct xt_table *table);
 extern unsigned int arpt_do_table(struct sk_buff *skb,
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index e40ddb9..ea281e6 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -301,7 +301,7 @@ struct ebt_table
 #define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \
 		     ~(__alignof__(struct ebt_replace)-1))
 extern struct ebt_table *ebt_register_table(struct net *net,
-					    struct ebt_table *table);
+					    const struct ebt_table *table);
 extern void ebt_unregister_table(struct ebt_table *table);
 extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
diff --git a/include/linux/netfilter_ipv4/Kbuild b/include/linux/netfilter_ipv4/Kbuild
index 3a7105b..431b407 100644
--- a/include/linux/netfilter_ipv4/Kbuild
+++ b/include/linux/netfilter_ipv4/Kbuild
@@ -1,46 +1,14 @@
-header-y += ipt_CLASSIFY.h
 header-y += ipt_CLUSTERIP.h
-header-y += ipt_CONNMARK.h
-header-y += ipt_DSCP.h
 header-y += ipt_ECN.h
 header-y += ipt_LOG.h
-header-y += ipt_MARK.h
-header-y += ipt_NFQUEUE.h
 header-y += ipt_REJECT.h
 header-y += ipt_SAME.h
-header-y += ipt_TCPMSS.h
-header-y += ipt_TOS.h
 header-y += ipt_TTL.h
 header-y += ipt_ULOG.h
 header-y += ipt_addrtype.h
 header-y += ipt_ah.h
-header-y += ipt_comment.h
-header-y += ipt_connbytes.h
-header-y += ipt_connmark.h
-header-y += ipt_conntrack.h
-header-y += ipt_dccp.h
-header-y += ipt_dscp.h
 header-y += ipt_ecn.h
-header-y += ipt_esp.h
-header-y += ipt_hashlimit.h
-header-y += ipt_helper.h
-header-y += ipt_iprange.h
-header-y += ipt_length.h
-header-y += ipt_limit.h
-header-y += ipt_mac.h
-header-y += ipt_mark.h
-header-y += ipt_multiport.h
-header-y += ipt_owner.h
-header-y += ipt_physdev.h
-header-y += ipt_pkttype.h
-header-y += ipt_policy.h
 header-y += ipt_realm.h
-header-y += ipt_recent.h
-header-y += ipt_sctp.h
-header-y += ipt_state.h
-header-y += ipt_string.h
-header-y += ipt_tcpmss.h
-header-y += ipt_tos.h
 header-y += ipt_ttl.h
 
 unifdef-y += ip_queue.h
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index 092bd50..61fafc8 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -245,7 +245,7 @@ ipt_get_target(struct ipt_entry *e)
 extern void ipt_init(void) __init;
 
 extern struct xt_table *ipt_register_table(struct net *net,
-					   struct xt_table *table,
+					   const struct xt_table *table,
 					   const struct ipt_replace *repl);
 extern void ipt_unregister_table(struct xt_table *table);
 
diff --git a/include/linux/netfilter_ipv4/ipt_CLASSIFY.h b/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
deleted file mode 100644
index a46d511..0000000
--- a/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IPT_CLASSIFY_H
-#define _IPT_CLASSIFY_H
-
-#include <linux/netfilter/xt_CLASSIFY.h>
-#define ipt_classify_target_info xt_classify_target_info
-
-#endif /*_IPT_CLASSIFY_H */
diff --git a/include/linux/netfilter_ipv4/ipt_CONNMARK.h b/include/linux/netfilter_ipv4/ipt_CONNMARK.h
deleted file mode 100644
index 9ecfee0..0000000
--- a/include/linux/netfilter_ipv4/ipt_CONNMARK.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _IPT_CONNMARK_H_target
-#define _IPT_CONNMARK_H_target
-
-/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
- * by Henrik Nordstrom <hno@marasystems.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/netfilter/xt_CONNMARK.h>
-#define IPT_CONNMARK_SET	XT_CONNMARK_SET
-#define IPT_CONNMARK_SAVE	XT_CONNMARK_SAVE
-#define	IPT_CONNMARK_RESTORE	XT_CONNMARK_RESTORE
-
-#define ipt_connmark_target_info xt_connmark_target_info
-
-#endif /*_IPT_CONNMARK_H_target*/
diff --git a/include/linux/netfilter_ipv4/ipt_DSCP.h b/include/linux/netfilter_ipv4/ipt_DSCP.h
deleted file mode 100644
index 3491e52..0000000
--- a/include/linux/netfilter_ipv4/ipt_DSCP.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* iptables module for setting the IPv4 DSCP field
- *
- * (C) 2002 Harald Welte <laforge@gnumonks.org>
- * based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com>
- * This software is distributed under GNU GPL v2, 1991
- * 
- * See RFC2474 for a description of the DSCP field within the IP Header.
- *
- * ipt_DSCP.h,v 1.7 2002/03/14 12:03:13 laforge Exp
-*/
-#ifndef _IPT_DSCP_TARGET_H
-#define _IPT_DSCP_TARGET_H
-#include <linux/netfilter_ipv4/ipt_dscp.h>
-#include <linux/netfilter/xt_DSCP.h>
-
-#define ipt_DSCP_info xt_DSCP_info
-
-#endif /* _IPT_DSCP_TARGET_H */
diff --git a/include/linux/netfilter_ipv4/ipt_ECN.h b/include/linux/netfilter_ipv4/ipt_ECN.h
index 94e0d98..7ca4591 100644
--- a/include/linux/netfilter_ipv4/ipt_ECN.h
+++ b/include/linux/netfilter_ipv4/ipt_ECN.h
@@ -8,9 +8,9 @@
 */
 #ifndef _IPT_ECN_TARGET_H
 #define _IPT_ECN_TARGET_H
-#include <linux/netfilter_ipv4/ipt_DSCP.h>
+#include <linux/netfilter/xt_DSCP.h>
 
-#define IPT_ECN_IP_MASK	(~IPT_DSCP_MASK)
+#define IPT_ECN_IP_MASK	(~XT_DSCP_MASK)
 
 #define IPT_ECN_OP_SET_IP	0x01	/* set ECN bits of IPv4 header */
 #define IPT_ECN_OP_SET_ECE	0x10	/* set ECE bit of TCP header */
diff --git a/include/linux/netfilter_ipv4/ipt_MARK.h b/include/linux/netfilter_ipv4/ipt_MARK.h
deleted file mode 100644
index 697a486..0000000
--- a/include/linux/netfilter_ipv4/ipt_MARK.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _IPT_MARK_H_target
-#define _IPT_MARK_H_target
-
-/* Backwards compatibility for old userspace */
-
-#include <linux/netfilter/xt_MARK.h>
-
-/* Version 0 */
-#define ipt_mark_target_info xt_mark_target_info
-
-/* Version 1 */
-#define IPT_MARK_SET	XT_MARK_SET
-#define IPT_MARK_AND	XT_MARK_AND
-#define	IPT_MARK_OR	XT_MARK_OR
-
-#define ipt_mark_target_info_v1 xt_mark_target_info_v1
-
-#endif /*_IPT_MARK_H_target*/
diff --git a/include/linux/netfilter_ipv4/ipt_NFQUEUE.h b/include/linux/netfilter_ipv4/ipt_NFQUEUE.h
deleted file mode 100644
index 97a2a75..0000000
--- a/include/linux/netfilter_ipv4/ipt_NFQUEUE.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* iptables module for using NFQUEUE mechanism
- *
- * (C) 2005 Harald Welte <laforge@netfilter.org>
- *
- * This software is distributed under GNU GPL v2, 1991
- * 
-*/
-#ifndef _IPT_NFQ_TARGET_H
-#define _IPT_NFQ_TARGET_H
-
-/* Backwards compatibility for old userspace */
-#include <linux/netfilter/xt_NFQUEUE.h>
-
-#define ipt_NFQ_info xt_NFQ_info
-
-#endif /* _IPT_DSCP_TARGET_H */
diff --git a/include/linux/netfilter_ipv4/ipt_TCPMSS.h b/include/linux/netfilter_ipv4/ipt_TCPMSS.h
deleted file mode 100644
index 7a850f9..0000000
--- a/include/linux/netfilter_ipv4/ipt_TCPMSS.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _IPT_TCPMSS_H
-#define _IPT_TCPMSS_H
-
-#include <linux/netfilter/xt_TCPMSS.h>
-
-#define ipt_tcpmss_info		xt_tcpmss_info
-#define IPT_TCPMSS_CLAMP_PMTU	XT_TCPMSS_CLAMP_PMTU
-
-#endif /*_IPT_TCPMSS_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_TOS.h b/include/linux/netfilter_ipv4/ipt_TOS.h
deleted file mode 100644
index 6bf9e1f..0000000
--- a/include/linux/netfilter_ipv4/ipt_TOS.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _IPT_TOS_H_target
-#define _IPT_TOS_H_target
-
-#ifndef IPTOS_NORMALSVC
-#define IPTOS_NORMALSVC 0
-#endif
-
-struct ipt_tos_target_info {
-	u_int8_t tos;
-};
-
-#endif /*_IPT_TOS_H_target*/
diff --git a/include/linux/netfilter_ipv4/ipt_comment.h b/include/linux/netfilter_ipv4/ipt_comment.h
deleted file mode 100644
index ae2afc2..0000000
--- a/include/linux/netfilter_ipv4/ipt_comment.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _IPT_COMMENT_H
-#define _IPT_COMMENT_H
-
-#include <linux/netfilter/xt_comment.h>
-
-#define IPT_MAX_COMMENT_LEN XT_MAX_COMMENT_LEN
-
-#define ipt_comment_info xt_comment_info
-
-#endif /* _IPT_COMMENT_H */
diff --git a/include/linux/netfilter_ipv4/ipt_connbytes.h b/include/linux/netfilter_ipv4/ipt_connbytes.h
deleted file mode 100644
index f63e6ee..0000000
--- a/include/linux/netfilter_ipv4/ipt_connbytes.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _IPT_CONNBYTES_H
-#define _IPT_CONNBYTES_H
-
-#include <linux/netfilter/xt_connbytes.h>
-#define ipt_connbytes_what xt_connbytes_what
-
-#define IPT_CONNBYTES_PKTS	XT_CONNBYTES_PKTS
-#define IPT_CONNBYTES_BYTES	XT_CONNBYTES_BYTES
-#define IPT_CONNBYTES_AVGPKT	XT_CONNBYTES_AVGPKT
-
-#define ipt_connbytes_direction 	xt_connbytes_direction
-#define IPT_CONNBYTES_DIR_ORIGINAL 	XT_CONNBYTES_DIR_ORIGINAL
-#define IPT_CONNBYTES_DIR_REPLY 	XT_CONNBYTES_DIR_REPLY
-#define IPT_CONNBYTES_DIR_BOTH		XT_CONNBYTES_DIR_BOTH
-
-#define ipt_connbytes_info xt_connbytes_info
-
-#endif
diff --git a/include/linux/netfilter_ipv4/ipt_connmark.h b/include/linux/netfilter_ipv4/ipt_connmark.h
deleted file mode 100644
index c7ba656..0000000
--- a/include/linux/netfilter_ipv4/ipt_connmark.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IPT_CONNMARK_H
-#define _IPT_CONNMARK_H
-
-#include <linux/netfilter/xt_connmark.h>
-#define ipt_connmark_info xt_connmark_info
-
-#endif /*_IPT_CONNMARK_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_conntrack.h b/include/linux/netfilter_ipv4/ipt_conntrack.h
deleted file mode 100644
index cde6762..0000000
--- a/include/linux/netfilter_ipv4/ipt_conntrack.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Header file for kernel module to match connection tracking information.
- * GPL (C) 2001  Marc Boucher (marc@mbsi.ca).
- */
-
-#ifndef _IPT_CONNTRACK_H
-#define _IPT_CONNTRACK_H
-
-#include <linux/netfilter/xt_conntrack.h>
-
-#define IPT_CONNTRACK_STATE_BIT(ctinfo) XT_CONNTRACK_STATE_BIT(ctinfo)
-#define IPT_CONNTRACK_STATE_INVALID 	XT_CONNTRACK_STATE_INVALID
-
-#define IPT_CONNTRACK_STATE_SNAT 	XT_CONNTRACK_STATE_SNAT
-#define IPT_CONNTRACK_STATE_DNAT	XT_CONNTRACK_STATE_DNAT
-#define IPT_CONNTRACK_STATE_UNTRACKED	XT_CONNTRACK_STATE_UNTRACKED
-
-/* flags, invflags: */
-#define IPT_CONNTRACK_STATE		XT_CONNTRACK_STATE
-#define IPT_CONNTRACK_PROTO		XT_CONNTRACK_PROTO
-#define IPT_CONNTRACK_ORIGSRC		XT_CONNTRACK_ORIGSRC
-#define IPT_CONNTRACK_ORIGDST		XT_CONNTRACK_ORIGDST
-#define IPT_CONNTRACK_REPLSRC		XT_CONNTRACK_REPLSRC
-#define IPT_CONNTRACK_REPLDST		XT_CONNTRACK_REPLDST
-#define IPT_CONNTRACK_STATUS		XT_CONNTRACK_STATUS
-#define IPT_CONNTRACK_EXPIRES		XT_CONNTRACK_EXPIRES
-
-#define ipt_conntrack_info		xt_conntrack_info
-#endif /*_IPT_CONNTRACK_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_dccp.h b/include/linux/netfilter_ipv4/ipt_dccp.h
deleted file mode 100644
index e70d11e..0000000
--- a/include/linux/netfilter_ipv4/ipt_dccp.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _IPT_DCCP_H_
-#define _IPT_DCCP_H_
-
-#include <linux/netfilter/xt_dccp.h>
-#define IPT_DCCP_SRC_PORTS	XT_DCCP_SRC_PORTS
-#define IPT_DCCP_DEST_PORTS	XT_DCCP_DEST_PORTS
-#define IPT_DCCP_TYPE		XT_DCCP_TYPE
-#define IPT_DCCP_OPTION		XT_DCCP_OPTION
-
-#define IPT_DCCP_VALID_FLAGS 	XT_DCCP_VALID_FLAGS
-
-#define ipt_dccp_info xt_dccp_info
-
-#endif /* _IPT_DCCP_H_ */
-
diff --git a/include/linux/netfilter_ipv4/ipt_dscp.h b/include/linux/netfilter_ipv4/ipt_dscp.h
deleted file mode 100644
index 4b82ca9..0000000
--- a/include/linux/netfilter_ipv4/ipt_dscp.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* iptables module for matching the IPv4 DSCP field
- *
- * (C) 2002 Harald Welte <laforge@gnumonks.org>
- * This software is distributed under GNU GPL v2, 1991
- * 
- * See RFC2474 for a description of the DSCP field within the IP Header.
- *
- * ipt_dscp.h,v 1.3 2002/08/05 19:00:21 laforge Exp
-*/
-#ifndef _IPT_DSCP_H
-#define _IPT_DSCP_H
-
-#include <linux/netfilter/xt_dscp.h>
-
-#define IPT_DSCP_MASK	XT_DSCP_MASK
-#define IPT_DSCP_SHIFT	XT_DSCP_SHIFT
-#define IPT_DSCP_MAX	XT_DSCP_MAX
-
-#define ipt_dscp_info	xt_dscp_info
-
-#endif /* _IPT_DSCP_H */
diff --git a/include/linux/netfilter_ipv4/ipt_ecn.h b/include/linux/netfilter_ipv4/ipt_ecn.h
index 1f0d9a4..9945baa 100644
--- a/include/linux/netfilter_ipv4/ipt_ecn.h
+++ b/include/linux/netfilter_ipv4/ipt_ecn.h
@@ -8,9 +8,9 @@
 */
 #ifndef _IPT_ECN_H
 #define _IPT_ECN_H
-#include <linux/netfilter_ipv4/ipt_dscp.h>
+#include <linux/netfilter/xt_dscp.h>
 
-#define IPT_ECN_IP_MASK	(~IPT_DSCP_MASK)
+#define IPT_ECN_IP_MASK	(~XT_DSCP_MASK)
 
 #define IPT_ECN_OP_MATCH_IP	0x01
 #define IPT_ECN_OP_MATCH_ECE	0x10
diff --git a/include/linux/netfilter_ipv4/ipt_esp.h b/include/linux/netfilter_ipv4/ipt_esp.h
deleted file mode 100644
index 78296e7..0000000
--- a/include/linux/netfilter_ipv4/ipt_esp.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _IPT_ESP_H
-#define _IPT_ESP_H
-
-#include <linux/netfilter/xt_esp.h>
-
-#define ipt_esp xt_esp
-#define IPT_ESP_INV_SPI		XT_ESP_INV_SPI
-#define IPT_ESP_INV_MASK	XT_ESP_INV_MASK
-
-#endif /*_IPT_ESP_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_hashlimit.h b/include/linux/netfilter_ipv4/ipt_hashlimit.h
deleted file mode 100644
index 5662120..0000000
--- a/include/linux/netfilter_ipv4/ipt_hashlimit.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _IPT_HASHLIMIT_H
-#define _IPT_HASHLIMIT_H
-
-#include <linux/netfilter/xt_hashlimit.h>
-
-#define IPT_HASHLIMIT_SCALE	XT_HASHLIMIT_SCALE
-#define IPT_HASHLIMIT_HASH_DIP	XT_HASHLIMIT_HASH_DIP
-#define IPT_HASHLIMIT_HASH_DPT	XT_HASHLIMIT_HASH_DPT
-#define IPT_HASHLIMIT_HASH_SIP	XT_HASHLIMIT_HASH_SIP
-#define IPT_HASHLIMIT_HASH_SPT	XT_HASHLIMIT_HASH_SPT
-
-#define ipt_hashlimit_info xt_hashlimit_info
-
-#endif /* _IPT_HASHLIMIT_H */
diff --git a/include/linux/netfilter_ipv4/ipt_helper.h b/include/linux/netfilter_ipv4/ipt_helper.h
deleted file mode 100644
index 80452c2..0000000
--- a/include/linux/netfilter_ipv4/ipt_helper.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IPT_HELPER_H
-#define _IPT_HELPER_H
-
-#include <linux/netfilter/xt_helper.h>
-#define ipt_helper_info xt_helper_info
-
-#endif /* _IPT_HELPER_H */
diff --git a/include/linux/netfilter_ipv4/ipt_iprange.h b/include/linux/netfilter_ipv4/ipt_iprange.h
deleted file mode 100644
index 5f1aebd..0000000
--- a/include/linux/netfilter_ipv4/ipt_iprange.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _IPT_IPRANGE_H
-#define _IPT_IPRANGE_H
-
-#include <linux/types.h>
-#include <linux/netfilter/xt_iprange.h>
-
-struct ipt_iprange {
-	/* Inclusive: network order. */
-	__be32 min_ip, max_ip;
-};
-
-struct ipt_iprange_info
-{
-	struct ipt_iprange src;
-	struct ipt_iprange dst;
-
-	/* Flags from above */
-	u_int8_t flags;
-};
-
-#endif /* _IPT_IPRANGE_H */
diff --git a/include/linux/netfilter_ipv4/ipt_length.h b/include/linux/netfilter_ipv4/ipt_length.h
deleted file mode 100644
index 9b45206..0000000
--- a/include/linux/netfilter_ipv4/ipt_length.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IPT_LENGTH_H
-#define _IPT_LENGTH_H
-
-#include <linux/netfilter/xt_length.h>
-#define ipt_length_info xt_length_info
-
-#endif /*_IPT_LENGTH_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_limit.h b/include/linux/netfilter_ipv4/ipt_limit.h
deleted file mode 100644
index 92f5cd0..0000000
--- a/include/linux/netfilter_ipv4/ipt_limit.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _IPT_RATE_H
-#define _IPT_RATE_H
-
-#include <linux/netfilter/xt_limit.h>
-#define IPT_LIMIT_SCALE XT_LIMIT_SCALE
-#define ipt_rateinfo xt_rateinfo
-
-#endif /*_IPT_RATE_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_mac.h b/include/linux/netfilter_ipv4/ipt_mac.h
deleted file mode 100644
index b186008..0000000
--- a/include/linux/netfilter_ipv4/ipt_mac.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IPT_MAC_H
-#define _IPT_MAC_H
-
-#include <linux/netfilter/xt_mac.h>
-#define ipt_mac_info xt_mac_info
-
-#endif /*_IPT_MAC_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_mark.h b/include/linux/netfilter_ipv4/ipt_mark.h
deleted file mode 100644
index bfde67c..0000000
--- a/include/linux/netfilter_ipv4/ipt_mark.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _IPT_MARK_H
-#define _IPT_MARK_H
-
-/* Backwards compatibility for old userspace */
-#include <linux/netfilter/xt_mark.h>
-
-#define ipt_mark_info xt_mark_info
-
-#endif /*_IPT_MARK_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_multiport.h b/include/linux/netfilter_ipv4/ipt_multiport.h
deleted file mode 100644
index 55fe85e..0000000
--- a/include/linux/netfilter_ipv4/ipt_multiport.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _IPT_MULTIPORT_H
-#define _IPT_MULTIPORT_H
-
-#include <linux/netfilter/xt_multiport.h>
-
-#define IPT_MULTIPORT_SOURCE		XT_MULTIPORT_SOURCE
-#define IPT_MULTIPORT_DESTINATION	XT_MULTIPORT_DESTINATION
-#define IPT_MULTIPORT_EITHER		XT_MULTIPORT_EITHER
-
-#define IPT_MULTI_PORTS			XT_MULTI_PORTS
-
-#define ipt_multiport			xt_multiport
-#define ipt_multiport_v1		xt_multiport_v1
-
-#endif /*_IPT_MULTIPORT_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_owner.h b/include/linux/netfilter_ipv4/ipt_owner.h
deleted file mode 100644
index a78445b..0000000
--- a/include/linux/netfilter_ipv4/ipt_owner.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _IPT_OWNER_H
-#define _IPT_OWNER_H
-
-/* match and invert flags */
-#define IPT_OWNER_UID	0x01
-#define IPT_OWNER_GID	0x02
-#define IPT_OWNER_PID	0x04
-#define IPT_OWNER_SID	0x08
-#define IPT_OWNER_COMM	0x10
-
-struct ipt_owner_info {
-    __kernel_uid32_t uid;
-    __kernel_gid32_t gid;
-    __kernel_pid_t pid;
-    __kernel_pid_t sid;
-    char comm[16];
-    u_int8_t match, invert;	/* flags */
-};
-
-#endif /*_IPT_OWNER_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_physdev.h b/include/linux/netfilter_ipv4/ipt_physdev.h
deleted file mode 100644
index 2400e71..0000000
--- a/include/linux/netfilter_ipv4/ipt_physdev.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _IPT_PHYSDEV_H
-#define _IPT_PHYSDEV_H
-
-/* Backwards compatibility for old userspace */
-
-#include <linux/netfilter/xt_physdev.h>
-
-#define IPT_PHYSDEV_OP_IN		XT_PHYSDEV_OP_IN
-#define IPT_PHYSDEV_OP_OUT		XT_PHYSDEV_OP_OUT
-#define IPT_PHYSDEV_OP_BRIDGED		XT_PHYSDEV_OP_BRIDGED
-#define IPT_PHYSDEV_OP_ISIN		XT_PHYSDEV_OP_ISIN
-#define IPT_PHYSDEV_OP_ISOUT		XT_PHYSDEV_OP_ISOUT
-#define IPT_PHYSDEV_OP_MASK		XT_PHYSDEV_OP_MASK
-
-#define ipt_physdev_info xt_physdev_info
-
-#endif /*_IPT_PHYSDEV_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_pkttype.h b/include/linux/netfilter_ipv4/ipt_pkttype.h
deleted file mode 100644
index ff1fbc9..0000000
--- a/include/linux/netfilter_ipv4/ipt_pkttype.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IPT_PKTTYPE_H
-#define _IPT_PKTTYPE_H
-
-#include <linux/netfilter/xt_pkttype.h>
-#define ipt_pkttype_info xt_pkttype_info
-
-#endif /*_IPT_PKTTYPE_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h
deleted file mode 100644
index 1037fb2..0000000
--- a/include/linux/netfilter_ipv4/ipt_policy.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _IPT_POLICY_H
-#define _IPT_POLICY_H
-
-#include <linux/netfilter/xt_policy.h>
-
-#define IPT_POLICY_MAX_ELEM		XT_POLICY_MAX_ELEM
-
-/* ipt_policy_flags */
-#define IPT_POLICY_MATCH_IN		XT_POLICY_MATCH_IN
-#define IPT_POLICY_MATCH_OUT		XT_POLICY_MATCH_OUT
-#define IPT_POLICY_MATCH_NONE		XT_POLICY_MATCH_NONE
-#define IPT_POLICY_MATCH_STRICT		XT_POLICY_MATCH_STRICT
-
-/* ipt_policy_modes */
-#define IPT_POLICY_MODE_TRANSPORT	XT_POLICY_MODE_TRANSPORT
-#define IPT_POLICY_MODE_TUNNEL		XT_POLICY_MODE_TUNNEL
-
-#define ipt_policy_spec			xt_policy_spec
-#define ipt_policy_addr			xt_policy_addr
-#define ipt_policy_elem			xt_policy_elem
-#define ipt_policy_info			xt_policy_info
-
-#endif /* _IPT_POLICY_H */
diff --git a/include/linux/netfilter_ipv4/ipt_recent.h b/include/linux/netfilter_ipv4/ipt_recent.h
deleted file mode 100644
index d636cca..0000000
--- a/include/linux/netfilter_ipv4/ipt_recent.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _IPT_RECENT_H
-#define _IPT_RECENT_H
-
-#include <linux/netfilter/xt_recent.h>
-
-#define ipt_recent_info xt_recent_mtinfo
-
-enum {
-	IPT_RECENT_CHECK    = XT_RECENT_CHECK,
-	IPT_RECENT_SET      = XT_RECENT_SET,
-	IPT_RECENT_UPDATE   = XT_RECENT_UPDATE,
-	IPT_RECENT_REMOVE   = XT_RECENT_REMOVE,
-	IPT_RECENT_TTL      = XT_RECENT_TTL,
-
-	IPT_RECENT_SOURCE   = XT_RECENT_SOURCE,
-	IPT_RECENT_DEST     = XT_RECENT_DEST,
-
-	IPT_RECENT_NAME_LEN = XT_RECENT_NAME_LEN,
-};
-
-#endif /*_IPT_RECENT_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_sctp.h b/include/linux/netfilter_ipv4/ipt_sctp.h
deleted file mode 100644
index 80b3dba..0000000
--- a/include/linux/netfilter_ipv4/ipt_sctp.h
+++ /dev/null
@@ -1,105 +0,0 @@
-#ifndef _IPT_SCTP_H_
-#define _IPT_SCTP_H_
-
-#define IPT_SCTP_SRC_PORTS	        0x01
-#define IPT_SCTP_DEST_PORTS	        0x02
-#define IPT_SCTP_CHUNK_TYPES		0x04
-
-#define IPT_SCTP_VALID_FLAGS		0x07
-
-
-struct ipt_sctp_flag_info {
-	u_int8_t chunktype;
-	u_int8_t flag;
-	u_int8_t flag_mask;
-};
-
-#define IPT_NUM_SCTP_FLAGS	4
-
-struct ipt_sctp_info {
-	u_int16_t dpts[2];  /* Min, Max */
-	u_int16_t spts[2];  /* Min, Max */
-
-	u_int32_t chunkmap[256 / sizeof (u_int32_t)];  /* Bit mask of chunks to be matched according to RFC 2960 */
-
-#define SCTP_CHUNK_MATCH_ANY   0x01  /* Match if any of the chunk types are present */
-#define SCTP_CHUNK_MATCH_ALL   0x02  /* Match if all of the chunk types are present */
-#define SCTP_CHUNK_MATCH_ONLY  0x04  /* Match if these are the only chunk types present */
-
-	u_int32_t chunk_match_type;
-	struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
-	int flag_count;
-
-	u_int32_t flags;
-	u_int32_t invflags;
-};
-
-#define bytes(type) (sizeof(type) * 8)
-
-#define SCTP_CHUNKMAP_SET(chunkmap, type) 		\
-	do { 						\
-		chunkmap[type / bytes(u_int32_t)] |= 	\
-			1 << (type % bytes(u_int32_t));	\
-	} while (0)
-
-#define SCTP_CHUNKMAP_CLEAR(chunkmap, type)		 	\
-	do {							\
-		chunkmap[type / bytes(u_int32_t)] &= 		\
-			~(1 << (type % bytes(u_int32_t)));	\
-	} while (0)
-
-#define SCTP_CHUNKMAP_IS_SET(chunkmap, type) 			\
-({								\
-	(chunkmap[type / bytes (u_int32_t)] & 			\
-		(1 << (type % bytes (u_int32_t)))) ? 1: 0;	\
-})
-
-#define SCTP_CHUNKMAP_RESET(chunkmap) 				\
-	do {							\
-		int i; 						\
-		for (i = 0; i < ARRAY_SIZE(chunkmap); i++)	\
-			chunkmap[i] = 0;			\
-	} while (0)
-
-#define SCTP_CHUNKMAP_SET_ALL(chunkmap) 			\
-	do {							\
-		int i; 						\
-		for (i = 0; i < ARRAY_SIZE(chunkmap); i++)	\
-			chunkmap[i] = ~0;			\
-	} while (0)
-
-#define SCTP_CHUNKMAP_COPY(destmap, srcmap) 			\
-	do {							\
-		int i; 						\
-		for (i = 0; i < ARRAY_SIZE(chunkmap); i++)	\
-			destmap[i] = srcmap[i];			\
-	} while (0)
-
-#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap) 		\
-({							\
-	int i; 						\
-	int flag = 1;					\
-	for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {	\
-		if (chunkmap[i]) {			\
-			flag = 0;			\
-			break;				\
-		}					\
-	}						\
-        flag;						\
-})
-
-#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap) 		\
-({							\
-	int i; 						\
-	int flag = 1;					\
-	for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {	\
-		if (chunkmap[i] != ~0) {		\
-			flag = 0;			\
-				break;			\
-		}					\
-	}						\
-        flag;						\
-})
-
-#endif /* _IPT_SCTP_H_ */
-
diff --git a/include/linux/netfilter_ipv4/ipt_state.h b/include/linux/netfilter_ipv4/ipt_state.h
deleted file mode 100644
index a44a99c..0000000
--- a/include/linux/netfilter_ipv4/ipt_state.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _IPT_STATE_H
-#define _IPT_STATE_H
-
-/* Backwards compatibility for old userspace */
-
-#include <linux/netfilter/xt_state.h>
-
-#define IPT_STATE_BIT		XT_STATE_BIT
-#define IPT_STATE_INVALID	XT_STATE_INVALID
-
-#define IPT_STATE_UNTRACKED	XT_STATE_UNTRACKED
-
-#define ipt_state_info		xt_state_info
-
-#endif /*_IPT_STATE_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_string.h b/include/linux/netfilter_ipv4/ipt_string.h
deleted file mode 100644
index c26de30..0000000
--- a/include/linux/netfilter_ipv4/ipt_string.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _IPT_STRING_H
-#define _IPT_STRING_H
-
-#include <linux/netfilter/xt_string.h>
-
-#define IPT_STRING_MAX_PATTERN_SIZE XT_STRING_MAX_PATTERN_SIZE
-#define IPT_STRING_MAX_ALGO_NAME_SIZE XT_STRING_MAX_ALGO_NAME_SIZE
-#define ipt_string_info xt_string_info
-
-#endif /*_IPT_STRING_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_tcpmss.h b/include/linux/netfilter_ipv4/ipt_tcpmss.h
deleted file mode 100644
index 18bbc8e..0000000
--- a/include/linux/netfilter_ipv4/ipt_tcpmss.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IPT_TCPMSS_MATCH_H
-#define _IPT_TCPMSS_MATCH_H
-
-#include <linux/netfilter/xt_tcpmss.h>
-#define ipt_tcpmss_match_info xt_tcpmss_match_info
-
-#endif /*_IPT_TCPMSS_MATCH_H*/
diff --git a/include/linux/netfilter_ipv4/ipt_tos.h b/include/linux/netfilter_ipv4/ipt_tos.h
deleted file mode 100644
index a21f5df..0000000
--- a/include/linux/netfilter_ipv4/ipt_tos.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _IPT_TOS_H
-#define _IPT_TOS_H
-
-struct ipt_tos_info {
-    u_int8_t tos;
-    u_int8_t invert;
-};
-
-#ifndef IPTOS_NORMALSVC
-#define IPTOS_NORMALSVC 0
-#endif
-
-#endif /*_IPT_TOS_H*/
diff --git a/include/linux/netfilter_ipv6/Kbuild b/include/linux/netfilter_ipv6/Kbuild
index aca4bd1..e864eae 100644
--- a/include/linux/netfilter_ipv6/Kbuild
+++ b/include/linux/netfilter_ipv6/Kbuild
@@ -1,22 +1,12 @@
 header-y += ip6t_HL.h
 header-y += ip6t_LOG.h
-header-y += ip6t_MARK.h
 header-y += ip6t_REJECT.h
 header-y += ip6t_ah.h
-header-y += ip6t_esp.h
 header-y += ip6t_frag.h
-header-y += ip6t_hl.h
 header-y += ip6t_ipv6header.h
-header-y += ip6t_length.h
-header-y += ip6t_limit.h
-header-y += ip6t_mac.h
-header-y += ip6t_mark.h
+header-y += ip6t_hl.h
 header-y += ip6t_mh.h
-header-y += ip6t_multiport.h
 header-y += ip6t_opts.h
-header-y += ip6t_owner.h
-header-y += ip6t_physdev.h
-header-y += ip6t_policy.h
 header-y += ip6t_rt.h
 
 unifdef-y += ip6_tables.h
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 1089e33..a64e145 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -306,7 +306,7 @@ ip6t_get_target(struct ip6t_entry *e)
 extern void ip6t_init(void) __init;
 
 extern struct xt_table *ip6t_register_table(struct net *net,
-					    struct xt_table *table,
+					    const struct xt_table *table,
 					    const struct ip6t_replace *repl);
 extern void ip6t_unregister_table(struct xt_table *table);
 extern unsigned int ip6t_do_table(struct sk_buff *skb,
diff --git a/include/linux/netfilter_ipv6/ip6t_MARK.h b/include/linux/netfilter_ipv6/ip6t_MARK.h
deleted file mode 100644
index 7cf629a..0000000
--- a/include/linux/netfilter_ipv6/ip6t_MARK.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _IP6T_MARK_H_target
-#define _IP6T_MARK_H_target
-
-/* Backwards compatibility for old userspace */
-#include <linux/netfilter/xt_MARK.h>
-
-#define ip6t_mark_target_info xt_mark_target_info
-
-#endif /*_IP6T_MARK_H_target*/
diff --git a/include/linux/netfilter_ipv6/ip6t_esp.h b/include/linux/netfilter_ipv6/ip6t_esp.h
deleted file mode 100644
index f62eaf5..0000000
--- a/include/linux/netfilter_ipv6/ip6t_esp.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef _IP6T_ESP_H
-#define _IP6T_ESP_H
-
-#include <linux/netfilter/xt_esp.h>
-
-#define ip6t_esp xt_esp
-#define IP6T_ESP_INV_SPI	XT_ESP_INV_SPI
-#define IP6T_ESP_INV_MASK	XT_ESP_INV_MASK
-
-#endif /*_IP6T_ESP_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_length.h b/include/linux/netfilter_ipv6/ip6t_length.h
deleted file mode 100644
index 9e9689d..0000000
--- a/include/linux/netfilter_ipv6/ip6t_length.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _IP6T_LENGTH_H
-#define _IP6T_LENGTH_H
-
-#include <linux/netfilter/xt_length.h>
-#define ip6t_length_info xt_length_info
-
-#endif /*_IP6T_LENGTH_H*/
-	
diff --git a/include/linux/netfilter_ipv6/ip6t_limit.h b/include/linux/netfilter_ipv6/ip6t_limit.h
deleted file mode 100644
index 487e5ea..0000000
--- a/include/linux/netfilter_ipv6/ip6t_limit.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _IP6T_RATE_H
-#define _IP6T_RATE_H
-
-#include <linux/netfilter/xt_limit.h>
-#define IP6T_LIMIT_SCALE XT_LIMIT_SCALE
-#define ip6t_rateinfo xt_rateinfo
-
-#endif /*_IP6T_RATE_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_mac.h b/include/linux/netfilter_ipv6/ip6t_mac.h
deleted file mode 100644
index ac58e83..0000000
--- a/include/linux/netfilter_ipv6/ip6t_mac.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _IP6T_MAC_H
-#define _IP6T_MAC_H
-
-#include <linux/netfilter/xt_mac.h>
-#define ip6t_mac_info xt_mac_info
-
-#endif /*_IP6T_MAC_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_mark.h b/include/linux/netfilter_ipv6/ip6t_mark.h
deleted file mode 100644
index ff20495..0000000
--- a/include/linux/netfilter_ipv6/ip6t_mark.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _IP6T_MARK_H
-#define _IP6T_MARK_H
-
-/* Backwards compatibility for old userspace */
-#include <linux/netfilter/xt_mark.h>
-
-#define ip6t_mark_info xt_mark_info
-
-#endif /*_IPT_MARK_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_multiport.h b/include/linux/netfilter_ipv6/ip6t_multiport.h
deleted file mode 100644
index 042c926..0000000
--- a/include/linux/netfilter_ipv6/ip6t_multiport.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _IP6T_MULTIPORT_H
-#define _IP6T_MULTIPORT_H
-
-#include <linux/netfilter/xt_multiport.h>
-
-#define IP6T_MULTIPORT_SOURCE		XT_MULTIPORT_SOURCE
-#define IP6T_MULTIPORT_DESTINATION	XT_MULTIPORT_DESTINATION
-#define IP6T_MULTIPORT_EITHER		XT_MULTIPORT_EITHER
-
-#define IP6T_MULTI_PORTS		XT_MULTI_PORTS
-
-#define ip6t_multiport			xt_multiport
-
-#endif /*_IP6T_MULTIPORT_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_owner.h b/include/linux/netfilter_ipv6/ip6t_owner.h
deleted file mode 100644
index ec5cc7a..0000000
--- a/include/linux/netfilter_ipv6/ip6t_owner.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _IP6T_OWNER_H
-#define _IP6T_OWNER_H
-
-/* match and invert flags */
-#define IP6T_OWNER_UID	0x01
-#define IP6T_OWNER_GID	0x02
-#define IP6T_OWNER_PID	0x04
-#define IP6T_OWNER_SID	0x08
-
-struct ip6t_owner_info {
-    __kernel_uid32_t uid;
-    __kernel_gid32_t gid;
-    __kernel_pid_t pid;
-    __kernel_pid_t sid;
-    u_int8_t match, invert;	/* flags */
-};
-
-#endif /*_IPT_OWNER_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_physdev.h b/include/linux/netfilter_ipv6/ip6t_physdev.h
deleted file mode 100644
index c161c0a..0000000
--- a/include/linux/netfilter_ipv6/ip6t_physdev.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _IP6T_PHYSDEV_H
-#define _IP6T_PHYSDEV_H
-
-/* Backwards compatibility for old userspace */
-
-#include <linux/netfilter/xt_physdev.h>
-
-#define IP6T_PHYSDEV_OP_IN		XT_PHYSDEV_OP_IN
-#define IP6T_PHYSDEV_OP_OUT		XT_PHYSDEV_OP_OUT
-#define IP6T_PHYSDEV_OP_BRIDGED		XT_PHYSDEV_OP_BRIDGED
-#define IP6T_PHYSDEV_OP_ISIN		XT_PHYSDEV_OP_ISIN
-#define IP6T_PHYSDEV_OP_ISOUT		XT_PHYSDEV_OP_ISOUT
-#define IP6T_PHYSDEV_OP_MASK		XT_PHYSDEV_OP_MASK
-
-#define ip6t_physdev_info xt_physdev_info
-
-#endif /*_IP6T_PHYSDEV_H*/
diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h
deleted file mode 100644
index b1c449d..0000000
--- a/include/linux/netfilter_ipv6/ip6t_policy.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _IP6T_POLICY_H
-#define _IP6T_POLICY_H
-
-#include <linux/netfilter/xt_policy.h>
-
-#define IP6T_POLICY_MAX_ELEM		XT_POLICY_MAX_ELEM
-
-/* ip6t_policy_flags */
-#define IP6T_POLICY_MATCH_IN		XT_POLICY_MATCH_IN
-#define IP6T_POLICY_MATCH_OUT		XT_POLICY_MATCH_OUT
-#define IP6T_POLICY_MATCH_NONE		XT_POLICY_MATCH_NONE
-#define IP6T_POLICY_MATCH_STRICT	XT_POLICY_MATCH_STRICT
-
-/* ip6t_policy_modes */
-#define IP6T_POLICY_MODE_TRANSPORT	XT_POLICY_MODE_TRANSPORT
-#define IP6T_POLICY_MODE_TUNNEL		XT_POLICY_MODE_TUNNEL
-
-#define ip6t_policy_spec		xt_policy_spec
-#define ip6t_policy_addr		xt_policy_addr
-#define ip6t_policy_elem		xt_policy_elem
-#define ip6t_policy_info		xt_policy_info
-
-#endif /* _IP6T_POLICY_H */
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 5ba398e..080f6ba 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -176,12 +176,16 @@ struct netlink_skb_parms
 #define NETLINK_CREDS(skb)	(&NETLINK_CB((skb)).creds)
 
 
+extern void netlink_table_grab(void);
+extern void netlink_table_ungrab(void);
+
 extern struct sock *netlink_kernel_create(struct net *net,
 					  int unit,unsigned int groups,
 					  void (*input)(struct sk_buff *skb),
 					  struct mutex *cb_mutex,
 					  struct module *module);
 extern void netlink_kernel_release(struct sock *sk);
+extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern void netlink_clear_multicast_users(struct sock *sk, unsigned int group);
 extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
@@ -217,12 +221,13 @@ int netlink_sendskb(struct sock *sk, struct sk_buff *skb);
 
 struct netlink_callback
 {
-	struct sk_buff	*skb;
-	struct nlmsghdr	*nlh;
-	int		(*dump)(struct sk_buff * skb, struct netlink_callback *cb);
-	int		(*done)(struct netlink_callback *cb);
-	int		family;
-	long		args[6];
+	struct sk_buff		*skb;
+	const struct nlmsghdr	*nlh;
+	int			(*dump)(struct sk_buff * skb,
+					struct netlink_callback *cb);
+	int			(*done)(struct netlink_callback *cb);
+	int			family;
+	long			args[6];
 };
 
 struct netlink_notify
@@ -258,7 +263,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
 	NLMSG_NEW(skb, pid, seq, type, len, 0)
 
 extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
-			      struct nlmsghdr *nlh,
+			      const struct nlmsghdr *nlh,
 			      int (*dump)(struct sk_buff *skb, struct netlink_callback*),
 			      int (*done)(struct netlink_callback*));
 
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index dbea93b..a8d71ed 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -242,6 +242,29 @@
  * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
  *	determined by the network interface.
  *
+ * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute
+ *	to identify the device, and the TESTDATA blob attribute to pass through
+ *	to the driver.
+ *
+ * @NL80211_CMD_CONNECT: connection request and notification; this command
+ *	requests to connect to a specified network but without separating
+ *	auth and assoc steps. For this, you need to specify the SSID in a
+ *	%NL80211_ATTR_SSID attribute, and can optionally specify the association
+ *	IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC,
+ *	%NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_CONTROL_PORT.
+ *	It is also sent as an event, with the BSSID and response IEs when the
+ *	connection is established or failed to be established. This can be
+ *	determined by the STATUS_CODE attribute.
+ * @NL80211_CMD_ROAM: request that the card roam (currently not implemented),
+ *	sent as an event when the card/driver roamed by itself.
+ * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
+ *	userspace that a connection was dropped by the AP or due to other
+ *	reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
+ *	%NL80211_ATTR_REASON_CODE attributes are used.
+ *
+ * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices
+ *	associated with this wiphy must be down and will follow.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -310,6 +333,14 @@ enum nl80211_commands {
 	NL80211_CMD_JOIN_IBSS,
 	NL80211_CMD_LEAVE_IBSS,
 
+	NL80211_CMD_TESTMODE,
+
+	NL80211_CMD_CONNECT,
+	NL80211_CMD_ROAM,
+	NL80211_CMD_DISCONNECT,
+
+	NL80211_CMD_SET_WIPHY_NETNS,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -449,10 +480,6 @@ enum nl80211_commands {
  * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
  * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
  *	scanning and include a zero-length SSID (wildcard) for wildcard scan
- * @NL80211_ATTR_SCAN_GENERATION: the scan generation increases whenever the
- *	scan result list changes (BSS expired or added) so that applications
- *	can verify that they got a single, consistent snapshot (when all dump
- *	messages carried the same generation number)
  * @NL80211_ATTR_BSS: scan result BSS
  *
  * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
@@ -511,6 +538,52 @@ enum nl80211_commands {
  *	authorized by user space. Otherwise, port is marked authorized by
  *	default in station mode.
  *
+ * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver.
+ *	We recommend using nested, driver-specific attributes within this.
+ *
+ * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT
+ *	event was due to the AP disconnecting the station, and not due to
+ *	a local disconnect request.
+ * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT
+ *	event (u16)
+ * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating
+ *	that protected APs should be used.
+ *
+ * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to
+ *	indicate which unicast key ciphers will be used with the connection
+ *	(an array of u32).
+ * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate
+ *	which group key cipher will be used with the connection (a u32).
+ * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE to indicate
+ *	which WPA version(s) the AP we want to associate with is using
+ *	(a u32 with flags from &enum nl80211_wpa_versions).
+ * @NL80211_ATTR_AKM_SUITES: Used with CONNECT and ASSOCIATE to indicate
+ *	which key management algorithm(s) to use (an array of u32).
+ *
+ * @NL80211_ATTR_REQ_IE: (Re)association request information elements as
+ *	sent out by the card, for ROAM and successful CONNECT events.
+ * @NL80211_ATTR_RESP_IE: (Re)association response information elements as
+ *	sent by peer, for ROAM and successful CONNECT events.
+ *
+ * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE
+ *	commands to specify using a reassociate frame
+ *
+ * @NL80211_ATTR_KEY: key information in a nested attribute with
+ *	%NL80211_KEY_* sub-attributes
+ * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect()
+ *	and join_ibss(), key information is in a nested attribute each
+ *	with %NL80211_KEY_* sub-attributes
+ *
+ * @NL80211_ATTR_PID: Process ID of a network namespace.
+ *
+ * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
+ *	dumps. This number increases whenever the object list being
+ *	dumped changes, and as such userspace can verify that it has
+ *	obtained a complete and consistent snapshot by verifying that
+ *	all dump messages contain the same generation number. If it
+ *	changed then the list changed and the dump should be repeated
+ *	completely from scratch.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -582,7 +655,7 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_SCAN_FREQUENCIES,
 	NL80211_ATTR_SCAN_SSIDS,
-	NL80211_ATTR_SCAN_GENERATION,
+	NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */
 	NL80211_ATTR_BSS,
 
 	NL80211_ATTR_REG_INITIATOR,
@@ -619,16 +692,42 @@ enum nl80211_attrs {
 
 	NL80211_ATTR_CONTROL_PORT,
 
+	NL80211_ATTR_TESTDATA,
+
+	NL80211_ATTR_PRIVACY,
+
+	NL80211_ATTR_DISCONNECTED_BY_AP,
+	NL80211_ATTR_STATUS_CODE,
+
+	NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
+	NL80211_ATTR_CIPHER_SUITE_GROUP,
+	NL80211_ATTR_WPA_VERSIONS,
+	NL80211_ATTR_AKM_SUITES,
+
+	NL80211_ATTR_REQ_IE,
+	NL80211_ATTR_RESP_IE,
+
+	NL80211_ATTR_PREV_BSSID,
+
+	NL80211_ATTR_KEY,
+	NL80211_ATTR_KEYS,
+
+	NL80211_ATTR_PID,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
 	NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
 };
 
+/* source-level API compatibility */
+#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
+
 /*
  * Allow user space programs to use #ifdef on new attributes by defining them
  * here
  */
+#define NL80211_CMD_CONNECT NL80211_CMD_CONNECT
 #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY
 #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES
 #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS
@@ -642,6 +741,12 @@ enum nl80211_attrs {
 #define NL80211_ATTR_SSID NL80211_ATTR_SSID
 #define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE
 #define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE
+#define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE
+#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP
+#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS
+#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES
+#define NL80211_ATTR_KEY NL80211_ATTR_KEY
+#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
 
 #define NL80211_MAX_SUPP_RATES			32
 #define NL80211_MAX_SUPP_REG_RULES		32
@@ -650,6 +755,9 @@ enum nl80211_attrs {
 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY	24
 #define NL80211_HT_CAPABILITY_LEN		26
 
+#define NL80211_MAX_NR_CIPHER_SUITES		5
+#define NL80211_MAX_NR_AKM_SUITES		2
+
 /**
  * enum nl80211_iftype - (virtual) interface types
  *
@@ -1168,6 +1276,7 @@ enum nl80211_channel_type {
  *	in mBm (100 * dBm) (s32)
  * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
  *	in unspecified units, scaled to 0..100 (u8)
+ * @NL80211_BSS_STATUS: status, if this BSS is "used"
  * @__NL80211_BSS_AFTER_LAST: internal
  * @NL80211_BSS_MAX: highest BSS attribute
  */
@@ -1181,6 +1290,7 @@ enum nl80211_bss {
 	NL80211_BSS_INFORMATION_ELEMENTS,
 	NL80211_BSS_SIGNAL_MBM,
 	NL80211_BSS_SIGNAL_UNSPEC,
+	NL80211_BSS_STATUS,
 
 	/* keep last */
 	__NL80211_BSS_AFTER_LAST,
@@ -1188,18 +1298,37 @@ enum nl80211_bss {
 };
 
 /**
+ * enum nl80211_bss_status - BSS "status"
+ */
+enum nl80211_bss_status {
+	NL80211_BSS_STATUS_AUTHENTICATED,
+	NL80211_BSS_STATUS_ASSOCIATED,
+	NL80211_BSS_STATUS_IBSS_JOINED,
+};
+
+/**
  * enum nl80211_auth_type - AuthenticationType
  *
  * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication
  * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only)
  * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r)
  * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP)
+ * @__NL80211_AUTHTYPE_NUM: internal
+ * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm
+ * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by
+ *	trying multiple times); this is invalid in netlink -- leave out
+ *	the attribute for this on CONNECT commands.
  */
 enum nl80211_auth_type {
 	NL80211_AUTHTYPE_OPEN_SYSTEM,
 	NL80211_AUTHTYPE_SHARED_KEY,
 	NL80211_AUTHTYPE_FT,
 	NL80211_AUTHTYPE_NETWORK_EAP,
+
+	/* keep last */
+	__NL80211_AUTHTYPE_NUM,
+	NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1,
+	NL80211_AUTHTYPE_AUTOMATIC
 };
 
 /**
@@ -1224,4 +1353,39 @@ enum nl80211_mfp {
 	NL80211_MFP_REQUIRED,
 };
 
+enum nl80211_wpa_versions {
+	NL80211_WPA_VERSION_1 = 1 << 0,
+	NL80211_WPA_VERSION_2 = 1 << 1,
+};
+
+/**
+ * enum nl80211_key_attributes - key attributes
+ * @__NL80211_KEY_INVALID: invalid
+ * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *	16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *	keys
+ * @NL80211_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *	section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *	CCMP keys, each six bytes in little endian
+ * @NL80211_KEY_DEFAULT: flag indicating default key
+ * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
+ * @__NL80211_KEY_AFTER_LAST: internal
+ * @NL80211_KEY_MAX: highest key attribute
+ */
+enum nl80211_key_attributes {
+	__NL80211_KEY_INVALID,
+	NL80211_KEY_DATA,
+	NL80211_KEY_IDX,
+	NL80211_KEY_CIPHER,
+	NL80211_KEY_SEQ,
+	NL80211_KEY_DEFAULT,
+	NL80211_KEY_DEFAULT_MGMT,
+
+	/* keep last */
+	__NL80211_KEY_AFTER_LAST,
+	NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
index 2cda00c..b7d9435 100644
--- a/include/linux/nl802154.h
+++ b/include/linux/nl802154.h
@@ -64,12 +64,14 @@ enum {
 	IEEE802154_ATTR_COORD_REALIGN,
 	IEEE802154_ATTR_SEC,
 
+	IEEE802154_ATTR_PAGE,
+
 	__IEEE802154_ATTR_MAX,
 };
 
 #define IEEE802154_ATTR_MAX (__IEEE802154_ATTR_MAX - 1)
 
-extern struct nla_policy ieee802154_policy[];
+extern const struct nla_policy ieee802154_policy[];
 
 /* commands */
 /* REQ should be responded with CONF
@@ -111,6 +113,8 @@ enum {
 	IEEE802154_RX_ENABLE_REQ, /* Not supported yet */
 	IEEE802154_RX_ENABLE_CONF, /* Not supported yet */
 
+	IEEE802154_LIST_IFACE,
+
 	__IEEE802154_CMD_MAX,
 };
 
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 81bc252..44428d2 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -199,6 +199,8 @@ static inline int notifier_to_errno(int ret)
 #define NETDEV_FEAT_CHANGE	0x000B
 #define NETDEV_BONDING_FAILOVER 0x000C
 #define NETDEV_PRE_UP		0x000D
+#define NETDEV_BONDING_OLDTYPE  0x000E
+#define NETDEV_BONDING_NEWTYPE  0x000F
 
 #define SYS_DOWN	0x0001	/* Notify of system down */
 #define SYS_RESTART	SYS_DOWN
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index e2e5ce5..2b87acf 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -99,7 +99,7 @@ enum pageflags {
 #ifdef CONFIG_HAVE_MLOCKED_PAGE_BIT
 	PG_mlocked,		/* Page is vma mlocked */
 #endif
-#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
+#ifdef CONFIG_ARCH_USES_PG_UNCACHED
 	PG_uncached,		/* Page has been mapped as uncached */
 #endif
 	__NR_PAGEFLAGS,
@@ -257,7 +257,7 @@ PAGEFLAG_FALSE(Mlocked)
 	SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked)
 #endif
 
-#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
+#ifdef CONFIG_ARCH_USES_PG_UNCACHED
 PAGEFLAG(Uncached, uncached)
 #else
 PAGEFLAG_FALSE(Uncached)
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h
index 13f126c..ada779f 100644
--- a/include/linux/page_cgroup.h
+++ b/include/linux/page_cgroup.h
@@ -105,14 +105,14 @@ static inline void __init page_cgroup_init_flatmem(void)
 
 #endif
 
-#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
 #include <linux/swap.h>
+
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
 extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id);
 extern unsigned short lookup_swap_cgroup(swp_entry_t ent);
 extern int swap_cgroup_swapon(int type, unsigned long max_pages);
 extern void swap_cgroup_swapoff(int type);
 #else
-#include <linux/swap.h>
 
 static inline
 unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 115fb7b..f5c7cd3 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -241,6 +241,7 @@ struct pci_dev {
 	unsigned int	d1_support:1;	/* Low power state D1 is supported */
 	unsigned int	d2_support:1;	/* Low power state D2 is supported */
 	unsigned int	no_d1d2:1;	/* Only allow D0 and D3 */
+	unsigned int	wakeup_prepared:1;
 
 #ifdef CONFIG_PCIEASPM
 	struct pcie_link_state	*link_state;	/* ASPM link state. */
@@ -273,9 +274,12 @@ struct pci_dev {
 	unsigned int	ari_enabled:1;	/* ARI forwarding */
 	unsigned int	is_managed:1;
 	unsigned int	is_pcie:1;
+	unsigned int    needs_freset:1; /* Dev requires fundamental reset */
 	unsigned int	state_saved:1;
 	unsigned int	is_physfn:1;
 	unsigned int	is_virtfn:1;
+	unsigned int	reset_fn:1;
+	unsigned int    is_hotplug_bridge:1;
 	pci_dev_flags_t dev_flags;
 	atomic_t	enable_cnt;	/* pci_enable_device has been called */
 
@@ -794,6 +798,11 @@ int __must_check __pci_register_driver(struct pci_driver *, struct module *,
 void pci_unregister_driver(struct pci_driver *dev);
 void pci_remove_behind_bridge(struct pci_dev *dev);
 struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
+int pci_add_dynid(struct pci_driver *drv,
+		  unsigned int vendor, unsigned int device,
+		  unsigned int subvendor, unsigned int subdevice,
+		  unsigned int class, unsigned int class_mask,
+		  unsigned long driver_data);
 const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
 					 struct pci_dev *dev);
 int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
@@ -805,6 +814,8 @@ int pci_cfg_space_size_ext(struct pci_dev *dev);
 int pci_cfg_space_size(struct pci_dev *dev);
 unsigned char pci_bus_max_busnr(struct pci_bus *bus);
 
+int pci_set_vga_state(struct pci_dev *pdev, bool decode,
+		      unsigned int command_bits, bool change_bridge);
 /* kmem_cache style wrapper around pci_alloc_consistent() */
 
 #include <linux/dmapool.h>
@@ -1236,6 +1247,9 @@ extern int pci_pci_problems;
 extern unsigned long pci_cardbus_io_size;
 extern unsigned long pci_cardbus_mem_size;
 
+extern unsigned long pci_hotplug_io_size;
+extern unsigned long pci_hotplug_mem_size;
+
 int pcibios_add_platform_entries(struct pci_dev *dev);
 void pcibios_disable_device(struct pci_dev *dev);
 int pcibios_set_pcie_reset_state(struct pci_dev *dev,
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index 4391741..652ba79 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -62,7 +62,8 @@ enum pcie_link_width {
 };
 
 enum pcie_link_speed {
-	PCIE_2PT5GB		= 0x14,
+	PCIE_2_5GB		= 0x14,
+	PCIE_5_0GB		= 0x15,
 	PCIE_LNK_SPEED_UNKNOWN	= 0xFF,
 };
 
@@ -226,11 +227,18 @@ struct hotplug_params {
 #ifdef CONFIG_ACPI
 #include <acpi/acpi.h>
 #include <acpi/acpi_bus.h>
-extern acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
-				struct hotplug_params *hpp);
+int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp);
 int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags);
 int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle);
-int acpi_pci_detect_ejectable(struct pci_bus *pbus);
+int acpi_pci_detect_ejectable(acpi_handle handle);
+#else
+static inline int pci_get_hp_params(struct pci_dev *dev,
+				    struct hotplug_params *hpp)
+{
+	return -ENODEV;
+}
 #endif
+
+void pci_configure_slot(struct pci_dev *dev);
 #endif
 
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index c8fdcad..3b6b788 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2,6 +2,9 @@
  *	PCI Class, Vendor and Device IDs
  *
  *	Please keep sorted.
+ *
+ *	Do not add new entries to this file unless the definitions
+ *	are shared between multiple drivers.
  */
 
 /* Device classes and subclasses */
@@ -881,6 +884,7 @@
 #define PCI_DEVICE_ID_APPLE_SH_SUNGEM   0x0051
 #define PCI_DEVICE_ID_APPLE_U3L_AGP	0x0058
 #define PCI_DEVICE_ID_APPLE_U3H_AGP	0x0059
+#define PCI_DEVICE_ID_APPLE_U4_PCIE	0x005b
 #define PCI_DEVICE_ID_APPLE_IPID2_AGP	0x0066
 #define PCI_DEVICE_ID_APPLE_IPID2_ATA	0x0069
 #define PCI_DEVICE_ID_APPLE_IPID2_FW	0x006a
@@ -1525,6 +1529,8 @@
 #define PCI_DEVICE_ID_ARTOP_ATP860R	0x0007
 #define PCI_DEVICE_ID_ARTOP_ATP865	0x0008
 #define PCI_DEVICE_ID_ARTOP_ATP865R	0x0009
+#define PCI_DEVICE_ID_ARTOP_ATP867A	0x000A
+#define PCI_DEVICE_ID_ARTOP_ATP867B	0x000B
 #define PCI_DEVICE_ID_ARTOP_AEC7610	0x8002
 #define PCI_DEVICE_ID_ARTOP_AEC7612UW	0x8010
 #define PCI_DEVICE_ID_ARTOP_AEC7612U	0x8020
@@ -1988,6 +1994,8 @@
 
 #define PCI_VENDOR_ID_SAMSUNG		0x144d
 
+#define PCI_VENDOR_ID_GIGABYTE		0x1458
+
 #define PCI_VENDOR_ID_AMBIT		0x1468
 
 #define PCI_VENDOR_ID_MYRICOM		0x14c1
@@ -2066,7 +2074,6 @@
 #define PCI_DEVICE_ID_TIGON3_5787M	0x1693
 #define PCI_DEVICE_ID_TIGON3_5782	0x1696
 #define PCI_DEVICE_ID_TIGON3_5784	0x1698
-#define PCI_DEVICE_ID_TIGON3_5785	0x1699
 #define PCI_DEVICE_ID_TIGON3_5786	0x169a
 #define PCI_DEVICE_ID_TIGON3_5787	0x169b
 #define PCI_DEVICE_ID_TIGON3_5788	0x169c
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index fcaee42..dd0bed4 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -42,6 +42,7 @@
 #define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
 
 #define PCI_STATUS		0x06	/* 16 bits */
+#define  PCI_STATUS_INTERRUPT	0x08	/* Interrupt status */
 #define  PCI_STATUS_CAP_LIST	0x10	/* Support Capability List */
 #define  PCI_STATUS_66MHZ	0x20	/* Support 66 Mhz PCI 2.1 bus */
 #define  PCI_STATUS_UDF		0x40	/* Support User Definable Features [obsolete] */
diff --git a/include/linux/percpu-defs.h b/include/linux/percpu-defs.h
index 68438e1..9bd0319 100644
--- a/include/linux/percpu-defs.h
+++ b/include/linux/percpu-defs.h
@@ -10,22 +10,70 @@
 /*
  * Base implementations of per-CPU variable declarations and definitions, where
  * the section in which the variable is to be placed is provided by the
- * 'section' argument.  This may be used to affect the parameters governing the
+ * 'sec' argument.  This may be used to affect the parameters governing the
  * variable's storage.
  *
  * NOTE!  The sections for the DECLARE and for the DEFINE must match, lest
  * linkage errors occur due the compiler generating the wrong code to access
  * that section.
  */
-#define DECLARE_PER_CPU_SECTION(type, name, section)			\
-	extern								\
-	__attribute__((__section__(PER_CPU_BASE_SECTION section)))	\
-	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
-
-#define DEFINE_PER_CPU_SECTION(type, name, section)			\
-	__attribute__((__section__(PER_CPU_BASE_SECTION section)))	\
-	PER_CPU_ATTRIBUTES PER_CPU_DEF_ATTRIBUTES			\
+#define __PCPU_ATTRS(sec)						\
+	__attribute__((section(PER_CPU_BASE_SECTION sec)))		\
+	PER_CPU_ATTRIBUTES
+
+#define __PCPU_DUMMY_ATTRS						\
+	__attribute__((section(".discard"), unused))
+
+/*
+ * s390 and alpha modules require percpu variables to be defined as
+ * weak to force the compiler to generate GOT based external
+ * references for them.  This is necessary because percpu sections
+ * will be located outside of the usually addressable area.
+ *
+ * This definition puts the following two extra restrictions when
+ * defining percpu variables.
+ *
+ * 1. The symbol must be globally unique, even the static ones.
+ * 2. Static percpu variables cannot be defined inside a function.
+ *
+ * Archs which need weak percpu definitions should define
+ * ARCH_NEEDS_WEAK_PER_CPU in asm/percpu.h when necessary.
+ *
+ * To ensure that the generic code observes the above two
+ * restrictions, if CONFIG_DEBUG_FORCE_WEAK_PER_CPU is set weak
+ * definition is used for all cases.
+ */
+#if defined(ARCH_NEEDS_WEAK_PER_CPU) || defined(CONFIG_DEBUG_FORCE_WEAK_PER_CPU)
+/*
+ * __pcpu_scope_* dummy variable is used to enforce scope.  It
+ * receives the static modifier when it's used in front of
+ * DEFINE_PER_CPU() and will trigger build failure if
+ * DECLARE_PER_CPU() is used for the same variable.
+ *
+ * __pcpu_unique_* dummy variable is used to enforce symbol uniqueness
+ * such that hidden weak symbol collision, which will cause unrelated
+ * variables to share the same address, can be detected during build.
+ */
+#define DECLARE_PER_CPU_SECTION(type, name, sec)			\
+	extern __PCPU_DUMMY_ATTRS char __pcpu_scope_##name;		\
+	extern __PCPU_ATTRS(sec) __typeof__(type) per_cpu__##name
+
+#define DEFINE_PER_CPU_SECTION(type, name, sec)				\
+	__PCPU_DUMMY_ATTRS char __pcpu_scope_##name;			\
+	__PCPU_DUMMY_ATTRS char __pcpu_unique_##name;			\
+	__PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES __weak			\
 	__typeof__(type) per_cpu__##name
+#else
+/*
+ * Normal declaration and definition macros.
+ */
+#define DECLARE_PER_CPU_SECTION(type, name, sec)			\
+	extern __PCPU_ATTRS(sec) __typeof__(type) per_cpu__##name
+
+#define DEFINE_PER_CPU_SECTION(type, name, sec)				\
+	__PCPU_ATTRS(sec) PER_CPU_DEF_ATTRIBUTES			\
+	__typeof__(type) per_cpu__##name
+#endif
 
 /*
  * Variant on the per-CPU variable declaration/definition theme used for
@@ -66,14 +114,24 @@
 	DEFINE_PER_CPU_SECTION(type, name, PER_CPU_SHARED_ALIGNED_SECTION) \
 	____cacheline_aligned_in_smp
 
+#define DECLARE_PER_CPU_ALIGNED(type, name)				\
+	DECLARE_PER_CPU_SECTION(type, name, PER_CPU_ALIGNED_SECTION)	\
+	____cacheline_aligned
+
+#define DEFINE_PER_CPU_ALIGNED(type, name)				\
+	DEFINE_PER_CPU_SECTION(type, name, PER_CPU_ALIGNED_SECTION)	\
+	____cacheline_aligned
+
 /*
  * Declaration/definition used for per-CPU variables that must be page aligned.
  */
-#define DECLARE_PER_CPU_PAGE_ALIGNED(type, name)				\
-	DECLARE_PER_CPU_SECTION(type, name, ".page_aligned")
+#define DECLARE_PER_CPU_PAGE_ALIGNED(type, name)			\
+	DECLARE_PER_CPU_SECTION(type, name, ".page_aligned")		\
+	__aligned(PAGE_SIZE)
 
 #define DEFINE_PER_CPU_PAGE_ALIGNED(type, name)				\
-	DEFINE_PER_CPU_SECTION(type, name, ".page_aligned")
+	DEFINE_PER_CPU_SECTION(type, name, ".page_aligned")		\
+	__aligned(PAGE_SIZE)
 
 /*
  * Intermodule exports for per-CPU variables.
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 26fd9d1..878836c 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -34,7 +34,7 @@
 
 #ifdef CONFIG_SMP
 
-#ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA
+#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA
 
 /* minimum unit size, also is the maximum supported allocation size */
 #define PCPU_MIN_UNIT_SIZE		PFN_ALIGN(64 << 10)
@@ -57,19 +57,70 @@
 #endif
 
 extern void *pcpu_base_addr;
+extern const unsigned long *pcpu_unit_offsets;
 
-typedef struct page * (*pcpu_get_page_fn_t)(unsigned int cpu, int pageno);
-typedef void (*pcpu_populate_pte_fn_t)(unsigned long addr);
+struct pcpu_group_info {
+	int			nr_units;	/* aligned # of units */
+	unsigned long		base_offset;	/* base address offset */
+	unsigned int		*cpu_map;	/* unit->cpu map, empty
+						 * entries contain NR_CPUS */
+};
+
+struct pcpu_alloc_info {
+	size_t			static_size;
+	size_t			reserved_size;
+	size_t			dyn_size;
+	size_t			unit_size;
+	size_t			atom_size;
+	size_t			alloc_size;
+	size_t			__ai_size;	/* internal, don't use */
+	int			nr_groups;	/* 0 if grouping unnecessary */
+	struct pcpu_group_info	groups[];
+};
 
-extern size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
-				size_t static_size, size_t reserved_size,
-				ssize_t dyn_size, ssize_t unit_size,
-				void *base_addr,
-				pcpu_populate_pte_fn_t populate_pte_fn);
+enum pcpu_fc {
+	PCPU_FC_AUTO,
+	PCPU_FC_EMBED,
+	PCPU_FC_PAGE,
 
-extern ssize_t __init pcpu_embed_first_chunk(
-				size_t static_size, size_t reserved_size,
-				ssize_t dyn_size, ssize_t unit_size);
+	PCPU_FC_NR,
+};
+extern const char *pcpu_fc_names[PCPU_FC_NR];
+
+extern enum pcpu_fc pcpu_chosen_fc;
+
+typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size,
+				     size_t align);
+typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size);
+typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr);
+typedef int (pcpu_fc_cpu_distance_fn_t)(unsigned int from, unsigned int to);
+
+extern struct pcpu_alloc_info * __init pcpu_alloc_alloc_info(int nr_groups,
+							     int nr_units);
+extern void __init pcpu_free_alloc_info(struct pcpu_alloc_info *ai);
+
+extern struct pcpu_alloc_info * __init pcpu_build_alloc_info(
+				size_t reserved_size, ssize_t dyn_size,
+				size_t atom_size,
+				pcpu_fc_cpu_distance_fn_t cpu_distance_fn);
+
+extern int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
+					 void *base_addr);
+
+#ifdef CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK
+extern int __init pcpu_embed_first_chunk(size_t reserved_size, ssize_t dyn_size,
+				size_t atom_size,
+				pcpu_fc_cpu_distance_fn_t cpu_distance_fn,
+				pcpu_fc_alloc_fn_t alloc_fn,
+				pcpu_fc_free_fn_t free_fn);
+#endif
+
+#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
+extern int __init pcpu_page_first_chunk(size_t reserved_size,
+				pcpu_fc_alloc_fn_t alloc_fn,
+				pcpu_fc_free_fn_t free_fn,
+				pcpu_fc_populate_pte_fn_t populate_pte_fn);
+#endif
 
 /*
  * Use this to get to a cpu's version of the per-cpu object
@@ -80,7 +131,7 @@ extern ssize_t __init pcpu_embed_first_chunk(
 
 extern void *__alloc_reserved_percpu(size_t size, size_t align);
 
-#else /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */
+#else /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */
 
 struct percpu_data {
 	void *ptrs[1];
@@ -99,11 +150,15 @@ struct percpu_data {
         (__typeof__(ptr))__p->ptrs[(cpu)];				\
 })
 
-#endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */
+#endif /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */
 
 extern void *__alloc_percpu(size_t size, size_t align);
 extern void free_percpu(void *__pdata);
 
+#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
+extern void __init setup_per_cpu_areas(void);
+#endif
+
 #else /* CONFIG_SMP */
 
 #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
@@ -124,6 +179,13 @@ static inline void free_percpu(void *p)
 	kfree(p);
 }
 
+static inline void __init setup_per_cpu_areas(void) { }
+
+static inline void *pcpu_lpage_remapped(void *kaddr)
+{
+	return NULL;
+}
+
 #endif /* CONFIG_SMP */
 
 #define alloc_percpu(type)	(type *)__alloc_percpu(sizeof(type), \
diff --git a/include/linux/perf_counter.h b/include/linux/perf_counter.h
index 972f90d..368bd70 100644
--- a/include/linux/perf_counter.h
+++ b/include/linux/perf_counter.h
@@ -1,5 +1,9 @@
 /*
- *  Performance counters:
+ *  NOTE: this file will be removed in a future kernel release, it is
+ *  provided as a courtesy copy of user-space code that relies on the
+ *  old (pre-rename) symbols and constants.
+ *
+ *  Performance events:
  *
  *    Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de>
  *    Copyright (C) 2008-2009, Red Hat, Inc., Ingo Molnar
@@ -131,19 +135,19 @@ enum perf_counter_sample_format {
  * as specified by attr.read_format:
  *
  * struct read_format {
- * 	{ u64		value;
- * 	  { u64		time_enabled; } && PERF_FORMAT_ENABLED
- * 	  { u64		time_running; } && PERF_FORMAT_RUNNING
- * 	  { u64		id;           } && PERF_FORMAT_ID
- * 	} && !PERF_FORMAT_GROUP
+ *	{ u64		value;
+ *	  { u64		time_enabled; } && PERF_FORMAT_ENABLED
+ *	  { u64		time_running; } && PERF_FORMAT_RUNNING
+ *	  { u64		id;           } && PERF_FORMAT_ID
+ *	} && !PERF_FORMAT_GROUP
  *
- * 	{ u64		nr;
- * 	  { u64		time_enabled; } && PERF_FORMAT_ENABLED
- * 	  { u64		time_running; } && PERF_FORMAT_RUNNING
- * 	  { u64		value;
- * 	    { u64	id;           } && PERF_FORMAT_ID
- * 	  }		cntr[nr];
- * 	} && PERF_FORMAT_GROUP
+ *	{ u64		nr;
+ *	  { u64		time_enabled; } && PERF_FORMAT_ENABLED
+ *	  { u64		time_running; } && PERF_FORMAT_RUNNING
+ *	  { u64		value;
+ *	    { u64	id;           } && PERF_FORMAT_ID
+ *	  }		cntr[nr];
+ *	} && PERF_FORMAT_GROUP
  * };
  */
 enum perf_counter_read_format {
@@ -199,10 +203,14 @@ struct perf_counter_attr {
 				inherit_stat   :  1, /* per task counts       */
 				enable_on_exec :  1, /* next exec enables     */
 				task           :  1, /* trace fork/exit       */
+				watermark      :  1, /* wakeup_watermark      */
 
-				__reserved_1   : 50;
+				__reserved_1   : 49;
 
-	__u32			wakeup_events;	/* wakeup every n events */
+	union {
+		__u32		wakeup_events;	  /* wakeup every n events */
+		__u32		wakeup_watermark; /* bytes before wakeup   */
+	};
 	__u32			__reserved_2;
 
 	__u64			__reserved_3;
@@ -310,9 +318,9 @@ enum perf_event_type {
 
 	/*
 	 * struct {
-	 * 	struct perf_event_header	header;
-	 * 	u64				id;
-	 * 	u64				lost;
+	 *	struct perf_event_header	header;
+	 *	u64				id;
+	 *	u64				lost;
 	 * };
 	 */
 	PERF_EVENT_LOST			= 2,
@@ -332,6 +340,7 @@ enum perf_event_type {
 	 *	struct perf_event_header	header;
 	 *	u32				pid, ppid;
 	 *	u32				tid, ptid;
+	 *	u64				time;
 	 * };
 	 */
 	PERF_EVENT_EXIT			= 4,
@@ -352,16 +361,17 @@ enum perf_event_type {
 	 *	struct perf_event_header	header;
 	 *	u32				pid, ppid;
 	 *	u32				tid, ptid;
+	 *	{ u64				time;     } && PERF_SAMPLE_TIME
 	 * };
 	 */
 	PERF_EVENT_FORK			= 7,
 
 	/*
 	 * struct {
-	 * 	struct perf_event_header	header;
-	 * 	u32				pid, tid;
+	 *	struct perf_event_header	header;
+	 *	u32				pid, tid;
 	 *
-	 * 	struct read_format		values;
+	 *	struct read_format		values;
 	 * };
 	 */
 	PERF_EVENT_READ			= 8,
@@ -377,23 +387,23 @@ enum perf_event_type {
 	 *	{ u64			id;	  } && PERF_SAMPLE_ID
 	 *	{ u64			stream_id;} && PERF_SAMPLE_STREAM_ID
 	 *	{ u32			cpu, res; } && PERF_SAMPLE_CPU
-	 * 	{ u64			period;   } && PERF_SAMPLE_PERIOD
+	 *	{ u64			period;   } && PERF_SAMPLE_PERIOD
 	 *
 	 *	{ struct read_format	values;	  } && PERF_SAMPLE_READ
 	 *
 	 *	{ u64			nr,
 	 *	  u64			ips[nr];  } && PERF_SAMPLE_CALLCHAIN
 	 *
-	 * 	#
-	 * 	# The RAW record below is opaque data wrt the ABI
-	 * 	#
-	 * 	# That is, the ABI doesn't make any promises wrt to
-	 * 	# the stability of its content, it may vary depending
-	 * 	# on event, hardware, kernel version and phase of
-	 * 	# the moon.
-	 * 	#
-	 * 	# In other words, PERF_SAMPLE_RAW contents are not an ABI.
-	 * 	#
+	 *	#
+	 *	# The RAW record below is opaque data wrt the ABI
+	 *	#
+	 *	# That is, the ABI doesn't make any promises wrt to
+	 *	# the stability of its content, it may vary depending
+	 *	# on event, hardware, kernel version and phase of
+	 *	# the moon.
+	 *	#
+	 *	# In other words, PERF_SAMPLE_RAW contents are not an ABI.
+	 *	#
 	 *
 	 *	{ u32			size;
 	 *	  char                  data[size];}&& PERF_SAMPLE_RAW
@@ -416,392 +426,16 @@ enum perf_callchain_context {
 	PERF_CONTEXT_MAX		= (__u64)-4095,
 };
 
-#define PERF_FLAG_FD_NO_GROUP	(1U << 0)
-#define PERF_FLAG_FD_OUTPUT	(1U << 1)
+#define PERF_FLAG_FD_NO_GROUP		(1U << 0)
+#define PERF_FLAG_FD_OUTPUT		(1U << 1)
 
-#ifdef __KERNEL__
 /*
- * Kernel-internal data types and definitions:
- */
-
-#ifdef CONFIG_PERF_COUNTERS
-# include <asm/perf_counter.h>
-#endif
-
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/rculist.h>
-#include <linux/rcupdate.h>
-#include <linux/spinlock.h>
-#include <linux/hrtimer.h>
-#include <linux/fs.h>
-#include <linux/pid_namespace.h>
-#include <asm/atomic.h>
-
-#define PERF_MAX_STACK_DEPTH		255
-
-struct perf_callchain_entry {
-	__u64				nr;
-	__u64				ip[PERF_MAX_STACK_DEPTH];
-};
-
-struct perf_raw_record {
-	u32				size;
-	void				*data;
-};
-
-struct task_struct;
-
-/**
- * struct hw_perf_counter - performance counter hardware details:
- */
-struct hw_perf_counter {
-#ifdef CONFIG_PERF_COUNTERS
-	union {
-		struct { /* hardware */
-			u64		config;
-			unsigned long	config_base;
-			unsigned long	counter_base;
-			int		idx;
-		};
-		union { /* software */
-			atomic64_t	count;
-			struct hrtimer	hrtimer;
-		};
-	};
-	atomic64_t			prev_count;
-	u64				sample_period;
-	u64				last_period;
-	atomic64_t			period_left;
-	u64				interrupts;
-
-	u64				freq_count;
-	u64				freq_interrupts;
-	u64				freq_stamp;
-#endif
-};
-
-struct perf_counter;
-
-/**
- * struct pmu - generic performance monitoring unit
- */
-struct pmu {
-	int (*enable)			(struct perf_counter *counter);
-	void (*disable)			(struct perf_counter *counter);
-	void (*read)			(struct perf_counter *counter);
-	void (*unthrottle)		(struct perf_counter *counter);
-};
-
-/**
- * enum perf_counter_active_state - the states of a counter
- */
-enum perf_counter_active_state {
-	PERF_COUNTER_STATE_ERROR	= -2,
-	PERF_COUNTER_STATE_OFF		= -1,
-	PERF_COUNTER_STATE_INACTIVE	=  0,
-	PERF_COUNTER_STATE_ACTIVE	=  1,
-};
-
-struct file;
-
-struct perf_mmap_data {
-	struct rcu_head			rcu_head;
-	int				nr_pages;	/* nr of data pages  */
-	int				writable;	/* are we writable   */
-	int				nr_locked;	/* nr pages mlocked  */
-
-	atomic_t			poll;		/* POLL_ for wakeups */
-	atomic_t			events;		/* event limit       */
-
-	atomic_long_t			head;		/* write position    */
-	atomic_long_t			done_head;	/* completed head    */
-
-	atomic_t			lock;		/* concurrent writes */
-	atomic_t			wakeup;		/* needs a wakeup    */
-	atomic_t			lost;		/* nr records lost   */
-
-	struct perf_counter_mmap_page   *user_page;
-	void				*data_pages[0];
-};
-
-struct perf_pending_entry {
-	struct perf_pending_entry *next;
-	void (*func)(struct perf_pending_entry *);
-};
-
-/**
- * struct perf_counter - performance counter kernel representation:
- */
-struct perf_counter {
-#ifdef CONFIG_PERF_COUNTERS
-	struct list_head		list_entry;
-	struct list_head		event_entry;
-	struct list_head		sibling_list;
-	int				nr_siblings;
-	struct perf_counter		*group_leader;
-	struct perf_counter		*output;
-	const struct pmu		*pmu;
-
-	enum perf_counter_active_state	state;
-	atomic64_t			count;
-
-	/*
-	 * These are the total time in nanoseconds that the counter
-	 * has been enabled (i.e. eligible to run, and the task has
-	 * been scheduled in, if this is a per-task counter)
-	 * and running (scheduled onto the CPU), respectively.
-	 *
-	 * They are computed from tstamp_enabled, tstamp_running and
-	 * tstamp_stopped when the counter is in INACTIVE or ACTIVE state.
-	 */
-	u64				total_time_enabled;
-	u64				total_time_running;
-
-	/*
-	 * These are timestamps used for computing total_time_enabled
-	 * and total_time_running when the counter is in INACTIVE or
-	 * ACTIVE state, measured in nanoseconds from an arbitrary point
-	 * in time.
-	 * tstamp_enabled: the notional time when the counter was enabled
-	 * tstamp_running: the notional time when the counter was scheduled on
-	 * tstamp_stopped: in INACTIVE state, the notional time when the
-	 *	counter was scheduled off.
-	 */
-	u64				tstamp_enabled;
-	u64				tstamp_running;
-	u64				tstamp_stopped;
-
-	struct perf_counter_attr	attr;
-	struct hw_perf_counter		hw;
-
-	struct perf_counter_context	*ctx;
-	struct file			*filp;
-
-	/*
-	 * These accumulate total time (in nanoseconds) that children
-	 * counters have been enabled and running, respectively.
-	 */
-	atomic64_t			child_total_time_enabled;
-	atomic64_t			child_total_time_running;
-
-	/*
-	 * Protect attach/detach and child_list:
-	 */
-	struct mutex			child_mutex;
-	struct list_head		child_list;
-	struct perf_counter		*parent;
-
-	int				oncpu;
-	int				cpu;
-
-	struct list_head		owner_entry;
-	struct task_struct		*owner;
-
-	/* mmap bits */
-	struct mutex			mmap_mutex;
-	atomic_t			mmap_count;
-	struct perf_mmap_data		*data;
-
-	/* poll related */
-	wait_queue_head_t		waitq;
-	struct fasync_struct		*fasync;
-
-	/* delayed work for NMIs and such */
-	int				pending_wakeup;
-	int				pending_kill;
-	int				pending_disable;
-	struct perf_pending_entry	pending;
-
-	atomic_t			event_limit;
-
-	void (*destroy)(struct perf_counter *);
-	struct rcu_head			rcu_head;
-
-	struct pid_namespace		*ns;
-	u64				id;
-#endif
-};
-
-/**
- * struct perf_counter_context - counter context structure
- *
- * Used as a container for task counters and CPU counters as well:
- */
-struct perf_counter_context {
-	/*
-	 * Protect the states of the counters in the list,
-	 * nr_active, and the list:
-	 */
-	spinlock_t			lock;
-	/*
-	 * Protect the list of counters.  Locking either mutex or lock
-	 * is sufficient to ensure the list doesn't change; to change
-	 * the list you need to lock both the mutex and the spinlock.
-	 */
-	struct mutex			mutex;
-
-	struct list_head		counter_list;
-	struct list_head		event_list;
-	int				nr_counters;
-	int				nr_active;
-	int				is_active;
-	int				nr_stat;
-	atomic_t			refcount;
-	struct task_struct		*task;
-
-	/*
-	 * Context clock, runs when context enabled.
-	 */
-	u64				time;
-	u64				timestamp;
-
-	/*
-	 * These fields let us detect when two contexts have both
-	 * been cloned (inherited) from a common ancestor.
-	 */
-	struct perf_counter_context	*parent_ctx;
-	u64				parent_gen;
-	u64				generation;
-	int				pin_count;
-	struct rcu_head			rcu_head;
-};
-
-/**
- * struct perf_counter_cpu_context - per cpu counter context structure
+ * In case some app still references the old symbols:
  */
-struct perf_cpu_context {
-	struct perf_counter_context	ctx;
-	struct perf_counter_context	*task_ctx;
-	int				active_oncpu;
-	int				max_pertask;
-	int				exclusive;
 
-	/*
-	 * Recursion avoidance:
-	 *
-	 * task, softirq, irq, nmi context
-	 */
-	int				recursion[4];
-};
+#define __NR_perf_counter_open		__NR_perf_event_open
 
-#ifdef CONFIG_PERF_COUNTERS
+#define PR_TASK_PERF_COUNTERS_DISABLE	PR_TASK_PERF_EVENTS_DISABLE
+#define PR_TASK_PERF_COUNTERS_ENABLE	PR_TASK_PERF_EVENTS_ENABLE
 
-/*
- * Set by architecture code:
- */
-extern int perf_max_counters;
-
-extern const struct pmu *hw_perf_counter_init(struct perf_counter *counter);
-
-extern void perf_counter_task_sched_in(struct task_struct *task, int cpu);
-extern void perf_counter_task_sched_out(struct task_struct *task,
-					struct task_struct *next, int cpu);
-extern void perf_counter_task_tick(struct task_struct *task, int cpu);
-extern int perf_counter_init_task(struct task_struct *child);
-extern void perf_counter_exit_task(struct task_struct *child);
-extern void perf_counter_free_task(struct task_struct *task);
-extern void set_perf_counter_pending(void);
-extern void perf_counter_do_pending(void);
-extern void perf_counter_print_debug(void);
-extern void __perf_disable(void);
-extern bool __perf_enable(void);
-extern void perf_disable(void);
-extern void perf_enable(void);
-extern int perf_counter_task_disable(void);
-extern int perf_counter_task_enable(void);
-extern int hw_perf_group_sched_in(struct perf_counter *group_leader,
-	       struct perf_cpu_context *cpuctx,
-	       struct perf_counter_context *ctx, int cpu);
-extern void perf_counter_update_userpage(struct perf_counter *counter);
-
-struct perf_sample_data {
-	struct pt_regs			*regs;
-	u64				addr;
-	u64				period;
-	struct perf_raw_record		*raw;
-};
-
-extern int perf_counter_overflow(struct perf_counter *counter, int nmi,
-				 struct perf_sample_data *data);
-extern void perf_counter_output(struct perf_counter *counter, int nmi,
-				struct perf_sample_data *data);
-
-/*
- * Return 1 for a software counter, 0 for a hardware counter
- */
-static inline int is_software_counter(struct perf_counter *counter)
-{
-	return (counter->attr.type != PERF_TYPE_RAW) &&
-		(counter->attr.type != PERF_TYPE_HARDWARE) &&
-		(counter->attr.type != PERF_TYPE_HW_CACHE);
-}
-
-extern atomic_t perf_swcounter_enabled[PERF_COUNT_SW_MAX];
-
-extern void __perf_swcounter_event(u32, u64, int, struct pt_regs *, u64);
-
-static inline void
-perf_swcounter_event(u32 event, u64 nr, int nmi, struct pt_regs *regs, u64 addr)
-{
-	if (atomic_read(&perf_swcounter_enabled[event]))
-		__perf_swcounter_event(event, nr, nmi, regs, addr);
-}
-
-extern void __perf_counter_mmap(struct vm_area_struct *vma);
-
-static inline void perf_counter_mmap(struct vm_area_struct *vma)
-{
-	if (vma->vm_flags & VM_EXEC)
-		__perf_counter_mmap(vma);
-}
-
-extern void perf_counter_comm(struct task_struct *tsk);
-extern void perf_counter_fork(struct task_struct *tsk);
-
-extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs);
-
-extern int sysctl_perf_counter_paranoid;
-extern int sysctl_perf_counter_mlock;
-extern int sysctl_perf_counter_sample_rate;
-
-extern void perf_counter_init(void);
-extern void perf_tpcounter_event(int event_id, u64 addr, u64 count,
-				 void *record, int entry_size);
-
-#ifndef perf_misc_flags
-#define perf_misc_flags(regs)	(user_mode(regs) ? PERF_EVENT_MISC_USER : \
-				 PERF_EVENT_MISC_KERNEL)
-#define perf_instruction_pointer(regs)	instruction_pointer(regs)
-#endif
-
-#else
-static inline void
-perf_counter_task_sched_in(struct task_struct *task, int cpu)		{ }
-static inline void
-perf_counter_task_sched_out(struct task_struct *task,
-			    struct task_struct *next, int cpu)		{ }
-static inline void
-perf_counter_task_tick(struct task_struct *task, int cpu)		{ }
-static inline int perf_counter_init_task(struct task_struct *child)	{ return 0; }
-static inline void perf_counter_exit_task(struct task_struct *child)	{ }
-static inline void perf_counter_free_task(struct task_struct *task)	{ }
-static inline void perf_counter_do_pending(void)			{ }
-static inline void perf_counter_print_debug(void)			{ }
-static inline void perf_disable(void)					{ }
-static inline void perf_enable(void)					{ }
-static inline int perf_counter_task_disable(void)	{ return -EINVAL; }
-static inline int perf_counter_task_enable(void)	{ return -EINVAL; }
-
-static inline void
-perf_swcounter_event(u32 event, u64 nr, int nmi,
-		     struct pt_regs *regs, u64 addr)			{ }
-
-static inline void perf_counter_mmap(struct vm_area_struct *vma)	{ }
-static inline void perf_counter_comm(struct task_struct *tsk)		{ }
-static inline void perf_counter_fork(struct task_struct *tsk)		{ }
-static inline void perf_counter_init(void)				{ }
-#endif
-
-#endif /* __KERNEL__ */
 #endif /* _LINUX_PERF_COUNTER_H */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
new file mode 100644
index 0000000..acefaf7
--- /dev/null
+++ b/include/linux/perf_event.h
@@ -0,0 +1,858 @@
+/*
+ * Performance events:
+ *
+ *    Copyright (C) 2008-2009, Thomas Gleixner <tglx@linutronix.de>
+ *    Copyright (C) 2008-2009, Red Hat, Inc., Ingo Molnar
+ *    Copyright (C) 2008-2009, Red Hat, Inc., Peter Zijlstra
+ *
+ * Data type definitions, declarations, prototypes.
+ *
+ *    Started by: Thomas Gleixner and Ingo Molnar
+ *
+ * For licencing details see kernel-base/COPYING
+ */
+#ifndef _LINUX_PERF_EVENT_H
+#define _LINUX_PERF_EVENT_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/byteorder.h>
+
+/*
+ * User-space ABI bits:
+ */
+
+/*
+ * attr.type
+ */
+enum perf_type_id {
+	PERF_TYPE_HARDWARE			= 0,
+	PERF_TYPE_SOFTWARE			= 1,
+	PERF_TYPE_TRACEPOINT			= 2,
+	PERF_TYPE_HW_CACHE			= 3,
+	PERF_TYPE_RAW				= 4,
+
+	PERF_TYPE_MAX,				/* non-ABI */
+};
+
+/*
+ * Generalized performance event event_id types, used by the
+ * attr.event_id parameter of the sys_perf_event_open()
+ * syscall:
+ */
+enum perf_hw_id {
+	/*
+	 * Common hardware events, generalized by the kernel:
+	 */
+	PERF_COUNT_HW_CPU_CYCLES		= 0,
+	PERF_COUNT_HW_INSTRUCTIONS		= 1,
+	PERF_COUNT_HW_CACHE_REFERENCES		= 2,
+	PERF_COUNT_HW_CACHE_MISSES		= 3,
+	PERF_COUNT_HW_BRANCH_INSTRUCTIONS	= 4,
+	PERF_COUNT_HW_BRANCH_MISSES		= 5,
+	PERF_COUNT_HW_BUS_CYCLES		= 6,
+
+	PERF_COUNT_HW_MAX,			/* non-ABI */
+};
+
+/*
+ * Generalized hardware cache events:
+ *
+ *       { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x
+ *       { read, write, prefetch } x
+ *       { accesses, misses }
+ */
+enum perf_hw_cache_id {
+	PERF_COUNT_HW_CACHE_L1D			= 0,
+	PERF_COUNT_HW_CACHE_L1I			= 1,
+	PERF_COUNT_HW_CACHE_LL			= 2,
+	PERF_COUNT_HW_CACHE_DTLB		= 3,
+	PERF_COUNT_HW_CACHE_ITLB		= 4,
+	PERF_COUNT_HW_CACHE_BPU			= 5,
+
+	PERF_COUNT_HW_CACHE_MAX,		/* non-ABI */
+};
+
+enum perf_hw_cache_op_id {
+	PERF_COUNT_HW_CACHE_OP_READ		= 0,
+	PERF_COUNT_HW_CACHE_OP_WRITE		= 1,
+	PERF_COUNT_HW_CACHE_OP_PREFETCH		= 2,
+
+	PERF_COUNT_HW_CACHE_OP_MAX,		/* non-ABI */
+};
+
+enum perf_hw_cache_op_result_id {
+	PERF_COUNT_HW_CACHE_RESULT_ACCESS	= 0,
+	PERF_COUNT_HW_CACHE_RESULT_MISS		= 1,
+
+	PERF_COUNT_HW_CACHE_RESULT_MAX,		/* non-ABI */
+};
+
+/*
+ * Special "software" events provided by the kernel, even if the hardware
+ * does not support performance events. These events measure various
+ * physical and sw events of the kernel (and allow the profiling of them as
+ * well):
+ */
+enum perf_sw_ids {
+	PERF_COUNT_SW_CPU_CLOCK			= 0,
+	PERF_COUNT_SW_TASK_CLOCK		= 1,
+	PERF_COUNT_SW_PAGE_FAULTS		= 2,
+	PERF_COUNT_SW_CONTEXT_SWITCHES		= 3,
+	PERF_COUNT_SW_CPU_MIGRATIONS		= 4,
+	PERF_COUNT_SW_PAGE_FAULTS_MIN		= 5,
+	PERF_COUNT_SW_PAGE_FAULTS_MAJ		= 6,
+
+	PERF_COUNT_SW_MAX,			/* non-ABI */
+};
+
+/*
+ * Bits that can be set in attr.sample_type to request information
+ * in the overflow packets.
+ */
+enum perf_event_sample_format {
+	PERF_SAMPLE_IP				= 1U << 0,
+	PERF_SAMPLE_TID				= 1U << 1,
+	PERF_SAMPLE_TIME			= 1U << 2,
+	PERF_SAMPLE_ADDR			= 1U << 3,
+	PERF_SAMPLE_READ			= 1U << 4,
+	PERF_SAMPLE_CALLCHAIN			= 1U << 5,
+	PERF_SAMPLE_ID				= 1U << 6,
+	PERF_SAMPLE_CPU				= 1U << 7,
+	PERF_SAMPLE_PERIOD			= 1U << 8,
+	PERF_SAMPLE_STREAM_ID			= 1U << 9,
+	PERF_SAMPLE_RAW				= 1U << 10,
+
+	PERF_SAMPLE_MAX = 1U << 11,		/* non-ABI */
+};
+
+/*
+ * The format of the data returned by read() on a perf event fd,
+ * as specified by attr.read_format:
+ *
+ * struct read_format {
+ *	{ u64		value;
+ *	  { u64		time_enabled; } && PERF_FORMAT_ENABLED
+ *	  { u64		time_running; } && PERF_FORMAT_RUNNING
+ *	  { u64		id;           } && PERF_FORMAT_ID
+ *	} && !PERF_FORMAT_GROUP
+ *
+ *	{ u64		nr;
+ *	  { u64		time_enabled; } && PERF_FORMAT_ENABLED
+ *	  { u64		time_running; } && PERF_FORMAT_RUNNING
+ *	  { u64		value;
+ *	    { u64	id;           } && PERF_FORMAT_ID
+ *	  }		cntr[nr];
+ *	} && PERF_FORMAT_GROUP
+ * };
+ */
+enum perf_event_read_format {
+	PERF_FORMAT_TOTAL_TIME_ENABLED		= 1U << 0,
+	PERF_FORMAT_TOTAL_TIME_RUNNING		= 1U << 1,
+	PERF_FORMAT_ID				= 1U << 2,
+	PERF_FORMAT_GROUP			= 1U << 3,
+
+	PERF_FORMAT_MAX = 1U << 4,		/* non-ABI */
+};
+
+#define PERF_ATTR_SIZE_VER0	64	/* sizeof first published struct */
+
+/*
+ * Hardware event_id to monitor via a performance monitoring event:
+ */
+struct perf_event_attr {
+
+	/*
+	 * Major type: hardware/software/tracepoint/etc.
+	 */
+	__u32			type;
+
+	/*
+	 * Size of the attr structure, for fwd/bwd compat.
+	 */
+	__u32			size;
+
+	/*
+	 * Type specific configuration information.
+	 */
+	__u64			config;
+
+	union {
+		__u64		sample_period;
+		__u64		sample_freq;
+	};
+
+	__u64			sample_type;
+	__u64			read_format;
+
+	__u64			disabled       :  1, /* off by default        */
+				inherit	       :  1, /* children inherit it   */
+				pinned	       :  1, /* must always be on PMU */
+				exclusive      :  1, /* only group on PMU     */
+				exclude_user   :  1, /* don't count user      */
+				exclude_kernel :  1, /* ditto kernel          */
+				exclude_hv     :  1, /* ditto hypervisor      */
+				exclude_idle   :  1, /* don't count when idle */
+				mmap           :  1, /* include mmap data     */
+				comm	       :  1, /* include comm data     */
+				freq           :  1, /* use freq, not period  */
+				inherit_stat   :  1, /* per task counts       */
+				enable_on_exec :  1, /* next exec enables     */
+				task           :  1, /* trace fork/exit       */
+				watermark      :  1, /* wakeup_watermark      */
+
+				__reserved_1   : 49;
+
+	union {
+		__u32		wakeup_events;	  /* wakeup every n events */
+		__u32		wakeup_watermark; /* bytes before wakeup   */
+	};
+	__u32			__reserved_2;
+
+	__u64			__reserved_3;
+};
+
+/*
+ * Ioctls that can be done on a perf event fd:
+ */
+#define PERF_EVENT_IOC_ENABLE		_IO ('$', 0)
+#define PERF_EVENT_IOC_DISABLE		_IO ('$', 1)
+#define PERF_EVENT_IOC_REFRESH		_IO ('$', 2)
+#define PERF_EVENT_IOC_RESET		_IO ('$', 3)
+#define PERF_EVENT_IOC_PERIOD		_IOW('$', 4, u64)
+#define PERF_EVENT_IOC_SET_OUTPUT	_IO ('$', 5)
+
+enum perf_event_ioc_flags {
+	PERF_IOC_FLAG_GROUP		= 1U << 0,
+};
+
+/*
+ * Structure of the page that can be mapped via mmap
+ */
+struct perf_event_mmap_page {
+	__u32	version;		/* version number of this structure */
+	__u32	compat_version;		/* lowest version this is compat with */
+
+	/*
+	 * Bits needed to read the hw events in user-space.
+	 *
+	 *   u32 seq;
+	 *   s64 count;
+	 *
+	 *   do {
+	 *     seq = pc->lock;
+	 *
+	 *     barrier()
+	 *     if (pc->index) {
+	 *       count = pmc_read(pc->index - 1);
+	 *       count += pc->offset;
+	 *     } else
+	 *       goto regular_read;
+	 *
+	 *     barrier();
+	 *   } while (pc->lock != seq);
+	 *
+	 * NOTE: for obvious reason this only works on self-monitoring
+	 *       processes.
+	 */
+	__u32	lock;			/* seqlock for synchronization */
+	__u32	index;			/* hardware event identifier */
+	__s64	offset;			/* add to hardware event value */
+	__u64	time_enabled;		/* time event active */
+	__u64	time_running;		/* time event on cpu */
+
+		/*
+		 * Hole for extension of the self monitor capabilities
+		 */
+
+	__u64	__reserved[123];	/* align to 1k */
+
+	/*
+	 * Control data for the mmap() data buffer.
+	 *
+	 * User-space reading the @data_head value should issue an rmb(), on
+	 * SMP capable platforms, after reading this value -- see
+	 * perf_event_wakeup().
+	 *
+	 * When the mapping is PROT_WRITE the @data_tail value should be
+	 * written by userspace to reflect the last read data. In this case
+	 * the kernel will not over-write unread data.
+	 */
+	__u64   data_head;		/* head in the data section */
+	__u64	data_tail;		/* user-space written tail */
+};
+
+#define PERF_RECORD_MISC_CPUMODE_MASK		(3 << 0)
+#define PERF_RECORD_MISC_CPUMODE_UNKNOWN		(0 << 0)
+#define PERF_RECORD_MISC_KERNEL			(1 << 0)
+#define PERF_RECORD_MISC_USER			(2 << 0)
+#define PERF_RECORD_MISC_HYPERVISOR		(3 << 0)
+
+struct perf_event_header {
+	__u32	type;
+	__u16	misc;
+	__u16	size;
+};
+
+enum perf_event_type {
+
+	/*
+	 * The MMAP events record the PROT_EXEC mappings so that we can
+	 * correlate userspace IPs to code. They have the following structure:
+	 *
+	 * struct {
+	 *	struct perf_event_header	header;
+	 *
+	 *	u32				pid, tid;
+	 *	u64				addr;
+	 *	u64				len;
+	 *	u64				pgoff;
+	 *	char				filename[];
+	 * };
+	 */
+	PERF_RECORD_MMAP			= 1,
+
+	/*
+	 * struct {
+	 *	struct perf_event_header	header;
+	 *	u64				id;
+	 *	u64				lost;
+	 * };
+	 */
+	PERF_RECORD_LOST			= 2,
+
+	/*
+	 * struct {
+	 *	struct perf_event_header	header;
+	 *
+	 *	u32				pid, tid;
+	 *	char				comm[];
+	 * };
+	 */
+	PERF_RECORD_COMM			= 3,
+
+	/*
+	 * struct {
+	 *	struct perf_event_header	header;
+	 *	u32				pid, ppid;
+	 *	u32				tid, ptid;
+	 *	u64				time;
+	 * };
+	 */
+	PERF_RECORD_EXIT			= 4,
+
+	/*
+	 * struct {
+	 *	struct perf_event_header	header;
+	 *	u64				time;
+	 *	u64				id;
+	 *	u64				stream_id;
+	 * };
+	 */
+	PERF_RECORD_THROTTLE		= 5,
+	PERF_RECORD_UNTHROTTLE		= 6,
+
+	/*
+	 * struct {
+	 *	struct perf_event_header	header;
+	 *	u32				pid, ppid;
+	 *	u32				tid, ptid;
+	 *	{ u64				time;     } && PERF_SAMPLE_TIME
+	 * };
+	 */
+	PERF_RECORD_FORK			= 7,
+
+	/*
+	 * struct {
+	 * 	struct perf_event_header	header;
+	 * 	u32				pid, tid;
+	 *
+	 * 	struct read_format		values;
+	 * };
+	 */
+	PERF_RECORD_READ			= 8,
+
+	/*
+	 * struct {
+	 *	struct perf_event_header	header;
+	 *
+	 *	{ u64			ip;	  } && PERF_SAMPLE_IP
+	 *	{ u32			pid, tid; } && PERF_SAMPLE_TID
+	 *	{ u64			time;     } && PERF_SAMPLE_TIME
+	 *	{ u64			addr;     } && PERF_SAMPLE_ADDR
+	 *	{ u64			id;	  } && PERF_SAMPLE_ID
+	 *	{ u64			stream_id;} && PERF_SAMPLE_STREAM_ID
+	 *	{ u32			cpu, res; } && PERF_SAMPLE_CPU
+	 *	{ u64			period;   } && PERF_SAMPLE_PERIOD
+	 *
+	 *	{ struct read_format	values;	  } && PERF_SAMPLE_READ
+	 *
+	 *	{ u64			nr,
+	 *	  u64			ips[nr];  } && PERF_SAMPLE_CALLCHAIN
+	 *
+	 *	#
+	 *	# The RAW record below is opaque data wrt the ABI
+	 *	#
+	 *	# That is, the ABI doesn't make any promises wrt to
+	 *	# the stability of its content, it may vary depending
+	 *	# on event, hardware, kernel version and phase of
+	 *	# the moon.
+	 *	#
+	 *	# In other words, PERF_SAMPLE_RAW contents are not an ABI.
+	 *	#
+	 *
+	 *	{ u32			size;
+	 *	  char                  data[size];}&& PERF_SAMPLE_RAW
+	 * };
+	 */
+	PERF_RECORD_SAMPLE		= 9,
+
+	PERF_RECORD_MAX,			/* non-ABI */
+};
+
+enum perf_callchain_context {
+	PERF_CONTEXT_HV			= (__u64)-32,
+	PERF_CONTEXT_KERNEL		= (__u64)-128,
+	PERF_CONTEXT_USER		= (__u64)-512,
+
+	PERF_CONTEXT_GUEST		= (__u64)-2048,
+	PERF_CONTEXT_GUEST_KERNEL	= (__u64)-2176,
+	PERF_CONTEXT_GUEST_USER		= (__u64)-2560,
+
+	PERF_CONTEXT_MAX		= (__u64)-4095,
+};
+
+#define PERF_FLAG_FD_NO_GROUP	(1U << 0)
+#define PERF_FLAG_FD_OUTPUT	(1U << 1)
+
+#ifdef __KERNEL__
+/*
+ * Kernel-internal data types and definitions:
+ */
+
+#ifdef CONFIG_PERF_EVENTS
+# include <asm/perf_event.h>
+#endif
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/rculist.h>
+#include <linux/rcupdate.h>
+#include <linux/spinlock.h>
+#include <linux/hrtimer.h>
+#include <linux/fs.h>
+#include <linux/pid_namespace.h>
+#include <asm/atomic.h>
+
+#define PERF_MAX_STACK_DEPTH		255
+
+struct perf_callchain_entry {
+	__u64				nr;
+	__u64				ip[PERF_MAX_STACK_DEPTH];
+};
+
+struct perf_raw_record {
+	u32				size;
+	void				*data;
+};
+
+struct task_struct;
+
+/**
+ * struct hw_perf_event - performance event hardware details:
+ */
+struct hw_perf_event {
+#ifdef CONFIG_PERF_EVENTS
+	union {
+		struct { /* hardware */
+			u64		config;
+			unsigned long	config_base;
+			unsigned long	event_base;
+			int		idx;
+		};
+		union { /* software */
+			atomic64_t	count;
+			struct hrtimer	hrtimer;
+		};
+	};
+	atomic64_t			prev_count;
+	u64				sample_period;
+	u64				last_period;
+	atomic64_t			period_left;
+	u64				interrupts;
+
+	u64				freq_count;
+	u64				freq_interrupts;
+	u64				freq_stamp;
+#endif
+};
+
+struct perf_event;
+
+/**
+ * struct pmu - generic performance monitoring unit
+ */
+struct pmu {
+	int (*enable)			(struct perf_event *event);
+	void (*disable)			(struct perf_event *event);
+	void (*read)			(struct perf_event *event);
+	void (*unthrottle)		(struct perf_event *event);
+};
+
+/**
+ * enum perf_event_active_state - the states of a event
+ */
+enum perf_event_active_state {
+	PERF_EVENT_STATE_ERROR		= -2,
+	PERF_EVENT_STATE_OFF		= -1,
+	PERF_EVENT_STATE_INACTIVE	=  0,
+	PERF_EVENT_STATE_ACTIVE		=  1,
+};
+
+struct file;
+
+struct perf_mmap_data {
+	struct rcu_head			rcu_head;
+	int				nr_pages;	/* nr of data pages  */
+	int				writable;	/* are we writable   */
+	int				nr_locked;	/* nr pages mlocked  */
+
+	atomic_t			poll;		/* POLL_ for wakeups */
+	atomic_t			events;		/* event_id limit       */
+
+	atomic_long_t			head;		/* write position    */
+	atomic_long_t			done_head;	/* completed head    */
+
+	atomic_t			lock;		/* concurrent writes */
+	atomic_t			wakeup;		/* needs a wakeup    */
+	atomic_t			lost;		/* nr records lost   */
+
+	long				watermark;	/* wakeup watermark  */
+
+	struct perf_event_mmap_page	*user_page;
+	void				*data_pages[0];
+};
+
+struct perf_pending_entry {
+	struct perf_pending_entry *next;
+	void (*func)(struct perf_pending_entry *);
+};
+
+/**
+ * struct perf_event - performance event kernel representation:
+ */
+struct perf_event {
+#ifdef CONFIG_PERF_EVENTS
+	struct list_head		group_entry;
+	struct list_head		event_entry;
+	struct list_head		sibling_list;
+	int				nr_siblings;
+	struct perf_event		*group_leader;
+	struct perf_event		*output;
+	const struct pmu		*pmu;
+
+	enum perf_event_active_state	state;
+	atomic64_t			count;
+
+	/*
+	 * These are the total time in nanoseconds that the event
+	 * has been enabled (i.e. eligible to run, and the task has
+	 * been scheduled in, if this is a per-task event)
+	 * and running (scheduled onto the CPU), respectively.
+	 *
+	 * They are computed from tstamp_enabled, tstamp_running and
+	 * tstamp_stopped when the event is in INACTIVE or ACTIVE state.
+	 */
+	u64				total_time_enabled;
+	u64				total_time_running;
+
+	/*
+	 * These are timestamps used for computing total_time_enabled
+	 * and total_time_running when the event is in INACTIVE or
+	 * ACTIVE state, measured in nanoseconds from an arbitrary point
+	 * in time.
+	 * tstamp_enabled: the notional time when the event was enabled
+	 * tstamp_running: the notional time when the event was scheduled on
+	 * tstamp_stopped: in INACTIVE state, the notional time when the
+	 *	event was scheduled off.
+	 */
+	u64				tstamp_enabled;
+	u64				tstamp_running;
+	u64				tstamp_stopped;
+
+	struct perf_event_attr	attr;
+	struct hw_perf_event		hw;
+
+	struct perf_event_context	*ctx;
+	struct file			*filp;
+
+	/*
+	 * These accumulate total time (in nanoseconds) that children
+	 * events have been enabled and running, respectively.
+	 */
+	atomic64_t			child_total_time_enabled;
+	atomic64_t			child_total_time_running;
+
+	/*
+	 * Protect attach/detach and child_list:
+	 */
+	struct mutex			child_mutex;
+	struct list_head		child_list;
+	struct perf_event		*parent;
+
+	int				oncpu;
+	int				cpu;
+
+	struct list_head		owner_entry;
+	struct task_struct		*owner;
+
+	/* mmap bits */
+	struct mutex			mmap_mutex;
+	atomic_t			mmap_count;
+	struct perf_mmap_data		*data;
+
+	/* poll related */
+	wait_queue_head_t		waitq;
+	struct fasync_struct		*fasync;
+
+	/* delayed work for NMIs and such */
+	int				pending_wakeup;
+	int				pending_kill;
+	int				pending_disable;
+	struct perf_pending_entry	pending;
+
+	atomic_t			event_limit;
+
+	void (*destroy)(struct perf_event *);
+	struct rcu_head			rcu_head;
+
+	struct pid_namespace		*ns;
+	u64				id;
+#endif
+};
+
+/**
+ * struct perf_event_context - event context structure
+ *
+ * Used as a container for task events and CPU events as well:
+ */
+struct perf_event_context {
+	/*
+	 * Protect the states of the events in the list,
+	 * nr_active, and the list:
+	 */
+	spinlock_t			lock;
+	/*
+	 * Protect the list of events.  Locking either mutex or lock
+	 * is sufficient to ensure the list doesn't change; to change
+	 * the list you need to lock both the mutex and the spinlock.
+	 */
+	struct mutex			mutex;
+
+	struct list_head		group_list;
+	struct list_head		event_list;
+	int				nr_events;
+	int				nr_active;
+	int				is_active;
+	int				nr_stat;
+	atomic_t			refcount;
+	struct task_struct		*task;
+
+	/*
+	 * Context clock, runs when context enabled.
+	 */
+	u64				time;
+	u64				timestamp;
+
+	/*
+	 * These fields let us detect when two contexts have both
+	 * been cloned (inherited) from a common ancestor.
+	 */
+	struct perf_event_context	*parent_ctx;
+	u64				parent_gen;
+	u64				generation;
+	int				pin_count;
+	struct rcu_head			rcu_head;
+};
+
+/**
+ * struct perf_event_cpu_context - per cpu event context structure
+ */
+struct perf_cpu_context {
+	struct perf_event_context	ctx;
+	struct perf_event_context	*task_ctx;
+	int				active_oncpu;
+	int				max_pertask;
+	int				exclusive;
+
+	/*
+	 * Recursion avoidance:
+	 *
+	 * task, softirq, irq, nmi context
+	 */
+	int				recursion[4];
+};
+
+struct perf_output_handle {
+	struct perf_event		*event;
+	struct perf_mmap_data		*data;
+	unsigned long			head;
+	unsigned long			offset;
+	int				nmi;
+	int				sample;
+	int				locked;
+	unsigned long			flags;
+};
+
+#ifdef CONFIG_PERF_EVENTS
+
+/*
+ * Set by architecture code:
+ */
+extern int perf_max_events;
+
+extern const struct pmu *hw_perf_event_init(struct perf_event *event);
+
+extern void perf_event_task_sched_in(struct task_struct *task, int cpu);
+extern void perf_event_task_sched_out(struct task_struct *task,
+					struct task_struct *next, int cpu);
+extern void perf_event_task_tick(struct task_struct *task, int cpu);
+extern int perf_event_init_task(struct task_struct *child);
+extern void perf_event_exit_task(struct task_struct *child);
+extern void perf_event_free_task(struct task_struct *task);
+extern void set_perf_event_pending(void);
+extern void perf_event_do_pending(void);
+extern void perf_event_print_debug(void);
+extern void __perf_disable(void);
+extern bool __perf_enable(void);
+extern void perf_disable(void);
+extern void perf_enable(void);
+extern int perf_event_task_disable(void);
+extern int perf_event_task_enable(void);
+extern int hw_perf_group_sched_in(struct perf_event *group_leader,
+	       struct perf_cpu_context *cpuctx,
+	       struct perf_event_context *ctx, int cpu);
+extern void perf_event_update_userpage(struct perf_event *event);
+
+struct perf_sample_data {
+	u64				type;
+
+	u64				ip;
+	struct {
+		u32	pid;
+		u32	tid;
+	}				tid_entry;
+	u64				time;
+	u64				addr;
+	u64				id;
+	u64				stream_id;
+	struct {
+		u32	cpu;
+		u32	reserved;
+	}				cpu_entry;
+	u64				period;
+	struct perf_callchain_entry	*callchain;
+	struct perf_raw_record		*raw;
+};
+
+extern void perf_output_sample(struct perf_output_handle *handle,
+			       struct perf_event_header *header,
+			       struct perf_sample_data *data,
+			       struct perf_event *event);
+extern void perf_prepare_sample(struct perf_event_header *header,
+				struct perf_sample_data *data,
+				struct perf_event *event,
+				struct pt_regs *regs);
+
+extern int perf_event_overflow(struct perf_event *event, int nmi,
+				 struct perf_sample_data *data,
+				 struct pt_regs *regs);
+
+/*
+ * Return 1 for a software event, 0 for a hardware event
+ */
+static inline int is_software_event(struct perf_event *event)
+{
+	return (event->attr.type != PERF_TYPE_RAW) &&
+		(event->attr.type != PERF_TYPE_HARDWARE) &&
+		(event->attr.type != PERF_TYPE_HW_CACHE);
+}
+
+extern atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX];
+
+extern void __perf_sw_event(u32, u64, int, struct pt_regs *, u64);
+
+static inline void
+perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr)
+{
+	if (atomic_read(&perf_swevent_enabled[event_id]))
+		__perf_sw_event(event_id, nr, nmi, regs, addr);
+}
+
+extern void __perf_event_mmap(struct vm_area_struct *vma);
+
+static inline void perf_event_mmap(struct vm_area_struct *vma)
+{
+	if (vma->vm_flags & VM_EXEC)
+		__perf_event_mmap(vma);
+}
+
+extern void perf_event_comm(struct task_struct *tsk);
+extern void perf_event_fork(struct task_struct *tsk);
+
+extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs);
+
+extern int sysctl_perf_event_paranoid;
+extern int sysctl_perf_event_mlock;
+extern int sysctl_perf_event_sample_rate;
+
+extern void perf_event_init(void);
+extern void perf_tp_event(int event_id, u64 addr, u64 count,
+				 void *record, int entry_size);
+
+#ifndef perf_misc_flags
+#define perf_misc_flags(regs)	(user_mode(regs) ? PERF_RECORD_MISC_USER : \
+				 PERF_RECORD_MISC_KERNEL)
+#define perf_instruction_pointer(regs)	instruction_pointer(regs)
+#endif
+
+extern int perf_output_begin(struct perf_output_handle *handle,
+			     struct perf_event *event, unsigned int size,
+			     int nmi, int sample);
+extern void perf_output_end(struct perf_output_handle *handle);
+extern void perf_output_copy(struct perf_output_handle *handle,
+			     const void *buf, unsigned int len);
+#else
+static inline void
+perf_event_task_sched_in(struct task_struct *task, int cpu)		{ }
+static inline void
+perf_event_task_sched_out(struct task_struct *task,
+			    struct task_struct *next, int cpu)		{ }
+static inline void
+perf_event_task_tick(struct task_struct *task, int cpu)			{ }
+static inline int perf_event_init_task(struct task_struct *child)	{ return 0; }
+static inline void perf_event_exit_task(struct task_struct *child)	{ }
+static inline void perf_event_free_task(struct task_struct *task)	{ }
+static inline void perf_event_do_pending(void)				{ }
+static inline void perf_event_print_debug(void)				{ }
+static inline void perf_disable(void)					{ }
+static inline void perf_enable(void)					{ }
+static inline int perf_event_task_disable(void)				{ return -EINVAL; }
+static inline int perf_event_task_enable(void)				{ return -EINVAL; }
+
+static inline void
+perf_sw_event(u32 event_id, u64 nr, int nmi,
+		     struct pt_regs *regs, u64 addr)			{ }
+
+static inline void perf_event_mmap(struct vm_area_struct *vma)		{ }
+static inline void perf_event_comm(struct task_struct *tsk)		{ }
+static inline void perf_event_fork(struct task_struct *tsk)		{ }
+static inline void perf_event_init(void)				{ }
+
+#endif
+
+#define perf_output_put(handle, x) \
+	perf_output_copy((handle), &(x), sizeof(x))
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_PERF_EVENT_H */
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
index ee5e3c9..1ef5a07 100644
--- a/include/linux/phonet.h
+++ b/include/linux/phonet.h
@@ -99,6 +99,9 @@ struct sockaddr_pn {
 	__u8 spn_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - 3];
 } __attribute__ ((packed));
 
+/* Well known address */
+#define PN_DEV_PC	0x10
+
 static inline __u16 pn_object(__u8 addr, __u16 port)
 {
 	return (addr << 8) | (port & 0x3ff);
@@ -170,4 +173,21 @@ static inline __u8 pn_sockaddr_get_resource(const struct sockaddr_pn *spn)
 	return spn->spn_resource;
 }
 
+/* Phonet device ioctl requests */
+#ifdef __KERNEL__
+#define SIOCPNGAUTOCONF		(SIOCDEVPRIVATE + 0)
+
+struct if_phonet_autoconf {
+	uint8_t device;
+};
+
+struct if_phonet_req {
+	char ifr_phonet_name[16];
+	union {
+		struct if_phonet_autoconf ifru_phonet_autoconf;
+	} ifr_ifru;
+};
+#define ifr_phonet_autoconf ifr_ifru.ifru_phonet_autoconf
+#endif /* __KERNEL__ */
+
 #endif
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 8dc5123..3c6675c 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -22,6 +22,9 @@ struct platform_device {
 	struct resource	* resource;
 
 	struct platform_device_id	*id_entry;
+
+	/* arch specific additions */
+	struct pdev_archdata	archdata;
 };
 
 #define platform_get_device_id(pdev)	((pdev)->id_entry)
@@ -57,8 +60,6 @@ struct platform_driver {
 	int (*remove)(struct platform_device *);
 	void (*shutdown)(struct platform_device *);
 	int (*suspend)(struct platform_device *, pm_message_t state);
-	int (*suspend_late)(struct platform_device *, pm_message_t state);
-	int (*resume_early)(struct platform_device *);
 	int (*resume)(struct platform_device *);
 	struct device_driver driver;
 	struct platform_device_id *id_table;
diff --git a/include/linux/pm.h b/include/linux/pm.h
index b3f7476..3b7e04b 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -22,6 +22,10 @@
 #define _LINUX_PM_H
 
 #include <linux/list.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
 
 /*
  * Callbacks for platform drivers to implement.
@@ -165,6 +169,28 @@ typedef struct pm_message {
  * It is allowed to unregister devices while the above callbacks are being
  * executed.  However, it is not allowed to unregister a device from within any
  * of its own callbacks.
+ *
+ * There also are the following callbacks related to run-time power management
+ * of devices:
+ *
+ * @runtime_suspend: Prepare the device for a condition in which it won't be
+ *	able to communicate with the CPU(s) and RAM due to power management.
+ *	This need not mean that the device should be put into a low power state.
+ *	For example, if the device is behind a link which is about to be turned
+ *	off, the device may remain at full power.  If the device does go to low
+ *	power and if device_may_wakeup(dev) is true, remote wake-up (i.e., a
+ *	hardware mechanism allowing the device to request a change of its power
+ *	state, such as PCI PME) should be enabled for it.
+ *
+ * @runtime_resume: Put the device into the fully active state in response to a
+ *	wake-up event generated by hardware or at the request of software.  If
+ *	necessary, put the device into the full power state and restore its
+ *	registers, so that it is fully operational.
+ *
+ * @runtime_idle: Device appears to be inactive and it might be put into a low
+ *	power state if all of the necessary conditions are satisfied.  Check
+ *	these conditions and handle the device as appropriate, possibly queueing
+ *	a suspend request for it.  The return value is ignored by the PM core.
  */
 
 struct dev_pm_ops {
@@ -182,8 +208,25 @@ struct dev_pm_ops {
 	int (*thaw_noirq)(struct device *dev);
 	int (*poweroff_noirq)(struct device *dev);
 	int (*restore_noirq)(struct device *dev);
+	int (*runtime_suspend)(struct device *dev);
+	int (*runtime_resume)(struct device *dev);
+	int (*runtime_idle)(struct device *dev);
 };
 
+/*
+ * Use this if you want to use the same suspend and resume callbacks for suspend
+ * to RAM and hibernation.
+ */
+#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \
+struct dev_pm_ops name = { \
+	.suspend = suspend_fn, \
+	.resume = resume_fn, \
+	.freeze = suspend_fn, \
+	.thaw = resume_fn, \
+	.poweroff = suspend_fn, \
+	.restore = resume_fn, \
+}
+
 /**
  * PM_EVENT_ messages
  *
@@ -315,14 +358,80 @@ enum dpm_state {
 	DPM_OFF_IRQ,
 };
 
+/**
+ * Device run-time power management status.
+ *
+ * These status labels are used internally by the PM core to indicate the
+ * current status of a device with respect to the PM core operations.  They do
+ * not reflect the actual power state of the device or its status as seen by the
+ * driver.
+ *
+ * RPM_ACTIVE		Device is fully operational.  Indicates that the device
+ *			bus type's ->runtime_resume() callback has completed
+ *			successfully.
+ *
+ * RPM_SUSPENDED	Device bus type's ->runtime_suspend() callback has
+ *			completed successfully.  The device is regarded as
+ *			suspended.
+ *
+ * RPM_RESUMING		Device bus type's ->runtime_resume() callback is being
+ *			executed.
+ *
+ * RPM_SUSPENDING	Device bus type's ->runtime_suspend() callback is being
+ *			executed.
+ */
+
+enum rpm_status {
+	RPM_ACTIVE = 0,
+	RPM_RESUMING,
+	RPM_SUSPENDED,
+	RPM_SUSPENDING,
+};
+
+/**
+ * Device run-time power management request types.
+ *
+ * RPM_REQ_NONE		Do nothing.
+ *
+ * RPM_REQ_IDLE		Run the device bus type's ->runtime_idle() callback
+ *
+ * RPM_REQ_SUSPEND	Run the device bus type's ->runtime_suspend() callback
+ *
+ * RPM_REQ_RESUME	Run the device bus type's ->runtime_resume() callback
+ */
+
+enum rpm_request {
+	RPM_REQ_NONE = 0,
+	RPM_REQ_IDLE,
+	RPM_REQ_SUSPEND,
+	RPM_REQ_RESUME,
+};
+
 struct dev_pm_info {
 	pm_message_t		power_state;
-	unsigned		can_wakeup:1;
-	unsigned		should_wakeup:1;
+	unsigned int		can_wakeup:1;
+	unsigned int		should_wakeup:1;
 	enum dpm_state		status;		/* Owned by the PM core */
-#ifdef	CONFIG_PM_SLEEP
+#ifdef CONFIG_PM_SLEEP
 	struct list_head	entry;
 #endif
+#ifdef CONFIG_PM_RUNTIME
+	struct timer_list	suspend_timer;
+	unsigned long		timer_expires;
+	struct work_struct	work;
+	wait_queue_head_t	wait_queue;
+	spinlock_t		lock;
+	atomic_t		usage_count;
+	atomic_t		child_count;
+	unsigned int		disable_depth:3;
+	unsigned int		ignore_children:1;
+	unsigned int		idle_notification:1;
+	unsigned int		request_pending:1;
+	unsigned int		deferred_resume:1;
+	enum rpm_request	request;
+	enum rpm_status		runtime_status;
+	int			runtime_error;
+#endif
 };
 
 /*
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
new file mode 100644
index 0000000..4408704
--- /dev/null
+++ b/include/linux/pm_runtime.h
@@ -0,0 +1,114 @@
+/*
+ * pm_runtime.h - Device run-time power management helper functions.
+ *
+ * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#ifndef _LINUX_PM_RUNTIME_H
+#define _LINUX_PM_RUNTIME_H
+
+#include <linux/device.h>
+#include <linux/pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+
+extern struct workqueue_struct *pm_wq;
+
+extern int pm_runtime_idle(struct device *dev);
+extern int pm_runtime_suspend(struct device *dev);
+extern int pm_runtime_resume(struct device *dev);
+extern int pm_request_idle(struct device *dev);
+extern int pm_schedule_suspend(struct device *dev, unsigned int delay);
+extern int pm_request_resume(struct device *dev);
+extern int __pm_runtime_get(struct device *dev, bool sync);
+extern int __pm_runtime_put(struct device *dev, bool sync);
+extern int __pm_runtime_set_status(struct device *dev, unsigned int status);
+extern int pm_runtime_barrier(struct device *dev);
+extern void pm_runtime_enable(struct device *dev);
+extern void __pm_runtime_disable(struct device *dev, bool check_resume);
+
+static inline bool pm_children_suspended(struct device *dev)
+{
+	return dev->power.ignore_children
+		|| !atomic_read(&dev->power.child_count);
+}
+
+static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
+{
+	dev->power.ignore_children = enable;
+}
+
+static inline void pm_runtime_get_noresume(struct device *dev)
+{
+	atomic_inc(&dev->power.usage_count);
+}
+
+static inline void pm_runtime_put_noidle(struct device *dev)
+{
+	atomic_add_unless(&dev->power.usage_count, -1, 0);
+}
+
+#else /* !CONFIG_PM_RUNTIME */
+
+static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; }
+static inline int pm_runtime_suspend(struct device *dev) { return -ENOSYS; }
+static inline int pm_runtime_resume(struct device *dev) { return 0; }
+static inline int pm_request_idle(struct device *dev) { return -ENOSYS; }
+static inline int pm_schedule_suspend(struct device *dev, unsigned int delay)
+{
+	return -ENOSYS;
+}
+static inline int pm_request_resume(struct device *dev) { return 0; }
+static inline int __pm_runtime_get(struct device *dev, bool sync) { return 1; }
+static inline int __pm_runtime_put(struct device *dev, bool sync) { return 0; }
+static inline int __pm_runtime_set_status(struct device *dev,
+					    unsigned int status) { return 0; }
+static inline int pm_runtime_barrier(struct device *dev) { return 0; }
+static inline void pm_runtime_enable(struct device *dev) {}
+static inline void __pm_runtime_disable(struct device *dev, bool c) {}
+
+static inline bool pm_children_suspended(struct device *dev) { return false; }
+static inline void pm_suspend_ignore_children(struct device *dev, bool en) {}
+static inline void pm_runtime_get_noresume(struct device *dev) {}
+static inline void pm_runtime_put_noidle(struct device *dev) {}
+
+#endif /* !CONFIG_PM_RUNTIME */
+
+static inline int pm_runtime_get(struct device *dev)
+{
+	return __pm_runtime_get(dev, false);
+}
+
+static inline int pm_runtime_get_sync(struct device *dev)
+{
+	return __pm_runtime_get(dev, true);
+}
+
+static inline int pm_runtime_put(struct device *dev)
+{
+	return __pm_runtime_put(dev, false);
+}
+
+static inline int pm_runtime_put_sync(struct device *dev)
+{
+	return __pm_runtime_put(dev, true);
+}
+
+static inline int pm_runtime_set_active(struct device *dev)
+{
+	return __pm_runtime_set_status(dev, RPM_ACTIVE);
+}
+
+static inline void pm_runtime_set_suspended(struct device *dev)
+{
+	__pm_runtime_set_status(dev, RPM_SUSPENDED);
+}
+
+static inline void pm_runtime_disable(struct device *dev)
+{
+	__pm_runtime_disable(dev, true);
+}
+
+#endif
diff --git a/include/linux/prctl.h b/include/linux/prctl.h
index b00df4c..07bff66 100644
--- a/include/linux/prctl.h
+++ b/include/linux/prctl.h
@@ -85,7 +85,7 @@
 #define PR_SET_TIMERSLACK 29
 #define PR_GET_TIMERSLACK 30
 
-#define PR_TASK_PERF_COUNTERS_DISABLE		31
-#define PR_TASK_PERF_COUNTERS_ENABLE		32
+#define PR_TASK_PERF_EVENTS_DISABLE		31
+#define PR_TASK_PERF_EVENTS_ENABLE		32
 
 #endif /* _LINUX_PRCTL_H */
diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h
index f9ddd03..589a409 100644
--- a/include/linux/rculist_nulls.h
+++ b/include/linux/rculist_nulls.h
@@ -102,7 +102,7 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
  */
 #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \
 	for (pos = rcu_dereference((head)->first);			 \
-		(!is_a_nulls(pos)) && 			\
+		(!is_a_nulls(pos)) &&			\
 		({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \
 		pos = rcu_dereference(pos->next))
 
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 95e0615..6fe0363 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -1,5 +1,5 @@
 /*
- * Read-Copy Update mechanism for mutual exclusion 
+ * Read-Copy Update mechanism for mutual exclusion
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
  * Copyright IBM Corporation, 2001
  *
  * Author: Dipankar Sarma <dipankar@in.ibm.com>
- * 
+ *
  * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
  * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
  * Papers:
@@ -26,7 +26,7 @@
  * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001)
  *
  * For detailed explanation of Read-Copy Update mechanism see -
- * 		http://lse.sourceforge.net/locking/rcupdate.html
+ *		http://lse.sourceforge.net/locking/rcupdate.html
  *
  */
 
@@ -52,8 +52,13 @@ struct rcu_head {
 };
 
 /* Exported common interfaces */
+#ifdef CONFIG_TREE_PREEMPT_RCU
 extern void synchronize_rcu(void);
+#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
+#define synchronize_rcu synchronize_sched
+#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
 extern void synchronize_rcu_bh(void);
+extern void synchronize_sched(void);
 extern void rcu_barrier(void);
 extern void rcu_barrier_bh(void);
 extern void rcu_barrier_sched(void);
@@ -262,24 +267,6 @@ struct rcu_synchronize {
 extern void wakeme_after_rcu(struct rcu_head  *head);
 
 /**
- * synchronize_sched - block until all CPUs have exited any non-preemptive
- * kernel code sequences.
- *
- * This means that all preempt_disable code sequences, including NMI and
- * hardware-interrupt handlers, in progress on entry will have completed
- * before this primitive returns.  However, this does not guarantee that
- * softirq handlers will have completed, since in some kernels, these
- * handlers can run in process context, and can block.
- *
- * This primitive provides the guarantees made by the (now removed)
- * synchronize_kernel() API.  In contrast, synchronize_rcu() only
- * guarantees that rcu_read_lock() sections will have completed.
- * In "classic RCU", these two guarantees happen to be one and
- * the same, but can differ in realtime RCU implementations.
- */
-#define synchronize_sched() __synchronize_sched()
-
-/**
  * call_rcu - Queue an RCU callback for invocation after a grace period.
  * @head: structure to be used for queueing the RCU updates.
  * @func: actual update function to be invoked after the grace period
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index a893077..3768277 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -24,7 +24,7 @@
  * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
  *
  * For detailed explanation of Read-Copy Update mechanism see -
- * 	Documentation/RCU
+ *	Documentation/RCU
  */
 
 #ifndef __LINUX_RCUTREE_H
@@ -53,6 +53,8 @@ static inline void __rcu_read_unlock(void)
 	preempt_enable();
 }
 
+#define __synchronize_sched() synchronize_rcu()
+
 static inline void exit_rcu(void)
 {
 }
@@ -68,8 +70,6 @@ static inline void __rcu_read_unlock_bh(void)
 	local_bh_enable();
 }
 
-#define __synchronize_sched() synchronize_rcu()
-
 extern void call_rcu_sched(struct rcu_head *head,
 			   void (*func)(struct rcu_head *rcu));
 
diff --git a/include/linux/rds.h b/include/linux/rds.h
index d91dc91..89d46e1 100644
--- a/include/linux/rds.h
+++ b/include/linux/rds.h
@@ -147,6 +147,18 @@ struct rds_info_socket {
 	u_int64_t	inum;
 } __attribute__((packed));
 
+struct rds_info_tcp_socket {
+	__be32          local_addr;
+	__be16          local_port;
+	__be32          peer_addr;
+	__be16          peer_port;
+	u_int64_t       hdr_rem;
+	u_int64_t       data_rem;
+	u_int32_t       last_sent_nxt;
+	u_int32_t       last_expected_una;
+	u_int32_t       last_seen_una;
+} __attribute__((packed));
+
 #define RDS_IB_GID_LEN	16
 struct rds_info_rdma_connection {
 	__be32		src_addr;
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 225f733..ce1be70 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -193,6 +193,8 @@ void *rdev_get_drvdata(struct regulator_dev *rdev);
 struct device *rdev_get_dev(struct regulator_dev *rdev);
 int rdev_get_id(struct regulator_dev *rdev);
 
+int regulator_mode_to_status(unsigned int);
+
 void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
 
 #endif
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 278777f..3392c59 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -6,20 +6,17 @@
  * Copyright (C) 2007 Dmitry Torokhov
  * Copyright 2009 Johannes Berg <johannes@sipsolutions.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.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU 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.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
 #include <linux/types.h>
@@ -47,6 +44,7 @@ enum rfkill_type {
 	RFKILL_TYPE_UWB,
 	RFKILL_TYPE_WIMAX,
 	RFKILL_TYPE_WWAN,
+	RFKILL_TYPE_GPS,
 	NUM_RFKILL_TYPES,
 };
 
@@ -82,6 +80,20 @@ struct rfkill_event {
 	__u8  soft, hard;
 } __packed;
 
+/*
+ * We are planning to be backward and forward compatible with changes
+ * to the event struct, by adding new, optional, members at the end.
+ * When reading an event (whether the kernel from userspace or vice
+ * versa) we need to accept anything that's at least as large as the
+ * version 1 event size, but might be able to accept other sizes in
+ * the future.
+ *
+ * One exception is the kernel -- we already have two event sizes in
+ * that we've made the 'hard' member optional since our only option
+ * is to ignore it anyway.
+ */
+#define RFKILL_EVENT_SIZE_V1	8
+
 /* ioctl for turning off rfkill-input (if present) */
 #define RFKILL_IOC_MAGIC	'R'
 #define RFKILL_IOC_NOINPUT	1
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index ba3254e..adf2068 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -104,7 +104,7 @@ enum {
 	RTM_NEWADDRLABEL = 72,
 #define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
 	RTM_DELADDRLABEL,
-#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
+#define RTM_DELADDRLABEL RTM_DELADDRLABEL
 	RTM_GETADDRLABEL,
 #define RTM_GETADDRLABEL RTM_GETADDRLABEL
 
diff --git a/include/linux/rxrpc.h b/include/linux/rxrpc.h
index f7b826b..a53915c 100644
--- a/include/linux/rxrpc.h
+++ b/include/linux/rxrpc.h
@@ -58,5 +58,12 @@ struct sockaddr_rxrpc {
 #define RXRPC_SECURITY_AUTH	1	/* authenticated packets */
 #define RXRPC_SECURITY_ENCRYPT	2	/* encrypted packets */
 
+/*
+ * RxRPC security indices
+ */
+#define RXRPC_SECURITY_NONE	0	/* no security protocol */
+#define RXRPC_SECURITY_RXKAD	2	/* kaserver or kerberos 4 */
+#define RXRPC_SECURITY_RXGK	4	/* gssapi-based */
+#define RXRPC_SECURITY_RXK5	5	/* kerberos 5 */
 
 #endif /* _LINUX_RXRPC_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f3d74bd..8fe351c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -100,7 +100,7 @@ struct robust_list_head;
 struct bio;
 struct fs_struct;
 struct bts_context;
-struct perf_counter_context;
+struct perf_event_context;
 
 /*
  * List of flags we want to share for kernel threads,
@@ -190,6 +190,7 @@ extern unsigned long long time_sync_thresh;
 /* in tsk->state again */
 #define TASK_DEAD		64
 #define TASK_WAKEKILL		128
+#define TASK_WAKING		256
 
 /* Convenience macros for the sake of set_task_state */
 #define TASK_KILLABLE		(TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
@@ -256,7 +257,7 @@ extern asmlinkage void schedule_tail(struct task_struct *prev);
 extern void init_idle(struct task_struct *idle, int cpu);
 extern void init_idle_bootup_task(struct task_struct *idle);
 
-extern int runqueue_is_locked(void);
+extern int runqueue_is_locked(int cpu);
 extern void task_rq_unlock_wait(struct task_struct *p);
 
 extern cpumask_var_t nohz_cpu_mask;
@@ -700,7 +701,7 @@ struct user_struct {
 #endif
 #endif
 
-#ifdef CONFIG_PERF_COUNTERS
+#ifdef CONFIG_PERF_EVENTS
 	atomic_long_t locked_vm;
 #endif
 };
@@ -802,14 +803,14 @@ enum cpu_idle_type {
 #define SD_BALANCE_NEWIDLE	0x0002	/* Balance when about to become idle */
 #define SD_BALANCE_EXEC		0x0004	/* Balance on exec */
 #define SD_BALANCE_FORK		0x0008	/* Balance on fork, clone */
-#define SD_WAKE_IDLE		0x0010	/* Wake to idle CPU on task wakeup */
+#define SD_BALANCE_WAKE		0x0010  /* Balance on wakeup */
 #define SD_WAKE_AFFINE		0x0020	/* Wake task to waking CPU */
-#define SD_WAKE_BALANCE		0x0040	/* Perform balancing at task wakeup */
+#define SD_PREFER_LOCAL		0x0040  /* Prefer to keep tasks local to this domain */
 #define SD_SHARE_CPUPOWER	0x0080	/* Domain members share cpu power */
 #define SD_POWERSAVINGS_BALANCE	0x0100	/* Balance for power savings */
 #define SD_SHARE_PKG_RESOURCES	0x0200	/* Domain members share cpu pkg resources */
 #define SD_SERIALIZE		0x0400	/* Only a single load balancing instance */
-#define SD_WAKE_IDLE_FAR	0x0800	/* Gain latency sacrificing cache hit */
+
 #define SD_PREFER_SIBLING	0x1000	/* Prefer to place tasks in a sibling domain */
 
 enum powersavings_balance_level {
@@ -991,6 +992,9 @@ static inline int test_sd_parent(struct sched_domain *sd, int flag)
 	return 0;
 }
 
+unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu);
+unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu);
+
 #else /* CONFIG_SMP */
 
 struct sched_domain_attr;
@@ -1002,6 +1006,7 @@ partition_sched_domains(int ndoms_new, struct cpumask *doms_new,
 }
 #endif	/* !CONFIG_SMP */
 
+
 struct io_context;			/* See blkdev.h */
 
 
@@ -1019,6 +1024,12 @@ struct uts_namespace;
 struct rq;
 struct sched_domain;
 
+/*
+ * wake flags
+ */
+#define WF_SYNC		0x01		/* waker goes to sleep after wakup */
+#define WF_FORK		0x02		/* child wakeup after fork */
+
 struct sched_class {
 	const struct sched_class *next;
 
@@ -1026,13 +1037,13 @@ struct sched_class {
 	void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep);
 	void (*yield_task) (struct rq *rq);
 
-	void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync);
+	void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int flags);
 
 	struct task_struct * (*pick_next_task) (struct rq *rq);
 	void (*put_prev_task) (struct rq *rq, struct task_struct *p);
 
 #ifdef CONFIG_SMP
-	int  (*select_task_rq)(struct task_struct *p, int sync);
+	int  (*select_task_rq)(struct task_struct *p, int sd_flag, int flags);
 
 	unsigned long (*load_balance) (struct rq *this_rq, int this_cpu,
 			struct rq *busiest, unsigned long max_load_move,
@@ -1064,6 +1075,8 @@ struct sched_class {
 	void (*prio_changed) (struct rq *this_rq, struct task_struct *task,
 			     int oldprio, int running);
 
+	unsigned int (*get_rr_interval) (struct task_struct *task);
+
 #ifdef CONFIG_FAIR_GROUP_SCHED
 	void (*moved_group) (struct task_struct *p);
 #endif
@@ -1102,6 +1115,8 @@ struct sched_entity {
 	u64			start_runtime;
 	u64			avg_wakeup;
 
+	u64			avg_running;
+
 #ifdef CONFIG_SCHEDSTATS
 	u64			wait_start;
 	u64			wait_max;
@@ -1436,10 +1451,10 @@ struct task_struct {
 	struct list_head pi_state_list;
 	struct futex_pi_state *pi_state_cache;
 #endif
-#ifdef CONFIG_PERF_COUNTERS
-	struct perf_counter_context *perf_counter_ctxp;
-	struct mutex perf_counter_mutex;
-	struct list_head perf_counter_list;
+#ifdef CONFIG_PERF_EVENTS
+	struct perf_event_context *perf_event_ctxp;
+	struct mutex perf_event_mutex;
+	struct list_head perf_event_list;
 #endif
 #ifdef CONFIG_NUMA
 	struct mempolicy *mempolicy;	/* Protected by alloc_lock */
@@ -1740,7 +1755,6 @@ extern cputime_t task_gtime(struct task_struct *p);
 
 #define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */
 #define RCU_READ_UNLOCK_NEED_QS (1 << 1) /* RCU core needs CPU response. */
-#define RCU_READ_UNLOCK_GOT_QS  (1 << 2) /* CPU has responded to RCU core. */
 
 static inline void rcu_copy_process(struct task_struct *p)
 {
diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index 20f965d..82e0f26 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -61,6 +61,11 @@ void selinux_secmark_refcount_inc(void);
  *     existing SECMARK targets has been removed/flushed.
  */
 void selinux_secmark_refcount_dec(void);
+
+/**
+ * selinux_is_enabled - is SELinux enabled?
+ */
+bool selinux_is_enabled(void);
 #else
 
 static inline int selinux_string_to_sid(const char *str, u32 *sid)
@@ -84,6 +89,10 @@ static inline void selinux_secmark_refcount_dec(void)
 	return;
 }
 
+static inline bool selinux_is_enabled(void)
+{
+	return false;
+}
 #endif	/* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff --git a/include/linux/serial.h b/include/linux/serial.h
index e5bb75a..c8613c3 100644
--- a/include/linux/serial.h
+++ b/include/linux/serial.h
@@ -122,6 +122,7 @@ struct serial_uart_config {
 
 /* Internal flags used only by kernel */
 #define ASYNCB_INITIALIZED	31 /* Serial port was initialized */
+#define ASYNCB_SUSPENDED	30 /* Serial port is suspended */
 #define ASYNCB_NORMAL_ACTIVE	29 /* Normal device is active */
 #define ASYNCB_BOOT_AUTOCONF	28 /* Autoconfigure port on bootup */
 #define ASYNCB_CLOSING		27 /* Serial port is closing */
@@ -133,6 +134,7 @@ struct serial_uart_config {
 #define ASYNCB_FIRST_KERNEL	22
 
 #define ASYNC_HUP_NOTIFY	(1U << ASYNCB_HUP_NOTIFY)
+#define ASYNC_SUSPENDED		(1U << ASYNCB_SUSPENDED)
 #define ASYNC_FOURPORT		(1U << ASYNCB_FOURPORT)
 #define ASYNC_SAK		(1U << ASYNCB_SAK)
 #define ASYNC_SPLIT_TERMIOS	(1U << ASYNCB_SPLIT_TERMIOS)
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index d4d2a78..fb46aba 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -22,6 +22,7 @@ struct plat_serial8250_port {
 	void __iomem	*membase;	/* ioremap cookie or NULL */
 	resource_size_t	mapbase;	/* resource base */
 	unsigned int	irq;		/* interrupt number */
+	unsigned long	irqflags;	/* request_irq flags */
 	unsigned int	uartclk;	/* UART clock rate */
 	void            *private_data;
 	unsigned char	regshift;	/* register shift */
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 23d2fb0..d58e460 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -20,6 +20,8 @@
 #ifndef LINUX_SERIAL_CORE_H
 #define LINUX_SERIAL_CORE_H
 
+#include <linux/serial.h>
+
 /*
  * The type definitions.  These are from Ted Ts'o's serial.h
  */
@@ -186,7 +188,6 @@
 #include <linux/sysrq.h>
 
 struct uart_port;
-struct uart_info;
 struct serial_struct;
 struct device;
 
@@ -265,6 +266,7 @@ struct uart_port {
 	unsigned int		(*serial_in)(struct uart_port *, int);
 	void			(*serial_out)(struct uart_port *, int, int);
 	unsigned int		irq;			/* irq number */
+	unsigned long		irqflags;		/* irq flags  */
 	unsigned int		uartclk;		/* base uart clock */
 	unsigned int		fifosize;		/* tx fifo size */
 	unsigned char		x_char;			/* xon/xoff char */
@@ -283,7 +285,7 @@ struct uart_port {
 
 	unsigned int		read_status_mask;	/* driver specific */
 	unsigned int		ignore_status_mask;	/* driver specific */
-	struct uart_info	*info;			/* pointer to parent info */
+	struct uart_state	*state;			/* pointer to parent state */
 	struct uart_icount	icount;			/* statistics */
 
 	struct console		*cons;			/* struct console, if any */
@@ -335,52 +337,16 @@ struct uart_port {
 };
 
 /*
- * This is the state information which is only valid when the port
- * is open; it may be cleared the core driver once the device has
- * been closed.  Either the low level driver or the core can modify
- * stuff here.
- */
-typedef unsigned int __bitwise__ uif_t;
-
-struct uart_info {
-	struct tty_port		port;
-	struct circ_buf		xmit;
-	uif_t			flags;
-
-/*
- * Definitions for info->flags.  These are _private_ to serial_core, and
- * are specific to this structure.  They may be queried by low level drivers.
- *
- * FIXME: use the ASY_ definitions
- */
-#define UIF_CHECK_CD		((__force uif_t) (1 << 25))
-#define UIF_CTS_FLOW		((__force uif_t) (1 << 26))
-#define UIF_NORMAL_ACTIVE	((__force uif_t) (1 << 29))
-#define UIF_INITIALIZED		((__force uif_t) (1 << 31))
-#define UIF_SUSPENDED		((__force uif_t) (1 << 30))
-
-	struct tasklet_struct	tlet;
-	wait_queue_head_t	delta_msr_wait;
-};
-
-/*
  * This is the state information which is persistent across opens.
- * The low level driver must not to touch any elements contained
- * within.
  */
 struct uart_state {
-	unsigned int		close_delay;		/* msec */
-	unsigned int		closing_wait;		/* msec */
-
-#define USF_CLOSING_WAIT_INF	(0)
-#define USF_CLOSING_WAIT_NONE	(~0U)
+	struct tty_port		port;
 
-	int			count;
 	int			pm_state;
-	struct uart_info	info;
-	struct uart_port	*port;
+	struct circ_buf		xmit;
 
-	struct mutex		mutex;
+	struct tasklet_struct	tlet;
+	struct uart_port	*uart_port;
 };
 
 #define UART_XMIT_SIZE	PAGE_SIZE
@@ -461,7 +427,7 @@ int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
 
 static inline int uart_tx_stopped(struct uart_port *port)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 	if(tty->stopped || tty->hw_stopped)
 		return 1;
 	return 0;
@@ -476,7 +442,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
 #ifdef SUPPORT_SYSRQ
 	if (port->sysrq) {
 		if (ch && time_before(jiffies, port->sysrq)) {
-			handle_sysrq(ch, port->info->port.tty);
+			handle_sysrq(ch, port->state->port.tty);
 			port->sysrq = 0;
 			return 1;
 		}
@@ -494,7 +460,7 @@ uart_handle_sysrq_char(struct uart_port *port, unsigned int ch)
  */
 static inline int uart_handle_break(struct uart_port *port)
 {
-	struct uart_info *info = port->info;
+	struct uart_state *state = port->state;
 #ifdef SUPPORT_SYSRQ
 	if (port->cons && port->cons->index == port->line) {
 		if (!port->sysrq) {
@@ -505,7 +471,7 @@ static inline int uart_handle_break(struct uart_port *port)
 	}
 #endif
 	if (port->flags & UPF_SAK)
-		do_SAK(info->port.tty);
+		do_SAK(state->port.tty);
 	return 0;
 }
 
@@ -515,22 +481,23 @@ static inline int uart_handle_break(struct uart_port *port)
  *	@status: new carrier detect status, nonzero if active
  */
 static inline void
-uart_handle_dcd_change(struct uart_port *port, unsigned int status)
+uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
 {
-	struct uart_info *info = port->info;
+	struct uart_state *state = uport->state;
+	struct tty_port *port = &state->port;
 
-	port->icount.dcd++;
+	uport->icount.dcd++;
 
 #ifdef CONFIG_HARD_PPS
-	if ((port->flags & UPF_HARDPPS_CD) && status)
+	if ((uport->flags & UPF_HARDPPS_CD) && status)
 		hardpps();
 #endif
 
-	if (info->flags & UIF_CHECK_CD) {
+	if (port->flags & ASYNC_CHECK_CD) {
 		if (status)
-			wake_up_interruptible(&info->port.open_wait);
-		else if (info->port.tty)
-			tty_hangup(info->port.tty);
+			wake_up_interruptible(&port->open_wait);
+		else if (port->tty)
+			tty_hangup(port->tty);
 	}
 }
 
@@ -540,24 +507,24 @@ uart_handle_dcd_change(struct uart_port *port, unsigned int status)
  *	@status: new clear to send status, nonzero if active
  */
 static inline void
-uart_handle_cts_change(struct uart_port *port, unsigned int status)
+uart_handle_cts_change(struct uart_port *uport, unsigned int status)
 {
-	struct uart_info *info = port->info;
-	struct tty_struct *tty = info->port.tty;
+	struct tty_port *port = &uport->state->port;
+	struct tty_struct *tty = port->tty;
 
-	port->icount.cts++;
+	uport->icount.cts++;
 
-	if (info->flags & UIF_CTS_FLOW) {
+	if (port->flags & ASYNC_CTS_FLOW) {
 		if (tty->hw_stopped) {
 			if (status) {
 				tty->hw_stopped = 0;
-				port->ops->start_tx(port);
-				uart_write_wakeup(port);
+				uport->ops->start_tx(uport);
+				uart_write_wakeup(uport);
 			}
 		} else {
 			if (!status) {
 				tty->hw_stopped = 1;
-				port->ops->stop_tx(port);
+				uport->ops->stop_tx(uport);
 			}
 		}
 	}
@@ -569,7 +536,7 @@ static inline void
 uart_insert_char(struct uart_port *port, unsigned int status,
 		 unsigned int overrun, unsigned int ch, unsigned int flag)
 {
-	struct tty_struct *tty = port->info->port.tty;
+	struct tty_struct *tty = port->state->port.tty;
 
 	if ((status & port->ignore_status_mask & ~overrun) == 0)
 		tty_insert_flip_char(tty, ch, flag);
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 126d24c..a640bc2 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -31,8 +31,6 @@ struct serio {
 
 	bool manual_bind;
 	bool registered;	/* port has been fully registered with driver core */
-	bool suspended;		/* port is suspended */
-
 
 	struct serio_device_id id;
 
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
index eb1423a..68e212f 100644
--- a/include/linux/sh_intc.h
+++ b/include/linux/sh_intc.h
@@ -85,7 +85,6 @@ struct intc_desc symbol __initdata = {					\
 }
 #endif
 
-unsigned int intc_evt2irq(unsigned int vector);
 void __init register_intc_controller(struct intc_desc *desc);
 int intc_set_priority(unsigned int irq, unsigned int prio);
 
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 6d3f2f4..deee7af 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -38,6 +38,9 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
 	return container_of(inode, struct shmem_inode_info, vfs_inode);
 }
 
+extern int init_tmpfs(void);
+extern int shmem_fill_super(struct super_block *sb, void *data, int silent);
+
 #ifdef CONFIG_TMPFS_POSIX_ACL
 int shmem_check_acl(struct inode *, int);
 int shmem_acl_init(struct inode *, struct inode *);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f2c69a2..df7b23a 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -304,7 +304,6 @@ typedef unsigned char *sk_buff_data_t;
  *	@tc_index: Traffic control index
  *	@tc_verd: traffic control verdict
  *	@ndisc_nodetype: router type (from link layer)
- *	@do_not_encrypt: set to prevent encryption of this frame
  *	@dma_cookie: a cookie to one of several possible DMA operations
  *		done by skb DMA functions
  *	@secmark: security marking
@@ -380,12 +379,9 @@ struct sk_buff {
 #ifdef CONFIG_IPV6_NDISC_NODETYPE
 	__u8			ndisc_nodetype:2;
 #endif
-#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
-	__u8			do_not_encrypt:1;
-#endif
 	kmemcheck_bitfield_end(flags2);
 
-	/* 0/13/14 bit hole */
+	/* 0/14 bit hole */
 
 #ifdef CONFIG_NET_DMA
 	dma_cookie_t		dma_cookie;
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
index bb5368d..0ec00b3 100644
--- a/include/linux/slob_def.h
+++ b/include/linux/slob_def.h
@@ -34,9 +34,4 @@ static __always_inline void *__kmalloc(size_t size, gfp_t flags)
 	return kmalloc(size, flags);
 }
 
-static inline void kmem_cache_init_late(void)
-{
-	/* Nothing to do */
-}
-
 #endif /* __LINUX_SLOB_DEF_H */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index c1c862b..5ad70a6 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -153,12 +153,10 @@ static __always_inline int kmalloc_index(size_t size)
 	if (size <= KMALLOC_MIN_SIZE)
 		return KMALLOC_SHIFT_LOW;
 
-#if KMALLOC_MIN_SIZE <= 64
-	if (size > 64 && size <= 96)
+	if (KMALLOC_MIN_SIZE <= 32 && size > 64 && size <= 96)
 		return 1;
-	if (size > 128 && size <= 192)
+	if (KMALLOC_MIN_SIZE <= 64 && size > 128 && size <= 192)
 		return 2;
-#endif
 	if (size <=          8) return 3;
 	if (size <=         16) return 4;
 	if (size <=         32) return 5;
@@ -304,6 +302,4 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 }
 #endif
 
-void __init kmem_cache_init_late(void);
-
 #endif /* _LINUX_SLUB_DEF_H */
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index 5ae8fa2..3d0a9ff 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -27,24 +27,54 @@ struct ssb_sprom {
 	u8 et1mdcport;		/* MDIO for enet1 */
 	u8 board_rev;		/* Board revision number from SPROM. */
 	u8 country_code;	/* Country Code */
-	u8 ant_available_a;	/* A-PHY antenna available bits (up to 4) */
-	u8 ant_available_bg;	/* B/G-PHY antenna available bits (up to 4) */
+	u8 ant_available_a;	/* 2GHz antenna available bits (up to 4) */
+	u8 ant_available_bg;	/* 5GHz antenna available bits (up to 4) */
 	u16 pa0b0;
 	u16 pa0b1;
 	u16 pa0b2;
 	u16 pa1b0;
 	u16 pa1b1;
 	u16 pa1b2;
+	u16 pa1lob0;
+	u16 pa1lob1;
+	u16 pa1lob2;
+	u16 pa1hib0;
+	u16 pa1hib1;
+	u16 pa1hib2;
 	u8 gpio0;		/* GPIO pin 0 */
 	u8 gpio1;		/* GPIO pin 1 */
 	u8 gpio2;		/* GPIO pin 2 */
 	u8 gpio3;		/* GPIO pin 3 */
-	u16 maxpwr_a;		/* A-PHY Amplifier Max Power (in dBm Q5.2) */
-	u16 maxpwr_bg;		/* B/G-PHY Amplifier Max Power (in dBm Q5.2) */
+	u16 maxpwr_bg;		/* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
+	u16 maxpwr_al;		/* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
+	u16 maxpwr_a;		/* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
+	u16 maxpwr_ah;		/* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
 	u8 itssi_a;		/* Idle TSSI Target for A-PHY */
 	u8 itssi_bg;		/* Idle TSSI Target for B/G-PHY */
-	u16 boardflags_lo;	/* Boardflags (low 16 bits) */
-	u16 boardflags_hi;	/* Boardflags (high 16 bits) */
+	u8 tri2g;		/* 2.4GHz TX isolation */
+	u8 tri5gl;		/* 5.2GHz TX isolation */
+	u8 tri5g;		/* 5.3GHz TX isolation */
+	u8 tri5gh;		/* 5.8GHz TX isolation */
+	u8 rxpo2g;		/* 2GHz RX power offset */
+	u8 rxpo5g;		/* 5GHz RX power offset */
+	u8 rssisav2g;		/* 2GHz RSSI params */
+	u8 rssismc2g;
+	u8 rssismf2g;
+	u8 bxa2g;		/* 2GHz BX arch */
+	u8 rssisav5g;		/* 5GHz RSSI params */
+	u8 rssismc5g;
+	u8 rssismf5g;
+	u8 bxa5g;		/* 5GHz BX arch */
+	u16 cck2gpo;		/* CCK power offset */
+	u32 ofdm2gpo;		/* 2.4GHz OFDM power offset */
+	u32 ofdm5glpo;		/* 5.2GHz OFDM power offset */
+	u32 ofdm5gpo;		/* 5.3GHz OFDM power offset */
+	u32 ofdm5ghpo;		/* 5.8GHz OFDM power offset */
+	u16 boardflags_lo;	/* Board flags (bits 0-15) */
+	u16 boardflags_hi;	/* Board flags (bits 16-31) */
+	u16 boardflags2_lo;	/* Board flags (bits 32-47) */
+	u16 boardflags2_hi;	/* Board flags (bits 48-63) */
+	/* TODO store board flags in a single u64 */
 
 	/* Antenna gain values for up to 4 antennas
 	 * on each band. Values in dBm/4 (Q5.2). Negative gain means the
@@ -58,7 +88,7 @@ struct ssb_sprom {
 		} ghz5;		/* 5GHz band */
 	} antenna_gain;
 
-	/* TODO - add any parameters needed from rev 2, 3, or 4 SPROMs */
+	/* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
 };
 
 /* Information about the PCB the circuitry is soldered on. */
@@ -208,6 +238,7 @@ enum ssb_bustype {
 	SSB_BUSTYPE_SSB,	/* This SSB bus is the system bus */
 	SSB_BUSTYPE_PCI,	/* SSB is connected to PCI bus */
 	SSB_BUSTYPE_PCMCIA,	/* SSB is connected to PCMCIA bus */
+	SSB_BUSTYPE_SDIO,	/* SSB is connected to SDIO bus */
 };
 
 /* board_vendor */
@@ -240,8 +271,12 @@ struct ssb_bus {
 
 	/* The core in the basic address register window. (PCI bus only) */
 	struct ssb_device *mapped_device;
-	/* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
-	u8 mapped_pcmcia_seg;
+	union {
+		/* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
+		u8 mapped_pcmcia_seg;
+		/* Current SSB base address window for SDIO. */
+		u32 sdio_sbaddr;
+	};
 	/* Lock for core and segment switching.
 	 * On PCMCIA-host busses this is used to protect the whole MMIO access. */
 	spinlock_t bar_lock;
@@ -252,6 +287,11 @@ struct ssb_bus {
 	struct pci_dev *host_pci;
 	/* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
 	struct pcmcia_device *host_pcmcia;
+	/* Pointer to the SDIO device (only if bustype == SSB_BUSTYPE_SDIO). */
+	struct sdio_func *host_sdio;
+
+	/* See enum ssb_quirks */
+	unsigned int quirks;
 
 #ifdef CONFIG_SSB_SPROM
 	/* Mutex to protect the SPROM writing. */
@@ -306,6 +346,11 @@ struct ssb_bus {
 #endif /* DEBUG */
 };
 
+enum ssb_quirks {
+	/* SDIO connected card requires performing a read after writing a 32-bit value */
+	SSB_QUIRK_SDIO_READ_AFTER_WRITE32	= (1 << 0),
+};
+
 /* The initialization-invariants. */
 struct ssb_init_invariants {
 	/* Versioning information about the PCB. */
@@ -336,6 +381,12 @@ extern int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
 				      struct pcmcia_device *pcmcia_dev,
 				      unsigned long baseaddr);
 #endif /* CONFIG_SSB_PCMCIAHOST */
+#ifdef CONFIG_SSB_SDIOHOST
+extern int ssb_bus_sdiobus_register(struct ssb_bus *bus,
+				    struct sdio_func *sdio_func,
+				    unsigned int quirks);
+#endif /* CONFIG_SSB_SDIOHOST */
+
 
 extern void ssb_bus_unregister(struct ssb_bus *bus);
 
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index d3b1d18..4e27acf 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -629,5 +629,15 @@ extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
 /* PMU support */
 extern void ssb_pmu_init(struct ssb_chipcommon *cc);
 
+enum ssb_pmu_ldo_volt_id {
+	LDO_PAREF = 0,
+	LDO_VOLT1,
+	LDO_VOLT2,
+	LDO_VOLT3,
+};
+
+void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
+			     enum ssb_pmu_ldo_volt_id id, u32 voltage);
+void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
 
 #endif /* LINUX_SSB_CHIPCO_H_ */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
index a01b982..9ae9082 100644
--- a/include/linux/ssb/ssb_regs.h
+++ b/include/linux/ssb/ssb_regs.h
@@ -162,7 +162,7 @@
 
 /* SPROM shadow area. If not otherwise noted, fields are
  * two bytes wide. Note that the SPROM can _only_ be read
- * in two-byte quantinies.
+ * in two-byte quantities.
  */
 #define SSB_SPROMSIZE_WORDS		64
 #define SSB_SPROMSIZE_BYTES		(SSB_SPROMSIZE_WORDS * sizeof(u16))
@@ -327,8 +327,11 @@
 #define  SSB_SPROM5_GPIOB_P3_SHIFT	8
 
 /* SPROM Revision 8 */
-#define SSB_SPROM8_BFLLO		0x1084	/* Boardflags (low 16 bits) */
-#define SSB_SPROM8_BFLHI		0x1086	/* Boardflags Hi */
+#define SSB_SPROM8_BOARDREV		0x1082	/* Board revision */
+#define SSB_SPROM8_BFLLO		0x1084	/* Board flags (bits 0-15) */
+#define SSB_SPROM8_BFLHI		0x1086	/* Board flags (bits 16-31) */
+#define SSB_SPROM8_BFL2LO		0x1088	/* Board flags (bits 32-47) */
+#define SSB_SPROM8_BFL2HI		0x108A	/* Board flags (bits 48-63) */
 #define SSB_SPROM8_IL0MAC		0x108C	/* 6 byte MAC address */
 #define SSB_SPROM8_CCODE		0x1092	/* 2 byte country code */
 #define SSB_SPROM8_ANTAVAIL		0x109C  /* Antenna available bitfields*/
@@ -354,14 +357,63 @@
 #define  SSB_SPROM8_GPIOB_P2		0x00FF	/* Pin 2 */
 #define  SSB_SPROM8_GPIOB_P3		0xFF00	/* Pin 3 */
 #define  SSB_SPROM8_GPIOB_P3_SHIFT	8
-#define SSB_SPROM8_MAXP_BG		0x10C0  /* Max Power BG in path 1 */
-#define  SSB_SPROM8_MAXP_BG_MASK	0x00FF  /* Mask for Max Power BG */
+#define SSB_SPROM8_RSSIPARM2G		0x10A4	/* RSSI params for 2GHz */
+#define  SSB_SPROM8_RSSISMF2G		0x000F
+#define  SSB_SPROM8_RSSISMC2G		0x00F0
+#define  SSB_SPROM8_RSSISMC2G_SHIFT	4
+#define  SSB_SPROM8_RSSISAV2G		0x0700
+#define  SSB_SPROM8_RSSISAV2G_SHIFT	8
+#define  SSB_SPROM8_BXA2G		0x1800
+#define  SSB_SPROM8_BXA2G_SHIFT		11
+#define SSB_SPROM8_RSSIPARM5G		0x10A6	/* RSSI params for 5GHz */
+#define  SSB_SPROM8_RSSISMF5G		0x000F
+#define  SSB_SPROM8_RSSISMC5G		0x00F0
+#define  SSB_SPROM8_RSSISMC5G_SHIFT	4
+#define  SSB_SPROM8_RSSISAV5G		0x0700
+#define  SSB_SPROM8_RSSISAV5G_SHIFT	8
+#define  SSB_SPROM8_BXA5G		0x1800
+#define  SSB_SPROM8_BXA5G_SHIFT		11
+#define SSB_SPROM8_TRI25G		0x10A8	/* TX isolation 2.4&5.3GHz */
+#define  SSB_SPROM8_TRI2G		0x00FF	/* TX isolation 2.4GHz */
+#define  SSB_SPROM8_TRI5G		0xFF00	/* TX isolation 5.3GHz */
+#define  SSB_SPROM8_TRI5G_SHIFT		8
+#define SSB_SPROM8_TRI5GHL		0x10AA	/* TX isolation 5.2/5.8GHz */
+#define  SSB_SPROM8_TRI5GL		0x00FF	/* TX isolation 5.2GHz */
+#define  SSB_SPROM8_TRI5GH		0xFF00	/* TX isolation 5.8GHz */
+#define  SSB_SPROM8_TRI5GH_SHIFT	8
+#define SSB_SPROM8_RXPO			0x10AC  /* RX power offsets */
+#define  SSB_SPROM8_RXPO2G		0x00FF	/* 2GHz RX power offset */
+#define  SSB_SPROM8_RXPO5G		0xFF00	/* 5GHz RX power offset */
+#define  SSB_SPROM8_RXPO5G_SHIFT	8
+#define SSB_SPROM8_MAXP_BG		0x10C0  /* Max Power 2GHz in path 1 */
+#define  SSB_SPROM8_MAXP_BG_MASK	0x00FF  /* Mask for Max Power 2GHz */
 #define  SSB_SPROM8_ITSSI_BG		0xFF00	/* Mask for path 1 itssi_bg */
 #define  SSB_SPROM8_ITSSI_BG_SHIFT	8
-#define SSB_SPROM8_MAXP_A		0x10C8  /* Max Power A in path 1 */
-#define  SSB_SPROM8_MAXP_A_MASK		0x00FF  /* Mask for Max Power A */
+#define SSB_SPROM8_PA0B0		0x10C2	/* 2GHz power amp settings */
+#define SSB_SPROM8_PA0B1		0x10C4
+#define SSB_SPROM8_PA0B2		0x10C6
+#define SSB_SPROM8_MAXP_A		0x10C8  /* Max Power 5.3GHz */
+#define  SSB_SPROM8_MAXP_A_MASK		0x00FF  /* Mask for Max Power 5.3GHz */
 #define  SSB_SPROM8_ITSSI_A		0xFF00	/* Mask for path 1 itssi_a */
 #define  SSB_SPROM8_ITSSI_A_SHIFT	8
+#define SSB_SPROM8_MAXP_AHL		0x10CA  /* Max Power 5.2/5.8GHz */
+#define  SSB_SPROM8_MAXP_AH_MASK	0x00FF  /* Mask for Max Power 5.8GHz */
+#define  SSB_SPROM8_MAXP_AL_MASK	0xFF00  /* Mask for Max Power 5.2GHz */
+#define  SSB_SPROM8_MAXP_AL_SHIFT	8
+#define SSB_SPROM8_PA1B0		0x10CC	/* 5.3GHz power amp settings */
+#define SSB_SPROM8_PA1B1		0x10CE
+#define SSB_SPROM8_PA1B2		0x10D0
+#define SSB_SPROM8_PA1LOB0		0x10D2	/* 5.2GHz power amp settings */
+#define SSB_SPROM8_PA1LOB1		0x10D4
+#define SSB_SPROM8_PA1LOB2		0x10D6
+#define SSB_SPROM8_PA1HIB0		0x10D8	/* 5.8GHz power amp settings */
+#define SSB_SPROM8_PA1HIB1		0x10DA
+#define SSB_SPROM8_PA1HIB2		0x10DC
+#define SSB_SPROM8_CCK2GPO		0x1140	/* CCK power offset */
+#define SSB_SPROM8_OFDM2GPO		0x1142	/* 2.4GHz OFDM power offset */
+#define SSB_SPROM8_OFDM5GPO		0x1146	/* 5.3GHz OFDM power offset */
+#define SSB_SPROM8_OFDM5GLPO		0x114A	/* 5.2GHz OFDM power offset */
+#define SSB_SPROM8_OFDM5GHPO		0x114E	/* 5.8GHz OFDM power offset */
 
 /* Values for SSB_SPROM1_BINF_CCODE */
 enum {
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index a8e3782..8d8285a 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -55,7 +55,7 @@ struct compat_timeval;
 struct robust_list_head;
 struct getcpu_cache;
 struct old_linux_dirent;
-struct perf_counter_attr;
+struct perf_event_attr;
 
 #include <linux/types.h>
 #include <linux/aio_abi.h>
@@ -100,33 +100,25 @@ struct perf_counter_attr;
 
 #ifdef CONFIG_EVENT_PROFILE
 #define TRACE_SYS_ENTER_PROFILE(sname)					       \
-static int prof_sysenter_enable_##sname(struct ftrace_event_call *event_call)  \
+static int prof_sysenter_enable_##sname(void)				       \
 {									       \
-	int ret = 0;							       \
-	if (!atomic_inc_return(&event_enter_##sname.profile_count))	       \
-		ret = reg_prof_syscall_enter("sys"#sname);		       \
-	return ret;							       \
+	return reg_prof_syscall_enter("sys"#sname);			       \
 }									       \
 									       \
-static void prof_sysenter_disable_##sname(struct ftrace_event_call *event_call)\
+static void prof_sysenter_disable_##sname(void)				       \
 {									       \
-	if (atomic_add_negative(-1, &event_enter_##sname.profile_count))       \
-		unreg_prof_syscall_enter("sys"#sname);			       \
+	unreg_prof_syscall_enter("sys"#sname);				       \
 }
 
 #define TRACE_SYS_EXIT_PROFILE(sname)					       \
-static int prof_sysexit_enable_##sname(struct ftrace_event_call *event_call)   \
+static int prof_sysexit_enable_##sname(void)				       \
 {									       \
-	int ret = 0;							       \
-	if (!atomic_inc_return(&event_exit_##sname.profile_count))	       \
-		ret = reg_prof_syscall_exit("sys"#sname);		       \
-	return ret;							       \
+	return reg_prof_syscall_exit("sys"#sname);			       \
 }									       \
 									       \
-static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \
+static void prof_sysexit_disable_##sname(void)				       \
 {                                                                              \
-	if (atomic_add_negative(-1, &event_exit_##sname.profile_count))	       \
-		unreg_prof_syscall_exit("sys"#sname);			       \
+	unreg_prof_syscall_exit("sys"#sname);				       \
 }
 
 #define TRACE_SYS_ENTER_PROFILE_INIT(sname)				       \
@@ -885,7 +877,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int,
 int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
 
 
-asmlinkage long sys_perf_counter_open(
-		struct perf_counter_attr __user *attr_uptr,
+asmlinkage long sys_perf_event_open(
+		struct perf_event_attr __user *attr_uptr,
 		pid_t pid, int cpu, int group_fd, unsigned long flags);
 #endif
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
index 7e9680f..3398f45 100644
--- a/include/linux/taskstats_kern.h
+++ b/include/linux/taskstats_kern.h
@@ -9,7 +9,6 @@
 
 #include <linux/taskstats.h>
 #include <linux/sched.h>
-#include <net/genetlink.h>
 
 #ifdef CONFIG_TASKSTATS
 extern struct kmem_cache *taskstats_cache;
diff --git a/include/linux/tboot.h b/include/linux/tboot.h
new file mode 100644
index 0000000..bf2a0c7
--- /dev/null
+++ b/include/linux/tboot.h
@@ -0,0 +1,162 @@
+/*
+ * tboot.h: shared data structure with tboot and kernel and functions
+ *          used by kernel for runtime support of Intel(R) Trusted
+ *          Execution Technology
+ *
+ * Copyright (c) 2006-2009, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LINUX_TBOOT_H
+#define _LINUX_TBOOT_H
+
+/* these must have the values from 0-5 in this order */
+enum {
+	TB_SHUTDOWN_REBOOT = 0,
+	TB_SHUTDOWN_S5,
+	TB_SHUTDOWN_S4,
+	TB_SHUTDOWN_S3,
+	TB_SHUTDOWN_HALT,
+	TB_SHUTDOWN_WFS
+};
+
+#ifdef CONFIG_INTEL_TXT
+#include <acpi/acpi.h>
+/* used to communicate between tboot and the launched kernel */
+
+#define TB_KEY_SIZE             64   /* 512 bits */
+
+#define MAX_TB_MAC_REGIONS      32
+
+struct tboot_mac_region {
+	u64  start;         /* must be 64 byte -aligned */
+	u32  size;          /* must be 64 byte -granular */
+} __packed;
+
+/* GAS - Generic Address Structure (ACPI 2.0+) */
+struct tboot_acpi_generic_address {
+	u8  space_id;
+	u8  bit_width;
+	u8  bit_offset;
+	u8  access_width;
+	u64 address;
+} __packed;
+
+/*
+ * combines Sx info from FADT and FACS tables per ACPI 2.0+ spec
+ * (http://www.acpi.info/)
+ */
+struct tboot_acpi_sleep_info {
+	struct tboot_acpi_generic_address pm1a_cnt_blk;
+	struct tboot_acpi_generic_address pm1b_cnt_blk;
+	struct tboot_acpi_generic_address pm1a_evt_blk;
+	struct tboot_acpi_generic_address pm1b_evt_blk;
+	u16 pm1a_cnt_val;
+	u16 pm1b_cnt_val;
+	u64 wakeup_vector;
+	u32 vector_width;
+	u64 kernel_s3_resume_vector;
+} __packed;
+
+/*
+ * shared memory page used for communication between tboot and kernel
+ */
+struct tboot {
+	/*
+	 * version 3+ fields:
+	 */
+
+	/* TBOOT_UUID */
+	u8 uuid[16];
+
+	/* version number: 5 is current */
+	u32 version;
+
+	/* physical addr of tb_log_t log */
+	u32 log_addr;
+
+	/*
+	 * physical addr of entry point for tboot shutdown and
+	 * type of shutdown (TB_SHUTDOWN_*) being requested
+	 */
+	u32 shutdown_entry;
+	u32 shutdown_type;
+
+	/* kernel-specified ACPI info for Sx shutdown */
+	struct tboot_acpi_sleep_info acpi_sinfo;
+
+	/* tboot location in memory (physical) */
+	u32 tboot_base;
+	u32 tboot_size;
+
+	/* memory regions (phys addrs) for tboot to MAC on S3 */
+	u8 num_mac_regions;
+	struct tboot_mac_region mac_regions[MAX_TB_MAC_REGIONS];
+
+
+	/*
+	 * version 4+ fields:
+	 */
+
+	/* symmetric key for use by kernel; will be encrypted on S3 */
+	u8 s3_key[TB_KEY_SIZE];
+
+
+	/*
+	 * version 5+ fields:
+	 */
+
+	/* used to 4byte-align num_in_wfs */
+	u8 reserved_align[3];
+
+	/* number of processors in wait-for-SIPI */
+	u32 num_in_wfs;
+} __packed;
+
+/*
+ * UUID for tboot data struct to facilitate matching
+ * defined as {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} by tboot, which is
+ * represented as {} in the char array used here
+ */
+#define TBOOT_UUID	{0xff, 0x8d, 0x3c, 0x66, 0xb3, 0xe8, 0x82, 0x4b, 0xbf,\
+			 0xaa, 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8}
+
+extern struct tboot *tboot;
+
+static inline int tboot_enabled(void)
+{
+	return tboot != NULL;
+}
+
+extern void tboot_probe(void);
+extern void tboot_shutdown(u32 shutdown_type);
+extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control);
+extern struct acpi_table_header *tboot_get_dmar_table(
+				      struct acpi_table_header *dmar_tbl);
+extern int tboot_force_iommu(void);
+
+#else
+
+#define tboot_probe()			do { } while (0)
+#define tboot_shutdown(shutdown_type)	do { } while (0)
+#define tboot_sleep(sleep_state, pm1a_control, pm1b_control)	\
+					do { } while (0)
+#define tboot_get_dmar_table(dmar_tbl)	(dmar_tbl)
+#define tboot_force_iommu()		0
+
+#endif /* !CONFIG_INTEL_TXT */
+
+#endif /* _LINUX_TBOOT_H */
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 8afac76..61723a7 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -233,7 +233,7 @@ struct tcp_request_sock {
 	struct inet_request_sock 	req;
 #ifdef CONFIG_TCP_MD5SIG
 	/* Only used by TCP MD5 Signature so far. */
-	struct tcp_request_sock_ops	*af_specific;
+	const struct tcp_request_sock_ops *af_specific;
 #endif
 	u32			 	rcv_isn;
 	u32			 	snt_isn;
@@ -401,9 +401,9 @@ struct tcp_sock {
 
 #ifdef CONFIG_TCP_MD5SIG
 /* TCP AF-Specific parts; only used by MD5 Signature support so far */
-	struct tcp_sock_af_ops	*af_specific;
+	const struct tcp_sock_af_ops	*af_specific;
 
-/* TCP MD5 Signagure Option information */
+/* TCP MD5 Signature Option information */
 	struct tcp_md5sig_info	*md5sig_info;
 #endif
 };
diff --git a/include/linux/time.h b/include/linux/time.h
index ea16c1a..56787c0 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -75,7 +75,7 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon,
 			    const unsigned int day, const unsigned int hour,
 			    const unsigned int min, const unsigned int sec);
 
-extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);
+extern void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec);
 extern struct timespec timespec_add_safe(const struct timespec lhs,
 					 const struct timespec rhs);
 
@@ -101,7 +101,8 @@ extern struct timespec xtime;
 extern struct timespec wall_to_monotonic;
 extern seqlock_t xtime_lock;
 
-extern unsigned long read_persistent_clock(void);
+extern void read_persistent_clock(struct timespec *ts);
+extern void read_boot_clock(struct timespec *ts);
 extern int update_persistent_clock(struct timespec now);
 extern int no_sync_cmos_clock __read_mostly;
 void timekeeping_init(void);
@@ -109,6 +110,8 @@ extern int timekeeping_suspended;
 
 unsigned long get_seconds(void);
 struct timespec current_kernel_time(void);
+struct timespec __current_kernel_time(void); /* does not hold xtime_lock */
+struct timespec get_monotonic_coarse(void);
 
 #define CURRENT_TIME		(current_kernel_time())
 #define CURRENT_TIME_SEC	((struct timespec) { get_seconds(), 0 })
@@ -147,6 +150,7 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 extern int timekeeping_valid_for_hres(void);
 extern void update_wall_time(void);
 extern void update_xtime_cache(u64 nsec);
+extern void timekeeping_leap_insert(int leapsecond);
 
 struct tms;
 extern void do_sys_times(struct tms *);
@@ -241,6 +245,8 @@ struct itimerval {
 #define CLOCK_PROCESS_CPUTIME_ID	2
 #define CLOCK_THREAD_CPUTIME_ID		3
 #define CLOCK_MONOTONIC_RAW		4
+#define CLOCK_REALTIME_COARSE		5
+#define CLOCK_MONOTONIC_COARSE		6
 
 /*
  * The IDs of various hardware clocks:
diff --git a/include/linux/timer.h b/include/linux/timer.h
index be62ec2..a2d1eb6 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -175,11 +175,6 @@ extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
 
 /*
  * Return when the next timer-wheel timeout occurs (in absolute jiffies),
- * locks the timer base:
- */
-extern unsigned long next_timer_interrupt(void);
-/*
- * Return when the next timer-wheel timeout occurs (in absolute jiffies),
  * locks the timer base and does the comparison against the given
  * jiffie.
  */
diff --git a/include/linux/tipc.h b/include/linux/tipc.h
index bea4694..3d92396 100644
--- a/include/linux/tipc.h
+++ b/include/linux/tipc.h
@@ -209,5 +209,7 @@ struct sockaddr_tipc {
 #define TIPC_SRC_DROPPABLE	128	/* Default: 0 (resend congested msg) */
 #define TIPC_DEST_DROPPABLE	129	/* Default: based on socket type */
 #define TIPC_CONN_TIMEOUT	130	/* Default: 8000 (ms)  */
+#define TIPC_NODE_RECVQ_DEPTH	131	/* Default: none (read only) */
+#define TIPC_SOCK_RECVQ_DEPTH	132	/* Default: none (read only) */
 
 #endif
diff --git a/include/linux/topology.h b/include/linux/topology.h
index 85e8cf7..809b26c 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -95,14 +95,12 @@ int arch_update_cpu_topology(void);
 				| 1*SD_BALANCE_NEWIDLE			\
 				| 1*SD_BALANCE_EXEC			\
 				| 1*SD_BALANCE_FORK			\
-				| 0*SD_WAKE_IDLE			\
+				| 0*SD_BALANCE_WAKE			\
 				| 1*SD_WAKE_AFFINE			\
-				| 1*SD_WAKE_BALANCE			\
 				| 1*SD_SHARE_CPUPOWER			\
 				| 0*SD_POWERSAVINGS_BALANCE		\
 				| 0*SD_SHARE_PKG_RESOURCES		\
 				| 0*SD_SERIALIZE			\
-				| 0*SD_WAKE_IDLE_FAR			\
 				| 0*SD_PREFER_SIBLING			\
 				,					\
 	.last_balance		= jiffies,				\
@@ -122,20 +120,19 @@ int arch_update_cpu_topology(void);
 	.imbalance_pct		= 125,					\
 	.cache_nice_tries	= 1,					\
 	.busy_idx		= 2,					\
-	.wake_idx		= 1,					\
-	.forkexec_idx		= 1,					\
+	.wake_idx		= 0,					\
+	.forkexec_idx		= 0,					\
 									\
 	.flags			= 1*SD_LOAD_BALANCE			\
 				| 1*SD_BALANCE_NEWIDLE			\
 				| 1*SD_BALANCE_EXEC			\
 				| 1*SD_BALANCE_FORK			\
-				| 1*SD_WAKE_IDLE			\
+				| 0*SD_BALANCE_WAKE			\
 				| 1*SD_WAKE_AFFINE			\
-				| 1*SD_WAKE_BALANCE			\
+				| 1*SD_PREFER_LOCAL			\
 				| 0*SD_SHARE_CPUPOWER			\
 				| 1*SD_SHARE_PKG_RESOURCES		\
 				| 0*SD_SERIALIZE			\
-				| 0*SD_WAKE_IDLE_FAR			\
 				| sd_balance_for_mc_power()		\
 				| sd_power_saving_flags()		\
 				,					\
@@ -155,21 +152,20 @@ int arch_update_cpu_topology(void);
 	.cache_nice_tries	= 1,					\
 	.busy_idx		= 2,					\
 	.idle_idx		= 1,					\
-	.newidle_idx		= 2,					\
-	.wake_idx		= 1,					\
-	.forkexec_idx		= 1,					\
+	.newidle_idx		= 0,					\
+	.wake_idx		= 0,					\
+	.forkexec_idx		= 0,					\
 									\
 	.flags			= 1*SD_LOAD_BALANCE			\
 				| 1*SD_BALANCE_NEWIDLE			\
 				| 1*SD_BALANCE_EXEC			\
 				| 1*SD_BALANCE_FORK			\
-				| 1*SD_WAKE_IDLE			\
-				| 0*SD_WAKE_AFFINE			\
-				| 1*SD_WAKE_BALANCE			\
+				| 0*SD_BALANCE_WAKE			\
+				| 1*SD_WAKE_AFFINE			\
+				| 1*SD_PREFER_LOCAL			\
 				| 0*SD_SHARE_CPUPOWER			\
 				| 0*SD_SHARE_PKG_RESOURCES		\
 				| 0*SD_SERIALIZE			\
-				| 0*SD_WAKE_IDLE_FAR			\
 				| sd_balance_for_package_power()	\
 				| sd_power_saving_flags()		\
 				,					\
@@ -191,14 +187,12 @@ int arch_update_cpu_topology(void);
 				| 1*SD_BALANCE_NEWIDLE			\
 				| 0*SD_BALANCE_EXEC			\
 				| 0*SD_BALANCE_FORK			\
-				| 0*SD_WAKE_IDLE			\
-				| 1*SD_WAKE_AFFINE			\
-				| 0*SD_WAKE_BALANCE			\
+				| 0*SD_BALANCE_WAKE			\
+				| 0*SD_WAKE_AFFINE			\
 				| 0*SD_SHARE_CPUPOWER			\
 				| 0*SD_POWERSAVINGS_BALANCE		\
 				| 0*SD_SHARE_PKG_RESOURCES		\
 				| 1*SD_SERIALIZE			\
-				| 1*SD_WAKE_IDLE_FAR			\
 				| 0*SD_PREFER_SIBLING			\
 				,					\
 	.last_balance		= jiffies,				\
diff --git a/include/linux/transport_class.h b/include/linux/transport_class.h
index eaec1ea..9ae8da3 100644
--- a/include/linux/transport_class.h
+++ b/include/linux/transport_class.h
@@ -55,7 +55,7 @@ struct anon_transport_class cls = {				\
 
 struct transport_container {
 	struct attribute_container ac;
-	struct attribute_group *statistics;
+	const struct attribute_group *statistics;
 };
 
 #define attribute_container_to_transport_container(x) \
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 0d3974f..f0f43d0 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -187,7 +187,12 @@ struct tty_port;
 struct tty_port_operations {
 	/* Return 1 if the carrier is raised */
 	int (*carrier_raised)(struct tty_port *port);
+	/* Control the DTR line */
 	void (*dtr_rts)(struct tty_port *port, int raise);
+	/* Called when the last close completes or a hangup finishes
+	   IFF the port was initialized. Do not use to free resources */
+	void (*shutdown)(struct tty_port *port);
+	void (*drop)(struct tty_port *port);
 };
 	
 struct tty_port {
@@ -198,11 +203,12 @@ struct tty_port {
 	int			count;		/* Usage count */
 	wait_queue_head_t	open_wait;	/* Open waiters */
 	wait_queue_head_t	close_wait;	/* Close waiters */
+	wait_queue_head_t	delta_msr_wait;	/* Modem status change */
 	unsigned long		flags;		/* TTY flags ASY_*/
 	struct mutex		mutex;		/* Locking */
 	unsigned char		*xmit_buf;	/* Optional buffer */
-	int			close_delay;	/* Close port delay */
-	int			closing_wait;	/* Delay for output */
+	unsigned int		close_delay;	/* Close port delay */
+	unsigned int		closing_wait;	/* Delay for output */
 	int			drain_delay;	/* Set to zero if no pure time
 						   based drain is needed else
 						   set to size of fifo */
@@ -459,6 +465,12 @@ extern int tty_port_block_til_ready(struct tty_port *port,
 extern int tty_port_close_start(struct tty_port *port,
 				struct tty_struct *tty, struct file *filp);
 extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
+extern void tty_port_close(struct tty_port *port,
+				struct tty_struct *tty, struct file *filp);
+extern inline int tty_port_users(struct tty_port *port)
+{
+	return port->count + port->blocked_open;
+}
 
 extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
 extern int tty_unregister_ldisc(int disc);
@@ -519,14 +531,13 @@ extern void serial_console_init(void);
 
 extern int pcxe_open(struct tty_struct *tty, struct file *filp);
 
-/* printk.c */
-
-extern void console_print(const char *);
-
 /* vt.c */
 
 extern int vt_ioctl(struct tty_struct *tty, struct file *file,
 		    unsigned int cmd, unsigned long arg);
 
+extern long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
+		     unsigned int cmd, unsigned long arg);
+
 #endif /* __KERNEL__ */
 #endif
diff --git a/include/linux/usb.h b/include/linux/usb.h
index b1e3c2f..a8fe05f 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -922,7 +922,7 @@ extern struct bus_type usb_bus_type;
 /**
  * struct usb_class_driver - identifies a USB driver that wants to use the USB major number
  * @name: the usb class device name for this driver.  Will show up in sysfs.
- * @nodename: Callback to provide a naming hint for a possible
+ * @devnode: Callback to provide a naming hint for a possible
  *	device node to create.
  * @fops: pointer to the struct file_operations of this driver.
  * @minor_base: the start of the minor range for this driver.
@@ -933,7 +933,7 @@ extern struct bus_type usb_bus_type;
  */
 struct usb_class_driver {
 	char *name;
-	char *(*nodename)(struct device *dev);
+	char *(*devnode)(struct device *dev, mode_t *mode);
 	const struct file_operations *fops;
 	int minor_base;
 };
diff --git a/include/linux/usb/m66592.h b/include/linux/usb/m66592.h
new file mode 100644
index 0000000..cda9625
--- /dev/null
+++ b/include/linux/usb/m66592.h
@@ -0,0 +1,44 @@
+/*
+ * M66592 driver platform data
+ *
+ * Copyright (C) 2009  Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __LINUX_USB_M66592_H
+#define __LINUX_USB_M66592_H
+
+#define M66592_PLATDATA_XTAL_12MHZ	0x01
+#define M66592_PLATDATA_XTAL_24MHZ	0x02
+#define M66592_PLATDATA_XTAL_48MHZ	0x03
+
+struct m66592_platdata {
+	/* one = on chip controller, zero = external controller */
+	unsigned	on_chip:1;
+
+	/* one = big endian, zero = little endian */
+	unsigned	endian:1;
+
+	/* (external controller only) M66592_PLATDATA_XTAL_nnMHZ */
+	unsigned	xtal:2;
+
+	/* (external controller only) one = 3.3V, zero = 1.5V */
+	unsigned	vif:1;
+
+};
+
+#endif /* __LINUX_USB_M66592_H */
+
diff --git a/include/linux/usb/r8a66597.h b/include/linux/usb/r8a66597.h
index e9f0384..26d2167 100644
--- a/include/linux/usb/r8a66597.h
+++ b/include/linux/usb/r8a66597.h
@@ -28,9 +28,12 @@
 #define R8A66597_PLATDATA_XTAL_48MHZ	0x03
 
 struct r8a66597_platdata {
-	/* This ops can controll port power instead of DVSTCTR register. */
+	/* This callback can control port power instead of DVSTCTR register. */
 	void (*port_power)(int port, int power);
 
+	/* set one = on chip controller, set zero = external controller */
+	unsigned	on_chip:1;
+
 	/* (external controller only) set R8A66597_PLATDATA_XTAL_nnMHZ */
 	unsigned	xtal:2;
 
@@ -40,5 +43,373 @@ struct r8a66597_platdata {
 	/* set one = big endian, set zero = little endian */
 	unsigned	endian:1;
 };
-#endif
+
+/* Register definitions */
+#define SYSCFG0		0x00
+#define SYSCFG1		0x02
+#define SYSSTS0		0x04
+#define SYSSTS1		0x06
+#define DVSTCTR0	0x08
+#define DVSTCTR1	0x0A
+#define TESTMODE	0x0C
+#define PINCFG		0x0E
+#define DMA0CFG		0x10
+#define DMA1CFG		0x12
+#define CFIFO		0x14
+#define D0FIFO		0x18
+#define D1FIFO		0x1C
+#define CFIFOSEL	0x20
+#define CFIFOCTR	0x22
+#define CFIFOSIE	0x24
+#define D0FIFOSEL	0x28
+#define D0FIFOCTR	0x2A
+#define D1FIFOSEL	0x2C
+#define D1FIFOCTR	0x2E
+#define INTENB0		0x30
+#define INTENB1		0x32
+#define INTENB2		0x34
+#define BRDYENB		0x36
+#define NRDYENB		0x38
+#define BEMPENB		0x3A
+#define SOFCFG		0x3C
+#define INTSTS0		0x40
+#define INTSTS1		0x42
+#define INTSTS2		0x44
+#define BRDYSTS		0x46
+#define NRDYSTS		0x48
+#define BEMPSTS		0x4A
+#define FRMNUM		0x4C
+#define UFRMNUM		0x4E
+#define USBADDR		0x50
+#define USBREQ		0x54
+#define USBVAL		0x56
+#define USBINDX		0x58
+#define USBLENG		0x5A
+#define DCPCFG		0x5C
+#define DCPMAXP		0x5E
+#define DCPCTR		0x60
+#define PIPESEL		0x64
+#define PIPECFG		0x68
+#define PIPEBUF		0x6A
+#define PIPEMAXP	0x6C
+#define PIPEPERI	0x6E
+#define PIPE1CTR	0x70
+#define PIPE2CTR	0x72
+#define PIPE3CTR	0x74
+#define PIPE4CTR	0x76
+#define PIPE5CTR	0x78
+#define PIPE6CTR	0x7A
+#define PIPE7CTR	0x7C
+#define PIPE8CTR	0x7E
+#define PIPE9CTR	0x80
+#define PIPE1TRE	0x90
+#define PIPE1TRN	0x92
+#define PIPE2TRE	0x94
+#define PIPE2TRN	0x96
+#define PIPE3TRE	0x98
+#define PIPE3TRN	0x9A
+#define PIPE4TRE	0x9C
+#define	PIPE4TRN	0x9E
+#define	PIPE5TRE	0xA0
+#define	PIPE5TRN	0xA2
+#define DEVADD0		0xD0
+#define DEVADD1		0xD2
+#define DEVADD2		0xD4
+#define DEVADD3		0xD6
+#define DEVADD4		0xD8
+#define DEVADD5		0xDA
+#define DEVADD6		0xDC
+#define DEVADD7		0xDE
+#define DEVADD8		0xE0
+#define DEVADD9		0xE2
+#define DEVADDA		0xE4
+
+/* System Configuration Control Register */
+#define	XTAL		0xC000	/* b15-14: Crystal selection */
+#define	  XTAL48	 0x8000	  /* 48MHz */
+#define	  XTAL24	 0x4000	  /* 24MHz */
+#define	  XTAL12	 0x0000	  /* 12MHz */
+#define	XCKE		0x2000	/* b13: External clock enable */
+#define	PLLC		0x0800	/* b11: PLL control */
+#define	SCKE		0x0400	/* b10: USB clock enable */
+#define	PCSDIS		0x0200	/* b9: not CS wakeup */
+#define	LPSME		0x0100	/* b8: Low power sleep mode */
+#define	HSE		0x0080	/* b7: Hi-speed enable */
+#define	DCFM		0x0040	/* b6: Controller function select  */
+#define	DRPD		0x0020	/* b5: D+/- pull down control */
+#define	DPRPU		0x0010	/* b4: D+ pull up control */
+#define	USBE		0x0001	/* b0: USB module operation enable */
+
+/* System Configuration Status Register */
+#define	OVCBIT		0x8000	/* b15-14: Over-current bit */
+#define	OVCMON		0xC000	/* b15-14: Over-current monitor */
+#define	SOFEA		0x0020	/* b5: SOF monitor */
+#define	IDMON		0x0004	/* b3: ID-pin monitor */
+#define	LNST		0x0003	/* b1-0: D+, D- line status */
+#define	  SE1		 0x0003	  /* SE1 */
+#define	  FS_KSTS	 0x0002	  /* Full-Speed K State */
+#define	  FS_JSTS	 0x0001	  /* Full-Speed J State */
+#define	  LS_JSTS	 0x0002	  /* Low-Speed J State */
+#define	  LS_KSTS	 0x0001	  /* Low-Speed K State */
+#define	  SE0		 0x0000	  /* SE0 */
+
+/* Device State Control Register */
+#define	EXTLP0		0x0400	/* b10: External port */
+#define	VBOUT		0x0200	/* b9: VBUS output */
+#define	WKUP		0x0100	/* b8: Remote wakeup */
+#define	RWUPE		0x0080	/* b7: Remote wakeup sense */
+#define	USBRST		0x0040	/* b6: USB reset enable */
+#define	RESUME		0x0020	/* b5: Resume enable */
+#define	UACT		0x0010	/* b4: USB bus enable */
+#define	RHST		0x0007	/* b1-0: Reset handshake status */
+#define	  HSPROC	 0x0004	  /* HS handshake is processing */
+#define	  HSMODE	 0x0003	  /* Hi-Speed mode */
+#define	  FSMODE	 0x0002	  /* Full-Speed mode */
+#define	  LSMODE	 0x0001	  /* Low-Speed mode */
+#define	  UNDECID	 0x0000	  /* Undecided */
+
+/* Test Mode Register */
+#define	UTST			0x000F	/* b3-0: Test select */
+#define	  H_TST_PACKET		 0x000C	  /* HOST TEST Packet */
+#define	  H_TST_SE0_NAK		 0x000B	  /* HOST TEST SE0 NAK */
+#define	  H_TST_K		 0x000A	  /* HOST TEST K */
+#define	  H_TST_J		 0x0009	  /* HOST TEST J */
+#define	  H_TST_NORMAL		 0x0000	  /* HOST Normal Mode */
+#define	  P_TST_PACKET		 0x0004	  /* PERI TEST Packet */
+#define	  P_TST_SE0_NAK		 0x0003	  /* PERI TEST SE0 NAK */
+#define	  P_TST_K		 0x0002	  /* PERI TEST K */
+#define	  P_TST_J		 0x0001	  /* PERI TEST J */
+#define	  P_TST_NORMAL		 0x0000	  /* PERI Normal Mode */
+
+/* Data Pin Configuration Register */
+#define	LDRV			0x8000	/* b15: Drive Current Adjust */
+#define	  VIF1			  0x0000		/* VIF = 1.8V */
+#define	  VIF3			  0x8000		/* VIF = 3.3V */
+#define	INTA			0x0001	/* b1: USB INT-pin active */
+
+/* DMAx Pin Configuration Register */
+#define	DREQA			0x4000	/* b14: Dreq active select */
+#define	BURST			0x2000	/* b13: Burst mode */
+#define	DACKA			0x0400	/* b10: Dack active select */
+#define	DFORM			0x0380	/* b9-7: DMA mode select */
+#define	  CPU_ADR_RD_WR		 0x0000	  /* Address + RD/WR mode (CPU bus) */
+#define	  CPU_DACK_RD_WR	 0x0100	  /* DACK + RD/WR mode (CPU bus) */
+#define	  CPU_DACK_ONLY		 0x0180	  /* DACK only mode (CPU bus) */
+#define	  SPLIT_DACK_ONLY	 0x0200	  /* DACK only mode (SPLIT bus) */
+#define	DENDA			0x0040	/* b6: Dend active select */
+#define	PKTM			0x0020	/* b5: Packet mode */
+#define	DENDE			0x0010	/* b4: Dend enable */
+#define	OBUS			0x0004	/* b2: OUTbus mode */
+
+/* CFIFO/DxFIFO Port Select Register */
+#define	RCNT		0x8000	/* b15: Read count mode */
+#define	REW		0x4000	/* b14: Buffer rewind */
+#define	DCLRM		0x2000	/* b13: DMA buffer clear mode */
+#define	DREQE		0x1000	/* b12: DREQ output enable */
+#define	  MBW_8		 0x0000	  /*  8bit */
+#define	  MBW_16	 0x0400	  /* 16bit */
+#define	  MBW_32	 0x0800   /* 32bit */
+#define	BIGEND		0x0100	/* b8: Big endian mode */
+#define	  BYTE_LITTLE	 0x0000		/* little dendian */
+#define	  BYTE_BIG	 0x0100		/* big endifan */
+#define	ISEL		0x0020	/* b5: DCP FIFO port direction select */
+#define	CURPIPE		0x000F	/* b2-0: PIPE select */
+
+/* CFIFO/DxFIFO Port Control Register */
+#define	BVAL		0x8000	/* b15: Buffer valid flag */
+#define	BCLR		0x4000	/* b14: Buffer clear */
+#define	FRDY		0x2000	/* b13: FIFO ready */
+#define	DTLN		0x0FFF	/* b11-0: FIFO received data length */
+
+/* Interrupt Enable Register 0 */
+#define	VBSE	0x8000	/* b15: VBUS interrupt */
+#define	RSME	0x4000	/* b14: Resume interrupt */
+#define	SOFE	0x2000	/* b13: Frame update interrupt */
+#define	DVSE	0x1000	/* b12: Device state transition interrupt */
+#define	CTRE	0x0800	/* b11: Control transfer stage transition interrupt */
+#define	BEMPE	0x0400	/* b10: Buffer empty interrupt */
+#define	NRDYE	0x0200	/* b9: Buffer not ready interrupt */
+#define	BRDYE	0x0100	/* b8: Buffer ready interrupt */
+
+/* Interrupt Enable Register 1 */
+#define	OVRCRE		0x8000	/* b15: Over-current interrupt */
+#define	BCHGE		0x4000	/* b14: USB us chenge interrupt */
+#define	DTCHE		0x1000	/* b12: Detach sense interrupt */
+#define	ATTCHE		0x0800	/* b11: Attach sense interrupt */
+#define	EOFERRE		0x0040	/* b6: EOF error interrupt */
+#define	SIGNE		0x0020	/* b5: SETUP IGNORE interrupt */
+#define	SACKE		0x0010	/* b4: SETUP ACK interrupt */
+
+/* BRDY Interrupt Enable/Status Register */
+#define	BRDY9		0x0200	/* b9: PIPE9 */
+#define	BRDY8		0x0100	/* b8: PIPE8 */
+#define	BRDY7		0x0080	/* b7: PIPE7 */
+#define	BRDY6		0x0040	/* b6: PIPE6 */
+#define	BRDY5		0x0020	/* b5: PIPE5 */
+#define	BRDY4		0x0010	/* b4: PIPE4 */
+#define	BRDY3		0x0008	/* b3: PIPE3 */
+#define	BRDY2		0x0004	/* b2: PIPE2 */
+#define	BRDY1		0x0002	/* b1: PIPE1 */
+#define	BRDY0		0x0001	/* b1: PIPE0 */
+
+/* NRDY Interrupt Enable/Status Register */
+#define	NRDY9		0x0200	/* b9: PIPE9 */
+#define	NRDY8		0x0100	/* b8: PIPE8 */
+#define	NRDY7		0x0080	/* b7: PIPE7 */
+#define	NRDY6		0x0040	/* b6: PIPE6 */
+#define	NRDY5		0x0020	/* b5: PIPE5 */
+#define	NRDY4		0x0010	/* b4: PIPE4 */
+#define	NRDY3		0x0008	/* b3: PIPE3 */
+#define	NRDY2		0x0004	/* b2: PIPE2 */
+#define	NRDY1		0x0002	/* b1: PIPE1 */
+#define	NRDY0		0x0001	/* b1: PIPE0 */
+
+/* BEMP Interrupt Enable/Status Register */
+#define	BEMP9		0x0200	/* b9: PIPE9 */
+#define	BEMP8		0x0100	/* b8: PIPE8 */
+#define	BEMP7		0x0080	/* b7: PIPE7 */
+#define	BEMP6		0x0040	/* b6: PIPE6 */
+#define	BEMP5		0x0020	/* b5: PIPE5 */
+#define	BEMP4		0x0010	/* b4: PIPE4 */
+#define	BEMP3		0x0008	/* b3: PIPE3 */
+#define	BEMP2		0x0004	/* b2: PIPE2 */
+#define	BEMP1		0x0002	/* b1: PIPE1 */
+#define	BEMP0		0x0001	/* b0: PIPE0 */
+
+/* SOF Pin Configuration Register */
+#define	TRNENSEL	0x0100	/* b8: Select transaction enable period */
+#define	BRDYM		0x0040	/* b6: BRDY clear timing */
+#define	INTL		0x0020	/* b5: Interrupt sense select */
+#define	EDGESTS		0x0010	/* b4:  */
+#define	SOFMODE		0x000C	/* b3-2: SOF pin select */
+#define	  SOF_125US	 0x0008	  /* SOF OUT 125us Frame Signal */
+#define	  SOF_1MS	 0x0004	  /* SOF OUT 1ms Frame Signal */
+#define	  SOF_DISABLE	 0x0000	  /* SOF OUT Disable */
+
+/* Interrupt Status Register 0 */
+#define	VBINT	0x8000	/* b15: VBUS interrupt */
+#define	RESM	0x4000	/* b14: Resume interrupt */
+#define	SOFR	0x2000	/* b13: SOF frame update interrupt */
+#define	DVST	0x1000	/* b12: Device state transition interrupt */
+#define	CTRT	0x0800	/* b11: Control transfer stage transition interrupt */
+#define	BEMP	0x0400	/* b10: Buffer empty interrupt */
+#define	NRDY	0x0200	/* b9: Buffer not ready interrupt */
+#define	BRDY	0x0100	/* b8: Buffer ready interrupt */
+#define	VBSTS	0x0080	/* b7: VBUS input port */
+#define	DVSQ	0x0070	/* b6-4: Device state */
+#define	  DS_SPD_CNFG	 0x0070	  /* Suspend Configured */
+#define	  DS_SPD_ADDR	 0x0060	  /* Suspend Address */
+#define	  DS_SPD_DFLT	 0x0050	  /* Suspend Default */
+#define	  DS_SPD_POWR	 0x0040	  /* Suspend Powered */
+#define	  DS_SUSP	 0x0040	  /* Suspend */
+#define	  DS_CNFG	 0x0030	  /* Configured */
+#define	  DS_ADDS	 0x0020	  /* Address */
+#define	  DS_DFLT	 0x0010	  /* Default */
+#define	  DS_POWR	 0x0000	  /* Powered */
+#define	DVSQS		0x0030	/* b5-4: Device state */
+#define	VALID		0x0008	/* b3: Setup packet detected flag */
+#define	CTSQ		0x0007	/* b2-0: Control transfer stage */
+#define	  CS_SQER	 0x0006	  /* Sequence error */
+#define	  CS_WRND	 0x0005	  /* Control write nodata status stage */
+#define	  CS_WRSS	 0x0004	  /* Control write status stage */
+#define	  CS_WRDS	 0x0003	  /* Control write data stage */
+#define	  CS_RDSS	 0x0002	  /* Control read status stage */
+#define	  CS_RDDS	 0x0001	  /* Control read data stage */
+#define	  CS_IDST	 0x0000	  /* Idle or setup stage */
+
+/* Interrupt Status Register 1 */
+#define	OVRCR		0x8000	/* b15: Over-current interrupt */
+#define	BCHG		0x4000	/* b14: USB bus chenge interrupt */
+#define	DTCH		0x1000	/* b12: Detach sense interrupt */
+#define	ATTCH		0x0800	/* b11: Attach sense interrupt */
+#define	EOFERR		0x0040	/* b6: EOF-error interrupt */
+#define	SIGN		0x0020	/* b5: Setup ignore interrupt */
+#define	SACK		0x0010	/* b4: Setup acknowledge interrupt */
+
+/* Frame Number Register */
+#define	OVRN		0x8000	/* b15: Overrun error */
+#define	CRCE		0x4000	/* b14: Received data error */
+#define	FRNM		0x07FF	/* b10-0: Frame number */
+
+/* Micro Frame Number Register */
+#define	UFRNM		0x0007	/* b2-0: Micro frame number */
+
+/* Default Control Pipe Maxpacket Size Register */
+/* Pipe Maxpacket Size Register */
+#define	DEVSEL	0xF000	/* b15-14: Device address select */
+#define	MAXP	0x007F	/* b6-0: Maxpacket size of default control pipe */
+
+/* Default Control Pipe Control Register */
+#define	BSTS		0x8000	/* b15: Buffer status */
+#define	SUREQ		0x4000	/* b14: Send USB request  */
+#define	CSCLR		0x2000	/* b13: complete-split status clear */
+#define	CSSTS		0x1000	/* b12: complete-split status */
+#define	SUREQCLR	0x0800	/* b11: stop setup request */
+#define	SQCLR		0x0100	/* b8: Sequence toggle bit clear */
+#define	SQSET		0x0080	/* b7: Sequence toggle bit set */
+#define	SQMON		0x0040	/* b6: Sequence toggle bit monitor */
+#define	PBUSY		0x0020	/* b5: pipe busy */
+#define	PINGE		0x0010	/* b4: ping enable */
+#define	CCPL		0x0004	/* b2: Enable control transfer complete */
+#define	PID		0x0003	/* b1-0: Response PID */
+#define	  PID_STALL11	 0x0003	  /* STALL */
+#define	  PID_STALL	 0x0002	  /* STALL */
+#define	  PID_BUF	 0x0001	  /* BUF */
+#define	  PID_NAK	 0x0000	  /* NAK */
+
+/* Pipe Window Select Register */
+#define	PIPENM		0x0007	/* b2-0: Pipe select */
+
+/* Pipe Configuration Register */
+#define	R8A66597_TYP	0xC000	/* b15-14: Transfer type */
+#define	  R8A66597_ISO	 0xC000		  /* Isochronous */
+#define	  R8A66597_INT	 0x8000		  /* Interrupt */
+#define	  R8A66597_BULK	 0x4000		  /* Bulk */
+#define	R8A66597_BFRE	0x0400	/* b10: Buffer ready interrupt mode select */
+#define	R8A66597_DBLB	0x0200	/* b9: Double buffer mode select */
+#define	R8A66597_CNTMD	0x0100	/* b8: Continuous transfer mode select */
+#define	R8A66597_SHTNAK	0x0080	/* b7: Transfer end NAK */
+#define	R8A66597_DIR	0x0010	/* b4: Transfer direction select */
+#define	R8A66597_EPNUM	0x000F	/* b3-0: Eendpoint number select */
+
+/* Pipe Buffer Configuration Register */
+#define	BUFSIZE		0x7C00	/* b14-10: Pipe buffer size */
+#define	BUFNMB		0x007F	/* b6-0: Pipe buffer number */
+#define	PIPE0BUF	256
+#define	PIPExBUF	64
+
+/* Pipe Maxpacket Size Register */
+#define	MXPS		0x07FF	/* b10-0: Maxpacket size */
+
+/* Pipe Cycle Configuration Register */
+#define	IFIS	0x1000	/* b12: Isochronous in-buffer flush mode select */
+#define	IITV	0x0007	/* b2-0: Isochronous interval */
+
+/* Pipex Control Register */
+#define	BSTS	0x8000	/* b15: Buffer status */
+#define	INBUFM	0x4000	/* b14: IN buffer monitor (Only for PIPE1 to 5) */
+#define	CSCLR	0x2000	/* b13: complete-split status clear */
+#define	CSSTS	0x1000	/* b12: complete-split status */
+#define	ATREPM	0x0400	/* b10: Auto repeat mode */
+#define	ACLRM	0x0200	/* b9: Out buffer auto clear mode */
+#define	SQCLR	0x0100	/* b8: Sequence toggle bit clear */
+#define	SQSET	0x0080	/* b7: Sequence toggle bit set */
+#define	SQMON	0x0040	/* b6: Sequence toggle bit monitor */
+#define	PBUSY	0x0020	/* b5: pipe busy */
+#define	PID	0x0003	/* b1-0: Response PID */
+
+/* PIPExTRE */
+#define	TRENB		0x0200	/* b9: Transaction counter enable */
+#define	TRCLR		0x0100	/* b8: Transaction counter clear */
+
+/* PIPExTRN */
+#define	TRNCNT		0xFFFF	/* b15-0: Transaction counter */
+
+/* DEVADDx */
+#define	UPPHUB		0x7800
+#define	HUBPORT		0x0700
+#define	USBSPD		0x00C0
+#define	RTPORT		0x0001
+
+#endif /* __LINUX_USB_R8A66597_H */
 
diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h
index 37836b9..1ef1ebc 100644
--- a/include/linux/usb/rndis_host.h
+++ b/include/linux/usb/rndis_host.h
@@ -70,12 +70,13 @@ struct rndis_msg_hdr {
 #define RNDIS_MSG_KEEPALIVE_C	(RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
 
 /* codes for "status" field of completion messages */
-#define	RNDIS_STATUS_SUCCESS		cpu_to_le32(0x00000000)
-#define	RNDIS_STATUS_FAILURE		cpu_to_le32(0xc0000001)
-#define	RNDIS_STATUS_INVALID_DATA	cpu_to_le32(0xc0010015)
-#define	RNDIS_STATUS_NOT_SUPPORTED	cpu_to_le32(0xc00000bb)
-#define	RNDIS_STATUS_MEDIA_CONNECT	cpu_to_le32(0x4001000b)
-#define	RNDIS_STATUS_MEDIA_DISCONNECT	cpu_to_le32(0x4001000c)
+#define	RNDIS_STATUS_SUCCESS			cpu_to_le32(0x00000000)
+#define	RNDIS_STATUS_FAILURE			cpu_to_le32(0xc0000001)
+#define	RNDIS_STATUS_INVALID_DATA		cpu_to_le32(0xc0010015)
+#define	RNDIS_STATUS_NOT_SUPPORTED		cpu_to_le32(0xc00000bb)
+#define	RNDIS_STATUS_MEDIA_CONNECT		cpu_to_le32(0x4001000b)
+#define	RNDIS_STATUS_MEDIA_DISCONNECT		cpu_to_le32(0x4001000c)
+#define	RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION	cpu_to_le32(0x40010012)
 
 /* codes for OID_GEN_PHYSICAL_MEDIUM */
 #define	RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED	cpu_to_le32(0x00000000)
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 0ec50ba..7b85e32 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -238,9 +238,8 @@ struct usb_serial_driver {
 	int (*resume)(struct usb_serial *serial);
 
 	/* serial function calls */
-	/* Called by console with tty = NULL and by tty */
-	int  (*open)(struct tty_struct *tty,
-			struct usb_serial_port *port, struct file *filp);
+	/* Called by console and by the tty layer */
+	int  (*open)(struct tty_struct *tty, struct usb_serial_port *port);
 	void (*close)(struct usb_serial_port *port);
 	int  (*write)(struct tty_struct *tty, struct usb_serial_port *port,
 			const unsigned char *buf, int count);
@@ -261,6 +260,9 @@ struct usb_serial_driver {
 	   be an attached tty at this point */
 	void (*dtr_rts)(struct usb_serial_port *port, int on);
 	int  (*carrier_raised)(struct usb_serial_port *port);
+	/* Called by the usb serial hooks to allow the user to rework the
+	   termios state */
+	void (*init_termios)(struct tty_struct *tty);
 	/* USB events */
 	void (*read_int_callback)(struct urb *urb);
 	void (*write_int_callback)(struct urb *urb);
@@ -300,7 +302,7 @@ static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
 extern struct usb_serial *usb_serial_get_by_index(unsigned int minor);
 extern void usb_serial_put(struct usb_serial *serial);
 extern int usb_serial_generic_open(struct tty_struct *tty,
-		struct usb_serial_port *port, struct file *filp);
+	struct usb_serial_port *port);
 extern int usb_serial_generic_write(struct tty_struct *tty,
 	struct usb_serial_port *port, const unsigned char *buf, int count);
 extern void usb_serial_generic_close(struct usb_serial_port *port);
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 310e18a..bb69e25 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -53,6 +53,7 @@ struct usbnet {
 	struct sk_buff_head	rxq;
 	struct sk_buff_head	txq;
 	struct sk_buff_head	done;
+	struct sk_buff_head	rxq_pause;
 	struct urb		*interrupt;
 	struct tasklet_struct	bh;
 
@@ -63,6 +64,7 @@ struct usbnet {
 #		define EVENT_RX_MEMORY	2
 #		define EVENT_STS_SPLIT	3
 #		define EVENT_LINK_RESET	4
+#		define EVENT_RX_PAUSED	5
 };
 
 static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -86,6 +88,7 @@ struct driver_info {
 
 #define FLAG_FRAMING_AX 0x0040		/* AX88772/178 packets */
 #define FLAG_WLAN	0x0080		/* use "wlan%d" names */
+#define FLAG_AVOID_UNLINK_URBS 0x0100	/* don't unlink urbs at usbnet_stop() */
 
 
 	/* init device ... can sleep, or cause probe() failure */
@@ -97,6 +100,9 @@ struct driver_info {
 	/* reset device ... can sleep */
 	int	(*reset)(struct usbnet *);
 
+	/* stop device ... can sleep */
+	int	(*stop)(struct usbnet *);
+
 	/* see if peer is connected ... can sleep */
 	int	(*check_connect)(struct usbnet *);
 
@@ -118,9 +124,8 @@ struct driver_info {
 	 * right after minidriver have initialized hardware. */
 	int	(*early_init)(struct usbnet *dev);
 
-	/* called by minidriver when link state changes, state: 0=disconnect,
-	 * 1=connect */
-	void	(*link_change)(struct usbnet *dev, int state);
+	/* called by minidriver when receiving indication */
+	void	(*indication)(struct usbnet *dev, void *ind, int indlen);
 
 	/* for new devices, use the descriptor-reading code instead */
 	int		in;		/* rx endpoint */
@@ -177,7 +182,8 @@ struct skb_data {	/* skb->cb is one of these */
 
 extern int usbnet_open (struct net_device *net);
 extern int usbnet_stop (struct net_device *net);
-extern int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net);
+extern netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
+				      struct net_device *net);
 extern void usbnet_tx_timeout (struct net_device *net);
 extern int usbnet_change_mtu (struct net_device *net, int new_mtu);
 
@@ -187,6 +193,10 @@ extern void usbnet_defer_kevent (struct usbnet *, int);
 extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
 extern void usbnet_unlink_rx_urbs(struct usbnet *);
 
+extern void usbnet_pause_rx(struct usbnet *);
+extern void usbnet_resume_rx(struct usbnet *);
+extern void usbnet_purge_paused_rxq(struct usbnet *);
+
 extern int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd);
 extern int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd);
 extern u32 usbnet_get_link (struct net_device *net);
diff --git a/include/linux/usb/video.h b/include/linux/usb/video.h
new file mode 100644
index 0000000..be436d9
--- /dev/null
+++ b/include/linux/usb/video.h
@@ -0,0 +1,164 @@
+/*
+ * USB Video Class definitions.
+ *
+ * Copyright (C) 2009 Laurent Pinchart <laurent.pinchart@skynet.be>
+ *
+ * This file holds USB constants and structures defined by the USB Device
+ * Class Definition for Video Devices. Unless otherwise stated, comments
+ * below reference relevant sections of the USB Video Class 1.1 specification
+ * available at
+ *
+ * http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_1.zip
+ */
+
+#ifndef __LINUX_USB_VIDEO_H
+#define __LINUX_USB_VIDEO_H
+
+#include <linux/types.h>
+
+/* --------------------------------------------------------------------------
+ * UVC constants
+ */
+
+/* A.2. Video Interface Subclass Codes */
+#define UVC_SC_UNDEFINED				0x00
+#define UVC_SC_VIDEOCONTROL				0x01
+#define UVC_SC_VIDEOSTREAMING				0x02
+#define UVC_SC_VIDEO_INTERFACE_COLLECTION		0x03
+
+/* A.3. Video Interface Protocol Codes */
+#define UVC_PC_PROTOCOL_UNDEFINED			0x00
+
+/* A.5. Video Class-Specific VC Interface Descriptor Subtypes */
+#define UVC_VC_DESCRIPTOR_UNDEFINED			0x00
+#define UVC_VC_HEADER					0x01
+#define UVC_VC_INPUT_TERMINAL				0x02
+#define UVC_VC_OUTPUT_TERMINAL				0x03
+#define UVC_VC_SELECTOR_UNIT				0x04
+#define UVC_VC_PROCESSING_UNIT				0x05
+#define UVC_VC_EXTENSION_UNIT				0x06
+
+/* A.6. Video Class-Specific VS Interface Descriptor Subtypes */
+#define UVC_VS_UNDEFINED				0x00
+#define UVC_VS_INPUT_HEADER				0x01
+#define UVC_VS_OUTPUT_HEADER				0x02
+#define UVC_VS_STILL_IMAGE_FRAME			0x03
+#define UVC_VS_FORMAT_UNCOMPRESSED			0x04
+#define UVC_VS_FRAME_UNCOMPRESSED			0x05
+#define UVC_VS_FORMAT_MJPEG				0x06
+#define UVC_VS_FRAME_MJPEG				0x07
+#define UVC_VS_FORMAT_MPEG2TS				0x0a
+#define UVC_VS_FORMAT_DV				0x0c
+#define UVC_VS_COLORFORMAT				0x0d
+#define UVC_VS_FORMAT_FRAME_BASED			0x10
+#define UVC_VS_FRAME_FRAME_BASED			0x11
+#define UVC_VS_FORMAT_STREAM_BASED			0x12
+
+/* A.7. Video Class-Specific Endpoint Descriptor Subtypes */
+#define UVC_EP_UNDEFINED				0x00
+#define UVC_EP_GENERAL					0x01
+#define UVC_EP_ENDPOINT					0x02
+#define UVC_EP_INTERRUPT				0x03
+
+/* A.8. Video Class-Specific Request Codes */
+#define UVC_RC_UNDEFINED				0x00
+#define UVC_SET_CUR					0x01
+#define UVC_GET_CUR					0x81
+#define UVC_GET_MIN					0x82
+#define UVC_GET_MAX					0x83
+#define UVC_GET_RES					0x84
+#define UVC_GET_LEN					0x85
+#define UVC_GET_INFO					0x86
+#define UVC_GET_DEF					0x87
+
+/* A.9.1. VideoControl Interface Control Selectors */
+#define UVC_VC_CONTROL_UNDEFINED			0x00
+#define UVC_VC_VIDEO_POWER_MODE_CONTROL			0x01
+#define UVC_VC_REQUEST_ERROR_CODE_CONTROL		0x02
+
+/* A.9.2. Terminal Control Selectors */
+#define UVC_TE_CONTROL_UNDEFINED			0x00
+
+/* A.9.3. Selector Unit Control Selectors */
+#define UVC_SU_CONTROL_UNDEFINED			0x00
+#define UVC_SU_INPUT_SELECT_CONTROL			0x01
+
+/* A.9.4. Camera Terminal Control Selectors */
+#define UVC_CT_CONTROL_UNDEFINED			0x00
+#define UVC_CT_SCANNING_MODE_CONTROL			0x01
+#define UVC_CT_AE_MODE_CONTROL				0x02
+#define UVC_CT_AE_PRIORITY_CONTROL			0x03
+#define UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL		0x04
+#define UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL		0x05
+#define UVC_CT_FOCUS_ABSOLUTE_CONTROL			0x06
+#define UVC_CT_FOCUS_RELATIVE_CONTROL			0x07
+#define UVC_CT_FOCUS_AUTO_CONTROL			0x08
+#define UVC_CT_IRIS_ABSOLUTE_CONTROL			0x09
+#define UVC_CT_IRIS_RELATIVE_CONTROL			0x0a
+#define UVC_CT_ZOOM_ABSOLUTE_CONTROL			0x0b
+#define UVC_CT_ZOOM_RELATIVE_CONTROL			0x0c
+#define UVC_CT_PANTILT_ABSOLUTE_CONTROL			0x0d
+#define UVC_CT_PANTILT_RELATIVE_CONTROL			0x0e
+#define UVC_CT_ROLL_ABSOLUTE_CONTROL			0x0f
+#define UVC_CT_ROLL_RELATIVE_CONTROL			0x10
+#define UVC_CT_PRIVACY_CONTROL				0x11
+
+/* A.9.5. Processing Unit Control Selectors */
+#define UVC_PU_CONTROL_UNDEFINED			0x00
+#define UVC_PU_BACKLIGHT_COMPENSATION_CONTROL		0x01
+#define UVC_PU_BRIGHTNESS_CONTROL			0x02
+#define UVC_PU_CONTRAST_CONTROL				0x03
+#define UVC_PU_GAIN_CONTROL				0x04
+#define UVC_PU_POWER_LINE_FREQUENCY_CONTROL		0x05
+#define UVC_PU_HUE_CONTROL				0x06
+#define UVC_PU_SATURATION_CONTROL			0x07
+#define UVC_PU_SHARPNESS_CONTROL			0x08
+#define UVC_PU_GAMMA_CONTROL				0x09
+#define UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL	0x0a
+#define UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL	0x0b
+#define UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL		0x0c
+#define UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL	0x0d
+#define UVC_PU_DIGITAL_MULTIPLIER_CONTROL		0x0e
+#define UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL		0x0f
+#define UVC_PU_HUE_AUTO_CONTROL				0x10
+#define UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL		0x11
+#define UVC_PU_ANALOG_LOCK_STATUS_CONTROL		0x12
+
+/* A.9.7. VideoStreaming Interface Control Selectors */
+#define UVC_VS_CONTROL_UNDEFINED			0x00
+#define UVC_VS_PROBE_CONTROL				0x01
+#define UVC_VS_COMMIT_CONTROL				0x02
+#define UVC_VS_STILL_PROBE_CONTROL			0x03
+#define UVC_VS_STILL_COMMIT_CONTROL			0x04
+#define UVC_VS_STILL_IMAGE_TRIGGER_CONTROL		0x05
+#define UVC_VS_STREAM_ERROR_CODE_CONTROL		0x06
+#define UVC_VS_GENERATE_KEY_FRAME_CONTROL		0x07
+#define UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL		0x08
+#define UVC_VS_SYNC_DELAY_CONTROL			0x09
+
+/* B.1. USB Terminal Types */
+#define UVC_TT_VENDOR_SPECIFIC				0x0100
+#define UVC_TT_STREAMING				0x0101
+
+/* B.2. Input Terminal Types */
+#define UVC_ITT_VENDOR_SPECIFIC				0x0200
+#define UVC_ITT_CAMERA					0x0201
+#define UVC_ITT_MEDIA_TRANSPORT_INPUT			0x0202
+
+/* B.3. Output Terminal Types */
+#define UVC_OTT_VENDOR_SPECIFIC				0x0300
+#define UVC_OTT_DISPLAY					0x0301
+#define UVC_OTT_MEDIA_TRANSPORT_OUTPUT			0x0302
+
+/* B.4. External Terminal Types */
+#define UVC_EXTERNAL_VENDOR_SPECIFIC			0x0400
+#define UVC_COMPOSITE_CONNECTOR				0x0401
+#define UVC_SVIDEO_CONNECTOR				0x0402
+#define UVC_COMPONENT_CONNECTOR				0x0403
+
+/* 2.4.2.2. Status Packet Type */
+#define UVC_STATUS_TYPE_CONTROL				1
+#define UVC_STATUS_TYPE_STREAMING			2
+
+#endif /* __LINUX_USB_VIDEO_H */
+
diff --git a/include/linux/uwb.h b/include/linux/uwb.h
index c021289..7fc9746 100644
--- a/include/linux/uwb.h
+++ b/include/linux/uwb.h
@@ -597,7 +597,7 @@ void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t);
 void uwb_rc_neh_error(struct uwb_rc *, int);
 void uwb_rc_reset_all(struct uwb_rc *rc);
 void uwb_rc_pre_reset(struct uwb_rc *rc);
-void uwb_rc_post_reset(struct uwb_rc *rc);
+int uwb_rc_post_reset(struct uwb_rc *rc);
 
 /**
  * uwb_rsv_is_owner - is the owner of this reservation the RC?
diff --git a/include/linux/vgaarb.h b/include/linux/vgaarb.h
new file mode 100644
index 0000000..e81c64a
--- /dev/null
+++ b/include/linux/vgaarb.h
@@ -0,0 +1,200 @@
+/*
+ * vgaarb.c
+ *
+ * (C) Copyright 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * (C) Copyright 2007 Paulo R. Zanoni <przanoni@gmail.com>
+ * (C) Copyright 2007, 2009 Tiago Vignatti <vignatti@freedesktop.org>
+ */
+
+#ifndef LINUX_VGA_H
+
+#include <asm/vga.h>
+
+/* Legacy VGA regions */
+#define VGA_RSRC_NONE	       0x00
+#define VGA_RSRC_LEGACY_IO     0x01
+#define VGA_RSRC_LEGACY_MEM    0x02
+#define VGA_RSRC_LEGACY_MASK   (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)
+/* Non-legacy access */
+#define VGA_RSRC_NORMAL_IO     0x04
+#define VGA_RSRC_NORMAL_MEM    0x08
+
+/* Passing that instead of a pci_dev to use the system "default"
+ * device, that is the one used by vgacon. Archs will probably
+ * have to provide their own vga_default_device();
+ */
+#define VGA_DEFAULT_DEVICE     (NULL)
+
+/* For use by clients */
+
+/**
+ *     vga_set_legacy_decoding
+ *
+ *     @pdev: pci device of the VGA card
+ *     @decodes: bit mask of what legacy regions the card decodes
+ *
+ *     Indicates to the arbiter if the card decodes legacy VGA IOs,
+ *     legacy VGA Memory, both, or none. All cards default to both,
+ *     the card driver (fbdev for example) should tell the arbiter
+ *     if it has disabled legacy decoding, so the card can be left
+ *     out of the arbitration process (and can be safe to take
+ *     interrupts at any time.
+ */
+extern void vga_set_legacy_decoding(struct pci_dev *pdev,
+									unsigned int decodes);
+
+/**
+ *     vga_get         - acquire & locks VGA resources
+ *
+ *     @pdev: pci device of the VGA card or NULL for the system default
+ *     @rsrc: bit mask of resources to acquire and lock
+ *     @interruptible: blocking should be interruptible by signals ?
+ *
+ *     This function acquires VGA resources for the given
+ *     card and mark those resources locked. If the resource requested
+ *     are "normal" (and not legacy) resources, the arbiter will first check
+ *     wether the card is doing legacy decoding for that type of resource. If
+ *     yes, the lock is "converted" into a legacy resource lock.
+ *     The arbiter will first look for all VGA cards that might conflict
+ *     and disable their IOs and/or Memory access, inlcuding VGA forwarding
+ *     on P2P bridges if necessary, so that the requested resources can
+ *     be used. Then, the card is marked as locking these resources and
+ *     the IO and/or Memory accesse are enabled on the card (including
+ *     VGA forwarding on parent P2P bridges if any).
+ *     This function will block if some conflicting card is already locking
+ *     one of the required resources (or any resource on a different bus
+ *     segment, since P2P bridges don't differenciate VGA memory and IO
+ *     afaik). You can indicate wether this blocking should be interruptible
+ *     by a signal (for userland interface) or not.
+ *     Must not be called at interrupt time or in atomic context.
+ *     If the card already owns the resources, the function succeeds.
+ *     Nested calls are supported (a per-resource counter is maintained)
+ */
+
+extern int vga_get(struct pci_dev *pdev, unsigned int rsrc,
+											int interruptible);
+
+/**
+ *     vga_get_interruptible
+ *
+ *     Shortcut to vga_get
+ */
+
+static inline int vga_get_interruptible(struct pci_dev *pdev,
+					unsigned int rsrc)
+{
+       return vga_get(pdev, rsrc, 1);
+}
+
+/**
+ *     vga_get_uninterruptible
+ *
+ *     Shortcut to vga_get
+ */
+
+static inline int vga_get_uninterruptible(struct pci_dev *pdev,
+					  unsigned int rsrc)
+{
+       return vga_get(pdev, rsrc, 0);
+}
+
+/**
+ *     vga_tryget      - try to acquire & lock legacy VGA resources
+ *
+ *     @pdev: pci devivce of VGA card or NULL for system default
+ *     @rsrc: bit mask of resources to acquire and lock
+ *
+ *     This function performs the same operation as vga_get(), but
+ *     will return an error (-EBUSY) instead of blocking if the resources
+ *     are already locked by another card. It can be called in any context
+ */
+
+extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc);
+
+/**
+ *     vga_put         - release lock on legacy VGA resources
+ *
+ *     @pdev: pci device of VGA card or NULL for system default
+ *     @rsrc: but mask of resource to release
+ *
+ *     This function releases resources previously locked by vga_get()
+ *     or vga_tryget(). The resources aren't disabled right away, so
+ *     that a subsequence vga_get() on the same card will succeed
+ *     immediately. Resources have a counter, so locks are only
+ *     released if the counter reaches 0.
+ */
+
+extern void vga_put(struct pci_dev *pdev, unsigned int rsrc);
+
+
+/**
+ *     vga_default_device
+ *
+ *     This can be defined by the platform. The default implementation
+ *     is rather dumb and will probably only work properly on single
+ *     vga card setups and/or x86 platforms.
+ *
+ *     If your VGA default device is not PCI, you'll have to return
+ *     NULL here. In this case, I assume it will not conflict with
+ *     any PCI card. If this is not true, I'll have to define two archs
+ *     hooks for enabling/disabling the VGA default device if that is
+ *     possible. This may be a problem with real _ISA_ VGA cards, in
+ *     addition to a PCI one. I don't know at this point how to deal
+ *     with that card. Can theirs IOs be disabled at all ? If not, then
+ *     I suppose it's a matter of having the proper arch hook telling
+ *     us about it, so we basically never allow anybody to succeed a
+ *     vga_get()...
+ */
+
+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE
+extern struct pci_dev *vga_default_device(void);
+#endif
+
+/**
+ *     vga_conflicts
+ *
+ *     Architectures should define this if they have several
+ *     independant PCI domains that can afford concurrent VGA
+ *     decoding
+ */
+
+#ifndef __ARCH_HAS_VGA_CONFLICT
+static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2)
+{
+       return 1;
+}
+#endif
+
+/**
+ *	vga_client_register
+ *
+ *	@pdev: pci device of the VGA client
+ *	@cookie: client cookie to be used in callbacks
+ *	@irq_set_state: irq state change callback
+ *	@set_vga_decode: vga decode change callback
+ *
+ * 	return value: 0 on success, -1 on failure
+ * 	Register a client with the VGA arbitration logic
+ *
+ *	Clients have two callback mechanisms they can use.
+ *	irq enable/disable callback -
+ *		If a client can't disable its GPUs VGA resources, then we
+ *		need to be able to ask it to turn off its irqs when we
+ *		turn off its mem and io decoding.
+ *	set_vga_decode
+ *		If a client can disable its GPU VGA resource, it will
+ *		get a callback from this to set the encode/decode state
+ *
+ * Rationale: we cannot disable VGA decode resources unconditionally
+ * some single GPU laptops seem to require ACPI or BIOS access to the
+ * VGA registers to control things like backlights etc.
+ * Hopefully newer multi-GPU laptops do something saner, and desktops
+ * won't have any special ACPI for this.
+ * They driver will get a callback when VGA arbitration is first used
+ * by userspace since we some older X servers have issues.
+ */
+int vga_client_register(struct pci_dev *pdev, void *cookie,
+			void (*irq_set_state)(void *cookie, bool state),
+			unsigned int (*set_vga_decode)(void *cookie, bool state));
+
+#endif /* LINUX_VGA_H */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 74f1687..b59e78c 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -167,6 +167,7 @@ enum v4l2_ctrl_type {
 	V4L2_CTRL_TYPE_BUTTON	     = 4,
 	V4L2_CTRL_TYPE_INTEGER64     = 5,
 	V4L2_CTRL_TYPE_CTRL_CLASS    = 6,
+	V4L2_CTRL_TYPE_STRING        = 7,
 };
 
 enum v4l2_tuner_type {
@@ -252,10 +253,12 @@ struct v4l2_capability {
 #define V4L2_CAP_RDS_CAPTURE		0x00000100  /* RDS data capture */
 #define V4L2_CAP_VIDEO_OUTPUT_OVERLAY	0x00000200  /* Can do video output overlay */
 #define V4L2_CAP_HW_FREQ_SEEK		0x00000400  /* Can do hardware frequency seek  */
+#define V4L2_CAP_RDS_OUTPUT		0x00000800  /* Is an RDS encoder */
 
 #define V4L2_CAP_TUNER			0x00010000  /* has a tuner */
 #define V4L2_CAP_AUDIO			0x00020000  /* has audio support */
 #define V4L2_CAP_RADIO			0x00040000  /* is a radio device */
+#define V4L2_CAP_MODULATOR		0x00080000  /* has a modulator */
 
 #define V4L2_CAP_READWRITE              0x01000000  /* read/write systemcalls */
 #define V4L2_CAP_ASYNCIO                0x02000000  /* async I/O */
@@ -275,7 +278,9 @@ struct v4l2_pix_format {
 	__u32			priv;		/* private data, depends on pixelformat */
 };
 
-/*      Pixel format         FOURCC                        depth  Description  */
+/*      Pixel format         FOURCC                          depth  Description  */
+
+/* RGB formats */
 #define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R', 'G', 'B', '1') /*  8  RGB-3-3-2     */
 #define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R', '4', '4', '4') /* 16  xxxxrrrr ggggbbbb */
 #define V4L2_PIX_FMT_RGB555  v4l2_fourcc('R', 'G', 'B', 'O') /* 16  RGB-5-5-5     */
@@ -286,12 +291,20 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_RGB24   v4l2_fourcc('R', 'G', 'B', '3') /* 24  RGB-8-8-8     */
 #define V4L2_PIX_FMT_BGR32   v4l2_fourcc('B', 'G', 'R', '4') /* 32  BGR-8-8-8-8   */
 #define V4L2_PIX_FMT_RGB32   v4l2_fourcc('R', 'G', 'B', '4') /* 32  RGB-8-8-8-8   */
+
+/* Grey formats */
 #define V4L2_PIX_FMT_GREY    v4l2_fourcc('G', 'R', 'E', 'Y') /*  8  Greyscale     */
 #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale     */
+
+/* Palette formats */
 #define V4L2_PIX_FMT_PAL8    v4l2_fourcc('P', 'A', 'L', '8') /*  8  8-bit palette */
+
+/* Luminance+Chrominance formats */
 #define V4L2_PIX_FMT_YVU410  v4l2_fourcc('Y', 'V', 'U', '9') /*  9  YVU 4:1:0     */
 #define V4L2_PIX_FMT_YVU420  v4l2_fourcc('Y', 'V', '1', '2') /* 12  YVU 4:2:0     */
 #define V4L2_PIX_FMT_YUYV    v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YVYU    v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
 #define V4L2_PIX_FMT_UYVY    v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16  YUV 4:2:2     */
 #define V4L2_PIX_FMT_VYUY    v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16  YUV 4:2:2     */
 #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16  YVU422 planar */
@@ -301,6 +314,10 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_YUV555  v4l2_fourcc('Y', 'U', 'V', 'O') /* 16  YUV-5-5-5     */
 #define V4L2_PIX_FMT_YUV565  v4l2_fourcc('Y', 'U', 'V', 'P') /* 16  YUV-5-6-5     */
 #define V4L2_PIX_FMT_YUV32   v4l2_fourcc('Y', 'U', 'V', '4') /* 32  YUV-8-8-8-8   */
+#define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y', 'U', 'V', '9') /*  9  YUV 4:1:0     */
+#define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y', 'U', '1', '2') /* 12  YUV 4:2:0     */
+#define V4L2_PIX_FMT_HI240   v4l2_fourcc('H', 'I', '2', '4') /*  8  8-bit color   */
+#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H', 'M', '1', '2') /*  8  YUV 4:2:0 16x16 macroblocks */
 
 /* two planes -- one Y, one Cr + Cb interleaved  */
 #define V4L2_PIX_FMT_NV12    v4l2_fourcc('N', 'V', '1', '2') /* 12  Y/CbCr 4:2:0  */
@@ -308,25 +325,17 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_NV16    v4l2_fourcc('N', 'V', '1', '6') /* 16  Y/CbCr 4:2:2  */
 #define V4L2_PIX_FMT_NV61    v4l2_fourcc('N', 'V', '6', '1') /* 16  Y/CrCb 4:2:2  */
 
-/*  The following formats are not defined in the V4L2 specification */
-#define V4L2_PIX_FMT_YUV410  v4l2_fourcc('Y', 'U', 'V', '9') /*  9  YUV 4:1:0     */
-#define V4L2_PIX_FMT_YUV420  v4l2_fourcc('Y', 'U', '1', '2') /* 12  YUV 4:2:0     */
-#define V4L2_PIX_FMT_YYUV    v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_HI240   v4l2_fourcc('H', 'I', '2', '4') /*  8  8-bit color   */
-#define V4L2_PIX_FMT_HM12    v4l2_fourcc('H', 'M', '1', '2') /*  8  YUV 4:2:0 16x16 macroblocks */
-
-/* see http://www.siliconimaging.com/RGB%20Bayer.htm */
+/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
 #define V4L2_PIX_FMT_SGBRG8  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */
 #define V4L2_PIX_FMT_SGRBG8  v4l2_fourcc('G', 'R', 'B', 'G') /*  8  GRGR.. BGBG.. */
-
-/*
- * 10bit raw bayer, expanded to 16 bits
- * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
- */
-#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0')
-/* 10bit raw bayer DPCM compressed to 8 bits */
+#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10bit raw bayer */
+	/* 10bit raw bayer DPCM compressed to 8 bits */
 #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
+	/*
+	 * 10bit raw bayer, expanded to 16 bits
+	 * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
+	 */
 #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16  BGBG.. GRGR.. */
 
 /* compressed formats */
@@ -350,7 +359,6 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
 #define V4L2_PIX_FMT_SQ905C   v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
 #define V4L2_PIX_FMT_PJPG     v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
-#define V4L2_PIX_FMT_YVYU     v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
 #define V4L2_PIX_FMT_OV511    v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
 #define V4L2_PIX_FMT_OV518    v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
 
@@ -367,6 +375,7 @@ struct v4l2_fmtdesc {
 };
 
 #define V4L2_FMT_FLAG_COMPRESSED 0x0001
+#define V4L2_FMT_FLAG_EMULATED   0x0002
 
 #if 1
 	/* Experimental Frame Size and frame rate enumeration */
@@ -788,11 +797,12 @@ struct v4l2_control {
 
 struct v4l2_ext_control {
 	__u32 id;
-	__u32 reserved2[2];
+	__u32 size;
+	__u32 reserved2[1];
 	union {
 		__s32 value;
 		__s64 value64;
-		void *reserved;
+		char *string;
 	};
 } __attribute__ ((packed));
 
@@ -808,6 +818,7 @@ struct v4l2_ext_controls {
 #define V4L2_CTRL_CLASS_USER 0x00980000	/* Old-style 'user' controls */
 #define V4L2_CTRL_CLASS_MPEG 0x00990000	/* MPEG-compression controls */
 #define V4L2_CTRL_CLASS_CAMERA 0x009a0000	/* Camera class controls */
+#define V4L2_CTRL_CLASS_FM_TX 0x009b0000	/* FM Modulator control class */
 
 #define V4L2_CTRL_ID_MASK      	  (0x0fffffff)
 #define V4L2_CTRL_ID2CLASS(id)    ((id) & 0x0fff0000UL)
@@ -899,9 +910,10 @@ enum v4l2_colorfx {
 	V4L2_COLORFX_SEPIA	= 2,
 };
 #define V4L2_CID_AUTOBRIGHTNESS			(V4L2_CID_BASE+32)
+#define V4L2_CID_BAND_STOP_FILTER		(V4L2_CID_BASE+33)
 
 /* last CID + 1 */
-#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+33)
+#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+34)
 
 /*  MPEG-class control IDs defined by V4L2 */
 #define V4L2_CID_MPEG_BASE 			(V4L2_CTRL_CLASS_MPEG | 0x900)
@@ -1147,6 +1159,39 @@ enum  v4l2_exposure_auto_type {
 
 #define V4L2_CID_PRIVACY			(V4L2_CID_CAMERA_CLASS_BASE+16)
 
+/* FM Modulator class control IDs */
+#define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
+#define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
+
+#define V4L2_CID_RDS_TX_DEVIATION		(V4L2_CID_FM_TX_CLASS_BASE + 1)
+#define V4L2_CID_RDS_TX_PI			(V4L2_CID_FM_TX_CLASS_BASE + 2)
+#define V4L2_CID_RDS_TX_PTY			(V4L2_CID_FM_TX_CLASS_BASE + 3)
+#define V4L2_CID_RDS_TX_PS_NAME			(V4L2_CID_FM_TX_CLASS_BASE + 5)
+#define V4L2_CID_RDS_TX_RADIO_TEXT		(V4L2_CID_FM_TX_CLASS_BASE + 6)
+
+#define V4L2_CID_AUDIO_LIMITER_ENABLED		(V4L2_CID_FM_TX_CLASS_BASE + 64)
+#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME	(V4L2_CID_FM_TX_CLASS_BASE + 65)
+#define V4L2_CID_AUDIO_LIMITER_DEVIATION	(V4L2_CID_FM_TX_CLASS_BASE + 66)
+
+#define V4L2_CID_AUDIO_COMPRESSION_ENABLED	(V4L2_CID_FM_TX_CLASS_BASE + 80)
+#define V4L2_CID_AUDIO_COMPRESSION_GAIN		(V4L2_CID_FM_TX_CLASS_BASE + 81)
+#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD	(V4L2_CID_FM_TX_CLASS_BASE + 82)
+#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME	(V4L2_CID_FM_TX_CLASS_BASE + 83)
+#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME	(V4L2_CID_FM_TX_CLASS_BASE + 84)
+
+#define V4L2_CID_PILOT_TONE_ENABLED		(V4L2_CID_FM_TX_CLASS_BASE + 96)
+#define V4L2_CID_PILOT_TONE_DEVIATION		(V4L2_CID_FM_TX_CLASS_BASE + 97)
+#define V4L2_CID_PILOT_TONE_FREQUENCY		(V4L2_CID_FM_TX_CLASS_BASE + 98)
+
+#define V4L2_CID_TUNE_PREEMPHASIS		(V4L2_CID_FM_TX_CLASS_BASE + 112)
+enum v4l2_preemphasis {
+	V4L2_PREEMPHASIS_DISABLED	= 0,
+	V4L2_PREEMPHASIS_50_uS		= 1,
+	V4L2_PREEMPHASIS_75_uS		= 2,
+};
+#define V4L2_CID_TUNE_POWER_LEVEL		(V4L2_CID_FM_TX_CLASS_BASE + 113)
+#define V4L2_CID_TUNE_ANTENNA_CAPACITOR		(V4L2_CID_FM_TX_CLASS_BASE + 114)
+
 /*
  *	T U N I N G
  */
@@ -1181,6 +1226,7 @@ struct v4l2_modulator {
 #define V4L2_TUNER_CAP_LANG2		0x0020
 #define V4L2_TUNER_CAP_SAP		0x0020
 #define V4L2_TUNER_CAP_LANG1		0x0040
+#define V4L2_TUNER_CAP_RDS		0x0080
 
 /*  Flags for the 'rxsubchans' field */
 #define V4L2_TUNER_SUB_MONO		0x0001
@@ -1188,6 +1234,7 @@ struct v4l2_modulator {
 #define V4L2_TUNER_SUB_LANG2		0x0004
 #define V4L2_TUNER_SUB_SAP		0x0004
 #define V4L2_TUNER_SUB_LANG1		0x0008
+#define V4L2_TUNER_SUB_RDS		0x0010
 
 /*  Values for the 'audmode' field */
 #define V4L2_TUNER_MODE_MONO		0x0000
@@ -1213,6 +1260,27 @@ struct v4l2_hw_freq_seek {
 };
 
 /*
+ *	R D S
+ */
+
+struct v4l2_rds_data {
+	__u8 	lsb;
+	__u8 	msb;
+	__u8 	block;
+} __attribute__ ((packed));
+
+#define V4L2_RDS_BLOCK_MSK 	 0x7
+#define V4L2_RDS_BLOCK_A 	 0
+#define V4L2_RDS_BLOCK_B 	 1
+#define V4L2_RDS_BLOCK_C 	 2
+#define V4L2_RDS_BLOCK_D 	 3
+#define V4L2_RDS_BLOCK_C_ALT 	 4
+#define V4L2_RDS_BLOCK_INVALID 	 7
+
+#define V4L2_RDS_BLOCK_CORRECTED 0x40
+#define V4L2_RDS_BLOCK_ERROR 	 0x80
+
+/*
  *	A U D I O
  */
 struct v4l2_audio {
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index a43ebec..227c2a5 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -115,4 +115,10 @@ extern rwlock_t vmlist_lock;
 extern struct vm_struct *vmlist;
 extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
 
+struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
+				     const size_t *sizes, int nr_vms,
+				     size_t align, gfp_t gfp_mask);
+
+void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms);
+
 #endif /* _LINUX_VMALLOC_H */
diff --git a/include/linux/vt.h b/include/linux/vt.h
index 02c1c02..7afca0d 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -1,17 +1,6 @@
 #ifndef _LINUX_VT_H
 #define _LINUX_VT_H
 
-#ifdef __KERNEL__
-struct notifier_block;
-
-struct vt_notifier_param {
-	struct vc_data *vc;	/* VC on which the update happened */
-	unsigned int c;		/* Printed char */
-};
-
-extern int register_vt_notifier(struct notifier_block *nb);
-extern int unregister_vt_notifier(struct notifier_block *nb);
-#endif
 
 /*
  * These constants are also useful for user-level apps (e.g., VC
@@ -74,4 +63,25 @@ struct vt_consize {
 #define VT_UNLOCKSWITCH 0x560C  /* allow vt switching */
 #define VT_GETHIFONTMASK 0x560D  /* return hi font mask */
 
+struct vt_event {
+	unsigned int event;
+#define VT_EVENT_SWITCH		0x0001	/* Console switch */
+#define VT_EVENT_BLANK		0x0002	/* Screen blank */
+#define VT_EVENT_UNBLANK	0x0004	/* Screen unblank */
+#define VT_EVENT_RESIZE		0x0008	/* Resize display */
+#define VT_MAX_EVENT		0x000F
+	unsigned int old;		/* Old console */
+	unsigned int new;		/* New console (if changing) */
+	unsigned int pad[4];		/* Padding for expansion */
+};
+
+#define VT_WAITEVENT	0x560E	/* Wait for an event */
+
+struct vt_setactivate {
+	unsigned int console;
+	struct vt_mode mode;
+};
+
+#define VT_SETACTIVATE	0x560F	/* Activate and set the mode of a console */
+
 #endif /* _LINUX_VT_H */
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 2f11134..c0c4e11 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -13,6 +13,7 @@
 #include <linux/console_struct.h>
 #include <linux/mm.h>
 #include <linux/consolemap.h>
+#include <linux/notifier.h>
 
 /*
  * Presently, a lot of graphics programs do not restore the contents of
@@ -91,7 +92,8 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
 #endif
 
 /* vt.c */
-int vt_waitactive(int vt);
+void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
+int vt_waitactive(int n);
 void change_console(struct vc_data *new_vc);
 void reset_vc(struct vc_data *vc);
 extern int unbind_con_driver(const struct consw *csw, int first, int last,
@@ -116,4 +118,16 @@ struct vt_spawn_console {
 };
 extern struct vt_spawn_console vt_spawn_con;
 
+extern int vt_move_to_console(unsigned int vt, int alloc);
+
+/* Interfaces for VC notification of character events (for accessibility etc) */
+
+struct vt_notifier_param {
+	struct vc_data *vc;	/* VC on which the update happened */
+	unsigned int c;		/* Printed char */
+};
+
+extern int register_vt_notifier(struct notifier_block *nb);
+extern int unregister_vt_notifier(struct notifier_block *nb);
+
 #endif /* _VT_KERN_H */
diff --git a/include/linux/wait.h b/include/linux/wait.h
index cf3c2f5..a48e16b 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -26,8 +26,8 @@
 #include <asm/current.h>
 
 typedef struct __wait_queue wait_queue_t;
-typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);
-int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);
+typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
+int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);
 
 struct __wait_queue {
 	unsigned int flags;
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index cb24204..5b4c6c7 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1132,6 +1132,14 @@ struct __compat_iw_event {
 };
 #define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
 #define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
+
+/* Size of the various events for compat */
+#define IW_EV_COMPAT_CHAR_LEN	(IW_EV_COMPAT_LCP_LEN + IFNAMSIZ)
+#define IW_EV_COMPAT_UINT_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(__u32))
+#define IW_EV_COMPAT_FREQ_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_freq))
+#define IW_EV_COMPAT_PARAM_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_param))
+#define IW_EV_COMPAT_ADDR_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct sockaddr))
+#define IW_EV_COMPAT_QUAL_LEN	(IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_quality))
 #define IW_EV_COMPAT_POINT_LEN	\
 	(IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
 	 IW_EV_COMPAT_POINT_OFF)
diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h
index 6f69968..0c98781 100644
--- a/include/linux/wm97xx.h
+++ b/include/linux/wm97xx.h
@@ -16,6 +16,12 @@
 #include <linux/platform_device.h>
 
 /*
+ * WM97xx variants
+ */
+#define	WM97xx_GENERIC			0x0000
+#define	WM97xx_WM1613			0x1613
+
+/*
  * WM97xx AC97 Touchscreen registers
  */
 #define AC97_WM97XX_DIGITISER1		0x76
@@ -283,6 +289,7 @@ struct wm97xx {
 	unsigned pen_is_down:1;		/* Pen is down */
 	unsigned aux_waiting:1;		/* aux measurement waiting */
 	unsigned pen_probably_down:1;	/* used in polling mode */
+	u16 variant;			/* WM97xx chip variant */
 	u16 suspend_mode;               /* PRP in suspend mode */
 };
 
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 78b1e46..75cf586 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -50,7 +50,6 @@ struct writeback_control {
 	unsigned encountered_congestion:1; /* An output: a queue is full */
 	unsigned for_kupdate:1;		/* A kupdate writeback */
 	unsigned for_reclaim:1;		/* Invoked from the page allocator */
-	unsigned for_writepages:1;	/* This is a writepages() call */
 	unsigned range_cyclic:1;	/* range_start is cyclic */
 	unsigned more_io:1;		/* more io to be dispatched */
 	/*
@@ -69,8 +68,8 @@ struct writeback_control {
  */	
 struct bdi_writeback;
 int inode_wait(void *);
-long writeback_inodes_sb(struct super_block *);
-long sync_inodes_sb(struct super_block *);
+void writeback_inodes_sb(struct super_block *);
+void sync_inodes_sb(struct super_block *);
 void writeback_inodes_wbc(struct writeback_control *wbc);
 long wb_do_writeback(struct bdi_writeback *wb, int force_wait);
 void wakeup_flusher_threads(long nr_pages);
@@ -150,10 +149,6 @@ int write_cache_pages(struct address_space *mapping,
 		      struct writeback_control *wbc, writepage_t writepage,
 		      void *data);
 int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
-int sync_page_range(struct inode *inode, struct address_space *mapping,
-			loff_t pos, loff_t count);
-int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
-			   loff_t pos, loff_t count);
 void set_page_dirty_balance(struct page *page, int page_mkwrite);
 void writeback_set_ratelimit(void);
 
diff --git a/include/media/davinci/ccdc_types.h b/include/media/davinci/ccdc_types.h
new file mode 100644
index 0000000..5773874
--- /dev/null
+++ b/include/media/davinci/ccdc_types.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments 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 _CCDC_TYPES_H
+#define _CCDC_TYPES_H
+enum ccdc_pixfmt {
+	CCDC_PIXFMT_RAW,
+	CCDC_PIXFMT_YCBCR_16BIT,
+	CCDC_PIXFMT_YCBCR_8BIT
+};
+
+enum ccdc_frmfmt {
+	CCDC_FRMFMT_PROGRESSIVE,
+	CCDC_FRMFMT_INTERLACED
+};
+
+/* PIXEL ORDER IN MEMORY from LSB to MSB */
+/* only applicable for 8-bit input mode  */
+enum ccdc_pixorder {
+	CCDC_PIXORDER_YCBYCR,
+	CCDC_PIXORDER_CBYCRY,
+};
+
+enum ccdc_buftype {
+	CCDC_BUFTYPE_FLD_INTERLEAVED,
+	CCDC_BUFTYPE_FLD_SEPARATED
+};
+#endif
diff --git a/include/media/davinci/dm355_ccdc.h b/include/media/davinci/dm355_ccdc.h
new file mode 100644
index 0000000..df8a7b1
--- /dev/null
+++ b/include/media/davinci/dm355_ccdc.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2005-2009 Texas Instruments 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 _DM355_CCDC_H
+#define _DM355_CCDC_H
+#include <media/davinci/ccdc_types.h>
+#include <media/davinci/vpfe_types.h>
+
+/* enum for No of pixel per line to be avg. in Black Clamping */
+enum ccdc_sample_length {
+	CCDC_SAMPLE_1PIXELS,
+	CCDC_SAMPLE_2PIXELS,
+	CCDC_SAMPLE_4PIXELS,
+	CCDC_SAMPLE_8PIXELS,
+	CCDC_SAMPLE_16PIXELS
+};
+
+/* enum for No of lines in Black Clamping */
+enum ccdc_sample_line {
+	CCDC_SAMPLE_1LINES,
+	CCDC_SAMPLE_2LINES,
+	CCDC_SAMPLE_4LINES,
+	CCDC_SAMPLE_8LINES,
+	CCDC_SAMPLE_16LINES
+};
+
+/* enum for Alaw gama width */
+enum ccdc_gamma_width {
+	CCDC_GAMMA_BITS_13_4,
+	CCDC_GAMMA_BITS_12_3,
+	CCDC_GAMMA_BITS_11_2,
+	CCDC_GAMMA_BITS_10_1,
+	CCDC_GAMMA_BITS_09_0
+};
+
+enum ccdc_colpats {
+	CCDC_RED,
+	CCDC_GREEN_RED,
+	CCDC_GREEN_BLUE,
+	CCDC_BLUE
+};
+
+struct ccdc_col_pat {
+	enum ccdc_colpats olop;
+	enum ccdc_colpats olep;
+	enum ccdc_colpats elop;
+	enum ccdc_colpats elep;
+};
+
+enum ccdc_datasft {
+	CCDC_DATA_NO_SHIFT,
+	CCDC_DATA_SHIFT_1BIT,
+	CCDC_DATA_SHIFT_2BIT,
+	CCDC_DATA_SHIFT_3BIT,
+	CCDC_DATA_SHIFT_4BIT,
+	CCDC_DATA_SHIFT_5BIT,
+	CCDC_DATA_SHIFT_6BIT
+};
+
+enum ccdc_data_size {
+	CCDC_DATA_16BITS,
+	CCDC_DATA_15BITS,
+	CCDC_DATA_14BITS,
+	CCDC_DATA_13BITS,
+	CCDC_DATA_12BITS,
+	CCDC_DATA_11BITS,
+	CCDC_DATA_10BITS,
+	CCDC_DATA_8BITS
+};
+enum ccdc_mfilt1 {
+	CCDC_NO_MEDIAN_FILTER1,
+	CCDC_AVERAGE_FILTER1,
+	CCDC_MEDIAN_FILTER1
+};
+
+enum ccdc_mfilt2 {
+	CCDC_NO_MEDIAN_FILTER2,
+	CCDC_AVERAGE_FILTER2,
+	CCDC_MEDIAN_FILTER2
+};
+
+/* structure for ALaw */
+struct ccdc_a_law {
+	/* Enable/disable A-Law */
+	unsigned char enable;
+	/* Gama Width Input */
+	enum ccdc_gamma_width gama_wd;
+};
+
+/* structure for Black Clamping */
+struct ccdc_black_clamp {
+	/* only if bClampEnable is TRUE */
+	unsigned char b_clamp_enable;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_length sample_pixel;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_line sample_ln;
+	/* only if bClampEnable is TRUE */
+	unsigned short start_pixel;
+	/* only if bClampEnable is FALSE */
+	unsigned short sgain;
+	unsigned short dc_sub;
+};
+
+/* structure for Black Level Compensation */
+struct ccdc_black_compensation {
+	/* Constant value to subtract from Red component */
+	unsigned char r;
+	/* Constant value to subtract from Gr component */
+	unsigned char gr;
+	/* Constant value to subtract from Blue component */
+	unsigned char b;
+	/* Constant value to subtract from Gb component */
+	unsigned char gb;
+};
+
+struct ccdc_float {
+	int integer;
+	unsigned int decimal;
+};
+
+#define CCDC_CSC_COEFF_TABLE_SIZE	16
+/* structure for color space converter */
+struct ccdc_csc {
+	unsigned char enable;
+	/*
+	 * S8Q5. Use 2 decimal precision, user values range from -3.00 to 3.99.
+	 * example - to use 1.03, set integer part as 1, and decimal part as 3
+	 * to use -1.03, set integer part as -1 and decimal part as 3
+	 */
+	struct ccdc_float coeff[CCDC_CSC_COEFF_TABLE_SIZE];
+};
+
+/* Structures for Vertical Defect Correction*/
+enum ccdc_vdf_csl {
+	CCDC_VDF_NORMAL,
+	CCDC_VDF_HORZ_INTERPOL_SAT,
+	CCDC_VDF_HORZ_INTERPOL
+};
+
+enum ccdc_vdf_cuda {
+	CCDC_VDF_WHOLE_LINE_CORRECT,
+	CCDC_VDF_UPPER_DISABLE
+};
+
+enum ccdc_dfc_mwr {
+	CCDC_DFC_MWR_WRITE_COMPLETE,
+	CCDC_DFC_WRITE_REG
+};
+
+enum ccdc_dfc_mrd {
+	CCDC_DFC_READ_COMPLETE,
+	CCDC_DFC_READ_REG
+};
+
+enum ccdc_dfc_ma_rst {
+	CCDC_DFC_INCR_ADDR,
+	CCDC_DFC_CLR_ADDR
+};
+
+enum ccdc_dfc_mclr {
+	CCDC_DFC_CLEAR_COMPLETE,
+	CCDC_DFC_CLEAR
+};
+
+struct ccdc_dft_corr_ctl {
+	enum ccdc_vdf_csl vdfcsl;
+	enum ccdc_vdf_cuda vdfcuda;
+	unsigned int vdflsft;
+};
+
+struct ccdc_dft_corr_mem_ctl {
+	enum ccdc_dfc_mwr dfcmwr;
+	enum ccdc_dfc_mrd dfcmrd;
+	enum ccdc_dfc_ma_rst dfcmarst;
+	enum ccdc_dfc_mclr dfcmclr;
+};
+
+#define CCDC_DFT_TABLE_SIZE	16
+/*
+ * Main Structure for vertical defect correction. Vertical defect
+ * correction can correct upto 16 defects if defects less than 16
+ * then pad the rest with 0
+ */
+struct ccdc_vertical_dft {
+	unsigned char ver_dft_en;
+	unsigned char gen_dft_en;
+	unsigned int saturation_ctl;
+	struct ccdc_dft_corr_ctl dft_corr_ctl;
+	struct ccdc_dft_corr_mem_ctl dft_corr_mem_ctl;
+	int table_size;
+	unsigned int dft_corr_horz[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_vert[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_sub1[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_sub2[CCDC_DFT_TABLE_SIZE];
+	unsigned int dft_corr_sub3[CCDC_DFT_TABLE_SIZE];
+};
+
+struct ccdc_data_offset {
+	unsigned char horz_offset;
+	unsigned char vert_offset;
+};
+
+/*
+ * Structure for CCDC configuration parameters for raw capture mode passed
+ * by application
+ */
+struct ccdc_config_params_raw {
+	/* data shift to be applied before storing */
+	enum ccdc_datasft datasft;
+	/* data size value from 8 to 16 bits */
+	enum ccdc_data_size data_sz;
+	/* median filter for sdram */
+	enum ccdc_mfilt1 mfilt1;
+	enum ccdc_mfilt2 mfilt2;
+	/* low pass filter enable/disable */
+	unsigned char lpf_enable;
+	/* Threshold of median filter */
+	int med_filt_thres;
+	/*
+	 * horz and vertical data offset. Appliable for defect correction
+	 * and lsc
+	 */
+	struct ccdc_data_offset data_offset;
+	/* Structure for Optional A-Law */
+	struct ccdc_a_law alaw;
+	/* Structure for Optical Black Clamp */
+	struct ccdc_black_clamp blk_clamp;
+	/* Structure for Black Compensation */
+	struct ccdc_black_compensation blk_comp;
+	/* struture for vertical Defect Correction Module Configuration */
+	struct ccdc_vertical_dft vertical_dft;
+	/* structure for color space converter Module Configuration */
+	struct ccdc_csc csc;
+	/* color patters for bayer capture */
+	struct ccdc_col_pat col_pat_field0;
+	struct ccdc_col_pat col_pat_field1;
+};
+
+#ifdef __KERNEL__
+#include <linux/io.h>
+
+#define CCDC_WIN_PAL	{0, 0, 720, 576}
+#define CCDC_WIN_VGA	{0, 0, 640, 480}
+
+struct ccdc_params_ycbcr {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* enable BT.656 embedded sync mode */
+	int bt656_enable;
+	/* cb:y:cr:y or y:cb:y:cr in memory */
+	enum ccdc_pixorder pix_order;
+	/* interleaved or separated fields  */
+	enum ccdc_buftype buf_type;
+};
+
+/* Gain applied to Raw Bayer data */
+struct ccdc_gain {
+	unsigned short r_ye;
+	unsigned short gr_cy;
+	unsigned short gb_g;
+	unsigned short b_mg;
+};
+
+/* Structure for CCDC configuration parameters for raw capture mode */
+struct ccdc_params_raw {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* interleaved or separated fields */
+	enum ccdc_buftype buf_type;
+	/* Gain values */
+	struct ccdc_gain gain;
+	/* offset */
+	unsigned int ccdc_offset;
+	/* horizontal flip enable */
+	unsigned char horz_flip_enable;
+	/*
+	 * enable to store the image in inverse order in memory
+	 * (bottom to top)
+	 */
+	unsigned char image_invert_enable;
+	/* Configurable part of raw data */
+	struct ccdc_config_params_raw config_params;
+};
+
+#endif
+#endif				/* DM355_CCDC_H */
diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h
new file mode 100644
index 0000000..3e178eb
--- /dev/null
+++ b/include/media/davinci/dm644x_ccdc.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2006-2009 Texas Instruments 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 _DM644X_CCDC_H
+#define _DM644X_CCDC_H
+#include <media/davinci/ccdc_types.h>
+#include <media/davinci/vpfe_types.h>
+
+/* enum for No of pixel per line to be avg. in Black Clamping*/
+enum ccdc_sample_length {
+	CCDC_SAMPLE_1PIXELS,
+	CCDC_SAMPLE_2PIXELS,
+	CCDC_SAMPLE_4PIXELS,
+	CCDC_SAMPLE_8PIXELS,
+	CCDC_SAMPLE_16PIXELS
+};
+
+/* enum for No of lines in Black Clamping */
+enum ccdc_sample_line {
+	CCDC_SAMPLE_1LINES,
+	CCDC_SAMPLE_2LINES,
+	CCDC_SAMPLE_4LINES,
+	CCDC_SAMPLE_8LINES,
+	CCDC_SAMPLE_16LINES
+};
+
+/* enum for Alaw gama width */
+enum ccdc_gama_width {
+	CCDC_GAMMA_BITS_15_6,
+	CCDC_GAMMA_BITS_14_5,
+	CCDC_GAMMA_BITS_13_4,
+	CCDC_GAMMA_BITS_12_3,
+	CCDC_GAMMA_BITS_11_2,
+	CCDC_GAMMA_BITS_10_1,
+	CCDC_GAMMA_BITS_09_0
+};
+
+enum ccdc_data_size {
+	CCDC_DATA_16BITS,
+	CCDC_DATA_15BITS,
+	CCDC_DATA_14BITS,
+	CCDC_DATA_13BITS,
+	CCDC_DATA_12BITS,
+	CCDC_DATA_11BITS,
+	CCDC_DATA_10BITS,
+	CCDC_DATA_8BITS
+};
+
+/* structure for ALaw */
+struct ccdc_a_law {
+	/* Enable/disable A-Law */
+	unsigned char enable;
+	/* Gama Width Input */
+	enum ccdc_gama_width gama_wd;
+};
+
+/* structure for Black Clamping */
+struct ccdc_black_clamp {
+	unsigned char enable;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_length sample_pixel;
+	/* only if bClampEnable is TRUE */
+	enum ccdc_sample_line sample_ln;
+	/* only if bClampEnable is TRUE */
+	unsigned short start_pixel;
+	/* only if bClampEnable is TRUE */
+	unsigned short sgain;
+	/* only if bClampEnable is FALSE */
+	unsigned short dc_sub;
+};
+
+/* structure for Black Level Compensation */
+struct ccdc_black_compensation {
+	/* Constant value to subtract from Red component */
+	char r;
+	/* Constant value to subtract from Gr component */
+	char gr;
+	/* Constant value to subtract from Blue component */
+	char b;
+	/* Constant value to subtract from Gb component */
+	char gb;
+};
+
+/* structure for fault pixel correction */
+struct ccdc_fault_pixel {
+	/* Enable or Disable fault pixel correction */
+	unsigned char enable;
+	/* Number of fault pixel */
+	unsigned short fp_num;
+	/* Address of fault pixel table */
+	unsigned int fpc_table_addr;
+};
+
+/* Structure for CCDC configuration parameters for raw capture mode passed
+ * by application
+ */
+struct ccdc_config_params_raw {
+	/* data size value from 8 to 16 bits */
+	enum ccdc_data_size data_sz;
+	/* Structure for Optional A-Law */
+	struct ccdc_a_law alaw;
+	/* Structure for Optical Black Clamp */
+	struct ccdc_black_clamp blk_clamp;
+	/* Structure for Black Compensation */
+	struct ccdc_black_compensation blk_comp;
+	/* Structure for Fault Pixel Module Configuration */
+	struct ccdc_fault_pixel fault_pxl;
+};
+
+
+#ifdef __KERNEL__
+#include <linux/io.h>
+/* Define to enable/disable video port */
+#define FP_NUM_BYTES		4
+/* Define for extra pixel/line and extra lines/frame */
+#define NUM_EXTRAPIXELS		8
+#define NUM_EXTRALINES		8
+
+/* settings for commonly used video formats */
+#define CCDC_WIN_PAL     {0, 0, 720, 576}
+/* ntsc square pixel */
+#define CCDC_WIN_VGA	{0, 0, (640 + NUM_EXTRAPIXELS), (480 + NUM_EXTRALINES)}
+
+/* Structure for CCDC configuration parameters for raw capture mode */
+struct ccdc_params_raw {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* interleaved or separated fields */
+	enum ccdc_buftype buf_type;
+	/*
+	 * enable to store the image in inverse
+	 * order in memory(bottom to top)
+	 */
+	unsigned char image_invert_enable;
+	/* configurable paramaters */
+	struct ccdc_config_params_raw config_params;
+};
+
+struct ccdc_params_ycbcr {
+	/* pixel format */
+	enum ccdc_pixfmt pix_fmt;
+	/* progressive or interlaced frame */
+	enum ccdc_frmfmt frm_fmt;
+	/* video window */
+	struct v4l2_rect win;
+	/* field id polarity */
+	enum vpfe_pin_pol fid_pol;
+	/* vertical sync polarity */
+	enum vpfe_pin_pol vd_pol;
+	/* horizontal sync polarity */
+	enum vpfe_pin_pol hd_pol;
+	/* enable BT.656 embedded sync mode */
+	int bt656_enable;
+	/* cb:y:cr:y or y:cb:y:cr in memory */
+	enum ccdc_pixorder pix_order;
+	/* interleaved or separated fields  */
+	enum ccdc_buftype buf_type;
+};
+#endif
+#endif				/* _DM644X_CCDC_H */
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
new file mode 100644
index 0000000..71d8982
--- /dev/null
+++ b/include/media/davinci/vpfe_capture.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments 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 _VPFE_CAPTURE_H
+#define _VPFE_CAPTURE_H
+
+#ifdef __KERNEL__
+
+/* Header files */
+#include <media/v4l2-dev.h>
+#include <linux/videodev2.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf-dma-contig.h>
+#include <media/davinci/vpfe_types.h>
+
+#define VPFE_CAPTURE_NUM_DECODERS        5
+
+/* Macros */
+#define VPFE_MAJOR_RELEASE              0
+#define VPFE_MINOR_RELEASE              0
+#define VPFE_BUILD                      1
+#define VPFE_CAPTURE_VERSION_CODE       ((VPFE_MAJOR_RELEASE << 16) | \
+					(VPFE_MINOR_RELEASE << 8)  | \
+					VPFE_BUILD)
+
+#define CAPTURE_DRV_NAME		"vpfe-capture"
+
+struct vpfe_pixel_format {
+	struct v4l2_fmtdesc fmtdesc;
+	/* bytes per pixel */
+	int bpp;
+};
+
+struct vpfe_std_info {
+	int active_pixels;
+	int active_lines;
+	/* current frame format */
+	int frame_format;
+};
+
+struct vpfe_route {
+	u32 input;
+	u32 output;
+};
+
+struct vpfe_subdev_info {
+	/* Sub device name */
+	char name[32];
+	/* Sub device group id */
+	int grp_id;
+	/* Number of inputs supported */
+	int num_inputs;
+	/* inputs available at the sub device */
+	struct v4l2_input *inputs;
+	/* Sub dev routing information for each input */
+	struct vpfe_route *routes;
+	/* check if sub dev supports routing */
+	int can_route;
+	/* ccdc bus/interface configuration */
+	struct vpfe_hw_if_param ccdc_if_params;
+	/* i2c subdevice board info */
+	struct i2c_board_info board_info;
+};
+
+struct vpfe_config {
+	/* Number of sub devices connected to vpfe */
+	int num_subdevs;
+	/* information about each subdev */
+	struct vpfe_subdev_info *sub_devs;
+	/* evm card info */
+	char *card_name;
+	/* ccdc name */
+	char *ccdc;
+	/* vpfe clock */
+	struct clk *vpssclk;
+	struct clk *slaveclk;
+};
+
+struct vpfe_device {
+	/* V4l2 specific parameters */
+	/* Identifies video device for this channel */
+	struct video_device *video_dev;
+	/* sub devices */
+	struct v4l2_subdev **sd;
+	/* vpfe cfg */
+	struct vpfe_config *cfg;
+	/* V4l2 device */
+	struct v4l2_device v4l2_dev;
+	/* parent device */
+	struct device *pdev;
+	/* Used to keep track of state of the priority */
+	struct v4l2_prio_state prio;
+	/* number of open instances of the channel */
+	u32 usrs;
+	/* Indicates id of the field which is being displayed */
+	u32 field_id;
+	/* flag to indicate whether decoder is initialized */
+	u8 initialized;
+	/* current interface type */
+	struct vpfe_hw_if_param vpfe_if_params;
+	/* ptr to currently selected sub device */
+	struct vpfe_subdev_info *current_subdev;
+	/* current input at the sub device */
+	int current_input;
+	/* Keeps track of the information about the standard */
+	struct vpfe_std_info std_info;
+	/* std index into std table */
+	int std_index;
+	/* CCDC IRQs used when CCDC/ISIF output to SDRAM */
+	unsigned int ccdc_irq0;
+	unsigned int ccdc_irq1;
+	/* number of buffers in fbuffers */
+	u32 numbuffers;
+	/* List of buffer pointers for storing frames */
+	u8 *fbuffers[VIDEO_MAX_FRAME];
+	/* Pointer pointing to current v4l2_buffer */
+	struct videobuf_buffer *cur_frm;
+	/* Pointer pointing to next v4l2_buffer */
+	struct videobuf_buffer *next_frm;
+	/*
+	 * This field keeps track of type of buffer exchange mechanism
+	 * user has selected
+	 */
+	enum v4l2_memory memory;
+	/* Used to store pixel format */
+	struct v4l2_format fmt;
+	/*
+	 * used when IMP is chained to store the crop window which
+	 * is different from the image window
+	 */
+	struct v4l2_rect crop;
+	/* Buffer queue used in video-buf */
+	struct videobuf_queue buffer_queue;
+	/* Queue of filled frames */
+	struct list_head dma_queue;
+	/* Used in video-buf */
+	spinlock_t irqlock;
+	/* IRQ lock for DMA queue */
+	spinlock_t dma_queue_lock;
+	/* lock used to access this structure */
+	struct mutex lock;
+	/* number of users performing IO */
+	u32 io_usrs;
+	/* Indicates whether streaming started */
+	u8 started;
+	/*
+	 * offset where second field starts from the starting of the
+	 * buffer for field seperated YCbCr formats
+	 */
+	u32 field_off;
+};
+
+/* File handle structure */
+struct vpfe_fh {
+	struct vpfe_device *vpfe_dev;
+	/* Indicates whether this file handle is doing IO */
+	u8 io_allowed;
+	/* Used to keep track priority of this instance */
+	enum v4l2_priority prio;
+};
+
+struct vpfe_config_params {
+	u8 min_numbuffers;
+	u8 numbuffers;
+	u32 min_bufsize;
+	u32 device_bufsize;
+};
+
+#endif				/* End of __KERNEL__ */
+/**
+ * VPFE_CMD_S_CCDC_RAW_PARAMS - EXPERIMENTAL IOCTL to set raw capture params
+ * This can be used to configure modules such as defect pixel correction,
+ * color space conversion, culling etc. This is an experimental ioctl that
+ * will change in future kernels. So use this ioctl with care !
+ * TODO: This is to be split into multiple ioctls and also explore the
+ * possibility of extending the v4l2 api to include this
+ **/
+#define VPFE_CMD_S_CCDC_RAW_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 1, \
+					void *)
+#endif				/* _DAVINCI_VPFE_H */
diff --git a/include/media/davinci/vpfe_types.h b/include/media/davinci/vpfe_types.h
new file mode 100644
index 0000000..76fb74b
--- /dev/null
+++ b/include/media/davinci/vpfe_types.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2009 Texas Instruments 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 _VPFE_TYPES_H
+#define _VPFE_TYPES_H
+
+#ifdef __KERNEL__
+
+enum vpfe_pin_pol {
+	VPFE_PINPOL_POSITIVE,
+	VPFE_PINPOL_NEGATIVE
+};
+
+enum vpfe_hw_if_type {
+	/* BT656 - 8 bit */
+	VPFE_BT656,
+	/* BT1120 - 16 bit */
+	VPFE_BT1120,
+	/* Raw Bayer */
+	VPFE_RAW_BAYER,
+	/* YCbCr - 8 bit with external sync */
+	VPFE_YCBCR_SYNC_8,
+	/* YCbCr - 16 bit with external sync */
+	VPFE_YCBCR_SYNC_16,
+	/* BT656 - 10 bit */
+	VPFE_BT656_10BIT
+};
+
+/* interface description */
+struct vpfe_hw_if_param {
+	enum vpfe_hw_if_type if_type;
+	enum vpfe_pin_pol hdpol;
+	enum vpfe_pin_pol vdpol;
+};
+
+#endif
+#endif
diff --git a/include/media/davinci/vpss.h b/include/media/davinci/vpss.h
new file mode 100644
index 0000000..fcdff74
--- /dev/null
+++ b/include/media/davinci/vpss.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2009 Texas Instruments 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
+ *
+ * vpss - video processing subsystem module header file.
+ *
+ * Include this header file if a driver needs to configure vpss system
+ * module. It exports a set of library functions  for video drivers to
+ * configure vpss system module functions such as clock enable/disable,
+ * vpss interrupt mux to arm, and other common vpss system module
+ * functions.
+ */
+#ifndef _VPSS_H
+#define _VPSS_H
+
+/* selector for ccdc input selection on DM355 */
+enum vpss_ccdc_source_sel {
+	VPSS_CCDCIN,
+	VPSS_HSSIIN
+};
+
+/* Used for enable/diable VPSS Clock */
+enum vpss_clock_sel {
+	/* DM355/DM365 */
+	VPSS_CCDC_CLOCK,
+	VPSS_IPIPE_CLOCK,
+	VPSS_H3A_CLOCK,
+	VPSS_CFALD_CLOCK,
+	/*
+	 * When using VPSS_VENC_CLOCK_SEL in vpss_enable_clock() api
+	 * following applies:-
+	 * en = 0 selects ENC_CLK
+	 * en = 1 selects ENC_CLK/2
+	 */
+	VPSS_VENC_CLOCK_SEL,
+	VPSS_VPBE_CLOCK,
+};
+
+/* select input to ccdc on dm355 */
+int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel);
+/* enable/disable a vpss clock, 0 - success, -1 - failure */
+int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en);
+
+/* wbl reset for dm644x */
+enum vpss_wbl_sel {
+	VPSS_PCR_AEW_WBL_0 = 16,
+	VPSS_PCR_AF_WBL_0,
+	VPSS_PCR_RSZ4_WBL_0,
+	VPSS_PCR_RSZ3_WBL_0,
+	VPSS_PCR_RSZ2_WBL_0,
+	VPSS_PCR_RSZ1_WBL_0,
+	VPSS_PCR_PREV_WBL_0,
+	VPSS_PCR_CCDC_WBL_O,
+};
+int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel);
+#endif
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 9dcb632..29f0e53 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -31,8 +31,18 @@
 #define IR_TYPE_PD      2 /* Pulse distance encoded IR */
 #define IR_TYPE_OTHER  99
 
-#define IR_KEYTAB_TYPE	u32
-#define IR_KEYTAB_SIZE	128  // enougth for rc5, probably need more some day ...
+#define IR_KEYTAB_TYPE u32
+#define IR_KEYTAB_SIZE	128  /* enougth for rc5, probably need more some day */
+
+struct ir_scancode {
+	u16	scancode;
+	u32	keycode;
+};
+
+struct ir_scancode_table {
+	struct ir_scancode *scan;
+	int size;
+};
 
 #define IR_KEYCODE(tab,code)	(((unsigned)code < IR_KEYTAB_SIZE) \
 				 ? tab[code] : KEY_RESERVED)
@@ -93,7 +103,7 @@ struct card_ir {
 };
 
 void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
-		   int ir_type, IR_KEYTAB_TYPE *ir_codes);
+		   int ir_type, struct ir_scancode_table *ir_codes);
 void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir);
 void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
 		      u32 ir_key, u32 ir_raw);
@@ -107,67 +117,63 @@ void ir_rc5_timer_keyup(unsigned long data);
 
 /* Keymaps to be used by other modules */
 
-extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pixelview_new[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvb_t[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_iodata_bctv7e[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_adstech_dvb_t_pci[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pinnacle_grey[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_flyvideo[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_flydvb[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_cinergy[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_eztv[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_avermedia[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_videomate_tv_pvr[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_manli[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pctv_sedna[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pinnacle_color[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_npgtech[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_norwood[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_proteus_2309[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_encore_enltv2[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_behold[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE];
-extern IR_KEYTAB_TYPE ir_codes_evga_indtube[IR_KEYTAB_SIZE];
-
+extern struct ir_scancode_table ir_codes_empty_table;
+extern struct ir_scancode_table ir_codes_avermedia_table;
+extern struct ir_scancode_table ir_codes_avermedia_dvbt_table;
+extern struct ir_scancode_table ir_codes_avermedia_m135a_table;
+extern struct ir_scancode_table ir_codes_avermedia_cardbus_table;
+extern struct ir_scancode_table ir_codes_apac_viewcomp_table;
+extern struct ir_scancode_table ir_codes_pixelview_table;
+extern struct ir_scancode_table ir_codes_pixelview_new_table;
+extern struct ir_scancode_table ir_codes_nebula_table;
+extern struct ir_scancode_table ir_codes_dntv_live_dvb_t_table;
+extern struct ir_scancode_table ir_codes_iodata_bctv7e_table;
+extern struct ir_scancode_table ir_codes_adstech_dvb_t_pci_table;
+extern struct ir_scancode_table ir_codes_msi_tvanywhere_table;
+extern struct ir_scancode_table ir_codes_cinergy_1400_table;
+extern struct ir_scancode_table ir_codes_avertv_303_table;
+extern struct ir_scancode_table ir_codes_dntv_live_dvbt_pro_table;
+extern struct ir_scancode_table ir_codes_em_terratec_table;
+extern struct ir_scancode_table ir_codes_pinnacle_grey_table;
+extern struct ir_scancode_table ir_codes_flyvideo_table;
+extern struct ir_scancode_table ir_codes_flydvb_table;
+extern struct ir_scancode_table ir_codes_cinergy_table;
+extern struct ir_scancode_table ir_codes_eztv_table;
+extern struct ir_scancode_table ir_codes_avermedia_table;
+extern struct ir_scancode_table ir_codes_videomate_tv_pvr_table;
+extern struct ir_scancode_table ir_codes_manli_table;
+extern struct ir_scancode_table ir_codes_gotview7135_table;
+extern struct ir_scancode_table ir_codes_purpletv_table;
+extern struct ir_scancode_table ir_codes_pctv_sedna_table;
+extern struct ir_scancode_table ir_codes_pv951_table;
+extern struct ir_scancode_table ir_codes_rc5_tv_table;
+extern struct ir_scancode_table ir_codes_winfast_table;
+extern struct ir_scancode_table ir_codes_pinnacle_color_table;
+extern struct ir_scancode_table ir_codes_hauppauge_new_table;
+extern struct ir_scancode_table ir_codes_npgtech_table;
+extern struct ir_scancode_table ir_codes_norwood_table;
+extern struct ir_scancode_table ir_codes_proteus_2309_table;
+extern struct ir_scancode_table ir_codes_budget_ci_old_table;
+extern struct ir_scancode_table ir_codes_asus_pc39_table;
+extern struct ir_scancode_table ir_codes_encore_enltv_table;
+extern struct ir_scancode_table ir_codes_encore_enltv2_table;
+extern struct ir_scancode_table ir_codes_tt_1500_table;
+extern struct ir_scancode_table ir_codes_fusionhdtv_mce_table;
+extern struct ir_scancode_table ir_codes_behold_table;
+extern struct ir_scancode_table ir_codes_behold_columbus_table;
+extern struct ir_scancode_table ir_codes_pinnacle_pctv_hd_table;
+extern struct ir_scancode_table ir_codes_genius_tvgo_a11mce_table;
+extern struct ir_scancode_table ir_codes_powercolor_real_angel_table;
+extern struct ir_scancode_table ir_codes_avermedia_a16d_table;
+extern struct ir_scancode_table ir_codes_encore_enltv_fm53_table;
+extern struct ir_scancode_table ir_codes_real_audio_220_32_keys_table;
+extern struct ir_scancode_table ir_codes_msi_tvanywhere_plus_table;
+extern struct ir_scancode_table ir_codes_ati_tv_wonder_hd_600_table;
+extern struct ir_scancode_table ir_codes_kworld_plus_tv_analog_table;
+extern struct ir_scancode_table ir_codes_kaiomy_table;
+extern struct ir_scancode_table ir_codes_dm1105_nec_table;
+extern struct ir_scancode_table ir_codes_evga_indtube_table;
+extern struct ir_scancode_table ir_codes_terratec_cinergy_xs_table;
+extern struct ir_scancode_table ir_codes_videomate_s350_table;
+extern struct ir_scancode_table ir_codes_gadmei_rm008z_table;
 #endif
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 3ad4ed5..aaf65e8 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -6,7 +6,8 @@
 struct IR_i2c;
 
 struct IR_i2c {
-	IR_KEYTAB_TYPE         *ir_codes;
+	struct ir_scancode_table *ir_codes;
+
 	struct i2c_client      *c;
 	struct input_dev       *input;
 	struct ir_input_state  ir;
@@ -20,10 +21,27 @@ struct IR_i2c {
 	int                    (*get_key)(struct IR_i2c*, u32*, u32*);
 };
 
+enum ir_kbd_get_key_fn {
+	IR_KBD_GET_KEY_CUSTOM = 0,
+	IR_KBD_GET_KEY_PIXELVIEW,
+	IR_KBD_GET_KEY_PV951,
+	IR_KBD_GET_KEY_HAUP,
+	IR_KBD_GET_KEY_KNC1,
+	IR_KBD_GET_KEY_FUSIONHDTV,
+	IR_KBD_GET_KEY_HAUP_XVR,
+	IR_KBD_GET_KEY_AVERMEDIA_CARDBUS,
+};
+
 /* Can be passed when instantiating an ir_video i2c device */
 struct IR_i2c_init_data {
-	IR_KEYTAB_TYPE         *ir_codes;
+	struct ir_scancode_table *ir_codes;
 	const char             *name;
+	int                    type; /* IR_TYPE_RC5, IR_TYPE_PD, etc */
+	/*
+	 * Specify either a function pointer or a value indicating one of
+	 * ir_kbd_i2c's internal get_key functions
+	 */
 	int                    (*get_key)(struct IR_i2c*, u32*, u32*);
+	enum ir_kbd_get_key_fn internal_get_key_func;
 };
 #endif
diff --git a/include/media/radio-si4713.h b/include/media/radio-si4713.h
new file mode 100644
index 0000000..f6aae29
--- /dev/null
+++ b/include/media/radio-si4713.h
@@ -0,0 +1,30 @@
+/*
+ * include/media/radio-si4713.h
+ *
+ * Board related data definitions for Si4713 radio transmitter chip.
+ *
+ * Copyright (c) 2009 Nokia Corporation
+ * Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+
+#ifndef RADIO_SI4713_H
+#define RADIO_SI4713_H
+
+#include <linux/i2c.h>
+
+#define SI4713_NAME "radio-si4713"
+
+/*
+ * Platform dependent definition
+ */
+struct radio_si4713_platform_data {
+	int i2c_bus;
+	struct i2c_board_info *subdev_board_info;
+};
+
+#endif /* ifndef RADIO_SI4713_H*/
diff --git a/include/media/si4713.h b/include/media/si4713.h
new file mode 100644
index 0000000..99850a5
--- /dev/null
+++ b/include/media/si4713.h
@@ -0,0 +1,49 @@
+/*
+ * include/media/si4713.h
+ *
+ * Board related data definitions for Si4713 i2c device driver.
+ *
+ * Copyright (c) 2009 Nokia Corporation
+ * Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+
+#ifndef SI4713_H
+#define SI4713_H
+
+/* The SI4713 I2C sensor chip has a fixed slave address of 0xc6 or 0x22. */
+#define SI4713_I2C_ADDR_BUSEN_HIGH	0x63
+#define SI4713_I2C_ADDR_BUSEN_LOW	0x11
+
+/*
+ * Platform dependent definition
+ */
+struct si4713_platform_data {
+	/* Set power state, zero is off, non-zero is on. */
+	int (*set_power)(int power);
+};
+
+/*
+ * Structure to query for Received Noise Level (RNL).
+ */
+struct si4713_rnl {
+	__u32 index;		/* modulator index */
+	__u32 frequency;	/* frequency to peform rnl measurement */
+	__s32 rnl;		/* result of measurement in dBuV */
+	__u32 reserved[4];	/* drivers and apps must init this to 0 */
+};
+
+/*
+ * This is the ioctl number to query for rnl. Users must pass a
+ * struct si4713_rnl pointer specifying desired frequency in 'frequency' field
+ * following driver capabilities (i.e V4L2_TUNER_CAP_LOW).
+ * Driver must return measured value in the same struture, filling 'rnl' field.
+ */
+#define SI4713_IOC_MEASURE_RNL	_IOWR('V', BASE_VIDIOC_PRIVATE + 0, \
+						struct si4713_rnl)
+
+#endif /* ifndef SI4713_H*/
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 23ecead..3d74e60 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -16,24 +16,17 @@
 #include <linux/pm.h>
 #include <linux/videodev2.h>
 #include <media/videobuf-core.h>
+#include <media/v4l2-device.h>
 
 struct soc_camera_device {
 	struct list_head list;
 	struct device dev;
-	struct device *control;
-	unsigned short width;		/* Current window */
-	unsigned short height;		/* sizes */
-	unsigned short x_min;		/* Camera capabilities */
-	unsigned short y_min;
-	unsigned short x_current;	/* Current window location */
-	unsigned short y_current;
+	struct device *pdev;		/* Platform device */
+	s32 user_width;
+	s32 user_height;
 	unsigned short width_min;
-	unsigned short width_max;
 	unsigned short height_min;
-	unsigned short height_max;
 	unsigned short y_skip_top;	/* Lines to skip at the top */
-	unsigned short gain;
-	unsigned short exposure;
 	unsigned char iface;		/* Host number */
 	unsigned char devnum;		/* Device number per host */
 	unsigned char buswidth;		/* See comment in .c */
@@ -46,7 +39,6 @@ struct soc_camera_device {
 	struct soc_camera_format_xlate *user_formats;
 	int num_user_formats;
 	enum v4l2_field field;		/* Preserve field over close() */
-	struct module *owner;
 	void *host_priv;		/* Per-device host private data */
 	/* soc_camera.c private count. Only accessed with .video_lock held */
 	int use_count;
@@ -59,8 +51,8 @@ struct soc_camera_file {
 };
 
 struct soc_camera_host {
+	struct v4l2_device v4l2_dev;
 	struct list_head list;
-	struct device *dev;
 	unsigned char nr;				/* Host number */
 	void *priv;
 	const char *drv_name;
@@ -73,9 +65,18 @@ struct soc_camera_host_ops {
 	void (*remove)(struct soc_camera_device *);
 	int (*suspend)(struct soc_camera_device *, pm_message_t);
 	int (*resume)(struct soc_camera_device *);
+	/*
+	 * .get_formats() is called for each client device format, but
+	 * .put_formats() is only called once. Further, if any of the calls to
+	 * .get_formats() fail, .put_formats() will not be called at all, the
+	 * failing .get_formats() must then clean up internally.
+	 */
 	int (*get_formats)(struct soc_camera_device *, int,
 			   struct soc_camera_format_xlate *);
-	int (*set_crop)(struct soc_camera_device *, struct v4l2_rect *);
+	void (*put_formats)(struct soc_camera_device *);
+	int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *);
+	int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *);
+	int (*set_crop)(struct soc_camera_device *, struct v4l2_crop *);
 	int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
 	int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
 	void (*init_videobuf)(struct videobuf_queue *,
@@ -83,7 +84,11 @@ struct soc_camera_host_ops {
 	int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *);
 	int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
 	int (*set_bus_param)(struct soc_camera_device *, __u32);
+	int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *);
+	int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *);
 	unsigned int (*poll)(struct file *, poll_table *);
+	const struct v4l2_queryctrl *controls;
+	int num_controls;
 };
 
 #define SOCAM_SENSOR_INVERT_PCLK	(1 << 0)
@@ -102,6 +107,12 @@ struct soc_camera_link {
 	int i2c_adapter_id;
 	struct i2c_board_info *board_info;
 	const char *module_name;
+	/*
+	 * For non-I2C devices platform platform has to provide methods to
+	 * add a device to the system and to remove
+	 */
+	int (*add_device)(struct soc_camera_link *, struct device *);
+	void (*del_device)(struct soc_camera_link *);
 	/* Optional callbacks to power on or off and reset the sensor */
 	int (*power)(struct device *, int);
 	int (*reset)(struct device *);
@@ -115,27 +126,45 @@ struct soc_camera_link {
 	void (*free_bus)(struct soc_camera_link *);
 };
 
-static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev)
+static inline struct soc_camera_device *to_soc_camera_dev(
+	const struct device *dev)
 {
 	return container_of(dev, struct soc_camera_device, dev);
 }
 
-static inline struct soc_camera_host *to_soc_camera_host(struct device *dev)
+static inline struct soc_camera_host *to_soc_camera_host(
+	const struct device *dev)
 {
-	return dev_get_drvdata(dev);
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+
+	return container_of(v4l2_dev, struct soc_camera_host, v4l2_dev);
 }
 
-extern int soc_camera_host_register(struct soc_camera_host *ici);
-extern void soc_camera_host_unregister(struct soc_camera_host *ici);
-extern int soc_camera_device_register(struct soc_camera_device *icd);
-extern void soc_camera_device_unregister(struct soc_camera_device *icd);
+static inline struct soc_camera_link *to_soc_camera_link(
+	const struct soc_camera_device *icd)
+{
+	return icd->dev.platform_data;
+}
 
-extern int soc_camera_video_start(struct soc_camera_device *icd);
-extern void soc_camera_video_stop(struct soc_camera_device *icd);
+static inline struct device *to_soc_camera_control(
+	const struct soc_camera_device *icd)
+{
+	return dev_get_drvdata(&icd->dev);
+}
 
-extern const struct soc_camera_data_format *soc_camera_format_by_fourcc(
+static inline struct v4l2_subdev *soc_camera_to_subdev(
+	const struct soc_camera_device *icd)
+{
+	struct device *control = to_soc_camera_control(icd);
+	return dev_get_drvdata(control);
+}
+
+int soc_camera_host_register(struct soc_camera_host *ici);
+void soc_camera_host_unregister(struct soc_camera_host *ici);
+
+const struct soc_camera_data_format *soc_camera_format_by_fourcc(
 	struct soc_camera_device *icd, unsigned int fourcc);
-extern const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
+const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
 	struct soc_camera_device *icd, unsigned int fourcc);
 
 struct soc_camera_data_format {
@@ -163,30 +192,11 @@ struct soc_camera_format_xlate {
 };
 
 struct soc_camera_ops {
-	struct module *owner;
-	int (*probe)(struct soc_camera_device *);
-	void (*remove)(struct soc_camera_device *);
 	int (*suspend)(struct soc_camera_device *, pm_message_t state);
 	int (*resume)(struct soc_camera_device *);
-	int (*init)(struct soc_camera_device *);
-	int (*release)(struct soc_camera_device *);
-	int (*start_capture)(struct soc_camera_device *);
-	int (*stop_capture)(struct soc_camera_device *);
-	int (*set_crop)(struct soc_camera_device *, struct v4l2_rect *);
-	int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
-	int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
 	unsigned long (*query_bus_param)(struct soc_camera_device *);
 	int (*set_bus_param)(struct soc_camera_device *, unsigned long);
-	int (*get_chip_id)(struct soc_camera_device *,
-			   struct v4l2_dbg_chip_ident *);
-	int (*set_std)(struct soc_camera_device *, v4l2_std_id *);
 	int (*enum_input)(struct soc_camera_device *, struct v4l2_input *);
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-	int (*get_register)(struct soc_camera_device *, struct v4l2_dbg_register *);
-	int (*set_register)(struct soc_camera_device *, struct v4l2_dbg_register *);
-#endif
-	int (*get_control)(struct soc_camera_device *, struct v4l2_control *);
-	int (*set_control)(struct soc_camera_device *, struct v4l2_control *);
 	const struct v4l2_queryctrl *controls;
 	int num_controls;
 };
@@ -268,6 +278,21 @@ static inline unsigned long soc_camera_bus_param_compatible(
 		common_flags;
 }
 
+static inline void soc_camera_limit_side(unsigned int *start,
+		unsigned int *length, unsigned int start_min,
+		unsigned int length_min, unsigned int length_max)
+{
+	if (*length < length_min)
+		*length = length_min;
+	else if (*length > length_max)
+		*length = length_max;
+
+	if (*start < start_min)
+		*start = start_min;
+	else if (*start > start_min + length_max - *length)
+		*start = start_min + length_max - *length;
+}
+
 extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
 						   unsigned long flags);
 
diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h
index 1d092b4..bb70401 100644
--- a/include/media/soc_camera_platform.h
+++ b/include/media/soc_camera_platform.h
@@ -12,15 +12,18 @@
 #define __SOC_CAMERA_H__
 
 #include <linux/videodev2.h>
+#include <media/soc_camera.h>
+
+struct device;
 
 struct soc_camera_platform_info {
-	int iface;
-	char *format_name;
+	const char *format_name;
 	unsigned long format_depth;
 	struct v4l2_pix_format format;
 	unsigned long bus_param;
-	void (*power)(int);
+	struct device *dev;
 	int (*set_capture)(struct soc_camera_platform_info *info, int enable);
+	struct soc_camera_link link;
 };
 
 #endif /* __SOC_CAMERA_H__ */
diff --git a/include/media/tuner.h b/include/media/tuner.h
index cbf97f4..4d5b53f 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -126,6 +126,9 @@
 #define TUNER_PHILIPS_FMD1216MEX_MK3	78
 #define TUNER_PHILIPS_FM1216MK5		79
 #define TUNER_PHILIPS_FQ1216LME_MK3	80	/* Active loopthrough, no FM */
+#define TUNER_PARTSNIC_PTI_5NF05	81
+#define TUNER_PHILIPS_CU1216L           82
+#define TUNER_NXP_TDA18271		83
 
 /* tv card specific */
 #define TDA9887_PRESENT 		(1<<0)
diff --git a/include/media/tvp514x.h b/include/media/tvp514x.h
index 5e7ee96..74387e8 100644
--- a/include/media/tvp514x.h
+++ b/include/media/tvp514x.h
@@ -104,10 +104,6 @@ enum tvp514x_output {
  * @ vs_polarity: VSYNC Polarity configuration for current interface.
  */
 struct tvp514x_platform_data {
-	char *master;
-	int (*power_set) (enum v4l2_power on);
-	int (*ifparm) (struct v4l2_ifparm *p);
-	int (*priv_data_set) (void *);
 	/* Interface control params */
 	bool clk_polarity;
 	bool hs_polarity;
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 94e908c..cf16689 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -135,6 +135,9 @@ enum {
 	/* module adv7175: just ident 7175 */
 	V4L2_IDENT_ADV7175 = 7175,
 
+	/* module adv7180: just ident 7180 */
+	V4L2_IDENT_ADV7180 = 7180,
+
 	/* module saa7185: just ident 7185 */
 	V4L2_IDENT_SAA7185 = 7185,
 
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 33a1842..1c25b10 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -139,29 +139,23 @@ struct v4l2_subdev_ops;
 /* Load an i2c module and return an initialized v4l2_subdev struct.
    Only call request_module if module_name != NULL.
    The client_type argument is the name of the chip that's on the adapter. */
-struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
-		struct i2c_adapter *adapter,
-		const char *module_name, const char *client_type, u8 addr);
-/* Probe and load an i2c module and return an initialized v4l2_subdev struct.
-   Only call request_module if module_name != NULL.
-   The client_type argument is the name of the chip that's on the adapter. */
-struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
+struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
 		struct i2c_adapter *adapter,
 		const char *module_name, const char *client_type,
-		const unsigned short *addrs);
-/* Like v4l2_i2c_new_probed_subdev, except probe for a single address. */
-struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
-		struct i2c_adapter *adapter,
-		const char *module_name, const char *client_type, u8 addr);
+		int irq, void *platform_data,
+		u8 addr, const unsigned short *probe_addrs);
 
 /* Load an i2c module and return an initialized v4l2_subdev struct.
    Only call request_module if module_name != NULL.
    The client_type argument is the name of the chip that's on the adapter. */
-struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
+static inline struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
 		struct i2c_adapter *adapter,
 		const char *module_name, const char *client_type,
-		int irq, void *platform_data,
-		u8 addr, const unsigned short *probe_addrs);
+		u8 addr, const unsigned short *probe_addrs)
+{
+	return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, module_name,
+				client_type, 0, NULL, addr, probe_addrs);
+}
 
 struct i2c_board_info;
 
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 2058dd4..73c9867 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -100,8 +100,10 @@ struct video_device
 
    Also note that vdev->minor is set to -1 if the registration failed. */
 int __must_check video_register_device(struct video_device *vdev, int type, int nr);
-int __must_check video_register_device_index(struct video_device *vdev,
-						int type, int nr, int index);
+
+/* Same as video_register_device, but no warning is issued if the desired
+   device node number was already in use. */
+int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr);
 
 /* Unregister video devices. Will do nothing if vdev == NULL or
    vdev->minor < 0. */
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 5dcb367..d411345 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -137,6 +137,8 @@ struct v4l2_subdev_tuner_ops {
 	int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq);
 	int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
 	int (*s_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt);
+	int (*g_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
+	int (*s_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm);
 	int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type);
 	int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config);
 	int (*s_standby)(struct v4l2_subdev *sd);
@@ -220,6 +222,9 @@ struct v4l2_subdev_video_ops {
 	int (*g_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt);
 	int (*try_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt);
 	int (*s_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+	int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc);
+	int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop);
+	int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop);
 	int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
 	int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
 	int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 7b55ab2..0f7c378 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -143,6 +143,8 @@ extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr
 extern int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
 extern void ipv6_mc_up(struct inet6_dev *idev);
 extern void ipv6_mc_down(struct inet6_dev *idev);
+extern void ipv6_mc_unmap(struct inet6_dev *idev);
+extern void ipv6_mc_remap(struct inet6_dev *idev);
 extern void ipv6_mc_init_dev(struct inet6_dev *idev);
 extern void ipv6_mc_destroy_dev(struct inet6_dev *idev);
 extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
diff --git a/include/net/af_ieee802154.h b/include/net/af_ieee802154.h
new file mode 100644
index 0000000..75e64c7
--- /dev/null
+++ b/include/net/af_ieee802154.h
@@ -0,0 +1,62 @@
+/*
+ * IEEE 802.15.4 inteface for userspace
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef _AF_IEEE802154_H
+#define _AF_IEEE802154_H
+
+#include <linux/socket.h> /* for sa_family_t */
+
+enum {
+	IEEE802154_ADDR_NONE = 0x0,
+	/* RESERVED = 0x01, */
+	IEEE802154_ADDR_SHORT = 0x2, /* 16-bit address + PANid */
+	IEEE802154_ADDR_LONG = 0x3, /* 64-bit address + PANid */
+};
+
+/* address length, octets */
+#define IEEE802154_ADDR_LEN	8
+
+struct ieee802154_addr {
+	int addr_type;
+	u16 pan_id;
+	union {
+		u8 hwaddr[IEEE802154_ADDR_LEN];
+		u16 short_addr;
+	};
+};
+
+#define IEEE802154_PANID_BROADCAST	0xffff
+#define IEEE802154_ADDR_BROADCAST	0xffff
+#define IEEE802154_ADDR_UNDEF		0xfffe
+
+struct sockaddr_ieee802154 {
+	sa_family_t family; /* AF_IEEE802154 */
+	struct ieee802154_addr addr;
+};
+
+/* get/setsockopt */
+#define SOL_IEEE802154	0
+
+#define WPAN_WANTACK	0
+
+#endif
diff --git a/include/net/arp.h b/include/net/arp.h
index c236270..716f43c 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -26,6 +26,6 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
 				  const unsigned char *target_hw);
 extern void arp_xmit(struct sk_buff *skb);
 
-extern struct neigh_ops arp_broken_ops;
+extern const struct neigh_ops arp_broken_ops;
 
 #endif	/* _ARP_H */
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 968166a..718394e 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -138,8 +138,11 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
 struct bt_skb_cb {
 	__u8 pkt_type;
 	__u8 incoming;
+	__u8 tx_seq;
+	__u8 retries;
+	__u8 sar;
 };
-#define bt_cb(skb) ((struct bt_skb_cb *)(skb->cb)) 
+#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))
 
 static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)
 {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c4ca422..7b640ae 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -117,7 +117,7 @@ struct hci_dev {
 	struct sk_buff		*sent_cmd;
 	struct sk_buff		*reassembly[3];
 
-	struct semaphore	req_lock;
+	struct mutex		req_lock;
 	wait_queue_head_t	req_wait_q;
 	__u32			req_status;
 	__u32			req_result;
@@ -187,6 +187,7 @@ struct hci_conn {
 	struct work_struct work_del;
 
 	struct device	dev;
+	atomic_t	devref;
 
 	struct hci_dev	*hdev;
 	void		*l2cap_data;
@@ -339,6 +340,9 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
 void hci_conn_enter_active_mode(struct hci_conn *conn);
 void hci_conn_enter_sniff_mode(struct hci_conn *conn);
 
+void hci_conn_hold_device(struct hci_conn *conn);
+void hci_conn_put_device(struct hci_conn *conn);
+
 static inline void hci_conn_hold(struct hci_conn *conn)
 {
 	atomic_inc(&conn->refcnt);
@@ -700,8 +704,8 @@ struct hci_sec_filter {
 #define HCI_REQ_PEND	  1
 #define HCI_REQ_CANCELED  2
 
-#define hci_req_lock(d)		down(&d->req_lock)
-#define hci_req_unlock(d)	up(&d->req_lock)
+#define hci_req_lock(d)		mutex_lock(&d->req_lock)
+#define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
 
 void hci_req_complete(struct hci_dev *hdev, int result);
 
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index e919fca..9516f4b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -27,12 +27,14 @@
 
 /* L2CAP defaults */
 #define L2CAP_DEFAULT_MTU		672
+#define L2CAP_DEFAULT_MIN_MTU		48
 #define L2CAP_DEFAULT_FLUSH_TO		0xffff
-#define L2CAP_DEFAULT_RX_WINDOW		1
-#define L2CAP_DEFAULT_MAX_RECEIVE	1
-#define L2CAP_DEFAULT_RETRANS_TO	300    /* 300 milliseconds */
-#define L2CAP_DEFAULT_MONITOR_TO	1000   /* 1 second */
-#define L2CAP_DEFAULT_MAX_RX_APDU	0xfff7
+#define L2CAP_DEFAULT_TX_WINDOW		63
+#define L2CAP_DEFAULT_NUM_TO_ACK        (L2CAP_DEFAULT_TX_WINDOW/5)
+#define L2CAP_DEFAULT_MAX_TX		3
+#define L2CAP_DEFAULT_RETRANS_TO	1000    /* 1 second */
+#define L2CAP_DEFAULT_MONITOR_TO	12000   /* 12 seconds */
+#define L2CAP_DEFAULT_MAX_PDU_SIZE	672
 
 #define L2CAP_CONN_TIMEOUT	(40000) /* 40 seconds */
 #define L2CAP_INFO_TIMEOUT	(4000)  /*  4 seconds */
@@ -52,6 +54,7 @@ struct l2cap_options {
 	__u16 imtu;
 	__u16 flush_to;
 	__u8  mode;
+	__u8  fcs;
 };
 
 #define L2CAP_CONNINFO	0x02
@@ -93,6 +96,32 @@ struct l2cap_conninfo {
 #define L2CAP_FCS_NONE		0x00
 #define L2CAP_FCS_CRC16		0x01
 
+/* L2CAP Control Field bit masks */
+#define L2CAP_CTRL_SAR               0xC000
+#define L2CAP_CTRL_REQSEQ            0x3F00
+#define L2CAP_CTRL_TXSEQ             0x007E
+#define L2CAP_CTRL_RETRANS           0x0080
+#define L2CAP_CTRL_FINAL             0x0080
+#define L2CAP_CTRL_POLL              0x0010
+#define L2CAP_CTRL_SUPERVISE         0x000C
+#define L2CAP_CTRL_FRAME_TYPE        0x0001 /* I- or S-Frame */
+
+#define L2CAP_CTRL_TXSEQ_SHIFT      1
+#define L2CAP_CTRL_REQSEQ_SHIFT     8
+#define L2CAP_CTRL_SAR_SHIFT       14
+
+/* L2CAP Supervisory Function */
+#define L2CAP_SUPER_RCV_READY           0x0000
+#define L2CAP_SUPER_REJECT              0x0004
+#define L2CAP_SUPER_RCV_NOT_READY       0x0008
+#define L2CAP_SUPER_SELECT_REJECT       0x000C
+
+/* L2CAP Segmentation and Reassembly */
+#define L2CAP_SDU_UNSEGMENTED       0x0000
+#define L2CAP_SDU_START             0x4000
+#define L2CAP_SDU_END               0x8000
+#define L2CAP_SDU_CONTINUE          0xC000
+
 /* L2CAP structures */
 struct l2cap_hdr {
 	__le16     len;
@@ -190,7 +219,7 @@ struct l2cap_conf_rfc {
 #define L2CAP_MODE_RETRANS	0x01
 #define L2CAP_MODE_FLOWCTL	0x02
 #define L2CAP_MODE_ERTM		0x03
-#define L2CAP_MODE_STREAM	0x04
+#define L2CAP_MODE_STREAMING	0x04
 
 struct l2cap_disconn_req {
 	__le16     dcid;
@@ -261,6 +290,14 @@ struct l2cap_conn {
 
 /* ----- L2CAP channel and socket info ----- */
 #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
+#define TX_QUEUE(sk) (&l2cap_pi(sk)->tx_queue)
+#define SREJ_QUEUE(sk) (&l2cap_pi(sk)->srej_queue)
+#define SREJ_LIST(sk) (&l2cap_pi(sk)->srej_l.list)
+
+struct srej_list {
+	__u8	tx_seq;
+	struct list_head list;
+};
 
 struct l2cap_pinfo {
 	struct bt_sock	bt;
@@ -271,30 +308,97 @@ struct l2cap_pinfo {
 	__u16		imtu;
 	__u16		omtu;
 	__u16		flush_to;
-	__u8            sec_level;
+	__u8		mode;
+	__u8		num_conf_req;
+	__u8		num_conf_rsp;
+
+	__u8		fcs;
+	__u8		sec_level;
 	__u8		role_switch;
-	__u8            force_reliable;
+	__u8		force_reliable;
 
 	__u8		conf_req[64];
 	__u8		conf_len;
 	__u8		conf_state;
-	__u8		conf_retry;
+	__u8		conn_state;
+
+	__u8		next_tx_seq;
+	__u8		expected_ack_seq;
+	__u8		req_seq;
+	__u8		expected_tx_seq;
+	__u8		buffer_seq;
+	__u8		buffer_seq_srej;
+	__u8		srej_save_reqseq;
+	__u8		unacked_frames;
+	__u8		retry_count;
+	__u8		num_to_ack;
+	__u16		sdu_len;
+	__u16		partial_sdu_len;
+	struct sk_buff	*sdu;
 
 	__u8		ident;
 
+	__u8		remote_tx_win;
+	__u8		remote_max_tx;
+	__u16		retrans_timeout;
+	__u16		monitor_timeout;
+	__u16		max_pdu_size;
+
 	__le16		sport;
 
+	struct timer_list	retrans_timer;
+	struct timer_list	monitor_timer;
+	struct sk_buff_head	tx_queue;
+	struct sk_buff_head	srej_queue;
+	struct srej_list	srej_l;
 	struct l2cap_conn	*conn;
 	struct sock		*next_c;
 	struct sock		*prev_c;
 };
 
-#define L2CAP_CONF_REQ_SENT	0x01
-#define L2CAP_CONF_INPUT_DONE	0x02
-#define L2CAP_CONF_OUTPUT_DONE	0x04
-#define L2CAP_CONF_CONNECT_PEND	0x80
-
-#define L2CAP_CONF_MAX_RETRIES	2
+#define L2CAP_CONF_REQ_SENT       0x01
+#define L2CAP_CONF_INPUT_DONE     0x02
+#define L2CAP_CONF_OUTPUT_DONE    0x04
+#define L2CAP_CONF_MTU_DONE       0x08
+#define L2CAP_CONF_MODE_DONE      0x10
+#define L2CAP_CONF_CONNECT_PEND   0x20
+#define L2CAP_CONF_NO_FCS_RECV    0x40
+#define L2CAP_CONF_STATE2_DEVICE  0x80
+
+#define L2CAP_CONF_MAX_CONF_REQ 2
+#define L2CAP_CONF_MAX_CONF_RSP 2
+
+#define L2CAP_CONN_SAR_SDU         0x01
+#define L2CAP_CONN_SREJ_SENT       0x02
+#define L2CAP_CONN_WAIT_F          0x04
+#define L2CAP_CONN_SREJ_ACT        0x08
+#define L2CAP_CONN_SEND_PBIT       0x10
+#define L2CAP_CONN_REMOTE_BUSY     0x20
+#define L2CAP_CONN_LOCAL_BUSY      0x40
+
+#define __mod_retrans_timer() mod_timer(&l2cap_pi(sk)->retrans_timer, \
+		jiffies +  msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
+#define __mod_monitor_timer() mod_timer(&l2cap_pi(sk)->monitor_timer, \
+		jiffies + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
+
+static inline int l2cap_tx_window_full(struct sock *sk)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	int sub;
+
+	sub = (pi->next_tx_seq - pi->expected_ack_seq) % 64;
+
+	if (sub < 0)
+		sub += 64;
+
+	return (sub == pi->remote_tx_win);
+}
+
+#define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1
+#define __get_reqseq(ctrl) ((ctrl) & L2CAP_CTRL_REQSEQ) >> 8
+#define __is_iframe(ctrl) !((ctrl) & L2CAP_CTRL_FRAME_TYPE)
+#define __is_sframe(ctrl) (ctrl) & L2CAP_CTRL_FRAME_TYPE
+#define __is_sar_start(ctrl) ((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START
 
 void l2cap_load(void);
 
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index c274993..921d7b3 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -29,6 +29,7 @@
 #define RFCOMM_CONN_TIMEOUT (HZ * 30)
 #define RFCOMM_DISC_TIMEOUT (HZ * 20)
 #define RFCOMM_AUTH_TIMEOUT (HZ * 25)
+#define RFCOMM_IDLE_TIMEOUT (HZ * 2)
 
 #define RFCOMM_DEFAULT_MTU	127
 #define RFCOMM_DEFAULT_CREDITS	7
@@ -154,6 +155,7 @@ struct rfcomm_msc {
 struct rfcomm_session {
 	struct list_head list;
 	struct socket   *sock;
+	struct timer_list timer;
 	unsigned long    state;
 	unsigned long    flags;
 	atomic_t         refcnt;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d1892d6..3d874c6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -80,7 +80,6 @@ enum ieee80211_channel_flags {
  * with cfg80211.
  *
  * @center_freq: center frequency in MHz
- * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz
  * @hw_value: hardware-specific value for the channel
  * @flags: channel flags from &enum ieee80211_channel_flags.
  * @orig_flags: channel flags at registration time, used by regulatory
@@ -97,7 +96,6 @@ enum ieee80211_channel_flags {
 struct ieee80211_channel {
 	enum ieee80211_band band;
 	u16 center_freq;
-	u8 max_bandwidth;
 	u16 hw_value;
 	u32 flags;
 	int max_antenna_gain;
@@ -372,6 +370,10 @@ struct rate_info {
  * @txrate: current unicast bitrate to this station
  * @rx_packets: packets received from this station
  * @tx_packets: packets transmitted to this station
+ * @generation: generation number for nl80211 dumps.
+ *	This number should increase every time the list of stations
+ *	changes, i.e. when a station is added or removed, so that
+ *	userspace can tell whether it got a consistent snapshot.
  */
 struct station_info {
 	u32 filled;
@@ -385,6 +387,8 @@ struct station_info {
 	struct rate_info txrate;
 	u32 rx_packets;
 	u32 tx_packets;
+
+	int generation;
 };
 
 /**
@@ -444,6 +448,10 @@ enum mpath_info_flags {
  * @flags: mesh path flags
  * @discovery_timeout: total mesh path discovery timeout, in msecs
  * @discovery_retries: mesh path discovery retries
+ * @generation: generation number for nl80211 dumps.
+ *	This number should increase every time the list of mesh paths
+ *	changes, i.e. when a station is added or removed, so that
+ *	userspace can tell whether it got a consistent snapshot.
  */
 struct mpath_info {
 	u32 filled;
@@ -454,6 +462,8 @@ struct mpath_info {
 	u32 discovery_timeout;
 	u8 discovery_retries;
 	u8 flags;
+
+	int generation;
 };
 
 /**
@@ -538,23 +548,26 @@ struct cfg80211_ssid {
  * @ssids: SSIDs to scan for (active scan only)
  * @n_ssids: number of SSIDs
  * @channels: channels to scan on.
- * @n_channels: number of channels for each band
+ * @n_channels: total number of channels to scan
  * @ie: optional information element(s) to add into Probe Request or %NULL
  * @ie_len: length of ie in octets
  * @wiphy: the wiphy this was for
- * @ifidx: the interface index
+ * @dev: the interface
  */
 struct cfg80211_scan_request {
 	struct cfg80211_ssid *ssids;
 	int n_ssids;
-	struct ieee80211_channel **channels;
 	u32 n_channels;
 	const u8 *ie;
 	size_t ie_len;
 
 	/* internal */
 	struct wiphy *wiphy;
-	int ifidx;
+	struct net_device *dev;
+	bool aborted;
+
+	/* keep last */
+	struct ieee80211_channel *channels[0];
 };
 
 /**
@@ -584,7 +597,6 @@ enum cfg80211_signal_type {
  *	is no guarantee that these are well-formed!)
  * @len_information_elements: total length of the information elements
  * @signal: signal strength value (type depends on the wiphy's signal_type)
- * @hold: BSS should not expire
  * @free_priv: function pointer to free private data
  * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
  */
@@ -605,37 +617,59 @@ struct cfg80211_bss {
 };
 
 /**
+ * ieee80211_bss_get_ie - find IE with given ID
+ * @bss: the bss to search
+ * @ie: the IE ID
+ * Returns %NULL if not found.
+ */
+const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
+
+
+/**
+ * struct cfg80211_crypto_settings - Crypto settings
+ * @wpa_versions: indicates which, if any, WPA versions are enabled
+ *	(from enum nl80211_wpa_versions)
+ * @cipher_group: group key cipher suite (or 0 if unset)
+ * @n_ciphers_pairwise: number of AP supported unicast ciphers
+ * @ciphers_pairwise: unicast key cipher suites
+ * @n_akm_suites: number of AKM suites
+ * @akm_suites: AKM suites
+ * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
+ *	sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
+ *	required to assume that the port is unauthorized until authorized by
+ *	user space. Otherwise, port is marked authorized by default.
+ */
+struct cfg80211_crypto_settings {
+	u32 wpa_versions;
+	u32 cipher_group;
+	int n_ciphers_pairwise;
+	u32 ciphers_pairwise[NL80211_MAX_NR_CIPHER_SUITES];
+	int n_akm_suites;
+	u32 akm_suites[NL80211_MAX_NR_AKM_SUITES];
+	bool control_port;
+};
+
+/**
  * struct cfg80211_auth_request - Authentication request data
  *
  * This structure provides information needed to complete IEEE 802.11
  * authentication.
- * NOTE: This structure will likely change when more code from mac80211 is
- * moved into cfg80211 so that non-mac80211 drivers can benefit from it, too.
- * Before using this in a driver that does not use mac80211, it would be better
- * to check the status of that work and better yet, volunteer to work on it.
- *
- * @chan: The channel to use or %NULL if not specified (auto-select based on
- *	scan results)
- * @peer_addr: The address of the peer STA (AP BSSID in infrastructure case);
- *	this field is required to be present; if the driver wants to help with
- *	BSS selection, it should use (yet to be added) MLME event to allow user
- *	space SME to be notified of roaming candidate, so that the SME can then
- *	use the authentication request with the recommended BSSID and whatever
- *	other data may be needed for authentication/association
- * @ssid: SSID or %NULL if not yet available
- * @ssid_len: Length of ssid in octets
+ *
+ * @bss: The BSS to authenticate with.
  * @auth_type: Authentication type (algorithm)
  * @ie: Extra IEs to add to Authentication frame or %NULL
  * @ie_len: Length of ie buffer in octets
+ * @key_len: length of WEP key for shared key authentication
+ * @key_idx: index of WEP key for shared key authentication
+ * @key: WEP key for shared key authentication
  */
 struct cfg80211_auth_request {
-	struct ieee80211_channel *chan;
-	u8 *peer_addr;
-	const u8 *ssid;
-	size_t ssid_len;
-	enum nl80211_auth_type auth_type;
+	struct cfg80211_bss *bss;
 	const u8 *ie;
 	size_t ie_len;
+	enum nl80211_auth_type auth_type;
+	const u8 *key;
+	u8 key_len, key_idx;
 };
 
 /**
@@ -643,35 +677,19 @@ struct cfg80211_auth_request {
  *
  * This structure provides information needed to complete IEEE 802.11
  * (re)association.
- * NOTE: This structure will likely change when more code from mac80211 is
- * moved into cfg80211 so that non-mac80211 drivers can benefit from it, too.
- * Before using this in a driver that does not use mac80211, it would be better
- * to check the status of that work and better yet, volunteer to work on it.
- *
- * @chan: The channel to use or %NULL if not specified (auto-select based on
- *	scan results)
- * @peer_addr: The address of the peer STA (AP BSSID); this field is required
- *	to be present and the STA must be in State 2 (authenticated) with the
- *	peer STA
- * @ssid: SSID
- * @ssid_len: Length of ssid in octets
+ * @bss: The BSS to associate with.
  * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
  * @ie_len: Length of ie buffer in octets
  * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
- * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
- *	sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
- *	required to assume that the port is unauthorized until authorized by
- *	user space. Otherwise, port is marked authorized by default.
+ * @crypto: crypto settings
+ * @prev_bssid: previous BSSID, if not %NULL use reassociate frame
  */
 struct cfg80211_assoc_request {
-	struct ieee80211_channel *chan;
-	u8 *peer_addr;
-	const u8 *ssid;
-	size_t ssid_len;
-	const u8 *ie;
+	struct cfg80211_bss *bss;
+	const u8 *ie, *prev_bssid;
 	size_t ie_len;
+	struct cfg80211_crypto_settings crypto;
 	bool use_mfp;
-	bool control_port;
 };
 
 /**
@@ -680,16 +698,16 @@ struct cfg80211_assoc_request {
  * This structure provides information needed to complete IEEE 802.11
  * deauthentication.
  *
- * @peer_addr: The address of the peer STA (AP BSSID); this field is required
- *	to be present and the STA must be authenticated with the peer STA
+ * @bss: the BSS to deauthenticate from
  * @ie: Extra IEs to add to Deauthentication frame or %NULL
  * @ie_len: Length of ie buffer in octets
+ * @reason_code: The reason code for the deauthentication
  */
 struct cfg80211_deauth_request {
-	u8 *peer_addr;
-	u16 reason_code;
+	struct cfg80211_bss *bss;
 	const u8 *ie;
 	size_t ie_len;
+	u16 reason_code;
 };
 
 /**
@@ -698,16 +716,16 @@ struct cfg80211_deauth_request {
  * This structure provides information needed to complete IEEE 802.11
  * disassocation.
  *
- * @peer_addr: The address of the peer STA (AP BSSID); this field is required
- *	to be present and the STA must be associated with the peer STA
+ * @bss: the BSS to disassociate from
  * @ie: Extra IEs to add to Disassociation frame or %NULL
  * @ie_len: Length of ie buffer in octets
+ * @reason_code: The reason code for the disassociation
  */
 struct cfg80211_disassoc_request {
-	u8 *peer_addr;
-	u16 reason_code;
+	struct cfg80211_bss *bss;
 	const u8 *ie;
 	size_t ie_len;
+	u16 reason_code;
 };
 
 /**
@@ -726,6 +744,8 @@ struct cfg80211_disassoc_request {
  * @ie: information element(s) to include in the beacon
  * @ie_len: length of that
  * @beacon_interval: beacon interval to use
+ * @privacy: this is a protected network, keys will be configured
+ *	after joining
  */
 struct cfg80211_ibss_params {
 	u8 *ssid;
@@ -735,6 +755,42 @@ struct cfg80211_ibss_params {
 	u8 ssid_len, ie_len;
 	u16 beacon_interval;
 	bool channel_fixed;
+	bool privacy;
+};
+
+/**
+ * struct cfg80211_connect_params - Connection parameters
+ *
+ * This structure provides information needed to complete IEEE 802.11
+ * authentication and association.
+ *
+ * @channel: The channel to use or %NULL if not specified (auto-select based
+ *	on scan results)
+ * @bssid: The AP BSSID or %NULL if not specified (auto-select based on scan
+ *	results)
+ * @ssid: SSID
+ * @ssid_len: Length of ssid in octets
+ * @auth_type: Authentication type (algorithm)
+ * @assoc_ie: IEs for association request
+ * @assoc_ie_len: Length of assoc_ie in octets
+ * @privacy: indicates whether privacy-enabled APs should be used
+ * @crypto: crypto settings
+ * @key_len: length of WEP key for shared key authentication
+ * @key_idx: index of WEP key for shared key authentication
+ * @key: WEP key for shared key authentication
+ */
+struct cfg80211_connect_params {
+	struct ieee80211_channel *channel;
+	u8 *bssid;
+	u8 *ssid;
+	size_t ssid_len;
+	enum nl80211_auth_type auth_type;
+	u8 *ie;
+	size_t ie_len;
+	bool privacy;
+	struct cfg80211_crypto_settings crypto;
+	const u8 *key;
+	u8 key_len, key_idx;
 };
 
 /**
@@ -764,6 +820,26 @@ enum tx_power_setting {
 	TX_POWER_FIXED,
 };
 
+/*
+ * cfg80211_bitrate_mask - masks for bitrate control
+ */
+struct cfg80211_bitrate_mask {
+/*
+ * As discussed in Berlin, this struct really
+ * should look like this:
+
+	struct {
+		u32 legacy;
+		u8 mcs[IEEE80211_HT_MCS_MASK_LEN];
+	} control[IEEE80211_NUM_BANDS];
+
+ * Since we can always fix in-kernel users, let's keep
+ * it simpler for now:
+ */
+	u32 fixed;   /* fixed bitrate, 0 == not fixed */
+	u32 maxrate; /* in kbps, 0 == no limit */
+};
+
 /**
  * struct cfg80211_ops - backend description for wireless configuration
  *
@@ -781,7 +857,8 @@ enum tx_power_setting {
  * @resume: wiphy device needs to be resumed
  *
  * @add_virtual_intf: create a new virtual interface with the given name,
- *	must set the struct wireless_dev's iftype.
+ *	must set the struct wireless_dev's iftype. Beware: You must create
+ *	the new netdev in the wiphy's network namespace!
  *
  * @del_virtual_intf: remove the virtual interface determined by ifindex.
  *
@@ -841,6 +918,12 @@ enum tx_power_setting {
  * @deauth: Request to deauthenticate from the specified peer
  * @disassoc: Request to disassociate from the specified peer
  *
+ * @connect: Connect to the ESS with the specified parameters. When connected,
+ *	call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
+ *	If the connection fails for some reason, call cfg80211_connect_result()
+ *	with the status from the AP.
+ * @disconnect: Disconnect from the BSS/ESS.
+ *
  * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
  *	cfg80211_ibss_joined(), also call that function when changing BSSID due
  *	to a merge.
@@ -857,6 +940,8 @@ enum tx_power_setting {
  *
  * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
  *	functions to adjust rfkill hw state
+ *
+ * @testmode_cmd: run a test mode command
  */
 struct cfg80211_ops {
 	int	(*suspend)(struct wiphy *wiphy);
@@ -865,8 +950,9 @@ struct cfg80211_ops {
 	int	(*add_virtual_intf)(struct wiphy *wiphy, char *name,
 				    enum nl80211_iftype type, u32 *flags,
 				    struct vif_params *params);
-	int	(*del_virtual_intf)(struct wiphy *wiphy, int ifindex);
-	int	(*change_virtual_intf)(struct wiphy *wiphy, int ifindex,
+	int	(*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev);
+	int	(*change_virtual_intf)(struct wiphy *wiphy,
+				       struct net_device *dev,
 				       enum nl80211_iftype type, u32 *flags,
 				       struct vif_params *params);
 
@@ -939,9 +1025,16 @@ struct cfg80211_ops {
 	int	(*assoc)(struct wiphy *wiphy, struct net_device *dev,
 			 struct cfg80211_assoc_request *req);
 	int	(*deauth)(struct wiphy *wiphy, struct net_device *dev,
-			  struct cfg80211_deauth_request *req);
+			  struct cfg80211_deauth_request *req,
+			  void *cookie);
 	int	(*disassoc)(struct wiphy *wiphy, struct net_device *dev,
-			    struct cfg80211_disassoc_request *req);
+			    struct cfg80211_disassoc_request *req,
+			    void *cookie);
+
+	int	(*connect)(struct wiphy *wiphy, struct net_device *dev,
+			   struct cfg80211_connect_params *sme);
+	int	(*disconnect)(struct wiphy *wiphy, struct net_device *dev,
+			      u16 reason_code);
 
 	int	(*join_ibss)(struct wiphy *wiphy, struct net_device *dev,
 			     struct cfg80211_ibss_params *params);
@@ -953,7 +1046,23 @@ struct cfg80211_ops {
 				enum tx_power_setting type, int dbm);
 	int	(*get_tx_power)(struct wiphy *wiphy, int *dbm);
 
+	int	(*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
+				u8 *addr);
+
 	void	(*rfkill_poll)(struct wiphy *wiphy);
+
+#ifdef CONFIG_NL80211_TESTMODE
+	int	(*testmode_cmd)(struct wiphy *wiphy, void *data, int len);
+#endif
+
+	int	(*set_bitrate_mask)(struct wiphy *wiphy,
+				    struct net_device *dev,
+				    const u8 *peer,
+				    const struct cfg80211_bitrate_mask *mask);
+
+	/* some temporary stuff to finish wext */
+	int	(*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,
+				  bool enabled, int timeout);
 };
 
 /*
@@ -996,6 +1105,12 @@ struct cfg80211_ops {
  * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold);
  *	-1 = fragmentation disabled, only odd values >= 256 used
  * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled
+ * @net: the network namespace this wiphy currently lives in
+ * @netnsok: if set to false, do not allow changing the netns of this
+ *	wiphy at all
+ * @ps_default: default for powersave, will be set depending on the
+ *	kernel's default on wiphy_new(), but can be changed by the
+ *	driver if it has a good reason to override the default
  */
 struct wiphy {
 	/* assign these fields before you register the wiphy */
@@ -1010,6 +1125,9 @@ struct wiphy {
 	bool strict_regulatory;
 	bool disable_beacon_hints;
 
+	bool netnsok;
+	bool ps_default;
+
 	enum cfg80211_signal_type signal_type;
 
 	int bss_priv_size;
@@ -1048,9 +1166,35 @@ struct wiphy {
 	/* dir in debugfs: ieee80211/<wiphyname> */
 	struct dentry *debugfsdir;
 
+#ifdef CONFIG_NET_NS
+	/* the network namespace this phy lives in currently */
+	struct net *_net;
+#endif
+
 	char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
 };
 
+#ifdef CONFIG_NET_NS
+static inline struct net *wiphy_net(struct wiphy *wiphy)
+{
+	return wiphy->_net;
+}
+
+static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net)
+{
+	wiphy->_net = net;
+}
+#else
+static inline struct net *wiphy_net(struct wiphy *wiphy)
+{
+	return &init_net;
+}
+
+static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net)
+{
+}
+#endif
+
 /**
  * wiphy_priv - return priv from wiphy
  *
@@ -1063,6 +1207,17 @@ static inline void *wiphy_priv(struct wiphy *wiphy)
 }
 
 /**
+ * priv_to_wiphy - return the wiphy containing the priv
+ *
+ * @priv: a pointer previously returned by wiphy_priv
+ */
+static inline struct wiphy *priv_to_wiphy(void *priv)
+{
+	BUG_ON(!priv);
+	return container_of(priv, struct wiphy, priv);
+}
+
+/**
  * set_wiphy_dev - set device pointer for wiphy
  *
  * @wiphy: The wiphy whose device to bind
@@ -1134,6 +1289,13 @@ extern void wiphy_unregister(struct wiphy *wiphy);
  */
 extern void wiphy_free(struct wiphy *wiphy);
 
+/* internal structs */
+struct cfg80211_conn;
+struct cfg80211_internal_bss;
+struct cfg80211_cached_keys;
+
+#define MAX_AUTH_BSSES		4
+
 /**
  * struct wireless_dev - wireless per-netdev state
  *
@@ -1157,22 +1319,45 @@ struct wireless_dev {
 	struct wiphy *wiphy;
 	enum nl80211_iftype iftype;
 
-	/* private to the generic wireless code */
+	/* the remainder of this struct should be private to cfg80211 */
 	struct list_head list;
 	struct net_device *netdev;
 
-	/* currently used for IBSS - might be rearranged in the future */
-	struct cfg80211_bss *current_bss;
-	u8 bssid[ETH_ALEN];
+	struct mutex mtx;
+
+	struct work_struct cleanup_work;
+
+	/* currently used for IBSS and SME - might be rearranged later */
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	u8 ssid_len;
+	enum {
+		CFG80211_SME_IDLE,
+		CFG80211_SME_CONNECTING,
+		CFG80211_SME_CONNECTED,
+	} sme_state;
+	struct cfg80211_conn *conn;
+	struct cfg80211_cached_keys *connect_keys;
+
+	struct list_head event_list;
+	spinlock_t event_lock;
+
+	struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
+	struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
+	struct cfg80211_internal_bss *current_bss; /* associated / joined */
 
 #ifdef CONFIG_WIRELESS_EXT
 	/* wext data */
 	struct {
 		struct cfg80211_ibss_params ibss;
-		u8 bssid[ETH_ALEN];
+		struct cfg80211_connect_params connect;
+		struct cfg80211_cached_keys *keys;
+		u8 *ie;
+		size_t ie_len;
+		u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
+		u8 ssid[IEEE80211_MAX_SSID_LEN];
 		s8 default_key, default_mgmt_key;
+		bool ps, prev_bssid_valid;
+		int ps_timeout;
 	} wext;
 #endif
 };
@@ -1352,20 +1537,6 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb);
 extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
 
 /**
- * regulatory_hint_11d - hints a country IE as a regulatory domain
- * @wiphy: the wireless device giving the hint (used only for reporting
- *	conflicts)
- * @country_ie: pointer to the country IE
- * @country_ie_len: length of the country IE
- *
- * We will intersect the rd with the what CRDA tells us should apply
- * for the alpha2 this country IE belongs to, this prevents APs from
- * sending us incorrect or outdated information against a country.
- */
-extern void regulatory_hint_11d(struct wiphy *wiphy,
-				u8 *country_ie,
-				u8 country_ie_len);
-/**
  * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
  * @wiphy: the wireless device we want to process the regulatory domain on
  * @regd: the custom regulatory domain to use for this wiphy
@@ -1433,27 +1604,34 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
 int cfg80211_wext_giwrange(struct net_device *dev,
 			   struct iw_request_info *info,
 			   struct iw_point *data, char *extra);
-int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_freq *freq, char *extra);
-int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
-			       struct iw_request_info *info,
-			       struct iw_freq *freq, char *extra);
-int cfg80211_ibss_wext_siwessid(struct net_device *dev,
-				struct iw_request_info *info,
-				struct iw_point *data, char *ssid);
-int cfg80211_ibss_wext_giwessid(struct net_device *dev,
-				struct iw_request_info *info,
-				struct iw_point *data, char *ssid);
-int cfg80211_ibss_wext_siwap(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct sockaddr *ap_addr, char *extra);
-int cfg80211_ibss_wext_giwap(struct net_device *dev,
-			     struct iw_request_info *info,
-			     struct sockaddr *ap_addr, char *extra);
+int cfg80211_wext_siwgenie(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *extra);
+int cfg80211_wext_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra);
+int cfg80211_wext_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra);
 
-struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
-					     struct iw_freq *freq);
+int cfg80211_wext_siwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *freq, char *extra);
+int cfg80211_wext_giwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *freq, char *extra);
+int cfg80211_wext_siwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid);
+int cfg80211_wext_giwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid);
+int cfg80211_wext_siwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra);
+int cfg80211_wext_giwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra);
 
 int cfg80211_wext_siwrts(struct net_device *dev,
 			 struct iw_request_info *info,
@@ -1488,6 +1666,21 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
 int cfg80211_wext_giwtxpower(struct net_device *dev,
 			     struct iw_request_info *info,
 			     union iwreq_data *data, char *keybuf);
+struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev);
+
+int cfg80211_wext_siwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra);
+int cfg80211_wext_giwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra);
+
+int cfg80211_wext_siwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra);
+int cfg80211_wext_giwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra);
 
 /*
  * callbacks for asynchronous cfg80211 methods, notification
@@ -1569,7 +1762,7 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
  * This function is called whenever an authentication has been processed in
  * station mode. The driver is required to call either this function or
  * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
- * call.
+ * call. This function may sleep.
  */
 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
 
@@ -1577,6 +1770,8 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
  * cfg80211_send_auth_timeout - notification of timed out authentication
  * @dev: network device
  * @addr: The MAC address of the device with which the authentication timed out
+ *
+ * This function may sleep.
  */
 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
 
@@ -1589,7 +1784,7 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
  * This function is called whenever a (re)association response has been
  * processed in station mode. The driver is required to call either this
  * function or cfg80211_send_assoc_timeout() to indicate the result of
- * cfg80211_ops::assoc() call.
+ * cfg80211_ops::assoc() call. This function may sleep.
  */
 void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
 
@@ -1597,6 +1792,8 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
  * cfg80211_send_assoc_timeout - notification of timed out association
  * @dev: network device
  * @addr: The MAC address of the device with which the association timed out
+ *
+ * This function may sleep.
  */
 void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
 
@@ -1605,41 +1802,30 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
  * @dev: network device
  * @buf: deauthentication frame (header + body)
  * @len: length of the frame data
+ * @cookie: cookie from ->deauth if called within that callback,
+ *	%NULL otherwise
  *
  * This function is called whenever deauthentication has been processed in
  * station mode. This includes both received deauthentication frames and
- * locally generated ones.
+ * locally generated ones. This function may sleep.
  */
-void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len,
+			  void *cookie);
 
 /**
  * cfg80211_send_disassoc - notification of processed disassociation
  * @dev: network device
  * @buf: disassociation response frame (header + body)
  * @len: length of the frame data
+ * @cookie: cookie from ->disassoc if called within that callback,
+ *	%NULL otherwise
  *
  * This function is called whenever disassociation has been processed in
  * station mode. This includes both received disassociation frames and locally
- * generated ones.
- */
-void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);
-
-/**
- * cfg80211_hold_bss - exclude bss from expiration
- * @bss: bss which should not expire
- *
- * In a case when the BSS is not updated but it shouldn't expire this
- * function can be used to mark the BSS to be excluded from expiration.
- */
-void cfg80211_hold_bss(struct cfg80211_bss *bss);
-
-/**
- * cfg80211_unhold_bss - remove expiration exception from the BSS
- * @bss: bss which can expire again
- *
- * This function marks the BSS to be expirable again.
+ * generated ones. This function may sleep.
  */
-void cfg80211_unhold_bss(struct cfg80211_bss *bss);
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len,
+			    void *cookie);
 
 /**
  * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
@@ -1648,6 +1834,7 @@ void cfg80211_unhold_bss(struct cfg80211_bss *bss);
  * @key_type: The key type that the received frame used
  * @key_id: Key identifier (0..3)
  * @tsc: The TSC value of the frame that generated the MIC failure (6 octets)
+ * @gfp: allocation flags
  *
  * This function is called whenever the local MAC detects a MIC failure in a
  * received frame. This matches with MLME-MICHAELMICFAILURE.indication()
@@ -1655,7 +1842,7 @@ void cfg80211_unhold_bss(struct cfg80211_bss *bss);
  */
 void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
 				  enum nl80211_key_type key_type, int key_id,
-				  const u8 *tsc);
+				  const u8 *tsc, gfp_t gfp);
 
 /**
  * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS
@@ -1692,4 +1879,137 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy);
  */
 void wiphy_rfkill_stop_polling(struct wiphy *wiphy);
 
+#ifdef CONFIG_NL80211_TESTMODE
+/**
+ * cfg80211_testmode_alloc_reply_skb - allocate testmode reply
+ * @wiphy: the wiphy
+ * @approxlen: an upper bound of the length of the data that will
+ *	be put into the skb
+ *
+ * This function allocates and pre-fills an skb for a reply to
+ * the testmode command. Since it is intended for a reply, calling
+ * it outside of the @testmode_cmd operation is invalid.
+ *
+ * The returned skb (or %NULL if any errors happen) is pre-filled
+ * with the wiphy index and set up in a way that any data that is
+ * put into the skb (with skb_put(), nla_put() or similar) will end
+ * up being within the %NL80211_ATTR_TESTDATA attribute, so all that
+ * needs to be done with the skb is adding data for the corresponding
+ * userspace tool which can then read that data out of the testdata
+ * attribute. You must not modify the skb in any other way.
+ *
+ * When done, call cfg80211_testmode_reply() with the skb and return
+ * its error code as the result of the @testmode_cmd operation.
+ */
+struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
+						  int approxlen);
+
+/**
+ * cfg80211_testmode_reply - send the reply skb
+ * @skb: The skb, must have been allocated with
+ *	cfg80211_testmode_alloc_reply_skb()
+ *
+ * Returns an error code or 0 on success, since calling this
+ * function will usually be the last thing before returning
+ * from the @testmode_cmd you should return the error code.
+ * Note that this function consumes the skb regardless of the
+ * return value.
+ */
+int cfg80211_testmode_reply(struct sk_buff *skb);
+
+/**
+ * cfg80211_testmode_alloc_event_skb - allocate testmode event
+ * @wiphy: the wiphy
+ * @approxlen: an upper bound of the length of the data that will
+ *	be put into the skb
+ * @gfp: allocation flags
+ *
+ * This function allocates and pre-fills an skb for an event on the
+ * testmode multicast group.
+ *
+ * The returned skb (or %NULL if any errors happen) is set up in the
+ * same way as with cfg80211_testmode_alloc_reply_skb() but prepared
+ * for an event. As there, you should simply add data to it that will
+ * then end up in the %NL80211_ATTR_TESTDATA attribute. Again, you must
+ * not modify the skb in any other way.
+ *
+ * When done filling the skb, call cfg80211_testmode_event() with the
+ * skb to send the event.
+ */
+struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
+						  int approxlen, gfp_t gfp);
+
+/**
+ * cfg80211_testmode_event - send the event
+ * @skb: The skb, must have been allocated with
+ *	cfg80211_testmode_alloc_event_skb()
+ * @gfp: allocation flags
+ *
+ * This function sends the given @skb, which must have been allocated
+ * by cfg80211_testmode_alloc_event_skb(), as an event. It always
+ * consumes it.
+ */
+void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp);
+
+#define CFG80211_TESTMODE_CMD(cmd)	.testmode_cmd = (cmd),
+#else
+#define CFG80211_TESTMODE_CMD(cmd)
+#endif
+
+/**
+ * cfg80211_connect_result - notify cfg80211 of connection result
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the AP
+ * @req_ie: association request IEs (maybe be %NULL)
+ * @req_ie_len: association request IEs length
+ * @resp_ie: association response IEs (may be %NULL)
+ * @resp_ie_len: assoc response IEs length
+ * @status: status code, 0 for successful connection, use
+ *	%WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
+ *	the real status code for failures.
+ * @gfp: allocation flags
+ *
+ * It should be called by the underlying driver whenever connect() has
+ * succeeded.
+ */
+void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			     const u8 *req_ie, size_t req_ie_len,
+			     const u8 *resp_ie, size_t resp_ie_len,
+			     u16 status, gfp_t gfp);
+
+/**
+ * cfg80211_roamed - notify cfg80211 of roaming
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the new AP
+ * @req_ie: association request IEs (maybe be %NULL)
+ * @req_ie_len: association request IEs length
+ * @resp_ie: association response IEs (may be %NULL)
+ * @resp_ie_len: assoc response IEs length
+ * @gfp: allocation flags
+ *
+ * It should be called by the underlying driver whenever it roamed
+ * from one AP to another while connected.
+ */
+void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
+		     const u8 *req_ie, size_t req_ie_len,
+		     const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
+
+/**
+ * cfg80211_disconnected - notify cfg80211 that connection was dropped
+ *
+ * @dev: network device
+ * @ie: information elements of the deauth/disassoc frame (may be %NULL)
+ * @ie_len: length of IEs
+ * @reason: reason code for the disconnection, set it to 0 if unknown
+ * @gfp: allocation flags
+ *
+ * After it calls this function, the driver should enter an idle state
+ * and not try to connect to any AP any more.
+ */
+void cfg80211_disconnected(struct net_device *dev, u16 reason,
+			   u8 *ie, size_t ie_len, gfp_t gfp);
+
+
 #endif /* __NET_CFG80211_H */
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h
index 775cfc8..b36ac7e 100644
--- a/include/net/dcbnl.h
+++ b/include/net/dcbnl.h
@@ -48,6 +48,8 @@ struct dcbnl_rtnl_ops {
 	void (*setbcncfg)(struct net_device *, int, u32);
 	void (*getbcnrp)(struct net_device *, int, u8 *);
 	void (*setbcnrp)(struct net_device *, int, u8);
+	u8   (*setapp)(struct net_device *, u8, u16, u8);
+	u8   (*getapp)(struct net_device *, u8, u16);
 };
 
 #endif /* __NET_DCBNL_H__ */
diff --git a/include/net/dst.h b/include/net/dst.h
index 7fc409c..5a900dd 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -8,6 +8,7 @@
 #ifndef _NET_DST_H
 #define _NET_DST_H
 
+#include <net/dst_ops.h>
 #include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/rcupdate.h>
@@ -102,28 +103,6 @@ struct dst_entry
 	};
 };
 
-
-struct dst_ops
-{
-	unsigned short		family;
-	__be16			protocol;
-	unsigned		gc_thresh;
-
-	int			(*gc)(struct dst_ops *ops);
-	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
-	void			(*destroy)(struct dst_entry *);
-	void			(*ifdown)(struct dst_entry *,
-					  struct net_device *dev, int how);
-	struct dst_entry *	(*negative_advice)(struct dst_entry *);
-	void			(*link_failure)(struct sk_buff *);
-	void			(*update_pmtu)(struct dst_entry *dst, u32 mtu);
-	int			(*local_out)(struct sk_buff *skb);
-
-	atomic_t		entries;
-	struct kmem_cache 		*kmem_cachep;
-	struct net              *dst_net;
-};
-
 #ifdef __KERNEL__
 
 static inline u32
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
new file mode 100644
index 0000000..d1ff9b7
--- /dev/null
+++ b/include/net/dst_ops.h
@@ -0,0 +1,28 @@
+#ifndef _NET_DST_OPS_H
+#define _NET_DST_OPS_H
+#include <linux/types.h>
+
+struct dst_entry;
+struct kmem_cachep;
+struct net_device;
+struct sk_buff;
+
+struct dst_ops {
+	unsigned short		family;
+	__be16			protocol;
+	unsigned		gc_thresh;
+
+	int			(*gc)(struct dst_ops *ops);
+	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
+	void			(*destroy)(struct dst_entry *);
+	void			(*ifdown)(struct dst_entry *,
+					  struct net_device *dev, int how);
+	struct dst_entry *	(*negative_advice)(struct dst_entry *);
+	void			(*link_failure)(struct sk_buff *);
+	void			(*update_pmtu)(struct dst_entry *dst, u32 mtu);
+	int			(*local_out)(struct sk_buff *skb);
+
+	atomic_t		entries;
+	struct kmem_cache	*kmem_cachep;
+};
+#endif
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 1b0e3ee..2a1c068 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -3,6 +3,7 @@
 
 #include <linux/genetlink.h>
 #include <net/netlink.h>
+#include <net/net_namespace.h>
 
 /**
  * struct genl_multicast_group - generic netlink multicast group
@@ -27,6 +28,8 @@ struct genl_multicast_group
  * @name: name of family
  * @version: protocol version
  * @maxattr: maximum number of attributes supported
+ * @netnsok: set to true if the family can handle network
+ *	namespaces and should be presented in all of them
  * @attrbuf: buffer to store parsed attributes
  * @ops_list: list of all assigned operations
  * @family_list: family list
@@ -39,6 +42,7 @@ struct genl_family
 	char			name[GENL_NAMSIZ];
 	unsigned int		version;
 	unsigned int		maxattr;
+	bool			netnsok;
 	struct nlattr **	attrbuf;	/* private */
 	struct list_head	ops_list;	/* private */
 	struct list_head	family_list;	/* private */
@@ -62,8 +66,32 @@ struct genl_info
 	struct genlmsghdr *	genlhdr;
 	void *			userhdr;
 	struct nlattr **	attrs;
+#ifdef CONFIG_NET_NS
+	struct net *		_net;
+#endif
 };
 
+#ifdef CONFIG_NET_NS
+static inline struct net *genl_info_net(struct genl_info *info)
+{
+	return info->_net;
+}
+
+static inline void genl_info_net_set(struct genl_info *info, struct net *net)
+{
+	info->_net = net;
+}
+#else
+static inline struct net *genl_info_net(struct genl_info *info)
+{
+	return &init_net;
+}
+
+static inline void genl_info_net_set(struct genl_info *info, struct net *net)
+{
+}
+#endif
+
 /**
  * struct genl_ops - generic netlink operations
  * @cmd: command identifier
@@ -98,8 +126,6 @@ extern int genl_register_mc_group(struct genl_family *family,
 extern void genl_unregister_mc_group(struct genl_family *family,
 				     struct genl_multicast_group *grp);
 
-extern struct sock *genl_sock;
-
 /**
  * genlmsg_put - Add generic netlink header to netlink message
  * @skb: socket buffer holding the message
@@ -170,7 +196,21 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
 }
 
 /**
- * genlmsg_multicast - multicast a netlink message
+ * genlmsg_multicast_netns - multicast a netlink message to a specific netns
+ * @net: the net namespace
+ * @skb: netlink message as socket buffer
+ * @pid: own netlink pid to avoid sending to yourself
+ * @group: multicast group id
+ * @flags: allocation flags
+ */
+static inline int genlmsg_multicast_netns(struct net *net, struct sk_buff *skb,
+					  u32 pid, unsigned int group, gfp_t flags)
+{
+	return nlmsg_multicast(net->genl_sock, skb, pid, group, flags);
+}
+
+/**
+ * genlmsg_multicast - multicast a netlink message to the default netns
  * @skb: netlink message as socket buffer
  * @pid: own netlink pid to avoid sending to yourself
  * @group: multicast group id
@@ -179,17 +219,29 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
 static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
 				    unsigned int group, gfp_t flags)
 {
-	return nlmsg_multicast(genl_sock, skb, pid, group, flags);
+	return genlmsg_multicast_netns(&init_net, skb, pid, group, flags);
 }
 
 /**
+ * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
+ * @skb: netlink message as socket buffer
+ * @pid: own netlink pid to avoid sending to yourself
+ * @group: multicast group id
+ * @flags: allocation flags
+ *
+ * This function must hold the RTNL or rcu_read_lock().
+ */
+int genlmsg_multicast_allns(struct sk_buff *skb, u32 pid,
+			    unsigned int group, gfp_t flags);
+
+/**
  * genlmsg_unicast - unicast a netlink message
  * @skb: netlink message as socket buffer
  * @pid: netlink pid of the destination socket
  */
-static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
+static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 pid)
 {
-	return nlmsg_unicast(genl_sock, skb, pid);
+	return nlmsg_unicast(net->genl_sock, skb, pid);
 }
 
 /**
@@ -199,7 +251,7 @@ static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid)
  */
 static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
 {
-	return genlmsg_unicast(skb, info->snd_pid);
+	return genlmsg_unicast(genl_info_net(info), skb, info->snd_pid);
 }
 
 /**
diff --git a/include/net/ieee802154.h b/include/net/ieee802154.h
new file mode 100644
index 0000000..d52685d
--- /dev/null
+++ b/include/net/ieee802154.h
@@ -0,0 +1,160 @@
+/*
+ * IEEE802.15.4-2003 specification
+ *
+ * Copyright (C) 2007, 2008 Siemens AG
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
+ * Maxim Osipov <maxim.osipov@siemens.com>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef NET_IEEE802154_H
+#define NET_IEEE802154_H
+
+#define IEEE802154_FC_TYPE_BEACON	0x0	/* Frame is beacon */
+#define	IEEE802154_FC_TYPE_DATA		0x1	/* Frame is data */
+#define IEEE802154_FC_TYPE_ACK		0x2	/* Frame is acknowledgment */
+#define IEEE802154_FC_TYPE_MAC_CMD	0x3	/* Frame is MAC command */
+
+#define IEEE802154_FC_TYPE_SHIFT		0
+#define IEEE802154_FC_TYPE_MASK		((1 << 3) - 1)
+#define IEEE802154_FC_TYPE(x)		((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT)
+#define IEEE802154_FC_SET_TYPE(v, x)	do {	\
+	v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \
+	    (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \
+	} while (0)
+
+#define IEEE802154_FC_SECEN		(1 << 3)
+#define IEEE802154_FC_FRPEND		(1 << 4)
+#define IEEE802154_FC_ACK_REQ		(1 << 5)
+#define IEEE802154_FC_INTRA_PAN		(1 << 6)
+
+#define IEEE802154_FC_SAMODE_SHIFT	14
+#define IEEE802154_FC_SAMODE_MASK	(3 << IEEE802154_FC_SAMODE_SHIFT)
+#define IEEE802154_FC_DAMODE_SHIFT	10
+#define IEEE802154_FC_DAMODE_MASK	(3 << IEEE802154_FC_DAMODE_SHIFT)
+
+#define IEEE802154_FC_SAMODE(x)		\
+	(((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT)
+
+#define IEEE802154_FC_DAMODE(x)		\
+	(((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT)
+
+
+/* MAC's Command Frames Identifiers */
+#define IEEE802154_CMD_ASSOCIATION_REQ		0x01
+#define IEEE802154_CMD_ASSOCIATION_RESP		0x02
+#define IEEE802154_CMD_DISASSOCIATION_NOTIFY	0x03
+#define IEEE802154_CMD_DATA_REQ			0x04
+#define IEEE802154_CMD_PANID_CONFLICT_NOTIFY	0x05
+#define IEEE802154_CMD_ORPHAN_NOTIFY		0x06
+#define IEEE802154_CMD_BEACON_REQ		0x07
+#define IEEE802154_CMD_COORD_REALIGN_NOTIFY	0x08
+#define IEEE802154_CMD_GTS_REQ			0x09
+
+/*
+ * The return values of MAC operations
+ */
+enum {
+	/*
+	 * The requested operation was completed successfully.
+	 * For a transmission request, this value indicates
+	 * a successful transmission.
+	 */
+	IEEE802154_SUCCESS = 0x0,
+
+	/* The beacon was lost following a synchronization request. */
+	IEEE802154_BEACON_LOSS = 0xe0,
+	/*
+	 * A transmission could not take place due to activity on the
+	 * channel, i.e., the CSMA-CA mechanism has failed.
+	 */
+	IEEE802154_CHNL_ACCESS_FAIL = 0xe1,
+	/* The GTS request has been denied by the PAN coordinator. */
+	IEEE802154_DENINED = 0xe2,
+	/* The attempt to disable the transceiver has failed. */
+	IEEE802154_DISABLE_TRX_FAIL = 0xe3,
+	/*
+	 * The received frame induces a failed security check according to
+	 * the security suite.
+	 */
+	IEEE802154_FAILED_SECURITY_CHECK = 0xe4,
+	/*
+	 * The frame resulting from secure processing has a length that is
+	 * greater than aMACMaxFrameSize.
+	 */
+	IEEE802154_FRAME_TOO_LONG = 0xe5,
+	/*
+	 * The requested GTS transmission failed because the specified GTS
+	 * either did not have a transmit GTS direction or was not defined.
+	 */
+	IEEE802154_INVALID_GTS = 0xe6,
+	/*
+	 * A request to purge an MSDU from the transaction queue was made using
+	 * an MSDU handle that was not found in the transaction table.
+	 */
+	IEEE802154_INVALID_HANDLE = 0xe7,
+	/* A parameter in the primitive is out of the valid range.*/
+	IEEE802154_INVALID_PARAMETER = 0xe8,
+	/* No acknowledgment was received after aMaxFrameRetries. */
+	IEEE802154_NO_ACK = 0xe9,
+	/* A scan operation failed to find any network beacons.*/
+	IEEE802154_NO_BEACON = 0xea,
+	/* No response data were available following a request. */
+	IEEE802154_NO_DATA = 0xeb,
+	/* The operation failed because a short address was not allocated. */
+	IEEE802154_NO_SHORT_ADDRESS = 0xec,
+	/*
+	 * A receiver enable request was unsuccessful because it could not be
+	 * completed within the CAP.
+	 */
+	IEEE802154_OUT_OF_CAP = 0xed,
+	/*
+	 * A PAN identifier conflict has been detected and communicated to the
+	 * PAN coordinator.
+	 */
+	IEEE802154_PANID_CONFLICT = 0xee,
+	/* A coordinator realignment command has been received. */
+	IEEE802154_REALIGMENT = 0xef,
+	/* The transaction has expired and its information discarded. */
+	IEEE802154_TRANSACTION_EXPIRED = 0xf0,
+	/* There is no capacity to store the transaction. */
+	IEEE802154_TRANSACTION_OVERFLOW = 0xf1,
+	/*
+	 * The transceiver was in the transmitter enabled state when the
+	 * receiver was requested to be enabled.
+	 */
+	IEEE802154_TX_ACTIVE = 0xf2,
+	/* The appropriate key is not available in the ACL. */
+	IEEE802154_UNAVAILABLE_KEY = 0xf3,
+	/*
+	 * A SET/GET request was issued with the identifier of a PIB attribute
+	 * that is not supported.
+	 */
+	IEEE802154_UNSUPPORTED_ATTR = 0xf4,
+	/*
+	 * A request to perform a scan operation failed because the MLME was
+	 * in the process of performing a previously initiated scan operation.
+	 */
+	IEEE802154_SCAN_IN_PROGRESS = 0xfc,
+};
+
+
+#endif
+
+
diff --git a/include/net/ieee802154/af_ieee802154.h b/include/net/ieee802154/af_ieee802154.h
deleted file mode 100644
index 0d78605..0000000
--- a/include/net/ieee802154/af_ieee802154.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * IEEE 802.15.4 inteface for userspace
- *
- * Copyright 2007, 2008 Siemens AG
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Written by:
- * Sergey Lapin <slapin@ossfans.org>
- * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
- */
-
-#ifndef _AF_IEEE802154_H
-#define _AF_IEEE802154_H
-
-#include <linux/socket.h> /* for sa_family_t */
-
-enum {
-	IEEE802154_ADDR_NONE = 0x0,
-	/* RESERVED = 0x01, */
-	IEEE802154_ADDR_SHORT = 0x2, /* 16-bit address + PANid */
-	IEEE802154_ADDR_LONG = 0x3, /* 64-bit address + PANid */
-};
-
-/* address length, octets */
-#define IEEE802154_ADDR_LEN	8
-
-struct ieee802154_addr {
-	int addr_type;
-	u16 pan_id;
-	union {
-		u8 hwaddr[IEEE802154_ADDR_LEN];
-		u16 short_addr;
-	};
-};
-
-#define IEEE802154_PANID_BROADCAST	0xffff
-#define IEEE802154_ADDR_BROADCAST	0xffff
-#define IEEE802154_ADDR_UNDEF		0xfffe
-
-struct sockaddr_ieee802154 {
-	sa_family_t family; /* AF_IEEE802154 */
-	struct ieee802154_addr addr;
-};
-
-/* master device */
-#define IEEE802154_SIOC_ADD_SLAVE		(SIOCDEVPRIVATE + 0)
-
-#endif
diff --git a/include/net/ieee802154/mac_def.h b/include/net/ieee802154/mac_def.h
deleted file mode 100644
index 8cb6846..0000000
--- a/include/net/ieee802154/mac_def.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * IEEE802.15.4-2003 specification
- *
- * Copyright (C) 2007, 2008 Siemens AG
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Written by:
- * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
- * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
- * Maxim Osipov <maxim.osipov@siemens.com>
- * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
- */
-
-#ifndef IEEE802154_MAC_DEF_H
-#define IEEE802154_MAC_DEF_H
-
-#define IEEE802154_FC_TYPE_BEACON	0x0	/* Frame is beacon */
-#define	IEEE802154_FC_TYPE_DATA		0x1	/* Frame is data */
-#define IEEE802154_FC_TYPE_ACK		0x2	/* Frame is acknowledgment */
-#define IEEE802154_FC_TYPE_MAC_CMD	0x3	/* Frame is MAC command */
-
-#define IEEE802154_FC_TYPE_SHIFT		0
-#define IEEE802154_FC_TYPE_MASK		((1 << 3) - 1)
-#define IEEE802154_FC_TYPE(x)		((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT)
-#define IEEE802154_FC_SET_TYPE(v, x)	do {	\
-	v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \
-	    (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \
-	} while (0)
-
-#define IEEE802154_FC_SECEN		(1 << 3)
-#define IEEE802154_FC_FRPEND		(1 << 4)
-#define IEEE802154_FC_ACK_REQ		(1 << 5)
-#define IEEE802154_FC_INTRA_PAN		(1 << 6)
-
-#define IEEE802154_FC_SAMODE_SHIFT	14
-#define IEEE802154_FC_SAMODE_MASK	(3 << IEEE802154_FC_SAMODE_SHIFT)
-#define IEEE802154_FC_DAMODE_SHIFT	10
-#define IEEE802154_FC_DAMODE_MASK	(3 << IEEE802154_FC_DAMODE_SHIFT)
-
-#define IEEE802154_FC_SAMODE(x)		\
-	(((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT)
-
-#define IEEE802154_FC_DAMODE(x)		\
-	(((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT)
-
-
-/* MAC's Command Frames Identifiers */
-#define IEEE802154_CMD_ASSOCIATION_REQ		0x01
-#define IEEE802154_CMD_ASSOCIATION_RESP		0x02
-#define IEEE802154_CMD_DISASSOCIATION_NOTIFY	0x03
-#define IEEE802154_CMD_DATA_REQ			0x04
-#define IEEE802154_CMD_PANID_CONFLICT_NOTIFY	0x05
-#define IEEE802154_CMD_ORPHAN_NOTIFY		0x06
-#define IEEE802154_CMD_BEACON_REQ		0x07
-#define IEEE802154_CMD_COORD_REALIGN_NOTIFY	0x08
-#define IEEE802154_CMD_GTS_REQ			0x09
-
-/*
- * The return values of MAC operations
- */
-enum {
-	/*
-	 * The requested operation was completed successfully.
-	 * For a transmission request, this value indicates
-	 * a successful transmission.
-	 */
-	IEEE802154_SUCCESS = 0x0,
-
-	/* The beacon was lost following a synchronization request. */
-	IEEE802154_BEACON_LOSS = 0xe0,
-	/*
-	 * A transmission could not take place due to activity on the
-	 * channel, i.e., the CSMA-CA mechanism has failed.
-	 */
-	IEEE802154_CHNL_ACCESS_FAIL = 0xe1,
-	/* The GTS request has been denied by the PAN coordinator. */
-	IEEE802154_DENINED = 0xe2,
-	/* The attempt to disable the transceiver has failed. */
-	IEEE802154_DISABLE_TRX_FAIL = 0xe3,
-	/*
-	 * The received frame induces a failed security check according to
-	 * the security suite.
-	 */
-	IEEE802154_FAILED_SECURITY_CHECK = 0xe4,
-	/*
-	 * The frame resulting from secure processing has a length that is
-	 * greater than aMACMaxFrameSize.
-	 */
-	IEEE802154_FRAME_TOO_LONG = 0xe5,
-	/*
-	 * The requested GTS transmission failed because the specified GTS
-	 * either did not have a transmit GTS direction or was not defined.
-	 */
-	IEEE802154_INVALID_GTS = 0xe6,
-	/*
-	 * A request to purge an MSDU from the transaction queue was made using
-	 * an MSDU handle that was not found in the transaction table.
-	 */
-	IEEE802154_INVALID_HANDLE = 0xe7,
-	/* A parameter in the primitive is out of the valid range.*/
-	IEEE802154_INVALID_PARAMETER = 0xe8,
-	/* No acknowledgment was received after aMaxFrameRetries. */
-	IEEE802154_NO_ACK = 0xe9,
-	/* A scan operation failed to find any network beacons.*/
-	IEEE802154_NO_BEACON = 0xea,
-	/* No response data were available following a request. */
-	IEEE802154_NO_DATA = 0xeb,
-	/* The operation failed because a short address was not allocated. */
-	IEEE802154_NO_SHORT_ADDRESS = 0xec,
-	/*
-	 * A receiver enable request was unsuccessful because it could not be
-	 * completed within the CAP.
-	 */
-	IEEE802154_OUT_OF_CAP = 0xed,
-	/*
-	 * A PAN identifier conflict has been detected and communicated to the
-	 * PAN coordinator.
-	 */
-	IEEE802154_PANID_CONFLICT = 0xee,
-	/* A coordinator realignment command has been received. */
-	IEEE802154_REALIGMENT = 0xef,
-	/* The transaction has expired and its information discarded. */
-	IEEE802154_TRANSACTION_EXPIRED = 0xf0,
-	/* There is no capacity to store the transaction. */
-	IEEE802154_TRANSACTION_OVERFLOW = 0xf1,
-	/*
-	 * The transceiver was in the transmitter enabled state when the
-	 * receiver was requested to be enabled.
-	 */
-	IEEE802154_TX_ACTIVE = 0xf2,
-	/* The appropriate key is not available in the ACL. */
-	IEEE802154_UNAVAILABLE_KEY = 0xf3,
-	/*
-	 * A SET/GET request was issued with the identifier of a PIB attribute
-	 * that is not supported.
-	 */
-	IEEE802154_UNSUPPORTED_ATTR = 0xf4,
-	/*
-	 * A request to perform a scan operation failed because the MLME was
-	 * in the process of performing a previously initiated scan operation.
-	 */
-	IEEE802154_SCAN_IN_PROGRESS = 0xfc,
-};
-
-
-#endif
-
-
diff --git a/include/net/ieee802154/netdevice.h b/include/net/ieee802154/netdevice.h
deleted file mode 100644
index e2506af..0000000
--- a/include/net/ieee802154/netdevice.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * An interface between IEEE802.15.4 device and rest of the kernel.
- *
- * Copyright (C) 2007, 2008, 2009 Siemens AG
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Written by:
- * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
- * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
- * Maxim Osipov <maxim.osipov@siemens.com>
- * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
- */
-
-#ifndef IEEE802154_NETDEVICE_H
-#define IEEE802154_NETDEVICE_H
-
-/*
- * A control block of skb passed between the ARPHRD_IEEE802154 device
- * and other stack parts.
- */
-struct ieee802154_mac_cb {
-	u8 lqi;
-	struct ieee802154_addr sa;
-	struct ieee802154_addr da;
-	u8 flags;
-	u8 seq;
-};
-
-static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
-{
-	return (struct ieee802154_mac_cb *)skb->cb;
-}
-
-#define MAC_CB_FLAG_TYPEMASK		((1 << 3) - 1)
-
-#define MAC_CB_FLAG_ACKREQ		(1 << 3)
-#define MAC_CB_FLAG_SECEN		(1 << 4)
-#define MAC_CB_FLAG_INTRAPAN		(1 << 5)
-
-static inline int mac_cb_is_ackreq(struct sk_buff *skb)
-{
-	return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ;
-}
-
-static inline int mac_cb_is_secen(struct sk_buff *skb)
-{
-	return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN;
-}
-
-static inline int mac_cb_is_intrapan(struct sk_buff *skb)
-{
-	return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN;
-}
-
-static inline int mac_cb_type(struct sk_buff *skb)
-{
-	return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK;
-}
-
-#define IEEE802154_MAC_SCAN_ED		0
-#define IEEE802154_MAC_SCAN_ACTIVE	1
-#define IEEE802154_MAC_SCAN_PASSIVE	2
-#define IEEE802154_MAC_SCAN_ORPHAN	3
-
-/*
- * This should be located at net_device->ml_priv
- */
-struct ieee802154_mlme_ops {
-	int (*assoc_req)(struct net_device *dev,
-			struct ieee802154_addr *addr,
-			u8 channel, u8 cap);
-	int (*assoc_resp)(struct net_device *dev,
-			struct ieee802154_addr *addr,
-			u16 short_addr, u8 status);
-	int (*disassoc_req)(struct net_device *dev,
-			struct ieee802154_addr *addr,
-			u8 reason);
-	int (*start_req)(struct net_device *dev,
-			struct ieee802154_addr *addr,
-			u8 channel, u8 bcn_ord, u8 sf_ord,
-			u8 pan_coord, u8 blx, u8 coord_realign);
-	int (*scan_req)(struct net_device *dev,
-			u8 type, u32 channels, u8 duration);
-
-	/*
-	 * FIXME: these should become the part of PIB/MIB interface.
-	 * However we still don't have IB interface of any kind
-	 */
-	u16 (*get_pan_id)(struct net_device *dev);
-	u16 (*get_short_addr)(struct net_device *dev);
-	u8 (*get_dsn)(struct net_device *dev);
-	u8 (*get_bsn)(struct net_device *dev);
-};
-
-static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
-		struct net_device *dev)
-{
-	return dev->ml_priv;
-}
-
-#endif
-
-
diff --git a/include/net/ieee802154/nl802154.h b/include/net/ieee802154/nl802154.h
deleted file mode 100644
index 78efcdf..0000000
--- a/include/net/ieee802154/nl802154.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * nl802154.h
- *
- * Copyright (C) 2007, 2008, 2009 Siemens AG
- *
- * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef IEEE802154_NL_H
-#define IEEE802154_NL_H
-
-struct net_device;
-struct ieee802154_addr;
-
-int ieee802154_nl_assoc_indic(struct net_device *dev,
-		struct ieee802154_addr *addr, u8 cap);
-int ieee802154_nl_assoc_confirm(struct net_device *dev,
-		u16 short_addr, u8 status);
-int ieee802154_nl_disassoc_indic(struct net_device *dev,
-		struct ieee802154_addr *addr, u8 reason);
-int ieee802154_nl_disassoc_confirm(struct net_device *dev,
-		u8 status);
-int ieee802154_nl_scan_confirm(struct net_device *dev,
-		u8 status, u8 scan_type, u32 unscanned,
-		u8 *edl/*, struct list_head *pan_desc_list */);
-int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid,
-		u16 coord_addr);
-
-#endif
diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h
new file mode 100644
index 0000000..5dc6a61
--- /dev/null
+++ b/include/net/ieee802154_netdev.h
@@ -0,0 +1,115 @@
+/*
+ * An interface between IEEE802.15.4 device and rest of the kernel.
+ *
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
+ * Maxim Osipov <maxim.osipov@siemens.com>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef IEEE802154_NETDEVICE_H
+#define IEEE802154_NETDEVICE_H
+
+/*
+ * A control block of skb passed between the ARPHRD_IEEE802154 device
+ * and other stack parts.
+ */
+struct ieee802154_mac_cb {
+	u8 lqi;
+	struct ieee802154_addr sa;
+	struct ieee802154_addr da;
+	u8 flags;
+	u8 seq;
+};
+
+static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
+{
+	return (struct ieee802154_mac_cb *)skb->cb;
+}
+
+#define MAC_CB_FLAG_TYPEMASK		((1 << 3) - 1)
+
+#define MAC_CB_FLAG_ACKREQ		(1 << 3)
+#define MAC_CB_FLAG_SECEN		(1 << 4)
+#define MAC_CB_FLAG_INTRAPAN		(1 << 5)
+
+static inline int mac_cb_is_ackreq(struct sk_buff *skb)
+{
+	return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ;
+}
+
+static inline int mac_cb_is_secen(struct sk_buff *skb)
+{
+	return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN;
+}
+
+static inline int mac_cb_is_intrapan(struct sk_buff *skb)
+{
+	return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN;
+}
+
+static inline int mac_cb_type(struct sk_buff *skb)
+{
+	return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK;
+}
+
+#define IEEE802154_MAC_SCAN_ED		0
+#define IEEE802154_MAC_SCAN_ACTIVE	1
+#define IEEE802154_MAC_SCAN_PASSIVE	2
+#define IEEE802154_MAC_SCAN_ORPHAN	3
+
+/*
+ * This should be located at net_device->ml_priv
+ */
+struct ieee802154_mlme_ops {
+	int (*assoc_req)(struct net_device *dev,
+			struct ieee802154_addr *addr,
+			u8 channel, u8 page, u8 cap);
+	int (*assoc_resp)(struct net_device *dev,
+			struct ieee802154_addr *addr,
+			u16 short_addr, u8 status);
+	int (*disassoc_req)(struct net_device *dev,
+			struct ieee802154_addr *addr,
+			u8 reason);
+	int (*start_req)(struct net_device *dev,
+			struct ieee802154_addr *addr,
+			u8 channel, u8 page, u8 bcn_ord, u8 sf_ord,
+			u8 pan_coord, u8 blx, u8 coord_realign);
+	int (*scan_req)(struct net_device *dev,
+			u8 type, u32 channels, u8 page, u8 duration);
+
+	/*
+	 * FIXME: these should become the part of PIB/MIB interface.
+	 * However we still don't have IB interface of any kind
+	 */
+	u16 (*get_pan_id)(struct net_device *dev);
+	u16 (*get_short_addr)(struct net_device *dev);
+	u8 (*get_dsn)(struct net_device *dev);
+	u8 (*get_bsn)(struct net_device *dev);
+};
+
+static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
+		struct net_device *dev)
+{
+	return dev->ml_priv;
+}
+
+#endif
+
+
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 7c5c0f7..15b492a 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -22,6 +22,12 @@
 #include <net/flow.h>
 #include <net/netlink.h>
 
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+#define FIB6_TABLE_HASHSZ 256
+#else
+#define FIB6_TABLE_HASHSZ 1
+#endif
+
 struct rt6_info;
 
 struct fib6_config
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index bbae1e8..98978e7 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -99,47 +99,47 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
 	return &buf[*idx - len];
 }
 
-#define IP_VS_DBG_BUF(level, msg...)			\
-    do {						\
-	    char ip_vs_dbg_buf[160];			\
-	    int ip_vs_dbg_idx = 0;			\
-	    if (level <= ip_vs_get_debug_level())	\
-		    printk(KERN_DEBUG "IPVS: " msg);	\
-    } while (0)
-#define IP_VS_ERR_BUF(msg...)				\
-    do {						\
-	    char ip_vs_dbg_buf[160];			\
-	    int ip_vs_dbg_idx = 0;			\
-	    printk(KERN_ERR "IPVS: " msg);		\
-    } while (0)
+#define IP_VS_DBG_BUF(level, msg, ...)					\
+	do {								\
+		char ip_vs_dbg_buf[160];				\
+		int ip_vs_dbg_idx = 0;					\
+		if (level <= ip_vs_get_debug_level())			\
+			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
+	} while (0)
+#define IP_VS_ERR_BUF(msg...)						\
+	do {								\
+		char ip_vs_dbg_buf[160];				\
+		int ip_vs_dbg_idx = 0;					\
+		pr_err(msg);						\
+	} while (0)
 
 /* Only use from within IP_VS_DBG_BUF() or IP_VS_ERR_BUF macros */
-#define IP_VS_DBG_ADDR(af, addr)			\
-    ip_vs_dbg_addr(af, ip_vs_dbg_buf,			\
-		   sizeof(ip_vs_dbg_buf), addr,		\
-		   &ip_vs_dbg_idx)
-
-#define IP_VS_DBG(level, msg...)			\
-    do {						\
-	    if (level <= ip_vs_get_debug_level())	\
-		    printk(KERN_DEBUG "IPVS: " msg);	\
-    } while (0)
-#define IP_VS_DBG_RL(msg...)				\
-    do {						\
-	    if (net_ratelimit())			\
-		    printk(KERN_DEBUG "IPVS: " msg);	\
-    } while (0)
-#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)		\
-    do {						\
-	    if (level <= ip_vs_get_debug_level())	\
-		pp->debug_packet(pp, skb, ofs, msg);	\
-    } while (0)
-#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)	\
-    do {						\
-	    if (level <= ip_vs_get_debug_level() &&	\
-		net_ratelimit())			\
-		pp->debug_packet(pp, skb, ofs, msg);	\
-    } while (0)
+#define IP_VS_DBG_ADDR(af, addr)					\
+	ip_vs_dbg_addr(af, ip_vs_dbg_buf,				\
+		       sizeof(ip_vs_dbg_buf), addr,			\
+		       &ip_vs_dbg_idx)
+
+#define IP_VS_DBG(level, msg, ...)					\
+	do {								\
+		if (level <= ip_vs_get_debug_level())			\
+			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
+	} while (0)
+#define IP_VS_DBG_RL(msg, ...)						\
+	do {								\
+		if (net_ratelimit())					\
+			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
+	} while (0)
+#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)				\
+	do {								\
+		if (level <= ip_vs_get_debug_level())			\
+			pp->debug_packet(pp, skb, ofs, msg);		\
+	} while (0)
+#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)			\
+	do {								\
+		if (level <= ip_vs_get_debug_level() &&			\
+		    net_ratelimit())					\
+			pp->debug_packet(pp, skb, ofs, msg);		\
+	} while (0)
 #else	/* NO DEBUGGING at ALL */
 #define IP_VS_DBG_BUF(level, msg...)  do {} while (0)
 #define IP_VS_ERR_BUF(msg...)  do {} while (0)
@@ -150,29 +150,27 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
 #endif
 
 #define IP_VS_BUG() BUG()
-#define IP_VS_ERR(msg...) printk(KERN_ERR "IPVS: " msg)
-#define IP_VS_INFO(msg...) printk(KERN_INFO "IPVS: " msg)
-#define IP_VS_WARNING(msg...) \
-	printk(KERN_WARNING "IPVS: " msg)
-#define IP_VS_ERR_RL(msg...)				\
-    do {						\
-	    if (net_ratelimit())			\
-		    printk(KERN_ERR "IPVS: " msg);	\
-    } while (0)
+#define IP_VS_ERR_RL(msg, ...)						\
+	do {								\
+		if (net_ratelimit())					\
+			pr_err(msg, ##__VA_ARGS__);			\
+	} while (0)
 
 #ifdef CONFIG_IP_VS_DEBUG
 #define EnterFunction(level)						\
-    do {								\
-	    if (level <= ip_vs_get_debug_level())			\
-		    printk(KERN_DEBUG "Enter: %s, %s line %i\n",	\
-			   __func__, __FILE__, __LINE__);		\
-    } while (0)
-#define LeaveFunction(level)                                            \
-    do {                                                                \
-	    if (level <= ip_vs_get_debug_level())                       \
-			printk(KERN_DEBUG "Leave: %s, %s line %i\n",    \
-			       __func__, __FILE__, __LINE__);       \
-    } while (0)
+	do {								\
+		if (level <= ip_vs_get_debug_level())			\
+			printk(KERN_DEBUG				\
+			       pr_fmt("Enter: %s, %s line %i\n"),	\
+			       __func__, __FILE__, __LINE__);		\
+	} while (0)
+#define LeaveFunction(level)						\
+	do {								\
+		if (level <= ip_vs_get_debug_level())			\
+			printk(KERN_DEBUG				\
+			       pr_fmt("Leave: %s, %s line %i\n"),	\
+			       __func__, __FILE__, __LINE__);		\
+	} while (0)
 #else
 #define EnterFunction(level)   do {} while (0)
 #define LeaveFunction(level)   do {} while (0)
@@ -740,7 +738,8 @@ extern void ip_vs_protocol_cleanup(void);
 extern void ip_vs_protocol_timeout_change(int flags);
 extern int *ip_vs_create_timeout_table(int *table, int size);
 extern int
-ip_vs_set_state_timeout(int *table, int num, char **names, char *name, int to);
+ip_vs_set_state_timeout(int *table, int num, const char *const *names,
+			const char *name, int to);
 extern void
 ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
 			  int offset, const char *msg);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index f27fd83..ad9a511 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -441,6 +441,18 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
 	return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
 }
 
+static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr)
+{
+	static u32 ipv6_fragmentation_id = 1;
+	static DEFINE_SPINLOCK(ip6_id_lock);
+
+	spin_lock_bh(&ip6_id_lock);
+	fhdr->identification = htonl(ipv6_fragmentation_id);
+	if (++ipv6_fragmentation_id == 0)
+		ipv6_fragmentation_id = 1;
+	spin_unlock_bh(&ip6_id_lock);
+}
+
 /*
  *	Prototypes exported by ipv6
  */
diff --git a/include/net/irda/ircomm_event.h b/include/net/irda/ircomm_event.h
index c290447..bc0c6f3 100644
--- a/include/net/irda/ircomm_event.h
+++ b/include/net/irda/ircomm_event.h
@@ -74,7 +74,7 @@ struct ircomm_info {
 	struct qos_info *qos;
 };
 
-extern char *ircomm_state[];
+extern const char *const ircomm_state[];
 
 struct ircomm_cb;   /* Forward decl. */
 
diff --git a/include/net/irda/ircomm_tty_attach.h b/include/net/irda/ircomm_tty_attach.h
index f91a569..0a63bbb 100644
--- a/include/net/irda/ircomm_tty_attach.h
+++ b/include/net/irda/ircomm_tty_attach.h
@@ -66,8 +66,8 @@ struct ircomm_tty_info {
         __u8      dlsap_sel;
 };
 
-extern char *ircomm_state[];
-extern char *ircomm_tty_state[];
+extern const char *const ircomm_state[];
+extern const char *const ircomm_tty_state[];
 
 int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
 			struct sk_buff *skb, struct ircomm_tty_info *info);
diff --git a/include/net/irda/irlap_event.h b/include/net/irda/irlap_event.h
index 2ae2e11..4c90824 100644
--- a/include/net/irda/irlap_event.h
+++ b/include/net/irda/irlap_event.h
@@ -120,7 +120,7 @@ typedef enum { /* FIXME check the two first reason codes */
 	LAP_PRIMARY_CONFLICT,
 } LAP_REASON;
 
-extern const char *irlap_state[];
+extern const char *const irlap_state[];
 
 void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event, 
 		    struct sk_buff *skb, struct irlap_info *info);
diff --git a/include/net/irda/irlmp_event.h b/include/net/irda/irlmp_event.h
index e03ae4a..9e4ec17 100644
--- a/include/net/irda/irlmp_event.h
+++ b/include/net/irda/irlmp_event.h
@@ -79,8 +79,8 @@ typedef enum {
 	LM_LAP_IDLE_TIMEOUT,
 } IRLMP_EVENT;
 
-extern const char *irlmp_state[];
-extern const char *irlsap_state[];
+extern const char *const irlmp_state[];
+extern const char *const irlsap_state[];
 
 void irlmp_watchdog_timer_expired(void *data);
 void irlmp_discovery_timer_expired(void *data);
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index 51b9a37..e9054a2 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -416,13 +416,13 @@ struct iw_spy_data
  * data (i.e. valid as long as struct net_device exist, same locking rules).
  */
 /* Forward declaration */
-struct ieee80211_device;
+struct libipw_device;
 /* The struct */
 struct iw_public_data {
 	/* Driver enhanced spy support */
 	struct iw_spy_data *		spy_data;
-	/* Structure managed by the in-kernel IEEE 802.11 layer */
-	struct ieee80211_device *	ieee80211;
+	/* Legacy structure managed by the ipw2x00-specific IEEE 802.11 layer */
+	struct libipw_device *		libipw;
 };
 
 /**************************** PROTOTYPES ****************************/
@@ -443,7 +443,7 @@ extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
 extern void wireless_send_event(struct net_device *	dev,
 				unsigned int		cmd,
 				union iwreq_data *	wrqu,
-				char *			extra);
+				const char *		extra);
 
 /* We may need a function to send a stream of events to user space.
  * More on that later... */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index c061044..466859b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -73,6 +73,21 @@
  */
 
 /**
+ * DOC: mac80211 workqueue
+ *
+ * mac80211 provides its own workqueue for drivers and internal mac80211 use.
+ * The workqueue is a single threaded workqueue and can only be accessed by
+ * helpers for sanity checking. Drivers must ensure all work added onto the
+ * mac80211 workqueue should be cancelled on the driver stop() callback.
+ *
+ * mac80211 will flushed the workqueue upon interface removal and during
+ * suspend.
+ *
+ * All work performed on the mac80211 workqueue must not acquire the RTNL lock.
+ *
+ */
+
+/**
  * enum ieee80211_max_queues - maximum number of queues
  *
  * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
@@ -224,7 +239,14 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU
  * @IEEE80211_TX_CTL_INJECTED: Frame was injected, internal to mac80211.
  * @IEEE80211_TX_STAT_TX_FILTERED: The frame was not transmitted
- *	because the destination STA was in powersave mode.
+ *	because the destination STA was in powersave mode. Note that to
+ *	avoid race conditions, the filter must be set by the hardware or
+ *	firmware upon receiving a frame that indicates that the station
+ *	went to sleep (must be done on device to filter frames already on
+ *	the queue) and may only be unset after mac80211 gives the OK for
+ *	that by setting the IEEE80211_TX_CTL_CLEAR_PS_FILT (see above),
+ *	since only then is it guaranteed that no more frames are in the
+ *	hardware queue.
  * @IEEE80211_TX_STAT_ACK: Frame was acknowledged
  * @IEEE80211_TX_STAT_AMPDU: The frame was aggregated, so status
  * 	is for the whole aggregation.
@@ -241,6 +263,15 @@ struct ieee80211_bss_conf {
  *	it can be sent out.
  * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211,
  *	used to indicate that a frame was already retried due to PS
+ * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
+ *	used to indicate frame should not be encrypted
+ * @IEEE80211_TX_CTL_PSPOLL_RESPONSE: (internal?)
+ *	This frame is a response to a PS-poll frame and should be sent
+ *	although the station is in powersave mode.
+ * @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the
+ *	transmit function after the current frame, this can be used
+ *	by drivers to kick the DMA queue only if unset or when the
+ *	queue gets full.
  */
 enum mac80211_tx_control_flags {
 	IEEE80211_TX_CTL_REQ_TX_STATUS		= BIT(0),
@@ -259,6 +290,9 @@ enum mac80211_tx_control_flags {
 	IEEE80211_TX_INTFL_RCALGO		= BIT(13),
 	IEEE80211_TX_INTFL_NEED_TXPROCESSING	= BIT(14),
 	IEEE80211_TX_INTFL_RETRIED		= BIT(15),
+	IEEE80211_TX_INTFL_DONT_ENCRYPT		= BIT(16),
+	IEEE80211_TX_CTL_PSPOLL_RESPONSE	= BIT(17),
+	IEEE80211_TX_CTL_MORE_FRAMES		= BIT(18),
 };
 
 /**
@@ -316,6 +350,21 @@ enum mac80211_rate_control_flags {
  *
  * When used for transmit status reporting, the driver should
  * always report the rate along with the flags it used.
+ *
+ * &struct ieee80211_tx_info contains an array of these structs
+ * in the control information, and it will be filled by the rate
+ * control algorithm according to what should be sent. For example,
+ * if this array contains, in the format { <idx>, <count> } the
+ * information
+ *    { 3, 2 }, { 2, 2 }, { 1, 4 }, { -1, 0 }, { -1, 0 }
+ * then this means that the frame should be transmitted
+ * up to twice at rate 3, up to twice at rate 2, and up to four
+ * times at rate 1 if it doesn't get acknowledged. Say it gets
+ * acknowledged by the peer after the fifth attempt, the status
+ * information should then contain
+ *   { 3, 2 }, { 2, 2 }, { 1, 1 }, { -1, 0 } ...
+ * since it was transmitted twice at rate 3, twice at rate 2
+ * and once at rate 1 after which we received an acknowledgement.
  */
 struct ieee80211_tx_rate {
 	s8 idx;
@@ -397,6 +446,11 @@ static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
 	return (struct ieee80211_tx_info *)skb->cb;
 }
 
+static inline struct ieee80211_rx_status *IEEE80211_SKB_RXCB(struct sk_buff *skb)
+{
+	return (struct ieee80211_rx_status *)skb->cb;
+}
+
 /**
  * ieee80211_tx_info_clear_status - clear TX status
  *
@@ -478,7 +532,7 @@ enum mac80211_rx_flags {
  *
  * The low-level driver should provide this information (the subset
  * supported by hardware) to the 802.11 code with each received
- * frame.
+ * frame, in the skb's control buffer (cb).
  *
  * @mactime: value in microseconds of the 64-bit Time Synchronization Function
  * 	(TSF) timer when the first data symbol (MPDU) arrived at the hardware.
@@ -529,7 +583,6 @@ enum ieee80211_conf_flags {
 /**
  * enum ieee80211_conf_changed - denotes which configuration changed
  *
- * @_IEEE80211_CONF_CHANGE_RADIO_ENABLED: DEPRECATED
  * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
  * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
  * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed
@@ -539,7 +592,6 @@ enum ieee80211_conf_flags {
  * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
  */
 enum ieee80211_conf_changed {
-	_IEEE80211_CONF_CHANGE_RADIO_ENABLED	= BIT(0),
 	IEEE80211_CONF_CHANGE_LISTEN_INTERVAL	= BIT(2),
 	IEEE80211_CONF_CHANGE_RADIOTAP		= BIT(3),
 	IEEE80211_CONF_CHANGE_PS		= BIT(4),
@@ -549,14 +601,6 @@ enum ieee80211_conf_changed {
 	IEEE80211_CONF_CHANGE_IDLE		= BIT(8),
 };
 
-static inline __deprecated enum ieee80211_conf_changed
-__IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
-{
-	return _IEEE80211_CONF_CHANGE_RADIO_ENABLED;
-}
-#define IEEE80211_CONF_CHANGE_RADIO_ENABLED \
-	__IEEE80211_CONF_CHANGE_RADIO_ENABLED()
-
 /**
  * struct ieee80211_conf - configuration of the device
  *
@@ -564,9 +608,6 @@ __IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
  *
  * @flags: configuration flags defined above
  *
- * @radio_enabled: when zero, driver is required to switch off the radio.
- * @beacon_int: DEPRECATED, DO NOT USE
- *
  * @listen_interval: listen interval in units of beacon interval
  * @max_sleep_period: the maximum number of beacon intervals to sleep for
  *	before checking the beacon for a TIM bit (managed mode only); this
@@ -590,13 +631,11 @@ __IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
  *    number of transmissions not the number of retries
  */
 struct ieee80211_conf {
-	int __deprecated beacon_int;
 	u32 flags;
 	int power_level, dynamic_ps_timeout;
 	int max_sleep_period;
 
 	u16 listen_interval;
-	bool __deprecated radio_enabled;
 
 	u8 long_frame_max_tx_count, short_frame_max_tx_count;
 
@@ -901,12 +940,6 @@ enum ieee80211_hw_flags {
  *
  * @conf: &struct ieee80211_conf, device configuration, don't use.
  *
- * @workqueue: single threaded workqueue available for driver use,
- *	allocated by mac80211 on registration and flushed when an
- *	interface is removed.
- *	NOTICE: All work performed on this workqueue must not
- *	acquire the RTNL lock.
- *
  * @priv: pointer to private area that was allocated for driver use
  *	along with this structure.
  *
@@ -942,7 +975,6 @@ enum ieee80211_hw_flags {
 struct ieee80211_hw {
 	struct ieee80211_conf conf;
 	struct wiphy *wiphy;
-	struct workqueue_struct *workqueue;
 	const char *rate_control_algorithm;
 	void *priv;
 	u32 flags;
@@ -1172,10 +1204,13 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  * the driver's configure_filter() function which frames should be
  * passed to mac80211 and which should be filtered out.
  *
- * The configure_filter() callback is invoked with the parameters
- * @mc_count and @mc_list for the combined multicast address list
- * of all virtual interfaces, @changed_flags telling which flags
- * were changed and @total_flags with the new flag states.
+ * Before configure_filter() is invoked, the prepare_multicast()
+ * callback is invoked with the parameters @mc_count and @mc_list
+ * for the combined multicast address list of all virtual interfaces.
+ * It's use is optional, and it returns a u64 that is passed to
+ * configure_filter(). Additionally, configure_filter() has the
+ * arguments @changed_flags telling which flags were changed and
+ * @total_flags with the new flag states.
  *
  * If your device has no multicast address filters your driver will
  * need to check both the %FIF_ALLMULTI flag and the @mc_count
@@ -1224,10 +1259,13 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  *	mac80211 needs to do and the amount of CPU wakeups, so you should
  *	honour this flag if possible.
  *
- * @FIF_CONTROL: pass control frames, if PROMISC_IN_BSS is not set then
- *	only those addressed to this station
+ * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
+ *  is not set then only those addressed to this station.
  *
  * @FIF_OTHER_BSS: pass frames destined to other BSSes
+ *
+ * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS  is not set then only
+ *  those addressed to this station.
  */
 enum ieee80211_filter_flags {
 	FIF_PROMISC_IN_BSS	= 1<<0,
@@ -1237,6 +1275,7 @@ enum ieee80211_filter_flags {
 	FIF_BCN_PRBRESP_PROMISC	= 1<<4,
 	FIF_CONTROL		= 1<<5,
 	FIF_OTHER_BSS		= 1<<6,
+	FIF_PSPOLL		= 1<<7,
 };
 
 /**
@@ -1289,7 +1328,8 @@ enum ieee80211_ampdu_mlme_action {
  *	is disabled. This should turn off the hardware (at least
  *	it must turn off frame reception.)
  *	May be called right after add_interface if that rejects
- *	an interface.
+ *	an interface. If you added any work onto the mac80211 workqueue
+ *	you should ensure to cancel it on this callback.
  *	Must be implemented.
  *
  * @add_interface: Called when a netdevice attached to the hardware is
@@ -1323,9 +1363,13 @@ enum ieee80211_ampdu_mlme_action {
  *	for association indication. The @changed parameter indicates which
  *	of the bss parameters has changed when a call is made.
  *
+ * @prepare_multicast: Prepare for multicast filter configuration.
+ *	This callback is optional, and its return value is passed
+ *	to configure_filter(). This callback must be atomic.
+ *
  * @configure_filter: Configure the device's RX filter.
  *	See the section "Frame filtering" for more information.
- *	This callback must be implemented and atomic.
+ *	This callback must be implemented.
  *
  * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
  * 	must be set or cleared for a given STA. Must be atomic.
@@ -1411,6 +1455,8 @@ enum ieee80211_ampdu_mlme_action {
  * @rfkill_poll: Poll rfkill hardware state. If you need this, you also
  *	need to set wiphy->rfkill_poll to %true before registration,
  *	and need to call wiphy_rfkill_set_hw_state() in the callback.
+ *
+ * @testmode_cmd: Implement a cfg80211 test mode command.
  */
 struct ieee80211_ops {
 	int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1425,10 +1471,12 @@ struct ieee80211_ops {
 				 struct ieee80211_vif *vif,
 				 struct ieee80211_bss_conf *info,
 				 u32 changed);
+	u64 (*prepare_multicast)(struct ieee80211_hw *hw,
+				 int mc_count, struct dev_addr_list *mc_list);
 	void (*configure_filter)(struct ieee80211_hw *hw,
 				 unsigned int changed_flags,
 				 unsigned int *total_flags,
-				 int mc_count, struct dev_addr_list *mc_list);
+				 u64 multicast);
 	int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
 		       bool set);
 	int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -1461,6 +1509,9 @@ struct ieee80211_ops {
 			    struct ieee80211_sta *sta, u16 tid, u16 *ssn);
 
 	void (*rfkill_poll)(struct ieee80211_hw *hw);
+#ifdef CONFIG_NL80211_TESTMODE
+	int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len);
+#endif
 };
 
 /**
@@ -1606,10 +1657,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw);
  */
 void ieee80211_restart_hw(struct ieee80211_hw *hw);
 
-/* trick to avoid symbol clashes with the ieee80211 subsystem */
-void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
-		    struct ieee80211_rx_status *status);
-
 /**
  * ieee80211_rx - receive frame
  *
@@ -1624,14 +1671,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
  *
  * @hw: the hardware this frame came in on
  * @skb: the buffer to receive, owned by mac80211 after this call
- * @status: status of this frame; the status pointer need not be valid
- *	after this function returns
  */
-static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
-				struct ieee80211_rx_status *status)
-{
-	__ieee80211_rx(hw, skb, status);
-}
+void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb);
 
 /**
  * ieee80211_rx_irqsafe - receive frame
@@ -1644,13 +1685,8 @@ static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
  *
  * @hw: the hardware this frame came in on
  * @skb: the buffer to receive, owned by mac80211 after this call
- * @status: status of this frame; the status pointer need not be valid
- *	after this function returns and is not freed by mac80211,
- *	it is recommended that it points to a stack area
  */
-void ieee80211_rx_irqsafe(struct ieee80211_hw *hw,
-			  struct sk_buff *skb,
-			  struct ieee80211_rx_status *status);
+void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb);
 
 /**
  * ieee80211_tx_status - transmit status callback
@@ -1917,6 +1953,31 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
 						void *data);
 
 /**
+ * ieee80211_queue_work - add work onto the mac80211 workqueue
+ *
+ * Drivers and mac80211 use this to add work onto the mac80211 workqueue.
+ * This helper ensures drivers are not queueing work when they should not be.
+ *
+ * @hw: the hardware struct for the interface we are adding work for
+ * @work: the work we want to add onto the mac80211 workqueue
+ */
+void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work);
+
+/**
+ * ieee80211_queue_delayed_work - add work onto the mac80211 workqueue
+ *
+ * Drivers and mac80211 use this to queue delayed work onto the mac80211
+ * workqueue.
+ *
+ * @hw: the hardware struct for the interface we are adding work for
+ * @dwork: delayable work to queue onto the mac80211 workqueue
+ * @delay: number of jiffies to wait before queueing
+ */
+void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
+				  struct delayed_work *dwork,
+				  unsigned long delay);
+
+/**
  * ieee80211_start_tx_ba_session - Start a tx Block Ack session.
  * @hw: pointer as obtained from ieee80211_alloc_hw().
  * @ra: receiver address of the BA session recipient
@@ -2090,6 +2151,29 @@ static inline int rate_supported(struct ieee80211_sta *sta,
 	return (sta == NULL || sta->supp_rates[band] & BIT(index));
 }
 
+/**
+ * rate_control_send_low - helper for drivers for management/no-ack frames
+ *
+ * Rate control algorithms that agree to use the lowest rate to
+ * send management frames and NO_ACK data with the respective hw
+ * retries should use this in the beginning of their mac80211 get_rate
+ * callback. If true is returned the rate control can simply return.
+ * If false is returned we guarantee that sta and sta and priv_sta is
+ * not null.
+ *
+ * Rate control algorithms wishing to do more intelligent selection of
+ * rate for multicast/broadcast frames may choose to not use this.
+ *
+ * @sta: &struct ieee80211_sta pointer to the target destination. Note
+ * 	that this may be null.
+ * @priv_sta: private rate control structure. This may be null.
+ * @txrc: rate control information we sholud populate for mac80211.
+ */
+bool rate_control_send_low(struct ieee80211_sta *sta,
+			   void *priv_sta,
+			   struct ieee80211_tx_rate_control *txrc);
+
+
 static inline s8
 rate_lowest_index(struct ieee80211_supported_band *sband,
 		  struct ieee80211_sta *sta)
@@ -2106,6 +2190,17 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
 	return 0;
 }
 
+static inline
+bool rate_usable_index_exists(struct ieee80211_supported_band *sband,
+			      struct ieee80211_sta *sta)
+{
+	unsigned int i;
+
+	for (i = 0; i < sband->n_bitrates; i++)
+		if (rate_supported(sta, sband->band, i))
+			return true;
+	return false;
+}
 
 int ieee80211_rate_control_register(struct rate_control_ops *ops);
 void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index d8d790e..3817fda 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -24,6 +24,7 @@
 
 #include <linux/err.h>
 #include <linux/sysctl.h>
+#include <linux/workqueue.h>
 #include <net/rtnetlink.h>
 
 /*
@@ -117,7 +118,7 @@ struct neighbour
 	int			(*output)(struct sk_buff *skb);
 	struct sk_buff_head	arp_queue;
 	struct timer_list	timer;
-	struct neigh_ops	*ops;
+	const struct neigh_ops	*ops;
 	u8			primary_key[0];
 };
 
@@ -167,7 +168,7 @@ struct neigh_table
 	int			gc_thresh2;
 	int			gc_thresh3;
 	unsigned long		last_flush;
-	struct timer_list 	gc_timer;
+	struct delayed_work	gc_work;
 	struct timer_list 	proxy_timer;
 	struct sk_buff_head	proxy_queue;
 	atomic_t		entries;
@@ -178,7 +179,6 @@ struct neigh_table
 	struct neighbour	**hash_buckets;
 	unsigned int		hash_mask;
 	__u32			hash_rnd;
-	unsigned int		hash_chain_gc;
 	struct pneigh_entry	**phash_buckets;
 };
 
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index ded434b..a120284 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -26,6 +26,7 @@ struct net_device;
 struct sock;
 struct ctl_table_header;
 struct net_generic;
+struct sock;
 
 struct net {
 	atomic_t		count;		/* To decided when the network
@@ -57,6 +58,7 @@ struct net {
 	spinlock_t		rules_mod_lock;
 
 	struct sock 		*rtnl;			/* rtnetlink socket */
+	struct sock		*genl_sock;
 
 	struct netns_core	core;
 	struct netns_mib	mib;
@@ -78,6 +80,9 @@ struct net {
 #ifdef CONFIG_XFRM
 	struct netns_xfrm	xfrm;
 #endif
+#ifdef CONFIG_WIRELESS_EXT
+	struct sk_buff_head	wext_nlevents;
+#endif
 	struct net_generic	*gen;
 };
 
@@ -106,6 +111,8 @@ static inline struct net *copy_net_ns(unsigned long flags, struct net *net_ns)
 
 extern struct list_head net_namespace_list;
 
+extern struct net *get_net_ns_by_pid(pid_t pid);
+
 #ifdef CONFIG_NET_NS
 extern void __put_net(struct net *net);
 
@@ -208,6 +215,9 @@ static inline struct net *read_pnet(struct net * const *pnet)
 #define for_each_net(VAR)				\
 	list_for_each_entry(VAR, &net_namespace_list, list)
 
+#define for_each_net_rcu(VAR)				\
+	list_for_each_entry_rcu(VAR, &net_namespace_list, list)
+
 #ifdef CONFIG_NET_NS
 #define __net_init
 #define __net_exit
@@ -229,13 +239,15 @@ struct pernet_operations {
  * needs per network namespace operations use device pernet operations,
  * otherwise use pernet subsys operations.
  *
- * This is critically important.  Most of the network code cleanup
- * runs with the assumption that dev_remove_pack has been called so no
- * new packets will arrive during and after the cleanup functions have
- * been called.  dev_remove_pack is not per namespace so instead the
- * guarantee of no more packets arriving in a network namespace is
- * provided by ensuring that all network devices and all sockets have
- * left the network namespace before the cleanup methods are called.
+ * Network interfaces need to be removed from a dying netns _before_
+ * subsys notifiers can be called, as most of the network code cleanup
+ * (which is done from subsys notifiers) runs with the assumption that
+ * dev_remove_pack has been called so no new packets will arrive during
+ * and after the cleanup functions have been called.  dev_remove_pack
+ * is not per namespace so instead the guarantee of no more packets
+ * arriving in a network namespace is provided by ensuring that all
+ * network devices and all sockets have left the network namespace
+ * before the cleanup methods are called.
  *
  * For the longest time the ipv4 icmp code was registered as a pernet
  * device which caused kernel oops, and panics during network
diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h
index 5868406..33602ab 100644
--- a/include/net/netfilter/nf_nat_core.h
+++ b/include/net/netfilter/nf_nat_core.h
@@ -31,6 +31,6 @@ struct nlattr;
 extern int
 (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
 				  enum nf_nat_manip_type manip,
-				  struct nlattr *attr);
+				  const struct nlattr *attr);
 
 #endif /* _NF_NAT_CORE_H */
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 007bdb0..a63b219 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -365,7 +365,7 @@ static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
  *
  * See nla_parse()
  */
-static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen,
+static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen,
 			      struct nlattr *tb[], int maxtype,
 			      const struct nla_policy *policy)
 {
@@ -414,7 +414,7 @@ static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
  *
  * Returns 1 if a report back to the application is requested.
  */
-static inline int nlmsg_report(struct nlmsghdr *nlh)
+static inline int nlmsg_report(const struct nlmsghdr *nlh)
 {
 	return !!(nlh->nlmsg_flags & NLM_F_ECHO);
 }
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index afab4e4..dfeb2d7 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -6,6 +6,7 @@
 
 #ifndef __NETNS_IPV6_H__
 #define __NETNS_IPV6_H__
+#include <net/dst_ops.h>
 
 struct ctl_table_header;
 
@@ -42,7 +43,7 @@ struct netns_ipv6 {
 	struct timer_list       ip6_fib_timer;
 	struct hlist_head       *fib_table_hash;
 	struct fib6_table       *fib6_main_tbl;
-	struct dst_ops		*ip6_dst_ops;
+	struct dst_ops		ip6_dst_ops;
 	unsigned int		 ip6_rt_gc_expire;
 	unsigned long		 ip6_rt_last_gc;
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h
index 9554a64..591db7d 100644
--- a/include/net/netns/x_tables.h
+++ b/include/net/netns/x_tables.h
@@ -8,8 +8,11 @@ struct ebt_table;
 
 struct netns_xt {
 	struct list_head tables[NFPROTO_NUMPROTO];
+#if defined(CONFIG_BRIDGE_NF_EBTABLES) || \
+    defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE)
 	struct ebt_table *broute_table;
 	struct ebt_table *frame_filter;
 	struct ebt_table *frame_nat;
+#endif
 };
 #endif
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
new file mode 100644
index 0000000..99d2ba1
--- /dev/null
+++ b/include/net/nl802154.h
@@ -0,0 +1,126 @@
+/*
+ * nl802154.h
+ *
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef IEEE802154_NL_H
+#define IEEE802154_NL_H
+
+struct net_device;
+struct ieee802154_addr;
+
+/**
+ * ieee802154_nl_assoc_indic - Notify userland of an association request.
+ * @dev: The network device on which this association request was
+ *       received.
+ * @addr: The address of the device requesting association.
+ * @cap: The capability information field from the device.
+ *
+ * This informs a userland coordinator of a device requesting to
+ * associate with the PAN controlled by the coordinator.
+ *
+ * Note: This is in section 7.3.1 of the IEEE 802.15.4-2006 document.
+ */
+int ieee802154_nl_assoc_indic(struct net_device *dev,
+		struct ieee802154_addr *addr, u8 cap);
+
+/**
+ * ieee802154_nl_assoc_confirm - Notify userland of association.
+ * @dev: The device which has completed association.
+ * @short_addr: The short address assigned to the device.
+ * @status: The status of the association.
+ *
+ * Inform userland of the result of an association request. If the
+ * association request included asking the coordinator to allocate
+ * a short address then it is returned in @short_addr.
+ *
+ * Note: This is in section 7.3.2 of the IEEE 802.15.4 document.
+ */
+int ieee802154_nl_assoc_confirm(struct net_device *dev,
+		u16 short_addr, u8 status);
+
+/**
+ * ieee802154_nl_disassoc_indic - Notify userland of disassociation.
+ * @dev: The device on which disassociation was indicated.
+ * @addr: The device which is disassociating.
+ * @reason: The reason for the disassociation.
+ *
+ * Inform userland that a device has disassociated from the network.
+ *
+ * Note: This is in section 7.3.3 of the IEEE 802.15.4 document.
+ */
+int ieee802154_nl_disassoc_indic(struct net_device *dev,
+		struct ieee802154_addr *addr, u8 reason);
+
+/**
+ * ieee802154_nl_disassoc_confirm - Notify userland of disassociation
+ * completion.
+ * @dev: The device on which disassociation was ordered.
+ * @status: The result of the disassociation.
+ *
+ * Inform userland of the result of requesting that a device
+ * disassociate, or the result of requesting that we disassociate from
+ * a PAN managed by another coordinator.
+ *
+ * Note: This is in section 7.1.4.3 of the IEEE 802.15.4 document.
+ */
+int ieee802154_nl_disassoc_confirm(struct net_device *dev,
+		u8 status);
+
+/**
+ * ieee802154_nl_scan_confirm - Notify userland of completion of scan.
+ * @dev: The device which was instructed to scan.
+ * @status: The status of the scan operation.
+ * @scan_type: What type of scan was performed.
+ * @unscanned: Any channels that the device was unable to scan.
+ * @edl: The energy levels (if a passive scan).
+ *
+ *
+ * Note: This is in section 7.1.11 of the IEEE 802.15.4 document.
+ * Note: This API does not permit the return of an active scan result.
+ */
+int ieee802154_nl_scan_confirm(struct net_device *dev,
+		u8 status, u8 scan_type, u32 unscanned, u8 page,
+		u8 *edl/*, struct list_head *pan_desc_list */);
+
+/**
+ * ieee802154_nl_beacon_indic - Notify userland of a received beacon.
+ * @dev: The device on which a beacon was received.
+ * @panid: The PAN of the coordinator.
+ * @coord_addr: The short address of the coordinator on that PAN.
+ *
+ * Note: This is in section 7.1.5 of the IEEE 802.15.4 document.
+ * Note: This API does not provide extended information such as what
+ * channel the PAN is on or what the LQI of the beacon frame was on
+ * receipt.
+ * Note: This API cannot indicate a beacon frame for a coordinator
+ *       operating in long addressing mode.
+ */
+int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid,
+		u16 coord_addr);
+
+/**
+ * ieee802154_nl_start_confirm - Notify userland of completion of start.
+ * @dev: The device which was instructed to scan.
+ * @status: The status of the scan operation.
+ *
+ * Note: This is in section 7.1.14 of the IEEE 802.15.4 document.
+ */
+int ieee802154_nl_start_confirm(struct net_device *dev, u8 status);
+
+#endif
diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
index 29d1267..44c923c 100644
--- a/include/net/phonet/pn_dev.h
+++ b/include/net/phonet/pn_dev.h
@@ -49,4 +49,6 @@ void phonet_address_notify(int event, struct net_device *dev, u8 addr);
 
 #define PN_NO_ADDR	0xff
 
+extern const struct file_operations pn_sock_seq_fops;
+
 #endif
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 82a3191..f911ec7 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -87,6 +87,9 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
 extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
 extern void qdisc_put_stab(struct qdisc_size_table *tab);
 extern void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc);
+extern int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+			   struct net_device *dev, struct netdev_queue *txq,
+			   spinlock_t *root_lock);
 
 extern void __qdisc_run(struct Qdisc *q);
 
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 1089d5a..60249e5 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -94,21 +94,20 @@ struct inet_protosw {
 #define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
 #define INET_PROTOSW_ICSK      0x04  /* Is this an inet_connection_sock? */
 
-extern struct net_protocol *inet_protocol_base;
-extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
+extern const struct net_protocol *inet_protos[MAX_INET_PROTOS];
 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
+extern const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
 #endif
 
-extern int	inet_add_protocol(struct net_protocol *prot, unsigned char num);
-extern int	inet_del_protocol(struct net_protocol *prot, unsigned char num);
+extern int	inet_add_protocol(const struct net_protocol *prot, unsigned char num);
+extern int	inet_del_protocol(const struct net_protocol *prot, unsigned char num);
 extern void	inet_register_protosw(struct inet_protosw *p);
 extern void	inet_unregister_protosw(struct inet_protosw *p);
 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-extern int	inet6_add_protocol(struct inet6_protocol *prot, unsigned char num);
-extern int	inet6_del_protocol(struct inet6_protocol *prot, unsigned char num);
+extern int	inet6_add_protocol(const struct inet6_protocol *prot, unsigned char num);
+extern int	inet6_del_protocol(const struct inet6_protocol *prot, unsigned char num);
 extern int	inet6_register_protosw(struct inet_protosw *p);
 extern void	inet6_unregister_protosw(struct inet_protosw *p);
 #endif
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 3c1895e..c3aa044 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -14,7 +14,7 @@ extern void	rtnl_register(int protocol, int msgtype,
 extern int	rtnl_unregister(int protocol, int msgtype);
 extern void	rtnl_unregister_all(int protocol);
 
-static inline int rtnl_msg_family(struct nlmsghdr *nlh)
+static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
 {
 	if (nlmsg_len(nlh) >= sizeof(struct rtgenmsg))
 		return ((struct rtgenmsg *) nlmsg_data(nlh))->rtgen_family;
@@ -70,6 +70,9 @@ struct rtnl_link_ops {
 	size_t			(*get_xstats_size)(const struct net_device *dev);
 	int			(*fill_xstats)(struct sk_buff *skb,
 					       const struct net_device *dev);
+	int			(*get_tx_queues)(struct net *net, struct nlattr *tb[],
+						 unsigned int *tx_queues,
+						 unsigned int *real_tx_queues);
 };
 
 extern int	__rtnl_link_register(struct rtnl_link_ops *ops);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 5482e95..c33180d 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -45,6 +45,8 @@ struct Qdisc
 #define TCQ_F_BUILTIN		1
 #define TCQ_F_THROTTLED		2
 #define TCQ_F_INGRESS		4
+#define TCQ_F_CAN_BYPASS	8
+#define TCQ_F_MQROOT		16
 #define TCQ_F_WARN_NONWC	(1 << 16)
 	int			padded;
 	struct Qdisc_ops	*ops;
@@ -79,6 +81,7 @@ struct Qdisc
 struct Qdisc_class_ops
 {
 	/* Child qdisc manipulation */
+	struct netdev_queue *	(*select_queue)(struct Qdisc *, struct tcmsg *);
 	int			(*graft)(struct Qdisc *, unsigned long cl,
 					struct Qdisc *, struct Qdisc **);
 	struct Qdisc *		(*leaf)(struct Qdisc *, unsigned long cl);
@@ -121,6 +124,7 @@ struct Qdisc_ops
 	void			(*reset)(struct Qdisc *);
 	void			(*destroy)(struct Qdisc *);
 	int			(*change)(struct Qdisc *, struct nlattr *arg);
+	void			(*attach)(struct Qdisc *);
 
 	int			(*dump)(struct Qdisc *, struct sk_buff *);
 	int			(*dump_stats)(struct Qdisc *, struct gnet_dump *);
@@ -182,6 +186,11 @@ struct qdisc_skb_cb {
 	char			data[];
 };
 
+static inline int qdisc_qlen(struct Qdisc *q)
+{
+	return q->q.qlen;
+}
+
 static inline struct qdisc_skb_cb *qdisc_skb_cb(struct sk_buff *skb)
 {
 	return (struct qdisc_skb_cb *)skb->cb;
@@ -249,6 +258,8 @@ static inline void sch_tree_unlock(struct Qdisc *q)
 
 extern struct Qdisc noop_qdisc;
 extern struct Qdisc_ops noop_qdisc_ops;
+extern struct Qdisc_ops pfifo_fast_ops;
+extern struct Qdisc_ops mq_qdisc_ops;
 
 struct Qdisc_class_common
 {
@@ -296,6 +307,8 @@ extern void dev_init_scheduler(struct net_device *dev);
 extern void dev_shutdown(struct net_device *dev);
 extern void dev_activate(struct net_device *dev);
 extern void dev_deactivate(struct net_device *dev);
+extern struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
+				     struct Qdisc *qdisc);
 extern void qdisc_reset(struct Qdisc *qdisc);
 extern void qdisc_destroy(struct Qdisc *qdisc);
 extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n);
@@ -387,13 +400,18 @@ static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch)
 	return qdisc_enqueue(skb, sch) & NET_XMIT_MASK;
 }
 
+static inline void __qdisc_update_bstats(struct Qdisc *sch, unsigned int len)
+{
+	sch->bstats.bytes += len;
+	sch->bstats.packets++;
+}
+
 static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
 				       struct sk_buff_head *list)
 {
 	__skb_queue_tail(list, skb);
 	sch->qstats.backlog += qdisc_pkt_len(skb);
-	sch->bstats.bytes += qdisc_pkt_len(skb);
-	sch->bstats.packets++;
+	__qdisc_update_bstats(sch, qdisc_pkt_len(skb));
 
 	return NET_XMIT_SUCCESS;
 }
diff --git a/include/net/scm.h b/include/net/scm.h
index f45bb6e..cf48c80 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -26,7 +26,6 @@ struct scm_cookie
 #ifdef CONFIG_SECURITY_NETWORK
 	u32			secid;		/* Passed security ID 	*/
 #endif
-	unsigned long		seq;		/* Connection seqno	*/
 };
 
 extern void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm);
@@ -59,7 +58,6 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 	scm->creds.gid = current_gid();
 	scm->creds.pid = task_tgid_vnr(p);
 	scm->fp = NULL;
-	scm->seq = 0;
 	unix_get_peersec_dgram(sock, scm);
 	if (msg->msg_controllen <= 0)
 		return 0;
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 3b96680..8be5135 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -106,6 +106,7 @@ typedef enum {
 	SCTP_CMD_ASSOC_SHKEY,    /* generate the association shared keys */
 	SCTP_CMD_T1_RETRAN,	 /* Mark for retransmission after T1 timeout  */
 	SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
+	SCTP_CMD_SEND_MSG,	 /* Send the whole use message */
 	SCTP_CMD_LAST
 } sctp_verb_t;
 
@@ -139,6 +140,7 @@ typedef union {
 	struct sctp_ulpevent *ulpevent;
 	struct sctp_packet *packet;
 	sctp_sackhdr_t *sackh;
+	struct sctp_datamsg *msg;
 } sctp_arg_t;
 
 /* We are simulating ML type constructors here.
@@ -188,6 +190,7 @@ SCTP_ARG_CONSTRUCTOR(PEER_INIT,	sctp_init_chunk_t *, init)
 SCTP_ARG_CONSTRUCTOR(ULPEVENT,  struct sctp_ulpevent *, ulpevent)
 SCTP_ARG_CONSTRUCTOR(PACKET,	struct sctp_packet *, packet)
 SCTP_ARG_CONSTRUCTOR(SACKH,	sctp_sackhdr_t *, sackh)
+SCTP_ARG_CONSTRUCTOR(DATAMSG,	struct sctp_datamsg *, msg)
 
 typedef struct {
 	sctp_arg_t obj;
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index b05b055..58f714a 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -231,7 +231,7 @@ typedef enum {
 	SCTP_SS_LISTENING      = TCP_LISTEN,
 	SCTP_SS_ESTABLISHING   = TCP_SYN_SENT,
 	SCTP_SS_ESTABLISHED    = TCP_ESTABLISHED,
-	SCTP_SS_DISCONNECTING  = TCP_CLOSING,
+	SCTP_SS_CLOSING        = TCP_CLOSING,
 } sctp_sock_state_t;
 
 /* These functions map various type to printable names.  */
@@ -241,7 +241,9 @@ const char *sctp_tname(const sctp_subtype_t);	/* timeouts */
 const char *sctp_pname(const sctp_subtype_t);	/* primitives */
 
 /* This is a table of printable names of sctp_state_t's.  */
-extern const char *sctp_state_tbl[], *sctp_evttype_tbl[], *sctp_status_tbl[];
+extern const char *const sctp_state_tbl[];
+extern const char *const sctp_evttype_tbl[];
+extern const char *const sctp_status_tbl[];
 
 /* Maximum chunk length considering padding requirements. */
 enum { SCTP_MAX_CHUNK_LEN = ((1<<16) - sizeof(__u32)) };
@@ -361,6 +363,13 @@ typedef enum {
 	SCTP_SCOPE_UNUSABLE,		/* IPv4 unusable addresses */
 } sctp_scope_t;
 
+typedef enum {
+	SCTP_SCOPE_POLICY_DISABLE,	/* Disable IPv4 address scoping */
+	SCTP_SCOPE_POLICY_ENABLE,	/* Enable IPv4 address scoping */
+	SCTP_SCOPE_POLICY_PRIVATE,	/* Follow draft but allow IPv4 private addresses */
+	SCTP_SCOPE_POLICY_LINK,		/* Follow draft but allow IPv4 link local addresses */
+} sctp_scope_policy_t;
+
 /* Based on IPv4 scoping <draft-stewart-tsvwg-sctp-ipv4-00.txt>,
  * SCTP IPv4 unusable addresses: 0.0.0.0/8, 224.0.0.0/4, 198.18.0.0/24,
  * 192.88.99.0/24.
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index d16a304..8a6d529 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -486,15 +486,16 @@ static inline __s32 sctp_jitter(__u32 rto)
 }
 
 /* Break down data chunks at this point.  */
-static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
+static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu)
 {
+	struct sctp_sock *sp = sctp_sk(asoc->base.sk);
 	int frag = pmtu;
 
 	frag -= sp->pf->af->net_header_len;
 	frag -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk);
 
-	if (sp->user_frag)
-		frag = min_t(int, frag, sp->user_frag);
+	if (asoc->user_frag)
+		frag = min_t(int, frag, asoc->user_frag);
 
 	frag = min_t(int, frag, SCTP_MAX_CHUNK_LEN);
 
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index edfcacf..42d00ce 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -219,6 +219,15 @@ extern struct sctp_globals {
 	/* Flag to idicate if SCTP-AUTH is enabled */
 	int auth_enable;
 
+	/*
+	 * Policy to control SCTP IPv4 address scoping
+	 * 0   - Disable IPv4 address scoping
+	 * 1   - Enable IPv4 address scoping
+	 * 2   - Selectively allow only IPv4 private addresses
+	 * 3   - Selectively allow only IPv4 link local address
+	 */
+	int ipv4_scope_policy;
+
 	/* Flag to indicate whether computing and verifying checksum
 	 * is disabled. */
         int checksum_disable;
@@ -252,6 +261,7 @@ extern struct sctp_globals {
 #define sctp_port_hashtable		(sctp_globals.port_hashtable)
 #define sctp_local_addr_list		(sctp_globals.local_addr_list)
 #define sctp_local_addr_lock		(sctp_globals.addr_list_lock)
+#define sctp_scope_policy		(sctp_globals.ipv4_scope_policy)
 #define sctp_addip_enable		(sctp_globals.addip_enable)
 #define sctp_addip_noauth		(sctp_globals.addip_noauth_enable)
 #define sctp_prsctp_enable		(sctp_globals.prsctp_enable)
@@ -628,7 +638,7 @@ struct sctp_datamsg {
 	/* Chunks waiting to be submitted to lower layer. */
 	struct list_head chunks;
 	/* Chunks that have been transmitted. */
-	struct list_head track;
+	size_t msg_size;
 	/* Reference counting. */
 	atomic_t refcnt;
 	/* When is this message no longer interesting to the peer? */
@@ -643,6 +653,7 @@ struct sctp_datamsg {
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
 					    struct sctp_sndrcvinfo *,
 					    struct msghdr *, int len);
+void sctp_datamsg_free(struct sctp_datamsg *);
 void sctp_datamsg_put(struct sctp_datamsg *);
 void sctp_chunk_fail(struct sctp_chunk *, int error);
 int sctp_chunk_abandoned(struct sctp_chunk *);
@@ -811,22 +822,12 @@ struct sctp_packet {
 	/* pointer to the auth chunk for this packet */
 	struct sctp_chunk *auth;
 
-	/* This packet contains a COOKIE-ECHO chunk. */
-	__u8 has_cookie_echo;
-
-	/* This packet contains a SACK chunk. */
-	__u8 has_sack;
-
-	/* This packet contains an AUTH chunk */
-	__u8 has_auth;
-
-	/* This packet contains at least 1 DATA chunk */
-	__u8 has_data;
-
-	/* SCTP cannot fragment this packet. So let ip fragment it. */
-	__u8 ipfragok;
-
-	__u8 malloced;
+	u8  has_cookie_echo:1,	/* This packet contains a COOKIE-ECHO chunk. */
+	    has_sack:1,		/* This packet contains a SACK chunk. */
+	    has_auth:1,		/* This packet contains an AUTH chunk */
+	    has_data:1,		/* This packet contains at least 1 DATA chunk */
+	    ipfragok:1,		/* So let ip fragment this packet */
+	    malloced:1;		/* Is it malloced? */
 };
 
 struct sctp_packet *sctp_packet_init(struct sctp_packet *,
@@ -1567,13 +1568,13 @@ struct sctp_association {
 		__u32	sack_cnt;
 
 		/* These are capabilities which our peer advertised.  */
-		__u8	ecn_capable;	 /* Can peer do ECN? */
-		__u8	ipv4_address;	 /* Peer understands IPv4 addresses? */
-		__u8	ipv6_address;	 /* Peer understands IPv6 addresses? */
-		__u8	hostname_address;/* Peer understands DNS addresses? */
-		__u8    asconf_capable;  /* Does peer support ADDIP? */
-		__u8    prsctp_capable;  /* Can peer do PR-SCTP? */
-		__u8	auth_capable;	 /* Is peer doing SCTP-AUTH? */
+		__u8	ecn_capable:1,	    /* Can peer do ECN? */
+			ipv4_address:1,	    /* Peer understands IPv4 addresses? */
+			ipv6_address:1,	    /* Peer understands IPv6 addresses? */
+			hostname_address:1, /* Peer understands DNS addresses? */
+			asconf_capable:1,   /* Does peer support ADDIP? */
+			prsctp_capable:1,   /* Can peer do PR-SCTP? */
+			auth_capable:1;	    /* Is peer doing SCTP-AUTH? */
 
 		__u32   adaptation_ind;	 /* Adaptation Code point. */
 
@@ -1738,6 +1739,12 @@ struct sctp_association {
 	 */
 	__u32 rwnd_over;
 
+	/* Keeps treack of rwnd pressure.  This happens when we have
+	 * a window, but not recevie buffer (i.e small packets).  This one
+	 * is releases slowly (1 PMTU at a time ).
+	 */
+	__u32 rwnd_press;
+
 	/* This is the sndbuf size in use for the association.
 	 * This corresponds to the sndbuf size for the association,
 	 * as specified in the sk->sndbuf.
@@ -1756,6 +1763,7 @@ struct sctp_association {
 
 	/* The message size at which SCTP fragmentation will occur. */
 	__u32 frag_point;
+	__u32 user_frag;
 
 	/* Counter used to count INIT errors. */
 	int init_err_counter;
@@ -1905,11 +1913,8 @@ struct sctp_association {
 
 	__u16 active_key_id;
 
-	/* Need to send an ECNE Chunk? */
-	char need_ecne;
-
-	/* Is it a temporary association? */
-	char temp;
+	__u8 need_ecne:1,	/* Need to send an ECNE Chunk? */
+	     temp:1;		/* Is it a temporary association? */
 };
 
 
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 1580c04..be2334a 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -210,12 +210,6 @@ enum sctp_sinfo_flags {
 };
 
 
-typedef union {
-	__u8   			raw;
-	struct sctp_initmsg	init;
-	struct sctp_sndrcvinfo	sndrcv;
-} sctp_cmsg_data_t;
-
 /* These are cmsg_types.  */
 typedef enum sctp_cmsg_type {
 	SCTP_INIT,              /* 5.2.1 SCTP Initiation Structure */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 88af843..56b7602 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -469,6 +469,7 @@ extern void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
 				      int nonagle);
 extern int tcp_may_send_now(struct sock *sk);
 extern int tcp_retransmit_skb(struct sock *, struct sk_buff *);
+extern void tcp_retransmit_timer(struct sock *sk);
 extern void tcp_xmit_retransmit_queue(struct sock *);
 extern void tcp_simple_retransmit(struct sock *);
 extern int tcp_trim_head(struct sock *, struct sk_buff *, u32);
@@ -521,6 +522,17 @@ extern int tcp_mtu_to_mss(struct sock *sk, int pmtu);
 extern int tcp_mss_to_mtu(struct sock *sk, int mss);
 extern void tcp_mtup_init(struct sock *sk);
 
+static inline void tcp_bound_rto(const struct sock *sk)
+{
+	if (inet_csk(sk)->icsk_rto > TCP_RTO_MAX)
+		inet_csk(sk)->icsk_rto = TCP_RTO_MAX;
+}
+
+static inline u32 __tcp_set_rto(const struct tcp_sock *tp)
+{
+	return (tp->srtt >> 3) + tp->rttvar;
+}
+
 static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
 {
 	tp->pred_flags = htonl((tp->tcp_header_len << 26) |
@@ -781,6 +793,13 @@ static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
 	return tp->packets_out - tcp_left_out(tp) + tp->retrans_out;
 }
 
+#define TCP_INFINITE_SSTHRESH	0x7fffffff
+
+static inline bool tcp_in_initial_slowstart(const struct tcp_sock *tp)
+{
+	return tp->snd_ssthresh >= TCP_INFINITE_SSTHRESH;
+}
+
 /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
  * The exception is rate halving phase, when cwnd is decreasing towards
  * ssthresh.
@@ -1007,6 +1026,11 @@ static inline int keepalive_time_when(const struct tcp_sock *tp)
 	return tp->keepalive_time ? : sysctl_tcp_keepalive_time;
 }
 
+static inline int keepalive_probes(const struct tcp_sock *tp)
+{
+	return tp->keepalive_probes ? : sysctl_tcp_keepalive_probes;
+}
+
 static inline int tcp_fin_time(const struct sock *sk)
 {
 	int fin_timeout = tcp_sk(sk)->linger2 ? : sysctl_tcp_fin_timeout;
@@ -1169,7 +1193,7 @@ extern int			tcp_v4_md5_do_del(struct sock *sk,
 #define tcp_twsk_md5_key(twsk)	NULL
 #endif
 
-extern struct tcp_md5sig_pool	**tcp_alloc_md5sig_pool(void);
+extern struct tcp_md5sig_pool	**tcp_alloc_md5sig_pool(struct sock *);
 extern void			tcp_free_md5sig_pool(void);
 
 extern struct tcp_md5sig_pool	*__tcp_get_md5sig_pool(int cpu);
@@ -1235,6 +1259,29 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu
 #define tcp_for_write_queue_from_safe(skb, tmp, sk)			\
 	skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp)
 
+/* This function calculates a "timeout" which is equivalent to the timeout of a
+ * TCP connection after "boundary" unsucessful, exponentially backed-off
+ * retransmissions with an initial RTO of TCP_RTO_MIN.
+ */
+static inline bool retransmits_timed_out(const struct sock *sk,
+					 unsigned int boundary)
+{
+	unsigned int timeout, linear_backoff_thresh;
+
+	if (!inet_csk(sk)->icsk_retransmits)
+		return false;
+
+	linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN);
+
+	if (boundary <= linear_backoff_thresh)
+		timeout = ((2 << boundary) - 1) * TCP_RTO_MIN;
+	else
+		timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN +
+			  (boundary - linear_backoff_thresh) * TCP_RTO_MAX;
+
+	return (tcp_time_stamp - tcp_sk(sk)->retrans_stamp) >= timeout;
+}
+
 static inline struct sk_buff *tcp_send_head(struct sock *sk)
 {
 	return sk->sk_send_head;
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index bfb240c..d65381c 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -51,7 +51,7 @@ extern int			datagram_send_ctl(struct net *net,
 /*
  *	address family specific functions
  */
-extern struct inet_connection_sock_af_ops ipv4_specific;
+extern const struct inet_connection_sock_af_ops ipv4_specific;
 
 extern void inet6_destroy_sock(struct sock *sk);
 
diff --git a/include/net/udp.h b/include/net/udp.h
index 90e6ce5..5fb029f 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -207,4 +207,7 @@ extern void udp4_proc_exit(void);
 #endif
 
 extern void udp_init(void);
+
+extern int udp4_ufo_send_check(struct sk_buff *skb);
+extern struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features);
 #endif	/* _UDP_H */
diff --git a/include/net/wpan-phy.h b/include/net/wpan-phy.h
new file mode 100644
index 0000000..547b1e2
--- /dev/null
+++ b/include/net/wpan-phy.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef WPAN_PHY_H
+#define WPAN_PHY_H
+
+#include <linux/netdevice.h>
+#include <linux/mutex.h>
+
+struct wpan_phy {
+	struct mutex pib_lock;
+
+	/*
+	 * This is a PIB acording to 802.15.4-2006.
+	 * We do not provide timing-related variables, as they
+	 * aren't used outside of driver
+	 */
+	u8 current_channel;
+	u8 current_page;
+	u32 channels_supported;
+	u8 transmit_power;
+	u8 cca_mode;
+
+	struct device dev;
+	int idx;
+
+	char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
+};
+
+struct wpan_phy *wpan_phy_alloc(size_t priv_size);
+int wpan_phy_register(struct device *parent, struct wpan_phy *phy);
+void wpan_phy_unregister(struct wpan_phy *phy);
+void wpan_phy_free(struct wpan_phy *phy);
+
+static inline void *wpan_phy_priv(struct wpan_phy *phy)
+{
+	BUG_ON(!phy);
+	return &phy->priv;
+}
+
+struct wpan_phy *wpan_phy_find(const char *str);
+static inline const char *wpan_phy_name(struct wpan_phy *phy)
+{
+	return dev_name(&phy->dev);
+}
+#endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9e3a3f4..223e90a 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1280,7 +1280,7 @@ struct xfrm6_tunnel {
 };
 
 extern void xfrm_init(void);
-extern void xfrm4_init(void);
+extern void xfrm4_init(int rt_hash_size);
 extern int xfrm_state_init(struct net *net);
 extern void xfrm_state_fini(struct net *net);
 extern void xfrm4_state_init(void);
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 9b4ac93..9a3b498 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -90,14 +90,14 @@ typedef struct pccard_io_map {
 	u_char	map;
 	u_char	flags;
 	u_short	speed;
-	u_int	start, stop;
+	phys_addr_t start, stop;
 } pccard_io_map;
 
 typedef struct pccard_mem_map {
 	u_char		map;
 	u_char		flags;
 	u_short		speed;
-	u_long		static_start;
+	phys_addr_t	static_start;
 	u_int		card_start;
 	struct resource	*res;
 } pccard_mem_map;
diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h
index ffab027..324dd0e 100644
--- a/include/scsi/fc/fc_gs.h
+++ b/include/scsi/fc/fc_gs.h
@@ -87,6 +87,7 @@ enum fc_ct_explan {
 	FC_FS_EXP_PNAM =	0x02,	/* port name not registered */
 	FC_FS_EXP_NNAM =	0x03,	/* node name not registered */
 	FC_FS_EXP_COS =		0x04,	/* class of service not registered */
+	FC_FS_EXP_FTNR =	0x07,	/* FC-4 types not registered */
 	/* definitions not complete */
 };
 
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index a0ff61c..27dad70 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -32,6 +32,7 @@ struct fc_ct_req {
 		struct fc_ns_gid_ft gid;
 		struct fc_ns_rn_id  rn;
 		struct fc_ns_rft rft;
+		struct fc_ns_fid fid;
 	} payload;
 };
 
@@ -57,6 +58,23 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
 }
 
 /**
+ * fc_adisc_fill() - Fill in adisc request frame
+ * @lport: local port.
+ * @fp: fc frame where payload will be placed.
+ */
+static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
+{
+	struct fc_els_adisc *adisc;
+
+	adisc = fc_frame_payload_get(fp, sizeof(*adisc));
+	memset(adisc, 0, sizeof(*adisc));
+	adisc->adisc_cmd = ELS_ADISC;
+	put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
+	put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
+	hton24(adisc->adisc_port_id, fc_host_port_id(lport->host));
+}
+
+/**
  * fc_ct_hdr_fill- fills ct header and reset ct payload
  * returns pointer to ct request.
  */
@@ -77,10 +95,17 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp,
 }
 
 /**
- * fc_ct_fill - Fill in a name service request frame
+ * fc_ct_fill() - Fill in a name service request frame
+ * @lport: local port.
+ * @fc_id: FC_ID of non-destination rport for GPN_ID and similar inquiries.
+ * @fp: frame to contain payload.
+ * @op: CT opcode.
+ * @r_ctl: pointer to FC header R_CTL.
+ * @fh_type: pointer to FC-4 type.
  */
-static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
-		      unsigned int op, enum fc_rctl *r_ctl, u32 *did,
+static inline int fc_ct_fill(struct fc_lport *lport,
+		      u32 fc_id, struct fc_frame *fp,
+		      unsigned int op, enum fc_rctl *r_ctl,
 		      enum fc_fh_type *fh_type)
 {
 	struct fc_ct_req *ct;
@@ -91,6 +116,11 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
 		ct->payload.gid.fn_fc4_type = FC_TYPE_FCP;
 		break;
 
+	case FC_NS_GPN_ID:
+		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_fid));
+		hton24(ct->payload.fid.fp_fid, fc_id);
+		break;
+
 	case FC_NS_RFT_ID:
 		ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft));
 		hton24(ct->payload.rft.fid.fp_fid,
@@ -110,7 +140,6 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp,
 		return -EINVAL;
 	}
 	*r_ctl = FC_RCTL_DD_UNSOL_CTL;
-	*did = FC_FID_DIR_SERV;
 	*fh_type = FC_TYPE_CT;
 	return 0;
 }
@@ -249,51 +278,42 @@ static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp)
 /**
  * fc_els_fill - Fill in an ELS  request frame
  */
-static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport,
+static inline int fc_els_fill(struct fc_lport *lport,
+		       u32 did,
 		       struct fc_frame *fp, unsigned int op,
-		       enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type)
+		       enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
 {
 	switch (op) {
+	case ELS_ADISC:
+		fc_adisc_fill(lport, fp);
+		break;
+
 	case ELS_PLOGI:
 		fc_plogi_fill(lport, fp, ELS_PLOGI);
-		*did = rport->port_id;
 		break;
 
 	case ELS_FLOGI:
 		fc_flogi_fill(lport, fp);
-		*did = FC_FID_FLOGI;
 		break;
 
 	case ELS_LOGO:
 		fc_logo_fill(lport, fp);
-		*did = FC_FID_FLOGI;
-		/*
-		 * if rport is valid then it
-		 * is port logo, therefore
-		 * set did to rport id.
-		 */
-		if (rport)
-			*did = rport->port_id;
 		break;
 
 	case ELS_RTV:
 		fc_rtv_fill(lport, fp);
-		*did = rport->port_id;
 		break;
 
 	case ELS_REC:
 		fc_rec_fill(lport, fp);
-		*did = rport->port_id;
 		break;
 
 	case ELS_PRLI:
 		fc_prli_fill(lport, fp);
-		*did = rport->port_id;
 		break;
 
 	case ELS_SCR:
 		fc_scr_fill(lport, fp);
-		*did = FC_FID_FCTRL;
 		break;
 
 	default:
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index 5951105..c35d238 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -37,13 +37,6 @@
 #define	FC_FRAME_HEADROOM	32	/* headroom for VLAN + FCoE headers */
 #define	FC_FRAME_TAILROOM	8	/* trailer space for FCoE */
 
-/*
- * Information about an individual fibre channel frame received or to be sent.
- * The buffer may be in up to 4 additional non-contiguous sections,
- * but the linear section must hold the frame header.
- */
-#define FC_FRAME_SG_LEN		4	/* scatter/gather list maximum length */
-
 #define fp_skb(fp)	(&((fp)->skb))
 #define fr_hdr(fp)	((fp)->skb.data)
 #define fr_len(fp)	((fp)->skb.len)
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 4426f00..d67dda2 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -262,6 +262,7 @@ enum iscsi_err {
 	ISCSI_ERR_NO_SCSI_CMD		= ISCSI_ERR_BASE + 17,
 	ISCSI_ERR_INVALID_HOST		= ISCSI_ERR_BASE + 18,
 	ISCSI_ERR_XMIT_FAILED		= ISCSI_ERR_BASE + 19,
+	ISCSI_ERR_TCP_CONN_CLOSE	= ISCSI_ERR_BASE + 20,
 };
 
 /*
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index b92584a..65dc9aa 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -51,55 +51,49 @@ do {								\
 		do {						\
 			CMD;					\
 		} while (0);					\
-} while (0);
+} while (0)
 
 #define FC_LIBFC_DBG(fmt, args...)					\
 	FC_CHECK_LOGGING(FC_LIBFC_LOGGING,				\
-			 printk(KERN_INFO "libfc: " fmt, ##args);)
+			 printk(KERN_INFO "libfc: " fmt, ##args))
 
 #define FC_LPORT_DBG(lport, fmt, args...)				\
 	FC_CHECK_LOGGING(FC_LPORT_LOGGING,				\
-			 printk(KERN_INFO "lport: %6x: " fmt,		\
-				fc_host_port_id(lport->host), ##args);)
+			 printk(KERN_INFO "host%u: lport %6x: " fmt,	\
+				(lport)->host->host_no,			\
+				fc_host_port_id((lport)->host), ##args))
 
 #define FC_DISC_DBG(disc, fmt, args...)					\
 	FC_CHECK_LOGGING(FC_DISC_LOGGING,				\
-			 printk(KERN_INFO "disc: %6x: " fmt,		\
-				fc_host_port_id(disc->lport->host),	\
-				##args);)
-
-#define FC_RPORT_DBG(rport, fmt, args...)				\
-do {									\
-	struct fc_rport_libfc_priv *rdata = rport->dd_data;		\
-	struct fc_lport *lport = rdata->local_port;			\
+			 printk(KERN_INFO "host%u: disc: " fmt,		\
+				(disc)->lport->host->host_no,		\
+				##args))
+
+#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...)			\
 	FC_CHECK_LOGGING(FC_RPORT_LOGGING,				\
-			 printk(KERN_INFO "rport: %6x: %6x: " fmt,	\
-				fc_host_port_id(lport->host),		\
-				rport->port_id, ##args);)		\
-} while (0);
+			 printk(KERN_INFO "host%u: rport %6x: " fmt,	\
+				(lport)->host->host_no,			\
+				(port_id), ##args))
+
+#define FC_RPORT_DBG(rdata, fmt, args...)				\
+	FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args)
 
 #define FC_FCP_DBG(pkt, fmt, args...)					\
 	FC_CHECK_LOGGING(FC_FCP_LOGGING,				\
-			 printk(KERN_INFO "fcp: %6x: %6x: " fmt,	\
-				fc_host_port_id(pkt->lp->host),		\
-				pkt->rport->port_id, ##args);)
-
-#define FC_EM_DBG(em, fmt, args...)					\
-	FC_CHECK_LOGGING(FC_EM_LOGGING,					\
-			 printk(KERN_INFO "em: %6x: " fmt,		\
-				fc_host_port_id(em->lp->host),		\
-				##args);)
+			 printk(KERN_INFO "host%u: fcp: %6x: " fmt,	\
+				(pkt)->lp->host->host_no,		\
+				pkt->rport->port_id, ##args))
 
 #define FC_EXCH_DBG(exch, fmt, args...)					\
 	FC_CHECK_LOGGING(FC_EXCH_LOGGING,				\
-			 printk(KERN_INFO "exch: %6x: %4x: " fmt,	\
-				fc_host_port_id(exch->lp->host),	\
-				exch->xid, ##args);)
+			 printk(KERN_INFO "host%u: xid %4x: " fmt,	\
+				(exch)->lp->host->host_no,		\
+				exch->xid, ##args))
 
 #define FC_SCSI_DBG(lport, fmt, args...)				\
 	FC_CHECK_LOGGING(FC_SCSI_LOGGING,                               \
-			 printk(KERN_INFO "scsi: %6x: " fmt,		\
-				fc_host_port_id(lport->host), ##args);)
+			 printk(KERN_INFO "host%u: scsi: " fmt,		\
+				(lport)->host->host_no,	##args))
 
 /*
  * libfc error codes
@@ -125,7 +119,7 @@ do {									\
  * FC HBA status
  */
 enum fc_lport_state {
-	LPORT_ST_NONE = 0,
+	LPORT_ST_DISABLED = 0,
 	LPORT_ST_FLOGI,
 	LPORT_ST_DNS,
 	LPORT_ST_RPN_ID,
@@ -143,53 +137,74 @@ enum fc_disc_event {
 };
 
 enum fc_rport_state {
-	RPORT_ST_NONE = 0,
 	RPORT_ST_INIT,		/* initialized */
 	RPORT_ST_PLOGI,		/* waiting for PLOGI completion */
 	RPORT_ST_PRLI,		/* waiting for PRLI completion */
 	RPORT_ST_RTV,		/* waiting for RTV completion */
 	RPORT_ST_READY,		/* ready for use */
 	RPORT_ST_LOGO,		/* port logout sent */
-};
-
-enum fc_rport_trans_state {
-	FC_PORTSTATE_ROGUE,
-	FC_PORTSTATE_REAL,
+	RPORT_ST_ADISC,		/* Discover Address sent */
+	RPORT_ST_DELETE,	/* port being deleted */
 };
 
 /**
  * struct fc_disc_port - temporary discovery port to hold rport identifiers
- * @lp: Fibre Channel host port instance
- * @peers: node for list management during discovery and RSCN processing
- * @ids: identifiers structure to pass to fc_remote_port_add()
- * @rport_work: work struct for starting the rport state machine
+ * @lp:         Fibre Channel host port instance
+ * @peers:      Node for list management during discovery and RSCN processing
+ * @rport_work: Work struct for starting the rport state machine
+ * @port_id:    Port ID of the discovered port
  */
 struct fc_disc_port {
 	struct fc_lport             *lp;
 	struct list_head            peers;
-	struct fc_rport_identifiers ids;
 	struct work_struct	    rport_work;
+	u32                         port_id;
 };
 
 enum fc_rport_event {
 	RPORT_EV_NONE = 0,
-	RPORT_EV_CREATED,
+	RPORT_EV_READY,
 	RPORT_EV_FAILED,
 	RPORT_EV_STOP,
 	RPORT_EV_LOGO
 };
 
+struct fc_rport_priv;
+
 struct fc_rport_operations {
-	void (*event_callback)(struct fc_lport *, struct fc_rport *,
+	void (*event_callback)(struct fc_lport *, struct fc_rport_priv *,
 			       enum fc_rport_event);
 };
 
 /**
  * struct fc_rport_libfc_priv - libfc internal information about a remote port
  * @local_port: Fibre Channel host port instance
+ * @rp_state: indicates READY for I/O or DELETE when blocked.
+ * @flags: REC and RETRY supported flags
+ * @e_d_tov: error detect timeout value (in msec)
+ * @r_a_tov: resource allocation timeout value (in msec)
+ */
+struct fc_rport_libfc_priv {
+	struct fc_lport		   *local_port;
+	enum fc_rport_state        rp_state;
+	u16			   flags;
+	#define FC_RP_FLAGS_REC_SUPPORTED	(1 << 0)
+	#define FC_RP_FLAGS_RETRY		(1 << 1)
+	unsigned int	           e_d_tov;
+	unsigned int	           r_a_tov;
+};
+
+/**
+ * struct fc_rport_priv - libfc rport and discovery info about a remote port
+ * @local_port: Fibre Channel host port instance
+ * @rport: transport remote port
+ * @kref: reference counter
  * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges
+ * @ids: remote port identifiers and roles
  * @flags: REC and RETRY supported flags
  * @max_seq: maximum number of concurrent sequences
+ * @disc_id: discovery identifier
+ * @maxframe_size: maximum frame size
  * @retries: retry count in current state
  * @e_d_tov: error detect timeout value (in msec)
  * @r_a_tov: resource allocation timeout value (in msec)
@@ -197,38 +212,28 @@ struct fc_rport_operations {
  * @retry_work:
  * @event_callback: Callback for rport READY, FAILED or LOGO
  */
-struct fc_rport_libfc_priv {
+struct fc_rport_priv {
 	struct fc_lport		   *local_port;
+	struct fc_rport		   *rport;
+	struct kref		   kref;
 	enum fc_rport_state        rp_state;
+	struct fc_rport_identifiers ids;
 	u16			   flags;
-	#define FC_RP_FLAGS_REC_SUPPORTED	(1 << 0)
-	#define FC_RP_FLAGS_RETRY		(1 << 1)
 	u16		           max_seq;
+	u16			   disc_id;
+	u16			   maxframe_size;
 	unsigned int	           retries;
 	unsigned int	           e_d_tov;
 	unsigned int	           r_a_tov;
-	enum fc_rport_trans_state  trans_state;
 	struct mutex               rp_mutex;
 	struct delayed_work	   retry_work;
 	enum fc_rport_event        event;
 	struct fc_rport_operations *ops;
 	struct list_head           peers;
 	struct work_struct         event_work;
+	u32			   supported_classes;
 };
 
-#define PRIV_TO_RPORT(x)						\
-	(struct fc_rport *)((void *)x - sizeof(struct fc_rport));
-#define RPORT_TO_PRIV(x)						\
-	(struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport));
-
-struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *);
-
-static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn)
-{
-	rport->node_name = wwnn;
-	rport->port_name = wwpn;
-}
-
 /*
  * fcoe stats structure
  */
@@ -344,6 +349,8 @@ static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)
  */
 
 struct fc_exch_mgr;
+struct fc_exch_mgr_anchor;
+extern u16	fc_cpu_mask;	/* cpu mask for possible cpus */
 
 /*
  * Sequence.
@@ -368,6 +375,7 @@ struct fc_seq {
  */
 struct fc_exch {
 	struct fc_exch_mgr *em;		/* exchange manager */
+	struct fc_exch_pool *pool;	/* per cpu exches pool */
 	u32		state;		/* internal driver state */
 	u16		xid;		/* our exchange ID */
 	struct list_head	ex_list;	/* free or busy list linkage */
@@ -415,7 +423,7 @@ struct libfc_function_template {
 	 * STATUS: OPTIONAL
 	 */
 	struct fc_seq *(*elsct_send)(struct fc_lport *lport,
-				     struct fc_rport *rport,
+				     u32 did,
 				     struct fc_frame *fp,
 				     unsigned int op,
 				     void (*resp)(struct fc_seq *,
@@ -519,25 +527,6 @@ struct libfc_function_template {
 	void (*exch_done)(struct fc_seq *sp);
 
 	/*
-	 * Assigns a EM and a free XID for an new exchange and then
-	 * allocates a new exchange and sequence pair.
-	 * The fp can be used to determine free XID.
-	 *
-	 * STATUS: OPTIONAL
-	 */
-	struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp);
-
-	/*
-	 * Release previously assigned XID by exch_get API.
-	 * The LLD may implement this if XID is assigned by LLD
-	 * in exch_get().
-	 *
-	 * STATUS: OPTIONAL
-	 */
-	void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp,
-			 u16 ex_id);
-
-	/*
 	 * Start a new sequence on the same exchange/sequence tuple.
 	 *
 	 * STATUS: OPTIONAL
@@ -577,9 +566,11 @@ struct libfc_function_template {
 	int (*lport_reset)(struct fc_lport *);
 
 	/*
-	 * Create a remote port
+	 * Create a remote port with a given port ID
+	 *
+	 * STATUS: OPTIONAL
 	 */
-	struct fc_rport *(*rport_create)(struct fc_disc_port *);
+	struct fc_rport_priv *(*rport_create)(struct fc_lport *, u32);
 
 	/*
 	 * Initiates the RP state machine. It is called from the LP module.
@@ -592,7 +583,7 @@ struct libfc_function_template {
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	int (*rport_login)(struct fc_rport *rport);
+	int (*rport_login)(struct fc_rport_priv *);
 
 	/*
 	 * Logoff, and remove the rport from the transport if
@@ -600,7 +591,7 @@ struct libfc_function_template {
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	int (*rport_logoff)(struct fc_rport *rport);
+	int (*rport_logoff)(struct fc_rport_priv *);
 
 	/*
 	 * Recieve a request from a remote port.
@@ -608,14 +599,20 @@ struct libfc_function_template {
 	 * STATUS: OPTIONAL
 	 */
 	void (*rport_recv_req)(struct fc_seq *, struct fc_frame *,
-			       struct fc_rport *);
+			       struct fc_lport *);
 
 	/*
 	 * lookup an rport by it's port ID.
 	 *
 	 * STATUS: OPTIONAL
 	 */
-	struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32);
+	struct fc_rport_priv *(*rport_lookup)(const struct fc_lport *, u32);
+
+	/*
+	 * Destroy an rport after final kref_put().
+	 * The argument is a pointer to the kref inside the fc_rport_priv.
+	 */
+	void (*rport_destroy)(struct kref *);
 
 	/*
 	 * Send a fcp cmd from fsp pkt.
@@ -681,18 +678,16 @@ struct libfc_function_template {
 /* information used by the discovery layer */
 struct fc_disc {
 	unsigned char		retry_count;
-	unsigned char		delay;
 	unsigned char		pending;
 	unsigned char		requested;
 	unsigned short		seq_count;
 	unsigned char		buf_len;
-	enum fc_disc_event	event;
+	u16			disc_id;
 
 	void (*disc_callback)(struct fc_lport *,
 			      enum fc_disc_event);
 
 	struct list_head	 rports;
-	struct list_head	 rogue_rports;
 	struct fc_lport		*lport;
 	struct mutex		disc_mutex;
 	struct fc_gpn_ft_resp	partial_buf;	/* partial name buffer */
@@ -704,9 +699,9 @@ struct fc_lport {
 
 	/* Associations */
 	struct Scsi_Host	*host;
-	struct fc_exch_mgr	*emp;
-	struct fc_rport		*dns_rp;
-	struct fc_rport		*ptp_rp;
+	struct list_head	ema_list;
+	struct fc_rport_priv	*dns_rp;
+	struct fc_rport_priv	*ptp_rp;
 	void			*scsi_priv;
 	struct fc_disc          disc;
 
@@ -960,6 +955,28 @@ int fc_elsct_init(struct fc_lport *lp);
 int fc_exch_init(struct fc_lport *lp);
 
 /*
+ * Adds Exchange Manager (EM) mp to lport.
+ *
+ * Adds specified mp to lport using struct fc_exch_mgr_anchor,
+ * the struct fc_exch_mgr_anchor allows same EM sharing by
+ * more than one lport with their specified match function,
+ * the match function is used in allocating exchange from
+ * added mp.
+ */
+struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport,
+					   struct fc_exch_mgr *mp,
+					   bool (*match)(struct fc_frame *));
+
+/*
+ * Deletes Exchange Manager (EM) from lport by removing
+ * its anchor ema from lport.
+ *
+ * If removed anchor ema was the last user of its associated EM
+ * then also destroys associated EM.
+ */
+void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema);
+
+/*
  * Allocates an Exchange Manager (EM).
  *
  * The EM manages exchanges for their allocation and
@@ -974,27 +991,25 @@ int fc_exch_init(struct fc_lport *lp);
  * a new exchange.
  * The LLD may choose to have multiple EMs,
  * e.g. one EM instance per CPU receive thread in LLD.
- * The LLD can use exch_get() of struct libfc_function_template
- * to specify XID for a new exchange within
- * a specified EM instance.
  *
- * The em_idx to uniquely identify an EM instance.
+ * Specified match function is used in allocating exchanges
+ * from newly allocated EM.
  */
 struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp,
 				      enum fc_class class,
 				      u16 min_xid,
-				      u16 max_xid);
+				      u16 max_xid,
+				      bool (*match)(struct fc_frame *));
 
 /*
- * Free an exchange manager.
+ * Free all exchange managers of a lport.
  */
-void fc_exch_mgr_free(struct fc_exch_mgr *mp);
+void fc_exch_mgr_free(struct fc_lport *lport);
 
 /*
  * Receive a frame on specified local port and exchange manager.
  */
-void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp,
-		  struct fc_frame *fp);
+void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp);
 
 /*
  * This function is for exch_seq_send function pointer in
@@ -1036,28 +1051,20 @@ int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec);
 void fc_exch_done(struct fc_seq *sp);
 
 /*
- * Assigns a EM and XID for a frame and then allocates
- * a new exchange and sequence pair.
- * The fp can be used to determine free XID.
- */
-struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp);
-
-/*
  * Allocate a new exchange and sequence pair.
- * if ex_id is zero then next free exchange id
- * from specified exchange manger mp will be assigned.
  */
-struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp,
-			      struct fc_frame *fp, u16 ex_id);
+struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp);
 /*
  * Start a new sequence on the same exchange as the supplied sequence.
  */
 struct fc_seq *fc_seq_start_next(struct fc_seq *sp);
 
+
 /*
- * Reset an exchange manager, completing all sequences and exchanges.
- * If s_id is non-zero, reset only exchanges originating from that FID.
- * If d_id is non-zero, reset only exchanges sending to that FID.
+ * Reset all EMs of a lport, releasing its all sequences and
+ * exchanges. If sid is non-zero, then reset only exchanges
+ * we sourced from that FID. If did is non-zero, reset only
+ * exchanges destined to that FID.
  */
 void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id);
 
@@ -1078,4 +1085,9 @@ void fc_destroy_exch_mgr(void);
 int fc_setup_rport(void);
 void fc_destroy_rport(void);
 
+/*
+ * Internal libfc functions.
+ */
+const char *fc_els_resp_type(struct fc_frame *);
+
 #endif /* _LIBFC_H_ */
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 61afeb5..887e57e 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -390,6 +390,7 @@ extern void iscsi_session_failure(struct iscsi_session *session,
 extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
 				enum iscsi_param param, char *buf);
 extern void iscsi_suspend_tx(struct iscsi_conn *conn);
+extern void iscsi_suspend_queue(struct iscsi_conn *conn);
 extern void iscsi_conn_queue_work(struct iscsi_conn *conn);
 
 #define iscsi_conn_printk(prefix, _c, fmt, a...) \
@@ -415,6 +416,8 @@ extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t);
 extern void iscsi_requeue_task(struct iscsi_task *task);
 extern void iscsi_put_task(struct iscsi_task *task);
 extern void __iscsi_get_task(struct iscsi_task *task);
+extern void iscsi_complete_scsi_task(struct iscsi_task *task,
+				     uint32_t exp_cmdsn, uint32_t max_cmdsn);
 
 /*
  * generic helpers
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 3f566af..9af48cb 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -187,10 +187,13 @@ struct scsi_device_handler {
 	void (*detach)(struct scsi_device *);
 	int (*activate)(struct scsi_device *);
 	int (*prep_fn)(struct scsi_device *, struct request *);
+	int (*set_params)(struct scsi_device *, const char *);
 };
 
 struct scsi_dh_data {
 	struct scsi_device_handler *scsi_dh;
+	struct scsi_device *sdev;
+	struct kref kref;
 	char buf[0];
 };
 
diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h
index 33efce2..ff24074 100644
--- a/include/scsi/scsi_dh.h
+++ b/include/scsi/scsi_dh.h
@@ -60,6 +60,7 @@ extern int scsi_dh_activate(struct request_queue *);
 extern int scsi_dh_handler_exist(const char *);
 extern int scsi_dh_attach(struct request_queue *, const char *);
 extern void scsi_dh_detach(struct request_queue *);
+extern int scsi_dh_set_params(struct request_queue *, const char *);
 #else
 static inline int scsi_dh_activate(struct request_queue *req)
 {
@@ -77,4 +78,8 @@ static inline void scsi_dh_detach(struct request_queue *q)
 {
 	return;
 }
+static inline int scsi_dh_set_params(struct request_queue *req, const char *params)
+{
+	return -SCSI_DH_NOSYS;
+}
 #endif
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index 9a74b46..d86af94 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -171,6 +171,7 @@ TRACE_EVENT(block_rq_complete,
 		  (unsigned long long)__entry->sector,
 		  __entry->nr_sector, __entry->errors)
 );
+
 TRACE_EVENT(block_bio_bounce,
 
 	TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -186,7 +187,8 @@ TRACE_EVENT(block_bio_bounce,
 	),
 
 	TP_fast_assign(
-		__entry->dev		= bio->bi_bdev->bd_dev;
+		__entry->dev		= bio->bi_bdev ?
+					  bio->bi_bdev->bd_dev : 0;
 		__entry->sector		= bio->bi_sector;
 		__entry->nr_sector	= bio->bi_size >> 9;
 		blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_size);
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 7d8b5bc..c1bd8f1 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -5,10 +5,15 @@
 #define _TRACE_EXT4_H
 
 #include <linux/writeback.h>
-#include "../../../fs/ext4/ext4.h"
-#include "../../../fs/ext4/mballoc.h"
 #include <linux/tracepoint.h>
 
+struct ext4_allocation_context;
+struct ext4_allocation_request;
+struct ext4_prealloc_space;
+struct ext4_inode_info;
+
+#define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode))
+
 TRACE_EVENT(ext4_free_inode,
 	TP_PROTO(struct inode *inode),
 
@@ -33,8 +38,8 @@ TRACE_EVENT(ext4_free_inode,
 	),
 
 	TP_printk("dev %s ino %lu mode %d uid %u gid %u blocks %llu",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->mode,
-		  __entry->uid, __entry->gid,
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->mode, __entry->uid, __entry->gid,
 		  (unsigned long long) __entry->blocks)
 );
 
@@ -56,7 +61,8 @@ TRACE_EVENT(ext4_request_inode,
 	),
 
 	TP_printk("dev %s dir %lu mode %d",
-		  jbd2_dev_to_name(__entry->dev), __entry->dir, __entry->mode)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->dir,
+		  __entry->mode)
 );
 
 TRACE_EVENT(ext4_allocate_inode,
@@ -79,7 +85,8 @@ TRACE_EVENT(ext4_allocate_inode,
 	),
 
 	TP_printk("dev %s ino %lu dir %lu mode %d",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->dir, __entry->mode)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  (unsigned long) __entry->dir, __entry->mode)
 );
 
 TRACE_EVENT(ext4_write_begin,
@@ -106,8 +113,8 @@ TRACE_EVENT(ext4_write_begin,
 	),
 
 	TP_printk("dev %s ino %lu pos %llu len %u flags %u",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len,
-		  __entry->flags)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pos, __entry->len, __entry->flags)
 );
 
 TRACE_EVENT(ext4_ordered_write_end,
@@ -133,8 +140,8 @@ TRACE_EVENT(ext4_ordered_write_end,
 	),
 
 	TP_printk("dev %s ino %lu pos %llu len %u copied %u",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len,
-		  __entry->copied)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pos, __entry->len, __entry->copied)
 );
 
 TRACE_EVENT(ext4_writeback_write_end,
@@ -160,8 +167,8 @@ TRACE_EVENT(ext4_writeback_write_end,
 	),
 
 	TP_printk("dev %s ino %lu pos %llu len %u copied %u",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len,
-		  __entry->copied)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pos, __entry->len, __entry->copied)
 );
 
 TRACE_EVENT(ext4_journalled_write_end,
@@ -186,8 +193,8 @@ TRACE_EVENT(ext4_journalled_write_end,
 	),
 
 	TP_printk("dev %s ino %lu pos %llu len %u copied %u",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len,
-		  __entry->copied)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pos, __entry->len, __entry->copied)
 );
 
 TRACE_EVENT(ext4_writepage,
@@ -209,7 +216,8 @@ TRACE_EVENT(ext4_writepage,
 	),
 
 	TP_printk("dev %s ino %lu page_index %lu",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->index)
 );
 
 TRACE_EVENT(ext4_da_writepages,
@@ -227,7 +235,6 @@ TRACE_EVENT(ext4_da_writepages,
 		__field(	char,	nonblocking		)
 		__field(	char,	for_kupdate		)
 		__field(	char,	for_reclaim		)
-		__field(	char,	for_writepages		)
 		__field(	char,	range_cyclic		)
 	),
 
@@ -241,16 +248,50 @@ TRACE_EVENT(ext4_da_writepages,
 		__entry->nonblocking	= wbc->nonblocking;
 		__entry->for_kupdate	= wbc->for_kupdate;
 		__entry->for_reclaim	= wbc->for_reclaim;
-		__entry->for_writepages	= wbc->for_writepages;
 		__entry->range_cyclic	= wbc->range_cyclic;
 	),
 
-	TP_printk("dev %s ino %lu nr_t_write %ld pages_skipped %ld range_start %llu range_end %llu nonblocking %d for_kupdate %d for_reclaim %d for_writepages %d range_cyclic %d",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->nr_to_write,
+	TP_printk("dev %s ino %lu nr_to_write %ld pages_skipped %ld range_start %llu range_end %llu nonblocking %d for_kupdate %d for_reclaim %d range_cyclic %d",
+		  jbd2_dev_to_name(__entry->dev),
+		  (unsigned long) __entry->ino, __entry->nr_to_write,
 		  __entry->pages_skipped, __entry->range_start,
 		  __entry->range_end, __entry->nonblocking,
 		  __entry->for_kupdate, __entry->for_reclaim,
-		  __entry->for_writepages, __entry->range_cyclic)
+		  __entry->range_cyclic)
+);
+
+TRACE_EVENT(ext4_da_write_pages,
+	TP_PROTO(struct inode *inode, struct mpage_da_data *mpd),
+
+	TP_ARGS(inode, mpd),
+
+	TP_STRUCT__entry(
+		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
+		__field(	__u64,	b_blocknr		)
+		__field(	__u32,	b_size			)
+		__field(	__u32,	b_state			)
+		__field(	unsigned long,	first_page	)
+		__field(	int,	io_done			)
+		__field(	int,	pages_written		)
+	),
+
+	TP_fast_assign(
+		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
+		__entry->b_blocknr	= mpd->b_blocknr;
+		__entry->b_size		= mpd->b_size;
+		__entry->b_state	= mpd->b_state;
+		__entry->first_page	= mpd->first_page;
+		__entry->io_done	= mpd->io_done;
+		__entry->pages_written	= mpd->pages_written;
+	),
+
+	TP_printk("dev %s ino %lu b_blocknr %llu b_size %u b_state 0x%04x first_page %lu io_done %d pages_written %d",
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->b_blocknr, __entry->b_size,
+		  __entry->b_state, __entry->first_page,
+		  __entry->io_done, __entry->pages_written)
 );
 
 TRACE_EVENT(ext4_da_writepages_result,
@@ -282,7 +323,8 @@ TRACE_EVENT(ext4_da_writepages_result,
 	),
 
 	TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld congestion %d more_io %d no_nrwrite_index_update %d",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->ret,
+		  jbd2_dev_to_name(__entry->dev),
+		  (unsigned long) __entry->ino, __entry->ret,
 		  __entry->pages_written, __entry->pages_skipped,
 		  __entry->encountered_congestion, __entry->more_io,
 		  __entry->no_nrwrite_index_update)
@@ -311,8 +353,8 @@ TRACE_EVENT(ext4_da_write_begin,
 	),
 
 	TP_printk("dev %s ino %lu pos %llu len %u flags %u",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len,
-		  __entry->flags)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pos, __entry->len, __entry->flags)
 );
 
 TRACE_EVENT(ext4_da_write_end,
@@ -338,8 +380,8 @@ TRACE_EVENT(ext4_da_write_end,
 	),
 
 	TP_printk("dev %s ino %lu pos %llu len %u copied %u",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pos, __entry->len,
-		  __entry->copied)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pos, __entry->len, __entry->copied)
 );
 
 TRACE_EVENT(ext4_discard_blocks,
@@ -389,8 +431,8 @@ TRACE_EVENT(ext4_mb_new_inode_pa,
 	),
 
 	TP_printk("dev %s ino %lu pstart %llu len %u lstart %llu",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pa_pstart,
-		  __entry->pa_len, __entry->pa_lstart)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pa_pstart, __entry->pa_len, __entry->pa_lstart)
 );
 
 TRACE_EVENT(ext4_mb_new_group_pa,
@@ -417,8 +459,8 @@ TRACE_EVENT(ext4_mb_new_group_pa,
 	),
 
 	TP_printk("dev %s ino %lu pstart %llu len %u lstart %llu",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->pa_pstart,
-		  __entry->pa_len, __entry->pa_lstart)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->pa_pstart, __entry->pa_len, __entry->pa_lstart)
 );
 
 TRACE_EVENT(ext4_mb_release_inode_pa,
@@ -444,8 +486,8 @@ TRACE_EVENT(ext4_mb_release_inode_pa,
 	),
 
 	TP_printk("dev %s ino %lu block %llu count %u",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->block,
-		  __entry->count)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->block, __entry->count)
 );
 
 TRACE_EVENT(ext4_mb_release_group_pa,
@@ -490,7 +532,7 @@ TRACE_EVENT(ext4_discard_preallocations,
 	),
 
 	TP_printk("dev %s ino %lu",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino)
 );
 
 TRACE_EVENT(ext4_mb_discard_preallocations,
@@ -545,8 +587,8 @@ TRACE_EVENT(ext4_request_blocks,
 	),
 
 	TP_printk("dev %s ino %lu flags %u len %u lblk %llu goal %llu lleft %llu lright %llu pleft %llu pright %llu ",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->flags,
-		  __entry->len,
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->flags, __entry->len,
 		  (unsigned long long) __entry->logical,
 		  (unsigned long long) __entry->goal,
 		  (unsigned long long) __entry->lleft,
@@ -589,8 +631,8 @@ TRACE_EVENT(ext4_allocate_blocks,
 	),
 
 	TP_printk("dev %s ino %lu flags %u len %u block %llu lblk %llu goal %llu lleft %llu lright %llu pleft %llu pright %llu ",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->flags,
-		  __entry->len, __entry->block,
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->flags, __entry->len, __entry->block,
 		  (unsigned long long) __entry->logical,
 		  (unsigned long long) __entry->goal,
 		  (unsigned long long) __entry->lleft,
@@ -623,8 +665,8 @@ TRACE_EVENT(ext4_free_blocks,
 	),
 
 	TP_printk("dev %s ino %lu block %llu count %lu metadata %d",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->block,
-		  __entry->count, __entry->metadata)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->block, __entry->count, __entry->metadata)
 );
 
 TRACE_EVENT(ext4_sync_file,
@@ -647,8 +689,8 @@ TRACE_EVENT(ext4_sync_file,
 	),
 
 	TP_printk("dev %s ino %ld parent %ld datasync %d ",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->parent,
-		  __entry->datasync)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  (unsigned long) __entry->parent, __entry->datasync)
 );
 
 TRACE_EVENT(ext4_sync_fs,
@@ -671,6 +713,30 @@ TRACE_EVENT(ext4_sync_fs,
 		  __entry->wait)
 );
 
+TRACE_EVENT(ext4_alloc_da_blocks,
+	TP_PROTO(struct inode *inode),
+
+	TP_ARGS(inode),
+
+	TP_STRUCT__entry(
+		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
+		__field( unsigned int,	data_blocks	)
+		__field( unsigned int,	meta_blocks	)
+	),
+
+	TP_fast_assign(
+		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
+		__entry->data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
+		__entry->meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
+	),
+
+	TP_printk("dev %s ino %lu data_blocks %u meta_blocks %u",
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
+		  __entry->data_blocks, __entry->meta_blocks)
+);
+
 #endif /* _TRACE_EXT4_H */
 
 /* This part must be outside protection */
diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h
index 1cb0c3a..b89f9db 100644
--- a/include/trace/events/irq.h
+++ b/include/trace/events/irq.h
@@ -8,16 +8,17 @@
 #include <linux/interrupt.h>
 
 #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
-#define show_softirq_name(val)			\
-	__print_symbolic(val,			\
-			 softirq_name(HI),	\
-			 softirq_name(TIMER),	\
-			 softirq_name(NET_TX),	\
-			 softirq_name(NET_RX),	\
-			 softirq_name(BLOCK),	\
-			 softirq_name(TASKLET),	\
-			 softirq_name(SCHED),	\
-			 softirq_name(HRTIMER),	\
+#define show_softirq_name(val)				\
+	__print_symbolic(val,				\
+			 softirq_name(HI),		\
+			 softirq_name(TIMER),		\
+			 softirq_name(NET_TX),		\
+			 softirq_name(NET_RX),		\
+			 softirq_name(BLOCK),		\
+			 softirq_name(BLOCK_IOPOLL),	\
+			 softirq_name(TASKLET),		\
+			 softirq_name(SCHED),		\
+			 softirq_name(HRTIMER),		\
 			 softirq_name(RCU))
 
 /**
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
index 10813fa..b851f0b 100644
--- a/include/trace/events/jbd2.h
+++ b/include/trace/events/jbd2.h
@@ -159,7 +159,7 @@ TRACE_EVENT(jbd2_submit_inode_data,
 	),
 
 	TP_printk("dev %s ino %lu",
-		  jbd2_dev_to_name(__entry->dev), __entry->ino)
+		  jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino)
 );
 
 #endif /* _TRACE_JBD2_H */
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
new file mode 100644
index 0000000..dbe1084
--- /dev/null
+++ b/include/trace/events/kvm.h
@@ -0,0 +1,151 @@
+#if !defined(_TRACE_KVM_MAIN_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KVM_MAIN_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+#define TRACE_INCLUDE_FILE kvm
+
+#if defined(__KVM_HAVE_IOAPIC)
+TRACE_EVENT(kvm_set_irq,
+	TP_PROTO(unsigned int gsi, int level, int irq_source_id),
+	TP_ARGS(gsi, level, irq_source_id),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	gsi		)
+		__field(	int,		level		)
+		__field(	int,		irq_source_id	)
+	),
+
+	TP_fast_assign(
+		__entry->gsi		= gsi;
+		__entry->level		= level;
+		__entry->irq_source_id	= irq_source_id;
+	),
+
+	TP_printk("gsi %u level %d source %d",
+		  __entry->gsi, __entry->level, __entry->irq_source_id)
+);
+
+#define kvm_deliver_mode		\
+	{0x0, "Fixed"},			\
+	{0x1, "LowPrio"},		\
+	{0x2, "SMI"},			\
+	{0x3, "Res3"},			\
+	{0x4, "NMI"},			\
+	{0x5, "INIT"},			\
+	{0x6, "SIPI"},			\
+	{0x7, "ExtINT"}
+
+TRACE_EVENT(kvm_ioapic_set_irq,
+	    TP_PROTO(__u64 e, int pin, bool coalesced),
+	    TP_ARGS(e, pin, coalesced),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		e		)
+		__field(	int,		pin		)
+		__field(	bool,		coalesced	)
+	),
+
+	TP_fast_assign(
+		__entry->e		= e;
+		__entry->pin		= pin;
+		__entry->coalesced	= coalesced;
+	),
+
+	TP_printk("pin %u dst %x vec=%u (%s|%s|%s%s)%s",
+		  __entry->pin, (u8)(__entry->e >> 56), (u8)__entry->e,
+		  __print_symbolic((__entry->e >> 8 & 0x7), kvm_deliver_mode),
+		  (__entry->e & (1<<11)) ? "logical" : "physical",
+		  (__entry->e & (1<<15)) ? "level" : "edge",
+		  (__entry->e & (1<<16)) ? "|masked" : "",
+		  __entry->coalesced ? " (coalesced)" : "")
+);
+
+TRACE_EVENT(kvm_msi_set_irq,
+	    TP_PROTO(__u64 address, __u64 data),
+	    TP_ARGS(address, data),
+
+	TP_STRUCT__entry(
+		__field(	__u64,		address		)
+		__field(	__u64,		data		)
+	),
+
+	TP_fast_assign(
+		__entry->address	= address;
+		__entry->data		= data;
+	),
+
+	TP_printk("dst %u vec %x (%s|%s|%s%s)",
+		  (u8)(__entry->address >> 12), (u8)__entry->data,
+		  __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode),
+		  (__entry->address & (1<<2)) ? "logical" : "physical",
+		  (__entry->data & (1<<15)) ? "level" : "edge",
+		  (__entry->address & (1<<3)) ? "|rh" : "")
+);
+
+#define kvm_irqchips						\
+	{KVM_IRQCHIP_PIC_MASTER,	"PIC master"},		\
+	{KVM_IRQCHIP_PIC_SLAVE,		"PIC slave"},		\
+	{KVM_IRQCHIP_IOAPIC,		"IOAPIC"}
+
+TRACE_EVENT(kvm_ack_irq,
+	TP_PROTO(unsigned int irqchip, unsigned int pin),
+	TP_ARGS(irqchip, pin),
+
+	TP_STRUCT__entry(
+		__field(	unsigned int,	irqchip		)
+		__field(	unsigned int,	pin		)
+	),
+
+	TP_fast_assign(
+		__entry->irqchip	= irqchip;
+		__entry->pin		= pin;
+	),
+
+	TP_printk("irqchip %s pin %u",
+		  __print_symbolic(__entry->irqchip, kvm_irqchips),
+		 __entry->pin)
+);
+
+
+
+#endif /* defined(__KVM_HAVE_IOAPIC) */
+
+#define KVM_TRACE_MMIO_READ_UNSATISFIED 0
+#define KVM_TRACE_MMIO_READ 1
+#define KVM_TRACE_MMIO_WRITE 2
+
+#define kvm_trace_symbol_mmio \
+	{ KVM_TRACE_MMIO_READ_UNSATISFIED, "unsatisfied-read" }, \
+	{ KVM_TRACE_MMIO_READ, "read" }, \
+	{ KVM_TRACE_MMIO_WRITE, "write" }
+
+TRACE_EVENT(kvm_mmio,
+	TP_PROTO(int type, int len, u64 gpa, u64 val),
+	TP_ARGS(type, len, gpa, val),
+
+	TP_STRUCT__entry(
+		__field(	u32,	type		)
+		__field(	u32,	len		)
+		__field(	u64,	gpa		)
+		__field(	u64,	val		)
+	),
+
+	TP_fast_assign(
+		__entry->type		= type;
+		__entry->len		= len;
+		__entry->gpa		= gpa;
+		__entry->val		= val;
+	),
+
+	TP_printk("mmio %s len %u gpa 0x%llx val 0x%llx",
+		  __print_symbolic(__entry->type, kvm_trace_symbol_mmio),
+		  __entry->len, __entry->gpa, __entry->val)
+);
+
+#endif /* _TRACE_KVM_MAIN_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
new file mode 100644
index 0000000..ea6d579
--- /dev/null
+++ b/include/trace/events/power.h
@@ -0,0 +1,81 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM power
+
+#if !defined(_TRACE_POWER_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_POWER_H
+
+#include <linux/ktime.h>
+#include <linux/tracepoint.h>
+
+#ifndef _TRACE_POWER_ENUM_
+#define _TRACE_POWER_ENUM_
+enum {
+	POWER_NONE = 0,
+	POWER_CSTATE = 1,
+	POWER_PSTATE = 2,
+};
+#endif
+
+
+
+TRACE_EVENT(power_start,
+
+	TP_PROTO(unsigned int type, unsigned int state),
+
+	TP_ARGS(type, state),
+
+	TP_STRUCT__entry(
+		__field(	u64,		type		)
+		__field(	u64,		state		)
+	),
+
+	TP_fast_assign(
+		__entry->type = type;
+		__entry->state = state;
+	),
+
+	TP_printk("type=%lu state=%lu", (unsigned long)__entry->type, (unsigned long)__entry->state)
+);
+
+TRACE_EVENT(power_end,
+
+	TP_PROTO(int dummy),
+
+	TP_ARGS(dummy),
+
+	TP_STRUCT__entry(
+		__field(	u64,		dummy		)
+	),
+
+	TP_fast_assign(
+		__entry->dummy = 0xffff;
+	),
+
+	TP_printk("dummy=%lu", (unsigned long)__entry->dummy)
+
+);
+
+
+TRACE_EVENT(power_frequency,
+
+	TP_PROTO(unsigned int type, unsigned int state),
+
+	TP_ARGS(type, state),
+
+	TP_STRUCT__entry(
+		__field(	u64,		type		)
+		__field(	u64,		state		)
+	),
+
+	TP_fast_assign(
+		__entry->type = type;
+		__entry->state = state;
+	),
+
+	TP_printk("type=%lu state=%lu", (unsigned long)__entry->type, (unsigned long) __entry->state)
+);
+
+#endif /* _TRACE_POWER_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index b48f1ad..4069c43 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -380,6 +380,39 @@ TRACE_EVENT(sched_stat_wait,
 );
 
 /*
+ * Tracepoint for accounting runtime (time the task is executing
+ * on a CPU).
+ */
+TRACE_EVENT(sched_stat_runtime,
+
+	TP_PROTO(struct task_struct *tsk, u64 runtime, u64 vruntime),
+
+	TP_ARGS(tsk, runtime, vruntime),
+
+	TP_STRUCT__entry(
+		__array( char,	comm,	TASK_COMM_LEN	)
+		__field( pid_t,	pid			)
+		__field( u64,	runtime			)
+		__field( u64,	vruntime			)
+	),
+
+	TP_fast_assign(
+		memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
+		__entry->pid		= tsk->pid;
+		__entry->runtime	= runtime;
+		__entry->vruntime	= vruntime;
+	)
+	TP_perf_assign(
+		__perf_count(runtime);
+	),
+
+	TP_printk("task: %s:%d runtime: %Lu [ns], vruntime: %Lu [ns]",
+			__entry->comm, __entry->pid,
+			(unsigned long long)__entry->runtime,
+			(unsigned long long)__entry->vruntime)
+);
+
+/*
  * Tracepoint for accounting sleep time (time the task is not runnable,
  * including iowait, see below).
  */
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h
index e499863..4b2be6d 100644
--- a/include/trace/events/skb.h
+++ b/include/trace/events/skb.h
@@ -5,6 +5,7 @@
 #define _TRACE_SKB_H
 
 #include <linux/skbuff.h>
+#include <linux/netdevice.h>
 #include <linux/tracepoint.h>
 
 /*
@@ -34,6 +35,25 @@ TRACE_EVENT(kfree_skb,
 		__entry->skbaddr, __entry->protocol, __entry->location)
 );
 
+TRACE_EVENT(skb_copy_datagram_iovec,
+
+	TP_PROTO(const struct sk_buff *skb, int len),
+
+	TP_ARGS(skb, len),
+
+	TP_STRUCT__entry(
+		__field(	const void *,		skbaddr		)
+		__field(	int,			len		)
+	),
+
+	TP_fast_assign(
+		__entry->skbaddr = skb;
+		__entry->len = len;
+	),
+
+	TP_printk("skbaddr=%p len=%d", __entry->skbaddr, __entry->len)
+);
+
 #endif /* _TRACE_SKB_H */
 
 /* This part must be outside protection */
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 308bafd..cc0d966 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -239,9 +239,9 @@ ftrace_format_##call(struct ftrace_event_call *unused,			\
 #undef __print_flags
 #define __print_flags(flag, delim, flag_array...)			\
 	({								\
-		static const struct trace_print_flags flags[] =		\
+		static const struct trace_print_flags __flags[] =	\
 			{ flag_array, { -1, NULL }};			\
-		ftrace_print_flags_seq(p, delim, flag, flags);		\
+		ftrace_print_flags_seq(p, delim, flag, __flags);	\
 	})
 
 #undef __print_symbolic
@@ -254,7 +254,7 @@ ftrace_format_##call(struct ftrace_event_call *unused,			\
 
 #undef TRACE_EVENT
 #define TRACE_EVENT(call, proto, args, tstruct, assign, print)		\
-enum print_line_t							\
+static enum print_line_t						\
 ftrace_raw_output_##call(struct trace_iterator *iter, int flags)	\
 {									\
 	struct trace_seq *s = &iter->seq;				\
@@ -317,7 +317,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags)	\
 
 #undef TRACE_EVENT
 #define TRACE_EVENT(call, proto, args, tstruct, func, print)		\
-int									\
+static int								\
 ftrace_define_fields_##call(struct ftrace_event_call *event_call)	\
 {									\
 	struct ftrace_raw_##call field;					\
@@ -378,24 +378,18 @@ static inline int ftrace_get_offsets_##call(				\
 #ifdef CONFIG_EVENT_PROFILE
 
 /*
- * Generate the functions needed for tracepoint perf_counter support.
+ * Generate the functions needed for tracepoint perf_event support.
  *
  * NOTE: The insertion profile callback (ftrace_profile_<call>) is defined later
  *
- * static int ftrace_profile_enable_<call>(struct ftrace_event_call *event_call)
+ * static int ftrace_profile_enable_<call>(void)
  * {
- * 	int ret = 0;
- *
- * 	if (!atomic_inc_return(&event_call->profile_count))
- * 		ret = register_trace_<call>(ftrace_profile_<call>);
- *
- * 	return ret;
+ * 	return register_trace_<call>(ftrace_profile_<call>);
  * }
  *
- * static void ftrace_profile_disable_<call>(struct ftrace_event_call *event_call)
+ * static void ftrace_profile_disable_<call>(void)
  * {
- * 	if (atomic_add_negative(-1, &event->call->profile_count))
- * 		unregister_trace_<call>(ftrace_profile_<call>);
+ * 	unregister_trace_<call>(ftrace_profile_<call>);
  * }
  *
  */
@@ -405,20 +399,14 @@ static inline int ftrace_get_offsets_##call(				\
 									\
 static void ftrace_profile_##call(proto);				\
 									\
-static int ftrace_profile_enable_##call(struct ftrace_event_call *event_call) \
+static int ftrace_profile_enable_##call(void)				\
 {									\
-	int ret = 0;							\
-									\
-	if (!atomic_inc_return(&event_call->profile_count))		\
-		ret = register_trace_##call(ftrace_profile_##call);	\
-									\
-	return ret;							\
+	return register_trace_##call(ftrace_profile_##call);		\
 }									\
 									\
-static void ftrace_profile_disable_##call(struct ftrace_event_call *event_call)\
+static void ftrace_profile_disable_##call(void)				\
 {									\
-	if (atomic_add_negative(-1, &event_call->profile_count))	\
-		unregister_trace_##call(ftrace_profile_##call);		\
+	unregister_trace_##call(ftrace_profile_##call);			\
 }
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
@@ -656,15 +644,16 @@ __attribute__((section("_ftrace_events"))) event_##call = {		\
  * {
  *	struct ftrace_data_offsets_<call> __maybe_unused __data_offsets;
  *	struct ftrace_event_call *event_call = &event_<call>;
- *	extern void perf_tpcounter_event(int, u64, u64, void *, int);
+ *	extern void perf_tp_event(int, u64, u64, void *, int);
  *	struct ftrace_raw_##call *entry;
  *	u64 __addr = 0, __count = 1;
  *	unsigned long irq_flags;
+ *	struct trace_entry *ent;
  *	int __entry_size;
  *	int __data_size;
+ *	int __cpu
  *	int pc;
  *
- *	local_save_flags(irq_flags);
  *	pc = preempt_count();
  *
  *	__data_size = ftrace_get_offsets_<call>(&__data_offsets, args);
@@ -675,25 +664,34 @@ __attribute__((section("_ftrace_events"))) event_##call = {		\
  *			     sizeof(u64));
  *	__entry_size -= sizeof(u32);
  *
- *	do {
- *		char raw_data[__entry_size]; <- allocate our sample in the stack
- *		struct trace_entry *ent;
+ *	// Protect the non nmi buffer
+ *	// This also protects the rcu read side
+ *	local_irq_save(irq_flags);
+ *	__cpu = smp_processor_id();
+ *
+ *	if (in_nmi())
+ *		raw_data = rcu_dereference(trace_profile_buf_nmi);
+ *	else
+ *		raw_data = rcu_dereference(trace_profile_buf);
+ *
+ *	if (!raw_data)
+ *		goto end;
  *
- *		zero dead bytes from alignment to avoid stack leak to userspace:
+ *	raw_data = per_cpu_ptr(raw_data, __cpu);
  *
- *		*(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;
- *		entry = (struct ftrace_raw_<call> *)raw_data;
- *		ent = &entry->ent;
- *		tracing_generic_entry_update(ent, irq_flags, pc);
- *		ent->type = event_call->id;
+ *	//zero dead bytes from alignment to avoid stack leak to userspace:
+ *	*(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;
+ *	entry = (struct ftrace_raw_<call> *)raw_data;
+ *	ent = &entry->ent;
+ *	tracing_generic_entry_update(ent, irq_flags, pc);
+ *	ent->type = event_call->id;
  *
- *		<tstruct> <- do some jobs with dynamic arrays
+ *	<tstruct> <- do some jobs with dynamic arrays
  *
- *		<assign>  <- affect our values
+ *	<assign>  <- affect our values
  *
- *		perf_tpcounter_event(event_call->id, __addr, __count, entry,
- *			     __entry_size);  <- submit them to perf counter
- *	} while (0);
+ *	perf_tp_event(event_call->id, __addr, __count, entry,
+ *		     __entry_size);  <- submit them to perf counter
  *
  * }
  */
@@ -712,15 +710,17 @@ static void ftrace_profile_##call(proto)				\
 {									\
 	struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
 	struct ftrace_event_call *event_call = &event_##call;		\
-	extern void perf_tpcounter_event(int, u64, u64, void *, int);	\
+	extern void perf_tp_event(int, u64, u64, void *, int);	\
 	struct ftrace_raw_##call *entry;				\
 	u64 __addr = 0, __count = 1;					\
 	unsigned long irq_flags;					\
+	struct trace_entry *ent;					\
 	int __entry_size;						\
 	int __data_size;						\
+	char *raw_data;							\
+	int __cpu;							\
 	int pc;								\
 									\
-	local_save_flags(irq_flags);					\
 	pc = preempt_count();						\
 									\
 	__data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
@@ -728,23 +728,38 @@ static void ftrace_profile_##call(proto)				\
 			     sizeof(u64));				\
 	__entry_size -= sizeof(u32);					\
 									\
-	do {								\
-		char raw_data[__entry_size];				\
-		struct trace_entry *ent;				\
+	if (WARN_ONCE(__entry_size > FTRACE_MAX_PROFILE_SIZE,		\
+		      "profile buffer not large enough"))		\
+		return;							\
+									\
+	local_irq_save(irq_flags);					\
+	__cpu = smp_processor_id();					\
 									\
-		*(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;	\
-		entry = (struct ftrace_raw_##call *)raw_data;		\
-		ent = &entry->ent;					\
-		tracing_generic_entry_update(ent, irq_flags, pc);	\
-		ent->type = event_call->id;				\
+	if (in_nmi())							\
+		raw_data = rcu_dereference(trace_profile_buf_nmi);		\
+	else								\
+		raw_data = rcu_dereference(trace_profile_buf);		\
 									\
-		tstruct							\
+	if (!raw_data)							\
+		goto end;						\
 									\
-		{ assign; }						\
+	raw_data = per_cpu_ptr(raw_data, __cpu);			\
 									\
-		perf_tpcounter_event(event_call->id, __addr, __count, entry,\
+	*(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL;		\
+	entry = (struct ftrace_raw_##call *)raw_data;			\
+	ent = &entry->ent;						\
+	tracing_generic_entry_update(ent, irq_flags, pc);		\
+	ent->type = event_call->id;					\
+									\
+	tstruct								\
+									\
+	{ assign; }							\
+									\
+	perf_tp_event(event_call->id, __addr, __count, entry,		\
 			     __entry_size);				\
-	} while (0);							\
+									\
+end:									\
+	local_irq_restore(irq_flags);					\
 									\
 }
 
diff --git a/init/Kconfig b/init/Kconfig
index 8e8b76d..0aa6579 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -331,7 +331,8 @@ config TREE_PREEMPT_RCU
 	  This option selects the RCU implementation that is
 	  designed for very large SMP systems with hundreds or
 	  thousands of CPUs, but for which real-time response
-	  is also required.
+	  is also required.  It also scales down nicely to
+	  smaller systems.
 
 endchoice
 
@@ -915,31 +916,36 @@ config AIO
           by some high performance threaded applications. Disabling
           this option saves about 7k.
 
-config HAVE_PERF_COUNTERS
+config HAVE_PERF_EVENTS
 	bool
 	help
 	  See tools/perf/design.txt for details.
 
-menu "Performance Counters"
+menu "Kernel Performance Events And Counters"
 
-config PERF_COUNTERS
-	bool "Kernel Performance Counters"
-	default y if PROFILING
-	depends on HAVE_PERF_COUNTERS
+config PERF_EVENTS
+	bool "Kernel performance events and counters"
+	default y if (PROFILING || PERF_COUNTERS)
+	depends on HAVE_PERF_EVENTS
 	select ANON_INODES
 	help
-	  Enable kernel support for performance counter hardware.
+	  Enable kernel support for various performance events provided
+	  by software and hardware.
+
+	  Software events are supported either build-in or via the
+	  use of generic tracepoints.
 
-	  Performance counters are special hardware registers available
-	  on most modern CPUs. These registers count the number of certain
+	  Most modern CPUs support performance events via performance
+	  counter registers. These registers count the number of certain
 	  types of hw events: such as instructions executed, cachemisses
 	  suffered, or branches mis-predicted - without slowing down the
 	  kernel or applications. These registers can also trigger interrupts
 	  when a threshold number of events have passed - and can thus be
 	  used to profile the code that runs on that CPU.
 
-	  The Linux Performance Counter subsystem provides an abstraction of
-	  these hardware capabilities, available via a system call. It
+	  The Linux Performance Event subsystem provides an abstraction of
+	  these software and hardware cevent apabilities, available via a
+	  system call and used by the "perf" utility in tools/perf/. It
 	  provides per task and per CPU counters, and it provides event
 	  capabilities on top of those.
 
@@ -947,17 +953,29 @@ config PERF_COUNTERS
 
 config EVENT_PROFILE
 	bool "Tracepoint profiling sources"
-	depends on PERF_COUNTERS && EVENT_TRACING
+	depends on PERF_EVENTS && EVENT_TRACING
 	default y
 	help
-	 Allow the use of tracepoints as software performance counters.
+	 Allow the use of tracepoints as software performance events.
 
-	 When this is enabled, you can create perf counters based on
+	 When this is enabled, you can create perf events based on
 	 tracepoints using PERF_TYPE_TRACEPOINT and the tracepoint ID
 	 found in debugfs://tracing/events/*/*/id. (The -e/--events
 	 option to the perf tool can parse and interpret symbolic
 	 tracepoints, in the subsystem:tracepoint_name format.)
 
+config PERF_COUNTERS
+	bool "Kernel performance counters (old config option)"
+	depends on HAVE_PERF_EVENTS
+	help
+	  This config has been obsoleted by the PERF_EVENTS
+	  config option - please see that one for details.
+
+	  It has no effect on the kernel whether you enable
+	  it or not, it is a compatibility placeholder.
+
+	  Say N if unsure.
+
 endmenu
 
 config VM_EVENT_COUNTERS
@@ -1054,13 +1072,6 @@ config PROFILING
 config TRACEPOINTS
 	bool
 
-config MARKERS
-	bool "Activate markers"
-	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
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 093f659..bb008d0 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -415,7 +415,7 @@ void __init prepare_namespace(void)
 
 	mount_root();
 out:
+	devtmpfs_mount("dev");
 	sys_mount(".", "/", NULL, MS_MOVE, NULL);
 	sys_chroot(".");
 }
-
diff --git a/init/main.c b/init/main.c
index b34fd8e..34971be 100644
--- a/init/main.c
+++ b/init/main.c
@@ -68,6 +68,7 @@
 #include <linux/async.h>
 #include <linux/kmemcheck.h>
 #include <linux/kmemtrace.h>
+#include <linux/shmem_fs.h>
 #include <trace/boot.h>
 
 #include <asm/io.h>
@@ -353,7 +354,6 @@ static void __init smp_init(void)
 #define smp_init()	do { } while (0)
 #endif
 
-static inline void setup_per_cpu_areas(void) { }
 static inline void setup_nr_cpu_ids(void) { }
 static inline void smp_prepare_cpus(unsigned int maxcpus) { }
 
@@ -374,29 +374,6 @@ static void __init setup_nr_cpu_ids(void)
 	nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1;
 }
 
-#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
-
-EXPORT_SYMBOL(__per_cpu_offset);
-
-static void __init setup_per_cpu_areas(void)
-{
-	unsigned long size, i;
-	char *ptr;
-	unsigned long nr_possible_cpus = num_possible_cpus();
-
-	/* Copy section for each CPU (we discard the original) */
-	size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
-	ptr = alloc_bootmem_pages(size * nr_possible_cpus);
-
-	for_each_possible_cpu(i) {
-		__per_cpu_offset[i] = ptr - __per_cpu_start;
-		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-		ptr += size;
-	}
-}
-#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
-
 /* Called by boot processor to activate the rest. */
 static void __init smp_init(void)
 {
@@ -809,6 +786,7 @@ static void __init do_basic_setup(void)
 	init_workqueues();
 	cpuset_init_smp();
 	usermodehelper_init();
+	init_tmpfs();
 	driver_init();
 	init_irq_proc();
 	do_ctors();
diff --git a/ipc/shm.c b/ipc/shm.c
index 1bc4701..30162a5 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -410,7 +410,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
 	return error;
 
 no_id:
-	if (shp->mlock_user)	/* shmflg & SHM_HUGETLB case */
+	if (is_file_hugepages(file) && shp->mlock_user)
 		user_shm_unlock(size, shp->mlock_user);
 	fput(file);
 no_file:
diff --git a/kernel/Makefile b/kernel/Makefile
index b833bd5..187c89b 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -87,17 +87,15 @@ obj-$(CONFIG_RELAY) += relay.o
 obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
-obj-$(CONFIG_MARKERS) += marker.o
 obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
 obj-$(CONFIG_LATENCYTOP) += latencytop.o
-obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
 obj-$(CONFIG_FUNCTION_TRACER) += trace/
 obj-$(CONFIG_TRACING) += trace/
 obj-$(CONFIG_X86_DS) += trace/
 obj-$(CONFIG_RING_BUFFER) += trace/
 obj-$(CONFIG_SMP) += sched_cpupri.o
 obj-$(CONFIG_SLOW_WORK) += slow-work.o
-obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o
+obj-$(CONFIG_PERF_EVENTS) += perf_event.o
 
 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
@@ -117,7 +115,7 @@ $(obj)/config_data.gz: .config FORCE
 	$(call if_changed,gzip)
 
 quiet_cmd_ikconfiggz = IKCFG   $@
-      cmd_ikconfiggz = (echo "static const char kernel_config_data[] = MAGIC_START"; cat $< | scripts/bin2c; echo "MAGIC_END;") > $@
+      cmd_ikconfiggz = (echo "static const char kernel_config_data[] __used = MAGIC_START"; cat $< | scripts/bin2c; echo "MAGIC_END;") > $@
 targets += config_data.h
 $(obj)/config_data.h: $(obj)/config_data.gz FORCE
 	$(call if_changed,ikconfiggz)
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 8ce1004..6ba0f1e 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -401,6 +401,7 @@ int disable_nonboot_cpus(void)
 			break;
 		}
 	}
+
 	if (!error) {
 		BUG_ON(num_online_cpus() > 1);
 		/* Make sure the CPUs won't be enabled by someone else */
@@ -413,6 +414,14 @@ int disable_nonboot_cpus(void)
 	return error;
 }
 
+void __weak arch_enable_nonboot_cpus_begin(void)
+{
+}
+
+void __weak arch_enable_nonboot_cpus_end(void)
+{
+}
+
 void __ref enable_nonboot_cpus(void)
 {
 	int cpu, error;
@@ -424,6 +433,9 @@ void __ref enable_nonboot_cpus(void)
 		goto out;
 
 	printk("Enabling non-boot CPUs ...\n");
+
+	arch_enable_nonboot_cpus_begin();
+
 	for_each_cpu(cpu, frozen_cpus) {
 		error = _cpu_up(cpu, 1);
 		if (!error) {
@@ -432,6 +444,9 @@ void __ref enable_nonboot_cpus(void)
 		}
 		printk(KERN_WARNING "Error taking CPU%d up: %d\n", cpu, error);
 	}
+
+	arch_enable_nonboot_cpus_end();
+
 	cpumask_clear(frozen_cpus);
 out:
 	cpu_maps_update_done();
diff --git a/kernel/cred.c b/kernel/cred.c
index 006fcab..d7f7a01 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -147,7 +147,8 @@ static void put_cred_rcu(struct rcu_head *rcu)
 	key_put(cred->thread_keyring);
 	key_put(cred->request_key_auth);
 	release_tgcred(cred);
-	put_group_info(cred->group_info);
+	if (cred->group_info)
+		put_group_info(cred->group_info);
 	free_uid(cred->user);
 	kmem_cache_free(cred_jar, cred);
 }
diff --git a/kernel/delayacct.c b/kernel/delayacct.c
index abb6e17..ead9b61 100644
--- a/kernel/delayacct.c
+++ b/kernel/delayacct.c
@@ -15,6 +15,7 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/taskstats.h>
 #include <linux/time.h>
 #include <linux/sysctl.h>
 #include <linux/delayacct.h>
diff --git a/kernel/dma-coherent.c b/kernel/dma-coherent.c
deleted file mode 100644
index 962a3b5..0000000
--- a/kernel/dma-coherent.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Coherent per-device memory handling.
- * Borrowed from i386
- */
-#include <linux/kernel.h>
-#include <linux/dma-mapping.h>
-
-struct dma_coherent_mem {
-	void		*virt_base;
-	u32		device_base;
-	int		size;
-	int		flags;
-	unsigned long	*bitmap;
-};
-
-int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-				dma_addr_t device_addr, size_t size, int flags)
-{
-	void __iomem *mem_base = NULL;
-	int pages = size >> PAGE_SHIFT;
-	int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
-
-	if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
-		goto out;
-	if (!size)
-		goto out;
-	if (dev->dma_mem)
-		goto out;
-
-	/* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
-
-	mem_base = ioremap(bus_addr, size);
-	if (!mem_base)
-		goto out;
-
-	dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
-	if (!dev->dma_mem)
-		goto out;
-	dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!dev->dma_mem->bitmap)
-		goto free1_out;
-
-	dev->dma_mem->virt_base = mem_base;
-	dev->dma_mem->device_base = device_addr;
-	dev->dma_mem->size = pages;
-	dev->dma_mem->flags = flags;
-
-	if (flags & DMA_MEMORY_MAP)
-		return DMA_MEMORY_MAP;
-
-	return DMA_MEMORY_IO;
-
- free1_out:
-	kfree(dev->dma_mem);
- out:
-	if (mem_base)
-		iounmap(mem_base);
-	return 0;
-}
-EXPORT_SYMBOL(dma_declare_coherent_memory);
-
-void dma_release_declared_memory(struct device *dev)
-{
-	struct dma_coherent_mem *mem = dev->dma_mem;
-
-	if (!mem)
-		return;
-	dev->dma_mem = NULL;
-	iounmap(mem->virt_base);
-	kfree(mem->bitmap);
-	kfree(mem);
-}
-EXPORT_SYMBOL(dma_release_declared_memory);
-
-void *dma_mark_declared_memory_occupied(struct device *dev,
-					dma_addr_t device_addr, size_t size)
-{
-	struct dma_coherent_mem *mem = dev->dma_mem;
-	int pos, err;
-
-	size += device_addr & ~PAGE_MASK;
-
-	if (!mem)
-		return ERR_PTR(-EINVAL);
-
-	pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
-	err = bitmap_allocate_region(mem->bitmap, pos, get_order(size));
-	if (err != 0)
-		return ERR_PTR(err);
-	return mem->virt_base + (pos << PAGE_SHIFT);
-}
-EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
-
-/**
- * dma_alloc_from_coherent() - try to allocate memory from the per-device coherent area
- *
- * @dev:	device from which we allocate memory
- * @size:	size of requested memory area
- * @dma_handle:	This will be filled with the correct dma handle
- * @ret:	This pointer will be filled with the virtual address
- *		to allocated area.
- *
- * This function should be only called from per-arch dma_alloc_coherent()
- * to support allocation from per-device coherent memory pools.
- *
- * Returns 0 if dma_alloc_coherent should continue with allocating from
- * generic memory areas, or !0 if dma_alloc_coherent should return @ret.
- */
-int dma_alloc_from_coherent(struct device *dev, ssize_t size,
-				       dma_addr_t *dma_handle, void **ret)
-{
-	struct dma_coherent_mem *mem;
-	int order = get_order(size);
-	int pageno;
-
-	if (!dev)
-		return 0;
-	mem = dev->dma_mem;
-	if (!mem)
-		return 0;
-
-	*ret = NULL;
-
-	if (unlikely(size > (mem->size << PAGE_SHIFT)))
-		goto err;
-
-	pageno = bitmap_find_free_region(mem->bitmap, mem->size, order);
-	if (unlikely(pageno < 0))
-		goto err;
-
-	/*
-	 * Memory was found in the per-device area.
-	 */
-	*dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
-	*ret = mem->virt_base + (pageno << PAGE_SHIFT);
-	memset(*ret, 0, size);
-
-	return 1;
-
-err:
-	/*
-	 * In the case where the allocation can not be satisfied from the
-	 * per-device area, try to fall back to generic memory if the
-	 * constraints allow it.
-	 */
-	return mem->flags & DMA_MEMORY_EXCLUSIVE;
-}
-EXPORT_SYMBOL(dma_alloc_from_coherent);
-
-/**
- * dma_release_from_coherent() - try to free the memory allocated from per-device coherent memory pool
- * @dev:	device from which the memory was allocated
- * @order:	the order of pages allocated
- * @vaddr:	virtual address of allocated pages
- *
- * This checks whether the memory was allocated from the per-device
- * coherent memory pool and if so, releases that memory.
- *
- * Returns 1 if we correctly released the memory, or 0 if
- * dma_release_coherent() should proceed with releasing memory from
- * generic pools.
- */
-int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
-{
-	struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
-
-	if (mem && vaddr >= mem->virt_base && vaddr <
-		   (mem->virt_base + (mem->size << PAGE_SHIFT))) {
-		int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
-
-		bitmap_release_region(mem->bitmap, page, order);
-		return 1;
-	}
-	return 0;
-}
-EXPORT_SYMBOL(dma_release_from_coherent);
diff --git a/kernel/exit.c b/kernel/exit.c
index ae5d866..e47ee8a 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -47,7 +47,7 @@
 #include <linux/tracehook.h>
 #include <linux/fs_struct.h>
 #include <linux/init_task.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <trace/events/sched.h>
 
 #include <asm/uaccess.h>
@@ -154,8 +154,8 @@ static void delayed_put_task_struct(struct rcu_head *rhp)
 {
 	struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
 
-#ifdef CONFIG_PERF_COUNTERS
-	WARN_ON_ONCE(tsk->perf_counter_ctxp);
+#ifdef CONFIG_PERF_EVENTS
+	WARN_ON_ONCE(tsk->perf_event_ctxp);
 #endif
 	trace_sched_process_free(tsk);
 	put_task_struct(tsk);
@@ -981,7 +981,7 @@ NORET_TYPE void do_exit(long code)
 	 * Flush inherited counters to the parent - before the parent
 	 * gets woken up by child-exit notifications.
 	 */
-	perf_counter_exit_task(tsk);
+	perf_event_exit_task(tsk);
 
 	exit_notify(tsk, group_dead);
 #ifdef CONFIG_NUMA
diff --git a/kernel/fork.c b/kernel/fork.c
index bfee931..2cebfb2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -61,7 +61,7 @@
 #include <linux/blkdev.h>
 #include <linux/fs_struct.h>
 #include <linux/magic.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -1078,7 +1078,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	/* Perform scheduler related setup. Assign this task to a CPU. */
 	sched_fork(p, clone_flags);
 
-	retval = perf_counter_init_task(p);
+	retval = perf_event_init_task(p);
 	if (retval)
 		goto bad_fork_cleanup_policy;
 
@@ -1253,7 +1253,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
 	write_unlock_irq(&tasklist_lock);
 	proc_fork_connector(p);
 	cgroup_post_fork(p);
-	perf_counter_fork(p);
+	perf_event_fork(p);
 	return p;
 
 bad_fork_free_pid:
@@ -1280,7 +1280,7 @@ bad_fork_cleanup_semundo:
 bad_fork_cleanup_audit:
 	audit_free(p);
 bad_fork_cleanup_policy:
-	perf_counter_free_task(p);
+	perf_event_free_task(p);
 #ifdef CONFIG_NUMA
 	mpol_put(p->mempolicy);
 bad_fork_cleanup_cgroup:
diff --git a/kernel/gcov/Kconfig b/kernel/gcov/Kconfig
index 22e9dcf..654efd0 100644
--- a/kernel/gcov/Kconfig
+++ b/kernel/gcov/Kconfig
@@ -34,7 +34,7 @@ config GCOV_KERNEL
 config GCOV_PROFILE_ALL
 	bool "Profile entire Kernel"
 	depends on GCOV_KERNEL
-	depends on S390 || X86
+	depends on S390 || X86 || (PPC && EXPERIMENTAL)
 	default n
 	---help---
 	This options activates profiling for the entire kernel.
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 49da79a..c03f221 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -48,37 +48,6 @@
 
 #include <asm/uaccess.h>
 
-/**
- * ktime_get - get the monotonic time in ktime_t format
- *
- * returns the time in ktime_t format
- */
-ktime_t ktime_get(void)
-{
-	struct timespec now;
-
-	ktime_get_ts(&now);
-
-	return timespec_to_ktime(now);
-}
-EXPORT_SYMBOL_GPL(ktime_get);
-
-/**
- * ktime_get_real - get the real (wall-) time in ktime_t format
- *
- * returns the time in ktime_t format
- */
-ktime_t ktime_get_real(void)
-{
-	struct timespec now;
-
-	getnstimeofday(&now);
-
-	return timespec_to_ktime(now);
-}
-
-EXPORT_SYMBOL_GPL(ktime_get_real);
-
 /*
  * The timer bases:
  *
@@ -106,31 +75,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
 	}
 };
 
-/**
- * ktime_get_ts - get the monotonic clock in timespec format
- * @ts:		pointer to timespec variable
- *
- * The function calculates the monotonic clock from the realtime
- * clock and the wall_to_monotonic offset and stores the result
- * in normalized timespec format in the variable pointed to by @ts.
- */
-void ktime_get_ts(struct timespec *ts)
-{
-	struct timespec tomono;
-	unsigned long seq;
-
-	do {
-		seq = read_seqbegin(&xtime_lock);
-		getnstimeofday(ts);
-		tomono = wall_to_monotonic;
-
-	} while (read_seqretry(&xtime_lock, seq));
-
-	set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
-				ts->tv_nsec + tomono.tv_nsec);
-}
-EXPORT_SYMBOL_GPL(ktime_get_ts);
-
 /*
  * Get the coarse grained time at the softirq based on xtime and
  * wall_to_monotonic.
@@ -485,6 +429,7 @@ void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t clock_id,
 	debug_object_init_on_stack(timer, &hrtimer_debug_descr);
 	__hrtimer_init(timer, clock_id, mode);
 }
+EXPORT_SYMBOL_GPL(hrtimer_init_on_stack);
 
 void destroy_hrtimer_on_stack(struct hrtimer *timer)
 {
@@ -1154,7 +1099,6 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
 		clock_id = CLOCK_MONOTONIC;
 
 	timer->base = &cpu_base->clock_base[clock_id];
-	INIT_LIST_HEAD(&timer->cb_entry);
 	hrtimer_init_timer_hres(timer);
 
 #ifdef CONFIG_TIMER_STATS
@@ -1477,6 +1421,7 @@ void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *task)
 	sl->timer.function = hrtimer_wakeup;
 	sl->task = task;
 }
+EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
 
 static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
 {
diff --git a/kernel/kfifo.c b/kernel/kfifo.c
index 26539e3..3765ff3 100644
--- a/kernel/kfifo.c
+++ b/kernel/kfifo.c
@@ -117,7 +117,7 @@ EXPORT_SYMBOL(kfifo_free);
  * writer, you don't need extra locking to use these functions.
  */
 unsigned int __kfifo_put(struct kfifo *fifo,
-			 unsigned char *buffer, unsigned int len)
+			const unsigned char *buffer, unsigned int len)
 {
 	unsigned int l;
 
diff --git a/kernel/marker.c b/kernel/marker.c
deleted file mode 100644
index ea54f26..0000000
--- a/kernel/marker.c
+++ /dev/null
@@ -1,930 +0,0 @@
-/*
- * Copyright (C) 2007 Mathieu Desnoyers
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU 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/module.h>
-#include <linux/mutex.h>
-#include <linux/types.h>
-#include <linux/jhash.h>
-#include <linux/list.h>
-#include <linux/rcupdate.h>
-#include <linux/marker.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-
-extern struct marker __start___markers[];
-extern struct marker __stop___markers[];
-
-/* Set to 1 to enable marker debug output */
-static const int marker_debug;
-
-/*
- * markers_mutex nests inside module_mutex. Markers mutex protects the builtin
- * and module markers and the hash table.
- */
-static DEFINE_MUTEX(markers_mutex);
-
-/*
- * Marker hash table, containing the active markers.
- * Protected by module_mutex.
- */
-#define MARKER_HASH_BITS 6
-#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS)
-static struct hlist_head marker_table[MARKER_TABLE_SIZE];
-
-/*
- * Note about RCU :
- * It is used to make sure every handler has finished using its private data
- * between two consecutive operation (add or remove) on a given marker.  It is
- * also used to delay the free of multiple probes array until a quiescent state
- * is reached.
- * marker entries modifications are protected by the markers_mutex.
- */
-struct marker_entry {
-	struct hlist_node hlist;
-	char *format;
-			/* Probe wrapper */
-	void (*call)(const struct marker *mdata, void *call_private, ...);
-	struct marker_probe_closure single;
-	struct marker_probe_closure *multi;
-	int refcount;	/* Number of times armed. 0 if disarmed. */
-	struct rcu_head rcu;
-	void *oldptr;
-	int rcu_pending;
-	unsigned char ptype:1;
-	unsigned char format_allocated:1;
-	char name[0];	/* Contains name'\0'format'\0' */
-};
-
-/**
- * __mark_empty_function - Empty probe callback
- * @probe_private: probe private data
- * @call_private: call site private data
- * @fmt: format string
- * @...: variable argument list
- *
- * Empty callback provided as a probe to the markers. By providing this to a
- * disabled marker, we make sure the  execution flow is always valid even
- * though the function pointer change and the marker enabling are two distinct
- * operations that modifies the execution flow of preemptible code.
- */
-notrace void __mark_empty_function(void *probe_private, void *call_private,
-	const char *fmt, va_list *args)
-{
-}
-EXPORT_SYMBOL_GPL(__mark_empty_function);
-
-/*
- * marker_probe_cb Callback that prepares the variable argument list for probes.
- * @mdata: pointer of type struct marker
- * @call_private: caller site private data
- * @...:  Variable argument list.
- *
- * Since we do not use "typical" pointer based RCU in the 1 argument case, we
- * need to put a full smp_rmb() in this branch. This is why we do not use
- * rcu_dereference() for the pointer read.
- */
-notrace void marker_probe_cb(const struct marker *mdata,
-		void *call_private, ...)
-{
-	va_list args;
-	char ptype;
-
-	/*
-	 * rcu_read_lock_sched does two things : disabling preemption to make
-	 * sure the teardown of the callbacks can be done correctly when they
-	 * are in modules and they insure RCU read coherency.
-	 */
-	rcu_read_lock_sched_notrace();
-	ptype = mdata->ptype;
-	if (likely(!ptype)) {
-		marker_probe_func *func;
-		/* Must read the ptype before ptr. They are not data dependant,
-		 * so we put an explicit smp_rmb() here. */
-		smp_rmb();
-		func = mdata->single.func;
-		/* Must read the ptr before private data. They are not data
-		 * dependant, so we put an explicit smp_rmb() here. */
-		smp_rmb();
-		va_start(args, call_private);
-		func(mdata->single.probe_private, call_private, mdata->format,
-			&args);
-		va_end(args);
-	} else {
-		struct marker_probe_closure *multi;
-		int i;
-		/*
-		 * Read mdata->ptype before mdata->multi.
-		 */
-		smp_rmb();
-		multi = mdata->multi;
-		/*
-		 * multi points to an array, therefore accessing the array
-		 * depends on reading multi. However, even in this case,
-		 * we must insure that the pointer is read _before_ the array
-		 * data. Same as rcu_dereference, but we need a full smp_rmb()
-		 * in the fast path, so put the explicit barrier here.
-		 */
-		smp_read_barrier_depends();
-		for (i = 0; multi[i].func; i++) {
-			va_start(args, call_private);
-			multi[i].func(multi[i].probe_private, call_private,
-				mdata->format, &args);
-			va_end(args);
-		}
-	}
-	rcu_read_unlock_sched_notrace();
-}
-EXPORT_SYMBOL_GPL(marker_probe_cb);
-
-/*
- * marker_probe_cb Callback that does not prepare the variable argument list.
- * @mdata: pointer of type struct marker
- * @call_private: caller site private data
- * @...:  Variable argument list.
- *
- * Should be connected to markers "MARK_NOARGS".
- */
-static notrace void marker_probe_cb_noarg(const struct marker *mdata,
-		void *call_private, ...)
-{
-	va_list args;	/* not initialized */
-	char ptype;
-
-	rcu_read_lock_sched_notrace();
-	ptype = mdata->ptype;
-	if (likely(!ptype)) {
-		marker_probe_func *func;
-		/* Must read the ptype before ptr. They are not data dependant,
-		 * so we put an explicit smp_rmb() here. */
-		smp_rmb();
-		func = mdata->single.func;
-		/* Must read the ptr before private data. They are not data
-		 * dependant, so we put an explicit smp_rmb() here. */
-		smp_rmb();
-		func(mdata->single.probe_private, call_private, mdata->format,
-			&args);
-	} else {
-		struct marker_probe_closure *multi;
-		int i;
-		/*
-		 * Read mdata->ptype before mdata->multi.
-		 */
-		smp_rmb();
-		multi = mdata->multi;
-		/*
-		 * multi points to an array, therefore accessing the array
-		 * depends on reading multi. However, even in this case,
-		 * we must insure that the pointer is read _before_ the array
-		 * data. Same as rcu_dereference, but we need a full smp_rmb()
-		 * in the fast path, so put the explicit barrier here.
-		 */
-		smp_read_barrier_depends();
-		for (i = 0; multi[i].func; i++)
-			multi[i].func(multi[i].probe_private, call_private,
-				mdata->format, &args);
-	}
-	rcu_read_unlock_sched_notrace();
-}
-
-static void free_old_closure(struct rcu_head *head)
-{
-	struct marker_entry *entry = container_of(head,
-		struct marker_entry, rcu);
-	kfree(entry->oldptr);
-	/* Make sure we free the data before setting the pending flag to 0 */
-	smp_wmb();
-	entry->rcu_pending = 0;
-}
-
-static void debug_print_probes(struct marker_entry *entry)
-{
-	int i;
-
-	if (!marker_debug)
-		return;
-
-	if (!entry->ptype) {
-		printk(KERN_DEBUG "Single probe : %p %p\n",
-			entry->single.func,
-			entry->single.probe_private);
-	} else {
-		for (i = 0; entry->multi[i].func; i++)
-			printk(KERN_DEBUG "Multi probe %d : %p %p\n", i,
-				entry->multi[i].func,
-				entry->multi[i].probe_private);
-	}
-}
-
-static struct marker_probe_closure *
-marker_entry_add_probe(struct marker_entry *entry,
-		marker_probe_func *probe, void *probe_private)
-{
-	int nr_probes = 0;
-	struct marker_probe_closure *old, *new;
-
-	WARN_ON(!probe);
-
-	debug_print_probes(entry);
-	old = entry->multi;
-	if (!entry->ptype) {
-		if (entry->single.func == probe &&
-				entry->single.probe_private == probe_private)
-			return ERR_PTR(-EBUSY);
-		if (entry->single.func == __mark_empty_function) {
-			/* 0 -> 1 probes */
-			entry->single.func = probe;
-			entry->single.probe_private = probe_private;
-			entry->refcount = 1;
-			entry->ptype = 0;
-			debug_print_probes(entry);
-			return NULL;
-		} else {
-			/* 1 -> 2 probes */
-			nr_probes = 1;
-			old = NULL;
-		}
-	} else {
-		/* (N -> N+1), (N != 0, 1) probes */
-		for (nr_probes = 0; old[nr_probes].func; nr_probes++)
-			if (old[nr_probes].func == probe
-					&& old[nr_probes].probe_private
-						== probe_private)
-				return ERR_PTR(-EBUSY);
-	}
-	/* + 2 : one for new probe, one for NULL func */
-	new = kzalloc((nr_probes + 2) * sizeof(struct marker_probe_closure),
-			GFP_KERNEL);
-	if (new == NULL)
-		return ERR_PTR(-ENOMEM);
-	if (!old)
-		new[0] = entry->single;
-	else
-		memcpy(new, old,
-			nr_probes * sizeof(struct marker_probe_closure));
-	new[nr_probes].func = probe;
-	new[nr_probes].probe_private = probe_private;
-	entry->refcount = nr_probes + 1;
-	entry->multi = new;
-	entry->ptype = 1;
-	debug_print_probes(entry);
-	return old;
-}
-
-static struct marker_probe_closure *
-marker_entry_remove_probe(struct marker_entry *entry,
-		marker_probe_func *probe, void *probe_private)
-{
-	int nr_probes = 0, nr_del = 0, i;
-	struct marker_probe_closure *old, *new;
-
-	old = entry->multi;
-
-	debug_print_probes(entry);
-	if (!entry->ptype) {
-		/* 0 -> N is an error */
-		WARN_ON(entry->single.func == __mark_empty_function);
-		/* 1 -> 0 probes */
-		WARN_ON(probe && entry->single.func != probe);
-		WARN_ON(entry->single.probe_private != probe_private);
-		entry->single.func = __mark_empty_function;
-		entry->refcount = 0;
-		entry->ptype = 0;
-		debug_print_probes(entry);
-		return NULL;
-	} else {
-		/* (N -> M), (N > 1, M >= 0) probes */
-		for (nr_probes = 0; old[nr_probes].func; nr_probes++) {
-			if ((!probe || old[nr_probes].func == probe)
-					&& old[nr_probes].probe_private
-						== probe_private)
-				nr_del++;
-		}
-	}
-
-	if (nr_probes - nr_del == 0) {
-		/* N -> 0, (N > 1) */
-		entry->single.func = __mark_empty_function;
-		entry->refcount = 0;
-		entry->ptype = 0;
-	} else if (nr_probes - nr_del == 1) {
-		/* N -> 1, (N > 1) */
-		for (i = 0; old[i].func; i++)
-			if ((probe && old[i].func != probe) ||
-					old[i].probe_private != probe_private)
-				entry->single = old[i];
-		entry->refcount = 1;
-		entry->ptype = 0;
-	} else {
-		int j = 0;
-		/* N -> M, (N > 1, M > 1) */
-		/* + 1 for NULL */
-		new = kzalloc((nr_probes - nr_del + 1)
-			* sizeof(struct marker_probe_closure), GFP_KERNEL);
-		if (new == NULL)
-			return ERR_PTR(-ENOMEM);
-		for (i = 0; old[i].func; i++)
-			if ((probe && old[i].func != probe) ||
-					old[i].probe_private != probe_private)
-				new[j++] = old[i];
-		entry->refcount = nr_probes - nr_del;
-		entry->ptype = 1;
-		entry->multi = new;
-	}
-	debug_print_probes(entry);
-	return old;
-}
-
-/*
- * Get marker if the marker is present in the marker hash table.
- * Must be called with markers_mutex held.
- * Returns NULL if not present.
- */
-static struct marker_entry *get_marker(const char *name)
-{
-	struct hlist_head *head;
-	struct hlist_node *node;
-	struct marker_entry *e;
-	u32 hash = jhash(name, strlen(name), 0);
-
-	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
-	hlist_for_each_entry(e, node, head, hlist) {
-		if (!strcmp(name, e->name))
-			return e;
-	}
-	return NULL;
-}
-
-/*
- * Add the marker to the marker hash table. Must be called with markers_mutex
- * held.
- */
-static struct marker_entry *add_marker(const char *name, const char *format)
-{
-	struct hlist_head *head;
-	struct hlist_node *node;
-	struct marker_entry *e;
-	size_t name_len = strlen(name) + 1;
-	size_t format_len = 0;
-	u32 hash = jhash(name, name_len-1, 0);
-
-	if (format)
-		format_len = strlen(format) + 1;
-	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
-	hlist_for_each_entry(e, node, head, hlist) {
-		if (!strcmp(name, e->name)) {
-			printk(KERN_NOTICE
-				"Marker %s busy\n", name);
-			return ERR_PTR(-EBUSY);	/* Already there */
-		}
-	}
-	/*
-	 * Using kmalloc here to allocate a variable length element. Could
-	 * cause some memory fragmentation if overused.
-	 */
-	e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
-			GFP_KERNEL);
-	if (!e)
-		return ERR_PTR(-ENOMEM);
-	memcpy(&e->name[0], name, name_len);
-	if (format) {
-		e->format = &e->name[name_len];
-		memcpy(e->format, format, format_len);
-		if (strcmp(e->format, MARK_NOARGS) == 0)
-			e->call = marker_probe_cb_noarg;
-		else
-			e->call = marker_probe_cb;
-		trace_mark(core_marker_format, "name %s format %s",
-				e->name, e->format);
-	} else {
-		e->format = NULL;
-		e->call = marker_probe_cb;
-	}
-	e->single.func = __mark_empty_function;
-	e->single.probe_private = NULL;
-	e->multi = NULL;
-	e->ptype = 0;
-	e->format_allocated = 0;
-	e->refcount = 0;
-	e->rcu_pending = 0;
-	hlist_add_head(&e->hlist, head);
-	return e;
-}
-
-/*
- * Remove the marker from the marker hash table. Must be called with mutex_lock
- * held.
- */
-static int remove_marker(const char *name)
-{
-	struct hlist_head *head;
-	struct hlist_node *node;
-	struct marker_entry *e;
-	int found = 0;
-	size_t len = strlen(name) + 1;
-	u32 hash = jhash(name, len-1, 0);
-
-	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
-	hlist_for_each_entry(e, node, head, hlist) {
-		if (!strcmp(name, e->name)) {
-			found = 1;
-			break;
-		}
-	}
-	if (!found)
-		return -ENOENT;
-	if (e->single.func != __mark_empty_function)
-		return -EBUSY;
-	hlist_del(&e->hlist);
-	if (e->format_allocated)
-		kfree(e->format);
-	/* Make sure the call_rcu has been executed */
-	if (e->rcu_pending)
-		rcu_barrier_sched();
-	kfree(e);
-	return 0;
-}
-
-/*
- * Set the mark_entry format to the format found in the element.
- */
-static int marker_set_format(struct marker_entry *entry, const char *format)
-{
-	entry->format = kstrdup(format, GFP_KERNEL);
-	if (!entry->format)
-		return -ENOMEM;
-	entry->format_allocated = 1;
-
-	trace_mark(core_marker_format, "name %s format %s",
-			entry->name, entry->format);
-	return 0;
-}
-
-/*
- * Sets the probe callback corresponding to one marker.
- */
-static int set_marker(struct marker_entry *entry, struct marker *elem,
-		int active)
-{
-	int ret = 0;
-	WARN_ON(strcmp(entry->name, elem->name) != 0);
-
-	if (entry->format) {
-		if (strcmp(entry->format, elem->format) != 0) {
-			printk(KERN_NOTICE
-				"Format mismatch for probe %s "
-				"(%s), marker (%s)\n",
-				entry->name,
-				entry->format,
-				elem->format);
-			return -EPERM;
-		}
-	} else {
-		ret = marker_set_format(entry, elem->format);
-		if (ret)
-			return ret;
-	}
-
-	/*
-	 * probe_cb setup (statically known) is done here. It is
-	 * asynchronous with the rest of execution, therefore we only
-	 * pass from a "safe" callback (with argument) to an "unsafe"
-	 * callback (does not set arguments).
-	 */
-	elem->call = entry->call;
-	/*
-	 * Sanity check :
-	 * We only update the single probe private data when the ptr is
-	 * set to a _non_ single probe! (0 -> 1 and N -> 1, N != 1)
-	 */
-	WARN_ON(elem->single.func != __mark_empty_function
-		&& elem->single.probe_private != entry->single.probe_private
-		&& !elem->ptype);
-	elem->single.probe_private = entry->single.probe_private;
-	/*
-	 * Make sure the private data is valid when we update the
-	 * single probe ptr.
-	 */
-	smp_wmb();
-	elem->single.func = entry->single.func;
-	/*
-	 * We also make sure that the new probe callbacks array is consistent
-	 * before setting a pointer to it.
-	 */
-	rcu_assign_pointer(elem->multi, entry->multi);
-	/*
-	 * Update the function or multi probe array pointer before setting the
-	 * ptype.
-	 */
-	smp_wmb();
-	elem->ptype = entry->ptype;
-
-	if (elem->tp_name && (active ^ elem->state)) {
-		WARN_ON(!elem->tp_cb);
-		/*
-		 * It is ok to directly call the probe registration because type
-		 * checking has been done in the __trace_mark_tp() macro.
-		 */
-
-		if (active) {
-			/*
-			 * try_module_get should always succeed because we hold
-			 * lock_module() to get the tp_cb address.
-			 */
-			ret = try_module_get(__module_text_address(
-				(unsigned long)elem->tp_cb));
-			BUG_ON(!ret);
-			ret = tracepoint_probe_register_noupdate(
-				elem->tp_name,
-				elem->tp_cb);
-		} else {
-			ret = tracepoint_probe_unregister_noupdate(
-				elem->tp_name,
-				elem->tp_cb);
-			/*
-			 * tracepoint_probe_update_all() must be called
-			 * before the module containing tp_cb is unloaded.
-			 */
-			module_put(__module_text_address(
-				(unsigned long)elem->tp_cb));
-		}
-	}
-	elem->state = active;
-
-	return ret;
-}
-
-/*
- * Disable a marker and its probe callback.
- * Note: only waiting an RCU period after setting elem->call to the empty
- * function insures that the original callback is not used anymore. This insured
- * by rcu_read_lock_sched around the call site.
- */
-static void disable_marker(struct marker *elem)
-{
-	int ret;
-
-	/* leave "call" as is. It is known statically. */
-	if (elem->tp_name && elem->state) {
-		WARN_ON(!elem->tp_cb);
-		/*
-		 * It is ok to directly call the probe registration because type
-		 * checking has been done in the __trace_mark_tp() macro.
-		 */
-		ret = tracepoint_probe_unregister_noupdate(elem->tp_name,
-			elem->tp_cb);
-		WARN_ON(ret);
-		/*
-		 * tracepoint_probe_update_all() must be called
-		 * before the module containing tp_cb is unloaded.
-		 */
-		module_put(__module_text_address((unsigned long)elem->tp_cb));
-	}
-	elem->state = 0;
-	elem->single.func = __mark_empty_function;
-	/* Update the function before setting the ptype */
-	smp_wmb();
-	elem->ptype = 0;	/* single probe */
-	/*
-	 * Leave the private data and id there, because removal is racy and
-	 * should be done only after an RCU period. These are never used until
-	 * the next initialization anyway.
-	 */
-}
-
-/**
- * marker_update_probe_range - Update a probe range
- * @begin: beginning of the range
- * @end: end of the range
- *
- * Updates the probe callback corresponding to a range of markers.
- */
-void marker_update_probe_range(struct marker *begin,
-	struct marker *end)
-{
-	struct marker *iter;
-	struct marker_entry *mark_entry;
-
-	mutex_lock(&markers_mutex);
-	for (iter = begin; iter < end; iter++) {
-		mark_entry = get_marker(iter->name);
-		if (mark_entry) {
-			set_marker(mark_entry, iter, !!mark_entry->refcount);
-			/*
-			 * ignore error, continue
-			 */
-		} else {
-			disable_marker(iter);
-		}
-	}
-	mutex_unlock(&markers_mutex);
-}
-
-/*
- * Update probes, removing the faulty probes.
- *
- * Internal callback only changed before the first probe is connected to it.
- * Single probe private data can only be changed on 0 -> 1 and 2 -> 1
- * transitions.  All other transitions will leave the old private data valid.
- * This makes the non-atomicity of the callback/private data updates valid.
- *
- * "special case" updates :
- * 0 -> 1 callback
- * 1 -> 0 callback
- * 1 -> 2 callbacks
- * 2 -> 1 callbacks
- * Other updates all behave the same, just like the 2 -> 3 or 3 -> 2 updates.
- * Site effect : marker_set_format may delete the marker entry (creating a
- * replacement).
- */
-static void marker_update_probes(void)
-{
-	/* Core kernel markers */
-	marker_update_probe_range(__start___markers, __stop___markers);
-	/* Markers in modules. */
-	module_update_markers();
-	tracepoint_probe_update_all();
-}
-
-/**
- * marker_probe_register -  Connect a probe to a marker
- * @name: marker name
- * @format: format string
- * @probe: probe handler
- * @probe_private: probe private data
- *
- * private data must be a valid allocated memory address, or NULL.
- * Returns 0 if ok, error value on error.
- * The probe address must at least be aligned on the architecture pointer size.
- */
-int marker_probe_register(const char *name, const char *format,
-			marker_probe_func *probe, void *probe_private)
-{
-	struct marker_entry *entry;
-	int ret = 0;
-	struct marker_probe_closure *old;
-
-	mutex_lock(&markers_mutex);
-	entry = get_marker(name);
-	if (!entry) {
-		entry = add_marker(name, format);
-		if (IS_ERR(entry))
-			ret = PTR_ERR(entry);
-	} else if (format) {
-		if (!entry->format)
-			ret = marker_set_format(entry, format);
-		else if (strcmp(entry->format, format))
-			ret = -EPERM;
-	}
-	if (ret)
-		goto end;
-
-	/*
-	 * If we detect that a call_rcu is pending for this marker,
-	 * make sure it's executed now.
-	 */
-	if (entry->rcu_pending)
-		rcu_barrier_sched();
-	old = marker_entry_add_probe(entry, probe, probe_private);
-	if (IS_ERR(old)) {
-		ret = PTR_ERR(old);
-		goto end;
-	}
-	mutex_unlock(&markers_mutex);
-	marker_update_probes();
-	mutex_lock(&markers_mutex);
-	entry = get_marker(name);
-	if (!entry)
-		goto end;
-	if (entry->rcu_pending)
-		rcu_barrier_sched();
-	entry->oldptr = old;
-	entry->rcu_pending = 1;
-	/* write rcu_pending before calling the RCU callback */
-	smp_wmb();
-	call_rcu_sched(&entry->rcu, free_old_closure);
-end:
-	mutex_unlock(&markers_mutex);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(marker_probe_register);
-
-/**
- * marker_probe_unregister -  Disconnect a probe from a marker
- * @name: marker name
- * @probe: probe function pointer
- * @probe_private: probe private data
- *
- * Returns the private data given to marker_probe_register, or an ERR_PTR().
- * We do not need to call a synchronize_sched to make sure the probes have
- * finished running before doing a module unload, because the module unload
- * itself uses stop_machine(), which insures that every preempt disabled section
- * have finished.
- */
-int marker_probe_unregister(const char *name,
-	marker_probe_func *probe, void *probe_private)
-{
-	struct marker_entry *entry;
-	struct marker_probe_closure *old;
-	int ret = -ENOENT;
-
-	mutex_lock(&markers_mutex);
-	entry = get_marker(name);
-	if (!entry)
-		goto end;
-	if (entry->rcu_pending)
-		rcu_barrier_sched();
-	old = marker_entry_remove_probe(entry, probe, probe_private);
-	mutex_unlock(&markers_mutex);
-	marker_update_probes();
-	mutex_lock(&markers_mutex);
-	entry = get_marker(name);
-	if (!entry)
-		goto end;
-	if (entry->rcu_pending)
-		rcu_barrier_sched();
-	entry->oldptr = old;
-	entry->rcu_pending = 1;
-	/* write rcu_pending before calling the RCU callback */
-	smp_wmb();
-	call_rcu_sched(&entry->rcu, free_old_closure);
-	remove_marker(name);	/* Ignore busy error message */
-	ret = 0;
-end:
-	mutex_unlock(&markers_mutex);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(marker_probe_unregister);
-
-static struct marker_entry *
-get_marker_from_private_data(marker_probe_func *probe, void *probe_private)
-{
-	struct marker_entry *entry;
-	unsigned int i;
-	struct hlist_head *head;
-	struct hlist_node *node;
-
-	for (i = 0; i < MARKER_TABLE_SIZE; i++) {
-		head = &marker_table[i];
-		hlist_for_each_entry(entry, node, head, hlist) {
-			if (!entry->ptype) {
-				if (entry->single.func == probe
-						&& entry->single.probe_private
-						== probe_private)
-					return entry;
-			} else {
-				struct marker_probe_closure *closure;
-				closure = entry->multi;
-				for (i = 0; closure[i].func; i++) {
-					if (closure[i].func == probe &&
-							closure[i].probe_private
-							== probe_private)
-						return entry;
-				}
-			}
-		}
-	}
-	return NULL;
-}
-
-/**
- * marker_probe_unregister_private_data -  Disconnect a probe from a marker
- * @probe: probe function
- * @probe_private: probe private data
- *
- * Unregister a probe by providing the registered private data.
- * Only removes the first marker found in hash table.
- * Return 0 on success or error value.
- * We do not need to call a synchronize_sched to make sure the probes have
- * finished running before doing a module unload, because the module unload
- * itself uses stop_machine(), which insures that every preempt disabled section
- * have finished.
- */
-int marker_probe_unregister_private_data(marker_probe_func *probe,
-		void *probe_private)
-{
-	struct marker_entry *entry;
-	int ret = 0;
-	struct marker_probe_closure *old;
-
-	mutex_lock(&markers_mutex);
-	entry = get_marker_from_private_data(probe, probe_private);
-	if (!entry) {
-		ret = -ENOENT;
-		goto end;
-	}
-	if (entry->rcu_pending)
-		rcu_barrier_sched();
-	old = marker_entry_remove_probe(entry, NULL, probe_private);
-	mutex_unlock(&markers_mutex);
-	marker_update_probes();
-	mutex_lock(&markers_mutex);
-	entry = get_marker_from_private_data(probe, probe_private);
-	if (!entry)
-		goto end;
-	if (entry->rcu_pending)
-		rcu_barrier_sched();
-	entry->oldptr = old;
-	entry->rcu_pending = 1;
-	/* write rcu_pending before calling the RCU callback */
-	smp_wmb();
-	call_rcu_sched(&entry->rcu, free_old_closure);
-	remove_marker(entry->name);	/* Ignore busy error message */
-end:
-	mutex_unlock(&markers_mutex);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
-
-/**
- * marker_get_private_data - Get a marker's probe private data
- * @name: marker name
- * @probe: probe to match
- * @num: get the nth matching probe's private data
- *
- * Returns the nth private data pointer (starting from 0) matching, or an
- * ERR_PTR.
- * Returns the private data pointer, or an ERR_PTR.
- * The private data pointer should _only_ be dereferenced if the caller is the
- * owner of the data, or its content could vanish. This is mostly used to
- * confirm that a caller is the owner of a registered probe.
- */
-void *marker_get_private_data(const char *name, marker_probe_func *probe,
-		int num)
-{
-	struct hlist_head *head;
-	struct hlist_node *node;
-	struct marker_entry *e;
-	size_t name_len = strlen(name) + 1;
-	u32 hash = jhash(name, name_len-1, 0);
-	int i;
-
-	head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
-	hlist_for_each_entry(e, node, head, hlist) {
-		if (!strcmp(name, e->name)) {
-			if (!e->ptype) {
-				if (num == 0 && e->single.func == probe)
-					return e->single.probe_private;
-			} else {
-				struct marker_probe_closure *closure;
-				int match = 0;
-				closure = e->multi;
-				for (i = 0; closure[i].func; i++) {
-					if (closure[i].func != probe)
-						continue;
-					if (match++ == num)
-						return closure[i].probe_private;
-				}
-			}
-			break;
-		}
-	}
-	return ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL_GPL(marker_get_private_data);
-
-#ifdef CONFIG_MODULES
-
-int marker_module_notify(struct notifier_block *self,
-			 unsigned long val, void *data)
-{
-	struct module *mod = data;
-
-	switch (val) {
-	case MODULE_STATE_COMING:
-		marker_update_probe_range(mod->markers,
-			mod->markers + mod->num_markers);
-		break;
-	case MODULE_STATE_GOING:
-		marker_update_probe_range(mod->markers,
-			mod->markers + mod->num_markers);
-		break;
-	}
-	return 0;
-}
-
-struct notifier_block marker_module_nb = {
-	.notifier_call = marker_module_notify,
-	.priority = 0,
-};
-
-static int init_markers(void)
-{
-	return register_module_notifier(&marker_module_nb);
-}
-__initcall(init_markers);
-
-#endif /* CONFIG_MODULES */
diff --git a/kernel/module.c b/kernel/module.c
index 46580ed..b6ee424 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -369,7 +369,7 @@ EXPORT_SYMBOL_GPL(find_module);
 
 #ifdef CONFIG_SMP
 
-#ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA
+#ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA
 
 static void *percpu_modalloc(unsigned long size, unsigned long align,
 			     const char *name)
@@ -394,7 +394,7 @@ static void percpu_modfree(void *freeme)
 	free_percpu(freeme);
 }
 
-#else /* ... !CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */
+#else /* ... CONFIG_HAVE_LEGACY_PER_CPU_AREA */
 
 /* Number of blocks used and allocated. */
 static unsigned int pcpu_num_used, pcpu_num_allocated;
@@ -540,7 +540,7 @@ static int percpu_modinit(void)
 }
 __initcall(percpu_modinit);
 
-#endif /* CONFIG_HAVE_DYNAMIC_PER_CPU_AREA */
+#endif /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */
 
 static unsigned int find_pcpusec(Elf_Ehdr *hdr,
 				 Elf_Shdr *sechdrs,
@@ -2237,10 +2237,6 @@ static noinline struct module *load_module(void __user *umod,
 				  sizeof(*mod->ctors), &mod->num_ctors);
 #endif
 
-#ifdef CONFIG_MARKERS
-	mod->markers = section_objs(hdr, sechdrs, secstrings, "__markers",
-				    sizeof(*mod->markers), &mod->num_markers);
-#endif
 #ifdef CONFIG_TRACEPOINTS
 	mod->tracepoints = section_objs(hdr, sechdrs, secstrings,
 					"__tracepoints",
@@ -2958,20 +2954,6 @@ void module_layout(struct module *mod,
 EXPORT_SYMBOL(module_layout);
 #endif
 
-#ifdef CONFIG_MARKERS
-void module_update_markers(void)
-{
-	struct module *mod;
-
-	mutex_lock(&module_mutex);
-	list_for_each_entry(mod, &modules, list)
-		if (!mod->taints)
-			marker_update_probe_range(mod->markers,
-				mod->markers + mod->num_markers);
-	mutex_unlock(&module_mutex);
-}
-#endif
-
 #ifdef CONFIG_TRACEPOINTS
 void module_update_tracepoints(void)
 {
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
deleted file mode 100644
index e0d91fd..0000000
--- a/kernel/perf_counter.c
+++ /dev/null
@@ -1,4962 +0,0 @@
-/*
- * Performance counter core code
- *
- *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
- *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
- *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
- *  Copyright  ©  2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
- *
- *  For licensing details see kernel-base/COPYING
- */
-
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/cpu.h>
-#include <linux/smp.h>
-#include <linux/file.h>
-#include <linux/poll.h>
-#include <linux/sysfs.h>
-#include <linux/dcache.h>
-#include <linux/percpu.h>
-#include <linux/ptrace.h>
-#include <linux/vmstat.h>
-#include <linux/hardirq.h>
-#include <linux/rculist.h>
-#include <linux/uaccess.h>
-#include <linux/syscalls.h>
-#include <linux/anon_inodes.h>
-#include <linux/kernel_stat.h>
-#include <linux/perf_counter.h>
-
-#include <asm/irq_regs.h>
-
-/*
- * Each CPU has a list of per CPU counters:
- */
-DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context);
-
-int perf_max_counters __read_mostly = 1;
-static int perf_reserved_percpu __read_mostly;
-static int perf_overcommit __read_mostly = 1;
-
-static atomic_t nr_counters __read_mostly;
-static atomic_t nr_mmap_counters __read_mostly;
-static atomic_t nr_comm_counters __read_mostly;
-static atomic_t nr_task_counters __read_mostly;
-
-/*
- * perf counter paranoia level:
- *  -1 - not paranoid at all
- *   0 - disallow raw tracepoint access for unpriv
- *   1 - disallow cpu counters for unpriv
- *   2 - disallow kernel profiling for unpriv
- */
-int sysctl_perf_counter_paranoid __read_mostly = 1;
-
-static inline bool perf_paranoid_tracepoint_raw(void)
-{
-	return sysctl_perf_counter_paranoid > -1;
-}
-
-static inline bool perf_paranoid_cpu(void)
-{
-	return sysctl_perf_counter_paranoid > 0;
-}
-
-static inline bool perf_paranoid_kernel(void)
-{
-	return sysctl_perf_counter_paranoid > 1;
-}
-
-int sysctl_perf_counter_mlock __read_mostly = 512; /* 'free' kb per user */
-
-/*
- * max perf counter sample rate
- */
-int sysctl_perf_counter_sample_rate __read_mostly = 100000;
-
-static atomic64_t perf_counter_id;
-
-/*
- * Lock for (sysadmin-configurable) counter reservations:
- */
-static DEFINE_SPINLOCK(perf_resource_lock);
-
-/*
- * Architecture provided APIs - weak aliases:
- */
-extern __weak const struct pmu *hw_perf_counter_init(struct perf_counter *counter)
-{
-	return NULL;
-}
-
-void __weak hw_perf_disable(void)		{ barrier(); }
-void __weak hw_perf_enable(void)		{ barrier(); }
-
-void __weak hw_perf_counter_setup(int cpu)	{ barrier(); }
-void __weak hw_perf_counter_setup_online(int cpu)	{ barrier(); }
-
-int __weak
-hw_perf_group_sched_in(struct perf_counter *group_leader,
-	       struct perf_cpu_context *cpuctx,
-	       struct perf_counter_context *ctx, int cpu)
-{
-	return 0;
-}
-
-void __weak perf_counter_print_debug(void)	{ }
-
-static DEFINE_PER_CPU(int, disable_count);
-
-void __perf_disable(void)
-{
-	__get_cpu_var(disable_count)++;
-}
-
-bool __perf_enable(void)
-{
-	return !--__get_cpu_var(disable_count);
-}
-
-void perf_disable(void)
-{
-	__perf_disable();
-	hw_perf_disable();
-}
-
-void perf_enable(void)
-{
-	if (__perf_enable())
-		hw_perf_enable();
-}
-
-static void get_ctx(struct perf_counter_context *ctx)
-{
-	WARN_ON(!atomic_inc_not_zero(&ctx->refcount));
-}
-
-static void free_ctx(struct rcu_head *head)
-{
-	struct perf_counter_context *ctx;
-
-	ctx = container_of(head, struct perf_counter_context, rcu_head);
-	kfree(ctx);
-}
-
-static void put_ctx(struct perf_counter_context *ctx)
-{
-	if (atomic_dec_and_test(&ctx->refcount)) {
-		if (ctx->parent_ctx)
-			put_ctx(ctx->parent_ctx);
-		if (ctx->task)
-			put_task_struct(ctx->task);
-		call_rcu(&ctx->rcu_head, free_ctx);
-	}
-}
-
-static void unclone_ctx(struct perf_counter_context *ctx)
-{
-	if (ctx->parent_ctx) {
-		put_ctx(ctx->parent_ctx);
-		ctx->parent_ctx = NULL;
-	}
-}
-
-/*
- * If we inherit counters we want to return the parent counter id
- * to userspace.
- */
-static u64 primary_counter_id(struct perf_counter *counter)
-{
-	u64 id = counter->id;
-
-	if (counter->parent)
-		id = counter->parent->id;
-
-	return id;
-}
-
-/*
- * Get the perf_counter_context for a task and lock it.
- * This has to cope with with the fact that until it is locked,
- * the context could get moved to another task.
- */
-static struct perf_counter_context *
-perf_lock_task_context(struct task_struct *task, unsigned long *flags)
-{
-	struct perf_counter_context *ctx;
-
-	rcu_read_lock();
- retry:
-	ctx = rcu_dereference(task->perf_counter_ctxp);
-	if (ctx) {
-		/*
-		 * If this context is a clone of another, it might
-		 * get swapped for another underneath us by
-		 * perf_counter_task_sched_out, though the
-		 * rcu_read_lock() protects us from any context
-		 * getting freed.  Lock the context and check if it
-		 * got swapped before we could get the lock, and retry
-		 * if so.  If we locked the right context, then it
-		 * can't get swapped on us any more.
-		 */
-		spin_lock_irqsave(&ctx->lock, *flags);
-		if (ctx != rcu_dereference(task->perf_counter_ctxp)) {
-			spin_unlock_irqrestore(&ctx->lock, *flags);
-			goto retry;
-		}
-
-		if (!atomic_inc_not_zero(&ctx->refcount)) {
-			spin_unlock_irqrestore(&ctx->lock, *flags);
-			ctx = NULL;
-		}
-	}
-	rcu_read_unlock();
-	return ctx;
-}
-
-/*
- * Get the context for a task and increment its pin_count so it
- * can't get swapped to another task.  This also increments its
- * reference count so that the context can't get freed.
- */
-static struct perf_counter_context *perf_pin_task_context(struct task_struct *task)
-{
-	struct perf_counter_context *ctx;
-	unsigned long flags;
-
-	ctx = perf_lock_task_context(task, &flags);
-	if (ctx) {
-		++ctx->pin_count;
-		spin_unlock_irqrestore(&ctx->lock, flags);
-	}
-	return ctx;
-}
-
-static void perf_unpin_context(struct perf_counter_context *ctx)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&ctx->lock, flags);
-	--ctx->pin_count;
-	spin_unlock_irqrestore(&ctx->lock, flags);
-	put_ctx(ctx);
-}
-
-/*
- * Add a counter from the lists for its context.
- * Must be called with ctx->mutex and ctx->lock held.
- */
-static void
-list_add_counter(struct perf_counter *counter, struct perf_counter_context *ctx)
-{
-	struct perf_counter *group_leader = counter->group_leader;
-
-	/*
-	 * Depending on whether it is a standalone or sibling counter,
-	 * add it straight to the context's counter list, or to the group
-	 * leader's sibling list:
-	 */
-	if (group_leader == counter)
-		list_add_tail(&counter->list_entry, &ctx->counter_list);
-	else {
-		list_add_tail(&counter->list_entry, &group_leader->sibling_list);
-		group_leader->nr_siblings++;
-	}
-
-	list_add_rcu(&counter->event_entry, &ctx->event_list);
-	ctx->nr_counters++;
-	if (counter->attr.inherit_stat)
-		ctx->nr_stat++;
-}
-
-/*
- * Remove a counter from the lists for its context.
- * Must be called with ctx->mutex and ctx->lock held.
- */
-static void
-list_del_counter(struct perf_counter *counter, struct perf_counter_context *ctx)
-{
-	struct perf_counter *sibling, *tmp;
-
-	if (list_empty(&counter->list_entry))
-		return;
-	ctx->nr_counters--;
-	if (counter->attr.inherit_stat)
-		ctx->nr_stat--;
-
-	list_del_init(&counter->list_entry);
-	list_del_rcu(&counter->event_entry);
-
-	if (counter->group_leader != counter)
-		counter->group_leader->nr_siblings--;
-
-	/*
-	 * If this was a group counter with sibling counters then
-	 * upgrade the siblings to singleton counters by adding them
-	 * to the context list directly:
-	 */
-	list_for_each_entry_safe(sibling, tmp,
-				 &counter->sibling_list, list_entry) {
-
-		list_move_tail(&sibling->list_entry, &ctx->counter_list);
-		sibling->group_leader = sibling;
-	}
-}
-
-static void
-counter_sched_out(struct perf_counter *counter,
-		  struct perf_cpu_context *cpuctx,
-		  struct perf_counter_context *ctx)
-{
-	if (counter->state != PERF_COUNTER_STATE_ACTIVE)
-		return;
-
-	counter->state = PERF_COUNTER_STATE_INACTIVE;
-	if (counter->pending_disable) {
-		counter->pending_disable = 0;
-		counter->state = PERF_COUNTER_STATE_OFF;
-	}
-	counter->tstamp_stopped = ctx->time;
-	counter->pmu->disable(counter);
-	counter->oncpu = -1;
-
-	if (!is_software_counter(counter))
-		cpuctx->active_oncpu--;
-	ctx->nr_active--;
-	if (counter->attr.exclusive || !cpuctx->active_oncpu)
-		cpuctx->exclusive = 0;
-}
-
-static void
-group_sched_out(struct perf_counter *group_counter,
-		struct perf_cpu_context *cpuctx,
-		struct perf_counter_context *ctx)
-{
-	struct perf_counter *counter;
-
-	if (group_counter->state != PERF_COUNTER_STATE_ACTIVE)
-		return;
-
-	counter_sched_out(group_counter, cpuctx, ctx);
-
-	/*
-	 * Schedule out siblings (if any):
-	 */
-	list_for_each_entry(counter, &group_counter->sibling_list, list_entry)
-		counter_sched_out(counter, cpuctx, ctx);
-
-	if (group_counter->attr.exclusive)
-		cpuctx->exclusive = 0;
-}
-
-/*
- * Cross CPU call to remove a performance counter
- *
- * We disable the counter on the hardware level first. After that we
- * remove it from the context list.
- */
-static void __perf_counter_remove_from_context(void *info)
-{
-	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
-	struct perf_counter *counter = info;
-	struct perf_counter_context *ctx = counter->ctx;
-
-	/*
-	 * If this is a task context, we need to check whether it is
-	 * the current task context of this cpu. If not it has been
-	 * scheduled out before the smp call arrived.
-	 */
-	if (ctx->task && cpuctx->task_ctx != ctx)
-		return;
-
-	spin_lock(&ctx->lock);
-	/*
-	 * Protect the list operation against NMI by disabling the
-	 * counters on a global level.
-	 */
-	perf_disable();
-
-	counter_sched_out(counter, cpuctx, ctx);
-
-	list_del_counter(counter, ctx);
-
-	if (!ctx->task) {
-		/*
-		 * Allow more per task counters with respect to the
-		 * reservation:
-		 */
-		cpuctx->max_pertask =
-			min(perf_max_counters - ctx->nr_counters,
-			    perf_max_counters - perf_reserved_percpu);
-	}
-
-	perf_enable();
-	spin_unlock(&ctx->lock);
-}
-
-
-/*
- * Remove the counter from a task's (or a CPU's) list of counters.
- *
- * Must be called with ctx->mutex held.
- *
- * CPU counters are removed with a smp call. For task counters we only
- * call when the task is on a CPU.
- *
- * If counter->ctx is a cloned context, callers must make sure that
- * every task struct that counter->ctx->task could possibly point to
- * remains valid.  This is OK when called from perf_release since
- * that only calls us on the top-level context, which can't be a clone.
- * When called from perf_counter_exit_task, it's OK because the
- * context has been detached from its task.
- */
-static void perf_counter_remove_from_context(struct perf_counter *counter)
-{
-	struct perf_counter_context *ctx = counter->ctx;
-	struct task_struct *task = ctx->task;
-
-	if (!task) {
-		/*
-		 * Per cpu counters are removed via an smp call and
-		 * the removal is always sucessful.
-		 */
-		smp_call_function_single(counter->cpu,
-					 __perf_counter_remove_from_context,
-					 counter, 1);
-		return;
-	}
-
-retry:
-	task_oncpu_function_call(task, __perf_counter_remove_from_context,
-				 counter);
-
-	spin_lock_irq(&ctx->lock);
-	/*
-	 * If the context is active we need to retry the smp call.
-	 */
-	if (ctx->nr_active && !list_empty(&counter->list_entry)) {
-		spin_unlock_irq(&ctx->lock);
-		goto retry;
-	}
-
-	/*
-	 * The lock prevents that this context is scheduled in so we
-	 * can remove the counter safely, if the call above did not
-	 * succeed.
-	 */
-	if (!list_empty(&counter->list_entry)) {
-		list_del_counter(counter, ctx);
-	}
-	spin_unlock_irq(&ctx->lock);
-}
-
-static inline u64 perf_clock(void)
-{
-	return cpu_clock(smp_processor_id());
-}
-
-/*
- * Update the record of the current time in a context.
- */
-static void update_context_time(struct perf_counter_context *ctx)
-{
-	u64 now = perf_clock();
-
-	ctx->time += now - ctx->timestamp;
-	ctx->timestamp = now;
-}
-
-/*
- * Update the total_time_enabled and total_time_running fields for a counter.
- */
-static void update_counter_times(struct perf_counter *counter)
-{
-	struct perf_counter_context *ctx = counter->ctx;
-	u64 run_end;
-
-	if (counter->state < PERF_COUNTER_STATE_INACTIVE ||
-	    counter->group_leader->state < PERF_COUNTER_STATE_INACTIVE)
-		return;
-
-	counter->total_time_enabled = ctx->time - counter->tstamp_enabled;
-
-	if (counter->state == PERF_COUNTER_STATE_INACTIVE)
-		run_end = counter->tstamp_stopped;
-	else
-		run_end = ctx->time;
-
-	counter->total_time_running = run_end - counter->tstamp_running;
-}
-
-/*
- * Update total_time_enabled and total_time_running for all counters in a group.
- */
-static void update_group_times(struct perf_counter *leader)
-{
-	struct perf_counter *counter;
-
-	update_counter_times(leader);
-	list_for_each_entry(counter, &leader->sibling_list, list_entry)
-		update_counter_times(counter);
-}
-
-/*
- * Cross CPU call to disable a performance counter
- */
-static void __perf_counter_disable(void *info)
-{
-	struct perf_counter *counter = info;
-	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
-	struct perf_counter_context *ctx = counter->ctx;
-
-	/*
-	 * If this is a per-task counter, need to check whether this
-	 * counter's task is the current task on this cpu.
-	 */
-	if (ctx->task && cpuctx->task_ctx != ctx)
-		return;
-
-	spin_lock(&ctx->lock);
-
-	/*
-	 * If the counter is on, turn it off.
-	 * If it is in error state, leave it in error state.
-	 */
-	if (counter->state >= PERF_COUNTER_STATE_INACTIVE) {
-		update_context_time(ctx);
-		update_group_times(counter);
-		if (counter == counter->group_leader)
-			group_sched_out(counter, cpuctx, ctx);
-		else
-			counter_sched_out(counter, cpuctx, ctx);
-		counter->state = PERF_COUNTER_STATE_OFF;
-	}
-
-	spin_unlock(&ctx->lock);
-}
-
-/*
- * Disable a counter.
- *
- * If counter->ctx is a cloned context, callers must make sure that
- * every task struct that counter->ctx->task could possibly point to
- * remains valid.  This condition is satisifed when called through
- * perf_counter_for_each_child or perf_counter_for_each because they
- * hold the top-level counter's child_mutex, so any descendant that
- * goes to exit will block in sync_child_counter.
- * When called from perf_pending_counter it's OK because counter->ctx
- * is the current context on this CPU and preemption is disabled,
- * hence we can't get into perf_counter_task_sched_out for this context.
- */
-static void perf_counter_disable(struct perf_counter *counter)
-{
-	struct perf_counter_context *ctx = counter->ctx;
-	struct task_struct *task = ctx->task;
-
-	if (!task) {
-		/*
-		 * Disable the counter on the cpu that it's on
-		 */
-		smp_call_function_single(counter->cpu, __perf_counter_disable,
-					 counter, 1);
-		return;
-	}
-
- retry:
-	task_oncpu_function_call(task, __perf_counter_disable, counter);
-
-	spin_lock_irq(&ctx->lock);
-	/*
-	 * If the counter is still active, we need to retry the cross-call.
-	 */
-	if (counter->state == PERF_COUNTER_STATE_ACTIVE) {
-		spin_unlock_irq(&ctx->lock);
-		goto retry;
-	}
-
-	/*
-	 * Since we have the lock this context can't be scheduled
-	 * in, so we can change the state safely.
-	 */
-	if (counter->state == PERF_COUNTER_STATE_INACTIVE) {
-		update_group_times(counter);
-		counter->state = PERF_COUNTER_STATE_OFF;
-	}
-
-	spin_unlock_irq(&ctx->lock);
-}
-
-static int
-counter_sched_in(struct perf_counter *counter,
-		 struct perf_cpu_context *cpuctx,
-		 struct perf_counter_context *ctx,
-		 int cpu)
-{
-	if (counter->state <= PERF_COUNTER_STATE_OFF)
-		return 0;
-
-	counter->state = PERF_COUNTER_STATE_ACTIVE;
-	counter->oncpu = cpu;	/* TODO: put 'cpu' into cpuctx->cpu */
-	/*
-	 * The new state must be visible before we turn it on in the hardware:
-	 */
-	smp_wmb();
-
-	if (counter->pmu->enable(counter)) {
-		counter->state = PERF_COUNTER_STATE_INACTIVE;
-		counter->oncpu = -1;
-		return -EAGAIN;
-	}
-
-	counter->tstamp_running += ctx->time - counter->tstamp_stopped;
-
-	if (!is_software_counter(counter))
-		cpuctx->active_oncpu++;
-	ctx->nr_active++;
-
-	if (counter->attr.exclusive)
-		cpuctx->exclusive = 1;
-
-	return 0;
-}
-
-static int
-group_sched_in(struct perf_counter *group_counter,
-	       struct perf_cpu_context *cpuctx,
-	       struct perf_counter_context *ctx,
-	       int cpu)
-{
-	struct perf_counter *counter, *partial_group;
-	int ret;
-
-	if (group_counter->state == PERF_COUNTER_STATE_OFF)
-		return 0;
-
-	ret = hw_perf_group_sched_in(group_counter, cpuctx, ctx, cpu);
-	if (ret)
-		return ret < 0 ? ret : 0;
-
-	if (counter_sched_in(group_counter, cpuctx, ctx, cpu))
-		return -EAGAIN;
-
-	/*
-	 * Schedule in siblings as one group (if any):
-	 */
-	list_for_each_entry(counter, &group_counter->sibling_list, list_entry) {
-		if (counter_sched_in(counter, cpuctx, ctx, cpu)) {
-			partial_group = counter;
-			goto group_error;
-		}
-	}
-
-	return 0;
-
-group_error:
-	/*
-	 * Groups can be scheduled in as one unit only, so undo any
-	 * partial group before returning:
-	 */
-	list_for_each_entry(counter, &group_counter->sibling_list, list_entry) {
-		if (counter == partial_group)
-			break;
-		counter_sched_out(counter, cpuctx, ctx);
-	}
-	counter_sched_out(group_counter, cpuctx, ctx);
-
-	return -EAGAIN;
-}
-
-/*
- * Return 1 for a group consisting entirely of software counters,
- * 0 if the group contains any hardware counters.
- */
-static int is_software_only_group(struct perf_counter *leader)
-{
-	struct perf_counter *counter;
-
-	if (!is_software_counter(leader))
-		return 0;
-
-	list_for_each_entry(counter, &leader->sibling_list, list_entry)
-		if (!is_software_counter(counter))
-			return 0;
-
-	return 1;
-}
-
-/*
- * Work out whether we can put this counter group on the CPU now.
- */
-static int group_can_go_on(struct perf_counter *counter,
-			   struct perf_cpu_context *cpuctx,
-			   int can_add_hw)
-{
-	/*
-	 * Groups consisting entirely of software counters can always go on.
-	 */
-	if (is_software_only_group(counter))
-		return 1;
-	/*
-	 * If an exclusive group is already on, no other hardware
-	 * counters can go on.
-	 */
-	if (cpuctx->exclusive)
-		return 0;
-	/*
-	 * If this group is exclusive and there are already
-	 * counters on the CPU, it can't go on.
-	 */
-	if (counter->attr.exclusive && cpuctx->active_oncpu)
-		return 0;
-	/*
-	 * Otherwise, try to add it if all previous groups were able
-	 * to go on.
-	 */
-	return can_add_hw;
-}
-
-static void add_counter_to_ctx(struct perf_counter *counter,
-			       struct perf_counter_context *ctx)
-{
-	list_add_counter(counter, ctx);
-	counter->tstamp_enabled = ctx->time;
-	counter->tstamp_running = ctx->time;
-	counter->tstamp_stopped = ctx->time;
-}
-
-/*
- * Cross CPU call to install and enable a performance counter
- *
- * Must be called with ctx->mutex held
- */
-static void __perf_install_in_context(void *info)
-{
-	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
-	struct perf_counter *counter = info;
-	struct perf_counter_context *ctx = counter->ctx;
-	struct perf_counter *leader = counter->group_leader;
-	int cpu = smp_processor_id();
-	int err;
-
-	/*
-	 * If this is a task context, we need to check whether it is
-	 * the current task context of this cpu. If not it has been
-	 * scheduled out before the smp call arrived.
-	 * Or possibly this is the right context but it isn't
-	 * on this cpu because it had no counters.
-	 */
-	if (ctx->task && cpuctx->task_ctx != ctx) {
-		if (cpuctx->task_ctx || ctx->task != current)
-			return;
-		cpuctx->task_ctx = ctx;
-	}
-
-	spin_lock(&ctx->lock);
-	ctx->is_active = 1;
-	update_context_time(ctx);
-
-	/*
-	 * Protect the list operation against NMI by disabling the
-	 * counters on a global level. NOP for non NMI based counters.
-	 */
-	perf_disable();
-
-	add_counter_to_ctx(counter, ctx);
-
-	/*
-	 * Don't put the counter on if it is disabled or if
-	 * it is in a group and the group isn't on.
-	 */
-	if (counter->state != PERF_COUNTER_STATE_INACTIVE ||
-	    (leader != counter && leader->state != PERF_COUNTER_STATE_ACTIVE))
-		goto unlock;
-
-	/*
-	 * An exclusive counter can't go on if there are already active
-	 * hardware counters, and no hardware counter can go on if there
-	 * is already an exclusive counter on.
-	 */
-	if (!group_can_go_on(counter, cpuctx, 1))
-		err = -EEXIST;
-	else
-		err = counter_sched_in(counter, cpuctx, ctx, cpu);
-
-	if (err) {
-		/*
-		 * This counter couldn't go on.  If it is in a group
-		 * then we have to pull the whole group off.
-		 * If the counter group is pinned then put it in error state.
-		 */
-		if (leader != counter)
-			group_sched_out(leader, cpuctx, ctx);
-		if (leader->attr.pinned) {
-			update_group_times(leader);
-			leader->state = PERF_COUNTER_STATE_ERROR;
-		}
-	}
-
-	if (!err && !ctx->task && cpuctx->max_pertask)
-		cpuctx->max_pertask--;
-
- unlock:
-	perf_enable();
-
-	spin_unlock(&ctx->lock);
-}
-
-/*
- * Attach a performance counter to a context
- *
- * First we add the counter to the list with the hardware enable bit
- * in counter->hw_config cleared.
- *
- * If the counter is attached to a task which is on a CPU we use a smp
- * call to enable it in the task context. The task might have been
- * scheduled away, but we check this in the smp call again.
- *
- * Must be called with ctx->mutex held.
- */
-static void
-perf_install_in_context(struct perf_counter_context *ctx,
-			struct perf_counter *counter,
-			int cpu)
-{
-	struct task_struct *task = ctx->task;
-
-	if (!task) {
-		/*
-		 * Per cpu counters are installed via an smp call and
-		 * the install is always sucessful.
-		 */
-		smp_call_function_single(cpu, __perf_install_in_context,
-					 counter, 1);
-		return;
-	}
-
-retry:
-	task_oncpu_function_call(task, __perf_install_in_context,
-				 counter);
-
-	spin_lock_irq(&ctx->lock);
-	/*
-	 * we need to retry the smp call.
-	 */
-	if (ctx->is_active && list_empty(&counter->list_entry)) {
-		spin_unlock_irq(&ctx->lock);
-		goto retry;
-	}
-
-	/*
-	 * The lock prevents that this context is scheduled in so we
-	 * can add the counter safely, if it the call above did not
-	 * succeed.
-	 */
-	if (list_empty(&counter->list_entry))
-		add_counter_to_ctx(counter, ctx);
-	spin_unlock_irq(&ctx->lock);
-}
-
-/*
- * Put a counter into inactive state and update time fields.
- * Enabling the leader of a group effectively enables all
- * the group members that aren't explicitly disabled, so we
- * have to update their ->tstamp_enabled also.
- * Note: this works for group members as well as group leaders
- * since the non-leader members' sibling_lists will be empty.
- */
-static void __perf_counter_mark_enabled(struct perf_counter *counter,
-					struct perf_counter_context *ctx)
-{
-	struct perf_counter *sub;
-
-	counter->state = PERF_COUNTER_STATE_INACTIVE;
-	counter->tstamp_enabled = ctx->time - counter->total_time_enabled;
-	list_for_each_entry(sub, &counter->sibling_list, list_entry)
-		if (sub->state >= PERF_COUNTER_STATE_INACTIVE)
-			sub->tstamp_enabled =
-				ctx->time - sub->total_time_enabled;
-}
-
-/*
- * Cross CPU call to enable a performance counter
- */
-static void __perf_counter_enable(void *info)
-{
-	struct perf_counter *counter = info;
-	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
-	struct perf_counter_context *ctx = counter->ctx;
-	struct perf_counter *leader = counter->group_leader;
-	int err;
-
-	/*
-	 * If this is a per-task counter, need to check whether this
-	 * counter's task is the current task on this cpu.
-	 */
-	if (ctx->task && cpuctx->task_ctx != ctx) {
-		if (cpuctx->task_ctx || ctx->task != current)
-			return;
-		cpuctx->task_ctx = ctx;
-	}
-
-	spin_lock(&ctx->lock);
-	ctx->is_active = 1;
-	update_context_time(ctx);
-
-	if (counter->state >= PERF_COUNTER_STATE_INACTIVE)
-		goto unlock;
-	__perf_counter_mark_enabled(counter, ctx);
-
-	/*
-	 * If the counter is in a group and isn't the group leader,
-	 * then don't put it on unless the group is on.
-	 */
-	if (leader != counter && leader->state != PERF_COUNTER_STATE_ACTIVE)
-		goto unlock;
-
-	if (!group_can_go_on(counter, cpuctx, 1)) {
-		err = -EEXIST;
-	} else {
-		perf_disable();
-		if (counter == leader)
-			err = group_sched_in(counter, cpuctx, ctx,
-					     smp_processor_id());
-		else
-			err = counter_sched_in(counter, cpuctx, ctx,
-					       smp_processor_id());
-		perf_enable();
-	}
-
-	if (err) {
-		/*
-		 * If this counter can't go on and it's part of a
-		 * group, then the whole group has to come off.
-		 */
-		if (leader != counter)
-			group_sched_out(leader, cpuctx, ctx);
-		if (leader->attr.pinned) {
-			update_group_times(leader);
-			leader->state = PERF_COUNTER_STATE_ERROR;
-		}
-	}
-
- unlock:
-	spin_unlock(&ctx->lock);
-}
-
-/*
- * Enable a counter.
- *
- * If counter->ctx is a cloned context, callers must make sure that
- * every task struct that counter->ctx->task could possibly point to
- * remains valid.  This condition is satisfied when called through
- * perf_counter_for_each_child or perf_counter_for_each as described
- * for perf_counter_disable.
- */
-static void perf_counter_enable(struct perf_counter *counter)
-{
-	struct perf_counter_context *ctx = counter->ctx;
-	struct task_struct *task = ctx->task;
-
-	if (!task) {
-		/*
-		 * Enable the counter on the cpu that it's on
-		 */
-		smp_call_function_single(counter->cpu, __perf_counter_enable,
-					 counter, 1);
-		return;
-	}
-
-	spin_lock_irq(&ctx->lock);
-	if (counter->state >= PERF_COUNTER_STATE_INACTIVE)
-		goto out;
-
-	/*
-	 * If the counter is in error state, clear that first.
-	 * That way, if we see the counter in error state below, we
-	 * know that it has gone back into error state, as distinct
-	 * from the task having been scheduled away before the
-	 * cross-call arrived.
-	 */
-	if (counter->state == PERF_COUNTER_STATE_ERROR)
-		counter->state = PERF_COUNTER_STATE_OFF;
-
- retry:
-	spin_unlock_irq(&ctx->lock);
-	task_oncpu_function_call(task, __perf_counter_enable, counter);
-
-	spin_lock_irq(&ctx->lock);
-
-	/*
-	 * If the context is active and the counter is still off,
-	 * we need to retry the cross-call.
-	 */
-	if (ctx->is_active && counter->state == PERF_COUNTER_STATE_OFF)
-		goto retry;
-
-	/*
-	 * Since we have the lock this context can't be scheduled
-	 * in, so we can change the state safely.
-	 */
-	if (counter->state == PERF_COUNTER_STATE_OFF)
-		__perf_counter_mark_enabled(counter, ctx);
-
- out:
-	spin_unlock_irq(&ctx->lock);
-}
-
-static int perf_counter_refresh(struct perf_counter *counter, int refresh)
-{
-	/*
-	 * not supported on inherited counters
-	 */
-	if (counter->attr.inherit)
-		return -EINVAL;
-
-	atomic_add(refresh, &counter->event_limit);
-	perf_counter_enable(counter);
-
-	return 0;
-}
-
-void __perf_counter_sched_out(struct perf_counter_context *ctx,
-			      struct perf_cpu_context *cpuctx)
-{
-	struct perf_counter *counter;
-
-	spin_lock(&ctx->lock);
-	ctx->is_active = 0;
-	if (likely(!ctx->nr_counters))
-		goto out;
-	update_context_time(ctx);
-
-	perf_disable();
-	if (ctx->nr_active) {
-		list_for_each_entry(counter, &ctx->counter_list, list_entry) {
-			if (counter != counter->group_leader)
-				counter_sched_out(counter, cpuctx, ctx);
-			else
-				group_sched_out(counter, cpuctx, ctx);
-		}
-	}
-	perf_enable();
- out:
-	spin_unlock(&ctx->lock);
-}
-
-/*
- * Test whether two contexts are equivalent, i.e. whether they
- * have both been cloned from the same version of the same context
- * and they both have the same number of enabled counters.
- * If the number of enabled counters is the same, then the set
- * of enabled counters should be the same, because these are both
- * inherited contexts, therefore we can't access individual counters
- * in them directly with an fd; we can only enable/disable all
- * counters via prctl, or enable/disable all counters in a family
- * via ioctl, which will have the same effect on both contexts.
- */
-static int context_equiv(struct perf_counter_context *ctx1,
-			 struct perf_counter_context *ctx2)
-{
-	return ctx1->parent_ctx && ctx1->parent_ctx == ctx2->parent_ctx
-		&& ctx1->parent_gen == ctx2->parent_gen
-		&& !ctx1->pin_count && !ctx2->pin_count;
-}
-
-static void __perf_counter_read(void *counter);
-
-static void __perf_counter_sync_stat(struct perf_counter *counter,
-				     struct perf_counter *next_counter)
-{
-	u64 value;
-
-	if (!counter->attr.inherit_stat)
-		return;
-
-	/*
-	 * Update the counter value, we cannot use perf_counter_read()
-	 * because we're in the middle of a context switch and have IRQs
-	 * disabled, which upsets smp_call_function_single(), however
-	 * we know the counter must be on the current CPU, therefore we
-	 * don't need to use it.
-	 */
-	switch (counter->state) {
-	case PERF_COUNTER_STATE_ACTIVE:
-		__perf_counter_read(counter);
-		break;
-
-	case PERF_COUNTER_STATE_INACTIVE:
-		update_counter_times(counter);
-		break;
-
-	default:
-		break;
-	}
-
-	/*
-	 * In order to keep per-task stats reliable we need to flip the counter
-	 * values when we flip the contexts.
-	 */
-	value = atomic64_read(&next_counter->count);
-	value = atomic64_xchg(&counter->count, value);
-	atomic64_set(&next_counter->count, value);
-
-	swap(counter->total_time_enabled, next_counter->total_time_enabled);
-	swap(counter->total_time_running, next_counter->total_time_running);
-
-	/*
-	 * Since we swizzled the values, update the user visible data too.
-	 */
-	perf_counter_update_userpage(counter);
-	perf_counter_update_userpage(next_counter);
-}
-
-#define list_next_entry(pos, member) \
-	list_entry(pos->member.next, typeof(*pos), member)
-
-static void perf_counter_sync_stat(struct perf_counter_context *ctx,
-				   struct perf_counter_context *next_ctx)
-{
-	struct perf_counter *counter, *next_counter;
-
-	if (!ctx->nr_stat)
-		return;
-
-	counter = list_first_entry(&ctx->event_list,
-				   struct perf_counter, event_entry);
-
-	next_counter = list_first_entry(&next_ctx->event_list,
-					struct perf_counter, event_entry);
-
-	while (&counter->event_entry != &ctx->event_list &&
-	       &next_counter->event_entry != &next_ctx->event_list) {
-
-		__perf_counter_sync_stat(counter, next_counter);
-
-		counter = list_next_entry(counter, event_entry);
-		next_counter = list_next_entry(next_counter, event_entry);
-	}
-}
-
-/*
- * Called from scheduler to remove the counters of the current task,
- * with interrupts disabled.
- *
- * We stop each counter and update the counter value in counter->count.
- *
- * This does not protect us against NMI, but disable()
- * sets the disabled bit in the control field of counter _before_
- * accessing the counter control register. If a NMI hits, then it will
- * not restart the counter.
- */
-void perf_counter_task_sched_out(struct task_struct *task,
-				 struct task_struct *next, int cpu)
-{
-	struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
-	struct perf_counter_context *ctx = task->perf_counter_ctxp;
-	struct perf_counter_context *next_ctx;
-	struct perf_counter_context *parent;
-	struct pt_regs *regs;
-	int do_switch = 1;
-
-	regs = task_pt_regs(task);
-	perf_swcounter_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0);
-
-	if (likely(!ctx || !cpuctx->task_ctx))
-		return;
-
-	update_context_time(ctx);
-
-	rcu_read_lock();
-	parent = rcu_dereference(ctx->parent_ctx);
-	next_ctx = next->perf_counter_ctxp;
-	if (parent && next_ctx &&
-	    rcu_dereference(next_ctx->parent_ctx) == parent) {
-		/*
-		 * Looks like the two contexts are clones, so we might be
-		 * able to optimize the context switch.  We lock both
-		 * contexts and check that they are clones under the
-		 * lock (including re-checking that neither has been
-		 * uncloned in the meantime).  It doesn't matter which
-		 * order we take the locks because no other cpu could
-		 * be trying to lock both of these tasks.
-		 */
-		spin_lock(&ctx->lock);
-		spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING);
-		if (context_equiv(ctx, next_ctx)) {
-			/*
-			 * XXX do we need a memory barrier of sorts
-			 * wrt to rcu_dereference() of perf_counter_ctxp
-			 */
-			task->perf_counter_ctxp = next_ctx;
-			next->perf_counter_ctxp = ctx;
-			ctx->task = next;
-			next_ctx->task = task;
-			do_switch = 0;
-
-			perf_counter_sync_stat(ctx, next_ctx);
-		}
-		spin_unlock(&next_ctx->lock);
-		spin_unlock(&ctx->lock);
-	}
-	rcu_read_unlock();
-
-	if (do_switch) {
-		__perf_counter_sched_out(ctx, cpuctx);
-		cpuctx->task_ctx = NULL;
-	}
-}
-
-/*
- * Called with IRQs disabled
- */
-static void __perf_counter_task_sched_out(struct perf_counter_context *ctx)
-{
-	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
-
-	if (!cpuctx->task_ctx)
-		return;
-
-	if (WARN_ON_ONCE(ctx != cpuctx->task_ctx))
-		return;
-
-	__perf_counter_sched_out(ctx, cpuctx);
-	cpuctx->task_ctx = NULL;
-}
-
-/*
- * Called with IRQs disabled
- */
-static void perf_counter_cpu_sched_out(struct perf_cpu_context *cpuctx)
-{
-	__perf_counter_sched_out(&cpuctx->ctx, cpuctx);
-}
-
-static void
-__perf_counter_sched_in(struct perf_counter_context *ctx,
-			struct perf_cpu_context *cpuctx, int cpu)
-{
-	struct perf_counter *counter;
-	int can_add_hw = 1;
-
-	spin_lock(&ctx->lock);
-	ctx->is_active = 1;
-	if (likely(!ctx->nr_counters))
-		goto out;
-
-	ctx->timestamp = perf_clock();
-
-	perf_disable();
-
-	/*
-	 * First go through the list and put on any pinned groups
-	 * in order to give them the best chance of going on.
-	 */
-	list_for_each_entry(counter, &ctx->counter_list, list_entry) {
-		if (counter->state <= PERF_COUNTER_STATE_OFF ||
-		    !counter->attr.pinned)
-			continue;
-		if (counter->cpu != -1 && counter->cpu != cpu)
-			continue;
-
-		if (counter != counter->group_leader)
-			counter_sched_in(counter, cpuctx, ctx, cpu);
-		else {
-			if (group_can_go_on(counter, cpuctx, 1))
-				group_sched_in(counter, cpuctx, ctx, cpu);
-		}
-
-		/*
-		 * If this pinned group hasn't been scheduled,
-		 * put it in error state.
-		 */
-		if (counter->state == PERF_COUNTER_STATE_INACTIVE) {
-			update_group_times(counter);
-			counter->state = PERF_COUNTER_STATE_ERROR;
-		}
-	}
-
-	list_for_each_entry(counter, &ctx->counter_list, list_entry) {
-		/*
-		 * Ignore counters in OFF or ERROR state, and
-		 * ignore pinned counters since we did them already.
-		 */
-		if (counter->state <= PERF_COUNTER_STATE_OFF ||
-		    counter->attr.pinned)
-			continue;
-
-		/*
-		 * Listen to the 'cpu' scheduling filter constraint
-		 * of counters:
-		 */
-		if (counter->cpu != -1 && counter->cpu != cpu)
-			continue;
-
-		if (counter != counter->group_leader) {
-			if (counter_sched_in(counter, cpuctx, ctx, cpu))
-				can_add_hw = 0;
-		} else {
-			if (group_can_go_on(counter, cpuctx, can_add_hw)) {
-				if (group_sched_in(counter, cpuctx, ctx, cpu))
-					can_add_hw = 0;
-			}
-		}
-	}
-	perf_enable();
- out:
-	spin_unlock(&ctx->lock);
-}
-
-/*
- * Called from scheduler to add the counters of the current task
- * with interrupts disabled.
- *
- * We restore the counter value and then enable it.
- *
- * This does not protect us against NMI, but enable()
- * sets the enabled bit in the control field of counter _before_
- * accessing the counter control register. If a NMI hits, then it will
- * keep the counter running.
- */
-void perf_counter_task_sched_in(struct task_struct *task, int cpu)
-{
-	struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
-	struct perf_counter_context *ctx = task->perf_counter_ctxp;
-
-	if (likely(!ctx))
-		return;
-	if (cpuctx->task_ctx == ctx)
-		return;
-	__perf_counter_sched_in(ctx, cpuctx, cpu);
-	cpuctx->task_ctx = ctx;
-}
-
-static void perf_counter_cpu_sched_in(struct perf_cpu_context *cpuctx, int cpu)
-{
-	struct perf_counter_context *ctx = &cpuctx->ctx;
-
-	__perf_counter_sched_in(ctx, cpuctx, cpu);
-}
-
-#define MAX_INTERRUPTS (~0ULL)
-
-static void perf_log_throttle(struct perf_counter *counter, int enable);
-
-static void perf_adjust_period(struct perf_counter *counter, u64 events)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-	u64 period, sample_period;
-	s64 delta;
-
-	events *= hwc->sample_period;
-	period = div64_u64(events, counter->attr.sample_freq);
-
-	delta = (s64)(period - hwc->sample_period);
-	delta = (delta + 7) / 8; /* low pass filter */
-
-	sample_period = hwc->sample_period + delta;
-
-	if (!sample_period)
-		sample_period = 1;
-
-	hwc->sample_period = sample_period;
-}
-
-static void perf_ctx_adjust_freq(struct perf_counter_context *ctx)
-{
-	struct perf_counter *counter;
-	struct hw_perf_counter *hwc;
-	u64 interrupts, freq;
-
-	spin_lock(&ctx->lock);
-	list_for_each_entry(counter, &ctx->counter_list, list_entry) {
-		if (counter->state != PERF_COUNTER_STATE_ACTIVE)
-			continue;
-
-		hwc = &counter->hw;
-
-		interrupts = hwc->interrupts;
-		hwc->interrupts = 0;
-
-		/*
-		 * unthrottle counters on the tick
-		 */
-		if (interrupts == MAX_INTERRUPTS) {
-			perf_log_throttle(counter, 1);
-			counter->pmu->unthrottle(counter);
-			interrupts = 2*sysctl_perf_counter_sample_rate/HZ;
-		}
-
-		if (!counter->attr.freq || !counter->attr.sample_freq)
-			continue;
-
-		/*
-		 * if the specified freq < HZ then we need to skip ticks
-		 */
-		if (counter->attr.sample_freq < HZ) {
-			freq = counter->attr.sample_freq;
-
-			hwc->freq_count += freq;
-			hwc->freq_interrupts += interrupts;
-
-			if (hwc->freq_count < HZ)
-				continue;
-
-			interrupts = hwc->freq_interrupts;
-			hwc->freq_interrupts = 0;
-			hwc->freq_count -= HZ;
-		} else
-			freq = HZ;
-
-		perf_adjust_period(counter, freq * interrupts);
-
-		/*
-		 * In order to avoid being stalled by an (accidental) huge
-		 * sample period, force reset the sample period if we didn't
-		 * get any events in this freq period.
-		 */
-		if (!interrupts) {
-			perf_disable();
-			counter->pmu->disable(counter);
-			atomic64_set(&hwc->period_left, 0);
-			counter->pmu->enable(counter);
-			perf_enable();
-		}
-	}
-	spin_unlock(&ctx->lock);
-}
-
-/*
- * Round-robin a context's counters:
- */
-static void rotate_ctx(struct perf_counter_context *ctx)
-{
-	struct perf_counter *counter;
-
-	if (!ctx->nr_counters)
-		return;
-
-	spin_lock(&ctx->lock);
-	/*
-	 * Rotate the first entry last (works just fine for group counters too):
-	 */
-	perf_disable();
-	list_for_each_entry(counter, &ctx->counter_list, list_entry) {
-		list_move_tail(&counter->list_entry, &ctx->counter_list);
-		break;
-	}
-	perf_enable();
-
-	spin_unlock(&ctx->lock);
-}
-
-void perf_counter_task_tick(struct task_struct *curr, int cpu)
-{
-	struct perf_cpu_context *cpuctx;
-	struct perf_counter_context *ctx;
-
-	if (!atomic_read(&nr_counters))
-		return;
-
-	cpuctx = &per_cpu(perf_cpu_context, cpu);
-	ctx = curr->perf_counter_ctxp;
-
-	perf_ctx_adjust_freq(&cpuctx->ctx);
-	if (ctx)
-		perf_ctx_adjust_freq(ctx);
-
-	perf_counter_cpu_sched_out(cpuctx);
-	if (ctx)
-		__perf_counter_task_sched_out(ctx);
-
-	rotate_ctx(&cpuctx->ctx);
-	if (ctx)
-		rotate_ctx(ctx);
-
-	perf_counter_cpu_sched_in(cpuctx, cpu);
-	if (ctx)
-		perf_counter_task_sched_in(curr, cpu);
-}
-
-/*
- * Enable all of a task's counters that have been marked enable-on-exec.
- * This expects task == current.
- */
-static void perf_counter_enable_on_exec(struct task_struct *task)
-{
-	struct perf_counter_context *ctx;
-	struct perf_counter *counter;
-	unsigned long flags;
-	int enabled = 0;
-
-	local_irq_save(flags);
-	ctx = task->perf_counter_ctxp;
-	if (!ctx || !ctx->nr_counters)
-		goto out;
-
-	__perf_counter_task_sched_out(ctx);
-
-	spin_lock(&ctx->lock);
-
-	list_for_each_entry(counter, &ctx->counter_list, list_entry) {
-		if (!counter->attr.enable_on_exec)
-			continue;
-		counter->attr.enable_on_exec = 0;
-		if (counter->state >= PERF_COUNTER_STATE_INACTIVE)
-			continue;
-		__perf_counter_mark_enabled(counter, ctx);
-		enabled = 1;
-	}
-
-	/*
-	 * Unclone this context if we enabled any counter.
-	 */
-	if (enabled)
-		unclone_ctx(ctx);
-
-	spin_unlock(&ctx->lock);
-
-	perf_counter_task_sched_in(task, smp_processor_id());
- out:
-	local_irq_restore(flags);
-}
-
-/*
- * Cross CPU call to read the hardware counter
- */
-static void __perf_counter_read(void *info)
-{
-	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
-	struct perf_counter *counter = info;
-	struct perf_counter_context *ctx = counter->ctx;
-	unsigned long flags;
-
-	/*
-	 * If this is a task context, we need to check whether it is
-	 * the current task context of this cpu.  If not it has been
-	 * scheduled out before the smp call arrived.  In that case
-	 * counter->count would have been updated to a recent sample
-	 * when the counter was scheduled out.
-	 */
-	if (ctx->task && cpuctx->task_ctx != ctx)
-		return;
-
-	local_irq_save(flags);
-	if (ctx->is_active)
-		update_context_time(ctx);
-	counter->pmu->read(counter);
-	update_counter_times(counter);
-	local_irq_restore(flags);
-}
-
-static u64 perf_counter_read(struct perf_counter *counter)
-{
-	/*
-	 * If counter is enabled and currently active on a CPU, update the
-	 * value in the counter structure:
-	 */
-	if (counter->state == PERF_COUNTER_STATE_ACTIVE) {
-		smp_call_function_single(counter->oncpu,
-					 __perf_counter_read, counter, 1);
-	} else if (counter->state == PERF_COUNTER_STATE_INACTIVE) {
-		update_counter_times(counter);
-	}
-
-	return atomic64_read(&counter->count);
-}
-
-/*
- * Initialize the perf_counter context in a task_struct:
- */
-static void
-__perf_counter_init_context(struct perf_counter_context *ctx,
-			    struct task_struct *task)
-{
-	memset(ctx, 0, sizeof(*ctx));
-	spin_lock_init(&ctx->lock);
-	mutex_init(&ctx->mutex);
-	INIT_LIST_HEAD(&ctx->counter_list);
-	INIT_LIST_HEAD(&ctx->event_list);
-	atomic_set(&ctx->refcount, 1);
-	ctx->task = task;
-}
-
-static struct perf_counter_context *find_get_context(pid_t pid, int cpu)
-{
-	struct perf_counter_context *ctx;
-	struct perf_cpu_context *cpuctx;
-	struct task_struct *task;
-	unsigned long flags;
-	int err;
-
-	/*
-	 * If cpu is not a wildcard then this is a percpu counter:
-	 */
-	if (cpu != -1) {
-		/* Must be root to operate on a CPU counter: */
-		if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
-			return ERR_PTR(-EACCES);
-
-		if (cpu < 0 || cpu > num_possible_cpus())
-			return ERR_PTR(-EINVAL);
-
-		/*
-		 * We could be clever and allow to attach a counter to an
-		 * offline CPU and activate it when the CPU comes up, but
-		 * that's for later.
-		 */
-		if (!cpu_isset(cpu, cpu_online_map))
-			return ERR_PTR(-ENODEV);
-
-		cpuctx = &per_cpu(perf_cpu_context, cpu);
-		ctx = &cpuctx->ctx;
-		get_ctx(ctx);
-
-		return ctx;
-	}
-
-	rcu_read_lock();
-	if (!pid)
-		task = current;
-	else
-		task = find_task_by_vpid(pid);
-	if (task)
-		get_task_struct(task);
-	rcu_read_unlock();
-
-	if (!task)
-		return ERR_PTR(-ESRCH);
-
-	/*
-	 * Can't attach counters to a dying task.
-	 */
-	err = -ESRCH;
-	if (task->flags & PF_EXITING)
-		goto errout;
-
-	/* Reuse ptrace permission checks for now. */
-	err = -EACCES;
-	if (!ptrace_may_access(task, PTRACE_MODE_READ))
-		goto errout;
-
- retry:
-	ctx = perf_lock_task_context(task, &flags);
-	if (ctx) {
-		unclone_ctx(ctx);
-		spin_unlock_irqrestore(&ctx->lock, flags);
-	}
-
-	if (!ctx) {
-		ctx = kmalloc(sizeof(struct perf_counter_context), GFP_KERNEL);
-		err = -ENOMEM;
-		if (!ctx)
-			goto errout;
-		__perf_counter_init_context(ctx, task);
-		get_ctx(ctx);
-		if (cmpxchg(&task->perf_counter_ctxp, NULL, ctx)) {
-			/*
-			 * We raced with some other task; use
-			 * the context they set.
-			 */
-			kfree(ctx);
-			goto retry;
-		}
-		get_task_struct(task);
-	}
-
-	put_task_struct(task);
-	return ctx;
-
- errout:
-	put_task_struct(task);
-	return ERR_PTR(err);
-}
-
-static void free_counter_rcu(struct rcu_head *head)
-{
-	struct perf_counter *counter;
-
-	counter = container_of(head, struct perf_counter, rcu_head);
-	if (counter->ns)
-		put_pid_ns(counter->ns);
-	kfree(counter);
-}
-
-static void perf_pending_sync(struct perf_counter *counter);
-
-static void free_counter(struct perf_counter *counter)
-{
-	perf_pending_sync(counter);
-
-	if (!counter->parent) {
-		atomic_dec(&nr_counters);
-		if (counter->attr.mmap)
-			atomic_dec(&nr_mmap_counters);
-		if (counter->attr.comm)
-			atomic_dec(&nr_comm_counters);
-		if (counter->attr.task)
-			atomic_dec(&nr_task_counters);
-	}
-
-	if (counter->output) {
-		fput(counter->output->filp);
-		counter->output = NULL;
-	}
-
-	if (counter->destroy)
-		counter->destroy(counter);
-
-	put_ctx(counter->ctx);
-	call_rcu(&counter->rcu_head, free_counter_rcu);
-}
-
-/*
- * Called when the last reference to the file is gone.
- */
-static int perf_release(struct inode *inode, struct file *file)
-{
-	struct perf_counter *counter = file->private_data;
-	struct perf_counter_context *ctx = counter->ctx;
-
-	file->private_data = NULL;
-
-	WARN_ON_ONCE(ctx->parent_ctx);
-	mutex_lock(&ctx->mutex);
-	perf_counter_remove_from_context(counter);
-	mutex_unlock(&ctx->mutex);
-
-	mutex_lock(&counter->owner->perf_counter_mutex);
-	list_del_init(&counter->owner_entry);
-	mutex_unlock(&counter->owner->perf_counter_mutex);
-	put_task_struct(counter->owner);
-
-	free_counter(counter);
-
-	return 0;
-}
-
-static int perf_counter_read_size(struct perf_counter *counter)
-{
-	int entry = sizeof(u64); /* value */
-	int size = 0;
-	int nr = 1;
-
-	if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
-		size += sizeof(u64);
-
-	if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
-		size += sizeof(u64);
-
-	if (counter->attr.read_format & PERF_FORMAT_ID)
-		entry += sizeof(u64);
-
-	if (counter->attr.read_format & PERF_FORMAT_GROUP) {
-		nr += counter->group_leader->nr_siblings;
-		size += sizeof(u64);
-	}
-
-	size += entry * nr;
-
-	return size;
-}
-
-static u64 perf_counter_read_value(struct perf_counter *counter)
-{
-	struct perf_counter *child;
-	u64 total = 0;
-
-	total += perf_counter_read(counter);
-	list_for_each_entry(child, &counter->child_list, child_list)
-		total += perf_counter_read(child);
-
-	return total;
-}
-
-static int perf_counter_read_entry(struct perf_counter *counter,
-				   u64 read_format, char __user *buf)
-{
-	int n = 0, count = 0;
-	u64 values[2];
-
-	values[n++] = perf_counter_read_value(counter);
-	if (read_format & PERF_FORMAT_ID)
-		values[n++] = primary_counter_id(counter);
-
-	count = n * sizeof(u64);
-
-	if (copy_to_user(buf, values, count))
-		return -EFAULT;
-
-	return count;
-}
-
-static int perf_counter_read_group(struct perf_counter *counter,
-				   u64 read_format, char __user *buf)
-{
-	struct perf_counter *leader = counter->group_leader, *sub;
-	int n = 0, size = 0, err = -EFAULT;
-	u64 values[3];
-
-	values[n++] = 1 + leader->nr_siblings;
-	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
-		values[n++] = leader->total_time_enabled +
-			atomic64_read(&leader->child_total_time_enabled);
-	}
-	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
-		values[n++] = leader->total_time_running +
-			atomic64_read(&leader->child_total_time_running);
-	}
-
-	size = n * sizeof(u64);
-
-	if (copy_to_user(buf, values, size))
-		return -EFAULT;
-
-	err = perf_counter_read_entry(leader, read_format, buf + size);
-	if (err < 0)
-		return err;
-
-	size += err;
-
-	list_for_each_entry(sub, &leader->sibling_list, list_entry) {
-		err = perf_counter_read_entry(sub, read_format,
-				buf + size);
-		if (err < 0)
-			return err;
-
-		size += err;
-	}
-
-	return size;
-}
-
-static int perf_counter_read_one(struct perf_counter *counter,
-				 u64 read_format, char __user *buf)
-{
-	u64 values[4];
-	int n = 0;
-
-	values[n++] = perf_counter_read_value(counter);
-	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
-		values[n++] = counter->total_time_enabled +
-			atomic64_read(&counter->child_total_time_enabled);
-	}
-	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
-		values[n++] = counter->total_time_running +
-			atomic64_read(&counter->child_total_time_running);
-	}
-	if (read_format & PERF_FORMAT_ID)
-		values[n++] = primary_counter_id(counter);
-
-	if (copy_to_user(buf, values, n * sizeof(u64)))
-		return -EFAULT;
-
-	return n * sizeof(u64);
-}
-
-/*
- * Read the performance counter - simple non blocking version for now
- */
-static ssize_t
-perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count)
-{
-	u64 read_format = counter->attr.read_format;
-	int ret;
-
-	/*
-	 * Return end-of-file for a read on a counter that is in
-	 * error state (i.e. because it was pinned but it couldn't be
-	 * scheduled on to the CPU at some point).
-	 */
-	if (counter->state == PERF_COUNTER_STATE_ERROR)
-		return 0;
-
-	if (count < perf_counter_read_size(counter))
-		return -ENOSPC;
-
-	WARN_ON_ONCE(counter->ctx->parent_ctx);
-	mutex_lock(&counter->child_mutex);
-	if (read_format & PERF_FORMAT_GROUP)
-		ret = perf_counter_read_group(counter, read_format, buf);
-	else
-		ret = perf_counter_read_one(counter, read_format, buf);
-	mutex_unlock(&counter->child_mutex);
-
-	return ret;
-}
-
-static ssize_t
-perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
-{
-	struct perf_counter *counter = file->private_data;
-
-	return perf_read_hw(counter, buf, count);
-}
-
-static unsigned int perf_poll(struct file *file, poll_table *wait)
-{
-	struct perf_counter *counter = file->private_data;
-	struct perf_mmap_data *data;
-	unsigned int events = POLL_HUP;
-
-	rcu_read_lock();
-	data = rcu_dereference(counter->data);
-	if (data)
-		events = atomic_xchg(&data->poll, 0);
-	rcu_read_unlock();
-
-	poll_wait(file, &counter->waitq, wait);
-
-	return events;
-}
-
-static void perf_counter_reset(struct perf_counter *counter)
-{
-	(void)perf_counter_read(counter);
-	atomic64_set(&counter->count, 0);
-	perf_counter_update_userpage(counter);
-}
-
-/*
- * Holding the top-level counter's child_mutex means that any
- * descendant process that has inherited this counter will block
- * in sync_child_counter if it goes to exit, thus satisfying the
- * task existence requirements of perf_counter_enable/disable.
- */
-static void perf_counter_for_each_child(struct perf_counter *counter,
-					void (*func)(struct perf_counter *))
-{
-	struct perf_counter *child;
-
-	WARN_ON_ONCE(counter->ctx->parent_ctx);
-	mutex_lock(&counter->child_mutex);
-	func(counter);
-	list_for_each_entry(child, &counter->child_list, child_list)
-		func(child);
-	mutex_unlock(&counter->child_mutex);
-}
-
-static void perf_counter_for_each(struct perf_counter *counter,
-				  void (*func)(struct perf_counter *))
-{
-	struct perf_counter_context *ctx = counter->ctx;
-	struct perf_counter *sibling;
-
-	WARN_ON_ONCE(ctx->parent_ctx);
-	mutex_lock(&ctx->mutex);
-	counter = counter->group_leader;
-
-	perf_counter_for_each_child(counter, func);
-	func(counter);
-	list_for_each_entry(sibling, &counter->sibling_list, list_entry)
-		perf_counter_for_each_child(counter, func);
-	mutex_unlock(&ctx->mutex);
-}
-
-static int perf_counter_period(struct perf_counter *counter, u64 __user *arg)
-{
-	struct perf_counter_context *ctx = counter->ctx;
-	unsigned long size;
-	int ret = 0;
-	u64 value;
-
-	if (!counter->attr.sample_period)
-		return -EINVAL;
-
-	size = copy_from_user(&value, arg, sizeof(value));
-	if (size != sizeof(value))
-		return -EFAULT;
-
-	if (!value)
-		return -EINVAL;
-
-	spin_lock_irq(&ctx->lock);
-	if (counter->attr.freq) {
-		if (value > sysctl_perf_counter_sample_rate) {
-			ret = -EINVAL;
-			goto unlock;
-		}
-
-		counter->attr.sample_freq = value;
-	} else {
-		counter->attr.sample_period = value;
-		counter->hw.sample_period = value;
-	}
-unlock:
-	spin_unlock_irq(&ctx->lock);
-
-	return ret;
-}
-
-int perf_counter_set_output(struct perf_counter *counter, int output_fd);
-
-static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	struct perf_counter *counter = file->private_data;
-	void (*func)(struct perf_counter *);
-	u32 flags = arg;
-
-	switch (cmd) {
-	case PERF_COUNTER_IOC_ENABLE:
-		func = perf_counter_enable;
-		break;
-	case PERF_COUNTER_IOC_DISABLE:
-		func = perf_counter_disable;
-		break;
-	case PERF_COUNTER_IOC_RESET:
-		func = perf_counter_reset;
-		break;
-
-	case PERF_COUNTER_IOC_REFRESH:
-		return perf_counter_refresh(counter, arg);
-
-	case PERF_COUNTER_IOC_PERIOD:
-		return perf_counter_period(counter, (u64 __user *)arg);
-
-	case PERF_COUNTER_IOC_SET_OUTPUT:
-		return perf_counter_set_output(counter, arg);
-
-	default:
-		return -ENOTTY;
-	}
-
-	if (flags & PERF_IOC_FLAG_GROUP)
-		perf_counter_for_each(counter, func);
-	else
-		perf_counter_for_each_child(counter, func);
-
-	return 0;
-}
-
-int perf_counter_task_enable(void)
-{
-	struct perf_counter *counter;
-
-	mutex_lock(&current->perf_counter_mutex);
-	list_for_each_entry(counter, &current->perf_counter_list, owner_entry)
-		perf_counter_for_each_child(counter, perf_counter_enable);
-	mutex_unlock(&current->perf_counter_mutex);
-
-	return 0;
-}
-
-int perf_counter_task_disable(void)
-{
-	struct perf_counter *counter;
-
-	mutex_lock(&current->perf_counter_mutex);
-	list_for_each_entry(counter, &current->perf_counter_list, owner_entry)
-		perf_counter_for_each_child(counter, perf_counter_disable);
-	mutex_unlock(&current->perf_counter_mutex);
-
-	return 0;
-}
-
-#ifndef PERF_COUNTER_INDEX_OFFSET
-# define PERF_COUNTER_INDEX_OFFSET 0
-#endif
-
-static int perf_counter_index(struct perf_counter *counter)
-{
-	if (counter->state != PERF_COUNTER_STATE_ACTIVE)
-		return 0;
-
-	return counter->hw.idx + 1 - PERF_COUNTER_INDEX_OFFSET;
-}
-
-/*
- * Callers need to ensure there can be no nesting of this function, otherwise
- * the seqlock logic goes bad. We can not serialize this because the arch
- * code calls this from NMI context.
- */
-void perf_counter_update_userpage(struct perf_counter *counter)
-{
-	struct perf_counter_mmap_page *userpg;
-	struct perf_mmap_data *data;
-
-	rcu_read_lock();
-	data = rcu_dereference(counter->data);
-	if (!data)
-		goto unlock;
-
-	userpg = data->user_page;
-
-	/*
-	 * Disable preemption so as to not let the corresponding user-space
-	 * spin too long if we get preempted.
-	 */
-	preempt_disable();
-	++userpg->lock;
-	barrier();
-	userpg->index = perf_counter_index(counter);
-	userpg->offset = atomic64_read(&counter->count);
-	if (counter->state == PERF_COUNTER_STATE_ACTIVE)
-		userpg->offset -= atomic64_read(&counter->hw.prev_count);
-
-	userpg->time_enabled = counter->total_time_enabled +
-			atomic64_read(&counter->child_total_time_enabled);
-
-	userpg->time_running = counter->total_time_running +
-			atomic64_read(&counter->child_total_time_running);
-
-	barrier();
-	++userpg->lock;
-	preempt_enable();
-unlock:
-	rcu_read_unlock();
-}
-
-static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	struct perf_counter *counter = vma->vm_file->private_data;
-	struct perf_mmap_data *data;
-	int ret = VM_FAULT_SIGBUS;
-
-	if (vmf->flags & FAULT_FLAG_MKWRITE) {
-		if (vmf->pgoff == 0)
-			ret = 0;
-		return ret;
-	}
-
-	rcu_read_lock();
-	data = rcu_dereference(counter->data);
-	if (!data)
-		goto unlock;
-
-	if (vmf->pgoff == 0) {
-		vmf->page = virt_to_page(data->user_page);
-	} else {
-		int nr = vmf->pgoff - 1;
-
-		if ((unsigned)nr > data->nr_pages)
-			goto unlock;
-
-		if (vmf->flags & FAULT_FLAG_WRITE)
-			goto unlock;
-
-		vmf->page = virt_to_page(data->data_pages[nr]);
-	}
-
-	get_page(vmf->page);
-	vmf->page->mapping = vma->vm_file->f_mapping;
-	vmf->page->index   = vmf->pgoff;
-
-	ret = 0;
-unlock:
-	rcu_read_unlock();
-
-	return ret;
-}
-
-static int perf_mmap_data_alloc(struct perf_counter *counter, int nr_pages)
-{
-	struct perf_mmap_data *data;
-	unsigned long size;
-	int i;
-
-	WARN_ON(atomic_read(&counter->mmap_count));
-
-	size = sizeof(struct perf_mmap_data);
-	size += nr_pages * sizeof(void *);
-
-	data = kzalloc(size, GFP_KERNEL);
-	if (!data)
-		goto fail;
-
-	data->user_page = (void *)get_zeroed_page(GFP_KERNEL);
-	if (!data->user_page)
-		goto fail_user_page;
-
-	for (i = 0; i < nr_pages; i++) {
-		data->data_pages[i] = (void *)get_zeroed_page(GFP_KERNEL);
-		if (!data->data_pages[i])
-			goto fail_data_pages;
-	}
-
-	data->nr_pages = nr_pages;
-	atomic_set(&data->lock, -1);
-
-	rcu_assign_pointer(counter->data, data);
-
-	return 0;
-
-fail_data_pages:
-	for (i--; i >= 0; i--)
-		free_page((unsigned long)data->data_pages[i]);
-
-	free_page((unsigned long)data->user_page);
-
-fail_user_page:
-	kfree(data);
-
-fail:
-	return -ENOMEM;
-}
-
-static void perf_mmap_free_page(unsigned long addr)
-{
-	struct page *page = virt_to_page((void *)addr);
-
-	page->mapping = NULL;
-	__free_page(page);
-}
-
-static void __perf_mmap_data_free(struct rcu_head *rcu_head)
-{
-	struct perf_mmap_data *data;
-	int i;
-
-	data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
-
-	perf_mmap_free_page((unsigned long)data->user_page);
-	for (i = 0; i < data->nr_pages; i++)
-		perf_mmap_free_page((unsigned long)data->data_pages[i]);
-
-	kfree(data);
-}
-
-static void perf_mmap_data_free(struct perf_counter *counter)
-{
-	struct perf_mmap_data *data = counter->data;
-
-	WARN_ON(atomic_read(&counter->mmap_count));
-
-	rcu_assign_pointer(counter->data, NULL);
-	call_rcu(&data->rcu_head, __perf_mmap_data_free);
-}
-
-static void perf_mmap_open(struct vm_area_struct *vma)
-{
-	struct perf_counter *counter = vma->vm_file->private_data;
-
-	atomic_inc(&counter->mmap_count);
-}
-
-static void perf_mmap_close(struct vm_area_struct *vma)
-{
-	struct perf_counter *counter = vma->vm_file->private_data;
-
-	WARN_ON_ONCE(counter->ctx->parent_ctx);
-	if (atomic_dec_and_mutex_lock(&counter->mmap_count, &counter->mmap_mutex)) {
-		struct user_struct *user = current_user();
-
-		atomic_long_sub(counter->data->nr_pages + 1, &user->locked_vm);
-		vma->vm_mm->locked_vm -= counter->data->nr_locked;
-		perf_mmap_data_free(counter);
-		mutex_unlock(&counter->mmap_mutex);
-	}
-}
-
-static struct vm_operations_struct perf_mmap_vmops = {
-	.open		= perf_mmap_open,
-	.close		= perf_mmap_close,
-	.fault		= perf_mmap_fault,
-	.page_mkwrite	= perf_mmap_fault,
-};
-
-static int perf_mmap(struct file *file, struct vm_area_struct *vma)
-{
-	struct perf_counter *counter = file->private_data;
-	unsigned long user_locked, user_lock_limit;
-	struct user_struct *user = current_user();
-	unsigned long locked, lock_limit;
-	unsigned long vma_size;
-	unsigned long nr_pages;
-	long user_extra, extra;
-	int ret = 0;
-
-	if (!(vma->vm_flags & VM_SHARED))
-		return -EINVAL;
-
-	vma_size = vma->vm_end - vma->vm_start;
-	nr_pages = (vma_size / PAGE_SIZE) - 1;
-
-	/*
-	 * If we have data pages ensure they're a power-of-two number, so we
-	 * can do bitmasks instead of modulo.
-	 */
-	if (nr_pages != 0 && !is_power_of_2(nr_pages))
-		return -EINVAL;
-
-	if (vma_size != PAGE_SIZE * (1 + nr_pages))
-		return -EINVAL;
-
-	if (vma->vm_pgoff != 0)
-		return -EINVAL;
-
-	WARN_ON_ONCE(counter->ctx->parent_ctx);
-	mutex_lock(&counter->mmap_mutex);
-	if (counter->output) {
-		ret = -EINVAL;
-		goto unlock;
-	}
-
-	if (atomic_inc_not_zero(&counter->mmap_count)) {
-		if (nr_pages != counter->data->nr_pages)
-			ret = -EINVAL;
-		goto unlock;
-	}
-
-	user_extra = nr_pages + 1;
-	user_lock_limit = sysctl_perf_counter_mlock >> (PAGE_SHIFT - 10);
-
-	/*
-	 * Increase the limit linearly with more CPUs:
-	 */
-	user_lock_limit *= num_online_cpus();
-
-	user_locked = atomic_long_read(&user->locked_vm) + user_extra;
-
-	extra = 0;
-	if (user_locked > user_lock_limit)
-		extra = user_locked - user_lock_limit;
-
-	lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
-	lock_limit >>= PAGE_SHIFT;
-	locked = vma->vm_mm->locked_vm + extra;
-
-	if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) {
-		ret = -EPERM;
-		goto unlock;
-	}
-
-	WARN_ON(counter->data);
-	ret = perf_mmap_data_alloc(counter, nr_pages);
-	if (ret)
-		goto unlock;
-
-	atomic_set(&counter->mmap_count, 1);
-	atomic_long_add(user_extra, &user->locked_vm);
-	vma->vm_mm->locked_vm += extra;
-	counter->data->nr_locked = extra;
-	if (vma->vm_flags & VM_WRITE)
-		counter->data->writable = 1;
-
-unlock:
-	mutex_unlock(&counter->mmap_mutex);
-
-	vma->vm_flags |= VM_RESERVED;
-	vma->vm_ops = &perf_mmap_vmops;
-
-	return ret;
-}
-
-static int perf_fasync(int fd, struct file *filp, int on)
-{
-	struct inode *inode = filp->f_path.dentry->d_inode;
-	struct perf_counter *counter = filp->private_data;
-	int retval;
-
-	mutex_lock(&inode->i_mutex);
-	retval = fasync_helper(fd, filp, on, &counter->fasync);
-	mutex_unlock(&inode->i_mutex);
-
-	if (retval < 0)
-		return retval;
-
-	return 0;
-}
-
-static const struct file_operations perf_fops = {
-	.release		= perf_release,
-	.read			= perf_read,
-	.poll			= perf_poll,
-	.unlocked_ioctl		= perf_ioctl,
-	.compat_ioctl		= perf_ioctl,
-	.mmap			= perf_mmap,
-	.fasync			= perf_fasync,
-};
-
-/*
- * Perf counter wakeup
- *
- * If there's data, ensure we set the poll() state and publish everything
- * to user-space before waking everybody up.
- */
-
-void perf_counter_wakeup(struct perf_counter *counter)
-{
-	wake_up_all(&counter->waitq);
-
-	if (counter->pending_kill) {
-		kill_fasync(&counter->fasync, SIGIO, counter->pending_kill);
-		counter->pending_kill = 0;
-	}
-}
-
-/*
- * Pending wakeups
- *
- * Handle the case where we need to wakeup up from NMI (or rq->lock) context.
- *
- * The NMI bit means we cannot possibly take locks. Therefore, maintain a
- * single linked list and use cmpxchg() to add entries lockless.
- */
-
-static void perf_pending_counter(struct perf_pending_entry *entry)
-{
-	struct perf_counter *counter = container_of(entry,
-			struct perf_counter, pending);
-
-	if (counter->pending_disable) {
-		counter->pending_disable = 0;
-		__perf_counter_disable(counter);
-	}
-
-	if (counter->pending_wakeup) {
-		counter->pending_wakeup = 0;
-		perf_counter_wakeup(counter);
-	}
-}
-
-#define PENDING_TAIL ((struct perf_pending_entry *)-1UL)
-
-static DEFINE_PER_CPU(struct perf_pending_entry *, perf_pending_head) = {
-	PENDING_TAIL,
-};
-
-static void perf_pending_queue(struct perf_pending_entry *entry,
-			       void (*func)(struct perf_pending_entry *))
-{
-	struct perf_pending_entry **head;
-
-	if (cmpxchg(&entry->next, NULL, PENDING_TAIL) != NULL)
-		return;
-
-	entry->func = func;
-
-	head = &get_cpu_var(perf_pending_head);
-
-	do {
-		entry->next = *head;
-	} while (cmpxchg(head, entry->next, entry) != entry->next);
-
-	set_perf_counter_pending();
-
-	put_cpu_var(perf_pending_head);
-}
-
-static int __perf_pending_run(void)
-{
-	struct perf_pending_entry *list;
-	int nr = 0;
-
-	list = xchg(&__get_cpu_var(perf_pending_head), PENDING_TAIL);
-	while (list != PENDING_TAIL) {
-		void (*func)(struct perf_pending_entry *);
-		struct perf_pending_entry *entry = list;
-
-		list = list->next;
-
-		func = entry->func;
-		entry->next = NULL;
-		/*
-		 * Ensure we observe the unqueue before we issue the wakeup,
-		 * so that we won't be waiting forever.
-		 * -- see perf_not_pending().
-		 */
-		smp_wmb();
-
-		func(entry);
-		nr++;
-	}
-
-	return nr;
-}
-
-static inline int perf_not_pending(struct perf_counter *counter)
-{
-	/*
-	 * If we flush on whatever cpu we run, there is a chance we don't
-	 * need to wait.
-	 */
-	get_cpu();
-	__perf_pending_run();
-	put_cpu();
-
-	/*
-	 * Ensure we see the proper queue state before going to sleep
-	 * so that we do not miss the wakeup. -- see perf_pending_handle()
-	 */
-	smp_rmb();
-	return counter->pending.next == NULL;
-}
-
-static void perf_pending_sync(struct perf_counter *counter)
-{
-	wait_event(counter->waitq, perf_not_pending(counter));
-}
-
-void perf_counter_do_pending(void)
-{
-	__perf_pending_run();
-}
-
-/*
- * Callchain support -- arch specific
- */
-
-__weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
-{
-	return NULL;
-}
-
-/*
- * Output
- */
-
-struct perf_output_handle {
-	struct perf_counter	*counter;
-	struct perf_mmap_data	*data;
-	unsigned long		head;
-	unsigned long		offset;
-	int			nmi;
-	int			sample;
-	int			locked;
-	unsigned long		flags;
-};
-
-static bool perf_output_space(struct perf_mmap_data *data,
-			      unsigned int offset, unsigned int head)
-{
-	unsigned long tail;
-	unsigned long mask;
-
-	if (!data->writable)
-		return true;
-
-	mask = (data->nr_pages << PAGE_SHIFT) - 1;
-	/*
-	 * Userspace could choose to issue a mb() before updating the tail
-	 * pointer. So that all reads will be completed before the write is
-	 * issued.
-	 */
-	tail = ACCESS_ONCE(data->user_page->data_tail);
-	smp_rmb();
-
-	offset = (offset - tail) & mask;
-	head   = (head   - tail) & mask;
-
-	if ((int)(head - offset) < 0)
-		return false;
-
-	return true;
-}
-
-static void perf_output_wakeup(struct perf_output_handle *handle)
-{
-	atomic_set(&handle->data->poll, POLL_IN);
-
-	if (handle->nmi) {
-		handle->counter->pending_wakeup = 1;
-		perf_pending_queue(&handle->counter->pending,
-				   perf_pending_counter);
-	} else
-		perf_counter_wakeup(handle->counter);
-}
-
-/*
- * Curious locking construct.
- *
- * We need to ensure a later event doesn't publish a head when a former
- * event isn't done writing. However since we need to deal with NMIs we
- * cannot fully serialize things.
- *
- * What we do is serialize between CPUs so we only have to deal with NMI
- * nesting on a single CPU.
- *
- * We only publish the head (and generate a wakeup) when the outer-most
- * event completes.
- */
-static void perf_output_lock(struct perf_output_handle *handle)
-{
-	struct perf_mmap_data *data = handle->data;
-	int cpu;
-
-	handle->locked = 0;
-
-	local_irq_save(handle->flags);
-	cpu = smp_processor_id();
-
-	if (in_nmi() && atomic_read(&data->lock) == cpu)
-		return;
-
-	while (atomic_cmpxchg(&data->lock, -1, cpu) != -1)
-		cpu_relax();
-
-	handle->locked = 1;
-}
-
-static void perf_output_unlock(struct perf_output_handle *handle)
-{
-	struct perf_mmap_data *data = handle->data;
-	unsigned long head;
-	int cpu;
-
-	data->done_head = data->head;
-
-	if (!handle->locked)
-		goto out;
-
-again:
-	/*
-	 * The xchg implies a full barrier that ensures all writes are done
-	 * before we publish the new head, matched by a rmb() in userspace when
-	 * reading this position.
-	 */
-	while ((head = atomic_long_xchg(&data->done_head, 0)))
-		data->user_page->data_head = head;
-
-	/*
-	 * NMI can happen here, which means we can miss a done_head update.
-	 */
-
-	cpu = atomic_xchg(&data->lock, -1);
-	WARN_ON_ONCE(cpu != smp_processor_id());
-
-	/*
-	 * Therefore we have to validate we did not indeed do so.
-	 */
-	if (unlikely(atomic_long_read(&data->done_head))) {
-		/*
-		 * Since we had it locked, we can lock it again.
-		 */
-		while (atomic_cmpxchg(&data->lock, -1, cpu) != -1)
-			cpu_relax();
-
-		goto again;
-	}
-
-	if (atomic_xchg(&data->wakeup, 0))
-		perf_output_wakeup(handle);
-out:
-	local_irq_restore(handle->flags);
-}
-
-static void perf_output_copy(struct perf_output_handle *handle,
-			     const void *buf, unsigned int len)
-{
-	unsigned int pages_mask;
-	unsigned int offset;
-	unsigned int size;
-	void **pages;
-
-	offset		= handle->offset;
-	pages_mask	= handle->data->nr_pages - 1;
-	pages		= handle->data->data_pages;
-
-	do {
-		unsigned int page_offset;
-		int nr;
-
-		nr	    = (offset >> PAGE_SHIFT) & pages_mask;
-		page_offset = offset & (PAGE_SIZE - 1);
-		size	    = min_t(unsigned int, PAGE_SIZE - page_offset, len);
-
-		memcpy(pages[nr] + page_offset, buf, size);
-
-		len	    -= size;
-		buf	    += size;
-		offset	    += size;
-	} while (len);
-
-	handle->offset = offset;
-
-	/*
-	 * Check we didn't copy past our reservation window, taking the
-	 * possible unsigned int wrap into account.
-	 */
-	WARN_ON_ONCE(((long)(handle->head - handle->offset)) < 0);
-}
-
-#define perf_output_put(handle, x) \
-	perf_output_copy((handle), &(x), sizeof(x))
-
-static int perf_output_begin(struct perf_output_handle *handle,
-			     struct perf_counter *counter, unsigned int size,
-			     int nmi, int sample)
-{
-	struct perf_counter *output_counter;
-	struct perf_mmap_data *data;
-	unsigned int offset, head;
-	int have_lost;
-	struct {
-		struct perf_event_header header;
-		u64			 id;
-		u64			 lost;
-	} lost_event;
-
-	rcu_read_lock();
-	/*
-	 * For inherited counters we send all the output towards the parent.
-	 */
-	if (counter->parent)
-		counter = counter->parent;
-
-	output_counter = rcu_dereference(counter->output);
-	if (output_counter)
-		counter = output_counter;
-
-	data = rcu_dereference(counter->data);
-	if (!data)
-		goto out;
-
-	handle->data	= data;
-	handle->counter	= counter;
-	handle->nmi	= nmi;
-	handle->sample	= sample;
-
-	if (!data->nr_pages)
-		goto fail;
-
-	have_lost = atomic_read(&data->lost);
-	if (have_lost)
-		size += sizeof(lost_event);
-
-	perf_output_lock(handle);
-
-	do {
-		offset = head = atomic_long_read(&data->head);
-		head += size;
-		if (unlikely(!perf_output_space(data, offset, head)))
-			goto fail;
-	} while (atomic_long_cmpxchg(&data->head, offset, head) != offset);
-
-	handle->offset	= offset;
-	handle->head	= head;
-
-	if ((offset >> PAGE_SHIFT) != (head >> PAGE_SHIFT))
-		atomic_set(&data->wakeup, 1);
-
-	if (have_lost) {
-		lost_event.header.type = PERF_EVENT_LOST;
-		lost_event.header.misc = 0;
-		lost_event.header.size = sizeof(lost_event);
-		lost_event.id          = counter->id;
-		lost_event.lost        = atomic_xchg(&data->lost, 0);
-
-		perf_output_put(handle, lost_event);
-	}
-
-	return 0;
-
-fail:
-	atomic_inc(&data->lost);
-	perf_output_unlock(handle);
-out:
-	rcu_read_unlock();
-
-	return -ENOSPC;
-}
-
-static void perf_output_end(struct perf_output_handle *handle)
-{
-	struct perf_counter *counter = handle->counter;
-	struct perf_mmap_data *data = handle->data;
-
-	int wakeup_events = counter->attr.wakeup_events;
-
-	if (handle->sample && wakeup_events) {
-		int events = atomic_inc_return(&data->events);
-		if (events >= wakeup_events) {
-			atomic_sub(wakeup_events, &data->events);
-			atomic_set(&data->wakeup, 1);
-		}
-	}
-
-	perf_output_unlock(handle);
-	rcu_read_unlock();
-}
-
-static u32 perf_counter_pid(struct perf_counter *counter, struct task_struct *p)
-{
-	/*
-	 * only top level counters have the pid namespace they were created in
-	 */
-	if (counter->parent)
-		counter = counter->parent;
-
-	return task_tgid_nr_ns(p, counter->ns);
-}
-
-static u32 perf_counter_tid(struct perf_counter *counter, struct task_struct *p)
-{
-	/*
-	 * only top level counters have the pid namespace they were created in
-	 */
-	if (counter->parent)
-		counter = counter->parent;
-
-	return task_pid_nr_ns(p, counter->ns);
-}
-
-static void perf_output_read_one(struct perf_output_handle *handle,
-				 struct perf_counter *counter)
-{
-	u64 read_format = counter->attr.read_format;
-	u64 values[4];
-	int n = 0;
-
-	values[n++] = atomic64_read(&counter->count);
-	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
-		values[n++] = counter->total_time_enabled +
-			atomic64_read(&counter->child_total_time_enabled);
-	}
-	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
-		values[n++] = counter->total_time_running +
-			atomic64_read(&counter->child_total_time_running);
-	}
-	if (read_format & PERF_FORMAT_ID)
-		values[n++] = primary_counter_id(counter);
-
-	perf_output_copy(handle, values, n * sizeof(u64));
-}
-
-/*
- * XXX PERF_FORMAT_GROUP vs inherited counters seems difficult.
- */
-static void perf_output_read_group(struct perf_output_handle *handle,
-			    struct perf_counter *counter)
-{
-	struct perf_counter *leader = counter->group_leader, *sub;
-	u64 read_format = counter->attr.read_format;
-	u64 values[5];
-	int n = 0;
-
-	values[n++] = 1 + leader->nr_siblings;
-
-	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
-		values[n++] = leader->total_time_enabled;
-
-	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
-		values[n++] = leader->total_time_running;
-
-	if (leader != counter)
-		leader->pmu->read(leader);
-
-	values[n++] = atomic64_read(&leader->count);
-	if (read_format & PERF_FORMAT_ID)
-		values[n++] = primary_counter_id(leader);
-
-	perf_output_copy(handle, values, n * sizeof(u64));
-
-	list_for_each_entry(sub, &leader->sibling_list, list_entry) {
-		n = 0;
-
-		if (sub != counter)
-			sub->pmu->read(sub);
-
-		values[n++] = atomic64_read(&sub->count);
-		if (read_format & PERF_FORMAT_ID)
-			values[n++] = primary_counter_id(sub);
-
-		perf_output_copy(handle, values, n * sizeof(u64));
-	}
-}
-
-static void perf_output_read(struct perf_output_handle *handle,
-			     struct perf_counter *counter)
-{
-	if (counter->attr.read_format & PERF_FORMAT_GROUP)
-		perf_output_read_group(handle, counter);
-	else
-		perf_output_read_one(handle, counter);
-}
-
-void perf_counter_output(struct perf_counter *counter, int nmi,
-				struct perf_sample_data *data)
-{
-	int ret;
-	u64 sample_type = counter->attr.sample_type;
-	struct perf_output_handle handle;
-	struct perf_event_header header;
-	u64 ip;
-	struct {
-		u32 pid, tid;
-	} tid_entry;
-	struct perf_callchain_entry *callchain = NULL;
-	int callchain_size = 0;
-	u64 time;
-	struct {
-		u32 cpu, reserved;
-	} cpu_entry;
-
-	header.type = PERF_EVENT_SAMPLE;
-	header.size = sizeof(header);
-
-	header.misc = 0;
-	header.misc |= perf_misc_flags(data->regs);
-
-	if (sample_type & PERF_SAMPLE_IP) {
-		ip = perf_instruction_pointer(data->regs);
-		header.size += sizeof(ip);
-	}
-
-	if (sample_type & PERF_SAMPLE_TID) {
-		/* namespace issues */
-		tid_entry.pid = perf_counter_pid(counter, current);
-		tid_entry.tid = perf_counter_tid(counter, current);
-
-		header.size += sizeof(tid_entry);
-	}
-
-	if (sample_type & PERF_SAMPLE_TIME) {
-		/*
-		 * Maybe do better on x86 and provide cpu_clock_nmi()
-		 */
-		time = sched_clock();
-
-		header.size += sizeof(u64);
-	}
-
-	if (sample_type & PERF_SAMPLE_ADDR)
-		header.size += sizeof(u64);
-
-	if (sample_type & PERF_SAMPLE_ID)
-		header.size += sizeof(u64);
-
-	if (sample_type & PERF_SAMPLE_STREAM_ID)
-		header.size += sizeof(u64);
-
-	if (sample_type & PERF_SAMPLE_CPU) {
-		header.size += sizeof(cpu_entry);
-
-		cpu_entry.cpu = raw_smp_processor_id();
-		cpu_entry.reserved = 0;
-	}
-
-	if (sample_type & PERF_SAMPLE_PERIOD)
-		header.size += sizeof(u64);
-
-	if (sample_type & PERF_SAMPLE_READ)
-		header.size += perf_counter_read_size(counter);
-
-	if (sample_type & PERF_SAMPLE_CALLCHAIN) {
-		callchain = perf_callchain(data->regs);
-
-		if (callchain) {
-			callchain_size = (1 + callchain->nr) * sizeof(u64);
-			header.size += callchain_size;
-		} else
-			header.size += sizeof(u64);
-	}
-
-	if (sample_type & PERF_SAMPLE_RAW) {
-		int size = sizeof(u32);
-
-		if (data->raw)
-			size += data->raw->size;
-		else
-			size += sizeof(u32);
-
-		WARN_ON_ONCE(size & (sizeof(u64)-1));
-		header.size += size;
-	}
-
-	ret = perf_output_begin(&handle, counter, header.size, nmi, 1);
-	if (ret)
-		return;
-
-	perf_output_put(&handle, header);
-
-	if (sample_type & PERF_SAMPLE_IP)
-		perf_output_put(&handle, ip);
-
-	if (sample_type & PERF_SAMPLE_TID)
-		perf_output_put(&handle, tid_entry);
-
-	if (sample_type & PERF_SAMPLE_TIME)
-		perf_output_put(&handle, time);
-
-	if (sample_type & PERF_SAMPLE_ADDR)
-		perf_output_put(&handle, data->addr);
-
-	if (sample_type & PERF_SAMPLE_ID) {
-		u64 id = primary_counter_id(counter);
-
-		perf_output_put(&handle, id);
-	}
-
-	if (sample_type & PERF_SAMPLE_STREAM_ID)
-		perf_output_put(&handle, counter->id);
-
-	if (sample_type & PERF_SAMPLE_CPU)
-		perf_output_put(&handle, cpu_entry);
-
-	if (sample_type & PERF_SAMPLE_PERIOD)
-		perf_output_put(&handle, data->period);
-
-	if (sample_type & PERF_SAMPLE_READ)
-		perf_output_read(&handle, counter);
-
-	if (sample_type & PERF_SAMPLE_CALLCHAIN) {
-		if (callchain)
-			perf_output_copy(&handle, callchain, callchain_size);
-		else {
-			u64 nr = 0;
-			perf_output_put(&handle, nr);
-		}
-	}
-
-	if (sample_type & PERF_SAMPLE_RAW) {
-		if (data->raw) {
-			perf_output_put(&handle, data->raw->size);
-			perf_output_copy(&handle, data->raw->data, data->raw->size);
-		} else {
-			struct {
-				u32	size;
-				u32	data;
-			} raw = {
-				.size = sizeof(u32),
-				.data = 0,
-			};
-			perf_output_put(&handle, raw);
-		}
-	}
-
-	perf_output_end(&handle);
-}
-
-/*
- * read event
- */
-
-struct perf_read_event {
-	struct perf_event_header	header;
-
-	u32				pid;
-	u32				tid;
-};
-
-static void
-perf_counter_read_event(struct perf_counter *counter,
-			struct task_struct *task)
-{
-	struct perf_output_handle handle;
-	struct perf_read_event event = {
-		.header = {
-			.type = PERF_EVENT_READ,
-			.misc = 0,
-			.size = sizeof(event) + perf_counter_read_size(counter),
-		},
-		.pid = perf_counter_pid(counter, task),
-		.tid = perf_counter_tid(counter, task),
-	};
-	int ret;
-
-	ret = perf_output_begin(&handle, counter, event.header.size, 0, 0);
-	if (ret)
-		return;
-
-	perf_output_put(&handle, event);
-	perf_output_read(&handle, counter);
-
-	perf_output_end(&handle);
-}
-
-/*
- * task tracking -- fork/exit
- *
- * enabled by: attr.comm | attr.mmap | attr.task
- */
-
-struct perf_task_event {
-	struct task_struct		*task;
-	struct perf_counter_context	*task_ctx;
-
-	struct {
-		struct perf_event_header	header;
-
-		u32				pid;
-		u32				ppid;
-		u32				tid;
-		u32				ptid;
-	} event;
-};
-
-static void perf_counter_task_output(struct perf_counter *counter,
-				     struct perf_task_event *task_event)
-{
-	struct perf_output_handle handle;
-	int size = task_event->event.header.size;
-	struct task_struct *task = task_event->task;
-	int ret = perf_output_begin(&handle, counter, size, 0, 0);
-
-	if (ret)
-		return;
-
-	task_event->event.pid = perf_counter_pid(counter, task);
-	task_event->event.ppid = perf_counter_pid(counter, current);
-
-	task_event->event.tid = perf_counter_tid(counter, task);
-	task_event->event.ptid = perf_counter_tid(counter, current);
-
-	perf_output_put(&handle, task_event->event);
-	perf_output_end(&handle);
-}
-
-static int perf_counter_task_match(struct perf_counter *counter)
-{
-	if (counter->attr.comm || counter->attr.mmap || counter->attr.task)
-		return 1;
-
-	return 0;
-}
-
-static void perf_counter_task_ctx(struct perf_counter_context *ctx,
-				  struct perf_task_event *task_event)
-{
-	struct perf_counter *counter;
-
-	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
-		return;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) {
-		if (perf_counter_task_match(counter))
-			perf_counter_task_output(counter, task_event);
-	}
-	rcu_read_unlock();
-}
-
-static void perf_counter_task_event(struct perf_task_event *task_event)
-{
-	struct perf_cpu_context *cpuctx;
-	struct perf_counter_context *ctx = task_event->task_ctx;
-
-	cpuctx = &get_cpu_var(perf_cpu_context);
-	perf_counter_task_ctx(&cpuctx->ctx, task_event);
-	put_cpu_var(perf_cpu_context);
-
-	rcu_read_lock();
-	if (!ctx)
-		ctx = rcu_dereference(task_event->task->perf_counter_ctxp);
-	if (ctx)
-		perf_counter_task_ctx(ctx, task_event);
-	rcu_read_unlock();
-}
-
-static void perf_counter_task(struct task_struct *task,
-			      struct perf_counter_context *task_ctx,
-			      int new)
-{
-	struct perf_task_event task_event;
-
-	if (!atomic_read(&nr_comm_counters) &&
-	    !atomic_read(&nr_mmap_counters) &&
-	    !atomic_read(&nr_task_counters))
-		return;
-
-	task_event = (struct perf_task_event){
-		.task	  = task,
-		.task_ctx = task_ctx,
-		.event    = {
-			.header = {
-				.type = new ? PERF_EVENT_FORK : PERF_EVENT_EXIT,
-				.misc = 0,
-				.size = sizeof(task_event.event),
-			},
-			/* .pid  */
-			/* .ppid */
-			/* .tid  */
-			/* .ptid */
-		},
-	};
-
-	perf_counter_task_event(&task_event);
-}
-
-void perf_counter_fork(struct task_struct *task)
-{
-	perf_counter_task(task, NULL, 1);
-}
-
-/*
- * comm tracking
- */
-
-struct perf_comm_event {
-	struct task_struct	*task;
-	char			*comm;
-	int			comm_size;
-
-	struct {
-		struct perf_event_header	header;
-
-		u32				pid;
-		u32				tid;
-	} event;
-};
-
-static void perf_counter_comm_output(struct perf_counter *counter,
-				     struct perf_comm_event *comm_event)
-{
-	struct perf_output_handle handle;
-	int size = comm_event->event.header.size;
-	int ret = perf_output_begin(&handle, counter, size, 0, 0);
-
-	if (ret)
-		return;
-
-	comm_event->event.pid = perf_counter_pid(counter, comm_event->task);
-	comm_event->event.tid = perf_counter_tid(counter, comm_event->task);
-
-	perf_output_put(&handle, comm_event->event);
-	perf_output_copy(&handle, comm_event->comm,
-				   comm_event->comm_size);
-	perf_output_end(&handle);
-}
-
-static int perf_counter_comm_match(struct perf_counter *counter)
-{
-	if (counter->attr.comm)
-		return 1;
-
-	return 0;
-}
-
-static void perf_counter_comm_ctx(struct perf_counter_context *ctx,
-				  struct perf_comm_event *comm_event)
-{
-	struct perf_counter *counter;
-
-	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
-		return;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) {
-		if (perf_counter_comm_match(counter))
-			perf_counter_comm_output(counter, comm_event);
-	}
-	rcu_read_unlock();
-}
-
-static void perf_counter_comm_event(struct perf_comm_event *comm_event)
-{
-	struct perf_cpu_context *cpuctx;
-	struct perf_counter_context *ctx;
-	unsigned int size;
-	char comm[TASK_COMM_LEN];
-
-	memset(comm, 0, sizeof(comm));
-	strncpy(comm, comm_event->task->comm, sizeof(comm));
-	size = ALIGN(strlen(comm)+1, sizeof(u64));
-
-	comm_event->comm = comm;
-	comm_event->comm_size = size;
-
-	comm_event->event.header.size = sizeof(comm_event->event) + size;
-
-	cpuctx = &get_cpu_var(perf_cpu_context);
-	perf_counter_comm_ctx(&cpuctx->ctx, comm_event);
-	put_cpu_var(perf_cpu_context);
-
-	rcu_read_lock();
-	/*
-	 * doesn't really matter which of the child contexts the
-	 * events ends up in.
-	 */
-	ctx = rcu_dereference(current->perf_counter_ctxp);
-	if (ctx)
-		perf_counter_comm_ctx(ctx, comm_event);
-	rcu_read_unlock();
-}
-
-void perf_counter_comm(struct task_struct *task)
-{
-	struct perf_comm_event comm_event;
-
-	if (task->perf_counter_ctxp)
-		perf_counter_enable_on_exec(task);
-
-	if (!atomic_read(&nr_comm_counters))
-		return;
-
-	comm_event = (struct perf_comm_event){
-		.task	= task,
-		/* .comm      */
-		/* .comm_size */
-		.event  = {
-			.header = {
-				.type = PERF_EVENT_COMM,
-				.misc = 0,
-				/* .size */
-			},
-			/* .pid */
-			/* .tid */
-		},
-	};
-
-	perf_counter_comm_event(&comm_event);
-}
-
-/*
- * mmap tracking
- */
-
-struct perf_mmap_event {
-	struct vm_area_struct	*vma;
-
-	const char		*file_name;
-	int			file_size;
-
-	struct {
-		struct perf_event_header	header;
-
-		u32				pid;
-		u32				tid;
-		u64				start;
-		u64				len;
-		u64				pgoff;
-	} event;
-};
-
-static void perf_counter_mmap_output(struct perf_counter *counter,
-				     struct perf_mmap_event *mmap_event)
-{
-	struct perf_output_handle handle;
-	int size = mmap_event->event.header.size;
-	int ret = perf_output_begin(&handle, counter, size, 0, 0);
-
-	if (ret)
-		return;
-
-	mmap_event->event.pid = perf_counter_pid(counter, current);
-	mmap_event->event.tid = perf_counter_tid(counter, current);
-
-	perf_output_put(&handle, mmap_event->event);
-	perf_output_copy(&handle, mmap_event->file_name,
-				   mmap_event->file_size);
-	perf_output_end(&handle);
-}
-
-static int perf_counter_mmap_match(struct perf_counter *counter,
-				   struct perf_mmap_event *mmap_event)
-{
-	if (counter->attr.mmap)
-		return 1;
-
-	return 0;
-}
-
-static void perf_counter_mmap_ctx(struct perf_counter_context *ctx,
-				  struct perf_mmap_event *mmap_event)
-{
-	struct perf_counter *counter;
-
-	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
-		return;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) {
-		if (perf_counter_mmap_match(counter, mmap_event))
-			perf_counter_mmap_output(counter, mmap_event);
-	}
-	rcu_read_unlock();
-}
-
-static void perf_counter_mmap_event(struct perf_mmap_event *mmap_event)
-{
-	struct perf_cpu_context *cpuctx;
-	struct perf_counter_context *ctx;
-	struct vm_area_struct *vma = mmap_event->vma;
-	struct file *file = vma->vm_file;
-	unsigned int size;
-	char tmp[16];
-	char *buf = NULL;
-	const char *name;
-
-	memset(tmp, 0, sizeof(tmp));
-
-	if (file) {
-		/*
-		 * d_path works from the end of the buffer backwards, so we
-		 * need to add enough zero bytes after the string to handle
-		 * the 64bit alignment we do later.
-		 */
-		buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
-		if (!buf) {
-			name = strncpy(tmp, "//enomem", sizeof(tmp));
-			goto got_name;
-		}
-		name = d_path(&file->f_path, buf, PATH_MAX);
-		if (IS_ERR(name)) {
-			name = strncpy(tmp, "//toolong", sizeof(tmp));
-			goto got_name;
-		}
-	} else {
-		if (arch_vma_name(mmap_event->vma)) {
-			name = strncpy(tmp, arch_vma_name(mmap_event->vma),
-				       sizeof(tmp));
-			goto got_name;
-		}
-
-		if (!vma->vm_mm) {
-			name = strncpy(tmp, "[vdso]", sizeof(tmp));
-			goto got_name;
-		}
-
-		name = strncpy(tmp, "//anon", sizeof(tmp));
-		goto got_name;
-	}
-
-got_name:
-	size = ALIGN(strlen(name)+1, sizeof(u64));
-
-	mmap_event->file_name = name;
-	mmap_event->file_size = size;
-
-	mmap_event->event.header.size = sizeof(mmap_event->event) + size;
-
-	cpuctx = &get_cpu_var(perf_cpu_context);
-	perf_counter_mmap_ctx(&cpuctx->ctx, mmap_event);
-	put_cpu_var(perf_cpu_context);
-
-	rcu_read_lock();
-	/*
-	 * doesn't really matter which of the child contexts the
-	 * events ends up in.
-	 */
-	ctx = rcu_dereference(current->perf_counter_ctxp);
-	if (ctx)
-		perf_counter_mmap_ctx(ctx, mmap_event);
-	rcu_read_unlock();
-
-	kfree(buf);
-}
-
-void __perf_counter_mmap(struct vm_area_struct *vma)
-{
-	struct perf_mmap_event mmap_event;
-
-	if (!atomic_read(&nr_mmap_counters))
-		return;
-
-	mmap_event = (struct perf_mmap_event){
-		.vma	= vma,
-		/* .file_name */
-		/* .file_size */
-		.event  = {
-			.header = {
-				.type = PERF_EVENT_MMAP,
-				.misc = 0,
-				/* .size */
-			},
-			/* .pid */
-			/* .tid */
-			.start  = vma->vm_start,
-			.len    = vma->vm_end - vma->vm_start,
-			.pgoff  = vma->vm_pgoff,
-		},
-	};
-
-	perf_counter_mmap_event(&mmap_event);
-}
-
-/*
- * IRQ throttle logging
- */
-
-static void perf_log_throttle(struct perf_counter *counter, int enable)
-{
-	struct perf_output_handle handle;
-	int ret;
-
-	struct {
-		struct perf_event_header	header;
-		u64				time;
-		u64				id;
-		u64				stream_id;
-	} throttle_event = {
-		.header = {
-			.type = PERF_EVENT_THROTTLE,
-			.misc = 0,
-			.size = sizeof(throttle_event),
-		},
-		.time		= sched_clock(),
-		.id		= primary_counter_id(counter),
-		.stream_id	= counter->id,
-	};
-
-	if (enable)
-		throttle_event.header.type = PERF_EVENT_UNTHROTTLE;
-
-	ret = perf_output_begin(&handle, counter, sizeof(throttle_event), 1, 0);
-	if (ret)
-		return;
-
-	perf_output_put(&handle, throttle_event);
-	perf_output_end(&handle);
-}
-
-/*
- * Generic counter overflow handling, sampling.
- */
-
-int perf_counter_overflow(struct perf_counter *counter, int nmi,
-			  struct perf_sample_data *data)
-{
-	int events = atomic_read(&counter->event_limit);
-	int throttle = counter->pmu->unthrottle != NULL;
-	struct hw_perf_counter *hwc = &counter->hw;
-	int ret = 0;
-
-	if (!throttle) {
-		hwc->interrupts++;
-	} else {
-		if (hwc->interrupts != MAX_INTERRUPTS) {
-			hwc->interrupts++;
-			if (HZ * hwc->interrupts >
-					(u64)sysctl_perf_counter_sample_rate) {
-				hwc->interrupts = MAX_INTERRUPTS;
-				perf_log_throttle(counter, 0);
-				ret = 1;
-			}
-		} else {
-			/*
-			 * Keep re-disabling counters even though on the previous
-			 * pass we disabled it - just in case we raced with a
-			 * sched-in and the counter got enabled again:
-			 */
-			ret = 1;
-		}
-	}
-
-	if (counter->attr.freq) {
-		u64 now = sched_clock();
-		s64 delta = now - hwc->freq_stamp;
-
-		hwc->freq_stamp = now;
-
-		if (delta > 0 && delta < TICK_NSEC)
-			perf_adjust_period(counter, NSEC_PER_SEC / (int)delta);
-	}
-
-	/*
-	 * XXX event_limit might not quite work as expected on inherited
-	 * counters
-	 */
-
-	counter->pending_kill = POLL_IN;
-	if (events && atomic_dec_and_test(&counter->event_limit)) {
-		ret = 1;
-		counter->pending_kill = POLL_HUP;
-		if (nmi) {
-			counter->pending_disable = 1;
-			perf_pending_queue(&counter->pending,
-					   perf_pending_counter);
-		} else
-			perf_counter_disable(counter);
-	}
-
-	perf_counter_output(counter, nmi, data);
-	return ret;
-}
-
-/*
- * Generic software counter infrastructure
- */
-
-/*
- * We directly increment counter->count and keep a second value in
- * counter->hw.period_left to count intervals. This period counter
- * is kept in the range [-sample_period, 0] so that we can use the
- * sign as trigger.
- */
-
-static u64 perf_swcounter_set_period(struct perf_counter *counter)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-	u64 period = hwc->last_period;
-	u64 nr, offset;
-	s64 old, val;
-
-	hwc->last_period = hwc->sample_period;
-
-again:
-	old = val = atomic64_read(&hwc->period_left);
-	if (val < 0)
-		return 0;
-
-	nr = div64_u64(period + val, period);
-	offset = nr * period;
-	val -= offset;
-	if (atomic64_cmpxchg(&hwc->period_left, old, val) != old)
-		goto again;
-
-	return nr;
-}
-
-static void perf_swcounter_overflow(struct perf_counter *counter,
-				    int nmi, struct perf_sample_data *data)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-	u64 overflow;
-
-	data->period = counter->hw.last_period;
-	overflow = perf_swcounter_set_period(counter);
-
-	if (hwc->interrupts == MAX_INTERRUPTS)
-		return;
-
-	for (; overflow; overflow--) {
-		if (perf_counter_overflow(counter, nmi, data)) {
-			/*
-			 * We inhibit the overflow from happening when
-			 * hwc->interrupts == MAX_INTERRUPTS.
-			 */
-			break;
-		}
-	}
-}
-
-static void perf_swcounter_unthrottle(struct perf_counter *counter)
-{
-	/*
-	 * Nothing to do, we already reset hwc->interrupts.
-	 */
-}
-
-static void perf_swcounter_add(struct perf_counter *counter, u64 nr,
-			       int nmi, struct perf_sample_data *data)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-
-	atomic64_add(nr, &counter->count);
-
-	if (!hwc->sample_period)
-		return;
-
-	if (!data->regs)
-		return;
-
-	if (!atomic64_add_negative(nr, &hwc->period_left))
-		perf_swcounter_overflow(counter, nmi, data);
-}
-
-static int perf_swcounter_is_counting(struct perf_counter *counter)
-{
-	/*
-	 * The counter is active, we're good!
-	 */
-	if (counter->state == PERF_COUNTER_STATE_ACTIVE)
-		return 1;
-
-	/*
-	 * The counter is off/error, not counting.
-	 */
-	if (counter->state != PERF_COUNTER_STATE_INACTIVE)
-		return 0;
-
-	/*
-	 * The counter is inactive, if the context is active
-	 * we're part of a group that didn't make it on the 'pmu',
-	 * not counting.
-	 */
-	if (counter->ctx->is_active)
-		return 0;
-
-	/*
-	 * We're inactive and the context is too, this means the
-	 * task is scheduled out, we're counting events that happen
-	 * to us, like migration events.
-	 */
-	return 1;
-}
-
-static int perf_swcounter_match(struct perf_counter *counter,
-				enum perf_type_id type,
-				u32 event, struct pt_regs *regs)
-{
-	if (!perf_swcounter_is_counting(counter))
-		return 0;
-
-	if (counter->attr.type != type)
-		return 0;
-	if (counter->attr.config != event)
-		return 0;
-
-	if (regs) {
-		if (counter->attr.exclude_user && user_mode(regs))
-			return 0;
-
-		if (counter->attr.exclude_kernel && !user_mode(regs))
-			return 0;
-	}
-
-	return 1;
-}
-
-static void perf_swcounter_ctx_event(struct perf_counter_context *ctx,
-				     enum perf_type_id type,
-				     u32 event, u64 nr, int nmi,
-				     struct perf_sample_data *data)
-{
-	struct perf_counter *counter;
-
-	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
-		return;
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(counter, &ctx->event_list, event_entry) {
-		if (perf_swcounter_match(counter, type, event, data->regs))
-			perf_swcounter_add(counter, nr, nmi, data);
-	}
-	rcu_read_unlock();
-}
-
-static int *perf_swcounter_recursion_context(struct perf_cpu_context *cpuctx)
-{
-	if (in_nmi())
-		return &cpuctx->recursion[3];
-
-	if (in_irq())
-		return &cpuctx->recursion[2];
-
-	if (in_softirq())
-		return &cpuctx->recursion[1];
-
-	return &cpuctx->recursion[0];
-}
-
-static void do_perf_swcounter_event(enum perf_type_id type, u32 event,
-				    u64 nr, int nmi,
-				    struct perf_sample_data *data)
-{
-	struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context);
-	int *recursion = perf_swcounter_recursion_context(cpuctx);
-	struct perf_counter_context *ctx;
-
-	if (*recursion)
-		goto out;
-
-	(*recursion)++;
-	barrier();
-
-	perf_swcounter_ctx_event(&cpuctx->ctx, type, event,
-				 nr, nmi, data);
-	rcu_read_lock();
-	/*
-	 * doesn't really matter which of the child contexts the
-	 * events ends up in.
-	 */
-	ctx = rcu_dereference(current->perf_counter_ctxp);
-	if (ctx)
-		perf_swcounter_ctx_event(ctx, type, event, nr, nmi, data);
-	rcu_read_unlock();
-
-	barrier();
-	(*recursion)--;
-
-out:
-	put_cpu_var(perf_cpu_context);
-}
-
-void __perf_swcounter_event(u32 event, u64 nr, int nmi,
-			    struct pt_regs *regs, u64 addr)
-{
-	struct perf_sample_data data = {
-		.regs = regs,
-		.addr = addr,
-	};
-
-	do_perf_swcounter_event(PERF_TYPE_SOFTWARE, event, nr, nmi, &data);
-}
-
-static void perf_swcounter_read(struct perf_counter *counter)
-{
-}
-
-static int perf_swcounter_enable(struct perf_counter *counter)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-
-	if (hwc->sample_period) {
-		hwc->last_period = hwc->sample_period;
-		perf_swcounter_set_period(counter);
-	}
-	return 0;
-}
-
-static void perf_swcounter_disable(struct perf_counter *counter)
-{
-}
-
-static const struct pmu perf_ops_generic = {
-	.enable		= perf_swcounter_enable,
-	.disable	= perf_swcounter_disable,
-	.read		= perf_swcounter_read,
-	.unthrottle	= perf_swcounter_unthrottle,
-};
-
-/*
- * hrtimer based swcounter callback
- */
-
-static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
-{
-	enum hrtimer_restart ret = HRTIMER_RESTART;
-	struct perf_sample_data data;
-	struct perf_counter *counter;
-	u64 period;
-
-	counter	= container_of(hrtimer, struct perf_counter, hw.hrtimer);
-	counter->pmu->read(counter);
-
-	data.addr = 0;
-	data.regs = get_irq_regs();
-	/*
-	 * In case we exclude kernel IPs or are somehow not in interrupt
-	 * context, provide the next best thing, the user IP.
-	 */
-	if ((counter->attr.exclude_kernel || !data.regs) &&
-			!counter->attr.exclude_user)
-		data.regs = task_pt_regs(current);
-
-	if (data.regs) {
-		if (perf_counter_overflow(counter, 0, &data))
-			ret = HRTIMER_NORESTART;
-	}
-
-	period = max_t(u64, 10000, counter->hw.sample_period);
-	hrtimer_forward_now(hrtimer, ns_to_ktime(period));
-
-	return ret;
-}
-
-/*
- * Software counter: cpu wall time clock
- */
-
-static void cpu_clock_perf_counter_update(struct perf_counter *counter)
-{
-	int cpu = raw_smp_processor_id();
-	s64 prev;
-	u64 now;
-
-	now = cpu_clock(cpu);
-	prev = atomic64_read(&counter->hw.prev_count);
-	atomic64_set(&counter->hw.prev_count, now);
-	atomic64_add(now - prev, &counter->count);
-}
-
-static int cpu_clock_perf_counter_enable(struct perf_counter *counter)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-	int cpu = raw_smp_processor_id();
-
-	atomic64_set(&hwc->prev_count, cpu_clock(cpu));
-	hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	hwc->hrtimer.function = perf_swcounter_hrtimer;
-	if (hwc->sample_period) {
-		u64 period = max_t(u64, 10000, hwc->sample_period);
-		__hrtimer_start_range_ns(&hwc->hrtimer,
-				ns_to_ktime(period), 0,
-				HRTIMER_MODE_REL, 0);
-	}
-
-	return 0;
-}
-
-static void cpu_clock_perf_counter_disable(struct perf_counter *counter)
-{
-	if (counter->hw.sample_period)
-		hrtimer_cancel(&counter->hw.hrtimer);
-	cpu_clock_perf_counter_update(counter);
-}
-
-static void cpu_clock_perf_counter_read(struct perf_counter *counter)
-{
-	cpu_clock_perf_counter_update(counter);
-}
-
-static const struct pmu perf_ops_cpu_clock = {
-	.enable		= cpu_clock_perf_counter_enable,
-	.disable	= cpu_clock_perf_counter_disable,
-	.read		= cpu_clock_perf_counter_read,
-};
-
-/*
- * Software counter: task time clock
- */
-
-static void task_clock_perf_counter_update(struct perf_counter *counter, u64 now)
-{
-	u64 prev;
-	s64 delta;
-
-	prev = atomic64_xchg(&counter->hw.prev_count, now);
-	delta = now - prev;
-	atomic64_add(delta, &counter->count);
-}
-
-static int task_clock_perf_counter_enable(struct perf_counter *counter)
-{
-	struct hw_perf_counter *hwc = &counter->hw;
-	u64 now;
-
-	now = counter->ctx->time;
-
-	atomic64_set(&hwc->prev_count, now);
-	hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	hwc->hrtimer.function = perf_swcounter_hrtimer;
-	if (hwc->sample_period) {
-		u64 period = max_t(u64, 10000, hwc->sample_period);
-		__hrtimer_start_range_ns(&hwc->hrtimer,
-				ns_to_ktime(period), 0,
-				HRTIMER_MODE_REL, 0);
-	}
-
-	return 0;
-}
-
-static void task_clock_perf_counter_disable(struct perf_counter *counter)
-{
-	if (counter->hw.sample_period)
-		hrtimer_cancel(&counter->hw.hrtimer);
-	task_clock_perf_counter_update(counter, counter->ctx->time);
-
-}
-
-static void task_clock_perf_counter_read(struct perf_counter *counter)
-{
-	u64 time;
-
-	if (!in_nmi()) {
-		update_context_time(counter->ctx);
-		time = counter->ctx->time;
-	} else {
-		u64 now = perf_clock();
-		u64 delta = now - counter->ctx->timestamp;
-		time = counter->ctx->time + delta;
-	}
-
-	task_clock_perf_counter_update(counter, time);
-}
-
-static const struct pmu perf_ops_task_clock = {
-	.enable		= task_clock_perf_counter_enable,
-	.disable	= task_clock_perf_counter_disable,
-	.read		= task_clock_perf_counter_read,
-};
-
-#ifdef CONFIG_EVENT_PROFILE
-void perf_tpcounter_event(int event_id, u64 addr, u64 count, void *record,
-			  int entry_size)
-{
-	struct perf_raw_record raw = {
-		.size = entry_size,
-		.data = record,
-	};
-
-	struct perf_sample_data data = {
-		.regs = get_irq_regs(),
-		.addr = addr,
-		.raw = &raw,
-	};
-
-	if (!data.regs)
-		data.regs = task_pt_regs(current);
-
-	do_perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, count, 1, &data);
-}
-EXPORT_SYMBOL_GPL(perf_tpcounter_event);
-
-extern int ftrace_profile_enable(int);
-extern void ftrace_profile_disable(int);
-
-static void tp_perf_counter_destroy(struct perf_counter *counter)
-{
-	ftrace_profile_disable(counter->attr.config);
-}
-
-static const struct pmu *tp_perf_counter_init(struct perf_counter *counter)
-{
-	/*
-	 * Raw tracepoint data is a severe data leak, only allow root to
-	 * have these.
-	 */
-	if ((counter->attr.sample_type & PERF_SAMPLE_RAW) &&
-			perf_paranoid_tracepoint_raw() &&
-			!capable(CAP_SYS_ADMIN))
-		return ERR_PTR(-EPERM);
-
-	if (ftrace_profile_enable(counter->attr.config))
-		return NULL;
-
-	counter->destroy = tp_perf_counter_destroy;
-
-	return &perf_ops_generic;
-}
-#else
-static const struct pmu *tp_perf_counter_init(struct perf_counter *counter)
-{
-	return NULL;
-}
-#endif
-
-atomic_t perf_swcounter_enabled[PERF_COUNT_SW_MAX];
-
-static void sw_perf_counter_destroy(struct perf_counter *counter)
-{
-	u64 event = counter->attr.config;
-
-	WARN_ON(counter->parent);
-
-	atomic_dec(&perf_swcounter_enabled[event]);
-}
-
-static const struct pmu *sw_perf_counter_init(struct perf_counter *counter)
-{
-	const struct pmu *pmu = NULL;
-	u64 event = counter->attr.config;
-
-	/*
-	 * Software counters (currently) can't in general distinguish
-	 * between user, kernel and hypervisor events.
-	 * However, context switches and cpu migrations are considered
-	 * to be kernel events, and page faults are never hypervisor
-	 * events.
-	 */
-	switch (event) {
-	case PERF_COUNT_SW_CPU_CLOCK:
-		pmu = &perf_ops_cpu_clock;
-
-		break;
-	case PERF_COUNT_SW_TASK_CLOCK:
-		/*
-		 * If the user instantiates this as a per-cpu counter,
-		 * use the cpu_clock counter instead.
-		 */
-		if (counter->ctx->task)
-			pmu = &perf_ops_task_clock;
-		else
-			pmu = &perf_ops_cpu_clock;
-
-		break;
-	case PERF_COUNT_SW_PAGE_FAULTS:
-	case PERF_COUNT_SW_PAGE_FAULTS_MIN:
-	case PERF_COUNT_SW_PAGE_FAULTS_MAJ:
-	case PERF_COUNT_SW_CONTEXT_SWITCHES:
-	case PERF_COUNT_SW_CPU_MIGRATIONS:
-		if (!counter->parent) {
-			atomic_inc(&perf_swcounter_enabled[event]);
-			counter->destroy = sw_perf_counter_destroy;
-		}
-		pmu = &perf_ops_generic;
-		break;
-	}
-
-	return pmu;
-}
-
-/*
- * Allocate and initialize a counter structure
- */
-static struct perf_counter *
-perf_counter_alloc(struct perf_counter_attr *attr,
-		   int cpu,
-		   struct perf_counter_context *ctx,
-		   struct perf_counter *group_leader,
-		   struct perf_counter *parent_counter,
-		   gfp_t gfpflags)
-{
-	const struct pmu *pmu;
-	struct perf_counter *counter;
-	struct hw_perf_counter *hwc;
-	long err;
-
-	counter = kzalloc(sizeof(*counter), gfpflags);
-	if (!counter)
-		return ERR_PTR(-ENOMEM);
-
-	/*
-	 * Single counters are their own group leaders, with an
-	 * empty sibling list:
-	 */
-	if (!group_leader)
-		group_leader = counter;
-
-	mutex_init(&counter->child_mutex);
-	INIT_LIST_HEAD(&counter->child_list);
-
-	INIT_LIST_HEAD(&counter->list_entry);
-	INIT_LIST_HEAD(&counter->event_entry);
-	INIT_LIST_HEAD(&counter->sibling_list);
-	init_waitqueue_head(&counter->waitq);
-
-	mutex_init(&counter->mmap_mutex);
-
-	counter->cpu		= cpu;
-	counter->attr		= *attr;
-	counter->group_leader	= group_leader;
-	counter->pmu		= NULL;
-	counter->ctx		= ctx;
-	counter->oncpu		= -1;
-
-	counter->parent		= parent_counter;
-
-	counter->ns		= get_pid_ns(current->nsproxy->pid_ns);
-	counter->id		= atomic64_inc_return(&perf_counter_id);
-
-	counter->state		= PERF_COUNTER_STATE_INACTIVE;
-
-	if (attr->disabled)
-		counter->state = PERF_COUNTER_STATE_OFF;
-
-	pmu = NULL;
-
-	hwc = &counter->hw;
-	hwc->sample_period = attr->sample_period;
-	if (attr->freq && attr->sample_freq)
-		hwc->sample_period = 1;
-	hwc->last_period = hwc->sample_period;
-
-	atomic64_set(&hwc->period_left, hwc->sample_period);
-
-	/*
-	 * we currently do not support PERF_FORMAT_GROUP on inherited counters
-	 */
-	if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
-		goto done;
-
-	switch (attr->type) {
-	case PERF_TYPE_RAW:
-	case PERF_TYPE_HARDWARE:
-	case PERF_TYPE_HW_CACHE:
-		pmu = hw_perf_counter_init(counter);
-		break;
-
-	case PERF_TYPE_SOFTWARE:
-		pmu = sw_perf_counter_init(counter);
-		break;
-
-	case PERF_TYPE_TRACEPOINT:
-		pmu = tp_perf_counter_init(counter);
-		break;
-
-	default:
-		break;
-	}
-done:
-	err = 0;
-	if (!pmu)
-		err = -EINVAL;
-	else if (IS_ERR(pmu))
-		err = PTR_ERR(pmu);
-
-	if (err) {
-		if (counter->ns)
-			put_pid_ns(counter->ns);
-		kfree(counter);
-		return ERR_PTR(err);
-	}
-
-	counter->pmu = pmu;
-
-	if (!counter->parent) {
-		atomic_inc(&nr_counters);
-		if (counter->attr.mmap)
-			atomic_inc(&nr_mmap_counters);
-		if (counter->attr.comm)
-			atomic_inc(&nr_comm_counters);
-		if (counter->attr.task)
-			atomic_inc(&nr_task_counters);
-	}
-
-	return counter;
-}
-
-static int perf_copy_attr(struct perf_counter_attr __user *uattr,
-			  struct perf_counter_attr *attr)
-{
-	int ret;
-	u32 size;
-
-	if (!access_ok(VERIFY_WRITE, uattr, PERF_ATTR_SIZE_VER0))
-		return -EFAULT;
-
-	/*
-	 * zero the full structure, so that a short copy will be nice.
-	 */
-	memset(attr, 0, sizeof(*attr));
-
-	ret = get_user(size, &uattr->size);
-	if (ret)
-		return ret;
-
-	if (size > PAGE_SIZE)	/* silly large */
-		goto err_size;
-
-	if (!size)		/* abi compat */
-		size = PERF_ATTR_SIZE_VER0;
-
-	if (size < PERF_ATTR_SIZE_VER0)
-		goto err_size;
-
-	/*
-	 * If we're handed a bigger struct than we know of,
-	 * ensure all the unknown bits are 0.
-	 */
-	if (size > sizeof(*attr)) {
-		unsigned long val;
-		unsigned long __user *addr;
-		unsigned long __user *end;
-
-		addr = PTR_ALIGN((void __user *)uattr + sizeof(*attr),
-				sizeof(unsigned long));
-		end  = PTR_ALIGN((void __user *)uattr + size,
-				sizeof(unsigned long));
-
-		for (; addr < end; addr += sizeof(unsigned long)) {
-			ret = get_user(val, addr);
-			if (ret)
-				return ret;
-			if (val)
-				goto err_size;
-		}
-	}
-
-	ret = copy_from_user(attr, uattr, size);
-	if (ret)
-		return -EFAULT;
-
-	/*
-	 * If the type exists, the corresponding creation will verify
-	 * the attr->config.
-	 */
-	if (attr->type >= PERF_TYPE_MAX)
-		return -EINVAL;
-
-	if (attr->__reserved_1 || attr->__reserved_2 || attr->__reserved_3)
-		return -EINVAL;
-
-	if (attr->sample_type & ~(PERF_SAMPLE_MAX-1))
-		return -EINVAL;
-
-	if (attr->read_format & ~(PERF_FORMAT_MAX-1))
-		return -EINVAL;
-
-out:
-	return ret;
-
-err_size:
-	put_user(sizeof(*attr), &uattr->size);
-	ret = -E2BIG;
-	goto out;
-}
-
-int perf_counter_set_output(struct perf_counter *counter, int output_fd)
-{
-	struct perf_counter *output_counter = NULL;
-	struct file *output_file = NULL;
-	struct perf_counter *old_output;
-	int fput_needed = 0;
-	int ret = -EINVAL;
-
-	if (!output_fd)
-		goto set;
-
-	output_file = fget_light(output_fd, &fput_needed);
-	if (!output_file)
-		return -EBADF;
-
-	if (output_file->f_op != &perf_fops)
-		goto out;
-
-	output_counter = output_file->private_data;
-
-	/* Don't chain output fds */
-	if (output_counter->output)
-		goto out;
-
-	/* Don't set an output fd when we already have an output channel */
-	if (counter->data)
-		goto out;
-
-	atomic_long_inc(&output_file->f_count);
-
-set:
-	mutex_lock(&counter->mmap_mutex);
-	old_output = counter->output;
-	rcu_assign_pointer(counter->output, output_counter);
-	mutex_unlock(&counter->mmap_mutex);
-
-	if (old_output) {
-		/*
-		 * we need to make sure no existing perf_output_*()
-		 * is still referencing this counter.
-		 */
-		synchronize_rcu();
-		fput(old_output->filp);
-	}
-
-	ret = 0;
-out:
-	fput_light(output_file, fput_needed);
-	return ret;
-}
-
-/**
- * sys_perf_counter_open - open a performance counter, associate it to a task/cpu
- *
- * @attr_uptr:	event type attributes for monitoring/sampling
- * @pid:		target pid
- * @cpu:		target cpu
- * @group_fd:		group leader counter fd
- */
-SYSCALL_DEFINE5(perf_counter_open,
-		struct perf_counter_attr __user *, attr_uptr,
-		pid_t, pid, int, cpu, int, group_fd, unsigned long, flags)
-{
-	struct perf_counter *counter, *group_leader;
-	struct perf_counter_attr attr;
-	struct perf_counter_context *ctx;
-	struct file *counter_file = NULL;
-	struct file *group_file = NULL;
-	int fput_needed = 0;
-	int fput_needed2 = 0;
-	int err;
-
-	/* for future expandability... */
-	if (flags & ~(PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT))
-		return -EINVAL;
-
-	err = perf_copy_attr(attr_uptr, &attr);
-	if (err)
-		return err;
-
-	if (!attr.exclude_kernel) {
-		if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
-			return -EACCES;
-	}
-
-	if (attr.freq) {
-		if (attr.sample_freq > sysctl_perf_counter_sample_rate)
-			return -EINVAL;
-	}
-
-	/*
-	 * Get the target context (task or percpu):
-	 */
-	ctx = find_get_context(pid, cpu);
-	if (IS_ERR(ctx))
-		return PTR_ERR(ctx);
-
-	/*
-	 * Look up the group leader (we will attach this counter to it):
-	 */
-	group_leader = NULL;
-	if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) {
-		err = -EINVAL;
-		group_file = fget_light(group_fd, &fput_needed);
-		if (!group_file)
-			goto err_put_context;
-		if (group_file->f_op != &perf_fops)
-			goto err_put_context;
-
-		group_leader = group_file->private_data;
-		/*
-		 * Do not allow a recursive hierarchy (this new sibling
-		 * becoming part of another group-sibling):
-		 */
-		if (group_leader->group_leader != group_leader)
-			goto err_put_context;
-		/*
-		 * Do not allow to attach to a group in a different
-		 * task or CPU context:
-		 */
-		if (group_leader->ctx != ctx)
-			goto err_put_context;
-		/*
-		 * Only a group leader can be exclusive or pinned
-		 */
-		if (attr.exclusive || attr.pinned)
-			goto err_put_context;
-	}
-
-	counter = perf_counter_alloc(&attr, cpu, ctx, group_leader,
-				     NULL, GFP_KERNEL);
-	err = PTR_ERR(counter);
-	if (IS_ERR(counter))
-		goto err_put_context;
-
-	err = anon_inode_getfd("[perf_counter]", &perf_fops, counter, 0);
-	if (err < 0)
-		goto err_free_put_context;
-
-	counter_file = fget_light(err, &fput_needed2);
-	if (!counter_file)
-		goto err_free_put_context;
-
-	if (flags & PERF_FLAG_FD_OUTPUT) {
-		err = perf_counter_set_output(counter, group_fd);
-		if (err)
-			goto err_fput_free_put_context;
-	}
-
-	counter->filp = counter_file;
-	WARN_ON_ONCE(ctx->parent_ctx);
-	mutex_lock(&ctx->mutex);
-	perf_install_in_context(ctx, counter, cpu);
-	++ctx->generation;
-	mutex_unlock(&ctx->mutex);
-
-	counter->owner = current;
-	get_task_struct(current);
-	mutex_lock(&current->perf_counter_mutex);
-	list_add_tail(&counter->owner_entry, &current->perf_counter_list);
-	mutex_unlock(&current->perf_counter_mutex);
-
-err_fput_free_put_context:
-	fput_light(counter_file, fput_needed2);
-
-err_free_put_context:
-	if (err < 0)
-		kfree(counter);
-
-err_put_context:
-	if (err < 0)
-		put_ctx(ctx);
-
-	fput_light(group_file, fput_needed);
-
-	return err;
-}
-
-/*
- * inherit a counter from parent task to child task:
- */
-static struct perf_counter *
-inherit_counter(struct perf_counter *parent_counter,
-	      struct task_struct *parent,
-	      struct perf_counter_context *parent_ctx,
-	      struct task_struct *child,
-	      struct perf_counter *group_leader,
-	      struct perf_counter_context *child_ctx)
-{
-	struct perf_counter *child_counter;
-
-	/*
-	 * Instead of creating recursive hierarchies of counters,
-	 * we link inherited counters back to the original parent,
-	 * which has a filp for sure, which we use as the reference
-	 * count:
-	 */
-	if (parent_counter->parent)
-		parent_counter = parent_counter->parent;
-
-	child_counter = perf_counter_alloc(&parent_counter->attr,
-					   parent_counter->cpu, child_ctx,
-					   group_leader, parent_counter,
-					   GFP_KERNEL);
-	if (IS_ERR(child_counter))
-		return child_counter;
-	get_ctx(child_ctx);
-
-	/*
-	 * Make the child state follow the state of the parent counter,
-	 * not its attr.disabled bit.  We hold the parent's mutex,
-	 * so we won't race with perf_counter_{en, dis}able_family.
-	 */
-	if (parent_counter->state >= PERF_COUNTER_STATE_INACTIVE)
-		child_counter->state = PERF_COUNTER_STATE_INACTIVE;
-	else
-		child_counter->state = PERF_COUNTER_STATE_OFF;
-
-	if (parent_counter->attr.freq)
-		child_counter->hw.sample_period = parent_counter->hw.sample_period;
-
-	/*
-	 * Link it up in the child's context:
-	 */
-	add_counter_to_ctx(child_counter, child_ctx);
-
-	/*
-	 * Get a reference to the parent filp - we will fput it
-	 * when the child counter exits. This is safe to do because
-	 * we are in the parent and we know that the filp still
-	 * exists and has a nonzero count:
-	 */
-	atomic_long_inc(&parent_counter->filp->f_count);
-
-	/*
-	 * Link this into the parent counter's child list
-	 */
-	WARN_ON_ONCE(parent_counter->ctx->parent_ctx);
-	mutex_lock(&parent_counter->child_mutex);
-	list_add_tail(&child_counter->child_list, &parent_counter->child_list);
-	mutex_unlock(&parent_counter->child_mutex);
-
-	return child_counter;
-}
-
-static int inherit_group(struct perf_counter *parent_counter,
-	      struct task_struct *parent,
-	      struct perf_counter_context *parent_ctx,
-	      struct task_struct *child,
-	      struct perf_counter_context *child_ctx)
-{
-	struct perf_counter *leader;
-	struct perf_counter *sub;
-	struct perf_counter *child_ctr;
-
-	leader = inherit_counter(parent_counter, parent, parent_ctx,
-				 child, NULL, child_ctx);
-	if (IS_ERR(leader))
-		return PTR_ERR(leader);
-	list_for_each_entry(sub, &parent_counter->sibling_list, list_entry) {
-		child_ctr = inherit_counter(sub, parent, parent_ctx,
-					    child, leader, child_ctx);
-		if (IS_ERR(child_ctr))
-			return PTR_ERR(child_ctr);
-	}
-	return 0;
-}
-
-static void sync_child_counter(struct perf_counter *child_counter,
-			       struct task_struct *child)
-{
-	struct perf_counter *parent_counter = child_counter->parent;
-	u64 child_val;
-
-	if (child_counter->attr.inherit_stat)
-		perf_counter_read_event(child_counter, child);
-
-	child_val = atomic64_read(&child_counter->count);
-
-	/*
-	 * Add back the child's count to the parent's count:
-	 */
-	atomic64_add(child_val, &parent_counter->count);
-	atomic64_add(child_counter->total_time_enabled,
-		     &parent_counter->child_total_time_enabled);
-	atomic64_add(child_counter->total_time_running,
-		     &parent_counter->child_total_time_running);
-
-	/*
-	 * Remove this counter from the parent's list
-	 */
-	WARN_ON_ONCE(parent_counter->ctx->parent_ctx);
-	mutex_lock(&parent_counter->child_mutex);
-	list_del_init(&child_counter->child_list);
-	mutex_unlock(&parent_counter->child_mutex);
-
-	/*
-	 * Release the parent counter, if this was the last
-	 * reference to it.
-	 */
-	fput(parent_counter->filp);
-}
-
-static void
-__perf_counter_exit_task(struct perf_counter *child_counter,
-			 struct perf_counter_context *child_ctx,
-			 struct task_struct *child)
-{
-	struct perf_counter *parent_counter;
-
-	update_counter_times(child_counter);
-	perf_counter_remove_from_context(child_counter);
-
-	parent_counter = child_counter->parent;
-	/*
-	 * It can happen that parent exits first, and has counters
-	 * that are still around due to the child reference. These
-	 * counters need to be zapped - but otherwise linger.
-	 */
-	if (parent_counter) {
-		sync_child_counter(child_counter, child);
-		free_counter(child_counter);
-	}
-}
-
-/*
- * When a child task exits, feed back counter values to parent counters.
- */
-void perf_counter_exit_task(struct task_struct *child)
-{
-	struct perf_counter *child_counter, *tmp;
-	struct perf_counter_context *child_ctx;
-	unsigned long flags;
-
-	if (likely(!child->perf_counter_ctxp)) {
-		perf_counter_task(child, NULL, 0);
-		return;
-	}
-
-	local_irq_save(flags);
-	/*
-	 * We can't reschedule here because interrupts are disabled,
-	 * and either child is current or it is a task that can't be
-	 * scheduled, so we are now safe from rescheduling changing
-	 * our context.
-	 */
-	child_ctx = child->perf_counter_ctxp;
-	__perf_counter_task_sched_out(child_ctx);
-
-	/*
-	 * Take the context lock here so that if find_get_context is
-	 * reading child->perf_counter_ctxp, we wait until it has
-	 * incremented the context's refcount before we do put_ctx below.
-	 */
-	spin_lock(&child_ctx->lock);
-	child->perf_counter_ctxp = NULL;
-	/*
-	 * If this context is a clone; unclone it so it can't get
-	 * swapped to another process while we're removing all
-	 * the counters from it.
-	 */
-	unclone_ctx(child_ctx);
-	spin_unlock_irqrestore(&child_ctx->lock, flags);
-
-	/*
-	 * Report the task dead after unscheduling the counters so that we
-	 * won't get any samples after PERF_EVENT_EXIT. We can however still
-	 * get a few PERF_EVENT_READ events.
-	 */
-	perf_counter_task(child, child_ctx, 0);
-
-	/*
-	 * We can recurse on the same lock type through:
-	 *
-	 *   __perf_counter_exit_task()
-	 *     sync_child_counter()
-	 *       fput(parent_counter->filp)
-	 *         perf_release()
-	 *           mutex_lock(&ctx->mutex)
-	 *
-	 * But since its the parent context it won't be the same instance.
-	 */
-	mutex_lock_nested(&child_ctx->mutex, SINGLE_DEPTH_NESTING);
-
-again:
-	list_for_each_entry_safe(child_counter, tmp, &child_ctx->counter_list,
-				 list_entry)
-		__perf_counter_exit_task(child_counter, child_ctx, child);
-
-	/*
-	 * If the last counter was a group counter, it will have appended all
-	 * its siblings to the list, but we obtained 'tmp' before that which
-	 * will still point to the list head terminating the iteration.
-	 */
-	if (!list_empty(&child_ctx->counter_list))
-		goto again;
-
-	mutex_unlock(&child_ctx->mutex);
-
-	put_ctx(child_ctx);
-}
-
-/*
- * free an unexposed, unused context as created by inheritance by
- * init_task below, used by fork() in case of fail.
- */
-void perf_counter_free_task(struct task_struct *task)
-{
-	struct perf_counter_context *ctx = task->perf_counter_ctxp;
-	struct perf_counter *counter, *tmp;
-
-	if (!ctx)
-		return;
-
-	mutex_lock(&ctx->mutex);
-again:
-	list_for_each_entry_safe(counter, tmp, &ctx->counter_list, list_entry) {
-		struct perf_counter *parent = counter->parent;
-
-		if (WARN_ON_ONCE(!parent))
-			continue;
-
-		mutex_lock(&parent->child_mutex);
-		list_del_init(&counter->child_list);
-		mutex_unlock(&parent->child_mutex);
-
-		fput(parent->filp);
-
-		list_del_counter(counter, ctx);
-		free_counter(counter);
-	}
-
-	if (!list_empty(&ctx->counter_list))
-		goto again;
-
-	mutex_unlock(&ctx->mutex);
-
-	put_ctx(ctx);
-}
-
-/*
- * Initialize the perf_counter context in task_struct
- */
-int perf_counter_init_task(struct task_struct *child)
-{
-	struct perf_counter_context *child_ctx, *parent_ctx;
-	struct perf_counter_context *cloned_ctx;
-	struct perf_counter *counter;
-	struct task_struct *parent = current;
-	int inherited_all = 1;
-	int ret = 0;
-
-	child->perf_counter_ctxp = NULL;
-
-	mutex_init(&child->perf_counter_mutex);
-	INIT_LIST_HEAD(&child->perf_counter_list);
-
-	if (likely(!parent->perf_counter_ctxp))
-		return 0;
-
-	/*
-	 * This is executed from the parent task context, so inherit
-	 * counters that have been marked for cloning.
-	 * First allocate and initialize a context for the child.
-	 */
-
-	child_ctx = kmalloc(sizeof(struct perf_counter_context), GFP_KERNEL);
-	if (!child_ctx)
-		return -ENOMEM;
-
-	__perf_counter_init_context(child_ctx, child);
-	child->perf_counter_ctxp = child_ctx;
-	get_task_struct(child);
-
-	/*
-	 * If the parent's context is a clone, pin it so it won't get
-	 * swapped under us.
-	 */
-	parent_ctx = perf_pin_task_context(parent);
-
-	/*
-	 * No need to check if parent_ctx != NULL here; since we saw
-	 * it non-NULL earlier, the only reason for it to become NULL
-	 * is if we exit, and since we're currently in the middle of
-	 * a fork we can't be exiting at the same time.
-	 */
-
-	/*
-	 * Lock the parent list. No need to lock the child - not PID
-	 * hashed yet and not running, so nobody can access it.
-	 */
-	mutex_lock(&parent_ctx->mutex);
-
-	/*
-	 * We dont have to disable NMIs - we are only looking at
-	 * the list, not manipulating it:
-	 */
-	list_for_each_entry_rcu(counter, &parent_ctx->event_list, event_entry) {
-		if (counter != counter->group_leader)
-			continue;
-
-		if (!counter->attr.inherit) {
-			inherited_all = 0;
-			continue;
-		}
-
-		ret = inherit_group(counter, parent, parent_ctx,
-					     child, child_ctx);
-		if (ret) {
-			inherited_all = 0;
-			break;
-		}
-	}
-
-	if (inherited_all) {
-		/*
-		 * Mark the child context as a clone of the parent
-		 * context, or of whatever the parent is a clone of.
-		 * Note that if the parent is a clone, it could get
-		 * uncloned at any point, but that doesn't matter
-		 * because the list of counters and the generation
-		 * count can't have changed since we took the mutex.
-		 */
-		cloned_ctx = rcu_dereference(parent_ctx->parent_ctx);
-		if (cloned_ctx) {
-			child_ctx->parent_ctx = cloned_ctx;
-			child_ctx->parent_gen = parent_ctx->parent_gen;
-		} else {
-			child_ctx->parent_ctx = parent_ctx;
-			child_ctx->parent_gen = parent_ctx->generation;
-		}
-		get_ctx(child_ctx->parent_ctx);
-	}
-
-	mutex_unlock(&parent_ctx->mutex);
-
-	perf_unpin_context(parent_ctx);
-
-	return ret;
-}
-
-static void __cpuinit perf_counter_init_cpu(int cpu)
-{
-	struct perf_cpu_context *cpuctx;
-
-	cpuctx = &per_cpu(perf_cpu_context, cpu);
-	__perf_counter_init_context(&cpuctx->ctx, NULL);
-
-	spin_lock(&perf_resource_lock);
-	cpuctx->max_pertask = perf_max_counters - perf_reserved_percpu;
-	spin_unlock(&perf_resource_lock);
-
-	hw_perf_counter_setup(cpu);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void __perf_counter_exit_cpu(void *info)
-{
-	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
-	struct perf_counter_context *ctx = &cpuctx->ctx;
-	struct perf_counter *counter, *tmp;
-
-	list_for_each_entry_safe(counter, tmp, &ctx->counter_list, list_entry)
-		__perf_counter_remove_from_context(counter);
-}
-static void perf_counter_exit_cpu(int cpu)
-{
-	struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
-	struct perf_counter_context *ctx = &cpuctx->ctx;
-
-	mutex_lock(&ctx->mutex);
-	smp_call_function_single(cpu, __perf_counter_exit_cpu, NULL, 1);
-	mutex_unlock(&ctx->mutex);
-}
-#else
-static inline void perf_counter_exit_cpu(int cpu) { }
-#endif
-
-static int __cpuinit
-perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (long)hcpu;
-
-	switch (action) {
-
-	case CPU_UP_PREPARE:
-	case CPU_UP_PREPARE_FROZEN:
-		perf_counter_init_cpu(cpu);
-		break;
-
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
-		hw_perf_counter_setup_online(cpu);
-		break;
-
-	case CPU_DOWN_PREPARE:
-	case CPU_DOWN_PREPARE_FROZEN:
-		perf_counter_exit_cpu(cpu);
-		break;
-
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-/*
- * This has to have a higher priority than migration_notifier in sched.c.
- */
-static struct notifier_block __cpuinitdata perf_cpu_nb = {
-	.notifier_call		= perf_cpu_notify,
-	.priority		= 20,
-};
-
-void __init perf_counter_init(void)
-{
-	perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
-			(void *)(long)smp_processor_id());
-	perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
-			(void *)(long)smp_processor_id());
-	register_cpu_notifier(&perf_cpu_nb);
-}
-
-static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf)
-{
-	return sprintf(buf, "%d\n", perf_reserved_percpu);
-}
-
-static ssize_t
-perf_set_reserve_percpu(struct sysdev_class *class,
-			const char *buf,
-			size_t count)
-{
-	struct perf_cpu_context *cpuctx;
-	unsigned long val;
-	int err, cpu, mpt;
-
-	err = strict_strtoul(buf, 10, &val);
-	if (err)
-		return err;
-	if (val > perf_max_counters)
-		return -EINVAL;
-
-	spin_lock(&perf_resource_lock);
-	perf_reserved_percpu = val;
-	for_each_online_cpu(cpu) {
-		cpuctx = &per_cpu(perf_cpu_context, cpu);
-		spin_lock_irq(&cpuctx->ctx.lock);
-		mpt = min(perf_max_counters - cpuctx->ctx.nr_counters,
-			  perf_max_counters - perf_reserved_percpu);
-		cpuctx->max_pertask = mpt;
-		spin_unlock_irq(&cpuctx->ctx.lock);
-	}
-	spin_unlock(&perf_resource_lock);
-
-	return count;
-}
-
-static ssize_t perf_show_overcommit(struct sysdev_class *class, char *buf)
-{
-	return sprintf(buf, "%d\n", perf_overcommit);
-}
-
-static ssize_t
-perf_set_overcommit(struct sysdev_class *class, const char *buf, size_t count)
-{
-	unsigned long val;
-	int err;
-
-	err = strict_strtoul(buf, 10, &val);
-	if (err)
-		return err;
-	if (val > 1)
-		return -EINVAL;
-
-	spin_lock(&perf_resource_lock);
-	perf_overcommit = val;
-	spin_unlock(&perf_resource_lock);
-
-	return count;
-}
-
-static SYSDEV_CLASS_ATTR(
-				reserve_percpu,
-				0644,
-				perf_show_reserve_percpu,
-				perf_set_reserve_percpu
-			);
-
-static SYSDEV_CLASS_ATTR(
-				overcommit,
-				0644,
-				perf_show_overcommit,
-				perf_set_overcommit
-			);
-
-static struct attribute *perfclass_attrs[] = {
-	&attr_reserve_percpu.attr,
-	&attr_overcommit.attr,
-	NULL
-};
-
-static struct attribute_group perfclass_attr_group = {
-	.attrs			= perfclass_attrs,
-	.name			= "perf_counters",
-};
-
-static int __init perf_counter_sysfs_init(void)
-{
-	return sysfs_create_group(&cpu_sysdev_class.kset.kobj,
-				  &perfclass_attr_group);
-}
-device_initcall(perf_counter_sysfs_init);
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
new file mode 100644
index 0000000..76ac4db
--- /dev/null
+++ b/kernel/perf_event.c
@@ -0,0 +1,5000 @@
+/*
+ * Performance events core code:
+ *
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright  ©  2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
+ *
+ * For licensing details see kernel-base/COPYING
+ */
+
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/file.h>
+#include <linux/poll.h>
+#include <linux/sysfs.h>
+#include <linux/dcache.h>
+#include <linux/percpu.h>
+#include <linux/ptrace.h>
+#include <linux/vmstat.h>
+#include <linux/hardirq.h>
+#include <linux/rculist.h>
+#include <linux/uaccess.h>
+#include <linux/syscalls.h>
+#include <linux/anon_inodes.h>
+#include <linux/kernel_stat.h>
+#include <linux/perf_event.h>
+
+#include <asm/irq_regs.h>
+
+/*
+ * Each CPU has a list of per CPU events:
+ */
+DEFINE_PER_CPU(struct perf_cpu_context, perf_cpu_context);
+
+int perf_max_events __read_mostly = 1;
+static int perf_reserved_percpu __read_mostly;
+static int perf_overcommit __read_mostly = 1;
+
+static atomic_t nr_events __read_mostly;
+static atomic_t nr_mmap_events __read_mostly;
+static atomic_t nr_comm_events __read_mostly;
+static atomic_t nr_task_events __read_mostly;
+
+/*
+ * perf event paranoia level:
+ *  -1 - not paranoid at all
+ *   0 - disallow raw tracepoint access for unpriv
+ *   1 - disallow cpu events for unpriv
+ *   2 - disallow kernel profiling for unpriv
+ */
+int sysctl_perf_event_paranoid __read_mostly = 1;
+
+static inline bool perf_paranoid_tracepoint_raw(void)
+{
+	return sysctl_perf_event_paranoid > -1;
+}
+
+static inline bool perf_paranoid_cpu(void)
+{
+	return sysctl_perf_event_paranoid > 0;
+}
+
+static inline bool perf_paranoid_kernel(void)
+{
+	return sysctl_perf_event_paranoid > 1;
+}
+
+int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */
+
+/*
+ * max perf event sample rate
+ */
+int sysctl_perf_event_sample_rate __read_mostly = 100000;
+
+static atomic64_t perf_event_id;
+
+/*
+ * Lock for (sysadmin-configurable) event reservations:
+ */
+static DEFINE_SPINLOCK(perf_resource_lock);
+
+/*
+ * Architecture provided APIs - weak aliases:
+ */
+extern __weak const struct pmu *hw_perf_event_init(struct perf_event *event)
+{
+	return NULL;
+}
+
+void __weak hw_perf_disable(void)		{ barrier(); }
+void __weak hw_perf_enable(void)		{ barrier(); }
+
+void __weak hw_perf_event_setup(int cpu)	{ barrier(); }
+void __weak hw_perf_event_setup_online(int cpu)	{ barrier(); }
+
+int __weak
+hw_perf_group_sched_in(struct perf_event *group_leader,
+	       struct perf_cpu_context *cpuctx,
+	       struct perf_event_context *ctx, int cpu)
+{
+	return 0;
+}
+
+void __weak perf_event_print_debug(void)	{ }
+
+static DEFINE_PER_CPU(int, perf_disable_count);
+
+void __perf_disable(void)
+{
+	__get_cpu_var(perf_disable_count)++;
+}
+
+bool __perf_enable(void)
+{
+	return !--__get_cpu_var(perf_disable_count);
+}
+
+void perf_disable(void)
+{
+	__perf_disable();
+	hw_perf_disable();
+}
+
+void perf_enable(void)
+{
+	if (__perf_enable())
+		hw_perf_enable();
+}
+
+static void get_ctx(struct perf_event_context *ctx)
+{
+	WARN_ON(!atomic_inc_not_zero(&ctx->refcount));
+}
+
+static void free_ctx(struct rcu_head *head)
+{
+	struct perf_event_context *ctx;
+
+	ctx = container_of(head, struct perf_event_context, rcu_head);
+	kfree(ctx);
+}
+
+static void put_ctx(struct perf_event_context *ctx)
+{
+	if (atomic_dec_and_test(&ctx->refcount)) {
+		if (ctx->parent_ctx)
+			put_ctx(ctx->parent_ctx);
+		if (ctx->task)
+			put_task_struct(ctx->task);
+		call_rcu(&ctx->rcu_head, free_ctx);
+	}
+}
+
+static void unclone_ctx(struct perf_event_context *ctx)
+{
+	if (ctx->parent_ctx) {
+		put_ctx(ctx->parent_ctx);
+		ctx->parent_ctx = NULL;
+	}
+}
+
+/*
+ * If we inherit events we want to return the parent event id
+ * to userspace.
+ */
+static u64 primary_event_id(struct perf_event *event)
+{
+	u64 id = event->id;
+
+	if (event->parent)
+		id = event->parent->id;
+
+	return id;
+}
+
+/*
+ * Get the perf_event_context for a task and lock it.
+ * This has to cope with with the fact that until it is locked,
+ * the context could get moved to another task.
+ */
+static struct perf_event_context *
+perf_lock_task_context(struct task_struct *task, unsigned long *flags)
+{
+	struct perf_event_context *ctx;
+
+	rcu_read_lock();
+ retry:
+	ctx = rcu_dereference(task->perf_event_ctxp);
+	if (ctx) {
+		/*
+		 * If this context is a clone of another, it might
+		 * get swapped for another underneath us by
+		 * perf_event_task_sched_out, though the
+		 * rcu_read_lock() protects us from any context
+		 * getting freed.  Lock the context and check if it
+		 * got swapped before we could get the lock, and retry
+		 * if so.  If we locked the right context, then it
+		 * can't get swapped on us any more.
+		 */
+		spin_lock_irqsave(&ctx->lock, *flags);
+		if (ctx != rcu_dereference(task->perf_event_ctxp)) {
+			spin_unlock_irqrestore(&ctx->lock, *flags);
+			goto retry;
+		}
+
+		if (!atomic_inc_not_zero(&ctx->refcount)) {
+			spin_unlock_irqrestore(&ctx->lock, *flags);
+			ctx = NULL;
+		}
+	}
+	rcu_read_unlock();
+	return ctx;
+}
+
+/*
+ * Get the context for a task and increment its pin_count so it
+ * can't get swapped to another task.  This also increments its
+ * reference count so that the context can't get freed.
+ */
+static struct perf_event_context *perf_pin_task_context(struct task_struct *task)
+{
+	struct perf_event_context *ctx;
+	unsigned long flags;
+
+	ctx = perf_lock_task_context(task, &flags);
+	if (ctx) {
+		++ctx->pin_count;
+		spin_unlock_irqrestore(&ctx->lock, flags);
+	}
+	return ctx;
+}
+
+static void perf_unpin_context(struct perf_event_context *ctx)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ctx->lock, flags);
+	--ctx->pin_count;
+	spin_unlock_irqrestore(&ctx->lock, flags);
+	put_ctx(ctx);
+}
+
+/*
+ * Add a event from the lists for its context.
+ * Must be called with ctx->mutex and ctx->lock held.
+ */
+static void
+list_add_event(struct perf_event *event, struct perf_event_context *ctx)
+{
+	struct perf_event *group_leader = event->group_leader;
+
+	/*
+	 * Depending on whether it is a standalone or sibling event,
+	 * add it straight to the context's event list, or to the group
+	 * leader's sibling list:
+	 */
+	if (group_leader == event)
+		list_add_tail(&event->group_entry, &ctx->group_list);
+	else {
+		list_add_tail(&event->group_entry, &group_leader->sibling_list);
+		group_leader->nr_siblings++;
+	}
+
+	list_add_rcu(&event->event_entry, &ctx->event_list);
+	ctx->nr_events++;
+	if (event->attr.inherit_stat)
+		ctx->nr_stat++;
+}
+
+/*
+ * Remove a event from the lists for its context.
+ * Must be called with ctx->mutex and ctx->lock held.
+ */
+static void
+list_del_event(struct perf_event *event, struct perf_event_context *ctx)
+{
+	struct perf_event *sibling, *tmp;
+
+	if (list_empty(&event->group_entry))
+		return;
+	ctx->nr_events--;
+	if (event->attr.inherit_stat)
+		ctx->nr_stat--;
+
+	list_del_init(&event->group_entry);
+	list_del_rcu(&event->event_entry);
+
+	if (event->group_leader != event)
+		event->group_leader->nr_siblings--;
+
+	/*
+	 * If this was a group event with sibling events then
+	 * upgrade the siblings to singleton events by adding them
+	 * to the context list directly:
+	 */
+	list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) {
+
+		list_move_tail(&sibling->group_entry, &ctx->group_list);
+		sibling->group_leader = sibling;
+	}
+}
+
+static void
+event_sched_out(struct perf_event *event,
+		  struct perf_cpu_context *cpuctx,
+		  struct perf_event_context *ctx)
+{
+	if (event->state != PERF_EVENT_STATE_ACTIVE)
+		return;
+
+	event->state = PERF_EVENT_STATE_INACTIVE;
+	if (event->pending_disable) {
+		event->pending_disable = 0;
+		event->state = PERF_EVENT_STATE_OFF;
+	}
+	event->tstamp_stopped = ctx->time;
+	event->pmu->disable(event);
+	event->oncpu = -1;
+
+	if (!is_software_event(event))
+		cpuctx->active_oncpu--;
+	ctx->nr_active--;
+	if (event->attr.exclusive || !cpuctx->active_oncpu)
+		cpuctx->exclusive = 0;
+}
+
+static void
+group_sched_out(struct perf_event *group_event,
+		struct perf_cpu_context *cpuctx,
+		struct perf_event_context *ctx)
+{
+	struct perf_event *event;
+
+	if (group_event->state != PERF_EVENT_STATE_ACTIVE)
+		return;
+
+	event_sched_out(group_event, cpuctx, ctx);
+
+	/*
+	 * Schedule out siblings (if any):
+	 */
+	list_for_each_entry(event, &group_event->sibling_list, group_entry)
+		event_sched_out(event, cpuctx, ctx);
+
+	if (group_event->attr.exclusive)
+		cpuctx->exclusive = 0;
+}
+
+/*
+ * Cross CPU call to remove a performance event
+ *
+ * We disable the event on the hardware level first. After that we
+ * remove it from the context list.
+ */
+static void __perf_event_remove_from_context(void *info)
+{
+	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+	struct perf_event *event = info;
+	struct perf_event_context *ctx = event->ctx;
+
+	/*
+	 * If this is a task context, we need to check whether it is
+	 * the current task context of this cpu. If not it has been
+	 * scheduled out before the smp call arrived.
+	 */
+	if (ctx->task && cpuctx->task_ctx != ctx)
+		return;
+
+	spin_lock(&ctx->lock);
+	/*
+	 * Protect the list operation against NMI by disabling the
+	 * events on a global level.
+	 */
+	perf_disable();
+
+	event_sched_out(event, cpuctx, ctx);
+
+	list_del_event(event, ctx);
+
+	if (!ctx->task) {
+		/*
+		 * Allow more per task events with respect to the
+		 * reservation:
+		 */
+		cpuctx->max_pertask =
+			min(perf_max_events - ctx->nr_events,
+			    perf_max_events - perf_reserved_percpu);
+	}
+
+	perf_enable();
+	spin_unlock(&ctx->lock);
+}
+
+
+/*
+ * Remove the event from a task's (or a CPU's) list of events.
+ *
+ * Must be called with ctx->mutex held.
+ *
+ * CPU events are removed with a smp call. For task events we only
+ * call when the task is on a CPU.
+ *
+ * If event->ctx is a cloned context, callers must make sure that
+ * every task struct that event->ctx->task could possibly point to
+ * remains valid.  This is OK when called from perf_release since
+ * that only calls us on the top-level context, which can't be a clone.
+ * When called from perf_event_exit_task, it's OK because the
+ * context has been detached from its task.
+ */
+static void perf_event_remove_from_context(struct perf_event *event)
+{
+	struct perf_event_context *ctx = event->ctx;
+	struct task_struct *task = ctx->task;
+
+	if (!task) {
+		/*
+		 * Per cpu events are removed via an smp call and
+		 * the removal is always sucessful.
+		 */
+		smp_call_function_single(event->cpu,
+					 __perf_event_remove_from_context,
+					 event, 1);
+		return;
+	}
+
+retry:
+	task_oncpu_function_call(task, __perf_event_remove_from_context,
+				 event);
+
+	spin_lock_irq(&ctx->lock);
+	/*
+	 * If the context is active we need to retry the smp call.
+	 */
+	if (ctx->nr_active && !list_empty(&event->group_entry)) {
+		spin_unlock_irq(&ctx->lock);
+		goto retry;
+	}
+
+	/*
+	 * The lock prevents that this context is scheduled in so we
+	 * can remove the event safely, if the call above did not
+	 * succeed.
+	 */
+	if (!list_empty(&event->group_entry)) {
+		list_del_event(event, ctx);
+	}
+	spin_unlock_irq(&ctx->lock);
+}
+
+static inline u64 perf_clock(void)
+{
+	return cpu_clock(smp_processor_id());
+}
+
+/*
+ * Update the record of the current time in a context.
+ */
+static void update_context_time(struct perf_event_context *ctx)
+{
+	u64 now = perf_clock();
+
+	ctx->time += now - ctx->timestamp;
+	ctx->timestamp = now;
+}
+
+/*
+ * Update the total_time_enabled and total_time_running fields for a event.
+ */
+static void update_event_times(struct perf_event *event)
+{
+	struct perf_event_context *ctx = event->ctx;
+	u64 run_end;
+
+	if (event->state < PERF_EVENT_STATE_INACTIVE ||
+	    event->group_leader->state < PERF_EVENT_STATE_INACTIVE)
+		return;
+
+	event->total_time_enabled = ctx->time - event->tstamp_enabled;
+
+	if (event->state == PERF_EVENT_STATE_INACTIVE)
+		run_end = event->tstamp_stopped;
+	else
+		run_end = ctx->time;
+
+	event->total_time_running = run_end - event->tstamp_running;
+}
+
+/*
+ * Update total_time_enabled and total_time_running for all events in a group.
+ */
+static void update_group_times(struct perf_event *leader)
+{
+	struct perf_event *event;
+
+	update_event_times(leader);
+	list_for_each_entry(event, &leader->sibling_list, group_entry)
+		update_event_times(event);
+}
+
+/*
+ * Cross CPU call to disable a performance event
+ */
+static void __perf_event_disable(void *info)
+{
+	struct perf_event *event = info;
+	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+	struct perf_event_context *ctx = event->ctx;
+
+	/*
+	 * If this is a per-task event, need to check whether this
+	 * event's task is the current task on this cpu.
+	 */
+	if (ctx->task && cpuctx->task_ctx != ctx)
+		return;
+
+	spin_lock(&ctx->lock);
+
+	/*
+	 * If the event is on, turn it off.
+	 * If it is in error state, leave it in error state.
+	 */
+	if (event->state >= PERF_EVENT_STATE_INACTIVE) {
+		update_context_time(ctx);
+		update_group_times(event);
+		if (event == event->group_leader)
+			group_sched_out(event, cpuctx, ctx);
+		else
+			event_sched_out(event, cpuctx, ctx);
+		event->state = PERF_EVENT_STATE_OFF;
+	}
+
+	spin_unlock(&ctx->lock);
+}
+
+/*
+ * Disable a event.
+ *
+ * If event->ctx is a cloned context, callers must make sure that
+ * every task struct that event->ctx->task could possibly point to
+ * remains valid.  This condition is satisifed when called through
+ * perf_event_for_each_child or perf_event_for_each because they
+ * hold the top-level event's child_mutex, so any descendant that
+ * goes to exit will block in sync_child_event.
+ * When called from perf_pending_event it's OK because event->ctx
+ * is the current context on this CPU and preemption is disabled,
+ * hence we can't get into perf_event_task_sched_out for this context.
+ */
+static void perf_event_disable(struct perf_event *event)
+{
+	struct perf_event_context *ctx = event->ctx;
+	struct task_struct *task = ctx->task;
+
+	if (!task) {
+		/*
+		 * Disable the event on the cpu that it's on
+		 */
+		smp_call_function_single(event->cpu, __perf_event_disable,
+					 event, 1);
+		return;
+	}
+
+ retry:
+	task_oncpu_function_call(task, __perf_event_disable, event);
+
+	spin_lock_irq(&ctx->lock);
+	/*
+	 * If the event is still active, we need to retry the cross-call.
+	 */
+	if (event->state == PERF_EVENT_STATE_ACTIVE) {
+		spin_unlock_irq(&ctx->lock);
+		goto retry;
+	}
+
+	/*
+	 * Since we have the lock this context can't be scheduled
+	 * in, so we can change the state safely.
+	 */
+	if (event->state == PERF_EVENT_STATE_INACTIVE) {
+		update_group_times(event);
+		event->state = PERF_EVENT_STATE_OFF;
+	}
+
+	spin_unlock_irq(&ctx->lock);
+}
+
+static int
+event_sched_in(struct perf_event *event,
+		 struct perf_cpu_context *cpuctx,
+		 struct perf_event_context *ctx,
+		 int cpu)
+{
+	if (event->state <= PERF_EVENT_STATE_OFF)
+		return 0;
+
+	event->state = PERF_EVENT_STATE_ACTIVE;
+	event->oncpu = cpu;	/* TODO: put 'cpu' into cpuctx->cpu */
+	/*
+	 * The new state must be visible before we turn it on in the hardware:
+	 */
+	smp_wmb();
+
+	if (event->pmu->enable(event)) {
+		event->state = PERF_EVENT_STATE_INACTIVE;
+		event->oncpu = -1;
+		return -EAGAIN;
+	}
+
+	event->tstamp_running += ctx->time - event->tstamp_stopped;
+
+	if (!is_software_event(event))
+		cpuctx->active_oncpu++;
+	ctx->nr_active++;
+
+	if (event->attr.exclusive)
+		cpuctx->exclusive = 1;
+
+	return 0;
+}
+
+static int
+group_sched_in(struct perf_event *group_event,
+	       struct perf_cpu_context *cpuctx,
+	       struct perf_event_context *ctx,
+	       int cpu)
+{
+	struct perf_event *event, *partial_group;
+	int ret;
+
+	if (group_event->state == PERF_EVENT_STATE_OFF)
+		return 0;
+
+	ret = hw_perf_group_sched_in(group_event, cpuctx, ctx, cpu);
+	if (ret)
+		return ret < 0 ? ret : 0;
+
+	if (event_sched_in(group_event, cpuctx, ctx, cpu))
+		return -EAGAIN;
+
+	/*
+	 * Schedule in siblings as one group (if any):
+	 */
+	list_for_each_entry(event, &group_event->sibling_list, group_entry) {
+		if (event_sched_in(event, cpuctx, ctx, cpu)) {
+			partial_group = event;
+			goto group_error;
+		}
+	}
+
+	return 0;
+
+group_error:
+	/*
+	 * Groups can be scheduled in as one unit only, so undo any
+	 * partial group before returning:
+	 */
+	list_for_each_entry(event, &group_event->sibling_list, group_entry) {
+		if (event == partial_group)
+			break;
+		event_sched_out(event, cpuctx, ctx);
+	}
+	event_sched_out(group_event, cpuctx, ctx);
+
+	return -EAGAIN;
+}
+
+/*
+ * Return 1 for a group consisting entirely of software events,
+ * 0 if the group contains any hardware events.
+ */
+static int is_software_only_group(struct perf_event *leader)
+{
+	struct perf_event *event;
+
+	if (!is_software_event(leader))
+		return 0;
+
+	list_for_each_entry(event, &leader->sibling_list, group_entry)
+		if (!is_software_event(event))
+			return 0;
+
+	return 1;
+}
+
+/*
+ * Work out whether we can put this event group on the CPU now.
+ */
+static int group_can_go_on(struct perf_event *event,
+			   struct perf_cpu_context *cpuctx,
+			   int can_add_hw)
+{
+	/*
+	 * Groups consisting entirely of software events can always go on.
+	 */
+	if (is_software_only_group(event))
+		return 1;
+	/*
+	 * If an exclusive group is already on, no other hardware
+	 * events can go on.
+	 */
+	if (cpuctx->exclusive)
+		return 0;
+	/*
+	 * If this group is exclusive and there are already
+	 * events on the CPU, it can't go on.
+	 */
+	if (event->attr.exclusive && cpuctx->active_oncpu)
+		return 0;
+	/*
+	 * Otherwise, try to add it if all previous groups were able
+	 * to go on.
+	 */
+	return can_add_hw;
+}
+
+static void add_event_to_ctx(struct perf_event *event,
+			       struct perf_event_context *ctx)
+{
+	list_add_event(event, ctx);
+	event->tstamp_enabled = ctx->time;
+	event->tstamp_running = ctx->time;
+	event->tstamp_stopped = ctx->time;
+}
+
+/*
+ * Cross CPU call to install and enable a performance event
+ *
+ * Must be called with ctx->mutex held
+ */
+static void __perf_install_in_context(void *info)
+{
+	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+	struct perf_event *event = info;
+	struct perf_event_context *ctx = event->ctx;
+	struct perf_event *leader = event->group_leader;
+	int cpu = smp_processor_id();
+	int err;
+
+	/*
+	 * If this is a task context, we need to check whether it is
+	 * the current task context of this cpu. If not it has been
+	 * scheduled out before the smp call arrived.
+	 * Or possibly this is the right context but it isn't
+	 * on this cpu because it had no events.
+	 */
+	if (ctx->task && cpuctx->task_ctx != ctx) {
+		if (cpuctx->task_ctx || ctx->task != current)
+			return;
+		cpuctx->task_ctx = ctx;
+	}
+
+	spin_lock(&ctx->lock);
+	ctx->is_active = 1;
+	update_context_time(ctx);
+
+	/*
+	 * Protect the list operation against NMI by disabling the
+	 * events on a global level. NOP for non NMI based events.
+	 */
+	perf_disable();
+
+	add_event_to_ctx(event, ctx);
+
+	/*
+	 * Don't put the event on if it is disabled or if
+	 * it is in a group and the group isn't on.
+	 */
+	if (event->state != PERF_EVENT_STATE_INACTIVE ||
+	    (leader != event && leader->state != PERF_EVENT_STATE_ACTIVE))
+		goto unlock;
+
+	/*
+	 * An exclusive event can't go on if there are already active
+	 * hardware events, and no hardware event can go on if there
+	 * is already an exclusive event on.
+	 */
+	if (!group_can_go_on(event, cpuctx, 1))
+		err = -EEXIST;
+	else
+		err = event_sched_in(event, cpuctx, ctx, cpu);
+
+	if (err) {
+		/*
+		 * This event couldn't go on.  If it is in a group
+		 * then we have to pull the whole group off.
+		 * If the event group is pinned then put it in error state.
+		 */
+		if (leader != event)
+			group_sched_out(leader, cpuctx, ctx);
+		if (leader->attr.pinned) {
+			update_group_times(leader);
+			leader->state = PERF_EVENT_STATE_ERROR;
+		}
+	}
+
+	if (!err && !ctx->task && cpuctx->max_pertask)
+		cpuctx->max_pertask--;
+
+ unlock:
+	perf_enable();
+
+	spin_unlock(&ctx->lock);
+}
+
+/*
+ * Attach a performance event to a context
+ *
+ * First we add the event to the list with the hardware enable bit
+ * in event->hw_config cleared.
+ *
+ * If the event is attached to a task which is on a CPU we use a smp
+ * call to enable it in the task context. The task might have been
+ * scheduled away, but we check this in the smp call again.
+ *
+ * Must be called with ctx->mutex held.
+ */
+static void
+perf_install_in_context(struct perf_event_context *ctx,
+			struct perf_event *event,
+			int cpu)
+{
+	struct task_struct *task = ctx->task;
+
+	if (!task) {
+		/*
+		 * Per cpu events are installed via an smp call and
+		 * the install is always sucessful.
+		 */
+		smp_call_function_single(cpu, __perf_install_in_context,
+					 event, 1);
+		return;
+	}
+
+retry:
+	task_oncpu_function_call(task, __perf_install_in_context,
+				 event);
+
+	spin_lock_irq(&ctx->lock);
+	/*
+	 * we need to retry the smp call.
+	 */
+	if (ctx->is_active && list_empty(&event->group_entry)) {
+		spin_unlock_irq(&ctx->lock);
+		goto retry;
+	}
+
+	/*
+	 * The lock prevents that this context is scheduled in so we
+	 * can add the event safely, if it the call above did not
+	 * succeed.
+	 */
+	if (list_empty(&event->group_entry))
+		add_event_to_ctx(event, ctx);
+	spin_unlock_irq(&ctx->lock);
+}
+
+/*
+ * Put a event into inactive state and update time fields.
+ * Enabling the leader of a group effectively enables all
+ * the group members that aren't explicitly disabled, so we
+ * have to update their ->tstamp_enabled also.
+ * Note: this works for group members as well as group leaders
+ * since the non-leader members' sibling_lists will be empty.
+ */
+static void __perf_event_mark_enabled(struct perf_event *event,
+					struct perf_event_context *ctx)
+{
+	struct perf_event *sub;
+
+	event->state = PERF_EVENT_STATE_INACTIVE;
+	event->tstamp_enabled = ctx->time - event->total_time_enabled;
+	list_for_each_entry(sub, &event->sibling_list, group_entry)
+		if (sub->state >= PERF_EVENT_STATE_INACTIVE)
+			sub->tstamp_enabled =
+				ctx->time - sub->total_time_enabled;
+}
+
+/*
+ * Cross CPU call to enable a performance event
+ */
+static void __perf_event_enable(void *info)
+{
+	struct perf_event *event = info;
+	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+	struct perf_event_context *ctx = event->ctx;
+	struct perf_event *leader = event->group_leader;
+	int err;
+
+	/*
+	 * If this is a per-task event, need to check whether this
+	 * event's task is the current task on this cpu.
+	 */
+	if (ctx->task && cpuctx->task_ctx != ctx) {
+		if (cpuctx->task_ctx || ctx->task != current)
+			return;
+		cpuctx->task_ctx = ctx;
+	}
+
+	spin_lock(&ctx->lock);
+	ctx->is_active = 1;
+	update_context_time(ctx);
+
+	if (event->state >= PERF_EVENT_STATE_INACTIVE)
+		goto unlock;
+	__perf_event_mark_enabled(event, ctx);
+
+	/*
+	 * If the event is in a group and isn't the group leader,
+	 * then don't put it on unless the group is on.
+	 */
+	if (leader != event && leader->state != PERF_EVENT_STATE_ACTIVE)
+		goto unlock;
+
+	if (!group_can_go_on(event, cpuctx, 1)) {
+		err = -EEXIST;
+	} else {
+		perf_disable();
+		if (event == leader)
+			err = group_sched_in(event, cpuctx, ctx,
+					     smp_processor_id());
+		else
+			err = event_sched_in(event, cpuctx, ctx,
+					       smp_processor_id());
+		perf_enable();
+	}
+
+	if (err) {
+		/*
+		 * If this event can't go on and it's part of a
+		 * group, then the whole group has to come off.
+		 */
+		if (leader != event)
+			group_sched_out(leader, cpuctx, ctx);
+		if (leader->attr.pinned) {
+			update_group_times(leader);
+			leader->state = PERF_EVENT_STATE_ERROR;
+		}
+	}
+
+ unlock:
+	spin_unlock(&ctx->lock);
+}
+
+/*
+ * Enable a event.
+ *
+ * If event->ctx is a cloned context, callers must make sure that
+ * every task struct that event->ctx->task could possibly point to
+ * remains valid.  This condition is satisfied when called through
+ * perf_event_for_each_child or perf_event_for_each as described
+ * for perf_event_disable.
+ */
+static void perf_event_enable(struct perf_event *event)
+{
+	struct perf_event_context *ctx = event->ctx;
+	struct task_struct *task = ctx->task;
+
+	if (!task) {
+		/*
+		 * Enable the event on the cpu that it's on
+		 */
+		smp_call_function_single(event->cpu, __perf_event_enable,
+					 event, 1);
+		return;
+	}
+
+	spin_lock_irq(&ctx->lock);
+	if (event->state >= PERF_EVENT_STATE_INACTIVE)
+		goto out;
+
+	/*
+	 * If the event is in error state, clear that first.
+	 * That way, if we see the event in error state below, we
+	 * know that it has gone back into error state, as distinct
+	 * from the task having been scheduled away before the
+	 * cross-call arrived.
+	 */
+	if (event->state == PERF_EVENT_STATE_ERROR)
+		event->state = PERF_EVENT_STATE_OFF;
+
+ retry:
+	spin_unlock_irq(&ctx->lock);
+	task_oncpu_function_call(task, __perf_event_enable, event);
+
+	spin_lock_irq(&ctx->lock);
+
+	/*
+	 * If the context is active and the event is still off,
+	 * we need to retry the cross-call.
+	 */
+	if (ctx->is_active && event->state == PERF_EVENT_STATE_OFF)
+		goto retry;
+
+	/*
+	 * Since we have the lock this context can't be scheduled
+	 * in, so we can change the state safely.
+	 */
+	if (event->state == PERF_EVENT_STATE_OFF)
+		__perf_event_mark_enabled(event, ctx);
+
+ out:
+	spin_unlock_irq(&ctx->lock);
+}
+
+static int perf_event_refresh(struct perf_event *event, int refresh)
+{
+	/*
+	 * not supported on inherited events
+	 */
+	if (event->attr.inherit)
+		return -EINVAL;
+
+	atomic_add(refresh, &event->event_limit);
+	perf_event_enable(event);
+
+	return 0;
+}
+
+void __perf_event_sched_out(struct perf_event_context *ctx,
+			      struct perf_cpu_context *cpuctx)
+{
+	struct perf_event *event;
+
+	spin_lock(&ctx->lock);
+	ctx->is_active = 0;
+	if (likely(!ctx->nr_events))
+		goto out;
+	update_context_time(ctx);
+
+	perf_disable();
+	if (ctx->nr_active) {
+		list_for_each_entry(event, &ctx->group_list, group_entry) {
+			if (event != event->group_leader)
+				event_sched_out(event, cpuctx, ctx);
+			else
+				group_sched_out(event, cpuctx, ctx);
+		}
+	}
+	perf_enable();
+ out:
+	spin_unlock(&ctx->lock);
+}
+
+/*
+ * Test whether two contexts are equivalent, i.e. whether they
+ * have both been cloned from the same version of the same context
+ * and they both have the same number of enabled events.
+ * If the number of enabled events is the same, then the set
+ * of enabled events should be the same, because these are both
+ * inherited contexts, therefore we can't access individual events
+ * in them directly with an fd; we can only enable/disable all
+ * events via prctl, or enable/disable all events in a family
+ * via ioctl, which will have the same effect on both contexts.
+ */
+static int context_equiv(struct perf_event_context *ctx1,
+			 struct perf_event_context *ctx2)
+{
+	return ctx1->parent_ctx && ctx1->parent_ctx == ctx2->parent_ctx
+		&& ctx1->parent_gen == ctx2->parent_gen
+		&& !ctx1->pin_count && !ctx2->pin_count;
+}
+
+static void __perf_event_read(void *event);
+
+static void __perf_event_sync_stat(struct perf_event *event,
+				     struct perf_event *next_event)
+{
+	u64 value;
+
+	if (!event->attr.inherit_stat)
+		return;
+
+	/*
+	 * Update the event value, we cannot use perf_event_read()
+	 * because we're in the middle of a context switch and have IRQs
+	 * disabled, which upsets smp_call_function_single(), however
+	 * we know the event must be on the current CPU, therefore we
+	 * don't need to use it.
+	 */
+	switch (event->state) {
+	case PERF_EVENT_STATE_ACTIVE:
+		__perf_event_read(event);
+		break;
+
+	case PERF_EVENT_STATE_INACTIVE:
+		update_event_times(event);
+		break;
+
+	default:
+		break;
+	}
+
+	/*
+	 * In order to keep per-task stats reliable we need to flip the event
+	 * values when we flip the contexts.
+	 */
+	value = atomic64_read(&next_event->count);
+	value = atomic64_xchg(&event->count, value);
+	atomic64_set(&next_event->count, value);
+
+	swap(event->total_time_enabled, next_event->total_time_enabled);
+	swap(event->total_time_running, next_event->total_time_running);
+
+	/*
+	 * Since we swizzled the values, update the user visible data too.
+	 */
+	perf_event_update_userpage(event);
+	perf_event_update_userpage(next_event);
+}
+
+#define list_next_entry(pos, member) \
+	list_entry(pos->member.next, typeof(*pos), member)
+
+static void perf_event_sync_stat(struct perf_event_context *ctx,
+				   struct perf_event_context *next_ctx)
+{
+	struct perf_event *event, *next_event;
+
+	if (!ctx->nr_stat)
+		return;
+
+	event = list_first_entry(&ctx->event_list,
+				   struct perf_event, event_entry);
+
+	next_event = list_first_entry(&next_ctx->event_list,
+					struct perf_event, event_entry);
+
+	while (&event->event_entry != &ctx->event_list &&
+	       &next_event->event_entry != &next_ctx->event_list) {
+
+		__perf_event_sync_stat(event, next_event);
+
+		event = list_next_entry(event, event_entry);
+		next_event = list_next_entry(next_event, event_entry);
+	}
+}
+
+/*
+ * Called from scheduler to remove the events of the current task,
+ * with interrupts disabled.
+ *
+ * We stop each event and update the event value in event->count.
+ *
+ * This does not protect us against NMI, but disable()
+ * sets the disabled bit in the control field of event _before_
+ * accessing the event control register. If a NMI hits, then it will
+ * not restart the event.
+ */
+void perf_event_task_sched_out(struct task_struct *task,
+				 struct task_struct *next, int cpu)
+{
+	struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
+	struct perf_event_context *ctx = task->perf_event_ctxp;
+	struct perf_event_context *next_ctx;
+	struct perf_event_context *parent;
+	struct pt_regs *regs;
+	int do_switch = 1;
+
+	regs = task_pt_regs(task);
+	perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, regs, 0);
+
+	if (likely(!ctx || !cpuctx->task_ctx))
+		return;
+
+	update_context_time(ctx);
+
+	rcu_read_lock();
+	parent = rcu_dereference(ctx->parent_ctx);
+	next_ctx = next->perf_event_ctxp;
+	if (parent && next_ctx &&
+	    rcu_dereference(next_ctx->parent_ctx) == parent) {
+		/*
+		 * Looks like the two contexts are clones, so we might be
+		 * able to optimize the context switch.  We lock both
+		 * contexts and check that they are clones under the
+		 * lock (including re-checking that neither has been
+		 * uncloned in the meantime).  It doesn't matter which
+		 * order we take the locks because no other cpu could
+		 * be trying to lock both of these tasks.
+		 */
+		spin_lock(&ctx->lock);
+		spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING);
+		if (context_equiv(ctx, next_ctx)) {
+			/*
+			 * XXX do we need a memory barrier of sorts
+			 * wrt to rcu_dereference() of perf_event_ctxp
+			 */
+			task->perf_event_ctxp = next_ctx;
+			next->perf_event_ctxp = ctx;
+			ctx->task = next;
+			next_ctx->task = task;
+			do_switch = 0;
+
+			perf_event_sync_stat(ctx, next_ctx);
+		}
+		spin_unlock(&next_ctx->lock);
+		spin_unlock(&ctx->lock);
+	}
+	rcu_read_unlock();
+
+	if (do_switch) {
+		__perf_event_sched_out(ctx, cpuctx);
+		cpuctx->task_ctx = NULL;
+	}
+}
+
+/*
+ * Called with IRQs disabled
+ */
+static void __perf_event_task_sched_out(struct perf_event_context *ctx)
+{
+	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+
+	if (!cpuctx->task_ctx)
+		return;
+
+	if (WARN_ON_ONCE(ctx != cpuctx->task_ctx))
+		return;
+
+	__perf_event_sched_out(ctx, cpuctx);
+	cpuctx->task_ctx = NULL;
+}
+
+/*
+ * Called with IRQs disabled
+ */
+static void perf_event_cpu_sched_out(struct perf_cpu_context *cpuctx)
+{
+	__perf_event_sched_out(&cpuctx->ctx, cpuctx);
+}
+
+static void
+__perf_event_sched_in(struct perf_event_context *ctx,
+			struct perf_cpu_context *cpuctx, int cpu)
+{
+	struct perf_event *event;
+	int can_add_hw = 1;
+
+	spin_lock(&ctx->lock);
+	ctx->is_active = 1;
+	if (likely(!ctx->nr_events))
+		goto out;
+
+	ctx->timestamp = perf_clock();
+
+	perf_disable();
+
+	/*
+	 * First go through the list and put on any pinned groups
+	 * in order to give them the best chance of going on.
+	 */
+	list_for_each_entry(event, &ctx->group_list, group_entry) {
+		if (event->state <= PERF_EVENT_STATE_OFF ||
+		    !event->attr.pinned)
+			continue;
+		if (event->cpu != -1 && event->cpu != cpu)
+			continue;
+
+		if (event != event->group_leader)
+			event_sched_in(event, cpuctx, ctx, cpu);
+		else {
+			if (group_can_go_on(event, cpuctx, 1))
+				group_sched_in(event, cpuctx, ctx, cpu);
+		}
+
+		/*
+		 * If this pinned group hasn't been scheduled,
+		 * put it in error state.
+		 */
+		if (event->state == PERF_EVENT_STATE_INACTIVE) {
+			update_group_times(event);
+			event->state = PERF_EVENT_STATE_ERROR;
+		}
+	}
+
+	list_for_each_entry(event, &ctx->group_list, group_entry) {
+		/*
+		 * Ignore events in OFF or ERROR state, and
+		 * ignore pinned events since we did them already.
+		 */
+		if (event->state <= PERF_EVENT_STATE_OFF ||
+		    event->attr.pinned)
+			continue;
+
+		/*
+		 * Listen to the 'cpu' scheduling filter constraint
+		 * of events:
+		 */
+		if (event->cpu != -1 && event->cpu != cpu)
+			continue;
+
+		if (event != event->group_leader) {
+			if (event_sched_in(event, cpuctx, ctx, cpu))
+				can_add_hw = 0;
+		} else {
+			if (group_can_go_on(event, cpuctx, can_add_hw)) {
+				if (group_sched_in(event, cpuctx, ctx, cpu))
+					can_add_hw = 0;
+			}
+		}
+	}
+	perf_enable();
+ out:
+	spin_unlock(&ctx->lock);
+}
+
+/*
+ * Called from scheduler to add the events of the current task
+ * with interrupts disabled.
+ *
+ * We restore the event value and then enable it.
+ *
+ * This does not protect us against NMI, but enable()
+ * sets the enabled bit in the control field of event _before_
+ * accessing the event control register. If a NMI hits, then it will
+ * keep the event running.
+ */
+void perf_event_task_sched_in(struct task_struct *task, int cpu)
+{
+	struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
+	struct perf_event_context *ctx = task->perf_event_ctxp;
+
+	if (likely(!ctx))
+		return;
+	if (cpuctx->task_ctx == ctx)
+		return;
+	__perf_event_sched_in(ctx, cpuctx, cpu);
+	cpuctx->task_ctx = ctx;
+}
+
+static void perf_event_cpu_sched_in(struct perf_cpu_context *cpuctx, int cpu)
+{
+	struct perf_event_context *ctx = &cpuctx->ctx;
+
+	__perf_event_sched_in(ctx, cpuctx, cpu);
+}
+
+#define MAX_INTERRUPTS (~0ULL)
+
+static void perf_log_throttle(struct perf_event *event, int enable);
+
+static void perf_adjust_period(struct perf_event *event, u64 events)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 period, sample_period;
+	s64 delta;
+
+	events *= hwc->sample_period;
+	period = div64_u64(events, event->attr.sample_freq);
+
+	delta = (s64)(period - hwc->sample_period);
+	delta = (delta + 7) / 8; /* low pass filter */
+
+	sample_period = hwc->sample_period + delta;
+
+	if (!sample_period)
+		sample_period = 1;
+
+	hwc->sample_period = sample_period;
+}
+
+static void perf_ctx_adjust_freq(struct perf_event_context *ctx)
+{
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	u64 interrupts, freq;
+
+	spin_lock(&ctx->lock);
+	list_for_each_entry(event, &ctx->group_list, group_entry) {
+		if (event->state != PERF_EVENT_STATE_ACTIVE)
+			continue;
+
+		hwc = &event->hw;
+
+		interrupts = hwc->interrupts;
+		hwc->interrupts = 0;
+
+		/*
+		 * unthrottle events on the tick
+		 */
+		if (interrupts == MAX_INTERRUPTS) {
+			perf_log_throttle(event, 1);
+			event->pmu->unthrottle(event);
+			interrupts = 2*sysctl_perf_event_sample_rate/HZ;
+		}
+
+		if (!event->attr.freq || !event->attr.sample_freq)
+			continue;
+
+		/*
+		 * if the specified freq < HZ then we need to skip ticks
+		 */
+		if (event->attr.sample_freq < HZ) {
+			freq = event->attr.sample_freq;
+
+			hwc->freq_count += freq;
+			hwc->freq_interrupts += interrupts;
+
+			if (hwc->freq_count < HZ)
+				continue;
+
+			interrupts = hwc->freq_interrupts;
+			hwc->freq_interrupts = 0;
+			hwc->freq_count -= HZ;
+		} else
+			freq = HZ;
+
+		perf_adjust_period(event, freq * interrupts);
+
+		/*
+		 * In order to avoid being stalled by an (accidental) huge
+		 * sample period, force reset the sample period if we didn't
+		 * get any events in this freq period.
+		 */
+		if (!interrupts) {
+			perf_disable();
+			event->pmu->disable(event);
+			atomic64_set(&hwc->period_left, 0);
+			event->pmu->enable(event);
+			perf_enable();
+		}
+	}
+	spin_unlock(&ctx->lock);
+}
+
+/*
+ * Round-robin a context's events:
+ */
+static void rotate_ctx(struct perf_event_context *ctx)
+{
+	struct perf_event *event;
+
+	if (!ctx->nr_events)
+		return;
+
+	spin_lock(&ctx->lock);
+	/*
+	 * Rotate the first entry last (works just fine for group events too):
+	 */
+	perf_disable();
+	list_for_each_entry(event, &ctx->group_list, group_entry) {
+		list_move_tail(&event->group_entry, &ctx->group_list);
+		break;
+	}
+	perf_enable();
+
+	spin_unlock(&ctx->lock);
+}
+
+void perf_event_task_tick(struct task_struct *curr, int cpu)
+{
+	struct perf_cpu_context *cpuctx;
+	struct perf_event_context *ctx;
+
+	if (!atomic_read(&nr_events))
+		return;
+
+	cpuctx = &per_cpu(perf_cpu_context, cpu);
+	ctx = curr->perf_event_ctxp;
+
+	perf_ctx_adjust_freq(&cpuctx->ctx);
+	if (ctx)
+		perf_ctx_adjust_freq(ctx);
+
+	perf_event_cpu_sched_out(cpuctx);
+	if (ctx)
+		__perf_event_task_sched_out(ctx);
+
+	rotate_ctx(&cpuctx->ctx);
+	if (ctx)
+		rotate_ctx(ctx);
+
+	perf_event_cpu_sched_in(cpuctx, cpu);
+	if (ctx)
+		perf_event_task_sched_in(curr, cpu);
+}
+
+/*
+ * Enable all of a task's events that have been marked enable-on-exec.
+ * This expects task == current.
+ */
+static void perf_event_enable_on_exec(struct task_struct *task)
+{
+	struct perf_event_context *ctx;
+	struct perf_event *event;
+	unsigned long flags;
+	int enabled = 0;
+
+	local_irq_save(flags);
+	ctx = task->perf_event_ctxp;
+	if (!ctx || !ctx->nr_events)
+		goto out;
+
+	__perf_event_task_sched_out(ctx);
+
+	spin_lock(&ctx->lock);
+
+	list_for_each_entry(event, &ctx->group_list, group_entry) {
+		if (!event->attr.enable_on_exec)
+			continue;
+		event->attr.enable_on_exec = 0;
+		if (event->state >= PERF_EVENT_STATE_INACTIVE)
+			continue;
+		__perf_event_mark_enabled(event, ctx);
+		enabled = 1;
+	}
+
+	/*
+	 * Unclone this context if we enabled any event.
+	 */
+	if (enabled)
+		unclone_ctx(ctx);
+
+	spin_unlock(&ctx->lock);
+
+	perf_event_task_sched_in(task, smp_processor_id());
+ out:
+	local_irq_restore(flags);
+}
+
+/*
+ * Cross CPU call to read the hardware event
+ */
+static void __perf_event_read(void *info)
+{
+	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+	struct perf_event *event = info;
+	struct perf_event_context *ctx = event->ctx;
+	unsigned long flags;
+
+	/*
+	 * If this is a task context, we need to check whether it is
+	 * the current task context of this cpu.  If not it has been
+	 * scheduled out before the smp call arrived.  In that case
+	 * event->count would have been updated to a recent sample
+	 * when the event was scheduled out.
+	 */
+	if (ctx->task && cpuctx->task_ctx != ctx)
+		return;
+
+	local_irq_save(flags);
+	if (ctx->is_active)
+		update_context_time(ctx);
+	event->pmu->read(event);
+	update_event_times(event);
+	local_irq_restore(flags);
+}
+
+static u64 perf_event_read(struct perf_event *event)
+{
+	/*
+	 * If event is enabled and currently active on a CPU, update the
+	 * value in the event structure:
+	 */
+	if (event->state == PERF_EVENT_STATE_ACTIVE) {
+		smp_call_function_single(event->oncpu,
+					 __perf_event_read, event, 1);
+	} else if (event->state == PERF_EVENT_STATE_INACTIVE) {
+		update_event_times(event);
+	}
+
+	return atomic64_read(&event->count);
+}
+
+/*
+ * Initialize the perf_event context in a task_struct:
+ */
+static void
+__perf_event_init_context(struct perf_event_context *ctx,
+			    struct task_struct *task)
+{
+	memset(ctx, 0, sizeof(*ctx));
+	spin_lock_init(&ctx->lock);
+	mutex_init(&ctx->mutex);
+	INIT_LIST_HEAD(&ctx->group_list);
+	INIT_LIST_HEAD(&ctx->event_list);
+	atomic_set(&ctx->refcount, 1);
+	ctx->task = task;
+}
+
+static struct perf_event_context *find_get_context(pid_t pid, int cpu)
+{
+	struct perf_event_context *ctx;
+	struct perf_cpu_context *cpuctx;
+	struct task_struct *task;
+	unsigned long flags;
+	int err;
+
+	/*
+	 * If cpu is not a wildcard then this is a percpu event:
+	 */
+	if (cpu != -1) {
+		/* Must be root to operate on a CPU event: */
+		if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
+			return ERR_PTR(-EACCES);
+
+		if (cpu < 0 || cpu > num_possible_cpus())
+			return ERR_PTR(-EINVAL);
+
+		/*
+		 * We could be clever and allow to attach a event to an
+		 * offline CPU and activate it when the CPU comes up, but
+		 * that's for later.
+		 */
+		if (!cpu_isset(cpu, cpu_online_map))
+			return ERR_PTR(-ENODEV);
+
+		cpuctx = &per_cpu(perf_cpu_context, cpu);
+		ctx = &cpuctx->ctx;
+		get_ctx(ctx);
+
+		return ctx;
+	}
+
+	rcu_read_lock();
+	if (!pid)
+		task = current;
+	else
+		task = find_task_by_vpid(pid);
+	if (task)
+		get_task_struct(task);
+	rcu_read_unlock();
+
+	if (!task)
+		return ERR_PTR(-ESRCH);
+
+	/*
+	 * Can't attach events to a dying task.
+	 */
+	err = -ESRCH;
+	if (task->flags & PF_EXITING)
+		goto errout;
+
+	/* Reuse ptrace permission checks for now. */
+	err = -EACCES;
+	if (!ptrace_may_access(task, PTRACE_MODE_READ))
+		goto errout;
+
+ retry:
+	ctx = perf_lock_task_context(task, &flags);
+	if (ctx) {
+		unclone_ctx(ctx);
+		spin_unlock_irqrestore(&ctx->lock, flags);
+	}
+
+	if (!ctx) {
+		ctx = kmalloc(sizeof(struct perf_event_context), GFP_KERNEL);
+		err = -ENOMEM;
+		if (!ctx)
+			goto errout;
+		__perf_event_init_context(ctx, task);
+		get_ctx(ctx);
+		if (cmpxchg(&task->perf_event_ctxp, NULL, ctx)) {
+			/*
+			 * We raced with some other task; use
+			 * the context they set.
+			 */
+			kfree(ctx);
+			goto retry;
+		}
+		get_task_struct(task);
+	}
+
+	put_task_struct(task);
+	return ctx;
+
+ errout:
+	put_task_struct(task);
+	return ERR_PTR(err);
+}
+
+static void free_event_rcu(struct rcu_head *head)
+{
+	struct perf_event *event;
+
+	event = container_of(head, struct perf_event, rcu_head);
+	if (event->ns)
+		put_pid_ns(event->ns);
+	kfree(event);
+}
+
+static void perf_pending_sync(struct perf_event *event);
+
+static void free_event(struct perf_event *event)
+{
+	perf_pending_sync(event);
+
+	if (!event->parent) {
+		atomic_dec(&nr_events);
+		if (event->attr.mmap)
+			atomic_dec(&nr_mmap_events);
+		if (event->attr.comm)
+			atomic_dec(&nr_comm_events);
+		if (event->attr.task)
+			atomic_dec(&nr_task_events);
+	}
+
+	if (event->output) {
+		fput(event->output->filp);
+		event->output = NULL;
+	}
+
+	if (event->destroy)
+		event->destroy(event);
+
+	put_ctx(event->ctx);
+	call_rcu(&event->rcu_head, free_event_rcu);
+}
+
+/*
+ * Called when the last reference to the file is gone.
+ */
+static int perf_release(struct inode *inode, struct file *file)
+{
+	struct perf_event *event = file->private_data;
+	struct perf_event_context *ctx = event->ctx;
+
+	file->private_data = NULL;
+
+	WARN_ON_ONCE(ctx->parent_ctx);
+	mutex_lock(&ctx->mutex);
+	perf_event_remove_from_context(event);
+	mutex_unlock(&ctx->mutex);
+
+	mutex_lock(&event->owner->perf_event_mutex);
+	list_del_init(&event->owner_entry);
+	mutex_unlock(&event->owner->perf_event_mutex);
+	put_task_struct(event->owner);
+
+	free_event(event);
+
+	return 0;
+}
+
+static int perf_event_read_size(struct perf_event *event)
+{
+	int entry = sizeof(u64); /* value */
+	int size = 0;
+	int nr = 1;
+
+	if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+		size += sizeof(u64);
+
+	if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+		size += sizeof(u64);
+
+	if (event->attr.read_format & PERF_FORMAT_ID)
+		entry += sizeof(u64);
+
+	if (event->attr.read_format & PERF_FORMAT_GROUP) {
+		nr += event->group_leader->nr_siblings;
+		size += sizeof(u64);
+	}
+
+	size += entry * nr;
+
+	return size;
+}
+
+static u64 perf_event_read_value(struct perf_event *event)
+{
+	struct perf_event *child;
+	u64 total = 0;
+
+	total += perf_event_read(event);
+	list_for_each_entry(child, &event->child_list, child_list)
+		total += perf_event_read(child);
+
+	return total;
+}
+
+static int perf_event_read_entry(struct perf_event *event,
+				   u64 read_format, char __user *buf)
+{
+	int n = 0, count = 0;
+	u64 values[2];
+
+	values[n++] = perf_event_read_value(event);
+	if (read_format & PERF_FORMAT_ID)
+		values[n++] = primary_event_id(event);
+
+	count = n * sizeof(u64);
+
+	if (copy_to_user(buf, values, count))
+		return -EFAULT;
+
+	return count;
+}
+
+static int perf_event_read_group(struct perf_event *event,
+				   u64 read_format, char __user *buf)
+{
+	struct perf_event *leader = event->group_leader, *sub;
+	int n = 0, size = 0, err = -EFAULT;
+	u64 values[3];
+
+	values[n++] = 1 + leader->nr_siblings;
+	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+		values[n++] = leader->total_time_enabled +
+			atomic64_read(&leader->child_total_time_enabled);
+	}
+	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+		values[n++] = leader->total_time_running +
+			atomic64_read(&leader->child_total_time_running);
+	}
+
+	size = n * sizeof(u64);
+
+	if (copy_to_user(buf, values, size))
+		return -EFAULT;
+
+	err = perf_event_read_entry(leader, read_format, buf + size);
+	if (err < 0)
+		return err;
+
+	size += err;
+
+	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
+		err = perf_event_read_entry(sub, read_format,
+				buf + size);
+		if (err < 0)
+			return err;
+
+		size += err;
+	}
+
+	return size;
+}
+
+static int perf_event_read_one(struct perf_event *event,
+				 u64 read_format, char __user *buf)
+{
+	u64 values[4];
+	int n = 0;
+
+	values[n++] = perf_event_read_value(event);
+	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+		values[n++] = event->total_time_enabled +
+			atomic64_read(&event->child_total_time_enabled);
+	}
+	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+		values[n++] = event->total_time_running +
+			atomic64_read(&event->child_total_time_running);
+	}
+	if (read_format & PERF_FORMAT_ID)
+		values[n++] = primary_event_id(event);
+
+	if (copy_to_user(buf, values, n * sizeof(u64)))
+		return -EFAULT;
+
+	return n * sizeof(u64);
+}
+
+/*
+ * Read the performance event - simple non blocking version for now
+ */
+static ssize_t
+perf_read_hw(struct perf_event *event, char __user *buf, size_t count)
+{
+	u64 read_format = event->attr.read_format;
+	int ret;
+
+	/*
+	 * Return end-of-file for a read on a event that is in
+	 * error state (i.e. because it was pinned but it couldn't be
+	 * scheduled on to the CPU at some point).
+	 */
+	if (event->state == PERF_EVENT_STATE_ERROR)
+		return 0;
+
+	if (count < perf_event_read_size(event))
+		return -ENOSPC;
+
+	WARN_ON_ONCE(event->ctx->parent_ctx);
+	mutex_lock(&event->child_mutex);
+	if (read_format & PERF_FORMAT_GROUP)
+		ret = perf_event_read_group(event, read_format, buf);
+	else
+		ret = perf_event_read_one(event, read_format, buf);
+	mutex_unlock(&event->child_mutex);
+
+	return ret;
+}
+
+static ssize_t
+perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+	struct perf_event *event = file->private_data;
+
+	return perf_read_hw(event, buf, count);
+}
+
+static unsigned int perf_poll(struct file *file, poll_table *wait)
+{
+	struct perf_event *event = file->private_data;
+	struct perf_mmap_data *data;
+	unsigned int events = POLL_HUP;
+
+	rcu_read_lock();
+	data = rcu_dereference(event->data);
+	if (data)
+		events = atomic_xchg(&data->poll, 0);
+	rcu_read_unlock();
+
+	poll_wait(file, &event->waitq, wait);
+
+	return events;
+}
+
+static void perf_event_reset(struct perf_event *event)
+{
+	(void)perf_event_read(event);
+	atomic64_set(&event->count, 0);
+	perf_event_update_userpage(event);
+}
+
+/*
+ * Holding the top-level event's child_mutex means that any
+ * descendant process that has inherited this event will block
+ * in sync_child_event if it goes to exit, thus satisfying the
+ * task existence requirements of perf_event_enable/disable.
+ */
+static void perf_event_for_each_child(struct perf_event *event,
+					void (*func)(struct perf_event *))
+{
+	struct perf_event *child;
+
+	WARN_ON_ONCE(event->ctx->parent_ctx);
+	mutex_lock(&event->child_mutex);
+	func(event);
+	list_for_each_entry(child, &event->child_list, child_list)
+		func(child);
+	mutex_unlock(&event->child_mutex);
+}
+
+static void perf_event_for_each(struct perf_event *event,
+				  void (*func)(struct perf_event *))
+{
+	struct perf_event_context *ctx = event->ctx;
+	struct perf_event *sibling;
+
+	WARN_ON_ONCE(ctx->parent_ctx);
+	mutex_lock(&ctx->mutex);
+	event = event->group_leader;
+
+	perf_event_for_each_child(event, func);
+	func(event);
+	list_for_each_entry(sibling, &event->sibling_list, group_entry)
+		perf_event_for_each_child(event, func);
+	mutex_unlock(&ctx->mutex);
+}
+
+static int perf_event_period(struct perf_event *event, u64 __user *arg)
+{
+	struct perf_event_context *ctx = event->ctx;
+	unsigned long size;
+	int ret = 0;
+	u64 value;
+
+	if (!event->attr.sample_period)
+		return -EINVAL;
+
+	size = copy_from_user(&value, arg, sizeof(value));
+	if (size != sizeof(value))
+		return -EFAULT;
+
+	if (!value)
+		return -EINVAL;
+
+	spin_lock_irq(&ctx->lock);
+	if (event->attr.freq) {
+		if (value > sysctl_perf_event_sample_rate) {
+			ret = -EINVAL;
+			goto unlock;
+		}
+
+		event->attr.sample_freq = value;
+	} else {
+		event->attr.sample_period = value;
+		event->hw.sample_period = value;
+	}
+unlock:
+	spin_unlock_irq(&ctx->lock);
+
+	return ret;
+}
+
+int perf_event_set_output(struct perf_event *event, int output_fd);
+
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct perf_event *event = file->private_data;
+	void (*func)(struct perf_event *);
+	u32 flags = arg;
+
+	switch (cmd) {
+	case PERF_EVENT_IOC_ENABLE:
+		func = perf_event_enable;
+		break;
+	case PERF_EVENT_IOC_DISABLE:
+		func = perf_event_disable;
+		break;
+	case PERF_EVENT_IOC_RESET:
+		func = perf_event_reset;
+		break;
+
+	case PERF_EVENT_IOC_REFRESH:
+		return perf_event_refresh(event, arg);
+
+	case PERF_EVENT_IOC_PERIOD:
+		return perf_event_period(event, (u64 __user *)arg);
+
+	case PERF_EVENT_IOC_SET_OUTPUT:
+		return perf_event_set_output(event, arg);
+
+	default:
+		return -ENOTTY;
+	}
+
+	if (flags & PERF_IOC_FLAG_GROUP)
+		perf_event_for_each(event, func);
+	else
+		perf_event_for_each_child(event, func);
+
+	return 0;
+}
+
+int perf_event_task_enable(void)
+{
+	struct perf_event *event;
+
+	mutex_lock(&current->perf_event_mutex);
+	list_for_each_entry(event, &current->perf_event_list, owner_entry)
+		perf_event_for_each_child(event, perf_event_enable);
+	mutex_unlock(&current->perf_event_mutex);
+
+	return 0;
+}
+
+int perf_event_task_disable(void)
+{
+	struct perf_event *event;
+
+	mutex_lock(&current->perf_event_mutex);
+	list_for_each_entry(event, &current->perf_event_list, owner_entry)
+		perf_event_for_each_child(event, perf_event_disable);
+	mutex_unlock(&current->perf_event_mutex);
+
+	return 0;
+}
+
+#ifndef PERF_EVENT_INDEX_OFFSET
+# define PERF_EVENT_INDEX_OFFSET 0
+#endif
+
+static int perf_event_index(struct perf_event *event)
+{
+	if (event->state != PERF_EVENT_STATE_ACTIVE)
+		return 0;
+
+	return event->hw.idx + 1 - PERF_EVENT_INDEX_OFFSET;
+}
+
+/*
+ * Callers need to ensure there can be no nesting of this function, otherwise
+ * the seqlock logic goes bad. We can not serialize this because the arch
+ * code calls this from NMI context.
+ */
+void perf_event_update_userpage(struct perf_event *event)
+{
+	struct perf_event_mmap_page *userpg;
+	struct perf_mmap_data *data;
+
+	rcu_read_lock();
+	data = rcu_dereference(event->data);
+	if (!data)
+		goto unlock;
+
+	userpg = data->user_page;
+
+	/*
+	 * Disable preemption so as to not let the corresponding user-space
+	 * spin too long if we get preempted.
+	 */
+	preempt_disable();
+	++userpg->lock;
+	barrier();
+	userpg->index = perf_event_index(event);
+	userpg->offset = atomic64_read(&event->count);
+	if (event->state == PERF_EVENT_STATE_ACTIVE)
+		userpg->offset -= atomic64_read(&event->hw.prev_count);
+
+	userpg->time_enabled = event->total_time_enabled +
+			atomic64_read(&event->child_total_time_enabled);
+
+	userpg->time_running = event->total_time_running +
+			atomic64_read(&event->child_total_time_running);
+
+	barrier();
+	++userpg->lock;
+	preempt_enable();
+unlock:
+	rcu_read_unlock();
+}
+
+static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct perf_event *event = vma->vm_file->private_data;
+	struct perf_mmap_data *data;
+	int ret = VM_FAULT_SIGBUS;
+
+	if (vmf->flags & FAULT_FLAG_MKWRITE) {
+		if (vmf->pgoff == 0)
+			ret = 0;
+		return ret;
+	}
+
+	rcu_read_lock();
+	data = rcu_dereference(event->data);
+	if (!data)
+		goto unlock;
+
+	if (vmf->pgoff == 0) {
+		vmf->page = virt_to_page(data->user_page);
+	} else {
+		int nr = vmf->pgoff - 1;
+
+		if ((unsigned)nr > data->nr_pages)
+			goto unlock;
+
+		if (vmf->flags & FAULT_FLAG_WRITE)
+			goto unlock;
+
+		vmf->page = virt_to_page(data->data_pages[nr]);
+	}
+
+	get_page(vmf->page);
+	vmf->page->mapping = vma->vm_file->f_mapping;
+	vmf->page->index   = vmf->pgoff;
+
+	ret = 0;
+unlock:
+	rcu_read_unlock();
+
+	return ret;
+}
+
+static int perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
+{
+	struct perf_mmap_data *data;
+	unsigned long size;
+	int i;
+
+	WARN_ON(atomic_read(&event->mmap_count));
+
+	size = sizeof(struct perf_mmap_data);
+	size += nr_pages * sizeof(void *);
+
+	data = kzalloc(size, GFP_KERNEL);
+	if (!data)
+		goto fail;
+
+	data->user_page = (void *)get_zeroed_page(GFP_KERNEL);
+	if (!data->user_page)
+		goto fail_user_page;
+
+	for (i = 0; i < nr_pages; i++) {
+		data->data_pages[i] = (void *)get_zeroed_page(GFP_KERNEL);
+		if (!data->data_pages[i])
+			goto fail_data_pages;
+	}
+
+	data->nr_pages = nr_pages;
+	atomic_set(&data->lock, -1);
+
+	if (event->attr.watermark) {
+		data->watermark = min_t(long, PAGE_SIZE * nr_pages,
+				      event->attr.wakeup_watermark);
+	}
+	if (!data->watermark)
+		data->watermark = max(PAGE_SIZE, PAGE_SIZE * nr_pages / 4);
+
+	rcu_assign_pointer(event->data, data);
+
+	return 0;
+
+fail_data_pages:
+	for (i--; i >= 0; i--)
+		free_page((unsigned long)data->data_pages[i]);
+
+	free_page((unsigned long)data->user_page);
+
+fail_user_page:
+	kfree(data);
+
+fail:
+	return -ENOMEM;
+}
+
+static void perf_mmap_free_page(unsigned long addr)
+{
+	struct page *page = virt_to_page((void *)addr);
+
+	page->mapping = NULL;
+	__free_page(page);
+}
+
+static void __perf_mmap_data_free(struct rcu_head *rcu_head)
+{
+	struct perf_mmap_data *data;
+	int i;
+
+	data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
+
+	perf_mmap_free_page((unsigned long)data->user_page);
+	for (i = 0; i < data->nr_pages; i++)
+		perf_mmap_free_page((unsigned long)data->data_pages[i]);
+
+	kfree(data);
+}
+
+static void perf_mmap_data_free(struct perf_event *event)
+{
+	struct perf_mmap_data *data = event->data;
+
+	WARN_ON(atomic_read(&event->mmap_count));
+
+	rcu_assign_pointer(event->data, NULL);
+	call_rcu(&data->rcu_head, __perf_mmap_data_free);
+}
+
+static void perf_mmap_open(struct vm_area_struct *vma)
+{
+	struct perf_event *event = vma->vm_file->private_data;
+
+	atomic_inc(&event->mmap_count);
+}
+
+static void perf_mmap_close(struct vm_area_struct *vma)
+{
+	struct perf_event *event = vma->vm_file->private_data;
+
+	WARN_ON_ONCE(event->ctx->parent_ctx);
+	if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
+		struct user_struct *user = current_user();
+
+		atomic_long_sub(event->data->nr_pages + 1, &user->locked_vm);
+		vma->vm_mm->locked_vm -= event->data->nr_locked;
+		perf_mmap_data_free(event);
+		mutex_unlock(&event->mmap_mutex);
+	}
+}
+
+static struct vm_operations_struct perf_mmap_vmops = {
+	.open		= perf_mmap_open,
+	.close		= perf_mmap_close,
+	.fault		= perf_mmap_fault,
+	.page_mkwrite	= perf_mmap_fault,
+};
+
+static int perf_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct perf_event *event = file->private_data;
+	unsigned long user_locked, user_lock_limit;
+	struct user_struct *user = current_user();
+	unsigned long locked, lock_limit;
+	unsigned long vma_size;
+	unsigned long nr_pages;
+	long user_extra, extra;
+	int ret = 0;
+
+	if (!(vma->vm_flags & VM_SHARED))
+		return -EINVAL;
+
+	vma_size = vma->vm_end - vma->vm_start;
+	nr_pages = (vma_size / PAGE_SIZE) - 1;
+
+	/*
+	 * If we have data pages ensure they're a power-of-two number, so we
+	 * can do bitmasks instead of modulo.
+	 */
+	if (nr_pages != 0 && !is_power_of_2(nr_pages))
+		return -EINVAL;
+
+	if (vma_size != PAGE_SIZE * (1 + nr_pages))
+		return -EINVAL;
+
+	if (vma->vm_pgoff != 0)
+		return -EINVAL;
+
+	WARN_ON_ONCE(event->ctx->parent_ctx);
+	mutex_lock(&event->mmap_mutex);
+	if (event->output) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (atomic_inc_not_zero(&event->mmap_count)) {
+		if (nr_pages != event->data->nr_pages)
+			ret = -EINVAL;
+		goto unlock;
+	}
+
+	user_extra = nr_pages + 1;
+	user_lock_limit = sysctl_perf_event_mlock >> (PAGE_SHIFT - 10);
+
+	/*
+	 * Increase the limit linearly with more CPUs:
+	 */
+	user_lock_limit *= num_online_cpus();
+
+	user_locked = atomic_long_read(&user->locked_vm) + user_extra;
+
+	extra = 0;
+	if (user_locked > user_lock_limit)
+		extra = user_locked - user_lock_limit;
+
+	lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
+	lock_limit >>= PAGE_SHIFT;
+	locked = vma->vm_mm->locked_vm + extra;
+
+	if ((locked > lock_limit) && perf_paranoid_tracepoint_raw() &&
+		!capable(CAP_IPC_LOCK)) {
+		ret = -EPERM;
+		goto unlock;
+	}
+
+	WARN_ON(event->data);
+	ret = perf_mmap_data_alloc(event, nr_pages);
+	if (ret)
+		goto unlock;
+
+	atomic_set(&event->mmap_count, 1);
+	atomic_long_add(user_extra, &user->locked_vm);
+	vma->vm_mm->locked_vm += extra;
+	event->data->nr_locked = extra;
+	if (vma->vm_flags & VM_WRITE)
+		event->data->writable = 1;
+
+unlock:
+	mutex_unlock(&event->mmap_mutex);
+
+	vma->vm_flags |= VM_RESERVED;
+	vma->vm_ops = &perf_mmap_vmops;
+
+	return ret;
+}
+
+static int perf_fasync(int fd, struct file *filp, int on)
+{
+	struct inode *inode = filp->f_path.dentry->d_inode;
+	struct perf_event *event = filp->private_data;
+	int retval;
+
+	mutex_lock(&inode->i_mutex);
+	retval = fasync_helper(fd, filp, on, &event->fasync);
+	mutex_unlock(&inode->i_mutex);
+
+	if (retval < 0)
+		return retval;
+
+	return 0;
+}
+
+static const struct file_operations perf_fops = {
+	.release		= perf_release,
+	.read			= perf_read,
+	.poll			= perf_poll,
+	.unlocked_ioctl		= perf_ioctl,
+	.compat_ioctl		= perf_ioctl,
+	.mmap			= perf_mmap,
+	.fasync			= perf_fasync,
+};
+
+/*
+ * Perf event wakeup
+ *
+ * If there's data, ensure we set the poll() state and publish everything
+ * to user-space before waking everybody up.
+ */
+
+void perf_event_wakeup(struct perf_event *event)
+{
+	wake_up_all(&event->waitq);
+
+	if (event->pending_kill) {
+		kill_fasync(&event->fasync, SIGIO, event->pending_kill);
+		event->pending_kill = 0;
+	}
+}
+
+/*
+ * Pending wakeups
+ *
+ * Handle the case where we need to wakeup up from NMI (or rq->lock) context.
+ *
+ * The NMI bit means we cannot possibly take locks. Therefore, maintain a
+ * single linked list and use cmpxchg() to add entries lockless.
+ */
+
+static void perf_pending_event(struct perf_pending_entry *entry)
+{
+	struct perf_event *event = container_of(entry,
+			struct perf_event, pending);
+
+	if (event->pending_disable) {
+		event->pending_disable = 0;
+		__perf_event_disable(event);
+	}
+
+	if (event->pending_wakeup) {
+		event->pending_wakeup = 0;
+		perf_event_wakeup(event);
+	}
+}
+
+#define PENDING_TAIL ((struct perf_pending_entry *)-1UL)
+
+static DEFINE_PER_CPU(struct perf_pending_entry *, perf_pending_head) = {
+	PENDING_TAIL,
+};
+
+static void perf_pending_queue(struct perf_pending_entry *entry,
+			       void (*func)(struct perf_pending_entry *))
+{
+	struct perf_pending_entry **head;
+
+	if (cmpxchg(&entry->next, NULL, PENDING_TAIL) != NULL)
+		return;
+
+	entry->func = func;
+
+	head = &get_cpu_var(perf_pending_head);
+
+	do {
+		entry->next = *head;
+	} while (cmpxchg(head, entry->next, entry) != entry->next);
+
+	set_perf_event_pending();
+
+	put_cpu_var(perf_pending_head);
+}
+
+static int __perf_pending_run(void)
+{
+	struct perf_pending_entry *list;
+	int nr = 0;
+
+	list = xchg(&__get_cpu_var(perf_pending_head), PENDING_TAIL);
+	while (list != PENDING_TAIL) {
+		void (*func)(struct perf_pending_entry *);
+		struct perf_pending_entry *entry = list;
+
+		list = list->next;
+
+		func = entry->func;
+		entry->next = NULL;
+		/*
+		 * Ensure we observe the unqueue before we issue the wakeup,
+		 * so that we won't be waiting forever.
+		 * -- see perf_not_pending().
+		 */
+		smp_wmb();
+
+		func(entry);
+		nr++;
+	}
+
+	return nr;
+}
+
+static inline int perf_not_pending(struct perf_event *event)
+{
+	/*
+	 * If we flush on whatever cpu we run, there is a chance we don't
+	 * need to wait.
+	 */
+	get_cpu();
+	__perf_pending_run();
+	put_cpu();
+
+	/*
+	 * Ensure we see the proper queue state before going to sleep
+	 * so that we do not miss the wakeup. -- see perf_pending_handle()
+	 */
+	smp_rmb();
+	return event->pending.next == NULL;
+}
+
+static void perf_pending_sync(struct perf_event *event)
+{
+	wait_event(event->waitq, perf_not_pending(event));
+}
+
+void perf_event_do_pending(void)
+{
+	__perf_pending_run();
+}
+
+/*
+ * Callchain support -- arch specific
+ */
+
+__weak struct perf_callchain_entry *perf_callchain(struct pt_regs *regs)
+{
+	return NULL;
+}
+
+/*
+ * Output
+ */
+static bool perf_output_space(struct perf_mmap_data *data, unsigned long tail,
+			      unsigned long offset, unsigned long head)
+{
+	unsigned long mask;
+
+	if (!data->writable)
+		return true;
+
+	mask = (data->nr_pages << PAGE_SHIFT) - 1;
+
+	offset = (offset - tail) & mask;
+	head   = (head   - tail) & mask;
+
+	if ((int)(head - offset) < 0)
+		return false;
+
+	return true;
+}
+
+static void perf_output_wakeup(struct perf_output_handle *handle)
+{
+	atomic_set(&handle->data->poll, POLL_IN);
+
+	if (handle->nmi) {
+		handle->event->pending_wakeup = 1;
+		perf_pending_queue(&handle->event->pending,
+				   perf_pending_event);
+	} else
+		perf_event_wakeup(handle->event);
+}
+
+/*
+ * Curious locking construct.
+ *
+ * We need to ensure a later event_id doesn't publish a head when a former
+ * event_id isn't done writing. However since we need to deal with NMIs we
+ * cannot fully serialize things.
+ *
+ * What we do is serialize between CPUs so we only have to deal with NMI
+ * nesting on a single CPU.
+ *
+ * We only publish the head (and generate a wakeup) when the outer-most
+ * event_id completes.
+ */
+static void perf_output_lock(struct perf_output_handle *handle)
+{
+	struct perf_mmap_data *data = handle->data;
+	int cpu;
+
+	handle->locked = 0;
+
+	local_irq_save(handle->flags);
+	cpu = smp_processor_id();
+
+	if (in_nmi() && atomic_read(&data->lock) == cpu)
+		return;
+
+	while (atomic_cmpxchg(&data->lock, -1, cpu) != -1)
+		cpu_relax();
+
+	handle->locked = 1;
+}
+
+static void perf_output_unlock(struct perf_output_handle *handle)
+{
+	struct perf_mmap_data *data = handle->data;
+	unsigned long head;
+	int cpu;
+
+	data->done_head = data->head;
+
+	if (!handle->locked)
+		goto out;
+
+again:
+	/*
+	 * The xchg implies a full barrier that ensures all writes are done
+	 * before we publish the new head, matched by a rmb() in userspace when
+	 * reading this position.
+	 */
+	while ((head = atomic_long_xchg(&data->done_head, 0)))
+		data->user_page->data_head = head;
+
+	/*
+	 * NMI can happen here, which means we can miss a done_head update.
+	 */
+
+	cpu = atomic_xchg(&data->lock, -1);
+	WARN_ON_ONCE(cpu != smp_processor_id());
+
+	/*
+	 * Therefore we have to validate we did not indeed do so.
+	 */
+	if (unlikely(atomic_long_read(&data->done_head))) {
+		/*
+		 * Since we had it locked, we can lock it again.
+		 */
+		while (atomic_cmpxchg(&data->lock, -1, cpu) != -1)
+			cpu_relax();
+
+		goto again;
+	}
+
+	if (atomic_xchg(&data->wakeup, 0))
+		perf_output_wakeup(handle);
+out:
+	local_irq_restore(handle->flags);
+}
+
+void perf_output_copy(struct perf_output_handle *handle,
+		      const void *buf, unsigned int len)
+{
+	unsigned int pages_mask;
+	unsigned int offset;
+	unsigned int size;
+	void **pages;
+
+	offset		= handle->offset;
+	pages_mask	= handle->data->nr_pages - 1;
+	pages		= handle->data->data_pages;
+
+	do {
+		unsigned int page_offset;
+		int nr;
+
+		nr	    = (offset >> PAGE_SHIFT) & pages_mask;
+		page_offset = offset & (PAGE_SIZE - 1);
+		size	    = min_t(unsigned int, PAGE_SIZE - page_offset, len);
+
+		memcpy(pages[nr] + page_offset, buf, size);
+
+		len	    -= size;
+		buf	    += size;
+		offset	    += size;
+	} while (len);
+
+	handle->offset = offset;
+
+	/*
+	 * Check we didn't copy past our reservation window, taking the
+	 * possible unsigned int wrap into account.
+	 */
+	WARN_ON_ONCE(((long)(handle->head - handle->offset)) < 0);
+}
+
+int perf_output_begin(struct perf_output_handle *handle,
+		      struct perf_event *event, unsigned int size,
+		      int nmi, int sample)
+{
+	struct perf_event *output_event;
+	struct perf_mmap_data *data;
+	unsigned long tail, offset, head;
+	int have_lost;
+	struct {
+		struct perf_event_header header;
+		u64			 id;
+		u64			 lost;
+	} lost_event;
+
+	rcu_read_lock();
+	/*
+	 * For inherited events we send all the output towards the parent.
+	 */
+	if (event->parent)
+		event = event->parent;
+
+	output_event = rcu_dereference(event->output);
+	if (output_event)
+		event = output_event;
+
+	data = rcu_dereference(event->data);
+	if (!data)
+		goto out;
+
+	handle->data	= data;
+	handle->event	= event;
+	handle->nmi	= nmi;
+	handle->sample	= sample;
+
+	if (!data->nr_pages)
+		goto fail;
+
+	have_lost = atomic_read(&data->lost);
+	if (have_lost)
+		size += sizeof(lost_event);
+
+	perf_output_lock(handle);
+
+	do {
+		/*
+		 * Userspace could choose to issue a mb() before updating the
+		 * tail pointer. So that all reads will be completed before the
+		 * write is issued.
+		 */
+		tail = ACCESS_ONCE(data->user_page->data_tail);
+		smp_rmb();
+		offset = head = atomic_long_read(&data->head);
+		head += size;
+		if (unlikely(!perf_output_space(data, tail, offset, head)))
+			goto fail;
+	} while (atomic_long_cmpxchg(&data->head, offset, head) != offset);
+
+	handle->offset	= offset;
+	handle->head	= head;
+
+	if (head - tail > data->watermark)
+		atomic_set(&data->wakeup, 1);
+
+	if (have_lost) {
+		lost_event.header.type = PERF_RECORD_LOST;
+		lost_event.header.misc = 0;
+		lost_event.header.size = sizeof(lost_event);
+		lost_event.id          = event->id;
+		lost_event.lost        = atomic_xchg(&data->lost, 0);
+
+		perf_output_put(handle, lost_event);
+	}
+
+	return 0;
+
+fail:
+	atomic_inc(&data->lost);
+	perf_output_unlock(handle);
+out:
+	rcu_read_unlock();
+
+	return -ENOSPC;
+}
+
+void perf_output_end(struct perf_output_handle *handle)
+{
+	struct perf_event *event = handle->event;
+	struct perf_mmap_data *data = handle->data;
+
+	int wakeup_events = event->attr.wakeup_events;
+
+	if (handle->sample && wakeup_events) {
+		int events = atomic_inc_return(&data->events);
+		if (events >= wakeup_events) {
+			atomic_sub(wakeup_events, &data->events);
+			atomic_set(&data->wakeup, 1);
+		}
+	}
+
+	perf_output_unlock(handle);
+	rcu_read_unlock();
+}
+
+static u32 perf_event_pid(struct perf_event *event, struct task_struct *p)
+{
+	/*
+	 * only top level events have the pid namespace they were created in
+	 */
+	if (event->parent)
+		event = event->parent;
+
+	return task_tgid_nr_ns(p, event->ns);
+}
+
+static u32 perf_event_tid(struct perf_event *event, struct task_struct *p)
+{
+	/*
+	 * only top level events have the pid namespace they were created in
+	 */
+	if (event->parent)
+		event = event->parent;
+
+	return task_pid_nr_ns(p, event->ns);
+}
+
+static void perf_output_read_one(struct perf_output_handle *handle,
+				 struct perf_event *event)
+{
+	u64 read_format = event->attr.read_format;
+	u64 values[4];
+	int n = 0;
+
+	values[n++] = atomic64_read(&event->count);
+	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+		values[n++] = event->total_time_enabled +
+			atomic64_read(&event->child_total_time_enabled);
+	}
+	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+		values[n++] = event->total_time_running +
+			atomic64_read(&event->child_total_time_running);
+	}
+	if (read_format & PERF_FORMAT_ID)
+		values[n++] = primary_event_id(event);
+
+	perf_output_copy(handle, values, n * sizeof(u64));
+}
+
+/*
+ * XXX PERF_FORMAT_GROUP vs inherited events seems difficult.
+ */
+static void perf_output_read_group(struct perf_output_handle *handle,
+			    struct perf_event *event)
+{
+	struct perf_event *leader = event->group_leader, *sub;
+	u64 read_format = event->attr.read_format;
+	u64 values[5];
+	int n = 0;
+
+	values[n++] = 1 + leader->nr_siblings;
+
+	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+		values[n++] = leader->total_time_enabled;
+
+	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+		values[n++] = leader->total_time_running;
+
+	if (leader != event)
+		leader->pmu->read(leader);
+
+	values[n++] = atomic64_read(&leader->count);
+	if (read_format & PERF_FORMAT_ID)
+		values[n++] = primary_event_id(leader);
+
+	perf_output_copy(handle, values, n * sizeof(u64));
+
+	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
+		n = 0;
+
+		if (sub != event)
+			sub->pmu->read(sub);
+
+		values[n++] = atomic64_read(&sub->count);
+		if (read_format & PERF_FORMAT_ID)
+			values[n++] = primary_event_id(sub);
+
+		perf_output_copy(handle, values, n * sizeof(u64));
+	}
+}
+
+static void perf_output_read(struct perf_output_handle *handle,
+			     struct perf_event *event)
+{
+	if (event->attr.read_format & PERF_FORMAT_GROUP)
+		perf_output_read_group(handle, event);
+	else
+		perf_output_read_one(handle, event);
+}
+
+void perf_output_sample(struct perf_output_handle *handle,
+			struct perf_event_header *header,
+			struct perf_sample_data *data,
+			struct perf_event *event)
+{
+	u64 sample_type = data->type;
+
+	perf_output_put(handle, *header);
+
+	if (sample_type & PERF_SAMPLE_IP)
+		perf_output_put(handle, data->ip);
+
+	if (sample_type & PERF_SAMPLE_TID)
+		perf_output_put(handle, data->tid_entry);
+
+	if (sample_type & PERF_SAMPLE_TIME)
+		perf_output_put(handle, data->time);
+
+	if (sample_type & PERF_SAMPLE_ADDR)
+		perf_output_put(handle, data->addr);
+
+	if (sample_type & PERF_SAMPLE_ID)
+		perf_output_put(handle, data->id);
+
+	if (sample_type & PERF_SAMPLE_STREAM_ID)
+		perf_output_put(handle, data->stream_id);
+
+	if (sample_type & PERF_SAMPLE_CPU)
+		perf_output_put(handle, data->cpu_entry);
+
+	if (sample_type & PERF_SAMPLE_PERIOD)
+		perf_output_put(handle, data->period);
+
+	if (sample_type & PERF_SAMPLE_READ)
+		perf_output_read(handle, event);
+
+	if (sample_type & PERF_SAMPLE_CALLCHAIN) {
+		if (data->callchain) {
+			int size = 1;
+
+			if (data->callchain)
+				size += data->callchain->nr;
+
+			size *= sizeof(u64);
+
+			perf_output_copy(handle, data->callchain, size);
+		} else {
+			u64 nr = 0;
+			perf_output_put(handle, nr);
+		}
+	}
+
+	if (sample_type & PERF_SAMPLE_RAW) {
+		if (data->raw) {
+			perf_output_put(handle, data->raw->size);
+			perf_output_copy(handle, data->raw->data,
+					 data->raw->size);
+		} else {
+			struct {
+				u32	size;
+				u32	data;
+			} raw = {
+				.size = sizeof(u32),
+				.data = 0,
+			};
+			perf_output_put(handle, raw);
+		}
+	}
+}
+
+void perf_prepare_sample(struct perf_event_header *header,
+			 struct perf_sample_data *data,
+			 struct perf_event *event,
+			 struct pt_regs *regs)
+{
+	u64 sample_type = event->attr.sample_type;
+
+	data->type = sample_type;
+
+	header->type = PERF_RECORD_SAMPLE;
+	header->size = sizeof(*header);
+
+	header->misc = 0;
+	header->misc |= perf_misc_flags(regs);
+
+	if (sample_type & PERF_SAMPLE_IP) {
+		data->ip = perf_instruction_pointer(regs);
+
+		header->size += sizeof(data->ip);
+	}
+
+	if (sample_type & PERF_SAMPLE_TID) {
+		/* namespace issues */
+		data->tid_entry.pid = perf_event_pid(event, current);
+		data->tid_entry.tid = perf_event_tid(event, current);
+
+		header->size += sizeof(data->tid_entry);
+	}
+
+	if (sample_type & PERF_SAMPLE_TIME) {
+		data->time = perf_clock();
+
+		header->size += sizeof(data->time);
+	}
+
+	if (sample_type & PERF_SAMPLE_ADDR)
+		header->size += sizeof(data->addr);
+
+	if (sample_type & PERF_SAMPLE_ID) {
+		data->id = primary_event_id(event);
+
+		header->size += sizeof(data->id);
+	}
+
+	if (sample_type & PERF_SAMPLE_STREAM_ID) {
+		data->stream_id = event->id;
+
+		header->size += sizeof(data->stream_id);
+	}
+
+	if (sample_type & PERF_SAMPLE_CPU) {
+		data->cpu_entry.cpu		= raw_smp_processor_id();
+		data->cpu_entry.reserved	= 0;
+
+		header->size += sizeof(data->cpu_entry);
+	}
+
+	if (sample_type & PERF_SAMPLE_PERIOD)
+		header->size += sizeof(data->period);
+
+	if (sample_type & PERF_SAMPLE_READ)
+		header->size += perf_event_read_size(event);
+
+	if (sample_type & PERF_SAMPLE_CALLCHAIN) {
+		int size = 1;
+
+		data->callchain = perf_callchain(regs);
+
+		if (data->callchain)
+			size += data->callchain->nr;
+
+		header->size += size * sizeof(u64);
+	}
+
+	if (sample_type & PERF_SAMPLE_RAW) {
+		int size = sizeof(u32);
+
+		if (data->raw)
+			size += data->raw->size;
+		else
+			size += sizeof(u32);
+
+		WARN_ON_ONCE(size & (sizeof(u64)-1));
+		header->size += size;
+	}
+}
+
+static void perf_event_output(struct perf_event *event, int nmi,
+				struct perf_sample_data *data,
+				struct pt_regs *regs)
+{
+	struct perf_output_handle handle;
+	struct perf_event_header header;
+
+	perf_prepare_sample(&header, data, event, regs);
+
+	if (perf_output_begin(&handle, event, header.size, nmi, 1))
+		return;
+
+	perf_output_sample(&handle, &header, data, event);
+
+	perf_output_end(&handle);
+}
+
+/*
+ * read event_id
+ */
+
+struct perf_read_event {
+	struct perf_event_header	header;
+
+	u32				pid;
+	u32				tid;
+};
+
+static void
+perf_event_read_event(struct perf_event *event,
+			struct task_struct *task)
+{
+	struct perf_output_handle handle;
+	struct perf_read_event read_event = {
+		.header = {
+			.type = PERF_RECORD_READ,
+			.misc = 0,
+			.size = sizeof(read_event) + perf_event_read_size(event),
+		},
+		.pid = perf_event_pid(event, task),
+		.tid = perf_event_tid(event, task),
+	};
+	int ret;
+
+	ret = perf_output_begin(&handle, event, read_event.header.size, 0, 0);
+	if (ret)
+		return;
+
+	perf_output_put(&handle, read_event);
+	perf_output_read(&handle, event);
+
+	perf_output_end(&handle);
+}
+
+/*
+ * task tracking -- fork/exit
+ *
+ * enabled by: attr.comm | attr.mmap | attr.task
+ */
+
+struct perf_task_event {
+	struct task_struct		*task;
+	struct perf_event_context	*task_ctx;
+
+	struct {
+		struct perf_event_header	header;
+
+		u32				pid;
+		u32				ppid;
+		u32				tid;
+		u32				ptid;
+		u64				time;
+	} event_id;
+};
+
+static void perf_event_task_output(struct perf_event *event,
+				     struct perf_task_event *task_event)
+{
+	struct perf_output_handle handle;
+	int size;
+	struct task_struct *task = task_event->task;
+	int ret;
+
+	size  = task_event->event_id.header.size;
+	ret = perf_output_begin(&handle, event, size, 0, 0);
+
+	if (ret)
+		return;
+
+	task_event->event_id.pid = perf_event_pid(event, task);
+	task_event->event_id.ppid = perf_event_pid(event, current);
+
+	task_event->event_id.tid = perf_event_tid(event, task);
+	task_event->event_id.ptid = perf_event_tid(event, current);
+
+	task_event->event_id.time = perf_clock();
+
+	perf_output_put(&handle, task_event->event_id);
+
+	perf_output_end(&handle);
+}
+
+static int perf_event_task_match(struct perf_event *event)
+{
+	if (event->attr.comm || event->attr.mmap || event->attr.task)
+		return 1;
+
+	return 0;
+}
+
+static void perf_event_task_ctx(struct perf_event_context *ctx,
+				  struct perf_task_event *task_event)
+{
+	struct perf_event *event;
+
+	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
+		return;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+		if (perf_event_task_match(event))
+			perf_event_task_output(event, task_event);
+	}
+	rcu_read_unlock();
+}
+
+static void perf_event_task_event(struct perf_task_event *task_event)
+{
+	struct perf_cpu_context *cpuctx;
+	struct perf_event_context *ctx = task_event->task_ctx;
+
+	cpuctx = &get_cpu_var(perf_cpu_context);
+	perf_event_task_ctx(&cpuctx->ctx, task_event);
+	put_cpu_var(perf_cpu_context);
+
+	rcu_read_lock();
+	if (!ctx)
+		ctx = rcu_dereference(task_event->task->perf_event_ctxp);
+	if (ctx)
+		perf_event_task_ctx(ctx, task_event);
+	rcu_read_unlock();
+}
+
+static void perf_event_task(struct task_struct *task,
+			      struct perf_event_context *task_ctx,
+			      int new)
+{
+	struct perf_task_event task_event;
+
+	if (!atomic_read(&nr_comm_events) &&
+	    !atomic_read(&nr_mmap_events) &&
+	    !atomic_read(&nr_task_events))
+		return;
+
+	task_event = (struct perf_task_event){
+		.task	  = task,
+		.task_ctx = task_ctx,
+		.event_id    = {
+			.header = {
+				.type = new ? PERF_RECORD_FORK : PERF_RECORD_EXIT,
+				.misc = 0,
+				.size = sizeof(task_event.event_id),
+			},
+			/* .pid  */
+			/* .ppid */
+			/* .tid  */
+			/* .ptid */
+		},
+	};
+
+	perf_event_task_event(&task_event);
+}
+
+void perf_event_fork(struct task_struct *task)
+{
+	perf_event_task(task, NULL, 1);
+}
+
+/*
+ * comm tracking
+ */
+
+struct perf_comm_event {
+	struct task_struct	*task;
+	char			*comm;
+	int			comm_size;
+
+	struct {
+		struct perf_event_header	header;
+
+		u32				pid;
+		u32				tid;
+	} event_id;
+};
+
+static void perf_event_comm_output(struct perf_event *event,
+				     struct perf_comm_event *comm_event)
+{
+	struct perf_output_handle handle;
+	int size = comm_event->event_id.header.size;
+	int ret = perf_output_begin(&handle, event, size, 0, 0);
+
+	if (ret)
+		return;
+
+	comm_event->event_id.pid = perf_event_pid(event, comm_event->task);
+	comm_event->event_id.tid = perf_event_tid(event, comm_event->task);
+
+	perf_output_put(&handle, comm_event->event_id);
+	perf_output_copy(&handle, comm_event->comm,
+				   comm_event->comm_size);
+	perf_output_end(&handle);
+}
+
+static int perf_event_comm_match(struct perf_event *event)
+{
+	if (event->attr.comm)
+		return 1;
+
+	return 0;
+}
+
+static void perf_event_comm_ctx(struct perf_event_context *ctx,
+				  struct perf_comm_event *comm_event)
+{
+	struct perf_event *event;
+
+	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
+		return;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+		if (perf_event_comm_match(event))
+			perf_event_comm_output(event, comm_event);
+	}
+	rcu_read_unlock();
+}
+
+static void perf_event_comm_event(struct perf_comm_event *comm_event)
+{
+	struct perf_cpu_context *cpuctx;
+	struct perf_event_context *ctx;
+	unsigned int size;
+	char comm[TASK_COMM_LEN];
+
+	memset(comm, 0, sizeof(comm));
+	strncpy(comm, comm_event->task->comm, sizeof(comm));
+	size = ALIGN(strlen(comm)+1, sizeof(u64));
+
+	comm_event->comm = comm;
+	comm_event->comm_size = size;
+
+	comm_event->event_id.header.size = sizeof(comm_event->event_id) + size;
+
+	cpuctx = &get_cpu_var(perf_cpu_context);
+	perf_event_comm_ctx(&cpuctx->ctx, comm_event);
+	put_cpu_var(perf_cpu_context);
+
+	rcu_read_lock();
+	/*
+	 * doesn't really matter which of the child contexts the
+	 * events ends up in.
+	 */
+	ctx = rcu_dereference(current->perf_event_ctxp);
+	if (ctx)
+		perf_event_comm_ctx(ctx, comm_event);
+	rcu_read_unlock();
+}
+
+void perf_event_comm(struct task_struct *task)
+{
+	struct perf_comm_event comm_event;
+
+	if (task->perf_event_ctxp)
+		perf_event_enable_on_exec(task);
+
+	if (!atomic_read(&nr_comm_events))
+		return;
+
+	comm_event = (struct perf_comm_event){
+		.task	= task,
+		/* .comm      */
+		/* .comm_size */
+		.event_id  = {
+			.header = {
+				.type = PERF_RECORD_COMM,
+				.misc = 0,
+				/* .size */
+			},
+			/* .pid */
+			/* .tid */
+		},
+	};
+
+	perf_event_comm_event(&comm_event);
+}
+
+/*
+ * mmap tracking
+ */
+
+struct perf_mmap_event {
+	struct vm_area_struct	*vma;
+
+	const char		*file_name;
+	int			file_size;
+
+	struct {
+		struct perf_event_header	header;
+
+		u32				pid;
+		u32				tid;
+		u64				start;
+		u64				len;
+		u64				pgoff;
+	} event_id;
+};
+
+static void perf_event_mmap_output(struct perf_event *event,
+				     struct perf_mmap_event *mmap_event)
+{
+	struct perf_output_handle handle;
+	int size = mmap_event->event_id.header.size;
+	int ret = perf_output_begin(&handle, event, size, 0, 0);
+
+	if (ret)
+		return;
+
+	mmap_event->event_id.pid = perf_event_pid(event, current);
+	mmap_event->event_id.tid = perf_event_tid(event, current);
+
+	perf_output_put(&handle, mmap_event->event_id);
+	perf_output_copy(&handle, mmap_event->file_name,
+				   mmap_event->file_size);
+	perf_output_end(&handle);
+}
+
+static int perf_event_mmap_match(struct perf_event *event,
+				   struct perf_mmap_event *mmap_event)
+{
+	if (event->attr.mmap)
+		return 1;
+
+	return 0;
+}
+
+static void perf_event_mmap_ctx(struct perf_event_context *ctx,
+				  struct perf_mmap_event *mmap_event)
+{
+	struct perf_event *event;
+
+	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
+		return;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+		if (perf_event_mmap_match(event, mmap_event))
+			perf_event_mmap_output(event, mmap_event);
+	}
+	rcu_read_unlock();
+}
+
+static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
+{
+	struct perf_cpu_context *cpuctx;
+	struct perf_event_context *ctx;
+	struct vm_area_struct *vma = mmap_event->vma;
+	struct file *file = vma->vm_file;
+	unsigned int size;
+	char tmp[16];
+	char *buf = NULL;
+	const char *name;
+
+	memset(tmp, 0, sizeof(tmp));
+
+	if (file) {
+		/*
+		 * d_path works from the end of the buffer backwards, so we
+		 * need to add enough zero bytes after the string to handle
+		 * the 64bit alignment we do later.
+		 */
+		buf = kzalloc(PATH_MAX + sizeof(u64), GFP_KERNEL);
+		if (!buf) {
+			name = strncpy(tmp, "//enomem", sizeof(tmp));
+			goto got_name;
+		}
+		name = d_path(&file->f_path, buf, PATH_MAX);
+		if (IS_ERR(name)) {
+			name = strncpy(tmp, "//toolong", sizeof(tmp));
+			goto got_name;
+		}
+	} else {
+		if (arch_vma_name(mmap_event->vma)) {
+			name = strncpy(tmp, arch_vma_name(mmap_event->vma),
+				       sizeof(tmp));
+			goto got_name;
+		}
+
+		if (!vma->vm_mm) {
+			name = strncpy(tmp, "[vdso]", sizeof(tmp));
+			goto got_name;
+		}
+
+		name = strncpy(tmp, "//anon", sizeof(tmp));
+		goto got_name;
+	}
+
+got_name:
+	size = ALIGN(strlen(name)+1, sizeof(u64));
+
+	mmap_event->file_name = name;
+	mmap_event->file_size = size;
+
+	mmap_event->event_id.header.size = sizeof(mmap_event->event_id) + size;
+
+	cpuctx = &get_cpu_var(perf_cpu_context);
+	perf_event_mmap_ctx(&cpuctx->ctx, mmap_event);
+	put_cpu_var(perf_cpu_context);
+
+	rcu_read_lock();
+	/*
+	 * doesn't really matter which of the child contexts the
+	 * events ends up in.
+	 */
+	ctx = rcu_dereference(current->perf_event_ctxp);
+	if (ctx)
+		perf_event_mmap_ctx(ctx, mmap_event);
+	rcu_read_unlock();
+
+	kfree(buf);
+}
+
+void __perf_event_mmap(struct vm_area_struct *vma)
+{
+	struct perf_mmap_event mmap_event;
+
+	if (!atomic_read(&nr_mmap_events))
+		return;
+
+	mmap_event = (struct perf_mmap_event){
+		.vma	= vma,
+		/* .file_name */
+		/* .file_size */
+		.event_id  = {
+			.header = {
+				.type = PERF_RECORD_MMAP,
+				.misc = 0,
+				/* .size */
+			},
+			/* .pid */
+			/* .tid */
+			.start  = vma->vm_start,
+			.len    = vma->vm_end - vma->vm_start,
+			.pgoff  = vma->vm_pgoff,
+		},
+	};
+
+	perf_event_mmap_event(&mmap_event);
+}
+
+/*
+ * IRQ throttle logging
+ */
+
+static void perf_log_throttle(struct perf_event *event, int enable)
+{
+	struct perf_output_handle handle;
+	int ret;
+
+	struct {
+		struct perf_event_header	header;
+		u64				time;
+		u64				id;
+		u64				stream_id;
+	} throttle_event = {
+		.header = {
+			.type = PERF_RECORD_THROTTLE,
+			.misc = 0,
+			.size = sizeof(throttle_event),
+		},
+		.time		= perf_clock(),
+		.id		= primary_event_id(event),
+		.stream_id	= event->id,
+	};
+
+	if (enable)
+		throttle_event.header.type = PERF_RECORD_UNTHROTTLE;
+
+	ret = perf_output_begin(&handle, event, sizeof(throttle_event), 1, 0);
+	if (ret)
+		return;
+
+	perf_output_put(&handle, throttle_event);
+	perf_output_end(&handle);
+}
+
+/*
+ * Generic event overflow handling, sampling.
+ */
+
+static int __perf_event_overflow(struct perf_event *event, int nmi,
+				   int throttle, struct perf_sample_data *data,
+				   struct pt_regs *regs)
+{
+	int events = atomic_read(&event->event_limit);
+	struct hw_perf_event *hwc = &event->hw;
+	int ret = 0;
+
+	throttle = (throttle && event->pmu->unthrottle != NULL);
+
+	if (!throttle) {
+		hwc->interrupts++;
+	} else {
+		if (hwc->interrupts != MAX_INTERRUPTS) {
+			hwc->interrupts++;
+			if (HZ * hwc->interrupts >
+					(u64)sysctl_perf_event_sample_rate) {
+				hwc->interrupts = MAX_INTERRUPTS;
+				perf_log_throttle(event, 0);
+				ret = 1;
+			}
+		} else {
+			/*
+			 * Keep re-disabling events even though on the previous
+			 * pass we disabled it - just in case we raced with a
+			 * sched-in and the event got enabled again:
+			 */
+			ret = 1;
+		}
+	}
+
+	if (event->attr.freq) {
+		u64 now = perf_clock();
+		s64 delta = now - hwc->freq_stamp;
+
+		hwc->freq_stamp = now;
+
+		if (delta > 0 && delta < TICK_NSEC)
+			perf_adjust_period(event, NSEC_PER_SEC / (int)delta);
+	}
+
+	/*
+	 * XXX event_limit might not quite work as expected on inherited
+	 * events
+	 */
+
+	event->pending_kill = POLL_IN;
+	if (events && atomic_dec_and_test(&event->event_limit)) {
+		ret = 1;
+		event->pending_kill = POLL_HUP;
+		if (nmi) {
+			event->pending_disable = 1;
+			perf_pending_queue(&event->pending,
+					   perf_pending_event);
+		} else
+			perf_event_disable(event);
+	}
+
+	perf_event_output(event, nmi, data, regs);
+	return ret;
+}
+
+int perf_event_overflow(struct perf_event *event, int nmi,
+			  struct perf_sample_data *data,
+			  struct pt_regs *regs)
+{
+	return __perf_event_overflow(event, nmi, 1, data, regs);
+}
+
+/*
+ * Generic software event infrastructure
+ */
+
+/*
+ * We directly increment event->count and keep a second value in
+ * event->hw.period_left to count intervals. This period event
+ * is kept in the range [-sample_period, 0] so that we can use the
+ * sign as trigger.
+ */
+
+static u64 perf_swevent_set_period(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 period = hwc->last_period;
+	u64 nr, offset;
+	s64 old, val;
+
+	hwc->last_period = hwc->sample_period;
+
+again:
+	old = val = atomic64_read(&hwc->period_left);
+	if (val < 0)
+		return 0;
+
+	nr = div64_u64(period + val, period);
+	offset = nr * period;
+	val -= offset;
+	if (atomic64_cmpxchg(&hwc->period_left, old, val) != old)
+		goto again;
+
+	return nr;
+}
+
+static void perf_swevent_overflow(struct perf_event *event,
+				    int nmi, struct perf_sample_data *data,
+				    struct pt_regs *regs)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int throttle = 0;
+	u64 overflow;
+
+	data->period = event->hw.last_period;
+	overflow = perf_swevent_set_period(event);
+
+	if (hwc->interrupts == MAX_INTERRUPTS)
+		return;
+
+	for (; overflow; overflow--) {
+		if (__perf_event_overflow(event, nmi, throttle,
+					    data, regs)) {
+			/*
+			 * We inhibit the overflow from happening when
+			 * hwc->interrupts == MAX_INTERRUPTS.
+			 */
+			break;
+		}
+		throttle = 1;
+	}
+}
+
+static void perf_swevent_unthrottle(struct perf_event *event)
+{
+	/*
+	 * Nothing to do, we already reset hwc->interrupts.
+	 */
+}
+
+static void perf_swevent_add(struct perf_event *event, u64 nr,
+			       int nmi, struct perf_sample_data *data,
+			       struct pt_regs *regs)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	atomic64_add(nr, &event->count);
+
+	if (!hwc->sample_period)
+		return;
+
+	if (!regs)
+		return;
+
+	if (!atomic64_add_negative(nr, &hwc->period_left))
+		perf_swevent_overflow(event, nmi, data, regs);
+}
+
+static int perf_swevent_is_counting(struct perf_event *event)
+{
+	/*
+	 * The event is active, we're good!
+	 */
+	if (event->state == PERF_EVENT_STATE_ACTIVE)
+		return 1;
+
+	/*
+	 * The event is off/error, not counting.
+	 */
+	if (event->state != PERF_EVENT_STATE_INACTIVE)
+		return 0;
+
+	/*
+	 * The event is inactive, if the context is active
+	 * we're part of a group that didn't make it on the 'pmu',
+	 * not counting.
+	 */
+	if (event->ctx->is_active)
+		return 0;
+
+	/*
+	 * We're inactive and the context is too, this means the
+	 * task is scheduled out, we're counting events that happen
+	 * to us, like migration events.
+	 */
+	return 1;
+}
+
+static int perf_swevent_match(struct perf_event *event,
+				enum perf_type_id type,
+				u32 event_id, struct pt_regs *regs)
+{
+	if (!perf_swevent_is_counting(event))
+		return 0;
+
+	if (event->attr.type != type)
+		return 0;
+	if (event->attr.config != event_id)
+		return 0;
+
+	if (regs) {
+		if (event->attr.exclude_user && user_mode(regs))
+			return 0;
+
+		if (event->attr.exclude_kernel && !user_mode(regs))
+			return 0;
+	}
+
+	return 1;
+}
+
+static void perf_swevent_ctx_event(struct perf_event_context *ctx,
+				     enum perf_type_id type,
+				     u32 event_id, u64 nr, int nmi,
+				     struct perf_sample_data *data,
+				     struct pt_regs *regs)
+{
+	struct perf_event *event;
+
+	if (system_state != SYSTEM_RUNNING || list_empty(&ctx->event_list))
+		return;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(event, &ctx->event_list, event_entry) {
+		if (perf_swevent_match(event, type, event_id, regs))
+			perf_swevent_add(event, nr, nmi, data, regs);
+	}
+	rcu_read_unlock();
+}
+
+static int *perf_swevent_recursion_context(struct perf_cpu_context *cpuctx)
+{
+	if (in_nmi())
+		return &cpuctx->recursion[3];
+
+	if (in_irq())
+		return &cpuctx->recursion[2];
+
+	if (in_softirq())
+		return &cpuctx->recursion[1];
+
+	return &cpuctx->recursion[0];
+}
+
+static void do_perf_sw_event(enum perf_type_id type, u32 event_id,
+				    u64 nr, int nmi,
+				    struct perf_sample_data *data,
+				    struct pt_regs *regs)
+{
+	struct perf_cpu_context *cpuctx = &get_cpu_var(perf_cpu_context);
+	int *recursion = perf_swevent_recursion_context(cpuctx);
+	struct perf_event_context *ctx;
+
+	if (*recursion)
+		goto out;
+
+	(*recursion)++;
+	barrier();
+
+	perf_swevent_ctx_event(&cpuctx->ctx, type, event_id,
+				 nr, nmi, data, regs);
+	rcu_read_lock();
+	/*
+	 * doesn't really matter which of the child contexts the
+	 * events ends up in.
+	 */
+	ctx = rcu_dereference(current->perf_event_ctxp);
+	if (ctx)
+		perf_swevent_ctx_event(ctx, type, event_id, nr, nmi, data, regs);
+	rcu_read_unlock();
+
+	barrier();
+	(*recursion)--;
+
+out:
+	put_cpu_var(perf_cpu_context);
+}
+
+void __perf_sw_event(u32 event_id, u64 nr, int nmi,
+			    struct pt_regs *regs, u64 addr)
+{
+	struct perf_sample_data data = {
+		.addr = addr,
+	};
+
+	do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi,
+				&data, regs);
+}
+
+static void perf_swevent_read(struct perf_event *event)
+{
+}
+
+static int perf_swevent_enable(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->sample_period) {
+		hwc->last_period = hwc->sample_period;
+		perf_swevent_set_period(event);
+	}
+	return 0;
+}
+
+static void perf_swevent_disable(struct perf_event *event)
+{
+}
+
+static const struct pmu perf_ops_generic = {
+	.enable		= perf_swevent_enable,
+	.disable	= perf_swevent_disable,
+	.read		= perf_swevent_read,
+	.unthrottle	= perf_swevent_unthrottle,
+};
+
+/*
+ * hrtimer based swevent callback
+ */
+
+static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer)
+{
+	enum hrtimer_restart ret = HRTIMER_RESTART;
+	struct perf_sample_data data;
+	struct pt_regs *regs;
+	struct perf_event *event;
+	u64 period;
+
+	event	= container_of(hrtimer, struct perf_event, hw.hrtimer);
+	event->pmu->read(event);
+
+	data.addr = 0;
+	regs = get_irq_regs();
+	/*
+	 * In case we exclude kernel IPs or are somehow not in interrupt
+	 * context, provide the next best thing, the user IP.
+	 */
+	if ((event->attr.exclude_kernel || !regs) &&
+			!event->attr.exclude_user)
+		regs = task_pt_regs(current);
+
+	if (regs) {
+		if (perf_event_overflow(event, 0, &data, regs))
+			ret = HRTIMER_NORESTART;
+	}
+
+	period = max_t(u64, 10000, event->hw.sample_period);
+	hrtimer_forward_now(hrtimer, ns_to_ktime(period));
+
+	return ret;
+}
+
+/*
+ * Software event: cpu wall time clock
+ */
+
+static void cpu_clock_perf_event_update(struct perf_event *event)
+{
+	int cpu = raw_smp_processor_id();
+	s64 prev;
+	u64 now;
+
+	now = cpu_clock(cpu);
+	prev = atomic64_read(&event->hw.prev_count);
+	atomic64_set(&event->hw.prev_count, now);
+	atomic64_add(now - prev, &event->count);
+}
+
+static int cpu_clock_perf_event_enable(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	int cpu = raw_smp_processor_id();
+
+	atomic64_set(&hwc->prev_count, cpu_clock(cpu));
+	hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	hwc->hrtimer.function = perf_swevent_hrtimer;
+	if (hwc->sample_period) {
+		u64 period = max_t(u64, 10000, hwc->sample_period);
+		__hrtimer_start_range_ns(&hwc->hrtimer,
+				ns_to_ktime(period), 0,
+				HRTIMER_MODE_REL, 0);
+	}
+
+	return 0;
+}
+
+static void cpu_clock_perf_event_disable(struct perf_event *event)
+{
+	if (event->hw.sample_period)
+		hrtimer_cancel(&event->hw.hrtimer);
+	cpu_clock_perf_event_update(event);
+}
+
+static void cpu_clock_perf_event_read(struct perf_event *event)
+{
+	cpu_clock_perf_event_update(event);
+}
+
+static const struct pmu perf_ops_cpu_clock = {
+	.enable		= cpu_clock_perf_event_enable,
+	.disable	= cpu_clock_perf_event_disable,
+	.read		= cpu_clock_perf_event_read,
+};
+
+/*
+ * Software event: task time clock
+ */
+
+static void task_clock_perf_event_update(struct perf_event *event, u64 now)
+{
+	u64 prev;
+	s64 delta;
+
+	prev = atomic64_xchg(&event->hw.prev_count, now);
+	delta = now - prev;
+	atomic64_add(delta, &event->count);
+}
+
+static int task_clock_perf_event_enable(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 now;
+
+	now = event->ctx->time;
+
+	atomic64_set(&hwc->prev_count, now);
+	hrtimer_init(&hwc->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	hwc->hrtimer.function = perf_swevent_hrtimer;
+	if (hwc->sample_period) {
+		u64 period = max_t(u64, 10000, hwc->sample_period);
+		__hrtimer_start_range_ns(&hwc->hrtimer,
+				ns_to_ktime(period), 0,
+				HRTIMER_MODE_REL, 0);
+	}
+
+	return 0;
+}
+
+static void task_clock_perf_event_disable(struct perf_event *event)
+{
+	if (event->hw.sample_period)
+		hrtimer_cancel(&event->hw.hrtimer);
+	task_clock_perf_event_update(event, event->ctx->time);
+
+}
+
+static void task_clock_perf_event_read(struct perf_event *event)
+{
+	u64 time;
+
+	if (!in_nmi()) {
+		update_context_time(event->ctx);
+		time = event->ctx->time;
+	} else {
+		u64 now = perf_clock();
+		u64 delta = now - event->ctx->timestamp;
+		time = event->ctx->time + delta;
+	}
+
+	task_clock_perf_event_update(event, time);
+}
+
+static const struct pmu perf_ops_task_clock = {
+	.enable		= task_clock_perf_event_enable,
+	.disable	= task_clock_perf_event_disable,
+	.read		= task_clock_perf_event_read,
+};
+
+#ifdef CONFIG_EVENT_PROFILE
+void perf_tp_event(int event_id, u64 addr, u64 count, void *record,
+			  int entry_size)
+{
+	struct perf_raw_record raw = {
+		.size = entry_size,
+		.data = record,
+	};
+
+	struct perf_sample_data data = {
+		.addr = addr,
+		.raw = &raw,
+	};
+
+	struct pt_regs *regs = get_irq_regs();
+
+	if (!regs)
+		regs = task_pt_regs(current);
+
+	do_perf_sw_event(PERF_TYPE_TRACEPOINT, event_id, count, 1,
+				&data, regs);
+}
+EXPORT_SYMBOL_GPL(perf_tp_event);
+
+extern int ftrace_profile_enable(int);
+extern void ftrace_profile_disable(int);
+
+static void tp_perf_event_destroy(struct perf_event *event)
+{
+	ftrace_profile_disable(event->attr.config);
+}
+
+static const struct pmu *tp_perf_event_init(struct perf_event *event)
+{
+	/*
+	 * Raw tracepoint data is a severe data leak, only allow root to
+	 * have these.
+	 */
+	if ((event->attr.sample_type & PERF_SAMPLE_RAW) &&
+			perf_paranoid_tracepoint_raw() &&
+			!capable(CAP_SYS_ADMIN))
+		return ERR_PTR(-EPERM);
+
+	if (ftrace_profile_enable(event->attr.config))
+		return NULL;
+
+	event->destroy = tp_perf_event_destroy;
+
+	return &perf_ops_generic;
+}
+#else
+static const struct pmu *tp_perf_event_init(struct perf_event *event)
+{
+	return NULL;
+}
+#endif
+
+atomic_t perf_swevent_enabled[PERF_COUNT_SW_MAX];
+
+static void sw_perf_event_destroy(struct perf_event *event)
+{
+	u64 event_id = event->attr.config;
+
+	WARN_ON(event->parent);
+
+	atomic_dec(&perf_swevent_enabled[event_id]);
+}
+
+static const struct pmu *sw_perf_event_init(struct perf_event *event)
+{
+	const struct pmu *pmu = NULL;
+	u64 event_id = event->attr.config;
+
+	/*
+	 * Software events (currently) can't in general distinguish
+	 * between user, kernel and hypervisor events.
+	 * However, context switches and cpu migrations are considered
+	 * to be kernel events, and page faults are never hypervisor
+	 * events.
+	 */
+	switch (event_id) {
+	case PERF_COUNT_SW_CPU_CLOCK:
+		pmu = &perf_ops_cpu_clock;
+
+		break;
+	case PERF_COUNT_SW_TASK_CLOCK:
+		/*
+		 * If the user instantiates this as a per-cpu event,
+		 * use the cpu_clock event instead.
+		 */
+		if (event->ctx->task)
+			pmu = &perf_ops_task_clock;
+		else
+			pmu = &perf_ops_cpu_clock;
+
+		break;
+	case PERF_COUNT_SW_PAGE_FAULTS:
+	case PERF_COUNT_SW_PAGE_FAULTS_MIN:
+	case PERF_COUNT_SW_PAGE_FAULTS_MAJ:
+	case PERF_COUNT_SW_CONTEXT_SWITCHES:
+	case PERF_COUNT_SW_CPU_MIGRATIONS:
+		if (!event->parent) {
+			atomic_inc(&perf_swevent_enabled[event_id]);
+			event->destroy = sw_perf_event_destroy;
+		}
+		pmu = &perf_ops_generic;
+		break;
+	}
+
+	return pmu;
+}
+
+/*
+ * Allocate and initialize a event structure
+ */
+static struct perf_event *
+perf_event_alloc(struct perf_event_attr *attr,
+		   int cpu,
+		   struct perf_event_context *ctx,
+		   struct perf_event *group_leader,
+		   struct perf_event *parent_event,
+		   gfp_t gfpflags)
+{
+	const struct pmu *pmu;
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	long err;
+
+	event = kzalloc(sizeof(*event), gfpflags);
+	if (!event)
+		return ERR_PTR(-ENOMEM);
+
+	/*
+	 * Single events are their own group leaders, with an
+	 * empty sibling list:
+	 */
+	if (!group_leader)
+		group_leader = event;
+
+	mutex_init(&event->child_mutex);
+	INIT_LIST_HEAD(&event->child_list);
+
+	INIT_LIST_HEAD(&event->group_entry);
+	INIT_LIST_HEAD(&event->event_entry);
+	INIT_LIST_HEAD(&event->sibling_list);
+	init_waitqueue_head(&event->waitq);
+
+	mutex_init(&event->mmap_mutex);
+
+	event->cpu		= cpu;
+	event->attr		= *attr;
+	event->group_leader	= group_leader;
+	event->pmu		= NULL;
+	event->ctx		= ctx;
+	event->oncpu		= -1;
+
+	event->parent		= parent_event;
+
+	event->ns		= get_pid_ns(current->nsproxy->pid_ns);
+	event->id		= atomic64_inc_return(&perf_event_id);
+
+	event->state		= PERF_EVENT_STATE_INACTIVE;
+
+	if (attr->disabled)
+		event->state = PERF_EVENT_STATE_OFF;
+
+	pmu = NULL;
+
+	hwc = &event->hw;
+	hwc->sample_period = attr->sample_period;
+	if (attr->freq && attr->sample_freq)
+		hwc->sample_period = 1;
+	hwc->last_period = hwc->sample_period;
+
+	atomic64_set(&hwc->period_left, hwc->sample_period);
+
+	/*
+	 * we currently do not support PERF_FORMAT_GROUP on inherited events
+	 */
+	if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
+		goto done;
+
+	switch (attr->type) {
+	case PERF_TYPE_RAW:
+	case PERF_TYPE_HARDWARE:
+	case PERF_TYPE_HW_CACHE:
+		pmu = hw_perf_event_init(event);
+		break;
+
+	case PERF_TYPE_SOFTWARE:
+		pmu = sw_perf_event_init(event);
+		break;
+
+	case PERF_TYPE_TRACEPOINT:
+		pmu = tp_perf_event_init(event);
+		break;
+
+	default:
+		break;
+	}
+done:
+	err = 0;
+	if (!pmu)
+		err = -EINVAL;
+	else if (IS_ERR(pmu))
+		err = PTR_ERR(pmu);
+
+	if (err) {
+		if (event->ns)
+			put_pid_ns(event->ns);
+		kfree(event);
+		return ERR_PTR(err);
+	}
+
+	event->pmu = pmu;
+
+	if (!event->parent) {
+		atomic_inc(&nr_events);
+		if (event->attr.mmap)
+			atomic_inc(&nr_mmap_events);
+		if (event->attr.comm)
+			atomic_inc(&nr_comm_events);
+		if (event->attr.task)
+			atomic_inc(&nr_task_events);
+	}
+
+	return event;
+}
+
+static int perf_copy_attr(struct perf_event_attr __user *uattr,
+			  struct perf_event_attr *attr)
+{
+	u32 size;
+	int ret;
+
+	if (!access_ok(VERIFY_WRITE, uattr, PERF_ATTR_SIZE_VER0))
+		return -EFAULT;
+
+	/*
+	 * zero the full structure, so that a short copy will be nice.
+	 */
+	memset(attr, 0, sizeof(*attr));
+
+	ret = get_user(size, &uattr->size);
+	if (ret)
+		return ret;
+
+	if (size > PAGE_SIZE)	/* silly large */
+		goto err_size;
+
+	if (!size)		/* abi compat */
+		size = PERF_ATTR_SIZE_VER0;
+
+	if (size < PERF_ATTR_SIZE_VER0)
+		goto err_size;
+
+	/*
+	 * If we're handed a bigger struct than we know of,
+	 * ensure all the unknown bits are 0 - i.e. new
+	 * user-space does not rely on any kernel feature
+	 * extensions we dont know about yet.
+	 */
+	if (size > sizeof(*attr)) {
+		unsigned char __user *addr;
+		unsigned char __user *end;
+		unsigned char val;
+
+		addr = (void __user *)uattr + sizeof(*attr);
+		end  = (void __user *)uattr + size;
+
+		for (; addr < end; addr++) {
+			ret = get_user(val, addr);
+			if (ret)
+				return ret;
+			if (val)
+				goto err_size;
+		}
+		size = sizeof(*attr);
+	}
+
+	ret = copy_from_user(attr, uattr, size);
+	if (ret)
+		return -EFAULT;
+
+	/*
+	 * If the type exists, the corresponding creation will verify
+	 * the attr->config.
+	 */
+	if (attr->type >= PERF_TYPE_MAX)
+		return -EINVAL;
+
+	if (attr->__reserved_1 || attr->__reserved_2 || attr->__reserved_3)
+		return -EINVAL;
+
+	if (attr->sample_type & ~(PERF_SAMPLE_MAX-1))
+		return -EINVAL;
+
+	if (attr->read_format & ~(PERF_FORMAT_MAX-1))
+		return -EINVAL;
+
+out:
+	return ret;
+
+err_size:
+	put_user(sizeof(*attr), &uattr->size);
+	ret = -E2BIG;
+	goto out;
+}
+
+int perf_event_set_output(struct perf_event *event, int output_fd)
+{
+	struct perf_event *output_event = NULL;
+	struct file *output_file = NULL;
+	struct perf_event *old_output;
+	int fput_needed = 0;
+	int ret = -EINVAL;
+
+	if (!output_fd)
+		goto set;
+
+	output_file = fget_light(output_fd, &fput_needed);
+	if (!output_file)
+		return -EBADF;
+
+	if (output_file->f_op != &perf_fops)
+		goto out;
+
+	output_event = output_file->private_data;
+
+	/* Don't chain output fds */
+	if (output_event->output)
+		goto out;
+
+	/* Don't set an output fd when we already have an output channel */
+	if (event->data)
+		goto out;
+
+	atomic_long_inc(&output_file->f_count);
+
+set:
+	mutex_lock(&event->mmap_mutex);
+	old_output = event->output;
+	rcu_assign_pointer(event->output, output_event);
+	mutex_unlock(&event->mmap_mutex);
+
+	if (old_output) {
+		/*
+		 * we need to make sure no existing perf_output_*()
+		 * is still referencing this event.
+		 */
+		synchronize_rcu();
+		fput(old_output->filp);
+	}
+
+	ret = 0;
+out:
+	fput_light(output_file, fput_needed);
+	return ret;
+}
+
+/**
+ * sys_perf_event_open - open a performance event, associate it to a task/cpu
+ *
+ * @attr_uptr:	event_id type attributes for monitoring/sampling
+ * @pid:		target pid
+ * @cpu:		target cpu
+ * @group_fd:		group leader event fd
+ */
+SYSCALL_DEFINE5(perf_event_open,
+		struct perf_event_attr __user *, attr_uptr,
+		pid_t, pid, int, cpu, int, group_fd, unsigned long, flags)
+{
+	struct perf_event *event, *group_leader;
+	struct perf_event_attr attr;
+	struct perf_event_context *ctx;
+	struct file *event_file = NULL;
+	struct file *group_file = NULL;
+	int fput_needed = 0;
+	int fput_needed2 = 0;
+	int err;
+
+	/* for future expandability... */
+	if (flags & ~(PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT))
+		return -EINVAL;
+
+	err = perf_copy_attr(attr_uptr, &attr);
+	if (err)
+		return err;
+
+	if (!attr.exclude_kernel) {
+		if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN))
+			return -EACCES;
+	}
+
+	if (attr.freq) {
+		if (attr.sample_freq > sysctl_perf_event_sample_rate)
+			return -EINVAL;
+	}
+
+	/*
+	 * Get the target context (task or percpu):
+	 */
+	ctx = find_get_context(pid, cpu);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	/*
+	 * Look up the group leader (we will attach this event to it):
+	 */
+	group_leader = NULL;
+	if (group_fd != -1 && !(flags & PERF_FLAG_FD_NO_GROUP)) {
+		err = -EINVAL;
+		group_file = fget_light(group_fd, &fput_needed);
+		if (!group_file)
+			goto err_put_context;
+		if (group_file->f_op != &perf_fops)
+			goto err_put_context;
+
+		group_leader = group_file->private_data;
+		/*
+		 * Do not allow a recursive hierarchy (this new sibling
+		 * becoming part of another group-sibling):
+		 */
+		if (group_leader->group_leader != group_leader)
+			goto err_put_context;
+		/*
+		 * Do not allow to attach to a group in a different
+		 * task or CPU context:
+		 */
+		if (group_leader->ctx != ctx)
+			goto err_put_context;
+		/*
+		 * Only a group leader can be exclusive or pinned
+		 */
+		if (attr.exclusive || attr.pinned)
+			goto err_put_context;
+	}
+
+	event = perf_event_alloc(&attr, cpu, ctx, group_leader,
+				     NULL, GFP_KERNEL);
+	err = PTR_ERR(event);
+	if (IS_ERR(event))
+		goto err_put_context;
+
+	err = anon_inode_getfd("[perf_event]", &perf_fops, event, 0);
+	if (err < 0)
+		goto err_free_put_context;
+
+	event_file = fget_light(err, &fput_needed2);
+	if (!event_file)
+		goto err_free_put_context;
+
+	if (flags & PERF_FLAG_FD_OUTPUT) {
+		err = perf_event_set_output(event, group_fd);
+		if (err)
+			goto err_fput_free_put_context;
+	}
+
+	event->filp = event_file;
+	WARN_ON_ONCE(ctx->parent_ctx);
+	mutex_lock(&ctx->mutex);
+	perf_install_in_context(ctx, event, cpu);
+	++ctx->generation;
+	mutex_unlock(&ctx->mutex);
+
+	event->owner = current;
+	get_task_struct(current);
+	mutex_lock(&current->perf_event_mutex);
+	list_add_tail(&event->owner_entry, &current->perf_event_list);
+	mutex_unlock(&current->perf_event_mutex);
+
+err_fput_free_put_context:
+	fput_light(event_file, fput_needed2);
+
+err_free_put_context:
+	if (err < 0)
+		kfree(event);
+
+err_put_context:
+	if (err < 0)
+		put_ctx(ctx);
+
+	fput_light(group_file, fput_needed);
+
+	return err;
+}
+
+/*
+ * inherit a event from parent task to child task:
+ */
+static struct perf_event *
+inherit_event(struct perf_event *parent_event,
+	      struct task_struct *parent,
+	      struct perf_event_context *parent_ctx,
+	      struct task_struct *child,
+	      struct perf_event *group_leader,
+	      struct perf_event_context *child_ctx)
+{
+	struct perf_event *child_event;
+
+	/*
+	 * Instead of creating recursive hierarchies of events,
+	 * we link inherited events back to the original parent,
+	 * which has a filp for sure, which we use as the reference
+	 * count:
+	 */
+	if (parent_event->parent)
+		parent_event = parent_event->parent;
+
+	child_event = perf_event_alloc(&parent_event->attr,
+					   parent_event->cpu, child_ctx,
+					   group_leader, parent_event,
+					   GFP_KERNEL);
+	if (IS_ERR(child_event))
+		return child_event;
+	get_ctx(child_ctx);
+
+	/*
+	 * Make the child state follow the state of the parent event,
+	 * not its attr.disabled bit.  We hold the parent's mutex,
+	 * so we won't race with perf_event_{en, dis}able_family.
+	 */
+	if (parent_event->state >= PERF_EVENT_STATE_INACTIVE)
+		child_event->state = PERF_EVENT_STATE_INACTIVE;
+	else
+		child_event->state = PERF_EVENT_STATE_OFF;
+
+	if (parent_event->attr.freq)
+		child_event->hw.sample_period = parent_event->hw.sample_period;
+
+	/*
+	 * Link it up in the child's context:
+	 */
+	add_event_to_ctx(child_event, child_ctx);
+
+	/*
+	 * Get a reference to the parent filp - we will fput it
+	 * when the child event exits. This is safe to do because
+	 * we are in the parent and we know that the filp still
+	 * exists and has a nonzero count:
+	 */
+	atomic_long_inc(&parent_event->filp->f_count);
+
+	/*
+	 * Link this into the parent event's child list
+	 */
+	WARN_ON_ONCE(parent_event->ctx->parent_ctx);
+	mutex_lock(&parent_event->child_mutex);
+	list_add_tail(&child_event->child_list, &parent_event->child_list);
+	mutex_unlock(&parent_event->child_mutex);
+
+	return child_event;
+}
+
+static int inherit_group(struct perf_event *parent_event,
+	      struct task_struct *parent,
+	      struct perf_event_context *parent_ctx,
+	      struct task_struct *child,
+	      struct perf_event_context *child_ctx)
+{
+	struct perf_event *leader;
+	struct perf_event *sub;
+	struct perf_event *child_ctr;
+
+	leader = inherit_event(parent_event, parent, parent_ctx,
+				 child, NULL, child_ctx);
+	if (IS_ERR(leader))
+		return PTR_ERR(leader);
+	list_for_each_entry(sub, &parent_event->sibling_list, group_entry) {
+		child_ctr = inherit_event(sub, parent, parent_ctx,
+					    child, leader, child_ctx);
+		if (IS_ERR(child_ctr))
+			return PTR_ERR(child_ctr);
+	}
+	return 0;
+}
+
+static void sync_child_event(struct perf_event *child_event,
+			       struct task_struct *child)
+{
+	struct perf_event *parent_event = child_event->parent;
+	u64 child_val;
+
+	if (child_event->attr.inherit_stat)
+		perf_event_read_event(child_event, child);
+
+	child_val = atomic64_read(&child_event->count);
+
+	/*
+	 * Add back the child's count to the parent's count:
+	 */
+	atomic64_add(child_val, &parent_event->count);
+	atomic64_add(child_event->total_time_enabled,
+		     &parent_event->child_total_time_enabled);
+	atomic64_add(child_event->total_time_running,
+		     &parent_event->child_total_time_running);
+
+	/*
+	 * Remove this event from the parent's list
+	 */
+	WARN_ON_ONCE(parent_event->ctx->parent_ctx);
+	mutex_lock(&parent_event->child_mutex);
+	list_del_init(&child_event->child_list);
+	mutex_unlock(&parent_event->child_mutex);
+
+	/*
+	 * Release the parent event, if this was the last
+	 * reference to it.
+	 */
+	fput(parent_event->filp);
+}
+
+static void
+__perf_event_exit_task(struct perf_event *child_event,
+			 struct perf_event_context *child_ctx,
+			 struct task_struct *child)
+{
+	struct perf_event *parent_event;
+
+	update_event_times(child_event);
+	perf_event_remove_from_context(child_event);
+
+	parent_event = child_event->parent;
+	/*
+	 * It can happen that parent exits first, and has events
+	 * that are still around due to the child reference. These
+	 * events need to be zapped - but otherwise linger.
+	 */
+	if (parent_event) {
+		sync_child_event(child_event, child);
+		free_event(child_event);
+	}
+}
+
+/*
+ * When a child task exits, feed back event values to parent events.
+ */
+void perf_event_exit_task(struct task_struct *child)
+{
+	struct perf_event *child_event, *tmp;
+	struct perf_event_context *child_ctx;
+	unsigned long flags;
+
+	if (likely(!child->perf_event_ctxp)) {
+		perf_event_task(child, NULL, 0);
+		return;
+	}
+
+	local_irq_save(flags);
+	/*
+	 * We can't reschedule here because interrupts are disabled,
+	 * and either child is current or it is a task that can't be
+	 * scheduled, so we are now safe from rescheduling changing
+	 * our context.
+	 */
+	child_ctx = child->perf_event_ctxp;
+	__perf_event_task_sched_out(child_ctx);
+
+	/*
+	 * Take the context lock here so that if find_get_context is
+	 * reading child->perf_event_ctxp, we wait until it has
+	 * incremented the context's refcount before we do put_ctx below.
+	 */
+	spin_lock(&child_ctx->lock);
+	child->perf_event_ctxp = NULL;
+	/*
+	 * If this context is a clone; unclone it so it can't get
+	 * swapped to another process while we're removing all
+	 * the events from it.
+	 */
+	unclone_ctx(child_ctx);
+	spin_unlock_irqrestore(&child_ctx->lock, flags);
+
+	/*
+	 * Report the task dead after unscheduling the events so that we
+	 * won't get any samples after PERF_RECORD_EXIT. We can however still
+	 * get a few PERF_RECORD_READ events.
+	 */
+	perf_event_task(child, child_ctx, 0);
+
+	/*
+	 * We can recurse on the same lock type through:
+	 *
+	 *   __perf_event_exit_task()
+	 *     sync_child_event()
+	 *       fput(parent_event->filp)
+	 *         perf_release()
+	 *           mutex_lock(&ctx->mutex)
+	 *
+	 * But since its the parent context it won't be the same instance.
+	 */
+	mutex_lock_nested(&child_ctx->mutex, SINGLE_DEPTH_NESTING);
+
+again:
+	list_for_each_entry_safe(child_event, tmp, &child_ctx->group_list,
+				 group_entry)
+		__perf_event_exit_task(child_event, child_ctx, child);
+
+	/*
+	 * If the last event was a group event, it will have appended all
+	 * its siblings to the list, but we obtained 'tmp' before that which
+	 * will still point to the list head terminating the iteration.
+	 */
+	if (!list_empty(&child_ctx->group_list))
+		goto again;
+
+	mutex_unlock(&child_ctx->mutex);
+
+	put_ctx(child_ctx);
+}
+
+/*
+ * free an unexposed, unused context as created by inheritance by
+ * init_task below, used by fork() in case of fail.
+ */
+void perf_event_free_task(struct task_struct *task)
+{
+	struct perf_event_context *ctx = task->perf_event_ctxp;
+	struct perf_event *event, *tmp;
+
+	if (!ctx)
+		return;
+
+	mutex_lock(&ctx->mutex);
+again:
+	list_for_each_entry_safe(event, tmp, &ctx->group_list, group_entry) {
+		struct perf_event *parent = event->parent;
+
+		if (WARN_ON_ONCE(!parent))
+			continue;
+
+		mutex_lock(&parent->child_mutex);
+		list_del_init(&event->child_list);
+		mutex_unlock(&parent->child_mutex);
+
+		fput(parent->filp);
+
+		list_del_event(event, ctx);
+		free_event(event);
+	}
+
+	if (!list_empty(&ctx->group_list))
+		goto again;
+
+	mutex_unlock(&ctx->mutex);
+
+	put_ctx(ctx);
+}
+
+/*
+ * Initialize the perf_event context in task_struct
+ */
+int perf_event_init_task(struct task_struct *child)
+{
+	struct perf_event_context *child_ctx, *parent_ctx;
+	struct perf_event_context *cloned_ctx;
+	struct perf_event *event;
+	struct task_struct *parent = current;
+	int inherited_all = 1;
+	int ret = 0;
+
+	child->perf_event_ctxp = NULL;
+
+	mutex_init(&child->perf_event_mutex);
+	INIT_LIST_HEAD(&child->perf_event_list);
+
+	if (likely(!parent->perf_event_ctxp))
+		return 0;
+
+	/*
+	 * This is executed from the parent task context, so inherit
+	 * events that have been marked for cloning.
+	 * First allocate and initialize a context for the child.
+	 */
+
+	child_ctx = kmalloc(sizeof(struct perf_event_context), GFP_KERNEL);
+	if (!child_ctx)
+		return -ENOMEM;
+
+	__perf_event_init_context(child_ctx, child);
+	child->perf_event_ctxp = child_ctx;
+	get_task_struct(child);
+
+	/*
+	 * If the parent's context is a clone, pin it so it won't get
+	 * swapped under us.
+	 */
+	parent_ctx = perf_pin_task_context(parent);
+
+	/*
+	 * No need to check if parent_ctx != NULL here; since we saw
+	 * it non-NULL earlier, the only reason for it to become NULL
+	 * is if we exit, and since we're currently in the middle of
+	 * a fork we can't be exiting at the same time.
+	 */
+
+	/*
+	 * Lock the parent list. No need to lock the child - not PID
+	 * hashed yet and not running, so nobody can access it.
+	 */
+	mutex_lock(&parent_ctx->mutex);
+
+	/*
+	 * We dont have to disable NMIs - we are only looking at
+	 * the list, not manipulating it:
+	 */
+	list_for_each_entry_rcu(event, &parent_ctx->event_list, event_entry) {
+		if (event != event->group_leader)
+			continue;
+
+		if (!event->attr.inherit) {
+			inherited_all = 0;
+			continue;
+		}
+
+		ret = inherit_group(event, parent, parent_ctx,
+					     child, child_ctx);
+		if (ret) {
+			inherited_all = 0;
+			break;
+		}
+	}
+
+	if (inherited_all) {
+		/*
+		 * Mark the child context as a clone of the parent
+		 * context, or of whatever the parent is a clone of.
+		 * Note that if the parent is a clone, it could get
+		 * uncloned at any point, but that doesn't matter
+		 * because the list of events and the generation
+		 * count can't have changed since we took the mutex.
+		 */
+		cloned_ctx = rcu_dereference(parent_ctx->parent_ctx);
+		if (cloned_ctx) {
+			child_ctx->parent_ctx = cloned_ctx;
+			child_ctx->parent_gen = parent_ctx->parent_gen;
+		} else {
+			child_ctx->parent_ctx = parent_ctx;
+			child_ctx->parent_gen = parent_ctx->generation;
+		}
+		get_ctx(child_ctx->parent_ctx);
+	}
+
+	mutex_unlock(&parent_ctx->mutex);
+
+	perf_unpin_context(parent_ctx);
+
+	return ret;
+}
+
+static void __cpuinit perf_event_init_cpu(int cpu)
+{
+	struct perf_cpu_context *cpuctx;
+
+	cpuctx = &per_cpu(perf_cpu_context, cpu);
+	__perf_event_init_context(&cpuctx->ctx, NULL);
+
+	spin_lock(&perf_resource_lock);
+	cpuctx->max_pertask = perf_max_events - perf_reserved_percpu;
+	spin_unlock(&perf_resource_lock);
+
+	hw_perf_event_setup(cpu);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void __perf_event_exit_cpu(void *info)
+{
+	struct perf_cpu_context *cpuctx = &__get_cpu_var(perf_cpu_context);
+	struct perf_event_context *ctx = &cpuctx->ctx;
+	struct perf_event *event, *tmp;
+
+	list_for_each_entry_safe(event, tmp, &ctx->group_list, group_entry)
+		__perf_event_remove_from_context(event);
+}
+static void perf_event_exit_cpu(int cpu)
+{
+	struct perf_cpu_context *cpuctx = &per_cpu(perf_cpu_context, cpu);
+	struct perf_event_context *ctx = &cpuctx->ctx;
+
+	mutex_lock(&ctx->mutex);
+	smp_call_function_single(cpu, __perf_event_exit_cpu, NULL, 1);
+	mutex_unlock(&ctx->mutex);
+}
+#else
+static inline void perf_event_exit_cpu(int cpu) { }
+#endif
+
+static int __cpuinit
+perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (long)hcpu;
+
+	switch (action) {
+
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+		perf_event_init_cpu(cpu);
+		break;
+
+	case CPU_ONLINE:
+	case CPU_ONLINE_FROZEN:
+		hw_perf_event_setup_online(cpu);
+		break;
+
+	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
+		perf_event_exit_cpu(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+/*
+ * This has to have a higher priority than migration_notifier in sched.c.
+ */
+static struct notifier_block __cpuinitdata perf_cpu_nb = {
+	.notifier_call		= perf_cpu_notify,
+	.priority		= 20,
+};
+
+void __init perf_event_init(void)
+{
+	perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
+			(void *)(long)smp_processor_id());
+	perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
+			(void *)(long)smp_processor_id());
+	register_cpu_notifier(&perf_cpu_nb);
+}
+
+static ssize_t perf_show_reserve_percpu(struct sysdev_class *class, char *buf)
+{
+	return sprintf(buf, "%d\n", perf_reserved_percpu);
+}
+
+static ssize_t
+perf_set_reserve_percpu(struct sysdev_class *class,
+			const char *buf,
+			size_t count)
+{
+	struct perf_cpu_context *cpuctx;
+	unsigned long val;
+	int err, cpu, mpt;
+
+	err = strict_strtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val > perf_max_events)
+		return -EINVAL;
+
+	spin_lock(&perf_resource_lock);
+	perf_reserved_percpu = val;
+	for_each_online_cpu(cpu) {
+		cpuctx = &per_cpu(perf_cpu_context, cpu);
+		spin_lock_irq(&cpuctx->ctx.lock);
+		mpt = min(perf_max_events - cpuctx->ctx.nr_events,
+			  perf_max_events - perf_reserved_percpu);
+		cpuctx->max_pertask = mpt;
+		spin_unlock_irq(&cpuctx->ctx.lock);
+	}
+	spin_unlock(&perf_resource_lock);
+
+	return count;
+}
+
+static ssize_t perf_show_overcommit(struct sysdev_class *class, char *buf)
+{
+	return sprintf(buf, "%d\n", perf_overcommit);
+}
+
+static ssize_t
+perf_set_overcommit(struct sysdev_class *class, const char *buf, size_t count)
+{
+	unsigned long val;
+	int err;
+
+	err = strict_strtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val > 1)
+		return -EINVAL;
+
+	spin_lock(&perf_resource_lock);
+	perf_overcommit = val;
+	spin_unlock(&perf_resource_lock);
+
+	return count;
+}
+
+static SYSDEV_CLASS_ATTR(
+				reserve_percpu,
+				0644,
+				perf_show_reserve_percpu,
+				perf_set_reserve_percpu
+			);
+
+static SYSDEV_CLASS_ATTR(
+				overcommit,
+				0644,
+				perf_show_overcommit,
+				perf_set_overcommit
+			);
+
+static struct attribute *perfclass_attrs[] = {
+	&attr_reserve_percpu.attr,
+	&attr_overcommit.attr,
+	NULL
+};
+
+static struct attribute_group perfclass_attr_group = {
+	.attrs			= perfclass_attrs,
+	.name			= "perf_events",
+};
+
+static int __init perf_event_sysfs_init(void)
+{
+	return sysfs_create_group(&cpu_sysdev_class.kset.kobj,
+				  &perfclass_attr_group);
+}
+device_initcall(perf_event_sysfs_init);
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index d089d05..4954407 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -242,6 +242,25 @@ static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
 	return 0;
 }
 
+
+static int posix_get_realtime_coarse(clockid_t which_clock, struct timespec *tp)
+{
+	*tp = current_kernel_time();
+	return 0;
+}
+
+static int posix_get_monotonic_coarse(clockid_t which_clock,
+						struct timespec *tp)
+{
+	*tp = get_monotonic_coarse();
+	return 0;
+}
+
+int posix_get_coarse_res(const clockid_t which_clock, struct timespec *tp)
+{
+	*tp = ktime_to_timespec(KTIME_LOW_RES);
+	return 0;
+}
 /*
  * Initialize everything, well, just everything in Posix clocks/timers ;)
  */
@@ -262,10 +281,26 @@ static __init int init_posix_timers(void)
 		.timer_create = no_timer_create,
 		.nsleep = no_nsleep,
 	};
+	struct k_clock clock_realtime_coarse = {
+		.clock_getres = posix_get_coarse_res,
+		.clock_get = posix_get_realtime_coarse,
+		.clock_set = do_posix_clock_nosettime,
+		.timer_create = no_timer_create,
+		.nsleep = no_nsleep,
+	};
+	struct k_clock clock_monotonic_coarse = {
+		.clock_getres = posix_get_coarse_res,
+		.clock_get = posix_get_monotonic_coarse,
+		.clock_set = do_posix_clock_nosettime,
+		.timer_create = no_timer_create,
+		.nsleep = no_nsleep,
+	};
 
 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
 	register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
 	register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
+	register_posix_clock(CLOCK_REALTIME_COARSE, &clock_realtime_coarse);
+	register_posix_clock(CLOCK_MONOTONIC_COARSE, &clock_monotonic_coarse);
 
 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, SLAB_PANIC,
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 72067cb..91e09d3 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -208,3 +208,17 @@ config APM_EMULATION
 	  random kernel OOPSes or reboots that don't seem to be related to
 	  anything, try disabling/enabling this option (or disabling/enabling
 	  APM in your BIOS).
+
+config PM_RUNTIME
+	bool "Run-time PM core functionality"
+	depends on PM
+	---help---
+	  Enable functionality allowing I/O devices to be put into energy-saving
+	  (low power) states at run time (or autosuspended) after a specified
+	  period of inactivity and woken up in response to a hardware-generated
+	  wake-up event or a driver's request.
+
+	  Hardware support is generally required for this functionality to work
+	  and the bus type drivers of the buses the devices are on are
+	  responsible for the actual handling of the autosuspend requests and
+	  wake-up events.
diff --git a/kernel/power/console.c b/kernel/power/console.c
index a3961b2..5187136 100644
--- a/kernel/power/console.c
+++ b/kernel/power/console.c
@@ -14,56 +14,13 @@
 #define SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1)
 
 static int orig_fgconsole, orig_kmsg;
-static int disable_vt_switch;
-
-/*
- * Normally during a suspend, we allocate a new console and switch to it.
- * When we resume, we switch back to the original console.  This switch
- * can be slow, so on systems where the framebuffer can handle restoration
- * of video registers anyways, there's little point in doing the console
- * switch.  This function allows you to disable it by passing it '0'.
- */
-void pm_set_vt_switch(int do_switch)
-{
-	acquire_console_sem();
-	disable_vt_switch = !do_switch;
-	release_console_sem();
-}
-EXPORT_SYMBOL(pm_set_vt_switch);
 
 int pm_prepare_console(void)
 {
-	acquire_console_sem();
-
-	if (disable_vt_switch) {
-		release_console_sem();
-		return 0;
-	}
-
-	orig_fgconsole = fg_console;
-
-	if (vc_allocate(SUSPEND_CONSOLE)) {
-	  /* we can't have a free VC for now. Too bad,
-	   * we don't want to mess the screen for now. */
-		release_console_sem();
+	orig_fgconsole = vt_move_to_console(SUSPEND_CONSOLE, 1);
+	if (orig_fgconsole < 0)
 		return 1;
-	}
 
-	if (set_console(SUSPEND_CONSOLE)) {
-		/*
-		 * We're unable to switch to the SUSPEND_CONSOLE.
-		 * Let the calling function know so it can decide
-		 * what to do.
-		 */
-		release_console_sem();
-		return 1;
-	}
-	release_console_sem();
-
-	if (vt_waitactive(SUSPEND_CONSOLE)) {
-		pr_debug("Suspend: Can't switch VCs.");
-		return 1;
-	}
 	orig_kmsg = kmsg_redirect;
 	kmsg_redirect = SUSPEND_CONSOLE;
 	return 0;
@@ -71,19 +28,9 @@ int pm_prepare_console(void)
 
 void pm_restore_console(void)
 {
-	acquire_console_sem();
-	if (disable_vt_switch) {
-		release_console_sem();
-		return;
-	}
-	set_console(orig_fgconsole);
-	release_console_sem();
-
-	if (vt_waitactive(orig_fgconsole)) {
-		pr_debug("Resume: Can't switch VCs.");
-		return;
+	if (orig_fgconsole >= 0) {
+		vt_move_to_console(orig_fgconsole, 0);
+		kmsg_redirect = orig_kmsg;
 	}
-
-	kmsg_redirect = orig_kmsg;
 }
 #endif
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 81d2e74..04b3a83 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -298,8 +298,8 @@ int hibernation_snapshot(int platform_mode)
 	if (error)
 		return error;
 
-	/* Free memory before shutting down devices. */
-	error = swsusp_shrink_memory();
+	/* Preallocate image memory before shutting down devices. */
+	error = hibernate_preallocate_memory();
 	if (error)
 		goto Close;
 
@@ -315,6 +315,10 @@ int hibernation_snapshot(int platform_mode)
 	/* Control returns here after successful restore */
 
  Resume_devices:
+	/* We may need to release the preallocated image pages here. */
+	if (error || !in_suspend)
+		swsusp_free();
+
 	dpm_resume_end(in_suspend ?
 		(error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE);
 	resume_console();
@@ -460,11 +464,11 @@ int hibernation_platform_enter(void)
 
 	error = hibernation_ops->prepare();
 	if (error)
-		goto Platofrm_finish;
+		goto Platform_finish;
 
 	error = disable_nonboot_cpus();
 	if (error)
-		goto Platofrm_finish;
+		goto Platform_finish;
 
 	local_irq_disable();
 	sysdev_suspend(PMSG_HIBERNATE);
@@ -476,7 +480,7 @@ int hibernation_platform_enter(void)
 	 * We don't need to reenable the nonboot CPUs or resume consoles, since
 	 * the system is going to be halted anyway.
 	 */
- Platofrm_finish:
+ Platform_finish:
 	hibernation_ops->finish();
 
 	dpm_suspend_noirq(PMSG_RESTORE);
@@ -578,7 +582,10 @@ int hibernate(void)
 		goto Thaw;
 
 	error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
-	if (in_suspend && !error) {
+	if (error)
+		goto Thaw;
+
+	if (in_suspend) {
 		unsigned int flags = 0;
 
 		if (hibernation_mode == HIBERNATION_PLATFORM)
@@ -590,8 +597,8 @@ int hibernate(void)
 			power_down();
 	} else {
 		pr_debug("PM: Image restored successfully.\n");
-		swsusp_free();
 	}
+
  Thaw:
 	thaw_processes();
  Finish:
diff --git a/kernel/power/main.c b/kernel/power/main.c
index f710e36..347d2cc 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -11,6 +11,7 @@
 #include <linux/kobject.h>
 #include <linux/string.h>
 #include <linux/resume-trace.h>
+#include <linux/workqueue.h>
 
 #include "power.h"
 
@@ -217,8 +218,24 @@ static struct attribute_group attr_group = {
 	.attrs = g,
 };
 
+#ifdef CONFIG_PM_RUNTIME
+struct workqueue_struct *pm_wq;
+
+static int __init pm_start_workqueue(void)
+{
+	pm_wq = create_freezeable_workqueue("pm");
+
+	return pm_wq ? 0 : -ENOMEM;
+}
+#else
+static inline int pm_start_workqueue(void) { return 0; }
+#endif
+
 static int __init pm_init(void)
 {
+	int error = pm_start_workqueue();
+	if (error)
+		return error;
 	power_kobj = kobject_create_and_add("power", NULL);
 	if (!power_kobj)
 		return -ENOMEM;
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 26d5a26..46c5a26 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -74,7 +74,7 @@ extern asmlinkage int swsusp_arch_resume(void);
 
 extern int create_basic_memory_bitmaps(void);
 extern void free_basic_memory_bitmaps(void);
-extern int swsusp_shrink_memory(void);
+extern int hibernate_preallocate_memory(void);
 
 /**
  *	Auxiliary structure used for reading the snapshot image data and
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 523a451..97955b0 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -233,7 +233,7 @@ static void *chain_alloc(struct chain_allocator *ca, unsigned int size)
 
 #define BM_END_OF_MAP	(~0UL)
 
-#define BM_BITS_PER_BLOCK	(PAGE_SIZE << 3)
+#define BM_BITS_PER_BLOCK	(PAGE_SIZE * BITS_PER_BYTE)
 
 struct bm_block {
 	struct list_head hook;	/* hook into a list of bitmap blocks */
@@ -275,7 +275,7 @@ static void memory_bm_free(struct memory_bitmap *bm, int clear_nosave_free);
 
 /**
  *	create_bm_block_list - create a list of block bitmap objects
- *	@nr_blocks - number of blocks to allocate
+ *	@pages - number of pages to track
  *	@list - list to put the allocated blocks into
  *	@ca - chain allocator to be used for allocating memory
  */
@@ -853,7 +853,7 @@ static unsigned int count_highmem_pages(void)
 	struct zone *zone;
 	unsigned int n = 0;
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		unsigned long pfn, max_zone_pfn;
 
 		if (!is_highmem(zone))
@@ -916,7 +916,7 @@ static unsigned int count_data_pages(void)
 	unsigned long pfn, max_zone_pfn;
 	unsigned int n = 0;
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		if (is_highmem(zone))
 			continue;
 
@@ -1010,7 +1010,7 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
 	struct zone *zone;
 	unsigned long pfn;
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		unsigned long max_zone_pfn;
 
 		mark_free_pages(zone);
@@ -1033,6 +1033,25 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
 static unsigned int nr_copy_pages;
 /* Number of pages needed for saving the original pfns of the image pages */
 static unsigned int nr_meta_pages;
+/*
+ * Numbers of normal and highmem page frames allocated for hibernation image
+ * before suspending devices.
+ */
+unsigned int alloc_normal, alloc_highmem;
+/*
+ * Memory bitmap used for marking saveable pages (during hibernation) or
+ * hibernation image pages (during restore)
+ */
+static struct memory_bitmap orig_bm;
+/*
+ * Memory bitmap used during hibernation for marking allocated page frames that
+ * will contain copies of saveable pages.  During restore it is initially used
+ * for marking hibernation image pages, but then the set bits from it are
+ * duplicated in @orig_bm and it is released.  On highmem systems it is next
+ * used for marking "safe" highmem pages, but it has to be reinitialized for
+ * this purpose.
+ */
+static struct memory_bitmap copy_bm;
 
 /**
  *	swsusp_free - free pages allocated for the suspend.
@@ -1046,7 +1065,7 @@ void swsusp_free(void)
 	struct zone *zone;
 	unsigned long pfn, max_zone_pfn;
 
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages;
 		for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++)
 			if (pfn_valid(pfn)) {
@@ -1064,74 +1083,286 @@ void swsusp_free(void)
 	nr_meta_pages = 0;
 	restore_pblist = NULL;
 	buffer = NULL;
+	alloc_normal = 0;
+	alloc_highmem = 0;
 }
 
+/* Helper functions used for the shrinking of memory. */
+
+#define GFP_IMAGE	(GFP_KERNEL | __GFP_NOWARN)
+
 /**
- *	swsusp_shrink_memory -  Try to free as much memory as needed
- *
- *	... but do not OOM-kill anyone
+ * preallocate_image_pages - Allocate a number of pages for hibernation image
+ * @nr_pages: Number of page frames to allocate.
+ * @mask: GFP flags to use for the allocation.
  *
- *	Notice: all userland should be stopped before it is called, or
- *	livelock is possible.
+ * Return value: Number of page frames actually allocated
+ */
+static unsigned long preallocate_image_pages(unsigned long nr_pages, gfp_t mask)
+{
+	unsigned long nr_alloc = 0;
+
+	while (nr_pages > 0) {
+		struct page *page;
+
+		page = alloc_image_page(mask);
+		if (!page)
+			break;
+		memory_bm_set_bit(&copy_bm, page_to_pfn(page));
+		if (PageHighMem(page))
+			alloc_highmem++;
+		else
+			alloc_normal++;
+		nr_pages--;
+		nr_alloc++;
+	}
+
+	return nr_alloc;
+}
+
+static unsigned long preallocate_image_memory(unsigned long nr_pages)
+{
+	return preallocate_image_pages(nr_pages, GFP_IMAGE);
+}
+
+#ifdef CONFIG_HIGHMEM
+static unsigned long preallocate_image_highmem(unsigned long nr_pages)
+{
+	return preallocate_image_pages(nr_pages, GFP_IMAGE | __GFP_HIGHMEM);
+}
+
+/**
+ *  __fraction - Compute (an approximation of) x * (multiplier / base)
  */
+static unsigned long __fraction(u64 x, u64 multiplier, u64 base)
+{
+	x *= multiplier;
+	do_div(x, base);
+	return (unsigned long)x;
+}
+
+static unsigned long preallocate_highmem_fraction(unsigned long nr_pages,
+						unsigned long highmem,
+						unsigned long total)
+{
+	unsigned long alloc = __fraction(nr_pages, highmem, total);
 
-#define SHRINK_BITE	10000
-static inline unsigned long __shrink_memory(long tmp)
+	return preallocate_image_pages(alloc, GFP_IMAGE | __GFP_HIGHMEM);
+}
+#else /* CONFIG_HIGHMEM */
+static inline unsigned long preallocate_image_highmem(unsigned long nr_pages)
 {
-	if (tmp > SHRINK_BITE)
-		tmp = SHRINK_BITE;
-	return shrink_all_memory(tmp);
+	return 0;
 }
 
-int swsusp_shrink_memory(void)
+static inline unsigned long preallocate_highmem_fraction(unsigned long nr_pages,
+						unsigned long highmem,
+						unsigned long total)
+{
+	return 0;
+}
+#endif /* CONFIG_HIGHMEM */
+
+/**
+ * free_unnecessary_pages - Release preallocated pages not needed for the image
+ */
+static void free_unnecessary_pages(void)
+{
+	unsigned long save_highmem, to_free_normal, to_free_highmem;
+
+	to_free_normal = alloc_normal - count_data_pages();
+	save_highmem = count_highmem_pages();
+	if (alloc_highmem > save_highmem) {
+		to_free_highmem = alloc_highmem - save_highmem;
+	} else {
+		to_free_highmem = 0;
+		to_free_normal -= save_highmem - alloc_highmem;
+	}
+
+	memory_bm_position_reset(&copy_bm);
+
+	while (to_free_normal > 0 && to_free_highmem > 0) {
+		unsigned long pfn = memory_bm_next_pfn(&copy_bm);
+		struct page *page = pfn_to_page(pfn);
+
+		if (PageHighMem(page)) {
+			if (!to_free_highmem)
+				continue;
+			to_free_highmem--;
+			alloc_highmem--;
+		} else {
+			if (!to_free_normal)
+				continue;
+			to_free_normal--;
+			alloc_normal--;
+		}
+		memory_bm_clear_bit(&copy_bm, pfn);
+		swsusp_unset_page_forbidden(page);
+		swsusp_unset_page_free(page);
+		__free_page(page);
+	}
+}
+
+/**
+ * minimum_image_size - Estimate the minimum acceptable size of an image
+ * @saveable: Number of saveable pages in the system.
+ *
+ * We want to avoid attempting to free too much memory too hard, so estimate the
+ * minimum acceptable size of a hibernation image to use as the lower limit for
+ * preallocating memory.
+ *
+ * We assume that the minimum image size should be proportional to
+ *
+ * [number of saveable pages] - [number of pages that can be freed in theory]
+ *
+ * where the second term is the sum of (1) reclaimable slab pages, (2) active
+ * and (3) inactive anonymouns pages, (4) active and (5) inactive file pages,
+ * minus mapped file pages.
+ */
+static unsigned long minimum_image_size(unsigned long saveable)
+{
+	unsigned long size;
+
+	size = global_page_state(NR_SLAB_RECLAIMABLE)
+		+ global_page_state(NR_ACTIVE_ANON)
+		+ global_page_state(NR_INACTIVE_ANON)
+		+ global_page_state(NR_ACTIVE_FILE)
+		+ global_page_state(NR_INACTIVE_FILE)
+		- global_page_state(NR_FILE_MAPPED);
+
+	return saveable <= size ? 0 : saveable - size;
+}
+
+/**
+ * hibernate_preallocate_memory - Preallocate memory for hibernation image
+ *
+ * To create a hibernation image it is necessary to make a copy of every page
+ * frame in use.  We also need a number of page frames to be free during
+ * hibernation for allocations made while saving the image and for device
+ * drivers, in case they need to allocate memory from their hibernation
+ * callbacks (these two numbers are given by PAGES_FOR_IO and SPARE_PAGES,
+ * respectively, both of which are rough estimates).  To make this happen, we
+ * compute the total number of available page frames and allocate at least
+ *
+ * ([page frames total] + PAGES_FOR_IO + [metadata pages]) / 2 + 2 * SPARE_PAGES
+ *
+ * of them, which corresponds to the maximum size of a hibernation image.
+ *
+ * If image_size is set below the number following from the above formula,
+ * the preallocation of memory is continued until the total number of saveable
+ * pages in the system is below the requested image size or the minimum
+ * acceptable image size returned by minimum_image_size(), whichever is greater.
+ */
+int hibernate_preallocate_memory(void)
 {
-	long tmp;
 	struct zone *zone;
-	unsigned long pages = 0;
-	unsigned int i = 0;
-	char *p = "-\\|/";
+	unsigned long saveable, size, max_size, count, highmem, pages = 0;
+	unsigned long alloc, save_highmem, pages_highmem;
 	struct timeval start, stop;
+	int error;
 
-	printk(KERN_INFO "PM: Shrinking memory...  ");
+	printk(KERN_INFO "PM: Preallocating image memory... ");
 	do_gettimeofday(&start);
-	do {
-		long size, highmem_size;
-
-		highmem_size = count_highmem_pages();
-		size = count_data_pages() + PAGES_FOR_IO + SPARE_PAGES;
-		tmp = size;
-		size += highmem_size;
-		for_each_populated_zone(zone) {
-			tmp += snapshot_additional_pages(zone);
-			if (is_highmem(zone)) {
-				highmem_size -=
-					zone_page_state(zone, NR_FREE_PAGES);
-			} else {
-				tmp -= zone_page_state(zone, NR_FREE_PAGES);
-				tmp += zone->lowmem_reserve[ZONE_NORMAL];
-			}
-		}
 
-		if (highmem_size < 0)
-			highmem_size = 0;
+	error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY);
+	if (error)
+		goto err_out;
 
-		tmp += highmem_size;
-		if (tmp > 0) {
-			tmp = __shrink_memory(tmp);
-			if (!tmp)
-				return -ENOMEM;
-			pages += tmp;
-		} else if (size > image_size / PAGE_SIZE) {
-			tmp = __shrink_memory(size - (image_size / PAGE_SIZE));
-			pages += tmp;
-		}
-		printk("\b%c", p[i++%4]);
-	} while (tmp > 0);
+	error = memory_bm_create(&copy_bm, GFP_IMAGE, PG_ANY);
+	if (error)
+		goto err_out;
+
+	alloc_normal = 0;
+	alloc_highmem = 0;
+
+	/* Count the number of saveable data pages. */
+	save_highmem = count_highmem_pages();
+	saveable = count_data_pages();
+
+	/*
+	 * Compute the total number of page frames we can use (count) and the
+	 * number of pages needed for image metadata (size).
+	 */
+	count = saveable;
+	saveable += save_highmem;
+	highmem = save_highmem;
+	size = 0;
+	for_each_populated_zone(zone) {
+		size += snapshot_additional_pages(zone);
+		if (is_highmem(zone))
+			highmem += zone_page_state(zone, NR_FREE_PAGES);
+		else
+			count += zone_page_state(zone, NR_FREE_PAGES);
+	}
+	count += highmem;
+	count -= totalreserve_pages;
+
+	/* Compute the maximum number of saveable pages to leave in memory. */
+	max_size = (count - (size + PAGES_FOR_IO)) / 2 - 2 * SPARE_PAGES;
+	size = DIV_ROUND_UP(image_size, PAGE_SIZE);
+	if (size > max_size)
+		size = max_size;
+	/*
+	 * If the maximum is not less than the current number of saveable pages
+	 * in memory, allocate page frames for the image and we're done.
+	 */
+	if (size >= saveable) {
+		pages = preallocate_image_highmem(save_highmem);
+		pages += preallocate_image_memory(saveable - pages);
+		goto out;
+	}
+
+	/* Estimate the minimum size of the image. */
+	pages = minimum_image_size(saveable);
+	if (size < pages)
+		size = min_t(unsigned long, pages, max_size);
+
+	/*
+	 * Let the memory management subsystem know that we're going to need a
+	 * large number of page frames to allocate and make it free some memory.
+	 * NOTE: If this is not done, performance will be hurt badly in some
+	 * test cases.
+	 */
+	shrink_all_memory(saveable - size);
+
+	/*
+	 * The number of saveable pages in memory was too high, so apply some
+	 * pressure to decrease it.  First, make room for the largest possible
+	 * image and fail if that doesn't work.  Next, try to decrease the size
+	 * of the image as much as indicated by 'size' using allocations from
+	 * highmem and non-highmem zones separately.
+	 */
+	pages_highmem = preallocate_image_highmem(highmem / 2);
+	alloc = (count - max_size) - pages_highmem;
+	pages = preallocate_image_memory(alloc);
+	if (pages < alloc)
+		goto err_out;
+	size = max_size - size;
+	alloc = size;
+	size = preallocate_highmem_fraction(size, highmem, count);
+	pages_highmem += size;
+	alloc -= size;
+	pages += preallocate_image_memory(alloc);
+	pages += pages_highmem;
+
+	/*
+	 * We only need as many page frames for the image as there are saveable
+	 * pages in memory, but we have allocated more.  Release the excessive
+	 * ones now.
+	 */
+	free_unnecessary_pages();
+
+ out:
 	do_gettimeofday(&stop);
-	printk("\bdone (%lu pages freed)\n", pages);
-	swsusp_show_speed(&start, &stop, pages, "Freed");
+	printk(KERN_CONT "done (allocated %lu pages)\n", pages);
+	swsusp_show_speed(&start, &stop, pages, "Allocated");
 
 	return 0;
+
+ err_out:
+	printk(KERN_CONT "\n");
+	swsusp_free();
+	return -ENOMEM;
 }
 
 #ifdef CONFIG_HIGHMEM
@@ -1142,7 +1373,7 @@ int swsusp_shrink_memory(void)
 
 static unsigned int count_pages_for_highmem(unsigned int nr_highmem)
 {
-	unsigned int free_highmem = count_free_highmem_pages();
+	unsigned int free_highmem = count_free_highmem_pages() + alloc_highmem;
 
 	if (free_highmem >= nr_highmem)
 		nr_highmem = 0;
@@ -1164,19 +1395,17 @@ count_pages_for_highmem(unsigned int nr_highmem) { return 0; }
 static int enough_free_mem(unsigned int nr_pages, unsigned int nr_highmem)
 {
 	struct zone *zone;
-	unsigned int free = 0, meta = 0;
+	unsigned int free = alloc_normal;
 
-	for_each_zone(zone) {
-		meta += snapshot_additional_pages(zone);
+	for_each_populated_zone(zone)
 		if (!is_highmem(zone))
 			free += zone_page_state(zone, NR_FREE_PAGES);
-	}
 
 	nr_pages += count_pages_for_highmem(nr_highmem);
-	pr_debug("PM: Normal pages needed: %u + %u + %u, available pages: %u\n",
-		nr_pages, PAGES_FOR_IO, meta, free);
+	pr_debug("PM: Normal pages needed: %u + %u, available pages: %u\n",
+		nr_pages, PAGES_FOR_IO, free);
 
-	return free > nr_pages + PAGES_FOR_IO + meta;
+	return free > nr_pages + PAGES_FOR_IO;
 }
 
 #ifdef CONFIG_HIGHMEM
@@ -1198,7 +1427,7 @@ static inline int get_highmem_buffer(int safe_needed)
  */
 
 static inline unsigned int
-alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int nr_highmem)
+alloc_highmem_pages(struct memory_bitmap *bm, unsigned int nr_highmem)
 {
 	unsigned int to_alloc = count_free_highmem_pages();
 
@@ -1218,7 +1447,7 @@ alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int nr_highmem)
 static inline int get_highmem_buffer(int safe_needed) { return 0; }
 
 static inline unsigned int
-alloc_highmem_image_pages(struct memory_bitmap *bm, unsigned int n) { return 0; }
+alloc_highmem_pages(struct memory_bitmap *bm, unsigned int n) { return 0; }
 #endif /* CONFIG_HIGHMEM */
 
 /**
@@ -1237,51 +1466,36 @@ static int
 swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm,
 		unsigned int nr_pages, unsigned int nr_highmem)
 {
-	int error;
-
-	error = memory_bm_create(orig_bm, GFP_ATOMIC | __GFP_COLD, PG_ANY);
-	if (error)
-		goto Free;
-
-	error = memory_bm_create(copy_bm, GFP_ATOMIC | __GFP_COLD, PG_ANY);
-	if (error)
-		goto Free;
+	int error = 0;
 
 	if (nr_highmem > 0) {
 		error = get_highmem_buffer(PG_ANY);
 		if (error)
-			goto Free;
-
-		nr_pages += alloc_highmem_image_pages(copy_bm, nr_highmem);
+			goto err_out;
+		if (nr_highmem > alloc_highmem) {
+			nr_highmem -= alloc_highmem;
+			nr_pages += alloc_highmem_pages(copy_bm, nr_highmem);
+		}
 	}
-	while (nr_pages-- > 0) {
-		struct page *page = alloc_image_page(GFP_ATOMIC | __GFP_COLD);
-
-		if (!page)
-			goto Free;
+	if (nr_pages > alloc_normal) {
+		nr_pages -= alloc_normal;
+		while (nr_pages-- > 0) {
+			struct page *page;
 
-		memory_bm_set_bit(copy_bm, page_to_pfn(page));
+			page = alloc_image_page(GFP_ATOMIC | __GFP_COLD);
+			if (!page)
+				goto err_out;
+			memory_bm_set_bit(copy_bm, page_to_pfn(page));
+		}
 	}
+
 	return 0;
 
- Free:
+ err_out:
 	swsusp_free();
-	return -ENOMEM;
+	return error;
 }
 
-/* Memory bitmap used for marking saveable pages (during suspend) or the
- * suspend image pages (during resume)
- */
-static struct memory_bitmap orig_bm;
-/* Memory bitmap used on suspend for marking allocated pages that will contain
- * the copies of saveable pages.  During resume it is initially used for
- * marking the suspend image pages, but then its set bits are duplicated in
- * @orig_bm and it is released.  Next, on systems with high memory, it may be
- * used for marking "safe" highmem pages, but it has to be reinitialized for
- * this purpose.
- */
-static struct memory_bitmap copy_bm;
-
 asmlinkage int swsusp_save(void)
 {
 	unsigned int nr_pages, nr_highmem;
@@ -1474,7 +1688,7 @@ static int mark_unsafe_pages(struct memory_bitmap *bm)
 	unsigned long pfn, max_zone_pfn;
 
 	/* Clear page flags */
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages;
 		for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++)
 			if (pfn_valid(pfn))
diff --git a/kernel/printk.c b/kernel/printk.c
index e10d193..602033a 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1075,12 +1075,6 @@ void __sched console_conditional_schedule(void)
 }
 EXPORT_SYMBOL(console_conditional_schedule);
 
-void console_print(const char *s)
-{
-	printk(KERN_EMERG "%s", s);
-}
-EXPORT_SYMBOL(console_print);
-
 void console_unblank(void)
 {
 	struct console *c;
diff --git a/kernel/profile.c b/kernel/profile.c
index 419250e..a55d3a3 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -442,48 +442,51 @@ void profile_tick(int type)
 
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <asm/uaccess.h>
 
-static int prof_cpu_mask_read_proc(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
+static int prof_cpu_mask_proc_show(struct seq_file *m, void *v)
 {
-	int len = cpumask_scnprintf(page, count, data);
-	if (count - len < 2)
-		return -EINVAL;
-	len += sprintf(page + len, "\n");
-	return len;
+	seq_cpumask(m, prof_cpu_mask);
+	seq_putc(m, '\n');
+	return 0;
 }
 
-static int prof_cpu_mask_write_proc(struct file *file,
-	const char __user *buffer,  unsigned long count, void *data)
+static int prof_cpu_mask_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, prof_cpu_mask_proc_show, NULL);
+}
+
+static ssize_t prof_cpu_mask_proc_write(struct file *file,
+	const char __user *buffer, size_t count, loff_t *pos)
 {
-	struct cpumask *mask = data;
-	unsigned long full_count = count, err;
 	cpumask_var_t new_value;
+	int err;
 
 	if (!alloc_cpumask_var(&new_value, GFP_KERNEL))
 		return -ENOMEM;
 
 	err = cpumask_parse_user(buffer, count, new_value);
 	if (!err) {
-		cpumask_copy(mask, new_value);
-		err = full_count;
+		cpumask_copy(prof_cpu_mask, new_value);
+		err = count;
 	}
 	free_cpumask_var(new_value);
 	return err;
 }
 
+static const struct file_operations prof_cpu_mask_proc_fops = {
+	.open		= prof_cpu_mask_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= prof_cpu_mask_proc_write,
+};
+
 void create_prof_cpu_mask(struct proc_dir_entry *root_irq_dir)
 {
-	struct proc_dir_entry *entry;
-
 	/* create /proc/irq/prof_cpu_mask */
-	entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
-	if (!entry)
-		return;
-	entry->data = prof_cpu_mask;
-	entry->read_proc = prof_cpu_mask_read_proc;
-	entry->write_proc = prof_cpu_mask_write_proc;
+	proc_create("prof_cpu_mask", 0600, root_irq_dir, &prof_cpu_mask_proc_fops);
 }
 
 /*
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index bd5d5c8..37ac454 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -19,7 +19,7 @@
  *
  * Authors: Dipankar Sarma <dipankar@in.ibm.com>
  *	    Manfred Spraul <manfred@colorfullife.com>
- * 
+ *
  * Based on the original work by Paul McKenney <paulmck@us.ibm.com>
  * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
  * Papers:
@@ -27,7 +27,7 @@
  * http://lse.sourceforge.net/locking/rclock_OLS.2001.05.01c.sc.pdf (OLS2001)
  *
  * For detailed explanation of Read-Copy Update mechanism see -
- * 		http://lse.sourceforge.net/locking/rcupdate.html
+ *		http://lse.sourceforge.net/locking/rcupdate.html
  *
  */
 #include <linux/types.h>
@@ -74,6 +74,8 @@ void wakeme_after_rcu(struct rcu_head  *head)
 	complete(&rcu->completion);
 }
 
+#ifdef CONFIG_TREE_PREEMPT_RCU
+
 /**
  * synchronize_rcu - wait until a grace period has elapsed.
  *
@@ -87,7 +89,7 @@ void synchronize_rcu(void)
 {
 	struct rcu_synchronize rcu;
 
-	if (rcu_blocking_is_gp())
+	if (!rcu_scheduler_active)
 		return;
 
 	init_completion(&rcu.completion);
@@ -98,6 +100,46 @@ void synchronize_rcu(void)
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
+#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
+
+/**
+ * synchronize_sched - wait until an rcu-sched grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu-sched
+ * grace period has elapsed, in other words after all currently executing
+ * rcu-sched read-side critical sections have completed.   These read-side
+ * critical sections are delimited by rcu_read_lock_sched() and
+ * rcu_read_unlock_sched(), and may be nested.  Note that preempt_disable(),
+ * local_irq_disable(), and so on may be used in place of
+ * rcu_read_lock_sched().
+ *
+ * This means that all preempt_disable code sequences, including NMI and
+ * hardware-interrupt handlers, in progress on entry will have completed
+ * before this primitive returns.  However, this does not guarantee that
+ * softirq handlers will have completed, since in some kernels, these
+ * handlers can run in process context, and can block.
+ *
+ * This primitive provides the guarantees made by the (now removed)
+ * synchronize_kernel() API.  In contrast, synchronize_rcu() only
+ * guarantees that rcu_read_lock() sections will have completed.
+ * In "classic RCU", these two guarantees happen to be one and
+ * the same, but can differ in realtime RCU implementations.
+ */
+void synchronize_sched(void)
+{
+	struct rcu_synchronize rcu;
+
+	if (rcu_blocking_is_gp())
+		return;
+
+	init_completion(&rcu.completion);
+	/* Will wake me after RCU finished. */
+	call_rcu_sched(&rcu.head, wakeme_after_rcu);
+	/* Wait for it. */
+	wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(synchronize_sched);
+
 /**
  * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
  *
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index b33db53..233768f 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -18,7 +18,7 @@
  * Copyright (C) IBM Corporation, 2005, 2006
  *
  * Authors: Paul E. McKenney <paulmck@us.ibm.com>
- *          Josh Triplett <josh@freedesktop.org>
+ *	  Josh Triplett <josh@freedesktop.org>
  *
  * See also:  Documentation/RCU/torture.txt
  */
@@ -50,7 +50,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and "
-              "Josh Triplett <josh@freedesktop.org>");
+	      "Josh Triplett <josh@freedesktop.org>");
 
 static int nreaders = -1;	/* # reader threads, defaults to 2*ncpus */
 static int nfakewriters = 4;	/* # fake writer threads */
@@ -110,8 +110,8 @@ struct rcu_torture {
 };
 
 static LIST_HEAD(rcu_torture_freelist);
-static struct rcu_torture *rcu_torture_current = NULL;
-static long rcu_torture_current_version = 0;
+static struct rcu_torture *rcu_torture_current;
+static long rcu_torture_current_version;
 static struct rcu_torture rcu_tortures[10 * RCU_TORTURE_PIPE_LEN];
 static DEFINE_SPINLOCK(rcu_torture_lock);
 static DEFINE_PER_CPU(long [RCU_TORTURE_PIPE_LEN + 1], rcu_torture_count) =
@@ -124,11 +124,11 @@ static atomic_t n_rcu_torture_alloc_fail;
 static atomic_t n_rcu_torture_free;
 static atomic_t n_rcu_torture_mberror;
 static atomic_t n_rcu_torture_error;
-static long n_rcu_torture_timers = 0;
+static long n_rcu_torture_timers;
 static struct list_head rcu_torture_removed;
 static cpumask_var_t shuffle_tmp_mask;
 
-static int stutter_pause_test = 0;
+static int stutter_pause_test;
 
 #if defined(MODULE) || defined(CONFIG_RCU_TORTURE_TEST_RUNNABLE)
 #define RCUTORTURE_RUNNABLE_INIT 1
@@ -267,7 +267,8 @@ struct rcu_torture_ops {
 	int irq_capable;
 	char *name;
 };
-static struct rcu_torture_ops *cur_ops = NULL;
+
+static struct rcu_torture_ops *cur_ops;
 
 /*
  * Definitions for rcu torture testing.
@@ -281,14 +282,17 @@ static int rcu_torture_read_lock(void) __acquires(RCU)
 
 static void rcu_read_delay(struct rcu_random_state *rrsp)
 {
-	long delay;
-	const long longdelay = 200;
+	const unsigned long shortdelay_us = 200;
+	const unsigned long longdelay_ms = 50;
 
-	/* We want there to be long-running readers, but not all the time. */
+	/* We want a short delay sometimes to make a reader delay the grace
+	 * period, and we want a long delay occasionally to trigger
+	 * force_quiescent_state. */
 
-	delay = rcu_random(rrsp) % (nrealreaders * 2 * longdelay);
-	if (!delay)
-		udelay(longdelay);
+	if (!(rcu_random(rrsp) % (nrealreaders * 2000 * longdelay_ms)))
+		mdelay(longdelay_ms);
+	if (!(rcu_random(rrsp) % (nrealreaders * 2 * shortdelay_us)))
+		udelay(shortdelay_us);
 }
 
 static void rcu_torture_read_unlock(int idx) __releases(RCU)
@@ -339,8 +343,8 @@ static struct rcu_torture_ops rcu_ops = {
 	.sync		= synchronize_rcu,
 	.cb_barrier	= rcu_barrier,
 	.stats		= NULL,
-	.irq_capable 	= 1,
-	.name 		= "rcu"
+	.irq_capable	= 1,
+	.name		= "rcu"
 };
 
 static void rcu_sync_torture_deferred_free(struct rcu_torture *p)
@@ -638,7 +642,8 @@ rcu_torture_writer(void *arg)
 
 	do {
 		schedule_timeout_uninterruptible(1);
-		if ((rp = rcu_torture_alloc()) == NULL)
+		rp = rcu_torture_alloc();
+		if (rp == NULL)
 			continue;
 		rp->rtort_pipe_count = 0;
 		udelay(rcu_random(&rand) & 0x3ff);
@@ -1110,7 +1115,7 @@ rcu_torture_init(void)
 		printk(KERN_ALERT "rcutorture: invalid torture type: \"%s\"\n",
 		       torture_type);
 		mutex_unlock(&fullstop_mutex);
-		return (-EINVAL);
+		return -EINVAL;
 	}
 	if (cur_ops->init)
 		cur_ops->init(); /* no "goto unwind" prior to this point!!! */
@@ -1161,7 +1166,7 @@ rcu_torture_init(void)
 		goto unwind;
 	}
 	fakewriter_tasks = kzalloc(nfakewriters * sizeof(fakewriter_tasks[0]),
-	                           GFP_KERNEL);
+				   GFP_KERNEL);
 	if (fakewriter_tasks == NULL) {
 		VERBOSE_PRINTK_ERRSTRING("out of memory");
 		firsterr = -ENOMEM;
@@ -1170,7 +1175,7 @@ rcu_torture_init(void)
 	for (i = 0; i < nfakewriters; i++) {
 		VERBOSE_PRINTK_STRING("Creating rcu_torture_fakewriter task");
 		fakewriter_tasks[i] = kthread_run(rcu_torture_fakewriter, NULL,
-		                                  "rcu_torture_fakewriter");
+						  "rcu_torture_fakewriter");
 		if (IS_ERR(fakewriter_tasks[i])) {
 			firsterr = PTR_ERR(fakewriter_tasks[i]);
 			VERBOSE_PRINTK_ERRSTRING("Failed to create fakewriter");
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 6b11b07..52b06f6 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -25,7 +25,7 @@
  * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen.
  *
  * For detailed explanation of Read-Copy Update mechanism see -
- * 	Documentation/RCU
+ *	Documentation/RCU
  */
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -107,27 +107,23 @@ static void __cpuinit rcu_init_percpu_data(int cpu, struct rcu_state *rsp,
  */
 void rcu_sched_qs(int cpu)
 {
-	unsigned long flags;
 	struct rcu_data *rdp;
 
-	local_irq_save(flags);
 	rdp = &per_cpu(rcu_sched_data, cpu);
-	rdp->passed_quiesc = 1;
 	rdp->passed_quiesc_completed = rdp->completed;
-	rcu_preempt_qs(cpu);
-	local_irq_restore(flags);
+	barrier();
+	rdp->passed_quiesc = 1;
+	rcu_preempt_note_context_switch(cpu);
 }
 
 void rcu_bh_qs(int cpu)
 {
-	unsigned long flags;
 	struct rcu_data *rdp;
 
-	local_irq_save(flags);
 	rdp = &per_cpu(rcu_bh_data, cpu);
-	rdp->passed_quiesc = 1;
 	rdp->passed_quiesc_completed = rdp->completed;
-	local_irq_restore(flags);
+	barrier();
+	rdp->passed_quiesc = 1;
 }
 
 #ifdef CONFIG_NO_HZ
@@ -605,8 +601,6 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
 {
 	struct rcu_data *rdp = rsp->rda[smp_processor_id()];
 	struct rcu_node *rnp = rcu_get_root(rsp);
-	struct rcu_node *rnp_cur;
-	struct rcu_node *rnp_end;
 
 	if (!cpu_needs_another_gp(rsp, rdp)) {
 		spin_unlock_irqrestore(&rnp->lock, flags);
@@ -615,6 +609,7 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
 
 	/* Advance to a new grace period and initialize state. */
 	rsp->gpnum++;
+	WARN_ON_ONCE(rsp->signaled == RCU_GP_INIT);
 	rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */
 	rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
 	record_gp_stall_check_time(rsp);
@@ -631,7 +626,9 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
 
 	/* Special-case the common single-level case. */
 	if (NUM_RCU_NODES == 1) {
+		rcu_preempt_check_blocked_tasks(rnp);
 		rnp->qsmask = rnp->qsmaskinit;
+		rnp->gpnum = rsp->gpnum;
 		rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state OK. */
 		spin_unlock_irqrestore(&rnp->lock, flags);
 		return;
@@ -644,42 +641,28 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
 	spin_lock(&rsp->onofflock);  /* irqs already disabled. */
 
 	/*
-	 * Set the quiescent-state-needed bits in all the non-leaf RCU
-	 * nodes for all currently online CPUs.  This operation relies
-	 * on the layout of the hierarchy within the rsp->node[] array.
-	 * Note that other CPUs will access only the leaves of the
-	 * hierarchy, which still indicate that no grace period is in
-	 * progress.  In addition, we have excluded CPU-hotplug operations.
-	 *
-	 * We therefore do not need to hold any locks.  Any required
-	 * memory barriers will be supplied by the locks guarding the
-	 * leaf rcu_nodes in the hierarchy.
-	 */
-
-	rnp_end = rsp->level[NUM_RCU_LVLS - 1];
-	for (rnp_cur = &rsp->node[0]; rnp_cur < rnp_end; rnp_cur++)
-		rnp_cur->qsmask = rnp_cur->qsmaskinit;
-
-	/*
-	 * Now set up the leaf nodes.  Here we must be careful.  First,
-	 * we need to hold the lock in order to exclude other CPUs, which
-	 * might be contending for the leaf nodes' locks.  Second, as
-	 * soon as we initialize a given leaf node, its CPUs might run
-	 * up the rest of the hierarchy.  We must therefore acquire locks
-	 * for each node that we touch during this stage.  (But we still
-	 * are excluding CPU-hotplug operations.)
+	 * Set the quiescent-state-needed bits in all the rcu_node
+	 * structures for all currently online CPUs in breadth-first
+	 * order, starting from the root rcu_node structure.  This
+	 * operation relies on the layout of the hierarchy within the
+	 * rsp->node[] array.  Note that other CPUs will access only
+	 * the leaves of the hierarchy, which still indicate that no
+	 * grace period is in progress, at least until the corresponding
+	 * leaf node has been initialized.  In addition, we have excluded
+	 * CPU-hotplug operations.
 	 *
 	 * Note that the grace period cannot complete until we finish
 	 * the initialization process, as there will be at least one
 	 * qsmask bit set in the root node until that time, namely the
-	 * one corresponding to this CPU.
+	 * one corresponding to this CPU, due to the fact that we have
+	 * irqs disabled.
 	 */
-	rnp_end = &rsp->node[NUM_RCU_NODES];
-	rnp_cur = rsp->level[NUM_RCU_LVLS - 1];
-	for (; rnp_cur < rnp_end; rnp_cur++) {
-		spin_lock(&rnp_cur->lock);	/* irqs already disabled. */
-		rnp_cur->qsmask = rnp_cur->qsmaskinit;
-		spin_unlock(&rnp_cur->lock);	/* irqs already disabled. */
+	for (rnp = &rsp->node[0]; rnp < &rsp->node[NUM_RCU_NODES]; rnp++) {
+		spin_lock(&rnp->lock);	/* irqs already disabled. */
+		rcu_preempt_check_blocked_tasks(rnp);
+		rnp->qsmask = rnp->qsmaskinit;
+		rnp->gpnum = rsp->gpnum;
+		spin_unlock(&rnp->lock);	/* irqs already disabled. */
 	}
 
 	rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state now OK. */
@@ -722,6 +705,7 @@ rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
 static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
 	__releases(rnp->lock)
 {
+	WARN_ON_ONCE(rsp->completed == rsp->gpnum);
 	rsp->completed = rsp->gpnum;
 	rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
 	rcu_start_gp(rsp, flags);  /* releases root node's rnp->lock. */
@@ -739,6 +723,8 @@ cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp,
 	      unsigned long flags)
 	__releases(rnp->lock)
 {
+	struct rcu_node *rnp_c;
+
 	/* Walk up the rcu_node hierarchy. */
 	for (;;) {
 		if (!(rnp->qsmask & mask)) {
@@ -762,8 +748,10 @@ cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp,
 			break;
 		}
 		spin_unlock_irqrestore(&rnp->lock, flags);
+		rnp_c = rnp;
 		rnp = rnp->parent;
 		spin_lock_irqsave(&rnp->lock, flags);
+		WARN_ON_ONCE(rnp_c->qsmask);
 	}
 
 	/*
@@ -776,10 +764,10 @@ cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp,
 
 /*
  * Record a quiescent state for the specified CPU, which must either be
- * the current CPU or an offline CPU.  The lastcomp argument is used to
- * make sure we are still in the grace period of interest.  We don't want
- * to end the current grace period based on quiescent states detected in
- * an earlier grace period!
+ * the current CPU.  The lastcomp argument is used to make sure we are
+ * still in the grace period of interest.  We don't want to end the current
+ * grace period based on quiescent states detected in an earlier grace
+ * period!
  */
 static void
 cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
@@ -814,7 +802,6 @@ cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
 		 * This GP can't end until cpu checks in, so all of our
 		 * callbacks can be processed during the next GP.
 		 */
-		rdp = rsp->rda[smp_processor_id()];
 		rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
 
 		cpu_quiet_msk(mask, rsp, rnp, flags); /* releases rnp->lock */
@@ -872,7 +859,7 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
 	spin_lock_irqsave(&rsp->onofflock, flags);
 
 	/* Remove the outgoing CPU from the masks in the rcu_node hierarchy. */
-	rnp = rdp->mynode;
+	rnp = rdp->mynode;	/* this is the outgoing CPU's rnp. */
 	mask = rdp->grpmask;	/* rnp->grplo is constant. */
 	do {
 		spin_lock(&rnp->lock);		/* irqs already disabled. */
@@ -881,7 +868,7 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
 			spin_unlock(&rnp->lock); /* irqs remain disabled. */
 			break;
 		}
-		rcu_preempt_offline_tasks(rsp, rnp);
+		rcu_preempt_offline_tasks(rsp, rnp, rdp);
 		mask = rnp->grpmask;
 		spin_unlock(&rnp->lock);	/* irqs remain disabled. */
 		rnp = rnp->parent;
@@ -890,9 +877,6 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
 
 	spin_unlock(&rsp->onofflock);		/* irqs remain disabled. */
 
-	/* Being offline is a quiescent state, so go record it. */
-	cpu_quiet(cpu, rsp, rdp, lastcomp);
-
 	/*
 	 * Move callbacks from the outgoing CPU to the running CPU.
 	 * Note that the outgoing CPU is now quiscent, so it is now
@@ -1457,20 +1441,7 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
 		rnp = rnp->parent;
 	} while (rnp != NULL && !(rnp->qsmaskinit & mask));
 
-	spin_unlock(&rsp->onofflock);		/* irqs remain disabled. */
-
-	/*
-	 * A new grace period might start here.  If so, we will be part of
-	 * it, and its gpnum will be greater than ours, so we will
-	 * participate.  It is also possible for the gpnum to have been
-	 * incremented before this function was called, and the bitmasks
-	 * to not be filled out until now, in which case we will also
-	 * participate due to our gpnum being behind.
-	 */
-
-	/* Since it is coming online, the CPU is in a quiescent state. */
-	cpu_quiet(cpu, rsp, rdp, lastcomp);
-	local_irq_restore(flags);
+	spin_unlock_irqrestore(&rsp->onofflock, flags);
 }
 
 static void __cpuinit rcu_online_cpu(int cpu)
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index bf8a6f9..8e8287a 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -142,7 +142,7 @@ struct rcu_data {
 	 */
 	struct rcu_head *nxtlist;
 	struct rcu_head **nxttail[RCU_NEXT_SIZE];
-	long		qlen; 	 	/* # of queued callbacks */
+	long		qlen;		/* # of queued callbacks */
 	long		blimit;		/* Upper limit on a processed batch */
 
 #ifdef CONFIG_NO_HZ
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index 4778936..1cee04f 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -64,22 +64,31 @@ EXPORT_SYMBOL_GPL(rcu_batches_completed);
  * not in a quiescent state.  There might be any number of tasks blocked
  * while in an RCU read-side critical section.
  */
-static void rcu_preempt_qs_record(int cpu)
+static void rcu_preempt_qs(int cpu)
 {
 	struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
-	rdp->passed_quiesc = 1;
 	rdp->passed_quiesc_completed = rdp->completed;
+	barrier();
+	rdp->passed_quiesc = 1;
 }
 
 /*
- * We have entered the scheduler or are between softirqs in ksoftirqd.
- * If we are in an RCU read-side critical section, we need to reflect
- * that in the state of the rcu_node structure corresponding to this CPU.
- * Caller must disable hardirqs.
+ * We have entered the scheduler, and the current task might soon be
+ * context-switched away from.  If this task is in an RCU read-side
+ * critical section, we will no longer be able to rely on the CPU to
+ * record that fact, so we enqueue the task on the appropriate entry
+ * of the blocked_tasks[] array.  The task will dequeue itself when
+ * it exits the outermost enclosing RCU read-side critical section.
+ * Therefore, the current grace period cannot be permitted to complete
+ * until the blocked_tasks[] entry indexed by the low-order bit of
+ * rnp->gpnum empties.
+ *
+ * Caller must disable preemption.
  */
-static void rcu_preempt_qs(int cpu)
+static void rcu_preempt_note_context_switch(int cpu)
 {
 	struct task_struct *t = current;
+	unsigned long flags;
 	int phase;
 	struct rcu_data *rdp;
 	struct rcu_node *rnp;
@@ -90,7 +99,7 @@ static void rcu_preempt_qs(int cpu)
 		/* Possibly blocking in an RCU read-side critical section. */
 		rdp = rcu_preempt_state.rda[cpu];
 		rnp = rdp->mynode;
-		spin_lock(&rnp->lock);
+		spin_lock_irqsave(&rnp->lock, flags);
 		t->rcu_read_unlock_special |= RCU_READ_UNLOCK_BLOCKED;
 		t->rcu_blocked_node = rnp;
 
@@ -103,11 +112,15 @@ static void rcu_preempt_qs(int cpu)
 		 * state for the current grace period), then as long
 		 * as that task remains queued, the current grace period
 		 * cannot end.
+		 *
+		 * But first, note that the current CPU must still be
+		 * on line!
 		 */
-		phase = !(rnp->qsmask & rdp->grpmask) ^ (rnp->gpnum & 0x1);
+		WARN_ON_ONCE((rdp->grpmask & rnp->qsmaskinit) == 0);
+		WARN_ON_ONCE(!list_empty(&t->rcu_node_entry));
+		phase = (rnp->gpnum + !(rnp->qsmask & rdp->grpmask)) & 0x1;
 		list_add(&t->rcu_node_entry, &rnp->blocked_tasks[phase]);
-		smp_mb();  /* Ensure later ctxt swtch seen after above. */
-		spin_unlock(&rnp->lock);
+		spin_unlock_irqrestore(&rnp->lock, flags);
 	}
 
 	/*
@@ -119,9 +132,10 @@ static void rcu_preempt_qs(int cpu)
 	 * grace period, then the fact that the task has been enqueued
 	 * means that we continue to block the current grace period.
 	 */
-	rcu_preempt_qs_record(cpu);
-	t->rcu_read_unlock_special &= ~(RCU_READ_UNLOCK_NEED_QS |
-					RCU_READ_UNLOCK_GOT_QS);
+	rcu_preempt_qs(cpu);
+	local_irq_save(flags);
+	t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
+	local_irq_restore(flags);
 }
 
 /*
@@ -157,7 +171,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
 	special = t->rcu_read_unlock_special;
 	if (special & RCU_READ_UNLOCK_NEED_QS) {
 		t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
-		t->rcu_read_unlock_special |= RCU_READ_UNLOCK_GOT_QS;
+		rcu_preempt_qs(smp_processor_id());
 	}
 
 	/* Hardware IRQ handlers cannot block. */
@@ -177,10 +191,10 @@ static void rcu_read_unlock_special(struct task_struct *t)
 		 */
 		for (;;) {
 			rnp = t->rcu_blocked_node;
-			spin_lock(&rnp->lock);
+			spin_lock(&rnp->lock);  /* irqs already disabled. */
 			if (rnp == t->rcu_blocked_node)
 				break;
-			spin_unlock(&rnp->lock);
+			spin_unlock(&rnp->lock);  /* irqs remain disabled. */
 		}
 		empty = list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
 		list_del_init(&t->rcu_node_entry);
@@ -194,9 +208,8 @@ static void rcu_read_unlock_special(struct task_struct *t)
 		 */
 		if (!empty && rnp->qsmask == 0 &&
 		    list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1])) {
-			t->rcu_read_unlock_special &=
-				~(RCU_READ_UNLOCK_NEED_QS |
-				  RCU_READ_UNLOCK_GOT_QS);
+			struct rcu_node *rnp_p;
+
 			if (rnp->parent == NULL) {
 				/* Only one rcu_node in the tree. */
 				cpu_quiet_msk_finish(&rcu_preempt_state, flags);
@@ -205,9 +218,10 @@ static void rcu_read_unlock_special(struct task_struct *t)
 			/* Report up the rest of the hierarchy. */
 			mask = rnp->grpmask;
 			spin_unlock_irqrestore(&rnp->lock, flags);
-			rnp = rnp->parent;
-			spin_lock_irqsave(&rnp->lock, flags);
-			cpu_quiet_msk(mask, &rcu_preempt_state, rnp, flags);
+			rnp_p = rnp->parent;
+			spin_lock_irqsave(&rnp_p->lock, flags);
+			WARN_ON_ONCE(rnp->qsmask);
+			cpu_quiet_msk(mask, &rcu_preempt_state, rnp_p, flags);
 			return;
 		}
 		spin_unlock(&rnp->lock);
@@ -259,6 +273,19 @@ static void rcu_print_task_stall(struct rcu_node *rnp)
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
 
 /*
+ * Check that the list of blocked tasks for the newly completed grace
+ * period is in fact empty.  It is a serious bug to complete a grace
+ * period that still has RCU readers blocked!  This function must be
+ * invoked -before- updating this rnp's ->gpnum, and the rnp's ->lock
+ * must be held by the caller.
+ */
+static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
+{
+	WARN_ON_ONCE(!list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]));
+	WARN_ON_ONCE(rnp->qsmask);
+}
+
+/*
  * Check for preempted RCU readers for the specified rcu_node structure.
  * If the caller needs a reliable answer, it must hold the rcu_node's
  * >lock.
@@ -280,7 +307,8 @@ static int rcu_preempted_readers(struct rcu_node *rnp)
  * The caller must hold rnp->lock with irqs disabled.
  */
 static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
-				      struct rcu_node *rnp)
+				      struct rcu_node *rnp,
+				      struct rcu_data *rdp)
 {
 	int i;
 	struct list_head *lp;
@@ -292,6 +320,9 @@ static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
 		WARN_ONCE(1, "Last CPU thought to be offlined?");
 		return;  /* Shouldn't happen: at least one CPU online. */
 	}
+	WARN_ON_ONCE(rnp != rdp->mynode &&
+		     (!list_empty(&rnp->blocked_tasks[0]) ||
+		      !list_empty(&rnp->blocked_tasks[1])));
 
 	/*
 	 * Move tasks up to root rcu_node.  Rely on the fact that the
@@ -335,20 +366,12 @@ static void rcu_preempt_check_callbacks(int cpu)
 	struct task_struct *t = current;
 
 	if (t->rcu_read_lock_nesting == 0) {
-		t->rcu_read_unlock_special &=
-			~(RCU_READ_UNLOCK_NEED_QS | RCU_READ_UNLOCK_GOT_QS);
-		rcu_preempt_qs_record(cpu);
+		t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_NEED_QS;
+		rcu_preempt_qs(cpu);
 		return;
 	}
-	if (per_cpu(rcu_preempt_data, cpu).qs_pending) {
-		if (t->rcu_read_unlock_special & RCU_READ_UNLOCK_GOT_QS) {
-			rcu_preempt_qs_record(cpu);
-			t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_GOT_QS;
-		} else if (!(t->rcu_read_unlock_special &
-			     RCU_READ_UNLOCK_NEED_QS)) {
-			t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS;
-		}
-	}
+	if (per_cpu(rcu_preempt_data, cpu).qs_pending)
+		t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS;
 }
 
 /*
@@ -434,7 +457,7 @@ EXPORT_SYMBOL_GPL(rcu_batches_completed);
  * Because preemptable RCU does not exist, we never have to check for
  * CPUs being in quiescent states.
  */
-static void rcu_preempt_qs(int cpu)
+static void rcu_preempt_note_context_switch(int cpu)
 {
 }
 
@@ -451,6 +474,16 @@ static void rcu_print_task_stall(struct rcu_node *rnp)
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
 
 /*
+ * Because there is no preemptable RCU, there can be no readers blocked,
+ * so there is no need to check for blocked tasks.  So check only for
+ * bogus qsmask values.
+ */
+static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
+{
+	WARN_ON_ONCE(rnp->qsmask);
+}
+
+/*
  * Because preemptable RCU does not exist, there are never any preempted
  * RCU readers.
  */
@@ -466,7 +499,8 @@ static int rcu_preempted_readers(struct rcu_node *rnp)
  * tasks that were blocked within RCU read-side critical sections.
  */
 static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
-				      struct rcu_node *rnp)
+				      struct rcu_node *rnp,
+				      struct rcu_data *rdp)
 {
 }
 
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index 0ea1bff..c89f5e9 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -20,7 +20,7 @@
  * Papers:  http://www.rdrop.com/users/paulmck/RCU
  *
  * For detailed explanation of Read-Copy Update mechanism see -
- * 		Documentation/RCU
+ *		Documentation/RCU
  *
  */
 #include <linux/types.h>
diff --git a/kernel/sched.c b/kernel/sched.c
index e27a536..91843ba 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -39,7 +39,7 @@
 #include <linux/completion.h>
 #include <linux/kernel_stat.h>
 #include <linux/debug_locks.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/security.h>
 #include <linux/notifier.h>
 #include <linux/profile.h>
@@ -119,8 +119,6 @@
  */
 #define RUNTIME_INF	((u64)~0ULL)
 
-static void double_rq_lock(struct rq *rq1, struct rq *rq2);
-
 static inline int rt_policy(int policy)
 {
 	if (unlikely(policy == SCHED_FIFO || policy == SCHED_RR))
@@ -295,12 +293,12 @@ struct task_group root_task_group;
 /* Default task group's sched entity on each cpu */
 static DEFINE_PER_CPU(struct sched_entity, init_sched_entity);
 /* Default task group's cfs_rq on each cpu */
-static DEFINE_PER_CPU(struct cfs_rq, init_tg_cfs_rq) ____cacheline_aligned_in_smp;
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct cfs_rq, init_tg_cfs_rq);
 #endif /* CONFIG_FAIR_GROUP_SCHED */
 
 #ifdef CONFIG_RT_GROUP_SCHED
 static DEFINE_PER_CPU(struct sched_rt_entity, init_sched_rt_entity);
-static DEFINE_PER_CPU(struct rt_rq, init_rt_rq) ____cacheline_aligned_in_smp;
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct rt_rq, init_rt_rq);
 #endif /* CONFIG_RT_GROUP_SCHED */
 #else /* !CONFIG_USER_SCHED */
 #define root_task_group init_task_group
@@ -378,13 +376,6 @@ static inline void set_task_rq(struct task_struct *p, unsigned int cpu)
 
 #else
 
-#ifdef CONFIG_SMP
-static int root_task_group_empty(void)
-{
-	return 1;
-}
-#endif
-
 static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { }
 static inline struct task_group *task_group(struct task_struct *p)
 {
@@ -514,14 +505,6 @@ struct root_domain {
 #ifdef CONFIG_SMP
 	struct cpupri cpupri;
 #endif
-#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
-	/*
-	 * Preferred wake up cpu nominated by sched_mc balance that will be
-	 * used when most cpus are idle in the system indicating overall very
-	 * low system utilisation. Triggered at POWERSAVINGS_BALANCE_WAKEUP(2)
-	 */
-	unsigned int sched_mc_preferred_wakeup_cpu;
-#endif
 };
 
 /*
@@ -646,9 +629,10 @@ struct rq {
 
 static DEFINE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues);
 
-static inline void check_preempt_curr(struct rq *rq, struct task_struct *p, int sync)
+static inline
+void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags)
 {
-	rq->curr->sched_class->check_preempt_curr(rq, p, sync);
+	rq->curr->sched_class->check_preempt_curr(rq, p, flags);
 }
 
 static inline int cpu_of(struct rq *rq)
@@ -697,15 +681,9 @@ inline void update_rq_clock(struct rq *rq)
  * This interface allows printk to be called with the runqueue lock
  * held and know whether or not it is OK to wake up the klogd.
  */
-int runqueue_is_locked(void)
+int runqueue_is_locked(int cpu)
 {
-	int cpu = get_cpu();
-	struct rq *rq = cpu_rq(cpu);
-	int ret;
-
-	ret = spin_is_locked(&rq->lock);
-	put_cpu();
-	return ret;
+	return spin_is_locked(&cpu_rq(cpu)->lock);
 }
 
 /*
@@ -1509,8 +1487,65 @@ static int tg_nop(struct task_group *tg, void *data)
 #endif
 
 #ifdef CONFIG_SMP
-static unsigned long source_load(int cpu, int type);
-static unsigned long target_load(int cpu, int type);
+/* Used instead of source_load when we know the type == 0 */
+static unsigned long weighted_cpuload(const int cpu)
+{
+	return cpu_rq(cpu)->load.weight;
+}
+
+/*
+ * Return a low guess at the load of a migration-source cpu weighted
+ * according to the scheduling class and "nice" value.
+ *
+ * We want to under-estimate the load of migration sources, to
+ * balance conservatively.
+ */
+static unsigned long source_load(int cpu, int type)
+{
+	struct rq *rq = cpu_rq(cpu);
+	unsigned long total = weighted_cpuload(cpu);
+
+	if (type == 0 || !sched_feat(LB_BIAS))
+		return total;
+
+	return min(rq->cpu_load[type-1], total);
+}
+
+/*
+ * Return a high guess at the load of a migration-target cpu weighted
+ * according to the scheduling class and "nice" value.
+ */
+static unsigned long target_load(int cpu, int type)
+{
+	struct rq *rq = cpu_rq(cpu);
+	unsigned long total = weighted_cpuload(cpu);
+
+	if (type == 0 || !sched_feat(LB_BIAS))
+		return total;
+
+	return max(rq->cpu_load[type-1], total);
+}
+
+static struct sched_group *group_of(int cpu)
+{
+	struct sched_domain *sd = rcu_dereference(cpu_rq(cpu)->sd);
+
+	if (!sd)
+		return NULL;
+
+	return sd->groups;
+}
+
+static unsigned long power_of(int cpu)
+{
+	struct sched_group *group = group_of(cpu);
+
+	if (!group)
+		return SCHED_LOAD_SCALE;
+
+	return group->cpu_power;
+}
+
 static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
 
 static unsigned long cpu_avg_load_per_task(int cpu)
@@ -1695,6 +1730,8 @@ static inline void update_shares_locked(struct rq *rq, struct sched_domain *sd)
 
 #ifdef CONFIG_PREEMPT
 
+static void double_rq_lock(struct rq *rq1, struct rq *rq2);
+
 /*
  * fair double_lock_balance: Safely acquires both rq->locks in a fair
  * way at the expense of forcing extra atomic operations in all
@@ -1959,13 +1996,6 @@ static inline void check_class_changed(struct rq *rq, struct task_struct *p,
 }
 
 #ifdef CONFIG_SMP
-
-/* Used instead of source_load when we know the type == 0 */
-static unsigned long weighted_cpuload(const int cpu)
-{
-	return cpu_rq(cpu)->load.weight;
-}
-
 /*
  * Is this task likely cache-hot:
  */
@@ -2023,7 +2053,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
 		if (task_hot(p, old_rq->clock, NULL))
 			schedstat_inc(p, se.nr_forced2_migrations);
 #endif
-		perf_swcounter_event(PERF_COUNT_SW_CPU_MIGRATIONS,
+		perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS,
 				     1, 1, NULL, 0);
 	}
 	p->se.vruntime -= old_cfsrq->min_vruntime -
@@ -2239,185 +2269,6 @@ void kick_process(struct task_struct *p)
 	preempt_enable();
 }
 EXPORT_SYMBOL_GPL(kick_process);
-
-/*
- * Return a low guess at the load of a migration-source cpu weighted
- * according to the scheduling class and "nice" value.
- *
- * We want to under-estimate the load of migration sources, to
- * balance conservatively.
- */
-static unsigned long source_load(int cpu, int type)
-{
-	struct rq *rq = cpu_rq(cpu);
-	unsigned long total = weighted_cpuload(cpu);
-
-	if (type == 0 || !sched_feat(LB_BIAS))
-		return total;
-
-	return min(rq->cpu_load[type-1], total);
-}
-
-/*
- * Return a high guess at the load of a migration-target cpu weighted
- * according to the scheduling class and "nice" value.
- */
-static unsigned long target_load(int cpu, int type)
-{
-	struct rq *rq = cpu_rq(cpu);
-	unsigned long total = weighted_cpuload(cpu);
-
-	if (type == 0 || !sched_feat(LB_BIAS))
-		return total;
-
-	return max(rq->cpu_load[type-1], total);
-}
-
-/*
- * find_idlest_group finds and returns the least busy CPU group within the
- * domain.
- */
-static struct sched_group *
-find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu)
-{
-	struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups;
-	unsigned long min_load = ULONG_MAX, this_load = 0;
-	int load_idx = sd->forkexec_idx;
-	int imbalance = 100 + (sd->imbalance_pct-100)/2;
-
-	do {
-		unsigned long load, avg_load;
-		int local_group;
-		int i;
-
-		/* Skip over this group if it has no CPUs allowed */
-		if (!cpumask_intersects(sched_group_cpus(group),
-					&p->cpus_allowed))
-			continue;
-
-		local_group = cpumask_test_cpu(this_cpu,
-					       sched_group_cpus(group));
-
-		/* Tally up the load of all CPUs in the group */
-		avg_load = 0;
-
-		for_each_cpu(i, sched_group_cpus(group)) {
-			/* Bias balancing toward cpus of our domain */
-			if (local_group)
-				load = source_load(i, load_idx);
-			else
-				load = target_load(i, load_idx);
-
-			avg_load += load;
-		}
-
-		/* Adjust by relative CPU power of the group */
-		avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
-
-		if (local_group) {
-			this_load = avg_load;
-			this = group;
-		} else if (avg_load < min_load) {
-			min_load = avg_load;
-			idlest = group;
-		}
-	} while (group = group->next, group != sd->groups);
-
-	if (!idlest || 100*this_load < imbalance*min_load)
-		return NULL;
-	return idlest;
-}
-
-/*
- * find_idlest_cpu - find the idlest cpu among the cpus in group.
- */
-static int
-find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
-{
-	unsigned long load, min_load = ULONG_MAX;
-	int idlest = -1;
-	int i;
-
-	/* Traverse only the allowed CPUs */
-	for_each_cpu_and(i, sched_group_cpus(group), &p->cpus_allowed) {
-		load = weighted_cpuload(i);
-
-		if (load < min_load || (load == min_load && i == this_cpu)) {
-			min_load = load;
-			idlest = i;
-		}
-	}
-
-	return idlest;
-}
-
-/*
- * sched_balance_self: balance the current task (running on cpu) in domains
- * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
- * SD_BALANCE_EXEC.
- *
- * Balance, ie. select the least loaded group.
- *
- * Returns the target CPU number, or the same CPU if no balancing is needed.
- *
- * preempt must be disabled.
- */
-static int sched_balance_self(int cpu, int flag)
-{
-	struct task_struct *t = current;
-	struct sched_domain *tmp, *sd = NULL;
-
-	for_each_domain(cpu, tmp) {
-		/*
-		 * If power savings logic is enabled for a domain, stop there.
-		 */
-		if (tmp->flags & SD_POWERSAVINGS_BALANCE)
-			break;
-		if (tmp->flags & flag)
-			sd = tmp;
-	}
-
-	if (sd)
-		update_shares(sd);
-
-	while (sd) {
-		struct sched_group *group;
-		int new_cpu, weight;
-
-		if (!(sd->flags & flag)) {
-			sd = sd->child;
-			continue;
-		}
-
-		group = find_idlest_group(sd, t, cpu);
-		if (!group) {
-			sd = sd->child;
-			continue;
-		}
-
-		new_cpu = find_idlest_cpu(group, t, cpu);
-		if (new_cpu == -1 || new_cpu == cpu) {
-			/* Now try balancing at a lower domain level of cpu */
-			sd = sd->child;
-			continue;
-		}
-
-		/* Now try balancing at a lower domain level of new_cpu */
-		cpu = new_cpu;
-		weight = cpumask_weight(sched_domain_span(sd));
-		sd = NULL;
-		for_each_domain(cpu, tmp) {
-			if (weight <= cpumask_weight(sched_domain_span(tmp)))
-				break;
-			if (tmp->flags & flag)
-				sd = tmp;
-		}
-		/* while loop will break here if sd == NULL */
-	}
-
-	return cpu;
-}
-
 #endif /* CONFIG_SMP */
 
 /**
@@ -2455,37 +2306,22 @@ void task_oncpu_function_call(struct task_struct *p,
  *
  * returns failure only if the task is already active.
  */
-static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
+static int try_to_wake_up(struct task_struct *p, unsigned int state,
+			  int wake_flags)
 {
 	int cpu, orig_cpu, this_cpu, success = 0;
 	unsigned long flags;
-	long old_state;
 	struct rq *rq;
 
 	if (!sched_feat(SYNC_WAKEUPS))
-		sync = 0;
-
-#ifdef CONFIG_SMP
-	if (sched_feat(LB_WAKEUP_UPDATE) && !root_task_group_empty()) {
-		struct sched_domain *sd;
+		wake_flags &= ~WF_SYNC;
 
-		this_cpu = raw_smp_processor_id();
-		cpu = task_cpu(p);
-
-		for_each_domain(this_cpu, sd) {
-			if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
-				update_shares(sd);
-				break;
-			}
-		}
-	}
-#endif
+	this_cpu = get_cpu();
 
 	smp_wmb();
 	rq = task_rq_lock(p, &flags);
 	update_rq_clock(rq);
-	old_state = p->state;
-	if (!(old_state & state))
+	if (!(p->state & state))
 		goto out;
 
 	if (p->se.on_rq)
@@ -2493,27 +2329,29 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
 
 	cpu = task_cpu(p);
 	orig_cpu = cpu;
-	this_cpu = smp_processor_id();
 
 #ifdef CONFIG_SMP
 	if (unlikely(task_running(rq, p)))
 		goto out_activate;
 
-	cpu = p->sched_class->select_task_rq(p, sync);
-	if (cpu != orig_cpu) {
+	/*
+	 * In order to handle concurrent wakeups and release the rq->lock
+	 * we put the task in TASK_WAKING state.
+	 *
+	 * First fix up the nr_uninterruptible count:
+	 */
+	if (task_contributes_to_load(p))
+		rq->nr_uninterruptible--;
+	p->state = TASK_WAKING;
+	task_rq_unlock(rq, &flags);
+
+	cpu = p->sched_class->select_task_rq(p, SD_BALANCE_WAKE, wake_flags);
+	if (cpu != orig_cpu)
 		set_task_cpu(p, cpu);
-		task_rq_unlock(rq, &flags);
-		/* might preempt at this point */
-		rq = task_rq_lock(p, &flags);
-		old_state = p->state;
-		if (!(old_state & state))
-			goto out;
-		if (p->se.on_rq)
-			goto out_running;
 
-		this_cpu = smp_processor_id();
-		cpu = task_cpu(p);
-	}
+	rq = task_rq_lock(p, &flags);
+	WARN_ON(p->state != TASK_WAKING);
+	cpu = task_cpu(p);
 
 #ifdef CONFIG_SCHEDSTATS
 	schedstat_inc(rq, ttwu_count);
@@ -2533,7 +2371,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync)
 out_activate:
 #endif /* CONFIG_SMP */
 	schedstat_inc(p, se.nr_wakeups);
-	if (sync)
+	if (wake_flags & WF_SYNC)
 		schedstat_inc(p, se.nr_wakeups_sync);
 	if (orig_cpu != cpu)
 		schedstat_inc(p, se.nr_wakeups_migrate);
@@ -2562,7 +2400,7 @@ out_activate:
 
 out_running:
 	trace_sched_wakeup(rq, p, success);
-	check_preempt_curr(rq, p, sync);
+	check_preempt_curr(rq, p, wake_flags);
 
 	p->state = TASK_RUNNING;
 #ifdef CONFIG_SMP
@@ -2571,6 +2409,7 @@ out_running:
 #endif
 out:
 	task_rq_unlock(rq, &flags);
+	put_cpu();
 
 	return success;
 }
@@ -2613,6 +2452,7 @@ static void __sched_fork(struct task_struct *p)
 	p->se.avg_overlap		= 0;
 	p->se.start_runtime		= 0;
 	p->se.avg_wakeup		= sysctl_sched_wakeup_granularity;
+	p->se.avg_running		= 0;
 
 #ifdef CONFIG_SCHEDSTATS
 	p->se.wait_start			= 0;
@@ -2674,11 +2514,6 @@ void sched_fork(struct task_struct *p, int clone_flags)
 
 	__sched_fork(p);
 
-#ifdef CONFIG_SMP
-	cpu = sched_balance_self(cpu, SD_BALANCE_FORK);
-#endif
-	set_task_cpu(p, cpu);
-
 	/*
 	 * Make sure we do not leak PI boosting priority to the child.
 	 */
@@ -2709,6 +2544,11 @@ void sched_fork(struct task_struct *p, int clone_flags)
 	if (!rt_prio(p->prio))
 		p->sched_class = &fair_sched_class;
 
+#ifdef CONFIG_SMP
+	cpu = p->sched_class->select_task_rq(p, SD_BALANCE_FORK, 0);
+#endif
+	set_task_cpu(p, cpu);
+
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 	if (likely(sched_info_on()))
 		memset(&p->sched_info, 0, sizeof(p->sched_info));
@@ -2754,7 +2594,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
 		inc_nr_running(rq);
 	}
 	trace_sched_wakeup_new(rq, p, 1);
-	check_preempt_curr(rq, p, 0);
+	check_preempt_curr(rq, p, WF_FORK);
 #ifdef CONFIG_SMP
 	if (p->sched_class->task_wake_up)
 		p->sched_class->task_wake_up(rq, p);
@@ -2878,7 +2718,7 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
 	 */
 	prev_state = prev->state;
 	finish_arch_switch(prev);
-	perf_counter_task_sched_in(current, cpu_of(rq));
+	perf_event_task_sched_in(current, cpu_of(rq));
 	finish_lock_switch(rq, prev);
 
 	fire_sched_in_preempt_notifiers(current);
@@ -3263,7 +3103,7 @@ out:
 void sched_exec(void)
 {
 	int new_cpu, this_cpu = get_cpu();
-	new_cpu = sched_balance_self(this_cpu, SD_BALANCE_EXEC);
+	new_cpu = current->sched_class->select_task_rq(current, SD_BALANCE_EXEC, 0);
 	put_cpu();
 	if (new_cpu != this_cpu)
 		sched_migrate_task(current, new_cpu);
@@ -3683,11 +3523,6 @@ static inline int check_power_save_busiest_group(struct sd_lb_stats *sds,
 	*imbalance = sds->min_load_per_task;
 	sds->busiest = sds->group_min;
 
-	if (sched_mc_power_savings >= POWERSAVINGS_BALANCE_WAKEUP) {
-		cpu_rq(this_cpu)->rd->sched_mc_preferred_wakeup_cpu =
-			group_first_cpu(sds->group_leader);
-	}
-
 	return 1;
 
 }
@@ -3711,7 +3546,18 @@ static inline int check_power_save_busiest_group(struct sd_lb_stats *sds,
 }
 #endif /* CONFIG_SCHED_MC || CONFIG_SCHED_SMT */
 
-unsigned long __weak arch_scale_smt_power(struct sched_domain *sd, int cpu)
+
+unsigned long default_scale_freq_power(struct sched_domain *sd, int cpu)
+{
+	return SCHED_LOAD_SCALE;
+}
+
+unsigned long __weak arch_scale_freq_power(struct sched_domain *sd, int cpu)
+{
+	return default_scale_freq_power(sd, cpu);
+}
+
+unsigned long default_scale_smt_power(struct sched_domain *sd, int cpu)
 {
 	unsigned long weight = cpumask_weight(sched_domain_span(sd));
 	unsigned long smt_gain = sd->smt_gain;
@@ -3721,6 +3567,11 @@ unsigned long __weak arch_scale_smt_power(struct sched_domain *sd, int cpu)
 	return smt_gain;
 }
 
+unsigned long __weak arch_scale_smt_power(struct sched_domain *sd, int cpu)
+{
+	return default_scale_smt_power(sd, cpu);
+}
+
 unsigned long scale_rt_power(int cpu)
 {
 	struct rq *rq = cpu_rq(cpu);
@@ -3745,10 +3596,19 @@ static void update_cpu_power(struct sched_domain *sd, int cpu)
 	unsigned long power = SCHED_LOAD_SCALE;
 	struct sched_group *sdg = sd->groups;
 
-	/* here we could scale based on cpufreq */
+	if (sched_feat(ARCH_POWER))
+		power *= arch_scale_freq_power(sd, cpu);
+	else
+		power *= default_scale_freq_power(sd, cpu);
+
+	power >>= SCHED_LOAD_SHIFT;
 
 	if ((sd->flags & SD_SHARE_CPUPOWER) && weight > 1) {
-		power *= arch_scale_smt_power(sd, cpu);
+		if (sched_feat(ARCH_POWER))
+			power *= arch_scale_smt_power(sd, cpu);
+		else
+			power *= default_scale_smt_power(sd, cpu);
+
 		power >>= SCHED_LOAD_SHIFT;
 	}
 
@@ -4161,26 +4021,6 @@ ret:
 	return NULL;
 }
 
-static struct sched_group *group_of(int cpu)
-{
-	struct sched_domain *sd = rcu_dereference(cpu_rq(cpu)->sd);
-
-	if (!sd)
-		return NULL;
-
-	return sd->groups;
-}
-
-static unsigned long power_of(int cpu)
-{
-	struct sched_group *group = group_of(cpu);
-
-	if (!group)
-		return SCHED_LOAD_SCALE;
-
-	return group->cpu_power;
-}
-
 /*
  * find_busiest_queue - find the busiest runqueue among the cpus in group.
  */
@@ -5353,7 +5193,7 @@ void scheduler_tick(void)
 	curr->sched_class->task_tick(rq, curr, 0);
 	spin_unlock(&rq->lock);
 
-	perf_counter_task_tick(curr, cpu);
+	perf_event_task_tick(curr, cpu);
 
 #ifdef CONFIG_SMP
 	rq->idle_at_tick = idle_cpu(cpu);
@@ -5465,14 +5305,13 @@ static inline void schedule_debug(struct task_struct *prev)
 #endif
 }
 
-static void put_prev_task(struct rq *rq, struct task_struct *prev)
+static void put_prev_task(struct rq *rq, struct task_struct *p)
 {
-	if (prev->state == TASK_RUNNING) {
-		u64 runtime = prev->se.sum_exec_runtime;
+	u64 runtime = p->se.sum_exec_runtime - p->se.prev_sum_exec_runtime;
 
-		runtime -= prev->se.prev_sum_exec_runtime;
-		runtime = min_t(u64, runtime, 2*sysctl_sched_migration_cost);
+	update_avg(&p->se.avg_running, runtime);
 
+	if (p->state == TASK_RUNNING) {
 		/*
 		 * In order to avoid avg_overlap growing stale when we are
 		 * indeed overlapping and hence not getting put to sleep, grow
@@ -5482,9 +5321,12 @@ static void put_prev_task(struct rq *rq, struct task_struct *prev)
 		 * correlates to the amount of cache footprint a task can
 		 * build up.
 		 */
-		update_avg(&prev->se.avg_overlap, runtime);
+		runtime = min_t(u64, runtime, 2*sysctl_sched_migration_cost);
+		update_avg(&p->se.avg_overlap, runtime);
+	} else {
+		update_avg(&p->se.avg_running, 0);
 	}
-	prev->sched_class->put_prev_task(rq, prev);
+	p->sched_class->put_prev_task(rq, p);
 }
 
 /*
@@ -5567,7 +5409,7 @@ need_resched_nonpreemptible:
 
 	if (likely(prev != next)) {
 		sched_info_switch(prev, next);
-		perf_counter_task_sched_out(prev, next, cpu);
+		perf_event_task_sched_out(prev, next, cpu);
 
 		rq->nr_switches++;
 		rq->curr = next;
@@ -5716,10 +5558,10 @@ asmlinkage void __sched preempt_schedule_irq(void)
 
 #endif /* CONFIG_PREEMPT */
 
-int default_wake_function(wait_queue_t *curr, unsigned mode, int sync,
+int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
 			  void *key)
 {
-	return try_to_wake_up(curr->private, mode, sync);
+	return try_to_wake_up(curr->private, mode, wake_flags);
 }
 EXPORT_SYMBOL(default_wake_function);
 
@@ -5733,14 +5575,14 @@ EXPORT_SYMBOL(default_wake_function);
  * zero in this (rare) case, and we handle it by continuing to scan the queue.
  */
 static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
-			int nr_exclusive, int sync, void *key)
+			int nr_exclusive, int wake_flags, void *key)
 {
 	wait_queue_t *curr, *next;
 
 	list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
 		unsigned flags = curr->flags;
 
-		if (curr->func(curr, mode, sync, key) &&
+		if (curr->func(curr, mode, wake_flags, key) &&
 				(flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
 			break;
 	}
@@ -5801,16 +5643,16 @@ void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode,
 			int nr_exclusive, void *key)
 {
 	unsigned long flags;
-	int sync = 1;
+	int wake_flags = WF_SYNC;
 
 	if (unlikely(!q))
 		return;
 
 	if (unlikely(!nr_exclusive))
-		sync = 0;
+		wake_flags = 0;
 
 	spin_lock_irqsave(&q->lock, flags);
-	__wake_up_common(q, mode, nr_exclusive, sync, key);
+	__wake_up_common(q, mode, nr_exclusive, wake_flags, key);
 	spin_unlock_irqrestore(&q->lock, flags);
 }
 EXPORT_SYMBOL_GPL(__wake_up_sync_key);
@@ -6977,23 +6819,8 @@ SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
 	if (retval)
 		goto out_unlock;
 
-	/*
-	 * Time slice is 0 for SCHED_FIFO tasks and for SCHED_OTHER
-	 * tasks that are on an otherwise idle runqueue:
-	 */
-	time_slice = 0;
-	if (p->policy == SCHED_RR) {
-		time_slice = DEF_TIMESLICE;
-	} else if (p->policy != SCHED_FIFO) {
-		struct sched_entity *se = &p->se;
-		unsigned long flags;
-		struct rq *rq;
+	time_slice = p->sched_class->get_rr_interval(p);
 
-		rq = task_rq_lock(p, &flags);
-		if (rq->cfs.load.weight)
-			time_slice = NS_TO_JIFFIES(sched_slice(&rq->cfs, se));
-		task_rq_unlock(rq, &flags);
-	}
 	read_unlock(&tasklist_lock);
 	jiffies_to_timespec(time_slice, &t);
 	retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
@@ -7844,7 +7671,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
 /*
  * Register at high priority so that task migration (migrate_all_tasks)
  * happens before everything else.  This has to be lower priority than
- * the notifier in the perf_counter subsystem, though.
+ * the notifier in the perf_event subsystem, though.
  */
 static struct notifier_block __cpuinitdata migration_notifier = {
 	.notifier_call = migration_call,
@@ -8000,9 +7827,7 @@ static int sd_degenerate(struct sched_domain *sd)
 	}
 
 	/* Following flags don't use groups */
-	if (sd->flags & (SD_WAKE_IDLE |
-			 SD_WAKE_AFFINE |
-			 SD_WAKE_BALANCE))
+	if (sd->flags & (SD_WAKE_AFFINE))
 		return 0;
 
 	return 1;
@@ -8019,10 +7844,6 @@ sd_parent_degenerate(struct sched_domain *sd, struct sched_domain *parent)
 	if (!cpumask_equal(sched_domain_span(sd), sched_domain_span(parent)))
 		return 0;
 
-	/* Does parent contain flags not in child? */
-	/* WAKE_BALANCE is a subset of WAKE_AFFINE */
-	if (cflags & SD_WAKE_AFFINE)
-		pflags &= ~SD_WAKE_BALANCE;
 	/* Flags needing groups don't count if only 1 group in parent */
 	if (parent->groups == parent->groups->next) {
 		pflags &= ~(SD_LOAD_BALANCE |
@@ -8708,10 +8529,10 @@ static void set_domain_attribute(struct sched_domain *sd,
 		request = attr->relax_domain_level;
 	if (request < sd->level) {
 		/* turn off idle balance on this domain */
-		sd->flags &= ~(SD_WAKE_IDLE|SD_BALANCE_NEWIDLE);
+		sd->flags &= ~(SD_BALANCE_WAKE|SD_BALANCE_NEWIDLE);
 	} else {
 		/* turn on idle balance on this domain */
-		sd->flags |= (SD_WAKE_IDLE_FAR|SD_BALANCE_NEWIDLE);
+		sd->flags |= (SD_BALANCE_WAKE|SD_BALANCE_NEWIDLE);
 	}
 }
 
@@ -9329,6 +9150,7 @@ void __init sched_init_smp(void)
 	cpumask_var_t non_isolated_cpus;
 
 	alloc_cpumask_var(&non_isolated_cpus, GFP_KERNEL);
+	alloc_cpumask_var(&fallback_doms, GFP_KERNEL);
 
 #if defined(CONFIG_NUMA)
 	sched_group_nodes_bycpu = kzalloc(nr_cpu_ids * sizeof(void **),
@@ -9360,7 +9182,6 @@ void __init sched_init_smp(void)
 	sched_init_granularity();
 	free_cpumask_var(non_isolated_cpus);
 
-	alloc_cpumask_var(&fallback_doms, GFP_KERNEL);
 	init_sched_rt_class();
 }
 #else
@@ -9707,7 +9528,7 @@ void __init sched_init(void)
 	alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
 #endif /* SMP */
 
-	perf_counter_init();
+	perf_event_init();
 
 	scheduler_running = 1;
 }
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index e1d16c9..ac2e1dc 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -48,13 +48,6 @@ static __read_mostly int sched_clock_running;
 __read_mostly int sched_clock_stable;
 
 struct sched_clock_data {
-	/*
-	 * Raw spinlock - this is a special case: this might be called
-	 * from within instrumentation code so we dont want to do any
-	 * instrumentation ourselves.
-	 */
-	raw_spinlock_t		lock;
-
 	u64			tick_raw;
 	u64			tick_gtod;
 	u64			clock;
@@ -80,7 +73,6 @@ void sched_clock_init(void)
 	for_each_possible_cpu(cpu) {
 		struct sched_clock_data *scd = cpu_sdc(cpu);
 
-		scd->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
 		scd->tick_raw = 0;
 		scd->tick_gtod = ktime_now;
 		scd->clock = ktime_now;
@@ -109,14 +101,19 @@ static inline u64 wrap_max(u64 x, u64 y)
  *  - filter out backward motion
  *  - use the GTOD tick value to create a window to filter crazy TSC values
  */
-static u64 __update_sched_clock(struct sched_clock_data *scd, u64 now)
+static u64 sched_clock_local(struct sched_clock_data *scd)
 {
-	s64 delta = now - scd->tick_raw;
-	u64 clock, min_clock, max_clock;
+	u64 now, clock, old_clock, min_clock, max_clock;
+	s64 delta;
 
+again:
+	now = sched_clock();
+	delta = now - scd->tick_raw;
 	if (unlikely(delta < 0))
 		delta = 0;
 
+	old_clock = scd->clock;
+
 	/*
 	 * scd->clock = clamp(scd->tick_gtod + delta,
 	 *		      max(scd->tick_gtod, scd->clock),
@@ -124,84 +121,73 @@ static u64 __update_sched_clock(struct sched_clock_data *scd, u64 now)
 	 */
 
 	clock = scd->tick_gtod + delta;
-	min_clock = wrap_max(scd->tick_gtod, scd->clock);
-	max_clock = wrap_max(scd->clock, scd->tick_gtod + TICK_NSEC);
+	min_clock = wrap_max(scd->tick_gtod, old_clock);
+	max_clock = wrap_max(old_clock, scd->tick_gtod + TICK_NSEC);
 
 	clock = wrap_max(clock, min_clock);
 	clock = wrap_min(clock, max_clock);
 
-	scd->clock = clock;
+	if (cmpxchg(&scd->clock, old_clock, clock) != old_clock)
+		goto again;
 
-	return scd->clock;
+	return clock;
 }
 
-static void lock_double_clock(struct sched_clock_data *data1,
-				struct sched_clock_data *data2)
+static u64 sched_clock_remote(struct sched_clock_data *scd)
 {
-	if (data1 < data2) {
-		__raw_spin_lock(&data1->lock);
-		__raw_spin_lock(&data2->lock);
+	struct sched_clock_data *my_scd = this_scd();
+	u64 this_clock, remote_clock;
+	u64 *ptr, old_val, val;
+
+	sched_clock_local(my_scd);
+again:
+	this_clock = my_scd->clock;
+	remote_clock = scd->clock;
+
+	/*
+	 * Use the opportunity that we have both locks
+	 * taken to couple the two clocks: we take the
+	 * larger time as the latest time for both
+	 * runqueues. (this creates monotonic movement)
+	 */
+	if (likely((s64)(remote_clock - this_clock) < 0)) {
+		ptr = &scd->clock;
+		old_val = remote_clock;
+		val = this_clock;
 	} else {
-		__raw_spin_lock(&data2->lock);
-		__raw_spin_lock(&data1->lock);
+		/*
+		 * Should be rare, but possible:
+		 */
+		ptr = &my_scd->clock;
+		old_val = this_clock;
+		val = remote_clock;
 	}
+
+	if (cmpxchg(ptr, old_val, val) != old_val)
+		goto again;
+
+	return val;
 }
 
 u64 sched_clock_cpu(int cpu)
 {
-	u64 now, clock, this_clock, remote_clock;
 	struct sched_clock_data *scd;
+	u64 clock;
+
+	WARN_ON_ONCE(!irqs_disabled());
 
 	if (sched_clock_stable)
 		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();
-
-	if (cpu != raw_smp_processor_id()) {
-		struct sched_clock_data *my_scd = this_scd();
-
-		lock_double_clock(scd, my_scd);
-
-		this_clock = __update_sched_clock(my_scd, now);
-		remote_clock = scd->clock;
-
-		/*
-		 * Use the opportunity that we have both locks
-		 * taken to couple the two clocks: we take the
-		 * larger time as the latest time for both
-		 * runqueues. (this creates monotonic movement)
-		 */
-		if (likely((s64)(remote_clock - this_clock) < 0)) {
-			clock = this_clock;
-			scd->clock = clock;
-		} else {
-			/*
-			 * Should be rare, but possible:
-			 */
-			clock = remote_clock;
-			my_scd->clock = remote_clock;
-		}
-
-		__raw_spin_unlock(&my_scd->lock);
-	} else {
-		__raw_spin_lock(&scd->lock);
-		clock = __update_sched_clock(scd, now);
-	}
+	scd = cpu_sdc(cpu);
 
-	__raw_spin_unlock(&scd->lock);
+	if (cpu != smp_processor_id())
+		clock = sched_clock_remote(scd);
+	else
+		clock = sched_clock_local(scd);
 
 	return clock;
 }
@@ -223,11 +209,9 @@ void sched_clock_tick(void)
 	now_gtod = ktime_to_ns(ktime_get());
 	now = sched_clock();
 
-	__raw_spin_lock(&scd->lock);
 	scd->tick_raw = now;
 	scd->tick_gtod = now_gtod;
-	__update_sched_clock(scd, now);
-	__raw_spin_unlock(&scd->lock);
+	sched_clock_local(scd);
 }
 
 /*
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 5ddbd08..efb8440 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -395,6 +395,7 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
 	PN(se.sum_exec_runtime);
 	PN(se.avg_overlap);
 	PN(se.avg_wakeup);
+	PN(se.avg_running);
 
 	nr_switches = p->nvcsw + p->nivcsw;
 
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index aa7f841..ecc637a 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -513,6 +513,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
 	if (entity_is_task(curr)) {
 		struct task_struct *curtask = task_of(curr);
 
+		trace_sched_stat_runtime(curtask, delta_exec, curr->vruntime);
 		cpuacct_charge(curtask, delta_exec);
 		account_group_exec_runtime(curtask, delta_exec);
 	}
@@ -709,24 +710,28 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 	if (initial && sched_feat(START_DEBIT))
 		vruntime += sched_vslice(cfs_rq, se);
 
-	if (!initial) {
-		/* sleeps upto a single latency don't count. */
-		if (sched_feat(NEW_FAIR_SLEEPERS)) {
-			unsigned long thresh = sysctl_sched_latency;
+	/* sleeps up to a single latency don't count. */
+	if (!initial && sched_feat(FAIR_SLEEPERS)) {
+		unsigned long thresh = sysctl_sched_latency;
 
-			/*
-			 * Convert the sleeper threshold into virtual time.
-			 * SCHED_IDLE is a special sub-class.  We care about
-			 * fairness only relative to other SCHED_IDLE tasks,
-			 * all of which have the same weight.
-			 */
-			if (sched_feat(NORMALIZED_SLEEPER) &&
-					(!entity_is_task(se) ||
-					 task_of(se)->policy != SCHED_IDLE))
-				thresh = calc_delta_fair(thresh, se);
+		/*
+		 * Convert the sleeper threshold into virtual time.
+		 * SCHED_IDLE is a special sub-class.  We care about
+		 * fairness only relative to other SCHED_IDLE tasks,
+		 * all of which have the same weight.
+		 */
+		if (sched_feat(NORMALIZED_SLEEPER) && (!entity_is_task(se) ||
+				 task_of(se)->policy != SCHED_IDLE))
+			thresh = calc_delta_fair(thresh, se);
 
-			vruntime -= thresh;
-		}
+		/*
+		 * Halve their sleep time's effect, to allow
+		 * for a gentler effect of sleepers:
+		 */
+		if (sched_feat(GENTLE_FAIR_SLEEPERS))
+			thresh >>= 1;
+
+		vruntime -= thresh;
 	}
 
 	/* ensure we never gain time by being placed backwards. */
@@ -757,10 +762,10 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup)
 
 static void __clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
-	if (cfs_rq->last == se)
+	if (!se || cfs_rq->last == se)
 		cfs_rq->last = NULL;
 
-	if (cfs_rq->next == se)
+	if (!se || cfs_rq->next == se)
 		cfs_rq->next = NULL;
 }
 
@@ -1062,83 +1067,6 @@ static void yield_task_fair(struct rq *rq)
 	se->vruntime = rightmost->vruntime + 1;
 }
 
-/*
- * wake_idle() will wake a task on an idle cpu if task->cpu is
- * not idle and an idle cpu is available.  The span of cpus to
- * search starts with cpus closest then further out as needed,
- * so we always favor a closer, idle cpu.
- * Domains may include CPUs that are not usable for migration,
- * hence we need to mask them out (rq->rd->online)
- *
- * Returns the CPU we should wake onto.
- */
-#if defined(ARCH_HAS_SCHED_WAKE_IDLE)
-
-#define cpu_rd_active(cpu, rq) cpumask_test_cpu(cpu, rq->rd->online)
-
-static int wake_idle(int cpu, struct task_struct *p)
-{
-	struct sched_domain *sd;
-	int i;
-	unsigned int chosen_wakeup_cpu;
-	int this_cpu;
-	struct rq *task_rq = task_rq(p);
-
-	/*
-	 * At POWERSAVINGS_BALANCE_WAKEUP level, if both this_cpu and prev_cpu
-	 * are idle and this is not a kernel thread and this task's affinity
-	 * allows it to be moved to preferred cpu, then just move!
-	 */
-
-	this_cpu = smp_processor_id();
-	chosen_wakeup_cpu =
-		cpu_rq(this_cpu)->rd->sched_mc_preferred_wakeup_cpu;
-
-	if (sched_mc_power_savings >= POWERSAVINGS_BALANCE_WAKEUP &&
-		idle_cpu(cpu) && idle_cpu(this_cpu) &&
-		p->mm && !(p->flags & PF_KTHREAD) &&
-		cpu_isset(chosen_wakeup_cpu, p->cpus_allowed))
-		return chosen_wakeup_cpu;
-
-	/*
-	 * If it is idle, then it is the best cpu to run this task.
-	 *
-	 * This cpu is also the best, if it has more than one task already.
-	 * Siblings must be also busy(in most cases) as they didn't already
-	 * pickup the extra load from this cpu and hence we need not check
-	 * sibling runqueue info. This will avoid the checks and cache miss
-	 * penalities associated with that.
-	 */
-	if (idle_cpu(cpu) || cpu_rq(cpu)->cfs.nr_running > 1)
-		return cpu;
-
-	for_each_domain(cpu, sd) {
-		if ((sd->flags & SD_WAKE_IDLE)
-		    || ((sd->flags & SD_WAKE_IDLE_FAR)
-			&& !task_hot(p, task_rq->clock, sd))) {
-			for_each_cpu_and(i, sched_domain_span(sd),
-					 &p->cpus_allowed) {
-				if (cpu_rd_active(i, task_rq) && idle_cpu(i)) {
-					if (i != task_cpu(p)) {
-						schedstat_inc(p,
-						       se.nr_wakeups_idle);
-					}
-					return i;
-				}
-			}
-		} else {
-			break;
-		}
-	}
-	return cpu;
-}
-#else /* !ARCH_HAS_SCHED_WAKE_IDLE*/
-static inline int wake_idle(int cpu, struct task_struct *p)
-{
-	return cpu;
-}
-#endif
-
 #ifdef CONFIG_SMP
 
 #ifdef CONFIG_FAIR_GROUP_SCHED
@@ -1225,25 +1153,34 @@ static inline unsigned long effective_load(struct task_group *tg, int cpu,
 
 #endif
 
-static int
-wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
-	    struct task_struct *p, int prev_cpu, int this_cpu, int sync,
-	    int idx, unsigned long load, unsigned long this_load,
-	    unsigned int imbalance)
+static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 {
-	struct task_struct *curr = this_rq->curr;
-	struct task_group *tg;
-	unsigned long tl = this_load;
+	struct task_struct *curr = current;
+	unsigned long this_load, load;
+	int idx, this_cpu, prev_cpu;
 	unsigned long tl_per_task;
+	unsigned int imbalance;
+	struct task_group *tg;
 	unsigned long weight;
 	int balanced;
 
-	if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS))
-		return 0;
+	idx	  = sd->wake_idx;
+	this_cpu  = smp_processor_id();
+	prev_cpu  = task_cpu(p);
+	load	  = source_load(prev_cpu, idx);
+	this_load = target_load(this_cpu, idx);
 
-	if (sync && (curr->se.avg_overlap > sysctl_sched_migration_cost ||
-			p->se.avg_overlap > sysctl_sched_migration_cost))
-		sync = 0;
+	if (sync) {
+	       if (sched_feat(SYNC_LESS) &&
+		   (curr->se.avg_overlap > sysctl_sched_migration_cost ||
+		    p->se.avg_overlap > sysctl_sched_migration_cost))
+		       sync = 0;
+	} else {
+		if (sched_feat(SYNC_MORE) &&
+		    (curr->se.avg_overlap < sysctl_sched_migration_cost &&
+		     p->se.avg_overlap < sysctl_sched_migration_cost))
+			sync = 1;
+	}
 
 	/*
 	 * If sync wakeup then subtract the (maximum possible)
@@ -1254,24 +1191,26 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
 		tg = task_group(current);
 		weight = current->se.load.weight;
 
-		tl += effective_load(tg, this_cpu, -weight, -weight);
+		this_load += effective_load(tg, this_cpu, -weight, -weight);
 		load += effective_load(tg, prev_cpu, 0, -weight);
 	}
 
 	tg = task_group(p);
 	weight = p->se.load.weight;
 
+	imbalance = 100 + (sd->imbalance_pct - 100) / 2;
+
 	/*
 	 * In low-load situations, where prev_cpu is idle and this_cpu is idle
-	 * due to the sync cause above having dropped tl to 0, we'll always have
-	 * an imbalance, but there's really nothing you can do about that, so
-	 * that's good too.
+	 * due to the sync cause above having dropped this_load to 0, we'll
+	 * always have an imbalance, but there's really nothing you can do
+	 * about that, so that's good too.
 	 *
 	 * Otherwise check if either cpus are near enough in load to allow this
 	 * task to be woken on this_cpu.
 	 */
-	balanced = !tl ||
-		100*(tl + effective_load(tg, this_cpu, weight, weight)) <=
+	balanced = !this_load ||
+		100*(this_load + effective_load(tg, this_cpu, weight, weight)) <=
 		imbalance*(load + effective_load(tg, prev_cpu, 0, weight));
 
 	/*
@@ -1285,14 +1224,15 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
 	schedstat_inc(p, se.nr_wakeups_affine_attempts);
 	tl_per_task = cpu_avg_load_per_task(this_cpu);
 
-	if (balanced || (tl <= load && tl + target_load(prev_cpu, idx) <=
-			tl_per_task)) {
+	if (balanced ||
+	    (this_load <= load &&
+	     this_load + target_load(prev_cpu, idx) <= tl_per_task)) {
 		/*
 		 * This domain has SD_WAKE_AFFINE and
 		 * p is cache cold in this domain, and
 		 * there is no bad imbalance.
 		 */
-		schedstat_inc(this_sd, ttwu_move_affine);
+		schedstat_inc(sd, ttwu_move_affine);
 		schedstat_inc(p, se.nr_wakeups_affine);
 
 		return 1;
@@ -1300,65 +1240,216 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq,
 	return 0;
 }
 
-static int select_task_rq_fair(struct task_struct *p, int sync)
+/*
+ * find_idlest_group finds and returns the least busy CPU group within the
+ * domain.
+ */
+static struct sched_group *
+find_idlest_group(struct sched_domain *sd, struct task_struct *p,
+		  int this_cpu, int load_idx)
 {
-	struct sched_domain *sd, *this_sd = NULL;
-	int prev_cpu, this_cpu, new_cpu;
-	unsigned long load, this_load;
-	struct rq *this_rq;
-	unsigned int imbalance;
-	int idx;
+	struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups;
+	unsigned long min_load = ULONG_MAX, this_load = 0;
+	int imbalance = 100 + (sd->imbalance_pct-100)/2;
 
-	prev_cpu	= task_cpu(p);
-	this_cpu	= smp_processor_id();
-	this_rq		= cpu_rq(this_cpu);
-	new_cpu		= prev_cpu;
+	do {
+		unsigned long load, avg_load;
+		int local_group;
+		int i;
 
-	/*
-	 * 'this_sd' is the first domain that both
-	 * this_cpu and prev_cpu are present in:
-	 */
-	for_each_domain(this_cpu, sd) {
-		if (cpumask_test_cpu(prev_cpu, sched_domain_span(sd))) {
-			this_sd = sd;
-			break;
+		/* Skip over this group if it has no CPUs allowed */
+		if (!cpumask_intersects(sched_group_cpus(group),
+					&p->cpus_allowed))
+			continue;
+
+		local_group = cpumask_test_cpu(this_cpu,
+					       sched_group_cpus(group));
+
+		/* Tally up the load of all CPUs in the group */
+		avg_load = 0;
+
+		for_each_cpu(i, sched_group_cpus(group)) {
+			/* Bias balancing toward cpus of our domain */
+			if (local_group)
+				load = source_load(i, load_idx);
+			else
+				load = target_load(i, load_idx);
+
+			avg_load += load;
+		}
+
+		/* Adjust by relative CPU power of the group */
+		avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power;
+
+		if (local_group) {
+			this_load = avg_load;
+			this = group;
+		} else if (avg_load < min_load) {
+			min_load = avg_load;
+			idlest = group;
+		}
+	} while (group = group->next, group != sd->groups);
+
+	if (!idlest || 100*this_load < imbalance*min_load)
+		return NULL;
+	return idlest;
+}
+
+/*
+ * find_idlest_cpu - find the idlest cpu among the cpus in group.
+ */
+static int
+find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu)
+{
+	unsigned long load, min_load = ULONG_MAX;
+	int idlest = -1;
+	int i;
+
+	/* Traverse only the allowed CPUs */
+	for_each_cpu_and(i, sched_group_cpus(group), &p->cpus_allowed) {
+		load = weighted_cpuload(i);
+
+		if (load < min_load || (load == min_load && i == this_cpu)) {
+			min_load = load;
+			idlest = i;
 		}
 	}
 
-	if (unlikely(!cpumask_test_cpu(this_cpu, &p->cpus_allowed)))
-		goto out;
+	return idlest;
+}
 
-	/*
-	 * Check for affine wakeup and passive balancing possibilities.
-	 */
-	if (!this_sd)
+/*
+ * sched_balance_self: balance the current task (running on cpu) in domains
+ * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and
+ * SD_BALANCE_EXEC.
+ *
+ * Balance, ie. select the least loaded group.
+ *
+ * Returns the target CPU number, or the same CPU if no balancing is needed.
+ *
+ * preempt must be disabled.
+ */
+static int select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags)
+{
+	struct sched_domain *tmp, *affine_sd = NULL, *sd = NULL;
+	int cpu = smp_processor_id();
+	int prev_cpu = task_cpu(p);
+	int new_cpu = cpu;
+	int want_affine = 0;
+	int want_sd = 1;
+	int sync = wake_flags & WF_SYNC;
+
+	if (sd_flag & SD_BALANCE_WAKE) {
+		if (sched_feat(AFFINE_WAKEUPS) &&
+		    cpumask_test_cpu(cpu, &p->cpus_allowed))
+			want_affine = 1;
+		new_cpu = prev_cpu;
+	}
+
+	rcu_read_lock();
+	for_each_domain(cpu, tmp) {
+		/*
+		 * If power savings logic is enabled for a domain, see if we
+		 * are not overloaded, if so, don't balance wider.
+		 */
+		if (tmp->flags & (SD_POWERSAVINGS_BALANCE|SD_PREFER_LOCAL)) {
+			unsigned long power = 0;
+			unsigned long nr_running = 0;
+			unsigned long capacity;
+			int i;
+
+			for_each_cpu(i, sched_domain_span(tmp)) {
+				power += power_of(i);
+				nr_running += cpu_rq(i)->cfs.nr_running;
+			}
+
+			capacity = DIV_ROUND_CLOSEST(power, SCHED_LOAD_SCALE);
+
+			if (tmp->flags & SD_POWERSAVINGS_BALANCE)
+				nr_running /= 2;
+
+			if (nr_running < capacity)
+				want_sd = 0;
+		}
+
+		if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
+		    cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
+
+			affine_sd = tmp;
+			want_affine = 0;
+		}
+
+		if (!want_sd && !want_affine)
+			break;
+
+		if (!(tmp->flags & sd_flag))
+			continue;
+
+		if (want_sd)
+			sd = tmp;
+	}
+
+	if (sched_feat(LB_SHARES_UPDATE)) {
+		/*
+		 * Pick the largest domain to update shares over
+		 */
+		tmp = sd;
+		if (affine_sd && (!tmp ||
+				  cpumask_weight(sched_domain_span(affine_sd)) >
+				  cpumask_weight(sched_domain_span(sd))))
+			tmp = affine_sd;
+
+		if (tmp)
+			update_shares(tmp);
+	}
+
+	if (affine_sd && wake_affine(affine_sd, p, sync)) {
+		new_cpu = cpu;
 		goto out;
+	}
 
-	idx = this_sd->wake_idx;
+	while (sd) {
+		int load_idx = sd->forkexec_idx;
+		struct sched_group *group;
+		int weight;
 
-	imbalance = 100 + (this_sd->imbalance_pct - 100) / 2;
+		if (!(sd->flags & sd_flag)) {
+			sd = sd->child;
+			continue;
+		}
 
-	load = source_load(prev_cpu, idx);
-	this_load = target_load(this_cpu, idx);
+		if (sd_flag & SD_BALANCE_WAKE)
+			load_idx = sd->wake_idx;
 
-	if (wake_affine(this_sd, this_rq, p, prev_cpu, this_cpu, sync, idx,
-				     load, this_load, imbalance))
-		return this_cpu;
+		group = find_idlest_group(sd, p, cpu, load_idx);
+		if (!group) {
+			sd = sd->child;
+			continue;
+		}
 
-	/*
-	 * Start passive balancing when half the imbalance_pct
-	 * limit is reached.
-	 */
-	if (this_sd->flags & SD_WAKE_BALANCE) {
-		if (imbalance*this_load <= 100*load) {
-			schedstat_inc(this_sd, ttwu_move_balance);
-			schedstat_inc(p, se.nr_wakeups_passive);
-			return this_cpu;
+		new_cpu = find_idlest_cpu(group, p, cpu);
+		if (new_cpu == -1 || new_cpu == cpu) {
+			/* Now try balancing at a lower domain level of cpu */
+			sd = sd->child;
+			continue;
+		}
+
+		/* Now try balancing at a lower domain level of new_cpu */
+		cpu = new_cpu;
+		weight = cpumask_weight(sched_domain_span(sd));
+		sd = NULL;
+		for_each_domain(cpu, tmp) {
+			if (weight <= cpumask_weight(sched_domain_span(tmp)))
+				break;
+			if (tmp->flags & sd_flag)
+				sd = tmp;
 		}
+		/* while loop will break here if sd == NULL */
 	}
 
 out:
-	return wake_idle(new_cpu, p);
+	rcu_read_unlock();
+	return new_cpu;
 }
 #endif /* CONFIG_SMP */
 
@@ -1471,11 +1562,12 @@ static void set_next_buddy(struct sched_entity *se)
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
+static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_flags)
 {
 	struct task_struct *curr = rq->curr;
 	struct sched_entity *se = &curr->se, *pse = &p->se;
 	struct cfs_rq *cfs_rq = task_cfs_rq(curr);
+	int sync = wake_flags & WF_SYNC;
 
 	update_curr(cfs_rq);
 
@@ -1501,7 +1593,8 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
 	 */
 	if (sched_feat(LAST_BUDDY) && likely(se->on_rq && curr != rq->idle))
 		set_last_buddy(se);
-	set_next_buddy(pse);
+	if (sched_feat(NEXT_BUDDY) && !(wake_flags & WF_FORK))
+		set_next_buddy(pse);
 
 	/*
 	 * We can come here with TIF_NEED_RESCHED already set from new task
@@ -1523,16 +1616,25 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync)
 		return;
 	}
 
-	if (!sched_feat(WAKEUP_PREEMPT))
-		return;
-
-	if (sched_feat(WAKEUP_OVERLAP) && (sync ||
-			(se->avg_overlap < sysctl_sched_migration_cost &&
-			 pse->avg_overlap < sysctl_sched_migration_cost))) {
+	if ((sched_feat(WAKEUP_SYNC) && sync) ||
+	    (sched_feat(WAKEUP_OVERLAP) &&
+	     (se->avg_overlap < sysctl_sched_migration_cost &&
+	      pse->avg_overlap < sysctl_sched_migration_cost))) {
 		resched_task(curr);
 		return;
 	}
 
+	if (sched_feat(WAKEUP_RUNNING)) {
+		if (pse->avg_running < se->avg_running) {
+			set_next_buddy(pse);
+			resched_task(curr);
+			return;
+		}
+	}
+
+	if (!sched_feat(WAKEUP_PREEMPT))
+		return;
+
 	find_matching_se(&se, &pse);
 
 	BUG_ON(!pse);
@@ -1555,8 +1657,13 @@ static struct task_struct *pick_next_task_fair(struct rq *rq)
 		/*
 		 * If se was a buddy, clear it so that it will have to earn
 		 * the favour again.
+		 *
+		 * If se was not a buddy, clear the buddies because neither
+		 * was elegible to run, let them earn it again.
+		 *
+		 * IOW. unconditionally clear buddies.
 		 */
-		__clear_buddies(cfs_rq, se);
+		__clear_buddies(cfs_rq, NULL);
 		set_next_entity(cfs_rq, se);
 		cfs_rq = group_cfs_rq(se);
 	} while (cfs_rq);
@@ -1832,6 +1939,25 @@ static void moved_group_fair(struct task_struct *p)
 }
 #endif
 
+unsigned int get_rr_interval_fair(struct task_struct *task)
+{
+	struct sched_entity *se = &task->se;
+	unsigned long flags;
+	struct rq *rq;
+	unsigned int rr_interval = 0;
+
+	/*
+	 * Time slice is 0 for SCHED_OTHER tasks that are on an otherwise
+	 * idle runqueue:
+	 */
+	rq = task_rq_lock(task, &flags);
+	if (rq->cfs.load.weight)
+		rr_interval = NS_TO_JIFFIES(sched_slice(&rq->cfs, se));
+	task_rq_unlock(rq, &flags);
+
+	return rr_interval;
+}
+
 /*
  * All the scheduling class methods:
  */
@@ -1860,6 +1986,8 @@ static const struct sched_class fair_sched_class = {
 	.prio_changed		= prio_changed_fair,
 	.switched_to		= switched_to_fair,
 
+	.get_rr_interval	= get_rr_interval_fair,
+
 #ifdef CONFIG_FAIR_GROUP_SCHED
 	.moved_group		= moved_group_fair,
 #endif
diff --git a/kernel/sched_features.h b/kernel/sched_features.h
index e2dc63a..0d94083 100644
--- a/kernel/sched_features.h
+++ b/kernel/sched_features.h
@@ -1,17 +1,123 @@
-SCHED_FEAT(NEW_FAIR_SLEEPERS, 0)
+/*
+ * Disregards a certain amount of sleep time (sched_latency_ns) and
+ * considers the task to be running during that period. This gives it
+ * a service deficit on wakeup, allowing it to run sooner.
+ */
+SCHED_FEAT(FAIR_SLEEPERS, 1)
+
+/*
+ * Only give sleepers 50% of their service deficit. This allows
+ * them to run sooner, but does not allow tons of sleepers to
+ * rip the spread apart.
+ */
+SCHED_FEAT(GENTLE_FAIR_SLEEPERS, 1)
+
+/*
+ * By not normalizing the sleep time, heavy tasks get an effective
+ * longer period, and lighter task an effective shorter period they
+ * are considered running.
+ */
 SCHED_FEAT(NORMALIZED_SLEEPER, 0)
-SCHED_FEAT(ADAPTIVE_GRAN, 1)
-SCHED_FEAT(WAKEUP_PREEMPT, 1)
+
+/*
+ * Place new tasks ahead so that they do not starve already running
+ * tasks
+ */
 SCHED_FEAT(START_DEBIT, 1)
+
+/*
+ * Should wakeups try to preempt running tasks.
+ */
+SCHED_FEAT(WAKEUP_PREEMPT, 1)
+
+/*
+ * Compute wakeup_gran based on task behaviour, clipped to
+ *  [0, sched_wakeup_gran_ns]
+ */
+SCHED_FEAT(ADAPTIVE_GRAN, 1)
+
+/*
+ * When converting the wakeup granularity to virtual time, do it such
+ * that heavier tasks preempting a lighter task have an edge.
+ */
+SCHED_FEAT(ASYM_GRAN, 1)
+
+/*
+ * Always wakeup-preempt SYNC wakeups, see SYNC_WAKEUPS.
+ */
+SCHED_FEAT(WAKEUP_SYNC, 0)
+
+/*
+ * Wakeup preempt based on task behaviour. Tasks that do not overlap
+ * don't get preempted.
+ */
+SCHED_FEAT(WAKEUP_OVERLAP, 0)
+
+/*
+ * Wakeup preemption towards tasks that run short
+ */
+SCHED_FEAT(WAKEUP_RUNNING, 0)
+
+/*
+ * Use the SYNC wakeup hint, pipes and the likes use this to indicate
+ * the remote end is likely to consume the data we just wrote, and
+ * therefore has cache benefit from being placed on the same cpu, see
+ * also AFFINE_WAKEUPS.
+ */
+SCHED_FEAT(SYNC_WAKEUPS, 1)
+
+/*
+ * Based on load and program behaviour, see if it makes sense to place
+ * a newly woken task on the same cpu as the task that woke it --
+ * improve cache locality. Typically used with SYNC wakeups as
+ * generated by pipes and the like, see also SYNC_WAKEUPS.
+ */
 SCHED_FEAT(AFFINE_WAKEUPS, 1)
+
+/*
+ * Weaken SYNC hint based on overlap
+ */
+SCHED_FEAT(SYNC_LESS, 1)
+
+/*
+ * Add SYNC hint based on overlap
+ */
+SCHED_FEAT(SYNC_MORE, 0)
+
+/*
+ * Prefer to schedule the task we woke last (assuming it failed
+ * wakeup-preemption), since its likely going to consume data we
+ * touched, increases cache locality.
+ */
+SCHED_FEAT(NEXT_BUDDY, 0)
+
+/*
+ * Prefer to schedule the task that ran last (when we did
+ * wake-preempt) as that likely will touch the same data, increases
+ * cache locality.
+ */
+SCHED_FEAT(LAST_BUDDY, 1)
+
+/*
+ * Consider buddies to be cache hot, decreases the likelyness of a
+ * cache buddy being migrated away, increases cache locality.
+ */
 SCHED_FEAT(CACHE_HOT_BUDDY, 1)
-SCHED_FEAT(SYNC_WAKEUPS, 1)
+
+/*
+ * Use arch dependent cpu power functions
+ */
+SCHED_FEAT(ARCH_POWER, 0)
+
 SCHED_FEAT(HRTICK, 0)
 SCHED_FEAT(DOUBLE_TICK, 0)
-SCHED_FEAT(ASYM_GRAN, 1)
 SCHED_FEAT(LB_BIAS, 1)
-SCHED_FEAT(LB_WAKEUP_UPDATE, 1)
+SCHED_FEAT(LB_SHARES_UPDATE, 1)
 SCHED_FEAT(ASYM_EFF_LOAD, 1)
-SCHED_FEAT(WAKEUP_OVERLAP, 0)
-SCHED_FEAT(LAST_BUDDY, 1)
+
+/*
+ * Spin-wait on mutex acquisition when the mutex owner is running on
+ * another cpu -- assumes that when the owner is running, it will soon
+ * release the lock. Decreases scheduling overhead.
+ */
 SCHED_FEAT(OWNER_SPIN, 1)
diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c
index 499672c..b133a28 100644
--- a/kernel/sched_idletask.c
+++ b/kernel/sched_idletask.c
@@ -6,7 +6,7 @@
  */
 
 #ifdef CONFIG_SMP
-static int select_task_rq_idle(struct task_struct *p, int sync)
+static int select_task_rq_idle(struct task_struct *p, int sd_flag, int flags)
 {
 	return task_cpu(p); /* IDLE tasks as never migrated */
 }
@@ -14,7 +14,7 @@ static int select_task_rq_idle(struct task_struct *p, int sync)
 /*
  * Idle tasks are unconditionally rescheduled:
  */
-static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int sync)
+static void check_preempt_curr_idle(struct rq *rq, struct task_struct *p, int flags)
 {
 	resched_task(rq->idle);
 }
@@ -97,6 +97,11 @@ static void prio_changed_idle(struct rq *rq, struct task_struct *p,
 		check_preempt_curr(rq, p, 0);
 }
 
+unsigned int get_rr_interval_idle(struct task_struct *task)
+{
+	return 0;
+}
+
 /*
  * Simple, special scheduling class for the per-CPU idle tasks:
  */
@@ -122,6 +127,8 @@ static const struct sched_class idle_sched_class = {
 	.set_curr_task          = set_curr_task_idle,
 	.task_tick		= task_tick_idle,
 
+	.get_rr_interval	= get_rr_interval_idle,
+
 	.prio_changed		= prio_changed_idle,
 	.switched_to		= switched_to_idle,
 
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 2eb4bd6..a4d790c 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -938,10 +938,13 @@ static void yield_task_rt(struct rq *rq)
 #ifdef CONFIG_SMP
 static int find_lowest_rq(struct task_struct *task);
 
-static int select_task_rq_rt(struct task_struct *p, int sync)
+static int select_task_rq_rt(struct task_struct *p, int sd_flag, int flags)
 {
 	struct rq *rq = task_rq(p);
 
+	if (sd_flag != SD_BALANCE_WAKE)
+		return smp_processor_id();
+
 	/*
 	 * If the current task is an RT task, then
 	 * try to see if we can wake this RT task up on another
@@ -999,7 +1002,7 @@ static void check_preempt_equal_prio(struct rq *rq, struct task_struct *p)
 /*
  * Preempt the current task with a newly woken task if needed:
  */
-static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int sync)
+static void check_preempt_curr_rt(struct rq *rq, struct task_struct *p, int flags)
 {
 	if (p->prio < rq->curr->prio) {
 		resched_task(rq->curr);
@@ -1731,6 +1734,17 @@ static void set_curr_task_rt(struct rq *rq)
 	dequeue_pushable_task(rq, p);
 }
 
+unsigned int get_rr_interval_rt(struct task_struct *task)
+{
+	/*
+	 * Time slice is 0 for SCHED_FIFO tasks
+	 */
+	if (task->policy == SCHED_RR)
+		return DEF_TIMESLICE;
+	else
+		return 0;
+}
+
 static const struct sched_class rt_sched_class = {
 	.next			= &fair_sched_class,
 	.enqueue_task		= enqueue_task_rt,
@@ -1759,6 +1773,8 @@ static const struct sched_class rt_sched_class = {
 	.set_curr_task          = set_curr_task_rt,
 	.task_tick		= task_tick_rt,
 
+	.get_rr_interval	= get_rr_interval_rt,
+
 	.prio_changed		= prio_changed_rt,
 	.switched_to		= switched_to_rt,
 };
diff --git a/kernel/smp.c b/kernel/smp.c
index 94188b8..8e21850 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -177,6 +177,11 @@ void generic_smp_call_function_interrupt(void)
 	int cpu = get_cpu();
 
 	/*
+	 * Shouldn't receive this interrupt on a cpu that is not yet online.
+	 */
+	WARN_ON_ONCE(!cpu_online(cpu));
+
+	/*
 	 * 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
@@ -230,6 +235,11 @@ void generic_smp_call_function_single_interrupt(void)
 	unsigned int data_flags;
 	LIST_HEAD(list);
 
+	/*
+	 * Shouldn't receive this interrupt on a cpu that is not yet online.
+	 */
+	WARN_ON_ONCE(!cpu_online(smp_processor_id()));
+
 	spin_lock(&q->lock);
 	list_replace_init(&q->list, &list);
 	spin_unlock(&q->lock);
@@ -285,8 +295,14 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
 	 */
 	this_cpu = get_cpu();
 
-	/* Can deadlock when called with interrupts disabled */
-	WARN_ON_ONCE(irqs_disabled() && !oops_in_progress);
+	/*
+	 * Can deadlock when called with interrupts disabled.
+	 * We allow cpu's that are not yet online though, as no one else can
+	 * send smp call function interrupt to this cpu and as such deadlocks
+	 * can't happen.
+	 */
+	WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled()
+		     && !oops_in_progress);
 
 	if (cpu == this_cpu) {
 		local_irq_save(flags);
@@ -329,8 +345,14 @@ void __smp_call_function_single(int cpu, struct call_single_data *data,
 {
 	csd_lock(data);
 
-	/* Can deadlock when called with interrupts disabled */
-	WARN_ON_ONCE(wait && irqs_disabled() && !oops_in_progress);
+	/*
+	 * Can deadlock when called with interrupts disabled.
+	 * We allow cpu's that are not yet online though, as no one else can
+	 * send smp call function interrupt to this cpu and as such deadlocks
+	 * can't happen.
+	 */
+	WARN_ON_ONCE(cpu_online(smp_processor_id()) && wait && irqs_disabled()
+		     && !oops_in_progress);
 
 	generic_exec_single(cpu, data, wait);
 }
@@ -365,8 +387,14 @@ void smp_call_function_many(const struct cpumask *mask,
 	unsigned long flags;
 	int cpu, next_cpu, this_cpu = smp_processor_id();
 
-	/* Can deadlock when called with interrupts disabled */
-	WARN_ON_ONCE(irqs_disabled() && !oops_in_progress);
+	/*
+	 * Can deadlock when called with interrupts disabled.
+	 * We allow cpu's that are not yet online though, as no one else can
+	 * send smp call function interrupt to this cpu and as such deadlocks
+	 * can't happen.
+	 */
+	WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled()
+		     && !oops_in_progress);
 
 	/* So, what's a CPU they want? Ignoring this one. */
 	cpu = cpumask_first_and(mask, cpu_online_mask);
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 7db2506..f8749e5 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -57,7 +57,7 @@ static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp
 static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
 
 char *softirq_to_name[NR_SOFTIRQS] = {
-	"HI", "TIMER", "NET_TX", "NET_RX", "BLOCK",
+	"HI", "TIMER", "NET_TX", "NET_RX", "BLOCK", "BLOCK_IOPOLL",
 	"TASKLET", "SCHED", "HRTIMER",	"RCU"
 };
 
diff --git a/kernel/sys.c b/kernel/sys.c
index b3f1097..ea5c3bc 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -14,7 +14,7 @@
 #include <linux/prctl.h>
 #include <linux/highuid.h>
 #include <linux/fs.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/resource.h>
 #include <linux/kernel.h>
 #include <linux/kexec.h>
@@ -1511,11 +1511,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 		case PR_SET_TSC:
 			error = SET_TSC_CTL(arg2);
 			break;
-		case PR_TASK_PERF_COUNTERS_DISABLE:
-			error = perf_counter_task_disable();
+		case PR_TASK_PERF_EVENTS_DISABLE:
+			error = perf_event_task_disable();
 			break;
-		case PR_TASK_PERF_COUNTERS_ENABLE:
-			error = perf_counter_task_enable();
+		case PR_TASK_PERF_EVENTS_ENABLE:
+			error = perf_event_task_enable();
 			break;
 		case PR_GET_TIMERSLACK:
 			error = current->timer_slack_ns;
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 68320f6..515bc23 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -177,4 +177,4 @@ cond_syscall(sys_eventfd);
 cond_syscall(sys_eventfd2);
 
 /* performance counters: */
-cond_syscall(sys_perf_counter_open);
+cond_syscall(sys_perf_event_open);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 3125cff..6ba49c7 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -50,7 +50,7 @@
 #include <linux/reboot.h>
 #include <linux/ftrace.h>
 #include <linux/slow-work.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>
@@ -91,6 +91,9 @@ extern int sysctl_nr_trim_pages;
 #ifdef CONFIG_RCU_TORTURE_TEST
 extern int rcutorture_runnable;
 #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
+#ifdef CONFIG_BLOCK
+extern int blk_iopoll_enabled;
+#endif
 
 /* Constants used for minimum and  maximum */
 #ifdef CONFIG_DETECT_SOFTLOCKUP
@@ -961,28 +964,28 @@ static struct ctl_table kern_table[] = {
 		.child		= slow_work_sysctls,
 	},
 #endif
-#ifdef CONFIG_PERF_COUNTERS
+#ifdef CONFIG_PERF_EVENTS
 	{
 		.ctl_name	= CTL_UNNUMBERED,
-		.procname	= "perf_counter_paranoid",
-		.data		= &sysctl_perf_counter_paranoid,
-		.maxlen		= sizeof(sysctl_perf_counter_paranoid),
+		.procname	= "perf_event_paranoid",
+		.data		= &sysctl_perf_event_paranoid,
+		.maxlen		= sizeof(sysctl_perf_event_paranoid),
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
 	{
 		.ctl_name	= CTL_UNNUMBERED,
-		.procname	= "perf_counter_mlock_kb",
-		.data		= &sysctl_perf_counter_mlock,
-		.maxlen		= sizeof(sysctl_perf_counter_mlock),
+		.procname	= "perf_event_mlock_kb",
+		.data		= &sysctl_perf_event_mlock,
+		.maxlen		= sizeof(sysctl_perf_event_mlock),
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
 	{
 		.ctl_name	= CTL_UNNUMBERED,
-		.procname	= "perf_counter_max_sample_rate",
-		.data		= &sysctl_perf_counter_sample_rate,
-		.maxlen		= sizeof(sysctl_perf_counter_sample_rate),
+		.procname	= "perf_event_max_sample_rate",
+		.data		= &sysctl_perf_event_sample_rate,
+		.maxlen		= sizeof(sysctl_perf_event_sample_rate),
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
@@ -997,7 +1000,16 @@ static struct ctl_table kern_table[] = {
 		.proc_handler	= &proc_dointvec,
 	},
 #endif
-
+#ifdef CONFIG_BLOCK
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "blk_iopoll",
+		.data		= &blk_iopoll_enabled,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+#endif
 /*
  * NOTE: do not add new entries to this table unless you have read
  * Documentation/sysctl/ctl_unnumbered.txt
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 888adbc..ea8384d 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -108,7 +108,7 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
 /*
  * Send taskstats data in @skb to listener with nl_pid @pid
  */
-static int send_reply(struct sk_buff *skb, pid_t pid)
+static int send_reply(struct sk_buff *skb, struct genl_info *info)
 {
 	struct genlmsghdr *genlhdr = nlmsg_data(nlmsg_hdr(skb));
 	void *reply = genlmsg_data(genlhdr);
@@ -120,7 +120,7 @@ static int send_reply(struct sk_buff *skb, pid_t pid)
 		return rc;
 	}
 
-	return genlmsg_unicast(skb, pid);
+	return genlmsg_reply(skb, info);
 }
 
 /*
@@ -150,7 +150,7 @@ static void send_cpu_listeners(struct sk_buff *skb,
 			if (!skb_next)
 				break;
 		}
-		rc = genlmsg_unicast(skb_cur, s->pid);
+		rc = genlmsg_unicast(&init_net, skb_cur, s->pid);
 		if (rc == -ECONNREFUSED) {
 			s->valid = 0;
 			delcount++;
@@ -418,7 +418,7 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
 		goto err;
 	}
 
-	rc = send_reply(rep_skb, info->snd_pid);
+	rc = send_reply(rep_skb, info);
 
 err:
 	fput_light(file, fput_needed);
@@ -487,7 +487,7 @@ free_return_rc:
 	} else
 		goto err;
 
-	return send_reply(rep_skb, info->snd_pid);
+	return send_reply(rep_skb, info);
 err:
 	nlmsg_free(rep_skb);
 	return rc;
diff --git a/kernel/time.c b/kernel/time.c
index 2951194..2e2e469 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -370,13 +370,20 @@ EXPORT_SYMBOL(mktime);
  *	0 <= tv_nsec < NSEC_PER_SEC
  * For negative values only the tv_sec field is negative !
  */
-void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec)
+void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec)
 {
 	while (nsec >= NSEC_PER_SEC) {
+		/*
+		 * The following asm() prevents the compiler from
+		 * optimising this loop into a modulo operation. See
+		 * also __iter_div_u64_rem() in include/linux/time.h
+		 */
+		asm("" : "+rm"(nsec));
 		nsec -= NSEC_PER_SEC;
 		++sec;
 	}
 	while (nsec < 0) {
+		asm("" : "+rm"(nsec));
 		nsec += NSEC_PER_SEC;
 		--sec;
 	}
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 7466cb8..0911334 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -21,7 +21,6 @@
  *
  * TODO WishList:
  *   o Allow clocksource drivers to be unregistered
- *   o get rid of clocksource_jiffies extern
  */
 
 #include <linux/clocksource.h>
@@ -30,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/sched.h> /* for spin_unlock_irq() using preempt_count() m68k */
 #include <linux/tick.h>
+#include <linux/kthread.h>
 
 void timecounter_init(struct timecounter *tc,
 		      const struct cyclecounter *cc,
@@ -107,50 +107,35 @@ u64 timecounter_cyc2time(struct timecounter *tc,
 }
 EXPORT_SYMBOL(timecounter_cyc2time);
 
-/* XXX - Would like a better way for initializing curr_clocksource */
-extern struct clocksource clocksource_jiffies;
-
 /*[Clocksource internal variables]---------
  * curr_clocksource:
- *	currently selected clocksource. Initialized to clocksource_jiffies.
- * next_clocksource:
- *	pending next selected clocksource.
+ *	currently selected clocksource.
  * clocksource_list:
  *	linked list with the registered clocksources
- * clocksource_lock:
- *	protects manipulations to curr_clocksource and next_clocksource
- *	and the clocksource_list
+ * clocksource_mutex:
+ *	protects manipulations to curr_clocksource and the clocksource_list
  * override_name:
  *	Name of the user-specified clocksource.
  */
-static struct clocksource *curr_clocksource = &clocksource_jiffies;
-static struct clocksource *next_clocksource;
-static struct clocksource *clocksource_override;
+static struct clocksource *curr_clocksource;
 static LIST_HEAD(clocksource_list);
-static DEFINE_SPINLOCK(clocksource_lock);
+static DEFINE_MUTEX(clocksource_mutex);
 static char override_name[32];
 static int finished_booting;
 
-/* clocksource_done_booting - Called near the end of core bootup
- *
- * Hack to avoid lots of clocksource churn at boot time.
- * We use fs_initcall because we want this to start before
- * device_initcall but after subsys_initcall.
- */
-static int __init clocksource_done_booting(void)
-{
-	finished_booting = 1;
-	return 0;
-}
-fs_initcall(clocksource_done_booting);
-
 #ifdef CONFIG_CLOCKSOURCE_WATCHDOG
+static void clocksource_watchdog_work(struct work_struct *work);
+
 static LIST_HEAD(watchdog_list);
 static struct clocksource *watchdog;
 static struct timer_list watchdog_timer;
+static DECLARE_WORK(watchdog_work, clocksource_watchdog_work);
 static DEFINE_SPINLOCK(watchdog_lock);
 static cycle_t watchdog_last;
-static unsigned long watchdog_resumed;
+static int watchdog_running;
+
+static int clocksource_watchdog_kthread(void *data);
+static void __clocksource_change_rating(struct clocksource *cs, int rating);
 
 /*
  * Interval: 0.5sec Threshold: 0.0625s
@@ -158,135 +143,249 @@ static unsigned long watchdog_resumed;
 #define WATCHDOG_INTERVAL (HZ >> 1)
 #define WATCHDOG_THRESHOLD (NSEC_PER_SEC >> 4)
 
-static void clocksource_ratewd(struct clocksource *cs, int64_t delta)
+static void clocksource_watchdog_work(struct work_struct *work)
 {
-	if (delta > -WATCHDOG_THRESHOLD && delta < WATCHDOG_THRESHOLD)
-		return;
+	/*
+	 * If kthread_run fails the next watchdog scan over the
+	 * watchdog_list will find the unstable clock again.
+	 */
+	kthread_run(clocksource_watchdog_kthread, NULL, "kwatchdog");
+}
 
+static void __clocksource_unstable(struct clocksource *cs)
+{
+	cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
+	cs->flags |= CLOCK_SOURCE_UNSTABLE;
+	if (finished_booting)
+		schedule_work(&watchdog_work);
+}
+
+static void clocksource_unstable(struct clocksource *cs, int64_t delta)
+{
 	printk(KERN_WARNING "Clocksource %s unstable (delta = %Ld ns)\n",
 	       cs->name, delta);
-	cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
-	clocksource_change_rating(cs, 0);
-	list_del(&cs->wd_list);
+	__clocksource_unstable(cs);
+}
+
+/**
+ * clocksource_mark_unstable - mark clocksource unstable via watchdog
+ * @cs:		clocksource to be marked unstable
+ *
+ * This function is called instead of clocksource_change_rating from
+ * cpu hotplug code to avoid a deadlock between the clocksource mutex
+ * and the cpu hotplug mutex. It defers the update of the clocksource
+ * to the watchdog thread.
+ */
+void clocksource_mark_unstable(struct clocksource *cs)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&watchdog_lock, flags);
+	if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) {
+		if (list_empty(&cs->wd_list))
+			list_add(&cs->wd_list, &watchdog_list);
+		__clocksource_unstable(cs);
+	}
+	spin_unlock_irqrestore(&watchdog_lock, flags);
 }
 
 static void clocksource_watchdog(unsigned long data)
 {
-	struct clocksource *cs, *tmp;
+	struct clocksource *cs;
 	cycle_t csnow, wdnow;
 	int64_t wd_nsec, cs_nsec;
-	int resumed;
+	int next_cpu;
 
 	spin_lock(&watchdog_lock);
-
-	resumed = test_and_clear_bit(0, &watchdog_resumed);
+	if (!watchdog_running)
+		goto out;
 
 	wdnow = watchdog->read(watchdog);
-	wd_nsec = cyc2ns(watchdog, (wdnow - watchdog_last) & watchdog->mask);
+	wd_nsec = clocksource_cyc2ns((wdnow - watchdog_last) & watchdog->mask,
+				     watchdog->mult, watchdog->shift);
 	watchdog_last = wdnow;
 
-	list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) {
-		csnow = cs->read(cs);
+	list_for_each_entry(cs, &watchdog_list, wd_list) {
 
-		if (unlikely(resumed)) {
-			cs->wd_last = csnow;
+		/* Clocksource already marked unstable? */
+		if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
+			if (finished_booting)
+				schedule_work(&watchdog_work);
 			continue;
 		}
 
-		/* Initialized ? */
+		csnow = cs->read(cs);
+
+		/* Clocksource initialized ? */
 		if (!(cs->flags & CLOCK_SOURCE_WATCHDOG)) {
-			if ((cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) &&
-			    (watchdog->flags & CLOCK_SOURCE_IS_CONTINUOUS)) {
-				cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
-				/*
-				 * We just marked the clocksource as
-				 * highres-capable, notify the rest of the
-				 * system as well so that we transition
-				 * into high-res mode:
-				 */
-				tick_clock_notify();
-			}
 			cs->flags |= CLOCK_SOURCE_WATCHDOG;
 			cs->wd_last = csnow;
-		} else {
-			cs_nsec = cyc2ns(cs, (csnow - cs->wd_last) & cs->mask);
-			cs->wd_last = csnow;
-			/* Check the delta. Might remove from the list ! */
-			clocksource_ratewd(cs, cs_nsec - wd_nsec);
+			continue;
 		}
-	}
 
-	if (!list_empty(&watchdog_list)) {
-		/*
-		 * Cycle through CPUs to check if the CPUs stay
-		 * synchronized to each other.
-		 */
-		int next_cpu = cpumask_next(raw_smp_processor_id(),
-					    cpu_online_mask);
+		/* Check the deviation from the watchdog clocksource. */
+		cs_nsec = clocksource_cyc2ns((csnow - cs->wd_last) &
+					     cs->mask, cs->mult, cs->shift);
+		cs->wd_last = csnow;
+		if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) {
+			clocksource_unstable(cs, cs_nsec - wd_nsec);
+			continue;
+		}
 
-		if (next_cpu >= nr_cpu_ids)
-			next_cpu = cpumask_first(cpu_online_mask);
-		watchdog_timer.expires += WATCHDOG_INTERVAL;
-		add_timer_on(&watchdog_timer, next_cpu);
+		if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) &&
+		    (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) &&
+		    (watchdog->flags & CLOCK_SOURCE_IS_CONTINUOUS)) {
+			cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
+			/*
+			 * We just marked the clocksource as highres-capable,
+			 * notify the rest of the system as well so that we
+			 * transition into high-res mode:
+			 */
+			tick_clock_notify();
+		}
 	}
+
+	/*
+	 * Cycle through CPUs to check if the CPUs stay synchronized
+	 * to each other.
+	 */
+	next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
+	if (next_cpu >= nr_cpu_ids)
+		next_cpu = cpumask_first(cpu_online_mask);
+	watchdog_timer.expires += WATCHDOG_INTERVAL;
+	add_timer_on(&watchdog_timer, next_cpu);
+out:
 	spin_unlock(&watchdog_lock);
 }
+
+static inline void clocksource_start_watchdog(void)
+{
+	if (watchdog_running || !watchdog || list_empty(&watchdog_list))
+		return;
+	init_timer(&watchdog_timer);
+	watchdog_timer.function = clocksource_watchdog;
+	watchdog_last = watchdog->read(watchdog);
+	watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
+	add_timer_on(&watchdog_timer, cpumask_first(cpu_online_mask));
+	watchdog_running = 1;
+}
+
+static inline void clocksource_stop_watchdog(void)
+{
+	if (!watchdog_running || (watchdog && !list_empty(&watchdog_list)))
+		return;
+	del_timer(&watchdog_timer);
+	watchdog_running = 0;
+}
+
+static inline void clocksource_reset_watchdog(void)
+{
+	struct clocksource *cs;
+
+	list_for_each_entry(cs, &watchdog_list, wd_list)
+		cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
+}
+
 static void clocksource_resume_watchdog(void)
 {
-	set_bit(0, &watchdog_resumed);
+	unsigned long flags;
+
+	spin_lock_irqsave(&watchdog_lock, flags);
+	clocksource_reset_watchdog();
+	spin_unlock_irqrestore(&watchdog_lock, flags);
 }
 
-static void clocksource_check_watchdog(struct clocksource *cs)
+static void clocksource_enqueue_watchdog(struct clocksource *cs)
 {
-	struct clocksource *cse;
 	unsigned long flags;
 
 	spin_lock_irqsave(&watchdog_lock, flags);
 	if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
-		int started = !list_empty(&watchdog_list);
-
+		/* cs is a clocksource to be watched. */
 		list_add(&cs->wd_list, &watchdog_list);
-		if (!started && watchdog) {
-			watchdog_last = watchdog->read(watchdog);
-			watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL;
-			add_timer_on(&watchdog_timer,
-				     cpumask_first(cpu_online_mask));
-		}
+		cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
 	} else {
+		/* cs is a watchdog. */
 		if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
 			cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
-
+		/* Pick the best watchdog. */
 		if (!watchdog || cs->rating > watchdog->rating) {
-			if (watchdog)
-				del_timer(&watchdog_timer);
 			watchdog = cs;
-			init_timer(&watchdog_timer);
-			watchdog_timer.function = clocksource_watchdog;
-
 			/* Reset watchdog cycles */
-			list_for_each_entry(cse, &watchdog_list, wd_list)
-				cse->flags &= ~CLOCK_SOURCE_WATCHDOG;
-			/* Start if list is not empty */
-			if (!list_empty(&watchdog_list)) {
-				watchdog_last = watchdog->read(watchdog);
-				watchdog_timer.expires =
-					jiffies + WATCHDOG_INTERVAL;
-				add_timer_on(&watchdog_timer,
-					     cpumask_first(cpu_online_mask));
-			}
+			clocksource_reset_watchdog();
+		}
+	}
+	/* Check if the watchdog timer needs to be started. */
+	clocksource_start_watchdog();
+	spin_unlock_irqrestore(&watchdog_lock, flags);
+}
+
+static void clocksource_dequeue_watchdog(struct clocksource *cs)
+{
+	struct clocksource *tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&watchdog_lock, flags);
+	if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
+		/* cs is a watched clocksource. */
+		list_del_init(&cs->wd_list);
+	} else if (cs == watchdog) {
+		/* Reset watchdog cycles */
+		clocksource_reset_watchdog();
+		/* Current watchdog is removed. Find an alternative. */
+		watchdog = NULL;
+		list_for_each_entry(tmp, &clocksource_list, list) {
+			if (tmp == cs || tmp->flags & CLOCK_SOURCE_MUST_VERIFY)
+				continue;
+			if (!watchdog || tmp->rating > watchdog->rating)
+				watchdog = tmp;
 		}
 	}
+	cs->flags &= ~CLOCK_SOURCE_WATCHDOG;
+	/* Check if the watchdog timer needs to be stopped. */
+	clocksource_stop_watchdog();
 	spin_unlock_irqrestore(&watchdog_lock, flags);
 }
-#else
-static void clocksource_check_watchdog(struct clocksource *cs)
+
+static int clocksource_watchdog_kthread(void *data)
+{
+	struct clocksource *cs, *tmp;
+	unsigned long flags;
+	LIST_HEAD(unstable);
+
+	mutex_lock(&clocksource_mutex);
+	spin_lock_irqsave(&watchdog_lock, flags);
+	list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list)
+		if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
+			list_del_init(&cs->wd_list);
+			list_add(&cs->wd_list, &unstable);
+		}
+	/* Check if the watchdog timer needs to be stopped. */
+	clocksource_stop_watchdog();
+	spin_unlock_irqrestore(&watchdog_lock, flags);
+
+	/* Needs to be done outside of watchdog lock */
+	list_for_each_entry_safe(cs, tmp, &unstable, wd_list) {
+		list_del_init(&cs->wd_list);
+		__clocksource_change_rating(cs, 0);
+	}
+	mutex_unlock(&clocksource_mutex);
+	return 0;
+}
+
+#else /* CONFIG_CLOCKSOURCE_WATCHDOG */
+
+static void clocksource_enqueue_watchdog(struct clocksource *cs)
 {
 	if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
 		cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
 }
 
+static inline void clocksource_dequeue_watchdog(struct clocksource *cs) { }
 static inline void clocksource_resume_watchdog(void) { }
-#endif
+static inline int clocksource_watchdog_kthread(void *data) { return 0; }
+
+#endif /* CONFIG_CLOCKSOURCE_WATCHDOG */
 
 /**
  * clocksource_resume - resume the clocksource(s)
@@ -294,18 +393,16 @@ static inline void clocksource_resume_watchdog(void) { }
 void clocksource_resume(void)
 {
 	struct clocksource *cs;
-	unsigned long flags;
 
-	spin_lock_irqsave(&clocksource_lock, flags);
+	mutex_lock(&clocksource_mutex);
 
-	list_for_each_entry(cs, &clocksource_list, list) {
+	list_for_each_entry(cs, &clocksource_list, list)
 		if (cs->resume)
 			cs->resume();
-	}
 
 	clocksource_resume_watchdog();
 
-	spin_unlock_irqrestore(&clocksource_lock, flags);
+	mutex_unlock(&clocksource_mutex);
 }
 
 /**
@@ -320,75 +417,94 @@ void clocksource_touch_watchdog(void)
 	clocksource_resume_watchdog();
 }
 
+#ifdef CONFIG_GENERIC_TIME
+
 /**
- * clocksource_get_next - Returns the selected clocksource
+ * clocksource_select - Select the best clocksource available
+ *
+ * Private function. Must hold clocksource_mutex when called.
  *
+ * Select the clocksource with the best rating, or the clocksource,
+ * which is selected by userspace override.
  */
-struct clocksource *clocksource_get_next(void)
+static void clocksource_select(void)
 {
-	unsigned long flags;
+	struct clocksource *best, *cs;
 
-	spin_lock_irqsave(&clocksource_lock, flags);
-	if (next_clocksource && finished_booting) {
-		curr_clocksource = next_clocksource;
-		next_clocksource = NULL;
+	if (!finished_booting || list_empty(&clocksource_list))
+		return;
+	/* First clocksource on the list has the best rating. */
+	best = list_first_entry(&clocksource_list, struct clocksource, list);
+	/* Check for the override clocksource. */
+	list_for_each_entry(cs, &clocksource_list, list) {
+		if (strcmp(cs->name, override_name) != 0)
+			continue;
+		/*
+		 * Check to make sure we don't switch to a non-highres
+		 * capable clocksource if the tick code is in oneshot
+		 * mode (highres or nohz)
+		 */
+		if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) &&
+		    tick_oneshot_mode_active()) {
+			/* Override clocksource cannot be used. */
+			printk(KERN_WARNING "Override clocksource %s is not "
+			       "HRT compatible. Cannot switch while in "
+			       "HRT/NOHZ mode\n", cs->name);
+			override_name[0] = 0;
+		} else
+			/* Override clocksource can be used. */
+			best = cs;
+		break;
+	}
+	if (curr_clocksource != best) {
+		printk(KERN_INFO "Switching to clocksource %s\n", best->name);
+		curr_clocksource = best;
+		timekeeping_notify(curr_clocksource);
 	}
-	spin_unlock_irqrestore(&clocksource_lock, flags);
-
-	return curr_clocksource;
 }
 
-/**
- * select_clocksource - Selects the best registered clocksource.
- *
- * Private function. Must hold clocksource_lock when called.
+#else /* CONFIG_GENERIC_TIME */
+
+static inline void clocksource_select(void) { }
+
+#endif
+
+/*
+ * clocksource_done_booting - Called near the end of core bootup
  *
- * Select the clocksource with the best rating, or the clocksource,
- * which is selected by userspace override.
+ * Hack to avoid lots of clocksource churn at boot time.
+ * We use fs_initcall because we want this to start before
+ * device_initcall but after subsys_initcall.
  */
-static struct clocksource *select_clocksource(void)
+static int __init clocksource_done_booting(void)
 {
-	struct clocksource *next;
-
-	if (list_empty(&clocksource_list))
-		return NULL;
-
-	if (clocksource_override)
-		next = clocksource_override;
-	else
-		next = list_entry(clocksource_list.next, struct clocksource,
-				  list);
+	finished_booting = 1;
 
-	if (next == curr_clocksource)
-		return NULL;
+	/*
+	 * Run the watchdog first to eliminate unstable clock sources
+	 */
+	clocksource_watchdog_kthread(NULL);
 
-	return next;
+	mutex_lock(&clocksource_mutex);
+	clocksource_select();
+	mutex_unlock(&clocksource_mutex);
+	return 0;
 }
+fs_initcall(clocksource_done_booting);
 
 /*
  * Enqueue the clocksource sorted by rating
  */
-static int clocksource_enqueue(struct clocksource *c)
+static void clocksource_enqueue(struct clocksource *cs)
 {
-	struct list_head *tmp, *entry = &clocksource_list;
+	struct list_head *entry = &clocksource_list;
+	struct clocksource *tmp;
 
-	list_for_each(tmp, &clocksource_list) {
-		struct clocksource *cs;
-
-		cs = list_entry(tmp, struct clocksource, list);
-		if (cs == c)
-			return -EBUSY;
+	list_for_each_entry(tmp, &clocksource_list, list)
 		/* Keep track of the place, where to insert */
-		if (cs->rating >= c->rating)
-			entry = tmp;
-	}
-	list_add(&c->list, entry);
-
-	if (strlen(c->name) == strlen(override_name) &&
-	    !strcmp(c->name, override_name))
-		clocksource_override = c;
-
-	return 0;
+		if (tmp->rating >= cs->rating)
+			entry = &tmp->list;
+	list_add(&cs->list, entry);
 }
 
 /**
@@ -397,52 +513,48 @@ static int clocksource_enqueue(struct clocksource *c)
  *
  * Returns -EBUSY if registration fails, zero otherwise.
  */
-int clocksource_register(struct clocksource *c)
+int clocksource_register(struct clocksource *cs)
 {
-	unsigned long flags;
-	int ret;
-
-	spin_lock_irqsave(&clocksource_lock, flags);
-	ret = clocksource_enqueue(c);
-	if (!ret)
-		next_clocksource = select_clocksource();
-	spin_unlock_irqrestore(&clocksource_lock, flags);
-	if (!ret)
-		clocksource_check_watchdog(c);
-	return ret;
+	mutex_lock(&clocksource_mutex);
+	clocksource_enqueue(cs);
+	clocksource_select();
+	clocksource_enqueue_watchdog(cs);
+	mutex_unlock(&clocksource_mutex);
+	return 0;
 }
 EXPORT_SYMBOL(clocksource_register);
 
+static void __clocksource_change_rating(struct clocksource *cs, int rating)
+{
+	list_del(&cs->list);
+	cs->rating = rating;
+	clocksource_enqueue(cs);
+	clocksource_select();
+}
+
 /**
  * clocksource_change_rating - Change the rating of a registered clocksource
- *
  */
 void clocksource_change_rating(struct clocksource *cs, int rating)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&clocksource_lock, flags);
-	list_del(&cs->list);
-	cs->rating = rating;
-	clocksource_enqueue(cs);
-	next_clocksource = select_clocksource();
-	spin_unlock_irqrestore(&clocksource_lock, flags);
+	mutex_lock(&clocksource_mutex);
+	__clocksource_change_rating(cs, rating);
+	mutex_unlock(&clocksource_mutex);
 }
+EXPORT_SYMBOL(clocksource_change_rating);
 
 /**
  * clocksource_unregister - remove a registered clocksource
  */
 void clocksource_unregister(struct clocksource *cs)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&clocksource_lock, flags);
+	mutex_lock(&clocksource_mutex);
+	clocksource_dequeue_watchdog(cs);
 	list_del(&cs->list);
-	if (clocksource_override == cs)
-		clocksource_override = NULL;
-	next_clocksource = select_clocksource();
-	spin_unlock_irqrestore(&clocksource_lock, flags);
+	clocksource_select();
+	mutex_unlock(&clocksource_mutex);
 }
+EXPORT_SYMBOL(clocksource_unregister);
 
 #ifdef CONFIG_SYSFS
 /**
@@ -458,9 +570,9 @@ sysfs_show_current_clocksources(struct sys_device *dev,
 {
 	ssize_t count = 0;
 
-	spin_lock_irq(&clocksource_lock);
+	mutex_lock(&clocksource_mutex);
 	count = snprintf(buf, PAGE_SIZE, "%s\n", curr_clocksource->name);
-	spin_unlock_irq(&clocksource_lock);
+	mutex_unlock(&clocksource_mutex);
 
 	return count;
 }
@@ -478,9 +590,7 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
 					  struct sysdev_attribute *attr,
 					  const char *buf, size_t count)
 {
-	struct clocksource *ovr = NULL;
 	size_t ret = count;
-	int len;
 
 	/* strings from sysfs write are not 0 terminated! */
 	if (count >= sizeof(override_name))
@@ -490,44 +600,14 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
 	if (buf[count-1] == '\n')
 		count--;
 
-	spin_lock_irq(&clocksource_lock);
+	mutex_lock(&clocksource_mutex);
 
 	if (count > 0)
 		memcpy(override_name, buf, count);
 	override_name[count] = 0;
+	clocksource_select();
 
-	len = strlen(override_name);
-	if (len) {
-		struct clocksource *cs;
-
-		ovr = clocksource_override;
-		/* try to select it: */
-		list_for_each_entry(cs, &clocksource_list, list) {
-			if (strlen(cs->name) == len &&
-			    !strcmp(cs->name, override_name))
-				ovr = cs;
-		}
-	}
-
-	/*
-	 * Check to make sure we don't switch to a non-highres capable
-	 * clocksource if the tick code is in oneshot mode (highres or nohz)
-	 */
-	if (tick_oneshot_mode_active() && ovr &&
-	    !(ovr->flags & CLOCK_SOURCE_VALID_FOR_HRES)) {
-		printk(KERN_WARNING "%s clocksource is not HRT compatible. "
-			"Cannot switch while in HRT/NOHZ mode\n", ovr->name);
-		ovr = NULL;
-		override_name[0] = 0;
-	}
-
-	/* Reselect, when the override name has changed */
-	if (ovr != clocksource_override) {
-		clocksource_override = ovr;
-		next_clocksource = select_clocksource();
-	}
-
-	spin_unlock_irq(&clocksource_lock);
+	mutex_unlock(&clocksource_mutex);
 
 	return ret;
 }
@@ -547,7 +627,7 @@ sysfs_show_available_clocksources(struct sys_device *dev,
 	struct clocksource *src;
 	ssize_t count = 0;
 
-	spin_lock_irq(&clocksource_lock);
+	mutex_lock(&clocksource_mutex);
 	list_for_each_entry(src, &clocksource_list, list) {
 		/*
 		 * Don't show non-HRES clocksource if the tick code is
@@ -559,7 +639,7 @@ sysfs_show_available_clocksources(struct sys_device *dev,
 				  max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
 				  "%s ", src->name);
 	}
-	spin_unlock_irq(&clocksource_lock);
+	mutex_unlock(&clocksource_mutex);
 
 	count += snprintf(buf + count,
 			  max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n");
@@ -614,11 +694,10 @@ device_initcall(init_clocksource_sysfs);
  */
 static int __init boot_override_clocksource(char* str)
 {
-	unsigned long flags;
-	spin_lock_irqsave(&clocksource_lock, flags);
+	mutex_lock(&clocksource_mutex);
 	if (str)
 		strlcpy(override_name, str, sizeof(override_name));
-	spin_unlock_irqrestore(&clocksource_lock, flags);
+	mutex_unlock(&clocksource_mutex);
 	return 1;
 }
 
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index c3f6c30..5404a84 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -61,7 +61,6 @@ struct clocksource clocksource_jiffies = {
 	.read		= jiffies_read,
 	.mask		= 0xffffffff, /*32bits*/
 	.mult		= NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
-	.mult_orig	= NSEC_PER_JIFFY << JIFFIES_SHIFT,
 	.shift		= JIFFIES_SHIFT,
 };
 
@@ -71,3 +70,8 @@ static int __init init_jiffies_clocksource(void)
 }
 
 core_initcall(init_jiffies_clocksource);
+
+struct clocksource * __init __weak clocksource_default_clock(void)
+{
+	return &clocksource_jiffies;
+}
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 7fc6437..4800f93 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -194,8 +194,7 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
 	case TIME_OK:
 		break;
 	case TIME_INS:
-		xtime.tv_sec--;
-		wall_to_monotonic.tv_sec++;
+		timekeeping_leap_insert(-1);
 		time_state = TIME_OOP;
 		printk(KERN_NOTICE
 			"Clock: inserting leap second 23:59:60 UTC\n");
@@ -203,9 +202,8 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
 		res = HRTIMER_RESTART;
 		break;
 	case TIME_DEL:
-		xtime.tv_sec++;
+		timekeeping_leap_insert(1);
 		time_tai--;
-		wall_to_monotonic.tv_sec--;
 		time_state = TIME_WAIT;
 		printk(KERN_NOTICE
 			"Clock: deleting leap second 23:59:59 UTC\n");
@@ -219,7 +217,6 @@ static enum hrtimer_restart ntp_leap_second(struct hrtimer *timer)
 			time_state = TIME_OK;
 		break;
 	}
-	update_vsyscall(&xtime, clock);
 
 	write_sequnlock(&xtime_lock);
 
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index e8c77d9..fb0f46f 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -18,7 +18,117 @@
 #include <linux/jiffies.h>
 #include <linux/time.h>
 #include <linux/tick.h>
+#include <linux/stop_machine.h>
+
+/* Structure holding internal timekeeping values. */
+struct timekeeper {
+	/* Current clocksource used for timekeeping. */
+	struct clocksource *clock;
+	/* The shift value of the current clocksource. */
+	int	shift;
+
+	/* Number of clock cycles in one NTP interval. */
+	cycle_t cycle_interval;
+	/* Number of clock shifted nano seconds in one NTP interval. */
+	u64	xtime_interval;
+	/* Raw nano seconds accumulated per NTP interval. */
+	u32	raw_interval;
+
+	/* Clock shifted nano seconds remainder not stored in xtime.tv_nsec. */
+	u64	xtime_nsec;
+	/* Difference between accumulated time and NTP time in ntp
+	 * shifted nano seconds. */
+	s64	ntp_error;
+	/* Shift conversion between clock shifted nano seconds and
+	 * ntp shifted nano seconds. */
+	int	ntp_error_shift;
+	/* NTP adjusted clock multiplier */
+	u32	mult;
+};
+
+struct timekeeper timekeeper;
+
+/**
+ * timekeeper_setup_internals - Set up internals to use clocksource clock.
+ *
+ * @clock:		Pointer to clocksource.
+ *
+ * Calculates a fixed cycle/nsec interval for a given clocksource/adjustment
+ * pair and interval request.
+ *
+ * Unless you're the timekeeping code, you should not be using this!
+ */
+static void timekeeper_setup_internals(struct clocksource *clock)
+{
+	cycle_t interval;
+	u64 tmp;
+
+	timekeeper.clock = clock;
+	clock->cycle_last = clock->read(clock);
 
+	/* Do the ns -> cycle conversion first, using original mult */
+	tmp = NTP_INTERVAL_LENGTH;
+	tmp <<= clock->shift;
+	tmp += clock->mult/2;
+	do_div(tmp, clock->mult);
+	if (tmp == 0)
+		tmp = 1;
+
+	interval = (cycle_t) tmp;
+	timekeeper.cycle_interval = interval;
+
+	/* Go back from cycles -> shifted ns */
+	timekeeper.xtime_interval = (u64) interval * clock->mult;
+	timekeeper.raw_interval =
+		((u64) interval * clock->mult) >> clock->shift;
+
+	timekeeper.xtime_nsec = 0;
+	timekeeper.shift = clock->shift;
+
+	timekeeper.ntp_error = 0;
+	timekeeper.ntp_error_shift = NTP_SCALE_SHIFT - clock->shift;
+
+	/*
+	 * The timekeeper keeps its own mult values for the currently
+	 * active clocksource. These value will be adjusted via NTP
+	 * to counteract clock drifting.
+	 */
+	timekeeper.mult = clock->mult;
+}
+
+/* Timekeeper helper functions. */
+static inline s64 timekeeping_get_ns(void)
+{
+	cycle_t cycle_now, cycle_delta;
+	struct clocksource *clock;
+
+	/* read clocksource: */
+	clock = timekeeper.clock;
+	cycle_now = clock->read(clock);
+
+	/* calculate the delta since the last update_wall_time: */
+	cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+	/* return delta convert to nanoseconds using ntp adjusted mult. */
+	return clocksource_cyc2ns(cycle_delta, timekeeper.mult,
+				  timekeeper.shift);
+}
+
+static inline s64 timekeeping_get_ns_raw(void)
+{
+	cycle_t cycle_now, cycle_delta;
+	struct clocksource *clock;
+
+	/* read clocksource: */
+	clock = timekeeper.clock;
+	cycle_now = clock->read(clock);
+
+	/* calculate the delta since the last update_wall_time: */
+	cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+	/* return delta convert to nanoseconds using ntp adjusted mult. */
+	return clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
+}
 
 /*
  * This read-write spinlock protects us from races in SMP while
@@ -44,7 +154,12 @@ __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock);
  */
 struct timespec xtime __attribute__ ((aligned (16)));
 struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
-static unsigned long total_sleep_time;		/* seconds */
+static struct timespec total_sleep_time;
+
+/*
+ * The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock.
+ */
+struct timespec raw_time;
 
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
@@ -56,35 +171,44 @@ void update_xtime_cache(u64 nsec)
 	timespec_add_ns(&xtime_cache, nsec);
 }
 
-struct clocksource *clock;
-
+/* must hold xtime_lock */
+void timekeeping_leap_insert(int leapsecond)
+{
+	xtime.tv_sec += leapsecond;
+	wall_to_monotonic.tv_sec -= leapsecond;
+	update_vsyscall(&xtime, timekeeper.clock);
+}
 
 #ifdef CONFIG_GENERIC_TIME
+
 /**
- * clocksource_forward_now - update clock to the current time
+ * timekeeping_forward_now - update clock to the current time
  *
  * Forward the current clock to update its state since the last call to
  * update_wall_time(). This is useful before significant clock changes,
  * as it avoids having to deal with this time offset explicitly.
  */
-static void clocksource_forward_now(void)
+static void timekeeping_forward_now(void)
 {
 	cycle_t cycle_now, cycle_delta;
+	struct clocksource *clock;
 	s64 nsec;
 
-	cycle_now = clocksource_read(clock);
+	clock = timekeeper.clock;
+	cycle_now = clock->read(clock);
 	cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
 	clock->cycle_last = cycle_now;
 
-	nsec = cyc2ns(clock, cycle_delta);
+	nsec = clocksource_cyc2ns(cycle_delta, timekeeper.mult,
+				  timekeeper.shift);
 
 	/* If arch requires, add in gettimeoffset() */
 	nsec += arch_gettimeoffset();
 
 	timespec_add_ns(&xtime, nsec);
 
-	nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
-	clock->raw_time.tv_nsec += nsec;
+	nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
+	timespec_add_ns(&raw_time, nsec);
 }
 
 /**
@@ -95,7 +219,6 @@ static void clocksource_forward_now(void)
  */
 void getnstimeofday(struct timespec *ts)
 {
-	cycle_t cycle_now, cycle_delta;
 	unsigned long seq;
 	s64 nsecs;
 
@@ -105,15 +228,7 @@ void getnstimeofday(struct timespec *ts)
 		seq = read_seqbegin(&xtime_lock);
 
 		*ts = xtime;
-
-		/* read clocksource: */
-		cycle_now = clocksource_read(clock);
-
-		/* calculate the delta since the last update_wall_time: */
-		cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
-
-		/* convert to nanoseconds: */
-		nsecs = cyc2ns(clock, cycle_delta);
+		nsecs = timekeeping_get_ns();
 
 		/* If arch requires, add in gettimeoffset() */
 		nsecs += arch_gettimeoffset();
@@ -125,6 +240,57 @@ void getnstimeofday(struct timespec *ts)
 
 EXPORT_SYMBOL(getnstimeofday);
 
+ktime_t ktime_get(void)
+{
+	unsigned int seq;
+	s64 secs, nsecs;
+
+	WARN_ON(timekeeping_suspended);
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		secs = xtime.tv_sec + wall_to_monotonic.tv_sec;
+		nsecs = xtime.tv_nsec + wall_to_monotonic.tv_nsec;
+		nsecs += timekeeping_get_ns();
+
+	} while (read_seqretry(&xtime_lock, seq));
+	/*
+	 * Use ktime_set/ktime_add_ns to create a proper ktime on
+	 * 32-bit architectures without CONFIG_KTIME_SCALAR.
+	 */
+	return ktime_add_ns(ktime_set(secs, 0), nsecs);
+}
+EXPORT_SYMBOL_GPL(ktime_get);
+
+/**
+ * ktime_get_ts - get the monotonic clock in timespec format
+ * @ts:		pointer to timespec variable
+ *
+ * The function calculates the monotonic clock from the realtime
+ * clock and the wall_to_monotonic offset and stores the result
+ * in normalized timespec format in the variable pointed to by @ts.
+ */
+void ktime_get_ts(struct timespec *ts)
+{
+	struct timespec tomono;
+	unsigned int seq;
+	s64 nsecs;
+
+	WARN_ON(timekeeping_suspended);
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		*ts = xtime;
+		tomono = wall_to_monotonic;
+		nsecs = timekeeping_get_ns();
+
+	} while (read_seqretry(&xtime_lock, seq));
+
+	set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
+				ts->tv_nsec + tomono.tv_nsec + nsecs);
+}
+EXPORT_SYMBOL_GPL(ktime_get_ts);
+
 /**
  * do_gettimeofday - Returns the time of day in a timeval
  * @tv:		pointer to the timeval to be set
@@ -157,7 +323,7 @@ int do_settimeofday(struct timespec *tv)
 
 	write_seqlock_irqsave(&xtime_lock, flags);
 
-	clocksource_forward_now();
+	timekeeping_forward_now();
 
 	ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec;
 	ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec;
@@ -167,10 +333,10 @@ int do_settimeofday(struct timespec *tv)
 
 	update_xtime_cache(0);
 
-	clock->error = 0;
+	timekeeper.ntp_error = 0;
 	ntp_clear();
 
-	update_vsyscall(&xtime, clock);
+	update_vsyscall(&xtime, timekeeper.clock);
 
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -187,44 +353,97 @@ EXPORT_SYMBOL(do_settimeofday);
  *
  * Accumulates current time interval and initializes new clocksource
  */
-static void change_clocksource(void)
+static int change_clocksource(void *data)
 {
 	struct clocksource *new, *old;
 
-	new = clocksource_get_next();
+	new = (struct clocksource *) data;
+
+	timekeeping_forward_now();
+	if (!new->enable || new->enable(new) == 0) {
+		old = timekeeper.clock;
+		timekeeper_setup_internals(new);
+		if (old->disable)
+			old->disable(old);
+	}
+	return 0;
+}
 
-	if (clock == new)
+/**
+ * timekeeping_notify - Install a new clock source
+ * @clock:		pointer to the clock source
+ *
+ * This function is called from clocksource.c after a new, better clock
+ * source has been registered. The caller holds the clocksource_mutex.
+ */
+void timekeeping_notify(struct clocksource *clock)
+{
+	if (timekeeper.clock == clock)
 		return;
+	stop_machine(change_clocksource, clock, NULL);
+	tick_clock_notify();
+}
 
-	clocksource_forward_now();
+#else /* GENERIC_TIME */
 
-	if (clocksource_enable(new))
-		return;
+static inline void timekeeping_forward_now(void) { }
 
-	new->raw_time = clock->raw_time;
-	old = clock;
-	clock = new;
-	clocksource_disable(old);
+/**
+ * ktime_get - get the monotonic time in ktime_t format
+ *
+ * returns the time in ktime_t format
+ */
+ktime_t ktime_get(void)
+{
+	struct timespec now;
 
-	clock->cycle_last = 0;
-	clock->cycle_last = clocksource_read(clock);
-	clock->error = 0;
-	clock->xtime_nsec = 0;
-	clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
+	ktime_get_ts(&now);
 
-	tick_clock_notify();
+	return timespec_to_ktime(now);
+}
+EXPORT_SYMBOL_GPL(ktime_get);
 
-	/*
-	 * We're holding xtime lock and waking up klogd would deadlock
-	 * us on enqueue.  So no printing!
-	printk(KERN_INFO "Time: %s clocksource has been installed.\n",
-	       clock->name);
-	 */
+/**
+ * ktime_get_ts - get the monotonic clock in timespec format
+ * @ts:		pointer to timespec variable
+ *
+ * The function calculates the monotonic clock from the realtime
+ * clock and the wall_to_monotonic offset and stores the result
+ * in normalized timespec format in the variable pointed to by @ts.
+ */
+void ktime_get_ts(struct timespec *ts)
+{
+	struct timespec tomono;
+	unsigned long seq;
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		getnstimeofday(ts);
+		tomono = wall_to_monotonic;
+
+	} while (read_seqretry(&xtime_lock, seq));
+
+	set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec,
+				ts->tv_nsec + tomono.tv_nsec);
 }
-#else
-static inline void clocksource_forward_now(void) { }
-static inline void change_clocksource(void) { }
-#endif
+EXPORT_SYMBOL_GPL(ktime_get_ts);
+
+#endif /* !GENERIC_TIME */
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ *
+ * returns the time in ktime_t format
+ */
+ktime_t ktime_get_real(void)
+{
+	struct timespec now;
+
+	getnstimeofday(&now);
+
+	return timespec_to_ktime(now);
+}
+EXPORT_SYMBOL_GPL(ktime_get_real);
 
 /**
  * getrawmonotonic - Returns the raw monotonic time in a timespec
@@ -236,21 +455,11 @@ void getrawmonotonic(struct timespec *ts)
 {
 	unsigned long seq;
 	s64 nsecs;
-	cycle_t cycle_now, cycle_delta;
 
 	do {
 		seq = read_seqbegin(&xtime_lock);
-
-		/* read clocksource: */
-		cycle_now = clocksource_read(clock);
-
-		/* calculate the delta since the last update_wall_time: */
-		cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
-
-		/* convert to nanoseconds: */
-		nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
-
-		*ts = clock->raw_time;
+		nsecs = timekeeping_get_ns_raw();
+		*ts = raw_time;
 
 	} while (read_seqretry(&xtime_lock, seq));
 
@@ -270,7 +479,7 @@ int timekeeping_valid_for_hres(void)
 	do {
 		seq = read_seqbegin(&xtime_lock);
 
-		ret = clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
+		ret = timekeeper.clock->flags & CLOCK_SOURCE_VALID_FOR_HRES;
 
 	} while (read_seqretry(&xtime_lock, seq));
 
@@ -278,17 +487,33 @@ int timekeeping_valid_for_hres(void)
 }
 
 /**
- * read_persistent_clock -  Return time in seconds from the persistent clock.
+ * read_persistent_clock -  Return time from the persistent clock.
  *
  * Weak dummy function for arches that do not yet support it.
- * Returns seconds from epoch using the battery backed persistent clock.
- * Returns zero if unsupported.
+ * Reads the time from the battery backed persistent clock.
+ * Returns a timespec with tv_sec=0 and tv_nsec=0 if unsupported.
  *
  *  XXX - Do be sure to remove it once all arches implement it.
  */
-unsigned long __attribute__((weak)) read_persistent_clock(void)
+void __attribute__((weak)) read_persistent_clock(struct timespec *ts)
 {
-	return 0;
+	ts->tv_sec = 0;
+	ts->tv_nsec = 0;
+}
+
+/**
+ * read_boot_clock -  Return time of the system start.
+ *
+ * Weak dummy function for arches that do not yet support it.
+ * Function to read the exact time the system has been started.
+ * Returns a timespec with tv_sec=0 and tv_nsec=0 if unsupported.
+ *
+ *  XXX - Do be sure to remove it once all arches implement it.
+ */
+void __attribute__((weak)) read_boot_clock(struct timespec *ts)
+{
+	ts->tv_sec = 0;
+	ts->tv_nsec = 0;
 }
 
 /*
@@ -296,29 +521,40 @@ unsigned long __attribute__((weak)) read_persistent_clock(void)
  */
 void __init timekeeping_init(void)
 {
+	struct clocksource *clock;
 	unsigned long flags;
-	unsigned long sec = read_persistent_clock();
+	struct timespec now, boot;
+
+	read_persistent_clock(&now);
+	read_boot_clock(&boot);
 
 	write_seqlock_irqsave(&xtime_lock, flags);
 
 	ntp_init();
 
-	clock = clocksource_get_next();
-	clocksource_enable(clock);
-	clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
-	clock->cycle_last = clocksource_read(clock);
-
-	xtime.tv_sec = sec;
-	xtime.tv_nsec = 0;
+	clock = clocksource_default_clock();
+	if (clock->enable)
+		clock->enable(clock);
+	timekeeper_setup_internals(clock);
+
+	xtime.tv_sec = now.tv_sec;
+	xtime.tv_nsec = now.tv_nsec;
+	raw_time.tv_sec = 0;
+	raw_time.tv_nsec = 0;
+	if (boot.tv_sec == 0 && boot.tv_nsec == 0) {
+		boot.tv_sec = xtime.tv_sec;
+		boot.tv_nsec = xtime.tv_nsec;
+	}
 	set_normalized_timespec(&wall_to_monotonic,
-		-xtime.tv_sec, -xtime.tv_nsec);
+				-boot.tv_sec, -boot.tv_nsec);
 	update_xtime_cache(0);
-	total_sleep_time = 0;
+	total_sleep_time.tv_sec = 0;
+	total_sleep_time.tv_nsec = 0;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 }
 
 /* time in seconds when suspend began */
-static unsigned long timekeeping_suspend_time;
+static struct timespec timekeeping_suspend_time;
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
@@ -331,24 +567,24 @@ static unsigned long timekeeping_suspend_time;
 static int timekeeping_resume(struct sys_device *dev)
 {
 	unsigned long flags;
-	unsigned long now = read_persistent_clock();
+	struct timespec ts;
+
+	read_persistent_clock(&ts);
 
 	clocksource_resume();
 
 	write_seqlock_irqsave(&xtime_lock, flags);
 
-	if (now && (now > timekeeping_suspend_time)) {
-		unsigned long sleep_length = now - timekeeping_suspend_time;
-
-		xtime.tv_sec += sleep_length;
-		wall_to_monotonic.tv_sec -= sleep_length;
-		total_sleep_time += sleep_length;
+	if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) {
+		ts = timespec_sub(ts, timekeeping_suspend_time);
+		xtime = timespec_add_safe(xtime, ts);
+		wall_to_monotonic = timespec_sub(wall_to_monotonic, ts);
+		total_sleep_time = timespec_add_safe(total_sleep_time, ts);
 	}
 	update_xtime_cache(0);
 	/* re-base the last cycle value */
-	clock->cycle_last = 0;
-	clock->cycle_last = clocksource_read(clock);
-	clock->error = 0;
+	timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock);
+	timekeeper.ntp_error = 0;
 	timekeeping_suspended = 0;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -366,10 +602,10 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
 {
 	unsigned long flags;
 
-	timekeeping_suspend_time = read_persistent_clock();
+	read_persistent_clock(&timekeeping_suspend_time);
 
 	write_seqlock_irqsave(&xtime_lock, flags);
-	clocksource_forward_now();
+	timekeeping_forward_now();
 	timekeeping_suspended = 1;
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
@@ -404,7 +640,7 @@ device_initcall(timekeeping_init_device);
  * If the error is already larger, we look ahead even further
  * to compensate for late or lost adjustments.
  */
-static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
+static __always_inline int timekeeping_bigadjust(s64 error, s64 *interval,
 						 s64 *offset)
 {
 	s64 tick_error, i;
@@ -420,7 +656,7 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
 	 * here.  This is tuned so that an error of about 1 msec is adjusted
 	 * within about 1 sec (or 2^20 nsec in 2^SHIFT_HZ ticks).
 	 */
-	error2 = clock->error >> (NTP_SCALE_SHIFT + 22 - 2 * SHIFT_HZ);
+	error2 = timekeeper.ntp_error >> (NTP_SCALE_SHIFT + 22 - 2 * SHIFT_HZ);
 	error2 = abs(error2);
 	for (look_ahead = 0; error2 > 0; look_ahead++)
 		error2 >>= 2;
@@ -429,8 +665,8 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
 	 * Now calculate the error in (1 << look_ahead) ticks, but first
 	 * remove the single look ahead already included in the error.
 	 */
-	tick_error = tick_length >> (NTP_SCALE_SHIFT - clock->shift + 1);
-	tick_error -= clock->xtime_interval >> 1;
+	tick_error = tick_length >> (timekeeper.ntp_error_shift + 1);
+	tick_error -= timekeeper.xtime_interval >> 1;
 	error = ((error - tick_error) >> look_ahead) + tick_error;
 
 	/* Finally calculate the adjustment shift value.  */
@@ -455,18 +691,18 @@ static __always_inline int clocksource_bigadjust(s64 error, s64 *interval,
  * this is optimized for the most common adjustments of -1,0,1,
  * for other values we can do a bit more work.
  */
-static void clocksource_adjust(s64 offset)
+static void timekeeping_adjust(s64 offset)
 {
-	s64 error, interval = clock->cycle_interval;
+	s64 error, interval = timekeeper.cycle_interval;
 	int adj;
 
-	error = clock->error >> (NTP_SCALE_SHIFT - clock->shift - 1);
+	error = timekeeper.ntp_error >> (timekeeper.ntp_error_shift - 1);
 	if (error > interval) {
 		error >>= 2;
 		if (likely(error <= interval))
 			adj = 1;
 		else
-			adj = clocksource_bigadjust(error, &interval, &offset);
+			adj = timekeeping_bigadjust(error, &interval, &offset);
 	} else if (error < -interval) {
 		error >>= 2;
 		if (likely(error >= -interval)) {
@@ -474,15 +710,15 @@ static void clocksource_adjust(s64 offset)
 			interval = -interval;
 			offset = -offset;
 		} else
-			adj = clocksource_bigadjust(error, &interval, &offset);
+			adj = timekeeping_bigadjust(error, &interval, &offset);
 	} else
 		return;
 
-	clock->mult += adj;
-	clock->xtime_interval += interval;
-	clock->xtime_nsec -= offset;
-	clock->error -= (interval - offset) <<
-			(NTP_SCALE_SHIFT - clock->shift);
+	timekeeper.mult += adj;
+	timekeeper.xtime_interval += interval;
+	timekeeper.xtime_nsec -= offset;
+	timekeeper.ntp_error -= (interval - offset) <<
+				timekeeper.ntp_error_shift;
 }
 
 /**
@@ -492,53 +728,59 @@ static void clocksource_adjust(s64 offset)
  */
 void update_wall_time(void)
 {
+	struct clocksource *clock;
 	cycle_t offset;
+	u64 nsecs;
 
 	/* Make sure we're fully resumed: */
 	if (unlikely(timekeeping_suspended))
 		return;
 
+	clock = timekeeper.clock;
 #ifdef CONFIG_GENERIC_TIME
-	offset = (clocksource_read(clock) - clock->cycle_last) & clock->mask;
+	offset = (clock->read(clock) - clock->cycle_last) & clock->mask;
 #else
-	offset = clock->cycle_interval;
+	offset = timekeeper.cycle_interval;
 #endif
-	clock->xtime_nsec = (s64)xtime.tv_nsec << clock->shift;
+	timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift;
 
 	/* normally this loop will run just once, however in the
 	 * case of lost or late ticks, it will accumulate correctly.
 	 */
-	while (offset >= clock->cycle_interval) {
+	while (offset >= timekeeper.cycle_interval) {
+		u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift;
+
 		/* accumulate one interval */
-		offset -= clock->cycle_interval;
-		clock->cycle_last += clock->cycle_interval;
+		offset -= timekeeper.cycle_interval;
+		clock->cycle_last += timekeeper.cycle_interval;
 
-		clock->xtime_nsec += clock->xtime_interval;
-		if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
-			clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
+		timekeeper.xtime_nsec += timekeeper.xtime_interval;
+		if (timekeeper.xtime_nsec >= nsecps) {
+			timekeeper.xtime_nsec -= nsecps;
 			xtime.tv_sec++;
 			second_overflow();
 		}
 
-		clock->raw_time.tv_nsec += clock->raw_interval;
-		if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) {
-			clock->raw_time.tv_nsec -= NSEC_PER_SEC;
-			clock->raw_time.tv_sec++;
+		raw_time.tv_nsec += timekeeper.raw_interval;
+		if (raw_time.tv_nsec >= NSEC_PER_SEC) {
+			raw_time.tv_nsec -= NSEC_PER_SEC;
+			raw_time.tv_sec++;
 		}
 
 		/* accumulate error between NTP and clock interval */
-		clock->error += tick_length;
-		clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
+		timekeeper.ntp_error += tick_length;
+		timekeeper.ntp_error -= timekeeper.xtime_interval <<
+					timekeeper.ntp_error_shift;
 	}
 
 	/* correct the clock when NTP error is too big */
-	clocksource_adjust(offset);
+	timekeeping_adjust(offset);
 
 	/*
 	 * Since in the loop above, we accumulate any amount of time
 	 * in xtime_nsec over a second into xtime.tv_sec, its possible for
 	 * xtime_nsec to be fairly small after the loop. Further, if we're
-	 * slightly speeding the clocksource up in clocksource_adjust(),
+	 * slightly speeding the clocksource up in timekeeping_adjust(),
 	 * its possible the required corrective factor to xtime_nsec could
 	 * cause it to underflow.
 	 *
@@ -550,24 +792,25 @@ void update_wall_time(void)
 	 * We'll correct this error next time through this function, when
 	 * xtime_nsec is not as small.
 	 */
-	if (unlikely((s64)clock->xtime_nsec < 0)) {
-		s64 neg = -(s64)clock->xtime_nsec;
-		clock->xtime_nsec = 0;
-		clock->error += neg << (NTP_SCALE_SHIFT - clock->shift);
+	if (unlikely((s64)timekeeper.xtime_nsec < 0)) {
+		s64 neg = -(s64)timekeeper.xtime_nsec;
+		timekeeper.xtime_nsec = 0;
+		timekeeper.ntp_error += neg << timekeeper.ntp_error_shift;
 	}
 
 	/* store full nanoseconds into xtime after rounding it up and
 	 * add the remainder to the error difference.
 	 */
-	xtime.tv_nsec = ((s64)clock->xtime_nsec >> clock->shift) + 1;
-	clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
-	clock->error += clock->xtime_nsec << (NTP_SCALE_SHIFT - clock->shift);
+	xtime.tv_nsec =	((s64) timekeeper.xtime_nsec >> timekeeper.shift) + 1;
+	timekeeper.xtime_nsec -= (s64) xtime.tv_nsec << timekeeper.shift;
+	timekeeper.ntp_error +=	timekeeper.xtime_nsec <<
+				timekeeper.ntp_error_shift;
 
-	update_xtime_cache(cyc2ns(clock, offset));
+	nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift);
+	update_xtime_cache(nsecs);
 
 	/* check to see if there is a new clocksource to use */
-	change_clocksource();
-	update_vsyscall(&xtime, clock);
+	update_vsyscall(&xtime, timekeeper.clock);
 }
 
 /**
@@ -583,9 +826,12 @@ void update_wall_time(void)
  */
 void getboottime(struct timespec *ts)
 {
-	set_normalized_timespec(ts,
-		- (wall_to_monotonic.tv_sec + total_sleep_time),
-		- wall_to_monotonic.tv_nsec);
+	struct timespec boottime = {
+		.tv_sec = wall_to_monotonic.tv_sec + total_sleep_time.tv_sec,
+		.tv_nsec = wall_to_monotonic.tv_nsec + total_sleep_time.tv_nsec
+	};
+
+	set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec);
 }
 
 /**
@@ -594,7 +840,7 @@ void getboottime(struct timespec *ts)
  */
 void monotonic_to_bootbased(struct timespec *ts)
 {
-	ts->tv_sec += total_sleep_time;
+	*ts = timespec_add_safe(*ts, total_sleep_time);
 }
 
 unsigned long get_seconds(void)
@@ -603,6 +849,10 @@ unsigned long get_seconds(void)
 }
 EXPORT_SYMBOL(get_seconds);
 
+struct timespec __current_kernel_time(void)
+{
+	return xtime_cache;
+}
 
 struct timespec current_kernel_time(void)
 {
@@ -618,3 +868,20 @@ struct timespec current_kernel_time(void)
 	return now;
 }
 EXPORT_SYMBOL(current_kernel_time);
+
+struct timespec get_monotonic_coarse(void)
+{
+	struct timespec now, mono;
+	unsigned long seq;
+
+	do {
+		seq = read_seqbegin(&xtime_lock);
+
+		now = xtime_cache;
+		mono = wall_to_monotonic;
+	} while (read_seqretry(&xtime_lock, seq));
+
+	set_normalized_timespec(&now, now.tv_sec + mono.tv_sec,
+				now.tv_nsec + mono.tv_nsec);
+	return now;
+}
diff --git a/kernel/timer.c b/kernel/timer.c
index a3d25f4..811e5c3 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -37,7 +37,7 @@
 #include <linux/delay.h>
 #include <linux/tick.h>
 #include <linux/kallsyms.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <linux/sched.h>
 
 #include <asm/uaccess.h>
@@ -72,6 +72,7 @@ struct tvec_base {
 	spinlock_t lock;
 	struct timer_list *running_timer;
 	unsigned long timer_jiffies;
+	unsigned long next_timer;
 	struct tvec_root tv1;
 	struct tvec tv2;
 	struct tvec tv3;
@@ -622,6 +623,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
 
 	if (timer_pending(timer)) {
 		detach_timer(timer, 0);
+		if (timer->expires == base->next_timer &&
+		    !tbase_get_deferrable(timer->base))
+			base->next_timer = base->timer_jiffies;
 		ret = 1;
 	} else {
 		if (pending_only)
@@ -663,6 +667,9 @@ __mod_timer(struct timer_list *timer, unsigned long expires,
 	}
 
 	timer->expires = expires;
+	if (time_before(timer->expires, base->next_timer) &&
+	    !tbase_get_deferrable(timer->base))
+		base->next_timer = timer->expires;
 	internal_add_timer(base, timer);
 
 out_unlock:
@@ -781,6 +788,9 @@ void add_timer_on(struct timer_list *timer, int cpu)
 	spin_lock_irqsave(&base->lock, flags);
 	timer_set_base(timer, base);
 	debug_timer_activate(timer);
+	if (time_before(timer->expires, base->next_timer) &&
+	    !tbase_get_deferrable(timer->base))
+		base->next_timer = timer->expires;
 	internal_add_timer(base, timer);
 	/*
 	 * Check whether the other CPU is idle and needs to be
@@ -817,6 +827,9 @@ int del_timer(struct timer_list *timer)
 		base = lock_timer_base(timer, &flags);
 		if (timer_pending(timer)) {
 			detach_timer(timer, 1);
+			if (timer->expires == base->next_timer &&
+			    !tbase_get_deferrable(timer->base))
+				base->next_timer = base->timer_jiffies;
 			ret = 1;
 		}
 		spin_unlock_irqrestore(&base->lock, flags);
@@ -850,6 +863,9 @@ int try_to_del_timer_sync(struct timer_list *timer)
 	ret = 0;
 	if (timer_pending(timer)) {
 		detach_timer(timer, 1);
+		if (timer->expires == base->next_timer &&
+		    !tbase_get_deferrable(timer->base))
+			base->next_timer = base->timer_jiffies;
 		ret = 1;
 	}
 out:
@@ -1007,8 +1023,8 @@ static inline void __run_timers(struct tvec_base *base)
 #ifdef CONFIG_NO_HZ
 /*
  * Find out when the next timer event is due to happen. This
- * is used on S/390 to stop all activity when a cpus is idle.
- * This functions needs to be called disabled.
+ * is used on S/390 to stop all activity when a CPU is idle.
+ * This function needs to be called with interrupts disabled.
  */
 static unsigned long __next_timer_interrupt(struct tvec_base *base)
 {
@@ -1134,7 +1150,9 @@ unsigned long get_next_timer_interrupt(unsigned long now)
 	unsigned long expires;
 
 	spin_lock(&base->lock);
-	expires = __next_timer_interrupt(base);
+	if (time_before_eq(base->next_timer, base->timer_jiffies))
+		base->next_timer = __next_timer_interrupt(base);
+	expires = base->next_timer;
 	spin_unlock(&base->lock);
 
 	if (time_before_eq(expires, now))
@@ -1169,7 +1187,7 @@ static void run_timer_softirq(struct softirq_action *h)
 {
 	struct tvec_base *base = __get_cpu_var(tvec_bases);
 
-	perf_counter_do_pending();
+	perf_event_do_pending();
 
 	hrtimer_run_pending();
 
@@ -1522,6 +1540,7 @@ static int __cpuinit init_timers_cpu(int cpu)
 		INIT_LIST_HEAD(base->tv1.vec + j);
 
 	base->timer_jiffies = jiffies;
+	base->next_timer = base->timer_jiffies;
 	return 0;
 }
 
@@ -1534,6 +1553,9 @@ static void migrate_timer_list(struct tvec_base *new_base, struct list_head *hea
 		timer = list_first_entry(head, struct timer_list, entry);
 		detach_timer(timer, 0);
 		timer_set_base(timer, new_base);
+		if (time_before(timer->expires, new_base->next_timer) &&
+		    !tbase_get_deferrable(timer->base))
+			new_base->next_timer = timer->expires;
 		internal_add_timer(new_base, timer);
 	}
 }
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 1ea0d12..e716346 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -11,12 +11,18 @@ config NOP_TRACER
 
 config HAVE_FTRACE_NMI_ENTER
 	bool
+	help
+	  See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FUNCTION_TRACER
 	bool
+	help
+	  See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FUNCTION_GRAPH_TRACER
 	bool
+	help
+	  See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FUNCTION_GRAPH_FP_TEST
 	bool
@@ -28,21 +34,25 @@ config HAVE_FUNCTION_GRAPH_FP_TEST
 config HAVE_FUNCTION_TRACE_MCOUNT_TEST
 	bool
 	help
-	 This gets selected when the arch tests the function_trace_stop
-	 variable at the mcount call site. Otherwise, this variable
-	 is tested by the called function.
+	  See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_DYNAMIC_FTRACE
 	bool
+	help
+	  See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_FTRACE_MCOUNT_RECORD
 	bool
+	help
+	  See Documentation/trace/ftrace-implementation.txt
 
 config HAVE_HW_BRANCH_TRACER
 	bool
 
 config HAVE_SYSCALL_TRACEPOINTS
 	bool
+	help
+	  See Documentation/trace/ftrace-implementation.txt
 
 config TRACER_MAX_TRACE
 	bool
@@ -469,6 +479,18 @@ config FTRACE_STARTUP_TEST
 	  functioning properly. It will do tests on all the configured
 	  tracers of ftrace.
 
+config EVENT_TRACE_TEST_SYSCALLS
+	bool "Run selftest on syscall events"
+	depends on FTRACE_STARTUP_TEST
+	help
+	 This option will also enable testing every syscall event.
+	 It only enables the event and disables it and runs various loads
+	 with the event enabled. This adds a bit more time for kernel boot
+	 up since it runs this on every system call defined.
+
+	 TBD - enable a way to actually call the syscalls as we test their
+	       events
+
 config MMIOTRACE
 	bool "Memory mapped IO tracing"
 	depends on HAVE_MMIOTRACE_SUPPORT && PCI
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 844164d..26f03ac 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -42,7 +42,6 @@ obj-$(CONFIG_BOOT_TRACER) += trace_boot.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += trace_functions_graph.o
 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
@@ -54,5 +53,6 @@ obj-$(CONFIG_EVENT_TRACING) += trace_export.o
 obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
 obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
 obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
+obj-$(CONFIG_EVENT_TRACING) += power-traces.o
 
 libftrace-y := ftrace.o
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8c804e2..c71e91b 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1323,11 +1323,10 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
 
 enum {
 	FTRACE_ITER_FILTER	= (1 << 0),
-	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),
+	FTRACE_ITER_NOTRACE	= (1 << 1),
+	FTRACE_ITER_FAILURES	= (1 << 2),
+	FTRACE_ITER_PRINTALL	= (1 << 3),
+	FTRACE_ITER_HASH	= (1 << 4),
 };
 
 #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
@@ -1337,8 +1336,7 @@ struct ftrace_iterator {
 	int			hidx;
 	int			idx;
 	unsigned		flags;
-	unsigned char		buffer[FTRACE_BUFF_MAX+1];
-	unsigned		buffer_idx;
+	struct trace_parser	parser;
 };
 
 static void *
@@ -1407,7 +1405,7 @@ static int t_hash_show(struct seq_file *m, void *v)
 	if (rec->ops->print)
 		return rec->ops->print(m, rec->ip, rec->ops, rec->data);
 
-	seq_printf(m, "%pf:%pf", (void *)rec->ip, (void *)rec->ops->func);
+	seq_printf(m, "%ps:%ps", (void *)rec->ip, (void *)rec->ops->func);
 
 	if (rec->data)
 		seq_printf(m, ":%p", rec->data);
@@ -1517,7 +1515,7 @@ static int t_show(struct seq_file *m, void *v)
 	if (!rec)
 		return 0;
 
-	seq_printf(m, "%pf\n", (void *)rec->ip);
+	seq_printf(m, "%ps\n", (void *)rec->ip);
 
 	return 0;
 }
@@ -1604,6 +1602,11 @@ ftrace_regex_open(struct inode *inode, struct file *file, int enable)
 	if (!iter)
 		return -ENOMEM;
 
+	if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) {
+		kfree(iter);
+		return -ENOMEM;
+	}
+
 	mutex_lock(&ftrace_regex_lock);
 	if ((file->f_mode & FMODE_WRITE) &&
 	    (file->f_flags & O_TRUNC))
@@ -2059,9 +2062,9 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
 	int i, len = 0;
 	char *search;
 
-	if (glob && (strcmp(glob, "*") || !strlen(glob)))
+	if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
 		glob = NULL;
-	else {
+	else if (glob) {
 		int not;
 
 		type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
@@ -2196,9 +2199,8 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
 		   size_t cnt, loff_t *ppos, int enable)
 {
 	struct ftrace_iterator *iter;
-	char ch;
-	size_t read = 0;
-	ssize_t ret;
+	struct trace_parser *parser;
+	ssize_t ret, read;
 
 	if (!cnt || cnt < 0)
 		return 0;
@@ -2211,72 +2213,23 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
 	} else
 		iter = file->private_data;
 
-	if (!*ppos) {
-		iter->flags &= ~FTRACE_ITER_CONT;
-		iter->buffer_idx = 0;
-	}
+	parser = &iter->parser;
+	read = trace_get_user(parser, ubuf, cnt, ppos);
 
-	ret = get_user(ch, ubuf++);
-	if (ret)
-		goto out;
-	read++;
-	cnt--;
-
-	/*
-	 * If the parser haven't finished with the last write,
-	 * continue reading the user input without skipping spaces.
-	 */
-	if (!(iter->flags & FTRACE_ITER_CONT)) {
-		/* skip white space */
-		while (cnt && isspace(ch)) {
-			ret = get_user(ch, ubuf++);
-			if (ret)
-				goto out;
-			read++;
-			cnt--;
-		}
-
-		/* only spaces were written */
-		if (isspace(ch)) {
-			*ppos += read;
-			ret = read;
-			goto out;
-		}
-
-		iter->buffer_idx = 0;
-	}
-
-	while (cnt && !isspace(ch)) {
-		if (iter->buffer_idx < FTRACE_BUFF_MAX)
-			iter->buffer[iter->buffer_idx++] = ch;
-		else {
-			ret = -EINVAL;
-			goto out;
-		}
-		ret = get_user(ch, ubuf++);
+	if (trace_parser_loaded(parser) &&
+	    !trace_parser_cont(parser)) {
+		ret = ftrace_process_regex(parser->buffer,
+					   parser->idx, enable);
 		if (ret)
 			goto out;
-		read++;
-		cnt--;
-	}
 
-	if (isspace(ch)) {
-		iter->buffer[iter->buffer_idx] = 0;
-		ret = ftrace_process_regex(iter->buffer,
-					   iter->buffer_idx, enable);
-		if (ret)
-			goto out;
-		iter->buffer_idx = 0;
-	} else {
-		iter->flags |= FTRACE_ITER_CONT;
-		iter->buffer[iter->buffer_idx++] = ch;
+		trace_parser_clear(parser);
 	}
 
-	*ppos += read;
 	ret = read;
- out:
-	mutex_unlock(&ftrace_regex_lock);
 
+	mutex_unlock(&ftrace_regex_lock);
+out:
 	return ret;
 }
 
@@ -2381,6 +2334,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
 {
 	struct seq_file *m = (struct seq_file *)file->private_data;
 	struct ftrace_iterator *iter;
+	struct trace_parser *parser;
 
 	mutex_lock(&ftrace_regex_lock);
 	if (file->f_mode & FMODE_READ) {
@@ -2390,9 +2344,10 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
 	} else
 		iter = file->private_data;
 
-	if (iter->buffer_idx) {
-		iter->buffer[iter->buffer_idx] = 0;
-		ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
+	parser = &iter->parser;
+	if (trace_parser_loaded(parser)) {
+		parser->buffer[parser->idx] = 0;
+		ftrace_match_records(parser->buffer, parser->idx, enable);
 	}
 
 	mutex_lock(&ftrace_lock);
@@ -2400,7 +2355,9 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
 		ftrace_run_update_code(FTRACE_ENABLE_CALLS);
 	mutex_unlock(&ftrace_lock);
 
+	trace_parser_put(parser);
 	kfree(iter);
+
 	mutex_unlock(&ftrace_regex_lock);
 	return 0;
 }
@@ -2457,11 +2414,9 @@ unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
 static void *
 __g_next(struct seq_file *m, loff_t *pos)
 {
-	unsigned long *array = m->private;
-
 	if (*pos >= ftrace_graph_count)
 		return NULL;
-	return &array[*pos];
+	return &ftrace_graph_funcs[*pos];
 }
 
 static void *
@@ -2499,7 +2454,7 @@ static int g_show(struct seq_file *m, void *v)
 		return 0;
 	}
 
-	seq_printf(m, "%pf\n", v);
+	seq_printf(m, "%ps\n", (void *)*ptr);
 
 	return 0;
 }
@@ -2525,16 +2480,10 @@ ftrace_graph_open(struct inode *inode, struct file *file)
 		ftrace_graph_count = 0;
 		memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
 	}
+	mutex_unlock(&graph_lock);
 
-	if (file->f_mode & FMODE_READ) {
+	if (file->f_mode & FMODE_READ)
 		ret = seq_open(file, &ftrace_graph_seq_ops);
-		if (!ret) {
-			struct seq_file *m = file->private_data;
-			m->private = ftrace_graph_funcs;
-		}
-	} else
-		file->private_data = ftrace_graph_funcs;
-	mutex_unlock(&graph_lock);
 
 	return ret;
 }
@@ -2602,12 +2551,9 @@ static ssize_t
 ftrace_graph_write(struct file *file, const char __user *ubuf,
 		   size_t cnt, loff_t *ppos)
 {
-	unsigned char buffer[FTRACE_BUFF_MAX+1];
-	unsigned long *array;
+	struct trace_parser parser;
 	size_t read = 0;
 	ssize_t ret;
-	int index = 0;
-	char ch;
 
 	if (!cnt || cnt < 0)
 		return 0;
@@ -2619,57 +2565,26 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
 		goto out;
 	}
 
-	if (file->f_mode & FMODE_READ) {
-		struct seq_file *m = file->private_data;
-		array = m->private;
-	} else
-		array = file->private_data;
-
-	ret = get_user(ch, ubuf++);
-	if (ret)
+	if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) {
+		ret = -ENOMEM;
 		goto out;
-	read++;
-	cnt--;
-
-	/* skip white space */
-	while (cnt && isspace(ch)) {
-		ret = get_user(ch, ubuf++);
-		if (ret)
-			goto out;
-		read++;
-		cnt--;
 	}
 
-	if (isspace(ch)) {
-		*ppos += read;
-		ret = read;
-		goto out;
-	}
+	read = trace_get_user(&parser, ubuf, cnt, ppos);
 
-	while (cnt && !isspace(ch)) {
-		if (index < FTRACE_BUFF_MAX)
-			buffer[index++] = ch;
-		else {
-			ret = -EINVAL;
-			goto out;
-		}
-		ret = get_user(ch, ubuf++);
+	if (trace_parser_loaded((&parser))) {
+		parser.buffer[parser.idx] = 0;
+
+		/* we allow only one expression at a time */
+		ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
+					parser.buffer);
 		if (ret)
 			goto out;
-		read++;
-		cnt--;
 	}
-	buffer[index] = 0;
-
-	/* we allow only one expression at a time */
-	ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
-	if (ret)
-		goto out;
-
-	file->f_pos += read;
 
 	ret = read;
  out:
+	trace_parser_put(&parser);
 	mutex_unlock(&graph_lock);
 
 	return ret;
diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c
new file mode 100644
index 0000000..e06c6e3
--- /dev/null
+++ b/kernel/trace/power-traces.c
@@ -0,0 +1,20 @@
+/*
+ * Power trace points
+ *
+ * Copyright (C) 2009 Arjan van de Ven <arjan@linux.intel.com>
+ */
+
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/power.h>
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(power_start);
+EXPORT_TRACEPOINT_SYMBOL_GPL(power_end);
+EXPORT_TRACEPOINT_SYMBOL_GPL(power_frequency);
+
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 454e74e..d4ff019 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -201,8 +201,6 @@ int tracing_is_on(void)
 }
 EXPORT_SYMBOL_GPL(tracing_is_on);
 
-#include "trace.h"
-
 #define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array))
 #define RB_ALIGNMENT		4U
 #define RB_MAX_SMALL_DATA	(RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX)
@@ -701,8 +699,8 @@ static int rb_head_page_set(struct ring_buffer_per_cpu *cpu_buffer,
 
 	val &= ~RB_FLAG_MASK;
 
-	ret = (unsigned long)cmpxchg(&list->next,
-				     val | old_flag, val | new_flag);
+	ret = cmpxchg((unsigned long *)&list->next,
+		      val | old_flag, val | new_flag);
 
 	/* check if the reader took the page */
 	if ((ret & ~RB_FLAG_MASK) != val)
@@ -794,7 +792,7 @@ static int rb_head_page_replace(struct buffer_page *old,
 	val = *ptr & ~RB_FLAG_MASK;
 	val |= RB_PAGE_HEAD;
 
-	ret = cmpxchg(ptr, val, &new->list);
+	ret = cmpxchg(ptr, val, (unsigned long)&new->list);
 
 	return ret == val;
 }
@@ -2997,15 +2995,12 @@ static void rb_advance_iter(struct ring_buffer_iter *iter)
 }
 
 static struct ring_buffer_event *
-rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
+rb_buffer_peek(struct ring_buffer_per_cpu *cpu_buffer, u64 *ts)
 {
-	struct ring_buffer_per_cpu *cpu_buffer;
 	struct ring_buffer_event *event;
 	struct buffer_page *reader;
 	int nr_loops = 0;
 
-	cpu_buffer = buffer->buffers[cpu];
-
  again:
 	/*
 	 * We repeat when a timestamp is encountered. It is possible
@@ -3049,7 +3044,7 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
 	case RINGBUF_TYPE_DATA:
 		if (ts) {
 			*ts = cpu_buffer->read_stamp + event->time_delta;
-			ring_buffer_normalize_time_stamp(buffer,
+			ring_buffer_normalize_time_stamp(cpu_buffer->buffer,
 							 cpu_buffer->cpu, ts);
 		}
 		return event;
@@ -3168,7 +3163,7 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
 	local_irq_save(flags);
 	if (dolock)
 		spin_lock(&cpu_buffer->reader_lock);
-	event = rb_buffer_peek(buffer, cpu, ts);
+	event = rb_buffer_peek(cpu_buffer, ts);
 	if (event && event->type_len == RINGBUF_TYPE_PADDING)
 		rb_advance_reader(cpu_buffer);
 	if (dolock)
@@ -3237,7 +3232,7 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
 	if (dolock)
 		spin_lock(&cpu_buffer->reader_lock);
 
-	event = rb_buffer_peek(buffer, cpu, ts);
+	event = rb_buffer_peek(cpu_buffer, ts);
 	if (event)
 		rb_advance_reader(cpu_buffer);
 
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 5c75dee..a35925d 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -125,13 +125,13 @@ int ftrace_dump_on_oops;
 
 static int tracing_set_tracer(const char *buf);
 
-#define BOOTUP_TRACER_SIZE		100
-static char bootup_tracer_buf[BOOTUP_TRACER_SIZE] __initdata;
+#define MAX_TRACER_SIZE		100
+static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata;
 static char *default_bootup_tracer;
 
 static int __init set_ftrace(char *str)
 {
-	strncpy(bootup_tracer_buf, str, BOOTUP_TRACER_SIZE);
+	strncpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);
 	default_bootup_tracer = bootup_tracer_buf;
 	/* We are using ftrace early, expand it */
 	ring_buffer_expanded = 1;
@@ -242,13 +242,6 @@ static struct tracer		*trace_types __read_mostly;
 static struct tracer		*current_trace __read_mostly;
 
 /*
- * max_tracer_type_len is used to simplify the allocating of
- * buffers to read userspace tracer names. We keep track of
- * the longest tracer name registered.
- */
-static int			max_tracer_type_len;
-
-/*
  * trace_types_lock is used to protect the trace_types list.
  * This lock is also used to keep user access serialized.
  * Accesses from userspace will grab this lock while userspace
@@ -275,12 +268,18 @@ static DEFINE_SPINLOCK(tracing_start_lock);
  */
 void trace_wake_up(void)
 {
+	int cpu;
+
+	if (trace_flags & TRACE_ITER_BLOCK)
+		return;
 	/*
 	 * The runqueue_is_locked() can fail, but this is the best we
 	 * have for now:
 	 */
-	if (!(trace_flags & TRACE_ITER_BLOCK) && !runqueue_is_locked())
+	cpu = get_cpu();
+	if (!runqueue_is_locked(cpu))
 		wake_up(&trace_wait);
+	put_cpu();
 }
 
 static int __init set_buf_size(char *str)
@@ -339,6 +338,112 @@ static struct {
 
 int trace_clock_id;
 
+/*
+ * trace_parser_get_init - gets the buffer for trace parser
+ */
+int trace_parser_get_init(struct trace_parser *parser, int size)
+{
+	memset(parser, 0, sizeof(*parser));
+
+	parser->buffer = kmalloc(size, GFP_KERNEL);
+	if (!parser->buffer)
+		return 1;
+
+	parser->size = size;
+	return 0;
+}
+
+/*
+ * trace_parser_put - frees the buffer for trace parser
+ */
+void trace_parser_put(struct trace_parser *parser)
+{
+	kfree(parser->buffer);
+}
+
+/*
+ * trace_get_user - reads the user input string separated by  space
+ * (matched by isspace(ch))
+ *
+ * For each string found the 'struct trace_parser' is updated,
+ * and the function returns.
+ *
+ * Returns number of bytes read.
+ *
+ * See kernel/trace/trace.h for 'struct trace_parser' details.
+ */
+int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
+	size_t cnt, loff_t *ppos)
+{
+	char ch;
+	size_t read = 0;
+	ssize_t ret;
+
+	if (!*ppos)
+		trace_parser_clear(parser);
+
+	ret = get_user(ch, ubuf++);
+	if (ret)
+		goto out;
+
+	read++;
+	cnt--;
+
+	/*
+	 * The parser is not finished with the last write,
+	 * continue reading the user input without skipping spaces.
+	 */
+	if (!parser->cont) {
+		/* skip white space */
+		while (cnt && isspace(ch)) {
+			ret = get_user(ch, ubuf++);
+			if (ret)
+				goto out;
+			read++;
+			cnt--;
+		}
+
+		/* only spaces were written */
+		if (isspace(ch)) {
+			*ppos += read;
+			ret = read;
+			goto out;
+		}
+
+		parser->idx = 0;
+	}
+
+	/* read the non-space input */
+	while (cnt && !isspace(ch)) {
+		if (parser->idx < parser->size)
+			parser->buffer[parser->idx++] = ch;
+		else {
+			ret = -EINVAL;
+			goto out;
+		}
+		ret = get_user(ch, ubuf++);
+		if (ret)
+			goto out;
+		read++;
+		cnt--;
+	}
+
+	/* We either got finished input or we have to wait for another call. */
+	if (isspace(ch)) {
+		parser->buffer[parser->idx] = 0;
+		parser->cont = false;
+	} else {
+		parser->cont = true;
+		parser->buffer[parser->idx++] = ch;
+	}
+
+	*ppos += read;
+	ret = read;
+
+out:
+	return ret;
+}
+
 ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
 {
 	int len;
@@ -513,7 +618,6 @@ __releases(kernel_lock)
 __acquires(kernel_lock)
 {
 	struct tracer *t;
-	int len;
 	int ret = 0;
 
 	if (!type->name) {
@@ -521,6 +625,11 @@ __acquires(kernel_lock)
 		return -1;
 	}
 
+	if (strlen(type->name) > MAX_TRACER_SIZE) {
+		pr_info("Tracer has a name longer than %d\n", MAX_TRACER_SIZE);
+		return -1;
+	}
+
 	/*
 	 * When this gets called we hold the BKL which means that
 	 * preemption is disabled. Various trace selftests however
@@ -535,7 +644,7 @@ __acquires(kernel_lock)
 	for (t = trace_types; t; t = t->next) {
 		if (strcmp(type->name, t->name) == 0) {
 			/* already found */
-			pr_info("Trace %s already registered\n",
+			pr_info("Tracer %s already registered\n",
 				type->name);
 			ret = -1;
 			goto out;
@@ -586,9 +695,6 @@ __acquires(kernel_lock)
 
 	type->next = trace_types;
 	trace_types = type;
-	len = strlen(type->name);
-	if (len > max_tracer_type_len)
-		max_tracer_type_len = len;
 
  out:
 	tracing_selftest_running = false;
@@ -597,7 +703,7 @@ __acquires(kernel_lock)
 	if (ret || !default_bootup_tracer)
 		goto out_unlock;
 
-	if (strncmp(default_bootup_tracer, type->name, BOOTUP_TRACER_SIZE))
+	if (strncmp(default_bootup_tracer, type->name, MAX_TRACER_SIZE))
 		goto out_unlock;
 
 	printk(KERN_INFO "Starting tracer '%s'\n", type->name);
@@ -619,14 +725,13 @@ __acquires(kernel_lock)
 void unregister_tracer(struct tracer *type)
 {
 	struct tracer **t;
-	int len;
 
 	mutex_lock(&trace_types_lock);
 	for (t = &trace_types; *t; t = &(*t)->next) {
 		if (*t == type)
 			goto found;
 	}
-	pr_info("Trace %s not registered\n", type->name);
+	pr_info("Tracer %s not registered\n", type->name);
 	goto out;
 
  found:
@@ -639,17 +744,7 @@ void unregister_tracer(struct tracer *type)
 			current_trace->stop(&global_trace);
 		current_trace = &nop_trace;
 	}
-
-	if (strlen(type->name) != max_tracer_type_len)
-		goto out;
-
-	max_tracer_type_len = 0;
-	for (t = &trace_types; *t; t = &(*t)->next) {
-		len = strlen((*t)->name);
-		if (len > max_tracer_type_len)
-			max_tracer_type_len = len;
-	}
- out:
+out:
 	mutex_unlock(&trace_types_lock);
 }
 
@@ -719,6 +814,11 @@ static void trace_init_cmdlines(void)
 	cmdline_idx = 0;
 }
 
+int is_tracing_stopped(void)
+{
+	return trace_stop_count;
+}
+
 /**
  * ftrace_off_permanent - disable all ftrace code permanently
  *
@@ -886,7 +986,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
 
 	entry->preempt_count		= pc & 0xff;
 	entry->pid			= (tsk) ? tsk->pid : 0;
-	entry->tgid			= (tsk) ? tsk->tgid : 0;
+	entry->lock_depth		= (tsk) ? tsk->lock_depth : 0;
 	entry->flags =
 #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
 		(irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
@@ -1068,6 +1168,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
 		return;
 	entry	= ring_buffer_event_data(event);
 
+	entry->tgid		= current->tgid;
 	memset(&entry->caller, 0, sizeof(entry->caller));
 
 	trace.nr_entries	= 0;
@@ -1094,6 +1195,7 @@ ftrace_trace_special(void *__tr,
 		     unsigned long arg1, unsigned long arg2, unsigned long arg3,
 		     int pc)
 {
+	struct ftrace_event_call *call = &event_special;
 	struct ring_buffer_event *event;
 	struct trace_array *tr = __tr;
 	struct ring_buffer *buffer = tr->buffer;
@@ -1107,7 +1209,9 @@ ftrace_trace_special(void *__tr,
 	entry->arg1			= arg1;
 	entry->arg2			= arg2;
 	entry->arg3			= arg3;
-	trace_buffer_unlock_commit(buffer, event, 0, pc);
+
+	if (!filter_check_discard(call, entry, buffer, event))
+		trace_buffer_unlock_commit(buffer, event, 0, pc);
 }
 
 void
@@ -1530,10 +1634,10 @@ static void print_lat_help_header(struct seq_file *m)
 	seq_puts(m, "#                | / _----=> need-resched    \n");
 	seq_puts(m, "#                || / _---=> hardirq/softirq \n");
 	seq_puts(m, "#                ||| / _--=> preempt-depth   \n");
-	seq_puts(m, "#                |||| /                      \n");
-	seq_puts(m, "#                |||||     delay             \n");
-	seq_puts(m, "#  cmd     pid   ||||| time  |   caller      \n");
-	seq_puts(m, "#     \\   /      |||||   \\   |   /           \n");
+	seq_puts(m, "#                |||| /_--=> lock-depth       \n");
+	seq_puts(m, "#                |||||/     delay             \n");
+	seq_puts(m, "#  cmd     pid   |||||| time  |   caller      \n");
+	seq_puts(m, "#     \\   /      ||||||   \\   |   /           \n");
 }
 
 static void print_func_help_header(struct seq_file *m)
@@ -2489,7 +2593,7 @@ static ssize_t
 tracing_set_trace_read(struct file *filp, char __user *ubuf,
 		       size_t cnt, loff_t *ppos)
 {
-	char buf[max_tracer_type_len+2];
+	char buf[MAX_TRACER_SIZE+2];
 	int r;
 
 	mutex_lock(&trace_types_lock);
@@ -2639,15 +2743,15 @@ static ssize_t
 tracing_set_trace_write(struct file *filp, const char __user *ubuf,
 			size_t cnt, loff_t *ppos)
 {
-	char buf[max_tracer_type_len+1];
+	char buf[MAX_TRACER_SIZE+1];
 	int i;
 	size_t ret;
 	int err;
 
 	ret = cnt;
 
-	if (cnt > max_tracer_type_len)
-		cnt = max_tracer_type_len;
+	if (cnt > MAX_TRACER_SIZE)
+		cnt = MAX_TRACER_SIZE;
 
 	if (copy_from_user(&buf, ubuf, cnt))
 		return -EFAULT;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index fa1dccb..405cb85 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -7,10 +7,10 @@
 #include <linux/clocksource.h>
 #include <linux/ring_buffer.h>
 #include <linux/mmiotrace.h>
+#include <linux/tracepoint.h>
 #include <linux/ftrace.h>
 #include <trace/boot.h>
 #include <linux/kmemtrace.h>
-#include <trace/power.h>
 
 #include <linux/trace_seq.h>
 #include <linux/ftrace_event.h>
@@ -36,163 +36,59 @@ enum trace_type {
 	TRACE_HW_BRANCHES,
 	TRACE_KMEM_ALLOC,
 	TRACE_KMEM_FREE,
-	TRACE_POWER,
 	TRACE_BLK,
 
 	__TRACE_LAST_TYPE,
 };
 
-/*
- * Function trace entry - function address and parent function addres:
- */
-struct ftrace_entry {
-	struct trace_entry	ent;
-	unsigned long		ip;
-	unsigned long		parent_ip;
-};
-
-/* Function call entry */
-struct ftrace_graph_ent_entry {
-	struct trace_entry		ent;
-	struct ftrace_graph_ent		graph_ent;
+enum kmemtrace_type_id {
+	KMEMTRACE_TYPE_KMALLOC = 0,	/* kmalloc() or kfree(). */
+	KMEMTRACE_TYPE_CACHE,		/* kmem_cache_*(). */
+	KMEMTRACE_TYPE_PAGES,		/* __get_free_pages() and friends. */
 };
 
-/* Function return entry */
-struct ftrace_graph_ret_entry {
-	struct trace_entry		ent;
-	struct ftrace_graph_ret		ret;
-};
 extern struct tracer boot_tracer;
 
-/*
- * Context switch trace entry - which task (and prio) we switched from/to:
- */
-struct ctx_switch_entry {
-	struct trace_entry	ent;
-	unsigned int		prev_pid;
-	unsigned char		prev_prio;
-	unsigned char		prev_state;
-	unsigned int		next_pid;
-	unsigned char		next_prio;
-	unsigned char		next_state;
-	unsigned int		next_cpu;
-};
-
-/*
- * Special (free-form) trace entry:
- */
-struct special_entry {
-	struct trace_entry	ent;
-	unsigned long		arg1;
-	unsigned long		arg2;
-	unsigned long		arg3;
-};
-
-/*
- * Stack-trace entry:
- */
-
-#define FTRACE_STACK_ENTRIES	8
-
-struct stack_entry {
-	struct trace_entry	ent;
-	unsigned long		caller[FTRACE_STACK_ENTRIES];
-};
-
-struct userstack_entry {
-	struct trace_entry	ent;
-	unsigned long		caller[FTRACE_STACK_ENTRIES];
-};
-
-/*
- * trace_printk entry:
- */
-struct bprint_entry {
-	struct trace_entry	ent;
-	unsigned long		ip;
-	const char		*fmt;
-	u32			buf[];
-};
+#undef __field
+#define __field(type, item)		type	item;
 
-struct print_entry {
-	struct trace_entry	ent;
-	unsigned long		ip;
-	char			buf[];
-};
+#undef __field_struct
+#define __field_struct(type, item)	__field(type, item)
 
-#define TRACE_OLD_SIZE		88
+#undef __field_desc
+#define __field_desc(type, container, item)
 
-struct trace_field_cont {
-	unsigned char		type;
-	/* Temporary till we get rid of this completely */
-	char			buf[TRACE_OLD_SIZE - 1];
-};
+#undef __array
+#define __array(type, item, size)	type	item[size];
 
-struct trace_mmiotrace_rw {
-	struct trace_entry	ent;
-	struct mmiotrace_rw	rw;
-};
+#undef __array_desc
+#define __array_desc(type, container, item, size)
 
-struct trace_mmiotrace_map {
-	struct trace_entry	ent;
-	struct mmiotrace_map	map;
-};
+#undef __dynamic_array
+#define __dynamic_array(type, item)	type	item[];
 
-struct trace_boot_call {
-	struct trace_entry	ent;
-	struct boot_trace_call boot_call;
-};
+#undef F_STRUCT
+#define F_STRUCT(args...)		args
 
-struct trace_boot_ret {
-	struct trace_entry	ent;
-	struct boot_trace_ret boot_ret;
-};
-
-#define TRACE_FUNC_SIZE 30
-#define TRACE_FILE_SIZE 20
-struct trace_branch {
-	struct trace_entry	ent;
-	unsigned	        line;
-	char			func[TRACE_FUNC_SIZE+1];
-	char			file[TRACE_FILE_SIZE+1];
-	char			correct;
-};
-
-struct hw_branch_entry {
-	struct trace_entry	ent;
-	u64			from;
-	u64			to;
-};
-
-struct trace_power {
-	struct trace_entry	ent;
-	struct power_trace	state_data;
-};
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)	\
+	struct struct_name {					\
+		struct trace_entry	ent;			\
+		tstruct						\
+	}
 
-enum kmemtrace_type_id {
-	KMEMTRACE_TYPE_KMALLOC = 0,	/* kmalloc() or kfree(). */
-	KMEMTRACE_TYPE_CACHE,		/* kmem_cache_*(). */
-	KMEMTRACE_TYPE_PAGES,		/* __get_free_pages() and friends. */
-};
+#undef TP_ARGS
+#define TP_ARGS(args...)	args
 
-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;
-};
+#undef FTRACE_ENTRY_DUP
+#define FTRACE_ENTRY_DUP(name, name_struct, id, tstruct, printk)
 
-struct kmemtrace_free_entry {
-	struct trace_entry	ent;
-	enum kmemtrace_type_id type_id;
-	unsigned long call_site;
-	const void *ptr;
-};
+#include "trace_entries.h"
 
+/*
+ * syscalls are special, and need special handling, this is why
+ * they are not included in trace_entries.h
+ */
 struct syscall_trace_enter {
 	struct trace_entry	ent;
 	int			nr;
@@ -205,13 +101,12 @@ struct syscall_trace_exit {
 	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
- *  NEED_RESCED		- reschedule is requested
+ *  NEED_RESCHED	- reschedule is requested
  *  HARDIRQ		- inside an interrupt handler
  *  SOFTIRQ		- inside a softirq handler
  */
@@ -310,7 +205,6 @@ extern void __ftrace_bad_type(void);
 		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 kmemtrace_alloc_entry,	\
 			  TRACE_KMEM_ALLOC);	\
 		IF_ASSIGN(var, ent, struct kmemtrace_free_entry,	\
@@ -390,7 +284,6 @@ struct tracer {
 	struct tracer		*next;
 	int			print_max;
 	struct tracer_flags	*flags;
-	struct tracer_stat	*stats;
 };
 
 
@@ -469,6 +362,7 @@ void tracing_stop_sched_switch_record(void);
 void tracing_start_sched_switch_record(void);
 int register_tracer(struct tracer *type);
 void unregister_tracer(struct tracer *type);
+int is_tracing_stopped(void);
 
 extern unsigned long nsecs_to_usecs(unsigned long nsecs);
 
@@ -509,20 +403,6 @@ static inline void __trace_stack(struct trace_array *tr, unsigned long flags,
 
 extern cycle_t ftrace_now(int cpu);
 
-#ifdef CONFIG_CONTEXT_SWITCH_TRACER
-typedef void
-(*tracer_switch_func_t)(void *private,
-			void *__rq,
-			struct task_struct *prev,
-			struct task_struct *next);
-
-struct tracer_switch_ops {
-	tracer_switch_func_t		func;
-	void				*private;
-	struct tracer_switch_ops	*next;
-};
-#endif /* CONFIG_CONTEXT_SWITCH_TRACER */
-
 extern void trace_find_cmdline(int pid, char comm[]);
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -638,6 +518,41 @@ static inline int ftrace_trace_task(struct task_struct *task)
 #endif
 
 /*
+ * struct trace_parser - servers for reading the user input separated by spaces
+ * @cont: set if the input is not complete - no final space char was found
+ * @buffer: holds the parsed user input
+ * @idx: user input lenght
+ * @size: buffer size
+ */
+struct trace_parser {
+	bool		cont;
+	char		*buffer;
+	unsigned	idx;
+	unsigned	size;
+};
+
+static inline bool trace_parser_loaded(struct trace_parser *parser)
+{
+	return (parser->idx != 0);
+}
+
+static inline bool trace_parser_cont(struct trace_parser *parser)
+{
+	return parser->cont;
+}
+
+static inline void trace_parser_clear(struct trace_parser *parser)
+{
+	parser->cont = false;
+	parser->idx = 0;
+}
+
+extern int trace_parser_get_init(struct trace_parser *parser, int size);
+extern void trace_parser_put(struct trace_parser *parser);
+extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
+	size_t cnt, loff_t *ppos);
+
+/*
  * trace_iterator_flags is an enumeration that defines bit
  * positions into trace_flags that controls the output.
  *
@@ -823,58 +738,18 @@ filter_check_discard(struct ftrace_event_call *call, void *rec,
 	return 0;
 }
 
-#define DEFINE_COMPARISON_PRED(type)					\
-static int filter_pred_##type(struct filter_pred *pred, void *event,	\
-			      int val1, int val2)			\
-{									\
-	type *addr = (type *)(event + pred->offset);			\
-	type val = (type)pred->val;					\
-	int match = 0;							\
-									\
-	switch (pred->op) {						\
-	case OP_LT:							\
-		match = (*addr < val);					\
-		break;							\
-	case OP_LE:							\
-		match = (*addr <= val);					\
-		break;							\
-	case OP_GT:							\
-		match = (*addr > val);					\
-		break;							\
-	case OP_GE:							\
-		match = (*addr >= val);					\
-		break;							\
-	default:							\
-		break;							\
-	}								\
-									\
-	return match;							\
-}
-
-#define DEFINE_EQUALITY_PRED(size)					\
-static int filter_pred_##size(struct filter_pred *pred, void *event,	\
-			      int val1, int val2)			\
-{									\
-	u##size *addr = (u##size *)(event + pred->offset);		\
-	u##size val = (u##size)pred->val;				\
-	int match;							\
-									\
-	match = (val == *addr) ^ pred->not;				\
-									\
-	return match;							\
-}
-
 extern struct mutex event_mutex;
 extern struct list_head ftrace_events;
 
 extern const char *__start___trace_bprintk_fmt[];
 extern const char *__stop___trace_bprintk_fmt[];
 
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(call, struct_name, id, tstruct, print)		\
 	extern struct ftrace_event_call event_##call;
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct, tpfmt)
-#include "trace_event_types.h"
+#undef FTRACE_ENTRY_DUP
+#define FTRACE_ENTRY_DUP(call, struct_name, id, tstruct, print)		\
+	FTRACE_ENTRY(call, struct_name, id, PARAMS(tstruct), PARAMS(print))
+#include "trace_entries.h"
 
 #endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index 19bfc75..c21d5f3 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -129,6 +129,7 @@ struct tracer boot_tracer __read_mostly =
 
 void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
 {
+	struct ftrace_event_call *call = &event_boot_call;
 	struct ring_buffer_event *event;
 	struct ring_buffer *buffer;
 	struct trace_boot_call *entry;
@@ -150,13 +151,15 @@ void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
 		goto out;
 	entry	= ring_buffer_event_data(event);
 	entry->boot_call = *bt;
-	trace_buffer_unlock_commit(buffer, event, 0, 0);
+	if (!filter_check_discard(call, entry, buffer, event))
+		trace_buffer_unlock_commit(buffer, event, 0, 0);
  out:
 	preempt_enable();
 }
 
 void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
 {
+	struct ftrace_event_call *call = &event_boot_ret;
 	struct ring_buffer_event *event;
 	struct ring_buffer *buffer;
 	struct trace_boot_ret *entry;
@@ -175,7 +178,8 @@ void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
 		goto out;
 	entry	= ring_buffer_event_data(event);
 	entry->boot_ret = *bt;
-	trace_buffer_unlock_commit(buffer, event, 0, 0);
+	if (!filter_check_discard(call, entry, buffer, event))
+		trace_buffer_unlock_commit(buffer, event, 0, 0);
  out:
 	preempt_enable();
 }
diff --git a/kernel/trace/trace_clock.c b/kernel/trace/trace_clock.c
index b588fd8..20c5f92 100644
--- a/kernel/trace/trace_clock.c
+++ b/kernel/trace/trace_clock.c
@@ -66,10 +66,14 @@ u64 notrace trace_clock(void)
  * 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;
+/* keep prev_time and lock in the same cacheline. */
+static struct {
+	u64 prev_time;
+	raw_spinlock_t lock;
+} trace_clock_struct ____cacheline_aligned_in_smp =
+	{
+		.lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED,
+	};
 
 u64 notrace trace_clock_global(void)
 {
@@ -88,19 +92,19 @@ u64 notrace trace_clock_global(void)
 	if (unlikely(in_nmi()))
 		goto out;
 
-	__raw_spin_lock(&trace_clock_lock);
+	__raw_spin_lock(&trace_clock_struct.lock);
 
 	/*
 	 * TODO: if this happens often then maybe we should reset
-	 * my_scd->clock to prev_trace_clock_time+1, to make sure
+	 * my_scd->clock to prev_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;
+	if ((s64)(now - trace_clock_struct.prev_time) < 0)
+		now = trace_clock_struct.prev_time + 1;
 
-	prev_trace_clock_time = now;
+	trace_clock_struct.prev_time = now;
 
-	__raw_spin_unlock(&trace_clock_lock);
+	__raw_spin_unlock(&trace_clock_struct.lock);
 
  out:
 	raw_local_irq_restore(flags);
diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h
new file mode 100644
index 0000000..ead3d72
--- /dev/null
+++ b/kernel/trace/trace_entries.h
@@ -0,0 +1,366 @@
+/*
+ * This file defines the trace event structures that go into the ring
+ * buffer directly. They are created via macros so that changes for them
+ * appear in the format file. Using macros will automate this process.
+ *
+ * The macro used to create a ftrace data structure is:
+ *
+ * FTRACE_ENTRY( name, struct_name, id, structure, print )
+ *
+ * @name: the name used the event name, as well as the name of
+ *   the directory that holds the format file.
+ *
+ * @struct_name: the name of the structure that is created.
+ *
+ * @id: The event identifier that is used to detect what event
+ *    this is from the ring buffer.
+ *
+ * @structure: the structure layout
+ *
+ *  - __field(	type,	item	)
+ *	  This is equivalent to declaring
+ *		type	item;
+ *	  in the structure.
+ *  - __array(	type,	item,	size	)
+ *	  This is equivalent to declaring
+ *		type	item[size];
+ *	  in the structure.
+ *
+ *   * for structures within structures, the format of the internal
+ *	structure is layed out. This allows the internal structure
+ *	to be deciphered for the format file. Although these macros
+ *	may become out of sync with the internal structure, they
+ *	will create a compile error if it happens. Since the
+ *	internel structures are just tracing helpers, this is not
+ *	an issue.
+ *
+ *	When an internal structure is used, it should use:
+ *
+ *	__field_struct(	type,	item	)
+ *
+ *	instead of __field. This will prevent it from being shown in
+ *	the output file. The fields in the structure should use.
+ *
+ *	__field_desc(	type,	container,	item		)
+ *	__array_desc(	type,	container,	item,	len	)
+ *
+ *	type, item and len are the same as __field and __array, but
+ *	container is added. This is the name of the item in
+ *	__field_struct that this is describing.
+ *
+ *
+ * @print: the print format shown to users in the format file.
+ */
+
+/*
+ * Function trace entry - function address and parent function addres:
+ */
+FTRACE_ENTRY(function, ftrace_entry,
+
+	TRACE_FN,
+
+	F_STRUCT(
+		__field(	unsigned long,	ip		)
+		__field(	unsigned long,	parent_ip	)
+	),
+
+	F_printk(" %lx <-- %lx", __entry->ip, __entry->parent_ip)
+);
+
+/* Function call entry */
+FTRACE_ENTRY(funcgraph_entry, ftrace_graph_ent_entry,
+
+	TRACE_GRAPH_ENT,
+
+	F_STRUCT(
+		__field_struct(	struct ftrace_graph_ent,	graph_ent	)
+		__field_desc(	unsigned long,	graph_ent,	func		)
+		__field_desc(	int,		graph_ent,	depth		)
+	),
+
+	F_printk("--> %lx (%d)", __entry->func, __entry->depth)
+);
+
+/* Function return entry */
+FTRACE_ENTRY(funcgraph_exit, ftrace_graph_ret_entry,
+
+	TRACE_GRAPH_RET,
+
+	F_STRUCT(
+		__field_struct(	struct ftrace_graph_ret,	ret	)
+		__field_desc(	unsigned long,	ret,		func	)
+		__field_desc(	unsigned long long, ret,	calltime)
+		__field_desc(	unsigned long long, ret,	rettime	)
+		__field_desc(	unsigned long,	ret,		overrun	)
+		__field_desc(	int,		ret,		depth	)
+	),
+
+	F_printk("<-- %lx (%d) (start: %llx  end: %llx) over: %d",
+		 __entry->func, __entry->depth,
+		 __entry->calltime, __entry->rettime,
+		 __entry->depth)
+);
+
+/*
+ * Context switch trace entry - which task (and prio) we switched from/to:
+ *
+ * This is used for both wakeup and context switches. We only want
+ * to create one structure, but we need two outputs for it.
+ */
+#define FTRACE_CTX_FIELDS					\
+	__field(	unsigned int,	prev_pid	)	\
+	__field(	unsigned char,	prev_prio	)	\
+	__field(	unsigned char,	prev_state	)	\
+	__field(	unsigned int,	next_pid	)	\
+	__field(	unsigned char,	next_prio	)	\
+	__field(	unsigned char,	next_state	)	\
+	__field(	unsigned int,	next_cpu	)
+
+FTRACE_ENTRY(context_switch, ctx_switch_entry,
+
+	TRACE_CTX,
+
+	F_STRUCT(
+		FTRACE_CTX_FIELDS
+	),
+
+	F_printk("%u:%u:%u  ==> %u:%u:%u [%03u]",
+		 __entry->prev_pid, __entry->prev_prio, __entry->prev_state,
+		 __entry->next_pid, __entry->next_prio, __entry->next_state,
+		 __entry->next_cpu
+		)
+);
+
+/*
+ * FTRACE_ENTRY_DUP only creates the format file, it will not
+ *  create another structure.
+ */
+FTRACE_ENTRY_DUP(wakeup, ctx_switch_entry,
+
+	TRACE_WAKE,
+
+	F_STRUCT(
+		FTRACE_CTX_FIELDS
+	),
+
+	F_printk("%u:%u:%u  ==+ %u:%u:%u [%03u]",
+		 __entry->prev_pid, __entry->prev_prio, __entry->prev_state,
+		 __entry->next_pid, __entry->next_prio, __entry->next_state,
+		 __entry->next_cpu
+		)
+);
+
+/*
+ * Special (free-form) trace entry:
+ */
+FTRACE_ENTRY(special, special_entry,
+
+	TRACE_SPECIAL,
+
+	F_STRUCT(
+		__field(	unsigned long,	arg1	)
+		__field(	unsigned long,	arg2	)
+		__field(	unsigned long,	arg3	)
+	),
+
+	F_printk("(%08lx) (%08lx) (%08lx)",
+		 __entry->arg1, __entry->arg2, __entry->arg3)
+);
+
+/*
+ * Stack-trace entry:
+ */
+
+#define FTRACE_STACK_ENTRIES	8
+
+FTRACE_ENTRY(kernel_stack, stack_entry,
+
+	TRACE_STACK,
+
+	F_STRUCT(
+		__array(	unsigned long,	caller, FTRACE_STACK_ENTRIES	)
+	),
+
+	F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+		 "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n",
+		 __entry->caller[0], __entry->caller[1], __entry->caller[2],
+		 __entry->caller[3], __entry->caller[4], __entry->caller[5],
+		 __entry->caller[6], __entry->caller[7])
+);
+
+FTRACE_ENTRY(user_stack, userstack_entry,
+
+	TRACE_USER_STACK,
+
+	F_STRUCT(
+		__field(	unsigned int,	tgid	)
+		__array(	unsigned long,	caller, FTRACE_STACK_ENTRIES	)
+	),
+
+	F_printk("\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n"
+		 "\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n\t=> (%08lx)\n",
+		 __entry->caller[0], __entry->caller[1], __entry->caller[2],
+		 __entry->caller[3], __entry->caller[4], __entry->caller[5],
+		 __entry->caller[6], __entry->caller[7])
+);
+
+/*
+ * trace_printk entry:
+ */
+FTRACE_ENTRY(bprint, bprint_entry,
+
+	TRACE_BPRINT,
+
+	F_STRUCT(
+		__field(	unsigned long,	ip	)
+		__field(	const char *,	fmt	)
+		__dynamic_array(	u32,	buf	)
+	),
+
+	F_printk("%08lx fmt:%p",
+		 __entry->ip, __entry->fmt)
+);
+
+FTRACE_ENTRY(print, print_entry,
+
+	TRACE_PRINT,
+
+	F_STRUCT(
+		__field(	unsigned long,	ip	)
+		__dynamic_array(	char,	buf	)
+	),
+
+	F_printk("%08lx %s",
+		 __entry->ip, __entry->buf)
+);
+
+FTRACE_ENTRY(mmiotrace_rw, trace_mmiotrace_rw,
+
+	TRACE_MMIO_RW,
+
+	F_STRUCT(
+		__field_struct(	struct mmiotrace_rw,	rw	)
+		__field_desc(	resource_size_t, rw,	phys	)
+		__field_desc(	unsigned long,	rw,	value	)
+		__field_desc(	unsigned long,	rw,	pc	)
+		__field_desc(	int, 		rw,	map_id	)
+		__field_desc(	unsigned char,	rw,	opcode	)
+		__field_desc(	unsigned char,	rw,	width	)
+	),
+
+	F_printk("%lx %lx %lx %d %x %x",
+		 (unsigned long)__entry->phys, __entry->value, __entry->pc,
+		 __entry->map_id, __entry->opcode, __entry->width)
+);
+
+FTRACE_ENTRY(mmiotrace_map, trace_mmiotrace_map,
+
+	TRACE_MMIO_MAP,
+
+	F_STRUCT(
+		__field_struct(	struct mmiotrace_map,	map	)
+		__field_desc(	resource_size_t, map,	phys	)
+		__field_desc(	unsigned long,	map,	virt	)
+		__field_desc(	unsigned long,	map,	len	)
+		__field_desc(	int, 		map,	map_id	)
+		__field_desc(	unsigned char,	map,	opcode	)
+	),
+
+	F_printk("%lx %lx %lx %d %x",
+		 (unsigned long)__entry->phys, __entry->virt, __entry->len,
+		 __entry->map_id, __entry->opcode)
+);
+
+FTRACE_ENTRY(boot_call, trace_boot_call,
+
+	TRACE_BOOT_CALL,
+
+	F_STRUCT(
+		__field_struct(	struct boot_trace_call,	boot_call	)
+		__field_desc(	pid_t,	boot_call,	caller		)
+		__array_desc(	char,	boot_call,	func,	KSYM_SYMBOL_LEN)
+	),
+
+	F_printk("%d  %s", __entry->caller, __entry->func)
+);
+
+FTRACE_ENTRY(boot_ret, trace_boot_ret,
+
+	TRACE_BOOT_RET,
+
+	F_STRUCT(
+		__field_struct(	struct boot_trace_ret,	boot_ret	)
+		__array_desc(	char,	boot_ret,	func,	KSYM_SYMBOL_LEN)
+		__field_desc(	int,	boot_ret,	result		)
+		__field_desc(	unsigned long, boot_ret, duration	)
+	),
+
+	F_printk("%s %d %lx",
+		 __entry->func, __entry->result, __entry->duration)
+);
+
+#define TRACE_FUNC_SIZE 30
+#define TRACE_FILE_SIZE 20
+
+FTRACE_ENTRY(branch, trace_branch,
+
+	TRACE_BRANCH,
+
+	F_STRUCT(
+		__field(	unsigned int,	line				)
+		__array(	char,		func,	TRACE_FUNC_SIZE+1	)
+		__array(	char,		file,	TRACE_FILE_SIZE+1	)
+		__field(	char,		correct				)
+	),
+
+	F_printk("%u:%s:%s (%u)",
+		 __entry->line,
+		 __entry->func, __entry->file, __entry->correct)
+);
+
+FTRACE_ENTRY(hw_branch, hw_branch_entry,
+
+	TRACE_HW_BRANCHES,
+
+	F_STRUCT(
+		__field(	u64,	from	)
+		__field(	u64,	to	)
+	),
+
+	F_printk("from: %llx to: %llx", __entry->from, __entry->to)
+);
+
+FTRACE_ENTRY(kmem_alloc, kmemtrace_alloc_entry,
+
+	TRACE_KMEM_ALLOC,
+
+	F_STRUCT(
+		__field(	enum kmemtrace_type_id,	type_id		)
+		__field(	unsigned long,		call_site	)
+		__field(	const void *,		ptr		)
+		__field(	size_t,			bytes_req	)
+		__field(	size_t,			bytes_alloc	)
+		__field(	gfp_t,			gfp_flags	)
+		__field(	int,			node		)
+	),
+
+	F_printk("type:%u call_site:%lx ptr:%p req:%zi alloc:%zi"
+		 " flags:%x node:%d",
+		 __entry->type_id, __entry->call_site, __entry->ptr,
+		 __entry->bytes_req, __entry->bytes_alloc,
+		 __entry->gfp_flags, __entry->node)
+);
+
+FTRACE_ENTRY(kmem_free, kmemtrace_free_entry,
+
+	TRACE_KMEM_FREE,
+
+	F_STRUCT(
+		__field(	enum kmemtrace_type_id,	type_id		)
+		__field(	unsigned long,		call_site	)
+		__field(	const void *,		ptr		)
+	),
+
+	F_printk("type:%u call_site:%lx ptr:%p",
+		 __entry->type_id, __entry->call_site, __entry->ptr)
+);
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
index 11ba5bb..dd44b87 100644
--- a/kernel/trace/trace_event_profile.c
+++ b/kernel/trace/trace_event_profile.c
@@ -5,8 +5,60 @@
  *
  */
 
+#include <linux/module.h>
 #include "trace.h"
 
+/*
+ * We can't use a size but a type in alloc_percpu()
+ * So let's create a dummy type that matches the desired size
+ */
+typedef struct {char buf[FTRACE_MAX_PROFILE_SIZE];} profile_buf_t;
+
+char		*trace_profile_buf;
+EXPORT_SYMBOL_GPL(trace_profile_buf);
+
+char		*trace_profile_buf_nmi;
+EXPORT_SYMBOL_GPL(trace_profile_buf_nmi);
+
+/* Count the events in use (per event id, not per instance) */
+static int	total_profile_count;
+
+static int ftrace_profile_enable_event(struct ftrace_event_call *event)
+{
+	char *buf;
+	int ret = -ENOMEM;
+
+	if (atomic_inc_return(&event->profile_count))
+		return 0;
+
+	if (!total_profile_count++) {
+		buf = (char *)alloc_percpu(profile_buf_t);
+		if (!buf)
+			goto fail_buf;
+
+		rcu_assign_pointer(trace_profile_buf, buf);
+
+		buf = (char *)alloc_percpu(profile_buf_t);
+		if (!buf)
+			goto fail_buf_nmi;
+
+		rcu_assign_pointer(trace_profile_buf_nmi, buf);
+	}
+
+	ret = event->profile_enable();
+	if (!ret)
+		return 0;
+
+	kfree(trace_profile_buf_nmi);
+fail_buf_nmi:
+	kfree(trace_profile_buf);
+fail_buf:
+	total_profile_count--;
+	atomic_dec(&event->profile_count);
+
+	return ret;
+}
+
 int ftrace_profile_enable(int event_id)
 {
 	struct ftrace_event_call *event;
@@ -14,8 +66,9 @@ int ftrace_profile_enable(int event_id)
 
 	mutex_lock(&event_mutex);
 	list_for_each_entry(event, &ftrace_events, list) {
-		if (event->id == event_id && event->profile_enable) {
-			ret = event->profile_enable(event);
+		if (event->id == event_id && event->profile_enable &&
+		    try_module_get(event->mod)) {
+			ret = ftrace_profile_enable_event(event);
 			break;
 		}
 	}
@@ -24,6 +77,33 @@ int ftrace_profile_enable(int event_id)
 	return ret;
 }
 
+static void ftrace_profile_disable_event(struct ftrace_event_call *event)
+{
+	char *buf, *nmi_buf;
+
+	if (!atomic_add_negative(-1, &event->profile_count))
+		return;
+
+	event->profile_disable();
+
+	if (!--total_profile_count) {
+		buf = trace_profile_buf;
+		rcu_assign_pointer(trace_profile_buf, NULL);
+
+		nmi_buf = trace_profile_buf_nmi;
+		rcu_assign_pointer(trace_profile_buf_nmi, NULL);
+
+		/*
+		 * Ensure every events in profiling have finished before
+		 * releasing the buffers
+		 */
+		synchronize_sched();
+
+		free_percpu(buf);
+		free_percpu(nmi_buf);
+	}
+}
+
 void ftrace_profile_disable(int event_id)
 {
 	struct ftrace_event_call *event;
@@ -31,7 +111,8 @@ void ftrace_profile_disable(int event_id)
 	mutex_lock(&event_mutex);
 	list_for_each_entry(event, &ftrace_events, list) {
 		if (event->id == event_id) {
-			event->profile_disable(event);
+			ftrace_profile_disable_event(event);
+			module_put(event->mod);
 			break;
 		}
 	}
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h
deleted file mode 100644
index 6db005e..0000000
--- a/kernel/trace/trace_event_types.h
+++ /dev/null
@@ -1,178 +0,0 @@
-#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(unsigned long long, ret.calltime, calltime)
-		TRACE_FIELD(unsigned long long, ret.rettime, rettime)
-		TRACE_FIELD(unsigned long, ret.overrun, overrun)
-		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_NOFILTER(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,
-				    TRACE_FUNC_SIZE+1, func)
-		TRACE_FIELD_SPECIAL(char file[TRACE_FUNC_SIZE+1], file,
-				    TRACE_FUNC_SIZE+1, 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_SIGN(ktime_t, state_data.stamp, stamp, 1)
-		TRACE_FIELD_SIGN(ktime_t, state_data.end, end, 1)
-		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
index 78b1ed2..6f03c8a 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -21,6 +21,7 @@
 
 #include "trace_output.h"
 
+#undef TRACE_SYSTEM
 #define TRACE_SYSTEM "TRACE_SYSTEM"
 
 DEFINE_MUTEX(event_mutex);
@@ -86,7 +87,7 @@ int trace_define_common_fields(struct ftrace_event_call *call)
 	__common_field(unsigned char, flags);
 	__common_field(unsigned char, preempt_count);
 	__common_field(int, pid);
-	__common_field(int, tgid);
+	__common_field(int, lock_depth);
 
 	return ret;
 }
@@ -230,11 +231,9 @@ static ssize_t
 ftrace_event_write(struct file *file, const char __user *ubuf,
 		   size_t cnt, loff_t *ppos)
 {
+	struct trace_parser parser;
 	size_t read = 0;
-	int i, set = 1;
 	ssize_t ret;
-	char *buf;
-	char ch;
 
 	if (!cnt || cnt < 0)
 		return 0;
@@ -243,60 +242,28 @@ ftrace_event_write(struct file *file, const char __user *ubuf,
 	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)
+	if (trace_parser_get_init(&parser, EVENT_BUF_SIZE + 1))
 		return -ENOMEM;
 
-	if (cnt > EVENT_BUF_SIZE)
-		cnt = EVENT_BUF_SIZE;
+	read = trace_get_user(&parser, ubuf, cnt, ppos);
+
+	if (trace_parser_loaded((&parser))) {
+		int set = 1;
 
-	i = 0;
-	while (cnt && !isspace(ch)) {
-		if (!i && ch == '!')
+		if (*parser.buffer == '!')
 			set = 0;
-		else
-			buf[i++] = ch;
 
-		ret = get_user(ch, ubuf++);
+		parser.buffer[parser.idx] = 0;
+
+		ret = ftrace_set_clr_event(parser.buffer + !set, set);
 		if (ret)
-			goto out_free;
-		read++;
-		cnt--;
+			goto out_put;
 	}
-	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);
+ out_put:
+	trace_parser_put(&parser);
 
 	return ret;
 }
@@ -304,42 +271,32 @@ ftrace_event_write(struct file *file, const char __user *ubuf,
 static void *
 t_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	struct list_head *list = m->private;
-	struct ftrace_event_call *call;
+	struct ftrace_event_call *call = v;
 
 	(*pos)++;
 
-	for (;;) {
-		if (list == &ftrace_events)
-			return NULL;
-
-		call = list_entry(list, struct ftrace_event_call, list);
-
+	list_for_each_entry_continue(call, &ftrace_events, list) {
 		/*
 		 * The ftrace subsystem is for showing formats only.
 		 * They can not be enabled or disabled via the event files.
 		 */
 		if (call->regfunc)
-			break;
-
-		list = list->next;
+			return call;
 	}
 
-	m->private = list->next;
-
-	return call;
+	return NULL;
 }
 
 static void *t_start(struct seq_file *m, loff_t *pos)
 {
-	struct ftrace_event_call *call = NULL;
+	struct ftrace_event_call *call;
 	loff_t l;
 
 	mutex_lock(&event_mutex);
 
-	m->private = ftrace_events.next;
+	call = list_entry(&ftrace_events, struct ftrace_event_call, list);
 	for (l = 0; l <= *pos; ) {
-		call = t_next(m, NULL, &l);
+		call = t_next(m, call, &l);
 		if (!call)
 			break;
 	}
@@ -349,37 +306,28 @@ static void *t_start(struct seq_file *m, loff_t *pos)
 static void *
 s_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	struct list_head *list = m->private;
-	struct ftrace_event_call *call;
+	struct ftrace_event_call *call = v;
 
 	(*pos)++;
 
- retry:
-	if (list == &ftrace_events)
-		return NULL;
-
-	call = list_entry(list, struct ftrace_event_call, list);
-
-	if (!call->enabled) {
-		list = list->next;
-		goto retry;
+	list_for_each_entry_continue(call, &ftrace_events, list) {
+		if (call->enabled)
+			return call;
 	}
 
-	m->private = list->next;
-
-	return call;
+	return NULL;
 }
 
 static void *s_start(struct seq_file *m, loff_t *pos)
 {
-	struct ftrace_event_call *call = NULL;
+	struct ftrace_event_call *call;
 	loff_t l;
 
 	mutex_lock(&event_mutex);
 
-	m->private = ftrace_events.next;
+	call = list_entry(&ftrace_events, struct ftrace_event_call, list);
 	for (l = 0; l <= *pos; ) {
-		call = s_next(m, NULL, &l);
+		call = s_next(m, call, &l);
 		if (!call)
 			break;
 	}
@@ -578,7 +526,7 @@ static int trace_write_header(struct trace_seq *s)
 				FIELD(unsigned char, flags),
 				FIELD(unsigned char, preempt_count),
 				FIELD(int, pid),
-				FIELD(int, tgid));
+				FIELD(int, lock_depth));
 }
 
 static ssize_t
@@ -1187,7 +1135,7 @@ static int trace_module_notify(struct notifier_block *self,
 }
 #endif /* CONFIG_MODULES */
 
-struct notifier_block trace_module_nb = {
+static struct notifier_block trace_module_nb = {
 	.notifier_call = trace_module_notify,
 	.priority = 0,
 };
@@ -1359,6 +1307,18 @@ static __init void event_trace_self_tests(void)
 		if (!call->regfunc)
 			continue;
 
+/*
+ * Testing syscall events here is pretty useless, but
+ * we still do it if configured. But this is time consuming.
+ * What we really need is a user thread to perform the
+ * syscalls as we test.
+ */
+#ifndef CONFIG_EVENT_TRACE_TEST_SYSCALLS
+		if (call->system &&
+		    strcmp(call->system, "syscalls") == 0)
+			continue;
+#endif
+
 		pr_info("Testing event %s: ", call->name);
 
 		/*
@@ -1432,7 +1392,7 @@ static __init void event_trace_self_tests(void)
 
 #ifdef CONFIG_FUNCTION_TRACER
 
-static DEFINE_PER_CPU(atomic_t, test_event_disable);
+static DEFINE_PER_CPU(atomic_t, ftrace_test_event_disable);
 
 static void
 function_test_events_call(unsigned long ip, unsigned long parent_ip)
@@ -1449,7 +1409,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip)
 	pc = preempt_count();
 	resched = ftrace_preempt_disable();
 	cpu = raw_smp_processor_id();
-	disabled = atomic_inc_return(&per_cpu(test_event_disable, cpu));
+	disabled = atomic_inc_return(&per_cpu(ftrace_test_event_disable, cpu));
 
 	if (disabled != 1)
 		goto out;
@@ -1468,7 +1428,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip)
 	trace_nowake_buffer_unlock_commit(buffer, event, flags, pc);
 
  out:
-	atomic_dec(&per_cpu(test_event_disable, cpu));
+	atomic_dec(&per_cpu(ftrace_test_event_disable, cpu));
 	ftrace_preempt_enable(resched);
 }
 
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 93660fb..2324578 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -121,6 +121,47 @@ struct filter_parse_state {
 	} operand;
 };
 
+#define DEFINE_COMPARISON_PRED(type)					\
+static int filter_pred_##type(struct filter_pred *pred, void *event,	\
+			      int val1, int val2)			\
+{									\
+	type *addr = (type *)(event + pred->offset);			\
+	type val = (type)pred->val;					\
+	int match = 0;							\
+									\
+	switch (pred->op) {						\
+	case OP_LT:							\
+		match = (*addr < val);					\
+		break;							\
+	case OP_LE:							\
+		match = (*addr <= val);					\
+		break;							\
+	case OP_GT:							\
+		match = (*addr > val);					\
+		break;							\
+	case OP_GE:							\
+		match = (*addr >= val);					\
+		break;							\
+	default:							\
+		break;							\
+	}								\
+									\
+	return match;							\
+}
+
+#define DEFINE_EQUALITY_PRED(size)					\
+static int filter_pred_##size(struct filter_pred *pred, void *event,	\
+			      int val1, int val2)			\
+{									\
+	u##size *addr = (u##size *)(event + pred->offset);		\
+	u##size val = (u##size)pred->val;				\
+	int match;							\
+									\
+	match = (val == *addr) ^ pred->not;				\
+									\
+	return match;							\
+}
+
 DEFINE_COMPARISON_PRED(s64);
 DEFINE_COMPARISON_PRED(u64);
 DEFINE_COMPARISON_PRED(s32);
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c
index df1bf6e..9753fcc 100644
--- a/kernel/trace/trace_export.c
+++ b/kernel/trace/trace_export.c
@@ -15,146 +15,125 @@
 
 #include "trace_output.h"
 
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM	ftrace
 
-#undef TRACE_STRUCT
-#define TRACE_STRUCT(args...) args
+/* not needed for this file */
+#undef __field_struct
+#define __field_struct(type, item)
 
-extern void __bad_type_size(void);
+#undef __field
+#define __field(type, item)				type item;
 
-#undef TRACE_FIELD
-#define TRACE_FIELD(type, item, assign)					\
-	if (sizeof(type) != sizeof(field.item))				\
-		__bad_type_size();					\
+#undef __field_desc
+#define __field_desc(type, container, item)		type item;
+
+#undef __array
+#define __array(type, item, size)			type item[size];
+
+#undef __array_desc
+#define __array_desc(type, container, item, size)	type item[size];
+
+#undef __dynamic_array
+#define __dynamic_array(type, item)			type item[];
+
+#undef F_STRUCT
+#define F_STRUCT(args...)				args
+
+#undef F_printk
+#define F_printk(fmt, args...) fmt, args
+
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)	\
+struct ____ftrace_##name {					\
+	tstruct							\
+};								\
+static void __used ____ftrace_check_##name(void)		\
+{								\
+	struct ____ftrace_##name *__entry = NULL;		\
+								\
+	/* force cmpile-time check on F_printk() */		\
+	printk(print);						\
+}
+
+#undef FTRACE_ENTRY_DUP
+#define FTRACE_ENTRY_DUP(name, struct_name, id, tstruct, print)	\
+	FTRACE_ENTRY(name, struct_name, id, PARAMS(tstruct), PARAMS(print))
+
+#include "trace_entries.h"
+
+
+#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));	\
+			       "offset:%zu;\tsize:%zu;\n",		\
+			       offsetof(typeof(field), item),		\
+			       sizeof(field.item));			\
 	if (!ret)							\
 		return 0;
 
+#undef __field_desc
+#define __field_desc(type, container, item)				\
+	ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"	\
+			       "offset:%zu;\tsize:%zu;\n",		\
+			       offsetof(typeof(field), container.item),	\
+			       sizeof(field.container.item));		\
+	if (!ret)							\
+		return 0;
 
-#undef TRACE_FIELD_SPECIAL
-#define TRACE_FIELD_SPECIAL(type_item, item, len, 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));	\
+#undef __array
+#define __array(type, item, len)					\
+	ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
+			       "offset:%zu;\tsize:%zu;\n",		\
+			       offsetof(typeof(field), item),	\
+			       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)); \
+#undef __array_desc
+#define __array_desc(type, container, item, len)			\
+	ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \
+			       "offset:%zu;\tsize:%zu;\n",		\
+			       offsetof(typeof(field), container.item),	\
+			       sizeof(field.container.item));		\
 	if (!ret)							\
 		return 0;
 
-#undef TRACE_FIELD_SIGN
-#define TRACE_FIELD_SIGN(type, item, assign, is_signed)	\
-	TRACE_FIELD(type, item, assign)
+#undef __dynamic_array
+#define __dynamic_array(type, item)					\
+	ret = trace_seq_printf(s, "\tfield:" #type " " #item ";\t"	\
+			       "offset:%zu;\tsize:0;\n",		\
+			       offsetof(typeof(field), item));		\
+	if (!ret)							\
+		return 0;
 
-#undef TP_RAW_FMT
-#define TP_RAW_FMT(args...) args
+#undef F_printk
+#define F_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
 
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
-static int								\
-ftrace_format_##call(struct ftrace_event_call *unused,			\
-		      struct trace_seq *s)				\
-{									\
-	struct args field;						\
-	int ret;							\
-									\
-	tstruct;							\
-									\
-	trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt);		\
-									\
-	return ret;							\
-}
+#undef __entry
+#define __entry REC
 
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct,	\
-				    tpfmt)				\
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)		\
 static int								\
-ftrace_format_##call(struct ftrace_event_call *unused,			\
-		      struct trace_seq *s)				\
+ftrace_format_##name(struct ftrace_event_call *unused,			\
+		     struct trace_seq *s)				\
 {									\
-	struct args field;						\
-	int ret;							\
+	struct struct_name field __attribute__((unused));		\
+	int ret = 0;							\
 									\
 	tstruct;							\
 									\
-	trace_seq_printf(s, "\nprint fmt: \"%s\"\n", tpfmt);		\
+	trace_seq_printf(s, "\nprint fmt: " print);			\
 									\
 	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 TRACE_FIELD_SIGN
-#define TRACE_FIELD_SIGN(type, item, assign, is_signed)	\
-	TRACE_FIELD(type, 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, len, cmd)	\
-	cmd;
-
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
-int ftrace_define_fields_##call(struct ftrace_event_call *event_call);	\
-static int ftrace_raw_init_event_##call(void);				\
-									\
-struct ftrace_event_call __used						\
-__attribute__((__aligned__(4)))						\
-__attribute__((section("_ftrace_events"))) event_##call = {		\
-	.name			= #call,				\
-	.id			= proto,				\
-	.system			= __stringify(TRACE_SYSTEM),		\
-	.raw_init		= ftrace_raw_init_event_##call,		\
-	.show_format		= ftrace_format_##call,			\
-	.define_fields		= ftrace_define_fields_##call,		\
-};									\
-static int ftrace_raw_init_event_##call(void)				\
-{									\
-	INIT_LIST_HEAD(&event_##call.fields);				\
-	return 0;							\
-}									\
-
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct,	\
-				    tpfmt)				\
-									\
-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_entries.h"
 
-#include "trace_event_types.h"
 
-#undef TRACE_FIELD
-#define TRACE_FIELD(type, item, assign)					\
+#undef __field
+#define __field(type, item)						\
 	ret = trace_define_field(event_call, #type, #item,		\
 				 offsetof(typeof(field), item),		\
 				 sizeof(field.item),			\
@@ -162,32 +141,45 @@ __attribute__((section("_ftrace_events"))) event_##call = {		\
 	if (ret)							\
 		return ret;
 
-#undef TRACE_FIELD_SPECIAL
-#define TRACE_FIELD_SPECIAL(type, item, len, cmd)			\
+#undef __field_desc
+#define __field_desc(type, container, item)	\
+	ret = trace_define_field(event_call, #type, #item,		\
+				 offsetof(typeof(field),		\
+					  container.item),		\
+				 sizeof(field.container.item),		\
+				 is_signed_type(type), FILTER_OTHER);	\
+	if (ret)							\
+		return ret;
+
+#undef __array
+#define __array(type, item, len)					\
+	BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);				\
 	ret = trace_define_field(event_call, #type "[" #len "]", #item,	\
 				 offsetof(typeof(field), item),		\
 				 sizeof(field.item), 0, FILTER_OTHER);	\
 	if (ret)							\
 		return ret;
 
-#undef TRACE_FIELD_SIGN
-#define TRACE_FIELD_SIGN(type, item, assign, is_signed)			\
-	ret = trace_define_field(event_call, #type, #item,		\
-				 offsetof(typeof(field), item),		\
-				 sizeof(field.item), is_signed,		\
+#undef __array_desc
+#define __array_desc(type, container, item, len)			\
+	BUILD_BUG_ON(len > MAX_FILTER_STR_VAL);				\
+	ret = trace_define_field(event_call, #type "[" #len "]", #item,	\
+				 offsetof(typeof(field),		\
+					  container.item),		\
+				 sizeof(field.container.item), 0,	\
 				 FILTER_OTHER);				\
 	if (ret)							\
 		return ret;
 
-#undef TRACE_FIELD_ZERO_CHAR
-#define TRACE_FIELD_ZERO_CHAR(item)
+#undef __dynamic_array
+#define __dynamic_array(type, item)
 
-#undef TRACE_EVENT_FORMAT
-#define TRACE_EVENT_FORMAT(call, proto, args, fmt, tstruct, tpfmt)	\
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(name, struct_name, id, tstruct, print)		\
 int									\
-ftrace_define_fields_##call(struct ftrace_event_call *event_call)	\
+ftrace_define_fields_##name(struct ftrace_event_call *event_call)	\
 {									\
-	struct args field;						\
+	struct struct_name field;					\
 	int ret;							\
 									\
 	ret = trace_define_common_fields(event_call);			\
@@ -199,8 +191,42 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call)	\
 	return ret;							\
 }
 
-#undef TRACE_EVENT_FORMAT_NOFILTER
-#define TRACE_EVENT_FORMAT_NOFILTER(call, proto, args, fmt, tstruct,	\
-				    tpfmt)
+#include "trace_entries.h"
+
+
+#undef __field
+#define __field(type, item)
+
+#undef __field_desc
+#define __field_desc(type, container, item)
+
+#undef __array
+#define __array(type, item, len)
+
+#undef __array_desc
+#define __array_desc(type, container, item, len)
+
+#undef __dynamic_array
+#define __dynamic_array(type, item)
+
+#undef FTRACE_ENTRY
+#define FTRACE_ENTRY(call, struct_name, type, tstruct, print)		\
+static int ftrace_raw_init_event_##call(void);				\
+									\
+struct ftrace_event_call __used						\
+__attribute__((__aligned__(4)))						\
+__attribute__((section("_ftrace_events"))) event_##call = {		\
+	.name			= #call,				\
+	.id			= type,					\
+	.system			= __stringify(TRACE_SYSTEM),		\
+	.raw_init		= ftrace_raw_init_event_##call,		\
+	.show_format		= ftrace_format_##call,			\
+	.define_fields		= ftrace_define_fields_##call,		\
+};									\
+static int ftrace_raw_init_event_##call(void)				\
+{									\
+	INIT_LIST_HEAD(&event_##call.fields);				\
+	return 0;							\
+}									\
 
-#include "trace_event_types.h"
+#include "trace_entries.h"
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 5b01b94..b3f3776 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -290,7 +290,7 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
 {
 	long count = (long)data;
 
-	seq_printf(m, "%pf:", (void *)ip);
+	seq_printf(m, "%ps:", (void *)ip);
 
 	if (ops == &traceon_probe_ops)
 		seq_printf(m, "traceon");
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index b3749a2..45e6c01 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -124,7 +124,7 @@ ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret,
 	if (unlikely(current->ret_stack[index].fp != frame_pointer)) {
 		ftrace_graph_stop();
 		WARN(1, "Bad frame pointer: expected %lx, received %lx\n"
-		     "  from func %pF return to %lx\n",
+		     "  from func %ps return to %lx\n",
 		     current->ret_stack[index].fp,
 		     frame_pointer,
 		     (void *)current->ret_stack[index].func,
@@ -364,6 +364,15 @@ print_graph_proc(struct trace_seq *s, pid_t pid)
 }
 
 
+static enum print_line_t
+print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
+{
+	if (!trace_seq_putc(s, ' '))
+		return 0;
+
+	return trace_print_lat_fmt(s, entry);
+}
+
 /* 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, struct fgraph_data *data)
@@ -521,6 +530,7 @@ print_graph_irq(struct trace_iterator *iter, unsigned long addr,
 		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);
@@ -659,7 +669,7 @@ print_graph_entry_leaf(struct trace_iterator *iter,
 			return TRACE_TYPE_PARTIAL_LINE;
 	}
 
-	ret = trace_seq_printf(s, "%pf();\n", (void *)call->func);
+	ret = trace_seq_printf(s, "%ps();\n", (void *)call->func);
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
@@ -702,7 +712,7 @@ print_graph_entry_nested(struct trace_iterator *iter,
 			return TRACE_TYPE_PARTIAL_LINE;
 	}
 
-	ret = trace_seq_printf(s, "%pf() {\n", (void *)call->func);
+	ret = trace_seq_printf(s, "%ps() {\n", (void *)call->func);
 	if (!ret)
 		return TRACE_TYPE_PARTIAL_LINE;
 
@@ -758,6 +768,13 @@ print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s,
 			return TRACE_TYPE_PARTIAL_LINE;
 	}
 
+	/* Latency format */
+	if (trace_flags & TRACE_ITER_LATENCY_FMT) {
+		ret = print_graph_lat_fmt(s, ent);
+		if (ret == TRACE_TYPE_PARTIAL_LINE)
+			return TRACE_TYPE_PARTIAL_LINE;
+	}
+
 	return 0;
 }
 
@@ -952,28 +969,59 @@ print_graph_function(struct trace_iterator *iter)
 	return TRACE_TYPE_HANDLED;
 }
 
+static void print_lat_header(struct seq_file *s)
+{
+	static const char spaces[] = "                "	/* 16 spaces */
+		"    "					/* 4 spaces */
+		"                 ";			/* 17 spaces */
+	int size = 0;
+
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
+		size += 16;
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
+		size += 4;
+	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
+		size += 17;
+
+	seq_printf(s, "#%.*s  _-----=> irqs-off        \n", size, spaces);
+	seq_printf(s, "#%.*s / _----=> need-resched    \n", size, spaces);
+	seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces);
+	seq_printf(s, "#%.*s|| / _--=> preempt-depth   \n", size, spaces);
+	seq_printf(s, "#%.*s||| / _-=> lock-depth      \n", size, spaces);
+	seq_printf(s, "#%.*s|||| /                     \n", size, spaces);
+}
+
 static void print_graph_headers(struct seq_file *s)
 {
+	int lat = trace_flags & TRACE_ITER_LATENCY_FMT;
+
+	if (lat)
+		print_lat_header(s);
+
 	/* 1st line */
-	seq_printf(s, "# ");
+	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      ");
+		seq_printf(s, "  TASK/PID       ");
+	if (lat)
+		seq_printf(s, "|||||");
 	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
 		seq_printf(s, "  DURATION   ");
 	seq_printf(s, "               FUNCTION CALLS\n");
 
 	/* 2nd line */
-	seq_printf(s, "# ");
+	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, "  |    |        ");
+		seq_printf(s, "   |    |        ");
+	if (lat)
+		seq_printf(s, "|||||");
 	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
 		seq_printf(s, "   |   |      ");
 	seq_printf(s, "               |   |   |   |\n");
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index 5555b75..3aa7eaa 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -129,15 +129,10 @@ check_critical_timing(struct trace_array *tr,
 		      unsigned long parent_ip,
 		      int cpu)
 {
-	unsigned long latency, t0, t1;
 	cycle_t T0, T1, delta;
 	unsigned long flags;
 	int pc;
 
-	/*
-	 * usecs conversion is slow so we try to delay the conversion
-	 * as long as possible:
-	 */
 	T0 = data->preempt_timestamp;
 	T1 = ftrace_now(cpu);
 	delta = T1-T0;
@@ -157,18 +152,15 @@ check_critical_timing(struct trace_array *tr,
 
 	trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 
-	latency = nsecs_to_usecs(delta);
-
 	if (data->critical_sequence != max_sequence)
 		goto out_unlock;
 
-	tracing_max_latency = delta;
-	t0 = nsecs_to_usecs(T0);
-	t1 = nsecs_to_usecs(T1);
-
 	data->critical_end = parent_ip;
 
-	update_max_tr_single(tr, current, cpu);
+	if (likely(!is_tracing_stopped())) {
+		tracing_max_latency = delta;
+		update_max_tr_single(tr, current, cpu);
+	}
 
 	max_sequence++;
 
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index c4c9bbd..0acd834 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -307,6 +307,7 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
 				struct trace_array_cpu *data,
 				struct mmiotrace_rw *rw)
 {
+	struct ftrace_event_call *call = &event_mmiotrace_rw;
 	struct ring_buffer *buffer = tr->buffer;
 	struct ring_buffer_event *event;
 	struct trace_mmiotrace_rw *entry;
@@ -320,7 +321,9 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
 	}
 	entry	= ring_buffer_event_data(event);
 	entry->rw			= *rw;
-	trace_buffer_unlock_commit(buffer, event, 0, pc);
+
+	if (!filter_check_discard(call, entry, buffer, event))
+		trace_buffer_unlock_commit(buffer, event, 0, pc);
 }
 
 void mmio_trace_rw(struct mmiotrace_rw *rw)
@@ -334,6 +337,7 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
 				struct trace_array_cpu *data,
 				struct mmiotrace_map *map)
 {
+	struct ftrace_event_call *call = &event_mmiotrace_map;
 	struct ring_buffer *buffer = tr->buffer;
 	struct ring_buffer_event *event;
 	struct trace_mmiotrace_map *entry;
@@ -347,7 +351,9 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
 	}
 	entry	= ring_buffer_event_data(event);
 	entry->map			= *map;
-	trace_buffer_unlock_commit(buffer, event, 0, pc);
+
+	if (!filter_check_discard(call, entry, buffer, event))
+		trace_buffer_unlock_commit(buffer, event, 0, pc);
 }
 
 void mmio_trace_mapping(struct mmiotrace_map *map)
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index e0c2545..f572f44 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -407,7 +407,7 @@ seq_print_userip_objs(const struct userstack_entry *entry, struct trace_seq *s,
 		 * since individual threads might have already quit!
 		 */
 		rcu_read_lock();
-		task = find_task_by_vpid(entry->ent.tgid);
+		task = find_task_by_vpid(entry->tgid);
 		if (task)
 			mm = get_task_mm(task);
 		rcu_read_unlock();
@@ -460,18 +460,23 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
 	return ret;
 }
 
-static int
-lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+/**
+ * trace_print_lat_fmt - print the irq, preempt and lockdep fields
+ * @s: trace seq struct to write to
+ * @entry: The trace entry field from the ring buffer
+ *
+ * Prints the generic fields of irqs off, in hard or softirq, preempt
+ * count and lock depth.
+ */
+int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
 {
 	int hardirq, softirq;
-	char comm[TASK_COMM_LEN];
+	int ret;
 
-	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,
+	if (!trace_seq_printf(s, "%c%c%c",
 			      (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
 				(entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
 				  'X' : '.',
@@ -481,9 +486,30 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
 				hardirq ? 'h' : softirq ? 's' : '.'))
 		return 0;
 
+	if (entry->lock_depth < 0)
+		ret = trace_seq_putc(s, '.');
+	else
+		ret = trace_seq_printf(s, "%d", entry->lock_depth);
+	if (!ret)
+		return 0;
+
 	if (entry->preempt_count)
 		return trace_seq_printf(s, "%x", entry->preempt_count);
-	return trace_seq_puts(s, ".");
+	return trace_seq_putc(s, '.');
+}
+
+static int
+lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+{
+	char comm[TASK_COMM_LEN];
+
+	trace_find_cmdline(entry->pid, comm);
+
+	if (!trace_seq_printf(s, "%8.8s-%-5d %3d",
+			      comm, entry->pid, cpu))
+		return 0;
+
+	return trace_print_lat_fmt(s, entry);
 }
 
 static unsigned long preempt_mark_thresh = 100;
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h
index d38bec4..9d91c72 100644
--- a/kernel/trace/trace_output.h
+++ b/kernel/trace/trace_output.h
@@ -26,6 +26,8 @@ extern struct trace_event *ftrace_find_event(int type);
 
 extern enum print_line_t trace_nop_print(struct trace_iterator *iter,
 					 int flags);
+extern int
+trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry);
 
 /* used by module unregistering */
 extern int __unregister_ftrace_event(struct trace_event *event);
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
deleted file mode 100644
index fe1a00f..0000000
--- a/kernel/trace/trace_power.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * ring buffer based C-state tracer
- *
- * Arjan van de Ven <arjan@linux.intel.com>
- * Copyright (C) 2008 Intel Corporation
- *
- * Much is borrowed from trace_boot.c which is
- * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
- *
- */
-
-#include <linux/init.h>
-#include <linux/debugfs.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 ftrace_event_call *call = &event_power;
-	struct ring_buffer_event *event;
-	struct ring_buffer *buffer;
-	struct trace_power *entry;
-	struct trace_array_cpu *data;
-	struct trace_array *tr = power_trace;
-
-	if (!trace_power_enabled)
-		return;
-
-	buffer = tr->buffer;
-
-	preempt_disable();
-	it->end = ktime_get();
-	data = tr->data[smp_processor_id()];
-
-	event = trace_buffer_lock_reserve(buffer, TRACE_POWER,
-					  sizeof(*entry), 0, 0);
-	if (!event)
-		goto out;
-	entry	= ring_buffer_event_data(event);
-	entry->state_data = *it;
-	if (!filter_check_discard(call, entry, buffer, event))
-		trace_buffer_unlock_commit(buffer, event, 0, 0);
- out:
-	preempt_enable();
-}
-
-static void probe_power_mark(struct power_trace *it, unsigned int type,
-				unsigned int level)
-{
-	struct ftrace_event_call *call = &event_power;
-	struct ring_buffer_event *event;
-	struct ring_buffer *buffer;
-	struct trace_power *entry;
-	struct trace_array_cpu *data;
-	struct trace_array *tr = power_trace;
-
-	if (!trace_power_enabled)
-		return;
-
-	buffer = tr->buffer;
-
-	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(buffer, TRACE_POWER,
-					  sizeof(*entry), 0, 0);
-	if (!event)
-		goto out;
-	entry	= ring_buffer_event_data(event);
-	entry->state_data = *it;
-	if (!filter_check_discard(call, entry, buffer, event))
-		trace_buffer_unlock_commit(buffer, 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)
-{
-	trace_power_enabled = 1;
-}
-
-static void stop_power_trace(struct trace_array *tr)
-{
-	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)
-{
-	power_trace = tr;
-
-	trace_power_enabled = 1;
-	tracing_power_register();
-
-	tracing_reset_online_cpus(tr);
-	return 0;
-}
-
-static enum print_line_t power_print_line(struct trace_iterator *iter)
-{
-	int ret = 0;
-	struct trace_entry *entry = iter->ent;
-	struct trace_power *field ;
-	struct power_trace *it;
-	struct trace_seq *s = &iter->seq;
-	struct timespec stamp;
-	struct timespec duration;
-
-	trace_assign_type(field, entry);
-	it = &field->state_data;
-	stamp = ktime_to_timespec(it->stamp);
-	duration = ktime_to_timespec(ktime_sub(it->end, it->stamp));
-
-	if (entry->type == TRACE_POWER) {
-		if (it->type == POWER_CSTATE)
-			ret = trace_seq_printf(s, "[%5ld.%09ld] CSTATE: Going to C%i on cpu %i for %ld.%09ld\n",
-					  stamp.tv_sec,
-					  stamp.tv_nsec,
-					  it->state, iter->cpu,
-					  duration.tv_sec,
-					  duration.tv_nsec);
-		if (it->type == POWER_PSTATE)
-			ret = trace_seq_printf(s, "[%5ld.%09ld] PSTATE: Going to P%i on cpu %i\n",
-					  stamp.tv_sec,
-					  stamp.tv_nsec,
-					  it->state, iter->cpu);
-		if (!ret)
-			return TRACE_TYPE_PARTIAL_LINE;
-		return TRACE_TYPE_HANDLED;
-	}
-	return TRACE_TYPE_UNHANDLED;
-}
-
-static void power_print_header(struct seq_file *s)
-{
-	seq_puts(s, "#   TIMESTAMP      STATE  EVENT\n");
-	seq_puts(s, "#       |            |      |\n");
-}
-
-static struct tracer power_tracer __read_mostly =
-{
-	.name		= "power",
-	.init		= power_trace_init,
-	.start		= start_power_trace,
-	.stop		= stop_power_trace,
-	.reset		= power_trace_reset,
-	.print_line	= power_print_line,
-	.print_header	= power_print_header,
-};
-
-static int init_power_trace(void)
-{
-	return register_tracer(&power_tracer);
-}
-device_initcall(init_power_trace);
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 687699d..2547d88 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -11,7 +11,6 @@
 #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>
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index ad69f10..26185d7 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -24,6 +24,7 @@ static int __read_mostly	tracer_enabled;
 
 static struct task_struct	*wakeup_task;
 static int			wakeup_cpu;
+static int			wakeup_current_cpu;
 static unsigned			wakeup_prio = -1;
 static int			wakeup_rt;
 
@@ -56,33 +57,23 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
 	resched = ftrace_preempt_disable();
 
 	cpu = raw_smp_processor_id();
+	if (cpu != wakeup_current_cpu)
+		goto out_enable;
+
 	data = tr->data[cpu];
 	disabled = atomic_inc_return(&data->disabled);
 	if (unlikely(disabled != 1))
 		goto out;
 
 	local_irq_save(flags);
-	__raw_spin_lock(&wakeup_lock);
-
-	if (unlikely(!wakeup_task))
-		goto unlock;
-
-	/*
-	 * The task can't disappear because it needs to
-	 * wake up first, and we have the wakeup_lock.
-	 */
-	if (task_cpu(wakeup_task) != cpu)
-		goto unlock;
 
 	trace_function(tr, ip, parent_ip, flags, pc);
 
- unlock:
-	__raw_spin_unlock(&wakeup_lock);
 	local_irq_restore(flags);
 
  out:
 	atomic_dec(&data->disabled);
-
+ out_enable:
 	ftrace_preempt_enable(resched);
 }
 
@@ -107,11 +98,18 @@ static int report_latency(cycle_t delta)
 	return 1;
 }
 
+static void probe_wakeup_migrate_task(struct task_struct *task, int cpu)
+{
+	if (task != wakeup_task)
+		return;
+
+	wakeup_current_cpu = cpu;
+}
+
 static void notrace
 probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
 	struct task_struct *next)
 {
-	unsigned long latency = 0, t0 = 0, t1 = 0;
 	struct trace_array_cpu *data;
 	cycle_t T0, T1, delta;
 	unsigned long flags;
@@ -157,10 +155,6 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
 	trace_function(wakeup_trace, CALLER_ADDR0, CALLER_ADDR1, flags, pc);
 	tracing_sched_switch_trace(wakeup_trace, prev, next, flags, pc);
 
-	/*
-	 * usecs conversion is slow so we try to delay the conversion
-	 * as long as possible:
-	 */
 	T0 = data->preempt_timestamp;
 	T1 = ftrace_now(cpu);
 	delta = T1-T0;
@@ -168,13 +162,10 @@ probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
 	if (!report_latency(delta))
 		goto out_unlock;
 
-	latency = nsecs_to_usecs(delta);
-
-	tracing_max_latency = delta;
-	t0 = nsecs_to_usecs(T0);
-	t1 = nsecs_to_usecs(T1);
-
-	update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu);
+	if (likely(!is_tracing_stopped())) {
+		tracing_max_latency = delta;
+		update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu);
+	}
 
 out_unlock:
 	__wakeup_reset(wakeup_trace);
@@ -244,6 +235,7 @@ probe_wakeup(struct rq *rq, struct task_struct *p, int success)
 	__wakeup_reset(wakeup_trace);
 
 	wakeup_cpu = task_cpu(p);
+	wakeup_current_cpu = wakeup_cpu;
 	wakeup_prio = p->prio;
 
 	wakeup_task = p;
@@ -293,6 +285,13 @@ static void start_wakeup_tracer(struct trace_array *tr)
 		goto fail_deprobe_wake_new;
 	}
 
+	ret = register_trace_sched_migrate_task(probe_wakeup_migrate_task);
+	if (ret) {
+		pr_info("wakeup trace: Couldn't activate tracepoint"
+			" probe to kernel_sched_migrate_task\n");
+		return;
+	}
+
 	wakeup_reset(tr);
 
 	/*
@@ -325,6 +324,7 @@ static void stop_wakeup_tracer(struct trace_array *tr)
 	unregister_trace_sched_switch(probe_wakeup_sched_switch);
 	unregister_trace_sched_wakeup_new(probe_wakeup);
 	unregister_trace_sched_wakeup(probe_wakeup);
+	unregister_trace_sched_migrate_task(probe_wakeup_migrate_task);
 }
 
 static int __wakeup_tracer_init(struct trace_array *tr)
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 8712ce3..9fbce6c 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -2,7 +2,7 @@
 #include <trace/events/syscalls.h>
 #include <linux/kernel.h>
 #include <linux/ftrace.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <asm/syscall.h>
 
 #include "trace_output.h"
@@ -384,10 +384,13 @@ static int sys_prof_refcount_exit;
 
 static void prof_syscall_enter(struct pt_regs *regs, long id)
 {
-	struct syscall_trace_enter *rec;
 	struct syscall_metadata *sys_data;
+	struct syscall_trace_enter *rec;
+	unsigned long flags;
+	char *raw_data;
 	int syscall_nr;
 	int size;
+	int cpu;
 
 	syscall_nr = syscall_get_nr(current, regs);
 	if (!test_bit(syscall_nr, enabled_prof_enter_syscalls))
@@ -402,20 +405,38 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
 	size = ALIGN(size + sizeof(u32), sizeof(u64));
 	size -= sizeof(u32);
 
-	do {
-		char raw_data[size];
+	if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+		      "profile buffer not large enough"))
+		return;
+
+	/* Protect the per cpu buffer, begin the rcu read side */
+	local_irq_save(flags);
 
-		/* zero the dead bytes from align to not leak stack to user */
-		*(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
+	cpu = smp_processor_id();
+
+	if (in_nmi())
+		raw_data = rcu_dereference(trace_profile_buf_nmi);
+	else
+		raw_data = rcu_dereference(trace_profile_buf);
+
+	if (!raw_data)
+		goto end;
 
-		rec = (struct syscall_trace_enter *) raw_data;
-		tracing_generic_entry_update(&rec->ent, 0, 0);
-		rec->ent.type = sys_data->enter_id;
-		rec->nr = syscall_nr;
-		syscall_get_arguments(current, regs, 0, sys_data->nb_args,
-				       (unsigned long *)&rec->args);
-		perf_tpcounter_event(sys_data->enter_id, 0, 1, rec, size);
-	} while(0);
+	raw_data = per_cpu_ptr(raw_data, cpu);
+
+	/* zero the dead bytes from align to not leak stack to user */
+	*(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
+
+	rec = (struct syscall_trace_enter *) raw_data;
+	tracing_generic_entry_update(&rec->ent, 0, 0);
+	rec->ent.type = sys_data->enter_id;
+	rec->nr = syscall_nr;
+	syscall_get_arguments(current, regs, 0, sys_data->nb_args,
+			       (unsigned long *)&rec->args);
+	perf_tp_event(sys_data->enter_id, 0, 1, rec, size);
+
+end:
+	local_irq_restore(flags);
 }
 
 int reg_prof_syscall_enter(char *name)
@@ -460,8 +481,12 @@ void unreg_prof_syscall_enter(char *name)
 static void prof_syscall_exit(struct pt_regs *regs, long ret)
 {
 	struct syscall_metadata *sys_data;
-	struct syscall_trace_exit rec;
+	struct syscall_trace_exit *rec;
+	unsigned long flags;
 	int syscall_nr;
+	char *raw_data;
+	int size;
+	int cpu;
 
 	syscall_nr = syscall_get_nr(current, regs);
 	if (!test_bit(syscall_nr, enabled_prof_exit_syscalls))
@@ -471,12 +496,46 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
 	if (!sys_data)
 		return;
 
-	tracing_generic_entry_update(&rec.ent, 0, 0);
-	rec.ent.type = sys_data->exit_id;
-	rec.nr = syscall_nr;
-	rec.ret = syscall_get_return_value(current, regs);
+	/* We can probably do that at build time */
+	size = ALIGN(sizeof(*rec) + sizeof(u32), sizeof(u64));
+	size -= sizeof(u32);
 
-	perf_tpcounter_event(sys_data->exit_id, 0, 1, &rec, sizeof(rec));
+	/*
+	 * Impossible, but be paranoid with the future
+	 * How to put this check outside runtime?
+	 */
+	if (WARN_ONCE(size > FTRACE_MAX_PROFILE_SIZE,
+		"exit event has grown above profile buffer size"))
+		return;
+
+	/* Protect the per cpu buffer, begin the rcu read side */
+	local_irq_save(flags);
+	cpu = smp_processor_id();
+
+	if (in_nmi())
+		raw_data = rcu_dereference(trace_profile_buf_nmi);
+	else
+		raw_data = rcu_dereference(trace_profile_buf);
+
+	if (!raw_data)
+		goto end;
+
+	raw_data = per_cpu_ptr(raw_data, cpu);
+
+	/* zero the dead bytes from align to not leak stack to user */
+	*(u64 *)(&raw_data[size - sizeof(u64)]) = 0ULL;
+
+	rec = (struct syscall_trace_exit *)raw_data;
+
+	tracing_generic_entry_update(&rec->ent, 0, 0);
+	rec->ent.type = sys_data->exit_id;
+	rec->nr = syscall_nr;
+	rec->ret = syscall_get_return_value(current, regs);
+
+	perf_tp_event(sys_data->exit_id, 0, 1, rec, size);
+
+end:
+	local_irq_restore(flags);
 }
 
 int reg_prof_syscall_exit(char *name)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7dbd5d9..d57b12f 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -338,7 +338,7 @@ config SLUB_STATS
 
 config DEBUG_KMEMLEAK
 	bool "Kernel memory leak detector"
-	depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM) && \
+	depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM || PPC) && \
 		!MEMORY_HOTPLUG
 	select DEBUG_FS if SYSFS
 	select STACKTRACE if STACKTRACE_SUPPORT
@@ -805,6 +805,21 @@ config DEBUG_BLOCK_EXT_DEVT
 
 	  Say N if you are unsure.
 
+config DEBUG_FORCE_WEAK_PER_CPU
+	bool "Force weak per-cpu definitions"
+	depends on DEBUG_KERNEL
+	help
+	  s390 and alpha require percpu variables in modules to be
+	  defined weak to work around addressing range issue which
+	  puts the following two restrictions on percpu variable
+	  definitions.
+
+	  1. percpu symbols must be unique whether static or not
+	  2. percpu variables can't be defined inside a function
+
+	  To ensure that generic code follows the above rules, this
+	  option forces all percpu variables to be defined as weak.
+
 config LKDTM
 	tristate "Linux Kernel Dump Test Tool Module"
 	depends on DEBUG_KERNEL
diff --git a/lib/inflate.c b/lib/inflate.c
index 1a8e8a9..d102559 100644
--- a/lib/inflate.c
+++ b/lib/inflate.c
@@ -7,7 +7,7 @@
  * Adapted for booting Linux by Hannu Savolainen 1993
  * based on gzip-1.0.3 
  *
- * Nicolas Pitre <nico@cam.org>, 1999/04/14 :
+ * Nicolas Pitre <nico@fluxnic.net>, 1999/04/14 :
  *   Little mods for all variable to reside either into rodata or bss segments
  *   by marking constant variables with 'const' and initializing all the others
  *   at run-time only.  This allows for the kernel uncompressor to run
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 756ccaf..d320c18 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -25,6 +25,7 @@
 #include <linux/kallsyms.h>
 #include <linux/uaccess.h>
 #include <linux/ioport.h>
+#include <net/addrconf.h>
 
 #include <asm/page.h>		/* for PAGE_SIZE */
 #include <asm/div64.h>
@@ -580,7 +581,7 @@ static char *symbol_string(char *buf, char *end, void *ptr,
 	unsigned long value = (unsigned long) ptr;
 #ifdef CONFIG_KALLSYMS
 	char sym[KSYM_SYMBOL_LEN];
-	if (ext != 'f')
+	if (ext != 'f' && ext != 's')
 		sprint_symbol(sym, value);
 	else
 		kallsyms_lookup(value, NULL, NULL, NULL, sym);
@@ -630,60 +631,156 @@ static char *resource_string(char *buf, char *end, struct resource *res,
 }
 
 static char *mac_address_string(char *buf, char *end, u8 *addr,
-				struct printf_spec spec)
+				struct printf_spec spec, const char *fmt)
 {
-	char mac_addr[6 * 3]; /* (6 * 2 hex digits), 5 colons and trailing zero */
+	char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")];
 	char *p = mac_addr;
 	int i;
 
 	for (i = 0; i < 6; i++) {
 		p = pack_hex_byte(p, addr[i]);
-		if (!(spec.flags & SPECIAL) && i != 5)
+		if (fmt[0] == 'M' && i != 5)
 			*p++ = ':';
 	}
 	*p = '\0';
-	spec.flags &= ~SPECIAL;
 
 	return string(buf, end, mac_addr, spec);
 }
 
-static char *ip6_addr_string(char *buf, char *end, u8 *addr,
-				struct printf_spec spec)
+static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)
 {
-	char ip6_addr[8 * 5]; /* (8 * 4 hex digits), 7 colons and trailing zero */
-	char *p = ip6_addr;
 	int i;
 
+	for (i = 0; i < 4; i++) {
+		char temp[3];	/* hold each IP quad in reverse order */
+		int digits = put_dec_trunc(temp, addr[i]) - temp;
+		if (leading_zeros) {
+			if (digits < 3)
+				*p++ = '0';
+			if (digits < 2)
+				*p++ = '0';
+		}
+		/* reverse the digits in the quad */
+		while (digits--)
+			*p++ = temp[digits];
+		if (i < 3)
+			*p++ = '.';
+	}
+
+	*p = '\0';
+	return p;
+}
+
+static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
+{
+	int i;
+	int j;
+	int range;
+	unsigned char zerolength[8];
+	int longest = 1;
+	int colonpos = -1;
+	u16 word;
+	u8 hi;
+	u8 lo;
+	bool needcolon = false;
+	bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr);
+
+	memset(zerolength, 0, sizeof(zerolength));
+
+	if (useIPv4)
+		range = 6;
+	else
+		range = 8;
+
+	/* find position of longest 0 run */
+	for (i = 0; i < range; i++) {
+		for (j = i; j < range; j++) {
+			if (addr->s6_addr16[j] != 0)
+				break;
+			zerolength[i]++;
+		}
+	}
+	for (i = 0; i < range; i++) {
+		if (zerolength[i] > longest) {
+			longest = zerolength[i];
+			colonpos = i;
+		}
+	}
+
+	/* emit address */
+	for (i = 0; i < range; i++) {
+		if (i == colonpos) {
+			if (needcolon || i == 0)
+				*p++ = ':';
+			*p++ = ':';
+			needcolon = false;
+			i += longest - 1;
+			continue;
+		}
+		if (needcolon) {
+			*p++ = ':';
+			needcolon = false;
+		}
+		/* hex u16 without leading 0s */
+		word = ntohs(addr->s6_addr16[i]);
+		hi = word >> 8;
+		lo = word & 0xff;
+		if (hi) {
+			if (hi > 0x0f)
+				p = pack_hex_byte(p, hi);
+			else
+				*p++ = hex_asc_lo(hi);
+		}
+		if (hi || lo > 0x0f)
+			p = pack_hex_byte(p, lo);
+		else
+			*p++ = hex_asc_lo(lo);
+		needcolon = true;
+	}
+
+	if (useIPv4) {
+		if (needcolon)
+			*p++ = ':';
+		p = ip4_string(p, &addr->s6_addr[12], false);
+	}
+
+	*p = '\0';
+	return p;
+}
+
+static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt)
+{
+	int i;
 	for (i = 0; i < 8; i++) {
-		p = pack_hex_byte(p, addr[2 * i]);
-		p = pack_hex_byte(p, addr[2 * i + 1]);
-		if (!(spec.flags & SPECIAL) && i != 7)
+		p = pack_hex_byte(p, addr->s6_addr[2 * i]);
+		p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]);
+		if (fmt[0] == 'I' && i != 7)
 			*p++ = ':';
 	}
+
 	*p = '\0';
-	spec.flags &= ~SPECIAL;
+	return p;
+}
+
+static char *ip6_addr_string(char *buf, char *end, const u8 *addr,
+			     struct printf_spec spec, const char *fmt)
+{
+	char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
+
+	if (fmt[0] == 'I' && fmt[2] == 'c')
+		ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr);
+	else
+		ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt);
 
 	return string(buf, end, ip6_addr, spec);
 }
 
-static char *ip4_addr_string(char *buf, char *end, u8 *addr,
-				struct printf_spec spec)
+static char *ip4_addr_string(char *buf, char *end, const u8 *addr,
+			     struct printf_spec spec, const char *fmt)
 {
-	char ip4_addr[4 * 4]; /* (4 * 3 decimal digits), 3 dots and trailing zero */
-	char temp[3];	/* hold each IP quad in reverse order */
-	char *p = ip4_addr;
-	int i, digits;
+	char ip4_addr[sizeof("255.255.255.255")];
 
-	for (i = 0; i < 4; i++) {
-		digits = put_dec_trunc(temp, addr[i]) - temp;
-		/* reverse the digits in the quad */
-		while (digits--)
-			*p++ = temp[digits];
-		if (i != 3)
-			*p++ = '.';
-	}
-	*p = '\0';
-	spec.flags &= ~SPECIAL;
+	ip4_string(ip4_addr, addr, fmt[0] == 'i');
 
 	return string(buf, end, ip4_addr, spec);
 }
@@ -697,16 +794,21 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr,
  *
  * - 'F' For symbolic function descriptor pointers with offset
  * - 'f' For simple symbolic function names without offset
- * - 'S' For symbolic direct pointers
+ * - 'S' For symbolic direct pointers with offset
+ * - 's' For symbolic direct pointers without offset
  * - 'R' For a struct resource pointer, it prints the range of
  *       addresses (not the name nor the flags)
  * - 'M' For a 6-byte MAC address, it prints the address in the
  *       usual colon-separated hex notation
- * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way (dot-separated
- *       decimal for v4 and colon separated network-order 16 bit hex for v6)
- * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is
- *       currently the same
- *
+ * - 'm' For a 6-byte MAC address, it prints the hex address without colons
+ * - 'I' [46] for IPv4/IPv6 addresses printed in the usual way
+ *       IPv4 uses dot-separated decimal without leading 0's (1.2.3.4)
+ *       IPv6 uses colon separated network-order 16 bit hex with leading 0's
+ * - 'i' [46] for 'raw' IPv4/IPv6 addresses
+ *       IPv6 omits the colons (01020304...0f)
+ *       IPv4 uses dot-separated decimal with leading 0's (010.123.045.006)
+ * - 'I6c' for IPv6 addresses printed as specified by
+ *       http://www.ietf.org/id/draft-kawamura-ipv6-text-representation-03.txt
  * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
  * function pointers are really function descriptors, which contain a
  * pointer to the real address.
@@ -721,25 +823,30 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr,
 	case 'F':
 	case 'f':
 		ptr = dereference_function_descriptor(ptr);
+	case 's':
 		/* Fallthrough */
 	case 'S':
 		return symbol_string(buf, end, ptr, spec, *fmt);
 	case 'R':
 		return resource_string(buf, end, ptr, spec);
-	case 'm':
-		spec.flags |= SPECIAL;
-		/* Fallthrough */
-	case 'M':
-		return mac_address_string(buf, end, ptr, spec);
-	case 'i':
-		spec.flags |= SPECIAL;
-		/* Fallthrough */
-	case 'I':
-		if (fmt[1] == '6')
-			return ip6_addr_string(buf, end, ptr, spec);
-		if (fmt[1] == '4')
-			return ip4_addr_string(buf, end, ptr, spec);
-		spec.flags &= ~SPECIAL;
+	case 'M':			/* Colon separated: 00:01:02:03:04:05 */
+	case 'm':			/* Contiguous: 000102030405 */
+		return mac_address_string(buf, end, ptr, spec, fmt);
+	case 'I':			/* Formatted IP supported
+					 * 4:	1.2.3.4
+					 * 6:	0001:0203:...:0708
+					 * 6c:	1::708 or 1::1.2.3.4
+					 */
+	case 'i':			/* Contiguous:
+					 * 4:	001.002.003.004
+					 * 6:   000102...0f
+					 */
+		switch (fmt[1]) {
+		case '6':
+			return ip6_addr_string(buf, end, ptr, spec, fmt);
+		case '4':
+			return ip4_addr_string(buf, end, ptr, spec, fmt);
+		}
 		break;
 	}
 	spec.flags |= SMALL;
@@ -958,10 +1065,12 @@ qualifier:
  * @args: Arguments for the format string
  *
  * This function follows C99 vsnprintf, but has some extensions:
- * %pS output the name of a text symbol
+ * %pS output the name of a text symbol with offset
+ * %ps output the name of a text symbol without offset
  * %pF output the name of a function pointer with its offset
  * %pf output the name of a function pointer without its offset
  * %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
@@ -1417,11 +1526,7 @@ EXPORT_SYMBOL_GPL(vbin_printf);
  * 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 with its offset
- * %pf output the name of a function pointer without its offset
- * %pR output the address range in a struct resource
- * %n is ignored
+ *  see vsnprintf comment for details.
  *
  * The return value is the number of characters which would
  * be generated for the given input, excluding the trailing
diff --git a/mm/Kconfig b/mm/Kconfig
index fe5f674..3aa519f 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -153,7 +153,7 @@ config MEMORY_HOTREMOVE
 #
 config PAGEFLAGS_EXTENDED
 	def_bool y
-	depends on 64BIT || SPARSEMEM_VMEMMAP || !NUMA || !SPARSEMEM
+	depends on 64BIT || SPARSEMEM_VMEMMAP || !SPARSEMEM
 
 # Heavily threaded applications may benefit from splitting the mm-wide
 # page_table_lock, so that faults on different parts of the user address
diff --git a/mm/Makefile b/mm/Makefile
index 147a7a7..ea4b18b 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -33,7 +33,7 @@ obj-$(CONFIG_FAILSLAB) += failslab.o
 obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
 obj-$(CONFIG_FS_XIP) += filemap_xip.o
 obj-$(CONFIG_MIGRATION) += migrate.o
-ifdef CONFIG_HAVE_DYNAMIC_PER_CPU_AREA
+ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA
 obj-$(CONFIG_SMP) += percpu.o
 else
 obj-$(CONFIG_SMP) += allocpercpu.o
diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c
index dfdee6a..df34cea 100644
--- a/mm/allocpercpu.c
+++ b/mm/allocpercpu.c
@@ -5,6 +5,8 @@
  */
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/bootmem.h>
+#include <asm/sections.h>
 
 #ifndef cache_line_size
 #define cache_line_size()	L1_CACHE_BYTES
@@ -147,3 +149,29 @@ void free_percpu(void *__pdata)
 	kfree(__percpu_disguise(__pdata));
 }
 EXPORT_SYMBOL_GPL(free_percpu);
+
+/*
+ * Generic percpu area setup.
+ */
+#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
+
+EXPORT_SYMBOL(__per_cpu_offset);
+
+void __init setup_per_cpu_areas(void)
+{
+	unsigned long size, i;
+	char *ptr;
+	unsigned long nr_possible_cpus = num_possible_cpus();
+
+	/* Copy section for each CPU (we discard the original) */
+	size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
+	ptr = alloc_bootmem_pages(size * nr_possible_cpus);
+
+	for_each_possible_cpu(i) {
+		__per_cpu_offset[i] = ptr - __per_cpu_start;
+		memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+		ptr += size;
+	}
+}
+#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index d3ca0da..3d3accb 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -26,6 +26,12 @@ struct backing_dev_info default_backing_dev_info = {
 EXPORT_SYMBOL_GPL(default_backing_dev_info);
 
 static struct class *bdi_class;
+
+/*
+ * bdi_lock protects updates to bdi_list and bdi_pending_list, as well as
+ * reader side protection for bdi_pending_list. bdi_list has RCU reader side
+ * locking.
+ */
 DEFINE_SPINLOCK(bdi_lock);
 LIST_HEAD(bdi_list);
 LIST_HEAD(bdi_pending_list);
@@ -284,9 +290,9 @@ static int bdi_start_fn(void *ptr)
 	/*
 	 * Add us to the active bdi_list
 	 */
-	spin_lock(&bdi_lock);
-	list_add(&bdi->bdi_list, &bdi_list);
-	spin_unlock(&bdi_lock);
+	spin_lock_bh(&bdi_lock);
+	list_add_rcu(&bdi->bdi_list, &bdi_list);
+	spin_unlock_bh(&bdi_lock);
 
 	bdi_task_init(bdi, wb);
 
@@ -389,7 +395,7 @@ static int bdi_forker_task(void *ptr)
 		if (wb_has_dirty_io(me) || !list_empty(&me->bdi->work_list))
 			wb_do_writeback(me, 0);
 
-		spin_lock(&bdi_lock);
+		spin_lock_bh(&bdi_lock);
 
 		/*
 		 * Check if any existing bdi's have dirty data without
@@ -410,7 +416,7 @@ static int bdi_forker_task(void *ptr)
 		if (list_empty(&bdi_pending_list)) {
 			unsigned long wait;
 
-			spin_unlock(&bdi_lock);
+			spin_unlock_bh(&bdi_lock);
 			wait = msecs_to_jiffies(dirty_writeback_interval * 10);
 			schedule_timeout(wait);
 			try_to_freeze();
@@ -426,7 +432,7 @@ static int bdi_forker_task(void *ptr)
 		bdi = list_entry(bdi_pending_list.next, struct backing_dev_info,
 				 bdi_list);
 		list_del_init(&bdi->bdi_list);
-		spin_unlock(&bdi_lock);
+		spin_unlock_bh(&bdi_lock);
 
 		wb = &bdi->wb;
 		wb->task = kthread_run(bdi_start_fn, wb, "flush-%s",
@@ -445,9 +451,9 @@ static int bdi_forker_task(void *ptr)
 			 * a chance to flush other bdi's to free
 			 * memory.
 			 */
-			spin_lock(&bdi_lock);
+			spin_lock_bh(&bdi_lock);
 			list_add_tail(&bdi->bdi_list, &bdi_pending_list);
-			spin_unlock(&bdi_lock);
+			spin_unlock_bh(&bdi_lock);
 
 			bdi_flush_io(bdi);
 		}
@@ -456,6 +462,24 @@ static int bdi_forker_task(void *ptr)
 	return 0;
 }
 
+static void bdi_add_to_pending(struct rcu_head *head)
+{
+	struct backing_dev_info *bdi;
+
+	bdi = container_of(head, struct backing_dev_info, rcu_head);
+	INIT_LIST_HEAD(&bdi->bdi_list);
+
+	spin_lock(&bdi_lock);
+	list_add_tail(&bdi->bdi_list, &bdi_pending_list);
+	spin_unlock(&bdi_lock);
+
+	/*
+	 * We are now on the pending list, wake up bdi_forker_task()
+	 * to finish the job and add us back to the active bdi_list
+	 */
+	wake_up_process(default_backing_dev_info.wb.task);
+}
+
 /*
  * Add the default flusher task that gets created for any bdi
  * that has dirty data pending writeout
@@ -478,16 +502,29 @@ void static bdi_add_default_flusher_task(struct backing_dev_info *bdi)
 	 * waiting for previous additions to finish.
 	 */
 	if (!test_and_set_bit(BDI_pending, &bdi->state)) {
-		list_move_tail(&bdi->bdi_list, &bdi_pending_list);
+		list_del_rcu(&bdi->bdi_list);
 
 		/*
-		 * We are now on the pending list, wake up bdi_forker_task()
-		 * to finish the job and add us back to the active bdi_list
+		 * We must wait for the current RCU period to end before
+		 * moving to the pending list. So schedule that operation
+		 * from an RCU callback.
 		 */
-		wake_up_process(default_backing_dev_info.wb.task);
+		call_rcu(&bdi->rcu_head, bdi_add_to_pending);
 	}
 }
 
+/*
+ * Remove bdi from bdi_list, and ensure that it is no longer visible
+ */
+static void bdi_remove_from_list(struct backing_dev_info *bdi)
+{
+	spin_lock_bh(&bdi_lock);
+	list_del_rcu(&bdi->bdi_list);
+	spin_unlock_bh(&bdi_lock);
+
+	synchronize_rcu();
+}
+
 int bdi_register(struct backing_dev_info *bdi, struct device *parent,
 		const char *fmt, ...)
 {
@@ -506,9 +543,9 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
 		goto exit;
 	}
 
-	spin_lock(&bdi_lock);
-	list_add_tail(&bdi->bdi_list, &bdi_list);
-	spin_unlock(&bdi_lock);
+	spin_lock_bh(&bdi_lock);
+	list_add_tail_rcu(&bdi->bdi_list, &bdi_list);
+	spin_unlock_bh(&bdi_lock);
 
 	bdi->dev = dev;
 
@@ -526,9 +563,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
 			wb->task = NULL;
 			ret = -ENOMEM;
 
-			spin_lock(&bdi_lock);
-			list_del(&bdi->bdi_list);
-			spin_unlock(&bdi_lock);
+			bdi_remove_from_list(bdi);
 			goto exit;
 		}
 	}
@@ -565,9 +600,7 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
 	/*
 	 * Make sure nobody finds us on the bdi_list anymore
 	 */
-	spin_lock(&bdi_lock);
-	list_del(&bdi->bdi_list);
-	spin_unlock(&bdi_lock);
+	bdi_remove_from_list(bdi);
 
 	/*
 	 * Finally, kill the kernel threads. We don't need to be RCU
@@ -599,6 +632,7 @@ int bdi_init(struct backing_dev_info *bdi)
 	bdi->max_ratio = 100;
 	bdi->max_prop_frac = PROP_FRAC_BASE;
 	spin_lock_init(&bdi->wb_lock);
+	INIT_RCU_HEAD(&bdi->rcu_head);
 	INIT_LIST_HEAD(&bdi->bdi_list);
 	INIT_LIST_HEAD(&bdi->wb_list);
 	INIT_LIST_HEAD(&bdi->work_list);
@@ -634,7 +668,19 @@ void bdi_destroy(struct backing_dev_info *bdi)
 {
 	int i;
 
-	WARN_ON(bdi_has_dirty_io(bdi));
+	/*
+	 * Splice our entries to the default_backing_dev_info, if this
+	 * bdi disappears
+	 */
+	if (bdi_has_dirty_io(bdi)) {
+		struct bdi_writeback *dst = &default_backing_dev_info.wb;
+
+		spin_lock(&inode_lock);
+		list_splice(&bdi->wb.b_dirty, &dst->b_dirty);
+		list_splice(&bdi->wb.b_io, &dst->b_io);
+		list_splice(&bdi->wb.b_more_io, &dst->b_more_io);
+		spin_unlock(&inode_lock);
+	}
 
 	bdi_unregister(bdi);
 
diff --git a/mm/filemap.c b/mm/filemap.c
index ccea3b6..dd51c68 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -39,11 +39,10 @@
 /*
  * FIXME: remove all knowledge of the buffer layer from the core VM
  */
-#include <linux/buffer_head.h> /* for generic_osync_inode */
+#include <linux/buffer_head.h> /* for try_to_free_buffers */
 
 #include <asm/mman.h>
 
-
 /*
  * Shared mappings implemented 30.11.1994. It's not fully working yet,
  * though.
@@ -307,68 +306,24 @@ int wait_on_page_writeback_range(struct address_space *mapping,
 }
 
 /**
- * sync_page_range - write and wait on all pages in the passed range
- * @inode:	target inode
- * @mapping:	target address_space
- * @pos:	beginning offset in pages to write
- * @count:	number of bytes to write
- *
- * Write and wait upon all the pages in the passed range.  This is a "data
- * integrity" operation.  It waits upon in-flight writeout before starting and
- * waiting upon new writeout.  If there was an IO error, return it.
+ * filemap_fdatawait_range - wait for all under-writeback pages to complete in a given range
+ * @mapping: address space structure to wait for
+ * @start:	offset in bytes where the range starts
+ * @end:	offset in bytes where the range ends (inclusive)
  *
- * We need to re-take i_mutex during the generic_osync_inode list walk because
- * it is otherwise livelockable.
- */
-int sync_page_range(struct inode *inode, struct address_space *mapping,
-			loff_t pos, loff_t count)
-{
-	pgoff_t start = pos >> PAGE_CACHE_SHIFT;
-	pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
-	int ret;
-
-	if (!mapping_cap_writeback_dirty(mapping) || !count)
-		return 0;
-	ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
-	if (ret == 0) {
-		mutex_lock(&inode->i_mutex);
-		ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
-		mutex_unlock(&inode->i_mutex);
-	}
-	if (ret == 0)
-		ret = wait_on_page_writeback_range(mapping, start, end);
-	return ret;
-}
-EXPORT_SYMBOL(sync_page_range);
-
-/**
- * sync_page_range_nolock - write & wait on all pages in the passed range without locking
- * @inode:	target inode
- * @mapping:	target address_space
- * @pos:	beginning offset in pages to write
- * @count:	number of bytes to write
+ * Walk the list of under-writeback pages of the given address space
+ * in the given range and wait for all of them.
  *
- * Note: Holding i_mutex across sync_page_range_nolock() is not a good idea
- * as it forces O_SYNC writers to different parts of the same file
- * to be serialised right until io completion.
+ * This is just a simple wrapper so that callers don't have to convert offsets
+ * to page indexes themselves
  */
-int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
-			   loff_t pos, loff_t count)
+int filemap_fdatawait_range(struct address_space *mapping, loff_t start,
+			    loff_t end)
 {
-	pgoff_t start = pos >> PAGE_CACHE_SHIFT;
-	pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
-	int ret;
-
-	if (!mapping_cap_writeback_dirty(mapping) || !count)
-		return 0;
-	ret = filemap_fdatawrite_range(mapping, pos, pos + count - 1);
-	if (ret == 0)
-		ret = generic_osync_inode(inode, mapping, OSYNC_METADATA);
-	if (ret == 0)
-		ret = wait_on_page_writeback_range(mapping, start, end);
-	return ret;
+	return wait_on_page_writeback_range(mapping, start >> PAGE_CACHE_SHIFT,
+					    end >> PAGE_CACHE_SHIFT);
 }
-EXPORT_SYMBOL(sync_page_range_nolock);
+EXPORT_SYMBOL(filemap_fdatawait_range);
 
 /**
  * filemap_fdatawait - wait for all under-writeback pages to complete
@@ -2167,20 +2122,7 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
 		}
 		*ppos = end;
 	}
-
-	/*
-	 * Sync the fs metadata but not the minor inode changes and
-	 * of course not the data as we did direct DMA for the IO.
-	 * i_mutex is held, which protects generic_osync_inode() from
-	 * livelocking.  AIO O_DIRECT ops attempt to sync metadata here.
-	 */
 out:
-	if ((written >= 0 || written == -EIOCBQUEUED) &&
-	    ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-		int err = generic_osync_inode(inode, mapping, OSYNC_METADATA);
-		if (err < 0)
-			written = err;
-	}
 	return written;
 }
 EXPORT_SYMBOL(generic_file_direct_write);
@@ -2312,8 +2254,6 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
 {
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
-	const struct address_space_operations *a_ops = mapping->a_ops;
-	struct inode *inode = mapping->host;
 	ssize_t status;
 	struct iov_iter i;
 
@@ -2323,16 +2263,6 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
 	if (likely(status >= 0)) {
 		written += status;
 		*ppos = pos + status;
-
-		/*
-		 * For now, when the user asks for O_SYNC, we'll actually give
-		 * O_DSYNC
-		 */
-		if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-			if (!a_ops->writepage || !is_sync_kiocb(iocb))
-				status = generic_osync_inode(inode, mapping,
-						OSYNC_METADATA|OSYNC_DATA);
-		}
   	}
 	
 	/*
@@ -2348,9 +2278,27 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
 }
 EXPORT_SYMBOL(generic_file_buffered_write);
 
-static ssize_t
-__generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
-				unsigned long nr_segs, loff_t *ppos)
+/**
+ * __generic_file_aio_write - write data to a file
+ * @iocb:	IO state structure (file, offset, etc.)
+ * @iov:	vector with data to write
+ * @nr_segs:	number of segments in the vector
+ * @ppos:	position where to write
+ *
+ * This function does all the work needed for actually writing data to a
+ * file. It does all basic checks, removes SUID from the file, updates
+ * modification times and calls proper subroutines depending on whether we
+ * do direct IO or a standard buffered write.
+ *
+ * It expects i_mutex to be grabbed unless we work on a block device or similar
+ * object which does not need locking at all.
+ *
+ * This function does *not* take care of syncing data in case of O_SYNC write.
+ * A caller has to handle it. This is mainly due to the fact that we want to
+ * avoid syncing under i_mutex.
+ */
+ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+				 unsigned long nr_segs, loff_t *ppos)
 {
 	struct file *file = iocb->ki_filp;
 	struct address_space * mapping = file->f_mapping;
@@ -2447,51 +2395,37 @@ out:
 	current->backing_dev_info = NULL;
 	return written ? written : err;
 }
+EXPORT_SYMBOL(__generic_file_aio_write);
 
-ssize_t generic_file_aio_write_nolock(struct kiocb *iocb,
-		const struct iovec *iov, unsigned long nr_segs, loff_t pos)
-{
-	struct file *file = iocb->ki_filp;
-	struct address_space *mapping = file->f_mapping;
-	struct inode *inode = mapping->host;
-	ssize_t ret;
-
-	BUG_ON(iocb->ki_pos != pos);
-
-	ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs,
-			&iocb->ki_pos);
-
-	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
-		ssize_t err;
-
-		err = sync_page_range_nolock(inode, mapping, pos, ret);
-		if (err < 0)
-			ret = err;
-	}
-	return ret;
-}
-EXPORT_SYMBOL(generic_file_aio_write_nolock);
-
+/**
+ * generic_file_aio_write - write data to a file
+ * @iocb:	IO state structure
+ * @iov:	vector with data to write
+ * @nr_segs:	number of segments in the vector
+ * @pos:	position in file where to write
+ *
+ * This is a wrapper around __generic_file_aio_write() to be used by most
+ * filesystems. It takes care of syncing the file in case of O_SYNC file
+ * and acquires i_mutex as needed.
+ */
 ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 		unsigned long nr_segs, loff_t pos)
 {
 	struct file *file = iocb->ki_filp;
-	struct address_space *mapping = file->f_mapping;
-	struct inode *inode = mapping->host;
+	struct inode *inode = file->f_mapping->host;
 	ssize_t ret;
 
 	BUG_ON(iocb->ki_pos != pos);
 
 	mutex_lock(&inode->i_mutex);
-	ret = __generic_file_aio_write_nolock(iocb, iov, nr_segs,
-			&iocb->ki_pos);
+	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
 	mutex_unlock(&inode->i_mutex);
 
-	if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+	if (ret > 0 || ret == -EIOCBQUEUED) {
 		ssize_t err;
 
-		err = sync_page_range(inode, mapping, pos, ret);
-		if (err < 0)
+		err = generic_write_sync(file, pos, ret);
+		if (err < 0 && ret > 0)
 			ret = err;
 	}
 	return ret;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index cafdcee..b16d636 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -234,6 +234,7 @@ unsigned long vma_kernel_pagesize(struct vm_area_struct *vma)
 
 	return 1UL << (hstate->order + PAGE_SHIFT);
 }
+EXPORT_SYMBOL_GPL(vma_kernel_pagesize);
 
 /*
  * Return the page size being used by the MMU to back a VMA. In the majority
diff --git a/mm/kmemleak-test.c b/mm/kmemleak-test.c
index d5292fc..177a516 100644
--- a/mm/kmemleak-test.c
+++ b/mm/kmemleak-test.c
@@ -36,7 +36,7 @@ struct test_node {
 };
 
 static LIST_HEAD(test_list);
-static DEFINE_PER_CPU(void *, test_pointer);
+static DEFINE_PER_CPU(void *, kmemleak_test_pointer);
 
 /*
  * Some very simple testing. This function needs to be extended for
@@ -86,9 +86,9 @@ static int __init kmemleak_test_init(void)
 	}
 
 	for_each_possible_cpu(i) {
-		per_cpu(test_pointer, i) = kmalloc(129, GFP_KERNEL);
+		per_cpu(kmemleak_test_pointer, i) = kmalloc(129, GFP_KERNEL);
 		pr_info("kmemleak: kmalloc(129) = %p\n",
-			per_cpu(test_pointer, i));
+			per_cpu(kmemleak_test_pointer, i));
 	}
 
 	return 0;
diff --git a/mm/memory.c b/mm/memory.c
index aede2ce..e8f63d9 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -56,6 +56,7 @@
 #include <linux/swapops.h>
 #include <linux/elf.h>
 
+#include <asm/io.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
diff --git a/mm/mmap.c b/mm/mmap.c
index 8101de4..376492e 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -28,7 +28,7 @@
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
 #include <linux/mmu_notifier.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 
 #include <asm/uaccess.h>
 #include <asm/cacheflush.h>
@@ -905,7 +905,7 @@ void vm_stat_account(struct mm_struct *mm, unsigned long flags,
 #endif /* CONFIG_PROC_FS */
 
 /*
- * The caller must hold down_write(current->mm->mmap_sem).
+ * The caller must hold down_write(&current->mm->mmap_sem).
  */
 
 unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
@@ -1220,7 +1220,7 @@ munmap_back:
 	if (correct_wcount)
 		atomic_inc(&inode->i_writecount);
 out:
-	perf_counter_mmap(vma);
+	perf_event_mmap(vma);
 
 	mm->total_vm += len >> PAGE_SHIFT;
 	vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
@@ -2308,7 +2308,7 @@ int install_special_mapping(struct mm_struct *mm,
 
 	mm->total_vm += len >> PAGE_SHIFT;
 
-	perf_counter_mmap(vma);
+	perf_event_mmap(vma);
 
 	return 0;
 }
diff --git a/mm/mprotect.c b/mm/mprotect.c
index d80311b..8bc969d 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -23,7 +23,7 @@
 #include <linux/swapops.h>
 #include <linux/mmu_notifier.h>
 #include <linux/migrate.h>
-#include <linux/perf_counter.h>
+#include <linux/perf_event.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
@@ -300,7 +300,7 @@ SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len,
 		error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
 		if (error)
 			goto out;
-		perf_counter_mmap(vma);
+		perf_event_mmap(vma);
 		nstart = tmp;
 
 		if (nstart < prev->vm_end)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 25e7770..d1ba464 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -315,7 +315,7 @@ int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio)
 {
 	int ret = 0;
 
-	spin_lock(&bdi_lock);
+	spin_lock_bh(&bdi_lock);
 	if (min_ratio > bdi->max_ratio) {
 		ret = -EINVAL;
 	} else {
@@ -327,7 +327,7 @@ int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio)
 			ret = -EINVAL;
 		}
 	}
-	spin_unlock(&bdi_lock);
+	spin_unlock_bh(&bdi_lock);
 
 	return ret;
 }
@@ -339,14 +339,14 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned max_ratio)
 	if (max_ratio > 100)
 		return -EINVAL;
 
-	spin_lock(&bdi_lock);
+	spin_lock_bh(&bdi_lock);
 	if (bdi->min_ratio > max_ratio) {
 		ret = -EINVAL;
 	} else {
 		bdi->max_ratio = max_ratio;
 		bdi->max_prop_frac = (PROP_FRAC_BASE * max_ratio) / 100;
 	}
-	spin_unlock(&bdi_lock);
+	spin_unlock_bh(&bdi_lock);
 
 	return ret;
 }
@@ -485,6 +485,7 @@ static void balance_dirty_pages(struct address_space *mapping)
 	unsigned long bdi_thresh;
 	unsigned long pages_written = 0;
 	unsigned long write_chunk = sync_writeback_pages();
+	unsigned long pause = 1;
 
 	struct backing_dev_info *bdi = mapping->backing_dev_info;
 
@@ -561,7 +562,15 @@ static void balance_dirty_pages(struct address_space *mapping)
 		if (pages_written >= write_chunk)
 			break;		/* We've done our duty */
 
-		schedule_timeout(1);
+		schedule_timeout_interruptible(pause);
+
+		/*
+		 * Increase the delay for each loop, up to our previous
+		 * default of taking a 100ms nap.
+		 */
+		pause <<= 1;
+		if (pause > HZ / 10)
+			pause = HZ / 10;
 	}
 
 	if (bdi_nr_reclaimable + bdi_nr_writeback < bdi_thresh &&
@@ -582,16 +591,8 @@ static void balance_dirty_pages(struct address_space *mapping)
 	if ((laptop_mode && pages_written) ||
 	    (!laptop_mode && ((nr_writeback = global_page_state(NR_FILE_DIRTY)
 					  + global_page_state(NR_UNSTABLE_NFS))
-					  > background_thresh))) {
-		struct writeback_control wbc = {
-			.bdi		= bdi,
-			.sync_mode	= WB_SYNC_NONE,
-			.nr_to_write	= nr_writeback,
-		};
-
-
-		bdi_start_writeback(&wbc);
-	}
+					  > background_thresh)))
+		bdi_start_writeback(bdi, nr_writeback);
 }
 
 void set_page_dirty_balance(struct page *page, int page_mkwrite)
@@ -604,6 +605,8 @@ void set_page_dirty_balance(struct page *page, int page_mkwrite)
 	}
 }
 
+static DEFINE_PER_CPU(unsigned long, bdp_ratelimits) = 0;
+
 /**
  * balance_dirty_pages_ratelimited_nr - balance dirty memory state
  * @mapping: address_space which was dirtied
@@ -621,7 +624,6 @@ void set_page_dirty_balance(struct page *page, int page_mkwrite)
 void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
 					unsigned long nr_pages_dirtied)
 {
-	static DEFINE_PER_CPU(unsigned long, ratelimits) = 0;
 	unsigned long ratelimit;
 	unsigned long *p;
 
@@ -634,7 +636,7 @@ void balance_dirty_pages_ratelimited_nr(struct address_space *mapping,
 	 * tasks in balance_dirty_pages(). Period.
 	 */
 	preempt_disable();
-	p =  &__get_cpu_var(ratelimits);
+	p =  &__get_cpu_var(bdp_ratelimits);
 	*p += nr_pages_dirtied;
 	if (unlikely(*p >= ratelimit)) {
 		*p = 0;
@@ -1019,12 +1021,10 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
 
 	if (wbc->nr_to_write <= 0)
 		return 0;
-	wbc->for_writepages = 1;
 	if (mapping->a_ops->writepages)
 		ret = mapping->a_ops->writepages(mapping, wbc);
 	else
 		ret = generic_writepages(mapping, wbc);
-	wbc->for_writepages = 0;
 	return ret;
 }
 
diff --git a/mm/percpu.c b/mm/percpu.c
index 3311c89..43d8cac 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -8,12 +8,13 @@
  *
  * This is percpu allocator which can handle both static and dynamic
  * areas.  Percpu areas are allocated in chunks in vmalloc area.  Each
- * chunk is consisted of nr_cpu_ids units and the first chunk is used
- * for static percpu variables in the kernel image (special boot time
- * alloc/init handling necessary as these areas need to be brought up
- * before allocation services are running).  Unit grows as necessary
- * and all units grow or shrink in unison.  When a chunk is filled up,
- * another chunk is allocated.  ie. in vmalloc area
+ * chunk is consisted of boot-time determined number of units and the
+ * first chunk is used for static percpu variables in the kernel image
+ * (special boot time alloc/init handling necessary as these areas
+ * need to be brought up before allocation services are running).
+ * Unit grows as necessary and all units grow or shrink in unison.
+ * When a chunk is filled up, another chunk is allocated.  ie. in
+ * vmalloc area
  *
  *  c0                           c1                         c2
  *  -------------------          -------------------        ------------
@@ -22,11 +23,13 @@
  *
  * Allocation is done in offset-size areas of single unit space.  Ie,
  * an area of 512 bytes at 6k in c1 occupies 512 bytes at 6k of c1:u0,
- * c1:u1, c1:u2 and c1:u3.  Percpu access can be done by configuring
- * percpu base registers pcpu_unit_size apart.
+ * c1:u1, c1:u2 and c1:u3.  On UMA, units corresponds directly to
+ * cpus.  On NUMA, the mapping can be non-linear and even sparse.
+ * Percpu access can be done by configuring percpu base registers
+ * according to cpu to unit mapping and pcpu_unit_size.
  *
- * There are usually many small percpu allocations many of them as
- * small as 4 bytes.  The allocator organizes chunks into lists
+ * There are usually many small percpu allocations many of them being
+ * as small as 4 bytes.  The allocator organizes chunks into lists
  * according to free size and tries to allocate from the fullest one.
  * Each chunk keeps the maximum contiguous area size hint which is
  * guaranteed to be eqaul to or larger than the maximum contiguous
@@ -43,7 +46,7 @@
  *
  * To use this allocator, arch code should do the followings.
  *
- * - define CONFIG_HAVE_DYNAMIC_PER_CPU_AREA
+ * - drop CONFIG_HAVE_LEGACY_PER_CPU_AREA
  *
  * - define __addr_to_pcpu_ptr() and __pcpu_ptr_to_addr() to translate
  *   regular address to percpu pointer and back if they need to be
@@ -55,7 +58,9 @@
 
 #include <linux/bitmap.h>
 #include <linux/bootmem.h>
+#include <linux/err.h>
 #include <linux/list.h>
+#include <linux/log2.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -89,25 +94,38 @@ struct pcpu_chunk {
 	struct list_head	list;		/* linked to pcpu_slot lists */
 	int			free_size;	/* free bytes in the chunk */
 	int			contig_hint;	/* max contiguous size hint */
-	struct vm_struct	*vm;		/* mapped vmalloc region */
+	void			*base_addr;	/* base address of this chunk */
 	int			map_used;	/* # of map entries used */
 	int			map_alloc;	/* # of map entries allocated */
 	int			*map;		/* allocation map */
+	struct vm_struct	**vms;		/* mapped vmalloc regions */
 	bool			immutable;	/* no [de]population allowed */
-	struct page		**page;		/* points to page array */
-	struct page		*page_ar[];	/* #cpus * UNIT_PAGES */
+	unsigned long		populated[];	/* populated bitmap */
 };
 
 static int pcpu_unit_pages __read_mostly;
 static int pcpu_unit_size __read_mostly;
-static int pcpu_chunk_size __read_mostly;
+static int pcpu_nr_units __read_mostly;
+static int pcpu_atom_size __read_mostly;
 static int pcpu_nr_slots __read_mostly;
 static size_t pcpu_chunk_struct_size __read_mostly;
 
+/* cpus with the lowest and highest unit numbers */
+static unsigned int pcpu_first_unit_cpu __read_mostly;
+static unsigned int pcpu_last_unit_cpu __read_mostly;
+
 /* the address of the first chunk which starts with the kernel static area */
 void *pcpu_base_addr __read_mostly;
 EXPORT_SYMBOL_GPL(pcpu_base_addr);
 
+static const int *pcpu_unit_map __read_mostly;		/* cpu -> unit */
+const unsigned long *pcpu_unit_offsets __read_mostly;	/* cpu -> unit offset */
+
+/* group information, used for vm allocation */
+static int pcpu_nr_groups __read_mostly;
+static const unsigned long *pcpu_group_offsets __read_mostly;
+static const size_t *pcpu_group_sizes __read_mostly;
+
 /*
  * The first chunk which always exists.  Note that unlike other
  * chunks, this one can be allocated and mapped in several different
@@ -129,9 +147,9 @@ static int pcpu_reserved_chunk_limit;
  * Synchronization rules.
  *
  * There are two locks - pcpu_alloc_mutex and pcpu_lock.  The former
- * protects allocation/reclaim paths, chunks and chunk->page arrays.
- * The latter is a spinlock and protects the index data structures -
- * chunk slots, chunks and area maps in chunks.
+ * protects allocation/reclaim paths, chunks, populated bitmap and
+ * vmalloc mapping.  The latter is a spinlock and protects the index
+ * data structures - chunk slots, chunks and area maps in chunks.
  *
  * During allocation, pcpu_alloc_mutex is kept locked all the time and
  * pcpu_lock is grabbed and released as necessary.  All actual memory
@@ -178,31 +196,23 @@ static int pcpu_chunk_slot(const struct pcpu_chunk *chunk)
 
 static int pcpu_page_idx(unsigned int cpu, int page_idx)
 {
-	return cpu * pcpu_unit_pages + page_idx;
-}
-
-static struct page **pcpu_chunk_pagep(struct pcpu_chunk *chunk,
-				      unsigned int cpu, int page_idx)
-{
-	return &chunk->page[pcpu_page_idx(cpu, page_idx)];
+	return pcpu_unit_map[cpu] * pcpu_unit_pages + page_idx;
 }
 
 static unsigned long pcpu_chunk_addr(struct pcpu_chunk *chunk,
 				     unsigned int cpu, int page_idx)
 {
-	return (unsigned long)chunk->vm->addr +
-		(pcpu_page_idx(cpu, page_idx) << PAGE_SHIFT);
+	return (unsigned long)chunk->base_addr + pcpu_unit_offsets[cpu] +
+		(page_idx << PAGE_SHIFT);
 }
 
-static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk,
-				     int page_idx)
+static struct page *pcpu_chunk_page(struct pcpu_chunk *chunk,
+				    unsigned int cpu, int page_idx)
 {
-	/*
-	 * Any possible cpu id can be used here, so there's no need to
-	 * worry about preemption or cpu hotplug.
-	 */
-	return *pcpu_chunk_pagep(chunk, raw_smp_processor_id(),
-				 page_idx) != NULL;
+	/* must not be used on pre-mapped chunk */
+	WARN_ON(chunk->immutable);
+
+	return vmalloc_to_page((void *)pcpu_chunk_addr(chunk, cpu, page_idx));
 }
 
 /* set the pointer to a chunk in a page struct */
@@ -217,6 +227,34 @@ static struct pcpu_chunk *pcpu_get_page_chunk(struct page *page)
 	return (struct pcpu_chunk *)page->index;
 }
 
+static void pcpu_next_unpop(struct pcpu_chunk *chunk, int *rs, int *re, int end)
+{
+	*rs = find_next_zero_bit(chunk->populated, end, *rs);
+	*re = find_next_bit(chunk->populated, end, *rs + 1);
+}
+
+static void pcpu_next_pop(struct pcpu_chunk *chunk, int *rs, int *re, int end)
+{
+	*rs = find_next_bit(chunk->populated, end, *rs);
+	*re = find_next_zero_bit(chunk->populated, end, *rs + 1);
+}
+
+/*
+ * (Un)populated page region iterators.  Iterate over (un)populated
+ * page regions betwen @start and @end in @chunk.  @rs and @re should
+ * be integer variables and will be set to start and end page index of
+ * the current region.
+ */
+#define pcpu_for_each_unpop_region(chunk, rs, re, start, end)		    \
+	for ((rs) = (start), pcpu_next_unpop((chunk), &(rs), &(re), (end)); \
+	     (rs) < (re);						    \
+	     (rs) = (re) + 1, pcpu_next_unpop((chunk), &(rs), &(re), (end)))
+
+#define pcpu_for_each_pop_region(chunk, rs, re, start, end)		    \
+	for ((rs) = (start), pcpu_next_pop((chunk), &(rs), &(re), (end));   \
+	     (rs) < (re);						    \
+	     (rs) = (re) + 1, pcpu_next_pop((chunk), &(rs), &(re), (end)))
+
 /**
  * pcpu_mem_alloc - allocate memory
  * @size: bytes to allocate
@@ -292,10 +330,10 @@ static void pcpu_chunk_relocate(struct pcpu_chunk *chunk, int oslot)
  */
 static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
 {
-	void *first_start = pcpu_first_chunk->vm->addr;
+	void *first_start = pcpu_first_chunk->base_addr;
 
 	/* is it in the first chunk? */
-	if (addr >= first_start && addr < first_start + pcpu_chunk_size) {
+	if (addr >= first_start && addr < first_start + pcpu_unit_size) {
 		/* is it in the reserved area? */
 		if (addr < first_start + pcpu_reserved_chunk_limit)
 			return pcpu_reserved_chunk;
@@ -309,7 +347,7 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
 	 * space.  Note that any possible cpu id can be used here, so
 	 * there's no need to worry about preemption or cpu hotplug.
 	 */
-	addr += raw_smp_processor_id() * pcpu_unit_size;
+	addr += pcpu_unit_offsets[raw_smp_processor_id()];
 	return pcpu_get_page_chunk(vmalloc_to_page(addr));
 }
 
@@ -558,125 +596,327 @@ static void pcpu_free_area(struct pcpu_chunk *chunk, int freeme)
 }
 
 /**
- * pcpu_unmap - unmap pages out of a pcpu_chunk
+ * pcpu_get_pages_and_bitmap - get temp pages array and bitmap
  * @chunk: chunk of interest
- * @page_start: page index of the first page to unmap
- * @page_end: page index of the last page to unmap + 1
- * @flush_tlb: whether to flush tlb or not
+ * @bitmapp: output parameter for bitmap
+ * @may_alloc: may allocate the array
  *
- * For each cpu, unmap pages [@page_start,@page_end) out of @chunk.
- * If @flush is true, vcache is flushed before unmapping and tlb
- * after.
+ * Returns pointer to array of pointers to struct page and bitmap,
+ * both of which can be indexed with pcpu_page_idx().  The returned
+ * array is cleared to zero and *@bitmapp is copied from
+ * @chunk->populated.  Note that there is only one array and bitmap
+ * and access exclusion is the caller's responsibility.
+ *
+ * CONTEXT:
+ * pcpu_alloc_mutex and does GFP_KERNEL allocation if @may_alloc.
+ * Otherwise, don't care.
+ *
+ * RETURNS:
+ * Pointer to temp pages array on success, NULL on failure.
  */
-static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end,
-		       bool flush_tlb)
+static struct page **pcpu_get_pages_and_bitmap(struct pcpu_chunk *chunk,
+					       unsigned long **bitmapp,
+					       bool may_alloc)
 {
-	unsigned int last = nr_cpu_ids - 1;
-	unsigned int cpu;
+	static struct page **pages;
+	static unsigned long *bitmap;
+	size_t pages_size = pcpu_nr_units * pcpu_unit_pages * sizeof(pages[0]);
+	size_t bitmap_size = BITS_TO_LONGS(pcpu_unit_pages) *
+			     sizeof(unsigned long);
+
+	if (!pages || !bitmap) {
+		if (may_alloc && !pages)
+			pages = pcpu_mem_alloc(pages_size);
+		if (may_alloc && !bitmap)
+			bitmap = pcpu_mem_alloc(bitmap_size);
+		if (!pages || !bitmap)
+			return NULL;
+	}
 
-	/* unmap must not be done on immutable chunk */
-	WARN_ON(chunk->immutable);
+	memset(pages, 0, pages_size);
+	bitmap_copy(bitmap, chunk->populated, pcpu_unit_pages);
 
-	/*
-	 * Each flushing trial can be very expensive, issue flush on
-	 * the whole region at once rather than doing it for each cpu.
-	 * This could be an overkill but is more scalable.
-	 */
-	flush_cache_vunmap(pcpu_chunk_addr(chunk, 0, page_start),
-			   pcpu_chunk_addr(chunk, last, page_end));
+	*bitmapp = bitmap;
+	return pages;
+}
 
-	for_each_possible_cpu(cpu)
-		unmap_kernel_range_noflush(
-				pcpu_chunk_addr(chunk, cpu, page_start),
-				(page_end - page_start) << PAGE_SHIFT);
-
-	/* ditto as flush_cache_vunmap() */
-	if (flush_tlb)
-		flush_tlb_kernel_range(pcpu_chunk_addr(chunk, 0, page_start),
-				       pcpu_chunk_addr(chunk, last, page_end));
+/**
+ * pcpu_free_pages - free pages which were allocated for @chunk
+ * @chunk: chunk pages were allocated for
+ * @pages: array of pages to be freed, indexed by pcpu_page_idx()
+ * @populated: populated bitmap
+ * @page_start: page index of the first page to be freed
+ * @page_end: page index of the last page to be freed + 1
+ *
+ * Free pages [@page_start and @page_end) in @pages for all units.
+ * The pages were allocated for @chunk.
+ */
+static void pcpu_free_pages(struct pcpu_chunk *chunk,
+			    struct page **pages, unsigned long *populated,
+			    int page_start, int page_end)
+{
+	unsigned int cpu;
+	int i;
+
+	for_each_possible_cpu(cpu) {
+		for (i = page_start; i < page_end; i++) {
+			struct page *page = pages[pcpu_page_idx(cpu, i)];
+
+			if (page)
+				__free_page(page);
+		}
+	}
 }
 
 /**
- * pcpu_depopulate_chunk - depopulate and unmap an area of a pcpu_chunk
- * @chunk: chunk to depopulate
- * @off: offset to the area to depopulate
- * @size: size of the area to depopulate in bytes
- * @flush: whether to flush cache and tlb or not
- *
- * For each cpu, depopulate and unmap pages [@page_start,@page_end)
- * from @chunk.  If @flush is true, vcache is flushed before unmapping
- * and tlb after.
- *
- * CONTEXT:
- * pcpu_alloc_mutex.
+ * pcpu_alloc_pages - allocates pages for @chunk
+ * @chunk: target chunk
+ * @pages: array to put the allocated pages into, indexed by pcpu_page_idx()
+ * @populated: populated bitmap
+ * @page_start: page index of the first page to be allocated
+ * @page_end: page index of the last page to be allocated + 1
+ *
+ * Allocate pages [@page_start,@page_end) into @pages for all units.
+ * The allocation is for @chunk.  Percpu core doesn't care about the
+ * content of @pages and will pass it verbatim to pcpu_map_pages().
  */
-static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size,
-				  bool flush)
+static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
+			    struct page **pages, unsigned long *populated,
+			    int page_start, int page_end)
 {
-	int page_start = PFN_DOWN(off);
-	int page_end = PFN_UP(off + size);
-	int unmap_start = -1;
-	int uninitialized_var(unmap_end);
+	const gfp_t gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD;
 	unsigned int cpu;
 	int i;
 
-	for (i = page_start; i < page_end; i++) {
-		for_each_possible_cpu(cpu) {
-			struct page **pagep = pcpu_chunk_pagep(chunk, cpu, i);
+	for_each_possible_cpu(cpu) {
+		for (i = page_start; i < page_end; i++) {
+			struct page **pagep = &pages[pcpu_page_idx(cpu, i)];
+
+			*pagep = alloc_pages_node(cpu_to_node(cpu), gfp, 0);
+			if (!*pagep) {
+				pcpu_free_pages(chunk, pages, populated,
+						page_start, page_end);
+				return -ENOMEM;
+			}
+		}
+	}
+	return 0;
+}
 
-			if (!*pagep)
-				continue;
+/**
+ * pcpu_pre_unmap_flush - flush cache prior to unmapping
+ * @chunk: chunk the regions to be flushed belongs to
+ * @page_start: page index of the first page to be flushed
+ * @page_end: page index of the last page to be flushed + 1
+ *
+ * Pages in [@page_start,@page_end) of @chunk are about to be
+ * unmapped.  Flush cache.  As each flushing trial can be very
+ * expensive, issue flush on the whole region at once rather than
+ * doing it for each cpu.  This could be an overkill but is more
+ * scalable.
+ */
+static void pcpu_pre_unmap_flush(struct pcpu_chunk *chunk,
+				 int page_start, int page_end)
+{
+	flush_cache_vunmap(
+		pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
+		pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+}
+
+static void __pcpu_unmap_pages(unsigned long addr, int nr_pages)
+{
+	unmap_kernel_range_noflush(addr, nr_pages << PAGE_SHIFT);
+}
 
-			__free_page(*pagep);
+/**
+ * pcpu_unmap_pages - unmap pages out of a pcpu_chunk
+ * @chunk: chunk of interest
+ * @pages: pages array which can be used to pass information to free
+ * @populated: populated bitmap
+ * @page_start: page index of the first page to unmap
+ * @page_end: page index of the last page to unmap + 1
+ *
+ * For each cpu, unmap pages [@page_start,@page_end) out of @chunk.
+ * Corresponding elements in @pages were cleared by the caller and can
+ * be used to carry information to pcpu_free_pages() which will be
+ * called after all unmaps are finished.  The caller should call
+ * proper pre/post flush functions.
+ */
+static void pcpu_unmap_pages(struct pcpu_chunk *chunk,
+			     struct page **pages, unsigned long *populated,
+			     int page_start, int page_end)
+{
+	unsigned int cpu;
+	int i;
 
-			/*
-			 * If it's partial depopulation, it might get
-			 * populated or depopulated again.  Mark the
-			 * page gone.
-			 */
-			*pagep = NULL;
+	for_each_possible_cpu(cpu) {
+		for (i = page_start; i < page_end; i++) {
+			struct page *page;
 
-			unmap_start = unmap_start < 0 ? i : unmap_start;
-			unmap_end = i + 1;
+			page = pcpu_chunk_page(chunk, cpu, i);
+			WARN_ON(!page);
+			pages[pcpu_page_idx(cpu, i)] = page;
 		}
+		__pcpu_unmap_pages(pcpu_chunk_addr(chunk, cpu, page_start),
+				   page_end - page_start);
 	}
 
-	if (unmap_start >= 0)
-		pcpu_unmap(chunk, unmap_start, unmap_end, flush);
+	for (i = page_start; i < page_end; i++)
+		__clear_bit(i, populated);
+}
+
+/**
+ * pcpu_post_unmap_tlb_flush - flush TLB after unmapping
+ * @chunk: pcpu_chunk the regions to be flushed belong to
+ * @page_start: page index of the first page to be flushed
+ * @page_end: page index of the last page to be flushed + 1
+ *
+ * Pages [@page_start,@page_end) of @chunk have been unmapped.  Flush
+ * TLB for the regions.  This can be skipped if the area is to be
+ * returned to vmalloc as vmalloc will handle TLB flushing lazily.
+ *
+ * As with pcpu_pre_unmap_flush(), TLB flushing also is done at once
+ * for the whole region.
+ */
+static void pcpu_post_unmap_tlb_flush(struct pcpu_chunk *chunk,
+				      int page_start, int page_end)
+{
+	flush_tlb_kernel_range(
+		pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
+		pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+}
+
+static int __pcpu_map_pages(unsigned long addr, struct page **pages,
+			    int nr_pages)
+{
+	return map_kernel_range_noflush(addr, nr_pages << PAGE_SHIFT,
+					PAGE_KERNEL, pages);
 }
 
 /**
- * pcpu_map - map pages into a pcpu_chunk
+ * pcpu_map_pages - map pages into a pcpu_chunk
  * @chunk: chunk of interest
+ * @pages: pages array containing pages to be mapped
+ * @populated: populated bitmap
  * @page_start: page index of the first page to map
  * @page_end: page index of the last page to map + 1
  *
- * For each cpu, map pages [@page_start,@page_end) into @chunk.
- * vcache is flushed afterwards.
+ * For each cpu, map pages [@page_start,@page_end) into @chunk.  The
+ * caller is responsible for calling pcpu_post_map_flush() after all
+ * mappings are complete.
+ *
+ * This function is responsible for setting corresponding bits in
+ * @chunk->populated bitmap and whatever is necessary for reverse
+ * lookup (addr -> chunk).
  */
-static int pcpu_map(struct pcpu_chunk *chunk, int page_start, int page_end)
+static int pcpu_map_pages(struct pcpu_chunk *chunk,
+			  struct page **pages, unsigned long *populated,
+			  int page_start, int page_end)
 {
-	unsigned int last = nr_cpu_ids - 1;
-	unsigned int cpu;
-	int err;
-
-	/* map must not be done on immutable chunk */
-	WARN_ON(chunk->immutable);
+	unsigned int cpu, tcpu;
+	int i, err;
 
 	for_each_possible_cpu(cpu) {
-		err = map_kernel_range_noflush(
-				pcpu_chunk_addr(chunk, cpu, page_start),
-				(page_end - page_start) << PAGE_SHIFT,
-				PAGE_KERNEL,
-				pcpu_chunk_pagep(chunk, cpu, page_start));
+		err = __pcpu_map_pages(pcpu_chunk_addr(chunk, cpu, page_start),
+				       &pages[pcpu_page_idx(cpu, page_start)],
+				       page_end - page_start);
 		if (err < 0)
-			return err;
+			goto err;
+	}
+
+	/* mapping successful, link chunk and mark populated */
+	for (i = page_start; i < page_end; i++) {
+		for_each_possible_cpu(cpu)
+			pcpu_set_page_chunk(pages[pcpu_page_idx(cpu, i)],
+					    chunk);
+		__set_bit(i, populated);
 	}
 
-	/* flush at once, please read comments in pcpu_unmap() */
-	flush_cache_vmap(pcpu_chunk_addr(chunk, 0, page_start),
-			 pcpu_chunk_addr(chunk, last, page_end));
 	return 0;
+
+err:
+	for_each_possible_cpu(tcpu) {
+		if (tcpu == cpu)
+			break;
+		__pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start),
+				   page_end - page_start);
+	}
+	return err;
+}
+
+/**
+ * pcpu_post_map_flush - flush cache after mapping
+ * @chunk: pcpu_chunk the regions to be flushed belong to
+ * @page_start: page index of the first page to be flushed
+ * @page_end: page index of the last page to be flushed + 1
+ *
+ * Pages [@page_start,@page_end) of @chunk have been mapped.  Flush
+ * cache.
+ *
+ * As with pcpu_pre_unmap_flush(), TLB flushing also is done at once
+ * for the whole region.
+ */
+static void pcpu_post_map_flush(struct pcpu_chunk *chunk,
+				int page_start, int page_end)
+{
+	flush_cache_vmap(
+		pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start),
+		pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end));
+}
+
+/**
+ * pcpu_depopulate_chunk - depopulate and unmap an area of a pcpu_chunk
+ * @chunk: chunk to depopulate
+ * @off: offset to the area to depopulate
+ * @size: size of the area to depopulate in bytes
+ * @flush: whether to flush cache and tlb or not
+ *
+ * For each cpu, depopulate and unmap pages [@page_start,@page_end)
+ * from @chunk.  If @flush is true, vcache is flushed before unmapping
+ * and tlb after.
+ *
+ * CONTEXT:
+ * pcpu_alloc_mutex.
+ */
+static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size)
+{
+	int page_start = PFN_DOWN(off);
+	int page_end = PFN_UP(off + size);
+	struct page **pages;
+	unsigned long *populated;
+	int rs, re;
+
+	/* quick path, check whether it's empty already */
+	pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
+		if (rs == page_start && re == page_end)
+			return;
+		break;
+	}
+
+	/* immutable chunks can't be depopulated */
+	WARN_ON(chunk->immutable);
+
+	/*
+	 * If control reaches here, there must have been at least one
+	 * successful population attempt so the temp pages array must
+	 * be available now.
+	 */
+	pages = pcpu_get_pages_and_bitmap(chunk, &populated, false);
+	BUG_ON(!pages);
+
+	/* unmap and free */
+	pcpu_pre_unmap_flush(chunk, page_start, page_end);
+
+	pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end)
+		pcpu_unmap_pages(chunk, pages, populated, rs, re);
+
+	/* no need to flush tlb, vmalloc will handle it lazily */
+
+	pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end)
+		pcpu_free_pages(chunk, pages, populated, rs, re);
+
+	/* commit new bitmap */
+	bitmap_copy(chunk->populated, populated, pcpu_unit_pages);
 }
 
 /**
@@ -693,58 +933,68 @@ static int pcpu_map(struct pcpu_chunk *chunk, int page_start, int page_end)
  */
 static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size)
 {
-	const gfp_t alloc_mask = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD;
 	int page_start = PFN_DOWN(off);
 	int page_end = PFN_UP(off + size);
-	int map_start = -1;
-	int uninitialized_var(map_end);
+	int free_end = page_start, unmap_end = page_start;
+	struct page **pages;
+	unsigned long *populated;
 	unsigned int cpu;
-	int i;
+	int rs, re, rc;
 
-	for (i = page_start; i < page_end; i++) {
-		if (pcpu_chunk_page_occupied(chunk, i)) {
-			if (map_start >= 0) {
-				if (pcpu_map(chunk, map_start, map_end))
-					goto err;
-				map_start = -1;
-			}
-			continue;
-		}
+	/* quick path, check whether all pages are already there */
+	pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end) {
+		if (rs == page_start && re == page_end)
+			goto clear;
+		break;
+	}
 
-		map_start = map_start < 0 ? i : map_start;
-		map_end = i + 1;
+	/* need to allocate and map pages, this chunk can't be immutable */
+	WARN_ON(chunk->immutable);
 
-		for_each_possible_cpu(cpu) {
-			struct page **pagep = pcpu_chunk_pagep(chunk, cpu, i);
+	pages = pcpu_get_pages_and_bitmap(chunk, &populated, true);
+	if (!pages)
+		return -ENOMEM;
 
-			*pagep = alloc_pages_node(cpu_to_node(cpu),
-						  alloc_mask, 0);
-			if (!*pagep)
-				goto err;
-			pcpu_set_page_chunk(*pagep, chunk);
-		}
+	/* alloc and map */
+	pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
+		rc = pcpu_alloc_pages(chunk, pages, populated, rs, re);
+		if (rc)
+			goto err_free;
+		free_end = re;
 	}
 
-	if (map_start >= 0 && pcpu_map(chunk, map_start, map_end))
-		goto err;
+	pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
+		rc = pcpu_map_pages(chunk, pages, populated, rs, re);
+		if (rc)
+			goto err_unmap;
+		unmap_end = re;
+	}
+	pcpu_post_map_flush(chunk, page_start, page_end);
 
+	/* commit new bitmap */
+	bitmap_copy(chunk->populated, populated, pcpu_unit_pages);
+clear:
 	for_each_possible_cpu(cpu)
-		memset(chunk->vm->addr + cpu * pcpu_unit_size + off, 0,
-		       size);
-
+		memset((void *)pcpu_chunk_addr(chunk, cpu, 0) + off, 0, size);
 	return 0;
-err:
-	/* likely under heavy memory pressure, give memory back */
-	pcpu_depopulate_chunk(chunk, off, size, true);
-	return -ENOMEM;
+
+err_unmap:
+	pcpu_pre_unmap_flush(chunk, page_start, unmap_end);
+	pcpu_for_each_unpop_region(chunk, rs, re, page_start, unmap_end)
+		pcpu_unmap_pages(chunk, pages, populated, rs, re);
+	pcpu_post_unmap_tlb_flush(chunk, page_start, unmap_end);
+err_free:
+	pcpu_for_each_unpop_region(chunk, rs, re, page_start, free_end)
+		pcpu_free_pages(chunk, pages, populated, rs, re);
+	return rc;
 }
 
 static void free_pcpu_chunk(struct pcpu_chunk *chunk)
 {
 	if (!chunk)
 		return;
-	if (chunk->vm)
-		free_vm_area(chunk->vm);
+	if (chunk->vms)
+		pcpu_free_vm_areas(chunk->vms, pcpu_nr_groups);
 	pcpu_mem_free(chunk->map, chunk->map_alloc * sizeof(chunk->map[0]));
 	kfree(chunk);
 }
@@ -760,10 +1010,11 @@ static struct pcpu_chunk *alloc_pcpu_chunk(void)
 	chunk->map = pcpu_mem_alloc(PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0]));
 	chunk->map_alloc = PCPU_DFL_MAP_ALLOC;
 	chunk->map[chunk->map_used++] = pcpu_unit_size;
-	chunk->page = chunk->page_ar;
 
-	chunk->vm = get_vm_area(pcpu_chunk_size, VM_ALLOC);
-	if (!chunk->vm) {
+	chunk->vms = pcpu_get_vm_areas(pcpu_group_offsets, pcpu_group_sizes,
+				       pcpu_nr_groups, pcpu_atom_size,
+				       GFP_KERNEL);
+	if (!chunk->vms) {
 		free_pcpu_chunk(chunk);
 		return NULL;
 	}
@@ -771,6 +1022,7 @@ static struct pcpu_chunk *alloc_pcpu_chunk(void)
 	INIT_LIST_HEAD(&chunk->list);
 	chunk->free_size = pcpu_unit_size;
 	chunk->contig_hint = pcpu_unit_size;
+	chunk->base_addr = chunk->vms[0]->addr - pcpu_group_offsets[0];
 
 	return chunk;
 }
@@ -860,7 +1112,8 @@ area_found:
 
 	mutex_unlock(&pcpu_alloc_mutex);
 
-	return __addr_to_pcpu_ptr(chunk->vm->addr + off);
+	/* return address relative to base address */
+	return __addr_to_pcpu_ptr(chunk->base_addr + off);
 
 fail_unlock:
 	spin_unlock_irq(&pcpu_lock);
@@ -938,12 +1191,13 @@ static void pcpu_reclaim(struct work_struct *work)
 	}
 
 	spin_unlock_irq(&pcpu_lock);
-	mutex_unlock(&pcpu_alloc_mutex);
 
 	list_for_each_entry_safe(chunk, next, &todo, list) {
-		pcpu_depopulate_chunk(chunk, 0, pcpu_unit_size, false);
+		pcpu_depopulate_chunk(chunk, 0, pcpu_unit_size);
 		free_pcpu_chunk(chunk);
 	}
+
+	mutex_unlock(&pcpu_alloc_mutex);
 }
 
 /**
@@ -968,7 +1222,7 @@ void free_percpu(void *ptr)
 	spin_lock_irqsave(&pcpu_lock, flags);
 
 	chunk = pcpu_chunk_addr_search(addr);
-	off = addr - chunk->vm->addr;
+	off = addr - chunk->base_addr;
 
 	pcpu_free_area(chunk, off);
 
@@ -987,30 +1241,295 @@ void free_percpu(void *ptr)
 }
 EXPORT_SYMBOL_GPL(free_percpu);
 
+static inline size_t pcpu_calc_fc_sizes(size_t static_size,
+					size_t reserved_size,
+					ssize_t *dyn_sizep)
+{
+	size_t size_sum;
+
+	size_sum = PFN_ALIGN(static_size + reserved_size +
+			     (*dyn_sizep >= 0 ? *dyn_sizep : 0));
+	if (*dyn_sizep != 0)
+		*dyn_sizep = size_sum - static_size - reserved_size;
+
+	return size_sum;
+}
+
 /**
- * pcpu_setup_first_chunk - initialize the first percpu chunk
- * @get_page_fn: callback to fetch page pointer
- * @static_size: the size of static percpu area in bytes
+ * pcpu_alloc_alloc_info - allocate percpu allocation info
+ * @nr_groups: the number of groups
+ * @nr_units: the number of units
+ *
+ * Allocate ai which is large enough for @nr_groups groups containing
+ * @nr_units units.  The returned ai's groups[0].cpu_map points to the
+ * cpu_map array which is long enough for @nr_units and filled with
+ * NR_CPUS.  It's the caller's responsibility to initialize cpu_map
+ * pointer of other groups.
+ *
+ * RETURNS:
+ * Pointer to the allocated pcpu_alloc_info on success, NULL on
+ * failure.
+ */
+struct pcpu_alloc_info * __init pcpu_alloc_alloc_info(int nr_groups,
+						      int nr_units)
+{
+	struct pcpu_alloc_info *ai;
+	size_t base_size, ai_size;
+	void *ptr;
+	int unit;
+
+	base_size = ALIGN(sizeof(*ai) + nr_groups * sizeof(ai->groups[0]),
+			  __alignof__(ai->groups[0].cpu_map[0]));
+	ai_size = base_size + nr_units * sizeof(ai->groups[0].cpu_map[0]);
+
+	ptr = alloc_bootmem_nopanic(PFN_ALIGN(ai_size));
+	if (!ptr)
+		return NULL;
+	ai = ptr;
+	ptr += base_size;
+
+	ai->groups[0].cpu_map = ptr;
+
+	for (unit = 0; unit < nr_units; unit++)
+		ai->groups[0].cpu_map[unit] = NR_CPUS;
+
+	ai->nr_groups = nr_groups;
+	ai->__ai_size = PFN_ALIGN(ai_size);
+
+	return ai;
+}
+
+/**
+ * pcpu_free_alloc_info - free percpu allocation info
+ * @ai: pcpu_alloc_info to free
+ *
+ * Free @ai which was allocated by pcpu_alloc_alloc_info().
+ */
+void __init pcpu_free_alloc_info(struct pcpu_alloc_info *ai)
+{
+	free_bootmem(__pa(ai), ai->__ai_size);
+}
+
+/**
+ * pcpu_build_alloc_info - build alloc_info considering distances between CPUs
  * @reserved_size: the size of reserved percpu area in bytes
  * @dyn_size: free size for dynamic allocation in bytes, -1 for auto
- * @unit_size: unit size in bytes, must be multiple of PAGE_SIZE, -1 for auto
- * @base_addr: mapped address, NULL for auto
- * @populate_pte_fn: callback to allocate pagetable, NULL if unnecessary
+ * @atom_size: allocation atom size
+ * @cpu_distance_fn: callback to determine distance between cpus, optional
+ *
+ * This function determines grouping of units, their mappings to cpus
+ * and other parameters considering needed percpu size, allocation
+ * atom size and distances between CPUs.
+ *
+ * Groups are always mutliples of atom size and CPUs which are of
+ * LOCAL_DISTANCE both ways are grouped together and share space for
+ * units in the same group.  The returned configuration is guaranteed
+ * to have CPUs on different nodes on different groups and >=75% usage
+ * of allocated virtual address space.
+ *
+ * RETURNS:
+ * On success, pointer to the new allocation_info is returned.  On
+ * failure, ERR_PTR value is returned.
+ */
+struct pcpu_alloc_info * __init pcpu_build_alloc_info(
+				size_t reserved_size, ssize_t dyn_size,
+				size_t atom_size,
+				pcpu_fc_cpu_distance_fn_t cpu_distance_fn)
+{
+	static int group_map[NR_CPUS] __initdata;
+	static int group_cnt[NR_CPUS] __initdata;
+	const size_t static_size = __per_cpu_end - __per_cpu_start;
+	int group_cnt_max = 0, nr_groups = 1, nr_units = 0;
+	size_t size_sum, min_unit_size, alloc_size;
+	int upa, max_upa, uninitialized_var(best_upa);	/* units_per_alloc */
+	int last_allocs, group, unit;
+	unsigned int cpu, tcpu;
+	struct pcpu_alloc_info *ai;
+	unsigned int *cpu_map;
+
+	/*
+	 * Determine min_unit_size, alloc_size and max_upa such that
+	 * alloc_size is multiple of atom_size and is the smallest
+	 * which can accomodate 4k aligned segments which are equal to
+	 * or larger than min_unit_size.
+	 */
+	size_sum = pcpu_calc_fc_sizes(static_size, reserved_size, &dyn_size);
+	min_unit_size = max_t(size_t, size_sum, PCPU_MIN_UNIT_SIZE);
+
+	alloc_size = roundup(min_unit_size, atom_size);
+	upa = alloc_size / min_unit_size;
+	while (alloc_size % upa || ((alloc_size / upa) & ~PAGE_MASK))
+		upa--;
+	max_upa = upa;
+
+	/* group cpus according to their proximity */
+	for_each_possible_cpu(cpu) {
+		group = 0;
+	next_group:
+		for_each_possible_cpu(tcpu) {
+			if (cpu == tcpu)
+				break;
+			if (group_map[tcpu] == group && cpu_distance_fn &&
+			    (cpu_distance_fn(cpu, tcpu) > LOCAL_DISTANCE ||
+			     cpu_distance_fn(tcpu, cpu) > LOCAL_DISTANCE)) {
+				group++;
+				nr_groups = max(nr_groups, group + 1);
+				goto next_group;
+			}
+		}
+		group_map[cpu] = group;
+		group_cnt[group]++;
+		group_cnt_max = max(group_cnt_max, group_cnt[group]);
+	}
+
+	/*
+	 * Expand unit size until address space usage goes over 75%
+	 * and then as much as possible without using more address
+	 * space.
+	 */
+	last_allocs = INT_MAX;
+	for (upa = max_upa; upa; upa--) {
+		int allocs = 0, wasted = 0;
+
+		if (alloc_size % upa || ((alloc_size / upa) & ~PAGE_MASK))
+			continue;
+
+		for (group = 0; group < nr_groups; group++) {
+			int this_allocs = DIV_ROUND_UP(group_cnt[group], upa);
+			allocs += this_allocs;
+			wasted += this_allocs * upa - group_cnt[group];
+		}
+
+		/*
+		 * Don't accept if wastage is over 25%.  The
+		 * greater-than comparison ensures upa==1 always
+		 * passes the following check.
+		 */
+		if (wasted > num_possible_cpus() / 3)
+			continue;
+
+		/* and then don't consume more memory */
+		if (allocs > last_allocs)
+			break;
+		last_allocs = allocs;
+		best_upa = upa;
+	}
+	upa = best_upa;
+
+	/* allocate and fill alloc_info */
+	for (group = 0; group < nr_groups; group++)
+		nr_units += roundup(group_cnt[group], upa);
+
+	ai = pcpu_alloc_alloc_info(nr_groups, nr_units);
+	if (!ai)
+		return ERR_PTR(-ENOMEM);
+	cpu_map = ai->groups[0].cpu_map;
+
+	for (group = 0; group < nr_groups; group++) {
+		ai->groups[group].cpu_map = cpu_map;
+		cpu_map += roundup(group_cnt[group], upa);
+	}
+
+	ai->static_size = static_size;
+	ai->reserved_size = reserved_size;
+	ai->dyn_size = dyn_size;
+	ai->unit_size = alloc_size / upa;
+	ai->atom_size = atom_size;
+	ai->alloc_size = alloc_size;
+
+	for (group = 0, unit = 0; group_cnt[group]; group++) {
+		struct pcpu_group_info *gi = &ai->groups[group];
+
+		/*
+		 * Initialize base_offset as if all groups are located
+		 * back-to-back.  The caller should update this to
+		 * reflect actual allocation.
+		 */
+		gi->base_offset = unit * ai->unit_size;
+
+		for_each_possible_cpu(cpu)
+			if (group_map[cpu] == group)
+				gi->cpu_map[gi->nr_units++] = cpu;
+		gi->nr_units = roundup(gi->nr_units, upa);
+		unit += gi->nr_units;
+	}
+	BUG_ON(unit != nr_units);
+
+	return ai;
+}
+
+/**
+ * pcpu_dump_alloc_info - print out information about pcpu_alloc_info
+ * @lvl: loglevel
+ * @ai: allocation info to dump
+ *
+ * Print out information about @ai using loglevel @lvl.
+ */
+static void pcpu_dump_alloc_info(const char *lvl,
+				 const struct pcpu_alloc_info *ai)
+{
+	int group_width = 1, cpu_width = 1, width;
+	char empty_str[] = "--------";
+	int alloc = 0, alloc_end = 0;
+	int group, v;
+	int upa, apl;	/* units per alloc, allocs per line */
+
+	v = ai->nr_groups;
+	while (v /= 10)
+		group_width++;
+
+	v = num_possible_cpus();
+	while (v /= 10)
+		cpu_width++;
+	empty_str[min_t(int, cpu_width, sizeof(empty_str) - 1)] = '\0';
+
+	upa = ai->alloc_size / ai->unit_size;
+	width = upa * (cpu_width + 1) + group_width + 3;
+	apl = rounddown_pow_of_two(max(60 / width, 1));
+
+	printk("%spcpu-alloc: s%zu r%zu d%zu u%zu alloc=%zu*%zu",
+	       lvl, ai->static_size, ai->reserved_size, ai->dyn_size,
+	       ai->unit_size, ai->alloc_size / ai->atom_size, ai->atom_size);
+
+	for (group = 0; group < ai->nr_groups; group++) {
+		const struct pcpu_group_info *gi = &ai->groups[group];
+		int unit = 0, unit_end = 0;
+
+		BUG_ON(gi->nr_units % upa);
+		for (alloc_end += gi->nr_units / upa;
+		     alloc < alloc_end; alloc++) {
+			if (!(alloc % apl)) {
+				printk("\n");
+				printk("%spcpu-alloc: ", lvl);
+			}
+			printk("[%0*d] ", group_width, group);
+
+			for (unit_end += upa; unit < unit_end; unit++)
+				if (gi->cpu_map[unit] != NR_CPUS)
+					printk("%0*d ", cpu_width,
+					       gi->cpu_map[unit]);
+				else
+					printk("%s ", empty_str);
+		}
+	}
+	printk("\n");
+}
+
+/**
+ * pcpu_setup_first_chunk - initialize the first percpu chunk
+ * @ai: pcpu_alloc_info describing how to percpu area is shaped
+ * @base_addr: mapped address
  *
  * Initialize the first percpu chunk which contains the kernel static
  * perpcu area.  This function is to be called from arch percpu area
- * setup path.  The first two parameters are mandatory.  The rest are
- * optional.
- *
- * @get_page_fn() should return pointer to percpu page given cpu
- * number and page number.  It should at least return enough pages to
- * cover the static area.  The returned pages for static area should
- * have been initialized with valid data.  If @unit_size is specified,
- * it can also return pages after the static area.  NULL return
- * indicates end of pages for the cpu.  Note that @get_page_fn() must
- * return the same number of pages for all cpus.
- *
- * @reserved_size, if non-zero, specifies the amount of bytes to
+ * setup path.
+ *
+ * @ai contains all information necessary to initialize the first
+ * chunk and prime the dynamic percpu allocator.
+ *
+ * @ai->static_size is the size of static percpu area.
+ *
+ * @ai->reserved_size, if non-zero, specifies the amount of bytes to
  * reserve after the static area in the first chunk.  This reserves
  * the first chunk such that it's available only through reserved
  * percpu allocation.  This is primarily used to serve module percpu
@@ -1018,22 +1537,29 @@ EXPORT_SYMBOL_GPL(free_percpu);
  * limited offset range for symbol relocations to guarantee module
  * percpu symbols fall inside the relocatable range.
  *
- * @dyn_size, if non-negative, determines the number of bytes
- * available for dynamic allocation in the first chunk.  Specifying
- * non-negative value makes percpu leave alone the area beyond
- * @static_size + @reserved_size + @dyn_size.
+ * @ai->dyn_size determines the number of bytes available for dynamic
+ * allocation in the first chunk.  The area between @ai->static_size +
+ * @ai->reserved_size + @ai->dyn_size and @ai->unit_size is unused.
  *
- * @unit_size, if non-negative, specifies unit size and must be
- * aligned to PAGE_SIZE and equal to or larger than @static_size +
- * @reserved_size + if non-negative, @dyn_size.
+ * @ai->unit_size specifies unit size and must be aligned to PAGE_SIZE
+ * and equal to or larger than @ai->static_size + @ai->reserved_size +
+ * @ai->dyn_size.
  *
- * Non-null @base_addr means that the caller already allocated virtual
- * region for the first chunk and mapped it.  percpu must not mess
- * with the chunk.  Note that @base_addr with 0 @unit_size or non-NULL
- * @populate_pte_fn doesn't make any sense.
+ * @ai->atom_size is the allocation atom size and used as alignment
+ * for vm areas.
  *
- * @populate_pte_fn is used to populate the pagetable.  NULL means the
- * caller already populated the pagetable.
+ * @ai->alloc_size is the allocation size and always multiple of
+ * @ai->atom_size.  This is larger than @ai->atom_size if
+ * @ai->unit_size is larger than @ai->atom_size.
+ *
+ * @ai->nr_groups and @ai->groups describe virtual memory layout of
+ * percpu areas.  Units which should be colocated are put into the
+ * same group.  Dynamic VM areas will be allocated according to these
+ * groupings.  If @ai->nr_groups is zero, a single group containing
+ * all units is assumed.
+ *
+ * The caller should have mapped the first chunk at @base_addr and
+ * copied static data to each unit.
  *
  * If the first chunk ends up with both reserved and dynamic areas, it
  * is served by two chunks - one to serve the core static and reserved
@@ -1043,49 +1569,83 @@ EXPORT_SYMBOL_GPL(free_percpu);
  * and available for dynamic allocation like any other chunks.
  *
  * RETURNS:
- * The determined pcpu_unit_size which can be used to initialize
- * percpu access.
+ * 0 on success, -errno on failure.
  */
-size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
-				     size_t static_size, size_t reserved_size,
-				     ssize_t dyn_size, ssize_t unit_size,
-				     void *base_addr,
-				     pcpu_populate_pte_fn_t populate_pte_fn)
+int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
+				  void *base_addr)
 {
-	static struct vm_struct first_vm;
 	static int smap[2], dmap[2];
-	size_t size_sum = static_size + reserved_size +
-			  (dyn_size >= 0 ? dyn_size : 0);
+	size_t dyn_size = ai->dyn_size;
+	size_t size_sum = ai->static_size + ai->reserved_size + dyn_size;
 	struct pcpu_chunk *schunk, *dchunk = NULL;
+	unsigned long *group_offsets;
+	size_t *group_sizes;
+	unsigned long *unit_off;
 	unsigned int cpu;
-	int nr_pages;
-	int err, i;
+	int *unit_map;
+	int group, unit, i;
 
-	/* santiy checks */
+	/* sanity checks */
 	BUILD_BUG_ON(ARRAY_SIZE(smap) >= PCPU_DFL_MAP_ALLOC ||
 		     ARRAY_SIZE(dmap) >= PCPU_DFL_MAP_ALLOC);
-	BUG_ON(!static_size);
-	if (unit_size >= 0) {
-		BUG_ON(unit_size < size_sum);
-		BUG_ON(unit_size & ~PAGE_MASK);
-		BUG_ON(unit_size < PCPU_MIN_UNIT_SIZE);
-	} else
-		BUG_ON(base_addr);
-	BUG_ON(base_addr && populate_pte_fn);
-
-	if (unit_size >= 0)
-		pcpu_unit_pages = unit_size >> PAGE_SHIFT;
-	else
-		pcpu_unit_pages = max_t(int, PCPU_MIN_UNIT_SIZE >> PAGE_SHIFT,
-					PFN_UP(size_sum));
+	BUG_ON(ai->nr_groups <= 0);
+	BUG_ON(!ai->static_size);
+	BUG_ON(!base_addr);
+	BUG_ON(ai->unit_size < size_sum);
+	BUG_ON(ai->unit_size & ~PAGE_MASK);
+	BUG_ON(ai->unit_size < PCPU_MIN_UNIT_SIZE);
+
+	pcpu_dump_alloc_info(KERN_DEBUG, ai);
+
+	/* process group information and build config tables accordingly */
+	group_offsets = alloc_bootmem(ai->nr_groups * sizeof(group_offsets[0]));
+	group_sizes = alloc_bootmem(ai->nr_groups * sizeof(group_sizes[0]));
+	unit_map = alloc_bootmem(nr_cpu_ids * sizeof(unit_map[0]));
+	unit_off = alloc_bootmem(nr_cpu_ids * sizeof(unit_off[0]));
+
+	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+		unit_map[cpu] = NR_CPUS;
+	pcpu_first_unit_cpu = NR_CPUS;
+
+	for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) {
+		const struct pcpu_group_info *gi = &ai->groups[group];
+
+		group_offsets[group] = gi->base_offset;
+		group_sizes[group] = gi->nr_units * ai->unit_size;
+
+		for (i = 0; i < gi->nr_units; i++) {
+			cpu = gi->cpu_map[i];
+			if (cpu == NR_CPUS)
+				continue;
 
-	pcpu_unit_size = pcpu_unit_pages << PAGE_SHIFT;
-	pcpu_chunk_size = nr_cpu_ids * pcpu_unit_size;
-	pcpu_chunk_struct_size = sizeof(struct pcpu_chunk)
-		+ nr_cpu_ids * pcpu_unit_pages * sizeof(struct page *);
+			BUG_ON(cpu > nr_cpu_ids || !cpu_possible(cpu));
+			BUG_ON(unit_map[cpu] != NR_CPUS);
 
-	if (dyn_size < 0)
-		dyn_size = pcpu_unit_size - static_size - reserved_size;
+			unit_map[cpu] = unit + i;
+			unit_off[cpu] = gi->base_offset + i * ai->unit_size;
+
+			if (pcpu_first_unit_cpu == NR_CPUS)
+				pcpu_first_unit_cpu = cpu;
+		}
+	}
+	pcpu_last_unit_cpu = cpu;
+	pcpu_nr_units = unit;
+
+	for_each_possible_cpu(cpu)
+		BUG_ON(unit_map[cpu] == NR_CPUS);
+
+	pcpu_nr_groups = ai->nr_groups;
+	pcpu_group_offsets = group_offsets;
+	pcpu_group_sizes = group_sizes;
+	pcpu_unit_map = unit_map;
+	pcpu_unit_offsets = unit_off;
+
+	/* determine basic parameters */
+	pcpu_unit_pages = ai->unit_size >> PAGE_SHIFT;
+	pcpu_unit_size = pcpu_unit_pages << PAGE_SHIFT;
+	pcpu_atom_size = ai->atom_size;
+	pcpu_chunk_struct_size = sizeof(struct pcpu_chunk) +
+		BITS_TO_LONGS(pcpu_unit_pages) * sizeof(unsigned long);
 
 	/*
 	 * Allocate chunk slots.  The additional last slot is for
@@ -1105,189 +1665,351 @@ size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
 	 */
 	schunk = alloc_bootmem(pcpu_chunk_struct_size);
 	INIT_LIST_HEAD(&schunk->list);
-	schunk->vm = &first_vm;
+	schunk->base_addr = base_addr;
 	schunk->map = smap;
 	schunk->map_alloc = ARRAY_SIZE(smap);
-	schunk->page = schunk->page_ar;
+	schunk->immutable = true;
+	bitmap_fill(schunk->populated, pcpu_unit_pages);
 
-	if (reserved_size) {
-		schunk->free_size = reserved_size;
+	if (ai->reserved_size) {
+		schunk->free_size = ai->reserved_size;
 		pcpu_reserved_chunk = schunk;
-		pcpu_reserved_chunk_limit = static_size + reserved_size;
+		pcpu_reserved_chunk_limit = ai->static_size + ai->reserved_size;
 	} else {
 		schunk->free_size = dyn_size;
 		dyn_size = 0;			/* dynamic area covered */
 	}
 	schunk->contig_hint = schunk->free_size;
 
-	schunk->map[schunk->map_used++] = -static_size;
+	schunk->map[schunk->map_used++] = -ai->static_size;
 	if (schunk->free_size)
 		schunk->map[schunk->map_used++] = schunk->free_size;
 
 	/* init dynamic chunk if necessary */
 	if (dyn_size) {
-		dchunk = alloc_bootmem(sizeof(struct pcpu_chunk));
+		dchunk = alloc_bootmem(pcpu_chunk_struct_size);
 		INIT_LIST_HEAD(&dchunk->list);
-		dchunk->vm = &first_vm;
+		dchunk->base_addr = base_addr;
 		dchunk->map = dmap;
 		dchunk->map_alloc = ARRAY_SIZE(dmap);
-		dchunk->page = schunk->page_ar;	/* share page map with schunk */
+		dchunk->immutable = true;
+		bitmap_fill(dchunk->populated, pcpu_unit_pages);
 
 		dchunk->contig_hint = dchunk->free_size = dyn_size;
 		dchunk->map[dchunk->map_used++] = -pcpu_reserved_chunk_limit;
 		dchunk->map[dchunk->map_used++] = dchunk->free_size;
 	}
 
-	/* allocate vm address */
-	first_vm.flags = VM_ALLOC;
-	first_vm.size = pcpu_chunk_size;
-
-	if (!base_addr)
-		vm_area_register_early(&first_vm, PAGE_SIZE);
-	else {
-		/*
-		 * Pages already mapped.  No need to remap into
-		 * vmalloc area.  In this case the first chunks can't
-		 * be mapped or unmapped by percpu and are marked
-		 * immutable.
-		 */
-		first_vm.addr = base_addr;
-		schunk->immutable = true;
-		if (dchunk)
-			dchunk->immutable = true;
-	}
-
-	/* assign pages */
-	nr_pages = -1;
-	for_each_possible_cpu(cpu) {
-		for (i = 0; i < pcpu_unit_pages; i++) {
-			struct page *page = get_page_fn(cpu, i);
-
-			if (!page)
-				break;
-			*pcpu_chunk_pagep(schunk, cpu, i) = page;
-		}
-
-		BUG_ON(i < PFN_UP(static_size));
-
-		if (nr_pages < 0)
-			nr_pages = i;
-		else
-			BUG_ON(nr_pages != i);
-	}
-
-	/* map them */
-	if (populate_pte_fn) {
-		for_each_possible_cpu(cpu)
-			for (i = 0; i < nr_pages; i++)
-				populate_pte_fn(pcpu_chunk_addr(schunk,
-								cpu, i));
-
-		err = pcpu_map(schunk, 0, nr_pages);
-		if (err)
-			panic("failed to setup static percpu area, err=%d\n",
-			      err);
-	}
-
 	/* link the first chunk in */
 	pcpu_first_chunk = dchunk ?: schunk;
 	pcpu_chunk_relocate(pcpu_first_chunk, -1);
 
 	/* we're done */
-	pcpu_base_addr = (void *)pcpu_chunk_addr(schunk, 0, 0);
-	return pcpu_unit_size;
+	pcpu_base_addr = base_addr;
+	return 0;
 }
 
-/*
- * Embedding first chunk setup helper.
- */
-static void *pcpue_ptr __initdata;
-static size_t pcpue_size __initdata;
-static size_t pcpue_unit_size __initdata;
+const char *pcpu_fc_names[PCPU_FC_NR] __initdata = {
+	[PCPU_FC_AUTO]	= "auto",
+	[PCPU_FC_EMBED]	= "embed",
+	[PCPU_FC_PAGE]	= "page",
+};
 
-static struct page * __init pcpue_get_page(unsigned int cpu, int pageno)
-{
-	size_t off = (size_t)pageno << PAGE_SHIFT;
+enum pcpu_fc pcpu_chosen_fc __initdata = PCPU_FC_AUTO;
 
-	if (off >= pcpue_size)
-		return NULL;
+static int __init percpu_alloc_setup(char *str)
+{
+	if (0)
+		/* nada */;
+#ifdef CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK
+	else if (!strcmp(str, "embed"))
+		pcpu_chosen_fc = PCPU_FC_EMBED;
+#endif
+#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
+	else if (!strcmp(str, "page"))
+		pcpu_chosen_fc = PCPU_FC_PAGE;
+#endif
+	else
+		pr_warning("PERCPU: unknown allocator %s specified\n", str);
 
-	return virt_to_page(pcpue_ptr + cpu * pcpue_unit_size + off);
+	return 0;
 }
+early_param("percpu_alloc", percpu_alloc_setup);
 
+#if defined(CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK) || \
+	!defined(CONFIG_HAVE_SETUP_PER_CPU_AREA)
 /**
  * pcpu_embed_first_chunk - embed the first percpu chunk into bootmem
- * @static_size: the size of static percpu area in bytes
  * @reserved_size: the size of reserved percpu area in bytes
  * @dyn_size: free size for dynamic allocation in bytes, -1 for auto
- * @unit_size: unit size in bytes, must be multiple of PAGE_SIZE, -1 for auto
+ * @atom_size: allocation atom size
+ * @cpu_distance_fn: callback to determine distance between cpus, optional
+ * @alloc_fn: function to allocate percpu page
+ * @free_fn: funtion to free percpu page
  *
  * This is a helper to ease setting up embedded first percpu chunk and
  * can be called where pcpu_setup_first_chunk() is expected.
  *
  * If this function is used to setup the first chunk, it is allocated
- * as a contiguous area using bootmem allocator and used as-is without
- * being mapped into vmalloc area.  This enables the first chunk to
- * piggy back on the linear physical mapping which often uses larger
- * page size.
+ * by calling @alloc_fn and used as-is without being mapped into
+ * vmalloc area.  Allocations are always whole multiples of @atom_size
+ * aligned to @atom_size.
+ *
+ * This enables the first chunk to piggy back on the linear physical
+ * mapping which often uses larger page size.  Please note that this
+ * can result in very sparse cpu->unit mapping on NUMA machines thus
+ * requiring large vmalloc address space.  Don't use this allocator if
+ * vmalloc space is not orders of magnitude larger than distances
+ * between node memory addresses (ie. 32bit NUMA machines).
  *
  * When @dyn_size is positive, dynamic area might be larger than
- * specified to fill page alignment.  Also, when @dyn_size is auto,
- * @dyn_size does not fill the whole first chunk but only what's
- * necessary for page alignment after static and reserved areas.
+ * specified to fill page alignment.  When @dyn_size is auto,
+ * @dyn_size is just big enough to fill page alignment after static
+ * and reserved areas.
  *
  * If the needed size is smaller than the minimum or specified unit
- * size, the leftover is returned to the bootmem allocator.
+ * size, the leftover is returned using @free_fn.
  *
  * RETURNS:
- * The determined pcpu_unit_size which can be used to initialize
- * percpu access on success, -errno on failure.
+ * 0 on success, -errno on failure.
  */
-ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size,
-				      ssize_t dyn_size, ssize_t unit_size)
+int __init pcpu_embed_first_chunk(size_t reserved_size, ssize_t dyn_size,
+				  size_t atom_size,
+				  pcpu_fc_cpu_distance_fn_t cpu_distance_fn,
+				  pcpu_fc_alloc_fn_t alloc_fn,
+				  pcpu_fc_free_fn_t free_fn)
 {
-	size_t chunk_size;
-	unsigned int cpu;
+	void *base = (void *)ULONG_MAX;
+	void **areas = NULL;
+	struct pcpu_alloc_info *ai;
+	size_t size_sum, areas_size;
+	int group, i, rc;
+
+	ai = pcpu_build_alloc_info(reserved_size, dyn_size, atom_size,
+				   cpu_distance_fn);
+	if (IS_ERR(ai))
+		return PTR_ERR(ai);
+
+	size_sum = ai->static_size + ai->reserved_size + ai->dyn_size;
+	areas_size = PFN_ALIGN(ai->nr_groups * sizeof(void *));
+
+	areas = alloc_bootmem_nopanic(areas_size);
+	if (!areas) {
+		rc = -ENOMEM;
+		goto out_free;
+	}
 
-	/* determine parameters and allocate */
-	pcpue_size = PFN_ALIGN(static_size + reserved_size +
-			       (dyn_size >= 0 ? dyn_size : 0));
-	if (dyn_size != 0)
-		dyn_size = pcpue_size - static_size - reserved_size;
-
-	if (unit_size >= 0) {
-		BUG_ON(unit_size < pcpue_size);
-		pcpue_unit_size = unit_size;
-	} else
-		pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE);
-
-	chunk_size = pcpue_unit_size * nr_cpu_ids;
-
-	pcpue_ptr = __alloc_bootmem_nopanic(chunk_size, PAGE_SIZE,
-					    __pa(MAX_DMA_ADDRESS));
-	if (!pcpue_ptr) {
-		pr_warning("PERCPU: failed to allocate %zu bytes for "
-			   "embedding\n", chunk_size);
-		return -ENOMEM;
+	/* allocate, copy and determine base address */
+	for (group = 0; group < ai->nr_groups; group++) {
+		struct pcpu_group_info *gi = &ai->groups[group];
+		unsigned int cpu = NR_CPUS;
+		void *ptr;
+
+		for (i = 0; i < gi->nr_units && cpu == NR_CPUS; i++)
+			cpu = gi->cpu_map[i];
+		BUG_ON(cpu == NR_CPUS);
+
+		/* allocate space for the whole group */
+		ptr = alloc_fn(cpu, gi->nr_units * ai->unit_size, atom_size);
+		if (!ptr) {
+			rc = -ENOMEM;
+			goto out_free_areas;
+		}
+		areas[group] = ptr;
+
+		base = min(ptr, base);
+
+		for (i = 0; i < gi->nr_units; i++, ptr += ai->unit_size) {
+			if (gi->cpu_map[i] == NR_CPUS) {
+				/* unused unit, free whole */
+				free_fn(ptr, ai->unit_size);
+				continue;
+			}
+			/* copy and return the unused part */
+			memcpy(ptr, __per_cpu_load, ai->static_size);
+			free_fn(ptr + size_sum, ai->unit_size - size_sum);
+		}
 	}
 
-	/* return the leftover and copy */
-	for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
-		void *ptr = pcpue_ptr + cpu * pcpue_unit_size;
+	/* base address is now known, determine group base offsets */
+	for (group = 0; group < ai->nr_groups; group++)
+		ai->groups[group].base_offset = areas[group] - base;
+
+	pr_info("PERCPU: Embedded %zu pages/cpu @%p s%zu r%zu d%zu u%zu\n",
+		PFN_DOWN(size_sum), base, ai->static_size, ai->reserved_size,
+		ai->dyn_size, ai->unit_size);
+
+	rc = pcpu_setup_first_chunk(ai, base);
+	goto out_free;
+
+out_free_areas:
+	for (group = 0; group < ai->nr_groups; group++)
+		free_fn(areas[group],
+			ai->groups[group].nr_units * ai->unit_size);
+out_free:
+	pcpu_free_alloc_info(ai);
+	if (areas)
+		free_bootmem(__pa(areas), areas_size);
+	return rc;
+}
+#endif /* CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK ||
+	  !CONFIG_HAVE_SETUP_PER_CPU_AREA */
+
+#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
+/**
+ * pcpu_page_first_chunk - map the first chunk using PAGE_SIZE pages
+ * @reserved_size: the size of reserved percpu area in bytes
+ * @alloc_fn: function to allocate percpu page, always called with PAGE_SIZE
+ * @free_fn: funtion to free percpu page, always called with PAGE_SIZE
+ * @populate_pte_fn: function to populate pte
+ *
+ * This is a helper to ease setting up page-remapped first percpu
+ * chunk and can be called where pcpu_setup_first_chunk() is expected.
+ *
+ * This is the basic allocator.  Static percpu area is allocated
+ * page-by-page into vmalloc area.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int __init pcpu_page_first_chunk(size_t reserved_size,
+				 pcpu_fc_alloc_fn_t alloc_fn,
+				 pcpu_fc_free_fn_t free_fn,
+				 pcpu_fc_populate_pte_fn_t populate_pte_fn)
+{
+	static struct vm_struct vm;
+	struct pcpu_alloc_info *ai;
+	char psize_str[16];
+	int unit_pages;
+	size_t pages_size;
+	struct page **pages;
+	int unit, i, j, rc;
+
+	snprintf(psize_str, sizeof(psize_str), "%luK", PAGE_SIZE >> 10);
+
+	ai = pcpu_build_alloc_info(reserved_size, -1, PAGE_SIZE, NULL);
+	if (IS_ERR(ai))
+		return PTR_ERR(ai);
+	BUG_ON(ai->nr_groups != 1);
+	BUG_ON(ai->groups[0].nr_units != num_possible_cpus());
+
+	unit_pages = ai->unit_size >> PAGE_SHIFT;
+
+	/* unaligned allocations can't be freed, round up to page size */
+	pages_size = PFN_ALIGN(unit_pages * num_possible_cpus() *
+			       sizeof(pages[0]));
+	pages = alloc_bootmem(pages_size);
+
+	/* allocate pages */
+	j = 0;
+	for (unit = 0; unit < num_possible_cpus(); unit++)
+		for (i = 0; i < unit_pages; i++) {
+			unsigned int cpu = ai->groups[0].cpu_map[unit];
+			void *ptr;
+
+			ptr = alloc_fn(cpu, PAGE_SIZE, PAGE_SIZE);
+			if (!ptr) {
+				pr_warning("PERCPU: failed to allocate %s page "
+					   "for cpu%u\n", psize_str, cpu);
+				goto enomem;
+			}
+			pages[j++] = virt_to_page(ptr);
+		}
+
+	/* allocate vm area, map the pages and copy static data */
+	vm.flags = VM_ALLOC;
+	vm.size = num_possible_cpus() * ai->unit_size;
+	vm_area_register_early(&vm, PAGE_SIZE);
+
+	for (unit = 0; unit < num_possible_cpus(); unit++) {
+		unsigned long unit_addr =
+			(unsigned long)vm.addr + unit * ai->unit_size;
+
+		for (i = 0; i < unit_pages; i++)
+			populate_pte_fn(unit_addr + (i << PAGE_SHIFT));
+
+		/* pte already populated, the following shouldn't fail */
+		rc = __pcpu_map_pages(unit_addr, &pages[unit * unit_pages],
+				      unit_pages);
+		if (rc < 0)
+			panic("failed to map percpu area, err=%d\n", rc);
 
-		if (cpu_possible(cpu)) {
-			free_bootmem(__pa(ptr + pcpue_size),
-				     pcpue_unit_size - pcpue_size);
-			memcpy(ptr, __per_cpu_load, static_size);
-		} else
-			free_bootmem(__pa(ptr), pcpue_unit_size);
+		/*
+		 * FIXME: Archs with virtual cache should flush local
+		 * cache for the linear mapping here - something
+		 * equivalent to flush_cache_vmap() on the local cpu.
+		 * flush_cache_vmap() can't be used as most supporting
+		 * data structures are not set up yet.
+		 */
+
+		/* copy static data */
+		memcpy((void *)unit_addr, __per_cpu_load, ai->static_size);
 	}
 
 	/* we're ready, commit */
-	pr_info("PERCPU: Embedded %zu pages at %p, static data %zu bytes\n",
-		pcpue_size >> PAGE_SHIFT, pcpue_ptr, static_size);
+	pr_info("PERCPU: %d %s pages/cpu @%p s%zu r%zu d%zu\n",
+		unit_pages, psize_str, vm.addr, ai->static_size,
+		ai->reserved_size, ai->dyn_size);
+
+	rc = pcpu_setup_first_chunk(ai, vm.addr);
+	goto out_free_ar;
+
+enomem:
+	while (--j >= 0)
+		free_fn(page_address(pages[j]), PAGE_SIZE);
+	rc = -ENOMEM;
+out_free_ar:
+	free_bootmem(__pa(pages), pages_size);
+	pcpu_free_alloc_info(ai);
+	return rc;
+}
+#endif /* CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK */
+
+/*
+ * Generic percpu area setup.
+ *
+ * The embedding helper is used because its behavior closely resembles
+ * the original non-dynamic generic percpu area setup.  This is
+ * important because many archs have addressing restrictions and might
+ * fail if the percpu area is located far away from the previous
+ * location.  As an added bonus, in non-NUMA cases, embedding is
+ * generally a good idea TLB-wise because percpu area can piggy back
+ * on the physical linear memory mapping which uses large page
+ * mappings on applicable archs.
+ */
+#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(__per_cpu_offset);
+
+static void * __init pcpu_dfl_fc_alloc(unsigned int cpu, size_t size,
+				       size_t align)
+{
+	return __alloc_bootmem_nopanic(size, align, __pa(MAX_DMA_ADDRESS));
+}
 
-	return pcpu_setup_first_chunk(pcpue_get_page, static_size,
-				      reserved_size, dyn_size,
-				      pcpue_unit_size, pcpue_ptr, NULL);
+static void __init pcpu_dfl_fc_free(void *ptr, size_t size)
+{
+	free_bootmem(__pa(ptr), size);
+}
+
+void __init setup_per_cpu_areas(void)
+{
+	unsigned long delta;
+	unsigned int cpu;
+	int rc;
+
+	/*
+	 * Always reserve area for module percpu variables.  That's
+	 * what the legacy allocator did.
+	 */
+	rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
+				    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE, NULL,
+				    pcpu_dfl_fc_alloc, pcpu_dfl_fc_free);
+	if (rc < 0)
+		panic("Failed to initialized percpu areas.");
+
+	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+	for_each_possible_cpu(cpu)
+		__per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
 }
+#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
diff --git a/mm/quicklist.c b/mm/quicklist.c
index e66d07d..6eedf7e 100644
--- a/mm/quicklist.c
+++ b/mm/quicklist.c
@@ -19,7 +19,7 @@
 #include <linux/module.h>
 #include <linux/quicklist.h>
 
-DEFINE_PER_CPU(struct quicklist, quicklist)[CONFIG_NR_QUICK];
+DEFINE_PER_CPU(struct quicklist [CONFIG_NR_QUICK], quicklist);
 
 #define FRACTION_OF_NODE_MEM	16
 
diff --git a/mm/shmem.c b/mm/shmem.c
index 5a0b3d4..bd20f8b 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2298,8 +2298,7 @@ static void shmem_put_super(struct super_block *sb)
 	sb->s_fs_info = NULL;
 }
 
-static int shmem_fill_super(struct super_block *sb,
-			    void *data, int silent)
+int shmem_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct dentry *root;
@@ -2519,7 +2518,7 @@ static struct file_system_type tmpfs_fs_type = {
 	.kill_sb	= kill_litter_super,
 };
 
-static int __init init_tmpfs(void)
+int __init init_tmpfs(void)
 {
 	int error;
 
@@ -2576,7 +2575,7 @@ static struct file_system_type tmpfs_fs_type = {
 	.kill_sb	= kill_litter_super,
 };
 
-static int __init init_tmpfs(void)
+int __init init_tmpfs(void)
 {
 	BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
 
@@ -2687,5 +2686,3 @@ int shmem_zero_setup(struct vm_area_struct *vma)
 	vma->vm_ops = &shmem_vm_ops;
 	return 0;
 }
-
-module_init(init_tmpfs)
diff --git a/mm/slob.c b/mm/slob.c
index 9641da3..837ebd6 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -692,3 +692,8 @@ void __init kmem_cache_init(void)
 {
 	slob_ready = 1;
 }
+
+void __init kmem_cache_init_late(void)
+{
+	/* Nothing to do */
+}
diff --git a/mm/slub.c b/mm/slub.c
index b627675..0a216aa 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -141,6 +141,13 @@
 				SLAB_POISON | SLAB_STORE_USER)
 
 /*
+ * Debugging flags that require metadata to be stored in the slab.  These get
+ * disabled when slub_debug=O is used and a cache's min order increases with
+ * metadata.
+ */
+#define DEBUG_METADATA_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER)
+
+/*
  * Set of flags that will prevent slab merging
  */
 #define SLUB_NEVER_MERGE (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER | \
@@ -325,6 +332,7 @@ static int slub_debug;
 #endif
 
 static char *slub_debug_slabs;
+static int disable_higher_order_debug;
 
 /*
  * Object debugging
@@ -646,7 +654,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page)
 	slab_err(s, page, "Padding overwritten. 0x%p-0x%p", fault, end - 1);
 	print_section("Padding", end - remainder, remainder);
 
-	restore_bytes(s, "slab padding", POISON_INUSE, start, end);
+	restore_bytes(s, "slab padding", POISON_INUSE, end - remainder, end);
 	return 0;
 }
 
@@ -976,6 +984,15 @@ static int __init setup_slub_debug(char *str)
 		 */
 		goto check_slabs;
 
+	if (tolower(*str) == 'o') {
+		/*
+		 * Avoid enabling debugging on caches if its minimum order
+		 * would increase as a result.
+		 */
+		disable_higher_order_debug = 1;
+		goto out;
+	}
+
 	slub_debug = 0;
 	if (*str == '-')
 		/*
@@ -1026,8 +1043,8 @@ static unsigned long kmem_cache_flags(unsigned long objsize,
 	 * Enable debugging if selected on the kernel commandline.
 	 */
 	if (slub_debug && (!slub_debug_slabs ||
-	    strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs)) == 0))
-			flags |= slub_debug;
+		!strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs))))
+		flags |= slub_debug;
 
 	return flags;
 }
@@ -1054,6 +1071,8 @@ static inline unsigned long kmem_cache_flags(unsigned long objsize,
 }
 #define slub_debug 0
 
+#define disable_higher_order_debug 0
+
 static inline unsigned long slabs_node(struct kmem_cache *s, int node)
 							{ return 0; }
 static inline unsigned long node_nr_slabs(struct kmem_cache_node *n)
@@ -1109,8 +1128,7 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
 	}
 
 	if (kmemcheck_enabled
-		&& !(s->flags & (SLAB_NOTRACK | DEBUG_DEFAULT_FLAGS)))
-	{
+		&& !(s->flags & (SLAB_NOTRACK | DEBUG_DEFAULT_FLAGS))) {
 		int pages = 1 << oo_order(oo);
 
 		kmemcheck_alloc_shadow(page, oo_order(oo), flags, node);
@@ -1560,6 +1578,10 @@ slab_out_of_memory(struct kmem_cache *s, gfp_t gfpflags, int nid)
 		"default order: %d, min order: %d\n", s->name, s->objsize,
 		s->size, oo_order(s->oo), oo_order(s->min));
 
+	if (oo_order(s->min) > get_order(s->objsize))
+		printk(KERN_WARNING "  %s debugging increased min order, use "
+		       "slub_debug=O to disable.\n", s->name);
+
 	for_each_online_node(node) {
 		struct kmem_cache_node *n = get_node(s, node);
 		unsigned long nr_slabs;
@@ -2001,7 +2023,7 @@ static inline int calculate_order(int size)
 				return order;
 			fraction /= 2;
 		}
-		min_objects --;
+		min_objects--;
 	}
 
 	/*
@@ -2091,8 +2113,8 @@ init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
  */
 #define NR_KMEM_CACHE_CPU 100
 
-static DEFINE_PER_CPU(struct kmem_cache_cpu,
-				kmem_cache_cpu)[NR_KMEM_CACHE_CPU];
+static DEFINE_PER_CPU(struct kmem_cache_cpu [NR_KMEM_CACHE_CPU],
+		      kmem_cache_cpu);
 
 static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
 static DECLARE_BITMAP(kmem_cach_cpu_free_init_once, CONFIG_NR_CPUS);
@@ -2400,6 +2422,7 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
 	 * on bootup.
 	 */
 	align = calculate_alignment(flags, align, s->objsize);
+	s->align = align;
 
 	/*
 	 * SLUB stores one object immediately after another beginning from
@@ -2452,6 +2475,18 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
 
 	if (!calculate_sizes(s, -1))
 		goto error;
+	if (disable_higher_order_debug) {
+		/*
+		 * Disable debugging flags that store metadata if the min slab
+		 * order increased.
+		 */
+		if (get_order(s->size) > get_order(s->objsize)) {
+			s->flags &= ~DEBUG_METADATA_FLAGS;
+			s->offset = 0;
+			if (!calculate_sizes(s, -1))
+				goto error;
+		}
+	}
 
 	/*
 	 * The larger the object size is, the more pages we want on the partial
@@ -2790,6 +2825,11 @@ static s8 size_index[24] = {
 	2	/* 192 */
 };
 
+static inline int size_index_elem(size_t bytes)
+{
+	return (bytes - 1) / 8;
+}
+
 static struct kmem_cache *get_slab(size_t size, gfp_t flags)
 {
 	int index;
@@ -2798,7 +2838,7 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
 		if (!size)
 			return ZERO_SIZE_PTR;
 
-		index = size_index[(size - 1) / 8];
+		index = size_index[size_index_elem(size)];
 	} else
 		index = fls(size - 1);
 
@@ -3156,10 +3196,12 @@ void __init kmem_cache_init(void)
 	slab_state = PARTIAL;
 
 	/* Caches that are not of the two-to-the-power-of size */
-	if (KMALLOC_MIN_SIZE <= 64) {
+	if (KMALLOC_MIN_SIZE <= 32) {
 		create_kmalloc_cache(&kmalloc_caches[1],
 				"kmalloc-96", 96, GFP_NOWAIT);
 		caches++;
+	}
+	if (KMALLOC_MIN_SIZE <= 64) {
 		create_kmalloc_cache(&kmalloc_caches[2],
 				"kmalloc-192", 192, GFP_NOWAIT);
 		caches++;
@@ -3186,17 +3228,28 @@ void __init kmem_cache_init(void)
 	BUILD_BUG_ON(KMALLOC_MIN_SIZE > 256 ||
 		(KMALLOC_MIN_SIZE & (KMALLOC_MIN_SIZE - 1)));
 
-	for (i = 8; i < KMALLOC_MIN_SIZE; i += 8)
-		size_index[(i - 1) / 8] = KMALLOC_SHIFT_LOW;
+	for (i = 8; i < KMALLOC_MIN_SIZE; i += 8) {
+		int elem = size_index_elem(i);
+		if (elem >= ARRAY_SIZE(size_index))
+			break;
+		size_index[elem] = KMALLOC_SHIFT_LOW;
+	}
 
-	if (KMALLOC_MIN_SIZE == 128) {
+	if (KMALLOC_MIN_SIZE == 64) {
+		/*
+		 * The 96 byte size cache is not used if the alignment
+		 * is 64 byte.
+		 */
+		for (i = 64 + 8; i <= 96; i += 8)
+			size_index[size_index_elem(i)] = 7;
+	} else if (KMALLOC_MIN_SIZE == 128) {
 		/*
 		 * The 192 byte sized cache is not used if the alignment
 		 * is 128 byte. Redirect kmalloc to use the 256 byte cache
 		 * instead.
 		 */
 		for (i = 128 + 8; i <= 192; i += 8)
-			size_index[(i - 1) / 8] = 8;
+			size_index[size_index_elem(i)] = 8;
 	}
 
 	slab_state = UP;
@@ -4543,8 +4596,11 @@ static int sysfs_slab_add(struct kmem_cache *s)
 	}
 
 	err = sysfs_create_group(&s->kobj, &slab_attr_group);
-	if (err)
+	if (err) {
+		kobject_del(&s->kobj);
+		kobject_put(&s->kobj);
 		return err;
+	}
 	kobject_uevent(&s->kobj, KOBJ_ADD);
 	if (!unmergeable) {
 		/* Setup first alias */
@@ -4726,7 +4782,7 @@ static const struct file_operations proc_slabinfo_operations = {
 
 static int __init slab_proc_init(void)
 {
-	proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
+	proc_create("slabinfo", S_IRUGO, NULL, &proc_slabinfo_operations);
 	return 0;
 }
 module_init(slab_proc_init);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 8ffdc0d..74f1102 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -161,7 +161,8 @@ static int discard_swap(struct swap_info_struct *si)
 		}
 
 		err = blkdev_issue_discard(si->bdev, start_block,
-						nr_blocks, GFP_KERNEL);
+						nr_blocks, GFP_KERNEL,
+						DISCARD_FL_BARRIER);
 		if (err)
 			break;
 
@@ -200,7 +201,8 @@ static void discard_swap_cluster(struct swap_info_struct *si,
 			start_block <<= PAGE_SHIFT - 9;
 			nr_blocks <<= PAGE_SHIFT - 9;
 			if (blkdev_issue_discard(si->bdev, start_block,
-							nr_blocks, GFP_NOIO))
+							nr_blocks, GFP_NOIO,
+							DISCARD_FL_BARRIER))
 				break;
 		}
 
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index f8189a4..204b824 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -265,6 +265,7 @@ struct vmap_area {
 static DEFINE_SPINLOCK(vmap_area_lock);
 static struct rb_root vmap_area_root = RB_ROOT;
 static LIST_HEAD(vmap_area_list);
+static unsigned long vmap_area_pcpu_hole;
 
 static struct vmap_area *__find_vmap_area(unsigned long addr)
 {
@@ -431,6 +432,15 @@ static void __free_vmap_area(struct vmap_area *va)
 	RB_CLEAR_NODE(&va->rb_node);
 	list_del_rcu(&va->list);
 
+	/*
+	 * Track the highest possible candidate for pcpu area
+	 * allocation.  Areas outside of vmalloc area can be returned
+	 * here too, consider only end addresses which fall inside
+	 * vmalloc area proper.
+	 */
+	if (va->va_end > VMALLOC_START && va->va_end <= VMALLOC_END)
+		vmap_area_pcpu_hole = max(vmap_area_pcpu_hole, va->va_end);
+
 	call_rcu(&va->rcu_head, rcu_free_va);
 }
 
@@ -1038,6 +1048,9 @@ void __init vmalloc_init(void)
 		va->va_end = va->va_start + tmp->size;
 		__insert_vmap_area(va);
 	}
+
+	vmap_area_pcpu_hole = VMALLOC_END;
+
 	vmap_initialized = true;
 }
 
@@ -1122,13 +1135,34 @@ EXPORT_SYMBOL_GPL(map_vm_area);
 DEFINE_RWLOCK(vmlist_lock);
 struct vm_struct *vmlist;
 
+static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
+			      unsigned long flags, void *caller)
+{
+	struct vm_struct *tmp, **p;
+
+	vm->flags = flags;
+	vm->addr = (void *)va->va_start;
+	vm->size = va->va_end - va->va_start;
+	vm->caller = caller;
+	va->private = vm;
+	va->flags |= VM_VM_AREA;
+
+	write_lock(&vmlist_lock);
+	for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) {
+		if (tmp->addr >= vm->addr)
+			break;
+	}
+	vm->next = *p;
+	*p = vm;
+	write_unlock(&vmlist_lock);
+}
+
 static struct vm_struct *__get_vm_area_node(unsigned long size,
 		unsigned long flags, unsigned long start, unsigned long end,
 		int node, gfp_t gfp_mask, void *caller)
 {
 	static struct vmap_area *va;
 	struct vm_struct *area;
-	struct vm_struct *tmp, **p;
 	unsigned long align = 1;
 
 	BUG_ON(in_interrupt());
@@ -1147,7 +1181,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
 	if (unlikely(!size))
 		return NULL;
 
-	area = kmalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node);
+	area = kzalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node);
 	if (unlikely(!area))
 		return NULL;
 
@@ -1162,25 +1196,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
 		return NULL;
 	}
 
-	area->flags = flags;
-	area->addr = (void *)va->va_start;
-	area->size = size;
-	area->pages = NULL;
-	area->nr_pages = 0;
-	area->phys_addr = 0;
-	area->caller = caller;
-	va->private = area;
-	va->flags |= VM_VM_AREA;
-
-	write_lock(&vmlist_lock);
-	for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) {
-		if (tmp->addr >= area->addr)
-			break;
-	}
-	area->next = *p;
-	*p = area;
-	write_unlock(&vmlist_lock);
-
+	insert_vmalloc_vm(area, va, flags, caller);
 	return area;
 }
 
@@ -1818,6 +1834,286 @@ void free_vm_area(struct vm_struct *area)
 }
 EXPORT_SYMBOL_GPL(free_vm_area);
 
+static struct vmap_area *node_to_va(struct rb_node *n)
+{
+	return n ? rb_entry(n, struct vmap_area, rb_node) : NULL;
+}
+
+/**
+ * pvm_find_next_prev - find the next and prev vmap_area surrounding @end
+ * @end: target address
+ * @pnext: out arg for the next vmap_area
+ * @pprev: out arg for the previous vmap_area
+ *
+ * Returns: %true if either or both of next and prev are found,
+ *	    %false if no vmap_area exists
+ *
+ * Find vmap_areas end addresses of which enclose @end.  ie. if not
+ * NULL, *pnext->va_end > @end and *pprev->va_end <= @end.
+ */
+static bool pvm_find_next_prev(unsigned long end,
+			       struct vmap_area **pnext,
+			       struct vmap_area **pprev)
+{
+	struct rb_node *n = vmap_area_root.rb_node;
+	struct vmap_area *va = NULL;
+
+	while (n) {
+		va = rb_entry(n, struct vmap_area, rb_node);
+		if (end < va->va_end)
+			n = n->rb_left;
+		else if (end > va->va_end)
+			n = n->rb_right;
+		else
+			break;
+	}
+
+	if (!va)
+		return false;
+
+	if (va->va_end > end) {
+		*pnext = va;
+		*pprev = node_to_va(rb_prev(&(*pnext)->rb_node));
+	} else {
+		*pprev = va;
+		*pnext = node_to_va(rb_next(&(*pprev)->rb_node));
+	}
+	return true;
+}
+
+/**
+ * pvm_determine_end - find the highest aligned address between two vmap_areas
+ * @pnext: in/out arg for the next vmap_area
+ * @pprev: in/out arg for the previous vmap_area
+ * @align: alignment
+ *
+ * Returns: determined end address
+ *
+ * Find the highest aligned address between *@pnext and *@pprev below
+ * VMALLOC_END.  *@pnext and *@pprev are adjusted so that the aligned
+ * down address is between the end addresses of the two vmap_areas.
+ *
+ * Please note that the address returned by this function may fall
+ * inside *@pnext vmap_area.  The caller is responsible for checking
+ * that.
+ */
+static unsigned long pvm_determine_end(struct vmap_area **pnext,
+				       struct vmap_area **pprev,
+				       unsigned long align)
+{
+	const unsigned long vmalloc_end = VMALLOC_END & ~(align - 1);
+	unsigned long addr;
+
+	if (*pnext)
+		addr = min((*pnext)->va_start & ~(align - 1), vmalloc_end);
+	else
+		addr = vmalloc_end;
+
+	while (*pprev && (*pprev)->va_end > addr) {
+		*pnext = *pprev;
+		*pprev = node_to_va(rb_prev(&(*pnext)->rb_node));
+	}
+
+	return addr;
+}
+
+/**
+ * pcpu_get_vm_areas - allocate vmalloc areas for percpu allocator
+ * @offsets: array containing offset of each area
+ * @sizes: array containing size of each area
+ * @nr_vms: the number of areas to allocate
+ * @align: alignment, all entries in @offsets and @sizes must be aligned to this
+ * @gfp_mask: allocation mask
+ *
+ * Returns: kmalloc'd vm_struct pointer array pointing to allocated
+ *	    vm_structs on success, %NULL on failure
+ *
+ * Percpu allocator wants to use congruent vm areas so that it can
+ * maintain the offsets among percpu areas.  This function allocates
+ * congruent vmalloc areas for it.  These areas tend to be scattered
+ * pretty far, distance between two areas easily going up to
+ * gigabytes.  To avoid interacting with regular vmallocs, these areas
+ * are allocated from top.
+ *
+ * Despite its complicated look, this allocator is rather simple.  It
+ * does everything top-down and scans areas from the end looking for
+ * matching slot.  While scanning, if any of the areas overlaps with
+ * existing vmap_area, the base address is pulled down to fit the
+ * area.  Scanning is repeated till all the areas fit and then all
+ * necessary data structres are inserted and the result is returned.
+ */
+struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
+				     const size_t *sizes, int nr_vms,
+				     size_t align, gfp_t gfp_mask)
+{
+	const unsigned long vmalloc_start = ALIGN(VMALLOC_START, align);
+	const unsigned long vmalloc_end = VMALLOC_END & ~(align - 1);
+	struct vmap_area **vas, *prev, *next;
+	struct vm_struct **vms;
+	int area, area2, last_area, term_area;
+	unsigned long base, start, end, last_end;
+	bool purged = false;
+
+	gfp_mask &= GFP_RECLAIM_MASK;
+
+	/* verify parameters and allocate data structures */
+	BUG_ON(align & ~PAGE_MASK || !is_power_of_2(align));
+	for (last_area = 0, area = 0; area < nr_vms; area++) {
+		start = offsets[area];
+		end = start + sizes[area];
+
+		/* is everything aligned properly? */
+		BUG_ON(!IS_ALIGNED(offsets[area], align));
+		BUG_ON(!IS_ALIGNED(sizes[area], align));
+
+		/* detect the area with the highest address */
+		if (start > offsets[last_area])
+			last_area = area;
+
+		for (area2 = 0; area2 < nr_vms; area2++) {
+			unsigned long start2 = offsets[area2];
+			unsigned long end2 = start2 + sizes[area2];
+
+			if (area2 == area)
+				continue;
+
+			BUG_ON(start2 >= start && start2 < end);
+			BUG_ON(end2 <= end && end2 > start);
+		}
+	}
+	last_end = offsets[last_area] + sizes[last_area];
+
+	if (vmalloc_end - vmalloc_start < last_end) {
+		WARN_ON(true);
+		return NULL;
+	}
+
+	vms = kzalloc(sizeof(vms[0]) * nr_vms, gfp_mask);
+	vas = kzalloc(sizeof(vas[0]) * nr_vms, gfp_mask);
+	if (!vas || !vms)
+		goto err_free;
+
+	for (area = 0; area < nr_vms; area++) {
+		vas[area] = kzalloc(sizeof(struct vmap_area), gfp_mask);
+		vms[area] = kzalloc(sizeof(struct vm_struct), gfp_mask);
+		if (!vas[area] || !vms[area])
+			goto err_free;
+	}
+retry:
+	spin_lock(&vmap_area_lock);
+
+	/* start scanning - we scan from the top, begin with the last area */
+	area = term_area = last_area;
+	start = offsets[area];
+	end = start + sizes[area];
+
+	if (!pvm_find_next_prev(vmap_area_pcpu_hole, &next, &prev)) {
+		base = vmalloc_end - last_end;
+		goto found;
+	}
+	base = pvm_determine_end(&next, &prev, align) - end;
+
+	while (true) {
+		BUG_ON(next && next->va_end <= base + end);
+		BUG_ON(prev && prev->va_end > base + end);
+
+		/*
+		 * base might have underflowed, add last_end before
+		 * comparing.
+		 */
+		if (base + last_end < vmalloc_start + last_end) {
+			spin_unlock(&vmap_area_lock);
+			if (!purged) {
+				purge_vmap_area_lazy();
+				purged = true;
+				goto retry;
+			}
+			goto err_free;
+		}
+
+		/*
+		 * If next overlaps, move base downwards so that it's
+		 * right below next and then recheck.
+		 */
+		if (next && next->va_start < base + end) {
+			base = pvm_determine_end(&next, &prev, align) - end;
+			term_area = area;
+			continue;
+		}
+
+		/*
+		 * If prev overlaps, shift down next and prev and move
+		 * base so that it's right below new next and then
+		 * recheck.
+		 */
+		if (prev && prev->va_end > base + start)  {
+			next = prev;
+			prev = node_to_va(rb_prev(&next->rb_node));
+			base = pvm_determine_end(&next, &prev, align) - end;
+			term_area = area;
+			continue;
+		}
+
+		/*
+		 * This area fits, move on to the previous one.  If
+		 * the previous one is the terminal one, we're done.
+		 */
+		area = (area + nr_vms - 1) % nr_vms;
+		if (area == term_area)
+			break;
+		start = offsets[area];
+		end = start + sizes[area];
+		pvm_find_next_prev(base + end, &next, &prev);
+	}
+found:
+	/* we've found a fitting base, insert all va's */
+	for (area = 0; area < nr_vms; area++) {
+		struct vmap_area *va = vas[area];
+
+		va->va_start = base + offsets[area];
+		va->va_end = va->va_start + sizes[area];
+		__insert_vmap_area(va);
+	}
+
+	vmap_area_pcpu_hole = base + offsets[last_area];
+
+	spin_unlock(&vmap_area_lock);
+
+	/* insert all vm's */
+	for (area = 0; area < nr_vms; area++)
+		insert_vmalloc_vm(vms[area], vas[area], VM_ALLOC,
+				  pcpu_get_vm_areas);
+
+	kfree(vas);
+	return vms;
+
+err_free:
+	for (area = 0; area < nr_vms; area++) {
+		if (vas)
+			kfree(vas[area]);
+		if (vms)
+			kfree(vms[area]);
+	}
+	kfree(vas);
+	kfree(vms);
+	return NULL;
+}
+
+/**
+ * pcpu_free_vm_areas - free vmalloc areas for percpu allocator
+ * @vms: vm_struct pointer array returned by pcpu_get_vm_areas()
+ * @nr_vms: the number of allocated areas
+ *
+ * Free vm_structs and the array allocated by pcpu_get_vm_areas().
+ */
+void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms)
+{
+	int i;
+
+	for (i = 0; i < nr_vms; i++)
+		free_vm_area(vms[i]);
+	kfree(vms);
+}
 
 #ifdef CONFIG_PROC_FS
 static void *s_start(struct seq_file *m, loff_t *pos)
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index fe64908..8836575 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -225,12 +225,6 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id)
 		return -EOPNOTSUPP;
 	}
 
-	/* The real device must be up and operating in order to
-	 * assosciate a VLAN device with it.
-	 */
-	if (!(real_dev->flags & IFF_UP))
-		return -ENETDOWN;
-
 	if (__find_vlan_dev(real_dev, vlan_id) != NULL)
 		return -EEXIST;
 
@@ -336,12 +330,13 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
 		snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id);
 	}
 
-	new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name,
-			       vlan_setup);
+	new_dev = alloc_netdev_mq(sizeof(struct vlan_dev_info), name,
+				  vlan_setup, real_dev->num_tx_queues);
 
 	if (new_dev == NULL)
 		return -ENOBUFS;
 
+	new_dev->real_num_tx_queues = real_dev->real_num_tx_queues;
 	dev_net_set(new_dev, net);
 	/* need 4 bytes for extra VLAN header info,
 	 * hope the underlying device can handle it.
@@ -397,6 +392,9 @@ static void vlan_transfer_features(struct net_device *dev,
 	vlandev->features &= ~dev->vlan_features;
 	vlandev->features |= dev->features & dev->vlan_features;
 	vlandev->gso_max_size = dev->gso_max_size;
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+	vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
+#endif
 
 	if (old_features != vlandev->features)
 		netdev_features_change(vlandev);
@@ -468,6 +466,19 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 		}
 		break;
 
+	case NETDEV_CHANGEMTU:
+		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+			vlandev = vlan_group_get_device(grp, i);
+			if (!vlandev)
+				continue;
+
+			if (vlandev->mtu <= dev->mtu)
+				continue;
+
+			dev_set_mtu(vlandev, dev->mtu);
+		}
+		break;
+
 	case NETDEV_FEAT_CHANGE:
 		/* Propagate device features to underlying device */
 		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 96bad8f..4198ec5 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -288,10 +288,14 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 	return rc;
 }
 
-static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev)
 {
-	struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+	int i = skb_get_queue_mapping(skb);
+	struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
 	struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
+	unsigned int len;
+	int ret;
 
 	/* Handle non-VLAN frames if they are sent to us, for example by DHCP.
 	 *
@@ -317,29 +321,43 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
 	}
 
-	txq->tx_packets++;
-	txq->tx_bytes += skb->len;
 
 	skb->dev = vlan_dev_info(dev)->real_dev;
-	dev_queue_xmit(skb);
+	len = skb->len;
+	ret = dev_queue_xmit(skb);
+
+	if (likely(ret == NET_XMIT_SUCCESS)) {
+		txq->tx_packets++;
+		txq->tx_bytes += len;
+	} else
+		txq->tx_dropped++;
+
 	return NETDEV_TX_OK;
 }
 
-static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
-					    struct net_device *dev)
+static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
+						    struct net_device *dev)
 {
-	struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+	int i = skb_get_queue_mapping(skb);
+	struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
 	u16 vlan_tci;
+	unsigned int len;
+	int ret;
 
 	vlan_tci = vlan_dev_info(dev)->vlan_id;
 	vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
 	skb = __vlan_hwaccel_put_tag(skb, vlan_tci);
 
-	txq->tx_packets++;
-	txq->tx_bytes += skb->len;
-
 	skb->dev = vlan_dev_info(dev)->real_dev;
-	dev_queue_xmit(skb);
+	len = skb->len;
+	ret = dev_queue_xmit(skb);
+
+	if (likely(ret == NET_XMIT_SUCCESS)) {
+		txq->tx_packets++;
+		txq->tx_bytes += len;
+	} else
+		txq->tx_dropped++;
+
 	return NETDEV_TX_OK;
 }
 
@@ -561,6 +579,55 @@ static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa)
 	return err;
 }
 
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid,
+				   struct scatterlist *sgl, unsigned int sgc)
+{
+	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
+	int rc = 0;
+
+	if (ops->ndo_fcoe_ddp_setup)
+		rc = ops->ndo_fcoe_ddp_setup(real_dev, xid, sgl, sgc);
+
+	return rc;
+}
+
+static int vlan_dev_fcoe_ddp_done(struct net_device *dev, u16 xid)
+{
+	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
+	int len = 0;
+
+	if (ops->ndo_fcoe_ddp_done)
+		len = ops->ndo_fcoe_ddp_done(real_dev, xid);
+
+	return len;
+}
+
+static int vlan_dev_fcoe_enable(struct net_device *dev)
+{
+	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
+	int rc = -EINVAL;
+
+	if (ops->ndo_fcoe_enable)
+		rc = ops->ndo_fcoe_enable(real_dev);
+	return rc;
+}
+
+static int vlan_dev_fcoe_disable(struct net_device *dev)
+{
+	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+	const struct net_device_ops *ops = real_dev->netdev_ops;
+	int rc = -EINVAL;
+
+	if (ops->ndo_fcoe_disable)
+		rc = ops->ndo_fcoe_disable(real_dev);
+	return rc;
+}
+#endif
+
 static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
 {
 	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
@@ -635,6 +702,10 @@ static int vlan_dev_init(struct net_device *dev)
 	if (is_zero_ether_addr(dev->broadcast))
 		memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
 
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+	dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid;
+#endif
+
 	if (real_dev->features & NETIF_F_HW_VLAN_TX) {
 		dev->header_ops      = real_dev->header_ops;
 		dev->hard_header_len = real_dev->hard_header_len;
@@ -715,6 +786,12 @@ static const struct net_device_ops vlan_netdev_ops = {
 	.ndo_change_rx_flags	= vlan_dev_change_rx_flags,
 	.ndo_do_ioctl		= vlan_dev_ioctl,
 	.ndo_neigh_setup	= vlan_dev_neigh_setup,
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+	.ndo_fcoe_ddp_setup	= vlan_dev_fcoe_ddp_setup,
+	.ndo_fcoe_ddp_done	= vlan_dev_fcoe_ddp_done,
+	.ndo_fcoe_enable	= vlan_dev_fcoe_enable,
+	.ndo_fcoe_disable	= vlan_dev_fcoe_disable,
+#endif
 };
 
 static const struct net_device_ops vlan_netdev_accel_ops = {
@@ -731,6 +808,12 @@ static const struct net_device_ops vlan_netdev_accel_ops = {
 	.ndo_change_rx_flags	= vlan_dev_change_rx_flags,
 	.ndo_do_ioctl		= vlan_dev_ioctl,
 	.ndo_neigh_setup	= vlan_dev_neigh_setup,
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+	.ndo_fcoe_ddp_setup	= vlan_dev_fcoe_ddp_setup,
+	.ndo_fcoe_ddp_done	= vlan_dev_fcoe_ddp_done,
+	.ndo_fcoe_enable	= vlan_dev_fcoe_enable,
+	.ndo_fcoe_disable	= vlan_dev_fcoe_disable,
+#endif
 };
 
 void vlan_setup(struct net_device *dev)
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index e9c91dc..343146e 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -100,6 +100,25 @@ static int vlan_changelink(struct net_device *dev,
 	return 0;
 }
 
+static int vlan_get_tx_queues(struct net *net,
+			      struct nlattr *tb[],
+			      unsigned int *num_tx_queues,
+			      unsigned int *real_num_tx_queues)
+{
+	struct net_device *real_dev;
+
+	if (!tb[IFLA_LINK])
+		return -EINVAL;
+
+	real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK]));
+	if (!real_dev)
+		return -ENODEV;
+
+	*num_tx_queues      = real_dev->num_tx_queues;
+	*real_num_tx_queues = real_dev->real_num_tx_queues;
+	return 0;
+}
+
 static int vlan_newlink(struct net_device *dev,
 			struct nlattr *tb[], struct nlattr *data[])
 {
@@ -216,6 +235,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = {
 	.maxtype	= IFLA_VLAN_MAX,
 	.policy		= vlan_policy,
 	.priv_size	= sizeof(struct vlan_dev_info),
+	.get_tx_queues  = vlan_get_tx_queues,
 	.setup		= vlan_setup,
 	.validate	= vlan_validate,
 	.newlink	= vlan_newlink,
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index b55a091..6262c33 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -107,7 +107,7 @@ static const struct file_operations vlandev_fops = {
  */
 
 /* Strings */
-static const char *vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
+static const char *const vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
     [VLAN_NAME_TYPE_RAW_PLUS_VID]        = "VLAN_NAME_TYPE_RAW_PLUS_VID",
     [VLAN_NAME_TYPE_PLUS_VID_NO_PAD]	 = "VLAN_NAME_TYPE_PLUS_VID_NO_PAD",
     [VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD",
diff --git a/net/Kconfig b/net/Kconfig
index 7051b97..041c35e 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -23,6 +23,26 @@ menuconfig NET
 
 if NET
 
+config WANT_COMPAT_NETLINK_MESSAGES
+	bool
+	help
+	  This option can be selected by other options that need compat
+	  netlink messages.
+
+config COMPAT_NETLINK_MESSAGES
+	def_bool y
+	depends on COMPAT
+	depends on WIRELESS_EXT || WANT_COMPAT_NETLINK_MESSAGES
+	help
+	  This option makes it possible to send different netlink messages
+	  to tasks depending on whether the task is a compat task or not. To
+	  achieve this, you need to set skb_shinfo(skb)->frag_list to the
+	  compat skb before sending the skb, the netlink code will sort out
+	  which message to actually pass to the task.
+
+	  Newly written code should NEVER need this option but do
+	  compat-independent messages instead!
+
 menu "Networking options"
 
 source "net/packet/Kconfig"
diff --git a/net/Makefile b/net/Makefile
index ba324ae..1542e72 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -24,7 +24,6 @@ obj-y				+= ipv6/
 endif
 obj-$(CONFIG_PACKET)		+= packet/
 obj-$(CONFIG_NET_KEY)		+= key/
-obj-$(CONFIG_NET_SCHED)		+= sched/
 obj-$(CONFIG_BRIDGE)		+= bridge/
 obj-$(CONFIG_NET_DSA)		+= dsa/
 obj-$(CONFIG_IPX)		+= ipx/
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index 89f99d3..9d4adfd 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -599,7 +599,7 @@ int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb,
 
 	/* Non ELAP we cannot do. */
 	if (dev->type != ARPHRD_ETHER)
-		return -1;
+		goto free_it;
 
 	skb->dev = dev;
 	skb->protocol = htons(ETH_P_ATALK);
@@ -634,7 +634,7 @@ int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb,
 	if (!a) {
 		/* Whoops slipped... good job it's an unreliable protocol 8) */
 		write_unlock_bh(&aarp_lock);
-		return -1;
+		goto free_it;
 	}
 
 	/* Set up the queue */
@@ -663,15 +663,21 @@ out_unlock:
 	write_unlock_bh(&aarp_lock);
 
 	/* Tell the ddp layer we have taken over for this frame. */
-	return 0;
+	goto sent;
 
 sendit:
 	if (skb->sk)
 		skb->priority = skb->sk->sk_priority;
-	dev_queue_xmit(skb);
+	if (dev_queue_xmit(skb))
+		goto drop;
 sent:
-	return 1;
+	return NET_XMIT_SUCCESS;
+free_it:
+	kfree_skb(skb);
+drop:
+	return NET_XMIT_DROP;
 }
+EXPORT_SYMBOL(aarp_send_ddp);
 
 /*
  *	An entry in the aarp unresolved queue has become resolved. Send
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 875eda5..b1a4290 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1270,8 +1270,10 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
 	struct net_device_stats *stats;
 
 	/* This needs to be able to handle ipddp"N" devices */
-	if (!dev)
-		return -ENODEV;
+	if (!dev) {
+		kfree_skb(skb);
+		return NET_RX_DROP;
+	}
 
 	skb->protocol = htons(ETH_P_IP);
 	skb_pull(skb, 13);
@@ -1281,8 +1283,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
 	stats = netdev_priv(dev);
 	stats->rx_packets++;
 	stats->rx_bytes += skb->len + 13;
-	netif_rx(skb);  /* Send the SKB up to a higher place. */
-	return 0;
+	return netif_rx(skb);  /* Send the SKB up to a higher place. */
 }
 #else
 /* make it easy for gcc to optimize this test out, i.e. kill the code */
@@ -1290,9 +1291,8 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
 #define handle_ip_over_ddp(skb) 0
 #endif
 
-static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
-			       struct ddpehdr *ddp, __u16 len_hops,
-			       int origlen)
+static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
+			      struct ddpehdr *ddp, __u16 len_hops, int origlen)
 {
 	struct atalk_route *rt;
 	struct atalk_addr ta;
@@ -1359,8 +1359,6 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
 		/* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
 		struct sk_buff *nskb = skb_realloc_headroom(skb, 32);
 		kfree_skb(skb);
-		if (!nskb)
-			goto out;
 		skb = nskb;
 	} else
 		skb = skb_unshare(skb, GFP_ATOMIC);
@@ -1369,12 +1367,16 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
 	 * If the buffer didn't vanish into the lack of space bitbucket we can
 	 * send it.
 	 */
-	if (skb && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1)
-		goto free_it;
-out:
-	return;
+	if (skb == NULL)
+		goto drop;
+
+	if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP)
+		return NET_RX_DROP;
+	return NET_RX_SUCCESS;
 free_it:
 	kfree_skb(skb);
+drop:
+	return NET_RX_DROP;
 }
 
 /**
@@ -1400,7 +1402,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 	__u16 len_hops;
 
 	if (!net_eq(dev_net(dev), &init_net))
-		goto freeit;
+		goto drop;
 
 	/* Don't mangle buffer if shared */
 	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
@@ -1408,7 +1410,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 
 	/* Size check and make sure header is contiguous */
 	if (!pskb_may_pull(skb, sizeof(*ddp)))
-		goto freeit;
+		goto drop;
 
 	ddp = ddp_hdr(skb);
 
@@ -1426,7 +1428,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 	if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) {
 		pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, "
 			 "skb->len=%u)\n", len_hops & 1023, skb->len);
-		goto freeit;
+		goto drop;
 	}
 
 	/*
@@ -1436,7 +1438,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 	if (ddp->deh_sum &&
 	    atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum)
 		/* Not a valid AppleTalk frame - dustbin time */
-		goto freeit;
+		goto drop;
 
 	/* Check the packet is aimed at us */
 	if (!ddp->deh_dnet)	/* Net 0 is 'this network' */
@@ -1448,8 +1450,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 		/* Not ours, so we route the packet via the correct
 		 * AppleTalk iface
 		 */
-		atalk_route_packet(skb, dev, ddp, len_hops, origlen);
-		goto out;
+		return atalk_route_packet(skb, dev, ddp, len_hops, origlen);
 	}
 
 	/* if IP over DDP is not selected this code will be optimized out */
@@ -1465,18 +1466,21 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 
 	sock = atalk_search_socket(&tosat, atif);
 	if (!sock) /* But not one of our sockets */
-		goto freeit;
+		goto drop;
 
 	/* Queue packet (standard) */
 	skb->sk = sock;
 
 	if (sock_queue_rcv_skb(sock, skb) < 0)
-		goto freeit;
-out:
-	return 0;
-freeit:
+		goto drop;
+
+	return NET_RX_SUCCESS;
+
+drop:
 	kfree_skb(skb);
-	goto out;
+out:
+	return NET_RX_DROP;
+
 }
 
 /*
@@ -1652,10 +1656,10 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
 		if (skb2) {
 			loopback = 1;
 			SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
-			if (aarp_send_ddp(dev, skb2,
-					  &usat->sat_addr, NULL) == -1)
-				kfree_skb(skb2);
-				/* else queued/sent above in the aarp queue */
+			/*
+			 * If it fails it is queued/sent above in the aarp queue
+			 */
+			aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL);
 		}
 	}
 
@@ -1685,9 +1689,10 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
 		    usat = &gsat;
 		}
 
-		if (aarp_send_ddp(dev, skb, &usat->sat_addr, NULL) == -1)
-			kfree_skb(skb);
-		/* else queued/sent above in the aarp queue */
+		/*
+		 * If it fails it is queued/sent above in the aarp queue
+		 */
+		aarp_send_ddp(dev, skb, &usat->sat_addr, NULL);
 	}
 	SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len);
 
@@ -1865,7 +1870,6 @@ static struct packet_type ppptalk_packet_type __read_mostly = {
 static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B };
 
 /* Export symbols for use by drivers when AppleTalk is a module */
-EXPORT_SYMBOL(aarp_send_ddp);
 EXPORT_SYMBOL(atrtr_get_dev);
 EXPORT_SYMBOL(atalk_find_dev_addr);
 
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 2912665..26a646d 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -69,7 +69,7 @@ struct br2684_vcc {
 	struct net_device *device;
 	/* keep old push, pop functions for chaining */
 	void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb);
-	/* void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); */
+	void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
 	enum br2684_encaps encaps;
 	struct list_head brvccs;
 #ifdef CONFIG_ATM_BR2684_IPFILTER
@@ -142,6 +142,22 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
 	return NULL;
 }
 
+/* chained vcc->pop function.  Check if we should wake the netif_queue */
+static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	struct br2684_vcc *brvcc = BR2684_VCC(vcc);
+	struct net_device *net_dev = skb->dev;
+
+	pr_debug("br2684_pop(vcc %p ; net_dev %p )\n", vcc, net_dev);
+	brvcc->old_pop(vcc, skb);
+
+	if (!net_dev)
+		return;
+
+	if (atm_may_send(vcc, 0))
+		netif_wake_queue(net_dev);
+
+}
 /*
  * Send a packet out a particular vcc.  Not to useful right now, but paves
  * the way for multiple vcc's per itf.  Returns true if we can send,
@@ -200,20 +216,19 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
 
 	ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
 	pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
-	if (!atm_may_send(atmvcc, skb->truesize)) {
-		/*
-		 * We free this here for now, because we cannot know in a higher
-		 * layer whether the skb pointer it supplied wasn't freed yet.
-		 * Now, it always is.
-		 */
-		dev_kfree_skb(skb);
-		return 0;
-	}
 	atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc);
 	ATM_SKB(skb)->atm_options = atmvcc->atm_options;
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 	atmvcc->send(atmvcc, skb);
+
+	if (!atm_may_send(atmvcc, 0)) {
+		netif_stop_queue(brvcc->device);
+		/*check for race with br2684_pop*/
+		if (atm_may_send(atmvcc, 0))
+			netif_start_queue(brvcc->device);
+	}
+
 	return 1;
 }
 
@@ -223,7 +238,8 @@ static inline struct br2684_vcc *pick_outgoing_vcc(const struct sk_buff *skb,
 	return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next);	/* 1 vcc/dev right now */
 }
 
-static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t br2684_start_xmit(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct br2684_dev *brdev = BRPRIV(dev);
 	struct br2684_vcc *brvcc;
@@ -238,7 +254,7 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		/* netif_stop_queue(dev); */
 		dev_kfree_skb(skb);
 		read_unlock(&devs_lock);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (!br2684_xmit_vcc(skb, dev, brvcc)) {
 		/*
@@ -252,7 +268,7 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		dev->stats.tx_fifo_errors++;
 	}
 	read_unlock(&devs_lock);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -503,8 +519,10 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
 	atmvcc->user_back = brvcc;
 	brvcc->encaps = (enum br2684_encaps)be.encaps;
 	brvcc->old_push = atmvcc->push;
+	brvcc->old_pop = atmvcc->pop;
 	barrier();
 	atmvcc->push = br2684_push;
+	atmvcc->pop = br2684_pop;
 
 	__skb_queue_head_init(&queue);
 	rq = &sk_atm(atmvcc)->sk_receive_queue;
diff --git a/net/atm/clip.c b/net/atm/clip.c
index e65a3b1..64629c3 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -267,7 +267,7 @@ static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb)
 	kfree_skb(skb);
 }
 
-static struct neigh_ops clip_neigh_ops = {
+static const struct neigh_ops clip_neigh_ops = {
 	.family =		AF_INET,
 	.solicit =		clip_neigh_solicit,
 	.error_report =		clip_neigh_error,
@@ -360,7 +360,8 @@ static int clip_encap(struct atm_vcc *vcc, int mode)
 	return 0;
 }
 
-static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
+				   struct net_device *dev)
 {
 	struct clip_priv *clip_priv = PRIV(dev);
 	struct atmarp_entry *entry;
@@ -373,7 +374,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_ERR "clip_start_xmit: skb_dst(skb) == NULL\n");
 		dev_kfree_skb(skb);
 		dev->stats.tx_dropped++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	if (!skb_dst(skb)->neighbour) {
 #if 0
@@ -387,7 +388,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		printk(KERN_ERR "clip_start_xmit: NO NEIGHBOUR !\n");
 		dev_kfree_skb(skb);
 		dev->stats.tx_dropped++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	entry = NEIGH2ENTRY(skb_dst(skb)->neighbour);
 	if (!entry->vccs) {
@@ -402,7 +403,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			dev_kfree_skb(skb);
 			dev->stats.tx_dropped++;
 		}
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
 	ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
@@ -421,14 +422,14 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	old = xchg(&entry->vccs->xoff, 1);	/* assume XOFF ... */
 	if (old) {
 		printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n");
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 	vcc->send(vcc, skb);
 	if (atm_may_send(vcc, 0)) {
 		entry->vccs->xoff = 0;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 	spin_lock_irqsave(&clip_priv->xoff_lock, flags);
 	netif_stop_queue(dev);	/* XOFF -> throttle immediately */
@@ -440,7 +441,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	   of the brief netif_stop_queue. If this isn't true or if it
 	   changes, use netif_wake_queue instead. */
 	spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int clip_mkip(struct atm_vcc *vcc, int timeout)
diff --git a/net/atm/lec.c b/net/atm/lec.c
index ff2e594..b2d6445 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -59,7 +59,8 @@ static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
 				 */
 
 static int lec_open(struct net_device *dev);
-static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t lec_start_xmit(struct sk_buff *skb,
+				  struct net_device *dev);
 static int lec_close(struct net_device *dev);
 static void lec_init(struct net_device *dev);
 static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
@@ -247,7 +248,8 @@ static void lec_tx_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t lec_start_xmit(struct sk_buff *skb,
+				  struct net_device *dev)
 {
 	struct sk_buff *skb2;
 	struct lec_priv *priv = netdev_priv(dev);
@@ -289,7 +291,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
 		kfree_skb(skb);
 		if (skb2 == NULL)
-			return 0;
+			return NETDEV_TX_OK;
 		skb = skb2;
 	}
 	skb_push(skb, 2);
@@ -307,7 +309,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
 		kfree_skb(skb);
 		if (skb2 == NULL)
-			return 0;
+			return NETDEV_TX_OK;
 		skb = skb2;
 	}
 #endif
@@ -345,7 +347,7 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			dev_kfree_skb(skb);
 			if (skb2 == NULL) {
 				dev->stats.tx_dropped++;
-				return 0;
+				return NETDEV_TX_OK;
 			}
 			skb = skb2;
 		}
@@ -416,7 +418,7 @@ out:
 	if (entry)
 		lec_arp_put(entry);
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /* The inverse routine to net_open(). */
@@ -935,9 +937,9 @@ static int lecd_attach(struct atm_vcc *vcc, int arg)
 }
 
 #ifdef CONFIG_PROC_FS
-static char *lec_arp_get_status_string(unsigned char status)
+static const char *lec_arp_get_status_string(unsigned char status)
 {
-	static char *lec_arp_status_string[] = {
+	static const char *const lec_arp_status_string[] = {
 		"ESI_UNKNOWN       ",
 		"ESI_ARP_PENDING   ",
 		"ESI_VC_PENDING    ",
@@ -1121,7 +1123,8 @@ static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
 static int lec_seq_show(struct seq_file *seq, void *v)
 {
-	static char lec_banner[] = "Itf  MAC          ATM destination"
+	static const char lec_banner[] =
+	    "Itf  MAC          ATM destination"
 	    "                          Status            Flags "
 	    "VPI/VCI Recv VPI/VCI\n";
 
@@ -1505,7 +1508,7 @@ lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
 }
 
 #if DEBUG_ARP_TABLE
-static char *get_status_string(unsigned char st)
+static const char *get_status_string(unsigned char st)
 {
 	switch (st) {
 	case ESI_UNKNOWN:
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index e5bf114..38a6cb0 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -73,7 +73,8 @@ static void mpoad_close(struct atm_vcc *vcc);
 static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb);
 
 static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb);
-static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mpc_send_packet(struct sk_buff *skb,
+					 struct net_device *dev);
 static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned long event, void *dev);
 static void mpc_timer_refresh(void);
 static void mpc_cache_check( unsigned long checking_time  );
@@ -528,7 +529,8 @@ static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc)
 /*
  * Probably needs some error checks and locking, not sure...
  */
-static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mpc_send_packet(struct sk_buff *skb,
+					 struct net_device *dev)
 {
 	struct mpoa_client *mpc;
 	struct ethhdr *eth;
@@ -554,7 +556,7 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
 	while (i < mpc->number_of_mps_macs) {
 		if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN)))
 			if ( send_via_shortcut(skb, mpc) == 0 )           /* try shortcut */
-				return 0;                                 /* success!     */
+				return NETDEV_TX_OK;                      /* success!     */
 		i++;
 	}
 
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 38de5ff..ab8419a 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -151,8 +151,9 @@ static void *vcc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
 static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
 {
-	static const char *class_name[] = { "off","UBR","CBR","VBR","ABR" };
-	static const char *aal_name[] = {
+	static const char *const class_name[] =
+		{"off","UBR","CBR","VBR","ABR"};
+	static const char *const aal_name[] = {
 		"---",	"1",	"2",	"3/4",	/*  0- 3 */
 		"???",	"5",	"???",	"???",	/*  4- 7 */
 		"???",	"???",	"???",	"???",	/*  8-11 */
@@ -178,7 +179,7 @@ static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
 
 static const char *vcc_state(struct atm_vcc *vcc)
 {
-	static const char *map[] = { ATM_VS2TXT_MAP };
+	static const char *const map[] = { ATM_VS2TXT_MAP };
 
 	return map[ATM_VF2VS(vcc->flags)];
 }
@@ -335,7 +336,7 @@ static const struct file_operations vcc_seq_fops = {
 
 static int svc_seq_show(struct seq_file *seq, void *v)
 {
-	static char atm_svc_banner[] =
+	static const char atm_svc_banner[] =
 		"Itf VPI VCI           State      Remote\n";
 
 	if (v == SEQ_START_TOKEN)
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 59fdb1d..ed37168 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -34,6 +34,7 @@ menuconfig BT
 config BT_L2CAP
 	tristate "L2CAP protocol support"
 	depends on BT
+	select CRC16
 	help
 	  L2CAP (Logical Link Control and Adaptation Protocol) provides
 	  connection oriented and connection-less data transport.  L2CAP
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 0250e06..8cfb5a8 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -49,7 +49,7 @@ static struct net_proto_family *bt_proto[BT_MAX_PROTO];
 static DEFINE_RWLOCK(bt_proto_lock);
 
 static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
-static const char *bt_key_strings[BT_MAX_PROTO] = {
+static const char *const bt_key_strings[BT_MAX_PROTO] = {
 	"sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
 	"sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
 	"sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
@@ -61,7 +61,7 @@ static const char *bt_key_strings[BT_MAX_PROTO] = {
 };
 
 static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
-static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
+static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
 	"slock-AF_BLUETOOTH-BTPROTO_L2CAP",
 	"slock-AF_BLUETOOTH-BTPROTO_HCI",
 	"slock-AF_BLUETOOTH-BTPROTO_SCO",
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 52a6ce0..cafe9f5 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -533,6 +533,10 @@ static struct device *bnep_get_device(struct bnep_session *session)
 	return conn ? &conn->dev : NULL;
 }
 
+static struct device_type bnep_type = {
+	.name	= "bluetooth",
+};
+
 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
 {
 	struct net_device *dev;
@@ -586,6 +590,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
 #endif
 
 	SET_NETDEV_DEV(dev, bnep_get_device(s));
+	SET_NETDEV_DEVTYPE(dev, &bnep_type);
 
 	err = register_netdev(dev);
 	if (err) {
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index d7a0e97..26fb831 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -165,7 +165,8 @@ static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session
 }
 #endif
 
-static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t bnep_net_xmit(struct sk_buff *skb,
+				 struct net_device *dev)
 {
 	struct bnep_session *s = netdev_priv(dev);
 	struct sock *sk = s->sock->sk;
@@ -175,14 +176,14 @@ static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
 #ifdef CONFIG_BT_BNEP_MC_FILTER
 	if (bnep_net_mc_filter(skb, s)) {
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 #endif
 
 #ifdef CONFIG_BT_BNEP_PROTO_FILTER
 	if (bnep_net_proto_filter(skb, s)) {
 		kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 #endif
 
@@ -203,7 +204,7 @@ static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static const struct net_device_ops bnep_netdev_ops = {
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index fa47d5d..a975098 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -246,6 +246,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 	if (hdev->notify)
 		hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
 
+	atomic_set(&conn->devref, 0);
+
 	hci_conn_init_sysfs(conn);
 
 	tasklet_enable(&hdev->tx_task);
@@ -288,7 +290,7 @@ int hci_conn_del(struct hci_conn *conn)
 
 	skb_queue_purge(&conn->data_q);
 
-	hci_conn_del_sysfs(conn);
+	hci_conn_put_device(conn);
 
 	hci_dev_put(hdev);
 
@@ -583,6 +585,19 @@ void hci_conn_check_pending(struct hci_dev *hdev)
 	hci_dev_unlock(hdev);
 }
 
+void hci_conn_hold_device(struct hci_conn *conn)
+{
+	atomic_inc(&conn->devref);
+}
+EXPORT_SYMBOL(hci_conn_hold_device);
+
+void hci_conn_put_device(struct hci_conn *conn)
+{
+	if (atomic_dec_and_test(&conn->devref))
+		hci_conn_del_sysfs(conn);
+}
+EXPORT_SYMBOL(hci_conn_put_device);
+
 int hci_get_conn_list(void __user *arg)
 {
 	struct hci_conn_list_req req, *cl;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 406ad07..e1da8f6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -911,7 +911,7 @@ int hci_register_dev(struct hci_dev *hdev)
 		hdev->reassembly[i] = NULL;
 
 	init_waitqueue_head(&hdev->req_wait_q);
-	init_MUTEX(&hdev->req_lock);
+	mutex_init(&hdev->req_lock);
 
 	inquiry_cache_init(hdev);
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 184ba0a..e99fe38 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -887,6 +887,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 		} else
 			conn->state = BT_CONNECTED;
 
+		hci_conn_hold_device(conn);
 		hci_conn_add_sysfs(conn);
 
 		if (test_bit(HCI_AUTH, &hdev->flags))
@@ -1693,6 +1694,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu
 		conn->handle = __le16_to_cpu(ev->handle);
 		conn->state  = BT_CONNECTED;
 
+		hci_conn_hold_device(conn);
 		hci_conn_add_sysfs(conn);
 		break;
 
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 95f7a7a..7f939ce 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -68,7 +68,7 @@ static struct attribute_group bt_link_group = {
 	.attrs = bt_link_attrs,
 };
 
-static struct attribute_group *bt_link_groups[] = {
+static const struct attribute_group *bt_link_groups[] = {
 	&bt_link_group,
 	NULL
 };
@@ -392,7 +392,7 @@ static struct attribute_group bt_host_group = {
 	.attrs = bt_host_attrs,
 };
 
-static struct attribute_group *bt_host_groups[] = {
+static const struct attribute_group *bt_host_groups[] = {
 	&bt_host_group,
 	NULL
 };
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index b186768..09bedeb 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -40,6 +40,7 @@
 
 #include <linux/input.h>
 #include <linux/hid.h>
+#include <linux/hidraw.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
@@ -92,10 +93,14 @@ static void __hidp_link_session(struct hidp_session *session)
 {
 	__module_get(THIS_MODULE);
 	list_add(&session->list, &hidp_session_list);
+
+	hci_conn_hold_device(session->conn);
 }
 
 static void __hidp_unlink_session(struct hidp_session *session)
 {
+	hci_conn_put_device(session->conn);
+
 	list_del(&session->list);
 	module_put(THIS_MODULE);
 }
@@ -374,6 +379,7 @@ static void hidp_process_hid_control(struct hidp_session *session,
 
 		/* Kill session thread */
 		atomic_inc(&session->terminate);
+		hidp_schedule(session);
 	}
 }
 
@@ -573,7 +579,11 @@ static int hidp_session(void *arg)
 	if (session->hid) {
 		if (session->hid->claimed & HID_CLAIMED_INPUT)
 			hidinput_disconnect(session->hid);
+		if (session->hid->claimed & HID_CLAIMED_HIDRAW)
+			hidraw_disconnect(session->hid);
+
 		hid_destroy_device(session->hid);
+		session->hid = NULL;
 	}
 
 	/* Wakeup user-space polling for socket errors */
@@ -601,25 +611,27 @@ static struct device *hidp_get_device(struct hidp_session *session)
 {
 	bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
 	bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
+	struct device *device = NULL;
 	struct hci_dev *hdev;
-	struct hci_conn *conn;
 
 	hdev = hci_get_route(dst, src);
 	if (!hdev)
 		return NULL;
 
-	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+	session->conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+	if (session->conn)
+		device = &session->conn->dev;
 
 	hci_dev_put(hdev);
 
-	return conn ? &conn->dev : NULL;
+	return device;
 }
 
 static int hidp_setup_input(struct hidp_session *session,
 				struct hidp_connadd_req *req)
 {
 	struct input_dev *input;
-	int i;
+	int err, i;
 
 	input = input_allocate_device();
 	if (!input)
@@ -666,7 +678,13 @@ static int hidp_setup_input(struct hidp_session *session,
 
 	input->event = hidp_input_event;
 
-	return input_register_device(input);
+	err = input_register_device(input);
+	if (err < 0) {
+		hci_conn_put_device(session->conn);
+		return err;
+	}
+
+	return 0;
 }
 
 static int hidp_open(struct hid_device *hid)
@@ -748,13 +766,11 @@ static int hidp_setup_hid(struct hidp_session *session,
 {
 	struct hid_device *hid;
 	bdaddr_t src, dst;
-	int ret;
+	int err;
 
 	hid = hid_allocate_device();
-	if (IS_ERR(hid)) {
-		ret = PTR_ERR(session->hid);
-		goto err;
-	}
+	if (IS_ERR(hid))
+		return PTR_ERR(session->hid);
 
 	session->hid = hid;
 	session->req = req;
@@ -776,16 +792,17 @@ static int hidp_setup_hid(struct hidp_session *session,
 	hid->dev.parent = hidp_get_device(session);
 	hid->ll_driver = &hidp_hid_driver;
 
-	ret = hid_add_device(hid);
-	if (ret)
-		goto err_hid;
+	err = hid_add_device(hid);
+	if (err < 0)
+		goto failed;
 
 	return 0;
-err_hid:
+
+failed:
 	hid_destroy_device(hid);
 	session->hid = NULL;
-err:
-	return ret;
+
+	return err;
 }
 
 int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
@@ -835,13 +852,13 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
 	if (req->rd_size > 0) {
 		err = hidp_setup_hid(session, req);
 		if (err && err != -ENODEV)
-			goto err_skb;
+			goto purge;
 	}
 
 	if (!session->hid) {
 		err = hidp_setup_input(session, req);
 		if (err < 0)
-			goto err_skb;
+			goto purge;
 	}
 
 	__hidp_link_session(session);
@@ -869,13 +886,20 @@ unlink:
 
 	__hidp_unlink_session(session);
 
-	if (session->input)
+	if (session->input) {
 		input_unregister_device(session->input);
-	if (session->hid)
+		session->input = NULL;
+	}
+
+	if (session->hid) {
 		hid_destroy_device(session->hid);
-err_skb:
+		session->hid = NULL;
+	}
+
+purge:
 	skb_queue_purge(&session->ctrl_transmit);
 	skb_queue_purge(&session->intr_transmit);
+
 failed:
 	up_write(&hidp_session_sem);
 
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index e503c89..faf3d74 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -126,6 +126,8 @@ int hidp_get_conninfo(struct hidp_conninfo *ci);
 struct hidp_session {
 	struct list_head list;
 
+	struct hci_conn *conn;
+
 	struct socket *ctrl_sock;
 	struct socket *intr_sock;
 
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index bd0a4c1..b030125 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -41,6 +41,7 @@
 #include <linux/list.h>
 #include <linux/device.h>
 #include <linux/uaccess.h>
+#include <linux/crc16.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -50,7 +51,9 @@
 #include <net/bluetooth/hci_core.h>
 #include <net/bluetooth/l2cap.h>
 
-#define VERSION "2.13"
+#define VERSION "2.14"
+
+static int enable_ertm = 0;
 
 static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
 static u8 l2cap_fixed_chan[8] = { 0x02, };
@@ -331,6 +334,48 @@ static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16
 	return hci_send_acl(conn->hcon, skb, 0);
 }
 
+static inline int l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
+{
+	struct sk_buff *skb;
+	struct l2cap_hdr *lh;
+	struct l2cap_conn *conn = pi->conn;
+	int count, hlen = L2CAP_HDR_SIZE + 2;
+
+	if (pi->fcs == L2CAP_FCS_CRC16)
+		hlen += 2;
+
+	BT_DBG("pi %p, control 0x%2.2x", pi, control);
+
+	count = min_t(unsigned int, conn->mtu, hlen);
+	control |= L2CAP_CTRL_FRAME_TYPE;
+
+	skb = bt_skb_alloc(count, GFP_ATOMIC);
+	if (!skb)
+		return -ENOMEM;
+
+	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE);
+	lh->cid = cpu_to_le16(pi->dcid);
+	put_unaligned_le16(control, skb_put(skb, 2));
+
+	if (pi->fcs == L2CAP_FCS_CRC16) {
+		u16 fcs = crc16(0, (u8 *)lh, count - 2);
+		put_unaligned_le16(fcs, skb_put(skb, 2));
+	}
+
+	return hci_send_acl(pi->conn->hcon, skb, 0);
+}
+
+static inline int l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
+{
+	if (pi->conn_state & L2CAP_CONN_LOCAL_BUSY)
+		control |= L2CAP_SUPER_RCV_NOT_READY;
+	else
+		control |= L2CAP_SUPER_RCV_READY;
+
+	return l2cap_send_sframe(pi, control);
+}
+
 static void l2cap_do_start(struct sock *sk)
 {
 	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
@@ -364,6 +409,16 @@ static void l2cap_do_start(struct sock *sk)
 	}
 }
 
+static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk)
+{
+	struct l2cap_disconn_req req;
+
+	req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
+	req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
+	l2cap_send_cmd(conn, l2cap_get_ident(conn),
+			L2CAP_DISCONN_REQ, sizeof(req), &req);
+}
+
 /* ---- L2CAP connections ---- */
 static void l2cap_conn_start(struct l2cap_conn *conn)
 {
@@ -648,15 +703,10 @@ static void __l2cap_sock_close(struct sock *sk, int reason)
 	case BT_CONFIG:
 		if (sk->sk_type == SOCK_SEQPACKET) {
 			struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-			struct l2cap_disconn_req req;
 
 			sk->sk_state = BT_DISCONN;
 			l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
-
-			req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
-			req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
-			l2cap_send_cmd(conn, l2cap_get_ident(conn),
-					L2CAP_DISCONN_REQ, sizeof(req), &req);
+			l2cap_send_disconn_req(conn, sk);
 		} else
 			l2cap_chan_del(sk, reason);
 		break;
@@ -715,12 +765,16 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
 
 		pi->imtu = l2cap_pi(parent)->imtu;
 		pi->omtu = l2cap_pi(parent)->omtu;
+		pi->mode = l2cap_pi(parent)->mode;
+		pi->fcs  = l2cap_pi(parent)->fcs;
 		pi->sec_level = l2cap_pi(parent)->sec_level;
 		pi->role_switch = l2cap_pi(parent)->role_switch;
 		pi->force_reliable = l2cap_pi(parent)->force_reliable;
 	} else {
 		pi->imtu = L2CAP_DEFAULT_MTU;
 		pi->omtu = 0;
+		pi->mode = L2CAP_MODE_BASIC;
+		pi->fcs  = L2CAP_FCS_CRC16;
 		pi->sec_level = BT_SECURITY_LOW;
 		pi->role_switch = 0;
 		pi->force_reliable = 0;
@@ -956,6 +1010,19 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 		goto done;
 	}
 
+	switch (l2cap_pi(sk)->mode) {
+	case L2CAP_MODE_BASIC:
+		break;
+	case L2CAP_MODE_ERTM:
+	case L2CAP_MODE_STREAMING:
+		if (enable_ertm)
+			break;
+		/* fall through */
+	default:
+		err = -ENOTSUPP;
+		goto done;
+	}
+
 	switch (sk->sk_state) {
 	case BT_CONNECT:
 	case BT_CONNECT2:
@@ -1007,6 +1074,19 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
 		goto done;
 	}
 
+	switch (l2cap_pi(sk)->mode) {
+	case L2CAP_MODE_BASIC:
+		break;
+	case L2CAP_MODE_ERTM:
+	case L2CAP_MODE_STREAMING:
+		if (enable_ertm)
+			break;
+		/* fall through */
+	default:
+		err = -ENOTSUPP;
+		goto done;
+	}
+
 	if (!l2cap_pi(sk)->psm) {
 		bdaddr_t *src = &bt_sk(sk)->src;
 		u16 psm;
@@ -1117,39 +1197,219 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
 	return 0;
 }
 
-static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
+static void l2cap_monitor_timeout(unsigned long arg)
 {
-	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-	struct sk_buff *skb, **frag;
-	int err, hlen, count, sent = 0;
-	struct l2cap_hdr *lh;
+	struct sock *sk = (void *) arg;
+	u16 control;
 
-	BT_DBG("sk %p len %d", sk, len);
+	bh_lock_sock(sk);
+	if (l2cap_pi(sk)->retry_count >= l2cap_pi(sk)->remote_max_tx) {
+		l2cap_send_disconn_req(l2cap_pi(sk)->conn, sk);
+		return;
+	}
 
-	/* First fragment (with L2CAP header) */
-	if (sk->sk_type == SOCK_DGRAM)
-		hlen = L2CAP_HDR_SIZE + 2;
-	else
-		hlen = L2CAP_HDR_SIZE;
+	l2cap_pi(sk)->retry_count++;
+	__mod_monitor_timer();
 
-	count = min_t(unsigned int, (conn->mtu - hlen), len);
+	control = L2CAP_CTRL_POLL;
+	l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
+	bh_unlock_sock(sk);
+}
 
-	skb = bt_skb_send_alloc(sk, hlen + count,
-			msg->msg_flags & MSG_DONTWAIT, &err);
-	if (!skb)
-		return err;
+static void l2cap_retrans_timeout(unsigned long arg)
+{
+	struct sock *sk = (void *) arg;
+	u16 control;
 
-	/* Create L2CAP header */
-	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-	lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
-	lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
+	bh_lock_sock(sk);
+	l2cap_pi(sk)->retry_count = 1;
+	__mod_monitor_timer();
+
+	l2cap_pi(sk)->conn_state |= L2CAP_CONN_WAIT_F;
+
+	control = L2CAP_CTRL_POLL;
+	l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
+	bh_unlock_sock(sk);
+}
+
+static void l2cap_drop_acked_frames(struct sock *sk)
+{
+	struct sk_buff *skb;
+
+	while ((skb = skb_peek(TX_QUEUE(sk)))) {
+		if (bt_cb(skb)->tx_seq == l2cap_pi(sk)->expected_ack_seq)
+			break;
+
+		skb = skb_dequeue(TX_QUEUE(sk));
+		kfree_skb(skb);
+
+		l2cap_pi(sk)->unacked_frames--;
+	}
+
+	if (!l2cap_pi(sk)->unacked_frames)
+		del_timer(&l2cap_pi(sk)->retrans_timer);
 
-	if (sk->sk_type == SOCK_DGRAM)
-		put_unaligned(l2cap_pi(sk)->psm, (__le16 *) skb_put(skb, 2));
+	return;
+}
+
+static inline int l2cap_do_send(struct sock *sk, struct sk_buff *skb)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	int err;
+
+	BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len);
+
+	err = hci_send_acl(pi->conn->hcon, skb, 0);
+	if (err < 0)
+		kfree_skb(skb);
+
+	return err;
+}
+
+static int l2cap_streaming_send(struct sock *sk)
+{
+	struct sk_buff *skb, *tx_skb;
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	u16 control, fcs;
+	int err;
+
+	while ((skb = sk->sk_send_head)) {
+		tx_skb = skb_clone(skb, GFP_ATOMIC);
+
+		control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+		control |= pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT;
+		put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
+
+		if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+			fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
+			put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
+		}
+
+		err = l2cap_do_send(sk, tx_skb);
+		if (err < 0) {
+			l2cap_send_disconn_req(pi->conn, sk);
+			return err;
+		}
+
+		pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+
+		if (skb_queue_is_last(TX_QUEUE(sk), skb))
+			sk->sk_send_head = NULL;
+		else
+			sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
+
+		skb = skb_dequeue(TX_QUEUE(sk));
+		kfree_skb(skb);
+	}
+	return 0;
+}
+
+static int l2cap_retransmit_frame(struct sock *sk, u8 tx_seq)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	struct sk_buff *skb, *tx_skb;
+	u16 control, fcs;
+	int err;
+
+	skb = skb_peek(TX_QUEUE(sk));
+	do {
+		if (bt_cb(skb)->tx_seq != tx_seq) {
+			if (skb_queue_is_last(TX_QUEUE(sk), skb))
+				break;
+			skb = skb_queue_next(TX_QUEUE(sk), skb);
+			continue;
+		}
+
+		if (pi->remote_max_tx &&
+				bt_cb(skb)->retries == pi->remote_max_tx) {
+			l2cap_send_disconn_req(pi->conn, sk);
+			break;
+		}
+
+		tx_skb = skb_clone(skb, GFP_ATOMIC);
+		bt_cb(skb)->retries++;
+		control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+		control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+				| (tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
+		put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
+
+		if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+			fcs = crc16(0, (u8 *)tx_skb->data, tx_skb->len - 2);
+			put_unaligned_le16(fcs, tx_skb->data + tx_skb->len - 2);
+		}
+
+		err = l2cap_do_send(sk, tx_skb);
+		if (err < 0) {
+			l2cap_send_disconn_req(pi->conn, sk);
+			return err;
+		}
+		break;
+	} while(1);
+	return 0;
+}
+
+static int l2cap_ertm_send(struct sock *sk)
+{
+	struct sk_buff *skb, *tx_skb;
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	u16 control, fcs;
+	int err;
+
+	if (pi->conn_state & L2CAP_CONN_WAIT_F)
+		return 0;
+
+	while ((skb = sk->sk_send_head) && (!l2cap_tx_window_full(sk))
+			&& !(pi->conn_state & L2CAP_CONN_REMOTE_BUSY)) {
+		tx_skb = skb_clone(skb, GFP_ATOMIC);
+
+		if (pi->remote_max_tx &&
+				bt_cb(skb)->retries == pi->remote_max_tx) {
+			l2cap_send_disconn_req(pi->conn, sk);
+			break;
+		}
+
+		bt_cb(skb)->retries++;
+
+		control = get_unaligned_le16(tx_skb->data + L2CAP_HDR_SIZE);
+		control |= (pi->req_seq << L2CAP_CTRL_REQSEQ_SHIFT)
+				| (pi->next_tx_seq << L2CAP_CTRL_TXSEQ_SHIFT);
+		put_unaligned_le16(control, tx_skb->data + L2CAP_HDR_SIZE);
+
+
+		if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16) {
+			fcs = crc16(0, (u8 *)skb->data, tx_skb->len - 2);
+			put_unaligned_le16(fcs, skb->data + tx_skb->len - 2);
+		}
+
+		err = l2cap_do_send(sk, tx_skb);
+		if (err < 0) {
+			l2cap_send_disconn_req(pi->conn, sk);
+			return err;
+		}
+		__mod_retrans_timer();
+
+		bt_cb(skb)->tx_seq = pi->next_tx_seq;
+		pi->next_tx_seq = (pi->next_tx_seq + 1) % 64;
+
+		pi->unacked_frames++;
+
+		if (skb_queue_is_last(TX_QUEUE(sk), skb))
+			sk->sk_send_head = NULL;
+		else
+			sk->sk_send_head = skb_queue_next(TX_QUEUE(sk), skb);
+	}
+
+	return 0;
+}
+
+static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, int len, int count, struct sk_buff *skb)
+{
+	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+	struct sk_buff **frag;
+	int err, sent = 0;
 
 	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-		err = -EFAULT;
-		goto fail;
+		return -EFAULT;
 	}
 
 	sent += count;
@@ -1162,33 +1422,173 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
 
 		*frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
 		if (!*frag)
-			goto fail;
-
-		if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-			err = -EFAULT;
-			goto fail;
-		}
+			return -EFAULT;
+		if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count))
+			return -EFAULT;
 
 		sent += count;
 		len  -= count;
 
 		frag = &(*frag)->next;
 	}
-	err = hci_send_acl(conn->hcon, skb, 0);
-	if (err < 0)
-		goto fail;
 
 	return sent;
+}
 
-fail:
-	kfree_skb(skb);
-	return err;
+static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len)
+{
+	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+	struct sk_buff *skb;
+	int err, count, hlen = L2CAP_HDR_SIZE + 2;
+	struct l2cap_hdr *lh;
+
+	BT_DBG("sk %p len %d", sk, (int)len);
+
+	count = min_t(unsigned int, (conn->mtu - hlen), len);
+	skb = bt_skb_send_alloc(sk, count + hlen,
+			msg->msg_flags & MSG_DONTWAIT, &err);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	/* Create L2CAP header */
+	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
+	lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
+	put_unaligned_le16(l2cap_pi(sk)->psm, skb_put(skb, 2));
+
+	err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
+	if (unlikely(err < 0)) {
+		kfree_skb(skb);
+		return ERR_PTR(err);
+	}
+	return skb;
+}
+
+static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len)
+{
+	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+	struct sk_buff *skb;
+	int err, count, hlen = L2CAP_HDR_SIZE;
+	struct l2cap_hdr *lh;
+
+	BT_DBG("sk %p len %d", sk, (int)len);
+
+	count = min_t(unsigned int, (conn->mtu - hlen), len);
+	skb = bt_skb_send_alloc(sk, count + hlen,
+			msg->msg_flags & MSG_DONTWAIT, &err);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	/* Create L2CAP header */
+	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
+	lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
+
+	err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
+	if (unlikely(err < 0)) {
+		kfree_skb(skb);
+		return ERR_PTR(err);
+	}
+	return skb;
+}
+
+static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen)
+{
+	struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+	struct sk_buff *skb;
+	int err, count, hlen = L2CAP_HDR_SIZE + 2;
+	struct l2cap_hdr *lh;
+
+	BT_DBG("sk %p len %d", sk, (int)len);
+
+	if (sdulen)
+		hlen += 2;
+
+	if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
+		hlen += 2;
+
+	count = min_t(unsigned int, (conn->mtu - hlen), len);
+	skb = bt_skb_send_alloc(sk, count + hlen,
+			msg->msg_flags & MSG_DONTWAIT, &err);
+	if (!skb)
+		return ERR_PTR(-ENOMEM);
+
+	/* Create L2CAP header */
+	lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
+	lh->cid = cpu_to_le16(l2cap_pi(sk)->dcid);
+	lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
+	put_unaligned_le16(control, skb_put(skb, 2));
+	if (sdulen)
+		put_unaligned_le16(sdulen, skb_put(skb, 2));
+
+	err = l2cap_skbuff_fromiovec(sk, msg, len, count, skb);
+	if (unlikely(err < 0)) {
+		kfree_skb(skb);
+		return ERR_PTR(err);
+	}
+
+	if (l2cap_pi(sk)->fcs == L2CAP_FCS_CRC16)
+		put_unaligned_le16(0, skb_put(skb, 2));
+
+	bt_cb(skb)->retries = 0;
+	return skb;
+}
+
+static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	struct sk_buff *skb;
+	struct sk_buff_head sar_queue;
+	u16 control;
+	size_t size = 0;
+
+	__skb_queue_head_init(&sar_queue);
+	control = L2CAP_SDU_START;
+	skb = l2cap_create_iframe_pdu(sk, msg, pi->max_pdu_size, control, len);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	__skb_queue_tail(&sar_queue, skb);
+	len -= pi->max_pdu_size;
+	size +=pi->max_pdu_size;
+	control = 0;
+
+	while (len > 0) {
+		size_t buflen;
+
+		if (len > pi->max_pdu_size) {
+			control |= L2CAP_SDU_CONTINUE;
+			buflen = pi->max_pdu_size;
+		} else {
+			control |= L2CAP_SDU_END;
+			buflen = len;
+		}
+
+		skb = l2cap_create_iframe_pdu(sk, msg, buflen, control, 0);
+		if (IS_ERR(skb)) {
+			skb_queue_purge(&sar_queue);
+			return PTR_ERR(skb);
+		}
+
+		__skb_queue_tail(&sar_queue, skb);
+		len -= buflen;
+		size += buflen;
+		control = 0;
+	}
+	skb_queue_splice_tail(&sar_queue, TX_QUEUE(sk));
+	if (sk->sk_send_head == NULL)
+		sk->sk_send_head = sar_queue.next;
+
+	return size;
 }
 
 static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
 {
 	struct sock *sk = sock->sk;
-	int err = 0;
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	struct sk_buff *skb;
+	u16 control;
+	int err;
 
 	BT_DBG("sock %p, sk %p", sock, sk);
 
@@ -1200,16 +1600,73 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
 		return -EOPNOTSUPP;
 
 	/* Check outgoing MTU */
-	if (sk->sk_type != SOCK_RAW && len > l2cap_pi(sk)->omtu)
+	if (sk->sk_type == SOCK_SEQPACKET && pi->mode == L2CAP_MODE_BASIC
+			&& len > pi->omtu)
 		return -EINVAL;
 
 	lock_sock(sk);
 
-	if (sk->sk_state == BT_CONNECTED)
-		err = l2cap_do_send(sk, msg, len);
-	else
+	if (sk->sk_state != BT_CONNECTED) {
 		err = -ENOTCONN;
+		goto done;
+	}
+
+	/* Connectionless channel */
+	if (sk->sk_type == SOCK_DGRAM) {
+		skb = l2cap_create_connless_pdu(sk, msg, len);
+		err = l2cap_do_send(sk, skb);
+		goto done;
+	}
+
+	switch (pi->mode) {
+	case L2CAP_MODE_BASIC:
+		/* Create a basic PDU */
+		skb = l2cap_create_basic_pdu(sk, msg, len);
+		if (IS_ERR(skb)) {
+			err = PTR_ERR(skb);
+			goto done;
+		}
+
+		err = l2cap_do_send(sk, skb);
+		if (!err)
+			err = len;
+		break;
+
+	case L2CAP_MODE_ERTM:
+	case L2CAP_MODE_STREAMING:
+		/* Entire SDU fits into one PDU */
+		if (len <= pi->max_pdu_size) {
+			control = L2CAP_SDU_UNSEGMENTED;
+			skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0);
+			if (IS_ERR(skb)) {
+				err = PTR_ERR(skb);
+				goto done;
+			}
+			__skb_queue_tail(TX_QUEUE(sk), skb);
+			if (sk->sk_send_head == NULL)
+				sk->sk_send_head = skb;
+		} else {
+		/* Segment SDU into multiples PDUs */
+			err = l2cap_sar_segment_sdu(sk, msg, len);
+			if (err < 0)
+				goto done;
+		}
+
+		if (pi->mode == L2CAP_MODE_STREAMING)
+			err = l2cap_streaming_send(sk);
+		else
+			err = l2cap_ertm_send(sk);
+
+		if (!err)
+			err = len;
+		break;
+
+	default:
+		BT_DBG("bad state %1.1x", pi->mode);
+		err = -EINVAL;
+	}
 
+done:
 	release_sock(sk);
 	return err;
 }
@@ -1257,7 +1714,8 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
 		opts.imtu     = l2cap_pi(sk)->imtu;
 		opts.omtu     = l2cap_pi(sk)->omtu;
 		opts.flush_to = l2cap_pi(sk)->flush_to;
-		opts.mode     = L2CAP_MODE_BASIC;
+		opts.mode     = l2cap_pi(sk)->mode;
+		opts.fcs      = l2cap_pi(sk)->fcs;
 
 		len = min_t(unsigned int, sizeof(opts), optlen);
 		if (copy_from_user((char *) &opts, optval, len)) {
@@ -1265,8 +1723,10 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
 			break;
 		}
 
-		l2cap_pi(sk)->imtu  = opts.imtu;
-		l2cap_pi(sk)->omtu  = opts.omtu;
+		l2cap_pi(sk)->imtu = opts.imtu;
+		l2cap_pi(sk)->omtu = opts.omtu;
+		l2cap_pi(sk)->mode = opts.mode;
+		l2cap_pi(sk)->fcs  = opts.fcs;
 		break;
 
 	case L2CAP_LM:
@@ -1379,7 +1839,8 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
 		opts.imtu     = l2cap_pi(sk)->imtu;
 		opts.omtu     = l2cap_pi(sk)->omtu;
 		opts.flush_to = l2cap_pi(sk)->flush_to;
-		opts.mode     = L2CAP_MODE_BASIC;
+		opts.mode     = l2cap_pi(sk)->mode;
+		opts.fcs      = l2cap_pi(sk)->fcs;
 
 		len = min_t(unsigned int, len, sizeof(opts));
 		if (copy_to_user(optval, (char *) &opts, len))
@@ -1708,16 +2169,108 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
 	*ptr += L2CAP_CONF_OPT_SIZE + len;
 }
 
+static int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
+{
+	u32 local_feat_mask = l2cap_feat_mask;
+	if (enable_ertm)
+		local_feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING;
+
+	switch (mode) {
+	case L2CAP_MODE_ERTM:
+		return L2CAP_FEAT_ERTM & feat_mask & local_feat_mask;
+	case L2CAP_MODE_STREAMING:
+		return L2CAP_FEAT_STREAMING & feat_mask & local_feat_mask;
+	default:
+		return 0x00;
+	}
+}
+
+static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
+{
+	switch (mode) {
+	case L2CAP_MODE_STREAMING:
+	case L2CAP_MODE_ERTM:
+		if (l2cap_mode_supported(mode, remote_feat_mask))
+			return mode;
+		/* fall through */
+	default:
+		return L2CAP_MODE_BASIC;
+	}
+}
+
 static int l2cap_build_conf_req(struct sock *sk, void *data)
 {
 	struct l2cap_pinfo *pi = l2cap_pi(sk);
 	struct l2cap_conf_req *req = data;
+	struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
 	void *ptr = req->data;
 
 	BT_DBG("sk %p", sk);
 
-	if (pi->imtu != L2CAP_DEFAULT_MTU)
-		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+	if (pi->num_conf_req || pi->num_conf_rsp)
+		goto done;
+
+	switch (pi->mode) {
+	case L2CAP_MODE_STREAMING:
+	case L2CAP_MODE_ERTM:
+		pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
+		if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
+			l2cap_send_disconn_req(pi->conn, sk);
+		break;
+	default:
+		pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
+		break;
+	}
+
+done:
+	switch (pi->mode) {
+	case L2CAP_MODE_BASIC:
+		if (pi->imtu != L2CAP_DEFAULT_MTU)
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+		break;
+
+	case L2CAP_MODE_ERTM:
+		rfc.mode            = L2CAP_MODE_ERTM;
+		rfc.txwin_size      = L2CAP_DEFAULT_TX_WINDOW;
+		rfc.max_transmit    = L2CAP_DEFAULT_MAX_TX;
+		rfc.retrans_timeout = 0;
+		rfc.monitor_timeout = 0;
+		rfc.max_pdu_size    = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+					sizeof(rfc), (unsigned long) &rfc);
+
+		if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
+			break;
+
+		if (pi->fcs == L2CAP_FCS_NONE ||
+				pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
+			pi->fcs = L2CAP_FCS_NONE;
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
+		}
+		break;
+
+	case L2CAP_MODE_STREAMING:
+		rfc.mode            = L2CAP_MODE_STREAMING;
+		rfc.txwin_size      = 0;
+		rfc.max_transmit    = 0;
+		rfc.retrans_timeout = 0;
+		rfc.monitor_timeout = 0;
+		rfc.max_pdu_size    = cpu_to_le16(L2CAP_DEFAULT_MAX_PDU_SIZE);
+
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+					sizeof(rfc), (unsigned long) &rfc);
+
+		if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
+			break;
+
+		if (pi->fcs == L2CAP_FCS_NONE ||
+				pi->conf_state & L2CAP_CONF_NO_FCS_RECV) {
+			pi->fcs = L2CAP_FCS_NONE;
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, pi->fcs);
+		}
+		break;
+	}
 
 	/* FIXME: Need actual value of the flush timeout */
 	//if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
@@ -1767,6 +2320,12 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
 				memcpy(&rfc, (void *) val, olen);
 			break;
 
+		case L2CAP_CONF_FCS:
+			if (val == L2CAP_FCS_NONE)
+				pi->conf_state |= L2CAP_CONF_NO_FCS_RECV;
+
+			break;
+
 		default:
 			if (hint)
 				break;
@@ -1777,30 +2336,83 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
 		}
 	}
 
+	if (pi->num_conf_rsp || pi->num_conf_req)
+		goto done;
+
+	switch (pi->mode) {
+	case L2CAP_MODE_STREAMING:
+	case L2CAP_MODE_ERTM:
+		pi->conf_state |= L2CAP_CONF_STATE2_DEVICE;
+		if (!l2cap_mode_supported(pi->mode, pi->conn->feat_mask))
+			return -ECONNREFUSED;
+		break;
+	default:
+		pi->mode = l2cap_select_mode(rfc.mode, pi->conn->feat_mask);
+		break;
+	}
+
+done:
+	if (pi->mode != rfc.mode) {
+		result = L2CAP_CONF_UNACCEPT;
+		rfc.mode = pi->mode;
+
+		if (pi->num_conf_rsp == 1)
+			return -ECONNREFUSED;
+
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+					sizeof(rfc), (unsigned long) &rfc);
+	}
+
+
 	if (result == L2CAP_CONF_SUCCESS) {
 		/* Configure output options and let the other side know
 		 * which ones we don't like. */
 
-		if (rfc.mode == L2CAP_MODE_BASIC) {
-			if (mtu < pi->omtu)
-				result = L2CAP_CONF_UNACCEPT;
-			else {
-				pi->omtu = mtu;
-				pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-			}
+		if (mtu < L2CAP_DEFAULT_MIN_MTU)
+			result = L2CAP_CONF_UNACCEPT;
+		else {
+			pi->omtu = mtu;
+			pi->conf_state |= L2CAP_CONF_MTU_DONE;
+		}
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
 
-			l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
-		} else {
+		switch (rfc.mode) {
+		case L2CAP_MODE_BASIC:
+			pi->fcs = L2CAP_FCS_NONE;
+			pi->conf_state |= L2CAP_CONF_MODE_DONE;
+			break;
+
+		case L2CAP_MODE_ERTM:
+			pi->remote_tx_win = rfc.txwin_size;
+			pi->remote_max_tx = rfc.max_transmit;
+			pi->max_pdu_size = rfc.max_pdu_size;
+
+			rfc.retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
+			rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+
+			pi->conf_state |= L2CAP_CONF_MODE_DONE;
+			break;
+
+		case L2CAP_MODE_STREAMING:
+			pi->remote_tx_win = rfc.txwin_size;
+			pi->max_pdu_size = rfc.max_pdu_size;
+
+			pi->conf_state |= L2CAP_CONF_MODE_DONE;
+			break;
+
+		default:
 			result = L2CAP_CONF_UNACCEPT;
 
 			memset(&rfc, 0, sizeof(rfc));
-			rfc.mode = L2CAP_MODE_BASIC;
-
-			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
-						sizeof(rfc), (unsigned long) &rfc);
+			rfc.mode = pi->mode;
 		}
-	}
 
+		l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+					sizeof(rfc), (unsigned long) &rfc);
+
+		if (result == L2CAP_CONF_SUCCESS)
+			pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+	}
 	rsp->scid   = cpu_to_le16(pi->dcid);
 	rsp->result = cpu_to_le16(result);
 	rsp->flags  = cpu_to_le16(0x0000);
@@ -1808,6 +2420,73 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
 	return ptr - data;
 }
 
+static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, u16 *result)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	struct l2cap_conf_req *req = data;
+	void *ptr = req->data;
+	int type, olen;
+	unsigned long val;
+	struct l2cap_conf_rfc rfc;
+
+	BT_DBG("sk %p, rsp %p, len %d, req %p", sk, rsp, len, data);
+
+	while (len >= L2CAP_CONF_OPT_SIZE) {
+		len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
+
+		switch (type) {
+		case L2CAP_CONF_MTU:
+			if (val < L2CAP_DEFAULT_MIN_MTU) {
+				*result = L2CAP_CONF_UNACCEPT;
+				pi->omtu = L2CAP_DEFAULT_MIN_MTU;
+			} else
+				pi->omtu = val;
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+			break;
+
+		case L2CAP_CONF_FLUSH_TO:
+			pi->flush_to = val;
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
+							2, pi->flush_to);
+			break;
+
+		case L2CAP_CONF_RFC:
+			if (olen == sizeof(rfc))
+				memcpy(&rfc, (void *)val, olen);
+
+			if ((pi->conf_state & L2CAP_CONF_STATE2_DEVICE) &&
+							rfc.mode != pi->mode)
+				return -ECONNREFUSED;
+
+			pi->mode = rfc.mode;
+			pi->fcs = 0;
+
+			l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+					sizeof(rfc), (unsigned long) &rfc);
+			break;
+		}
+	}
+
+	if (*result == L2CAP_CONF_SUCCESS) {
+		switch (rfc.mode) {
+		case L2CAP_MODE_ERTM:
+			pi->remote_tx_win   = rfc.txwin_size;
+			pi->retrans_timeout = rfc.retrans_timeout;
+			pi->monitor_timeout = rfc.monitor_timeout;
+			pi->max_pdu_size    = le16_to_cpu(rfc.max_pdu_size);
+			break;
+		case L2CAP_MODE_STREAMING:
+			pi->max_pdu_size    = le16_to_cpu(rfc.max_pdu_size);
+			break;
+		}
+	}
+
+	req->dcid   = cpu_to_le16(pi->dcid);
+	req->flags  = cpu_to_le16(0x0000);
+
+	return ptr - data;
+}
+
 static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 flags)
 {
 	struct l2cap_conf_rsp *rsp = data;
@@ -1994,6 +2673,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
 
 		l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
 					l2cap_build_conf_req(sk, req), req);
+		l2cap_pi(sk)->num_conf_req++;
 		break;
 
 	case L2CAP_CR_PEND:
@@ -2052,10 +2732,13 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
 	/* Complete config. */
 	len = l2cap_parse_conf_req(sk, rsp);
-	if (len < 0)
+	if (len < 0) {
+		l2cap_send_disconn_req(conn, sk);
 		goto unlock;
+	}
 
 	l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
+	l2cap_pi(sk)->num_conf_rsp++;
 
 	/* Reset config buffer. */
 	l2cap_pi(sk)->conf_len = 0;
@@ -2064,7 +2747,22 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 		goto unlock;
 
 	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
+		if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
+				|| l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
+			l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
+
 		sk->sk_state = BT_CONNECTED;
+		l2cap_pi(sk)->next_tx_seq = 0;
+		l2cap_pi(sk)->expected_ack_seq = 0;
+		l2cap_pi(sk)->unacked_frames = 0;
+
+		setup_timer(&l2cap_pi(sk)->retrans_timer,
+				l2cap_retrans_timeout, (unsigned long) sk);
+		setup_timer(&l2cap_pi(sk)->monitor_timer,
+				l2cap_monitor_timeout, (unsigned long) sk);
+
+		__skb_queue_head_init(TX_QUEUE(sk));
+		__skb_queue_head_init(SREJ_QUEUE(sk));
 		l2cap_chan_ready(sk);
 		goto unlock;
 	}
@@ -2073,6 +2771,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 		u8 buf[64];
 		l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
 					l2cap_build_conf_req(sk, buf), buf);
+		l2cap_pi(sk)->num_conf_req++;
 	}
 
 unlock:
@@ -2102,29 +2801,32 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 		break;
 
 	case L2CAP_CONF_UNACCEPT:
-		if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
-			char req[128];
-			/* It does not make sense to adjust L2CAP parameters
-			 * that are currently defined in the spec. We simply
-			 * resend config request that we sent earlier. It is
-			 * stupid, but it helps qualification testing which
-			 * expects at least some response from us. */
-			l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
-						l2cap_build_conf_req(sk, req), req);
-			goto done;
+		if (l2cap_pi(sk)->num_conf_rsp <= L2CAP_CONF_MAX_CONF_RSP) {
+			int len = cmd->len - sizeof(*rsp);
+			char req[64];
+
+			/* throw out any old stored conf requests */
+			result = L2CAP_CONF_SUCCESS;
+			len = l2cap_parse_conf_rsp(sk, rsp->data,
+							len, req, &result);
+			if (len < 0) {
+				l2cap_send_disconn_req(conn, sk);
+				goto done;
+			}
+
+			l2cap_send_cmd(conn, l2cap_get_ident(conn),
+						L2CAP_CONF_REQ, len, req);
+			l2cap_pi(sk)->num_conf_req++;
+			if (result != L2CAP_CONF_SUCCESS)
+				goto done;
+			break;
 		}
 
 	default:
 		sk->sk_state = BT_DISCONN;
 		sk->sk_err = ECONNRESET;
 		l2cap_sock_set_timer(sk, HZ * 5);
-		{
-			struct l2cap_disconn_req req;
-			req.dcid = cpu_to_le16(l2cap_pi(sk)->dcid);
-			req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
-			l2cap_send_cmd(conn, l2cap_get_ident(conn),
-					L2CAP_DISCONN_REQ, sizeof(req), &req);
-		}
+		l2cap_send_disconn_req(conn, sk);
 		goto done;
 	}
 
@@ -2134,7 +2836,16 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 	l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
 
 	if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
+		if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_NO_FCS_RECV)
+				|| l2cap_pi(sk)->fcs != L2CAP_FCS_NONE)
+			l2cap_pi(sk)->fcs = L2CAP_FCS_CRC16;
+
 		sk->sk_state = BT_CONNECTED;
+		l2cap_pi(sk)->expected_tx_seq = 0;
+		l2cap_pi(sk)->buffer_seq = 0;
+		l2cap_pi(sk)->num_to_ack = 0;
+		__skb_queue_head_init(TX_QUEUE(sk));
+		__skb_queue_head_init(SREJ_QUEUE(sk));
 		l2cap_chan_ready(sk);
 	}
 
@@ -2165,6 +2876,11 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
 
 	sk->sk_shutdown = SHUTDOWN_MASK;
 
+	skb_queue_purge(TX_QUEUE(sk));
+	skb_queue_purge(SREJ_QUEUE(sk));
+	del_timer(&l2cap_pi(sk)->retrans_timer);
+	del_timer(&l2cap_pi(sk)->monitor_timer);
+
 	l2cap_chan_del(sk, ECONNRESET);
 	bh_unlock_sock(sk);
 
@@ -2187,6 +2903,11 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
 	if (!sk)
 		return 0;
 
+	skb_queue_purge(TX_QUEUE(sk));
+	skb_queue_purge(SREJ_QUEUE(sk));
+	del_timer(&l2cap_pi(sk)->retrans_timer);
+	del_timer(&l2cap_pi(sk)->monitor_timer);
+
 	l2cap_chan_del(sk, 0);
 	bh_unlock_sock(sk);
 
@@ -2205,10 +2926,14 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm
 
 	if (type == L2CAP_IT_FEAT_MASK) {
 		u8 buf[8];
+		u32 feat_mask = l2cap_feat_mask;
 		struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
 		rsp->type   = cpu_to_le16(L2CAP_IT_FEAT_MASK);
 		rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
-		put_unaligned(cpu_to_le32(l2cap_feat_mask), (__le32 *) rsp->data);
+		if (enable_ertm)
+			feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING
+							 | L2CAP_FEAT_FCS;
+		put_unaligned_le32(feat_mask, rsp->data);
 		l2cap_send_cmd(conn, cmd->ident,
 					L2CAP_INFO_RSP, sizeof(buf), buf);
 	} else if (type == L2CAP_IT_FIXED_CHAN) {
@@ -2359,9 +3084,374 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
 	kfree_skb(skb);
 }
 
+static int l2cap_check_fcs(struct l2cap_pinfo *pi,  struct sk_buff *skb)
+{
+	u16 our_fcs, rcv_fcs;
+	int hdr_size = L2CAP_HDR_SIZE + 2;
+
+	if (pi->fcs == L2CAP_FCS_CRC16) {
+		skb_trim(skb, skb->len - 2);
+		rcv_fcs = get_unaligned_le16(skb->data + skb->len);
+		our_fcs = crc16(0, skb->data - hdr_size, skb->len + hdr_size);
+
+		if (our_fcs != rcv_fcs)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+static void l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
+{
+	struct sk_buff *next_skb;
+
+	bt_cb(skb)->tx_seq = tx_seq;
+	bt_cb(skb)->sar = sar;
+
+	next_skb = skb_peek(SREJ_QUEUE(sk));
+	if (!next_skb) {
+		__skb_queue_tail(SREJ_QUEUE(sk), skb);
+		return;
+	}
+
+	do {
+		if (bt_cb(next_skb)->tx_seq > tx_seq) {
+			__skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
+			return;
+		}
+
+		if (skb_queue_is_last(SREJ_QUEUE(sk), next_skb))
+			break;
+
+	} while((next_skb = skb_queue_next(SREJ_QUEUE(sk), next_skb)));
+
+	__skb_queue_tail(SREJ_QUEUE(sk), skb);
+}
+
+static int l2cap_sar_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 control)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	struct sk_buff *_skb;
+	int err = -EINVAL;
+
+	switch (control & L2CAP_CTRL_SAR) {
+	case L2CAP_SDU_UNSEGMENTED:
+		if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
+			kfree_skb(pi->sdu);
+			break;
+		}
+
+		err = sock_queue_rcv_skb(sk, skb);
+		if (!err)
+			return 0;
+
+		break;
+
+	case L2CAP_SDU_START:
+		if (pi->conn_state & L2CAP_CONN_SAR_SDU) {
+			kfree_skb(pi->sdu);
+			break;
+		}
+
+		pi->sdu_len = get_unaligned_le16(skb->data);
+		skb_pull(skb, 2);
+
+		pi->sdu = bt_skb_alloc(pi->sdu_len, GFP_ATOMIC);
+		if (!pi->sdu) {
+			err = -ENOMEM;
+			break;
+		}
+
+		memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+
+		pi->conn_state |= L2CAP_CONN_SAR_SDU;
+		pi->partial_sdu_len = skb->len;
+		err = 0;
+		break;
+
+	case L2CAP_SDU_CONTINUE:
+		if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+			break;
+
+		memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+
+		pi->partial_sdu_len += skb->len;
+		if (pi->partial_sdu_len > pi->sdu_len)
+			kfree_skb(pi->sdu);
+		else
+			err = 0;
+
+		break;
+
+	case L2CAP_SDU_END:
+		if (!(pi->conn_state & L2CAP_CONN_SAR_SDU))
+			break;
+
+		memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len);
+
+		pi->conn_state &= ~L2CAP_CONN_SAR_SDU;
+		pi->partial_sdu_len += skb->len;
+
+		if (pi->partial_sdu_len == pi->sdu_len) {
+			_skb = skb_clone(pi->sdu, GFP_ATOMIC);
+			err = sock_queue_rcv_skb(sk, _skb);
+			if (err < 0)
+				kfree_skb(_skb);
+		}
+		kfree_skb(pi->sdu);
+		err = 0;
+
+		break;
+	}
+
+	kfree_skb(skb);
+	return err;
+}
+
+static void l2cap_check_srej_gap(struct sock *sk, u8 tx_seq)
+{
+	struct sk_buff *skb;
+	u16 control = 0;
+
+	while((skb = skb_peek(SREJ_QUEUE(sk)))) {
+		if (bt_cb(skb)->tx_seq != tx_seq)
+			break;
+
+		skb = skb_dequeue(SREJ_QUEUE(sk));
+		control |= bt_cb(skb)->sar << L2CAP_CTRL_SAR_SHIFT;
+		l2cap_sar_reassembly_sdu(sk, skb, control);
+		l2cap_pi(sk)->buffer_seq_srej =
+			(l2cap_pi(sk)->buffer_seq_srej + 1) % 64;
+		tx_seq++;
+	}
+}
+
+static void l2cap_resend_srejframe(struct sock *sk, u8 tx_seq)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	struct srej_list *l, *tmp;
+	u16 control;
+
+	list_for_each_entry_safe(l,tmp, SREJ_LIST(sk), list) {
+		if (l->tx_seq == tx_seq) {
+			list_del(&l->list);
+			kfree(l);
+			return;
+		}
+		control = L2CAP_SUPER_SELECT_REJECT;
+		control |= l->tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+		l2cap_send_sframe(pi, control);
+		list_del(&l->list);
+		list_add_tail(&l->list, SREJ_LIST(sk));
+	}
+}
+
+static void l2cap_send_srejframe(struct sock *sk, u8 tx_seq)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	struct srej_list *new;
+	u16 control;
+
+	while (tx_seq != pi->expected_tx_seq) {
+		control = L2CAP_SUPER_SELECT_REJECT;
+		control |= pi->expected_tx_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+		if (pi->conn_state & L2CAP_CONN_SEND_PBIT) {
+			control |= L2CAP_CTRL_POLL;
+			pi->conn_state &= ~L2CAP_CONN_SEND_PBIT;
+		}
+		l2cap_send_sframe(pi, control);
+
+		new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
+		new->tx_seq = pi->expected_tx_seq++;
+		list_add_tail(&new->list, SREJ_LIST(sk));
+	}
+	pi->expected_tx_seq++;
+}
+
+static inline int l2cap_data_channel_iframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	u8 tx_seq = __get_txseq(rx_control);
+	u16 tx_control = 0;
+	u8 sar = rx_control >> L2CAP_CTRL_SAR_SHIFT;
+	int err = 0;
+
+	BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+
+	if (tx_seq == pi->expected_tx_seq)
+		goto expected;
+
+	if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+		struct srej_list *first;
+
+		first = list_first_entry(SREJ_LIST(sk),
+				struct srej_list, list);
+		if (tx_seq == first->tx_seq) {
+			l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+			l2cap_check_srej_gap(sk, tx_seq);
+
+			list_del(&first->list);
+			kfree(first);
+
+			if (list_empty(SREJ_LIST(sk))) {
+				pi->buffer_seq = pi->buffer_seq_srej;
+				pi->conn_state &= ~L2CAP_CONN_SREJ_SENT;
+			}
+		} else {
+			struct srej_list *l;
+			l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+
+			list_for_each_entry(l, SREJ_LIST(sk), list) {
+				if (l->tx_seq == tx_seq) {
+					l2cap_resend_srejframe(sk, tx_seq);
+					return 0;
+				}
+			}
+			l2cap_send_srejframe(sk, tx_seq);
+		}
+	} else {
+		pi->conn_state |= L2CAP_CONN_SREJ_SENT;
+
+		INIT_LIST_HEAD(SREJ_LIST(sk));
+		pi->buffer_seq_srej = pi->buffer_seq;
+
+		__skb_queue_head_init(SREJ_QUEUE(sk));
+		l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+
+		pi->conn_state |= L2CAP_CONN_SEND_PBIT;
+
+		l2cap_send_srejframe(sk, tx_seq);
+	}
+	return 0;
+
+expected:
+	pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+
+	if (pi->conn_state & L2CAP_CONN_SREJ_SENT) {
+		l2cap_add_to_srej_queue(sk, skb, tx_seq, sar);
+		return 0;
+	}
+
+	pi->buffer_seq = (pi->buffer_seq + 1) % 64;
+
+	err = l2cap_sar_reassembly_sdu(sk, skb, rx_control);
+	if (err < 0)
+		return err;
+
+	pi->num_to_ack = (pi->num_to_ack + 1) % L2CAP_DEFAULT_NUM_TO_ACK;
+	if (pi->num_to_ack == L2CAP_DEFAULT_NUM_TO_ACK - 1) {
+		tx_control |= L2CAP_SUPER_RCV_READY;
+		tx_control |= pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT;
+		l2cap_send_sframe(pi, tx_control);
+	}
+	return 0;
+}
+
+static inline int l2cap_data_channel_sframe(struct sock *sk, u16 rx_control, struct sk_buff *skb)
+{
+	struct l2cap_pinfo *pi = l2cap_pi(sk);
+	u8 tx_seq = __get_reqseq(rx_control);
+
+	BT_DBG("sk %p rx_control 0x%4.4x len %d", sk, rx_control, skb->len);
+
+	switch (rx_control & L2CAP_CTRL_SUPERVISE) {
+	case L2CAP_SUPER_RCV_READY:
+		if (rx_control & L2CAP_CTRL_POLL) {
+			u16 control = L2CAP_CTRL_FINAL;
+			control |= L2CAP_SUPER_RCV_READY |
+				(pi->buffer_seq << L2CAP_CTRL_REQSEQ_SHIFT);
+			l2cap_send_sframe(l2cap_pi(sk), control);
+			pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+
+		} else if (rx_control & L2CAP_CTRL_FINAL) {
+			pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+			pi->expected_ack_seq = tx_seq;
+			l2cap_drop_acked_frames(sk);
+
+			if (!(pi->conn_state & L2CAP_CONN_WAIT_F))
+				break;
+
+			pi->conn_state &= ~L2CAP_CONN_WAIT_F;
+			del_timer(&pi->monitor_timer);
+
+			if (pi->unacked_frames > 0)
+				__mod_retrans_timer();
+		} else {
+			pi->expected_ack_seq = tx_seq;
+			l2cap_drop_acked_frames(sk);
+
+			if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY)
+					&& (pi->unacked_frames > 0))
+				__mod_retrans_timer();
+
+			l2cap_ertm_send(sk);
+			pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+		}
+		break;
+
+	case L2CAP_SUPER_REJECT:
+		pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+
+		pi->expected_ack_seq = __get_reqseq(rx_control);
+		l2cap_drop_acked_frames(sk);
+
+		sk->sk_send_head = TX_QUEUE(sk)->next;
+		pi->next_tx_seq = pi->expected_ack_seq;
+
+		l2cap_ertm_send(sk);
+
+		break;
+
+	case L2CAP_SUPER_SELECT_REJECT:
+		pi->conn_state &= ~L2CAP_CONN_REMOTE_BUSY;
+
+		if (rx_control & L2CAP_CTRL_POLL) {
+			l2cap_retransmit_frame(sk, tx_seq);
+			pi->expected_ack_seq = tx_seq;
+			l2cap_drop_acked_frames(sk);
+			l2cap_ertm_send(sk);
+			if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+				pi->srej_save_reqseq = tx_seq;
+				pi->conn_state |= L2CAP_CONN_SREJ_ACT;
+			}
+		} else if (rx_control & L2CAP_CTRL_FINAL) {
+			if ((pi->conn_state & L2CAP_CONN_SREJ_ACT) &&
+					pi->srej_save_reqseq == tx_seq)
+				pi->srej_save_reqseq &= ~L2CAP_CONN_SREJ_ACT;
+			else
+				l2cap_retransmit_frame(sk, tx_seq);
+		}
+		else {
+			l2cap_retransmit_frame(sk, tx_seq);
+			if (pi->conn_state & L2CAP_CONN_WAIT_F) {
+				pi->srej_save_reqseq = tx_seq;
+				pi->conn_state |= L2CAP_CONN_SREJ_ACT;
+			}
+		}
+		break;
+
+	case L2CAP_SUPER_RCV_NOT_READY:
+		pi->conn_state |= L2CAP_CONN_REMOTE_BUSY;
+		pi->expected_ack_seq = tx_seq;
+		l2cap_drop_acked_frames(sk);
+
+		del_timer(&l2cap_pi(sk)->retrans_timer);
+		if (rx_control & L2CAP_CTRL_POLL) {
+			u16 control = L2CAP_CTRL_FINAL;
+			l2cap_send_rr_or_rnr(l2cap_pi(sk), control);
+		}
+		break;
+	}
+
+	return 0;
+}
+
 static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb)
 {
 	struct sock *sk;
+	struct l2cap_pinfo *pi;
+	u16 control, len;
+	u8 tx_seq;
+	int err;
 
 	sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
 	if (!sk) {
@@ -2369,22 +3459,91 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
 		goto drop;
 	}
 
+	pi = l2cap_pi(sk);
+
 	BT_DBG("sk %p, len %d", sk, skb->len);
 
 	if (sk->sk_state != BT_CONNECTED)
 		goto drop;
 
-	if (l2cap_pi(sk)->imtu < skb->len)
-		goto drop;
+	switch (pi->mode) {
+	case L2CAP_MODE_BASIC:
+		/* If socket recv buffers overflows we drop data here
+		 * which is *bad* because L2CAP has to be reliable.
+		 * But we don't have any other choice. L2CAP doesn't
+		 * provide flow control mechanism. */
 
-	/* If socket recv buffers overflows we drop data here
-	 * which is *bad* because L2CAP has to be reliable.
-	 * But we don't have any other choice. L2CAP doesn't
-	 * provide flow control mechanism. */
+		if (pi->imtu < skb->len)
+			goto drop;
+
+		if (!sock_queue_rcv_skb(sk, skb))
+			goto done;
+		break;
+
+	case L2CAP_MODE_ERTM:
+		control = get_unaligned_le16(skb->data);
+		skb_pull(skb, 2);
+		len = skb->len;
+
+		if (__is_sar_start(control))
+			len -= 2;
+
+		if (pi->fcs == L2CAP_FCS_CRC16)
+			len -= 2;
+
+		/*
+		 * We can just drop the corrupted I-frame here.
+		 * Receiver will miss it and start proper recovery
+		 * procedures and ask retransmission.
+		 */
+		if (len > L2CAP_DEFAULT_MAX_PDU_SIZE)
+			goto drop;
+
+		if (l2cap_check_fcs(pi, skb))
+			goto drop;
+
+		if (__is_iframe(control))
+			err = l2cap_data_channel_iframe(sk, control, skb);
+		else
+			err = l2cap_data_channel_sframe(sk, control, skb);
+
+		if (!err)
+			goto done;
+		break;
+
+	case L2CAP_MODE_STREAMING:
+		control = get_unaligned_le16(skb->data);
+		skb_pull(skb, 2);
+		len = skb->len;
+
+		if (__is_sar_start(control))
+			len -= 2;
+
+		if (pi->fcs == L2CAP_FCS_CRC16)
+			len -= 2;
+
+		if (len > L2CAP_DEFAULT_MAX_PDU_SIZE || __is_sframe(control))
+			goto drop;
+
+		if (l2cap_check_fcs(pi, skb))
+			goto drop;
+
+		tx_seq = __get_txseq(control);
+
+		if (pi->expected_tx_seq == tx_seq)
+			pi->expected_tx_seq = (pi->expected_tx_seq + 1) % 64;
+		else
+			pi->expected_tx_seq = tx_seq + 1;
+
+		err = l2cap_sar_reassembly_sdu(sk, skb, control);
 
-	if (!sock_queue_rcv_skb(sk, skb))
 		goto done;
 
+	default:
+		BT_DBG("sk %p: bad mode 0x%2.2x", sk, l2cap_pi(sk)->mode);
+		break;
+	}
+
 drop:
 	kfree_skb(skb);
 
@@ -2433,6 +3592,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 	cid = __le16_to_cpu(lh->cid);
 	len = __le16_to_cpu(lh->len);
 
+	if (len != skb->len) {
+		kfree_skb(skb);
+		return;
+	}
+
 	BT_DBG("len %d, cid 0x%4.4x", len, cid);
 
 	switch (cid) {
@@ -2441,7 +3605,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 		break;
 
 	case L2CAP_CID_CONN_LESS:
-		psm = get_unaligned((__le16 *) skb->data);
+		psm = get_unaligned_le16(skb->data);
 		skb_pull(skb, 2);
 		l2cap_conless_channel(conn, psm, skb);
 		break;
@@ -2828,6 +3992,9 @@ EXPORT_SYMBOL(l2cap_load);
 module_init(l2cap_init);
 module_exit(l2cap_exit);
 
+module_param(enable_ertm, bool, 0644);
+MODULE_PARM_DESC(enable_ertm, "Enable enhanced retransmission mode");
+
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
 MODULE_VERSION(VERSION);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 94b3388..25692bc 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -244,6 +244,33 @@ static inline int rfcomm_check_security(struct rfcomm_dlc *d)
 								auth_type);
 }
 
+static void rfcomm_session_timeout(unsigned long arg)
+{
+	struct rfcomm_session *s = (void *) arg;
+
+	BT_DBG("session %p state %ld", s, s->state);
+
+	set_bit(RFCOMM_TIMED_OUT, &s->flags);
+	rfcomm_session_put(s);
+	rfcomm_schedule(RFCOMM_SCHED_TIMEO);
+}
+
+static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout)
+{
+	BT_DBG("session %p state %ld timeout %ld", s, s->state, timeout);
+
+	if (!mod_timer(&s->timer, jiffies + timeout))
+		rfcomm_session_hold(s);
+}
+
+static void rfcomm_session_clear_timer(struct rfcomm_session *s)
+{
+	BT_DBG("session %p state %ld", s, s->state);
+
+	if (timer_pending(&s->timer) && del_timer(&s->timer))
+		rfcomm_session_put(s);
+}
+
 /* ---- RFCOMM DLCs ---- */
 static void rfcomm_dlc_timeout(unsigned long arg)
 {
@@ -320,6 +347,7 @@ static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
 
 	rfcomm_session_hold(s);
 
+	rfcomm_session_clear_timer(s);
 	rfcomm_dlc_hold(d);
 	list_add(&d->list, &s->dlcs);
 	d->session = s;
@@ -335,6 +363,9 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
 	d->session = NULL;
 	rfcomm_dlc_put(d);
 
+	if (list_empty(&s->dlcs))
+		rfcomm_session_set_timer(s, RFCOMM_IDLE_TIMEOUT);
+
 	rfcomm_session_put(s);
 }
 
@@ -567,6 +598,8 @@ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
 
 	BT_DBG("session %p sock %p", s, sock);
 
+	setup_timer(&s->timer, rfcomm_session_timeout, (unsigned long) s);
+
 	INIT_LIST_HEAD(&s->dlcs);
 	s->state = state;
 	s->sock  = sock;
@@ -598,6 +631,7 @@ static void rfcomm_session_del(struct rfcomm_session *s)
 	if (state == BT_CONNECTED)
 		rfcomm_send_disc(s, 0);
 
+	rfcomm_session_clear_timer(s);
 	sock_release(s->sock);
 	kfree(s);
 
@@ -639,6 +673,7 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err)
 		__rfcomm_dlc_close(d, err);
 	}
 
+	rfcomm_session_clear_timer(s);
 	rfcomm_session_put(s);
 }
 
@@ -1879,6 +1914,12 @@ static inline void rfcomm_process_sessions(void)
 		struct rfcomm_session *s;
 		s = list_entry(p, struct rfcomm_session, list);
 
+		if (test_and_clear_bit(RFCOMM_TIMED_OUT, &s->flags)) {
+			s->state = BT_DISCONN;
+			rfcomm_send_disc(s, 0);
+			continue;
+		}
+
 		if (s->state == BT_LISTEN) {
 			rfcomm_accept_connection(s);
 			continue;
@@ -2080,7 +2121,7 @@ static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
 /* ---- Initialization ---- */
 static int __init rfcomm_init(void)
 {
-	int ret;
+	int err;
 
 	l2cap_load();
 
@@ -2088,33 +2129,35 @@ static int __init rfcomm_init(void)
 
 	rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
 	if (IS_ERR(rfcomm_thread)) {
-		ret = PTR_ERR(rfcomm_thread);
-		goto out_thread;
+		err = PTR_ERR(rfcomm_thread);
+		goto unregister;
 	}
 
 	if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
 		BT_ERR("Failed to create RFCOMM info file");
 
-	ret = rfcomm_init_ttys();
-	if (ret)
-		goto out_tty;
+	err = rfcomm_init_ttys();
+	if (err < 0)
+		goto stop;
 
-	ret = rfcomm_init_sockets();
-	if (ret)
-		goto out_sock;
+	err = rfcomm_init_sockets();
+	if (err < 0)
+		goto cleanup;
 
 	BT_INFO("RFCOMM ver %s", VERSION);
 
 	return 0;
 
-out_sock:
+cleanup:
 	rfcomm_cleanup_ttys();
-out_tty:
+
+stop:
 	kthread_stop(rfcomm_thread);
-out_thread:
+
+unregister:
 	hci_unregister_cb(&rfcomm_cb);
 
-	return ret;
+	return err;
 }
 
 static void __exit rfcomm_exit(void)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 51ae0c3..13c27f1 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -359,20 +359,9 @@ static void sco_sock_kill(struct sock *sk)
 	sock_put(sk);
 }
 
-/* Close socket.
- * Must be called on unlocked socket.
- */
-static void sco_sock_close(struct sock *sk)
+static void __sco_sock_close(struct sock *sk)
 {
-	struct sco_conn *conn;
-
-	sco_sock_clear_timer(sk);
-
-	lock_sock(sk);
-
-	conn = sco_pi(sk)->conn;
-
-	BT_DBG("sk %p state %d conn %p socket %p", sk, sk->sk_state, conn, sk->sk_socket);
+	BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
 
 	switch (sk->sk_state) {
 	case BT_LISTEN:
@@ -390,9 +379,15 @@ static void sco_sock_close(struct sock *sk)
 		sock_set_flag(sk, SOCK_ZAPPED);
 		break;
 	}
+}
 
+/* Must be called on unlocked socket. */
+static void sco_sock_close(struct sock *sk)
+{
+	sco_sock_clear_timer(sk);
+	lock_sock(sk);
+	__sco_sock_close(sk);
 	release_sock(sk);
-
 	sco_sock_kill(sk);
 }
 
@@ -748,6 +743,30 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
 	return err;
 }
 
+static int sco_sock_shutdown(struct socket *sock, int how)
+{
+	struct sock *sk = sock->sk;
+	int err = 0;
+
+	BT_DBG("sock %p, sk %p", sock, sk);
+
+	if (!sk)
+		return 0;
+
+	lock_sock(sk);
+	if (!sk->sk_shutdown) {
+		sk->sk_shutdown = SHUTDOWN_MASK;
+		sco_sock_clear_timer(sk);
+		__sco_sock_close(sk);
+
+		if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
+			err = bt_sock_wait_state(sk, BT_CLOSED,
+							sk->sk_lingertime);
+	}
+	release_sock(sk);
+	return err;
+}
+
 static int sco_sock_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
@@ -969,7 +988,7 @@ static const struct proto_ops sco_sock_ops = {
 	.ioctl		= bt_sock_ioctl,
 	.mmap		= sock_no_mmap,
 	.socketpair	= sock_no_socketpair,
-	.shutdown	= sock_no_shutdown,
+	.shutdown	= sco_sock_shutdown,
 	.setsockopt	= sco_sock_setsockopt,
 	.getsockopt	= sco_sock_getsockopt
 };
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 18538d7..07a0777 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -20,7 +20,7 @@
 #include "br_private.h"
 
 /* net device transmit always called with no BH (preempt_disabled) */
-int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_bridge *br = netdev_priv(dev);
 	const unsigned char *dest = skb->data;
@@ -39,7 +39,7 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 	else
 		br_flood_deliver(br, skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int br_dev_open(struct net_device *dev)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index d2c27c8..bc1704a 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -22,7 +22,8 @@
 static inline int should_deliver(const struct net_bridge_port *p,
 				 const struct sk_buff *skb)
 {
-	return (skb->dev != p->dev && p->state == BR_STATE_FORWARDING);
+	return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
+		p->state == BR_STATE_FORWARDING);
 }
 
 static inline unsigned packet_length(const struct sk_buff *skb)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index eb404dc..142ebac 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -256,6 +256,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
 	p->path_cost = port_cost(dev);
 	p->priority = 0x8000 >> BR_PORT_BITS;
 	p->port_no = index;
+	p->flags = 0;
 	br_init_port(p);
 	p->state = BR_STATE_DISABLED;
 	br_stp_port_timer_init(p);
@@ -263,6 +264,10 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
 	return p;
 }
 
+static struct device_type br_type = {
+	.name	= "bridge",
+};
+
 int br_add_bridge(struct net *net, const char *name)
 {
 	struct net_device *dev;
@@ -279,6 +284,8 @@ int br_add_bridge(struct net *net, const char *name)
 			goto out_free;
 	}
 
+	SET_NETDEV_DEVTYPE(dev, &br_type);
+
 	ret = register_netdevice(dev);
 	if (ret)
 		goto out_free;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index d22f611..907a82e 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -359,7 +359,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
 				},
 				.proto = 0,
 			};
-			struct in_device *in_dev = in_dev_get(dev);
+			struct in_device *in_dev = __in_dev_get_rcu(dev);
 
 			/* If err equals -EHOSTUNREACH the error is due to a
 			 * martian destination or due to the fact that
@@ -905,46 +905,62 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb,
  * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
  * ip_refrag() can return NF_STOLEN. */
 static struct nf_hook_ops br_nf_ops[] __read_mostly = {
-	{ .hook = br_nf_pre_routing,
-	  .owner = THIS_MODULE,
-	  .pf = PF_BRIDGE,
-	  .hooknum = NF_BR_PRE_ROUTING,
-	  .priority = NF_BR_PRI_BRNF, },
-	{ .hook = br_nf_local_in,
-	  .owner = THIS_MODULE,
-	  .pf = PF_BRIDGE,
-	  .hooknum = NF_BR_LOCAL_IN,
-	  .priority = NF_BR_PRI_BRNF, },
-	{ .hook = br_nf_forward_ip,
-	  .owner = THIS_MODULE,
-	  .pf = PF_BRIDGE,
-	  .hooknum = NF_BR_FORWARD,
-	  .priority = NF_BR_PRI_BRNF - 1, },
-	{ .hook = br_nf_forward_arp,
-	  .owner = THIS_MODULE,
-	  .pf = PF_BRIDGE,
-	  .hooknum = NF_BR_FORWARD,
-	  .priority = NF_BR_PRI_BRNF, },
-	{ .hook = br_nf_local_out,
-	  .owner = THIS_MODULE,
-	  .pf = PF_BRIDGE,
-	  .hooknum = NF_BR_LOCAL_OUT,
-	  .priority = NF_BR_PRI_FIRST, },
-	{ .hook = br_nf_post_routing,
-	  .owner = THIS_MODULE,
-	  .pf = PF_BRIDGE,
-	  .hooknum = NF_BR_POST_ROUTING,
-	  .priority = NF_BR_PRI_LAST, },
-	{ .hook = ip_sabotage_in,
-	  .owner = THIS_MODULE,
-	  .pf = PF_INET,
-	  .hooknum = NF_INET_PRE_ROUTING,
-	  .priority = NF_IP_PRI_FIRST, },
-	{ .hook = ip_sabotage_in,
-	  .owner = THIS_MODULE,
-	  .pf = PF_INET6,
-	  .hooknum = NF_INET_PRE_ROUTING,
-	  .priority = NF_IP6_PRI_FIRST, },
+	{
+		.hook = br_nf_pre_routing,
+		.owner = THIS_MODULE,
+		.pf = PF_BRIDGE,
+		.hooknum = NF_BR_PRE_ROUTING,
+		.priority = NF_BR_PRI_BRNF,
+	},
+	{
+		.hook = br_nf_local_in,
+		.owner = THIS_MODULE,
+		.pf = PF_BRIDGE,
+		.hooknum = NF_BR_LOCAL_IN,
+		.priority = NF_BR_PRI_BRNF,
+	},
+	{
+		.hook = br_nf_forward_ip,
+		.owner = THIS_MODULE,
+		.pf = PF_BRIDGE,
+		.hooknum = NF_BR_FORWARD,
+		.priority = NF_BR_PRI_BRNF - 1,
+	},
+	{
+		.hook = br_nf_forward_arp,
+		.owner = THIS_MODULE,
+		.pf = PF_BRIDGE,
+		.hooknum = NF_BR_FORWARD,
+		.priority = NF_BR_PRI_BRNF,
+	},
+	{
+		.hook = br_nf_local_out,
+		.owner = THIS_MODULE,
+		.pf = PF_BRIDGE,
+		.hooknum = NF_BR_LOCAL_OUT,
+		.priority = NF_BR_PRI_FIRST,
+	},
+	{
+		.hook = br_nf_post_routing,
+		.owner = THIS_MODULE,
+		.pf = PF_BRIDGE,
+		.hooknum = NF_BR_POST_ROUTING,
+		.priority = NF_BR_PRI_LAST,
+	},
+	{
+		.hook = ip_sabotage_in,
+		.owner = THIS_MODULE,
+		.pf = PF_INET,
+		.hooknum = NF_INET_PRE_ROUTING,
+		.priority = NF_IP_PRI_FIRST,
+	},
+	{
+		.hook = ip_sabotage_in,
+		.owner = THIS_MODULE,
+		.pf = PF_INET6,
+		.hooknum = NF_INET_PRE_ROUTING,
+		.priority = NF_IP6_PRI_FIRST,
+	},
 };
 
 #ifdef CONFIG_SYSCTL
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index d5b5537..2114e45 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -81,6 +81,9 @@ struct net_bridge_port
 	struct timer_list		message_age_timer;
 	struct kobject			kobj;
 	struct rcu_head			rcu;
+
+	unsigned long 			flags;
+#define BR_HAIRPIN_MODE		0x00000001
 };
 
 struct net_bridge
@@ -140,7 +143,8 @@ static inline int br_is_root_bridge(const struct net_bridge *br)
 
 /* br_device.c */
 extern void br_dev_setup(struct net_device *dev);
-extern int br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
+extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
+			       struct net_device *dev);
 
 /* br_fdb.c */
 extern int br_fdb_init(void);
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 0660515..fd3f8d6 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -21,7 +21,7 @@
  */
 #define MESSAGE_AGE_INCR	((HZ < 256) ? 1 : (HZ/256))
 
-static const char *br_port_state_names[] = {
+static const char *const br_port_state_names[] = {
 	[BR_STATE_DISABLED] = "disabled",
 	[BR_STATE_LISTENING] = "listening",
 	[BR_STATE_LEARNING] = "learning",
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 4a3cdf8..820643a 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -143,6 +143,22 @@ static ssize_t store_flush(struct net_bridge_port *p, unsigned long v)
 }
 static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush);
 
+static ssize_t show_hairpin_mode(struct net_bridge_port *p, char *buf)
+{
+	int hairpin_mode = (p->flags & BR_HAIRPIN_MODE) ? 1 : 0;
+	return sprintf(buf, "%d\n", hairpin_mode);
+}
+static ssize_t store_hairpin_mode(struct net_bridge_port *p, unsigned long v)
+{
+	if (v)
+		p->flags |= BR_HAIRPIN_MODE;
+	else
+		p->flags &= ~BR_HAIRPIN_MODE;
+	return 0;
+}
+static BRPORT_ATTR(hairpin_mode, S_IRUGO | S_IWUSR,
+		   show_hairpin_mode, store_hairpin_mode);
+
 static struct brport_attribute *brport_attrs[] = {
 	&brport_attr_path_cost,
 	&brport_attr_priority,
@@ -159,6 +175,7 @@ static struct brport_attribute *brport_attrs[] = {
 	&brport_attr_forward_delay_timer,
 	&brport_attr_hold_timer,
 	&brport_attr_flush,
+	&brport_attr_hairpin_mode,
 	NULL
 };
 
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index a94f3cc..e4ea3fd 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -50,14 +50,6 @@ struct arppayload
 	unsigned char ip_dst[4];
 };
 
-static void print_MAC(const unsigned char *p)
-{
-	int i;
-
-	for (i = 0; i < ETH_ALEN; i++, p++)
-		printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':');
-}
-
 static void
 print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
 {
@@ -88,14 +80,11 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
 	unsigned int bitmask;
 
 	spin_lock_bh(&ebt_log_lock);
-	printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level,
-	       prefix, in ? in->name : "", out ? out->name : "");
-
-	print_MAC(eth_hdr(skb)->h_source);
-	printk("MAC dest = ");
-	print_MAC(eth_hdr(skb)->h_dest);
-
-	printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto));
+	printk("<%c>%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x",
+	       '0' + loginfo->u.log.level, prefix,
+	       in ? in->name : "", out ? out->name : "",
+	       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
+	       ntohs(eth_hdr(skb)->h_proto));
 
 	if (loginfo->type == NF_LOG_TYPE_LOG)
 		bitmask = loginfo->u.log.logflags;
@@ -171,12 +160,8 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
 				printk(" INCOMPLETE ARP payload");
 				goto out;
 			}
-			printk(" ARP MAC SRC=");
-			print_MAC(ap->mac_src);
-			printk(" ARP IP SRC=%pI4", ap->ip_src);
-			printk(" ARP MAC DST=");
-			print_MAC(ap->mac_dst);
-			printk(" ARP IP DST=%pI4", ap->ip_dst);
+			printk(" ARP MAC SRC=%pM ARP IP SRC=%pI4 ARP MAC DST=%pM ARP IP DST=%pI4",
+					ap->mac_src, ap->ip_src, ap->mac_dst, ap->ip_dst);
 		}
 	}
 out:
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 133eeae..ce50688 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -266,7 +266,7 @@ static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
 	if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
 		uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
 
-	return 0;
+	return true;
 }
 
 static struct xt_target ebt_ulog_tg_reg __read_mostly = {
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index c751111..d32ab13 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -41,7 +41,7 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
 	return 0;
 }
 
-static struct ebt_table broute_table =
+static const struct ebt_table broute_table =
 {
 	.name		= "broute",
 	.table		= &initial_table,
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index a5eea72..60b1a6c 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -50,7 +50,7 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
 	return 0;
 }
 
-static struct ebt_table frame_filter =
+static const struct ebt_table frame_filter =
 {
 	.name		= "filter",
 	.table		= &initial_table,
@@ -77,21 +77,21 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
 	{
 		.hook		= ebt_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_BRIDGE,
+		.pf		= NFPROTO_BRIDGE,
 		.hooknum	= NF_BR_LOCAL_IN,
 		.priority	= NF_BR_PRI_FILTER_BRIDGED,
 	},
 	{
 		.hook		= ebt_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_BRIDGE,
+		.pf		= NFPROTO_BRIDGE,
 		.hooknum	= NF_BR_FORWARD,
 		.priority	= NF_BR_PRI_FILTER_BRIDGED,
 	},
 	{
 		.hook		= ebt_out_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_BRIDGE,
+		.pf		= NFPROTO_BRIDGE,
 		.hooknum	= NF_BR_LOCAL_OUT,
 		.priority	= NF_BR_PRI_FILTER_OTHER,
 	},
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 6024c55..4a98804 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -77,21 +77,21 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
 	{
 		.hook		= ebt_nat_out,
 		.owner		= THIS_MODULE,
-		.pf		= PF_BRIDGE,
+		.pf		= NFPROTO_BRIDGE,
 		.hooknum	= NF_BR_LOCAL_OUT,
 		.priority	= NF_BR_PRI_NAT_DST_OTHER,
 	},
 	{
 		.hook		= ebt_nat_out,
 		.owner		= THIS_MODULE,
-		.pf		= PF_BRIDGE,
+		.pf		= NFPROTO_BRIDGE,
 		.hooknum	= NF_BR_POST_ROUTING,
 		.priority	= NF_BR_PRI_NAT_SRC,
 	},
 	{
 		.hook		= ebt_nat_in,
 		.owner		= THIS_MODULE,
-		.pf		= PF_BRIDGE,
+		.pf		= NFPROTO_BRIDGE,
 		.hooknum	= NF_BR_PRE_ROUTING,
 		.priority	= NF_BR_PRI_NAT_DST_BRIDGED,
 	},
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 37928d5..bd1c654 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1103,23 +1103,24 @@ free_newinfo:
 	return ret;
 }
 
-struct ebt_table *ebt_register_table(struct net *net, struct ebt_table *table)
+struct ebt_table *
+ebt_register_table(struct net *net, const struct ebt_table *input_table)
 {
 	struct ebt_table_info *newinfo;
-	struct ebt_table *t;
+	struct ebt_table *t, *table;
 	struct ebt_replace_kernel *repl;
 	int ret, i, countersize;
 	void *p;
 
-	if (!table || !(repl = table->table) || !repl->entries ||
-	    repl->entries_size == 0 ||
-	    repl->counters || table->private) {
+	if (input_table == NULL || (repl = input_table->table) == NULL ||
+	    repl->entries == 0 || repl->entries_size == 0 ||
+	    repl->counters != NULL || input_table->private != NULL) {
 		BUGPRINT("Bad table data for ebt_register_table!!!\n");
 		return ERR_PTR(-EINVAL);
 	}
 
 	/* Don't add one table to multiple lists. */
-	table = kmemdup(table, sizeof(struct ebt_table), GFP_KERNEL);
+	table = kmemdup(input_table, sizeof(struct ebt_table), GFP_KERNEL);
 	if (!table) {
 		ret = -ENOMEM;
 		goto out;
diff --git a/net/can/af_can.c b/net/can/af_can.c
index e733725..6068321 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -199,6 +199,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
  * @skb: pointer to socket buffer with CAN frame in data section
  * @loop: loopback for listeners on local CAN sockets (recommended default!)
  *
+ * Due to the loopback this routine must not be called from hardirq context.
+ *
  * Return:
  *  0 on success
  *  -ENETDOWN when the selected interface is down
@@ -278,7 +280,7 @@ int can_send(struct sk_buff *skb, int loop)
 	}
 
 	if (newskb)
-		netif_rx(newskb);
+		netif_rx_ni(newskb);
 
 	/* update statistics */
 	can_stats.tx_frames++;
@@ -651,12 +653,16 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
 	struct can_frame *cf = (struct can_frame *)skb->data;
 	int matches;
 
-	if (dev->type != ARPHRD_CAN || !net_eq(dev_net(dev), &init_net)) {
-		kfree_skb(skb);
-		return 0;
-	}
+	if (!net_eq(dev_net(dev), &init_net))
+		goto drop;
 
-	BUG_ON(skb->len != sizeof(struct can_frame) || cf->can_dlc > 8);
+	if (WARN_ONCE(dev->type != ARPHRD_CAN ||
+		      skb->len != sizeof(struct can_frame) ||
+		      cf->can_dlc > 8,
+		      "PF_CAN: dropped non conform skbuf: "
+		      "dev type %d, len %d, can_dlc %d\n",
+		      dev->type, skb->len, cf->can_dlc))
+		goto drop;
 
 	/* update statistics */
 	can_stats.rx_frames++;
@@ -682,7 +688,11 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
 		can_stats.matches_delta++;
 	}
 
-	return 0;
+	return NET_RX_SUCCESS;
+
+drop:
+	kfree_skb(skb);
+	return NET_RX_DROP;
 }
 
 /*
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 72720c7..597da4f 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -46,6 +46,7 @@
 #include <linux/hrtimer.h>
 #include <linux/list.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/uio.h>
 #include <linux/net.h>
 #include <linux/netdevice.h>
@@ -146,23 +147,18 @@ static char *bcm_proc_getifname(int ifindex)
 	return "???";
 }
 
-static int bcm_read_proc(char *page, char **start, off_t off,
-			 int count, int *eof, void *data)
+static int bcm_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
-	struct sock *sk = (struct sock *)data;
+	struct sock *sk = (struct sock *)m->private;
 	struct bcm_sock *bo = bcm_sk(sk);
 	struct bcm_op *op;
 
-	len += snprintf(page + len, PAGE_SIZE - len, ">>> socket %p",
-			sk->sk_socket);
-	len += snprintf(page + len, PAGE_SIZE - len, " / sk %p", sk);
-	len += snprintf(page + len, PAGE_SIZE - len, " / bo %p", bo);
-	len += snprintf(page + len, PAGE_SIZE - len, " / dropped %lu",
-			bo->dropped_usr_msgs);
-	len += snprintf(page + len, PAGE_SIZE - len, " / bound %s",
-			bcm_proc_getifname(bo->ifindex));
-	len += snprintf(page + len, PAGE_SIZE - len, " <<<\n");
+	seq_printf(m, ">>> socket %p", sk->sk_socket);
+	seq_printf(m, " / sk %p", sk);
+	seq_printf(m, " / bo %p", bo);
+	seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs);
+	seq_printf(m, " / bound %s", bcm_proc_getifname(bo->ifindex));
+	seq_printf(m, " <<<\n");
 
 	list_for_each_entry(op, &bo->rx_ops, list) {
 
@@ -172,71 +168,62 @@ static int bcm_read_proc(char *page, char **start, off_t off,
 		if (!op->frames_abs)
 			continue;
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"rx_op: %03X %-5s ",
+		seq_printf(m, "rx_op: %03X %-5s ",
 				op->can_id, bcm_proc_getifname(op->ifindex));
-		len += snprintf(page + len, PAGE_SIZE - len, "[%d]%c ",
-				op->nframes,
+		seq_printf(m, "[%d]%c ", op->nframes,
 				(op->flags & RX_CHECK_DLC)?'d':' ');
 		if (op->kt_ival1.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"timeo=%lld ",
+			seq_printf(m, "timeo=%lld ",
 					(long long)
 					ktime_to_us(op->kt_ival1));
 
 		if (op->kt_ival2.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"thr=%lld ",
+			seq_printf(m, "thr=%lld ",
 					(long long)
 					ktime_to_us(op->kt_ival2));
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"# recv %ld (%ld) => reduction: ",
+		seq_printf(m, "# recv %ld (%ld) => reduction: ",
 				op->frames_filtered, op->frames_abs);
 
 		reduction = 100 - (op->frames_filtered * 100) / op->frames_abs;
 
-		len += snprintf(page + len, PAGE_SIZE - len, "%s%ld%%\n",
+		seq_printf(m, "%s%ld%%\n",
 				(reduction == 100)?"near ":"", reduction);
-
-		if (len > PAGE_SIZE - 200) {
-			/* mark output cut off */
-			len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
-			break;
-		}
 	}
 
 	list_for_each_entry(op, &bo->tx_ops, list) {
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"tx_op: %03X %s [%d] ",
+		seq_printf(m, "tx_op: %03X %s [%d] ",
 				op->can_id, bcm_proc_getifname(op->ifindex),
 				op->nframes);
 
 		if (op->kt_ival1.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len, "t1=%lld ",
+			seq_printf(m, "t1=%lld ",
 					(long long) ktime_to_us(op->kt_ival1));
 
 		if (op->kt_ival2.tv64)
-			len += snprintf(page + len, PAGE_SIZE - len, "t2=%lld ",
+			seq_printf(m, "t2=%lld ",
 					(long long) ktime_to_us(op->kt_ival2));
 
-		len += snprintf(page + len, PAGE_SIZE - len, "# sent %ld\n",
-				op->frames_abs);
-
-		if (len > PAGE_SIZE - 100) {
-			/* mark output cut off */
-			len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
-			break;
-		}
+		seq_printf(m, "# sent %ld\n", op->frames_abs);
 	}
+	seq_putc(m, '\n');
+	return 0;
+}
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
-
-	*eof = 1;
-	return len;
+static int bcm_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, bcm_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations bcm_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= bcm_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
  *              of the given bcm tx op
@@ -1515,9 +1502,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
 	if (proc_dir) {
 		/* unique socket address as filename */
 		sprintf(bo->procname, "%p", sock);
-		bo->bcm_proc_read = create_proc_read_entry(bo->procname, 0644,
-							   proc_dir,
-							   bcm_read_proc, sk);
+		bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
+						     proc_dir,
+						     &bcm_proc_fops, sk);
 	}
 
 	return 0;
diff --git a/net/can/proc.c b/net/can/proc.c
index 1463653..9b9ad29 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -196,8 +196,8 @@ void can_stat_update(unsigned long data)
  *
  */
 
-static int can_print_rcvlist(char *page, int len, struct hlist_head *rx_list,
-			     struct net_device *dev)
+static void can_print_rcvlist(struct seq_file *m, struct hlist_head *rx_list,
+			      struct net_device *dev)
 {
 	struct receiver *r;
 	struct hlist_node *n;
@@ -208,199 +208,188 @@ static int can_print_rcvlist(char *page, int len, struct hlist_head *rx_list,
 			"   %-5s  %08X  %08x  %08x  %08x  %8ld  %s\n" :
 			"   %-5s     %03X    %08x  %08lx  %08lx  %8ld  %s\n";
 
-		len += snprintf(page + len, PAGE_SIZE - len, fmt,
-				DNAME(dev), r->can_id, r->mask,
+		seq_printf(m, fmt, DNAME(dev), r->can_id, r->mask,
 				(unsigned long)r->func, (unsigned long)r->data,
 				r->matches, r->ident);
-
-		/* does a typical line fit into the current buffer? */
-
-		/* 100 Bytes before end of buffer */
-		if (len > PAGE_SIZE - 100) {
-			/* mark output cut off */
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"   (..)\n");
-			break;
-		}
 	}
 	rcu_read_unlock();
-
-	return len;
 }
 
-static int can_print_recv_banner(char *page, int len)
+static void can_print_recv_banner(struct seq_file *m)
 {
 	/*
 	 *                  can1.  00000000  00000000  00000000
 	 *                 .......          0  tp20
 	 */
-	len += snprintf(page + len, PAGE_SIZE - len,
-			"  device   can_id   can_mask  function"
+	seq_puts(m, "  device   can_id   can_mask  function"
 			"  userdata   matches  ident\n");
-
-	return len;
 }
 
-static int can_proc_read_stats(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int can_stats_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
+	seq_putc(m, '\n');
+	seq_printf(m, " %8ld transmitted frames (TXF)\n", can_stats.tx_frames);
+	seq_printf(m, " %8ld received frames (RXF)\n", can_stats.rx_frames);
+	seq_printf(m, " %8ld matched frames (RXMF)\n", can_stats.matches);
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld transmitted frames (TXF)\n",
-			can_stats.tx_frames);
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld received frames (RXF)\n", can_stats.rx_frames);
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld matched frames (RXMF)\n", can_stats.matches);
-
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
+	seq_putc(m, '\n');
 
 	if (can_stattimer.function == can_stat_update) {
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld %% total match ratio (RXMR)\n",
+		seq_printf(m, " %8ld %% total match ratio (RXMR)\n",
 				can_stats.total_rx_match_ratio);
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s total tx rate (TXR)\n",
+		seq_printf(m, " %8ld frames/s total tx rate (TXR)\n",
 				can_stats.total_tx_rate);
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s total rx rate (RXR)\n",
+		seq_printf(m, " %8ld frames/s total rx rate (RXR)\n",
 				can_stats.total_rx_rate);
 
-		len += snprintf(page + len, PAGE_SIZE - len, "\n");
+		seq_putc(m, '\n');
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld %% current match ratio (CRXMR)\n",
+		seq_printf(m, " %8ld %% current match ratio (CRXMR)\n",
 				can_stats.current_rx_match_ratio);
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s current tx rate (CTXR)\n",
+		seq_printf(m, " %8ld frames/s current tx rate (CTXR)\n",
 				can_stats.current_tx_rate);
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s current rx rate (CRXR)\n",
+		seq_printf(m, " %8ld frames/s current rx rate (CRXR)\n",
 				can_stats.current_rx_rate);
 
-		len += snprintf(page + len, PAGE_SIZE - len, "\n");
+		seq_putc(m, '\n');
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld %% max match ratio (MRXMR)\n",
+		seq_printf(m, " %8ld %% max match ratio (MRXMR)\n",
 				can_stats.max_rx_match_ratio);
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s max tx rate (MTXR)\n",
+		seq_printf(m, " %8ld frames/s max tx rate (MTXR)\n",
 				can_stats.max_tx_rate);
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld frames/s max rx rate (MRXR)\n",
+		seq_printf(m, " %8ld frames/s max rx rate (MRXR)\n",
 				can_stats.max_rx_rate);
 
-		len += snprintf(page + len, PAGE_SIZE - len, "\n");
+		seq_putc(m, '\n');
 	}
 
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld current receive list entries (CRCV)\n",
+	seq_printf(m, " %8ld current receive list entries (CRCV)\n",
 			can_pstats.rcv_entries);
-	len += snprintf(page + len, PAGE_SIZE - len,
-			" %8ld maximum receive list entries (MRCV)\n",
+	seq_printf(m, " %8ld maximum receive list entries (MRCV)\n",
 			can_pstats.rcv_entries_max);
 
 	if (can_pstats.stats_reset)
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"\n %8ld statistic resets (STR)\n",
+		seq_printf(m, "\n %8ld statistic resets (STR)\n",
 				can_pstats.stats_reset);
 
 	if (can_pstats.user_reset)
-		len += snprintf(page + len, PAGE_SIZE - len,
-				" %8ld user statistic resets (USTR)\n",
+		seq_printf(m, " %8ld user statistic resets (USTR)\n",
 				can_pstats.user_reset);
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
-
-	*eof = 1;
-	return len;
+	seq_putc(m, '\n');
+	return 0;
 }
 
-static int can_proc_read_reset_stats(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static int can_stats_proc_open(struct inode *inode, struct file *file)
 {
-	int len = 0;
+	return single_open(file, can_stats_proc_show, NULL);
+}
+
+static const struct file_operations can_stats_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_stats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
+static int can_reset_stats_proc_show(struct seq_file *m, void *v)
+{
 	user_reset = 1;
 
 	if (can_stattimer.function == can_stat_update) {
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"Scheduled statistic reset #%ld.\n",
+		seq_printf(m, "Scheduled statistic reset #%ld.\n",
 				can_pstats.stats_reset + 1);
 
 	} else {
 		if (can_stats.jiffies_init != jiffies)
 			can_init_stats();
 
-		len += snprintf(page + len, PAGE_SIZE - len,
-				"Performed statistic reset #%ld.\n",
+		seq_printf(m, "Performed statistic reset #%ld.\n",
 				can_pstats.stats_reset);
 	}
+	return 0;
+}
 
-	*eof = 1;
-	return len;
+static int can_reset_stats_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_reset_stats_proc_show, NULL);
 }
 
-static int can_proc_read_version(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static const struct file_operations can_reset_stats_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_reset_stats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int can_version_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
+	seq_printf(m, "%s\n", CAN_VERSION_STRING);
+	return 0;
+}
 
-	len += snprintf(page + len, PAGE_SIZE - len, "%s\n",
-			CAN_VERSION_STRING);
-	*eof = 1;
-	return len;
+static int can_version_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_version_proc_show, NULL);
 }
 
-static int can_proc_read_rcvlist(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
+static const struct file_operations can_version_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_version_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int can_rcvlist_proc_show(struct seq_file *m, void *v)
 {
 	/* double cast to prevent GCC warning */
-	int idx = (int)(long)data;
-	int len = 0;
+	int idx = (int)(long)m->private;
 	struct dev_rcv_lists *d;
 	struct hlist_node *n;
 
-	len += snprintf(page + len, PAGE_SIZE - len,
-			"\nreceive list '%s':\n", rx_list_name[idx]);
+	seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]);
 
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) {
 
 		if (!hlist_empty(&d->rx[idx])) {
-			len = can_print_recv_banner(page, len);
-			len = can_print_rcvlist(page, len, &d->rx[idx], d->dev);
+			can_print_recv_banner(m);
+			can_print_rcvlist(m, &d->rx[idx], d->dev);
 		} else
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"  (%s: no entry)\n", DNAME(d->dev));
-
-		/* exit on end of buffer? */
-		if (len > PAGE_SIZE - 100)
-			break;
+			seq_printf(m, "  (%s: no entry)\n", DNAME(d->dev));
 	}
 	rcu_read_unlock();
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
+	seq_putc(m, '\n');
+	return 0;
+}
 
-	*eof = 1;
-	return len;
+static int can_rcvlist_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_rcvlist_proc_show, PDE(inode)->data);
 }
 
-static int can_proc_read_rcvlist_sff(char *page, char **start, off_t off,
-				     int count, int *eof, void *data)
+static const struct file_operations can_rcvlist_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_rcvlist_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
 	struct dev_rcv_lists *d;
 	struct hlist_node *n;
 
 	/* RX_SFF */
-	len += snprintf(page + len, PAGE_SIZE - len,
-			"\nreceive list 'rx_sff':\n");
+	seq_puts(m, "\nreceive list 'rx_sff':\n");
 
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) {
@@ -413,46 +402,38 @@ static int can_proc_read_rcvlist_sff(char *page, char **start, off_t off,
 			}
 
 		if (!all_empty) {
-			len = can_print_recv_banner(page, len);
+			can_print_recv_banner(m);
 			for (i = 0; i < 0x800; i++) {
-				if (!hlist_empty(&d->rx_sff[i]) &&
-				    len < PAGE_SIZE - 100)
-					len = can_print_rcvlist(page, len,
-								&d->rx_sff[i],
-								d->dev);
+				if (!hlist_empty(&d->rx_sff[i]))
+					can_print_rcvlist(m, &d->rx_sff[i],
+							  d->dev);
 			}
 		} else
-			len += snprintf(page + len, PAGE_SIZE - len,
-					"  (%s: no entry)\n", DNAME(d->dev));
-
-		/* exit on end of buffer? */
-		if (len > PAGE_SIZE - 100)
-			break;
+			seq_printf(m, "  (%s: no entry)\n", DNAME(d->dev));
 	}
 	rcu_read_unlock();
 
-	len += snprintf(page + len, PAGE_SIZE - len, "\n");
+	seq_putc(m, '\n');
+	return 0;
+}
 
-	*eof = 1;
-	return len;
+static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, can_rcvlist_sff_proc_show, NULL);
 }
 
+static const struct file_operations can_rcvlist_sff_proc_fops = {
+	.owner		= THIS_MODULE,
+	.open		= can_rcvlist_sff_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * proc utility functions
  */
 
-static struct proc_dir_entry *can_create_proc_readentry(const char *name,
-							mode_t mode,
-							read_proc_t *read_proc,
-							void *data)
-{
-	if (can_dir)
-		return create_proc_read_entry(name, mode, can_dir, read_proc,
-					      data);
-	else
-		return NULL;
-}
-
 static void can_remove_proc_readentry(const char *name)
 {
 	if (can_dir)
@@ -474,24 +455,24 @@ void can_init_proc(void)
 	}
 
 	/* own procfs entries from the AF_CAN core */
-	pde_version     = can_create_proc_readentry(CAN_PROC_VERSION, 0644,
-					can_proc_read_version, NULL);
-	pde_stats       = can_create_proc_readentry(CAN_PROC_STATS, 0644,
-					can_proc_read_stats, NULL);
-	pde_reset_stats = can_create_proc_readentry(CAN_PROC_RESET_STATS, 0644,
-					can_proc_read_reset_stats, NULL);
-	pde_rcvlist_err = can_create_proc_readentry(CAN_PROC_RCVLIST_ERR, 0644,
-					can_proc_read_rcvlist, (void *)RX_ERR);
-	pde_rcvlist_all = can_create_proc_readentry(CAN_PROC_RCVLIST_ALL, 0644,
-					can_proc_read_rcvlist, (void *)RX_ALL);
-	pde_rcvlist_fil = can_create_proc_readentry(CAN_PROC_RCVLIST_FIL, 0644,
-					can_proc_read_rcvlist, (void *)RX_FIL);
-	pde_rcvlist_inv = can_create_proc_readentry(CAN_PROC_RCVLIST_INV, 0644,
-					can_proc_read_rcvlist, (void *)RX_INV);
-	pde_rcvlist_eff = can_create_proc_readentry(CAN_PROC_RCVLIST_EFF, 0644,
-					can_proc_read_rcvlist, (void *)RX_EFF);
-	pde_rcvlist_sff = can_create_proc_readentry(CAN_PROC_RCVLIST_SFF, 0644,
-					can_proc_read_rcvlist_sff, NULL);
+	pde_version     = proc_create(CAN_PROC_VERSION, 0644, can_dir,
+				      &can_version_proc_fops);
+	pde_stats       = proc_create(CAN_PROC_STATS, 0644, can_dir,
+				      &can_stats_proc_fops);
+	pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644, can_dir,
+				      &can_reset_stats_proc_fops);
+	pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_ERR);
+	pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_ALL);
+	pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_FIL);
+	pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_INV);
+	pde_rcvlist_eff = proc_create_data(CAN_PROC_RCVLIST_EFF, 0644, can_dir,
+					   &can_rcvlist_proc_fops, (void *)RX_EFF);
+	pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644, can_dir,
+				      &can_rcvlist_sff_proc_fops);
 }
 
 /*
diff --git a/net/compat.c b/net/compat.c
index 8d73905..12728b1 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -743,6 +743,18 @@ asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, uns
 	return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
 }
 
+asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned flags)
+{
+	return sys_recv(fd, buf, len, flags | MSG_CMSG_COMPAT);
+}
+
+asmlinkage long compat_sys_recvfrom(int fd, void __user *buf, size_t len,
+				    unsigned flags, struct sockaddr __user *addr,
+				    int __user *addrlen)
+{
+	return sys_recvfrom(fd, buf, len, flags | MSG_CMSG_COMPAT, addr, addrlen);
+}
+
 asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
 {
 	int ret;
@@ -788,10 +800,11 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
 		ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]);
 		break;
 	case SYS_RECV:
-		ret = sys_recv(a0, compat_ptr(a1), a[2], a[3]);
+		ret = compat_sys_recv(a0, compat_ptr(a1), a[2], a[3]);
 		break;
 	case SYS_RECVFROM:
-		ret = sys_recvfrom(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), compat_ptr(a[5]));
+		ret = compat_sys_recvfrom(a0, compat_ptr(a1), a[2], a[3],
+					  compat_ptr(a[4]), compat_ptr(a[5]));
 		break;
 	case SYS_SHUTDOWN:
 		ret = sys_shutdown(a0,a1);
diff --git a/net/core/datagram.c b/net/core/datagram.c
index b0fe692..1c6cf3a 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -55,6 +55,7 @@
 #include <net/checksum.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
+#include <trace/events/skb.h>
 
 /*
  *	Is a socket 'connection oriented' ?
@@ -284,6 +285,8 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
 	int i, copy = start - offset;
 	struct sk_buff *frag_iter;
 
+	trace_skb_copy_datagram_iovec(skb, len);
+
 	/* Copy header. */
 	if (copy > 0) {
 		if (copy > len)
diff --git a/net/core/dev.c b/net/core/dev.c
index 278d489..560c8c9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -191,7 +191,6 @@ static struct list_head ptype_all __read_mostly;	/* Taps */
  * semaphore held.
  */
 DEFINE_RWLOCK(dev_base_lock);
-
 EXPORT_SYMBOL(dev_base_lock);
 
 #define NETDEV_HASHBITS	8
@@ -248,6 +247,7 @@ static RAW_NOTIFIER_HEAD(netdev_chain);
  */
 
 DEFINE_PER_CPU(struct softnet_data, softnet_data);
+EXPORT_PER_CPU_SYMBOL(softnet_data);
 
 #ifdef CONFIG_LOCKDEP
 /*
@@ -269,10 +269,10 @@ static const unsigned short netdev_lock_type[] =
 	 ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL,
 	 ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211,
 	 ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET,
-	 ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY,
+	 ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154,
 	 ARPHRD_VOID, ARPHRD_NONE};
 
-static const char *netdev_lock_name[] =
+static const char *const netdev_lock_name[] =
 	{"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25",
 	 "_xmit_PRONET", "_xmit_CHAOS", "_xmit_IEEE802", "_xmit_ARCNET",
 	 "_xmit_APPLETLK", "_xmit_DLCI", "_xmit_ATM", "_xmit_METRICOM",
@@ -287,7 +287,7 @@ static const char *netdev_lock_name[] =
 	 "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL",
 	 "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211",
 	 "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET",
-	 "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY",
+	 "_xmit_PHONET_PIPE", "_xmit_IEEE802154",
 	 "_xmit_VOID", "_xmit_NONE"};
 
 static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)];
@@ -381,6 +381,7 @@ void dev_add_pack(struct packet_type *pt)
 	}
 	spin_unlock_bh(&ptype_lock);
 }
+EXPORT_SYMBOL(dev_add_pack);
 
 /**
  *	__dev_remove_pack	 - remove packet handler
@@ -418,6 +419,8 @@ void __dev_remove_pack(struct packet_type *pt)
 out:
 	spin_unlock_bh(&ptype_lock);
 }
+EXPORT_SYMBOL(__dev_remove_pack);
+
 /**
  *	dev_remove_pack	 - remove packet handler
  *	@pt: packet type declaration
@@ -436,6 +439,7 @@ void dev_remove_pack(struct packet_type *pt)
 
 	synchronize_net();
 }
+EXPORT_SYMBOL(dev_remove_pack);
 
 /******************************************************************************
 
@@ -499,6 +503,7 @@ int netdev_boot_setup_check(struct net_device *dev)
 	}
 	return 0;
 }
+EXPORT_SYMBOL(netdev_boot_setup_check);
 
 
 /**
@@ -591,6 +596,7 @@ struct net_device *__dev_get_by_name(struct net *net, const char *name)
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(__dev_get_by_name);
 
 /**
  *	dev_get_by_name		- find a device by its name
@@ -615,6 +621,7 @@ struct net_device *dev_get_by_name(struct net *net, const char *name)
 	read_unlock(&dev_base_lock);
 	return dev;
 }
+EXPORT_SYMBOL(dev_get_by_name);
 
 /**
  *	__dev_get_by_index - find a device by its ifindex
@@ -640,6 +647,7 @@ struct net_device *__dev_get_by_index(struct net *net, int ifindex)
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(__dev_get_by_index);
 
 
 /**
@@ -664,6 +672,7 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex)
 	read_unlock(&dev_base_lock);
 	return dev;
 }
+EXPORT_SYMBOL(dev_get_by_index);
 
 /**
  *	dev_getbyhwaddr - find a device by its hardware address
@@ -693,7 +702,6 @@ struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *h
 
 	return NULL;
 }
-
 EXPORT_SYMBOL(dev_getbyhwaddr);
 
 struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
@@ -707,7 +715,6 @@ struct net_device *__dev_getfirstbyhwtype(struct net *net, unsigned short type)
 
 	return NULL;
 }
-
 EXPORT_SYMBOL(__dev_getfirstbyhwtype);
 
 struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
@@ -721,7 +728,6 @@ struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
 	rtnl_unlock();
 	return dev;
 }
-
 EXPORT_SYMBOL(dev_getfirstbyhwtype);
 
 /**
@@ -736,7 +742,8 @@ EXPORT_SYMBOL(dev_getfirstbyhwtype);
  *	dev_put to indicate they have finished with it.
  */
 
-struct net_device * dev_get_by_flags(struct net *net, unsigned short if_flags, unsigned short mask)
+struct net_device *dev_get_by_flags(struct net *net, unsigned short if_flags,
+				    unsigned short mask)
 {
 	struct net_device *dev, *ret;
 
@@ -752,6 +759,7 @@ struct net_device * dev_get_by_flags(struct net *net, unsigned short if_flags, u
 	read_unlock(&dev_base_lock);
 	return ret;
 }
+EXPORT_SYMBOL(dev_get_by_flags);
 
 /**
  *	dev_valid_name - check if name is okay for network device
@@ -777,6 +785,7 @@ int dev_valid_name(const char *name)
 	}
 	return 1;
 }
+EXPORT_SYMBOL(dev_valid_name);
 
 /**
  *	__dev_alloc_name - allocate a name for a device
@@ -870,6 +879,7 @@ int dev_alloc_name(struct net_device *dev, const char *name)
 		strlcpy(dev->name, buf, IFNAMSIZ);
 	return ret;
 }
+EXPORT_SYMBOL(dev_alloc_name);
 
 
 /**
@@ -906,8 +916,7 @@ int dev_change_name(struct net_device *dev, const char *newname)
 		err = dev_alloc_name(dev, newname);
 		if (err < 0)
 			return err;
-	}
-	else if (__dev_get_by_name(net, newname))
+	} else if (__dev_get_by_name(net, newname))
 		return -EEXIST;
 	else
 		strlcpy(dev->name, newname, IFNAMSIZ);
@@ -970,7 +979,7 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
 		return 0;
 	}
 
-	dev->ifalias = krealloc(dev->ifalias, len+1, GFP_KERNEL);
+	dev->ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL);
 	if (!dev->ifalias)
 		return -ENOMEM;
 
@@ -1006,10 +1015,11 @@ void netdev_state_change(struct net_device *dev)
 		rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
 	}
 }
+EXPORT_SYMBOL(netdev_state_change);
 
-void netdev_bonding_change(struct net_device *dev)
+void netdev_bonding_change(struct net_device *dev, unsigned long event)
 {
-	call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, dev);
+	call_netdevice_notifiers(event, dev);
 }
 EXPORT_SYMBOL(netdev_bonding_change);
 
@@ -1034,6 +1044,7 @@ void dev_load(struct net *net, const char *name)
 	if (!dev && capable(CAP_NET_ADMIN))
 		request_module("%s", name);
 }
+EXPORT_SYMBOL(dev_load);
 
 /**
  *	dev_open	- prepare an interface for use.
@@ -1118,6 +1129,7 @@ int dev_open(struct net_device *dev)
 
 	return ret;
 }
+EXPORT_SYMBOL(dev_open);
 
 /**
  *	dev_close - shutdown an interface.
@@ -1184,6 +1196,7 @@ int dev_close(struct net_device *dev)
 
 	return 0;
 }
+EXPORT_SYMBOL(dev_close);
 
 
 /**
@@ -1279,6 +1292,7 @@ rollback:
 	raw_notifier_chain_unregister(&netdev_chain, nb);
 	goto unlock;
 }
+EXPORT_SYMBOL(register_netdevice_notifier);
 
 /**
  *	unregister_netdevice_notifier - unregister a network notifier block
@@ -1299,6 +1313,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
 	rtnl_unlock();
 	return err;
 }
+EXPORT_SYMBOL(unregister_netdevice_notifier);
 
 /**
  *	call_netdevice_notifiers - call all network notifier blocks
@@ -1321,11 +1336,13 @@ void net_enable_timestamp(void)
 {
 	atomic_inc(&netstamp_needed);
 }
+EXPORT_SYMBOL(net_enable_timestamp);
 
 void net_disable_timestamp(void)
 {
 	atomic_dec(&netstamp_needed);
 }
+EXPORT_SYMBOL(net_disable_timestamp);
 
 static inline void net_timestamp(struct sk_buff *skb)
 {
@@ -1359,7 +1376,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 		if ((ptype->dev == dev || !ptype->dev) &&
 		    (ptype->af_packet_priv == NULL ||
 		     (struct sock *)ptype->af_packet_priv != skb->sk)) {
-			struct sk_buff *skb2= skb_clone(skb, GFP_ATOMIC);
+			struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 			if (!skb2)
 				break;
 
@@ -1527,6 +1544,7 @@ out_set_summed:
 out:
 	return ret;
 }
+EXPORT_SYMBOL(skb_checksum_help);
 
 /**
  *	skb_gso_segment - Perform segmentation on skb.
@@ -1589,7 +1607,6 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
 
 	return segs;
 }
-
 EXPORT_SYMBOL(skb_gso_segment);
 
 /* Take action when hardware reception checksum errors are detected. */
@@ -1704,7 +1721,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
 			skb_dst_drop(skb);
 
 		rc = ops->ndo_start_xmit(skb, dev);
-		if (rc == 0)
+		if (rc == NETDEV_TX_OK)
 			txq_trans_update(txq);
 		/*
 		 * TODO: if skb_orphan() was called by
@@ -1730,7 +1747,7 @@ gso:
 		skb->next = nskb->next;
 		nskb->next = NULL;
 		rc = ops->ndo_start_xmit(nskb, dev);
-		if (unlikely(rc)) {
+		if (unlikely(rc != NETDEV_TX_OK)) {
 			nskb->next = skb->next;
 			skb->next = nskb;
 			return rc;
@@ -1744,7 +1761,7 @@ gso:
 
 out_kfree_skb:
 	kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static u32 skb_tx_hashrnd;
@@ -1755,7 +1772,7 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
 
 	if (skb_rx_queue_recorded(skb)) {
 		hash = skb_get_rx_queue(skb);
-		while (unlikely (hash >= dev->real_num_tx_queues))
+		while (unlikely(hash >= dev->real_num_tx_queues))
 			hash -= dev->real_num_tx_queues;
 		return hash;
 	}
@@ -1786,6 +1803,40 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
 	return netdev_get_tx_queue(dev, queue_index);
 }
 
+static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
+				 struct net_device *dev,
+				 struct netdev_queue *txq)
+{
+	spinlock_t *root_lock = qdisc_lock(q);
+	int rc;
+
+	spin_lock(root_lock);
+	if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
+		kfree_skb(skb);
+		rc = NET_XMIT_DROP;
+	} else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
+		   !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) {
+		/*
+		 * This is a work-conserving queue; there are no old skbs
+		 * waiting to be sent out; and the qdisc is not running -
+		 * xmit the skb directly.
+		 */
+		__qdisc_update_bstats(q, skb->len);
+		if (sch_direct_xmit(skb, q, dev, txq, root_lock))
+			__qdisc_run(q);
+		else
+			clear_bit(__QDISC_STATE_RUNNING, &q->state);
+
+		rc = NET_XMIT_SUCCESS;
+	} else {
+		rc = qdisc_enqueue_root(skb, q);
+		qdisc_run(q);
+	}
+	spin_unlock(root_lock);
+
+	return rc;
+}
+
 /**
  *	dev_queue_xmit - transmit a buffer
  *	@skb: buffer to transmit
@@ -1856,22 +1907,10 @@ gso:
 	q = rcu_dereference(txq->qdisc);
 
 #ifdef CONFIG_NET_CLS_ACT
-	skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
+	skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_EGRESS);
 #endif
 	if (q->enqueue) {
-		spinlock_t *root_lock = qdisc_lock(q);
-
-		spin_lock(root_lock);
-
-		if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
-			kfree_skb(skb);
-			rc = NET_XMIT_DROP;
-		} else {
-			rc = qdisc_enqueue_root(skb, q);
-			qdisc_run(q);
-		}
-		spin_unlock(root_lock);
-
+		rc = __dev_xmit_skb(skb, q, dev, txq);
 		goto out;
 	}
 
@@ -1895,7 +1934,7 @@ gso:
 			HARD_TX_LOCK(dev, txq, cpu);
 
 			if (!netif_tx_queue_stopped(txq)) {
-				rc = 0;
+				rc = NET_XMIT_SUCCESS;
 				if (!dev_hard_start_xmit(skb, dev, txq)) {
 					HARD_TX_UNLOCK(dev, txq);
 					goto out;
@@ -1924,6 +1963,7 @@ out:
 	rcu_read_unlock_bh();
 	return rc;
 }
+EXPORT_SYMBOL(dev_queue_xmit);
 
 
 /*=======================================================================
@@ -1990,6 +2030,7 @@ enqueue:
 	kfree_skb(skb);
 	return NET_RX_DROP;
 }
+EXPORT_SYMBOL(netif_rx);
 
 int netif_rx_ni(struct sk_buff *skb)
 {
@@ -2003,7 +2044,6 @@ int netif_rx_ni(struct sk_buff *skb)
 
 	return err;
 }
-
 EXPORT_SYMBOL(netif_rx_ni);
 
 static void net_tx_action(struct softirq_action *h)
@@ -2076,7 +2116,7 @@ static inline int deliver_skb(struct sk_buff *skb,
 /* This hook is defined here for ATM LANE */
 int (*br_fdb_test_addr_hook)(struct net_device *dev,
 			     unsigned char *addr) __read_mostly;
-EXPORT_SYMBOL(br_fdb_test_addr_hook);
+EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
 #endif
 
 /*
@@ -2085,7 +2125,7 @@ EXPORT_SYMBOL(br_fdb_test_addr_hook);
  */
 struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
 					struct sk_buff *skb) __read_mostly;
-EXPORT_SYMBOL(br_handle_frame_hook);
+EXPORT_SYMBOL_GPL(br_handle_frame_hook);
 
 static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
 					    struct packet_type **pt_prev, int *ret,
@@ -2336,6 +2376,7 @@ out:
 	rcu_read_unlock();
 	return ret;
 }
+EXPORT_SYMBOL(netif_receive_skb);
 
 /* Network device is going away, flush any packets still pending  */
 static void flush_backlog(void *arg)
@@ -2852,7 +2893,7 @@ softnet_break:
 	goto out;
 }
 
-static gifconf_func_t * gifconf_list [NPROTO];
+static gifconf_func_t *gifconf_list[NPROTO];
 
 /**
  *	register_gifconf	-	register a SIOCGIF handler
@@ -2863,13 +2904,14 @@ static gifconf_func_t * gifconf_list [NPROTO];
  *	that is passed must not be freed or reused until it has been replaced
  *	by another handler.
  */
-int register_gifconf(unsigned int family, gifconf_func_t * gifconf)
+int register_gifconf(unsigned int family, gifconf_func_t *gifconf)
 {
 	if (family >= NPROTO)
 		return -EINVAL;
 	gifconf_list[family] = gifconf;
 	return 0;
 }
+EXPORT_SYMBOL(register_gifconf);
 
 
 /*
@@ -3080,7 +3122,7 @@ static int softnet_seq_show(struct seq_file *seq, void *v)
 	seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
 		   s->total, s->dropped, s->time_squeeze, 0,
 		   0, 0, 0, 0, /* was fastroute */
-		   s->cpu_collision );
+		   s->cpu_collision);
 	return 0;
 }
 
@@ -3316,6 +3358,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
 	rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE);
 	return 0;
 }
+EXPORT_SYMBOL(netdev_set_master);
 
 static void dev_change_rx_flags(struct net_device *dev, int flags)
 {
@@ -3394,6 +3437,7 @@ int dev_set_promiscuity(struct net_device *dev, int inc)
 		dev_set_rx_mode(dev);
 	return err;
 }
+EXPORT_SYMBOL(dev_set_promiscuity);
 
 /**
  *	dev_set_allmulti	- update allmulti count on a device
@@ -3437,6 +3481,7 @@ int dev_set_allmulti(struct net_device *dev, int inc)
 	}
 	return 0;
 }
+EXPORT_SYMBOL(dev_set_allmulti);
 
 /*
  *	Upload unicast and multicast address lists to device and
@@ -3927,6 +3972,7 @@ int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
 	}
 	return err;
 }
+EXPORT_SYMBOL_GPL(__dev_addr_sync);
 
 void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
 		       struct dev_addr_list **from, int *from_count)
@@ -3946,6 +3992,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
 		da = next;
 	}
 }
+EXPORT_SYMBOL_GPL(__dev_addr_unsync);
 
 /**
  *	dev_unicast_sync - Synchronize device's unicast list to another device
@@ -4064,6 +4111,7 @@ unsigned dev_get_flags(const struct net_device *dev)
 
 	return flags;
 }
+EXPORT_SYMBOL(dev_get_flags);
 
 /**
  *	dev_change_flags - change device settings
@@ -4114,12 +4162,13 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
 	}
 
 	if (dev->flags & IFF_UP &&
-	    ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
+	    ((old_flags ^ dev->flags) & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
 					  IFF_VOLATILE)))
 		call_netdevice_notifiers(NETDEV_CHANGE, dev);
 
 	if ((flags ^ dev->gflags) & IFF_PROMISC) {
-		int inc = (flags & IFF_PROMISC) ? +1 : -1;
+		int inc = (flags & IFF_PROMISC) ? 1 : -1;
+
 		dev->gflags ^= IFF_PROMISC;
 		dev_set_promiscuity(dev, inc);
 	}
@@ -4129,7 +4178,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
 	   IFF_ALLMULTI is requested not asking us and not reporting.
 	 */
 	if ((flags ^ dev->gflags) & IFF_ALLMULTI) {
-		int inc = (flags & IFF_ALLMULTI) ? +1 : -1;
+		int inc = (flags & IFF_ALLMULTI) ? 1 : -1;
+
 		dev->gflags ^= IFF_ALLMULTI;
 		dev_set_allmulti(dev, inc);
 	}
@@ -4141,6 +4191,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
 
 	return ret;
 }
+EXPORT_SYMBOL(dev_change_flags);
 
 /**
  *	dev_set_mtu - Change maximum transfer unit
@@ -4174,6 +4225,7 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
 		call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
 	return err;
 }
+EXPORT_SYMBOL(dev_set_mtu);
 
 /**
  *	dev_set_mac_address - Change Media Access Control Address
@@ -4198,6 +4250,7 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
 		call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
 	return err;
 }
+EXPORT_SYMBOL(dev_set_mac_address);
 
 /*
  *	Perform the SIOCxIFxxx calls, inside read_lock(dev_base_lock)
@@ -4211,56 +4264,56 @@ static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cm
 		return -ENODEV;
 
 	switch (cmd) {
-		case SIOCGIFFLAGS:	/* Get interface flags */
-			ifr->ifr_flags = (short) dev_get_flags(dev);
-			return 0;
+	case SIOCGIFFLAGS:	/* Get interface flags */
+		ifr->ifr_flags = (short) dev_get_flags(dev);
+		return 0;
 
-		case SIOCGIFMETRIC:	/* Get the metric on the interface
-					   (currently unused) */
-			ifr->ifr_metric = 0;
-			return 0;
+	case SIOCGIFMETRIC:	/* Get the metric on the interface
+				   (currently unused) */
+		ifr->ifr_metric = 0;
+		return 0;
 
-		case SIOCGIFMTU:	/* Get the MTU of a device */
-			ifr->ifr_mtu = dev->mtu;
-			return 0;
+	case SIOCGIFMTU:	/* Get the MTU of a device */
+		ifr->ifr_mtu = dev->mtu;
+		return 0;
 
-		case SIOCGIFHWADDR:
-			if (!dev->addr_len)
-				memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data);
-			else
-				memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
-				       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-			ifr->ifr_hwaddr.sa_family = dev->type;
-			return 0;
+	case SIOCGIFHWADDR:
+		if (!dev->addr_len)
+			memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data);
+		else
+			memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
+			       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
+		ifr->ifr_hwaddr.sa_family = dev->type;
+		return 0;
 
-		case SIOCGIFSLAVE:
-			err = -EINVAL;
-			break;
+	case SIOCGIFSLAVE:
+		err = -EINVAL;
+		break;
 
-		case SIOCGIFMAP:
-			ifr->ifr_map.mem_start = dev->mem_start;
-			ifr->ifr_map.mem_end   = dev->mem_end;
-			ifr->ifr_map.base_addr = dev->base_addr;
-			ifr->ifr_map.irq       = dev->irq;
-			ifr->ifr_map.dma       = dev->dma;
-			ifr->ifr_map.port      = dev->if_port;
-			return 0;
+	case SIOCGIFMAP:
+		ifr->ifr_map.mem_start = dev->mem_start;
+		ifr->ifr_map.mem_end   = dev->mem_end;
+		ifr->ifr_map.base_addr = dev->base_addr;
+		ifr->ifr_map.irq       = dev->irq;
+		ifr->ifr_map.dma       = dev->dma;
+		ifr->ifr_map.port      = dev->if_port;
+		return 0;
 
-		case SIOCGIFINDEX:
-			ifr->ifr_ifindex = dev->ifindex;
-			return 0;
+	case SIOCGIFINDEX:
+		ifr->ifr_ifindex = dev->ifindex;
+		return 0;
 
-		case SIOCGIFTXQLEN:
-			ifr->ifr_qlen = dev->tx_queue_len;
-			return 0;
+	case SIOCGIFTXQLEN:
+		ifr->ifr_qlen = dev->tx_queue_len;
+		return 0;
 
-		default:
-			/* dev_ioctl() should ensure this case
-			 * is never reached
-			 */
-			WARN_ON(1);
-			err = -EINVAL;
-			break;
+	default:
+		/* dev_ioctl() should ensure this case
+		 * is never reached
+		 */
+		WARN_ON(1);
+		err = -EINVAL;
+		break;
 
 	}
 	return err;
@@ -4281,92 +4334,91 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
 	ops = dev->netdev_ops;
 
 	switch (cmd) {
-		case SIOCSIFFLAGS:	/* Set interface flags */
-			return dev_change_flags(dev, ifr->ifr_flags);
-
-		case SIOCSIFMETRIC:	/* Set the metric on the interface
-					   (currently unused) */
-			return -EOPNOTSUPP;
+	case SIOCSIFFLAGS:	/* Set interface flags */
+		return dev_change_flags(dev, ifr->ifr_flags);
 
-		case SIOCSIFMTU:	/* Set the MTU of a device */
-			return dev_set_mtu(dev, ifr->ifr_mtu);
+	case SIOCSIFMETRIC:	/* Set the metric on the interface
+				   (currently unused) */
+		return -EOPNOTSUPP;
 
-		case SIOCSIFHWADDR:
-			return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
+	case SIOCSIFMTU:	/* Set the MTU of a device */
+		return dev_set_mtu(dev, ifr->ifr_mtu);
 
-		case SIOCSIFHWBROADCAST:
-			if (ifr->ifr_hwaddr.sa_family != dev->type)
-				return -EINVAL;
-			memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
-			       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-			call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
-			return 0;
+	case SIOCSIFHWADDR:
+		return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
 
-		case SIOCSIFMAP:
-			if (ops->ndo_set_config) {
-				if (!netif_device_present(dev))
-					return -ENODEV;
-				return ops->ndo_set_config(dev, &ifr->ifr_map);
-			}
-			return -EOPNOTSUPP;
-
-		case SIOCADDMULTI:
-			if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
-			    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
-				return -EINVAL;
-			if (!netif_device_present(dev))
-				return -ENODEV;
-			return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data,
-					  dev->addr_len, 1);
+	case SIOCSIFHWBROADCAST:
+		if (ifr->ifr_hwaddr.sa_family != dev->type)
+			return -EINVAL;
+		memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
+		       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
+		call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+		return 0;
 
-		case SIOCDELMULTI:
-			if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
-			    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
-				return -EINVAL;
+	case SIOCSIFMAP:
+		if (ops->ndo_set_config) {
 			if (!netif_device_present(dev))
 				return -ENODEV;
-			return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data,
-					     dev->addr_len, 1);
+			return ops->ndo_set_config(dev, &ifr->ifr_map);
+		}
+		return -EOPNOTSUPP;
 
-		case SIOCSIFTXQLEN:
-			if (ifr->ifr_qlen < 0)
-				return -EINVAL;
-			dev->tx_queue_len = ifr->ifr_qlen;
-			return 0;
+	case SIOCADDMULTI:
+		if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
+		    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
+			return -EINVAL;
+		if (!netif_device_present(dev))
+			return -ENODEV;
+		return dev_mc_add(dev, ifr->ifr_hwaddr.sa_data,
+				  dev->addr_len, 1);
+
+	case SIOCDELMULTI:
+		if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
+		    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
+			return -EINVAL;
+		if (!netif_device_present(dev))
+			return -ENODEV;
+		return dev_mc_delete(dev, ifr->ifr_hwaddr.sa_data,
+				     dev->addr_len, 1);
 
-		case SIOCSIFNAME:
-			ifr->ifr_newname[IFNAMSIZ-1] = '\0';
-			return dev_change_name(dev, ifr->ifr_newname);
+	case SIOCSIFTXQLEN:
+		if (ifr->ifr_qlen < 0)
+			return -EINVAL;
+		dev->tx_queue_len = ifr->ifr_qlen;
+		return 0;
 
-		/*
-		 *	Unknown or private ioctl
-		 */
+	case SIOCSIFNAME:
+		ifr->ifr_newname[IFNAMSIZ-1] = '\0';
+		return dev_change_name(dev, ifr->ifr_newname);
 
-		default:
-			if ((cmd >= SIOCDEVPRIVATE &&
-			    cmd <= SIOCDEVPRIVATE + 15) ||
-			    cmd == SIOCBONDENSLAVE ||
-			    cmd == SIOCBONDRELEASE ||
-			    cmd == SIOCBONDSETHWADDR ||
-			    cmd == SIOCBONDSLAVEINFOQUERY ||
-			    cmd == SIOCBONDINFOQUERY ||
-			    cmd == SIOCBONDCHANGEACTIVE ||
-			    cmd == SIOCGMIIPHY ||
-			    cmd == SIOCGMIIREG ||
-			    cmd == SIOCSMIIREG ||
-			    cmd == SIOCBRADDIF ||
-			    cmd == SIOCBRDELIF ||
-			    cmd == SIOCSHWTSTAMP ||
-			    cmd == SIOCWANDEV) {
-				err = -EOPNOTSUPP;
-				if (ops->ndo_do_ioctl) {
-					if (netif_device_present(dev))
-						err = ops->ndo_do_ioctl(dev, ifr, cmd);
-					else
-						err = -ENODEV;
-				}
-			} else
-				err = -EINVAL;
+	/*
+	 *	Unknown or private ioctl
+	 */
+	default:
+		if ((cmd >= SIOCDEVPRIVATE &&
+		    cmd <= SIOCDEVPRIVATE + 15) ||
+		    cmd == SIOCBONDENSLAVE ||
+		    cmd == SIOCBONDRELEASE ||
+		    cmd == SIOCBONDSETHWADDR ||
+		    cmd == SIOCBONDSLAVEINFOQUERY ||
+		    cmd == SIOCBONDINFOQUERY ||
+		    cmd == SIOCBONDCHANGEACTIVE ||
+		    cmd == SIOCGMIIPHY ||
+		    cmd == SIOCGMIIREG ||
+		    cmd == SIOCSMIIREG ||
+		    cmd == SIOCBRADDIF ||
+		    cmd == SIOCBRDELIF ||
+		    cmd == SIOCSHWTSTAMP ||
+		    cmd == SIOCWANDEV) {
+			err = -EOPNOTSUPP;
+			if (ops->ndo_do_ioctl) {
+				if (netif_device_present(dev))
+					err = ops->ndo_do_ioctl(dev, ifr, cmd);
+				else
+					err = -ENODEV;
+			}
+		} else
+			err = -EINVAL;
 
 	}
 	return err;
@@ -4423,135 +4475,135 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 	 */
 
 	switch (cmd) {
-		/*
-		 *	These ioctl calls:
-		 *	- can be done by all.
-		 *	- atomic and do not require locking.
-		 *	- return a value
-		 */
-		case SIOCGIFFLAGS:
-		case SIOCGIFMETRIC:
-		case SIOCGIFMTU:
-		case SIOCGIFHWADDR:
-		case SIOCGIFSLAVE:
-		case SIOCGIFMAP:
-		case SIOCGIFINDEX:
-		case SIOCGIFTXQLEN:
-			dev_load(net, ifr.ifr_name);
-			read_lock(&dev_base_lock);
-			ret = dev_ifsioc_locked(net, &ifr, cmd);
-			read_unlock(&dev_base_lock);
-			if (!ret) {
-				if (colon)
-					*colon = ':';
-				if (copy_to_user(arg, &ifr,
-						 sizeof(struct ifreq)))
-					ret = -EFAULT;
-			}
-			return ret;
+	/*
+	 *	These ioctl calls:
+	 *	- can be done by all.
+	 *	- atomic and do not require locking.
+	 *	- return a value
+	 */
+	case SIOCGIFFLAGS:
+	case SIOCGIFMETRIC:
+	case SIOCGIFMTU:
+	case SIOCGIFHWADDR:
+	case SIOCGIFSLAVE:
+	case SIOCGIFMAP:
+	case SIOCGIFINDEX:
+	case SIOCGIFTXQLEN:
+		dev_load(net, ifr.ifr_name);
+		read_lock(&dev_base_lock);
+		ret = dev_ifsioc_locked(net, &ifr, cmd);
+		read_unlock(&dev_base_lock);
+		if (!ret) {
+			if (colon)
+				*colon = ':';
+			if (copy_to_user(arg, &ifr,
+					 sizeof(struct ifreq)))
+				ret = -EFAULT;
+		}
+		return ret;
 
-		case SIOCETHTOOL:
-			dev_load(net, ifr.ifr_name);
-			rtnl_lock();
-			ret = dev_ethtool(net, &ifr);
-			rtnl_unlock();
-			if (!ret) {
-				if (colon)
-					*colon = ':';
-				if (copy_to_user(arg, &ifr,
-						 sizeof(struct ifreq)))
-					ret = -EFAULT;
-			}
-			return ret;
+	case SIOCETHTOOL:
+		dev_load(net, ifr.ifr_name);
+		rtnl_lock();
+		ret = dev_ethtool(net, &ifr);
+		rtnl_unlock();
+		if (!ret) {
+			if (colon)
+				*colon = ':';
+			if (copy_to_user(arg, &ifr,
+					 sizeof(struct ifreq)))
+				ret = -EFAULT;
+		}
+		return ret;
 
-		/*
-		 *	These ioctl calls:
-		 *	- require superuser power.
-		 *	- require strict serialization.
-		 *	- return a value
-		 */
-		case SIOCGMIIPHY:
-		case SIOCGMIIREG:
-		case SIOCSIFNAME:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-			dev_load(net, ifr.ifr_name);
-			rtnl_lock();
-			ret = dev_ifsioc(net, &ifr, cmd);
-			rtnl_unlock();
-			if (!ret) {
-				if (colon)
-					*colon = ':';
-				if (copy_to_user(arg, &ifr,
-						 sizeof(struct ifreq)))
-					ret = -EFAULT;
-			}
-			return ret;
+	/*
+	 *	These ioctl calls:
+	 *	- require superuser power.
+	 *	- require strict serialization.
+	 *	- return a value
+	 */
+	case SIOCGMIIPHY:
+	case SIOCGMIIREG:
+	case SIOCSIFNAME:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		dev_load(net, ifr.ifr_name);
+		rtnl_lock();
+		ret = dev_ifsioc(net, &ifr, cmd);
+		rtnl_unlock();
+		if (!ret) {
+			if (colon)
+				*colon = ':';
+			if (copy_to_user(arg, &ifr,
+					 sizeof(struct ifreq)))
+				ret = -EFAULT;
+		}
+		return ret;
 
-		/*
-		 *	These ioctl calls:
-		 *	- require superuser power.
-		 *	- require strict serialization.
-		 *	- do not return a value
-		 */
-		case SIOCSIFFLAGS:
-		case SIOCSIFMETRIC:
-		case SIOCSIFMTU:
-		case SIOCSIFMAP:
-		case SIOCSIFHWADDR:
-		case SIOCSIFSLAVE:
-		case SIOCADDMULTI:
-		case SIOCDELMULTI:
-		case SIOCSIFHWBROADCAST:
-		case SIOCSIFTXQLEN:
-		case SIOCSMIIREG:
-		case SIOCBONDENSLAVE:
-		case SIOCBONDRELEASE:
-		case SIOCBONDSETHWADDR:
-		case SIOCBONDCHANGEACTIVE:
-		case SIOCBRADDIF:
-		case SIOCBRDELIF:
-		case SIOCSHWTSTAMP:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-			/* fall through */
-		case SIOCBONDSLAVEINFOQUERY:
-		case SIOCBONDINFOQUERY:
+	/*
+	 *	These ioctl calls:
+	 *	- require superuser power.
+	 *	- require strict serialization.
+	 *	- do not return a value
+	 */
+	case SIOCSIFFLAGS:
+	case SIOCSIFMETRIC:
+	case SIOCSIFMTU:
+	case SIOCSIFMAP:
+	case SIOCSIFHWADDR:
+	case SIOCSIFSLAVE:
+	case SIOCADDMULTI:
+	case SIOCDELMULTI:
+	case SIOCSIFHWBROADCAST:
+	case SIOCSIFTXQLEN:
+	case SIOCSMIIREG:
+	case SIOCBONDENSLAVE:
+	case SIOCBONDRELEASE:
+	case SIOCBONDSETHWADDR:
+	case SIOCBONDCHANGEACTIVE:
+	case SIOCBRADDIF:
+	case SIOCBRDELIF:
+	case SIOCSHWTSTAMP:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		/* fall through */
+	case SIOCBONDSLAVEINFOQUERY:
+	case SIOCBONDINFOQUERY:
+		dev_load(net, ifr.ifr_name);
+		rtnl_lock();
+		ret = dev_ifsioc(net, &ifr, cmd);
+		rtnl_unlock();
+		return ret;
+
+	case SIOCGIFMEM:
+		/* Get the per device memory space. We can add this but
+		 * currently do not support it */
+	case SIOCSIFMEM:
+		/* Set the per device memory buffer space.
+		 * Not applicable in our case */
+	case SIOCSIFLINK:
+		return -EINVAL;
+
+	/*
+	 *	Unknown or private ioctl.
+	 */
+	default:
+		if (cmd == SIOCWANDEV ||
+		    (cmd >= SIOCDEVPRIVATE &&
+		     cmd <= SIOCDEVPRIVATE + 15)) {
 			dev_load(net, ifr.ifr_name);
 			rtnl_lock();
 			ret = dev_ifsioc(net, &ifr, cmd);
 			rtnl_unlock();
+			if (!ret && copy_to_user(arg, &ifr,
+						 sizeof(struct ifreq)))
+				ret = -EFAULT;
 			return ret;
-
-		case SIOCGIFMEM:
-			/* Get the per device memory space. We can add this but
-			 * currently do not support it */
-		case SIOCSIFMEM:
-			/* Set the per device memory buffer space.
-			 * Not applicable in our case */
-		case SIOCSIFLINK:
-			return -EINVAL;
-
-		/*
-		 *	Unknown or private ioctl.
-		 */
-		default:
-			if (cmd == SIOCWANDEV ||
-			    (cmd >= SIOCDEVPRIVATE &&
-			     cmd <= SIOCDEVPRIVATE + 15)) {
-				dev_load(net, ifr.ifr_name);
-				rtnl_lock();
-				ret = dev_ifsioc(net, &ifr, cmd);
-				rtnl_unlock();
-				if (!ret && copy_to_user(arg, &ifr,
-							 sizeof(struct ifreq)))
-					ret = -EFAULT;
-				return ret;
-			}
-			/* Take care of Wireless Extensions */
-			if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
-				return wext_handle_ioctl(net, &ifr, cmd, arg);
-			return -EINVAL;
+		}
+		/* Take care of Wireless Extensions */
+		if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
+			return wext_handle_ioctl(net, &ifr, cmd, arg);
+		return -EINVAL;
 	}
 }
 
@@ -4816,6 +4868,7 @@ err_uninit:
 		dev->netdev_ops->ndo_uninit(dev);
 	goto out;
 }
+EXPORT_SYMBOL(register_netdevice);
 
 /**
  *	init_dummy_netdev	- init a dummy network device for NAPI
@@ -5168,6 +5221,7 @@ void free_netdev(struct net_device *dev)
 	/* will free via device release */
 	put_device(&dev->dev);
 }
+EXPORT_SYMBOL(free_netdev);
 
 /**
  *	synchronize_net -  Synchronize with packet receive processing
@@ -5180,6 +5234,7 @@ void synchronize_net(void)
 	might_sleep();
 	synchronize_rcu();
 }
+EXPORT_SYMBOL(synchronize_net);
 
 /**
  *	unregister_netdevice - remove device from the kernel
@@ -5200,6 +5255,7 @@ void unregister_netdevice(struct net_device *dev)
 	/* Finish processing unregister after unlock */
 	net_set_todo(dev);
 }
+EXPORT_SYMBOL(unregister_netdevice);
 
 /**
  *	unregister_netdev - remove device from the kernel
@@ -5218,7 +5274,6 @@ void unregister_netdev(struct net_device *dev)
 	unregister_netdevice(dev);
 	rtnl_unlock();
 }
-
 EXPORT_SYMBOL(unregister_netdev);
 
 /**
@@ -5347,6 +5402,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
 out:
 	return err;
 }
+EXPORT_SYMBOL_GPL(dev_change_net_namespace);
 
 static int dev_cpu_callback(struct notifier_block *nfb,
 			    unsigned long action,
@@ -5407,7 +5463,7 @@ unsigned long netdev_increment_features(unsigned long all, unsigned long one,
 					unsigned long mask)
 {
 	/* If device needs checksumming, downgrade to it. */
-        if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
+	if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
 		all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM);
 	else if (mask & NETIF_F_ALL_CSUM) {
 		/* If one device supports v4/v6 checksumming, set for all. */
@@ -5633,41 +5689,3 @@ static int __init initialize_hashrnd(void)
 
 late_initcall_sync(initialize_hashrnd);
 
-EXPORT_SYMBOL(__dev_get_by_index);
-EXPORT_SYMBOL(__dev_get_by_name);
-EXPORT_SYMBOL(__dev_remove_pack);
-EXPORT_SYMBOL(dev_valid_name);
-EXPORT_SYMBOL(dev_add_pack);
-EXPORT_SYMBOL(dev_alloc_name);
-EXPORT_SYMBOL(dev_close);
-EXPORT_SYMBOL(dev_get_by_flags);
-EXPORT_SYMBOL(dev_get_by_index);
-EXPORT_SYMBOL(dev_get_by_name);
-EXPORT_SYMBOL(dev_open);
-EXPORT_SYMBOL(dev_queue_xmit);
-EXPORT_SYMBOL(dev_remove_pack);
-EXPORT_SYMBOL(dev_set_allmulti);
-EXPORT_SYMBOL(dev_set_promiscuity);
-EXPORT_SYMBOL(dev_change_flags);
-EXPORT_SYMBOL(dev_set_mtu);
-EXPORT_SYMBOL(dev_set_mac_address);
-EXPORT_SYMBOL(free_netdev);
-EXPORT_SYMBOL(netdev_boot_setup_check);
-EXPORT_SYMBOL(netdev_set_master);
-EXPORT_SYMBOL(netdev_state_change);
-EXPORT_SYMBOL(netif_receive_skb);
-EXPORT_SYMBOL(netif_rx);
-EXPORT_SYMBOL(register_gifconf);
-EXPORT_SYMBOL(register_netdevice);
-EXPORT_SYMBOL(register_netdevice_notifier);
-EXPORT_SYMBOL(skb_checksum_help);
-EXPORT_SYMBOL(synchronize_net);
-EXPORT_SYMBOL(unregister_netdevice);
-EXPORT_SYMBOL(unregister_netdevice_notifier);
-EXPORT_SYMBOL(net_enable_timestamp);
-EXPORT_SYMBOL(net_disable_timestamp);
-EXPORT_SYMBOL(dev_get_flags);
-
-EXPORT_SYMBOL(dev_load);
-
-EXPORT_PER_CPU_SYMBOL(softnet_data);
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 9d66fa9..0a113f2 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -52,6 +52,7 @@ struct per_cpu_dm_data {
 
 struct dm_hw_stat_delta {
 	struct net_device *dev;
+	unsigned long last_rx;
 	struct list_head list;
 	struct rcu_head rcu;
 	unsigned long last_drop_val;
@@ -180,17 +181,25 @@ static void trace_napi_poll_hit(struct napi_struct *napi)
 	struct dm_hw_stat_delta *new_stat;
 
 	/*
-	 * Ratelimit our check time to dm_hw_check_delta jiffies
+	 * Don't check napi structures with no associated device
 	 */
-	if (!time_after(jiffies, napi->dev->last_rx + dm_hw_check_delta))
+	if (!napi->dev)
 		return;
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(new_stat, &hw_stats_list, list) {
+		/*
+		 * only add a note to our monitor buffer if:
+		 * 1) this is the dev we received on
+		 * 2) its after the last_rx delta
+		 * 3) our rx_dropped count has gone up
+		 */
 		if ((new_stat->dev == napi->dev)  &&
+		    (time_after(jiffies, new_stat->last_rx + dm_hw_check_delta)) &&
 		    (napi->dev->stats.rx_dropped != new_stat->last_drop_val)) {
 			trace_drop_common(NULL, NULL);
 			new_stat->last_drop_val = napi->dev->stats.rx_dropped;
+			new_stat->last_rx = jiffies;
 			break;
 		}
 	}
@@ -286,6 +295,7 @@ static int dropmon_net_event(struct notifier_block *ev_block,
 			goto out;
 
 		new_stat->dev = dev;
+		new_stat->last_rx = jiffies;
 		INIT_RCU_HEAD(&new_stat->rcu);
 		spin_lock(&trace_state_lock);
 		list_add_rcu(&new_stat->list, &hw_stats_list);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index d9d5160..4c12ddb 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -30,10 +30,17 @@ u32 ethtool_op_get_link(struct net_device *dev)
 	return netif_carrier_ok(dev) ? 1 : 0;
 }
 
+u32 ethtool_op_get_rx_csum(struct net_device *dev)
+{
+	return (dev->features & NETIF_F_ALL_CSUM) != 0;
+}
+EXPORT_SYMBOL(ethtool_op_get_rx_csum);
+
 u32 ethtool_op_get_tx_csum(struct net_device *dev)
 {
 	return (dev->features & NETIF_F_ALL_CSUM) != 0;
 }
+EXPORT_SYMBOL(ethtool_op_get_tx_csum);
 
 int ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
 {
@@ -891,6 +898,19 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr,
 	return actor(dev, edata.data);
 }
 
+static int ethtool_flash_device(struct net_device *dev, char __user *useraddr)
+{
+	struct ethtool_flash efl;
+
+	if (copy_from_user(&efl, useraddr, sizeof(efl)))
+		return -EFAULT;
+
+	if (!dev->ethtool_ops->flash_device)
+		return -EOPNOTSUPP;
+
+	return dev->ethtool_ops->flash_device(dev, &efl);
+}
+
 /* The main entry point in this file.  Called from net/core/dev.c */
 
 int dev_ethtool(struct net *net, struct ifreq *ifr)
@@ -1004,7 +1024,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 		break;
 	case ETHTOOL_GRXCSUM:
 		rc = ethtool_get_value(dev, useraddr, ethcmd,
-				       dev->ethtool_ops->get_rx_csum);
+				       (dev->ethtool_ops->get_rx_csum ?
+					dev->ethtool_ops->get_rx_csum :
+					ethtool_op_get_rx_csum));
 		break;
 	case ETHTOOL_SRXCSUM:
 		rc = ethtool_set_rx_csum(dev, useraddr);
@@ -1068,7 +1090,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 		break;
 	case ETHTOOL_GFLAGS:
 		rc = ethtool_get_value(dev, useraddr, ethcmd,
-				       dev->ethtool_ops->get_flags);
+				       (dev->ethtool_ops->get_flags ?
+					dev->ethtool_ops->get_flags :
+					ethtool_op_get_flags));
 		break;
 	case ETHTOOL_SFLAGS:
 		rc = ethtool_set_value(dev, useraddr,
@@ -1100,6 +1124,9 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 	case ETHTOOL_SGRO:
 		rc = ethtool_set_gro(dev, useraddr);
 		break;
+	case ETHTOOL_FLASHDEV:
+		rc = ethtool_flash_device(dev, useraddr);
+		break;
 	default:
 		rc = -EOPNOTSUPP;
 	}
@@ -1116,7 +1143,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
 EXPORT_SYMBOL(ethtool_op_get_link);
 EXPORT_SYMBOL(ethtool_op_get_sg);
 EXPORT_SYMBOL(ethtool_op_get_tso);
-EXPORT_SYMBOL(ethtool_op_get_tx_csum);
 EXPORT_SYMBOL(ethtool_op_set_sg);
 EXPORT_SYMBOL(ethtool_op_set_tso);
 EXPORT_SYMBOL(ethtool_op_set_tx_csum);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 163b4f5..e587e68 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -692,75 +692,74 @@ static void neigh_connect(struct neighbour *neigh)
 		hh->hh_output = neigh->ops->hh_output;
 }
 
-static void neigh_periodic_timer(unsigned long arg)
+static void neigh_periodic_work(struct work_struct *work)
 {
-	struct neigh_table *tbl = (struct neigh_table *)arg;
+	struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work);
 	struct neighbour *n, **np;
-	unsigned long expire, now = jiffies;
+	unsigned int i;
 
 	NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs);
 
-	write_lock(&tbl->lock);
+	write_lock_bh(&tbl->lock);
 
 	/*
 	 *	periodically recompute ReachableTime from random function
 	 */
 
-	if (time_after(now, tbl->last_rand + 300 * HZ)) {
+	if (time_after(jiffies, tbl->last_rand + 300 * HZ)) {
 		struct neigh_parms *p;
-		tbl->last_rand = now;
+		tbl->last_rand = jiffies;
 		for (p = &tbl->parms; p; p = p->next)
 			p->reachable_time =
 				neigh_rand_reach_time(p->base_reachable_time);
 	}
 
-	np = &tbl->hash_buckets[tbl->hash_chain_gc];
-	tbl->hash_chain_gc = ((tbl->hash_chain_gc + 1) & tbl->hash_mask);
+	for (i = 0 ; i <= tbl->hash_mask; i++) {
+		np = &tbl->hash_buckets[i];
 
-	while ((n = *np) != NULL) {
-		unsigned int state;
+		while ((n = *np) != NULL) {
+			unsigned int state;
 
-		write_lock(&n->lock);
+			write_lock(&n->lock);
 
-		state = n->nud_state;
-		if (state & (NUD_PERMANENT | NUD_IN_TIMER)) {
-			write_unlock(&n->lock);
-			goto next_elt;
-		}
+			state = n->nud_state;
+			if (state & (NUD_PERMANENT | NUD_IN_TIMER)) {
+				write_unlock(&n->lock);
+				goto next_elt;
+			}
 
-		if (time_before(n->used, n->confirmed))
-			n->used = n->confirmed;
+			if (time_before(n->used, n->confirmed))
+				n->used = n->confirmed;
 
-		if (atomic_read(&n->refcnt) == 1 &&
-		    (state == NUD_FAILED ||
-		     time_after(now, n->used + n->parms->gc_staletime))) {
-			*np = n->next;
-			n->dead = 1;
+			if (atomic_read(&n->refcnt) == 1 &&
+			    (state == NUD_FAILED ||
+			     time_after(jiffies, n->used + n->parms->gc_staletime))) {
+				*np = n->next;
+				n->dead = 1;
+				write_unlock(&n->lock);
+				neigh_cleanup_and_release(n);
+				continue;
+			}
 			write_unlock(&n->lock);
-			neigh_cleanup_and_release(n);
-			continue;
-		}
-		write_unlock(&n->lock);
 
 next_elt:
-		np = &n->next;
+			np = &n->next;
+		}
+		/*
+		 * It's fine to release lock here, even if hash table
+		 * grows while we are preempted.
+		 */
+		write_unlock_bh(&tbl->lock);
+		cond_resched();
+		write_lock_bh(&tbl->lock);
 	}
-
 	/* Cycle through all hash buckets every base_reachable_time/2 ticks.
 	 * ARP entry timeouts range from 1/2 base_reachable_time to 3/2
 	 * base_reachable_time.
 	 */
-	expire = tbl->parms.base_reachable_time >> 1;
-	expire /= (tbl->hash_mask + 1);
-	if (!expire)
-		expire = 1;
-
-	if (expire>HZ)
-		mod_timer(&tbl->gc_timer, round_jiffies(now + expire));
-	else
-		mod_timer(&tbl->gc_timer, now + expire);
-
-	write_unlock(&tbl->lock);
+	schedule_delayed_work(&tbl->gc_work,
+			      tbl->parms.base_reachable_time >> 1);
+	write_unlock_bh(&tbl->lock);
 }
 
 static __inline__ int neigh_max_probes(struct neighbour *n)
@@ -1316,7 +1315,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
 }
 EXPORT_SYMBOL(pneigh_enqueue);
 
-static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
+static inline struct neigh_parms *lookup_neigh_parms(struct neigh_table *tbl,
 						      struct net *net, int ifindex)
 {
 	struct neigh_parms *p;
@@ -1337,7 +1336,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
 	struct net *net = dev_net(dev);
 	const struct net_device_ops *ops = dev->netdev_ops;
 
-	ref = lookup_neigh_params(tbl, net, 0);
+	ref = lookup_neigh_parms(tbl, net, 0);
 	if (!ref)
 		return NULL;
 
@@ -1442,10 +1441,8 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
 	get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));
 
 	rwlock_init(&tbl->lock);
-	setup_timer(&tbl->gc_timer, neigh_periodic_timer, (unsigned long)tbl);
-	tbl->gc_timer.expires  = now + 1;
-	add_timer(&tbl->gc_timer);
-
+	INIT_DELAYED_WORK_DEFERRABLE(&tbl->gc_work, neigh_periodic_work);
+	schedule_delayed_work(&tbl->gc_work, tbl->parms.reachable_time);
 	setup_timer(&tbl->proxy_timer, neigh_proxy_process, (unsigned long)tbl);
 	skb_queue_head_init_class(&tbl->proxy_queue,
 			&neigh_table_proxy_queue_class);
@@ -1482,7 +1479,8 @@ int neigh_table_clear(struct neigh_table *tbl)
 	struct neigh_table **tp;
 
 	/* It is not clean... Fix it to unload IPv6 module safely */
-	del_timer_sync(&tbl->gc_timer);
+	cancel_delayed_work(&tbl->gc_work);
+	flush_scheduled_work();
 	del_timer_sync(&tbl->proxy_timer);
 	pneigh_queue_purge(&tbl->proxy_queue);
 	neigh_ifdown(tbl, NULL);
@@ -1752,7 +1750,6 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
 			.ndtc_last_rand		= jiffies_to_msecs(rand_delta),
 			.ndtc_hash_rnd		= tbl->hash_rnd,
 			.ndtc_hash_mask		= tbl->hash_mask,
-			.ndtc_hash_chain_gc	= tbl->hash_chain_gc,
 			.ndtc_proxy_qlen	= tbl->proxy_queue.qlen,
 		};
 
@@ -1906,7 +1903,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 		if (tbp[NDTPA_IFINDEX])
 			ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]);
 
-		p = lookup_neigh_params(tbl, net, ifindex);
+		p = lookup_neigh_parms(tbl, net, ifindex);
 		if (p == NULL) {
 			err = -ENOENT;
 			goto errout_tbl_lock;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 3994680..7d4c575 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -141,7 +141,7 @@ static ssize_t show_dormant(struct device *dev,
 	return -EINVAL;
 }
 
-static const char *operstates[] = {
+static const char *const operstates[] = {
 	"unknown",
 	"notpresent", /* currently unused */
 	"down",
@@ -493,7 +493,7 @@ void netdev_unregister_kobject(struct net_device * net)
 int netdev_register_kobject(struct net_device *net)
 {
 	struct device *dev = &(net->dev);
-	struct attribute_group **groups = net->sysfs_groups;
+	const struct attribute_group **groups = net->sysfs_groups;
 
 	dev->class = &net_class;
 	dev->platform_data = net;
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 1972830..1c1af27 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -6,6 +6,8 @@
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/idr.h>
+#include <linux/rculist.h>
+#include <linux/nsproxy.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 
@@ -127,7 +129,7 @@ static struct net *net_create(void)
 	rv = setup_net(net);
 	if (rv == 0) {
 		rtnl_lock();
-		list_add_tail(&net->list, &net_namespace_list);
+		list_add_tail_rcu(&net->list, &net_namespace_list);
 		rtnl_unlock();
 	}
 	mutex_unlock(&net_mutex);
@@ -156,9 +158,16 @@ static void cleanup_net(struct work_struct *work)
 
 	/* Don't let anyone else find us. */
 	rtnl_lock();
-	list_del(&net->list);
+	list_del_rcu(&net->list);
 	rtnl_unlock();
 
+	/*
+	 * Another CPU might be rcu-iterating the list, wait for it.
+	 * This needs to be before calling the exit() notifiers, so
+	 * the rcu_barrier() below isn't sufficient alone.
+	 */
+	synchronize_rcu();
+
 	/* Run all of the network namespace exit methods */
 	list_for_each_entry_reverse(ops, &pernet_list, list) {
 		if (ops->exit)
@@ -193,6 +202,26 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)
 }
 #endif
 
+struct net *get_net_ns_by_pid(pid_t pid)
+{
+	struct task_struct *tsk;
+	struct net *net;
+
+	/* Lookup the network namespace */
+	net = ERR_PTR(-ESRCH);
+	rcu_read_lock();
+	tsk = find_task_by_vpid(pid);
+	if (tsk) {
+		struct nsproxy *nsproxy;
+		nsproxy = task_nsproxy(tsk);
+		if (nsproxy)
+			net = get_net(nsproxy->net_ns);
+	}
+	rcu_read_unlock();
+	return net;
+}
+EXPORT_SYMBOL_GPL(get_net_ns_by_pid);
+
 static int __init net_ns_init(void)
 {
 	struct net_generic *ng;
@@ -219,7 +248,7 @@ static int __init net_ns_init(void)
 		panic("Could not setup the initial network namespace");
 
 	rtnl_lock();
-	list_add_tail(&init_net.list, &net_namespace_list);
+	list_add_tail_rcu(&init_net.list, &net_namespace_list);
 	rtnl_unlock();
 
 	mutex_unlock(&net_mutex);
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 1b76eb1..0b4d0d3 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -9,6 +9,7 @@
  * Copyright (C) 2002  Red Hat, Inc.
  */
 
+#include <linux/moduleparam.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/string.h>
@@ -50,6 +51,9 @@ static atomic_t trapped;
 static void zap_completion_queue(void);
 static void arp_reply(struct sk_buff *skb);
 
+static unsigned int carrier_timeout = 4;
+module_param(carrier_timeout, uint, 0644);
+
 static void queue_process(struct work_struct *work)
 {
 	struct netpoll_info *npinfo =
@@ -737,7 +741,7 @@ int netpoll_setup(struct netpoll *np)
 		}
 
 		atleast = jiffies + HZ/10;
-		atmost = jiffies + 4*HZ;
+		atmost = jiffies + carrier_timeout * HZ;
 		while (!netif_carrier_ok(ndev)) {
 			if (time_after(jiffies, atmost)) {
 				printk(KERN_NOTICE
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 19b8c20..0bcecbf 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -131,6 +131,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/capability.h>
+#include <linux/hrtimer.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
@@ -162,14 +163,13 @@
 #include <asm/byteorder.h>
 #include <linux/rcupdate.h>
 #include <linux/bitops.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/timex.h>
+#include <linux/uaccess.h>
 #include <asm/dma.h>
-#include <asm/uaccess.h>
 #include <asm/div64.h>		/* do_div */
-#include <asm/timex.h>
-
-#define VERSION  "pktgen v2.70: Packet Generator for packet performance testing.\n"
 
+#define VERSION 	"2.72"
 #define IP_NAME_SZ 32
 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
 #define MPLS_STACK_BOTTOM htonl(0x00000100)
@@ -206,7 +206,7 @@
 #define PKTGEN_MAGIC 0xbe9be955
 #define PG_PROC_DIR "pktgen"
 #define PGCTRL	    "pgctrl"
-static struct proc_dir_entry *pg_proc_dir = NULL;
+static struct proc_dir_entry *pg_proc_dir;
 
 #define MAX_CFLOWS  65536
 
@@ -231,9 +231,9 @@ struct pktgen_dev {
 	 */
 	struct proc_dir_entry *entry;	/* proc file */
 	struct pktgen_thread *pg_thread;/* the owner */
-	struct list_head list;		/* Used for chaining in the thread's run-queue */
+	struct list_head list;		/* chaining in the thread's run-queue */
 
-	int running;		/* if this changes to false, the test will stop */
+	int running;		/* if false, the test will stop */
 
 	/* If min != max, then we will either do a linear iteration, or
 	 * we will do a random selection from within the range.
@@ -246,33 +246,37 @@ struct pktgen_dev {
 	int max_pkt_size;	/* = ETH_ZLEN; */
 	int pkt_overhead;	/* overhead for MPLS, VLANs, IPSEC etc */
 	int nfrags;
-	__u32 delay_us;		/* Default delay */
-	__u32 delay_ns;
+	u64 delay;		/* nano-seconds */
+
 	__u64 count;		/* Default No packets to send */
 	__u64 sofar;		/* How many pkts we've sent so far */
 	__u64 tx_bytes;		/* How many bytes we've transmitted */
-	__u64 errors;		/* Errors when trying to transmit, pkts will be re-sent */
+	__u64 errors;		/* Errors when trying to transmit,
+				   pkts will be re-sent */
 
 	/* runtime counters relating to clone_skb */
-	__u64 next_tx_us;	/* timestamp of when to tx next */
-	__u32 next_tx_ns;
 
 	__u64 allocated_skbs;
 	__u32 clone_count;
 	int last_ok;		/* Was last skb sent?
-				 * Or a failed transmit of some sort?  This will keep
-				 * sequence numbers in order, for example.
+				 * Or a failed transmit of some sort?
+				 * This will keep sequence numbers in order
 				 */
-	__u64 started_at;	/* micro-seconds */
-	__u64 stopped_at;	/* micro-seconds */
-	__u64 idle_acc;		/* micro-seconds */
+	ktime_t next_tx;
+	ktime_t started_at;
+	ktime_t stopped_at;
+	u64	idle_acc;	/* nano-seconds */
+
 	__u32 seq_num;
 
-	int clone_skb;		/* Use multiple SKBs during packet gen.  If this number
-				 * is greater than 1, then that many copies of the same
-				 * packet will be sent before a new packet is allocated.
-				 * For instance, if you want to send 1024 identical packets
-				 * before creating a new packet, set clone_skb to 1024.
+	int clone_skb;		/*
+				 * Use multiple SKBs during packet gen.
+				 * If this number is greater than 1, then
+				 * that many copies of the same packet will be
+				 * sent before a new packet is allocated.
+				 * If you want to send 1024 identical packets
+				 * before creating a new packet,
+				 * set clone_skb to 1024.
 				 */
 
 	char dst_min[IP_NAME_SZ];	/* IP, ie 1.2.3.4 */
@@ -304,8 +308,10 @@ struct pktgen_dev {
 	__u16 udp_dst_max;	/* exclusive, dest UDP port */
 
 	/* DSCP + ECN */
-	__u8 tos;            /* six most significant bits of (former) IPv4 TOS are for dscp codepoint */
-	__u8 traffic_class;  /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */
+	__u8 tos;            /* six MSB of (former) IPv4 TOS
+				are for dscp codepoint */
+	__u8 traffic_class;  /* ditto for the (former) Traffic Class in IPv6
+				(see RFC 3260, sec. 4) */
 
 	/* MPLS */
 	unsigned nr_labels;	/* Depth of stack, 0 = no MPLS */
@@ -346,15 +352,17 @@ struct pktgen_dev {
 	 */
 	__u16 pad;		/* pad out the hh struct to an even 16 bytes */
 
-	struct sk_buff *skb;	/* skb we are to transmit next, mainly used for when we
+	struct sk_buff *skb;	/* skb we are to transmit next, used for when we
 				 * are transmitting the same one multiple times
 				 */
-	struct net_device *odev;	/* The out-going device.  Note that the device should
-					 * have it's pg_info pointer pointing back to this
-					 * device.  This will be set when the user specifies
-					 * the out-going device name (not when the inject is
-					 * started as it used to do.)
-					 */
+	struct net_device *odev; /* The out-going device.
+				  * Note that the device should have it's
+				  * pg_info pointer pointing back to this
+				  * device.
+				  * Set when the user specifies the out-going
+				  * device name (not when the inject is
+				  * started as it used to do.)
+				  */
 	struct flow_state *flows;
 	unsigned cflows;	/* Concurrent flows (config) */
 	unsigned lflow;		/* Flow length  (config) */
@@ -379,13 +387,14 @@ struct pktgen_hdr {
 };
 
 struct pktgen_thread {
-	spinlock_t if_lock;
+	spinlock_t if_lock;		/* for list of devices */
 	struct list_head if_list;	/* All device here */
 	struct list_head th_list;
 	struct task_struct *tsk;
 	char result[512];
 
-	/* Field for thread to receive "posted" events terminate, stop ifs etc. */
+	/* Field for thread to receive "posted" events terminate,
+	   stop ifs etc. */
 
 	u32 control;
 	int cpu;
@@ -397,24 +406,22 @@ struct pktgen_thread {
 #define REMOVE 1
 #define FIND   0
 
-/** Convert to micro-seconds */
-static inline __u64 tv_to_us(const struct timeval *tv)
+static inline ktime_t ktime_now(void)
 {
-	__u64 us = tv->tv_usec;
-	us += (__u64) tv->tv_sec * (__u64) 1000000;
-	return us;
+	struct timespec ts;
+	ktime_get_ts(&ts);
+
+	return timespec_to_ktime(ts);
 }
 
-static __u64 getCurUs(void)
+/* This works even if 32 bit because of careful byte order choice */
+static inline int ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
 {
-	struct timeval tv;
-	do_gettimeofday(&tv);
-	return tv_to_us(&tv);
+	return cmp1.tv64 < cmp2.tv64;
 }
 
-/* old include end */
-
-static char version[] __initdata = VERSION;
+static const char version[] =
+	"pktgen " VERSION ": Packet Generator for packet performance testing.\n";
 
 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
 static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
@@ -424,7 +431,7 @@ static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
 static void pktgen_run_all_threads(void);
 static void pktgen_reset_all_threads(void);
 static void pktgen_stop_all_threads_ifs(void);
-static int pktgen_stop_device(struct pktgen_dev *pkt_dev);
+
 static void pktgen_stop(struct pktgen_thread *t);
 static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
 
@@ -432,10 +439,10 @@ static unsigned int scan_ip6(const char *s, char ip[16]);
 static unsigned int fmt_ip6(char *s, const char ip[16]);
 
 /* Module parameters, defaults. */
-static int pg_count_d = 1000;	/* 1000 pkts by default */
-static int pg_delay_d;
-static int pg_clone_skb_d;
-static int debug;
+static int pg_count_d __read_mostly = 1000;
+static int pg_delay_d __read_mostly;
+static int pg_clone_skb_d  __read_mostly;
+static int debug  __read_mostly;
 
 static DEFINE_MUTEX(pktgen_thread_lock);
 static LIST_HEAD(pktgen_threads);
@@ -451,12 +458,12 @@ static struct notifier_block pktgen_notifier_block = {
 
 static int pgctrl_show(struct seq_file *seq, void *v)
 {
-	seq_puts(seq, VERSION);
+	seq_puts(seq, version);
 	return 0;
 }
 
-static ssize_t pgctrl_write(struct file *file, const char __user * buf,
-			    size_t count, loff_t * ppos)
+static ssize_t pgctrl_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
 {
 	int err = 0;
 	char data[128];
@@ -509,10 +516,9 @@ static const struct file_operations pktgen_fops = {
 
 static int pktgen_if_show(struct seq_file *seq, void *v)
 {
-	struct pktgen_dev *pkt_dev = seq->private;
-	__u64 sa;
-	__u64 stopped;
-	__u64 now = getCurUs();
+	const struct pktgen_dev *pkt_dev = seq->private;
+	ktime_t stopped;
+	u64 idle;
 
 	seq_printf(seq,
 		   "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
@@ -520,9 +526,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 		   pkt_dev->max_pkt_size);
 
 	seq_printf(seq,
-		   "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
-		   pkt_dev->nfrags,
-		   1000 * pkt_dev->delay_us + pkt_dev->delay_ns,
+		   "     frags: %d  delay: %llu  clone_skb: %d  ifname: %s\n",
+		   pkt_dev->nfrags, (unsigned long long) pkt_dev->delay,
 		   pkt_dev->clone_skb, pkt_dev->odev->name);
 
 	seq_printf(seq, "     flows: %u flowlen: %u\n", pkt_dev->cflows,
@@ -549,11 +554,14 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 			   "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1,
 			   b2, b3);
 
-	} else
+	} else {
+		seq_printf(seq,
+			   "     dst_min: %s  dst_max: %s\n",
+			   pkt_dev->dst_min, pkt_dev->dst_max);
 		seq_printf(seq,
-			   "     dst_min: %s  dst_max: %s\n     src_min: %s  src_max: %s\n",
-			   pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min,
-			   pkt_dev->src_max);
+			   "        src_min: %s  src_max: %s\n",
+			   pkt_dev->src_min, pkt_dev->src_max);
+	}
 
 	seq_puts(seq, "     src_mac: ");
 
@@ -565,7 +573,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 	seq_printf(seq, "%pM\n", pkt_dev->dst_mac);
 
 	seq_printf(seq,
-		   "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
+		   "     udp_src_min: %d  udp_src_max: %d"
+		   "  udp_dst_min: %d  udp_dst_max: %d\n",
 		   pkt_dev->udp_src_min, pkt_dev->udp_src_max,
 		   pkt_dev->udp_dst_min, pkt_dev->udp_dst_max);
 
@@ -581,23 +590,21 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 				   i == pkt_dev->nr_labels-1 ? "\n" : ", ");
 	}
 
-	if (pkt_dev->vlan_id != 0xffff) {
+	if (pkt_dev->vlan_id != 0xffff)
 		seq_printf(seq, "     vlan_id: %u  vlan_p: %u  vlan_cfi: %u\n",
-			   pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi);
-	}
+			   pkt_dev->vlan_id, pkt_dev->vlan_p,
+			   pkt_dev->vlan_cfi);
 
-	if (pkt_dev->svlan_id != 0xffff) {
+	if (pkt_dev->svlan_id != 0xffff)
 		seq_printf(seq, "     svlan_id: %u  vlan_p: %u  vlan_cfi: %u\n",
-			   pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi);
-	}
+			   pkt_dev->svlan_id, pkt_dev->svlan_p,
+			   pkt_dev->svlan_cfi);
 
-	if (pkt_dev->tos) {
+	if (pkt_dev->tos)
 		seq_printf(seq, "     tos: 0x%02x\n", pkt_dev->tos);
-	}
 
-	if (pkt_dev->traffic_class) {
+	if (pkt_dev->traffic_class)
 		seq_printf(seq, "     traffic_class: 0x%02x\n", pkt_dev->traffic_class);
-	}
 
 	seq_printf(seq, "     Flags: ");
 
@@ -654,17 +661,21 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 
 	seq_puts(seq, "\n");
 
-	sa = pkt_dev->started_at;
-	stopped = pkt_dev->stopped_at;
-	if (pkt_dev->running)
-		stopped = now;	/* not really stopped, more like last-running-at */
+	/* not really stopped, more like last-running-at */
+	stopped = pkt_dev->running ? ktime_now() : pkt_dev->stopped_at;
+	idle = pkt_dev->idle_acc;
+	do_div(idle, NSEC_PER_USEC);
 
 	seq_printf(seq,
-		   "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
+		   "Current:\n     pkts-sofar: %llu  errors: %llu\n",
 		   (unsigned long long)pkt_dev->sofar,
-		   (unsigned long long)pkt_dev->errors, (unsigned long long)sa,
-		   (unsigned long long)stopped,
-		   (unsigned long long)pkt_dev->idle_acc);
+		   (unsigned long long)pkt_dev->errors);
+
+	seq_printf(seq,
+		   "     started: %lluus  stopped: %lluus idle: %lluus\n",
+		   (unsigned long long) ktime_to_us(pkt_dev->started_at),
+		   (unsigned long long) ktime_to_us(stopped),
+		   (unsigned long long) idle);
 
 	seq_printf(seq,
 		   "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
@@ -696,7 +707,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 }
 
 
-static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num)
+static int hex32_arg(const char __user *user_buffer, unsigned long maxlen,
+		     __u32 *num)
 {
 	int i = 0;
 	*num = 0;
@@ -846,9 +858,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	/* Read variable name */
 
 	len = strn_len(&user_buffer[i], sizeof(name) - 1);
-	if (len < 0) {
+	if (len < 0)
 		return len;
-	}
+
 	memset(name, 0, sizeof(name));
 	if (copy_from_user(name, &user_buffer[i], len))
 		return -EFAULT;
@@ -872,9 +884,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "min_pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value < 14 + 20 + 8)
 			value = 14 + 20 + 8;
@@ -889,9 +901,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "max_pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value < 14 + 20 + 8)
 			value = 14 + 20 + 8;
@@ -908,9 +920,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value < 14 + 20 + 8)
 			value = 14 + 20 + 8;
@@ -925,9 +937,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "debug")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		debug = value;
 		sprintf(pg_result, "OK: debug=%u", debug);
@@ -936,9 +948,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "frags")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->nfrags = value;
 		sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags);
@@ -946,26 +958,24 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "delay")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
-		if (value == 0x7FFFFFFF) {
-			pkt_dev->delay_us = 0x7FFFFFFF;
-			pkt_dev->delay_ns = 0;
-		} else {
-			pkt_dev->delay_us = value / 1000;
-			pkt_dev->delay_ns = value % 1000;
-		}
-		sprintf(pg_result, "OK: delay=%u",
-			1000 * pkt_dev->delay_us + pkt_dev->delay_ns);
+		if (value == 0x7FFFFFFF)
+			pkt_dev->delay = ULLONG_MAX;
+		else
+			pkt_dev->delay = (u64)value * NSEC_PER_USEC;
+
+		sprintf(pg_result, "OK: delay=%llu",
+			(unsigned long long) pkt_dev->delay);
 		return count;
 	}
 	if (!strcmp(name, "udp_src_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_src_min) {
 			pkt_dev->udp_src_min = value;
@@ -976,9 +986,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "udp_dst_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_dst_min) {
 			pkt_dev->udp_dst_min = value;
@@ -989,9 +999,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "udp_src_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_src_max) {
 			pkt_dev->udp_src_max = value;
@@ -1002,9 +1012,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "udp_dst_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_dst_max) {
 			pkt_dev->udp_dst_max = value;
@@ -1015,9 +1025,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "clone_skb")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->clone_skb = value;
 
@@ -1026,9 +1036,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->count = value;
 		sprintf(pg_result, "OK: count=%llu",
@@ -1037,9 +1047,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "src_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (pkt_dev->src_mac_count != value) {
 			pkt_dev->src_mac_count = value;
@@ -1051,9 +1061,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "dst_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (pkt_dev->dst_mac_count != value) {
 			pkt_dev->dst_mac_count = value;
@@ -1067,9 +1077,9 @@ static ssize_t pktgen_if_write(struct file *file,
 		char f[32];
 		memset(f, 0, 32);
 		len = strn_len(&user_buffer[i], sizeof(f) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		if (copy_from_user(f, &user_buffer[i], len))
 			return -EFAULT;
 		i += len;
@@ -1168,9 +1178,8 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
 
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
@@ -1190,9 +1199,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "dst_max")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
@@ -1303,9 +1312,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "src_min")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
 		buf[len] = 0;
@@ -1324,9 +1333,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	}
 	if (!strcmp(name, "src_max")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
 		buf[len] = 0;
@@ -1350,9 +1359,9 @@ static ssize_t pktgen_if_write(struct file *file,
 		memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
 
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		memset(valstr, 0, sizeof(valstr));
 		if (copy_from_user(valstr, &user_buffer[i], len))
 			return -EFAULT;
@@ -1392,9 +1401,9 @@ static ssize_t pktgen_if_write(struct file *file,
 		memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN);
 
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		memset(valstr, 0, sizeof(valstr));
 		if (copy_from_user(valstr, &user_buffer[i], len))
 			return -EFAULT;
@@ -1435,9 +1444,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "flows")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value > MAX_CFLOWS)
 			value = MAX_CFLOWS;
@@ -1449,9 +1458,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "flowlen")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->lflow = value;
 		sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow);
@@ -1460,9 +1469,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "queue_map_min")) {
 		len = num_arg(&user_buffer[i], 5, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->queue_map_min = value;
 		sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min);
@@ -1471,9 +1480,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "queue_map_max")) {
 		len = num_arg(&user_buffer[i], 5, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->queue_map_max = value;
 		sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max);
@@ -1505,9 +1514,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "vlan_id")) {
 		len = num_arg(&user_buffer[i], 4, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value <= 4095) {
 			pkt_dev->vlan_id = value;  /* turn on VLAN */
@@ -1532,9 +1541,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "vlan_p")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) {
 			pkt_dev->vlan_p = value;
@@ -1547,9 +1556,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "vlan_cfi")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) {
 			pkt_dev->vlan_cfi = value;
@@ -1562,9 +1571,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "svlan_id")) {
 		len = num_arg(&user_buffer[i], 4, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) {
 			pkt_dev->svlan_id = value;  /* turn on SVLAN */
@@ -1589,9 +1598,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "svlan_p")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) {
 			pkt_dev->svlan_p = value;
@@ -1604,9 +1613,9 @@ static ssize_t pktgen_if_write(struct file *file,
 
 	if (!strcmp(name, "svlan_cfi")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) {
 			pkt_dev->svlan_cfi = value;
@@ -1620,9 +1629,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	if (!strcmp(name, "tos")) {
 		__u32 tmp_value = 0;
 		len = hex32_arg(&user_buffer[i], 2, &tmp_value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (len == 2) {
 			pkt_dev->tos = tmp_value;
@@ -1636,9 +1645,9 @@ static ssize_t pktgen_if_write(struct file *file,
 	if (!strcmp(name, "traffic_class")) {
 		__u32 tmp_value = 0;
 		len = hex32_arg(&user_buffer[i], 2, &tmp_value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (len == 2) {
 			pkt_dev->traffic_class = tmp_value;
@@ -1670,7 +1679,7 @@ static const struct file_operations pktgen_if_fops = {
 static int pktgen_thread_show(struct seq_file *seq, void *v)
 {
 	struct pktgen_thread *t = seq->private;
-	struct pktgen_dev *pkt_dev;
+	const struct pktgen_dev *pkt_dev;
 
 	BUG_ON(!t);
 
@@ -1873,8 +1882,10 @@ static void pktgen_change_name(struct net_device *dev)
 
 			remove_proc_entry(pkt_dev->entry->name, pg_proc_dir);
 
-			pkt_dev->entry = create_proc_entry(dev->name, 0600,
-							   pg_proc_dir);
+			pkt_dev->entry = proc_create_data(dev->name, 0600,
+							  pg_proc_dir,
+							  &pktgen_if_fops,
+							  pkt_dev);
 			if (!pkt_dev->entry)
 				printk(KERN_ERR "pktgen: can't move proc "
 				       " entry for '%s'\n", dev->name);
@@ -1908,13 +1919,14 @@ static int pktgen_device_event(struct notifier_block *unused,
 	return NOTIFY_DONE;
 }
 
-static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname)
+static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev,
+						 const char *ifname)
 {
 	char b[IFNAMSIZ+5];
 	int i = 0;
 
-	for(i=0; ifname[i] != '@'; i++) {
-		if(i == IFNAMSIZ)
+	for (i = 0; ifname[i] != '@'; i++) {
+		if (i == IFNAMSIZ)
 			break;
 
 		b[i] = ifname[i];
@@ -1981,7 +1993,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
 		printk(KERN_WARNING "pktgen: WARNING: Requested "
 		       "queue_map_min (zero-based) (%d) exceeds valid range "
 		       "[0 - %d] for (%d) queues on %s, resetting\n",
-		       pkt_dev->queue_map_min, (ntxq ?: 1)- 1, ntxq,
+		       pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq,
 		       pkt_dev->odev->name);
 		pkt_dev->queue_map_min = ntxq - 1;
 	}
@@ -1989,7 +2001,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
 		printk(KERN_WARNING "pktgen: WARNING: Requested "
 		       "queue_map_max (zero-based) (%d) exceeds valid range "
 		       "[0 - %d] for (%d) queues on %s, resetting\n",
-		       pkt_dev->queue_map_max, (ntxq ?: 1)- 1, ntxq,
+		       pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq,
 		       pkt_dev->odev->name);
 		pkt_dev->queue_map_max = ntxq - 1;
 	}
@@ -2030,7 +2042,8 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
 			 */
 
 			rcu_read_lock();
-			if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) {
+			idev = __in6_dev_get(pkt_dev->odev);
+			if (idev) {
 				struct inet6_ifaddr *ifp;
 
 				read_lock_bh(&idev->lock);
@@ -2089,27 +2102,40 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
 	pkt_dev->nflows = 0;
 }
 
-static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
+
+static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 {
-	__u64 start;
-	__u64 now;
+	ktime_t start;
+	s32 remaining;
+	struct hrtimer_sleeper t;
+
+	hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	hrtimer_set_expires(&t.timer, spin_until);
+
+	remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer));
+	if (remaining <= 0)
+		return;
 
-	start = now = getCurUs();
-	while (now < spin_until_us) {
-		/* TODO: optimize sleeping behavior */
-		if (spin_until_us - now > jiffies_to_usecs(1) + 1)
-			schedule_timeout_interruptible(1);
-		else if (spin_until_us - now > 100) {
-			if (!pkt_dev->running)
-				return;
-			if (need_resched())
+	start = ktime_now();
+	if (remaining < 100)
+		udelay(remaining); 	/* really small just spin */
+	else {
+		/* see do_nanosleep */
+		hrtimer_init_sleeper(&t, current);
+		do {
+			set_current_state(TASK_INTERRUPTIBLE);
+			hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS);
+			if (!hrtimer_active(&t.timer))
+				t.task = NULL;
+
+			if (likely(t.task))
 				schedule();
-		}
 
-		now = getCurUs();
+			hrtimer_cancel(&t.timer);
+		} while (t.task && pkt_dev->running && !signal_pending(current));
+		__set_current_state(TASK_RUNNING);
 	}
-
-	pkt_dev->idle_acc += now - start;
+	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), start));
 }
 
 static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@@ -2120,13 +2146,9 @@ static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
 	pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev);
 }
 
-static inline int f_seen(struct pktgen_dev *pkt_dev, int flow)
+static inline int f_seen(const struct pktgen_dev *pkt_dev, int flow)
 {
-
-	if (pkt_dev->flows[flow].flags & F_INIT)
-		return 1;
-	else
-		return 0;
+	return !!(pkt_dev->flows[flow].flags & F_INIT);
 }
 
 static inline int f_pick(struct pktgen_dev *pkt_dev)
@@ -2174,7 +2196,7 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
 		if (x) {
 			pkt_dev->flows[flow].x = x;
 			set_pkt_overhead(pkt_dev);
-			pkt_dev->pkt_overhead+=x->props.header_len;
+			pkt_dev->pkt_overhead += x->props.header_len;
 		}
 
 	}
@@ -2313,18 +2335,18 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
 
 	if (!(pkt_dev->flags & F_IPV6)) {
 
-		if ((imn = ntohl(pkt_dev->saddr_min)) < (imx =
-							 ntohl(pkt_dev->
-							       saddr_max))) {
+		imn = ntohl(pkt_dev->saddr_min);
+		imx = ntohl(pkt_dev->saddr_max);
+		if (imn < imx) {
 			__u32 t;
 			if (pkt_dev->flags & F_IPSRC_RND)
 				t = random32() % (imx - imn) + imn;
 			else {
 				t = ntohl(pkt_dev->cur_saddr);
 				t++;
-				if (t > imx) {
+				if (t > imx)
 					t = imn;
-				}
+
 			}
 			pkt_dev->cur_saddr = htonl(t);
 		}
@@ -2435,14 +2457,14 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev)
 	if (err)
 		goto error;
 
-	x->curlft.bytes +=skb->len;
+	x->curlft.bytes += skb->len;
 	x->curlft.packets++;
 error:
 	spin_unlock(&x->lock);
 	return err;
 }
 
-static inline void free_SAs(struct pktgen_dev *pkt_dev)
+static void free_SAs(struct pktgen_dev *pkt_dev)
 {
 	if (pkt_dev->cflows) {
 		/* let go of the SAs if we have them */
@@ -2457,7 +2479,7 @@ static inline void free_SAs(struct pktgen_dev *pkt_dev)
 	}
 }
 
-static inline int process_ipsec(struct pktgen_dev *pkt_dev,
+static int process_ipsec(struct pktgen_dev *pkt_dev,
 			      struct sk_buff *skb, __be16 protocol)
 {
 	if (pkt_dev->flags & F_IPSEC_ON) {
@@ -2467,11 +2489,11 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
 			int ret;
 			__u8 *eth;
 			nhead = x->props.header_len - skb_headroom(skb);
-			if (nhead >0) {
+			if (nhead > 0) {
 				ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
 				if (ret < 0) {
 					printk(KERN_ERR "Error expanding "
-					       "ipsec packet %d\n",ret);
+					       "ipsec packet %d\n", ret);
 					goto err;
 				}
 			}
@@ -2481,13 +2503,13 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
 			ret = pktgen_output_ipsec(skb, pkt_dev);
 			if (ret) {
 				printk(KERN_ERR "Error creating ipsec "
-				       "packet %d\n",ret);
+				       "packet %d\n", ret);
 				goto err;
 			}
 			/* restore ll */
 			eth = (__u8 *) skb_push(skb, ETH_HLEN);
 			memcpy(eth, pkt_dev->hh, 12);
-			*(u16 *) & eth[12] = protocol;
+			*(u16 *) &eth[12] = protocol;
 		}
 	}
 	return 1;
@@ -2500,9 +2522,9 @@ err:
 static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
 {
 	unsigned i;
-	for (i = 0; i < pkt_dev->nr_labels; i++) {
+	for (i = 0; i < pkt_dev->nr_labels; i++)
 		*mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM;
-	}
+
 	mpls--;
 	*mpls |= MPLS_STACK_BOTTOM;
 }
@@ -2543,8 +2565,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 	mod_cur_headers(pkt_dev);
 
 	datalen = (odev->hard_header_len + 16) & ~0xf;
-	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
-			pkt_dev->pkt_overhead, GFP_ATOMIC);
+	skb = __netdev_alloc_skb(odev,
+				 pkt_dev->cur_pkt_size + 64
+				 + datalen + pkt_dev->pkt_overhead, GFP_NOWAIT);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
 		return NULL;
@@ -2668,8 +2691,9 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
 		}
 	}
 
-	/* Stamp the time, and sequence number, convert them to network byte order */
-
+	/* Stamp the time, and sequence number,
+	 * convert them to network byte order
+	 */
 	if (pgh) {
 		struct timeval timestamp;
 
@@ -2882,8 +2906,9 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 	queue_map = pkt_dev->cur_queue_map;
 	mod_cur_headers(pkt_dev);
 
-	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
-			pkt_dev->pkt_overhead, GFP_ATOMIC);
+	skb = __netdev_alloc_skb(odev,
+				 pkt_dev->cur_pkt_size + 64
+				 + 16 + pkt_dev->pkt_overhead, GFP_NOWAIT);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
 		return NULL;
@@ -2922,7 +2947,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 	udph = udp_hdr(skb);
 
 	memcpy(eth, pkt_dev->hh, 12);
-	*(__be16 *) & eth[12] = protocol;
+	*(__be16 *) &eth[12] = protocol;
 
 	/* Eth + IPh + UDPh + mpls */
 	datalen = pkt_dev->cur_pkt_size - 14 -
@@ -3016,8 +3041,10 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 		}
 	}
 
-	/* Stamp the time, and sequence number, convert them to network byte order */
-	/* should we update cloned packets too ? */
+	/* Stamp the time, and sequence number,
+	 * convert them to network byte order
+	 * should we update cloned packets too ?
+	 */
 	if (pgh) {
 		struct timeval timestamp;
 
@@ -3033,8 +3060,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
 	return skb;
 }
 
-static inline struct sk_buff *fill_packet(struct net_device *odev,
-					  struct pktgen_dev *pkt_dev)
+static struct sk_buff *fill_packet(struct net_device *odev,
+				   struct pktgen_dev *pkt_dev)
 {
 	if (pkt_dev->flags & F_IPV6)
 		return fill_packet_ipv6(odev, pkt_dev);
@@ -3072,9 +3099,9 @@ static void pktgen_run(struct pktgen_thread *t)
 			pktgen_clear_counters(pkt_dev);
 			pkt_dev->running = 1;	/* Cranke yeself! */
 			pkt_dev->skb = NULL;
-			pkt_dev->started_at = getCurUs();
-			pkt_dev->next_tx_us = getCurUs();	/* Transmit immediately */
-			pkt_dev->next_tx_ns = 0;
+			pkt_dev->started_at =
+				pkt_dev->next_tx = ktime_now();
+
 			set_pkt_overhead(pkt_dev);
 
 			strcpy(pkt_dev->result, "Starting");
@@ -3101,17 +3128,14 @@ static void pktgen_stop_all_threads_ifs(void)
 	mutex_unlock(&pktgen_thread_lock);
 }
 
-static int thread_is_running(struct pktgen_thread *t)
+static int thread_is_running(const struct pktgen_thread *t)
 {
-	struct pktgen_dev *pkt_dev;
-	int res = 0;
+	const struct pktgen_dev *pkt_dev;
 
 	list_for_each_entry(pkt_dev, &t->if_list, list)
-		if (pkt_dev->running) {
-			res = 1;
-			break;
-		}
-	return res;
+		if (pkt_dev->running)
+			return 1;
+	return 0;
 }
 
 static int pktgen_wait_thread_run(struct pktgen_thread *t)
@@ -3168,7 +3192,8 @@ static void pktgen_run_all_threads(void)
 
 	mutex_unlock(&pktgen_thread_lock);
 
-	schedule_timeout_interruptible(msecs_to_jiffies(125));	/* Propagate thread->control  */
+	/* Propagate thread->control  */
+	schedule_timeout_interruptible(msecs_to_jiffies(125));
 
 	pktgen_wait_all_threads_run();
 }
@@ -3186,35 +3211,29 @@ static void pktgen_reset_all_threads(void)
 
 	mutex_unlock(&pktgen_thread_lock);
 
-	schedule_timeout_interruptible(msecs_to_jiffies(125));	/* Propagate thread->control  */
+	/* Propagate thread->control  */
+	schedule_timeout_interruptible(msecs_to_jiffies(125));
 
 	pktgen_wait_all_threads_run();
 }
 
 static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
 {
-	__u64 total_us, bps, mbps, pps, idle;
+	__u64 bps, mbps, pps;
 	char *p = pkt_dev->result;
-
-	total_us = pkt_dev->stopped_at - pkt_dev->started_at;
-
-	idle = pkt_dev->idle_acc;
-
-	p += sprintf(p, "OK: %llu(c%llu+d%llu) usec, %llu (%dbyte,%dfrags)\n",
-		     (unsigned long long)total_us,
-		     (unsigned long long)(total_us - idle),
-		     (unsigned long long)idle,
+	ktime_t elapsed = ktime_sub(pkt_dev->stopped_at,
+				    pkt_dev->started_at);
+	ktime_t idle = ns_to_ktime(pkt_dev->idle_acc);
+
+	p += sprintf(p, "OK: %llu(c%llu+d%llu) nsec, %llu (%dbyte,%dfrags)\n",
+		     (unsigned long long)ktime_to_us(elapsed),
+		     (unsigned long long)ktime_to_us(ktime_sub(elapsed, idle)),
+		     (unsigned long long)ktime_to_us(idle),
 		     (unsigned long long)pkt_dev->sofar,
 		     pkt_dev->cur_pkt_size, nr_frags);
 
-	pps = pkt_dev->sofar * USEC_PER_SEC;
-
-	while ((total_us >> 32) != 0) {
-		pps >>= 1;
-		total_us >>= 1;
-	}
-
-	do_div(pps, total_us);
+	pps = div64_u64(pkt_dev->sofar * NSEC_PER_SEC,
+			ktime_to_ns(elapsed));
 
 	bps = pps * 8 * pkt_dev->cur_pkt_size;
 
@@ -3228,7 +3247,6 @@ static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
 }
 
 /* Set stopped-at timer, remove from running list, do counters & statistics */
-
 static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
 {
 	int nr_frags = pkt_dev->skb ? skb_shinfo(pkt_dev->skb)->nr_frags : -1;
@@ -3239,7 +3257,9 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
 		return -EINVAL;
 	}
 
-	pkt_dev->stopped_at = getCurUs();
+	kfree_skb(pkt_dev->skb);
+	pkt_dev->skb = NULL;
+	pkt_dev->stopped_at = ktime_now();
 	pkt_dev->running = 0;
 
 	show_results(pkt_dev, nr_frags);
@@ -3258,7 +3278,7 @@ static struct pktgen_dev *next_to_run(struct pktgen_thread *t)
 			continue;
 		if (best == NULL)
 			best = pkt_dev;
-		else if (pkt_dev->next_tx_us < best->next_tx_us)
+		else if (ktime_lt(pkt_dev->next_tx, best->next_tx))
 			best = pkt_dev;
 	}
 	if_unlock(t);
@@ -3275,9 +3295,6 @@ static void pktgen_stop(struct pktgen_thread *t)
 
 	list_for_each_entry(pkt_dev, &t->if_list, list) {
 		pktgen_stop_device(pkt_dev);
-		kfree_skb(pkt_dev->skb);
-
-		pkt_dev->skb = NULL;
 	}
 
 	if_unlock(t);
@@ -3348,30 +3365,37 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
 	mutex_unlock(&pktgen_thread_lock);
 }
 
-static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
+static void idle(struct pktgen_dev *pkt_dev)
+{
+	ktime_t idle_start = ktime_now();
+
+	if (need_resched())
+		schedule();
+	else
+		cpu_relax();
+
+	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), idle_start));
+}
+
+
+static void pktgen_xmit(struct pktgen_dev *pkt_dev)
 {
 	struct net_device *odev = pkt_dev->odev;
-	int (*xmit)(struct sk_buff *, struct net_device *)
+	netdev_tx_t (*xmit)(struct sk_buff *, struct net_device *)
 		= odev->netdev_ops->ndo_start_xmit;
 	struct netdev_queue *txq;
-	__u64 idle_start = 0;
 	u16 queue_map;
 	int ret;
 
-	if (pkt_dev->delay_us || pkt_dev->delay_ns) {
-		u64 now;
-
-		now = getCurUs();
-		if (now < pkt_dev->next_tx_us)
-			spin(pkt_dev, pkt_dev->next_tx_us);
+	if (pkt_dev->delay) {
+		spin(pkt_dev, pkt_dev->next_tx);
 
 		/* This is max DELAY, this has special meaning of
 		 * "never transmit"
 		 */
-		if (pkt_dev->delay_us == 0x7FFFFFFF) {
-			pkt_dev->next_tx_us = getCurUs() + pkt_dev->delay_us;
-			pkt_dev->next_tx_ns = pkt_dev->delay_ns;
-			goto out;
+		if (pkt_dev->delay == ULLONG_MAX) {
+			pkt_dev->next_tx = ktime_add_ns(ktime_now(), ULONG_MAX);
+			return;
 		}
 	}
 
@@ -3383,47 +3407,32 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
 	}
 
 	txq = netdev_get_tx_queue(odev, queue_map);
-	if (netif_tx_queue_stopped(txq) ||
-	    netif_tx_queue_frozen(txq) ||
-	    need_resched()) {
-		idle_start = getCurUs();
-
-		if (!netif_running(odev)) {
+	/* Did we saturate the queue already? */
+	if (netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq)) {
+		/* If device is down, then all queues are permnantly frozen */
+		if (netif_running(odev))
+			idle(pkt_dev);
+		else
 			pktgen_stop_device(pkt_dev);
-			kfree_skb(pkt_dev->skb);
-			pkt_dev->skb = NULL;
-			goto out;
-		}
-		if (need_resched())
-			schedule();
-
-		pkt_dev->idle_acc += getCurUs() - idle_start;
-
-		if (netif_tx_queue_stopped(txq) ||
-		    netif_tx_queue_frozen(txq)) {
-			pkt_dev->next_tx_us = getCurUs();	/* TODO */
-			pkt_dev->next_tx_ns = 0;
-			goto out;	/* Try the next interface */
-		}
+		return;
 	}
 
-	if (pkt_dev->last_ok || !pkt_dev->skb) {
-		if ((++pkt_dev->clone_count >= pkt_dev->clone_skb)
-		    || (!pkt_dev->skb)) {
-			/* build a new pkt */
-			kfree_skb(pkt_dev->skb);
+	if (!pkt_dev->skb || (pkt_dev->last_ok &&
+			      ++pkt_dev->clone_count >= pkt_dev->clone_skb)) {
+		/* build a new pkt */
+		kfree_skb(pkt_dev->skb);
 
-			pkt_dev->skb = fill_packet(odev, pkt_dev);
-			if (pkt_dev->skb == NULL) {
-				printk(KERN_ERR "pktgen: ERROR: couldn't "
-				       "allocate skb in fill_packet.\n");
-				schedule();
-				pkt_dev->clone_count--;	/* back out increment, OOM */
-				goto out;
-			}
-			pkt_dev->allocated_skbs++;
-			pkt_dev->clone_count = 0;	/* reset counter */
+		pkt_dev->skb = fill_packet(odev, pkt_dev);
+		if (pkt_dev->skb == NULL) {
+			printk(KERN_ERR "pktgen: ERROR: couldn't "
+			       "allocate skb in fill_packet.\n");
+			schedule();
+			pkt_dev->clone_count--;	/* back out increment, OOM */
+			return;
 		}
+
+		pkt_dev->allocated_skbs++;
+		pkt_dev->clone_count = 0;	/* reset counter */
 	}
 
 	/* fill_packet() might have changed the queue */
@@ -3431,73 +3440,53 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
 	txq = netdev_get_tx_queue(odev, queue_map);
 
 	__netif_tx_lock_bh(txq);
-	if (!netif_tx_queue_stopped(txq) &&
-	    !netif_tx_queue_frozen(txq)) {
-
+	if (unlikely(netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq)))
+		pkt_dev->last_ok = 0;
+	else {
 		atomic_inc(&(pkt_dev->skb->users));
-	      retry_now:
+
+	retry_now:
 		ret = (*xmit)(pkt_dev->skb, odev);
-		if (likely(ret == NETDEV_TX_OK)) {
+		switch (ret) {
+		case NETDEV_TX_OK:
 			txq_trans_update(txq);
 			pkt_dev->last_ok = 1;
 			pkt_dev->sofar++;
 			pkt_dev->seq_num++;
 			pkt_dev->tx_bytes += pkt_dev->cur_pkt_size;
-
-		} else if (ret == NETDEV_TX_LOCKED
-			   && (odev->features & NETIF_F_LLTX)) {
+			break;
+		case NETDEV_TX_LOCKED:
 			cpu_relax();
 			goto retry_now;
-		} else {	/* Retry it next time */
-
-			atomic_dec(&(pkt_dev->skb->users));
-
-			if (debug && net_ratelimit())
-				printk(KERN_INFO "pktgen: Hard xmit error\n");
-
+		default: /* Drivers are not supposed to return other values! */
+			if (net_ratelimit())
+				pr_info("pktgen: %s xmit error: %d\n",
+					odev->name, ret);
 			pkt_dev->errors++;
+			/* fallthru */
+		case NETDEV_TX_BUSY:
+			/* Retry it next time */
+			atomic_dec(&(pkt_dev->skb->users));
 			pkt_dev->last_ok = 0;
 		}
 
-		pkt_dev->next_tx_us = getCurUs();
-		pkt_dev->next_tx_ns = 0;
-
-		pkt_dev->next_tx_us += pkt_dev->delay_us;
-		pkt_dev->next_tx_ns += pkt_dev->delay_ns;
-
-		if (pkt_dev->next_tx_ns > 1000) {
-			pkt_dev->next_tx_us++;
-			pkt_dev->next_tx_ns -= 1000;
-		}
+		if (pkt_dev->delay)
+			pkt_dev->next_tx = ktime_add_ns(ktime_now(),
+							pkt_dev->delay);
 	}
-
-	else {			/* Retry it next time */
-		pkt_dev->last_ok = 0;
-		pkt_dev->next_tx_us = getCurUs();	/* TODO */
-		pkt_dev->next_tx_ns = 0;
-	}
-
 	__netif_tx_unlock_bh(txq);
 
 	/* If pkt_dev->count is zero, then run forever */
 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
-		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
-			idle_start = getCurUs();
-			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
-				if (signal_pending(current)) {
-					break;
-				}
-				schedule();
-			}
-			pkt_dev->idle_acc += getCurUs() - idle_start;
+		while (atomic_read(&(pkt_dev->skb->users)) != 1) {
+			if (signal_pending(current))
+				break;
+			idle(pkt_dev);
 		}
 
 		/* Done with this */
 		pktgen_stop_device(pkt_dev);
-		kfree_skb(pkt_dev->skb);
-		pkt_dev->skb = NULL;
 	}
-out:;
 }
 
 /*
@@ -3516,7 +3505,8 @@ static int pktgen_thread_worker(void *arg)
 	init_waitqueue_head(&t->queue);
 	complete(&t->start_done);
 
-	pr_debug("pktgen: starting pktgen/%d:  pid=%d\n", cpu, task_pid_nr(current));
+	pr_debug("pktgen: starting pktgen/%d:  pid=%d\n",
+		 cpu, task_pid_nr(current));
 
 	set_current_state(TASK_INTERRUPTIBLE);
 
@@ -3651,8 +3641,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
 	pkt_dev->max_pkt_size = ETH_ZLEN;
 	pkt_dev->nfrags = 0;
 	pkt_dev->clone_skb = pg_clone_skb_d;
-	pkt_dev->delay_us = pg_delay_d / 1000;
-	pkt_dev->delay_ns = pg_delay_d % 1000;
+	pkt_dev->delay = pg_delay_d;
 	pkt_dev->count = pg_count_d;
 	pkt_dev->sofar = 0;
 	pkt_dev->udp_src_min = 9;	/* sink port */
@@ -3864,10 +3853,15 @@ static void __exit pg_cleanup(void)
 module_init(pg_init);
 module_exit(pg_cleanup);
 
-MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se");
+MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se>");
 MODULE_DESCRIPTION("Packet Generator tool");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION);
 module_param(pg_count_d, int, 0);
+MODULE_PARM_DESC(pg_count_d, "Default number of packets to inject");
 module_param(pg_delay_d, int, 0);
+MODULE_PARM_DESC(pg_delay_d, "Default delay between packets (nanoseconds)");
 module_param(pg_clone_skb_d, int, 0);
+MODULE_PARM_DESC(pg_clone_skb_d, "Default number of copies of the same packet");
 module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Enable debugging of pktgen module");
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d78030f..eb42873 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -35,7 +35,6 @@
 #include <linux/security.h>
 #include <linux/mutex.h>
 #include <linux/if_addr.h>
-#include <linux/nsproxy.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -52,6 +51,7 @@
 #include <net/pkt_sched.h>
 #include <net/fib_rules.h>
 #include <net/rtnetlink.h>
+#include <net/net_namespace.h>
 
 struct rtnl_link
 {
@@ -606,7 +606,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 			    int type, u32 pid, u32 seq, u32 change,
 			    unsigned int flags)
 {
-	struct netdev_queue *txq;
 	struct ifinfomsg *ifm;
 	struct nlmsghdr *nlh;
 	const struct net_device_stats *stats;
@@ -637,9 +636,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 	if (dev->master)
 		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
 
-	txq = netdev_get_tx_queue(dev, 0);
-	if (txq->qdisc_sleeping)
-		NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id);
+	if (dev->qdisc)
+		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc->ops->id);
 
 	if (dev->ifalias)
 		NLA_PUT_STRING(skb, IFLA_IFALIAS, dev->ifalias);
@@ -725,25 +723,6 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
 	[IFLA_INFO_DATA]	= { .type = NLA_NESTED },
 };
 
-static struct net *get_net_ns_by_pid(pid_t pid)
-{
-	struct task_struct *tsk;
-	struct net *net;
-
-	/* Lookup the network namespace */
-	net = ERR_PTR(-ESRCH);
-	rcu_read_lock();
-	tsk = find_task_by_vpid(pid);
-	if (tsk) {
-		struct nsproxy *nsproxy;
-		nsproxy = task_nsproxy(tsk);
-		if (nsproxy)
-			net = get_net(nsproxy->net_ns);
-	}
-	rcu_read_unlock();
-	return net;
-}
-
 static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
 {
 	if (dev) {
@@ -993,12 +972,20 @@ struct net_device *rtnl_create_link(struct net *net, char *ifname,
 {
 	int err;
 	struct net_device *dev;
+	unsigned int num_queues = 1;
+	unsigned int real_num_queues = 1;
 
+	if (ops->get_tx_queues) {
+		err = ops->get_tx_queues(net, tb, &num_queues, &real_num_queues);
+		if (err)
+			goto err;
+	}
 	err = -ENOMEM;
-	dev = alloc_netdev(ops->priv_size, ifname, ops->setup);
+	dev = alloc_netdev_mq(ops->priv_size, ifname, ops->setup, num_queues);
 	if (!dev)
 		goto err;
 
+	dev->real_num_tx_queues = real_num_queues;
 	if (strchr(dev->name, '%')) {
 		err = dev_alloc_name(dev, dev->name);
 		if (err < 0)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 9e0597d..80a9616 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -559,9 +559,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #endif
 #endif
 	new->vlan_tci		= old->vlan_tci;
-#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
-	new->do_not_encrypt	= old->do_not_encrypt;
-#endif
 
 	skb_copy_secmark(new, old);
 }
diff --git a/net/core/sock.c b/net/core/sock.c
index 7633422..30d5446 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -142,7 +142,7 @@ static struct lock_class_key af_family_slock_keys[AF_MAX];
  * strings build-time, so that runtime initialization of socket
  * locks is fast):
  */
-static const char *af_family_key_strings[AF_MAX+1] = {
+static const char *const af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_UNSPEC", "sk_lock-AF_UNIX"     , "sk_lock-AF_INET"     ,
   "sk_lock-AF_AX25"  , "sk_lock-AF_IPX"      , "sk_lock-AF_APPLETALK",
   "sk_lock-AF_NETROM", "sk_lock-AF_BRIDGE"   , "sk_lock-AF_ATMPVC"   ,
@@ -158,7 +158,7 @@ static const char *af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_IEEE802154",
   "sk_lock-AF_MAX"
 };
-static const char *af_family_slock_key_strings[AF_MAX+1] = {
+static const char *const af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
   "slock-AF_AX25"  , "slock-AF_IPX"      , "slock-AF_APPLETALK",
   "slock-AF_NETROM", "slock-AF_BRIDGE"   , "slock-AF_ATMPVC"   ,
@@ -174,7 +174,7 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_IEEE802154",
   "slock-AF_MAX"
 };
-static const char *af_family_clock_key_strings[AF_MAX+1] = {
+static const char *const af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
   "clock-AF_AX25"  , "clock-AF_IPX"      , "clock-AF_APPLETALK",
   "clock-AF_NETROM", "clock-AF_BRIDGE"   , "clock-AF_ATMPVC"   ,
@@ -482,6 +482,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 		sk->sk_reuse = valbool;
 		break;
 	case SO_TYPE:
+	case SO_PROTOCOL:
+	case SO_DOMAIN:
 	case SO_ERROR:
 		ret = -ENOPROTOOPT;
 		break;
@@ -764,6 +766,14 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 		v.val = sk->sk_type;
 		break;
 
+	case SO_PROTOCOL:
+		v.val = sk->sk_protocol;
+		break;
+
+	case SO_DOMAIN:
+		v.val = sk->sk_family;
+		break;
+
 	case SO_ERROR:
 		v.val = -sock_error(sk);
 		if (v.val == 0)
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 8379496..e0879bf 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -64,6 +64,7 @@ static struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = {
 	[DCB_ATTR_CAP]         = {.type = NLA_NESTED},
 	[DCB_ATTR_PFC_STATE]   = {.type = NLA_U8},
 	[DCB_ATTR_BCN]         = {.type = NLA_NESTED},
+	[DCB_ATTR_APP]         = {.type = NLA_NESTED},
 };
 
 /* DCB priority flow control to User Priority nested attributes */
@@ -158,6 +159,13 @@ static struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = {
 	[DCB_BCN_ATTR_ALL]          = {.type = NLA_FLAG},
 };
 
+/* DCB APP nested attributes. */
+static struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = {
+	[DCB_APP_ATTR_IDTYPE]       = {.type = NLA_U8},
+	[DCB_APP_ATTR_ID]           = {.type = NLA_U16},
+	[DCB_APP_ATTR_PRIORITY]     = {.type = NLA_U8},
+};
+
 /* standard netlink reply call */
 static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
                        u32 seq, u16 flags)
@@ -536,6 +544,120 @@ static int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb,
 	return ret;
 }
 
+static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb,
+                        u32 pid, u32 seq, u16 flags)
+{
+	struct sk_buff *dcbnl_skb;
+	struct nlmsghdr *nlh;
+	struct dcbmsg *dcb;
+	struct nlattr *app_nest;
+	struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];
+	u16 id;
+	u8 up, idtype;
+	int ret = -EINVAL;
+
+	if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->getapp)
+		goto out;
+
+	ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
+	                       dcbnl_app_nest);
+	if (ret)
+		goto out;
+
+	ret = -EINVAL;
+	/* all must be non-null */
+	if ((!app_tb[DCB_APP_ATTR_IDTYPE]) ||
+	    (!app_tb[DCB_APP_ATTR_ID]))
+		goto out;
+
+	/* either by eth type or by socket number */
+	idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]);
+	if ((idtype != DCB_APP_IDTYPE_ETHTYPE) &&
+	    (idtype != DCB_APP_IDTYPE_PORTNUM))
+		goto out;
+
+	id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
+	up = netdev->dcbnl_ops->getapp(netdev, idtype, id);
+
+	/* send this back */
+	dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!dcbnl_skb)
+		goto out;
+
+	nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
+	dcb = NLMSG_DATA(nlh);
+	dcb->dcb_family = AF_UNSPEC;
+	dcb->cmd = DCB_CMD_GAPP;
+
+	app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP);
+	ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype);
+	if (ret)
+		goto out_cancel;
+
+	ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id);
+	if (ret)
+		goto out_cancel;
+
+	ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up);
+	if (ret)
+		goto out_cancel;
+
+	nla_nest_end(dcbnl_skb, app_nest);
+	nlmsg_end(dcbnl_skb, nlh);
+
+	ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
+	if (ret)
+		goto nlmsg_failure;
+
+	goto out;
+
+out_cancel:
+	nla_nest_cancel(dcbnl_skb, app_nest);
+nlmsg_failure:
+	kfree_skb(dcbnl_skb);
+out:
+	return ret;
+}
+
+static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
+                        u32 pid, u32 seq, u16 flags)
+{
+	int ret = -EINVAL;
+	u16 id;
+	u8 up, idtype;
+	struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];
+
+	if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp)
+		goto out;
+
+	ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
+	                       dcbnl_app_nest);
+	if (ret)
+		goto out;
+
+	ret = -EINVAL;
+	/* all must be non-null */
+	if ((!app_tb[DCB_APP_ATTR_IDTYPE]) ||
+	    (!app_tb[DCB_APP_ATTR_ID]) ||
+	    (!app_tb[DCB_APP_ATTR_PRIORITY]))
+		goto out;
+
+	/* either by eth type or by socket number */
+	idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]);
+	if ((idtype != DCB_APP_IDTYPE_ETHTYPE) &&
+	    (idtype != DCB_APP_IDTYPE_PORTNUM))
+		goto out;
+
+	id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
+	up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]);
+
+	ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up),
+	                  RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
+	                  pid, seq, flags);
+out:
+	return ret;
+}
+
 static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb,
                              u32 pid, u32 seq, u16 flags, int dir)
 {
@@ -1093,6 +1215,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 		ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq,
 		                       nlh->nlmsg_flags);
 		goto out;
+	case DCB_CMD_GAPP:
+		ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq,
+		                   nlh->nlmsg_flags);
+		goto out;
+	case DCB_CMD_SAPP:
+		ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq,
+		                   nlh->nlmsg_flags);
+		goto out;
 	default:
 		goto errout;
 	}
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 4b5db44..8408398 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -66,9 +66,9 @@ config IP_DCCP_CCID3_RTO
 	    A value of 0 disables this feature by enforcing the value specified
 	    in RFC 3448. The following values have been suggested as bounds for
 	    experimental use:
-	    	* 16-20ms to match the typical multimedia inter-frame interval
-	    	* 100ms as a reasonable compromise [default]
-	    	* 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4)
+		* 16-20ms to match the typical multimedia inter-frame interval
+		* 100ms as a reasonable compromise [default]
+		* 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4)
 
 	    The default of 100ms is a compromise between a large value for
 	    efficient DCCP implementations, and a small value to avoid disrupting
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index d235294..e8cf99e 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid2.c
- *
  *  Copyright (c) 2005, 2006 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
  *
  *  Changes to meet Linux coding standards, and DCCP infrastructure fixes.
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h
index 2c94ca0..326ac90 100644
--- a/net/dccp/ccids/ccid2.h
+++ b/net/dccp/ccids/ccid2.h
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid2.h
- *
  *  Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -40,14 +38,14 @@ struct ccid2_seq {
 #define CCID2_SEQBUF_LEN 1024
 #define CCID2_SEQBUF_MAX 128
 
-/** struct ccid2_hc_tx_sock - CCID2 TX half connection
- *
+/**
+ * struct ccid2_hc_tx_sock - CCID2 TX half connection
  * @ccid2hctx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5
  * @ccid2hctx_packets_acked - Ack counter for deriving cwnd growth (RFC 3465)
  * @ccid2hctx_lastrtt -time RTT was last measured
  * @ccid2hctx_rpseq - last consecutive seqno
  * @ccid2hctx_rpdupack - dupacks since rpseq
-*/
+ */
 struct ccid2_hc_tx_sock {
 	u32			ccid2hctx_cwnd;
 	u32			ccid2hctx_ssthresh;
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index a27b7f4..34dcc79 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid3.c
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
@@ -52,7 +50,7 @@ static int ccid3_debug;
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
 {
-	static char *ccid3_state_names[] = {
+	static const char *const ccid3_state_names[] = {
 	[TFRC_SSTATE_NO_SENT]  = "NO_SENT",
 	[TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
 	[TFRC_SSTATE_FBACK]    = "FBACK",
@@ -646,7 +644,7 @@ enum ccid3_fback_type {
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
 {
-	static char *ccid3_rx_state_names[] = {
+	static const char *const ccid3_rx_state_names[] = {
 	[TFRC_RSTATE_NO_DATA] = "NO_DATA",
 	[TFRC_RSTATE_DATA]    = "DATA",
 	[TFRC_RSTATE_TERM]    = "TERM",
@@ -750,7 +748,8 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
 	return 0;
 }
 
-/** ccid3_first_li  -  Implements [RFC 3448, 6.3.1]
+/**
+ * ccid3_first_li  -  Implements [RFC 5348, 6.3.1]
  *
  * Determine the length of the first loss interval via inverse lookup.
  * Assume that X_recv can be computed by the throughput equation
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 49ca32b..e5a2441 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/ccid3.h
- *
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *
@@ -75,8 +73,8 @@ enum ccid3_hc_tx_states {
 	TFRC_SSTATE_TERM,
 };
 
-/** struct ccid3_hc_tx_sock - CCID3 sender half-connection socket
- *
+/**
+ * struct ccid3_hc_tx_sock - CCID3 sender half-connection socket
  * @ccid3hctx_x - Current sending rate in 64 * bytes per second
  * @ccid3hctx_x_recv - Receive rate    in 64 * bytes per second
  * @ccid3hctx_x_calc - Calculated rate in bytes per second
@@ -119,9 +117,9 @@ struct ccid3_hc_tx_sock {
 
 static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
 {
-    struct ccid3_hc_tx_sock *hctx = ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid);
-    BUG_ON(hctx == NULL);
-    return hctx;
+	struct ccid3_hc_tx_sock *hctx = ccid_priv(dccp_sk(sk)->dccps_hc_tx_ccid);
+	BUG_ON(hctx == NULL);
+	return hctx;
 }
 
 /* TFRC receiver states */
@@ -131,22 +129,22 @@ enum ccid3_hc_rx_states {
 	TFRC_RSTATE_TERM    = 127,
 };
 
-/** struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
- *
- *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448 4.3)
- *  @ccid3hcrx_rtt  -  Receiver estimate of rtt (non-standard)
- *  @ccid3hcrx_p  -  Current loss event rate (RFC 3448 5.4)
- *  @ccid3hcrx_last_counter  -  Tracks window counter (RFC 4342, 8.1)
- *  @ccid3hcrx_state  -  Receiver state, one of %ccid3_hc_rx_states
- *  @ccid3hcrx_bytes_recv  -  Total sum of DCCP payload bytes
- *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448, sec. 4.3)
- *  @ccid3hcrx_rtt  -  Receiver estimate of RTT
- *  @ccid3hcrx_tstamp_last_feedback  -  Time at which last feedback was sent
- *  @ccid3hcrx_tstamp_last_ack  -  Time at which last feedback was sent
- *  @ccid3hcrx_hist  -  Packet history (loss detection + RTT sampling)
- *  @ccid3hcrx_li_hist  -  Loss Interval database
- *  @ccid3hcrx_s  -  Received packet size in bytes
- *  @ccid3hcrx_pinv  -  Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
+/**
+ * struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
+ * @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448 4.3)
+ * @ccid3hcrx_rtt  -  Receiver estimate of rtt (non-standard)
+ * @ccid3hcrx_p  -  Current loss event rate (RFC 3448 5.4)
+ * @ccid3hcrx_last_counter  -  Tracks window counter (RFC 4342, 8.1)
+ * @ccid3hcrx_state  -  Receiver state, one of %ccid3_hc_rx_states
+ * @ccid3hcrx_bytes_recv  -  Total sum of DCCP payload bytes
+ * @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448, sec. 4.3)
+ * @ccid3hcrx_rtt  -  Receiver estimate of RTT
+ * @ccid3hcrx_tstamp_last_feedback  -  Time at which last feedback was sent
+ * @ccid3hcrx_tstamp_last_ack  -  Time at which last feedback was sent
+ * @ccid3hcrx_hist  -  Packet history (loss detection + RTT sampling)
+ * @ccid3hcrx_li_hist  -  Loss Interval database
+ * @ccid3hcrx_s  -  Received packet size in bytes
+ * @ccid3hcrx_pinv  -  Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
  */
 struct ccid3_hc_rx_sock {
 	u8				ccid3hcrx_last_counter:4;
@@ -163,9 +161,9 @@ struct ccid3_hc_rx_sock {
 
 static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
 {
-    struct ccid3_hc_rx_sock *hcrx = ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid);
-    BUG_ON(hcrx == NULL);
-    return hcrx;
+	struct ccid3_hc_rx_sock *hcrx = ccid_priv(dccp_sk(sk)->dccps_hc_rx_ccid);
+	BUG_ON(hcrx == NULL);
+	return hcrx;
 }
 
 #endif /* _DCCP_CCID3_H_ */
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 4d1e401..8fc3cbf 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/lib/loss_interval.c
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
@@ -21,7 +19,7 @@ static const int tfrc_lh_weights[NINTERVAL] = { 10, 10, 10, 10, 8, 6, 4, 2 };
 /* implements LIFO semantics on the array */
 static inline u8 LIH_INDEX(const u8 ctr)
 {
-	return (LIH_SIZE - 1 - (ctr % LIH_SIZE));
+	return LIH_SIZE - 1 - (ctr % LIH_SIZE);
 }
 
 /* the `counter' index always points at the next entry to be populated */
@@ -129,7 +127,8 @@ static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
 		(cur->li_is_closed || SUB16(new_loss->tfrchrx_ccval, cur->li_ccval) > 4);
 }
 
-/** tfrc_lh_interval_add  -  Insert new record into the Loss Interval database
+/**
+ * tfrc_lh_interval_add  -  Insert new record into the Loss Interval database
  * @lh:		   Loss Interval database
  * @rh:		   Receive history containing a fresh loss event
  * @calc_first_li: Caller-dependent routine to compute length of first interval
diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h
index 246018a..d1d2f53 100644
--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -1,8 +1,6 @@
 #ifndef _DCCP_LI_HIST_
 #define _DCCP_LI_HIST_
 /*
- *  net/dccp/ccids/lib/loss_interval.h
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index b7785b3..3a4f414 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/packet_history.c
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *
@@ -128,7 +126,7 @@ u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
 
 
 /*
- * 	Receiver History Routines
+ *	Receiver History Routines
  */
 static struct kmem_cache *tfrc_rx_hist_slab;
 
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index 461cc91..7df6c52 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -70,7 +70,6 @@ struct tfrc_rx_hist_entry {
 
 /**
  * tfrc_rx_hist  -  RX history structure for TFRC-based protocols
- *
  * @ring:		Packet history for RTT sampling and loss detection
  * @loss_count:		Number of entries in circular history
  * @loss_start:		Movable index (for loss detection)
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h
index e9720b1..01bb48e 100644
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -1,8 +1,6 @@
 #ifndef _TFRC_H_
 #define _TFRC_H_
 /*
- *  net/dccp/ccids/lib/tfrc.h
- *
  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
@@ -32,7 +30,7 @@ extern int tfrc_debug;
 /* integer-arithmetic divisions of type (a * 1000000)/b */
 static inline u64 scaled_div(u64 a, u64 b)
 {
-	BUG_ON(b==0);
+	BUG_ON(b == 0);
 	return div64_u64(a * 1000000, b);
 }
 
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index c5d3a9e..22ca1cf 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -1,6 +1,4 @@
 /*
- *  net/dccp/ccids/lib/tfrc_equation.c
- *
  *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
@@ -79,10 +77,10 @@
     }
 
   With the given configuration, we have, with M = TFRC_CALC_X_ARRSIZE-1,
-    lookup[0][0]  =  g(1000000/(M+1)) 		 =  1000000 * f(0.2%)
-    lookup[M][0]  =  g(1000000)			 =  1000000 * f(100%)
-    lookup[0][1]  =  g(TFRC_SMALLEST_P)		  = 1000000 * f(0.01%)
-    lookup[M][1]  =  g(TFRC_CALC_X_SPLIT)	 =  1000000 * f(5%)
+    lookup[0][0]  =  g(1000000/(M+1))		= 1000000 * f(0.2%)
+    lookup[M][0]  =  g(1000000)			= 1000000 * f(100%)
+    lookup[0][1]  =  g(TFRC_SMALLEST_P)		= 1000000 * f(0.01%)
+    lookup[M][1]  =  g(TFRC_CALC_X_SPLIT)	= 1000000 * f(5%)
 
   In summary, the two columns represent f(p) for the following ranges:
     * The first column is for   0.002  <= p <= 1.0
@@ -610,11 +608,10 @@ static inline u32 tfrc_binsearch(u32 fval, u8 small)
 
 /**
  * tfrc_calc_x - Calculate the send rate as per section 3.1 of RFC3448
- *
- *  @s: packet size          in bytes
- *  @R: RTT                  scaled by 1000000   (i.e., microseconds)
- *  @p: loss ratio estimate  scaled by 1000000
- *  Returns X_calc           in bytes per second (not scaled).
+ * @s: packet size          in bytes
+ * @R: RTT                  scaled by 1000000   (i.e., microseconds)
+ * @p: loss ratio estimate  scaled by 1000000
+ * Returns X_calc           in bytes per second (not scaled).
  */
 u32 tfrc_calc_x(u16 s, u32 R, u32 p)
 {
@@ -630,17 +627,17 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
 		return ~0U;
 	}
 
-	if (p <= TFRC_CALC_X_SPLIT) 		{     /* 0.0000 < p <= 0.05   */
+	if (p <= TFRC_CALC_X_SPLIT)		{     /* 0.0000 < p <= 0.05   */
 		if (p < TFRC_SMALLEST_P) {	      /* 0.0000 < p <  0.0001 */
 			DCCP_WARN("Value of p (%d) below resolution. "
 				  "Substituting %d\n", p, TFRC_SMALLEST_P);
 			index = 0;
-		} else 				      /* 0.0001 <= p <= 0.05  */
+		} else				      /* 0.0001 <= p <= 0.05  */
 			index =  p/TFRC_SMALLEST_P - 1;
 
 		f = tfrc_calc_x_lookup[index][1];
 
-	} else {	 			      /* 0.05   <  p <= 1.00  */
+	} else {				      /* 0.05   <  p <= 1.00  */
 		index = p/(1000000/TFRC_CALC_X_ARRSIZE) - 1;
 
 		f = tfrc_calc_x_lookup[index][0];
@@ -661,7 +658,6 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
 
 /**
  *  tfrc_calc_x_reverse_lookup  -  try to find p given f(p)
- *
  *  @fvalue: function value to match, scaled by 1000000
  *  Returns closest match for p, also scaled by 1000000
  */
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index b04160a..972b8dc 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -213,7 +213,7 @@ static int dccp_feat_default_value(u8 feat_num)
  */
 static const char *dccp_feat_fname(const u8 feat)
 {
-	static const char *feature_names[] = {
+	static const char *const feature_names[] = {
 		[DCCPF_RESERVED]	= "Reserved",
 		[DCCPF_CCID]		= "CCID",
 		[DCCPF_SHORT_SEQNOS]	= "Allow Short Seqnos",
@@ -236,8 +236,9 @@ static const char *dccp_feat_fname(const u8 feat)
 	return feature_names[feat];
 }
 
-static const char *dccp_feat_sname[] = { "DEFAULT", "INITIALISING", "CHANGING",
-					 "UNSTABLE", "STABLE" };
+static const char *const dccp_feat_sname[] = {
+	"DEFAULT", "INITIALISING", "CHANGING", "UNSTABLE", "STABLE",
+};
 
 #ifdef CONFIG_IP_DCCP_DEBUG
 static const char *dccp_feat_oname(const u8 opt)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index a0a36c9..7302e14 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -880,7 +880,7 @@ discard_and_relse:
 	goto discard_it;
 }
 
-static struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
+static const struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
 	.queue_xmit	   = ip_queue_xmit,
 	.send_check	   = dccp_v4_send_check,
 	.rebuild_header	   = inet_sk_rebuild_header,
@@ -948,7 +948,7 @@ static struct proto dccp_v4_prot = {
 #endif
 };
 
-static struct net_protocol dccp_v4_protocol = {
+static const struct net_protocol dccp_v4_protocol = {
 	.handler	= dccp_v4_rcv,
 	.err_handler	= dccp_v4_err,
 	.no_policy	= 1,
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 3e70faa..e48ca5d 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -35,8 +35,8 @@
 
 /* The per-net dccp.v6_ctl_sk is used for sending RSTs and ACKs */
 
-static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
-static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
+static const struct inet_connection_sock_af_ops dccp_ipv6_mapped;
+static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
 
 static void dccp_v6_hash(struct sock *sk)
 {
@@ -1055,7 +1055,7 @@ failure:
 	return err;
 }
 
-static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
+static const struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
 	.queue_xmit	   = inet6_csk_xmit,
 	.send_check	   = dccp_v6_send_check,
 	.rebuild_header	   = inet6_sk_rebuild_header,
@@ -1076,7 +1076,7 @@ static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
 /*
  *	DCCP over IPv4 via INET6 API
  */
-static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
+static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
 	.queue_xmit	   = ip_queue_xmit,
 	.send_check	   = dccp_v4_send_check,
 	.rebuild_header	   = inet_sk_rebuild_header,
@@ -1152,13 +1152,13 @@ static struct proto dccp_v6_prot = {
 #endif
 };
 
-static struct inet6_protocol dccp_v6_protocol = {
+static const struct inet6_protocol dccp_v6_protocol = {
 	.handler	= dccp_v6_rcv,
 	.err_handler	= dccp_v6_err,
 	.flags		= INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
 };
 
-static struct proto_ops inet6_dccp_ops = {
+static const struct proto_ops inet6_dccp_ops = {
 	.family		   = PF_INET6,
 	.owner		   = THIS_MODULE,
 	.release	   = inet6_release,
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 1bca920..923db06 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -124,7 +124,7 @@ EXPORT_SYMBOL_GPL(dccp_done);
 
 const char *dccp_packet_name(const int type)
 {
-	static const char *dccp_packet_names[] = {
+	static const char *const dccp_packet_names[] = {
 		[DCCP_PKT_REQUEST]  = "REQUEST",
 		[DCCP_PKT_RESPONSE] = "RESPONSE",
 		[DCCP_PKT_DATA]	    = "DATA",
@@ -147,7 +147,7 @@ EXPORT_SYMBOL_GPL(dccp_packet_name);
 
 const char *dccp_state_name(const int state)
 {
-	static char *dccp_state_names[] = {
+	static const char *const dccp_state_names[] = {
 	[DCCP_OPEN]		= "OPEN",
 	[DCCP_REQUESTING]	= "REQUESTING",
 	[DCCP_PARTOPEN]		= "PARTOPEN",
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 923786b..794b5bf 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -59,7 +59,7 @@ static int dn_phase3_output(struct sk_buff *);
 /*
  * For talking to broadcast devices: Ethernet & PPP
  */
-static struct neigh_ops dn_long_ops = {
+static const struct neigh_ops dn_long_ops = {
 	.family =		AF_DECnet,
 	.error_report =		dn_long_error_report,
 	.output =		dn_long_output,
@@ -71,7 +71,7 @@ static struct neigh_ops dn_long_ops = {
 /*
  * For talking to pointopoint and multidrop devices: DDCMP and X.25
  */
-static struct neigh_ops dn_short_ops = {
+static const struct neigh_ops dn_short_ops = {
 	.family =		AF_DECnet,
 	.error_report =		dn_short_error_report,
 	.output =		dn_short_output,
@@ -83,7 +83,7 @@ static struct neigh_ops dn_short_ops = {
 /*
  * For talking to DECnet phase III nodes
  */
-static struct neigh_ops dn_phase3_ops = {
+static const struct neigh_ops dn_phase3_ops = {
 	.family =		AF_DECnet,
 	.error_report =		dn_short_error_report, /* Can use short version here */
 	.output =		dn_phase3_output,
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 1d6ca8a..9383d3e 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -774,7 +774,7 @@ static int dn_rt_bug(struct sk_buff *skb)
 
 	kfree_skb(skb);
 
-	return NET_RX_BAD;
+	return NET_RX_DROP;
 }
 
 static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 41055f3..4b0ea05 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -169,13 +169,13 @@ struct net_device *dsa_slave_create(struct dsa_switch *ds,
 				    int port, char *name);
 
 /* tag_dsa.c */
-int dsa_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t dsa_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /* tag_edsa.c */
-int edsa_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /* tag_trailer.c */
-int trailer_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev);
 
 
 #endif
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index 8fa25ba..cdf2d28 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -15,7 +15,7 @@
 
 #define DSA_HLEN	4
 
-int dsa_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t dsa_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	u8 *dsa_header;
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index 815607b..8f53948 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -16,7 +16,7 @@
 #define DSA_HLEN	4
 #define EDSA_HLEN	8
 
-int edsa_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	u8 *edsa_header;
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index 1c3e30c..a85c829 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -13,7 +13,7 @@
 #include <linux/netdevice.h>
 #include "dsa_priv.h"
 
-int trailer_xmit(struct sk_buff *skb, struct net_device *dev)
+netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	struct sk_buff *nskb;
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index f0bbc57..0e0254f 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -1073,7 +1073,7 @@ static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
 		skb->protocol = htons(ETH_P_IP);
 		skb_pull(skb, sizeof(struct ec_framehdr));
 		netif_rx(skb);
-		return 0;
+		return NET_RX_SUCCESS;
 	}
 
 	sk = ec_listening_socket(hdr->port, hdr->src_stn, hdr->src_net);
@@ -1084,7 +1084,7 @@ static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
 			    hdr->port))
 		goto drop;
 
-	return 0;
+	return NET_RX_SUCCESS;
 
 drop:
 	kfree_skb(skb);
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index f99338a..4068a9f 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,4 +1,4 @@
-obj-$(CONFIG_IEEE802154) +=	nl802154.o af_802154.o
+obj-$(CONFIG_IEEE802154) +=	nl802154.o af_802154.o wpan-class.o
 nl802154-y		:= netlink.o nl_policy.o
 af_802154-y		:= af_ieee802154.o raw.o dgram.o
 
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index af66180..cd949d5 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -34,8 +34,8 @@
 #include <net/tcp_states.h>
 #include <net/route.h>
 
-#include <net/ieee802154/af_ieee802154.h>
-#include <net/ieee802154/netdevice.h>
+#include <net/af_ieee802154.h>
+#include <net/ieee802154_netdev.h>
 
 #include "af802154.h"
 
@@ -147,9 +147,7 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
 	dev_load(sock_net(sk), ifr.ifr_name);
 	dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
 
-	if ((dev->type == ARPHRD_IEEE802154 ||
-	     dev->type == ARPHRD_IEEE802154_PHY) &&
-	    dev->netdev_ops->ndo_do_ioctl)
+	if (dev->type == ARPHRD_IEEE802154 && dev->netdev_ops->ndo_do_ioctl)
 		ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
 
 	if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index ba8b214..51593a4 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -26,9 +26,9 @@
 #include <linux/if_arp.h>
 #include <linux/list.h>
 #include <net/sock.h>
-#include <net/ieee802154/af_ieee802154.h>
-#include <net/ieee802154/mac_def.h>
-#include <net/ieee802154/netdevice.h>
+#include <net/af_ieee802154.h>
+#include <net/ieee802154.h>
+#include <net/ieee802154_netdev.h>
 
 #include <asm/ioctls.h>
 
@@ -40,9 +40,11 @@ static DEFINE_RWLOCK(dgram_lock);
 struct dgram_sock {
 	struct sock sk;
 
-	int bound;
 	struct ieee802154_addr src_addr;
 	struct ieee802154_addr dst_addr;
+
+	unsigned bound:1;
+	unsigned want_ack:1;
 };
 
 static inline struct dgram_sock *dgram_sk(const struct sock *sk)
@@ -50,7 +52,6 @@ static inline struct dgram_sock *dgram_sk(const struct sock *sk)
 	return container_of(sk, struct dgram_sock, sk);
 }
 
-
 static void dgram_hash(struct sock *sk)
 {
 	write_lock_bh(&dgram_lock);
@@ -73,6 +74,7 @@ static int dgram_init(struct sock *sk)
 
 	ro->dst_addr.addr_type = IEEE802154_ADDR_LONG;
 	ro->dst_addr.pan_id = 0xffff;
+	ro->want_ack = 1;
 	memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr));
 	return 0;
 }
@@ -86,18 +88,18 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
 {
 	struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
 	struct dgram_sock *ro = dgram_sk(sk);
-	int err = 0;
+	int err = -EINVAL;
 	struct net_device *dev;
 
+	lock_sock(sk);
+
 	ro->bound = 0;
 
 	if (len < sizeof(*addr))
-		return -EINVAL;
+		goto out;
 
 	if (addr->family != AF_IEEE802154)
-		return -EINVAL;
-
-	lock_sock(sk);
+		goto out;
 
 	dev = ieee802154_get_dev(sock_net(sk), &addr->addr);
 	if (!dev) {
@@ -113,6 +115,7 @@ static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
 	memcpy(&ro->src_addr, &addr->addr, sizeof(struct ieee802154_addr));
 
 	ro->bound = 1;
+	err = 0;
 out_put:
 	dev_put(dev);
 out:
@@ -235,7 +238,10 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
 
 	skb_reset_network_header(skb);
 
-	mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA | MAC_CB_FLAG_ACKREQ;
+	mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA;
+	if (ro->want_ack)
+		mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ;
+
 	mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
 	err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr,
 			ro->bound ? &ro->src_addr : NULL, size);
@@ -380,13 +386,59 @@ int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
 static int dgram_getsockopt(struct sock *sk, int level, int optname,
 		    char __user *optval, int __user *optlen)
 {
-	return -EOPNOTSUPP;
+	struct dgram_sock *ro = dgram_sk(sk);
+
+	int val, len;
+
+	if (level != SOL_IEEE802154)
+		return -EOPNOTSUPP;
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+
+	len = min_t(unsigned int, len, sizeof(int));
+
+	switch (optname) {
+	case WPAN_WANTACK:
+		val = ro->want_ack;
+		break;
+	default:
+		return -ENOPROTOOPT;
+	}
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+	if (copy_to_user(optval, &val, len))
+		return -EFAULT;
+	return 0;
 }
 
 static int dgram_setsockopt(struct sock *sk, int level, int optname,
-		    char __user *optval, int __user optlen)
+		    char __user *optval, int optlen)
 {
-	return -EOPNOTSUPP;
+	struct dgram_sock *ro = dgram_sk(sk);
+	int val;
+	int err = 0;
+
+	if (optlen < sizeof(int))
+		return -EINVAL;
+
+	if (get_user(val, (int __user *)optval))
+		return -EFAULT;
+
+	lock_sock(sk);
+
+	switch (optname) {
+	case WPAN_WANTACK:
+		ro->want_ack = !!val;
+		break;
+	default:
+		err = -ENOPROTOOPT;
+		break;
+	}
+
+	release_sock(sk);
+	return err;
 }
 
 struct proto ieee802154_dgram_prot = {
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 27eda9f..ca767bd 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -19,6 +19,7 @@
  * Written by:
  * Sergey Lapin <slapin@ossfans.org>
  * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ * Maxim Osipov <maxim.osipov@siemens.com>
  */
 
 #include <linux/kernel.h>
@@ -26,12 +27,15 @@
 #include <linux/netdevice.h>
 #include <net/netlink.h>
 #include <net/genetlink.h>
+#include <net/sock.h>
 #include <linux/nl802154.h>
-#include <net/ieee802154/af_ieee802154.h>
-#include <net/ieee802154/nl802154.h>
-#include <net/ieee802154/netdevice.h>
+#include <net/af_ieee802154.h>
+#include <net/nl802154.h>
+#include <net/ieee802154.h>
+#include <net/ieee802154_netdev.h>
 
 static unsigned int ieee802154_seq_num;
+static DEFINE_SPINLOCK(ieee802154_seq_lock);
 
 static struct genl_family ieee802154_coordinator_family = {
 	.id		= GENL_ID_GENERATE,
@@ -54,12 +58,15 @@ static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
 {
 	void *hdr;
 	struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+	unsigned long f;
 
 	if (!msg)
 		return NULL;
 
+	spin_lock_irqsave(&ieee802154_seq_lock, f);
 	hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
 			&ieee802154_coordinator_family, flags, req);
+	spin_unlock_irqrestore(&ieee802154_seq_lock, f);
 	if (!hdr) {
 		nlmsg_free(msg);
 		return NULL;
@@ -73,7 +80,7 @@ static int ieee802154_nl_finish(struct sk_buff *msg)
 	/* XXX: nlh is right at the start of msg */
 	void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
 
-	if (!genlmsg_end(msg, hdr))
+	if (genlmsg_end(msg, hdr) < 0)
 		goto out;
 
 	return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id,
@@ -229,7 +236,7 @@ nla_put_failure:
 EXPORT_SYMBOL(ieee802154_nl_beacon_indic);
 
 int ieee802154_nl_scan_confirm(struct net_device *dev,
-		u8 status, u8 scan_type, u32 unscanned,
+		u8 status, u8 scan_type, u32 unscanned, u8 page,
 		u8 *edl/* , struct list_head *pan_desc_list */)
 {
 	struct sk_buff *msg;
@@ -248,6 +255,7 @@ int ieee802154_nl_scan_confirm(struct net_device *dev,
 	NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
 	NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type);
 	NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned);
+	NLA_PUT_U8(msg, IEEE802154_ATTR_PAGE, page);
 
 	if (edl)
 		NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);
@@ -260,6 +268,60 @@ nla_put_failure:
 }
 EXPORT_SYMBOL(ieee802154_nl_scan_confirm);
 
+int ieee802154_nl_start_confirm(struct net_device *dev, u8 status)
+{
+	struct sk_buff *msg;
+
+	pr_debug("%s\n", __func__);
+
+	msg = ieee802154_nl_create(0, IEEE802154_START_CONF);
+	if (!msg)
+		return -ENOBUFS;
+
+	NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+	NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+	NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+			dev->dev_addr);
+
+	NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
+
+	return ieee802154_nl_finish(msg);
+
+nla_put_failure:
+	nlmsg_free(msg);
+	return -ENOBUFS;
+}
+EXPORT_SYMBOL(ieee802154_nl_start_confirm);
+
+static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid,
+	u32 seq, int flags, struct net_device *dev)
+{
+	void *hdr;
+
+	pr_debug("%s\n", __func__);
+
+	hdr = genlmsg_put(msg, 0, seq, &ieee802154_coordinator_family, flags,
+		IEEE802154_LIST_IFACE);
+	if (!hdr)
+		goto out;
+
+	NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+	NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+
+	NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+		dev->dev_addr);
+	NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR,
+		ieee802154_mlme_ops(dev)->get_short_addr(dev));
+	NLA_PUT_U16(msg, IEEE802154_ATTR_PAN_ID,
+		ieee802154_mlme_ops(dev)->get_pan_id(dev));
+	return genlmsg_end(msg, hdr);
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+out:
+	return -EMSGSIZE;
+}
+
 /* Requests from userspace */
 static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
 {
@@ -272,7 +334,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
 		dev = dev_get_by_name(&init_net, name);
 	} else if (info->attrs[IEEE802154_ATTR_DEV_INDEX])
 		dev = dev_get_by_index(&init_net,
-				nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX]));
+			nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX]));
 	else
 		return NULL;
 
@@ -292,6 +354,7 @@ static int ieee802154_associate_req(struct sk_buff *skb,
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
+	u8 page;
 	int ret = -EINVAL;
 
 	if (!info->attrs[IEEE802154_ATTR_CHANNEL] ||
@@ -317,8 +380,14 @@ static int ieee802154_associate_req(struct sk_buff *skb,
 	}
 	addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);
 
+	if (info->attrs[IEEE802154_ATTR_PAGE])
+		page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
+	else
+		page = 0;
+
 	ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr,
 			nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]),
+			page,
 			nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY]));
 
 	dev_put(dev);
@@ -401,6 +470,7 @@ static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
 	struct ieee802154_addr addr;
 
 	u8 channel, bcn_ord, sf_ord;
+	u8 page;
 	int pan_coord, blx, coord_realign;
 	int ret;
 
@@ -431,7 +501,19 @@ static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
 	blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]);
 	coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]);
 
-	ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel,
+	if (info->attrs[IEEE802154_ATTR_PAGE])
+		page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
+	else
+		page = 0;
+
+
+	if (addr.short_addr == IEEE802154_ADDR_BROADCAST) {
+		ieee802154_nl_start_confirm(dev, IEEE802154_NO_SHORT_ADDRESS);
+		dev_put(dev);
+		return -EINVAL;
+	}
+
+	ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel, page,
 		bcn_ord, sf_ord, pan_coord, blx, coord_realign);
 
 	dev_put(dev);
@@ -445,6 +527,7 @@ static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
 	u8 type;
 	u32 channels;
 	u8 duration;
+	u8 page;
 
 	if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] ||
 	    !info->attrs[IEEE802154_ATTR_CHANNELS] ||
@@ -459,13 +542,80 @@ static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
 	channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]);
 	duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]);
 
-	ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels,
+	if (info->attrs[IEEE802154_ATTR_PAGE])
+		page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]);
+	else
+		page = 0;
+
+
+	ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, page,
 			duration);
 
 	dev_put(dev);
 	return ret;
 }
 
+static int ieee802154_list_iface(struct sk_buff *skb,
+	struct genl_info *info)
+{
+	/* Request for interface name, index, type, IEEE address,
+	   PAN Id, short address */
+	struct sk_buff *msg;
+	struct net_device *dev = NULL;
+	int rc = -ENOBUFS;
+
+	pr_debug("%s\n", __func__);
+
+	dev = ieee802154_nl_get_dev(info);
+	if (!dev)
+		return -ENODEV;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg)
+		goto out_dev;
+
+	rc = ieee802154_nl_fill_iface(msg, info->snd_pid, info->snd_seq,
+			0, dev);
+	if (rc < 0)
+		goto out_free;
+
+	dev_put(dev);
+
+	return genlmsg_unicast(&init_net, msg, info->snd_pid);
+out_free:
+	nlmsg_free(msg);
+out_dev:
+	dev_put(dev);
+	return rc;
+
+}
+
+static int ieee802154_dump_iface(struct sk_buff *skb,
+	struct netlink_callback *cb)
+{
+	struct net *net = sock_net(skb->sk);
+	struct net_device *dev;
+	int idx;
+	int s_idx = cb->args[0];
+
+	pr_debug("%s\n", __func__);
+
+	idx = 0;
+	for_each_netdev(net, dev) {
+		if (idx < s_idx || (dev->type != ARPHRD_IEEE802154))
+			goto cont;
+
+		if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).pid,
+			cb->nlh->nlmsg_seq, NLM_F_MULTI, dev) < 0)
+			break;
+cont:
+		idx++;
+	}
+	cb->args[0] = idx;
+
+	return skb->len;
+}
+
 #define IEEE802154_OP(_cmd, _func)			\
 	{						\
 		.cmd	= _cmd,				\
@@ -475,12 +625,22 @@ static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
 		.flags	= GENL_ADMIN_PERM,		\
 	}
 
+#define IEEE802154_DUMP(_cmd, _func, _dump)		\
+	{						\
+		.cmd	= _cmd,				\
+		.policy	= ieee802154_policy,		\
+		.doit	= _func,			\
+		.dumpit	= _dump,			\
+	}
+
 static struct genl_ops ieee802154_coordinator_ops[] = {
 	IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
 	IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
 	IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
 	IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
 	IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
+	IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
+							ieee802154_dump_iface),
 };
 
 static int __init ieee802154_nl_init(void)
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
index c7d71d1..2363ebe 100644
--- a/net/ieee802154/nl_policy.c
+++ b/net/ieee802154/nl_policy.c
@@ -24,7 +24,7 @@
 
 #define NLA_HW_ADDR NLA_U64
 
-struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
+const struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
 	[IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, },
 	[IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, },
 
@@ -33,6 +33,7 @@ struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
 	[IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, },
 	[IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, },
 	[IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, },
+	[IEEE802154_ATTR_PAGE] = { .type = NLA_U8, },
 	[IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, },
 	[IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, },
 	[IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, },
@@ -50,3 +51,4 @@ struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
 	[IEEE802154_ATTR_DURATION] = { .type = NLA_U8, },
 	[IEEE802154_ATTR_ED_LIST] = { .len = 27 },
 };
+
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
index 9315977..1319885 100644
--- a/net/ieee802154/raw.c
+++ b/net/ieee802154/raw.c
@@ -26,7 +26,7 @@
 #include <linux/if_arp.h>
 #include <linux/list.h>
 #include <net/sock.h>
-#include <net/ieee802154/af_ieee802154.h>
+#include <net/af_ieee802154.h>
 
 #include "af802154.h"
 
@@ -74,8 +74,7 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len)
 		goto out;
 	}
 
-	if (dev->type != ARPHRD_IEEE802154_PHY &&
-	    dev->type != ARPHRD_IEEE802154) {
+	if (dev->type != ARPHRD_IEEE802154) {
 		err = -ENODEV;
 		goto out_put;
 	}
@@ -245,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
 }
 
 static int raw_setsockopt(struct sock *sk, int level, int optname,
-		    char __user *optval, int __user optlen)
+		    char __user *optval, int optlen)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
new file mode 100644
index 0000000..f306604
--- /dev/null
+++ b/net/ieee802154/wpan-class.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/device.h>
+
+#include <net/wpan-phy.h>
+
+#define MASTER_SHOW_COMPLEX(name, format_string, args...)		\
+static ssize_t name ## _show(struct device *dev,			\
+			    struct device_attribute *attr, char *buf)	\
+{									\
+	struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);	\
+	int ret;							\
+									\
+	mutex_lock(&phy->pib_lock);					\
+	ret = sprintf(buf, format_string "\n", args);			\
+	mutex_unlock(&phy->pib_lock);					\
+	return ret;							\
+}
+
+#define MASTER_SHOW(field, format_string)				\
+	MASTER_SHOW_COMPLEX(field, format_string, phy->field)
+
+MASTER_SHOW(current_channel, "%d");
+MASTER_SHOW(current_page, "%d");
+MASTER_SHOW(channels_supported, "%#x");
+MASTER_SHOW_COMPLEX(transmit_power, "%d +- %d dB",
+	((signed char) (phy->transmit_power << 2)) >> 2,
+	(phy->transmit_power >> 6) ? (phy->transmit_power >> 6) * 3 : 1 );
+MASTER_SHOW(cca_mode, "%d");
+
+static struct device_attribute pmib_attrs[] = {
+	__ATTR_RO(current_channel),
+	__ATTR_RO(current_page),
+	__ATTR_RO(channels_supported),
+	__ATTR_RO(transmit_power),
+	__ATTR_RO(cca_mode),
+	{},
+};
+
+static void wpan_phy_release(struct device *d)
+{
+	struct wpan_phy *phy = container_of(d, struct wpan_phy, dev);
+	kfree(phy);
+}
+
+static struct class wpan_phy_class = {
+	.name = "ieee802154",
+	.dev_release = wpan_phy_release,
+	.dev_attrs = pmib_attrs,
+};
+
+static DEFINE_MUTEX(wpan_phy_mutex);
+static int wpan_phy_idx;
+
+static int wpan_phy_match(struct device *dev, void *data)
+{
+	return !strcmp(dev_name(dev), (const char *)data);
+}
+
+struct wpan_phy *wpan_phy_find(const char *str)
+{
+	struct device *dev;
+
+	if (WARN_ON(!str))
+		return NULL;
+
+	dev = class_find_device(&wpan_phy_class, NULL,
+			(void *)str, wpan_phy_match);
+	if (!dev)
+		return NULL;
+
+	return container_of(dev, struct wpan_phy, dev);
+}
+EXPORT_SYMBOL(wpan_phy_find);
+
+static int wpan_phy_idx_valid(int idx)
+{
+	return idx >= 0;
+}
+
+struct wpan_phy *wpan_phy_alloc(size_t priv_size)
+{
+	struct wpan_phy *phy = kzalloc(sizeof(*phy) + priv_size,
+			GFP_KERNEL);
+
+	mutex_lock(&wpan_phy_mutex);
+	phy->idx = wpan_phy_idx++;
+	if (unlikely(!wpan_phy_idx_valid(phy->idx))) {
+		wpan_phy_idx--;
+		mutex_unlock(&wpan_phy_mutex);
+		kfree(phy);
+		return NULL;
+	}
+	mutex_unlock(&wpan_phy_mutex);
+
+	mutex_init(&phy->pib_lock);
+
+	device_initialize(&phy->dev);
+	dev_set_name(&phy->dev, "wpan-phy%d", phy->idx);
+
+	phy->dev.class = &wpan_phy_class;
+
+	return phy;
+}
+EXPORT_SYMBOL(wpan_phy_alloc);
+
+int wpan_phy_register(struct device *parent, struct wpan_phy *phy)
+{
+	phy->dev.parent = parent;
+
+	return device_add(&phy->dev);
+}
+EXPORT_SYMBOL(wpan_phy_register);
+
+void wpan_phy_unregister(struct wpan_phy *phy)
+{
+	device_del(&phy->dev);
+}
+EXPORT_SYMBOL(wpan_phy_unregister);
+
+void wpan_phy_free(struct wpan_phy *phy)
+{
+	put_device(&phy->dev);
+}
+EXPORT_SYMBOL(wpan_phy_free);
+
+static int __init wpan_phy_class_init(void)
+{
+	return class_register(&wpan_phy_class);
+}
+subsys_initcall(wpan_phy_class_init);
+
+static void __exit wpan_phy_class_exit(void)
+{
+	class_unregister(&wpan_phy_class);
+}
+module_exit(wpan_phy_class_exit);
+
+MODULE_DESCRIPTION("IEEE 802.15.4 device class");
+MODULE_LICENSE("GPL v2");
+
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 566ea6c..58c4b0f 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -124,7 +124,6 @@ static struct list_head inetsw[SOCK_MAX];
 static DEFINE_SPINLOCK(inetsw_lock);
 
 struct ipv4_config ipv4_config;
-
 EXPORT_SYMBOL(ipv4_config);
 
 /* New destruction routine */
@@ -139,12 +138,12 @@ void inet_sock_destruct(struct sock *sk)
 	sk_mem_reclaim(sk);
 
 	if (sk->sk_type == SOCK_STREAM && sk->sk_state != TCP_CLOSE) {
-		printk("Attempt to release TCP socket in state %d %p\n",
+		pr_err("Attempt to release TCP socket in state %d %p\n",
 		       sk->sk_state, sk);
 		return;
 	}
 	if (!sock_flag(sk, SOCK_DEAD)) {
-		printk("Attempt to release alive inet socket %p\n", sk);
+		pr_err("Attempt to release alive inet socket %p\n", sk);
 		return;
 	}
 
@@ -157,6 +156,7 @@ void inet_sock_destruct(struct sock *sk)
 	dst_release(sk->sk_dst_cache);
 	sk_refcnt_debug_dec(sk);
 }
+EXPORT_SYMBOL(inet_sock_destruct);
 
 /*
  *	The routines beyond this point handle the behaviour of an AF_INET
@@ -219,6 +219,7 @@ out:
 	release_sock(sk);
 	return err;
 }
+EXPORT_SYMBOL(inet_listen);
 
 u32 inet_ehash_secret __read_mostly;
 EXPORT_SYMBOL(inet_ehash_secret);
@@ -243,7 +244,7 @@ EXPORT_SYMBOL(build_ehash_secret);
 static inline int inet_netns_ok(struct net *net, int protocol)
 {
 	int hash;
-	struct net_protocol *ipprot;
+	const struct net_protocol *ipprot;
 
 	if (net_eq(net, &init_net))
 		return 1;
@@ -435,9 +436,11 @@ int inet_release(struct socket *sock)
 	}
 	return 0;
 }
+EXPORT_SYMBOL(inet_release);
 
 /* It is off by default, see below. */
 int sysctl_ip_nonlocal_bind __read_mostly;
+EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
 
 int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
@@ -519,6 +522,7 @@ out_release_sock:
 out:
 	return err;
 }
+EXPORT_SYMBOL(inet_bind);
 
 int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
 		       int addr_len, int flags)
@@ -532,6 +536,7 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
 		return -EAGAIN;
 	return sk->sk_prot->connect(sk, (struct sockaddr *)uaddr, addr_len);
 }
+EXPORT_SYMBOL(inet_dgram_connect);
 
 static long inet_wait_for_connect(struct sock *sk, long timeo)
 {
@@ -641,6 +646,7 @@ sock_error:
 		sock->state = SS_DISCONNECTING;
 	goto out;
 }
+EXPORT_SYMBOL(inet_stream_connect);
 
 /*
  *	Accept a pending connection. The TCP layer now gives BSD semantics.
@@ -668,6 +674,7 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags)
 do_err:
 	return err;
 }
+EXPORT_SYMBOL(inet_accept);
 
 
 /*
@@ -699,6 +706,7 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
 	*uaddr_len = sizeof(*sin);
 	return 0;
 }
+EXPORT_SYMBOL(inet_getname);
 
 int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 		 size_t size)
@@ -711,9 +719,11 @@ int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 
 	return sk->sk_prot->sendmsg(iocb, sk, msg, size);
 }
+EXPORT_SYMBOL(inet_sendmsg);
 
 
-static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
+static ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
+			     size_t size, int flags)
 {
 	struct sock *sk = sock->sk;
 
@@ -780,6 +790,7 @@ int inet_shutdown(struct socket *sock, int how)
 	release_sock(sk);
 	return err;
 }
+EXPORT_SYMBOL(inet_shutdown);
 
 /*
  *	ioctl() calls you can issue on an INET socket. Most of these are
@@ -798,44 +809,45 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 	struct net *net = sock_net(sk);
 
 	switch (cmd) {
-		case SIOCGSTAMP:
-			err = sock_get_timestamp(sk, (struct timeval __user *)arg);
-			break;
-		case SIOCGSTAMPNS:
-			err = sock_get_timestampns(sk, (struct timespec __user *)arg);
-			break;
-		case SIOCADDRT:
-		case SIOCDELRT:
-		case SIOCRTMSG:
-			err = ip_rt_ioctl(net, cmd, (void __user *)arg);
-			break;
-		case SIOCDARP:
-		case SIOCGARP:
-		case SIOCSARP:
-			err = arp_ioctl(net, cmd, (void __user *)arg);
-			break;
-		case SIOCGIFADDR:
-		case SIOCSIFADDR:
-		case SIOCGIFBRDADDR:
-		case SIOCSIFBRDADDR:
-		case SIOCGIFNETMASK:
-		case SIOCSIFNETMASK:
-		case SIOCGIFDSTADDR:
-		case SIOCSIFDSTADDR:
-		case SIOCSIFPFLAGS:
-		case SIOCGIFPFLAGS:
-		case SIOCSIFFLAGS:
-			err = devinet_ioctl(net, cmd, (void __user *)arg);
-			break;
-		default:
-			if (sk->sk_prot->ioctl)
-				err = sk->sk_prot->ioctl(sk, cmd, arg);
-			else
-				err = -ENOIOCTLCMD;
-			break;
+	case SIOCGSTAMP:
+		err = sock_get_timestamp(sk, (struct timeval __user *)arg);
+		break;
+	case SIOCGSTAMPNS:
+		err = sock_get_timestampns(sk, (struct timespec __user *)arg);
+		break;
+	case SIOCADDRT:
+	case SIOCDELRT:
+	case SIOCRTMSG:
+		err = ip_rt_ioctl(net, cmd, (void __user *)arg);
+		break;
+	case SIOCDARP:
+	case SIOCGARP:
+	case SIOCSARP:
+		err = arp_ioctl(net, cmd, (void __user *)arg);
+		break;
+	case SIOCGIFADDR:
+	case SIOCSIFADDR:
+	case SIOCGIFBRDADDR:
+	case SIOCSIFBRDADDR:
+	case SIOCGIFNETMASK:
+	case SIOCSIFNETMASK:
+	case SIOCGIFDSTADDR:
+	case SIOCSIFDSTADDR:
+	case SIOCSIFPFLAGS:
+	case SIOCGIFPFLAGS:
+	case SIOCSIFFLAGS:
+		err = devinet_ioctl(net, cmd, (void __user *)arg);
+		break;
+	default:
+		if (sk->sk_prot->ioctl)
+			err = sk->sk_prot->ioctl(sk, cmd, arg);
+		else
+			err = -ENOIOCTLCMD;
+		break;
 	}
 	return err;
 }
+EXPORT_SYMBOL(inet_ioctl);
 
 const struct proto_ops inet_stream_ops = {
 	.family		   = PF_INET,
@@ -862,6 +874,7 @@ const struct proto_ops inet_stream_ops = {
 	.compat_getsockopt = compat_sock_common_getsockopt,
 #endif
 };
+EXPORT_SYMBOL(inet_stream_ops);
 
 const struct proto_ops inet_dgram_ops = {
 	.family		   = PF_INET,
@@ -887,6 +900,7 @@ const struct proto_ops inet_dgram_ops = {
 	.compat_getsockopt = compat_sock_common_getsockopt,
 #endif
 };
+EXPORT_SYMBOL(inet_dgram_ops);
 
 /*
  * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without
@@ -1016,6 +1030,7 @@ out_illegal:
 	       p->type);
 	goto out;
 }
+EXPORT_SYMBOL(inet_register_protosw);
 
 void inet_unregister_protosw(struct inet_protosw *p)
 {
@@ -1031,6 +1046,7 @@ void inet_unregister_protosw(struct inet_protosw *p)
 		synchronize_net();
 	}
 }
+EXPORT_SYMBOL(inet_unregister_protosw);
 
 /*
  *      Shall we try to damage output packets if routing dev changes?
@@ -1141,13 +1157,12 @@ int inet_sk_rebuild_header(struct sock *sk)
 
 	return err;
 }
-
 EXPORT_SYMBOL(inet_sk_rebuild_header);
 
 static int inet_gso_send_check(struct sk_buff *skb)
 {
 	struct iphdr *iph;
-	struct net_protocol *ops;
+	const struct net_protocol *ops;
 	int proto;
 	int ihl;
 	int err = -EINVAL;
@@ -1183,10 +1198,11 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	struct iphdr *iph;
-	struct net_protocol *ops;
+	const struct net_protocol *ops;
 	int proto;
 	int ihl;
 	int id;
+	unsigned int offset = 0;
 
 	if (!(features & NETIF_F_V4_CSUM))
 		features &= ~NETIF_F_SG;
@@ -1229,7 +1245,14 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
 	skb = segs;
 	do {
 		iph = ip_hdr(skb);
-		iph->id = htons(id++);
+		if (proto == IPPROTO_UDP) {
+			iph->id = htons(id);
+			iph->frag_off = htons(offset >> 3);
+			if (skb->next != NULL)
+				iph->frag_off |= htons(IP_MF);
+			offset += (skb->len - skb->mac_len - iph->ihl * 4);
+		} else
+			iph->id = htons(id++);
 		iph->tot_len = htons(skb->len - skb->mac_len);
 		iph->check = 0;
 		iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
@@ -1242,7 +1265,7 @@ out:
 static struct sk_buff **inet_gro_receive(struct sk_buff **head,
 					 struct sk_buff *skb)
 {
-	struct net_protocol *ops;
+	const struct net_protocol *ops;
 	struct sk_buff **pp = NULL;
 	struct sk_buff *p;
 	struct iphdr *iph;
@@ -1319,7 +1342,7 @@ out:
 
 static int inet_gro_complete(struct sk_buff *skb)
 {
-	struct net_protocol *ops;
+	const struct net_protocol *ops;
 	struct iphdr *iph = ip_hdr(skb);
 	int proto = iph->protocol & (MAX_INET_PROTOS - 1);
 	int err = -ENOSYS;
@@ -1361,7 +1384,6 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family,
 	}
 	return rc;
 }
-
 EXPORT_SYMBOL_GPL(inet_ctl_sock_create);
 
 unsigned long snmp_fold_field(void *mib[], int offt)
@@ -1405,13 +1427,13 @@ void snmp_mib_free(void *ptr[2])
 EXPORT_SYMBOL_GPL(snmp_mib_free);
 
 #ifdef CONFIG_IP_MULTICAST
-static struct net_protocol igmp_protocol = {
+static const struct net_protocol igmp_protocol = {
 	.handler =	igmp_rcv,
 	.netns_ok =	1,
 };
 #endif
 
-static struct net_protocol tcp_protocol = {
+static const struct net_protocol tcp_protocol = {
 	.handler =	tcp_v4_rcv,
 	.err_handler =	tcp_v4_err,
 	.gso_send_check = tcp_v4_gso_send_check,
@@ -1422,14 +1444,16 @@ static struct net_protocol tcp_protocol = {
 	.netns_ok =	1,
 };
 
-static struct net_protocol udp_protocol = {
+static const struct net_protocol udp_protocol = {
 	.handler =	udp_rcv,
 	.err_handler =	udp_err,
+	.gso_send_check = udp4_ufo_send_check,
+	.gso_segment = udp4_ufo_fragment,
 	.no_policy =	1,
 	.netns_ok =	1,
 };
 
-static struct net_protocol icmp_protocol = {
+static const struct net_protocol icmp_protocol = {
 	.handler =	icmp_rcv,
 	.no_policy =	1,
 	.netns_ok =	1,
@@ -1666,19 +1690,3 @@ static int __init ipv4_proc_init(void)
 
 MODULE_ALIAS_NETPROTO(PF_INET);
 
-EXPORT_SYMBOL(inet_accept);
-EXPORT_SYMBOL(inet_bind);
-EXPORT_SYMBOL(inet_dgram_connect);
-EXPORT_SYMBOL(inet_dgram_ops);
-EXPORT_SYMBOL(inet_getname);
-EXPORT_SYMBOL(inet_ioctl);
-EXPORT_SYMBOL(inet_listen);
-EXPORT_SYMBOL(inet_register_protosw);
-EXPORT_SYMBOL(inet_release);
-EXPORT_SYMBOL(inet_sendmsg);
-EXPORT_SYMBOL(inet_shutdown);
-EXPORT_SYMBOL(inet_sock_destruct);
-EXPORT_SYMBOL(inet_stream_connect);
-EXPORT_SYMBOL(inet_stream_ops);
-EXPORT_SYMBOL(inet_unregister_protosw);
-EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index e878e49..5c66270 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -311,7 +311,7 @@ static const struct xfrm_type ah_type =
 	.output		= ah_output
 };
 
-static struct net_protocol ah4_protocol = {
+static const struct net_protocol ah4_protocol = {
 	.handler	=	xfrm4_rcv,
 	.err_handler	=	ah4_err,
 	.no_policy	=	1,
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 090e999..4e80f33 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -130,7 +130,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb);
 static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb);
 static void parp_redo(struct sk_buff *skb);
 
-static struct neigh_ops arp_generic_ops = {
+static const struct neigh_ops arp_generic_ops = {
 	.family =		AF_INET,
 	.solicit =		arp_solicit,
 	.error_report =		arp_error_report,
@@ -140,7 +140,7 @@ static struct neigh_ops arp_generic_ops = {
 	.queue_xmit =		dev_queue_xmit,
 };
 
-static struct neigh_ops arp_hh_ops = {
+static const struct neigh_ops arp_hh_ops = {
 	.family =		AF_INET,
 	.solicit =		arp_solicit,
 	.error_report =		arp_error_report,
@@ -150,7 +150,7 @@ static struct neigh_ops arp_hh_ops = {
 	.queue_xmit =		dev_queue_xmit,
 };
 
-static struct neigh_ops arp_direct_ops = {
+static const struct neigh_ops arp_direct_ops = {
 	.family =		AF_INET,
 	.output =		dev_queue_xmit,
 	.connected_output =	dev_queue_xmit,
@@ -158,7 +158,7 @@ static struct neigh_ops arp_direct_ops = {
 	.queue_xmit =		dev_queue_xmit,
 };
 
-struct neigh_ops arp_broken_ops = {
+const struct neigh_ops arp_broken_ops = {
 	.family =		AF_INET,
 	.solicit =		arp_solicit,
 	.error_report =		arp_error_report,
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 3863c3a..07336c6 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1087,6 +1087,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
 	case NETDEV_DOWN:
 		ip_mc_down(in_dev);
 		break;
+	case NETDEV_BONDING_OLDTYPE:
+		ip_mc_unmap(in_dev);
+		break;
+	case NETDEV_BONDING_NEWTYPE:
+		ip_mc_remap(in_dev);
+		break;
 	case NETDEV_CHANGEMTU:
 		if (inetdev_valid_mtu(dev->mtu))
 			break;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 18bb383..12f7287 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -615,7 +615,7 @@ static const struct xfrm_type esp_type =
 	.output		= esp_output
 };
 
-static struct net_protocol esp4_protocol = {
+static const struct net_protocol esp4_protocol = {
 	.handler	=	xfrm4_rcv,
 	.err_handler	=	esp4_err,
 	.no_policy	=	1,
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 63c2fa7..291bdf5 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -48,7 +48,7 @@
  *		Patrick McHardy <kaber@trash.net>
  */
 
-#define VERSION "0.408"
+#define VERSION "0.409"
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -164,6 +164,14 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn);
 static struct tnode *halve(struct trie *t, struct tnode *tn);
 /* tnodes to free after resize(); protected by RTNL */
 static struct tnode *tnode_free_head;
+static size_t tnode_free_size;
+
+/*
+ * synchronize_rcu after call_rcu for that many pages; it should be especially
+ * useful before resizing the root node with PREEMPT_NONE configs; the value was
+ * obtained experimentally, aiming to avoid visible slowdown.
+ */
+static const int sync_pages = 128;
 
 static struct kmem_cache *fn_alias_kmem __read_mostly;
 static struct kmem_cache *trie_leaf_kmem __read_mostly;
@@ -317,8 +325,7 @@ static inline void check_tnode(const struct tnode *tn)
 static const int halve_threshold = 25;
 static const int inflate_threshold = 50;
 static const int halve_threshold_root = 15;
-static const int inflate_threshold_root = 25;
-
+static const int inflate_threshold_root = 30;
 
 static void __alias_free_mem(struct rcu_head *head)
 {
@@ -393,6 +400,8 @@ static void tnode_free_safe(struct tnode *tn)
 	BUG_ON(IS_LEAF(tn));
 	tn->tnode_free = tnode_free_head;
 	tnode_free_head = tn;
+	tnode_free_size += sizeof(struct tnode) +
+			   (sizeof(struct node *) << tn->bits);
 }
 
 static void tnode_free_flush(void)
@@ -404,6 +413,11 @@ static void tnode_free_flush(void)
 		tn->tnode_free = NULL;
 		tnode_free(tn);
 	}
+
+	if (tnode_free_size >= PAGE_SIZE * sync_pages) {
+		tnode_free_size = 0;
+		synchronize_rcu();
+	}
 }
 
 static struct leaf *leaf_new(void)
@@ -499,14 +513,14 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
 	rcu_assign_pointer(tn->child[i], n);
 }
 
+#define MAX_WORK 10
 static struct node *resize(struct trie *t, struct tnode *tn)
 {
 	int i;
-	int err = 0;
 	struct tnode *old_tn;
 	int inflate_threshold_use;
 	int halve_threshold_use;
-	int max_resize;
+	int max_work;
 
 	if (!tn)
 		return NULL;
@@ -521,18 +535,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 	}
 	/* One child */
 	if (tn->empty_children == tnode_child_length(tn) - 1)
-		for (i = 0; i < tnode_child_length(tn); i++) {
-			struct node *n;
-
-			n = tn->child[i];
-			if (!n)
-				continue;
-
-			/* compress one level */
-			node_set_parent(n, NULL);
-			tnode_free_safe(tn);
-			return n;
-		}
+		goto one_child;
 	/*
 	 * Double as long as the resulting node has a number of
 	 * nonempty nodes that are above the threshold.
@@ -601,14 +604,17 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 
 	/* Keep root node larger  */
 
-	if (!tn->parent)
+	if (!node_parent((struct node*) tn)) {
 		inflate_threshold_use = inflate_threshold_root;
-	else
+		halve_threshold_use = halve_threshold_root;
+	}
+	else {
 		inflate_threshold_use = inflate_threshold;
+		halve_threshold_use = halve_threshold;
+	}
 
-	err = 0;
-	max_resize = 10;
-	while ((tn->full_children > 0 &&  max_resize-- &&
+	max_work = MAX_WORK;
+	while ((tn->full_children > 0 &&  max_work-- &&
 		50 * (tn->full_children + tnode_child_length(tn)
 		      - tn->empty_children)
 		>= inflate_threshold_use * tnode_child_length(tn))) {
@@ -625,35 +631,19 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 		}
 	}
 
-	if (max_resize < 0) {
-		if (!tn->parent)
-			pr_warning("Fix inflate_threshold_root."
-				   " Now=%d size=%d bits\n",
-				   inflate_threshold_root, tn->bits);
-		else
-			pr_warning("Fix inflate_threshold."
-				   " Now=%d size=%d bits\n",
-				   inflate_threshold, tn->bits);
-	}
-
 	check_tnode(tn);
 
+	/* Return if at least one inflate is run */
+	if( max_work != MAX_WORK)
+		return (struct node *) tn;
+
 	/*
 	 * Halve as long as the number of empty children in this
 	 * node is above threshold.
 	 */
 
-
-	/* Keep root node larger  */
-
-	if (!tn->parent)
-		halve_threshold_use = halve_threshold_root;
-	else
-		halve_threshold_use = halve_threshold;
-
-	err = 0;
-	max_resize = 10;
-	while (tn->bits > 1 &&  max_resize-- &&
+	max_work = MAX_WORK;
+	while (tn->bits > 1 &&  max_work-- &&
 	       100 * (tnode_child_length(tn) - tn->empty_children) <
 	       halve_threshold_use * tnode_child_length(tn)) {
 
@@ -668,19 +658,10 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 		}
 	}
 
-	if (max_resize < 0) {
-		if (!tn->parent)
-			pr_warning("Fix halve_threshold_root."
-				   " Now=%d size=%d bits\n",
-				   halve_threshold_root, tn->bits);
-		else
-			pr_warning("Fix halve_threshold."
-				   " Now=%d size=%d bits\n",
-				   halve_threshold, tn->bits);
-	}
 
 	/* Only one child remains */
-	if (tn->empty_children == tnode_child_length(tn) - 1)
+	if (tn->empty_children == tnode_child_length(tn) - 1) {
+one_child:
 		for (i = 0; i < tnode_child_length(tn); i++) {
 			struct node *n;
 
@@ -694,7 +675,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 			tnode_free_safe(tn);
 			return n;
 		}
-
+	}
 	return (struct node *) tn;
 }
 
@@ -1435,7 +1416,7 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
 			cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length),
 						   pos, bits);
 
-		n = tnode_get_child(pn, cindex);
+		n = tnode_get_child_rcu(pn, cindex);
 
 		if (n == NULL) {
 #ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -1570,7 +1551,7 @@ backtrace:
 		if (chopped_off <= pn->bits) {
 			cindex &= ~(1 << (chopped_off-1));
 		} else {
-			struct tnode *parent = node_parent((struct node *) pn);
+			struct tnode *parent = node_parent_rcu((struct node *) pn);
 			if (!parent)
 				goto failed;
 
@@ -1783,7 +1764,7 @@ static struct leaf *trie_firstleaf(struct trie *t)
 static struct leaf *trie_nextleaf(struct leaf *l)
 {
 	struct node *c = (struct node *) l;
-	struct tnode *p = node_parent(c);
+	struct tnode *p = node_parent_rcu(c);
 
 	if (!p)
 		return NULL;	/* trie with just one leaf */
@@ -2391,7 +2372,7 @@ static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s)
 	}
 }
 
-static const char *rtn_type_names[__RTN_MAX] = {
+static const char *const rtn_type_names[__RTN_MAX] = {
 	[RTN_UNSPEC] = "UNSPEC",
 	[RTN_UNICAST] = "UNICAST",
 	[RTN_LOCAL] = "LOCAL",
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 97c410e..5bc13fe 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -655,7 +655,7 @@ static void icmp_unreach(struct sk_buff *skb)
 	struct iphdr *iph;
 	struct icmphdr *icmph;
 	int hash, protocol;
-	struct net_protocol *ipprot;
+	const struct net_protocol *ipprot;
 	u32 info = 0;
 	struct net *net;
 
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 01b4284..d41e5de 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1298,6 +1298,28 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
 	}
 }
 
+/* Device changing type */
+
+void ip_mc_unmap(struct in_device *in_dev)
+{
+	struct ip_mc_list *i;
+
+	ASSERT_RTNL();
+
+	for (i = in_dev->mc_list; i; i = i->next)
+		igmp_group_dropped(i);
+}
+
+void ip_mc_remap(struct in_device *in_dev)
+{
+	struct ip_mc_list *i;
+
+	ASSERT_RTNL();
+
+	for (i = in_dev->mc_list; i; i = i->next)
+		igmp_group_added(i);
+}
+
 /* Device going down */
 
 void ip_mc_down(struct in_device *in_dev)
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index 61283f9..13f0781 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -218,8 +218,8 @@ void inet_twdr_hangman(unsigned long data)
 		/* We purged the entire slot, anything left?  */
 		if (twdr->tw_count)
 			need_timer = 1;
+		twdr->slot = ((twdr->slot + 1) & (INET_TWDR_TWKILL_SLOTS - 1));
 	}
-	twdr->slot = ((twdr->slot + 1) & (INET_TWDR_TWKILL_SLOTS - 1));
 	if (need_timer)
 		mod_timer(&twdr->tw_timer, jiffies + twdr->period);
 out:
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 82c11dd..d9645c9 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -662,7 +662,7 @@ drop_nolock:
 	return(0);
 }
 
-static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct net_device_stats *stats = &tunnel->dev->stats;
@@ -821,7 +821,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 			stats->tx_dropped++;
 			dev_kfree_skb(skb);
 			tunnel->recursion--;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 		if (skb->sk)
 			skb_set_owner_w(new_skb, skb->sk);
@@ -889,7 +889,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	IPTUNNEL_XMIT();
 	tunnel->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 
 tx_error_icmp:
 	dst_link_failure(skb);
@@ -898,7 +898,7 @@ tx_error:
 	stats->tx_errors++;
 	dev_kfree_skb(skb);
 	tunnel->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int ipgre_tunnel_bind_dev(struct net_device *dev)
@@ -1288,7 +1288,7 @@ static void ipgre_fb_tunnel_init(struct net_device *dev)
 }
 
 
-static struct net_protocol ipgre_protocol = {
+static const struct net_protocol ipgre_protocol = {
 	.handler	=	ipgre_rcv,
 	.err_handler	=	ipgre_err,
 	.netns_ok	=	1,
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index db46b4b..6c98b43 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -202,7 +202,7 @@ static int ip_local_deliver_finish(struct sk_buff *skb)
 	{
 		int protocol = ip_hdr(skb)->protocol;
 		int hash, raw;
-		struct net_protocol *ipprot;
+		const struct net_protocol *ipprot;
 
 	resubmit:
 		raw = raw_local_deliver(skb, protocol);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 7ffcd96..9fe5d7b 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1304,7 +1304,7 @@ int ip_push_pending_frames(struct sock *sk)
 	err = ip_local_out(skb);
 	if (err) {
 		if (err > 0)
-			err = inet->recverr ? net_xmit_errno(err) : 0;
+			err = net_xmit_errno(err);
 		if (err)
 			goto error;
 	}
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 3262ce0..38fbf04 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -146,7 +146,7 @@ static const struct xfrm_type ipcomp_type = {
 	.output		= ipcomp_output
 };
 
-static struct net_protocol ipcomp4_protocol = {
+static const struct net_protocol ipcomp4_protocol = {
 	.handler	=	xfrm4_rcv,
 	.err_handler	=	ipcomp4_err,
 	.no_policy	=	1,
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 93e2b78..62548cb 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -387,7 +387,7 @@ static int ipip_rcv(struct sk_buff *skb)
  *	and that skb is filled properly by that function.
  */
 
-static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct net_device_stats *stats = &tunnel->dev->stats;
@@ -486,7 +486,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 			stats->tx_dropped++;
 			dev_kfree_skb(skb);
 			tunnel->recursion--;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 		if (skb->sk)
 			skb_set_owner_w(new_skb, skb->sk);
@@ -524,7 +524,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	IPTUNNEL_XMIT();
 	tunnel->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 
 tx_error_icmp:
 	dst_link_failure(skb);
@@ -532,7 +532,7 @@ tx_error:
 	stats->tx_errors++;
 	dev_kfree_skb(skb);
 	tunnel->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void ipip_tunnel_bind_dev(struct net_device *dev)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 9a8da5e..c43ec2d 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -99,10 +99,6 @@ static int ipmr_cache_report(struct net *net,
 			     struct sk_buff *pkt, vifi_t vifi, int assert);
 static int ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm);
 
-#ifdef CONFIG_IP_PIMSM_V2
-static struct net_protocol pim_protocol;
-#endif
-
 static struct timer_list ipmr_expire_timer;
 
 /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */
@@ -201,7 +197,7 @@ failure:
 
 #ifdef CONFIG_IP_PIMSM
 
-static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net *net = dev_net(dev);
 
@@ -212,7 +208,7 @@ static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
 			  IGMPMSG_WHOLEPKT);
 	read_unlock(&mrt_lock);
 	kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static const struct net_device_ops reg_vif_netdev_ops = {
@@ -1945,7 +1941,7 @@ static const struct file_operations ipmr_mfc_fops = {
 #endif
 
 #ifdef CONFIG_IP_PIMSM_V2
-static struct net_protocol pim_protocol = {
+static const struct net_protocol pim_protocol = {
 	.handler	=	pim_rcv,
 	.netns_ok	=	1,
 };
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7505dff..27774c9 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -8,7 +8,7 @@
  * Copyright (C) 2002 David S. Miller (davem@redhat.com)
  *
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
@@ -341,15 +341,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 }
 
 /* All zeroes == unconditional rule. */
-static inline int unconditional(const struct arpt_arp *arp)
+static inline bool unconditional(const struct arpt_arp *arp)
 {
-	unsigned int i;
+	static const struct arpt_arp uncond;
 
-	for (i = 0; i < sizeof(*arp)/sizeof(__u32); i++)
-		if (((__u32 *)arp)[i])
-			return 0;
-
-	return 1;
+	return memcmp(arp, &uncond, sizeof(uncond)) == 0;
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
@@ -537,12 +533,28 @@ out:
 	return ret;
 }
 
+static bool check_underflow(struct arpt_entry *e)
+{
+	const struct arpt_entry_target *t;
+	unsigned int verdict;
+
+	if (!unconditional(&e->arp))
+		return false;
+	t = arpt_get_target(e);
+	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
+		return false;
+	verdict = ((struct arpt_standard_target *)t)->verdict;
+	verdict = -verdict - 1;
+	return verdict == NF_DROP || verdict == NF_ACCEPT;
+}
+
 static inline int check_entry_size_and_hooks(struct arpt_entry *e,
 					     struct xt_table_info *newinfo,
 					     unsigned char *base,
 					     unsigned char *limit,
 					     const unsigned int *hook_entries,
 					     const unsigned int *underflows,
+					     unsigned int valid_hooks,
 					     unsigned int *i)
 {
 	unsigned int h;
@@ -562,15 +574,21 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
 
 	/* Check hooks & underflows */
 	for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
+		if (!(valid_hooks & (1 << h)))
+			continue;
 		if ((unsigned char *)e - base == hook_entries[h])
 			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
+		if ((unsigned char *)e - base == underflows[h]) {
+			if (!check_underflow(e)) {
+				pr_err("Underflows must be unconditional and "
+				       "use the STANDARD target with "
+				       "ACCEPT/DROP\n");
+				return -EINVAL;
+			}
 			newinfo->underflow[h] = underflows[h];
+		}
 	}
 
-	/* FIXME: underflows must be unconditional, standard verdicts
-	   < 0 (not ARPT_RETURN). --RR */
-
 	/* Clear counters and comefrom */
 	e->counters = ((struct xt_counters) { 0, 0 });
 	e->comefrom = 0;
@@ -630,7 +648,7 @@ static int translate_table(const char *name,
 				 newinfo,
 				 entry0,
 				 entry0 + size,
-				 hook_entries, underflows, &i);
+				 hook_entries, underflows, valid_hooks, &i);
 	duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
 	if (ret != 0)
 		return ret;
@@ -1760,7 +1778,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
 	return ret;
 }
 
-struct xt_table *arpt_register_table(struct net *net, struct xt_table *table,
+struct xt_table *arpt_register_table(struct net *net,
+				     const struct xt_table *table,
 				     const struct arpt_replace *repl)
 {
 	int ret;
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 6ecfdae..9733760 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -15,7 +15,7 @@ MODULE_DESCRIPTION("arptables filter table");
 #define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
 			   (1 << NF_ARP_FORWARD))
 
-static struct
+static const struct
 {
 	struct arpt_replace repl;
 	struct arpt_standard entries[3];
@@ -45,7 +45,7 @@ static struct
 	.term = ARPT_ERROR_INIT,
 };
 
-static struct xt_table packet_filter = {
+static const struct xt_table packet_filter = {
 	.name		= "filter",
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.me		= THIS_MODULE,
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index fdefae6..cde755d 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -8,6 +8,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/cache.h>
 #include <linux/capability.h>
 #include <linux/skbuff.h>
@@ -190,16 +191,11 @@ get_entry(void *base, unsigned int offset)
 
 /* All zeroes == unconditional rule. */
 /* Mildly perf critical (only if packet tracing is on) */
-static inline int
-unconditional(const struct ipt_ip *ip)
+static inline bool unconditional(const struct ipt_ip *ip)
 {
-	unsigned int i;
-
-	for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
-		if (((__u32 *)ip)[i])
-			return 0;
+	static const struct ipt_ip uncond;
 
-	return 1;
+	return memcmp(ip, &uncond, sizeof(uncond)) == 0;
 #undef FWINV
 }
 
@@ -315,7 +311,6 @@ ipt_do_table(struct sk_buff *skb,
 
 	static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
 	const struct iphdr *ip;
-	u_int16_t datalen;
 	bool hotdrop = false;
 	/* Initializing verdict to NF_DROP keeps gcc happy. */
 	unsigned int verdict = NF_DROP;
@@ -328,7 +323,6 @@ ipt_do_table(struct sk_buff *skb,
 
 	/* Initialization */
 	ip = ip_hdr(skb);
-	datalen = skb->len - ip->ihl * 4;
 	indev = in ? in->name : nulldevname;
 	outdev = out ? out->name : nulldevname;
 	/* We handle fragments by dealing with the first fragment as
@@ -427,8 +421,6 @@ ipt_do_table(struct sk_buff *skb,
 #endif
 		/* Target might have changed stuff. */
 		ip = ip_hdr(skb);
-		datalen = skb->len - ip->ihl * 4;
-
 		if (verdict == IPT_CONTINUE)
 			e = ipt_next_entry(e);
 		else
@@ -716,6 +708,21 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
 	return ret;
 }
 
+static bool check_underflow(struct ipt_entry *e)
+{
+	const struct ipt_entry_target *t;
+	unsigned int verdict;
+
+	if (!unconditional(&e->ip))
+		return false;
+	t = ipt_get_target(e);
+	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
+		return false;
+	verdict = ((struct ipt_standard_target *)t)->verdict;
+	verdict = -verdict - 1;
+	return verdict == NF_DROP || verdict == NF_ACCEPT;
+}
+
 static int
 check_entry_size_and_hooks(struct ipt_entry *e,
 			   struct xt_table_info *newinfo,
@@ -723,6 +730,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
 			   unsigned char *limit,
 			   const unsigned int *hook_entries,
 			   const unsigned int *underflows,
+			   unsigned int valid_hooks,
 			   unsigned int *i)
 {
 	unsigned int h;
@@ -742,15 +750,21 @@ check_entry_size_and_hooks(struct ipt_entry *e,
 
 	/* Check hooks & underflows */
 	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+		if (!(valid_hooks & (1 << h)))
+			continue;
 		if ((unsigned char *)e - base == hook_entries[h])
 			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
+		if ((unsigned char *)e - base == underflows[h]) {
+			if (!check_underflow(e)) {
+				pr_err("Underflows must be unconditional and "
+				       "use the STANDARD target with "
+				       "ACCEPT/DROP\n");
+				return -EINVAL;
+			}
 			newinfo->underflow[h] = underflows[h];
+		}
 	}
 
-	/* FIXME: underflows must be unconditional, standard verdicts
-	   < 0 (not IPT_RETURN). --RR */
-
 	/* Clear counters and comefrom */
 	e->counters = ((struct xt_counters) { 0, 0 });
 	e->comefrom = 0;
@@ -813,7 +827,7 @@ translate_table(const char *name,
 				newinfo,
 				entry0,
 				entry0 + size,
-				hook_entries, underflows, &i);
+				hook_entries, underflows, valid_hooks, &i);
 	if (ret != 0)
 		return ret;
 
@@ -2051,7 +2065,8 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 	return ret;
 }
 
-struct xt_table *ipt_register_table(struct net *net, struct xt_table *table,
+struct xt_table *ipt_register_table(struct net *net,
+				    const struct xt_table *table,
 				    const struct ipt_replace *repl)
 {
 	int ret;
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index c30a969..df566cb 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -53,11 +53,11 @@ static struct
 	.term = IPT_ERROR_INIT,			/* ERROR */
 };
 
-static struct xt_table packet_filter = {
+static const struct xt_table packet_filter = {
 	.name		= "filter",
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.me		= THIS_MODULE,
-	.af		= AF_INET,
+	.af		= NFPROTO_IPV4,
 };
 
 /* The work comes in here from netfilter.c. */
@@ -102,21 +102,21 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
 	{
 		.hook		= ipt_local_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 	{
 		.hook		= ipt_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP_PRI_FILTER,
 	},
 	{
 		.hook		= ipt_local_out_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_FILTER,
 	},
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 4087614..036047f 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -28,7 +28,7 @@ MODULE_DESCRIPTION("iptables mangle table");
 			    (1 << NF_INET_POST_ROUTING))
 
 /* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
-static struct
+static const struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[5];
@@ -64,11 +64,11 @@ static struct
 	.term = IPT_ERROR_INIT,			/* ERROR */
 };
 
-static struct xt_table packet_mangler = {
+static const struct xt_table packet_mangler = {
 	.name		= "mangle",
 	.valid_hooks	= MANGLE_VALID_HOOKS,
 	.me		= THIS_MODULE,
-	.af		= AF_INET,
+	.af		= NFPROTO_IPV4,
 };
 
 /* The work comes in here from netfilter.c. */
@@ -162,35 +162,35 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
 	{
 		.hook		= ipt_pre_routing_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_local_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_forward_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_local_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
 	{
 		.hook		= ipt_post_routing_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_MANGLE,
 	},
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index e5356da..993edc2 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -9,7 +9,7 @@
 
 #define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
 
-static struct
+static const struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[2];
@@ -36,11 +36,11 @@ static struct
 	.term = IPT_ERROR_INIT,			/* ERROR */
 };
 
-static struct xt_table packet_raw = {
+static const struct xt_table packet_raw = {
 	.name = "raw",
 	.valid_hooks =  RAW_VALID_HOOKS,
 	.me = THIS_MODULE,
-	.af = AF_INET,
+	.af = NFPROTO_IPV4,
 };
 
 /* The work comes in here from netfilter.c. */
@@ -74,14 +74,14 @@ ipt_local_hook(unsigned int hook,
 static struct nf_hook_ops ipt_ops[] __read_mostly = {
 	{
 		.hook = ipt_hook,
-		.pf = PF_INET,
+		.pf = NFPROTO_IPV4,
 		.hooknum = NF_INET_PRE_ROUTING,
 		.priority = NF_IP_PRI_RAW,
 		.owner = THIS_MODULE,
 	},
 	{
 		.hook = ipt_local_hook,
-		.pf = PF_INET,
+		.pf = NFPROTO_IPV4,
 		.hooknum = NF_INET_LOCAL_OUT,
 		.priority = NF_IP_PRI_RAW,
 		.owner = THIS_MODULE,
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index 29ab630..99eb76c 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("iptables security table, for MAC rules");
 				(1 << NF_INET_FORWARD) | \
 				(1 << NF_INET_LOCAL_OUT)
 
-static struct
+static const struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[3];
@@ -57,11 +57,11 @@ static struct
 	.term = IPT_ERROR_INIT,			/* ERROR */
 };
 
-static struct xt_table security_table = {
+static const struct xt_table security_table = {
 	.name		= "security",
 	.valid_hooks	= SECURITY_VALID_HOOKS,
 	.me		= THIS_MODULE,
-	.af		= AF_INET,
+	.af		= NFPROTO_IPV4,
 };
 
 static unsigned int
@@ -105,21 +105,21 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
 	{
 		.hook		= ipt_local_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_SECURITY,
 	},
 	{
 		.hook		= ipt_forward_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP_PRI_SECURITY,
 	},
 	{
 		.hook		= ipt_local_out_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_SECURITY,
 	},
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 7d2ead7..aa95bb8 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -26,6 +26,7 @@
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 #include <net/netfilter/nf_nat_helper.h>
 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
+#include <net/netfilter/nf_log.h>
 
 int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
 			      struct nf_conn *ct,
@@ -113,8 +114,11 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
 
 	ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
 			   ct, ctinfo);
-	if (ret != NF_ACCEPT)
+	if (ret != NF_ACCEPT) {
+		nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL,
+			      "nf_ct_%s: dropping packet", helper->name);
 		return ret;
+	}
 
 	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
 		typeof(nf_nat_seq_adjust_hook) seq_adjust;
@@ -158,28 +162,28 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
 	{
 		.hook		= ipv4_conntrack_in,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_CONNTRACK,
 	},
 	{
 		.hook		= ipv4_conntrack_local,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_CONNTRACK,
 	},
 	{
 		.hook		= ipv4_confirm,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
 	},
 	{
 		.hook		= ipv4_confirm,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_CONNTRACK_CONFIRM,
 	},
@@ -256,11 +260,11 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
 	tuple.dst.u3.ip = inet->daddr;
 	tuple.dst.u.tcp.port = inet->dport;
 	tuple.src.l3num = PF_INET;
-	tuple.dst.protonum = IPPROTO_TCP;
+	tuple.dst.protonum = sk->sk_protocol;
 
-	/* We only do TCP at the moment: is there a better way? */
-	if (strcmp(sk->sk_prot->name, "TCP")) {
-		pr_debug("SO_ORIGINAL_DST: Not a TCP socket\n");
+	/* We only do TCP and SCTP at the moment: is there a better way? */
+	if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP) {
+		pr_debug("SO_ORIGINAL_DST: Not a TCP/SCTP socket\n");
 		return -ENOPROTOOPT;
 	}
 
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 3229e0a..68afc6e 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -212,7 +212,7 @@ find_best_ips_proto(struct nf_conntrack_tuple *tuple,
 	maxip = ntohl(range->max_ip);
 	j = jhash_2words((__force u32)tuple->src.u3.ip,
 			 range->flags & IP_NAT_RANGE_PERSISTENT ?
-				(__force u32)tuple->dst.u3.ip : 0, 0);
+				0 : (__force u32)tuple->dst.u3.ip, 0);
 	j = ((u64)j * (maxip - minip + 1)) >> 32;
 	*var_ipp = htonl(minip + j);
 }
@@ -620,7 +620,7 @@ static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
 };
 
 static int
-nfnetlink_parse_nat(struct nlattr *nat,
+nfnetlink_parse_nat(const struct nlattr *nat,
 		    const struct nf_conn *ct, struct nf_nat_range *range)
 {
 	struct nlattr *tb[CTA_NAT_MAX+1];
@@ -656,7 +656,7 @@ nfnetlink_parse_nat(struct nlattr *nat,
 static int
 nfnetlink_parse_nat_setup(struct nf_conn *ct,
 			  enum nf_nat_manip_type manip,
-			  struct nlattr *attr)
+			  const struct nlattr *attr)
 {
 	struct nf_nat_range range;
 
@@ -671,7 +671,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
 static int
 nfnetlink_parse_nat_setup(struct nf_conn *ct,
 			  enum nf_nat_manip_type manip,
-			  struct nlattr *attr)
+			  const struct nlattr *attr)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 6348a79..9e81e0d 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -28,7 +28,7 @@
 			 (1 << NF_INET_POST_ROUTING) | \
 			 (1 << NF_INET_LOCAL_OUT))
 
-static struct
+static const struct
 {
 	struct ipt_replace repl;
 	struct ipt_standard entries[3];
@@ -58,11 +58,11 @@ static struct
 	.term = IPT_ERROR_INIT,			/* ERROR */
 };
 
-static struct xt_table nat_table = {
+static const struct xt_table nat_table = {
 	.name		= "nat",
 	.valid_hooks	= NAT_VALID_HOOKS,
 	.me		= THIS_MODULE,
-	.af		= AF_INET,
+	.af		= NFPROTO_IPV4,
 };
 
 /* Source NAT */
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 5567bd0..5f41d01 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -251,7 +251,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
 	{
 		.hook		= nf_nat_in,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP_PRI_NAT_DST,
 	},
@@ -259,7 +259,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
 	{
 		.hook		= nf_nat_out,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP_PRI_NAT_SRC,
 	},
@@ -267,7 +267,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
 	{
 		.hook		= nf_nat_local_fn,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP_PRI_NAT_DST,
 	},
@@ -275,7 +275,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
 	{
 		.hook		= nf_nat_fn,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET,
+		.pf		= NFPROTO_IPV4,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_NAT_SRC,
 	},
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index ea50da0..542f22f 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -22,35 +22,20 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  */
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
+#include <linux/cache.h>
 #include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
-#include <linux/timer.h>
-#include <net/ip.h>
+#include <linux/spinlock.h>
 #include <net/protocol.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/ipip.h>
-#include <linux/igmp.h>
 
-struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp;
+const struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp;
 static DEFINE_SPINLOCK(inet_proto_lock);
 
 /*
  *	Add a protocol handler to the hash tables
  */
 
-int inet_add_protocol(struct net_protocol *prot, unsigned char protocol)
+int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
 	int hash, ret;
 
@@ -72,7 +57,7 @@ int inet_add_protocol(struct net_protocol *prot, unsigned char protocol)
  *	Remove a protocol from the hash tables.
  */
 
-int inet_del_protocol(struct net_protocol *prot, unsigned char protocol)
+int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
 	int hash, ret;
 
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 2979f14..ebb1e58 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -375,7 +375,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
 	err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		      dst_output);
 	if (err > 0)
-		err = inet->recverr ? net_xmit_errno(err) : 0;
+		err = net_xmit_errno(err);
 	if (err)
 		goto error;
 out:
@@ -386,6 +386,8 @@ error_fault:
 	kfree_skb(skb);
 error:
 	IP_INC_STATS(net, IPSTATS_MIB_OUTDISCARDS);
+	if (err == -ENOBUFS && !inet->recverr)
+		err = 0;
 	return err;
 }
 
@@ -576,8 +578,11 @@ back_from_confirm:
 					&ipc, &rt, msg->msg_flags);
 		if (err)
 			ip_flush_pending_frames(sk);
-		else if (!(msg->msg_flags & MSG_MORE))
+		else if (!(msg->msg_flags & MSG_MORE)) {
 			err = ip_push_pending_frames(sk);
+			if (err == -ENOBUFS && !inet->recverr)
+				err = 0;
+		}
 		release_sock(sk);
 	}
 done:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 278f46f..91867d3 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1514,13 +1514,17 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
 void ip_rt_send_redirect(struct sk_buff *skb)
 {
 	struct rtable *rt = skb_rtable(skb);
-	struct in_device *in_dev = in_dev_get(rt->u.dst.dev);
+	struct in_device *in_dev;
+	int log_martians;
 
-	if (!in_dev)
+	rcu_read_lock();
+	in_dev = __in_dev_get_rcu(rt->u.dst.dev);
+	if (!in_dev || !IN_DEV_TX_REDIRECTS(in_dev)) {
+		rcu_read_unlock();
 		return;
-
-	if (!IN_DEV_TX_REDIRECTS(in_dev))
-		goto out;
+	}
+	log_martians = IN_DEV_LOG_MARTIANS(in_dev);
+	rcu_read_unlock();
 
 	/* No redirected packets during ip_rt_redirect_silence;
 	 * reset the algorithm.
@@ -1533,7 +1537,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 	 */
 	if (rt->u.dst.rate_tokens >= ip_rt_redirect_number) {
 		rt->u.dst.rate_last = jiffies;
-		goto out;
+		return;
 	}
 
 	/* Check for load limit; set rate_last to the latest sent
@@ -1547,7 +1551,7 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 		rt->u.dst.rate_last = jiffies;
 		++rt->u.dst.rate_tokens;
 #ifdef CONFIG_IP_ROUTE_VERBOSE
-		if (IN_DEV_LOG_MARTIANS(in_dev) &&
+		if (log_martians &&
 		    rt->u.dst.rate_tokens == ip_rt_redirect_number &&
 		    net_ratelimit())
 			printk(KERN_WARNING "host %pI4/if%d ignores redirects for %pI4 to %pI4.\n",
@@ -1555,8 +1559,6 @@ void ip_rt_send_redirect(struct sk_buff *skb)
 				&rt->rt_dst, &rt->rt_gateway);
 #endif
 	}
-out:
-	in_dev_put(in_dev);
 }
 
 static int ip_error(struct sk_buff *skb)
@@ -3442,7 +3444,7 @@ int __init ip_rt_init(void)
 		printk(KERN_ERR "Unable to create route proc files\n");
 #ifdef CONFIG_XFRM
 	xfrm_init();
-	xfrm4_init();
+	xfrm4_init(ip_rt_max_size);
 #endif
 	rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL);
 
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index cd2b97f..a6e0e07 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -37,12 +37,13 @@ __initcall(init_syncookies);
 #define COOKIEBITS 24	/* Upper bits store count */
 #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
 
-static DEFINE_PER_CPU(__u32, cookie_scratch)[16 + 5 + SHA_WORKSPACE_WORDS];
+static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
+		      ipv4_cookie_scratch);
 
 static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
 		       u32 count, int c)
 {
-	__u32 *tmp = __get_cpu_var(cookie_scratch);
+	__u32 *tmp = __get_cpu_var(ipv4_cookie_scratch);
 
 	memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c]));
 	tmp[0] = (__force u32)saddr;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 9114524..19a0612 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1839,7 +1839,7 @@ void tcp_close(struct sock *sk, long timeout)
 		/* Unread data was tossed, zap the connection. */
 		NET_INC_STATS_USER(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
 		tcp_set_state(sk, TCP_CLOSE);
-		tcp_send_active_reset(sk, GFP_KERNEL);
+		tcp_send_active_reset(sk, sk->sk_allocation);
 	} else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
 		/* Check zero linger _after_ checking for unread data. */
 		sk->sk_prot->disconnect(sk, 0);
@@ -2012,7 +2012,7 @@ int tcp_disconnect(struct sock *sk, int flags)
 	tp->snd_cwnd = 2;
 	icsk->icsk_probes_out = 0;
 	tp->packets_out = 0;
-	tp->snd_ssthresh = 0x7fffffff;
+	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 	tp->snd_cwnd_cnt = 0;
 	tp->bytes_acked = 0;
 	tcp_set_ca_state(sk, TCP_CA_Open);
@@ -2336,13 +2336,13 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
 		val = !!(tp->nonagle&TCP_NAGLE_CORK);
 		break;
 	case TCP_KEEPIDLE:
-		val = (tp->keepalive_time ? : sysctl_tcp_keepalive_time) / HZ;
+		val = keepalive_time_when(tp) / HZ;
 		break;
 	case TCP_KEEPINTVL:
-		val = (tp->keepalive_intvl ? : sysctl_tcp_keepalive_intvl) / HZ;
+		val = keepalive_intvl_when(tp) / HZ;
 		break;
 	case TCP_KEEPCNT:
-		val = tp->keepalive_probes ? : sysctl_tcp_keepalive_probes;
+		val = keepalive_probes(tp);
 		break;
 	case TCP_SYNCNT:
 		val = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
@@ -2658,7 +2658,7 @@ void tcp_free_md5sig_pool(void)
 
 EXPORT_SYMBOL(tcp_free_md5sig_pool);
 
-static struct tcp_md5sig_pool **__tcp_alloc_md5sig_pool(void)
+static struct tcp_md5sig_pool **__tcp_alloc_md5sig_pool(struct sock *sk)
 {
 	int cpu;
 	struct tcp_md5sig_pool **pool;
@@ -2671,7 +2671,7 @@ static struct tcp_md5sig_pool **__tcp_alloc_md5sig_pool(void)
 		struct tcp_md5sig_pool *p;
 		struct crypto_hash *hash;
 
-		p = kzalloc(sizeof(*p), GFP_KERNEL);
+		p = kzalloc(sizeof(*p), sk->sk_allocation);
 		if (!p)
 			goto out_free;
 		*per_cpu_ptr(pool, cpu) = p;
@@ -2688,7 +2688,7 @@ out_free:
 	return NULL;
 }
 
-struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(void)
+struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(struct sock *sk)
 {
 	struct tcp_md5sig_pool **pool;
 	int alloc = 0;
@@ -2709,7 +2709,7 @@ retry:
 
 	if (alloc) {
 		/* we cannot hold spinlock here because this may sleep. */
-		struct tcp_md5sig_pool **p = __tcp_alloc_md5sig_pool();
+		struct tcp_md5sig_pool **p = __tcp_alloc_md5sig_pool(sk);
 		spin_lock_bh(&tcp_md5sig_pool_lock);
 		if (!p) {
 			tcp_md5sig_users--;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2bdb0da..d86784b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -685,7 +685,7 @@ static inline void tcp_set_rto(struct sock *sk)
 	 *    is invisible. Actually, Linux-2.4 also generates erratic
 	 *    ACKs in some circumstances.
 	 */
-	inet_csk(sk)->icsk_rto = (tp->srtt >> 3) + tp->rttvar;
+	inet_csk(sk)->icsk_rto = __tcp_set_rto(tp);
 
 	/* 2. Fixups made earlier cannot be right.
 	 *    If we do not estimate RTO correctly without them,
@@ -696,8 +696,7 @@ static inline void tcp_set_rto(struct sock *sk)
 	/* NOTE: clamping at TCP_RTO_MIN is not required, current algo
 	 * guarantees that rto is higher.
 	 */
-	if (inet_csk(sk)->icsk_rto > TCP_RTO_MAX)
-		inet_csk(sk)->icsk_rto = TCP_RTO_MAX;
+	tcp_bound_rto(sk);
 }
 
 /* Save metrics learned by this TCP session.
@@ -762,7 +761,7 @@ void tcp_update_metrics(struct sock *sk)
 			set_dst_metric_rtt(dst, RTAX_RTTVAR, var);
 		}
 
-		if (tp->snd_ssthresh >= 0xFFFF) {
+		if (tcp_in_initial_slowstart(tp)) {
 			/* Slow start still did not finish. */
 			if (dst_metric(dst, RTAX_SSTHRESH) &&
 			    !dst_metric_locked(dst, RTAX_SSTHRESH) &&
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 6d88219..7cda24b 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -328,26 +328,29 @@ static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu)
  *
  */
 
-void tcp_v4_err(struct sk_buff *skb, u32 info)
+void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
 {
-	struct iphdr *iph = (struct iphdr *)skb->data;
-	struct tcphdr *th = (struct tcphdr *)(skb->data + (iph->ihl << 2));
+	struct iphdr *iph = (struct iphdr *)icmp_skb->data;
+	struct tcphdr *th = (struct tcphdr *)(icmp_skb->data + (iph->ihl << 2));
+	struct inet_connection_sock *icsk;
 	struct tcp_sock *tp;
 	struct inet_sock *inet;
-	const int type = icmp_hdr(skb)->type;
-	const int code = icmp_hdr(skb)->code;
+	const int type = icmp_hdr(icmp_skb)->type;
+	const int code = icmp_hdr(icmp_skb)->code;
 	struct sock *sk;
+	struct sk_buff *skb;
 	__u32 seq;
+	__u32 remaining;
 	int err;
-	struct net *net = dev_net(skb->dev);
+	struct net *net = dev_net(icmp_skb->dev);
 
-	if (skb->len < (iph->ihl << 2) + 8) {
+	if (icmp_skb->len < (iph->ihl << 2) + 8) {
 		ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
 		return;
 	}
 
 	sk = inet_lookup(net, &tcp_hashinfo, iph->daddr, th->dest,
-			iph->saddr, th->source, inet_iif(skb));
+			iph->saddr, th->source, inet_iif(icmp_skb));
 	if (!sk) {
 		ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
 		return;
@@ -367,6 +370,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
 	if (sk->sk_state == TCP_CLOSE)
 		goto out;
 
+	icsk = inet_csk(sk);
 	tp = tcp_sk(sk);
 	seq = ntohl(th->seq);
 	if (sk->sk_state != TCP_LISTEN &&
@@ -393,6 +397,39 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
 		}
 
 		err = icmp_err_convert[code].errno;
+		/* check if icmp_skb allows revert of backoff
+		 * (see draft-zimmermann-tcp-lcd) */
+		if (code != ICMP_NET_UNREACH && code != ICMP_HOST_UNREACH)
+			break;
+		if (seq != tp->snd_una  || !icsk->icsk_retransmits ||
+		    !icsk->icsk_backoff)
+			break;
+
+		icsk->icsk_backoff--;
+		inet_csk(sk)->icsk_rto = __tcp_set_rto(tp) <<
+					 icsk->icsk_backoff;
+		tcp_bound_rto(sk);
+
+		skb = tcp_write_queue_head(sk);
+		BUG_ON(!skb);
+
+		remaining = icsk->icsk_rto - min(icsk->icsk_rto,
+				tcp_time_stamp - TCP_SKB_CB(skb)->when);
+
+		if (remaining) {
+			inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+						  remaining, TCP_RTO_MAX);
+		} else if (sock_owned_by_user(sk)) {
+			/* RTO revert clocked out retransmission,
+			 * but socket is locked. Will defer. */
+			inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+						  HZ/20, TCP_RTO_MAX);
+		} else {
+			/* RTO revert clocked out retransmission.
+			 * Will retransmit now */
+			tcp_retransmit_timer(sk);
+		}
+
 		break;
 	case ICMP_TIME_EXCEEDED:
 		err = EHOSTUNREACH;
@@ -849,7 +886,7 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
 			}
 			sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
 		}
-		if (tcp_alloc_md5sig_pool() == NULL) {
+		if (tcp_alloc_md5sig_pool(sk) == NULL) {
 			kfree(newkey);
 			return -ENOMEM;
 		}
@@ -970,8 +1007,9 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
 
 	if (!tcp_sk(sk)->md5sig_info) {
 		struct tcp_sock *tp = tcp_sk(sk);
-		struct tcp_md5sig_info *p = kzalloc(sizeof(*p), GFP_KERNEL);
+		struct tcp_md5sig_info *p;
 
+		p = kzalloc(sizeof(*p), sk->sk_allocation);
 		if (!p)
 			return -EINVAL;
 
@@ -979,7 +1017,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
 		sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
 	}
 
-	newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
+	newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, sk->sk_allocation);
 	if (!newkey)
 		return -ENOMEM;
 	return tcp_v4_md5_do_add(sk, sin->sin_addr.s_addr,
@@ -1158,7 +1196,7 @@ struct request_sock_ops tcp_request_sock_ops __read_mostly = {
 };
 
 #ifdef CONFIG_TCP_MD5SIG
-static struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
+static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
 	.md5_lookup	=	tcp_v4_reqsk_md5_lookup,
 	.calc_md5_hash	=	tcp_v4_md5_hash_skb,
 };
@@ -1717,7 +1755,7 @@ int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw)
 	return 0;
 }
 
-struct inet_connection_sock_af_ops ipv4_specific = {
+const struct inet_connection_sock_af_ops ipv4_specific = {
 	.queue_xmit	   = ip_queue_xmit,
 	.send_check	   = tcp_v4_send_check,
 	.rebuild_header	   = inet_sk_rebuild_header,
@@ -1737,7 +1775,7 @@ struct inet_connection_sock_af_ops ipv4_specific = {
 };
 
 #ifdef CONFIG_TCP_MD5SIG
-static struct tcp_sock_af_ops tcp_sock_ipv4_specific = {
+static const struct tcp_sock_af_ops tcp_sock_ipv4_specific = {
 	.md5_lookup		= tcp_v4_md5_lookup,
 	.calc_md5_hash		= tcp_v4_md5_hash_skb,
 	.md5_add		= tcp_v4_md5_add_func,
@@ -1770,7 +1808,7 @@ static int tcp_v4_init_sock(struct sock *sk)
 	/* See draft-stevens-tcpca-spec-01 for discussion of the
 	 * initialization of these values.
 	 */
-	tp->snd_ssthresh = 0x7fffffff;	/* Infinity */
+	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 	tp->snd_cwnd_clamp = ~0;
 	tp->mss_cache = 536;
 
@@ -2246,7 +2284,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
 		jiffies_to_clock_t(icsk->icsk_ack.ato),
 		(icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
 		tp->snd_cwnd,
-		tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh,
+		tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh,
 		len);
 }
 
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index f8d67cc..624c3c9 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -322,7 +322,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
 			if (key != NULL) {
 				memcpy(&tcptw->tw_md5_key, key->key, key->keylen);
 				tcptw->tw_md5_keylen = key->keylen;
-				if (tcp_alloc_md5sig_pool() == NULL)
+				if (tcp_alloc_md5sig_pool(sk) == NULL)
 					BUG();
 			}
 		} while (0);
@@ -363,7 +363,7 @@ void tcp_twsk_destructor(struct sock *sk)
 #ifdef CONFIG_TCP_MD5SIG
 	struct tcp_timewait_sock *twsk = tcp_twsk(sk);
 	if (twsk->tw_md5_keylen)
-		tcp_put_md5sig_pool();
+		tcp_free_md5sig_pool();
 #endif
 }
 
@@ -410,7 +410,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
 		newtp->retrans_out = 0;
 		newtp->sacked_out = 0;
 		newtp->fackets_out = 0;
-		newtp->snd_ssthresh = 0x7fffffff;
+		newtp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 
 		/* So many TCP implementations out there (incorrectly) count the
 		 * initial SYN frame in their delayed-ACK and congestion control
@@ -657,29 +657,6 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
 	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
 	if (child == NULL)
 		goto listen_overflow;
-#ifdef CONFIG_TCP_MD5SIG
-	else {
-		/* Copy over the MD5 key from the original socket */
-		struct tcp_md5sig_key *key;
-		struct tcp_sock *tp = tcp_sk(sk);
-		key = tp->af_specific->md5_lookup(sk, child);
-		if (key != NULL) {
-			/*
-			 * We're using one, so create a matching key on the
-			 * newsk structure. If we fail to get memory then we
-			 * end up not copying the key across. Shucks.
-			 */
-			char *newkey = kmemdup(key->key, key->keylen,
-					       GFP_ATOMIC);
-			if (newkey) {
-				if (!tcp_alloc_md5sig_pool())
-					BUG();
-				tp->af_specific->md5_add(child, child, newkey,
-							 key->keylen);
-			}
-		}
-	}
-#endif
 
 	inet_csk_reqsk_queue_unlink(sk, req, prev);
 	inet_csk_reqsk_queue_removed(sk, req);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index bd62712..5200aab 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -59,6 +59,7 @@ int sysctl_tcp_base_mss __read_mostly = 512;
 /* By default, RFC2861 behavior.  */
 int sysctl_tcp_slow_start_after_idle __read_mostly = 1;
 
+/* Account for new data that has been sent to the network. */
 static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -142,6 +143,7 @@ static void tcp_cwnd_restart(struct sock *sk, struct dst_entry *dst)
 	tp->snd_cwnd_used = 0;
 }
 
+/* Congestion state accounting after a packet has been sent. */
 static void tcp_event_data_sent(struct tcp_sock *tp,
 				struct sk_buff *skb, struct sock *sk)
 {
@@ -161,6 +163,7 @@ static void tcp_event_data_sent(struct tcp_sock *tp,
 		icsk->icsk_ack.pingpong = 1;
 }
 
+/* Account for an ACK we sent. */
 static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
 {
 	tcp_dec_quickack_mode(sk, pkts);
@@ -276,6 +279,7 @@ static u16 tcp_select_window(struct sock *sk)
 	return new_win;
 }
 
+/* Packet ECN state for a SYN-ACK */
 static inline void TCP_ECN_send_synack(struct tcp_sock *tp, struct sk_buff *skb)
 {
 	TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR;
@@ -283,6 +287,7 @@ static inline void TCP_ECN_send_synack(struct tcp_sock *tp, struct sk_buff *skb)
 		TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE;
 }
 
+/* Packet ECN state for a SYN.  */
 static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -301,6 +306,9 @@ TCP_ECN_make_synack(struct request_sock *req, struct tcphdr *th)
 		th->ece = 1;
 }
 
+/* Set up ECN state for a packet on a ESTABLISHED socket that is about to
+ * be sent.
+ */
 static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb,
 				int tcp_header_len)
 {
@@ -362,7 +370,9 @@ struct tcp_out_options {
 	__u32 tsval, tsecr;	/* need to include OPTION_TS */
 };
 
-/* Beware: Something in the Internet is very sensitive to the ordering of
+/* Write previously computed TCP options to the packet.
+ *
+ * Beware: Something in the Internet is very sensitive to the ordering of
  * TCP options, we learned this through the hard way, so be careful here.
  * Luckily we can at least blame others for their non-compliance but from
  * inter-operatibility perspective it seems that we're somewhat stuck with
@@ -445,6 +455,9 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
 	}
 }
 
+/* Compute TCP options for SYN packets. This is not the final
+ * network wire format yet.
+ */
 static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
 				struct tcp_out_options *opts,
 				struct tcp_md5sig_key **md5) {
@@ -493,6 +506,7 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
 	return size;
 }
 
+/* Set up TCP options for SYN-ACKs. */
 static unsigned tcp_synack_options(struct sock *sk,
 				   struct request_sock *req,
 				   unsigned mss, struct sk_buff *skb,
@@ -541,6 +555,9 @@ static unsigned tcp_synack_options(struct sock *sk,
 	return size;
 }
 
+/* Compute TCP options for ESTABLISHED sockets. This is not the
+ * final wire format yet.
+ */
 static unsigned tcp_established_options(struct sock *sk, struct sk_buff *skb,
 					struct tcp_out_options *opts,
 					struct tcp_md5sig_key **md5) {
@@ -705,7 +722,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 	return net_xmit_eval(err);
 }
 
-/* This routine just queue's the buffer
+/* This routine just queues the buffer for sending.
  *
  * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames,
  * otherwise socket can stall.
@@ -722,6 +739,7 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
 	sk_mem_charge(sk, skb->truesize);
 }
 
+/* Initialize TSO segments for a packet. */
 static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb,
 				 unsigned int mss_now)
 {
@@ -909,6 +927,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
 	skb->len = skb->data_len;
 }
 
+/* Remove acked data from a packet in the transmit queue. */
 int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
 {
 	if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -937,7 +956,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
 	return 0;
 }
 
-/* Not accounting for SACKs here. */
+/* Calculate MSS. Not accounting for SACKs here.  */
 int tcp_mtu_to_mss(struct sock *sk, int pmtu)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -981,6 +1000,7 @@ int tcp_mss_to_mtu(struct sock *sk, int mss)
 	return mtu;
 }
 
+/* MTU probing init per socket */
 void tcp_mtup_init(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -1143,7 +1163,8 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp,
 	return 0;
 }
 
-/* This must be invoked the first time we consider transmitting
+/* Intialize TSO state of a skb.
+ * This must be invoked the first time we consider transmitting
  * SKB onto the wire.
  */
 static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb,
@@ -1158,6 +1179,7 @@ static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb,
 	return tso_segs;
 }
 
+/* Minshall's variant of the Nagle send check. */
 static inline int tcp_minshall_check(const struct tcp_sock *tp)
 {
 	return after(tp->snd_sml, tp->snd_una) &&
@@ -1242,6 +1264,7 @@ static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb,
 	return cwnd_quota;
 }
 
+/* Test if sending is allowed right now. */
 int tcp_may_send_now(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -1378,6 +1401,10 @@ send_now:
 }
 
 /* Create a new MTU probe if we are ready.
+ * MTU probe is regularly attempting to increase the path MTU by
+ * deliberately sending larger packets.  This discovers routing
+ * changes resulting in larger path MTUs.
+ *
  * Returns 0 if we should wait to probe (no cwnd available),
  *         1 if a probe was sent,
  *         -1 otherwise
@@ -1790,6 +1817,7 @@ static void tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)
 	sk_wmem_free_skb(sk, next_skb);
 }
 
+/* Check if coalescing SKBs is legal. */
 static int tcp_can_collapse(struct sock *sk, struct sk_buff *skb)
 {
 	if (tcp_skb_pcount(skb) > 1)
@@ -1808,6 +1836,9 @@ static int tcp_can_collapse(struct sock *sk, struct sk_buff *skb)
 	return 1;
 }
 
+/* Collapse packets in the retransmit queue to make to create
+ * less packets on the wire. This is only done on retransmission.
+ */
 static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
 				     int space)
 {
@@ -1957,6 +1988,9 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 	return err;
 }
 
+/* Check if we forward retransmits are possible in the current
+ * window/congestion state.
+ */
 static int tcp_can_forward_retransmit(struct sock *sk)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2101,7 +2135,8 @@ void tcp_send_fin(struct sock *sk)
 	} else {
 		/* Socket is locked, keep trying until memory is available. */
 		for (;;) {
-			skb = alloc_skb_fclone(MAX_TCP_HEADER, GFP_KERNEL);
+			skb = alloc_skb_fclone(MAX_TCP_HEADER,
+					       sk->sk_allocation);
 			if (skb)
 				break;
 			yield();
@@ -2145,7 +2180,8 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
 	TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTRSTS);
 }
 
-/* WARNING: This routine must only be called when we have already sent
+/* Send a crossed SYN-ACK during socket establishment.
+ * WARNING: This routine must only be called when we have already sent
  * a SYN packet that crossed the incoming SYN that caused this routine
  * to get called. If this assumption fails then the initial rcv_wnd
  * and rcv_wscale values will not be correct.
@@ -2180,9 +2216,7 @@ int tcp_send_synack(struct sock *sk)
 	return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
 }
 
-/*
- * Prepare a SYN-ACK.
- */
+/* Prepare a SYN-ACK. */
 struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
 				struct request_sock *req)
 {
@@ -2269,9 +2303,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
 	return skb;
 }
 
-/*
- * Do all connect socket setups that can be done AF independent.
- */
+/* Do all connect socket setups that can be done AF independent. */
 static void tcp_connect_init(struct sock *sk)
 {
 	struct dst_entry *dst = __sk_dst_get(sk);
@@ -2330,9 +2362,7 @@ static void tcp_connect_init(struct sock *sk)
 	tcp_clear_retrans(tp);
 }
 
-/*
- * Build a SYN and send it off.
- */
+/* Build a SYN and send it off. */
 int tcp_connect(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -2359,7 +2389,7 @@ int tcp_connect(struct sock *sk)
 	sk->sk_wmem_queued += buff->truesize;
 	sk_mem_charge(sk, buff->truesize);
 	tp->packets_out += tcp_skb_pcount(buff);
-	tcp_transmit_skb(sk, buff, 1, GFP_KERNEL);
+	tcp_transmit_skb(sk, buff, 1, sk->sk_allocation);
 
 	/* We change tp->snd_nxt after the tcp_transmit_skb() call
 	 * in order to make this packet get counted in tcpOutSegs.
@@ -2493,6 +2523,7 @@ static int tcp_xmit_probe_skb(struct sock *sk, int urgent)
 	return tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC);
 }
 
+/* Initiate keepalive or window probe from timer. */
 int tcp_write_wakeup(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index b144a26..cdb2ca7 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -137,13 +137,14 @@ static int tcp_write_timeout(struct sock *sk)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	int retry_until;
+	bool do_reset;
 
 	if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
 		if (icsk->icsk_retransmits)
 			dst_negative_advice(&sk->sk_dst_cache);
 		retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries;
 	} else {
-		if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
+		if (retransmits_timed_out(sk, sysctl_tcp_retries1)) {
 			/* Black hole detection */
 			tcp_mtu_probing(icsk, sk);
 
@@ -155,13 +156,15 @@ static int tcp_write_timeout(struct sock *sk)
 			const int alive = (icsk->icsk_rto < TCP_RTO_MAX);
 
 			retry_until = tcp_orphan_retries(sk, alive);
+			do_reset = alive ||
+				   !retransmits_timed_out(sk, retry_until);
 
-			if (tcp_out_of_resources(sk, alive || icsk->icsk_retransmits < retry_until))
+			if (tcp_out_of_resources(sk, do_reset))
 				return 1;
 		}
 	}
 
-	if (icsk->icsk_retransmits >= retry_until) {
+	if (retransmits_timed_out(sk, retry_until)) {
 		/* Has it gone just too far? */
 		tcp_write_err(sk);
 		return 1;
@@ -279,7 +282,7 @@ static void tcp_probe_timer(struct sock *sk)
  *	The TCP retransmit timer.
  */
 
-static void tcp_retransmit_timer(struct sock *sk)
+void tcp_retransmit_timer(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
@@ -385,7 +388,7 @@ static void tcp_retransmit_timer(struct sock *sk)
 out_reset_timer:
 	icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX);
 	inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX);
-	if (icsk->icsk_retransmits > sysctl_tcp_retries1)
+	if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1))
 		__sk_dst_reset(sk);
 
 out:;
@@ -499,8 +502,7 @@ static void tcp_keepalive_timer (unsigned long data)
 	elapsed = tcp_time_stamp - tp->rcv_tstamp;
 
 	if (elapsed >= keepalive_time_when(tp)) {
-		if ((!tp->keepalive_probes && icsk->icsk_probes_out >= sysctl_tcp_keepalive_probes) ||
-		     (tp->keepalive_probes && icsk->icsk_probes_out >= tp->keepalive_probes)) {
+		if (icsk->icsk_probes_out >= keepalive_probes(tp)) {
 			tcp_send_active_reset(sk, GFP_ATOMIC);
 			tcp_write_err(sk);
 			goto out;
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c
index cb1f0e8..3959e0c 100644
--- a/net/ipv4/tunnel4.c
+++ b/net/ipv4/tunnel4.c
@@ -132,7 +132,7 @@ static void tunnel64_err(struct sk_buff *skb, u32 info)
 }
 #endif
 
-static struct net_protocol tunnel4_protocol = {
+static const struct net_protocol tunnel4_protocol = {
 	.handler	=	tunnel4_rcv,
 	.err_handler	=	tunnel4_err,
 	.no_policy	=	1,
@@ -140,7 +140,7 @@ static struct net_protocol tunnel4_protocol = {
 };
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static struct net_protocol tunnel64_protocol = {
+static const struct net_protocol tunnel64_protocol = {
 	.handler	=	tunnel64_rcv,
 	.err_handler	=	tunnel64_err,
 	.no_policy	=	1,
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 80e3812..ebaaa7f 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -110,11 +110,12 @@ struct udp_table udp_table;
 EXPORT_SYMBOL(udp_table);
 
 int sysctl_udp_mem[3] __read_mostly;
-int sysctl_udp_rmem_min __read_mostly;
-int sysctl_udp_wmem_min __read_mostly;
-
 EXPORT_SYMBOL(sysctl_udp_mem);
+
+int sysctl_udp_rmem_min __read_mostly;
 EXPORT_SYMBOL(sysctl_udp_rmem_min);
+
+int sysctl_udp_wmem_min __read_mostly;
 EXPORT_SYMBOL(sysctl_udp_wmem_min);
 
 atomic_t udp_memory_allocated;
@@ -158,7 +159,7 @@ static int udp_lib_lport_inuse(struct net *net, __u16 num,
  */
 int udp_lib_get_port(struct sock *sk, unsigned short snum,
 		       int (*saddr_comp)(const struct sock *sk1,
-					 const struct sock *sk2 )    )
+					 const struct sock *sk2))
 {
 	struct udp_hslot *hslot;
 	struct udp_table *udptable = sk->sk_prot->h.udp_table;
@@ -221,14 +222,15 @@ fail_unlock:
 fail:
 	return error;
 }
+EXPORT_SYMBOL(udp_lib_get_port);
 
 static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
 {
 	struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
 
-	return 	( !ipv6_only_sock(sk2)  &&
-		  (!inet1->rcv_saddr || !inet2->rcv_saddr ||
-		   inet1->rcv_saddr == inet2->rcv_saddr      ));
+	return 	(!ipv6_only_sock(sk2)  &&
+		 (!inet1->rcv_saddr || !inet2->rcv_saddr ||
+		   inet1->rcv_saddr == inet2->rcv_saddr));
 }
 
 int udp_v4_get_port(struct sock *sk, unsigned short snum)
@@ -383,8 +385,8 @@ found:
 void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
 {
 	struct inet_sock *inet;
-	struct iphdr *iph = (struct iphdr*)skb->data;
-	struct udphdr *uh = (struct udphdr*)(skb->data+(iph->ihl<<2));
+	struct iphdr *iph = (struct iphdr *)skb->data;
+	struct udphdr *uh = (struct udphdr *)(skb->data+(iph->ihl<<2));
 	const int type = icmp_hdr(skb)->type;
 	const int code = icmp_hdr(skb)->code;
 	struct sock *sk;
@@ -439,7 +441,7 @@ void __udp4_lib_err(struct sk_buff *skb, u32 info, struct udp_table *udptable)
 		if (!harderr || sk->sk_state != TCP_ESTABLISHED)
 			goto out;
 	} else {
-		ip_icmp_error(sk, skb, err, uh->dest, info, (u8*)(uh+1));
+		ip_icmp_error(sk, skb, err, uh->dest, info, (u8 *)(uh+1));
 	}
 	sk->sk_err = err;
 	sk->sk_error_report(sk);
@@ -474,7 +476,7 @@ EXPORT_SYMBOL(udp_flush_pending_frames);
  * 	        (checksum field must be zeroed out)
  */
 static void udp4_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
-				 __be32 src, __be32 dst, int len      )
+				 __be32 src, __be32 dst, int len)
 {
 	unsigned int offset;
 	struct udphdr *uh = udp_hdr(skb);
@@ -545,7 +547,7 @@ static int udp_push_pending_frames(struct sock *sk)
 
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
 
-		udp4_hwcsum_outgoing(sk, skb, fl->fl4_src,fl->fl4_dst, up->len);
+		udp4_hwcsum_outgoing(sk, skb, fl->fl4_src, fl->fl4_dst, up->len);
 		goto send;
 
 	} else						 /*   `normal' UDP    */
@@ -553,18 +555,24 @@ static int udp_push_pending_frames(struct sock *sk)
 
 	/* add protocol-dependent pseudo-header */
 	uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, up->len,
-				      sk->sk_protocol, csum             );
+				      sk->sk_protocol, csum);
 	if (uh->check == 0)
 		uh->check = CSUM_MANGLED_0;
 
 send:
 	err = ip_push_pending_frames(sk);
+	if (err) {
+		if (err == -ENOBUFS && !inet->recverr) {
+			UDP_INC_STATS_USER(sock_net(sk),
+					   UDP_MIB_SNDBUFERRORS, is_udplite);
+			err = 0;
+		}
+	} else
+		UDP_INC_STATS_USER(sock_net(sk),
+				   UDP_MIB_OUTDATAGRAMS, is_udplite);
 out:
 	up->len = 0;
 	up->pending = 0;
-	if (!err)
-		UDP_INC_STATS_USER(sock_net(sk),
-				UDP_MIB_OUTDATAGRAMS, is_udplite);
 	return err;
 }
 
@@ -592,7 +600,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	 *	Check the flags.
 	 */
 
-	if (msg->msg_flags&MSG_OOB)	/* Mirror BSD error message compatibility */
+	if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */
 		return -EOPNOTSUPP;
 
 	ipc.opt = NULL;
@@ -619,7 +627,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	 *	Get and verify the address.
 	 */
 	if (msg->msg_name) {
-		struct sockaddr_in * usin = (struct sockaddr_in*)msg->msg_name;
+		struct sockaddr_in * usin = (struct sockaddr_in *)msg->msg_name;
 		if (msg->msg_namelen < sizeof(*usin))
 			return -EINVAL;
 		if (usin->sin_family != AF_INET) {
@@ -684,7 +692,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	}
 
 	if (connected)
-		rt = (struct rtable*)sk_dst_check(sk, 0);
+		rt = (struct rtable *)sk_dst_check(sk, 0);
 
 	if (rt == NULL) {
 		struct flowi fl = { .oif = ipc.oif,
@@ -782,6 +790,7 @@ do_confirm:
 	err = 0;
 	goto out;
 }
+EXPORT_SYMBOL(udp_sendmsg);
 
 int udp_sendpage(struct sock *sk, struct page *page, int offset,
 		 size_t size, int flags)
@@ -871,6 +880,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 
 	return 0;
 }
+EXPORT_SYMBOL(udp_ioctl);
 
 /*
  * 	This should be easy, if there is something there we
@@ -892,7 +902,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	 *	Check any passed addresses
 	 */
 	if (addr_len)
-		*addr_len=sizeof(*sin);
+		*addr_len = sizeof(*sin);
 
 	if (flags & MSG_ERRQUEUE)
 		return ip_recv_error(sk, msg, len);
@@ -923,9 +933,11 @@ try_again:
 
 	if (skb_csum_unnecessary(skb))
 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-					      msg->msg_iov, copied       );
+					      msg->msg_iov, copied);
 	else {
-		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
+		err = skb_copy_and_csum_datagram_iovec(skb,
+						       sizeof(struct udphdr),
+						       msg->msg_iov);
 
 		if (err == -EINVAL)
 			goto csum_copy_err;
@@ -941,8 +953,7 @@ try_again:
 	sock_recv_timestamp(msg, sk, skb);
 
 	/* Copy the address. */
-	if (sin)
-	{
+	if (sin) {
 		sin->sin_family = AF_INET;
 		sin->sin_port = udp_hdr(skb)->source;
 		sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
@@ -995,6 +1006,7 @@ int udp_disconnect(struct sock *sk, int flags)
 	sk_dst_reset(sk);
 	return 0;
 }
+EXPORT_SYMBOL(udp_disconnect);
 
 void udp_lib_unhash(struct sock *sk)
 {
@@ -1044,7 +1056,7 @@ drop:
  * Note that in the success and error cases, the skb is assumed to
  * have either been requeued or freed.
  */
-int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
+int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
 	struct udp_sock *up = udp_sk(sk);
 	int rc;
@@ -1214,7 +1226,7 @@ static inline int udp4_csum_init(struct sk_buff *skb, struct udphdr *uh,
 	if (uh->check == 0) {
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	} else if (skb->ip_summed == CHECKSUM_COMPLETE) {
-	       if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
+		if (!csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
 				      proto, skb->csum))
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
@@ -1355,7 +1367,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 	int err = 0;
 	int is_udplite = IS_UDPLITE(sk);
 
-	if (optlen<sizeof(int))
+	if (optlen < sizeof(int))
 		return -EINVAL;
 
 	if (get_user(val, (int __user *)optval))
@@ -1426,6 +1438,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 
 	return err;
 }
+EXPORT_SYMBOL(udp_lib_setsockopt);
 
 int udp_setsockopt(struct sock *sk, int level, int optname,
 		   char __user *optval, int optlen)
@@ -1453,7 +1466,7 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 	struct udp_sock *up = udp_sk(sk);
 	int val, len;
 
-	if (get_user(len,optlen))
+	if (get_user(len, optlen))
 		return -EFAULT;
 
 	len = min_t(unsigned int, len, sizeof(int));
@@ -1486,10 +1499,11 @@ int udp_lib_getsockopt(struct sock *sk, int level, int optname,
 
 	if (put_user(len, optlen))
 		return -EFAULT;
-	if (copy_to_user(optval, &val,len))
+	if (copy_to_user(optval, &val, len))
 		return -EFAULT;
 	return 0;
 }
+EXPORT_SYMBOL(udp_lib_getsockopt);
 
 int udp_getsockopt(struct sock *sk, int level, int optname,
 		   char __user *optval, int __user *optlen)
@@ -1528,9 +1542,9 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
 	int 	is_lite = IS_UDPLITE(sk);
 
 	/* Check for false positives due to checksum errors */
-	if ( (mask & POLLRDNORM) &&
-	     !(file->f_flags & O_NONBLOCK) &&
-	     !(sk->sk_shutdown & RCV_SHUTDOWN)){
+	if ((mask & POLLRDNORM) &&
+	    !(file->f_flags & O_NONBLOCK) &&
+	    !(sk->sk_shutdown & RCV_SHUTDOWN)) {
 		struct sk_buff_head *rcvq = &sk->sk_receive_queue;
 		struct sk_buff *skb;
 
@@ -1552,6 +1566,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
 	return mask;
 
 }
+EXPORT_SYMBOL(udp_poll);
 
 struct proto udp_prot = {
 	.name		   = "UDP",
@@ -1582,6 +1597,7 @@ struct proto udp_prot = {
 	.compat_getsockopt = compat_udp_getsockopt,
 #endif
 };
+EXPORT_SYMBOL(udp_prot);
 
 /* ------------------------------------------------------------------------ */
 #ifdef CONFIG_PROC_FS
@@ -1703,11 +1719,13 @@ int udp_proc_register(struct net *net, struct udp_seq_afinfo *afinfo)
 		rc = -ENOMEM;
 	return rc;
 }
+EXPORT_SYMBOL(udp_proc_register);
 
 void udp_proc_unregister(struct net *net, struct udp_seq_afinfo *afinfo)
 {
 	proc_net_remove(net, afinfo->name);
 }
+EXPORT_SYMBOL(udp_proc_unregister);
 
 /* ------------------------------------------------------------------------ */
 static void udp4_format_sock(struct sock *sp, struct seq_file *f,
@@ -1741,7 +1759,7 @@ int udp4_seq_show(struct seq_file *seq, void *v)
 		int len;
 
 		udp4_format_sock(v, seq, state->bucket, &len);
-		seq_printf(seq, "%*s\n", 127 - len ,"");
+		seq_printf(seq, "%*s\n", 127 - len, "");
 	}
 	return 0;
 }
@@ -1816,16 +1834,64 @@ void __init udp_init(void)
 	sysctl_udp_wmem_min = SK_MEM_QUANTUM;
 }
 
-EXPORT_SYMBOL(udp_disconnect);
-EXPORT_SYMBOL(udp_ioctl);
-EXPORT_SYMBOL(udp_prot);
-EXPORT_SYMBOL(udp_sendmsg);
-EXPORT_SYMBOL(udp_lib_getsockopt);
-EXPORT_SYMBOL(udp_lib_setsockopt);
-EXPORT_SYMBOL(udp_poll);
-EXPORT_SYMBOL(udp_lib_get_port);
+int udp4_ufo_send_check(struct sk_buff *skb)
+{
+	const struct iphdr *iph;
+	struct udphdr *uh;
+
+	if (!pskb_may_pull(skb, sizeof(*uh)))
+		return -EINVAL;
+
+	iph = ip_hdr(skb);
+	uh = udp_hdr(skb);
+
+	uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, skb->len,
+				       IPPROTO_UDP, 0);
+	skb->csum_start = skb_transport_header(skb) - skb->head;
+	skb->csum_offset = offsetof(struct udphdr, check);
+	skb->ip_summed = CHECKSUM_PARTIAL;
+	return 0;
+}
+
+struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, int features)
+{
+	struct sk_buff *segs = ERR_PTR(-EINVAL);
+	unsigned int mss;
+	int offset;
+	__wsum csum;
+
+	mss = skb_shinfo(skb)->gso_size;
+	if (unlikely(skb->len <= mss))
+		goto out;
+
+	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
+		/* Packet is from an untrusted source, reset gso_segs. */
+		int type = skb_shinfo(skb)->gso_type;
+
+		if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY) ||
+			     !(type & (SKB_GSO_UDP))))
+			goto out;
+
+		skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
+
+		segs = NULL;
+		goto out;
+	}
+
+	/* Do software UFO. Complete and fill in the UDP checksum as HW cannot
+	 * do checksum of UDP packets sent as multiple IP fragments.
+	 */
+	offset = skb->csum_start - skb_headroom(skb);
+	csum = skb_checksum(skb, offset, skb->len - offset, 0);
+	offset += skb->csum_offset;
+	*(__sum16 *)(skb->data + offset) = csum_fold(csum);
+	skb->ip_summed = CHECKSUM_NONE;
+
+	/* Fragment the skb. IP headers of the fragments are updated in
+	 * inet_gso_segment()
+	 */
+	segs = skb_segment(skb, features);
+out:
+	return segs;
+}
 
-#ifdef CONFIG_PROC_FS
-EXPORT_SYMBOL(udp_proc_register);
-EXPORT_SYMBOL(udp_proc_unregister);
-#endif
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
index c784891..95248d7 100644
--- a/net/ipv4/udplite.c
+++ b/net/ipv4/udplite.c
@@ -25,7 +25,7 @@ static void udplite_err(struct sk_buff *skb, u32 info)
 	__udp4_lib_err(skb, info, &udplite_table);
 }
 
-static	struct net_protocol udplite_protocol = {
+static const struct net_protocol udplite_protocol = {
 	.handler	= udplite_rcv,
 	.err_handler	= udplite_err,
 	.no_policy	= 1,
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 0071ee6..74fb2eb 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -264,6 +264,22 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
 	.fill_dst =		xfrm4_fill_dst,
 };
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table xfrm4_policy_table[] = {
+	{
+		.ctl_name       = CTL_UNNUMBERED,
+		.procname       = "xfrm4_gc_thresh",
+		.data           = &xfrm4_dst_ops.gc_thresh,
+		.maxlen         = sizeof(int),
+		.mode           = 0644,
+		.proc_handler   = proc_dointvec,
+	},
+	{ }
+};
+
+static struct ctl_table_header *sysctl_hdr;
+#endif
+
 static void __init xfrm4_policy_init(void)
 {
 	xfrm_policy_register_afinfo(&xfrm4_policy_afinfo);
@@ -271,12 +287,31 @@ static void __init xfrm4_policy_init(void)
 
 static void __exit xfrm4_policy_fini(void)
 {
+#ifdef CONFIG_SYSCTL
+	if (sysctl_hdr)
+		unregister_net_sysctl_table(sysctl_hdr);
+#endif
 	xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo);
 }
 
-void __init xfrm4_init(void)
+void __init xfrm4_init(int rt_max_size)
 {
 	xfrm4_state_init();
 	xfrm4_policy_init();
+	/*
+	 * Select a default value for the gc_thresh based on the main route
+	 * table hash size.  It seems to me the worst case scenario is when
+	 * we have ipsec operating in transport mode, in which we create a
+	 * dst_entry per socket.  The xfrm gc algorithm starts trying to remove
+	 * entries at gc_thresh, and prevents new allocations as 2*gc_thresh
+	 * so lets set an initial xfrm gc_thresh value at the rt_max_size/2.
+	 * That will let us store an ipsec connection per route table entry,
+	 * and start cleaning when were 1/2 full
+	 */
+	xfrm4_dst_ops.gc_thresh = rt_max_size/2;
+#ifdef CONFIG_SYSCTL
+	sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv4_ctl_path,
+						xfrm4_policy_table);
+#endif
 }
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 43b3c9f..55f486d 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -137,6 +137,8 @@ static DEFINE_SPINLOCK(addrconf_verify_lock);
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
 static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
 
+static void addrconf_bonding_change(struct net_device *dev,
+				    unsigned long event);
 static int addrconf_ifdown(struct net_device *dev, int how);
 
 static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
@@ -1371,12 +1373,14 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *add
 
 /* Gets referenced address, destroys ifaddr */
 
-static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
+static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
 {
 	if (ifp->flags&IFA_F_PERMANENT) {
 		spin_lock_bh(&ifp->lock);
 		addrconf_del_timer(ifp);
 		ifp->flags |= IFA_F_TENTATIVE;
+		if (dad_failed)
+			ifp->flags |= IFA_F_DADFAILED;
 		spin_unlock_bh(&ifp->lock);
 		in6_ifa_put(ifp);
 #ifdef CONFIG_IPV6_PRIVACY
@@ -1403,8 +1407,8 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 	struct inet6_dev *idev = ifp->idev;
 
 	if (net_ratelimit())
-		printk(KERN_INFO "%s: IPv6 duplicate address detected!\n",
-			ifp->idev->dev->name);
+		printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
+			ifp->idev->dev->name, &ifp->addr);
 
 	if (idev->cnf.accept_dad > 1 && !idev->cnf.disable_ipv6) {
 		struct in6_addr addr;
@@ -1422,7 +1426,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 		}
 	}
 
-	addrconf_dad_stop(ifp);
+	addrconf_dad_stop(ifp, 1);
 }
 
 /* Join to solicited addr multicast group. */
@@ -2580,6 +2584,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 				return notifier_from_errno(err);
 		}
 		break;
+	case NETDEV_BONDING_OLDTYPE:
+	case NETDEV_BONDING_NEWTYPE:
+		addrconf_bonding_change(dev, event);
+		break;
 	}
 
 	return NOTIFY_OK;
@@ -2593,6 +2601,19 @@ static struct notifier_block ipv6_dev_notf = {
 	.priority = 0
 };
 
+static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
+{
+	struct inet6_dev *idev;
+	ASSERT_RTNL();
+
+	idev = __in6_dev_get(dev);
+
+	if (event == NETDEV_BONDING_NEWTYPE)
+		ipv6_mc_remap(idev);
+	else if (event == NETDEV_BONDING_OLDTYPE)
+		ipv6_mc_unmap(idev);
+}
+
 static int addrconf_ifdown(struct net_device *dev, int how)
 {
 	struct inet6_dev *idev;
@@ -2778,7 +2799,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
 	    idev->cnf.accept_dad < 1 ||
 	    !(ifp->flags&IFA_F_TENTATIVE) ||
 	    ifp->flags & IFA_F_NODAD) {
-		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
+		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
 		spin_unlock_bh(&ifp->lock);
 		read_unlock_bh(&idev->lock);
 
@@ -2795,7 +2816,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
 		 * - otherwise, kill it.
 		 */
 		in6_ifa_hold(ifp);
-		addrconf_dad_stop(ifp);
+		addrconf_dad_stop(ifp, 0);
 		return;
 	}
 
@@ -2829,7 +2850,7 @@ static void addrconf_dad_timer(unsigned long data)
 		 * DAD was successful
 		 */
 
-		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC);
+		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
 		spin_unlock_bh(&ifp->lock);
 		read_unlock_bh(&idev->lock);
 
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 45f9a2a..e127a32 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -710,7 +710,7 @@ EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
 
 static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
 {
-	struct inet6_protocol *ops = NULL;
+	const struct inet6_protocol *ops = NULL;
 
 	for (;;) {
 		struct ipv6_opt_hdr *opth;
@@ -745,7 +745,7 @@ static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
 static int ipv6_gso_send_check(struct sk_buff *skb)
 {
 	struct ipv6hdr *ipv6h;
-	struct inet6_protocol *ops;
+	const struct inet6_protocol *ops;
 	int err = -EINVAL;
 
 	if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
@@ -773,7 +773,12 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
 {
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	struct ipv6hdr *ipv6h;
-	struct inet6_protocol *ops;
+	const struct inet6_protocol *ops;
+	int proto;
+	struct frag_hdr *fptr;
+	unsigned int unfrag_ip6hlen;
+	u8 *prevhdr;
+	int offset = 0;
 
 	if (!(features & NETIF_F_V6_CSUM))
 		features &= ~NETIF_F_SG;
@@ -793,10 +798,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
 	__skb_pull(skb, sizeof(*ipv6h));
 	segs = ERR_PTR(-EPROTONOSUPPORT);
 
+	proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
 	rcu_read_lock();
-	ops = rcu_dereference(inet6_protos[
-		ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr)]);
-
+	ops = rcu_dereference(inet6_protos[proto]);
 	if (likely(ops && ops->gso_segment)) {
 		skb_reset_transport_header(skb);
 		segs = ops->gso_segment(skb, features);
@@ -810,6 +814,16 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
 		ipv6h = ipv6_hdr(skb);
 		ipv6h->payload_len = htons(skb->len - skb->mac_len -
 					   sizeof(*ipv6h));
+		if (proto == IPPROTO_UDP) {
+			unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
+			fptr = (struct frag_hdr *)(skb_network_header(skb) +
+				unfrag_ip6hlen);
+			fptr->frag_off = htons(offset);
+			if (skb->next != NULL)
+				fptr->frag_off |= htons(IP6_MF);
+			offset += (ntohs(ipv6h->payload_len) -
+				   sizeof(struct frag_hdr));
+		}
 	}
 
 out:
@@ -826,7 +840,7 @@ struct ipv6_gro_cb {
 static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
 					 struct sk_buff *skb)
 {
-	struct inet6_protocol *ops;
+	const struct inet6_protocol *ops;
 	struct sk_buff **pp = NULL;
 	struct sk_buff *p;
 	struct ipv6hdr *iph;
@@ -912,7 +926,7 @@ out:
 
 static int ipv6_gro_complete(struct sk_buff *skb)
 {
-	struct inet6_protocol *ops;
+	const struct inet6_protocol *ops;
 	struct ipv6hdr *iph = ipv6_hdr(skb);
 	int err = -ENOSYS;
 
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 86f42a2..c1589e2 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -527,7 +527,7 @@ static const struct xfrm_type ah6_type =
 	.hdr_offset	= xfrm6_find_1stfragopt,
 };
 
-static struct inet6_protocol ah6_protocol = {
+static const struct inet6_protocol ah6_protocol = {
 	.handler	=	xfrm6_rcv,
 	.err_handler	=	ah6_err,
 	.flags		=	INET6_PROTO_NOPOLICY,
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 678bb95..af597c7 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -558,7 +558,7 @@ static const struct xfrm_type esp6_type =
 	.hdr_offset	= xfrm6_find_1stfragopt,
 };
 
-static struct inet6_protocol esp6_protocol = {
+static const struct inet6_protocol esp6_protocol = {
 	.handler 	=	xfrm6_rcv,
 	.err_handler	=	esp6_err,
 	.flags		=	INET6_PROTO_NOPOLICY,
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 4aae658..df159ff 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -500,17 +500,17 @@ unknown_rh:
 	return -1;
 }
 
-static struct inet6_protocol rthdr_protocol = {
+static const struct inet6_protocol rthdr_protocol = {
 	.handler	=	ipv6_rthdr_rcv,
 	.flags		=	INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
 };
 
-static struct inet6_protocol destopt_protocol = {
+static const struct inet6_protocol destopt_protocol = {
 	.handler	=	ipv6_destopt_rcv,
 	.flags		=	INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
 };
 
-static struct inet6_protocol nodata_protocol = {
+static const struct inet6_protocol nodata_protocol = {
 	.handler	=	dst_discard,
 	.flags		=	INET6_PROTO_NOPOLICY,
 };
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index eab62a7..f23ebbe 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -86,7 +86,7 @@ static inline struct sock *icmpv6_sk(struct net *net)
 
 static int icmpv6_rcv(struct sk_buff *skb);
 
-static struct inet6_protocol icmpv6_protocol = {
+static const struct inet6_protocol icmpv6_protocol = {
 	.handler	=	icmpv6_rcv,
 	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
@@ -323,7 +323,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
 	int iif = 0;
 	int addr_type = 0;
 	int len;
-	int hlimit, tclass;
+	int hlimit;
 	int err = 0;
 
 	if ((u8 *)hdr < skb->head ||
@@ -469,10 +469,6 @@ route_done:
 	if (hlimit < 0)
 		hlimit = ip6_dst_hoplimit(dst);
 
-	tclass = np->tclass;
-	if (tclass < 0)
-		tclass = 0;
-
 	msg.skb = skb;
 	msg.offset = skb_network_offset(skb);
 	msg.type = type;
@@ -488,8 +484,8 @@ route_done:
 
 	err = ip6_append_data(sk, icmpv6_getfrag, &msg,
 			      len + sizeof(struct icmp6hdr),
-			      sizeof(struct icmp6hdr),
-			      hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
+			      sizeof(struct icmp6hdr), hlimit,
+			      np->tclass, NULL, &fl, (struct rt6_info*)dst,
 			      MSG_DONTWAIT);
 	if (err) {
 		ip6_flush_pending_frames(sk);
@@ -522,7 +518,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	struct dst_entry *dst;
 	int err = 0;
 	int hlimit;
-	int tclass;
 
 	saddr = &ipv6_hdr(skb)->daddr;
 
@@ -562,10 +557,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	if (hlimit < 0)
 		hlimit = ip6_dst_hoplimit(dst);
 
-	tclass = np->tclass;
-	if (tclass < 0)
-		tclass = 0;
-
 	idev = in6_dev_get(skb->dev);
 
 	msg.skb = skb;
@@ -573,7 +564,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
 	msg.type = ICMPV6_ECHO_REPLY;
 
 	err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
-				sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
+				sizeof(struct icmp6hdr), hlimit, np->tclass, NULL, &fl,
 				(struct rt6_info*)dst, MSG_DONTWAIT);
 
 	if (err) {
@@ -592,7 +583,7 @@ out:
 
 static void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info)
 {
-	struct inet6_protocol *ipprot;
+	const struct inet6_protocol *ipprot;
 	int inner_offset;
 	int hash;
 	u8 nexthdr;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 52ee1dc..0e93ca5 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -164,12 +164,6 @@ static __inline__ void rt6_release(struct rt6_info *rt)
 		dst_free(&rt->u.dst);
 }
 
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-#define FIB_TABLE_HASHSZ 256
-#else
-#define FIB_TABLE_HASHSZ 1
-#endif
-
 static void fib6_link_table(struct net *net, struct fib6_table *tb)
 {
 	unsigned int h;
@@ -180,7 +174,7 @@ static void fib6_link_table(struct net *net, struct fib6_table *tb)
 	 */
 	rwlock_init(&tb->tb6_lock);
 
-	h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1);
+	h = tb->tb6_id & (FIB6_TABLE_HASHSZ - 1);
 
 	/*
 	 * No protection necessary, this is the only list mutatation
@@ -231,7 +225,7 @@ struct fib6_table *fib6_get_table(struct net *net, u32 id)
 
 	if (id == 0)
 		id = RT6_TABLE_MAIN;
-	h = id & (FIB_TABLE_HASHSZ - 1);
+	h = id & (FIB6_TABLE_HASHSZ - 1);
 	rcu_read_lock();
 	head = &net->ipv6.fib_table_hash[h];
 	hlist_for_each_entry_rcu(tb, node, head, tb6_hlist) {
@@ -382,7 +376,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 	arg.net = net;
 	w->args = &arg;
 
-	for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
+	for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_e = 0) {
 		e = 0;
 		head = &net->ipv6.fib_table_hash[h];
 		hlist_for_each_entry(tb, node, head, tb6_hlist) {
@@ -1368,7 +1362,7 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
 	unsigned int h;
 
 	rcu_read_lock();
-	for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
+	for (h = 0; h < FIB6_TABLE_HASHSZ; h++) {
 		head = &net->ipv6.fib_table_hash[h];
 		hlist_for_each_entry_rcu(table, node, head, tb6_hlist) {
 			write_lock_bh(&table->tb6_lock);
@@ -1483,7 +1477,7 @@ static int fib6_net_init(struct net *net)
 	if (!net->ipv6.rt6_stats)
 		goto out_timer;
 
-	net->ipv6.fib_table_hash = kcalloc(FIB_TABLE_HASHSZ,
+	net->ipv6.fib_table_hash = kcalloc(FIB6_TABLE_HASHSZ,
 					   sizeof(*net->ipv6.fib_table_hash),
 					   GFP_KERNEL);
 	if (!net->ipv6.fib_table_hash)
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6d6a427..237e2db 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -63,7 +63,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 
 	if (skb->pkt_type == PACKET_OTHERHOST) {
 		kfree_skb(skb);
-		return 0;
+		return NET_RX_DROP;
 	}
 
 	rcu_read_lock();
@@ -133,7 +133,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 		if (ipv6_parse_hopopts(skb) < 0) {
 			IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS);
 			rcu_read_unlock();
-			return 0;
+			return NET_RX_DROP;
 		}
 	}
 
@@ -149,7 +149,7 @@ err:
 drop:
 	rcu_read_unlock();
 	kfree_skb(skb);
-	return 0;
+	return NET_RX_DROP;
 }
 
 /*
@@ -159,7 +159,7 @@ drop:
 
 static int ip6_input_finish(struct sk_buff *skb)
 {
-	struct inet6_protocol *ipprot;
+	const struct inet6_protocol *ipprot;
 	unsigned int nhoff;
 	int nexthdr, raw;
 	u8 hash;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 87f8419..cd48801 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -57,18 +57,6 @@
 
 static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 
-static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
-{
-	static u32 ipv6_fragmentation_id = 1;
-	static DEFINE_SPINLOCK(ip6_id_lock);
-
-	spin_lock_bh(&ip6_id_lock);
-	fhdr->identification = htonl(ipv6_fragmentation_id);
-	if (++ipv6_fragmentation_id == 0)
-		ipv6_fragmentation_id = 1;
-	spin_unlock_bh(&ip6_id_lock);
-}
-
 int __ip6_local_out(struct sk_buff *skb)
 {
 	int len;
@@ -206,7 +194,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
 	struct ipv6hdr *hdr;
 	u8  proto = fl->proto;
 	int seg_len = skb->len;
-	int hlimit, tclass;
+	int hlimit = -1;
+	int tclass = 0;
 	u32 mtu;
 
 	if (opt) {
@@ -249,19 +238,13 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
 	/*
 	 *	Fill in the IPv6 header
 	 */
-
-	hlimit = -1;
-	if (np)
+	if (np) {
+		tclass = np->tclass;
 		hlimit = np->hop_limit;
+	}
 	if (hlimit < 0)
 		hlimit = ip6_dst_hoplimit(dst);
 
-	tclass = -1;
-	if (np)
-		tclass = np->tclass;
-	if (tclass < 0)
-		tclass = 0;
-
 	*(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
 
 	hdr->payload_len = htons(seg_len);
@@ -706,7 +689,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 		skb_reset_network_header(skb);
 		memcpy(skb_network_header(skb), tmp_hdr, hlen);
 
-		ipv6_select_ident(skb, fh);
+		ipv6_select_ident(fh);
 		fh->nexthdr = nexthdr;
 		fh->reserved = 0;
 		fh->frag_off = htons(IP6_MF);
@@ -844,7 +827,7 @@ slow_path:
 		fh->nexthdr = nexthdr;
 		fh->reserved = 0;
 		if (!frag_id) {
-			ipv6_select_ident(skb, fh);
+			ipv6_select_ident(fh);
 			frag_id = fh->identification;
 		} else
 			fh->identification = frag_id;
@@ -1087,11 +1070,13 @@ static inline int ip6_ufo_append_data(struct sock *sk,
 	if (!err) {
 		struct frag_hdr fhdr;
 
-		/* specify the length of each IP datagram fragment*/
-		skb_shinfo(skb)->gso_size = mtu - fragheaderlen -
-					    sizeof(struct frag_hdr);
+		/* Specify the length of each IPv6 datagram fragment.
+		 * It has to be a multiple of 8.
+		 */
+		skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
+					     sizeof(struct frag_hdr)) & ~7;
 		skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
-		ipv6_select_ident(skb, &fhdr);
+		ipv6_select_ident(&fhdr);
 		skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
 		__skb_queue_tail(&sk->sk_write_queue, skb);
 
@@ -1526,7 +1511,7 @@ int ip6_push_pending_frames(struct sock *sk)
 	err = ip6_local_out(skb);
 	if (err) {
 		if (err > 0)
-			err = np->recverr ? net_xmit_errno(err) : 0;
+			err = net_xmit_errno(err);
 		if (err)
 			goto error;
 	}
@@ -1535,6 +1520,7 @@ out:
 	ip6_cork_release(inet, np);
 	return err;
 error:
+	IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
 	goto out;
 }
 
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 51f410e..7d25bbe 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1036,7 +1036,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 	return 0;
 }
 
-static int
+static netdev_tx_t
 ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ip6_tnl *t = netdev_priv(dev);
@@ -1063,14 +1063,14 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 		goto tx_err;
 
 	t->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 
 tx_err:
 	stats->tx_errors++;
 	stats->tx_dropped++;
 	kfree_skb(skb);
 	t->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void ip6_tnl_set_cap(struct ip6_tnl *t)
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index c769f15..3907510 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -83,10 +83,6 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt,
 static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm);
 static void mroute_clean_tables(struct net *net);
 
-#ifdef CONFIG_IPV6_PIMSM_V2
-static struct inet6_protocol pim6_protocol;
-#endif
-
 static struct timer_list ipmr_expire_timer;
 
 
@@ -204,7 +200,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
-static struct seq_operations ip6mr_vif_seq_ops = {
+static const struct seq_operations ip6mr_vif_seq_ops = {
 	.start = ip6mr_vif_seq_start,
 	.next  = ip6mr_vif_seq_next,
 	.stop  = ip6mr_vif_seq_stop,
@@ -217,7 +213,7 @@ static int ip6mr_vif_open(struct inode *inode, struct file *file)
 			    sizeof(struct ipmr_vif_iter));
 }
 
-static struct file_operations ip6mr_vif_fops = {
+static const struct file_operations ip6mr_vif_fops = {
 	.owner	 = THIS_MODULE,
 	.open    = ip6mr_vif_open,
 	.read    = seq_read,
@@ -341,7 +337,7 @@ static int ipmr_mfc_open(struct inode *inode, struct file *file)
 			    sizeof(struct ipmr_mfc_iter));
 }
 
-static struct file_operations ip6mr_mfc_fops = {
+static const struct file_operations ip6mr_mfc_fops = {
 	.owner	 = THIS_MODULE,
 	.open    = ipmr_mfc_open,
 	.read    = seq_read,
@@ -410,13 +406,14 @@ static int pim6_rcv(struct sk_buff *skb)
 	return 0;
 }
 
-static struct inet6_protocol pim6_protocol = {
+static const struct inet6_protocol pim6_protocol = {
 	.handler	=	pim6_rcv,
 };
 
 /* Service routines creating virtual interfaces: PIMREG */
 
-static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
+				      struct net_device *dev)
 {
 	struct net *net = dev_net(dev);
 
@@ -427,7 +424,7 @@ static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
 			   MRT6MSG_WHOLEPKT);
 	read_unlock(&mrt_lock);
 	kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static const struct net_device_ops reg_vif_netdev_ops = {
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 79c172f..2f2a5ca 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -178,7 +178,7 @@ static const struct xfrm_type ipcomp6_type =
 	.hdr_offset	= xfrm6_find_1stfragopt,
 };
 
-static struct inet6_protocol ipcomp6_protocol =
+static const struct inet6_protocol ipcomp6_protocol =
 {
 	.handler	= xfrm6_rcv,
 	.err_handler	= ipcomp6_err,
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index a7fdf9a..f5e0682 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -315,6 +315,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 			goto e_inval;
 		if (val < -1 || val > 0xff)
 			goto e_inval;
+		/* RFC 3542, 6.5: default traffic class of 0x0 */
+		if (val == -1)
+			val = 0;
 		np->tclass = val;
 		retv = 0;
 		break;
@@ -1037,8 +1040,6 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
 
 	case IPV6_TCLASS:
 		val = np->tclass;
-		if (val < 0)
-			val = 0;
 		break;
 
 	case IPV6_RECVTCLASS:
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 4b264ed..f9fcf69 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2107,7 +2107,6 @@ static int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca,
 		for (j=0; j<i; j++)
 			(void) ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]);
 	} else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) {
-		struct inet6_dev *idev = pmc->idev;
 		struct ip6_sf_list *psf;
 
 		/* filter mode change */
@@ -2250,6 +2249,25 @@ static void igmp6_timer_handler(unsigned long data)
 	ma_put(ma);
 }
 
+/* Device changing type */
+
+void ipv6_mc_unmap(struct inet6_dev *idev)
+{
+	struct ifmcaddr6 *i;
+
+	/* Install multicast list, except for all-nodes (already installed) */
+
+	read_lock_bh(&idev->lock);
+	for (i = idev->mc_list; i; i = i->next)
+		igmp6_group_dropped(i);
+	read_unlock_bh(&idev->lock);
+}
+
+void ipv6_mc_remap(struct inet6_dev *idev)
+{
+	ipv6_mc_up(idev);
+}
+
 /* Device going down */
 
 void ipv6_mc_down(struct inet6_dev *idev)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 9eb68e9..7015478 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -98,7 +98,7 @@ static int pndisc_constructor(struct pneigh_entry *n);
 static void pndisc_destructor(struct pneigh_entry *n);
 static void pndisc_redo(struct sk_buff *skb);
 
-static struct neigh_ops ndisc_generic_ops = {
+static const struct neigh_ops ndisc_generic_ops = {
 	.family =		AF_INET6,
 	.solicit =		ndisc_solicit,
 	.error_report =		ndisc_error_report,
@@ -108,7 +108,7 @@ static struct neigh_ops ndisc_generic_ops = {
 	.queue_xmit =		dev_queue_xmit,
 };
 
-static struct neigh_ops ndisc_hh_ops = {
+static const struct neigh_ops ndisc_hh_ops = {
 	.family =		AF_INET6,
 	.solicit =		ndisc_solicit,
 	.error_report =		ndisc_error_report,
@@ -119,7 +119,7 @@ static struct neigh_ops ndisc_hh_ops = {
 };
 
 
-static struct neigh_ops ndisc_direct_ops = {
+static const struct neigh_ops ndisc_direct_ops = {
 	.family =		AF_INET6,
 	.output =		dev_queue_xmit,
 	.connected_output =	dev_queue_xmit,
@@ -955,8 +955,8 @@ static void ndisc_recv_na(struct sk_buff *skb)
 		 */
 		if (skb->pkt_type != PACKET_LOOPBACK)
 			ND_PRINTK1(KERN_WARNING
-			   "ICMPv6 NA: someone advertises our address on %s!\n",
-			   ifp->idev->dev->name);
+			   "ICMPv6 NA: someone advertises our address %pI6 on %s!\n",
+			   &ifp->addr, ifp->idev->dev->name);
 		in6_ifa_put(ifp);
 		return;
 	}
@@ -1151,10 +1151,6 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 			   skb->dev->name);
 		return;
 	}
-	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
-		in6_dev_put(in6_dev);
-		return;
-	}
 
 	if (!ndisc_parse_options(opt, optlen, &ndopts)) {
 		in6_dev_put(in6_dev);
@@ -1163,6 +1159,10 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 		return;
 	}
 
+	/* skip route and link configuration on routers */
+	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
+		goto skip_linkparms;
+
 #ifdef CONFIG_IPV6_NDISC_NODETYPE
 	/* skip link-specific parameters from interior routers */
 	if (skb->ndisc_nodetype == NDISC_NODETYPE_NODEFAULT)
@@ -1283,9 +1283,7 @@ skip_defrtr:
 		}
 	}
 
-#ifdef CONFIG_IPV6_NDISC_NODETYPE
 skip_linkparms:
-#endif
 
 	/*
 	 *	Process options.
@@ -1312,6 +1310,10 @@ skip_linkparms:
 			     NEIGH_UPDATE_F_ISROUTER);
 	}
 
+	/* skip route and link configuration on routers */
+	if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra)
+		goto out;
+
 #ifdef CONFIG_IPV6_ROUTE_INFO
 	if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) {
 		struct nd_opt_hdr *p;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index ced1f2c..cc9f8ef 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -8,7 +8,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/capability.h>
 #include <linux/in.h>
 #include <linux/skbuff.h>
@@ -222,16 +222,11 @@ get_entry(void *base, unsigned int offset)
 
 /* All zeroes == unconditional rule. */
 /* Mildly perf critical (only if packet tracing is on) */
-static inline int
-unconditional(const struct ip6t_ip6 *ipv6)
+static inline bool unconditional(const struct ip6t_ip6 *ipv6)
 {
-	unsigned int i;
-
-	for (i = 0; i < sizeof(*ipv6); i++)
-		if (((char *)ipv6)[i])
-			break;
+	static const struct ip6t_ip6 uncond;
 
-	return (i == sizeof(*ipv6));
+	return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
 }
 
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
@@ -745,6 +740,21 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
 	return ret;
 }
 
+static bool check_underflow(struct ip6t_entry *e)
+{
+	const struct ip6t_entry_target *t;
+	unsigned int verdict;
+
+	if (!unconditional(&e->ipv6))
+		return false;
+	t = ip6t_get_target(e);
+	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
+		return false;
+	verdict = ((struct ip6t_standard_target *)t)->verdict;
+	verdict = -verdict - 1;
+	return verdict == NF_DROP || verdict == NF_ACCEPT;
+}
+
 static int
 check_entry_size_and_hooks(struct ip6t_entry *e,
 			   struct xt_table_info *newinfo,
@@ -752,6 +762,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 			   unsigned char *limit,
 			   const unsigned int *hook_entries,
 			   const unsigned int *underflows,
+			   unsigned int valid_hooks,
 			   unsigned int *i)
 {
 	unsigned int h;
@@ -771,15 +782,21 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
 
 	/* Check hooks & underflows */
 	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+		if (!(valid_hooks & (1 << h)))
+			continue;
 		if ((unsigned char *)e - base == hook_entries[h])
 			newinfo->hook_entry[h] = hook_entries[h];
-		if ((unsigned char *)e - base == underflows[h])
+		if ((unsigned char *)e - base == underflows[h]) {
+			if (!check_underflow(e)) {
+				pr_err("Underflows must be unconditional and "
+				       "use the STANDARD target with "
+				       "ACCEPT/DROP\n");
+				return -EINVAL;
+			}
 			newinfo->underflow[h] = underflows[h];
+		}
 	}
 
-	/* FIXME: underflows must be unconditional, standard verdicts
-	   < 0 (not IP6T_RETURN). --RR */
-
 	/* Clear counters and comefrom */
 	e->counters = ((struct xt_counters) { 0, 0 });
 	e->comefrom = 0;
@@ -842,7 +859,7 @@ translate_table(const char *name,
 				newinfo,
 				entry0,
 				entry0 + size,
-				hook_entries, underflows, &i);
+				hook_entries, underflows, valid_hooks, &i);
 	if (ret != 0)
 		return ret;
 
@@ -2083,7 +2100,8 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 	return ret;
 }
 
-struct xt_table *ip6t_register_table(struct net *net, struct xt_table *table,
+struct xt_table *ip6t_register_table(struct net *net,
+				     const struct xt_table *table,
 				     const struct ip6t_replace *repl)
 {
 	int ret;
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index db610ba..ca287f6 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -23,7 +23,6 @@ static bool
 eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 	unsigned char eui64[8];
-	int i = 0;
 
 	if (!(skb_mac_header(skb) >= skb->head &&
 	      skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
@@ -42,12 +41,8 @@ eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 			eui64[4] = 0xfe;
 			eui64[0] ^= 0x02;
 
-			i = 0;
-			while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]
-			       && i < 8)
-				i++;
-
-			if (i == 8)
+			if (!memcmp(ipv6_hdr(skb)->saddr.s6_addr + 8, eui64,
+				    sizeof(eui64)))
 				return true;
 		}
 	}
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index ef5a0a3..6f4383a 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -51,11 +51,11 @@ static struct
 	.term = IP6T_ERROR_INIT,		/* ERROR */
 };
 
-static struct xt_table packet_filter = {
+static const struct xt_table packet_filter = {
 	.name		= "filter",
 	.valid_hooks	= FILTER_VALID_HOOKS,
 	.me		= THIS_MODULE,
-	.af		= AF_INET6,
+	.af		= NFPROTO_IPV6,
 };
 
 /* The work comes in here from netfilter.c. */
@@ -95,21 +95,21 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 	{
 		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_FILTER,
 	},
 	{
 		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP6_PRI_FILTER,
 	},
 	{
 		.hook		= ip6t_local_out_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_FILTER,
 	},
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index ab0d398..0ad9143 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -21,7 +21,7 @@ MODULE_DESCRIPTION("ip6tables mangle table");
 			    (1 << NF_INET_LOCAL_OUT) | \
 			    (1 << NF_INET_POST_ROUTING))
 
-static struct
+static const struct
 {
 	struct ip6t_replace repl;
 	struct ip6t_standard entries[5];
@@ -57,11 +57,11 @@ static struct
 	.term = IP6T_ERROR_INIT,		/* ERROR */
 };
 
-static struct xt_table packet_mangler = {
+static const struct xt_table packet_mangler = {
 	.name		= "mangle",
 	.valid_hooks	= MANGLE_VALID_HOOKS,
 	.me		= THIS_MODULE,
-	.af		= AF_INET6,
+	.af		= NFPROTO_IPV6,
 };
 
 /* The work comes in here from netfilter.c. */
@@ -136,35 +136,35 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 	{
 		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_local_out_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
 	{
 		.hook		= ip6t_post_routing_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP6_PRI_MANGLE,
 	},
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 4b792b6..ed1a118 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -8,7 +8,7 @@
 
 #define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
 
-static struct
+static const struct
 {
 	struct ip6t_replace repl;
 	struct ip6t_standard entries[2];
@@ -35,11 +35,11 @@ static struct
 	.term = IP6T_ERROR_INIT,		/* ERROR */
 };
 
-static struct xt_table packet_raw = {
+static const struct xt_table packet_raw = {
 	.name = "raw",
 	.valid_hooks = RAW_VALID_HOOKS,
 	.me = THIS_MODULE,
-	.af = AF_INET6,
+	.af = NFPROTO_IPV6,
 };
 
 /* The work comes in here from netfilter.c. */
@@ -68,14 +68,14 @@ ip6t_local_out_hook(unsigned int hook,
 static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 	{
 	  .hook = ip6t_pre_routing_hook,
-	  .pf = PF_INET6,
+	  .pf = NFPROTO_IPV6,
 	  .hooknum = NF_INET_PRE_ROUTING,
 	  .priority = NF_IP6_PRI_FIRST,
 	  .owner = THIS_MODULE,
 	},
 	{
 	  .hook = ip6t_local_out_hook,
-	  .pf = PF_INET6,
+	  .pf = NFPROTO_IPV6,
 	  .hooknum = NF_INET_LOCAL_OUT,
 	  .priority = NF_IP6_PRI_FIRST,
 	  .owner = THIS_MODULE,
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 0ea37ff..41b444c 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -26,7 +26,7 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
 				(1 << NF_INET_FORWARD) | \
 				(1 << NF_INET_LOCAL_OUT)
 
-static struct
+static const struct
 {
 	struct ip6t_replace repl;
 	struct ip6t_standard entries[3];
@@ -56,11 +56,11 @@ static struct
 	.term = IP6T_ERROR_INIT,		/* ERROR */
 };
 
-static struct xt_table security_table = {
+static const struct xt_table security_table = {
 	.name		= "security",
 	.valid_hooks	= SECURITY_VALID_HOOKS,
 	.me		= THIS_MODULE,
-	.af		= AF_INET6,
+	.af		= NFPROTO_IPV6,
 };
 
 static unsigned int
@@ -101,21 +101,21 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
 	{
 		.hook		= ip6t_local_in_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_SECURITY,
 	},
 	{
 		.hook		= ip6t_forward_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_FORWARD,
 		.priority	= NF_IP6_PRI_SECURITY,
 	},
 	{
 		.hook		= ip6t_local_out_hook,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_SECURITY,
 	},
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 2a15c2d..5f2ec20 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -27,6 +27,7 @@
 #include <net/netfilter/nf_conntrack_l3proto.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
+#include <net/netfilter/nf_log.h>
 
 static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
 			      struct nf_conntrack_tuple *tuple)
@@ -176,8 +177,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
 	}
 
 	ret = helper->help(skb, protoff, ct, ctinfo);
-	if (ret != NF_ACCEPT)
+	if (ret != NF_ACCEPT) {
+		nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL,
+			      "nf_ct_%s: dropping packet", helper->name);
 		return ret;
+	}
 out:
 	/* We've seen it coming out the other side: confirm it */
 	return nf_conntrack_confirm(skb);
@@ -265,42 +269,42 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
 	{
 		.hook		= ipv6_defrag,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
 	},
 	{
 		.hook		= ipv6_conntrack_in,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_PRE_ROUTING,
 		.priority	= NF_IP6_PRI_CONNTRACK,
 	},
 	{
 		.hook		= ipv6_conntrack_local,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_CONNTRACK,
 	},
 	{
 		.hook		= ipv6_defrag,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_OUT,
 		.priority	= NF_IP6_PRI_CONNTRACK_DEFRAG,
 	},
 	{
 		.hook		= ipv6_confirm,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_POST_ROUTING,
 		.priority	= NF_IP6_PRI_LAST,
 	},
 	{
 		.hook		= ipv6_confirm,
 		.owner		= THIS_MODULE,
-		.pf		= PF_INET6,
+		.pf		= NFPROTO_IPV6,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP6_PRI_LAST-1,
 	},
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 590ddef..c9605c3 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -101,7 +101,7 @@ static struct snmp_mib snmp6_icmp6_list[] = {
 };
 
 /* RFC 4293 v6 ICMPMsgStatsTable; named items for RFC 2466 compatibility */
-static char *icmp6type2name[256] = {
+static const char *const icmp6type2name[256] = {
 	[ICMPV6_DEST_UNREACH] = "DestUnreachs",
 	[ICMPV6_PKT_TOOBIG] = "PktTooBigs",
 	[ICMPV6_TIME_EXCEED] = "TimeExcds",
@@ -144,7 +144,7 @@ static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib)
 	/* print by name -- deprecated items */
 	for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
 		int icmptype;
-		char *p;
+		const char *p;
 
 		icmptype = i & 0xff;
 		p = icmp6type2name[icmptype];
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index 9ab7891..1fa3468 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -20,27 +20,16 @@
  *      - Removed unused variable 'inet6_protocol_base'
  *      - Modified inet6_del_protocol() to correctly maintain copy bit.
  */
-
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/in6.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
-#include <linux/if_arp.h>
-
-#include <net/sock.h>
-#include <net/snmp.h>
-
-#include <net/ipv6.h>
+#include <linux/spinlock.h>
 #include <net/protocol.h>
 
-struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
+const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
 static DEFINE_SPINLOCK(inet6_proto_lock);
 
 
-int inet6_add_protocol(struct inet6_protocol *prot, unsigned char protocol)
+int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
 {
 	int ret, hash = protocol & (MAX_INET_PROTOS - 1);
 
@@ -64,7 +53,7 @@ EXPORT_SYMBOL(inet6_add_protocol);
  *	Remove a protocol from the hash tables.
  */
 
-int inet6_del_protocol(struct inet6_protocol *prot, unsigned char protocol)
+int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol)
 {
 	int ret, hash = protocol & (MAX_INET_PROTOS - 1);
 
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d6c3c1c..7d675b8 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -642,7 +642,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
 	err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
 		      dst_output);
 	if (err > 0)
-		err = np->recverr ? net_xmit_errno(err) : 0;
+		err = net_xmit_errno(err);
 	if (err)
 		goto error;
 out:
@@ -653,6 +653,8 @@ error_fault:
 	kfree_skb(skb);
 error:
 	IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
+	if (err == -ENOBUFS && !np->recverr)
+		err = 0;
 	return err;
 }
 
@@ -877,11 +879,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 			hlimit = ip6_dst_hoplimit(dst);
 	}
 
-	if (tclass < 0) {
+	if (tclass < 0)
 		tclass = np->tclass;
-		if (tclass < 0)
-			tclass = 0;
-	}
 
 	if (msg->msg_flags&MSG_CONFIRM)
 		goto do_confirm;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 2642a41..da5bd0e 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -627,7 +627,7 @@ fail_hdr:
 	return -1;
 }
 
-static struct inet6_protocol frag_protocol =
+static const struct inet6_protocol frag_protocol =
 {
 	.handler	=	ipv6_frag_rcv,
 	.flags		=	INET6_PROTO_NOPOLICY,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 1473ee0..77aecbe 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -481,7 +481,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
 
 	pref = rinfo->route_pref;
 	if (pref == ICMPV6_ROUTER_PREF_INVALID)
-		pref = ICMPV6_ROUTER_PREF_MEDIUM;
+		return -EINVAL;
 
 	lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ);
 
@@ -665,7 +665,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad
 				net->ipv6.sysctl.ip6_rt_gc_elasticity = 1;
 				net->ipv6.sysctl.ip6_rt_gc_min_interval = 0;
 
-				ip6_dst_gc(net->ipv6.ip6_dst_ops);
+				ip6_dst_gc(&net->ipv6.ip6_dst_ops);
 
 				net->ipv6.sysctl.ip6_rt_gc_elasticity =
 					saved_rt_elasticity;
@@ -970,7 +970,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
 	if (unlikely(idev == NULL))
 		return NULL;
 
-	rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+	rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
 	if (unlikely(rt == NULL)) {
 		in6_dev_put(idev);
 		goto out;
@@ -1060,7 +1060,7 @@ static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg),
 static int ip6_dst_gc(struct dst_ops *ops)
 {
 	unsigned long now = jiffies;
-	struct net *net = ops->dst_net;
+	struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops);
 	int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval;
 	int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size;
 	int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity;
@@ -1154,7 +1154,7 @@ int ip6_route_add(struct fib6_config *cfg)
 		goto out;
 	}
 
-	rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+	rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
 
 	if (rt == NULL) {
 		err = -ENOMEM;
@@ -1643,7 +1643,7 @@ out:
 static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
 {
 	struct net *net = dev_net(ort->rt6i_dev);
-	struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+	struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
 
 	if (rt) {
 		rt->u.dst.input = ort->u.dst.input;
@@ -1923,7 +1923,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 				    int anycast)
 {
 	struct net *net = dev_net(idev->dev);
-	struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops);
+	struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops);
 	struct neighbour *neigh;
 
 	if (rt == NULL)
@@ -2501,7 +2501,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v)
 		   net->ipv6.rt6_stats->fib_rt_alloc,
 		   net->ipv6.rt6_stats->fib_rt_entries,
 		   net->ipv6.rt6_stats->fib_rt_cache,
-		   atomic_read(&net->ipv6.ip6_dst_ops->entries),
+		   atomic_read(&net->ipv6.ip6_dst_ops.entries),
 		   net->ipv6.rt6_stats->fib_discarded_routes);
 
 	return 0;
@@ -2637,7 +2637,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net)
 
 	if (table) {
 		table[0].data = &net->ipv6.sysctl.flush_delay;
-		table[1].data = &net->ipv6.ip6_dst_ops->gc_thresh;
+		table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh;
 		table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
 		table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
 		table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
@@ -2655,12 +2655,8 @@ static int ip6_route_net_init(struct net *net)
 {
 	int ret = -ENOMEM;
 
-	net->ipv6.ip6_dst_ops = kmemdup(&ip6_dst_ops_template,
-					sizeof(*net->ipv6.ip6_dst_ops),
-					GFP_KERNEL);
-	if (!net->ipv6.ip6_dst_ops)
-		goto out;
-	net->ipv6.ip6_dst_ops->dst_net = hold_net(net);
+	memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template,
+	       sizeof(net->ipv6.ip6_dst_ops));
 
 	net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template,
 					   sizeof(*net->ipv6.ip6_null_entry),
@@ -2669,7 +2665,7 @@ static int ip6_route_net_init(struct net *net)
 		goto out_ip6_dst_ops;
 	net->ipv6.ip6_null_entry->u.dst.path =
 		(struct dst_entry *)net->ipv6.ip6_null_entry;
-	net->ipv6.ip6_null_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
+	net->ipv6.ip6_null_entry->u.dst.ops = &net->ipv6.ip6_dst_ops;
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 	net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
@@ -2679,7 +2675,7 @@ static int ip6_route_net_init(struct net *net)
 		goto out_ip6_null_entry;
 	net->ipv6.ip6_prohibit_entry->u.dst.path =
 		(struct dst_entry *)net->ipv6.ip6_prohibit_entry;
-	net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
+	net->ipv6.ip6_prohibit_entry->u.dst.ops = &net->ipv6.ip6_dst_ops;
 
 	net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
 					       sizeof(*net->ipv6.ip6_blk_hole_entry),
@@ -2688,7 +2684,7 @@ static int ip6_route_net_init(struct net *net)
 		goto out_ip6_prohibit_entry;
 	net->ipv6.ip6_blk_hole_entry->u.dst.path =
 		(struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
-	net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
+	net->ipv6.ip6_blk_hole_entry->u.dst.ops = &net->ipv6.ip6_dst_ops;
 #endif
 
 	net->ipv6.sysctl.flush_delay = 0;
@@ -2717,8 +2713,6 @@ out_ip6_null_entry:
 	kfree(net->ipv6.ip6_null_entry);
 #endif
 out_ip6_dst_ops:
-	release_net(net->ipv6.ip6_dst_ops->dst_net);
-	kfree(net->ipv6.ip6_dst_ops);
 	goto out;
 }
 
@@ -2733,8 +2727,6 @@ static void ip6_route_net_exit(struct net *net)
 	kfree(net->ipv6.ip6_prohibit_entry);
 	kfree(net->ipv6.ip6_blk_hole_entry);
 #endif
-	release_net(net->ipv6.ip6_dst_ops->dst_net);
-	kfree(net->ipv6.ip6_dst_ops);
 }
 
 static struct pernet_operations ip6_route_net_ops = {
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 98b7327..0ae4f64 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -609,7 +609,8 @@ static inline __be32 try_6to4(struct in6_addr *v6dst)
  *	and that skb is filled properly by that function.
  */
 
-static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
+				     struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct net_device_stats *stats = &tunnel->dev->stats;
@@ -753,7 +754,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 			stats->tx_dropped++;
 			dev_kfree_skb(skb);
 			tunnel->recursion--;
-			return 0;
+			return NETDEV_TX_OK;
 		}
 		if (skb->sk)
 			skb_set_owner_w(new_skb, skb->sk);
@@ -778,7 +779,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 	iph->version		=	4;
 	iph->ihl		=	sizeof(struct iphdr)>>2;
 	if (mtu > IPV6_MIN_MTU)
-		iph->frag_off	=	htons(IP_DF);
+		iph->frag_off	=	tiph->frag_off;
 	else
 		iph->frag_off	=	0;
 
@@ -794,7 +795,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	IPTUNNEL_XMIT();
 	tunnel->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 
 tx_error_icmp:
 	dst_link_failure(skb);
@@ -802,7 +803,7 @@ tx_error:
 	stats->tx_errors++;
 	dev_kfree_skb(skb);
 	tunnel->recursion--;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void ipip6_tunnel_bind_dev(struct net_device *dev)
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 8c25139..6b6ae91 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -74,12 +74,13 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
 	return child;
 }
 
-static DEFINE_PER_CPU(__u32, cookie_scratch)[16 + 5 + SHA_WORKSPACE_WORDS];
+static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
+		      ipv6_cookie_scratch);
 
 static u32 cookie_hash(struct in6_addr *saddr, struct in6_addr *daddr,
 		       __be16 sport, __be16 dport, u32 count, int c)
 {
-	__u32 *tmp = __get_cpu_var(cookie_scratch);
+	__u32 *tmp = __get_cpu_var(ipv6_cookie_scratch);
 
 	/*
 	 * we have 320 bits of information to hash, copy in the remaining
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index a031034..0dc6a4e 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -40,7 +40,7 @@ static ctl_table ipv6_table_template[] = {
 	{ .ctl_name = 0 }
 };
 
-static ctl_table ipv6_table[] = {
+static ctl_table ipv6_rotable[] = {
 	{
 		.ctl_name	= NET_IPV6_MLD_MAX_MSF,
 		.procname	= "mld_max_msf",
@@ -130,7 +130,7 @@ int ipv6_sysctl_register(void)
 {
 	int err = -ENOMEM;
 
-	ip6_header = register_net_sysctl_rotable(net_ipv6_ctl_path, ipv6_table);
+	ip6_header = register_net_sysctl_rotable(net_ipv6_ctl_path, ipv6_rotable);
 	if (ip6_header == NULL)
 		goto out;
 
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index d849dd5..21d100b 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -75,11 +75,11 @@ static void	tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
 
 static int	tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
 
-static struct inet_connection_sock_af_ops ipv6_mapped;
-static struct inet_connection_sock_af_ops ipv6_specific;
+static const struct inet_connection_sock_af_ops ipv6_mapped;
+static const struct inet_connection_sock_af_ops ipv6_specific;
 #ifdef CONFIG_TCP_MD5SIG
-static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
-static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
+static const struct tcp_sock_af_ops tcp_sock_ipv6_specific;
+static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
 #else
 static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
 						   struct in6_addr *addr)
@@ -591,7 +591,7 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
 			}
 			sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
 		}
-		if (tcp_alloc_md5sig_pool() == NULL) {
+		if (tcp_alloc_md5sig_pool(sk) == NULL) {
 			kfree(newkey);
 			return -ENOMEM;
 		}
@@ -894,7 +894,7 @@ struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
 };
 
 #ifdef CONFIG_TCP_MD5SIG
-static struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
+static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
 	.md5_lookup	=	tcp_v6_reqsk_md5_lookup,
 	.calc_md5_hash	=	tcp_v6_md5_hash_skb,
 };
@@ -1003,6 +1003,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
 	skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
 
 	t1 = (struct tcphdr *) skb_push(buff, tot_len);
+	skb_reset_transport_header(skb);
 
 	/* Swap the send and the receive. */
 	memset(t1, 0, sizeof(*t1));
@@ -1760,7 +1761,7 @@ static int tcp_v6_remember_stamp(struct sock *sk)
 	return 0;
 }
 
-static struct inet_connection_sock_af_ops ipv6_specific = {
+static const struct inet_connection_sock_af_ops ipv6_specific = {
 	.queue_xmit	   = inet6_csk_xmit,
 	.send_check	   = tcp_v6_send_check,
 	.rebuild_header	   = inet6_sk_rebuild_header,
@@ -1780,7 +1781,7 @@ static struct inet_connection_sock_af_ops ipv6_specific = {
 };
 
 #ifdef CONFIG_TCP_MD5SIG
-static struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
+static const struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
 	.md5_lookup	=	tcp_v6_md5_lookup,
 	.calc_md5_hash	=	tcp_v6_md5_hash_skb,
 	.md5_add	=	tcp_v6_md5_add_func,
@@ -1792,7 +1793,7 @@ static struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
  *	TCP over IPv4 via INET6 API
  */
 
-static struct inet_connection_sock_af_ops ipv6_mapped = {
+static const struct inet_connection_sock_af_ops ipv6_mapped = {
 	.queue_xmit	   = ip_queue_xmit,
 	.send_check	   = tcp_v4_send_check,
 	.rebuild_header	   = inet_sk_rebuild_header,
@@ -1812,7 +1813,7 @@ static struct inet_connection_sock_af_ops ipv6_mapped = {
 };
 
 #ifdef CONFIG_TCP_MD5SIG
-static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = {
+static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = {
 	.md5_lookup	=	tcp_v4_md5_lookup,
 	.calc_md5_hash	=	tcp_v4_md5_hash_skb,
 	.md5_add	=	tcp_v6_md5_add_func,
@@ -1845,7 +1846,7 @@ static int tcp_v6_init_sock(struct sock *sk)
 	/* See draft-stevens-tcpca-spec-01 for discussion of the
 	 * initialization of these values.
 	 */
-	tp->snd_ssthresh = 0x7fffffff;
+	tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
 	tp->snd_cwnd_clamp = ~0;
 	tp->mss_cache = 536;
 
@@ -1968,7 +1969,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
 		   jiffies_to_clock_t(icsk->icsk_rto),
 		   jiffies_to_clock_t(icsk->icsk_ack.ato),
 		   (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
-		   tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
+		   tp->snd_cwnd,
+		   tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh
 		   );
 }
 
@@ -2092,7 +2094,7 @@ struct proto tcpv6_prot = {
 #endif
 };
 
-static struct inet6_protocol tcpv6_protocol = {
+static const struct inet6_protocol tcpv6_protocol = {
 	.handler	=	tcp_v6_rcv,
 	.err_handler	=	tcp_v6_err,
 	.gso_send_check	=	tcp_v6_gso_send_check,
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 633ad78..51e2832 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -133,13 +133,13 @@ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 			break;
 }
 
-static struct inet6_protocol tunnel6_protocol = {
+static const struct inet6_protocol tunnel6_protocol = {
 	.handler	= tunnel6_rcv,
 	.err_handler	= tunnel6_err,
 	.flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
-static struct inet6_protocol tunnel46_protocol = {
+static const struct inet6_protocol tunnel46_protocol = {
 	.handler	= tunnel46_rcv,
 	.err_handler	= tunnel6_err,
 	.flags          = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 33b59bd..b265b70 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -638,6 +638,47 @@ static void udp_v6_flush_pending_frames(struct sock *sk)
 	}
 }
 
+/**
+ * 	udp6_hwcsum_outgoing  -  handle outgoing HW checksumming
+ * 	@sk: 	socket we are sending on
+ * 	@skb: 	sk_buff containing the filled-in UDP header
+ * 	        (checksum field must be zeroed out)
+ */
+static void udp6_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
+				 const struct in6_addr *saddr,
+				 const struct in6_addr *daddr, int len)
+{
+	unsigned int offset;
+	struct udphdr *uh = udp_hdr(skb);
+	__wsum csum = 0;
+
+	if (skb_queue_len(&sk->sk_write_queue) == 1) {
+		/* Only one fragment on the socket.  */
+		skb->csum_start = skb_transport_header(skb) - skb->head;
+		skb->csum_offset = offsetof(struct udphdr, check);
+		uh->check = ~csum_ipv6_magic(saddr, daddr, len, IPPROTO_UDP, 0);
+	} else {
+		/*
+		 * HW-checksum won't work as there are two or more
+		 * fragments on the socket so that all csums of sk_buffs
+		 * should be together
+		 */
+		offset = skb_transport_offset(skb);
+		skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);
+
+		skb->ip_summed = CHECKSUM_NONE;
+
+		skb_queue_walk(&sk->sk_write_queue, skb) {
+			csum = csum_add(csum, skb->csum);
+		}
+
+		uh->check = csum_ipv6_magic(saddr, daddr, len, IPPROTO_UDP,
+					    csum);
+		if (uh->check == 0)
+			uh->check = CSUM_MANGLED_0;
+	}
+}
+
 /*
  *	Sending
  */
@@ -668,7 +709,11 @@ static int udp_v6_push_pending_frames(struct sock *sk)
 
 	if (is_udplite)
 		csum = udplite_csum_outgoing(sk, skb);
-	 else
+	else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
+		udp6_hwcsum_outgoing(sk, skb, &fl->fl6_src, &fl->fl6_dst,
+				     up->len);
+		goto send;
+	} else
 		csum = udp_csum_outgoing(sk, skb);
 
 	/* add protocol-dependent pseudo-header */
@@ -677,13 +722,20 @@ static int udp_v6_push_pending_frames(struct sock *sk)
 	if (uh->check == 0)
 		uh->check = CSUM_MANGLED_0;
 
+send:
 	err = ip6_push_pending_frames(sk);
+	if (err) {
+		if (err == -ENOBUFS && !inet6_sk(sk)->recverr) {
+			UDP6_INC_STATS_USER(sock_net(sk),
+					    UDP_MIB_SNDBUFERRORS, is_udplite);
+			err = 0;
+		}
+	} else
+		UDP6_INC_STATS_USER(sock_net(sk),
+				    UDP_MIB_OUTDATAGRAMS, is_udplite);
 out:
 	up->len = 0;
 	up->pending = 0;
-	if (!err)
-		UDP6_INC_STATS_USER(sock_net(sk),
-				UDP_MIB_OUTDATAGRAMS, is_udplite);
 	return err;
 }
 
@@ -900,11 +952,8 @@ do_udp_sendmsg:
 			hlimit = ip6_dst_hoplimit(dst);
 	}
 
-	if (tclass < 0) {
+	if (tclass < 0)
 		tclass = np->tclass;
-		if (tclass < 0)
-			tclass = 0;
-	}
 
 	if (msg->msg_flags&MSG_CONFIRM)
 		goto do_confirm;
@@ -1032,9 +1081,102 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
 }
 #endif
 
-static struct inet6_protocol udpv6_protocol = {
+static int udp6_ufo_send_check(struct sk_buff *skb)
+{
+	struct ipv6hdr *ipv6h;
+	struct udphdr *uh;
+
+	if (!pskb_may_pull(skb, sizeof(*uh)))
+		return -EINVAL;
+
+	ipv6h = ipv6_hdr(skb);
+	uh = udp_hdr(skb);
+
+	uh->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
+				     IPPROTO_UDP, 0);
+	skb->csum_start = skb_transport_header(skb) - skb->head;
+	skb->csum_offset = offsetof(struct udphdr, check);
+	skb->ip_summed = CHECKSUM_PARTIAL;
+	return 0;
+}
+
+static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, int features)
+{
+	struct sk_buff *segs = ERR_PTR(-EINVAL);
+	unsigned int mss;
+	unsigned int unfrag_ip6hlen, unfrag_len;
+	struct frag_hdr *fptr;
+	u8 *mac_start, *prevhdr;
+	u8 nexthdr;
+	u8 frag_hdr_sz = sizeof(struct frag_hdr);
+	int offset;
+	__wsum csum;
+
+	mss = skb_shinfo(skb)->gso_size;
+	if (unlikely(skb->len <= mss))
+		goto out;
+
+	if (skb_gso_ok(skb, features | NETIF_F_GSO_ROBUST)) {
+		/* Packet is from an untrusted source, reset gso_segs. */
+		int type = skb_shinfo(skb)->gso_type;
+
+		if (unlikely(type & ~(SKB_GSO_UDP | SKB_GSO_DODGY) ||
+			     !(type & (SKB_GSO_UDP))))
+			goto out;
+
+		skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(skb->len, mss);
+
+		segs = NULL;
+		goto out;
+	}
+
+	/* Do software UFO. Complete and fill in the UDP checksum as HW cannot
+	 * do checksum of UDP packets sent as multiple IP fragments.
+	 */
+	offset = skb->csum_start - skb_headroom(skb);
+	csum = skb_checksum(skb, offset, skb->len- offset, 0);
+	offset += skb->csum_offset;
+	*(__sum16 *)(skb->data + offset) = csum_fold(csum);
+	skb->ip_summed = CHECKSUM_NONE;
+
+	/* Check if there is enough headroom to insert fragment header. */
+	if ((skb_headroom(skb) < frag_hdr_sz) &&
+	    pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC))
+		goto out;
+
+	/* Find the unfragmentable header and shift it left by frag_hdr_sz
+	 * bytes to insert fragment header.
+	 */
+	unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr);
+	nexthdr = *prevhdr;
+	*prevhdr = NEXTHDR_FRAGMENT;
+	unfrag_len = skb_network_header(skb) - skb_mac_header(skb) +
+		     unfrag_ip6hlen;
+	mac_start = skb_mac_header(skb);
+	memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len);
+
+	skb->mac_header -= frag_hdr_sz;
+	skb->network_header -= frag_hdr_sz;
+
+	fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);
+	fptr->nexthdr = nexthdr;
+	fptr->reserved = 0;
+	ipv6_select_ident(fptr);
+
+	/* Fragment the skb. ipv6 header and the remaining fields of the
+	 * fragment header are updated in ipv6_gso_segment()
+	 */
+	segs = skb_segment(skb, features);
+
+out:
+	return segs;
+}
+
+static const struct inet6_protocol udpv6_protocol = {
 	.handler	=	udpv6_rcv,
 	.err_handler	=	udpv6_err,
+	.gso_send_check =	udp6_ufo_send_check,
+	.gso_segment	=	udp6_ufo_fragment,
 	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index 4818c48..d737a27 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -25,7 +25,7 @@ static void udplitev6_err(struct sk_buff *skb,
 	__udp6_lib_err(skb, opt, type, code, offset, info, &udplite_table);
 }
 
-static struct inet6_protocol udplitev6_protocol = {
+static const struct inet6_protocol udplitev6_protocol = {
 	.handler	=	udplitev6_rcv,
 	.err_handler	=	udplitev6_err,
 	.flags		=	INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 3a3c677..8ec3d45 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -306,9 +306,26 @@ static void xfrm6_policy_fini(void)
 	xfrm_policy_unregister_afinfo(&xfrm6_policy_afinfo);
 }
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table xfrm6_policy_table[] = {
+	{
+		.ctl_name       = CTL_UNNUMBERED,
+		.procname       = "xfrm6_gc_thresh",
+		.data	   	= &xfrm6_dst_ops.gc_thresh,
+		.maxlen	 	= sizeof(int),
+		.mode	   	= 0644,
+		.proc_handler   = proc_dointvec,
+	},
+	{ }
+};
+
+static struct ctl_table_header *sysctl_hdr;
+#endif
+
 int __init xfrm6_init(void)
 {
 	int ret;
+	unsigned int gc_thresh;
 
 	ret = xfrm6_policy_init();
 	if (ret)
@@ -317,6 +334,23 @@ int __init xfrm6_init(void)
 	ret = xfrm6_state_init();
 	if (ret)
 		goto out_policy;
+	/*
+	 * We need a good default value for the xfrm6 gc threshold.
+	 * In ipv4 we set it to the route hash table size * 8, which
+	 * is half the size of the maximaum route cache for ipv4.  It
+	 * would be good to do the same thing for v6, except the table is
+	 * constructed differently here.  Here each table for a net namespace
+	 * can have FIB_TABLE_HASHSZ entries, so lets go with the same
+	 * computation that we used for ipv4 here.  Also, lets keep the initial
+	 * gc_thresh to a minimum of 1024, since, the ipv6 route cache defaults
+	 * to that as a minimum as well
+	 */
+	gc_thresh = FIB6_TABLE_HASHSZ * 8;
+	xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh;
+#ifdef CONFIG_SYSCTL
+	sysctl_hdr = register_net_sysctl_table(&init_net, net_ipv6_ctl_path,
+						xfrm6_policy_table);
+#endif
 out:
 	return ret;
 out_policy:
@@ -326,6 +360,10 @@ out_policy:
 
 void xfrm6_fini(void)
 {
+#ifdef CONFIG_SYSCTL
+	if (sysctl_hdr)
+		unregister_net_sysctl_table(sysctl_hdr);
+#endif
 	//xfrm6_input_fini();
 	xfrm6_policy_fini();
 	xfrm6_state_fini();
diff --git a/net/irda/ircomm/ircomm_event.c b/net/irda/ircomm/ircomm_event.c
index c35b3ef..d78554f 100644
--- a/net/irda/ircomm/ircomm_event.c
+++ b/net/irda/ircomm/ircomm_event.c
@@ -49,7 +49,7 @@ static int ircomm_state_waitr(struct ircomm_cb *self, IRCOMM_EVENT event,
 static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event,
 			     struct sk_buff *skb, struct ircomm_info *info);
 
-char *ircomm_state[] = {
+const char *const ircomm_state[] = {
 	"IRCOMM_IDLE",
 	"IRCOMM_WAITI",
 	"IRCOMM_WAITR",
@@ -57,7 +57,7 @@ char *ircomm_state[] = {
 };
 
 #ifdef CONFIG_IRDA_DEBUG
-static char *ircomm_event[] = {
+static const char *const ircomm_event[] = {
 	"IRCOMM_CONNECT_REQUEST",
 	"IRCOMM_CONNECT_RESPONSE",
 	"IRCOMM_TTP_CONNECT_INDICATION",
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index 9032a1d..eafc010 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -80,7 +80,7 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
 				  struct sk_buff *skb,
 				  struct ircomm_tty_info *info);
 
-char *ircomm_tty_state[] = {
+const char *const ircomm_tty_state[] = {
 	"IRCOMM_TTY_IDLE",
 	"IRCOMM_TTY_SEARCH",
 	"IRCOMM_TTY_QUERY_PARAMETERS",
@@ -91,7 +91,7 @@ char *ircomm_tty_state[] = {
 };
 
 #ifdef CONFIG_IRDA_DEBUG
-static char *ircomm_tty_event[] = {
+static const char *const ircomm_tty_event[] = {
 	"IRCOMM_TTY_ATTACH_CABLE",
 	"IRCOMM_TTY_DETACH_CABLE",
 	"IRCOMM_TTY_DATA_REQUEST",
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 4a105dc..294e34d 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -44,7 +44,7 @@
 
 #ifdef CONFIG_IRDA_DEBUG
 /* FIXME: This one should go in irlmp.c */
-static const char *ias_charset_types[] = {
+static const char *const ias_charset_types[] = {
 	"CS_ASCII",
 	"CS_ISO_8859_1",
 	"CS_ISO_8859_2",
@@ -966,7 +966,7 @@ static void iriap_watchdog_timer_expired(void *data)
 
 #ifdef CONFIG_PROC_FS
 
-static const char *ias_value_types[] = {
+static const char *const ias_value_types[] = {
 	"IAS_MISSING",
 	"IAS_INTEGER",
 	"IAS_OCT_SEQ",
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index 774d73a..6211682 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -69,14 +69,14 @@ static int eth;   /* Use "eth" or "irlan" name for devices */
 static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
 
 #ifdef CONFIG_PROC_FS
-static const char *irlan_access[] = {
+static const char *const irlan_access[] = {
 	"UNKNOWN",
 	"DIRECT",
 	"PEER",
 	"HOSTED"
 };
 
-static const char *irlan_media[] = {
+static const char *const irlan_media[] = {
 	"UNKNOWN",
 	"802.3",
 	"802.5"
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
index 724bcf9..7b6b631 100644
--- a/net/irda/irlan/irlan_eth.c
+++ b/net/irda/irlan/irlan_eth.c
@@ -41,7 +41,8 @@
 
 static int  irlan_eth_open(struct net_device *dev);
 static int  irlan_eth_close(struct net_device *dev);
-static int  irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t  irlan_eth_xmit(struct sk_buff *skb,
+					 struct net_device *dev);
 static void irlan_eth_set_multicast_list( struct net_device *dev);
 static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev);
 
@@ -162,7 +163,8 @@ static int irlan_eth_close(struct net_device *dev)
  *    Transmits ethernet frames over IrDA link.
  *
  */
-static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb,
+					struct net_device *dev)
 {
 	struct irlan_cb *self = netdev_priv(dev);
 	int ret;
@@ -177,7 +179,7 @@ static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		/* Did the realloc succeed? */
 		if (new_skb == NULL)
-			return 0;
+			return NETDEV_TX_OK;
 
 		/* Use the new skb instead */
 		skb = new_skb;
@@ -209,7 +211,7 @@ static int irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 		self->stats.tx_bytes += skb->len;
 	}
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
diff --git a/net/irda/irlap.c b/net/irda/irlap.c
index e4965b7..356e65b 100644
--- a/net/irda/irlap.c
+++ b/net/irda/irlap.c
@@ -63,7 +63,7 @@ static void irlap_init_qos_capabilities(struct irlap_cb *self,
 					struct qos_info *qos_user);
 
 #ifdef CONFIG_IRDA_DEBUG
-static char *lap_reasons[] = {
+static const char *const lap_reasons[] = {
 	"ERROR, NOT USED",
 	"LAP_DISC_INDICATION",
 	"LAP_NO_RESPONSE",
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index 16c4ef0..c5c5195 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -78,7 +78,7 @@ static int irlap_state_reset_check(struct irlap_cb *, IRLAP_EVENT event,
 				   struct sk_buff *, struct irlap_info *);
 
 #ifdef CONFIG_IRDA_DEBUG
-static const char *irlap_event[] = {
+static const char *const irlap_event[] = {
 	"DISCOVERY_REQUEST",
 	"CONNECT_REQUEST",
 	"CONNECT_RESPONSE",
@@ -120,7 +120,7 @@ static const char *irlap_event[] = {
 };
 #endif	/* CONFIG_IRDA_DEBUG */
 
-const char *irlap_state[] = {
+const char *const irlap_state[] = {
 	"LAP_NDM",
 	"LAP_QUERY",
 	"LAP_REPLY",
diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c
index 78cce0c..c1fb5db 100644
--- a/net/irda/irlmp_event.c
+++ b/net/irda/irlmp_event.c
@@ -33,13 +33,13 @@
 #include <net/irda/irlmp_frame.h>
 #include <net/irda/irlmp_event.h>
 
-const char *irlmp_state[] = {
+const char *const irlmp_state[] = {
 	"LAP_STANDBY",
 	"LAP_U_CONNECT",
 	"LAP_ACTIVE",
 };
 
-const char *irlsap_state[] = {
+const char *const irlsap_state[] = {
 	"LSAP_DISCONNECTED",
 	"LSAP_CONNECT",
 	"LSAP_CONNECT_PEND",
@@ -49,7 +49,7 @@ const char *irlsap_state[] = {
 };
 
 #ifdef CONFIG_IRDA_DEBUG
-static const char *irlmp_event[] = {
+static const char *const irlmp_event[] = {
 	"LM_CONNECT_REQUEST",
 	"LM_CONNECT_CONFIRM",
 	"LM_CONNECT_RESPONSE",
diff --git a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h
index d9f8bd4..b5df241 100644
--- a/net/irda/irnet/irnet_ppp.h
+++ b/net/irda/irnet/irnet_ppp.h
@@ -95,7 +95,7 @@ static int
 /**************************** VARIABLES ****************************/
 
 /* Filesystem callbacks (to call us) */
-static struct file_operations irnet_device_fops =
+static const struct file_operations irnet_device_fops =
 {
 	.owner		= THIS_MODULE,
 	.read		= dev_irnet_read,
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index 8dd7ed7..476b307 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -115,7 +115,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
 
 	genlmsg_end(msg, hdr);
 
-	return genlmsg_unicast(msg, info->snd_pid);
+	return genlmsg_reply(msg, info);
 
  err_out:
 	nlmsg_free(msg);
diff --git a/net/irda/irproc.c b/net/irda/irproc.c
index 8ff1861..318766e 100644
--- a/net/irda/irproc.c
+++ b/net/irda/irproc.c
@@ -34,21 +34,21 @@
 #include <net/irda/irlap.h>
 #include <net/irda/irlmp.h>
 
-extern struct file_operations discovery_seq_fops;
-extern struct file_operations irlap_seq_fops;
-extern struct file_operations irlmp_seq_fops;
-extern struct file_operations irttp_seq_fops;
-extern struct file_operations irias_seq_fops;
+extern const struct file_operations discovery_seq_fops;
+extern const struct file_operations irlap_seq_fops;
+extern const struct file_operations irlmp_seq_fops;
+extern const struct file_operations irttp_seq_fops;
+extern const struct file_operations irias_seq_fops;
 
 struct irda_entry {
 	const char *name;
-	struct file_operations *fops;
+	const struct file_operations *fops;
 };
 
 struct proc_dir_entry *proc_irda;
 EXPORT_SYMBOL(proc_irda);
 
-static struct irda_entry irda_dirs[] = {
+static const struct irda_entry irda_dirs[] = {
 	{"discovery",	&discovery_seq_fops},
 	{"irttp",	&irttp_seq_fops},
 	{"irlmp",	&irlmp_seq_fops},
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 49c15b4..d985d16 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -34,7 +34,7 @@
 
 static char iucv_userid[80];
 
-static struct proto_ops iucv_sock_ops;
+static const struct proto_ops iucv_sock_ops;
 
 static struct proto iucv_proto = {
 	.name		= "AF_IUCV",
@@ -59,8 +59,8 @@ do {									\
 	DEFINE_WAIT(__wait);						\
 	long __timeo = timeo;						\
 	ret = 0;							\
+	prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE);	\
 	while (!(condition)) {						\
-		prepare_to_wait(sk->sk_sleep, &__wait, TASK_INTERRUPTIBLE); \
 		if (!__timeo) {						\
 			ret = -EAGAIN;					\
 			break;						\
@@ -361,10 +361,9 @@ static void iucv_sock_cleanup_listen(struct sock *parent)
 	}
 
 	parent->sk_state = IUCV_CLOSED;
-	sock_set_flag(parent, SOCK_ZAPPED);
 }
 
-/* Kill socket */
+/* Kill socket (only if zapped and orphaned) */
 static void iucv_sock_kill(struct sock *sk)
 {
 	if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
@@ -426,17 +425,18 @@ static void iucv_sock_close(struct sock *sk)
 
 		skb_queue_purge(&iucv->send_skb_q);
 		skb_queue_purge(&iucv->backlog_skb_q);
-
-		sock_set_flag(sk, SOCK_ZAPPED);
 		break;
 
 	default:
 		sock_set_flag(sk, SOCK_ZAPPED);
+		/* nothing to do here */
 		break;
 	}
 
+	/* mark socket for deletion by iucv_sock_kill() */
+	sock_set_flag(sk, SOCK_ZAPPED);
+
 	release_sock(sk);
-	iucv_sock_kill(sk);
 }
 
 static void iucv_sock_init(struct sock *sk, struct sock *parent)
@@ -569,6 +569,7 @@ struct sock *iucv_accept_dequeue(struct sock *parent, struct socket *newsock)
 
 		if (sk->sk_state == IUCV_CONNECTED ||
 		    sk->sk_state == IUCV_SEVERED ||
+		    sk->sk_state == IUCV_DISCONN ||	/* due to PM restore */
 		    !newsock) {
 			iucv_accept_unlink(sk);
 			if (newsock)
@@ -1035,6 +1036,10 @@ out:
 	return err;
 }
 
+/* iucv_fragment_skb() - Fragment a single IUCV message into multiple skb's
+ *
+ * Locking: must be called with message_q.lock held
+ */
 static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
 {
 	int dataleft, size, copied = 0;
@@ -1069,6 +1074,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
 	return 0;
 }
 
+/* iucv_process_message() - Receive a single outstanding IUCV message
+ *
+ * Locking: must be called with message_q.lock held
+ */
 static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
 				 struct iucv_path *path,
 				 struct iucv_message *msg)
@@ -1119,6 +1128,10 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
 		skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb);
 }
 
+/* iucv_process_message_q() - Process outstanding IUCV messages
+ *
+ * Locking: must be called with message_q.lock held
+ */
 static void iucv_process_message_q(struct sock *sk)
 {
 	struct iucv_sock *iucv = iucv_sk(sk);
@@ -1209,6 +1222,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 		kfree_skb(skb);
 
 		/* Queue backlog skbs */
+		spin_lock_bh(&iucv->message_q.lock);
 		rskb = skb_dequeue(&iucv->backlog_skb_q);
 		while (rskb) {
 			if (sock_queue_rcv_skb(sk, rskb)) {
@@ -1220,11 +1234,10 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 			}
 		}
 		if (skb_queue_empty(&iucv->backlog_skb_q)) {
-			spin_lock_bh(&iucv->message_q.lock);
 			if (!list_empty(&iucv->message_q.list))
 				iucv_process_message_q(sk);
-			spin_unlock_bh(&iucv->message_q.lock);
 		}
+		spin_unlock_bh(&iucv->message_q.lock);
 	}
 
 done:
@@ -1682,7 +1695,7 @@ static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
 	bh_unlock_sock(sk);
 }
 
-static struct proto_ops iucv_sock_ops = {
+static const struct proto_ops iucv_sock_ops = {
 	.family		= PF_IUCV,
 	.owner		= THIS_MODULE,
 	.release	= iucv_sock_release,
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index c833481..3973d0e 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -79,6 +79,14 @@ static int iucv_bus_match(struct device *dev, struct device_driver *drv)
 	return 0;
 }
 
+enum iucv_pm_states {
+	IUCV_PM_INITIAL = 0,
+	IUCV_PM_FREEZING = 1,
+	IUCV_PM_THAWING = 2,
+	IUCV_PM_RESTORING = 3,
+};
+static enum iucv_pm_states iucv_pm_state;
+
 static int iucv_pm_prepare(struct device *);
 static void iucv_pm_complete(struct device *);
 static int iucv_pm_freeze(struct device *);
@@ -354,7 +362,7 @@ static int iucv_query_maxconn(void)
 		"	srl	%0,28\n"
 		: "=d" (ccode), "+d" (reg0), "+d" (reg1) : : "cc");
 	if (ccode == 0)
-		iucv_max_pathid = reg0;
+		iucv_max_pathid = reg1;
 	kfree(param);
 	return ccode ? -EPERM : 0;
 }
@@ -856,7 +864,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
 	int rc;
 
 	local_bh_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -905,7 +913,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
 
 	spin_lock_bh(&iucv_table_lock);
 	iucv_cleanup_queue();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -965,7 +973,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16])
 	int rc;
 
 	local_bh_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -997,7 +1005,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16])
 	int rc;
 
 	local_bh_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1026,7 +1034,7 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
 	int rc;
 
 	preempt_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1060,7 +1068,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
 	int rc;
 
 	local_bh_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1152,7 +1160,7 @@ int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
 	if (msg->flags & IUCV_IPRMDATA)
 		return iucv_message_receive_iprmdata(path, msg, flags,
 						     buffer, size, residual);
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1225,7 +1233,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg)
 	int rc;
 
 	local_bh_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1264,7 +1272,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
 	int rc;
 
 	local_bh_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1314,7 +1322,7 @@ int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
 	union iucv_param *parm;
 	int rc;
 
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1401,7 +1409,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
 	int rc;
 
 	local_bh_disable();
-	if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) {
+	if (cpus_empty(iucv_buffer_cpumask)) {
 		rc = -EIO;
 		goto out;
 	}
@@ -1875,6 +1883,7 @@ static int iucv_pm_freeze(struct device *dev)
 #ifdef CONFIG_PM_DEBUG
 	printk(KERN_WARNING "iucv_pm_freeze\n");
 #endif
+	iucv_pm_state = IUCV_PM_FREEZING;
 	for_each_cpu_mask_nr(cpu, iucv_irq_cpumask)
 		smp_call_function_single(cpu, iucv_block_cpu_almost, NULL, 1);
 	if (dev->driver && dev->driver->pm && dev->driver->pm->freeze)
@@ -1899,6 +1908,7 @@ static int iucv_pm_thaw(struct device *dev)
 #ifdef CONFIG_PM_DEBUG
 	printk(KERN_WARNING "iucv_pm_thaw\n");
 #endif
+	iucv_pm_state = IUCV_PM_THAWING;
 	if (!iucv_path_table) {
 		rc = iucv_enable();
 		if (rc)
@@ -1933,6 +1943,10 @@ static int iucv_pm_restore(struct device *dev)
 #ifdef CONFIG_PM_DEBUG
 	printk(KERN_WARNING "iucv_pm_restore %p\n", iucv_path_table);
 #endif
+	if ((iucv_pm_state != IUCV_PM_RESTORING) && iucv_path_table)
+		pr_warning("Suspending Linux did not completely close all IUCV "
+			"connections\n");
+	iucv_pm_state = IUCV_PM_RESTORING;
 	if (cpus_empty(iucv_irq_cpumask)) {
 		rc = iucv_query_maxconn();
 		rc = iucv_enable();
diff --git a/net/key/af_key.c b/net/key/af_key.c
index dba9abd..4e98193 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3705,7 +3705,7 @@ static void pfkey_seq_stop(struct seq_file *f, void *v)
 	read_unlock(&pfkey_table_lock);
 }
 
-static struct seq_operations pfkey_seq_ops = {
+static const struct seq_operations pfkey_seq_ops = {
 	.start	= pfkey_seq_start,
 	.next	= pfkey_seq_next,
 	.stop	= pfkey_seq_stop,
@@ -3718,7 +3718,7 @@ static int pfkey_seq_open(struct inode *inode, struct file *file)
 			    sizeof(struct seq_net_private));
 }
 
-static struct file_operations pfkey_proc_ops = {
+static const struct file_operations pfkey_proc_ops = {
 	.open	 = pfkey_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index 2ba1bc4..bda96d1 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -407,7 +407,7 @@ int lapb_data_indication(struct lapb_cb *lapb, struct sk_buff *skb)
 		return lapb->callbacks.data_indication(lapb->dev, skb);
 
 	kfree_skb(skb);
-	return NET_RX_CN_HIGH; /* For now; must be != NET_RX_DROP */
+	return NET_RX_SUCCESS; /* For now; must be != NET_RX_DROP */
 }
 
 int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *skb)
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
index f97be47..be47ac4 100644
--- a/net/llc/llc_proc.c
+++ b/net/llc/llc_proc.c
@@ -143,7 +143,7 @@ out:
 	return 0;
 }
 
-static char *llc_conn_state_names[] = {
+static const char *const llc_conn_state_names[] = {
 	[LLC_CONN_STATE_ADM] =        "adm",
 	[LLC_CONN_STATE_SETUP] =      "setup",
 	[LLC_CONN_STATE_NORMAL] =     "normal",
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 7836ee9..4d5543a 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -6,7 +6,6 @@ config MAC80211
 	select CRYPTO_ARC4
 	select CRYPTO_AES
 	select CRC32
-	select WIRELESS_EXT
 	---help---
 	  This option enables the hardware independent IEEE 802.11
 	  networking stack.
@@ -14,24 +13,7 @@ config MAC80211
 comment "CFG80211 needs to be enabled for MAC80211"
 	depends on CFG80211=n
 
-config MAC80211_DEFAULT_PS
-	bool "enable powersave by default"
-	depends on MAC80211
-	default y
-	help
-	  This option enables powersave mode by default.
-
-	  If this causes your applications to misbehave you should fix your
-	  applications instead -- they need to register their network
-	  latency requirement, see Documentation/power/pm_qos_interface.txt.
-
-config MAC80211_DEFAULT_PS_VALUE
-	int
-	default 1 if MAC80211_DEFAULT_PS
-	default 0
-
-menu "Rate control algorithm selection"
-	depends on MAC80211 != n
+if MAC80211 != n
 
 config MAC80211_RC_PID
 	bool "PID controller based rate control algorithm" if EMBEDDED
@@ -78,17 +60,17 @@ config MAC80211_RC_DEFAULT
 	default "pid" if MAC80211_RC_DEFAULT_PID
 	default ""
 
-endmenu
+endif
 
 config MAC80211_MESH
 	bool "Enable mac80211 mesh networking (pre-802.11s) support"
 	depends on MAC80211 && EXPERIMENTAL
-	depends on BROKEN
 	---help---
 	 This options enables support of Draft 802.11s mesh networking.
-	 The implementation is based on Draft 1.08 of the Mesh Networking
-	 amendment. For more information visit http://o11s.org/.
-
+	 The implementation is based on Draft 2.08 of the Mesh Networking
+	 amendment.  However, no compliance with that draft is claimed or even
+	 possible, as drafts leave a number of identifiers to be defined after
+	 ratification.  For more information visit http://o11s.org/.
 
 config MAC80211_LEDS
 	bool "Enable LED triggers"
@@ -222,3 +204,15 @@ config MAC80211_DEBUG_COUNTERS
 	  and show them in debugfs.
 
 	  If unsure, say N.
+
+config MAC80211_DRIVER_API_TRACER
+	bool "Driver API tracer"
+	depends on MAC80211_DEBUG_MENU
+	depends on EVENT_TRACING
+	help
+	  Say Y here to make mac80211 register with the ftrace
+	  framework for the driver API -- you can see which
+	  driver methods it is calling then by looking at the
+	  trace.
+
+	  If unsure, say N.
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 0e3ab88..9f3cf71 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -3,7 +3,6 @@ obj-$(CONFIG_MAC80211) += mac80211.o
 # mac80211 objects
 mac80211-y := \
 	main.o \
-	wext.o \
 	sta_info.o \
 	wep.o \
 	wpa.o \
@@ -41,6 +40,9 @@ mac80211-$(CONFIG_MAC80211_MESH) += \
 
 mac80211-$(CONFIG_PM) += pm.o
 
+mac80211-$(CONFIG_MAC80211_DRIVER_API_TRACER) += driver-trace.o
+CFLAGS_driver-trace.o := -I$(src)
+
 # objects for PID algorithm
 rc80211_pid-y := rc80211_pid_algo.o
 rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index a24e598..bd765f3 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -391,9 +391,6 @@ static void ieee80211_agg_splice_packets(struct ieee80211_local *local,
 
 	if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) {
 		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-		/* mark queue as pending, it is stopped already */
-		__set_bit(IEEE80211_QUEUE_STOP_REASON_PENDING,
-			  &local->queue_stop_reasons[queue]);
 		/* copy over remaining packets */
 		skb_queue_splice_tail_init(
 			&sta->ampdu_mlme.tid_tx[tid]->pending,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 3f47276..5608f6c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -57,36 +57,21 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
 	return 0;
 }
 
-static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
+static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev)
 {
-	struct net_device *dev;
-	struct ieee80211_sub_if_data *sdata;
-
-	/* we're under RTNL */
-	dev = __dev_get_by_index(&init_net, ifindex);
-	if (!dev)
-		return -ENODEV;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	ieee80211_if_remove(sdata);
+	ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev));
 
 	return 0;
 }
 
-static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
+static int ieee80211_change_iface(struct wiphy *wiphy,
+				  struct net_device *dev,
 				  enum nl80211_iftype type, u32 *flags,
 				  struct vif_params *params)
 {
-	struct net_device *dev;
 	struct ieee80211_sub_if_data *sdata;
 	int ret;
 
-	/* we're under RTNL */
-	dev = __dev_get_by_index(&init_net, ifindex);
-	if (!dev)
-		return -ENODEV;
-
 	if (!nl80211_type_check(type))
 		return -EINVAL;
 
@@ -338,6 +323,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
 {
 	struct ieee80211_sub_if_data *sdata = sta->sdata;
 
+	sinfo->generation = sdata->local->sta_generation;
+
 	sinfo->filled = STATION_INFO_INACTIVE_TIME |
 			STATION_INFO_RX_BYTES |
 			STATION_INFO_TX_BYTES |
@@ -924,6 +911,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
 	else
 		memset(next_hop, 0, ETH_ALEN);
 
+	pinfo->generation = mesh_paths_generation;
+
 	pinfo->filled = MPATH_INFO_FRAME_QLEN |
 			MPATH_INFO_DSN |
 			MPATH_INFO_METRIC |
@@ -1177,123 +1166,29 @@ static int ieee80211_scan(struct wiphy *wiphy,
 static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
 			  struct cfg80211_auth_request *req)
 {
-	struct ieee80211_sub_if_data *sdata;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	switch (req->auth_type) {
-	case NL80211_AUTHTYPE_OPEN_SYSTEM:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_OPEN;
-		break;
-	case NL80211_AUTHTYPE_SHARED_KEY:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_SHARED_KEY;
-		break;
-	case NL80211_AUTHTYPE_FT:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_FT;
-		break;
-	case NL80211_AUTHTYPE_NETWORK_EAP:
-		sdata->u.mgd.auth_algs = IEEE80211_AUTH_ALG_LEAP;
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	memcpy(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN);
-	sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-	sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
-
-	/* TODO: req->chan */
-	sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
-
-	if (req->ssid) {
-		sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
-		memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
-		sdata->u.mgd.ssid_len = req->ssid_len;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
-	}
-
-	kfree(sdata->u.mgd.sme_auth_ie);
-	sdata->u.mgd.sme_auth_ie = NULL;
-	sdata->u.mgd.sme_auth_ie_len = 0;
-	if (req->ie) {
-		sdata->u.mgd.sme_auth_ie = kmalloc(req->ie_len, GFP_KERNEL);
-		if (sdata->u.mgd.sme_auth_ie == NULL)
-			return -ENOMEM;
-		memcpy(sdata->u.mgd.sme_auth_ie, req->ie, req->ie_len);
-		sdata->u.mgd.sme_auth_ie_len = req->ie_len;
-	}
-
-	sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
-	sdata->u.mgd.state = IEEE80211_STA_MLME_DIRECT_PROBE;
-	ieee80211_sta_req_auth(sdata);
-	return 0;
+	return ieee80211_mgd_auth(IEEE80211_DEV_TO_SUB_IF(dev), req);
 }
 
 static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
 			   struct cfg80211_assoc_request *req)
 {
-	struct ieee80211_sub_if_data *sdata;
-	int ret;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (memcmp(sdata->u.mgd.bssid, req->peer_addr, ETH_ALEN) != 0 ||
-	    !(sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED))
-		return -ENOLINK; /* not authenticated */
-
-	sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-	sdata->u.mgd.flags |= IEEE80211_STA_BSSID_SET;
-
-	/* TODO: req->chan */
-	sdata->u.mgd.flags |= IEEE80211_STA_AUTO_CHANNEL_SEL;
-
-	if (req->ssid) {
-		sdata->u.mgd.flags |= IEEE80211_STA_SSID_SET;
-		memcpy(sdata->u.mgd.ssid, req->ssid, req->ssid_len);
-		sdata->u.mgd.ssid_len = req->ssid_len;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
-	} else
-		sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
-
-	ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
-	if (ret && ret != -EALREADY)
-		return ret;
-
-	if (req->use_mfp) {
-		sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
-		sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
-	} else {
-		sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
-	}
-
-	if (req->control_port)
-		sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT;
-	else
-		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
-
-	sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
-	sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
-	ieee80211_sta_req_auth(sdata);
-	return 0;
+	return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
 }
 
 static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
-			    struct cfg80211_deauth_request *req)
+			    struct cfg80211_deauth_request *req,
+			    void *cookie)
 {
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	/* TODO: req->ie, req->peer_addr */
-	return ieee80211_sta_deauthenticate(sdata, req->reason_code);
+	return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev),
+				    req, cookie);
 }
 
 static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
-			      struct cfg80211_disassoc_request *req)
+			      struct cfg80211_disassoc_request *req,
+			      void *cookie)
 {
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	/* TODO: req->ie, req->peer_addr */
-	return ieee80211_sta_disassociate(sdata, req->reason_code);
+	return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev),
+				      req, cookie);
 }
 
 static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
@@ -1374,6 +1269,16 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
 	return 0;
 }
 
+static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
+				  u8 *addr)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+	memcpy(&sdata->u.wds.remote_addr, addr, ETH_ALEN);
+
+	return 0;
+}
+
 static void ieee80211_rfkill_poll(struct wiphy *wiphy)
 {
 	struct ieee80211_local *local = wiphy_priv(wiphy);
@@ -1381,6 +1286,85 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy)
 	drv_rfkill_poll(local);
 }
 
+#ifdef CONFIG_NL80211_TESTMODE
+static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
+{
+	struct ieee80211_local *local = wiphy_priv(wiphy);
+
+	if (!local->ops->testmode_cmd)
+		return -EOPNOTSUPP;
+
+	return local->ops->testmode_cmd(&local->hw, data, len);
+}
+#endif
+
+static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
+				    bool enabled, int timeout)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct ieee80211_conf *conf = &local->hw.conf;
+
+	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
+		return -EOPNOTSUPP;
+
+	if (enabled == sdata->u.mgd.powersave &&
+	    timeout == conf->dynamic_ps_timeout)
+		return 0;
+
+	sdata->u.mgd.powersave = enabled;
+	conf->dynamic_ps_timeout = timeout;
+
+	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
+		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+
+	ieee80211_recalc_ps(local, -1);
+
+	return 0;
+}
+
+static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
+				      struct net_device *dev,
+				      const u8 *addr,
+				      const struct cfg80211_bitrate_mask *mask)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	int i, err = -EINVAL;
+	u32 target_rate;
+	struct ieee80211_supported_band *sband;
+
+	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+	/* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
+	 * target_rate = X, rate->fixed = 1 means only rate X
+	 * target_rate = X, rate->fixed = 0 means all rates <= X */
+	sdata->max_ratectrl_rateidx = -1;
+	sdata->force_unicast_rateidx = -1;
+
+	if (mask->fixed)
+		target_rate = mask->fixed / 100;
+	else if (mask->maxrate)
+		target_rate = mask->maxrate / 100;
+	else
+		return 0;
+
+	for (i=0; i< sband->n_bitrates; i++) {
+		struct ieee80211_rate *brate = &sband->bitrates[i];
+		int this_rate = brate->bitrate;
+
+		if (target_rate == this_rate) {
+			sdata->max_ratectrl_rateidx = i;
+			if (mask->fixed)
+				sdata->force_unicast_rateidx = i;
+			err = 0;
+			break;
+		}
+	}
+
+	return err;
+}
+
 struct cfg80211_ops mac80211_config_ops = {
 	.add_virtual_intf = ieee80211_add_iface,
 	.del_virtual_intf = ieee80211_del_iface,
@@ -1422,5 +1406,9 @@ struct cfg80211_ops mac80211_config_ops = {
 	.set_wiphy_params = ieee80211_set_wiphy_params,
 	.set_tx_power = ieee80211_set_tx_power,
 	.get_tx_power = ieee80211_get_tx_power,
+	.set_wds_peer = ieee80211_set_wds_peer,
 	.rfkill_poll = ieee80211_rfkill_poll,
+	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
+	.set_power_mgmt = ieee80211_set_power_mgmt,
+	.set_bitrate_mask = ieee80211_set_bitrate_mask,
 };
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 6c439cd..96991b6 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -175,7 +175,7 @@ static ssize_t queues_read(struct file *file, char __user *user_buf,
 	for (q = 0; q < local->hw.queues; q++)
 		res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
 				local->queue_stop_reasons[q],
-				__netif_subqueue_stopped(local->mdev, q));
+				skb_queue_len(&local->pending[q]));
 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
 	return simple_read_from_buffer(user_buf, count, ppos, buf, res);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index e342032..61234e7 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -95,33 +95,9 @@ IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC);
 IEEE80211_IF_FILE(max_ratectrl_rateidx, max_ratectrl_rateidx, DEC);
 
 /* STA attributes */
-IEEE80211_IF_FILE(state, u.mgd.state, DEC);
 IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
-IEEE80211_IF_FILE(prev_bssid, u.mgd.prev_bssid, MAC);
-IEEE80211_IF_FILE(ssid_len, u.mgd.ssid_len, SIZE);
 IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
-IEEE80211_IF_FILE(ap_capab, u.mgd.ap_capab, HEX);
 IEEE80211_IF_FILE(capab, u.mgd.capab, HEX);
-IEEE80211_IF_FILE(extra_ie_len, u.mgd.extra_ie_len, SIZE);
-IEEE80211_IF_FILE(auth_tries, u.mgd.auth_tries, DEC);
-IEEE80211_IF_FILE(assoc_tries, u.mgd.assoc_tries, DEC);
-IEEE80211_IF_FILE(auth_algs, u.mgd.auth_algs, HEX);
-IEEE80211_IF_FILE(auth_alg, u.mgd.auth_alg, DEC);
-IEEE80211_IF_FILE(auth_transaction, u.mgd.auth_transaction, DEC);
-
-static ssize_t ieee80211_if_fmt_flags(
-	const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
-	return scnprintf(buf, buflen, "%s%s%s%s%s%s%s\n",
-		 sdata->u.mgd.flags & IEEE80211_STA_SSID_SET ? "SSID\n" : "",
-		 sdata->u.mgd.flags & IEEE80211_STA_BSSID_SET ? "BSSID\n" : "",
-		 sdata->u.mgd.flags & IEEE80211_STA_PREV_BSSID_SET ? "prev BSSID\n" : "",
-		 sdata->u.mgd.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "",
-		 sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "",
-		 sdata->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "",
-		 sdata->vif.bss_conf.use_cts_prot ? "CTS prot\n" : "");
-}
-__IEEE80211_IF_FILE(flags);
 
 /* AP attributes */
 IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
@@ -140,6 +116,8 @@ IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
 
 #ifdef CONFIG_MAC80211_MESH
 /* Mesh stats attributes */
+IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
+IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
 IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
 IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
 IEEE80211_IF_FILE(dropped_frames_no_route,
@@ -184,20 +162,9 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_ADD(force_unicast_rateidx, sta);
 	DEBUGFS_ADD(max_ratectrl_rateidx, sta);
 
-	DEBUGFS_ADD(state, sta);
 	DEBUGFS_ADD(bssid, sta);
-	DEBUGFS_ADD(prev_bssid, sta);
-	DEBUGFS_ADD(ssid_len, sta);
 	DEBUGFS_ADD(aid, sta);
-	DEBUGFS_ADD(ap_capab, sta);
 	DEBUGFS_ADD(capab, sta);
-	DEBUGFS_ADD(extra_ie_len, sta);
-	DEBUGFS_ADD(auth_tries, sta);
-	DEBUGFS_ADD(assoc_tries, sta);
-	DEBUGFS_ADD(auth_algs, sta);
-	DEBUGFS_ADD(auth_alg, sta);
-	DEBUGFS_ADD(auth_transaction, sta);
-	DEBUGFS_ADD(flags, sta);
 }
 
 static void add_ap_files(struct ieee80211_sub_if_data *sdata)
@@ -240,6 +207,8 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
 {
 	sdata->mesh_stats_dir = debugfs_create_dir("mesh_stats",
 				sdata->debugfsdir);
+	MESHSTATS_ADD(fwded_mcast);
+	MESHSTATS_ADD(fwded_unicast);
 	MESHSTATS_ADD(fwded_frames);
 	MESHSTATS_ADD(dropped_frames_ttl);
 	MESHSTATS_ADD(dropped_frames_no_route);
@@ -317,20 +286,9 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata)
 	DEBUGFS_DEL(force_unicast_rateidx, sta);
 	DEBUGFS_DEL(max_ratectrl_rateidx, sta);
 
-	DEBUGFS_DEL(state, sta);
 	DEBUGFS_DEL(bssid, sta);
-	DEBUGFS_DEL(prev_bssid, sta);
-	DEBUGFS_DEL(ssid_len, sta);
 	DEBUGFS_DEL(aid, sta);
-	DEBUGFS_DEL(ap_capab, sta);
 	DEBUGFS_DEL(capab, sta);
-	DEBUGFS_DEL(extra_ie_len, sta);
-	DEBUGFS_DEL(auth_tries, sta);
-	DEBUGFS_DEL(assoc_tries, sta);
-	DEBUGFS_DEL(auth_algs, sta);
-	DEBUGFS_DEL(auth_alg, sta);
-	DEBUGFS_DEL(auth_transaction, sta);
-	DEBUGFS_DEL(flags, sta);
 }
 
 static void del_ap_files(struct ieee80211_sub_if_data *sdata)
@@ -373,6 +331,8 @@ static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
 
 static void del_mesh_stats(struct ieee80211_sub_if_data *sdata)
 {
+	MESHSTATS_DEL(fwded_mcast);
+	MESHSTATS_DEL(fwded_unicast);
 	MESHSTATS_DEL(fwded_frames);
 	MESHSTATS_DEL(dropped_frames_ttl);
 	MESHSTATS_DEL(dropped_frames_no_route);
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 90230c7..33a2e89 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -120,45 +120,38 @@ STA_OPS(last_seq_ctrl);
 static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
 					size_t count, loff_t *ppos)
 {
-	char buf[768], *p = buf;
+	char buf[30 + STA_TID_NUM * 70], *p = buf;
 	int i;
 	struct sta_info *sta = file->private_data;
-	p += scnprintf(p, sizeof(buf)+buf-p, "Agg state for STA is:\n");
-	p += scnprintf(p, sizeof(buf)+buf-p, " STA next dialog_token is %d \n "
-			"TIDs info is: \n TID :",
-			(sta->ampdu_mlme.dialog_token_allocator + 1));
-	for (i = 0; i < STA_TID_NUM; i++)
-		p += scnprintf(p, sizeof(buf)+buf-p, "%5d", i);
-
-	p += scnprintf(p, sizeof(buf)+buf-p, "\n RX  :");
-	for (i = 0; i < STA_TID_NUM; i++)
-		p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-			sta->ampdu_mlme.tid_state_rx[i]);
-
-	p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
-	for (i = 0; i < STA_TID_NUM; i++)
-		p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-			sta->ampdu_mlme.tid_state_rx[i] ?
-			sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
-
-	p += scnprintf(p, sizeof(buf)+buf-p, "\n TX  :");
-	for (i = 0; i < STA_TID_NUM; i++)
-		p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-			sta->ampdu_mlme.tid_state_tx[i]);
-
-	p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
-	for (i = 0; i < STA_TID_NUM; i++)
-		p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-			sta->ampdu_mlme.tid_state_tx[i] ?
-			sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
-
-	p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :");
-	for (i = 0; i < STA_TID_NUM; i++)
-		p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-			sta->ampdu_mlme.tid_state_tx[i] ?
-			sta->ampdu_mlme.tid_tx[i]->ssn : 0);
 
-	p += scnprintf(p, sizeof(buf)+buf-p, "\n");
+	spin_lock_bh(&sta->lock);
+	p += scnprintf(p, sizeof(buf)+buf-p, "next dialog_token is %#02x\n",
+			sta->ampdu_mlme.dialog_token_allocator + 1);
+	for (i = 0; i < STA_TID_NUM; i++) {
+		p += scnprintf(p, sizeof(buf)+buf-p, "TID %02d:", i);
+		p += scnprintf(p, sizeof(buf)+buf-p, " RX=%x",
+				sta->ampdu_mlme.tid_state_rx[i]);
+		p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x",
+				sta->ampdu_mlme.tid_state_rx[i] ?
+				sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
+		p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x",
+				sta->ampdu_mlme.tid_state_rx[i] ?
+				sta->ampdu_mlme.tid_rx[i]->ssn : 0);
+
+		p += scnprintf(p, sizeof(buf)+buf-p, " TX=%x",
+				sta->ampdu_mlme.tid_state_tx[i]);
+		p += scnprintf(p, sizeof(buf)+buf-p, "/DTKN=%#.2x",
+				sta->ampdu_mlme.tid_state_tx[i] ?
+				sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
+		p += scnprintf(p, sizeof(buf)+buf-p, "/SSN=%#.3x",
+				sta->ampdu_mlme.tid_state_tx[i] ?
+				sta->ampdu_mlme.tid_tx[i]->ssn : 0);
+		p += scnprintf(p, sizeof(buf)+buf-p, "/pending=%03d",
+				sta->ampdu_mlme.tid_state_tx[i] ?
+				skb_queue_len(&sta->ampdu_mlme.tid_tx[i]->pending) : 0);
+		p += scnprintf(p, sizeof(buf)+buf-p, "\n");
+	}
+	spin_unlock_bh(&sta->lock);
 
 	return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
 }
@@ -203,6 +196,22 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
 	DEBUGFS_ADD(inactive_ms);
 	DEBUGFS_ADD(last_seq_ctrl);
 	DEBUGFS_ADD(agg_status);
+	DEBUGFS_ADD(dev);
+	DEBUGFS_ADD(rx_packets);
+	DEBUGFS_ADD(tx_packets);
+	DEBUGFS_ADD(rx_bytes);
+	DEBUGFS_ADD(tx_bytes);
+	DEBUGFS_ADD(rx_duplicates);
+	DEBUGFS_ADD(rx_fragments);
+	DEBUGFS_ADD(rx_dropped);
+	DEBUGFS_ADD(tx_fragments);
+	DEBUGFS_ADD(tx_filtered);
+	DEBUGFS_ADD(tx_retry_failed);
+	DEBUGFS_ADD(tx_retry_count);
+	DEBUGFS_ADD(last_signal);
+	DEBUGFS_ADD(last_qual);
+	DEBUGFS_ADD(last_noise);
+	DEBUGFS_ADD(wep_weak_iv_count);
 }
 
 void ieee80211_sta_debugfs_remove(struct sta_info *sta)
@@ -212,6 +221,23 @@ void ieee80211_sta_debugfs_remove(struct sta_info *sta)
 	DEBUGFS_DEL(inactive_ms);
 	DEBUGFS_DEL(last_seq_ctrl);
 	DEBUGFS_DEL(agg_status);
+	DEBUGFS_DEL(aid);
+	DEBUGFS_DEL(dev);
+	DEBUGFS_DEL(rx_packets);
+	DEBUGFS_DEL(tx_packets);
+	DEBUGFS_DEL(rx_bytes);
+	DEBUGFS_DEL(tx_bytes);
+	DEBUGFS_DEL(rx_duplicates);
+	DEBUGFS_DEL(rx_fragments);
+	DEBUGFS_DEL(rx_dropped);
+	DEBUGFS_DEL(tx_fragments);
+	DEBUGFS_DEL(tx_filtered);
+	DEBUGFS_DEL(tx_retry_failed);
+	DEBUGFS_DEL(tx_retry_count);
+	DEBUGFS_DEL(last_signal);
+	DEBUGFS_DEL(last_qual);
+	DEBUGFS_DEL(last_noise);
+	DEBUGFS_DEL(wep_weak_iv_count);
 
 	debugfs_remove(sta->debugfs.dir);
 	sta->debugfs.dir = NULL;
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index b13446a..020a94a 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -3,6 +3,7 @@
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
+#include "driver-trace.h"
 
 static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
 {
@@ -11,29 +12,49 @@ static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
 
 static inline int drv_start(struct ieee80211_local *local)
 {
-	return local->ops->start(&local->hw);
+	int ret;
+
+	local->started = true;
+	smp_mb();
+	ret = local->ops->start(&local->hw);
+	trace_drv_start(local, ret);
+	return ret;
 }
 
 static inline void drv_stop(struct ieee80211_local *local)
 {
 	local->ops->stop(&local->hw);
+	trace_drv_stop(local);
+
+	/* sync away all work on the tasklet before clearing started */
+	tasklet_disable(&local->tasklet);
+	tasklet_enable(&local->tasklet);
+
+	barrier();
+
+	local->started = false;
 }
 
 static inline int drv_add_interface(struct ieee80211_local *local,
 				    struct ieee80211_if_init_conf *conf)
 {
-	return local->ops->add_interface(&local->hw, conf);
+	int ret = local->ops->add_interface(&local->hw, conf);
+	trace_drv_add_interface(local, conf->mac_addr, conf->vif, ret);
+	return ret;
 }
 
 static inline void drv_remove_interface(struct ieee80211_local *local,
 					struct ieee80211_if_init_conf *conf)
 {
 	local->ops->remove_interface(&local->hw, conf);
+	trace_drv_remove_interface(local, conf->mac_addr, conf->vif);
 }
 
 static inline int drv_config(struct ieee80211_local *local, u32 changed)
 {
-	return local->ops->config(&local->hw, changed);
+	int ret = local->ops->config(&local->hw, changed);
+	trace_drv_config(local, changed, ret);
+	return ret;
 }
 
 static inline void drv_bss_info_changed(struct ieee80211_local *local,
@@ -43,24 +64,45 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
 {
 	if (local->ops->bss_info_changed)
 		local->ops->bss_info_changed(&local->hw, vif, info, changed);
+	trace_drv_bss_info_changed(local, vif, info, changed);
+}
+
+static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
+					int mc_count,
+					struct dev_addr_list *mc_list)
+{
+	u64 ret = 0;
+
+	if (local->ops->prepare_multicast)
+		ret = local->ops->prepare_multicast(&local->hw, mc_count,
+						    mc_list);
+
+	trace_drv_prepare_multicast(local, mc_count, ret);
+
+	return ret;
 }
 
 static inline void drv_configure_filter(struct ieee80211_local *local,
 					unsigned int changed_flags,
 					unsigned int *total_flags,
-					int mc_count,
-					struct dev_addr_list *mc_list)
+					u64 multicast)
 {
+	might_sleep();
+
 	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
-				     mc_count, mc_list);
+				     multicast);
+	trace_drv_configure_filter(local, changed_flags, total_flags,
+				   multicast);
 }
 
 static inline int drv_set_tim(struct ieee80211_local *local,
 			      struct ieee80211_sta *sta, bool set)
 {
+	int ret = 0;
 	if (local->ops->set_tim)
-		return local->ops->set_tim(&local->hw, sta, set);
-	return 0;
+		ret = local->ops->set_tim(&local->hw, sta, set);
+	trace_drv_set_tim(local, sta, set, ret);
+	return ret;
 }
 
 static inline int drv_set_key(struct ieee80211_local *local,
@@ -68,7 +110,9 @@ static inline int drv_set_key(struct ieee80211_local *local,
 			      struct ieee80211_sta *sta,
 			      struct ieee80211_key_conf *key)
 {
-	return local->ops->set_key(&local->hw, cmd, vif, sta, key);
+	int ret = local->ops->set_key(&local->hw, cmd, vif, sta, key);
+	trace_drv_set_key(local, cmd, vif, sta, key, ret);
+	return ret;
 }
 
 static inline void drv_update_tkip_key(struct ieee80211_local *local,
@@ -79,32 +123,41 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
 	if (local->ops->update_tkip_key)
 		local->ops->update_tkip_key(&local->hw, conf, address,
 					    iv32, phase1key);
+	trace_drv_update_tkip_key(local, conf, address, iv32);
 }
 
 static inline int drv_hw_scan(struct ieee80211_local *local,
 			      struct cfg80211_scan_request *req)
 {
-	return local->ops->hw_scan(&local->hw, req);
+	int ret = local->ops->hw_scan(&local->hw, req);
+	trace_drv_hw_scan(local, req, ret);
+	return ret;
 }
 
 static inline void drv_sw_scan_start(struct ieee80211_local *local)
 {
 	if (local->ops->sw_scan_start)
 		local->ops->sw_scan_start(&local->hw);
+	trace_drv_sw_scan_start(local);
 }
 
 static inline void drv_sw_scan_complete(struct ieee80211_local *local)
 {
 	if (local->ops->sw_scan_complete)
 		local->ops->sw_scan_complete(&local->hw);
+	trace_drv_sw_scan_complete(local);
 }
 
 static inline int drv_get_stats(struct ieee80211_local *local,
 				struct ieee80211_low_level_stats *stats)
 {
-	if (!local->ops->get_stats)
-		return -EOPNOTSUPP;
-	return local->ops->get_stats(&local->hw, stats);
+	int ret = -EOPNOTSUPP;
+
+	if (local->ops->get_stats)
+		ret = local->ops->get_stats(&local->hw, stats);
+	trace_drv_get_stats(local, stats, ret);
+
+	return ret;
 }
 
 static inline void drv_get_tkip_seq(struct ieee80211_local *local,
@@ -112,14 +165,17 @@ static inline void drv_get_tkip_seq(struct ieee80211_local *local,
 {
 	if (local->ops->get_tkip_seq)
 		local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
+	trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
 }
 
 static inline int drv_set_rts_threshold(struct ieee80211_local *local,
 					u32 value)
 {
+	int ret = 0;
 	if (local->ops->set_rts_threshold)
-		return local->ops->set_rts_threshold(&local->hw, value);
-	return 0;
+		ret = local->ops->set_rts_threshold(&local->hw, value);
+	trace_drv_set_rts_threshold(local, value, ret);
+	return ret;
 }
 
 static inline void drv_sta_notify(struct ieee80211_local *local,
@@ -129,46 +185,57 @@ static inline void drv_sta_notify(struct ieee80211_local *local,
 {
 	if (local->ops->sta_notify)
 		local->ops->sta_notify(&local->hw, vif, cmd, sta);
+	trace_drv_sta_notify(local, vif, cmd, sta);
 }
 
 static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
 			      const struct ieee80211_tx_queue_params *params)
 {
+	int ret = -EOPNOTSUPP;
 	if (local->ops->conf_tx)
-		return local->ops->conf_tx(&local->hw, queue, params);
-	return -EOPNOTSUPP;
+		ret = local->ops->conf_tx(&local->hw, queue, params);
+	trace_drv_conf_tx(local, queue, params, ret);
+	return ret;
 }
 
 static inline int drv_get_tx_stats(struct ieee80211_local *local,
 				   struct ieee80211_tx_queue_stats *stats)
 {
-	return local->ops->get_tx_stats(&local->hw, stats);
+	int ret = local->ops->get_tx_stats(&local->hw, stats);
+	trace_drv_get_tx_stats(local, stats, ret);
+	return ret;
 }
 
 static inline u64 drv_get_tsf(struct ieee80211_local *local)
 {
+	u64 ret = -1ULL;
 	if (local->ops->get_tsf)
-		return local->ops->get_tsf(&local->hw);
-	return -1ULL;
+		ret = local->ops->get_tsf(&local->hw);
+	trace_drv_get_tsf(local, ret);
+	return ret;
 }
 
 static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
 {
 	if (local->ops->set_tsf)
 		local->ops->set_tsf(&local->hw, tsf);
+	trace_drv_set_tsf(local, tsf);
 }
 
 static inline void drv_reset_tsf(struct ieee80211_local *local)
 {
 	if (local->ops->reset_tsf)
 		local->ops->reset_tsf(&local->hw);
+	trace_drv_reset_tsf(local);
 }
 
 static inline int drv_tx_last_beacon(struct ieee80211_local *local)
 {
+	int ret = 1;
 	if (local->ops->tx_last_beacon)
-		return local->ops->tx_last_beacon(&local->hw);
-	return 1;
+		ret = local->ops->tx_last_beacon(&local->hw);
+	trace_drv_tx_last_beacon(local, ret);
+	return ret;
 }
 
 static inline int drv_ampdu_action(struct ieee80211_local *local,
@@ -176,10 +243,12 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
 				   struct ieee80211_sta *sta, u16 tid,
 				   u16 *ssn)
 {
+	int ret = -EOPNOTSUPP;
 	if (local->ops->ampdu_action)
-		return local->ops->ampdu_action(&local->hw, action,
-						sta, tid, ssn);
-	return -EOPNOTSUPP;
+		ret = local->ops->ampdu_action(&local->hw, action,
+					       sta, tid, ssn);
+	trace_drv_ampdu_action(local, action, sta, tid, ssn, ret);
+	return ret;
 }
 
 
diff --git a/net/mac80211/driver-trace.c b/net/mac80211/driver-trace.c
new file mode 100644
index 0000000..8ed8711
--- /dev/null
+++ b/net/mac80211/driver-trace.c
@@ -0,0 +1,9 @@
+/* bug in tracepoint.h, it should include this */
+#include <linux/module.h>
+
+/* sparse isn't too happy with all macros... */
+#ifndef __CHECKER__
+#include "driver-ops.h"
+#define CREATE_TRACE_POINTS
+#include "driver-trace.h"
+#endif
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
new file mode 100644
index 0000000..37b9051
--- /dev/null
+++ b/net/mac80211/driver-trace.h
@@ -0,0 +1,672 @@
+#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
+#define __MAC80211_DRIVER_TRACE
+
+#include <linux/tracepoint.h>
+#include <net/mac80211.h>
+#include "ieee80211_i.h"
+
+#if !defined(CONFIG_MAC80211_DRIVER_API_TRACER) || defined(__CHECKER__)
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#endif
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM mac80211
+
+#define MAXNAME		32
+#define LOCAL_ENTRY	__array(char, wiphy_name, 32)
+#define LOCAL_ASSIGN	strlcpy(__entry->wiphy_name, wiphy_name(local->hw.wiphy), MAXNAME)
+#define LOCAL_PR_FMT	"%s"
+#define LOCAL_PR_ARG	__entry->wiphy_name
+
+#define STA_ENTRY	__array(char, sta_addr, ETH_ALEN)
+#define STA_ASSIGN	(sta ? memcpy(__entry->sta_addr, sta->addr, ETH_ALEN) : memset(__entry->sta_addr, 0, ETH_ALEN))
+#define STA_PR_FMT	" sta:%pM"
+#define STA_PR_ARG	__entry->sta_addr
+
+#define VIF_ENTRY	__field(enum nl80211_iftype, vif_type) __field(void *, vif)
+#define VIF_ASSIGN	__entry->vif_type = vif ? vif->type : 0; __entry->vif = vif
+#define VIF_PR_FMT	" vif:%p(%d)"
+#define VIF_PR_ARG	__entry->vif, __entry->vif_type
+
+TRACE_EVENT(drv_start,
+	TP_PROTO(struct ieee80211_local *local, int ret),
+
+	TP_ARGS(local, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT, LOCAL_PR_ARG
+	)
+);
+
+TRACE_EVENT(drv_stop,
+	TP_PROTO(struct ieee80211_local *local),
+
+	TP_ARGS(local),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT, LOCAL_PR_ARG
+	)
+);
+
+TRACE_EVENT(drv_add_interface,
+	TP_PROTO(struct ieee80211_local *local,
+		 const u8 *addr,
+		 struct ieee80211_vif *vif,
+		 int ret),
+
+	TP_ARGS(local, addr, vif, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__array(char, addr, 6)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		memcpy(__entry->addr, addr, 6);
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT " addr:%pM ret:%d",
+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_remove_interface,
+	TP_PROTO(struct ieee80211_local *local,
+		 const u8 *addr, struct ieee80211_vif *vif),
+
+	TP_ARGS(local, addr, vif),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__array(char, addr, 6)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		memcpy(__entry->addr, addr, 6);
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT " addr:%pM",
+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
+	)
+);
+
+TRACE_EVENT(drv_config,
+	TP_PROTO(struct ieee80211_local *local,
+		 u32 changed,
+		 int ret),
+
+	TP_ARGS(local, changed, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u32, changed)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->changed = changed;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " ch:%#x ret:%d",
+		LOCAL_PR_ARG, __entry->changed, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_bss_info_changed,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_vif *vif,
+		 struct ieee80211_bss_conf *info,
+		 u32 changed),
+
+	TP_ARGS(local, vif, info, changed),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		__field(bool, assoc)
+		__field(u16, aid)
+		__field(bool, cts)
+		__field(bool, shortpre)
+		__field(bool, shortslot)
+		__field(u8, dtimper)
+		__field(u16, bcnint)
+		__field(u16, assoc_cap)
+		__field(u64, timestamp)
+		__field(u32, basic_rates)
+		__field(u32, changed)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		__entry->changed = changed;
+		__entry->aid = info->aid;
+		__entry->assoc = info->assoc;
+		__entry->shortpre = info->use_short_preamble;
+		__entry->cts = info->use_cts_prot;
+		__entry->shortslot = info->use_short_slot;
+		__entry->dtimper = info->dtim_period;
+		__entry->bcnint = info->beacon_int;
+		__entry->assoc_cap = info->assoc_capability;
+		__entry->timestamp = info->timestamp;
+		__entry->basic_rates = info->basic_rates;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT " changed:%#x",
+		LOCAL_PR_ARG, VIF_PR_ARG, __entry->changed
+	)
+);
+
+TRACE_EVENT(drv_prepare_multicast,
+	TP_PROTO(struct ieee80211_local *local, int mc_count, u64 ret),
+
+	TP_ARGS(local, mc_count, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(int, mc_count)
+		__field(u64, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->mc_count = mc_count;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " prepare mc (%d): %llx",
+		LOCAL_PR_ARG, __entry->mc_count,
+		(unsigned long long) __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_configure_filter,
+	TP_PROTO(struct ieee80211_local *local,
+		 unsigned int changed_flags,
+		 unsigned int *total_flags,
+		 u64 multicast),
+
+	TP_ARGS(local, changed_flags, total_flags, multicast),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(unsigned int, changed)
+		__field(unsigned int, total)
+		__field(u64, multicast)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->changed = changed_flags;
+		__entry->total = *total_flags;
+		__entry->multicast = multicast;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " changed:%#x total:%#x",
+		LOCAL_PR_ARG, __entry->changed, __entry->total
+	)
+);
+
+TRACE_EVENT(drv_set_tim,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_sta *sta, bool set, int ret),
+
+	TP_ARGS(local, sta, set, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		STA_ENTRY
+		__field(bool, set)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		STA_ASSIGN;
+		__entry->set = set;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT STA_PR_FMT " set:%d ret:%d",
+		LOCAL_PR_ARG, STA_PR_FMT, __entry->set, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_set_key,
+	TP_PROTO(struct ieee80211_local *local,
+		 enum set_key_cmd cmd, struct ieee80211_vif *vif,
+		 struct ieee80211_sta *sta,
+		 struct ieee80211_key_conf *key, int ret),
+
+	TP_ARGS(local, cmd, vif, sta, key, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		STA_ENTRY
+		__field(enum ieee80211_key_alg, alg)
+		__field(u8, hw_key_idx)
+		__field(u8, flags)
+		__field(s8, keyidx)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		STA_ASSIGN;
+		__entry->alg = key->alg;
+		__entry->flags = key->flags;
+		__entry->keyidx = key->keyidx;
+		__entry->hw_key_idx = key->hw_key_idx;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " ret:%d",
+		LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_update_tkip_key,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_key_conf *conf,
+		 const u8 *address, u32 iv32),
+
+	TP_ARGS(local, conf, address, iv32),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__array(u8, addr, 6)
+		__field(u32, iv32)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		memcpy(__entry->addr, address, 6);
+		__entry->iv32 = iv32;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " addr:%pM iv32:%#x",
+		LOCAL_PR_ARG, __entry->addr, __entry->iv32
+	)
+);
+
+TRACE_EVENT(drv_hw_scan,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct cfg80211_scan_request *req, int ret),
+
+	TP_ARGS(local, req, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " ret:%d",
+		LOCAL_PR_ARG, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_sw_scan_start,
+	TP_PROTO(struct ieee80211_local *local),
+
+	TP_ARGS(local),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT, LOCAL_PR_ARG
+	)
+);
+
+TRACE_EVENT(drv_sw_scan_complete,
+	TP_PROTO(struct ieee80211_local *local),
+
+	TP_ARGS(local),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT, LOCAL_PR_ARG
+	)
+);
+
+TRACE_EVENT(drv_get_stats,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_low_level_stats *stats,
+		 int ret),
+
+	TP_ARGS(local, stats, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(int, ret)
+		__field(unsigned int, ackfail)
+		__field(unsigned int, rtsfail)
+		__field(unsigned int, fcserr)
+		__field(unsigned int, rtssucc)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ret = ret;
+		__entry->ackfail = stats->dot11ACKFailureCount;
+		__entry->rtsfail = stats->dot11RTSFailureCount;
+		__entry->fcserr = stats->dot11FCSErrorCount;
+		__entry->rtssucc = stats->dot11RTSSuccessCount;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " ret:%d",
+		LOCAL_PR_ARG, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_get_tkip_seq,
+	TP_PROTO(struct ieee80211_local *local,
+		 u8 hw_key_idx, u32 *iv32, u16 *iv16),
+
+	TP_ARGS(local, hw_key_idx, iv32, iv16),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u8, hw_key_idx)
+		__field(u32, iv32)
+		__field(u16, iv16)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->hw_key_idx = hw_key_idx;
+		__entry->iv32 = *iv32;
+		__entry->iv16 = *iv16;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT, LOCAL_PR_ARG
+	)
+);
+
+TRACE_EVENT(drv_set_rts_threshold,
+	TP_PROTO(struct ieee80211_local *local, u32 value, int ret),
+
+	TP_ARGS(local, value, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u32, value)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ret = ret;
+		__entry->value = value;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " value:%d ret:%d",
+		LOCAL_PR_ARG, __entry->value, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_sta_notify,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_vif *vif,
+		 enum sta_notify_cmd cmd,
+		 struct ieee80211_sta *sta),
+
+	TP_ARGS(local, vif, cmd, sta),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		VIF_ENTRY
+		STA_ENTRY
+		__field(u32, cmd)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		VIF_ASSIGN;
+		STA_ASSIGN;
+		__entry->cmd = cmd;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  VIF_PR_FMT  STA_PR_FMT " cmd:%d",
+		LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->cmd
+	)
+);
+
+TRACE_EVENT(drv_conf_tx,
+	TP_PROTO(struct ieee80211_local *local, u16 queue,
+		 const struct ieee80211_tx_queue_params *params,
+		 int ret),
+
+	TP_ARGS(local, queue, params, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u16, queue)
+		__field(u16, txop)
+		__field(u16, cw_min)
+		__field(u16, cw_max)
+		__field(u8, aifs)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->queue = queue;
+		__entry->ret = ret;
+		__entry->txop = params->txop;
+		__entry->cw_max = params->cw_max;
+		__entry->cw_min = params->cw_min;
+		__entry->aifs = params->aifs;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " queue:%d ret:%d",
+		LOCAL_PR_ARG, __entry->queue, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_get_tx_stats,
+	TP_PROTO(struct ieee80211_local *local,
+		 struct ieee80211_tx_queue_stats *stats,
+		 int ret),
+
+	TP_ARGS(local, stats, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " ret:%d",
+		LOCAL_PR_ARG, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_get_tsf,
+	TP_PROTO(struct ieee80211_local *local, u64 ret),
+
+	TP_ARGS(local, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u64, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " ret:%llu",
+		LOCAL_PR_ARG, (unsigned long long)__entry->ret
+	)
+);
+
+TRACE_EVENT(drv_set_tsf,
+	TP_PROTO(struct ieee80211_local *local, u64 tsf),
+
+	TP_ARGS(local, tsf),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(u64, tsf)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->tsf = tsf;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " tsf:%llu",
+		LOCAL_PR_ARG, (unsigned long long)__entry->tsf
+	)
+);
+
+TRACE_EVENT(drv_reset_tsf,
+	TP_PROTO(struct ieee80211_local *local),
+
+	TP_ARGS(local),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT, LOCAL_PR_ARG
+	)
+);
+
+TRACE_EVENT(drv_tx_last_beacon,
+	TP_PROTO(struct ieee80211_local *local, int ret),
+
+	TP_ARGS(local, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		__entry->ret = ret;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT " ret:%d",
+		LOCAL_PR_ARG, __entry->ret
+	)
+);
+
+TRACE_EVENT(drv_ampdu_action,
+	TP_PROTO(struct ieee80211_local *local,
+		 enum ieee80211_ampdu_mlme_action action,
+		 struct ieee80211_sta *sta, u16 tid,
+		 u16 *ssn, int ret),
+
+	TP_ARGS(local, action, sta, tid, ssn, ret),
+
+	TP_STRUCT__entry(
+		LOCAL_ENTRY
+		STA_ENTRY
+		__field(u32, action)
+		__field(u16, tid)
+		__field(u16, ssn)
+		__field(int, ret)
+	),
+
+	TP_fast_assign(
+		LOCAL_ASSIGN;
+		STA_ASSIGN;
+		__entry->ret = ret;
+		__entry->action = action;
+		__entry->tid = tid;
+		__entry->ssn = *ssn;
+	),
+
+	TP_printk(
+		LOCAL_PR_FMT  STA_PR_FMT " action:%d tid:%d ret:%d",
+		LOCAL_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret
+	)
+);
+#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE driver-trace
+#include <trace/define_trace.h>
diff --git a/net/mac80211/event.c b/net/mac80211/event.c
index f288d01..01ae759 100644
--- a/net/mac80211/event.c
+++ b/net/mac80211/event.c
@@ -7,8 +7,7 @@
  *
  * mac80211 - events
  */
-
-#include <net/iw_handler.h>
+#include <net/cfg80211.h>
 #include "ieee80211_i.h"
 
 /*
@@ -17,26 +16,12 @@
  * driver or is still in the frame), it should provide that information.
  */
 void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
-				     struct ieee80211_hdr *hdr, const u8 *tsc)
+				     struct ieee80211_hdr *hdr, const u8 *tsc,
+				     gfp_t gfp)
 {
-	union iwreq_data wrqu;
-	char *buf = kmalloc(128, GFP_ATOMIC);
-
-	if (buf) {
-		/* TODO: needed parameters: count, key type, TSC */
-		sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
-			"keyid=%d %scast addr=%pM)",
-			keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
-			hdr->addr2);
-		memset(&wrqu, 0, sizeof(wrqu));
-		wrqu.data.length = strlen(buf);
-		wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf);
-		kfree(buf);
-	}
-
 	cfg80211_michael_mic_failure(sdata->dev, hdr->addr2,
 				     (hdr->addr1[0] & 0x01) ?
 				     NL80211_KEYTYPE_GROUP :
 				     NL80211_KEYTYPE_PAIRWISE,
-				     keyidx, tsc);
+				     keyidx, tsc, gfp);
 }
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 0b30277..920ec87 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -57,7 +57,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
 	 */
 	if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
 		ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
-				    sdata->u.ibss.bssid, 0);
+				    sdata->u.ibss.bssid, NULL, 0, 0);
 }
 
 static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
@@ -494,7 +494,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
 
 	capability = WLAN_CAPABILITY_IBSS;
 
-	if (sdata->default_key)
+	if (ifibss->privacy)
 		capability |= WLAN_CAPABILITY_PRIVACY;
 	else
 		sdata->drop_unencrypted = 0;
@@ -524,9 +524,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
 		return;
 
 	capability = WLAN_CAPABILITY_IBSS;
-	if (sdata->default_key)
+	if (ifibss->privacy)
 		capability |= WLAN_CAPABILITY_PRIVACY;
-
 	if (ifibss->fixed_bssid)
 		bssid = ifibss->bssid;
 	if (ifibss->fixed_channel)
@@ -705,7 +704,7 @@ static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_mgmt *mgmt;
 	u16 fc;
 
-	rx_status = (struct ieee80211_rx_status *) skb->cb;
+	rx_status = IEEE80211_SKB_RXCB(skb);
 	mgmt = (struct ieee80211_mgmt *) skb->data;
 	fc = le16_to_cpu(mgmt->frame_control);
 
@@ -743,7 +742,7 @@ static void ieee80211_ibss_work(struct work_struct *work)
 	if (!netif_running(sdata->dev))
 		return;
 
-	if (local->sw_scanning || local->hw_scanning)
+	if (local->scanning)
 		return;
 
 	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC))
@@ -782,7 +781,7 @@ static void ieee80211_ibss_timer(unsigned long data)
 	}
 
 	set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
-	queue_work(local->hw.workqueue, &ifibss->work);
+	ieee80211_queue_work(&local->hw, &ifibss->work);
 }
 
 #ifdef CONFIG_PM
@@ -836,8 +835,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
 }
 
 ieee80211_rx_result
-ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-		       struct ieee80211_rx_status *rx_status)
+ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_mgmt *mgmt;
@@ -852,11 +850,10 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
 	switch (fc & IEEE80211_FCTL_STYPE) {
 	case IEEE80211_STYPE_PROBE_RESP:
 	case IEEE80211_STYPE_BEACON:
-		memcpy(skb->cb, rx_status, sizeof(*rx_status));
 	case IEEE80211_STYPE_PROBE_REQ:
 	case IEEE80211_STYPE_AUTH:
 		skb_queue_tail(&sdata->u.ibss.skb_queue, skb);
-		queue_work(local->hw.workqueue, &sdata->u.ibss.work);
+		ieee80211_queue_work(&local->hw, &sdata->u.ibss.work);
 		return RX_QUEUED;
 	}
 
@@ -874,6 +871,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 	} else
 		sdata->u.ibss.fixed_bssid = false;
 
+	sdata->u.ibss.privacy = params->privacy;
+
 	sdata->vif.bss_conf.beacon_int = params->beacon_interval;
 
 	sdata->u.ibss.channel = params->channel;
@@ -913,7 +912,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
 	ieee80211_recalc_idle(sdata->local);
 
 	set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
-	queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
+	ieee80211_queue_work(&sdata->local->hw, &sdata->u.ibss.work);
 
 	return 0;
 }
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 68eb505..588005c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -24,7 +24,6 @@
 #include <linux/spinlock.h>
 #include <linux/etherdevice.h>
 #include <net/cfg80211.h>
-#include <net/iw_handler.h>
 #include <net/mac80211.h>
 #include "key.h"
 #include "sta_info.h"
@@ -213,7 +212,9 @@ struct ieee80211_if_vlan {
 };
 
 struct mesh_stats {
-	__u32 fwded_frames;		/* Mesh forwarded frames */
+	__u32 fwded_mcast;		/* Mesh forwarded multicast frames */
+	__u32 fwded_unicast;		/* Mesh forwarded unicast frames */
+	__u32 fwded_frames;		/* Mesh total forwarded frames */
 	__u32 dropped_frames_ttl;	/* Not transmitted since mesh_ttl == 0*/
 	__u32 dropped_frames_no_route;	/* Not transmitted, no route found */
 	atomic_t estab_plinks;
@@ -227,86 +228,81 @@ struct mesh_preq_queue {
 	u8 flags;
 };
 
+enum ieee80211_mgd_state {
+	IEEE80211_MGD_STATE_IDLE,
+	IEEE80211_MGD_STATE_PROBE,
+	IEEE80211_MGD_STATE_AUTH,
+	IEEE80211_MGD_STATE_ASSOC,
+};
+
+struct ieee80211_mgd_work {
+	struct list_head list;
+	struct ieee80211_bss *bss;
+	int ie_len;
+	u8 prev_bssid[ETH_ALEN];
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 ssid_len;
+	unsigned long timeout;
+	enum ieee80211_mgd_state state;
+	u16 auth_alg, auth_transaction;
+
+	int tries;
+
+	u8 key[WLAN_KEY_LEN_WEP104];
+	u8 key_len, key_idx;
+
+	/* must be last */
+	u8 ie[0]; /* for auth or assoc frame, not probe */
+};
+
 /* flags used in struct ieee80211_if_managed.flags */
-#define IEEE80211_STA_SSID_SET		BIT(0)
-#define IEEE80211_STA_BSSID_SET		BIT(1)
-#define IEEE80211_STA_PREV_BSSID_SET	BIT(2)
-#define IEEE80211_STA_AUTHENTICATED	BIT(3)
-#define IEEE80211_STA_ASSOCIATED	BIT(4)
-#define IEEE80211_STA_PROBEREQ_POLL	BIT(5)
-#define IEEE80211_STA_CREATE_IBSS	BIT(6)
-#define IEEE80211_STA_CONTROL_PORT	BIT(7)
-#define IEEE80211_STA_WMM_ENABLED	BIT(8)
-/* hole at 9, please re-use */
-#define IEEE80211_STA_AUTO_SSID_SEL	BIT(10)
-#define IEEE80211_STA_AUTO_BSSID_SEL	BIT(11)
-#define IEEE80211_STA_AUTO_CHANNEL_SEL	BIT(12)
-#define IEEE80211_STA_PRIVACY_INVOKED	BIT(13)
-#define IEEE80211_STA_TKIP_WEP_USED	BIT(14)
-#define IEEE80211_STA_CSA_RECEIVED	BIT(15)
-#define IEEE80211_STA_MFP_ENABLED	BIT(16)
-#define IEEE80211_STA_EXT_SME		BIT(17)
-/* flags for MLME request */
-#define IEEE80211_STA_REQ_SCAN 0
-#define IEEE80211_STA_REQ_AUTH 1
-#define IEEE80211_STA_REQ_RUN  2
+enum ieee80211_sta_flags {
+	IEEE80211_STA_BEACON_POLL	= BIT(0),
+	IEEE80211_STA_CONNECTION_POLL	= BIT(1),
+	IEEE80211_STA_CONTROL_PORT	= BIT(2),
+	IEEE80211_STA_WMM_ENABLED	= BIT(3),
+	IEEE80211_STA_DISABLE_11N	= BIT(4),
+	IEEE80211_STA_CSA_RECEIVED	= BIT(5),
+	IEEE80211_STA_MFP_ENABLED	= BIT(6),
+};
 
-/* bitfield of allowed auth algs */
-#define IEEE80211_AUTH_ALG_OPEN BIT(0)
-#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1)
-#define IEEE80211_AUTH_ALG_LEAP BIT(2)
-#define IEEE80211_AUTH_ALG_FT BIT(3)
+/* flags for MLME request */
+enum ieee80211_sta_request {
+	IEEE80211_STA_REQ_SCAN,
+};
 
 struct ieee80211_if_managed {
 	struct timer_list timer;
+	struct timer_list conn_mon_timer;
+	struct timer_list bcn_mon_timer;
 	struct timer_list chswitch_timer;
 	struct work_struct work;
+	struct work_struct monitor_work;
 	struct work_struct chswitch_work;
 	struct work_struct beacon_loss_work;
 
-	u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
+	unsigned long probe_timeout;
+	int probe_send_count;
 
-	u8 ssid[IEEE80211_MAX_SSID_LEN];
-	size_t ssid_len;
+	struct mutex mtx;
+	struct ieee80211_bss *associated;
+	struct ieee80211_mgd_work *old_associate_work;
+	struct list_head work_list;
 
-	enum {
-		IEEE80211_STA_MLME_DISABLED,
-		IEEE80211_STA_MLME_DIRECT_PROBE,
-		IEEE80211_STA_MLME_AUTHENTICATE,
-		IEEE80211_STA_MLME_ASSOCIATE,
-		IEEE80211_STA_MLME_ASSOCIATED,
-	} state;
+	u8 bssid[ETH_ALEN];
 
 	u16 aid;
-	u16 ap_capab, capab;
-	u8 *extra_ie; /* to be added to the end of AssocReq */
-	size_t extra_ie_len;
-
-	/* The last AssocReq/Resp IEs */
-	u8 *assocreq_ies, *assocresp_ies;
-	size_t assocreq_ies_len, assocresp_ies_len;
+	u16 capab;
 
 	struct sk_buff_head skb_queue;
 
-	int assoc_scan_tries; /* number of scans done pre-association */
-	int direct_probe_tries; /* retries for direct probes */
-	int auth_tries; /* retries for auth req */
-	int assoc_tries; /* retries for assoc req */
-
 	unsigned long timers_running; /* used for quiesce/restart */
 	bool powersave; /* powersave requested for this iface */
 
 	unsigned long request;
 
-	unsigned long last_probe;
-	unsigned long last_beacon;
-
 	unsigned int flags;
 
-	unsigned int auth_algs; /* bitfield of allowed auth algs */
-	int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
-	int auth_transaction;
-
 	u32 beacon_crc;
 
 	enum {
@@ -316,10 +312,6 @@ struct ieee80211_if_managed {
 	} mfp; /* management frame protection */
 
 	int wmm_last_param_set;
-
-	/* Extra IE data for management frames */
-	u8 *sme_auth_ie;
-	size_t sme_auth_ie_len;
 };
 
 enum ieee80211_ibss_request {
@@ -339,6 +331,7 @@ struct ieee80211_if_ibss {
 
 	bool fixed_bssid;
 	bool fixed_channel;
+	bool privacy;
 
 	u8 bssid[ETH_ALEN];
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -364,7 +357,7 @@ struct ieee80211_if_mesh {
 
 	unsigned long timers_running;
 
-	bool housekeeping;
+	unsigned long wrkq_flags;
 
 	u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
 	size_t mesh_id_len;
@@ -374,6 +367,10 @@ struct ieee80211_if_mesh {
 	u8 mesh_pm_id[4];
 	/* Congestion Control Mode Identifier */
 	u8 mesh_cc_id[4];
+	/* Synchronization Protocol Identifier */
+	u8 mesh_sp_id[4];
+	/* Authentication Protocol Identifier */
+	u8 mesh_auth_id[4];
 	/* Local mesh Destination Sequence Number */
 	u32 dsn;
 	/* Last used PREQ ID */
@@ -478,20 +475,9 @@ struct ieee80211_sub_if_data {
 	union {
 		struct {
 			struct dentry *drop_unencrypted;
-			struct dentry *state;
 			struct dentry *bssid;
-			struct dentry *prev_bssid;
-			struct dentry *ssid_len;
 			struct dentry *aid;
-			struct dentry *ap_capab;
 			struct dentry *capab;
-			struct dentry *extra_ie_len;
-			struct dentry *auth_tries;
-			struct dentry *assoc_tries;
-			struct dentry *auth_algs;
-			struct dentry *auth_alg;
-			struct dentry *auth_transaction;
-			struct dentry *flags;
 			struct dentry *force_unicast_rateidx;
 			struct dentry *max_ratectrl_rateidx;
 		} sta;
@@ -526,6 +512,8 @@ struct ieee80211_sub_if_data {
 #ifdef CONFIG_MAC80211_MESH
 	struct dentry *mesh_stats_dir;
 	struct {
+		struct dentry *fwded_mcast;
+		struct dentry *fwded_unicast;
 		struct dentry *fwded_frames;
 		struct dentry *dropped_frames_ttl;
 		struct dentry *dropped_frames_no_route;
@@ -588,12 +576,44 @@ enum queue_stop_reason {
 	IEEE80211_QUEUE_STOP_REASON_CSA,
 	IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
 	IEEE80211_QUEUE_STOP_REASON_SUSPEND,
-	IEEE80211_QUEUE_STOP_REASON_PENDING,
 	IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
 };
 
-struct ieee80211_master_priv {
-	struct ieee80211_local *local;
+/**
+ * mac80211 scan flags - currently active scan mode
+ *
+ * @SCAN_SW_SCANNING: We're currently in the process of scanning but may as
+ *	well be on the operating channel
+ * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
+ *	determine if we are on the operating channel or not
+ * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning,
+ *	gets only set in conjunction with SCAN_SW_SCANNING
+ */
+enum {
+	SCAN_SW_SCANNING,
+	SCAN_HW_SCANNING,
+	SCAN_OFF_CHANNEL,
+};
+
+/**
+ * enum mac80211_scan_state - scan state machine states
+ *
+ * @SCAN_DECISION: Main entry point to the scan state machine, this state
+ *	determines if we should keep on scanning or switch back to the
+ *	operating channel
+ * @SCAN_SET_CHANNEL: Set the next channel to be scanned
+ * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses
+ * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP
+ *	about us leaving the channel and stop all associated STA interfaces
+ * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the
+ *	AP about us being back and restart all associated STA interfaces
+ */
+enum mac80211_scan_state {
+	SCAN_DECISION,
+	SCAN_SET_CHANNEL,
+	SCAN_SEND_PROBE,
+	SCAN_LEAVE_OPER_CHANNEL,
+	SCAN_ENTER_OPER_CHANNEL,
 };
 
 struct ieee80211_local {
@@ -604,17 +624,33 @@ struct ieee80211_local {
 
 	const struct ieee80211_ops *ops;
 
+	/*
+	 * private workqueue to mac80211. mac80211 makes this accessible
+	 * via ieee80211_queue_work()
+	 */
+	struct workqueue_struct *workqueue;
+
 	unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
 	/* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
 	spinlock_t queue_stop_reason_lock;
 
-	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
 	int open_count;
 	int monitors, cooked_mntrs;
 	/* number of interfaces with corresponding FIF_ flags */
-	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
+	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
 	unsigned int filter_flags; /* FIF_* */
 	struct iw_statistics wstats;
+
+	/* protects the aggregated multicast list and filter calls */
+	spinlock_t filter_lock;
+
+	/* used for uploading changed mc list */
+	struct work_struct reconfig_filter;
+
+	/* aggregated multicast list */
+	struct dev_addr_list *mc_list;
+	int mc_count;
+
 	bool tim_in_locked_section; /* see ieee80211_beacon_get() */
 
 	/*
@@ -631,6 +667,9 @@ struct ieee80211_local {
 	 */
 	bool quiescing;
 
+	/* device is started */
+	bool started;
+
 	int tx_headroom; /* required headroom for hardware/radiotap */
 
 	/* Tasklet and skb queue to process calls from IRQ mode. All frames
@@ -653,6 +692,7 @@ struct ieee80211_local {
 	struct list_head sta_list;
 	struct sta_info *sta_hash[STA_HASH_SIZE];
 	struct timer_list sta_cleanup;
+	int sta_generation;
 
 	struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
 	struct tasklet_struct tx_pending_tasklet;
@@ -687,9 +727,9 @@ struct ieee80211_local {
 
 	/* Scanning and BSS list */
 	struct mutex scan_mtx;
-	bool sw_scanning, hw_scanning;
+	unsigned long scanning;
 	struct cfg80211_ssid scan_ssid;
-	struct cfg80211_scan_request int_scan_req;
+	struct cfg80211_scan_request *int_scan_req;
 	struct cfg80211_scan_request *scan_req;
 	struct ieee80211_channel *scan_channel;
 	const u8 *orig_ies;
@@ -697,7 +737,7 @@ struct ieee80211_local {
 	int scan_channel_idx;
 	int scan_ies_len;
 
-	enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
+	enum mac80211_scan_state next_scan_state;
 	struct delayed_work scan_work;
 	struct ieee80211_sub_if_data *scan_sdata;
 	enum nl80211_channel_type oper_channel_type;
@@ -834,10 +874,6 @@ struct ieee80211_local {
 static inline struct ieee80211_sub_if_data *
 IEEE80211_DEV_TO_SUB_IF(struct net_device *dev)
 {
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-	BUG_ON(!local || local->mdev == dev);
-
 	return netdev_priv(dev);
 }
 
@@ -937,21 +973,20 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 void ieee80211_configure_filter(struct ieee80211_local *local);
 u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
 
-/* wireless extensions */
-extern const struct iw_handler_def ieee80211_iw_handler_def;
-
 /* STA code */
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
+int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
+		       struct cfg80211_auth_request *req);
+int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
+			struct cfg80211_assoc_request *req);
+int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
+			 struct cfg80211_deauth_request *req,
+			 void *cookie);
+int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
+			   struct cfg80211_disassoc_request *req,
+			   void *cookie);
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-					  struct sk_buff *skb,
-					  struct ieee80211_rx_status *rx_status);
-int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata);
-int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
-int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
-int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
-void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata);
-int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason);
-int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
+					  struct sk_buff *skb);
 void ieee80211_send_pspoll(struct ieee80211_local *local,
 			   struct ieee80211_sub_if_data *sdata);
 void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
@@ -967,8 +1002,7 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
 void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result
-ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-		       struct ieee80211_rx_status *rx_status);
+ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
 					u8 *bssid, u8 *addr, u32 supp_rates);
 int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
@@ -983,16 +1017,9 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
 				    const u8 *ssid, u8 ssid_len);
 int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
 			   struct cfg80211_scan_request *req);
-int ieee80211_scan_results(struct ieee80211_local *local,
-			   struct iw_request_info *info,
-			   char *buf, size_t len);
 void ieee80211_scan_cancel(struct ieee80211_local *local);
 ieee80211_rx_result
-ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
-		  struct sk_buff *skb,
-		  struct ieee80211_rx_status *rx_status);
-int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
-			       const char *ie, size_t len);
+ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 
 void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
 struct ieee80211_bss *
@@ -1008,8 +1035,6 @@ ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
 		     u8 *ssid, u8 ssid_len);
 void ieee80211_rx_bss_put(struct ieee80211_local *local,
 			  struct ieee80211_bss *bss);
-void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid,
-			     int freq, u8 *ssid, u8 ssid_len);
 
 /* interface handling */
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
@@ -1025,9 +1050,10 @@ void ieee80211_recalc_idle(struct ieee80211_local *local);
 /* tx handling */
 void ieee80211_clear_tx_pending(struct ieee80211_local *local);
 void ieee80211_tx_pending(unsigned long data);
-int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
+netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
+					 struct net_device *dev);
+netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
+				       struct net_device *dev);
 
 /* HT */
 void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
@@ -1065,6 +1091,7 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
 
 /* Suspend/resume and hw reconfiguration */
 int ieee80211_reconfig(struct ieee80211_local *local);
+void ieee80211_stop_device(struct ieee80211_local *local);
 
 #ifdef CONFIG_PM
 int __ieee80211_suspend(struct ieee80211_hw *hw);
@@ -1092,7 +1119,8 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
 int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
 			     int rate, int erp, int short_preamble);
 void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
-				     struct ieee80211_hdr *hdr, const u8 *tsc);
+				     struct ieee80211_hdr *hdr, const u8 *tsc,
+				     gfp_t gfp);
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
 void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
 		      int encrypt);
@@ -1129,8 +1157,8 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 			 u16 transaction, u16 auth_alg,
-			 u8 *extra, size_t extra_len,
-			 const u8 *bssid, int encrypt);
+			 u8 *extra, size_t extra_len, const u8 *bssid,
+			 const u8 *key, u8 key_len, u8 key_idx);
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			     const u8 *ie, size_t ie_len);
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b7c8a44..b8295cb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -190,10 +190,6 @@ static int ieee80211_open(struct net_device *dev)
 			       ETH_ALEN);
 	}
 
-	if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0)
-		memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr,
-		       ETH_ALEN);
-
 	/*
 	 * Validate the MAC address for this device.
 	 */
@@ -224,18 +220,15 @@ static int ieee80211_open(struct net_device *dev)
 			local->fif_fcsfail++;
 		if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
 			local->fif_plcpfail++;
-		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
 			local->fif_control++;
+			local->fif_pspoll++;
+		}
 		if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
 			local->fif_other_bss++;
 
-		netif_addr_lock_bh(local->mdev);
 		ieee80211_configure_filter(local);
-		netif_addr_unlock_bh(local->mdev);
 		break;
-	case NL80211_IFTYPE_STATION:
-		sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
-		/* fall through */
 	default:
 		conf.vif = &sdata->vif;
 		conf.type = sdata->vif.type;
@@ -246,12 +239,15 @@ static int ieee80211_open(struct net_device *dev)
 
 		if (ieee80211_vif_is_mesh(&sdata->vif)) {
 			local->fif_other_bss++;
-			netif_addr_lock_bh(local->mdev);
 			ieee80211_configure_filter(local);
-			netif_addr_unlock_bh(local->mdev);
 
 			ieee80211_start_mesh(sdata);
+		} else if (sdata->vif.type == NL80211_IFTYPE_AP) {
+			local->fif_pspoll++;
+
+			ieee80211_configure_filter(local);
 		}
+
 		changed |= ieee80211_reset_erp_info(sdata);
 		ieee80211_bss_info_change_notify(sdata, changed);
 		ieee80211_enable_keys(sdata);
@@ -281,15 +277,6 @@ static int ieee80211_open(struct net_device *dev)
 		}
 	}
 
-	if (local->open_count == 0) {
-		res = dev_open(local->mdev);
-		WARN_ON(res);
-		if (res)
-			goto err_del_interface;
-		tasklet_enable(&local->tx_pending_tasklet);
-		tasklet_enable(&local->tasklet);
-	}
-
 	/*
 	 * set_multicast_list will be invoked by the networking core
 	 * which will check whether any increments here were done in
@@ -323,7 +310,7 @@ static int ieee80211_open(struct net_device *dev)
 	 * to fix this.
 	 */
 	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		queue_work(local->hw.workqueue, &sdata->u.mgd.work);
+		ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
 
 	netif_tx_start_all_queues(dev);
 
@@ -346,7 +333,10 @@ static int ieee80211_stop(struct net_device *dev)
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_init_conf conf;
 	struct sta_info *sta;
+	unsigned long flags;
+	struct sk_buff *skb, *tmp;
 	u32 hw_reconf_flags = 0;
+	int i;
 
 	/*
 	 * Stop TX on this interface first.
@@ -366,18 +356,6 @@ static int ieee80211_stop(struct net_device *dev)
 	rcu_read_unlock();
 
 	/*
-	 * Announce that we are leaving the network, in case we are a
-	 * station interface type. This must be done before removing
-	 * all stations associated with sta_info_flush, otherwise STA
-	 * information will be gone and no announce being done.
-	 */
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		if (sdata->u.mgd.state != IEEE80211_STA_MLME_DISABLED)
-			ieee80211_sta_deauthenticate(sdata,
-				WLAN_REASON_DEAUTH_LEAVING);
-	}
-
-	/*
 	 * Remove all stations associated with this interface.
 	 *
 	 * This must be done before calling ops->remove_interface()
@@ -408,13 +386,24 @@ static int ieee80211_stop(struct net_device *dev)
 	if (sdata->flags & IEEE80211_SDATA_PROMISC)
 		atomic_dec(&local->iff_promiscs);
 
-	dev_mc_unsync(local->mdev, dev);
+	if (sdata->vif.type == NL80211_IFTYPE_AP)
+		local->fif_pspoll--;
+
+	netif_addr_lock_bh(dev);
+	spin_lock_bh(&local->filter_lock);
+	__dev_addr_unsync(&local->mc_list, &local->mc_count,
+			  &dev->mc_list, &dev->mc_count);
+	spin_unlock_bh(&local->filter_lock);
+	netif_addr_unlock_bh(dev);
+
+	ieee80211_configure_filter(local);
+
 	del_timer_sync(&local->dynamic_ps_timer);
 	cancel_work_sync(&local->dynamic_ps_enable_work);
 
 	/* APs need special treatment */
 	if (sdata->vif.type == NL80211_IFTYPE_AP) {
-		struct ieee80211_sub_if_data *vlan, *tmp;
+		struct ieee80211_sub_if_data *vlan, *tmpsdata;
 		struct beacon_data *old_beacon = sdata->u.ap.beacon;
 
 		/* remove beacon */
@@ -423,7 +412,7 @@ static int ieee80211_stop(struct net_device *dev)
 		kfree(old_beacon);
 
 		/* down all dependent devices, that is VLANs */
-		list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans,
+		list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
 					 u.vlan.list)
 			dev_close(vlan->dev);
 		WARN_ON(!list_empty(&sdata->u.ap.vlans));
@@ -452,29 +441,30 @@ static int ieee80211_stop(struct net_device *dev)
 			local->fif_fcsfail--;
 		if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
 			local->fif_plcpfail--;
-		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
+		if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
+			local->fif_pspoll--;
 			local->fif_control--;
+		}
 		if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
 			local->fif_other_bss--;
 
-		netif_addr_lock_bh(local->mdev);
 		ieee80211_configure_filter(local);
-		netif_addr_unlock_bh(local->mdev);
 		break;
 	case NL80211_IFTYPE_STATION:
-		memset(sdata->u.mgd.bssid, 0, ETH_ALEN);
 		del_timer_sync(&sdata->u.mgd.chswitch_timer);
 		del_timer_sync(&sdata->u.mgd.timer);
+		del_timer_sync(&sdata->u.mgd.conn_mon_timer);
+		del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
 		/*
-		 * If the timer fired while we waited for it, it will have
-		 * requeued the work. Now the work will be running again
+		 * If any of the timers fired while we waited for it, it will
+		 * have queued its work. Now the work will be running again
 		 * but will not rearm the timer again because it checks
 		 * whether the interface is running, which, at this point,
 		 * it no longer is.
 		 */
 		cancel_work_sync(&sdata->u.mgd.work);
 		cancel_work_sync(&sdata->u.mgd.chswitch_work);
-
+		cancel_work_sync(&sdata->u.mgd.monitor_work);
 		cancel_work_sync(&sdata->u.mgd.beacon_loss_work);
 
 		/*
@@ -485,12 +475,6 @@ static int ieee80211_stop(struct net_device *dev)
 		 */
 		synchronize_rcu();
 		skb_queue_purge(&sdata->u.mgd.skb_queue);
-
-		sdata->u.mgd.flags &= ~(IEEE80211_STA_PRIVACY_INVOKED |
-					IEEE80211_STA_TKIP_WEP_USED);
-		kfree(sdata->u.mgd.extra_ie);
-		sdata->u.mgd.extra_ie = NULL;
-		sdata->u.mgd.extra_ie_len = 0;
 		/* fall through */
 	case NL80211_IFTYPE_ADHOC:
 		if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
@@ -507,37 +491,23 @@ static int ieee80211_stop(struct net_device *dev)
 			local->fif_other_bss--;
 			atomic_dec(&local->iff_allmultis);
 
-			netif_addr_lock_bh(local->mdev);
 			ieee80211_configure_filter(local);
-			netif_addr_unlock_bh(local->mdev);
 
 			ieee80211_stop_mesh(sdata);
 		}
 		/* fall through */
 	default:
-		if (local->scan_sdata == sdata) {
-			if (!local->ops->hw_scan)
-				cancel_delayed_work_sync(&local->scan_work);
-			/*
-			 * The software scan can no longer run now, so we can
-			 * clear out the scan_sdata reference. However, the
-			 * hardware scan may still be running. The complete
-			 * function must be prepared to handle a NULL value.
-			 */
-			local->scan_sdata = NULL;
-			/*
-			 * The memory barrier guarantees that another CPU
-			 * that is hardware-scanning will now see the fact
-			 * that this interface is gone.
-			 */
-			smp_mb();
-			/*
-			 * If software scanning, complete the scan but since
-			 * the scan_sdata is NULL already don't send out a
-			 * scan event to userspace -- the scan is incomplete.
-			 */
-			if (local->sw_scanning)
-				ieee80211_scan_completed(&local->hw, true);
+		if (local->scan_sdata == sdata)
+			ieee80211_scan_cancel(local);
+
+		/*
+		 * Disable beaconing for AP and mesh, IBSS can't
+		 * still be joined to a network at this point.
+		 */
+		if (sdata->vif.type == NL80211_IFTYPE_AP ||
+		    sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
+			ieee80211_bss_info_change_notify(sdata,
+				BSS_CHANGED_BEACON_ENABLED);
 		}
 
 		conf.vif = &sdata->vif;
@@ -555,17 +525,8 @@ static int ieee80211_stop(struct net_device *dev)
 	ieee80211_recalc_ps(local, -1);
 
 	if (local->open_count == 0) {
-		if (netif_running(local->mdev))
-			dev_close(local->mdev);
-
-		drv_stop(local);
-
-		ieee80211_led_radio(local, false);
-
-		flush_workqueue(local->hw.workqueue);
-
-		tasklet_disable(&local->tx_pending_tasklet);
-		tasklet_disable(&local->tasklet);
+		ieee80211_clear_tx_pending(local);
+		ieee80211_stop_device(local);
 
 		/* no reconfiguring after stop! */
 		hw_reconf_flags = 0;
@@ -575,6 +536,18 @@ static int ieee80211_stop(struct net_device *dev)
 	if (hw_reconf_flags)
 		ieee80211_hw_config(local, hw_reconf_flags);
 
+	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+	for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
+		skb_queue_walk_safe(&local->pending[i], skb, tmp) {
+			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+			if (info->control.vif == &sdata->vif) {
+				__skb_unlink(skb, &local->pending[i]);
+				dev_kfree_skb_irq(skb);
+			}
+		}
+	}
+	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
 	return 0;
 }
 
@@ -604,8 +577,11 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
 			atomic_dec(&local->iff_promiscs);
 		sdata->flags ^= IEEE80211_SDATA_PROMISC;
 	}
-
-	dev_mc_sync(local->mdev, dev);
+	spin_lock_bh(&local->filter_lock);
+	__dev_addr_sync(&local->mc_list, &local->mc_count,
+			&dev->mc_list, &dev->mc_count);
+	spin_unlock_bh(&local->filter_lock);
+	ieee80211_queue_work(&local->hw, &local->reconfig_filter);
 }
 
 /*
@@ -652,11 +628,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
 			kfree_skb(sdata->u.ibss.presp);
 		break;
 	case NL80211_IFTYPE_STATION:
-		kfree(sdata->u.mgd.extra_ie);
-		kfree(sdata->u.mgd.assocreq_ies);
-		kfree(sdata->u.mgd.assocresp_ies);
-		kfree(sdata->u.mgd.sme_auth_ie);
-		break;
 	case NL80211_IFTYPE_WDS:
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_MONITOR:
@@ -695,7 +666,6 @@ static void ieee80211_if_setup(struct net_device *dev)
 {
 	ether_setup(dev);
 	dev->netdev_ops = &ieee80211_dataif_ops;
-	dev->wireless_handlers = &ieee80211_iw_handler_def;
 	dev->destructor = free_netdev;
 }
 
@@ -784,6 +754,10 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
 	return 0;
 }
 
+static struct device_type wiphy_type = {
+	.name	= "wlan",
+};
+
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 		     struct net_device **new_dev, enum nl80211_iftype type,
 		     struct vif_params *params)
@@ -798,6 +772,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 			    name, ieee80211_if_setup);
 	if (!ndev)
 		return -ENOMEM;
+	dev_net_set(ndev, wiphy_net(local->hw.wiphy));
 
 	ndev->needed_headroom = local->tx_headroom +
 				4*6 /* four MAC addresses */
@@ -814,7 +789,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 
 	memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
 	SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
-	ndev->features |= NETIF_F_NETNS_LOCAL;
+	SET_NETDEV_DEVTYPE(ndev, &wiphy_type);
 
 	/* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
 	sdata = netdev_priv(ndev);
@@ -931,7 +906,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
 	struct ieee80211_sub_if_data *sdata;
 	int count = 0;
 
-	if (local->hw_scanning || local->sw_scanning)
+	if (local->scanning)
 		return ieee80211_idle_off(local, "scanning");
 
 	list_for_each_entry(sdata, &local->interfaces, list) {
@@ -939,7 +914,8 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
 			continue;
 		/* do not count disabled managed interfaces */
 		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
-		    sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED)
+		    !sdata->u.mgd.associated &&
+		    list_empty(&sdata->u.mgd.work_list))
 			continue;
 		/* do not count unused IBSS interfaces */
 		if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 092a017..797f539 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -50,9 +50,9 @@ struct ieee80211_tx_status_rtap_hdr {
 } __attribute__ ((packed));
 
 
-/* must be called under mdev tx lock */
 void ieee80211_configure_filter(struct ieee80211_local *local)
 {
+	u64 mc;
 	unsigned int changed_flags;
 	unsigned int new_flags = 0;
 
@@ -62,7 +62,7 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
 	if (atomic_read(&local->iff_allmultis))
 		new_flags |= FIF_ALLMULTI;
 
-	if (local->monitors)
+	if (local->monitors || local->scanning)
 		new_flags |= FIF_BCN_PRBRESP_PROMISC;
 
 	if (local->fif_fcsfail)
@@ -77,77 +77,29 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
 	if (local->fif_other_bss)
 		new_flags |= FIF_OTHER_BSS;
 
+	if (local->fif_pspoll)
+		new_flags |= FIF_PSPOLL;
+
+	spin_lock_bh(&local->filter_lock);
 	changed_flags = local->filter_flags ^ new_flags;
 
+	mc = drv_prepare_multicast(local, local->mc_count, local->mc_list);
+	spin_unlock_bh(&local->filter_lock);
+
 	/* be a bit nasty */
 	new_flags |= (1<<31);
 
-	drv_configure_filter(local, changed_flags, &new_flags,
-			     local->mdev->mc_count,
-			     local->mdev->mc_list);
+	drv_configure_filter(local, changed_flags, &new_flags, mc);
 
 	WARN_ON(new_flags & (1<<31));
 
 	local->filter_flags = new_flags & ~(1<<31);
 }
 
-/* master interface */
-
-static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr)
-{
-	memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
-	return ETH_ALEN;
-}
-
-static const struct header_ops ieee80211_header_ops = {
-	.create		= eth_header,
-	.parse		= header_parse_80211,
-	.rebuild	= eth_rebuild_header,
-	.cache		= eth_header_cache,
-	.cache_update	= eth_header_cache_update,
-};
-
-static int ieee80211_master_open(struct net_device *dev)
+static void ieee80211_reconfig_filter(struct work_struct *work)
 {
-	struct ieee80211_master_priv *mpriv = netdev_priv(dev);
-	struct ieee80211_local *local = mpriv->local;
-	struct ieee80211_sub_if_data *sdata;
-	int res = -EOPNOTSUPP;
-
-	/* we hold the RTNL here so can safely walk the list */
-	list_for_each_entry(sdata, &local->interfaces, list) {
-		if (netif_running(sdata->dev)) {
-			res = 0;
-			break;
-		}
-	}
-
-	if (res)
-		return res;
-
-	netif_tx_start_all_queues(local->mdev);
-
-	return 0;
-}
-
-static int ieee80211_master_stop(struct net_device *dev)
-{
-	struct ieee80211_master_priv *mpriv = netdev_priv(dev);
-	struct ieee80211_local *local = mpriv->local;
-	struct ieee80211_sub_if_data *sdata;
-
-	/* we hold the RTNL here so can safely walk the list */
-	list_for_each_entry(sdata, &local->interfaces, list)
-		if (netif_running(sdata->dev))
-			dev_close(sdata->dev);
-
-	return 0;
-}
-
-static void ieee80211_master_set_multicast_list(struct net_device *dev)
-{
-	struct ieee80211_master_priv *mpriv = netdev_priv(dev);
-	struct ieee80211_local *local = mpriv->local;
+	struct ieee80211_local *local =
+		container_of(work, struct ieee80211_local, reconfig_filter);
 
 	ieee80211_configure_filter(local);
 }
@@ -259,7 +211,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 	}
 
 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
-		if (local->sw_scanning) {
+		if (local->quiescing || !netif_running(sdata->dev) ||
+		    test_bit(SCAN_SW_SCANNING, &local->scanning)) {
 			sdata->vif.bss_conf.enable_beacon = false;
 		} else {
 			/*
@@ -288,9 +241,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
 
 	drv_bss_info_changed(local, &sdata->vif,
 			     &sdata->vif.bss_conf, changed);
-
-	/* DEPRECATED */
-	local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;
 }
 
 u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
@@ -310,7 +260,6 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	int tmp;
 
-	skb->dev = local->mdev;
 	skb->pkt_type = IEEE80211_TX_STATUS_MSG;
 	skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ?
 		       &local->skb_queue : &local->skb_queue_unreliable, skb);
@@ -330,19 +279,16 @@ static void ieee80211_tasklet_handler(unsigned long data)
 {
 	struct ieee80211_local *local = (struct ieee80211_local *) data;
 	struct sk_buff *skb;
-	struct ieee80211_rx_status rx_status;
 	struct ieee80211_ra_tid *ra_tid;
 
 	while ((skb = skb_dequeue(&local->skb_queue)) ||
 	       (skb = skb_dequeue(&local->skb_queue_unreliable))) {
 		switch (skb->pkt_type) {
 		case IEEE80211_RX_MSG:
-			/* status is in skb->cb */
-			memcpy(&rx_status, skb->cb, sizeof(rx_status));
 			/* Clear skb->pkt_type in order to not confuse kernel
 			 * netstack. */
 			skb->pkt_type = 0;
-			__ieee80211_rx(local_to_hw(local), skb, &rx_status);
+			ieee80211_rx(local_to_hw(local), skb);
 			break;
 		case IEEE80211_TX_STATUS_MSG:
 			skb->pkt_type = 0;
@@ -375,6 +321,31 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
+	/*
+	 * XXX: This is temporary!
+	 *
+	 *	The problem here is that when we get here, the driver will
+	 *	quite likely have pretty much overwritten info->control by
+	 *	using info->driver_data or info->rate_driver_data. Thus,
+	 *	when passing out the frame to the driver again, we would be
+	 *	passing completely bogus data since the driver would then
+	 *	expect a properly filled info->control. In mac80211 itself
+	 *	the same problem occurs, since we need info->control.vif
+	 *	internally.
+	 *
+	 *	To fix this, we should send the frame through TX processing
+	 *	again. However, it's not that simple, since the frame will
+	 *	have been software-encrypted (if applicable) already, and
+	 *	encrypting it again doesn't do much good. So to properly do
+	 *	that, we not only have to skip the actual 'raw' encryption
+	 *	(key selection etc. still has to be done!) but also the
+	 *	sequence number assignment since that impacts the crypto
+	 *	encapsulation, of course.
+	 *
+	 *	Hence, for now, fix the bug by just dropping the frame.
+	 */
+	goto drop;
+
 	sta->tx_filtered_count++;
 
 	/*
@@ -428,6 +399,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
 		return;
 	}
 
+ drop:
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 	if (net_ratelimit())
 		printk(KERN_DEBUG "%s: dropped TX filtered frame, "
@@ -510,6 +482,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 		}
 
 		rate_control_tx_status(local, sband, sta, skb);
+		if (ieee80211_vif_is_mesh(&sta->sdata->vif))
+			ieee80211s_update_metric(local, sta, skb);
 	}
 
 	rcu_read_unlock();
@@ -685,6 +659,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 	if (!wiphy)
 		return NULL;
 
+	wiphy->netnsok = true;
 	wiphy->privid = mac80211_wiphy_privid;
 
 	/* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
@@ -711,7 +686,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 	local->hw.max_rates = 1;
 	local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
 	local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
-	local->hw.conf.radio_enabled = true;
 	local->user_power_level = -1;
 
 	INIT_LIST_HEAD(&local->interfaces);
@@ -719,13 +693,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 	mutex_init(&local->scan_mtx);
 
 	spin_lock_init(&local->key_lock);
-
+	spin_lock_init(&local->filter_lock);
 	spin_lock_init(&local->queue_stop_reason_lock);
 
 	INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
 
 	INIT_WORK(&local->restart_work, ieee80211_restart_work);
 
+	INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
+
 	INIT_WORK(&local->dynamic_ps_enable_work,
 		  ieee80211_dynamic_ps_enable_work);
 	INIT_WORK(&local->dynamic_ps_disable_work,
@@ -739,12 +715,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 		skb_queue_head_init(&local->pending[i]);
 	tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
 		     (unsigned long)local);
-	tasklet_disable(&local->tx_pending_tasklet);
 
 	tasklet_init(&local->tasklet,
 		     ieee80211_tasklet_handler,
 		     (unsigned long) local);
-	tasklet_disable(&local->tasklet);
 
 	skb_queue_head_init(&local->skb_queue);
 	skb_queue_head_init(&local->skb_queue_unreliable);
@@ -755,30 +729,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 }
 EXPORT_SYMBOL(ieee80211_alloc_hw);
 
-static const struct net_device_ops ieee80211_master_ops = {
-	.ndo_start_xmit = ieee80211_master_start_xmit,
-	.ndo_open = ieee80211_master_open,
-	.ndo_stop = ieee80211_master_stop,
-	.ndo_set_multicast_list = ieee80211_master_set_multicast_list,
-	.ndo_select_queue = ieee80211_select_queue,
-};
-
-static void ieee80211_master_setup(struct net_device *mdev)
-{
-	mdev->type = ARPHRD_IEEE80211;
-	mdev->netdev_ops = &ieee80211_master_ops;
-	mdev->header_ops = &ieee80211_header_ops;
-	mdev->tx_queue_len = 1000;
-	mdev->addr_len = ETH_ALEN;
-}
-
 int ieee80211_register_hw(struct ieee80211_hw *hw)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	int result;
 	enum ieee80211_band band;
-	struct net_device *mdev;
-	struct ieee80211_master_priv *mpriv;
 	int channels, i, j, max_bitrates;
 	bool supp_ht;
 	static const u32 cipher_suites[] = {
@@ -818,9 +773,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		supp_ht = supp_ht || sband->ht_cap.ht_supported;
 	}
 
-	local->int_scan_req.n_channels = channels;
-	local->int_scan_req.channels = kzalloc(sizeof(void *) * channels, GFP_KERNEL);
-	if (!local->int_scan_req.channels)
+	local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
+				      sizeof(void *) * channels, GFP_KERNEL);
+	if (!local->int_scan_req)
 		return -ENOMEM;
 
 	/* if low-level driver supports AP, we also support VLAN */
@@ -877,19 +832,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	if (hw->queues > IEEE80211_MAX_QUEUES)
 		hw->queues = IEEE80211_MAX_QUEUES;
 
-	mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv),
-			       "wmaster%d", ieee80211_master_setup,
-			       hw->queues);
-	if (!mdev)
-		goto fail_mdev_alloc;
-
-	mpriv = netdev_priv(mdev);
-	mpriv->local = local;
-	local->mdev = mdev;
-
-	local->hw.workqueue =
+	local->workqueue =
 		create_singlethread_workqueue(wiphy_name(local->hw.wiphy));
-	if (!local->hw.workqueue) {
+	if (!local->workqueue) {
 		result = -ENOMEM;
 		goto fail_workqueue;
 	}
@@ -921,17 +866,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	}
 
 	rtnl_lock();
-	result = dev_alloc_name(local->mdev, local->mdev->name);
-	if (result < 0)
-		goto fail_dev;
-
-	memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
-	SET_NETDEV_DEV(local->mdev, wiphy_dev(local->hw.wiphy));
-	local->mdev->features |= NETIF_F_NETNS_LOCAL;
-
-	result = register_netdevice(local->mdev);
-	if (result < 0)
-		goto fail_dev;
 
 	result = ieee80211_init_rate_ctrl_alg(local,
 					      hw->rate_control_algorithm);
@@ -956,13 +890,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
 	/* alloc internal scan request */
 	i = 0;
-	local->int_scan_req.ssids = &local->scan_ssid;
-	local->int_scan_req.n_ssids = 1;
+	local->int_scan_req->ssids = &local->scan_ssid;
+	local->int_scan_req->n_ssids = 1;
 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 		if (!hw->wiphy->bands[band])
 			continue;
 		for (j = 0; j < hw->wiphy->bands[band]->n_channels; j++) {
-			local->int_scan_req.channels[i] =
+			local->int_scan_req->channels[i] =
 				&hw->wiphy->bands[band]->channels[j];
 			i++;
 		}
@@ -984,23 +918,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 	ieee80211_led_exit(local);
 	ieee80211_remove_interfaces(local);
  fail_rate:
-	unregister_netdevice(local->mdev);
-	local->mdev = NULL;
- fail_dev:
 	rtnl_unlock();
 	ieee80211_wep_free(local);
  fail_wep:
 	sta_info_stop(local);
  fail_sta_info:
 	debugfs_hw_del(local);
-	destroy_workqueue(local->hw.workqueue);
+	destroy_workqueue(local->workqueue);
  fail_workqueue:
-	if (local->mdev)
-		free_netdev(local->mdev);
- fail_mdev_alloc:
 	wiphy_unregister(local->hw.wiphy);
  fail_wiphy_register:
-	kfree(local->int_scan_req.channels);
+	kfree(local->int_scan_req);
 	return result;
 }
 EXPORT_SYMBOL(ieee80211_register_hw);
@@ -1022,15 +950,12 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 	 * because the driver cannot be handing us frames any
 	 * more and the tasklet is killed.
 	 */
-
-	/* First, we remove all virtual interfaces. */
 	ieee80211_remove_interfaces(local);
 
-	/* then, finally, remove the master interface */
-	unregister_netdevice(local->mdev);
-
 	rtnl_unlock();
 
+	cancel_work_sync(&local->reconfig_filter);
+
 	ieee80211_clear_tx_pending(local);
 	sta_info_stop(local);
 	rate_control_deinitialize(local);
@@ -1043,12 +968,11 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
 	skb_queue_purge(&local->skb_queue);
 	skb_queue_purge(&local->skb_queue_unreliable);
 
-	destroy_workqueue(local->hw.workqueue);
+	destroy_workqueue(local->workqueue);
 	wiphy_unregister(local->hw.wiphy);
 	ieee80211_wep_free(local);
 	ieee80211_led_exit(local);
-	free_netdev(local->mdev);
-	kfree(local->int_scan_req.channels);
+	kfree(local->int_scan_req);
 }
 EXPORT_SYMBOL(ieee80211_unregister_hw);
 
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 11cf45b..f7364e5 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -18,8 +18,11 @@
 #define PP_OFFSET 	1		/* Path Selection Protocol */
 #define PM_OFFSET	5		/* Path Selection Metric   */
 #define CC_OFFSET	9		/* Congestion Control Mode */
-#define CAPAB_OFFSET 17
-#define ACCEPT_PLINKS 0x80
+#define SP_OFFSET	13		/* Synchronization Protocol */
+#define AUTH_OFFSET	17		/* Authentication Protocol */
+#define CAPAB_OFFSET 	22
+#define CAPAB_ACCEPT_PLINKS 0x80
+#define CAPAB_FORWARDING    0x10
 
 #define TMR_RUNNING_HK	0
 #define TMR_RUNNING_MP	1
@@ -47,14 +50,14 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 
-	ifmsh->housekeeping = true;
+	ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING;
 
 	if (local->quiescing) {
 		set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
 		return;
 	}
 
-	queue_work(local->hw.workqueue, &ifmsh->work);
+	ieee80211_queue_work(&local->hw, &ifmsh->work);
 }
 
 /**
@@ -84,7 +87,9 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat
 		memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 &&
 		memcmp(ifmsh->mesh_pp_id, ie->mesh_config + PP_OFFSET, 4) == 0 &&
 		memcmp(ifmsh->mesh_pm_id, ie->mesh_config + PM_OFFSET, 4) == 0 &&
-		memcmp(ifmsh->mesh_cc_id, ie->mesh_config + CC_OFFSET, 4) == 0)
+		memcmp(ifmsh->mesh_cc_id, ie->mesh_config + CC_OFFSET, 4) == 0 &&
+		memcmp(ifmsh->mesh_sp_id, ie->mesh_config + SP_OFFSET, 4) == 0 &&
+		memcmp(ifmsh->mesh_auth_id, ie->mesh_config + AUTH_OFFSET, 4) == 0)
 		return true;
 
 	return false;
@@ -97,7 +102,7 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_dat
  */
 bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
 {
-	return (*(ie->mesh_config + CAPAB_OFFSET) & ACCEPT_PLINKS) != 0;
+	return (*(ie->mesh_config + CAPAB_OFFSET) & CAPAB_ACCEPT_PLINKS) != 0;
 }
 
 /**
@@ -123,11 +128,18 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
 
 void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
 {
-	u8 def_id[4] = {0x00, 0x0F, 0xAC, 0xff};
-
-	memcpy(sta->mesh_pp_id, def_id, 4);
-	memcpy(sta->mesh_pm_id, def_id, 4);
-	memcpy(sta->mesh_cc_id, def_id, 4);
+	u8 oui[3] = {0x00, 0x0F, 0xAC};
+
+	memcpy(sta->mesh_pp_id, oui, sizeof(oui));
+	memcpy(sta->mesh_pm_id, oui, sizeof(oui));
+	memcpy(sta->mesh_cc_id, oui, sizeof(oui));
+	memcpy(sta->mesh_sp_id, oui, sizeof(oui));
+	memcpy(sta->mesh_auth_id, oui, sizeof(oui));
+	sta->mesh_pp_id[sizeof(oui)] = 0;
+	sta->mesh_pm_id[sizeof(oui)] = 0;
+	sta->mesh_cc_id[sizeof(oui)] = 0xff;
+	sta->mesh_sp_id[sizeof(oui)] = 0xff;
+	sta->mesh_auth_id[sizeof(oui)] = 0x0;
 }
 
 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
@@ -245,7 +257,7 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
 	if (sdata->u.mesh.mesh_id_len)
 		memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len);
 
-	pos = skb_put(skb, 21);
+	pos = skb_put(skb, 2 + IEEE80211_MESH_CONFIG_LEN);
 	*pos++ = WLAN_EID_MESH_CONFIG;
 	*pos++ = IEEE80211_MESH_CONFIG_LEN;
 	/* Version */
@@ -263,15 +275,22 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
 	memcpy(pos, sdata->u.mesh.mesh_cc_id, 4);
 	pos += 4;
 
-	/* Channel precedence:
-	 * Not running simple channel unification protocol
-	 */
-	memset(pos, 0x00, 4);
+	/* Synchronization protocol identifier */
+	memcpy(pos, sdata->u.mesh.mesh_sp_id, 4);
 	pos += 4;
 
+	/* Authentication Protocol identifier */
+	memcpy(pos, sdata->u.mesh.mesh_auth_id, 4);
+	pos += 4;
+
+	/* Mesh Formation Info */
+	memset(pos, 0x00, 1);
+	pos += 1;
+
 	/* Mesh capability */
 	sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata);
-	*pos++ = sdata->u.mesh.accepting_plinks ? ACCEPT_PLINKS : 0x00;
+	*pos = CAPAB_FORWARDING;
+	*pos++ |= sdata->u.mesh.accepting_plinks ? CAPAB_ACCEPT_PLINKS : 0x00;
 	*pos++ = 0x00;
 
 	return;
@@ -320,30 +339,6 @@ struct mesh_table *mesh_table_alloc(int size_order)
 	return newtbl;
 }
 
-static void __mesh_table_free(struct mesh_table *tbl)
-{
-	kfree(tbl->hash_buckets);
-	kfree(tbl->hashwlock);
-	kfree(tbl);
-}
-
-void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
-{
-	struct hlist_head *mesh_hash;
-	struct hlist_node *p, *q;
-	int i;
-
-	mesh_hash = tbl->hash_buckets;
-	for (i = 0; i <= tbl->hash_mask; i++) {
-		spin_lock(&tbl->hashwlock[i]);
-		hlist_for_each_safe(p, q, &mesh_hash[i]) {
-			tbl->free_node(p, free_leafs);
-			atomic_dec(&tbl->entries);
-		}
-		spin_unlock(&tbl->hashwlock[i]);
-	}
-	__mesh_table_free(tbl);
-}
 
 static void ieee80211_mesh_path_timer(unsigned long data)
 {
@@ -357,63 +352,79 @@ static void ieee80211_mesh_path_timer(unsigned long data)
 		return;
 	}
 
-	queue_work(local->hw.workqueue, &ifmsh->work);
+	ieee80211_queue_work(&local->hw, &ifmsh->work);
 }
 
-struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
-{
-	struct mesh_table *newtbl;
-	struct hlist_head *oldhash;
-	struct hlist_node *p, *q;
-	int i;
-
-	if (atomic_read(&tbl->entries)
-			< tbl->mean_chain_len * (tbl->hash_mask + 1))
-		goto endgrow;
-
-	newtbl = mesh_table_alloc(tbl->size_order + 1);
-	if (!newtbl)
-		goto endgrow;
-
-	newtbl->free_node = tbl->free_node;
-	newtbl->mean_chain_len = tbl->mean_chain_len;
-	newtbl->copy_node = tbl->copy_node;
-	atomic_set(&newtbl->entries, atomic_read(&tbl->entries));
-
-	oldhash = tbl->hash_buckets;
-	for (i = 0; i <= tbl->hash_mask; i++)
-		hlist_for_each(p, &oldhash[i])
-			if (tbl->copy_node(p, newtbl) < 0)
-				goto errcopy;
-
-	return newtbl;
-
-errcopy:
-	for (i = 0; i <= newtbl->hash_mask; i++) {
-		hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
-			tbl->free_node(p, 0);
+/**
+ * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame
+ * @hdr:    	802.11 frame header
+ * @fc:		frame control field
+ * @meshda:	destination address in the mesh
+ * @meshsa:	source address address in the mesh.  Same as TA, as frame is
+ *              locally originated.
+ *
+ * Return the length of the 802.11 (does not include a mesh control header)
+ */
+int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, char
+		*meshda, char *meshsa) {
+	if (is_multicast_ether_addr(meshda)) {
+		*fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
+		/* DA TA SA */
+		memcpy(hdr->addr1, meshda, ETH_ALEN);
+		memcpy(hdr->addr2, meshsa, ETH_ALEN);
+		memcpy(hdr->addr3, meshsa, ETH_ALEN);
+		return 24;
+	} else {
+		*fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS |
+				IEEE80211_FCTL_TODS);
+		/* RA TA DA SA */
+		memset(hdr->addr1, 0, ETH_ALEN);   /* RA is resolved later */
+		memcpy(hdr->addr2, meshsa, ETH_ALEN);
+		memcpy(hdr->addr3, meshda, ETH_ALEN);
+		memcpy(hdr->addr4, meshsa, ETH_ALEN);
+		return 30;
 	}
-	__mesh_table_free(newtbl);
-endgrow:
-	return NULL;
 }
 
 /**
  * ieee80211_new_mesh_header - create a new mesh header
  * @meshhdr:    uninitialized mesh header
  * @sdata:	mesh interface to be used
+ * @addr4:	addr4 of the mesh frame (1st in ae header)
+ *              may be NULL
+ * @addr5:	addr5 of the mesh frame (1st or 2nd in ae header)
+ *              may be NULL unless addr6 is present
+ * @addr6:	addr6 of the mesh frame (2nd or 3rd in ae header)
+ * 		may be NULL unless addr5 is present
  *
  * Return the header length.
  */
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata)
+		struct ieee80211_sub_if_data *sdata, char *addr4,
+		char *addr5, char *addr6)
 {
-	meshhdr->flags = 0;
+	int aelen = 0;
+	memset(meshhdr, 0, sizeof(meshhdr));
 	meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
 	put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
 	sdata->u.mesh.mesh_seqnum++;
-
-	return 6;
+	if (addr4) {
+		meshhdr->flags |= MESH_FLAGS_AE_A4;
+		aelen += ETH_ALEN;
+		memcpy(meshhdr->eaddr1, addr4, ETH_ALEN);
+	}
+	if (addr5 && addr6) {
+		meshhdr->flags |= MESH_FLAGS_AE_A5_A6;
+		aelen += 2 * ETH_ALEN;
+		if (!addr4) {
+			memcpy(meshhdr->eaddr1, addr5, ETH_ALEN);
+			memcpy(meshhdr->eaddr2, addr6, ETH_ALEN);
+		} else {
+			memcpy(meshhdr->eaddr2, addr5, ETH_ALEN);
+			memcpy(meshhdr->eaddr3, addr6, ETH_ALEN);
+		}
+	}
+	return 6 + aelen;
 }
 
 static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
@@ -433,7 +444,6 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
 	if (free_plinks != sdata->u.mesh.accepting_plinks)
 		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
 
-	ifmsh->housekeeping = false;
 	mod_timer(&ifmsh->housekeeping_timer,
 		  round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
 }
@@ -470,10 +480,12 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 	struct ieee80211_local *local = sdata->local;
 
-	ifmsh->housekeeping = true;
-	queue_work(local->hw.workqueue, &ifmsh->work);
+	ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING;
+	ieee80211_queue_work(&local->hw, &ifmsh->work);
+	sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
 	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
-						BSS_CHANGED_BEACON_ENABLED);
+						BSS_CHANGED_BEACON_ENABLED |
+						BSS_CHANGED_BEACON_INT);
 }
 
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
@@ -568,7 +580,7 @@ static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 
 	ifmsh = &sdata->u.mesh;
 
-	rx_status = (struct ieee80211_rx_status *) skb->cb;
+	rx_status = IEEE80211_SKB_RXCB(skb);
 	mgmt = (struct ieee80211_mgmt *) skb->data;
 	stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
 
@@ -597,7 +609,7 @@ static void ieee80211_mesh_work(struct work_struct *work)
 	if (!netif_running(sdata->dev))
 		return;
 
-	if (local->sw_scanning || local->hw_scanning)
+	if (local->scanning)
 		return;
 
 	while ((skb = skb_dequeue(&ifmsh->skb_queue)))
@@ -608,7 +620,13 @@ static void ieee80211_mesh_work(struct work_struct *work)
 		       ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval)))
 		mesh_path_start_discovery(sdata);
 
-	if (ifmsh->housekeeping)
+	if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags))
+		mesh_mpath_table_grow();
+
+	if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags))
+		mesh_mpp_table_grow();
+
+	if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags))
 		ieee80211_mesh_housekeeping(sdata, ifmsh);
 }
 
@@ -619,7 +637,7 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
 	rcu_read_lock();
 	list_for_each_entry_rcu(sdata, &local->interfaces, list)
 		if (ieee80211_vif_is_mesh(&sdata->vif))
-			queue_work(local->hw.workqueue, &sdata->u.mesh.work);
+			ieee80211_queue_work(&local->hw, &sdata->u.mesh.work);
 	rcu_read_unlock();
 }
 
@@ -671,8 +689,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
 }
 
 ieee80211_rx_result
-ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-		       struct ieee80211_rx_status *rx_status)
+ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -686,12 +703,14 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
 	fc = le16_to_cpu(mgmt->frame_control);
 
 	switch (fc & IEEE80211_FCTL_STYPE) {
+	case IEEE80211_STYPE_ACTION:
+		if (skb->len < IEEE80211_MIN_ACTION_SIZE)
+			return RX_DROP_MONITOR;
+		/* fall through */
 	case IEEE80211_STYPE_PROBE_RESP:
 	case IEEE80211_STYPE_BEACON:
-	case IEEE80211_STYPE_ACTION:
-		memcpy(skb->cb, rx_status, sizeof(*rx_status));
 		skb_queue_tail(&ifmsh->skb_queue, skb);
-		queue_work(local->hw.workqueue, &ifmsh->work);
+		ieee80211_queue_work(&local->hw, &ifmsh->work);
 		return RX_QUEUED;
 	}
 
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index c7d7281..dd1c193 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -44,6 +44,23 @@ enum mesh_path_flags {
 };
 
 /**
+ * enum mesh_deferred_task_flags - mac80211 mesh deferred tasks
+ *
+ *
+ *
+ * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks
+ * @MESH_WORK_GROW_MPATH_TABLE: the mesh path table is full and needs
+ * to grow.
+ * @MESH_WORK_GROW_MPP_TABLE: the mesh portals table is full and needs to
+ * grow
+ */
+enum mesh_deferred_task_flags {
+	MESH_WORK_HOUSEKEEPING,
+	MESH_WORK_GROW_MPATH_TABLE,
+	MESH_WORK_GROW_MPP_TABLE,
+};
+
+/**
  * struct mesh_path - mac80211 mesh path structure
  *
  * @dst: mesh path destination mac address
@@ -61,7 +78,7 @@ enum mesh_path_flags {
  * 	retry
  * @discovery_retries: number of discovery retries
  * @flags: mesh path flags, as specified on &enum mesh_path_flags
- * @state_lock: mesh pat state lock
+ * @state_lock: mesh path state lock
  *
  *
  * The combination of dst and sdata is unique in the mesh path table. Since the
@@ -174,6 +191,7 @@ struct mesh_rmc {
  */
 #define MESH_PATH_REFRESH_TIME			1000
 #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
+#define MESH_DEFAULT_BEACON_INTERVAL		1000 	/* in 1024 us units */
 
 #define MESH_MAX_PREQ_RETRIES 4
 #define MESH_PATH_EXPIRE (600 * HZ)
@@ -193,8 +211,11 @@ struct mesh_rmc {
 
 /* Public interfaces */
 /* Various */
+int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
+		char *da, char *sa);
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
-		struct ieee80211_sub_if_data *sdata);
+		struct ieee80211_sub_if_data *sdata, char *addr4,
+		char *addr5, char *addr6);
 int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
 		struct ieee80211_sub_if_data *sdata);
 bool mesh_matches_local(struct ieee802_11_elems *ie,
@@ -205,11 +226,12 @@ void mesh_mgmt_ies_add(struct sk_buff *skb,
 void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
 int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
 void ieee80211s_init(void);
+void ieee80211s_update_metric(struct ieee80211_local *local,
+		struct sta_info *stainfo, struct sk_buff *skb);
 void ieee80211s_stop(void);
 void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result
-ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-		       struct ieee80211_rx_status *rx_status);
+ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb);
 void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
 
@@ -247,7 +269,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
 /* Mesh tables */
 struct mesh_table *mesh_table_alloc(int size_order);
 void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
-struct mesh_table *mesh_table_grow(struct mesh_table *tbl);
+void mesh_mpath_table_grow(void);
+void mesh_mpp_table_grow(void);
 u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
 		struct mesh_table *tbl);
 /* Mesh paths */
@@ -266,6 +289,8 @@ void mesh_path_discard_frame(struct sk_buff *skb,
 void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
 void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
 
+extern int mesh_paths_generation;
+
 #ifdef CONFIG_MAC80211_MESH
 extern int mesh_allocated;
 
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index f49ef28..e12a786 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -201,6 +201,24 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
 	return 0;
 }
 
+void ieee80211s_update_metric(struct ieee80211_local *local,
+		struct sta_info *stainfo, struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	int failed;
+
+	if (!ieee80211_is_data(hdr->frame_control))
+		return;
+
+	failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
+
+	/* moving average, scaled to 100 */
+	stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed);
+	if (stainfo->fail_avg > 95)
+		mesh_plink_broken(stainfo);
+}
+
 static u32 airtime_link_metric_get(struct ieee80211_local *local,
 				   struct sta_info *sta)
 {
@@ -397,7 +415,8 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
 
 static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 				    struct ieee80211_mgmt *mgmt,
-				    u8 *preq_elem, u32 metric) {
+				    u8 *preq_elem, u32 metric)
+{
 	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 	struct mesh_path *mpath;
 	u8 *dst_addr, *orig_addr;
@@ -430,7 +449,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 			if ((!(mpath->flags & MESH_PATH_DSN_VALID)) ||
 					DSN_LT(mpath->dsn, dst_dsn)) {
 				mpath->dsn = dst_dsn;
-				mpath->flags &= MESH_PATH_DSN_VALID;
+				mpath->flags |= MESH_PATH_DSN_VALID;
 			} else if ((!(dst_flags & MP_F_DO)) &&
 					(mpath->flags & MESH_PATH_ACTIVE)) {
 				reply = true;
@@ -478,6 +497,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
 				hopcount, ttl, cpu_to_le32(lifetime),
 				cpu_to_le32(metric), cpu_to_le32(preq_id),
 				sdata);
+		ifmsh->mshstats.fwded_mcast++;
 		ifmsh->mshstats.fwded_frames++;
 	}
 }
@@ -536,6 +556,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
 		cpu_to_le32(lifetime), cpu_to_le32(metric),
 		0, sdata);
 	rcu_read_unlock();
+
+	sdata->u.mesh.mshstats.fwded_unicast++;
 	sdata->u.mesh.mshstats.fwded_frames++;
 	return;
 
@@ -660,14 +682,14 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
 	spin_unlock(&ifmsh->mesh_preq_queue_lock);
 
 	if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
-		queue_work(sdata->local->hw.workqueue, &ifmsh->work);
+		ieee80211_queue_work(&sdata->local->hw, &ifmsh->work);
 
 	else if (time_before(jiffies, ifmsh->last_preq)) {
 		/* avoid long wait if did not send preqs for a long time
 		 * and jiffies wrapped around
 		 */
 		ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
-		queue_work(sdata->local->hw.workqueue, &ifmsh->work);
+		ieee80211_queue_work(&sdata->local->hw, &ifmsh->work);
 	} else
 		mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
 						min_preq_int_jiff(sdata));
@@ -686,11 +708,11 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
 	u8 ttl, dst_flags;
 	u32 lifetime;
 
-	spin_lock(&ifmsh->mesh_preq_queue_lock);
+	spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
 	if (!ifmsh->preq_queue_len ||
 		time_before(jiffies, ifmsh->last_preq +
 				min_preq_int_jiff(sdata))) {
-		spin_unlock(&ifmsh->mesh_preq_queue_lock);
+		spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
 		return;
 	}
 
@@ -698,7 +720,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
 			struct mesh_preq_queue, list);
 	list_del(&preq_node->list);
 	--ifmsh->preq_queue_len;
-	spin_unlock(&ifmsh->mesh_preq_queue_lock);
+	spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
 
 	rcu_read_lock();
 	mpath = mesh_path_lookup(preq_node->dst, sdata);
@@ -784,7 +806,6 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 		mesh_path_add(dst_addr, sdata);
 		mpath = mesh_path_lookup(dst_addr, sdata);
 		if (!mpath) {
-			dev_kfree_skb(skb);
 			sdata->u.mesh.mshstats.dropped_frames_no_route++;
 			err = -ENOSPC;
 			goto endlookup;
@@ -792,7 +813,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 	}
 
 	if (mpath->flags & MESH_PATH_ACTIVE) {
-		if (time_after(jiffies, mpath->exp_time -
+		if (time_after(jiffies, mpath->exp_time +
 			msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time))
 				&& !memcmp(sdata->dev->dev_addr, hdr->addr4,
 					   ETH_ALEN)
@@ -804,17 +825,17 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 		memcpy(hdr->addr1, mpath->next_hop->sta.addr,
 				ETH_ALEN);
 	} else {
+		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 		if (!(mpath->flags & MESH_PATH_RESOLVING)) {
 			/* Start discovery only if it is not running yet */
 			mesh_queue_preq(mpath, PREQ_Q_F_START);
 		}
 
 		if (skb_queue_len(&mpath->frame_queue) >=
-				MESH_FRAME_QUEUE_LEN) {
-			skb_to_free = mpath->frame_queue.next;
-			skb_unlink(skb_to_free, &mpath->frame_queue);
-		}
+				MESH_FRAME_QUEUE_LEN)
+			skb_to_free = skb_dequeue(&mpath->frame_queue);
 
+		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 		skb_queue_tail(&mpath->frame_queue, skb);
 		if (skb_to_free)
 			mesh_path_discard_frame(skb_to_free, sdata);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 479597e..751c4d0 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -38,6 +38,71 @@ struct mpath_node {
 static struct mesh_table *mesh_paths;
 static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
 
+int mesh_paths_generation;
+static void __mesh_table_free(struct mesh_table *tbl)
+{
+	kfree(tbl->hash_buckets);
+	kfree(tbl->hashwlock);
+	kfree(tbl);
+}
+
+void mesh_table_free(struct mesh_table *tbl, bool free_leafs)
+{
+	struct hlist_head *mesh_hash;
+	struct hlist_node *p, *q;
+	int i;
+
+	mesh_hash = tbl->hash_buckets;
+	for (i = 0; i <= tbl->hash_mask; i++) {
+		spin_lock(&tbl->hashwlock[i]);
+		hlist_for_each_safe(p, q, &mesh_hash[i]) {
+			tbl->free_node(p, free_leafs);
+			atomic_dec(&tbl->entries);
+		}
+		spin_unlock(&tbl->hashwlock[i]);
+	}
+	__mesh_table_free(tbl);
+}
+
+static struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
+{
+	struct mesh_table *newtbl;
+	struct hlist_head *oldhash;
+	struct hlist_node *p, *q;
+	int i;
+
+	if (atomic_read(&tbl->entries)
+			< tbl->mean_chain_len * (tbl->hash_mask + 1))
+		goto endgrow;
+
+	newtbl = mesh_table_alloc(tbl->size_order + 1);
+	if (!newtbl)
+		goto endgrow;
+
+	newtbl->free_node = tbl->free_node;
+	newtbl->mean_chain_len = tbl->mean_chain_len;
+	newtbl->copy_node = tbl->copy_node;
+	atomic_set(&newtbl->entries, atomic_read(&tbl->entries));
+
+	oldhash = tbl->hash_buckets;
+	for (i = 0; i <= tbl->hash_mask; i++)
+		hlist_for_each(p, &oldhash[i])
+			if (tbl->copy_node(p, newtbl) < 0)
+				goto errcopy;
+
+	return newtbl;
+
+errcopy:
+	for (i = 0; i <= newtbl->hash_mask; i++) {
+		hlist_for_each_safe(p, q, &newtbl->hash_buckets[i])
+			tbl->free_node(p, 0);
+	}
+	__mesh_table_free(newtbl);
+endgrow:
+	return NULL;
+}
+
+
 /* This lock will have the grow table function as writer and add / delete nodes
  * as readers. When reading the table (i.e. doing lookups) we are well protected
  * by RCU
@@ -55,7 +120,25 @@ static DEFINE_RWLOCK(pathtbl_resize_lock);
  */
 void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
 {
+	struct sk_buff *skb;
+	struct ieee80211_hdr *hdr;
+	struct sk_buff_head tmpq;
+	unsigned long flags;
+
 	rcu_assign_pointer(mpath->next_hop, sta);
+
+	__skb_queue_head_init(&tmpq);
+
+	spin_lock_irqsave(&mpath->frame_queue.lock, flags);
+
+	while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) {
+		hdr = (struct ieee80211_hdr *) skb->data;
+		memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
+		__skb_queue_tail(&tmpq, skb);
+	}
+
+	skb_queue_splice(&tmpq, &mpath->frame_queue);
+	spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
 }
 
 
@@ -167,6 +250,8 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data
  */
 int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
 {
+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+	struct ieee80211_local *local = sdata->local;
 	struct mesh_path *mpath, *new_mpath;
 	struct mpath_node *node, *new_node;
 	struct hlist_head *bucket;
@@ -175,8 +260,6 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
 	int err = 0;
 	u32 hash_idx;
 
-	might_sleep();
-
 	if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0)
 		/* never add ourselves as neighbours */
 		return -ENOTSUPP;
@@ -188,11 +271,11 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
 		return -ENOSPC;
 
 	err = -ENOMEM;
-	new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
+	new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC);
 	if (!new_mpath)
 		goto err_path_alloc;
 
-	new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
+	new_node = kmalloc(sizeof(struct mpath_node), GFP_ATOMIC);
 	if (!new_node)
 		goto err_node_alloc;
 
@@ -225,23 +308,13 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
 		mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1))
 		grow = 1;
 
+	mesh_paths_generation++;
+
 	spin_unlock(&mesh_paths->hashwlock[hash_idx]);
 	read_unlock(&pathtbl_resize_lock);
 	if (grow) {
-		struct mesh_table *oldtbl, *newtbl;
-
-		write_lock(&pathtbl_resize_lock);
-		oldtbl = mesh_paths;
-		newtbl = mesh_table_grow(mesh_paths);
-		if (!newtbl) {
-			write_unlock(&pathtbl_resize_lock);
-			return 0;
-		}
-		rcu_assign_pointer(mesh_paths, newtbl);
-		write_unlock(&pathtbl_resize_lock);
-
-		synchronize_rcu();
-		mesh_table_free(oldtbl, false);
+		set_bit(MESH_WORK_GROW_MPATH_TABLE,  &ifmsh->wrkq_flags);
+		ieee80211_queue_work(&local->hw, &ifmsh->work);
 	}
 	return 0;
 
@@ -256,9 +329,46 @@ err_path_alloc:
 	return err;
 }
 
+void mesh_mpath_table_grow(void)
+{
+	struct mesh_table *oldtbl, *newtbl;
+
+	write_lock(&pathtbl_resize_lock);
+	oldtbl = mesh_paths;
+	newtbl = mesh_table_grow(mesh_paths);
+	if (!newtbl) {
+		write_unlock(&pathtbl_resize_lock);
+		return;
+	}
+	rcu_assign_pointer(mesh_paths, newtbl);
+	write_unlock(&pathtbl_resize_lock);
+
+	synchronize_rcu();
+	mesh_table_free(oldtbl, false);
+}
+
+void mesh_mpp_table_grow(void)
+{
+	struct mesh_table *oldtbl, *newtbl;
+
+	write_lock(&pathtbl_resize_lock);
+	oldtbl = mpp_paths;
+	newtbl = mesh_table_grow(mpp_paths);
+	if (!newtbl) {
+		write_unlock(&pathtbl_resize_lock);
+		return;
+	}
+	rcu_assign_pointer(mpp_paths, newtbl);
+	write_unlock(&pathtbl_resize_lock);
+
+	synchronize_rcu();
+	mesh_table_free(oldtbl, false);
+}
 
 int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
 {
+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+	struct ieee80211_local *local = sdata->local;
 	struct mesh_path *mpath, *new_mpath;
 	struct mpath_node *node, *new_node;
 	struct hlist_head *bucket;
@@ -267,8 +377,6 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
 	int err = 0;
 	u32 hash_idx;
 
-	might_sleep();
-
 	if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0)
 		/* never add ourselves as neighbours */
 		return -ENOTSUPP;
@@ -277,11 +385,11 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
 		return -ENOTSUPP;
 
 	err = -ENOMEM;
-	new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
+	new_mpath = kzalloc(sizeof(struct mesh_path), GFP_ATOMIC);
 	if (!new_mpath)
 		goto err_path_alloc;
 
-	new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
+	new_node = kmalloc(sizeof(struct mpath_node), GFP_ATOMIC);
 	if (!new_node)
 		goto err_node_alloc;
 
@@ -315,20 +423,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
 	spin_unlock(&mpp_paths->hashwlock[hash_idx]);
 	read_unlock(&pathtbl_resize_lock);
 	if (grow) {
-		struct mesh_table *oldtbl, *newtbl;
-
-		write_lock(&pathtbl_resize_lock);
-		oldtbl = mpp_paths;
-		newtbl = mesh_table_grow(mpp_paths);
-		if (!newtbl) {
-			write_unlock(&pathtbl_resize_lock);
-			return 0;
-		}
-		rcu_assign_pointer(mpp_paths, newtbl);
-		write_unlock(&pathtbl_resize_lock);
-
-		synchronize_rcu();
-		mesh_table_free(oldtbl, false);
+		set_bit(MESH_WORK_GROW_MPP_TABLE,  &ifmsh->wrkq_flags);
+		ieee80211_queue_work(&local->hw, &ifmsh->work);
 	}
 	return 0;
 
@@ -466,6 +562,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
 
 	err = -ENXIO;
 enddel:
+	mesh_paths_generation++;
 	spin_unlock(&mesh_paths->hashwlock[hash_idx]);
 	read_unlock(&pathtbl_resize_lock);
 	return err;
@@ -481,11 +578,9 @@ enddel:
  */
 void mesh_path_tx_pending(struct mesh_path *mpath)
 {
-	struct sk_buff *skb;
-
-	while ((skb = skb_dequeue(&mpath->frame_queue)) &&
-			(mpath->flags & MESH_PATH_ACTIVE))
-		dev_queue_xmit(skb);
+	if (mpath->flags & MESH_PATH_ACTIVE)
+		ieee80211_add_pending_skbs(mpath->sdata->local,
+				&mpath->frame_queue);
 }
 
 /**
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index cb14253..ffcbad7 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -409,7 +409,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
 	baselen = (u8 *) mgmt->u.action.u.plink_action.variable - (u8 *) mgmt;
 	if (mgmt->u.action.u.plink_action.action_code == PLINK_CONFIRM) {
 		baseaddr += 4;
-		baselen -= 4;
+		baselen += 4;
 	}
 	ieee802_11_parse_elems(baseaddr, len - baselen, &elems);
 	if (!elems.peer_link) {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 07e7e41..97a278a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -27,43 +27,99 @@
 #include "rate.h"
 #include "led.h"
 
-#define IEEE80211_ASSOC_SCANS_MAX_TRIES 2
 #define IEEE80211_AUTH_TIMEOUT (HZ / 5)
 #define IEEE80211_AUTH_MAX_TRIES 3
 #define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
 #define IEEE80211_ASSOC_MAX_TRIES 3
-#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
-#define IEEE80211_PROBE_WAIT (HZ / 5)
-#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
-#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
+#define IEEE80211_MAX_PROBE_TRIES 5
+
+/*
+ * beacon loss detection timeout
+ * XXX: should depend on beacon interval
+ */
+#define IEEE80211_BEACON_LOSS_TIME	(2 * HZ)
+/*
+ * Time the connection can be idle before we probe
+ * it to see if we can still talk to the AP.
+ */
+#define IEEE80211_CONNECTION_IDLE_TIME	(30 * HZ)
+/*
+ * Time we wait for a probe response after sending
+ * a probe request because of beacon loss or for
+ * checking the connection still works.
+ */
+#define IEEE80211_PROBE_WAIT		(HZ / 2)
 
 #define TMR_RUNNING_TIMER	0
 #define TMR_RUNNING_CHANSW	1
 
+/*
+ * All cfg80211 functions have to be called outside a locked
+ * section so that they can acquire a lock themselves... This
+ * is much simpler than queuing up things in cfg80211, but we
+ * do need some indirection for that here.
+ */
+enum rx_mgmt_action {
+	/* no action required */
+	RX_MGMT_NONE,
+
+	/* caller must call cfg80211_send_rx_auth() */
+	RX_MGMT_CFG80211_AUTH,
+
+	/* caller must call cfg80211_send_rx_assoc() */
+	RX_MGMT_CFG80211_ASSOC,
+
+	/* caller must call cfg80211_send_deauth() */
+	RX_MGMT_CFG80211_DEAUTH,
+
+	/* caller must call cfg80211_send_disassoc() */
+	RX_MGMT_CFG80211_DISASSOC,
+
+	/* caller must call cfg80211_auth_timeout() & free work */
+	RX_MGMT_CFG80211_AUTH_TO,
+
+	/* caller must call cfg80211_assoc_timeout() & free work */
+	RX_MGMT_CFG80211_ASSOC_TO,
+};
+
 /* utils */
-static int ecw2cw(int ecw)
+static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
 {
-	return (1 << ecw) - 1;
+	WARN_ON(!mutex_is_locked(&ifmgd->mtx));
 }
 
-static u8 *ieee80211_bss_get_ie(struct ieee80211_bss *bss, u8 ie)
+/*
+ * We can have multiple work items (and connection probing)
+ * scheduling this timer, but we need to take care to only
+ * reschedule it when it should fire _earlier_ than it was
+ * asked for before, or if it's not pending right now. This
+ * function ensures that. Note that it then is required to
+ * run this function for all timeouts after the first one
+ * has happened -- the work that runs from this timer will
+ * do that.
+ */
+static void run_again(struct ieee80211_if_managed *ifmgd,
+			     unsigned long timeout)
 {
-	u8 *end, *pos;
+	ASSERT_MGD_MTX(ifmgd);
 
-	pos = bss->cbss.information_elements;
-	if (pos == NULL)
-		return NULL;
-	end = pos + bss->cbss.len_information_elements;
+	if (!timer_pending(&ifmgd->timer) ||
+	    time_before(timeout, ifmgd->timer.expires))
+		mod_timer(&ifmgd->timer, timeout);
+}
 
-	while (pos + 1 < end) {
-		if (pos + 2 + pos[1] > end)
-			break;
-		if (pos[0] == ie)
-			return pos;
-		pos += 2 + pos[1];
-	}
+static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
+{
+	if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
+		return;
+
+	mod_timer(&sdata->u.mgd.bcn_mon_timer,
+		  round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
+}
 
-	return NULL;
+static int ecw2cw(int ecw)
+{
+	return (1 << ecw) - 1;
 }
 
 static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
@@ -94,11 +150,10 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
  */
 static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
 			       struct ieee80211_ht_info *hti,
-			       u16 ap_ht_cap_flags)
+			       const u8 *bssid, u16 ap_ht_cap_flags)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_supported_band *sband;
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct sta_info *sta;
 	u32 changed = 0;
 	u16 ht_opmode;
@@ -147,12 +202,10 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
 		ieee80211_hw_config(local, 0);
 
 		rcu_read_lock();
-
-		sta = sta_info_get(local, ifmgd->bssid);
+		sta = sta_info_get(local, bssid);
 		if (sta)
 			rate_control_rate_update(local, sband, sta,
 						 IEEE80211_RC_HT_CHANGED);
-
 		rcu_read_unlock();
         }
 
@@ -175,23 +228,24 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
 
 /* frame sending functions */
 
-static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
+static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
+				 struct ieee80211_mgd_work *wk)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
-	u8 *pos, *ies, *ht_ie;
+	u8 *pos;
+	const u8 *ies, *ht_ie;
 	int i, len, count, rates_len, supp_rates_len;
 	u16 capab;
-	struct ieee80211_bss *bss;
 	int wmm = 0;
 	struct ieee80211_supported_band *sband;
 	u32 rates = 0;
 
 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
-			    sizeof(*mgmt) + 200 + ifmgd->extra_ie_len +
-			    ifmgd->ssid_len);
+			    sizeof(*mgmt) + 200 + wk->ie_len +
+			    wk->ssid_len);
 	if (!skb) {
 		printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
 		       "frame\n", sdata->dev->name);
@@ -210,45 +264,35 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 			capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
 	}
 
-	bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
-				   local->hw.conf.channel->center_freq,
-				   ifmgd->ssid, ifmgd->ssid_len);
-	if (bss) {
-		if (bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
-			capab |= WLAN_CAPABILITY_PRIVACY;
-		if (bss->wmm_used)
-			wmm = 1;
+	if (wk->bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
+		capab |= WLAN_CAPABILITY_PRIVACY;
+	if (wk->bss->wmm_used)
+		wmm = 1;
 
-		/* get all rates supported by the device and the AP as
-		 * some APs don't like getting a superset of their rates
-		 * in the association request (e.g. D-Link DAP 1353 in
-		 * b-only mode) */
-		rates_len = ieee80211_compatible_rates(bss, sband, &rates);
+	/* get all rates supported by the device and the AP as
+	 * some APs don't like getting a superset of their rates
+	 * in the association request (e.g. D-Link DAP 1353 in
+	 * b-only mode) */
+	rates_len = ieee80211_compatible_rates(wk->bss, sband, &rates);
 
-		if ((bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
-		    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
-			capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
-
-		ieee80211_rx_bss_put(local, bss);
-	} else {
-		rates = ~0;
-		rates_len = sband->n_bitrates;
-	}
+	if ((wk->bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
+	    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
+		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
 
 	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
 	memset(mgmt, 0, 24);
-	memcpy(mgmt->da, ifmgd->bssid, ETH_ALEN);
+	memcpy(mgmt->da, wk->bss->cbss.bssid, ETH_ALEN);
 	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
-	memcpy(mgmt->bssid, ifmgd->bssid, ETH_ALEN);
+	memcpy(mgmt->bssid, wk->bss->cbss.bssid, ETH_ALEN);
 
-	if (ifmgd->flags & IEEE80211_STA_PREV_BSSID_SET) {
+	if (!is_zero_ether_addr(wk->prev_bssid)) {
 		skb_put(skb, 10);
 		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 						  IEEE80211_STYPE_REASSOC_REQ);
 		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
 		mgmt->u.reassoc_req.listen_interval =
 				cpu_to_le16(local->hw.conf.listen_interval);
-		memcpy(mgmt->u.reassoc_req.current_ap, ifmgd->prev_bssid,
+		memcpy(mgmt->u.reassoc_req.current_ap, wk->prev_bssid,
 		       ETH_ALEN);
 	} else {
 		skb_put(skb, 4);
@@ -260,10 +304,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 	}
 
 	/* SSID */
-	ies = pos = skb_put(skb, 2 + ifmgd->ssid_len);
+	ies = pos = skb_put(skb, 2 + wk->ssid_len);
 	*pos++ = WLAN_EID_SSID;
-	*pos++ = ifmgd->ssid_len;
-	memcpy(pos, ifmgd->ssid, ifmgd->ssid_len);
+	*pos++ = wk->ssid_len;
+	memcpy(pos, wk->ssid, wk->ssid_len);
 
 	/* add all rates which were marked to be used above */
 	supp_rates_len = rates_len;
@@ -318,9 +362,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 		}
 	}
 
-	if (ifmgd->extra_ie) {
-		pos = skb_put(skb, ifmgd->extra_ie_len);
-		memcpy(pos, ifmgd->extra_ie, ifmgd->extra_ie_len);
+	if (wk->ie_len && wk->ie) {
+		pos = skb_put(skb, wk->ie_len);
+		memcpy(pos, wk->ie, wk->ie_len);
 	}
 
 	if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) {
@@ -345,9 +389,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 	 */
 	if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
 	    sband->ht_cap.ht_supported &&
-	    (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) &&
+	    (ht_ie = ieee80211_bss_get_ie(&wk->bss->cbss, WLAN_EID_HT_INFORMATION)) &&
 	    ht_ie[1] >= sizeof(struct ieee80211_ht_info) &&
-	    (!(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED))) {
+	    (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) {
 		struct ieee80211_ht_info *ht_info =
 			(struct ieee80211_ht_info *)(ht_ie + 2);
 		u16 cap = sband->ht_cap.cap;
@@ -382,18 +426,13 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 		memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
 	}
 
-	kfree(ifmgd->assocreq_ies);
-	ifmgd->assocreq_ies_len = (skb->data + skb->len) - ies;
-	ifmgd->assocreq_ies = kmalloc(ifmgd->assocreq_ies_len, GFP_KERNEL);
-	if (ifmgd->assocreq_ies)
-		memcpy(ifmgd->assocreq_ies, ies, ifmgd->assocreq_ies_len);
-
 	ieee80211_tx_skb(sdata, skb, 0);
 }
 
 
 static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
-					   u16 stype, u16 reason)
+					   const u8 *bssid, u16 stype, u16 reason,
+					   void *cookie)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -410,18 +449,18 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
 
 	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
 	memset(mgmt, 0, 24);
-	memcpy(mgmt->da, ifmgd->bssid, ETH_ALEN);
+	memcpy(mgmt->da, bssid, ETH_ALEN);
 	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
-	memcpy(mgmt->bssid, ifmgd->bssid, ETH_ALEN);
+	memcpy(mgmt->bssid, bssid, ETH_ALEN);
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
 	skb_put(skb, 2);
 	/* u.deauth.reason_code == u.disassoc.reason_code */
 	mgmt->u.deauth.reason_code = cpu_to_le16(reason);
 
 	if (stype == IEEE80211_STYPE_DEAUTH)
-		cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
+		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, cookie);
 	else
-		cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
+		cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, cookie);
 	ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
 }
 
@@ -494,28 +533,26 @@ static void ieee80211_chswitch_work(struct work_struct *work)
 {
 	struct ieee80211_sub_if_data *sdata =
 		container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
-	struct ieee80211_bss *bss;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
 	if (!netif_running(sdata->dev))
 		return;
 
-	bss = ieee80211_rx_bss_get(sdata->local, ifmgd->bssid,
-				   sdata->local->hw.conf.channel->center_freq,
-				   ifmgd->ssid, ifmgd->ssid_len);
-	if (!bss)
-		goto exit;
+	mutex_lock(&ifmgd->mtx);
+	if (!ifmgd->associated)
+		goto out;
 
 	sdata->local->oper_channel = sdata->local->csa_channel;
+	ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL);
+
 	/* XXX: shouldn't really modify cfg80211-owned data! */
-	if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL))
-		bss->cbss.channel = sdata->local->oper_channel;
+	ifmgd->associated->cbss.channel = sdata->local->oper_channel;
 
-	ieee80211_rx_bss_put(sdata->local, bss);
-exit:
-	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
 	ieee80211_wake_queues_by_reason(&sdata->local->hw,
 					IEEE80211_QUEUE_STOP_REASON_CSA);
+ out:
+	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
+	mutex_unlock(&ifmgd->mtx);
 }
 
 static void ieee80211_chswitch_timer(unsigned long data)
@@ -529,7 +566,7 @@ static void ieee80211_chswitch_timer(unsigned long data)
 		return;
 	}
 
-	queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
+	ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
 }
 
 void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
@@ -540,10 +577,12 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
 
-	if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATED)
+	ASSERT_MGD_MTX(ifmgd);
+
+	if (!ifmgd->associated)
 		return;
 
-	if (sdata->local->sw_scanning || sdata->local->hw_scanning)
+	if (sdata->local->scanning)
 		return;
 
 	/* Disregard subsequent beacons if we are already running a timer
@@ -559,7 +598,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	sdata->local->csa_channel = new_ch;
 
 	if (sw_elem->count <= 1) {
-		queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
+		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
 	} else {
 		ieee80211_stop_queues_by_reason(&sdata->local->hw,
 					IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -601,7 +640,7 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
 	 * If we are scanning right now then the parameters will
 	 * take effect when scan finishes.
 	 */
-	if (local->hw_scanning || local->sw_scanning)
+	if (local->scanning)
 		return;
 
 	if (conf->dynamic_ps_timeout > 0 &&
@@ -651,8 +690,9 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
 	}
 
 	if (count == 1 && found->u.mgd.powersave &&
-	    (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) &&
-	    !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) {
+	    found->u.mgd.associated && list_empty(&found->u.mgd.work_list) &&
+	    !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
+				    IEEE80211_STA_CONNECTION_POLL))) {
 		s32 beaconint_us;
 
 		if (latency < 0)
@@ -724,7 +764,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data)
 	if (local->quiescing || local->suspended)
 		return;
 
-	queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
+	ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
 }
 
 /* MLME */
@@ -806,9 +846,6 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
 					   u16 capab, bool erp_valid, u8 erp)
 {
 	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-#endif
 	u32 changed = 0;
 	bool use_protection;
 	bool use_short_preamble;
@@ -825,42 +862,16 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
 	use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
 
 	if (use_protection != bss_conf->use_cts_prot) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "%s: CTS protection %s (BSSID=%pM)\n",
-			       sdata->dev->name,
-			       use_protection ? "enabled" : "disabled",
-			       ifmgd->bssid);
-		}
-#endif
 		bss_conf->use_cts_prot = use_protection;
 		changed |= BSS_CHANGED_ERP_CTS_PROT;
 	}
 
 	if (use_short_preamble != bss_conf->use_short_preamble) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "%s: switched to %s barker preamble"
-			       " (BSSID=%pM)\n",
-			       sdata->dev->name,
-			       use_short_preamble ? "short" : "long",
-			       ifmgd->bssid);
-		}
-#endif
 		bss_conf->use_short_preamble = use_short_preamble;
 		changed |= BSS_CHANGED_ERP_PREAMBLE;
 	}
 
 	if (use_short_slot != bss_conf->use_short_slot) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "%s: switched to %s slot time"
-			       " (BSSID=%pM)\n",
-			       sdata->dev->name,
-			       use_short_slot ? "short" : "long",
-			       ifmgd->bssid);
-		}
-#endif
 		bss_conf->use_short_slot = use_short_slot;
 		changed |= BSS_CHANGED_ERP_SLOT;
 	}
@@ -868,105 +879,31 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
 	return changed;
 }
 
-static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata)
-{
-	union iwreq_data wrqu;
-
-	memset(&wrqu, 0, sizeof(wrqu));
-	if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)
-		memcpy(wrqu.ap_addr.sa_data, sdata->u.mgd.bssid, ETH_ALEN);
-	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
-}
-
-static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	char *buf;
-	size_t len;
-	int i;
-	union iwreq_data wrqu;
-
-	if (!ifmgd->assocreq_ies && !ifmgd->assocresp_ies)
-		return;
-
-	buf = kmalloc(50 + 2 * (ifmgd->assocreq_ies_len +
-				ifmgd->assocresp_ies_len), GFP_KERNEL);
-	if (!buf)
-		return;
-
-	len = sprintf(buf, "ASSOCINFO(");
-	if (ifmgd->assocreq_ies) {
-		len += sprintf(buf + len, "ReqIEs=");
-		for (i = 0; i < ifmgd->assocreq_ies_len; i++) {
-			len += sprintf(buf + len, "%02x",
-				       ifmgd->assocreq_ies[i]);
-		}
-	}
-	if (ifmgd->assocresp_ies) {
-		if (ifmgd->assocreq_ies)
-			len += sprintf(buf + len, " ");
-		len += sprintf(buf + len, "RespIEs=");
-		for (i = 0; i < ifmgd->assocresp_ies_len; i++) {
-			len += sprintf(buf + len, "%02x",
-				       ifmgd->assocresp_ies[i]);
-		}
-	}
-	len += sprintf(buf + len, ")");
-
-	if (len > IW_CUSTOM_MAX) {
-		len = sprintf(buf, "ASSOCRESPIE=");
-		for (i = 0; i < ifmgd->assocresp_ies_len; i++) {
-			len += sprintf(buf + len, "%02x",
-				       ifmgd->assocresp_ies[i]);
-		}
-	}
-
-	if (len <= IW_CUSTOM_MAX) {
-		memset(&wrqu, 0, sizeof(wrqu));
-		wrqu.data.length = len;
-		wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf);
-	}
-
-	kfree(buf);
-}
-
-
 static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
+				     struct ieee80211_mgd_work *wk,
 				     u32 bss_info_changed)
 {
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_conf *conf = &local_to_hw(local)->conf;
-
-	struct ieee80211_bss *bss;
+	struct ieee80211_bss *bss = wk->bss;
 
 	bss_info_changed |= BSS_CHANGED_ASSOC;
-	ifmgd->flags |= IEEE80211_STA_ASSOCIATED;
+	/* set timing information */
+	sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
+	sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
+	sdata->vif.bss_conf.dtim_period = bss->dtim_period;
 
-	bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
-				   conf->channel->center_freq,
-				   ifmgd->ssid, ifmgd->ssid_len);
-	if (bss) {
-		/* set timing information */
-		sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
-		sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
-		sdata->vif.bss_conf.dtim_period = bss->dtim_period;
+	bss_info_changed |= BSS_CHANGED_BEACON_INT;
+	bss_info_changed |= ieee80211_handle_bss_capability(sdata,
+		bss->cbss.capability, bss->has_erp_value, bss->erp_value);
 
-		bss_info_changed |= BSS_CHANGED_BEACON_INT;
-		bss_info_changed |= ieee80211_handle_bss_capability(sdata,
-			bss->cbss.capability, bss->has_erp_value, bss->erp_value);
-
-		cfg80211_hold_bss(&bss->cbss);
-
-		ieee80211_rx_bss_put(local, bss);
-	}
+	sdata->u.mgd.associated = bss;
+	sdata->u.mgd.old_associate_work = wk;
+	memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
 
-	ifmgd->flags |= IEEE80211_STA_PREV_BSSID_SET;
-	memcpy(ifmgd->prev_bssid, sdata->u.mgd.bssid, ETH_ALEN);
-	ieee80211_sta_send_associnfo(sdata);
+	/* just to be sure */
+	sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+				IEEE80211_STA_BEACON_POLL);
 
-	ifmgd->last_probe = jiffies;
 	ieee80211_led_assoc(local, 1);
 
 	sdata->vif.bss_conf.assoc = 1;
@@ -982,176 +919,157 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 
 	ieee80211_bss_info_change_notify(sdata, bss_info_changed);
 
-	/* will be same as sdata */
-	if (local->ps_sdata) {
-		mutex_lock(&local->iflist_mtx);
-		ieee80211_recalc_ps(local, -1);
-		mutex_unlock(&local->iflist_mtx);
-	}
+	mutex_lock(&local->iflist_mtx);
+	ieee80211_recalc_ps(local, -1);
+	mutex_unlock(&local->iflist_mtx);
 
 	netif_tx_start_all_queues(sdata->dev);
 	netif_carrier_on(sdata->dev);
-
-	ieee80211_sta_send_apinfo(sdata);
 }
 
-static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
+static enum rx_mgmt_action __must_check
+ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
+		       struct ieee80211_mgd_work *wk)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
 
-	ifmgd->direct_probe_tries++;
-	if (ifmgd->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) {
+	wk->tries++;
+	if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
 		printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
-		       sdata->dev->name, ifmgd->bssid);
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_recalc_idle(local);
-		cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
+		       sdata->dev->name, wk->bss->cbss.bssid);
 
 		/*
 		 * Most likely AP is not in the range so remove the
-		 * bss information associated to the AP
+		 * bss struct for that AP.
 		 */
-		ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
-				sdata->local->hw.conf.channel->center_freq,
-				ifmgd->ssid, ifmgd->ssid_len);
+		cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
 
 		/*
 		 * We might have a pending scan which had no chance to run yet
-		 * due to state == IEEE80211_STA_MLME_DIRECT_PROBE.
-		 * Hence, queue the STAs work again
+		 * due to work needing to be done. Hence, queue the STAs work
+		 * again for that.
 		 */
-		queue_work(local->hw.workqueue, &ifmgd->work);
-		return;
+		ieee80211_queue_work(&local->hw, &ifmgd->work);
+		return RX_MGMT_CFG80211_AUTH_TO;
 	}
 
-	printk(KERN_DEBUG "%s: direct probe to AP %pM try %d\n",
-			sdata->dev->name, ifmgd->bssid,
-			ifmgd->direct_probe_tries);
+	printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n",
+			sdata->dev->name, wk->bss->cbss.bssid,
+			wk->tries);
 
-	ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
-
-	/* Direct probe is sent to broadcast address as some APs
+	/*
+	 * Direct probe is sent to broadcast address as some APs
 	 * will not answer to direct packet in unassociated state.
 	 */
-	ieee80211_send_probe_req(sdata, NULL,
-				 ifmgd->ssid, ifmgd->ssid_len, NULL, 0);
+	ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0);
+
+	wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
+	run_again(ifmgd, wk->timeout);
 
-	mod_timer(&ifmgd->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
+	return RX_MGMT_NONE;
 }
 
 
-static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
+static enum rx_mgmt_action __must_check
+ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
+		       struct ieee80211_mgd_work *wk)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
-	u8 *ies;
-	size_t ies_len;
 
-	ifmgd->auth_tries++;
-	if (ifmgd->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
+	wk->tries++;
+	if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
 		printk(KERN_DEBUG "%s: authentication with AP %pM"
 		       " timed out\n",
-		       sdata->dev->name, ifmgd->bssid);
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_recalc_idle(local);
-		cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
-		ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
-				sdata->local->hw.conf.channel->center_freq,
-				ifmgd->ssid, ifmgd->ssid_len);
+		       sdata->dev->name, wk->bss->cbss.bssid);
+
+		/*
+		 * Most likely AP is not in the range so remove the
+		 * bss struct for that AP.
+		 */
+		cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
 
 		/*
 		 * We might have a pending scan which had no chance to run yet
-		 * due to state == IEEE80211_STA_MLME_AUTHENTICATE.
-		 * Hence, queue the STAs work again
+		 * due to work needing to be done. Hence, queue the STAs work
+		 * again for that.
 		 */
-		queue_work(local->hw.workqueue, &ifmgd->work);
-		return;
+		ieee80211_queue_work(&local->hw, &ifmgd->work);
+		return RX_MGMT_CFG80211_AUTH_TO;
 	}
 
-	ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
-	printk(KERN_DEBUG "%s: authenticate with AP %pM\n",
-	       sdata->dev->name, ifmgd->bssid);
+	printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n",
+	       sdata->dev->name, wk->bss->cbss.bssid, wk->tries);
 
-	if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
-		ies = ifmgd->sme_auth_ie;
-		ies_len = ifmgd->sme_auth_ie_len;
-	} else {
-		ies = NULL;
-		ies_len = 0;
-	}
-	ieee80211_send_auth(sdata, 1, ifmgd->auth_alg, ies, ies_len,
-			    ifmgd->bssid, 0);
-	ifmgd->auth_transaction = 2;
+	ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len,
+			    wk->bss->cbss.bssid, NULL, 0, 0);
+	wk->auth_transaction = 2;
+
+	wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
+	run_again(ifmgd, wk->timeout);
 
-	mod_timer(&ifmgd->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
+	return RX_MGMT_NONE;
 }
 
-/*
- * The disassoc 'reason' argument can be either our own reason
- * if self disconnected or a reason code from the AP.
- */
 static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
-				   bool deauth, bool self_disconnected,
-				   u16 reason)
+				   bool deauth)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_conf *conf = &local_to_hw(local)->conf;
-	struct ieee80211_bss *bss;
 	struct sta_info *sta;
 	u32 changed = 0, config_changed = 0;
+	u8 bssid[ETH_ALEN];
+
+	ASSERT_MGD_MTX(ifmgd);
+
+	if (WARN_ON(!ifmgd->associated))
+		return;
+
+	memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
+
+	ifmgd->associated = NULL;
+	memset(ifmgd->bssid, 0, ETH_ALEN);
 
 	if (deauth) {
-		ifmgd->direct_probe_tries = 0;
-		ifmgd->auth_tries = 0;
+		kfree(ifmgd->old_associate_work);
+		ifmgd->old_associate_work = NULL;
+	} else {
+		struct ieee80211_mgd_work *wk = ifmgd->old_associate_work;
+
+		wk->state = IEEE80211_MGD_STATE_IDLE;
+		list_add(&wk->list, &ifmgd->work_list);
 	}
-	ifmgd->assoc_scan_tries = 0;
-	ifmgd->assoc_tries = 0;
+
+	/*
+	 * we need to commit the associated = NULL change because the
+	 * scan code uses that to determine whether this iface should
+	 * go to/wake up from powersave or not -- and could otherwise
+	 * wake the queues erroneously.
+	 */
+	smp_mb();
+
+	/*
+	 * Thus, we can only afterwards stop the queues -- to account
+	 * for the case where another CPU is finishing a scan at this
+	 * time -- we don't want the scan code to enable queues.
+	 */
 
 	netif_tx_stop_all_queues(sdata->dev);
 	netif_carrier_off(sdata->dev);
 
 	rcu_read_lock();
-	sta = sta_info_get(local, ifmgd->bssid);
+	sta = sta_info_get(local, bssid);
 	if (sta)
 		ieee80211_sta_tear_down_BA_sessions(sta);
 	rcu_read_unlock();
 
-	bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
-				   conf->channel->center_freq,
-				   ifmgd->ssid, ifmgd->ssid_len);
-
-	if (bss) {
-		cfg80211_unhold_bss(&bss->cbss);
-		ieee80211_rx_bss_put(local, bss);
-	}
-
-	if (self_disconnected) {
-		if (deauth)
-			ieee80211_send_deauth_disassoc(sdata,
-				IEEE80211_STYPE_DEAUTH, reason);
-		else
-			ieee80211_send_deauth_disassoc(sdata,
-				IEEE80211_STYPE_DISASSOC, reason);
-	}
-
-	ifmgd->flags &= ~IEEE80211_STA_ASSOCIATED;
 	changed |= ieee80211_reset_erp_info(sdata);
 
 	ieee80211_led_assoc(local, 0);
 	changed |= BSS_CHANGED_ASSOC;
 	sdata->vif.bss_conf.assoc = false;
 
-	ieee80211_sta_send_apinfo(sdata);
-
-	if (self_disconnected || reason == WLAN_REASON_DISASSOC_STA_HAS_LEFT) {
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
-				sdata->local->hw.conf.channel->center_freq,
-				ifmgd->ssid, ifmgd->ssid_len);
-	}
-
 	ieee80211_set_wmm_default(sdata);
 
 	ieee80211_recalc_idle(local);
@@ -1180,7 +1098,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 
 	rcu_read_lock();
 
-	sta = sta_info_get(local, ifmgd->bssid);
+	sta = sta_info_get(local, bssid);
 	if (!sta) {
 		rcu_read_unlock();
 		return;
@@ -1193,83 +1111,42 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 	sta_info_destroy(sta);
 }
 
-static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
-{
-	if (!sdata || !sdata->default_key ||
-	    sdata->default_key->conf.alg != ALG_WEP)
-		return 0;
-	return 1;
-}
-
-static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_bss *bss;
-	int bss_privacy;
-	int wep_privacy;
-	int privacy_invoked;
-
-	if (!ifmgd || (ifmgd->flags & IEEE80211_STA_EXT_SME))
-		return 0;
-
-	bss = ieee80211_rx_bss_get(local, ifmgd->bssid,
-				   local->hw.conf.channel->center_freq,
-				   ifmgd->ssid, ifmgd->ssid_len);
-	if (!bss)
-		return 0;
-
-	bss_privacy = !!(bss->cbss.capability & WLAN_CAPABILITY_PRIVACY);
-	wep_privacy = !!ieee80211_sta_wep_configured(sdata);
-	privacy_invoked = !!(ifmgd->flags & IEEE80211_STA_PRIVACY_INVOKED);
-
-	ieee80211_rx_bss_put(local, bss);
-
-	if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
-		return 0;
-
-	return 1;
-}
-
-static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
+static enum rx_mgmt_action __must_check
+ieee80211_associate(struct ieee80211_sub_if_data *sdata,
+		    struct ieee80211_mgd_work *wk)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
 
-	ifmgd->assoc_tries++;
-	if (ifmgd->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
+	wk->tries++;
+	if (wk->tries > IEEE80211_ASSOC_MAX_TRIES) {
 		printk(KERN_DEBUG "%s: association with AP %pM"
 		       " timed out\n",
-		       sdata->dev->name, ifmgd->bssid);
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_recalc_idle(local);
-		cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid);
-		ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
-				sdata->local->hw.conf.channel->center_freq,
-				ifmgd->ssid, ifmgd->ssid_len);
+		       sdata->dev->name, wk->bss->cbss.bssid);
+
+		/*
+		 * Most likely AP is not in the range so remove the
+		 * bss struct for that AP.
+		 */
+		cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
+
 		/*
 		 * We might have a pending scan which had no chance to run yet
-		 * due to state == IEEE80211_STA_MLME_ASSOCIATE.
-		 * Hence, queue the STAs work again
+		 * due to work needing to be done. Hence, queue the STAs work
+		 * again for that.
 		 */
-		queue_work(local->hw.workqueue, &ifmgd->work);
-		return;
+		ieee80211_queue_work(&local->hw, &ifmgd->work);
+		return RX_MGMT_CFG80211_ASSOC_TO;
 	}
 
-	ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE;
-	printk(KERN_DEBUG "%s: associate with AP %pM\n",
-	       sdata->dev->name, ifmgd->bssid);
-	if (ieee80211_privacy_mismatch(sdata)) {
-		printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
-		       "mixed-cell disabled - abort association\n", sdata->dev->name);
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_recalc_idle(local);
-		return;
-	}
+	printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n",
+	       sdata->dev->name, wk->bss->cbss.bssid, wk->tries);
+	ieee80211_send_assoc(sdata, wk);
 
-	ieee80211_send_assoc(sdata);
+	wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
+	run_again(ifmgd, wk->timeout);
 
-	mod_timer(&ifmgd->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
+	return RX_MGMT_NONE;
 }
 
 void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -1280,160 +1157,113 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
 	 * from AP because we know that the connection is working both ways
 	 * at that time. But multicast frames (and hence also beacons) must
 	 * be ignored here, because we need to trigger the timer during
-	 * data idle periods for sending the periodical probe request to
-	 * the AP.
+	 * data idle periods for sending the periodic probe request to the
+	 * AP we're connected to.
 	 */
-	if (!is_multicast_ether_addr(hdr->addr1))
-		mod_timer(&sdata->u.mgd.timer,
-			  jiffies + IEEE80211_MONITORING_INTERVAL);
-}
-
-void ieee80211_beacon_loss_work(struct work_struct *work)
-{
-	struct ieee80211_sub_if_data *sdata =
-		container_of(work, struct ieee80211_sub_if_data,
-			     u.mgd.beacon_loss_work);
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-
-	/*
-	 * The driver has already reported this event and we have
-	 * already sent a probe request. Maybe the AP died and the
-	 * driver keeps reporting until we disassociate... We have
-	 * to ignore that because otherwise we would continually
-	 * reset the timer and never check whether we received a
-	 * probe response!
-	 */
-	if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
+	if (is_multicast_ether_addr(hdr->addr1))
 		return;
 
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-	if (net_ratelimit()) {
-		printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM "
-		       "- sending probe request\n", sdata->dev->name,
-		       sdata->u.mgd.bssid);
-	}
-#endif
-
-	ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
-
-	mutex_lock(&sdata->local->iflist_mtx);
-	ieee80211_recalc_ps(sdata->local, -1);
-	mutex_unlock(&sdata->local->iflist_mtx);
-
-	ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
-				 ifmgd->ssid_len, NULL, 0);
-
-	mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
+	mod_timer(&sdata->u.mgd.conn_mon_timer,
+		  round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
 }
 
-void ieee80211_beacon_loss(struct ieee80211_vif *vif)
+static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
 {
-	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	const u8 *ssid;
+
+	ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID);
+	ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid,
+				 ssid + 2, ssid[1], NULL, 0);
 
-	queue_work(sdata->local->hw.workqueue,
-		   &sdata->u.mgd.beacon_loss_work);
+	ifmgd->probe_send_count++;
+	ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
+	run_again(ifmgd, ifmgd->probe_timeout);
 }
-EXPORT_SYMBOL(ieee80211_beacon_loss);
 
-static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
+static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
+				   bool beacon)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	struct ieee80211_local *local = sdata->local;
-	struct sta_info *sta;
-	unsigned long last_rx;
-	bool disassoc = false;
+	bool already = false;
 
-	/* TODO: start monitoring current AP signal quality and number of
-	 * missed beacons. Scan other channels every now and then and search
-	 * for better APs. */
-	/* TODO: remove expired BSSes */
+	if (!netif_running(sdata->dev))
+		return;
 
-	ifmgd->state = IEEE80211_STA_MLME_ASSOCIATED;
+	if (sdata->local->scanning)
+		return;
 
-	rcu_read_lock();
+	mutex_lock(&ifmgd->mtx);
 
-	sta = sta_info_get(local, ifmgd->bssid);
-	if (!sta) {
-		printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
-		       sdata->dev->name, ifmgd->bssid);
-		disassoc = true;
-		rcu_read_unlock();
+	if (!ifmgd->associated)
 		goto out;
-	}
 
-	last_rx = sta->last_rx;
-	rcu_read_unlock();
-
-	if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
-	    time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) {
-		printk(KERN_DEBUG "%s: no probe response from AP %pM "
-		       "- disassociating\n",
-		       sdata->dev->name, ifmgd->bssid);
-		disassoc = true;
-		ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
-		goto out;
-	}
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+	if (beacon && net_ratelimit())
+		printk(KERN_DEBUG "%s: detected beacon loss from AP "
+		       "- sending probe request\n", sdata->dev->name);
+#endif
 
 	/*
-	 * Beacon filtering is only enabled with power save and then the
-	 * stack should not check for beacon loss.
+	 * The driver/our work has already reported this event or the
+	 * connection monitoring has kicked in and we have already sent
+	 * a probe request. Or maybe the AP died and the driver keeps
+	 * reporting until we disassociate...
+	 *
+	 * In either case we have to ignore the current call to this
+	 * function (except for setting the correct probe reason bit)
+	 * because otherwise we would reset the timer every time and
+	 * never check whether we received a probe response!
 	 */
-	if (!((local->hw.flags & IEEE80211_HW_BEACON_FILTER) &&
-	      (local->hw.conf.flags & IEEE80211_CONF_PS)) &&
-	    time_after(jiffies,
-		       ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-		if (net_ratelimit()) {
-			printk(KERN_DEBUG "%s: beacon loss from AP %pM "
-			       "- sending probe request\n",
-			       sdata->dev->name, ifmgd->bssid);
-		}
-#endif
-		ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
-		mutex_lock(&local->iflist_mtx);
-		ieee80211_recalc_ps(local, -1);
-		mutex_unlock(&local->iflist_mtx);
-		ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
-					 ifmgd->ssid_len, NULL, 0);
-		mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
+	if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+			    IEEE80211_STA_CONNECTION_POLL))
+		already = true;
+
+	if (beacon)
+		ifmgd->flags |= IEEE80211_STA_BEACON_POLL;
+	else
+		ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
+
+	if (already)
 		goto out;
-	}
 
-	if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) {
-		ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
-		mutex_lock(&local->iflist_mtx);
-		ieee80211_recalc_ps(local, -1);
-		mutex_unlock(&local->iflist_mtx);
-		ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
-					 ifmgd->ssid_len, NULL, 0);
-	}
+	mutex_lock(&sdata->local->iflist_mtx);
+	ieee80211_recalc_ps(sdata->local, -1);
+	mutex_unlock(&sdata->local->iflist_mtx);
 
+	ifmgd->probe_send_count = 0;
+	ieee80211_mgd_probe_ap_send(sdata);
  out:
-	if (!disassoc)
-		mod_timer(&ifmgd->timer,
-			  jiffies + IEEE80211_MONITORING_INTERVAL);
-	else
-		ieee80211_set_disassoc(sdata, true, true,
-					WLAN_REASON_PREV_AUTH_NOT_VALID);
+	mutex_unlock(&ifmgd->mtx);
 }
 
+void ieee80211_beacon_loss_work(struct work_struct *work)
+{
+	struct ieee80211_sub_if_data *sdata =
+		container_of(work, struct ieee80211_sub_if_data,
+			     u.mgd.beacon_loss_work);
+
+	ieee80211_mgd_probe_ap(sdata, true);
+}
 
-static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
+void ieee80211_beacon_loss(struct ieee80211_vif *vif)
 {
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
 
+	ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work);
+}
+EXPORT_SYMBOL(ieee80211_beacon_loss);
+
+static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
+				     struct ieee80211_mgd_work *wk)
+{
+	wk->state = IEEE80211_MGD_STATE_IDLE;
 	printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
-	ifmgd->flags |= IEEE80211_STA_AUTHENTICATED;
-	if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
-		/* Wait for SME to request association */
-		ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-		ieee80211_recalc_idle(sdata->local);
-	} else
-		ieee80211_associate(sdata);
 }
 
 
 static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
+				     struct ieee80211_mgd_work *wk,
 				     struct ieee80211_mgmt *mgmt,
 				     size_t len)
 {
@@ -1444,161 +1274,133 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
 	ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
 	if (!elems.challenge)
 		return;
-	ieee80211_send_auth(sdata, 3, sdata->u.mgd.auth_alg,
+	ieee80211_send_auth(sdata, 3, wk->auth_alg,
 			    elems.challenge - 2, elems.challenge_len + 2,
-			    sdata->u.mgd.bssid, 1);
-	sdata->u.mgd.auth_transaction = 4;
+			    wk->bss->cbss.bssid,
+			    wk->key, wk->key_len, wk->key_idx);
+	wk->auth_transaction = 4;
 }
 
-static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
-				   struct ieee80211_mgmt *mgmt,
-				   size_t len)
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
+		       struct ieee80211_mgd_work *wk,
+		       struct ieee80211_mgmt *mgmt, size_t len)
 {
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	u16 auth_alg, auth_transaction, status_code;
 
-	if (ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE)
-		return;
+	if (wk->state != IEEE80211_MGD_STATE_AUTH)
+		return RX_MGMT_NONE;
 
 	if (len < 24 + 6)
-		return;
+		return RX_MGMT_NONE;
 
-	if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN) != 0)
-		return;
+	if (memcmp(wk->bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0)
+		return RX_MGMT_NONE;
 
-	if (memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0)
-		return;
+	if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0)
+		return RX_MGMT_NONE;
 
 	auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
 	auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
 	status_code = le16_to_cpu(mgmt->u.auth.status_code);
 
-	if (auth_alg != ifmgd->auth_alg ||
-	    auth_transaction != ifmgd->auth_transaction)
-		return;
+	if (auth_alg != wk->auth_alg ||
+	    auth_transaction != wk->auth_transaction)
+		return RX_MGMT_NONE;
 
 	if (status_code != WLAN_STATUS_SUCCESS) {
-		if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
-			u8 algs[3];
-			const int num_algs = ARRAY_SIZE(algs);
-			int i, pos;
-			algs[0] = algs[1] = algs[2] = 0xff;
-			if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_OPEN)
-				algs[0] = WLAN_AUTH_OPEN;
-			if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY)
-				algs[1] = WLAN_AUTH_SHARED_KEY;
-			if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP)
-				algs[2] = WLAN_AUTH_LEAP;
-			if (ifmgd->auth_alg == WLAN_AUTH_OPEN)
-				pos = 0;
-			else if (ifmgd->auth_alg == WLAN_AUTH_SHARED_KEY)
-				pos = 1;
-			else
-				pos = 2;
-			for (i = 0; i < num_algs; i++) {
-				pos++;
-				if (pos >= num_algs)
-					pos = 0;
-				if (algs[pos] == ifmgd->auth_alg ||
-				    algs[pos] == 0xff)
-					continue;
-				if (algs[pos] == WLAN_AUTH_SHARED_KEY &&
-				    !ieee80211_sta_wep_configured(sdata))
-					continue;
-				ifmgd->auth_alg = algs[pos];
-				break;
-			}
-		}
-		return;
+		list_del(&wk->list);
+		kfree(wk);
+		return RX_MGMT_CFG80211_AUTH;
 	}
 
-	switch (ifmgd->auth_alg) {
+	switch (wk->auth_alg) {
 	case WLAN_AUTH_OPEN:
 	case WLAN_AUTH_LEAP:
 	case WLAN_AUTH_FT:
-		ieee80211_auth_completed(sdata);
-		cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len);
-		break;
+		ieee80211_auth_completed(sdata, wk);
+		return RX_MGMT_CFG80211_AUTH;
 	case WLAN_AUTH_SHARED_KEY:
-		if (ifmgd->auth_transaction == 4) {
-			ieee80211_auth_completed(sdata);
-			cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, len);
+		if (wk->auth_transaction == 4) {
+			ieee80211_auth_completed(sdata, wk);
+			return RX_MGMT_CFG80211_AUTH;
 		} else
-			ieee80211_auth_challenge(sdata, mgmt, len);
+			ieee80211_auth_challenge(sdata, wk, mgmt, len);
 		break;
 	}
+
+	return RX_MGMT_NONE;
 }
 
 
-static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
-				     struct ieee80211_mgmt *mgmt,
-				     size_t len)
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
+			 struct ieee80211_mgd_work *wk,
+			 struct ieee80211_mgmt *mgmt, size_t len)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	const u8 *bssid = NULL;
 	u16 reason_code;
 
 	if (len < 24 + 2)
-		return;
+		return RX_MGMT_NONE;
 
-	if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN))
-		return;
+	ASSERT_MGD_MTX(ifmgd);
+
+	if (wk)
+		bssid = wk->bss->cbss.bssid;
+	else
+		bssid = ifmgd->associated->cbss.bssid;
 
 	reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 
-	if (ifmgd->flags & IEEE80211_STA_AUTHENTICATED)
-		printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n",
-				sdata->dev->name, reason_code);
+	printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
+			sdata->dev->name, bssid, reason_code);
 
-	if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
-	    (ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
-	     ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE ||
-	     ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)) {
-		ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
-		mod_timer(&ifmgd->timer, jiffies +
-				      IEEE80211_RETRY_AUTH_INTERVAL);
+	if (!wk) {
+		ieee80211_set_disassoc(sdata, true);
+	} else {
+		list_del(&wk->list);
+		kfree(wk);
 	}
 
-	ieee80211_set_disassoc(sdata, true, false, 0);
-	ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
-	cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len);
+	return RX_MGMT_CFG80211_DEAUTH;
 }
 
 
-static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
-				       struct ieee80211_mgmt *mgmt,
-				       size_t len)
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
+			   struct ieee80211_mgmt *mgmt, size_t len)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	u16 reason_code;
 
 	if (len < 24 + 2)
-		return;
+		return RX_MGMT_NONE;
 
-	if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN))
-		return;
+	ASSERT_MGD_MTX(ifmgd);
 
-	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
+	if (WARN_ON(!ifmgd->associated))
+		return RX_MGMT_NONE;
 
-	if (ifmgd->flags & IEEE80211_STA_ASSOCIATED)
-		printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
-				sdata->dev->name, reason_code);
+	if (WARN_ON(memcmp(ifmgd->associated->cbss.bssid, mgmt->sa, ETH_ALEN)))
+		return RX_MGMT_NONE;
 
-	if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
-	    ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) {
-		ifmgd->state = IEEE80211_STA_MLME_ASSOCIATE;
-		mod_timer(&ifmgd->timer, jiffies +
-				      IEEE80211_RETRY_AUTH_INTERVAL);
-	}
+	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 
-	ieee80211_set_disassoc(sdata, false, false, reason_code);
-	cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len);
+	printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
+			sdata->dev->name, reason_code);
+
+	ieee80211_set_disassoc(sdata, false);
+	return RX_MGMT_CFG80211_DISASSOC;
 }
 
 
-static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
-					 struct ieee80211_mgmt *mgmt,
-					 size_t len,
-					 int reassoc)
+static enum rx_mgmt_action __must_check
+ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+			     struct ieee80211_mgd_work *wk,
+			     struct ieee80211_mgmt *mgmt, size_t len,
+			     bool reassoc)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
@@ -1614,17 +1416,16 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 	bool have_higher_than_11mbit = false, newsta = false;
 	u16 ap_ht_cap_flags;
 
-	/* AssocResp and ReassocResp have identical structure, so process both
-	 * of them in this function. */
-
-	if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE)
-		return;
+	/*
+	 * AssocResp and ReassocResp have identical structure, so process both
+	 * of them in this function.
+	 */
 
 	if (len < 24 + 6)
-		return;
+		return RX_MGMT_NONE;
 
-	if (memcmp(ifmgd->bssid, mgmt->sa, ETH_ALEN) != 0)
-		return;
+	if (memcmp(wk->bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0)
+		return RX_MGMT_NONE;
 
 	capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
 	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
@@ -1647,26 +1448,18 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 		printk(KERN_DEBUG "%s: AP rejected association temporarily; "
 		       "comeback duration %u TU (%u ms)\n",
 		       sdata->dev->name, tu, ms);
+		wk->timeout = jiffies + msecs_to_jiffies(ms);
 		if (ms > IEEE80211_ASSOC_TIMEOUT)
-			mod_timer(&ifmgd->timer,
-				  jiffies + msecs_to_jiffies(ms));
-		return;
+			run_again(ifmgd, jiffies + msecs_to_jiffies(ms));
+		return RX_MGMT_NONE;
 	}
 
 	if (status_code != WLAN_STATUS_SUCCESS) {
 		printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
 		       sdata->dev->name, status_code);
-		/* if this was a reassociation, ensure we try a "full"
-		 * association next time. This works around some broken APs
-		 * which do not correctly reject reassociation requests. */
-		ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
-		cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
-		if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
-			/* Wait for SME to decide what to do next */
-			ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-			ieee80211_recalc_idle(local);
-		}
-		return;
+		list_del(&wk->list);
+		kfree(wk);
+		return RX_MGMT_CFG80211_ASSOC;
 	}
 
 	if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
@@ -1677,51 +1470,35 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 	if (!elems.supp_rates) {
 		printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
 		       sdata->dev->name);
-		return;
+		return RX_MGMT_NONE;
 	}
 
 	printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
 	ifmgd->aid = aid;
-	ifmgd->ap_capab = capab_info;
-
-	kfree(ifmgd->assocresp_ies);
-	ifmgd->assocresp_ies_len = len - (pos - (u8 *) mgmt);
-	ifmgd->assocresp_ies = kmalloc(ifmgd->assocresp_ies_len, GFP_KERNEL);
-	if (ifmgd->assocresp_ies)
-		memcpy(ifmgd->assocresp_ies, pos, ifmgd->assocresp_ies_len);
 
 	rcu_read_lock();
 
 	/* Add STA entry for the AP */
-	sta = sta_info_get(local, ifmgd->bssid);
+	sta = sta_info_get(local, wk->bss->cbss.bssid);
 	if (!sta) {
 		newsta = true;
 
-		sta = sta_info_alloc(sdata, ifmgd->bssid, GFP_ATOMIC);
+		rcu_read_unlock();
+
+		sta = sta_info_alloc(sdata, wk->bss->cbss.bssid, GFP_KERNEL);
 		if (!sta) {
 			printk(KERN_DEBUG "%s: failed to alloc STA entry for"
 			       " the AP\n", sdata->dev->name);
-			rcu_read_unlock();
-			return;
+			return RX_MGMT_NONE;
 		}
 
-		/* update new sta with its last rx activity */
-		sta->last_rx = jiffies;
-	}
+		set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
+				   WLAN_STA_ASSOC_AP);
+		if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
+			set_sta_flags(sta, WLAN_STA_AUTHORIZED);
 
-	/*
-	 * FIXME: Do we really need to update the sta_info's information here?
-	 *	  We already know about the AP (we found it in our list) so it
-	 *	  should already be filled with the right info, no?
-	 *	  As is stands, all this is racy because typically we assume
-	 *	  the information that is filled in here (except flags) doesn't
-	 *	  change while a STA structure is alive. As such, it should move
-	 *	  to between the sta_info_alloc() and sta_info_insert() above.
-	 */
-
-	set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP);
-	if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
-		set_sta_flags(sta, WLAN_STA_AUTHORIZED);
+		rcu_read_lock();
+	}
 
 	rates = 0;
 	basic_rates = 0;
@@ -1771,8 +1548,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 	else
 		sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
 
-	/* If TKIP/WEP is used, no need to parse AP's HT capabilities */
-	if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED))
+	if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
 		ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
 				elems.ht_cap_elem, &sta->sta.ht_cap);
 
@@ -1792,7 +1568,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 			printk(KERN_DEBUG "%s: failed to insert STA entry for"
 			       " the AP (error %d)\n", sdata->dev->name, err);
 			rcu_read_unlock();
-			return;
+			return RX_MGMT_NONE;
 		}
 	}
 
@@ -1806,24 +1582,29 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
 
 	if (elems.ht_info_elem && elems.wmm_param &&
 	    (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
-	    !(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED))
+	    !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
 		changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
+					       wk->bss->cbss.bssid,
 					       ap_ht_cap_flags);
 
+        /* delete work item -- must be before set_associated for PS */
+	list_del(&wk->list);
+
 	/* set AID and assoc capability,
 	 * ieee80211_set_associated() will tell the driver */
 	bss_conf->aid = aid;
 	bss_conf->assoc_capability = capab_info;
-	ieee80211_set_associated(sdata, changed);
+	/* this will take ownership of wk */
+	ieee80211_set_associated(sdata, wk, changed);
 
 	/*
-	 * initialise the time of last beacon to be the association time,
-	 * otherwise beacon loss check will trigger immediately
+	 * Start timer to probe the connection to the AP now.
+	 * Also start the timer that will detect beacon loss.
 	 */
-	ifmgd->last_beacon = jiffies;
+	ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
+	mod_beacon_timer(sdata);
 
-	ieee80211_associated(sdata);
-	cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
+	return RX_MGMT_CFG80211_ASSOC;
 }
 
 
@@ -1851,23 +1632,25 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 
 	bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
 					channel, beacon);
-	if (!bss)
+	if (bss)
+		ieee80211_rx_bss_put(local, bss);
+
+	if (!sdata->u.mgd.associated)
 		return;
 
 	if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
-	    (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN) == 0)) {
+	    (memcmp(mgmt->bssid, sdata->u.mgd.associated->cbss.bssid,
+							ETH_ALEN) == 0)) {
 		struct ieee80211_channel_sw_ie *sw_elem =
 			(struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
 		ieee80211_sta_process_chanswitch(sdata, sw_elem, bss);
 	}
-
-	ieee80211_rx_bss_put(local, bss);
 }
 
 
 static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
-					 struct ieee80211_mgmt *mgmt,
-					 size_t len,
+					 struct ieee80211_mgd_work *wk,
+					 struct ieee80211_mgmt *mgmt, size_t len,
 					 struct ieee80211_rx_status *rx_status)
 {
 	struct ieee80211_if_managed *ifmgd;
@@ -1876,6 +1659,8 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 
 	ifmgd = &sdata->u.mgd;
 
+	ASSERT_MGD_MTX(ifmgd);
+
 	if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
 		return; /* ignore ProbeResp to foreign address */
 
@@ -1889,17 +1674,32 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
 	ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
 
 	/* direct probe may be part of the association flow */
-	if (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE) {
+	if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) {
 		printk(KERN_DEBUG "%s direct probe responded\n",
 		       sdata->dev->name);
-		ieee80211_authenticate(sdata);
+		wk->tries = 0;
+		wk->state = IEEE80211_MGD_STATE_AUTH;
+		WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE);
 	}
 
-	if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
-		ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
+	if (ifmgd->associated &&
+	    memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 &&
+	    ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+			    IEEE80211_STA_CONNECTION_POLL)) {
+		ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+				  IEEE80211_STA_BEACON_POLL);
 		mutex_lock(&sdata->local->iflist_mtx);
 		ieee80211_recalc_ps(sdata->local, -1);
 		mutex_unlock(&sdata->local->iflist_mtx);
+		/*
+		 * We've received a probe response, but are not sure whether
+		 * we have or will be receiving any beacons or data, so let's
+		 * schedule the timers again, just in case.
+		 */
+		mod_beacon_timer(sdata);
+		mod_timer(&ifmgd->conn_mon_timer,
+			  round_jiffies_up(jiffies +
+					   IEEE80211_CONNECTION_IDLE_TIME));
 	}
 }
 
@@ -1937,6 +1737,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 	bool erp_valid, directed_tim = false;
 	u8 erp_value = 0;
 	u32 ncrc;
+	u8 *bssid;
+
+	ASSERT_MGD_MTX(ifmgd);
 
 	/* Process beacon from the current BSS */
 	baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
@@ -1946,23 +1749,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 	if (rx_status->freq != local->hw.conf.channel->center_freq)
 		return;
 
-	if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) ||
-	    memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0)
+	/*
+	 * We might have received a number of frames, among them a
+	 * disassoc frame and a beacon...
+	 */
+	if (!ifmgd->associated)
+		return;
+
+	bssid = ifmgd->associated->cbss.bssid;
+
+	/*
+	 * And in theory even frames from a different AP we were just
+	 * associated to a split-second ago!
+	 */
+	if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
 		return;
 
-	if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
+	if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: cancelling probereq poll due "
 			       "to a received beacon\n", sdata->dev->name);
 		}
 #endif
-		ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
+		ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
 		mutex_lock(&local->iflist_mtx);
 		ieee80211_recalc_ps(local, -1);
 		mutex_unlock(&local->iflist_mtx);
 	}
 
+	/*
+	 * Push the beacon loss detection into the future since
+	 * we are processing a beacon from the AP just now.
+	 */
+	mod_beacon_timer(sdata);
+
 	ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
 	ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
 					  len - baselen, &elems,
@@ -2019,15 +1840,15 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 
 
 	if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
-	    !(ifmgd->flags & IEEE80211_STA_TKIP_WEP_USED)) {
+	    !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) {
 		struct sta_info *sta;
 		struct ieee80211_supported_band *sband;
 		u16 ap_ht_cap_flags;
 
 		rcu_read_lock();
 
-		sta = sta_info_get(local, ifmgd->bssid);
-		if (!sta) {
+		sta = sta_info_get(local, bssid);
+		if (WARN_ON(!sta)) {
 			rcu_read_unlock();
 			return;
 		}
@@ -2042,15 +1863,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 		rcu_read_unlock();
 
 		changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
-					       ap_ht_cap_flags);
+					       bssid, ap_ht_cap_flags);
 	}
 
+	/* Note: country IE parsing is done for us by cfg80211 */
 	if (elems.country_elem) {
-		/* Note we are only reviewing this on beacons
-		 * for the BSSID we are associated to */
-		regulatory_hint_11d(local->hw.wiphy,
-			elems.country_elem, elems.country_elem_len);
-
 		/* TODO: IBSS also needs this */
 		if (elems.pwr_constr_elem)
 			ieee80211_handle_pwr_constr(sdata,
@@ -2063,8 +1880,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 }
 
 ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
-					  struct sk_buff *skb,
-					  struct ieee80211_rx_status *rx_status)
+					  struct sk_buff *skb)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_mgmt *mgmt;
@@ -2080,14 +1896,14 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
 	case IEEE80211_STYPE_PROBE_REQ:
 	case IEEE80211_STYPE_PROBE_RESP:
 	case IEEE80211_STYPE_BEACON:
-		memcpy(skb->cb, rx_status, sizeof(*rx_status));
 	case IEEE80211_STYPE_AUTH:
 	case IEEE80211_STYPE_ASSOC_RESP:
 	case IEEE80211_STYPE_REASSOC_RESP:
 	case IEEE80211_STYPE_DEAUTH:
 	case IEEE80211_STYPE_DISASSOC:
+	case IEEE80211_STYPE_ACTION:
 		skb_queue_tail(&sdata->u.mgd.skb_queue, skb);
-		queue_work(local->hw.workqueue, &sdata->u.mgd.work);
+		ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
 		return RX_QUEUED;
 	}
 
@@ -2097,40 +1913,119 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
 static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 					 struct sk_buff *skb)
 {
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_rx_status *rx_status;
 	struct ieee80211_mgmt *mgmt;
+	struct ieee80211_mgd_work *wk;
+	enum rx_mgmt_action rma = RX_MGMT_NONE;
 	u16 fc;
 
 	rx_status = (struct ieee80211_rx_status *) skb->cb;
 	mgmt = (struct ieee80211_mgmt *) skb->data;
 	fc = le16_to_cpu(mgmt->frame_control);
 
-	switch (fc & IEEE80211_FCTL_STYPE) {
-	case IEEE80211_STYPE_PROBE_RESP:
-		ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len,
-					     rx_status);
-		break;
-	case IEEE80211_STYPE_BEACON:
-		ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
-					 rx_status);
-		break;
-	case IEEE80211_STYPE_AUTH:
-		ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
+	mutex_lock(&ifmgd->mtx);
+
+	if (ifmgd->associated &&
+	    memcmp(ifmgd->associated->cbss.bssid, mgmt->bssid,
+							ETH_ALEN) == 0) {
+		switch (fc & IEEE80211_FCTL_STYPE) {
+		case IEEE80211_STYPE_BEACON:
+			ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
+						 rx_status);
+			break;
+		case IEEE80211_STYPE_PROBE_RESP:
+			ieee80211_rx_mgmt_probe_resp(sdata, NULL, mgmt,
+						     skb->len, rx_status);
+			break;
+		case IEEE80211_STYPE_DEAUTH:
+			rma = ieee80211_rx_mgmt_deauth(sdata, NULL,
+						       mgmt, skb->len);
+			break;
+		case IEEE80211_STYPE_DISASSOC:
+			rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
+			break;
+		case IEEE80211_STYPE_ACTION:
+			/* XXX: differentiate, can only happen for CSA now! */
+			ieee80211_sta_process_chanswitch(sdata,
+					&mgmt->u.action.u.chan_switch.sw_elem,
+					ifmgd->associated);
+			break;
+		}
+		mutex_unlock(&ifmgd->mtx);
+
+		switch (rma) {
+		case RX_MGMT_NONE:
+			/* no action */
+			break;
+		case RX_MGMT_CFG80211_DEAUTH:
+			cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len,
+					     NULL);
+			break;
+		case RX_MGMT_CFG80211_DISASSOC:
+			cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len,
+					       NULL);
+			break;
+		default:
+			WARN(1, "unexpected: %d", rma);
+		}
+		goto out;
+	}
+
+	list_for_each_entry(wk, &ifmgd->work_list, list) {
+		if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0)
+			continue;
+
+		switch (fc & IEEE80211_FCTL_STYPE) {
+		case IEEE80211_STYPE_PROBE_RESP:
+			ieee80211_rx_mgmt_probe_resp(sdata, wk, mgmt, skb->len,
+						     rx_status);
+			break;
+		case IEEE80211_STYPE_AUTH:
+			rma = ieee80211_rx_mgmt_auth(sdata, wk, mgmt, skb->len);
+			break;
+		case IEEE80211_STYPE_ASSOC_RESP:
+			rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
+							   skb->len, false);
+			break;
+		case IEEE80211_STYPE_REASSOC_RESP:
+			rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
+							   skb->len, true);
+			break;
+		case IEEE80211_STYPE_DEAUTH:
+			rma = ieee80211_rx_mgmt_deauth(sdata, wk, mgmt,
+						       skb->len);
+			break;
+		}
+		/*
+		 * We've processed this frame for that work, so it can't
+		 * belong to another work struct.
+		 * NB: this is also required for correctness because the
+		 * called functions can free 'wk', and for 'rma'!
+		 */
 		break;
-	case IEEE80211_STYPE_ASSOC_RESP:
-		ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, 0);
+	}
+
+	mutex_unlock(&ifmgd->mtx);
+
+	switch (rma) {
+	case RX_MGMT_NONE:
+		/* no action */
 		break;
-	case IEEE80211_STYPE_REASSOC_RESP:
-		ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, 1);
+	case RX_MGMT_CFG80211_AUTH:
+		cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len);
 		break;
-	case IEEE80211_STYPE_DEAUTH:
-		ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
+	case RX_MGMT_CFG80211_ASSOC:
+		cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len);
 		break;
-	case IEEE80211_STYPE_DISASSOC:
-		ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
+	case RX_MGMT_CFG80211_DEAUTH:
+		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, NULL);
 		break;
+	default:
+		WARN(1, "unexpected: %d", rma);
 	}
 
+ out:
 	kfree_skb(skb);
 }
 
@@ -2146,215 +2041,216 @@ static void ieee80211_sta_timer(unsigned long data)
 		return;
 	}
 
-	set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
-	queue_work(local->hw.workqueue, &ifmgd->work);
+	ieee80211_queue_work(&local->hw, &ifmgd->work);
 }
 
-static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata)
+static void ieee80211_sta_work(struct work_struct *work)
 {
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_sub_if_data *sdata =
+		container_of(work, struct ieee80211_sub_if_data, u.mgd.work);
 	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_if_managed *ifmgd;
+	struct sk_buff *skb;
+	struct ieee80211_mgd_work *wk, *tmp;
+	LIST_HEAD(free_work);
+	enum rx_mgmt_action rma;
+	bool anybusy = false;
 
-	/* Reset own TSF to allow time synchronization work. */
-	drv_reset_tsf(local);
+	if (!netif_running(sdata->dev))
+		return;
 
-	ifmgd->wmm_last_param_set = -1; /* allow any WMM update */
+	if (local->scanning)
+		return;
 
+	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
+		return;
 
-	if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_OPEN)
-		ifmgd->auth_alg = WLAN_AUTH_OPEN;
-	else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY)
-		ifmgd->auth_alg = WLAN_AUTH_SHARED_KEY;
-	else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_LEAP)
-		ifmgd->auth_alg = WLAN_AUTH_LEAP;
-	else if (ifmgd->auth_algs & IEEE80211_AUTH_ALG_FT)
-		ifmgd->auth_alg = WLAN_AUTH_FT;
-	else
-		ifmgd->auth_alg = WLAN_AUTH_OPEN;
-	ifmgd->auth_transaction = -1;
-	ifmgd->flags &= ~IEEE80211_STA_ASSOCIATED;
-	ifmgd->assoc_scan_tries = 0;
-	ifmgd->direct_probe_tries = 0;
-	ifmgd->auth_tries = 0;
-	ifmgd->assoc_tries = 0;
-	netif_tx_stop_all_queues(sdata->dev);
-	netif_carrier_off(sdata->dev);
-}
+	/*
+	 * ieee80211_queue_work() should have picked up most cases,
+	 * here we'll pick the the rest.
+	 */
+	if (WARN(local->suspended, "STA MLME work scheduled while "
+		 "going to suspend\n"))
+		return;
 
-static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_bss *bss;
-	u8 *bssid = ifmgd->bssid, *ssid = ifmgd->ssid;
-	u8 ssid_len = ifmgd->ssid_len;
-	u16 capa_mask = WLAN_CAPABILITY_ESS;
-	u16 capa_val = WLAN_CAPABILITY_ESS;
-	struct ieee80211_channel *chan = local->oper_channel;
+	ifmgd = &sdata->u.mgd;
 
-	if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) &&
-	    ifmgd->flags & (IEEE80211_STA_AUTO_SSID_SEL |
-			    IEEE80211_STA_AUTO_BSSID_SEL |
-			    IEEE80211_STA_AUTO_CHANNEL_SEL)) {
-		capa_mask |= WLAN_CAPABILITY_PRIVACY;
-		if (sdata->default_key)
-			capa_val |= WLAN_CAPABILITY_PRIVACY;
-	}
+	/* first process frames to avoid timing out while a frame is pending */
+	while ((skb = skb_dequeue(&ifmgd->skb_queue)))
+		ieee80211_sta_rx_queued_mgmt(sdata, skb);
+
+	/* then process the rest of the work */
+	mutex_lock(&ifmgd->mtx);
 
-	if (ifmgd->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
-		chan = NULL;
+	if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
+			    IEEE80211_STA_CONNECTION_POLL) &&
+	    ifmgd->associated) {
+		u8 bssid[ETH_ALEN];
 
-	if (ifmgd->flags & IEEE80211_STA_AUTO_BSSID_SEL)
-		bssid = NULL;
+		memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
+		if (time_is_after_jiffies(ifmgd->probe_timeout))
+			run_again(ifmgd, ifmgd->probe_timeout);
 
-	if (ifmgd->flags & IEEE80211_STA_AUTO_SSID_SEL) {
-		ssid = NULL;
-		ssid_len = 0;
+		else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+			printk(KERN_DEBUG "No probe response from AP %pM"
+				" after %dms, try %d\n", bssid,
+				(1000 * IEEE80211_PROBE_WAIT)/HZ,
+				ifmgd->probe_send_count);
+#endif
+			ieee80211_mgd_probe_ap_send(sdata);
+		} else {
+			/*
+			 * We actually lost the connection ... or did we?
+			 * Let's make sure!
+			 */
+			ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+					  IEEE80211_STA_BEACON_POLL);
+			printk(KERN_DEBUG "No probe response from AP %pM"
+				" after %dms, disconnecting.\n",
+				bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
+			ieee80211_set_disassoc(sdata, true);
+			mutex_unlock(&ifmgd->mtx);
+			/*
+			 * must be outside lock due to cfg80211,
+			 * but that's not a problem.
+			 */
+			ieee80211_send_deauth_disassoc(sdata, bssid,
+					IEEE80211_STYPE_DEAUTH,
+					WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+					NULL);
+			mutex_lock(&ifmgd->mtx);
+		}
 	}
 
-	bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan,
-				       bssid, ssid, ssid_len,
-				       capa_mask, capa_val);
 
-	if (bss) {
-		local->oper_channel = bss->cbss.channel;
-		local->oper_channel_type = NL80211_CHAN_NO_HT;
-		ieee80211_hw_config(local, 0);
+	ieee80211_recalc_idle(local);
 
-		if (!(ifmgd->flags & IEEE80211_STA_SSID_SET))
-			ieee80211_sta_set_ssid(sdata, bss->ssid,
-					       bss->ssid_len);
-		ieee80211_sta_set_bssid(sdata, bss->cbss.bssid);
-		ieee80211_sta_def_wmm_params(sdata, bss->supp_rates_len,
-						    bss->supp_rates);
-		if (sdata->u.mgd.mfp == IEEE80211_MFP_REQUIRED)
-			sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
-		else
-			sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
-
-		/* Send out direct probe if no probe resp was received or
-		 * the one we have is outdated
-		 */
-		if (!bss->last_probe_resp ||
-		    time_after(jiffies, bss->last_probe_resp
-					+ IEEE80211_SCAN_RESULT_EXPIRE))
-			ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
-		else
-			ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
+	list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
+		if (time_is_after_jiffies(wk->timeout)) {
+			/*
+			 * This work item isn't supposed to be worked on
+			 * right now, but take care to adjust the timer
+			 * properly.
+			 */
+			run_again(ifmgd, wk->timeout);
+			continue;
+		}
 
-		ieee80211_rx_bss_put(local, bss);
-		ieee80211_sta_reset_auth(sdata);
-		return 0;
-	} else {
-		if (ifmgd->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
+		switch (wk->state) {
+		default:
+			WARN_ON(1);
+			/* fall through */
+		case IEEE80211_MGD_STATE_IDLE:
+			/* nothing */
+			rma = RX_MGMT_NONE;
+			break;
+		case IEEE80211_MGD_STATE_PROBE:
+			rma = ieee80211_direct_probe(sdata, wk);
+			break;
+		case IEEE80211_MGD_STATE_AUTH:
+			rma = ieee80211_authenticate(sdata, wk);
+			break;
+		case IEEE80211_MGD_STATE_ASSOC:
+			rma = ieee80211_associate(sdata, wk);
+			break;
+		}
+
+		switch (rma) {
+		case RX_MGMT_NONE:
+			/* no action required */
+			break;
+		case RX_MGMT_CFG80211_AUTH_TO:
+		case RX_MGMT_CFG80211_ASSOC_TO:
+			list_del(&wk->list);
+			list_add(&wk->list, &free_work);
+			wk->tries = rma; /* small abuse but only local */
+			break;
+		default:
+			WARN(1, "unexpected: %d", rma);
+		}
+	}
 
-			ifmgd->assoc_scan_tries++;
+	list_for_each_entry(wk, &ifmgd->work_list, list) {
+		if (wk->state != IEEE80211_MGD_STATE_IDLE) {
+			anybusy = true;
+			break;
+		}
+	}
+	if (!anybusy &&
+	    test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
+		ieee80211_queue_delayed_work(&local->hw,
+					     &local->scan_work,
+					     round_jiffies_relative(0));
 
-			ieee80211_request_internal_scan(sdata, ifmgd->ssid,
-							ssid_len);
+	mutex_unlock(&ifmgd->mtx);
 
-			ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
-			set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
-		} else {
-			ifmgd->assoc_scan_tries = 0;
-			ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-			ieee80211_recalc_idle(local);
+	list_for_each_entry_safe(wk, tmp, &free_work, list) {
+		switch (wk->tries) {
+		case RX_MGMT_CFG80211_AUTH_TO:
+			cfg80211_send_auth_timeout(sdata->dev,
+						   wk->bss->cbss.bssid);
+			break;
+		case RX_MGMT_CFG80211_ASSOC_TO:
+			cfg80211_send_assoc_timeout(sdata->dev,
+						    wk->bss->cbss.bssid);
+			break;
+		default:
+			WARN(1, "unexpected: %d", wk->tries);
 		}
+
+		list_del(&wk->list);
+		kfree(wk);
 	}
-	return -1;
-}
 
+	ieee80211_recalc_idle(local);
+}
 
-static void ieee80211_sta_work(struct work_struct *work)
+static void ieee80211_sta_bcn_mon_timer(unsigned long data)
 {
 	struct ieee80211_sub_if_data *sdata =
-		container_of(work, struct ieee80211_sub_if_data, u.mgd.work);
+		(struct ieee80211_sub_if_data *) data;
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_if_managed *ifmgd;
-	struct sk_buff *skb;
-
-	if (!netif_running(sdata->dev))
-		return;
 
-	if (local->sw_scanning || local->hw_scanning)
+	if (local->quiescing)
 		return;
 
-	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
-		return;
-
-	/*
-	 * Nothing should have been stuffed into the workqueue during
-	 * the suspend->resume cycle. If this WARN is seen then there
-	 * is a bug with either the driver suspend or something in
-	 * mac80211 stuffing into the workqueue which we haven't yet
-	 * cleared during mac80211's suspend cycle.
-	 */
-	if (WARN_ON(local->suspended))
-		return;
-
-	ifmgd = &sdata->u.mgd;
-
-	while ((skb = skb_dequeue(&ifmgd->skb_queue)))
-		ieee80211_sta_rx_queued_mgmt(sdata, skb);
+	ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work);
+}
 
-	if (ifmgd->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
-	    ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE &&
-	    ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE &&
-	    test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) {
-		queue_delayed_work(local->hw.workqueue, &local->scan_work,
-				   round_jiffies_relative(0));
-		return;
-	}
+static void ieee80211_sta_conn_mon_timer(unsigned long data)
+{
+	struct ieee80211_sub_if_data *sdata =
+		(struct ieee80211_sub_if_data *) data;
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_local *local = sdata->local;
 
-	if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request)) {
-		if (ieee80211_sta_config_auth(sdata))
-			return;
-		clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
-	} else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request))
+	if (local->quiescing)
 		return;
 
-	ieee80211_recalc_idle(local);
-
-	switch (ifmgd->state) {
-	case IEEE80211_STA_MLME_DISABLED:
-		break;
-	case IEEE80211_STA_MLME_DIRECT_PROBE:
-		ieee80211_direct_probe(sdata);
-		break;
-	case IEEE80211_STA_MLME_AUTHENTICATE:
-		ieee80211_authenticate(sdata);
-		break;
-	case IEEE80211_STA_MLME_ASSOCIATE:
-		ieee80211_associate(sdata);
-		break;
-	case IEEE80211_STA_MLME_ASSOCIATED:
-		ieee80211_associated(sdata);
-		break;
-	default:
-		WARN_ON(1);
-		break;
-	}
+	ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
+}
 
-	if (ieee80211_privacy_mismatch(sdata)) {
-		printk(KERN_DEBUG "%s: privacy configuration mismatch and "
-		       "mixed-cell disabled - disassociate\n", sdata->dev->name);
+static void ieee80211_sta_monitor_work(struct work_struct *work)
+{
+	struct ieee80211_sub_if_data *sdata =
+		container_of(work, struct ieee80211_sub_if_data,
+			     u.mgd.monitor_work);
 
-		ieee80211_set_disassoc(sdata, false, true,
-					WLAN_REASON_UNSPECIFIED);
-	}
+	ieee80211_mgd_probe_ap(sdata, false);
 }
 
 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
 {
 	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		/*
-		 * Need to update last_beacon to avoid beacon loss
-		 * test to trigger.
-		 */
-		sdata->u.mgd.last_beacon = jiffies;
-
-
-		queue_work(sdata->local->hw.workqueue,
+		sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL |
+					IEEE80211_STA_CONNECTION_POLL);
+
+		/* let's probe the connection once */
+		ieee80211_queue_work(&sdata->local->hw,
+			   &sdata->u.mgd.monitor_work);
+		/* and do all the other regular work too */
+		ieee80211_queue_work(&sdata->local->hw,
 			   &sdata->u.mgd.work);
 	}
 }
@@ -2378,6 +2274,11 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
 	cancel_work_sync(&ifmgd->chswitch_work);
 	if (del_timer_sync(&ifmgd->chswitch_timer))
 		set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
+
+	cancel_work_sync(&ifmgd->monitor_work);
+	/* these will just be re-established on connection */
+	del_timer_sync(&ifmgd->conn_mon_timer);
+	del_timer_sync(&ifmgd->bcn_mon_timer);
 }
 
 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
@@ -2395,210 +2296,277 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_if_managed *ifmgd;
-	u32 hw_flags;
 
 	ifmgd = &sdata->u.mgd;
 	INIT_WORK(&ifmgd->work, ieee80211_sta_work);
+	INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
 	INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
 	INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work);
 	setup_timer(&ifmgd->timer, ieee80211_sta_timer,
 		    (unsigned long) sdata);
+	setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
+		    (unsigned long) sdata);
+	setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer,
+		    (unsigned long) sdata);
 	setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
 		    (unsigned long) sdata);
 	skb_queue_head_init(&ifmgd->skb_queue);
 
+	INIT_LIST_HEAD(&ifmgd->work_list);
+
 	ifmgd->capab = WLAN_CAPABILITY_ESS;
-	ifmgd->auth_algs = IEEE80211_AUTH_ALG_OPEN |
-		IEEE80211_AUTH_ALG_SHARED_KEY;
-	ifmgd->flags |= IEEE80211_STA_CREATE_IBSS |
-		IEEE80211_STA_AUTO_BSSID_SEL |
-		IEEE80211_STA_AUTO_CHANNEL_SEL;
+	ifmgd->flags = 0;
 	if (sdata->local->hw.queues >= 4)
 		ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
 
-	hw_flags = sdata->local->hw.flags;
-
-	if (hw_flags & IEEE80211_HW_SUPPORTS_PS) {
-		ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE;
-		sdata->local->hw.conf.dynamic_ps_timeout = 500;
-	}
+	mutex_init(&ifmgd->mtx);
 }
 
-/* configuration hooks */
-void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata)
+/* scan finished notification */
+void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
 {
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	struct ieee80211_local *local = sdata->local;
-
-	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
-		return;
-
-	if ((ifmgd->flags & (IEEE80211_STA_BSSID_SET |
-			     IEEE80211_STA_AUTO_BSSID_SEL)) &&
-	    (ifmgd->flags & (IEEE80211_STA_SSID_SET |
-			     IEEE80211_STA_AUTO_SSID_SEL))) {
-
-		if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
-			ieee80211_set_disassoc(sdata, true, true,
-					       WLAN_REASON_DEAUTH_LEAVING);
-
-		if (ifmgd->ssid_len == 0) {
-			/*
-			 * Only allow association to be started if a valid SSID
-			 * is configured.
-			 */
-			return;
-		}
+	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
 
-		if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) ||
-		    ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE)
-			set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
-		else if (ifmgd->flags & IEEE80211_STA_EXT_SME)
-			set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
-		queue_work(local->hw.workqueue, &ifmgd->work);
-	}
+	/* Restart STA timers */
+	rcu_read_lock();
+	list_for_each_entry_rcu(sdata, &local->interfaces, list)
+		ieee80211_restart_sta_timer(sdata);
+	rcu_read_unlock();
 }
 
-int ieee80211_sta_commit(struct ieee80211_sub_if_data *sdata)
+int ieee80211_max_network_latency(struct notifier_block *nb,
+				  unsigned long data, void *dummy)
 {
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	s32 latency_usec = (s32) data;
+	struct ieee80211_local *local =
+		container_of(nb, struct ieee80211_local,
+			     network_latency_notifier);
 
-	if (ifmgd->ssid_len)
-		ifmgd->flags |= IEEE80211_STA_SSID_SET;
-	else
-		ifmgd->flags &= ~IEEE80211_STA_SSID_SET;
+	mutex_lock(&local->iflist_mtx);
+	ieee80211_recalc_ps(local, latency_usec);
+	mutex_unlock(&local->iflist_mtx);
 
 	return 0;
 }
 
-int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
+/* config hooks */
+int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
+		       struct cfg80211_auth_request *req)
 {
-	struct ieee80211_if_managed *ifmgd;
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	const u8 *ssid;
+	struct ieee80211_mgd_work *wk;
+	u16 auth_alg;
 
-	if (len > IEEE80211_MAX_SSID_LEN)
-		return -EINVAL;
+	switch (req->auth_type) {
+	case NL80211_AUTHTYPE_OPEN_SYSTEM:
+		auth_alg = WLAN_AUTH_OPEN;
+		break;
+	case NL80211_AUTHTYPE_SHARED_KEY:
+		auth_alg = WLAN_AUTH_SHARED_KEY;
+		break;
+	case NL80211_AUTHTYPE_FT:
+		auth_alg = WLAN_AUTH_FT;
+		break;
+	case NL80211_AUTHTYPE_NETWORK_EAP:
+		auth_alg = WLAN_AUTH_LEAP;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
 
-	ifmgd = &sdata->u.mgd;
+	wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
+	if (!wk)
+		return -ENOMEM;
 
-	if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) {
-		if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
-			ieee80211_set_disassoc(sdata, true, true,
-					       WLAN_REASON_DEAUTH_LEAVING);
+	wk->bss = (void *)req->bss;
 
-		/*
-		 * Do not use reassociation if SSID is changed (different ESS).
-		 */
-		ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
-		memset(ifmgd->ssid, 0, sizeof(ifmgd->ssid));
-		memcpy(ifmgd->ssid, ssid, len);
-		ifmgd->ssid_len = len;
+	if (req->ie && req->ie_len) {
+		memcpy(wk->ie, req->ie, req->ie_len);
+		wk->ie_len = req->ie_len;
 	}
 
-	return ieee80211_sta_commit(sdata);
-}
+	if (req->key && req->key_len) {
+		wk->key_len = req->key_len;
+		wk->key_idx = req->key_idx;
+		memcpy(wk->key, req->key, req->key_len);
+	}
 
-int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	memcpy(ssid, ifmgd->ssid, ifmgd->ssid_len);
-	*len = ifmgd->ssid_len;
+	ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
+	memcpy(wk->ssid, ssid + 2, ssid[1]);
+	wk->ssid_len = ssid[1];
+
+	wk->state = IEEE80211_MGD_STATE_PROBE;
+	wk->auth_alg = auth_alg;
+	wk->timeout = jiffies; /* run right away */
+
+	/*
+	 * XXX: if still associated need to tell AP that we're going
+	 *	to sleep and then change channel etc.
+	 */
+	sdata->local->oper_channel = req->bss->channel;
+	ieee80211_hw_config(sdata->local, 0);
+
+	mutex_lock(&ifmgd->mtx);
+	list_add(&wk->list, &sdata->u.mgd.work_list);
+	mutex_unlock(&ifmgd->mtx);
+
+	ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
 	return 0;
 }
 
-int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
+int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
+			struct cfg80211_assoc_request *req)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_mgd_work *wk, *found = NULL;
+	int i, err;
 
-	if (compare_ether_addr(bssid, ifmgd->bssid) != 0 &&
-	    ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED)
-		ieee80211_set_disassoc(sdata, true, true,
-				       WLAN_REASON_DEAUTH_LEAVING);
+	mutex_lock(&ifmgd->mtx);
 
-	if (is_valid_ether_addr(bssid)) {
-		memcpy(ifmgd->bssid, bssid, ETH_ALEN);
-		ifmgd->flags |= IEEE80211_STA_BSSID_SET;
-	} else {
-		memset(ifmgd->bssid, 0, ETH_ALEN);
-		ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
+	list_for_each_entry(wk, &ifmgd->work_list, list) {
+		if (&wk->bss->cbss == req->bss &&
+		    wk->state == IEEE80211_MGD_STATE_IDLE) {
+			found = wk;
+			break;
+		}
 	}
 
-	return ieee80211_sta_commit(sdata);
-}
+	if (!found) {
+		err = -ENOLINK;
+		goto out;
+	}
 
-int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
-			       const char *ie, size_t len)
-{
-	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	list_del(&found->list);
 
-	if (len == 0 && ifmgd->extra_ie_len == 0)
-		return -EALREADY;
+	wk = krealloc(found, sizeof(*wk) + req->ie_len, GFP_KERNEL);
+	if (!wk) {
+		list_add(&found->list, &ifmgd->work_list);
+		err = -ENOMEM;
+		goto out;
+	}
 
-	if (len == ifmgd->extra_ie_len && ifmgd->extra_ie &&
-	    memcmp(ifmgd->extra_ie, ie, len) == 0)
-		return -EALREADY;
+	list_add(&wk->list, &ifmgd->work_list);
 
-	kfree(ifmgd->extra_ie);
-	if (len == 0) {
-		ifmgd->extra_ie = NULL;
-		ifmgd->extra_ie_len = 0;
-		return 0;
-	}
-	ifmgd->extra_ie = kmalloc(len, GFP_KERNEL);
-	if (!ifmgd->extra_ie) {
-		ifmgd->extra_ie_len = 0;
-		return -ENOMEM;
+	ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
+
+	for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
+		if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
+		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
+		    req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104)
+			ifmgd->flags |= IEEE80211_STA_DISABLE_11N;
+
+	sdata->local->oper_channel = req->bss->channel;
+	ieee80211_hw_config(sdata->local, 0);
+
+	if (req->ie && req->ie_len) {
+		memcpy(wk->ie, req->ie, req->ie_len);
+		wk->ie_len = req->ie_len;
+	} else
+		wk->ie_len = 0;
+
+	if (req->prev_bssid)
+		memcpy(wk->prev_bssid, req->prev_bssid, ETH_ALEN);
+
+	wk->state = IEEE80211_MGD_STATE_ASSOC;
+	wk->tries = 0;
+	wk->timeout = jiffies; /* run right away */
+
+	if (req->use_mfp) {
+		ifmgd->mfp = IEEE80211_MFP_REQUIRED;
+		ifmgd->flags |= IEEE80211_STA_MFP_ENABLED;
+	} else {
+		ifmgd->mfp = IEEE80211_MFP_DISABLED;
+		ifmgd->flags &= ~IEEE80211_STA_MFP_ENABLED;
 	}
-	memcpy(ifmgd->extra_ie, ie, len);
-	ifmgd->extra_ie_len = len;
-	return 0;
-}
 
-int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
-{
-	printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
-	       sdata->dev->name, reason);
+	if (req->crypto.control_port)
+		ifmgd->flags |= IEEE80211_STA_CONTROL_PORT;
+	else
+		ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
 
-	ieee80211_set_disassoc(sdata, true, true, reason);
-	return 0;
+	ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
+
+	err = 0;
+
+ out:
+	mutex_unlock(&ifmgd->mtx);
+	return err;
 }
 
-int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
+int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
+			 struct cfg80211_deauth_request *req,
+			 void *cookie)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+	struct ieee80211_mgd_work *wk;
+	const u8 *bssid = NULL;
 
-	printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
-	       sdata->dev->name, reason);
+	printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
+	       sdata->dev->name, req->reason_code);
+
+	mutex_lock(&ifmgd->mtx);
+
+	if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
+		bssid = req->bss->bssid;
+		ieee80211_set_disassoc(sdata, true);
+	} else list_for_each_entry(wk, &ifmgd->work_list, list) {
+		if (&wk->bss->cbss == req->bss) {
+			bssid = req->bss->bssid;
+			list_del(&wk->list);
+			kfree(wk);
+			break;
+		}
+	}
 
-	if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED))
+	/*
+	 * cfg80211 should catch this ... but it's racy since
+	 * we can receive a deauth frame, process it, hand it
+	 * to cfg80211 while that's in a locked section already
+	 * trying to tell us that the user wants to disconnect.
+	 */
+	if (!bssid) {
+		mutex_unlock(&ifmgd->mtx);
 		return -ENOLINK;
+	}
+
+	mutex_unlock(&ifmgd->mtx);
+
+	ieee80211_send_deauth_disassoc(sdata, bssid,
+			IEEE80211_STYPE_DEAUTH, req->reason_code,
+			cookie);
 
-	ieee80211_set_disassoc(sdata, false, true, reason);
 	return 0;
 }
 
-/* scan finished notification */
-void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
+int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
+			   struct cfg80211_disassoc_request *req,
+			   void *cookie)
 {
-	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
-	/* Restart STA timers */
-	rcu_read_lock();
-	list_for_each_entry_rcu(sdata, &local->interfaces, list)
-		ieee80211_restart_sta_timer(sdata);
-	rcu_read_unlock();
-}
+	printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
+	       sdata->dev->name, req->reason_code);
 
-int ieee80211_max_network_latency(struct notifier_block *nb,
-				  unsigned long data, void *dummy)
-{
-	s32 latency_usec = (s32) data;
-	struct ieee80211_local *local =
-		container_of(nb, struct ieee80211_local,
-			     network_latency_notifier);
+	mutex_lock(&ifmgd->mtx);
 
-	mutex_lock(&local->iflist_mtx);
-	ieee80211_recalc_ps(local, latency_usec);
-	mutex_unlock(&local->iflist_mtx);
+	/*
+	 * cfg80211 should catch this ... but it's racy since
+	 * we can receive a disassoc frame, process it, hand it
+	 * to cfg80211 while that's in a locked section already
+	 * trying to tell us that the user wants to disconnect.
+	 */
+	if (&ifmgd->associated->cbss != req->bss) {
+		mutex_unlock(&ifmgd->mtx);
+		return -ENOLINK;
+	}
+
+	ieee80211_set_disassoc(sdata, false);
+
+	mutex_unlock(&ifmgd->mtx);
 
+	ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
+			IEEE80211_STYPE_DISASSOC, req->reason_code,
+			cookie);
 	return 0;
 }
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 5e3d476..e535f1c 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -26,7 +26,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
 	/* make quiescing visible to timers everywhere */
 	mb();
 
-	flush_workqueue(local->hw.workqueue);
+	flush_workqueue(local->workqueue);
 
 	/* Don't try to run timers while suspended. */
 	del_timer_sync(&local->sta_cleanup);
@@ -96,6 +96,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
 		if (!netif_running(sdata->dev))
 			continue;
 
+		/* disable beaconing */
+		ieee80211_bss_info_change_notify(sdata,
+			BSS_CHANGED_BEACON_ENABLED);
+
 		conf.vif = &sdata->vif;
 		conf.type = sdata->vif.type;
 		conf.mac_addr = sdata->dev->dev_addr;
@@ -103,17 +107,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
 	}
 
 	/* stop hardware - this must stop RX */
-	if (local->open_count) {
-		ieee80211_led_radio(local, false);
-		drv_stop(local);
-	}
-
-	/*
-	 * flush again, in case driver queued work -- it
-	 * shouldn't be doing (or cancel everything in the
-	 * stop callback) that but better safe than sorry.
-	 */
-	flush_workqueue(local->hw.workqueue);
+	if (local->open_count)
+		ieee80211_stop_device(local);
 
 	local->suspended = true;
 	/* need suspended to be visible before quiescing is false */
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 4641f00..b33efc4 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -198,6 +198,35 @@ static void rate_control_release(struct kref *kref)
 	kfree(ctrl_ref);
 }
 
+static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc)
+{
+	struct sk_buff *skb = txrc->skb;
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	__le16 fc;
+
+	fc = hdr->frame_control;
+
+	return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc));
+}
+
+bool rate_control_send_low(struct ieee80211_sta *sta,
+			   void *priv_sta,
+			   struct ieee80211_tx_rate_control *txrc)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
+
+	if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) {
+		info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta);
+		info->control.rates[0].count =
+			(info->flags & IEEE80211_TX_CTL_NO_ACK) ?
+			1 : txrc->hw->max_rate_tries;
+		return true;
+	}
+	return false;
+}
+EXPORT_SYMBOL(rate_control_send_low);
+
 void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
 			   struct sta_info *sta,
 			   struct ieee80211_tx_rate_control *txrc)
@@ -258,7 +287,7 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
 	struct rate_control_ref *ref, *old;
 
 	ASSERT_RTNL();
-	if (local->open_count || netif_running(local->mdev))
+	if (local->open_count)
 		return -EBUSY;
 
 	ref = rate_control_alloc(name, local);
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 37771ab..6e5d68b 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -70,20 +70,6 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
 	return i;
 }
 
-static inline bool
-use_low_rate(struct sk_buff *skb)
-{
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	u16 fc;
-
-	fc = le16_to_cpu(hdr->frame_control);
-
-	return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
-		(fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA);
-}
-
-
 static void
 minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
 {
@@ -232,7 +218,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
 		  void *priv_sta, struct ieee80211_tx_rate_control *txrc)
 {
 	struct sk_buff *skb = txrc->skb;
-	struct ieee80211_supported_band *sband = txrc->sband;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct minstrel_sta_info *mi = priv_sta;
 	struct minstrel_priv *mp = priv;
@@ -245,14 +230,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
 	int mrr_ndx[3];
 	int sample_rate;
 
-	if (!sta || !mi || use_low_rate(skb)) {
-		ar[0].idx = rate_lowest_index(sband, sta);
-		if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-			ar[0].count = 1;
-		else
-			ar[0].count = mp->max_retry;
+	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
-	}
 
 	mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
 
@@ -439,7 +418,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
 
 			/* contention window */
 			tx_time_single += t_slot + min(cw, mp->cw_max);
-			cw = (cw + 1) << 1;
+			cw = (cw << 1) | 1;
 
 			tx_time += tx_time_single;
 			tx_time_cts += tx_time_single + mi->sp_ack_dur;
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
index 869fe0e..38bf416 100644
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -33,7 +33,6 @@ struct minstrel_rate {
 
 	/* per-rate throughput */
 	u32 cur_tp;
-	u32 throughput;
 
 	u64 succ_hist;
 	u64 att_hist;
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
index 98f4807..a715d94 100644
--- a/net/mac80211/rc80211_minstrel_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -83,7 +83,7 @@ minstrel_stats_open(struct inode *inode, struct file *file)
 		p += sprintf(p, "%3u%s", mr->bitrate / 2,
 				(mr->bitrate & 1 ? ".5" : "  "));
 
-		tp = ((mr->cur_tp * 96) / 18000) >> 10;
+		tp = mr->cur_tp / ((18000 << 10) / 96);
 		prob = mr->cur_prob / 18;
 		eprob = mr->probability / 18;
 
@@ -139,7 +139,7 @@ minstrel_stats_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
-static struct file_operations minstrel_stat_fops = {
+static const struct file_operations minstrel_stat_fops = {
 	.owner = THIS_MODULE,
 	.open = minstrel_stats_open,
 	.read = minstrel_stats_read,
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index a0bef76..699d3ed 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -169,19 +169,9 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
 	 * still a good measurement and copy it. */
 	if (unlikely(spinfo->tx_num_xmit == 0))
 		pf = spinfo->last_pf;
-	else {
-		/* XXX: BAD HACK!!! */
-		struct sta_info *si = container_of(sta, struct sta_info, sta);
-
+	else
 		pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
 
-		if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100)
-			mesh_plink_broken(si);
-		pf <<= RC_PID_ARITH_SHIFT;
-		si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
-					>> RC_PID_ARITH_SHIFT;
-	}
-
 	spinfo->tx_num_xmit = 0;
 	spinfo->tx_num_failed = 0;
 
@@ -276,11 +266,9 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
 {
 	struct sk_buff *skb = txrc->skb;
 	struct ieee80211_supported_band *sband = txrc->sband;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct rc_pid_sta_info *spinfo = priv_sta;
 	int rateidx;
-	u16 fc;
 
 	if (txrc->rts)
 		info->control.rates[0].count =
@@ -290,16 +278,8 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
 			txrc->hw->conf.short_frame_max_tx_count;
 
 	/* Send management frames and NO_ACK data using lowest rate. */
-	fc = le16_to_cpu(hdr->frame_control);
-	if (!sta || !spinfo ||
-	    (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-	    info->flags & IEEE80211_TX_CTL_NO_ACK) {
-		info->control.rates[0].idx = rate_lowest_index(sband, sta);
-		if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-			info->control.rates[0].count = 1;
-
+	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
-	}
 
 	rateidx = spinfo->txrate_idx;
 
@@ -321,7 +301,6 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
 	struct rc_pid_sta_info *spinfo = priv_sta;
 	struct rc_pid_info *pinfo = priv;
 	struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
-	struct sta_info *si;
 	int i, j, tmp;
 	bool s;
 
@@ -358,9 +337,6 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
 	}
 
 	spinfo->txrate_idx = rate_lowest_index(sband, sta);
-	/* HACK */
-	si = container_of(sta, struct sta_info, sta);
-	si->fail_avg = 0;
 }
 
 static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index a08a9b5..a59043f 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -198,7 +198,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
 
 #undef RC_PID_PRINT_BUF_SIZE
 
-static struct file_operations rc_pid_fop_events = {
+static const struct file_operations rc_pid_fop_events = {
 	.owner = THIS_MODULE,
 	.read = rate_control_pid_events_read,
 	.poll = rate_control_pid_events_poll,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 0936fc2..c01588f 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -30,7 +30,6 @@
 static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 					   struct tid_ampdu_rx *tid_agg_rx,
 					   struct sk_buff *skb,
-					   struct ieee80211_rx_status *status,
 					   u16 mpdu_seq_num,
 					   int bar_req);
 /*
@@ -59,11 +58,11 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
 	return skb;
 }
 
-static inline int should_drop_frame(struct ieee80211_rx_status *status,
-				    struct sk_buff *skb,
+static inline int should_drop_frame(struct sk_buff *skb,
 				    int present_fcs_len,
 				    int radiotap_len)
 {
+	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 
 	if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
@@ -111,10 +110,10 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local,
 static void
 ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
 				 struct sk_buff *skb,
-				 struct ieee80211_rx_status *status,
 				 struct ieee80211_rate *rate,
 				 int rtap_len)
 {
+	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_radiotap_header *rthdr;
 	unsigned char *pos;
 
@@ -220,9 +219,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
  */
 static struct sk_buff *
 ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
-		     struct ieee80211_rx_status *status,
 		     struct ieee80211_rate *rate)
 {
+	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
 	struct ieee80211_sub_if_data *sdata;
 	int needed_headroom = 0;
 	struct sk_buff *skb, *skb2;
@@ -248,8 +247,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 		present_fcs_len = FCS_LEN;
 
 	if (!local->monitors) {
-		if (should_drop_frame(status, origskb, present_fcs_len,
-				      rtap_len)) {
+		if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
 			dev_kfree_skb(origskb);
 			return NULL;
 		}
@@ -257,7 +255,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 		return remove_monitor_info(local, origskb, rtap_len);
 	}
 
-	if (should_drop_frame(status, origskb, present_fcs_len, rtap_len)) {
+	if (should_drop_frame(origskb, present_fcs_len, rtap_len)) {
 		/* only need to expand headroom if necessary */
 		skb = origskb;
 		origskb = NULL;
@@ -289,7 +287,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 
 	/* if necessary, prepend radiotap information */
 	if (!(status->flag & RX_FLAG_RADIOTAP))
-		ieee80211_add_rx_radiotap_header(local, skb, status, rate,
+		ieee80211_add_rx_radiotap_header(local, skb, rate,
 						 needed_headroom);
 
 	skb_reset_mac_header(skb);
@@ -420,13 +418,13 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
 	struct ieee80211_local *local = rx->local;
 	struct sk_buff *skb = rx->skb;
 
-	if (unlikely(local->hw_scanning))
-		return ieee80211_scan_rx(rx->sdata, skb, rx->status);
+	if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning)))
+		return ieee80211_scan_rx(rx->sdata, skb);
 
-	if (unlikely(local->sw_scanning)) {
+	if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) &&
+		     (rx->flags & IEEE80211_RX_IN_SCAN))) {
 		/* drop all the other packets during a software scan anyway */
-		if (ieee80211_scan_rx(rx->sdata, skb, rx->status)
-		    != RX_QUEUED)
+		if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
 			dev_kfree_skb(skb);
 		return RX_QUEUED;
 	}
@@ -491,12 +489,21 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
 	unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control);
+	char *dev_addr = rx->dev->dev_addr;
 
 	if (ieee80211_is_data(hdr->frame_control)) {
-		if (!ieee80211_has_a4(hdr->frame_control))
-			return RX_DROP_MONITOR;
-		if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0)
-			return RX_DROP_MONITOR;
+		if (is_multicast_ether_addr(hdr->addr1)) {
+			if (ieee80211_has_tods(hdr->frame_control) ||
+				!ieee80211_has_fromds(hdr->frame_control))
+				return RX_DROP_MONITOR;
+			if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0)
+				return RX_DROP_MONITOR;
+		} else {
+			if (!ieee80211_has_a4(hdr->frame_control))
+				return RX_DROP_MONITOR;
+			if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0)
+				return RX_DROP_MONITOR;
+		}
 	}
 
 	/* If there is not an established peer link and this is not a peer link
@@ -529,7 +536,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
 
 	if (ieee80211_is_data(hdr->frame_control) &&
 	    is_multicast_ether_addr(hdr->addr1) &&
-	    mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->sdata))
+	    mesh_rmc_check(hdr->addr3, msh_h_get(hdr, hdrlen), rx->sdata))
 		return RX_DROP_MONITOR;
 #undef msh_h_get
 
@@ -785,7 +792,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
 	struct ieee80211_local *local = sdata->local;
 
 	atomic_inc(&sdata->bss->num_sta_ps);
-	set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
+	set_sta_flags(sta, WLAN_STA_PS);
 	drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta);
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
 	printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
@@ -801,7 +808,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
 
 	atomic_dec(&sdata->bss->num_sta_ps);
 
-	clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
+	clear_sta_flags(sta, WLAN_STA_PS);
 	drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
 
 	if (!skb_queue_empty(&sta->ps_tx_buf))
@@ -836,28 +843,22 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 	if (!sta)
 		return RX_CONTINUE;
 
-	/* Update last_rx only for IBSS packets which are for the current
-	 * BSSID to avoid keeping the current IBSS network alive in cases where
-	 * other STAs are using different BSSID. */
+	/*
+	 * Update last_rx only for IBSS packets which are for the current
+	 * BSSID to avoid keeping the current IBSS network alive in cases
+	 * where other STAs start using different BSSID.
+	 */
 	if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
 		u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
 						NL80211_IFTYPE_ADHOC);
 		if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0)
 			sta->last_rx = jiffies;
-	} else
-	if (!is_multicast_ether_addr(hdr->addr1) ||
-	    rx->sdata->vif.type == NL80211_IFTYPE_STATION) {
-		/* Update last_rx only for unicast frames in order to prevent
-		 * the Probe Request frames (the only broadcast frames from a
-		 * STA in infrastructure mode) from keeping a connection alive.
+	} else if (!is_multicast_ether_addr(hdr->addr1)) {
+		/*
 		 * Mesh beacons will update last_rx when if they are found to
 		 * match the current local configuration when processed.
 		 */
-		if (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
-		    ieee80211_is_beacon(hdr->frame_control)) {
-			rx->sdata->u.mgd.last_beacon = jiffies;
-		} else
-			sta->last_rx = jiffies;
+		sta->last_rx = jiffies;
 	}
 
 	if (!(rx->flags & IEEE80211_RX_RA_MATCH))
@@ -1125,14 +1126,15 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
 		skb_queue_empty(&rx->sta->ps_tx_buf);
 
 	if (skb) {
+		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 		struct ieee80211_hdr *hdr =
 			(struct ieee80211_hdr *) skb->data;
 
 		/*
-		 * Tell TX path to send one frame even though the STA may
+		 * Tell TX path to send this frame even though the STA may
 		 * still remain is PS mode after this frame exchange.
 		 */
-		set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
+		info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE;
 
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
 		printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n",
@@ -1147,7 +1149,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
 		else
 			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
 
-		dev_queue_xmit(skb);
+		ieee80211_add_pending_skb(rx->local, skb);
 
 		if (no_pending_pkts)
 			sta_info_clear_tim_bit(rx->sta);
@@ -1487,10 +1489,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 	struct ieee80211s_hdr *mesh_hdr;
 	unsigned int hdrlen;
 	struct sk_buff *skb = rx->skb, *fwd_skb;
+	struct ieee80211_local *local = rx->local;
+	struct ieee80211_sub_if_data *sdata;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 	mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
+	sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
 
 	if (!ieee80211_is_data(hdr->frame_control))
 		return RX_CONTINUE;
@@ -1499,11 +1504,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 		/* illegal frame */
 		return RX_DROP_MONITOR;
 
-	if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
-		struct ieee80211_sub_if_data *sdata;
+	if (!is_multicast_ether_addr(hdr->addr1) &&
+			(mesh_hdr->flags & MESH_FLAGS_AE_A5_A6)) {
 		struct mesh_path *mppath;
 
-		sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
 		rcu_read_lock();
 		mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
 		if (!mppath) {
@@ -1518,7 +1522,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 		rcu_read_unlock();
 	}
 
-	if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0)
+	/* Frame has reached destination.  Don't forward */
+	if (!is_multicast_ether_addr(hdr->addr1) &&
+			compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0)
 		return RX_CONTINUE;
 
 	mesh_hdr->ttl--;
@@ -1529,6 +1535,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 						     dropped_frames_ttl);
 		else {
 			struct ieee80211_hdr *fwd_hdr;
+			struct ieee80211_tx_info *info;
+
 			fwd_skb = skb_copy(skb, GFP_ATOMIC);
 
 			if (!fwd_skb && net_ratelimit())
@@ -1536,19 +1544,40 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 						   rx->dev->name);
 
 			fwd_hdr =  (struct ieee80211_hdr *) fwd_skb->data;
-			/*
-			 * Save TA to addr1 to send TA a path error if a
-			 * suitable next hop is not found
-			 */
-			memcpy(fwd_hdr->addr1, fwd_hdr->addr2, ETH_ALEN);
 			memcpy(fwd_hdr->addr2, rx->dev->dev_addr, ETH_ALEN);
-			fwd_skb->dev = rx->local->mdev;
-			fwd_skb->iif = rx->dev->ifindex;
-			dev_queue_xmit(fwd_skb);
+			info = IEEE80211_SKB_CB(fwd_skb);
+			memset(info, 0, sizeof(*info));
+			info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+			info->control.vif = &rx->sdata->vif;
+			ieee80211_select_queue(local, fwd_skb);
+			if (is_multicast_ether_addr(fwd_hdr->addr1))
+				IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+								fwded_mcast);
+			else {
+				int err;
+				/*
+				 * Save TA to addr1 to send TA a path error if a
+				 * suitable next hop is not found
+				 */
+				memcpy(fwd_hdr->addr1, fwd_hdr->addr2,
+						ETH_ALEN);
+				err = mesh_nexthop_lookup(fwd_skb, sdata);
+				/* Failed to immediately resolve next hop:
+				 * fwded frame was dropped or will be added
+				 * later to the pending skb queue.  */
+				if (err)
+					return RX_DROP_MONITOR;
+
+				IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+								fwded_unicast);
+			}
+			IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
+						     fwded_frames);
+			ieee80211_add_pending_skb(local, fwd_skb);
 		}
 	}
 
-	if (is_multicast_ether_addr(hdr->addr3) ||
+	if (is_multicast_ether_addr(hdr->addr1) ||
 	    rx->dev->flags & IFF_PROMISC)
 		return RX_CONTINUE;
 	else
@@ -1620,7 +1649,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
 		/* manage reordering buffer according to requested */
 		/* sequence number */
 		rcu_read_lock();
-		ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, NULL,
+		ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL,
 						 start_seq_num, 1);
 		rcu_read_unlock();
 		return RX_DROP_UNUSABLE;
@@ -1644,12 +1673,7 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
 
 	if (compare_ether_addr(mgmt->sa, sdata->u.mgd.bssid) != 0 ||
 	    compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid) != 0) {
-		/* Not from the current AP. */
-		return;
-	}
-
-	if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATE) {
-		/* Association in progress; ignore SA Query */
+		/* Not from the current AP or not associated yet. */
 		return;
 	}
 
@@ -1686,7 +1710,6 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 	struct ieee80211_local *local = rx->local;
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
-	struct ieee80211_bss *bss;
 	int len = rx->skb->len;
 
 	if (!ieee80211_is_action(mgmt->frame_control))
@@ -1764,17 +1787,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
 			if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))
 				return RX_DROP_MONITOR;
 
-			bss = ieee80211_rx_bss_get(local, sdata->u.mgd.bssid,
-					   local->hw.conf.channel->center_freq,
-					   sdata->u.mgd.ssid,
-					   sdata->u.mgd.ssid_len);
-			if (!bss)
-				return RX_DROP_MONITOR;
-
-			ieee80211_sta_process_chanswitch(sdata,
-				     &mgmt->u.action.u.chan_switch.sw_elem, bss);
-			ieee80211_rx_bss_put(local, bss);
-			break;
+			return ieee80211_sta_rx_mgmt(sdata, rx->skb);
 		}
 		break;
 	case WLAN_CATEGORY_SA_QUERY:
@@ -1817,19 +1830,18 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
 		return RX_DROP_MONITOR;
 
 	if (ieee80211_vif_is_mesh(&sdata->vif))
-		return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status);
+		return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
 
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return ieee80211_ibss_rx_mgmt(sdata, rx->skb, rx->status);
+		return ieee80211_ibss_rx_mgmt(sdata, rx->skb);
 
 	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		return ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status);
+		return ieee80211_sta_rx_mgmt(sdata, rx->skb);
 
 	return RX_DROP_MONITOR;
 }
 
-static void ieee80211_rx_michael_mic_report(struct net_device *dev,
-					    struct ieee80211_hdr *hdr,
+static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr,
 					    struct ieee80211_rx_data *rx)
 {
 	int keyidx;
@@ -1866,7 +1878,8 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
 	    !ieee80211_is_auth(hdr->frame_control))
 		goto ignore;
 
-	mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL);
+	mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL,
+					GFP_ATOMIC);
  ignore:
 	dev_kfree_skb(rx->skb);
 	rx->skb = NULL;
@@ -2028,13 +2041,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
 	case NL80211_IFTYPE_STATION:
 		if (!bssid)
 			return 0;
-		if (!ieee80211_bssid_match(bssid, sdata->u.mgd.bssid)) {
-			if (!(rx->flags & IEEE80211_RX_IN_SCAN))
-				return 0;
-			rx->flags &= ~IEEE80211_RX_RA_MATCH;
-		} else if (!multicast &&
-			   compare_ether_addr(sdata->dev->dev_addr,
-					      hdr->addr1) != 0) {
+		if (!multicast &&
+		    compare_ether_addr(sdata->dev->dev_addr, hdr->addr1) != 0) {
 			if (!(sdata->dev->flags & IFF_PROMISC))
 				return 0;
 			rx->flags &= ~IEEE80211_RX_RA_MATCH;
@@ -2114,9 +2122,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
  */
 static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 					 struct sk_buff *skb,
-					 struct ieee80211_rx_status *status,
 					 struct ieee80211_rate *rate)
 {
+	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_hdr *hdr;
@@ -2143,11 +2151,12 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
 	}
 
 	if ((status->flag & RX_FLAG_MMIC_ERROR)) {
-		ieee80211_rx_michael_mic_report(local->mdev, hdr, &rx);
+		ieee80211_rx_michael_mic_report(hdr, &rx);
 		return;
 	}
 
-	if (unlikely(local->sw_scanning || local->hw_scanning))
+	if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
+		     test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
 		rx.flags |= IEEE80211_RX_IN_SCAN;
 
 	ieee80211_parse_qos(&rx);
@@ -2227,20 +2236,21 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
 {
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_rate *rate;
-	struct ieee80211_rx_status status;
+	struct sk_buff *skb = tid_agg_rx->reorder_buf[index];
+	struct ieee80211_rx_status *status;
 
-	if (!tid_agg_rx->reorder_buf[index])
+	if (!skb)
 		goto no_frame;
 
+	status = IEEE80211_SKB_RXCB(skb);
+
 	/* release the reordered frames to stack */
-	memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status));
-	sband = hw->wiphy->bands[status.band];
-	if (status.flag & RX_FLAG_HT)
+	sband = hw->wiphy->bands[status->band];
+	if (status->flag & RX_FLAG_HT)
 		rate = sband->bitrates; /* TODO: HT rates */
 	else
-		rate = &sband->bitrates[status.rate_idx];
-	__ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
-				     &status, rate);
+		rate = &sband->bitrates[status->rate_idx];
+	__ieee80211_rx_handle_packet(hw, skb, rate);
 	tid_agg_rx->stored_mpdu_num--;
 	tid_agg_rx->reorder_buf[index] = NULL;
 
@@ -2265,7 +2275,6 @@ no_frame:
 static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 					   struct tid_ampdu_rx *tid_agg_rx,
 					   struct sk_buff *skb,
-					   struct ieee80211_rx_status *rxstatus,
 					   u16 mpdu_seq_num,
 					   int bar_req)
 {
@@ -2324,8 +2333,6 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 	/* put the frame in the reordering buffer */
 	tid_agg_rx->reorder_buf[index] = skb;
 	tid_agg_rx->reorder_time[index] = jiffies;
-	memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
-	       sizeof(*rxstatus));
 	tid_agg_rx->stored_mpdu_num++;
 	/* release the buffer until next missing frame */
 	index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
@@ -2374,8 +2381,7 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 }
 
 static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
-				     struct sk_buff *skb,
-				     struct ieee80211_rx_status *status)
+				     struct sk_buff *skb)
 {
 	struct ieee80211_hw *hw = &local->hw;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -2424,7 +2430,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
 
 	/* according to mpdu sequence number deal with reordering buffer */
 	mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
-	ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, status,
+	ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb,
 						mpdu_seq_num, 0);
  end_reorder:
 	return ret;
@@ -2434,24 +2440,20 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
  * This is the receive path handler. It is called by a low level driver when an
  * 802.11 MPDU is received from the hardware.
  */
-void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
-		    struct ieee80211_rx_status *status)
+void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct ieee80211_rate *rate = NULL;
 	struct ieee80211_supported_band *sband;
+	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
 
-	if (status->band < 0 ||
-	    status->band >= IEEE80211_NUM_BANDS) {
-		WARN_ON(1);
-		return;
-	}
+	if (WARN_ON(status->band < 0 ||
+		    status->band >= IEEE80211_NUM_BANDS))
+		goto drop;
 
 	sband = local->hw.wiphy->bands[status->band];
-	if (!sband) {
-		WARN_ON(1);
-		return;
-	}
+	if (WARN_ON(!sband))
+		goto drop;
 
 	/*
 	 * If we're suspending, it is possible although not too likely
@@ -2460,16 +2462,21 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 * that might, for example, cause stations to be added or other
 	 * driver callbacks be invoked.
 	 */
-	if (unlikely(local->quiescing || local->suspended)) {
-		kfree_skb(skb);
-		return;
-	}
+	if (unlikely(local->quiescing || local->suspended))
+		goto drop;
+
+	/*
+	 * The same happens when we're not even started,
+	 * but that's worth a warning.
+	 */
+	if (WARN_ON(!local->started))
+		goto drop;
 
 	if (status->flag & RX_FLAG_HT) {
 		/* rate_idx is MCS index */
 		if (WARN_ON(status->rate_idx < 0 ||
 			    status->rate_idx >= 76))
-			return;
+			goto drop;
 		/* HT rates are not in the table - use the highest legacy rate
 		 * for now since other parts of mac80211 may not yet be fully
 		 * MCS aware. */
@@ -2477,7 +2484,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	} else {
 		if (WARN_ON(status->rate_idx < 0 ||
 			    status->rate_idx >= sband->n_bitrates))
-			return;
+			goto drop;
 		rate = &sband->bitrates[status->rate_idx];
 	}
 
@@ -2494,7 +2501,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 * if it was previously present.
 	 * Also, frames with less than 16 bytes are dropped.
 	 */
-	skb = ieee80211_rx_monitor(local, skb, status, rate);
+	skb = ieee80211_rx_monitor(local, skb, rate);
 	if (!skb) {
 		rcu_read_unlock();
 		return;
@@ -2512,25 +2519,25 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 * frames from other than operational channel), but that should not
 	 * happen in normal networks.
 	 */
-	if (!ieee80211_rx_reorder_ampdu(local, skb, status))
-		__ieee80211_rx_handle_packet(hw, skb, status, rate);
+	if (!ieee80211_rx_reorder_ampdu(local, skb))
+		__ieee80211_rx_handle_packet(hw, skb, rate);
 
 	rcu_read_unlock();
+
+	return;
+ drop:
+	kfree_skb(skb);
 }
-EXPORT_SYMBOL(__ieee80211_rx);
+EXPORT_SYMBOL(ieee80211_rx);
 
 /* This is a version of the rx handler that can be called from hard irq
  * context. Post the skb on the queue and schedule the tasklet */
-void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb,
-			  struct ieee80211_rx_status *status)
+void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 
 	BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb));
 
-	skb->dev = local->mdev;
-	/* copy status into skb->cb for use by tasklet */
-	memcpy(skb->cb, status, sizeof(*status));
 	skb->pkt_type = IEEE80211_RX_MSG;
 	skb_queue_tail(&local->skb_queue, skb);
 	tasklet_schedule(&local->tasklet);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 2a8d09a..0399011 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -18,7 +18,6 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <net/mac80211.h>
-#include <net/iw_handler.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
@@ -26,7 +25,7 @@
 
 #define IEEE80211_PROBE_DELAY (HZ / 33)
 #define IEEE80211_CHANNEL_TIME (HZ / 33)
-#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
+#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 8)
 
 struct ieee80211_bss *
 ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
@@ -121,23 +120,10 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
 	return bss;
 }
 
-void ieee80211_rx_bss_remove(struct ieee80211_sub_if_data *sdata, u8 *bssid,
-			     int freq, u8 *ssid, u8 ssid_len)
-{
-	struct ieee80211_bss *bss;
-	struct ieee80211_local *local = sdata->local;
-
-	bss = ieee80211_rx_bss_get(local, bssid, freq, ssid, ssid_len);
-	if (bss) {
-		cfg80211_unlink_bss(local->hw.wiphy, (void *)bss);
-		ieee80211_rx_bss_put(local, bss);
-	}
-}
-
 ieee80211_rx_result
-ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-		  struct ieee80211_rx_status *rx_status)
+ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 {
+	struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_mgmt *mgmt;
 	struct ieee80211_bss *bss;
 	u8 *elements;
@@ -278,7 +264,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
 
 	mutex_lock(&local->scan_mtx);
 
-	if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) {
+	if (WARN_ON(!local->scanning)) {
 		mutex_unlock(&local->scan_mtx);
 		return;
 	}
@@ -288,16 +274,16 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
 		return;
 	}
 
-	if (local->hw_scanning)
+	if (test_bit(SCAN_HW_SCANNING, &local->scanning))
 		ieee80211_restore_scan_ies(local);
 
-	if (local->scan_req != &local->int_scan_req)
+	if (local->scan_req != local->int_scan_req)
 		cfg80211_scan_done(local->scan_req, aborted);
 	local->scan_req = NULL;
+	local->scan_sdata = NULL;
 
-	was_hw_scan = local->hw_scanning;
-	local->hw_scanning = false;
-	local->sw_scanning = false;
+	was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
+	local->scanning = 0;
 	local->scan_channel = NULL;
 
 	/* we only have to protect scan_req and hw/sw scan */
@@ -307,16 +293,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
 	if (was_hw_scan)
 		goto done;
 
-	netif_tx_lock_bh(local->mdev);
-	netif_addr_lock(local->mdev);
-	local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
-	drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
-			     &local->filter_flags,
-			     local->mdev->mc_count,
-			     local->mdev->mc_list);
-
-	netif_addr_unlock(local->mdev);
-	netif_tx_unlock_bh(local->mdev);
+	ieee80211_configure_filter(local);
 
 	drv_sw_scan_complete(local);
 
@@ -327,7 +304,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
 
 		/* Tell AP we're back */
 		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-			if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
+			if (sdata->u.mgd.associated) {
 				ieee80211_scan_ps_disable(sdata);
 				netif_tx_wake_all_queues(sdata->dev);
 			}
@@ -382,30 +359,24 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
 			ieee80211_bss_info_change_notify(
 				sdata, BSS_CHANGED_BEACON_ENABLED);
 
-		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-			if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
-				netif_tx_stop_all_queues(sdata->dev);
-				ieee80211_scan_ps_enable(sdata);
-			}
-		} else
+		/*
+		 * only handle non-STA interfaces here, STA interfaces
+		 * are handled in the scan state machine
+		 */
+		if (sdata->vif.type != NL80211_IFTYPE_STATION)
 			netif_tx_stop_all_queues(sdata->dev);
 	}
 	mutex_unlock(&local->iflist_mtx);
 
-	local->scan_state = SCAN_SET_CHANNEL;
+	local->next_scan_state = SCAN_DECISION;
 	local->scan_channel_idx = 0;
 
-	netif_addr_lock_bh(local->mdev);
-	local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
-	drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
-			     &local->filter_flags,
-			     local->mdev->mc_count,
-			     local->mdev->mc_list);
-	netif_addr_unlock_bh(local->mdev);
+	ieee80211_configure_filter(local);
 
 	/* TODO: start scan as soon as all nullfunc frames are ACKed */
-	queue_delayed_work(local->hw.workqueue, &local->scan_work,
-			   IEEE80211_CHANNEL_TIME);
+	ieee80211_queue_delayed_work(&local->hw,
+				     &local->scan_work,
+				     IEEE80211_CHANNEL_TIME);
 
 	return 0;
 }
@@ -441,20 +412,18 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	local->scan_req = req;
 	local->scan_sdata = sdata;
 
-	if (req != &local->int_scan_req &&
+	if (req != local->int_scan_req &&
 	    sdata->vif.type == NL80211_IFTYPE_STATION &&
-	    (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE ||
-	     ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
-	     ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE)) {
-		/* actually wait for the assoc to finish/time out */
+	    !list_empty(&ifmgd->work_list)) {
+		/* actually wait for the work it's doing to finish/time out */
 		set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
 		return 0;
 	}
 
 	if (local->ops->hw_scan)
-		local->hw_scanning = true;
+		__set_bit(SCAN_HW_SCANNING, &local->scanning);
 	else
-		local->sw_scanning = true;
+		__set_bit(SCAN_SW_SCANNING, &local->scanning);
 	/*
 	 * Kicking off the scan need not be protected,
 	 * only the scan variable stuff, since now
@@ -477,11 +446,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	mutex_lock(&local->scan_mtx);
 
 	if (rc) {
-		if (local->ops->hw_scan) {
-			local->hw_scanning = false;
+		if (local->ops->hw_scan)
 			ieee80211_restore_scan_ies(local);
-		} else
-			local->sw_scanning = false;
+		local->scanning = 0;
 
 		ieee80211_recalc_idle(local);
 
@@ -492,13 +459,195 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
 	return rc;
 }
 
+static int ieee80211_scan_state_decision(struct ieee80211_local *local,
+					 unsigned long *next_delay)
+{
+	bool associated = false;
+	struct ieee80211_sub_if_data *sdata;
+
+	/* if no more bands/channels left, complete scan and advance to the idle state */
+	if (local->scan_channel_idx >= local->scan_req->n_channels) {
+		ieee80211_scan_completed(&local->hw, false);
+		return 1;
+	}
+
+	/* check if at least one STA interface is associated */
+	mutex_lock(&local->iflist_mtx);
+	list_for_each_entry(sdata, &local->interfaces, list) {
+		if (!netif_running(sdata->dev))
+			continue;
+
+		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+			if (sdata->u.mgd.associated) {
+				associated = true;
+				break;
+			}
+		}
+	}
+	mutex_unlock(&local->iflist_mtx);
+
+	if (local->scan_channel) {
+		/*
+		 * we're currently scanning a different channel, let's
+		 * switch back to the operating channel now if at least
+		 * one interface is associated. Otherwise just scan the
+		 * next channel
+		 */
+		if (associated)
+			local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
+		else
+			local->next_scan_state = SCAN_SET_CHANNEL;
+	} else {
+		/*
+		 * we're on the operating channel currently, let's
+		 * leave that channel now to scan another one
+		 */
+		local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
+	}
+
+	*next_delay = 0;
+	return 0;
+}
+
+static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
+						    unsigned long *next_delay)
+{
+	struct ieee80211_sub_if_data *sdata;
+
+	/*
+	 * notify the AP about us leaving the channel and stop all STA interfaces
+	 */
+	mutex_lock(&local->iflist_mtx);
+	list_for_each_entry(sdata, &local->interfaces, list) {
+		if (!netif_running(sdata->dev))
+			continue;
+
+		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+			netif_tx_stop_all_queues(sdata->dev);
+			if (sdata->u.mgd.associated)
+				ieee80211_scan_ps_enable(sdata);
+		}
+	}
+	mutex_unlock(&local->iflist_mtx);
+
+	__set_bit(SCAN_OFF_CHANNEL, &local->scanning);
+
+	/* advance to the next channel to be scanned */
+	*next_delay = HZ / 10;
+	local->next_scan_state = SCAN_SET_CHANNEL;
+}
+
+static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local,
+						    unsigned long *next_delay)
+{
+	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+
+	/* switch back to the operating channel */
+	local->scan_channel = NULL;
+	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+
+	/*
+	 * notify the AP about us being back and restart all STA interfaces
+	 */
+	mutex_lock(&local->iflist_mtx);
+	list_for_each_entry(sdata, &local->interfaces, list) {
+		if (!netif_running(sdata->dev))
+			continue;
+
+		/* Tell AP we're back */
+		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+			if (sdata->u.mgd.associated)
+				ieee80211_scan_ps_disable(sdata);
+			netif_tx_wake_all_queues(sdata->dev);
+		}
+	}
+	mutex_unlock(&local->iflist_mtx);
+
+	__clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
+
+	*next_delay = HZ / 5;
+	local->next_scan_state = SCAN_DECISION;
+}
+
+static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
+					     unsigned long *next_delay)
+{
+	int skip;
+	struct ieee80211_channel *chan;
+	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+
+	skip = 0;
+	chan = local->scan_req->channels[local->scan_channel_idx];
+
+	if (chan->flags & IEEE80211_CHAN_DISABLED ||
+	    (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
+	     chan->flags & IEEE80211_CHAN_NO_IBSS))
+		skip = 1;
+
+	if (!skip) {
+		local->scan_channel = chan;
+		if (ieee80211_hw_config(local,
+					IEEE80211_CONF_CHANGE_CHANNEL))
+			skip = 1;
+	}
+
+	/* advance state machine to next channel/band */
+	local->scan_channel_idx++;
+
+	if (skip) {
+		/* if we skip this channel return to the decision state */
+		local->next_scan_state = SCAN_DECISION;
+		return;
+	}
+
+	/*
+	 * Probe delay is used to update the NAV, cf. 11.1.3.2.2
+	 * (which unfortunately doesn't say _why_ step a) is done,
+	 * but it waits for the probe delay or until a frame is
+	 * received - and the received frame would update the NAV).
+	 * For now, we do not support waiting until a frame is
+	 * received.
+	 *
+	 * In any case, it is not necessary for a passive scan.
+	 */
+	if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+	    !local->scan_req->n_ssids) {
+		*next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+		local->next_scan_state = SCAN_DECISION;
+		return;
+	}
+
+	/* active scan, send probes */
+	*next_delay = IEEE80211_PROBE_DELAY;
+	local->next_scan_state = SCAN_SEND_PROBE;
+}
+
+static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
+					    unsigned long *next_delay)
+{
+	int i;
+	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
+
+	for (i = 0; i < local->scan_req->n_ssids; i++)
+		ieee80211_send_probe_req(
+			sdata, NULL,
+			local->scan_req->ssids[i].ssid,
+			local->scan_req->ssids[i].ssid_len,
+			local->scan_req->ie, local->scan_req->ie_len);
+
+	/*
+	 * After sending probe requests, wait for probe responses
+	 * on the channel.
+	 */
+	*next_delay = IEEE80211_CHANNEL_TIME;
+	local->next_scan_state = SCAN_DECISION;
+}
+
 void ieee80211_scan_work(struct work_struct *work)
 {
 	struct ieee80211_local *local =
 		container_of(work, struct ieee80211_local, scan_work.work);
 	struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-	struct ieee80211_channel *chan;
-	int skip, i;
 	unsigned long next_delay = 0;
 
 	mutex_lock(&local->scan_mtx);
@@ -507,11 +656,12 @@ void ieee80211_scan_work(struct work_struct *work)
 		return;
 	}
 
-	if (local->scan_req && !(local->sw_scanning || local->hw_scanning)) {
+	if (local->scan_req && !local->scanning) {
 		struct cfg80211_scan_request *req = local->scan_req;
 		int rc;
 
 		local->scan_req = NULL;
+		local->scan_sdata = NULL;
 
 		rc = __ieee80211_start_scan(sdata, req);
 		mutex_unlock(&local->scan_mtx);
@@ -531,72 +681,32 @@ void ieee80211_scan_work(struct work_struct *work)
 		return;
 	}
 
-	switch (local->scan_state) {
-	case SCAN_SET_CHANNEL:
-		/* if no more bands/channels left, complete scan */
-		if (local->scan_channel_idx >= local->scan_req->n_channels) {
-			ieee80211_scan_completed(&local->hw, false);
-			return;
-		}
-		skip = 0;
-		chan = local->scan_req->channels[local->scan_channel_idx];
-
-		if (chan->flags & IEEE80211_CHAN_DISABLED ||
-		    (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
-		     chan->flags & IEEE80211_CHAN_NO_IBSS))
-			skip = 1;
-
-		if (!skip) {
-			local->scan_channel = chan;
-			if (ieee80211_hw_config(local,
-						IEEE80211_CONF_CHANGE_CHANNEL))
-				skip = 1;
-		}
-
-		/* advance state machine to next channel/band */
-		local->scan_channel_idx++;
-
-		if (skip)
+	/*
+	 * as long as no delay is required advance immediately
+	 * without scheduling a new work
+	 */
+	do {
+		switch (local->next_scan_state) {
+		case SCAN_DECISION:
+			if (ieee80211_scan_state_decision(local, &next_delay))
+				return;
 			break;
-
-		/*
-		 * Probe delay is used to update the NAV, cf. 11.1.3.2.2
-		 * (which unfortunately doesn't say _why_ step a) is done,
-		 * but it waits for the probe delay or until a frame is
-		 * received - and the received frame would update the NAV).
-		 * For now, we do not support waiting until a frame is
-		 * received.
-		 *
-		 * In any case, it is not necessary for a passive scan.
-		 */
-		if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
-		    !local->scan_req->n_ssids) {
-			next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+		case SCAN_SET_CHANNEL:
+			ieee80211_scan_state_set_channel(local, &next_delay);
+			break;
+		case SCAN_SEND_PROBE:
+			ieee80211_scan_state_send_probe(local, &next_delay);
+			break;
+		case SCAN_LEAVE_OPER_CHANNEL:
+			ieee80211_scan_state_leave_oper_channel(local, &next_delay);
+			break;
+		case SCAN_ENTER_OPER_CHANNEL:
+			ieee80211_scan_state_enter_oper_channel(local, &next_delay);
 			break;
 		}
+	} while (next_delay == 0);
 
-		next_delay = IEEE80211_PROBE_DELAY;
-		local->scan_state = SCAN_SEND_PROBE;
-		break;
-	case SCAN_SEND_PROBE:
-		for (i = 0; i < local->scan_req->n_ssids; i++)
-			ieee80211_send_probe_req(
-				sdata, NULL,
-				local->scan_req->ssids[i].ssid,
-				local->scan_req->ssids[i].ssid_len,
-				local->scan_req->ie, local->scan_req->ie_len);
-
-		/*
-		 * After sending probe requests, wait for probe responses
-		 * on the channel.
-		 */
-		next_delay = IEEE80211_CHANNEL_TIME;
-		local->scan_state = SCAN_SET_CHANNEL;
-		break;
-	}
-
-	queue_delayed_work(local->hw.workqueue, &local->scan_work,
-			   next_delay);
+	ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
 }
 
 int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
@@ -623,10 +733,10 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
 	if (local->scan_req)
 		goto unlock;
 
-	memcpy(local->int_scan_req.ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
-	local->int_scan_req.ssids[0].ssid_len = ssid_len;
+	memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
+	local->int_scan_req->ssids[0].ssid_len = ssid_len;
 
-	ret = __ieee80211_start_scan(sdata, &sdata->local->int_scan_req);
+	ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
  unlock:
 	mutex_unlock(&local->scan_mtx);
 	return ret;
@@ -634,7 +744,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
 
 void ieee80211_scan_cancel(struct ieee80211_local *local)
 {
-	bool swscan;
+	bool abortscan;
 
 	cancel_delayed_work_sync(&local->scan_work);
 
@@ -643,9 +753,10 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
 	 * queued -- mostly at suspend under RTNL.
 	 */
 	mutex_lock(&local->scan_mtx);
-	swscan = local->sw_scanning;
+	abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+		    (!local->scanning && local->scan_req);
 	mutex_unlock(&local->scan_mtx);
 
-	if (swscan)
+	if (abortscan)
 		ieee80211_scan_completed(&local->hw, true);
 }
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index a360bce..eec0014 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -349,6 +349,7 @@ int sta_info_insert(struct sta_info *sta)
 		goto out_free;
 	}
 	list_add(&sta->list, &local->sta_list);
+	local->sta_generation++;
 	local->num_sta++;
 	sta_info_hash_add(local, sta);
 
@@ -485,6 +486,7 @@ static void __sta_info_unlink(struct sta_info **sta)
 	}
 
 	local->num_sta--;
+	local->sta_generation++;
 
 	if (local->ops->sta_notify) {
 		if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 49a1a1f..ccc3adf 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -30,7 +30,6 @@
  * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
  * @WLAN_STA_WME: Station is a QoS-STA.
  * @WLAN_STA_WDS: Station is one of our WDS peers.
- * @WLAN_STA_PSPOLL: Station has just PS-polled us.
  * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
  *	IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
  *	frame to this station is transmitted.
@@ -47,7 +46,6 @@ enum ieee80211_sta_info_flags {
 	WLAN_STA_ASSOC_AP	= 1<<5,
 	WLAN_STA_WME		= 1<<6,
 	WLAN_STA_WDS		= 1<<7,
-	WLAN_STA_PSPOLL		= 1<<8,
 	WLAN_STA_CLEAR_PS_FILT	= 1<<9,
 	WLAN_STA_MFP		= 1<<10,
 	WLAN_STA_SUSPEND	= 1<<11
@@ -308,6 +306,23 @@ struct sta_info {
 		struct dentry *inactive_ms;
 		struct dentry *last_seq_ctrl;
 		struct dentry *agg_status;
+		struct dentry *aid;
+		struct dentry *dev;
+		struct dentry *rx_packets;
+		struct dentry *tx_packets;
+		struct dentry *rx_bytes;
+		struct dentry *tx_bytes;
+		struct dentry *rx_duplicates;
+		struct dentry *rx_fragments;
+		struct dentry *rx_dropped;
+		struct dentry *tx_fragments;
+		struct dentry *tx_filtered;
+		struct dentry *tx_retry_failed;
+		struct dentry *tx_retry_count;
+		struct dentry *last_signal;
+		struct dentry *last_qual;
+		struct dentry *last_noise;
+		struct dentry *wep_weak_iv_count;
 		bool add_has_run;
 	} debugfs;
 #endif
@@ -342,17 +357,6 @@ static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
 	spin_unlock_irqrestore(&sta->flaglock, irqfl);
 }
 
-static inline void set_and_clear_sta_flags(struct sta_info *sta,
-					   const u32 set, const u32 clear)
-{
-	unsigned long irqfl;
-
-	spin_lock_irqsave(&sta->flaglock, irqfl);
-	sta->flags |= set;
-	sta->flags &= ~clear;
-	spin_unlock_irqrestore(&sta->flaglock, irqfl);
-}
-
 static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
 {
 	u32 ret;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3a8922c..5143d20 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -192,7 +192,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
 	if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
 		return TX_CONTINUE;
 
-	if (unlikely(tx->local->sw_scanning) &&
+	if (unlikely(test_bit(SCAN_OFF_CHANNEL, &tx->local->scanning)) &&
 	    !ieee80211_is_probe_req(hdr->frame_control) &&
 	    !ieee80211_is_nullfunc(hdr->frame_control))
 		/*
@@ -317,30 +317,30 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
 	if (!atomic_read(&tx->sdata->bss->num_sta_ps))
 		return TX_CONTINUE;
 
+	/* buffered in hardware */
+	if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) {
+		info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
+
+		return TX_CONTINUE;
+	}
+
 	/* buffered in mac80211 */
-	if (tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) {
-		if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
-			purge_old_ps_buffers(tx->local);
-		if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >=
-		    AP_MAX_BC_BUFFER) {
+	if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
+		purge_old_ps_buffers(tx->local);
+
+	if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) {
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-			if (net_ratelimit()) {
-				printk(KERN_DEBUG "%s: BC TX buffer full - "
-				       "dropping the oldest frame\n",
-				       tx->dev->name);
-			}
+		if (net_ratelimit())
+			printk(KERN_DEBUG "%s: BC TX buffer full - dropping the oldest frame\n",
+			       tx->dev->name);
 #endif
-			dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf));
-		} else
-			tx->local->total_ps_buffered++;
-		skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb);
-		return TX_QUEUED;
-	}
+		dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf));
+	} else
+		tx->local->total_ps_buffered++;
 
-	/* buffered in hardware */
-	info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
+	skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb);
 
-	return TX_CONTINUE;
+	return TX_QUEUED;
 }
 
 static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
@@ -373,7 +373,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
 	staflags = get_sta_flags(sta);
 
 	if (unlikely((staflags & WLAN_STA_PS) &&
-		     !(staflags & WLAN_STA_PSPOLL))) {
+		     !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) {
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
 		printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries "
 		       "before %d)\n",
@@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
 			sta_info_set_tim_bit(sta);
 
 		info->control.jiffies = jiffies;
+		info->control.vif = &tx->sdata->vif;
 		info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 		skb_queue_tail(&sta->ps_tx_buf, tx->skb);
 		return TX_QUEUED;
@@ -411,24 +412,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
 		       sta->sta.addr);
 	}
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
-	if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
-		/*
-		 * The sleeping station with pending data is now snoozing.
-		 * It queried us for its buffered frames and will go back
-		 * to deep sleep once it got everything.
-		 *
-		 * inform the driver, in case the hardware does powersave
-		 * frame filtering and keeps a station  blacklist on its own
-		 * (e.g: p54), so that frames can be delivered unimpeded.
-		 *
-		 * Note: It should be safe to disable the filter now.
-		 * As, it is really unlikely that we still have any pending
-		 * frame for this station in the hw's buffers/fifos left,
-		 * that is not rejected with a unsuccessful tx_status yet.
-		 */
 
-		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
-	}
 	return TX_CONTINUE;
 }
 
@@ -451,7 +435,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
 
-	if (unlikely(tx->skb->do_not_encrypt))
+	if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
 		tx->key = NULL;
 	else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
 		tx->key = key;
@@ -497,7 +481,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
 	}
 
 	if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
-		tx->skb->do_not_encrypt = 1;
+		info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
 
 	return TX_CONTINUE;
 }
@@ -512,6 +496,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 	int i, len;
 	bool inval = false, rts = false, short_preamble = false;
 	struct ieee80211_tx_rate_control txrc;
+	u32 sta_flags;
 
 	memset(&txrc, 0, sizeof(txrc));
 
@@ -544,7 +529,26 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
 	     (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
 		txrc.short_preamble = short_preamble = true;
 
+	sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
+
+	/*
+	 * Lets not bother rate control if we're associated and cannot
+	 * talk to the sta. This should not happen.
+	 */
+	if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) &&
+		 (sta_flags & WLAN_STA_ASSOC) &&
+		 !rate_usable_index_exists(sband, &tx->sta->sta),
+		 "%s: Dropped data frame as no usable bitrate found while "
+		 "scanning and associated. Target station: "
+		 "%pM on %d GHz band\n",
+		 tx->dev->name, hdr->addr1,
+		 tx->channel->band ? 5 : 2))
+		return TX_DROP;
 
+	/*
+	 * If we're associated with the sta at this point we know we can at
+	 * least send the frame at the lowest bit rate.
+	 */
 	rate_control_get_rate(tx->sdata, tx->sta, &txrc);
 
 	if (unlikely(info->control.rates[0].idx < 0))
@@ -676,7 +680,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
 	 * number, if we have no matching interface then we
 	 * neither assign one ourselves nor ask the driver to.
 	 */
-	if (unlikely(!info->control.vif))
+	if (unlikely(info->control.vif->type == NL80211_IFTYPE_MONITOR))
 		return TX_CONTINUE;
 
 	if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
@@ -696,7 +700,6 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
 		/* for pure STA mode without beacons, we can do it */
 		hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number);
 		tx->sdata->sequence_number += 0x10;
-		tx->sdata->sequence_number &= IEEE80211_SCTL_SEQ;
 		return TX_CONTINUE;
 	}
 
@@ -754,9 +757,7 @@ static int ieee80211_fragment(struct ieee80211_local *local,
 		memcpy(tmp->cb, skb->cb, sizeof(tmp->cb));
 		skb_copy_queue_mapping(tmp, skb);
 		tmp->priority = skb->priority;
-		tmp->do_not_encrypt = skb->do_not_encrypt;
 		tmp->dev = skb->dev;
-		tmp->iif = skb->iif;
 
 		/* copy header and data */
 		memcpy(skb_put(tmp, hdrlen), skb->data, hdrlen);
@@ -784,7 +785,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
 
 	/*
 	 * Warn when submitting a fragmented A-MPDU frame and drop it.
-	 * This scenario is handled in __ieee80211_tx_prepare but extra
+	 * This scenario is handled in ieee80211_tx_prepare but extra
 	 * caution taken here as fragmented ampdu may cause Tx stop.
 	 */
 	if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
@@ -842,6 +843,23 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
 }
 
 static ieee80211_tx_result debug_noinline
+ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
+{
+	struct sk_buff *skb = tx->skb;
+
+	if (!tx->sta)
+		return TX_CONTINUE;
+
+	tx->sta->tx_packets++;
+	do {
+		tx->sta->tx_fragments++;
+		tx->sta->tx_bytes += skb->len;
+	} while ((skb = skb->next));
+
+	return TX_CONTINUE;
+}
+
+static ieee80211_tx_result debug_noinline
 ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
 {
 	if (!tx->key)
@@ -885,23 +903,6 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
 	return TX_CONTINUE;
 }
 
-static ieee80211_tx_result debug_noinline
-ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
-{
-	struct sk_buff *skb = tx->skb;
-
-	if (!tx->sta)
-		return TX_CONTINUE;
-
-	tx->sta->tx_packets++;
-	do {
-		tx->sta->tx_fragments++;
-		tx->sta->tx_bytes += skb->len;
-	} while ((skb = skb->next));
-
-	return TX_CONTINUE;
-}
-
 /* actual transmit path */
 
 /*
@@ -923,11 +924,12 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
 	struct ieee80211_radiotap_header *rthdr =
 		(struct ieee80211_radiotap_header *) skb->data;
 	struct ieee80211_supported_band *sband;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
 
 	sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
-	skb->do_not_encrypt = 1;
+	info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
 	tx->flags &= ~IEEE80211_TX_FRAGMENTED;
 
 	/*
@@ -965,7 +967,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
 				skb_trim(skb, skb->len - FCS_LEN);
 			}
 			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
-				tx->skb->do_not_encrypt = 0;
+				info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
 			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
 				tx->flags |= IEEE80211_TX_FRAGMENTED;
 			break;
@@ -998,13 +1000,12 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
  * initialises @tx
  */
 static ieee80211_tx_result
-__ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
-		       struct sk_buff *skb,
-		       struct net_device *dev)
+ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
+		     struct ieee80211_tx_data *tx,
+		     struct sk_buff *skb)
 {
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_hdr *hdr;
-	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	int hdrlen, tid;
 	u8 *qc, *state;
@@ -1012,9 +1013,9 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 
 	memset(tx, 0, sizeof(*tx));
 	tx->skb = skb;
-	tx->dev = dev; /* use original interface */
+	tx->dev = sdata->dev; /* use original interface */
 	tx->local = local;
-	tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	tx->sdata = sdata;
 	tx->channel = local->hw.conf.channel;
 	/*
 	 * Set this flag (used below to indicate "automatic fragmentation"),
@@ -1023,7 +1024,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 	tx->flags |= IEEE80211_TX_FRAGMENTED;
 
 	/* process and remove the injection radiotap header */
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
 		if (!__ieee80211_parse_tx_radiotap(tx, skb))
 			return TX_DROP;
@@ -1075,6 +1075,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 		} else if (*state != HT_AGG_STATE_IDLE) {
 			/* in progress */
 			queued = true;
+			info->control.vif = &sdata->vif;
 			info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
 			__skb_queue_tail(&tid_tx->pending, skb);
 		}
@@ -1119,50 +1120,29 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 	return TX_CONTINUE;
 }
 
-/*
- * NB: @tx is uninitialised when passed in here
- */
-static int ieee80211_tx_prepare(struct ieee80211_local *local,
-				struct ieee80211_tx_data *tx,
-				struct sk_buff *skb)
-{
-	struct net_device *dev;
-
-	dev = dev_get_by_index(&init_net, skb->iif);
-	if (unlikely(dev && !is_ieee80211_device(local, dev))) {
-		dev_put(dev);
-		dev = NULL;
-	}
-	if (unlikely(!dev))
-		return -ENODEV;
-	/*
-	 * initialises tx with control
-	 *
-	 * return value is safe to ignore here because this function
-	 * can only be invoked for multicast frames
-	 *
-	 * XXX: clean up
-	 */
-	__ieee80211_tx_prepare(tx, skb, dev);
-	dev_put(dev);
-	return 0;
-}
-
 static int __ieee80211_tx(struct ieee80211_local *local,
 			  struct sk_buff **skbp,
-			  struct sta_info *sta)
+			  struct sta_info *sta,
+			  bool txpending)
 {
 	struct sk_buff *skb = *skbp, *next;
 	struct ieee80211_tx_info *info;
+	struct ieee80211_sub_if_data *sdata;
+	unsigned long flags;
 	int ret, len;
 	bool fragm = false;
 
-	local->mdev->trans_start = jiffies;
-
 	while (skb) {
-		if (ieee80211_queue_stopped(&local->hw,
-					    skb_get_queue_mapping(skb)))
-			return IEEE80211_TX_PENDING;
+		int q = skb_get_queue_mapping(skb);
+
+		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+		ret = IEEE80211_TX_OK;
+		if (local->queue_stop_reasons[q] ||
+		    (!txpending && !skb_queue_empty(&local->pending[q])))
+			ret = IEEE80211_TX_PENDING;
+		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+		if (ret != IEEE80211_TX_OK)
+			return ret;
 
 		info = IEEE80211_SKB_CB(skb);
 
@@ -1172,13 +1152,35 @@ static int __ieee80211_tx(struct ieee80211_local *local,
 
 		next = skb->next;
 		len = skb->len;
+
+		if (next)
+			info->flags |= IEEE80211_TX_CTL_MORE_FRAMES;
+
+		sdata = vif_to_sdata(info->control.vif);
+
+		switch (sdata->vif.type) {
+		case NL80211_IFTYPE_MONITOR:
+			info->control.vif = NULL;
+			break;
+		case NL80211_IFTYPE_AP_VLAN:
+			info->control.vif = &container_of(sdata->bss,
+				struct ieee80211_sub_if_data, u.ap)->vif;
+			break;
+		default:
+			/* keep */
+			break;
+		}
+
 		ret = drv_tx(local, skb);
 		if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
 			dev_kfree_skb(skb);
 			ret = NETDEV_TX_OK;
 		}
-		if (ret != NETDEV_TX_OK)
+		if (ret != NETDEV_TX_OK) {
+			info->control.vif = &sdata->vif;
 			return IEEE80211_TX_AGAIN;
+		}
+
 		*skbp = skb = next;
 		ieee80211_led_tx(local, 1);
 		fragm = true;
@@ -1210,9 +1212,9 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
 	CALL_TXH(ieee80211_tx_h_sequence)
 	CALL_TXH(ieee80211_tx_h_fragment)
 	/* handlers after fragment must be aware of tx info fragmentation! */
+	CALL_TXH(ieee80211_tx_h_stats)
 	CALL_TXH(ieee80211_tx_h_encrypt)
 	CALL_TXH(ieee80211_tx_h_calculate_duration)
-	CALL_TXH(ieee80211_tx_h_stats)
 #undef CALL_TXH
 
  txh_done:
@@ -1234,10 +1236,10 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
 	return 0;
 }
 
-static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
-			 bool txpending)
+static void ieee80211_tx(struct ieee80211_sub_if_data *sdata,
+			 struct sk_buff *skb, bool txpending)
 {
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_tx_data tx;
 	ieee80211_tx_result res_prepare;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1248,8 +1250,6 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 
 	queue = skb_get_queue_mapping(skb);
 
-	WARN_ON(!txpending && !skb_queue_empty(&local->pending[queue]));
-
 	if (unlikely(skb->len < 10)) {
 		dev_kfree_skb(skb);
 		return;
@@ -1258,7 +1258,7 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 	rcu_read_lock();
 
 	/* initialises tx */
-	res_prepare = __ieee80211_tx_prepare(&tx, skb, dev);
+	res_prepare = ieee80211_tx_prepare(sdata, &tx, skb);
 
 	if (unlikely(res_prepare == TX_DROP)) {
 		dev_kfree_skb(skb);
@@ -1277,7 +1277,7 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 
 	retries = 0;
  retry:
-	ret = __ieee80211_tx(local, &tx.skb, tx.sta);
+	ret = __ieee80211_tx(local, &tx.skb, tx.sta, txpending);
 	switch (ret) {
 	case IEEE80211_TX_OK:
 		break;
@@ -1295,34 +1295,35 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 
 		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 
-		if (__netif_subqueue_stopped(local->mdev, queue)) {
+		if (local->queue_stop_reasons[queue] ||
+		    !skb_queue_empty(&local->pending[queue])) {
+			/*
+			 * if queue is stopped, queue up frames for later
+			 * transmission from the tasklet
+			 */
 			do {
 				next = skb->next;
 				skb->next = NULL;
 				if (unlikely(txpending))
-					skb_queue_head(&local->pending[queue],
-						       skb);
+					__skb_queue_head(&local->pending[queue],
+							 skb);
 				else
-					skb_queue_tail(&local->pending[queue],
-						       skb);
+					__skb_queue_tail(&local->pending[queue],
+							 skb);
 			} while ((skb = next));
 
-			/*
-			 * Make sure nobody will enable the queue on us
-			 * (without going through the tasklet) nor disable the
-			 * netdev queue underneath the pending handling code.
-			 */
-			__set_bit(IEEE80211_QUEUE_STOP_REASON_PENDING,
-				  &local->queue_stop_reasons[queue]);
-
 			spin_unlock_irqrestore(&local->queue_stop_reason_lock,
 					       flags);
 		} else {
+			/*
+			 * otherwise retry, but this is a race condition or
+			 * a driver bug (which we warn about if it persists)
+			 */
 			spin_unlock_irqrestore(&local->queue_stop_reason_lock,
 					       flags);
 
 			retries++;
-			if (WARN(retries > 10, "tx refused but queue active"))
+			if (WARN(retries > 10, "tx refused but queue active\n"))
 				goto drop;
 			goto retry;
 		}
@@ -1383,44 +1384,25 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
 	return 0;
 }
 
-int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
+			   struct sk_buff *skb)
 {
-	struct ieee80211_master_priv *mpriv = netdev_priv(dev);
-	struct ieee80211_local *local = mpriv->local;
+	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-	struct net_device *odev = NULL;
-	struct ieee80211_sub_if_data *osdata;
+	struct ieee80211_sub_if_data *tmp_sdata;
 	int headroom;
 	bool may_encrypt;
-	enum {
-		NOT_MONITOR,
-		FOUND_SDATA,
-		UNKNOWN_ADDRESS,
-	} monitor_iface = NOT_MONITOR;
-
-	if (skb->iif)
-		odev = dev_get_by_index(&init_net, skb->iif);
-	if (unlikely(odev && !is_ieee80211_device(local, odev))) {
-		dev_put(odev);
-		odev = NULL;
-	}
-	if (unlikely(!odev)) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-		printk(KERN_DEBUG "%s: Discarded packet with nonexistent "
-		       "originating device\n", dev->name);
-#endif
-		dev_kfree_skb(skb);
-		return NETDEV_TX_OK;
-	}
+
+	dev_hold(sdata->dev);
 
 	if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
 	    local->hw.conf.dynamic_ps_timeout > 0 &&
-	    !local->sw_scanning && !local->hw_scanning && local->ps_sdata) {
+	    !(local->scanning) && local->ps_sdata) {
 		if (local->hw.conf.flags & IEEE80211_CONF_PS) {
 			ieee80211_stop_queues_by_reason(&local->hw,
 					IEEE80211_QUEUE_STOP_REASON_PS);
-			queue_work(local->hw.workqueue,
+			ieee80211_queue_work(&local->hw,
 					&local->dynamic_ps_disable_work);
 		}
 
@@ -1428,31 +1410,13 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		        msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
 	}
 
-	memset(info, 0, sizeof(*info));
-
 	info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
 
-	osdata = IEEE80211_DEV_TO_SUB_IF(odev);
-
-	if (ieee80211_vif_is_mesh(&osdata->vif) &&
-	    ieee80211_is_data(hdr->frame_control)) {
-		if (is_multicast_ether_addr(hdr->addr3))
-			memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
-		else
-			if (mesh_nexthop_lookup(skb, osdata)) {
-				dev_put(odev);
-				return NETDEV_TX_OK;
-			}
-		if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
-			IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
-							    fwded_frames);
-	} else if (unlikely(osdata->vif.type == NL80211_IFTYPE_MONITOR)) {
-		struct ieee80211_sub_if_data *sdata;
+	if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
 		int hdrlen;
 		u16 len_rthdr;
 
 		info->flags |= IEEE80211_TX_CTL_INJECTED;
-		monitor_iface = UNKNOWN_ADDRESS;
 
 		len_rthdr = ieee80211_get_radiotap_len(skb->data);
 		hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
@@ -1471,20 +1435,17 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			 */
 
 			rcu_read_lock();
-			list_for_each_entry_rcu(sdata, &local->interfaces,
+			list_for_each_entry_rcu(tmp_sdata, &local->interfaces,
 						list) {
-				if (!netif_running(sdata->dev))
+				if (!netif_running(tmp_sdata->dev))
 					continue;
-				if (sdata->vif.type != NL80211_IFTYPE_AP)
+				if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
 					continue;
-				if (compare_ether_addr(sdata->dev->dev_addr,
+				if (compare_ether_addr(tmp_sdata->dev->dev_addr,
 						       hdr->addr2)) {
-					dev_hold(sdata->dev);
-					dev_put(odev);
-					osdata = sdata;
-					odev = osdata->dev;
-					skb->iif = sdata->dev->ifindex;
-					monitor_iface = FOUND_SDATA;
+					dev_hold(tmp_sdata->dev);
+					dev_put(sdata->dev);
+					sdata = tmp_sdata;
 					break;
 				}
 			}
@@ -1492,40 +1453,44 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
-	may_encrypt = !skb->do_not_encrypt;
+	may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
 
-	headroom = osdata->local->tx_headroom;
+	headroom = local->tx_headroom;
 	if (may_encrypt)
 		headroom += IEEE80211_ENCRYPT_HEADROOM;
 	headroom -= skb_headroom(skb);
 	headroom = max_t(int, 0, headroom);
 
-	if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) {
+	if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) {
 		dev_kfree_skb(skb);
-		dev_put(odev);
-		return NETDEV_TX_OK;
+		dev_put(sdata->dev);
+		return;
 	}
 
-	if (osdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-		osdata = container_of(osdata->bss,
-				      struct ieee80211_sub_if_data,
-				      u.ap);
-	if (likely(monitor_iface != UNKNOWN_ADDRESS))
-		info->control.vif = &osdata->vif;
+	info->control.vif = &sdata->vif;
 
-	ieee80211_tx(odev, skb, false);
-	dev_put(odev);
+	if (ieee80211_vif_is_mesh(&sdata->vif) &&
+	    ieee80211_is_data(hdr->frame_control) &&
+		!is_multicast_ether_addr(hdr->addr1))
+			if (mesh_nexthop_lookup(skb, sdata)) {
+				/* skb queued: don't free */
+				dev_put(sdata->dev);
+				return;
+			}
 
-	return NETDEV_TX_OK;
+	ieee80211_select_queue(local, skb);
+	ieee80211_tx(sdata, skb, false);
+	dev_put(sdata->dev);
 }
 
-int ieee80211_monitor_start_xmit(struct sk_buff *skb,
-				 struct net_device *dev)
+netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
+					 struct net_device *dev)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_channel *chan = local->hw.conf.channel;
 	struct ieee80211_radiotap_header *prthdr =
 		(struct ieee80211_radiotap_header *)skb->data;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	u16 len_rthdr;
 
 	/*
@@ -1563,15 +1528,6 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
 	if (unlikely(skb->len < len_rthdr))
 		goto fail; /* skb too short for claimed rt header extent */
 
-	skb->dev = local->mdev;
-
-	/* needed because we set skb device to master */
-	skb->iif = dev->ifindex;
-
-	/* sometimes we do encrypt injected frames, will be fixed
-	 * up in radiotap parser if not wanted */
-	skb->do_not_encrypt = 0;
-
 	/*
 	 * fix up the pointers accounting for the radiotap
 	 * header still being in there.  We are being given
@@ -1586,8 +1542,10 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
 	skb_set_network_header(skb, len_rthdr);
 	skb_set_transport_header(skb, len_rthdr);
 
-	/* pass the radiotap header up to the next stage intact */
-	dev_queue_xmit(skb);
+	memset(info, 0, sizeof(*info));
+
+	/* pass the radiotap header up to xmit */
+	ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb);
 	return NETDEV_TX_OK;
 
 fail:
@@ -1610,11 +1568,12 @@ fail:
  * encapsulated packet will then be passed to master interface, wlan#.11, for
  * transmission (through low-level driver).
  */
-int ieee80211_subif_start_xmit(struct sk_buff *skb,
-			       struct net_device *dev)
+netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
+				    struct net_device *dev)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	int ret = NETDEV_TX_BUSY, head_need;
 	u16 ethertype, hdrlen,  meshhdrlen = 0;
 	__le16 fc;
@@ -1627,7 +1586,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 	u32 sta_flags = 0;
 
 	if (unlikely(skb->len < ETH_HLEN)) {
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		goto fail;
 	}
 
@@ -1660,52 +1619,58 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 		break;
 #ifdef CONFIG_MAC80211_MESH
 	case NL80211_IFTYPE_MESH_POINT:
-		fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
 		if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
 			/* Do not send frames with mesh_ttl == 0 */
 			sdata->u.mesh.mshstats.dropped_frames_ttl++;
-			ret = 0;
+			ret = NETDEV_TX_OK;
 			goto fail;
 		}
-		memset(&mesh_hdr, 0, sizeof(mesh_hdr));
 
 		if (compare_ether_addr(dev->dev_addr,
 					  skb->data + ETH_ALEN) == 0) {
-			/* RA TA DA SA */
-			memset(hdr.addr1, 0, ETH_ALEN);
-			memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
-			memcpy(hdr.addr3, skb->data, ETH_ALEN);
-			memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
-			meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata);
+			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
+					skb->data, skb->data + ETH_ALEN);
+			meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
+					sdata, NULL, NULL, NULL);
 		} else {
 			/* packet from other interface */
 			struct mesh_path *mppath;
+			int is_mesh_mcast = 1;
+			char *mesh_da;
 
-			memset(hdr.addr1, 0, ETH_ALEN);
-			memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
-			memcpy(hdr.addr4, dev->dev_addr, ETH_ALEN);
-
+			rcu_read_lock();
 			if (is_multicast_ether_addr(skb->data))
-				memcpy(hdr.addr3, skb->data, ETH_ALEN);
+				/* DA TA mSA AE:SA */
+				mesh_da = skb->data;
 			else {
-				rcu_read_lock();
 				mppath = mpp_path_lookup(skb->data, sdata);
-				if (mppath)
-					memcpy(hdr.addr3, mppath->mpp, ETH_ALEN);
-				else
-					memset(hdr.addr3, 0xff, ETH_ALEN);
-				rcu_read_unlock();
+				if (mppath) {
+					/* RA TA mDA mSA AE:DA SA */
+					mesh_da = mppath->mpp;
+					is_mesh_mcast = 0;
+				} else
+					/* DA TA mSA AE:SA */
+					mesh_da = dev->broadcast;
 			}
+			hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
+					mesh_da, dev->dev_addr);
+			rcu_read_unlock();
+			if (is_mesh_mcast)
+				meshhdrlen =
+					ieee80211_new_mesh_header(&mesh_hdr,
+							sdata,
+							skb->data + ETH_ALEN,
+							NULL,
+							NULL);
+			else
+				meshhdrlen =
+					ieee80211_new_mesh_header(&mesh_hdr,
+							sdata,
+							NULL,
+							skb->data,
+							skb->data + ETH_ALEN);
 
-			mesh_hdr.flags |= MESH_FLAGS_AE_A5_A6;
-			mesh_hdr.ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
-			put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &mesh_hdr.seqnum);
-			memcpy(mesh_hdr.eaddr1, skb->data, ETH_ALEN);
-			memcpy(mesh_hdr.eaddr2, skb->data + ETH_ALEN, ETH_ALEN);
-			sdata->u.mesh.mesh_seqnum++;
-			meshhdrlen = 18;
 		}
-		hdrlen = 30;
 		break;
 #endif
 	case NL80211_IFTYPE_STATION:
@@ -1724,7 +1689,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 		hdrlen = 24;
 		break;
 	default:
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		goto fail;
 	}
 
@@ -1766,7 +1731,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 
 		I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
 
-		ret = 0;
+		ret = NETDEV_TX_OK;
 		goto fail;
 	}
 
@@ -1842,9 +1807,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 	nh_pos += hdrlen;
 	h_pos += hdrlen;
 
-	skb->iif = dev->ifindex;
-
-	skb->dev = local->mdev;
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 
@@ -1855,13 +1817,15 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 	skb_set_network_header(skb, nh_pos);
 	skb_set_transport_header(skb, h_pos);
 
+	memset(info, 0, sizeof(*info));
+
 	dev->trans_start = jiffies;
-	dev_queue_xmit(skb);
+	ieee80211_xmit(sdata, skb);
 
-	return 0;
+	return NETDEV_TX_OK;
 
  fail:
-	if (!ret)
+	if (ret == NETDEV_TX_OK)
 		dev_kfree_skb(skb);
 
 	return ret;
@@ -1887,101 +1851,74 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
 	struct ieee80211_sub_if_data *sdata;
 	struct sta_info *sta;
 	struct ieee80211_hdr *hdr;
-	struct net_device *dev;
 	int ret;
 	bool result = true;
 
-	/* does interface still exist? */
-	dev = dev_get_by_index(&init_net, skb->iif);
-	if (!dev) {
-		dev_kfree_skb(skb);
-		return true;
-	}
-
-	/* validate info->control.vif against skb->iif */
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-		sdata = container_of(sdata->bss,
-				     struct ieee80211_sub_if_data,
-				     u.ap);
-
-	if (unlikely(info->control.vif && info->control.vif != &sdata->vif)) {
-		dev_kfree_skb(skb);
-		result = true;
-		goto out;
-	}
+	sdata = vif_to_sdata(info->control.vif);
 
 	if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) {
-		ieee80211_tx(dev, skb, true);
+		ieee80211_tx(sdata, skb, true);
 	} else {
 		hdr = (struct ieee80211_hdr *)skb->data;
 		sta = sta_info_get(local, hdr->addr1);
 
-		ret = __ieee80211_tx(local, &skb, sta);
+		ret = __ieee80211_tx(local, &skb, sta, true);
 		if (ret != IEEE80211_TX_OK)
 			result = false;
 	}
 
- out:
-	dev_put(dev);
-
 	return result;
 }
 
 /*
- * Transmit all pending packets. Called from tasklet, locks master device
- * TX lock so that no new packets can come in.
+ * Transmit all pending packets. Called from tasklet.
  */
 void ieee80211_tx_pending(unsigned long data)
 {
 	struct ieee80211_local *local = (struct ieee80211_local *)data;
-	struct net_device *dev = local->mdev;
 	unsigned long flags;
 	int i;
-	bool next;
+	bool txok;
 
 	rcu_read_lock();
-	netif_tx_lock_bh(dev);
 
+	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 	for (i = 0; i < local->hw.queues; i++) {
 		/*
 		 * If queue is stopped by something other than due to pending
 		 * frames, or we have no pending frames, proceed to next queue.
 		 */
-		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
-		next = false;
-		if (local->queue_stop_reasons[i] !=
-			BIT(IEEE80211_QUEUE_STOP_REASON_PENDING) ||
+		if (local->queue_stop_reasons[i] ||
 		    skb_queue_empty(&local->pending[i]))
-			next = true;
-		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
-
-		if (next)
 			continue;
 
-		/*
-		 * start the queue now to allow processing our packets,
-		 * we're under the tx lock here anyway so nothing will
-		 * happen as a result of this
-		 */
-		netif_start_subqueue(local->mdev, i);
-
 		while (!skb_queue_empty(&local->pending[i])) {
-			struct sk_buff *skb = skb_dequeue(&local->pending[i]);
+			struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
+			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+			struct ieee80211_sub_if_data *sdata;
 
-			if (!ieee80211_tx_pending_skb(local, skb)) {
-				skb_queue_head(&local->pending[i], skb);
-				break;
+			if (WARN_ON(!info->control.vif)) {
+				kfree_skb(skb);
+				continue;
 			}
-		}
 
-		/* Start regular packet processing again. */
-		if (skb_queue_empty(&local->pending[i]))
-			ieee80211_wake_queue_by_reason(&local->hw, i,
-					IEEE80211_QUEUE_STOP_REASON_PENDING);
+			sdata = vif_to_sdata(info->control.vif);
+			dev_hold(sdata->dev);
+			spin_unlock_irqrestore(&local->queue_stop_reason_lock,
+						flags);
+
+			txok = ieee80211_tx_pending_skb(local, skb);
+			dev_put(sdata->dev);
+			if (!txok)
+				__skb_queue_head(&local->pending[i], skb);
+			spin_lock_irqsave(&local->queue_stop_reason_lock,
+					  flags);
+			if (!txok)
+				break;
+		}
 	}
+	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
-	netif_tx_unlock_bh(dev);
 	rcu_read_unlock();
 }
 
@@ -2156,8 +2093,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
 
 	info = IEEE80211_SKB_CB(skb);
 
-	skb->do_not_encrypt = 1;
-
+	info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
 	info->band = band;
 	/*
 	 * XXX: For now, always use the lowest rate
@@ -2228,9 +2164,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
 	sdata = vif_to_sdata(vif);
 	bss = &sdata->u.ap;
 
-	if (!bss)
-		return NULL;
-
 	rcu_read_lock();
 	beacon = rcu_dereference(bss->beacon);
 
@@ -2256,7 +2189,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
 				cpu_to_le16(IEEE80211_FCTL_MOREDATA);
 		}
 
-		if (!ieee80211_tx_prepare(local, &tx, skb))
+		if (!ieee80211_tx_prepare(sdata, &tx, skb))
 			break;
 		dev_kfree_skb_any(skb);
 	}
@@ -2276,3 +2209,24 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
 	return skb;
 }
 EXPORT_SYMBOL(ieee80211_get_buffered_bc);
+
+void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
+		      int encrypt)
+{
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	skb_set_mac_header(skb, 0);
+	skb_set_network_header(skb, 0);
+	skb_set_transport_header(skb, 0);
+
+	if (!encrypt)
+		info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+
+	/*
+	 * The other path calling ieee80211_xmit is from the tasklet,
+	 * and while we can handle concurrent transmissions locking
+	 * requirements are that we do not come into tx with bhs on.
+	 */
+	local_bh_disable();
+	ieee80211_xmit(sdata, skb);
+	local_bh_enable();
+}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 915e777..dd65643 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -31,6 +31,7 @@
 #include "mesh.h"
 #include "wme.h"
 #include "led.h"
+#include "wep.h"
 
 /* privid for wiphys to determine whether they belong to us or not */
 void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -274,16 +275,12 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
 
 	__clear_bit(reason, &local->queue_stop_reasons[queue]);
 
-	if (!skb_queue_empty(&local->pending[queue]) &&
-	    local->queue_stop_reasons[queue] ==
-				BIT(IEEE80211_QUEUE_STOP_REASON_PENDING))
-		tasklet_schedule(&local->tx_pending_tasklet);
-
 	if (local->queue_stop_reasons[queue] != 0)
 		/* someone still has this queue stopped */
 		return;
 
-	netif_wake_subqueue(local->mdev, queue);
+	if (!skb_queue_empty(&local->pending[queue]))
+		tasklet_schedule(&local->tx_pending_tasklet);
 }
 
 void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -312,14 +309,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
 	if (WARN_ON(queue >= hw->queues))
 		return;
 
-	/*
-	 * Only stop if it was previously running, this is necessary
-	 * for correct pending packets handling because there we may
-	 * start (but not wake) the queue and rely on that.
-	 */
-	if (!local->queue_stop_reasons[queue])
-		netif_stop_subqueue(local->mdev, queue);
-
 	__set_bit(reason, &local->queue_stop_reasons[queue]);
 }
 
@@ -347,11 +336,16 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
 	struct ieee80211_hw *hw = &local->hw;
 	unsigned long flags;
 	int queue = skb_get_queue_mapping(skb);
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+	if (WARN_ON(!info->control.vif)) {
+		kfree(skb);
+		return;
+	}
 
 	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 	__ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
-	__ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING);
-	skb_queue_tail(&local->pending[queue], skb);
+	__skb_queue_tail(&local->pending[queue], skb);
 	__ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 }
@@ -370,18 +364,21 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
 			IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
 
 	while ((skb = skb_dequeue(skbs))) {
+		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+		if (WARN_ON(!info->control.vif)) {
+			kfree(skb);
+			continue;
+		}
+
 		ret++;
 		queue = skb_get_queue_mapping(skb);
-		skb_queue_tail(&local->pending[queue], skb);
+		__skb_queue_tail(&local->pending[queue], skb);
 	}
 
-	for (i = 0; i < hw->queues; i++) {
-		if (ret)
-			__ieee80211_stop_queue(hw, i,
-				IEEE80211_QUEUE_STOP_REASON_PENDING);
+	for (i = 0; i < hw->queues; i++)
 		__ieee80211_wake_queue(hw, i,
 			IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
-	}
 	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
 
 	return ret;
@@ -412,11 +409,16 @@ EXPORT_SYMBOL(ieee80211_stop_queues);
 int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
+	unsigned long flags;
+	int ret;
 
 	if (WARN_ON(queue >= hw->queues))
 		return true;
 
-	return __netif_subqueue_stopped(local->mdev, queue);
+	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+	ret = !!local->queue_stop_reasons[queue];
+	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+	return ret;
 }
 EXPORT_SYMBOL(ieee80211_queue_stopped);
 
@@ -509,6 +511,46 @@ void ieee80211_iterate_active_interfaces_atomic(
 }
 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
 
+/*
+ * Nothing should have been stuffed into the workqueue during
+ * the suspend->resume cycle. If this WARN is seen then there
+ * is a bug with either the driver suspend or something in
+ * mac80211 stuffing into the workqueue which we haven't yet
+ * cleared during mac80211's suspend cycle.
+ */
+static bool ieee80211_can_queue_work(struct ieee80211_local *local)
+{
+        if (WARN(local->suspended, "queueing ieee80211 work while "
+		 "going to suspend\n"))
+                return false;
+
+	return true;
+}
+
+void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+
+	if (!ieee80211_can_queue_work(local))
+		return;
+
+	queue_work(local->workqueue, work);
+}
+EXPORT_SYMBOL(ieee80211_queue_work);
+
+void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
+				  struct delayed_work *dwork,
+				  unsigned long delay)
+{
+	struct ieee80211_local *local = hw_to_local(hw);
+
+	if (!ieee80211_can_queue_work(local))
+		return;
+
+	queue_delayed_work(local->workqueue, dwork, delay);
+}
+EXPORT_SYMBOL(ieee80211_queue_delayed_work);
+
 void ieee802_11_parse_elems(u8 *start, size_t len,
 			    struct ieee802_11_elems *elems)
 {
@@ -760,20 +802,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
 	ieee80211_set_wmm_default(sdata);
 }
 
-void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
-		      int encrypt)
-{
-	skb->dev = sdata->local->mdev;
-	skb_set_mac_header(skb, 0);
-	skb_set_network_header(skb, 0);
-	skb_set_transport_header(skb, 0);
-
-	skb->iif = sdata->dev->ifindex;
-	skb->do_not_encrypt = !encrypt;
-
-	dev_queue_xmit(skb);
-}
-
 u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
 			      enum ieee80211_band band)
 {
@@ -804,12 +832,13 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 			 u16 transaction, u16 auth_alg,
-			 u8 *extra, size_t extra_len,
-			 const u8 *bssid, int encrypt)
+			 u8 *extra, size_t extra_len, const u8 *bssid,
+			 const u8 *key, u8 key_len, u8 key_idx)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
+	int err;
 
 	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
 			    sizeof(*mgmt) + 6 + extra_len);
@@ -824,8 +853,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 	memset(mgmt, 0, 24 + 6);
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 					  IEEE80211_STYPE_AUTH);
-	if (encrypt)
-		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 	memcpy(mgmt->da, bssid, ETH_ALEN);
 	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
 	memcpy(mgmt->bssid, bssid, ETH_ALEN);
@@ -835,7 +862,13 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
 	if (extra)
 		memcpy(skb_put(skb, extra_len), extra, extra_len);
 
-	ieee80211_tx_skb(sdata, skb, encrypt);
+	if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
+		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+		err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
+		WARN_ON(err);
+	}
+
+	ieee80211_tx_skb(sdata, skb, 0);
 }
 
 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
@@ -974,6 +1007,16 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
 	return supp_rates;
 }
 
+void ieee80211_stop_device(struct ieee80211_local *local)
+{
+	ieee80211_led_radio(local, false);
+
+	cancel_work_sync(&local->reconfig_filter);
+	drv_stop(local);
+
+	flush_workqueue(local->workqueue);
+}
+
 int ieee80211_reconfig(struct ieee80211_local *local)
 {
 	struct ieee80211_hw *hw = &local->hw;
@@ -1043,9 +1086,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 	/* reconfigure hardware */
 	ieee80211_hw_config(local, ~0);
 
-	netif_addr_lock_bh(local->mdev);
 	ieee80211_configure_filter(local);
-	netif_addr_unlock_bh(local->mdev);
 
 	/* Finally also reconfigure all the BSS information */
 	list_for_each_entry(sdata, &local->interfaces, list) {
@@ -1121,3 +1162,4 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 #endif
 	return 0;
 }
+
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index ef73105..8a980f1 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -67,10 +67,10 @@ static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
 
 
 static void ieee80211_wep_get_iv(struct ieee80211_local *local,
-				 struct ieee80211_key *key, u8 *iv)
+				 int keylen, int keyidx, u8 *iv)
 {
 	local->wep_iv++;
-	if (ieee80211_wep_weak_iv(local->wep_iv, key->conf.keylen))
+	if (ieee80211_wep_weak_iv(local->wep_iv, keylen))
 		local->wep_iv += 0x0100;
 
 	if (!iv)
@@ -79,13 +79,13 @@ static void ieee80211_wep_get_iv(struct ieee80211_local *local,
 	*iv++ = (local->wep_iv >> 16) & 0xff;
 	*iv++ = (local->wep_iv >> 8) & 0xff;
 	*iv++ = local->wep_iv & 0xff;
-	*iv++ = key->conf.keyidx << 6;
+	*iv++ = keyidx << 6;
 }
 
 
 static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
 				struct sk_buff *skb,
-				struct ieee80211_key *key)
+				int keylen, int keyidx)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	unsigned int hdrlen;
@@ -100,7 +100,7 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
 	hdrlen = ieee80211_hdrlen(hdr->frame_control);
 	newhdr = skb_push(skb, WEP_IV_LEN);
 	memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen);
-	ieee80211_wep_get_iv(local, key, newhdr + hdrlen);
+	ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
 	return newhdr + hdrlen;
 }
 
@@ -144,26 +144,17 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
  *
  * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
  */
-int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
-			  struct ieee80211_key *key)
+int ieee80211_wep_encrypt(struct ieee80211_local *local,
+			  struct sk_buff *skb,
+			  const u8 *key, int keylen, int keyidx)
 {
-	u32 klen;
-	u8 *rc4key, *iv;
+	u8 *iv;
 	size_t len;
+	u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
 
-	if (!key || key->conf.alg != ALG_WEP)
-		return -1;
-
-	klen = 3 + key->conf.keylen;
-	rc4key = kmalloc(klen, GFP_ATOMIC);
-	if (!rc4key)
-		return -1;
-
-	iv = ieee80211_wep_add_iv(local, skb, key);
-	if (!iv) {
-		kfree(rc4key);
+	iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx);
+	if (!iv)
 		return -1;
-	}
 
 	len = skb->len - (iv + WEP_IV_LEN - skb->data);
 
@@ -171,16 +162,14 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
 	memcpy(rc4key, iv, 3);
 
 	/* Copy rest of the WEP key (the secret part) */
-	memcpy(rc4key + 3, key->conf.key, key->conf.keylen);
+	memcpy(rc4key + 3, key, keylen);
 
 	/* Add room for ICV */
 	skb_put(skb, WEP_ICV_LEN);
 
-	ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, klen,
+	ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
 				   iv + WEP_IV_LEN, len);
 
-	kfree(rc4key);
-
 	return 0;
 }
 
@@ -216,8 +205,9 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
  * failure. If frame is OK, IV and ICV will be removed, i.e., decrypted payload
  * is moved to the beginning of the skb and skb length will be reduced.
  */
-int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
-			  struct ieee80211_key *key)
+static int ieee80211_wep_decrypt(struct ieee80211_local *local,
+				 struct sk_buff *skb,
+				 struct ieee80211_key *key)
 {
 	u32 klen;
 	u8 *rc4key;
@@ -314,12 +304,16 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
 	if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
-		if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
+		if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key,
+					  tx->key->conf.keylen,
+					  tx->key->conf.keyidx))
 			return -1;
 	} else {
 		info->control.hw_key = &tx->key->conf;
 		if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) {
-			if (!ieee80211_wep_add_iv(tx->local, skb, tx->key))
+			if (!ieee80211_wep_add_iv(tx->local, skb,
+						  tx->key->conf.keylen,
+						  tx->key->conf.keyidx))
 				return -1;
 		}
 	}
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index d3f0db4..fe29d7e 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -20,12 +20,11 @@ int ieee80211_wep_init(struct ieee80211_local *local);
 void ieee80211_wep_free(struct ieee80211_local *local);
 void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 				size_t klen, u8 *data, size_t data_len);
+int ieee80211_wep_encrypt(struct ieee80211_local *local,
+			  struct sk_buff *skb,
+			  const u8 *key, int keylen, int keyidx);
 int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
 			       size_t klen, u8 *data, size_t data_len);
-int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb,
-			  struct ieee80211_key *key);
-int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
-			  struct ieee80211_key *key);
 bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
 
 ieee80211_rx_result
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
deleted file mode 100644
index 1da81f4..0000000
--- a/net/mac80211/wext.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * Copyright 2002-2005, Instant802 Networks, Inc.
- * Copyright 2005-2006, Devicescape Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/skbuff.h>
-#include <linux/etherdevice.h>
-#include <linux/if_arp.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <asm/uaccess.h>
-
-#include <net/mac80211.h>
-#include "ieee80211_i.h"
-#include "led.h"
-#include "rate.h"
-#include "wpa.h"
-#include "aes_ccm.h"
-
-
-static int ieee80211_ioctl_siwgenie(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *data, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
-		if (ret && ret != -EALREADY)
-			return ret;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
-		if (ret != -EALREADY)
-			ieee80211_sta_req_auth(sdata);
-		return 0;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-static int ieee80211_ioctl_siwfreq(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_freq *freq, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_channel *chan;
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
-	else if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
-
-	/* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
-	if (freq->e == 0) {
-		if (freq->m < 0) {
-			if (sdata->vif.type == NL80211_IFTYPE_STATION)
-				sdata->u.mgd.flags |=
-					IEEE80211_STA_AUTO_CHANNEL_SEL;
-			return 0;
-		} else
-			chan = ieee80211_get_channel(local->hw.wiphy,
-				ieee80211_channel_to_frequency(freq->m));
-	} else {
-		int i, div = 1000000;
-		for (i = 0; i < freq->e; i++)
-			div /= 10;
-		if (div <= 0)
-			return -EINVAL;
-		chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div);
-	}
-
-	if (!chan)
-		return -EINVAL;
-
-	if (chan->flags & IEEE80211_CHAN_DISABLED)
-		return -EINVAL;
-
-	/*
-	 * no change except maybe auto -> fixed, ignore the HT
-	 * setting so you can fix a channel you're on already
-	 */
-	if (local->oper_channel == chan)
-		return 0;
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		ieee80211_sta_req_auth(sdata);
-
-	local->oper_channel = chan;
-	local->oper_channel_type = NL80211_CHAN_NO_HT;
-	ieee80211_hw_config(local, 0);
-
-	return 0;
-}
-
-
-static int ieee80211_ioctl_giwfreq(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_freq *freq, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
-
-	freq->m = local->oper_channel->center_freq;
-	freq->e = 6;
-
-	return 0;
-}
-
-
-static int ieee80211_ioctl_siwessid(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *data, char *ssid)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	size_t len = data->length;
-	int ret;
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
-
-	/* iwconfig uses nul termination in SSID.. */
-	if (len > 0 && ssid[len - 1] == '\0')
-		len--;
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		if (data->flags)
-			sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
-		else
-			sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
-
-		ret = ieee80211_sta_set_ssid(sdata, ssid, len);
-		if (ret)
-			return ret;
-
-		sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
-		ieee80211_sta_req_auth(sdata);
-		return 0;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-
-static int ieee80211_ioctl_giwessid(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_point *data, char *ssid)
-{
-	size_t len;
-	struct ieee80211_sub_if_data *sdata;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
-		if (res == 0) {
-			data->length = len;
-			data->flags = 1;
-		} else
-			data->flags = 0;
-		return res;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-
-static int ieee80211_ioctl_siwap(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct sockaddr *ap_addr, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		int ret;
-
-		if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
-			sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL |
-				IEEE80211_STA_AUTO_CHANNEL_SEL;
-		else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
-			sdata->u.mgd.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
-		else
-			sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
-		ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
-		if (ret)
-			return ret;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
-		sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
-		ieee80211_sta_req_auth(sdata);
-		return 0;
-	} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
-		/*
-		 * If it is necessary to update the WDS peer address
-		 * while the interface is running, then we need to do
-		 * more work here, namely if it is running we need to
-		 * add a new and remove the old STA entry, this is
-		 * normally handled by _open() and _stop().
-		 */
-		if (netif_running(dev))
-			return -EBUSY;
-
-		memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
-		       ETH_ALEN);
-
-		return 0;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-
-static int ieee80211_ioctl_giwap(struct net_device *dev,
-				 struct iw_request_info *info,
-				 struct sockaddr *ap_addr, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-		return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
-			ap_addr->sa_family = ARPHRD_ETHER;
-			memcpy(&ap_addr->sa_data, sdata->u.mgd.bssid, ETH_ALEN);
-		} else
-			memset(&ap_addr->sa_data, 0, ETH_ALEN);
-		return 0;
-	} else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
-		ap_addr->sa_family = ARPHRD_ETHER;
-		memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
-		return 0;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-
-static int ieee80211_ioctl_siwrate(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_param *rate, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	int i, err = -EINVAL;
-	u32 target_rate = rate->value / 100000;
-	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_supported_band *sband;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-	/* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
-	 * target_rate = X, rate->fixed = 1 means only rate X
-	 * target_rate = X, rate->fixed = 0 means all rates <= X */
-	sdata->max_ratectrl_rateidx = -1;
-	sdata->force_unicast_rateidx = -1;
-	if (rate->value < 0)
-		return 0;
-
-	for (i=0; i< sband->n_bitrates; i++) {
-		struct ieee80211_rate *brate = &sband->bitrates[i];
-		int this_rate = brate->bitrate;
-
-		if (target_rate == this_rate) {
-			sdata->max_ratectrl_rateidx = i;
-			if (rate->fixed)
-				sdata->force_unicast_rateidx = i;
-			err = 0;
-			break;
-		}
-	}
-	return err;
-}
-
-static int ieee80211_ioctl_giwrate(struct net_device *dev,
-				  struct iw_request_info *info,
-				  struct iw_param *rate, char *extra)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct sta_info *sta;
-	struct ieee80211_sub_if_data *sdata;
-	struct ieee80211_supported_band *sband;
-
-	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	if (sdata->vif.type != NL80211_IFTYPE_STATION)
-		return -EOPNOTSUPP;
-
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-	rcu_read_lock();
-
-	sta = sta_info_get(local, sdata->u.mgd.bssid);
-
-	if (sta && !(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS))
-		rate->value = sband->bitrates[sta->last_tx_rate.idx].bitrate;
-	else
-		rate->value = 0;
-
-	rcu_read_unlock();
-
-	if (!sta)
-		return -ENODEV;
-
-	rate->value *= 100000;
-
-	return 0;
-}
-
-static int ieee80211_ioctl_siwpower(struct net_device *dev,
-				    struct iw_request_info *info,
-				    struct iw_param *wrq,
-				    char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_conf *conf = &local->hw.conf;
-	int timeout = 0;
-	bool ps;
-
-	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
-		return -EOPNOTSUPP;
-
-	if (sdata->vif.type != NL80211_IFTYPE_STATION)
-		return -EINVAL;
-
-	if (wrq->disabled) {
-		ps = false;
-		timeout = 0;
-		goto set;
-	}
-
-	switch (wrq->flags & IW_POWER_MODE) {
-	case IW_POWER_ON:       /* If not specified */
-	case IW_POWER_MODE:     /* If set all mask */
-	case IW_POWER_ALL_R:    /* If explicitely state all */
-		ps = true;
-		break;
-	default:                /* Otherwise we ignore */
-		return -EINVAL;
-	}
-
-	if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
-		return -EINVAL;
-
-	if (wrq->flags & IW_POWER_TIMEOUT)
-		timeout = wrq->value / 1000;
-
- set:
-	if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
-		return 0;
-
-	sdata->u.mgd.powersave = ps;
-	conf->dynamic_ps_timeout = timeout;
-
-	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
-		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
-
-	ieee80211_recalc_ps(local, -1);
-
-	return 0;
-}
-
-static int ieee80211_ioctl_giwpower(struct net_device *dev,
-				    struct iw_request_info *info,
-				    union iwreq_data *wrqu,
-				    char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-	wrqu->power.disabled = !sdata->u.mgd.powersave;
-
-	return 0;
-}
-
-static int ieee80211_ioctl_siwauth(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_param *data, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	int ret = 0;
-
-	switch (data->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-	case IW_AUTH_CIPHER_GROUP:
-	case IW_AUTH_WPA_ENABLED:
-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-	case IW_AUTH_KEY_MGMT:
-	case IW_AUTH_CIPHER_GROUP_MGMT:
-		break;
-	case IW_AUTH_CIPHER_PAIRWISE:
-		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-			if (data->value & (IW_AUTH_CIPHER_WEP40 |
-			    IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_TKIP))
-				sdata->u.mgd.flags |=
-					IEEE80211_STA_TKIP_WEP_USED;
-			else
-				sdata->u.mgd.flags &=
-					~IEEE80211_STA_TKIP_WEP_USED;
-		}
-		break;
-	case IW_AUTH_DROP_UNENCRYPTED:
-		sdata->drop_unencrypted = !!data->value;
-		break;
-	case IW_AUTH_PRIVACY_INVOKED:
-		if (sdata->vif.type != NL80211_IFTYPE_STATION)
-			ret = -EINVAL;
-		else {
-			sdata->u.mgd.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
-			/*
-			 * Privacy invoked by wpa_supplicant, store the
-			 * value and allow associating to a protected
-			 * network without having a key up front.
-			 */
-			if (data->value)
-				sdata->u.mgd.flags |=
-					IEEE80211_STA_PRIVACY_INVOKED;
-		}
-		break;
-	case IW_AUTH_80211_AUTH_ALG:
-		if (sdata->vif.type == NL80211_IFTYPE_STATION)
-			sdata->u.mgd.auth_algs = data->value;
-		else
-			ret = -EOPNOTSUPP;
-		break;
-	case IW_AUTH_MFP:
-		if (!(sdata->local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) {
-			ret = -EOPNOTSUPP;
-			break;
-		}
-		if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-			switch (data->value) {
-			case IW_AUTH_MFP_DISABLED:
-				sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
-				break;
-			case IW_AUTH_MFP_OPTIONAL:
-				sdata->u.mgd.mfp = IEEE80211_MFP_OPTIONAL;
-				break;
-			case IW_AUTH_MFP_REQUIRED:
-				sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
-				break;
-			default:
-				ret = -EINVAL;
-			}
-		} else
-			ret = -EOPNOTSUPP;
-		break;
-	default:
-		ret = -EOPNOTSUPP;
-		break;
-	}
-	return ret;
-}
-
-/* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
-static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev)
-{
-	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct iw_statistics *wstats = &local->wstats;
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	struct sta_info *sta = NULL;
-
-	rcu_read_lock();
-
-	if (sdata->vif.type == NL80211_IFTYPE_STATION)
-		sta = sta_info_get(local, sdata->u.mgd.bssid);
-
-	if (!sta) {
-		wstats->discard.fragment = 0;
-		wstats->discard.misc = 0;
-		wstats->qual.qual = 0;
-		wstats->qual.level = 0;
-		wstats->qual.noise = 0;
-		wstats->qual.updated = IW_QUAL_ALL_INVALID;
-	} else {
-		wstats->qual.updated = 0;
-		/*
-		 * mirror what cfg80211 does for iwrange/scan results,
-		 * otherwise userspace gets confused.
-		 */
-		if (local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
-				       IEEE80211_HW_SIGNAL_DBM)) {
-			wstats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
-			wstats->qual.updated |= IW_QUAL_QUAL_UPDATED;
-		} else {
-			wstats->qual.updated |= IW_QUAL_LEVEL_INVALID;
-			wstats->qual.updated |= IW_QUAL_QUAL_INVALID;
-		}
-
-		if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) {
-			wstats->qual.level = sta->last_signal;
-			wstats->qual.qual = sta->last_signal;
-		} else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
-			int sig = sta->last_signal;
-
-			wstats->qual.updated |= IW_QUAL_DBM;
-			wstats->qual.level = sig;
-			if (sig < -110)
-				sig = -110;
-			else if (sig > -40)
-				sig = -40;
-			wstats->qual.qual = sig + 110;
-		}
-
-		if (local->hw.flags & IEEE80211_HW_NOISE_DBM) {
-			/*
-			 * This assumes that if driver reports noise, it also
-			 * reports signal in dBm.
-			 */
-			wstats->qual.noise = sta->last_noise;
-			wstats->qual.updated |= IW_QUAL_NOISE_UPDATED;
-		} else {
-			wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
-		}
-	}
-
-	rcu_read_unlock();
-
-	return wstats;
-}
-
-static int ieee80211_ioctl_giwauth(struct net_device *dev,
-				   struct iw_request_info *info,
-				   struct iw_param *data, char *extra)
-{
-	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	int ret = 0;
-
-	switch (data->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_80211_AUTH_ALG:
-		if (sdata->vif.type == NL80211_IFTYPE_STATION)
-			data->value = sdata->u.mgd.auth_algs;
-		else
-			ret = -EOPNOTSUPP;
-		break;
-	default:
-		ret = -EOPNOTSUPP;
-		break;
-	}
-	return ret;
-}
-
-
-/* Structures to export the Wireless Handlers */
-
-static const iw_handler ieee80211_handler[] =
-{
-	(iw_handler) NULL,				/* SIOCSIWCOMMIT */
-	(iw_handler) cfg80211_wext_giwname,		/* SIOCGIWNAME */
-	(iw_handler) NULL,				/* SIOCSIWNWID */
-	(iw_handler) NULL,				/* SIOCGIWNWID */
-	(iw_handler) ieee80211_ioctl_siwfreq,		/* SIOCSIWFREQ */
-	(iw_handler) ieee80211_ioctl_giwfreq,		/* SIOCGIWFREQ */
-	(iw_handler) cfg80211_wext_siwmode,		/* SIOCSIWMODE */
-	(iw_handler) cfg80211_wext_giwmode,		/* SIOCGIWMODE */
-	(iw_handler) NULL,				/* SIOCSIWSENS */
-	(iw_handler) NULL,				/* SIOCGIWSENS */
-	(iw_handler) NULL /* not used */,		/* SIOCSIWRANGE */
-	(iw_handler) cfg80211_wext_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) NULL,				/* SIOCSIWSPY */
-	(iw_handler) NULL,				/* SIOCGIWSPY */
-	(iw_handler) NULL,				/* SIOCSIWTHRSPY */
-	(iw_handler) NULL,				/* SIOCGIWTHRSPY */
-	(iw_handler) ieee80211_ioctl_siwap,		/* SIOCSIWAP */
-	(iw_handler) ieee80211_ioctl_giwap,		/* SIOCGIWAP */
-	(iw_handler) cfg80211_wext_siwmlme,		/* SIOCSIWMLME */
-	(iw_handler) NULL,				/* SIOCGIWAPLIST */
-	(iw_handler) cfg80211_wext_siwscan,		/* SIOCSIWSCAN */
-	(iw_handler) cfg80211_wext_giwscan,		/* SIOCGIWSCAN */
-	(iw_handler) ieee80211_ioctl_siwessid,		/* SIOCSIWESSID */
-	(iw_handler) ieee80211_ioctl_giwessid,		/* SIOCGIWESSID */
-	(iw_handler) NULL,				/* SIOCSIWNICKN */
-	(iw_handler) NULL,				/* SIOCGIWNICKN */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) ieee80211_ioctl_siwrate,		/* SIOCSIWRATE */
-	(iw_handler) ieee80211_ioctl_giwrate,		/* SIOCGIWRATE */
-	(iw_handler) cfg80211_wext_siwrts,		/* SIOCSIWRTS */
-	(iw_handler) cfg80211_wext_giwrts,		/* SIOCGIWRTS */
-	(iw_handler) cfg80211_wext_siwfrag,		/* SIOCSIWFRAG */
-	(iw_handler) cfg80211_wext_giwfrag,		/* SIOCGIWFRAG */
-	(iw_handler) cfg80211_wext_siwtxpower,		/* SIOCSIWTXPOW */
-	(iw_handler) cfg80211_wext_giwtxpower,		/* SIOCGIWTXPOW */
-	(iw_handler) cfg80211_wext_siwretry,		/* SIOCSIWRETRY */
-	(iw_handler) cfg80211_wext_giwretry,		/* SIOCGIWRETRY */
-	(iw_handler) cfg80211_wext_siwencode,		/* SIOCSIWENCODE */
-	(iw_handler) cfg80211_wext_giwencode,		/* SIOCGIWENCODE */
-	(iw_handler) ieee80211_ioctl_siwpower,		/* SIOCSIWPOWER */
-	(iw_handler) ieee80211_ioctl_giwpower,		/* SIOCGIWPOWER */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) NULL,				/* -- hole -- */
-	(iw_handler) ieee80211_ioctl_siwgenie,		/* SIOCSIWGENIE */
-	(iw_handler) NULL,				/* SIOCGIWGENIE */
-	(iw_handler) ieee80211_ioctl_siwauth,		/* SIOCSIWAUTH */
-	(iw_handler) ieee80211_ioctl_giwauth,		/* SIOCGIWAUTH */
-	(iw_handler) cfg80211_wext_siwencodeext,	/* SIOCSIWENCODEEXT */
-	(iw_handler) NULL,				/* SIOCGIWENCODEEXT */
-	(iw_handler) NULL,				/* SIOCSIWPMKSA */
-	(iw_handler) NULL,				/* -- hole -- */
-};
-
-const struct iw_handler_def ieee80211_iw_handler_def =
-{
-	.num_standard	= ARRAY_SIZE(ieee80211_handler),
-	.standard	= (iw_handler *) ieee80211_handler,
-	.get_wireless_stats = ieee80211_get_wireless_stats,
-};
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 116a923..b19b769 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -85,10 +85,8 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
 	return ieee802_1d_to_ac[skb->priority];
 }
 
-u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
+void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb)
 {
-	struct ieee80211_master_priv *mpriv = netdev_priv(dev);
-	struct ieee80211_local *local = mpriv->local;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	u16 queue;
 	u8 tid;
@@ -113,5 +111,5 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
 		*p = 0;
 	}
 
-	return queue;
+	skb_set_queue_mapping(skb, queue);
 }
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index 7520d2e..d4fd87c 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -20,6 +20,7 @@
 
 extern const int ieee802_1d_to_ac[8];
 
-u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb);
+void ieee80211_select_queue(struct ieee80211_local *local,
+			    struct sk_buff *skb);
 
 #endif /* _WME_H */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index dcfae88..7077869 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -122,7 +122,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
 			return RX_DROP_UNUSABLE;
 
 		mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
-						(void *) skb->data, NULL);
+						(void *) skb->data, NULL,
+						GFP_ATOMIC);
 		return RX_DROP_UNUSABLE;
 	}
 
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index 201b8ea..3c7e427 100644
--- a/net/netfilter/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
@@ -18,6 +18,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
@@ -262,12 +265,12 @@ static inline void vs_fix_seq(const struct ip_vs_seq *vseq, struct tcphdr *th)
 	if (vseq->delta || vseq->previous_delta) {
 		if(after(seq, vseq->init_seq)) {
 			th->seq = htonl(seq + vseq->delta);
-			IP_VS_DBG(9, "vs_fix_seq(): added delta (%d) to seq\n",
-				  vseq->delta);
+			IP_VS_DBG(9, "%s(): added delta (%d) to seq\n",
+				  __func__, vseq->delta);
 		} else {
 			th->seq = htonl(seq + vseq->previous_delta);
-			IP_VS_DBG(9, "vs_fix_seq(): added previous_delta "
-				  "(%d) to seq\n", vseq->previous_delta);
+			IP_VS_DBG(9, "%s(): added previous_delta (%d) to seq\n",
+				  __func__, vseq->previous_delta);
 		}
 	}
 }
@@ -291,14 +294,14 @@ vs_fix_ack_seq(const struct ip_vs_seq *vseq, struct tcphdr *th)
 		   to receive next, so compare it with init_seq+delta */
 		if(after(ack_seq, vseq->init_seq+vseq->delta)) {
 			th->ack_seq = htonl(ack_seq - vseq->delta);
-			IP_VS_DBG(9, "vs_fix_ack_seq(): subtracted delta "
-				  "(%d) from ack_seq\n", vseq->delta);
+			IP_VS_DBG(9, "%s(): subtracted delta "
+				  "(%d) from ack_seq\n", __func__, vseq->delta);
 
 		} else {
 			th->ack_seq = htonl(ack_seq - vseq->previous_delta);
-			IP_VS_DBG(9, "vs_fix_ack_seq(): subtracted "
+			IP_VS_DBG(9, "%s(): subtracted "
 				  "previous_delta (%d) from ack_seq\n",
-				  vseq->previous_delta);
+				  __func__, vseq->previous_delta);
 		}
 	}
 }
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 77bfdfe..27c30cf 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -22,6 +22,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/net.h>
@@ -150,8 +153,8 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)
 		atomic_inc(&cp->refcnt);
 		ret = 1;
 	} else {
-		IP_VS_ERR("ip_vs_conn_hash(): request for already hashed, "
-			  "called from %p\n", __builtin_return_address(0));
+		pr_err("%s(): request for already hashed, called from %pF\n",
+		       __func__, __builtin_return_address(0));
 		ret = 0;
 	}
 
@@ -689,7 +692,7 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
 
 	cp = kmem_cache_zalloc(ip_vs_conn_cachep, GFP_ATOMIC);
 	if (cp == NULL) {
-		IP_VS_ERR_RL("ip_vs_conn_new: no memory available.\n");
+		IP_VS_ERR_RL("%s(): no memory\n", __func__);
 		return NULL;
 	}
 
@@ -1073,10 +1076,10 @@ int __init ip_vs_conn_init(void)
 		return -ENOMEM;
 	}
 
-	IP_VS_INFO("Connection hash table configured "
-		   "(size=%d, memory=%ldKbytes)\n",
-		   IP_VS_CONN_TAB_SIZE,
-		   (long)(IP_VS_CONN_TAB_SIZE*sizeof(struct list_head))/1024);
+	pr_info("Connection hash table configured "
+		"(size=%d, memory=%ldKbytes)\n",
+		IP_VS_CONN_TAB_SIZE,
+		(long)(IP_VS_CONN_TAB_SIZE*sizeof(struct list_head))/1024);
 	IP_VS_DBG(0, "Each connection entry needs %Zd bytes at least\n",
 		  sizeof(struct ip_vs_conn));
 
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 8dddb17..b95699f 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -24,6 +24,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ip.h>
@@ -388,9 +391,9 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 	 */
 	if (!svc->fwmark && pptr[1] != svc->port) {
 		if (!svc->port)
-			IP_VS_ERR("Schedule: port zero only supported "
-				  "in persistent services, "
-				  "check your ipvs configuration\n");
+			pr_err("Schedule: port zero only supported "
+			       "in persistent services, "
+			       "check your ipvs configuration\n");
 		return NULL;
 	}
 
@@ -462,7 +465,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
 		ip_vs_service_put(svc);
 
 		/* create a new connection entry */
-		IP_VS_DBG(6, "ip_vs_leave: create a cache_bypass entry\n");
+		IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__);
 		cp = ip_vs_conn_new(svc->af, iph.protocol,
 				    &iph.saddr, pptr[0],
 				    &iph.daddr, pptr[1],
@@ -664,8 +667,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
 	unsigned int verdict = NF_DROP;
 
 	if (IP_VS_FWD_METHOD(cp) != 0) {
-		IP_VS_ERR("shouldn't reach here, because the box is on the "
-			  "half connection in the tun/dr module.\n");
+		pr_err("shouldn't reach here, because the box is on the "
+		       "half connection in the tun/dr module.\n");
 	}
 
 	/* Ensure the checksum is correct */
@@ -1256,7 +1259,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
 	struct ip_vs_iphdr iph;
 	struct ip_vs_protocol *pp;
 	struct ip_vs_conn *cp;
-	int ret, restart, af;
+	int ret, restart, af, pkts;
 
 	af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
 
@@ -1274,13 +1277,24 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
 		return NF_ACCEPT;
 	}
 
-	if (unlikely(iph.protocol == IPPROTO_ICMP)) {
-		int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
+#ifdef CONFIG_IP_VS_IPV6
+	if (af == AF_INET6) {
+		if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
+			int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
 
-		if (related)
-			return verdict;
-		ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
-	}
+			if (related)
+				return verdict;
+			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+		}
+	} else
+#endif
+		if (unlikely(iph.protocol == IPPROTO_ICMP)) {
+			int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
+
+			if (related)
+				return verdict;
+			ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
+		}
 
 	/* Protocol supported? */
 	pp = ip_vs_proto_get(iph.protocol);
@@ -1343,12 +1357,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
 	 * Sync connection if it is about to close to
 	 * encorage the standby servers to update the connections timeout
 	 */
-	atomic_inc(&cp->in_pkts);
+	pkts = atomic_add_return(1, &cp->in_pkts);
 	if (af == AF_INET &&
 	    (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
 	    (((cp->protocol != IPPROTO_TCP ||
 	       cp->state == IP_VS_TCP_S_ESTABLISHED) &&
-	      (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
+	      (pkts % sysctl_ip_vs_sync_threshold[1]
 	       == sysctl_ip_vs_sync_threshold[0])) ||
 	     ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
 	      ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
@@ -1487,7 +1501,7 @@ static int __init ip_vs_init(void)
 
 	ret = ip_vs_control_init();
 	if (ret < 0) {
-		IP_VS_ERR("can't setup control.\n");
+		pr_err("can't setup control.\n");
 		goto cleanup_estimator;
 	}
 
@@ -1495,23 +1509,23 @@ static int __init ip_vs_init(void)
 
 	ret = ip_vs_app_init();
 	if (ret < 0) {
-		IP_VS_ERR("can't setup application helper.\n");
+		pr_err("can't setup application helper.\n");
 		goto cleanup_protocol;
 	}
 
 	ret = ip_vs_conn_init();
 	if (ret < 0) {
-		IP_VS_ERR("can't setup connection table.\n");
+		pr_err("can't setup connection table.\n");
 		goto cleanup_app;
 	}
 
 	ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
 	if (ret < 0) {
-		IP_VS_ERR("can't register hooks.\n");
+		pr_err("can't register hooks.\n");
 		goto cleanup_conn;
 	}
 
-	IP_VS_INFO("ipvs loaded.\n");
+	pr_info("ipvs loaded.\n");
 	return ret;
 
   cleanup_conn:
@@ -1534,7 +1548,7 @@ static void __exit ip_vs_cleanup(void)
 	ip_vs_protocol_cleanup();
 	ip_vs_control_cleanup();
 	ip_vs_estimator_cleanup();
-	IP_VS_INFO("ipvs unloaded.\n");
+	pr_info("ipvs unloaded.\n");
 }
 
 module_init(ip_vs_init);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 7c1333c..fba2892 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -18,6 +18,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -340,8 +343,8 @@ static int ip_vs_svc_hash(struct ip_vs_service *svc)
 	unsigned hash;
 
 	if (svc->flags & IP_VS_SVC_F_HASHED) {
-		IP_VS_ERR("ip_vs_svc_hash(): request for already hashed, "
-			  "called from %p\n", __builtin_return_address(0));
+		pr_err("%s(): request for already hashed, called from %pF\n",
+		       __func__, __builtin_return_address(0));
 		return 0;
 	}
 
@@ -374,8 +377,8 @@ static int ip_vs_svc_hash(struct ip_vs_service *svc)
 static int ip_vs_svc_unhash(struct ip_vs_service *svc)
 {
 	if (!(svc->flags & IP_VS_SVC_F_HASHED)) {
-		IP_VS_ERR("ip_vs_svc_unhash(): request for unhash flagged, "
-			  "called from %p\n", __builtin_return_address(0));
+		pr_err("%s(): request for unhash flagged, called from %pF\n",
+		       __func__, __builtin_return_address(0));
 		return 0;
 	}
 
@@ -841,7 +844,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
 
 	dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC);
 	if (dest == NULL) {
-		IP_VS_ERR("ip_vs_new_dest: kmalloc failed.\n");
+		pr_err("%s(): no memory.\n", __func__);
 		return -ENOMEM;
 	}
 
@@ -885,13 +888,13 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 	EnterFunction(2);
 
 	if (udest->weight < 0) {
-		IP_VS_ERR("ip_vs_add_dest(): server weight less than zero\n");
+		pr_err("%s(): server weight less than zero\n", __func__);
 		return -ERANGE;
 	}
 
 	if (udest->l_threshold > udest->u_threshold) {
-		IP_VS_ERR("ip_vs_add_dest(): lower threshold is higher than "
-			  "upper threshold\n");
+		pr_err("%s(): lower threshold is higher than upper threshold\n",
+			__func__);
 		return -ERANGE;
 	}
 
@@ -903,7 +906,7 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 	dest = ip_vs_lookup_dest(svc, &daddr, dport);
 
 	if (dest != NULL) {
-		IP_VS_DBG(1, "ip_vs_add_dest(): dest already exists\n");
+		IP_VS_DBG(1, "%s(): dest already exists\n", __func__);
 		return -EEXIST;
 	}
 
@@ -997,13 +1000,13 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 	EnterFunction(2);
 
 	if (udest->weight < 0) {
-		IP_VS_ERR("ip_vs_edit_dest(): server weight less than zero\n");
+		pr_err("%s(): server weight less than zero\n", __func__);
 		return -ERANGE;
 	}
 
 	if (udest->l_threshold > udest->u_threshold) {
-		IP_VS_ERR("ip_vs_edit_dest(): lower threshold is higher than "
-			  "upper threshold\n");
+		pr_err("%s(): lower threshold is higher than upper threshold\n",
+			__func__);
 		return -ERANGE;
 	}
 
@@ -1015,7 +1018,7 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 	dest = ip_vs_lookup_dest(svc, &daddr, dport);
 
 	if (dest == NULL) {
-		IP_VS_DBG(1, "ip_vs_edit_dest(): dest doesn't exist\n");
+		IP_VS_DBG(1, "%s(): dest doesn't exist\n", __func__);
 		return -ENOENT;
 	}
 
@@ -1115,7 +1118,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
 	dest = ip_vs_lookup_dest(svc, &udest->addr, dport);
 
 	if (dest == NULL) {
-		IP_VS_DBG(1, "ip_vs_del_dest(): destination not found!\n");
+		IP_VS_DBG(1, "%s(): destination not found!\n", __func__);
 		return -ENOENT;
 	}
 
@@ -1161,8 +1164,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
 	/* Lookup the scheduler by 'u->sched_name' */
 	sched = ip_vs_scheduler_get(u->sched_name);
 	if (sched == NULL) {
-		IP_VS_INFO("Scheduler module ip_vs_%s not found\n",
-			   u->sched_name);
+		pr_info("Scheduler module ip_vs_%s not found\n", u->sched_name);
 		ret = -ENOENT;
 		goto out_mod_dec;
 	}
@@ -1176,7 +1178,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
 
 	svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
 	if (svc == NULL) {
-		IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n");
+		IP_VS_DBG(1, "%s(): no memory\n", __func__);
 		ret = -ENOMEM;
 		goto out_err;
 	}
@@ -1259,8 +1261,7 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
 	 */
 	sched = ip_vs_scheduler_get(u->sched_name);
 	if (sched == NULL) {
-		IP_VS_INFO("Scheduler module ip_vs_%s not found\n",
-			   u->sched_name);
+		pr_info("Scheduler module ip_vs_%s not found\n", u->sched_name);
 		return -ENOENT;
 	}
 	old_sched = sched;
@@ -2077,8 +2078,8 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 		return -EPERM;
 
 	if (len != set_arglen[SET_CMDID(cmd)]) {
-		IP_VS_ERR("set_ctl: len %u != %u\n",
-			  len, set_arglen[SET_CMDID(cmd)]);
+		pr_err("set_ctl: len %u != %u\n",
+		       len, set_arglen[SET_CMDID(cmd)]);
 		return -EINVAL;
 	}
 
@@ -2129,9 +2130,9 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 
 	/* Check for valid protocol: TCP or UDP, even for fwmark!=0 */
 	if (usvc.protocol != IPPROTO_TCP && usvc.protocol != IPPROTO_UDP) {
-		IP_VS_ERR("set_ctl: invalid protocol: %d %pI4:%d %s\n",
-			  usvc.protocol, &usvc.addr.ip,
-			  ntohs(usvc.port), usvc.sched_name);
+		pr_err("set_ctl: invalid protocol: %d %pI4:%d %s\n",
+		       usvc.protocol, &usvc.addr.ip,
+		       ntohs(usvc.port), usvc.sched_name);
 		ret = -EFAULT;
 		goto out_unlock;
 	}
@@ -2356,8 +2357,8 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 		return -EPERM;
 
 	if (*len < get_arglen[GET_CMDID(cmd)]) {
-		IP_VS_ERR("get_ctl: len %u < %u\n",
-			  *len, get_arglen[GET_CMDID(cmd)]);
+		pr_err("get_ctl: len %u < %u\n",
+		       *len, get_arglen[GET_CMDID(cmd)]);
 		return -EINVAL;
 	}
 
@@ -2402,7 +2403,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 		size = sizeof(*get) +
 			sizeof(struct ip_vs_service_entry) * get->num_services;
 		if (*len != size) {
-			IP_VS_ERR("length: %u != %u\n", *len, size);
+			pr_err("length: %u != %u\n", *len, size);
 			ret = -EINVAL;
 			goto out;
 		}
@@ -2442,7 +2443,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 		size = sizeof(*get) +
 			sizeof(struct ip_vs_dest_entry) * get->num_dests;
 		if (*len != size) {
-			IP_VS_ERR("length: %u != %u\n", *len, size);
+			pr_err("length: %u != %u\n", *len, size);
 			ret = -EINVAL;
 			goto out;
 		}
@@ -3170,7 +3171,7 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
 	else if (cmd == IPVS_CMD_GET_CONFIG)
 		reply_cmd = IPVS_CMD_SET_CONFIG;
 	else {
-		IP_VS_ERR("unknown Generic Netlink command\n");
+		pr_err("unknown Generic Netlink command\n");
 		return -EINVAL;
 	}
 
@@ -3231,11 +3232,11 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	genlmsg_end(msg, reply);
-	ret = genlmsg_unicast(msg, info->snd_pid);
+	ret = genlmsg_reply(msg, info);
 	goto out;
 
 nla_put_failure:
-	IP_VS_ERR("not enough space in Netlink message\n");
+	pr_err("not enough space in Netlink message\n");
 	ret = -EMSGSIZE;
 
 out_err:
@@ -3366,13 +3367,13 @@ int __init ip_vs_control_init(void)
 
 	ret = nf_register_sockopt(&ip_vs_sockopts);
 	if (ret) {
-		IP_VS_ERR("cannot register sockopt.\n");
+		pr_err("cannot register sockopt.\n");
 		return ret;
 	}
 
 	ret = ip_vs_genl_register();
 	if (ret) {
-		IP_VS_ERR("cannot register Generic Netlink interface.\n");
+		pr_err("cannot register Generic Netlink interface.\n");
 		nf_unregister_sockopt(&ip_vs_sockopts);
 		return ret;
 	}
diff --git a/net/netfilter/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c
index a9dac74..fe3e188 100644
--- a/net/netfilter/ipvs/ip_vs_dh.c
+++ b/net/netfilter/ipvs/ip_vs_dh.c
@@ -35,6 +35,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -147,7 +150,7 @@ static int ip_vs_dh_init_svc(struct ip_vs_service *svc)
 	tbl = kmalloc(sizeof(struct ip_vs_dh_bucket)*IP_VS_DH_TAB_SIZE,
 		      GFP_ATOMIC);
 	if (tbl == NULL) {
-		IP_VS_ERR("ip_vs_dh_init_svc(): no memory\n");
+		pr_err("%s(): no memory\n", __func__);
 		return -ENOMEM;
 	}
 	svc->sched_data = tbl;
@@ -214,7 +217,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 
 	ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
-	IP_VS_DBG(6, "ip_vs_dh_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	tbl = (struct ip_vs_dh_bucket *)svc->sched_data;
 	dest = ip_vs_dh_get(svc->af, tbl, &iph.daddr);
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
index 2eb2860..702b53c 100644
--- a/net/netfilter/ipvs/ip_vs_est.c
+++ b/net/netfilter/ipvs/ip_vs_est.c
@@ -11,6 +11,10 @@
  * Changes:
  *
  */
+
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/jiffies.h>
 #include <linux/slab.h>
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 428edbf..33e2c79 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -22,6 +22,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -382,8 +385,8 @@ static int __init ip_vs_ftp_init(void)
 		ret = register_ip_vs_app_inc(app, app->protocol, ports[i]);
 		if (ret)
 			break;
-		IP_VS_INFO("%s: loaded support on port[%d] = %d\n",
-			   app->name, i, ports[i]);
+		pr_info("%s: loaded support on port[%d] = %d\n",
+			app->name, i, ports[i]);
 	}
 
 	if (ret)
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 3eb5e26..c1757f3 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -39,6 +39,9 @@
  * me to write this module.
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -199,7 +202,7 @@ ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, const union nf_inet_addr *daddr,
 	if (!en) {
 		en = kmalloc(sizeof(*en), GFP_ATOMIC);
 		if (!en) {
-			IP_VS_ERR("ip_vs_lblc_new(): no memory\n");
+			pr_err("%s(): no memory\n", __func__);
 			return NULL;
 		}
 
@@ -332,7 +335,7 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc)
 	 */
 	tbl = kmalloc(sizeof(*tbl), GFP_ATOMIC);
 	if (tbl == NULL) {
-		IP_VS_ERR("ip_vs_lblc_init_svc(): no memory\n");
+		pr_err("%s(): no memory\n", __func__);
 		return -ENOMEM;
 	}
 	svc->sched_data = tbl;
@@ -477,7 +480,7 @@ ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 
 	ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
-	IP_VS_DBG(6, "ip_vs_lblc_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	/* First look in our cache */
 	read_lock(&svc->sched_lock);
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index c04ce56..715b57f 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -37,6 +37,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -108,7 +111,7 @@ ip_vs_dest_set_insert(struct ip_vs_dest_set *set, struct ip_vs_dest *dest)
 
 	e = kmalloc(sizeof(*e), GFP_ATOMIC);
 	if (e == NULL) {
-		IP_VS_ERR("ip_vs_dest_set_insert(): no memory\n");
+		pr_err("%s(): no memory\n", __func__);
 		return NULL;
 	}
 
@@ -202,8 +205,9 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
 		}
 	}
 
-	IP_VS_DBG_BUF(6, "ip_vs_dest_set_min: server %s:%d "
+	IP_VS_DBG_BUF(6, "%s(): server %s:%d "
 		      "activeconns %d refcnt %d weight %d overhead %d\n",
+		      __func__,
 		      IP_VS_DBG_ADDR(least->af, &least->addr),
 		      ntohs(least->port),
 		      atomic_read(&least->activeconns),
@@ -249,8 +253,9 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
 		}
 	}
 
-	IP_VS_DBG_BUF(6, "ip_vs_dest_set_max: server %s:%d "
+	IP_VS_DBG_BUF(6, "%s(): server %s:%d "
 		      "activeconns %d refcnt %d weight %d overhead %d\n",
+		      __func__,
 		      IP_VS_DBG_ADDR(most->af, &most->addr), ntohs(most->port),
 		      atomic_read(&most->activeconns),
 		      atomic_read(&most->refcnt),
@@ -374,7 +379,7 @@ ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl, const union nf_inet_addr *daddr,
 	if (!en) {
 		en = kmalloc(sizeof(*en), GFP_ATOMIC);
 		if (!en) {
-			IP_VS_ERR("ip_vs_lblcr_new(): no memory\n");
+			pr_err("%s(): no memory\n", __func__);
 			return NULL;
 		}
 
@@ -508,7 +513,7 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
 	 */
 	tbl = kmalloc(sizeof(*tbl), GFP_ATOMIC);
 	if (tbl == NULL) {
-		IP_VS_ERR("ip_vs_lblcr_init_svc(): no memory\n");
+		pr_err("%s(): no memory\n", __func__);
 		return -ENOMEM;
 	}
 	svc->sched_data = tbl;
@@ -654,7 +659,7 @@ ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 
 	ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
 
-	IP_VS_DBG(6, "ip_vs_lblcr_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	/* First look in our cache */
 	read_lock(&svc->sched_lock);
diff --git a/net/netfilter/ipvs/ip_vs_lc.c b/net/netfilter/ipvs/ip_vs_lc.c
index d0dadc8..4f69db1 100644
--- a/net/netfilter/ipvs/ip_vs_lc.c
+++ b/net/netfilter/ipvs/ip_vs_lc.c
@@ -14,6 +14,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 
@@ -44,7 +47,7 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 	struct ip_vs_dest *dest, *least = NULL;
 	unsigned int loh = 0, doh;
 
-	IP_VS_DBG(6, "ip_vs_lc_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	/*
 	 * Simply select the server with the least number of
diff --git a/net/netfilter/ipvs/ip_vs_nq.c b/net/netfilter/ipvs/ip_vs_nq.c
index 694952d..c413e18 100644
--- a/net/netfilter/ipvs/ip_vs_nq.c
+++ b/net/netfilter/ipvs/ip_vs_nq.c
@@ -31,6 +31,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 
@@ -57,7 +60,7 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 	struct ip_vs_dest *dest, *least = NULL;
 	unsigned int loh = 0, doh;
 
-	IP_VS_DBG(6, "ip_vs_nq_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	/*
 	 * We calculate the load of each dest server as follows:
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index a01520e..3e76716 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -13,6 +13,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
@@ -124,7 +127,8 @@ ip_vs_create_timeout_table(int *table, int size)
  *	Set timeout value for state specified by name
  */
 int
-ip_vs_set_state_timeout(int *table, int num, char **names, char *name, int to)
+ip_vs_set_state_timeout(int *table, int num, const char *const *names,
+			const char *name, int to)
 {
 	int i;
 
@@ -181,7 +185,7 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
 				&ih->daddr, ntohs(pptr[1]));
 	}
 
-	printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
+	pr_debug("%s: %s\n", msg, buf);
 }
 
 #ifdef CONFIG_IP_VS_IPV6
@@ -215,7 +219,7 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
 				&ih->daddr, ntohs(pptr[1]));
 	}
 
-	printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
+	pr_debug("%s: %s\n", msg, buf);
 }
 #endif
 
@@ -259,7 +263,7 @@ int __init ip_vs_protocol_init(void)
 #ifdef CONFIG_IP_VS_PROTO_ESP
 	REGISTER_PROTOCOL(&ip_vs_protocol_esp);
 #endif
-	IP_VS_INFO("Registered protocols (%s)\n", &protocols[2]);
+	pr_info("Registered protocols (%s)\n", &protocols[2]);
 
 	return 0;
 }
diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
index 79f56c1..c30b43c 100644
--- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
@@ -10,6 +10,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/module.h>
@@ -138,7 +141,7 @@ ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
 		sprintf(buf, "%s %pI4->%pI4",
 			pp->name, &ih->saddr, &ih->daddr);
 
-	printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
+	pr_debug("%s: %s\n", msg, buf);
 }
 
 #ifdef CONFIG_IP_VS_IPV6
@@ -156,7 +159,7 @@ ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
 		sprintf(buf, "%s %pI6->%pI6",
 			pp->name, &ih->saddr, &ih->daddr);
 
-	printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
+	pr_debug("%s: %s\n", msg, buf);
 }
 #endif
 
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index 8cba418..91d28e0 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -13,6 +13,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>                  /* for tcphdr */
@@ -374,7 +377,7 @@ static int tcp_timeouts[IP_VS_TCP_S_LAST+1] = {
 	[IP_VS_TCP_S_LAST]		=	2*HZ,
 };
 
-static char * tcp_state_name_table[IP_VS_TCP_S_LAST+1] = {
+static const char *const tcp_state_name_table[IP_VS_TCP_S_LAST+1] = {
 	[IP_VS_TCP_S_NONE]		=	"NONE",
 	[IP_VS_TCP_S_ESTABLISHED]	=	"ESTABLISHED",
 	[IP_VS_TCP_S_SYN_SENT]		=	"SYN_SENT",
@@ -661,7 +664,7 @@ tcp_app_conn_bind(struct ip_vs_conn *cp)
 				break;
 			spin_unlock(&tcp_app_lock);
 
-			IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
+			IP_VS_DBG_BUF(9, "%s(): Binding conn %s:%u->"
 				      "%s:%u to app %s on port %u\n",
 				      __func__,
 				      IP_VS_DBG_ADDR(cp->af, &cp->caddr),
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index d2930a7..e7a6885 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -13,6 +13,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/kernel.h>
@@ -442,7 +445,7 @@ static int udp_app_conn_bind(struct ip_vs_conn *cp)
 				break;
 			spin_unlock(&udp_app_lock);
 
-			IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
+			IP_VS_DBG_BUF(9, "%s(): Binding conn %s:%u->"
 				      "%s:%u to app %s on port %u\n",
 				      __func__,
 				      IP_VS_DBG_ADDR(cp->af, &cp->caddr),
@@ -469,7 +472,7 @@ static int udp_timeouts[IP_VS_UDP_S_LAST+1] = {
 	[IP_VS_UDP_S_LAST]		=	2*HZ,
 };
 
-static char * udp_state_name_table[IP_VS_UDP_S_LAST+1] = {
+static const char *const udp_state_name_table[IP_VS_UDP_S_LAST+1] = {
 	[IP_VS_UDP_S_NORMAL]		=	"UDP",
 	[IP_VS_UDP_S_LAST]		=	"BUG!",
 };
diff --git a/net/netfilter/ipvs/ip_vs_rr.c b/net/netfilter/ipvs/ip_vs_rr.c
index 2d16ab7..e210f37 100644
--- a/net/netfilter/ipvs/ip_vs_rr.c
+++ b/net/netfilter/ipvs/ip_vs_rr.c
@@ -19,6 +19,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 
@@ -48,7 +51,7 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 	struct list_head *p, *q;
 	struct ip_vs_dest *dest;
 
-	IP_VS_DBG(6, "ip_vs_rr_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	write_lock(&svc->sched_lock);
 	p = (struct list_head *)svc->sched_data;
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index a46ad9e..bbc1ac7 100644
--- a/net/netfilter/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
@@ -17,6 +17,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
@@ -44,11 +47,11 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc,
 	int ret;
 
 	if (svc == NULL) {
-		IP_VS_ERR("ip_vs_bind_scheduler(): svc arg NULL\n");
+		pr_err("%s(): svc arg NULL\n", __func__);
 		return -EINVAL;
 	}
 	if (scheduler == NULL) {
-		IP_VS_ERR("ip_vs_bind_scheduler(): scheduler arg NULL\n");
+		pr_err("%s(): scheduler arg NULL\n", __func__);
 		return -EINVAL;
 	}
 
@@ -57,7 +60,7 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc,
 	if (scheduler->init_service) {
 		ret = scheduler->init_service(svc);
 		if (ret) {
-			IP_VS_ERR("ip_vs_bind_scheduler(): init error\n");
+			pr_err("%s(): init error\n", __func__);
 			return ret;
 		}
 	}
@@ -74,19 +77,19 @@ int ip_vs_unbind_scheduler(struct ip_vs_service *svc)
 	struct ip_vs_scheduler *sched;
 
 	if (svc == NULL) {
-		IP_VS_ERR("ip_vs_unbind_scheduler(): svc arg NULL\n");
+		pr_err("%s(): svc arg NULL\n", __func__);
 		return -EINVAL;
 	}
 
 	sched = svc->scheduler;
 	if (sched == NULL) {
-		IP_VS_ERR("ip_vs_unbind_scheduler(): svc isn't bound\n");
+		pr_err("%s(): svc isn't bound\n", __func__);
 		return -EINVAL;
 	}
 
 	if (sched->done_service) {
 		if (sched->done_service(svc) != 0) {
-			IP_VS_ERR("ip_vs_unbind_scheduler(): done error\n");
+			pr_err("%s(): done error\n", __func__);
 			return -EINVAL;
 		}
 	}
@@ -103,8 +106,7 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name)
 {
 	struct ip_vs_scheduler *sched;
 
-	IP_VS_DBG(2, "ip_vs_sched_getbyname(): sched_name \"%s\"\n",
-		  sched_name);
+	IP_VS_DBG(2, "%s(): sched_name \"%s\"\n", __func__, sched_name);
 
 	read_lock_bh(&__ip_vs_sched_lock);
 
@@ -170,12 +172,12 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
 	struct ip_vs_scheduler *sched;
 
 	if (!scheduler) {
-		IP_VS_ERR("register_ip_vs_scheduler(): NULL arg\n");
+		pr_err("%s(): NULL arg\n", __func__);
 		return -EINVAL;
 	}
 
 	if (!scheduler->name) {
-		IP_VS_ERR("register_ip_vs_scheduler(): NULL scheduler_name\n");
+		pr_err("%s(): NULL scheduler_name\n", __func__);
 		return -EINVAL;
 	}
 
@@ -187,8 +189,8 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
 	if (!list_empty(&scheduler->n_list)) {
 		write_unlock_bh(&__ip_vs_sched_lock);
 		ip_vs_use_count_dec();
-		IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler "
-			  "already linked\n", scheduler->name);
+		pr_err("%s(): [%s] scheduler already linked\n",
+		       __func__, scheduler->name);
 		return -EINVAL;
 	}
 
@@ -200,9 +202,8 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
 		if (strcmp(scheduler->name, sched->name) == 0) {
 			write_unlock_bh(&__ip_vs_sched_lock);
 			ip_vs_use_count_dec();
-			IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler "
-					"already existed in the system\n",
-					scheduler->name);
+			pr_err("%s(): [%s] scheduler already existed "
+			       "in the system\n", __func__, scheduler->name);
 			return -EINVAL;
 		}
 	}
@@ -212,7 +213,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
 	list_add(&scheduler->n_list, &ip_vs_schedulers);
 	write_unlock_bh(&__ip_vs_sched_lock);
 
-	IP_VS_INFO("[%s] scheduler registered.\n", scheduler->name);
+	pr_info("[%s] scheduler registered.\n", scheduler->name);
 
 	return 0;
 }
@@ -224,15 +225,15 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
 int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
 {
 	if (!scheduler) {
-		IP_VS_ERR( "unregister_ip_vs_scheduler(): NULL arg\n");
+		pr_err("%s(): NULL arg\n", __func__);
 		return -EINVAL;
 	}
 
 	write_lock_bh(&__ip_vs_sched_lock);
 	if (list_empty(&scheduler->n_list)) {
 		write_unlock_bh(&__ip_vs_sched_lock);
-		IP_VS_ERR("unregister_ip_vs_scheduler(): [%s] scheduler "
-			  "is not in the list. failed\n", scheduler->name);
+		pr_err("%s(): [%s] scheduler is not in the list. failed\n",
+		       __func__, scheduler->name);
 		return -EINVAL;
 	}
 
@@ -245,7 +246,7 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
 	/* decrease the module use count */
 	ip_vs_use_count_dec();
 
-	IP_VS_INFO("[%s] scheduler unregistered.\n", scheduler->name);
+	pr_info("[%s] scheduler unregistered.\n", scheduler->name);
 
 	return 0;
 }
diff --git a/net/netfilter/ipvs/ip_vs_sed.c b/net/netfilter/ipvs/ip_vs_sed.c
index 20e4657..1ab75a9 100644
--- a/net/netfilter/ipvs/ip_vs_sed.c
+++ b/net/netfilter/ipvs/ip_vs_sed.c
@@ -35,6 +35,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 
@@ -61,7 +64,7 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 	struct ip_vs_dest *dest, *least;
 	unsigned int loh, doh;
 
-	IP_VS_DBG(6, "ip_vs_sed_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	/*
 	 * We calculate the load of each dest server as follows:
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c
index 75709eb..8e6cfd3 100644
--- a/net/netfilter/ipvs/ip_vs_sh.c
+++ b/net/netfilter/ipvs/ip_vs_sh.c
@@ -32,6 +32,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -144,7 +147,7 @@ static int ip_vs_sh_init_svc(struct ip_vs_service *svc)
 	tbl = kmalloc(sizeof(struct ip_vs_sh_bucket)*IP_VS_SH_TAB_SIZE,
 		      GFP_ATOMIC);
 	if (tbl == NULL) {
-		IP_VS_ERR("ip_vs_sh_init_svc(): no memory\n");
+		pr_err("%s(): no memory\n", __func__);
 		return -ENOMEM;
 	}
 	svc->sched_data = tbl;
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 5c48378..e177f0d 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -17,6 +17,9 @@
  *	Justin Ossevoort	:	Fix endian problem on sync message size.
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/inetdevice.h>
@@ -243,7 +246,7 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp)
 	if (!curr_sb) {
 		if (!(curr_sb=ip_vs_sync_buff_create())) {
 			spin_unlock(&curr_sb_lock);
-			IP_VS_ERR("ip_vs_sync_buff_create failed.\n");
+			pr_err("ip_vs_sync_buff_create failed.\n");
 			return;
 		}
 	}
@@ -409,7 +412,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
 			if (dest)
 				atomic_dec(&dest->refcnt);
 			if (!cp) {
-				IP_VS_ERR("ip_vs_conn_new failed\n");
+				pr_err("ip_vs_conn_new failed\n");
 				return;
 			}
 		} else if (!cp->dest) {
@@ -577,8 +580,8 @@ static int bind_mcastif_addr(struct socket *sock, char *ifname)
 
 	addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
 	if (!addr)
-		IP_VS_ERR("You probably need to specify IP address on "
-			  "multicast interface.\n");
+		pr_err("You probably need to specify IP address on "
+		       "multicast interface.\n");
 
 	IP_VS_DBG(7, "binding socket with (%s) %pI4\n",
 		  ifname, &addr);
@@ -602,13 +605,13 @@ static struct socket * make_send_sock(void)
 	/* First create a socket */
 	result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
 	if (result < 0) {
-		IP_VS_ERR("Error during creation of socket; terminating\n");
+		pr_err("Error during creation of socket; terminating\n");
 		return ERR_PTR(result);
 	}
 
 	result = set_mcast_if(sock->sk, ip_vs_master_mcast_ifn);
 	if (result < 0) {
-		IP_VS_ERR("Error setting outbound mcast interface\n");
+		pr_err("Error setting outbound mcast interface\n");
 		goto error;
 	}
 
@@ -617,14 +620,14 @@ static struct socket * make_send_sock(void)
 
 	result = bind_mcastif_addr(sock, ip_vs_master_mcast_ifn);
 	if (result < 0) {
-		IP_VS_ERR("Error binding address of the mcast interface\n");
+		pr_err("Error binding address of the mcast interface\n");
 		goto error;
 	}
 
 	result = sock->ops->connect(sock, (struct sockaddr *) &mcast_addr,
 			sizeof(struct sockaddr), 0);
 	if (result < 0) {
-		IP_VS_ERR("Error connecting to the multicast addr\n");
+		pr_err("Error connecting to the multicast addr\n");
 		goto error;
 	}
 
@@ -647,7 +650,7 @@ static struct socket * make_receive_sock(void)
 	/* First create a socket */
 	result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
 	if (result < 0) {
-		IP_VS_ERR("Error during creation of socket; terminating\n");
+		pr_err("Error during creation of socket; terminating\n");
 		return ERR_PTR(result);
 	}
 
@@ -657,7 +660,7 @@ static struct socket * make_receive_sock(void)
 	result = sock->ops->bind(sock, (struct sockaddr *) &mcast_addr,
 			sizeof(struct sockaddr));
 	if (result < 0) {
-		IP_VS_ERR("Error binding to the multicast addr\n");
+		pr_err("Error binding to the multicast addr\n");
 		goto error;
 	}
 
@@ -666,7 +669,7 @@ static struct socket * make_receive_sock(void)
 			(struct in_addr *) &mcast_addr.sin_addr,
 			ip_vs_backup_mcast_ifn);
 	if (result < 0) {
-		IP_VS_ERR("Error joining to the multicast group\n");
+		pr_err("Error joining to the multicast group\n");
 		goto error;
 	}
 
@@ -706,7 +709,7 @@ ip_vs_send_sync_msg(struct socket *sock, struct ip_vs_sync_mesg *msg)
 	msg->size = htons(msg->size);
 
 	if (ip_vs_send_async(sock, (char *)msg, msize) != msize)
-		IP_VS_ERR("ip_vs_send_async error\n");
+		pr_err("ip_vs_send_async error\n");
 }
 
 static int
@@ -737,9 +740,9 @@ static int sync_thread_master(void *data)
 	struct ip_vs_sync_thread_data *tinfo = data;
 	struct ip_vs_sync_buff *sb;
 
-	IP_VS_INFO("sync thread started: state = MASTER, mcast_ifn = %s, "
-		   "syncid = %d\n",
-		   ip_vs_master_mcast_ifn, ip_vs_master_syncid);
+	pr_info("sync thread started: state = MASTER, mcast_ifn = %s, "
+		"syncid = %d\n",
+		ip_vs_master_mcast_ifn, ip_vs_master_syncid);
 
 	while (!kthread_should_stop()) {
 		while ((sb = sb_dequeue())) {
@@ -780,9 +783,9 @@ static int sync_thread_backup(void *data)
 	struct ip_vs_sync_thread_data *tinfo = data;
 	int len;
 
-	IP_VS_INFO("sync thread started: state = BACKUP, mcast_ifn = %s, "
-		   "syncid = %d\n",
-		   ip_vs_backup_mcast_ifn, ip_vs_backup_syncid);
+	pr_info("sync thread started: state = BACKUP, mcast_ifn = %s, "
+		"syncid = %d\n",
+		ip_vs_backup_mcast_ifn, ip_vs_backup_syncid);
 
 	while (!kthread_should_stop()) {
 		wait_event_interruptible(*tinfo->sock->sk->sk_sleep,
@@ -794,7 +797,7 @@ static int sync_thread_backup(void *data)
 			len = ip_vs_receive(tinfo->sock, tinfo->buf,
 					sync_recv_mesg_maxlen);
 			if (len <= 0) {
-				IP_VS_ERR("receiving message error\n");
+				pr_err("receiving message error\n");
 				break;
 			}
 
@@ -824,7 +827,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
 	int (*threadfn)(void *data);
 	int result = -ENOMEM;
 
-	IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current));
+	IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current));
 	IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n",
 		  sizeof(struct ip_vs_sync_conn));
 
@@ -901,14 +904,14 @@ out:
 
 int stop_sync_thread(int state)
 {
-	IP_VS_DBG(7, "%s: pid %d\n", __func__, task_pid_nr(current));
+	IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current));
 
 	if (state == IP_VS_STATE_MASTER) {
 		if (!sync_master_thread)
 			return -ESRCH;
 
-		IP_VS_INFO("stopping master sync thread %d ...\n",
-			   task_pid_nr(sync_master_thread));
+		pr_info("stopping master sync thread %d ...\n",
+			task_pid_nr(sync_master_thread));
 
 		/*
 		 * The lock synchronizes with sb_queue_tail(), so that we don't
@@ -925,8 +928,8 @@ int stop_sync_thread(int state)
 		if (!sync_backup_thread)
 			return -ESRCH;
 
-		IP_VS_INFO("stopping backup sync thread %d ...\n",
-			   task_pid_nr(sync_backup_thread));
+		pr_info("stopping backup sync thread %d ...\n",
+			task_pid_nr(sync_backup_thread));
 
 		ip_vs_sync_state &= ~IP_VS_STATE_BACKUP;
 		kthread_stop(sync_backup_thread);
diff --git a/net/netfilter/ipvs/ip_vs_wlc.c b/net/netfilter/ipvs/ip_vs_wlc.c
index 8e94256..bbddfdb 100644
--- a/net/netfilter/ipvs/ip_vs_wlc.c
+++ b/net/netfilter/ipvs/ip_vs_wlc.c
@@ -19,6 +19,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 
diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index f7d74ef..6182e8e 100644
--- a/net/netfilter/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -18,6 +18,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/net.h>
@@ -74,11 +77,12 @@ static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc)
 static int ip_vs_wrr_max_weight(struct ip_vs_service *svc)
 {
 	struct ip_vs_dest *dest;
-	int weight = 0;
+	int new_weight, weight = 0;
 
 	list_for_each_entry(dest, &svc->destinations, n_list) {
-		if (atomic_read(&dest->weight) > weight)
-			weight = atomic_read(&dest->weight);
+		new_weight = atomic_read(&dest->weight);
+		if (new_weight > weight)
+			weight = new_weight;
 	}
 
 	return weight;
@@ -94,7 +98,7 @@ static int ip_vs_wrr_init_svc(struct ip_vs_service *svc)
 	 */
 	mark = kmalloc(sizeof(struct ip_vs_wrr_mark), GFP_ATOMIC);
 	if (mark == NULL) {
-		IP_VS_ERR("ip_vs_wrr_init_svc(): no memory\n");
+		pr_err("%s(): no memory\n", __func__);
 		return -ENOMEM;
 	}
 	mark->cl = &svc->destinations;
@@ -141,7 +145,7 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
 	struct ip_vs_wrr_mark *mark = svc->sched_data;
 	struct list_head *p;
 
-	IP_VS_DBG(6, "ip_vs_wrr_schedule(): Scheduling...\n");
+	IP_VS_DBG(6, "%s(): Scheduling...\n", __func__);
 
 	/*
 	 * This loop will always terminate, because mark->cw in (0, max_weight]
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 5874657..30b3189 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -13,6 +13,9 @@
  *
  */
 
+#define KMSG_COMPONENT "IPVS"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/tcp.h>                  /* for tcphdr */
 #include <net/ip.h>
@@ -235,8 +238,8 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	EnterFunction(10);
 
 	if (ip_route_output_key(&init_net, &rt, &fl)) {
-		IP_VS_DBG_RL("ip_vs_bypass_xmit(): ip_route_output error, dest: %pI4\n",
-			     &iph->daddr);
+		IP_VS_DBG_RL("%s(): ip_route_output error, dest: %pI4\n",
+			     __func__, &iph->daddr);
 		goto tx_error_icmp;
 	}
 
@@ -245,7 +248,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF))) {
 		ip_rt_put(rt);
 		icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
-		IP_VS_DBG_RL("ip_vs_bypass_xmit(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
@@ -299,8 +302,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 
 	rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
 	if (!rt) {
-		IP_VS_DBG_RL("ip_vs_bypass_xmit_v6(): ip6_route_output error, dest: %pI6\n",
-			     &iph->daddr);
+		IP_VS_DBG_RL("%s(): ip6_route_output error, dest: %pI6\n",
+			     __func__, &iph->daddr);
 		goto tx_error_icmp;
 	}
 
@@ -309,7 +312,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if (skb->len > mtu) {
 		dst_release(&rt->u.dst);
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
-		IP_VS_DBG_RL("ip_vs_bypass_xmit_v6(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
@@ -536,9 +539,9 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	EnterFunction(10);
 
 	if (skb->protocol != htons(ETH_P_IP)) {
-		IP_VS_DBG_RL("ip_vs_tunnel_xmit(): protocol error, "
+		IP_VS_DBG_RL("%s(): protocol error, "
 			     "ETH_P_IP: %d, skb protocol: %d\n",
-			     htons(ETH_P_IP), skb->protocol);
+			     __func__, htons(ETH_P_IP), skb->protocol);
 		goto tx_error;
 	}
 
@@ -550,7 +553,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
 	if (mtu < 68) {
 		ip_rt_put(rt);
-		IP_VS_DBG_RL("ip_vs_tunnel_xmit(): mtu less than 68\n");
+		IP_VS_DBG_RL("%s(): mtu less than 68\n", __func__);
 		goto tx_error;
 	}
 	if (skb_dst(skb))
@@ -562,7 +565,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	    && mtu < ntohs(old_iph->tot_len)) {
 		icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
 		ip_rt_put(rt);
-		IP_VS_DBG_RL("ip_vs_tunnel_xmit(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
@@ -578,7 +581,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 		if (!new_skb) {
 			ip_rt_put(rt);
 			kfree_skb(skb);
-			IP_VS_ERR_RL("ip_vs_tunnel_xmit(): no memory\n");
+			IP_VS_ERR_RL("%s(): no memory\n", __func__);
 			return NF_STOLEN;
 		}
 		kfree_skb(skb);
@@ -646,9 +649,9 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	EnterFunction(10);
 
 	if (skb->protocol != htons(ETH_P_IPV6)) {
-		IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): protocol error, "
+		IP_VS_DBG_RL("%s(): protocol error, "
 			     "ETH_P_IPV6: %d, skb protocol: %d\n",
-			     htons(ETH_P_IPV6), skb->protocol);
+			     __func__, htons(ETH_P_IPV6), skb->protocol);
 		goto tx_error;
 	}
 
@@ -662,7 +665,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	/* TODO IPv6: do we need this check in IPv6? */
 	if (mtu < 1280) {
 		dst_release(&rt->u.dst);
-		IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): mtu less than 1280\n");
+		IP_VS_DBG_RL("%s(): mtu less than 1280\n", __func__);
 		goto tx_error;
 	}
 	if (skb_dst(skb))
@@ -671,7 +674,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) {
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
 		dst_release(&rt->u.dst);
-		IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
@@ -687,7 +690,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 		if (!new_skb) {
 			dst_release(&rt->u.dst);
 			kfree_skb(skb);
-			IP_VS_ERR_RL("ip_vs_tunnel_xmit_v6(): no memory\n");
+			IP_VS_ERR_RL("%s(): no memory\n", __func__);
 			return NF_STOLEN;
 		}
 		kfree_skb(skb);
@@ -760,7 +763,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if ((iph->frag_off & htons(IP_DF)) && skb->len > mtu) {
 		icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu));
 		ip_rt_put(rt);
-		IP_VS_DBG_RL("ip_vs_dr_xmit(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
@@ -813,7 +816,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if (skb->len > mtu) {
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
 		dst_release(&rt->u.dst);
-		IP_VS_DBG_RL("ip_vs_dr_xmit_v6(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
@@ -888,7 +891,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if ((skb->len > mtu) && (ip_hdr(skb)->frag_off & htons(IP_DF))) {
 		ip_rt_put(rt);
 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
-		IP_VS_DBG_RL("ip_vs_in_icmp(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
@@ -963,7 +966,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
 	if (skb->len > mtu) {
 		dst_release(&rt->u.dst);
 		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
-		IP_VS_DBG_RL("ip_vs_in_icmp(): frag needed\n");
+		IP_VS_DBG_RL("%s(): frag needed\n", __func__);
 		goto tx_error;
 	}
 
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b5869b9..b371098 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -47,7 +47,7 @@
 
 int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
 				      enum nf_nat_manip_type manip,
-				      struct nlattr *attr) __read_mostly;
+				      const struct nlattr *attr) __read_mostly;
 EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
 
 DEFINE_SPINLOCK(nf_conntrack_lock);
@@ -1089,14 +1089,14 @@ void nf_conntrack_flush_report(struct net *net, u32 pid, int report)
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
 
-static void nf_ct_release_dying_list(void)
+static void nf_ct_release_dying_list(struct net *net)
 {
 	struct nf_conntrack_tuple_hash *h;
 	struct nf_conn *ct;
 	struct hlist_nulls_node *n;
 
 	spin_lock_bh(&nf_conntrack_lock);
-	hlist_nulls_for_each_entry(h, n, &init_net.ct.dying, hnnode) {
+	hlist_nulls_for_each_entry(h, n, &net->ct.dying, hnnode) {
 		ct = nf_ct_tuplehash_to_ctrack(h);
 		/* never fails to remove them, no listeners at this point */
 		nf_ct_kill(ct);
@@ -1115,7 +1115,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
 {
  i_see_dead_people:
 	nf_ct_iterate_cleanup(net, kill_all, NULL);
-	nf_ct_release_dying_list();
+	nf_ct_release_dying_list(net);
 	if (atomic_read(&net->ct.count) != 0) {
 		schedule();
 		goto i_see_dead_people;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 49479d1..59d8064 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -704,7 +704,8 @@ ctnetlink_parse_tuple_proto(struct nlattr *attr,
 }
 
 static int
-ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
+ctnetlink_parse_tuple(const struct nlattr * const cda[],
+		      struct nf_conntrack_tuple *tuple,
 		      enum ctattr_tuple type, u_int8_t l3num)
 {
 	struct nlattr *tb[CTA_TUPLE_MAX+1];
@@ -740,7 +741,7 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
 }
 
 static inline int
-ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
+ctnetlink_parse_help(const struct nlattr *attr, char **helper_name)
 {
 	struct nlattr *tb[CTA_HELP_MAX+1];
 
@@ -764,7 +765,8 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
 
 static int
 ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
-			struct nlmsghdr *nlh, struct nlattr *cda[])
+			const struct nlmsghdr *nlh,
+			const struct nlattr * const cda[])
 {
 	struct nf_conntrack_tuple_hash *h;
 	struct nf_conntrack_tuple tuple;
@@ -823,7 +825,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
 
 static int
 ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
-			struct nlmsghdr *nlh, struct nlattr *cda[])
+			const struct nlmsghdr *nlh,
+			const struct nlattr * const cda[])
 {
 	struct nf_conntrack_tuple_hash *h;
 	struct nf_conntrack_tuple tuple;
@@ -884,7 +887,7 @@ out:
 static int
 ctnetlink_parse_nat_setup(struct nf_conn *ct,
 			  enum nf_nat_manip_type manip,
-			  struct nlattr *attr)
+			  const struct nlattr *attr)
 {
 	typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
 
@@ -914,7 +917,7 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
 #endif
 
 static int
-ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
 {
 	unsigned long d;
 	unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
@@ -940,7 +943,7 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static int
-ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[])
 {
 #ifdef CONFIG_NF_NAT_NEEDED
 	int ret;
@@ -966,7 +969,7 @@ ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static inline int
-ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
 {
 	struct nf_conntrack_helper *helper;
 	struct nf_conn_help *help = nfct_help(ct);
@@ -1028,7 +1031,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static inline int
-ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_timeout(struct nf_conn *ct, const struct nlattr * const cda[])
 {
 	u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
 
@@ -1042,9 +1045,10 @@ ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static inline int
-ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_protoinfo(struct nf_conn *ct, const struct nlattr * const cda[])
 {
-	struct nlattr *tb[CTA_PROTOINFO_MAX+1], *attr = cda[CTA_PROTOINFO];
+	const struct nlattr *attr = cda[CTA_PROTOINFO];
+	struct nlattr *tb[CTA_PROTOINFO_MAX+1];
 	struct nf_conntrack_l4proto *l4proto;
 	int err = 0;
 
@@ -1061,7 +1065,7 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[])
 
 #ifdef CONFIG_NF_NAT_NEEDED
 static inline int
-change_nat_seq_adj(struct nf_nat_seq *natseq, struct nlattr *attr)
+change_nat_seq_adj(struct nf_nat_seq *natseq, const struct nlattr * const attr)
 {
 	struct nlattr *cda[CTA_NAT_SEQ_MAX+1];
 
@@ -1089,7 +1093,8 @@ change_nat_seq_adj(struct nf_nat_seq *natseq, struct nlattr *attr)
 }
 
 static int
-ctnetlink_change_nat_seq_adj(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_nat_seq_adj(struct nf_conn *ct,
+			     const struct nlattr * const cda[])
 {
 	int ret = 0;
 	struct nf_conn_nat *nat = nfct_nat(ct);
@@ -1120,7 +1125,8 @@ ctnetlink_change_nat_seq_adj(struct nf_conn *ct, struct nlattr *cda[])
 #endif
 
 static int
-ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
+ctnetlink_change_conntrack(struct nf_conn *ct,
+			   const struct nlattr * const cda[])
 {
 	int err;
 
@@ -1169,7 +1175,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
 }
 
 static struct nf_conn *
-ctnetlink_create_conntrack(struct nlattr *cda[],
+ctnetlink_create_conntrack(const struct nlattr * const cda[],
 			   struct nf_conntrack_tuple *otuple,
 			   struct nf_conntrack_tuple *rtuple,
 			   u8 u3)
@@ -1304,7 +1310,8 @@ err1:
 
 static int
 ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
-			struct nlmsghdr *nlh, struct nlattr *cda[])
+			const struct nlmsghdr *nlh,
+			const struct nlattr * const cda[])
 {
 	struct nf_conntrack_tuple otuple, rtuple;
 	struct nf_conntrack_tuple_hash *h = NULL;
@@ -1629,7 +1636,8 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
 
 static int
 ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
-		     struct nlmsghdr *nlh, struct nlattr *cda[])
+		     const struct nlmsghdr *nlh,
+		     const struct nlattr * const cda[])
 {
 	struct nf_conntrack_tuple tuple;
 	struct nf_conntrack_expect *exp;
@@ -1689,7 +1697,8 @@ out:
 
 static int
 ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
-		     struct nlmsghdr *nlh, struct nlattr *cda[])
+		     const struct nlmsghdr *nlh,
+		     const struct nlattr * const cda[])
 {
 	struct nf_conntrack_expect *exp;
 	struct nf_conntrack_tuple tuple;
@@ -1767,13 +1776,15 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
 	return 0;
 }
 static int
-ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nlattr *cda[])
+ctnetlink_change_expect(struct nf_conntrack_expect *x,
+			const struct nlattr * const cda[])
 {
 	return -EOPNOTSUPP;
 }
 
 static int
-ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3, u32 pid, int report)
+ctnetlink_create_expect(const struct nlattr * const cda[], u_int8_t u3,
+			u32 pid, int report)
 {
 	struct nf_conntrack_tuple tuple, mask, master_tuple;
 	struct nf_conntrack_tuple_hash *h = NULL;
@@ -1831,7 +1842,8 @@ out:
 
 static int
 ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
-		     struct nlmsghdr *nlh, struct nlattr *cda[])
+		     const struct nlmsghdr *nlh,
+		     const struct nlattr * const cda[])
 {
 	struct nf_conntrack_tuple tuple;
 	struct nf_conntrack_expect *exp;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 92761a9..eedc0c1 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -170,7 +170,7 @@ replay:
 		if (err < 0)
 			return err;
 
-		err = nc->call(nfnl, skb, nlh, cda);
+		err = nc->call(nfnl, skb, nlh, (const struct nlattr **)cda);
 		if (err == -EAGAIN)
 			goto replay;
 		return err;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 66a6dd5..f900dc3 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -694,7 +694,8 @@ static struct notifier_block nfulnl_rtnl_notifier = {
 
 static int
 nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
-		  struct nlmsghdr *nlh, struct nlattr *nfqa[])
+		   const struct nlmsghdr *nlh,
+		   const struct nlattr * const nfqa[])
 {
 	return -ENOTSUPP;
 }
@@ -716,7 +717,8 @@ static const struct nla_policy nfula_cfg_policy[NFULA_CFG_MAX+1] = {
 
 static int
 nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
-		   struct nlmsghdr *nlh, struct nlattr *nfula[])
+		   const struct nlmsghdr *nlh,
+		   const struct nlattr * const nfula[])
 {
 	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
 	u_int16_t group_num = ntohs(nfmsg->res_id);
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 71daa09..7a9dec9 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -608,7 +608,8 @@ static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = {
 
 static int
 nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
-		   struct nlmsghdr *nlh, struct nlattr *nfqa[])
+		   const struct nlmsghdr *nlh,
+		   const struct nlattr * const nfqa[])
 {
 	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
 	u_int16_t queue_num = ntohs(nfmsg->res_id);
@@ -670,7 +671,8 @@ err_out_unlock:
 
 static int
 nfqnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
-		  struct nlmsghdr *nlh, struct nlattr *nfqa[])
+		  const struct nlmsghdr *nlh,
+		  const struct nlattr * const nfqa[])
 {
 	return -ENOTSUPP;
 }
@@ -687,7 +689,8 @@ static const struct nf_queue_handler nfqh = {
 
 static int
 nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
-		  struct nlmsghdr *nlh, struct nlattr *nfqa[])
+		  const struct nlmsghdr *nlh,
+		  const struct nlattr * const nfqa[])
 {
 	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
 	u_int16_t queue_num = ntohs(nfmsg->res_id);
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 025d1a0..a6ac83a 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -736,16 +736,17 @@ xt_replace_table(struct xt_table *table,
 }
 EXPORT_SYMBOL_GPL(xt_replace_table);
 
-struct xt_table *xt_register_table(struct net *net, struct xt_table *table,
+struct xt_table *xt_register_table(struct net *net,
+				   const struct xt_table *input_table,
 				   struct xt_table_info *bootstrap,
 				   struct xt_table_info *newinfo)
 {
 	int ret;
 	struct xt_table_info *private;
-	struct xt_table *t;
+	struct xt_table *t, *table;
 
 	/* Don't add one object to multiple lists. */
-	table = kmemdup(table, sizeof(struct xt_table), GFP_KERNEL);
+	table = kmemdup(input_table, sizeof(struct xt_table), GFP_KERNEL);
 	if (!table) {
 		ret = -ENOMEM;
 		goto out;
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index d6e5ab4..5934570 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -36,45 +36,6 @@ MODULE_ALIAS("ip6t_CONNMARK");
 #include <net/netfilter/nf_conntrack_ecache.h>
 
 static unsigned int
-connmark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
-{
-	const struct xt_connmark_target_info *markinfo = par->targinfo;
-	struct nf_conn *ct;
-	enum ip_conntrack_info ctinfo;
-	u_int32_t diff;
-	u_int32_t mark;
-	u_int32_t newmark;
-
-	ct = nf_ct_get(skb, &ctinfo);
-	if (ct) {
-		switch(markinfo->mode) {
-		case XT_CONNMARK_SET:
-			newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
-			if (newmark != ct->mark) {
-				ct->mark = newmark;
-				nf_conntrack_event_cache(IPCT_MARK, ct);
-			}
-			break;
-		case XT_CONNMARK_SAVE:
-			newmark = (ct->mark & ~markinfo->mask) |
-				  (skb->mark & markinfo->mask);
-			if (ct->mark != newmark) {
-				ct->mark = newmark;
-				nf_conntrack_event_cache(IPCT_MARK, ct);
-			}
-			break;
-		case XT_CONNMARK_RESTORE:
-			mark = skb->mark;
-			diff = (ct->mark ^ mark) & markinfo->mask;
-			skb->mark = mark ^ diff;
-			break;
-		}
-	}
-
-	return XT_CONTINUE;
-}
-
-static unsigned int
 connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 	const struct xt_connmark_tginfo1 *info = par->targinfo;
@@ -112,30 +73,6 @@ connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
 	return XT_CONTINUE;
 }
 
-static bool connmark_tg_check_v0(const struct xt_tgchk_param *par)
-{
-	const struct xt_connmark_target_info *matchinfo = par->targinfo;
-
-	if (matchinfo->mode == XT_CONNMARK_RESTORE) {
-		if (strcmp(par->table, "mangle") != 0) {
-			printk(KERN_WARNING "CONNMARK: restore can only be "
-			       "called from \"mangle\" table, not \"%s\"\n",
-			       par->table);
-			return false;
-		}
-	}
-	if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) {
-		printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
-		return false;
-	}
-	if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-		printk(KERN_WARNING "can't load conntrack support for "
-				    "proto=%u\n", par->family);
-		return false;
-	}
-	return true;
-}
-
 static bool connmark_tg_check(const struct xt_tgchk_param *par)
 {
 	if (nf_ct_l3proto_try_module_get(par->family) < 0) {
@@ -151,74 +88,25 @@ static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
 	nf_ct_l3proto_module_put(par->family);
 }
 
-#ifdef CONFIG_COMPAT
-struct compat_xt_connmark_target_info {
-	compat_ulong_t	mark, mask;
-	u_int8_t	mode;
-	u_int8_t	__pad1;
-	u_int16_t	__pad2;
-};
-
-static void connmark_tg_compat_from_user_v0(void *dst, void *src)
-{
-	const struct compat_xt_connmark_target_info *cm = src;
-	struct xt_connmark_target_info m = {
-		.mark	= cm->mark,
-		.mask	= cm->mask,
-		.mode	= cm->mode,
-	};
-	memcpy(dst, &m, sizeof(m));
-}
-
-static int connmark_tg_compat_to_user_v0(void __user *dst, void *src)
-{
-	const struct xt_connmark_target_info *m = src;
-	struct compat_xt_connmark_target_info cm = {
-		.mark	= m->mark,
-		.mask	= m->mask,
-		.mode	= m->mode,
-	};
-	return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
-}
-#endif /* CONFIG_COMPAT */
-
-static struct xt_target connmark_tg_reg[] __read_mostly = {
-	{
-		.name		= "CONNMARK",
-		.revision	= 0,
-		.family		= NFPROTO_UNSPEC,
-		.checkentry	= connmark_tg_check_v0,
-		.destroy	= connmark_tg_destroy,
-		.target		= connmark_tg_v0,
-		.targetsize	= sizeof(struct xt_connmark_target_info),
-#ifdef CONFIG_COMPAT
-		.compatsize	= sizeof(struct compat_xt_connmark_target_info),
-		.compat_from_user = connmark_tg_compat_from_user_v0,
-		.compat_to_user	= connmark_tg_compat_to_user_v0,
-#endif
-		.me		= THIS_MODULE
-	},
-	{
-		.name           = "CONNMARK",
-		.revision       = 1,
-		.family         = NFPROTO_UNSPEC,
-		.checkentry     = connmark_tg_check,
-		.target         = connmark_tg,
-		.targetsize     = sizeof(struct xt_connmark_tginfo1),
-		.destroy        = connmark_tg_destroy,
-		.me             = THIS_MODULE,
-	},
+static struct xt_target connmark_tg_reg __read_mostly = {
+	.name           = "CONNMARK",
+	.revision       = 1,
+	.family         = NFPROTO_UNSPEC,
+	.checkentry     = connmark_tg_check,
+	.target         = connmark_tg,
+	.targetsize     = sizeof(struct xt_connmark_tginfo1),
+	.destroy        = connmark_tg_destroy,
+	.me             = THIS_MODULE,
 };
 
 static int __init connmark_tg_init(void)
 {
-	return xt_register_targets(connmark_tg_reg,
-	       ARRAY_SIZE(connmark_tg_reg));
+	return xt_register_target(&connmark_tg_reg);
 }
 
 static void __exit connmark_tg_exit(void)
 {
-	xt_unregister_targets(connmark_tg_reg, ARRAY_SIZE(connmark_tg_reg));
+	xt_unregister_target(&connmark_tg_reg);
 }
 
 module_init(connmark_tg_init);
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 6a347e7..74ce892 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -18,7 +18,6 @@
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_DSCP.h>
-#include <linux/netfilter_ipv4/ipt_TOS.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification");
@@ -73,41 +72,6 @@ static bool dscp_tg_check(const struct xt_tgchk_param *par)
 }
 
 static unsigned int
-tos_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
-{
-	const struct ipt_tos_target_info *info = par->targinfo;
-	struct iphdr *iph = ip_hdr(skb);
-	u_int8_t oldtos;
-
-	if ((iph->tos & IPTOS_TOS_MASK) != info->tos) {
-		if (!skb_make_writable(skb, sizeof(struct iphdr)))
-			return NF_DROP;
-
-		iph      = ip_hdr(skb);
-		oldtos   = iph->tos;
-		iph->tos = (iph->tos & IPTOS_PREC_MASK) | info->tos;
-		csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
-	}
-
-	return XT_CONTINUE;
-}
-
-static bool tos_tg_check_v0(const struct xt_tgchk_param *par)
-{
-	const struct ipt_tos_target_info *info = par->targinfo;
-	const uint8_t tos = info->tos;
-
-	if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT &&
-	    tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST &&
-	    tos != IPTOS_NORMALSVC) {
-		printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
-		return false;
-	}
-
-	return true;
-}
-
-static unsigned int
 tos_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 	const struct xt_tos_target_info *info = par->targinfo;
@@ -168,16 +132,6 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
 	},
 	{
 		.name		= "TOS",
-		.revision	= 0,
-		.family		= NFPROTO_IPV4,
-		.table		= "mangle",
-		.target		= tos_tg_v0,
-		.targetsize	= sizeof(struct ipt_tos_target_info),
-		.checkentry	= tos_tg_check_v0,
-		.me		= THIS_MODULE,
-	},
-	{
-		.name		= "TOS",
 		.revision	= 1,
 		.family		= NFPROTO_IPV4,
 		.table		= "mangle",
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index 67574bc..225f8d1 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -25,39 +25,6 @@ MODULE_ALIAS("ipt_MARK");
 MODULE_ALIAS("ip6t_MARK");
 
 static unsigned int
-mark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
-{
-	const struct xt_mark_target_info *markinfo = par->targinfo;
-
-	skb->mark = markinfo->mark;
-	return XT_CONTINUE;
-}
-
-static unsigned int
-mark_tg_v1(struct sk_buff *skb, const struct xt_target_param *par)
-{
-	const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
-	int mark = 0;
-
-	switch (markinfo->mode) {
-	case XT_MARK_SET:
-		mark = markinfo->mark;
-		break;
-
-	case XT_MARK_AND:
-		mark = skb->mark & markinfo->mark;
-		break;
-
-	case XT_MARK_OR:
-		mark = skb->mark | markinfo->mark;
-		break;
-	}
-
-	skb->mark = mark;
-	return XT_CONTINUE;
-}
-
-static unsigned int
 mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
 	const struct xt_mark_tginfo2 *info = par->targinfo;
@@ -66,135 +33,23 @@ mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
 	return XT_CONTINUE;
 }
 
-static bool mark_tg_check_v0(const struct xt_tgchk_param *par)
-{
-	const struct xt_mark_target_info *markinfo = par->targinfo;
-
-	if (markinfo->mark > 0xffffffff) {
-		printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
-		return false;
-	}
-	return true;
-}
-
-static bool mark_tg_check_v1(const struct xt_tgchk_param *par)
-{
-	const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
-
-	if (markinfo->mode != XT_MARK_SET
-	    && markinfo->mode != XT_MARK_AND
-	    && markinfo->mode != XT_MARK_OR) {
-		printk(KERN_WARNING "MARK: unknown mode %u\n",
-		       markinfo->mode);
-		return false;
-	}
-	if (markinfo->mark > 0xffffffff) {
-		printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
-		return false;
-	}
-	return true;
-}
-
-#ifdef CONFIG_COMPAT
-struct compat_xt_mark_target_info {
-	compat_ulong_t	mark;
-};
-
-static void mark_tg_compat_from_user_v0(void *dst, void *src)
-{
-	const struct compat_xt_mark_target_info *cm = src;
-	struct xt_mark_target_info m = {
-		.mark	= cm->mark,
-	};
-	memcpy(dst, &m, sizeof(m));
-}
-
-static int mark_tg_compat_to_user_v0(void __user *dst, void *src)
-{
-	const struct xt_mark_target_info *m = src;
-	struct compat_xt_mark_target_info cm = {
-		.mark	= m->mark,
-	};
-	return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
-}
-
-struct compat_xt_mark_target_info_v1 {
-	compat_ulong_t	mark;
-	u_int8_t	mode;
-	u_int8_t	__pad1;
-	u_int16_t	__pad2;
-};
-
-static void mark_tg_compat_from_user_v1(void *dst, void *src)
-{
-	const struct compat_xt_mark_target_info_v1 *cm = src;
-	struct xt_mark_target_info_v1 m = {
-		.mark	= cm->mark,
-		.mode	= cm->mode,
-	};
-	memcpy(dst, &m, sizeof(m));
-}
-
-static int mark_tg_compat_to_user_v1(void __user *dst, void *src)
-{
-	const struct xt_mark_target_info_v1 *m = src;
-	struct compat_xt_mark_target_info_v1 cm = {
-		.mark	= m->mark,
-		.mode	= m->mode,
-	};
-	return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
-}
-#endif /* CONFIG_COMPAT */
-
-static struct xt_target mark_tg_reg[] __read_mostly = {
-	{
-		.name		= "MARK",
-		.family		= NFPROTO_UNSPEC,
-		.revision	= 0,
-		.checkentry	= mark_tg_check_v0,
-		.target		= mark_tg_v0,
-		.targetsize	= sizeof(struct xt_mark_target_info),
-#ifdef CONFIG_COMPAT
-		.compatsize	= sizeof(struct compat_xt_mark_target_info),
-		.compat_from_user = mark_tg_compat_from_user_v0,
-		.compat_to_user	= mark_tg_compat_to_user_v0,
-#endif
-		.table		= "mangle",
-		.me		= THIS_MODULE,
-	},
-	{
-		.name		= "MARK",
-		.family		= NFPROTO_UNSPEC,
-		.revision	= 1,
-		.checkentry	= mark_tg_check_v1,
-		.target		= mark_tg_v1,
-		.targetsize	= sizeof(struct xt_mark_target_info_v1),
-#ifdef CONFIG_COMPAT
-		.compatsize	= sizeof(struct compat_xt_mark_target_info_v1),
-		.compat_from_user = mark_tg_compat_from_user_v1,
-		.compat_to_user	= mark_tg_compat_to_user_v1,
-#endif
-		.table		= "mangle",
-		.me		= THIS_MODULE,
-	},
-	{
-		.name           = "MARK",
-		.revision       = 2,
-		.family         = NFPROTO_UNSPEC,
-		.target         = mark_tg,
-		.targetsize     = sizeof(struct xt_mark_tginfo2),
-		.me             = THIS_MODULE,
-	},
+static struct xt_target mark_tg_reg __read_mostly = {
+	.name           = "MARK",
+	.revision       = 2,
+	.family         = NFPROTO_UNSPEC,
+	.target         = mark_tg,
+	.targetsize     = sizeof(struct xt_mark_tginfo2),
+	.me             = THIS_MODULE,
 };
 
 static int __init mark_tg_init(void)
 {
-	return xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
+	return xt_register_target(&mark_tg_reg);
 }
 
 static void __exit mark_tg_exit(void)
 {
-	xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
+	xt_unregister_target(&mark_tg_reg);
 }
 
 module_init(mark_tg_init);
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 86cacab..122aa8b 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -47,36 +47,6 @@ connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static bool
-connmark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-	const struct xt_connmark_info *info = par->matchinfo;
-	const struct nf_conn *ct;
-	enum ip_conntrack_info ctinfo;
-
-	ct = nf_ct_get(skb, &ctinfo);
-	if (!ct)
-		return false;
-
-	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
-}
-
-static bool connmark_mt_check_v0(const struct xt_mtchk_param *par)
-{
-	const struct xt_connmark_info *cm = par->matchinfo;
-
-	if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
-		printk(KERN_WARNING "connmark: only support 32bit mark\n");
-		return false;
-	}
-	if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-		printk(KERN_WARNING "can't load conntrack support for "
-				    "proto=%u\n", par->family);
-		return false;
-	}
-	return true;
-}
-
 static bool connmark_mt_check(const struct xt_mtchk_param *par)
 {
 	if (nf_ct_l3proto_try_module_get(par->family) < 0) {
@@ -92,74 +62,25 @@ static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
 	nf_ct_l3proto_module_put(par->family);
 }
 
-#ifdef CONFIG_COMPAT
-struct compat_xt_connmark_info {
-	compat_ulong_t	mark, mask;
-	u_int8_t	invert;
-	u_int8_t	__pad1;
-	u_int16_t	__pad2;
-};
-
-static void connmark_mt_compat_from_user_v0(void *dst, void *src)
-{
-	const struct compat_xt_connmark_info *cm = src;
-	struct xt_connmark_info m = {
-		.mark	= cm->mark,
-		.mask	= cm->mask,
-		.invert	= cm->invert,
-	};
-	memcpy(dst, &m, sizeof(m));
-}
-
-static int connmark_mt_compat_to_user_v0(void __user *dst, void *src)
-{
-	const struct xt_connmark_info *m = src;
-	struct compat_xt_connmark_info cm = {
-		.mark	= m->mark,
-		.mask	= m->mask,
-		.invert	= m->invert,
-	};
-	return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
-}
-#endif /* CONFIG_COMPAT */
-
-static struct xt_match connmark_mt_reg[] __read_mostly = {
-	{
-		.name		= "connmark",
-		.revision	= 0,
-		.family		= NFPROTO_UNSPEC,
-		.checkentry	= connmark_mt_check_v0,
-		.match		= connmark_mt_v0,
-		.destroy	= connmark_mt_destroy,
-		.matchsize	= sizeof(struct xt_connmark_info),
-#ifdef CONFIG_COMPAT
-		.compatsize	= sizeof(struct compat_xt_connmark_info),
-		.compat_from_user = connmark_mt_compat_from_user_v0,
-		.compat_to_user	= connmark_mt_compat_to_user_v0,
-#endif
-		.me		= THIS_MODULE
-	},
-	{
-		.name           = "connmark",
-		.revision       = 1,
-		.family         = NFPROTO_UNSPEC,
-		.checkentry     = connmark_mt_check,
-		.match          = connmark_mt,
-		.matchsize      = sizeof(struct xt_connmark_mtinfo1),
-		.destroy        = connmark_mt_destroy,
-		.me             = THIS_MODULE,
-	},
+static struct xt_match connmark_mt_reg __read_mostly = {
+	.name           = "connmark",
+	.revision       = 1,
+	.family         = NFPROTO_UNSPEC,
+	.checkentry     = connmark_mt_check,
+	.match          = connmark_mt,
+	.matchsize      = sizeof(struct xt_connmark_mtinfo1),
+	.destroy        = connmark_mt_destroy,
+	.me             = THIS_MODULE,
 };
 
 static int __init connmark_mt_init(void)
 {
-	return xt_register_matches(connmark_mt_reg,
-	       ARRAY_SIZE(connmark_mt_reg));
+	return xt_register_match(&connmark_mt_reg);
 }
 
 static void __exit connmark_mt_exit(void)
 {
-	xt_unregister_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
+	xt_unregister_match(&connmark_mt_reg);
 }
 
 module_init(connmark_mt_init);
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index fc58180..6dc4652 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -19,101 +19,12 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: connection tracking state match");
 MODULE_ALIAS("ipt_conntrack");
 MODULE_ALIAS("ip6t_conntrack");
 
 static bool
-conntrack_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-	const struct xt_conntrack_info *sinfo = par->matchinfo;
-	const struct nf_conn *ct;
-	enum ip_conntrack_info ctinfo;
-	unsigned int statebit;
-
-	ct = nf_ct_get(skb, &ctinfo);
-
-#define FWINV(bool, invflg) ((bool) ^ !!(sinfo->invflags & (invflg)))
-
-	if (ct == &nf_conntrack_untracked)
-		statebit = XT_CONNTRACK_STATE_UNTRACKED;
-	else if (ct)
-		statebit = XT_CONNTRACK_STATE_BIT(ctinfo);
-	else
-		statebit = XT_CONNTRACK_STATE_INVALID;
-
-	if (sinfo->flags & XT_CONNTRACK_STATE) {
-		if (ct) {
-			if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
-				statebit |= XT_CONNTRACK_STATE_SNAT;
-			if (test_bit(IPS_DST_NAT_BIT, &ct->status))
-				statebit |= XT_CONNTRACK_STATE_DNAT;
-		}
-		if (FWINV((statebit & sinfo->statemask) == 0,
-			  XT_CONNTRACK_STATE))
-			return false;
-	}
-
-	if (ct == NULL) {
-		if (sinfo->flags & ~XT_CONNTRACK_STATE)
-			return false;
-		return true;
-	}
-
-	if (sinfo->flags & XT_CONNTRACK_PROTO &&
-	    FWINV(nf_ct_protonum(ct) !=
-		  sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
-		  XT_CONNTRACK_PROTO))
-		return false;
-
-	if (sinfo->flags & XT_CONNTRACK_ORIGSRC &&
-	    FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip &
-		   sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
-		  sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
-		  XT_CONNTRACK_ORIGSRC))
-		return false;
-
-	if (sinfo->flags & XT_CONNTRACK_ORIGDST &&
-	    FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip &
-		   sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
-		  sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
-		  XT_CONNTRACK_ORIGDST))
-		return false;
-
-	if (sinfo->flags & XT_CONNTRACK_REPLSRC &&
-	    FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip &
-		   sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) !=
-		  sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
-		  XT_CONNTRACK_REPLSRC))
-		return false;
-
-	if (sinfo->flags & XT_CONNTRACK_REPLDST &&
-	    FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip &
-		   sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) !=
-		  sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
-		  XT_CONNTRACK_REPLDST))
-		return false;
-
-	if (sinfo->flags & XT_CONNTRACK_STATUS &&
-	    FWINV((ct->status & sinfo->statusmask) == 0,
-		  XT_CONNTRACK_STATUS))
-		return false;
-
-	if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
-		unsigned long expires = timer_pending(&ct->timeout) ?
-					(ct->timeout.expires - jiffies)/HZ : 0;
-
-		if (FWINV(!(expires >= sinfo->expires_min &&
-			    expires <= sinfo->expires_max),
-			  XT_CONNTRACK_EXPIRES))
-			return false;
-	}
-	return true;
-#undef FWINV
-}
-
-static bool
 conntrack_addrcmp(const union nf_inet_addr *kaddr,
                   const union nf_inet_addr *uaddr,
                   const union nf_inet_addr *umask, unsigned int l3proto)
@@ -337,73 +248,9 @@ static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par)
 	conntrack_mt_destroy(par);
 }
 
-#ifdef CONFIG_COMPAT
-struct compat_xt_conntrack_info
-{
-	compat_uint_t			statemask;
-	compat_uint_t			statusmask;
-	struct ip_conntrack_old_tuple	tuple[IP_CT_DIR_MAX];
-	struct in_addr			sipmsk[IP_CT_DIR_MAX];
-	struct in_addr			dipmsk[IP_CT_DIR_MAX];
-	compat_ulong_t			expires_min;
-	compat_ulong_t			expires_max;
-	u_int8_t			flags;
-	u_int8_t			invflags;
-};
-
-static void conntrack_mt_compat_from_user_v0(void *dst, void *src)
-{
-	const struct compat_xt_conntrack_info *cm = src;
-	struct xt_conntrack_info m = {
-		.statemask	= cm->statemask,
-		.statusmask	= cm->statusmask,
-		.expires_min	= cm->expires_min,
-		.expires_max	= cm->expires_max,
-		.flags		= cm->flags,
-		.invflags	= cm->invflags,
-	};
-	memcpy(m.tuple, cm->tuple, sizeof(m.tuple));
-	memcpy(m.sipmsk, cm->sipmsk, sizeof(m.sipmsk));
-	memcpy(m.dipmsk, cm->dipmsk, sizeof(m.dipmsk));
-	memcpy(dst, &m, sizeof(m));
-}
-
-static int conntrack_mt_compat_to_user_v0(void __user *dst, void *src)
-{
-	const struct xt_conntrack_info *m = src;
-	struct compat_xt_conntrack_info cm = {
-		.statemask	= m->statemask,
-		.statusmask	= m->statusmask,
-		.expires_min	= m->expires_min,
-		.expires_max	= m->expires_max,
-		.flags		= m->flags,
-		.invflags	= m->invflags,
-	};
-	memcpy(cm.tuple, m->tuple, sizeof(cm.tuple));
-	memcpy(cm.sipmsk, m->sipmsk, sizeof(cm.sipmsk));
-	memcpy(cm.dipmsk, m->dipmsk, sizeof(cm.dipmsk));
-	return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
-}
-#endif
-
 static struct xt_match conntrack_mt_reg[] __read_mostly = {
 	{
 		.name       = "conntrack",
-		.revision   = 0,
-		.family     = NFPROTO_IPV4,
-		.match      = conntrack_mt_v0,
-		.checkentry = conntrack_mt_check,
-		.destroy    = conntrack_mt_destroy,
-		.matchsize  = sizeof(struct xt_conntrack_info),
-		.me         = THIS_MODULE,
-#ifdef CONFIG_COMPAT
-		.compatsize       = sizeof(struct compat_xt_conntrack_info),
-		.compat_from_user = conntrack_mt_compat_from_user_v0,
-		.compat_to_user   = conntrack_mt_compat_to_user_v0,
-#endif
-	},
-	{
-		.name       = "conntrack",
 		.revision   = 1,
 		.family     = NFPROTO_UNSPEC,
 		.matchsize  = sizeof(struct xt_conntrack_mtinfo1),
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index c3f8085..0280d3a 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -15,7 +15,6 @@
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_dscp.h>
-#include <linux/netfilter_ipv4/ipt_tos.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: DSCP/TOS field match");
@@ -55,14 +54,6 @@ static bool dscp_mt_check(const struct xt_mtchk_param *par)
 	return true;
 }
 
-static bool
-tos_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-	const struct ipt_tos_info *info = par->matchinfo;
-
-	return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
-}
-
 static bool tos_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 	const struct xt_tos_match_info *info = par->matchinfo;
@@ -94,14 +85,6 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
 	},
 	{
 		.name		= "tos",
-		.revision	= 0,
-		.family		= NFPROTO_IPV4,
-		.match		= tos_mt_v0,
-		.matchsize	= sizeof(struct ipt_tos_info),
-		.me		= THIS_MODULE,
-	},
-	{
-		.name		= "tos",
 		.revision	= 1,
 		.family		= NFPROTO_IPV4,
 		.match		= tos_mt,
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index 501f9b6..ffc9638 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -14,40 +14,6 @@
 #include <linux/ipv6.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_iprange.h>
-#include <linux/netfilter_ipv4/ipt_iprange.h>
-
-static bool
-iprange_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-	const struct ipt_iprange_info *info = par->matchinfo;
-	const struct iphdr *iph = ip_hdr(skb);
-
-	if (info->flags & IPRANGE_SRC) {
-		if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
-			  || ntohl(iph->saddr) > ntohl(info->src.max_ip))
-			 ^ !!(info->flags & IPRANGE_SRC_INV)) {
-			pr_debug("src IP %pI4 NOT in range %s%pI4-%pI4\n",
-				 &iph->saddr,
-				 info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
-				 &info->src.min_ip,
-				 &info->src.max_ip);
-			return false;
-		}
-	}
-	if (info->flags & IPRANGE_DST) {
-		if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
-			  || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
-			 ^ !!(info->flags & IPRANGE_DST_INV)) {
-			pr_debug("dst IP %pI4 NOT in range %s%pI4-%pI4\n",
-				 &iph->daddr,
-				 info->flags & IPRANGE_DST_INV ? "(INV) " : "",
-				 &info->dst.min_ip,
-				 &info->dst.max_ip);
-			return false;
-		}
-	}
-	return true;
-}
 
 static bool
 iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
@@ -127,14 +93,6 @@ iprange_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 static struct xt_match iprange_mt_reg[] __read_mostly = {
 	{
 		.name      = "iprange",
-		.revision  = 0,
-		.family    = NFPROTO_IPV4,
-		.match     = iprange_mt_v0,
-		.matchsize = sizeof(struct ipt_iprange_info),
-		.me        = THIS_MODULE,
-	},
-	{
-		.name      = "iprange",
 		.revision  = 1,
 		.family    = NFPROTO_IPV4,
 		.match     = iprange_mt4,
@@ -164,7 +122,8 @@ static void __exit iprange_mt_exit(void)
 module_init(iprange_mt_init);
 module_exit(iprange_mt_exit);
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
 MODULE_ALIAS("ipt_iprange");
 MODULE_ALIAS("ip6t_iprange");
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index 10b9e34..1db07d8 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -3,7 +3,7 @@
  *
  *	(C) 1999-2001 Marc Boucher <marc@mbsi.ca>
  *	Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
- *	Jan Engelhardt <jengelh@computergmbh.de>
+ *	Jan Engelhardt <jengelh@medozas.de>
  *
  *	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
@@ -23,14 +23,6 @@ MODULE_ALIAS("ipt_mark");
 MODULE_ALIAS("ip6t_mark");
 
 static bool
-mark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-	const struct xt_mark_info *info = par->matchinfo;
-
-	return ((skb->mark & info->mask) == info->mark) ^ info->invert;
-}
-
-static bool
 mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
 	const struct xt_mark_mtinfo1 *info = par->matchinfo;
@@ -38,81 +30,23 @@ mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 	return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static bool mark_mt_check_v0(const struct xt_mtchk_param *par)
-{
-	const struct xt_mark_info *minfo = par->matchinfo;
-
-	if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
-		printk(KERN_WARNING "mark: only supports 32bit mark\n");
-		return false;
-	}
-	return true;
-}
-
-#ifdef CONFIG_COMPAT
-struct compat_xt_mark_info {
-	compat_ulong_t	mark, mask;
-	u_int8_t	invert;
-	u_int8_t	__pad1;
-	u_int16_t	__pad2;
-};
-
-static void mark_mt_compat_from_user_v0(void *dst, void *src)
-{
-	const struct compat_xt_mark_info *cm = src;
-	struct xt_mark_info m = {
-		.mark	= cm->mark,
-		.mask	= cm->mask,
-		.invert	= cm->invert,
-	};
-	memcpy(dst, &m, sizeof(m));
-}
-
-static int mark_mt_compat_to_user_v0(void __user *dst, void *src)
-{
-	const struct xt_mark_info *m = src;
-	struct compat_xt_mark_info cm = {
-		.mark	= m->mark,
-		.mask	= m->mask,
-		.invert	= m->invert,
-	};
-	return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
-}
-#endif /* CONFIG_COMPAT */
-
-static struct xt_match mark_mt_reg[] __read_mostly = {
-	{
-		.name		= "mark",
-		.revision	= 0,
-		.family		= NFPROTO_UNSPEC,
-		.checkentry	= mark_mt_check_v0,
-		.match		= mark_mt_v0,
-		.matchsize	= sizeof(struct xt_mark_info),
-#ifdef CONFIG_COMPAT
-		.compatsize	= sizeof(struct compat_xt_mark_info),
-		.compat_from_user = mark_mt_compat_from_user_v0,
-		.compat_to_user	= mark_mt_compat_to_user_v0,
-#endif
-		.me		= THIS_MODULE,
-	},
-	{
-		.name           = "mark",
-		.revision       = 1,
-		.family         = NFPROTO_UNSPEC,
-		.match          = mark_mt,
-		.matchsize      = sizeof(struct xt_mark_mtinfo1),
-		.me             = THIS_MODULE,
-	},
+static struct xt_match mark_mt_reg __read_mostly = {
+	.name           = "mark",
+	.revision       = 1,
+	.family         = NFPROTO_UNSPEC,
+	.match          = mark_mt,
+	.matchsize      = sizeof(struct xt_mark_mtinfo1),
+	.me             = THIS_MODULE,
 };
 
 static int __init mark_mt_init(void)
 {
-	return xt_register_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg));
+	return xt_register_match(&mark_mt_reg);
 }
 
 static void __exit mark_mt_exit(void)
 {
-	xt_unregister_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg));
+	xt_unregister_match(&mark_mt_reg);
 }
 
 module_init(mark_mt_init);
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
index 0f482e2..63e1905 100644
--- a/net/netfilter/xt_osf.c
+++ b/net/netfilter/xt_osf.c
@@ -70,7 +70,8 @@ static void xt_osf_finger_free_rcu(struct rcu_head *rcu_head)
 }
 
 static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb,
-			struct nlmsghdr *nlh, struct nlattr *osf_attrs[])
+			       const struct nlmsghdr *nlh,
+			       const struct nlattr * const osf_attrs[])
 {
 	struct xt_osf_user_finger *f;
 	struct xt_osf_finger *kf = NULL, *sf;
@@ -112,7 +113,8 @@ static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb,
 }
 
 static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
-			struct nlmsghdr *nlh, struct nlattr *osf_attrs[])
+				  const struct nlmsghdr *nlh,
+				  const struct nlattr * const osf_attrs[])
 {
 	struct xt_osf_user_finger *f;
 	struct xt_osf_finger *sf;
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 22b2a5e..d24c76d 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -5,7 +5,6 @@
  * (C) 2000 Marc Boucher <marc@mbsi.ca>
  *
  * Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
- * <jengelh@computergmbh.de>
  *
  * 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
@@ -17,60 +16,6 @@
 #include <net/sock.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_owner.h>
-#include <linux/netfilter_ipv4/ipt_owner.h>
-#include <linux/netfilter_ipv6/ip6t_owner.h>
-
-static bool
-owner_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-	const struct ipt_owner_info *info = par->matchinfo;
-	const struct file *filp;
-
-	if (skb->sk == NULL || skb->sk->sk_socket == NULL)
-		return false;
-
-	filp = skb->sk->sk_socket->file;
-	if (filp == NULL)
-		return false;
-
-	if (info->match & IPT_OWNER_UID)
-		if ((filp->f_cred->fsuid != info->uid) ^
-		    !!(info->invert & IPT_OWNER_UID))
-			return false;
-
-	if (info->match & IPT_OWNER_GID)
-		if ((filp->f_cred->fsgid != info->gid) ^
-		    !!(info->invert & IPT_OWNER_GID))
-			return false;
-
-	return true;
-}
-
-static bool
-owner_mt6_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-	const struct ip6t_owner_info *info = par->matchinfo;
-	const struct file *filp;
-
-	if (skb->sk == NULL || skb->sk->sk_socket == NULL)
-		return false;
-
-	filp = skb->sk->sk_socket->file;
-	if (filp == NULL)
-		return false;
-
-	if (info->match & IP6T_OWNER_UID)
-		if ((filp->f_cred->fsuid != info->uid) ^
-		    !!(info->invert & IP6T_OWNER_UID))
-			return false;
-
-	if (info->match & IP6T_OWNER_GID)
-		if ((filp->f_cred->fsgid != info->gid) ^
-		    !!(info->invert & IP6T_OWNER_GID))
-			return false;
-
-	return true;
-}
 
 static bool
 owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
@@ -107,81 +52,30 @@ owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 	return true;
 }
 
-static bool owner_mt_check_v0(const struct xt_mtchk_param *par)
-{
-	const struct ipt_owner_info *info = par->matchinfo;
-
-	if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) {
-		printk(KERN_WARNING KBUILD_MODNAME
-		       ": PID, SID and command matching is not "
-		       "supported anymore\n");
-		return false;
-	}
-
-	return true;
-}
-
-static bool owner_mt6_check_v0(const struct xt_mtchk_param *par)
-{
-	const struct ip6t_owner_info *info = par->matchinfo;
-
-	if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
-		printk(KERN_WARNING KBUILD_MODNAME
-		       ": PID and SID matching is not supported anymore\n");
-		return false;
-	}
-
-	return true;
-}
-
-static struct xt_match owner_mt_reg[] __read_mostly = {
-	{
-		.name       = "owner",
-		.revision   = 0,
-		.family     = NFPROTO_IPV4,
-		.match      = owner_mt_v0,
-		.matchsize  = sizeof(struct ipt_owner_info),
-		.checkentry = owner_mt_check_v0,
-		.hooks      = (1 << NF_INET_LOCAL_OUT) |
-		              (1 << NF_INET_POST_ROUTING),
-		.me         = THIS_MODULE,
-	},
-	{
-		.name       = "owner",
-		.revision   = 0,
-		.family     = NFPROTO_IPV6,
-		.match      = owner_mt6_v0,
-		.matchsize  = sizeof(struct ip6t_owner_info),
-		.checkentry = owner_mt6_check_v0,
-		.hooks      = (1 << NF_INET_LOCAL_OUT) |
-		              (1 << NF_INET_POST_ROUTING),
-		.me         = THIS_MODULE,
-	},
-	{
-		.name       = "owner",
-		.revision   = 1,
-		.family     = NFPROTO_UNSPEC,
-		.match      = owner_mt,
-		.matchsize  = sizeof(struct xt_owner_match_info),
-		.hooks      = (1 << NF_INET_LOCAL_OUT) |
-		              (1 << NF_INET_POST_ROUTING),
-		.me         = THIS_MODULE,
-	},
+static struct xt_match owner_mt_reg __read_mostly = {
+	.name       = "owner",
+	.revision   = 1,
+	.family     = NFPROTO_UNSPEC,
+	.match      = owner_mt,
+	.matchsize  = sizeof(struct xt_owner_match_info),
+	.hooks      = (1 << NF_INET_LOCAL_OUT) |
+	              (1 << NF_INET_POST_ROUTING),
+	.me         = THIS_MODULE,
 };
 
 static int __init owner_mt_init(void)
 {
-	return xt_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
+	return xt_register_match(&owner_mt_reg);
 }
 
 static void __exit owner_mt_exit(void)
 {
-	xt_unregister_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
+	xt_unregister_match(&owner_mt_reg);
 }
 
 module_init(owner_mt_init);
 module_exit(owner_mt_exit);
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: socket owner matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_owner");
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 16e6c43..6ce0020 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -185,8 +185,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
 	return 0;
 
 cfg_unlbl_map_add_failure:
-	if (entry != NULL)
-		kfree(entry->domain);
+	kfree(entry->domain);
 	kfree(entry);
 	kfree(addrmap);
 	kfree(map4);
@@ -385,8 +384,7 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
 
 cfg_cipsov4_map_add_failure:
 	cipso_v4_doi_putdef(doi_def);
-	if (entry != NULL)
-		kfree(entry->domain);
+	kfree(entry->domain);
 	kfree(entry);
 	kfree(addrmap);
 	kfree(addrinfo);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 2936fa3..c5aab6a 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -83,6 +83,11 @@ struct netlink_sock {
 	struct module		*module;
 };
 
+struct listeners_rcu_head {
+	struct rcu_head rcu_head;
+	void *ptr;
+};
+
 #define NETLINK_KERNEL_SOCKET	0x1
 #define NETLINK_RECV_PKTINFO	0x2
 #define NETLINK_BROADCAST_SEND_ERROR	0x4
@@ -172,9 +177,11 @@ static void netlink_sock_destruct(struct sock *sk)
  * this, _but_ remember, it adds useless work on UP machines.
  */
 
-static void netlink_table_grab(void)
+void netlink_table_grab(void)
 	__acquires(nl_table_lock)
 {
+	might_sleep();
+
 	write_lock_irq(&nl_table_lock);
 
 	if (atomic_read(&nl_table_users)) {
@@ -195,7 +202,7 @@ static void netlink_table_grab(void)
 	}
 }
 
-static void netlink_table_ungrab(void)
+void netlink_table_ungrab(void)
 	__releases(nl_table_lock)
 {
 	write_unlock_irq(&nl_table_lock);
@@ -1356,7 +1363,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
 	struct netlink_sock *nlk = nlk_sk(sk);
 	int noblock = flags&MSG_DONTWAIT;
 	size_t copied;
-	struct sk_buff *skb;
+	struct sk_buff *skb, *frag __maybe_unused = NULL;
 	int err;
 
 	if (flags&MSG_OOB)
@@ -1368,6 +1375,35 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
 	if (skb == NULL)
 		goto out;
 
+#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
+	if (unlikely(skb_shinfo(skb)->frag_list)) {
+		bool need_compat = !!(flags & MSG_CMSG_COMPAT);
+
+		/*
+		 * If this skb has a frag_list, then here that means that
+		 * we will have to use the frag_list skb for compat tasks
+		 * and the regular skb for non-compat tasks.
+		 *
+		 * The skb might (and likely will) be cloned, so we can't
+		 * just reset frag_list and go on with things -- we need to
+		 * keep that. For the compat case that's easy -- simply get
+		 * a reference to the compat skb and free the regular one
+		 * including the frag. For the non-compat case, we need to
+		 * avoid sending the frag to the user -- so assign NULL but
+		 * restore it below before freeing the skb.
+		 */
+		if (need_compat) {
+			struct sk_buff *compskb = skb_shinfo(skb)->frag_list;
+			skb_get(compskb);
+			kfree_skb(skb);
+			skb = compskb;
+		} else {
+			frag = skb_shinfo(skb)->frag_list;
+			skb_shinfo(skb)->frag_list = NULL;
+		}
+	}
+#endif
+
 	msg->msg_namelen = 0;
 
 	copied = skb->len;
@@ -1398,6 +1434,11 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
 	siocb->scm->creds = *NETLINK_CREDS(skb);
 	if (flags & MSG_TRUNC)
 		copied = skb->len;
+
+#ifdef CONFIG_COMPAT_NETLINK_MESSAGES
+	skb_shinfo(skb)->frag_list = frag;
+#endif
+
 	skb_free_datagram(sk, skb);
 
 	if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2)
@@ -1453,7 +1494,8 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
 	if (groups < 32)
 		groups = 32;
 
-	listeners = kzalloc(NLGRPSZ(groups), GFP_KERNEL);
+	listeners = kzalloc(NLGRPSZ(groups) + sizeof(struct listeners_rcu_head),
+			    GFP_KERNEL);
 	if (!listeners)
 		goto out_sock_release;
 
@@ -1501,6 +1543,49 @@ netlink_kernel_release(struct sock *sk)
 EXPORT_SYMBOL(netlink_kernel_release);
 
 
+static void netlink_free_old_listeners(struct rcu_head *rcu_head)
+{
+	struct listeners_rcu_head *lrh;
+
+	lrh = container_of(rcu_head, struct listeners_rcu_head, rcu_head);
+	kfree(lrh->ptr);
+}
+
+int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
+{
+	unsigned long *listeners, *old = NULL;
+	struct listeners_rcu_head *old_rcu_head;
+	struct netlink_table *tbl = &nl_table[sk->sk_protocol];
+
+	if (groups < 32)
+		groups = 32;
+
+	if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) {
+		listeners = kzalloc(NLGRPSZ(groups) +
+				    sizeof(struct listeners_rcu_head),
+				    GFP_ATOMIC);
+		if (!listeners)
+			return -ENOMEM;
+		old = tbl->listeners;
+		memcpy(listeners, old, NLGRPSZ(tbl->groups));
+		rcu_assign_pointer(tbl->listeners, listeners);
+		/*
+		 * Free the old memory after an RCU grace period so we
+		 * don't leak it. We use call_rcu() here in order to be
+		 * able to call this function from atomic contexts. The
+		 * allocation of this memory will have reserved enough
+		 * space for struct listeners_rcu_head at the end.
+		 */
+		old_rcu_head = (void *)(tbl->listeners +
+					NLGRPLONGS(tbl->groups));
+		old_rcu_head->ptr = old;
+		call_rcu(&old_rcu_head->rcu_head, netlink_free_old_listeners);
+	}
+	tbl->groups = groups;
+
+	return 0;
+}
+
 /**
  * netlink_change_ngroups - change number of multicast groups
  *
@@ -1515,33 +1600,14 @@ EXPORT_SYMBOL(netlink_kernel_release);
  */
 int netlink_change_ngroups(struct sock *sk, unsigned int groups)
 {
-	unsigned long *listeners, *old = NULL;
-	struct netlink_table *tbl = &nl_table[sk->sk_protocol];
-	int err = 0;
-
-	if (groups < 32)
-		groups = 32;
+	int err;
 
 	netlink_table_grab();
-	if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) {
-		listeners = kzalloc(NLGRPSZ(groups), GFP_ATOMIC);
-		if (!listeners) {
-			err = -ENOMEM;
-			goto out_ungrab;
-		}
-		old = tbl->listeners;
-		memcpy(listeners, old, NLGRPSZ(tbl->groups));
-		rcu_assign_pointer(tbl->listeners, listeners);
-	}
-	tbl->groups = groups;
-
- out_ungrab:
+	err = __netlink_change_ngroups(sk, groups);
 	netlink_table_ungrab();
-	synchronize_rcu();
-	kfree(old);
+
 	return err;
 }
-EXPORT_SYMBOL(netlink_change_ngroups);
 
 /**
  * netlink_clear_multicast_users - kick off multicast listeners
@@ -1564,7 +1630,6 @@ void netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
 
 	netlink_table_ungrab();
 }
-EXPORT_SYMBOL(netlink_clear_multicast_users);
 
 void netlink_set_nonroot(int protocol, unsigned int flags)
 {
@@ -1647,7 +1712,7 @@ errout:
 }
 
 int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
-		       struct nlmsghdr *nlh,
+		       const struct nlmsghdr *nlh,
 		       int (*dump)(struct sk_buff *skb,
 				   struct netlink_callback *),
 		       int (*done)(struct netlink_callback *))
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index eed4c6a..566941e 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -18,8 +18,6 @@
 #include <net/sock.h>
 #include <net/genetlink.h>
 
-struct sock *genl_sock = NULL;
-
 static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */
 
 static inline void genl_lock(void)
@@ -138,7 +136,7 @@ int genl_register_mc_group(struct genl_family *family,
 {
 	int id;
 	unsigned long *new_groups;
-	int err;
+	int err = 0;
 
 	BUG_ON(grp->name[0] == '\0');
 
@@ -175,10 +173,34 @@ int genl_register_mc_group(struct genl_family *family,
 		mc_groups_longs++;
 	}
 
-	err = netlink_change_ngroups(genl_sock,
-				     mc_groups_longs * BITS_PER_LONG);
-	if (err)
-		goto out;
+	if (family->netnsok) {
+		struct net *net;
+
+		netlink_table_grab();
+		rcu_read_lock();
+		for_each_net_rcu(net) {
+			err = __netlink_change_ngroups(net->genl_sock,
+					mc_groups_longs * BITS_PER_LONG);
+			if (err) {
+				/*
+				 * No need to roll back, can only fail if
+				 * memory allocation fails and then the
+				 * number of _possible_ groups has been
+				 * increased on some sockets which is ok.
+				 */
+				rcu_read_unlock();
+				netlink_table_ungrab();
+				goto out;
+			}
+		}
+		rcu_read_unlock();
+		netlink_table_ungrab();
+	} else {
+		err = netlink_change_ngroups(init_net.genl_sock,
+					     mc_groups_longs * BITS_PER_LONG);
+		if (err)
+			goto out;
+	}
 
 	grp->id = id;
 	set_bit(id, mc_groups);
@@ -195,8 +217,14 @@ EXPORT_SYMBOL(genl_register_mc_group);
 static void __genl_unregister_mc_group(struct genl_family *family,
 				       struct genl_multicast_group *grp)
 {
+	struct net *net;
 	BUG_ON(grp->family != family);
-	netlink_clear_multicast_users(genl_sock, grp->id);
+
+	rcu_read_lock();
+	for_each_net_rcu(net)
+		netlink_clear_multicast_users(net->genl_sock, grp->id);
+	rcu_read_unlock();
+
 	clear_bit(grp->id, mc_groups);
 	list_del(&grp->list);
 	genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, grp);
@@ -467,6 +495,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
 	struct genl_ops *ops;
 	struct genl_family *family;
+	struct net *net = sock_net(skb->sk);
 	struct genl_info info;
 	struct genlmsghdr *hdr = nlmsg_data(nlh);
 	int hdrlen, err;
@@ -475,6 +504,10 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 	if (family == NULL)
 		return -ENOENT;
 
+	/* this family doesn't exist in this netns */
+	if (!family->netnsok && !net_eq(net, &init_net))
+		return -ENOENT;
+
 	hdrlen = GENL_HDRLEN + family->hdrsize;
 	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
 		return -EINVAL;
@@ -492,7 +525,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 			return -EOPNOTSUPP;
 
 		genl_unlock();
-		err = netlink_dump_start(genl_sock, skb, nlh,
+		err = netlink_dump_start(net->genl_sock, skb, nlh,
 					 ops->dumpit, ops->done);
 		genl_lock();
 		return err;
@@ -514,6 +547,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 	info.genlhdr = nlmsg_data(nlh);
 	info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
 	info.attrs = family->attrbuf;
+	genl_info_net_set(&info, net);
 
 	return ops->doit(skb, &info);
 }
@@ -534,6 +568,7 @@ static struct genl_family genl_ctrl = {
 	.name = "nlctrl",
 	.version = 0x2,
 	.maxattr = CTRL_ATTR_MAX,
+	.netnsok = true,
 };
 
 static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
@@ -650,6 +685,7 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
 
 	int i, n = 0;
 	struct genl_family *rt;
+	struct net *net = sock_net(skb->sk);
 	int chains_to_skip = cb->args[0];
 	int fams_to_skip = cb->args[1];
 
@@ -658,6 +694,8 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
 			continue;
 		n = 0;
 		list_for_each_entry(rt, genl_family_chain(i), family_list) {
+			if (!rt->netnsok && !net_eq(net, &init_net))
+				continue;
 			if (++n < fams_to_skip)
 				continue;
 			if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid,
@@ -729,6 +767,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
 	if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
 		u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
 		res = genl_family_find_byid(id);
+		err = -ENOENT;
 	}
 
 	if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
@@ -736,49 +775,61 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
 
 		name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]);
 		res = genl_family_find_byname(name);
+		err = -ENOENT;
 	}
 
-	if (res == NULL) {
-		err = -ENOENT;
-		goto errout;
+	if (res == NULL)
+		return err;
+
+	if (!res->netnsok && !net_eq(genl_info_net(info), &init_net)) {
+		/* family doesn't exist here */
+		return -ENOENT;
 	}
 
 	msg = ctrl_build_family_msg(res, info->snd_pid, info->snd_seq,
 				    CTRL_CMD_NEWFAMILY);
-	if (IS_ERR(msg)) {
-		err = PTR_ERR(msg);
-		goto errout;
-	}
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	err = genlmsg_reply(msg, info);
-errout:
-	return err;
+	return genlmsg_reply(msg, info);
 }
 
 static int genl_ctrl_event(int event, void *data)
 {
 	struct sk_buff *msg;
+	struct genl_family *family;
+	struct genl_multicast_group *grp;
 
-	if (genl_sock == NULL)
+	/* genl is still initialising */
+	if (!init_net.genl_sock)
 		return 0;
 
 	switch (event) {
 	case CTRL_CMD_NEWFAMILY:
 	case CTRL_CMD_DELFAMILY:
-		msg = ctrl_build_family_msg(data, 0, 0, event);
-		if (IS_ERR(msg))
-			return PTR_ERR(msg);
-
-		genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
+		family = data;
+		msg = ctrl_build_family_msg(family, 0, 0, event);
 		break;
 	case CTRL_CMD_NEWMCAST_GRP:
 	case CTRL_CMD_DELMCAST_GRP:
+		grp = data;
+		family = grp->family;
 		msg = ctrl_build_mcgrp_msg(data, 0, 0, event);
-		if (IS_ERR(msg))
-			return PTR_ERR(msg);
-
-		genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
 		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
+
+	if (!family->netnsok) {
+		genlmsg_multicast_netns(&init_net, msg, 0,
+					GENL_ID_CTRL, GFP_KERNEL);
+	} else {
+		rcu_read_lock();
+		genlmsg_multicast_allns(msg, 0, GENL_ID_CTRL, GFP_ATOMIC);
+		rcu_read_unlock();
 	}
 
 	return 0;
@@ -795,6 +846,33 @@ static struct genl_multicast_group notify_grp = {
 	.name		= "notify",
 };
 
+static int __net_init genl_pernet_init(struct net *net)
+{
+	/* we'll bump the group number right afterwards */
+	net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, 0,
+					       genl_rcv, &genl_mutex,
+					       THIS_MODULE);
+
+	if (!net->genl_sock && net_eq(net, &init_net))
+		panic("GENL: Cannot initialize generic netlink\n");
+
+	if (!net->genl_sock)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void __net_exit genl_pernet_exit(struct net *net)
+{
+	netlink_kernel_release(net->genl_sock);
+	net->genl_sock = NULL;
+}
+
+static struct pernet_operations genl_pernet_ops = {
+	.init = genl_pernet_init,
+	.exit = genl_pernet_exit,
+};
+
 static int __init genl_init(void)
 {
 	int i, err;
@@ -804,36 +882,67 @@ static int __init genl_init(void)
 
 	err = genl_register_family(&genl_ctrl);
 	if (err < 0)
-		goto errout;
+		goto problem;
 
 	err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops);
 	if (err < 0)
-		goto errout_register;
+		goto problem;
 
 	netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
 
-	/* we'll bump the group number right afterwards */
-	genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0,
-					  genl_rcv, &genl_mutex, THIS_MODULE);
-	if (genl_sock == NULL)
-		panic("GENL: Cannot initialize generic netlink\n");
+	err = register_pernet_subsys(&genl_pernet_ops);
+	if (err)
+		goto problem;
 
 	err = genl_register_mc_group(&genl_ctrl, &notify_grp);
 	if (err < 0)
-		goto errout_register;
+		goto problem;
 
 	return 0;
 
-errout_register:
-	genl_unregister_family(&genl_ctrl);
-errout:
+problem:
 	panic("GENL: Cannot register controller: %d\n", err);
 }
 
 subsys_initcall(genl_init);
 
-EXPORT_SYMBOL(genl_sock);
 EXPORT_SYMBOL(genl_register_ops);
 EXPORT_SYMBOL(genl_unregister_ops);
 EXPORT_SYMBOL(genl_register_family);
 EXPORT_SYMBOL(genl_unregister_family);
+
+static int genlmsg_mcast(struct sk_buff *skb, u32 pid, unsigned long group,
+			 gfp_t flags)
+{
+	struct sk_buff *tmp;
+	struct net *net, *prev = NULL;
+	int err;
+
+	for_each_net_rcu(net) {
+		if (prev) {
+			tmp = skb_clone(skb, flags);
+			if (!tmp) {
+				err = -ENOMEM;
+				goto error;
+			}
+			err = nlmsg_multicast(prev->genl_sock, tmp,
+					      pid, group, flags);
+			if (err)
+				goto error;
+		}
+
+		prev = net;
+	}
+
+	return nlmsg_multicast(prev->genl_sock, skb, pid, group, flags);
+ error:
+	kfree_skb(skb);
+	return err;
+}
+
+int genlmsg_multicast_allns(struct sk_buff *skb, u32 pid, unsigned int group,
+			    gfp_t flags)
+{
+	return genlmsg_mcast(skb, pid, group, flags);
+}
+EXPORT_SYMBOL(genlmsg_multicast_allns);
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 3513724..7aa11b0 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -169,7 +169,7 @@ static int nr_close(struct net_device *dev)
 	return 0;
 }
 
-static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nr_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_device_stats *stats = &dev->stats;
 	unsigned int len = skb->len;
@@ -177,13 +177,13 @@ static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
 	if (!nr_route_frame(skb, NULL)) {
 		kfree_skb(skb);
 		stats->tx_errors++;
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	stats->tx_packets++;
 	stats->tx_bytes += len;
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static const struct header_ops nr_header_ops = {
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index ebe5718..d3d52c6 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -137,8 +137,7 @@ dev->hard_header == NULL (ll header is added by device, we cannot control it)
 
 /* Private packet socket structures. */
 
-struct packet_mclist
-{
+struct packet_mclist {
 	struct packet_mclist	*next;
 	int			ifindex;
 	int			count;
@@ -149,8 +148,7 @@ struct packet_mclist
 /* identical to struct packet_mreq except it has
  * a longer address field.
  */
-struct packet_mreq_max
-{
+struct packet_mreq_max {
 	int		mr_ifindex;
 	unsigned short	mr_type;
 	unsigned short	mr_alen;
@@ -162,7 +160,7 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
 		int closing, int tx_ring);
 
 struct packet_ring_buffer {
-	char *			*pg_vec;
+	char			**pg_vec;
 	unsigned int		head;
 	unsigned int		frames_per_block;
 	unsigned int		frame_size;
@@ -239,7 +237,7 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status)
 		flush_dcache_page(virt_to_page(&h.h2->tp_status));
 		break;
 	default:
-		printk(KERN_ERR "TPACKET version not supported\n");
+		pr_err("TPACKET version not supported\n");
 		BUG();
 	}
 
@@ -265,7 +263,7 @@ static int __packet_get_status(struct packet_sock *po, void *frame)
 		flush_dcache_page(virt_to_page(&h.h2->tp_status));
 		return h.h2->tp_status;
 	default:
-		printk(KERN_ERR "TPACKET version not supported\n");
+		pr_err("TPACKET version not supported\n");
 		BUG();
 		return 0;
 	}
@@ -327,7 +325,7 @@ static void packet_sock_destruct(struct sock *sk)
 	WARN_ON(atomic_read(&sk->sk_wmem_alloc));
 
 	if (!sock_flag(sk, SOCK_DEAD)) {
-		printk("Attempt to release alive packet socket: %p\n", sk);
+		pr_err("Attempt to release alive packet socket: %p\n", sk);
 		return;
 	}
 
@@ -339,7 +337,8 @@ static const struct proto_ops packet_ops;
 
 static const struct proto_ops packet_ops_spkt;
 
-static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt, struct net_device *orig_dev)
+static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,
+			   struct packet_type *pt, struct net_device *orig_dev)
 {
 	struct sock *sk;
 	struct sockaddr_pkt *spkt;
@@ -368,7 +367,8 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
 	if (dev_net(dev) != sock_net(sk))
 		goto out;
 
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (skb == NULL)
 		goto oom;
 
 	/* drop any routing info */
@@ -394,7 +394,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
 	 *	to prevent sockets using all the memory up.
 	 */
 
-	if (sock_queue_rcv_skb(sk,skb) == 0)
+	if (sock_queue_rcv_skb(sk, skb) == 0)
 		return 0;
 
 out:
@@ -413,25 +413,23 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
 			       struct msghdr *msg, size_t len)
 {
 	struct sock *sk = sock->sk;
-	struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name;
+	struct sockaddr_pkt *saddr = (struct sockaddr_pkt *)msg->msg_name;
 	struct sk_buff *skb;
 	struct net_device *dev;
-	__be16 proto=0;
+	__be16 proto = 0;
 	int err;
 
 	/*
 	 *	Get and verify the address.
 	 */
 
-	if (saddr)
-	{
+	if (saddr) {
 		if (msg->msg_namelen < sizeof(struct sockaddr))
-			return(-EINVAL);
-		if (msg->msg_namelen==sizeof(struct sockaddr_pkt))
-			proto=saddr->spkt_protocol;
-	}
-	else
-		return(-ENOTCONN);	/* SOCK_PACKET must be sent giving an address */
+			return -EINVAL;
+		if (msg->msg_namelen == sizeof(struct sockaddr_pkt))
+			proto = saddr->spkt_protocol;
+	} else
+		return -ENOTCONN;	/* SOCK_PACKET must be sent giving an address */
 
 	/*
 	 *	Find the device first to size check it
@@ -448,8 +446,8 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
 		goto out_unlock;
 
 	/*
-	 *	You may not queue a frame bigger than the mtu. This is the lowest level
-	 *	raw protocol and you must do your own fragmentation at this level.
+	 * You may not queue a frame bigger than the mtu. This is the lowest level
+	 * raw protocol and you must do your own fragmentation at this level.
 	 */
 
 	err = -EMSGSIZE;
@@ -460,9 +458,9 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
 	skb = sock_wmalloc(sk, len + LL_RESERVED_SPACE(dev), 0, GFP_KERNEL);
 
 	/*
-	 *	If the write buffer is full, then tough. At this level the user gets to
-	 *	deal with the problem - do your own algorithmic backoffs. That's far
-	 *	more flexible.
+	 * If the write buffer is full, then tough. At this level the user
+	 * gets to deal with the problem - do your own algorithmic backoffs.
+	 * That's far more flexible.
 	 */
 
 	if (skb == NULL)
@@ -488,7 +486,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
 	}
 
 	/* Returns -EFAULT on error */
-	err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
+	err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
 	skb->protocol = proto;
 	skb->dev = dev;
 	skb->priority = sk->sk_priority;
@@ -501,7 +499,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
 
 	dev_queue_xmit(skb);
 	dev_put(dev);
-	return(len);
+	return len;
 
 out_free:
 	kfree_skb(skb);
@@ -537,12 +535,13 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
    we will not harm anyone.
  */
 
-static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+static int packet_rcv(struct sk_buff *skb, struct net_device *dev,
+		      struct packet_type *pt, struct net_device *orig_dev)
 {
 	struct sock *sk;
 	struct sockaddr_ll *sll;
 	struct packet_sock *po;
-	u8 * skb_head = skb->data;
+	u8 *skb_head = skb->data;
 	int skb_len = skb->len;
 	unsigned int snaplen, res;
 
@@ -648,7 +647,8 @@ drop:
 }
 
 #ifdef CONFIG_PACKET_MMAP
-static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
+		       struct packet_type *pt, struct net_device *orig_dev)
 {
 	struct sock *sk;
 	struct packet_sock *po;
@@ -658,7 +658,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
 		struct tpacket2_hdr *h2;
 		void *raw;
 	} h;
-	u8 * skb_head = skb->data;
+	u8 *skb_head = skb->data;
 	int skb_len = skb->len;
 	unsigned int snaplen, res;
 	unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
@@ -821,7 +821,7 @@ ring_is_full:
 static void tpacket_destruct_skb(struct sk_buff *skb)
 {
 	struct packet_sock *po = pkt_sk(skb->sk);
-	void * ph;
+	void *ph;
 
 	BUG_ON(skb == NULL);
 
@@ -836,9 +836,9 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
 	sock_wfree(skb);
 }
 
-static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff * skb,
-		void * frame, struct net_device *dev, int size_max,
-		__be16 proto, unsigned char * addr)
+static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
+		void *frame, struct net_device *dev, int size_max,
+		__be16 proto, unsigned char *addr)
 {
 	union {
 		struct tpacket_hdr *h1;
@@ -867,8 +867,7 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff * skb,
 		break;
 	}
 	if (unlikely(tp_len > size_max)) {
-		printk(KERN_ERR "packet size is too long (%d > %d)\n",
-				tp_len, size_max);
+		pr_err("packet size is too long (%d > %d)\n", tp_len, size_max);
 		return -EMSGSIZE;
 	}
 
@@ -883,12 +882,11 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff * skb,
 				NULL, tp_len);
 		if (unlikely(err < 0))
 			return -EINVAL;
-	} else if (dev->hard_header_len ) {
+	} else if (dev->hard_header_len) {
 		/* net device doesn't like empty head */
 		if (unlikely(tp_len <= dev->hard_header_len)) {
-			printk(KERN_ERR "packet size is too short "
-					"(%d < %d)\n", tp_len,
-					dev->hard_header_len);
+			pr_err("packet size is too short (%d < %d)\n",
+			       tp_len, dev->hard_header_len);
 			return -EINVAL;
 		}
 
@@ -917,9 +915,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff * skb,
 		nr_frags = skb_shinfo(skb)->nr_frags;
 
 		if (unlikely(nr_frags >= MAX_SKB_FRAGS)) {
-			printk(KERN_ERR "Packet exceed the number "
-					"of skb frags(%lu)\n",
-					MAX_SKB_FRAGS);
+			pr_err("Packet exceed the number of skb frags(%lu)\n",
+			       MAX_SKB_FRAGS);
 			return -EFAULT;
 		}
 
@@ -944,8 +941,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 	struct net_device *dev;
 	__be16 proto;
 	int ifindex, err, reserve = 0;
-	void * ph;
-	struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name;
+	void *ph;
+	struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
 	int tp_len, size_max;
 	unsigned char *addr;
 	int len_sum = 0;
@@ -1038,8 +1035,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 			goto out_xmit;
 		packet_increment_head(&po->tx_ring);
 		len_sum += tp_len;
-	}
-	while (likely((ph != NULL) || ((!(msg->msg_flags & MSG_DONTWAIT))
+	} while (likely((ph != NULL) || ((!(msg->msg_flags & MSG_DONTWAIT))
 					&& (atomic_read(&po->tx_ring.pending))))
 	      );
 
@@ -1064,7 +1060,7 @@ static int packet_snd(struct socket *sock,
 			  struct msghdr *msg, size_t len)
 {
 	struct sock *sk = sock->sk;
-	struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name;
+	struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
 	struct sk_buff *skb;
 	struct net_device *dev;
 	__be16 proto;
@@ -1110,7 +1106,7 @@ static int packet_snd(struct socket *sock,
 
 	skb = sock_alloc_send_skb(sk, len + LL_ALLOCATED_SPACE(dev),
 				msg->msg_flags & MSG_DONTWAIT, &err);
-	if (skb==NULL)
+	if (skb == NULL)
 		goto out_unlock;
 
 	skb_reserve(skb, LL_RESERVED_SPACE(dev));
@@ -1122,7 +1118,7 @@ static int packet_snd(struct socket *sock,
 		goto out_free;
 
 	/* Returns -EFAULT on error */
-	err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
+	err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
 	if (err)
 		goto out_free;
 
@@ -1140,7 +1136,7 @@ static int packet_snd(struct socket *sock,
 
 	dev_put(dev);
 
-	return(len);
+	return len;
 
 out_free:
 	kfree_skb(skb);
@@ -1283,9 +1279,10 @@ out_unlock:
  *	Bind a packet socket to a device
  */
 
-static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
+			    int addr_len)
 {
-	struct sock *sk=sock->sk;
+	struct sock *sk = sock->sk;
 	char name[15];
 	struct net_device *dev;
 	int err = -ENODEV;
@@ -1296,7 +1293,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add
 
 	if (addr_len != sizeof(struct sockaddr))
 		return -EINVAL;
-	strlcpy(name,uaddr->sa_data,sizeof(name));
+	strlcpy(name, uaddr->sa_data, sizeof(name));
 
 	dev = dev_get_by_name(sock_net(sk), name);
 	if (dev) {
@@ -1308,8 +1305,8 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add
 
 static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
-	struct sockaddr_ll *sll = (struct sockaddr_ll*)uaddr;
-	struct sock *sk=sock->sk;
+	struct sockaddr_ll *sll = (struct sockaddr_ll *)uaddr;
+	struct sock *sk = sock->sk;
 	struct net_device *dev = NULL;
 	int err;
 
@@ -1404,7 +1401,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
 	sk_add_node(sk, &net->packet.sklist);
 	sock_prot_inuse_add(net, &packet_proto, 1);
 	write_unlock_bh(&net->packet.sklist_lock);
-	return(0);
+	return 0;
 out:
 	return err;
 }
@@ -1441,7 +1438,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 	 *	but then it will block.
 	 */
 
-	skb=skb_recv_datagram(sk,flags,flags&MSG_DONTWAIT,&err);
+	skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
 
 	/*
 	 *	An error occurred so return it. Because skb_recv_datagram()
@@ -1469,10 +1466,9 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 	 */
 
 	copied = skb->len;
-	if (copied > len)
-	{
-		copied=len;
-		msg->msg_flags|=MSG_TRUNC;
+	if (copied > len) {
+		copied = len;
+		msg->msg_flags |= MSG_TRUNC;
 	}
 
 	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
@@ -1539,7 +1535,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
 	struct net_device *dev;
 	struct sock *sk = sock->sk;
 	struct packet_sock *po = pkt_sk(sk);
-	struct sockaddr_ll *sll = (struct sockaddr_ll*)uaddr;
+	struct sockaddr_ll *sll = (struct sockaddr_ll *)uaddr;
 
 	if (peer)
 		return -EOPNOTSUPP;
@@ -1584,14 +1580,15 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
 		else
 			return dev_unicast_delete(dev, i->addr);
 		break;
-	default:;
+	default:
+		break;
 	}
 	return 0;
 }
 
 static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what)
 {
-	for ( ; i; i=i->next) {
+	for ( ; i; i = i->next) {
 		if (i->ifindex == dev->ifindex)
 			packet_dev_mc(dev, i, what);
 	}
@@ -1693,7 +1690,8 @@ static void packet_flush_mclist(struct sock *sk)
 		struct net_device *dev;
 
 		po->mclist = ml->next;
-		if ((dev = dev_get_by_index(sock_net(sk), ml->ifindex)) != NULL) {
+		dev = dev_get_by_index(sock_net(sk), ml->ifindex);
+		if (dev != NULL) {
 			packet_dev_mc(dev, ml, -1);
 			dev_put(dev);
 		}
@@ -1723,7 +1721,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 			return -EINVAL;
 		if (len > sizeof(mreq))
 			len = sizeof(mreq);
-		if (copy_from_user(&mreq,optval,len))
+		if (copy_from_user(&mreq, optval, len))
 			return -EFAULT;
 		if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))
 			return -EINVAL;
@@ -1740,9 +1738,9 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 	{
 		struct tpacket_req req;
 
-		if (optlen<sizeof(req))
+		if (optlen < sizeof(req))
 			return -EINVAL;
-		if (copy_from_user(&req,optval,sizeof(req)))
+		if (copy_from_user(&req, optval, sizeof(req)))
 			return -EFAULT;
 		return packet_set_ring(sk, &req, 0, optname == PACKET_TX_RING);
 	}
@@ -1750,9 +1748,9 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 	{
 		int val;
 
-		if (optlen!=sizeof(val))
+		if (optlen != sizeof(val))
 			return -EINVAL;
-		if (copy_from_user(&val,optval,sizeof(val)))
+		if (copy_from_user(&val, optval, sizeof(val)))
 			return -EFAULT;
 
 		pkt_sk(sk)->copy_thresh = val;
@@ -1985,51 +1983,51 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
 	struct sock *sk = sock->sk;
 
 	switch (cmd) {
-		case SIOCOUTQ:
-		{
-			int amount = sk_wmem_alloc_get(sk);
+	case SIOCOUTQ:
+	{
+		int amount = sk_wmem_alloc_get(sk);
 
-			return put_user(amount, (int __user *)arg);
-		}
-		case SIOCINQ:
-		{
-			struct sk_buff *skb;
-			int amount = 0;
-
-			spin_lock_bh(&sk->sk_receive_queue.lock);
-			skb = skb_peek(&sk->sk_receive_queue);
-			if (skb)
-				amount = skb->len;
-			spin_unlock_bh(&sk->sk_receive_queue.lock);
-			return put_user(amount, (int __user *)arg);
-		}
-		case SIOCGSTAMP:
-			return sock_get_timestamp(sk, (struct timeval __user *)arg);
-		case SIOCGSTAMPNS:
-			return sock_get_timestampns(sk, (struct timespec __user *)arg);
+		return put_user(amount, (int __user *)arg);
+	}
+	case SIOCINQ:
+	{
+		struct sk_buff *skb;
+		int amount = 0;
+
+		spin_lock_bh(&sk->sk_receive_queue.lock);
+		skb = skb_peek(&sk->sk_receive_queue);
+		if (skb)
+			amount = skb->len;
+		spin_unlock_bh(&sk->sk_receive_queue.lock);
+		return put_user(amount, (int __user *)arg);
+	}
+	case SIOCGSTAMP:
+		return sock_get_timestamp(sk, (struct timeval __user *)arg);
+	case SIOCGSTAMPNS:
+		return sock_get_timestampns(sk, (struct timespec __user *)arg);
 
 #ifdef CONFIG_INET
-		case SIOCADDRT:
-		case SIOCDELRT:
-		case SIOCDARP:
-		case SIOCGARP:
-		case SIOCSARP:
-		case SIOCGIFADDR:
-		case SIOCSIFADDR:
-		case SIOCGIFBRDADDR:
-		case SIOCSIFBRDADDR:
-		case SIOCGIFNETMASK:
-		case SIOCSIFNETMASK:
-		case SIOCGIFDSTADDR:
-		case SIOCSIFDSTADDR:
-		case SIOCSIFFLAGS:
-			if (!net_eq(sock_net(sk), &init_net))
-				return -ENOIOCTLCMD;
-			return inet_dgram_ops.ioctl(sock, cmd, arg);
+	case SIOCADDRT:
+	case SIOCDELRT:
+	case SIOCDARP:
+	case SIOCGARP:
+	case SIOCSARP:
+	case SIOCGIFADDR:
+	case SIOCSIFADDR:
+	case SIOCGIFBRDADDR:
+	case SIOCSIFBRDADDR:
+	case SIOCGIFNETMASK:
+	case SIOCSIFNETMASK:
+	case SIOCGIFDSTADDR:
+	case SIOCSIFDSTADDR:
+	case SIOCSIFFLAGS:
+		if (!net_eq(sock_net(sk), &init_net))
+			return -ENOIOCTLCMD;
+		return inet_dgram_ops.ioctl(sock, cmd, arg);
 #endif
 
-		default:
-			return -ENOIOCTLCMD;
+	default:
+		return -ENOIOCTLCMD;
 	}
 	return 0;
 }
@@ -2039,7 +2037,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
 #define packet_poll datagram_poll
 #else
 
-static unsigned int packet_poll(struct file * file, struct socket *sock,
+static unsigned int packet_poll(struct file *file, struct socket *sock,
 				poll_table *wait)
 {
 	struct sock *sk = sock->sk;
@@ -2069,7 +2067,7 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
 static void packet_mm_open(struct vm_area_struct *vma)
 {
 	struct file *file = vma->vm_file;
-	struct socket * sock = file->private_data;
+	struct socket *sock = file->private_data;
 	struct sock *sk = sock->sk;
 
 	if (sk)
@@ -2079,7 +2077,7 @@ static void packet_mm_open(struct vm_area_struct *vma)
 static void packet_mm_close(struct vm_area_struct *vma)
 {
 	struct file *file = vma->vm_file;
-	struct socket * sock = file->private_data;
+	struct socket *sock = file->private_data;
 	struct sock *sk = sock->sk;
 
 	if (sk)
@@ -2087,8 +2085,8 @@ static void packet_mm_close(struct vm_area_struct *vma)
 }
 
 static struct vm_operations_struct packet_mmap_ops = {
-	.open =	packet_mm_open,
-	.close =packet_mm_close,
+	.open	=	packet_mm_open,
+	.close	=	packet_mm_close,
 };
 
 static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
@@ -2239,8 +2237,8 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
 		skb_queue_purge(rb_queue);
 #undef XC
 		if (atomic_read(&po->mapped))
-			printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n",
-						atomic_read(&po->mapped));
+			pr_err("packet_mmap: vma is busy: %d\n",
+			       atomic_read(&po->mapped));
 	}
 	mutex_unlock(&po->pg_vec_lock);
 
@@ -2303,7 +2301,7 @@ static int packet_mmap(struct file *file, struct socket *sock,
 			int pg_num;
 
 			for (pg_num = 0; pg_num < rb->pg_vec_pages;
-					pg_num++,page++) {
+					pg_num++, page++) {
 				err = vm_insert_page(vma, start, page);
 				if (unlikely(err))
 					goto out;
@@ -2372,7 +2370,7 @@ static struct net_proto_family packet_family_ops = {
 };
 
 static struct notifier_block packet_netdev_notifier = {
-	.notifier_call =packet_notifier,
+	.notifier_call =	packet_notifier,
 };
 
 #ifdef CONFIG_PROC_FS
@@ -2402,7 +2400,7 @@ static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 	++*pos;
 	return  (v == SEQ_START_TOKEN)
 		? sk_head(&net->packet.sklist)
-		: sk_next((struct sock*)v) ;
+		: sk_next((struct sock *)v) ;
 }
 
 static void packet_seq_stop(struct seq_file *seq, void *v)
@@ -2430,7 +2428,7 @@ static int packet_seq_show(struct seq_file *seq, void *v)
 			   po->running,
 			   atomic_read(&s->sk_rmem_alloc),
 			   sock_i_uid(s),
-			   sock_i_ino(s) );
+			   sock_i_ino(s));
 	}
 
 	return 0;
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
index e087862..ef5c75c 100644
--- a/net/phonet/datagram.c
+++ b/net/phonet/datagram.c
@@ -159,8 +159,11 @@ out_nofree:
 static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 {
 	int err = sock_queue_rcv_skb(sk, skb);
-	if (err < 0)
+	if (err < 0) {
 		kfree_skb(skb);
+		if (err == -ENOMEM)
+			atomic_inc(&sk->sk_drops);
+	}
 	return err ? NET_RX_DROP : NET_RX_SUCCESS;
 }
 
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c
index 480839d..d183509 100644
--- a/net/phonet/pep-gprs.c
+++ b/net/phonet/pep-gprs.c
@@ -183,7 +183,7 @@ static int gprs_close(struct net_device *dev)
 	return 0;
 }
 
-static int gprs_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t gprs_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct gprs_dev *gp = netdev_priv(dev);
 	struct sock *sk = gp->sk;
@@ -195,7 +195,7 @@ static int gprs_xmit(struct sk_buff *skb, struct net_device *dev)
 		break;
 	default:
 		dev_kfree_skb(skb);
-		return 0;
+		return NETDEV_TX_OK;
 	}
 
 	skb_orphan(skb);
@@ -215,7 +215,7 @@ static int gprs_xmit(struct sk_buff *skb, struct net_device *dev)
 	netif_stop_queue(dev);
 	if (pep_writeable(sk))
 		netif_wake_queue(dev);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int gprs_set_mtu(struct net_device *dev, int new_mtu)
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index eef833e..b8252d2 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -346,8 +346,10 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
 		break;
 
 	case PNS_PEP_CTRL_REQ:
-		if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX)
+		if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX) {
+			atomic_inc(&sk->sk_drops);
 			break;
+		}
 		__skb_pull(skb, 4);
 		queue = &pn->ctrlreq_queue;
 		goto queue;
@@ -358,10 +360,13 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
 			err = sock_queue_rcv_skb(sk, skb);
 			if (!err)
 				return 0;
+			if (err == -ENOMEM)
+				atomic_inc(&sk->sk_drops);
 			break;
 		}
 
 		if (pn->rx_credits == 0) {
+			atomic_inc(&sk->sk_drops);
 			err = -ENOBUFS;
 			break;
 		}
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index c2b77a6..5f42f30 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -27,6 +27,8 @@
 #include <linux/net.h>
 #include <linux/netdevice.h>
 #include <linux/phonet.h>
+#include <linux/proc_fs.h>
+#include <linux/if_arp.h>
 #include <net/sock.h>
 #include <net/netns/generic.h>
 #include <net/phonet/pn_dev.h>
@@ -194,14 +196,44 @@ found:
 	return err;
 }
 
+/* automatically configure a Phonet device, if supported */
+static int phonet_device_autoconf(struct net_device *dev)
+{
+	struct if_phonet_req req;
+	int ret;
+
+	if (!dev->netdev_ops->ndo_do_ioctl)
+		return -EOPNOTSUPP;
+
+	ret = dev->netdev_ops->ndo_do_ioctl(dev, (struct ifreq *)&req,
+						SIOCPNGAUTOCONF);
+	if (ret < 0)
+		return ret;
+
+	ASSERT_RTNL();
+	ret = phonet_address_add(dev, req.ifr_phonet_autoconf.device);
+	if (ret)
+		return ret;
+	phonet_address_notify(RTM_NEWADDR, dev,
+				req.ifr_phonet_autoconf.device);
+	return 0;
+}
+
 /* notify Phonet of device events */
 static int phonet_device_notify(struct notifier_block *me, unsigned long what,
 				void *arg)
 {
 	struct net_device *dev = arg;
 
-	if (what == NETDEV_UNREGISTER)
+	switch (what) {
+	case NETDEV_REGISTER:
+		if (dev->type == ARPHRD_PHONET)
+			phonet_device_autoconf(dev);
+		break;
+	case NETDEV_UNREGISTER:
 		phonet_device_destroy(dev);
+		break;
+	}
 	return 0;
 
 }
@@ -218,6 +250,11 @@ static int phonet_init_net(struct net *net)
 	if (!pnn)
 		return -ENOMEM;
 
+	if (!proc_net_fops_create(net, "phonet", 0, &pn_sock_seq_fops)) {
+		kfree(pnn);
+		return -ENOMEM;
+	}
+
 	INIT_LIST_HEAD(&pnn->pndevs.list);
 	spin_lock_init(&pnn->pndevs.lock);
 	net_assign_generic(net, phonet_net_id, pnn);
@@ -233,6 +270,8 @@ static void phonet_exit_net(struct net *net)
 	for_each_netdev(net, dev)
 		phonet_device_destroy(dev);
 	rtnl_unlock();
+
+	proc_net_remove(net, "phonet");
 	kfree(pnn);
 }
 
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index f8b4cee..d21fd35 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -147,7 +147,7 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 
 			if (fill_addr(skb, pnd->netdev, addr << 2,
 					 NETLINK_CB(cb->skb).pid,
-					cb->nlh->nlmsg_seq, RTM_NEWADDR))
+					cb->nlh->nlmsg_seq, RTM_NEWADDR) < 0)
 				goto out;
 		}
 	}
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index ada2a35..7a4ee39 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -412,3 +412,102 @@ found:
 	return 0;
 }
 EXPORT_SYMBOL(pn_sock_get_port);
+
+#ifdef CONFIG_PROC_FS
+static struct sock *pn_sock_get_idx(struct seq_file *seq, loff_t pos)
+{
+	struct net *net = seq_file_net(seq);
+	struct hlist_node *node;
+	struct sock *sknode;
+
+	sk_for_each(sknode, node, &pnsocks.hlist) {
+		if (!net_eq(net, sock_net(sknode)))
+			continue;
+		if (!pos)
+			return sknode;
+		pos--;
+	}
+	return NULL;
+}
+
+static struct sock *pn_sock_get_next(struct seq_file *seq, struct sock *sk)
+{
+	struct net *net = seq_file_net(seq);
+
+	do
+		sk = sk_next(sk);
+	while (sk && !net_eq(net, sock_net(sk)));
+
+	return sk;
+}
+
+static void *pn_sock_seq_start(struct seq_file *seq, loff_t *pos)
+	__acquires(pnsocks.lock)
+{
+	spin_lock_bh(&pnsocks.lock);
+	return *pos ? pn_sock_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *pn_sock_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+	struct sock *sk;
+
+	if (v == SEQ_START_TOKEN)
+		sk = pn_sock_get_idx(seq, 0);
+	else
+		sk = pn_sock_get_next(seq, v);
+	(*pos)++;
+	return sk;
+}
+
+static void pn_sock_seq_stop(struct seq_file *seq, void *v)
+	__releases(pnsocks.lock)
+{
+	spin_unlock_bh(&pnsocks.lock);
+}
+
+static int pn_sock_seq_show(struct seq_file *seq, void *v)
+{
+	int len;
+
+	if (v == SEQ_START_TOKEN)
+		seq_printf(seq, "%s%n", "pt  loc  rem rs st tx_queue rx_queue "
+			"  uid inode ref pointer drops", &len);
+	else {
+		struct sock *sk = v;
+		struct pn_sock *pn = pn_sk(sk);
+
+		seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu "
+			"%d %p %d%n",
+			sk->sk_protocol, pn->sobject, 0, pn->resource,
+			sk->sk_state,
+			sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
+			sock_i_uid(sk), sock_i_ino(sk),
+			atomic_read(&sk->sk_refcnt), sk,
+			atomic_read(&sk->sk_drops), &len);
+	}
+	seq_printf(seq, "%*s\n", 127 - len, "");
+	return 0;
+}
+
+static const struct seq_operations pn_sock_seq_ops = {
+	.start = pn_sock_seq_start,
+	.next = pn_sock_seq_next,
+	.stop = pn_sock_seq_stop,
+	.show = pn_sock_seq_show,
+};
+
+static int pn_sock_open(struct inode *inode, struct file *file)
+{
+	return seq_open_net(inode, file, &pn_sock_seq_ops,
+				sizeof(struct seq_net_private));
+}
+
+const struct file_operations pn_sock_seq_fops = {
+	.owner = THIS_MODULE,
+	.open = pn_sock_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release_net,
+};
+#endif
diff --git a/net/rds/Kconfig b/net/rds/Kconfig
index 796773b..ec753b3 100644
--- a/net/rds/Kconfig
+++ b/net/rds/Kconfig
@@ -1,14 +1,28 @@
 
 config RDS
-	tristate "Reliable Datagram Sockets (RDS) (EXPERIMENTAL)"
-	depends on INET && INFINIBAND_IPOIB && EXPERIMENTAL
-	depends on INFINIBAND && INFINIBAND_ADDR_TRANS
+	tristate "The RDS Protocol (EXPERIMENTAL)"
+	depends on INET && EXPERIMENTAL
 	---help---
-	  RDS provides reliable, sequenced delivery of datagrams
-	  over Infiniband.
+	  The RDS (Reliable Datagram Sockets) protocol provides reliable,
+	  sequenced delivery of datagrams over Infiniband, iWARP,
+	  or TCP.
+
+config RDS_RDMA
+	tristate "RDS over Infiniband and iWARP"
+	depends on RDS && INFINIBAND && INFINIBAND_ADDR_TRANS
+	---help---
+	  Allow RDS to use Infiniband and iWARP as a transport.
+	  This transport supports RDMA operations.
+
+config RDS_TCP
+	tristate "RDS over TCP"
+	depends on RDS
+	---help---
+	  Allow RDS to use TCP as a transport.
+	  This transport does not support RDMA operations.
 
 config RDS_DEBUG
-        bool "Debugging messages"
+        bool "RDS debugging messages"
 	depends on RDS
         default n
 
diff --git a/net/rds/Makefile b/net/rds/Makefile
index 51f2758..b46eca1 100644
--- a/net/rds/Makefile
+++ b/net/rds/Makefile
@@ -1,13 +1,20 @@
 obj-$(CONFIG_RDS) += rds.o
 rds-y :=	af_rds.o bind.o cong.o connection.o info.o message.o   \
 			recv.o send.o stats.o sysctl.o threads.o transport.o \
-			loop.o page.o rdma.o \
-			rdma_transport.o \
+			loop.o page.o rdma.o
+
+obj-$(CONFIG_RDS_RDMA) += rds_rdma.o
+rds_rdma-objs :=	rdma_transport.o \
 			ib.o ib_cm.o ib_recv.o ib_ring.o ib_send.o ib_stats.o \
 			ib_sysctl.o ib_rdma.o \
 			iw.o iw_cm.o iw_recv.o iw_ring.o iw_send.o iw_stats.o \
 			iw_sysctl.o iw_rdma.o
 
+
+obj-$(CONFIG_RDS_TCP) += rds_tcp.o
+rds_tcp-objs :=		tcp.o tcp_connect.o tcp_listen.o tcp_recv.o \
+			tcp_send.o tcp_stats.o
+
 ifeq ($(CONFIG_RDS_DEBUG), y)
 EXTRA_CFLAGS += -DDEBUG
 endif
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index b11e7e5..6b58aef 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -39,7 +39,6 @@
 
 #include "rds.h"
 #include "rdma.h"
-#include "rdma_transport.h"
 
 /* this is just used for stats gathering :/ */
 static DEFINE_SPINLOCK(rds_sock_lock);
@@ -360,7 +359,7 @@ static struct proto rds_proto = {
 	.obj_size = sizeof(struct rds_sock),
 };
 
-static struct proto_ops rds_proto_ops = {
+static const struct proto_ops rds_proto_ops = {
 	.family =	AF_RDS,
 	.owner =	THIS_MODULE,
 	.release =	rds_release,
@@ -509,7 +508,6 @@ out:
 
 static void __exit rds_exit(void)
 {
-	rds_rdma_exit();
 	sock_unregister(rds_family_ops.family);
 	proto_unregister(&rds_proto);
 	rds_conn_exit();
@@ -549,14 +547,8 @@ static int __init rds_init(void)
 	rds_info_register_func(RDS_INFO_SOCKETS, rds_sock_info);
 	rds_info_register_func(RDS_INFO_RECV_MESSAGES, rds_sock_inc_info);
 
-	/* ib/iwarp transports currently compiled-in */
-	ret = rds_rdma_init();
-	if (ret)
-		goto out_sock;
 	goto out;
 
-out_sock:
-	sock_unregister(rds_family_ops.family);
 out_proto:
 	proto_unregister(&rds_proto);
 out_stats:
diff --git a/net/rds/bind.c b/net/rds/bind.c
index c17cc39..5d95fc0 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -187,6 +187,9 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 	if (trans == NULL) {
 		ret = -EADDRNOTAVAIL;
 		rds_remove_bound(rs);
+		if (printk_ratelimit())
+			printk(KERN_INFO "RDS: rds_bind() could not find a transport, "
+				"load rds_tcp or rds_rdma?\n");
 		goto out;
 	}
 
diff --git a/net/rds/cong.c b/net/rds/cong.c
index 710e459..dd2711d 100644
--- a/net/rds/cong.c
+++ b/net/rds/cong.c
@@ -254,6 +254,7 @@ void rds_cong_map_updated(struct rds_cong_map *map, uint64_t portmask)
 		read_unlock_irqrestore(&rds_cong_monitor_lock, flags);
 	}
 }
+EXPORT_SYMBOL_GPL(rds_cong_map_updated);
 
 int rds_cong_updated_since(unsigned long *recent)
 {
diff --git a/net/rds/connection.c b/net/rds/connection.c
index d14445c..cc8b568 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -126,7 +126,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
 				       struct rds_transport *trans, gfp_t gfp,
 				       int is_outgoing)
 {
-	struct rds_connection *conn, *tmp, *parent = NULL;
+	struct rds_connection *conn, *parent = NULL;
 	struct hlist_head *head = rds_conn_bucket(laddr, faddr);
 	unsigned long flags;
 	int ret;
@@ -155,7 +155,6 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
 	}
 
 	INIT_HLIST_NODE(&conn->c_hash_node);
-	conn->c_version = RDS_PROTOCOL_3_0;
 	conn->c_laddr = laddr;
 	conn->c_faddr = faddr;
 	spin_lock_init(&conn->c_lock);
@@ -211,26 +210,40 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
 	  trans->t_name ? trans->t_name : "[unknown]",
 	  is_outgoing ? "(outgoing)" : "");
 
+	/*
+	 * Since we ran without holding the conn lock, someone could
+	 * have created the same conn (either normal or passive) in the
+	 * interim. We check while holding the lock. If we won, we complete
+	 * init and return our conn. If we lost, we rollback and return the
+	 * other one.
+	 */
 	spin_lock_irqsave(&rds_conn_lock, flags);
-	if (parent == NULL) {
-		tmp = rds_conn_lookup(head, laddr, faddr, trans);
-		if (tmp == NULL)
-			hlist_add_head(&conn->c_hash_node, head);
-	} else {
-		tmp = parent->c_passive;
-		if (!tmp)
+	if (parent) {
+		/* Creating passive conn */
+		if (parent->c_passive) {
+			trans->conn_free(conn->c_transport_data);
+			kmem_cache_free(rds_conn_slab, conn);
+			conn = parent->c_passive;
+		} else {
 			parent->c_passive = conn;
-	}
-
-	if (tmp) {
-		trans->conn_free(conn->c_transport_data);
-		kmem_cache_free(rds_conn_slab, conn);
-		conn = tmp;
+			rds_cong_add_conn(conn);
+			rds_conn_count++;
+		}
 	} else {
-		rds_cong_add_conn(conn);
-		rds_conn_count++;
+		/* Creating normal conn */
+		struct rds_connection *found;
+
+		found = rds_conn_lookup(head, laddr, faddr, trans);
+		if (found) {
+			trans->conn_free(conn->c_transport_data);
+			kmem_cache_free(rds_conn_slab, conn);
+			conn = found;
+		} else {
+			hlist_add_head(&conn->c_hash_node, head);
+			rds_cong_add_conn(conn);
+			rds_conn_count++;
+		}
 	}
-
 	spin_unlock_irqrestore(&rds_conn_lock, flags);
 
 out:
@@ -242,12 +255,14 @@ struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr,
 {
 	return __rds_conn_create(laddr, faddr, trans, gfp, 0);
 }
+EXPORT_SYMBOL_GPL(rds_conn_create);
 
 struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr,
 				       struct rds_transport *trans, gfp_t gfp)
 {
 	return __rds_conn_create(laddr, faddr, trans, gfp, 1);
 }
+EXPORT_SYMBOL_GPL(rds_conn_create_outgoing);
 
 void rds_conn_destroy(struct rds_connection *conn)
 {
@@ -290,6 +305,7 @@ void rds_conn_destroy(struct rds_connection *conn)
 
 	rds_conn_count--;
 }
+EXPORT_SYMBOL_GPL(rds_conn_destroy);
 
 static void rds_conn_message_info(struct socket *sock, unsigned int len,
 				  struct rds_info_iterator *iter,
@@ -393,6 +409,7 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len,
 
 	spin_unlock_irqrestore(&rds_conn_lock, flags);
 }
+EXPORT_SYMBOL_GPL(rds_for_each_conn_info);
 
 static int rds_conn_info_visitor(struct rds_connection *conn,
 				  void *buffer)
@@ -468,6 +485,7 @@ void rds_conn_drop(struct rds_connection *conn)
 	atomic_set(&conn->c_state, RDS_CONN_ERROR);
 	queue_work(rds_wq, &conn->c_down_w);
 }
+EXPORT_SYMBOL_GPL(rds_conn_drop);
 
 /*
  * An error occurred on the connection
diff --git a/net/rds/ib.c b/net/rds/ib.c
index b9bcd32..536ebe5 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -43,11 +43,14 @@
 
 unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE;
 unsigned int fmr_message_size = RDS_FMR_SIZE + 1; /* +1 allows for unaligned MRs */
+unsigned int rds_ib_retry_count = RDS_IB_DEFAULT_RETRY_COUNT;
 
 module_param(fmr_pool_size, int, 0444);
 MODULE_PARM_DESC(fmr_pool_size, " Max number of fmr per HCA");
 module_param(fmr_message_size, int, 0444);
 MODULE_PARM_DESC(fmr_message_size, " Max size of a RDMA transfer");
+module_param(rds_ib_retry_count, int, 0444);
+MODULE_PARM_DESC(rds_ib_retry_count, " Number of hw retries before reporting an error");
 
 struct list_head rds_ib_devices;
 
@@ -82,9 +85,6 @@ void rds_ib_add_one(struct ib_device *device)
 	rds_ibdev->max_wrs = dev_attr->max_qp_wr;
 	rds_ibdev->max_sge = min(dev_attr->max_sge, RDS_IB_MAX_SGE);
 
-	rds_ibdev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
-	rds_ibdev->fmr_page_size  = 1 << rds_ibdev->fmr_page_shift;
-	rds_ibdev->fmr_page_mask  = ~((u64) rds_ibdev->fmr_page_size - 1);
 	rds_ibdev->fmr_max_remaps = dev_attr->max_map_per_fmr?: 32;
 	rds_ibdev->max_fmrs = dev_attr->max_fmr ?
 			min_t(unsigned int, dev_attr->max_fmr, fmr_pool_size) :
@@ -282,6 +282,7 @@ struct rds_transport rds_ib_transport = {
 	.flush_mrs		= rds_ib_flush_mrs,
 	.t_owner		= THIS_MODULE,
 	.t_name			= "infiniband",
+	.t_type			= RDS_TRANS_IB
 };
 
 int __init rds_ib_init(void)
diff --git a/net/rds/ib.h b/net/rds/ib.h
index 455ae73..1378b85 100644
--- a/net/rds/ib.h
+++ b/net/rds/ib.h
@@ -15,6 +15,8 @@
 #define RDS_IB_DEFAULT_RECV_WR		1024
 #define RDS_IB_DEFAULT_SEND_WR		256
 
+#define RDS_IB_DEFAULT_RETRY_COUNT	2
+
 #define RDS_IB_SUPPORTED_PROTOCOLS	0x00000003	/* minor versions supported */
 
 extern struct list_head rds_ib_devices;
@@ -157,9 +159,6 @@ struct rds_ib_device {
 	struct ib_pd		*pd;
 	struct ib_mr		*mr;
 	struct rds_ib_mr_pool	*mr_pool;
-	int			fmr_page_shift;
-	int			fmr_page_size;
-	u64			fmr_page_mask;
 	unsigned int		fmr_max_remaps;
 	unsigned int		max_fmrs;
 	int			max_sge;
@@ -247,6 +246,7 @@ extern struct ib_client rds_ib_client;
 
 extern unsigned int fmr_pool_size;
 extern unsigned int fmr_message_size;
+extern unsigned int rds_ib_retry_count;
 
 extern spinlock_t ib_nodev_conns_lock;
 extern struct list_head ib_nodev_conns;
@@ -355,17 +355,25 @@ extern ctl_table rds_ib_sysctl_table[];
 /*
  * Helper functions for getting/setting the header and data SGEs in
  * RDS packets (not RDMA)
+ *
+ * From version 3.1 onwards, header is in front of data in the sge.
  */
 static inline struct ib_sge *
 rds_ib_header_sge(struct rds_ib_connection *ic, struct ib_sge *sge)
 {
-	return &sge[0];
+	if (ic->conn->c_version > RDS_PROTOCOL_3_0)
+		return &sge[0];
+	else
+		return &sge[1];
 }
 
 static inline struct ib_sge *
 rds_ib_data_sge(struct rds_ib_connection *ic, struct ib_sge *sge)
 {
-	return &sge[1];
+	if (ic->conn->c_version > RDS_PROTOCOL_3_0)
+		return &sge[1];
+	else
+		return &sge[0];
 }
 
 #endif
diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c
index f8e40e1..c2d372f 100644
--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -98,21 +98,34 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
 	struct ib_qp_attr qp_attr;
 	int err;
 
-	if (event->param.conn.private_data_len) {
+	if (event->param.conn.private_data_len >= sizeof(*dp)) {
 		dp = event->param.conn.private_data;
 
-		rds_ib_set_protocol(conn,
+		/* make sure it isn't empty data */
+		if (dp->dp_protocol_major) {
+			rds_ib_set_protocol(conn,
 				RDS_PROTOCOL(dp->dp_protocol_major,
-					dp->dp_protocol_minor));
-		rds_ib_set_flow_control(conn, be32_to_cpu(dp->dp_credit));
+				dp->dp_protocol_minor));
+			rds_ib_set_flow_control(conn, be32_to_cpu(dp->dp_credit));
+		}
 	}
 
 	printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n",
-			&conn->c_laddr,
+			&conn->c_faddr,
 			RDS_PROTOCOL_MAJOR(conn->c_version),
 			RDS_PROTOCOL_MINOR(conn->c_version),
 			ic->i_flowctl ? ", flow control" : "");
 
+	/*
+	 * Init rings and fill recv. this needs to wait until protocol negotiation
+	 * is complete, since ring layout is different from 3.0 to 3.1.
+	 */
+	rds_ib_send_init_ring(ic);
+	rds_ib_recv_init_ring(ic);
+	/* Post receive buffers - as a side effect, this will update
+	 * the posted credit count. */
+	rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1);
+
 	/* Tune RNR behavior */
 	rds_ib_tune_rnr(ic, &qp_attr);
 
@@ -145,7 +158,7 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn,
 	/* XXX tune these? */
 	conn_param->responder_resources = 1;
 	conn_param->initiator_depth = 1;
-	conn_param->retry_count = 7;
+	conn_param->retry_count = min_t(unsigned int, rds_ib_retry_count, 7);
 	conn_param->rnr_retry_count = 7;
 
 	if (dp) {
@@ -190,9 +203,9 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data)
 		rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST);
 		break;
 	default:
-		printk(KERN_WARNING "RDS/ib: unhandled QP event %u "
-		       "on connection to %pI4\n", event->event,
-		       &conn->c_faddr);
+		rds_ib_conn_error(conn, "RDS/IB: Fatal QP Event %u "
+			"- connection %pI4->%pI4, reconnecting\n",
+			event->event, &conn->c_laddr, &conn->c_faddr);
 		break;
 	}
 }
@@ -321,7 +334,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
 		rdsdebug("send allocation failed\n");
 		goto out;
 	}
-	rds_ib_send_init_ring(ic);
+	memset(ic->i_sends, 0, ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work));
 
 	ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work));
 	if (ic->i_recvs == NULL) {
@@ -329,14 +342,10 @@ static int rds_ib_setup_qp(struct rds_connection *conn)
 		rdsdebug("recv allocation failed\n");
 		goto out;
 	}
+	memset(ic->i_recvs, 0, ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work));
 
-	rds_ib_recv_init_ring(ic);
 	rds_ib_recv_init_ack(ic);
 
-	/* Post receive buffers - as a side effect, this will update
-	 * the posted credit count. */
-	rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1);
-
 	rdsdebug("conn %p pd %p mr %p cq %p %p\n", conn, ic->i_pd, ic->i_mr,
 		 ic->i_send_cq, ic->i_recv_cq);
 
@@ -344,19 +353,32 @@ out:
 	return ret;
 }
 
-static u32 rds_ib_protocol_compatible(const struct rds_ib_connect_private *dp)
+static u32 rds_ib_protocol_compatible(struct rdma_cm_event *event)
 {
+	const struct rds_ib_connect_private *dp = event->param.conn.private_data;
 	u16 common;
 	u32 version = 0;
 
-	/* rdma_cm private data is odd - when there is any private data in the
+	/*
+	 * rdma_cm private data is odd - when there is any private data in the
 	 * request, we will be given a pretty large buffer without telling us the
 	 * original size. The only way to tell the difference is by looking at
 	 * the contents, which are initialized to zero.
 	 * If the protocol version fields aren't set, this is a connection attempt
 	 * from an older version. This could could be 3.0 or 2.0 - we can't tell.
-	 * We really should have changed this for OFED 1.3 :-( */
-	if (dp->dp_protocol_major == 0)
+	 * We really should have changed this for OFED 1.3 :-(
+	 */
+
+	/* Be paranoid. RDS always has privdata */
+	if (!event->param.conn.private_data_len) {
+		printk(KERN_NOTICE "RDS incoming connection has no private data, "
+			"rejecting\n");
+		return 0;
+	}
+
+	/* Even if len is crap *now* I still want to check it. -ASG */
+	if (event->param.conn.private_data_len < sizeof (*dp)
+	    || dp->dp_protocol_major == 0)
 		return RDS_PROTOCOL_3_0;
 
 	common = be16_to_cpu(dp->dp_protocol_minor_mask) & RDS_IB_SUPPORTED_PROTOCOLS;
@@ -388,7 +410,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
 	int err, destroy = 1;
 
 	/* Check whether the remote protocol version matches ours. */
-	version = rds_ib_protocol_compatible(dp);
+	version = rds_ib_protocol_compatible(event);
 	if (!version)
 		goto out;
 
diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c
index 81033af..ef3ab5b 100644
--- a/net/rds/ib_rdma.c
+++ b/net/rds/ib_rdma.c
@@ -211,7 +211,7 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev)
 
 	pool->fmr_attr.max_pages = fmr_message_size;
 	pool->fmr_attr.max_maps = rds_ibdev->fmr_max_remaps;
-	pool->fmr_attr.page_shift = rds_ibdev->fmr_page_shift;
+	pool->fmr_attr.page_shift = PAGE_SHIFT;
 	pool->max_free_pinned = rds_ibdev->max_fmrs * fmr_message_size / 4;
 
 	/* We never allow more than max_items MRs to be allocated.
@@ -349,13 +349,13 @@ static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibm
 		unsigned int dma_len = ib_sg_dma_len(dev, &scat[i]);
 		u64 dma_addr = ib_sg_dma_address(dev, &scat[i]);
 
-		if (dma_addr & ~rds_ibdev->fmr_page_mask) {
+		if (dma_addr & ~PAGE_MASK) {
 			if (i > 0)
 				return -EINVAL;
 			else
 				++page_cnt;
 		}
-		if ((dma_addr + dma_len) & ~rds_ibdev->fmr_page_mask) {
+		if ((dma_addr + dma_len) & ~PAGE_MASK) {
 			if (i < sg_dma_len - 1)
 				return -EINVAL;
 			else
@@ -365,7 +365,7 @@ static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibm
 		len += dma_len;
 	}
 
-	page_cnt += len >> rds_ibdev->fmr_page_shift;
+	page_cnt += len >> PAGE_SHIFT;
 	if (page_cnt > fmr_message_size)
 		return -EINVAL;
 
@@ -378,9 +378,9 @@ static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibm
 		unsigned int dma_len = ib_sg_dma_len(dev, &scat[i]);
 		u64 dma_addr = ib_sg_dma_address(dev, &scat[i]);
 
-		for (j = 0; j < dma_len; j += rds_ibdev->fmr_page_size)
+		for (j = 0; j < dma_len; j += PAGE_SIZE)
 			dma_pages[page_cnt++] =
-				(dma_addr & rds_ibdev->fmr_page_mask) + j;
+				(dma_addr & PAGE_MASK) + j;
 	}
 
 	ret = ib_map_phys_fmr(ibmr->fmr,
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index 5709bad..cd7a6cf 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -555,6 +555,47 @@ u64 rds_ib_piggyb_ack(struct rds_ib_connection *ic)
 	return rds_ib_get_ack(ic);
 }
 
+static struct rds_header *rds_ib_get_header(struct rds_connection *conn,
+					    struct rds_ib_recv_work *recv,
+					    u32 data_len)
+{
+	struct rds_ib_connection *ic = conn->c_transport_data;
+	void *hdr_buff = &ic->i_recv_hdrs[recv - ic->i_recvs];
+	void *addr;
+	u32 misplaced_hdr_bytes;
+
+	/*
+	 * Support header at the front (RDS 3.1+) as well as header-at-end.
+	 *
+	 * Cases:
+	 * 1) header all in header buff (great!)
+	 * 2) header all in data page (copy all to header buff)
+	 * 3) header split across hdr buf + data page
+	 *    (move bit in hdr buff to end before copying other bit from data page)
+	 */
+	if (conn->c_version > RDS_PROTOCOL_3_0 || data_len == RDS_FRAG_SIZE)
+	        return hdr_buff;
+
+	if (data_len <= (RDS_FRAG_SIZE - sizeof(struct rds_header))) {
+		addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0);
+		memcpy(hdr_buff,
+		       addr + recv->r_frag->f_offset + data_len,
+		       sizeof(struct rds_header));
+		kunmap_atomic(addr, KM_SOFTIRQ0);
+		return hdr_buff;
+	}
+
+	misplaced_hdr_bytes = (sizeof(struct rds_header) - (RDS_FRAG_SIZE - data_len));
+
+	memmove(hdr_buff + misplaced_hdr_bytes, hdr_buff, misplaced_hdr_bytes);
+
+	addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0);
+	memcpy(hdr_buff, addr + recv->r_frag->f_offset + data_len,
+	       sizeof(struct rds_header) - misplaced_hdr_bytes);
+	kunmap_atomic(addr, KM_SOFTIRQ0);
+	return hdr_buff;
+}
+
 /*
  * It's kind of lame that we're copying from the posted receive pages into
  * long-lived bitmaps.  We could have posted the bitmaps and rdma written into
@@ -645,7 +686,7 @@ struct rds_ib_ack_state {
 };
 
 static void rds_ib_process_recv(struct rds_connection *conn,
-				struct rds_ib_recv_work *recv, u32 byte_len,
+				struct rds_ib_recv_work *recv, u32 data_len,
 				struct rds_ib_ack_state *state)
 {
 	struct rds_ib_connection *ic = conn->c_transport_data;
@@ -655,9 +696,9 @@ static void rds_ib_process_recv(struct rds_connection *conn,
 	/* XXX shut down the connection if port 0,0 are seen? */
 
 	rdsdebug("ic %p ibinc %p recv %p byte len %u\n", ic, ibinc, recv,
-		 byte_len);
+		 data_len);
 
-	if (byte_len < sizeof(struct rds_header)) {
+	if (data_len < sizeof(struct rds_header)) {
 		rds_ib_conn_error(conn, "incoming message "
 		       "from %pI4 didn't inclue a "
 		       "header, disconnecting and "
@@ -665,9 +706,9 @@ static void rds_ib_process_recv(struct rds_connection *conn,
 		       &conn->c_faddr);
 		return;
 	}
-	byte_len -= sizeof(struct rds_header);
+	data_len -= sizeof(struct rds_header);
 
-	ihdr = &ic->i_recv_hdrs[recv - ic->i_recvs];
+	ihdr = rds_ib_get_header(conn, recv, data_len);
 
 	/* Validate the checksum. */
 	if (!rds_message_verify_checksum(ihdr)) {
@@ -687,7 +728,7 @@ static void rds_ib_process_recv(struct rds_connection *conn,
 	if (ihdr->h_credit)
 		rds_ib_send_add_credits(conn, ihdr->h_credit);
 
-	if (ihdr->h_sport == 0 && ihdr->h_dport == 0 && byte_len == 0) {
+	if (ihdr->h_sport == 0 && ihdr->h_dport == 0 && data_len == 0) {
 		/* This is an ACK-only packet. The fact that it gets
 		 * special treatment here is that historically, ACKs
 		 * were rather special beasts.
diff --git a/net/rds/ib_stats.c b/net/rds/ib_stats.c
index 02e3e3d..d2c904d 100644
--- a/net/rds/ib_stats.c
+++ b/net/rds/ib_stats.c
@@ -37,9 +37,9 @@
 #include "rds.h"
 #include "ib.h"
 
-DEFINE_PER_CPU(struct rds_ib_statistics, rds_ib_stats) ____cacheline_aligned;
+DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_ib_statistics, rds_ib_stats);
 
-static char *rds_ib_stat_names[] = {
+static const char *const rds_ib_stat_names[] = {
 	"ib_connect_raced",
 	"ib_listen_closed_stale",
 	"ib_tx_cq_call",
diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c
index d87830d..84b5ffc 100644
--- a/net/rds/ib_sysctl.c
+++ b/net/rds/ib_sysctl.c
@@ -53,7 +53,17 @@ unsigned long rds_ib_sysctl_max_unsig_bytes = (16 << 20);
 static unsigned long rds_ib_sysctl_max_unsig_bytes_min = 1;
 static unsigned long rds_ib_sysctl_max_unsig_bytes_max = ~0UL;
 
-unsigned int rds_ib_sysctl_flow_control = 1;
+/*
+ * This sysctl does nothing.
+ *
+ * Backwards compatibility with RDS 3.0 wire protocol
+ * disables initial FC credit exchange.
+ * If it's ever possible to drop 3.0 support,
+ * setting this to 1 and moving init/refill of send/recv
+ * rings from ib_cm_connect_complete() back into ib_setup_qp()
+ * will cause credits to be added before protocol negotiation.
+ */
+unsigned int rds_ib_sysctl_flow_control = 0;
 
 ctl_table rds_ib_sysctl_table[] = {
 	{
diff --git a/net/rds/info.c b/net/rds/info.c
index 62aeef3..814a91a 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -79,6 +79,7 @@ void rds_info_register_func(int optname, rds_info_func func)
 	rds_info_funcs[offset] = func;
 	spin_unlock(&rds_info_lock);
 }
+EXPORT_SYMBOL_GPL(rds_info_register_func);
 
 void rds_info_deregister_func(int optname, rds_info_func func)
 {
@@ -91,6 +92,7 @@ void rds_info_deregister_func(int optname, rds_info_func func)
 	rds_info_funcs[offset] = NULL;
 	spin_unlock(&rds_info_lock);
 }
+EXPORT_SYMBOL_GPL(rds_info_deregister_func);
 
 /*
  * Typically we hold an atomic kmap across multiple rds_info_copy() calls
@@ -137,6 +139,7 @@ void rds_info_copy(struct rds_info_iterator *iter, void *data,
 		}
 	}
 }
+EXPORT_SYMBOL_GPL(rds_info_copy);
 
 /*
  * @optval points to the userspace buffer that the information snapshot
diff --git a/net/rds/iw.c b/net/rds/iw.c
index d16e1cb..db224f7 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -83,23 +83,16 @@ void rds_iw_add_one(struct ib_device *device)
 	rds_iwdev->max_wrs = dev_attr->max_qp_wr;
 	rds_iwdev->max_sge = min(dev_attr->max_sge, RDS_IW_MAX_SGE);
 
-	rds_iwdev->page_shift = max(PAGE_SHIFT, ffs(dev_attr->page_size_cap) - 1);
-
 	rds_iwdev->dev = device;
 	rds_iwdev->pd = ib_alloc_pd(device);
 	if (IS_ERR(rds_iwdev->pd))
 		goto free_dev;
 
 	if (!rds_iwdev->dma_local_lkey) {
-		if (device->node_type != RDMA_NODE_RNIC) {
-			rds_iwdev->mr = ib_get_dma_mr(rds_iwdev->pd,
-						IB_ACCESS_LOCAL_WRITE);
-		} else {
-			rds_iwdev->mr = ib_get_dma_mr(rds_iwdev->pd,
-						IB_ACCESS_REMOTE_READ |
-						IB_ACCESS_REMOTE_WRITE |
-						IB_ACCESS_LOCAL_WRITE);
-		}
+		rds_iwdev->mr = ib_get_dma_mr(rds_iwdev->pd,
+					IB_ACCESS_REMOTE_READ |
+					IB_ACCESS_REMOTE_WRITE |
+					IB_ACCESS_LOCAL_WRITE);
 		if (IS_ERR(rds_iwdev->mr))
 			goto err_pd;
 	} else
@@ -291,6 +284,7 @@ struct rds_transport rds_iw_transport = {
 	.flush_mrs		= rds_iw_flush_mrs,
 	.t_owner		= THIS_MODULE,
 	.t_name			= "iwarp",
+	.t_type			= RDS_TRANS_IWARP,
 	.t_prefer_loopback	= 1,
 };
 
diff --git a/net/rds/iw.h b/net/rds/iw.h
index 0715dde..dd72b62 100644
--- a/net/rds/iw.h
+++ b/net/rds/iw.h
@@ -181,7 +181,6 @@ struct rds_iw_device {
 	struct ib_pd		*pd;
 	struct ib_mr		*mr;
 	struct rds_iw_mr_pool	*mr_pool;
-	int			page_shift;
 	int			max_sge;
 	unsigned int		max_wrs;
 	unsigned int		dma_local_lkey:1;
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c
index dcdb37d..de4a1b1 100644
--- a/net/rds/iw_rdma.c
+++ b/net/rds/iw_rdma.c
@@ -263,18 +263,12 @@ static void rds_iw_set_scatterlist(struct rds_iw_scatterlist *sg,
 }
 
 static u64 *rds_iw_map_scatterlist(struct rds_iw_device *rds_iwdev,
-			struct rds_iw_scatterlist *sg,
-			unsigned int dma_page_shift)
+			struct rds_iw_scatterlist *sg)
 {
 	struct ib_device *dev = rds_iwdev->dev;
 	u64 *dma_pages = NULL;
-	u64 dma_mask;
-	unsigned int dma_page_size;
 	int i, j, ret;
 
-	dma_page_size = 1 << dma_page_shift;
-	dma_mask = dma_page_size - 1;
-
 	WARN_ON(sg->dma_len);
 
 	sg->dma_len = ib_dma_map_sg(dev, sg->list, sg->len, DMA_BIDIRECTIONAL);
@@ -295,18 +289,18 @@ static u64 *rds_iw_map_scatterlist(struct rds_iw_device *rds_iwdev,
 		sg->bytes += dma_len;
 
 		end_addr = dma_addr + dma_len;
-		if (dma_addr & dma_mask) {
+		if (dma_addr & PAGE_MASK) {
 			if (i > 0)
 				goto out_unmap;
-			dma_addr &= ~dma_mask;
+			dma_addr &= ~PAGE_MASK;
 		}
-		if (end_addr & dma_mask) {
+		if (end_addr & PAGE_MASK) {
 			if (i < sg->dma_len - 1)
 				goto out_unmap;
-			end_addr = (end_addr + dma_mask) & ~dma_mask;
+			end_addr = (end_addr + PAGE_MASK) & ~PAGE_MASK;
 		}
 
-		sg->dma_npages += (end_addr - dma_addr) >> dma_page_shift;
+		sg->dma_npages += (end_addr - dma_addr) >> PAGE_SHIFT;
 	}
 
 	/* Now gather the dma addrs into one list */
@@ -325,8 +319,8 @@ static u64 *rds_iw_map_scatterlist(struct rds_iw_device *rds_iwdev,
 		u64 end_addr;
 
 		end_addr = dma_addr + dma_len;
-		dma_addr &= ~dma_mask;
-		for (; dma_addr < end_addr; dma_addr += dma_page_size)
+		dma_addr &= ~PAGE_MASK;
+		for (; dma_addr < end_addr; dma_addr += PAGE_SIZE)
 			dma_pages[j++] = dma_addr;
 		BUG_ON(j > sg->dma_npages);
 	}
@@ -727,7 +721,7 @@ static int rds_iw_rdma_build_fastreg(struct rds_iw_mapping *mapping)
 	f_wr.wr.fast_reg.rkey = mapping->m_rkey;
 	f_wr.wr.fast_reg.page_list = ibmr->page_list;
 	f_wr.wr.fast_reg.page_list_len = mapping->m_sg.dma_len;
-	f_wr.wr.fast_reg.page_shift = ibmr->device->page_shift;
+	f_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
 	f_wr.wr.fast_reg.access_flags = IB_ACCESS_LOCAL_WRITE |
 				IB_ACCESS_REMOTE_READ |
 				IB_ACCESS_REMOTE_WRITE;
@@ -780,9 +774,7 @@ static int rds_iw_map_fastreg(struct rds_iw_mr_pool *pool,
 
 	rds_iw_set_scatterlist(&mapping->m_sg, sg, sg_len);
 
-	dma_pages = rds_iw_map_scatterlist(rds_iwdev,
-				&mapping->m_sg,
-				rds_iwdev->page_shift);
+	dma_pages = rds_iw_map_scatterlist(rds_iwdev, &mapping->m_sg);
 	if (IS_ERR(dma_pages)) {
 		ret = PTR_ERR(dma_pages);
 		dma_pages = NULL;
diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c
index 44a6a05..1f5abe3 100644
--- a/net/rds/iw_send.c
+++ b/net/rds/iw_send.c
@@ -779,7 +779,7 @@ static void rds_iw_build_send_fastreg(struct rds_iw_device *rds_iwdev, struct rd
 	send->s_wr.wr.fast_reg.rkey = send->s_mr->rkey;
 	send->s_wr.wr.fast_reg.page_list = send->s_page_list;
 	send->s_wr.wr.fast_reg.page_list_len = nent;
-	send->s_wr.wr.fast_reg.page_shift = rds_iwdev->page_shift;
+	send->s_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
 	send->s_wr.wr.fast_reg.access_flags = IB_ACCESS_REMOTE_WRITE;
 	send->s_wr.wr.fast_reg.iova_start = sg_addr;
 
diff --git a/net/rds/iw_stats.c b/net/rds/iw_stats.c
index ccc7e8f..5fe67f6 100644
--- a/net/rds/iw_stats.c
+++ b/net/rds/iw_stats.c
@@ -37,9 +37,9 @@
 #include "rds.h"
 #include "iw.h"
 
-DEFINE_PER_CPU(struct rds_iw_statistics, rds_iw_stats) ____cacheline_aligned;
+DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_iw_statistics, rds_iw_stats);
 
-static char *rds_iw_stat_names[] = {
+static const char *const rds_iw_stat_names[] = {
 	"iw_connect_raced",
 	"iw_listen_closed_stale",
 	"iw_tx_cq_call",
diff --git a/net/rds/message.c b/net/rds/message.c
index 5a15dc8..ca50a8e 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -50,6 +50,7 @@ void rds_message_addref(struct rds_message *rm)
 	rdsdebug("addref rm %p ref %d\n", rm, atomic_read(&rm->m_refcount));
 	atomic_inc(&rm->m_refcount);
 }
+EXPORT_SYMBOL_GPL(rds_message_addref);
 
 /*
  * This relies on dma_map_sg() not touching sg[].page during merging.
@@ -92,6 +93,7 @@ void rds_message_put(struct rds_message *rm)
 		kfree(rm);
 	}
 }
+EXPORT_SYMBOL_GPL(rds_message_put);
 
 void rds_message_inc_free(struct rds_incoming *inc)
 {
@@ -108,6 +110,7 @@ void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
 	hdr->h_sequence = cpu_to_be64(seq);
 	hdr->h_exthdr[0] = RDS_EXTHDR_NONE;
 }
+EXPORT_SYMBOL_GPL(rds_message_populate_header);
 
 int rds_message_add_extension(struct rds_header *hdr,
 		unsigned int type, const void *data, unsigned int len)
@@ -133,6 +136,7 @@ int rds_message_add_extension(struct rds_header *hdr,
 	dst[len] = RDS_EXTHDR_NONE;
 	return 1;
 }
+EXPORT_SYMBOL_GPL(rds_message_add_extension);
 
 /*
  * If a message has extension headers, retrieve them here.
@@ -208,6 +212,7 @@ int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 o
 	ext_hdr.h_rdma_offset = cpu_to_be32(offset);
 	return rds_message_add_extension(hdr, RDS_EXTHDR_RDMA_DEST, &ext_hdr, sizeof(ext_hdr));
 }
+EXPORT_SYMBOL_GPL(rds_message_add_rdma_dest_extension);
 
 struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp)
 {
@@ -399,4 +404,5 @@ void rds_message_unmapped(struct rds_message *rm)
 	if (waitqueue_active(&rds_message_flush_waitq))
 		wake_up(&rds_message_flush_waitq);
 }
+EXPORT_SYMBOL_GPL(rds_message_unmapped);
 
diff --git a/net/rds/page.c b/net/rds/page.c
index c460743..3679012 100644
--- a/net/rds/page.c
+++ b/net/rds/page.c
@@ -39,7 +39,7 @@ struct rds_page_remainder {
 	unsigned long	r_offset;
 };
 
-DEFINE_PER_CPU(struct rds_page_remainder, rds_page_remainders) ____cacheline_aligned;
+DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder, rds_page_remainders);
 
 /*
  * returns 0 on success or -errno on failure.
@@ -81,6 +81,7 @@ int rds_page_copy_user(struct page *page, unsigned long offset,
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rds_page_copy_user);
 
 /*
  * Message allocation uses this to build up regions of a message.
diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c
index 7d0f901..9ece910 100644
--- a/net/rds/rdma_transport.c
+++ b/net/rds/rdma_transport.c
@@ -101,7 +101,7 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
 		break;
 
 	case RDMA_CM_EVENT_DISCONNECTED:
-		printk(KERN_WARNING "RDS/IW: DISCONNECT event - dropping connection "
+		printk(KERN_WARNING "RDS/RDMA: DISCONNECT event - dropping connection "
 			"%pI4->%pI4\n", &conn->c_laddr,
 			 &conn->c_faddr);
 		rds_conn_drop(conn);
@@ -132,12 +132,12 @@ static int __init rds_rdma_listen_init(void)
 	cm_id = rdma_create_id(rds_rdma_cm_event_handler, NULL, RDMA_PS_TCP);
 	if (IS_ERR(cm_id)) {
 		ret = PTR_ERR(cm_id);
-		printk(KERN_ERR "RDS/IW: failed to setup listener, "
+		printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
 		       "rdma_create_id() returned %d\n", ret);
 		goto out;
 	}
 
-	sin.sin_family = PF_INET,
+	sin.sin_family = AF_INET,
 	sin.sin_addr.s_addr = (__force u32)htonl(INADDR_ANY);
 	sin.sin_port = (__force u16)htons(RDS_PORT);
 
@@ -147,14 +147,14 @@ static int __init rds_rdma_listen_init(void)
 	 */
 	ret = rdma_bind_addr(cm_id, (struct sockaddr *)&sin);
 	if (ret) {
-		printk(KERN_ERR "RDS/IW: failed to setup listener, "
+		printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
 		       "rdma_bind_addr() returned %d\n", ret);
 		goto out;
 	}
 
 	ret = rdma_listen(cm_id, 128);
 	if (ret) {
-		printk(KERN_ERR "RDS/IW: failed to setup listener, "
+		printk(KERN_ERR "RDS/RDMA: failed to setup listener, "
 		       "rdma_listen() returned %d\n", ret);
 		goto out;
 	}
@@ -203,6 +203,7 @@ err_iw_init:
 out:
 	return ret;
 }
+module_init(rds_rdma_init);
 
 void rds_rdma_exit(void)
 {
@@ -211,4 +212,9 @@ void rds_rdma_exit(void)
 	rds_ib_exit();
 	rds_iw_exit();
 }
+module_exit(rds_rdma_exit);
+
+MODULE_AUTHOR("Oracle Corporation <rds-devel@oss.oracle.com>");
+MODULE_DESCRIPTION("RDS: IB/iWARP transport");
+MODULE_LICENSE("Dual BSD/GPL");
 
diff --git a/net/rds/rds.h b/net/rds/rds.h
index dbe1112..85d6f89 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -311,11 +311,17 @@ struct rds_notifier {
  * 		   flag and header.
  */
 
+#define RDS_TRANS_IB	0
+#define RDS_TRANS_IWARP	1
+#define RDS_TRANS_TCP	2
+#define RDS_TRANS_COUNT	3
+
 struct rds_transport {
 	char			t_name[TRANSNAMSIZ];
 	struct list_head	t_item;
 	struct module		*t_owner;
 	unsigned int		t_prefer_loopback:1;
+	unsigned int		t_type;
 
 	int (*laddr_check)(__be32 addr);
 	int (*conn_alloc)(struct rds_connection *conn, gfp_t gfp);
@@ -652,7 +658,8 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats);
 int __init rds_stats_init(void);
 void rds_stats_exit(void);
 void rds_stats_info_copy(struct rds_info_iterator *iter,
-			 uint64_t *values, char **names, size_t nr);
+			 uint64_t *values, const char *const *names,
+			 size_t nr);
 
 /* sysctl.c */
 int __init rds_sysctl_init(void);
diff --git a/net/rds/recv.c b/net/rds/recv.c
index f2118c5..fdff33c 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -46,12 +46,14 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn,
 	inc->i_saddr = saddr;
 	inc->i_rdma_cookie = 0;
 }
+EXPORT_SYMBOL_GPL(rds_inc_init);
 
 void rds_inc_addref(struct rds_incoming *inc)
 {
 	rdsdebug("addref inc %p ref %d\n", inc, atomic_read(&inc->i_refcount));
 	atomic_inc(&inc->i_refcount);
 }
+EXPORT_SYMBOL_GPL(rds_inc_addref);
 
 void rds_inc_put(struct rds_incoming *inc)
 {
@@ -62,6 +64,7 @@ void rds_inc_put(struct rds_incoming *inc)
 		inc->i_conn->c_trans->inc_free(inc);
 	}
 }
+EXPORT_SYMBOL_GPL(rds_inc_put);
 
 static void rds_recv_rcvbuf_delta(struct rds_sock *rs, struct sock *sk,
 				  struct rds_cong_map *map,
@@ -237,6 +240,7 @@ out:
 	if (rs)
 		rds_sock_put(rs);
 }
+EXPORT_SYMBOL_GPL(rds_recv_incoming);
 
 /*
  * be very careful here.  This is being called as the condition in
@@ -409,18 +413,18 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 	if (msg_flags & MSG_OOB)
 		goto out;
 
-	/* If there are pending notifications, do those - and nothing else */
-	if (!list_empty(&rs->rs_notify_queue)) {
-		ret = rds_notify_queue_get(rs, msg);
-		goto out;
-	}
+	while (1) {
+		/* If there are pending notifications, do those - and nothing else */
+		if (!list_empty(&rs->rs_notify_queue)) {
+			ret = rds_notify_queue_get(rs, msg);
+			break;
+		}
 
-	if (rs->rs_cong_notify) {
-		ret = rds_notify_cong(rs, msg);
-		goto out;
-	}
+		if (rs->rs_cong_notify) {
+			ret = rds_notify_cong(rs, msg);
+			break;
+		}
 
-	while (1) {
 		if (!rds_next_incoming(rs, &inc)) {
 			if (nonblock) {
 				ret = -EAGAIN;
@@ -428,7 +432,9 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 			}
 
 			timeo = wait_event_interruptible_timeout(*sk->sk_sleep,
-						rds_next_incoming(rs, &inc),
+						(!list_empty(&rs->rs_notify_queue)
+						|| rs->rs_cong_notify
+						|| rds_next_incoming(rs, &inc)),
 						timeo);
 			rdsdebug("recvmsg woke inc %p timeo %ld\n", inc,
 				 timeo);
diff --git a/net/rds/send.c b/net/rds/send.c
index a4a7f42..28c88ff 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -439,6 +439,7 @@ void rds_rdma_send_complete(struct rds_message *rm, int status)
 		sock_put(rds_rs_to_sk(rs));
 	}
 }
+EXPORT_SYMBOL_GPL(rds_rdma_send_complete);
 
 /*
  * This is the same as rds_rdma_send_complete except we
@@ -494,6 +495,7 @@ out:
 
 	return found;
 }
+EXPORT_SYMBOL_GPL(rds_send_get_message);
 
 /*
  * This removes messages from the socket's list if they're on it.  The list
@@ -610,6 +612,7 @@ void rds_send_drop_acked(struct rds_connection *conn, u64 ack,
 	/* now remove the messages from the sock list as needed */
 	rds_send_remove_from_sock(&list, RDS_RDMA_SUCCESS);
 }
+EXPORT_SYMBOL_GPL(rds_send_drop_acked);
 
 void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest)
 {
diff --git a/net/rds/stats.c b/net/rds/stats.c
index 6371468..7598eb0 100644
--- a/net/rds/stats.c
+++ b/net/rds/stats.c
@@ -37,10 +37,11 @@
 #include "rds.h"
 
 DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats);
+EXPORT_PER_CPU_SYMBOL_GPL(rds_stats);
 
 /* :.,$s/unsigned long\>.*\<s_\(.*\);/"\1",/g */
 
-static char *rds_stat_names[] = {
+static const char *const rds_stat_names[] = {
 	"conn_reset",
 	"recv_drop_bad_checksum",
 	"recv_drop_old_seq",
@@ -77,7 +78,7 @@ static char *rds_stat_names[] = {
 };
 
 void rds_stats_info_copy(struct rds_info_iterator *iter,
-			 uint64_t *values, char **names, size_t nr)
+			 uint64_t *values, const char *const *names, size_t nr)
 {
 	struct rds_info_counter ctr;
 	size_t i;
@@ -90,6 +91,7 @@ void rds_stats_info_copy(struct rds_info_iterator *iter,
 		rds_info_copy(iter, &ctr, sizeof(ctr));
 	}
 }
+EXPORT_SYMBOL_GPL(rds_stats_info_copy);
 
 /*
  * This gives global counters across all the transports.  The strings
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
new file mode 100644
index 0000000..b5198ae
--- /dev/null
+++ b/net/rds/tcp.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2006 Oracle.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/in.h>
+#include <net/tcp.h>
+
+#include "rds.h"
+#include "tcp.h"
+
+/* only for info exporting */
+static DEFINE_SPINLOCK(rds_tcp_tc_list_lock);
+static LIST_HEAD(rds_tcp_tc_list);
+unsigned int rds_tcp_tc_count;
+
+/* Track rds_tcp_connection structs so they can be cleaned up */
+static DEFINE_SPINLOCK(rds_tcp_conn_lock);
+static LIST_HEAD(rds_tcp_conn_list);
+
+static struct kmem_cache *rds_tcp_conn_slab;
+
+#define RDS_TCP_DEFAULT_BUFSIZE (128 * 1024)
+
+/* doing it this way avoids calling tcp_sk() */
+void rds_tcp_nonagle(struct socket *sock)
+{
+	mm_segment_t oldfs = get_fs();
+	int val = 1;
+
+	set_fs(KERNEL_DS);
+	sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY, (char __user *)&val,
+			      sizeof(val));
+	set_fs(oldfs);
+}
+
+void rds_tcp_tune(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+
+	rds_tcp_nonagle(sock);
+
+	/*
+	 * We're trying to saturate gigabit with the default,
+	 * see svc_sock_setbufsize().
+	 */
+	lock_sock(sk);
+	sk->sk_sndbuf = RDS_TCP_DEFAULT_BUFSIZE;
+	sk->sk_rcvbuf = RDS_TCP_DEFAULT_BUFSIZE;
+	sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK;
+	release_sock(sk);
+}
+
+u32 rds_tcp_snd_nxt(struct rds_tcp_connection *tc)
+{
+	return tcp_sk(tc->t_sock->sk)->snd_nxt;
+}
+
+u32 rds_tcp_snd_una(struct rds_tcp_connection *tc)
+{
+	return tcp_sk(tc->t_sock->sk)->snd_una;
+}
+
+void rds_tcp_restore_callbacks(struct socket *sock,
+			       struct rds_tcp_connection *tc)
+{
+	rdsdebug("restoring sock %p callbacks from tc %p\n", sock, tc);
+	write_lock_bh(&sock->sk->sk_callback_lock);
+
+	/* done under the callback_lock to serialize with write_space */
+	spin_lock(&rds_tcp_tc_list_lock);
+	list_del_init(&tc->t_list_item);
+	rds_tcp_tc_count--;
+	spin_unlock(&rds_tcp_tc_list_lock);
+
+	tc->t_sock = NULL;
+
+	sock->sk->sk_write_space = tc->t_orig_write_space;
+	sock->sk->sk_data_ready = tc->t_orig_data_ready;
+	sock->sk->sk_state_change = tc->t_orig_state_change;
+	sock->sk->sk_user_data = NULL;
+
+	write_unlock_bh(&sock->sk->sk_callback_lock);
+}
+
+/*
+ * This is the only path that sets tc->t_sock.  Send and receive trust that
+ * it is set.  The RDS_CONN_CONNECTED bit protects those paths from being
+ * called while it isn't set.
+ */
+void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn)
+{
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+
+	rdsdebug("setting sock %p callbacks to tc %p\n", sock, tc);
+	write_lock_bh(&sock->sk->sk_callback_lock);
+
+	/* done under the callback_lock to serialize with write_space */
+	spin_lock(&rds_tcp_tc_list_lock);
+	list_add_tail(&tc->t_list_item, &rds_tcp_tc_list);
+	rds_tcp_tc_count++;
+	spin_unlock(&rds_tcp_tc_list_lock);
+
+	/* accepted sockets need our listen data ready undone */
+	if (sock->sk->sk_data_ready == rds_tcp_listen_data_ready)
+		sock->sk->sk_data_ready = sock->sk->sk_user_data;
+
+	tc->t_sock = sock;
+	tc->conn = conn;
+	tc->t_orig_data_ready = sock->sk->sk_data_ready;
+	tc->t_orig_write_space = sock->sk->sk_write_space;
+	tc->t_orig_state_change = sock->sk->sk_state_change;
+
+	sock->sk->sk_user_data = conn;
+	sock->sk->sk_data_ready = rds_tcp_data_ready;
+	sock->sk->sk_write_space = rds_tcp_write_space;
+	sock->sk->sk_state_change = rds_tcp_state_change;
+
+	write_unlock_bh(&sock->sk->sk_callback_lock);
+}
+
+static void rds_tcp_tc_info(struct socket *sock, unsigned int len,
+			    struct rds_info_iterator *iter,
+			    struct rds_info_lengths *lens)
+{
+	struct rds_info_tcp_socket tsinfo;
+	struct rds_tcp_connection *tc;
+	unsigned long flags;
+	struct sockaddr_in sin;
+	int sinlen;
+
+	spin_lock_irqsave(&rds_tcp_tc_list_lock, flags);
+
+	if (len / sizeof(tsinfo) < rds_tcp_tc_count)
+		goto out;
+
+	list_for_each_entry(tc, &rds_tcp_tc_list, t_list_item) {
+
+		sock->ops->getname(sock, (struct sockaddr *)&sin, &sinlen, 0);
+		tsinfo.local_addr = sin.sin_addr.s_addr;
+		tsinfo.local_port = sin.sin_port;
+		sock->ops->getname(sock, (struct sockaddr *)&sin, &sinlen, 1);
+		tsinfo.peer_addr = sin.sin_addr.s_addr;
+		tsinfo.peer_port = sin.sin_port;
+
+		tsinfo.hdr_rem = tc->t_tinc_hdr_rem;
+		tsinfo.data_rem = tc->t_tinc_data_rem;
+		tsinfo.last_sent_nxt = tc->t_last_sent_nxt;
+		tsinfo.last_expected_una = tc->t_last_expected_una;
+		tsinfo.last_seen_una = tc->t_last_seen_una;
+
+		rds_info_copy(iter, &tsinfo, sizeof(tsinfo));
+	}
+
+out:
+	lens->nr = rds_tcp_tc_count;
+	lens->each = sizeof(tsinfo);
+
+	spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags);
+}
+
+static int rds_tcp_laddr_check(__be32 addr)
+{
+	if (inet_addr_type(&init_net, addr) == RTN_LOCAL)
+		return 0;
+	return -EADDRNOTAVAIL;
+}
+
+static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp)
+{
+	struct rds_tcp_connection *tc;
+
+	tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp);
+	if (tc == NULL)
+		return -ENOMEM;
+
+	tc->t_sock = NULL;
+	tc->t_tinc = NULL;
+	tc->t_tinc_hdr_rem = sizeof(struct rds_header);
+	tc->t_tinc_data_rem = 0;
+
+	conn->c_transport_data = tc;
+
+	spin_lock_irq(&rds_tcp_conn_lock);
+	list_add_tail(&tc->t_tcp_node, &rds_tcp_conn_list);
+	spin_unlock_irq(&rds_tcp_conn_lock);
+
+	rdsdebug("alloced tc %p\n", conn->c_transport_data);
+	return 0;
+}
+
+static void rds_tcp_conn_free(void *arg)
+{
+	struct rds_tcp_connection *tc = arg;
+	rdsdebug("freeing tc %p\n", tc);
+	kmem_cache_free(rds_tcp_conn_slab, tc);
+}
+
+static void rds_tcp_destroy_conns(void)
+{
+	struct rds_tcp_connection *tc, *_tc;
+	LIST_HEAD(tmp_list);
+
+	/* avoid calling conn_destroy with irqs off */
+	spin_lock_irq(&rds_tcp_conn_lock);
+	list_splice(&rds_tcp_conn_list, &tmp_list);
+	INIT_LIST_HEAD(&rds_tcp_conn_list);
+	spin_unlock_irq(&rds_tcp_conn_lock);
+
+	list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node) {
+		if (tc->conn->c_passive)
+			rds_conn_destroy(tc->conn->c_passive);
+		rds_conn_destroy(tc->conn);
+	}
+}
+
+void rds_tcp_exit(void)
+{
+	rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
+	rds_tcp_listen_stop();
+	rds_tcp_destroy_conns();
+	rds_trans_unregister(&rds_tcp_transport);
+	rds_tcp_recv_exit();
+	kmem_cache_destroy(rds_tcp_conn_slab);
+}
+module_exit(rds_tcp_exit);
+
+struct rds_transport rds_tcp_transport = {
+	.laddr_check		= rds_tcp_laddr_check,
+	.xmit_prepare		= rds_tcp_xmit_prepare,
+	.xmit_complete		= rds_tcp_xmit_complete,
+	.xmit_cong_map		= rds_tcp_xmit_cong_map,
+	.xmit			= rds_tcp_xmit,
+	.recv			= rds_tcp_recv,
+	.conn_alloc		= rds_tcp_conn_alloc,
+	.conn_free		= rds_tcp_conn_free,
+	.conn_connect		= rds_tcp_conn_connect,
+	.conn_shutdown		= rds_tcp_conn_shutdown,
+	.inc_copy_to_user	= rds_tcp_inc_copy_to_user,
+	.inc_purge		= rds_tcp_inc_purge,
+	.inc_free		= rds_tcp_inc_free,
+	.stats_info_copy	= rds_tcp_stats_info_copy,
+	.exit			= rds_tcp_exit,
+	.t_owner		= THIS_MODULE,
+	.t_name			= "tcp",
+	.t_type			= RDS_TRANS_TCP,
+	.t_prefer_loopback	= 1,
+};
+
+int __init rds_tcp_init(void)
+{
+	int ret;
+
+	rds_tcp_conn_slab = kmem_cache_create("rds_tcp_connection",
+					      sizeof(struct rds_tcp_connection),
+					      0, 0, NULL);
+	if (rds_tcp_conn_slab == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = rds_tcp_recv_init();
+	if (ret)
+		goto out_slab;
+
+	ret = rds_trans_register(&rds_tcp_transport);
+	if (ret)
+		goto out_recv;
+
+	ret = rds_tcp_listen_init();
+	if (ret)
+		goto out_register;
+
+	rds_info_register_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info);
+
+	goto out;
+
+out_register:
+	rds_trans_unregister(&rds_tcp_transport);
+out_recv:
+	rds_tcp_recv_exit();
+out_slab:
+	kmem_cache_destroy(rds_tcp_conn_slab);
+out:
+	return ret;
+}
+module_init(rds_tcp_init);
+
+MODULE_AUTHOR("Oracle Corporation <rds-devel@oss.oracle.com>");
+MODULE_DESCRIPTION("RDS: TCP transport");
+MODULE_LICENSE("Dual BSD/GPL");
+
diff --git a/net/rds/tcp.h b/net/rds/tcp.h
new file mode 100644
index 0000000..844fa6b
--- /dev/null
+++ b/net/rds/tcp.h
@@ -0,0 +1,93 @@
+#ifndef _RDS_TCP_H
+#define _RDS_TCP_H
+
+#define RDS_TCP_PORT	16385
+
+struct rds_tcp_incoming {
+	struct rds_incoming	ti_inc;
+	struct sk_buff_head	ti_skb_list;
+};
+
+struct rds_tcp_connection {
+
+	struct list_head	t_tcp_node;
+	struct rds_connection   *conn;
+	struct socket		*t_sock;
+	void			*t_orig_write_space;
+	void			*t_orig_data_ready;
+	void			*t_orig_state_change;
+
+	struct rds_tcp_incoming	*t_tinc;
+	size_t			t_tinc_hdr_rem;
+	size_t			t_tinc_data_rem;
+
+	/* XXX error report? */
+	struct work_struct	t_conn_w;
+	struct work_struct	t_send_w;
+	struct work_struct	t_down_w;
+	struct work_struct	t_recv_w;
+
+	/* for info exporting only */
+	struct list_head	t_list_item;
+	u32			t_last_sent_nxt;
+	u32			t_last_expected_una;
+	u32			t_last_seen_una;
+};
+
+struct rds_tcp_statistics {
+	uint64_t	s_tcp_data_ready_calls;
+	uint64_t	s_tcp_write_space_calls;
+	uint64_t	s_tcp_sndbuf_full;
+	uint64_t	s_tcp_connect_raced;
+	uint64_t	s_tcp_listen_closed_stale;
+};
+
+/* tcp.c */
+int __init rds_tcp_init(void);
+void rds_tcp_exit(void);
+void rds_tcp_tune(struct socket *sock);
+void rds_tcp_nonagle(struct socket *sock);
+void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn);
+void rds_tcp_restore_callbacks(struct socket *sock,
+			       struct rds_tcp_connection *tc);
+u32 rds_tcp_snd_nxt(struct rds_tcp_connection *tc);
+u32 rds_tcp_snd_una(struct rds_tcp_connection *tc);
+u64 rds_tcp_map_seq(struct rds_tcp_connection *tc, u32 seq);
+extern struct rds_transport rds_tcp_transport;
+
+/* tcp_connect.c */
+int rds_tcp_conn_connect(struct rds_connection *conn);
+void rds_tcp_conn_shutdown(struct rds_connection *conn);
+void rds_tcp_state_change(struct sock *sk);
+
+/* tcp_listen.c */
+int __init rds_tcp_listen_init(void);
+void rds_tcp_listen_stop(void);
+void rds_tcp_listen_data_ready(struct sock *sk, int bytes);
+
+/* tcp_recv.c */
+int __init rds_tcp_recv_init(void);
+void rds_tcp_recv_exit(void);
+void rds_tcp_data_ready(struct sock *sk, int bytes);
+int rds_tcp_recv(struct rds_connection *conn);
+void rds_tcp_inc_purge(struct rds_incoming *inc);
+void rds_tcp_inc_free(struct rds_incoming *inc);
+int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
+			     size_t size);
+
+/* tcp_send.c */
+void rds_tcp_xmit_prepare(struct rds_connection *conn);
+void rds_tcp_xmit_complete(struct rds_connection *conn);
+int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm,
+	         unsigned int hdr_off, unsigned int sg, unsigned int off);
+void rds_tcp_write_space(struct sock *sk);
+int rds_tcp_xmit_cong_map(struct rds_connection *conn,
+			  struct rds_cong_map *map, unsigned long offset);
+
+/* tcp_stats.c */
+DECLARE_PER_CPU(struct rds_tcp_statistics, rds_tcp_stats);
+#define rds_tcp_stats_inc(member) rds_stats_inc_which(rds_tcp_stats, member)
+unsigned int rds_tcp_stats_info_copy(struct rds_info_iterator *iter,
+				     unsigned int avail);
+
+#endif
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
new file mode 100644
index 0000000..211522f
--- /dev/null
+++ b/net/rds/tcp_connect.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2006 Oracle.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/in.h>
+#include <net/tcp.h>
+
+#include "rds.h"
+#include "tcp.h"
+
+void rds_tcp_state_change(struct sock *sk)
+{
+	void (*state_change)(struct sock *sk);
+	struct rds_connection *conn;
+	struct rds_tcp_connection *tc;
+
+	read_lock(&sk->sk_callback_lock);
+	conn = sk->sk_user_data;
+	if (conn == NULL) {
+		state_change = sk->sk_state_change;
+		goto out;
+	}
+	tc = conn->c_transport_data;
+	state_change = tc->t_orig_state_change;
+
+	rdsdebug("sock %p state_change to %d\n", tc->t_sock, sk->sk_state);
+
+	switch(sk->sk_state) {
+		/* ignore connecting sockets as they make progress */
+		case TCP_SYN_SENT:
+		case TCP_SYN_RECV:
+			break;
+		case TCP_ESTABLISHED:
+			rds_connect_complete(conn);
+			break;
+		case TCP_CLOSE:
+			rds_conn_drop(conn);
+		default:
+			break;
+	}
+out:
+	read_unlock(&sk->sk_callback_lock);
+	state_change(sk);
+}
+
+int rds_tcp_conn_connect(struct rds_connection *conn)
+{
+	struct socket *sock = NULL;
+	struct sockaddr_in src, dest;
+	int ret;
+
+	ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0)
+		goto out;
+
+	rds_tcp_tune(sock);
+
+	src.sin_family = AF_INET;
+	src.sin_addr.s_addr = (__force u32)conn->c_laddr;
+	src.sin_port = (__force u16)htons(0);
+
+	ret = sock->ops->bind(sock, (struct sockaddr *)&src, sizeof(src));
+	if (ret) {
+		rdsdebug("bind failed with %d at address %u.%u.%u.%u\n",
+		     ret, NIPQUAD(conn->c_laddr));
+		goto out;
+	}
+
+	dest.sin_family = AF_INET;
+	dest.sin_addr.s_addr = (__force u32)conn->c_faddr;
+	dest.sin_port = (__force u16)htons(RDS_TCP_PORT);
+
+	/*
+	 * once we call connect() we can start getting callbacks and they
+	 * own the socket
+	 */
+	rds_tcp_set_callbacks(sock, conn);
+	ret = sock->ops->connect(sock, (struct sockaddr *)&dest, sizeof(dest),
+				 O_NONBLOCK);
+	sock = NULL;
+
+	rdsdebug("connect to address %u.%u.%u.%u returned %d\n",
+		 NIPQUAD(conn->c_faddr), ret);
+	if (ret == -EINPROGRESS)
+		ret = 0;
+
+out:
+	if (sock)
+		sock_release(sock);
+	return ret;
+}
+
+/*
+ * Before killing the tcp socket this needs to serialize with callbacks.  The
+ * caller has already grabbed the sending sem so we're serialized with other
+ * senders.
+ *
+ * TCP calls the callbacks with the sock lock so we hold it while we reset the
+ * callbacks to those set by TCP.  Our callbacks won't execute again once we
+ * hold the sock lock.
+ */
+void rds_tcp_conn_shutdown(struct rds_connection *conn)
+{
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+	struct socket *sock = tc->t_sock;
+
+	rdsdebug("shutting down conn %p tc %p sock %p\n", conn, tc, sock);
+
+	if (sock) {
+		sock->ops->shutdown(sock, RCV_SHUTDOWN | SEND_SHUTDOWN);
+		lock_sock(sock->sk);
+		rds_tcp_restore_callbacks(sock, tc); /* tc->tc_sock = NULL */
+
+		release_sock(sock->sk);
+		sock_release(sock);
+	};
+
+	if (tc->t_tinc) {
+		rds_inc_put(&tc->t_tinc->ti_inc);
+		tc->t_tinc = NULL;
+	}
+	tc->t_tinc_hdr_rem = sizeof(struct rds_header);
+	tc->t_tinc_data_rem = 0;
+}
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
new file mode 100644
index 0000000..24b743e
--- /dev/null
+++ b/net/rds/tcp_listen.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2006 Oracle.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/in.h>
+#include <net/tcp.h>
+
+#include "rds.h"
+#include "tcp.h"
+
+/*
+ * cheesy, but simple..
+ */
+static void rds_tcp_accept_worker(struct work_struct *work);
+static DECLARE_WORK(rds_tcp_listen_work, rds_tcp_accept_worker);
+static struct socket *rds_tcp_listen_sock;
+
+static int rds_tcp_accept_one(struct socket *sock)
+{
+	struct socket *new_sock = NULL;
+	struct rds_connection *conn;
+	int ret;
+	struct inet_sock *inet;
+
+	ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type,
+			       sock->sk->sk_protocol, &new_sock);
+	if (ret)
+		goto out;
+
+	new_sock->type = sock->type;
+	new_sock->ops = sock->ops;
+	ret = sock->ops->accept(sock, new_sock, O_NONBLOCK);
+	if (ret < 0)
+		goto out;
+
+	rds_tcp_tune(new_sock);
+
+	inet = inet_sk(new_sock->sk);
+
+	rdsdebug("accepted tcp %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n",
+		  NIPQUAD(inet->saddr), ntohs(inet->sport),
+		  NIPQUAD(inet->daddr), ntohs(inet->dport));
+
+	conn = rds_conn_create(inet->saddr, inet->daddr, &rds_tcp_transport,
+			       GFP_KERNEL);
+	if (IS_ERR(conn)) {
+		ret = PTR_ERR(conn);
+		goto out;
+	}
+
+	/*
+	 * see the comment above rds_queue_delayed_reconnect()
+	 */
+	if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_CONNECTING)) {
+		if (rds_conn_state(conn) == RDS_CONN_UP)
+			rds_tcp_stats_inc(s_tcp_listen_closed_stale);
+		else
+			rds_tcp_stats_inc(s_tcp_connect_raced);
+		rds_conn_drop(conn);
+		ret = 0;
+		goto out;
+	}
+
+	rds_tcp_set_callbacks(new_sock, conn);
+	rds_connect_complete(conn);
+	new_sock = NULL;
+	ret = 0;
+
+out:
+	if (new_sock)
+		sock_release(new_sock);
+	return ret;
+}
+
+static void rds_tcp_accept_worker(struct work_struct *work)
+{
+	while (rds_tcp_accept_one(rds_tcp_listen_sock) == 0)
+		cond_resched();
+}
+
+void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
+{
+	void (*ready)(struct sock *sk, int bytes);
+
+	rdsdebug("listen data ready sk %p\n", sk);
+
+	read_lock(&sk->sk_callback_lock);
+	ready = sk->sk_user_data;
+	if (ready == NULL) { /* check for teardown race */
+		ready = sk->sk_data_ready;
+		goto out;
+	}
+
+	/*
+	 * ->sk_data_ready is also called for a newly established child socket
+	 * before it has been accepted and the accepter has set up their
+	 * data_ready.. we only want to queue listen work for our listening
+	 * socket
+	 */
+	if (sk->sk_state == TCP_LISTEN)
+		queue_work(rds_wq, &rds_tcp_listen_work);
+
+out:
+	read_unlock(&sk->sk_callback_lock);
+	ready(sk, bytes);
+}
+
+int __init rds_tcp_listen_init(void)
+{
+	struct sockaddr_in sin;
+	struct socket *sock = NULL;
+	int ret;
+
+	ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0)
+		goto out;
+
+	sock->sk->sk_reuse = 1;
+	rds_tcp_nonagle(sock);
+
+	write_lock_bh(&sock->sk->sk_callback_lock);
+	sock->sk->sk_user_data = sock->sk->sk_data_ready;
+	sock->sk->sk_data_ready = rds_tcp_listen_data_ready;
+	write_unlock_bh(&sock->sk->sk_callback_lock);
+
+	sin.sin_family = PF_INET,
+	sin.sin_addr.s_addr = (__force u32)htonl(INADDR_ANY);
+	sin.sin_port = (__force u16)htons(RDS_TCP_PORT);
+
+	ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
+	if (ret < 0)
+		goto out;
+
+	ret = sock->ops->listen(sock, 64);
+	if (ret < 0)
+		goto out;
+
+	rds_tcp_listen_sock = sock;
+	sock = NULL;
+out:
+	if (sock)
+		sock_release(sock);
+	return ret;
+}
+
+void rds_tcp_listen_stop(void)
+{
+	struct socket *sock = rds_tcp_listen_sock;
+	struct sock *sk;
+
+	if (sock == NULL)
+		return;
+
+	sk = sock->sk;
+
+	/* serialize with and prevent further callbacks */
+	lock_sock(sk);
+	write_lock_bh(&sk->sk_callback_lock);
+	if (sk->sk_user_data) {
+		sk->sk_data_ready = sk->sk_user_data;
+		sk->sk_user_data = NULL;
+	}
+	write_unlock_bh(&sk->sk_callback_lock);
+	release_sock(sk);
+
+	/* wait for accepts to stop and close the socket */
+	flush_workqueue(rds_wq);
+	sock_release(sock);
+	rds_tcp_listen_sock = NULL;
+}
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
new file mode 100644
index 0000000..c00daff
--- /dev/null
+++ b/net/rds/tcp_recv.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2006 Oracle.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include <linux/kernel.h>
+#include <net/tcp.h>
+
+#include "rds.h"
+#include "tcp.h"
+
+static struct kmem_cache *rds_tcp_incoming_slab;
+
+void rds_tcp_inc_purge(struct rds_incoming *inc)
+{
+	struct rds_tcp_incoming *tinc;
+	tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
+	rdsdebug("purging tinc %p inc %p\n", tinc, inc);
+	skb_queue_purge(&tinc->ti_skb_list);
+}
+
+void rds_tcp_inc_free(struct rds_incoming *inc)
+{
+	struct rds_tcp_incoming *tinc;
+	tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
+	rds_tcp_inc_purge(inc);
+	rdsdebug("freeing tinc %p inc %p\n", tinc, inc);
+	kmem_cache_free(rds_tcp_incoming_slab, tinc);
+}
+
+/*
+ * this is pretty lame, but, whatever.
+ */
+int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
+			     size_t size)
+{
+	struct rds_tcp_incoming *tinc;
+	struct iovec *iov, tmp;
+	struct sk_buff *skb;
+	unsigned long to_copy, skb_off;
+	int ret = 0;
+
+	if (size == 0)
+		goto out;
+
+	tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
+	iov = first_iov;
+	tmp = *iov;
+
+	skb_queue_walk(&tinc->ti_skb_list, skb) {
+		skb_off = 0;
+		while (skb_off < skb->len) {
+			while (tmp.iov_len == 0) {
+				iov++;
+				tmp = *iov;
+			}
+
+			to_copy = min(tmp.iov_len, size);
+			to_copy = min(to_copy, skb->len - skb_off);
+
+			rdsdebug("ret %d size %zu skb %p skb_off %lu "
+				 "skblen %d iov_base %p iov_len %zu cpy %lu\n",
+				 ret, size, skb, skb_off, skb->len,
+				 tmp.iov_base, tmp.iov_len, to_copy);
+
+			/* modifies tmp as it copies */
+			if (skb_copy_datagram_iovec(skb, skb_off, &tmp,
+						    to_copy)) {
+				ret = -EFAULT;
+				goto out;
+			}
+
+			size -= to_copy;
+			ret += to_copy;
+			skb_off += to_copy;
+			if (size == 0)
+				goto out;
+		}
+	}
+out:
+	return ret;
+}
+
+/*
+ * We have a series of skbs that have fragmented pieces of the congestion
+ * bitmap.  They must add up to the exact size of the congestion bitmap.  We
+ * use the skb helpers to copy those into the pages that make up the in-memory
+ * congestion bitmap for the remote address of this connection.  We then tell
+ * the congestion core that the bitmap has been changed so that it can wake up
+ * sleepers.
+ *
+ * This is racing with sending paths which are using test_bit to see if the
+ * bitmap indicates that their recipient is congested.
+ */
+
+static void rds_tcp_cong_recv(struct rds_connection *conn,
+			      struct rds_tcp_incoming *tinc)
+{
+	struct sk_buff *skb;
+	unsigned int to_copy, skb_off;
+	unsigned int map_off;
+	unsigned int map_page;
+	struct rds_cong_map *map;
+	int ret;
+
+	/* catch completely corrupt packets */
+	if (be32_to_cpu(tinc->ti_inc.i_hdr.h_len) != RDS_CONG_MAP_BYTES)
+		return;
+
+	map_page = 0;
+	map_off = 0;
+	map = conn->c_fcong;
+
+	skb_queue_walk(&tinc->ti_skb_list, skb) {
+		skb_off = 0;
+		while (skb_off < skb->len) {
+			to_copy = min_t(unsigned int, PAGE_SIZE - map_off,
+					skb->len - skb_off);
+
+			BUG_ON(map_page >= RDS_CONG_MAP_PAGES);
+
+			/* only returns 0 or -error */
+			ret = skb_copy_bits(skb, skb_off,
+				(void *)map->m_page_addrs[map_page] + map_off,
+				to_copy);
+			BUG_ON(ret != 0);
+
+			skb_off += to_copy;
+			map_off += to_copy;
+			if (map_off == PAGE_SIZE) {
+				map_off = 0;
+				map_page++;
+			}
+		}
+	}
+
+	rds_cong_map_updated(map, ~(u64) 0);
+}
+
+struct rds_tcp_desc_arg {
+	struct rds_connection *conn;
+	gfp_t gfp;
+	enum km_type km;
+};
+
+static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb,
+			     unsigned int offset, size_t len)
+{
+	struct rds_tcp_desc_arg *arg = desc->arg.data;
+	struct rds_connection *conn = arg->conn;
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+	struct rds_tcp_incoming *tinc = tc->t_tinc;
+	struct sk_buff *clone;
+	size_t left = len, to_copy;
+
+	rdsdebug("tcp data tc %p skb %p offset %u len %zu\n", tc, skb, offset,
+		 len);
+
+	/*
+	 * tcp_read_sock() interprets partial progress as an indication to stop
+	 * processing.
+	 */
+	while (left) {
+		if (tinc == NULL) {
+			tinc = kmem_cache_alloc(rds_tcp_incoming_slab,
+					        arg->gfp);
+			if (tinc == NULL) {
+				desc->error = -ENOMEM;
+				goto out;
+			}
+			tc->t_tinc = tinc;
+			rdsdebug("alloced tinc %p\n", tinc);
+			rds_inc_init(&tinc->ti_inc, conn, conn->c_faddr);
+			/*
+			 * XXX * we might be able to use the __ variants when
+			 * we've already serialized at a higher level.
+			 */
+			skb_queue_head_init(&tinc->ti_skb_list);
+		}
+
+		if (left && tc->t_tinc_hdr_rem) {
+			to_copy = min(tc->t_tinc_hdr_rem, left);
+			rdsdebug("copying %zu header from skb %p\n", to_copy,
+				 skb);
+			skb_copy_bits(skb, offset,
+				      (char *)&tinc->ti_inc.i_hdr +
+						sizeof(struct rds_header) -
+						tc->t_tinc_hdr_rem,
+				      to_copy);
+			tc->t_tinc_hdr_rem -= to_copy;
+			left -= to_copy;
+			offset += to_copy;
+
+			if (tc->t_tinc_hdr_rem == 0) {
+				/* could be 0 for a 0 len message */
+				tc->t_tinc_data_rem =
+					be32_to_cpu(tinc->ti_inc.i_hdr.h_len);
+			}
+		}
+
+		if (left && tc->t_tinc_data_rem) {
+			clone = skb_clone(skb, arg->gfp);
+			if (clone == NULL) {
+				desc->error = -ENOMEM;
+				goto out;
+			}
+
+			to_copy = min(tc->t_tinc_data_rem, left);
+			pskb_pull(clone, offset);
+			pskb_trim(clone, to_copy);
+			skb_queue_tail(&tinc->ti_skb_list, clone);
+
+			rdsdebug("skb %p data %p len %d off %u to_copy %zu -> "
+				 "clone %p data %p len %d\n",
+				 skb, skb->data, skb->len, offset, to_copy,
+				 clone, clone->data, clone->len);
+
+			tc->t_tinc_data_rem -= to_copy;
+			left -= to_copy;
+			offset += to_copy;
+		}
+
+		if (tc->t_tinc_hdr_rem == 0 && tc->t_tinc_data_rem == 0) {
+			if (tinc->ti_inc.i_hdr.h_flags == RDS_FLAG_CONG_BITMAP)
+				rds_tcp_cong_recv(conn, tinc);
+			else
+				rds_recv_incoming(conn, conn->c_faddr,
+						  conn->c_laddr, &tinc->ti_inc,
+						  arg->gfp, arg->km);
+
+			tc->t_tinc_hdr_rem = sizeof(struct rds_header);
+			tc->t_tinc_data_rem = 0;
+			tc->t_tinc = NULL;
+			rds_inc_put(&tinc->ti_inc);
+			tinc = NULL;
+		}
+	}
+out:
+	rdsdebug("returning len %zu left %zu skb len %d rx queue depth %d\n",
+		 len, left, skb->len,
+		 skb_queue_len(&tc->t_sock->sk->sk_receive_queue));
+	return len - left;
+}
+
+/* the caller has to hold the sock lock */
+int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp, enum km_type km)
+{
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+	struct socket *sock = tc->t_sock;
+	read_descriptor_t desc;
+	struct rds_tcp_desc_arg arg;
+
+	/* It's like glib in the kernel! */
+	arg.conn = conn;
+	arg.gfp = gfp;
+	arg.km = km;
+	desc.arg.data = &arg;
+	desc.error = 0;
+	desc.count = 1; /* give more than one skb per call */
+
+	tcp_read_sock(sock->sk, &desc, rds_tcp_data_recv);
+	rdsdebug("tcp_read_sock for tc %p gfp 0x%x returned %d\n", tc, gfp,
+		 desc.error);
+
+	return desc.error;
+}
+
+/*
+ * We hold the sock lock to serialize our rds_tcp_recv->tcp_read_sock from
+ * data_ready.
+ *
+ * if we fail to allocate we're in trouble.. blindly wait some time before
+ * trying again to see if the VM can free up something for us.
+ */
+int rds_tcp_recv(struct rds_connection *conn)
+{
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+	struct socket *sock = tc->t_sock;
+	int ret = 0;
+
+	rdsdebug("recv worker conn %p tc %p sock %p\n", conn, tc, sock);
+
+	lock_sock(sock->sk);
+	ret = rds_tcp_read_sock(conn, GFP_KERNEL, KM_USER0);
+	release_sock(sock->sk);
+
+	return ret;
+}
+
+void rds_tcp_data_ready(struct sock *sk, int bytes)
+{
+	void (*ready)(struct sock *sk, int bytes);
+	struct rds_connection *conn;
+	struct rds_tcp_connection *tc;
+
+	rdsdebug("data ready sk %p bytes %d\n", sk, bytes);
+
+	read_lock(&sk->sk_callback_lock);
+	conn = sk->sk_user_data;
+	if (conn == NULL) { /* check for teardown race */
+		ready = sk->sk_data_ready;
+		goto out;
+	}
+
+	tc = conn->c_transport_data;
+	ready = tc->t_orig_data_ready;
+	rds_tcp_stats_inc(s_tcp_data_ready_calls);
+
+	if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM)
+		queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
+out:
+	read_unlock(&sk->sk_callback_lock);
+	ready(sk, bytes);
+}
+
+int __init rds_tcp_recv_init(void)
+{
+	rds_tcp_incoming_slab = kmem_cache_create("rds_tcp_incoming",
+					sizeof(struct rds_tcp_incoming),
+					0, 0, NULL);
+	if (rds_tcp_incoming_slab == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+void rds_tcp_recv_exit(void)
+{
+	kmem_cache_destroy(rds_tcp_incoming_slab);
+}
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c
new file mode 100644
index 0000000..ab545e0
--- /dev/null
+++ b/net/rds/tcp_send.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2006 Oracle.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/in.h>
+#include <net/tcp.h>
+
+#include "rds.h"
+#include "tcp.h"
+
+static void rds_tcp_cork(struct socket *sock, int val)
+{
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+	sock->ops->setsockopt(sock, SOL_TCP, TCP_CORK, (char __user *)&val,
+			      sizeof(val));
+	set_fs(oldfs);
+}
+
+void rds_tcp_xmit_prepare(struct rds_connection *conn)
+{
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+
+	rds_tcp_cork(tc->t_sock, 1);
+}
+
+void rds_tcp_xmit_complete(struct rds_connection *conn)
+{
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+
+	rds_tcp_cork(tc->t_sock, 0);
+}
+
+/* the core send_sem serializes this with other xmit and shutdown */
+int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len)
+{
+	struct kvec vec = {
+                .iov_base = data,
+                .iov_len = len,
+	};
+        struct msghdr msg = {
+                .msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL,
+        };
+
+	return kernel_sendmsg(sock, &msg, &vec, 1, vec.iov_len);
+}
+
+/* the core send_sem serializes this with other xmit and shutdown */
+int rds_tcp_xmit_cong_map(struct rds_connection *conn,
+			  struct rds_cong_map *map, unsigned long offset)
+{
+	static struct rds_header rds_tcp_map_header = {
+		.h_flags = RDS_FLAG_CONG_BITMAP,
+	};
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+	unsigned long i;
+	int ret;
+	int copied = 0;
+
+	/* Some problem claims cpu_to_be32(constant) isn't a constant. */
+	rds_tcp_map_header.h_len = cpu_to_be32(RDS_CONG_MAP_BYTES);
+
+	if (offset < sizeof(struct rds_header)) {
+		ret = rds_tcp_sendmsg(tc->t_sock,
+				      (void *)&rds_tcp_map_header + offset,
+				      sizeof(struct rds_header) - offset);
+		if (ret <= 0)
+			return ret;
+		offset += ret;
+		copied = ret;
+		if (offset < sizeof(struct rds_header))
+			return ret;
+	}
+
+	offset -= sizeof(struct rds_header);
+	i = offset / PAGE_SIZE;
+	offset = offset % PAGE_SIZE;
+	BUG_ON(i >= RDS_CONG_MAP_PAGES);
+
+	do {
+		ret = tc->t_sock->ops->sendpage(tc->t_sock,
+					virt_to_page(map->m_page_addrs[i]),
+					offset, PAGE_SIZE - offset,
+					MSG_DONTWAIT);
+		if (ret <= 0)
+			break;
+		copied += ret;
+		offset += ret;
+		if (offset == PAGE_SIZE) {
+			offset = 0;
+			i++;
+		}
+	} while (i < RDS_CONG_MAP_PAGES);
+
+        return copied ? copied : ret;
+}
+
+/* the core send_sem serializes this with other xmit and shutdown */
+int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm,
+	         unsigned int hdr_off, unsigned int sg, unsigned int off)
+{
+	struct rds_tcp_connection *tc = conn->c_transport_data;
+	int done = 0;
+	int ret = 0;
+
+	if (hdr_off == 0) {
+		/*
+		 * m_ack_seq is set to the sequence number of the last byte of
+		 * header and data.  see rds_tcp_is_acked().
+		 */
+		tc->t_last_sent_nxt = rds_tcp_snd_nxt(tc);
+		rm->m_ack_seq = tc->t_last_sent_nxt +
+				sizeof(struct rds_header) +
+				be32_to_cpu(rm->m_inc.i_hdr.h_len) - 1;
+		smp_mb__before_clear_bit();
+		set_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags);
+		tc->t_last_expected_una = rm->m_ack_seq + 1;
+
+		rdsdebug("rm %p tcp nxt %u ack_seq %llu\n",
+			 rm, rds_tcp_snd_nxt(tc),
+			 (unsigned long long)rm->m_ack_seq);
+	}
+
+	if (hdr_off < sizeof(struct rds_header)) {
+		/* see rds_tcp_write_space() */
+		set_bit(SOCK_NOSPACE, &tc->t_sock->sk->sk_socket->flags);
+
+		ret = rds_tcp_sendmsg(tc->t_sock,
+				      (void *)&rm->m_inc.i_hdr + hdr_off,
+				      sizeof(rm->m_inc.i_hdr) - hdr_off);
+		if (ret < 0)
+			goto out;
+		done += ret;
+		if (hdr_off + done != sizeof(struct rds_header))
+			goto out;
+	}
+
+	while (sg < rm->m_nents) {
+		ret = tc->t_sock->ops->sendpage(tc->t_sock,
+						sg_page(&rm->m_sg[sg]),
+						rm->m_sg[sg].offset + off,
+						rm->m_sg[sg].length - off,
+						MSG_DONTWAIT|MSG_NOSIGNAL);
+		rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->m_sg[sg]),
+			 rm->m_sg[sg].offset + off, rm->m_sg[sg].length - off,
+			 ret);
+		if (ret <= 0)
+			break;
+
+		off += ret;
+		done += ret;
+		if (off == rm->m_sg[sg].length) {
+			off = 0;
+			sg++;
+		}
+	}
+
+out:
+	if (ret <= 0) {
+		/* write_space will hit after EAGAIN, all else fatal */
+		if (ret == -EAGAIN) {
+			rds_tcp_stats_inc(s_tcp_sndbuf_full);
+			ret = 0;
+		} else {
+			printk(KERN_WARNING "RDS/tcp: send to %u.%u.%u.%u "
+			       "returned %d, disconnecting and reconnecting\n",
+			       NIPQUAD(conn->c_faddr), ret);
+			rds_conn_drop(conn);
+		}
+	}
+	if (done == 0)
+		done = ret;
+	return done;
+}
+
+/*
+ * rm->m_ack_seq is set to the tcp sequence number that corresponds to the
+ * last byte of the message, including the header.  This means that the
+ * entire message has been received if rm->m_ack_seq is "before" the next
+ * unacked byte of the TCP sequence space.  We have to do very careful
+ * wrapping 32bit comparisons here.
+ */
+static int rds_tcp_is_acked(struct rds_message *rm, uint64_t ack)
+{
+	if (!test_bit(RDS_MSG_HAS_ACK_SEQ, &rm->m_flags))
+		return 0;
+	return (__s32)((u32)rm->m_ack_seq - (u32)ack) < 0;
+}
+
+void rds_tcp_write_space(struct sock *sk)
+{
+	void (*write_space)(struct sock *sk);
+	struct rds_connection *conn;
+	struct rds_tcp_connection *tc;
+
+	read_lock(&sk->sk_callback_lock);
+	conn = sk->sk_user_data;
+	if (conn == NULL) {
+		write_space = sk->sk_write_space;
+		goto out;
+	}
+
+	tc = conn->c_transport_data;
+	rdsdebug("write_space for tc %p\n", tc);
+	write_space = tc->t_orig_write_space;
+	rds_tcp_stats_inc(s_tcp_write_space_calls);
+
+	rdsdebug("tcp una %u\n", rds_tcp_snd_una(tc));
+	tc->t_last_seen_una = rds_tcp_snd_una(tc);
+	rds_send_drop_acked(conn, rds_tcp_snd_una(tc), rds_tcp_is_acked);
+
+	queue_delayed_work(rds_wq, &conn->c_send_w, 0);
+out:
+	read_unlock(&sk->sk_callback_lock);
+
+	/*
+	 * write_space is only called when data leaves tcp's send queue if
+	 * SOCK_NOSPACE is set.  We set SOCK_NOSPACE every time we put
+	 * data in tcp's send queue because we use write_space to parse the
+	 * sequence numbers and notice that rds messages have been fully
+	 * received.
+	 *
+	 * tcp's write_space clears SOCK_NOSPACE if the send queue has more
+	 * than a certain amount of space. So we need to set it again *after*
+	 * we call tcp's write_space or else we might only get called on the
+	 * first of a series of incoming tcp acks.
+	 */
+	write_space(sk);
+
+	if (sk->sk_socket)
+		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+}
diff --git a/net/rds/tcp_stats.c b/net/rds/tcp_stats.c
new file mode 100644
index 0000000..d5898d0
--- /dev/null
+++ b/net/rds/tcp_stats.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2006 Oracle.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include <linux/percpu.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+
+#include "rds.h"
+#include "tcp.h"
+
+DEFINE_PER_CPU(struct rds_tcp_statistics, rds_tcp_stats)
+	____cacheline_aligned;
+
+static const char const *rds_tcp_stat_names[] = {
+	"tcp_data_ready_calls",
+	"tcp_write_space_calls",
+	"tcp_sndbuf_full",
+	"tcp_connect_raced",
+	"tcp_listen_closed_stale",
+};
+
+unsigned int rds_tcp_stats_info_copy(struct rds_info_iterator *iter,
+				     unsigned int avail)
+{
+	struct rds_tcp_statistics stats = {0, };
+	uint64_t *src;
+	uint64_t *sum;
+	size_t i;
+	int cpu;
+
+	if (avail < ARRAY_SIZE(rds_tcp_stat_names))
+		goto out;
+
+	for_each_online_cpu(cpu) {
+		src = (uint64_t *)&(per_cpu(rds_tcp_stats, cpu));
+		sum = (uint64_t *)&stats;
+		for (i = 0; i < sizeof(stats) / sizeof(uint64_t); i++)
+			*(sum++) += *(src++);
+	}
+
+	rds_stats_info_copy(iter, (uint64_t *)&stats, rds_tcp_stat_names,
+			    ARRAY_SIZE(rds_tcp_stat_names));
+out:
+	return ARRAY_SIZE(rds_tcp_stat_names);
+}
diff --git a/net/rds/threads.c b/net/rds/threads.c
index 828a1bf..dd7e0ca 100644
--- a/net/rds/threads.c
+++ b/net/rds/threads.c
@@ -68,6 +68,7 @@
  *	(TCP, IB/RDMA) to provide the necessary synchronisation.
  */
 struct workqueue_struct *rds_wq;
+EXPORT_SYMBOL_GPL(rds_wq);
 
 void rds_connect_complete(struct rds_connection *conn)
 {
@@ -89,6 +90,7 @@ void rds_connect_complete(struct rds_connection *conn)
 	queue_delayed_work(rds_wq, &conn->c_send_w, 0);
 	queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
 }
+EXPORT_SYMBOL_GPL(rds_connect_complete);
 
 /*
  * This random exponential backoff is relied on to eventually resolve racing
diff --git a/net/rds/transport.c b/net/rds/transport.c
index 767da61..7e10679 100644
--- a/net/rds/transport.c
+++ b/net/rds/transport.c
@@ -37,7 +37,7 @@
 #include "rds.h"
 #include "loop.h"
 
-static LIST_HEAD(rds_transports);
+static struct rds_transport *transports[RDS_TRANS_COUNT];
 static DECLARE_RWSEM(rds_trans_sem);
 
 int rds_trans_register(struct rds_transport *trans)
@@ -46,36 +46,44 @@ int rds_trans_register(struct rds_transport *trans)
 
 	down_write(&rds_trans_sem);
 
-	list_add_tail(&trans->t_item, &rds_transports);
-	printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name);
+	if (transports[trans->t_type])
+		printk(KERN_ERR "RDS Transport type %d already registered\n",
+			trans->t_type);
+	else {
+		transports[trans->t_type] = trans;
+		printk(KERN_INFO "Registered RDS/%s transport\n", trans->t_name);
+	}
 
 	up_write(&rds_trans_sem);
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(rds_trans_register);
 
 void rds_trans_unregister(struct rds_transport *trans)
 {
 	down_write(&rds_trans_sem);
 
-	list_del_init(&trans->t_item);
+	transports[trans->t_type] = NULL;
 	printk(KERN_INFO "Unregistered RDS/%s transport\n", trans->t_name);
 
 	up_write(&rds_trans_sem);
 }
+EXPORT_SYMBOL_GPL(rds_trans_unregister);
 
 struct rds_transport *rds_trans_get_preferred(__be32 addr)
 {
-	struct rds_transport *trans;
 	struct rds_transport *ret = NULL;
+	int i;
 
 	if (IN_LOOPBACK(ntohl(addr)))
 		return &rds_loop_transport;
 
 	down_read(&rds_trans_sem);
-	list_for_each_entry(trans, &rds_transports, t_item) {
-		if (trans->laddr_check(addr) == 0) {
-			ret = trans;
+	for (i = 0; i < RDS_TRANS_COUNT; i++)
+	{
+		if (transports[i] && (transports[i]->laddr_check(addr) == 0)) {
+			ret = transports[i];
 			break;
 		}
 	}
@@ -97,12 +105,15 @@ unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter,
 	struct rds_transport *trans;
 	unsigned int total = 0;
 	unsigned int part;
+	int i;
 
 	rds_info_iter_unmap(iter);
 	down_read(&rds_trans_sem);
 
-	list_for_each_entry(trans, &rds_transports, t_item) {
-		if (trans->stats_info_copy == NULL)
+	for (i = 0; i < RDS_TRANS_COUNT; i++)
+	{
+		trans = transports[i];
+		if (!trans || !trans->stats_info_copy)
 			continue;
 
 		part = trans->stats_info_copy(iter, avail);
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 2fc4a17..dbeaf29 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -589,11 +589,13 @@ static const char *rfkill_get_type_str(enum rfkill_type type)
 		return "wimax";
 	case RFKILL_TYPE_WWAN:
 		return "wwan";
+	case RFKILL_TYPE_GPS:
+		return "gps";
 	default:
 		BUG();
 	}
 
-	BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1);
+	BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_GPS + 1);
 }
 
 static ssize_t rfkill_type_show(struct device *dev,
@@ -1091,10 +1093,16 @@ static ssize_t rfkill_fop_write(struct file *file, const char __user *buf,
 	struct rfkill_event ev;
 
 	/* we don't need the 'hard' variable but accept it */
-	if (count < sizeof(ev) - 1)
+	if (count < RFKILL_EVENT_SIZE_V1 - 1)
 		return -EINVAL;
 
-	if (copy_from_user(&ev, buf, sizeof(ev) - 1))
+	/*
+	 * Copy as much data as we can accept into our 'ev' buffer,
+	 * but tell userspace how much we've copied so it can determine
+	 * our API version even in a write() call, if it cares.
+	 */
+	count = min(count, sizeof(ev));
+	if (copy_from_user(&ev, buf, count))
 		return -EFAULT;
 
 	if (ev.op != RFKILL_OP_CHANGE && ev.op != RFKILL_OP_CHANGE_ALL)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index e5f478c..1e166c9 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -63,7 +63,7 @@ int sysctl_rose_window_size             = ROSE_DEFAULT_WINDOW_SIZE;
 static HLIST_HEAD(rose_list);
 static DEFINE_SPINLOCK(rose_list_lock);
 
-static struct proto_ops rose_proto_ops;
+static const struct proto_ops rose_proto_ops;
 
 ax25_address rose_callsign;
 
@@ -1515,7 +1515,7 @@ static struct net_proto_family rose_family_ops = {
 	.owner		=	THIS_MODULE,
 };
 
-static struct proto_ops rose_proto_ops = {
+static const struct proto_ops rose_proto_ops = {
 	.family		=	PF_ROSE,
 	.owner		=	THIS_MODULE,
 	.release	=	rose_release,
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index 389d6e0..424b893 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -131,7 +131,7 @@ static int rose_close(struct net_device *dev)
 	return 0;
 }
 
-static int rose_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t rose_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_device_stats *stats = &dev->stats;
 
@@ -141,7 +141,7 @@ static int rose_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	dev_kfree_skb(skb);
 	stats->tx_errors++;
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static const struct header_ops rose_header_ops = {
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c
index 3ac1672..b4a2209 100644
--- a/net/rxrpc/ar-ack.c
+++ b/net/rxrpc/ar-ack.c
@@ -20,7 +20,7 @@
 
 static unsigned rxrpc_ack_defer = 1;
 
-static const char *rxrpc_acks[] = {
+static const char *const rxrpc_acks[] = {
 	"---", "REQ", "DUP", "OOS", "WIN", "MEM", "PNG", "PNR", "DLY", "IDL",
 	"-?-"
 };
@@ -40,7 +40,7 @@ static const s8 rxrpc_ack_priority[] = {
 /*
  * propose an ACK be sent
  */
-void __rxrpc_propose_ACK(struct rxrpc_call *call, uint8_t ack_reason,
+void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
 			 __be32 serial, bool immediate)
 {
 	unsigned long expiry;
@@ -120,7 +120,7 @@ cancel_timer:
 /*
  * propose an ACK be sent, locking the call structure
  */
-void rxrpc_propose_ACK(struct rxrpc_call *call, uint8_t ack_reason,
+void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
 		       __be32 serial, bool immediate)
 {
 	s8 prior = rxrpc_ack_priority[ack_reason];
@@ -520,7 +520,7 @@ static void rxrpc_zap_tx_window(struct rxrpc_call *call)
 	struct rxrpc_skb_priv *sp;
 	struct sk_buff *skb;
 	unsigned long _skb, *acks_window;
-	uint8_t winsz = call->acks_winsz;
+	u8 winsz = call->acks_winsz;
 	int tail;
 
 	acks_window = call->acks_window;
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 3e7318c..7043b29 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -229,7 +229,7 @@ struct rxrpc_conn_bundle {
 	int			debug_id;	/* debug ID for printks */
 	unsigned short		num_conns;	/* number of connections in this bundle */
 	__be16			service_id;	/* service ID */
-	uint8_t			security_ix;	/* security type */
+	u8			security_ix;	/* security type */
 };
 
 /*
@@ -370,10 +370,10 @@ struct rxrpc_call {
 	u8			channel;	/* connection channel occupied by this call */
 
 	/* transmission-phase ACK management */
-	uint8_t			acks_head;	/* offset into window of first entry */
-	uint8_t			acks_tail;	/* offset into window of last entry */
-	uint8_t			acks_winsz;	/* size of un-ACK'd window */
-	uint8_t			acks_unacked;	/* lowest unacked packet in last ACK received */
+	u8			acks_head;	/* offset into window of first entry */
+	u8			acks_tail;	/* offset into window of last entry */
+	u8			acks_winsz;	/* size of un-ACK'd window */
+	u8			acks_unacked;	/* lowest unacked packet in last ACK received */
 	int			acks_latest;	/* serial number of latest ACK received */
 	rxrpc_seq_t		acks_hard;	/* highest definitively ACK'd msg seq */
 	unsigned long		*acks_window;	/* sent packet window
@@ -388,7 +388,7 @@ struct rxrpc_call {
 	rxrpc_seq_t		rx_first_oos;	/* first packet in rx_oos_queue (or 0) */
 	rxrpc_seq_t		ackr_win_top;	/* top of ACK window (rx_data_eaten is bottom) */
 	rxrpc_seq_net_t		ackr_prev_seq;	/* previous sequence number received */
-	uint8_t			ackr_reason;	/* reason to ACK */
+	u8			ackr_reason;	/* reason to ACK */
 	__be32			ackr_serial;	/* serial of packet being ACK'd */
 	atomic_t		ackr_not_idle;	/* number of packets in Rx queue */
 
@@ -402,22 +402,6 @@ struct rxrpc_call {
 };
 
 /*
- * RxRPC key for Kerberos (type-2 security)
- */
-struct rxkad_key {
-	u16	security_index;		/* RxRPC header security index */
-	u16	ticket_len;		/* length of ticket[] */
-	u32	expiry;			/* time at which expires */
-	u32	kvno;			/* key version number */
-	u8	session_key[8];		/* DES session key */
-	u8	ticket[0];		/* the encrypted ticket */
-};
-
-struct rxrpc_key_payload {
-	struct rxkad_key k;
-};
-
-/*
  * locally abort an RxRPC call
  */
 static inline void rxrpc_abort_call(struct rxrpc_call *call, u32 abort_code)
@@ -450,8 +434,8 @@ extern int rxrpc_reject_call(struct rxrpc_sock *);
 /*
  * ar-ack.c
  */
-extern void __rxrpc_propose_ACK(struct rxrpc_call *, uint8_t, __be32, bool);
-extern void rxrpc_propose_ACK(struct rxrpc_call *, uint8_t, __be32, bool);
+extern void __rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool);
+extern void rxrpc_propose_ACK(struct rxrpc_call *, u8, __be32, bool);
 extern void rxrpc_process_call(struct work_struct *);
 
 /*
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index ad8c7a7..74697b2 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -17,6 +17,7 @@
 #include <linux/skbuff.h>
 #include <linux/key-type.h>
 #include <linux/crypto.h>
+#include <linux/ctype.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <keys/rxrpc-type.h>
@@ -28,6 +29,7 @@ static int rxrpc_instantiate_s(struct key *, const void *, size_t);
 static void rxrpc_destroy(struct key *);
 static void rxrpc_destroy_s(struct key *);
 static void rxrpc_describe(const struct key *, struct seq_file *);
+static long rxrpc_read(const struct key *, char __user *, size_t);
 
 /*
  * rxrpc defined keys take an arbitrary string as the description and an
@@ -39,6 +41,7 @@ struct key_type key_type_rxrpc = {
 	.match		= user_match,
 	.destroy	= rxrpc_destroy,
 	.describe	= rxrpc_describe,
+	.read		= rxrpc_read,
 };
 EXPORT_SYMBOL(key_type_rxrpc);
 
@@ -55,6 +58,595 @@ struct key_type key_type_rxrpc_s = {
 };
 
 /*
+ * parse an RxKAD type XDR format token
+ * - the caller guarantees we have at least 4 words
+ */
+static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr,
+				       unsigned toklen)
+{
+	struct rxrpc_key_token *token, **pptoken;
+	size_t plen;
+	u32 tktlen;
+	int ret;
+
+	_enter(",{%x,%x,%x,%x},%u",
+	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
+	       toklen);
+
+	if (toklen <= 8 * 4)
+		return -EKEYREJECTED;
+	tktlen = ntohl(xdr[7]);
+	_debug("tktlen: %x", tktlen);
+	if (tktlen > AFSTOKEN_RK_TIX_MAX)
+		return -EKEYREJECTED;
+	if (8 * 4 + tktlen != toklen)
+		return -EKEYREJECTED;
+
+	plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
+	ret = key_payload_reserve(key, key->datalen + plen);
+	if (ret < 0)
+		return ret;
+
+	plen -= sizeof(*token);
+	token = kmalloc(sizeof(*token), GFP_KERNEL);
+	if (!token)
+		return -ENOMEM;
+
+	token->kad = kmalloc(plen, GFP_KERNEL);
+	if (!token->kad) {
+		kfree(token);
+		return -ENOMEM;
+	}
+
+	token->security_index	= RXRPC_SECURITY_RXKAD;
+	token->kad->ticket_len	= tktlen;
+	token->kad->vice_id	= ntohl(xdr[0]);
+	token->kad->kvno	= ntohl(xdr[1]);
+	token->kad->start	= ntohl(xdr[4]);
+	token->kad->expiry	= ntohl(xdr[5]);
+	token->kad->primary_flag = ntohl(xdr[6]);
+	memcpy(&token->kad->session_key, &xdr[2], 8);
+	memcpy(&token->kad->ticket, &xdr[8], tktlen);
+
+	_debug("SCIX: %u", token->security_index);
+	_debug("TLEN: %u", token->kad->ticket_len);
+	_debug("EXPY: %x", token->kad->expiry);
+	_debug("KVNO: %u", token->kad->kvno);
+	_debug("PRIM: %u", token->kad->primary_flag);
+	_debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
+	       token->kad->session_key[0], token->kad->session_key[1],
+	       token->kad->session_key[2], token->kad->session_key[3],
+	       token->kad->session_key[4], token->kad->session_key[5],
+	       token->kad->session_key[6], token->kad->session_key[7]);
+	if (token->kad->ticket_len >= 8)
+		_debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
+		       token->kad->ticket[0], token->kad->ticket[1],
+		       token->kad->ticket[2], token->kad->ticket[3],
+		       token->kad->ticket[4], token->kad->ticket[5],
+		       token->kad->ticket[6], token->kad->ticket[7]);
+
+	/* count the number of tokens attached */
+	key->type_data.x[0]++;
+
+	/* attach the data */
+	for (pptoken = (struct rxrpc_key_token **)&key->payload.data;
+	     *pptoken;
+	     pptoken = &(*pptoken)->next)
+		continue;
+	*pptoken = token;
+	if (token->kad->expiry < key->expiry)
+		key->expiry = token->kad->expiry;
+
+	_leave(" = 0");
+	return 0;
+}
+
+static void rxrpc_free_krb5_principal(struct krb5_principal *princ)
+{
+	int loop;
+
+	if (princ->name_parts) {
+		for (loop = princ->n_name_parts - 1; loop >= 0; loop--)
+			kfree(princ->name_parts[loop]);
+		kfree(princ->name_parts);
+	}
+	kfree(princ->realm);
+}
+
+static void rxrpc_free_krb5_tagged(struct krb5_tagged_data *td)
+{
+	kfree(td->data);
+}
+
+/*
+ * free up an RxK5 token
+ */
+static void rxrpc_rxk5_free(struct rxk5_key *rxk5)
+{
+	int loop;
+
+	rxrpc_free_krb5_principal(&rxk5->client);
+	rxrpc_free_krb5_principal(&rxk5->server);
+	rxrpc_free_krb5_tagged(&rxk5->session);
+
+	if (rxk5->addresses) {
+		for (loop = rxk5->n_addresses - 1; loop >= 0; loop--)
+			rxrpc_free_krb5_tagged(&rxk5->addresses[loop]);
+		kfree(rxk5->addresses);
+	}
+	if (rxk5->authdata) {
+		for (loop = rxk5->n_authdata - 1; loop >= 0; loop--)
+			rxrpc_free_krb5_tagged(&rxk5->authdata[loop]);
+		kfree(rxk5->authdata);
+	}
+
+	kfree(rxk5->ticket);
+	kfree(rxk5->ticket2);
+	kfree(rxk5);
+}
+
+/*
+ * extract a krb5 principal
+ */
+static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
+				       const __be32 **_xdr,
+				       unsigned *_toklen)
+{
+	const __be32 *xdr = *_xdr;
+	unsigned toklen = *_toklen, n_parts, loop, tmp;
+
+	/* there must be at least one name, and at least #names+1 length
+	 * words */
+	if (toklen <= 12)
+		return -EINVAL;
+
+	_enter(",{%x,%x,%x},%u",
+	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), toklen);
+
+	n_parts = ntohl(*xdr++);
+	toklen -= 4;
+	if (n_parts <= 0 || n_parts > AFSTOKEN_K5_COMPONENTS_MAX)
+		return -EINVAL;
+	princ->n_name_parts = n_parts;
+
+	if (toklen <= (n_parts + 1) * 4)
+		return -EINVAL;
+
+	princ->name_parts = kcalloc(sizeof(char *), n_parts, GFP_KERNEL);
+	if (!princ->name_parts)
+		return -ENOMEM;
+
+	for (loop = 0; loop < n_parts; loop++) {
+		if (toklen < 4)
+			return -EINVAL;
+		tmp = ntohl(*xdr++);
+		toklen -= 4;
+		if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX)
+			return -EINVAL;
+		if (tmp > toklen)
+			return -EINVAL;
+		princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL);
+		if (!princ->name_parts[loop])
+			return -ENOMEM;
+		memcpy(princ->name_parts[loop], xdr, tmp);
+		princ->name_parts[loop][tmp] = 0;
+		tmp = (tmp + 3) & ~3;
+		toklen -= tmp;
+		xdr += tmp >> 2;
+	}
+
+	if (toklen < 4)
+		return -EINVAL;
+	tmp = ntohl(*xdr++);
+	toklen -= 4;
+	if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX)
+		return -EINVAL;
+	if (tmp > toklen)
+		return -EINVAL;
+	princ->realm = kmalloc(tmp + 1, GFP_KERNEL);
+	if (!princ->realm)
+		return -ENOMEM;
+	memcpy(princ->realm, xdr, tmp);
+	princ->realm[tmp] = 0;
+	tmp = (tmp + 3) & ~3;
+	toklen -= tmp;
+	xdr += tmp >> 2;
+
+	_debug("%s/...@%s", princ->name_parts[0], princ->realm);
+
+	*_xdr = xdr;
+	*_toklen = toklen;
+	_leave(" = 0 [toklen=%u]", toklen);
+	return 0;
+}
+
+/*
+ * extract a piece of krb5 tagged data
+ */
+static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
+					 size_t max_data_size,
+					 const __be32 **_xdr,
+					 unsigned *_toklen)
+{
+	const __be32 *xdr = *_xdr;
+	unsigned toklen = *_toklen, len;
+
+	/* there must be at least one tag and one length word */
+	if (toklen <= 8)
+		return -EINVAL;
+
+	_enter(",%zu,{%x,%x},%u",
+	       max_data_size, ntohl(xdr[0]), ntohl(xdr[1]), toklen);
+
+	td->tag = ntohl(*xdr++);
+	len = ntohl(*xdr++);
+	toklen -= 8;
+	if (len > max_data_size)
+		return -EINVAL;
+	td->data_len = len;
+
+	if (len > 0) {
+		td->data = kmalloc(len, GFP_KERNEL);
+		if (!td->data)
+			return -ENOMEM;
+		memcpy(td->data, xdr, len);
+		len = (len + 3) & ~3;
+		toklen -= len;
+		xdr += len >> 2;
+	}
+
+	_debug("tag %x len %x", td->tag, td->data_len);
+
+	*_xdr = xdr;
+	*_toklen = toklen;
+	_leave(" = 0 [toklen=%u]", toklen);
+	return 0;
+}
+
+/*
+ * extract an array of tagged data
+ */
+static int rxrpc_krb5_decode_tagged_array(struct krb5_tagged_data **_td,
+					  u8 *_n_elem,
+					  u8 max_n_elem,
+					  size_t max_elem_size,
+					  const __be32 **_xdr,
+					  unsigned *_toklen)
+{
+	struct krb5_tagged_data *td;
+	const __be32 *xdr = *_xdr;
+	unsigned toklen = *_toklen, n_elem, loop;
+	int ret;
+
+	/* there must be at least one count */
+	if (toklen < 4)
+		return -EINVAL;
+
+	_enter(",,%u,%zu,{%x},%u",
+	       max_n_elem, max_elem_size, ntohl(xdr[0]), toklen);
+
+	n_elem = ntohl(*xdr++);
+	toklen -= 4;
+	if (n_elem < 0 || n_elem > max_n_elem)
+		return -EINVAL;
+	*_n_elem = n_elem;
+	if (n_elem > 0) {
+		if (toklen <= (n_elem + 1) * 4)
+			return -EINVAL;
+
+		_debug("n_elem %d", n_elem);
+
+		td = kcalloc(sizeof(struct krb5_tagged_data), n_elem,
+			     GFP_KERNEL);
+		if (!td)
+			return -ENOMEM;
+		*_td = td;
+
+		for (loop = 0; loop < n_elem; loop++) {
+			ret = rxrpc_krb5_decode_tagged_data(&td[loop],
+							    max_elem_size,
+							    &xdr, &toklen);
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	*_xdr = xdr;
+	*_toklen = toklen;
+	_leave(" = 0 [toklen=%u]", toklen);
+	return 0;
+}
+
+/*
+ * extract a krb5 ticket
+ */
+static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
+				    const __be32 **_xdr, unsigned *_toklen)
+{
+	const __be32 *xdr = *_xdr;
+	unsigned toklen = *_toklen, len;
+
+	/* there must be at least one length word */
+	if (toklen <= 4)
+		return -EINVAL;
+
+	_enter(",{%x},%u", ntohl(xdr[0]), toklen);
+
+	len = ntohl(*xdr++);
+	toklen -= 4;
+	if (len > AFSTOKEN_K5_TIX_MAX)
+		return -EINVAL;
+	*_tktlen = len;
+
+	_debug("ticket len %u", len);
+
+	if (len > 0) {
+		*_ticket = kmalloc(len, GFP_KERNEL);
+		if (!*_ticket)
+			return -ENOMEM;
+		memcpy(*_ticket, xdr, len);
+		len = (len + 3) & ~3;
+		toklen -= len;
+		xdr += len >> 2;
+	}
+
+	*_xdr = xdr;
+	*_toklen = toklen;
+	_leave(" = 0 [toklen=%u]", toklen);
+	return 0;
+}
+
+/*
+ * parse an RxK5 type XDR format token
+ * - the caller guarantees we have at least 4 words
+ */
+static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr,
+				      unsigned toklen)
+{
+	struct rxrpc_key_token *token, **pptoken;
+	struct rxk5_key *rxk5;
+	const __be32 *end_xdr = xdr + (toklen >> 2);
+	int ret;
+
+	_enter(",{%x,%x,%x,%x},%u",
+	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
+	       toklen);
+
+	/* reserve some payload space for this subkey - the length of the token
+	 * is a reasonable approximation */
+	ret = key_payload_reserve(key, key->datalen + toklen);
+	if (ret < 0)
+		return ret;
+
+	token = kzalloc(sizeof(*token), GFP_KERNEL);
+	if (!token)
+		return -ENOMEM;
+
+	rxk5 = kzalloc(sizeof(*rxk5), GFP_KERNEL);
+	if (!rxk5) {
+		kfree(token);
+		return -ENOMEM;
+	}
+
+	token->security_index = RXRPC_SECURITY_RXK5;
+	token->k5 = rxk5;
+
+	/* extract the principals */
+	ret = rxrpc_krb5_decode_principal(&rxk5->client, &xdr, &toklen);
+	if (ret < 0)
+		goto error;
+	ret = rxrpc_krb5_decode_principal(&rxk5->server, &xdr, &toklen);
+	if (ret < 0)
+		goto error;
+
+	/* extract the session key and the encoding type (the tag field ->
+	 * ENCTYPE_xxx) */
+	ret = rxrpc_krb5_decode_tagged_data(&rxk5->session, AFSTOKEN_DATA_MAX,
+					    &xdr, &toklen);
+	if (ret < 0)
+		goto error;
+
+	if (toklen < 4 * 8 + 2 * 4)
+		goto inval;
+	rxk5->authtime	= be64_to_cpup((const __be64 *) xdr);
+	xdr += 2;
+	rxk5->starttime	= be64_to_cpup((const __be64 *) xdr);
+	xdr += 2;
+	rxk5->endtime	= be64_to_cpup((const __be64 *) xdr);
+	xdr += 2;
+	rxk5->renew_till = be64_to_cpup((const __be64 *) xdr);
+	xdr += 2;
+	rxk5->is_skey = ntohl(*xdr++);
+	rxk5->flags = ntohl(*xdr++);
+	toklen -= 4 * 8 + 2 * 4;
+
+	_debug("times: a=%llx s=%llx e=%llx rt=%llx",
+	       rxk5->authtime, rxk5->starttime, rxk5->endtime,
+	       rxk5->renew_till);
+	_debug("is_skey=%x flags=%x", rxk5->is_skey, rxk5->flags);
+
+	/* extract the permitted client addresses */
+	ret = rxrpc_krb5_decode_tagged_array(&rxk5->addresses,
+					     &rxk5->n_addresses,
+					     AFSTOKEN_K5_ADDRESSES_MAX,
+					     AFSTOKEN_DATA_MAX,
+					     &xdr, &toklen);
+	if (ret < 0)
+		goto error;
+
+	ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
+
+	/* extract the tickets */
+	ret = rxrpc_krb5_decode_ticket(&rxk5->ticket, &rxk5->ticket_len,
+				       &xdr, &toklen);
+	if (ret < 0)
+		goto error;
+	ret = rxrpc_krb5_decode_ticket(&rxk5->ticket2, &rxk5->ticket2_len,
+				       &xdr, &toklen);
+	if (ret < 0)
+		goto error;
+
+	ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
+
+	/* extract the typed auth data */
+	ret = rxrpc_krb5_decode_tagged_array(&rxk5->authdata,
+					     &rxk5->n_authdata,
+					     AFSTOKEN_K5_AUTHDATA_MAX,
+					     AFSTOKEN_BDATALN_MAX,
+					     &xdr, &toklen);
+	if (ret < 0)
+		goto error;
+
+	ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
+
+	if (toklen != 0)
+		goto inval;
+
+	/* attach the payload to the key */
+	for (pptoken = (struct rxrpc_key_token **)&key->payload.data;
+	     *pptoken;
+	     pptoken = &(*pptoken)->next)
+		continue;
+	*pptoken = token;
+	if (token->kad->expiry < key->expiry)
+		key->expiry = token->kad->expiry;
+
+	_leave(" = 0");
+	return 0;
+
+inval:
+	ret = -EINVAL;
+error:
+	rxrpc_rxk5_free(rxk5);
+	kfree(token);
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
+ * attempt to parse the data as the XDR format
+ * - the caller guarantees we have more than 7 words
+ */
+static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen)
+{
+	const __be32 *xdr = data, *token;
+	const char *cp;
+	unsigned len, tmp, loop, ntoken, toklen, sec_ix;
+	int ret;
+
+	_enter(",{%x,%x,%x,%x},%zu",
+	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
+	       datalen);
+
+	if (datalen > AFSTOKEN_LENGTH_MAX)
+		goto not_xdr;
+
+	/* XDR is an array of __be32's */
+	if (datalen & 3)
+		goto not_xdr;
+
+	/* the flags should be 0 (the setpag bit must be handled by
+	 * userspace) */
+	if (ntohl(*xdr++) != 0)
+		goto not_xdr;
+	datalen -= 4;
+
+	/* check the cell name */
+	len = ntohl(*xdr++);
+	if (len < 1 || len > AFSTOKEN_CELL_MAX)
+		goto not_xdr;
+	datalen -= 4;
+	tmp = (len + 3) & ~3;
+	if (tmp > datalen)
+		goto not_xdr;
+
+	cp = (const char *) xdr;
+	for (loop = 0; loop < len; loop++)
+		if (!isprint(cp[loop]))
+			goto not_xdr;
+	if (len < tmp)
+		for (; loop < tmp; loop++)
+			if (cp[loop])
+				goto not_xdr;
+	_debug("cellname: [%u/%u] '%*.*s'",
+	       len, tmp, len, len, (const char *) xdr);
+	datalen -= tmp;
+	xdr += tmp >> 2;
+
+	/* get the token count */
+	if (datalen < 12)
+		goto not_xdr;
+	ntoken = ntohl(*xdr++);
+	datalen -= 4;
+	_debug("ntoken: %x", ntoken);
+	if (ntoken < 1 || ntoken > AFSTOKEN_MAX)
+		goto not_xdr;
+
+	/* check each token wrapper */
+	token = xdr;
+	loop = ntoken;
+	do {
+		if (datalen < 8)
+			goto not_xdr;
+		toklen = ntohl(*xdr++);
+		sec_ix = ntohl(*xdr);
+		datalen -= 4;
+		_debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
+		if (toklen < 20 || toklen > datalen)
+			goto not_xdr;
+		datalen -= (toklen + 3) & ~3;
+		xdr += (toklen + 3) >> 2;
+
+	} while (--loop > 0);
+
+	_debug("remainder: %zu", datalen);
+	if (datalen != 0)
+		goto not_xdr;
+
+	/* okay: we're going to assume it's valid XDR format
+	 * - we ignore the cellname, relying on the key to be correctly named
+	 */
+	do {
+		xdr = token;
+		toklen = ntohl(*xdr++);
+		token = xdr + ((toklen + 3) >> 2);
+		sec_ix = ntohl(*xdr++);
+		toklen -= 4;
+
+		_debug("TOKEN type=%u [%p-%p]", sec_ix, xdr, token);
+
+		switch (sec_ix) {
+		case RXRPC_SECURITY_RXKAD:
+			ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen);
+			if (ret != 0)
+				goto error;
+			break;
+
+		case RXRPC_SECURITY_RXK5:
+			ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen);
+			if (ret != 0)
+				goto error;
+			break;
+
+		default:
+			ret = -EPROTONOSUPPORT;
+			goto error;
+		}
+
+	} while (--ntoken > 0);
+
+	_leave(" = 0");
+	return 0;
+
+not_xdr:
+	_leave(" = -EPROTO");
+	return -EPROTO;
+error:
+	_leave(" = %d", ret);
+	return ret;
+}
+
+/*
  * instantiate an rxrpc defined key
  * data should be of the form:
  *	OFFSET	LEN	CONTENT
@@ -70,8 +662,8 @@ struct key_type key_type_rxrpc_s = {
  */
 static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
 {
-	const struct rxkad_key *tsec;
-	struct rxrpc_key_payload *upayload;
+	const struct rxrpc_key_data_v1 *v1;
+	struct rxrpc_key_token *token, **pp;
 	size_t plen;
 	u32 kver;
 	int ret;
@@ -82,6 +674,13 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
 	if (!data && datalen == 0)
 		return 0;
 
+	/* determine if the XDR payload format is being used */
+	if (datalen > 7 * 4) {
+		ret = rxrpc_instantiate_xdr(key, data, datalen);
+		if (ret != -EPROTO)
+			return ret;
+	}
+
 	/* get the key interface version number */
 	ret = -EINVAL;
 	if (datalen <= 4 || !data)
@@ -98,53 +697,67 @@ static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen)
 
 	/* deal with a version 1 key */
 	ret = -EINVAL;
-	if (datalen < sizeof(*tsec))
+	if (datalen < sizeof(*v1))
 		goto error;
 
-	tsec = data;
-	if (datalen != sizeof(*tsec) + tsec->ticket_len)
+	v1 = data;
+	if (datalen != sizeof(*v1) + v1->ticket_length)
 		goto error;
 
-	_debug("SCIX: %u", tsec->security_index);
-	_debug("TLEN: %u", tsec->ticket_len);
-	_debug("EXPY: %x", tsec->expiry);
-	_debug("KVNO: %u", tsec->kvno);
+	_debug("SCIX: %u", v1->security_index);
+	_debug("TLEN: %u", v1->ticket_length);
+	_debug("EXPY: %x", v1->expiry);
+	_debug("KVNO: %u", v1->kvno);
 	_debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
-	       tsec->session_key[0], tsec->session_key[1],
-	       tsec->session_key[2], tsec->session_key[3],
-	       tsec->session_key[4], tsec->session_key[5],
-	       tsec->session_key[6], tsec->session_key[7]);
-	if (tsec->ticket_len >= 8)
+	       v1->session_key[0], v1->session_key[1],
+	       v1->session_key[2], v1->session_key[3],
+	       v1->session_key[4], v1->session_key[5],
+	       v1->session_key[6], v1->session_key[7]);
+	if (v1->ticket_length >= 8)
 		_debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
-		       tsec->ticket[0], tsec->ticket[1],
-		       tsec->ticket[2], tsec->ticket[3],
-		       tsec->ticket[4], tsec->ticket[5],
-		       tsec->ticket[6], tsec->ticket[7]);
+		       v1->ticket[0], v1->ticket[1],
+		       v1->ticket[2], v1->ticket[3],
+		       v1->ticket[4], v1->ticket[5],
+		       v1->ticket[6], v1->ticket[7]);
 
 	ret = -EPROTONOSUPPORT;
-	if (tsec->security_index != 2)
+	if (v1->security_index != RXRPC_SECURITY_RXKAD)
 		goto error;
 
-	key->type_data.x[0] = tsec->security_index;
-
-	plen = sizeof(*upayload) + tsec->ticket_len;
-	ret = key_payload_reserve(key, plen);
+	plen = sizeof(*token->kad) + v1->ticket_length;
+	ret = key_payload_reserve(key, plen + sizeof(*token));
 	if (ret < 0)
 		goto error;
 
 	ret = -ENOMEM;
-	upayload = kmalloc(plen, GFP_KERNEL);
-	if (!upayload)
+	token = kmalloc(sizeof(*token), GFP_KERNEL);
+	if (!token)
 		goto error;
+	token->kad = kmalloc(plen, GFP_KERNEL);
+	if (!token->kad)
+		goto error_free;
+
+	token->security_index		= RXRPC_SECURITY_RXKAD;
+	token->kad->ticket_len		= v1->ticket_length;
+	token->kad->expiry		= v1->expiry;
+	token->kad->kvno		= v1->kvno;
+	memcpy(&token->kad->session_key, &v1->session_key, 8);
+	memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
 
 	/* attach the data */
-	memcpy(&upayload->k, tsec, sizeof(*tsec));
-	memcpy(&upayload->k.ticket, (void *)tsec + sizeof(*tsec),
-	       tsec->ticket_len);
-	key->payload.data = upayload;
-	key->expiry = tsec->expiry;
+	key->type_data.x[0]++;
+
+	pp = (struct rxrpc_key_token **)&key->payload.data;
+	while (*pp)
+		pp = &(*pp)->next;
+	*pp = token;
+	if (token->kad->expiry < key->expiry)
+		key->expiry = token->kad->expiry;
+	token = NULL;
 	ret = 0;
 
+error_free:
+	kfree(token);
 error:
 	return ret;
 }
@@ -184,7 +797,26 @@ static int rxrpc_instantiate_s(struct key *key, const void *data,
  */
 static void rxrpc_destroy(struct key *key)
 {
-	kfree(key->payload.data);
+	struct rxrpc_key_token *token;
+
+	while ((token = key->payload.data)) {
+		key->payload.data = token->next;
+		switch (token->security_index) {
+		case RXRPC_SECURITY_RXKAD:
+			kfree(token->kad);
+			break;
+		case RXRPC_SECURITY_RXK5:
+			if (token->k5)
+				rxrpc_rxk5_free(token->k5);
+			break;
+		default:
+			printk(KERN_ERR "Unknown token type %x on rxrpc key\n",
+			       token->security_index);
+			BUG();
+		}
+
+		kfree(token);
+	}
 }
 
 /*
@@ -293,7 +925,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
 
 	struct {
 		u32 kver;
-		struct rxkad_key tsec;
+		struct rxrpc_key_data_v1 v1;
 	} data;
 
 	_enter("");
@@ -308,13 +940,12 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
 	_debug("key %d", key_serial(key));
 
 	data.kver = 1;
-	data.tsec.security_index = 2;
-	data.tsec.ticket_len = 0;
-	data.tsec.expiry = expiry;
-	data.tsec.kvno = 0;
+	data.v1.security_index = RXRPC_SECURITY_RXKAD;
+	data.v1.ticket_length = 0;
+	data.v1.expiry = expiry;
+	data.v1.kvno = 0;
 
-	memcpy(&data.tsec.session_key, session_key,
-	       sizeof(data.tsec.session_key));
+	memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));
 
 	ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
 	if (ret < 0)
@@ -360,3 +991,210 @@ struct key *rxrpc_get_null_key(const char *keyname)
 	return key;
 }
 EXPORT_SYMBOL(rxrpc_get_null_key);
+
+/*
+ * read the contents of an rxrpc key
+ * - this returns the result in XDR form
+ */
+static long rxrpc_read(const struct key *key,
+		       char __user *buffer, size_t buflen)
+{
+	const struct rxrpc_key_token *token;
+	const struct krb5_principal *princ;
+	size_t size;
+	__be32 __user *xdr, *oldxdr;
+	u32 cnlen, toksize, ntoks, tok, zero;
+	u16 toksizes[AFSTOKEN_MAX];
+	int loop;
+
+	_enter("");
+
+	/* we don't know what form we should return non-AFS keys in */
+	if (memcmp(key->description, "afs@", 4) != 0)
+		return -EOPNOTSUPP;
+	cnlen = strlen(key->description + 4);
+
+#define RND(X) (((X) + 3) & ~3)
+
+	/* AFS keys we return in XDR form, so we need to work out the size of
+	 * the XDR */
+	size = 2 * 4;	/* flags, cellname len */
+	size += RND(cnlen);	/* cellname */
+	size += 1 * 4;	/* token count */
+
+	ntoks = 0;
+	for (token = key->payload.data; token; token = token->next) {
+		toksize = 4;	/* sec index */
+
+		switch (token->security_index) {
+		case RXRPC_SECURITY_RXKAD:
+			toksize += 8 * 4;	/* viceid, kvno, key*2, begin,
+						 * end, primary, tktlen */
+			toksize += RND(token->kad->ticket_len);
+			break;
+
+		case RXRPC_SECURITY_RXK5:
+			princ = &token->k5->client;
+			toksize += 4 + princ->n_name_parts * 4;
+			for (loop = 0; loop < princ->n_name_parts; loop++)
+				toksize += RND(strlen(princ->name_parts[loop]));
+			toksize += 4 + RND(strlen(princ->realm));
+
+			princ = &token->k5->server;
+			toksize += 4 + princ->n_name_parts * 4;
+			for (loop = 0; loop < princ->n_name_parts; loop++)
+				toksize += RND(strlen(princ->name_parts[loop]));
+			toksize += 4 + RND(strlen(princ->realm));
+
+			toksize += 8 + RND(token->k5->session.data_len);
+
+			toksize += 4 * 8 + 2 * 4;
+
+			toksize += 4 + token->k5->n_addresses * 8;
+			for (loop = 0; loop < token->k5->n_addresses; loop++)
+				toksize += RND(token->k5->addresses[loop].data_len);
+
+			toksize += 4 + RND(token->k5->ticket_len);
+			toksize += 4 + RND(token->k5->ticket2_len);
+
+			toksize += 4 + token->k5->n_authdata * 8;
+			for (loop = 0; loop < token->k5->n_authdata; loop++)
+				toksize += RND(token->k5->authdata[loop].data_len);
+			break;
+
+		default: /* we have a ticket we can't encode */
+			BUG();
+			continue;
+		}
+
+		_debug("token[%u]: toksize=%u", ntoks, toksize);
+		ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX);
+
+		toksizes[ntoks++] = toksize;
+		size += toksize + 4; /* each token has a length word */
+	}
+
+#undef RND
+
+	if (!buffer || buflen < size)
+		return size;
+
+	xdr = (__be32 __user *) buffer;
+	zero = 0;
+#define ENCODE(x)				\
+	do {					\
+		__be32 y = htonl(x);		\
+		if (put_user(y, xdr++) < 0)	\
+			goto fault;		\
+	} while(0)
+#define ENCODE_DATA(l, s)						\
+	do {								\
+		u32 _l = (l);						\
+		ENCODE(l);						\
+		if (copy_to_user(xdr, (s), _l) != 0)			\
+			goto fault;					\
+		if (_l & 3 &&						\
+		    copy_to_user((u8 *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \
+			goto fault;					\
+		xdr += (_l + 3) >> 2;					\
+	} while(0)
+#define ENCODE64(x)					\
+	do {						\
+		__be64 y = cpu_to_be64(x);		\
+		if (copy_to_user(xdr, &y, 8) != 0)	\
+			goto fault;			\
+		xdr += 8 >> 2;				\
+	} while(0)
+#define ENCODE_STR(s)				\
+	do {					\
+		const char *_s = (s);		\
+		ENCODE_DATA(strlen(_s), _s);	\
+	} while(0)
+
+	ENCODE(0);					/* flags */
+	ENCODE_DATA(cnlen, key->description + 4);	/* cellname */
+	ENCODE(ntoks);
+
+	tok = 0;
+	for (token = key->payload.data; token; token = token->next) {
+		toksize = toksizes[tok++];
+		ENCODE(toksize);
+		oldxdr = xdr;
+		ENCODE(token->security_index);
+
+		switch (token->security_index) {
+		case RXRPC_SECURITY_RXKAD:
+			ENCODE(token->kad->vice_id);
+			ENCODE(token->kad->kvno);
+			ENCODE_DATA(8, token->kad->session_key);
+			ENCODE(token->kad->start);
+			ENCODE(token->kad->expiry);
+			ENCODE(token->kad->primary_flag);
+			ENCODE_DATA(token->kad->ticket_len, token->kad->ticket);
+			break;
+
+		case RXRPC_SECURITY_RXK5:
+			princ = &token->k5->client;
+			ENCODE(princ->n_name_parts);
+			for (loop = 0; loop < princ->n_name_parts; loop++)
+				ENCODE_STR(princ->name_parts[loop]);
+			ENCODE_STR(princ->realm);
+
+			princ = &token->k5->server;
+			ENCODE(princ->n_name_parts);
+			for (loop = 0; loop < princ->n_name_parts; loop++)
+				ENCODE_STR(princ->name_parts[loop]);
+			ENCODE_STR(princ->realm);
+
+			ENCODE(token->k5->session.tag);
+			ENCODE_DATA(token->k5->session.data_len,
+				    token->k5->session.data);
+
+			ENCODE64(token->k5->authtime);
+			ENCODE64(token->k5->starttime);
+			ENCODE64(token->k5->endtime);
+			ENCODE64(token->k5->renew_till);
+			ENCODE(token->k5->is_skey);
+			ENCODE(token->k5->flags);
+
+			ENCODE(token->k5->n_addresses);
+			for (loop = 0; loop < token->k5->n_addresses; loop++) {
+				ENCODE(token->k5->addresses[loop].tag);
+				ENCODE_DATA(token->k5->addresses[loop].data_len,
+					    token->k5->addresses[loop].data);
+			}
+
+			ENCODE_DATA(token->k5->ticket_len, token->k5->ticket);
+			ENCODE_DATA(token->k5->ticket2_len, token->k5->ticket2);
+
+			ENCODE(token->k5->n_authdata);
+			for (loop = 0; loop < token->k5->n_authdata; loop++) {
+				ENCODE(token->k5->authdata[loop].tag);
+				ENCODE_DATA(token->k5->authdata[loop].data_len,
+					    token->k5->authdata[loop].data);
+			}
+			break;
+
+		default:
+			BUG();
+			break;
+		}
+
+		ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==,
+			  toksize);
+	}
+
+#undef ENCODE_STR
+#undef ENCODE_DATA
+#undef ENCODE64
+#undef ENCODE
+
+	ASSERTCMP(tok, ==, ntoks);
+	ASSERTCMP((char __user *) xdr - buffer, ==, size);
+	_leave(" = %zu", size);
+	return size;
+
+fault:
+	_leave(" = -EFAULT");
+	return -EFAULT;
+}
diff --git a/net/rxrpc/ar-security.c b/net/rxrpc/ar-security.c
index dc62920..49b3cc3 100644
--- a/net/rxrpc/ar-security.c
+++ b/net/rxrpc/ar-security.c
@@ -16,6 +16,7 @@
 #include <linux/crypto.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
+#include <keys/rxrpc-type.h>
 #include "ar-internal.h"
 
 static LIST_HEAD(rxrpc_security_methods);
@@ -122,6 +123,7 @@ EXPORT_SYMBOL_GPL(rxrpc_unregister_security);
  */
 int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
 {
+	struct rxrpc_key_token *token;
 	struct rxrpc_security *sec;
 	struct key *key = conn->key;
 	int ret;
@@ -135,7 +137,11 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
 	if (ret < 0)
 		return ret;
 
-	sec = rxrpc_security_lookup(key->type_data.x[0]);
+	if (!key->payload.data)
+		return -EKEYREJECTED;
+	token = key->payload.data;
+
+	sec = rxrpc_security_lookup(token->security_index);
 	if (!sec)
 		return -EKEYREJECTED;
 	conn->security = sec;
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index ef8f910..713ac59 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -18,6 +18,7 @@
 #include <linux/ctype.h>
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
+#include <keys/rxrpc-type.h>
 #define rxrpc_debug rxkad_debug
 #include "ar-internal.h"
 
@@ -42,7 +43,7 @@ struct rxkad_level2_hdr {
 	__be32	checksum;	/* decrypted data checksum */
 };
 
-MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos)");
+MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)");
 MODULE_AUTHOR("Red Hat, Inc.");
 MODULE_LICENSE("GPL");
 
@@ -59,14 +60,14 @@ static DEFINE_MUTEX(rxkad_ci_mutex);
  */
 static int rxkad_init_connection_security(struct rxrpc_connection *conn)
 {
-	struct rxrpc_key_payload *payload;
 	struct crypto_blkcipher *ci;
+	struct rxrpc_key_token *token;
 	int ret;
 
 	_enter("{%d},{%x}", conn->debug_id, key_serial(conn->key));
 
-	payload = conn->key->payload.data;
-	conn->security_ix = payload->k.security_index;
+	token = conn->key->payload.data;
+	conn->security_ix = token->security_index;
 
 	ci = crypto_alloc_blkcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
 	if (IS_ERR(ci)) {
@@ -75,8 +76,8 @@ static int rxkad_init_connection_security(struct rxrpc_connection *conn)
 		goto error;
 	}
 
-	if (crypto_blkcipher_setkey(ci, payload->k.session_key,
-				    sizeof(payload->k.session_key)) < 0)
+	if (crypto_blkcipher_setkey(ci, token->kad->session_key,
+				    sizeof(token->kad->session_key)) < 0)
 		BUG();
 
 	switch (conn->security_level) {
@@ -110,7 +111,7 @@ error:
  */
 static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
 {
-	struct rxrpc_key_payload *payload;
+	struct rxrpc_key_token *token;
 	struct blkcipher_desc desc;
 	struct scatterlist sg[2];
 	struct rxrpc_crypt iv;
@@ -123,8 +124,8 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
 	if (!conn->key)
 		return;
 
-	payload = conn->key->payload.data;
-	memcpy(&iv, payload->k.session_key, sizeof(iv));
+	token = conn->key->payload.data;
+	memcpy(&iv, token->kad->session_key, sizeof(iv));
 
 	desc.tfm = conn->cipher;
 	desc.info = iv.x;
@@ -197,7 +198,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
 					u32 data_size,
 					void *sechdr)
 {
-	const struct rxrpc_key_payload *payload;
+	const struct rxrpc_key_token *token;
 	struct rxkad_level2_hdr rxkhdr
 		__attribute__((aligned(8))); /* must be all on one page */
 	struct rxrpc_skb_priv *sp;
@@ -219,8 +220,8 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
 	rxkhdr.checksum = 0;
 
 	/* encrypt from the session key */
-	payload = call->conn->key->payload.data;
-	memcpy(&iv, payload->k.session_key, sizeof(iv));
+	token = call->conn->key->payload.data;
+	memcpy(&iv, token->kad->session_key, sizeof(iv));
 	desc.tfm = call->conn->cipher;
 	desc.info = iv.x;
 	desc.flags = 0;
@@ -400,7 +401,7 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
 				       struct sk_buff *skb,
 				       u32 *_abort_code)
 {
-	const struct rxrpc_key_payload *payload;
+	const struct rxrpc_key_token *token;
 	struct rxkad_level2_hdr sechdr;
 	struct rxrpc_skb_priv *sp;
 	struct blkcipher_desc desc;
@@ -431,8 +432,8 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
 	skb_to_sgvec(skb, sg, 0, skb->len);
 
 	/* decrypt from the session key */
-	payload = call->conn->key->payload.data;
-	memcpy(&iv, payload->k.session_key, sizeof(iv));
+	token = call->conn->key->payload.data;
+	memcpy(&iv, token->kad->session_key, sizeof(iv));
 	desc.tfm = call->conn->cipher;
 	desc.info = iv.x;
 	desc.flags = 0;
@@ -506,7 +507,7 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
 	if (!call->conn->cipher)
 		return 0;
 
-	if (sp->hdr.securityIndex != 2) {
+	if (sp->hdr.securityIndex != RXRPC_SECURITY_RXKAD) {
 		*_abort_code = RXKADINCONSISTENCY;
 		_leave(" = -EPROTO [not rxkad]");
 		return -EPROTO;
@@ -737,7 +738,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
 				      struct sk_buff *skb,
 				      u32 *_abort_code)
 {
-	const struct rxrpc_key_payload *payload;
+	const struct rxrpc_key_token *token;
 	struct rxkad_challenge challenge;
 	struct rxkad_response resp
 		__attribute__((aligned(8))); /* must be aligned for crypto */
@@ -778,7 +779,7 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
 	if (conn->security_level < min_level)
 		goto protocol_error;
 
-	payload = conn->key->payload.data;
+	token = conn->key->payload.data;
 
 	/* build the response packet */
 	memset(&resp, 0, sizeof(resp));
@@ -797,13 +798,13 @@ static int rxkad_respond_to_challenge(struct rxrpc_connection *conn,
 		(conn->channels[3] ? conn->channels[3]->call_id : 0);
 	resp.encrypted.inc_nonce = htonl(nonce + 1);
 	resp.encrypted.level = htonl(conn->security_level);
-	resp.kvno = htonl(payload->k.kvno);
-	resp.ticket_len = htonl(payload->k.ticket_len);
+	resp.kvno = htonl(token->kad->kvno);
+	resp.ticket_len = htonl(token->kad->ticket_len);
 
 	/* calculate the response checksum and then do the encryption */
 	rxkad_calc_response_checksum(&resp);
-	rxkad_encrypt_response(conn, &resp, &payload->k);
-	return rxkad_send_response(conn, &sp->hdr, &resp, &payload->k);
+	rxkad_encrypt_response(conn, &resp, token->kad);
+	return rxkad_send_response(conn, &sp->hdr, &resp, token->kad);
 
 protocol_error:
 	*_abort_code = abort_code;
@@ -1122,7 +1123,7 @@ static void rxkad_clear(struct rxrpc_connection *conn)
 static struct rxrpc_security rxkad = {
 	.owner				= THIS_MODULE,
 	.name				= "rxkad",
-	.security_index			= RXKAD_VERSION,
+	.security_index			= RXRPC_SECURITY_RXKAD,
 	.init_connection_security	= rxkad_init_connection_security,
 	.prime_packet_security		= rxkad_prime_packet_security,
 	.secure_packet			= rxkad_secure_packet,
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 54d950c..f14e71b 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the Linux Traffic Control Unit.
 #
 
-obj-y	:= sch_generic.o
+obj-y	:= sch_generic.o sch_mq.o
 
 obj-$(CONFIG_NET_SCHED)		+= sch_api.o sch_blackhole.o
 obj-$(CONFIG_NET_CLS)		+= cls_api.o
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9d03cc3..2dfb3e7 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1011,7 +1011,7 @@ replay:
 }
 
 static struct nlattr *
-find_dump_kind(struct nlmsghdr *n)
+find_dump_kind(const struct nlmsghdr *n)
 {
 	struct nlattr *tb1, *tb2[TCA_ACT_MAX+1];
 	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 09cdcdf..6a53694 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -168,8 +168,7 @@ replay:
 
 	/* Find qdisc */
 	if (!parent) {
-		struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, 0);
-		q = dev_queue->qdisc_sleeping;
+		q = dev->qdisc;
 		parent = q->handle;
 	} else {
 		q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent));
@@ -181,6 +180,9 @@ replay:
 	if ((cops = q->ops->cl_ops) == NULL)
 		return -EINVAL;
 
+	if (cops->tcf_chain == NULL)
+		return -EOPNOTSUPP;
+
 	/* Do we search for filter, attached to class? */
 	if (TC_H_MIN(parent)) {
 		cl = cops->get(q, parent);
@@ -405,7 +407,6 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n,
 static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct net *net = sock_net(skb->sk);
-	struct netdev_queue *dev_queue;
 	int t;
 	int s_t;
 	struct net_device *dev;
@@ -424,15 +425,16 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
 	if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
 		return skb->len;
 
-	dev_queue = netdev_get_tx_queue(dev, 0);
 	if (!tcm->tcm_parent)
-		q = dev_queue->qdisc_sleeping;
+		q = dev->qdisc;
 	else
 		q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
 	if (!q)
 		goto out;
 	if ((cops = q->ops->cl_ops) == NULL)
 		goto errout;
+	if (cops->tcf_chain == NULL)
+		goto errout;
 	if (TC_H_MIN(tcm->tcm_parent)) {
 		cl = cops->get(q, tcm->tcm_parent);
 		if (cl == 0)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index fdb694e..903e418 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -207,7 +207,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
 static void qdisc_list_add(struct Qdisc *q)
 {
 	if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS))
-		list_add_tail(&q->list, &qdisc_root_sleeping(q)->list);
+		list_add_tail(&q->list, &qdisc_dev(q)->qdisc->list);
 }
 
 void qdisc_list_del(struct Qdisc *q)
@@ -219,17 +219,11 @@ EXPORT_SYMBOL(qdisc_list_del);
 
 struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
 {
-	unsigned int i;
 	struct Qdisc *q;
 
-	for (i = 0; i < dev->num_tx_queues; i++) {
-		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
-		struct Qdisc *txq_root = txq->qdisc_sleeping;
-
-		q = qdisc_match_from_root(txq_root, handle);
-		if (q)
-			goto out;
-	}
+	q = qdisc_match_from_root(dev->qdisc, handle);
+	if (q)
+		goto out;
 
 	q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
 out:
@@ -616,32 +610,6 @@ static u32 qdisc_alloc_handle(struct net_device *dev)
 	return i>0 ? autohandle : 0;
 }
 
-/* Attach toplevel qdisc to device queue. */
-
-static struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
-				     struct Qdisc *qdisc)
-{
-	struct Qdisc *oqdisc = dev_queue->qdisc_sleeping;
-	spinlock_t *root_lock;
-
-	root_lock = qdisc_lock(oqdisc);
-	spin_lock_bh(root_lock);
-
-	/* Prune old scheduler */
-	if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1)
-		qdisc_reset(oqdisc);
-
-	/* ... and graft new one */
-	if (qdisc == NULL)
-		qdisc = &noop_qdisc;
-	dev_queue->qdisc_sleeping = qdisc;
-	rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc);
-
-	spin_unlock_bh(root_lock);
-
-	return oqdisc;
-}
-
 void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
 {
 	const struct Qdisc_class_ops *cops;
@@ -710,6 +678,11 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 		if (dev->flags & IFF_UP)
 			dev_deactivate(dev);
 
+		if (new && new->ops->attach) {
+			new->ops->attach(new);
+			num_q = 0;
+		}
+
 		for (i = 0; i < num_q; i++) {
 			struct netdev_queue *dev_queue = &dev->rx_queue;
 
@@ -720,6 +693,16 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 			if (new && i > 0)
 				atomic_inc(&new->refcnt);
 
+			if (!ingress)
+				qdisc_destroy(old);
+		}
+
+		if (!ingress) {
+			notify_and_destroy(skb, n, classid, dev->qdisc, new);
+			if (new && !new->ops->attach)
+				atomic_inc(&new->refcnt);
+			dev->qdisc = new ? : &noop_qdisc;
+		} else {
 			notify_and_destroy(skb, n, classid, old, new);
 		}
 
@@ -728,14 +711,14 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 	} else {
 		const struct Qdisc_class_ops *cops = parent->ops->cl_ops;
 
-		err = -EINVAL;
-
-		if (cops) {
+		err = -EOPNOTSUPP;
+		if (cops && cops->graft) {
 			unsigned long cl = cops->get(parent, classid);
 			if (cl) {
 				err = cops->graft(parent, cl, new, &old);
 				cops->put(parent, cl);
-			}
+			} else
+				err = -ENOENT;
 		}
 		if (!err)
 			notify_and_destroy(skb, n, classid, old, new);
@@ -755,7 +738,8 @@ static struct lock_class_key qdisc_rx_lock;
 
 static struct Qdisc *
 qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
-	     u32 parent, u32 handle, struct nlattr **tca, int *errp)
+	     struct Qdisc *p, u32 parent, u32 handle,
+	     struct nlattr **tca, int *errp)
 {
 	int err;
 	struct nlattr *kind = tca[TCA_KIND];
@@ -825,31 +809,28 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
 			stab = qdisc_get_stab(tca[TCA_STAB]);
 			if (IS_ERR(stab)) {
 				err = PTR_ERR(stab);
-				goto err_out3;
+				goto err_out4;
 			}
 			sch->stab = stab;
 		}
 		if (tca[TCA_RATE]) {
 			spinlock_t *root_lock;
 
+			err = -EOPNOTSUPP;
+			if (sch->flags & TCQ_F_MQROOT)
+				goto err_out4;
+
 			if ((sch->parent != TC_H_ROOT) &&
-			    !(sch->flags & TCQ_F_INGRESS))
+			    !(sch->flags & TCQ_F_INGRESS) &&
+			    (!p || !(p->flags & TCQ_F_MQROOT)))
 				root_lock = qdisc_root_sleeping_lock(sch);
 			else
 				root_lock = qdisc_lock(sch);
 
 			err = gen_new_estimator(&sch->bstats, &sch->rate_est,
 						root_lock, tca[TCA_RATE]);
-			if (err) {
-				/*
-				 * Any broken qdiscs that would require
-				 * a ops->reset() here? The qdisc was never
-				 * in action so it shouldn't be necessary.
-				 */
-				if (ops->destroy)
-					ops->destroy(sch);
-				goto err_out3;
-			}
+			if (err)
+				goto err_out4;
 		}
 
 		qdisc_list_add(sch);
@@ -857,7 +838,6 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
 		return sch;
 	}
 err_out3:
-	qdisc_put_stab(sch->stab);
 	dev_put(dev);
 	kfree((char *) sch - sch->padded);
 err_out2:
@@ -865,6 +845,16 @@ err_out2:
 err_out:
 	*errp = err;
 	return NULL;
+
+err_out4:
+	/*
+	 * Any broken qdiscs that would require a ops->reset() here?
+	 * The qdisc was never in action so it shouldn't be necessary.
+	 */
+	qdisc_put_stab(sch->stab);
+	if (ops->destroy)
+		ops->destroy(sch);
+	goto err_out3;
 }
 
 static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
@@ -889,13 +879,16 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
 	qdisc_put_stab(sch->stab);
 	sch->stab = stab;
 
-	if (tca[TCA_RATE])
+	if (tca[TCA_RATE]) {
 		/* NB: ignores errors from replace_estimator
 		   because change can't be undone. */
+		if (sch->flags & TCQ_F_MQROOT)
+			goto out;
 		gen_replace_estimator(&sch->bstats, &sch->rate_est,
 					    qdisc_root_sleeping_lock(sch),
 					    tca[TCA_RATE]);
-
+	}
+out:
 	return 0;
 }
 
@@ -974,9 +967,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 				q = dev->rx_queue.qdisc_sleeping;
 			}
 		} else {
-			struct netdev_queue *dev_queue;
-			dev_queue = netdev_get_tx_queue(dev, 0);
-			q = dev_queue->qdisc_sleeping;
+			q = dev->qdisc;
 		}
 		if (!q)
 			return -ENOENT;
@@ -1044,9 +1035,7 @@ replay:
 				q = dev->rx_queue.qdisc_sleeping;
 			}
 		} else {
-			struct netdev_queue *dev_queue;
-			dev_queue = netdev_get_tx_queue(dev, 0);
-			q = dev_queue->qdisc_sleeping;
+			q = dev->qdisc;
 		}
 
 		/* It may be default qdisc, ignore it */
@@ -1123,13 +1112,23 @@ create_n_graft:
 	if (!(n->nlmsg_flags&NLM_F_CREATE))
 		return -ENOENT;
 	if (clid == TC_H_INGRESS)
-		q = qdisc_create(dev, &dev->rx_queue,
+		q = qdisc_create(dev, &dev->rx_queue, p,
 				 tcm->tcm_parent, tcm->tcm_parent,
 				 tca, &err);
-	else
-		q = qdisc_create(dev, netdev_get_tx_queue(dev, 0),
+	else {
+		struct netdev_queue *dev_queue;
+
+		if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue)
+			dev_queue = p->ops->cl_ops->select_queue(p, tcm);
+		else if (p)
+			dev_queue = p->dev_queue;
+		else
+			dev_queue = netdev_get_tx_queue(dev, 0);
+
+		q = qdisc_create(dev, dev_queue, p,
 				 tcm->tcm_parent, tcm->tcm_handle,
 				 tca, &err);
+	}
 	if (q == NULL) {
 		if (err == -EAGAIN)
 			goto replay;
@@ -1291,8 +1290,7 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
 			s_q_idx = 0;
 		q_idx = 0;
 
-		dev_queue = netdev_get_tx_queue(dev, 0);
-		if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0)
+		if (tc_dump_qdisc_root(dev->qdisc, skb, cb, &q_idx, s_q_idx) < 0)
 			goto done;
 
 		dev_queue = &dev->rx_queue;
@@ -1323,7 +1321,6 @@ done:
 static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
 	struct net *net = sock_net(skb->sk);
-	struct netdev_queue *dev_queue;
 	struct tcmsg *tcm = NLMSG_DATA(n);
 	struct nlattr *tca[TCA_MAX + 1];
 	struct net_device *dev;
@@ -1361,7 +1358,6 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 
 	/* Step 1. Determine qdisc handle X:0 */
 
-	dev_queue = netdev_get_tx_queue(dev, 0);
 	if (pid != TC_H_ROOT) {
 		u32 qid1 = TC_H_MAJ(pid);
 
@@ -1372,7 +1368,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 		} else if (qid1) {
 			qid = qid1;
 		} else if (qid == 0)
-			qid = dev_queue->qdisc_sleeping->handle;
+			qid = dev->qdisc->handle;
 
 		/* Now qid is genuine qdisc handle consistent
 		   both with parent and child.
@@ -1383,7 +1379,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 			pid = TC_H_MAKE(qid, pid);
 	} else {
 		if (qid == 0)
-			qid = dev_queue->qdisc_sleeping->handle;
+			qid = dev->qdisc->handle;
 	}
 
 	/* OK. Locate qdisc */
@@ -1417,7 +1413,9 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 				goto out;
 			break;
 		case RTM_DELTCLASS:
-			err = cops->delete(q, cl);
+			err = -EOPNOTSUPP;
+			if (cops->delete)
+				err = cops->delete(q, cl);
 			if (err == 0)
 				tclass_notify(skb, n, q, cl, RTM_DELTCLASS);
 			goto out;
@@ -1431,7 +1429,9 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 	}
 
 	new_cl = cl;
-	err = cops->change(q, clid, pid, tca, &new_cl);
+	err = -EOPNOTSUPP;
+	if (cops->change)
+		err = cops->change(q, clid, pid, tca, &new_cl);
 	if (err == 0)
 		tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS);
 
@@ -1586,8 +1586,7 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
 	s_t = cb->args[0];
 	t = 0;
 
-	dev_queue = netdev_get_tx_queue(dev, 0);
-	if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0)
+	if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0)
 		goto done;
 
 	dev_queue = &dev->rx_queue;
@@ -1707,6 +1706,7 @@ static int __init pktsched_init(void)
 {
 	register_qdisc(&pfifo_qdisc_ops);
 	register_qdisc(&bfifo_qdisc_ops);
+	register_qdisc(&mq_qdisc_ops);
 	proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
 
 	rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index d5798e1..5b132c4 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1621,29 +1621,25 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 {
 	struct cbq_class *cl = (struct cbq_class*)arg;
 
-	if (cl) {
-		if (new == NULL) {
-			new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
-						&pfifo_qdisc_ops,
-						cl->common.classid);
-			if (new == NULL)
-				return -ENOBUFS;
-		} else {
+	if (new == NULL) {
+		new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+					&pfifo_qdisc_ops, cl->common.classid);
+		if (new == NULL)
+			return -ENOBUFS;
+	} else {
 #ifdef CONFIG_NET_CLS_ACT
-			if (cl->police == TC_POLICE_RECLASSIFY)
-				new->reshape_fail = cbq_reshape_fail;
+		if (cl->police == TC_POLICE_RECLASSIFY)
+			new->reshape_fail = cbq_reshape_fail;
 #endif
-		}
-		sch_tree_lock(sch);
-		*old = cl->q;
-		cl->q = new;
-		qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-		qdisc_reset(*old);
-		sch_tree_unlock(sch);
-
-		return 0;
 	}
-	return -ENOENT;
+	sch_tree_lock(sch);
+	*old = cl->q;
+	cl->q = new;
+	qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
+	qdisc_reset(*old);
+	sch_tree_unlock(sch);
+
+	return 0;
 }
 
 static struct Qdisc *
@@ -1651,7 +1647,7 @@ cbq_leaf(struct Qdisc *sch, unsigned long arg)
 {
 	struct cbq_class *cl = (struct cbq_class*)arg;
 
-	return cl ? cl->q : NULL;
+	return cl->q;
 }
 
 static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg)
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 12b2fb0..5a888af 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -274,8 +274,10 @@ static int drr_dump_class_stats(struct Qdisc *sch, unsigned long arg,
 	struct tc_drr_stats xstats;
 
 	memset(&xstats, 0, sizeof(xstats));
-	if (cl->qdisc->q.qlen)
+	if (cl->qdisc->q.qlen) {
 		xstats.deficit = cl->deficit;
+		cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
+	}
 
 	if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
 	    gnet_stats_copy_rate_est(d, &cl->rate_est) < 0 ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 27d0381..4ae6aa5 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -37,15 +37,11 @@
  * - updates to tree and tree walking are only done under the rtnl mutex.
  */
 
-static inline int qdisc_qlen(struct Qdisc *q)
-{
-	return q->q.qlen;
-}
-
 static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
 {
 	q->gso_skb = skb;
 	q->qstats.requeues++;
+	q->q.qlen++;	/* it's still part of the queue */
 	__netif_schedule(q);
 
 	return 0;
@@ -61,9 +57,11 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
 
 		/* check the reason of requeuing without tx lock first */
 		txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
-		if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))
+		if (!netif_tx_queue_stopped(txq) &&
+		    !netif_tx_queue_frozen(txq)) {
 			q->gso_skb = NULL;
-		else
+			q->q.qlen--;
+		} else
 			skb = NULL;
 	} else {
 		skb = q->dequeue(q);
@@ -103,44 +101,23 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb,
 }
 
 /*
- * NOTE: Called under qdisc_lock(q) with locally disabled BH.
- *
- * __QDISC_STATE_RUNNING guarantees only one CPU can process
- * this qdisc at a time. qdisc_lock(q) serializes queue accesses for
- * this queue.
- *
- *  netif_tx_lock serializes accesses to device driver.
- *
- *  qdisc_lock(q) and netif_tx_lock are mutually exclusive,
- *  if one is grabbed, another must be free.
- *
- * Note, that this procedure can be called by a watchdog timer
+ * Transmit one skb, and handle the return status as required. Holding the
+ * __QDISC_STATE_RUNNING bit guarantees that only one CPU can execute this
+ * function.
  *
  * Returns to the caller:
  *				0  - queue is empty or throttled.
  *				>0 - queue is not empty.
- *
  */
-static inline int qdisc_restart(struct Qdisc *q)
+int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+		    struct net_device *dev, struct netdev_queue *txq,
+		    spinlock_t *root_lock)
 {
-	struct netdev_queue *txq;
 	int ret = NETDEV_TX_BUSY;
-	struct net_device *dev;
-	spinlock_t *root_lock;
-	struct sk_buff *skb;
-
-	/* Dequeue packet */
-	if (unlikely((skb = dequeue_skb(q)) == NULL))
-		return 0;
-
-	root_lock = qdisc_lock(q);
 
 	/* And release qdisc */
 	spin_unlock(root_lock);
 
-	dev = qdisc_dev(q);
-	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
-
 	HARD_TX_LOCK(dev, txq, smp_processor_id());
 	if (!netif_tx_queue_stopped(txq) &&
 	    !netif_tx_queue_frozen(txq))
@@ -177,6 +154,44 @@ static inline int qdisc_restart(struct Qdisc *q)
 	return ret;
 }
 
+/*
+ * NOTE: Called under qdisc_lock(q) with locally disabled BH.
+ *
+ * __QDISC_STATE_RUNNING guarantees only one CPU can process
+ * this qdisc at a time. qdisc_lock(q) serializes queue accesses for
+ * this queue.
+ *
+ *  netif_tx_lock serializes accesses to device driver.
+ *
+ *  qdisc_lock(q) and netif_tx_lock are mutually exclusive,
+ *  if one is grabbed, another must be free.
+ *
+ * Note, that this procedure can be called by a watchdog timer
+ *
+ * Returns to the caller:
+ *				0  - queue is empty or throttled.
+ *				>0 - queue is not empty.
+ *
+ */
+static inline int qdisc_restart(struct Qdisc *q)
+{
+	struct netdev_queue *txq;
+	struct net_device *dev;
+	spinlock_t *root_lock;
+	struct sk_buff *skb;
+
+	/* Dequeue packet */
+	skb = dequeue_skb(q);
+	if (unlikely(!skb))
+		return 0;
+
+	root_lock = qdisc_lock(q);
+	dev = qdisc_dev(q);
+	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+
+	return sch_direct_xmit(skb, q, dev, txq, root_lock);
+}
+
 void __qdisc_run(struct Qdisc *q)
 {
 	unsigned long start_time = jiffies;
@@ -391,18 +406,38 @@ static const u8 prio2band[TC_PRIO_MAX+1] =
 
 #define PFIFO_FAST_BANDS 3
 
-static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
-					     struct Qdisc *qdisc)
+/*
+ * Private data for a pfifo_fast scheduler containing:
+ * 	- queues for the three band
+ * 	- bitmap indicating which of the bands contain skbs
+ */
+struct pfifo_fast_priv {
+	u32 bitmap;
+	struct sk_buff_head q[PFIFO_FAST_BANDS];
+};
+
+/*
+ * Convert a bitmap to the first band number where an skb is queued, where:
+ * 	bitmap=0 means there are no skbs on any band.
+ * 	bitmap=1 means there is an skb on band 0.
+ *	bitmap=7 means there are skbs on all 3 bands, etc.
+ */
+static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0};
+
+static inline struct sk_buff_head *band2list(struct pfifo_fast_priv *priv,
+					     int band)
 {
-	struct sk_buff_head *list = qdisc_priv(qdisc);
-	return list + prio2band[skb->priority & TC_PRIO_MAX];
+	return priv->q + band;
 }
 
 static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
 {
-	struct sk_buff_head *list = prio2list(skb, qdisc);
+	if (skb_queue_len(&qdisc->q) < qdisc_dev(qdisc)->tx_queue_len) {
+		int band = prio2band[skb->priority & TC_PRIO_MAX];
+		struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+		struct sk_buff_head *list = band2list(priv, band);
 
-	if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
+		priv->bitmap |= (1 << band);
 		qdisc->q.qlen++;
 		return __qdisc_enqueue_tail(skb, qdisc, list);
 	}
@@ -412,14 +447,18 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
 
 static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
 {
-	int prio;
-	struct sk_buff_head *list = qdisc_priv(qdisc);
+	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+	int band = bitmap2band[priv->bitmap];
 
-	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
-		if (!skb_queue_empty(list + prio)) {
-			qdisc->q.qlen--;
-			return __qdisc_dequeue_head(qdisc, list + prio);
-		}
+	if (likely(band >= 0)) {
+		struct sk_buff_head *list = band2list(priv, band);
+		struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list);
+
+		qdisc->q.qlen--;
+		if (skb_queue_empty(list))
+			priv->bitmap &= ~(1 << band);
+
+		return skb;
 	}
 
 	return NULL;
@@ -427,12 +466,13 @@ static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
 
 static struct sk_buff *pfifo_fast_peek(struct Qdisc* qdisc)
 {
-	int prio;
-	struct sk_buff_head *list = qdisc_priv(qdisc);
+	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
+	int band = bitmap2band[priv->bitmap];
 
-	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
-		if (!skb_queue_empty(list + prio))
-			return skb_peek(list + prio);
+	if (band >= 0) {
+		struct sk_buff_head *list = band2list(priv, band);
+
+		return skb_peek(list);
 	}
 
 	return NULL;
@@ -441,11 +481,12 @@ static struct sk_buff *pfifo_fast_peek(struct Qdisc* qdisc)
 static void pfifo_fast_reset(struct Qdisc* qdisc)
 {
 	int prio;
-	struct sk_buff_head *list = qdisc_priv(qdisc);
+	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
 
 	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
-		__qdisc_reset_queue(qdisc, list + prio);
+		__qdisc_reset_queue(qdisc, band2list(priv, prio));
 
+	priv->bitmap = 0;
 	qdisc->qstats.backlog = 0;
 	qdisc->q.qlen = 0;
 }
@@ -465,17 +506,17 @@ nla_put_failure:
 static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
 {
 	int prio;
-	struct sk_buff_head *list = qdisc_priv(qdisc);
+	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
 
 	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
-		skb_queue_head_init(list + prio);
+		skb_queue_head_init(band2list(priv, prio));
 
 	return 0;
 }
 
-static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
+struct Qdisc_ops pfifo_fast_ops __read_mostly = {
 	.id		=	"pfifo_fast",
-	.priv_size	=	PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
+	.priv_size	=	sizeof(struct pfifo_fast_priv),
 	.enqueue	=	pfifo_fast_enqueue,
 	.dequeue	=	pfifo_fast_dequeue,
 	.peek		=	pfifo_fast_peek,
@@ -547,8 +588,11 @@ void qdisc_reset(struct Qdisc *qdisc)
 	if (ops->reset)
 		ops->reset(qdisc);
 
-	kfree_skb(qdisc->gso_skb);
-	qdisc->gso_skb = NULL;
+	if (qdisc->gso_skb) {
+		kfree_skb(qdisc->gso_skb);
+		qdisc->gso_skb = NULL;
+		qdisc->q.qlen = 0;
+	}
 }
 EXPORT_SYMBOL(qdisc_reset);
 
@@ -579,17 +623,29 @@ void qdisc_destroy(struct Qdisc *qdisc)
 }
 EXPORT_SYMBOL(qdisc_destroy);
 
-static bool dev_all_qdisc_sleeping_noop(struct net_device *dev)
+/* Attach toplevel qdisc to device queue. */
+struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
+			      struct Qdisc *qdisc)
 {
-	unsigned int i;
+	struct Qdisc *oqdisc = dev_queue->qdisc_sleeping;
+	spinlock_t *root_lock;
 
-	for (i = 0; i < dev->num_tx_queues; i++) {
-		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
+	root_lock = qdisc_lock(oqdisc);
+	spin_lock_bh(root_lock);
 
-		if (txq->qdisc_sleeping != &noop_qdisc)
-			return false;
-	}
-	return true;
+	/* Prune old scheduler */
+	if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1)
+		qdisc_reset(oqdisc);
+
+	/* ... and graft new one */
+	if (qdisc == NULL)
+		qdisc = &noop_qdisc;
+	dev_queue->qdisc_sleeping = qdisc;
+	rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc);
+
+	spin_unlock_bh(root_lock);
+
+	return oqdisc;
 }
 
 static void attach_one_default_qdisc(struct net_device *dev,
@@ -605,12 +661,35 @@ static void attach_one_default_qdisc(struct net_device *dev,
 			printk(KERN_INFO "%s: activation failed\n", dev->name);
 			return;
 		}
+
+		/* Can by-pass the queue discipline for default qdisc */
+		qdisc->flags |= TCQ_F_CAN_BYPASS;
 	} else {
 		qdisc =  &noqueue_qdisc;
 	}
 	dev_queue->qdisc_sleeping = qdisc;
 }
 
+static void attach_default_qdiscs(struct net_device *dev)
+{
+	struct netdev_queue *txq;
+	struct Qdisc *qdisc;
+
+	txq = netdev_get_tx_queue(dev, 0);
+
+	if (!netif_is_multiqueue(dev) || dev->tx_queue_len == 0) {
+		netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
+		dev->qdisc = txq->qdisc_sleeping;
+		atomic_inc(&dev->qdisc->refcnt);
+	} else {
+		qdisc = qdisc_create_dflt(dev, txq, &mq_qdisc_ops, TC_H_ROOT);
+		if (qdisc) {
+			qdisc->ops->attach(qdisc);
+			dev->qdisc = qdisc;
+		}
+	}
+}
+
 static void transition_one_qdisc(struct net_device *dev,
 				 struct netdev_queue *dev_queue,
 				 void *_need_watchdog)
@@ -638,8 +717,8 @@ void dev_activate(struct net_device *dev)
 	   virtual interfaces
 	 */
 
-	if (dev_all_qdisc_sleeping_noop(dev))
-		netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
+	if (dev->qdisc == &noop_qdisc)
+		attach_default_qdiscs(dev);
 
 	if (!netif_carrier_ok(dev))
 		/* Delay activation until next carrier-on event */
@@ -730,6 +809,7 @@ static void dev_init_scheduler_queue(struct net_device *dev,
 
 void dev_init_scheduler(struct net_device *dev)
 {
+	dev->qdisc = &noop_qdisc;
 	netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
 	dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
 
@@ -755,5 +835,8 @@ void dev_shutdown(struct net_device *dev)
 {
 	netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
 	shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
+	qdisc_destroy(dev->qdisc);
+	dev->qdisc = &noop_qdisc;
+
 	WARN_ON(timer_pending(&dev->watchdog_timer));
 }
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index dad0144..375d64c 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1203,8 +1203,6 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 {
 	struct hfsc_class *cl = (struct hfsc_class *)arg;
 
-	if (cl == NULL)
-		return -ENOENT;
 	if (cl->level > 0)
 		return -EINVAL;
 	if (new == NULL) {
@@ -1228,7 +1226,7 @@ hfsc_class_leaf(struct Qdisc *sch, unsigned long arg)
 {
 	struct hfsc_class *cl = (struct hfsc_class *)arg;
 
-	if (cl != NULL && cl->level == 0)
+	if (cl->level == 0)
 		return cl->qdisc;
 
 	return NULL;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index ec4d463..85acab9 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1117,30 +1117,29 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 {
 	struct htb_class *cl = (struct htb_class *)arg;
 
-	if (cl && !cl->level) {
-		if (new == NULL &&
-		    (new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
-					     &pfifo_qdisc_ops,
-					     cl->common.classid))
-		    == NULL)
-			return -ENOBUFS;
-		sch_tree_lock(sch);
-		*old = cl->un.leaf.q;
-		cl->un.leaf.q = new;
-		if (*old != NULL) {
-			qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
-			qdisc_reset(*old);
-		}
-		sch_tree_unlock(sch);
-		return 0;
+	if (cl->level)
+		return -EINVAL;
+	if (new == NULL &&
+	    (new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+				     &pfifo_qdisc_ops,
+				     cl->common.classid)) == NULL)
+		return -ENOBUFS;
+
+	sch_tree_lock(sch);
+	*old = cl->un.leaf.q;
+	cl->un.leaf.q = new;
+	if (*old != NULL) {
+		qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
+		qdisc_reset(*old);
 	}
-	return -ENOENT;
+	sch_tree_unlock(sch);
+	return 0;
 }
 
 static struct Qdisc *htb_leaf(struct Qdisc *sch, unsigned long arg)
 {
 	struct htb_class *cl = (struct htb_class *)arg;
-	return (cl && !cl->level) ? cl->un.leaf.q : NULL;
+	return !cl->level ? cl->un.leaf.q : NULL;
 }
 
 static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg)
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 4a2b773..a9e646b 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -22,12 +22,6 @@ struct ingress_qdisc_data {
 
 /* ------------------------- Class/flow operations ------------------------- */
 
-static int ingress_graft(struct Qdisc *sch, unsigned long arg,
-			 struct Qdisc *new, struct Qdisc **old)
-{
-	return -EOPNOTSUPP;
-}
-
 static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg)
 {
 	return NULL;
@@ -48,12 +42,6 @@ static void ingress_put(struct Qdisc *sch, unsigned long cl)
 {
 }
 
-static int ingress_change(struct Qdisc *sch, u32 classid, u32 parent,
-			  struct nlattr **tca, unsigned long *arg)
-{
-	return 0;
-}
-
 static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 {
 	return;
@@ -123,11 +111,9 @@ nla_put_failure:
 }
 
 static const struct Qdisc_class_ops ingress_class_ops = {
-	.graft		=	ingress_graft,
 	.leaf		=	ingress_leaf,
 	.get		=	ingress_get,
 	.put		=	ingress_put,
-	.change		=	ingress_change,
 	.walk		=	ingress_walk,
 	.tcf_chain	=	ingress_find_tcf,
 	.bind_tcf	=	ingress_bind_filter,
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
new file mode 100644
index 0000000..d1dea3d
--- /dev/null
+++ b/net/sched/sch_mq.c
@@ -0,0 +1,241 @@
+/*
+ * net/sched/sch_mq.c		Classful multiqueue dummy scheduler
+ *
+ * Copyright (c) 2009 Patrick McHardy <kaber@trash.net>
+ *
+ * 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/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <net/netlink.h>
+#include <net/pkt_sched.h>
+
+struct mq_sched {
+	struct Qdisc		**qdiscs;
+};
+
+static void mq_destroy(struct Qdisc *sch)
+{
+	struct net_device *dev = qdisc_dev(sch);
+	struct mq_sched *priv = qdisc_priv(sch);
+	unsigned int ntx;
+
+	if (!priv->qdiscs)
+		return;
+	for (ntx = 0; ntx < dev->num_tx_queues && priv->qdiscs[ntx]; ntx++)
+		qdisc_destroy(priv->qdiscs[ntx]);
+	kfree(priv->qdiscs);
+}
+
+static int mq_init(struct Qdisc *sch, struct nlattr *opt)
+{
+	struct net_device *dev = qdisc_dev(sch);
+	struct mq_sched *priv = qdisc_priv(sch);
+	struct netdev_queue *dev_queue;
+	struct Qdisc *qdisc;
+	unsigned int ntx;
+
+	if (sch->parent != TC_H_ROOT)
+		return -EOPNOTSUPP;
+
+	if (!netif_is_multiqueue(dev))
+		return -EOPNOTSUPP;
+
+	/* pre-allocate qdiscs, attachment can't fail */
+	priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]),
+			       GFP_KERNEL);
+	if (priv->qdiscs == NULL)
+		return -ENOMEM;
+
+	for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
+		dev_queue = netdev_get_tx_queue(dev, ntx);
+		qdisc = qdisc_create_dflt(dev, dev_queue, &pfifo_fast_ops,
+					  TC_H_MAKE(TC_H_MAJ(sch->handle),
+						    TC_H_MIN(ntx + 1)));
+		if (qdisc == NULL)
+			goto err;
+		qdisc->flags |= TCQ_F_CAN_BYPASS;
+		priv->qdiscs[ntx] = qdisc;
+	}
+
+	sch->flags |= TCQ_F_MQROOT;
+	return 0;
+
+err:
+	mq_destroy(sch);
+	return -ENOMEM;
+}
+
+static void mq_attach(struct Qdisc *sch)
+{
+	struct net_device *dev = qdisc_dev(sch);
+	struct mq_sched *priv = qdisc_priv(sch);
+	struct Qdisc *qdisc;
+	unsigned int ntx;
+
+	for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
+		qdisc = priv->qdiscs[ntx];
+		qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
+		if (qdisc)
+			qdisc_destroy(qdisc);
+	}
+	kfree(priv->qdiscs);
+	priv->qdiscs = NULL;
+}
+
+static int mq_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+	struct net_device *dev = qdisc_dev(sch);
+	struct Qdisc *qdisc;
+	unsigned int ntx;
+
+	sch->q.qlen = 0;
+	memset(&sch->bstats, 0, sizeof(sch->bstats));
+	memset(&sch->qstats, 0, sizeof(sch->qstats));
+
+	for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
+		qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
+		spin_lock_bh(qdisc_lock(qdisc));
+		sch->q.qlen		+= qdisc->q.qlen;
+		sch->bstats.bytes	+= qdisc->bstats.bytes;
+		sch->bstats.packets	+= qdisc->bstats.packets;
+		sch->qstats.qlen	+= qdisc->qstats.qlen;
+		sch->qstats.backlog	+= qdisc->qstats.backlog;
+		sch->qstats.drops	+= qdisc->qstats.drops;
+		sch->qstats.requeues	+= qdisc->qstats.requeues;
+		sch->qstats.overlimits	+= qdisc->qstats.overlimits;
+		spin_unlock_bh(qdisc_lock(qdisc));
+	}
+	return 0;
+}
+
+static struct netdev_queue *mq_queue_get(struct Qdisc *sch, unsigned long cl)
+{
+	struct net_device *dev = qdisc_dev(sch);
+	unsigned long ntx = cl - 1;
+
+	if (ntx >= dev->num_tx_queues)
+		return NULL;
+	return netdev_get_tx_queue(dev, ntx);
+}
+
+static struct netdev_queue *mq_select_queue(struct Qdisc *sch,
+					    struct tcmsg *tcm)
+{
+	unsigned int ntx = TC_H_MIN(tcm->tcm_parent);
+	struct netdev_queue *dev_queue = mq_queue_get(sch, ntx);
+
+	if (!dev_queue) {
+		struct net_device *dev = qdisc_dev(sch);
+
+		return netdev_get_tx_queue(dev, 0);
+	}
+	return dev_queue;
+}
+
+static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
+		    struct Qdisc **old)
+{
+	struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
+	struct net_device *dev = qdisc_dev(sch);
+
+	if (dev->flags & IFF_UP)
+		dev_deactivate(dev);
+
+	*old = dev_graft_qdisc(dev_queue, new);
+
+	if (dev->flags & IFF_UP)
+		dev_activate(dev);
+	return 0;
+}
+
+static struct Qdisc *mq_leaf(struct Qdisc *sch, unsigned long cl)
+{
+	struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
+
+	return dev_queue->qdisc_sleeping;
+}
+
+static unsigned long mq_get(struct Qdisc *sch, u32 classid)
+{
+	unsigned int ntx = TC_H_MIN(classid);
+
+	if (!mq_queue_get(sch, ntx))
+		return 0;
+	return ntx;
+}
+
+static void mq_put(struct Qdisc *sch, unsigned long cl)
+{
+	return;
+}
+
+static int mq_dump_class(struct Qdisc *sch, unsigned long cl,
+			 struct sk_buff *skb, struct tcmsg *tcm)
+{
+	struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
+
+	tcm->tcm_parent = TC_H_ROOT;
+	tcm->tcm_handle |= TC_H_MIN(cl);
+	tcm->tcm_info = dev_queue->qdisc_sleeping->handle;
+	return 0;
+}
+
+static int mq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
+			       struct gnet_dump *d)
+{
+	struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
+
+	sch = dev_queue->qdisc_sleeping;
+	sch->qstats.qlen = sch->q.qlen;
+	if (gnet_stats_copy_basic(d, &sch->bstats) < 0 ||
+	    gnet_stats_copy_queue(d, &sch->qstats) < 0)
+		return -1;
+	return 0;
+}
+
+static void mq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+	struct net_device *dev = qdisc_dev(sch);
+	unsigned int ntx;
+
+	if (arg->stop)
+		return;
+
+	arg->count = arg->skip;
+	for (ntx = arg->skip; ntx < dev->num_tx_queues; ntx++) {
+		if (arg->fn(sch, ntx + 1, arg) < 0) {
+			arg->stop = 1;
+			break;
+		}
+		arg->count++;
+	}
+}
+
+static const struct Qdisc_class_ops mq_class_ops = {
+	.select_queue	= mq_select_queue,
+	.graft		= mq_graft,
+	.leaf		= mq_leaf,
+	.get		= mq_get,
+	.put		= mq_put,
+	.walk		= mq_walk,
+	.dump		= mq_dump_class,
+	.dump_stats	= mq_dump_class_stats,
+};
+
+struct Qdisc_ops mq_qdisc_ops __read_mostly = {
+	.cl_ops		= &mq_class_ops,
+	.id		= "mq",
+	.priv_size	= sizeof(struct mq_sched),
+	.init		= mq_init,
+	.destroy	= mq_destroy,
+	.attach		= mq_attach,
+	.dump		= mq_dump,
+	.owner		= THIS_MODULE,
+};
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 9127312..7db2c88 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -298,9 +298,6 @@ static int multiq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 	struct multiq_sched_data *q = qdisc_priv(sch);
 	unsigned long band = arg - 1;
 
-	if (band >= q->bands)
-		return -EINVAL;
-
 	if (new == NULL)
 		new = &noop_qdisc;
 
@@ -320,9 +317,6 @@ multiq_leaf(struct Qdisc *sch, unsigned long arg)
 	struct multiq_sched_data *q = qdisc_priv(sch);
 	unsigned long band = arg - 1;
 
-	if (band >= q->bands)
-		return NULL;
-
 	return q->queues[band];
 }
 
@@ -348,36 +342,13 @@ static void multiq_put(struct Qdisc *q, unsigned long cl)
 	return;
 }
 
-static int multiq_change(struct Qdisc *sch, u32 handle, u32 parent,
-			 struct nlattr **tca, unsigned long *arg)
-{
-	unsigned long cl = *arg;
-	struct multiq_sched_data *q = qdisc_priv(sch);
-
-	if (cl - 1 > q->bands)
-		return -ENOENT;
-	return 0;
-}
-
-static int multiq_delete(struct Qdisc *sch, unsigned long cl)
-{
-	struct multiq_sched_data *q = qdisc_priv(sch);
-	if (cl - 1 > q->bands)
-		return -ENOENT;
-	return 0;
-}
-
-
 static int multiq_dump_class(struct Qdisc *sch, unsigned long cl,
 			     struct sk_buff *skb, struct tcmsg *tcm)
 {
 	struct multiq_sched_data *q = qdisc_priv(sch);
 
-	if (cl - 1 > q->bands)
-		return -ENOENT;
 	tcm->tcm_handle |= TC_H_MIN(cl);
-	if (q->queues[cl-1])
-		tcm->tcm_info = q->queues[cl-1]->handle;
+	tcm->tcm_info = q->queues[cl-1]->handle;
 	return 0;
 }
 
@@ -388,6 +359,7 @@ static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 	struct Qdisc *cl_q;
 
 	cl_q = q->queues[cl - 1];
+	cl_q->qstats.qlen = cl_q->q.qlen;
 	if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
 	    gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
 		return -1;
@@ -430,8 +402,6 @@ static const struct Qdisc_class_ops multiq_class_ops = {
 	.leaf		=	multiq_leaf,
 	.get		=	multiq_get,
 	.put		=	multiq_put,
-	.change		=	multiq_change,
-	.delete		=	multiq_delete,
 	.walk		=	multiq_walk,
 	.tcf_chain	=	multiq_find_tcf,
 	.bind_tcf	=	multiq_bind,
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 94cecef..93285ce 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -262,9 +262,6 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 	struct prio_sched_data *q = qdisc_priv(sch);
 	unsigned long band = arg - 1;
 
-	if (band >= q->bands)
-		return -EINVAL;
-
 	if (new == NULL)
 		new = &noop_qdisc;
 
@@ -284,9 +281,6 @@ prio_leaf(struct Qdisc *sch, unsigned long arg)
 	struct prio_sched_data *q = qdisc_priv(sch);
 	unsigned long band = arg - 1;
 
-	if (band >= q->bands)
-		return NULL;
-
 	return q->queues[band];
 }
 
@@ -311,35 +305,13 @@ static void prio_put(struct Qdisc *q, unsigned long cl)
 	return;
 }
 
-static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct nlattr **tca, unsigned long *arg)
-{
-	unsigned long cl = *arg;
-	struct prio_sched_data *q = qdisc_priv(sch);
-
-	if (cl - 1 > q->bands)
-		return -ENOENT;
-	return 0;
-}
-
-static int prio_delete(struct Qdisc *sch, unsigned long cl)
-{
-	struct prio_sched_data *q = qdisc_priv(sch);
-	if (cl - 1 > q->bands)
-		return -ENOENT;
-	return 0;
-}
-
-
 static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb,
 			   struct tcmsg *tcm)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
 
-	if (cl - 1 > q->bands)
-		return -ENOENT;
 	tcm->tcm_handle |= TC_H_MIN(cl);
-	if (q->queues[cl-1])
-		tcm->tcm_info = q->queues[cl-1]->handle;
+	tcm->tcm_info = q->queues[cl-1]->handle;
 	return 0;
 }
 
@@ -350,6 +322,7 @@ static int prio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 	struct Qdisc *cl_q;
 
 	cl_q = q->queues[cl - 1];
+	cl_q->qstats.qlen = cl_q->q.qlen;
 	if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
 	    gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
 		return -1;
@@ -392,8 +365,6 @@ static const struct Qdisc_class_ops prio_class_ops = {
 	.leaf		=	prio_leaf,
 	.get		=	prio_get,
 	.put		=	prio_put,
-	.change		=	prio_change,
-	.delete		=	prio_delete,
 	.walk		=	prio_walk,
 	.tcf_chain	=	prio_find_tcf,
 	.bind_tcf	=	prio_bind,
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 2bdf241..072cdf4 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -268,8 +268,6 @@ static int red_dump_class(struct Qdisc *sch, unsigned long cl,
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 
-	if (cl != 1)
-		return -ENOENT;
 	tcm->tcm_handle |= TC_H_MIN(1);
 	tcm->tcm_info = q->qdisc->handle;
 	return 0;
@@ -308,17 +306,6 @@ static void red_put(struct Qdisc *sch, unsigned long arg)
 	return;
 }
 
-static int red_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-			    struct nlattr **tca, unsigned long *arg)
-{
-	return -ENOSYS;
-}
-
-static int red_delete(struct Qdisc *sch, unsigned long cl)
-{
-	return -ENOSYS;
-}
-
 static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 {
 	if (!walker->stop) {
@@ -331,20 +318,12 @@ static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 	}
 }
 
-static struct tcf_proto **red_find_tcf(struct Qdisc *sch, unsigned long cl)
-{
-	return NULL;
-}
-
 static const struct Qdisc_class_ops red_class_ops = {
 	.graft		=	red_graft,
 	.leaf		=	red_leaf,
 	.get		=	red_get,
 	.put		=	red_put,
-	.change		=	red_change_class,
-	.delete		=	red_delete,
 	.walk		=	red_walk,
-	.tcf_chain	=	red_find_tcf,
 	.dump		=	red_dump_class,
 };
 
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 8706920..cb21380 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -496,12 +496,6 @@ nla_put_failure:
 	return -1;
 }
 
-static int sfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-			    struct nlattr **tca, unsigned long *arg)
-{
-	return -EOPNOTSUPP;
-}
-
 static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
 {
 	return 0;
@@ -560,7 +554,6 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
 
 static const struct Qdisc_class_ops sfq_class_ops = {
 	.get		=	sfq_get,
-	.change		=	sfq_change_class,
 	.tcf_chain	=	sfq_find_tcf,
 	.dump		=	sfq_dump_class,
 	.dump_stats	=	sfq_dump_class_stats,
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index e22dfe8..8fb8107 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -368,9 +368,6 @@ static int tbf_dump_class(struct Qdisc *sch, unsigned long cl,
 {
 	struct tbf_sched_data *q = qdisc_priv(sch);
 
-	if (cl != 1) 	/* only one class */
-		return -ENOENT;
-
 	tcm->tcm_handle |= TC_H_MIN(1);
 	tcm->tcm_info = q->qdisc->handle;
 
@@ -410,17 +407,6 @@ static void tbf_put(struct Qdisc *sch, unsigned long arg)
 {
 }
 
-static int tbf_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-			    struct nlattr **tca, unsigned long *arg)
-{
-	return -ENOSYS;
-}
-
-static int tbf_delete(struct Qdisc *sch, unsigned long arg)
-{
-	return -ENOSYS;
-}
-
 static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 {
 	if (!walker->stop) {
@@ -433,21 +419,13 @@ static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 	}
 }
 
-static struct tcf_proto **tbf_find_tcf(struct Qdisc *sch, unsigned long cl)
-{
-	return NULL;
-}
-
 static const struct Qdisc_class_ops tbf_class_ops =
 {
 	.graft		=	tbf_graft,
 	.leaf		=	tbf_leaf,
 	.get		=	tbf_get,
 	.put		=	tbf_put,
-	.change		=	tbf_change_class,
-	.delete		=	tbf_delete,
 	.walk		=	tbf_walk,
-	.tcf_chain	=	tbf_find_tcf,
 	.dump		=	tbf_dump_class,
 };
 
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 9c002b6..5a002c2 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -268,7 +268,7 @@ static inline int teql_resolve(struct sk_buff *skb,
 	return __teql_resolve(skb, skb_res, dev);
 }
 
-static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct teql_master *master = netdev_priv(dev);
 	struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
@@ -307,14 +307,14 @@ restart:
 
 				if (!netif_tx_queue_stopped(slave_txq) &&
 				    !netif_tx_queue_frozen(slave_txq) &&
-				    slave_ops->ndo_start_xmit(skb, slave) == 0) {
+				    slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) {
 					txq_trans_update(slave_txq);
 					__netif_tx_unlock(slave_txq);
 					master->slaves = NEXT_SLAVE(q);
 					netif_wake_queue(dev);
 					txq->tx_packets++;
 					txq->tx_bytes += length;
-					return 0;
+					return NETDEV_TX_OK;
 				}
 				__netif_tx_unlock(slave_txq);
 			}
@@ -323,7 +323,7 @@ restart:
 			break;
 		case 1:
 			master->slaves = NEXT_SLAVE(q);
-			return 0;
+			return NETDEV_TX_OK;
 		default:
 			nores = 1;
 			break;
@@ -345,7 +345,7 @@ restart:
 drop:
 	txq->tx_dropped++;
 	dev_kfree_skb(skb);
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static int teql_master_open(struct net_device *dev)
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 525864b..8450960 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -112,6 +112,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 	asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000)
 					* 1000;
 	asoc->frag_point = 0;
+	asoc->user_frag = sp->user_frag;
 
 	/* Set the association max_retrans and RTO values from the
 	 * socket values.
@@ -202,6 +203,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
 	asoc->a_rwnd = asoc->rwnd;
 
 	asoc->rwnd_over = 0;
+	asoc->rwnd_press = 0;
 
 	/* Use my own max window until I learn something better.  */
 	asoc->peer.rwnd = SCTP_DEFAULT_MAXWINDOW;
@@ -582,6 +584,33 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
 	    asoc->addip_last_asconf->transport == peer)
 		asoc->addip_last_asconf->transport = NULL;
 
+	/* If we have something on the transmitted list, we have to
+	 * save it off.  The best place is the active path.
+	 */
+	if (!list_empty(&peer->transmitted)) {
+		struct sctp_transport *active = asoc->peer.active_path;
+		struct sctp_chunk *ch;
+
+		/* Reset the transport of each chunk on this list */
+		list_for_each_entry(ch, &peer->transmitted,
+					transmitted_list) {
+			ch->transport = NULL;
+			ch->rtt_in_progress = 0;
+		}
+
+		list_splice_tail_init(&peer->transmitted,
+					&active->transmitted);
+
+		/* Start a T3 timer here in case it wasn't running so
+		 * that these migrated packets have a chance to get
+		 * retrnasmitted.
+		 */
+		if (!timer_pending(&active->T3_rtx_timer))
+			if (!mod_timer(&active->T3_rtx_timer,
+					jiffies + active->rto))
+				sctp_transport_hold(active);
+	}
+
 	asoc->peer.transport_count--;
 
 	sctp_transport_free(peer);
@@ -651,13 +680,15 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 	 */
 	peer->param_flags = asoc->param_flags;
 
+	sctp_transport_route(peer, NULL, sp);
+
 	/* Initialize the pmtu of the transport. */
-	if (peer->param_flags & SPP_PMTUD_ENABLE)
-		sctp_transport_pmtu(peer);
-	else if (asoc->pathmtu)
-		peer->pathmtu = asoc->pathmtu;
-	else
-		peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
+	if (peer->param_flags & SPP_PMTUD_DISABLE) {
+		if (asoc->pathmtu)
+			peer->pathmtu = asoc->pathmtu;
+		else
+			peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
+	}
 
 	/* If this is the first transport addr on this association,
 	 * initialize the association PMTU to the peer's PMTU.
@@ -673,7 +704,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
 			  "%d\n", asoc, asoc->pathmtu);
 	peer->pmtu_pending = 0;
 
-	asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
+	asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu);
 
 	/* The asoc->peer.port might not be meaningful yet, but
 	 * initialize the packet structure anyway.
@@ -810,11 +841,16 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
 		break;
 
 	case SCTP_TRANSPORT_DOWN:
-		/* if the transort was never confirmed, do not transition it
-		 * to inactive state.
+		/* If the transport was never confirmed, do not transition it
+		 * to inactive state.  Also, release the cached route since
+		 * there may be a better route next time.
 		 */
 		if (transport->state != SCTP_UNCONFIRMED)
 			transport->state = SCTP_INACTIVE;
+		else {
+			dst_release(transport->dst);
+			transport->dst = NULL;
+		}
 
 		spc_state = SCTP_ADDR_UNREACHABLE;
 		break;
@@ -1324,9 +1360,8 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
 	}
 
 	if (pmtu) {
-		struct sctp_sock *sp = sctp_sk(asoc->base.sk);
 		asoc->pathmtu = pmtu;
-		asoc->frag_point = sctp_frag_point(sp, pmtu);
+		asoc->frag_point = sctp_frag_point(asoc, pmtu);
 	}
 
 	SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n",
@@ -1369,6 +1404,17 @@ void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned len)
 		asoc->rwnd += len;
 	}
 
+	/* If we had window pressure, start recovering it
+	 * once our rwnd had reached the accumulated pressure
+	 * threshold.  The idea is to recover slowly, but up
+	 * to the initial advertised window.
+	 */
+	if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press) {
+		int change = min(asoc->pathmtu, asoc->rwnd_press);
+		asoc->rwnd += change;
+		asoc->rwnd_press -= change;
+	}
+
 	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd increased by %d to (%u, %u) "
 			  "- %u\n", __func__, asoc, len, asoc->rwnd,
 			  asoc->rwnd_over, asoc->a_rwnd);
@@ -1401,17 +1447,38 @@ void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned len)
 /* Decrease asoc's rwnd by len. */
 void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len)
 {
+	int rx_count;
+	int over = 0;
+
 	SCTP_ASSERT(asoc->rwnd, "rwnd zero", return);
 	SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return);
+
+	if (asoc->ep->rcvbuf_policy)
+		rx_count = atomic_read(&asoc->rmem_alloc);
+	else
+		rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc);
+
+	/* If we've reached or overflowed our receive buffer, announce
+	 * a 0 rwnd if rwnd would still be positive.  Store the
+	 * the pottential pressure overflow so that the window can be restored
+	 * back to original value.
+	 */
+	if (rx_count >= asoc->base.sk->sk_rcvbuf)
+		over = 1;
+
 	if (asoc->rwnd >= len) {
 		asoc->rwnd -= len;
+		if (over) {
+			asoc->rwnd_press = asoc->rwnd;
+			asoc->rwnd = 0;
+		}
 	} else {
 		asoc->rwnd_over = len - asoc->rwnd;
 		asoc->rwnd = 0;
 	}
-	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd decreased by %d to (%u, %u)\n",
+	SCTP_DEBUG_PRINTK("%s: asoc %p rwnd decreased by %d to (%u, %u, %u)\n",
 			  __func__, asoc, len, asoc->rwnd,
-			  asoc->rwnd_over);
+			  asoc->rwnd_over, asoc->rwnd_press);
 }
 
 /* Build the bind address list for the association based on info from the
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 6d5944a..13a6fba 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -510,9 +510,28 @@ int sctp_in_scope(const union sctp_addr *addr, sctp_scope_t scope)
 	 * of requested destination address, sender and receiver
 	 * SHOULD include all of its addresses with level greater
 	 * than or equal to L.
+	 *
+	 * Address scoping can be selectively controlled via sysctl
+	 * option
 	 */
-	if (addr_scope <= scope)
+	switch (sctp_scope_policy) {
+	case SCTP_SCOPE_POLICY_DISABLE:
 		return 1;
+	case SCTP_SCOPE_POLICY_ENABLE:
+		if (addr_scope <= scope)
+			return 1;
+		break;
+	case SCTP_SCOPE_POLICY_PRIVATE:
+		if (addr_scope <= scope || SCTP_SCOPE_PRIVATE == addr_scope)
+			return 1;
+		break;
+	case SCTP_SCOPE_POLICY_LINK:
+		if (addr_scope <= scope || SCTP_SCOPE_LINK == addr_scope)
+			return 1;
+		break;
+	default:
+		break;
+	}
 
 	return 0;
 }
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 1748ef9..acf7c4d 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -59,6 +59,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
 	msg->can_abandon = 0;
 	msg->expires_at = 0;
 	INIT_LIST_HEAD(&msg->chunks);
+	msg->msg_size = 0;
 }
 
 /* Allocate and initialize datamsg. */
@@ -73,6 +74,19 @@ SCTP_STATIC struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp)
 	return msg;
 }
 
+void sctp_datamsg_free(struct sctp_datamsg *msg)
+{
+	struct sctp_chunk *chunk;
+
+	/* This doesn't have to be a _safe vairant because
+	 * sctp_chunk_free() only drops the refs.
+	 */
+	list_for_each_entry(chunk, &msg->chunks, frag_list)
+		sctp_chunk_free(chunk);
+
+	sctp_datamsg_put(msg);
+}
+
 /* Final destructruction of datamsg memory. */
 static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
 {
@@ -142,6 +156,7 @@ static void sctp_datamsg_assign(struct sctp_datamsg *msg, struct sctp_chunk *chu
 {
 	sctp_datamsg_hold(msg);
 	chunk->msg = msg;
+	msg->msg_size += chunk->skb->len;
 }
 
 
@@ -158,6 +173,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 {
 	int max, whole, i, offset, over, err;
 	int len, first_len;
+	int max_data;
 	struct sctp_chunk *chunk;
 	struct sctp_datamsg *msg;
 	struct list_head *pos, *temp;
@@ -179,8 +195,14 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 				  __func__, msg, msg->expires_at, jiffies);
 	}
 
-	max = asoc->frag_point;
+	/* This is the biggest possible DATA chunk that can fit into
+	 * the packet
+	 */
+	max_data = asoc->pathmtu -
+		sctp_sk(asoc->base.sk)->pf->af->net_header_len -
+		sizeof(struct sctphdr) - sizeof(struct sctp_data_chunk);
 
+	max = asoc->frag_point;
 	/* If the the peer requested that we authenticate DATA chunks
 	 * we need to accound for bundling of the AUTH chunks along with
 	 * DATA.
@@ -189,23 +211,41 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
 		struct sctp_hmac *hmac_desc = sctp_auth_asoc_get_hmac(asoc);
 
 		if (hmac_desc)
-			max -= WORD_ROUND(sizeof(sctp_auth_chunk_t) +
+			max_data -= WORD_ROUND(sizeof(sctp_auth_chunk_t) +
 					    hmac_desc->hmac_len);
 	}
 
+	/* Now, check if we need to reduce our max */
+	if (max > max_data)
+		max = max_data;
+
 	whole = 0;
 	first_len = max;
 
+	/* Check to see if we have a pending SACK and try to let it be bundled
+	 * with this message.  Do this if we don't have any data queued already.
+	 * To check that, look at out_qlen and retransmit list.
+	 * NOTE: we will not reduce to account for SACK, if the message would
+	 * not have been fragmented.
+	 */
+	if (timer_pending(&asoc->timers[SCTP_EVENT_TIMEOUT_SACK]) &&
+	    asoc->outqueue.out_qlen == 0 &&
+	    list_empty(&asoc->outqueue.retransmit) &&
+	    msg_len > max)
+		max_data -= WORD_ROUND(sizeof(sctp_sack_chunk_t));
+
 	/* Encourage Cookie-ECHO bundling. */
-	if (asoc->state < SCTP_STATE_COOKIE_ECHOED) {
-		whole = msg_len / (max - SCTP_ARBITRARY_COOKIE_ECHO_LEN);
-
-		/* Account for the DATA to be bundled with the COOKIE-ECHO. */
-		if (whole) {
-			first_len = max - SCTP_ARBITRARY_COOKIE_ECHO_LEN;
-			msg_len -= first_len;
-			whole = 1;
-		}
+	if (asoc->state < SCTP_STATE_COOKIE_ECHOED)
+		max_data -= SCTP_ARBITRARY_COOKIE_ECHO_LEN;
+
+	/* Now that we adjusted completely, reset first_len */
+	if (first_len > max_data)
+		first_len = max_data;
+
+	/* Account for a different sized first fragment */
+	if (msg_len >= first_len) {
+		msg_len -= first_len;
+		whole = 1;
 	}
 
 	/* How many full sized?  How many bytes leftover? */
diff --git a/net/sctp/debug.c b/net/sctp/debug.c
index 7ff548a..bf24fa6 100644
--- a/net/sctp/debug.c
+++ b/net/sctp/debug.c
@@ -52,7 +52,7 @@ int sctp_debug_flag = 1;	/* Initially enable DEBUG */
 #endif	/* SCTP_DEBUG */
 
 /* These are printable forms of Chunk ID's from section 3.1.  */
-static const char *sctp_cid_tbl[SCTP_NUM_BASE_CHUNK_TYPES] = {
+static const char *const sctp_cid_tbl[SCTP_NUM_BASE_CHUNK_TYPES] = {
 	"DATA",
 	"INIT",
 	"INIT_ACK",
@@ -97,7 +97,7 @@ const char *sctp_cname(const sctp_subtype_t cid)
 }
 
 /* These are printable forms of the states.  */
-const char *sctp_state_tbl[SCTP_STATE_NUM_STATES] = {
+const char *const sctp_state_tbl[SCTP_STATE_NUM_STATES] = {
 	"STATE_EMPTY",
 	"STATE_CLOSED",
 	"STATE_COOKIE_WAIT",
@@ -110,7 +110,7 @@ const char *sctp_state_tbl[SCTP_STATE_NUM_STATES] = {
 };
 
 /* Events that could change the state of an association.  */
-const char *sctp_evttype_tbl[] = {
+const char *const sctp_evttype_tbl[] = {
 	"EVENT_T_unknown",
 	"EVENT_T_CHUNK",
 	"EVENT_T_TIMEOUT",
@@ -119,7 +119,7 @@ const char *sctp_evttype_tbl[] = {
 };
 
 /* Return value of a state function */
-const char *sctp_status_tbl[] = {
+const char *const sctp_status_tbl[] = {
 	"DISPOSITION_DISCARD",
 	"DISPOSITION_CONSUME",
 	"DISPOSITION_NOMEM",
@@ -132,7 +132,7 @@ const char *sctp_status_tbl[] = {
 };
 
 /* Printable forms of primitives */
-static const char *sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = {
+static const char *const sctp_primitive_tbl[SCTP_NUM_PRIMITIVE_TYPES] = {
 	"PRIMITIVE_ASSOCIATE",
 	"PRIMITIVE_SHUTDOWN",
 	"PRIMITIVE_ABORT",
@@ -149,7 +149,7 @@ const char *sctp_pname(const sctp_subtype_t id)
 	return "unknown_primitive";
 }
 
-static const char *sctp_other_tbl[] = {
+static const char *const sctp_other_tbl[] = {
 	"NO_PENDING_TSN",
 	"ICMP_PROTO_UNREACH",
 };
@@ -162,7 +162,7 @@ const char *sctp_oname(const sctp_subtype_t id)
 	return "unknown 'other' event";
 }
 
-static const char *sctp_timer_tbl[] = {
+static const char *const sctp_timer_tbl[] = {
 	"TIMEOUT_NONE",
 	"TIMEOUT_T1_COOKIE",
 	"TIMEOUT_T1_INIT",
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 6a4b190..bb280e6 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -949,7 +949,7 @@ static int sctp6_rcv(struct sk_buff *skb)
 	return sctp_rcv(skb) ? -1 : 0;
 }
 
-static struct inet6_protocol sctpv6_protocol = {
+static const struct inet6_protocol sctpv6_protocol = {
 	.handler      = sctp6_rcv,
 	.err_handler  = sctp_v6_err,
 	.flags        = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
diff --git a/net/sctp/output.c b/net/sctp/output.c
index b94c211..5cbda8f 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -61,8 +61,24 @@
 #include <net/sctp/checksum.h>
 
 /* Forward declarations for private helpers. */
-static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
+static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
 					   struct sctp_chunk *chunk);
+static void sctp_packet_append_data(struct sctp_packet *packet,
+					   struct sctp_chunk *chunk);
+static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet,
+					struct sctp_chunk *chunk,
+					u16 chunk_len);
+
+static void sctp_packet_reset(struct sctp_packet *packet)
+{
+	packet->size = packet->overhead;
+	packet->has_cookie_echo = 0;
+	packet->has_sack = 0;
+	packet->has_data = 0;
+	packet->has_auth = 0;
+	packet->ipfragok = 0;
+	packet->auth = NULL;
+}
 
 /* Config a packet.
  * This appears to be a followup set of initializations.
@@ -75,13 +91,8 @@ struct sctp_packet *sctp_packet_config(struct sctp_packet *packet,
 	SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __func__,
 			  packet, vtag);
 
+	sctp_packet_reset(packet);
 	packet->vtag = vtag;
-	packet->has_cookie_echo = 0;
-	packet->has_sack = 0;
-	packet->has_auth = 0;
-	packet->has_data = 0;
-	packet->ipfragok = 0;
-	packet->auth = NULL;
 
 	if (ecn_capable && sctp_packet_empty(packet)) {
 		chunk = sctp_get_ecne_prepend(packet->transport->asoc);
@@ -119,15 +130,9 @@ struct sctp_packet *sctp_packet_init(struct sctp_packet *packet,
 	}
 	overhead += sizeof(struct sctphdr);
 	packet->overhead = overhead;
-	packet->size = overhead;
+	sctp_packet_reset(packet);
 	packet->vtag = 0;
-	packet->has_cookie_echo = 0;
-	packet->has_sack = 0;
-	packet->has_auth = 0;
-	packet->has_data = 0;
-	packet->ipfragok = 0;
 	packet->malloced = 0;
-	packet->auth = NULL;
 	return packet;
 }
 
@@ -204,7 +209,7 @@ static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt,
 	/* See if this is an auth chunk we are bundling or if
 	 * auth is already bundled.
 	 */
-	if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->auth)
+	if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->has_auth)
 		return retval;
 
 	/* if the peer did not request this chunk to be authenticated,
@@ -234,18 +239,19 @@ static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt,
 	if (sctp_chunk_is_data(chunk) && !pkt->has_sack &&
 	    !pkt->has_cookie_echo) {
 		struct sctp_association *asoc;
+		struct timer_list *timer;
 		asoc = pkt->transport->asoc;
+		timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
 
-		if (asoc->a_rwnd > asoc->rwnd) {
+		/* If the SACK timer is running, we have a pending SACK */
+		if (timer_pending(timer)) {
 			struct sctp_chunk *sack;
 			asoc->a_rwnd = asoc->rwnd;
 			sack = sctp_make_sack(asoc);
 			if (sack) {
-				struct timer_list *timer;
 				retval = sctp_packet_append_chunk(pkt, sack);
 				asoc->peer.sack_needed = 0;
-				timer = &asoc->timers[SCTP_EVENT_TIMEOUT_SACK];
-				if (timer_pending(timer) && del_timer(timer))
+				if (del_timer(timer))
 					sctp_association_put(asoc);
 			}
 		}
@@ -261,13 +267,20 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
 {
 	sctp_xmit_t retval = SCTP_XMIT_OK;
 	__u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length));
-	size_t psize;
-	size_t pmtu;
-	int too_big;
 
 	SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __func__, packet,
 			  chunk);
 
+	/* Data chunks are special.  Before seeing what else we can
+	 * bundle into this packet, check to see if we are allowed to
+	 * send this DATA.
+	 */
+	if (sctp_chunk_is_data(chunk)) {
+		retval = sctp_packet_can_append_data(packet, chunk);
+		if (retval != SCTP_XMIT_OK)
+			goto finish;
+	}
+
 	/* Try to bundle AUTH chunk */
 	retval = sctp_packet_bundle_auth(packet, chunk);
 	if (retval != SCTP_XMIT_OK)
@@ -278,51 +291,16 @@ sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *packet,
 	if (retval != SCTP_XMIT_OK)
 		goto finish;
 
-	psize = packet->size;
-	pmtu  = ((packet->transport->asoc) ?
-		 (packet->transport->asoc->pathmtu) :
-		 (packet->transport->pathmtu));
-
-	too_big = (psize + chunk_len > pmtu);
-
-	/* Decide if we need to fragment or resubmit later. */
-	if (too_big) {
-		/* It's OK to fragmet at IP level if any one of the following
-		 * is true:
-		 * 	1. The packet is empty (meaning this chunk is greater
-		 * 	   the MTU)
-		 * 	2. The chunk we are adding is a control chunk
-		 * 	3. The packet doesn't have any data in it yet and data
-		 * 	requires authentication.
-		 */
-		if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk) ||
-		    (!packet->has_data && chunk->auth)) {
-			/* We no longer do re-fragmentation.
-			 * Just fragment at the IP layer, if we
-			 * actually hit this condition
-			 */
-			packet->ipfragok = 1;
-			goto append;
-
-		} else {
-			retval = SCTP_XMIT_PMTU_FULL;
-			goto finish;
-		}
-	}
-
-append:
-	/* We believe that this chunk is OK to add to the packet (as
-	 * long as we have the cwnd for it).
-	 */
+	/* Check to see if this chunk will fit into the packet */
+	retval = sctp_packet_will_fit(packet, chunk, chunk_len);
+	if (retval != SCTP_XMIT_OK)
+		goto finish;
 
-	/* DATA is a special case since we must examine both rwnd and cwnd
-	 * before we send DATA.
-	 */
+	/* We believe that this chunk is OK to add to the packet */
 	switch (chunk->chunk_hdr->type) {
 	    case SCTP_CID_DATA:
-		retval = sctp_packet_append_data(packet, chunk);
-		if (SCTP_XMIT_OK != retval)
-			goto finish;
+		/* Account for the data being in the packet */
+		sctp_packet_append_data(packet, chunk);
 		/* Disallow SACK bundling after DATA. */
 		packet->has_sack = 1;
 		/* Disallow AUTH bundling after DATA */
@@ -598,7 +576,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
 	(*tp->af_specific->sctp_xmit)(nskb, tp);
 
 out:
-	packet->size = packet->overhead;
+	sctp_packet_reset(packet);
 	return err;
 no_route:
 	kfree_skb(nskb);
@@ -632,16 +610,15 @@ nomem:
  * 2nd Level Abstractions
  ********************************************************************/
 
-/* This private function handles the specifics of appending DATA chunks.  */
-static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
+/* This private function check to see if a chunk can be added */
+static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
 					   struct sctp_chunk *chunk)
 {
 	sctp_xmit_t retval = SCTP_XMIT_OK;
-	size_t datasize, rwnd, inflight;
+	size_t datasize, rwnd, inflight, flight_size;
 	struct sctp_transport *transport = packet->transport;
 	__u32 max_burst_bytes;
 	struct sctp_association *asoc = transport->asoc;
-	struct sctp_sock *sp = sctp_sk(asoc->base.sk);
 	struct sctp_outq *q = &asoc->outqueue;
 
 	/* RFC 2960 6.1  Transmission of DATA Chunks
@@ -658,7 +635,8 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
 	 */
 
 	rwnd = asoc->peer.rwnd;
-	inflight = asoc->outqueue.outstanding_bytes;
+	inflight = q->outstanding_bytes;
+	flight_size = transport->flight_size;
 
 	datasize = sctp_data_size(chunk);
 
@@ -681,8 +659,8 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
 	 *		cwnd = flightsize + Max.Burst * MTU
 	 */
 	max_burst_bytes = asoc->max_burst * asoc->pathmtu;
-	if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
-		transport->cwnd = transport->flight_size + max_burst_bytes;
+	if ((flight_size + max_burst_bytes) < transport->cwnd) {
+		transport->cwnd = flight_size + max_burst_bytes;
 		SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
 				  "transport: %p, cwnd: %d, "
 				  "ssthresh: %d, flight_size: %d, "
@@ -707,7 +685,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
 	 *    ignore the value of cwnd and SHOULD NOT delay retransmission.
 	 */
 	if (chunk->fast_retransmit != SCTP_NEED_FRTX)
-		if (transport->flight_size >= transport->cwnd) {
+		if (flight_size >= transport->cwnd) {
 			retval = SCTP_XMIT_RWND_FULL;
 			goto finish;
 		}
@@ -717,20 +695,36 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
 	 * if any previously transmitted data on the connection remains
 	 * unacknowledged.
 	 */
-	if (!sp->nodelay && sctp_packet_empty(packet) &&
-	    q->outstanding_bytes && sctp_state(asoc, ESTABLISHED)) {
-		unsigned len = datasize + q->out_qlen;
+	if (!sctp_sk(asoc->base.sk)->nodelay && sctp_packet_empty(packet) &&
+	    inflight && sctp_state(asoc, ESTABLISHED)) {
+		unsigned max = transport->pathmtu - packet->overhead;
+		unsigned len = chunk->skb->len + q->out_qlen;
 
 		/* Check whether this chunk and all the rest of pending
 		 * data will fit or delay in hopes of bundling a full
 		 * sized packet.
+		 * Don't delay large message writes that may have been
+		 * fragmeneted into small peices.
 		 */
-		if (len < asoc->frag_point) {
+		if ((len < max) && (chunk->msg->msg_size < max)) {
 			retval = SCTP_XMIT_NAGLE_DELAY;
 			goto finish;
 		}
 	}
 
+finish:
+	return retval;
+}
+
+/* This private function does management things when adding DATA chunk */
+static void sctp_packet_append_data(struct sctp_packet *packet,
+				struct sctp_chunk *chunk)
+{
+	struct sctp_transport *transport = packet->transport;
+	size_t datasize = sctp_data_size(chunk);
+	struct sctp_association *asoc = transport->asoc;
+	u32 rwnd = asoc->peer.rwnd;
+
 	/* Keep track of how many bytes are in flight over this transport. */
 	transport->flight_size += datasize;
 
@@ -753,7 +747,45 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
 	/* Has been accepted for transmission. */
 	if (!asoc->peer.prsctp_capable)
 		chunk->msg->can_abandon = 0;
+}
+
+static sctp_xmit_t sctp_packet_will_fit(struct sctp_packet *packet,
+					struct sctp_chunk *chunk,
+					u16 chunk_len)
+{
+	size_t psize;
+	size_t pmtu;
+	int too_big;
+	sctp_xmit_t retval = SCTP_XMIT_OK;
+
+	psize = packet->size;
+	pmtu  = ((packet->transport->asoc) ?
+		(packet->transport->asoc->pathmtu) :
+		(packet->transport->pathmtu));
+
+	too_big = (psize + chunk_len > pmtu);
+
+	/* Decide if we need to fragment or resubmit later. */
+	if (too_big) {
+		/* It's OK to fragmet at IP level if any one of the following
+		 * is true:
+		 * 	1. The packet is empty (meaning this chunk is greater
+		 * 	   the MTU)
+		 * 	2. The chunk we are adding is a control chunk
+		 * 	3. The packet doesn't have any data in it yet and data
+		 * 	requires authentication.
+		 */
+		if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk) ||
+		    (!packet->has_data && chunk->auth)) {
+			/* We no longer do re-fragmentation.
+			 * Just fragment at the IP layer, if we
+			 * actually hit this condition
+			 */
+			packet->ipfragok = 1;
+		} else {
+			retval = SCTP_XMIT_PMTU_FULL;
+		}
+	}
 
-finish:
 	return retval;
 }
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index d765fc5..c9f20e2 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -406,8 +406,9 @@ void sctp_retransmit_mark(struct sctp_outq *q,
 			 * not be retransmitted
 			 */
 			if (!chunk->tsn_gap_acked) {
-				chunk->transport->flight_size -=
-						sctp_data_size(chunk);
+				if (chunk->transport)
+					chunk->transport->flight_size -=
+							sctp_data_size(chunk);
 				q->outstanding_bytes -= sctp_data_size(chunk);
 				q->asoc->peer.rwnd += (sctp_data_size(chunk) +
 							sizeof(struct sk_buff));
@@ -443,7 +444,8 @@ void sctp_retransmit_mark(struct sctp_outq *q,
 			q->asoc->peer.rwnd += (sctp_data_size(chunk) +
 						sizeof(struct sk_buff));
 			q->outstanding_bytes -= sctp_data_size(chunk);
-			transport->flight_size -= sctp_data_size(chunk);
+			if (chunk->transport)
+				transport->flight_size -= sctp_data_size(chunk);
 
 			/* sctpimpguide-05 Section 2.8.2
 			 * M5) If a T3-rtx timer expires, the
@@ -1310,6 +1312,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 	__u32 rtt;
 	__u8 restart_timer = 0;
 	int bytes_acked = 0;
+	int migrate_bytes = 0;
 
 	/* These state variables are for coherent debug output. --xguo */
 
@@ -1343,8 +1346,9 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 			 * considering it as 'outstanding'.
 			 */
 			if (!tchunk->tsn_gap_acked) {
-				tchunk->transport->flight_size -=
-						sctp_data_size(tchunk);
+				if (tchunk->transport)
+					tchunk->transport->flight_size -=
+							sctp_data_size(tchunk);
 				q->outstanding_bytes -= sctp_data_size(tchunk);
 			}
 			continue;
@@ -1378,6 +1382,20 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 								  rtt);
 				}
 			}
+
+			/* If the chunk hasn't been marked as ACKED,
+			 * mark it and account bytes_acked if the
+			 * chunk had a valid transport (it will not
+			 * have a transport if ASCONF had deleted it
+			 * while DATA was outstanding).
+			 */
+			if (!tchunk->tsn_gap_acked) {
+				tchunk->tsn_gap_acked = 1;
+				bytes_acked += sctp_data_size(tchunk);
+				if (!tchunk->transport)
+					migrate_bytes += sctp_data_size(tchunk);
+			}
+
 			if (TSN_lte(tsn, sack_ctsn)) {
 				/* RFC 2960  6.3.2 Retransmission Timer Rules
 				 *
@@ -1391,8 +1409,6 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 				restart_timer = 1;
 
 				if (!tchunk->tsn_gap_acked) {
-					tchunk->tsn_gap_acked = 1;
-					bytes_acked += sctp_data_size(tchunk);
 					/*
 					 * SFR-CACC algorithm:
 					 * 2) If the SACK contains gap acks
@@ -1432,10 +1448,6 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 				 * older than that newly acknowledged DATA
 				 * chunk, are qualified as 'Stray DATA chunks'.
 				 */
-				if (!tchunk->tsn_gap_acked) {
-					tchunk->tsn_gap_acked = 1;
-					bytes_acked += sctp_data_size(tchunk);
-				}
 				list_add_tail(lchunk, &tlist);
 			}
 
@@ -1491,7 +1503,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 						  tsn);
 				tchunk->tsn_gap_acked = 0;
 
-				bytes_acked -= sctp_data_size(tchunk);
+				if (tchunk->transport)
+					bytes_acked -= sctp_data_size(tchunk);
 
 				/* RFC 2960 6.3.2 Retransmission Timer Rules
 				 *
@@ -1561,6 +1574,14 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 #endif /* SCTP_DEBUG */
 	if (transport) {
 		if (bytes_acked) {
+			/* We may have counted DATA that was migrated
+			 * to this transport due to DEL-IP operation.
+			 * Subtract those bytes, since the were never
+			 * send on this transport and shouldn't be
+			 * credited to this transport.
+			 */
+			bytes_acked -= migrate_bytes;
+
 			/* 8.2. When an outstanding TSN is acknowledged,
 			 * the endpoint shall clear the error counter of
 			 * the destination transport address to which the
@@ -1589,7 +1610,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 			transport->flight_size -= bytes_acked;
 			if (transport->flight_size == 0)
 				transport->partial_bytes_acked = 0;
-			q->outstanding_bytes -= bytes_acked;
+			q->outstanding_bytes -= bytes_acked + migrate_bytes;
 		} else {
 			/* RFC 2960 6.1, sctpimpguide-06 2.15.2
 			 * When a sender is doing zero window probing, it
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index f268910..d093cbf 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -512,10 +512,8 @@ int __init sctp_remaddr_proc_init(void)
 {
 	struct proc_dir_entry *p;
 
-	p = create_proc_entry("remaddr", S_IRUGO, proc_net_sctp);
+	p = proc_create("remaddr", S_IRUGO, proc_net_sctp, &sctp_remaddr_seq_fops);
 	if (!p)
 		return -ENOMEM;
-	p->proc_fops = &sctp_remaddr_seq_fops;
-
 	return 0;
 }
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index a76da65..c557f1f 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -431,16 +431,14 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
  * of requested destination address, sender and receiver
  * SHOULD include all of its addresses with level greater
  * than or equal to L.
+ *
+ * IPv4 scoping can be controlled through sysctl option
+ * net.sctp.addr_scope_policy
  */
 static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
 {
 	sctp_scope_t retval;
 
-	/* Should IPv4 scoping be a sysctl configurable option
-	 * so users can turn it off (default on) for certain
-	 * unconventional networking environments?
-	 */
-
 	/* Check for unusable SCTP addresses. */
 	if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) {
 		retval =  SCTP_SCOPE_UNUSABLE;
@@ -926,7 +924,7 @@ static struct inet_protosw sctp_stream_protosw = {
 };
 
 /* Register with IP layer.  */
-static struct net_protocol sctp_protocol = {
+static const struct net_protocol sctp_protocol = {
 	.handler     = sctp_rcv,
 	.err_handler = sctp_v4_err,
 	.no_policy   = 1,
@@ -1259,6 +1257,9 @@ SCTP_STATIC __init int sctp_init(void)
 	/* Disable AUTH by default. */
 	sctp_auth_enable = 0;
 
+	/* Set SCOPE policy to enabled */
+	sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE;
+
 	sctp_sysctl_register();
 
 	INIT_LIST_HEAD(&sctp_address_families);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 61cc607..9d881a6 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2861,6 +2861,11 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 	addr_param = (union sctp_addr_param *)
 			((void *)asconf_param + sizeof(sctp_addip_param_t));
 
+	if (asconf_param->param_hdr.type != SCTP_PARAM_ADD_IP &&
+	    asconf_param->param_hdr.type != SCTP_PARAM_DEL_IP &&
+	    asconf_param->param_hdr.type != SCTP_PARAM_SET_PRIMARY)
+		return SCTP_ERROR_UNKNOWN_PARAM;
+
 	switch (addr_param->v4.param_hdr.type) {
 	case SCTP_PARAM_IPV6_ADDRESS:
 		if (!asoc->peer.ipv6_address)
@@ -2958,9 +2963,6 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 
 		sctp_assoc_set_primary(asoc, peer);
 		break;
-	default:
-		return SCTP_ERROR_UNKNOWN_PARAM;
-		break;
 	}
 
 	return SCTP_ERROR_NO_ERROR;
@@ -3104,7 +3106,7 @@ done:
 }
 
 /* Process a asconf parameter that is successfully acked. */
-static int sctp_asconf_param_success(struct sctp_association *asoc,
+static void sctp_asconf_param_success(struct sctp_association *asoc,
 				     sctp_addip_param_t *asconf_param)
 {
 	struct sctp_af *af;
@@ -3113,7 +3115,6 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
 	union sctp_addr_param *addr_param;
 	struct sctp_transport *transport;
 	struct sctp_sockaddr_entry *saddr;
-	int retval = 0;
 
 	addr_param = (union sctp_addr_param *)
 			((void *)asconf_param + sizeof(sctp_addip_param_t));
@@ -3133,10 +3134,18 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
 				saddr->state = SCTP_ADDR_SRC;
 		}
 		local_bh_enable();
+		list_for_each_entry(transport, &asoc->peer.transport_addr_list,
+				transports) {
+			if (transport->state == SCTP_ACTIVE)
+				continue;
+			dst_release(transport->dst);
+			sctp_transport_route(transport, NULL,
+					     sctp_sk(asoc->base.sk));
+		}
 		break;
 	case SCTP_PARAM_DEL_IP:
 		local_bh_disable();
-		retval = sctp_del_bind_addr(bp, &addr);
+		sctp_del_bind_addr(bp, &addr);
 		local_bh_enable();
 		list_for_each_entry(transport, &asoc->peer.transport_addr_list,
 				transports) {
@@ -3148,8 +3157,6 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
 	default:
 		break;
 	}
-
-	return retval;
 }
 
 /* Get the corresponding ASCONF response error code from the ASCONF_ACK chunk
@@ -3266,7 +3273,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
 
 		switch (err_code) {
 		case SCTP_ERROR_NO_ERROR:
-			retval = sctp_asconf_param_success(asoc, asconf_param);
+			sctp_asconf_param_success(asoc, asconf_param);
 			break;
 
 		case SCTP_ERROR_RSRC_LOW:
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 86426aa..8674d49 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -440,14 +440,26 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
 	/* The check for association's overall error counter exceeding the
 	 * threshold is done in the state function.
 	 */
-	/* When probing UNCONFIRMED addresses, the association overall
-	 * error count is NOT incremented
+	/* We are here due to a timer expiration.  If the timer was
+	 * not a HEARTBEAT, then normal error tracking is done.
+	 * If the timer was a heartbeat, we only increment error counts
+	 * when we already have an outstanding HEARTBEAT that has not
+	 * been acknowledged.
+	 * Additionaly, some tranport states inhibit error increments.
 	 */
-	if (transport->state != SCTP_UNCONFIRMED)
+	if (!is_hb) {
 		asoc->overall_error_count++;
+		if (transport->state != SCTP_INACTIVE)
+			transport->error_count++;
+	 } else if (transport->hb_sent) {
+		if (transport->state != SCTP_UNCONFIRMED)
+			asoc->overall_error_count++;
+		if (transport->state != SCTP_INACTIVE)
+			transport->error_count++;
+	}
 
 	if (transport->state != SCTP_INACTIVE &&
-	    (transport->error_count++ >= transport->pathmaxrxt)) {
+	    (transport->error_count > transport->pathmaxrxt)) {
 		SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
 					 " transport IP: port:%d failed.\n",
 					 asoc,
@@ -931,6 +943,27 @@ static void sctp_cmd_t1_timer_update(struct sctp_association *asoc,
 
 }
 
+/* Send the whole message, chunk by chunk, to the outqueue.
+ * This way the whole message is queued up and bundling if
+ * encouraged for small fragments.
+ */
+static int sctp_cmd_send_msg(struct sctp_association *asoc,
+				struct sctp_datamsg *msg)
+{
+	struct sctp_chunk *chunk;
+	int error = 0;
+
+	list_for_each_entry(chunk, &msg->chunks, frag_list) {
+		error = sctp_outq_tail(&asoc->outqueue, chunk);
+		if (error)
+			break;
+	}
+
+	return error;
+}
+
+
+
 /* These three macros allow us to pull the debugging code out of the
  * main flow of sctp_do_sm() to keep attention focused on the real
  * functionality there.
@@ -1500,7 +1533,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 		case SCTP_CMD_PROCESS_CTSN:
 			/* Dummy up a SACK for processing. */
 			sackh.cum_tsn_ack = cmd->obj.be32;
-			sackh.a_rwnd = 0;
+			sackh.a_rwnd = asoc->peer.rwnd +
+					asoc->outqueue.outstanding_bytes;
 			sackh.num_gap_ack_blocks = 0;
 			sackh.num_dup_tsns = 0;
 			sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_SACK,
@@ -1575,7 +1609,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 		case SCTP_CMD_UPDATE_INITTAG:
 			asoc->peer.i.init_tag = cmd->obj.u32;
 			break;
-
+		case SCTP_CMD_SEND_MSG:
+			if (!asoc->outqueue.cork) {
+				sctp_outq_cork(&asoc->outqueue);
+				local_cork = 1;
+			}
+			error = sctp_cmd_send_msg(asoc, cmd->obj.msg);
+			break;
 		default:
 			printk(KERN_WARNING "Impossible command: %u, %p\n",
 			       cmd->verb, cmd->obj.ptr);
@@ -1593,9 +1633,9 @@ out:
 	 */
 	if (asoc && SCTP_EVENT_T_CHUNK == event_type && chunk) {
 		if (chunk->end_of_packet || chunk->singleton)
-			sctp_outq_uncork(&asoc->outqueue);
+			error = sctp_outq_uncork(&asoc->outqueue);
 	} else if (local_cork)
-			sctp_outq_uncork(&asoc->outqueue);
+		error = sctp_outq_uncork(&asoc->outqueue);
 	return error;
 nomem:
 	error = -ENOMEM;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 7288192..c8fae19 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -334,6 +334,15 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
 	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_init_chunk_t)))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* If the INIT is coming toward a closing socket, we'll send back
+	 * and ABORT.  Essentially, this catches the race of INIT being
+	 * backloged to the socket at the same time as the user isses close().
+	 * Since the socket and all its associations are going away, we
+	 * can treat this OOTB
+	 */
+	if (sctp_sstate(ep->base.sk, CLOSING))
+		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+
 	/* Verify the INIT chunk before processing it. */
 	err_chunk = NULL;
 	if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
@@ -962,7 +971,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
 {
 	struct sctp_transport *transport = (struct sctp_transport *) arg;
 
-	if (asoc->overall_error_count > asoc->max_retrans) {
+	if (asoc->overall_error_count >= asoc->max_retrans) {
 		sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
 				SCTP_ERROR(ETIMEDOUT));
 		/* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
@@ -1106,7 +1115,8 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
 	/* Make sure that the HEARTBEAT-ACK chunk has a valid length.  */
-	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_heartbeat_chunk_t)))
+	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t) +
+					    sizeof(sctp_sender_hb_info_t)))
 		return sctp_sf_violation_chunklen(ep, asoc, type, arg,
 						  commands);
 
@@ -2561,6 +2571,12 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
 	chunk->subh.shutdown_hdr = sdh;
 	ctsn = ntohl(sdh->cum_tsn_ack);
 
+	if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
+		SCTP_DEBUG_PRINTK("ctsn %x\n", ctsn);
+		SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n", asoc->ctsn_ack_point);
+		return SCTP_DISPOSITION_DISCARD;
+	}
+
 	/* If Cumulative TSN Ack beyond the max tsn currently
 	 * send, terminating the association and respond to the
 	 * sender with an ABORT.
@@ -2624,6 +2640,7 @@ sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep,
 {
 	struct sctp_chunk *chunk = arg;
 	sctp_shutdownhdr_t *sdh;
+	__u32 ctsn;
 
 	if (!sctp_vtag_verify(chunk, asoc))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2635,12 +2652,19 @@ sctp_disposition_t sctp_sf_do_9_2_shut_ctsn(const struct sctp_endpoint *ep,
 						  commands);
 
 	sdh = (sctp_shutdownhdr_t *)chunk->skb->data;
+	ctsn = ntohl(sdh->cum_tsn_ack);
+
+	if (TSN_lt(ctsn, asoc->ctsn_ack_point)) {
+		SCTP_DEBUG_PRINTK("ctsn %x\n", ctsn);
+		SCTP_DEBUG_PRINTK("ctsn_ack_point %x\n", asoc->ctsn_ack_point);
+		return SCTP_DISPOSITION_DISCARD;
+	}
 
 	/* If Cumulative TSN Ack beyond the max tsn currently
 	 * send, terminating the association and respond to the
 	 * sender with an ABORT.
 	 */
-	if (!TSN_lt(ntohl(sdh->cum_tsn_ack), asoc->next_tsn))
+	if (!TSN_lt(ctsn, asoc->next_tsn))
 		return sctp_sf_violation_ctsn(ep, asoc, type, arg, commands);
 
 	/* verify, by checking the Cumulative TSN Ack field of the
@@ -2867,6 +2891,9 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
 		goto discard_force;
 	case SCTP_IERROR_NO_DATA:
 		goto consume;
+	case SCTP_IERROR_PROTO_VIOLATION:
+		return sctp_sf_abort_violation(ep, asoc, chunk, commands,
+			(u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t));
 	default:
 		BUG();
 	}
@@ -2977,6 +3004,9 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
 		break;
 	case SCTP_IERROR_NO_DATA:
 		goto consume;
+	case SCTP_IERROR_PROTO_VIOLATION:
+		return sctp_sf_abort_violation(ep, asoc, chunk, commands,
+			(u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t));
 	default:
 		BUG();
 	}
@@ -3519,6 +3549,12 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
 		asconf_ack = sctp_assoc_lookup_asconf_ack(asoc, hdr->serial);
 		if (!asconf_ack)
 			return SCTP_DISPOSITION_DISCARD;
+
+		/* Reset the transport so that we select the correct one
+		 * this time around.  This is to make sure that we don't
+		 * accidentally use a stale transport that's been removed.
+		 */
+		asconf_ack->transport = NULL;
 	} else {
 		/* ADDIP 5.2 E5) Otherwise, the ASCONF Chunk is discarded since
 		 * it must be either a stale packet or from an attacker.
@@ -4546,9 +4582,9 @@ sctp_disposition_t sctp_sf_do_prm_send(const struct sctp_endpoint *ep,
 				       void *arg,
 				       sctp_cmd_seq_t *commands)
 {
-	struct sctp_chunk *chunk = arg;
+	struct sctp_datamsg *msg = arg;
 
-	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(chunk));
+	sctp_add_cmd_sf(commands, SCTP_CMD_SEND_MSG, SCTP_DATAMSG(msg));
 	return SCTP_DISPOSITION_CONSUME;
 }
 
@@ -5847,6 +5883,9 @@ static int sctp_eat_data(const struct sctp_association *asoc,
 	__u32 tsn;
 	struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
 	struct sock *sk = asoc->base.sk;
+	u16 ssn;
+	u16 sid;
+	u8 ordered = 0;
 
 	data_hdr = chunk->subh.data_hdr = (sctp_datahdr_t *)chunk->skb->data;
 	skb_pull(chunk->skb, sizeof(sctp_datahdr_t));
@@ -5986,8 +6025,10 @@ static int sctp_eat_data(const struct sctp_association *asoc,
 	 */
 	if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
 		SCTP_INC_STATS(SCTP_MIB_INUNORDERCHUNKS);
-	else
+	else {
 		SCTP_INC_STATS(SCTP_MIB_INORDERCHUNKS);
+		ordered = 1;
+	}
 
 	/* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
 	 *
@@ -5997,7 +6038,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
 	 * with cause set to "Invalid Stream Identifier" (See Section 3.3.10)
 	 * and discard the DATA chunk.
 	 */
-	if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) {
+	sid = ntohs(data_hdr->stream);
+	if (sid >= asoc->c.sinit_max_instreams) {
 		/* Mark tsn as received even though we drop it */
 		sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn));
 
@@ -6010,6 +6052,18 @@ static int sctp_eat_data(const struct sctp_association *asoc,
 		return SCTP_IERROR_BAD_STREAM;
 	}
 
+	/* Check to see if the SSN is possible for this TSN.
+	 * The biggest gap we can record is 4K wide.  Since SSNs wrap
+	 * at an unsigned short, there is no way that an SSN can
+	 * wrap and for a valid TSN.  We can simply check if the current
+	 * SSN is smaller then the next expected one.  If it is, it wrapped
+	 * and is invalid.
+	 */
+	ssn = ntohs(data_hdr->ssn);
+	if (ordered && SSN_lt(ssn, sctp_ssn_peek(&asoc->ssnmap->in, sid))) {
+		return SCTP_IERROR_PROTO_VIOLATION;
+	}
+
 	/* Send the data up to the user.  Note:  Schedule  the
 	 * SCTP_CMD_CHUNK_ULP cmd before the SCTP_CMD_GEN_SACK, as the SACK
 	 * chunk needs the updated rwnd.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 971890d..89af37a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1361,6 +1361,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
 
 	sctp_lock_sock(sk);
 	sk->sk_shutdown = SHUTDOWN_MASK;
+	sk->sk_state = SCTP_SS_CLOSING;
 
 	ep = sctp_sk(sk)->ep;
 
@@ -1813,20 +1814,22 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
 		sctp_set_owner_w(chunk);
 
 		chunk->transport = chunk_tp;
-
-		/* Send it to the lower layers.  Note:  all chunks
-		 * must either fail or succeed.   The lower layer
-		 * works that way today.  Keep it that way or this
-		 * breaks.
-		 */
-		err = sctp_primitive_SEND(asoc, chunk);
-		/* Did the lower layer accept the chunk? */
-		if (err)
-			sctp_chunk_free(chunk);
-		SCTP_DEBUG_PRINTK("We sent primitively.\n");
 	}
 
-	sctp_datamsg_put(datamsg);
+	/* Send it to the lower layers.  Note:  all chunks
+	 * must either fail or succeed.   The lower layer
+	 * works that way today.  Keep it that way or this
+	 * breaks.
+	 */
+	err = sctp_primitive_SEND(asoc, datamsg);
+	/* Did the lower layer accept the chunk? */
+	if (err)
+		sctp_datamsg_free(datamsg);
+	else
+		sctp_datamsg_put(datamsg);
+
+	SCTP_DEBUG_PRINTK("We sent primitively.\n");
+
 	if (err)
 		goto out_free;
 	else
@@ -2240,7 +2243,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
 			sctp_assoc_sync_pmtu(asoc);
 		} else if (asoc) {
 			asoc->pathmtu = params->spp_pathmtu;
-			sctp_frag_point(sp, params->spp_pathmtu);
+			sctp_frag_point(asoc, params->spp_pathmtu);
 		} else {
 			sp->pathmtu = params->spp_pathmtu;
 		}
@@ -2877,15 +2880,10 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl
 			val -= sizeof(struct sctphdr) +
 					sizeof(struct sctp_data_chunk);
 		}
-
-		asoc->frag_point = val;
+		asoc->user_frag = val;
+		asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu);
 	} else {
 		sp->user_frag = val;
-
-		/* Update the frag_point of the existing associations. */
-		list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
-			asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
-		}
 	}
 
 	return 0;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 63eabbc..ab7151d 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -51,6 +51,7 @@ static int timer_max = 86400000; /* ms in one day */
 static int int_max = INT_MAX;
 static int sack_timer_min = 1;
 static int sack_timer_max = 500;
+static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
 
 extern int sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
@@ -272,6 +273,17 @@ static ctl_table sctp_table[] = {
 		.proc_handler	= proc_dointvec,
 		.strategy	= sysctl_intvec
 	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "addr_scope_policy",
+		.data		= &sctp_scope_policy,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero,
+		.extra2		= &addr_scope_max,
+	},
 	{ .ctl_name = 0 }
 };
 
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index e5dde45..c256e48 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -503,6 +503,9 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
 		transport->ssthresh = max(transport->cwnd/2,
 					  4*transport->asoc->pathmtu);
 		transport->cwnd = transport->asoc->pathmtu;
+
+		/* T3-rtx also clears fast recovery on the transport */
+		transport->fast_recovery = 0;
 		break;
 
 	case SCTP_LOWER_CWND_FAST_RTX:
diff --git a/net/socket.c b/net/socket.c
index 6d47165..2a022c0 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -489,6 +489,7 @@ static struct socket *sock_alloc(void)
 
 	sock = SOCKET_I(inode);
 
+	kmemcheck_annotate_bitfield(sock, type);
 	inode->i_mode = S_IFSOCK | S_IRWXUGO;
 	inode->i_uid = current_fsuid();
 	inode->i_gid = current_fsgid();
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index a7a3677..327011f 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -119,7 +119,7 @@ int  tipc_register_media(u32 media_type,
 		warn("Media <%s> rejected, no broadcast address\n", name);
 		goto exit;
 	}
-	if ((bearer_priority < TIPC_MIN_LINK_PRI) &&
+	if ((bearer_priority < TIPC_MIN_LINK_PRI) ||
 	    (bearer_priority > TIPC_MAX_LINK_PRI)) {
 		warn("Media <%s> rejected, illegal priority (%u)\n", name,
 		     bearer_priority);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 3c57005..7bda8e3 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -62,7 +62,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
 		rep_nlh = nlmsg_hdr(rep_buf);
 		memcpy(rep_nlh, req_nlh, hdr_space);
 		rep_nlh->nlmsg_len = rep_buf->len;
-		genlmsg_unicast(rep_buf, NETLINK_CB(skb).pid);
+		genlmsg_unicast(&init_net, rep_buf, NETLINK_CB(skb).pid);
 	}
 
 	return 0;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 1848693..e8254e8 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1748,6 +1748,12 @@ static int getsockopt(struct socket *sock,
 		value = jiffies_to_msecs(sk->sk_rcvtimeo);
 		/* no need to set "res", since already 0 at this point */
 		break;
+	 case TIPC_NODE_RECVQ_DEPTH:
+		value = (u32)atomic_read(&tipc_queue_size);
+		break;
+	 case TIPC_SOCK_RECVQ_DEPTH:
+		value = skb_queue_len(&sk->sk_receive_queue);
+		break;
 	default:
 		res = -EINVAL;
 	}
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index fc3ebb9..51ab497 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1501,6 +1501,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 	struct sk_buff *skb;
 	int sent = 0;
 	struct scm_cookie tmp_scm;
+	bool fds_sent = false;
 
 	if (NULL == siocb->scm)
 		siocb->scm = &tmp_scm;
@@ -1562,12 +1563,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
 		size = min_t(int, size, skb_tailroom(skb));
 
 		memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
-		if (siocb->scm->fp) {
+		/* Only send the fds in the first buffer */
+		if (siocb->scm->fp && !fds_sent) {
 			err = unix_attach_fds(siocb->scm, skb);
 			if (err) {
 				kfree_skb(skb);
 				goto out_err;
 			}
+			fds_sent = true;
 		}
 
 		err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 4428dd5..abf7ca3 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -1,6 +1,47 @@
 config CFG80211
-	tristate "Improved wireless configuration API"
+	tristate "cfg80211 - wireless configuration API"
 	depends on RFKILL || !RFKILL
+	---help---
+	  cfg80211 is the Linux wireless LAN (802.11) configuration API.
+	  Enable this if you have a wireless device.
+
+	  For more information refer to documentation on the wireless wiki:
+
+	  http://wireless.kernel.org/en/developers/Documentation/cfg80211
+
+	  When built as a module it will be called cfg80211.
+
+config NL80211_TESTMODE
+	bool "nl80211 testmode command"
+	depends on CFG80211
+	help
+	  The nl80211 testmode command helps implementing things like
+	  factory calibration or validation tools for wireless chips.
+
+	  Select this option ONLY for kernels that are specifically
+	  built for such purposes.
+
+	  Debugging tools that are supposed to end up in the hands of
+	  users should better be implemented with debugfs.
+
+	  Say N.
+
+config CFG80211_DEVELOPER_WARNINGS
+	bool "enable developer warnings"
+	depends on CFG80211
+	default n
+	help
+	  This option enables some additional warnings that help
+	  cfg80211 developers and driver developers, but that can
+	  trigger due to races with userspace.
+
+	  For example, when a driver reports that it was disconnected
+	  from the AP, but the user disconnects manually at the same
+	  time, the warning might trigger spuriously due to races.
+
+	  Say Y only if you are developing cfg80211 or a driver based
+	  on it (or mac80211).
+
 
 config CFG80211_REG_DEBUG
 	bool "cfg80211 regulatory debugging"
@@ -8,9 +49,29 @@ config CFG80211_REG_DEBUG
 	default n
 	---help---
 	  You can enable this if you want to debug regulatory changes.
+	  For more information on cfg80211 regulatory refer to the wireless
+	  wiki:
+
+	  http://wireless.kernel.org/en/developers/Regulatory
 
 	  If unsure, say N.
 
+config CFG80211_DEFAULT_PS
+	bool "enable powersave by default"
+	depends on CFG80211
+	default y
+	help
+	  This option enables powersave mode by default.
+
+	  If this causes your applications to misbehave you should fix your
+	  applications instead -- they need to register their network
+	  latency requirement, see Documentation/power/pm_qos_interface.txt.
+
+config CFG80211_DEFAULT_PS_VALUE
+	int
+	default 1 if CFG80211_DEFAULT_PS
+	default 0
+
 config CFG80211_DEBUGFS
 	bool "cfg80211 DebugFS entries"
 	depends on CFG80211 && DEBUG_FS
@@ -35,19 +96,13 @@ config WIRELESS_OLD_REGULATORY
 
 config WIRELESS_EXT
 	bool "Wireless extensions"
-	default n
+	default y
 	---help---
 	  This option enables the legacy wireless extensions
 	  (wireless network interface configuration via ioctls.)
 
-	  Wireless extensions will be replaced by cfg80211 and
-	  will be required only by legacy drivers that implement
-	  wireless extension handlers. This option does not
-	  affect the wireless-extension backward compatibility
-	  code in cfg80211.
-
-	  Say N (if you can) unless you know you need wireless
-	  extensions for external modules.
+	  Say Y unless you've upgraded all your userspace to use
+	  nl80211 instead of wireless extensions.
 
 config WIRELESS_EXT_SYSFS
 	bool "Wireless extensions sysfs files"
diff --git a/net/wireless/Makefile b/net/wireless/Makefile
index f78c483..3ecaa91 100644
--- a/net/wireless/Makefile
+++ b/net/wireless/Makefile
@@ -5,8 +5,9 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
 obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
 obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
 
-cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
+cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
+cfg80211-y += mlme.o ibss.o sme.o chan.o
 cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
-cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
+cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o wext-sme.o
 
 ccflags-y += -D__CHECK_ENDIAN__
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
new file mode 100644
index 0000000..a46ac6c
--- /dev/null
+++ b/net/wireless/chan.c
@@ -0,0 +1,89 @@
+/*
+ * This file contains helper code to handle channel
+ * settings and keeping track of what is possible at
+ * any point in time.
+ *
+ * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
+ */
+
+#include <net/cfg80211.h>
+#include "core.h"
+
+struct ieee80211_channel *
+rdev_fixed_channel(struct cfg80211_registered_device *rdev,
+		   struct wireless_dev *for_wdev)
+{
+	struct wireless_dev *wdev;
+	struct ieee80211_channel *result = NULL;
+
+	WARN_ON(!mutex_is_locked(&rdev->devlist_mtx));
+
+	list_for_each_entry(wdev, &rdev->netdev_list, list) {
+		if (wdev == for_wdev)
+			continue;
+
+		/*
+		 * Lock manually to tell lockdep about allowed
+		 * nesting here if for_wdev->mtx is held already.
+		 * This is ok as it's all under the rdev devlist
+		 * mutex and as such can only be done once at any
+		 * given time.
+		 */
+		mutex_lock_nested(&wdev->mtx, SINGLE_DEPTH_NESTING);
+		if (wdev->current_bss)
+			result = wdev->current_bss->pub.channel;
+		wdev_unlock(wdev);
+
+		if (result)
+			break;
+	}
+
+	return result;
+}
+
+int rdev_set_freq(struct cfg80211_registered_device *rdev,
+		  struct wireless_dev *for_wdev,
+		  int freq, enum nl80211_channel_type channel_type)
+{
+	struct ieee80211_channel *chan;
+	struct ieee80211_sta_ht_cap *ht_cap;
+	int result;
+
+	if (rdev_fixed_channel(rdev, for_wdev))
+		return -EBUSY;
+
+	if (!rdev->ops->set_channel)
+		return -EOPNOTSUPP;
+
+	chan = ieee80211_get_channel(&rdev->wiphy, freq);
+
+	/* Primary channel not allowed */
+	if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
+		return -EINVAL;
+
+	if (channel_type == NL80211_CHAN_HT40MINUS &&
+	    chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
+		return -EINVAL;
+	else if (channel_type == NL80211_CHAN_HT40PLUS &&
+		 chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
+		return -EINVAL;
+
+	ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
+
+	if (channel_type != NL80211_CHAN_NO_HT) {
+		if (!ht_cap->ht_supported)
+			return -EINVAL;
+
+		if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
+		    ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
+			return -EINVAL;
+	}
+
+	result = rdev->ops->set_channel(&rdev->wiphy, chan, channel_type);
+	if (result)
+		return result;
+
+	rdev->channel = chan;
+
+	return 0;
+}
diff --git a/net/wireless/core.c b/net/wireless/core.c
index d585029..45b2be3 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -12,6 +12,7 @@
 #include <linux/debugfs.h>
 #include <linux/notifier.h>
 #include <linux/device.h>
+#include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
 #include <net/genetlink.h>
 #include <net/cfg80211.h>
@@ -19,6 +20,7 @@
 #include "core.h"
 #include "sysfs.h"
 #include "debugfs.h"
+#include "wext-compat.h"
 
 /* name for sysfs, %d is appended */
 #define PHY_NAME "phy"
@@ -30,12 +32,11 @@ MODULE_DESCRIPTION("wireless configuration support");
 /* RCU might be appropriate here since we usually
  * only read the list, and that can happen quite
  * often because we need to do it for each command */
-LIST_HEAD(cfg80211_drv_list);
+LIST_HEAD(cfg80211_rdev_list);
+int cfg80211_rdev_list_generation;
 
 /*
- * This is used to protect the cfg80211_drv_list, cfg80211_regdomain,
- * country_ie_regdomain, the reg_beacon_list and the the last regulatory
- * request receipt (last_request).
+ * This is used to protect the cfg80211_rdev_list
  */
 DEFINE_MUTEX(cfg80211_mutex);
 
@@ -43,18 +44,18 @@ DEFINE_MUTEX(cfg80211_mutex);
 static struct dentry *ieee80211_debugfs_dir;
 
 /* requires cfg80211_mutex to be held! */
-struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx)
+struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx)
 {
-	struct cfg80211_registered_device *result = NULL, *drv;
+	struct cfg80211_registered_device *result = NULL, *rdev;
 
 	if (!wiphy_idx_valid(wiphy_idx))
 		return NULL;
 
 	assert_cfg80211_lock();
 
-	list_for_each_entry(drv, &cfg80211_drv_list, list) {
-		if (drv->wiphy_idx == wiphy_idx) {
-			result = drv;
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		if (rdev->wiphy_idx == wiphy_idx) {
+			result = rdev;
 			break;
 		}
 	}
@@ -64,32 +65,32 @@ struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx)
 
 int get_wiphy_idx(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	if (!wiphy)
 		return WIPHY_IDX_STALE;
-	drv = wiphy_to_dev(wiphy);
-	return drv->wiphy_idx;
+	rdev = wiphy_to_dev(wiphy);
+	return rdev->wiphy_idx;
 }
 
-/* requires cfg80211_drv_mutex to be held! */
+/* requires cfg80211_rdev_mutex to be held! */
 struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
 	if (!wiphy_idx_valid(wiphy_idx))
 		return NULL;
 
 	assert_cfg80211_lock();
 
-	drv = cfg80211_drv_by_wiphy_idx(wiphy_idx);
-	if (!drv)
+	rdev = cfg80211_rdev_by_wiphy_idx(wiphy_idx);
+	if (!rdev)
 		return NULL;
-	return &drv->wiphy;
+	return &rdev->wiphy;
 }
 
 /* requires cfg80211_mutex to be held! */
 struct cfg80211_registered_device *
-__cfg80211_drv_from_info(struct genl_info *info)
+__cfg80211_rdev_from_info(struct genl_info *info)
 {
 	int ifindex;
 	struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL;
@@ -99,14 +100,14 @@ __cfg80211_drv_from_info(struct genl_info *info)
 	assert_cfg80211_lock();
 
 	if (info->attrs[NL80211_ATTR_WIPHY]) {
-		bywiphyidx = cfg80211_drv_by_wiphy_idx(
+		bywiphyidx = cfg80211_rdev_by_wiphy_idx(
 				nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
 		err = -ENODEV;
 	}
 
 	if (info->attrs[NL80211_ATTR_IFINDEX]) {
 		ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
-		dev = dev_get_by_index(&init_net, ifindex);
+		dev = dev_get_by_index(genl_info_net(info), ifindex);
 		if (dev) {
 			if (dev->ieee80211_ptr)
 				byifidx =
@@ -134,54 +135,48 @@ __cfg80211_drv_from_info(struct genl_info *info)
 struct cfg80211_registered_device *
 cfg80211_get_dev_from_info(struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
 	mutex_lock(&cfg80211_mutex);
-	drv = __cfg80211_drv_from_info(info);
+	rdev = __cfg80211_rdev_from_info(info);
 
 	/* if it is not an error we grab the lock on
 	 * it to assure it won't be going away while
 	 * we operate on it */
-	if (!IS_ERR(drv))
-		mutex_lock(&drv->mtx);
+	if (!IS_ERR(rdev))
+		mutex_lock(&rdev->mtx);
 
 	mutex_unlock(&cfg80211_mutex);
 
-	return drv;
+	return rdev;
 }
 
 struct cfg80211_registered_device *
-cfg80211_get_dev_from_ifindex(int ifindex)
+cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
 {
-	struct cfg80211_registered_device *drv = ERR_PTR(-ENODEV);
+	struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV);
 	struct net_device *dev;
 
 	mutex_lock(&cfg80211_mutex);
-	dev = dev_get_by_index(&init_net, ifindex);
+	dev = dev_get_by_index(net, ifindex);
 	if (!dev)
 		goto out;
 	if (dev->ieee80211_ptr) {
-		drv = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
-		mutex_lock(&drv->mtx);
+		rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
+		mutex_lock(&rdev->mtx);
 	} else
-		drv = ERR_PTR(-ENODEV);
+		rdev = ERR_PTR(-ENODEV);
 	dev_put(dev);
  out:
 	mutex_unlock(&cfg80211_mutex);
-	return drv;
-}
-
-void cfg80211_put_dev(struct cfg80211_registered_device *drv)
-{
-	BUG_ON(IS_ERR(drv));
-	mutex_unlock(&drv->mtx);
+	return rdev;
 }
 
 /* requires cfg80211_mutex to be held */
 int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 			char *newname)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev2;
 	int wiphy_idx, taken = -1, result, digits;
 
 	assert_cfg80211_lock();
@@ -207,8 +202,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 		return 0;
 
 	/* Ensure another device does not already have this name. */
-	list_for_each_entry(drv, &cfg80211_drv_list, list)
-		if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0)
+	list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
+		if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
 			return -EINVAL;
 
 	result = device_rename(&rdev->wiphy.dev, newname);
@@ -228,28 +223,64 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 	return 0;
 }
 
+int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
+			  struct net *net)
+{
+	struct wireless_dev *wdev;
+	int err = 0;
+
+	if (!rdev->wiphy.netnsok)
+		return -EOPNOTSUPP;
+
+	list_for_each_entry(wdev, &rdev->netdev_list, list) {
+		wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
+		err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
+		if (err)
+			break;
+		wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
+	}
+
+	if (err) {
+		/* failed -- clean up to old netns */
+		net = wiphy_net(&rdev->wiphy);
+
+		list_for_each_entry_continue_reverse(wdev, &rdev->netdev_list,
+						     list) {
+			wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
+			err = dev_change_net_namespace(wdev->netdev, net,
+							"wlan%d");
+			WARN_ON(err);
+			wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
+		}
+	}
+
+	wiphy_net_set(&rdev->wiphy, net);
+
+	return err;
+}
+
 static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
 {
-	struct cfg80211_registered_device *drv = data;
+	struct cfg80211_registered_device *rdev = data;
 
-	drv->ops->rfkill_poll(&drv->wiphy);
+	rdev->ops->rfkill_poll(&rdev->wiphy);
 }
 
 static int cfg80211_rfkill_set_block(void *data, bool blocked)
 {
-	struct cfg80211_registered_device *drv = data;
+	struct cfg80211_registered_device *rdev = data;
 	struct wireless_dev *wdev;
 
 	if (!blocked)
 		return 0;
 
 	rtnl_lock();
-	mutex_lock(&drv->devlist_mtx);
+	mutex_lock(&rdev->devlist_mtx);
 
-	list_for_each_entry(wdev, &drv->netdev_list, list)
+	list_for_each_entry(wdev, &rdev->netdev_list, list)
 		dev_close(wdev->netdev);
 
-	mutex_unlock(&drv->devlist_mtx);
+	mutex_unlock(&rdev->devlist_mtx);
 	rtnl_unlock();
 
 	return 0;
@@ -257,10 +288,25 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
 
 static void cfg80211_rfkill_sync_work(struct work_struct *work)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
-	drv = container_of(work, struct cfg80211_registered_device, rfkill_sync);
-	cfg80211_rfkill_set_block(drv, rfkill_blocked(drv->rfkill));
+	rdev = container_of(work, struct cfg80211_registered_device, rfkill_sync);
+	cfg80211_rfkill_set_block(rdev, rfkill_blocked(rdev->rfkill));
+}
+
+static void cfg80211_event_work(struct work_struct *work)
+{
+	struct cfg80211_registered_device *rdev;
+
+	rdev = container_of(work, struct cfg80211_registered_device,
+			    event_work);
+
+	rtnl_lock();
+	cfg80211_lock_rdev(rdev);
+
+	cfg80211_process_rdev_events(rdev);
+	cfg80211_unlock_rdev(rdev);
+	rtnl_unlock();
 }
 
 /* exported functions */
@@ -269,76 +315,90 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
 {
 	static int wiphy_counter;
 
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int alloc_size;
 
-	WARN_ON(!ops->add_key && ops->del_key);
-	WARN_ON(ops->add_key && !ops->del_key);
+	WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
+	WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
+	WARN_ON(ops->connect && !ops->disconnect);
+	WARN_ON(ops->join_ibss && !ops->leave_ibss);
+	WARN_ON(ops->add_virtual_intf && !ops->del_virtual_intf);
+	WARN_ON(ops->add_station && !ops->del_station);
+	WARN_ON(ops->add_mpath && !ops->del_mpath);
 
-	alloc_size = sizeof(*drv) + sizeof_priv;
+	alloc_size = sizeof(*rdev) + sizeof_priv;
 
-	drv = kzalloc(alloc_size, GFP_KERNEL);
-	if (!drv)
+	rdev = kzalloc(alloc_size, GFP_KERNEL);
+	if (!rdev)
 		return NULL;
 
-	drv->ops = ops;
+	rdev->ops = ops;
 
 	mutex_lock(&cfg80211_mutex);
 
-	drv->wiphy_idx = wiphy_counter++;
+	rdev->wiphy_idx = wiphy_counter++;
 
-	if (unlikely(!wiphy_idx_valid(drv->wiphy_idx))) {
+	if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
 		wiphy_counter--;
 		mutex_unlock(&cfg80211_mutex);
 		/* ugh, wrapped! */
-		kfree(drv);
+		kfree(rdev);
 		return NULL;
 	}
 
 	mutex_unlock(&cfg80211_mutex);
 
 	/* give it a proper name */
-	dev_set_name(&drv->wiphy.dev, PHY_NAME "%d", drv->wiphy_idx);
+	dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
 
-	mutex_init(&drv->mtx);
-	mutex_init(&drv->devlist_mtx);
-	INIT_LIST_HEAD(&drv->netdev_list);
-	spin_lock_init(&drv->bss_lock);
-	INIT_LIST_HEAD(&drv->bss_list);
+	mutex_init(&rdev->mtx);
+	mutex_init(&rdev->devlist_mtx);
+	INIT_LIST_HEAD(&rdev->netdev_list);
+	spin_lock_init(&rdev->bss_lock);
+	INIT_LIST_HEAD(&rdev->bss_list);
+	INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
 
-	device_initialize(&drv->wiphy.dev);
-	drv->wiphy.dev.class = &ieee80211_class;
-	drv->wiphy.dev.platform_data = drv;
+	device_initialize(&rdev->wiphy.dev);
+	rdev->wiphy.dev.class = &ieee80211_class;
+	rdev->wiphy.dev.platform_data = rdev;
 
-	drv->rfkill_ops.set_block = cfg80211_rfkill_set_block;
-	drv->rfkill = rfkill_alloc(dev_name(&drv->wiphy.dev),
-				   &drv->wiphy.dev, RFKILL_TYPE_WLAN,
-				   &drv->rfkill_ops, drv);
+	rdev->wiphy.ps_default = CONFIG_CFG80211_DEFAULT_PS_VALUE;
 
-	if (!drv->rfkill) {
-		kfree(drv);
+	wiphy_net_set(&rdev->wiphy, &init_net);
+
+	rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block;
+	rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev),
+				   &rdev->wiphy.dev, RFKILL_TYPE_WLAN,
+				   &rdev->rfkill_ops, rdev);
+
+	if (!rdev->rfkill) {
+		kfree(rdev);
 		return NULL;
 	}
 
-	INIT_WORK(&drv->rfkill_sync, cfg80211_rfkill_sync_work);
+	INIT_WORK(&rdev->rfkill_sync, cfg80211_rfkill_sync_work);
+	INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
+	INIT_WORK(&rdev->event_work, cfg80211_event_work);
+
+	init_waitqueue_head(&rdev->dev_wait);
 
 	/*
 	 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
 	 * Fragmentation and RTS threshold are disabled by default with the
 	 * special -1 value.
 	 */
-	drv->wiphy.retry_short = 7;
-	drv->wiphy.retry_long = 4;
-	drv->wiphy.frag_threshold = (u32) -1;
-	drv->wiphy.rts_threshold = (u32) -1;
+	rdev->wiphy.retry_short = 7;
+	rdev->wiphy.retry_long = 4;
+	rdev->wiphy.frag_threshold = (u32) -1;
+	rdev->wiphy.rts_threshold = (u32) -1;
 
-	return &drv->wiphy;
+	return &rdev->wiphy;
 }
 EXPORT_SYMBOL(wiphy_new);
 
 int wiphy_register(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 	int res;
 	enum ieee80211_band band;
 	struct ieee80211_supported_band *sband;
@@ -346,9 +406,6 @@ int wiphy_register(struct wiphy *wiphy)
 	int i;
 	u16 ifmodes = wiphy->interface_modes;
 
-	if (WARN_ON(wiphy->max_scan_ssids < 1))
-		return -EINVAL;
-
 	/* sanity check ifmodes */
 	WARN_ON(!ifmodes);
 	ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
@@ -395,11 +452,11 @@ int wiphy_register(struct wiphy *wiphy)
 	/* check and set up bitrates */
 	ieee80211_set_bitrate_flags(wiphy);
 
-	res = device_add(&drv->wiphy.dev);
+	res = device_add(&rdev->wiphy.dev);
 	if (res)
 		return res;
 
-	res = rfkill_register(drv->rfkill);
+	res = rfkill_register(rdev->rfkill);
 	if (res)
 		goto out_rm_dev;
 
@@ -408,16 +465,17 @@ int wiphy_register(struct wiphy *wiphy)
 	/* set up regulatory info */
 	wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
 
-	list_add(&drv->list, &cfg80211_drv_list);
+	list_add(&rdev->list, &cfg80211_rdev_list);
+	cfg80211_rdev_list_generation++;
 
 	mutex_unlock(&cfg80211_mutex);
 
 	/* add to debugfs */
-	drv->wiphy.debugfsdir =
-		debugfs_create_dir(wiphy_name(&drv->wiphy),
+	rdev->wiphy.debugfsdir =
+		debugfs_create_dir(wiphy_name(&rdev->wiphy),
 				   ieee80211_debugfs_dir);
-	if (IS_ERR(drv->wiphy.debugfsdir))
-		drv->wiphy.debugfsdir = NULL;
+	if (IS_ERR(rdev->wiphy.debugfsdir))
+		rdev->wiphy.debugfsdir = NULL;
 
 	if (wiphy->custom_regulatory) {
 		struct regulatory_request request;
@@ -430,83 +488,101 @@ int wiphy_register(struct wiphy *wiphy)
 		nl80211_send_reg_change_event(&request);
 	}
 
-	cfg80211_debugfs_drv_add(drv);
+	cfg80211_debugfs_rdev_add(rdev);
 
 	return 0;
 
  out_rm_dev:
-	device_del(&drv->wiphy.dev);
+	device_del(&rdev->wiphy.dev);
 	return res;
 }
 EXPORT_SYMBOL(wiphy_register);
 
 void wiphy_rfkill_start_polling(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	if (!drv->ops->rfkill_poll)
+	if (!rdev->ops->rfkill_poll)
 		return;
-	drv->rfkill_ops.poll = cfg80211_rfkill_poll;
-	rfkill_resume_polling(drv->rfkill);
+	rdev->rfkill_ops.poll = cfg80211_rfkill_poll;
+	rfkill_resume_polling(rdev->rfkill);
 }
 EXPORT_SYMBOL(wiphy_rfkill_start_polling);
 
 void wiphy_rfkill_stop_polling(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	rfkill_pause_polling(drv->rfkill);
+	rfkill_pause_polling(rdev->rfkill);
 }
 EXPORT_SYMBOL(wiphy_rfkill_stop_polling);
 
 void wiphy_unregister(struct wiphy *wiphy)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	rfkill_unregister(drv->rfkill);
+	rfkill_unregister(rdev->rfkill);
 
 	/* protect the device list */
 	mutex_lock(&cfg80211_mutex);
 
-	BUG_ON(!list_empty(&drv->netdev_list));
+	wait_event(rdev->dev_wait, ({
+		int __count;
+		mutex_lock(&rdev->devlist_mtx);
+		__count = rdev->opencount;
+		mutex_unlock(&rdev->devlist_mtx);
+		__count == 0;}));
+
+	mutex_lock(&rdev->devlist_mtx);
+	BUG_ON(!list_empty(&rdev->netdev_list));
+	mutex_unlock(&rdev->devlist_mtx);
+
+	/*
+	 * First remove the hardware from everywhere, this makes
+	 * it impossible to find from userspace.
+	 */
+	cfg80211_debugfs_rdev_del(rdev);
+	list_del(&rdev->list);
 
 	/*
-	 * Try to grab drv->mtx. If a command is still in progress,
+	 * Try to grab rdev->mtx. If a command is still in progress,
 	 * hopefully the driver will refuse it since it's tearing
 	 * down the device already. We wait for this command to complete
 	 * before unlinking the item from the list.
 	 * Note: as codified by the BUG_ON above we cannot get here if
-	 * a virtual interface is still associated. Hence, we can only
-	 * get to lock contention here if userspace issues a command
-	 * that identified the hardware by wiphy index.
+	 * a virtual interface is still present. Hence, we can only get
+	 * to lock contention here if userspace issues a command that
+	 * identified the hardware by wiphy index.
 	 */
-	mutex_lock(&drv->mtx);
-	/* unlock again before freeing */
-	mutex_unlock(&drv->mtx);
-
-	cfg80211_debugfs_drv_del(drv);
+	cfg80211_lock_rdev(rdev);
+	/* nothing */
+	cfg80211_unlock_rdev(rdev);
 
 	/* If this device got a regulatory hint tell core its
 	 * free to listen now to a new shiny device regulatory hint */
 	reg_device_remove(wiphy);
 
-	list_del(&drv->list);
-	device_del(&drv->wiphy.dev);
-	debugfs_remove(drv->wiphy.debugfsdir);
+	cfg80211_rdev_list_generation++;
+	device_del(&rdev->wiphy.dev);
+	debugfs_remove(rdev->wiphy.debugfsdir);
 
 	mutex_unlock(&cfg80211_mutex);
+
+	flush_work(&rdev->scan_done_wk);
+	cancel_work_sync(&rdev->conn_work);
+	flush_work(&rdev->event_work);
 }
 EXPORT_SYMBOL(wiphy_unregister);
 
-void cfg80211_dev_free(struct cfg80211_registered_device *drv)
+void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
 {
 	struct cfg80211_internal_bss *scan, *tmp;
-	rfkill_destroy(drv->rfkill);
-	mutex_destroy(&drv->mtx);
-	mutex_destroy(&drv->devlist_mtx);
-	list_for_each_entry_safe(scan, tmp, &drv->bss_list, list)
+	rfkill_destroy(rdev->rfkill);
+	mutex_destroy(&rdev->mtx);
+	mutex_destroy(&rdev->devlist_mtx);
+	list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
 		cfg80211_put_bss(&scan->pub);
-	kfree(drv);
+	kfree(rdev);
 }
 
 void wiphy_free(struct wiphy *wiphy)
@@ -517,68 +593,181 @@ EXPORT_SYMBOL(wiphy_free);
 
 void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
 {
-	struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
-	if (rfkill_set_hw_state(drv->rfkill, blocked))
-		schedule_work(&drv->rfkill_sync);
+	if (rfkill_set_hw_state(rdev->rfkill, blocked))
+		schedule_work(&rdev->rfkill_sync);
 }
 EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
 
+static void wdev_cleanup_work(struct work_struct *work)
+{
+	struct wireless_dev *wdev;
+	struct cfg80211_registered_device *rdev;
+
+	wdev = container_of(work, struct wireless_dev, cleanup_work);
+	rdev = wiphy_to_dev(wdev->wiphy);
+
+	cfg80211_lock_rdev(rdev);
+
+	if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == wdev->netdev)) {
+		rdev->scan_req->aborted = true;
+		___cfg80211_scan_done(rdev, true);
+	}
+
+	cfg80211_unlock_rdev(rdev);
+
+	mutex_lock(&rdev->devlist_mtx);
+	rdev->opencount--;
+	mutex_unlock(&rdev->devlist_mtx);
+	wake_up(&rdev->dev_wait);
+
+	dev_put(wdev->netdev);
+}
+
 static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
 					 unsigned long state,
 					 void *ndev)
 {
 	struct net_device *dev = ndev;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_registered_device *rdev;
 
-	if (!dev->ieee80211_ptr)
+	if (!wdev)
 		return NOTIFY_DONE;
 
-	rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
+	rdev = wiphy_to_dev(wdev->wiphy);
 
-	WARN_ON(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_UNSPECIFIED);
+	WARN_ON(wdev->iftype == NL80211_IFTYPE_UNSPECIFIED);
 
 	switch (state) {
 	case NETDEV_REGISTER:
+		/*
+		 * NB: cannot take rdev->mtx here because this may be
+		 * called within code protected by it when interfaces
+		 * are added with nl80211.
+		 */
+		mutex_init(&wdev->mtx);
+		INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
+		INIT_LIST_HEAD(&wdev->event_list);
+		spin_lock_init(&wdev->event_lock);
 		mutex_lock(&rdev->devlist_mtx);
-		list_add(&dev->ieee80211_ptr->list, &rdev->netdev_list);
+		list_add(&wdev->list, &rdev->netdev_list);
+		rdev->devlist_generation++;
+		/* can only change netns with wiphy */
+		dev->features |= NETIF_F_NETNS_LOCAL;
+
 		if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
 				      "phy80211")) {
 			printk(KERN_ERR "wireless: failed to add phy80211 "
 				"symlink to netdev!\n");
 		}
-		dev->ieee80211_ptr->netdev = dev;
+		wdev->netdev = dev;
+		wdev->sme_state = CFG80211_SME_IDLE;
+		mutex_unlock(&rdev->devlist_mtx);
 #ifdef CONFIG_WIRELESS_EXT
-		dev->ieee80211_ptr->wext.default_key = -1;
-		dev->ieee80211_ptr->wext.default_mgmt_key = -1;
+		if (!dev->wireless_handlers)
+			dev->wireless_handlers = &cfg80211_wext_handler;
+		wdev->wext.default_key = -1;
+		wdev->wext.default_mgmt_key = -1;
+		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+		wdev->wext.ps = wdev->wiphy->ps_default;
+		wdev->wext.ps_timeout = 100;
+		if (rdev->ops->set_power_mgmt)
+			if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
+						      wdev->wext.ps,
+						      wdev->wext.ps_timeout)) {
+				/* assume this means it's off */
+				wdev->wext.ps = false;
+			}
 #endif
-		mutex_unlock(&rdev->devlist_mtx);
 		break;
 	case NETDEV_GOING_DOWN:
-		if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+		switch (wdev->iftype) {
+		case NL80211_IFTYPE_ADHOC:
+			cfg80211_leave_ibss(rdev, dev, true);
 			break;
-		if (!dev->ieee80211_ptr->ssid_len)
+		case NL80211_IFTYPE_STATION:
+			wdev_lock(wdev);
+#ifdef CONFIG_WIRELESS_EXT
+			kfree(wdev->wext.ie);
+			wdev->wext.ie = NULL;
+			wdev->wext.ie_len = 0;
+			wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+#endif
+			__cfg80211_disconnect(rdev, dev,
+					      WLAN_REASON_DEAUTH_LEAVING, true);
+			cfg80211_mlme_down(rdev, dev);
+			wdev_unlock(wdev);
+			break;
+		default:
 			break;
-		cfg80211_leave_ibss(rdev, dev, true);
+		}
+		break;
+	case NETDEV_DOWN:
+		dev_hold(dev);
+		schedule_work(&wdev->cleanup_work);
 		break;
 	case NETDEV_UP:
+		/*
+		 * If we have a really quick DOWN/UP succession we may
+		 * have this work still pending ... cancel it and see
+		 * if it was pending, in which case we need to account
+		 * for some of the work it would have done.
+		 */
+		if (cancel_work_sync(&wdev->cleanup_work)) {
+			mutex_lock(&rdev->devlist_mtx);
+			rdev->opencount--;
+			mutex_unlock(&rdev->devlist_mtx);
+			dev_put(dev);
+		}
 #ifdef CONFIG_WIRELESS_EXT
-		if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+		cfg80211_lock_rdev(rdev);
+		mutex_lock(&rdev->devlist_mtx);
+		wdev_lock(wdev);
+		switch (wdev->iftype) {
+		case NL80211_IFTYPE_ADHOC:
+			cfg80211_ibss_wext_join(rdev, wdev);
 			break;
-		if (!dev->ieee80211_ptr->wext.ibss.ssid_len)
+		case NL80211_IFTYPE_STATION:
+			cfg80211_mgd_wext_connect(rdev, wdev);
 			break;
-		cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext.ibss);
-		break;
+		default:
+			break;
+		}
+		wdev_unlock(wdev);
+		rdev->opencount++;
+		mutex_unlock(&rdev->devlist_mtx);
+		cfg80211_unlock_rdev(rdev);
 #endif
+		break;
 	case NETDEV_UNREGISTER:
+		/*
+		 * NB: cannot take rdev->mtx here because this may be
+		 * called within code protected by it when interfaces
+		 * are removed with nl80211.
+		 */
 		mutex_lock(&rdev->devlist_mtx);
-		if (!list_empty(&dev->ieee80211_ptr->list)) {
+		/*
+		 * It is possible to get NETDEV_UNREGISTER
+		 * multiple times. To detect that, check
+		 * that the interface is still on the list
+		 * of registered interfaces, and only then
+		 * remove and clean it up.
+		 */
+		if (!list_empty(&wdev->list)) {
 			sysfs_remove_link(&dev->dev.kobj, "phy80211");
-			list_del_init(&dev->ieee80211_ptr->list);
+			list_del_init(&wdev->list);
+			rdev->devlist_generation++;
+#ifdef CONFIG_WIRELESS_EXT
+			kfree(wdev->wext.keys);
+#endif
 		}
 		mutex_unlock(&rdev->devlist_mtx);
 		break;
 	case NETDEV_PRE_UP:
+		if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
+			return notifier_from_errno(-EOPNOTSUPP);
 		if (rfkill_blocked(rdev->rfkill))
 			return notifier_from_errno(-ERFKILL);
 		break;
@@ -591,10 +780,32 @@ static struct notifier_block cfg80211_netdev_notifier = {
 	.notifier_call = cfg80211_netdev_notifier_call,
 };
 
-static int cfg80211_init(void)
+static void __net_exit cfg80211_pernet_exit(struct net *net)
+{
+	struct cfg80211_registered_device *rdev;
+
+	rtnl_lock();
+	mutex_lock(&cfg80211_mutex);
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		if (net_eq(wiphy_net(&rdev->wiphy), net))
+			WARN_ON(cfg80211_switch_netns(rdev, &init_net));
+	}
+	mutex_unlock(&cfg80211_mutex);
+	rtnl_unlock();
+}
+
+static struct pernet_operations cfg80211_pernet_ops = {
+	.exit = cfg80211_pernet_exit,
+};
+
+static int __init cfg80211_init(void)
 {
 	int err;
 
+	err = register_pernet_device(&cfg80211_pernet_ops);
+	if (err)
+		goto out_fail_pernet;
+
 	err = wiphy_sysfs_init();
 	if (err)
 		goto out_fail_sysfs;
@@ -622,9 +833,10 @@ out_fail_nl80211:
 out_fail_notifier:
 	wiphy_sysfs_exit();
 out_fail_sysfs:
+	unregister_pernet_device(&cfg80211_pernet_ops);
+out_fail_pernet:
 	return err;
 }
-
 subsys_initcall(cfg80211_init);
 
 static void cfg80211_exit(void)
@@ -634,5 +846,6 @@ static void cfg80211_exit(void)
 	unregister_netdevice_notifier(&cfg80211_netdev_notifier);
 	wiphy_sysfs_exit();
 	regulatory_exit();
+	unregister_pernet_device(&cfg80211_pernet_ops);
 }
 module_exit(cfg80211_exit);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index bfa340c..2a33d8b 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -49,6 +49,9 @@ struct cfg80211_registered_device {
 	/* associate netdev list */
 	struct mutex devlist_mtx;
 	struct list_head netdev_list;
+	int devlist_generation;
+	int opencount; /* also protected by devlist_mtx */
+	wait_queue_head_t dev_wait;
 
 	/* BSSes/scanning */
 	spinlock_t bss_lock;
@@ -57,6 +60,17 @@ struct cfg80211_registered_device {
 	u32 bss_generation;
 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
 	unsigned long suspend_at;
+	struct work_struct scan_done_wk;
+
+#ifdef CONFIG_NL80211_TESTMODE
+	struct genl_info *testmode_info;
+#endif
+
+	struct work_struct conn_work;
+	struct work_struct event_work;
+
+	/* current channel */
+	struct ieee80211_channel *channel;
 
 #ifdef CONFIG_CFG80211_DEBUGFS
 	/* Debugfs entries */
@@ -89,13 +103,14 @@ bool wiphy_idx_valid(int wiphy_idx)
 }
 
 extern struct mutex cfg80211_mutex;
-extern struct list_head cfg80211_drv_list;
+extern struct list_head cfg80211_rdev_list;
+extern int cfg80211_rdev_list_generation;
 
 #define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
 
 /*
  * You can use this to mark a wiphy_idx as not having an associated wiphy.
- * It guarantees cfg80211_drv_by_wiphy_idx(wiphy_idx) will return NULL
+ * It guarantees cfg80211_rdev_by_wiphy_idx(wiphy_idx) will return NULL
  */
 #define WIPHY_IDX_STALE -1
 
@@ -104,17 +119,40 @@ struct cfg80211_internal_bss {
 	struct rb_node rbn;
 	unsigned long ts;
 	struct kref ref;
-	bool hold, ies_allocated;
+	atomic_t hold;
+	bool ies_allocated;
 
 	/* must be last because of priv member */
 	struct cfg80211_bss pub;
 };
 
-struct cfg80211_registered_device *cfg80211_drv_by_wiphy_idx(int wiphy_idx);
+static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pub)
+{
+	return container_of(pub, struct cfg80211_internal_bss, pub);
+}
+
+static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss)
+{
+	kref_get(&bss->ref);
+}
+
+static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
+{
+	atomic_inc(&bss->hold);
+}
+
+static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
+{
+	int r = atomic_dec_return(&bss->hold);
+	WARN_ON(r < 0);
+}
+
+
+struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx);
 int get_wiphy_idx(struct wiphy *wiphy);
 
 struct cfg80211_registered_device *
-__cfg80211_drv_from_info(struct genl_info *info);
+__cfg80211_rdev_from_info(struct genl_info *info);
 
 /*
  * This function returns a pointer to the driver
@@ -122,12 +160,12 @@ __cfg80211_drv_from_info(struct genl_info *info);
  * If successful, it returns non-NULL and also locks
  * the driver's mutex!
  *
- * This means that you need to call cfg80211_put_dev()
+ * This means that you need to call cfg80211_unlock_rdev()
  * before being allowed to acquire &cfg80211_mutex!
  *
  * This is necessary because we need to lock the global
  * mutex to get an item off the list safely, and then
- * we lock the drv mutex so it doesn't go away under us.
+ * we lock the rdev mutex so it doesn't go away under us.
  *
  * We don't want to keep cfg80211_mutex locked
  * for all the time in order to allow requests on
@@ -139,19 +177,93 @@ __cfg80211_drv_from_info(struct genl_info *info);
 extern struct cfg80211_registered_device *
 cfg80211_get_dev_from_info(struct genl_info *info);
 
-/* requires cfg80211_drv_mutex to be held! */
+/* requires cfg80211_rdev_mutex to be held! */
 struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
 
 /* identical to cfg80211_get_dev_from_info but only operate on ifindex */
 extern struct cfg80211_registered_device *
-cfg80211_get_dev_from_ifindex(int ifindex);
+cfg80211_get_dev_from_ifindex(struct net *net, int ifindex);
+
+int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
+			  struct net *net);
+
+static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
+{
+	mutex_lock(&rdev->mtx);
+}
+
+static inline void cfg80211_unlock_rdev(struct cfg80211_registered_device *rdev)
+{
+	BUG_ON(IS_ERR(rdev) || !rdev);
+	mutex_unlock(&rdev->mtx);
+}
+
+static inline void wdev_lock(struct wireless_dev *wdev)
+	__acquires(wdev)
+{
+	mutex_lock(&wdev->mtx);
+	__acquire(wdev->mtx);
+}
+
+static inline void wdev_unlock(struct wireless_dev *wdev)
+	__releases(wdev)
+{
+	__release(wdev->mtx);
+	mutex_unlock(&wdev->mtx);
+}
+
+#define ASSERT_RDEV_LOCK(rdev) WARN_ON(!mutex_is_locked(&(rdev)->mtx));
+#define ASSERT_WDEV_LOCK(wdev) WARN_ON(!mutex_is_locked(&(wdev)->mtx));
+
+enum cfg80211_event_type {
+	EVENT_CONNECT_RESULT,
+	EVENT_ROAMED,
+	EVENT_DISCONNECTED,
+	EVENT_IBSS_JOINED,
+};
+
+struct cfg80211_event {
+	struct list_head list;
+	enum cfg80211_event_type type;
+
+	union {
+		struct {
+			u8 bssid[ETH_ALEN];
+			const u8 *req_ie;
+			const u8 *resp_ie;
+			size_t req_ie_len;
+			size_t resp_ie_len;
+			u16 status;
+		} cr;
+		struct {
+			u8 bssid[ETH_ALEN];
+			const u8 *req_ie;
+			const u8 *resp_ie;
+			size_t req_ie_len;
+			size_t resp_ie_len;
+		} rm;
+		struct {
+			const u8 *ie;
+			size_t ie_len;
+			u16 reason;
+		} dc;
+		struct {
+			u8 bssid[ETH_ALEN];
+		} ij;
+	};
+};
+
+struct cfg80211_cached_keys {
+	struct key_params params[6];
+	u8 data[6][WLAN_MAX_KEY_LEN];
+	int def, defmgmt;
+};
 
-extern void cfg80211_put_dev(struct cfg80211_registered_device *drv);
 
 /* free object */
-extern void cfg80211_dev_free(struct cfg80211_registered_device *drv);
+extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
 
-extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
+extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
 			       char *newname);
 
 void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
@@ -163,15 +275,124 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev,
                       unsigned long age_secs);
 
 /* IBSS */
+int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev,
+			 struct cfg80211_ibss_params *params,
+			 struct cfg80211_cached_keys *connkeys);
 int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 		       struct net_device *dev,
-		       struct cfg80211_ibss_params *params);
+		       struct cfg80211_ibss_params *params,
+		       struct cfg80211_cached_keys *connkeys);
 void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
 int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
 			struct net_device *dev, bool nowext);
+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
+int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
+			    struct wireless_dev *wdev);
+
+/* MLME */
+int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev,
+			 struct ieee80211_channel *chan,
+			 enum nl80211_auth_type auth_type,
+			 const u8 *bssid,
+			 const u8 *ssid, int ssid_len,
+			 const u8 *ie, int ie_len,
+			 const u8 *key, int key_len, int key_idx);
+int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev, struct ieee80211_channel *chan,
+		       enum nl80211_auth_type auth_type, const u8 *bssid,
+		       const u8 *ssid, int ssid_len,
+		       const u8 *ie, int ie_len,
+		       const u8 *key, int key_len, int key_idx);
+int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev,
+			  struct ieee80211_channel *chan,
+			  const u8 *bssid, const u8 *prev_bssid,
+			  const u8 *ssid, int ssid_len,
+			  const u8 *ie, int ie_len, bool use_mfp,
+			  struct cfg80211_crypto_settings *crypt);
+int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, struct ieee80211_channel *chan,
+			const u8 *bssid, const u8 *prev_bssid,
+			const u8 *ssid, int ssid_len,
+			const u8 *ie, int ie_len, bool use_mfp,
+			struct cfg80211_crypto_settings *crypt);
+int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
+			   struct net_device *dev, const u8 *bssid,
+			   const u8 *ie, int ie_len, u16 reason);
+int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev, const u8 *bssid,
+			 const u8 *ie, int ie_len, u16 reason);
+int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
+			   struct net_device *dev, const u8 *bssid,
+			   const u8 *ie, int ie_len, u16 reason);
+void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
+			struct net_device *dev);
+void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			       const u8 *req_ie, size_t req_ie_len,
+			       const u8 *resp_ie, size_t resp_ie_len,
+			       u16 status, bool wextev,
+			       struct cfg80211_bss *bss);
+
+/* SME */
+int __cfg80211_connect(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev,
+		       struct cfg80211_connect_params *connect,
+		       struct cfg80211_cached_keys *connkeys,
+		       const u8 *prev_bssid);
+int cfg80211_connect(struct cfg80211_registered_device *rdev,
+		     struct net_device *dev,
+		     struct cfg80211_connect_params *connect,
+		     struct cfg80211_cached_keys *connkeys);
+int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev, u16 reason,
+			  bool wextev);
+int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, u16 reason,
+			bool wextev);
+void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
+		       const u8 *req_ie, size_t req_ie_len,
+		       const u8 *resp_ie, size_t resp_ie_len);
+int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
+			      struct wireless_dev *wdev);
+
+void cfg80211_conn_work(struct work_struct *work);
+bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev);
 
 /* internal helpers */
-int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
+int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
+				   struct key_params *params, int key_idx,
 				   const u8 *mac_addr);
+void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
+			     size_t ie_len, u16 reason, bool from_ap);
+void cfg80211_sme_scan_done(struct net_device *dev);
+void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
+void cfg80211_sme_disassoc(struct net_device *dev, int idx);
+void __cfg80211_scan_done(struct work_struct *wk);
+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
+void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
+int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev, enum nl80211_iftype ntype,
+			  u32 *flags, struct vif_params *params);
+void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
+
+struct ieee80211_channel *
+rdev_fixed_channel(struct cfg80211_registered_device *rdev,
+		   struct wireless_dev *for_wdev);
+int rdev_set_freq(struct cfg80211_registered_device *rdev,
+		  struct wireless_dev *for_wdev,
+		  int freq, enum nl80211_channel_type channel_type);
+
+#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
+#define CFG80211_DEV_WARN_ON(cond)	WARN_ON(cond)
+#else
+/*
+ * Trick to enable using it as a condition,
+ * and also not give a warning when it's
+ * not used that way.
+ */
+#define CFG80211_DEV_WARN_ON(cond)	({bool __r = (cond); __r; })
+#endif
 
 #endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
index 679ddfc..13d93d8 100644
--- a/net/wireless/debugfs.c
+++ b/net/wireless/debugfs.c
@@ -104,15 +104,15 @@ static const struct file_operations ht40allow_map_ops = {
 };
 
 #define DEBUGFS_ADD(name)						\
-	drv->debugfs.name = debugfs_create_file(#name, S_IRUGO, phyd,	\
-						  &drv->wiphy, &name## _ops);
+	rdev->debugfs.name = debugfs_create_file(#name, S_IRUGO, phyd,	\
+						  &rdev->wiphy, &name## _ops);
 #define DEBUGFS_DEL(name)						\
-	debugfs_remove(drv->debugfs.name);				\
-	drv->debugfs.name = NULL;
+	debugfs_remove(rdev->debugfs.name);				\
+	rdev->debugfs.name = NULL;
 
-void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv)
+void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev)
 {
-	struct dentry *phyd = drv->wiphy.debugfsdir;
+	struct dentry *phyd = rdev->wiphy.debugfsdir;
 
 	DEBUGFS_ADD(rts_threshold);
 	DEBUGFS_ADD(fragmentation_threshold);
@@ -121,7 +121,7 @@ void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv)
 	DEBUGFS_ADD(ht40allow_map);
 }
 
-void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv)
+void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev)
 {
 	DEBUGFS_DEL(rts_threshold);
 	DEBUGFS_DEL(fragmentation_threshold);
diff --git a/net/wireless/debugfs.h b/net/wireless/debugfs.h
index c226983..6419b6d 100644
--- a/net/wireless/debugfs.h
+++ b/net/wireless/debugfs.h
@@ -2,13 +2,13 @@
 #define __CFG80211_DEBUGFS_H
 
 #ifdef CONFIG_CFG80211_DEBUGFS
-void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv);
-void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv);
+void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev);
+void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev);
 #else
 static inline
-void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv) {}
+void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) {}
 static inline
-void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv) {}
+void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev) {}
 #endif
 
 #endif /* __CFG80211_DEBUGFS_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index a4a1c34..c883389 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -7,10 +7,11 @@
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <net/cfg80211.h>
+#include "wext-compat.h"
 #include "nl80211.h"
 
 
-void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct cfg80211_bss *bss;
@@ -21,10 +22,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
 		return;
 
-	if (WARN_ON(!wdev->ssid_len))
-		return;
-
-	if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0)
+	if (!wdev->ssid_len)
 		return;
 
 	bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
@@ -36,39 +34,76 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
 
 	if (wdev->current_bss) {
 		cfg80211_unhold_bss(wdev->current_bss);
-		cfg80211_put_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
 	}
 
-	cfg80211_hold_bss(bss);
-	wdev->current_bss = bss;
-	memcpy(wdev->bssid, bssid, ETH_ALEN);
+	cfg80211_hold_bss(bss_from_pub(bss));
+	wdev->current_bss = bss_from_pub(bss);
+
+	cfg80211_upload_connect_keys(wdev);
 
-	nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
+	nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
+				GFP_KERNEL);
 #ifdef CONFIG_WIRELESS_EXT
 	memset(&wrqu, 0, sizeof(wrqu));
 	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
 #endif
 }
+
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	CFG80211_DEV_WARN_ON(!wdev->ssid_len);
+
+	ev = kzalloc(sizeof(*ev), gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_IBSS_JOINED;
+	memcpy(ev->cr.bssid, bssid, ETH_ALEN);
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
+}
 EXPORT_SYMBOL(cfg80211_ibss_joined);
 
-int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
-		       struct net_device *dev,
-		       struct cfg80211_ibss_params *params)
+int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev,
+			 struct cfg80211_ibss_params *params,
+			 struct cfg80211_cached_keys *connkeys)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct ieee80211_channel *chan;
 	int err;
 
+	ASSERT_WDEV_LOCK(wdev);
+
+	chan = rdev_fixed_channel(rdev, wdev);
+	if (chan && chan != params->channel)
+		return -EBUSY;
+
 	if (wdev->ssid_len)
 		return -EALREADY;
 
+	if (WARN_ON(wdev->connect_keys))
+		kfree(wdev->connect_keys);
+	wdev->connect_keys = connkeys;
+
 #ifdef CONFIG_WIRELESS_EXT
 	wdev->wext.ibss.channel = params->channel;
 #endif
 	err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
-
-	if (err)
+	if (err) {
+		wdev->connect_keys = NULL;
 		return err;
+	}
 
 	memcpy(wdev->ssid, params->ssid, params->ssid_len);
 	wdev->ssid_len = params->ssid_len;
@@ -76,45 +111,107 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 	return 0;
 }
 
-void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev,
+		       struct cfg80211_ibss_params *params,
+		       struct cfg80211_cached_keys *connkeys)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(wdev);
+	err = __cfg80211_join_ibss(rdev, dev, params, connkeys);
+	wdev_unlock(wdev);
+	mutex_unlock(&rdev->devlist_mtx);
+
+	return err;
+}
+
+static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	int i;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	kfree(wdev->connect_keys);
+	wdev->connect_keys = NULL;
+
+	/*
+	 * Delete all the keys ... pairwise keys can't really
+	 * exist any more anyway, but default keys might.
+	 */
+	if (rdev->ops->del_key)
+		for (i = 0; i < 6; i++)
+			rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
 
 	if (wdev->current_bss) {
 		cfg80211_unhold_bss(wdev->current_bss);
-		cfg80211_put_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
 	}
 
 	wdev->current_bss = NULL;
 	wdev->ssid_len = 0;
-	memset(wdev->bssid, 0, ETH_ALEN);
 #ifdef CONFIG_WIRELESS_EXT
 	if (!nowext)
 		wdev->wext.ibss.ssid_len = 0;
 #endif
 }
 
-int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
-			struct net_device *dev, bool nowext)
+void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	wdev_lock(wdev);
+	__cfg80211_clear_ibss(dev, nowext);
+	wdev_unlock(wdev);
+}
+
+static int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+				 struct net_device *dev, bool nowext)
 {
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	int err;
 
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (!wdev->ssid_len)
+		return -ENOLINK;
+
 	err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
 
 	if (err)
 		return err;
 
-	cfg80211_clear_ibss(dev, nowext);
+	__cfg80211_clear_ibss(dev, nowext);
 
 	return 0;
 }
 
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+			struct net_device *dev, bool nowext)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_leave_ibss(rdev, dev, nowext);
+	wdev_unlock(wdev);
+
+	return err;
+}
+
 #ifdef CONFIG_WIRELESS_EXT
-static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
-				   struct wireless_dev *wdev)
+int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
+			    struct wireless_dev *wdev)
 {
+	struct cfg80211_cached_keys *ck = NULL;
 	enum ieee80211_band band;
-	int i;
+	int i, err;
+
+	ASSERT_WDEV_LOCK(wdev);
 
 	if (!wdev->wext.ibss.beacon_interval)
 		wdev->wext.ibss.beacon_interval = 100;
@@ -154,43 +251,66 @@ static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 	if (!netif_running(wdev->netdev))
 		return 0;
 
-	return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy),
-				  wdev->netdev, &wdev->wext.ibss);
+	if (wdev->wext.keys)
+		wdev->wext.keys->def = wdev->wext.default_key;
+
+	wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
+
+	if (wdev->wext.keys) {
+		ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
+		if (!ck)
+			return -ENOMEM;
+		for (i = 0; i < 6; i++)
+			ck->params[i].key = ck->data[i];
+	}
+	err = __cfg80211_join_ibss(rdev, wdev->netdev,
+				   &wdev->wext.ibss, ck);
+	if (err)
+		kfree(ck);
+
+	return err;
 }
 
 int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
 			       struct iw_request_info *info,
-			       struct iw_freq *freq, char *extra)
+			       struct iw_freq *wextfreq, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct ieee80211_channel *chan;
-	int err;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct ieee80211_channel *chan = NULL;
+	int err, freq;
 
 	/* call only for ibss! */
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
 		return -EINVAL;
 
-	if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+	if (!rdev->ops->join_ibss)
 		return -EOPNOTSUPP;
 
-	chan = cfg80211_wext_freq(wdev->wiphy, freq);
-	if (chan && IS_ERR(chan))
-		return PTR_ERR(chan);
+	freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
+	if (freq < 0)
+		return freq;
 
-	if (chan &&
-	    (chan->flags & IEEE80211_CHAN_NO_IBSS ||
-	     chan->flags & IEEE80211_CHAN_DISABLED))
-		return -EINVAL;
+	if (freq) {
+		chan = ieee80211_get_channel(wdev->wiphy, freq);
+		if (!chan)
+			return -EINVAL;
+		if (chan->flags & IEEE80211_CHAN_NO_IBSS ||
+		    chan->flags & IEEE80211_CHAN_DISABLED)
+			return -EINVAL;
+	}
 
 	if (wdev->wext.ibss.channel == chan)
 		return 0;
 
-	if (wdev->ssid_len) {
-		err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
-					  dev, true);
-		if (err)
-			return err;
-	}
+	wdev_lock(wdev);
+	err = 0;
+	if (wdev->ssid_len)
+		err = __cfg80211_leave_ibss(rdev, dev, true);
+	wdev_unlock(wdev);
+
+	if (err)
+		return err;
 
 	if (chan) {
 		wdev->wext.ibss.channel = chan;
@@ -200,10 +320,14 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
 		wdev->wext.ibss.channel_fixed = false;
 	}
 
-	return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(wdev);
+	err = cfg80211_ibss_wext_join(rdev, wdev);
+	wdev_unlock(wdev);
+	mutex_unlock(&rdev->devlist_mtx);
+
+	return err;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
 
 int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
 			       struct iw_request_info *info,
@@ -216,10 +340,12 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
 		return -EINVAL;
 
+	wdev_lock(wdev);
 	if (wdev->current_bss)
-		chan = wdev->current_bss->channel;
+		chan = wdev->current_bss->pub.channel;
 	else if (wdev->wext.ibss.channel)
 		chan = wdev->wext.ibss.channel;
+	wdev_unlock(wdev);
 
 	if (chan) {
 		freq->m = chan->center_freq;
@@ -230,14 +356,13 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
 	/* no channel if not joining */
 	return -EINVAL;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
 
 int cfg80211_ibss_wext_siwessid(struct net_device *dev,
 				struct iw_request_info *info,
 				struct iw_point *data, char *ssid)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 	size_t len = data->length;
 	int err;
 
@@ -245,15 +370,17 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
 		return -EINVAL;
 
-	if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+	if (!rdev->ops->join_ibss)
 		return -EOPNOTSUPP;
 
-	if (wdev->ssid_len) {
-		err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
-					  dev, true);
-		if (err)
-			return err;
-	}
+	wdev_lock(wdev);
+	err = 0;
+	if (wdev->ssid_len)
+		err = __cfg80211_leave_ibss(rdev, dev, true);
+	wdev_unlock(wdev);
+
+	if (err)
+		return err;
 
 	/* iwconfig uses nul termination in SSID.. */
 	if (len > 0 && ssid[len - 1] == '\0')
@@ -263,10 +390,14 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
 	memcpy(wdev->wext.ibss.ssid, ssid, len);
 	wdev->wext.ibss.ssid_len = len;
 
-	return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(wdev);
+	err = cfg80211_ibss_wext_join(rdev, wdev);
+	wdev_unlock(wdev);
+	mutex_unlock(&rdev->devlist_mtx);
+
+	return err;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
 
 int cfg80211_ibss_wext_giwessid(struct net_device *dev,
 				struct iw_request_info *info,
@@ -280,6 +411,7 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev,
 
 	data->flags = 0;
 
+	wdev_lock(wdev);
 	if (wdev->ssid_len) {
 		data->flags = 1;
 		data->length = wdev->ssid_len;
@@ -289,17 +421,17 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev,
 		data->length = wdev->wext.ibss.ssid_len;
 		memcpy(ssid, wdev->wext.ibss.ssid, data->length);
 	}
+	wdev_unlock(wdev);
 
 	return 0;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
 
 int cfg80211_ibss_wext_siwap(struct net_device *dev,
 			     struct iw_request_info *info,
 			     struct sockaddr *ap_addr, char *extra)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
 	u8 *bssid = ap_addr->sa_data;
 	int err;
 
@@ -307,7 +439,7 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
 		return -EINVAL;
 
-	if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+	if (!rdev->ops->join_ibss)
 		return -EOPNOTSUPP;
 
 	if (ap_addr->sa_family != ARPHRD_ETHER)
@@ -326,12 +458,14 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
 	    compare_ether_addr(bssid, wdev->wext.ibss.bssid) == 0)
 		return 0;
 
-	if (wdev->ssid_len) {
-		err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
-					  dev, true);
-		if (err)
-			return err;
-	}
+	wdev_lock(wdev);
+	err = 0;
+	if (wdev->ssid_len)
+		err = __cfg80211_leave_ibss(rdev, dev, true);
+	wdev_unlock(wdev);
+
+	if (err)
+		return err;
 
 	if (bssid) {
 		memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
@@ -339,10 +473,14 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
 	} else
 		wdev->wext.ibss.bssid = NULL;
 
-	return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(wdev);
+	err = cfg80211_ibss_wext_join(rdev, wdev);
+	wdev_unlock(wdev);
+	mutex_unlock(&rdev->devlist_mtx);
+
+	return err;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
 
 int cfg80211_ibss_wext_giwap(struct net_device *dev,
 			     struct iw_request_info *info,
@@ -356,14 +494,16 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev,
 
 	ap_addr->sa_family = ARPHRD_ETHER;
 
-	if (wdev->wext.ibss.bssid) {
+	wdev_lock(wdev);
+	if (wdev->current_bss)
+		memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN);
+	else if (wdev->wext.ibss.bssid)
 		memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
-		return 0;
-	}
+	else
+		memset(ap_addr->sa_data, 0, ETH_ALEN);
+
+	wdev_unlock(wdev);
 
-	memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN);
 	return 0;
 }
-/* temporary symbol - mark GPL - in the future the handler won't be */
-EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
 #endif
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 4218436..79d2eec 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -8,75 +8,652 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/nl80211.h>
+#include <linux/wireless.h>
 #include <net/cfg80211.h>
+#include <net/iw_handler.h>
 #include "core.h"
 #include "nl80211.h"
 
 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	nl80211_send_rx_auth(rdev, dev, buf, len);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	u8 *bssid = mgmt->bssid;
+	int i;
+	u16 status = le16_to_cpu(mgmt->u.auth.status_code);
+	bool done = false;
+
+	wdev_lock(wdev);
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
+							ETH_ALEN) == 0) {
+			if (status == WLAN_STATUS_SUCCESS) {
+				wdev->auth_bsses[i] = wdev->authtry_bsses[i];
+			} else {
+				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+			}
+			wdev->authtry_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+
+	WARN_ON(!done);
+
+	nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
+	cfg80211_sme_rx_auth(dev, buf, len);
+
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_auth);
 
 void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	u16 status_code;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	nl80211_send_rx_assoc(rdev, dev, buf, len);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	u8 *ie = mgmt->u.assoc_resp.variable;
+	int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
+	struct cfg80211_internal_bss *bss = NULL;
+
+	wdev_lock(wdev);
+
+	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
+
+	/*
+	 * This is a bit of a hack, we don't notify userspace of
+	 * a (re-)association reply if we tried to send a reassoc
+	 * and got a reject -- we only try again with an assoc
+	 * frame instead of reassoc.
+	 */
+	if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
+	    cfg80211_sme_failed_reassoc(wdev))
+		goto out;
+
+	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
+
+	if (status_code == WLAN_STATUS_SUCCESS) {
+		for (i = 0; i < MAX_AUTH_BSSES; i++) {
+			if (!wdev->auth_bsses[i])
+				continue;
+			if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid,
+				   ETH_ALEN) == 0) {
+				bss = wdev->auth_bsses[i];
+				wdev->auth_bsses[i] = NULL;
+				/* additional reference to drop hold */
+				cfg80211_ref_bss(bss);
+				break;
+			}
+		}
+
+		WARN_ON(!bss);
+	}
+
+	if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
+		/*
+		 * This is for the userspace SME, the CONNECTING
+		 * state will be changed to CONNECTED by
+		 * __cfg80211_connect_result() below.
+		 */
+		wdev->sme_state = CFG80211_SME_CONNECTING;
+	}
+
+	/* this consumes one bss reference (unless bss is NULL) */
+	__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
+				  status_code,
+				  status_code == WLAN_STATUS_SUCCESS,
+				  bss ? &bss->pub : NULL);
+	/* drop hold now, and also reference acquired above */
+	if (bss) {
+		cfg80211_unhold_bss(bss);
+		cfg80211_put_bss(&bss->pub);
+	}
+
+ out:
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
 
-void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
+static void __cfg80211_send_deauth(struct net_device *dev,
+				   const u8 *buf, size_t len)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	nl80211_send_deauth(rdev, dev, buf, len);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	const u8 *bssid = mgmt->bssid;
+	int i;
+	bool done = false;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
+
+	if (wdev->current_bss &&
+	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
+		done = true;
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
+		wdev->current_bss = NULL;
+	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i] &&
+		    memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->auth_bsses[i]);
+			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
+			wdev->auth_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+			wdev->authtry_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+
+	WARN_ON(!done);
+
+	if (wdev->sme_state == CFG80211_SME_CONNECTED) {
+		u16 reason_code;
+		bool from_ap;
+
+		reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
+
+		from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
+		__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
+	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
+		__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  false, NULL);
+	}
+}
+
+
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len,
+			  void *cookie)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	BUG_ON(cookie && wdev != cookie);
+
+	if (cookie) {
+		/* called within callback */
+		__cfg80211_send_deauth(dev, buf, len);
+	} else {
+		wdev_lock(wdev);
+		__cfg80211_send_deauth(dev, buf, len);
+		wdev_unlock(wdev);
+	}
 }
 EXPORT_SYMBOL(cfg80211_send_deauth);
 
-void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
+static void __cfg80211_send_disassoc(struct net_device *dev,
+				     const u8 *buf, size_t len)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	nl80211_send_disassoc(rdev, dev, buf, len);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	const u8 *bssid = mgmt->bssid;
+	int i;
+	u16 reason_code;
+	bool from_ap;
+	bool done = false;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
+
+	if (wdev->sme_state != CFG80211_SME_CONNECTED)
+		return;
+
+	if (wdev->current_bss &&
+	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
+		for (i = 0; i < MAX_AUTH_BSSES; i++) {
+			if (wdev->authtry_bsses[i] || wdev->auth_bsses[i])
+				continue;
+			wdev->auth_bsses[i] = wdev->current_bss;
+			wdev->current_bss = NULL;
+			done = true;
+			cfg80211_sme_disassoc(dev, i);
+			break;
+		}
+		WARN_ON(!done);
+	} else
+		WARN_ON(1);
+
+
+	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
+
+	from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
+	__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
 }
-EXPORT_SYMBOL(cfg80211_send_disassoc);
 
-static void cfg80211_wext_disconnected(struct net_device *dev)
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len,
+			    void *cookie)
 {
-#ifdef CONFIG_WIRELESS_EXT
-	union iwreq_data wrqu;
-	memset(&wrqu, 0, sizeof(wrqu));
-	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
-#endif
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	BUG_ON(cookie && wdev != cookie);
+
+	if (cookie) {
+		/* called within callback */
+		__cfg80211_send_disassoc(dev, buf, len);
+	} else {
+		wdev_lock(wdev);
+		__cfg80211_send_disassoc(dev, buf, len);
+		wdev_unlock(wdev);
+	}
 }
+EXPORT_SYMBOL(cfg80211_send_disassoc);
 
 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	nl80211_send_auth_timeout(rdev, dev, addr);
-	cfg80211_wext_disconnected(dev);
+	int i;
+	bool done = false;
+
+	wdev_lock(wdev);
+
+	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
+	if (wdev->sme_state == CFG80211_SME_CONNECTING)
+		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  false, NULL);
+
+	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(wdev->authtry_bsses[i]->pub.bssid,
+			   addr, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+			wdev->authtry_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+
+	WARN_ON(!done);
+
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 
 void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
 {
-	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	nl80211_send_assoc_timeout(rdev, dev, addr);
-	cfg80211_wext_disconnected(dev);
+	int i;
+	bool done = false;
+
+	wdev_lock(wdev);
+
+	nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
+	if (wdev->sme_state == CFG80211_SME_CONNECTING)
+		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  false, NULL);
+
+	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i] &&
+		    memcmp(wdev->auth_bsses[i]->pub.bssid,
+			   addr, ETH_ALEN) == 0) {
+			cfg80211_unhold_bss(wdev->auth_bsses[i]);
+			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
+			wdev->auth_bsses[i] = NULL;
+			done = true;
+			break;
+		}
+	}
+
+	WARN_ON(!done);
+
+	wdev_unlock(wdev);
 }
 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
 
 void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
 				  enum nl80211_key_type key_type, int key_id,
-				  const u8 *tsc)
+				  const u8 *tsc, gfp_t gfp)
 {
 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc);
+#ifdef CONFIG_WIRELESS_EXT
+	union iwreq_data wrqu;
+	char *buf = kmalloc(128, gfp);
+
+	if (buf) {
+		sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
+			"keyid=%d %scast addr=%pM)", key_id,
+			key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
+			addr);
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = strlen(buf);
+		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
+		kfree(buf);
+	}
+#endif
+
+	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
 }
 EXPORT_SYMBOL(cfg80211_michael_mic_failure);
+
+/* some MLME handling for userspace SME */
+int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev,
+			 struct ieee80211_channel *chan,
+			 enum nl80211_auth_type auth_type,
+			 const u8 *bssid,
+			 const u8 *ssid, int ssid_len,
+			 const u8 *ie, int ie_len,
+			 const u8 *key, int key_len, int key_idx)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_auth_request req;
+	struct cfg80211_internal_bss *bss;
+	int i, err, slot = -1, nfree = 0;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
+		if (!key || !key_len || key_idx < 0 || key_idx > 4)
+			return -EINVAL;
+
+	if (wdev->current_bss &&
+	    memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
+		return -EALREADY;
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid,
+						ETH_ALEN) == 0)
+			return -EALREADY;
+		if (wdev->auth_bsses[i] &&
+		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
+						ETH_ALEN) == 0)
+			return -EALREADY;
+	}
+
+	memset(&req, 0, sizeof(req));
+
+	req.ie = ie;
+	req.ie_len = ie_len;
+	req.auth_type = auth_type;
+	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
+				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+	req.key = key;
+	req.key_len = key_len;
+	req.key_idx = key_idx;
+	if (!req.bss)
+		return -ENOENT;
+
+	bss = bss_from_pub(req.bss);
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
+			slot = i;
+			nfree++;
+		}
+	}
+
+	/* we need one free slot for disassoc and one for this auth */
+	if (nfree < 2) {
+		err = -ENOSPC;
+		goto out;
+	}
+
+	wdev->authtry_bsses[slot] = bss;
+	cfg80211_hold_bss(bss);
+
+	err = rdev->ops->auth(&rdev->wiphy, dev, &req);
+	if (err) {
+		wdev->authtry_bsses[slot] = NULL;
+		cfg80211_unhold_bss(bss);
+	}
+
+ out:
+	if (err)
+		cfg80211_put_bss(req.bss);
+	return err;
+}
+
+int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev, struct ieee80211_channel *chan,
+		       enum nl80211_auth_type auth_type, const u8 *bssid,
+		       const u8 *ssid, int ssid_len,
+		       const u8 *ie, int ie_len,
+		       const u8 *key, int key_len, int key_idx)
+{
+	int err;
+
+	wdev_lock(dev->ieee80211_ptr);
+	err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
+				   ssid, ssid_len, ie, ie_len,
+				   key, key_len, key_idx);
+	wdev_unlock(dev->ieee80211_ptr);
+
+	return err;
+}
+
+int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev,
+			  struct ieee80211_channel *chan,
+			  const u8 *bssid, const u8 *prev_bssid,
+			  const u8 *ssid, int ssid_len,
+			  const u8 *ie, int ie_len, bool use_mfp,
+			  struct cfg80211_crypto_settings *crypt)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_assoc_request req;
+	struct cfg80211_internal_bss *bss;
+	int i, err, slot = -1;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	memset(&req, 0, sizeof(req));
+
+	if (wdev->current_bss)
+		return -EALREADY;
+
+	req.ie = ie;
+	req.ie_len = ie_len;
+	memcpy(&req.crypto, crypt, sizeof(req.crypto));
+	req.use_mfp = use_mfp;
+	req.prev_bssid = prev_bssid;
+	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
+				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+	if (!req.bss)
+		return -ENOENT;
+
+	bss = bss_from_pub(req.bss);
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (bss == wdev->auth_bsses[i]) {
+			slot = i;
+			break;
+		}
+	}
+
+	if (slot < 0) {
+		err = -ENOTCONN;
+		goto out;
+	}
+
+	err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
+ out:
+	/* still a reference in wdev->auth_bsses[slot] */
+	cfg80211_put_bss(req.bss);
+	return err;
+}
+
+int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
+			struct net_device *dev,
+			struct ieee80211_channel *chan,
+			const u8 *bssid, const u8 *prev_bssid,
+			const u8 *ssid, int ssid_len,
+			const u8 *ie, int ie_len, bool use_mfp,
+			struct cfg80211_crypto_settings *crypt)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
+				    ssid, ssid_len, ie, ie_len, use_mfp, crypt);
+	wdev_unlock(wdev);
+
+	return err;
+}
+
+int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
+			   struct net_device *dev, const u8 *bssid,
+			   const u8 *ie, int ie_len, u16 reason)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_deauth_request req;
+	int i;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	memset(&req, 0, sizeof(req));
+	req.reason_code = reason;
+	req.ie = ie;
+	req.ie_len = ie_len;
+	if (wdev->current_bss &&
+	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
+		req.bss = &wdev->current_bss->pub;
+	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i] &&
+		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
+			req.bss = &wdev->auth_bsses[i]->pub;
+			break;
+		}
+		if (wdev->authtry_bsses[i] &&
+		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
+			req.bss = &wdev->authtry_bsses[i]->pub;
+			break;
+		}
+	}
+
+	if (!req.bss)
+		return -ENOTCONN;
+
+	return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
+}
+
+int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
+			 struct net_device *dev, const u8 *bssid,
+			 const u8 *ie, int ie_len, u16 reason)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason);
+	wdev_unlock(wdev);
+
+	return err;
+}
+
+static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
+				    struct net_device *dev, const u8 *bssid,
+				    const u8 *ie, int ie_len, u16 reason)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_disassoc_request req;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (wdev->sme_state != CFG80211_SME_CONNECTED)
+		return -ENOTCONN;
+
+	if (WARN_ON(!wdev->current_bss))
+		return -ENOTCONN;
+
+	memset(&req, 0, sizeof(req));
+	req.reason_code = reason;
+	req.ie = ie;
+	req.ie_len = ie_len;
+	if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
+		req.bss = &wdev->current_bss->pub;
+	else
+		return -ENOTCONN;
+
+	return rdev->ops->disassoc(&rdev->wiphy, dev, &req, wdev);
+}
+
+int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
+			   struct net_device *dev, const u8 *bssid,
+			   const u8 *ie, int ie_len, u16 reason)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	wdev_lock(wdev);
+	err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason);
+	wdev_unlock(wdev);
+
+	return err;
+}
+
+void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
+			struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_deauth_request req;
+	int i;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (!rdev->ops->deauth)
+		return;
+
+	memset(&req, 0, sizeof(req));
+	req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
+	req.ie = NULL;
+	req.ie_len = 0;
+
+	if (wdev->current_bss) {
+		req.bss = &wdev->current_bss->pub;
+		rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
+		if (wdev->current_bss) {
+			cfg80211_unhold_bss(wdev->current_bss);
+			cfg80211_put_bss(&wdev->current_bss->pub);
+			wdev->current_bss = NULL;
+		}
+	}
+
+	for (i = 0; i < MAX_AUTH_BSSES; i++) {
+		if (wdev->auth_bsses[i]) {
+			req.bss = &wdev->auth_bsses[i]->pub;
+			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
+			if (wdev->auth_bsses[i]) {
+				cfg80211_unhold_bss(wdev->auth_bsses[i]);
+				cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
+				wdev->auth_bsses[i] = NULL;
+			}
+		}
+		if (wdev->authtry_bsses[i]) {
+			req.bss = &wdev->authtry_bsses[i]->pub;
+			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
+			if (wdev->authtry_bsses[i]) {
+				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
+				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
+				wdev->authtry_bsses[i] = NULL;
+			}
+		}
+	}
+}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 634496b..eddab09 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14,8 +14,10 @@
 #include <linux/rtnetlink.h>
 #include <linux/netlink.h>
 #include <linux/etherdevice.h>
+#include <net/net_namespace.h>
 #include <net/genetlink.h>
 #include <net/cfg80211.h>
+#include <net/sock.h>
 #include "core.h"
 #include "nl80211.h"
 #include "reg.h"
@@ -27,27 +29,29 @@ static struct genl_family nl80211_fam = {
 	.hdrsize = 0,		/* no private header */
 	.version = 1,		/* no particular meaning now */
 	.maxattr = NL80211_ATTR_MAX,
+	.netnsok = true,
 };
 
-/* internal helper: get drv and dev */
-static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,
-				       struct cfg80211_registered_device **drv,
+/* internal helper: get rdev and dev */
+static int get_rdev_dev_by_info_ifindex(struct genl_info *info,
+				       struct cfg80211_registered_device **rdev,
 				       struct net_device **dev)
 {
+	struct nlattr **attrs = info->attrs;
 	int ifindex;
 
 	if (!attrs[NL80211_ATTR_IFINDEX])
 		return -EINVAL;
 
 	ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
-	*dev = dev_get_by_index(&init_net, ifindex);
+	*dev = dev_get_by_index(genl_info_net(info), ifindex);
 	if (!*dev)
 		return -ENODEV;
 
-	*drv = cfg80211_get_dev_from_ifindex(ifindex);
-	if (IS_ERR(*drv)) {
+	*rdev = cfg80211_get_dev_from_ifindex(genl_info_net(info), ifindex);
+	if (IS_ERR(*rdev)) {
 		dev_put(*dev);
-		return PTR_ERR(*drv);
+		return PTR_ERR(*rdev);
 	}
 
 	return 0;
@@ -71,7 +75,9 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
 
 	[NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN },
 
+	[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
 	[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
 				    .len = WLAN_MAX_KEY_LEN },
 	[NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
@@ -128,6 +134,21 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
 		.len = sizeof(struct nl80211_sta_flag_update),
 	},
 	[NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
+	[NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
+	[NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
+	[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
+	[NL80211_ATTR_PID] = { .type = NLA_U32 },
+};
+
+/* policy for the attributes */
+static struct nla_policy
+nl80211_key_policy[NL80211_KEY_MAX + 1] __read_mostly = {
+	[NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
+	[NL80211_KEY_IDX] = { .type = NLA_U8 },
+	[NL80211_KEY_CIPHER] = { .type = NLA_U32 },
+	[NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
+	[NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
+	[NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
 };
 
 /* IE validation */
@@ -194,6 +215,177 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
 
 /* netlink command implementations */
 
+struct key_parse {
+	struct key_params p;
+	int idx;
+	bool def, defmgmt;
+};
+
+static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
+{
+	struct nlattr *tb[NL80211_KEY_MAX + 1];
+	int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
+				   nl80211_key_policy);
+	if (err)
+		return err;
+
+	k->def = !!tb[NL80211_KEY_DEFAULT];
+	k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
+
+	if (tb[NL80211_KEY_IDX])
+		k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
+
+	if (tb[NL80211_KEY_DATA]) {
+		k->p.key = nla_data(tb[NL80211_KEY_DATA]);
+		k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
+	}
+
+	if (tb[NL80211_KEY_SEQ]) {
+		k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
+		k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
+	}
+
+	if (tb[NL80211_KEY_CIPHER])
+		k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
+
+	return 0;
+}
+
+static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
+{
+	if (info->attrs[NL80211_ATTR_KEY_DATA]) {
+		k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
+		k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
+	}
+
+	if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
+		k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
+		k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
+	}
+
+	if (info->attrs[NL80211_ATTR_KEY_IDX])
+		k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+
+	if (info->attrs[NL80211_ATTR_KEY_CIPHER])
+		k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
+
+	k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
+	k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
+
+	return 0;
+}
+
+static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
+{
+	int err;
+
+	memset(k, 0, sizeof(*k));
+	k->idx = -1;
+
+	if (info->attrs[NL80211_ATTR_KEY])
+		err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
+	else
+		err = nl80211_parse_key_old(info, k);
+
+	if (err)
+		return err;
+
+	if (k->def && k->defmgmt)
+		return -EINVAL;
+
+	if (k->idx != -1) {
+		if (k->defmgmt) {
+			if (k->idx < 4 || k->idx > 5)
+				return -EINVAL;
+		} else if (k->def) {
+			if (k->idx < 0 || k->idx > 3)
+				return -EINVAL;
+		} else {
+			if (k->idx < 0 || k->idx > 5)
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static struct cfg80211_cached_keys *
+nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
+		       struct nlattr *keys)
+{
+	struct key_parse parse;
+	struct nlattr *key;
+	struct cfg80211_cached_keys *result;
+	int rem, err, def = 0;
+
+	result = kzalloc(sizeof(*result), GFP_KERNEL);
+	if (!result)
+		return ERR_PTR(-ENOMEM);
+
+	result->def = -1;
+	result->defmgmt = -1;
+
+	nla_for_each_nested(key, keys, rem) {
+		memset(&parse, 0, sizeof(parse));
+		parse.idx = -1;
+
+		err = nl80211_parse_key_new(key, &parse);
+		if (err)
+			goto error;
+		err = -EINVAL;
+		if (!parse.p.key)
+			goto error;
+		if (parse.idx < 0 || parse.idx > 4)
+			goto error;
+		if (parse.def) {
+			if (def)
+				goto error;
+			def = 1;
+			result->def = parse.idx;
+		} else if (parse.defmgmt)
+			goto error;
+		err = cfg80211_validate_key_settings(rdev, &parse.p,
+						     parse.idx, NULL);
+		if (err)
+			goto error;
+		result->params[parse.idx].cipher = parse.p.cipher;
+		result->params[parse.idx].key_len = parse.p.key_len;
+		result->params[parse.idx].key = result->data[parse.idx];
+		memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
+	}
+
+	return result;
+ error:
+	kfree(result);
+	return ERR_PTR(err);
+}
+
+static int nl80211_key_allowed(struct wireless_dev *wdev)
+{
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (!netif_running(wdev->netdev))
+		return -ENETDOWN;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_AP_VLAN:
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		if (!wdev->current_bss)
+			return -ENOLINK;
+		break;
+	case NL80211_IFTYPE_STATION:
+		if (wdev->sme_state != CFG80211_SME_CONNECTED)
+			return -ENOLINK;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 			      struct cfg80211_registered_device *dev)
 {
@@ -216,6 +408,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
 	NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
 
+	NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
+		    cfg80211_rdev_list_generation);
+
 	NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
 		   dev->wiphy.retry_short);
 	NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
@@ -345,8 +540,23 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	CMD(deauth, DEAUTHENTICATE);
 	CMD(disassoc, DISASSOCIATE);
 	CMD(join_ibss, JOIN_IBSS);
+	if (dev->wiphy.netnsok) {
+		i++;
+		NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
+	}
 
 #undef CMD
+
+	if (dev->ops->connect || dev->ops->auth) {
+		i++;
+		NLA_PUT_U32(msg, i, NL80211_CMD_CONNECT);
+	}
+
+	if (dev->ops->disconnect || dev->ops->deauth) {
+		i++;
+		NLA_PUT_U32(msg, i, NL80211_CMD_DISCONNECT);
+	}
+
 	nla_nest_end(msg, nl_cmds);
 
 	return genlmsg_end(msg, hdr);
@@ -363,7 +573,9 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
 	struct cfg80211_registered_device *dev;
 
 	mutex_lock(&cfg80211_mutex);
-	list_for_each_entry(dev, &cfg80211_drv_list, list) {
+	list_for_each_entry(dev, &cfg80211_rdev_list, list) {
+		if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
+			continue;
 		if (++idx <= start)
 			continue;
 		if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
@@ -396,14 +608,14 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
 	if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
 		goto out_free;
 
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 
-	return genlmsg_unicast(msg, info->snd_pid);
+	return genlmsg_reply(msg, info);
 
  out_free:
 	nlmsg_free(msg);
  out_err:
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 	return -ENOBUFS;
 }
 
@@ -445,7 +657,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 
 	mutex_lock(&cfg80211_mutex);
 
-	rdev = __cfg80211_drv_from_info(info);
+	rdev = __cfg80211_rdev_from_info(info);
 	if (IS_ERR(rdev)) {
 		mutex_unlock(&cfg80211_mutex);
 		result = PTR_ERR(rdev);
@@ -492,15 +704,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 
 	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
 		enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
-		struct ieee80211_channel *chan;
-		struct ieee80211_sta_ht_cap *ht_cap;
 		u32 freq;
 
-		if (!rdev->ops->set_channel) {
-			result = -EOPNOTSUPP;
-			goto bad_res;
-		}
-
 		result = -EINVAL;
 
 		if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
@@ -514,38 +719,10 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 		}
 
 		freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
-		chan = ieee80211_get_channel(&rdev->wiphy, freq);
-
-		/* Primary channel not allowed */
-		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
-			goto bad_res;
-
-		if (channel_type == NL80211_CHAN_HT40MINUS &&
-		    (chan->flags & IEEE80211_CHAN_NO_HT40MINUS))
-			goto bad_res;
-		else if (channel_type == NL80211_CHAN_HT40PLUS &&
-			 (chan->flags & IEEE80211_CHAN_NO_HT40PLUS))
-			goto bad_res;
-
-		/*
-		 * At this point we know if that if HT40 was requested
-		 * we are allowed to use it and the extension channel
-		 * exists.
-		 */
-
-		ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
 
-		/* no HT capabilities or intolerant */
-		if (channel_type != NL80211_CHAN_NO_HT) {
-			if (!ht_cap->ht_supported)
-				goto bad_res;
-			if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
-			    (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
-				goto bad_res;
-		}
-
-		result = rdev->ops->set_channel(&rdev->wiphy, chan,
-						channel_type);
+		mutex_lock(&rdev->devlist_mtx);
+		result = rdev_set_freq(rdev, NULL, freq, channel_type);
+		mutex_unlock(&rdev->devlist_mtx);
 		if (result)
 			goto bad_res;
 	}
@@ -651,6 +828,11 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
 	NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
 	NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
+
+	NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
+		    rdev->devlist_generation ^
+			(cfg80211_rdev_list_generation << 2));
+
 	return genlmsg_end(msg, hdr);
 
  nla_put_failure:
@@ -664,32 +846,34 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
 	int if_idx = 0;
 	int wp_start = cb->args[0];
 	int if_start = cb->args[1];
-	struct cfg80211_registered_device *dev;
+	struct cfg80211_registered_device *rdev;
 	struct wireless_dev *wdev;
 
 	mutex_lock(&cfg80211_mutex);
-	list_for_each_entry(dev, &cfg80211_drv_list, list) {
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
+		if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
+			continue;
 		if (wp_idx < wp_start) {
 			wp_idx++;
 			continue;
 		}
 		if_idx = 0;
 
-		mutex_lock(&dev->devlist_mtx);
-		list_for_each_entry(wdev, &dev->netdev_list, list) {
+		mutex_lock(&rdev->devlist_mtx);
+		list_for_each_entry(wdev, &rdev->netdev_list, list) {
 			if (if_idx < if_start) {
 				if_idx++;
 				continue;
 			}
 			if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
 					       cb->nlh->nlmsg_seq, NLM_F_MULTI,
-					       dev, wdev->netdev) < 0) {
-				mutex_unlock(&dev->devlist_mtx);
+					       rdev, wdev->netdev) < 0) {
+				mutex_unlock(&rdev->devlist_mtx);
 				goto out;
 			}
 			if_idx++;
 		}
-		mutex_unlock(&dev->devlist_mtx);
+		mutex_unlock(&rdev->devlist_mtx);
 
 		wp_idx++;
 	}
@@ -709,7 +893,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
 	struct net_device *netdev;
 	int err;
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);
+	err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
 	if (err)
 		return err;
 
@@ -722,15 +906,15 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
 		goto out_free;
 
 	dev_put(netdev);
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 
-	return genlmsg_unicast(msg, info->snd_pid);
+	return genlmsg_reply(msg, info);
 
  out_free:
 	nlmsg_free(msg);
  out_err:
 	dev_put(netdev);
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
 	return -ENOBUFS;
 }
 
@@ -765,9 +949,9 @@ static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
 
 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct vif_params params;
-	int err, ifindex;
+	int err;
 	enum nl80211_iftype otype, ntype;
 	struct net_device *dev;
 	u32 _flags, *flags = NULL;
@@ -777,13 +961,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	ifindex = dev->ifindex;
 	otype = ntype = dev->ieee80211_ptr->iftype;
-	dev_put(dev);
 
 	if (info->attrs[NL80211_ATTR_IFTYPE]) {
 		ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
@@ -795,12 +977,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 		}
 	}
 
-	if (!drv->ops->change_virtual_intf ||
-	    !(drv->wiphy.interface_modes & (1 << ntype))) {
-		err = -EOPNOTSUPP;
-		goto unlock;
-	}
-
 	if (info->attrs[NL80211_ATTR_MESH_ID]) {
 		if (ntype != NL80211_IFTYPE_MESH_POINT) {
 			err = -EINVAL;
@@ -826,21 +1002,13 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	if (change)
-		err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
-						    ntype, flags, &params);
+		err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
 	else
 		err = 0;
 
-	dev = __dev_get_by_index(&init_net, ifindex);
-	WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
-
-	if (dev && !err && (ntype != otype)) {
-		if (otype == NL80211_IFTYPE_ADHOC)
-			cfg80211_clear_ibss(dev, false);
-	}
-
  unlock:
-	cfg80211_put_dev(drv);
+	dev_put(dev);
+	cfg80211_unlock_rdev(rdev);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -848,7 +1016,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct vif_params params;
 	int err;
 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
@@ -867,14 +1035,14 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	drv = cfg80211_get_dev_from_info(info);
-	if (IS_ERR(drv)) {
-		err = PTR_ERR(drv);
+	rdev = cfg80211_get_dev_from_info(info);
+	if (IS_ERR(rdev)) {
+		err = PTR_ERR(rdev);
 		goto unlock_rtnl;
 	}
 
-	if (!drv->ops->add_virtual_intf ||
-	    !(drv->wiphy.interface_modes & (1 << type))) {
+	if (!rdev->ops->add_virtual_intf ||
+	    !(rdev->wiphy.interface_modes & (1 << type))) {
 		err = -EOPNOTSUPP;
 		goto unlock;
 	}
@@ -888,12 +1056,12 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 	err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
 				  info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
 				  &flags);
-	err = drv->ops->add_virtual_intf(&drv->wiphy,
+	err = rdev->ops->add_virtual_intf(&rdev->wiphy,
 		nla_data(info->attrs[NL80211_ATTR_IFNAME]),
 		type, err ? NULL : &flags, &params);
 
  unlock:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -901,27 +1069,26 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
-	int ifindex, err;
+	struct cfg80211_registered_device *rdev;
+	int err;
 	struct net_device *dev;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
-	ifindex = dev->ifindex;
-	dev_put(dev);
 
-	if (!drv->ops->del_virtual_intf) {
+	if (!rdev->ops->del_virtual_intf) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_virtual_intf(&drv->wiphy, ifindex);
+	err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
+	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
 	return err;
@@ -930,10 +1097,12 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
 struct get_key_cookie {
 	struct sk_buff *msg;
 	int error;
+	int idx;
 };
 
 static void get_key_callback(void *c, struct key_params *params)
 {
+	struct nlattr *key;
 	struct get_key_cookie *cookie = c;
 
 	if (params->key)
@@ -948,6 +1117,26 @@ static void get_key_callback(void *c, struct key_params *params)
 		NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
 			    params->cipher);
 
+	key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
+	if (!key)
+		goto nla_put_failure;
+
+	if (params->key)
+		NLA_PUT(cookie->msg, NL80211_KEY_DATA,
+			params->key_len, params->key);
+
+	if (params->seq)
+		NLA_PUT(cookie->msg, NL80211_KEY_SEQ,
+			params->seq_len, params->seq);
+
+	if (params->cipher)
+		NLA_PUT_U32(cookie->msg, NL80211_KEY_CIPHER,
+			    params->cipher);
+
+	NLA_PUT_U8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx);
+
+	nla_nest_end(cookie->msg, key);
+
 	return;
  nla_put_failure:
 	cookie->error = 1;
@@ -955,7 +1144,7 @@ static void get_key_callback(void *c, struct key_params *params)
 
 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 key_idx = 0;
@@ -977,11 +1166,11 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->get_key) {
+	if (!rdev->ops->get_key) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1001,13 +1190,14 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	cookie.msg = msg;
+	cookie.idx = key_idx;
 
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
 	NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
 	if (mac_addr)
 		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
 
-	err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
+	err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr,
 				&cookie, get_key_callback);
 
 	if (err)
@@ -1017,7 +1207,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 		goto nla_put_failure;
 
 	genlmsg_end(msg, hdr);
-	err = genlmsg_unicast(msg, info->snd_pid);
+	err = genlmsg_reply(msg, info);
 	goto out;
 
  nla_put_failure:
@@ -1025,7 +1215,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
  free_msg:
 	nlmsg_free(msg);
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1035,57 +1225,57 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
+	struct key_parse key;
 	int err;
 	struct net_device *dev;
-	u8 key_idx;
 	int (*func)(struct wiphy *wiphy, struct net_device *netdev,
 		    u8 key_index);
 
-	if (!info->attrs[NL80211_ATTR_KEY_IDX])
-		return -EINVAL;
-
-	key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+	err = nl80211_parse_key(info, &key);
+	if (err)
+		return err;
 
-	if (info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) {
-		if (key_idx < 4 || key_idx > 5)
-			return -EINVAL;
-	} else if (key_idx > 3)
+	if (key.idx < 0)
 		return -EINVAL;
 
-	/* currently only support setting default key */
-	if (!info->attrs[NL80211_ATTR_KEY_DEFAULT] &&
-	    !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
+	/* only support setting default key */
+	if (!key.def && !key.defmgmt)
 		return -EINVAL;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (info->attrs[NL80211_ATTR_KEY_DEFAULT])
-		func = drv->ops->set_default_key;
+	if (key.def)
+		func = rdev->ops->set_default_key;
 	else
-		func = drv->ops->set_default_mgmt_key;
+		func = rdev->ops->set_default_mgmt_key;
 
 	if (!func) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = func(&drv->wiphy, dev, key_idx);
+	wdev_lock(dev->ieee80211_ptr);
+	err = nl80211_key_allowed(dev->ieee80211_ptr);
+	if (!err)
+		err = func(&rdev->wiphy, dev, key.idx);
+
 #ifdef CONFIG_WIRELESS_EXT
 	if (!err) {
-		if (func == drv->ops->set_default_key)
-			dev->ieee80211_ptr->wext.default_key = key_idx;
+		if (func == rdev->ops->set_default_key)
+			dev->ieee80211_ptr->wext.default_key = key.idx;
 		else
-			dev->ieee80211_ptr->wext.default_mgmt_key = key_idx;
+			dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
 	}
 #endif
+	wdev_unlock(dev->ieee80211_ptr);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 
  unlock_rtnl:
@@ -1096,62 +1286,47 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
-	int err, i;
+	struct cfg80211_registered_device *rdev;
+	int err;
 	struct net_device *dev;
-	struct key_params params;
-	u8 key_idx = 0;
+	struct key_parse key;
 	u8 *mac_addr = NULL;
 
-	memset(&params, 0, sizeof(params));
+	err = nl80211_parse_key(info, &key);
+	if (err)
+		return err;
 
-	if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
+	if (!key.p.key)
 		return -EINVAL;
 
-	if (info->attrs[NL80211_ATTR_KEY_DATA]) {
-		params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
-		params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
-	}
-
-	if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
-		params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
-		params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
-	}
-
-	if (info->attrs[NL80211_ATTR_KEY_IDX])
-		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
-
-	params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
-
 	if (info->attrs[NL80211_ATTR_MAC])
 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	if (cfg80211_validate_key_settings(&params, key_idx, mac_addr))
-		return -EINVAL;
-
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
-		if (params.cipher == drv->wiphy.cipher_suites[i])
-			break;
-	if (i == drv->wiphy.n_cipher_suites) {
-		err = -EINVAL;
+	if (!rdev->ops->add_key) {
+		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	if (!drv->ops->add_key) {
-		err = -EOPNOTSUPP;
+	if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) {
+		err = -EINVAL;
 		goto out;
 	}
 
-	err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
+	wdev_lock(dev->ieee80211_ptr);
+	err = nl80211_key_allowed(dev->ieee80211_ptr);
+	if (!err)
+		err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx,
+					 mac_addr, &key.p);
+	wdev_unlock(dev->ieee80211_ptr);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1161,45 +1336,47 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
-	u8 key_idx = 0;
 	u8 *mac_addr = NULL;
+	struct key_parse key;
 
-	if (info->attrs[NL80211_ATTR_KEY_IDX])
-		key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
-
-	if (key_idx > 5)
-		return -EINVAL;
+	err = nl80211_parse_key(info, &key);
+	if (err)
+		return err;
 
 	if (info->attrs[NL80211_ATTR_MAC])
 		mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->del_key) {
+	if (!rdev->ops->del_key) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
+	wdev_lock(dev->ieee80211_ptr);
+	err = nl80211_key_allowed(dev->ieee80211_ptr);
+	if (!err)
+		err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr);
 
 #ifdef CONFIG_WIRELESS_EXT
 	if (!err) {
-		if (key_idx == dev->ieee80211_ptr->wext.default_key)
+		if (key.idx == dev->ieee80211_ptr->wext.default_key)
 			dev->ieee80211_ptr->wext.default_key = -1;
-		else if (key_idx == dev->ieee80211_ptr->wext.default_mgmt_key)
+		else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
 			dev->ieee80211_ptr->wext.default_mgmt_key = -1;
 	}
 #endif
+	wdev_unlock(dev->ieee80211_ptr);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 
  unlock_rtnl:
@@ -1212,7 +1389,7 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
 {
         int (*call)(struct wiphy *wiphy, struct net_device *dev,
 		    struct beacon_parameters *info);
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct beacon_parameters params;
@@ -1223,7 +1400,7 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
@@ -1242,10 +1419,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
 			goto out;
 		}
 
-		call = drv->ops->add_beacon;
+		call = rdev->ops->add_beacon;
 		break;
 	case NL80211_CMD_SET_BEACON:
-		call = drv->ops->set_beacon;
+		call = rdev->ops->set_beacon;
 		break;
 	default:
 		WARN_ON(1);
@@ -1291,10 +1468,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	err = call(&drv->wiphy, dev, &params);
+	err = call(&rdev->wiphy, dev, &params);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1304,17 +1481,17 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->del_beacon) {
+	if (!rdev->ops->del_beacon) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1323,10 +1500,10 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
 		err = -EOPNOTSUPP;
 		goto out;
 	}
-	err = drv->ops->del_beacon(&drv->wiphy, dev);
+	err = rdev->ops->del_beacon(&rdev->wiphy, dev);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  unlock_rtnl:
 	rtnl_unlock();
@@ -1433,6 +1610,8 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
 
+	NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, sinfo->generation);
+
 	sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
 	if (!sinfoattr)
 		goto nla_put_failure;
@@ -1520,13 +1699,13 @@ static int nl80211_dump_station(struct sk_buff *skb,
 
 	rtnl_lock();
 
-	netdev = __dev_get_by_index(&init_net, ifidx);
+	netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
 	if (!netdev) {
 		err = -ENODEV;
 		goto out_rtnl;
 	}
 
-	dev = cfg80211_get_dev_from_ifindex(ifidx);
+	dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
 	if (IS_ERR(dev)) {
 		err = PTR_ERR(dev);
 		goto out_rtnl;
@@ -1560,7 +1739,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
 	cb->args[1] = sta_idx;
 	err = skb->len;
  out_err:
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
  out_rtnl:
 	rtnl_unlock();
 
@@ -1569,7 +1748,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
 
 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct station_info sinfo;
@@ -1585,16 +1764,16 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->get_station) {
+	if (!rdev->ops->get_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &sinfo);
+	err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo);
 	if (err)
 		goto out;
 
@@ -1606,13 +1785,13 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
 				 dev, mac_addr, &sinfo) < 0)
 		goto out_free;
 
-	err = genlmsg_unicast(msg, info->snd_pid);
+	err = genlmsg_reply(msg, info);
 	goto out;
 
  out_free:
 	nlmsg_free(msg);
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1623,14 +1802,16 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
 /*
  * Get vlan interface making sure it is on the right wiphy.
  */
-static int get_vlan(struct nlattr *vlanattr,
+static int get_vlan(struct genl_info *info,
 		    struct cfg80211_registered_device *rdev,
 		    struct net_device **vlan)
 {
+	struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
 	*vlan = NULL;
 
 	if (vlanattr) {
-		*vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
+		*vlan = dev_get_by_index(genl_info_net(info),
+					 nla_get_u32(vlanattr));
 		if (!*vlan)
 			return -ENODEV;
 		if (!(*vlan)->ieee80211_ptr)
@@ -1643,7 +1824,7 @@ static int get_vlan(struct nlattr *vlanattr,
 
 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct station_parameters params;
@@ -1685,11 +1866,11 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
+	err = get_vlan(info, rdev, &params.vlan);
 	if (err)
 		goto out;
 
@@ -1738,17 +1919,17 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 	if (err)
 		goto out;
 
-	if (!drv->ops->change_station) {
+	if (!rdev->ops->change_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
+	err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, &params);
 
  out:
 	if (params.vlan)
 		dev_put(params.vlan);
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1758,7 +1939,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct station_parameters params;
@@ -1798,11 +1979,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
+	err = get_vlan(info, rdev, &params.vlan);
 	if (err)
 		goto out;
 
@@ -1838,7 +2019,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 	if (err)
 		goto out;
 
-	if (!drv->ops->add_station) {
+	if (!rdev->ops->add_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -1848,12 +2029,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
+	err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
 
  out:
 	if (params.vlan)
 		dev_put(params.vlan);
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1863,7 +2044,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *mac_addr = NULL;
@@ -1873,7 +2054,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
@@ -1884,15 +2065,15 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	if (!drv->ops->del_station) {
+	if (!rdev->ops->del_station) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
+	err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -1916,6 +2097,8 @@ static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
 	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
 	NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
 
+	NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, pinfo->generation);
+
 	pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
 	if (!pinfoattr)
 		goto nla_put_failure;
@@ -1979,13 +2162,13 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
 
 	rtnl_lock();
 
-	netdev = __dev_get_by_index(&init_net, ifidx);
+	netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
 	if (!netdev) {
 		err = -ENODEV;
 		goto out_rtnl;
 	}
 
-	dev = cfg80211_get_dev_from_ifindex(ifidx);
+	dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
 	if (IS_ERR(dev)) {
 		err = PTR_ERR(dev);
 		goto out_rtnl;
@@ -1998,7 +2181,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
 
 	if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
 		err = -EOPNOTSUPP;
-		goto out;
+		goto out_err;
 	}
 
 	while (1) {
@@ -2023,7 +2206,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
 	cb->args[1] = path_idx;
 	err = skb->len;
  out_err:
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(dev);
  out_rtnl:
 	rtnl_unlock();
 
@@ -2032,7 +2215,7 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
 
 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct mpath_info pinfo;
@@ -2049,11 +2232,11 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->get_mpath) {
+	if (!rdev->ops->get_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2063,7 +2246,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	err = drv->ops->get_mpath(&drv->wiphy, dev, dst, next_hop, &pinfo);
+	err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo);
 	if (err)
 		goto out;
 
@@ -2075,13 +2258,13 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
 				 dev, dst, next_hop, &pinfo) < 0)
 		goto out_free;
 
-	err = genlmsg_unicast(msg, info->snd_pid);
+	err = genlmsg_reply(msg, info);
 	goto out;
 
  out_free:
 	nlmsg_free(msg);
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2091,7 +2274,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *dst = NULL;
@@ -2108,11 +2291,11 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->change_mpath) {
+	if (!rdev->ops->change_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2127,10 +2310,10 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	err = drv->ops->change_mpath(&drv->wiphy, dev, dst, next_hop);
+	err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2139,7 +2322,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
 }
 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *dst = NULL;
@@ -2156,11 +2339,11 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->add_mpath) {
+	if (!rdev->ops->add_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2175,10 +2358,10 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	err = drv->ops->add_mpath(&drv->wiphy, dev, dst, next_hop);
+	err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2188,7 +2371,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	u8 *dst = NULL;
@@ -2198,19 +2381,19 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->del_mpath) {
+	if (!rdev->ops->del_mpath) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-	err = drv->ops->del_mpath(&drv->wiphy, dev, dst);
+	err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2220,7 +2403,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	int err;
 	struct net_device *dev;
 	struct bss_parameters params;
@@ -2249,11 +2432,11 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->change_bss) {
+	if (!rdev->ops->change_bss) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2263,10 +2446,10 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	err = drv->ops->change_bss(&drv->wiphy, dev, &params);
+	err = rdev->ops->change_bss(&rdev->wiphy, dev, &params);
 
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2357,7 +2540,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
 static int nl80211_get_mesh_params(struct sk_buff *skb,
 	struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct mesh_config cur_params;
 	int err;
 	struct net_device *dev;
@@ -2368,17 +2551,17 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	rtnl_lock();
 
 	/* Look up our device */
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->get_mesh_params) {
+	if (!rdev->ops->get_mesh_params) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
 
 	/* Get the mesh params */
-	err = drv->ops->get_mesh_params(&drv->wiphy, dev, &cur_params);
+	err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params);
 	if (err)
 		goto out;
 
@@ -2424,7 +2607,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 			cur_params.dot11MeshHWMPnetDiameterTraversalTime);
 	nla_nest_end(msg, pinfoattr);
 	genlmsg_end(msg, hdr);
-	err = genlmsg_unicast(msg, info->snd_pid);
+	err = genlmsg_reply(msg, info);
 	goto out;
 
  nla_put_failure:
@@ -2432,7 +2615,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
 	err = -EMSGSIZE;
  out:
 	/* Cleanup */
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2470,7 +2653,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
 {
 	int err;
 	u32 mask;
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct mesh_config cfg;
 	struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
@@ -2485,11 +2668,11 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	if (!drv->ops->set_mesh_params) {
+	if (!rdev->ops->set_mesh_params) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2534,11 +2717,11 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
 			nla_get_u16);
 
 	/* Apply changes */
-	err = drv->ops->set_mesh_params(&drv->wiphy, dev, &cfg, mask);
+	err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
 
  out:
 	/* cleanup */
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2612,7 +2795,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
 	nla_nest_end(msg, nl_reg_rules);
 
 	genlmsg_end(msg, hdr);
-	err = genlmsg_unicast(msg, info->snd_pid);
+	err = genlmsg_reply(msg, info);
 	goto out;
 
 nla_put_failure:
@@ -2698,16 +2881,41 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
 	return r;
 }
 
+static int validate_scan_freqs(struct nlattr *freqs)
+{
+	struct nlattr *attr1, *attr2;
+	int n_channels = 0, tmp1, tmp2;
+
+	nla_for_each_nested(attr1, freqs, tmp1) {
+		n_channels++;
+		/*
+		 * Some hardware has a limited channel list for
+		 * scanning, and it is pretty much nonsensical
+		 * to scan for a channel twice, so disallow that
+		 * and don't require drivers to check that the
+		 * channel list they get isn't longer than what
+		 * they can scan, as long as they can scan all
+		 * the channels they registered at once.
+		 */
+		nla_for_each_nested(attr2, freqs, tmp2)
+			if (attr1 != attr2 &&
+			    nla_get_u32(attr1) == nla_get_u32(attr2))
+				return 0;
+	}
+
+	return n_channels;
+}
+
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct cfg80211_scan_request *request;
 	struct cfg80211_ssid *ssid;
 	struct ieee80211_channel *channel;
 	struct nlattr *attr;
 	struct wiphy *wiphy;
-	int err, tmp, n_ssids = 0, n_channels = 0, i;
+	int err, tmp, n_ssids = 0, n_channels, i;
 	enum ieee80211_band band;
 	size_t ie_len;
 
@@ -2716,13 +2924,13 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto out_rtnl;
 
-	wiphy = &drv->wiphy;
+	wiphy = &rdev->wiphy;
 
-	if (!drv->ops->scan) {
+	if (!rdev->ops->scan) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -2732,19 +2940,21 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	if (drv->scan_req) {
+	if (rdev->scan_req) {
 		err = -EBUSY;
 		goto out;
 	}
 
 	if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
-		nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp)
-			n_channels++;
+		n_channels = validate_scan_freqs(
+				info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
 		if (!n_channels) {
 			err = -EINVAL;
 			goto out;
 		}
 	} else {
+		n_channels = 0;
+
 		for (band = 0; band < IEEE80211_NUM_BANDS; band++)
 			if (wiphy->bands[band])
 				n_channels += wiphy->bands[band]->n_channels;
@@ -2778,10 +2988,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	request->channels = (void *)((char *)request + sizeof(*request));
 	request->n_channels = n_channels;
 	if (n_ssids)
-		request->ssids = (void *)(request->channels + n_channels);
+		request->ssids = (void *)&request->channels[n_channels];
 	request->n_ssids = n_ssids;
 	if (ie_len) {
 		if (request->ssids)
@@ -2836,19 +3045,24 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 		       request->ie_len);
 	}
 
-	request->ifidx = dev->ifindex;
-	request->wiphy = &drv->wiphy;
+	request->dev = dev;
+	request->wiphy = &rdev->wiphy;
+
+	rdev->scan_req = request;
+	err = rdev->ops->scan(&rdev->wiphy, dev, request);
 
-	drv->scan_req = request;
-	err = drv->ops->scan(&drv->wiphy, dev, request);
+	if (!err) {
+		nl80211_send_scan_start(rdev, dev);
+		dev_hold(dev);
+	}
 
  out_free:
 	if (err) {
-		drv->scan_req = NULL;
+		rdev->scan_req = NULL;
 		kfree(request);
 	}
  out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
  out_rtnl:
 	rtnl_unlock();
@@ -2858,20 +3072,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
 static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 			    struct cfg80211_registered_device *rdev,
-			    struct net_device *dev,
-			    struct cfg80211_bss *res)
+			    struct wireless_dev *wdev,
+			    struct cfg80211_internal_bss *intbss)
 {
+	struct cfg80211_bss *res = &intbss->pub;
 	void *hdr;
 	struct nlattr *bss;
+	int i;
+
+	ASSERT_WDEV_LOCK(wdev);
 
 	hdr = nl80211hdr_put(msg, pid, seq, flags,
 			     NL80211_CMD_NEW_SCAN_RESULTS);
 	if (!hdr)
 		return -1;
 
-	NLA_PUT_U32(msg, NL80211_ATTR_SCAN_GENERATION,
-		    rdev->bss_generation);
-	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+	NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation);
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex);
 
 	bss = nla_nest_start(msg, NL80211_ATTR_BSS);
 	if (!bss)
@@ -2900,6 +3117,28 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 		break;
 	}
 
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_STATION:
+		if (intbss == wdev->current_bss)
+			NLA_PUT_U32(msg, NL80211_BSS_STATUS,
+				    NL80211_BSS_STATUS_ASSOCIATED);
+		else for (i = 0; i < MAX_AUTH_BSSES; i++) {
+			if (intbss != wdev->auth_bsses[i])
+				continue;
+			NLA_PUT_U32(msg, NL80211_BSS_STATUS,
+				    NL80211_BSS_STATUS_AUTHENTICATED);
+			break;
+		}
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		if (intbss == wdev->current_bss)
+			NLA_PUT_U32(msg, NL80211_BSS_STATUS,
+				    NL80211_BSS_STATUS_IBSS_JOINED);
+		break;
+	default:
+		break;
+	}
+
 	nla_nest_end(msg, bss);
 
 	return genlmsg_end(msg, hdr);
@@ -2912,9 +3151,10 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 static int nl80211_dump_scan(struct sk_buff *skb,
 			     struct netlink_callback *cb)
 {
-	struct cfg80211_registered_device *dev;
-	struct net_device *netdev;
+	struct cfg80211_registered_device *rdev;
+	struct net_device *dev;
 	struct cfg80211_internal_bss *scan;
+	struct wireless_dev *wdev;
 	int ifidx = cb->args[0];
 	int start = cb->args[1], idx = 0;
 	int err;
@@ -2935,58 +3175,83 @@ static int nl80211_dump_scan(struct sk_buff *skb,
 		cb->args[0] = ifidx;
 	}
 
-	netdev = dev_get_by_index(&init_net, ifidx);
-	if (!netdev)
+	dev = dev_get_by_index(sock_net(skb->sk), ifidx);
+	if (!dev)
 		return -ENODEV;
 
-	dev = cfg80211_get_dev_from_ifindex(ifidx);
-	if (IS_ERR(dev)) {
-		err = PTR_ERR(dev);
+	rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
+	if (IS_ERR(rdev)) {
+		err = PTR_ERR(rdev);
 		goto out_put_netdev;
 	}
 
-	spin_lock_bh(&dev->bss_lock);
-	cfg80211_bss_expire(dev);
+	wdev = dev->ieee80211_ptr;
+
+	wdev_lock(wdev);
+	spin_lock_bh(&rdev->bss_lock);
+	cfg80211_bss_expire(rdev);
 
-	list_for_each_entry(scan, &dev->bss_list, list) {
+	list_for_each_entry(scan, &rdev->bss_list, list) {
 		if (++idx <= start)
 			continue;
 		if (nl80211_send_bss(skb,
 				NETLINK_CB(cb->skb).pid,
 				cb->nlh->nlmsg_seq, NLM_F_MULTI,
-				dev, netdev, &scan->pub) < 0) {
+				rdev, wdev, scan) < 0) {
 			idx--;
 			goto out;
 		}
 	}
 
  out:
-	spin_unlock_bh(&dev->bss_lock);
+	spin_unlock_bh(&rdev->bss_lock);
+	wdev_unlock(wdev);
 
 	cb->args[1] = idx;
 	err = skb->len;
-	cfg80211_put_dev(dev);
+	cfg80211_unlock_rdev(rdev);
  out_put_netdev:
-	dev_put(netdev);
+	dev_put(dev);
 
 	return err;
 }
 
 static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type)
 {
-	return auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM ||
-		auth_type == NL80211_AUTHTYPE_SHARED_KEY ||
-		auth_type == NL80211_AUTHTYPE_FT ||
-		auth_type == NL80211_AUTHTYPE_NETWORK_EAP;
+	return auth_type <= NL80211_AUTHTYPE_MAX;
 }
 
+static bool nl80211_valid_wpa_versions(u32 wpa_versions)
+{
+	return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
+				  NL80211_WPA_VERSION_2));
+}
+
+static bool nl80211_valid_akm_suite(u32 akm)
+{
+	return akm == WLAN_AKM_SUITE_8021X ||
+		akm == WLAN_AKM_SUITE_PSK;
+}
+
+static bool nl80211_valid_cipher_suite(u32 cipher)
+{
+	return cipher == WLAN_CIPHER_SUITE_WEP40 ||
+		cipher == WLAN_CIPHER_SUITE_WEP104 ||
+		cipher == WLAN_CIPHER_SUITE_TKIP ||
+		cipher == WLAN_CIPHER_SUITE_CCMP ||
+		cipher == WLAN_CIPHER_SUITE_AES_CMAC;
+}
+
+
 static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
-	struct cfg80211_auth_request req;
-	struct wiphy *wiphy;
-	int err;
+	struct ieee80211_channel *chan;
+	const u8 *bssid, *ssid, *ie = NULL;
+	int err, ssid_len, ie_len = 0;
+	enum nl80211_auth_type auth_type;
+	struct key_parse key;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
@@ -2997,13 +3262,38 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 	if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
 		return -EINVAL;
 
+	if (!info->attrs[NL80211_ATTR_SSID])
+		return -EINVAL;
+
+	if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
+		return -EINVAL;
+
+	err = nl80211_parse_key(info, &key);
+	if (err)
+		return err;
+
+	if (key.idx >= 0) {
+		if (!key.p.key || !key.p.key_len)
+			return -EINVAL;
+		if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
+		     key.p.key_len != WLAN_KEY_LEN_WEP40) &&
+		    (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
+		     key.p.key_len != WLAN_KEY_LEN_WEP104))
+			return -EINVAL;
+		if (key.idx > 4)
+			return -EINVAL;
+	} else {
+		key.p.key_len = 0;
+		key.p.key = NULL;
+	}
+
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->auth) {
+	if (!rdev->ops->auth) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3018,69 +3308,130 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
-
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
-
-	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-		req.chan = ieee80211_get_channel(
-			wiphy,
-			nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
-		if (!req.chan) {
-			err = -EINVAL;
-			goto out;
-		}
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	chan = ieee80211_get_channel(&rdev->wiphy,
+		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+	if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
+		err = -EINVAL;
+		goto out;
 	}
 
-	if (info->attrs[NL80211_ATTR_SSID]) {
-		req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
-		req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
-	}
+	ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+	ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
-	if (!nl80211_valid_auth_type(req.auth_type)) {
+	auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+	if (!nl80211_valid_auth_type(auth_type)) {
 		err = -EINVAL;
 		goto out;
 	}
 
-	err = drv->ops->auth(&drv->wiphy, dev, &req);
+	err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
+				 ssid, ssid_len, ie, ie_len,
+				 key.p.key, key.p.key_len, key.idx);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
 	return err;
 }
 
+static int nl80211_crypto_settings(struct genl_info *info,
+				   struct cfg80211_crypto_settings *settings,
+				   int cipher_limit)
+{
+	memset(settings, 0, sizeof(*settings));
+
+	settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
+
+	if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
+		void *data;
+		int len, i;
+
+		data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
+		len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
+		settings->n_ciphers_pairwise = len / sizeof(u32);
+
+		if (len % sizeof(u32))
+			return -EINVAL;
+
+		if (settings->n_ciphers_pairwise > cipher_limit)
+			return -EINVAL;
+
+		memcpy(settings->ciphers_pairwise, data, len);
+
+		for (i = 0; i < settings->n_ciphers_pairwise; i++)
+			if (!nl80211_valid_cipher_suite(
+					settings->ciphers_pairwise[i]))
+				return -EINVAL;
+	}
+
+	if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
+		settings->cipher_group =
+			nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
+		if (!nl80211_valid_cipher_suite(settings->cipher_group))
+			return -EINVAL;
+	}
+
+	if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
+		settings->wpa_versions =
+			nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
+		if (!nl80211_valid_wpa_versions(settings->wpa_versions))
+			return -EINVAL;
+	}
+
+	if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
+		void *data;
+		int len, i;
+
+		data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
+		len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
+		settings->n_akm_suites = len / sizeof(u32);
+
+		if (len % sizeof(u32))
+			return -EINVAL;
+
+		memcpy(settings->akm_suites, data, len);
+
+		for (i = 0; i < settings->n_ciphers_pairwise; i++)
+			if (!nl80211_valid_akm_suite(settings->akm_suites[i]))
+				return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
-	struct cfg80211_assoc_request req;
-	struct wiphy *wiphy;
-	int err;
+	struct cfg80211_crypto_settings crypto;
+	struct ieee80211_channel *chan, *fixedchan;
+	const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
+	int err, ssid_len, ie_len = 0;
+	bool use_mfp = false;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
 
 	if (!info->attrs[NL80211_ATTR_MAC] ||
-	    !info->attrs[NL80211_ATTR_SSID])
+	    !info->attrs[NL80211_ATTR_SSID] ||
+	    !info->attrs[NL80211_ATTR_WIPHY_FREQ])
 		return -EINVAL;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->assoc) {
+	if (!rdev->ops->assoc) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3095,46 +3446,54 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	chan = ieee80211_get_channel(&rdev->wiphy,
+		nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+	if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
+		err = -EINVAL;
+		goto out;
+	}
 
-	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
-		req.chan = ieee80211_get_channel(
-			wiphy,
-			nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
-		if (!req.chan) {
-			err = -EINVAL;
-			goto out;
-		}
+	mutex_lock(&rdev->devlist_mtx);
+	fixedchan = rdev_fixed_channel(rdev, NULL);
+	if (fixedchan && chan != fixedchan) {
+		err = -EBUSY;
+		mutex_unlock(&rdev->devlist_mtx);
+		goto out;
 	}
+	mutex_unlock(&rdev->devlist_mtx);
 
-	req.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
-	req.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+	ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+	ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
 	if (info->attrs[NL80211_ATTR_USE_MFP]) {
-		enum nl80211_mfp use_mfp =
+		enum nl80211_mfp mfp =
 			nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
-		if (use_mfp == NL80211_MFP_REQUIRED)
-			req.use_mfp = true;
-		else if (use_mfp != NL80211_MFP_NO) {
+		if (mfp == NL80211_MFP_REQUIRED)
+			use_mfp = true;
+		else if (mfp != NL80211_MFP_NO) {
 			err = -EINVAL;
 			goto out;
 		}
 	}
 
-	req.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
+	if (info->attrs[NL80211_ATTR_PREV_BSSID])
+		prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
 
-	err = drv->ops->assoc(&drv->wiphy, dev, &req);
+	err = nl80211_crypto_settings(info, &crypto, 1);
+	if (!err)
+		err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
+					  ssid, ssid_len, ie, ie_len, use_mfp,
+					  &crypto);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3143,11 +3502,11 @@ unlock_rtnl:
 
 static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
-	struct cfg80211_deauth_request req;
-	struct wiphy *wiphy;
-	int err;
+	const u8 *ie = NULL, *bssid;
+	int err, ie_len = 0;
+	u16 reason_code;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
@@ -3160,11 +3519,11 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->deauth) {
+	if (!rdev->ops->deauth) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3179,27 +3538,24 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
-
-	req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
-	if (req.reason_code == 0) {
+	reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+	if (reason_code == 0) {
 		/* Reason Code 0 is reserved */
 		err = -EINVAL;
 		goto out;
 	}
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	err = drv->ops->deauth(&drv->wiphy, dev, &req);
+	err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3208,11 +3564,11 @@ unlock_rtnl:
 
 static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
-	struct cfg80211_disassoc_request req;
-	struct wiphy *wiphy;
-	int err;
+	const u8 *ie = NULL, *bssid;
+	int err, ie_len = 0;
+	u16 reason_code;
 
 	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
 		return -EINVAL;
@@ -3225,11 +3581,11 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->disassoc) {
+	if (!rdev->ops->disassoc) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3244,27 +3600,24 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
-	memset(&req, 0, sizeof(req));
+	bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-	req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
-
-	req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
-	if (req.reason_code == 0) {
+	reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+	if (reason_code == 0) {
 		/* Reason Code 0 is reserved */
 		err = -EINVAL;
 		goto out;
 	}
 
 	if (info->attrs[NL80211_ATTR_IE]) {
-		req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
-		req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+		ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
 	}
 
-	err = drv->ops->disassoc(&drv->wiphy, dev, &req);
+	err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
 	rtnl_unlock();
@@ -3273,10 +3626,11 @@ unlock_rtnl:
 
 static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	struct cfg80211_ibss_params ibss;
 	struct wiphy *wiphy;
+	struct cfg80211_cached_keys *connkeys = NULL;
 	int err;
 
 	memset(&ibss, 0, sizeof(ibss));
@@ -3300,11 +3654,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->join_ibss) {
+	if (!rdev->ops->join_ibss) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3319,7 +3673,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	wiphy = &drv->wiphy;
+	wiphy = &rdev->wiphy;
 
 	if (info->attrs[NL80211_ATTR_MAC])
 		ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
@@ -3341,30 +3695,43 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
+	ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
+
+	if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
+		connkeys = nl80211_parse_connkeys(rdev,
+					info->attrs[NL80211_ATTR_KEYS]);
+		if (IS_ERR(connkeys)) {
+			err = PTR_ERR(connkeys);
+			connkeys = NULL;
+			goto out;
+		}
+	}
 
-	err = cfg80211_join_ibss(drv, dev, &ibss);
+	err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
+	if (err)
+		kfree(connkeys);
 	rtnl_unlock();
 	return err;
 }
 
 static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct net_device *dev;
 	int err;
 
 	rtnl_lock();
 
-	err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
 	if (err)
 		goto unlock_rtnl;
 
-	if (!drv->ops->leave_ibss) {
+	if (!rdev->ops->leave_ibss) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -3379,12 +3746,309 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	err = cfg80211_leave_ibss(drv, dev, false);
+	err = cfg80211_leave_ibss(rdev, dev, false);
+
+out:
+	cfg80211_unlock_rdev(rdev);
+	dev_put(dev);
+unlock_rtnl:
+	rtnl_unlock();
+	return err;
+}
+
+#ifdef CONFIG_NL80211_TESTMODE
+static struct genl_multicast_group nl80211_testmode_mcgrp = {
+	.name = "testmode",
+};
+
+static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev;
+	int err;
+
+	if (!info->attrs[NL80211_ATTR_TESTDATA])
+		return -EINVAL;
+
+	rtnl_lock();
+
+	rdev = cfg80211_get_dev_from_info(info);
+	if (IS_ERR(rdev)) {
+		err = PTR_ERR(rdev);
+		goto unlock_rtnl;
+	}
+
+	err = -EOPNOTSUPP;
+	if (rdev->ops->testmode_cmd) {
+		rdev->testmode_info = info;
+		err = rdev->ops->testmode_cmd(&rdev->wiphy,
+				nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
+				nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
+		rdev->testmode_info = NULL;
+	}
+
+	cfg80211_unlock_rdev(rdev);
+
+ unlock_rtnl:
+	rtnl_unlock();
+	return err;
+}
+
+static struct sk_buff *
+__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
+			      int approxlen, u32 pid, u32 seq, gfp_t gfp)
+{
+	struct sk_buff *skb;
+	void *hdr;
+	struct nlattr *data;
+
+	skb = nlmsg_new(approxlen + 100, gfp);
+	if (!skb)
+		return NULL;
+
+	hdr = nl80211hdr_put(skb, pid, seq, 0, NL80211_CMD_TESTMODE);
+	if (!hdr) {
+		kfree_skb(skb);
+		return NULL;
+	}
+
+	NLA_PUT_U32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	data = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
+
+	((void **)skb->cb)[0] = rdev;
+	((void **)skb->cb)[1] = hdr;
+	((void **)skb->cb)[2] = data;
+
+	return skb;
+
+ nla_put_failure:
+	kfree_skb(skb);
+	return NULL;
+}
+
+struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
+						  int approxlen)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+	if (WARN_ON(!rdev->testmode_info))
+		return NULL;
+
+	return __cfg80211_testmode_alloc_skb(rdev, approxlen,
+				rdev->testmode_info->snd_pid,
+				rdev->testmode_info->snd_seq,
+				GFP_KERNEL);
+}
+EXPORT_SYMBOL(cfg80211_testmode_alloc_reply_skb);
+
+int cfg80211_testmode_reply(struct sk_buff *skb)
+{
+	struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
+	void *hdr = ((void **)skb->cb)[1];
+	struct nlattr *data = ((void **)skb->cb)[2];
+
+	if (WARN_ON(!rdev->testmode_info)) {
+		kfree_skb(skb);
+		return -EINVAL;
+	}
+
+	nla_nest_end(skb, data);
+	genlmsg_end(skb, hdr);
+	return genlmsg_reply(skb, rdev->testmode_info);
+}
+EXPORT_SYMBOL(cfg80211_testmode_reply);
+
+struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
+						  int approxlen, gfp_t gfp)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+	return __cfg80211_testmode_alloc_skb(rdev, approxlen, 0, 0, gfp);
+}
+EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb);
+
+void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
+{
+	void *hdr = ((void **)skb->cb)[1];
+	struct nlattr *data = ((void **)skb->cb)[2];
+
+	nla_nest_end(skb, data);
+	genlmsg_end(skb, hdr);
+	genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp);
+}
+EXPORT_SYMBOL(cfg80211_testmode_event);
+#endif
+
+static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev;
+	struct net_device *dev;
+	struct cfg80211_connect_params connect;
+	struct wiphy *wiphy;
+	struct cfg80211_cached_keys *connkeys = NULL;
+	int err;
+
+	memset(&connect, 0, sizeof(connect));
+
+	if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+		return -EINVAL;
+
+	if (!info->attrs[NL80211_ATTR_SSID] ||
+	    !nla_len(info->attrs[NL80211_ATTR_SSID]))
+		return -EINVAL;
+
+	if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
+		connect.auth_type =
+			nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+		if (!nl80211_valid_auth_type(connect.auth_type))
+			return -EINVAL;
+	} else
+		connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+
+	connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
+
+	err = nl80211_crypto_settings(info, &connect.crypto,
+				      NL80211_MAX_NR_CIPHER_SUITES);
+	if (err)
+		return err;
+	rtnl_lock();
+
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+	if (err)
+		goto unlock_rtnl;
+
+	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
+
+	wiphy = &rdev->wiphy;
+
+	if (info->attrs[NL80211_ATTR_MAC])
+		connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+	connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+	connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+
+	if (info->attrs[NL80211_ATTR_IE]) {
+		connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+		connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+	}
+
+	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
+		connect.channel =
+			ieee80211_get_channel(wiphy,
+			    nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+		if (!connect.channel ||
+		    connect.channel->flags & IEEE80211_CHAN_DISABLED) {
+			err = -EINVAL;
+			goto out;
+		}
+	}
+
+	if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
+		connkeys = nl80211_parse_connkeys(rdev,
+					info->attrs[NL80211_ATTR_KEYS]);
+		if (IS_ERR(connkeys)) {
+			err = PTR_ERR(connkeys);
+			connkeys = NULL;
+			goto out;
+		}
+	}
+
+	err = cfg80211_connect(rdev, dev, &connect, connkeys);
 
 out:
-	cfg80211_put_dev(drv);
+	cfg80211_unlock_rdev(rdev);
 	dev_put(dev);
 unlock_rtnl:
+	if (err)
+		kfree(connkeys);
+	rtnl_unlock();
+	return err;
+}
+
+static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev;
+	struct net_device *dev;
+	int err;
+	u16 reason;
+
+	if (!info->attrs[NL80211_ATTR_REASON_CODE])
+		reason = WLAN_REASON_DEAUTH_LEAVING;
+	else
+		reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+
+	if (reason == 0)
+		return -EINVAL;
+
+	rtnl_lock();
+
+	err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+	if (err)
+		goto unlock_rtnl;
+
+	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
+		err = -EOPNOTSUPP;
+		goto out;
+	}
+
+	if (!netif_running(dev)) {
+		err = -ENETDOWN;
+		goto out;
+	}
+
+	err = cfg80211_disconnect(rdev, dev, reason, true);
+
+out:
+	cfg80211_unlock_rdev(rdev);
+	dev_put(dev);
+unlock_rtnl:
+	rtnl_unlock();
+	return err;
+}
+
+static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev;
+	struct net *net;
+	int err;
+	u32 pid;
+
+	if (!info->attrs[NL80211_ATTR_PID])
+		return -EINVAL;
+
+	pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
+
+	rtnl_lock();
+
+	rdev = cfg80211_get_dev_from_info(info);
+	if (IS_ERR(rdev)) {
+		err = PTR_ERR(rdev);
+		goto out;
+	}
+
+	net = get_net_ns_by_pid(pid);
+	if (IS_ERR(net)) {
+		err = PTR_ERR(net);
+		goto out;
+	}
+
+	err = 0;
+
+	/* check if anything to do */
+	if (net_eq(wiphy_net(&rdev->wiphy), net))
+		goto out_put_net;
+
+	err = cfg80211_switch_netns(rdev, net);
+ out_put_net:
+	put_net(net);
+ out:
+	cfg80211_unlock_rdev(rdev);
 	rtnl_unlock();
 	return err;
 }
@@ -3602,6 +4266,32 @@ static struct genl_ops nl80211_ops[] = {
 		.policy = nl80211_policy,
 		.flags = GENL_ADMIN_PERM,
 	},
+#ifdef CONFIG_NL80211_TESTMODE
+	{
+		.cmd = NL80211_CMD_TESTMODE,
+		.doit = nl80211_testmode_do,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+#endif
+	{
+		.cmd = NL80211_CMD_CONNECT,
+		.doit = nl80211_connect,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = NL80211_CMD_DISCONNECT,
+		.doit = nl80211_disconnect,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = NL80211_CMD_SET_WIPHY_NETNS,
+		.doit = nl80211_wiphy_netns,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+	},
 };
 static struct genl_multicast_group nl80211_mlme_mcgrp = {
 	.name = "mlme",
@@ -3633,7 +4323,8 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_config_mcgrp.id, GFP_KERNEL);
 }
 
 static int nl80211_add_scan_req(struct sk_buff *msg,
@@ -3643,6 +4334,8 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
 	struct nlattr *nest;
 	int i;
 
+	ASSERT_RDEV_LOCK(rdev);
+
 	if (WARN_ON(!req))
 		return 0;
 
@@ -3668,11 +4361,11 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
 	return -ENOBUFS;
 }
 
-static int nl80211_send_scan_donemsg(struct sk_buff *msg,
-				     struct cfg80211_registered_device *rdev,
-				     struct net_device *netdev,
-				     u32 pid, u32 seq, int flags,
-				     u32 cmd)
+static int nl80211_send_scan_msg(struct sk_buff *msg,
+				 struct cfg80211_registered_device *rdev,
+				 struct net_device *netdev,
+				 u32 pid, u32 seq, int flags,
+				 u32 cmd)
 {
 	void *hdr;
 
@@ -3693,6 +4386,25 @@ static int nl80211_send_scan_donemsg(struct sk_buff *msg,
 	return -EMSGSIZE;
 }
 
+void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
+			     struct net_device *netdev)
+{
+	struct sk_buff *msg;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
+				  NL80211_CMD_TRIGGER_SCAN) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+
 void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
 			    struct net_device *netdev)
 {
@@ -3702,13 +4414,14 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
 	if (!msg)
 		return;
 
-	if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
-				      NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
+	if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
+				  NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
 		nlmsg_free(msg);
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_scan_mcgrp.id, GFP_KERNEL);
 }
 
 void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
@@ -3720,13 +4433,14 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
 	if (!msg)
 		return;
 
-	if (nl80211_send_scan_donemsg(msg, rdev, netdev, 0, 0, 0,
-				      NL80211_CMD_SCAN_ABORTED) < 0) {
+	if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
+				  NL80211_CMD_SCAN_ABORTED) < 0) {
 		nlmsg_free(msg);
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL);
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_scan_mcgrp.id, GFP_KERNEL);
 }
 
 /*
@@ -3775,7 +4489,10 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL);
+	rcu_read_lock();
+	genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
+				GFP_ATOMIC);
+	rcu_read_unlock();
 
 	return;
 
@@ -3787,12 +4504,12 @@ nla_put_failure:
 static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
 				    struct net_device *netdev,
 				    const u8 *buf, size_t len,
-				    enum nl80211_commands cmd)
+				    enum nl80211_commands cmd, gfp_t gfp)
 {
 	struct sk_buff *msg;
 	void *hdr;
 
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
 	if (!msg)
 		return;
 
@@ -3811,7 +4528,8 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, gfp);
 	return;
 
  nla_put_failure:
@@ -3820,42 +4538,45 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
 }
 
 void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
-			  struct net_device *netdev, const u8 *buf, size_t len)
+			  struct net_device *netdev, const u8 *buf,
+			  size_t len, gfp_t gfp)
 {
 	nl80211_send_mlme_event(rdev, netdev, buf, len,
-				NL80211_CMD_AUTHENTICATE);
+				NL80211_CMD_AUTHENTICATE, gfp);
 }
 
 void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
 			   struct net_device *netdev, const u8 *buf,
-			   size_t len)
+			   size_t len, gfp_t gfp)
 {
-	nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
+	nl80211_send_mlme_event(rdev, netdev, buf, len,
+				NL80211_CMD_ASSOCIATE, gfp);
 }
 
 void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
-			 struct net_device *netdev, const u8 *buf, size_t len)
+			 struct net_device *netdev, const u8 *buf,
+			 size_t len, gfp_t gfp)
 {
 	nl80211_send_mlme_event(rdev, netdev, buf, len,
-				NL80211_CMD_DEAUTHENTICATE);
+				NL80211_CMD_DEAUTHENTICATE, gfp);
 }
 
 void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
 			   struct net_device *netdev, const u8 *buf,
-			   size_t len)
+			   size_t len, gfp_t gfp)
 {
 	nl80211_send_mlme_event(rdev, netdev, buf, len,
-				NL80211_CMD_DISASSOCIATE);
+				NL80211_CMD_DISASSOCIATE, gfp);
 }
 
 static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
 				      struct net_device *netdev, int cmd,
-				      const u8 *addr)
+				      const u8 *addr, gfp_t gfp)
 {
 	struct sk_buff *msg;
 	void *hdr;
 
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
 	if (!msg)
 		return;
 
@@ -3875,7 +4596,8 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, gfp);
 	return;
 
  nla_put_failure:
@@ -3884,16 +4606,145 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
 }
 
 void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
-			       struct net_device *netdev, const u8 *addr)
+			       struct net_device *netdev, const u8 *addr,
+			       gfp_t gfp)
 {
 	nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
-				  addr);
+				  addr, gfp);
 }
 
 void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
-				struct net_device *netdev, const u8 *addr)
+				struct net_device *netdev, const u8 *addr,
+				gfp_t gfp)
 {
-	nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr);
+	nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
+				  addr, gfp);
+}
+
+void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
+				 struct net_device *netdev, const u8 *bssid,
+				 const u8 *req_ie, size_t req_ie_len,
+				 const u8 *resp_ie, size_t resp_ie_len,
+				 u16 status, gfp_t gfp)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	if (bssid)
+		NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+	NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status);
+	if (req_ie)
+		NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie);
+	if (resp_ie)
+		NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
+
+	if (genlmsg_end(msg, hdr) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, gfp);
+	return;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+
+}
+
+void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
+			 struct net_device *netdev, const u8 *bssid,
+			 const u8 *req_ie, size_t req_ie_len,
+			 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+	if (req_ie)
+		NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie);
+	if (resp_ie)
+		NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
+
+	if (genlmsg_end(msg, hdr) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, gfp);
+	return;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+
+}
+
+void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
+			       struct net_device *netdev, u16 reason,
+			       const u8 *ie, size_t ie_len, bool from_ap)
+{
+	struct sk_buff *msg;
+	void *hdr;
+
+	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
+	if (!hdr) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+	if (from_ap && reason)
+		NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason);
+	if (from_ap)
+		NLA_PUT_FLAG(msg, NL80211_ATTR_DISCONNECTED_BY_AP);
+	if (ie)
+		NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie);
+
+	if (genlmsg_end(msg, hdr) < 0) {
+		nlmsg_free(msg);
+		return;
+	}
+
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, GFP_KERNEL);
+	return;
+
+ nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+
 }
 
 void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
@@ -3922,7 +4773,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, gfp);
 	return;
 
  nla_put_failure:
@@ -3933,12 +4785,12 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
 void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
 				 struct net_device *netdev, const u8 *addr,
 				 enum nl80211_key_type key_type, int key_id,
-				 const u8 *tsc)
+				 const u8 *tsc, gfp_t gfp)
 {
 	struct sk_buff *msg;
 	void *hdr;
 
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
 	if (!msg)
 		return;
 
@@ -3962,7 +4814,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
+	genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+				nl80211_mlme_mcgrp.id, gfp);
 	return;
 
  nla_put_failure:
@@ -4015,7 +4868,10 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
 		return;
 	}
 
-	genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
+	rcu_read_lock();
+	genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
+				GFP_ATOMIC);
+	rcu_read_unlock();
 
 	return;
 
@@ -4051,6 +4907,12 @@ int nl80211_init(void)
 	if (err)
 		goto err_out;
 
+#ifdef CONFIG_NL80211_TESTMODE
+	err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp);
+	if (err)
+		goto err_out;
+#endif
+
 	return 0;
  err_out:
 	genl_unregister_family(&nl80211_fam);
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 5c12ad1..44cc2a7 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -3,39 +3,54 @@
 
 #include "core.h"
 
-extern int nl80211_init(void);
-extern void nl80211_exit(void);
-extern void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
-extern void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
-				   struct net_device *netdev);
-extern void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
-				      struct net_device *netdev);
-extern void nl80211_send_reg_change_event(struct regulatory_request *request);
-extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
-				 struct net_device *netdev,
-				 const u8 *buf, size_t len);
-extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
-				  struct net_device *netdev,
-				  const u8 *buf, size_t len);
-extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
+int nl80211_init(void);
+void nl80211_exit(void);
+void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
+void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
+			     struct net_device *netdev);
+void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
+			    struct net_device *netdev);
+void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
+			       struct net_device *netdev);
+void nl80211_send_reg_change_event(struct regulatory_request *request);
+void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
+			  struct net_device *netdev,
+			  const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
+			   struct net_device *netdev,
+			   const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
+			 struct net_device *netdev,
+			 const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
+			   struct net_device *netdev,
+			   const u8 *buf, size_t len, gfp_t gfp);
+void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
+			       struct net_device *netdev,
+			       const u8 *addr, gfp_t gfp);
+void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
 				struct net_device *netdev,
-				const u8 *buf, size_t len);
-extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
-				  struct net_device *netdev,
-				  const u8 *buf, size_t len);
-extern void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
-				      struct net_device *netdev,
-				      const u8 *addr);
-extern void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
-				       struct net_device *netdev,
-				       const u8 *addr);
-extern void
+				const u8 *addr, gfp_t gfp);
+void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
+				 struct net_device *netdev, const u8 *bssid,
+				 const u8 *req_ie, size_t req_ie_len,
+				 const u8 *resp_ie, size_t resp_ie_len,
+				 u16 status, gfp_t gfp);
+void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
+			 struct net_device *netdev, const u8 *bssid,
+			 const u8 *req_ie, size_t req_ie_len,
+			 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
+void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
+			       struct net_device *netdev, u16 reason,
+			       const u8 *ie, size_t ie_len, bool from_ap);
+
+void
 nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
 			    struct net_device *netdev, const u8 *addr,
 			    enum nl80211_key_type key_type,
-			    int key_id, const u8 *tsc);
+			    int key_id, const u8 *tsc, gfp_t gfp);
 
-extern void
+void
 nl80211_send_beacon_hint_event(struct wiphy *wiphy,
 			       struct ieee80211_channel *channel_before,
 			       struct ieee80211_channel *channel_after);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 75a406d..f256dff 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -62,6 +62,16 @@ const struct ieee80211_regdomain *cfg80211_regdomain;
  */
 static const struct ieee80211_regdomain *country_ie_regdomain;
 
+/*
+ * Protects static reg.c components:
+ *     - cfg80211_world_regdom
+ *     - cfg80211_regdom
+ *     - country_ie_regdomain
+ *     - last_request
+ */
+DEFINE_MUTEX(reg_mutex);
+#define assert_reg_lock() WARN_ON(!mutex_is_locked(&reg_mutex))
+
 /* Used to queue up regulatory hints */
 static LIST_HEAD(reg_requests_list);
 static spinlock_t reg_requests_lock;
@@ -113,11 +123,7 @@ static const struct ieee80211_regdomain world_regdom = {
 static const struct ieee80211_regdomain *cfg80211_world_regdom =
 	&world_regdom;
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-static char *ieee80211_regdom = "US";
-#else
 static char *ieee80211_regdom = "00";
-#endif
 
 module_param(ieee80211_regdom, charp, 0444);
 MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
@@ -1012,7 +1018,6 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
 			map_regdom_flags(reg_rule->flags) | bw_flags;
 		chan->max_antenna_gain = chan->orig_mag =
 			(int) MBI_TO_DBI(power_rule->max_antenna_gain);
-		chan->max_bandwidth = KHZ_TO_MHZ(desired_bw_khz);
 		chan->max_power = chan->orig_mpwr =
 			(int) MBM_TO_DBM(power_rule->max_eirp);
 		return;
@@ -1021,7 +1026,6 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
 	chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
 	chan->max_antenna_gain = min(chan->orig_mag,
 		(int) MBI_TO_DBI(power_rule->max_antenna_gain));
-	chan->max_bandwidth = KHZ_TO_MHZ(desired_bw_khz);
 	if (chan->orig_mpwr)
 		chan->max_power = min(chan->orig_mpwr,
 			(int) MBM_TO_DBM(power_rule->max_eirp));
@@ -1061,10 +1065,10 @@ static bool ignore_reg_update(struct wiphy *wiphy,
 
 static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 
-	list_for_each_entry(drv, &cfg80211_drv_list, list)
-		wiphy_update_regulatory(&drv->wiphy, initiator);
+	list_for_each_entry(rdev, &cfg80211_rdev_list, list)
+		wiphy_update_regulatory(&rdev->wiphy, initiator);
 }
 
 static void handle_reg_beacon(struct wiphy *wiphy,
@@ -1298,7 +1302,7 @@ static void handle_channel_custom(struct wiphy *wiphy,
 	struct ieee80211_supported_band *sband;
 	struct ieee80211_channel *chan;
 
-	assert_cfg80211_lock();
+	assert_reg_lock();
 
 	sband = wiphy->bands[band];
 	BUG_ON(chan_idx >= sband->n_channels);
@@ -1323,7 +1327,6 @@ static void handle_channel_custom(struct wiphy *wiphy,
 
 	chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
 	chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
-	chan->max_bandwidth = KHZ_TO_MHZ(desired_bw_khz);
 	chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
 }
 
@@ -1347,14 +1350,14 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
 	enum ieee80211_band band;
 	unsigned int bands_set = 0;
 
-	mutex_lock(&cfg80211_mutex);
+	mutex_lock(&reg_mutex);
 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 		if (!wiphy->bands[band])
 			continue;
 		handle_band_custom(wiphy, band, regd);
 		bands_set++;
 	}
-	mutex_unlock(&cfg80211_mutex);
+	mutex_unlock(&reg_mutex);
 
 	/*
 	 * no point in calling this if it won't have any effect
@@ -1421,7 +1424,7 @@ static int ignore_request(struct wiphy *wiphy,
 			if (last_wiphy != wiphy) {
 				/*
 				 * Two cards with two APs claiming different
-				 * different Country IE alpha2s. We could
+				 * Country IE alpha2s. We could
 				 * intersect them, but that seems unlikely
 				 * to be correct. Reject second one for now.
 				 */
@@ -1500,7 +1503,7 @@ static int ignore_request(struct wiphy *wiphy,
  * Returns zero if all went fine, %-EALREADY if a regulatory domain had
  * already been set or other standard error codes.
  *
- * Caller must hold &cfg80211_mutex
+ * Caller must hold &cfg80211_mutex and &reg_mutex
  */
 static int __regulatory_hint(struct wiphy *wiphy,
 			     struct regulatory_request *pending_request)
@@ -1575,6 +1578,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
 	BUG_ON(!reg_request->alpha2);
 
 	mutex_lock(&cfg80211_mutex);
+	mutex_lock(&reg_mutex);
 
 	if (wiphy_idx_valid(reg_request->wiphy_idx))
 		wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
@@ -1590,6 +1594,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
 	if (r == -EALREADY && wiphy && wiphy->strict_regulatory)
 		wiphy_update_regulatory(wiphy, reg_request->initiator);
 out:
+	mutex_unlock(&reg_mutex);
 	mutex_unlock(&cfg80211_mutex);
 }
 
@@ -1615,9 +1620,13 @@ static void reg_process_pending_hints(void)
 /* Processes beacon hints -- this has nothing to do with country IEs */
 static void reg_process_pending_beacon_hints(void)
 {
-	struct cfg80211_registered_device *drv;
+	struct cfg80211_registered_device *rdev;
 	struct reg_beacon *pending_beacon, *tmp;
 
+	/*
+	 * No need to hold the reg_mutex here as we just touch wiphys
+	 * and do not read or access regulatory variables.
+	 */
 	mutex_lock(&cfg80211_mutex);
 
 	/* This goes through the _pending_ beacon list */
@@ -1634,8 +1643,8 @@ static void reg_process_pending_beacon_hints(void)
 		list_del_init(&pending_beacon->list);
 
 		/* Applies the beacon hint to current wiphys */
-		list_for_each_entry(drv, &cfg80211_drv_list, list)
-			wiphy_update_new_beacon(&drv->wiphy, pending_beacon);
+		list_for_each_entry(rdev, &cfg80211_rdev_list, list)
+			wiphy_update_new_beacon(&rdev->wiphy, pending_beacon);
 
 		/* Remembers the beacon hint for new wiphys or reg changes */
 		list_add_tail(&pending_beacon->list, &reg_beacon_list);
@@ -1739,12 +1748,13 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
 }
 EXPORT_SYMBOL(regulatory_hint);
 
+/* Caller must hold reg_mutex */
 static bool reg_same_country_ie_hint(struct wiphy *wiphy,
 			u32 country_ie_checksum)
 {
 	struct wiphy *request_wiphy;
 
-	assert_cfg80211_lock();
+	assert_reg_lock();
 
 	if (unlikely(last_request->initiator !=
 	    NL80211_REGDOM_SET_BY_COUNTRY_IE))
@@ -1767,6 +1777,10 @@ static bool reg_same_country_ie_hint(struct wiphy *wiphy,
 	return false;
 }
 
+/*
+ * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and
+ * therefore cannot iterate over the rdev list here.
+ */
 void regulatory_hint_11d(struct wiphy *wiphy,
 			u8 *country_ie,
 			u8 country_ie_len)
@@ -1777,12 +1791,10 @@ void regulatory_hint_11d(struct wiphy *wiphy,
 	enum environment_cap env = ENVIRON_ANY;
 	struct regulatory_request *request;
 
-	mutex_lock(&cfg80211_mutex);
+	mutex_lock(&reg_mutex);
 
-	if (unlikely(!last_request)) {
-		mutex_unlock(&cfg80211_mutex);
-		return;
-	}
+	if (unlikely(!last_request))
+		goto out;
 
 	/* IE len must be evenly divisible by 2 */
 	if (country_ie_len & 0x01)
@@ -1808,54 +1820,14 @@ void regulatory_hint_11d(struct wiphy *wiphy,
 		env = ENVIRON_OUTDOOR;
 
 	/*
-	 * We will run this for *every* beacon processed for the BSSID, so
-	 * we optimize an early check to exit out early if we don't have to
-	 * do anything
+	 * We will run this only upon a successful connection on cfg80211.
+	 * We leave conflict resolution to the workqueue, where can hold
+	 * cfg80211_mutex.
 	 */
 	if (likely(last_request->initiator ==
 	    NL80211_REGDOM_SET_BY_COUNTRY_IE &&
-	    wiphy_idx_valid(last_request->wiphy_idx))) {
-		struct cfg80211_registered_device *drv_last_ie;
-
-		drv_last_ie =
-			cfg80211_drv_by_wiphy_idx(last_request->wiphy_idx);
-
-		/*
-		 * Lets keep this simple -- we trust the first AP
-		 * after we intersect with CRDA
-		 */
-		if (likely(&drv_last_ie->wiphy == wiphy)) {
-			/*
-			 * Ignore IEs coming in on this wiphy with
-			 * the same alpha2 and environment cap
-			 */
-			if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
-				  alpha2) &&
-				  env == drv_last_ie->env)) {
-				goto out;
-			}
-			/*
-			 * the wiphy moved on to another BSSID or the AP
-			 * was reconfigured. XXX: We need to deal with the
-			 * case where the user suspends and goes to goes
-			 * to another country, and then gets IEs from an
-			 * AP with different settings
-			 */
-			goto out;
-		} else {
-			/*
-			 * Ignore IEs coming in on two separate wiphys with
-			 * the same alpha2 and environment cap
-			 */
-			if (likely(alpha2_equal(drv_last_ie->country_ie_alpha2,
-				  alpha2) &&
-				  env == drv_last_ie->env)) {
-				goto out;
-			}
-			/* We could potentially intersect though */
-			goto out;
-		}
-	}
+	    wiphy_idx_valid(last_request->wiphy_idx)))
+		goto out;
 
 	rd = country_ie_2_rd(country_ie, country_ie_len, &checksum);
 	if (!rd)
@@ -1890,7 +1862,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
 	request->country_ie_checksum = checksum;
 	request->country_ie_env = env;
 
-	mutex_unlock(&cfg80211_mutex);
+	mutex_unlock(&reg_mutex);
 
 	queue_regulatory_request(request);
 
@@ -1899,9 +1871,8 @@ void regulatory_hint_11d(struct wiphy *wiphy,
 free_rd_out:
 	kfree(rd);
 out:
-	mutex_unlock(&cfg80211_mutex);
+	mutex_unlock(&reg_mutex);
 }
-EXPORT_SYMBOL(regulatory_hint_11d);
 
 static bool freq_is_chan_12_13_14(u16 freq)
 {
@@ -1996,14 +1967,14 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
 
 		if (last_request->initiator ==
 		    NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-			struct cfg80211_registered_device *drv;
-			drv = cfg80211_drv_by_wiphy_idx(
+			struct cfg80211_registered_device *rdev;
+			rdev = cfg80211_rdev_by_wiphy_idx(
 				last_request->wiphy_idx);
-			if (drv) {
+			if (rdev) {
 				printk(KERN_INFO "cfg80211: Current regulatory "
 					"domain updated by AP to: %c%c\n",
-					drv->country_ie_alpha2[0],
-					drv->country_ie_alpha2[1]);
+					rdev->country_ie_alpha2[0],
+					rdev->country_ie_alpha2[1]);
 			} else
 				printk(KERN_INFO "cfg80211: Current regulatory "
 					"domain intersected: \n");
@@ -2064,7 +2035,7 @@ static inline void reg_country_ie_process_debug(
 static int __set_regdom(const struct ieee80211_regdomain *rd)
 {
 	const struct ieee80211_regdomain *intersected_rd = NULL;
-	struct cfg80211_registered_device *drv = NULL;
+	struct cfg80211_registered_device *rdev = NULL;
 	struct wiphy *request_wiphy;
 	/* Some basic sanity checks first */
 
@@ -2203,11 +2174,11 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
 	if (!intersected_rd)
 		return -EINVAL;
 
-	drv = wiphy_to_dev(request_wiphy);
+	rdev = wiphy_to_dev(request_wiphy);
 
-	drv->country_ie_alpha2[0] = rd->alpha2[0];
-	drv->country_ie_alpha2[1] = rd->alpha2[1];
-	drv->env = last_request->country_ie_env;
+	rdev->country_ie_alpha2[0] = rd->alpha2[0];
+	rdev->country_ie_alpha2[1] = rd->alpha2[1];
+	rdev->env = last_request->country_ie_env;
 
 	BUG_ON(intersected_rd == rd);
 
@@ -2232,10 +2203,13 @@ int set_regdom(const struct ieee80211_regdomain *rd)
 
 	assert_cfg80211_lock();
 
+	mutex_lock(&reg_mutex);
+
 	/* Note that this doesn't update the wiphys, this is done below */
 	r = __set_regdom(rd);
 	if (r) {
 		kfree(rd);
+		mutex_unlock(&reg_mutex);
 		return r;
 	}
 
@@ -2250,6 +2224,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
 
 	nl80211_send_reg_change_event(last_request);
 
+	mutex_unlock(&reg_mutex);
+
 	return r;
 }
 
@@ -2260,16 +2236,20 @@ void reg_device_remove(struct wiphy *wiphy)
 
 	assert_cfg80211_lock();
 
+	mutex_lock(&reg_mutex);
+
 	kfree(wiphy->regd);
 
 	if (last_request)
 		request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
 
 	if (!request_wiphy || request_wiphy != wiphy)
-		return;
+		goto out;
 
 	last_request->wiphy_idx = WIPHY_IDX_STALE;
 	last_request->country_ie_env = ENVIRON_ANY;
+out:
+	mutex_unlock(&reg_mutex);
 }
 
 int regulatory_init(void)
@@ -2288,22 +2268,12 @@ int regulatory_init(void)
 
 	printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
 	print_regdomain_info(cfg80211_regdomain);
-	/*
-	 * The old code still requests for a new regdomain and if
-	 * you have CRDA you get it updated, otherwise you get
-	 * stuck with the static values. Since "EU" is not a valid
-	 * ISO / IEC 3166 alpha2 code we can't expect userpace to
-	 * give us a regulatory domain for it. We need last_request
-	 * iniitalized though so lets just send a request which we
-	 * know will be ignored... this crap will be removed once
-	 * OLD_REG dies.
-	 */
-	err = regulatory_hint_core(ieee80211_regdom);
 #else
 	cfg80211_regdomain = cfg80211_world_regdom;
 
-	err = regulatory_hint_core(ieee80211_regdom);
 #endif
+	/* We always try to get an update for the static regdomain */
+	err = regulatory_hint_core(cfg80211_regdomain->alpha2);
 	if (err) {
 		if (err == -ENOMEM)
 			return err;
@@ -2322,6 +2292,13 @@ int regulatory_init(void)
 #endif
 	}
 
+	/*
+	 * Finally, if the user set the module parameter treat it
+	 * as a user hint.
+	 */
+	if (!is_world_regdom(ieee80211_regdom))
+		regulatory_hint_user(ieee80211_regdom);
+
 	return 0;
 }
 
@@ -2333,6 +2310,7 @@ void regulatory_exit(void)
 	cancel_work_sync(&reg_work);
 
 	mutex_lock(&cfg80211_mutex);
+	mutex_lock(&reg_mutex);
 
 	reset_regdomains();
 
@@ -2371,5 +2349,6 @@ void regulatory_exit(void)
 	}
 	spin_unlock(&reg_requests_lock);
 
+	mutex_unlock(&reg_mutex);
 	mutex_unlock(&cfg80211_mutex);
 }
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 4e167a8..3362c7c 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -37,4 +37,19 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
 					struct ieee80211_channel *beacon_chan,
 					gfp_t gfp);
 
+/**
+ * regulatory_hint_11d - hints a country IE as a regulatory domain
+ * @wiphy: the wireless device giving the hint (used only for reporting
+ *	conflicts)
+ * @country_ie: pointer to the country IE
+ * @country_ie_len: length of the country IE
+ *
+ * We will intersect the rd with the what CRDA tells us should apply
+ * for the alpha2 this country IE belongs to, this prevents APs from
+ * sending us incorrect or outdated information against a country.
+ */
+void regulatory_hint_11d(struct wiphy *wiphy,
+			 u8 *country_ie,
+			 u8 country_ie_len);
+
 #endif  /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 7e595ce..e5f92ee 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -14,29 +14,41 @@
 #include <net/iw_handler.h>
 #include "core.h"
 #include "nl80211.h"
+#include "wext-compat.h"
 
-#define IEEE80211_SCAN_RESULT_EXPIRE	(10 * HZ)
+#define IEEE80211_SCAN_RESULT_EXPIRE	(15 * HZ)
 
-void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
+void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
 {
+	struct cfg80211_scan_request *request;
 	struct net_device *dev;
 #ifdef CONFIG_WIRELESS_EXT
 	union iwreq_data wrqu;
 #endif
 
-	dev = dev_get_by_index(&init_net, request->ifidx);
-	if (!dev)
-		goto out;
+	ASSERT_RDEV_LOCK(rdev);
 
-	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
+	request = rdev->scan_req;
+
+	if (!request)
+		return;
+
+	dev = request->dev;
 
-	if (aborted)
-		nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
+	/*
+	 * This must be before sending the other events!
+	 * Otherwise, wpa_supplicant gets completely confused with
+	 * wext events.
+	 */
+	cfg80211_sme_scan_done(dev);
+
+	if (request->aborted)
+		nl80211_send_scan_aborted(rdev, dev);
 	else
-		nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
+		nl80211_send_scan_done(rdev, dev);
 
 #ifdef CONFIG_WIRELESS_EXT
-	if (!aborted) {
+	if (!request->aborted) {
 		memset(&wrqu, 0, sizeof(wrqu));
 
 		wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
@@ -45,9 +57,38 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
 
 	dev_put(dev);
 
- out:
-	wiphy_to_dev(request->wiphy)->scan_req = NULL;
-	kfree(request);
+	rdev->scan_req = NULL;
+
+	/*
+	 * OK. If this is invoked with "leak" then we can't
+	 * free this ... but we've cleaned it up anyway. The
+	 * driver failed to call the scan_done callback, so
+	 * all bets are off, it might still be trying to use
+	 * the scan request or not ... if it accesses the dev
+	 * in there (it shouldn't anyway) then it may crash.
+	 */
+	if (!leak)
+		kfree(request);
+}
+
+void __cfg80211_scan_done(struct work_struct *wk)
+{
+	struct cfg80211_registered_device *rdev;
+
+	rdev = container_of(wk, struct cfg80211_registered_device,
+			    scan_done_wk);
+
+	cfg80211_lock_rdev(rdev);
+	___cfg80211_scan_done(rdev, false);
+	cfg80211_unlock_rdev(rdev);
+}
+
+void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
+{
+	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
+
+	request->aborted = aborted;
+	schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk);
 }
 EXPORT_SYMBOL(cfg80211_scan_done);
 
@@ -62,6 +103,8 @@ static void bss_release(struct kref *ref)
 	if (bss->ies_allocated)
 		kfree(bss->pub.information_elements);
 
+	BUG_ON(atomic_read(&bss->hold));
+
 	kfree(bss);
 }
 
@@ -84,8 +127,9 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
 	bool expired = false;
 
 	list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
-		if (bss->hold ||
-		    !time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
+		if (atomic_read(&bss->hold))
+			continue;
+		if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
 			continue;
 		list_del(&bss->list);
 		rb_erase(&bss->rbn, &dev->bss_tree);
@@ -97,7 +141,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
 		dev->bss_generation++;
 }
 
-static u8 *find_ie(u8 num, u8 *ies, size_t len)
+static u8 *find_ie(u8 num, u8 *ies, int len)
 {
 	while (len > 2 && ies[0] != num) {
 		len -= ies[1] + 2;
@@ -539,6 +583,7 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
 	spin_lock_bh(&dev->bss_lock);
 
 	list_del(&bss->list);
+	dev->bss_generation++;
 	rb_erase(&bss->rbn, &dev->bss_tree);
 
 	spin_unlock_bh(&dev->bss_lock);
@@ -547,30 +592,6 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
 }
 EXPORT_SYMBOL(cfg80211_unlink_bss);
 
-void cfg80211_hold_bss(struct cfg80211_bss *pub)
-{
-	struct cfg80211_internal_bss *bss;
-
-	if (!pub)
-		return;
-
-	bss = container_of(pub, struct cfg80211_internal_bss, pub);
-	bss->hold = true;
-}
-EXPORT_SYMBOL(cfg80211_hold_bss);
-
-void cfg80211_unhold_bss(struct cfg80211_bss *pub)
-{
-	struct cfg80211_internal_bss *bss;
-
-	if (!pub)
-		return;
-
-	bss = container_of(pub, struct cfg80211_internal_bss, pub);
-	bss->hold = false;
-}
-EXPORT_SYMBOL(cfg80211_unhold_bss);
-
 #ifdef CONFIG_WIRELESS_EXT
 int cfg80211_wext_siwscan(struct net_device *dev,
 			  struct iw_request_info *info,
@@ -586,7 +607,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 	if (!netif_running(dev))
 		return -ENETDOWN;
 
-	rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);
+	if (wrqu->data.length == sizeof(struct iw_scan_req))
+		wreq = (struct iw_scan_req *)extra;
+
+	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
 
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
@@ -598,9 +622,14 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 
 	wiphy = &rdev->wiphy;
 
-	for (band = 0; band < IEEE80211_NUM_BANDS; band++)
-		if (wiphy->bands[band])
-			n_channels += wiphy->bands[band]->n_channels;
+	/* Determine number of channels, needed to allocate creq */
+	if (wreq && wreq->num_channels)
+		n_channels = wreq->num_channels;
+	else {
+		for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+			if (wiphy->bands[band])
+				n_channels += wiphy->bands[band]->n_channels;
+	}
 
 	creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
 		       n_channels * sizeof(void *),
@@ -611,28 +640,52 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 	}
 
 	creq->wiphy = wiphy;
-	creq->ifidx = dev->ifindex;
-	creq->ssids = (void *)(creq + 1);
-	creq->channels = (void *)(creq->ssids + 1);
+	creq->dev = dev;
+	/* SSIDs come after channels */
+	creq->ssids = (void *)&creq->channels[n_channels];
 	creq->n_channels = n_channels;
 	creq->n_ssids = 1;
 
-	/* all channels */
+	/* translate "Scan on frequencies" request */
 	i = 0;
 	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
 		int j;
 		if (!wiphy->bands[band])
 			continue;
 		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+
+			/* If we have a wireless request structure and the
+			 * wireless request specifies frequencies, then search
+			 * for the matching hardware channel.
+			 */
+			if (wreq && wreq->num_channels) {
+				int k;
+				int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
+				for (k = 0; k < wreq->num_channels; k++) {
+					int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]);
+					if (wext_freq == wiphy_freq)
+						goto wext_freq_found;
+				}
+				goto wext_freq_not_found;
+			}
+
+		wext_freq_found:
 			creq->channels[i] = &wiphy->bands[band]->channels[j];
 			i++;
+		wext_freq_not_found: ;
 		}
 	}
+	/* No channels found? */
+	if (!i) {
+		err = -EINVAL;
+		goto out;
+	}
 
-	/* translate scan request */
-	if (wrqu->data.length == sizeof(struct iw_scan_req)) {
-		wreq = (struct iw_scan_req *)extra;
+	/* Set real number of channels specified in creq->channels[] */
+	creq->n_channels = i;
 
+	/* translate "Scan for SSID" request */
+	if (wreq) {
 		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
 			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
 				return -EINVAL;
@@ -648,9 +701,12 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 	if (err) {
 		rdev->scan_req = NULL;
 		kfree(creq);
+	} else {
+		nl80211_send_scan_start(rdev, dev);
+		dev_hold(dev);
 	}
  out:
-	cfg80211_put_dev(rdev);
+	cfg80211_unlock_rdev(rdev);
 	return err;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
@@ -941,7 +997,7 @@ int cfg80211_wext_giwscan(struct net_device *dev,
 	if (!netif_running(dev))
 		return -ENETDOWN;
 
-	rdev = cfg80211_get_dev_from_ifindex(dev->ifindex);
+	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
 
 	if (IS_ERR(rdev))
 		return PTR_ERR(rdev);
@@ -959,7 +1015,7 @@ int cfg80211_wext_giwscan(struct net_device *dev,
 	}
 
  out:
-	cfg80211_put_dev(rdev);
+	cfg80211_unlock_rdev(rdev);
 	return res;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
new file mode 100644
index 0000000..7fae7ee
--- /dev/null
+++ b/net/wireless/sme.c
@@ -0,0 +1,938 @@
+/*
+ * SME code for cfg80211's connect emulation.
+ *
+ * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (C) 2009   Intel Corporation. All rights reserved.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <linux/workqueue.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/cfg80211.h>
+#include <net/rtnetlink.h>
+#include "nl80211.h"
+#include "reg.h"
+
+struct cfg80211_conn {
+	struct cfg80211_connect_params params;
+	/* these are sub-states of the _CONNECTING sme_state */
+	enum {
+		CFG80211_CONN_IDLE,
+		CFG80211_CONN_SCANNING,
+		CFG80211_CONN_SCAN_AGAIN,
+		CFG80211_CONN_AUTHENTICATE_NEXT,
+		CFG80211_CONN_AUTHENTICATING,
+		CFG80211_CONN_ASSOCIATE_NEXT,
+		CFG80211_CONN_ASSOCIATING,
+	} state;
+	u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
+	u8 *ie;
+	size_t ie_len;
+	bool auto_auth, prev_bssid_valid;
+};
+
+
+static int cfg80211_conn_scan(struct wireless_dev *wdev)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_scan_request *request;
+	int n_channels, err;
+
+	ASSERT_RTNL();
+	ASSERT_RDEV_LOCK(rdev);
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (rdev->scan_req)
+		return -EBUSY;
+
+	if (wdev->conn->params.channel) {
+		n_channels = 1;
+	} else {
+		enum ieee80211_band band;
+		n_channels = 0;
+
+		for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+			if (!wdev->wiphy->bands[band])
+				continue;
+			n_channels += wdev->wiphy->bands[band]->n_channels;
+		}
+	}
+	request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
+			  sizeof(request->channels[0]) * n_channels,
+			  GFP_KERNEL);
+	if (!request)
+		return -ENOMEM;
+
+	if (wdev->conn->params.channel)
+		request->channels[0] = wdev->conn->params.channel;
+	else {
+		int i = 0, j;
+		enum ieee80211_band band;
+
+		for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+			if (!wdev->wiphy->bands[band])
+				continue;
+			for (j = 0; j < wdev->wiphy->bands[band]->n_channels;
+			     i++, j++)
+				request->channels[i] =
+					&wdev->wiphy->bands[band]->channels[j];
+		}
+	}
+	request->n_channels = n_channels;
+	request->ssids = (void *)&request->channels[n_channels];
+	request->n_ssids = 1;
+
+	memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
+		wdev->conn->params.ssid_len);
+	request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
+
+	request->dev = wdev->netdev;
+	request->wiphy = &rdev->wiphy;
+
+	rdev->scan_req = request;
+
+	err = rdev->ops->scan(wdev->wiphy, wdev->netdev, request);
+	if (!err) {
+		wdev->conn->state = CFG80211_CONN_SCANNING;
+		nl80211_send_scan_start(rdev, wdev->netdev);
+		dev_hold(wdev->netdev);
+	} else {
+		rdev->scan_req = NULL;
+		kfree(request);
+	}
+	return err;
+}
+
+static int cfg80211_conn_do_work(struct wireless_dev *wdev)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_connect_params *params;
+	const u8 *prev_bssid = NULL;
+	int err;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (!wdev->conn)
+		return 0;
+
+	params = &wdev->conn->params;
+
+	switch (wdev->conn->state) {
+	case CFG80211_CONN_SCAN_AGAIN:
+		return cfg80211_conn_scan(wdev);
+	case CFG80211_CONN_AUTHENTICATE_NEXT:
+		BUG_ON(!rdev->ops->auth);
+		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
+		return __cfg80211_mlme_auth(rdev, wdev->netdev,
+					    params->channel, params->auth_type,
+					    params->bssid,
+					    params->ssid, params->ssid_len,
+					    NULL, 0,
+					    params->key, params->key_len,
+					    params->key_idx);
+	case CFG80211_CONN_ASSOCIATE_NEXT:
+		BUG_ON(!rdev->ops->assoc);
+		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
+		if (wdev->conn->prev_bssid_valid)
+			prev_bssid = wdev->conn->prev_bssid;
+		err = __cfg80211_mlme_assoc(rdev, wdev->netdev,
+					    params->channel, params->bssid,
+					    prev_bssid,
+					    params->ssid, params->ssid_len,
+					    params->ie, params->ie_len,
+					    false, &params->crypto);
+		if (err)
+			__cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
+					       NULL, 0,
+					       WLAN_REASON_DEAUTH_LEAVING);
+		return err;
+	default:
+		return 0;
+	}
+}
+
+void cfg80211_conn_work(struct work_struct *work)
+{
+	struct cfg80211_registered_device *rdev =
+		container_of(work, struct cfg80211_registered_device, conn_work);
+	struct wireless_dev *wdev;
+
+	rtnl_lock();
+	cfg80211_lock_rdev(rdev);
+	mutex_lock(&rdev->devlist_mtx);
+
+	list_for_each_entry(wdev, &rdev->netdev_list, list) {
+		wdev_lock(wdev);
+		if (!netif_running(wdev->netdev)) {
+			wdev_unlock(wdev);
+			continue;
+		}
+		if (wdev->sme_state != CFG80211_SME_CONNECTING) {
+			wdev_unlock(wdev);
+			continue;
+		}
+		if (cfg80211_conn_do_work(wdev))
+			__cfg80211_connect_result(
+					wdev->netdev,
+					wdev->conn->params.bssid,
+					NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					false, NULL);
+		wdev_unlock(wdev);
+	}
+
+	mutex_unlock(&rdev->devlist_mtx);
+	cfg80211_unlock_rdev(rdev);
+	rtnl_unlock();
+}
+
+static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_bss *bss;
+	u16 capa = WLAN_CAPABILITY_ESS;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (wdev->conn->params.privacy)
+		capa |= WLAN_CAPABILITY_PRIVACY;
+
+	bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid,
+			       wdev->conn->params.ssid,
+			       wdev->conn->params.ssid_len,
+			       WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
+			       capa);
+	if (!bss)
+		return NULL;
+
+	memcpy(wdev->conn->bssid, bss->bssid, ETH_ALEN);
+	wdev->conn->params.bssid = wdev->conn->bssid;
+	wdev->conn->params.channel = bss->channel;
+	wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+	schedule_work(&rdev->conn_work);
+
+	return bss;
+}
+
+static void __cfg80211_sme_scan_done(struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_bss *bss;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (wdev->sme_state != CFG80211_SME_CONNECTING)
+		return;
+
+	if (!wdev->conn)
+		return;
+
+	if (wdev->conn->state != CFG80211_CONN_SCANNING &&
+	    wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
+		return;
+
+	bss = cfg80211_get_conn_bss(wdev);
+	if (bss) {
+		cfg80211_put_bss(bss);
+	} else {
+		/* not found */
+		if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
+			schedule_work(&rdev->conn_work);
+		else
+			__cfg80211_connect_result(
+					wdev->netdev,
+					wdev->conn->params.bssid,
+					NULL, 0, NULL, 0,
+					WLAN_STATUS_UNSPECIFIED_FAILURE,
+					false, NULL);
+	}
+}
+
+void cfg80211_sme_scan_done(struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	mutex_lock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
+	wdev_lock(wdev);
+	__cfg80211_sme_scan_done(dev);
+	wdev_unlock(wdev);
+	mutex_unlock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx);
+}
+
+void cfg80211_sme_rx_auth(struct net_device *dev,
+			  const u8 *buf, size_t len)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
+	u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	/* should only RX auth frames when connecting */
+	if (wdev->sme_state != CFG80211_SME_CONNECTING)
+		return;
+
+	if (WARN_ON(!wdev->conn))
+		return;
+
+	if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
+	    wdev->conn->auto_auth &&
+	    wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
+		/* select automatically between only open, shared, leap */
+		switch (wdev->conn->params.auth_type) {
+		case NL80211_AUTHTYPE_OPEN_SYSTEM:
+			if (wdev->connect_keys)
+				wdev->conn->params.auth_type =
+					NL80211_AUTHTYPE_SHARED_KEY;
+			else
+				wdev->conn->params.auth_type =
+					NL80211_AUTHTYPE_NETWORK_EAP;
+			break;
+		case NL80211_AUTHTYPE_SHARED_KEY:
+			wdev->conn->params.auth_type =
+				NL80211_AUTHTYPE_NETWORK_EAP;
+			break;
+		default:
+			/* huh? */
+			wdev->conn->params.auth_type =
+				NL80211_AUTHTYPE_OPEN_SYSTEM;
+			break;
+		}
+		wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+		schedule_work(&rdev->conn_work);
+	} else if (status_code != WLAN_STATUS_SUCCESS) {
+		__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
+					  status_code, false, NULL);
+	} else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
+		 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
+		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
+		schedule_work(&rdev->conn_work);
+	}
+}
+
+bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+	if (WARN_ON(!wdev->conn))
+		return false;
+
+	if (!wdev->conn->prev_bssid_valid)
+		return false;
+
+	/*
+	 * Some stupid APs don't accept reassoc, so we
+	 * need to fall back to trying regular assoc.
+	 */
+	wdev->conn->prev_bssid_valid = false;
+	wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
+	schedule_work(&rdev->conn_work);
+
+	return true;
+}
+
+void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			       const u8 *req_ie, size_t req_ie_len,
+			       const u8 *resp_ie, size_t resp_ie_len,
+			       u16 status, bool wextev,
+			       struct cfg80211_bss *bss)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	u8 *country_ie;
+#ifdef CONFIG_WIRELESS_EXT
+	union iwreq_data wrqu;
+#endif
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return;
+
+	if (wdev->sme_state != CFG80211_SME_CONNECTING)
+		return;
+
+	nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
+				    bssid, req_ie, req_ie_len,
+				    resp_ie, resp_ie_len,
+				    status, GFP_KERNEL);
+
+#ifdef CONFIG_WIRELESS_EXT
+	if (wextev) {
+		if (req_ie && status == WLAN_STATUS_SUCCESS) {
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.length = req_ie_len;
+			wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, req_ie);
+		}
+
+		if (resp_ie && status == WLAN_STATUS_SUCCESS) {
+			memset(&wrqu, 0, sizeof(wrqu));
+			wrqu.data.length = resp_ie_len;
+			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, resp_ie);
+		}
+
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+		if (bssid && status == WLAN_STATUS_SUCCESS) {
+			memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+			memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);
+			wdev->wext.prev_bssid_valid = true;
+		}
+		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+	}
+#endif
+
+	if (wdev->current_bss) {
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
+		wdev->current_bss = NULL;
+	}
+
+	if (wdev->conn)
+		wdev->conn->state = CFG80211_CONN_IDLE;
+
+	if (status != WLAN_STATUS_SUCCESS) {
+		wdev->sme_state = CFG80211_SME_IDLE;
+		if (wdev->conn)
+			kfree(wdev->conn->ie);
+		kfree(wdev->conn);
+		wdev->conn = NULL;
+		kfree(wdev->connect_keys);
+		wdev->connect_keys = NULL;
+		wdev->ssid_len = 0;
+		return;
+	}
+
+	if (!bss)
+		bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+				       wdev->ssid, wdev->ssid_len,
+				       WLAN_CAPABILITY_ESS,
+				       WLAN_CAPABILITY_ESS);
+
+	if (WARN_ON(!bss))
+		return;
+
+	cfg80211_hold_bss(bss_from_pub(bss));
+	wdev->current_bss = bss_from_pub(bss);
+
+	wdev->sme_state = CFG80211_SME_CONNECTED;
+	cfg80211_upload_connect_keys(wdev);
+
+	country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
+
+	if (!country_ie)
+		return;
+
+	/*
+	 * ieee80211_bss_get_ie() ensures we can access:
+	 * - country_ie + 2, the start of the country ie data, and
+	 * - and country_ie[1] which is the IE length
+	 */
+	regulatory_hint_11d(wdev->wiphy,
+			    country_ie + 2,
+			    country_ie[1]);
+}
+
+void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
+			     const u8 *req_ie, size_t req_ie_len,
+			     const u8 *resp_ie, size_t resp_ie_len,
+			     u16 status, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
+
+	ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_CONNECT_RESULT;
+	if (bssid)
+		memcpy(ev->cr.bssid, bssid, ETH_ALEN);
+	ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
+	ev->cr.req_ie_len = req_ie_len;
+	memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
+	ev->cr.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
+	ev->cr.resp_ie_len = resp_ie_len;
+	memcpy((void *)ev->cr.resp_ie, resp_ie, resp_ie_len);
+	ev->cr.status = status;
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
+}
+EXPORT_SYMBOL(cfg80211_connect_result);
+
+void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
+		       const u8 *req_ie, size_t req_ie_len,
+		       const u8 *resp_ie, size_t resp_ie_len)
+{
+	struct cfg80211_bss *bss;
+#ifdef CONFIG_WIRELESS_EXT
+	union iwreq_data wrqu;
+#endif
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return;
+
+	if (wdev->sme_state != CFG80211_SME_CONNECTED)
+		return;
+
+	/* internal error -- how did we get to CONNECTED w/o BSS? */
+	if (WARN_ON(!wdev->current_bss)) {
+		return;
+	}
+
+	cfg80211_unhold_bss(wdev->current_bss);
+	cfg80211_put_bss(&wdev->current_bss->pub);
+	wdev->current_bss = NULL;
+
+	bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+			       wdev->ssid, wdev->ssid_len,
+			       WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
+
+	if (WARN_ON(!bss))
+		return;
+
+	cfg80211_hold_bss(bss_from_pub(bss));
+	wdev->current_bss = bss_from_pub(bss);
+
+	nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), wdev->netdev, bssid,
+			    req_ie, req_ie_len, resp_ie, resp_ie_len,
+			    GFP_KERNEL);
+
+#ifdef CONFIG_WIRELESS_EXT
+	if (req_ie) {
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = req_ie_len;
+		wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
+				    &wrqu, req_ie);
+	}
+
+	if (resp_ie) {
+		memset(&wrqu, 0, sizeof(wrqu));
+		wrqu.data.length = resp_ie_len;
+		wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
+				    &wrqu, resp_ie);
+	}
+
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+	memcpy(wdev->wext.prev_bssid, bssid, ETH_ALEN);
+	wdev->wext.prev_bssid_valid = true;
+	wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+
+void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
+		     const u8 *req_ie, size_t req_ie_len,
+		     const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
+
+	ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_ROAMED;
+	memcpy(ev->rm.bssid, bssid, ETH_ALEN);
+	ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
+	ev->rm.req_ie_len = req_ie_len;
+	memcpy((void *)ev->rm.req_ie, req_ie, req_ie_len);
+	ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
+	ev->rm.resp_ie_len = resp_ie_len;
+	memcpy((void *)ev->rm.resp_ie, resp_ie, resp_ie_len);
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
+}
+EXPORT_SYMBOL(cfg80211_roamed);
+
+void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
+			     size_t ie_len, u16 reason, bool from_ap)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	int i;
+#ifdef CONFIG_WIRELESS_EXT
+	union iwreq_data wrqu;
+#endif
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return;
+
+	if (wdev->sme_state != CFG80211_SME_CONNECTED)
+		return;
+
+	if (wdev->current_bss) {
+		cfg80211_unhold_bss(wdev->current_bss);
+		cfg80211_put_bss(&wdev->current_bss->pub);
+	}
+
+	wdev->current_bss = NULL;
+	wdev->sme_state = CFG80211_SME_IDLE;
+	wdev->ssid_len = 0;
+
+	if (wdev->conn) {
+		const u8 *bssid;
+		int ret;
+
+		kfree(wdev->conn->ie);
+		wdev->conn->ie = NULL;
+		kfree(wdev->conn);
+		wdev->conn = NULL;
+
+		/*
+		 * If this disconnect was due to a disassoc, we
+		 * we might still have an auth BSS around. For
+		 * the userspace SME that's currently expected,
+		 * but for the kernel SME (nl80211 CONNECT or
+		 * wireless extensions) we want to clear up all
+		 * state.
+		 */
+		for (i = 0; i < MAX_AUTH_BSSES; i++) {
+			if (!wdev->auth_bsses[i])
+				continue;
+			bssid = wdev->auth_bsses[i]->pub.bssid;
+			ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
+						WLAN_REASON_DEAUTH_LEAVING);
+			WARN(ret, "deauth failed: %d\n", ret);
+		}
+	}
+
+	nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
+
+	/*
+	 * Delete all the keys ... pairwise keys can't really
+	 * exist any more anyway, but default keys might.
+	 */
+	if (rdev->ops->del_key)
+		for (i = 0; i < 6; i++)
+			rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
+
+#ifdef CONFIG_WIRELESS_EXT
+	memset(&wrqu, 0, sizeof(wrqu));
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+
+void cfg80211_disconnected(struct net_device *dev, u16 reason,
+			   u8 *ie, size_t ie_len, gfp_t gfp)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_event *ev;
+	unsigned long flags;
+
+	CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
+
+	ev = kzalloc(sizeof(*ev) + ie_len, gfp);
+	if (!ev)
+		return;
+
+	ev->type = EVENT_DISCONNECTED;
+	ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
+	ev->dc.ie_len = ie_len;
+	memcpy((void *)ev->dc.ie, ie, ie_len);
+	ev->dc.reason = reason;
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	list_add_tail(&ev->list, &wdev->event_list);
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+	schedule_work(&rdev->event_work);
+}
+EXPORT_SYMBOL(cfg80211_disconnected);
+
+int __cfg80211_connect(struct cfg80211_registered_device *rdev,
+		       struct net_device *dev,
+		       struct cfg80211_connect_params *connect,
+		       struct cfg80211_cached_keys *connkeys,
+		       const u8 *prev_bssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct ieee80211_channel *chan;
+	struct cfg80211_bss *bss = NULL;
+	int err;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (wdev->sme_state != CFG80211_SME_IDLE)
+		return -EALREADY;
+
+	chan = rdev_fixed_channel(rdev, wdev);
+	if (chan && chan != connect->channel)
+		return -EBUSY;
+
+	if (WARN_ON(wdev->connect_keys)) {
+		kfree(wdev->connect_keys);
+		wdev->connect_keys = NULL;
+	}
+
+	if (connkeys && connkeys->def >= 0) {
+		int idx;
+		u32 cipher;
+
+		idx = connkeys->def;
+		cipher = connkeys->params[idx].cipher;
+		/* If given a WEP key we may need it for shared key auth */
+		if (cipher == WLAN_CIPHER_SUITE_WEP40 ||
+		    cipher == WLAN_CIPHER_SUITE_WEP104) {
+			connect->key_idx = idx;
+			connect->key = connkeys->params[idx].key;
+			connect->key_len = connkeys->params[idx].key_len;
+
+			/*
+			 * If ciphers are not set (e.g. when going through
+			 * iwconfig), we have to set them appropriately here.
+			 */
+			if (connect->crypto.cipher_group == 0)
+				connect->crypto.cipher_group = cipher;
+
+			if (connect->crypto.n_ciphers_pairwise == 0) {
+				connect->crypto.n_ciphers_pairwise = 1;
+				connect->crypto.ciphers_pairwise[0] = cipher;
+			}
+		}
+	}
+
+	if (!rdev->ops->connect) {
+		if (!rdev->ops->auth || !rdev->ops->assoc)
+			return -EOPNOTSUPP;
+
+		if (WARN_ON(wdev->conn))
+			return -EINPROGRESS;
+
+		wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
+		if (!wdev->conn)
+			return -ENOMEM;
+
+		/*
+		 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
+		 */
+		memcpy(&wdev->conn->params, connect, sizeof(*connect));
+		if (connect->bssid) {
+			wdev->conn->params.bssid = wdev->conn->bssid;
+			memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
+		}
+
+		if (connect->ie) {
+			wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
+						GFP_KERNEL);
+			wdev->conn->params.ie = wdev->conn->ie;
+			if (!wdev->conn->ie) {
+				kfree(wdev->conn);
+				wdev->conn = NULL;
+				return -ENOMEM;
+			}
+		}
+
+		if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
+			wdev->conn->auto_auth = true;
+			/* start with open system ... should mostly work */
+			wdev->conn->params.auth_type =
+				NL80211_AUTHTYPE_OPEN_SYSTEM;
+		} else {
+			wdev->conn->auto_auth = false;
+		}
+
+		memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
+		wdev->ssid_len = connect->ssid_len;
+		wdev->conn->params.ssid = wdev->ssid;
+		wdev->conn->params.ssid_len = connect->ssid_len;
+
+		/* don't care about result -- but fill bssid & channel */
+		if (!wdev->conn->params.bssid || !wdev->conn->params.channel)
+			bss = cfg80211_get_conn_bss(wdev);
+
+		wdev->sme_state = CFG80211_SME_CONNECTING;
+		wdev->connect_keys = connkeys;
+
+		if (prev_bssid) {
+			memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
+			wdev->conn->prev_bssid_valid = true;
+		}
+
+		/* we're good if we have a matching bss struct */
+		if (bss) {
+			wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
+			err = cfg80211_conn_do_work(wdev);
+			cfg80211_put_bss(bss);
+		} else {
+			/* otherwise we'll need to scan for the AP first */
+			err = cfg80211_conn_scan(wdev);
+			/*
+			 * If we can't scan right now, then we need to scan again
+			 * after the current scan finished, since the parameters
+			 * changed (unless we find a good AP anyway).
+			 */
+			if (err == -EBUSY) {
+				err = 0;
+				wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
+			}
+		}
+		if (err) {
+			kfree(wdev->conn->ie);
+			kfree(wdev->conn);
+			wdev->conn = NULL;
+			wdev->sme_state = CFG80211_SME_IDLE;
+			wdev->connect_keys = NULL;
+			wdev->ssid_len = 0;
+		}
+
+		return err;
+	} else {
+		wdev->sme_state = CFG80211_SME_CONNECTING;
+		wdev->connect_keys = connkeys;
+		err = rdev->ops->connect(&rdev->wiphy, dev, connect);
+		if (err) {
+			wdev->connect_keys = NULL;
+			wdev->sme_state = CFG80211_SME_IDLE;
+			return err;
+		}
+
+		memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
+		wdev->ssid_len = connect->ssid_len;
+
+		return 0;
+	}
+}
+
+int cfg80211_connect(struct cfg80211_registered_device *rdev,
+		     struct net_device *dev,
+		     struct cfg80211_connect_params *connect,
+		     struct cfg80211_cached_keys *connkeys)
+{
+	int err;
+
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(dev->ieee80211_ptr);
+	err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL);
+	wdev_unlock(dev->ieee80211_ptr);
+	mutex_unlock(&rdev->devlist_mtx);
+
+	return err;
+}
+
+int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev, u16 reason, bool wextev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	int err;
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (wdev->sme_state == CFG80211_SME_IDLE)
+		return -EINVAL;
+
+	kfree(wdev->connect_keys);
+	wdev->connect_keys = NULL;
+
+	if (!rdev->ops->disconnect) {
+		if (!rdev->ops->deauth)
+			return -EOPNOTSUPP;
+
+		/* was it connected by userspace SME? */
+		if (!wdev->conn) {
+			cfg80211_mlme_down(rdev, dev);
+			return 0;
+		}
+
+		if (wdev->sme_state == CFG80211_SME_CONNECTING &&
+		    (wdev->conn->state == CFG80211_CONN_SCANNING ||
+		     wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
+			wdev->sme_state = CFG80211_SME_IDLE;
+			kfree(wdev->conn->ie);
+			kfree(wdev->conn);
+			wdev->conn = NULL;
+			wdev->ssid_len = 0;
+			return 0;
+		}
+
+		/* wdev->conn->params.bssid must be set if > SCANNING */
+		err = __cfg80211_mlme_deauth(rdev, dev,
+					     wdev->conn->params.bssid,
+					     NULL, 0, reason);
+		if (err)
+			return err;
+	} else {
+		err = rdev->ops->disconnect(&rdev->wiphy, dev, reason);
+		if (err)
+			return err;
+	}
+
+	if (wdev->sme_state == CFG80211_SME_CONNECTED)
+		__cfg80211_disconnected(dev, NULL, 0, 0, false);
+	else if (wdev->sme_state == CFG80211_SME_CONNECTING)
+		__cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
+					  WLAN_STATUS_UNSPECIFIED_FAILURE,
+					  wextev, NULL);
+
+	return 0;
+}
+
+int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
+			struct net_device *dev,
+			u16 reason, bool wextev)
+{
+	int err;
+
+	wdev_lock(dev->ieee80211_ptr);
+	err = __cfg80211_disconnect(rdev, dev, reason, wextev);
+	wdev_unlock(dev->ieee80211_ptr);
+
+	return err;
+}
+
+void cfg80211_sme_disassoc(struct net_device *dev, int idx)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	u8 bssid[ETH_ALEN];
+
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (!wdev->conn)
+		return;
+
+	if (wdev->conn->state == CFG80211_CONN_IDLE)
+		return;
+
+	/*
+	 * Ok, so the association was made by this SME -- we don't
+	 * want it any more so deauthenticate too.
+	 */
+
+	if (!wdev->auth_bsses[idx])
+		return;
+
+	memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
+	if (__cfg80211_mlme_deauth(rdev, dev, bssid,
+				   NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) {
+		/* whatever -- assume gone anyway */
+		cfg80211_unhold_bss(wdev->auth_bsses[idx]);
+		cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
+		wdev->auth_bsses[idx] = NULL;
+	}
+}
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 2555069..3fc2df8 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -141,9 +141,12 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
 			set_mandatory_flags_band(wiphy->bands[band], band);
 }
 
-int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
+int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
+				   struct key_params *params, int key_idx,
 				   const u8 *mac_addr)
 {
+	int i;
+
 	if (key_idx > 5)
 		return -EINVAL;
 
@@ -197,6 +200,12 @@ int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
 		}
 	}
 
+	for (i = 0; i < rdev->wiphy.n_cipher_suites; i++)
+		if (params->cipher == rdev->wiphy.cipher_suites[i])
+			break;
+	if (i == rdev->wiphy.n_cipher_suites)
+		return -EINVAL;
+
 	return 0;
 }
 
@@ -265,11 +274,11 @@ static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
 	switch (ae) {
 	case 0:
 		return 6;
-	case 1:
+	case MESH_FLAGS_AE_A4:
 		return 12;
-	case 2:
+	case MESH_FLAGS_AE_A5_A6:
 		return 18;
-	case 3:
+	case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
 		return 24;
 	default:
 		return 6;
@@ -324,10 +333,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
 		}
 		break;
 	case cpu_to_le16(IEEE80211_FCTL_FROMDS):
-		if (iftype != NL80211_IFTYPE_STATION ||
+		if ((iftype != NL80211_IFTYPE_STATION &&
+		    iftype != NL80211_IFTYPE_MESH_POINT) ||
 		    (is_multicast_ether_addr(dst) &&
 		     !compare_ether_addr(src, addr)))
 			return -1;
+		if (iftype == NL80211_IFTYPE_MESH_POINT) {
+			struct ieee80211s_hdr *meshdr =
+				(struct ieee80211s_hdr *) (skb->data + hdrlen);
+			hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
+			if (meshdr->flags & MESH_FLAGS_AE_A4)
+				memcpy(src, meshdr->eaddr1, ETH_ALEN);
+		}
 		break;
 	case cpu_to_le16(0):
 		if (iftype != NL80211_IFTYPE_ADHOC)
@@ -502,3 +519,166 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb)
 	return dscp >> 5;
 }
 EXPORT_SYMBOL(cfg80211_classify8021d);
+
+const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie)
+{
+	u8 *end, *pos;
+
+	pos = bss->information_elements;
+	if (pos == NULL)
+		return NULL;
+	end = pos + bss->len_information_elements;
+
+	while (pos + 1 < end) {
+		if (pos + 2 + pos[1] > end)
+			break;
+		if (pos[0] == ie)
+			return pos;
+		pos += 2 + pos[1];
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(ieee80211_bss_get_ie);
+
+void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
+{
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct net_device *dev = wdev->netdev;
+	int i;
+
+	if (!wdev->connect_keys)
+		return;
+
+	for (i = 0; i < 6; i++) {
+		if (!wdev->connect_keys->params[i].cipher)
+			continue;
+		if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL,
+					&wdev->connect_keys->params[i])) {
+			printk(KERN_ERR "%s: failed to set key %d\n",
+				dev->name, i);
+			continue;
+		}
+		if (wdev->connect_keys->def == i)
+			if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) {
+				printk(KERN_ERR "%s: failed to set defkey %d\n",
+					dev->name, i);
+				continue;
+			}
+		if (wdev->connect_keys->defmgmt == i)
+			if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i))
+				printk(KERN_ERR "%s: failed to set mgtdef %d\n",
+					dev->name, i);
+	}
+
+	kfree(wdev->connect_keys);
+	wdev->connect_keys = NULL;
+}
+
+static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
+{
+	struct cfg80211_event *ev;
+	unsigned long flags;
+	const u8 *bssid = NULL;
+
+	spin_lock_irqsave(&wdev->event_lock, flags);
+	while (!list_empty(&wdev->event_list)) {
+		ev = list_first_entry(&wdev->event_list,
+				      struct cfg80211_event, list);
+		list_del(&ev->list);
+		spin_unlock_irqrestore(&wdev->event_lock, flags);
+
+		wdev_lock(wdev);
+		switch (ev->type) {
+		case EVENT_CONNECT_RESULT:
+			if (!is_zero_ether_addr(ev->cr.bssid))
+				bssid = ev->cr.bssid;
+			__cfg80211_connect_result(
+				wdev->netdev, bssid,
+				ev->cr.req_ie, ev->cr.req_ie_len,
+				ev->cr.resp_ie, ev->cr.resp_ie_len,
+				ev->cr.status,
+				ev->cr.status == WLAN_STATUS_SUCCESS,
+				NULL);
+			break;
+		case EVENT_ROAMED:
+			__cfg80211_roamed(wdev, ev->rm.bssid,
+					  ev->rm.req_ie, ev->rm.req_ie_len,
+					  ev->rm.resp_ie, ev->rm.resp_ie_len);
+			break;
+		case EVENT_DISCONNECTED:
+			__cfg80211_disconnected(wdev->netdev,
+						ev->dc.ie, ev->dc.ie_len,
+						ev->dc.reason, true);
+			break;
+		case EVENT_IBSS_JOINED:
+			__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
+			break;
+		}
+		wdev_unlock(wdev);
+
+		kfree(ev);
+
+		spin_lock_irqsave(&wdev->event_lock, flags);
+	}
+	spin_unlock_irqrestore(&wdev->event_lock, flags);
+}
+
+void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
+{
+	struct wireless_dev *wdev;
+
+	ASSERT_RTNL();
+	ASSERT_RDEV_LOCK(rdev);
+
+	mutex_lock(&rdev->devlist_mtx);
+
+	list_for_each_entry(wdev, &rdev->netdev_list, list)
+		cfg80211_process_wdev_events(wdev);
+
+	mutex_unlock(&rdev->devlist_mtx);
+}
+
+int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
+			  struct net_device *dev, enum nl80211_iftype ntype,
+			  u32 *flags, struct vif_params *params)
+{
+	int err;
+	enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
+
+	ASSERT_RDEV_LOCK(rdev);
+
+	/* don't support changing VLANs, you just re-create them */
+	if (otype == NL80211_IFTYPE_AP_VLAN)
+		return -EOPNOTSUPP;
+
+	if (!rdev->ops->change_virtual_intf ||
+	    !(rdev->wiphy.interface_modes & (1 << ntype)))
+		return -EOPNOTSUPP;
+
+	if (ntype != otype) {
+		switch (otype) {
+		case NL80211_IFTYPE_ADHOC:
+			cfg80211_leave_ibss(rdev, dev, false);
+			break;
+		case NL80211_IFTYPE_STATION:
+			cfg80211_disconnect(rdev, dev,
+					    WLAN_REASON_DEAUTH_LEAVING, true);
+			break;
+		case NL80211_IFTYPE_MESH_POINT:
+			/* mesh should be handled? */
+			break;
+		default:
+			break;
+		}
+
+		cfg80211_process_rdev_events(rdev);
+	}
+
+	err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev,
+					     ntype, flags, params);
+
+	WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
+
+	return err;
+}
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index d030c53..429dd06 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -14,6 +14,7 @@
 #include <linux/etherdevice.h>
 #include <net/iw_handler.h>
 #include <net/cfg80211.h>
+#include "wext-compat.h"
 #include "core.h"
 
 int cfg80211_wext_giwname(struct net_device *dev,
@@ -69,18 +70,8 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
 	enum nl80211_iftype type;
 	int ret;
 
-	if (!wdev)
-		return -EOPNOTSUPP;
-
 	rdev = wiphy_to_dev(wdev->wiphy);
 
-	if (!rdev->ops->change_virtual_intf)
-		return -EOPNOTSUPP;
-
-	/* don't support changing VLANs, you just re-create them */
-	if (wdev->iftype == NL80211_IFTYPE_AP_VLAN)
-		return -EOPNOTSUPP;
-
 	switch (*mode) {
 	case IW_MODE_INFRA:
 		type = NL80211_IFTYPE_STATION;
@@ -103,9 +94,9 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
 
 	memset(&vifparams, 0, sizeof(vifparams));
 
-	ret = rdev->ops->change_virtual_intf(wdev->wiphy, dev->ifindex, type,
-					     NULL, &vifparams);
-	WARN_ON(!ret && wdev->iftype != type);
+	cfg80211_lock_rdev(rdev);
+	ret = cfg80211_change_iface(rdev, dev, type, NULL, &vifparams);
+	cfg80211_unlock_rdev(rdev);
 
 	return ret;
 }
@@ -154,7 +145,7 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
 	struct iw_range *range = (struct iw_range *) extra;
 	enum ieee80211_band band;
-	int c = 0;
+	int i, c = 0;
 
 	if (!wdev)
 		return -EOPNOTSUPP;
@@ -173,9 +164,6 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	range->min_frag = 256;
 	range->max_frag = 2346;
 
-	range->encoding_size[0] = 5;
-	range->encoding_size[1] = 13;
-	range->num_encoding_sizes = 2;
 	range->max_encoding_tokens = 4;
 
 	range->max_qual.updated = IW_QUAL_NOISE_INVALID;
@@ -204,11 +192,31 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	range->avg_qual.noise = range->max_qual.noise / 2;
 	range->avg_qual.updated = range->max_qual.updated;
 
-	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-			  IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+	for (i = 0; i < wdev->wiphy->n_cipher_suites; i++) {
+		switch (wdev->wiphy->cipher_suites[i]) {
+		case WLAN_CIPHER_SUITE_TKIP:
+			range->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP |
+					    IW_ENC_CAPA_WPA);
+			break;
+
+		case WLAN_CIPHER_SUITE_CCMP:
+			range->enc_capa |= (IW_ENC_CAPA_CIPHER_CCMP |
+					    IW_ENC_CAPA_WPA2);
+			break;
+
+		case WLAN_CIPHER_SUITE_WEP40:
+			range->encoding_size[range->num_encoding_sizes++] =
+				WLAN_KEY_LEN_WEP40;
+			break;
+
+		case WLAN_CIPHER_SUITE_WEP104:
+			range->encoding_size[range->num_encoding_sizes++] =
+				WLAN_KEY_LEN_WEP104;
+			break;
+		}
+	}
 
 	for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
-		int i;
 		struct ieee80211_supported_band *sband;
 
 		sband = wdev->wiphy->bands[band];
@@ -236,97 +244,40 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
 	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
 
-	range->scan_capa |= IW_SCAN_CAPA_ESSID;
+	if (wdev->wiphy->max_scan_ssids > 0)
+		range->scan_capa |= IW_SCAN_CAPA_ESSID;
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange);
 
-int cfg80211_wext_siwmlme(struct net_device *dev,
-			  struct iw_request_info *info,
-			  struct iw_point *data, char *extra)
-{
-	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct iw_mlme *mlme = (struct iw_mlme *)extra;
-	struct cfg80211_registered_device *rdev;
-	union {
-		struct cfg80211_disassoc_request disassoc;
-		struct cfg80211_deauth_request deauth;
-	} cmd;
-
-	if (!wdev)
-		return -EOPNOTSUPP;
-
-	rdev = wiphy_to_dev(wdev->wiphy);
-
-	if (wdev->iftype != NL80211_IFTYPE_STATION)
-		return -EINVAL;
-
-	if (mlme->addr.sa_family != ARPHRD_ETHER)
-		return -EINVAL;
-
-	memset(&cmd, 0, sizeof(cmd));
-
-	switch (mlme->cmd) {
-	case IW_MLME_DEAUTH:
-		if (!rdev->ops->deauth)
-			return -EOPNOTSUPP;
-		cmd.deauth.peer_addr = mlme->addr.sa_data;
-		cmd.deauth.reason_code = mlme->reason_code;
-		return rdev->ops->deauth(wdev->wiphy, dev, &cmd.deauth);
-	case IW_MLME_DISASSOC:
-		if (!rdev->ops->disassoc)
-			return -EOPNOTSUPP;
-		cmd.disassoc.peer_addr = mlme->addr.sa_data;
-		cmd.disassoc.reason_code = mlme->reason_code;
-		return rdev->ops->disassoc(wdev->wiphy, dev, &cmd.disassoc);
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
-
 
 /**
  * cfg80211_wext_freq - get wext frequency for non-"auto"
  * @wiphy: the wiphy
  * @freq: the wext freq encoding
  *
- * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
+ * Returns a frequency, or a negative error code, or 0 for auto.
  */
-struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
-					     struct iw_freq *freq)
+int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq)
 {
-	struct ieee80211_channel *chan;
-	int f;
-
 	/*
-	 * Parse frequency - return NULL for auto and
+	 * Parse frequency - return 0 for auto and
 	 * -EINVAL for impossible things.
 	 */
 	if (freq->e == 0) {
 		if (freq->m < 0)
-			return NULL;
-		f = ieee80211_channel_to_frequency(freq->m);
+			return 0;
+		return ieee80211_channel_to_frequency(freq->m);
 	} else {
 		int i, div = 1000000;
 		for (i = 0; i < freq->e; i++)
 			div /= 10;
 		if (div <= 0)
-			return ERR_PTR(-EINVAL);
-		f = freq->m / div;
+			return -EINVAL;
+		return freq->m / div;
 	}
-
-	/*
-	 * Look up channel struct and return -EINVAL when
-	 * it cannot be found.
-	 */
-	chan = ieee80211_get_channel(wiphy, f);
-	if (!chan)
-		return ERR_PTR(-EINVAL);
-	return chan;
 }
-EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
 
 int cfg80211_wext_siwrts(struct net_device *dev,
 			 struct iw_request_info *info,
@@ -479,15 +430,32 @@ int cfg80211_wext_giwretry(struct net_device *dev,
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
 
-static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
-				   struct net_device *dev, const u8 *addr,
-				   bool remove, bool tx_key, int idx,
-				   struct key_params *params)
+static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
+				     struct net_device *dev, const u8 *addr,
+				     bool remove, bool tx_key, int idx,
+				     struct key_params *params)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	int err;
+	int err, i;
+
+	if (!wdev->wext.keys) {
+		wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
+					      GFP_KERNEL);
+		if (!wdev->wext.keys)
+			return -ENOMEM;
+		for (i = 0; i < 6; i++)
+			wdev->wext.keys->params[i].key =
+				wdev->wext.keys->data[i];
+	}
+
+	if (wdev->iftype != NL80211_IFTYPE_ADHOC &&
+	    wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
 
 	if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+		if (!wdev->current_bss)
+			return -ENOLINK;
+
 		if (!rdev->ops->set_default_mgmt_key)
 			return -EOPNOTSUPP;
 
@@ -497,8 +465,14 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
 		return -EINVAL;
 
 	if (remove) {
-		err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
+		err = 0;
+		if (wdev->current_bss)
+			err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
 		if (!err) {
+			if (!addr) {
+				wdev->wext.keys->params[idx].key_len = 0;
+				wdev->wext.keys->params[idx].cipher = 0;
+			}
 			if (idx == wdev->wext.default_key)
 				wdev->wext.default_key = -1;
 			else if (idx == wdev->wext.default_mgmt_key)
@@ -512,36 +486,65 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
 			return 0;
 
 		return err;
-	} else {
-		if (addr)
-			tx_key = false;
+	}
 
-		if (cfg80211_validate_key_settings(params, idx, addr))
-			return -EINVAL;
+	if (addr)
+		tx_key = false;
 
+	if (cfg80211_validate_key_settings(rdev, params, idx, addr))
+		return -EINVAL;
+
+	err = 0;
+	if (wdev->current_bss)
 		err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params);
-		if (err)
-			return err;
+	if (err)
+		return err;
+
+	if (!addr) {
+		wdev->wext.keys->params[idx] = *params;
+		memcpy(wdev->wext.keys->data[idx],
+			params->key, params->key_len);
+		wdev->wext.keys->params[idx].key =
+			wdev->wext.keys->data[idx];
+	}
 
-		if (tx_key || (!addr && wdev->wext.default_key == -1)) {
+	if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+	     params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
+	    (tx_key || (!addr && wdev->wext.default_key == -1))) {
+		if (wdev->current_bss)
 			err = rdev->ops->set_default_key(&rdev->wiphy,
 							 dev, idx);
-			if (!err)
-				wdev->wext.default_key = idx;
-			return err;
-		}
+		if (!err)
+			wdev->wext.default_key = idx;
+		return err;
+	}
 
-		if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
-		    (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
+	if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
+	    (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
+		if (wdev->current_bss)
 			err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
 							      dev, idx);
-			if (!err)
-				wdev->wext.default_mgmt_key = idx;
-			return err;
-		}
-
-		return 0;
+		if (!err)
+			wdev->wext.default_mgmt_key = idx;
+		return err;
 	}
+
+	return 0;
+}
+
+static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
+				   struct net_device *dev, const u8 *addr,
+				   bool remove, bool tx_key, int idx,
+				   struct key_params *params)
+{
+	int err;
+
+	wdev_lock(dev->ieee80211_ptr);
+	err = __cfg80211_set_encryption(rdev, dev, addr, remove,
+					tx_key, idx, params);
+	wdev_unlock(dev->ieee80211_ptr);
+
+	return err;
 }
 
 int cfg80211_wext_siwencode(struct net_device *dev,
@@ -554,6 +557,10 @@ int cfg80211_wext_siwencode(struct net_device *dev,
 	bool remove = false;
 	struct key_params params;
 
+	if (wdev->iftype != NL80211_IFTYPE_STATION &&
+	    wdev->iftype != NL80211_IFTYPE_ADHOC)
+		return -EOPNOTSUPP;
+
 	/* no use -- only MFP (set_default_mgmt_key) is optional */
 	if (!rdev->ops->del_key ||
 	    !rdev->ops->add_key ||
@@ -574,9 +581,14 @@ int cfg80211_wext_siwencode(struct net_device *dev,
 		remove = true;
 	else if (erq->length == 0) {
 		/* No key data - just set the default TX key index */
-		err = rdev->ops->set_default_key(&rdev->wiphy, dev, idx);
+		err = 0;
+		wdev_lock(wdev);
+		if (wdev->current_bss)
+			err = rdev->ops->set_default_key(&rdev->wiphy,
+							 dev, idx);
 		if (!err)
 			wdev->wext.default_key = idx;
+		wdev_unlock(wdev);
 		return err;
 	}
 
@@ -609,6 +621,10 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
 	struct key_params params;
 	u32 cipher;
 
+	if (wdev->iftype != NL80211_IFTYPE_STATION &&
+	    wdev->iftype != NL80211_IFTYPE_ADHOC)
+		return -EOPNOTSUPP;
+
 	/* no use -- only MFP (set_default_mgmt_key) is optional */
 	if (!rdev->ops->del_key ||
 	    !rdev->ops->add_key ||
@@ -682,37 +698,15 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
 
-struct giwencode_cookie {
-	size_t buflen;
-	char *keybuf;
-};
-
-static void giwencode_get_key_cb(void *cookie, struct key_params *params)
-{
-	struct giwencode_cookie *data = cookie;
-
-	if (!params->key) {
-		data->buflen = 0;
-		return;
-	}
-
-	data->buflen = min_t(size_t, data->buflen, params->key_len);
-	memcpy(data->keybuf, params->key, data->buflen);
-}
-
 int cfg80211_wext_giwencode(struct net_device *dev,
 			    struct iw_request_info *info,
 			    struct iw_point *erq, char *keybuf)
 {
 	struct wireless_dev *wdev = dev->ieee80211_ptr;
-	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
-	int idx, err;
-	struct giwencode_cookie data = {
-		.keybuf = keybuf,
-		.buflen = erq->length,
-	};
+	int idx;
 
-	if (!rdev->ops->get_key)
+	if (wdev->iftype != NL80211_IFTYPE_STATION &&
+	    wdev->iftype != NL80211_IFTYPE_ADHOC)
 		return -EOPNOTSUPP;
 
 	idx = erq->flags & IW_ENCODE_INDEX;
@@ -727,24 +721,70 @@ int cfg80211_wext_giwencode(struct net_device *dev,
 
 	erq->flags = idx + 1;
 
-	err = rdev->ops->get_key(&rdev->wiphy, dev, idx, NULL, &data,
-				 giwencode_get_key_cb);
-	if (!err) {
-		erq->length = data.buflen;
-		erq->flags |= IW_ENCODE_ENABLED;
-		return 0;
-	}
-
-	if (err == -ENOENT) {
+	if (!wdev->wext.keys || !wdev->wext.keys->params[idx].cipher) {
 		erq->flags |= IW_ENCODE_DISABLED;
 		erq->length = 0;
 		return 0;
 	}
 
-	return err;
+	erq->length = min_t(size_t, erq->length,
+			    wdev->wext.keys->params[idx].key_len);
+	memcpy(keybuf, wdev->wext.keys->params[idx].key, erq->length);
+	erq->flags |= IW_ENCODE_ENABLED;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
 
+int cfg80211_wext_siwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *wextfreq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	int freq, err;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_siwfreq(dev, info, wextfreq, extra);
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_siwfreq(dev, info, wextfreq, extra);
+	default:
+		freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
+		if (freq < 0)
+			return freq;
+		if (freq == 0)
+			return -EINVAL;
+		mutex_lock(&rdev->devlist_mtx);
+		err = rdev_set_freq(rdev, NULL, freq, NL80211_CHAN_NO_HT);
+		mutex_unlock(&rdev->devlist_mtx);
+		return err;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
+
+int cfg80211_wext_giwfreq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *freq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+	default:
+		if (!rdev->channel)
+			return -EINVAL;
+		freq->m = rdev->channel->center_freq;
+		freq->e = 6;
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
+
 int cfg80211_wext_siwtxpower(struct net_device *dev,
 			     struct iw_request_info *info,
 			     union iwreq_data *data, char *extra)
@@ -827,3 +867,547 @@ int cfg80211_wext_giwtxpower(struct net_device *dev,
 	return 0;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);
+
+static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
+				 s32 auth_alg)
+{
+	int nr_alg = 0;
+
+	if (!auth_alg)
+		return -EINVAL;
+
+	if (auth_alg & ~(IW_AUTH_ALG_OPEN_SYSTEM |
+			 IW_AUTH_ALG_SHARED_KEY |
+			 IW_AUTH_ALG_LEAP))
+		return -EINVAL;
+
+	if (auth_alg & IW_AUTH_ALG_OPEN_SYSTEM) {
+		nr_alg++;
+		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+	}
+
+	if (auth_alg & IW_AUTH_ALG_SHARED_KEY) {
+		nr_alg++;
+		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_SHARED_KEY;
+	}
+
+	if (auth_alg & IW_AUTH_ALG_LEAP) {
+		nr_alg++;
+		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_NETWORK_EAP;
+	}
+
+	if (nr_alg > 1)
+		wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
+
+	return 0;
+}
+
+static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
+{
+	wdev->wext.connect.crypto.wpa_versions = 0;
+
+	if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
+			     IW_AUTH_WPA_VERSION_WPA2|
+		             IW_AUTH_WPA_VERSION_DISABLED))
+		return -EINVAL;
+
+	if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) &&
+	    (wpa_versions & (IW_AUTH_WPA_VERSION_WPA|
+			     IW_AUTH_WPA_VERSION_WPA2)))
+		return -EINVAL;
+
+	if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED)
+		wdev->wext.connect.crypto.wpa_versions &=
+			~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2);
+
+	if (wpa_versions & IW_AUTH_WPA_VERSION_WPA)
+		wdev->wext.connect.crypto.wpa_versions |=
+			NL80211_WPA_VERSION_1;
+
+	if (wpa_versions & IW_AUTH_WPA_VERSION_WPA2)
+		wdev->wext.connect.crypto.wpa_versions |=
+			NL80211_WPA_VERSION_2;
+
+	return 0;
+}
+
+static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
+{
+	wdev->wext.connect.crypto.cipher_group = 0;
+
+	if (cipher & IW_AUTH_CIPHER_WEP40)
+		wdev->wext.connect.crypto.cipher_group =
+			WLAN_CIPHER_SUITE_WEP40;
+	else if (cipher & IW_AUTH_CIPHER_WEP104)
+		wdev->wext.connect.crypto.cipher_group =
+			WLAN_CIPHER_SUITE_WEP104;
+	else if (cipher & IW_AUTH_CIPHER_TKIP)
+		wdev->wext.connect.crypto.cipher_group =
+			WLAN_CIPHER_SUITE_TKIP;
+	else if (cipher & IW_AUTH_CIPHER_CCMP)
+		wdev->wext.connect.crypto.cipher_group =
+			WLAN_CIPHER_SUITE_CCMP;
+	else if (cipher & IW_AUTH_CIPHER_AES_CMAC)
+		wdev->wext.connect.crypto.cipher_group =
+			WLAN_CIPHER_SUITE_AES_CMAC;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int cfg80211_set_cipher_pairwise(struct wireless_dev *wdev, u32 cipher)
+{
+	int nr_ciphers = 0;
+	u32 *ciphers_pairwise = wdev->wext.connect.crypto.ciphers_pairwise;
+
+	if (cipher & IW_AUTH_CIPHER_WEP40) {
+		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP40;
+		nr_ciphers++;
+	}
+
+	if (cipher & IW_AUTH_CIPHER_WEP104) {
+		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_WEP104;
+		nr_ciphers++;
+	}
+
+	if (cipher & IW_AUTH_CIPHER_TKIP) {
+		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_TKIP;
+		nr_ciphers++;
+	}
+
+	if (cipher & IW_AUTH_CIPHER_CCMP) {
+		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_CCMP;
+		nr_ciphers++;
+	}
+
+	if (cipher & IW_AUTH_CIPHER_AES_CMAC) {
+		ciphers_pairwise[nr_ciphers] = WLAN_CIPHER_SUITE_AES_CMAC;
+		nr_ciphers++;
+	}
+
+	BUILD_BUG_ON(NL80211_MAX_NR_CIPHER_SUITES < 5);
+
+	wdev->wext.connect.crypto.n_ciphers_pairwise = nr_ciphers;
+
+	return 0;
+}
+
+
+static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
+{
+	int nr_akm_suites = 0;
+
+	if (key_mgt & ~(IW_AUTH_KEY_MGMT_802_1X |
+			IW_AUTH_KEY_MGMT_PSK))
+		return -EINVAL;
+
+	if (key_mgt & IW_AUTH_KEY_MGMT_802_1X) {
+		wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
+			WLAN_AKM_SUITE_8021X;
+		nr_akm_suites++;
+	}
+
+	if (key_mgt & IW_AUTH_KEY_MGMT_PSK) {
+		wdev->wext.connect.crypto.akm_suites[nr_akm_suites] =
+			WLAN_AKM_SUITE_PSK;
+		nr_akm_suites++;
+	}
+
+	wdev->wext.connect.crypto.n_akm_suites = nr_akm_suites;
+
+	return 0;
+}
+
+int cfg80211_wext_siwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	switch (data->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_PRIVACY_INVOKED:
+		wdev->wext.connect.privacy = data->value;
+		return 0;
+	case IW_AUTH_WPA_VERSION:
+		return cfg80211_set_wpa_version(wdev, data->value);
+	case IW_AUTH_CIPHER_GROUP:
+		return cfg80211_set_cipher_group(wdev, data->value);
+	case IW_AUTH_KEY_MGMT:
+		return cfg80211_set_key_mgt(wdev, data->value);
+	case IW_AUTH_CIPHER_PAIRWISE:
+		return cfg80211_set_cipher_pairwise(wdev, data->value);
+	case IW_AUTH_80211_AUTH_ALG:
+		return cfg80211_set_auth_alg(wdev, data->value);
+	case IW_AUTH_WPA_ENABLED:
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+	case IW_AUTH_DROP_UNENCRYPTED:
+	case IW_AUTH_MFP:
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth);
+
+int cfg80211_wext_giwauth(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *data, char *extra)
+{
+	/* XXX: what do we need? */
+
+	return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
+
+int cfg80211_wext_siwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	bool ps = wdev->wext.ps;
+	int timeout = wdev->wext.ps_timeout;
+	int err;
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EINVAL;
+
+	if (!rdev->ops->set_power_mgmt)
+		return -EOPNOTSUPP;
+
+	if (wrq->disabled) {
+		ps = false;
+	} else {
+		switch (wrq->flags & IW_POWER_MODE) {
+		case IW_POWER_ON:       /* If not specified */
+		case IW_POWER_MODE:     /* If set all mask */
+		case IW_POWER_ALL_R:    /* If explicitely state all */
+			ps = true;
+			break;
+		default:                /* Otherwise we ignore */
+			return -EINVAL;
+		}
+
+		if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT))
+			return -EINVAL;
+
+		if (wrq->flags & IW_POWER_TIMEOUT)
+			timeout = wrq->value / 1000;
+	}
+
+	err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout);
+	if (err)
+		return err;
+
+	wdev->wext.ps = ps;
+	wdev->wext.ps_timeout = timeout;
+
+	return 0;
+
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
+
+int cfg80211_wext_giwpower(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *wrq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	wrq->disabled = !wdev->wext.ps;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
+
+static int cfg80211_wds_wext_siwap(struct net_device *dev,
+				   struct iw_request_info *info,
+				   struct sockaddr *addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	int err;
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
+		return -EINVAL;
+
+	if (addr->sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+
+	if (netif_running(dev))
+		return -EBUSY;
+
+	if (!rdev->ops->set_wds_peer)
+		return -EOPNOTSUPP;
+
+	err = rdev->ops->set_wds_peer(wdev->wiphy, dev, (u8 *) &addr->sa_data);
+	if (err)
+		return err;
+
+	memcpy(&wdev->wext.bssid, (u8 *) &addr->sa_data, ETH_ALEN);
+
+	return 0;
+}
+
+static int cfg80211_wds_wext_giwap(struct net_device *dev,
+				   struct iw_request_info *info,
+				   struct sockaddr *addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
+		return -EINVAL;
+
+	addr->sa_family = ARPHRD_ETHER;
+	memcpy(&addr->sa_data, wdev->wext.bssid, ETH_ALEN);
+
+	return 0;
+}
+
+int cfg80211_wext_siwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct cfg80211_bitrate_mask mask;
+
+	if (!rdev->ops->set_bitrate_mask)
+		return -EOPNOTSUPP;
+
+	mask.fixed = 0;
+	mask.maxrate = 0;
+
+	if (rate->value < 0) {
+		/* nothing */
+	} else if (rate->fixed) {
+		mask.fixed = rate->value / 1000; /* kbps */
+	} else {
+		mask.maxrate = rate->value / 1000; /* kbps */
+	}
+
+	return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask);
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);
+
+int cfg80211_wext_giwrate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *rate, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	/* we are under RTNL - globally locked - so can use a static struct */
+	static struct station_info sinfo;
+	u8 addr[ETH_ALEN];
+	int err;
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	if (!rdev->ops->get_station)
+		return -EOPNOTSUPP;
+
+	err = 0;
+	wdev_lock(wdev);
+	if (wdev->current_bss)
+		memcpy(addr, wdev->current_bss->pub.bssid, ETH_ALEN);
+	else
+		err = -EOPNOTSUPP;
+	wdev_unlock(wdev);
+	if (err)
+		return err;
+
+	err = rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo);
+	if (err)
+		return err;
+
+	if (!(sinfo.filled & STATION_INFO_TX_BITRATE))
+		return -EOPNOTSUPP;
+
+	rate->value = 0;
+
+	if (!(sinfo.txrate.flags & RATE_INFO_FLAGS_MCS))
+		rate->value = 100000 * sinfo.txrate.legacy;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate);
+
+/* Get wireless statistics.  Called by /proc/net/wireless and by SIOCGIWSTATS */
+struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	/* we are under RTNL - globally locked - so can use static structs */
+	static struct iw_statistics wstats;
+	static struct station_info sinfo;
+	u8 bssid[ETH_ALEN];
+
+	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
+		return NULL;
+
+	if (!rdev->ops->get_station)
+		return NULL;
+
+	/* Grab BSSID of current BSS, if any */
+	wdev_lock(wdev);
+	if (!wdev->current_bss) {
+		wdev_unlock(wdev);
+		return NULL;
+	}
+	memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
+	wdev_unlock(wdev);
+
+	if (rdev->ops->get_station(&rdev->wiphy, dev, bssid, &sinfo))
+		return NULL;
+
+	memset(&wstats, 0, sizeof(wstats));
+
+	switch (rdev->wiphy.signal_type) {
+	case CFG80211_SIGNAL_TYPE_MBM:
+		if (sinfo.filled & STATION_INFO_SIGNAL) {
+			int sig = sinfo.signal;
+			wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
+			wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
+			wstats.qual.updated |= IW_QUAL_DBM;
+			wstats.qual.level = sig;
+			if (sig < -110)
+				sig = -110;
+			else if (sig > -40)
+				sig = -40;
+			wstats.qual.qual = sig + 110;
+			break;
+		}
+	case CFG80211_SIGNAL_TYPE_UNSPEC:
+		if (sinfo.filled & STATION_INFO_SIGNAL) {
+			wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
+			wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
+			wstats.qual.level = sinfo.signal;
+			wstats.qual.qual = sinfo.signal;
+			break;
+		}
+	default:
+		wstats.qual.updated |= IW_QUAL_LEVEL_INVALID;
+		wstats.qual.updated |= IW_QUAL_QUAL_INVALID;
+	}
+
+	wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
+
+	return &wstats;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
+
+int cfg80211_wext_siwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_WDS:
+		return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
+
+int cfg80211_wext_giwap(struct net_device *dev,
+			struct iw_request_info *info,
+			struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
+	case NL80211_IFTYPE_WDS:
+		return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
+
+int cfg80211_wext_siwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
+
+int cfg80211_wext_giwessid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	switch (wdev->iftype) {
+	case NL80211_IFTYPE_ADHOC:
+		return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+	case NL80211_IFTYPE_STATION:
+		return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
+
+static const iw_handler cfg80211_handlers[] = {
+	[IW_IOCTL_IDX(SIOCGIWNAME)]	= (iw_handler) cfg80211_wext_giwname,
+	[IW_IOCTL_IDX(SIOCSIWFREQ)]	= (iw_handler) cfg80211_wext_siwfreq,
+	[IW_IOCTL_IDX(SIOCGIWFREQ)]	= (iw_handler) cfg80211_wext_giwfreq,
+	[IW_IOCTL_IDX(SIOCSIWMODE)]	= (iw_handler) cfg80211_wext_siwmode,
+	[IW_IOCTL_IDX(SIOCGIWMODE)]	= (iw_handler) cfg80211_wext_giwmode,
+	[IW_IOCTL_IDX(SIOCGIWRANGE)]	= (iw_handler) cfg80211_wext_giwrange,
+	[IW_IOCTL_IDX(SIOCSIWAP)]	= (iw_handler) cfg80211_wext_siwap,
+	[IW_IOCTL_IDX(SIOCGIWAP)]	= (iw_handler) cfg80211_wext_giwap,
+	[IW_IOCTL_IDX(SIOCSIWMLME)]	= (iw_handler) cfg80211_wext_siwmlme,
+	[IW_IOCTL_IDX(SIOCSIWSCAN)]	= (iw_handler) cfg80211_wext_siwscan,
+	[IW_IOCTL_IDX(SIOCGIWSCAN)]	= (iw_handler) cfg80211_wext_giwscan,
+	[IW_IOCTL_IDX(SIOCSIWESSID)]	= (iw_handler) cfg80211_wext_siwessid,
+	[IW_IOCTL_IDX(SIOCGIWESSID)]	= (iw_handler) cfg80211_wext_giwessid,
+	[IW_IOCTL_IDX(SIOCSIWRATE)]	= (iw_handler) cfg80211_wext_siwrate,
+	[IW_IOCTL_IDX(SIOCGIWRATE)]	= (iw_handler) cfg80211_wext_giwrate,
+	[IW_IOCTL_IDX(SIOCSIWRTS)]	= (iw_handler) cfg80211_wext_siwrts,
+	[IW_IOCTL_IDX(SIOCGIWRTS)]	= (iw_handler) cfg80211_wext_giwrts,
+	[IW_IOCTL_IDX(SIOCSIWFRAG)]	= (iw_handler) cfg80211_wext_siwfrag,
+	[IW_IOCTL_IDX(SIOCGIWFRAG)]	= (iw_handler) cfg80211_wext_giwfrag,
+	[IW_IOCTL_IDX(SIOCSIWTXPOW)]	= (iw_handler) cfg80211_wext_siwtxpower,
+	[IW_IOCTL_IDX(SIOCGIWTXPOW)]	= (iw_handler) cfg80211_wext_giwtxpower,
+	[IW_IOCTL_IDX(SIOCSIWRETRY)]	= (iw_handler) cfg80211_wext_siwretry,
+	[IW_IOCTL_IDX(SIOCGIWRETRY)]	= (iw_handler) cfg80211_wext_giwretry,
+	[IW_IOCTL_IDX(SIOCSIWENCODE)]	= (iw_handler) cfg80211_wext_siwencode,
+	[IW_IOCTL_IDX(SIOCGIWENCODE)]	= (iw_handler) cfg80211_wext_giwencode,
+	[IW_IOCTL_IDX(SIOCSIWPOWER)]	= (iw_handler) cfg80211_wext_siwpower,
+	[IW_IOCTL_IDX(SIOCGIWPOWER)]	= (iw_handler) cfg80211_wext_giwpower,
+	[IW_IOCTL_IDX(SIOCSIWGENIE)]	= (iw_handler) cfg80211_wext_siwgenie,
+	[IW_IOCTL_IDX(SIOCSIWAUTH)]	= (iw_handler) cfg80211_wext_siwauth,
+	[IW_IOCTL_IDX(SIOCGIWAUTH)]	= (iw_handler) cfg80211_wext_giwauth,
+	[IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext,
+};
+
+const struct iw_handler_def cfg80211_wext_handler = {
+	.num_standard		= ARRAY_SIZE(cfg80211_handlers),
+	.standard		= cfg80211_handlers,
+	.get_wireless_stats = cfg80211_wireless_stats,
+};
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h
new file mode 100644
index 0000000..20b3dae
--- /dev/null
+++ b/net/wireless/wext-compat.h
@@ -0,0 +1,49 @@
+#ifndef __WEXT_COMPAT
+#define __WEXT_COMPAT
+
+#include <net/iw_handler.h>
+#include <linux/wireless.h>
+
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+			     struct iw_request_info *info,
+			     struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+			     struct iw_request_info *info,
+			     struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+				struct iw_request_info *info,
+				struct iw_point *data, char *ssid);
+
+int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra);
+int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra);
+int cfg80211_mgd_wext_siwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra);
+int cfg80211_mgd_wext_giwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra);
+int cfg80211_mgd_wext_siwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid);
+int cfg80211_mgd_wext_giwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid);
+
+int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq);
+
+
+extern const struct iw_handler_def cfg80211_wext_handler;
+#endif /* __WEXT_COMPAT */
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
new file mode 100644
index 0000000..d16cd9e
--- /dev/null
+++ b/net/wireless/wext-sme.c
@@ -0,0 +1,404 @@
+/*
+ * cfg80211 wext compat for managed mode.
+ *
+ * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
+ * Copyright (C) 2009   Intel Corporation. All rights reserved.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <net/cfg80211.h>
+#include "wext-compat.h"
+#include "nl80211.h"
+
+int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
+			      struct wireless_dev *wdev)
+{
+	struct cfg80211_cached_keys *ck = NULL;
+	const u8 *prev_bssid = NULL;
+	int err, i;
+
+	ASSERT_RDEV_LOCK(rdev);
+	ASSERT_WDEV_LOCK(wdev);
+
+	if (!netif_running(wdev->netdev))
+		return 0;
+
+	wdev->wext.connect.ie = wdev->wext.ie;
+	wdev->wext.connect.ie_len = wdev->wext.ie_len;
+	wdev->wext.connect.privacy = wdev->wext.default_key != -1;
+
+	if (wdev->wext.keys) {
+		wdev->wext.keys->def = wdev->wext.default_key;
+		wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;
+	}
+
+	if (!wdev->wext.connect.ssid_len)
+		return 0;
+
+	if (wdev->wext.keys) {
+		ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
+		if (!ck)
+			return -ENOMEM;
+		for (i = 0; i < 6; i++)
+			ck->params[i].key = ck->data[i];
+	}
+
+	if (wdev->wext.prev_bssid_valid)
+		prev_bssid = wdev->wext.prev_bssid;
+
+	err = __cfg80211_connect(rdev, wdev->netdev,
+				 &wdev->wext.connect, ck, prev_bssid);
+	if (err)
+		kfree(ck);
+
+	return err;
+}
+
+int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *wextfreq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	struct ieee80211_channel *chan = NULL;
+	int err, freq;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	freq = cfg80211_wext_freq(wdev->wiphy, wextfreq);
+	if (freq < 0)
+		return freq;
+
+	if (freq) {
+		chan = ieee80211_get_channel(wdev->wiphy, freq);
+		if (!chan)
+			return -EINVAL;
+		if (chan->flags & IEEE80211_CHAN_DISABLED)
+			return -EINVAL;
+	}
+
+	cfg80211_lock_rdev(rdev);
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(wdev);
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		bool event = true;
+
+		if (wdev->wext.connect.channel == chan) {
+			err = 0;
+			goto out;
+		}
+
+		/* if SSID set, we'll try right again, avoid event */
+		if (wdev->wext.connect.ssid_len)
+			event = false;
+		err = __cfg80211_disconnect(rdev, dev,
+					    WLAN_REASON_DEAUTH_LEAVING, event);
+		if (err)
+			goto out;
+	}
+
+
+	wdev->wext.connect.channel = chan;
+
+	/* SSID is not set, we just want to switch channel */
+	if (chan && !wdev->wext.connect.ssid_len) {
+		err = rdev_set_freq(rdev, wdev, freq, NL80211_CHAN_NO_HT);
+		goto out;
+	}
+
+	err = cfg80211_mgd_wext_connect(rdev, wdev);
+ out:
+	wdev_unlock(wdev);
+	mutex_unlock(&rdev->devlist_mtx);
+	cfg80211_unlock_rdev(rdev);
+	return err;
+}
+
+int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_freq *freq, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct ieee80211_channel *chan = NULL;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	wdev_lock(wdev);
+	if (wdev->current_bss)
+		chan = wdev->current_bss->pub.channel;
+	else if (wdev->wext.connect.channel)
+		chan = wdev->wext.connect.channel;
+	wdev_unlock(wdev);
+
+	if (chan) {
+		freq->m = chan->center_freq;
+		freq->e = 6;
+		return 0;
+	}
+
+	/* no channel if not joining */
+	return -EINVAL;
+}
+
+int cfg80211_mgd_wext_siwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	size_t len = data->length;
+	int err;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	if (!data->flags)
+		len = 0;
+
+	/* iwconfig uses nul termination in SSID.. */
+	if (len > 0 && ssid[len - 1] == '\0')
+		len--;
+
+	cfg80211_lock_rdev(rdev);
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(wdev);
+
+	err = 0;
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		bool event = true;
+
+		if (wdev->wext.connect.ssid && len &&
+		    len == wdev->wext.connect.ssid_len &&
+		    memcmp(wdev->wext.connect.ssid, ssid, len) == 0)
+			goto out;
+
+		/* if SSID set now, we'll try to connect, avoid event */
+		if (len)
+			event = false;
+		err = __cfg80211_disconnect(rdev, dev,
+					    WLAN_REASON_DEAUTH_LEAVING, event);
+		if (err)
+			goto out;
+	}
+
+	wdev->wext.prev_bssid_valid = false;
+	wdev->wext.connect.ssid = wdev->wext.ssid;
+	memcpy(wdev->wext.ssid, ssid, len);
+	wdev->wext.connect.ssid_len = len;
+
+	wdev->wext.connect.crypto.control_port = false;
+
+	err = cfg80211_mgd_wext_connect(rdev, wdev);
+ out:
+	wdev_unlock(wdev);
+	mutex_unlock(&rdev->devlist_mtx);
+	cfg80211_unlock_rdev(rdev);
+	return err;
+}
+
+int cfg80211_mgd_wext_giwessid(struct net_device *dev,
+			       struct iw_request_info *info,
+			       struct iw_point *data, char *ssid)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	data->flags = 0;
+
+	wdev_lock(wdev);
+	if (wdev->current_bss) {
+		const u8 *ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
+						    WLAN_EID_SSID);
+		if (ie) {
+			data->flags = 1;
+			data->length = ie[1];
+			memcpy(ssid, ie + 2, data->length);
+		}
+	} else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) {
+		data->flags = 1;
+		data->length = wdev->wext.connect.ssid_len;
+		memcpy(ssid, wdev->wext.connect.ssid, data->length);
+	} else
+		data->flags = 0;
+	wdev_unlock(wdev);
+
+	return 0;
+}
+
+int cfg80211_mgd_wext_siwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	u8 *bssid = ap_addr->sa_data;
+	int err;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	if (ap_addr->sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+
+	/* automatic mode */
+	if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
+		bssid = NULL;
+
+	cfg80211_lock_rdev(rdev);
+	mutex_lock(&rdev->devlist_mtx);
+	wdev_lock(wdev);
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		err = 0;
+		/* both automatic */
+		if (!bssid && !wdev->wext.connect.bssid)
+			goto out;
+
+		/* fixed already - and no change */
+		if (wdev->wext.connect.bssid && bssid &&
+		    compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0)
+			goto out;
+
+		err = __cfg80211_disconnect(rdev, dev,
+					    WLAN_REASON_DEAUTH_LEAVING, false);
+		if (err)
+			goto out;
+	}
+
+	if (bssid) {
+		memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
+		wdev->wext.connect.bssid = wdev->wext.bssid;
+	} else
+		wdev->wext.connect.bssid = NULL;
+
+	err = cfg80211_mgd_wext_connect(rdev, wdev);
+ out:
+	wdev_unlock(wdev);
+	mutex_unlock(&rdev->devlist_mtx);
+	cfg80211_unlock_rdev(rdev);
+	return err;
+}
+
+int cfg80211_mgd_wext_giwap(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct sockaddr *ap_addr, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+	/* call only for station! */
+	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
+		return -EINVAL;
+
+	ap_addr->sa_family = ARPHRD_ETHER;
+
+	wdev_lock(wdev);
+	if (wdev->current_bss)
+		memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN);
+	else if (wdev->wext.connect.bssid)
+		memcpy(ap_addr->sa_data, wdev->wext.connect.bssid, ETH_ALEN);
+	else
+		memset(ap_addr->sa_data, 0, ETH_ALEN);
+	wdev_unlock(wdev);
+
+	return 0;
+}
+
+int cfg80211_wext_siwgenie(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *data, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+	u8 *ie = extra;
+	int ie_len = data->length, err;
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EOPNOTSUPP;
+
+	if (!ie_len)
+		ie = NULL;
+
+	wdev_lock(wdev);
+
+	/* no change */
+	err = 0;
+	if (wdev->wext.ie_len == ie_len &&
+	    memcmp(wdev->wext.ie, ie, ie_len) == 0)
+		goto out;
+
+	if (ie_len) {
+		ie = kmemdup(extra, ie_len, GFP_KERNEL);
+		if (!ie) {
+			err = -ENOMEM;
+			goto out;
+		}
+	} else
+		ie = NULL;
+
+	kfree(wdev->wext.ie);
+	wdev->wext.ie = ie;
+	wdev->wext.ie_len = ie_len;
+
+	if (wdev->sme_state != CFG80211_SME_IDLE) {
+		err = __cfg80211_disconnect(rdev, dev,
+					    WLAN_REASON_DEAUTH_LEAVING, false);
+		if (err)
+			goto out;
+	}
+
+	/* userspace better not think we'll reconnect */
+	err = 0;
+ out:
+	wdev_unlock(wdev);
+	return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie);
+
+int cfg80211_wext_siwmlme(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *data, char *extra)
+{
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	struct iw_mlme *mlme = (struct iw_mlme *)extra;
+	struct cfg80211_registered_device *rdev;
+	int err;
+
+	if (!wdev)
+		return -EOPNOTSUPP;
+
+	rdev = wiphy_to_dev(wdev->wiphy);
+
+	if (wdev->iftype != NL80211_IFTYPE_STATION)
+		return -EINVAL;
+
+	if (mlme->addr.sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+
+	wdev_lock(wdev);
+	switch (mlme->cmd) {
+	case IW_MLME_DEAUTH:
+	case IW_MLME_DISASSOC:
+		err = __cfg80211_disconnect(rdev, dev, mlme->reason_code,
+					    true);
+		break;
+	default:
+		err = -EOPNOTSUPP;
+		break;
+	}
+	wdev_unlock(wdev);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index 252c201..5b4a0ce 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -417,6 +417,21 @@ static const int event_type_size[] = {
 	IW_EV_QUAL_LEN,			/* IW_HEADER_TYPE_QUAL */
 };
 
+#ifdef CONFIG_COMPAT
+static const int compat_event_type_size[] = {
+	IW_EV_COMPAT_LCP_LEN,		/* IW_HEADER_TYPE_NULL */
+	0,
+	IW_EV_COMPAT_CHAR_LEN,		/* IW_HEADER_TYPE_CHAR */
+	0,
+	IW_EV_COMPAT_UINT_LEN,		/* IW_HEADER_TYPE_UINT */
+	IW_EV_COMPAT_FREQ_LEN,		/* IW_HEADER_TYPE_FREQ */
+	IW_EV_COMPAT_ADDR_LEN,		/* IW_HEADER_TYPE_ADDR */
+	0,
+	IW_EV_COMPAT_POINT_LEN,		/* Without variable payload */
+	IW_EV_COMPAT_PARAM_LEN,		/* IW_HEADER_TYPE_PARAM */
+	IW_EV_COMPAT_QUAL_LEN,		/* IW_HEADER_TYPE_QUAL */
+};
+#endif
 
 /************************ COMMON SUBROUTINES ************************/
 /*
@@ -610,6 +625,11 @@ static void wireless_seq_printf_stats(struct seq_file *seq,
 {
 	/* Get stats from the driver */
 	struct iw_statistics *stats = get_wireless_stats(dev);
+	static struct iw_statistics nullstats = {};
+
+	/* show device if it's wireless regardless of current stats */
+	if (!stats && dev->wireless_handlers)
+		stats = &nullstats;
 
 	if (stats) {
 		seq_printf(seq, "%6s: %04x  %3d%c  %3d%c  %3d%c  %6d %6d %6d "
@@ -628,7 +648,9 @@ static void wireless_seq_printf_stats(struct seq_file *seq,
 			   stats->discard.nwid, stats->discard.code,
 			   stats->discard.fragment, stats->discard.retries,
 			   stats->discard.misc, stats->miss.beacon);
-		stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
+
+		if (stats != &nullstats)
+			stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
 	}
 }
 
@@ -1250,65 +1272,57 @@ int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
 }
 #endif
 
-/************************* EVENT PROCESSING *************************/
-/*
- * Process events generated by the wireless layer or the driver.
- * Most often, the event will be propagated through rtnetlink
- */
+static int __net_init wext_pernet_init(struct net *net)
+{
+	skb_queue_head_init(&net->wext_nlevents);
+	return 0;
+}
 
-/* ---------------------------------------------------------------- */
-/*
- * Locking...
- * ----------
- *
- * Thanks to Herbert Xu <herbert@gondor.apana.org.au> for fixing
- * the locking issue in here and implementing this code !
- *
- * The issue : wireless_send_event() is often called in interrupt context,
- * while the Netlink layer can never be called in interrupt context.
- * The fully formed RtNetlink events are queued, and then a tasklet is run
- * to feed those to Netlink.
- * The skb_queue is interrupt safe, and its lock is not held while calling
- * Netlink, so there is no possibility of dealock.
- * Jean II
- */
+static void __net_exit wext_pernet_exit(struct net *net)
+{
+	skb_queue_purge(&net->wext_nlevents);
+}
 
-static struct sk_buff_head wireless_nlevent_queue;
+static struct pernet_operations wext_pernet_ops = {
+	.init = wext_pernet_init,
+	.exit = wext_pernet_exit,
+};
 
 static int __init wireless_nlevent_init(void)
 {
-	skb_queue_head_init(&wireless_nlevent_queue);
-	return 0;
+	return register_pernet_subsys(&wext_pernet_ops);
 }
 
 subsys_initcall(wireless_nlevent_init);
 
-static void wireless_nlevent_process(unsigned long data)
+/* Process events generated by the wireless layer or the driver. */
+static void wireless_nlevent_process(struct work_struct *work)
 {
 	struct sk_buff *skb;
+	struct net *net;
 
-	while ((skb = skb_dequeue(&wireless_nlevent_queue)))
-		rtnl_notify(skb, &init_net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+	rtnl_lock();
+
+	for_each_net(net) {
+		while ((skb = skb_dequeue(&net->wext_nlevents)))
+			rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
+				    GFP_KERNEL);
+	}
+
+	rtnl_unlock();
 }
 
-static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0);
+static DECLARE_WORK(wireless_nlevent_work, wireless_nlevent_process);
 
-/* ---------------------------------------------------------------- */
-/*
- * Fill a rtnetlink message with our event data.
- * Note that we propage only the specified event and don't dump the
- * current wireless config. Dumping the wireless config is far too
- * expensive (for each parameter, the driver need to query the hardware).
- */
-static int rtnetlink_fill_iwinfo(struct sk_buff *skb, struct net_device *dev,
-				 int type, char *event, int event_len)
+static struct nlmsghdr *rtnetlink_ifinfo_prep(struct net_device *dev,
+					      struct sk_buff *skb)
 {
 	struct ifinfomsg *r;
 	struct nlmsghdr  *nlh;
 
-	nlh = nlmsg_put(skb, 0, 0, type, sizeof(*r), 0);
-	if (nlh == NULL)
-		return -EMSGSIZE;
+	nlh = nlmsg_put(skb, 0, 0, RTM_NEWLINK, sizeof(*r), 0);
+	if (!nlh)
+		return NULL;
 
 	r = nlmsg_data(nlh);
 	r->ifi_family = AF_UNSPEC;
@@ -1319,48 +1333,14 @@ static int rtnetlink_fill_iwinfo(struct sk_buff *skb, struct net_device *dev,
 	r->ifi_change = 0;	/* Wireless changes don't affect those flags */
 
 	NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
-	/* Add the wireless events in the netlink packet */
-	NLA_PUT(skb, IFLA_WIRELESS, event_len, event);
 
-	return nlmsg_end(skb, nlh);
-
-nla_put_failure:
+	return nlh;
+ nla_put_failure:
 	nlmsg_cancel(skb, nlh);
-	return -EMSGSIZE;
+	return NULL;
 }
 
-/* ---------------------------------------------------------------- */
-/*
- * Create and broadcast and send it on the standard rtnetlink socket
- * This is a pure clone rtmsg_ifinfo() in net/core/rtnetlink.c
- * Andrzej Krzysztofowicz mandated that I used a IFLA_XXX field
- * within a RTM_NEWLINK event.
- */
-static void rtmsg_iwinfo(struct net_device *dev, char *event, int event_len)
-{
-	struct sk_buff *skb;
-	int err;
-
-	if (!net_eq(dev_net(dev), &init_net))
-		return;
-
-	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
-	if (!skb)
-		return;
 
-	err = rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK, event, event_len);
-	if (err < 0) {
-		WARN_ON(err == -EMSGSIZE);
-		kfree_skb(skb);
-		return;
-	}
-
-	NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
-	skb_queue_tail(&wireless_nlevent_queue, skb);
-	tasklet_schedule(&wireless_nlevent_tasklet);
-}
-
-/* ---------------------------------------------------------------- */
 /*
  * Main event dispatcher. Called from other parts and drivers.
  * Send the event on the appropriate channels.
@@ -1369,7 +1349,7 @@ static void rtmsg_iwinfo(struct net_device *dev, char *event, int event_len)
 void wireless_send_event(struct net_device *	dev,
 			 unsigned int		cmd,
 			 union iwreq_data *	wrqu,
-			 char *			extra)
+			 const char *		extra)
 {
 	const struct iw_ioctl_description *	descr = NULL;
 	int extra_len = 0;
@@ -1379,6 +1359,25 @@ void wireless_send_event(struct net_device *	dev,
 	int wrqu_off = 0;			/* Offset in wrqu */
 	/* Don't "optimise" the following variable, it will crash */
 	unsigned	cmd_index;		/* *MUST* be unsigned */
+	struct sk_buff *skb;
+	struct nlmsghdr *nlh;
+	struct nlattr *nla;
+#ifdef CONFIG_COMPAT
+	struct __compat_iw_event *compat_event;
+	struct compat_iw_point compat_wrqu;
+	struct sk_buff *compskb;
+#endif
+
+	/*
+	 * Nothing in the kernel sends scan events with data, be safe.
+	 * This is necessary because we cannot fix up scan event data
+	 * for compat, due to being contained in 'extra', but normally
+	 * applications are required to retrieve the scan data anyway
+	 * and no data is included in the event, this codifies that
+	 * practice.
+	 */
+	if (WARN_ON(cmd == SIOCGIWSCAN && extra))
+		extra = NULL;
 
 	/* Get the description of the Event */
 	if (cmd <= SIOCIWLAST) {
@@ -1426,25 +1425,107 @@ void wireless_send_event(struct net_device *	dev,
 	hdr_len = event_type_size[descr->header_type];
 	event_len = hdr_len + extra_len;
 
-	/* Create temporary buffer to hold the event */
-	event = kmalloc(event_len, GFP_ATOMIC);
-	if (event == NULL)
+	/*
+	 * The problem for 64/32 bit.
+	 *
+	 * On 64-bit, a regular event is laid out as follows:
+	 *      |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
+	 *      | event.len | event.cmd |     p a d d i n g     |
+	 *      | wrqu data ... (with the correct size)         |
+	 *
+	 * This padding exists because we manipulate event->u,
+	 * and 'event' is not packed.
+	 *
+	 * An iw_point event is laid out like this instead:
+	 *      |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
+	 *      | event.len | event.cmd |     p a d d i n g     |
+	 *      | iwpnt.len | iwpnt.flg |     p a d d i n g     |
+	 *      | extra data  ...
+	 *
+	 * The second padding exists because struct iw_point is extended,
+	 * but this depends on the platform...
+	 *
+	 * On 32-bit, all the padding shouldn't be there.
+	 */
+
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!skb)
+		return;
+
+	/* Send via the RtNetlink event channel */
+	nlh = rtnetlink_ifinfo_prep(dev, skb);
+	if (WARN_ON(!nlh)) {
+		kfree_skb(skb);
+		return;
+	}
+
+	/* Add the wireless events in the netlink packet */
+	nla = nla_reserve(skb, IFLA_WIRELESS, event_len);
+	if (!nla) {
+		kfree_skb(skb);
 		return;
+	}
+	event = nla_data(nla);
 
-	/* Fill event */
+	/* Fill event - first clear to avoid data leaking */
+	memset(event, 0, hdr_len);
 	event->len = event_len;
 	event->cmd = cmd;
 	memcpy(&event->u, ((char *) wrqu) + wrqu_off, hdr_len - IW_EV_LCP_LEN);
-	if (extra)
+	if (extra_len)
 		memcpy(((char *) event) + hdr_len, extra, extra_len);
 
+	nlmsg_end(skb, nlh);
+#ifdef CONFIG_COMPAT
+	hdr_len = compat_event_type_size[descr->header_type];
+	event_len = hdr_len + extra_len;
+
+	compskb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!compskb) {
+		kfree_skb(skb);
+		return;
+	}
+
 	/* Send via the RtNetlink event channel */
-	rtmsg_iwinfo(dev, (char *) event, event_len);
+	nlh = rtnetlink_ifinfo_prep(dev, compskb);
+	if (WARN_ON(!nlh)) {
+		kfree_skb(skb);
+		kfree_skb(compskb);
+		return;
+	}
 
-	/* Cleanup */
-	kfree(event);
+	/* Add the wireless events in the netlink packet */
+	nla = nla_reserve(compskb, IFLA_WIRELESS, event_len);
+	if (!nla) {
+		kfree_skb(skb);
+		kfree_skb(compskb);
+		return;
+	}
+	compat_event = nla_data(nla);
 
-	return;		/* Always success, I guess ;-) */
+	compat_event->len = event_len;
+	compat_event->cmd = cmd;
+	if (descr->header_type == IW_HEADER_TYPE_POINT) {
+		compat_wrqu.length = wrqu->data.length;
+		compat_wrqu.flags = wrqu->data.flags;
+		memcpy(&compat_event->pointer,
+			((char *) &compat_wrqu) + IW_EV_COMPAT_POINT_OFF,
+			hdr_len - IW_EV_COMPAT_LCP_LEN);
+		if (extra_len)
+			memcpy(((char *) compat_event) + hdr_len,
+				extra, extra_len);
+	} else {
+		/* extra_len must be zero, so no if (extra) needed */
+		memcpy(&compat_event->pointer, wrqu,
+			hdr_len - IW_EV_COMPAT_LCP_LEN);
+	}
+
+	nlmsg_end(compskb, nlh);
+
+	skb_shinfo(skb)->frag_list = compskb;
+#endif
+	skb_queue_tail(&dev_net(dev)->wext_nlevents, skb);
+	schedule_work(&wireless_nlevent_work);
 }
 EXPORT_SYMBOL(wireless_send_event);
 
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index a2adb51..fef8db5 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -60,7 +60,7 @@ static int xfrm_statistics_seq_open(struct inode *inode, struct file *file)
 	return single_open_net(inode, file, xfrm_statistics_seq_show);
 }
 
-static struct file_operations xfrm_statistics_seq_fops = {
+static const struct file_operations xfrm_statistics_seq_fops = {
 	.owner	 = THIS_MODULE,
 	.open	 = xfrm_statistics_seq_open,
 	.read	 = seq_read,
diff --git a/samples/Kconfig b/samples/Kconfig
index 428b065..b92bde3 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -7,12 +7,6 @@ menuconfig SAMPLES
 
 if SAMPLES
 
-config SAMPLE_MARKERS
-	tristate "Build markers examples -- loadable modules only"
-	depends on MARKERS && m
-	help
-	  This build markers example modules.
-
 config SAMPLE_TRACEPOINTS
 	tristate "Build tracepoints examples -- loadable modules only"
 	depends on TRACEPOINTS && m
diff --git a/samples/Makefile b/samples/Makefile
index 13e4b47..43343a0 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,3 +1,3 @@
 # Makefile for Linux samples code
 
-obj-$(CONFIG_SAMPLES)	+= markers/ kobject/ kprobes/ tracepoints/ trace_events/
+obj-$(CONFIG_SAMPLES)	+= kobject/ kprobes/ tracepoints/ trace_events/
diff --git a/samples/kprobes/kretprobe_example.c b/samples/kprobes/kretprobe_example.c
index 4e764b3..1041b67 100644
--- a/samples/kprobes/kretprobe_example.c
+++ b/samples/kprobes/kretprobe_example.c
@@ -23,6 +23,7 @@
 #include <linux/kprobes.h>
 #include <linux/ktime.h>
 #include <linux/limits.h>
+#include <linux/sched.h>
 
 static char func_name[NAME_MAX] = "do_fork";
 module_param_string(func, func_name, NAME_MAX, S_IRUGO);
diff --git a/samples/markers/Makefile b/samples/markers/Makefile
deleted file mode 100644
index 6d72312..0000000
--- a/samples/markers/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# builds the kprobes example kernel modules;
-# then to use one (as root):  insmod <module_name.ko>
-
-obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o
diff --git a/samples/markers/marker-example.c b/samples/markers/marker-example.c
deleted file mode 100644
index e9cd9c0..0000000
--- a/samples/markers/marker-example.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* marker-example.c
- *
- * Executes a marker when /proc/marker-example is opened.
- *
- * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
- *
- * This file is released under the GPLv2.
- * See the file COPYING for more details.
- */
-
-#include <linux/module.h>
-#include <linux/marker.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-
-struct proc_dir_entry *pentry_example;
-
-static int my_open(struct inode *inode, struct file *file)
-{
-	int i;
-
-	trace_mark(subsystem_event, "integer %d string %s", 123,
-		"example string");
-	for (i = 0; i < 10; i++)
-		trace_mark(subsystem_eventb, MARK_NOARGS);
-	return -EPERM;
-}
-
-static struct file_operations mark_ops = {
-	.open = my_open,
-};
-
-static int __init example_init(void)
-{
-	printk(KERN_ALERT "example init\n");
-	pentry_example = proc_create("marker-example", 0444, NULL, &mark_ops);
-	if (!pentry_example)
-		return -EPERM;
-	return 0;
-}
-
-static void __exit example_exit(void)
-{
-	printk(KERN_ALERT "example exit\n");
-	remove_proc_entry("marker-example", NULL);
-}
-
-module_init(example_init)
-module_exit(example_exit)
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mathieu Desnoyers");
-MODULE_DESCRIPTION("Marker example");
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c
deleted file mode 100644
index 2dfb3b3..0000000
--- a/samples/markers/probe-example.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* probe-example.c
- *
- * Connects two functions to marker call sites.
- *
- * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
- *
- * This file is released under the GPLv2.
- * See the file COPYING for more details.
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/marker.h>
-#include <asm/atomic.h>
-
-struct probe_data {
-	const char *name;
-	const char *format;
-	marker_probe_func *probe_func;
-};
-
-void probe_subsystem_event(void *probe_data, void *call_data,
-	const char *format, va_list *args)
-{
-	/* Declare args */
-	unsigned int value;
-	const char *mystr;
-
-	/* Assign args */
-	value = va_arg(*args, typeof(value));
-	mystr = va_arg(*args, typeof(mystr));
-
-	/* Call printk */
-	printk(KERN_INFO "Value %u, string %s\n", value, mystr);
-
-	/* or count, check rights, serialize data in a buffer */
-}
-
-atomic_t eventb_count = ATOMIC_INIT(0);
-
-void probe_subsystem_eventb(void *probe_data, void *call_data,
-	const char *format, va_list *args)
-{
-	/* Increment counter */
-	atomic_inc(&eventb_count);
-}
-
-static struct probe_data probe_array[] =
-{
-	{	.name = "subsystem_event",
-		.format = "integer %d string %s",
-		.probe_func = probe_subsystem_event },
-	{	.name = "subsystem_eventb",
-		.format = MARK_NOARGS,
-		.probe_func = probe_subsystem_eventb },
-};
-
-static int __init probe_init(void)
-{
-	int result;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(probe_array); i++) {
-		result = marker_probe_register(probe_array[i].name,
-				probe_array[i].format,
-				probe_array[i].probe_func, &probe_array[i]);
-		if (result)
-			printk(KERN_INFO "Unable to register probe %s\n",
-				probe_array[i].name);
-	}
-	return 0;
-}
-
-static void __exit probe_fini(void)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(probe_array); i++)
-		marker_probe_unregister(probe_array[i].name,
-			probe_array[i].probe_func, &probe_array[i]);
-	printk(KERN_INFO "Number of event b : %u\n",
-			atomic_read(&eventb_count));
-	marker_synchronize_unregister();
-}
-
-module_init(probe_init);
-module_exit(probe_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mathieu Desnoyers");
-MODULE_DESCRIPTION("SUBSYSTEM Probe");
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
index f24ae37..6af3732 100644
--- a/samples/trace_events/trace-events-sample.h
+++ b/samples/trace_events/trace-events-sample.h
@@ -1,6 +1,6 @@
 /*
  * If TRACE_SYSTEM is defined, that will be the directory created
- * in the ftrace directory under /debugfs/tracing/events/<system>
+ * in the ftrace directory under /sys/kernel/debug/tracing/events/<system>
  *
  * The define_trace.h below will also look for a file name of
  * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here.
diff --git a/scripts/Makefile b/scripts/Makefile
index 9dd5b25..842dbc2 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -10,7 +10,6 @@
 hostprogs-$(CONFIG_KALLSYMS)     += kallsyms
 hostprogs-$(CONFIG_LOGO)         += pnmtologo
 hostprogs-$(CONFIG_VT)           += conmakehash
-hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
 hostprogs-$(CONFIG_IKCONFIG)     += bin2c
 
 always		:= $(hostprogs-y) $(hostprogs-m)
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index f4053dc..8f14c81 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -13,7 +13,6 @@
 # 2) modpost is then used to
 # 3)  create one <module>.mod.c file pr. module
 # 4)  create one Module.symvers file with CRC for all exported symbols
-# 4a) [CONFIG_MARKERS] create one Module.markers file listing defined markers
 # 5) compile all <module>.mod.c files
 # 6) final link of the module to a <module.ko> file
 
@@ -59,10 +58,6 @@ include scripts/Makefile.lib
 
 kernelsymfile := $(objtree)/Module.symvers
 modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
-kernelmarkersfile := $(objtree)/Module.markers
-modulemarkersfile := $(firstword $(KBUILD_EXTMOD))/Module.markers
-
-markersfile = $(if $(KBUILD_EXTMOD),$(modulemarkersfile),$(kernelmarkersfile))
 
 # Step 1), find all modules listed in $(MODVERDIR)/
 __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
@@ -85,8 +80,6 @@ modpost = scripts/mod/modpost                    \
  $(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \
  $(if $(KBUILD_EXTMOD),-o $(modulesymfile))      \
  $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S)      \
- $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \
- $(if $(CONFIG_MARKERS),-M $(markersfile))	 \
  $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
  $(if $(cross_build),-c)
 
@@ -101,17 +94,12 @@ quiet_cmd_kernel-mod = MODPOST $@
       cmd_kernel-mod = $(modpost) $@
 
 vmlinux.o: FORCE
-	@rm -fr $(kernelmarkersfile)
 	$(call cmd,kernel-mod)
 
 # Declare generated files as targets for modpost
 $(symverfile):         __modpost ;
 $(modules:.ko=.mod.c): __modpost ;
 
-ifdef CONFIG_MARKERS
-$(markersfile):	       __modpost ;
-endif
-
 
 # Step 5), compile all *.mod.c files
 
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig
index 72997c3..de233ff 100755
--- a/scripts/extract-ikconfig
+++ b/scripts/extract-ikconfig
@@ -17,6 +17,10 @@ dump_config() {
 	return
     fi
     end=`$binoffset $file $IKCFG_ED 2>/dev/null`
+    [ "$?" != "0" ] && end="-1"
+    if [ "$end" -eq "-1" ]; then
+	return
+    fi
 
     start=`expr $start + 8`
     size=`expr $end - $start`
@@ -55,6 +59,8 @@ dump_config "$image"
 GZHDR1="0x1f 0x8b 0x08 0x00"
 GZHDR2="0x1f 0x8b 0x08 0x08"
 
+ELFHDR="0x7f 0x45 0x4c 0x46"
+
 # vmlinux.gz: Check for a compressed images
 off=`$binoffset "$image" $GZHDR1 2>/dev/null`
 [ "$?" != "0" ] && off="-1"
@@ -69,6 +75,14 @@ elif [ "$off" -ne "-1" ]; then
 	(dd ibs="$off" skip=1 count=0 && dd bs=512k) <"$image" 2>/dev/null | \
 		zcat >"$TMPFILE"
 	dump_config "$TMPFILE"
+
+# check if this is simply an ELF file
+else
+	off=`$binoffset "$image" $ELFHDR 2>/dev/null`
+	[ "$?" != "0" ] && off="-1"
+	if [ "$off" -eq "0" ]; then
+		dump_config "$image"
+	fi
 fi
 
 echo "ERROR: Unable to extract kernel configuration information."
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 5ddf8be..6d69c7c 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -2,7 +2,8 @@
 # Kernel configuration targets
 # These targets are used from top-level makefile
 
-PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
+PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \
+	localmodconfig localyesconfig
 
 ifdef KBUILD_KCONFIG
 Kconfig := $(KBUILD_KCONFIG)
@@ -28,6 +29,35 @@ oldconfig: $(obj)/conf
 silentoldconfig: $(obj)/conf
 	$< -s $(Kconfig)
 
+localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
+	$(Q)perl $< $(Kconfig) > .tmp.config
+	$(Q)if [ -f .config ]; then 				\
+			cmp -s .tmp.config .config ||		\
+			(mv -f .config .config.old.1;		\
+			 mv -f .tmp.config .config;		\
+			 $(obj)/conf -s $(Kconfig);		\
+			 mv -f .config.old.1 .config.old)	\
+	else							\
+			mv -f .tmp.config .config;		\
+			$(obj)/conf -s $(Kconfig);		\
+	fi
+	$(Q)rm -f .tmp.config
+
+localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
+	$(Q)perl $< $(Kconfig) > .tmp.config
+	$(Q)sed -i s/=m/=y/ .tmp.config
+	$(Q)if [ -f .config ]; then 				\
+			cmp -s .tmp.config .config ||		\
+			(mv -f .config .config.old.1;		\
+			 mv -f .tmp.config .config;		\
+			 $(obj)/conf -s $(Kconfig);		\
+			 mv -f .config.old.1 .config.old)	\
+	else							\
+			mv -f .tmp.config .config;		\
+			$(obj)/conf -s $(Kconfig);		\
+	fi
+	$(Q)rm -f .tmp.config
+
 # Create new linux.pot file
 # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
 # The symlink is used to repair a deficiency in arch/um
@@ -83,6 +113,8 @@ help:
 	@echo  '  xconfig	  - Update current config utilising a QT based front-end'
 	@echo  '  gconfig	  - Update current config utilising a GTK based front-end'
 	@echo  '  oldconfig	  - Update current config utilising a provided .config as base'
+	@echo  '  localmodconfig  - Update current config disabling modules not loaded'
+	@echo  '  localyesconfig  - Update current config converting local mods to core'
 	@echo  '  silentoldconfig - Same as oldconfig, but quietly, additionally update deps'
 	@echo  '  randconfig	  - New config with random answer to all options'
 	@echo  '  defconfig	  - New config with default answer to all options'
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
new file mode 100644
index 0000000..95984db
--- /dev/null
+++ b/scripts/kconfig/streamline_config.pl
@@ -0,0 +1,366 @@
+#!/usr/bin/perl -w
+#
+# Copywrite 2005-2009 - Steven Rostedt
+# Licensed under the terms of the GNU GPL License version 2
+#
+#  It's simple enough to figure out how this works.
+#  If not, then you can ask me at stripconfig@goodmis.org
+#
+# What it does?
+#
+#   If you have installed a Linux kernel from a distribution
+#   that turns on way too many modules than you need, and
+#   you only want the modules you use, then this program
+#   is perfect for you.
+#
+#   It gives you the ability to turn off all the modules that are
+#   not loaded on your system.
+#
+# Howto:
+#
+#  1. Boot up the kernel that you want to stream line the config on.
+#  2. Change directory to the directory holding the source of the
+#       kernel that you just booted.
+#  3. Copy the configuraton file to this directory as .config
+#  4. Have all your devices that you need modules for connected and
+#      operational (make sure that their corresponding modules are loaded)
+#  5. Run this script redirecting the output to some other file
+#       like config_strip.
+#  6. Back up your old config (if you want too).
+#  7. copy the config_strip file to .config
+#  8. Run "make oldconfig"
+#
+#  Now your kernel is ready to be built with only the modules that
+#  are loaded.
+#
+# Here's what I did with my Debian distribution.
+#
+#    cd /usr/src/linux-2.6.10
+#    cp /boot/config-2.6.10-1-686-smp .config
+#    ~/bin/streamline_config > config_strip
+#    mv .config config_sav
+#    mv config_strip .config
+#    make oldconfig
+#
+my $config = ".config";
+my $linuxpath = ".";
+
+my $uname = `uname -r`;
+chomp $uname;
+
+my @searchconfigs = (
+	{
+	    "file" => ".config",
+	    "exec" => "cat",
+	},
+	{
+	    "file" => "/proc/config.gz",
+	    "exec" => "zcat",
+	},
+	{
+	    "file" => "/boot/config-$uname",
+	    "exec" => "cat",
+	},
+	{
+	    "file" => "/boot/vmlinuz-$uname",
+	    "exec" => "scripts/extract-ikconfig",
+	    "test" => "scripts/extract-ikconfig",
+	},
+	{
+	    "file" => "vmlinux",
+	    "exec" => "scripts/extract-ikconfig",
+	    "test" => "scripts/extract-ikconfig",
+	},
+	{
+	    "file" => "/lib/modules/$uname/kernel/kernel/configs.ko",
+	    "exec" => "scripts/extract-ikconfig",
+	    "test" => "scripts/extract-ikconfig",
+	},
+	{
+	    "file" => "kernel/configs.ko",
+	    "exec" => "scripts/extract-ikconfig",
+	    "test" => "scripts/extract-ikconfig",
+	},
+	{
+	    "file" => "kernel/configs.o",
+	    "exec" => "scripts/extract-ikconfig",
+	    "test" => "scripts/extract-ikconfig",
+	},
+);
+
+sub find_config {
+    foreach my $conf (@searchconfigs) {
+	my $file = $conf->{"file"};
+
+	next if ( ! -f "$file");
+
+	if (defined($conf->{"test"})) {
+	    `$conf->{"test"} $conf->{"file"} 2>/dev/null`;
+	    next if ($?);
+	}
+
+	my $exec = $conf->{"exec"};
+
+	print STDERR "using config: '$file'\n";
+
+	open(CIN, "$exec $file |") || die "Failed to run $exec $file";
+	return;
+    }
+    die "No config file found";
+}
+
+find_config;
+
+my @makefiles = `find $linuxpath -name Makefile`;
+my %depends;
+my %selects;
+my %prompts;
+my %objects;
+my $var;
+my $cont = 0;
+
+# Get the top level Kconfig file (passed in)
+my $kconfig = $ARGV[0];
+
+# prevent recursion
+my %read_kconfigs;
+
+sub read_kconfig {
+    my ($kconfig) = @_;
+
+    my $state = "NONE";
+    my $config;
+    my @kconfigs;
+
+    open(KIN, $kconfig) || die "Can't open $kconfig";
+    while (<KIN>) {
+	chomp;
+
+	# collect any Kconfig sources
+	if (/^source\s*"(.*)"/) {
+	    $kconfigs[$#kconfigs+1] = $1;
+	}
+
+	# configs found
+	if (/^\s*config\s+(\S+)\s*$/) {
+	    $state = "NEW";
+	    $config = $1;
+
+	# collect the depends for the config
+	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
+	    $state = "DEP";
+	    $depends{$config} = $1;
+	} elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) {
+	    $depends{$config} .= " " . $1;
+
+	# Get the configs that select this config
+	} elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
+	    if (defined($selects{$1})) {
+		$selects{$1} .= " " . $config;
+	    } else {
+		$selects{$1} = $config;
+	    }
+
+	# configs without prompts must be selected
+	} elsif ($state ne "NONE" && /^\s*tristate\s\S/) {
+	    # note if the config has a prompt
+	    $prompt{$config} = 1;
+
+	# stop on "help"
+	} elsif (/^\s*help\s*$/) {
+	    $state = "NONE";
+	}
+    }
+    close(KIN);
+
+    # read in any configs that were found.
+    foreach $kconfig (@kconfigs) {
+	if (!defined($read_kconfigs{$kconfig})) {
+	    $read_kconfigs{$kconfig} = 1;
+	    read_kconfig($kconfig);
+	}
+    }
+}
+
+if ($kconfig) {
+    read_kconfig($kconfig);
+}
+
+# Read all Makefiles to map the configs to the objects
+foreach my $makefile (@makefiles) {
+    chomp $makefile;
+
+    open(MIN,$makefile) || die "Can't open $makefile";
+    while (<MIN>) {
+	my $objs;
+
+	# is this a line after a line with a backslash?
+	if ($cont && /(\S.*)$/) {
+	    $objs = $1;
+	}
+	$cont = 0;
+
+	# collect objects after obj-$(CONFIG_FOO_BAR)
+	if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) {
+	    $var = $1;
+	    $objs = $2;
+	}
+	if (defined($objs)) {
+	    # test if the line ends with a backslash
+	    if ($objs =~ m,(.*)\\$,) {
+		$objs = $1;
+		$cont = 1;
+	    }
+
+	    foreach my $obj (split /\s+/,$objs) {
+		$obj =~ s/-/_/g;
+		if ($obj =~ /(.*)\.o$/) {
+		    # Objects may bes enabled by more than one config.
+		    # Store configs in an array.
+		    my @arr;
+
+		    if (defined($objects{$1})) {
+			@arr = @{$objects{$1}};
+		    }
+
+		    $arr[$#arr+1] = $var;
+
+		    # The objects have a hash mapping to a reference
+		    # of an array of configs.
+		    $objects{$1} = \@arr;
+		}
+	    }
+	}
+    }
+    close(MIN);
+}
+
+my %modules;
+
+# see what modules are loaded on this system
+open(LIN,"/sbin/lsmod|") || die "Cant lsmod";
+while (<LIN>) {
+	next if (/^Module/);  # Skip the first line.
+	if (/^(\S+)/) {
+		$modules{$1} = 1;
+	}
+}
+close (LIN);
+
+# add to the configs hash all configs that are needed to enable
+# a loaded module.
+my %configs;
+foreach my $module (keys(%modules)) {
+    if (defined($objects{$module})) {
+	@arr = @{$objects{$module}};
+	foreach my $conf (@arr) {
+	    $configs{$conf} = $module;
+	}
+    } else {
+	# Most likely, someone has a custom (binary?) module loaded.
+	print STDERR "$module config not found!!\n";
+    }
+}
+
+my $valid = "A-Za-z_0-9";
+my $repeat = 1;
+
+#
+# Note, we do not care about operands (like: &&, ||, !) we want to add any
+# config that is in the depend list of another config. This script does
+# not enable configs that are not already enabled. If we come across a
+# config A that depends on !B, we can still add B to the list of depends
+# to keep on. If A was on in the original config, B would not have been
+# and B would not be turned on by this script.
+#
+sub parse_config_dep_select
+{
+    my ($p) = @_;
+
+    while ($p =~ /[$valid]/) {
+
+	if ($p =~ /^[^$valid]*([$valid]+)/) {
+	    my $conf = "CONFIG_" . $1;
+
+	    $p =~ s/^[^$valid]*[$valid]+//;
+
+	    if (!defined($configs{$conf})) {
+		# We must make sure that this config has its
+		# dependencies met.
+		$repeat = 1; # do again
+		$configs{$conf} = 1;
+	    }
+	} else {
+	    die "this should never happen";
+	}
+    }
+}
+
+while ($repeat) {
+    $repeat = 0;
+
+    foreach my $config (keys %configs) {
+	$config =~ s/^CONFIG_//;
+
+	if (defined($depends{$config})) {
+	    # This config has dependencies. Make sure they are also included
+	    parse_config_dep_select $depends{$config};
+	}
+
+	if (defined($prompt{$config}) || !defined($selects{$config})) {
+	    next;
+	}
+
+	# config has no prompt and must be selected.
+	parse_config_dep_select $selects{$config};
+    }
+}
+
+my %setconfigs;
+
+# Finally, read the .config file and turn off any module enabled that
+# we could not find a reason to keep enabled.
+while(<CIN>) {
+
+    if (/CONFIG_IKCONFIG/) {
+	if (/# CONFIG_IKCONFIG is not set/) {
+	    # enable IKCONFIG at least as a module
+	    print "CONFIG_IKCONFIG=m\n";
+	    # don't ask about PROC
+	    print "# CONFIG_IKCONFIG_PROC is not set\n";
+	} else {
+	    print;
+	}
+	next;
+    }
+
+    if (/^(CONFIG.*)=(m|y)/) {
+	if (defined($configs{$1})) {
+	    $setconfigs{$1} = $2;
+	} elsif ($2 eq "m") {
+	    print "# $1 is not set\n";
+	    next;
+	}
+    }
+    print;
+}
+close(CIN);
+
+# Integrity check, make sure all modules that we want enabled do
+# indeed have their configs set.
+loop:
+foreach my $module (keys(%modules)) {
+    if (defined($objects{$module})) {
+	my @arr = @{$objects{$module}};
+	foreach my $conf (@arr) {
+	    if (defined($setconfigs{$conf})) {
+		next loop;
+	    }
+	}
+	print STDERR "module $module did not have configs";
+	foreach my $conf (@arr) {
+	    print STDERR " " , $conf;
+	}
+	print STDERR "\n";
+    }
+}
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index b52d340..ea9f8a5 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -1995,6 +1995,7 @@ sub process_file($) {
     my $identifier;
     my $func;
     my $descr;
+    my $in_purpose = 0;
     my $initial_section_counter = $section_counter;
 
     if (defined($ENV{'SRCTREE'})) {
@@ -2044,6 +2045,7 @@ sub process_file($) {
 		    $descr =~ s/\s*$//;
 		    $descr =~ s/\s+/ /;
 		    $declaration_purpose = xml_escape($descr);
+		    $in_purpose = 1;
 		} else {
 		    $declaration_purpose = "";
 		}
@@ -2090,6 +2092,7 @@ sub process_file($) {
 		}
 
 		$in_doc_sect = 1;
+		$in_purpose = 0;
 		$contents = $newcontents;
 		if ($contents ne "") {
 		    while ((substr($contents, 0, 1) eq " ") ||
@@ -2119,11 +2122,19 @@ sub process_file($) {
 	    } elsif (/$doc_content/) {
 		# miguel-style comment kludge, look for blank lines after
 		# @parameter line to signify start of description
-		if ($1 eq "" &&
-			($section =~ m/^@/ || $section eq $section_context)) {
-		    dump_section($file, $section, xml_escape($contents));
-		    $section = $section_default;
-		    $contents = "";
+		if ($1 eq "") {
+		    if ($section =~ m/^@/ || $section eq $section_context) {
+			dump_section($file, $section, xml_escape($contents));
+			$section = $section_default;
+			$contents = "";
+		    } else {
+			$contents .= "\n";
+		    }
+		    $in_purpose = 0;
+		} elsif ($in_purpose == 1) {
+		    # Continued declaration purpose
+		    chomp($declaration_purpose);
+		    $declaration_purpose .= " " . xml_escape($1);
 		} else {
 		    $contents .= $1 . "\n";
 		}
diff --git a/scripts/module-common.lds b/scripts/module-common.lds
new file mode 100644
index 0000000..47a1f9a
--- /dev/null
+++ b/scripts/module-common.lds
@@ -0,0 +1,8 @@
+/*
+ * Common module linker script, always used when linking a module.
+ * Archs are free to supply their own linker scripts.  ld will
+ * combine them automatically.
+ */
+SECTIONS {
+	/DISCARD/ : { *(.discard) }
+}
diff --git a/scripts/tracing/power.pl b/scripts/tracing/power.pl
deleted file mode 100644
index 4f729b3..0000000
--- a/scripts/tracing/power.pl
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/perl
-
-# Copyright 2008, Intel Corporation
-#
-# This file is part of the Linux kernel
-#
-# This program file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; 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 in a file named COPYING; if not, write to the
-# Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor,
-# Boston, MA 02110-1301 USA
-#
-# Authors:
-# 	Arjan van de Ven <arjan@linux.intel.com>
-
-
-#
-# This script turns a cstate ftrace output into a SVG graphic that shows
-# historic C-state information
-#
-#
-# 	cat /sys/kernel/debug/tracing/trace | perl power.pl > out.svg
-#
-
-my @styles;
-my $base = 0;
-
-my @pstate_last;
-my @pstate_level;
-
-$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-$styles[8] = "fill:rgb(0,25,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
-
-
-print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
-print "<svg width=\"10000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
-
-my $scale = 30000.0;
-while (<>) {
-	my $line = $_;
-	if ($line =~ /([0-9\.]+)\] CSTATE: Going to C([0-9]) on cpu ([0-9]+) for ([0-9\.]+)/) {
-		if ($base == 0) {
-			$base = $1;
-		}
-		my $time = $1 - $base;
-		$time = $time * $scale;
-		my $C = $2;
-		my $cpu = $3;
-		my $y = 400 * $cpu;
-		my $duration = $4 * $scale;
-		my $msec = int($4 * 100000)/100.0;
-		my $height = $C * 20;
-		$style = $styles[$C];
-
-		$y = $y + 140 - $height;
-
-		$x2 = $time + 4;
-		$y2 = $y + 4;
-
-
-		print "<rect x=\"$time\" width=\"$duration\" y=\"$y\" height=\"$height\" style=\"$style\"/>\n";
-		print "<text transform=\"translate($x2,$y2) rotate(90)\">C$C $msec</text>\n";
-	}
-	if ($line =~ /([0-9\.]+)\] PSTATE: Going to P([0-9]) on cpu ([0-9]+)/) {
-		my $time = $1 - $base;
-		my $state = $2;
-		my $cpu = $3;
-
-		if (defined($pstate_last[$cpu])) {
-			my $from = $pstate_last[$cpu];
-			my $oldstate = $pstate_state[$cpu];
-			my $duration = ($time-$from) * $scale;
-
-			$from = $from * $scale;
-			my $to = $from + $duration;
-			my $height = 140 - ($oldstate * (140/8));
-
-			my $y = 400 * $cpu + 200 + $height;
-			my $y2 = $y+4;
-			my $style = $styles[8];
-
-			print "<rect x=\"$from\" y=\"$y\" width=\"$duration\" height=\"5\" style=\"$style\"/>\n";
-			print "<text transform=\"translate($from,$y2)\">P$oldstate (cpu $cpu)</text>\n";
-		};
-
-		$pstate_last[$cpu] = $time;
-		$pstate_state[$cpu] = $state;
-	}
-}
-
-
-print "</svg>\n";
diff --git a/security/Kconfig b/security/Kconfig
index 4c86534..fb363cd 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -113,6 +113,36 @@ config SECURITY_ROOTPLUG
 
 	  If you are unsure how to answer this question, answer N.
 
+config INTEL_TXT
+	bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
+	depends on HAVE_INTEL_TXT
+	help
+	  This option enables support for booting the kernel with the
+	  Trusted Boot (tboot) module. This will utilize
+	  Intel(R) Trusted Execution Technology to perform a measured launch
+	  of the kernel. If the system does not support Intel(R) TXT, this
+	  will have no effect.
+
+	  Intel TXT will provide higher assurance of system configuration and
+	  initial state as well as data reset protection.  This is used to
+	  create a robust initial kernel measurement and verification, which
+	  helps to ensure that kernel security mechanisms are functioning
+	  correctly. This level of protection requires a root of trust outside
+	  of the kernel itself.
+
+	  Intel TXT also helps solve real end user concerns about having
+	  confidence that their hardware is running the VMM or kernel that
+	  it was configured with, especially since they may be responsible for
+	  providing such assurances to VMs and services running on it.
+
+	  See <http://www.intel.com/technology/security/> for more information
+	  about Intel(R) TXT.
+	  See <http://tboot.sourceforge.net> for more information about tboot.
+	  See Documentation/intel_txt.txt for a description of how to enable
+	  Intel TXT support in a kernel boot.
+
+	  If you are unsure as to whether this is required, answer N.
+
 config LSM_MMAP_MIN_ADDR
 	int "Low address space for LSM to protect from user allocation"
 	depends on SECURITY && SECURITY_SELINUX
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 1e616ae..485fc62 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -26,8 +26,10 @@ static void key_garbage_collector(struct work_struct *);
 static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0);
 static DECLARE_WORK(key_gc_work, key_garbage_collector);
 static key_serial_t key_gc_cursor; /* the last key the gc considered */
+static bool key_gc_again;
 static unsigned long key_gc_executing;
 static time_t key_gc_next_run = LONG_MAX;
+static time_t key_gc_new_timer;
 
 /*
  * Schedule a garbage collection run
@@ -40,9 +42,7 @@ void key_schedule_gc(time_t gc_at)
 
 	kenter("%ld", gc_at - now);
 
-	gc_at += key_gc_delay;
-
-	if (now >= gc_at) {
+	if (gc_at <= now) {
 		schedule_work(&key_gc_work);
 	} else if (gc_at < key_gc_next_run) {
 		expires = jiffies + (gc_at - now) * HZ;
@@ -112,16 +112,18 @@ static void key_garbage_collector(struct work_struct *work)
 	struct rb_node *rb;
 	key_serial_t cursor;
 	struct key *key, *xkey;
-	time_t new_timer = LONG_MAX, limit;
+	time_t new_timer = LONG_MAX, limit, now;
 
-	kenter("");
+	now = current_kernel_time().tv_sec;
+	kenter("[%x,%ld]", key_gc_cursor, key_gc_new_timer - now);
 
 	if (test_and_set_bit(0, &key_gc_executing)) {
-		key_schedule_gc(current_kernel_time().tv_sec);
+		key_schedule_gc(current_kernel_time().tv_sec + 1);
+		kleave(" [busy; deferring]");
 		return;
 	}
 
-	limit = current_kernel_time().tv_sec;
+	limit = now;
 	if (limit > key_gc_delay)
 		limit -= key_gc_delay;
 	else
@@ -129,12 +131,19 @@ static void key_garbage_collector(struct work_struct *work)
 
 	spin_lock(&key_serial_lock);
 
-	if (RB_EMPTY_ROOT(&key_serial_tree))
-		goto reached_the_end;
+	if (unlikely(RB_EMPTY_ROOT(&key_serial_tree))) {
+		spin_unlock(&key_serial_lock);
+		clear_bit(0, &key_gc_executing);
+		return;
+	}
 
 	cursor = key_gc_cursor;
 	if (cursor < 0)
 		cursor = 0;
+	if (cursor > 0)
+		new_timer = key_gc_new_timer;
+	else
+		key_gc_again = false;
 
 	/* find the first key above the cursor */
 	key = NULL;
@@ -160,35 +169,50 @@ static void key_garbage_collector(struct work_struct *work)
 
 	/* trawl through the keys looking for keyrings */
 	for (;;) {
-		if (key->expiry > 0 && key->expiry < new_timer)
+		if (key->expiry > now && key->expiry < new_timer) {
+			kdebug("will expire %x in %ld",
+			       key_serial(key), key->expiry - now);
 			new_timer = key->expiry;
+		}
 
 		if (key->type == &key_type_keyring &&
-		    key_gc_keyring(key, limit)) {
-			/* the gc ate our lock */
-			schedule_work(&key_gc_work);
-			goto no_unlock;
-		}
+		    key_gc_keyring(key, limit))
+			/* the gc had to release our lock so that the keyring
+			 * could be modified, so we have to get it again */
+			goto gc_released_our_lock;
 
 		rb = rb_next(&key->serial_node);
-		if (!rb) {
-			key_gc_cursor = 0;
-			break;
-		}
+		if (!rb)
+			goto reached_the_end;
 		key = rb_entry(rb, struct key, serial_node);
 	}
 
-out:
-	spin_unlock(&key_serial_lock);
-no_unlock:
+gc_released_our_lock:
+	kdebug("gc_released_our_lock");
+	key_gc_new_timer = new_timer;
+	key_gc_again = true;
 	clear_bit(0, &key_gc_executing);
-	if (new_timer < LONG_MAX)
-		key_schedule_gc(new_timer);
-
-	kleave("");
+	schedule_work(&key_gc_work);
+	kleave(" [continue]");
 	return;
 
+	/* when we reach the end of the run, we set the timer for the next one */
 reached_the_end:
+	kdebug("reached_the_end");
+	spin_unlock(&key_serial_lock);
+	key_gc_new_timer = new_timer;
 	key_gc_cursor = 0;
-	goto out;
+	clear_bit(0, &key_gc_executing);
+
+	if (key_gc_again) {
+		/* there may have been a key that expired whilst we were
+		 * scanning, so if we discarded any links we should do another
+		 * scan */
+		new_timer = now + 1;
+		key_schedule_gc(new_timer);
+	} else if (new_timer < LONG_MAX) {
+		new_timer += key_gc_delay;
+		key_schedule_gc(new_timer);
+	}
+	kleave(" [end]");
 }
diff --git a/security/keys/key.c b/security/keys/key.c
index 08531ad..e50d264 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -500,7 +500,7 @@ int key_negate_and_link(struct key *key,
 		set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
 		now = current_kernel_time();
 		key->expiry = now.tv_sec + timeout;
-		key_schedule_gc(key->expiry);
+		key_schedule_gc(key->expiry + key_gc_delay);
 
 		if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
 			awaken = 1;
@@ -909,7 +909,7 @@ void key_revoke(struct key *key)
 	time = now.tv_sec;
 	if (key->revoked_at == 0 || key->revoked_at > time) {
 		key->revoked_at = time;
-		key_schedule_gc(key->revoked_at);
+		key_schedule_gc(key->revoked_at + key_gc_delay);
 	}
 
 	up_write(&key->sem);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 74c9685..2fb28ef 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1115,7 +1115,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
 	}
 
 	key->expiry = expiry;
-	key_schedule_gc(key->expiry);
+	key_schedule_gc(key->expiry + key_gc_delay);
 
 	up_write(&key->sem);
 	key_put(key);
@@ -1319,6 +1319,7 @@ long keyctl_session_to_parent(void)
 already_same:
 	ret = 0;
 not_permitted:
+	write_unlock_irq(&tasklist_lock);
 	put_cred(cred);
 	return ret;
 
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index ac977f6..8ec0274 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1019,18 +1019,18 @@ void keyring_gc(struct key *keyring, time_t limit)
 	struct key *key;
 	int loop, keep, max;
 
-	kenter("%x", key_serial(keyring));
+	kenter("{%x,%s}", key_serial(keyring), keyring->description);
 
 	down_write(&keyring->sem);
 
 	klist = keyring->payload.subscriptions;
 	if (!klist)
-		goto just_return;
+		goto no_klist;
 
 	/* work out how many subscriptions we're keeping */
 	keep = 0;
 	for (loop = klist->nkeys - 1; loop >= 0; loop--)
-		if (!key_is_dead(klist->keys[loop], limit));
+		if (!key_is_dead(klist->keys[loop], limit))
 			keep++;
 
 	if (keep == klist->nkeys)
@@ -1041,7 +1041,7 @@ void keyring_gc(struct key *keyring, time_t limit)
 	new = kmalloc(sizeof(struct keyring_list) + max * sizeof(struct key *),
 		      GFP_KERNEL);
 	if (!new)
-		goto just_return;
+		goto nomem;
 	new->maxkeys = max;
 	new->nkeys = 0;
 	new->delkey = 0;
@@ -1081,7 +1081,21 @@ void keyring_gc(struct key *keyring, time_t limit)
 discard_new:
 	new->nkeys = keep;
 	keyring_clear_rcu_disposal(&new->rcu);
+	up_write(&keyring->sem);
+	kleave(" [discard]");
+	return;
+
 just_return:
 	up_write(&keyring->sem);
-	kleave(" [no]");
+	kleave(" [no dead]");
+	return;
+
+no_klist:
+	up_write(&keyring->sem);
+	kleave(" [no_klist]");
+	return;
+
+nomem:
+	up_write(&keyring->sem);
+	kleave(" [oom]");
 }
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index e3d1901..1ed0f07 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -709,18 +709,16 @@ out:
 }
 
 /**
- * avc_ss_reset - Flush the cache and revalidate migrated permissions.
- * @seqno: policy sequence number
+ * avc_flush - Flush the cache
  */
-int avc_ss_reset(u32 seqno)
+static void avc_flush(void)
 {
-	struct avc_callback_node *c;
-	int i, rc = 0, tmprc;
-	unsigned long flag;
-	struct avc_node *node;
 	struct hlist_head *head;
 	struct hlist_node *next;
+	struct avc_node *node;
 	spinlock_t *lock;
+	unsigned long flag;
+	int i;
 
 	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
 		head = &avc_cache.slots[i];
@@ -737,6 +735,18 @@ int avc_ss_reset(u32 seqno)
 		rcu_read_unlock();
 		spin_unlock_irqrestore(lock, flag);
 	}
+}
+
+/**
+ * avc_ss_reset - Flush the cache and revalidate migrated permissions.
+ * @seqno: policy sequence number
+ */
+int avc_ss_reset(u32 seqno)
+{
+	struct avc_callback_node *c;
+	int rc = 0, tmprc;
+
+	avc_flush();
 
 	for (c = avc_callbacks; c; c = c->next) {
 		if (c->events & AVC_CALLBACK_RESET) {
@@ -858,6 +868,8 @@ u32 avc_policy_seqno(void)
 
 void avc_disable(void)
 {
+	avc_flush();
+	synchronize_rcu();
 	if (avc_node_cachep)
 		kmem_cache_destroy(avc_node_cachep);
 }
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index c73aeaa..c0a454a 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -63,3 +63,9 @@ void selinux_secmark_refcount_dec(void)
 	atomic_dec(&selinux_secmark_refcount);
 }
 EXPORT_SYMBOL_GPL(selinux_secmark_refcount_dec);
+
+bool selinux_is_enabled(void)
+{
+	return selinux_enabled;
+}
+EXPORT_SYMBOL_GPL(selinux_is_enabled);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 7ed47f6..1296058 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -7927,8 +7927,9 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
 
 static struct snd_kcontrol_new alc883_targa_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
@@ -7947,8 +7948,9 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = {
 
 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
@@ -7960,6 +7962,15 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
+	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
+	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	{ } /* end */
+};
+
 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -9167,7 +9178,8 @@ static struct alc_config_preset alc882_presets[] = {
 		.init_hook = alc882_targa_automute,
 	},
 	[ALC883_TARGA_8ch_DIG] = {
-		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
+		.mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
+			    alc883_chmode_mixer },
 		.init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
 				alc883_targa_verbs },
 		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
@@ -13370,7 +13382,8 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
 	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
 	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901",
 	[ALC269_FUJITSU]		= "fujitsu",
-	[ALC269_LIFEBOOK]		= "lifebook"
+	[ALC269_LIFEBOOK]		= "lifebook",
+	[ALC269_AUTO]			= "auto",
 };
 
 static struct snd_pci_quirk alc269_cfg_tbl[] = {
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index e31e53d..826137e 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -864,10 +864,6 @@ static struct hda_verb stac92hd73xx_core_init[] = {
 };
 
 static struct hda_verb stac92hd83xxx_core_init[] = {
-	{ 0xa, AC_VERB_SET_CONNECT_SEL, 0x1},
-	{ 0xb, AC_VERB_SET_CONNECT_SEL, 0x1},
-	{ 0xd, AC_VERB_SET_CONNECT_SEL, 0x0},
-
 	/* power state controls amps */
 	{ 0x01, AC_VERB_SET_EAPD, 1 << 2},
 	{}
@@ -1590,8 +1586,8 @@ static unsigned int ref92hd83xxx_pin_configs[10] = {
 };
 
 static unsigned int dell_s14_pin_configs[10] = {
-	0x02214030, 0x02211010, 0x02a19020, 0x01014050,
-	0x40f000f0, 0x01819040, 0x40f000f0, 0x90a60160,
+	0x0221403f, 0x0221101f, 0x02a19020, 0x90170110,
+	0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160,
 	0x40f000f0, 0x40f000f0,
 };
 
@@ -1690,6 +1686,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
 		      "HP mini 1000", STAC_HP_M4),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
 		      "HP HDX", STAC_HP_HDX),  /* HDX16 */
+	SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620,
+		      "HP dv6", STAC_HP_DV5),
 	SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
 		      "HP", STAC_HP_DV5),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -4166,7 +4164,10 @@ static int stac92xx_init(struct hda_codec *codec)
 		stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
 				AC_PINCTL_OUT_EN);
 		/* fake event to set up pins */
-		stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
+		if (cfg->hp_pins[0])
+			stac_issue_unsol_event(codec, cfg->hp_pins[0]);
+		else if (cfg->line_out_pins[0])
+			stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
 	} else {
 		stac92xx_auto_init_multi_out(codec);
 		stac92xx_auto_init_hp_out(codec);
@@ -4688,8 +4689,13 @@ static int stac92xx_resume(struct hda_codec *codec)
 	snd_hda_codec_resume_amp(codec);
 	snd_hda_codec_resume_cache(codec);
 	/* fake event to set up pins again to override cached values */
-	if (spec->hp_detect)
-		stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
+	if (spec->hp_detect) {
+		if (spec->autocfg.hp_pins[0])
+			stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
+		else if (spec->autocfg.line_out_pins[0])
+			stac_issue_unsol_event(codec,
+					       spec->autocfg.line_out_pins[0]);
+	}
 	return 0;
 }
 
@@ -5016,7 +5022,7 @@ again:
 		spec->eapd_switch = 1;
 		break;
 	}
-	if (spec->board_config > STAC_92HD73XX_REF) {
+	if (spec->board_config != STAC_92HD73XX_REF) {
 		/* GPIO0 High = Enable EAPD */
 		spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
 		spec->gpio_data = 0x01;
@@ -5066,7 +5072,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
 
 	codec->spec = spec;
 	codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
-	spec->mono_nid = 0x19;
 	spec->digbeep_nid = 0x21;
 	spec->mux_nids = stac92hd83xxx_mux_nids;
 	spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids);
@@ -5242,7 +5247,7 @@ again:
 		stac92xx_set_config_regs(codec,
 				stac92hd71bxx_brd_tbl[spec->board_config]);
 
-	if (spec->board_config > STAC_92HD71BXX_REF) {
+	if (spec->board_config != STAC_92HD71BXX_REF) {
 		/* GPIO0 = EAPD */
 		spec->gpio_mask = 0x01;
 		spec->gpio_dir = 0x01;
@@ -5375,6 +5380,11 @@ again:
 	case STAC_HP_DV5:
 		snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
 		stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN);
+		/* HP dv6 gives the headphone pin as a line-out.  Thus we
+		 * need to set hp_detect flag here to force to enable HP
+		 * detection.
+		 */
+		spec->hp_detect = 1;
 		break;
 	case STAC_HP_HDX:
 		spec->num_dmics = 1;
@@ -5557,14 +5567,17 @@ static int patch_stac927x(struct hda_codec *codec)
 	spec->dac_list = stac927x_dac_nids;
 	spec->multiout.dac_nids = spec->dac_nids;
 
+	if (spec->board_config != STAC_D965_REF) {
+		/* GPIO0 High = Enable EAPD */
+		spec->eapd_mask = spec->gpio_mask = 0x01;
+		spec->gpio_dir = spec->gpio_data = 0x01;
+	}
+
 	switch (spec->board_config) {
 	case STAC_D965_3ST:
 	case STAC_D965_5ST:
 		/* GPIO0 High = Enable EAPD */
-		spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x01;
-		spec->gpio_data = 0x01;
 		spec->num_dmics = 0;
-
 		spec->init = d965_core_init;
 		break;
 	case STAC_DELL_BIOS:
@@ -5583,16 +5596,11 @@ static int patch_stac927x(struct hda_codec *codec)
 		snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130);
 		/* fallthru */
 	case STAC_DELL_3ST:
-		/* GPIO2 High = Enable EAPD */
-		spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04;
-		spec->gpio_data = 0x04;
-		switch (codec->subsystem_id) {
-		case 0x1028022f:
-			/* correct EAPD to be GPIO0 */
-			spec->eapd_mask = spec->gpio_mask = 0x01;
-			spec->gpio_dir = spec->gpio_data = 0x01;
-			break;
-		};
+		if (codec->subsystem_id != 0x1028022f) {
+			/* GPIO2 High = Enable EAPD */
+			spec->eapd_mask = spec->gpio_mask = 0x04;
+			spec->gpio_dir = spec->gpio_data = 0x04;
+		}
 		spec->dmic_nids = stac927x_dmic_nids;
 		spec->num_dmics = STAC927X_NUM_DMICS;
 
@@ -5601,14 +5609,9 @@ static int patch_stac927x(struct hda_codec *codec)
 		spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
 		break;
 	default:
-		if (spec->board_config > STAC_D965_REF) {
-			/* GPIO0 High = Enable EAPD */
-			spec->eapd_mask = spec->gpio_mask = 0x01;
-			spec->gpio_dir = spec->gpio_data = 0x01;
-		}
 		spec->num_dmics = 0;
-
 		spec->init = stac927x_core_init;
+		break;
 	}
 
 	spec->num_caps = STAC927X_NUM_CAPS;
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 130b121..885ba01 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -193,38 +193,6 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
 	.set_bias_level = at91sam9g20ek_set_bias_level,
 };
 
-/*
- * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
- * New drivers should register the wm8731 I2C device in the machine
- * setup code (under arch/arm for ARM systems).
- */
-static int wm8731_i2c_register(void)
-{
-	struct i2c_board_info info;
-	struct i2c_adapter *adapter;
-	struct i2c_client *client;
-
-	memset(&info, 0, sizeof(struct i2c_board_info));
-	info.addr = 0x1b;
-	strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
-
-	adapter = i2c_get_adapter(0);
-	if (!adapter) {
-		printk(KERN_ERR "can't get i2c adapter 0\n");
-		return -ENODEV;
-	}
-
-	client = i2c_new_device(adapter, &info);
-	i2c_put_adapter(adapter);
-	if (!client) {
-		printk(KERN_ERR "can't add i2c device at 0x%x\n",
-			(unsigned int)info.addr);
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
 static struct snd_soc_device at91sam9g20ek_snd_devdata = {
 	.card = &snd_soc_at91sam9g20ek,
 	.codec_dev = &soc_codec_dev_wm8731,
@@ -279,10 +247,6 @@ static int __init at91sam9g20ek_init(void)
 	}
 	ssc_p->ssc = ssc;
 
-	ret = wm8731_i2c_register();
-	if (ret != 0)
-		goto err_ssc;
-
 	at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
 	if (!at91sam9g20ek_snd_device) {
 		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 3612bb9..01343dc 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -18,7 +18,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <sound/core.h>
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index e62b277..9a049a1 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -28,7 +28,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <sound/core.h>
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index d8a013a..98d663a 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -12,7 +12,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 091dacb..2f7da49 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -145,7 +145,7 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
 	prtd->master_lch = ret;
 
 	/* Request parameter RAM reload slot */
-	ret = edma_alloc_slot(EDMA_SLOT_ANY);
+	ret = edma_alloc_slot(EDMA_CTLR(prtd->master_lch), EDMA_SLOT_ANY);
 	if (ret < 0) {
 		edma_free_channel(prtd->master_lch);
 		return ret;
@@ -162,8 +162,8 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
 	 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
 	 */
 	edma_read_slot(prtd->slave_lch, &p_ram);
-	p_ram.opt |= TCINTEN | EDMA_TCC(prtd->master_lch);
-	p_ram.link_bcntrld = prtd->slave_lch << 5;
+	p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(prtd->master_lch));
+	p_ram.link_bcntrld = EDMA_CHAN_SLOT(prtd->slave_lch) << 5;
 	edma_write_slot(prtd->slave_lch, &p_ram);
 
 	return 0;
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 9ff62e3..6096d22 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -447,6 +447,7 @@ int mpc5200_audio_dma_create(struct of_device *op)
 	int size, irq, rc;
 	const __be32 *prop;
 	void __iomem *regs;
+	int ret;
 
 	/* Fetch the registers and IRQ of the PSC */
 	irq = irq_of_parse_and_map(op->node, 0);
@@ -463,14 +464,16 @@ int mpc5200_audio_dma_create(struct of_device *op)
 	/* Allocate and initialize the driver private data */
 	psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL);
 	if (!psc_dma) {
-		iounmap(regs);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out_unmap;
 	}
 
 	/* Get the PSC ID */
 	prop = of_get_property(op->node, "cell-index", &size);
-	if (!prop || size < sizeof *prop)
-		return -ENODEV;
+	if (!prop || size < sizeof *prop) {
+		ret = -ENODEV;
+		goto out_free;
+	}
 
 	spin_lock_init(&psc_dma->lock);
 	mutex_init(&psc_dma->mutex);
@@ -493,9 +496,8 @@ int mpc5200_audio_dma_create(struct of_device *op)
 	if (!psc_dma->capture.bcom_task ||
 	    !psc_dma->playback.bcom_task) {
 		dev_err(&op->dev, "Could not allocate bestcomm tasks\n");
-		iounmap(regs);
-		kfree(psc_dma);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto out_free;
 	}
 
 	/* Disable all interrupts and reset the PSC */
@@ -537,12 +539,8 @@ int mpc5200_audio_dma_create(struct of_device *op)
 			  &psc_dma_bcom_irq_tx, IRQF_SHARED,
 			  "psc-dma-playback", &psc_dma->playback);
 	if (rc) {
-		free_irq(psc_dma->irq, psc_dma);
-		free_irq(psc_dma->capture.irq,
-			 &psc_dma->capture);
-		free_irq(psc_dma->playback.irq,
-			 &psc_dma->playback);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto out_irq;
 	}
 
 	/* Save what we've done so it can be found again later */
@@ -550,6 +548,15 @@ int mpc5200_audio_dma_create(struct of_device *op)
 
 	/* Tell the ASoC OF helpers about it */
 	return snd_soc_register_platform(&mpc5200_audio_dma_platform);
+out_irq:
+	free_irq(psc_dma->irq, psc_dma);
+	free_irq(psc_dma->capture.irq, &psc_dma->capture);
+	free_irq(psc_dma->playback.irq, &psc_dma->playback);
+out_free:
+	kfree(psc_dma);
+out_unmap:
+	iounmap(regs);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
 
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index aa7af0b..9bc4aa3 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -230,6 +230,8 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
 	pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic);
 }
 
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
 /*
  * Wait for the LR signal to allow synchronisation to the L/R clock
  * from the codec. May only be needed for slave mode.
@@ -237,19 +239,21 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on)
 static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s)
 {
 	u32 iiscon;
-	unsigned long timeout = jiffies + msecs_to_jiffies(5);
+	unsigned long loops = msecs_to_loops(5);
 
 	pr_debug("Entered %s\n", __func__);
 
-	while (1) {
+	while (--loops) {
 		iiscon = readl(i2s->regs + S3C2412_IISCON);
 		if (iiscon & S3C2412_IISCON_LRINDEX)
 			break;
 
-		if (timeout < jiffies) {
-			printk(KERN_ERR "%s: timeout\n", __func__);
-			return -ETIMEDOUT;
-		}
+		cpu_relax();
+	}
+
+	if (!loops) {
+		printk(KERN_ERR "%s: timeout\n", __func__);
+		return -ETIMEDOUT;
 	}
 
 	return 0;
diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h
index a96dcad..e96f941 100644
--- a/sound/soc/s3c24xx/s3c24xx-ac97.h
+++ b/sound/soc/s3c24xx/s3c24xx-ac97.h
@@ -20,12 +20,6 @@
 #define AC_CMD_ADDR(x) (x << 16)
 #define AC_CMD_DATA(x) (x & 0xffff)
 
-#ifdef CONFIG_CPU_S3C2440
-#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
-#else
-#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97
-#endif
-
 extern struct snd_soc_dai s3c2443_ac97_dai[];
 
 #endif /*S3C24XXAC97_H_*/
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 0d8b08e..f79711b 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1131,9 +1131,10 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
 	ret = snprintf(buf, PAGE_SIZE, "%s: %s  in %d out %d\n",
 		       w->name, w->power ? "On" : "Off", in, out);
 
-	if (w->active && w->sname)
-		ret += snprintf(buf, PAGE_SIZE - ret, " stream %s active\n",
-				w->sname);
+	if (w->sname)
+		ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
+				w->sname,
+				w->active ? "active" : "inactive");
 
 	list_for_each_entry(p, &w->sources, list_sink) {
 		if (p->connect)
diff --git a/sound/sound_core.c b/sound/sound_core.c
index bb4b88e..49c9981 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Core sound module");
 MODULE_AUTHOR("Alan Cox");
 MODULE_LICENSE("GPL");
 
-static char *sound_nodename(struct device *dev)
+static char *sound_devnode(struct device *dev, mode_t *mode)
 {
 	if (MAJOR(dev->devt) == SOUND_MAJOR)
 		return NULL;
@@ -50,7 +50,7 @@ static int __init init_soundcore(void)
 		return PTR_ERR(sound_class);
 	}
 
-	sound_class->nodename = sound_nodename;
+	sound_class->devnode = sound_devnode;
 
 	return 0;
 }
diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt
new file mode 100644
index 0000000..1ce7919
--- /dev/null
+++ b/tools/perf/Documentation/perf-sched.txt
@@ -0,0 +1,41 @@
+perf-sched(1)
+==============
+
+NAME
+----
+perf-sched - Tool to trace/measure scheduler properties (latencies)
+
+SYNOPSIS
+--------
+[verse]
+'perf sched' {record|latency|replay|trace}
+
+DESCRIPTION
+-----------
+There's four variants of perf sched:
+
+  'perf sched record <command>' to record the scheduling events
+  of an arbitrary workload.
+
+  'perf sched latency' to report the per task scheduling latencies
+  and other scheduling properties of the workload.
+
+  'perf sched trace' to see a detailed trace of the workload that
+  was recorded.
+
+  'perf sched replay' to simulate the workload that was recorded
+  via perf sched record. (this is done by starting up mockup threads
+  that mimic the workload based on the events in the trace. These
+  threads can then replay the timings (CPU runtime and sleep patterns)
+  of the workload as it occured when it was recorded - and can repeat
+  it a number of times, measuring its performance.)
+
+OPTIONS
+-------
+-D::
+--dump-raw-trace=::
+        Display verbose dump of the sched data.
+
+SEE ALSO
+--------
+linkperf:perf-record[1]
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
new file mode 100644
index 0000000..1c2ed30
--- /dev/null
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -0,0 +1,38 @@
+perf-timechart(1)
+=================
+
+NAME
+----
+perf-timechart - Tool to visualize total system behavior during a workload
+
+SYNOPSIS
+--------
+[verse]
+'perf timechart' {record}
+
+DESCRIPTION
+-----------
+There are two variants of perf timechart:
+
+  'perf timechart record <command>' to record the system level events
+  of an arbitrary workload.
+
+  'perf timechart' to turn a trace into a Scalable Vector Graphics file,
+  that can be viewed with popular SVG viewers such as 'Inkscape'.
+
+OPTIONS
+-------
+-o::
+--output=::
+        Select the output file (default: output.svg)
+-i::
+--input=::
+        Select the input file (default: perf.data)
+-w::
+--width=::
+        Select the width of the SVG file (default: 1000)
+
+
+SEE ALSO
+--------
+linkperf:perf-record[1]
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
new file mode 100644
index 0000000..41ed753
--- /dev/null
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -0,0 +1,25 @@
+perf-trace(1)
+==============
+
+NAME
+----
+perf-trace - Read perf.data (created by perf record) and display trace output
+
+SYNOPSIS
+--------
+[verse]
+'perf trace' [-i <file> | --input=file] symbol_name
+
+DESCRIPTION
+-----------
+This command reads the input file and displays the trace recorded.
+
+OPTIONS
+-------
+-D::
+--dump-raw-trace=::
+        Display verbose dump of the trace data.
+
+SEE ALSO
+--------
+linkperf:perf-record[1]
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 9f8d207..b5f1953 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -318,7 +318,7 @@ export PERL_PATH
 
 LIB_FILE=libperf.a
 
-LIB_H += ../../include/linux/perf_counter.h
+LIB_H += ../../include/linux/perf_event.h
 LIB_H += ../../include/linux/rbtree.h
 LIB_H += ../../include/linux/list.h
 LIB_H += util/include/linux/list.h
@@ -373,13 +373,16 @@ LIB_OBJS += util/thread.o
 LIB_OBJS += util/trace-event-parse.o
 LIB_OBJS += util/trace-event-read.o
 LIB_OBJS += util/trace-event-info.o
+LIB_OBJS += util/svghelper.o
 
 BUILTIN_OBJS += builtin-annotate.o
 BUILTIN_OBJS += builtin-help.o
+BUILTIN_OBJS += builtin-sched.o
 BUILTIN_OBJS += builtin-list.o
 BUILTIN_OBJS += builtin-record.o
 BUILTIN_OBJS += builtin-report.o
 BUILTIN_OBJS += builtin-stat.o
+BUILTIN_OBJS += builtin-timechart.o
 BUILTIN_OBJS += builtin-top.o
 BUILTIN_OBJS += builtin-trace.o
 
@@ -710,6 +713,12 @@ builtin-help.o: builtin-help.c common-cmds.h PERF-CFLAGS
 		'-DPERF_MAN_PATH="$(mandir_SQ)"' \
 		'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
 
+builtin-timechart.o: builtin-timechart.c common-cmds.h PERF-CFLAGS
+	$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
+		'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
+		'-DPERF_MAN_PATH="$(mandir_SQ)"' \
+		'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
+
 $(BUILT_INS): perf$X
 	$(QUIET_BUILT_IN)$(RM) $@ && \
 	ln perf$X $@ 2>/dev/null || \
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 043d85b..1ec7416 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -505,7 +505,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 		return -1;
 	}
 
-	if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
+	if (event->header.misc & PERF_RECORD_MISC_KERNEL) {
 		show = SHOW_KERNEL;
 		level = 'k';
 
@@ -513,7 +513,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 
 		dump_printf(" ...... dso: %s\n", dso->name);
 
-	} else if (event->header.misc & PERF_EVENT_MISC_USER) {
+	} else if (event->header.misc & PERF_RECORD_MISC_USER) {
 
 		show = SHOW_USER;
 		level = '.';
@@ -565,7 +565,7 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
 
 	thread = threads__findnew(event->mmap.pid, &threads, &last_match);
 
-	dump_printf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
+	dump_printf("%p [%p]: PERF_RECORD_MMAP %d: [%p(%p) @ %p]: %s\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->mmap.pid,
@@ -575,7 +575,7 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
 		event->mmap.filename);
 
 	if (thread == NULL || map == NULL) {
-		dump_printf("problem processing PERF_EVENT_MMAP, skipping event.\n");
+		dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
 		return 0;
 	}
 
@@ -591,14 +591,14 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
 	struct thread *thread;
 
 	thread = threads__findnew(event->comm.pid, &threads, &last_match);
-	dump_printf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
+	dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->comm.comm, event->comm.pid);
 
 	if (thread == NULL ||
 	    thread__set_comm(thread, event->comm.comm)) {
-		dump_printf("problem processing PERF_EVENT_COMM, skipping event.\n");
+		dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
 		return -1;
 	}
 	total_comm++;
@@ -614,7 +614,7 @@ process_fork_event(event_t *event, unsigned long offset, unsigned long head)
 
 	thread = threads__findnew(event->fork.pid, &threads, &last_match);
 	parent = threads__findnew(event->fork.ppid, &threads, &last_match);
-	dump_printf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
+	dump_printf("%p [%p]: PERF_RECORD_FORK: %d:%d\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->fork.pid, event->fork.ppid);
@@ -627,7 +627,7 @@ process_fork_event(event_t *event, unsigned long offset, unsigned long head)
 		return 0;
 
 	if (!thread || !parent || thread__fork(thread, parent)) {
-		dump_printf("problem processing PERF_EVENT_FORK, skipping event.\n");
+		dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
 		return -1;
 	}
 	total_fork++;
@@ -639,23 +639,23 @@ static int
 process_event(event_t *event, unsigned long offset, unsigned long head)
 {
 	switch (event->header.type) {
-	case PERF_EVENT_SAMPLE:
+	case PERF_RECORD_SAMPLE:
 		return process_sample_event(event, offset, head);
 
-	case PERF_EVENT_MMAP:
+	case PERF_RECORD_MMAP:
 		return process_mmap_event(event, offset, head);
 
-	case PERF_EVENT_COMM:
+	case PERF_RECORD_COMM:
 		return process_comm_event(event, offset, head);
 
-	case PERF_EVENT_FORK:
+	case PERF_RECORD_FORK:
 		return process_fork_event(event, offset, head);
 	/*
 	 * We dont process them right now but they are fine:
 	 */
 
-	case PERF_EVENT_THROTTLE:
-	case PERF_EVENT_UNTHROTTLE:
+	case PERF_RECORD_THROTTLE:
+	case PERF_RECORD_UNTHROTTLE:
 		return 0;
 
 	default:
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 99a12fe..a5a050a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -48,6 +48,8 @@ static int			call_graph			= 0;
 static int			inherit_stat			= 0;
 static int			no_samples			= 0;
 static int			sample_address			= 0;
+static int			multiplex			= 0;
+static int			multiplex_fd			= -1;
 
 static long			samples;
 static struct timeval		last_read;
@@ -75,7 +77,7 @@ static struct mmap_data		mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
 
 static unsigned long mmap_read_head(struct mmap_data *md)
 {
-	struct perf_counter_mmap_page *pc = md->base;
+	struct perf_event_mmap_page *pc = md->base;
 	long head;
 
 	head = pc->data_head;
@@ -86,7 +88,7 @@ static unsigned long mmap_read_head(struct mmap_data *md)
 
 static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
 {
-	struct perf_counter_mmap_page *pc = md->base;
+	struct perf_event_mmap_page *pc = md->base;
 
 	/*
 	 * ensure all reads are done before we write the tail out.
@@ -231,7 +233,7 @@ static pid_t pid_synthesize_comm_event(pid_t pid, int full)
 		}
 	}
 
-	comm_ev.header.type = PERF_EVENT_COMM;
+	comm_ev.header.type = PERF_RECORD_COMM;
 	size = ALIGN(size, sizeof(u64));
 	comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size);
 
@@ -286,7 +288,7 @@ static void pid_synthesize_mmap_samples(pid_t pid, pid_t tgid)
 	while (1) {
 		char bf[BUFSIZ], *pbf = bf;
 		struct mmap_event mmap_ev = {
-			.header = { .type = PERF_EVENT_MMAP },
+			.header = { .type = PERF_RECORD_MMAP },
 		};
 		int n;
 		size_t size;
@@ -353,7 +355,7 @@ static void synthesize_all(void)
 
 static int group_fd;
 
-static struct perf_header_attr *get_header_attr(struct perf_counter_attr *a, int nr)
+static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr)
 {
 	struct perf_header_attr *h_attr;
 
@@ -369,7 +371,7 @@ static struct perf_header_attr *get_header_attr(struct perf_counter_attr *a, int
 
 static void create_counter(int counter, int cpu, pid_t pid)
 {
-	struct perf_counter_attr *attr = attrs + counter;
+	struct perf_event_attr *attr = attrs + counter;
 	struct perf_header_attr *h_attr;
 	int track = !counter; /* only the first counter needs these */
 	struct {
@@ -415,7 +417,7 @@ static void create_counter(int counter, int cpu, pid_t pid)
 	attr->disabled		= 1;
 
 try_again:
-	fd[nr_cpu][counter] = sys_perf_counter_open(attr, pid, cpu, group_fd, 0);
+	fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0);
 
 	if (fd[nr_cpu][counter] < 0) {
 		int err = errno;
@@ -442,7 +444,7 @@ try_again:
 		printf("\n");
 		error("perfcounter syscall returned with %d (%s)\n",
 			fd[nr_cpu][counter], strerror(err));
-		die("No CONFIG_PERF_COUNTERS=y kernel support configured?\n");
+		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
 		exit(-1);
 	}
 
@@ -470,22 +472,31 @@ try_again:
 	 */
 	if (group && group_fd == -1)
 		group_fd = fd[nr_cpu][counter];
+	if (multiplex && multiplex_fd == -1)
+		multiplex_fd = fd[nr_cpu][counter];
 
-	event_array[nr_poll].fd = fd[nr_cpu][counter];
-	event_array[nr_poll].events = POLLIN;
-	nr_poll++;
-
-	mmap_array[nr_cpu][counter].counter = counter;
-	mmap_array[nr_cpu][counter].prev = 0;
-	mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
-	mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
-			PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0);
-	if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
-		error("failed to mmap with %d (%s)\n", errno, strerror(errno));
-		exit(-1);
+	if (multiplex && fd[nr_cpu][counter] != multiplex_fd) {
+		int ret;
+
+		ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
+		assert(ret != -1);
+	} else {
+		event_array[nr_poll].fd = fd[nr_cpu][counter];
+		event_array[nr_poll].events = POLLIN;
+		nr_poll++;
+
+		mmap_array[nr_cpu][counter].counter = counter;
+		mmap_array[nr_cpu][counter].prev = 0;
+		mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1;
+		mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size,
+				PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0);
+		if (mmap_array[nr_cpu][counter].base == MAP_FAILED) {
+			error("failed to mmap with %d (%s)\n", errno, strerror(errno));
+			exit(-1);
+		}
 	}
 
-	ioctl(fd[nr_cpu][counter], PERF_COUNTER_IOC_ENABLE);
+	ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
 }
 
 static void open_counters(int cpu, pid_t pid)
@@ -513,6 +524,7 @@ static int __cmd_record(int argc, const char **argv)
 	pid_t pid = 0;
 	int flags;
 	int ret;
+	unsigned long waking = 0;
 
 	page_size = sysconf(_SC_PAGE_SIZE);
 	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
@@ -614,17 +626,29 @@ static int __cmd_record(int argc, const char **argv)
 		int hits = samples;
 
 		for (i = 0; i < nr_cpu; i++) {
-			for (counter = 0; counter < nr_counters; counter++)
-				mmap_read(&mmap_array[i][counter]);
+			for (counter = 0; counter < nr_counters; counter++) {
+				if (mmap_array[i][counter].base)
+					mmap_read(&mmap_array[i][counter]);
+			}
 		}
 
 		if (hits == samples) {
 			if (done)
 				break;
-			ret = poll(event_array, nr_poll, 100);
+			ret = poll(event_array, nr_poll, -1);
+			waking++;
+		}
+
+		if (done) {
+			for (i = 0; i < nr_cpu; i++) {
+				for (counter = 0; counter < nr_counters; counter++)
+					ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE);
+			}
 		}
 	}
 
+	fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
+
 	/*
 	 * Approximate RIP event size: 24 bytes.
 	 */
@@ -681,6 +705,8 @@ static const struct option options[] = {
 		    "Sample addresses"),
 	OPT_BOOLEAN('n', "no-samples", &no_samples,
 		    "don't sample"),
+	OPT_BOOLEAN('M', "multiplex", &multiplex,
+		    "multiplex counter output in a single channel"),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index cdf9a8d..19669c2 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -1121,7 +1121,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 		more_data += sizeof(u64);
 	}
 
-	dump_printf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
+	dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->header.misc,
@@ -1158,9 +1158,9 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 	if (comm_list && !strlist__has_entry(comm_list, thread->comm))
 		return 0;
 
-	cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
+	cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
-	if (cpumode == PERF_EVENT_MISC_KERNEL) {
+	if (cpumode == PERF_RECORD_MISC_KERNEL) {
 		show = SHOW_KERNEL;
 		level = 'k';
 
@@ -1168,7 +1168,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 
 		dump_printf(" ...... dso: %s\n", dso->name);
 
-	} else if (cpumode == PERF_EVENT_MISC_USER) {
+	} else if (cpumode == PERF_RECORD_MISC_USER) {
 
 		show = SHOW_USER;
 		level = '.';
@@ -1210,7 +1210,7 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
 
 	thread = threads__findnew(event->mmap.pid, &threads, &last_match);
 
-	dump_printf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
+	dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->mmap.pid,
@@ -1221,7 +1221,7 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
 		event->mmap.filename);
 
 	if (thread == NULL || map == NULL) {
-		dump_printf("problem processing PERF_EVENT_MMAP, skipping event.\n");
+		dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
 		return 0;
 	}
 
@@ -1238,14 +1238,14 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
 
 	thread = threads__findnew(event->comm.pid, &threads, &last_match);
 
-	dump_printf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
+	dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->comm.comm, event->comm.pid);
 
 	if (thread == NULL ||
 	    thread__set_comm_adjust(thread, event->comm.comm)) {
-		dump_printf("problem processing PERF_EVENT_COMM, skipping event.\n");
+		dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
 		return -1;
 	}
 	total_comm++;
@@ -1262,10 +1262,10 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head)
 	thread = threads__findnew(event->fork.pid, &threads, &last_match);
 	parent = threads__findnew(event->fork.ppid, &threads, &last_match);
 
-	dump_printf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n",
+	dump_printf("%p [%p]: PERF_RECORD_%s: (%d:%d):(%d:%d)\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
-		event->header.type == PERF_EVENT_FORK ? "FORK" : "EXIT",
+		event->header.type == PERF_RECORD_FORK ? "FORK" : "EXIT",
 		event->fork.pid, event->fork.tid,
 		event->fork.ppid, event->fork.ptid);
 
@@ -1276,11 +1276,11 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head)
 	if (thread == parent)
 		return 0;
 
-	if (event->header.type == PERF_EVENT_EXIT)
+	if (event->header.type == PERF_RECORD_EXIT)
 		return 0;
 
 	if (!thread || !parent || thread__fork(thread, parent)) {
-		dump_printf("problem processing PERF_EVENT_FORK, skipping event.\n");
+		dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
 		return -1;
 	}
 	total_fork++;
@@ -1291,7 +1291,7 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head)
 static int
 process_lost_event(event_t *event, unsigned long offset, unsigned long head)
 {
-	dump_printf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n",
+	dump_printf("%p [%p]: PERF_RECORD_LOST: id:%Ld: lost:%Ld\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->lost.id,
@@ -1305,7 +1305,7 @@ process_lost_event(event_t *event, unsigned long offset, unsigned long head)
 static int
 process_read_event(event_t *event, unsigned long offset, unsigned long head)
 {
-	struct perf_counter_attr *attr;
+	struct perf_event_attr *attr;
 
 	attr = perf_header__find_attr(event->read.id, header);
 
@@ -1319,7 +1319,7 @@ process_read_event(event_t *event, unsigned long offset, unsigned long head)
 					   event->read.value);
 	}
 
-	dump_printf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n",
+	dump_printf("%p [%p]: PERF_RECORD_READ: %d %d %s %Lu\n",
 			(void *)(offset + head),
 			(void *)(long)(event->header.size),
 			event->read.pid,
@@ -1337,31 +1337,31 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
 	trace_event(event);
 
 	switch (event->header.type) {
-	case PERF_EVENT_SAMPLE:
+	case PERF_RECORD_SAMPLE:
 		return process_sample_event(event, offset, head);
 
-	case PERF_EVENT_MMAP:
+	case PERF_RECORD_MMAP:
 		return process_mmap_event(event, offset, head);
 
-	case PERF_EVENT_COMM:
+	case PERF_RECORD_COMM:
 		return process_comm_event(event, offset, head);
 
-	case PERF_EVENT_FORK:
-	case PERF_EVENT_EXIT:
+	case PERF_RECORD_FORK:
+	case PERF_RECORD_EXIT:
 		return process_task_event(event, offset, head);
 
-	case PERF_EVENT_LOST:
+	case PERF_RECORD_LOST:
 		return process_lost_event(event, offset, head);
 
-	case PERF_EVENT_READ:
+	case PERF_RECORD_READ:
 		return process_read_event(event, offset, head);
 
 	/*
 	 * We dont process them right now but they are fine:
 	 */
 
-	case PERF_EVENT_THROTTLE:
-	case PERF_EVENT_UNTHROTTLE:
+	case PERF_RECORD_THROTTLE:
+	case PERF_RECORD_UNTHROTTLE:
 		return 0;
 
 	default:
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
new file mode 100644
index 0000000..ea9c15c
--- /dev/null
+++ b/tools/perf/builtin-sched.c
@@ -0,0 +1,2004 @@
+#include "builtin.h"
+#include "perf.h"
+
+#include "util/util.h"
+#include "util/cache.h"
+#include "util/symbol.h"
+#include "util/thread.h"
+#include "util/header.h"
+
+#include "util/parse-options.h"
+#include "util/trace-event.h"
+
+#include "util/debug.h"
+
+#include <sys/types.h>
+#include <sys/prctl.h>
+
+#include <semaphore.h>
+#include <pthread.h>
+#include <math.h>
+
+static char			const *input_name = "perf.data";
+static int			input;
+static unsigned long		page_size;
+static unsigned long		mmap_window = 32;
+
+static unsigned long		total_comm = 0;
+
+static struct rb_root		threads;
+static struct thread		*last_match;
+
+static struct perf_header	*header;
+static u64			sample_type;
+
+static char			default_sort_order[] = "avg, max, switch, runtime";
+static char			*sort_order = default_sort_order;
+
+#define PR_SET_NAME		15               /* Set process name */
+#define MAX_CPUS		4096
+
+#define BUG_ON(x)		assert(!(x))
+
+static u64			run_measurement_overhead;
+static u64			sleep_measurement_overhead;
+
+#define COMM_LEN		20
+#define SYM_LEN			129
+
+#define MAX_PID			65536
+
+static unsigned long		nr_tasks;
+
+struct sched_atom;
+
+struct task_desc {
+	unsigned long		nr;
+	unsigned long		pid;
+	char			comm[COMM_LEN];
+
+	unsigned long		nr_events;
+	unsigned long		curr_event;
+	struct sched_atom	**atoms;
+
+	pthread_t		thread;
+	sem_t			sleep_sem;
+
+	sem_t			ready_for_work;
+	sem_t			work_done_sem;
+
+	u64			cpu_usage;
+};
+
+enum sched_event_type {
+	SCHED_EVENT_RUN,
+	SCHED_EVENT_SLEEP,
+	SCHED_EVENT_WAKEUP,
+};
+
+struct sched_atom {
+	enum sched_event_type	type;
+	u64			timestamp;
+	u64			duration;
+	unsigned long		nr;
+	int			specific_wait;
+	sem_t			*wait_sem;
+	struct task_desc	*wakee;
+};
+
+static struct task_desc		*pid_to_task[MAX_PID];
+
+static struct task_desc		**tasks;
+
+static pthread_mutex_t		start_work_mutex = PTHREAD_MUTEX_INITIALIZER;
+static u64			start_time;
+
+static pthread_mutex_t		work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static unsigned long		nr_run_events;
+static unsigned long		nr_sleep_events;
+static unsigned long		nr_wakeup_events;
+
+static unsigned long		nr_sleep_corrections;
+static unsigned long		nr_run_events_optimized;
+
+static unsigned long		targetless_wakeups;
+static unsigned long		multitarget_wakeups;
+
+static u64			cpu_usage;
+static u64			runavg_cpu_usage;
+static u64			parent_cpu_usage;
+static u64			runavg_parent_cpu_usage;
+
+static unsigned long		nr_runs;
+static u64			sum_runtime;
+static u64			sum_fluct;
+static u64			run_avg;
+
+static unsigned long		replay_repeat = 10;
+static unsigned long		nr_timestamps;
+static unsigned long		nr_unordered_timestamps;
+static unsigned long		nr_state_machine_bugs;
+static unsigned long		nr_context_switch_bugs;
+static unsigned long		nr_events;
+static unsigned long		nr_lost_chunks;
+static unsigned long		nr_lost_events;
+
+#define TASK_STATE_TO_CHAR_STR "RSDTtZX"
+
+enum thread_state {
+	THREAD_SLEEPING = 0,
+	THREAD_WAIT_CPU,
+	THREAD_SCHED_IN,
+	THREAD_IGNORE
+};
+
+struct work_atom {
+	struct list_head	list;
+	enum thread_state	state;
+	u64			sched_out_time;
+	u64			wake_up_time;
+	u64			sched_in_time;
+	u64			runtime;
+};
+
+struct work_atoms {
+	struct list_head	work_list;
+	struct thread		*thread;
+	struct rb_node		node;
+	u64			max_lat;
+	u64			total_lat;
+	u64			nb_atoms;
+	u64			total_runtime;
+};
+
+typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *);
+
+static struct rb_root		atom_root, sorted_atom_root;
+
+static u64			all_runtime;
+static u64			all_count;
+
+
+static u64 get_nsecs(void)
+{
+	struct timespec ts;
+
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+
+	return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
+}
+
+static void burn_nsecs(u64 nsecs)
+{
+	u64 T0 = get_nsecs(), T1;
+
+	do {
+		T1 = get_nsecs();
+	} while (T1 + run_measurement_overhead < T0 + nsecs);
+}
+
+static void sleep_nsecs(u64 nsecs)
+{
+	struct timespec ts;
+
+	ts.tv_nsec = nsecs % 999999999;
+	ts.tv_sec = nsecs / 999999999;
+
+	nanosleep(&ts, NULL);
+}
+
+static void calibrate_run_measurement_overhead(void)
+{
+	u64 T0, T1, delta, min_delta = 1000000000ULL;
+	int i;
+
+	for (i = 0; i < 10; i++) {
+		T0 = get_nsecs();
+		burn_nsecs(0);
+		T1 = get_nsecs();
+		delta = T1-T0;
+		min_delta = min(min_delta, delta);
+	}
+	run_measurement_overhead = min_delta;
+
+	printf("run measurement overhead: %Ld nsecs\n", min_delta);
+}
+
+static void calibrate_sleep_measurement_overhead(void)
+{
+	u64 T0, T1, delta, min_delta = 1000000000ULL;
+	int i;
+
+	for (i = 0; i < 10; i++) {
+		T0 = get_nsecs();
+		sleep_nsecs(10000);
+		T1 = get_nsecs();
+		delta = T1-T0;
+		min_delta = min(min_delta, delta);
+	}
+	min_delta -= 10000;
+	sleep_measurement_overhead = min_delta;
+
+	printf("sleep measurement overhead: %Ld nsecs\n", min_delta);
+}
+
+static struct sched_atom *
+get_new_event(struct task_desc *task, u64 timestamp)
+{
+	struct sched_atom *event = calloc(1, sizeof(*event));
+	unsigned long idx = task->nr_events;
+	size_t size;
+
+	event->timestamp = timestamp;
+	event->nr = idx;
+
+	task->nr_events++;
+	size = sizeof(struct sched_atom *) * task->nr_events;
+	task->atoms = realloc(task->atoms, size);
+	BUG_ON(!task->atoms);
+
+	task->atoms[idx] = event;
+
+	return event;
+}
+
+static struct sched_atom *last_event(struct task_desc *task)
+{
+	if (!task->nr_events)
+		return NULL;
+
+	return task->atoms[task->nr_events - 1];
+}
+
+static void
+add_sched_event_run(struct task_desc *task, u64 timestamp, u64 duration)
+{
+	struct sched_atom *event, *curr_event = last_event(task);
+
+	/*
+	 * optimize an existing RUN event by merging this one
+	 * to it:
+	 */
+	if (curr_event && curr_event->type == SCHED_EVENT_RUN) {
+		nr_run_events_optimized++;
+		curr_event->duration += duration;
+		return;
+	}
+
+	event = get_new_event(task, timestamp);
+
+	event->type = SCHED_EVENT_RUN;
+	event->duration = duration;
+
+	nr_run_events++;
+}
+
+static void
+add_sched_event_wakeup(struct task_desc *task, u64 timestamp,
+		       struct task_desc *wakee)
+{
+	struct sched_atom *event, *wakee_event;
+
+	event = get_new_event(task, timestamp);
+	event->type = SCHED_EVENT_WAKEUP;
+	event->wakee = wakee;
+
+	wakee_event = last_event(wakee);
+	if (!wakee_event || wakee_event->type != SCHED_EVENT_SLEEP) {
+		targetless_wakeups++;
+		return;
+	}
+	if (wakee_event->wait_sem) {
+		multitarget_wakeups++;
+		return;
+	}
+
+	wakee_event->wait_sem = calloc(1, sizeof(*wakee_event->wait_sem));
+	sem_init(wakee_event->wait_sem, 0, 0);
+	wakee_event->specific_wait = 1;
+	event->wait_sem = wakee_event->wait_sem;
+
+	nr_wakeup_events++;
+}
+
+static void
+add_sched_event_sleep(struct task_desc *task, u64 timestamp,
+		      u64 task_state __used)
+{
+	struct sched_atom *event = get_new_event(task, timestamp);
+
+	event->type = SCHED_EVENT_SLEEP;
+
+	nr_sleep_events++;
+}
+
+static struct task_desc *register_pid(unsigned long pid, const char *comm)
+{
+	struct task_desc *task;
+
+	BUG_ON(pid >= MAX_PID);
+
+	task = pid_to_task[pid];
+
+	if (task)
+		return task;
+
+	task = calloc(1, sizeof(*task));
+	task->pid = pid;
+	task->nr = nr_tasks;
+	strcpy(task->comm, comm);
+	/*
+	 * every task starts in sleeping state - this gets ignored
+	 * if there's no wakeup pointing to this sleep state:
+	 */
+	add_sched_event_sleep(task, 0, 0);
+
+	pid_to_task[pid] = task;
+	nr_tasks++;
+	tasks = realloc(tasks, nr_tasks*sizeof(struct task_task *));
+	BUG_ON(!tasks);
+	tasks[task->nr] = task;
+
+	if (verbose)
+		printf("registered task #%ld, PID %ld (%s)\n", nr_tasks, pid, comm);
+
+	return task;
+}
+
+
+static void print_task_traces(void)
+{
+	struct task_desc *task;
+	unsigned long i;
+
+	for (i = 0; i < nr_tasks; i++) {
+		task = tasks[i];
+		printf("task %6ld (%20s:%10ld), nr_events: %ld\n",
+			task->nr, task->comm, task->pid, task->nr_events);
+	}
+}
+
+static void add_cross_task_wakeups(void)
+{
+	struct task_desc *task1, *task2;
+	unsigned long i, j;
+
+	for (i = 0; i < nr_tasks; i++) {
+		task1 = tasks[i];
+		j = i + 1;
+		if (j == nr_tasks)
+			j = 0;
+		task2 = tasks[j];
+		add_sched_event_wakeup(task1, 0, task2);
+	}
+}
+
+static void
+process_sched_event(struct task_desc *this_task __used, struct sched_atom *atom)
+{
+	int ret = 0;
+	u64 now;
+	long long delta;
+
+	now = get_nsecs();
+	delta = start_time + atom->timestamp - now;
+
+	switch (atom->type) {
+		case SCHED_EVENT_RUN:
+			burn_nsecs(atom->duration);
+			break;
+		case SCHED_EVENT_SLEEP:
+			if (atom->wait_sem)
+				ret = sem_wait(atom->wait_sem);
+			BUG_ON(ret);
+			break;
+		case SCHED_EVENT_WAKEUP:
+			if (atom->wait_sem)
+				ret = sem_post(atom->wait_sem);
+			BUG_ON(ret);
+			break;
+		default:
+			BUG_ON(1);
+	}
+}
+
+static u64 get_cpu_usage_nsec_parent(void)
+{
+	struct rusage ru;
+	u64 sum;
+	int err;
+
+	err = getrusage(RUSAGE_SELF, &ru);
+	BUG_ON(err);
+
+	sum =  ru.ru_utime.tv_sec*1e9 + ru.ru_utime.tv_usec*1e3;
+	sum += ru.ru_stime.tv_sec*1e9 + ru.ru_stime.tv_usec*1e3;
+
+	return sum;
+}
+
+static u64 get_cpu_usage_nsec_self(void)
+{
+	char filename [] = "/proc/1234567890/sched";
+	unsigned long msecs, nsecs;
+	char *line = NULL;
+	u64 total = 0;
+	size_t len = 0;
+	ssize_t chars;
+	FILE *file;
+	int ret;
+
+	sprintf(filename, "/proc/%d/sched", getpid());
+	file = fopen(filename, "r");
+	BUG_ON(!file);
+
+	while ((chars = getline(&line, &len, file)) != -1) {
+		ret = sscanf(line, "se.sum_exec_runtime : %ld.%06ld\n",
+			&msecs, &nsecs);
+		if (ret == 2) {
+			total = msecs*1e6 + nsecs;
+			break;
+		}
+	}
+	if (line)
+		free(line);
+	fclose(file);
+
+	return total;
+}
+
+static void *thread_func(void *ctx)
+{
+	struct task_desc *this_task = ctx;
+	u64 cpu_usage_0, cpu_usage_1;
+	unsigned long i, ret;
+	char comm2[22];
+
+	sprintf(comm2, ":%s", this_task->comm);
+	prctl(PR_SET_NAME, comm2);
+
+again:
+	ret = sem_post(&this_task->ready_for_work);
+	BUG_ON(ret);
+	ret = pthread_mutex_lock(&start_work_mutex);
+	BUG_ON(ret);
+	ret = pthread_mutex_unlock(&start_work_mutex);
+	BUG_ON(ret);
+
+	cpu_usage_0 = get_cpu_usage_nsec_self();
+
+	for (i = 0; i < this_task->nr_events; i++) {
+		this_task->curr_event = i;
+		process_sched_event(this_task, this_task->atoms[i]);
+	}
+
+	cpu_usage_1 = get_cpu_usage_nsec_self();
+	this_task->cpu_usage = cpu_usage_1 - cpu_usage_0;
+
+	ret = sem_post(&this_task->work_done_sem);
+	BUG_ON(ret);
+
+	ret = pthread_mutex_lock(&work_done_wait_mutex);
+	BUG_ON(ret);
+	ret = pthread_mutex_unlock(&work_done_wait_mutex);
+	BUG_ON(ret);
+
+	goto again;
+}
+
+static void create_tasks(void)
+{
+	struct task_desc *task;
+	pthread_attr_t attr;
+	unsigned long i;
+	int err;
+
+	err = pthread_attr_init(&attr);
+	BUG_ON(err);
+	err = pthread_attr_setstacksize(&attr, (size_t)(16*1024));
+	BUG_ON(err);
+	err = pthread_mutex_lock(&start_work_mutex);
+	BUG_ON(err);
+	err = pthread_mutex_lock(&work_done_wait_mutex);
+	BUG_ON(err);
+	for (i = 0; i < nr_tasks; i++) {
+		task = tasks[i];
+		sem_init(&task->sleep_sem, 0, 0);
+		sem_init(&task->ready_for_work, 0, 0);
+		sem_init(&task->work_done_sem, 0, 0);
+		task->curr_event = 0;
+		err = pthread_create(&task->thread, &attr, thread_func, task);
+		BUG_ON(err);
+	}
+}
+
+static void wait_for_tasks(void)
+{
+	u64 cpu_usage_0, cpu_usage_1;
+	struct task_desc *task;
+	unsigned long i, ret;
+
+	start_time = get_nsecs();
+	cpu_usage = 0;
+	pthread_mutex_unlock(&work_done_wait_mutex);
+
+	for (i = 0; i < nr_tasks; i++) {
+		task = tasks[i];
+		ret = sem_wait(&task->ready_for_work);
+		BUG_ON(ret);
+		sem_init(&task->ready_for_work, 0, 0);
+	}
+	ret = pthread_mutex_lock(&work_done_wait_mutex);
+	BUG_ON(ret);
+
+	cpu_usage_0 = get_cpu_usage_nsec_parent();
+
+	pthread_mutex_unlock(&start_work_mutex);
+
+	for (i = 0; i < nr_tasks; i++) {
+		task = tasks[i];
+		ret = sem_wait(&task->work_done_sem);
+		BUG_ON(ret);
+		sem_init(&task->work_done_sem, 0, 0);
+		cpu_usage += task->cpu_usage;
+		task->cpu_usage = 0;
+	}
+
+	cpu_usage_1 = get_cpu_usage_nsec_parent();
+	if (!runavg_cpu_usage)
+		runavg_cpu_usage = cpu_usage;
+	runavg_cpu_usage = (runavg_cpu_usage*9 + cpu_usage)/10;
+
+	parent_cpu_usage = cpu_usage_1 - cpu_usage_0;
+	if (!runavg_parent_cpu_usage)
+		runavg_parent_cpu_usage = parent_cpu_usage;
+	runavg_parent_cpu_usage = (runavg_parent_cpu_usage*9 +
+				   parent_cpu_usage)/10;
+
+	ret = pthread_mutex_lock(&start_work_mutex);
+	BUG_ON(ret);
+
+	for (i = 0; i < nr_tasks; i++) {
+		task = tasks[i];
+		sem_init(&task->sleep_sem, 0, 0);
+		task->curr_event = 0;
+	}
+}
+
+static void run_one_test(void)
+{
+	u64 T0, T1, delta, avg_delta, fluct, std_dev;
+
+	T0 = get_nsecs();
+	wait_for_tasks();
+	T1 = get_nsecs();
+
+	delta = T1 - T0;
+	sum_runtime += delta;
+	nr_runs++;
+
+	avg_delta = sum_runtime / nr_runs;
+	if (delta < avg_delta)
+		fluct = avg_delta - delta;
+	else
+		fluct = delta - avg_delta;
+	sum_fluct += fluct;
+	std_dev = sum_fluct / nr_runs / sqrt(nr_runs);
+	if (!run_avg)
+		run_avg = delta;
+	run_avg = (run_avg*9 + delta)/10;
+
+	printf("#%-3ld: %0.3f, ",
+		nr_runs, (double)delta/1000000.0);
+
+	printf("ravg: %0.2f, ",
+		(double)run_avg/1e6);
+
+	printf("cpu: %0.2f / %0.2f",
+		(double)cpu_usage/1e6, (double)runavg_cpu_usage/1e6);
+
+#if 0
+	/*
+	 * rusage statistics done by the parent, these are less
+	 * accurate than the sum_exec_runtime based statistics:
+	 */
+	printf(" [%0.2f / %0.2f]",
+		(double)parent_cpu_usage/1e6,
+		(double)runavg_parent_cpu_usage/1e6);
+#endif
+
+	printf("\n");
+
+	if (nr_sleep_corrections)
+		printf(" (%ld sleep corrections)\n", nr_sleep_corrections);
+	nr_sleep_corrections = 0;
+}
+
+static void test_calibrations(void)
+{
+	u64 T0, T1;
+
+	T0 = get_nsecs();
+	burn_nsecs(1e6);
+	T1 = get_nsecs();
+
+	printf("the run test took %Ld nsecs\n", T1-T0);
+
+	T0 = get_nsecs();
+	sleep_nsecs(1e6);
+	T1 = get_nsecs();
+
+	printf("the sleep test took %Ld nsecs\n", T1-T0);
+}
+
+static int
+process_comm_event(event_t *event, unsigned long offset, unsigned long head)
+{
+	struct thread *thread;
+
+	thread = threads__findnew(event->comm.pid, &threads, &last_match);
+
+	dump_printf("%p [%p]: perf_event_comm: %s:%d\n",
+		(void *)(offset + head),
+		(void *)(long)(event->header.size),
+		event->comm.comm, event->comm.pid);
+
+	if (thread == NULL ||
+	    thread__set_comm(thread, event->comm.comm)) {
+		dump_printf("problem processing perf_event_comm, skipping event.\n");
+		return -1;
+	}
+	total_comm++;
+
+	return 0;
+}
+
+
+struct raw_event_sample {
+	u32 size;
+	char data[0];
+};
+
+#define FILL_FIELD(ptr, field, event, data)	\
+	ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data)
+
+#define FILL_ARRAY(ptr, array, event, data)			\
+do {								\
+	void *__array = raw_field_ptr(event, #array, data);	\
+	memcpy(ptr.array, __array, sizeof(ptr.array));	\
+} while(0)
+
+#define FILL_COMMON_FIELDS(ptr, event, data)			\
+do {								\
+	FILL_FIELD(ptr, common_type, event, data);		\
+	FILL_FIELD(ptr, common_flags, event, data);		\
+	FILL_FIELD(ptr, common_preempt_count, event, data);	\
+	FILL_FIELD(ptr, common_pid, event, data);		\
+	FILL_FIELD(ptr, common_tgid, event, data);		\
+} while (0)
+
+
+
+struct trace_switch_event {
+	u32 size;
+
+	u16 common_type;
+	u8 common_flags;
+	u8 common_preempt_count;
+	u32 common_pid;
+	u32 common_tgid;
+
+	char prev_comm[16];
+	u32 prev_pid;
+	u32 prev_prio;
+	u64 prev_state;
+	char next_comm[16];
+	u32 next_pid;
+	u32 next_prio;
+};
+
+struct trace_runtime_event {
+	u32 size;
+
+	u16 common_type;
+	u8 common_flags;
+	u8 common_preempt_count;
+	u32 common_pid;
+	u32 common_tgid;
+
+	char comm[16];
+	u32 pid;
+	u64 runtime;
+	u64 vruntime;
+};
+
+struct trace_wakeup_event {
+	u32 size;
+
+	u16 common_type;
+	u8 common_flags;
+	u8 common_preempt_count;
+	u32 common_pid;
+	u32 common_tgid;
+
+	char comm[16];
+	u32 pid;
+
+	u32 prio;
+	u32 success;
+	u32 cpu;
+};
+
+struct trace_fork_event {
+	u32 size;
+
+	u16 common_type;
+	u8 common_flags;
+	u8 common_preempt_count;
+	u32 common_pid;
+	u32 common_tgid;
+
+	char parent_comm[16];
+	u32 parent_pid;
+	char child_comm[16];
+	u32 child_pid;
+};
+
+struct trace_sched_handler {
+	void (*switch_event)(struct trace_switch_event *,
+			     struct event *,
+			     int cpu,
+			     u64 timestamp,
+			     struct thread *thread);
+
+	void (*runtime_event)(struct trace_runtime_event *,
+			      struct event *,
+			      int cpu,
+			      u64 timestamp,
+			      struct thread *thread);
+
+	void (*wakeup_event)(struct trace_wakeup_event *,
+			     struct event *,
+			     int cpu,
+			     u64 timestamp,
+			     struct thread *thread);
+
+	void (*fork_event)(struct trace_fork_event *,
+			   struct event *,
+			   int cpu,
+			   u64 timestamp,
+			   struct thread *thread);
+};
+
+
+static void
+replay_wakeup_event(struct trace_wakeup_event *wakeup_event,
+		    struct event *event,
+		    int cpu __used,
+		    u64 timestamp __used,
+		    struct thread *thread __used)
+{
+	struct task_desc *waker, *wakee;
+
+	if (verbose) {
+		printf("sched_wakeup event %p\n", event);
+
+		printf(" ... pid %d woke up %s/%d\n",
+			wakeup_event->common_pid,
+			wakeup_event->comm,
+			wakeup_event->pid);
+	}
+
+	waker = register_pid(wakeup_event->common_pid, "<unknown>");
+	wakee = register_pid(wakeup_event->pid, wakeup_event->comm);
+
+	add_sched_event_wakeup(waker, timestamp, wakee);
+}
+
+static u64 cpu_last_switched[MAX_CPUS];
+
+static void
+replay_switch_event(struct trace_switch_event *switch_event,
+		    struct event *event,
+		    int cpu,
+		    u64 timestamp,
+		    struct thread *thread __used)
+{
+	struct task_desc *prev, *next;
+	u64 timestamp0;
+	s64 delta;
+
+	if (verbose)
+		printf("sched_switch event %p\n", event);
+
+	if (cpu >= MAX_CPUS || cpu < 0)
+		return;
+
+	timestamp0 = cpu_last_switched[cpu];
+	if (timestamp0)
+		delta = timestamp - timestamp0;
+	else
+		delta = 0;
+
+	if (delta < 0)
+		die("hm, delta: %Ld < 0 ?\n", delta);
+
+	if (verbose) {
+		printf(" ... switch from %s/%d to %s/%d [ran %Ld nsecs]\n",
+			switch_event->prev_comm, switch_event->prev_pid,
+			switch_event->next_comm, switch_event->next_pid,
+			delta);
+	}
+
+	prev = register_pid(switch_event->prev_pid, switch_event->prev_comm);
+	next = register_pid(switch_event->next_pid, switch_event->next_comm);
+
+	cpu_last_switched[cpu] = timestamp;
+
+	add_sched_event_run(prev, timestamp, delta);
+	add_sched_event_sleep(prev, timestamp, switch_event->prev_state);
+}
+
+
+static void
+replay_fork_event(struct trace_fork_event *fork_event,
+		  struct event *event,
+		  int cpu __used,
+		  u64 timestamp __used,
+		  struct thread *thread __used)
+{
+	if (verbose) {
+		printf("sched_fork event %p\n", event);
+		printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid);
+		printf("...  child: %s/%d\n", fork_event->child_comm, fork_event->child_pid);
+	}
+	register_pid(fork_event->parent_pid, fork_event->parent_comm);
+	register_pid(fork_event->child_pid, fork_event->child_comm);
+}
+
+static struct trace_sched_handler replay_ops  = {
+	.wakeup_event		= replay_wakeup_event,
+	.switch_event		= replay_switch_event,
+	.fork_event		= replay_fork_event,
+};
+
+struct sort_dimension {
+	const char		*name;
+	sort_fn_t		cmp;
+	struct list_head	list;
+};
+
+static LIST_HEAD(cmp_pid);
+
+static int
+thread_lat_cmp(struct list_head *list, struct work_atoms *l, struct work_atoms *r)
+{
+	struct sort_dimension *sort;
+	int ret = 0;
+
+	BUG_ON(list_empty(list));
+
+	list_for_each_entry(sort, list, list) {
+		ret = sort->cmp(l, r);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static struct work_atoms *
+thread_atoms_search(struct rb_root *root, struct thread *thread,
+			 struct list_head *sort_list)
+{
+	struct rb_node *node = root->rb_node;
+	struct work_atoms key = { .thread = thread };
+
+	while (node) {
+		struct work_atoms *atoms;
+		int cmp;
+
+		atoms = container_of(node, struct work_atoms, node);
+
+		cmp = thread_lat_cmp(sort_list, &key, atoms);
+		if (cmp > 0)
+			node = node->rb_left;
+		else if (cmp < 0)
+			node = node->rb_right;
+		else {
+			BUG_ON(thread != atoms->thread);
+			return atoms;
+		}
+	}
+	return NULL;
+}
+
+static void
+__thread_latency_insert(struct rb_root *root, struct work_atoms *data,
+			 struct list_head *sort_list)
+{
+	struct rb_node **new = &(root->rb_node), *parent = NULL;
+
+	while (*new) {
+		struct work_atoms *this;
+		int cmp;
+
+		this = container_of(*new, struct work_atoms, node);
+		parent = *new;
+
+		cmp = thread_lat_cmp(sort_list, data, this);
+
+		if (cmp > 0)
+			new = &((*new)->rb_left);
+		else
+			new = &((*new)->rb_right);
+	}
+
+	rb_link_node(&data->node, parent, new);
+	rb_insert_color(&data->node, root);
+}
+
+static void thread_atoms_insert(struct thread *thread)
+{
+	struct work_atoms *atoms;
+
+	atoms = calloc(sizeof(*atoms), 1);
+	if (!atoms)
+		die("No memory");
+
+	atoms->thread = thread;
+	INIT_LIST_HEAD(&atoms->work_list);
+	__thread_latency_insert(&atom_root, atoms, &cmp_pid);
+}
+
+static void
+latency_fork_event(struct trace_fork_event *fork_event __used,
+		   struct event *event __used,
+		   int cpu __used,
+		   u64 timestamp __used,
+		   struct thread *thread __used)
+{
+	/* should insert the newcomer */
+}
+
+__used
+static char sched_out_state(struct trace_switch_event *switch_event)
+{
+	const char *str = TASK_STATE_TO_CHAR_STR;
+
+	return str[switch_event->prev_state];
+}
+
+static void
+add_sched_out_event(struct work_atoms *atoms,
+		    char run_state,
+		    u64 timestamp)
+{
+	struct work_atom *atom;
+
+	atom = calloc(sizeof(*atom), 1);
+	if (!atom)
+		die("Non memory");
+
+	atom->sched_out_time = timestamp;
+
+	if (run_state == 'R') {
+		atom->state = THREAD_WAIT_CPU;
+		atom->wake_up_time = atom->sched_out_time;
+	}
+
+	list_add_tail(&atom->list, &atoms->work_list);
+}
+
+static void
+add_runtime_event(struct work_atoms *atoms, u64 delta, u64 timestamp __used)
+{
+	struct work_atom *atom;
+
+	BUG_ON(list_empty(&atoms->work_list));
+
+	atom = list_entry(atoms->work_list.prev, struct work_atom, list);
+
+	atom->runtime += delta;
+	atoms->total_runtime += delta;
+}
+
+static void
+add_sched_in_event(struct work_atoms *atoms, u64 timestamp)
+{
+	struct work_atom *atom;
+	u64 delta;
+
+	if (list_empty(&atoms->work_list))
+		return;
+
+	atom = list_entry(atoms->work_list.prev, struct work_atom, list);
+
+	if (atom->state != THREAD_WAIT_CPU)
+		return;
+
+	if (timestamp < atom->wake_up_time) {
+		atom->state = THREAD_IGNORE;
+		return;
+	}
+
+	atom->state = THREAD_SCHED_IN;
+	atom->sched_in_time = timestamp;
+
+	delta = atom->sched_in_time - atom->wake_up_time;
+	atoms->total_lat += delta;
+	if (delta > atoms->max_lat)
+		atoms->max_lat = delta;
+	atoms->nb_atoms++;
+}
+
+static void
+latency_switch_event(struct trace_switch_event *switch_event,
+		     struct event *event __used,
+		     int cpu,
+		     u64 timestamp,
+		     struct thread *thread __used)
+{
+	struct work_atoms *out_events, *in_events;
+	struct thread *sched_out, *sched_in;
+	u64 timestamp0;
+	s64 delta;
+
+	BUG_ON(cpu >= MAX_CPUS || cpu < 0);
+
+	timestamp0 = cpu_last_switched[cpu];
+	cpu_last_switched[cpu] = timestamp;
+	if (timestamp0)
+		delta = timestamp - timestamp0;
+	else
+		delta = 0;
+
+	if (delta < 0)
+		die("hm, delta: %Ld < 0 ?\n", delta);
+
+
+	sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match);
+	sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match);
+
+	out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid);
+	if (!out_events) {
+		thread_atoms_insert(sched_out);
+		out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid);
+		if (!out_events)
+			die("out-event: Internal tree error");
+	}
+	add_sched_out_event(out_events, sched_out_state(switch_event), timestamp);
+
+	in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid);
+	if (!in_events) {
+		thread_atoms_insert(sched_in);
+		in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid);
+		if (!in_events)
+			die("in-event: Internal tree error");
+		/*
+		 * Take came in we have not heard about yet,
+		 * add in an initial atom in runnable state:
+		 */
+		add_sched_out_event(in_events, 'R', timestamp);
+	}
+	add_sched_in_event(in_events, timestamp);
+}
+
+static void
+latency_runtime_event(struct trace_runtime_event *runtime_event,
+		     struct event *event __used,
+		     int cpu,
+		     u64 timestamp,
+		     struct thread *this_thread __used)
+{
+	struct work_atoms *atoms;
+	struct thread *thread;
+
+	BUG_ON(cpu >= MAX_CPUS || cpu < 0);
+
+	thread = threads__findnew(runtime_event->pid, &threads, &last_match);
+	atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);
+	if (!atoms) {
+		thread_atoms_insert(thread);
+		atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);
+		if (!atoms)
+			die("in-event: Internal tree error");
+		add_sched_out_event(atoms, 'R', timestamp);
+	}
+
+	add_runtime_event(atoms, runtime_event->runtime, timestamp);
+}
+
+static void
+latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
+		     struct event *__event __used,
+		     int cpu __used,
+		     u64 timestamp,
+		     struct thread *thread __used)
+{
+	struct work_atoms *atoms;
+	struct work_atom *atom;
+	struct thread *wakee;
+
+	/* Note for later, it may be interesting to observe the failing cases */
+	if (!wakeup_event->success)
+		return;
+
+	wakee = threads__findnew(wakeup_event->pid, &threads, &last_match);
+	atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid);
+	if (!atoms) {
+		thread_atoms_insert(wakee);
+		atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid);
+		if (!atoms)
+			die("wakeup-event: Internal tree error");
+		add_sched_out_event(atoms, 'S', timestamp);
+	}
+
+	BUG_ON(list_empty(&atoms->work_list));
+
+	atom = list_entry(atoms->work_list.prev, struct work_atom, list);
+
+	if (atom->state != THREAD_SLEEPING)
+		nr_state_machine_bugs++;
+
+	nr_timestamps++;
+	if (atom->sched_out_time > timestamp) {
+		nr_unordered_timestamps++;
+		return;
+	}
+
+	atom->state = THREAD_WAIT_CPU;
+	atom->wake_up_time = timestamp;
+}
+
+static struct trace_sched_handler lat_ops  = {
+	.wakeup_event		= latency_wakeup_event,
+	.switch_event		= latency_switch_event,
+	.runtime_event		= latency_runtime_event,
+	.fork_event		= latency_fork_event,
+};
+
+static void output_lat_thread(struct work_atoms *work_list)
+{
+	int i;
+	int ret;
+	u64 avg;
+
+	if (!work_list->nb_atoms)
+		return;
+	/*
+	 * Ignore idle threads:
+	 */
+	if (!strcmp(work_list->thread->comm, "swapper"))
+		return;
+
+	all_runtime += work_list->total_runtime;
+	all_count += work_list->nb_atoms;
+
+	ret = printf("  %s:%d ", work_list->thread->comm, work_list->thread->pid);
+
+	for (i = 0; i < 24 - ret; i++)
+		printf(" ");
+
+	avg = work_list->total_lat / work_list->nb_atoms;
+
+	printf("|%11.3f ms |%9llu | avg:%9.3f ms | max:%9.3f ms |\n",
+	      (double)work_list->total_runtime / 1e6,
+		 work_list->nb_atoms, (double)avg / 1e6,
+		 (double)work_list->max_lat / 1e6);
+}
+
+static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
+{
+	if (l->thread->pid < r->thread->pid)
+		return -1;
+	if (l->thread->pid > r->thread->pid)
+		return 1;
+
+	return 0;
+}
+
+static struct sort_dimension pid_sort_dimension = {
+	.name			= "pid",
+	.cmp			= pid_cmp,
+};
+
+static int avg_cmp(struct work_atoms *l, struct work_atoms *r)
+{
+	u64 avgl, avgr;
+
+	if (!l->nb_atoms)
+		return -1;
+
+	if (!r->nb_atoms)
+		return 1;
+
+	avgl = l->total_lat / l->nb_atoms;
+	avgr = r->total_lat / r->nb_atoms;
+
+	if (avgl < avgr)
+		return -1;
+	if (avgl > avgr)
+		return 1;
+
+	return 0;
+}
+
+static struct sort_dimension avg_sort_dimension = {
+	.name			= "avg",
+	.cmp			= avg_cmp,
+};
+
+static int max_cmp(struct work_atoms *l, struct work_atoms *r)
+{
+	if (l->max_lat < r->max_lat)
+		return -1;
+	if (l->max_lat > r->max_lat)
+		return 1;
+
+	return 0;
+}
+
+static struct sort_dimension max_sort_dimension = {
+	.name			= "max",
+	.cmp			= max_cmp,
+};
+
+static int switch_cmp(struct work_atoms *l, struct work_atoms *r)
+{
+	if (l->nb_atoms < r->nb_atoms)
+		return -1;
+	if (l->nb_atoms > r->nb_atoms)
+		return 1;
+
+	return 0;
+}
+
+static struct sort_dimension switch_sort_dimension = {
+	.name			= "switch",
+	.cmp			= switch_cmp,
+};
+
+static int runtime_cmp(struct work_atoms *l, struct work_atoms *r)
+{
+	if (l->total_runtime < r->total_runtime)
+		return -1;
+	if (l->total_runtime > r->total_runtime)
+		return 1;
+
+	return 0;
+}
+
+static struct sort_dimension runtime_sort_dimension = {
+	.name			= "runtime",
+	.cmp			= runtime_cmp,
+};
+
+static struct sort_dimension *available_sorts[] = {
+	&pid_sort_dimension,
+	&avg_sort_dimension,
+	&max_sort_dimension,
+	&switch_sort_dimension,
+	&runtime_sort_dimension,
+};
+
+#define NB_AVAILABLE_SORTS	(int)(sizeof(available_sorts) / sizeof(struct sort_dimension *))
+
+static LIST_HEAD(sort_list);
+
+static int sort_dimension__add(char *tok, struct list_head *list)
+{
+	int i;
+
+	for (i = 0; i < NB_AVAILABLE_SORTS; i++) {
+		if (!strcmp(available_sorts[i]->name, tok)) {
+			list_add_tail(&available_sorts[i]->list, list);
+
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+static void setup_sorting(void);
+
+static void sort_lat(void)
+{
+	struct rb_node *node;
+
+	for (;;) {
+		struct work_atoms *data;
+		node = rb_first(&atom_root);
+		if (!node)
+			break;
+
+		rb_erase(node, &atom_root);
+		data = rb_entry(node, struct work_atoms, node);
+		__thread_latency_insert(&sorted_atom_root, data, &sort_list);
+	}
+}
+
+static struct trace_sched_handler *trace_handler;
+
+static void
+process_sched_wakeup_event(struct raw_event_sample *raw,
+			   struct event *event,
+			   int cpu __used,
+			   u64 timestamp __used,
+			   struct thread *thread __used)
+{
+	struct trace_wakeup_event wakeup_event;
+
+	FILL_COMMON_FIELDS(wakeup_event, event, raw->data);
+
+	FILL_ARRAY(wakeup_event, comm, event, raw->data);
+	FILL_FIELD(wakeup_event, pid, event, raw->data);
+	FILL_FIELD(wakeup_event, prio, event, raw->data);
+	FILL_FIELD(wakeup_event, success, event, raw->data);
+	FILL_FIELD(wakeup_event, cpu, event, raw->data);
+
+	if (trace_handler->wakeup_event)
+		trace_handler->wakeup_event(&wakeup_event, event, cpu, timestamp, thread);
+}
+
+/*
+ * Track the current task - that way we can know whether there's any
+ * weird events, such as a task being switched away that is not current.
+ */
+static int max_cpu;
+
+static u32 curr_pid[MAX_CPUS] = { [0 ... MAX_CPUS-1] = -1 };
+
+static struct thread *curr_thread[MAX_CPUS];
+
+static char next_shortname1 = 'A';
+static char next_shortname2 = '0';
+
+static void
+map_switch_event(struct trace_switch_event *switch_event,
+		 struct event *event __used,
+		 int this_cpu,
+		 u64 timestamp,
+		 struct thread *thread __used)
+{
+	struct thread *sched_out, *sched_in;
+	int new_shortname;
+	u64 timestamp0;
+	s64 delta;
+	int cpu;
+
+	BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0);
+
+	if (this_cpu > max_cpu)
+		max_cpu = this_cpu;
+
+	timestamp0 = cpu_last_switched[this_cpu];
+	cpu_last_switched[this_cpu] = timestamp;
+	if (timestamp0)
+		delta = timestamp - timestamp0;
+	else
+		delta = 0;
+
+	if (delta < 0)
+		die("hm, delta: %Ld < 0 ?\n", delta);
+
+
+	sched_out = threads__findnew(switch_event->prev_pid, &threads, &last_match);
+	sched_in = threads__findnew(switch_event->next_pid, &threads, &last_match);
+
+	curr_thread[this_cpu] = sched_in;
+
+	printf("  ");
+
+	new_shortname = 0;
+	if (!sched_in->shortname[0]) {
+		sched_in->shortname[0] = next_shortname1;
+		sched_in->shortname[1] = next_shortname2;
+
+		if (next_shortname1 < 'Z') {
+			next_shortname1++;
+		} else {
+			next_shortname1='A';
+			if (next_shortname2 < '9') {
+				next_shortname2++;
+			} else {
+				next_shortname2='0';
+			}
+		}
+		new_shortname = 1;
+	}
+
+	for (cpu = 0; cpu <= max_cpu; cpu++) {
+		if (cpu != this_cpu)
+			printf(" ");
+		else
+			printf("*");
+
+		if (curr_thread[cpu]) {
+			if (curr_thread[cpu]->pid)
+				printf("%2s ", curr_thread[cpu]->shortname);
+			else
+				printf(".  ");
+		} else
+			printf("   ");
+	}
+
+	printf("  %12.6f secs ", (double)timestamp/1e9);
+	if (new_shortname) {
+		printf("%s => %s:%d\n",
+			sched_in->shortname, sched_in->comm, sched_in->pid);
+	} else {
+		printf("\n");
+	}
+}
+
+
+static void
+process_sched_switch_event(struct raw_event_sample *raw,
+			   struct event *event,
+			   int this_cpu,
+			   u64 timestamp __used,
+			   struct thread *thread __used)
+{
+	struct trace_switch_event switch_event;
+
+	FILL_COMMON_FIELDS(switch_event, event, raw->data);
+
+	FILL_ARRAY(switch_event, prev_comm, event, raw->data);
+	FILL_FIELD(switch_event, prev_pid, event, raw->data);
+	FILL_FIELD(switch_event, prev_prio, event, raw->data);
+	FILL_FIELD(switch_event, prev_state, event, raw->data);
+	FILL_ARRAY(switch_event, next_comm, event, raw->data);
+	FILL_FIELD(switch_event, next_pid, event, raw->data);
+	FILL_FIELD(switch_event, next_prio, event, raw->data);
+
+	if (curr_pid[this_cpu] != (u32)-1) {
+		/*
+		 * Are we trying to switch away a PID that is
+		 * not current?
+		 */
+		if (curr_pid[this_cpu] != switch_event.prev_pid)
+			nr_context_switch_bugs++;
+	}
+	if (trace_handler->switch_event)
+		trace_handler->switch_event(&switch_event, event, this_cpu, timestamp, thread);
+
+	curr_pid[this_cpu] = switch_event.next_pid;
+}
+
+static void
+process_sched_runtime_event(struct raw_event_sample *raw,
+			   struct event *event,
+			   int cpu __used,
+			   u64 timestamp __used,
+			   struct thread *thread __used)
+{
+	struct trace_runtime_event runtime_event;
+
+	FILL_ARRAY(runtime_event, comm, event, raw->data);
+	FILL_FIELD(runtime_event, pid, event, raw->data);
+	FILL_FIELD(runtime_event, runtime, event, raw->data);
+	FILL_FIELD(runtime_event, vruntime, event, raw->data);
+
+	if (trace_handler->runtime_event)
+		trace_handler->runtime_event(&runtime_event, event, cpu, timestamp, thread);
+}
+
+static void
+process_sched_fork_event(struct raw_event_sample *raw,
+			 struct event *event,
+			 int cpu __used,
+			 u64 timestamp __used,
+			 struct thread *thread __used)
+{
+	struct trace_fork_event fork_event;
+
+	FILL_COMMON_FIELDS(fork_event, event, raw->data);
+
+	FILL_ARRAY(fork_event, parent_comm, event, raw->data);
+	FILL_FIELD(fork_event, parent_pid, event, raw->data);
+	FILL_ARRAY(fork_event, child_comm, event, raw->data);
+	FILL_FIELD(fork_event, child_pid, event, raw->data);
+
+	if (trace_handler->fork_event)
+		trace_handler->fork_event(&fork_event, event, cpu, timestamp, thread);
+}
+
+static void
+process_sched_exit_event(struct event *event,
+			 int cpu __used,
+			 u64 timestamp __used,
+			 struct thread *thread __used)
+{
+	if (verbose)
+		printf("sched_exit event %p\n", event);
+}
+
+static void
+process_raw_event(event_t *raw_event __used, void *more_data,
+		  int cpu, u64 timestamp, struct thread *thread)
+{
+	struct raw_event_sample *raw = more_data;
+	struct event *event;
+	int type;
+
+	type = trace_parse_common_type(raw->data);
+	event = trace_find_event(type);
+
+	if (!strcmp(event->name, "sched_switch"))
+		process_sched_switch_event(raw, event, cpu, timestamp, thread);
+	if (!strcmp(event->name, "sched_stat_runtime"))
+		process_sched_runtime_event(raw, event, cpu, timestamp, thread);
+	if (!strcmp(event->name, "sched_wakeup"))
+		process_sched_wakeup_event(raw, event, cpu, timestamp, thread);
+	if (!strcmp(event->name, "sched_wakeup_new"))
+		process_sched_wakeup_event(raw, event, cpu, timestamp, thread);
+	if (!strcmp(event->name, "sched_process_fork"))
+		process_sched_fork_event(raw, event, cpu, timestamp, thread);
+	if (!strcmp(event->name, "sched_process_exit"))
+		process_sched_exit_event(event, cpu, timestamp, thread);
+}
+
+static int
+process_sample_event(event_t *event, unsigned long offset, unsigned long head)
+{
+	char level;
+	int show = 0;
+	struct dso *dso = NULL;
+	struct thread *thread;
+	u64 ip = event->ip.ip;
+	u64 timestamp = -1;
+	u32 cpu = -1;
+	u64 period = 1;
+	void *more_data = event->ip.__more_data;
+	int cpumode;
+
+	thread = threads__findnew(event->ip.pid, &threads, &last_match);
+
+	if (sample_type & PERF_SAMPLE_TIME) {
+		timestamp = *(u64 *)more_data;
+		more_data += sizeof(u64);
+	}
+
+	if (sample_type & PERF_SAMPLE_CPU) {
+		cpu = *(u32 *)more_data;
+		more_data += sizeof(u32);
+		more_data += sizeof(u32); /* reserved */
+	}
+
+	if (sample_type & PERF_SAMPLE_PERIOD) {
+		period = *(u64 *)more_data;
+		more_data += sizeof(u64);
+	}
+
+	dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
+		(void *)(offset + head),
+		(void *)(long)(event->header.size),
+		event->header.misc,
+		event->ip.pid, event->ip.tid,
+		(void *)(long)ip,
+		(long long)period);
+
+	dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
+
+	if (thread == NULL) {
+		eprintf("problem processing %d event, skipping it.\n",
+			event->header.type);
+		return -1;
+	}
+
+	cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+
+	if (cpumode == PERF_RECORD_MISC_KERNEL) {
+		show = SHOW_KERNEL;
+		level = 'k';
+
+		dso = kernel_dso;
+
+		dump_printf(" ...... dso: %s\n", dso->name);
+
+	} else if (cpumode == PERF_RECORD_MISC_USER) {
+
+		show = SHOW_USER;
+		level = '.';
+
+	} else {
+		show = SHOW_HV;
+		level = 'H';
+
+		dso = hypervisor_dso;
+
+		dump_printf(" ...... dso: [hypervisor]\n");
+	}
+
+	if (sample_type & PERF_SAMPLE_RAW)
+		process_raw_event(event, more_data, cpu, timestamp, thread);
+
+	return 0;
+}
+
+static int
+process_event(event_t *event, unsigned long offset, unsigned long head)
+{
+	trace_event(event);
+
+	nr_events++;
+	switch (event->header.type) {
+	case PERF_RECORD_MMAP:
+		return 0;
+	case PERF_RECORD_LOST:
+		nr_lost_chunks++;
+		nr_lost_events += event->lost.lost;
+		return 0;
+
+	case PERF_RECORD_COMM:
+		return process_comm_event(event, offset, head);
+
+	case PERF_RECORD_EXIT ... PERF_RECORD_READ:
+		return 0;
+
+	case PERF_RECORD_SAMPLE:
+		return process_sample_event(event, offset, head);
+
+	case PERF_RECORD_MAX:
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static int read_events(void)
+{
+	int ret, rc = EXIT_FAILURE;
+	unsigned long offset = 0;
+	unsigned long head = 0;
+	struct stat perf_stat;
+	event_t *event;
+	uint32_t size;
+	char *buf;
+
+	trace_report();
+	register_idle_thread(&threads, &last_match);
+
+	input = open(input_name, O_RDONLY);
+	if (input < 0) {
+		perror("failed to open file");
+		exit(-1);
+	}
+
+	ret = fstat(input, &perf_stat);
+	if (ret < 0) {
+		perror("failed to stat file");
+		exit(-1);
+	}
+
+	if (!perf_stat.st_size) {
+		fprintf(stderr, "zero-sized file, nothing to do!\n");
+		exit(0);
+	}
+	header = perf_header__read(input);
+	head = header->data_offset;
+	sample_type = perf_header__sample_type(header);
+
+	if (!(sample_type & PERF_SAMPLE_RAW))
+		die("No trace sample to read. Did you call perf record "
+		    "without -R?");
+
+	if (load_kernel() < 0) {
+		perror("failed to load kernel symbols");
+		return EXIT_FAILURE;
+	}
+
+remap:
+	buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
+			   MAP_SHARED, input, offset);
+	if (buf == MAP_FAILED) {
+		perror("failed to mmap file");
+		exit(-1);
+	}
+
+more:
+	event = (event_t *)(buf + head);
+
+	size = event->header.size;
+	if (!size)
+		size = 8;
+
+	if (head + event->header.size >= page_size * mmap_window) {
+		unsigned long shift = page_size * (head / page_size);
+		int res;
+
+		res = munmap(buf, page_size * mmap_window);
+		assert(res == 0);
+
+		offset += shift;
+		head -= shift;
+		goto remap;
+	}
+
+	size = event->header.size;
+
+
+	if (!size || process_event(event, offset, head) < 0) {
+
+		/*
+		 * assume we lost track of the stream, check alignment, and
+		 * increment a single u64 in the hope to catch on again 'soon'.
+		 */
+
+		if (unlikely(head & 7))
+			head &= ~7ULL;
+
+		size = 8;
+	}
+
+	head += size;
+
+	if (offset + head < (unsigned long)perf_stat.st_size)
+		goto more;
+
+	rc = EXIT_SUCCESS;
+	close(input);
+
+	return rc;
+}
+
+static void print_bad_events(void)
+{
+	if (nr_unordered_timestamps && nr_timestamps) {
+		printf("  INFO: %.3f%% unordered timestamps (%ld out of %ld)\n",
+			(double)nr_unordered_timestamps/(double)nr_timestamps*100.0,
+			nr_unordered_timestamps, nr_timestamps);
+	}
+	if (nr_lost_events && nr_events) {
+		printf("  INFO: %.3f%% lost events (%ld out of %ld, in %ld chunks)\n",
+			(double)nr_lost_events/(double)nr_events*100.0,
+			nr_lost_events, nr_events, nr_lost_chunks);
+	}
+	if (nr_state_machine_bugs && nr_timestamps) {
+		printf("  INFO: %.3f%% state machine bugs (%ld out of %ld)",
+			(double)nr_state_machine_bugs/(double)nr_timestamps*100.0,
+			nr_state_machine_bugs, nr_timestamps);
+		if (nr_lost_events)
+			printf(" (due to lost events?)");
+		printf("\n");
+	}
+	if (nr_context_switch_bugs && nr_timestamps) {
+		printf("  INFO: %.3f%% context switch bugs (%ld out of %ld)",
+			(double)nr_context_switch_bugs/(double)nr_timestamps*100.0,
+			nr_context_switch_bugs, nr_timestamps);
+		if (nr_lost_events)
+			printf(" (due to lost events?)");
+		printf("\n");
+	}
+}
+
+static void __cmd_lat(void)
+{
+	struct rb_node *next;
+
+	setup_pager();
+	read_events();
+	sort_lat();
+
+	printf("\n -----------------------------------------------------------------------------------------\n");
+	printf("  Task                  |   Runtime ms  | Switches | Average delay ms | Maximum delay ms |\n");
+	printf(" -----------------------------------------------------------------------------------------\n");
+
+	next = rb_first(&sorted_atom_root);
+
+	while (next) {
+		struct work_atoms *work_list;
+
+		work_list = rb_entry(next, struct work_atoms, node);
+		output_lat_thread(work_list);
+		next = rb_next(next);
+	}
+
+	printf(" -----------------------------------------------------------------------------------------\n");
+	printf("  TOTAL:                |%11.3f ms |%9Ld |\n",
+		(double)all_runtime/1e6, all_count);
+
+	printf(" ---------------------------------------------------\n");
+
+	print_bad_events();
+	printf("\n");
+
+}
+
+static struct trace_sched_handler map_ops  = {
+	.wakeup_event		= NULL,
+	.switch_event		= map_switch_event,
+	.runtime_event		= NULL,
+	.fork_event		= NULL,
+};
+
+static void __cmd_map(void)
+{
+	max_cpu = sysconf(_SC_NPROCESSORS_CONF);
+
+	setup_pager();
+	read_events();
+	print_bad_events();
+}
+
+static void __cmd_replay(void)
+{
+	unsigned long i;
+
+	calibrate_run_measurement_overhead();
+	calibrate_sleep_measurement_overhead();
+
+	test_calibrations();
+
+	read_events();
+
+	printf("nr_run_events:        %ld\n", nr_run_events);
+	printf("nr_sleep_events:      %ld\n", nr_sleep_events);
+	printf("nr_wakeup_events:     %ld\n", nr_wakeup_events);
+
+	if (targetless_wakeups)
+		printf("target-less wakeups:  %ld\n", targetless_wakeups);
+	if (multitarget_wakeups)
+		printf("multi-target wakeups: %ld\n", multitarget_wakeups);
+	if (nr_run_events_optimized)
+		printf("run atoms optimized: %ld\n",
+			nr_run_events_optimized);
+
+	print_task_traces();
+	add_cross_task_wakeups();
+
+	create_tasks();
+	printf("------------------------------------------------------------\n");
+	for (i = 0; i < replay_repeat; i++)
+		run_one_test();
+}
+
+
+static const char * const sched_usage[] = {
+	"perf sched [<options>] {record|latency|map|replay|trace}",
+	NULL
+};
+
+static const struct option sched_options[] = {
+	OPT_STRING('i', "input", &input_name, "file",
+		    "input file name"),
+	OPT_BOOLEAN('v', "verbose", &verbose,
+		    "be more verbose (show symbol address, etc)"),
+	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
+		    "dump raw trace in ASCII"),
+	OPT_END()
+};
+
+static const char * const latency_usage[] = {
+	"perf sched latency [<options>]",
+	NULL
+};
+
+static const struct option latency_options[] = {
+	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
+		   "sort by key(s): runtime, switch, avg, max"),
+	OPT_BOOLEAN('v', "verbose", &verbose,
+		    "be more verbose (show symbol address, etc)"),
+	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
+		    "dump raw trace in ASCII"),
+	OPT_END()
+};
+
+static const char * const replay_usage[] = {
+	"perf sched replay [<options>]",
+	NULL
+};
+
+static const struct option replay_options[] = {
+	OPT_INTEGER('r', "repeat", &replay_repeat,
+		    "repeat the workload replay N times (-1: infinite)"),
+	OPT_BOOLEAN('v', "verbose", &verbose,
+		    "be more verbose (show symbol address, etc)"),
+	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
+		    "dump raw trace in ASCII"),
+	OPT_END()
+};
+
+static void setup_sorting(void)
+{
+	char *tmp, *tok, *str = strdup(sort_order);
+
+	for (tok = strtok_r(str, ", ", &tmp);
+			tok; tok = strtok_r(NULL, ", ", &tmp)) {
+		if (sort_dimension__add(tok, &sort_list) < 0) {
+			error("Unknown --sort key: `%s'", tok);
+			usage_with_options(latency_usage, latency_options);
+		}
+	}
+
+	free(str);
+
+	sort_dimension__add((char *)"pid", &cmp_pid);
+}
+
+static const char *record_args[] = {
+	"record",
+	"-a",
+	"-R",
+	"-M",
+	"-f",
+	"-m", "1024",
+	"-c", "1",
+	"-e", "sched:sched_switch:r",
+	"-e", "sched:sched_stat_wait:r",
+	"-e", "sched:sched_stat_sleep:r",
+	"-e", "sched:sched_stat_iowait:r",
+	"-e", "sched:sched_stat_runtime:r",
+	"-e", "sched:sched_process_exit:r",
+	"-e", "sched:sched_process_fork:r",
+	"-e", "sched:sched_wakeup:r",
+	"-e", "sched:sched_migrate_task:r",
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+	unsigned int rec_argc, i, j;
+	const char **rec_argv;
+
+	rec_argc = ARRAY_SIZE(record_args) + argc - 1;
+	rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+	for (i = 0; i < ARRAY_SIZE(record_args); i++)
+		rec_argv[i] = strdup(record_args[i]);
+
+	for (j = 1; j < (unsigned int)argc; j++, i++)
+		rec_argv[i] = argv[j];
+
+	BUG_ON(i != rec_argc);
+
+	return cmd_record(i, rec_argv, NULL);
+}
+
+int cmd_sched(int argc, const char **argv, const char *prefix __used)
+{
+	symbol__init();
+	page_size = getpagesize();
+
+	argc = parse_options(argc, argv, sched_options, sched_usage,
+			     PARSE_OPT_STOP_AT_NON_OPTION);
+	if (!argc)
+		usage_with_options(sched_usage, sched_options);
+
+	if (!strncmp(argv[0], "rec", 3)) {
+		return __cmd_record(argc, argv);
+	} else if (!strncmp(argv[0], "lat", 3)) {
+		trace_handler = &lat_ops;
+		if (argc > 1) {
+			argc = parse_options(argc, argv, latency_options, latency_usage, 0);
+			if (argc)
+				usage_with_options(latency_usage, latency_options);
+		}
+		setup_sorting();
+		__cmd_lat();
+	} else if (!strcmp(argv[0], "map")) {
+		trace_handler = &map_ops;
+		setup_sorting();
+		__cmd_map();
+	} else if (!strncmp(argv[0], "rep", 3)) {
+		trace_handler = &replay_ops;
+		if (argc) {
+			argc = parse_options(argc, argv, replay_options, replay_usage, 0);
+			if (argc)
+				usage_with_options(replay_usage, replay_options);
+		}
+		__cmd_replay();
+	} else if (!strcmp(argv[0], "trace")) {
+		/*
+		 * Aliased to 'perf trace' for now:
+		 */
+		return cmd_trace(argc, argv, prefix);
+	} else {
+		usage_with_options(sched_usage, sched_options);
+	}
+
+	return 0;
+}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 61b8282..16af2d8 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -48,7 +48,7 @@
 #include <sys/prctl.h>
 #include <math.h>
 
-static struct perf_counter_attr default_attrs[] = {
+static struct perf_event_attr default_attrs[] = {
 
   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK	},
   { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES},
@@ -130,11 +130,11 @@ struct stats			runtime_cycles_stats;
 	 attrs[counter].config == PERF_COUNT_##c)
 
 #define ERR_PERF_OPEN \
-"Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n"
+"Error: counter %d, sys_perf_event_open() syscall returned with %d (%s)\n"
 
 static void create_perf_stat_counter(int counter, int pid)
 {
-	struct perf_counter_attr *attr = attrs + counter;
+	struct perf_event_attr *attr = attrs + counter;
 
 	if (scale)
 		attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -144,7 +144,7 @@ static void create_perf_stat_counter(int counter, int pid)
 		unsigned int cpu;
 
 		for (cpu = 0; cpu < nr_cpus; cpu++) {
-			fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0);
+			fd[cpu][counter] = sys_perf_event_open(attr, -1, cpu, -1, 0);
 			if (fd[cpu][counter] < 0 && verbose)
 				fprintf(stderr, ERR_PERF_OPEN, counter,
 					fd[cpu][counter], strerror(errno));
@@ -154,7 +154,7 @@ static void create_perf_stat_counter(int counter, int pid)
 		attr->disabled	     = 1;
 		attr->enable_on_exec = 1;
 
-		fd[0][counter] = sys_perf_counter_open(attr, pid, -1, -1, 0);
+		fd[0][counter] = sys_perf_event_open(attr, pid, -1, -1, 0);
 		if (fd[0][counter] < 0 && verbose)
 			fprintf(stderr, ERR_PERF_OPEN, counter,
 				fd[0][counter], strerror(errno));
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
new file mode 100644
index 0000000..4405681
--- /dev/null
+++ b/tools/perf/builtin-timechart.c
@@ -0,0 +1,1158 @@
+/*
+ * builtin-timechart.c - make an svg timechart of system activity
+ *
+ * (C) Copyright 2009 Intel Corporation
+ *
+ * Authors:
+ *     Arjan van de Ven <arjan@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#include "builtin.h"
+
+#include "util/util.h"
+
+#include "util/color.h"
+#include <linux/list.h>
+#include "util/cache.h"
+#include <linux/rbtree.h>
+#include "util/symbol.h"
+#include "util/string.h"
+#include "util/callchain.h"
+#include "util/strlist.h"
+
+#include "perf.h"
+#include "util/header.h"
+#include "util/parse-options.h"
+#include "util/parse-events.h"
+#include "util/svghelper.h"
+
+static char		const *input_name = "perf.data";
+static char		const *output_name = "output.svg";
+
+
+static unsigned long	page_size;
+static unsigned long	mmap_window = 32;
+static u64		sample_type;
+
+static unsigned int	numcpus;
+static u64		min_freq;	/* Lowest CPU frequency seen */
+static u64		max_freq;	/* Highest CPU frequency seen */
+static u64		turbo_frequency;
+
+static u64		first_time, last_time;
+
+
+static struct perf_header	*header;
+
+struct per_pid;
+struct per_pidcomm;
+
+struct cpu_sample;
+struct power_event;
+struct wake_event;
+
+struct sample_wrapper;
+
+/*
+ * Datastructure layout:
+ * We keep an list of "pid"s, matching the kernels notion of a task struct.
+ * Each "pid" entry, has a list of "comm"s.
+ *	this is because we want to track different programs different, while
+ *	exec will reuse the original pid (by design).
+ * Each comm has a list of samples that will be used to draw
+ * final graph.
+ */
+
+struct per_pid {
+	struct per_pid *next;
+
+	int		pid;
+	int		ppid;
+
+	u64		start_time;
+	u64		end_time;
+	u64		total_time;
+	int		display;
+
+	struct per_pidcomm *all;
+	struct per_pidcomm *current;
+
+	int painted;
+};
+
+
+struct per_pidcomm {
+	struct per_pidcomm *next;
+
+	u64		start_time;
+	u64		end_time;
+	u64		total_time;
+
+	int		Y;
+	int		display;
+
+	long		state;
+	u64		state_since;
+
+	char		*comm;
+
+	struct cpu_sample *samples;
+};
+
+struct sample_wrapper {
+	struct sample_wrapper *next;
+
+	u64		timestamp;
+	unsigned char	data[0];
+};
+
+#define TYPE_NONE	0
+#define TYPE_RUNNING	1
+#define TYPE_WAITING	2
+#define TYPE_BLOCKED	3
+
+struct cpu_sample {
+	struct cpu_sample *next;
+
+	u64 start_time;
+	u64 end_time;
+	int type;
+	int cpu;
+};
+
+static struct per_pid *all_data;
+
+#define CSTATE 1
+#define PSTATE 2
+
+struct power_event {
+	struct power_event *next;
+	int type;
+	int state;
+	u64 start_time;
+	u64 end_time;
+	int cpu;
+};
+
+struct wake_event {
+	struct wake_event *next;
+	int waker;
+	int wakee;
+	u64 time;
+};
+
+static struct power_event    *power_events;
+static struct wake_event     *wake_events;
+
+struct sample_wrapper *all_samples;
+
+static struct per_pid *find_create_pid(int pid)
+{
+	struct per_pid *cursor = all_data;
+
+	while (cursor) {
+		if (cursor->pid == pid)
+			return cursor;
+		cursor = cursor->next;
+	}
+	cursor = malloc(sizeof(struct per_pid));
+	assert(cursor != NULL);
+	memset(cursor, 0, sizeof(struct per_pid));
+	cursor->pid = pid;
+	cursor->next = all_data;
+	all_data = cursor;
+	return cursor;
+}
+
+static void pid_set_comm(int pid, char *comm)
+{
+	struct per_pid *p;
+	struct per_pidcomm *c;
+	p = find_create_pid(pid);
+	c = p->all;
+	while (c) {
+		if (c->comm && strcmp(c->comm, comm) == 0) {
+			p->current = c;
+			return;
+		}
+		if (!c->comm) {
+			c->comm = strdup(comm);
+			p->current = c;
+			return;
+		}
+		c = c->next;
+	}
+	c = malloc(sizeof(struct per_pidcomm));
+	assert(c != NULL);
+	memset(c, 0, sizeof(struct per_pidcomm));
+	c->comm = strdup(comm);
+	p->current = c;
+	c->next = p->all;
+	p->all = c;
+}
+
+static void pid_fork(int pid, int ppid, u64 timestamp)
+{
+	struct per_pid *p, *pp;
+	p = find_create_pid(pid);
+	pp = find_create_pid(ppid);
+	p->ppid = ppid;
+	if (pp->current && pp->current->comm && !p->current)
+		pid_set_comm(pid, pp->current->comm);
+
+	p->start_time = timestamp;
+	if (p->current) {
+		p->current->start_time = timestamp;
+		p->current->state_since = timestamp;
+	}
+}
+
+static void pid_exit(int pid, u64 timestamp)
+{
+	struct per_pid *p;
+	p = find_create_pid(pid);
+	p->end_time = timestamp;
+	if (p->current)
+		p->current->end_time = timestamp;
+}
+
+static void
+pid_put_sample(int pid, int type, unsigned int cpu, u64 start, u64 end)
+{
+	struct per_pid *p;
+	struct per_pidcomm *c;
+	struct cpu_sample *sample;
+
+	p = find_create_pid(pid);
+	c = p->current;
+	if (!c) {
+		c = malloc(sizeof(struct per_pidcomm));
+		assert(c != NULL);
+		memset(c, 0, sizeof(struct per_pidcomm));
+		p->current = c;
+		c->next = p->all;
+		p->all = c;
+	}
+
+	sample = malloc(sizeof(struct cpu_sample));
+	assert(sample != NULL);
+	memset(sample, 0, sizeof(struct cpu_sample));
+	sample->start_time = start;
+	sample->end_time = end;
+	sample->type = type;
+	sample->next = c->samples;
+	sample->cpu = cpu;
+	c->samples = sample;
+
+	if (sample->type == TYPE_RUNNING && end > start && start > 0) {
+		c->total_time += (end-start);
+		p->total_time += (end-start);
+	}
+
+	if (c->start_time == 0 || c->start_time > start)
+		c->start_time = start;
+	if (p->start_time == 0 || p->start_time > start)
+		p->start_time = start;
+
+	if (cpu > numcpus)
+		numcpus = cpu;
+}
+
+#define MAX_CPUS 4096
+
+static u64 cpus_cstate_start_times[MAX_CPUS];
+static int cpus_cstate_state[MAX_CPUS];
+static u64 cpus_pstate_start_times[MAX_CPUS];
+static u64 cpus_pstate_state[MAX_CPUS];
+
+static int
+process_comm_event(event_t *event)
+{
+	pid_set_comm(event->comm.pid, event->comm.comm);
+	return 0;
+}
+static int
+process_fork_event(event_t *event)
+{
+	pid_fork(event->fork.pid, event->fork.ppid, event->fork.time);
+	return 0;
+}
+
+static int
+process_exit_event(event_t *event)
+{
+	pid_exit(event->fork.pid, event->fork.time);
+	return 0;
+}
+
+struct trace_entry {
+	u32			size;
+	unsigned short		type;
+	unsigned char		flags;
+	unsigned char		preempt_count;
+	int			pid;
+	int			tgid;
+};
+
+struct power_entry {
+	struct trace_entry te;
+	s64	type;
+	s64	value;
+};
+
+#define TASK_COMM_LEN 16
+struct wakeup_entry {
+	struct trace_entry te;
+	char comm[TASK_COMM_LEN];
+	int   pid;
+	int   prio;
+	int   success;
+};
+
+/*
+ * 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
+ *  NEED_RESCED         - reschedule is requested
+ *  HARDIRQ             - inside an interrupt handler
+ *  SOFTIRQ             - inside a softirq handler
+ */
+enum trace_flag_type {
+	TRACE_FLAG_IRQS_OFF		= 0x01,
+	TRACE_FLAG_IRQS_NOSUPPORT	= 0x02,
+	TRACE_FLAG_NEED_RESCHED		= 0x04,
+	TRACE_FLAG_HARDIRQ		= 0x08,
+	TRACE_FLAG_SOFTIRQ		= 0x10,
+};
+
+
+
+struct sched_switch {
+	struct trace_entry te;
+	char prev_comm[TASK_COMM_LEN];
+	int  prev_pid;
+	int  prev_prio;
+	long prev_state; /* Arjan weeps. */
+	char next_comm[TASK_COMM_LEN];
+	int  next_pid;
+	int  next_prio;
+};
+
+static void c_state_start(int cpu, u64 timestamp, int state)
+{
+	cpus_cstate_start_times[cpu] = timestamp;
+	cpus_cstate_state[cpu] = state;
+}
+
+static void c_state_end(int cpu, u64 timestamp)
+{
+	struct power_event *pwr;
+	pwr = malloc(sizeof(struct power_event));
+	if (!pwr)
+		return;
+	memset(pwr, 0, sizeof(struct power_event));
+
+	pwr->state = cpus_cstate_state[cpu];
+	pwr->start_time = cpus_cstate_start_times[cpu];
+	pwr->end_time = timestamp;
+	pwr->cpu = cpu;
+	pwr->type = CSTATE;
+	pwr->next = power_events;
+
+	power_events = pwr;
+}
+
+static void p_state_change(int cpu, u64 timestamp, u64 new_freq)
+{
+	struct power_event *pwr;
+	pwr = malloc(sizeof(struct power_event));
+
+	if (new_freq > 8000000) /* detect invalid data */
+		return;
+
+	if (!pwr)
+		return;
+	memset(pwr, 0, sizeof(struct power_event));
+
+	pwr->state = cpus_pstate_state[cpu];
+	pwr->start_time = cpus_pstate_start_times[cpu];
+	pwr->end_time = timestamp;
+	pwr->cpu = cpu;
+	pwr->type = PSTATE;
+	pwr->next = power_events;
+
+	if (!pwr->start_time)
+		pwr->start_time = first_time;
+
+	power_events = pwr;
+
+	cpus_pstate_state[cpu] = new_freq;
+	cpus_pstate_start_times[cpu] = timestamp;
+
+	if ((u64)new_freq > max_freq)
+		max_freq = new_freq;
+
+	if (new_freq < min_freq || min_freq == 0)
+		min_freq = new_freq;
+
+	if (new_freq == max_freq - 1000)
+			turbo_frequency = max_freq;
+}
+
+static void
+sched_wakeup(int cpu, u64 timestamp, int pid, struct trace_entry *te)
+{
+	struct wake_event *we;
+	struct per_pid *p;
+	struct wakeup_entry *wake = (void *)te;
+
+	we = malloc(sizeof(struct wake_event));
+	if (!we)
+		return;
+
+	memset(we, 0, sizeof(struct wake_event));
+	we->time = timestamp;
+	we->waker = pid;
+
+	if ((te->flags & TRACE_FLAG_HARDIRQ) || (te->flags & TRACE_FLAG_SOFTIRQ))
+		we->waker = -1;
+
+	we->wakee = wake->pid;
+	we->next = wake_events;
+	wake_events = we;
+	p = find_create_pid(we->wakee);
+
+	if (p && p->current && p->current->state == TYPE_NONE) {
+		p->current->state_since = timestamp;
+		p->current->state = TYPE_WAITING;
+	}
+	if (p && p->current && p->current->state == TYPE_BLOCKED) {
+		pid_put_sample(p->pid, p->current->state, cpu, p->current->state_since, timestamp);
+		p->current->state_since = timestamp;
+		p->current->state = TYPE_WAITING;
+	}
+}
+
+static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
+{
+	struct per_pid *p = NULL, *prev_p;
+	struct sched_switch *sw = (void *)te;
+
+
+	prev_p = find_create_pid(sw->prev_pid);
+
+	p = find_create_pid(sw->next_pid);
+
+	if (prev_p->current && prev_p->current->state != TYPE_NONE)
+		pid_put_sample(sw->prev_pid, TYPE_RUNNING, cpu, prev_p->current->state_since, timestamp);
+	if (p && p->current) {
+		if (p->current->state != TYPE_NONE)
+			pid_put_sample(sw->next_pid, p->current->state, cpu, p->current->state_since, timestamp);
+
+			p->current->state_since = timestamp;
+			p->current->state = TYPE_RUNNING;
+	}
+
+	if (prev_p->current) {
+		prev_p->current->state = TYPE_NONE;
+		prev_p->current->state_since = timestamp;
+		if (sw->prev_state & 2)
+			prev_p->current->state = TYPE_BLOCKED;
+		if (sw->prev_state == 0)
+			prev_p->current->state = TYPE_WAITING;
+	}
+}
+
+
+static int
+process_sample_event(event_t *event)
+{
+	int cursor = 0;
+	u64 addr = 0;
+	u64 stamp = 0;
+	u32 cpu = 0;
+	u32 pid = 0;
+	struct trace_entry *te;
+
+	if (sample_type & PERF_SAMPLE_IP)
+		cursor++;
+
+	if (sample_type & PERF_SAMPLE_TID) {
+		pid = event->sample.array[cursor]>>32;
+		cursor++;
+	}
+	if (sample_type & PERF_SAMPLE_TIME) {
+		stamp = event->sample.array[cursor++];
+
+		if (!first_time || first_time > stamp)
+			first_time = stamp;
+		if (last_time < stamp)
+			last_time = stamp;
+
+	}
+	if (sample_type & PERF_SAMPLE_ADDR)
+		addr = event->sample.array[cursor++];
+	if (sample_type & PERF_SAMPLE_ID)
+		cursor++;
+	if (sample_type & PERF_SAMPLE_STREAM_ID)
+		cursor++;
+	if (sample_type & PERF_SAMPLE_CPU)
+		cpu = event->sample.array[cursor++] & 0xFFFFFFFF;
+	if (sample_type & PERF_SAMPLE_PERIOD)
+		cursor++;
+
+	te = (void *)&event->sample.array[cursor];
+
+	if (sample_type & PERF_SAMPLE_RAW && te->size > 0) {
+		char *event_str;
+		struct power_entry *pe;
+
+		pe = (void *)te;
+
+		event_str = perf_header__find_event(te->type);
+
+		if (!event_str)
+			return 0;
+
+		if (strcmp(event_str, "power:power_start") == 0)
+			c_state_start(cpu, stamp, pe->value);
+
+		if (strcmp(event_str, "power:power_end") == 0)
+			c_state_end(cpu, stamp);
+
+		if (strcmp(event_str, "power:power_frequency") == 0)
+			p_state_change(cpu, stamp, pe->value);
+
+		if (strcmp(event_str, "sched:sched_wakeup") == 0)
+			sched_wakeup(cpu, stamp, pid, te);
+
+		if (strcmp(event_str, "sched:sched_switch") == 0)
+			sched_switch(cpu, stamp, te);
+	}
+	return 0;
+}
+
+/*
+ * After the last sample we need to wrap up the current C/P state
+ * and close out each CPU for these.
+ */
+static void end_sample_processing(void)
+{
+	u64 cpu;
+	struct power_event *pwr;
+
+	for (cpu = 0; cpu < numcpus; cpu++) {
+		pwr = malloc(sizeof(struct power_event));
+		if (!pwr)
+			return;
+		memset(pwr, 0, sizeof(struct power_event));
+
+		/* C state */
+#if 0
+		pwr->state = cpus_cstate_state[cpu];
+		pwr->start_time = cpus_cstate_start_times[cpu];
+		pwr->end_time = last_time;
+		pwr->cpu = cpu;
+		pwr->type = CSTATE;
+		pwr->next = power_events;
+
+		power_events = pwr;
+#endif
+		/* P state */
+
+		pwr = malloc(sizeof(struct power_event));
+		if (!pwr)
+			return;
+		memset(pwr, 0, sizeof(struct power_event));
+
+		pwr->state = cpus_pstate_state[cpu];
+		pwr->start_time = cpus_pstate_start_times[cpu];
+		pwr->end_time = last_time;
+		pwr->cpu = cpu;
+		pwr->type = PSTATE;
+		pwr->next = power_events;
+
+		if (!pwr->start_time)
+			pwr->start_time = first_time;
+		if (!pwr->state)
+			pwr->state = min_freq;
+		power_events = pwr;
+	}
+}
+
+static u64 sample_time(event_t *event)
+{
+	int cursor;
+
+	cursor = 0;
+	if (sample_type & PERF_SAMPLE_IP)
+		cursor++;
+	if (sample_type & PERF_SAMPLE_TID)
+		cursor++;
+	if (sample_type & PERF_SAMPLE_TIME)
+		return event->sample.array[cursor];
+	return 0;
+}
+
+
+/*
+ * We first queue all events, sorted backwards by insertion.
+ * The order will get flipped later.
+ */
+static int
+queue_sample_event(event_t *event)
+{
+	struct sample_wrapper *copy, *prev;
+	int size;
+
+	size = event->sample.header.size + sizeof(struct sample_wrapper) + 8;
+
+	copy = malloc(size);
+	if (!copy)
+		return 1;
+
+	memset(copy, 0, size);
+
+	copy->next = NULL;
+	copy->timestamp = sample_time(event);
+
+	memcpy(&copy->data, event, event->sample.header.size);
+
+	/* insert in the right place in the list */
+
+	if (!all_samples) {
+		/* first sample ever */
+		all_samples = copy;
+		return 0;
+	}
+
+	if (all_samples->timestamp < copy->timestamp) {
+		/* insert at the head of the list */
+		copy->next = all_samples;
+		all_samples = copy;
+		return 0;
+	}
+
+	prev = all_samples;
+	while (prev->next) {
+		if (prev->next->timestamp < copy->timestamp) {
+			copy->next = prev->next;
+			prev->next = copy;
+			return 0;
+		}
+		prev = prev->next;
+	}
+	/* insert at the end of the list */
+	prev->next = copy;
+
+	return 0;
+}
+
+static void sort_queued_samples(void)
+{
+	struct sample_wrapper *cursor, *next;
+
+	cursor = all_samples;
+	all_samples = NULL;
+
+	while (cursor) {
+		next = cursor->next;
+		cursor->next = all_samples;
+		all_samples = cursor;
+		cursor = next;
+	}
+}
+
+/*
+ * Sort the pid datastructure
+ */
+static void sort_pids(void)
+{
+	struct per_pid *new_list, *p, *cursor, *prev;
+	/* sort by ppid first, then by pid, lowest to highest */
+
+	new_list = NULL;
+
+	while (all_data) {
+		p = all_data;
+		all_data = p->next;
+		p->next = NULL;
+
+		if (new_list == NULL) {
+			new_list = p;
+			p->next = NULL;
+			continue;
+		}
+		prev = NULL;
+		cursor = new_list;
+		while (cursor) {
+			if (cursor->ppid > p->ppid ||
+				(cursor->ppid == p->ppid && cursor->pid > p->pid)) {
+				/* must insert before */
+				if (prev) {
+					p->next = prev->next;
+					prev->next = p;
+					cursor = NULL;
+					continue;
+				} else {
+					p->next = new_list;
+					new_list = p;
+					cursor = NULL;
+					continue;
+				}
+			}
+
+			prev = cursor;
+			cursor = cursor->next;
+			if (!cursor)
+				prev->next = p;
+		}
+	}
+	all_data = new_list;
+}
+
+
+static void draw_c_p_states(void)
+{
+	struct power_event *pwr;
+	pwr = power_events;
+
+	/*
+	 * two pass drawing so that the P state bars are on top of the C state blocks
+	 */
+	while (pwr) {
+		if (pwr->type == CSTATE)
+			svg_cstate(pwr->cpu, pwr->start_time, pwr->end_time, pwr->state);
+		pwr = pwr->next;
+	}
+
+	pwr = power_events;
+	while (pwr) {
+		if (pwr->type == PSTATE) {
+			if (!pwr->state)
+				pwr->state = min_freq;
+			svg_pstate(pwr->cpu, pwr->start_time, pwr->end_time, pwr->state);
+		}
+		pwr = pwr->next;
+	}
+}
+
+static void draw_wakeups(void)
+{
+	struct wake_event *we;
+	struct per_pid *p;
+	struct per_pidcomm *c;
+
+	we = wake_events;
+	while (we) {
+		int from = 0, to = 0;
+		char *task_from = NULL, *task_to = NULL;
+
+		/* locate the column of the waker and wakee */
+		p = all_data;
+		while (p) {
+			if (p->pid == we->waker || p->pid == we->wakee) {
+				c = p->all;
+				while (c) {
+					if (c->Y && c->start_time <= we->time && c->end_time >= we->time) {
+						if (p->pid == we->waker) {
+							from = c->Y;
+							task_from = c->comm;
+						}
+						if (p->pid == we->wakee) {
+							to = c->Y;
+							task_to = c->comm;
+						}
+					}
+					c = c->next;
+				}
+			}
+			p = p->next;
+		}
+
+		if (we->waker == -1)
+			svg_interrupt(we->time, to);
+		else if (from && to && abs(from - to) == 1)
+			svg_wakeline(we->time, from, to);
+		else
+			svg_partial_wakeline(we->time, from, task_from, to, task_to);
+		we = we->next;
+	}
+}
+
+static void draw_cpu_usage(void)
+{
+	struct per_pid *p;
+	struct per_pidcomm *c;
+	struct cpu_sample *sample;
+	p = all_data;
+	while (p) {
+		c = p->all;
+		while (c) {
+			sample = c->samples;
+			while (sample) {
+				if (sample->type == TYPE_RUNNING)
+					svg_process(sample->cpu, sample->start_time, sample->end_time, "sample", c->comm);
+
+				sample = sample->next;
+			}
+			c = c->next;
+		}
+		p = p->next;
+	}
+}
+
+static void draw_process_bars(void)
+{
+	struct per_pid *p;
+	struct per_pidcomm *c;
+	struct cpu_sample *sample;
+	int Y = 0;
+
+	Y = 2 * numcpus + 2;
+
+	p = all_data;
+	while (p) {
+		c = p->all;
+		while (c) {
+			if (!c->display) {
+				c->Y = 0;
+				c = c->next;
+				continue;
+			}
+
+			svg_box(Y, c->start_time, c->end_time, "process");
+			sample = c->samples;
+			while (sample) {
+				if (sample->type == TYPE_RUNNING)
+					svg_sample(Y, sample->cpu, sample->start_time, sample->end_time);
+				if (sample->type == TYPE_BLOCKED)
+					svg_box(Y, sample->start_time, sample->end_time, "blocked");
+				if (sample->type == TYPE_WAITING)
+					svg_waiting(Y, sample->start_time, sample->end_time);
+				sample = sample->next;
+			}
+
+			if (c->comm) {
+				char comm[256];
+				if (c->total_time > 5000000000) /* 5 seconds */
+					sprintf(comm, "%s:%i (%2.2fs)", c->comm, p->pid, c->total_time / 1000000000.0);
+				else
+					sprintf(comm, "%s:%i (%3.1fms)", c->comm, p->pid, c->total_time / 1000000.0);
+
+				svg_text(Y, c->start_time, comm);
+			}
+			c->Y = Y;
+			Y++;
+			c = c->next;
+		}
+		p = p->next;
+	}
+}
+
+static int determine_display_tasks(u64 threshold)
+{
+	struct per_pid *p;
+	struct per_pidcomm *c;
+	int count = 0;
+
+	p = all_data;
+	while (p) {
+		p->display = 0;
+		if (p->start_time == 1)
+			p->start_time = first_time;
+
+		/* no exit marker, task kept running to the end */
+		if (p->end_time == 0)
+			p->end_time = last_time;
+		if (p->total_time >= threshold)
+			p->display = 1;
+
+		c = p->all;
+
+		while (c) {
+			c->display = 0;
+
+			if (c->start_time == 1)
+				c->start_time = first_time;
+
+			if (c->total_time >= threshold) {
+				c->display = 1;
+				count++;
+			}
+
+			if (c->end_time == 0)
+				c->end_time = last_time;
+
+			c = c->next;
+		}
+		p = p->next;
+	}
+	return count;
+}
+
+
+
+#define TIME_THRESH 10000000
+
+static void write_svg_file(const char *filename)
+{
+	u64 i;
+	int count;
+
+	numcpus++;
+
+
+	count = determine_display_tasks(TIME_THRESH);
+
+	/* We'd like to show at least 15 tasks; be less picky if we have fewer */
+	if (count < 15)
+		count = determine_display_tasks(TIME_THRESH / 10);
+
+	open_svg(filename, numcpus, count, first_time, last_time);
+
+	svg_time_grid();
+	svg_legenda();
+
+	for (i = 0; i < numcpus; i++)
+		svg_cpu_box(i, max_freq, turbo_frequency);
+
+	draw_cpu_usage();
+	draw_process_bars();
+	draw_c_p_states();
+	draw_wakeups();
+
+	svg_close();
+}
+
+static int
+process_event(event_t *event)
+{
+
+	switch (event->header.type) {
+
+	case PERF_RECORD_COMM:
+		return process_comm_event(event);
+	case PERF_RECORD_FORK:
+		return process_fork_event(event);
+	case PERF_RECORD_EXIT:
+		return process_exit_event(event);
+	case PERF_RECORD_SAMPLE:
+		return queue_sample_event(event);
+
+	/*
+	 * We dont process them right now but they are fine:
+	 */
+	case PERF_RECORD_MMAP:
+	case PERF_RECORD_THROTTLE:
+	case PERF_RECORD_UNTHROTTLE:
+		return 0;
+
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+static void process_samples(void)
+{
+	struct sample_wrapper *cursor;
+	event_t *event;
+
+	sort_queued_samples();
+
+	cursor = all_samples;
+	while (cursor) {
+		event = (void *)&cursor->data;
+		cursor = cursor->next;
+		process_sample_event(event);
+	}
+}
+
+
+static int __cmd_timechart(void)
+{
+	int ret, rc = EXIT_FAILURE;
+	unsigned long offset = 0;
+	unsigned long head, shift;
+	struct stat statbuf;
+	event_t *event;
+	uint32_t size;
+	char *buf;
+	int input;
+
+	input = open(input_name, O_RDONLY);
+	if (input < 0) {
+		fprintf(stderr, " failed to open file: %s", input_name);
+		if (!strcmp(input_name, "perf.data"))
+			fprintf(stderr, "  (try 'perf record' first)");
+		fprintf(stderr, "\n");
+		exit(-1);
+	}
+
+	ret = fstat(input, &statbuf);
+	if (ret < 0) {
+		perror("failed to stat file");
+		exit(-1);
+	}
+
+	if (!statbuf.st_size) {
+		fprintf(stderr, "zero-sized file, nothing to do!\n");
+		exit(0);
+	}
+
+	header = perf_header__read(input);
+	head = header->data_offset;
+
+	sample_type = perf_header__sample_type(header);
+
+	shift = page_size * (head / page_size);
+	offset += shift;
+	head -= shift;
+
+remap:
+	buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
+			   MAP_SHARED, input, offset);
+	if (buf == MAP_FAILED) {
+		perror("failed to mmap file");
+		exit(-1);
+	}
+
+more:
+	event = (event_t *)(buf + head);
+
+	size = event->header.size;
+	if (!size)
+		size = 8;
+
+	if (head + event->header.size >= page_size * mmap_window) {
+		int ret2;
+
+		shift = page_size * (head / page_size);
+
+		ret2 = munmap(buf, page_size * mmap_window);
+		assert(ret2 == 0);
+
+		offset += shift;
+		head -= shift;
+		goto remap;
+	}
+
+	size = event->header.size;
+
+	if (!size || process_event(event) < 0) {
+
+		printf("%p [%p]: skipping unknown header type: %d\n",
+			(void *)(offset + head),
+			(void *)(long)(event->header.size),
+			event->header.type);
+
+		/*
+		 * assume we lost track of the stream, check alignment, and
+		 * increment a single u64 in the hope to catch on again 'soon'.
+		 */
+
+		if (unlikely(head & 7))
+			head &= ~7ULL;
+
+		size = 8;
+	}
+
+	head += size;
+
+	if (offset + head >= header->data_offset + header->data_size)
+		goto done;
+
+	if (offset + head < (unsigned long)statbuf.st_size)
+		goto more;
+
+done:
+	rc = EXIT_SUCCESS;
+	close(input);
+
+
+	process_samples();
+
+	end_sample_processing();
+
+	sort_pids();
+
+	write_svg_file(output_name);
+
+	printf("Written %2.1f seconds of trace to %s.\n", (last_time - first_time) / 1000000000.0, output_name);
+
+	return rc;
+}
+
+static const char * const timechart_usage[] = {
+	"perf timechart [<options>] {record}",
+	NULL
+};
+
+static const char *record_args[] = {
+	"record",
+	"-a",
+	"-R",
+	"-M",
+	"-f",
+	"-c", "1",
+	"-e", "power:power_start",
+	"-e", "power:power_end",
+	"-e", "power:power_frequency",
+	"-e", "sched:sched_wakeup",
+	"-e", "sched:sched_switch",
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+	unsigned int rec_argc, i, j;
+	const char **rec_argv;
+
+	rec_argc = ARRAY_SIZE(record_args) + argc - 1;
+	rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+	for (i = 0; i < ARRAY_SIZE(record_args); i++)
+		rec_argv[i] = strdup(record_args[i]);
+
+	for (j = 1; j < (unsigned int)argc; j++, i++)
+		rec_argv[i] = argv[j];
+
+	return cmd_record(i, rec_argv, NULL);
+}
+
+static const struct option options[] = {
+	OPT_STRING('i', "input", &input_name, "file",
+		    "input file name"),
+	OPT_STRING('o', "output", &output_name, "file",
+		    "output file name"),
+	OPT_INTEGER('w', "width", &svg_page_width,
+		    "page width"),
+	OPT_END()
+};
+
+
+int cmd_timechart(int argc, const char **argv, const char *prefix __used)
+{
+	symbol__init();
+
+	page_size = getpagesize();
+
+	argc = parse_options(argc, argv, options, timechart_usage,
+			PARSE_OPT_STOP_AT_NON_OPTION);
+
+	if (argc && !strncmp(argv[0], "rec", 3))
+		return __cmd_record(argc, argv);
+	else if (argc)
+		usage_with_options(timechart_usage, options);
+
+	setup_pager();
+
+	return __cmd_timechart();
+}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 4002ccb..1ca8889 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -901,7 +901,7 @@ struct mmap_data {
 
 static unsigned int mmap_read_head(struct mmap_data *md)
 {
-	struct perf_counter_mmap_page *pc = md->base;
+	struct perf_event_mmap_page *pc = md->base;
 	int head;
 
 	head = pc->data_head;
@@ -977,9 +977,9 @@ static void mmap_read_counter(struct mmap_data *md)
 
 		old += size;
 
-		if (event->header.type == PERF_EVENT_SAMPLE) {
+		if (event->header.type == PERF_RECORD_SAMPLE) {
 			int user =
-	(event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK) == PERF_EVENT_MISC_USER;
+	(event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK) == PERF_RECORD_MISC_USER;
 			process_event(event->ip.ip, md->counter, user);
 		}
 	}
@@ -1005,7 +1005,7 @@ int group_fd;
 
 static void start_counter(int i, int counter)
 {
-	struct perf_counter_attr *attr;
+	struct perf_event_attr *attr;
 	int cpu;
 
 	cpu = profile_cpu;
@@ -1019,7 +1019,7 @@ static void start_counter(int i, int counter)
 	attr->inherit		= (cpu < 0) && inherit;
 
 try_again:
-	fd[i][counter] = sys_perf_counter_open(attr, target_pid, cpu, group_fd, 0);
+	fd[i][counter] = sys_perf_event_open(attr, target_pid, cpu, group_fd, 0);
 
 	if (fd[i][counter] < 0) {
 		int err = errno;
@@ -1044,7 +1044,7 @@ try_again:
 		printf("\n");
 		error("perfcounter syscall returned with %d (%s)\n",
 			fd[i][counter], strerror(err));
-		die("No CONFIG_PERF_COUNTERS=y kernel support configured?\n");
+		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
 		exit(-1);
 	}
 	assert(fd[i][counter] >= 0);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 914ab36..e9d256e 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -35,14 +35,14 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
 
 	thread = threads__findnew(event->comm.pid, &threads, &last_match);
 
-	dump_printf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
+	dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->comm.comm, event->comm.pid);
 
 	if (thread == NULL ||
 	    thread__set_comm(thread, event->comm.comm)) {
-		dump_printf("problem processing PERF_EVENT_COMM, skipping event.\n");
+		dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
 		return -1;
 	}
 	total_comm++;
@@ -82,7 +82,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 		more_data += sizeof(u64);
 	}
 
-	dump_printf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
+	dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
 		(void *)(offset + head),
 		(void *)(long)(event->header.size),
 		event->header.misc,
@@ -98,9 +98,9 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 		return -1;
 	}
 
-	cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
+	cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 
-	if (cpumode == PERF_EVENT_MISC_KERNEL) {
+	if (cpumode == PERF_RECORD_MISC_KERNEL) {
 		show = SHOW_KERNEL;
 		level = 'k';
 
@@ -108,7 +108,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
 
 		dump_printf(" ...... dso: %s\n", dso->name);
 
-	} else if (cpumode == PERF_EVENT_MISC_USER) {
+	} else if (cpumode == PERF_RECORD_MISC_USER) {
 
 		show = SHOW_USER;
 		level = '.';
@@ -146,19 +146,19 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
 	trace_event(event);
 
 	switch (event->header.type) {
-	case PERF_EVENT_MMAP ... PERF_EVENT_LOST:
+	case PERF_RECORD_MMAP ... PERF_RECORD_LOST:
 		return 0;
 
-	case PERF_EVENT_COMM:
+	case PERF_RECORD_COMM:
 		return process_comm_event(event, offset, head);
 
-	case PERF_EVENT_EXIT ... PERF_EVENT_READ:
+	case PERF_RECORD_EXIT ... PERF_RECORD_READ:
 		return 0;
 
-	case PERF_EVENT_SAMPLE:
+	case PERF_RECORD_SAMPLE:
 		return process_sample_event(event, offset, head);
 
-	case PERF_EVENT_MAX:
+	case PERF_RECORD_MAX:
 	default:
 		return -1;
 	}
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 3a63e41..e11d8d2 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -16,12 +16,14 @@ extern int check_pager_config(const char *cmd);
 
 extern int cmd_annotate(int argc, const char **argv, const char *prefix);
 extern int cmd_help(int argc, const char **argv, const char *prefix);
+extern int cmd_sched(int argc, const char **argv, const char *prefix);
+extern int cmd_list(int argc, const char **argv, const char *prefix);
 extern int cmd_record(int argc, const char **argv, const char *prefix);
 extern int cmd_report(int argc, const char **argv, const char *prefix);
 extern int cmd_stat(int argc, const char **argv, const char *prefix);
+extern int cmd_timechart(int argc, const char **argv, const char *prefix);
 extern int cmd_top(int argc, const char **argv, const char *prefix);
-extern int cmd_version(int argc, const char **argv, const char *prefix);
-extern int cmd_list(int argc, const char **argv, const char *prefix);
 extern int cmd_trace(int argc, const char **argv, const char *prefix);
+extern int cmd_version(int argc, const char **argv, const char *prefix);
 
 #endif
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index eebce30..00326e2 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -4,7 +4,10 @@
 #
 perf-annotate			mainporcelain common
 perf-list			mainporcelain common
+perf-sched			mainporcelain common
 perf-record			mainporcelain common
 perf-report			mainporcelain common
 perf-stat			mainporcelain common
+perf-timechart			mainporcelain common
 perf-top			mainporcelain common
+perf-trace			mainporcelain common
diff --git a/tools/perf/design.txt b/tools/perf/design.txt
index f71e0d2..f1946d1 100644
--- a/tools/perf/design.txt
+++ b/tools/perf/design.txt
@@ -18,10 +18,10 @@ underlying hardware counters.
 Performance counters are accessed via special file descriptors.
 There's one file descriptor per virtual counter used.
 
-The special file descriptor is opened via the perf_counter_open()
+The special file descriptor is opened via the perf_event_open()
 system call:
 
-   int sys_perf_counter_open(struct perf_counter_hw_event *hw_event_uptr,
+   int sys_perf_event_open(struct perf_event_hw_event *hw_event_uptr,
 			     pid_t pid, int cpu, int group_fd,
 			     unsigned long flags);
 
@@ -32,9 +32,9 @@ can be used to set the blocking mode, etc.
 Multiple counters can be kept open at a time, and the counters
 can be poll()ed.
 
-When creating a new counter fd, 'perf_counter_hw_event' is:
+When creating a new counter fd, 'perf_event_hw_event' is:
 
-struct perf_counter_hw_event {
+struct perf_event_hw_event {
         /*
          * The MSB of the config word signifies if the rest contains cpu
          * specific (raw) counter configuration data, if unset, the next
@@ -93,7 +93,7 @@ specified by 'event_id':
 
 /*
  * Generalized performance counter event types, used by the hw_event.event_id
- * parameter of the sys_perf_counter_open() syscall:
+ * parameter of the sys_perf_event_open() syscall:
  */
 enum hw_event_ids {
 	/*
@@ -159,7 +159,7 @@ in size.
  * reads on the counter should return the indicated quantities,
  * in increasing order of bit value, after the counter value.
  */
-enum perf_counter_read_format {
+enum perf_event_read_format {
         PERF_FORMAT_TOTAL_TIME_ENABLED  =  1,
         PERF_FORMAT_TOTAL_TIME_RUNNING  =  2,
 };
@@ -178,7 +178,7 @@ interrupt:
  * Bits that can be set in hw_event.record_type to request information
  * in the overflow packets.
  */
-enum perf_counter_record_format {
+enum perf_event_record_format {
         PERF_RECORD_IP          = 1U << 0,
         PERF_RECORD_TID         = 1U << 1,
         PERF_RECORD_TIME        = 1U << 2,
@@ -228,7 +228,7 @@ these events are recorded in the ring-buffer (see below).
 The 'comm' bit allows tracking of process comm data on process creation.
 This too is recorded in the ring-buffer (see below).
 
-The 'pid' parameter to the perf_counter_open() system call allows the
+The 'pid' parameter to the perf_event_open() system call allows the
 counter to be specific to a task:
 
  pid == 0: if the pid parameter is zero, the counter is attached to the
@@ -258,7 +258,7 @@ The 'flags' parameter is currently unused and must be zero.
 
 The 'group_fd' parameter allows counter "groups" to be set up.  A
 counter group has one counter which is the group "leader".  The leader
-is created first, with group_fd = -1 in the perf_counter_open call
+is created first, with group_fd = -1 in the perf_event_open call
 that creates it.  The rest of the group members are created
 subsequently, with group_fd giving the fd of the group leader.
 (A single counter on its own is created with group_fd = -1 and is
@@ -277,13 +277,13 @@ tracking are logged into a ring-buffer. This ring-buffer is created and
 accessed through mmap().
 
 The mmap size should be 1+2^n pages, where the first page is a meta-data page
-(struct perf_counter_mmap_page) that contains various bits of information such
+(struct perf_event_mmap_page) that contains various bits of information such
 as where the ring-buffer head is.
 
 /*
  * Structure of the page that can be mapped via mmap
  */
-struct perf_counter_mmap_page {
+struct perf_event_mmap_page {
         __u32   version;                /* version number of this structure */
         __u32   compat_version;         /* lowest version this is compat with */
 
@@ -317,7 +317,7 @@ struct perf_counter_mmap_page {
          * Control data for the mmap() data buffer.
          *
          * User-space reading this value should issue an rmb(), on SMP capable
-         * platforms, after reading this value -- see perf_counter_wakeup().
+         * platforms, after reading this value -- see perf_event_wakeup().
          */
         __u32   data_head;              /* head in the data section */
 };
@@ -327,9 +327,9 @@ NOTE: the hw-counter userspace bits are arch specific and are currently only
 
 The following 2^n pages are the ring-buffer which contains events of the form:
 
-#define PERF_EVENT_MISC_KERNEL          (1 << 0)
-#define PERF_EVENT_MISC_USER            (1 << 1)
-#define PERF_EVENT_MISC_OVERFLOW        (1 << 2)
+#define PERF_RECORD_MISC_KERNEL          (1 << 0)
+#define PERF_RECORD_MISC_USER            (1 << 1)
+#define PERF_RECORD_MISC_OVERFLOW        (1 << 2)
 
 struct perf_event_header {
         __u32   type;
@@ -353,8 +353,8 @@ enum perf_event_type {
          *      char                            filename[];
          * };
          */
-        PERF_EVENT_MMAP                 = 1,
-        PERF_EVENT_MUNMAP               = 2,
+        PERF_RECORD_MMAP                 = 1,
+        PERF_RECORD_MUNMAP               = 2,
 
         /*
          * struct {
@@ -364,10 +364,10 @@ enum perf_event_type {
          *      char                            comm[];
          * };
          */
-        PERF_EVENT_COMM                 = 3,
+        PERF_RECORD_COMM                 = 3,
 
         /*
-         * When header.misc & PERF_EVENT_MISC_OVERFLOW the event_type field
+         * When header.misc & PERF_RECORD_MISC_OVERFLOW the event_type field
          * will be PERF_RECORD_*
          *
          * struct {
@@ -397,7 +397,7 @@ Notification of new events is possible through poll()/select()/epoll() and
 fcntl() managing signals.
 
 Normally a notification is generated for every page filled, however one can
-additionally set perf_counter_hw_event.wakeup_events to generate one every
+additionally set perf_event_hw_event.wakeup_events to generate one every
 so many counter overflow events.
 
 Future work will include a splice() interface to the ring-buffer.
@@ -409,11 +409,11 @@ events but does continue to exist and maintain its count value.
 
 An individual counter or counter group can be enabled with
 
-	ioctl(fd, PERF_COUNTER_IOC_ENABLE);
+	ioctl(fd, PERF_EVENT_IOC_ENABLE);
 
 or disabled with
 
-	ioctl(fd, PERF_COUNTER_IOC_DISABLE);
+	ioctl(fd, PERF_EVENT_IOC_DISABLE);
 
 Enabling or disabling the leader of a group enables or disables the
 whole group; that is, while the group leader is disabled, none of the
@@ -424,16 +424,16 @@ other counter.
 
 Additionally, non-inherited overflow counters can use
 
-	ioctl(fd, PERF_COUNTER_IOC_REFRESH, nr);
+	ioctl(fd, PERF_EVENT_IOC_REFRESH, nr);
 
 to enable a counter for 'nr' events, after which it gets disabled again.
 
 A process can enable or disable all the counter groups that are
 attached to it, using prctl:
 
-	prctl(PR_TASK_PERF_COUNTERS_ENABLE);
+	prctl(PR_TASK_PERF_EVENTS_ENABLE);
 
-	prctl(PR_TASK_PERF_COUNTERS_DISABLE);
+	prctl(PR_TASK_PERF_EVENTS_DISABLE);
 
 This applies to all counters on the current process, whether created
 by this process or by another, and doesn't affect any counters that
@@ -447,11 +447,11 @@ Arch requirements
 If your architecture does not have hardware performance metrics, you can
 still use the generic software counters based on hrtimers for sampling.
 
-So to start with, in order to add HAVE_PERF_COUNTERS to your Kconfig, you
+So to start with, in order to add HAVE_PERF_EVENTS to your Kconfig, you
 will need at least this:
-	- asm/perf_counter.h - a basic stub will suffice at first
+	- asm/perf_event.h - a basic stub will suffice at first
 	- support for atomic64 types (and associated helper functions)
-	- set_perf_counter_pending() implemented
+	- set_perf_event_pending() implemented
 
 If your architecture does have hardware capabilities, you can override the
-weak stub hw_perf_counter_init() to register hardware counters.
+weak stub hw_perf_event_init() to register hardware counters.
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index fe4589d..19fc7fe 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -289,10 +289,12 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "record", cmd_record, 0 },
 		{ "report", cmd_report, 0 },
 		{ "stat", cmd_stat, 0 },
+		{ "timechart", cmd_timechart, 0 },
 		{ "top", cmd_top, 0 },
 		{ "annotate", cmd_annotate, 0 },
 		{ "version", cmd_version, 0 },
 		{ "trace", cmd_trace, 0 },
+		{ "sched", cmd_sched, 0 },
 	};
 	unsigned int i;
 	static const char ext[] = STRIP_EXTENSION;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index e5148e2..8cc4623 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -41,20 +41,26 @@
 #define cpu_relax()	asm volatile("" ::: "memory");
 #endif
 
+#ifdef __sparc__
+#include "../../arch/sparc/include/asm/unistd.h"
+#define rmb()		asm volatile("":::"memory")
+#define cpu_relax()	asm volatile("":::"memory")
+#endif
+
 #include <time.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/syscall.h>
 
-#include "../../include/linux/perf_counter.h"
+#include "../../include/linux/perf_event.h"
 #include "util/types.h"
 
 /*
- * prctl(PR_TASK_PERF_COUNTERS_DISABLE) will (cheaply) disable all
+ * prctl(PR_TASK_PERF_EVENTS_DISABLE) will (cheaply) disable all
  * counters in the current task.
  */
-#define PR_TASK_PERF_COUNTERS_DISABLE   31
-#define PR_TASK_PERF_COUNTERS_ENABLE    32
+#define PR_TASK_PERF_EVENTS_DISABLE   31
+#define PR_TASK_PERF_EVENTS_ENABLE    32
 
 #ifndef NSEC_PER_SEC
 # define NSEC_PER_SEC			1000000000ULL
@@ -84,12 +90,12 @@ static inline unsigned long long rdclock(void)
 	_min1 < _min2 ? _min1 : _min2; })
 
 static inline int
-sys_perf_counter_open(struct perf_counter_attr *attr,
+sys_perf_event_open(struct perf_event_attr *attr,
 		      pid_t pid, int cpu, int group_fd,
 		      unsigned long flags)
 {
 	attr->size = sizeof(*attr);
-	return syscall(__NR_perf_counter_open, attr, pid, cpu,
+	return syscall(__NR_perf_event_open, attr, pid, cpu,
 		       group_fd, flags);
 }
 
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index fa2d4e9..2c9c26d 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -1,5 +1,5 @@
-#ifndef __PERF_EVENT_H
-#define __PERF_EVENT_H
+#ifndef __PERF_RECORD_H
+#define __PERF_RECORD_H
 #include "../perf.h"
 #include "util.h"
 #include <linux/list.h>
@@ -39,6 +39,7 @@ struct fork_event {
 	struct perf_event_header header;
 	u32 pid, ppid;
 	u32 tid, ptid;
+	u64 time;
 };
 
 struct lost_event {
@@ -52,13 +53,19 @@ struct lost_event {
  */
 struct read_event {
 	struct perf_event_header header;
-	u32 pid,tid;
+	u32 pid, tid;
 	u64 value;
 	u64 time_enabled;
 	u64 time_running;
 	u64 id;
 };
 
+struct sample_event{
+	struct perf_event_header        header;
+	u64 array[];
+};
+
+
 typedef union event_union {
 	struct perf_event_header	header;
 	struct ip_event			ip;
@@ -67,6 +74,7 @@ typedef union event_union {
 	struct fork_event		fork;
 	struct lost_event		lost;
 	struct read_event		read;
+	struct sample_event		sample;
 } event_t;
 
 struct map {
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ec4d4c2..e306857 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -7,10 +7,9 @@
 #include "header.h"
 
 /*
- *
+ * Create new perf.data header attribute:
  */
-
-struct perf_header_attr *perf_header_attr__new(struct perf_counter_attr *attr)
+struct perf_header_attr *perf_header_attr__new(struct perf_event_attr *attr)
 {
 	struct perf_header_attr *self = malloc(sizeof(*self));
 
@@ -43,9 +42,8 @@ void perf_header_attr__add_id(struct perf_header_attr *self, u64 id)
 }
 
 /*
- *
+ * Create new perf.data header:
  */
-
 struct perf_header *perf_header__new(void)
 {
 	struct perf_header *self = malloc(sizeof(*self));
@@ -86,6 +84,46 @@ void perf_header__add_attr(struct perf_header *self,
 	self->attr[pos] = attr;
 }
 
+#define MAX_EVENT_NAME 64
+
+struct perf_trace_event_type {
+	u64	event_id;
+	char	name[MAX_EVENT_NAME];
+};
+
+static int event_count;
+static struct perf_trace_event_type *events;
+
+void perf_header__push_event(u64 id, const char *name)
+{
+	if (strlen(name) > MAX_EVENT_NAME)
+		printf("Event %s will be truncated\n", name);
+
+	if (!events) {
+		events = malloc(sizeof(struct perf_trace_event_type));
+		if (!events)
+			die("nomem");
+	} else {
+		events = realloc(events, (event_count + 1) * sizeof(struct perf_trace_event_type));
+		if (!events)
+			die("nomem");
+	}
+	memset(&events[event_count], 0, sizeof(struct perf_trace_event_type));
+	events[event_count].event_id = id;
+	strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1);
+	event_count++;
+}
+
+char *perf_header__find_event(u64 id)
+{
+	int i;
+	for (i = 0 ; i < event_count; i++) {
+		if (events[i].event_id == id)
+			return events[i].name;
+	}
+	return NULL;
+}
+
 static const char *__perf_magic = "PERFFILE";
 
 #define PERF_MAGIC	(*(u64 *)__perf_magic)
@@ -96,7 +134,7 @@ struct perf_file_section {
 };
 
 struct perf_file_attr {
-	struct perf_counter_attr	attr;
+	struct perf_event_attr	attr;
 	struct perf_file_section	ids;
 };
 
@@ -106,6 +144,7 @@ struct perf_file_header {
 	u64				attr_size;
 	struct perf_file_section	attrs;
 	struct perf_file_section	data;
+	struct perf_file_section	event_types;
 };
 
 static void do_write(int fd, void *buf, size_t size)
@@ -154,6 +193,11 @@ void perf_header__write(struct perf_header *self, int fd)
 		do_write(fd, &f_attr, sizeof(f_attr));
 	}
 
+	self->event_offset = lseek(fd, 0, SEEK_CUR);
+	self->event_size = event_count * sizeof(struct perf_trace_event_type);
+	if (events)
+		do_write(fd, events, self->event_size);
+
 
 	self->data_offset = lseek(fd, 0, SEEK_CUR);
 
@@ -169,6 +213,10 @@ void perf_header__write(struct perf_header *self, int fd)
 			.offset = self->data_offset,
 			.size	= self->data_size,
 		},
+		.event_types = {
+			.offset = self->event_offset,
+			.size	= self->event_size,
+		},
 	};
 
 	lseek(fd, 0, SEEK_SET);
@@ -234,6 +282,17 @@ struct perf_header *perf_header__read(int fd)
 		lseek(fd, tmp, SEEK_SET);
 	}
 
+	if (f_header.event_types.size) {
+		lseek(fd, f_header.event_types.offset, SEEK_SET);
+		events = malloc(f_header.event_types.size);
+		if (!events)
+			die("nomem");
+		do_read(fd, events, f_header.event_types.size);
+		event_count =  f_header.event_types.size / sizeof(struct perf_trace_event_type);
+	}
+	self->event_offset = f_header.event_types.offset;
+	self->event_size   = f_header.event_types.size;
+
 	self->data_offset = f_header.data.offset;
 	self->data_size   = f_header.data.size;
 
@@ -261,7 +320,7 @@ u64 perf_header__sample_type(struct perf_header *header)
 	return type;
 }
 
-struct perf_counter_attr *
+struct perf_event_attr *
 perf_header__find_attr(u64 id, struct perf_header *header)
 {
 	int i;
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 5d0a72e..a0761bc 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -1,12 +1,12 @@
 #ifndef _PERF_HEADER_H
 #define _PERF_HEADER_H
 
-#include "../../../include/linux/perf_counter.h"
+#include "../../../include/linux/perf_event.h"
 #include <sys/types.h>
 #include "types.h"
 
 struct perf_header_attr {
-	struct perf_counter_attr attr;
+	struct perf_event_attr attr;
 	int ids, size;
 	u64 *id;
 	off_t id_offset;
@@ -19,6 +19,8 @@ struct perf_header {
 	s64 attr_offset;
 	u64 data_offset;
 	u64 data_size;
+	u64 event_offset;
+	u64 event_size;
 };
 
 struct perf_header *perf_header__read(int fd);
@@ -27,12 +29,16 @@ void perf_header__write(struct perf_header *self, int fd);
 void perf_header__add_attr(struct perf_header *self,
 			   struct perf_header_attr *attr);
 
+void perf_header__push_event(u64 id, const char *name);
+char *perf_header__find_event(u64 id);
+
+
 struct perf_header_attr *
-perf_header_attr__new(struct perf_counter_attr *attr);
+perf_header_attr__new(struct perf_event_attr *attr);
 void perf_header_attr__add_id(struct perf_header_attr *self, u64 id);
 
 u64 perf_header__sample_type(struct perf_header *header);
-struct perf_counter_attr *
+struct perf_event_attr *
 perf_header__find_attr(u64 id, struct perf_header *header);
 
 
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a587d41..13ab4b8 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -6,10 +6,11 @@
 #include "exec_cmd.h"
 #include "string.h"
 #include "cache.h"
+#include "header.h"
 
 int					nr_counters;
 
-struct perf_counter_attr		attrs[MAX_COUNTERS];
+struct perf_event_attr		attrs[MAX_COUNTERS];
 
 struct event_symbol {
 	u8		type;
@@ -18,6 +19,12 @@ struct event_symbol {
 	const char	*alias;
 };
 
+enum event_result {
+	EVT_FAILED,
+	EVT_HANDLED,
+	EVT_HANDLED_ALL
+};
+
 char debugfs_path[MAXPATHLEN];
 
 #define CHW(x) .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_##x
@@ -41,13 +48,13 @@ static struct event_symbol event_symbols[] = {
   { CSW(CPU_MIGRATIONS),	"cpu-migrations",	"migrations"	},
 };
 
-#define __PERF_COUNTER_FIELD(config, name) \
-	((config & PERF_COUNTER_##name##_MASK) >> PERF_COUNTER_##name##_SHIFT)
+#define __PERF_EVENT_FIELD(config, name) \
+	((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT)
 
-#define PERF_COUNTER_RAW(config)	__PERF_COUNTER_FIELD(config, RAW)
-#define PERF_COUNTER_CONFIG(config)	__PERF_COUNTER_FIELD(config, CONFIG)
-#define PERF_COUNTER_TYPE(config)	__PERF_COUNTER_FIELD(config, TYPE)
-#define PERF_COUNTER_ID(config)		__PERF_COUNTER_FIELD(config, EVENT)
+#define PERF_EVENT_RAW(config)	__PERF_EVENT_FIELD(config, RAW)
+#define PERF_EVENT_CONFIG(config)	__PERF_EVENT_FIELD(config, CONFIG)
+#define PERF_EVENT_TYPE(config)	__PERF_EVENT_FIELD(config, TYPE)
+#define PERF_EVENT_ID(config)		__PERF_EVENT_FIELD(config, EVENT)
 
 static const char *hw_event_names[] = {
 	"cycles",
@@ -139,7 +146,7 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
 	   (strcmp(evt_dirent.d_name, "..")) &&				       \
 	   (!tp_event_has_id(&sys_dirent, &evt_dirent)))
 
-#define MAX_EVENT_LENGTH 30
+#define MAX_EVENT_LENGTH 512
 
 int valid_debugfs_mount(const char *debugfs)
 {
@@ -344,8 +351,8 @@ static int parse_aliases(const char **str, const char *names[][MAX_ALIASES], int
 	return -1;
 }
 
-static int
-parse_generic_hw_event(const char **str, struct perf_counter_attr *attr)
+static enum event_result
+parse_generic_hw_event(const char **str, struct perf_event_attr *attr)
 {
 	const char *s = *str;
 	int cache_type = -1, cache_op = -1, cache_result = -1;
@@ -356,7 +363,7 @@ parse_generic_hw_event(const char **str, struct perf_counter_attr *attr)
 	 * then bail out:
 	 */
 	if (cache_type == -1)
-		return 0;
+		return EVT_FAILED;
 
 	while ((cache_op == -1 || cache_result == -1) && *s == '-') {
 		++s;
@@ -402,27 +409,115 @@ parse_generic_hw_event(const char **str, struct perf_counter_attr *attr)
 	attr->type = PERF_TYPE_HW_CACHE;
 
 	*str = s;
-	return 1;
+	return EVT_HANDLED;
+}
+
+static enum event_result
+parse_single_tracepoint_event(char *sys_name,
+			      const char *evt_name,
+			      unsigned int evt_length,
+			      char *flags,
+			      struct perf_event_attr *attr,
+			      const char **strp)
+{
+	char evt_path[MAXPATHLEN];
+	char id_buf[4];
+	u64 id;
+	int fd;
+
+	if (flags) {
+		if (!strncmp(flags, "record", strlen(flags))) {
+			attr->sample_type |= PERF_SAMPLE_RAW;
+			attr->sample_type |= PERF_SAMPLE_TIME;
+			attr->sample_type |= PERF_SAMPLE_CPU;
+		}
+	}
+
+	snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
+		 sys_name, evt_name);
+
+	fd = open(evt_path, O_RDONLY);
+	if (fd < 0)
+		return EVT_FAILED;
+
+	if (read(fd, id_buf, sizeof(id_buf)) < 0) {
+		close(fd);
+		return EVT_FAILED;
+	}
+
+	close(fd);
+	id = atoll(id_buf);
+	attr->config = id;
+	attr->type = PERF_TYPE_TRACEPOINT;
+	*strp = evt_name + evt_length;
+
+	return EVT_HANDLED;
+}
+
+/* sys + ':' + event + ':' + flags*/
+#define MAX_EVOPT_LEN	(MAX_EVENT_LENGTH * 2 + 2 + 128)
+static enum event_result
+parse_subsystem_tracepoint_event(char *sys_name, char *flags)
+{
+	char evt_path[MAXPATHLEN];
+	struct dirent *evt_ent;
+	DIR *evt_dir;
+
+	snprintf(evt_path, MAXPATHLEN, "%s/%s", debugfs_path, sys_name);
+	evt_dir = opendir(evt_path);
+
+	if (!evt_dir) {
+		perror("Can't open event dir");
+		return EVT_FAILED;
+	}
+
+	while ((evt_ent = readdir(evt_dir))) {
+		char event_opt[MAX_EVOPT_LEN + 1];
+		int len;
+		unsigned int rem = MAX_EVOPT_LEN;
+
+		if (!strcmp(evt_ent->d_name, ".")
+		    || !strcmp(evt_ent->d_name, "..")
+		    || !strcmp(evt_ent->d_name, "enable")
+		    || !strcmp(evt_ent->d_name, "filter"))
+			continue;
+
+		len = snprintf(event_opt, MAX_EVOPT_LEN, "%s:%s", sys_name,
+			       evt_ent->d_name);
+		if (len < 0)
+			return EVT_FAILED;
+
+		rem -= len;
+		if (flags) {
+			if (rem < strlen(flags) + 1)
+				return EVT_FAILED;
+
+			strcat(event_opt, ":");
+			strcat(event_opt, flags);
+		}
+
+		if (parse_events(NULL, event_opt, 0))
+			return EVT_FAILED;
+	}
+
+	return EVT_HANDLED_ALL;
 }
 
-static int parse_tracepoint_event(const char **strp,
-				    struct perf_counter_attr *attr)
+
+static enum event_result parse_tracepoint_event(const char **strp,
+				    struct perf_event_attr *attr)
 {
 	const char *evt_name;
 	char *flags;
 	char sys_name[MAX_EVENT_LENGTH];
-	char id_buf[4];
-	int fd;
 	unsigned int sys_length, evt_length;
-	u64 id;
-	char evt_path[MAXPATHLEN];
 
 	if (valid_debugfs_mount(debugfs_path))
 		return 0;
 
 	evt_name = strchr(*strp, ':');
 	if (!evt_name)
-		return 0;
+		return EVT_FAILED;
 
 	sys_length = evt_name - *strp;
 	if (sys_length >= MAX_EVENT_LENGTH)
@@ -434,32 +529,22 @@ static int parse_tracepoint_event(const char **strp,
 
 	flags = strchr(evt_name, ':');
 	if (flags) {
-		*flags = '\0';
+		/* split it out: */
+		evt_name = strndup(evt_name, flags - evt_name);
 		flags++;
-		if (!strncmp(flags, "record", strlen(flags)))
-			attr->sample_type |= PERF_SAMPLE_RAW;
 	}
 
 	evt_length = strlen(evt_name);
 	if (evt_length >= MAX_EVENT_LENGTH)
-		return 0;
-
-	snprintf(evt_path, MAXPATHLEN, "%s/%s/%s/id", debugfs_path,
-		 sys_name, evt_name);
-	fd = open(evt_path, O_RDONLY);
-	if (fd < 0)
-		return 0;
+		return EVT_FAILED;
 
-	if (read(fd, id_buf, sizeof(id_buf)) < 0) {
-		close(fd);
-		return 0;
-	}
-	close(fd);
-	id = atoll(id_buf);
-	attr->config = id;
-	attr->type = PERF_TYPE_TRACEPOINT;
-	*strp = evt_name + evt_length;
-	return 1;
+	if (!strcmp(evt_name, "*")) {
+		*strp = evt_name + evt_length;
+		return parse_subsystem_tracepoint_event(sys_name, flags);
+	} else
+		return parse_single_tracepoint_event(sys_name, evt_name,
+						     evt_length, flags,
+						     attr, strp);
 }
 
 static int check_events(const char *str, unsigned int i)
@@ -477,8 +562,8 @@ static int check_events(const char *str, unsigned int i)
 	return 0;
 }
 
-static int
-parse_symbolic_event(const char **strp, struct perf_counter_attr *attr)
+static enum event_result
+parse_symbolic_event(const char **strp, struct perf_event_attr *attr)
 {
 	const char *str = *strp;
 	unsigned int i;
@@ -490,32 +575,33 @@ parse_symbolic_event(const char **strp, struct perf_counter_attr *attr)
 			attr->type = event_symbols[i].type;
 			attr->config = event_symbols[i].config;
 			*strp = str + n;
-			return 1;
+			return EVT_HANDLED;
 		}
 	}
-	return 0;
+	return EVT_FAILED;
 }
 
-static int parse_raw_event(const char **strp, struct perf_counter_attr *attr)
+static enum event_result
+parse_raw_event(const char **strp, struct perf_event_attr *attr)
 {
 	const char *str = *strp;
 	u64 config;
 	int n;
 
 	if (*str != 'r')
-		return 0;
+		return EVT_FAILED;
 	n = hex2u64(str + 1, &config);
 	if (n > 0) {
 		*strp = str + n + 1;
 		attr->type = PERF_TYPE_RAW;
 		attr->config = config;
-		return 1;
+		return EVT_HANDLED;
 	}
-	return 0;
+	return EVT_FAILED;
 }
 
-static int
-parse_numeric_event(const char **strp, struct perf_counter_attr *attr)
+static enum event_result
+parse_numeric_event(const char **strp, struct perf_event_attr *attr)
 {
 	const char *str = *strp;
 	char *endp;
@@ -530,14 +616,14 @@ parse_numeric_event(const char **strp, struct perf_counter_attr *attr)
 			attr->type = type;
 			attr->config = config;
 			*strp = endp;
-			return 1;
+			return EVT_HANDLED;
 		}
 	}
-	return 0;
+	return EVT_FAILED;
 }
 
-static int
-parse_event_modifier(const char **strp, struct perf_counter_attr *attr)
+static enum event_result
+parse_event_modifier(const char **strp, struct perf_event_attr *attr)
 {
 	const char *str = *strp;
 	int eu = 1, ek = 1, eh = 1;
@@ -569,37 +655,84 @@ parse_event_modifier(const char **strp, struct perf_counter_attr *attr)
  * Each event can have multiple symbolic names.
  * Symbolic names are (almost) exactly matched.
  */
-static int parse_event_symbols(const char **str, struct perf_counter_attr *attr)
+static enum event_result
+parse_event_symbols(const char **str, struct perf_event_attr *attr)
 {
-	if (!(parse_tracepoint_event(str, attr) ||
-	      parse_raw_event(str, attr) ||
-	      parse_numeric_event(str, attr) ||
-	      parse_symbolic_event(str, attr) ||
-	      parse_generic_hw_event(str, attr)))
-		return 0;
+	enum event_result ret;
+
+	ret = parse_tracepoint_event(str, attr);
+	if (ret != EVT_FAILED)
+		goto modifier;
+
+	ret = parse_raw_event(str, attr);
+	if (ret != EVT_FAILED)
+		goto modifier;
+
+	ret = parse_numeric_event(str, attr);
+	if (ret != EVT_FAILED)
+		goto modifier;
+
+	ret = parse_symbolic_event(str, attr);
+	if (ret != EVT_FAILED)
+		goto modifier;
 
+	ret = parse_generic_hw_event(str, attr);
+	if (ret != EVT_FAILED)
+		goto modifier;
+
+	return EVT_FAILED;
+
+modifier:
 	parse_event_modifier(str, attr);
 
-	return 1;
+	return ret;
 }
 
+static void store_event_type(const char *orgname)
+{
+	char filename[PATH_MAX], *c;
+	FILE *file;
+	int id;
+
+	sprintf(filename, "/sys/kernel/debug/tracing/events/%s/id", orgname);
+	c = strchr(filename, ':');
+	if (c)
+		*c = '/';
+
+	file = fopen(filename, "r");
+	if (!file)
+		return;
+	if (fscanf(file, "%i", &id) < 1)
+		die("cannot store event ID");
+	fclose(file);
+	perf_header__push_event(id, orgname);
+}
+
+
 int parse_events(const struct option *opt __used, const char *str, int unset __used)
 {
-	struct perf_counter_attr attr;
+	struct perf_event_attr attr;
+	enum event_result ret;
+
+	if (strchr(str, ':'))
+		store_event_type(str);
 
 	for (;;) {
 		if (nr_counters == MAX_COUNTERS)
 			return -1;
 
 		memset(&attr, 0, sizeof(attr));
-		if (!parse_event_symbols(&str, &attr))
+		ret = parse_event_symbols(&str, &attr);
+		if (ret == EVT_FAILED)
 			return -1;
 
 		if (!(*str == 0 || *str == ',' || isspace(*str)))
 			return -1;
 
-		attrs[nr_counters] = attr;
-		nr_counters++;
+		if (ret != EVT_HANDLED_ALL) {
+			attrs[nr_counters] = attr;
+			nr_counters++;
+		}
 
 		if (*str == 0)
 			break;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 60704c1..30c6081 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -16,7 +16,7 @@ extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
 
 extern int			nr_counters;
 
-extern struct perf_counter_attr attrs[MAX_COUNTERS];
+extern struct perf_event_attr attrs[MAX_COUNTERS];
 
 extern const char *event_name(int ctr);
 extern const char *__event_name(int type, u64 config);
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index 8aa3464..2ee248f 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -104,6 +104,8 @@ struct option {
 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
 #define OPT_CALLBACK(s, l, v, a, h, f) \
 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f) }
+#define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
+	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f), .flags = PARSE_OPT_NOARG }
 #define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
 	{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f), .defval = (intptr_t)d, .flags = PARSE_OPT_LASTARG_DEFAULT }
 
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
new file mode 100644
index 0000000..a778fd0
--- /dev/null
+++ b/tools/perf/util/svghelper.c
@@ -0,0 +1,488 @@
+/*
+ * svghelper.c - helper functions for outputting svg
+ *
+ * (C) Copyright 2009 Intel Corporation
+ *
+ * Authors:
+ *     Arjan van de Ven <arjan@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "svghelper.h"
+
+static u64 first_time, last_time;
+static u64 turbo_frequency, max_freq;
+
+
+#define SLOT_MULT 30.0
+#define SLOT_HEIGHT 25.0
+
+int svg_page_width = 1000;
+
+#define MIN_TEXT_SIZE 0.001
+
+static u64 total_height;
+static FILE *svgfile;
+
+static double cpu2slot(int cpu)
+{
+	return 2 * cpu + 1;
+}
+
+static double cpu2y(int cpu)
+{
+	return cpu2slot(cpu) * SLOT_MULT;
+}
+
+static double time2pixels(u64 time)
+{
+	double X;
+
+	X = 1.0 * svg_page_width * (time - first_time) / (last_time - first_time);
+	return X;
+}
+
+/*
+ * Round text sizes so that the svg viewer only needs a discrete
+ * number of renderings of the font
+ */
+static double round_text_size(double size)
+{
+	int loop = 100;
+	double target = 10.0;
+
+	if (size >= 10.0)
+		return size;
+	while (loop--) {
+		if (size >= target)
+			return target;
+		target = target / 2.0;
+	}
+	return size;
+}
+
+void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
+{
+	int new_width;
+
+	svgfile = fopen(filename, "w");
+	if (!svgfile) {
+		fprintf(stderr, "Cannot open %s for output\n", filename);
+		return;
+	}
+	first_time = start;
+	first_time = first_time / 100000000 * 100000000;
+	last_time = end;
+
+	/*
+	 * if the recording is short, we default to a width of 1000, but
+	 * for longer recordings we want at least 200 units of width per second
+	 */
+	new_width = (last_time - first_time) / 5000000;
+
+	if (new_width > svg_page_width)
+		svg_page_width = new_width;
+
+	total_height = (1 + rows + cpu2slot(cpus)) * SLOT_MULT;
+	fprintf(svgfile, "<?xml version=\"1.0\" standalone=\"no\"?> \n");
+	fprintf(svgfile, "<svg width=\"%i\" height=\"%llu\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n", svg_page_width, total_height);
+
+	fprintf(svgfile, "<defs>\n  <style type=\"text/css\">\n    <![CDATA[\n");
+
+	fprintf(svgfile, "      rect          { stroke-width: 1; }\n");
+	fprintf(svgfile, "      rect.process  { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:1;   stroke:rgb(  0,  0,  0); } \n");
+	fprintf(svgfile, "      rect.process2 { fill:rgb(180,180,180); fill-opacity:0.9; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
+	fprintf(svgfile, "      rect.sample   { fill:rgb(  0,  0,255); fill-opacity:0.8; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
+	fprintf(svgfile, "      rect.blocked  { fill:rgb(255,  0,  0); fill-opacity:0.5; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
+	fprintf(svgfile, "      rect.waiting  { fill:rgb(214,214,  0); fill-opacity:0.3; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
+	fprintf(svgfile, "      rect.WAITING  { fill:rgb(255,214, 48); fill-opacity:0.6; stroke-width:0;   stroke:rgb(  0,  0,  0); } \n");
+	fprintf(svgfile, "      rect.cpu      { fill:rgb(192,192,192); fill-opacity:0.2; stroke-width:0.5; stroke:rgb(128,128,128); } \n");
+	fprintf(svgfile, "      rect.pstate   { fill:rgb(128,128,128); fill-opacity:0.8; stroke-width:0; } \n");
+	fprintf(svgfile, "      rect.c1       { fill:rgb(255,214,214); fill-opacity:0.5; stroke-width:0; } \n");
+	fprintf(svgfile, "      rect.c2       { fill:rgb(255,172,172); fill-opacity:0.5; stroke-width:0; } \n");
+	fprintf(svgfile, "      rect.c3       { fill:rgb(255,130,130); fill-opacity:0.5; stroke-width:0; } \n");
+	fprintf(svgfile, "      rect.c4       { fill:rgb(255, 88, 88); fill-opacity:0.5; stroke-width:0; } \n");
+	fprintf(svgfile, "      rect.c5       { fill:rgb(255, 44, 44); fill-opacity:0.5; stroke-width:0; } \n");
+	fprintf(svgfile, "      rect.c6       { fill:rgb(255,  0,  0); fill-opacity:0.5; stroke-width:0; } \n");
+	fprintf(svgfile, "      line.pstate   { stroke:rgb(255,255,  0); stroke-opacity:0.8; stroke-width:2; } \n");
+
+	fprintf(svgfile, "    ]]>\n   </style>\n</defs>\n");
+}
+
+void svg_box(int Yslot, u64 start, u64 end, const char *type)
+{
+	if (!svgfile)
+		return;
+
+	fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"%s\"/>\n",
+		time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT, type);
+}
+
+void svg_sample(int Yslot, int cpu, u64 start, u64 end)
+{
+	double text_size;
+	if (!svgfile)
+		return;
+
+	fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"sample\"/>\n",
+		time2pixels(start), time2pixels(end)-time2pixels(start), Yslot * SLOT_MULT, SLOT_HEIGHT);
+
+	text_size = (time2pixels(end)-time2pixels(start));
+	if (cpu > 9)
+		text_size = text_size/2;
+	if (text_size > 1.25)
+		text_size = 1.25;
+	text_size = round_text_size(text_size);
+
+	if (text_size > MIN_TEXT_SIZE)
+		fprintf(svgfile, "<text x=\"%1.8f\" y=\"%1.8f\" font-size=\"%1.8fpt\">%i</text>\n",
+			time2pixels(start), Yslot *  SLOT_MULT + SLOT_HEIGHT - 1, text_size,  cpu + 1);
+
+}
+
+static char *time_to_string(u64 duration)
+{
+	static char text[80];
+
+	text[0] = 0;
+
+	if (duration < 1000) /* less than 1 usec */
+		return text;
+
+	if (duration < 1000 * 1000) { /* less than 1 msec */
+		sprintf(text, "%4.1f us", duration / 1000.0);
+		return text;
+	}
+	sprintf(text, "%4.1f ms", duration / 1000.0 / 1000);
+
+	return text;
+}
+
+void svg_waiting(int Yslot, u64 start, u64 end)
+{
+	char *text;
+	const char *style;
+	double font_size;
+
+	if (!svgfile)
+		return;
+
+	style = "waiting";
+
+	if (end-start > 10 * 1000000) /* 10 msec */
+		style = "WAITING";
+
+	text = time_to_string(end-start);
+
+	font_size = 1.0 * (time2pixels(end)-time2pixels(start));
+
+	if (font_size > 3)
+		font_size = 3;
+
+	font_size = round_text_size(font_size);
+
+	fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), Yslot * SLOT_MULT);
+	fprintf(svgfile, "<rect x=\"0\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
+		time2pixels(end)-time2pixels(start), SLOT_HEIGHT, style);
+	if (font_size > MIN_TEXT_SIZE)
+		fprintf(svgfile, "<text transform=\"rotate(90)\" font-size=\"%1.8fpt\"> %s</text>\n",
+			font_size, text);
+	fprintf(svgfile, "</g>\n");
+}
+
+static char *cpu_model(void)
+{
+	static char cpu_m[255];
+	char buf[256];
+	FILE *file;
+
+	cpu_m[0] = 0;
+	/* CPU type */
+	file = fopen("/proc/cpuinfo", "r");
+	if (file) {
+		while (fgets(buf, 255, file)) {
+			if (strstr(buf, "model name")) {
+				strncpy(cpu_m, &buf[13], 255);
+				break;
+			}
+		}
+		fclose(file);
+	}
+	return cpu_m;
+}
+
+void svg_cpu_box(int cpu, u64 __max_freq, u64 __turbo_freq)
+{
+	char cpu_string[80];
+	if (!svgfile)
+		return;
+
+	max_freq = __max_freq;
+	turbo_frequency = __turbo_freq;
+
+	fprintf(svgfile, "<rect x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\" class=\"cpu\"/>\n",
+		time2pixels(first_time),
+		time2pixels(last_time)-time2pixels(first_time),
+		cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT);
+
+	sprintf(cpu_string, "CPU %i", (int)cpu+1);
+	fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\">%s</text>\n",
+		10+time2pixels(first_time), cpu2y(cpu) + SLOT_HEIGHT/2, cpu_string);
+
+	fprintf(svgfile, "<text transform=\"translate(%4.8f,%4.8f)\" font-size=\"1.25pt\">%s</text>\n",
+		10+time2pixels(first_time), cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - 4, cpu_model());
+}
+
+void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name)
+{
+	double width;
+
+	if (!svgfile)
+		return;
+
+
+	fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\">\n", time2pixels(start), cpu2y(cpu));
+	fprintf(svgfile, "<rect x=\"0\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
+		time2pixels(end)-time2pixels(start), SLOT_MULT+SLOT_HEIGHT, type);
+	width = time2pixels(end)-time2pixels(start);
+	if (width > 6)
+		width = 6;
+
+	width = round_text_size(width);
+
+	if (width > MIN_TEXT_SIZE)
+		fprintf(svgfile, "<text transform=\"rotate(90)\" font-size=\"%3.8fpt\">%s</text>\n",
+			width, name);
+
+	fprintf(svgfile, "</g>\n");
+}
+
+void svg_cstate(int cpu, u64 start, u64 end, int type)
+{
+	double width;
+	char style[128];
+
+	if (!svgfile)
+		return;
+
+
+	if (type > 6)
+		type = 6;
+	sprintf(style, "c%i", type);
+
+	fprintf(svgfile, "<rect class=\"%s\" x=\"%4.8f\" width=\"%4.8f\" y=\"%4.1f\" height=\"%4.1f\"/>\n",
+		style,
+		time2pixels(start), time2pixels(end)-time2pixels(start),
+		cpu2y(cpu), SLOT_MULT+SLOT_HEIGHT);
+
+	width = (time2pixels(end)-time2pixels(start))/2.0;
+	if (width > 6)
+		width = 6;
+
+	width = round_text_size(width);
+
+	if (width > MIN_TEXT_SIZE)
+		fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\" font-size=\"%3.8fpt\">C%i</text>\n",
+			time2pixels(start), cpu2y(cpu)+width, width, type);
+}
+
+static char *HzToHuman(unsigned long hz)
+{
+	static char buffer[1024];
+	unsigned long long Hz;
+
+	memset(buffer, 0, 1024);
+
+	Hz = hz;
+
+	/* default: just put the Number in */
+	sprintf(buffer, "%9lli", Hz);
+
+	if (Hz > 1000)
+		sprintf(buffer, " %6lli Mhz", (Hz+500)/1000);
+
+	if (Hz > 1500000)
+		sprintf(buffer, " %6.2f Ghz", (Hz+5000.0)/1000000);
+
+	if (Hz == turbo_frequency)
+		sprintf(buffer, "Turbo");
+
+	return buffer;
+}
+
+void svg_pstate(int cpu, u64 start, u64 end, u64 freq)
+{
+	double height = 0;
+
+	if (!svgfile)
+		return;
+
+	if (max_freq)
+		height = freq * 1.0 / max_freq * (SLOT_HEIGHT + SLOT_MULT);
+	height = 1 + cpu2y(cpu) + SLOT_MULT + SLOT_HEIGHT - height;
+	fprintf(svgfile, "<line x1=\"%4.8f\" x2=\"%4.8f\" y1=\"%4.1f\" y2=\"%4.1f\" class=\"pstate\"/>\n",
+		time2pixels(start), time2pixels(end), height, height);
+	fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\" font-size=\"0.25pt\">%s</text>\n",
+		time2pixels(start), height+0.9, HzToHuman(freq));
+
+}
+
+
+void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2)
+{
+	double height;
+
+	if (!svgfile)
+		return;
+
+
+	if (row1 < row2) {
+		if (row1) {
+			fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
+				time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT + SLOT_MULT/32);
+			if (desc2)
+				fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &gt;</text></g>\n",
+					time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT + SLOT_HEIGHT/48, desc2);
+		}
+		if (row2) {
+			fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
+				time2pixels(start), row2 * SLOT_MULT - SLOT_MULT/32,  time2pixels(start), row2 * SLOT_MULT);
+			if (desc1)
+				fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &gt;</text></g>\n",
+					time2pixels(start), row2 * SLOT_MULT - SLOT_MULT/32, desc1);
+		}
+	} else {
+		if (row2) {
+			fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
+				time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT + SLOT_MULT/32);
+			if (desc1)
+				fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &lt;</text></g>\n",
+					time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT + SLOT_MULT/48, desc1);
+		}
+		if (row1) {
+			fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
+				time2pixels(start), row1 * SLOT_MULT - SLOT_MULT/32,  time2pixels(start), row1 * SLOT_MULT);
+			if (desc2)
+				fprintf(svgfile, "<g transform=\"translate(%4.8f,%4.8f)\"><text transform=\"rotate(90)\" font-size=\"0.02pt\">%s &lt;</text></g>\n",
+					time2pixels(start), row1 * SLOT_MULT - SLOT_HEIGHT/32, desc2);
+		}
+	}
+	height = row1 * SLOT_MULT;
+	if (row2 > row1)
+		height += SLOT_HEIGHT;
+	if (row1)
+		fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(32,255,32)\"/>\n",
+			time2pixels(start), height);
+}
+
+void svg_wakeline(u64 start, int row1, int row2)
+{
+	double height;
+
+	if (!svgfile)
+		return;
+
+
+	if (row1 < row2)
+		fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
+			time2pixels(start), row1 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row2 * SLOT_MULT);
+	else
+		fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%4.2f\" style=\"stroke:rgb(32,255,32);stroke-width:0.009\"/>\n",
+			time2pixels(start), row2 * SLOT_MULT + SLOT_HEIGHT,  time2pixels(start), row1 * SLOT_MULT);
+
+	height = row1 * SLOT_MULT;
+	if (row2 > row1)
+		height += SLOT_HEIGHT;
+	fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(32,255,32)\"/>\n",
+			time2pixels(start), height);
+}
+
+void svg_interrupt(u64 start, int row)
+{
+	if (!svgfile)
+		return;
+
+	fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(255,128,128)\"/>\n",
+			time2pixels(start), row * SLOT_MULT);
+	fprintf(svgfile, "<circle  cx=\"%4.8f\" cy=\"%4.2f\" r = \"0.01\"  style=\"fill:rgb(255,128,128)\"/>\n",
+			time2pixels(start), row * SLOT_MULT + SLOT_HEIGHT);
+}
+
+void svg_text(int Yslot, u64 start, const char *text)
+{
+	if (!svgfile)
+		return;
+
+	fprintf(svgfile, "<text x=\"%4.8f\" y=\"%4.8f\">%s</text>\n",
+		time2pixels(start), Yslot * SLOT_MULT+SLOT_HEIGHT/2, text);
+}
+
+static void svg_legenda_box(int X, const char *text, const char *style)
+{
+	double boxsize;
+	boxsize = SLOT_HEIGHT / 2;
+
+	fprintf(svgfile, "<rect x=\"%i\" width=\"%4.8f\" y=\"0\" height=\"%4.1f\" class=\"%s\"/>\n",
+		X, boxsize, boxsize, style);
+	fprintf(svgfile, "<text transform=\"translate(%4.8f, %4.8f)\" font-size=\"%4.8fpt\">%s</text>\n",
+		X + boxsize + 5, boxsize, 0.8 * boxsize, text);
+}
+
+void svg_legenda(void)
+{
+	if (!svgfile)
+		return;
+
+	svg_legenda_box(0,	"Running", "sample");
+	svg_legenda_box(100,	"Idle","rect.c1");
+	svg_legenda_box(200,	"Deeper Idle", "rect.c3");
+	svg_legenda_box(350,	"Deepest Idle", "rect.c6");
+	svg_legenda_box(550,	"Sleeping", "process2");
+	svg_legenda_box(650,	"Waiting for cpu", "waiting");
+	svg_legenda_box(800,	"Blocked on IO", "blocked");
+}
+
+void svg_time_grid(void)
+{
+	u64 i;
+
+	if (!svgfile)
+		return;
+
+	i = first_time;
+	while (i < last_time) {
+		int color = 220;
+		double thickness = 0.075;
+		if ((i % 100000000) == 0) {
+			thickness = 0.5;
+			color = 192;
+		}
+		if ((i % 1000000000) == 0) {
+			thickness = 2.0;
+			color = 128;
+		}
+
+		fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%llu\" style=\"stroke:rgb(%i,%i,%i);stroke-width:%1.3f\"/>\n",
+			time2pixels(i), SLOT_MULT/2, time2pixels(i), total_height, color, color, color, thickness);
+
+		i += 10000000;
+	}
+}
+
+void svg_close(void)
+{
+	if (svgfile) {
+		fprintf(svgfile, "</svg>\n");
+		fclose(svgfile);
+		svgfile = NULL;
+	}
+}
diff --git a/tools/perf/util/svghelper.h b/tools/perf/util/svghelper.h
new file mode 100644
index 0000000..cd93195
--- /dev/null
+++ b/tools/perf/util/svghelper.h
@@ -0,0 +1,28 @@
+#ifndef _INCLUDE_GUARD_SVG_HELPER_
+#define _INCLUDE_GUARD_SVG_HELPER_
+
+#include "types.h"
+
+extern void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end);
+extern void svg_box(int Yslot, u64 start, u64 end, const char *type);
+extern void svg_sample(int Yslot, int cpu, u64 start, u64 end);
+extern void svg_waiting(int Yslot, u64 start, u64 end);
+extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency);
+
+
+extern void svg_process(int cpu, u64 start, u64 end, const char *type, const char *name);
+extern void svg_cstate(int cpu, u64 start, u64 end, int type);
+extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq);
+
+
+extern void svg_time_grid(void);
+extern void svg_legenda(void);
+extern void svg_wakeline(u64 start, int row1, int row2);
+extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2);
+extern void svg_interrupt(u64 start, int row);
+extern void svg_text(int Yslot, u64 start, const char *text);
+extern void svg_close(void);
+
+extern int svg_page_width;
+
+#endif
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 7635928..45efb5d 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -8,7 +8,7 @@
 
 static struct thread *thread__new(pid_t pid)
 {
-	struct thread *self = malloc(sizeof(*self));
+	struct thread *self = calloc(1, sizeof(*self));
 
 	if (self != NULL) {
 		self->pid = pid;
@@ -85,7 +85,7 @@ register_idle_thread(struct rb_root *threads, struct thread **last_match)
 {
 	struct thread *thread = threads__findnew(0, threads, last_match);
 
-	if (!thread || thread__set_comm(thread, "[init]")) {
+	if (!thread || thread__set_comm(thread, "swapper")) {
 		fprintf(stderr, "problem inserting idle task.\n");
 		exit(-1);
 	}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 634f280..32aea3c 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -4,10 +4,11 @@
 #include "symbol.h"
 
 struct thread {
-	struct rb_node	 rb_node;
-	struct list_head maps;
-	pid_t		 pid;
-	char		 *comm;
+	struct rb_node		rb_node;
+	struct list_head	maps;
+	pid_t			pid;
+	char			shortname[3];
+	char			*comm;
 };
 
 int thread__set_comm(struct thread *self, const char *comm);
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c
index 6c9302a..af4b057 100644
--- a/tools/perf/util/trace-event-info.c
+++ b/tools/perf/util/trace-event-info.c
@@ -458,7 +458,7 @@ static void read_proc_kallsyms(void)
 static void read_ftrace_printk(void)
 {
 	unsigned int size, check_size;
-	const char *path;
+	char *path;
 	struct stat st;
 	int ret;
 
@@ -468,23 +468,24 @@ static void read_ftrace_printk(void)
 		/* not found */
 		size = 0;
 		write_or_die(&size, 4);
-		return;
+		goto out;
 	}
 	size = get_size(path);
 	write_or_die(&size, 4);
 	check_size = copy_file(path);
 	if (size != check_size)
 		die("error in size of file '%s'", path);
-
+out:
+	put_tracing_file(path);
 }
 
 static struct tracepoint_path *
-get_tracepoints_path(struct perf_counter_attr *pattrs, int nb_counters)
+get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
 {
 	struct tracepoint_path path, *ppath = &path;
 	int i;
 
-	for (i = 0; i < nb_counters; i++) {
+	for (i = 0; i < nb_events; i++) {
 		if (pattrs[i].type != PERF_TYPE_TRACEPOINT)
 			continue;
 		ppath->next = tracepoint_id_to_path(pattrs[i].config);
@@ -495,7 +496,7 @@ get_tracepoints_path(struct perf_counter_attr *pattrs, int nb_counters)
 
 	return path.next;
 }
-void read_tracing_data(struct perf_counter_attr *pattrs, int nb_counters)
+void read_tracing_data(struct perf_event_attr *pattrs, int nb_events)
 {
 	char buf[BUFSIZ];
 	struct tracepoint_path *tps;
@@ -529,7 +530,7 @@ void read_tracing_data(struct perf_counter_attr *pattrs, int nb_counters)
 	page_size = getpagesize();
 	write_or_die(&page_size, 4);
 
-	tps = get_tracepoints_path(pattrs, nb_counters);
+	tps = get_tracepoints_path(pattrs, nb_events);
 
 	read_header_files();
 	read_ftrace_files(tps);
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 629e602..f6a8437 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -1776,6 +1776,29 @@ static unsigned long long read_size(void *ptr, int size)
 	}
 }
 
+unsigned long long
+raw_field_value(struct event *event, const char *name, void *data)
+{
+	struct format_field *field;
+
+	field = find_any_field(event, name);
+	if (!field)
+		return 0ULL;
+
+	return read_size(data + field->offset, field->size);
+}
+
+void *raw_field_ptr(struct event *event, const char *name, void *data)
+{
+	struct format_field *field;
+
+	field = find_any_field(event, name);
+	if (!field)
+		return NULL;
+
+	return data + field->offset;
+}
+
 static int get_common_info(const char *type, int *offset, int *size)
 {
 	struct event *event;
@@ -1799,7 +1822,7 @@ static int get_common_info(const char *type, int *offset, int *size)
 	return 0;
 }
 
-static int parse_common_type(void *data)
+int trace_parse_common_type(void *data)
 {
 	static int type_offset;
 	static int type_size;
@@ -1832,7 +1855,7 @@ static int parse_common_pid(void *data)
 	return read_size(data + pid_offset, pid_size);
 }
 
-static struct event *find_event(int id)
+struct event *trace_find_event(int id)
 {
 	struct event *event;
 
@@ -2420,8 +2443,8 @@ get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func,
 	int type;
 	int pid;
 
-	type = parse_common_type(next->data);
-	event = find_event(type);
+	type = trace_parse_common_type(next->data);
+	event = trace_find_event(type);
 	if (!event)
 		return NULL;
 
@@ -2502,8 +2525,8 @@ print_graph_entry_leaf(struct event *event, void *data, struct record *ret_rec)
 	int type;
 	int i;
 
-	type = parse_common_type(ret_rec->data);
-	ret_event = find_event(type);
+	type = trace_parse_common_type(ret_rec->data);
+	ret_event = trace_find_event(type);
 
 	field = find_field(ret_event, "rettime");
 	if (!field)
@@ -2696,11 +2719,13 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
 	nsecs -= secs * NSECS_PER_SEC;
 	usecs = nsecs / NSECS_PER_USEC;
 
-	type = parse_common_type(data);
+	type = trace_parse_common_type(data);
 
-	event = find_event(type);
-	if (!event)
-		die("ug! no event found for type %d", type);
+	event = trace_find_event(type);
+	if (!event) {
+		printf("ug! no event found for type %d\n", type);
+		return;
+	}
 
 	pid = parse_common_pid(data);
 
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c
index a1217a1..1b5c847 100644
--- a/tools/perf/util/trace-event-read.c
+++ b/tools/perf/util/trace-event-read.c
@@ -458,12 +458,13 @@ struct record *trace_read_data(int cpu)
 	return data;
 }
 
-void trace_report (void)
+void trace_report(void)
 {
 	const char *input_file = "trace.info";
 	char buf[BUFSIZ];
 	char test[] = { 23, 8, 68 };
 	char *version;
+	int show_version = 0;
 	int show_funcs = 0;
 	int show_printk = 0;
 
@@ -480,7 +481,8 @@ void trace_report (void)
 		die("not a trace file (missing tracing)");
 
 	version = read_string();
-	printf("version = %s\n", version);
+	if (show_version)
+		printf("version = %s\n", version);
 	free(version);
 
 	read_or_die(buf, 1);
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 420294a..693f815 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -234,7 +234,12 @@ extern int header_page_data_offset;
 extern int header_page_data_size;
 
 int parse_header_page(char *buf, unsigned long size);
+int trace_parse_common_type(void *data);
+struct event *trace_find_event(int id);
+unsigned long long
+raw_field_value(struct event *event, const char *name, void *data);
+void *raw_field_ptr(struct event *event, const char *name, void *data);
 
-void read_tracing_data(struct perf_counter_attr *pattrs, int nb_counters);
+void read_tracing_data(struct perf_event_attr *pattrs, int nb_events);
 
 #endif /* _TRACE_EVENTS_H */
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
new file mode 100644
index 0000000..daece36
--- /dev/null
+++ b/virt/kvm/Kconfig
@@ -0,0 +1,14 @@
+# KVM common configuration items and defaults
+
+config HAVE_KVM
+       bool
+
+config HAVE_KVM_IRQCHIP
+       bool
+
+config HAVE_KVM_EVENTFD
+       bool
+       select EVENTFD
+
+config KVM_APIC_ARCHITECTURE
+       bool
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 5ae620d..04d69cd 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -14,32 +14,28 @@
 
 #include "coalesced_mmio.h"
 
-static int coalesced_mmio_in_range(struct kvm_io_device *this,
-				   gpa_t addr, int len, int is_write)
+static inline struct kvm_coalesced_mmio_dev *to_mmio(struct kvm_io_device *dev)
+{
+	return container_of(dev, struct kvm_coalesced_mmio_dev, dev);
+}
+
+static int coalesced_mmio_in_range(struct kvm_coalesced_mmio_dev *dev,
+				   gpa_t addr, int len)
 {
-	struct kvm_coalesced_mmio_dev *dev =
-				(struct kvm_coalesced_mmio_dev*)this->private;
 	struct kvm_coalesced_mmio_zone *zone;
-	int next;
+	struct kvm_coalesced_mmio_ring *ring;
+	unsigned avail;
 	int i;
 
-	if (!is_write)
-		return 0;
-
-	/* kvm->lock is taken by the caller and must be not released before
-         * dev.read/write
-         */
-
 	/* Are we able to batch it ? */
 
 	/* last is the first free entry
 	 * check if we don't meet the first used entry
 	 * there is always one unused entry in the buffer
 	 */
-
-	next = (dev->kvm->coalesced_mmio_ring->last + 1) %
-							KVM_COALESCED_MMIO_MAX;
-	if (next == dev->kvm->coalesced_mmio_ring->first) {
+	ring = dev->kvm->coalesced_mmio_ring;
+	avail = (ring->first - ring->last - 1) % KVM_COALESCED_MMIO_MAX;
+	if (avail < KVM_MAX_VCPUS) {
 		/* full */
 		return 0;
 	}
@@ -60,14 +56,15 @@ static int coalesced_mmio_in_range(struct kvm_io_device *this,
 	return 0;
 }
 
-static void coalesced_mmio_write(struct kvm_io_device *this,
-				 gpa_t addr, int len, const void *val)
+static int coalesced_mmio_write(struct kvm_io_device *this,
+				gpa_t addr, int len, const void *val)
 {
-	struct kvm_coalesced_mmio_dev *dev =
-				(struct kvm_coalesced_mmio_dev*)this->private;
+	struct kvm_coalesced_mmio_dev *dev = to_mmio(this);
 	struct kvm_coalesced_mmio_ring *ring = dev->kvm->coalesced_mmio_ring;
+	if (!coalesced_mmio_in_range(dev, addr, len))
+		return -EOPNOTSUPP;
 
-	/* kvm->lock must be taken by caller before call to in_range()*/
+	spin_lock(&dev->lock);
 
 	/* copy data in first free entry of the ring */
 
@@ -76,29 +73,40 @@ static void coalesced_mmio_write(struct kvm_io_device *this,
 	memcpy(ring->coalesced_mmio[ring->last].data, val, len);
 	smp_wmb();
 	ring->last = (ring->last + 1) % KVM_COALESCED_MMIO_MAX;
+	spin_unlock(&dev->lock);
+	return 0;
 }
 
 static void coalesced_mmio_destructor(struct kvm_io_device *this)
 {
-	kfree(this);
+	struct kvm_coalesced_mmio_dev *dev = to_mmio(this);
+
+	kfree(dev);
 }
 
+static const struct kvm_io_device_ops coalesced_mmio_ops = {
+	.write      = coalesced_mmio_write,
+	.destructor = coalesced_mmio_destructor,
+};
+
 int kvm_coalesced_mmio_init(struct kvm *kvm)
 {
 	struct kvm_coalesced_mmio_dev *dev;
+	int ret;
 
 	dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL);
 	if (!dev)
 		return -ENOMEM;
-	dev->dev.write  = coalesced_mmio_write;
-	dev->dev.in_range  = coalesced_mmio_in_range;
-	dev->dev.destructor  = coalesced_mmio_destructor;
-	dev->dev.private  = dev;
+	spin_lock_init(&dev->lock);
+	kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops);
 	dev->kvm = kvm;
 	kvm->coalesced_mmio_dev = dev;
-	kvm_io_bus_register_dev(&kvm->mmio_bus, &dev->dev);
 
-	return 0;
+	ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev);
+	if (ret < 0)
+		kfree(dev);
+
+	return ret;
 }
 
 int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm,
@@ -109,16 +117,16 @@ int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm,
 	if (dev == NULL)
 		return -EINVAL;
 
-	mutex_lock(&kvm->lock);
+	down_write(&kvm->slots_lock);
 	if (dev->nb_zones >= KVM_COALESCED_MMIO_ZONE_MAX) {
-		mutex_unlock(&kvm->lock);
+		up_write(&kvm->slots_lock);
 		return -ENOBUFS;
 	}
 
 	dev->zone[dev->nb_zones] = *zone;
 	dev->nb_zones++;
 
-	mutex_unlock(&kvm->lock);
+	up_write(&kvm->slots_lock);
 	return 0;
 }
 
@@ -132,7 +140,7 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
 	if (dev == NULL)
 		return -EINVAL;
 
-	mutex_lock(&kvm->lock);
+	down_write(&kvm->slots_lock);
 
 	i = dev->nb_zones;
 	while(i) {
@@ -150,7 +158,7 @@ int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm,
 		i--;
 	}
 
-	mutex_unlock(&kvm->lock);
+	up_write(&kvm->slots_lock);
 
 	return 0;
 }
diff --git a/virt/kvm/coalesced_mmio.h b/virt/kvm/coalesced_mmio.h
index 5ac0ec6..4b49f27 100644
--- a/virt/kvm/coalesced_mmio.h
+++ b/virt/kvm/coalesced_mmio.h
@@ -12,6 +12,7 @@
 struct kvm_coalesced_mmio_dev {
 	struct kvm_io_device dev;
 	struct kvm *kvm;
+	spinlock_t lock;
 	int nb_zones;
 	struct kvm_coalesced_mmio_zone zone[KVM_COALESCED_MMIO_ZONE_MAX];
 };
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
new file mode 100644
index 0000000..bb4ebd8
--- /dev/null
+++ b/virt/kvm/eventfd.c
@@ -0,0 +1,578 @@
+/*
+ * kvm eventfd support - use eventfd objects to signal various KVM events
+ *
+ * Copyright 2009 Novell.  All Rights Reserved.
+ *
+ * Author:
+ *	Gregory Haskins <ghaskins@novell.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU 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/kvm_host.h>
+#include <linux/kvm.h>
+#include <linux/workqueue.h>
+#include <linux/syscalls.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/file.h>
+#include <linux/list.h>
+#include <linux/eventfd.h>
+#include <linux/kernel.h>
+
+#include "iodev.h"
+
+/*
+ * --------------------------------------------------------------------
+ * irqfd: Allows an fd to be used to inject an interrupt to the guest
+ *
+ * Credit goes to Avi Kivity for the original idea.
+ * --------------------------------------------------------------------
+ */
+
+struct _irqfd {
+	struct kvm               *kvm;
+	struct eventfd_ctx       *eventfd;
+	int                       gsi;
+	struct list_head          list;
+	poll_table                pt;
+	wait_queue_head_t        *wqh;
+	wait_queue_t              wait;
+	struct work_struct        inject;
+	struct work_struct        shutdown;
+};
+
+static struct workqueue_struct *irqfd_cleanup_wq;
+
+static void
+irqfd_inject(struct work_struct *work)
+{
+	struct _irqfd *irqfd = container_of(work, struct _irqfd, inject);
+	struct kvm *kvm = irqfd->kvm;
+
+	mutex_lock(&kvm->irq_lock);
+	kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 1);
+	kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, irqfd->gsi, 0);
+	mutex_unlock(&kvm->irq_lock);
+}
+
+/*
+ * Race-free decouple logic (ordering is critical)
+ */
+static void
+irqfd_shutdown(struct work_struct *work)
+{
+	struct _irqfd *irqfd = container_of(work, struct _irqfd, shutdown);
+
+	/*
+	 * Synchronize with the wait-queue and unhook ourselves to prevent
+	 * further events.
+	 */
+	remove_wait_queue(irqfd->wqh, &irqfd->wait);
+
+	/*
+	 * We know no new events will be scheduled at this point, so block
+	 * until all previously outstanding events have completed
+	 */
+	flush_work(&irqfd->inject);
+
+	/*
+	 * It is now safe to release the object's resources
+	 */
+	eventfd_ctx_put(irqfd->eventfd);
+	kfree(irqfd);
+}
+
+
+/* assumes kvm->irqfds.lock is held */
+static bool
+irqfd_is_active(struct _irqfd *irqfd)
+{
+	return list_empty(&irqfd->list) ? false : true;
+}
+
+/*
+ * Mark the irqfd as inactive and schedule it for removal
+ *
+ * assumes kvm->irqfds.lock is held
+ */
+static void
+irqfd_deactivate(struct _irqfd *irqfd)
+{
+	BUG_ON(!irqfd_is_active(irqfd));
+
+	list_del_init(&irqfd->list);
+
+	queue_work(irqfd_cleanup_wq, &irqfd->shutdown);
+}
+
+/*
+ * Called with wqh->lock held and interrupts disabled
+ */
+static int
+irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+	struct _irqfd *irqfd = container_of(wait, struct _irqfd, wait);
+	unsigned long flags = (unsigned long)key;
+
+	if (flags & POLLIN)
+		/* An event has been signaled, inject an interrupt */
+		schedule_work(&irqfd->inject);
+
+	if (flags & POLLHUP) {
+		/* The eventfd is closing, detach from KVM */
+		struct kvm *kvm = irqfd->kvm;
+		unsigned long flags;
+
+		spin_lock_irqsave(&kvm->irqfds.lock, flags);
+
+		/*
+		 * We must check if someone deactivated the irqfd before
+		 * we could acquire the irqfds.lock since the item is
+		 * deactivated from the KVM side before it is unhooked from
+		 * the wait-queue.  If it is already deactivated, we can
+		 * simply return knowing the other side will cleanup for us.
+		 * We cannot race against the irqfd going away since the
+		 * other side is required to acquire wqh->lock, which we hold
+		 */
+		if (irqfd_is_active(irqfd))
+			irqfd_deactivate(irqfd);
+
+		spin_unlock_irqrestore(&kvm->irqfds.lock, flags);
+	}
+
+	return 0;
+}
+
+static void
+irqfd_ptable_queue_proc(struct file *file, wait_queue_head_t *wqh,
+			poll_table *pt)
+{
+	struct _irqfd *irqfd = container_of(pt, struct _irqfd, pt);
+
+	irqfd->wqh = wqh;
+	add_wait_queue(wqh, &irqfd->wait);
+}
+
+static int
+kvm_irqfd_assign(struct kvm *kvm, int fd, int gsi)
+{
+	struct _irqfd *irqfd;
+	struct file *file = NULL;
+	struct eventfd_ctx *eventfd = NULL;
+	int ret;
+	unsigned int events;
+
+	irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
+	if (!irqfd)
+		return -ENOMEM;
+
+	irqfd->kvm = kvm;
+	irqfd->gsi = gsi;
+	INIT_LIST_HEAD(&irqfd->list);
+	INIT_WORK(&irqfd->inject, irqfd_inject);
+	INIT_WORK(&irqfd->shutdown, irqfd_shutdown);
+
+	file = eventfd_fget(fd);
+	if (IS_ERR(file)) {
+		ret = PTR_ERR(file);
+		goto fail;
+	}
+
+	eventfd = eventfd_ctx_fileget(file);
+	if (IS_ERR(eventfd)) {
+		ret = PTR_ERR(eventfd);
+		goto fail;
+	}
+
+	irqfd->eventfd = eventfd;
+
+	/*
+	 * Install our own custom wake-up handling so we are notified via
+	 * a callback whenever someone signals the underlying eventfd
+	 */
+	init_waitqueue_func_entry(&irqfd->wait, irqfd_wakeup);
+	init_poll_funcptr(&irqfd->pt, irqfd_ptable_queue_proc);
+
+	events = file->f_op->poll(file, &irqfd->pt);
+
+	spin_lock_irq(&kvm->irqfds.lock);
+	list_add_tail(&irqfd->list, &kvm->irqfds.items);
+	spin_unlock_irq(&kvm->irqfds.lock);
+
+	/*
+	 * Check if there was an event already pending on the eventfd
+	 * before we registered, and trigger it as if we didn't miss it.
+	 */
+	if (events & POLLIN)
+		schedule_work(&irqfd->inject);
+
+	/*
+	 * do not drop the file until the irqfd is fully initialized, otherwise
+	 * we might race against the POLLHUP
+	 */
+	fput(file);
+
+	return 0;
+
+fail:
+	if (eventfd && !IS_ERR(eventfd))
+		eventfd_ctx_put(eventfd);
+
+	if (!IS_ERR(file))
+		fput(file);
+
+	kfree(irqfd);
+	return ret;
+}
+
+void
+kvm_eventfd_init(struct kvm *kvm)
+{
+	spin_lock_init(&kvm->irqfds.lock);
+	INIT_LIST_HEAD(&kvm->irqfds.items);
+	INIT_LIST_HEAD(&kvm->ioeventfds);
+}
+
+/*
+ * shutdown any irqfd's that match fd+gsi
+ */
+static int
+kvm_irqfd_deassign(struct kvm *kvm, int fd, int gsi)
+{
+	struct _irqfd *irqfd, *tmp;
+	struct eventfd_ctx *eventfd;
+
+	eventfd = eventfd_ctx_fdget(fd);
+	if (IS_ERR(eventfd))
+		return PTR_ERR(eventfd);
+
+	spin_lock_irq(&kvm->irqfds.lock);
+
+	list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list) {
+		if (irqfd->eventfd == eventfd && irqfd->gsi == gsi)
+			irqfd_deactivate(irqfd);
+	}
+
+	spin_unlock_irq(&kvm->irqfds.lock);
+	eventfd_ctx_put(eventfd);
+
+	/*
+	 * Block until we know all outstanding shutdown jobs have completed
+	 * so that we guarantee there will not be any more interrupts on this
+	 * gsi once this deassign function returns.
+	 */
+	flush_workqueue(irqfd_cleanup_wq);
+
+	return 0;
+}
+
+int
+kvm_irqfd(struct kvm *kvm, int fd, int gsi, int flags)
+{
+	if (flags & KVM_IRQFD_FLAG_DEASSIGN)
+		return kvm_irqfd_deassign(kvm, fd, gsi);
+
+	return kvm_irqfd_assign(kvm, fd, gsi);
+}
+
+/*
+ * This function is called as the kvm VM fd is being released. Shutdown all
+ * irqfds that still remain open
+ */
+void
+kvm_irqfd_release(struct kvm *kvm)
+{
+	struct _irqfd *irqfd, *tmp;
+
+	spin_lock_irq(&kvm->irqfds.lock);
+
+	list_for_each_entry_safe(irqfd, tmp, &kvm->irqfds.items, list)
+		irqfd_deactivate(irqfd);
+
+	spin_unlock_irq(&kvm->irqfds.lock);
+
+	/*
+	 * Block until we know all outstanding shutdown jobs have completed
+	 * since we do not take a kvm* reference.
+	 */
+	flush_workqueue(irqfd_cleanup_wq);
+
+}
+
+/*
+ * create a host-wide workqueue for issuing deferred shutdown requests
+ * aggregated from all vm* instances. We need our own isolated single-thread
+ * queue to prevent deadlock against flushing the normal work-queue.
+ */
+static int __init irqfd_module_init(void)
+{
+	irqfd_cleanup_wq = create_singlethread_workqueue("kvm-irqfd-cleanup");
+	if (!irqfd_cleanup_wq)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void __exit irqfd_module_exit(void)
+{
+	destroy_workqueue(irqfd_cleanup_wq);
+}
+
+module_init(irqfd_module_init);
+module_exit(irqfd_module_exit);
+
+/*
+ * --------------------------------------------------------------------
+ * ioeventfd: translate a PIO/MMIO memory write to an eventfd signal.
+ *
+ * userspace can register a PIO/MMIO address with an eventfd for receiving
+ * notification when the memory has been touched.
+ * --------------------------------------------------------------------
+ */
+
+struct _ioeventfd {
+	struct list_head     list;
+	u64                  addr;
+	int                  length;
+	struct eventfd_ctx  *eventfd;
+	u64                  datamatch;
+	struct kvm_io_device dev;
+	bool                 wildcard;
+};
+
+static inline struct _ioeventfd *
+to_ioeventfd(struct kvm_io_device *dev)
+{
+	return container_of(dev, struct _ioeventfd, dev);
+}
+
+static void
+ioeventfd_release(struct _ioeventfd *p)
+{
+	eventfd_ctx_put(p->eventfd);
+	list_del(&p->list);
+	kfree(p);
+}
+
+static bool
+ioeventfd_in_range(struct _ioeventfd *p, gpa_t addr, int len, const void *val)
+{
+	u64 _val;
+
+	if (!(addr == p->addr && len == p->length))
+		/* address-range must be precise for a hit */
+		return false;
+
+	if (p->wildcard)
+		/* all else equal, wildcard is always a hit */
+		return true;
+
+	/* otherwise, we have to actually compare the data */
+
+	BUG_ON(!IS_ALIGNED((unsigned long)val, len));
+
+	switch (len) {
+	case 1:
+		_val = *(u8 *)val;
+		break;
+	case 2:
+		_val = *(u16 *)val;
+		break;
+	case 4:
+		_val = *(u32 *)val;
+		break;
+	case 8:
+		_val = *(u64 *)val;
+		break;
+	default:
+		return false;
+	}
+
+	return _val == p->datamatch ? true : false;
+}
+
+/* MMIO/PIO writes trigger an event if the addr/val match */
+static int
+ioeventfd_write(struct kvm_io_device *this, gpa_t addr, int len,
+		const void *val)
+{
+	struct _ioeventfd *p = to_ioeventfd(this);
+
+	if (!ioeventfd_in_range(p, addr, len, val))
+		return -EOPNOTSUPP;
+
+	eventfd_signal(p->eventfd, 1);
+	return 0;
+}
+
+/*
+ * This function is called as KVM is completely shutting down.  We do not
+ * need to worry about locking just nuke anything we have as quickly as possible
+ */
+static void
+ioeventfd_destructor(struct kvm_io_device *this)
+{
+	struct _ioeventfd *p = to_ioeventfd(this);
+
+	ioeventfd_release(p);
+}
+
+static const struct kvm_io_device_ops ioeventfd_ops = {
+	.write      = ioeventfd_write,
+	.destructor = ioeventfd_destructor,
+};
+
+/* assumes kvm->slots_lock held */
+static bool
+ioeventfd_check_collision(struct kvm *kvm, struct _ioeventfd *p)
+{
+	struct _ioeventfd *_p;
+
+	list_for_each_entry(_p, &kvm->ioeventfds, list)
+		if (_p->addr == p->addr && _p->length == p->length &&
+		    (_p->wildcard || p->wildcard ||
+		     _p->datamatch == p->datamatch))
+			return true;
+
+	return false;
+}
+
+static int
+kvm_assign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
+{
+	int                       pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
+	struct kvm_io_bus        *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
+	struct _ioeventfd        *p;
+	struct eventfd_ctx       *eventfd;
+	int                       ret;
+
+	/* must be natural-word sized */
+	switch (args->len) {
+	case 1:
+	case 2:
+	case 4:
+	case 8:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* check for range overflow */
+	if (args->addr + args->len < args->addr)
+		return -EINVAL;
+
+	/* check for extra flags that we don't understand */
+	if (args->flags & ~KVM_IOEVENTFD_VALID_FLAG_MASK)
+		return -EINVAL;
+
+	eventfd = eventfd_ctx_fdget(args->fd);
+	if (IS_ERR(eventfd))
+		return PTR_ERR(eventfd);
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	INIT_LIST_HEAD(&p->list);
+	p->addr    = args->addr;
+	p->length  = args->len;
+	p->eventfd = eventfd;
+
+	/* The datamatch feature is optional, otherwise this is a wildcard */
+	if (args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH)
+		p->datamatch = args->datamatch;
+	else
+		p->wildcard = true;
+
+	down_write(&kvm->slots_lock);
+
+	/* Verify that there isnt a match already */
+	if (ioeventfd_check_collision(kvm, p)) {
+		ret = -EEXIST;
+		goto unlock_fail;
+	}
+
+	kvm_iodevice_init(&p->dev, &ioeventfd_ops);
+
+	ret = __kvm_io_bus_register_dev(bus, &p->dev);
+	if (ret < 0)
+		goto unlock_fail;
+
+	list_add_tail(&p->list, &kvm->ioeventfds);
+
+	up_write(&kvm->slots_lock);
+
+	return 0;
+
+unlock_fail:
+	up_write(&kvm->slots_lock);
+
+fail:
+	kfree(p);
+	eventfd_ctx_put(eventfd);
+
+	return ret;
+}
+
+static int
+kvm_deassign_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
+{
+	int                       pio = args->flags & KVM_IOEVENTFD_FLAG_PIO;
+	struct kvm_io_bus        *bus = pio ? &kvm->pio_bus : &kvm->mmio_bus;
+	struct _ioeventfd        *p, *tmp;
+	struct eventfd_ctx       *eventfd;
+	int                       ret = -ENOENT;
+
+	eventfd = eventfd_ctx_fdget(args->fd);
+	if (IS_ERR(eventfd))
+		return PTR_ERR(eventfd);
+
+	down_write(&kvm->slots_lock);
+
+	list_for_each_entry_safe(p, tmp, &kvm->ioeventfds, list) {
+		bool wildcard = !(args->flags & KVM_IOEVENTFD_FLAG_DATAMATCH);
+
+		if (p->eventfd != eventfd  ||
+		    p->addr != args->addr  ||
+		    p->length != args->len ||
+		    p->wildcard != wildcard)
+			continue;
+
+		if (!p->wildcard && p->datamatch != args->datamatch)
+			continue;
+
+		__kvm_io_bus_unregister_dev(bus, &p->dev);
+		ioeventfd_release(p);
+		ret = 0;
+		break;
+	}
+
+	up_write(&kvm->slots_lock);
+
+	eventfd_ctx_put(eventfd);
+
+	return ret;
+}
+
+int
+kvm_ioeventfd(struct kvm *kvm, struct kvm_ioeventfd *args)
+{
+	if (args->flags & KVM_IOEVENTFD_FLAG_DEASSIGN)
+		return kvm_deassign_ioeventfd(kvm, args);
+
+	return kvm_assign_ioeventfd(kvm, args);
+}
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 1150c6d..9fe140b 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -36,6 +36,7 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <asm/current.h>
+#include <trace/events/kvm.h>
 
 #include "ioapic.h"
 #include "lapic.h"
@@ -103,6 +104,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
 {
 	unsigned index;
 	bool mask_before, mask_after;
+	union kvm_ioapic_redirect_entry *e;
 
 	switch (ioapic->ioregsel) {
 	case IOAPIC_REG_VERSION:
@@ -122,19 +124,20 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
 		ioapic_debug("change redir index %x val %x\n", index, val);
 		if (index >= IOAPIC_NUM_PINS)
 			return;
-		mask_before = ioapic->redirtbl[index].fields.mask;
+		e = &ioapic->redirtbl[index];
+		mask_before = e->fields.mask;
 		if (ioapic->ioregsel & 1) {
-			ioapic->redirtbl[index].bits &= 0xffffffff;
-			ioapic->redirtbl[index].bits |= (u64) val << 32;
+			e->bits &= 0xffffffff;
+			e->bits |= (u64) val << 32;
 		} else {
-			ioapic->redirtbl[index].bits &= ~0xffffffffULL;
-			ioapic->redirtbl[index].bits |= (u32) val;
-			ioapic->redirtbl[index].fields.remote_irr = 0;
+			e->bits &= ~0xffffffffULL;
+			e->bits |= (u32) val;
+			e->fields.remote_irr = 0;
 		}
-		mask_after = ioapic->redirtbl[index].fields.mask;
+		mask_after = e->fields.mask;
 		if (mask_before != mask_after)
 			kvm_fire_mask_notifiers(ioapic->kvm, index, mask_after);
-		if (ioapic->redirtbl[index].fields.trig_mode == IOAPIC_LEVEL_TRIG
+		if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG
 		    && ioapic->irr & (1 << index))
 			ioapic_service(ioapic, index);
 		break;
@@ -164,7 +167,9 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
 	/* Always delivery PIT interrupt to vcpu 0 */
 	if (irq == 0) {
 		irqe.dest_mode = 0; /* Physical mode. */
-		irqe.dest_id = ioapic->kvm->vcpus[0]->vcpu_id;
+		/* need to read apic_id from apic regiest since
+		 * it can be rewritten */
+		irqe.dest_id = ioapic->kvm->bsp_vcpu->vcpu_id;
 	}
 #endif
 	return kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe);
@@ -188,7 +193,10 @@ int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
 			if ((edge && old_irr != ioapic->irr) ||
 			    (!edge && !entry.fields.remote_irr))
 				ret = ioapic_service(ioapic, irq);
+			else
+				ret = 0; /* report coalesced interrupt */
 		}
+		trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0);
 	}
 	return ret;
 }
@@ -220,24 +228,29 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
 			__kvm_ioapic_update_eoi(ioapic, i, trigger_mode);
 }
 
-static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr,
-			   int len, int is_write)
+static inline struct kvm_ioapic *to_ioapic(struct kvm_io_device *dev)
 {
-	struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
+	return container_of(dev, struct kvm_ioapic, dev);
+}
 
+static inline int ioapic_in_range(struct kvm_ioapic *ioapic, gpa_t addr)
+{
 	return ((addr >= ioapic->base_address &&
 		 (addr < ioapic->base_address + IOAPIC_MEM_LENGTH)));
 }
 
-static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
-			     void *val)
+static int ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
+			    void *val)
 {
-	struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
+	struct kvm_ioapic *ioapic = to_ioapic(this);
 	u32 result;
+	if (!ioapic_in_range(ioapic, addr))
+		return -EOPNOTSUPP;
 
 	ioapic_debug("addr %lx\n", (unsigned long)addr);
 	ASSERT(!(addr & 0xf));	/* check alignment */
 
+	mutex_lock(&ioapic->kvm->irq_lock);
 	addr &= 0xff;
 	switch (addr) {
 	case IOAPIC_REG_SELECT:
@@ -264,22 +277,28 @@ static void ioapic_mmio_read(struct kvm_io_device *this, gpa_t addr, int len,
 	default:
 		printk(KERN_WARNING "ioapic: wrong length %d\n", len);
 	}
+	mutex_unlock(&ioapic->kvm->irq_lock);
+	return 0;
 }
 
-static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
-			      const void *val)
+static int ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
+			     const void *val)
 {
-	struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;
+	struct kvm_ioapic *ioapic = to_ioapic(this);
 	u32 data;
+	if (!ioapic_in_range(ioapic, addr))
+		return -EOPNOTSUPP;
 
 	ioapic_debug("ioapic_mmio_write addr=%p len=%d val=%p\n",
 		     (void*)addr, len, val);
 	ASSERT(!(addr & 0xf));	/* check alignment */
+
+	mutex_lock(&ioapic->kvm->irq_lock);
 	if (len == 4 || len == 8)
 		data = *(u32 *) val;
 	else {
 		printk(KERN_WARNING "ioapic: Unsupported size %d\n", len);
-		return;
+		goto unlock;
 	}
 
 	addr &= 0xff;
@@ -300,6 +319,9 @@ static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
 	default:
 		break;
 	}
+unlock:
+	mutex_unlock(&ioapic->kvm->irq_lock);
+	return 0;
 }
 
 void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
@@ -314,21 +336,27 @@ void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
 	ioapic->id = 0;
 }
 
+static const struct kvm_io_device_ops ioapic_mmio_ops = {
+	.read     = ioapic_mmio_read,
+	.write    = ioapic_mmio_write,
+};
+
 int kvm_ioapic_init(struct kvm *kvm)
 {
 	struct kvm_ioapic *ioapic;
+	int ret;
 
 	ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL);
 	if (!ioapic)
 		return -ENOMEM;
 	kvm->arch.vioapic = ioapic;
 	kvm_ioapic_reset(ioapic);
-	ioapic->dev.read = ioapic_mmio_read;
-	ioapic->dev.write = ioapic_mmio_write;
-	ioapic->dev.in_range = ioapic_in_range;
-	ioapic->dev.private = ioapic;
+	kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);
 	ioapic->kvm = kvm;
-	kvm_io_bus_register_dev(&kvm->mmio_bus, &ioapic->dev);
-	return 0;
+	ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &ioapic->dev);
+	if (ret < 0)
+		kfree(ioapic);
+
+	return ret;
 }
 
diff --git a/virt/kvm/iodev.h b/virt/kvm/iodev.h
index 55e8846..12fd3ca 100644
--- a/virt/kvm/iodev.h
+++ b/virt/kvm/iodev.h
@@ -17,49 +17,54 @@
 #define __KVM_IODEV_H__
 
 #include <linux/kvm_types.h>
+#include <asm/errno.h>
 
-struct kvm_io_device {
-	void (*read)(struct kvm_io_device *this,
+struct kvm_io_device;
+
+/**
+ * kvm_io_device_ops are called under kvm slots_lock.
+ * read and write handlers return 0 if the transaction has been handled,
+ * or non-zero to have it passed to the next device.
+ **/
+struct kvm_io_device_ops {
+	int (*read)(struct kvm_io_device *this,
+		    gpa_t addr,
+		    int len,
+		    void *val);
+	int (*write)(struct kvm_io_device *this,
 		     gpa_t addr,
 		     int len,
-		     void *val);
-	void (*write)(struct kvm_io_device *this,
-		      gpa_t addr,
-		      int len,
-		      const void *val);
-	int (*in_range)(struct kvm_io_device *this, gpa_t addr, int len,
-			int is_write);
+		     const void *val);
 	void (*destructor)(struct kvm_io_device *this);
+};
 
-	void             *private;
+
+struct kvm_io_device {
+	const struct kvm_io_device_ops *ops;
 };
 
-static inline void kvm_iodevice_read(struct kvm_io_device *dev,
-				     gpa_t addr,
-				     int len,
-				     void *val)
+static inline void kvm_iodevice_init(struct kvm_io_device *dev,
+				     const struct kvm_io_device_ops *ops)
 {
-	dev->read(dev, addr, len, val);
+	dev->ops = ops;
 }
 
-static inline void kvm_iodevice_write(struct kvm_io_device *dev,
-				      gpa_t addr,
-				      int len,
-				      const void *val)
+static inline int kvm_iodevice_read(struct kvm_io_device *dev,
+				    gpa_t addr, int l, void *v)
 {
-	dev->write(dev, addr, len, val);
+	return dev->ops->read ? dev->ops->read(dev, addr, l, v) : -EOPNOTSUPP;
 }
 
-static inline int kvm_iodevice_inrange(struct kvm_io_device *dev,
-				       gpa_t addr, int len, int is_write)
+static inline int kvm_iodevice_write(struct kvm_io_device *dev,
+				     gpa_t addr, int l, const void *v)
 {
-	return dev->in_range(dev, addr, len, is_write);
+	return dev->ops->write ? dev->ops->write(dev, addr, l, v) : -EOPNOTSUPP;
 }
 
 static inline void kvm_iodevice_destructor(struct kvm_io_device *dev)
 {
-	if (dev->destructor)
-		dev->destructor(dev);
+	if (dev->ops->destructor)
+		dev->ops->destructor(dev);
 }
 
 #endif /* __KVM_IODEV_H__ */
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
index ddc17f0..001663f 100644
--- a/virt/kvm/irq_comm.c
+++ b/virt/kvm/irq_comm.c
@@ -20,6 +20,7 @@
  */
 
 #include <linux/kvm_host.h>
+#include <trace/events/kvm.h>
 
 #include <asm/msidef.h>
 #ifdef CONFIG_IA64
@@ -62,14 +63,14 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
 	int i, r = -1;
 	struct kvm_vcpu *vcpu, *lowest = NULL;
 
+	WARN_ON(!mutex_is_locked(&kvm->irq_lock));
+
 	if (irq->dest_mode == 0 && irq->dest_id == 0xff &&
 			kvm_is_dm_lowest_prio(irq))
 		printk(KERN_INFO "kvm: apic: phys broadcast and lowest prio\n");
 
-	for (i = 0; i < KVM_MAX_VCPUS; i++) {
-		vcpu = kvm->vcpus[i];
-
-		if (!vcpu || !kvm_apic_present(vcpu))
+	kvm_for_each_vcpu(i, vcpu, kvm) {
+		if (!kvm_apic_present(vcpu))
 			continue;
 
 		if (!kvm_apic_match_dest(vcpu, src, irq->shorthand,
@@ -99,6 +100,8 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 {
 	struct kvm_lapic_irq irq;
 
+	trace_kvm_msi_set_irq(e->msi.address_lo, e->msi.data);
+
 	irq.dest_id = (e->msi.address_lo &
 			MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
 	irq.vector = (e->msi.data &
@@ -113,7 +116,7 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
 	return kvm_irq_delivery_to_apic(kvm, NULL, &irq);
 }
 
-/* This should be called with the kvm->lock mutex held
+/* This should be called with the kvm->irq_lock mutex held
  * Return value:
  *  < 0   Interrupt was ignored (masked or not delivered for other reasons)
  *  = 0   Interrupt was coalesced (previous irq is still pending)
@@ -125,6 +128,10 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
 	unsigned long *irq_state, sig_level;
 	int ret = -1;
 
+	trace_kvm_set_irq(irq, level, irq_source_id);
+
+	WARN_ON(!mutex_is_locked(&kvm->irq_lock));
+
 	if (irq < KVM_IOAPIC_NUM_PINS) {
 		irq_state = (unsigned long *)&kvm->arch.irq_states[irq];
 
@@ -134,7 +141,9 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level)
 		else
 			clear_bit(irq_source_id, irq_state);
 		sig_level = !!(*irq_state);
-	} else /* Deal with MSI/MSI-X */
+	} else if (!level)
+		return ret;
+	else /* Deal with MSI/MSI-X */
 		sig_level = 1;
 
 	/* Not possible to detect if the guest uses the PIC or the
@@ -159,6 +168,8 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
 	struct hlist_node *n;
 	unsigned gsi = pin;
 
+	trace_kvm_ack_irq(irqchip, pin);
+
 	list_for_each_entry(e, &kvm->irq_routing, link)
 		if (e->type == KVM_IRQ_ROUTING_IRQCHIP &&
 		    e->irqchip.irqchip == irqchip &&
@@ -175,19 +186,26 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
 void kvm_register_irq_ack_notifier(struct kvm *kvm,
 				   struct kvm_irq_ack_notifier *kian)
 {
+	mutex_lock(&kvm->irq_lock);
 	hlist_add_head(&kian->link, &kvm->arch.irq_ack_notifier_list);
+	mutex_unlock(&kvm->irq_lock);
 }
 
-void kvm_unregister_irq_ack_notifier(struct kvm_irq_ack_notifier *kian)
+void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
+				    struct kvm_irq_ack_notifier *kian)
 {
+	mutex_lock(&kvm->irq_lock);
 	hlist_del_init(&kian->link);
+	mutex_unlock(&kvm->irq_lock);
 }
 
-/* The caller must hold kvm->lock mutex */
 int kvm_request_irq_source_id(struct kvm *kvm)
 {
 	unsigned long *bitmap = &kvm->arch.irq_sources_bitmap;
-	int irq_source_id = find_first_zero_bit(bitmap,
+	int irq_source_id;
+
+	mutex_lock(&kvm->irq_lock);
+	irq_source_id = find_first_zero_bit(bitmap,
 				sizeof(kvm->arch.irq_sources_bitmap));
 
 	if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
@@ -197,6 +215,7 @@ int kvm_request_irq_source_id(struct kvm *kvm)
 
 	ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
 	set_bit(irq_source_id, bitmap);
+	mutex_unlock(&kvm->irq_lock);
 
 	return irq_source_id;
 }
@@ -207,6 +226,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
 
 	ASSERT(irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID);
 
+	mutex_lock(&kvm->irq_lock);
 	if (irq_source_id < 0 ||
 	    irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) {
 		printk(KERN_ERR "kvm: IRQ source ID out of range!\n");
@@ -215,19 +235,24 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id)
 	for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++)
 		clear_bit(irq_source_id, &kvm->arch.irq_states[i]);
 	clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap);
+	mutex_unlock(&kvm->irq_lock);
 }
 
 void kvm_register_irq_mask_notifier(struct kvm *kvm, int irq,
 				    struct kvm_irq_mask_notifier *kimn)
 {
+	mutex_lock(&kvm->irq_lock);
 	kimn->irq = irq;
 	hlist_add_head(&kimn->link, &kvm->mask_notifier_list);
+	mutex_unlock(&kvm->irq_lock);
 }
 
 void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
 				      struct kvm_irq_mask_notifier *kimn)
 {
+	mutex_lock(&kvm->irq_lock);
 	hlist_del(&kimn->link);
+	mutex_unlock(&kvm->irq_lock);
 }
 
 void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask)
@@ -235,6 +260,8 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, int irq, bool mask)
 	struct kvm_irq_mask_notifier *kimn;
 	struct hlist_node *n;
 
+	WARN_ON(!mutex_is_locked(&kvm->irq_lock));
+
 	hlist_for_each_entry(kimn, n, &kvm->mask_notifier_list, link)
 		if (kimn->irq == irq)
 			kimn->func(kimn, mask);
@@ -250,7 +277,9 @@ static void __kvm_free_irq_routing(struct list_head *irq_routing)
 
 void kvm_free_irq_routing(struct kvm *kvm)
 {
+	mutex_lock(&kvm->irq_lock);
 	__kvm_free_irq_routing(&kvm->irq_routing);
+	mutex_unlock(&kvm->irq_lock);
 }
 
 static int setup_routing_entry(struct kvm_kernel_irq_routing_entry *e,
@@ -325,13 +354,13 @@ int kvm_set_irq_routing(struct kvm *kvm,
 		e = NULL;
 	}
 
-	mutex_lock(&kvm->lock);
+	mutex_lock(&kvm->irq_lock);
 	list_splice(&kvm->irq_routing, &tmp);
 	INIT_LIST_HEAD(&kvm->irq_routing);
 	list_splice(&irq_list, &kvm->irq_routing);
 	INIT_LIST_HEAD(&irq_list);
 	list_splice(&tmp, &irq_list);
-	mutex_unlock(&kvm->lock);
+	mutex_unlock(&kvm->irq_lock);
 
 	r = 0;
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 2884baf..897bff3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -59,9 +59,18 @@
 #include "irq.h"
 #endif
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/kvm.h>
+
 MODULE_AUTHOR("Qumranet");
 MODULE_LICENSE("GPL");
 
+/*
+ * Ordering of locks:
+ *
+ * 		kvm->slots_lock --> kvm->lock --> kvm->irq_lock
+ */
+
 DEFINE_SPINLOCK(kvm_lock);
 LIST_HEAD(vm_list);
 
@@ -79,6 +88,8 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
 
 static bool kvm_rebooting;
 
+static bool largepages_enabled = true;
+
 #ifdef KVM_CAP_DEVICE_ASSIGNMENT
 static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
 						      int assigned_dev_id)
@@ -120,17 +131,13 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
 {
 	struct kvm_assigned_dev_kernel *assigned_dev;
 	struct kvm *kvm;
-	int irq, i;
+	int i;
 
 	assigned_dev = container_of(work, struct kvm_assigned_dev_kernel,
 				    interrupt_work);
 	kvm = assigned_dev->kvm;
 
-	/* This is taken to safely inject irq inside the guest. When
-	 * the interrupt injection (or the ioapic code) uses a
-	 * finer-grained lock, update this
-	 */
-	mutex_lock(&kvm->lock);
+	mutex_lock(&kvm->irq_lock);
 	spin_lock_irq(&assigned_dev->assigned_dev_lock);
 	if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_HOST_MSIX) {
 		struct kvm_guest_msix_entry *guest_entries =
@@ -143,23 +150,13 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
 			kvm_set_irq(assigned_dev->kvm,
 				    assigned_dev->irq_source_id,
 				    guest_entries[i].vector, 1);
-			irq = assigned_dev->host_msix_entries[i].vector;
-			if (irq != 0)
-				enable_irq(irq);
-			assigned_dev->host_irq_disabled = false;
 		}
-	} else {
+	} else
 		kvm_set_irq(assigned_dev->kvm, assigned_dev->irq_source_id,
 			    assigned_dev->guest_irq, 1);
-		if (assigned_dev->irq_requested_type &
-				KVM_DEV_IRQ_GUEST_MSI) {
-			enable_irq(assigned_dev->host_irq);
-			assigned_dev->host_irq_disabled = false;
-		}
-	}
 
 	spin_unlock_irq(&assigned_dev->assigned_dev_lock);
-	mutex_unlock(&assigned_dev->kvm->lock);
+	mutex_unlock(&assigned_dev->kvm->irq_lock);
 }
 
 static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
@@ -179,8 +176,10 @@ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
 
 	schedule_work(&assigned_dev->interrupt_work);
 
-	disable_irq_nosync(irq);
-	assigned_dev->host_irq_disabled = true;
+	if (assigned_dev->irq_requested_type & KVM_DEV_IRQ_GUEST_INTX) {
+		disable_irq_nosync(irq);
+		assigned_dev->host_irq_disabled = true;
+	}
 
 out:
 	spin_unlock_irqrestore(&assigned_dev->assigned_dev_lock, flags);
@@ -215,7 +214,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
 static void deassign_guest_irq(struct kvm *kvm,
 			       struct kvm_assigned_dev_kernel *assigned_dev)
 {
-	kvm_unregister_irq_ack_notifier(&assigned_dev->ack_notifier);
+	kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier);
 	assigned_dev->ack_notifier.gsi = -1;
 
 	if (assigned_dev->irq_source_id != -1)
@@ -417,6 +416,7 @@ static int assigned_device_enable_guest_msi(struct kvm *kvm,
 {
 	dev->guest_irq = irq->guest_irq;
 	dev->ack_notifier.gsi = -1;
+	dev->host_irq_disabled = false;
 	return 0;
 }
 #endif
@@ -427,6 +427,7 @@ static int assigned_device_enable_guest_msix(struct kvm *kvm,
 {
 	dev->guest_irq = irq->guest_irq;
 	dev->ack_notifier.gsi = -1;
+	dev->host_irq_disabled = false;
 	return 0;
 }
 #endif
@@ -693,11 +694,6 @@ out:
 }
 #endif
 
-static inline int valid_vcpu(int n)
-{
-	return likely(n >= 0 && n < KVM_MAX_VCPUS);
-}
-
 inline int kvm_is_mmio_pfn(pfn_t pfn)
 {
 	if (pfn_valid(pfn)) {
@@ -745,12 +741,9 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
 	if (alloc_cpumask_var(&cpus, GFP_ATOMIC))
 		cpumask_clear(cpus);
 
-	me = get_cpu();
 	spin_lock(&kvm->requests_lock);
-	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-		vcpu = kvm->vcpus[i];
-		if (!vcpu)
-			continue;
+	me = smp_processor_id();
+	kvm_for_each_vcpu(i, vcpu, kvm) {
 		if (test_and_set_bit(req, &vcpu->requests))
 			continue;
 		cpu = vcpu->cpu;
@@ -764,7 +757,6 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req)
 	else
 		called = false;
 	spin_unlock(&kvm->requests_lock);
-	put_cpu();
 	free_cpumask_var(cpus);
 	return called;
 }
@@ -986,7 +978,9 @@ static struct kvm *kvm_create_vm(void)
 	spin_lock_init(&kvm->mmu_lock);
 	spin_lock_init(&kvm->requests_lock);
 	kvm_io_bus_init(&kvm->pio_bus);
+	kvm_eventfd_init(kvm);
 	mutex_init(&kvm->lock);
+	mutex_init(&kvm->irq_lock);
 	kvm_io_bus_init(&kvm->mmio_bus);
 	init_rwsem(&kvm->slots_lock);
 	atomic_set(&kvm->users_count, 1);
@@ -1006,19 +1000,25 @@ out:
 static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
 				  struct kvm_memory_slot *dont)
 {
+	int i;
+
 	if (!dont || free->rmap != dont->rmap)
 		vfree(free->rmap);
 
 	if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
 		vfree(free->dirty_bitmap);
 
-	if (!dont || free->lpage_info != dont->lpage_info)
-		vfree(free->lpage_info);
+
+	for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
+		if (!dont || free->lpage_info[i] != dont->lpage_info[i]) {
+			vfree(free->lpage_info[i]);
+			free->lpage_info[i] = NULL;
+		}
+	}
 
 	free->npages = 0;
 	free->dirty_bitmap = NULL;
 	free->rmap = NULL;
-	free->lpage_info = NULL;
 }
 
 void kvm_free_physmem(struct kvm *kvm)
@@ -1071,6 +1071,8 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
 {
 	struct kvm *kvm = filp->private_data;
 
+	kvm_irqfd_release(kvm);
+
 	kvm_put_kvm(kvm);
 	return 0;
 }
@@ -1089,8 +1091,8 @@ int __kvm_set_memory_region(struct kvm *kvm,
 {
 	int r;
 	gfn_t base_gfn;
-	unsigned long npages, ugfn;
-	unsigned long largepages, i;
+	unsigned long npages;
+	unsigned long i;
 	struct kvm_memory_slot *memslot;
 	struct kvm_memory_slot old, new;
 
@@ -1164,31 +1166,51 @@ int __kvm_set_memory_region(struct kvm *kvm,
 		else
 			new.userspace_addr = 0;
 	}
-	if (npages && !new.lpage_info) {
-		largepages = 1 + (base_gfn + npages - 1) / KVM_PAGES_PER_HPAGE;
-		largepages -= base_gfn / KVM_PAGES_PER_HPAGE;
+	if (!npages)
+		goto skip_lpage;
 
-		new.lpage_info = vmalloc(largepages * sizeof(*new.lpage_info));
+	for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
+		unsigned long ugfn;
+		unsigned long j;
+		int lpages;
+		int level = i + 2;
 
-		if (!new.lpage_info)
+		/* Avoid unused variable warning if no large pages */
+		(void)level;
+
+		if (new.lpage_info[i])
+			continue;
+
+		lpages = 1 + (base_gfn + npages - 1) /
+			     KVM_PAGES_PER_HPAGE(level);
+		lpages -= base_gfn / KVM_PAGES_PER_HPAGE(level);
+
+		new.lpage_info[i] = vmalloc(lpages * sizeof(*new.lpage_info[i]));
+
+		if (!new.lpage_info[i])
 			goto out_free;
 
-		memset(new.lpage_info, 0, largepages * sizeof(*new.lpage_info));
+		memset(new.lpage_info[i], 0,
+		       lpages * sizeof(*new.lpage_info[i]));
 
-		if (base_gfn % KVM_PAGES_PER_HPAGE)
-			new.lpage_info[0].write_count = 1;
-		if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE)
-			new.lpage_info[largepages-1].write_count = 1;
+		if (base_gfn % KVM_PAGES_PER_HPAGE(level))
+			new.lpage_info[i][0].write_count = 1;
+		if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE(level))
+			new.lpage_info[i][lpages - 1].write_count = 1;
 		ugfn = new.userspace_addr >> PAGE_SHIFT;
 		/*
 		 * If the gfn and userspace address are not aligned wrt each
-		 * other, disable large page support for this slot
+		 * other, or if explicitly asked to, disable large page
+		 * support for this slot
 		 */
-		if ((base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE - 1))
-			for (i = 0; i < largepages; ++i)
-				new.lpage_info[i].write_count = 1;
+		if ((base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE(level) - 1) ||
+		    !largepages_enabled)
+			for (j = 0; j < lpages; ++j)
+				new.lpage_info[i][j].write_count = 1;
 	}
 
+skip_lpage:
+
 	/* Allocate page dirty bitmap if needed */
 	if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
 		unsigned dirty_bytes = ALIGN(npages, BITS_PER_LONG) / 8;
@@ -1200,6 +1222,10 @@ int __kvm_set_memory_region(struct kvm *kvm,
 		if (old.npages)
 			kvm_arch_flush_shadow(kvm);
 	}
+#else  /* not defined CONFIG_S390 */
+	new.user_alloc = user_alloc;
+	if (user_alloc)
+		new.userspace_addr = mem->userspace_addr;
 #endif /* not defined CONFIG_S390 */
 
 	if (!npages)
@@ -1299,6 +1325,12 @@ out:
 	return r;
 }
 
+void kvm_disable_largepages(void)
+{
+	largepages_enabled = false;
+}
+EXPORT_SYMBOL_GPL(kvm_disable_largepages);
+
 int is_error_page(struct page *page)
 {
 	return page == bad_page;
@@ -1635,9 +1667,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
 	for (;;) {
 		prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
 
-		if ((kvm_arch_interrupt_allowed(vcpu) &&
-					kvm_cpu_has_interrupt(vcpu)) ||
-				kvm_arch_vcpu_runnable(vcpu)) {
+		if (kvm_arch_vcpu_runnable(vcpu)) {
 			set_bit(KVM_REQ_UNHALT, &vcpu->requests);
 			break;
 		}
@@ -1714,24 +1744,18 @@ static struct file_operations kvm_vcpu_fops = {
  */
 static int create_vcpu_fd(struct kvm_vcpu *vcpu)
 {
-	int fd = anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, 0);
-	if (fd < 0)
-		kvm_put_kvm(vcpu->kvm);
-	return fd;
+	return anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, 0);
 }
 
 /*
  * Creates some virtual cpus.  Good luck creating more than one.
  */
-static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
+static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
 {
 	int r;
-	struct kvm_vcpu *vcpu;
-
-	if (!valid_vcpu(n))
-		return -EINVAL;
+	struct kvm_vcpu *vcpu, *v;
 
-	vcpu = kvm_arch_vcpu_create(kvm, n);
+	vcpu = kvm_arch_vcpu_create(kvm, id);
 	if (IS_ERR(vcpu))
 		return PTR_ERR(vcpu);
 
@@ -1742,23 +1766,38 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
 		return r;
 
 	mutex_lock(&kvm->lock);
-	if (kvm->vcpus[n]) {
-		r = -EEXIST;
+	if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) {
+		r = -EINVAL;
 		goto vcpu_destroy;
 	}
-	kvm->vcpus[n] = vcpu;
-	mutex_unlock(&kvm->lock);
+
+	kvm_for_each_vcpu(r, v, kvm)
+		if (v->vcpu_id == id) {
+			r = -EEXIST;
+			goto vcpu_destroy;
+		}
+
+	BUG_ON(kvm->vcpus[atomic_read(&kvm->online_vcpus)]);
 
 	/* Now it's all set up, let userspace reach it */
 	kvm_get_kvm(kvm);
 	r = create_vcpu_fd(vcpu);
-	if (r < 0)
-		goto unlink;
+	if (r < 0) {
+		kvm_put_kvm(kvm);
+		goto vcpu_destroy;
+	}
+
+	kvm->vcpus[atomic_read(&kvm->online_vcpus)] = vcpu;
+	smp_wmb();
+	atomic_inc(&kvm->online_vcpus);
+
+#ifdef CONFIG_KVM_APIC_ARCHITECTURE
+	if (kvm->bsp_vcpu_id == id)
+		kvm->bsp_vcpu = vcpu;
+#endif
+	mutex_unlock(&kvm->lock);
 	return r;
 
-unlink:
-	mutex_lock(&kvm->lock);
-	kvm->vcpus[n] = NULL;
 vcpu_destroy:
 	mutex_unlock(&kvm->lock);
 	kvm_arch_vcpu_destroy(vcpu);
@@ -2199,6 +2238,7 @@ static long kvm_vm_ioctl(struct file *filp,
 		vfree(entries);
 		break;
 	}
+#endif /* KVM_CAP_IRQ_ROUTING */
 #ifdef __KVM_HAVE_MSIX
 	case KVM_ASSIGN_SET_MSIX_NR: {
 		struct kvm_assigned_msix_nr entry_nr;
@@ -2221,7 +2261,35 @@ static long kvm_vm_ioctl(struct file *filp,
 		break;
 	}
 #endif
-#endif /* KVM_CAP_IRQ_ROUTING */
+	case KVM_IRQFD: {
+		struct kvm_irqfd data;
+
+		r = -EFAULT;
+		if (copy_from_user(&data, argp, sizeof data))
+			goto out;
+		r = kvm_irqfd(kvm, data.fd, data.gsi, data.flags);
+		break;
+	}
+	case KVM_IOEVENTFD: {
+		struct kvm_ioeventfd data;
+
+		r = -EFAULT;
+		if (copy_from_user(&data, argp, sizeof data))
+			goto out;
+		r = kvm_ioeventfd(kvm, &data);
+		break;
+	}
+#ifdef CONFIG_KVM_APIC_ARCHITECTURE
+	case KVM_SET_BOOT_CPU_ID:
+		r = 0;
+		mutex_lock(&kvm->lock);
+		if (atomic_read(&kvm->online_vcpus) != 0)
+			r = -EBUSY;
+		else
+			kvm->bsp_vcpu_id = arg;
+		mutex_unlock(&kvm->lock);
+		break;
+#endif
 	default:
 		r = kvm_arch_vm_ioctl(filp, ioctl, arg);
 	}
@@ -2288,6 +2356,9 @@ static long kvm_dev_ioctl_check_extension_generic(long arg)
 	case KVM_CAP_USER_MEMORY:
 	case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
 	case KVM_CAP_JOIN_MEMORY_REGIONS_WORKS:
+#ifdef CONFIG_KVM_APIC_ARCHITECTURE
+	case KVM_CAP_SET_BOOT_CPU_ID:
+#endif
 		return 1;
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 	case KVM_CAP_IRQ_ROUTING:
@@ -2335,7 +2406,7 @@ static long kvm_dev_ioctl(struct file *filp,
 	case KVM_TRACE_ENABLE:
 	case KVM_TRACE_PAUSE:
 	case KVM_TRACE_DISABLE:
-		r = kvm_trace_ioctl(ioctl, arg);
+		r = -EOPNOTSUPP;
 		break;
 	default:
 		return kvm_arch_dev_ioctl(filp, ioctl, arg);
@@ -2449,26 +2520,71 @@ void kvm_io_bus_destroy(struct kvm_io_bus *bus)
 	}
 }
 
-struct kvm_io_device *kvm_io_bus_find_dev(struct kvm_io_bus *bus,
-					  gpa_t addr, int len, int is_write)
+/* kvm_io_bus_write - called under kvm->slots_lock */
+int kvm_io_bus_write(struct kvm_io_bus *bus, gpa_t addr,
+		     int len, const void *val)
 {
 	int i;
+	for (i = 0; i < bus->dev_count; i++)
+		if (!kvm_iodevice_write(bus->devs[i], addr, len, val))
+			return 0;
+	return -EOPNOTSUPP;
+}
 
-	for (i = 0; i < bus->dev_count; i++) {
-		struct kvm_io_device *pos = bus->devs[i];
+/* kvm_io_bus_read - called under kvm->slots_lock */
+int kvm_io_bus_read(struct kvm_io_bus *bus, gpa_t addr, int len, void *val)
+{
+	int i;
+	for (i = 0; i < bus->dev_count; i++)
+		if (!kvm_iodevice_read(bus->devs[i], addr, len, val))
+			return 0;
+	return -EOPNOTSUPP;
+}
 
-		if (pos->in_range(pos, addr, len, is_write))
-			return pos;
-	}
+int kvm_io_bus_register_dev(struct kvm *kvm, struct kvm_io_bus *bus,
+			     struct kvm_io_device *dev)
+{
+	int ret;
 
-	return NULL;
+	down_write(&kvm->slots_lock);
+	ret = __kvm_io_bus_register_dev(bus, dev);
+	up_write(&kvm->slots_lock);
+
+	return ret;
 }
 
-void kvm_io_bus_register_dev(struct kvm_io_bus *bus, struct kvm_io_device *dev)
+/* An unlocked version. Caller must have write lock on slots_lock. */
+int __kvm_io_bus_register_dev(struct kvm_io_bus *bus,
+			      struct kvm_io_device *dev)
 {
-	BUG_ON(bus->dev_count > (NR_IOBUS_DEVS-1));
+	if (bus->dev_count > NR_IOBUS_DEVS-1)
+		return -ENOSPC;
 
 	bus->devs[bus->dev_count++] = dev;
+
+	return 0;
+}
+
+void kvm_io_bus_unregister_dev(struct kvm *kvm,
+			       struct kvm_io_bus *bus,
+			       struct kvm_io_device *dev)
+{
+	down_write(&kvm->slots_lock);
+	__kvm_io_bus_unregister_dev(bus, dev);
+	up_write(&kvm->slots_lock);
+}
+
+/* An unlocked version. Caller must have write lock on slots_lock. */
+void __kvm_io_bus_unregister_dev(struct kvm_io_bus *bus,
+				 struct kvm_io_device *dev)
+{
+	int i;
+
+	for (i = 0; i < bus->dev_count; i++)
+		if (bus->devs[i] == dev) {
+			bus->devs[i] = bus->devs[--bus->dev_count];
+			break;
+		}
 }
 
 static struct notifier_block kvm_cpu_notifier = {
@@ -2501,11 +2617,9 @@ static int vcpu_stat_get(void *_offset, u64 *val)
 	*val = 0;
 	spin_lock(&kvm_lock);
 	list_for_each_entry(kvm, &vm_list, vm_list)
-		for (i = 0; i < KVM_MAX_VCPUS; ++i) {
-			vcpu = kvm->vcpus[i];
-			if (vcpu)
-				*val += *(u32 *)((void *)vcpu + offset);
-		}
+		kvm_for_each_vcpu(i, vcpu, kvm)
+			*val += *(u32 *)((void *)vcpu + offset);
+
 	spin_unlock(&kvm_lock);
 	return 0;
 }
@@ -2679,15 +2793,15 @@ out_free_0:
 	__free_page(bad_page);
 out:
 	kvm_arch_exit();
-	kvm_exit_debug();
 out_fail:
+	kvm_exit_debug();
 	return r;
 }
 EXPORT_SYMBOL_GPL(kvm_init);
 
 void kvm_exit(void)
 {
-	kvm_trace_cleanup();
+	tracepoint_synchronize_unregister();
 	misc_deregister(&kvm_dev);
 	kmem_cache_destroy(kvm_vcpu_cache);
 	sysdev_unregister(&kvm_sysdev);
diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
deleted file mode 100644
index f598744..0000000
--- a/virt/kvm/kvm_trace.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * kvm trace
- *
- * It is designed to allow debugging traces of kvm to be generated
- * on UP / SMP machines.  Each trace entry can be timestamped so that
- * it's possible to reconstruct a chronological record of trace events.
- * The implementation refers to blktrace kernel support.
- *
- * Copyright (c) 2008 Intel Corporation
- * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
- *
- * Authors: Feng(Eric) Liu, eric.e.liu@intel.com
- *
- * Date:    Feb 2008
- */
-
-#include <linux/module.h>
-#include <linux/relay.h>
-#include <linux/debugfs.h>
-#include <linux/ktime.h>
-
-#include <linux/kvm_host.h>
-
-#define KVM_TRACE_STATE_RUNNING 	(1 << 0)
-#define KVM_TRACE_STATE_PAUSE 		(1 << 1)
-#define KVM_TRACE_STATE_CLEARUP 	(1 << 2)
-
-struct kvm_trace {
-	int trace_state;
-	struct rchan *rchan;
-	struct dentry *lost_file;
-	atomic_t lost_records;
-};
-static struct kvm_trace *kvm_trace;
-
-struct kvm_trace_probe {
-	const char *name;
-	const char *format;
-	u32 timestamp_in;
-	marker_probe_func *probe_func;
-};
-
-static inline int calc_rec_size(int timestamp, int extra)
-{
-	int rec_size = KVM_TRC_HEAD_SIZE;
-
-	rec_size += extra;
-	return timestamp ? rec_size += KVM_TRC_CYCLE_SIZE : rec_size;
-}
-
-static void kvm_add_trace(void *probe_private, void *call_data,
-			  const char *format, va_list *args)
-{
-	struct kvm_trace_probe *p = probe_private;
-	struct kvm_trace *kt = kvm_trace;
-	struct kvm_trace_rec rec;
-	struct kvm_vcpu *vcpu;
-	int    i, size;
-	u32    extra;
-
-	if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING))
-		return;
-
-	rec.rec_val	= TRACE_REC_EVENT_ID(va_arg(*args, u32));
-	vcpu		= va_arg(*args, struct kvm_vcpu *);
-	rec.pid		= current->tgid;
-	rec.vcpu_id	= vcpu->vcpu_id;
-
-	extra   	= va_arg(*args, u32);
-	WARN_ON(!(extra <= KVM_TRC_EXTRA_MAX));
-	extra 		= min_t(u32, extra, KVM_TRC_EXTRA_MAX);
-
-	rec.rec_val |= TRACE_REC_TCS(p->timestamp_in)
-			| TRACE_REC_NUM_DATA_ARGS(extra);
-
-	if (p->timestamp_in) {
-		rec.u.timestamp.timestamp = ktime_to_ns(ktime_get());
-
-		for (i = 0; i < extra; i++)
-			rec.u.timestamp.extra_u32[i] = va_arg(*args, u32);
-	} else {
-		for (i = 0; i < extra; i++)
-			rec.u.notimestamp.extra_u32[i] = va_arg(*args, u32);
-	}
-
-	size = calc_rec_size(p->timestamp_in, extra * sizeof(u32));
-	relay_write(kt->rchan, &rec, size);
-}
-
-static struct kvm_trace_probe kvm_trace_probes[] = {
-	{ "kvm_trace_entryexit", "%u %p %u %u %u %u %u %u", 1, kvm_add_trace },
-	{ "kvm_trace_handler", "%u %p %u %u %u %u %u %u", 0, kvm_add_trace },
-};
-
-static int lost_records_get(void *data, u64 *val)
-{
-	struct kvm_trace *kt = data;
-
-	*val = atomic_read(&kt->lost_records);
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(kvm_trace_lost_ops, lost_records_get, NULL, "%llu\n");
-
-/*
- *  The relay channel is used in "no-overwrite" mode, it keeps trace of how
- *  many times we encountered a full subbuffer, to tell user space app the
- *  lost records there were.
- */
-static int kvm_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
-				     void *prev_subbuf, size_t prev_padding)
-{
-	struct kvm_trace *kt;
-
-	if (!relay_buf_full(buf)) {
-		if (!prev_subbuf) {
-			/*
-			 * executed only once when the channel is opened
-			 * save metadata as first record
-			 */
-			subbuf_start_reserve(buf, sizeof(u32));
-			*(u32 *)subbuf = 0x12345678;
-		}
-
-		return 1;
-	}
-
-	kt = buf->chan->private_data;
-	atomic_inc(&kt->lost_records);
-
-	return 0;
-}
-
-static struct dentry *kvm_create_buf_file_callack(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 int kvm_remove_buf_file_callback(struct dentry *dentry)
-{
-	debugfs_remove(dentry);
-	return 0;
-}
-
-static struct rchan_callbacks kvm_relay_callbacks = {
-	.subbuf_start 		= kvm_subbuf_start_callback,
-	.create_buf_file 	= kvm_create_buf_file_callack,
-	.remove_buf_file 	= kvm_remove_buf_file_callback,
-};
-
-static int do_kvm_trace_enable(struct kvm_user_trace_setup *kuts)
-{
-	struct kvm_trace *kt;
-	int i, r = -ENOMEM;
-
-	if (!kuts->buf_size || !kuts->buf_nr)
-		return -EINVAL;
-
-	kt = kzalloc(sizeof(*kt), GFP_KERNEL);
-	if (!kt)
-		goto err;
-
-	r = -EIO;
-	atomic_set(&kt->lost_records, 0);
-	kt->lost_file = debugfs_create_file("lost_records", 0444, kvm_debugfs_dir,
-					    kt, &kvm_trace_lost_ops);
-	if (!kt->lost_file)
-		goto err;
-
-	kt->rchan = relay_open("trace", kvm_debugfs_dir, kuts->buf_size,
-				kuts->buf_nr, &kvm_relay_callbacks, kt);
-	if (!kt->rchan)
-		goto err;
-
-	kvm_trace = kt;
-
-	for (i = 0; i < ARRAY_SIZE(kvm_trace_probes); i++) {
-		struct kvm_trace_probe *p = &kvm_trace_probes[i];
-
-		r = marker_probe_register(p->name, p->format, p->probe_func, p);
-		if (r)
-			printk(KERN_INFO "Unable to register probe %s\n",
-			       p->name);
-	}
-
-	kvm_trace->trace_state = KVM_TRACE_STATE_RUNNING;
-
-	return 0;
-err:
-	if (kt) {
-		if (kt->lost_file)
-			debugfs_remove(kt->lost_file);
-		if (kt->rchan)
-			relay_close(kt->rchan);
-		kfree(kt);
-	}
-	return r;
-}
-
-static int kvm_trace_enable(char __user *arg)
-{
-	struct kvm_user_trace_setup kuts;
-	int ret;
-
-	ret = copy_from_user(&kuts, arg, sizeof(kuts));
-	if (ret)
-		return -EFAULT;
-
-	ret = do_kvm_trace_enable(&kuts);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
-static int kvm_trace_pause(void)
-{
-	struct kvm_trace *kt = kvm_trace;
-	int r = -EINVAL;
-
-	if (kt == NULL)
-		return r;
-
-	if (kt->trace_state == KVM_TRACE_STATE_RUNNING) {
-		kt->trace_state = KVM_TRACE_STATE_PAUSE;
-		relay_flush(kt->rchan);
-		r = 0;
-	}
-
-	return r;
-}
-
-void kvm_trace_cleanup(void)
-{
-	struct kvm_trace *kt = kvm_trace;
-	int i;
-
-	if (kt == NULL)
-		return;
-
-	if (kt->trace_state == KVM_TRACE_STATE_RUNNING ||
-	    kt->trace_state == KVM_TRACE_STATE_PAUSE) {
-
-		kt->trace_state = KVM_TRACE_STATE_CLEARUP;
-
-		for (i = 0; i < ARRAY_SIZE(kvm_trace_probes); i++) {
-			struct kvm_trace_probe *p = &kvm_trace_probes[i];
-			marker_probe_unregister(p->name, p->probe_func, p);
-		}
-		marker_synchronize_unregister();
-
-		relay_close(kt->rchan);
-		debugfs_remove(kt->lost_file);
-		kfree(kt);
-	}
-}
-
-int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg)
-{
-	void __user *argp = (void __user *)arg;
-	long r = -EINVAL;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-
-	switch (ioctl) {
-	case KVM_TRACE_ENABLE:
-		r = kvm_trace_enable(argp);
-		break;
-	case KVM_TRACE_PAUSE:
-		r = kvm_trace_pause();
-		break;
-	case KVM_TRACE_DISABLE:
-		r = 0;
-		kvm_trace_cleanup();
-		break;
-	}
-
-	return r;
-}
